From f77dcb798e06f89df4cec75fe9611f32b00a2e6f Mon Sep 17 00:00:00 2001 From: alanw Date: Wed, 27 Jul 2011 08:18:47 +0100 Subject: [PATCH 001/157] Fix compile errors on Mac --- .gitignore | 11 +++++---- src/core/include/_FieldCacheRangeFilter.h | 4 ++-- src/core/util/LuceneThread.cpp | 28 +++++++++++------------ 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index fe509f7a..8d0e2199 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,10 @@ *.cmd *.suo *.ncb -*.idb -*.obj -*.opt -*.pch +*.idb +*.obj +*.opt +*.pch *.pyc *.log *.exe @@ -21,6 +21,9 @@ *.manifest *.user *.bak +*.lock* +*.waf* +.DS_Store bin/* src/msvc/Debug DLL src/msvc/Debug Static diff --git a/src/core/include/_FieldCacheRangeFilter.h b/src/core/include/_FieldCacheRangeFilter.h index 43a75d6f..7e494fd6 100644 --- a/src/core/include/_FieldCacheRangeFilter.h +++ b/src/core/include/_FieldCacheRangeFilter.h @@ -111,11 +111,11 @@ namespace Lucene { if (!includeLower && lowerVal == maxVal) return DocIdSet::EMPTY_DOCIDSET(); - TYPE inclusiveLowerPoint = (TYPE)(includeLower ? lowerVal : (lowerVal + 1)); + int64_t inclusiveLowerPoint = (int64_t)(includeLower ? lowerVal : (lowerVal + 1)); if (!includeUpper && upperVal == 0) return DocIdSet::EMPTY_DOCIDSET(); - TYPE inclusiveUpperPoint = (TYPE)(includeUpper ? upperVal : (upperVal - 1)); + int64_t inclusiveUpperPoint = (int64_t)(includeUpper ? upperVal : (upperVal - 1)); if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet::EMPTY_DOCIDSET(); diff --git a/src/core/util/LuceneThread.cpp b/src/core/util/LuceneThread.cpp index 2b2b3233..8fcac2d5 100644 --- a/src/core/util/LuceneThread.cpp +++ b/src/core/util/LuceneThread.cpp @@ -24,18 +24,18 @@ namespace Lucene { running = false; } - + LuceneThread::~LuceneThread() { } - + void LuceneThread::start() { setRunning(false); thread = newInstance(LuceneThread::runThread, this); setRunning(true); } - + void LuceneThread::runThread(LuceneThread* thread) { LuceneThreadPtr threadObject(thread->shared_from_this()); @@ -56,18 +56,18 @@ namespace Lucene SyncLock syncLock(this); this->running = running; } - + bool LuceneThread::isRunning() { SyncLock syncLock(this); return running; } - + bool LuceneThread::isAlive() { return (thread && isRunning()); } - + void LuceneThread::setPriority(int32_t priority) { #if defined(_WIN32) || defined(_WIN64) @@ -75,7 +75,7 @@ namespace Lucene SetThreadPriority(thread->native_handle(), priority); #endif } - + int32_t LuceneThread::getPriority() { #if defined(_WIN32) || defined(_WIN64) @@ -84,13 +84,13 @@ namespace Lucene return NORM_PRIORITY; #endif } - + void LuceneThread::yield() { if (thread) thread->yield(); } - + bool LuceneThread::join(int32_t timeout) { while (isAlive() && !thread->timed_join(boost::posix_time::milliseconds(timeout))) @@ -102,21 +102,21 @@ namespace Lucene } return true; } - + int64_t LuceneThread::currentId() { #if defined(_WIN32) || defined(_WIN64) - return GetCurrentThreadId(); + return (int64_t)GetCurrentThreadId(); #else - return pthread_self(); + return (int64_t)pthread_self(); #endif } - + void LuceneThread::threadSleep(int32_t time) { boost::this_thread::sleep(boost::posix_time::milliseconds(time)); } - + void LuceneThread::threadYield() { boost::this_thread::yield(); From c6ecc259d87136837cdccc7214451617d92ec94e Mon Sep 17 00:00:00 2001 From: alanw Date: Wed, 10 Aug 2011 22:16:48 +0200 Subject: [PATCH 002/157] Disable clang build --- wscript | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index d1129869..0f99d547 100644 --- a/wscript +++ b/wscript @@ -73,7 +73,7 @@ tester_include_dirs = [ def options(opt): opt.tool_options("boost") opt.tool_options('compiler_cxx') - opt.tool_options('clang', tooldir = 'build') + #opt.tool_options('clang', tooldir = 'build') opt.tool_options('gch', tooldir = 'build') opt.add_option( '--debug', @@ -96,7 +96,7 @@ def configure(conf): conf.check_cc(lib = 'z', mandatory = True) conf.check_cc(lib = 'pthread', mandatory = True) conf.check_tool('boost') - conf.check_tool('clang', 'build') + #conf.check_tool('clang', 'build') conf.check_tool('gch', 'build') conf.check_boost( static = 'onlystatic', From e28b15b02ff9de2208965e9af8eb80983380cdcd Mon Sep 17 00:00:00 2001 From: alanw Date: Sun, 21 Aug 2011 14:47:44 +0200 Subject: [PATCH 003/157] Fix exporting CharFolder and Lucene shared_ptr factory --- include/CharFolder.h | 12 ++++++------ include/LuceneFactory.h | 39 ++++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/include/CharFolder.h b/include/CharFolder.h index bd4913ef..e9f7630e 100644 --- a/include/CharFolder.h +++ b/include/CharFolder.h @@ -12,36 +12,36 @@ namespace Lucene { /// Utility class for folding character case. - class CharFolder : public LuceneObject + class LPPAPI CharFolder : public LuceneObject { public: virtual ~CharFolder(); LUCENE_CLASS(CharFolder); - + protected: static bool lowerCache; static bool upperCache; static wchar_t lowerChars[CHAR_MAX - CHAR_MIN + 1]; static wchar_t upperChars[CHAR_MAX - CHAR_MIN + 1]; - + public: static wchar_t toLower(wchar_t ch); static wchar_t toUpper(wchar_t ch); - + template static void toLower(ITER first, ITER last) { for (; first != last; ++first) *first = toLower(*first); } - + template static void toUpper(ITER first, ITER last) { for (; first != last; ++first) *first = toUpper(*first); } - + protected: static bool fillLower(); static bool fillUpper(); diff --git a/include/LuceneFactory.h b/include/LuceneFactory.h index 30d497b2..6424d2a0 100644 --- a/include/LuceneFactory.h +++ b/include/LuceneFactory.h @@ -8,6 +8,7 @@ #define LUCENEFACTORY_H #include +#include namespace Lucene { @@ -20,7 +21,7 @@ namespace Lucene return boost::allocate_shared(Allocator()); #endif } - + template boost::shared_ptr newInstance(A1 const& a1) { @@ -30,7 +31,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2) { @@ -40,7 +41,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3) { @@ -50,7 +51,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2, a3); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) { @@ -60,7 +61,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2, a3, a4); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) { @@ -70,7 +71,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) { @@ -80,7 +81,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) { @@ -90,7 +91,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6, a7); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) { @@ -100,7 +101,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6, a7, a8); #endif } - + template boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) { @@ -110,7 +111,7 @@ namespace Lucene return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9); #endif } - + template boost::shared_ptr newLucene() { @@ -118,7 +119,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1) { @@ -126,7 +127,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2) { @@ -134,7 +135,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3) { @@ -142,7 +143,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) { @@ -150,7 +151,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) { @@ -158,7 +159,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) { @@ -166,7 +167,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) { @@ -174,7 +175,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) { @@ -182,7 +183,7 @@ namespace Lucene instance->initialize(); return instance; } - + template boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) { From 2ad20d1a96c737631810b196ac197c7f97801f93 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sat, 5 May 2012 16:16:36 +0200 Subject: [PATCH 004/157] Clarified dual-licensing text. --- COPYING | 210 +--------------- GPL.license | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 686 insertions(+), 198 deletions(-) create mode 100644 GPL.license diff --git a/COPYING b/COPYING index d6456956..b2e8e49f 100644 --- a/COPYING +++ b/COPYING @@ -1,202 +1,16 @@ +This source code is dual-licensed. +================================== - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +LGPL: + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + See the file LGPL.licence - 1. Definitions. +Apache 2.0: + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. - "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 [yyyy] [name of copyright owner] - - 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. + See the file APACHE.licence diff --git a/GPL.license b/GPL.license new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/GPL.license @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 6953f6ebb9e5ee3ce5b3ceaf9379e925d00cf6c6 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Fri, 4 May 2012 15:21:51 +0100 Subject: [PATCH 005/157] Fix visibility of Lucene++ classes Passes -DLPP_HAVE_DLL to the compiler to actually enable LPP_BUILDING_LIB and LPPAPI which make symbols visible. --- src/core/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5639a2c7..c839f563 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -48,6 +48,7 @@ ADD_PRECOMPILED_HEADER(lucene++ ${lucene++-lib_SOURCE_DIR}/include/LuceneInc.h) SET_TARGET_PROPERTIES(lucene++ PROPERTIES VERSION ${LUCENE++_VERSION} SOVERSION ${LUCENE++_SOVERSION} + COMPILE_FLAGS -DLPP_HAVE_DLL ) TARGET_LINK_LIBRARIES(lucene++ lucene++-c @@ -63,7 +64,6 @@ install(TARGETS lucene++ ADD_LIBRARY(lucene++-static STATIC EXCLUDE_FROM_ALL ${lucene_sources} ${HEADERS} ${INTERN_HEADERS} ) -SET(PCH_ADDITIONAL_COMPILER_FLAGS_lucene++-static -DLPP_HAVE_DLL) ADD_PRECOMPILED_HEADER(lucene++-static ${lucene++-lib_SOURCE_DIR}/include/LuceneInc.h) #set properties on the libraries SET_TARGET_PROPERTIES(lucene++-static PROPERTIES From 783f9638cf15f9c15562275b8ba637059572d012 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Fri, 4 May 2012 15:21:51 +0100 Subject: [PATCH 006/157] Really hide C symbols of static utility library --- cmake/MacroCheckGccVisibility.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/MacroCheckGccVisibility.cmake b/cmake/MacroCheckGccVisibility.cmake index 2022aa31..4fb6f8ad 100644 --- a/cmake/MacroCheckGccVisibility.cmake +++ b/cmake/MacroCheckGccVisibility.cmake @@ -43,7 +43,7 @@ macro(MACRO_CHECK_GCC_VISIBILITY GccVisibility) if (${GccVisibility} AND GCC_IS_NEWER_THAN_4_1 AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") - set (KDE4_C_FLAGS "${KDE4_C_FLAGS}" "-fvisibility=hidden") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") if (GCC_IS_NEWER_THAN_4_2) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") From 18409f29f4207bdf3c4f5e968c2fc561594679c1 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Mon, 7 May 2012 08:50:08 +0100 Subject: [PATCH 007/157] Path testdir path to lucene++-tester This is to allow testing with shadow builds, like done by Debian Helper. --- src/test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 36ab3368..b1e2a28f 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -33,5 +33,5 @@ TARGET_LINK_LIBRARIES(lucene++-tester ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE} ${LUCENE_BOOST_LIBS} ) -ADD_TEST(${EXECUTABLE_OUTPUT_PATH}/lucene++-tester ${EXECUTABLE_OUTPUT_PATH}/lucene++-tester -p) +ADD_TEST(lucene++-tester ${EXECUTABLE_OUTPUT_PATH}/lucene++-tester -p --test_dir=${lucene++-tester_SOURCE_DIR}/testfiles) From f9fde5cf4787816dead77b5f857fa59df31df749 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Mon, 7 May 2012 09:02:06 +0100 Subject: [PATCH 008/157] Also install the contributions library. --- CMakeLists.txt | 12 +++++++++--- liblucene++-contrib.pc.cmake | 14 ++++++++++++++ src/contrib/CMakeLists.txt | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 liblucene++-contrib.pc.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7457c1b5..35328f2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,7 +154,7 @@ INCLUDE(PCHSupport) #################################### #include sub-projects ADD_SUBDIRECTORY (src/core) -ADD_SUBDIRECTORY (src/contrib EXCLUDE_FROM_ALL) +ADD_SUBDIRECTORY (src/contrib) ADD_SUBDIRECTORY (src/demo EXCLUDE_FROM_ALL) ADD_SUBDIRECTORY (src/test) @@ -163,8 +163,14 @@ ADD_SUBDIRECTORY (src/test) # install pkg-config file ################################# IF(NOT WIN32) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/liblucene++.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/liblucene++.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/liblucene++-contrib.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc @ONLY) + + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc DESTINATION ${LIB_DESTINATION}/pkgconfig ) ENDIF(NOT WIN32) diff --git a/liblucene++-contrib.pc.cmake b/liblucene++-contrib.pc.cmake new file mode 100644 index 00000000..8e02e3e5 --- /dev/null +++ b/liblucene++-contrib.pc.cmake @@ -0,0 +1,14 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix}/bin +libdir=${prefix}/@LIB_DESTINATION@ +includedir=${prefix}/include/lucene++ +lib=lucene++-contrib + +Name: liblucene++-contrib +Description: Contributions for Lucene++ - a C++ search engine, ported from the popular Apache Lucene +Version: @LUCENE++_VERSION@ +Libs: -L${prefix}/@LIB_DESTINATION@/ -l${lib} +Cflags: -I${includedir} +Requires: liblucene++=@LUCENE++_VERSION@ +~ + diff --git a/src/contrib/CMakeLists.txt b/src/contrib/CMakeLists.txt index 96c7d5dd..df28415a 100644 --- a/src/contrib/CMakeLists.txt +++ b/src/contrib/CMakeLists.txt @@ -17,7 +17,7 @@ INCLUDE_DIRECTORIES(${lucene++-contrib_SOURCE_DIR}/include) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) -install(FILES HEADERS +install(FILES ${HEADERS} DESTINATION include/lucene++ COMPONENT development-contrib) From 63f1f7f5551999c31a96897dbf25dd71e491ee10 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Mon, 7 May 2012 08:53:58 +0100 Subject: [PATCH 009/157] Install the built HTML documentation. This basically is to support proper packaging. --- cmake/Lucene++Docs.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmake/Lucene++Docs.cmake b/cmake/Lucene++Docs.cmake index bf2938b5..52f2f246 100644 --- a/cmake/Lucene++Docs.cmake +++ b/cmake/Lucene++Docs.cmake @@ -138,7 +138,12 @@ IF (ENABLE_DOCS) ) ENDIF ( TAR AND GZIP ) - #install man if it was built + #install HTML pages if they were built + IF ( DOCS_HTML AND NOT WIN32 ) + INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/html/ DESTINATION share/doc/lucene++-${LUCENE++_VERSION}) + ENDIF ( DOCS_HTML AND NOT WIN32 ) + + #install man pages if they were built IF ( DOCS_MAN ) INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/man/ DESTINATION man) ENDIF ( DOCS_MAN ) From f666cb3fcc7b56224d69f9294bfd7b519ff2a31b Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Mon, 7 May 2012 10:23:31 +0100 Subject: [PATCH 010/157] Properly link liblucene++-contrib with liblucene++ Otherwise (not only) dpkg-shlibdeps will complain about unresolved symbols. --- src/contrib/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/contrib/CMakeLists.txt b/src/contrib/CMakeLists.txt index df28415a..89e03b3b 100644 --- a/src/contrib/CMakeLists.txt +++ b/src/contrib/CMakeLists.txt @@ -47,7 +47,8 @@ SET_TARGET_PROPERTIES(lucene++-contrib PROPERTIES COMPILE_FLAGS -DLPP_HAVE_DLL ) TARGET_LINK_LIBRARIES(lucene++-contrib - ${CMAKE_THREAD_LIBS_INIT}) + ${CMAKE_THREAD_LIBS_INIT} + lucene++) install(TARGETS lucene++-contrib DESTINATION ${LIB_DESTINATION} COMPONENT runtime ) From f173112f88dcf6e63bf36810c6b734ef7991b3a8 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Mon, 7 May 2012 21:42:28 +0200 Subject: [PATCH 011/157] Now able to use the default std::allocator instead of the custom Allocator. --- bin/.gitignore | 1 - include/BitSet.h | 10 +- include/Collection.h | 96 +++++++++--------- include/Config.h | 3 + include/HashMap.h | 58 +++++------ include/HashSet.h | 42 ++++---- include/Lucene.h | 46 ++++----- include/{Allocator.h => LuceneAllocator.h} | 98 ++++++++++--------- include/LuceneFactory.h | 20 ++-- include/Map.h | 48 ++++----- include/PriorityQueue.h | 60 ++++++------ include/Set.h | 50 +++++----- include/SimpleLRUCache.h | 22 ++--- src/core/msvc/lucene++.vcproj | 4 +- .../{Allocator.cpp => LuceneAllocator.cpp} | 10 +- 15 files changed, 289 insertions(+), 279 deletions(-) delete mode 100644 bin/.gitignore rename include/{Allocator.h => LuceneAllocator.h} (62%) rename src/core/util/{Allocator.cpp => LuceneAllocator.cpp} (97%) diff --git a/bin/.gitignore b/bin/.gitignore deleted file mode 100644 index f59ec20a..00000000 --- a/bin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/include/BitSet.h b/include/BitSet.h index 2598f8f9..3fa9cdd3 100644 --- a/include/BitSet.h +++ b/include/BitSet.h @@ -17,13 +17,13 @@ namespace Lucene public: BitSet(uint32_t size = 0); virtual ~BitSet(); - + LUCENE_CLASS(BitSet); - + protected: - typedef boost::dynamic_bitset< uint64_t, Allocator > bitset_type; + typedef boost::dynamic_bitset< uint64_t, LuceneAllocator > bitset_type; bitset_type bitSet; - + public: const uint64_t* getBits(); void clear(); @@ -56,7 +56,7 @@ namespace Lucene bool intersectsBitSet(BitSetPtr set) const; uint32_t cardinality(); void resize(uint32_t size); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); diff --git a/include/Collection.h b/include/Collection.h index d785ecdc..2e05a822 100644 --- a/include/Collection.h +++ b/include/Collection.h @@ -19,18 +19,18 @@ namespace Lucene public: typedef Collection this_type; typedef boost::shared_ptr shared_ptr; - typedef std::vector< TYPE, Allocator > collection_type; + typedef std::vector< TYPE, LuceneAllocator > collection_type; typedef typename collection_type::iterator iterator; typedef typename collection_type::const_iterator const_iterator; typedef TYPE value_type; - + virtual ~Collection() { } - + protected: boost::shared_ptr container; - + public: static this_type newInstance(int32_t size = 0) { @@ -38,7 +38,7 @@ namespace Lucene instance.container = Lucene::newInstance(size); return instance; } - + template static this_type newInstance(ITER first, ITER last) { @@ -46,12 +46,12 @@ namespace Lucene instance.container = Lucene::newInstance(first, last); return instance; } - + void reset() { resize(0); } - + void resize(int32_t size) { if (size == 0) @@ -59,128 +59,128 @@ namespace Lucene else container->resize(size); } - + int32_t size() const { return (int32_t)container->size(); } - + bool empty() const { return container->empty(); } - + void clear() { container->clear(); } - + iterator begin() { return container->begin(); } - + iterator end() { return container->end(); } - + const_iterator begin() const { return container->begin(); } - + const_iterator end() const { return container->end(); } - + void add(const TYPE& type) { container->push_back(type); } - + void add(int32_t pos, const TYPE& type) { container->insert(container->begin() + pos, type); } - + template void addAll(ITER first, ITER last) { container->insert(container->end(), first, last); } - + template void insert(ITER pos, const TYPE& type) { container->insert(pos, type); } - + template ITER remove(ITER pos) { return container->erase(pos); } - + template ITER remove(ITER first, ITER last) { return container->erase(first, last); } - + void remove(const TYPE& type) { container->erase(std::remove(container->begin(), container->end(), type), container->end()); } - + template void remove_if(PRED comp) { container->erase(std::remove_if(container->begin(), container->end(), comp), container->end()); } - + TYPE removeFirst() { TYPE front = container->front(); container->erase(container->begin()); return front; } - + TYPE removeLast() { TYPE back = container->back(); container->pop_back(); return back; } - + iterator find(const TYPE& type) { return std::find(container->begin(), container->end(), type); } - + template iterator find_if(PRED comp) { return std::find_if(container->begin(), container->end(), comp); } - + bool contains(const TYPE& type) const { return (std::find(container->begin(), container->end(), type) != container->end()); } - + template bool contains_if(PRED comp) const { return (std::find_if(container->begin(), container->end(), comp) != container->end()); } - + bool equals(const this_type& other) const { return equals(other, std::equal_to()); } - + template bool equals(const this_type& other, PRED comp) const { @@ -188,48 +188,48 @@ namespace Lucene return false; return std::equal(container->begin(), container->end(), other.container->begin(), comp); } - + int32_t hashCode() { return (int32_t)(int64_t)container.get(); } - + void swap(this_type& other) { container.swap(other->container); } - + TYPE& operator[] (int32_t pos) { return (*container)[pos]; } - + const TYPE& operator[] (int32_t pos) const { return (*container)[pos]; } - + operator bool() const { return container; } - + bool operator! () const { return !container; } - + bool operator== (const this_type& other) { return (container == other.container); } - + bool operator!= (const this_type& other) { return (container != other.container); } }; - + template Collection newCollection(const TYPE& a1) { @@ -237,7 +237,7 @@ namespace Lucene result.add(a1); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2) { @@ -245,7 +245,7 @@ namespace Lucene result.add(a2); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3) { @@ -253,7 +253,7 @@ namespace Lucene result.add(a3); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4) { @@ -261,7 +261,7 @@ namespace Lucene result.add(a4); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5) { @@ -269,7 +269,7 @@ namespace Lucene result.add(a5); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6) { @@ -277,7 +277,7 @@ namespace Lucene result.add(a6); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7) { @@ -285,7 +285,7 @@ namespace Lucene result.add(a7); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8) { @@ -293,7 +293,7 @@ namespace Lucene result.add(a8); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8, const TYPE& a9) { @@ -301,7 +301,7 @@ namespace Lucene result.add(a9); return result; } - + template Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8, const TYPE& a9, const TYPE& a10) { diff --git a/include/Config.h b/include/Config.h index 90c55790..89725fcd 100644 --- a/include/Config.h +++ b/include/Config.h @@ -77,6 +77,9 @@ // Define to enable cyclic checking in debug builds // #define LPP_USE_CYCLIC_CHECK +// Define to use custom allocator (useful in Windows builds and when using nedmalloc) +#define LPP_USE_ALLOCATOR + // Define to use nedmalloc memory allocator // #define LPP_USE_NEDMALLOC diff --git a/include/HashMap.h b/include/HashMap.h index a01fb551..2d40f5dd 100644 --- a/include/HashMap.h +++ b/include/HashMap.h @@ -19,19 +19,19 @@ namespace Lucene public: typedef HashMap this_type; typedef std::pair key_value; - typedef boost::unordered_map< KEY, VALUE, HASH, EQUAL, Allocator > map_type; + typedef boost::unordered_map< KEY, VALUE, HASH, EQUAL, LuceneAllocator > map_type; typedef typename map_type::iterator iterator; typedef typename map_type::const_iterator const_iterator; typedef KEY key_type; typedef VALUE value_type; - + virtual ~HashMap() { } - + protected: boost::shared_ptr mapContainer; - + public: static this_type newInstance() { @@ -39,114 +39,114 @@ namespace Lucene instance.mapContainer = Lucene::newInstance(); return instance; } - + void reset() { mapContainer.reset(); } - + int32_t size() const { return (int32_t)mapContainer->size(); } - + bool empty() const { return mapContainer->empty(); } - + void clear() { mapContainer->clear(); } - + iterator begin() { return mapContainer->begin(); } - + iterator end() { return mapContainer->end(); } - + const_iterator begin() const { return mapContainer->begin(); } - + const_iterator end() const { return mapContainer->end(); } - + operator bool() const { return mapContainer; } - + bool operator! () const { return !mapContainer; } - + map_type& operator= (const map_type& other) { mapContainer = other.mapContainer; return *this; } - + void put(const KEY& key, const VALUE& value) { (*mapContainer)[key] = value; } - + template void putAll(ITER first, ITER last) { for (iterator current = first; current != last; ++current) (*mapContainer)[current->first] = current->second; } - + template void remove(ITER pos) { mapContainer->erase(pos); } - + template ITER remove(ITER first, ITER last) { return mapContainer->erase(first, last); } - + bool remove(const KEY& key) { return (mapContainer->erase(key) > 0); } - + iterator find(const KEY& key) { return mapContainer->find(key); } - + VALUE get(const KEY& key) const { iterator findValue = mapContainer->find(key); return findValue == mapContainer->end() ? VALUE() : findValue->second; } - + bool contains(const KEY& key) const { return (mapContainer->find(key) != mapContainer->end()); } - + VALUE& operator[] (const KEY& key) { return (*mapContainer)[key]; } }; - + /// Utility template class to handle weak keyed maps template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > class WeakHashMap : public HashMap @@ -154,16 +154,16 @@ namespace Lucene public: typedef WeakHashMap this_type; typedef std::pair key_value; - typedef typename boost::unordered_map< KEY, VALUE, HASH, EQUAL, Allocator > map_type; + typedef typename boost::unordered_map< KEY, VALUE, HASH, EQUAL, LuceneAllocator > map_type; typedef typename map_type::iterator iterator; - + static this_type newInstance() { this_type instance; instance.mapContainer = Lucene::newInstance(); return instance; } - + void removeWeak() { if (!this->mapContainer || this->mapContainer->empty()) @@ -176,7 +176,7 @@ namespace Lucene } this->mapContainer->swap(clearCopy); } - + VALUE get(const KEY& key) { iterator findValue = this->mapContainer->find(key); diff --git a/include/HashSet.h b/include/HashSet.h index d65979a8..cefd5337 100644 --- a/include/HashSet.h +++ b/include/HashSet.h @@ -18,18 +18,18 @@ namespace Lucene { public: typedef HashSet this_type; - typedef boost::unordered_set< TYPE, HASH, EQUAL, Allocator > set_type; + typedef boost::unordered_set< TYPE, HASH, EQUAL, LuceneAllocator > set_type; typedef typename set_type::iterator iterator; typedef typename set_type::const_iterator const_iterator; typedef TYPE value_type; - + virtual ~HashSet() { } - + protected: boost::shared_ptr setContainer; - + public: static this_type newInstance() { @@ -37,7 +37,7 @@ namespace Lucene instance.setContainer = Lucene::newInstance(); return instance; } - + template static this_type newInstance(ITER first, ITER last) { @@ -45,84 +45,84 @@ namespace Lucene instance.setContainer = Lucene::newInstance(first, last); return instance; } - + void reset() { setContainer.reset(); } - + int32_t size() const { return (int32_t)setContainer->size(); } - + bool empty() const { return setContainer->empty(); } - + void clear() { setContainer->clear(); } - + iterator begin() { return setContainer->begin(); } - + iterator end() { return setContainer->end(); } - + const_iterator begin() const { return setContainer->begin(); } - + const_iterator end() const { return setContainer->end(); } - + operator bool() const { return setContainer; } - + bool operator! () const { return !setContainer; } - + set_type& operator= (const set_type& other) { setContainer = other.setContainer; return *this; } - + bool add(const TYPE& type) { return setContainer->insert(type).second; } - + template void addAll(ITER first, ITER last) { setContainer->insert(first, last); } - + bool remove(const TYPE& type) { return (setContainer->erase(type) > 0); } - + iterator find(const TYPE& type) { return setContainer->find(type); } - + bool contains(const TYPE& type) const { return (setContainer->find(type) != setContainer->end()); diff --git a/include/Lucene.h b/include/Lucene.h index 5303cd46..838785fa 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -35,7 +35,7 @@ using boost::uint64_t; #define SIZEOF_ARRAY(arr) (sizeof(arr) / sizeof((arr)[0])) #include "LuceneTypes.h" -#include "Allocator.h" +#include "LuceneAllocator.h" namespace boost { @@ -55,16 +55,16 @@ namespace boost namespace Lucene { - typedef std::basic_string< char, std::char_traits, Allocator > SingleString; - typedef std::basic_ostringstream< char, std::char_traits, Allocator > SingleStringStream; - typedef std::basic_string< wchar_t, std::char_traits, Allocator > String; - typedef std::basic_ostringstream< wchar_t, std::char_traits, Allocator > StringStream; - - const std::basic_string< wchar_t, std::char_traits, Allocator > EmptyString; - + typedef std::basic_string< char, std::char_traits, LuceneAllocator > SingleString; + typedef std::basic_ostringstream< char, std::char_traits, LuceneAllocator > SingleStringStream; + typedef std::basic_string< wchar_t, std::char_traits, LuceneAllocator > String; + typedef std::basic_ostringstream< wchar_t, std::char_traits, LuceneAllocator > StringStream; + + const std::basic_string< wchar_t, std::char_traits, LuceneAllocator > EmptyString; + typedef boost::shared_ptr filelockPtr; typedef boost::shared_ptr threadPtr; - + typedef boost::shared_ptr ofstreamPtr; typedef boost::shared_ptr ifstreamPtr; typedef boost::shared_ptr localePtr; @@ -87,7 +87,7 @@ namespace Lucene typedef Array LongArray; typedef Array CharArray; typedef Array DoubleArray; - + template struct luceneEquals { @@ -96,7 +96,7 @@ namespace Lucene return first ? first->equals(second) : (!first && !second); } }; - + template struct luceneEqualTo { @@ -107,7 +107,7 @@ namespace Lucene } const TYPE& equalType; }; - + template struct luceneWeakEquals { @@ -118,7 +118,7 @@ namespace Lucene return first.lock()->equals(second.lock()); } }; - + template struct luceneHash : std::unary_function { @@ -127,7 +127,7 @@ namespace Lucene return type ? type->hashCode() : 0; } }; - + template struct luceneWeakHash : std::unary_function { @@ -136,7 +136,7 @@ namespace Lucene return type.expired() ? 0 : type.lock()->hashCode(); } }; - + template struct luceneCompare { @@ -149,14 +149,14 @@ namespace Lucene return (first->compareTo(second) < 0); } }; - + typedef boost::blank VariantNull; typedef boost::variant FieldsData; typedef boost::variant ComparableValue; typedef boost::variant NumericValue; typedef boost::variant StringValue; typedef boost::variant, Collection, Collection, VariantNull> CollectionValue; - + typedef HashSet< SegmentInfoPtr, luceneHash, luceneEquals > SetSegmentInfo; typedef HashSet< MergeThreadPtr, luceneHash, luceneEquals > SetMergeThread; typedef HashSet< OneMergePtr, luceneHash, luceneEquals > SetOneMerge; @@ -165,7 +165,7 @@ namespace Lucene typedef HashSet< BooleanClausePtr, luceneHash, luceneEquals > SetBooleanClause; typedef HashSet< ReaderFieldPtr, luceneHash, luceneEquals > SetReaderField; typedef HashSet SetByteArray; - + typedef HashMap< String, String > MapStringString; typedef HashMap< wchar_t, NormalizeCharMapPtr > MapCharNormalizeCharMap; typedef HashMap< String, AnalyzerPtr > MapStringAnalyzer; @@ -186,7 +186,7 @@ namespace Lucene typedef HashMap< String, double > MapStringDouble; typedef HashMap< int32_t, CachePtr > MapStringCache; typedef HashMap< String, LockPtr > MapStringLock; - + typedef HashMap< SegmentInfoPtr, SegmentReaderPtr, luceneHash, luceneEquals > MapSegmentInfoSegmentReader; typedef HashMap< SegmentInfoPtr, int32_t, luceneHash, luceneEquals > MapSegmentInfoInt; typedef HashMap< DocFieldConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField; @@ -200,17 +200,17 @@ namespace Lucene typedef HashMap< EntryPtr, boost::any, luceneHash, luceneEquals > MapEntryAny; typedef HashMap< PhrasePositionsPtr, LuceneObjectPtr, luceneHash, luceneEquals > MapPhrasePositionsLuceneObject; typedef HashMap< ReaderFieldPtr, SetReaderField, luceneHash, luceneEquals > MapReaderFieldSetReaderField; - + typedef WeakHashMap< LuceneObjectWeakPtr, LuceneObjectPtr, luceneWeakHash, luceneWeakEquals > WeakMapObjectObject; typedef WeakHashMap< LuceneObjectWeakPtr, MapEntryAny, luceneWeakHash, luceneWeakEquals > WeakMapLuceneObjectMapEntryAny; - + typedef Map< String, AttributePtr > MapStringAttribute; typedef Map< int64_t, DocumentsWriterThreadStatePtr > MapThreadDocumentsWriterThreadState; typedef Map< String, IndexReaderPtr > MapStringIndexReader; typedef Map< TermPtr, NumPtr, luceneCompare > MapTermNum; - + typedef boost::function TermVectorEntryComparator; - + template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > class SimpleLRUCache; typedef SimpleLRUCache< TermPtr, TermInfoPtr, luceneHash, luceneEquals > TermInfoCache; typedef boost::shared_ptr TermInfoCachePtr; diff --git a/include/Allocator.h b/include/LuceneAllocator.h similarity index 62% rename from include/Allocator.h rename to include/LuceneAllocator.h index 4c356feb..41240da2 100644 --- a/include/Allocator.h +++ b/include/LuceneAllocator.h @@ -13,24 +13,26 @@ namespace Lucene { /// Allocate block of memory. LPPAPI void* AllocMemory(size_t size); - + /// Reallocate a given block of memory. LPPAPI void* ReallocMemory(void* memory, size_t size); - + /// Release a given block of memory. LPPAPI void FreeMemory(void* memory); - + /// Release thread cache. Note: should be called whenever a thread /// exits and using nedmalloc. LPPAPI void ReleaseThreadCache(); - + + #ifdef LPP_USE_ALLOCATOR + /// Custom stl allocator used to help exporting stl container across process /// borders. It can also calls custom memory allocation functions that can /// help track memory leaks and/or improve performance over standard allocators. /// @see #AllocMemory(size_t) /// @see #FreeMemory(void*) template - class Allocator + class LuceneAllocator { public: typedef size_t size_type; @@ -41,106 +43,112 @@ namespace Lucene typedef const TYPE& const_reference; typedef TYPE value_type; - Allocator() + LuceneAllocator() { } - - Allocator(const Allocator&) + + LuceneAllocator(const LuceneAllocator&) { } - pointer allocate(size_type n, const void* = 0) + pointer allocate(size_type n, const void* = 0) { return (TYPE*)AllocMemory((size_t)(n * sizeof(TYPE))); } - void deallocate(void* p, size_type) + void deallocate(void* p, size_type) { - if (p != NULL) + if (p != NULL) FreeMemory(p); } - pointer address(reference x) const - { - return &x; + pointer address(reference x) const + { + return &x; } - const_pointer address(const_reference x) const - { - return &x; + const_pointer address(const_reference x) const + { + return &x; } - Allocator& operator= (const Allocator&) - { - return *this; + LuceneAllocator& operator= (const LuceneAllocator&) + { + return *this; } void construct(pointer p, const TYPE& val) { - new ((TYPE*)p) TYPE(val); + new ((TYPE*)p) TYPE(val); } - void destroy(pointer p) - { + void destroy(pointer p) + { p->~TYPE(); } - size_type max_size() const - { - return size_t(-1); + size_type max_size() const + { + return size_t(-1); } template - struct rebind - { - typedef Allocator other; + struct rebind + { + typedef LuceneAllocator other; }; template - Allocator(const Allocator&) + LuceneAllocator(const LuceneAllocator&) { } }; template - inline bool operator== (const Allocator&, const Allocator&) - { - return true; + inline bool operator== (const LuceneAllocator&, const LuceneAllocator&) + { + return true; } - + template - inline bool operator!= (const Allocator&, const Allocator&) - { - return false; + inline bool operator!= (const LuceneAllocator&, const LuceneAllocator&) + { + return false; } template <> - class Allocator + class LuceneAllocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; - Allocator() + LuceneAllocator() { } - - Allocator(const Allocator&) + + LuceneAllocator(const LuceneAllocator&) { } template - struct rebind - { - typedef Allocator other; + struct rebind + { + typedef LuceneAllocator other; }; template - Allocator(const Allocator&) + LuceneAllocator(const LuceneAllocator&) { } }; + + #endif } +#ifndef LPP_USE_ALLOCATOR +#define LuceneAllocator std::allocator +#endif + #endif diff --git a/include/LuceneFactory.h b/include/LuceneFactory.h index 6424d2a0..7e4f817c 100644 --- a/include/LuceneFactory.h +++ b/include/LuceneFactory.h @@ -18,7 +18,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T); #else - return boost::allocate_shared(Allocator()); + return boost::allocate_shared(LuceneAllocator()); #endif } @@ -28,7 +28,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1)); #else - return boost::allocate_shared(Allocator(), a1); + return boost::allocate_shared(LuceneAllocator(), a1); #endif } @@ -38,7 +38,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2)); #else - return boost::allocate_shared(Allocator(), a1, a2); + return boost::allocate_shared(LuceneAllocator(), a1, a2); #endif } @@ -48,7 +48,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3)); #else - return boost::allocate_shared(Allocator(), a1, a2, a3); + return boost::allocate_shared(LuceneAllocator(), a1, a2, a3); #endif } @@ -58,7 +58,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4)); #else - return boost::allocate_shared(Allocator(), a1, a2, a3, a4); + return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4); #endif } @@ -68,7 +68,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5)); #else - return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5); + return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5); #endif } @@ -78,7 +78,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6)); #else - return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6); + return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6); #endif } @@ -88,7 +88,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7)); #else - return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6, a7); + return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6, a7); #endif } @@ -98,7 +98,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8)); #else - return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6, a7, a8); + return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6, a7, a8); #endif } @@ -108,7 +108,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9)); #else - return boost::allocate_shared(Allocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9); + return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9); #endif } diff --git a/include/Map.h b/include/Map.h index db466e5c..c7dabcdf 100644 --- a/include/Map.h +++ b/include/Map.h @@ -19,19 +19,19 @@ namespace Lucene public: typedef Map this_type; typedef std::pair key_value; - typedef std::map< KEY, VALUE, LESS, Allocator > map_type; + typedef std::map< KEY, VALUE, LESS, LuceneAllocator > map_type; typedef typename map_type::iterator iterator; typedef typename map_type::const_iterator const_iterator; typedef KEY key_type; typedef VALUE value_type; - + virtual ~Map() { } - + protected: boost::shared_ptr mapContainer; - + public: static this_type newInstance() { @@ -39,108 +39,108 @@ namespace Lucene instance.mapContainer = Lucene::newInstance(); return instance; } - + void reset() { mapContainer.reset(); } - + int32_t size() const { return (int32_t)mapContainer->size(); } - + bool empty() const { return mapContainer->empty(); } - + void clear() { mapContainer->clear(); } - + iterator begin() { return mapContainer->begin(); } - + iterator end() { return mapContainer->end(); } - + const_iterator begin() const { return mapContainer->begin(); } - + const_iterator end() const { return mapContainer->end(); } - + operator bool() const { return mapContainer; } - + bool operator! () const { return !mapContainer; } - + map_type& operator= (const map_type& other) { mapContainer = other.mapContainer; return *this; } - + void put(const KEY& key, const VALUE& value) { (*mapContainer)[key] = value; } - + template void putAll(ITER first, ITER last) { for (iterator current = first; current != last; ++current) (*mapContainer)[current->first] = current->second; } - + template void remove(ITER pos) { mapContainer->erase(pos); } - + template ITER remove(ITER first, ITER last) { return mapContainer->erase(first, last); } - + bool remove(const KEY& key) { return (mapContainer->erase(key) > 0); } - + iterator find(const KEY& key) { return mapContainer->find(key); } - + VALUE get(const KEY& key) const { iterator findValue = mapContainer->find(key); return findValue == mapContainer->end() ? VALUE() : findValue->second; } - + bool contains(const KEY& key) const { return (mapContainer->find(key) != mapContainer->end()); } - + VALUE& operator[] (const KEY& key) { return (*mapContainer)[key]; diff --git a/include/PriorityQueue.h b/include/PriorityQueue.h index fb67bb03..318e1df2 100644 --- a/include/PriorityQueue.h +++ b/include/PriorityQueue.h @@ -12,7 +12,7 @@ namespace Lucene { - /// A PriorityQueue maintains a partial ordering of its elements such that the least element can always + /// A PriorityQueue maintains a partial ordering of its elements such that the least element can always /// be found in constant time. Put()'s and pop()'s require log(size) time. /// /// NOTE: This class pre-allocates a full array of length maxSize + 1. @@ -20,14 +20,14 @@ namespace Lucene class PriorityQueue : public LuceneObject { public: - typedef typename std::vector< TYPE, Allocator > heap_type; - + typedef typename std::vector< TYPE, LuceneAllocator > heap_type; + PriorityQueue(int32_t maxSize) { this->_size = 0; this->_maxSize = maxSize; } - + virtual ~PriorityQueue() { } @@ -36,12 +36,12 @@ namespace Lucene heap_type heap; int32_t _size; int32_t _maxSize; - + public: virtual void initialize() { bool empty = heap.empty(); - + if (empty) { int32_t heapSize = 0; @@ -53,8 +53,8 @@ namespace Lucene else if (_maxSize == INT_MAX) { // Don't wrap heapSize to -1, in this case, which causes a confusing NegativeArraySizeException. - // Note that very likely this will simply then hit an OOME, but at least that's more indicative - // to caller that this values is too big. We don't +1 in this case, but it's very unlikely in + // Note that very likely this will simply then hit an OOME, but at least that's more indicative + // to caller that this values is too big. We don't +1 in this case, but it's very unlikely in // practice one will actually insert this many objects into the PQ heapSize = INT_MAX; } @@ -65,7 +65,7 @@ namespace Lucene } this->heap.resize(heapSize); } - + // If sentinel objects are supported, populate the queue with them TYPE sentinel = getSentinelObject(); if (empty && sentinel) @@ -76,14 +76,14 @@ namespace Lucene _size = _maxSize; } } - + /// Return maximum size of queue int32_t maxSize() { return _maxSize; } - - /// Adds an Object to a PriorityQueue in log(size) time. If one tries to add more objects + + /// Adds an Object to a PriorityQueue in log(size) time. If one tries to add more objects /// than maxSize from initialize an {@link IndexOutOfBoundsException} is thrown. TYPE add(const TYPE& type) { @@ -94,10 +94,10 @@ namespace Lucene upHeap(); return heap[1]; } - - /// Adds an Object to a PriorityQueue in log(size) time. It returns the object (if any) that was - /// dropped off the heap because it was full. This can be the given parameter (in case it is - /// smaller than the full heap's minimum, and couldn't be added), or another object that was + + /// Adds an Object to a PriorityQueue in log(size) time. It returns the object (if any) that was + /// dropped off the heap because it was full. This can be the given parameter (in case it is + /// smaller than the full heap's minimum, and couldn't be added), or another object that was /// previously the smallest value in the heap and now has been replaced by a larger one, or null /// if the queue wasn't yet full with maxSize elements. TYPE addOverflow(const TYPE& type) @@ -117,15 +117,15 @@ namespace Lucene else return type; } - + /// Returns the least element of the PriorityQueue. TYPE top() { - // We don't need to check size here: if maxSize is 0, then heap is length 2 array with both + // We don't need to check size here: if maxSize is 0, then heap is length 2 array with both // entries null. If size is 0 then heap[1] is already null. return heap[1]; } - + /// Removes and returns the least element of the PriorityQueue. TYPE pop() { @@ -140,26 +140,26 @@ namespace Lucene else return TYPE(); } - + /// Should be called when the Object at top changes values. TYPE updateTop() { downHeap(); return heap[1]; } - + /// Returns the number of elements currently stored in the PriorityQueue. int32_t size() const { return _size; } - + /// Returns whether PriorityQueue is currently empty. bool empty() const { return (_size == 0); } - + /// Removes all entries from the PriorityQueue. void clear() { @@ -167,7 +167,7 @@ namespace Lucene heap[i] = TYPE(); _size = 0; } - + protected: void upHeap() { @@ -182,7 +182,7 @@ namespace Lucene } heap[i] = node; // install saved node } - + void downHeap() { int32_t i = 1; @@ -202,18 +202,18 @@ namespace Lucene } heap[i] = node; // install saved node } - + /// Determines the ordering of objects in this priority queue. Subclasses must define this one method. virtual bool lessThan(const TYPE& first, const TYPE& second) { return std::less()(first, second); } - - /// This method can be overridden by extending classes to return a sentinel object which will be used by - /// {@link #initialize} to fill the queue, so that the code which uses that queue can always assume it's + + /// This method can be overridden by extending classes to return a sentinel object which will be used by + /// {@link #initialize} to fill the queue, so that the code which uses that queue can always assume it's /// full and only change the top without attempting to insert any new object. /// - /// Those sentinel values should always compare worse than any non-sentinel value (ie., {@link #lessThan} + /// Those sentinel values should always compare worse than any non-sentinel value (ie., {@link #lessThan} /// should always favour the non-sentinel values). virtual TYPE getSentinelObject() { diff --git a/include/Set.h b/include/Set.h index 911c718a..bc62f170 100644 --- a/include/Set.h +++ b/include/Set.h @@ -18,18 +18,18 @@ namespace Lucene { public: typedef Set this_type; - typedef std::set< TYPE, LESS, Allocator > set_type; + typedef std::set< TYPE, LESS, LuceneAllocator > set_type; typedef typename set_type::iterator iterator; typedef typename set_type::const_iterator const_iterator; typedef TYPE value_type; - + virtual ~Set() { } - + protected: boost::shared_ptr setContainer; - + public: static this_type newInstance() { @@ -37,7 +37,7 @@ namespace Lucene instance.setContainer = Lucene::newInstance(); return instance; } - + template static this_type newInstance(ITER first, ITER last) { @@ -45,78 +45,78 @@ namespace Lucene instance.setContainer = Lucene::newInstance(first, last); return instance; } - + void reset() { setContainer.reset(); } - + int32_t size() const { return (int32_t)setContainer->size(); } - + bool empty() const { return setContainer->empty(); } - + void clear() { setContainer->clear(); } - + iterator begin() { return setContainer->begin(); } - + iterator end() { return setContainer->end(); } - + const_iterator begin() const { return setContainer->begin(); } - + const_iterator end() const { return setContainer->end(); } - + bool add(const TYPE& type) { return setContainer->insert(type).second; } - + template void addAll(ITER first, ITER last) { setContainer->insert(first, last); } - + bool remove(const TYPE& type) { return (setContainer->erase(type) > 0); } - + iterator find(const TYPE& type) { return setContainer->find(type); } - + bool contains(const TYPE& type) const { return (setContainer->find(type) != setContainer->end()); } - + bool equals(const this_type& other) const { return equals(other, std::equal_to()); } - + template bool equals(const this_type& other, PRED comp) const { @@ -124,27 +124,27 @@ namespace Lucene return false; return std::equal(setContainer->begin(), setContainer->end(), other.setContainer->begin(), comp); } - + void swap(this_type& other) { setContainer.swap(other->setContainer); } - + operator bool() const { return setContainer; } - + bool operator! () const { return !setContainer; } - + bool operator== (const this_type& other) { return (setContainer == other.setContainer); } - + bool operator!= (const this_type& other) { return (setContainer != other.setContainer); diff --git a/include/SimpleLRUCache.h b/include/SimpleLRUCache.h index 00542819..8b6ab822 100644 --- a/include/SimpleLRUCache.h +++ b/include/SimpleLRUCache.h @@ -22,18 +22,18 @@ namespace Lucene typedef std::pair key_value; typedef std::list< key_value > key_list; typedef typename key_list::const_iterator const_iterator; - typedef boost::unordered_map< KEY, typename key_list::iterator, HASH, EQUAL, Allocator< std::pair > > map_type; + typedef boost::unordered_map< KEY, typename key_list::iterator, HASH, EQUAL, LuceneAllocator< std::pair > > map_type; typedef typename map_type::const_iterator map_iterator; - + SimpleLRUCache(int32_t cacheSize) { this->cacheSize = cacheSize; } - + virtual ~SimpleLRUCache() { } - + protected: int32_t cacheSize; key_list cacheList; @@ -44,38 +44,38 @@ namespace Lucene { cacheList.push_front(std::make_pair(key, value)); cacheMap[key] = cacheList.begin(); - + if ((int32_t)cacheList.size() > cacheSize) { cacheMap.erase(cacheList.back().first); cacheList.pop_back(); } } - + VALUE get(const KEY& key) { map_iterator find = cacheMap.find(key); if (find == cacheMap.end()) return VALUE(); - + VALUE value(find->second->second); cacheList.erase(find->second); cacheList.push_front(std::make_pair(key, value)); cacheMap[key] = cacheList.begin(); - + return value; } - + bool contains(const KEY& key) const { return (cacheMap.find(key) != cacheMap.end()); } - + int32_t size() const { return (int32_t)cacheList.size(); } - + const_iterator begin() const { return cacheList.begin(); diff --git a/src/core/msvc/lucene++.vcproj b/src/core/msvc/lucene++.vcproj index 0a415bf4..390c7bb6 100644 --- a/src/core/msvc/lucene++.vcproj +++ b/src/core/msvc/lucene++.vcproj @@ -3520,11 +3520,11 @@ Name="platform" > Date: Thu, 26 Jul 2012 17:53:32 +0200 Subject: [PATCH 012/157] Patch Config.h from CMake options --- CMakeLists.txt | 21 ++++++++++++++++----- include/{Config.h => Config.h.cmake} | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) rename include/{Config.h => Config.h.cmake} (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 35328f2c..5fc7ff66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,14 +76,18 @@ OPTION(ENABLE_CYCLIC_CHECK SET(LIB_DESTINATION "lib" CACHE STRING "Define lib output directory name") IF ( ENABLE_NEDMALLOC ) - ADD_DEFINITIONS(-DLPP_USE_NEDMALLOC) + SET(DEFINE_USE_NEDMALLOC "define") +ELSE ( ENABLE_NEDMALLOC ) + SET(DEFINE_USE_NEDMALLOC "undef") ENDIF ( ENABLE_NEDMALLOC ) + IF ( ENABLE_CYCLIC_CHECK ) - ADD_DEFINITIONS(-DLPP_USE_CYCLIC_CHECK) + SET(DEFINE_USE_CYCLIC_CHECK "define") +ELSE ( ENABLE_CYCLIC_CHECK ) + SET(DEFINE_USE_CYCLIC_CHECK "undef") ENDIF ( ENABLE_CYCLIC_CHECK ) #################################### - #################################### # PLATFORM specific options #################################### @@ -149,6 +153,15 @@ INCLUDE(PCHSupport) #todo: make this optional and make it possible to add more headers - like boost threads +################################# +# generate Config.h +################################# + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/Config.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/include/Config.h @ONLY) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/include) + #################################### # The subdirs #################################### @@ -158,7 +171,6 @@ ADD_SUBDIRECTORY (src/contrib) ADD_SUBDIRECTORY (src/demo EXCLUDE_FROM_ALL) ADD_SUBDIRECTORY (src/test) - ################################# # install pkg-config file ################################# @@ -174,7 +186,6 @@ IF(NOT WIN32) DESTINATION ${LIB_DESTINATION}/pkgconfig ) ENDIF(NOT WIN32) - #################################### # Custom targets #################################### diff --git a/include/Config.h b/include/Config.h.cmake similarity index 96% rename from include/Config.h rename to include/Config.h.cmake index 89725fcd..5f2cb765 100644 --- a/include/Config.h +++ b/include/Config.h.cmake @@ -75,13 +75,13 @@ #endif // Define to enable cyclic checking in debug builds -// #define LPP_USE_CYCLIC_CHECK +#@DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK // Define to use custom allocator (useful in Windows builds and when using nedmalloc) #define LPP_USE_ALLOCATOR // Define to use nedmalloc memory allocator -// #define LPP_USE_NEDMALLOC +#@DEFINE_USE_NEDMALLOC@ LPP_USE_NEDMALLOC #ifdef LPP_USE_NEDMALLOC #define EXTSPEC LPPAPI From 4f4400b7667c0e63c8712e6238dd1c4ecbb3f116 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Thu, 26 Jul 2012 17:54:56 +0200 Subject: [PATCH 013/157] Add CMake option for LPP_USE_ALLOCATOR --- CMakeLists.txt | 6 ++++++ include/Config.h.cmake | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fc7ff66..ec89210e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,12 @@ ELSE ( ENABLE_NEDMALLOC ) SET(DEFINE_USE_NEDMALLOC "undef") ENDIF ( ENABLE_NEDMALLOC ) +IF ( ENABLE_STANDARD_ALLOCATOR ) + SET(DEFINE_USE_ALLOCATOR "undef") +ELSE ( ENABLE_STANDARD_ALLOCATOR ) + SET(DEFINE_USE_ALLOCATOR "define") +ENDIF ( ENABLE_STANDARD_ALLOCATOR ) + IF ( ENABLE_CYCLIC_CHECK ) SET(DEFINE_USE_CYCLIC_CHECK "define") ELSE ( ENABLE_CYCLIC_CHECK ) diff --git a/include/Config.h.cmake b/include/Config.h.cmake index 5f2cb765..08006207 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -78,7 +78,7 @@ #@DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK // Define to use custom allocator (useful in Windows builds and when using nedmalloc) -#define LPP_USE_ALLOCATOR +#@DEFINE_USE_ALLOCATOR@ LPP_USE_ALLOCATOR // Define to use nedmalloc memory allocator #@DEFINE_USE_NEDMALLOC@ LPP_USE_NEDMALLOC From 4907246249c9c75c996a2df862eef418a70a49c3 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Thu, 26 Jul 2012 17:55:24 +0200 Subject: [PATCH 014/157] Properly use LIB_DESTINATION in pkg-config files --- liblucene++-contrib.pc.cmake | 4 ++-- liblucene++.pc.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/liblucene++-contrib.pc.cmake b/liblucene++-contrib.pc.cmake index 8e02e3e5..f0aa77c4 100644 --- a/liblucene++-contrib.pc.cmake +++ b/liblucene++-contrib.pc.cmake @@ -1,13 +1,13 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix}/bin -libdir=${prefix}/@LIB_DESTINATION@ +libdir=@LIB_DESTINATION@ includedir=${prefix}/include/lucene++ lib=lucene++-contrib Name: liblucene++-contrib Description: Contributions for Lucene++ - a C++ search engine, ported from the popular Apache Lucene Version: @LUCENE++_VERSION@ -Libs: -L${prefix}/@LIB_DESTINATION@/ -l${lib} +Libs: -L@LIB_DESTINATION@/ -l${lib} Cflags: -I${includedir} Requires: liblucene++=@LUCENE++_VERSION@ ~ diff --git a/liblucene++.pc.cmake b/liblucene++.pc.cmake index 3fc09176..2e53c02d 100644 --- a/liblucene++.pc.cmake +++ b/liblucene++.pc.cmake @@ -1,13 +1,13 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix}/bin -libdir=${prefix}/@LIB_DESTINATION@ +libdir=@LIB_DESTINATION@ includedir=${prefix}/include/lucene++ lib=lucene++ Name: liblucene++ Description: Lucene++ - a C++ search engine, ported from the popular Apache Lucene Version: @LUCENE++_VERSION@ -Libs: -L${prefix}/@LIB_DESTINATION@/ -l${lib} +Libs: -L@LIB_DESTINATION@ -l${lib} Cflags: -I${includedir} ~ From 05e98a07cff2a746bc612e5df66552644e86f632 Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Tue, 31 Jul 2012 11:47:34 +0200 Subject: [PATCH 015/157] Also install generated Config.h --- src/core/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c839f563..a77c12fb 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -13,7 +13,8 @@ file(GLOB_RECURSE lucene_sources ${lucene++-lib_SOURCE_DIR}/util/*.cpp) file(GLOB_RECURSE INTERN_HEADERS ${lucene++-libs_SOURCE_DIR}/include/*.h) -file(GLOB_RECURSE HEADERS ${lucene++-base_SOURCE_DIR}/include/*.h) +file(GLOB_RECURSE HEADERS ${lucene++-base_SOURCE_DIR}/include/*.h + ${lucene++-base_BINARY_DIR}/include/*.h) #C sources... file(GLOB_RECURSE lucene_c_sources From 2446b8e4d1746af61c913330cc529c36ec1d1a57 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 17 Aug 2012 09:27:47 +0200 Subject: [PATCH 016/157] Amend README to reflect recent changes to CMake/Config.h --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 163d4372..029027ab 100644 --- a/README.rst +++ b/README.rst @@ -42,7 +42,7 @@ On Debian systems, the following packages are required: Build Instructions using Waf ------------------------------ -Alternatively you can use `Waf `_ to drive the build. Waf requires that you have a recent version of `Python `_ installed on your system. +**After running CMake** you can use `Waf `_ to drive the build. Waf requires that you have a recent version of `Python `_ installed on your system. To build the library the following commands should be issued:: @@ -70,7 +70,7 @@ Open solution lucene++.sln located in the *msvc* folder into Visual Studio 2008 **Note: "BOOST_ROOT" environment variable must be defined to point to the boost library directory (eg. c:\\boost_1_44_0)** -You'll need boost installed. +You'll need boost installed. `BoostPro `_ has some precompiled windows packages. You'll need the following extras installed:: From 77077f9796d733b32e5de85c0d73511003c3cd32 Mon Sep 17 00:00:00 2001 From: Charlie Root Date: Sat, 15 Sep 2012 15:11:12 +0700 Subject: [PATCH 017/157] Fix compilation under FreeBSD --- src/core/document/NumberTools.cpp | 8 ++++---- src/core/index/LogByteSizeMergePolicy.cpp | 2 +- src/core/index/LogDocMergePolicy.cpp | 2 +- src/core/search/FieldCacheRangeFilter.cpp | 2 +- src/core/search/NumericRangeQuery.cpp | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/document/NumberTools.cpp b/src/core/document/NumberTools.cpp index 64eac0f8..ff1cab40 100644 --- a/src/core/document/NumberTools.cpp +++ b/src/core/document/NumberTools.cpp @@ -50,7 +50,7 @@ namespace Lucene String NumberTools::longToString(int64_t l) { - if (l == LLONG_MIN) + if (l == std::numeric_limits::min()) { // special case, because long is not symmetric around zero return MIN_STRING_VALUE(); @@ -62,7 +62,7 @@ namespace Lucene if (l < 0) { buf += NEGATIVE_PREFIX; - l = LLONG_MAX + l + 1; + l = std::numeric_limits::max() + l + 1; } buf += POSITIVE_PREFIX; @@ -81,7 +81,7 @@ namespace Lucene boost::throw_exception(NumberFormatException(L"string is the wrong size")); if (str == MIN_STRING_VALUE()) - return LLONG_MIN; + return std::numeric_limits::min(); wchar_t prefix = str[0]; int64_t l = StringUtils::toLong(str.substr(1), RADIX); @@ -90,7 +90,7 @@ namespace Lucene { // nop } else if (prefix == NEGATIVE_PREFIX) - l = l - LLONG_MAX - 1; + l = l - std::numeric_limits::max() - 1; else boost::throw_exception(NumberFormatException(L"string does not begin with the correct prefix")); diff --git a/src/core/index/LogByteSizeMergePolicy.cpp b/src/core/index/LogByteSizeMergePolicy.cpp index cfa0ede4..4bcbfa69 100644 --- a/src/core/index/LogByteSizeMergePolicy.cpp +++ b/src/core/index/LogByteSizeMergePolicy.cpp @@ -19,7 +19,7 @@ namespace Lucene LogByteSizeMergePolicy::LogByteSizeMergePolicy(IndexWriterPtr writer) : LogMergePolicy(writer) { minMergeSize = (int64_t)(DEFAULT_MIN_MERGE_MB * 1024 * 1024); - maxMergeSize = DEFAULT_MAX_MERGE_MB == DBL_MAX ? LLONG_MAX : (int64_t)(DEFAULT_MAX_MERGE_MB * 1024 * 1024); + maxMergeSize = DEFAULT_MAX_MERGE_MB == DBL_MAX ? std::numeric_limits::max() : (int64_t)(DEFAULT_MAX_MERGE_MB * 1024 * 1024); } LogByteSizeMergePolicy::~LogByteSizeMergePolicy() diff --git a/src/core/index/LogDocMergePolicy.cpp b/src/core/index/LogDocMergePolicy.cpp index c2c90b0d..8d70ece2 100644 --- a/src/core/index/LogDocMergePolicy.cpp +++ b/src/core/index/LogDocMergePolicy.cpp @@ -17,7 +17,7 @@ namespace Lucene minMergeSize = DEFAULT_MIN_MERGE_DOCS; // maxMergeSize is never used by LogDocMergePolicy; set it to LLONG_MAX to disable it - maxMergeSize = LLONG_MAX; + maxMergeSize = std::numeric_limits::max(); } LogDocMergePolicy::~LogDocMergePolicy() diff --git a/src/core/search/FieldCacheRangeFilter.cpp b/src/core/search/FieldCacheRangeFilter.cpp index d13c4ccf..ce82a28a 100644 --- a/src/core/search/FieldCacheRangeFilter.cpp +++ b/src/core/search/FieldCacheRangeFilter.cpp @@ -215,7 +215,7 @@ namespace Lucene } FieldCacheRangeFilterLong::FieldCacheRangeFilterLong(const String& field, ParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) - : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, LLONG_MAX, includeLower, includeUpper) + : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::max(), includeLower, includeUpper) { } diff --git a/src/core/search/NumericRangeQuery.cpp b/src/core/search/NumericRangeQuery.cpp index bb3d1893..1326a6c5 100644 --- a/src/core/search/NumericRangeQuery.cpp +++ b/src/core/search/NumericRangeQuery.cpp @@ -202,27 +202,27 @@ namespace Lucene case 64: { // lower - int64_t minBound = LLONG_MIN; + int64_t minBound = std::numeric_limits::min(); if (VariantUtils::typeOf(query->min)) minBound = VariantUtils::get(query->min); else if (VariantUtils::typeOf(query->min)) minBound = NumericUtils::doubleToSortableLong(VariantUtils::get(query->min)); if (!query->minInclusive && !VariantUtils::isNull(query->min)) { - if (minBound == LLONG_MAX) + if (minBound == std::numeric_limits::max()) break; ++minBound; } // upper - int64_t maxBound = LLONG_MAX; + int64_t maxBound = std::numeric_limits::max(); if (VariantUtils::typeOf(query->max)) maxBound = VariantUtils::get(query->max); else if (VariantUtils::typeOf(query->max)) maxBound = NumericUtils::doubleToSortableLong(VariantUtils::get(query->max)); if (!query->maxInclusive && !VariantUtils::isNull(query->max)) { - if (maxBound == LLONG_MIN) + if (maxBound == std::numeric_limits::min()) break; --maxBound; } From c39e21115871768325f699340ebbdd9c4b1e0cf5 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 20 Sep 2012 07:08:53 +0200 Subject: [PATCH 018/157] Remove unnecessary int32_t cast. --- src/core/index/MultiLevelSkipListReader.cpp | 74 ++++++++++----------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/core/index/MultiLevelSkipListReader.cpp b/src/core/index/MultiLevelSkipListReader.cpp index 3567ea4b..b37342e0 100644 --- a/src/core/index/MultiLevelSkipListReader.cpp +++ b/src/core/index/MultiLevelSkipListReader.cpp @@ -19,7 +19,7 @@ namespace Lucene this->haveSkipped = false; this->lastDoc = 0; this->lastChildPointer = 0; - + this->skipStream = Collection::newInstance(maxSkipLevels); this->skipPointer = Collection::newInstance(maxSkipLevels); this->childPointer = Collection::newInstance(maxSkipLevels); @@ -30,28 +30,28 @@ namespace Lucene this->inputIsBuffered = boost::dynamic_pointer_cast(skipStream); this->skipInterval[0] = skipInterval; this->skipDoc = Collection::newInstance(maxSkipLevels); - + MiscUtils::arrayFill(this->skipPointer.begin(), 0, this->skipPointer.size(), 0); MiscUtils::arrayFill(this->childPointer.begin(), 0, this->childPointer.size(), 0); MiscUtils::arrayFill(this->numSkipped.begin(), 0, this->numSkipped.size(), 0); MiscUtils::arrayFill(this->skipDoc.begin(), 0, this->skipDoc.size(), 0); - + for (int32_t i = 1; i < maxSkipLevels; ++i) { // cache skip intervals this->skipInterval[i] = this->skipInterval[i - 1] * skipInterval; } } - + MultiLevelSkipListReader::~MultiLevelSkipListReader() { } - + int32_t MultiLevelSkipListReader::getDoc() { return lastDoc; } - + int32_t MultiLevelSkipListReader::skipTo(int32_t target) { if (!haveSkipped) @@ -60,12 +60,12 @@ namespace Lucene loadSkipLevels(); haveSkipped = true; } - + // walk up the levels until highest level is found that has a skip for this target int32_t level = 0; while (level < numberOfSkipLevels - 1 && target > skipDoc[level + 1]) ++level; - + while (level >= 0) { if (target > skipDoc[level]) @@ -76,22 +76,22 @@ namespace Lucene else { // no more skips on this level, go down one level - if (level > 0 && lastChildPointer > (int32_t)skipStream[level - 1]->getFilePointer()) + if (level > 0 && lastChildPointer > skipStream[level - 1]->getFilePointer()) seekChild(level - 1); --level; } } - + return numSkipped[0] - skipInterval[0] - 1; } - + bool MultiLevelSkipListReader::loadNextSkip(int32_t level) { // we have to skip, the target document is greater than the current skip list entry setLastSkipData(level); - + numSkipped[level] += skipInterval[level]; - + if (numSkipped[level] > docCount) { // this skip list is exhausted @@ -100,19 +100,19 @@ namespace Lucene numberOfSkipLevels = level; return false; } - + // read next skip entry skipDoc[level] += readSkipData(level, skipStream[level]); - + if (level != 0) { // read the child pointer if we are not on the leaf level childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; } - + return true; } - + void MultiLevelSkipListReader::seekChild(int32_t level) { skipStream[level]->seek(lastChildPointer); @@ -121,7 +121,7 @@ namespace Lucene if (level > 0) childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; } - + void MultiLevelSkipListReader::close() { for (Collection::iterator skip = skipStream.begin(); skip != skipStream.end(); ++skip) @@ -130,7 +130,7 @@ namespace Lucene (*skip)->close(); } } - + void MultiLevelSkipListReader::init(int64_t skipPointer, int32_t df) { this->skipPointer[0] = skipPointer; @@ -138,30 +138,30 @@ namespace Lucene MiscUtils::arrayFill(skipDoc.begin(), 0, skipDoc.size(), 0); MiscUtils::arrayFill(numSkipped.begin(), 0, numSkipped.size(), 0); MiscUtils::arrayFill(childPointer.begin(), 0, childPointer.size(), 0); - + haveSkipped = false; for (int32_t i = 1; i < numberOfSkipLevels; ++i) skipStream[i].reset(); } - + void MultiLevelSkipListReader::loadSkipLevels() { numberOfSkipLevels = docCount == 0 ? 0 : (int32_t)std::floor(std::log((double)docCount) / std::log((double)skipInterval[0])); if (numberOfSkipLevels > maxNumberOfSkipLevels) numberOfSkipLevels = maxNumberOfSkipLevels; - + skipStream[0]->seek(skipPointer[0]); - + int32_t toBuffer = numberOfLevelsToBuffer; - + for (int32_t i = numberOfSkipLevels - 1; i > 0; --i) { // the length of the current level int64_t length = skipStream[0]->readVLong(); - + // the start pointer of the current level skipPointer[i] = skipStream[0]->getFilePointer(); - + if (toBuffer > 0) { // buffer this level @@ -174,22 +174,22 @@ namespace Lucene skipStream[i] = boost::dynamic_pointer_cast(skipStream[0]->clone()); if (inputIsBuffered && length < BufferedIndexInput::BUFFER_SIZE) boost::dynamic_pointer_cast(skipStream[i])->setBufferSize((int32_t)length); - + // move base stream beyond the current level skipStream[0]->seek(skipStream[0]->getFilePointer() + length); } } - + // use base stream for the lowest level skipPointer[0] = skipStream[0]->getFilePointer(); } - + void MultiLevelSkipListReader::setLastSkipData(int32_t level) { lastDoc = skipDoc[level]; lastChildPointer = childPointer[level]; } - + SkipBuffer::SkipBuffer(IndexInputPtr input, int32_t length) { pos = 0; @@ -197,37 +197,37 @@ namespace Lucene pointer = input->getFilePointer(); input->readBytes(data.get(), 0, length); } - + SkipBuffer::~SkipBuffer() { } - + void SkipBuffer::close() { data.reset(); } - + int64_t SkipBuffer::getFilePointer() { return (pointer + pos); } - + int64_t SkipBuffer::length() { return data.size(); } - + uint8_t SkipBuffer::readByte() { return data[pos++]; } - + void SkipBuffer::readBytes(uint8_t* b, int32_t offset, int32_t length) { MiscUtils::arrayCopy(data.get(), pos, b, offset, length); pos += length; } - + void SkipBuffer::seek(int64_t pos) { this->pos = (int32_t)(pos - pointer); From 5170153646cbc69585236295240d2658e2540d21 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sun, 30 Sep 2012 23:15:53 +0200 Subject: [PATCH 019/157] Fix logic error when detecting next valid utf8 sequence. Closes #31. --- src/core/util/UTF8Stream.cpp | 104 +++++++++++++++++------------------ 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/src/core/util/UTF8Stream.cpp b/src/core/util/UTF8Stream.cpp index 8efb1404..35e3ec5c 100644 --- a/src/core/util/UTF8Stream.cpp +++ b/src/core/util/UTF8Stream.cpp @@ -16,10 +16,10 @@ namespace Lucene const uint16_t UTF8Base::TRAIL_SURROGATE_MAX = 0xdfffu; const uint16_t UTF8Base::LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); const uint32_t UTF8Base::SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; - + // Maximum valid value for a Unicode code point const uint32_t UTF8Base::CODE_POINT_MAX = 0x0010ffffu; - + #ifdef LPP_UNICODE_CHAR_SIZE_2 const wchar_t UTF8Base::UNICODE_REPLACEMENT_CHAR = (wchar_t)0xfffd; const wchar_t UTF8Base::UNICODE_TERMINATOR = (wchar_t)0xffff; @@ -27,11 +27,11 @@ namespace Lucene const wchar_t UTF8Base::UNICODE_REPLACEMENT_CHAR = (wchar_t)0x0001fffd; const wchar_t UTF8Base::UNICODE_TERMINATOR = (wchar_t)0x0001ffff; #endif - + UTF8Base::~UTF8Base() { } - + inline uint8_t UTF8Base::mask8(uint32_t b) { return static_cast(0xff & b); @@ -46,7 +46,7 @@ namespace Lucene { return ((mask8(b) >> 6) == 0x2); } - + inline bool UTF8Base::isSurrogate(uint32_t cp) { return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); @@ -61,47 +61,47 @@ namespace Lucene { return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); } - + inline bool UTF8Base::isValidCodePoint(uint32_t cp) { return (cp <= CODE_POINT_MAX && !isSurrogate(cp) && cp != 0xfffe && cp != 0xffff); } - + inline bool UTF8Base::isOverlongSequence(uint32_t cp, int32_t length) { if (cp < 0x80) { - if (length != 1) + if (length != 1) return true; } else if (cp < 0x800) { - if (length != 2) + if (length != 2) return true; } else if (cp < 0x10000) { - if (length != 3) + if (length != 3) return true; } return false; } - + UTF8Encoder::UTF8Encoder(const wchar_t* unicodeBegin, const wchar_t* unicodeEnd) { this->unicodeBegin = unicodeBegin; this->unicodeEnd = unicodeEnd; } - + UTF8Encoder::~UTF8Encoder() { } - + uint32_t UTF8Encoder::readNext() { return unicodeBegin == unicodeEnd ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*unicodeBegin++; } - + inline uint8_t* UTF8Encoder::appendChar(uint8_t* utf8, uint32_t cp) { if (cp < 0x80) // one octet @@ -126,12 +126,12 @@ namespace Lucene } return utf8; } - + int32_t UTF8Encoder::utf16to8(uint8_t* utf8, int32_t length) { uint8_t* start = utf8; uint32_t next = readNext(); - + while (next != UNICODE_TERMINATOR) { uint32_t cp = mask16(next); @@ -154,15 +154,15 @@ namespace Lucene break; next = readNext(); } - + return ((utf8 - start) == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : (utf8 - start); } - + int32_t UTF8Encoder::utf32to8(uint8_t* utf8, int32_t length) { uint8_t* start = utf8; uint32_t next = readNext(); - + while (next != UNICODE_TERMINATOR) { if (!isValidCodePoint(next)) @@ -172,10 +172,10 @@ namespace Lucene break; next = readNext(); } - + return ((utf8 - start) == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : (utf8 - start); } - + int32_t UTF8Encoder::encode(uint8_t* utf8, int32_t length) { #ifdef LPP_UNICODE_CHAR_SIZE_2 @@ -184,37 +184,37 @@ namespace Lucene return utf32to8(utf8, length); #endif } - + UTF8EncoderStream::UTF8EncoderStream(ReaderPtr reader) : UTF8Encoder(NULL, NULL) { this->reader = reader; } - + UTF8EncoderStream::~UTF8EncoderStream() { } - + uint32_t UTF8EncoderStream::readNext() { int32_t next = reader->read(); return next == Reader::READER_EOF ? UNICODE_TERMINATOR : (uint32_t)next; } - + UTF8Decoder::UTF8Decoder(const uint8_t* utf8Begin, const uint8_t* utf8End) { this->utf8Begin = utf8Begin; this->utf8End = utf8End; } - + UTF8Decoder::~UTF8Decoder() { } - + uint32_t UTF8Decoder::readNext() { return utf8Begin == utf8End ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*utf8Begin++; } - + inline int32_t UTF8Decoder::sequenceLength(uint32_t cp) { uint8_t lead = mask8(cp); @@ -228,7 +228,7 @@ namespace Lucene return 4; return 0; } - + inline bool UTF8Decoder::getSequence(uint32_t& cp, int32_t length) { cp = mask8(cp); @@ -267,27 +267,27 @@ namespace Lucene cp += next & 0x3f; return true; } - + inline bool UTF8Decoder::isValidNext(uint32_t& cp) { // Determine the sequence length based on the lead octet int32_t length = sequenceLength(cp); - if (length < 1 && length > 4) + if (length < 1 || length > 4) return false; // Now that we have a valid sequence length, get trail octets and calculate the code point if (!getSequence(cp, length)) return false; - + // Decoding succeeded, now security checks return (isValidCodePoint(cp) && !isOverlongSequence(cp, length)); } - + int32_t UTF8Decoder::utf8to16(wchar_t* unicode, int32_t length) { int32_t position = 0; uint32_t next = readNext(); - + while (next != UNICODE_TERMINATOR) { if (!isValidNext(next)) @@ -303,15 +303,15 @@ namespace Lucene break; next = readNext(); } - + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; } - + int32_t UTF8Decoder::utf8to32(wchar_t* unicode, int32_t length) { int32_t position = 0; uint32_t next = readNext(); - + while (next != UNICODE_TERMINATOR) { if (!isValidNext(next)) @@ -321,10 +321,10 @@ namespace Lucene break; next = readNext(); } - + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; } - + int32_t UTF8Decoder::decode(wchar_t* unicode, int32_t length) { #ifdef LPP_UNICODE_CHAR_SIZE_2 @@ -333,42 +333,42 @@ namespace Lucene return utf8to32(unicode, length); #endif } - + UTF8DecoderStream::UTF8DecoderStream(ReaderPtr reader) : UTF8Decoder(NULL, NULL) { this->reader = reader; } - + UTF8DecoderStream::~UTF8DecoderStream() { } - + uint32_t UTF8DecoderStream::readNext() { int32_t next = reader->read(); return next == Reader::READER_EOF ? UNICODE_TERMINATOR : (uint32_t)next; } - + UTF16Decoder::UTF16Decoder(const uint16_t* utf16Begin, const uint16_t* utf16End) { this->utf16Begin = utf16Begin; this->utf16End = utf16End; } - + UTF16Decoder::~UTF16Decoder() { } - + uint32_t UTF16Decoder::readNext() { return utf16Begin == utf16End ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*utf16Begin++; } - + int32_t UTF16Decoder::utf16to32(wchar_t* unicode, int32_t length) { int32_t position = 0; uint32_t next = readNext(); - + while (next != UNICODE_TERMINATOR) { uint32_t cp = mask16(next); @@ -390,15 +390,15 @@ namespace Lucene break; next = readNext(); } - + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; } - + int32_t UTF16Decoder::utf16to16(wchar_t* unicode, int32_t length) { int32_t position = 0; uint32_t next = readNext(); - + while (next != UNICODE_TERMINATOR) { unicode[position++] = static_cast(next); @@ -406,10 +406,10 @@ namespace Lucene break; next = readNext(); } - + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; } - + int32_t UTF16Decoder::decode(wchar_t* unicode, int32_t length) { #ifdef LPP_UNICODE_CHAR_SIZE_2 From 31701f891bd1576d762745f75a148be77fc96745 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 31 Jan 2013 23:04:25 +0100 Subject: [PATCH 020/157] Fix MultiLevelSkipListReader::close(). - Should close all but the first SkipBuffer. --- src/core/index/MultiLevelSkipListReader.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/index/MultiLevelSkipListReader.cpp b/src/core/index/MultiLevelSkipListReader.cpp index b37342e0..19096b6c 100644 --- a/src/core/index/MultiLevelSkipListReader.cpp +++ b/src/core/index/MultiLevelSkipListReader.cpp @@ -124,10 +124,10 @@ namespace Lucene void MultiLevelSkipListReader::close() { - for (Collection::iterator skip = skipStream.begin(); skip != skipStream.end(); ++skip) + for (int32_t i = 1; i < skipStream.size(); ++i) { - if (*skip) - (*skip)->close(); + if (skipStream[i]) + skipStream[i]->close(); } } From cb36d1d14d2d7dbb820500c627c51914e7541430 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 1 Feb 2013 15:48:55 +0100 Subject: [PATCH 021/157] Fix logic error in MultipleTermPositions::next(). Thanks to alian555. --- src/core/index/MultipleTermPositions.cpp | 66 ++++++++++++------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/core/index/MultipleTermPositions.cpp b/src/core/index/MultipleTermPositions.cpp index a6e3adeb..6da226e6 100644 --- a/src/core/index/MultipleTermPositions.cpp +++ b/src/core/index/MultipleTermPositions.cpp @@ -15,7 +15,7 @@ namespace Lucene MultipleTermPositions::MultipleTermPositions(IndexReaderPtr indexReader, Collection terms) { Collection termPositions(Collection::newInstance()); - + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) termPositions.add(indexReader->termPositions(*term)); @@ -24,16 +24,16 @@ namespace Lucene _doc = 0; _freq = 0; } - + MultipleTermPositions::~MultipleTermPositions() { } - + bool MultipleTermPositions::next() { if (termPositionsQueue->empty()) return false; - + posList->clear(); _doc = termPositionsQueue->top()->doc(); @@ -41,36 +41,38 @@ namespace Lucene do { tp = termPositionsQueue->top(); - + for (int32_t i = 0; i < tp->freq(); ++i) posList->add(tp->nextPosition()); - + if (tp->next()) termPositionsQueue->updateTop(); else + { termPositionsQueue->pop(); - tp->close(); + tp->close(); + } } while (!termPositionsQueue->empty() && termPositionsQueue->top()->doc() == _doc); - + posList->sort(); _freq = posList->size(); - + return true; } - + int32_t MultipleTermPositions::nextPosition() { return posList->next(); } - + bool MultipleTermPositions::skipTo(int32_t target) { while (termPositionsQueue->top() && target > termPositionsQueue->top()->doc()) { TermPositionsPtr tp(termPositionsQueue->top()); termPositionsQueue->pop(); - + if (tp->skipTo(target)) termPositionsQueue->add(tp); else @@ -78,59 +80,59 @@ namespace Lucene } return next(); } - + int32_t MultipleTermPositions::doc() { return _doc; } - + int32_t MultipleTermPositions::freq() { return _freq; } - + void MultipleTermPositions::close() { while (!termPositionsQueue->empty()) termPositionsQueue->pop()->close(); } - + void MultipleTermPositions::seek(TermPtr term) { boost::throw_exception(UnsupportedOperationException()); } - + void MultipleTermPositions::seek(TermEnumPtr termEnum) { boost::throw_exception(UnsupportedOperationException()); } - + int32_t MultipleTermPositions::read(Collection docs, Collection freqs) { boost::throw_exception(UnsupportedOperationException()); return 0; } - + ByteArray MultipleTermPositions::getPayload(ByteArray data, int32_t offset) { boost::throw_exception(UnsupportedOperationException()); return ByteArray(); } - + bool MultipleTermPositions::isPayloadAvailable() { return false; } - + TermPositionsQueue::TermPositionsQueue(Collection termPositions) : PriorityQueue(termPositions.size()) { this->termPositions = termPositions; } - + TermPositionsQueue::~TermPositionsQueue() { } - + void TermPositionsQueue::initialize() { PriorityQueue::initialize(); @@ -140,12 +142,12 @@ namespace Lucene add(*tp); } } - + bool TermPositionsQueue::lessThan(const TermPositionsPtr& first, const TermPositionsPtr& second) { return (first->doc() < second->doc()); } - + IntQueue::IntQueue() { arraySize = 16; @@ -153,39 +155,39 @@ namespace Lucene lastIndex = 0; array = Collection::newInstance(arraySize); } - + IntQueue::~IntQueue() { } - + void IntQueue::add(int32_t i) { if (lastIndex == arraySize) growArray(); array[lastIndex++] = i; } - + int32_t IntQueue::next() { return array[index++]; } - + void IntQueue::sort() { std::sort(array.begin() + index, array.begin() + lastIndex); } - + void IntQueue::clear() { index = 0; lastIndex = 0; } - + int32_t IntQueue::size() { return (lastIndex - index); } - + void IntQueue::growArray() { array.resize(arraySize * 2); From ca102b0219328af113397d9f186a19b358817092 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Mon, 11 Mar 2013 13:49:34 +0100 Subject: [PATCH 022/157] Fix for copy of compound file >2Go. Alain Barbet --- src/core/index/CompoundFileWriter.cpp | 68 +++++++++++++-------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/core/index/CompoundFileWriter.cpp b/src/core/index/CompoundFileWriter.cpp index 81f26b53..0c15d48d 100644 --- a/src/core/index/CompoundFileWriter.cpp +++ b/src/core/index/CompoundFileWriter.cpp @@ -27,60 +27,60 @@ namespace Lucene entries = Collection::newInstance(); merged = false; } - + CompoundFileWriter::~CompoundFileWriter() { } - + DirectoryPtr CompoundFileWriter::getDirectory() { return DirectoryPtr(_directory); } - + String CompoundFileWriter::getName() { return fileName; } - + void CompoundFileWriter::addFile(const String& file) { if (merged) boost::throw_exception(IllegalStateException(L"Can't add extensions after merge has been called")); - + if (file.empty()) boost::throw_exception(IllegalArgumentException(L"file cannot be empty")); - + if (!ids.add(file)) boost::throw_exception(IllegalArgumentException(L"File " + file + L" already added")); - + FileEntry entry; entry.file = file; entries.add(entry); } - + void CompoundFileWriter::close() { if (merged) boost::throw_exception(IllegalStateException(L"Merge already performed")); - + if (entries.empty()) boost::throw_exception(IllegalStateException(L"No entries to merge have been defined")); - + merged = true; - + DirectoryPtr directory(_directory); - + // open the compound stream IndexOutputPtr os; LuceneException finally; try { os = directory->createOutput(fileName); - + // Write the number of entries os->writeVInt(entries.size()); - - // Write the directory with all offsets at 0. Remember the positions of directory entries so that we + + // Write the directory with all offsets at 0. Remember the positions of directory entries so that we // can adjust the offsets later int64_t totalSize = 0; for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) @@ -90,13 +90,13 @@ namespace Lucene os->writeString(fe->file); totalSize += directory->fileLength(fe->file); } - - // Pre-allocate size of file as optimization - this can potentially help IO performance as we write the - // file and also later during searching. It also uncovers a disk-full situation earlier and hopefully + + // Pre-allocate size of file as optimization - this can potentially help IO performance as we write the + // file and also later during searching. It also uncovers a disk-full situation earlier and hopefully // without actually filling disk to 100% int64_t finalLength = totalSize + os->getFilePointer(); os->setLength(finalLength); - + // Open the files and copy their data into the stream. Remember the locations of each file's data section. ByteArray buffer(ByteArray::newInstance(16384)); for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) @@ -104,17 +104,17 @@ namespace Lucene fe->dataOffset = os->getFilePointer(); copyFile(*fe, os, buffer); } - + // Write the data offsets into the directory of the compound stream for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) { os->seek(fe->directoryOffset); os->writeLong(fe->dataOffset); } - + BOOST_ASSERT(finalLength == os->length()); - - // Close the output stream. Set the os to null before trying to close so that if an exception occurs during + + // Close the output stream. Set the os to null before trying to close so that if an exception occurs during // the close, the finally clause below will not attempt to close the stream the second time. IndexOutputPtr tmp(os); os.reset(); @@ -124,10 +124,10 @@ namespace Lucene { finally = e; } - + if (os) { - try + try { os->close(); } @@ -137,7 +137,7 @@ namespace Lucene } finally.throwException(); } - + void CompoundFileWriter::copyFile(const FileEntry& source, IndexOutputPtr os, ByteArray buffer) { IndexInputPtr is; @@ -146,15 +146,15 @@ namespace Lucene try { int64_t startPtr = os->getFilePointer(); - + is = directory->openInput(source.file); int64_t length = is->length(); int64_t remainder = length; - int32_t chunk = buffer.size(); - + int64_t chunk = buffer.size(); + while (remainder > 0) { - int32_t len = std::min(chunk, (int32_t)remainder); + int32_t len = (int32_t)std::min(chunk, remainder); is->readBytes(buffer.get(), 0, len, false); os->writeBytes(buffer.get(), len); remainder -= len; @@ -164,15 +164,15 @@ namespace Lucene checkAbort->work(80); } } - + // Verify that remainder is 0 if (remainder != 0) { - boost::throw_exception(IOException(L"Non-zero remainder length after copying: " + StringUtils::toString(remainder) + + boost::throw_exception(IOException(L"Non-zero remainder length after copying: " + StringUtils::toString(remainder) + L" (id: " + source.file + L", length: " + StringUtils::toString(length) + L", buffer size: " + StringUtils::toString(chunk) + L")")); } - + // Verify that the output length diff is equal to original file int64_t endPtr = os->getFilePointer(); int64_t diff = endPtr - startPtr; @@ -186,7 +186,7 @@ namespace Lucene { finally = e; } - + if (is) is->close(); finally.throwException(); From 21645edff6c9810398952847c8499ee5d58256f1 Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Wed, 20 Mar 2013 19:39:26 +0100 Subject: [PATCH 023/157] Improved the README file's build instructions. Also added a note regarding the current incompatibility with Boost 1.50 and newer (issue #30). See: https://github.com/luceneplusplus/LucenePlusPlus/issues/30 --- README.rst | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index 029027ab..24c76f97 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,7 @@ Lucene++ Welcome to lucene++ version **3.0.3**. -Lucene++ is an up to date C++ port of the popular Java Lucene library, a high-performance, full-featured text search engine. +Lucene++ is an up to date C++ port of the popular Java `Lucene `_ library, a high-performance, full-featured text search engine. Components @@ -27,7 +27,7 @@ Official `Java Lucene `_ - useful Build Instructions using CMake ------------------------------ -You'll need boost installed somewhere. +You'll need the `Boost `_ libraries installed somewhere. On Debian systems, the following packages are required: @@ -38,6 +38,24 @@ On Debian systems, the following packages are required: - libboost-iostreams-dev - libboost-test-dev +.. note:: + + At present, you must use Boost 1.49 or older. There is an incompatibility + to Boost 1.50 and newer that causes ``make`` to fail. See `issue #30`__. + +__ https://github.com/luceneplusplus/LucenePlusPlus/issues/30 + +To build the library the following commands should be issued:: + + $ cmake . + $ make + $ make install + +To build the demo programs, execute the following after having first built +the library:: + + $ make indexfiles searchfiles deletefiles + Build Instructions using Waf ------------------------------ @@ -60,7 +78,7 @@ Additionally static builds of the following libraries are required for a success - boost::iostreams - boost::unit_test_framework -The libraries and headers should be made available at a standard prefix (/usr/local for example). +The libraries and headers should be made available at a standard prefix (``/usr/local`` for example). Build Instructions for Windows systems @@ -68,11 +86,11 @@ Build Instructions for Windows systems Open solution lucene++.sln located in the *msvc* folder into Visual Studio 2008 and build. -**Note: "BOOST_ROOT" environment variable must be defined to point to the boost library directory (eg. c:\\boost_1_44_0)** +**Note: "BOOST_ROOT" environment variable must be defined to point to the Boost library directory (eg. c:\\boost_1_44_0)** -You'll need boost installed. +You'll need Boost installed. -`BoostPro `_ has some precompiled windows packages. You'll need the following extras installed:: +`BoostPro `_ has some precompiled Windows packages. You'll need the following extras installed:: - boost::system - boost::thread @@ -86,9 +104,9 @@ You'll need boost installed. Building Performance -------------------- -Use of ccache will speed up build times a lot. I found it easiest to add the /usr/lib/ccache directory to the beginning of your paths. This works for most common compilers. +Use of ccache will speed up build times a lot. I found it easiest to add the ``/usr/lib/ccache`` directory to the beginning of your paths. This works for most common compilers:: -PATH=/usr/lib/ccache:$PATH + PATH=/usr/lib/ccache:$PATH To run unit test suite From e3f8992953704b647b1f1aa57aacd3dff1541e65 Mon Sep 17 00:00:00 2001 From: Jason Gilanfarr Date: Wed, 29 May 2013 08:40:52 -0700 Subject: [PATCH 024/157] Update for boost-1.5 --- src/core/util/FileUtils.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/util/FileUtils.cpp b/src/core/util/FileUtils.cpp index 4d3d436e..e1cd0cd2 100644 --- a/src/core/util/FileUtils.cpp +++ b/src/core/util/FileUtils.cpp @@ -164,10 +164,10 @@ namespace Lucene { try { - for (boost::filesystem::wdirectory_iterator dir(path.c_str()); dir != boost::filesystem::wdirectory_iterator(); ++dir) + for (boost::filesystem::directory_iterator dir(path.c_str()); dir != boost::filesystem::directory_iterator(); ++dir) { if (!filesOnly || !boost::filesystem::is_directory(dir->status())) - dirList.add(dir->path().filename().c_str()); + dirList.add(dir->path().filename().wstring().c_str()); } return true; } @@ -202,9 +202,9 @@ namespace Lucene { try { - boost::filesystem::wpath join(path.c_str()); + boost::filesystem::path join(path.c_str()); join /= file.c_str(); - return join.directory_string().c_str(); + return join.wstring().c_str(); } catch (...) { @@ -217,7 +217,7 @@ namespace Lucene try { boost::filesystem::wpath parentPath(path.c_str()); - return parentPath.parent_path().directory_string().c_str(); + return parentPath.parent_path().wstring().c_str(); } catch (...) { @@ -230,7 +230,7 @@ namespace Lucene try { boost::filesystem::wpath fileName(path.c_str()); - return fileName.filename().c_str(); + return fileName.filename().wstring().c_str(); } catch (...) { From f185807ecd12e989e7a9f59b11dcb8e54f55d14f Mon Sep 17 00:00:00 2001 From: Jason Gilanfarr Date: Wed, 29 May 2013 09:49:38 -0700 Subject: [PATCH 025/157] Update include/Config.h.cmake to have correct boost filesystem version. --- include/Config.h.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/Config.h.cmake b/include/Config.h.cmake index 08006207..ac83b77a 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -90,7 +90,6 @@ // Make internal bitset storage public #define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS -// Force boost file-system version 2 for later boost versions > 1.46 -#define BOOST_FILESYSTEM_VERSION 2 +#define BOOST_FILESYSTEM_VERSION 3 #endif From 6251374c412d6b7e8b3855ad234a30ba49fba5d5 Mon Sep 17 00:00:00 2001 From: Jason Gilanfarr Date: Wed, 29 May 2013 14:11:53 -0700 Subject: [PATCH 026/157] Add CMake artifacts to gitignore --- .gitignore | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.gitignore b/.gitignore index 8d0e2199..59e8e10f 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,30 @@ src/demo/searchfiles/msvc/Release DLL src/demo/searchfiles/msvc/Release Static src/demo/searchfiles/msvc/Debug DLL src/demo/searchfiles/msvc/Debug Static +CMakeCache.txt +CMakeFiles/ +CTestTestfile.cmake +Makefile +cmake_install.cmake +cmake_uninstall.cmake +include/Config.h +install_manifest.txt +liblucene++-contrib.pc +liblucene++.pc +src/contrib/CMakeFiles/ +src/contrib/CTestTestfile.cmake +src/contrib/Makefile +src/contrib/cmake_install.cmake +src/core/CMakeFiles/ +src/core/CTestTestfile.cmake +src/core/Makefile +src/core/cmake_install.cmake +src/demo/CMakeFiles/ +src/demo/CTestTestfile.cmake +src/demo/Makefile +src/demo/cmake_install.cmake +src/test/CMakeFiles/ +src/test/CTestTestfile.cmake +src/test/Makefile +src/test/cmake_install.cmake + From 99facd71977fbf8aed495a3537dfc54962402815 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 12 Jul 2013 23:14:12 +0200 Subject: [PATCH 027/157] The right hand side needs to be cast to int64_t before being shifted. - Thanks to kojik1010. --- src/core/store/IndexInput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/store/IndexInput.cpp b/src/core/store/IndexInput.cpp index 3828c6d6..85580d63 100644 --- a/src/core/store/IndexInput.cpp +++ b/src/core/store/IndexInput.cpp @@ -64,7 +64,7 @@ namespace Lucene for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) { b = readByte(); - i |= (b & 0x7f) << shift; + i |= (int64_t)(b & 0x7f) << shift; } return i; } From 5958503b7ca05a2a1413fbe3cb310e48afd65234 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 19 Jul 2013 22:13:20 +0200 Subject: [PATCH 028/157] Fixed unit tests. --- src/test/index/IndexInputTest.cpp | 2 +- src/test/store/BufferedIndexInputTest.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/index/IndexInputTest.cpp b/src/test/index/IndexInputTest.cpp index 9c48cff1..3adf0505 100644 --- a/src/test/index/IndexInputTest.cpp +++ b/src/test/index/IndexInputTest.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(testReadVLong) uint8_t input[8] = { 213, 143, 132, 196, 172, 154, 129, 96 }; std::memcpy(inputBytes.get(), input, 8); IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readVLong(), -926873643); + BOOST_CHECK_EQUAL(is->readVLong(), 54048498881988565LL); } BOOST_AUTO_TEST_CASE(testReadString) diff --git a/src/test/store/BufferedIndexInputTest.cpp b/src/test/store/BufferedIndexInputTest.cpp index 78d4ef30..a4f1c37a 100644 --- a/src/test/store/BufferedIndexInputTest.cpp +++ b/src/test/store/BufferedIndexInputTest.cpp @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(testReadVLong) uint8_t input[8] = { 213, 143, 132, 196, 172, 154, 129, 96 }; std::memcpy(inputBytes.get(), input, 8); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 8); - BOOST_CHECK_EQUAL(indexInput.readVLong(), -926873643LL); + BOOST_CHECK_EQUAL(indexInput.readVLong(), 54048498881988565LL); } BOOST_AUTO_TEST_CASE(testReadString) From ea93d356c01da3a725486c5461db25754fe52260 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 19 Jul 2013 22:13:50 +0200 Subject: [PATCH 029/157] Disable pch in waf. --- wscript | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/wscript b/wscript index 0f99d547..77d0242f 100644 --- a/wscript +++ b/wscript @@ -74,19 +74,19 @@ def options(opt): opt.tool_options("boost") opt.tool_options('compiler_cxx') #opt.tool_options('clang', tooldir = 'build') - opt.tool_options('gch', tooldir = 'build') + #opt.tool_options('gch', tooldir = 'build') opt.add_option( - '--debug', + '--debug', default = False, action = "store_true", - help ='debug build no optimization, etc.', + help ='debug build no optimization, etc.', dest = 'debug') opt.add_option( - '--static', + '--static', default = False, action = "store_true", - help ='fully static build', + help ='fully static build', dest = 'static') @@ -97,25 +97,25 @@ def configure(conf): conf.check_cc(lib = 'pthread', mandatory = True) conf.check_tool('boost') #conf.check_tool('clang', 'build') - conf.check_tool('gch', 'build') + #conf.check_tool('gch', 'build') conf.check_boost( static = 'onlystatic', lib = ['filesystem', 'thread', 'regex', 'system', 'date_time', 'iostreams', 'unit_test_framework'] ) - + def build(bld): target_type = 'cstlib' if Options.options.static else 'cshlib' debug_define = '_DEBUG' if Options.options.debug else 'NDEBUG' if Options.options.debug: - compile_flags = ['-O0', '-g'] + compile_flags = ['-O0', '-g'] else: compile_flags = ['-O2'] lucene_sources = [] for source_dir in lucene_source_dirs: source_dir = bld.path.find_dir(source_dir) lucene_sources.extend(source_dir.ant_glob(source_patterns)) - + bld( name = 'lucene++', features = ['cxx', 'c'] + [target_type], @@ -128,12 +128,12 @@ def build(bld): defines = ['LPP_BUILDING_LIB', 'LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD Z' ) - + lucene_contrib_sources = [] for source_dir in lucene_contrib_source_dirs: source_dir = bld.path.find_dir(source_dir) lucene_contrib_sources.extend(source_dir.ant_glob(source_patterns)) - + bld( name = 'lucene_contrib', features = ['cxx', 'c'] + [target_type], @@ -147,12 +147,12 @@ def build(bld): uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD Z', use = 'lucene++' ) - + tester_sources = [] for source_dir in tester_source_dirs: source_dir = bld.path.find_dir(source_dir) tester_sources.extend(source_dir.ant_glob(source_patterns)) - + bld( name = 'lucene_tester', features = ['cxx', 'c', 'cprogram'], @@ -166,7 +166,7 @@ def build(bld): uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS BOOST_UNIT_TEST_FRAMEWORK PTHREAD Z', use = 'lucene++ lucene_contrib' ) - + bld( name = 'deletefiles', features = ['cxx', 'c', 'cprogram'], From 3b76d7cf92318e518f58329f69dd77338888d69b Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Tue, 30 Jul 2013 15:40:54 +0200 Subject: [PATCH 030/157] Release version 3.0.4. --- README.rst | 2 +- doxygen/lucene++ | 1292 +++++++++++++++++++++++----------------------- wscript | 2 +- 3 files changed, 648 insertions(+), 648 deletions(-) diff --git a/README.rst b/README.rst index 24c76f97..977b2614 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Lucene++ ========== -Welcome to lucene++ version **3.0.3**. +Welcome to lucene++ version **3.0.4**. Lucene++ is an up to date C++ port of the popular Java `Lucene `_ library, a high-performance, full-featured text search engine. diff --git a/doxygen/lucene++ b/doxygen/lucene++ index 07dc9395..827d7e52 100644 --- a/doxygen/lucene++ +++ b/doxygen/lucene++ @@ -14,76 +14,76 @@ # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = Lucene++ -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 3.0.0 +PROJECT_NUMBER = 3.0.4 -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = C:/Alan/lucene++/docs -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ @@ -98,203 +98,203 @@ ABBREVIATE_BRIEF = "The $name class" \ an \ the -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/ -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = YES -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set # FILE_PATTERNS otherwise the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES -# If you use Microsoft's C++/CLI language, you should set this option to YES to +# If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = YES -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 @@ -303,115 +303,115 @@ SYMBOL_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file +# If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO @@ -426,179 +426,179 @@ SORT_BRIEF_DOCS = NO SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = NO -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = NO -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = NO -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional +# The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. -LAYOUT_FILE = +LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = NO -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = C:/Alan/lucene++ -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.cc \ @@ -632,28 +632,28 @@ FILE_PATTERNS = *.cc \ *.vhd \ *.vhdl -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */test/* \ @@ -662,61 +662,61 @@ EXCLUDE_PATTERNS = */test/* \ */utf8/* \ */zlib/* -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. -INPUT_FILTER = +INPUT_FILTER = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. -FILTER_PATTERNS = +FILTER_PATTERNS = -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO @@ -725,53 +725,53 @@ FILTER_SOURCE_FILES = NO # configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO -# Setting the INLINE_SOURCES tag to YES will include the body +# Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES @@ -780,245 +780,245 @@ VERBATIM_HEADERS = YES # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a # standard header. -HTML_HEADER = +HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = +HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = +HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = YES -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be # written to the html output directory. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members +# The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. -QCH_FILE = +QCH_FILE = -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace -QHP_NAMESPACE = +QHP_NAMESPACE = -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. # Qt Help Project / Filter Attributes. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. -QHG_LOCATION = +QHG_LOCATION = -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) +# This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enable doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript +# for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) -# there is already a search function so this one should typically +# HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) +# there is already a search function so this one should typically # be disabled. SEARCHENGINE = YES @@ -1027,74 +1027,74 @@ SEARCHENGINE = YES # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO @@ -1110,68 +1110,68 @@ LATEX_SOURCE_CODE = NO # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO @@ -1180,33 +1180,33 @@ MAN_LINKS = NO # configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +XML_SCHEMA = -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +XML_DTD = -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES @@ -1215,10 +1215,10 @@ XML_PROGRAMLISTING = YES # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO @@ -1227,97 +1227,97 @@ GENERATE_AUTOGEN_DEF = NO # configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH = +INCLUDE_PATH = -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES @@ -1326,41 +1326,41 @@ SKIP_FUNCTION_MACROS = YES # Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES -# The PERL_PATH should be the absolute path and name of the perl script +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl @@ -1369,192 +1369,192 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. -DOT_FONTPATH = +DOT_FONTPATH = -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO -# If set to YES, the inheritance and collaboration graphs will show the +# If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png -# The tag DOT_PATH can be used to specify the path where the dot tool can be +# The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. -DOT_PATH = +DOT_PATH = -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES diff --git a/wscript b/wscript index 77d0242f..a8eb02ab 100644 --- a/wscript +++ b/wscript @@ -13,7 +13,7 @@ from TaskGen import feature, after import Task APPNAME='Lucene++' -VERSION='3.0.3.4' +VERSION='3.0.4.0' top = '.' out = 'bin' From 277b8d12404ce5d4d76ee6fbf22886d83e36fe26 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Tue, 27 Aug 2013 12:39:17 +0100 Subject: [PATCH 031/157] Fix segfault when recording directory listing (Marcin Junczys-Dowmunt). --- src/core/index/SegmentInfos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/index/SegmentInfos.cpp b/src/core/index/SegmentInfos.cpp index a29984a2..6e0a5178 100644 --- a/src/core/index/SegmentInfos.cpp +++ b/src/core/index/SegmentInfos.cpp @@ -421,10 +421,10 @@ namespace Lucene // as there is no stale caching on the directory contents (NOTE: NFS clients often have such stale caching) HashSet files(directory->listAll()); int64_t genA = segmentInfos->getCurrentSegmentGeneration(files); - - segmentInfos->message(L"directory listing genA=" + genA); - - // Method 2: open segments.gen and read its contents. Then we take the larger of the two gens. This way, + + segmentInfos->message(L"directory listing genA=" + StringUtils::toString(genA)); + + // Method 2: open segments.gen and read its contents. Then we take the larger of the two gens. This way, // if either approach is hitting a stale cache (NFS) we have a better chance of getting the right generation. int64_t genB = -1; for (int32_t i = 0; i < SegmentInfos::defaultGenFileRetryCount; ++i) From 65c63d0a6c3927e0f123f6ec24d5516739fd53b3 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 12 Sep 2013 10:34:00 +0100 Subject: [PATCH 032/157] Turn off custom allocator by default. closes #40 --- CMakeLists.txt | 25 ++++++++++++++----------- include/Config.h.cmake | 2 +- src/core/CMakeLists.txt | 12 ++++++++---- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec89210e..ab1f10dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,9 @@ ENDIF(NOT CMAKE_BUILD_TYPE) OPTION(ENABLE_PACKAGING "create build scripts for creating lucene++ packages" OFF) +OPTION(ENABLE_CUSTOM_ALLOCATOR + "use custom memory allocator" + OFF) OPTION(ENABLE_NEDMALLOC "use nedmalloc for memory allocations" OFF) @@ -75,18 +78,18 @@ OPTION(ENABLE_CYCLIC_CHECK #install path options SET(LIB_DESTINATION "lib" CACHE STRING "Define lib output directory name") +IF ( ENABLE_CUSTOM_ALLOCATOR ) + SET(DEFINE_USE_CUSTOM_ALLOCATOR "define") +ELSE ( ENABLE_CUSTOM_ALLOCATOR ) + SET(DEFINE_USE_CUSTOM_ALLOCATOR "undef") +ENDIF ( ENABLE_CUSTOM_ALLOCATOR ) + IF ( ENABLE_NEDMALLOC ) SET(DEFINE_USE_NEDMALLOC "define") ELSE ( ENABLE_NEDMALLOC ) SET(DEFINE_USE_NEDMALLOC "undef") ENDIF ( ENABLE_NEDMALLOC ) -IF ( ENABLE_STANDARD_ALLOCATOR ) - SET(DEFINE_USE_ALLOCATOR "undef") -ELSE ( ENABLE_STANDARD_ALLOCATOR ) - SET(DEFINE_USE_ALLOCATOR "define") -ENDIF ( ENABLE_STANDARD_ALLOCATOR ) - IF ( ENABLE_CYCLIC_CHECK ) SET(DEFINE_USE_CYCLIC_CHECK "define") ELSE ( ENABLE_CYCLIC_CHECK ) @@ -116,11 +119,11 @@ IF(CYGWIN) ADD_DEFINITIONS(-D__LARGE64_FILES) ENDIF(CYGWIN) -#set ansi mode +#set ansi mode SET(ENABLE_ANSI_MODE OFF) IF(CMAKE_COMPILER_IS_GNUCXX) SET(ENABLE_ANSI_MODE ON) - + #exceptions: IF(MINGW OR CYGWIN) SET(ENABLE_ANSI_MODE OFF) @@ -130,20 +133,20 @@ IF ( CMAKE_COMPILER_IS_GNUCC ) IF( ENABLE_ANSI_MODE ) SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi") ENDIF ( ENABLE_ANSI_MODE ) -ENDIF(CMAKE_COMPILER_IS_GNUCC) +ENDIF(CMAKE_COMPILER_IS_GNUCC) #################################### #find boost #################################### SET(Boost_USE_STATIC_LIBS ${LUCENE_USE_STATIC_BOOST_LIBS}) SET(Boost_USE_MULTITHREADED ON) -#Boost 1.38 required for bug fixes in basic_streambuf. +#Boost 1.38 required for bug fixes in basic_streambuf. #The following line fails in earlier builds, so if altered, may allow older versions of boost: #boost::gregorian::date date = parser.parse_date(paddedDate.c_str(), dateFormat->c_str(), svp); find_package( Boost 1.38.0 COMPONENTS date_time filesystem iostreams regex system thread unit_test_framework REQUIRED) IF (Boost_FOUND) MESSAGE( STATUS "boost found: includes in ${Boost_INCLUDE_DIRS}, library in ${Boost_LIBRARY_DIRS}") - SET(LUCENE_BOOST_LIBS + SET(LUCENE_BOOST_LIBS ${Boost_FILESYSTEM_LIBRARY_RELEASE} ${Boost_IOSTREAMS_LIBRARY_RELEASE} ${Boost_REGEX_LIBRARY_RELEASE} diff --git a/include/Config.h.cmake b/include/Config.h.cmake index ac83b77a..13f64601 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -78,7 +78,7 @@ #@DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK // Define to use custom allocator (useful in Windows builds and when using nedmalloc) -#@DEFINE_USE_ALLOCATOR@ LPP_USE_ALLOCATOR +#@DEFINE_USE_CUSTOM_ALLOCATOR@ LPP_USE_ALLOCATOR // Define to use nedmalloc memory allocator #@DEFINE_USE_NEDMALLOC@ LPP_USE_NEDMALLOC diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a77c12fb..ce91ae94 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -20,7 +20,11 @@ file(GLOB_RECURSE HEADERS ${lucene++-base_SOURCE_DIR}/include/*.h file(GLOB_RECURSE lucene_c_sources ${lucene++-lib_SOURCE_DIR}/util/*.c) - + +IF ( ENABLE_CUSTOM_ALLOCATOR ) + ADD_DEFINITIONS(-DLPP_USE_ALLOCATOR) +ENDIF() + IF ( ENABLE_NEDMALLOC ) ADD_DEFINITIONS(-DLPP_USE_NEDMALLOC) ENDIF() @@ -51,12 +55,12 @@ SET_TARGET_PROPERTIES(lucene++ PROPERTIES SOVERSION ${LUCENE++_SOVERSION} COMPILE_FLAGS -DLPP_HAVE_DLL ) -TARGET_LINK_LIBRARIES(lucene++ - lucene++-c +TARGET_LINK_LIBRARIES(lucene++ + lucene++-c ${CMAKE_THREAD_LIBS_INIT} ${LUCENE_BOOST_LIBS} ) install(TARGETS lucene++ - DESTINATION ${LIB_DESTINATION} + DESTINATION ${LIB_DESTINATION} COMPONENT runtime) ################################# From 3d8a008651e3e68825215343ad261631ba10bcd7 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 12 Sep 2013 11:11:39 +0100 Subject: [PATCH 033/157] Strip symbols from shared libraries. closes #39 --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab1f10dc..9c750060 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,6 +135,8 @@ IF ( CMAKE_COMPILER_IS_GNUCC ) ENDIF ( ENABLE_ANSI_MODE ) ENDIF(CMAKE_COMPILER_IS_GNUCC) +SET( CMAKE_EXE_LINKER_FLAGS "-s") + #################################### #find boost #################################### From f4f7a4e212dc96146a9b71c8a09d375a1cd9980e Mon Sep 17 00:00:00 2001 From: Jason Gilanfarr Date: Thu, 26 Sep 2013 16:46:23 -0700 Subject: [PATCH 034/157] Add support for compiling with c++11. --- include/Array.h | 2 +- include/AttributeSource.h | 2 +- include/Collection.h | 2 +- include/HashMap.h | 2 +- include/HashSet.h | 2 +- include/Map.h | 2 +- include/MiscUtils.h | 2 +- include/Set.h | 2 +- src/core/include/_FieldCacheRangeFilter.h | 2 +- src/core/index/DirectoryReader.cpp | 2 +- src/core/index/IndexWriter.cpp | 2 +- src/core/index/MultiLevelSkipListReader.cpp | 2 +- src/core/index/SegmentMerger.cpp | 2 +- src/core/index/SegmentReader.cpp | 4 ++-- src/core/queryparser/QueryParserTokenManager.cpp | 7 ++++--- src/core/search/FieldCacheRangeFilter.cpp | 2 +- src/core/search/Query.cpp | 2 +- src/core/store/NativeFSLockFactory.cpp | 2 +- src/core/util/OpenBitSetIterator.cpp | 2 +- 19 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/Array.h b/include/Array.h index 774d58a8..46f38aa3 100644 --- a/include/Array.h +++ b/include/Array.h @@ -119,7 +119,7 @@ namespace Lucene operator bool () const { - return container; + return container.get() != NULL; } bool operator! () const diff --git a/include/AttributeSource.h b/include/AttributeSource.h index ed3895b1..13f716e9 100644 --- a/include/AttributeSource.h +++ b/include/AttributeSource.h @@ -95,7 +95,7 @@ namespace Lucene template bool hasAttribute() { - return getAttribute(ATTR::_getClassName()); + return getAttribute(ATTR::_getClassName()).get() != NULL; } /// Returns the instance of the passed in Attribute contained in this AttributeSource. diff --git a/include/Collection.h b/include/Collection.h index 2e05a822..31d475eb 100644 --- a/include/Collection.h +++ b/include/Collection.h @@ -211,7 +211,7 @@ namespace Lucene operator bool() const { - return container; + return container.get() != NULL; } bool operator! () const diff --git a/include/HashMap.h b/include/HashMap.h index 2d40f5dd..217c7747 100644 --- a/include/HashMap.h +++ b/include/HashMap.h @@ -82,7 +82,7 @@ namespace Lucene operator bool() const { - return mapContainer; + return mapContainer.get() != NULL; } bool operator! () const diff --git a/include/HashSet.h b/include/HashSet.h index cefd5337..b7dff184 100644 --- a/include/HashSet.h +++ b/include/HashSet.h @@ -88,7 +88,7 @@ namespace Lucene operator bool() const { - return setContainer; + return setContainer.get() != NULL; } bool operator! () const diff --git a/include/Map.h b/include/Map.h index c7dabcdf..36e8cd95 100644 --- a/include/Map.h +++ b/include/Map.h @@ -82,7 +82,7 @@ namespace Lucene operator bool() const { - return mapContainer; + return mapContainer.get() != NULL; } bool operator! () const diff --git a/include/MiscUtils.h b/include/MiscUtils.h index ed65f70c..7227b930 100644 --- a/include/MiscUtils.h +++ b/include/MiscUtils.h @@ -125,7 +125,7 @@ namespace Lucene template static bool typeOf(LuceneObjectPtr object) { - return boost::dynamic_pointer_cast(object); + return boost::dynamic_pointer_cast(object).get() != NULL; } /// Return whether given Lucene objects are of equal type. diff --git a/include/Set.h b/include/Set.h index bc62f170..7adff103 100644 --- a/include/Set.h +++ b/include/Set.h @@ -132,7 +132,7 @@ namespace Lucene operator bool() const { - return setContainer; + return setContainer.get() != NULL; } bool operator! () const diff --git a/src/core/include/_FieldCacheRangeFilter.h b/src/core/include/_FieldCacheRangeFilter.h index 7e494fd6..ba44022c 100644 --- a/src/core/include/_FieldCacheRangeFilter.h +++ b/src/core/include/_FieldCacheRangeFilter.h @@ -146,7 +146,7 @@ namespace Lucene return false; if (lowerVal != otherFilter->lowerVal || upperVal != otherFilter->upperVal) return false; - if (parser ? !parser->equals(otherFilter->parser) : otherFilter->parser) + if (parser.get() != NULL ? !parser->equals(otherFilter->parser) : otherFilter->parser.get() != NULL) return false; return true; } diff --git a/src/core/index/DirectoryReader.cpp b/src/core/index/DirectoryReader.cpp index 2d2d1cea..9fddf414 100644 --- a/src/core/index/DirectoryReader.cpp +++ b/src/core/index/DirectoryReader.cpp @@ -976,7 +976,7 @@ namespace Lucene SegmentMergeInfoPtr smi(newLucene(starts[i], termEnum, reader)); smi->ord = i; - if (t ? termEnum->term() : smi->next()) + if (t.get() != NULL ? termEnum->term().get() != NULL : smi->next()) queue->add(smi); // initialize queue else smi->close(); diff --git a/src/core/index/IndexWriter.cpp b/src/core/index/IndexWriter.cpp index aabb6e4d..11926e96 100644 --- a/src/core/index/IndexWriter.cpp +++ b/src/core/index/IndexWriter.cpp @@ -687,7 +687,7 @@ namespace Lucene bool IndexWriter::verbose() { - return infoStream; + return infoStream.get() != NULL; } void IndexWriter::setWriteLockTimeout(int64_t writeLockTimeout) diff --git a/src/core/index/MultiLevelSkipListReader.cpp b/src/core/index/MultiLevelSkipListReader.cpp index 19096b6c..c38fd603 100644 --- a/src/core/index/MultiLevelSkipListReader.cpp +++ b/src/core/index/MultiLevelSkipListReader.cpp @@ -27,7 +27,7 @@ namespace Lucene this->maxNumberOfSkipLevels = maxSkipLevels; this->skipInterval = Collection::newInstance(maxSkipLevels); this->skipStream[0] = skipStream; - this->inputIsBuffered = boost::dynamic_pointer_cast(skipStream); + this->inputIsBuffered = boost::dynamic_pointer_cast(skipStream).get() != NULL; this->skipInterval[0] = skipInterval; this->skipDoc = Collection::newInstance(maxSkipLevels); diff --git a/src/core/index/SegmentMerger.cpp b/src/core/index/SegmentMerger.cpp index d5325019..41f4dc56 100644 --- a/src/core/index/SegmentMerger.cpp +++ b/src/core/index/SegmentMerger.cpp @@ -38,7 +38,7 @@ namespace Lucene const int32_t SegmentMerger::MAX_RAW_MERGE_DOCS = 4192; /// norms header placeholder - const uint8_t SegmentMerger::NORMS_HEADER[] = {'N', 'R', 'M', -1}; + const uint8_t SegmentMerger::NORMS_HEADER[] = {'N', 'R', 'M', static_cast(-1) }; const int32_t SegmentMerger::NORMS_HEADER_LENGTH = 4; SegmentMerger::SegmentMerger(DirectoryPtr dir, const String& name) diff --git a/src/core/index/SegmentReader.cpp b/src/core/index/SegmentReader.cpp index 2be0b1f0..d9d1b795 100644 --- a/src/core/index/SegmentReader.cpp +++ b/src/core/index/SegmentReader.cpp @@ -376,7 +376,7 @@ namespace Lucene bool SegmentReader::hasDeletions() { // Don't call ensureOpen() here (it could affect performance) - return deletedDocs; + return deletedDocs.get() != NULL; } bool SegmentReader::usesCompoundFile(SegmentInfoPtr si) @@ -923,7 +923,7 @@ namespace Lucene bool CoreReaders::termsIndexIsLoaded() { SyncLock syncLock(this); - return tis; + return tis.get() != NULL; } void CoreReaders::loadTermsIndex(SegmentInfoPtr si, int32_t termsIndexDivisor) diff --git a/src/core/queryparser/QueryParserTokenManager.cpp b/src/core/queryparser/QueryParserTokenManager.cpp index e769470f..cb64c976 100644 --- a/src/core/queryparser/QueryParserTokenManager.cpp +++ b/src/core/queryparser/QueryParserTokenManager.cpp @@ -15,9 +15,10 @@ namespace Lucene { const int64_t QueryParserTokenManager::jjbitVec0[] = {0x1LL, 0x0LL, 0x0LL, 0x0LL}; - const int64_t QueryParserTokenManager::jjbitVec1[] = {0xfffffffffffffffeLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL}; - const int64_t QueryParserTokenManager::jjbitVec3[] = {0x0LL, 0x0LL, 0xffffffffffffffffLL, 0xffffffffffffffffLL}; - const int64_t QueryParserTokenManager::jjbitVec4[] = {0xfffefffffffffffeLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL}; + const int64_t QueryParserTokenManager::jjbitVec1[] = {static_cast(0xfffffffffffffffeLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; + const int64_t QueryParserTokenManager::jjbitVec3[] = {0x0LL, 0x0LL, static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; + const int64_t QueryParserTokenManager::jjbitVec4[] = {static_cast(0xfffefffffffffffeLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; + const int32_t QueryParserTokenManager::jjnextStates[] = {15, 16, 18, 29, 32, 23, 33, 30, 20, 21, 32, 23, 33, 31, 34, 27, 2, 4, 5, 0, 1}; /// Token literal values. diff --git a/src/core/search/FieldCacheRangeFilter.cpp b/src/core/search/FieldCacheRangeFilter.cpp index ce82a28a..15851211 100644 --- a/src/core/search/FieldCacheRangeFilter.cpp +++ b/src/core/search/FieldCacheRangeFilter.cpp @@ -170,7 +170,7 @@ namespace Lucene return false; if (lowerVal != otherFilter->lowerVal || upperVal != otherFilter->upperVal) return false; - if (parser ? !parser->equals(otherFilter->parser) : otherFilter->parser) + if (parser.get() != NULL ? !parser->equals(otherFilter->parser) : otherFilter->parser.get() != NULL) return false; return true; } diff --git a/src/core/search/Query.cpp b/src/core/search/Query.cpp index 33aac962..0cfc4828 100644 --- a/src/core/search/Query.cpp +++ b/src/core/search/Query.cpp @@ -73,7 +73,7 @@ namespace Lucene Collection clauses; BooleanQueryPtr bq(boost::dynamic_pointer_cast(*query)); // check if we can split the query into clauses - bool splittable = bq; + bool splittable = bq.get() != NULL; if (splittable) { splittable = bq->isCoordDisabled(); diff --git a/src/core/store/NativeFSLockFactory.cpp b/src/core/store/NativeFSLockFactory.cpp index 06f9a474..cc5e96ed 100644 --- a/src/core/store/NativeFSLockFactory.cpp +++ b/src/core/store/NativeFSLockFactory.cpp @@ -79,7 +79,7 @@ namespace Lucene bool NativeFSLock::lockExists() { SyncLock syncLock(this); - return lock; + return lock.get() != NULL; } bool NativeFSLock::obtain() diff --git a/src/core/util/OpenBitSetIterator.cpp b/src/core/util/OpenBitSetIterator.cpp index 5d61c13e..3d43e068 100644 --- a/src/core/util/OpenBitSetIterator.cpp +++ b/src/core/util/OpenBitSetIterator.cpp @@ -43,7 +43,7 @@ namespace Lucene 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 + 0x876541, 0x876542, 0x8765421, 0x876543, 0x8765431, 0x8765432, static_cast(0x87654321) }; OpenBitSetIterator::OpenBitSetIterator(OpenBitSetPtr bitSet) From 4777666812df2d60e619f22eb64d0db533803840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Fri, 11 Oct 2013 17:29:44 +0200 Subject: [PATCH 035/157] Remove outdated note about Boost incompatibility from the README. Commit e3f8992 ported the code to use Boost.Filesystem V3 API, so the warning about not being able to use Boost 1.50+ is no longer true. --- README.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.rst b/README.rst index 977b2614..3614da77 100644 --- a/README.rst +++ b/README.rst @@ -38,11 +38,6 @@ On Debian systems, the following packages are required: - libboost-iostreams-dev - libboost-test-dev -.. note:: - - At present, you must use Boost 1.49 or older. There is an incompatibility - to Boost 1.50 and newer that causes ``make`` to fail. See `issue #30`__. - __ https://github.com/luceneplusplus/LucenePlusPlus/issues/30 To build the library the following commands should be issued:: From 86282785ae63e06f30028f9c66d9c02f03dd6e3c Mon Sep 17 00:00:00 2001 From: Matt Richards Date: Thu, 17 Oct 2013 23:32:53 -0700 Subject: [PATCH 036/157] Fix races when initializing static arrays in StandardTokenizerImpl I've observed crashes where one thread is in the middle of initializing ZZ_CMAP and other is trying to use the partially initialized array and crashes. Use boost::once to ensure that only one thread handles the initialization and no thread uses the data until it is fully initialized. --- include/StandardTokenizerImpl.h | 5 + .../standard/StandardTokenizerImpl.cpp | 173 ++++++++++-------- 2 files changed, 100 insertions(+), 78 deletions(-) diff --git a/include/StandardTokenizerImpl.h b/include/StandardTokenizerImpl.h index 0998c9a4..1ef35389 100644 --- a/include/StandardTokenizerImpl.h +++ b/include/StandardTokenizerImpl.h @@ -32,6 +32,7 @@ namespace Lucene static const int32_t ZZ_CMAP_PACKED_LENGTH; /// Translates characters to character classes + static void ZZ_CMAP_INIT(CharArray& zz_action); static const wchar_t* ZZ_CMAP(); /// Translates DFA states to action switch labels. @@ -40,6 +41,7 @@ namespace Lucene static const int32_t ZZ_ACTION_PACKED_LENGTH; /// Translates DFA states to action switch labels. + static void ZZ_ACTION_INIT(IntArray& zz_action); static const int32_t* ZZ_ACTION(); /// Translates a state to a row index in the transition table @@ -48,6 +50,7 @@ namespace Lucene static const int32_t ZZ_ROWMAP_PACKED_LENGTH; /// Translates a state to a row index in the transition table + static void ZZ_ROWMAP_INIT(IntArray& zz_rowmap); static const int32_t* ZZ_ROWMAP(); /// The transition table of the DFA @@ -56,6 +59,7 @@ namespace Lucene static const int32_t ZZ_TRANS_PACKED_LENGTH; /// The transition table of the DFA + static void ZZ_TRANS_INIT(IntArray& zz_trans); static const int32_t* ZZ_TRANS(); // error codes @@ -71,6 +75,7 @@ namespace Lucene static const int32_t ZZ_ATTRIBUTE_PACKED_LENGTH; /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState + static void ZZ_ATTRIBUTE_INIT(IntArray& zz_attribute); static const int32_t* ZZ_ATTRIBUTE(); /// The input device diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index 95ed1976..e26c542f 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -4,6 +4,8 @@ // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// +#include + #include "LuceneInc.h" #include "StandardTokenizerImpl.h" #include "StandardTokenizer.h" @@ -202,112 +204,127 @@ namespace Lucene StandardTokenizerImpl::~StandardTokenizerImpl() { } + + void StandardTokenizerImpl::ZZ_CMAP_INIT(CharArray& zz_cmap) + { + zz_cmap = CharArray::newInstance(ZZ_CMAP_LENGTH); + wchar_t* result = zz_cmap.get(); + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_CMAP_PACKED_LENGTH) + { + int32_t count = ZZ_CMAP_PACKED[i++]; + wchar_t value = ZZ_CMAP_PACKED[i++]; + do + result[j++] = value; + while (--count > 0); + } + } + const wchar_t* StandardTokenizerImpl::ZZ_CMAP() { + static boost::once_flag once = BOOST_ONCE_INIT; static CharArray _ZZ_CMAP; - if (!_ZZ_CMAP) + boost::call_once(once, ZZ_CMAP_INIT, _ZZ_CMAP); + return _ZZ_CMAP.get(); + } + + void StandardTokenizerImpl::ZZ_ACTION_INIT(IntArray& zz_action) + { + zz_action = IntArray::newInstance(ZZ_ACTION_LENGTH); + int32_t* result = zz_action.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_ACTION_PACKED_LENGTH) { - _ZZ_CMAP = CharArray::newInstance(ZZ_CMAP_LENGTH); - wchar_t* result = _ZZ_CMAP.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_CMAP_PACKED_LENGTH) - { - int32_t count = ZZ_CMAP_PACKED[i++]; - wchar_t value = ZZ_CMAP_PACKED[i++]; - do - result[j++] = value; - while (--count > 0); - } + int32_t count = ZZ_ACTION_PACKED_0[i++]; + int32_t value = ZZ_ACTION_PACKED_0[i++]; + do + result[j++] = value; + while (--count > 0); } - return _ZZ_CMAP.get(); } const int32_t* StandardTokenizerImpl::ZZ_ACTION() { + static boost::once_flag once = BOOST_ONCE_INIT; static IntArray _ZZ_ACTION; - if (!_ZZ_ACTION) - { - _ZZ_ACTION = IntArray::newInstance(ZZ_ACTION_LENGTH); - int32_t* result = _ZZ_ACTION.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_ACTION_PACKED_LENGTH) - { - int32_t count = ZZ_ACTION_PACKED_0[i++]; - int32_t value = ZZ_ACTION_PACKED_0[i++]; - do - result[j++] = value; - while (--count > 0); - } - } + boost::call_once(once, ZZ_ACTION_INIT, _ZZ_ACTION); return _ZZ_ACTION.get(); } - - const int32_t* StandardTokenizerImpl::ZZ_ROWMAP() + + void StandardTokenizerImpl::ZZ_ROWMAP_INIT(IntArray& zz_rowmap) { - static IntArray _ZZ_ROWMAP; - if (!_ZZ_ROWMAP) + zz_rowmap = IntArray::newInstance(ZZ_ROWMAP_LENGTH); + int32_t* result = zz_rowmap.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_ROWMAP_PACKED_LENGTH) { - _ZZ_ROWMAP = IntArray::newInstance(ZZ_ROWMAP_LENGTH); - int32_t* result = _ZZ_ROWMAP.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_ROWMAP_PACKED_LENGTH) - { - int32_t high = ZZ_ROWMAP_PACKED_0[i++] << 16; - result[j++] = high | ZZ_ROWMAP_PACKED_0[i++]; - } + int32_t high = ZZ_ROWMAP_PACKED_0[i++] << 16; + result[j++] = high | ZZ_ROWMAP_PACKED_0[i++]; } + } + + const int32_t* StandardTokenizerImpl::ZZ_ROWMAP() + { + static IntArray _ZZ_ROWMAP; + static boost::once_flag once = BOOST_ONCE_INIT; + boost:call_once(once, ZZ_ROWMAP_INIT, _ZZ_ROWMAP); return _ZZ_ROWMAP.get(); } + + void StandardTokenizerImpl::ZZ_TRANS_INIT(IntArray& zz_trans) + { + zz_trans = IntArray::newInstance(ZZ_TRANS_LENGTH); + int32_t* result = zz_trans.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_TRANS_PACKED_LENGTH) + { + int32_t count = ZZ_TRANS_PACKED_0[i++]; + int32_t value = ZZ_TRANS_PACKED_0[i++]; + --value; + do + result[j++] = value; + while (--count > 0); + } + } const int32_t* StandardTokenizerImpl::ZZ_TRANS() { + static boost::once_flag once = BOOST_ONCE_INIT; static IntArray _ZZ_TRANS; - if (!_ZZ_TRANS) + boost::call_once(once, ZZ_TRANS_INIT, _ZZ_TRANS); + return _ZZ_TRANS.get(); + } + + void StandardTokenizerImpl::ZZ_ATTRIBUTE_INIT(IntArray& zz_attribute) + { + zz_attribute = IntArray::newInstance(ZZ_ATTRIBUTE_LENGTH); + int32_t* result = zz_attribute.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_ATTRIBUTE_PACKED_LENGTH) { - _ZZ_TRANS = IntArray::newInstance(ZZ_TRANS_LENGTH); - int32_t* result = _ZZ_TRANS.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_TRANS_PACKED_LENGTH) - { - int32_t count = ZZ_TRANS_PACKED_0[i++]; - int32_t value = ZZ_TRANS_PACKED_0[i++]; - --value; - do - result[j++] = value; - while (--count > 0); - } + int32_t count = ZZ_ATTRIBUTE_PACKED_0[i++]; + int32_t value = ZZ_ATTRIBUTE_PACKED_0[i++]; + do + result[j++] = value; + while (--count > 0); } - return _ZZ_TRANS.get(); } - + const int32_t* StandardTokenizerImpl::ZZ_ATTRIBUTE() { + static boost::once_flag once = BOOST_ONCE_INIT; static IntArray _ZZ_ATTRIBUTE; - if (!_ZZ_ATTRIBUTE) - { - _ZZ_ATTRIBUTE = IntArray::newInstance(ZZ_ATTRIBUTE_LENGTH); - int32_t* result = _ZZ_ATTRIBUTE.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_ATTRIBUTE_PACKED_LENGTH) - { - int32_t count = ZZ_ATTRIBUTE_PACKED_0[i++]; - int32_t value = ZZ_ATTRIBUTE_PACKED_0[i++]; - do - result[j++] = value; - while (--count > 0); - } - } + boost::call_once(once, ZZ_ATTRIBUTE_INIT, _ZZ_ATTRIBUTE); return _ZZ_ATTRIBUTE.get(); } From 07d8d7bf705f5f333b67be50bcabed42ea21468b Mon Sep 17 00:00:00 2001 From: Matt Richards Date: Fri, 18 Oct 2013 09:54:39 -0700 Subject: [PATCH 037/157] Fix copy-and-paste error in TermVectorOffsetInfo::setStartOffset() The argument should be named startOffset, not endOffset, otherwise the function is a no-op. --- src/core/index/TermVectorOffsetInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/index/TermVectorOffsetInfo.cpp b/src/core/index/TermVectorOffsetInfo.cpp index b6875e4b..750a74c9 100644 --- a/src/core/index/TermVectorOffsetInfo.cpp +++ b/src/core/index/TermVectorOffsetInfo.cpp @@ -42,7 +42,7 @@ namespace Lucene return startOffset; } - void TermVectorOffsetInfo::setStartOffset(int32_t endOffset) + void TermVectorOffsetInfo::setStartOffset(int32_t startOffset) { this->startOffset = startOffset; } From 93863775533ae91cf8e7a4bd646682dd60688d45 Mon Sep 17 00:00:00 2001 From: Matt Richards Date: Fri, 18 Oct 2013 10:12:35 -0700 Subject: [PATCH 038/157] Fix some cases of adding integers to string literals. Use StringUtils::toString() before trying to concatenate or use operator<< which is more type-safe. --- src/core/index/IndexWriter.cpp | 4 ++-- src/core/queryparser/QueryParseError.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/index/IndexWriter.cpp b/src/core/index/IndexWriter.cpp index aabb6e4d..1e203036 100644 --- a/src/core/index/IndexWriter.cpp +++ b/src/core/index/IndexWriter.cpp @@ -862,7 +862,7 @@ namespace Lucene finally.throwException(); if (infoStream) - message(L"flushDocStores files=" + docWriter->closedFiles()); + message(L"flushDocStores files=" + StringUtils::toString(docWriter->closedFiles())); useCompoundDocStore = mergePolicy->useCompoundDocStore(segmentInfos); HashSet closedFiles(docWriter->closedFiles()); @@ -2359,7 +2359,7 @@ namespace Lucene { flushedDocCount = docWriter->flush(flushDocStores); if (infoStream) - message(L"flushedFiles=" + docWriter->getFlushedFiles()); + message(L"flushedFiles=" + StringUtils::toString(docWriter->getFlushedFiles())); success = true; } catch (LuceneException& e) diff --git a/src/core/queryparser/QueryParseError.cpp b/src/core/queryparser/QueryParseError.cpp index 2348299a..ab2ed2b3 100644 --- a/src/core/queryparser/QueryParseError.cpp +++ b/src/core/queryparser/QueryParseError.cpp @@ -19,12 +19,12 @@ namespace Lucene const String& errorAfter, wchar_t curChar) { StringStream buffer; - buffer << L"Lexical error at line " << errorLine << L", column " << errorColumn + L". Encountered:"; + buffer << L"Lexical error at line " << errorLine << L", column " << errorColumn << L". Encountered:"; if (EOFSeen) buffer << L""; else buffer << L"\"" << addEscapes(String(1, curChar)) << L"\""; - buffer << L" (" + (int32_t)curChar << L"), after : \"" << addEscapes(errorAfter) + L"\""; + buffer << L" (" << (int32_t)curChar << L"), after : \"" << addEscapes(errorAfter) + L"\""; return buffer.str(); } From e82a0fcec5dd8edb6f2dd98575b7dd9cdb65fa53 Mon Sep 17 00:00:00 2001 From: Matt Richards Date: Mon, 21 Oct 2013 18:36:13 -0700 Subject: [PATCH 039/157] Fix compatibility with Boost versions before 1.54 Before 1.54, there was no support for varadic calls to boost:call_once(), so make the arrays static members to avoid the need to pass them to the static init methods. --- include/StandardTokenizerImpl.h | 15 +++-- .../standard/StandardTokenizerImpl.cpp | 60 +++++++++---------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/include/StandardTokenizerImpl.h b/include/StandardTokenizerImpl.h index 1ef35389..c418236f 100644 --- a/include/StandardTokenizerImpl.h +++ b/include/StandardTokenizerImpl.h @@ -27,39 +27,43 @@ namespace Lucene static const int32_t ZZ_BUFFERSIZE; /// Translates characters to character classes + static CharArray _ZZ_CMAP; static const wchar_t ZZ_CMAP_PACKED[]; static const int32_t ZZ_CMAP_LENGTH; static const int32_t ZZ_CMAP_PACKED_LENGTH; /// Translates characters to character classes - static void ZZ_CMAP_INIT(CharArray& zz_action); + static void ZZ_CMAP_INIT(); static const wchar_t* ZZ_CMAP(); /// Translates DFA states to action switch labels. + static IntArray _ZZ_ACTION; static const wchar_t ZZ_ACTION_PACKED_0[]; static const int32_t ZZ_ACTION_LENGTH; static const int32_t ZZ_ACTION_PACKED_LENGTH; /// Translates DFA states to action switch labels. - static void ZZ_ACTION_INIT(IntArray& zz_action); + static void ZZ_ACTION_INIT(); static const int32_t* ZZ_ACTION(); /// Translates a state to a row index in the transition table + static IntArray _ZZ_ROWMAP; static const wchar_t ZZ_ROWMAP_PACKED_0[]; static const int32_t ZZ_ROWMAP_LENGTH; static const int32_t ZZ_ROWMAP_PACKED_LENGTH; /// Translates a state to a row index in the transition table - static void ZZ_ROWMAP_INIT(IntArray& zz_rowmap); + static void ZZ_ROWMAP_INIT(); static const int32_t* ZZ_ROWMAP(); /// The transition table of the DFA + static IntArray _ZZ_TRANS; static const wchar_t ZZ_TRANS_PACKED_0[]; static const int32_t ZZ_TRANS_LENGTH; static const int32_t ZZ_TRANS_PACKED_LENGTH; /// The transition table of the DFA - static void ZZ_TRANS_INIT(IntArray& zz_trans); + static void ZZ_TRANS_INIT(); static const int32_t* ZZ_TRANS(); // error codes @@ -70,12 +74,13 @@ namespace Lucene static const wchar_t* ZZ_ERROR_MSG[]; /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState + static IntArray _ZZ_ATTRIBUTE; static const wchar_t ZZ_ATTRIBUTE_PACKED_0[]; static const int32_t ZZ_ATTRIBUTE_LENGTH; static const int32_t ZZ_ATTRIBUTE_PACKED_LENGTH; /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState - static void ZZ_ATTRIBUTE_INIT(IntArray& zz_attribute); + static void ZZ_ATTRIBUTE_INIT(); static const int32_t* ZZ_ATTRIBUTE(); /// The input device diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index e26c542f..7abcbdda 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -18,8 +18,9 @@ namespace Lucene { /// Initial size of the lookahead buffer const int32_t StandardTokenizerImpl::ZZ_BUFFERSIZE = 16384; - + /// Translates characters to character classes + CharArray StandardTokenizerImpl::_ZZ_CMAP; const wchar_t StandardTokenizerImpl::ZZ_CMAP_PACKED[] = { L"\11\0\1\0\1\15\1\0\1\0\1\14\22\0\1\0\5\0\1\5" @@ -84,7 +85,8 @@ namespace Lucene const int32_t StandardTokenizerImpl::ZZ_CMAP_LENGTH = 65536; const int32_t StandardTokenizerImpl::ZZ_CMAP_PACKED_LENGTH = 1154; - + + IntArray StandardTokenizerImpl::_ZZ_ACTION; const wchar_t StandardTokenizerImpl::ZZ_ACTION_PACKED_0[] = { L"\1\0\1\1\3\2\1\3\1\1\13\0\1\2\3\4" @@ -95,7 +97,8 @@ namespace Lucene const int32_t StandardTokenizerImpl::ZZ_ACTION_LENGTH = 51; const int32_t StandardTokenizerImpl::ZZ_ACTION_PACKED_LENGTH = 50; - + + IntArray StandardTokenizerImpl::_ZZ_ROWMAP; const wchar_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_0[] = { L"\0\0\0\16\0\34\0\52\0\70\0\16\0\106\0\124" @@ -109,7 +112,8 @@ namespace Lucene const int32_t StandardTokenizerImpl::ZZ_ROWMAP_LENGTH = 51; const int32_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_LENGTH = 102; - + + IntArray StandardTokenizerImpl::_ZZ_TRANS; const wchar_t StandardTokenizerImpl::ZZ_TRANS_PACKED_0[] = { L"\1\2\1\3\1\4\7\2\1\5\1\6\1\7\1\2" @@ -167,7 +171,8 @@ namespace Lucene L"Error: could not match input", L"Error: pushback value was too large" }; - + + IntArray StandardTokenizerImpl::_ZZ_ATTRIBUTE; const wchar_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_0[] = { L"\1\0\1\11\3\1\1\11\1\1\13\0\4\1\2\0" @@ -205,10 +210,10 @@ namespace Lucene { } - void StandardTokenizerImpl::ZZ_CMAP_INIT(CharArray& zz_cmap) + void StandardTokenizerImpl::ZZ_CMAP_INIT() { - zz_cmap = CharArray::newInstance(ZZ_CMAP_LENGTH); - wchar_t* result = zz_cmap.get(); + _ZZ_CMAP = CharArray::newInstance(ZZ_CMAP_LENGTH); + wchar_t* result = _ZZ_CMAP.get(); int32_t i = 0; // index in packed string int32_t j = 0; // index in unpacked array @@ -225,15 +230,14 @@ namespace Lucene const wchar_t* StandardTokenizerImpl::ZZ_CMAP() { static boost::once_flag once = BOOST_ONCE_INIT; - static CharArray _ZZ_CMAP; - boost::call_once(once, ZZ_CMAP_INIT, _ZZ_CMAP); + boost::call_once(once, ZZ_CMAP_INIT); return _ZZ_CMAP.get(); } - void StandardTokenizerImpl::ZZ_ACTION_INIT(IntArray& zz_action) + void StandardTokenizerImpl::ZZ_ACTION_INIT() { - zz_action = IntArray::newInstance(ZZ_ACTION_LENGTH); - int32_t* result = zz_action.get(); + _ZZ_ACTION = IntArray::newInstance(ZZ_ACTION_LENGTH); + int32_t* result = _ZZ_ACTION.get(); int32_t i = 0; // index in packed string int32_t j = 0; // index in unpacked array @@ -250,15 +254,14 @@ namespace Lucene const int32_t* StandardTokenizerImpl::ZZ_ACTION() { static boost::once_flag once = BOOST_ONCE_INIT; - static IntArray _ZZ_ACTION; - boost::call_once(once, ZZ_ACTION_INIT, _ZZ_ACTION); + boost::call_once(once, ZZ_ACTION_INIT); return _ZZ_ACTION.get(); } - void StandardTokenizerImpl::ZZ_ROWMAP_INIT(IntArray& zz_rowmap) + void StandardTokenizerImpl::ZZ_ROWMAP_INIT() { - zz_rowmap = IntArray::newInstance(ZZ_ROWMAP_LENGTH); - int32_t* result = zz_rowmap.get(); + _ZZ_ROWMAP = IntArray::newInstance(ZZ_ROWMAP_LENGTH); + int32_t* result = _ZZ_ROWMAP.get(); int32_t i = 0; // index in packed string int32_t j = 0; // index in unpacked array @@ -271,16 +274,15 @@ namespace Lucene const int32_t* StandardTokenizerImpl::ZZ_ROWMAP() { - static IntArray _ZZ_ROWMAP; static boost::once_flag once = BOOST_ONCE_INIT; - boost:call_once(once, ZZ_ROWMAP_INIT, _ZZ_ROWMAP); + boost:call_once(once, ZZ_ROWMAP_INIT); return _ZZ_ROWMAP.get(); } - void StandardTokenizerImpl::ZZ_TRANS_INIT(IntArray& zz_trans) + void StandardTokenizerImpl::ZZ_TRANS_INIT() { - zz_trans = IntArray::newInstance(ZZ_TRANS_LENGTH); - int32_t* result = zz_trans.get(); + _ZZ_TRANS = IntArray::newInstance(ZZ_TRANS_LENGTH); + int32_t* result = _ZZ_TRANS.get(); int32_t i = 0; // index in packed string int32_t j = 0; // index in unpacked array @@ -298,15 +300,14 @@ namespace Lucene const int32_t* StandardTokenizerImpl::ZZ_TRANS() { static boost::once_flag once = BOOST_ONCE_INIT; - static IntArray _ZZ_TRANS; - boost::call_once(once, ZZ_TRANS_INIT, _ZZ_TRANS); + boost::call_once(once, ZZ_TRANS_INIT); return _ZZ_TRANS.get(); } - void StandardTokenizerImpl::ZZ_ATTRIBUTE_INIT(IntArray& zz_attribute) + void StandardTokenizerImpl::ZZ_ATTRIBUTE_INIT() { - zz_attribute = IntArray::newInstance(ZZ_ATTRIBUTE_LENGTH); - int32_t* result = zz_attribute.get(); + _ZZ_ATTRIBUTE = IntArray::newInstance(ZZ_ATTRIBUTE_LENGTH); + int32_t* result = _ZZ_ATTRIBUTE.get(); int32_t i = 0; // index in packed string int32_t j = 0; // index in unpacked array @@ -323,8 +324,7 @@ namespace Lucene const int32_t* StandardTokenizerImpl::ZZ_ATTRIBUTE() { static boost::once_flag once = BOOST_ONCE_INIT; - static IntArray _ZZ_ATTRIBUTE; - boost::call_once(once, ZZ_ATTRIBUTE_INIT, _ZZ_ATTRIBUTE); + boost::call_once(once, ZZ_ATTRIBUTE_INIT); return _ZZ_ATTRIBUTE.get(); } From 523d07a468bb7209da07b99ff7ba7091b3eaefea Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Tue, 22 Oct 2013 14:02:24 +0200 Subject: [PATCH 040/157] Fix StandardTokenizerImpl.cpp compilation. 8628278 broke compilation due to a typo (boost:call_once instead of boost::call_once). Additionally, VC++ compilation with precompiled header was broken, because LuceneInc.h must be included as the very first header. --- src/core/analysis/standard/StandardTokenizerImpl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index 7abcbdda..d73a45c6 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -4,8 +4,6 @@ // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// -#include - #include "LuceneInc.h" #include "StandardTokenizerImpl.h" #include "StandardTokenizer.h" @@ -14,6 +12,8 @@ #include "TermAttribute.h" #include "MiscUtils.h" +#include + namespace Lucene { /// Initial size of the lookahead buffer @@ -275,7 +275,7 @@ namespace Lucene const int32_t* StandardTokenizerImpl::ZZ_ROWMAP() { static boost::once_flag once = BOOST_ONCE_INIT; - boost:call_once(once, ZZ_ROWMAP_INIT); + boost::call_once(once, ZZ_ROWMAP_INIT); return _ZZ_ROWMAP.get(); } From 2ac8183e48a0ab95fa3f405bc26b1b20d51755f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Sun, 27 Oct 2013 09:17:45 +0100 Subject: [PATCH 041/157] Fix accidental use of operator+ instead of operator<<. There was a typo in the output expression, appending a number to a string, instead of concatenating them as indented. --- src/core/index/CheckIndex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/index/CheckIndex.cpp b/src/core/index/CheckIndex.cpp index 9e910f1f..7f783d85 100644 --- a/src/core/index/CheckIndex.cpp +++ b/src/core/index/CheckIndex.cpp @@ -640,7 +640,7 @@ namespace Lucene std::wcout << L"WARNING: would write new segments file, and " << result->totLoseDocCount << L" documents would be lost, if -fix were specified\n\n"; else { - std::wcout << L"WARNING: " << result->totLoseDocCount + L" documents will be lost\n"; + std::wcout << L"WARNING: " << result->totLoseDocCount << L" documents will be lost\n"; std::wcout << L"NOTE: will write new segments file in 5 seconds; this will remove " << result->totLoseDocCount; std::wcout << L" docs from the index. THIS IS YOUR LAST CHANCE TO CTRL+C!\n"; for (int32_t sec = 0; sec < 5; ++sec) From dd9451bdff32bb7ebb72d791114734c3a509b95a Mon Sep 17 00:00:00 2001 From: Vaclav Slavik Date: Sun, 8 Dec 2013 18:08:16 +0100 Subject: [PATCH 042/157] Fix incorrect paths handling on Windows. Lucene++ keeps paths around as wide strings, but uses narrow char APIs (e.g. std::ifstream) when accessing files, using conversion to UTF-8 to get char* strings. This is correct on OS X and usually(!) correct on modern Unix systems, but is completely wrong on Windows, which _never_ uses UTF-8 for filenames. Fix this using boost::filesystem classes (path and streams) and appropriate conversions. In one place, use a Windows-specific workaround to deal with lack of wide char boost API. In particular: - Use boost::filesystem::*fstream classes that accept Unicode paths. - Use boost::filesystem::(w)path for manual conversion when needed. - When using char* only API (interprocess::file_lock), use GetShortPathName() as a workaround. --- include/InfoStream.h | 4 ++-- include/Lucene.h | 5 +++-- src/core/index/IndexReader.cpp | 6 +++--- src/core/store/FSDirectory.cpp | 6 +++--- src/core/store/MMapDirectory.cpp | 2 +- src/core/store/NativeFSLockFactory.cpp | 21 ++++++++++++++++++--- src/core/store/SimpleFSDirectory.cpp | 6 +++--- src/core/store/SimpleFSLockFactory.cpp | 6 +++--- src/core/util/FileReader.cpp | 4 ++-- src/core/util/FileUtils.cpp | 2 +- src/core/util/InfoStream.cpp | 2 +- 11 files changed, 40 insertions(+), 24 deletions(-) diff --git a/include/InfoStream.h b/include/InfoStream.h index 7a32bf27..273c1b40 100644 --- a/include/InfoStream.h +++ b/include/InfoStream.h @@ -8,7 +8,7 @@ #define INFOSTREAM_H #include "LuceneObject.h" -#include +#include namespace Lucene { @@ -36,7 +36,7 @@ namespace Lucene LUCENE_CLASS(InfoStreamFile); protected: - std::wofstream file; + boost::filesystem::wofstream file; public: virtual InfoStreamFile& operator<< (const String& t); diff --git a/include/Lucene.h b/include/Lucene.h index 838785fa..203bc3c8 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -65,8 +66,8 @@ namespace Lucene typedef boost::shared_ptr filelockPtr; typedef boost::shared_ptr threadPtr; - typedef boost::shared_ptr ofstreamPtr; - typedef boost::shared_ptr ifstreamPtr; + typedef boost::shared_ptr ofstreamPtr; + typedef boost::shared_ptr ifstreamPtr; typedef boost::shared_ptr localePtr; } diff --git a/src/core/index/IndexReader.cpp b/src/core/index/IndexReader.cpp index 2a70c518..4489441e 100644 --- a/src/core/index/IndexReader.cpp +++ b/src/core/index/IndexReader.cpp @@ -5,7 +5,7 @@ ///////////////////////////////////////////////////////////////////////////// #include "LuceneInc.h" -#include +#include #include #include "IndexReader.h" #include "_IndexReader.h" @@ -383,8 +383,8 @@ namespace Lucene { std::wcout << L"extract " << *file << L" with " << len << L" bytes to local directory..."; IndexInputPtr ii(cfr->openInput(*file)); - - std::ofstream f(StringUtils::toUTF8(*file).c_str(), std::ios::binary | std::ios::out); + + boost::filesystem::ofstream f(*file, std::ios::binary | std::ios::out); // read and write with a small buffer, which is more effective than reading byte by byte ByteArray buffer(ByteArray::newInstance(1024)); diff --git a/src/core/store/FSDirectory.cpp b/src/core/store/FSDirectory.cpp index 61655e41..77b23be6 100644 --- a/src/core/store/FSDirectory.cpp +++ b/src/core/store/FSDirectory.cpp @@ -5,7 +5,7 @@ ///////////////////////////////////////////////////////////////////////////// #include "LuceneInc.h" -#include +#include #include "FSDirectory.h" #include "NativeFSLockFactory.h" #include "SimpleFSDirectory.h" @@ -158,10 +158,10 @@ namespace Lucene for (int32_t retryCount = 0; retryCount < 5; ++retryCount) { - std::ofstream syncFile; + boost::filesystem::ofstream syncFile; try { - syncFile.open(StringUtils::toUTF8(path).c_str(), std::ios::binary | std::ios::in | std::ios::out); + syncFile.open(path, std::ios::binary | std::ios::in | std::ios::out); } catch (...) { diff --git a/src/core/store/MMapDirectory.cpp b/src/core/store/MMapDirectory.cpp index 98cc0f23..ac702728 100644 --- a/src/core/store/MMapDirectory.cpp +++ b/src/core/store/MMapDirectory.cpp @@ -43,7 +43,7 @@ namespace Lucene { try { - file.open(StringUtils::toUTF8(path).c_str(), _length); + file.open(boost::filesystem::wpath(path), _length); } catch (...) { diff --git a/src/core/store/NativeFSLockFactory.cpp b/src/core/store/NativeFSLockFactory.cpp index cc5e96ed..3719ba6b 100644 --- a/src/core/store/NativeFSLockFactory.cpp +++ b/src/core/store/NativeFSLockFactory.cpp @@ -5,7 +5,7 @@ ///////////////////////////////////////////////////////////////////////////// #include "LuceneInc.h" -#include +#include #include #include "NativeFSLockFactory.h" #include "_NativeFSLockFactory.h" @@ -119,11 +119,26 @@ namespace Lucene try { // we can get intermittent "access denied" here, so we treat this as failure to acquire the lock - std::ofstream f(StringUtils::toUTF8(path).c_str(), std::ios::binary | std::ios::out); + boost::filesystem::ofstream f(path, std::ios::binary | std::ios::out); if (f.is_open()) { - lock = newInstance(StringUtils::toUTF8(path).c_str()); + std::string lockpath; + + // file_lock only accepts char* filenames and we cannot losslessly convert Unicode paths to + // char*. The usual way to work around this is to use 8.3 short names. +#if defined(_WIN32) || defined(_WIN64) + wchar_t pathOut[MAX_PATH+1]; + if (::GetShortPathNameW(path.c_str(), pathOut, MAX_PATH+1) != 0) + { + lockpath = boost::filesystem::path(pathOut).string(); + } + else +#endif // Windows + { + lockpath = boost::filesystem::path(path).string(); + } + lock = newInstance(lockpath.c_str()); lock->lock(); } } diff --git a/src/core/store/SimpleFSDirectory.cpp b/src/core/store/SimpleFSDirectory.cpp index 4eaddc64..0aed22ef 100644 --- a/src/core/store/SimpleFSDirectory.cpp +++ b/src/core/store/SimpleFSDirectory.cpp @@ -5,7 +5,7 @@ ///////////////////////////////////////////////////////////////////////////// #include "LuceneInc.h" -#include +#include #include "SimpleFSDirectory.h" #include "_SimpleFSDirectory.h" #include "IndexOutput.h" @@ -45,7 +45,7 @@ namespace Lucene InputFile::InputFile(const String& path) { - file = newInstance(StringUtils::toUTF8(path).c_str(), std::ios::binary | std::ios::in); + file = newInstance(path, std::ios::binary | std::ios::in); if (!file->is_open()) boost::throw_exception(FileNotFoundException(path)); position = 0; @@ -175,7 +175,7 @@ namespace Lucene OutputFile::OutputFile(const String& path) { this->path = path; - file = newInstance(StringUtils::toUTF8(path).c_str(), std::ios::binary | std::ios::out); + file = newInstance(path, std::ios::binary | std::ios::out); } OutputFile::~OutputFile() diff --git a/src/core/store/SimpleFSLockFactory.cpp b/src/core/store/SimpleFSLockFactory.cpp index 4bec1be5..e1da300a 100644 --- a/src/core/store/SimpleFSLockFactory.cpp +++ b/src/core/store/SimpleFSLockFactory.cpp @@ -5,7 +5,7 @@ ///////////////////////////////////////////////////////////////////////////// #include "LuceneInc.h" -#include +#include #include "SimpleFSLockFactory.h" #include "_SimpleFSLockFactory.h" #include "FileUtils.h" @@ -61,10 +61,10 @@ namespace Lucene } else if (!FileUtils::isDirectory(lockDir)) boost::throw_exception(RuntimeException(L"Found regular file where directory expected: " + lockDir)); - std::ofstream f; + boost::filesystem::ofstream f; try { - f.open(StringUtils::toUTF8(FileUtils::joinPath(lockDir, lockFile)).c_str(), std::ios::binary | std::ios::out); + f.open(FileUtils::joinPath(lockDir, lockFile), std::ios::binary | std::ios::out); } catch (...) { diff --git a/src/core/util/FileReader.cpp b/src/core/util/FileReader.cpp index a8b55408..085789ee 100644 --- a/src/core/util/FileReader.cpp +++ b/src/core/util/FileReader.cpp @@ -5,7 +5,7 @@ ///////////////////////////////////////////////////////////////////////////// #include "LuceneInc.h" -#include +#include #include "FileReader.h" #include "MiscUtils.h" #include "FileUtils.h" @@ -18,7 +18,7 @@ namespace Lucene FileReader::FileReader(const String& fileName) { - this->file = newInstance(StringUtils::toUTF8(fileName).c_str(), std::ios::binary | std::ios::in); + this->file = newInstance(fileName, std::ios::binary | std::ios::in); if (!file->is_open()) boost::throw_exception(FileNotFoundException(fileName)); _length = FileUtils::fileLength(fileName); diff --git a/src/core/util/FileUtils.cpp b/src/core/util/FileUtils.cpp index e1cd0cd2..8d491d0b 100644 --- a/src/core/util/FileUtils.cpp +++ b/src/core/util/FileUtils.cpp @@ -89,7 +89,7 @@ namespace Lucene int32_t fd = _wopen(path.c_str(), _O_WRONLY | _O_CREAT | _O_BINARY, _S_IWRITE); return _chsize(fd, (long)length) == 0; #else - return truncate(StringUtils::toUTF8(path).c_str(), (off_t)length) == 0; + return truncate(boost::filesystem::path(path).c_str(), (off_t)length) == 0; #endif } catch (...) diff --git a/src/core/util/InfoStream.cpp b/src/core/util/InfoStream.cpp index a9e1b4ff..04f92d4e 100644 --- a/src/core/util/InfoStream.cpp +++ b/src/core/util/InfoStream.cpp @@ -19,7 +19,7 @@ namespace Lucene { } - InfoStreamFile::InfoStreamFile(const String& path) : file(StringUtils::toUTF8(path).c_str()) + InfoStreamFile::InfoStreamFile(const String& path) : file(path) { } From f194708855c920a2c9bbd5d650db80da9f9bcd5b Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 30 Jan 2014 11:16:13 +0100 Subject: [PATCH 043/157] Release version 3.0.5. --- README.rst | 2 +- doxygen/lucene++ | 2 +- src/core/util/Constants.cpp | 16 ++++++++-------- wscript | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.rst b/README.rst index 3614da77..aa072bec 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Lucene++ ========== -Welcome to lucene++ version **3.0.4**. +Welcome to lucene++ version **3.0.5**. Lucene++ is an up to date C++ port of the popular Java `Lucene `_ library, a high-performance, full-featured text search engine. diff --git a/doxygen/lucene++ b/doxygen/lucene++ index 827d7e52..3ddd69c7 100644 --- a/doxygen/lucene++ +++ b/doxygen/lucene++ @@ -31,7 +31,7 @@ PROJECT_NAME = Lucene++ # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 3.0.4 +PROJECT_NUMBER = 3.0.5 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/src/core/util/Constants.cpp b/src/core/util/Constants.cpp index f96e86f9..4c374b77 100644 --- a/src/core/util/Constants.cpp +++ b/src/core/util/Constants.cpp @@ -20,28 +20,28 @@ namespace Lucene #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) String Constants::OS_NAME = L"BSD"; #endif - - String Constants::LUCENE_MAIN_VERSION = L"3.0.3.4"; - String Constants::LUCENE_VERSION = L"3.0.3"; - + + String Constants::LUCENE_MAIN_VERSION = L"3.0.5"; + String Constants::LUCENE_VERSION = L"3.0.5"; + Constants::Constants() { // private } - + Constants::~Constants() { } - + LuceneVersion::LuceneVersion() { // private } - + LuceneVersion::~LuceneVersion() { } - + bool LuceneVersion::onOrAfter(LuceneVersion::Version first, LuceneVersion::Version second) { return (first >= second); diff --git a/wscript b/wscript index a8eb02ab..06dbfcb6 100644 --- a/wscript +++ b/wscript @@ -13,7 +13,7 @@ from TaskGen import feature, after import Task APPNAME='Lucene++' -VERSION='3.0.4.0' +VERSION='3.0.5.0' top = '.' out = 'bin' From f588f8dbe29f2a2cfb10faa85fe4a7c1c473f817 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 7 Feb 2014 11:02:49 +0000 Subject: [PATCH 044/157] Fixed crash in TermBuffer. Thanks to Artem Goussev. --- src/core/index/TermBuffer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/index/TermBuffer.cpp b/src/core/index/TermBuffer.cpp index b6baedc1..e1b3dc78 100644 --- a/src/core/index/TermBuffer.cpp +++ b/src/core/index/TermBuffer.cpp @@ -60,7 +60,10 @@ namespace Lucene int32_t length = input->readVInt(); int32_t totalLength = start + length; if (preUTF8Strings) + { + text->setLength(totalLength); text->setLength(start + input->readChars(text->result.get(), start, length)); + } else { StringUtils::toUTF8(text->result.get(), text->length, bytes); From 5e53efc5d5192f0282d9fea7ce35938e2b4bc173 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sun, 9 Feb 2014 16:40:11 +0000 Subject: [PATCH 045/157] Simplify build and installation. - Remove waf in favour of CMake. - Remove static builds. - Remove custom allocator (no longer required in most cases). - Do not build separate project for .c files. --- CMakeLists.txt | 307 +- README.rst | 42 +- build/clang.py | 55 - build/gch.py | 39 - cmake/CreateLucene++Packages.cmake | 97 +- cmake/Lucene++Docs.cmake | 36 +- cmake/Toolchain-mingw32.cmake | 26 +- doc/Doxyfile.cmake | 50 +- doc/helpheader.htm.cmake | 6 +- include/BitSet.h | 2 +- include/Collection.h | 2 +- include/Config.h.cmake | 10 - include/HashMap.h | 4 +- include/HashSet.h | 2 +- include/Lucene.h | 10 +- include/LuceneAllocator.h | 130 - include/LuceneFactory.h | 20 +- include/Map.h | 2 +- include/PriorityQueue.h | 2 +- include/Set.h | 2 +- include/SimpleLRUCache.h | 2 +- lib/.gitignore | 1 - liblucene++-contrib.pc.cmake | 4 +- liblucene++.pc.cmake | 2 +- scripts/llvm/README | 12 - scripts/llvm/build/clang.py | 72 - scripts/llvm/waf | Bin 76812 -> 0 bytes scripts/llvm/wscript | 268 -- src/contrib/CMakeLists.txt | 105 +- src/core/CMakeLists.txt | 107 +- src/core/util/LuceneAllocator.cpp | 26 +- src/core/util/LuceneThread.cpp | 1 - src/core/util/nedmalloc/License.txt | 23 - src/core/util/nedmalloc/malloc.c.h | 5694 --------------------------- src/core/util/nedmalloc/nedmalloc.c | 950 ----- src/core/util/nedmalloc/nedmalloc.h | 180 - src/demo/CMakeLists.txt | 49 +- src/test/CMakeLists.txt | 63 +- waf | Bin 76812 -> 0 bytes wscript | 208 - 40 files changed, 433 insertions(+), 8178 deletions(-) delete mode 100644 build/clang.py delete mode 100644 build/gch.py delete mode 100644 lib/.gitignore delete mode 100644 scripts/llvm/README delete mode 100644 scripts/llvm/build/clang.py delete mode 100644 scripts/llvm/waf delete mode 100644 scripts/llvm/wscript delete mode 100644 src/core/util/nedmalloc/License.txt delete mode 100644 src/core/util/nedmalloc/malloc.c.h delete mode 100644 src/core/util/nedmalloc/nedmalloc.c delete mode 100644 src/core/util/nedmalloc/nedmalloc.h delete mode 100755 waf delete mode 100644 wscript diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c750060..6c84825d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,219 +1,170 @@ -project(lucene++-base) +project(lucene++) -#################################### -# VERSION information -#These versions match the Lucene version -SET(LUCENE++_VERSION_MAJOR "3") -SET(LUCENE++_VERSION_MINOR "0") -SET(LUCENE++_VERSION_REVISION "3") -SET(LUCENE++_VERSION_PATCH "4") - -# SOVERSION information -#Must be incremented for releases if the api is not backwards compatible -SET(LUCENE++_SOVERSION "0") - -#derived versions -MATH(EXPR LUCENE++_INT_VERSION "(${LUCENE++_VERSION_MAJOR} * 1000000) + (${LUCENE++_VERSION_MINOR} * 10000) + (${LUCENE++_VERSION_REVISION} * 100) + (${LUCENE++_VERSION_PATCH} * 1)" ) -SET(LUCENE++_VERSION "${LUCENE++_VERSION_MAJOR}.${LUCENE++_VERSION_MINOR}.${LUCENE++_VERSION_REVISION}.${LUCENE++_VERSION_PATCH}") -MESSAGE(${LUCENE++_INT_VERSION}) -MESSAGE(${LUCENE++_VERSION}) +cmake_minimum_required(VERSION 2.6) -#################################### +set(lucene++_VERSION_MAJOR 3) +set(lucene++_VERSION_MINOR 0) +set(lucene++_VERSION_PATCH 5) -#################################### -# Build system options and includes -#################################### -CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) -#build policies -if(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -endif(COMMAND cmake_policy) +set(lucene++_SOVERSION "0") + +set(lucene++_VERSION + "${lucene++_VERSION_MAJOR}.${lucene++_VERSION_MINOR}.${lucene++_VERSION_PATCH}" +) # include specific modules set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -#if setup using the Toolchain-llvm.cmake file, then use llvm... -IF ( ENABLE_LLVM ) - INCLUDE (Toolchain-llvm) -ENDIF ( ENABLE_LLVM ) - -#define options... -INCLUDE (Lucene++Docs) -INCLUDE (FindThreads) -INCLUDE (TestCXXAcceptsFlag) -ENABLE_TESTING() - -#Single output directory for building all executables and libraries. -SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE PATH "Executable Output Directory" FORCE) -SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE PATH "Library Output Directory" FORCE) -#################################### +# if setup using the Toolchain-llvm.cmake file, then use llvm... +if(ENABLE_LLVM) + include(Toolchain-llvm) +endif() #################################### -#user specified build options -#################################### -IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING - "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." - FORCE) -ELSE(NOT CMAKE_BUILD_TYPE) - MESSAGE( "Compiling as ${CMAKE_BUILD_TYPE}" ) -ENDIF(NOT CMAKE_BUILD_TYPE) - -OPTION(ENABLE_PACKAGING - "create build scripts for creating lucene++ packages" - OFF) -OPTION(ENABLE_CUSTOM_ALLOCATOR - "use custom memory allocator" - OFF) -OPTION(ENABLE_NEDMALLOC - "use nedmalloc for memory allocations" - OFF) -OPTION(LUCENE_USE_STATIC_BOOST_LIBS - "use static boost libraries " - OFF) -OPTION(ENABLE_CYCLIC_CHECK - "enable cyclic checking " - OFF) - -#install path options -SET(LIB_DESTINATION "lib" CACHE STRING "Define lib output directory name") - -IF ( ENABLE_CUSTOM_ALLOCATOR ) - SET(DEFINE_USE_CUSTOM_ALLOCATOR "define") -ELSE ( ENABLE_CUSTOM_ALLOCATOR ) - SET(DEFINE_USE_CUSTOM_ALLOCATOR "undef") -ENDIF ( ENABLE_CUSTOM_ALLOCATOR ) - -IF ( ENABLE_NEDMALLOC ) - SET(DEFINE_USE_NEDMALLOC "define") -ELSE ( ENABLE_NEDMALLOC ) - SET(DEFINE_USE_NEDMALLOC "undef") -ENDIF ( ENABLE_NEDMALLOC ) - -IF ( ENABLE_CYCLIC_CHECK ) - SET(DEFINE_USE_CYCLIC_CHECK "define") -ELSE ( ENABLE_CYCLIC_CHECK ) - SET(DEFINE_USE_CYCLIC_CHECK "undef") -ENDIF ( ENABLE_CYCLIC_CHECK ) +# user specified build options #################################### +if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif() + +option(ENABLE_PACKAGING + "Create build scripts for creating lucene++ packages" + OFF +) +option(LUCENE_USE_STATIC_BOOST_LIBS + "Use static boost libraries" + OFF +) +option(ENABLE_CYCLIC_CHECK + "Enable cyclic checking" + OFF +) + +#################################### +# bootstrap +#################################### + +find_package(Threads REQUIRED) +find_package(Boost COMPONENTS + date_time + filesystem + iostreams + regex + system + thread + unit_test_framework + REQUIRED +) +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_LIBS ${LUCENE_USE_STATIC_BOOST_LIBS}) + +set(lucene_boost_libs + ${Boost_LIBRARIES} + ${Boost_FILESYSTEM_LIBRARIES} + ${Boost_IOSTREAMS_LIBRARIES} + ${Boost_REGEX_LIBRARIES} + ${Boost_SYSTEM_LIBRARIES} + ${Boost_THREAD_LIBRARIES} +) + +include(Lucene++Docs) +include(TestCXXAcceptsFlag) + +set(LIB_DESTINATION + "lib" CACHE STRING "Define lib output directory name" +) + +if(ENABLE_CYCLIC_CHECK) + set(DEFINE_USE_CYCLIC_CHECK "define") +else() + set(DEFINE_USE_CYCLIC_CHECK "undef") +endif() #################################### -# PLATFORM specific options +# platform specific options #################################### -#add a debug build postfix if(WIN32 OR WIN64) - set(CMAKE_DEBUG_POSTFIX "d") -endif(WIN32 OR WIN64) + set(CMAKE_DEBUG_POSTFIX "d") +endif() if(NOT MSVC AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") - add_definitions(-fPIC) -endif(NOT MSVC AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") + add_definitions(-fPIC) +endif() -INCLUDE(MacroCheckGccVisibility) +include(MacroCheckGccVisibility) MACRO_CHECK_GCC_VISIBILITY(LPP_HAVE_GXXCLASSVISIBILITY) -if ( LPP_HAVE_GXXCLASSVISIBILITY ) - ADD_DEFINITIONS(-DLPP_HAVE_GXXCLASSVISIBILITY) +if(LPP_HAVE_GXXCLASSVISIBILITY) + add_definitions(-DLPP_HAVE_GXXCLASSVISIBILITY) endif() -IF(CYGWIN) - ADD_DEFINITIONS(-D__LARGE64_FILES) -ENDIF(CYGWIN) - -#set ansi mode -SET(ENABLE_ANSI_MODE OFF) -IF(CMAKE_COMPILER_IS_GNUCXX) - SET(ENABLE_ANSI_MODE ON) - - #exceptions: - IF(MINGW OR CYGWIN) - SET(ENABLE_ANSI_MODE OFF) - ENDIF(MINGW OR CYGWIN) -ENDIF(CMAKE_COMPILER_IS_GNUCXX) -IF ( CMAKE_COMPILER_IS_GNUCC ) - IF( ENABLE_ANSI_MODE ) - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi") - ENDIF ( ENABLE_ANSI_MODE ) -ENDIF(CMAKE_COMPILER_IS_GNUCC) - -SET( CMAKE_EXE_LINKER_FLAGS "-s") - -#################################### -#find boost -#################################### -SET(Boost_USE_STATIC_LIBS ${LUCENE_USE_STATIC_BOOST_LIBS}) -SET(Boost_USE_MULTITHREADED ON) -#Boost 1.38 required for bug fixes in basic_streambuf. -#The following line fails in earlier builds, so if altered, may allow older versions of boost: -#boost::gregorian::date date = parser.parse_date(paddedDate.c_str(), dateFormat->c_str(), svp); -find_package( Boost 1.38.0 COMPONENTS date_time filesystem iostreams regex system thread unit_test_framework REQUIRED) -IF (Boost_FOUND) - MESSAGE( STATUS "boost found: includes in ${Boost_INCLUDE_DIRS}, library in ${Boost_LIBRARY_DIRS}") - SET(LUCENE_BOOST_LIBS - ${Boost_FILESYSTEM_LIBRARY_RELEASE} - ${Boost_IOSTREAMS_LIBRARY_RELEASE} - ${Boost_REGEX_LIBRARY_RELEASE} - ${Boost_SYSTEM_LIBRARY_RELEASE} - ${Boost_THREAD_LIBRARY_RELEASE}) -ENDIF (Boost_FOUND) +if(CYGWIN) + add_definitions(-D__LARGE64_FILES) +endif() #################################### -# Pre-Compiled headers +# pre-compiled headers #################################### -INCLUDE(PCHSupport) - -#todo: make this optional and make it possible to add more headers - like boost threads - +include(PCHSupport) ################################# # generate Config.h ################################# +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/include/Config.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/include/Config.h @ONLY +) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/Config.h.cmake - ${CMAKE_CURRENT_BINARY_DIR}/include/Config.h @ONLY) +include_directories( + ${CMAKE_CURRENT_BINARY_DIR}/include +) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/include) - -#################################### -# The subdirs -#################################### -#include sub-projects -ADD_SUBDIRECTORY (src/core) -ADD_SUBDIRECTORY (src/contrib) -ADD_SUBDIRECTORY (src/demo EXCLUDE_FROM_ALL) -ADD_SUBDIRECTORY (src/test) +add_subdirectory(src/core) +add_subdirectory(src/contrib) +add_subdirectory(src/demo) +add_subdirectory(src/test) ################################# # install pkg-config file ################################# -IF(NOT WIN32) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/liblucene++.pc.cmake - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc @ONLY) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/liblucene++-contrib.pc.cmake - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc @ONLY) - - install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc - DESTINATION ${LIB_DESTINATION}/pkgconfig ) -ENDIF(NOT WIN32) +if(NOT WIN32) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/liblucene++.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc @ONLY) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/liblucene++-contrib.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc @ONLY) + install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc + ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc + DESTINATION ${LIB_DESTINATION}/pkgconfig) +endif() #################################### -# Custom targets +# custom targets #################################### -#add uninstall command -CONFIGURE_FILE( +configure_file( "${CMAKE_MODULE_PATH}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE @ONLY) -ADD_CUSTOM_TARGET(uninstall - "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + IMMEDIATE @ONLY +) +add_custom_target( + uninstall + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" +) -#################################### -# Finalise build script -#################################### +if(ENABLE_PACKAGING) + include(CreateLucene++Packages) +endif() + +enable_testing() -#this must go last... -IF (ENABLE_PACKAGING) - INCLUDE(CreateLucene++Packages) -ENDIF ( ENABLE_PACKAGING) +message("** Build Summary **") +message(" Version: ${lucene++_VERSION}") +message(" Prefix: ${CMAKE_INSTALL_PREFIX}") +message(" Build Type: ${CMAKE_BUILD_TYPE}") +message(" Architecture: ${CMAKE_SYSTEM_PROCESSOR}") +message(" System: ${CMAKE_SYSTEM_NAME}") +message(" Boost Include: ${Boost_INCLUDE_DIRS}") +message(" Boost Library: ${Boost_LIBRARY_DIRS}") diff --git a/README.rst b/README.rst index aa072bec..984a3825 100644 --- a/README.rst +++ b/README.rst @@ -24,8 +24,8 @@ Official `Java Lucene `_ - useful `Lucene in Action `_ by Otis Gospodnetic and Erik Hatcher. -Build Instructions using CMake ------------------------------- +Build Instructions +------------------ You'll need the `Boost `_ libraries installed somewhere. @@ -38,50 +38,24 @@ On Debian systems, the following packages are required: - libboost-iostreams-dev - libboost-test-dev -__ https://github.com/luceneplusplus/LucenePlusPlus/issues/30 - To build the library the following commands should be issued:: - $ cmake . + $ mkdir build; cd build + $ cmake .. $ make $ make install -To build the demo programs, execute the following after having first built -the library:: +To build the demo programs, execute the following after having first built the library:: $ make indexfiles searchfiles deletefiles -Build Instructions using Waf ------------------------------- - -**After running CMake** you can use `Waf `_ to drive the build. Waf requires that you have a recent version of `Python `_ installed on your system. - -To build the library the following commands should be issued:: - - $ ./waf configure - $ ./waf --static build - - -Additionally static builds of the following libraries are required for a successful build: - -- boost::date_time -- boost::filesystem -- boost::regex -- boost::thread -- boost::system -- boost::iostreams -- boost::unit_test_framework - -The libraries and headers should be made available at a standard prefix (``/usr/local`` for example). - - Build Instructions for Windows systems -------------------------------------- -Open solution lucene++.sln located in the *msvc* folder into Visual Studio 2008 and build. +Open solution lucene++.sln located in the *msvc* folder into Visual Studio and build. -**Note: "BOOST_ROOT" environment variable must be defined to point to the Boost library directory (eg. c:\\boost_1_44_0)** +**Note: "BOOST_ROOT" environment variable must be defined to point to the Boost library directory (eg. c:\\boost_1_51_0)** You'll need Boost installed. @@ -118,8 +92,6 @@ Acknowledgements ---------------- - Ben van Klinken and contributors to the CLucene project for inspiring this project. -- Jamie Kirkpatrick for cross-platform and waf build support. -- `nedmalloc `_ Copyright 2005-2006 Niall Douglas - md5 Copyright (C) 1999, 2000, 2002 Aladdin Enterprises - `Unicode character properties (guniprop) `_ Copyright (C) 1999 Tom Tromey, Copyright (C) 2000 Red Hat, Inc. diff --git a/build/clang.py b/build/clang.py deleted file mode 100644 index fcdae898..00000000 --- a/build/clang.py +++ /dev/null @@ -1,55 +0,0 @@ -############################################################################# -## Copyright (c) 2009-2011 Alan Wright. All rights reserved. -## Distributable under the terms of either the Apache License (Version 2.0) -## or the GNU Lesser General Public License. -############################################################################# - -from TaskGen import feature -import Options -import sys - - -@feature('cc') -def apply_clang(self): - ''' - Replaced the default compiler with clang if required. - ''' - if not getattr(self, 'clang', False) or Options.options.disable_clang: - return - self.env['CC'] = self.env['CLANG'] or self.env['CC'] - if sys.platform == "darwin": - # workaround problems with non-static inline functions - # http://clang.llvm.org/compatibility.html - self.env['CCFLAGS'] += ['-std=gnu89'] - - -@feature('cc') -def apply_clang_cpp(self): - ''' - Replaced the default compiler with clang if required. - ''' - if not getattr(self, 'clang', False) or Options.options.disable_clang: - return - self.env['CPP'] = self.env['CLANGPP'] or self.env['CXX'] - self.env['CXX'] = self.env['CLANGPP'] or self.env['CXX'] - if sys.platform == "darwin": - self.env['shlib_CXXFLAGS'] = ['-fPIC'] - - -def options(opt): - """ - Add options specific the codehash tool - """ - opt.add_option('--noclang', - dest = 'disable_clang', - action = 'store_true', - default = False, - help = 'disable the clang compiler if it is available') - - -def configure(conf): - search_paths = ['/Xcode4/usr/bin/'] if sys.platform == "darwin" else [] - if not getattr(conf, 'clang', False) or Options.options.disable_clang: - return - conf.find_program('clang', var='CLANG') - conf.find_program('clang++', var='CLANGPP', path_list = search_paths) diff --git a/build/gch.py b/build/gch.py deleted file mode 100644 index 6e3ccb40..00000000 --- a/build/gch.py +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################# -## Copyright (c) 2009-2011 Alan Wright. All rights reserved. -## Distributable under the terms of either the Apache License (Version 2.0) -## or the GNU Lesser General Public License. -############################################################################# - -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006 (ita) - -""" -for some obscure reason, the precompiled header will not be taken if -all.h is in the same directory as main.cpp -we recommend to add the header to compile in a separate directory without any sources - -Note: the #warning will come once when the .h is compiled, it will not come when the .cpp is compiled -Note: do not forget to set the include paths (include=...) -""" - -from waflib.TaskGen import feature, after -from waflib.Task import Task -from waflib.Tools import c_preproc - -#@feature('cxx') <- python >= 2.4 -#@after('apply_link') -def process_pch(self): - if getattr(self, 'pch', ''): - nodes = self.to_nodes(self.pch) - for x in nodes: - self.create_task('gchx', x, x.change_ext('.gch')) -feature('cxx')(process_pch) -after('apply_link')(process_pch) - -class gchx(Task): - run_str = '${CXX} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}' - scan = c_preproc.scan - ext_out = ['.h'] - color = 'BLUE' - diff --git a/cmake/CreateLucene++Packages.cmake b/cmake/CreateLucene++Packages.cmake index 8c9fd83e..4c11f99e 100644 --- a/cmake/CreateLucene++Packages.cmake +++ b/cmake/CreateLucene++Packages.cmake @@ -1,85 +1,82 @@ #Creates all the relevant packages -SET(CPACK_PACKAGE_VERSION_MAJOR ${LUCENE++_VERSION_MAJOR}) -SET(CPACK_PACKAGE_VERSION_MINOR ${LUCENE++_VERSION_MINOR}) -SET(CPACK_PACKAGE_VERSION_REVISION ${LUCENE++_VERSION_REVISION}) -SET(CPACK_PACKAGE_VERSION_PATCH ${LUCENE++_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MAJOR ${lucene++_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${lucene++_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${lucene++_VERSION_MAJOR}) -SET(CPACK_PACKAGE_VERSION ${LUCENE++_VERSION}) -SET(CPACK_PACKAGE_SOVERSION ${LUCENE++_SOVERSION}) +set(CPACK_PACKAGE_VERSION ${lucene++_VERSION}) +set(CPACK_PACKAGE_SOVERSION ${lucene++_SOVERSION}) -SET(CPACK_PACKAGE_VENDOR "Alan Wright") -SET(CPACK_PACKAGE_CONTACT "alanwright.home@googlemail.com") -SET(CPACK_PACKAGE_NAME "liblucene++") +set(CPACK_PACKAGE_VENDOR "Alan Wright") +set(CPACK_PACKAGE_CONTACT "alanwright.home@googlemail.com") +set(CPACK_PACKAGE_NAME "liblucene++") -SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") -SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Lucene++ is an up to date C++ port of the popular Java Lucene library, a high-performance, full-featured text search engine") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Lucene++ is an up to date C++ port of the popular Java Lucene library, a high-performance, full-featured text search engine") -SET(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") -SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") -#SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") +set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") #so, what are we going to install? -SET(CPACK_INSTALL_CMAKE_PROJECTS +set(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR};lucene++;ALL;/") -SET(CPACK_COMPONENTS_ALL development runtime) -SET(CPACK_GENERATOR "TGZ") -SET(CPACK_PACKAGE_FILE_NAME "lucene++-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}") +set(CPACK_COMPONENTS_ALL development runtime) +set(CPACK_GENERATOR "TGZ") +set(CPACK_PACKAGE_FILE_NAME "lucene++-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}") -IF( (WIN32 OR WIN64) AND NOT UNIX) - SET(CPACK_SOURCE_GENERATOR "ZIP") -ELSE( (WIN32 OR WIN64) AND NOT UNIX) - SET(CPACK_SOURCE_GENERATOR "TBZ2;TGZ") -ENDIF( (WIN32 OR WIN64) AND NOT UNIX) -SET(CPACK_SOURCE_PACKAGE_FILE_NAME "lucene++-${CPACK_PACKAGE_VERSION}-Source") +if((WIN32 OR WIN64) AND NOT UNIX) + set(CPACK_SOURCE_GENERATOR "ZIP") +else() + set(CPACK_SOURCE_GENERATOR "TBZ2;TGZ") +endif() +set(CPACK_SOURCE_PACKAGE_FILE_NAME "lucene++-${CPACK_PACKAGE_VERSION}-Source") #specific packaging requirements:, -SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.4), libgcc1 (>= 1:4.1.1-21), libstdc++6 (>= 4.1.1-21), libboost-date-time1.42.0, libboost-filesystem1.42.0, libboost-regex1.42.0, libboost-thread1.42.0, libboost-iostreams1.42.0") -SET(CPACK_DEBIAN_PACKAGE_SECTION "libs") -SET(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0") -SET(CPACK_RPM_PACKAGE_GROUP "libs") -SET(CPACK_RPM_PACKAGE_REQUIRES "libboost-date-time1.42.0, libboost-filesystem1.42.0, libboost-regex1.42.0, libboost-thread1.42.0, libboost-iostreams1.42.0") +set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.4), libgcc1 (>= 1:4.1.1-21), libstdc++6 (>= 4.1.1-21), libboost-date-time1.42.0, libboost-filesystem1.42.0, libboost-regex1.42.0, libboost-thread1.42.0, libboost-iostreams1.42.0") +set(CPACK_DEBIAN_PACKAGE_SECTION "libs") +set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0") +set(CPACK_RPM_PACKAGE_GROUP "libs") +set(CPACK_RPM_PACKAGE_REQUIRES "libboost-date-time1.42.0, libboost-filesystem1.42.0, libboost-regex1.42.0, libboost-thread1.42.0, libboost-iostreams1.42.0") #don't include the current binary dir. -get_filename_component(lucene++-base_BINARY_DIR_name ${lucene++-base_BINARY_DIR} NAME) -SET(CPACK_SOURCE_IGNORE_FILES +get_filename_component(lucene++_BINARY_DIR_name ${lucene++_BINARY_DIR} NAME) +set(CPACK_SOURCE_IGNORE_FILES "/\\\\.svn/" "/\\\\.git/" - "/\\\\.waf*/" "\\\\.swp$" "\\\\.#;/#" ".*~" ".*\\\\.tmp" ".*\\\\.save" - "/${lucene++-base_BINARY_DIR_name}/" + "/${lucene++_BINARY_DIR_name}/" ) -IF( (WIN32 OR WIN64) AND NOT UNIX) +if((WIN32 OR WIN64) AND NOT UNIX) # There is a bug in NSI that does not handle full unix paths properly. Make # sure there is at least one set of four (4) backlasshes. - SET(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") - #SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp") - #SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\MyExecutable.exe") - SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} Lucene++ Library") - SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lucene++.sourceforge.net") - SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lucene++.sourceforge.net") - SET(CPACK_NSIS_CONTACT "lucene++-developers@lists.sourceforge.net") - #SET(CPACK_NSIS_MODIFY_PATH ON) -ELSE( (WIN32 OR WIN64) AND NOT UNIX) -# SET(CPACK_STRIP_FILES "bin/xxx") - SET(CPACK_SOURCE_STRIP_FILES "") -ENDIF( (WIN32 OR WIN64) AND NOT UNIX) -#SET(CPACK_PACKAGE_EXECUTABLES "MyExecutable" "My Executable") + set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") + #set(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp") + #set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\MyExecutable.exe") + set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} Lucene++ Library") + set(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lucene++.sourceforge.net") + set(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lucene++.sourceforge.net") + set(CPACK_NSIS_CONTACT "lucene++-developers@lists.sourceforge.net") + #set(CPACK_NSIS_MODIFY_PATH ON) +else() +# set(CPACK_STRIP_FILES "bin/xxx") + set(CPACK_SOURCE_STRIP_FILES "") +endif() +#set(CPACK_PACKAGE_EXECUTABLES "MyExecutable" "My Executable") -ADD_CUSTOM_TARGET(dist-package +add_custom_target(dist-package COMMAND rsync -avP -e ssh ${CPACK_PACKAGE_FILE_NAME}.* ustramooner@frs.sourceforge.net:uploads/ # DEPENDS package ) -ADD_CUSTOM_TARGET(dist-package_source +add_custom_target(dist-package_source COMMAND rsync -avP -e ssh ${CPACK_SOURCE_PACKAGE_FILE_NAME}.* ustramooner@frs.sourceforge.net:uploads/ # DEPENDS package_source ) #this must be last -INCLUDE(CPack) +include(CPack) diff --git a/cmake/Lucene++Docs.cmake b/cmake/Lucene++Docs.cmake index 52f2f246..da0f4b23 100644 --- a/cmake/Lucene++Docs.cmake +++ b/cmake/Lucene++Docs.cmake @@ -22,9 +22,9 @@ MACRO(SET_BLANK) ENDMACRO(SET_BLANK) IF (ENABLE_DOCS) - OPTION(DOCS_HTML_HELP + OPTION(DOCS_HTML_HELP "Doxygen should compile HTML into a Help file (CHM)." NO) - + OPTION(DOCS_HTML "Doxygen should build HTML documentation." YES) OPTION(DOCS_XML @@ -35,7 +35,7 @@ IF (ENABLE_DOCS) "Doxygen should build man documentation." NO) OPTION(DOCS_TAGFILE "Doxygen should build a tagfile." NO) - + OPTION(DOCS_LATEX "Doxygen should build Latex documentation." NO ) @@ -48,12 +48,12 @@ IF (ENABLE_DOCS) DOCS_MAN DOCS_TAGFILE ) - + # # Check for the tools # FIND_PACKAGE(Doxygen) - + IF ( DOXYGEN_FOUND ) # This creates a new target to build documentation. # It runs ${DOXYGEN_EXECUTABLE} which is the full path and executable to @@ -64,7 +64,7 @@ IF (ENABLE_DOCS) ADD_CUSTOM_TARGET(doc ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/doc/doxyfile ) - + IF ( DOCS_HTML_HELP ) IF ( NOT DOCS_HTML ) MESSAGE ( FATAL_ERROR "DOCS_HTML is required to buidl DOCS_HTML_HELP" ) @@ -73,7 +73,7 @@ IF (ENABLE_DOCS) IF ( NOT HTML_HELP_COMPILER ) MESSAGE(FATAL_ERROR "HTML Help compiler not found, turn DOCS_HTML_HELP off to proceed") ENDIF ( NOT HTML_HELP_COMPILER ) - + #make cygwin work with hhc... IF ( CYGWIN ) EXECUTE_PROCESS ( COMMAND cygpath "${HTML_HELP_COMPILER}" @@ -85,22 +85,22 @@ IF (ENABLE_DOCS) SET ( HTML_HELP_COMPILER_EX ${HTML_HELP_COMPILER} ) ENDIF ( CYGWIN ) ENDIF ( DOCS_HTML_HELP ) - + IF ( DOCS_LATEX ) FIND_PACKAGE(LATEX) IF ( NOT LATEX_COMPILER ) MESSAGE(FATAL_ERROR "Latex compiler not found, turn DOCS_LATEX off to proceed") ENDIF ( NOT LATEX_COMPILER ) ENDIF ( DOCS_LATEX ) - + FIND_PACKAGE(Perl) - + IF ( DOXYGEN_DOT_EXECUTABLE ) SET ( HAVE_DOT "YES" ) ELSE ( DOXYGEN_DOT_EXECUTABLE ) SET ( HAVE_DOT "NO" ) ENDIF ( DOXYGEN_DOT_EXECUTABLE ) - + #doxygen expects YES/NO parameters SET_YESNO( DOCS_HTML_HELP @@ -117,17 +117,17 @@ IF (ENABLE_DOCS) HTML_HELP_COMPILER LATEX_COMPILER ) - + IF ( DOCS_TAGFILE ) SET ( DOCS_TAGFILE_LOCATION "${PROJECT_BINARY_DIR}/doc/tag/lucene++.tag" ) ENDIF ( DOCS_TAGFILE ) - + # This processes our Doxyfile.cmake and substitutes paths to generate a final Doxyfile CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/Doxyfile.cmake ${PROJECT_BINARY_DIR}/doc/doxyfile ) CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/helpheader.htm.cmake ${PROJECT_BINARY_DIR}/doc/helpheader.htm ) CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/helpfooter.htm.cmake ${PROJECT_BINARY_DIR}/doc/helpfooter.htm ) CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/doxygen.css.cmake ${PROJECT_BINARY_DIR}/doc/html/doxygen.css ) - + #create a target for tar.gz html help FIND_PACKAGE(UnixCommands) IF ( TAR AND GZIP ) @@ -137,20 +137,20 @@ IF (ENABLE_DOCS) #DEPENDS doc ) ENDIF ( TAR AND GZIP ) - + #install HTML pages if they were built IF ( DOCS_HTML AND NOT WIN32 ) - INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/html/ DESTINATION share/doc/lucene++-${LUCENE++_VERSION}) + INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/html/ DESTINATION share/doc/lucene++-${lucene++_VERSION}) ENDIF ( DOCS_HTML AND NOT WIN32 ) #install man pages if they were built IF ( DOCS_MAN ) INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/man/ DESTINATION man) ENDIF ( DOCS_MAN ) - + ELSE ( DOXYGEN_FOUND ) MESSAGE(FATAL_ERROR "Doxygen not found, turn ENABLE_DOCS off to proceed") ENDIF ( DOXYGEN_FOUND ) - + ENDIF (ENABLE_DOCS) diff --git a/cmake/Toolchain-mingw32.cmake b/cmake/Toolchain-mingw32.cmake index 8562fd81..73f6124c 100644 --- a/cmake/Toolchain-mingw32.cmake +++ b/cmake/Toolchain-mingw32.cmake @@ -5,29 +5,29 @@ # cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake -C ../cmake/Toolchain-mingw32.cmake .. # the name of the target operating system -SET(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_NAME Windows) # which compilers to use for C and C++ -SET(CMAKE_C_COMPILER i586-mingw32msvc-gcc) -SET(CMAKE_CXX_COMPILER i586-mingw32msvc-g++) +set(CMAKE_C_COMPILER i586-mingw32msvc-gcc) +set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++) # here is the target environment located -SET(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc /home/alex/mingw-install ) +set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc /home/alex/mingw-install ) -INCLUDE_DIRECTORIES(/usr/lib/gcc/i586-mingw32msvc/4.2.1-sjlj/include/c++) +include_directories(/usr/lib/gcc/i586-mingw32msvc/4.2.1-sjlj/include/c++) # adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search +# search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -SET(_CL_HAVE_GCCVISIBILITYPATCH 0) -SET(_CL_HAVE_NAMESPACES_EXITCODE 0) -SET(_CL_HAVE_NO_SNPRINTF_BUG_EXITCODE 0) -SET(_CL_HAVE_NO_SNWPRINTF_BUG_EXITCODE 0) -SET(LUCENE_STATIC_CONSTANT_SYNTAX_EXITCODE 1) -SET(_CL_HAVE_TRY_BLOCKS_EXITCODE 0) -SET(ENABLE_ANSI_MODE OFF) +set(_CL_HAVE_GCCVISIBILITYPATCH 0) +set(_CL_HAVE_NAMESPACES_EXITCODE 0) +set(_CL_HAVE_NO_SNPRINTF_BUG_EXITCODE 0) +set(_CL_HAVE_NO_SNWPRINTF_BUG_EXITCODE 0) +set(LUCENE_STATIC_CONSTANT_SYNTAX_EXITCODE 1) +set(_CL_HAVE_TRY_BLOCKS_EXITCODE 0) +set(ENABLE_ANSI_MODE OFF) diff --git a/doc/Doxyfile.cmake b/doc/Doxyfile.cmake index 7eda0e61..0a4a5797 100644 --- a/doc/Doxyfile.cmake +++ b/doc/Doxyfile.cmake @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- PROJECT_NAME = Lucene++ -PROJECT_NUMBER = @LUCENE++_SOVERSION@ +PROJECT_NUMBER = @lucene++_SOVERSION@ OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/doc OUTPUT_LANGUAGE = English @@ -24,7 +24,7 @@ REPEAT_BRIEF = YES ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = NO -STRIP_FROM_PATH = +STRIP_FROM_PATH = INTERNAL_DOCS = NO STRIP_CODE_COMMENTS = YES CASE_SENSE_NAMES = YES @@ -45,7 +45,7 @@ GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ALIASES = "memory=\par Memory management:\n" -ENABLED_SECTIONS = +ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO @@ -93,11 +93,11 @@ EXCLUDE_PATTERNS = "**/.svn/**" \ "*/md5/*" \ "*/nedmalloc/*" \ "*/utf8/*" -EXAMPLE_PATH = -EXAMPLE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = +IMAGE_PATH = +INPUT_FILTER = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- @@ -115,7 +115,7 @@ REFERENCES_RELATION = YES ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output @@ -126,7 +126,7 @@ HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = @PROJECT_BINARY_DIR@/doc/helpheader.htm HTML_FOOTER = @PROJECT_BINARY_DIR@/doc/helpfooter.htm -HTML_STYLESHEET = +HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES HTML_DYNAMIC_SECTIONS = YES @@ -151,8 +151,8 @@ LATEX_CMD_NAME = @LATEX_COMPILER@ MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = +EXTRA_PACKAGES = +LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = NO LATEX_BATCHMODE = NO @@ -165,8 +165,8 @@ GENERATE_RTF = @DOCS_RTF@ RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output @@ -181,8 +181,8 @@ MAN_LINKS = NO #--------------------------------------------------------------------------- GENERATE_XML = @DOCS_XML@ -XML_SCHEMA = -XML_DTD = +XML_SCHEMA = +XML_DTD = XML_OUTPUT = xml XML_PROGRAMLISTING = YES @@ -193,33 +193,33 @@ XML_PROGRAMLISTING = YES GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = PREDEFINED = "" -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::addtions related to external references +# Configuration::addtions related to external references #--------------------------------------------------------------------------- -TAGFILES = +TAGFILES = GENERATE_TAGFILE = @DOCS_TAGFILE_LOCATION@ ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = @PERL_EXECUTABLE@ #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES @@ -233,18 +233,18 @@ INCLUDED_BY_GRAPH = YES GRAPHICAL_HIERARCHY = YES DOT_IMAGE_FORMAT = png DOT_PATH = @DOXYGEN_DOT_EXECUTABLE@ -DOTFILE_DIRS = +DOTFILE_DIRS = GENERATE_LEGEND = YES DOT_CLEANUP = YES DOT_FONTNAME = FreeSans -DOT_FONTPATH = +DOT_FONTPATH = DOT_FONTSIZE = 10 DOT_GRAPH_MAX_NODES = 50 DOT_MULTI_TARGETS = NO DOT_TRANSPARENT = NO #--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine +# Configuration::addtions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = YES diff --git a/doc/helpheader.htm.cmake b/doc/helpheader.htm.cmake index 7cf76a5d..da5c781c 100644 --- a/doc/helpheader.htm.cmake +++ b/doc/helpheader.htm.cmake @@ -1,16 +1,16 @@ -Lucene++ API Documentation (Version @LUCENE++_SOVERSION@) +Lucene++ API Documentation (Version @lucene++_SOVERSION@) - + diff --git a/include/BitSet.h b/include/BitSet.h index 3fa9cdd3..c7c72f15 100644 --- a/include/BitSet.h +++ b/include/BitSet.h @@ -21,7 +21,7 @@ namespace Lucene LUCENE_CLASS(BitSet); protected: - typedef boost::dynamic_bitset< uint64_t, LuceneAllocator > bitset_type; + typedef boost::dynamic_bitset bitset_type; bitset_type bitSet; public: diff --git a/include/Collection.h b/include/Collection.h index 31d475eb..48155c1f 100644 --- a/include/Collection.h +++ b/include/Collection.h @@ -19,7 +19,7 @@ namespace Lucene public: typedef Collection this_type; typedef boost::shared_ptr shared_ptr; - typedef std::vector< TYPE, LuceneAllocator > collection_type; + typedef std::vector collection_type; typedef typename collection_type::iterator iterator; typedef typename collection_type::const_iterator const_iterator; typedef TYPE value_type; diff --git a/include/Config.h.cmake b/include/Config.h.cmake index 13f64601..eba35441 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -77,16 +77,6 @@ // Define to enable cyclic checking in debug builds #@DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK -// Define to use custom allocator (useful in Windows builds and when using nedmalloc) -#@DEFINE_USE_CUSTOM_ALLOCATOR@ LPP_USE_ALLOCATOR - -// Define to use nedmalloc memory allocator -#@DEFINE_USE_NEDMALLOC@ LPP_USE_NEDMALLOC - -#ifdef LPP_USE_NEDMALLOC -#define EXTSPEC LPPAPI -#endif - // Make internal bitset storage public #define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS diff --git a/include/HashMap.h b/include/HashMap.h index 217c7747..3363667b 100644 --- a/include/HashMap.h +++ b/include/HashMap.h @@ -19,7 +19,7 @@ namespace Lucene public: typedef HashMap this_type; typedef std::pair key_value; - typedef boost::unordered_map< KEY, VALUE, HASH, EQUAL, LuceneAllocator > map_type; + typedef boost::unordered_map map_type; typedef typename map_type::iterator iterator; typedef typename map_type::const_iterator const_iterator; typedef KEY key_type; @@ -154,7 +154,7 @@ namespace Lucene public: typedef WeakHashMap this_type; typedef std::pair key_value; - typedef typename boost::unordered_map< KEY, VALUE, HASH, EQUAL, LuceneAllocator > map_type; + typedef typename boost::unordered_map map_type; typedef typename map_type::iterator iterator; static this_type newInstance() diff --git a/include/HashSet.h b/include/HashSet.h index b7dff184..fbeebf66 100644 --- a/include/HashSet.h +++ b/include/HashSet.h @@ -18,7 +18,7 @@ namespace Lucene { public: typedef HashSet this_type; - typedef boost::unordered_set< TYPE, HASH, EQUAL, LuceneAllocator > set_type; + typedef boost::unordered_set set_type; typedef typename set_type::iterator iterator; typedef typename set_type::const_iterator const_iterator; typedef TYPE value_type; diff --git a/include/Lucene.h b/include/Lucene.h index 203bc3c8..4b4a3769 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -56,12 +56,12 @@ namespace boost namespace Lucene { - typedef std::basic_string< char, std::char_traits, LuceneAllocator > SingleString; - typedef std::basic_ostringstream< char, std::char_traits, LuceneAllocator > SingleStringStream; - typedef std::basic_string< wchar_t, std::char_traits, LuceneAllocator > String; - typedef std::basic_ostringstream< wchar_t, std::char_traits, LuceneAllocator > StringStream; + typedef std::basic_string< char, std::char_traits > SingleString; + typedef std::basic_ostringstream< char, std::char_traits > SingleStringStream; + typedef std::basic_string< wchar_t, std::char_traits > String; + typedef std::basic_ostringstream< wchar_t, std::char_traits > StringStream; - const std::basic_string< wchar_t, std::char_traits, LuceneAllocator > EmptyString; + const std::basic_string< wchar_t, std::char_traits > EmptyString; typedef boost::shared_ptr filelockPtr; typedef boost::shared_ptr threadPtr; diff --git a/include/LuceneAllocator.h b/include/LuceneAllocator.h index 41240da2..0bc7ad9a 100644 --- a/include/LuceneAllocator.h +++ b/include/LuceneAllocator.h @@ -19,136 +19,6 @@ namespace Lucene /// Release a given block of memory. LPPAPI void FreeMemory(void* memory); - - /// Release thread cache. Note: should be called whenever a thread - /// exits and using nedmalloc. - LPPAPI void ReleaseThreadCache(); - - #ifdef LPP_USE_ALLOCATOR - - /// Custom stl allocator used to help exporting stl container across process - /// borders. It can also calls custom memory allocation functions that can - /// help track memory leaks and/or improve performance over standard allocators. - /// @see #AllocMemory(size_t) - /// @see #FreeMemory(void*) - template - class LuceneAllocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef TYPE* pointer; - typedef const TYPE* const_pointer; - typedef TYPE& reference; - typedef const TYPE& const_reference; - typedef TYPE value_type; - - LuceneAllocator() - { - } - - LuceneAllocator(const LuceneAllocator&) - { - } - - pointer allocate(size_type n, const void* = 0) - { - return (TYPE*)AllocMemory((size_t)(n * sizeof(TYPE))); - } - - void deallocate(void* p, size_type) - { - if (p != NULL) - FreeMemory(p); - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - LuceneAllocator& operator= (const LuceneAllocator&) - { - return *this; - } - - void construct(pointer p, const TYPE& val) - { - new ((TYPE*)p) TYPE(val); - } - - void destroy(pointer p) - { - p->~TYPE(); - } - - size_type max_size() const - { - return size_t(-1); - } - - template - struct rebind - { - typedef LuceneAllocator other; - }; - - template - LuceneAllocator(const LuceneAllocator&) - { - } - }; - - template - inline bool operator== (const LuceneAllocator&, const LuceneAllocator&) - { - return true; - } - - template - inline bool operator!= (const LuceneAllocator&, const LuceneAllocator&) - { - return false; - } - - template <> - class LuceneAllocator - { - public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - LuceneAllocator() - { - } - - LuceneAllocator(const LuceneAllocator&) - { - } - - template - struct rebind - { - typedef LuceneAllocator other; - }; - - template - LuceneAllocator(const LuceneAllocator&) - { - } - }; - - #endif } -#ifndef LPP_USE_ALLOCATOR -#define LuceneAllocator std::allocator -#endif - #endif diff --git a/include/LuceneFactory.h b/include/LuceneFactory.h index 7e4f817c..dfd9cb19 100644 --- a/include/LuceneFactory.h +++ b/include/LuceneFactory.h @@ -18,7 +18,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T); #else - return boost::allocate_shared(LuceneAllocator()); + return boost::make_shared(); #endif } @@ -28,7 +28,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1)); #else - return boost::allocate_shared(LuceneAllocator(), a1); + return boost::make_shared(a1); #endif } @@ -38,7 +38,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2); + return boost::make_shared(a1, a2); #endif } @@ -48,7 +48,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2, a3); + return boost::make_shared(a1, a2, a3); #endif } @@ -58,7 +58,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4); + return boost::make_shared(a1, a2, a3, a4); #endif } @@ -68,7 +68,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5); + return boost::make_shared(a1, a2, a3, a4, a5); #endif } @@ -78,7 +78,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6); + return boost::make_shared(a1, a2, a3, a4, a5, a6); #endif } @@ -88,7 +88,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6, a7); + return boost::make_shared(a1, a2, a3, a4, a5, a6, a7); #endif } @@ -98,7 +98,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6, a7, a8); + return boost::make_shared(a1, a2, a3, a4, a5, a6, a7, a8); #endif } @@ -108,7 +108,7 @@ namespace Lucene #if BOOST_VERSION <= 103800 return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9)); #else - return boost::allocate_shared(LuceneAllocator(), a1, a2, a3, a4, a5, a6, a7, a8, a9); + return boost::make_shared(a1, a2, a3, a4, a5, a6, a7, a8, a9); #endif } diff --git a/include/Map.h b/include/Map.h index 36e8cd95..3d97d10c 100644 --- a/include/Map.h +++ b/include/Map.h @@ -19,7 +19,7 @@ namespace Lucene public: typedef Map this_type; typedef std::pair key_value; - typedef std::map< KEY, VALUE, LESS, LuceneAllocator > map_type; + typedef std::map map_type; typedef typename map_type::iterator iterator; typedef typename map_type::const_iterator const_iterator; typedef KEY key_type; diff --git a/include/PriorityQueue.h b/include/PriorityQueue.h index 318e1df2..6d3ffb31 100644 --- a/include/PriorityQueue.h +++ b/include/PriorityQueue.h @@ -20,7 +20,7 @@ namespace Lucene class PriorityQueue : public LuceneObject { public: - typedef typename std::vector< TYPE, LuceneAllocator > heap_type; + typedef typename std::vector heap_type; PriorityQueue(int32_t maxSize) { diff --git a/include/Set.h b/include/Set.h index 7adff103..90ca7027 100644 --- a/include/Set.h +++ b/include/Set.h @@ -18,7 +18,7 @@ namespace Lucene { public: typedef Set this_type; - typedef std::set< TYPE, LESS, LuceneAllocator > set_type; + typedef std::set set_type; typedef typename set_type::iterator iterator; typedef typename set_type::const_iterator const_iterator; typedef TYPE value_type; diff --git a/include/SimpleLRUCache.h b/include/SimpleLRUCache.h index 8b6ab822..33ff4d0e 100644 --- a/include/SimpleLRUCache.h +++ b/include/SimpleLRUCache.h @@ -22,7 +22,7 @@ namespace Lucene typedef std::pair key_value; typedef std::list< key_value > key_list; typedef typename key_list::const_iterator const_iterator; - typedef boost::unordered_map< KEY, typename key_list::iterator, HASH, EQUAL, LuceneAllocator< std::pair > > map_type; + typedef boost::unordered_map map_type; typedef typename map_type::const_iterator map_iterator; SimpleLRUCache(int32_t cacheSize) diff --git a/lib/.gitignore b/lib/.gitignore deleted file mode 100644 index f59ec20a..00000000 --- a/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/liblucene++-contrib.pc.cmake b/liblucene++-contrib.pc.cmake index f0aa77c4..3ebf9f98 100644 --- a/liblucene++-contrib.pc.cmake +++ b/liblucene++-contrib.pc.cmake @@ -6,9 +6,9 @@ lib=lucene++-contrib Name: liblucene++-contrib Description: Contributions for Lucene++ - a C++ search engine, ported from the popular Apache Lucene -Version: @LUCENE++_VERSION@ +Version: @lucene++_VERSION@ Libs: -L@LIB_DESTINATION@/ -l${lib} Cflags: -I${includedir} -Requires: liblucene++=@LUCENE++_VERSION@ +Requires: liblucene++=@lucene++_VERSION@ ~ diff --git a/liblucene++.pc.cmake b/liblucene++.pc.cmake index 2e53c02d..d238e51a 100644 --- a/liblucene++.pc.cmake +++ b/liblucene++.pc.cmake @@ -6,7 +6,7 @@ lib=lucene++ Name: liblucene++ Description: Lucene++ - a C++ search engine, ported from the popular Apache Lucene -Version: @LUCENE++_VERSION@ +Version: @lucene++_VERSION@ Libs: -L@LIB_DESTINATION@ -l${lib} Cflags: -I${includedir} ~ diff --git a/scripts/llvm/README b/scripts/llvm/README deleted file mode 100644 index ffd80db0..00000000 --- a/scripts/llvm/README +++ /dev/null @@ -1,12 +0,0 @@ -can almost get this to work: - -boost needs to be compiled in, so that we don't need native boost libs (DONE) -problems with linking with libstdc++: ntv.bc:(.text+0x1742): undefined reference to `std::ctype::_M_widen_init() const' - - seems to be a problem with libstdc++ (gcc 4.3 -> 4.4 regression) - - a solution is apparently to compile with lower optimisation levels, but that doesn't seem to help -waf script doesn't work all the way to the end yet... was still playing around with: - llvm-ld -native *.so target.bc -o ntv -lsupc++ -lstdc++ -L/usr/lib/llvm-2.8/gcc-4.2/lib64 -lpthread - - it worked better when linking to boost native libs -confused about how to compile c++ based bytecode to a runnable lib, seems kind of strange adding all the pthread, etc, which is native? -trying to convert the given code into C code doesn't work yet, due to a bug with large int sizes - diff --git a/scripts/llvm/build/clang.py b/scripts/llvm/build/clang.py deleted file mode 100644 index 6c998eec..00000000 --- a/scripts/llvm/build/clang.py +++ /dev/null @@ -1,72 +0,0 @@ -############################################################################# -## Copyright (c) 2009-2011 Alan Wright. All rights reserved. -## Distributable under the terms of either the Apache License (Version 2.0) -## or the GNU Lesser General Public License. -############################################################################# - -from TaskGen import feature -import Options -import sys - - -@feature('c') -def apply_clang(self): - if self.env['HAVE_LLVM'] == False: - return - ''' - Replaced the default compiler with clang if required. - ''' - if not getattr(self, 'clang', True) or Options.options.disable_clang: - return - self.env['CC'] = self.env['CLANG'] or self.env['CC'] - if sys.platform == "darwin": - # workaround problems with non-static inline functions - # http://clang.llvm.org/compatibility.html - self.env['CCFLAGS'] += ['-std=gnu89'] - -@feature('c') -def apply_clang_cpp(self): - if self.env['HAVE_LLVM'] == False: - return - ''' - Replaced the default compiler with clang if required. - ''' - if not getattr(self, 'clang', True) or Options.options.disable_clang: - return - self.env['CPP'] = self.env['CLANGPP'] or self.env['CXX'] - self.env['CXX'] = self.env['CLANGPP'] or self.env['CXX'] - if sys.platform == "darwin": - self.env['shlib_CXXFLAGS'] = ['-fPIC'] - -@feature('c') -def apply_clang_llvm(self): - if self.env['HAVE_LLVM'] == False: - return - #self.env['AR'] = self.env['LLVM-AR'] or self.env['AR'] - self.env['LINK_CC'] = self.env['LLVM-LD'] or self.env['LINK_CC'] - self.env['LINK_CXX'] = self.env['LLVM-LD'] or self.env['LINK_CXX'] - self.env['STLIB_MARKER'] = '' - self.env['SHLIB_MARKER'] = '' - -def options(opt): - """ - Add options specific the codehash tool - """ - opt.add_option('--noclang', - dest = 'disable_clang', - action = 'store_true', - default = False, - help = 'disable the clang compiler if it is available') - - -def configure(conf): - search_paths = ['/Xcode4/usr/bin/'] if sys.platform == "darwin" else [] - conf.find_program('clang', var='CLANG') - conf.find_program('clang++', var='CLANGPP', path_list = search_paths) - conf.find_program('llvm-ld', var='LLVM-LD', path_list = search_paths) - conf.find_program('llvm-ar', var='LLVM-AR', path_list = search_paths) - if conf.env['LLVM-LD'] == None or conf.env['LLVM-AR'] == None or conf.env['CLANG'] == None or conf.env['CLANGPP'] == None: - conf.env['HAVE_LLVM'] = False - else: - conf.env['HAVE_LLVM'] = True - diff --git a/scripts/llvm/waf b/scripts/llvm/waf deleted file mode 100644 index 73ad1d5d64bbeb633b015419b723402e0e931fa7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76812 zcmcG#by!sI)&`7}AY7D!Gy_8n2uMpy!_eIgLpMX0gmjmrG)Ol{i%3hCfPjcdcZc}x zLC^1;^S zw|21P2SL@8czL<`SlEG4bt^}E6IYO;iKQ1ah=Yxdn}vgoo$b*h8XB5MsxWhFSGbF{ zsT|t>JM~~Q9LH})%E6CB}U$y|w0qfjc;UE_n+yt-@A<)Fs(H#Z|bMkVrwzPsj z0)apdj&N%;7&9!U{;|Jw#Y*METUFB<^w z%-sNt{(mq75dlCf!W(l(GdFvf1N>i0Qqr zaMyc_0HyB0N(*4_56G^L7H|(l6cOqHQh;2YU}gwb0Q;;FTya70!Ql@xTwQ^n1171< zK-EBMN>b`tqN!PM)uEDV%pjcBE} zCFXmyv`2D}& zKvgBh)tMhb760BL%m*+4tdM60sVPf}LlHNU+LC~$qN+N~fY%^#B}Fw!6%Ak!FbR?n zRS=byRC@&Z|8N{YS6o9?QUPHZ;H{d5n3_6NT|-?GB(0<*aSx}Oq^c%VTvAN{B(H=3 zSPG<}CdmwFP#3*d42S>#0j2>X#5B~P_s~EU)g@I`HI&t%N{Wn+WR$c3=K&i(SCdmjy1PWLt4M2LYR!bDn3Ge{Wi{KPs)t}q{;2wZ4 z5HAo^3M49_3CI9UzF+(Zh_D*;FB^a%H4Sl@zi_kOXU|90_D+s2KzaevqN|tdqep<} zY5)vEH0-QAtZYDfl?3G75AbmCSiFGony|5(oAa8moAGd&allMX*m&8wO<%m=GobdW?g18@YGJ#vMB3?dv z1n^l(h{40eg5i-l%mQQz@nqzGgbCzIHx~zx=Ob$%k$SnZTERTsVJ?U>D9q-`$%go{ z0G9o0FDJtz%>UT^&vw@P;sOJ7-wTJixIpX?;(-J10Ea*r^w~H$_4wHBC0$$`UHCzC zuJ;3M_6#68kUb;gBTR&Dn5Q)y!v0r;n}d^ynXM6Euer4g1o%OSvp{&|1ap8OmYcX( zy6dqSFf+KAG5`|HfH?*;M;8}2Cpb`O%&dSc1cK0+GXf@iSXtY_KWLBVBASw)^P612o ztnc+BWc(2>1c1u`77`NHcVIwRjfn~Og#T}y|56G}{?Ta$fC0Dr-2~qKOzN% zgziP&TZmZAalhIWaK-k~|0#|WSnx+V@LP|apM~83aNNnx#0&;8g^05=G9zq72xa`w zagM*^F2MLBK=L0VyIKK#fE`ddOW+?ft_;i|2AC(@#l)4t;2tf2%JwFK}H_XtdZ3qm(QayZN$!eHv=;BD>1 z0s5mDSp9#9VSppf05I{_M!>$m5dBNqA5VY;@n_xtTj>6^?SBUEFTPp;c4mJtHU(OO z`$GydX9k&B!OU!dat}0eruW9Wx;fovKcLBSa)G%5EeZ_+(tm;va2^hvcp&U%a3B@^ zH(39y`hTIwePDpr@((@!VTLC_TP{9;^8jW4XF3!7&vbU5ZV|71;^qJ(09yzU1Hhku$a4?*ANC`N1*mj$uts#N ze|c?hYUYXv-XBKugZ}%lAi5|sxR(>m74+8(pg%UZvjfcdbHi#2b8&##adNP#!QfKB zxfF%}Y1v_}T7NVkvczBEz^;4o_gNYabA{hi8=%Nv+96m6^pgL_u|u4>f2Dh1)qPXfc6MT@guMtv{)f0fr{v$e07cGjKxT3M zTPQ#*!XTLE{lWNSm(cS+H3c95P+9+Y4d`H?b7i^zMifX0u#_3}w|ig){i|&N)FaM` z^?fS++aEA9Al~~i{JA{0b2KxtL%eWwg8#{_|JZL0Fr48z5RvB$z};WP|A#~W!UrMg z-ax>(`vZdjfEjdOh=Fnf2Q0Bilqm*)l$;z4_wS+@SQ!v+5&+!)OT|An09pZ!{{ull z;h(JX2=jlp0RQwWz}82PfY<<6z@UG#>k*A${E1e@rJ)1+(PxnN)Klus|Y z8E~tPgzL>2ShPh}I@#($Gnm@ME4r(tozGa+`B@ik-mWc5Hbn}NHSF}amlRcZj`1vK z9rzs`_$eGX3TJ*JTe$F;6F!Io9lSk=T7VvK?tDA2WN))yast$X=^xZEzRF?HeTXEm zn73$$@?(3Kv-4+IwU!6l^@B}!d!I(HswH=%)3YCps!uC5wi4geBRxP8QKlA4d`H=U zq*}B&jS7Z5UG`h|UKm_4T(WUEaO-IM`XhpAFTTjFWLfZLtm=GBW9l>4O?^te`|#8# z&&|)R&Gn_ugSYk5B|Zm22dyh!?Q_{vZRJ`^o63yem6IjF5af_^;pB?t_6sb{peVO- zC52+u$4kqV8=wbbn9{j;a9q7F_HT#b9v=E>xrYl|r6OPmdQ*&Cy`BwjCdz?}^SdC+ zuba4@-6K2B=lj?Z4jI0VnR5I$eeX0Y*)xSkS}&@F);vc`vNwEo)Qv29-)<~5o!J)b z_<0(fEq$$R9i_bRq3~J?Yl$=m(|0yQS6n-TcYeI6*Ka)~#pQW!HWsN>!fe2IPw#SM1Sk8*pq}wHW?xgN;)j-VoQpJVvLECyv>p|&-!PC1=cv*IwHWZ~M;v3%|@UirUWp<*9}0&bBYdhUj4WnsN7@ z<&Ag3x))Xbqr|NvDg7-TCDCuUvF8=K16AhqF*#ymcKa?mHpDyj{g$N-FJ8Ru?9bg5 zYM$%Zzi4as;5&}K8S}lEx3hYXH;Y$Rwbn9w;J)HW>+Sp1!v9qhpp^ zmux<)Va`KI0oQJ1Z~vs@1m2F^9+;$FI#anrCYqt}-lfgsc~j?Ei^^iXf!)G^w)=Rb zk|pnuYSvOq6VVIzVf~R(9qzL!#aRKr73l$w&KvvHOe*hB9rfxnwvr9wL1X5N^Jk+z zQ5|C?K7K=Og<91H`)#wKVPi&QJqmcJ$X3W!NFrABc*w?5BGcySNoooV?>Ov5!1Q2x zt|_S)u1^FRsGuM#Jg^931LIb{31WgiT|R>{FC%a>G%)x6%*M-v;{{@8U?$;Nb8$1g z6XJfUoZ&5+7ZGkHB+d<{zh6V(T|^s^pd>Q+7EK7OAS5pp8u|+T6%vZb{VWnv1Pv;Z z2xbVf`P(FV1+W4)r&JP?|C7ULH7@yF?+l*Y2L&QXq^KF;L8wR|R4cWK;uuW9C#NM1 z>5px^AB&jBkwT{AkxhujK}h{QyDN8bTQg;b&v^q(7yFqthBel32S7M%n=|=z*edE@ zK~Gg2%C=Ce-nj49n;B?&FKW(Qd_KGp11=K0Ei!DY^pFBa=QTOwNqV6^YDGWFnx6a1trQ zCy*e)k2lAFFdz+mrlEN+D$;@lhDeH@cY`6Q%CErm1!Cg%8X9Mfx=rIER-$YwPm+VI zqB#nPR67V;q)#+tQrm_eA}gO7AA^PW?xVTH6sj6g?jjaP2s9Cm zho+bLOTMTm^W+4`Mh3MeUKd@8lLZ}*h7M$sZYIS^Z>Rk#1j|AaLo%2)0mg|wlB7Tr zBQK@~hD5|GSPUklCW@rX0t8MpA4yW-=+mx~C84k7ipaN{r>8AWhelYX*UHC4H;phB z)9Xkw=W}J!%fAjLh)hnhNTDrEB2kDzhJhg>ku)4CvIAcRD?$eB>dZfxbJ3d0EXeE8 zrWMd}v2dD6A*a%Rv}5a4<;Y8rPwV3#RppROm6@FE3)Q5ZjKDYLrhmc&>VtwI*5M-D z59n(X88d?V`ou&+(#>hW=Cu;zqN-r)x-WzIk7?=XsKXbYK{-`&W9Z})*y!HLT628L zRAVeswa!S0PmGQaZ(yrQK%z@PhlViOS1jsrN;QOQ^VqQ$_VLI;>Mb;(?8PQUL8TGV zs?(~Uxk)S!QO`JF7D=?agS7Qh(+Uh^-K#?RVu~@)s4S!=@EwNGWC7PpH3?*OcKq@q+?Nl)~ebJs_2y3H`&`w zkTTPAi|9n8TPxFXsLvOZ(b(6UY7a)H$5a$1YNm6@e*Ro9%au~94s8lorBRn!u(4)I zuQ499`VuMynWCmiLnl#zK~(EBNSN~@ZFt1`Lu1k#~ zo-oc+Rnd7+X9FeX;Uu262(e3>rLn3fN;8);e^+Qrosr5|tdP(EBei-4ea#bXoiSvp zYB4Co{JBA;kw}vHbF!*Ey4Aphx$L|ojKjjBP?Z$>lZ1H%3M^8YK3~1ZOwxElr8c}k zgE5a@95N`=fNhnQ5jiBvsFEv7TPi;i`J~v+s>Yr$rj924b(9$~?Q|y8!t}|&gk+RF zomJn&6MMQ0G6_3U`J!?jFvR{zD%i|?;xShShj}5CI)c!Oh10w@%|>3nl!KHdg3G?a zG(9Fshs8uUDrB%f|yy1 zlcfkhyi|^iuwXI4SnIHpG$~5MSbZKQt^b3)dM16~Bw)m9^3Oo_)F~;*!;mXEo#X1cm=_<63 zxf6q}xiZak%~pPiUmH}{U0_WuwBE+y--hDuaFvsZ(?(a^X)*^4-o`J2>8YAne#D1e z_)OlSEA4ZjY+Ny6s)Ol;CVAFVSY5yn13anJGKrU?r@yi<98Wt2?=AwH&sMdweEAN; zu3SuJw92BkUxT)>7gzMUJ~0rHCd557w2qmbn4MFi*V+leC4aA(@io{IM*zj;sAVnw z`R3K+32Q6V$D=u_LPNV3V_x-1kS8}<)C*ZH*-BCcQZ{uKx(FFG&R<-=rLx~(il?X( z!poGSsLMU1VhPO9o9QGb-c@MK@oD*0oqLN|e%!f;`&N0vvfK53>9MMrUtiVZ{Z_6g zdDSh4C+*YKHO!m07C^?|{*f_jc#?$~8vt-HCZFh7vP`&FlYZ0#EDceSlWoHAU5Yo5!rfsie& z^>WAR7vE(2v};WVi4-zSdxgtNTgi$HNDYvD?HX2-sOQ|Q-n(q4u046eP9lS@ZCw~H zBL$|9-a>`K8b>KEmtoUYb)9E=aK@P8pBV?Y}Yo5f-!cJ zW=2Vg^vHORf1`x`i1_kQ2yKeMw?SQi>nl0A@ej;(>SCfb?kP!orwMMf6IGC7&NKi1 zDH?&zA9=kr3ej(G+>)!60^aC;YNUyk>8b|JZ-kgNsZW|sfq2hn9LAXmqYE?mH55)D zHs!y~?rv-sG=%GToIOAH&?(fIoc%h_9VDZwjdUOpDP$@)XB=kK>E9_=nTgk?tYsKR zL-nzF!$m=?c~ zCmL&eI~qOlB*~ApPk=3>kcEbJxkDl6L7{sYz6|)GY*=+FD;ADCBLjV-EVvObFOr5G z?J1a^e?rc#+Ws+owp1SUd7On?J>Ok}Q*aZ@&#rJHQuTWgMnR?NR>QK47uRE2;}z7v zpYJ0B*W)3-YE+i#5JbTnMFZ8$HwFNT^8hXXT5M7Zkha`O`bI!D9K)=wnMZ{_i| zEfaXHzYx^9%tG}kJ7}KqTHFl7Nb9-dswzeo9Ojx|>rZS;YGr!{bf~6Bmmm1AV!RE9k4c_~3d`sbs=)Gu8i}3Qit`Vss$&^YRvFr1( z-ofoxXQZ;M3L`6Y_Sij!N;B-W4r%?adwToWx~O`dZqK%HrmCq7F7*i{ z!n-@e8Oh2Sb#OYd?y}q0?a>E>6A!Ng8D2PlY31 zH=xFUdmKA>L``z$vuf0{A~%;t8Ne)+M&dFo5LdSv{nN*tL(b}aT&F-REqA`q%m$~W zuexv;9C_O|5v-(itgSsykY85zW-#w!_JzERcD$4#m|j;oNHw24o^0@-j0828{W=|s z`j~S?tD}7T*$aaatI0B((Y|=b_1pBWo%0DliV&=8*2Nvko$Y*c$yl+-s+)$UFKRYp zx^6^%zXO%zZyOr2f5Z!G&Ezyof9y?s-bv%S{Mu+O0ORnzwq!qEZuH=g;(AYJP=gl2hpq2eb3zFx>^T^~qCuc!pv%)&+KK`GB`>8q--u!Gk+dSA07k&z}JqRS`3@&66x3W4Moqv71 zEBpdC$5p#L_)^dvA55?0A)iMvn2^04#4)Dnw`Q4YTheUneB8bUrpI7(KeT)@*-YJ%5}t0Ir)7v1^Y8zvG2vZQ+>gh=nqqt(kf-A z(D$0s;FFbg+oyio3S6%rpm=B6GIl#xq^ zIb*WR36AL)JIPX^O-}TRmvYO7sb~<-z@gpigHGB_cv={-Z`v5_4*CG=3}0f{M+lkW z9I^J{V}b{GJ-1);*@~T53>Fk2e_nc6xe_3DspZ}VE?Rh_sM`GN3zp3n_#WQGHG9BX zs_E8?n*!1un8t0b+-I!S!_D>>9`7vPv={+~K2%GxrA_+7eTs>gM7>WFl~C)N!7OQi z#?Cw3({tbYSFn|w4B@sa zSi~fGN-#70%`2h90{COe%h$tYV0xA2VbM~%naQ1<(~*oWTSFn?E(=9$v?nX0*h&^f z`baAJZw4fm&vTo`)RK^CTt+KCOt&xF44ee-zoEDCG#YT59x{&>m|S%V+sfY1b5>m> zvmv=~?~yAMcEB_O(=Yi^g!h3l*kWS%^1ihwmWmt^K(R>UN?5&r-I@y-oMyg$y&YN5 z?&YAq?fb>T&_s3g;Cb z?%eZNC(AKo*z=(i(b}mLG}pw% zDH~tHNLmZfd(*k*{J%u@6r6v#jK%x-{7DSM6y3AvpW}{R!c&J~Va=r|C%iYVg3W7Q z7yFuE`t%l`!}1m-9x1ay@R4=OFvcA@O z12|#P)kX<^J6S@@jqon60+yyao)OlwY=v|$#lG>)lt{g-$(AXjDE`Ol#Ucq0cdWLe zs2Zz`D1Dz+fGsDCj!dfyYO)wfrM2e+g38?@!&il~CwKRl@L^%SX#9ynR*^~}Beq5M zjAxUxv(+RoS*ySNnzQ)qJrzWGI|Ipp_a?~c&)|}3%-8nLfi}g#tTlVRv z1!gp9K%-O2)paVFyK(3X?6Otfc2rQqiI5%h+4Ed-kk1PVNdf!hF(@Yi= zQ|ua+6y2YisJyGOudb@EvFQHGA?+&>OnF2d8||r7Yw!)y=@@b0jz&_LTd0atZ^j_) zVV-T6?JbT`&*E(!k})z8Ljl&q3SJ$>Ja2~T2 ziQ#f3yZ3a+k#Vi0aS-H#cAX>J{5Xhu2C z3I+CpmG#I~9g_KJ&YP}qce;I)CCA6A%b2b(8M$iFSt9|h>hp<|5R+#MSVlNiT1hv? z2e?&c9`KK!1u-e!szkqJb&IZUsx9Tnc-o`nVDYl*x`(0Dy+r4Y<y@-^_4&zat{8dmF<{|9z#(-C>tmle8)WaVm9j+A0alpmS8dP5; z(_ywtb-QME*!2!cwx?KOZ<&k?d#JWGeGNX|otyq0!a{GH8<6#c6BUE>bHl!QA(w(@<6%m`HaI`|GTcI*miMs)aKzL;U6w0 zS8lDg&(~o%P9uD(0>;HxnAyUbOgI#Gj@Nfp!W1P8vG)G!gOw;QyrnbBd3_-$sq(SO zpz_)X3nr!l`;BL(Oxs`pTiZJB569nZDYyOU)c?>|Q?Z5PhKXjMG*!O-?=_uo(Gkj6%}px(}r^ zcTFkIL4*sBQs(KeQ)%-Xd3as3X@Y63Q(AC=aSbH+I&1HFtTbA#a}NGYYGrcDx=h*k zc;u4wFKoW#6D{smA1^zQ-c?k5BBAaOJjAB+b;2@AR}&_P33fIXPZmwqCltbN>p2bM z_1%{ow5#7)1%cUWZinC0EiElx^N-HQfa%?}x}ZCEjUG~MSfOa-m~@U~)cw!vXEJ}W zK)y~&d|g)Z2*BY3Lqw@Mp1{Yx7y0|=7GUu=S}d&g;OBk4c_o7O)@1Vm(&G&Yp|Wtc z-MgB=S1qI-!Q)pPRq4lU1PXxk;*E;C))3B?~?Av z9|%Mu=Q0luq@OtT37Z-0{snOp4)}RTH>SzFkvAZPd>vcIrP8{QeUd2i2^|cvxnoWq ztDgBK@P2n@=eD&XJKiJoX%u=1(yIUmiaprVeVb`s>_AAc*;~w@c4m4p7z~Eo6#o#r zjAR>su2wmX7nOV0*@t}XUYvjU>1h=8le;C~Z^n<=L~f^V8v)73EO!pNd*$DKJ*?l% zU)M|_^~?S4{vGq#^eP_hX3d;)ETX?jx*X>u5xxF(Fmx85^*q7O_u$|qjc8`TiEzL> zzt|Y|tEEv4Ih6fK3F9w*hMH6rqbDURX2&H?Ee~D&B8f;|kIFPz2!K`!Ry}^P`d)Z9 z=>A$zFkp8R9&vPg9JjY?f=Y|28HdTBSNofJeJCCbDN}P6L5?xKa6}(bDMMl7^Wm+~ z=f##VH?8HvJ6>M8KKr>?^~OUw)q^5^+V3Y(PD9NH0XxO28v%LHJg9sJjoD(Ub#^@Qr8R(z6R8)Q4kK#bFw$ zM-dWtR5H`+jIr8vyoqe>h3q6?dix;4=RT0&bPX67PFp~Jb8*Q#fX`DZLqoHp0h0(P z)B0HsJgT4PWXl;+Ouzbh?s7(#zCXciazhyOYBZW6%WOXmoGlTEd`SbT21Q#@5Hrc8 zKG7#h_qU}?5Y3psF0V0lScL>cE!aYwUjzv1?8fL_{3gj8aKZqK`nskHU6QVm8v{G| zo3bHXe|!ldA;&UABbt#Zkkrx=KL2n&QTciL-CdZ+Do95yYnr#)`6b~$f_ zU)9!7r+*>M9G??f-HcqlknS@>J}JYJ8ow z;A37;%e>h89u1pA@;7fmb_1t2N&&+k;ooe_$eB9ii_z6ka$B`x->gg#)`8E3CsX6NcTZu@5B%hX`o(uir0kn#Oa69lM!);7XUZsMOupt2IZVF=gP_tjWV3 z#)~9I`e3C`j?%V0aQbE#)JWK-rC3$*m9MBod`+s4*koi&nTsI* zkM@v-7zzqlKL&ao)nM(f!Fyk0JJLx7jL&xVKDJ&+dGjgnl#~;u=jgd|(8R_1zE3=f z#jvtEabCUk!d3hrIXAC4j8vEL;Z|5g7OVxcLgPAOWlokhJF^cD-jh#tk%BqQRu2k#*cLFUzoA9{IM5FI zAcEmMUTU0j$mNu`yi`ZZB~BKXdKX!r{j;I@hxCsRyqHK8Kz4h|X)xn8M{D(Ie|^L$ zvTmYZV}*k0(rd@-+}Usb+E@DPs0e%p13@@R2z3#W*}#FZT~6 zst$_8vczMCB!eToByxl%6*oQB$^#DdZltEkT;kl_)c50STnkwb^I~=JTjL(wnKDjLQ|~l_^V8r ziXcO4BYdp>7j}(BKA+x#FO9~Kd{m0`s-NodCWS@`iVoS9%dbF4%CG~?KX*0skT8ph zsLW|T9p!*qwBM}E2hS|uk%#EIQ@OsxC?n^}`b{o@Oafx%8+@(dARV%v_i6g3y!hQf zT0*SOdNUz`Rpqir?jU!mxQbK={ce*aYHhCYLNY||ZDHxEbdAm}+B0_^yA&Qz~$hwdi z(%tQzOxgZWg-jS<$Rf9$%N5M=g=3QVtxs}qjD2<4IvPK35!WV z3$~g9a9*#B>3z%2KCnEdw8*?Q;$w@!+9f9~IOmN+6}*PYte%}ogxXiLkCNZ*MGMh% zz4VAxQK){!hPzjMI^3A>bx+rS!Wwv}sQNu{qmT6g8|iJcw~e-C1FeR)#;A2Zf zkkr*Eq&~8(Lp=ODZ!^C>gW;mor^@pXF84};uVzLct2#+M>c$lWl^%ei*M^C)o{EH49MGf_>mW9 z^m`6gqhlroAA#AA_it{Z$yd)h7yINz*U*x`vQC~Qf$2wOH|qu9Ca(s`Y&Y1gH^+`c zg`Hc$cxxg4+Q9^8<3Bq-fjD=&wEXqt4Z0&1)H{eN43Eh(FjOAYT0jX^I4mL$CI>3c z_7sMmY14^$yheSg%%ONIiq~SxCi0?a5K{@?Dnrum$p1Ht>PR$3K?Y3!Uh*5Sf|JJA z7W=oa@E$Ct%E+Wa=rpy8cA9N?`0ZnW;Njbh0E3NQ7k+l5UBhmPx}NKTgO|lr73b?sF-DNA6|h!qn4OQKtv}t#ekxaJE!pJ4I+UpI zOF7iTF^*+yhW;YnrhsYbF_h#E$B>1(&)+6gh^W%KJdUy- z=Q&Rq@1D&{&`O)bPj>bmlIp2#Yw4R0iyh}`voKPxuP%OXxzl~7b3w(2vsm6Hy)mq9 zg)#rOQ8AyK=b`a8-e(7@D6f&zKKiU&SiMnF((~7E7>E|^H013C@>YS>MttfGiPw)w zDk_=1qfZvnZMvcBzfx3oPH(@q@?>=dC@r3}EMeJL|i_ zkaz~iy0-$Q$eFsUhi9DIl01YsQ+l4vxxVuPBR5?XW%`4POzq9?dtJ+#-ys`eGs<^b z!{>Jf{w+!Ez7)PQmWd&zHn^je-16}E(jMW(cslQLXXGn_ql*#~Iiiz8ra3}A$7+9h z`-4E%3RE|u$meaBx-~IS?yH;}%e}Rm7Ta7A88GBkFy=%vG7s5UQfcUg&bQdTOJhDs z2Zqn;!eeDSmt=c)57R!rCX=vi*n3Bl4*Z`%OSBlHYDkVrpM|-a-qv)3rs=Pj9&MHL z5faW6$j7hMmG4$oj&+dk_5+OZTNkkirdBua(gWBvA-$Kv*B{t?LZ*`kBiP}5DNR;d^Flp|VX zjHEfH6nccnN8N`t5*z_>N2Z3|Td@3L^I`|C@E5ADhQSci)EUBLvb!X8d#dsgM{jP+ zGsP(-LFF(r+?@ckr;}5;eqpy5ytwtBJ{Jy{V55g#mE6j#-I&^jQB+dm?J)RNYcFAM z=j1&c(tYSIDF81)CY2>;c<=ZMR(r_sePZABt9%Rj4Y4&~8|}WP9>;*Pmhlt3Gv;9W#UkFp7?k1t zJ1XbQVRQVQz&wLy!#3uWW@y8qR?)mPei^;FrRtd2@+gFFE*Jcf(0@_VJ3oIq@o*_oHZ zD`_*WrP{4+y9?h}<2Gj8n$D}KV=Ky-GGutJ;|k@(8HN`-I@?05e~}C7QL%m>C3bDw z>xGiDbT?ldHZ9#080g?3#@P8}U6>6B+0V z@F1)B&vQ~{+i5ZAX#KogI7lHVE2ii1bcuoAq)+P8PL-DZS32WH;cb@df=`@98n{{A z{r3Gkus>5aWTXk+)k@M?j|PRnT#IiT*CwXeq2nrf#Rbs!GTlWCwq2WHD_?iIHoJ11 z`p4Am zT<;))0eZvqO4;P5(mbd9$6>{{HwjCtvtk60ykVRoBH^0}djBb`=B_zi(N1h{9KY4A zy{az#VnPjy;8(t{BxL4hho;f-;!SA!$F$8TTkL&h^hEUtMeAKwVo0UaBJhUV9CQ z@8NT%EGTEeyP+kEcZ~Vr$NU#D^r&Tu#MbV;Z=)rsw?~T z+pBB8jFxBh%^P#$9{r&m@(&ly&EAe`MYa4K(=Y$B>q|A)yt%b}kZjIwmsa|yC%EvWmYD(Dn!ARE_i>lGWjjsdk4WrJEFY71k{^P@snw8T_z0w{@ ztuK5xFivb=_i`<*9Bk-G-0ht-`kMY)Y!|(K^V&xeC06%6HAuZ=*YHO@n)&Zi+M8cXr2V+0H7~z5@OTG zWjH?DUf;se97hi;A-q~J7JQ{;Oqx_xN8>W=Fe-uYxVMv; zVi9xBs8_#@fA6+qVr758Y_3Moe&@t1KxKGmrR!OakcW>)EZ)}2d6a==grBBH{He*$ zbMK2=j$1aWEL>`JY@CnZ$z^D}(=6oT-Fc`~q+`5;U!3e`{$ewYh>ynDq%@m;iN9+C z8F~L%P)ZgL123B9)V1gEG+OBQiy?HqK4q+fpNuZC`gktBxJIo>r!UIBgFMWPHJ$?)dLPdS+0eX&%B!cy6 z>6dlEaq8vHxqDN>Slsx}lawDgIc|wRZv6eNfQKdtlhV(3ZoVaf0`LOW- zy)C;**SP5=35-`B8ob4rKcNy$=X?s$KCPfoYiP&rce>qpVlvDP zUee&`>G`Z9;VJJ}eUR1~8gq@&Yf^HPi^=8fI?T^83# zwZ;BRLl)5td-7LSbRV`r(r8aoN51Yg*nlCb^9>_JO%a`-x~D$hrcmF4zbraNN&g^y z{^J|2QMTs@kGqMq`LEpKpKfc`V2Hb@8=B8oP?uiEUNm?7^YVV44|!h#FYlHE$|qO{ zH;y(6lo+b9-+8bHGr#RGSG}cDb2^}ssy2+cYV)IX_MfhsSQ$9GkuvJ*TEi6TgRHiERxI zWuzIOcVWi9t>s>Sz|~7-lkLZwE!VIqF|E@SrZU}zN)?nvnJ+w{Z1w?)e*D_ORuh!( z@FI!w$DctykkMjD;i-d&!gG1}hdACz5C-ddng%I~n10HBmq?Ts6DX4tCu{q*tuGVp zu{PaJdO*8p%99Cj2fp&1ym}!woPXlrr~A_K>3f+-+^xF+Au3qGE_kR`zWd^?sQ7Jk zM@5*)T8p%RL`p`Q1v)4=V<5w)b>*d8^7)xdmvn6IE$ZPIxVE~W=ic&N#G!Pu->)Vi1tAG)=R~o=EL6GvWW{*J;_f5}l%YV94!;RWGL zb|KxQKNiiO+xl_@3wt>taA&!{vC?C9s&F;TfKC-PbKq%wF>XpO*j0XddU5`8|KL_w zhqC6F@-FUp`?H6Sz0lecvl0q!8Wg@i6yU@Pp>#u<)BO|g}crlz#>v; z;6|ukv}#POF2APkWVT>w&ofNF?&qGB8@C_X#(s4)Oh-GlMdO5N-5E37T$Mu zsj!-|Bgr^cQRcMhCga-tdU$v%ZDk5!Q`!)Hc!Wi{bB3b^^;Yo!sxoIGHeN>Qcd*Ah z4YK+tcpuXSp)neE;Z+HcaOsI}@~Kir(|7`#d!8laj-uzkVolABO|@Uklt)-3C4LJU z#I670M0~>;)y3iOcT3K1N05L6o@5-KQL3<_?0RL!^jqsx!|QNTu!AQq-SH@#VP?Tf zn1rRpF1i?}%nJJkSq`79Z!KxR=&}U!_AZX_HhATDOTp7-<&4*EqK5833yeiW!M?7! zS>vCj@q-h>IO%(I?H(bFj^`O(AKbVfx?r^=^Dz5paHLdNPoLsPK9{G`TYY-+*t2iN zX2~~_QH2Stnz*-o9b@HNR43}ZRG({SJecdqp5PrRi(rK(39uu5dR}M0F@r1>-I@vR zPOZ5#;-RpO>*MBJa-IEIzc4v;9s2X$I?HBEPI&%tyy$ZL%>2n|X^xVrPMW8IfNQ0^R zExT?5xJLW0obb82C3cunF&-awO8WhB> zL(P#%O#zaA&|p~BkQm*;P6pZY&UgW{&=y`~b=rEY3#QMF`5quX(MRyAsetV9Es6$C zsa&&qF_Nzlh;%79?A?4@`dhiaRS(uqiW1uPhfazHoA39RMj9F@YXy2mz)Y;)Sg*ie z7mr-?N#h&zo~A5Ny}{}zE}mN&?vKOGF}YE@@SeB(g&k=?7++YuJ2M=)MII6QLnG>H zga|f^9%{x`D+zq$jki>!%TCa*D-(vXo=LZ}T@0wnOJCN^e4VL`LeGE5o08U#-r+`I zn~f)}kP?h9*05QLWtD#Di>t`Z+bjmg8;wPqSu2tvCCf-xrCqKiS@aB0{%9q@!eaq3 zCsc8L36HgvnUjiAfpkk3M+?@W@WnW3atXPD>8&eqn#AZ`1T5A>zwlZ#aOxkRJnnB( ztclW%O&Ch+Zuly}IQeOpxTeslg0GBi0Bx0;fLkp;Eh(75`hit5o5-lMk^%%fxU(qw zameR&g7G}RoEg-S7ktk4Y|}$!Ol0UI(Zp-$FIoE2%{9Q`qG^Z23G1HU$ON!kfsPNp zS_e~1WOKmOpm{(Sh`$rt>7Vc=Ystu{YlfwjDl18AHV-Ny)2*G-0H!Ax|9W!z#lKuQ z?XWnV}u=pM>%CD!Sw3T344L7XLJ*L0ahTwXh~I!$O0@doXE;#3^(p67Khm27iu9kczQ z&6J)?Sc>|@$x^tig358x!H4|dvCmv)!u8#3+vX+zL&>c1sR)vwV7836nJB2FxvT3S zhzr*mMlwyR@;Dy9lEwb<7LCfjd$=TFwQx-Kk%}u3Rpdr%Tf_5Imy_0S?gKJg56M#9 zZNcg(Z$B#EjKb9cVnS+w-cvCe>(Nj@0}pN|WY_x5Qd5 zRa=53qFwu4J=u(ZpZF|fs&W>MeMb(9{XJbrHh~wHF0cK_jd~YmlTwh_;xQ*o1zF4v0wX9R$tXlo7E0rL zMKtvEI5#(@c7zz)TM4=wk_?6@N4siin9$*EEC@z8Ce_s=H++(!t4)e=FOH^l?u=ul z{^#FP*k^Wjwm7kyKieKcNeQs9J}(rjW=nT^~i)BGbSixlTZ$&ib#+sz%a;g`#Kf`JjjXJX__kt#JlL4zDG zb2CF>rNDy2H+9XNQS{yPO~qrT{Ce|@h4Mf;BPMD1md43VXLoX}V;Y=0nPS9}O=;YE zX0)2tkC#a(md?*uZJAK!-K{H*FxDlHNOm@JFNv3S?b9<{FA2jx$7V@&D3XpuYszZ* zj{J7tjqJhEjctiD%H?nQ)f1~C% zw$>$`-{ZZz+~m1ahxZfiuu_pze&;e7Pd`0$Q&fLz!PBPQhcQw1Vp8hqBViV>O!PXdZ(m+KKN-ScK6CPmPZjE_>X*PK!p&6>g^ zCh%$_Cg+Ejze$arELq0FcZ@9k^pgp&SyZ~rA!F{CwaW-LP*%i97LC?sP8ZG6GB*^; z6_Q3!Dr+@}W@TwU_&x^)n{s0azv<#hY@+mr`5;tEzMThKCN;~A*+vO?jPZ8J{w*8a zZ21^ls;9PAH=M$jY5TQ%XMUK>J(otplB1I!a#tOG%eP5_S8EVXBCl~=FRh5 zuck2(5;Ml6pZqrk_?S`o9# zN(uWkfp@AfIfqUh?%P=%dH)h0_58oR`djzQRl*a`BPK_KwVPfPH3GLIs+q zBPjXUx2oq*7~vA$>amY#Pp$9%PYetXe%%LJw}Oc7iy55%caNO3F4IRztKOsW%r8b& zcT9r8ip@MrtOh21hL^DI^Sgel)J=`Zg=f4elA%U%?eZ<8pCgatr2IawqvgK*g64? ze|*r++;YSw*=N{xjcF{ghNczfT7(i}i_tp985Hs+lPKQdFDxDj-{6m7yS8!qd^}E- zad}0rD?Sq*jdeufDjEXCY zk3%kRj`spNO;&$DRIN89)9&BBv+TI_eCMik^iOG>q@>G=g%;}v^vA_|_|Qj?`yJ?@ z*$GWE!5fhLI)KazZ$Fgj7|Z8O!A?g_ykNzy)_x|NZoeBifTx|Gw)LNIdJ>X)b}P{} zom-J3D4QUB;~z6Gr-U{dV6BMb;Eo07-<#yQJcE8Y{leto{Z5@0*GfNT)8|wYJ)St8 zyR#NXpR&ea^^54*xXwt>n*^WcuDGEn&BsRC8mFC%yUR)L8SC4_=3@4!G;sdD-Hdv= z`UT0AWK|Y(@qHN|c1Y)|$V)da!?~>yn+fhe`_qUL8gWav%{KuL-5BwvH(Hhqqf60p zC4(qYfuVEka8M&A(%L#2^xkD4DJGs4f*GG-%0(4{a3RyqYV>hqNM|6otkIE{b@ow~ zYSBm?4xBu@?|d#kA0sH=Men1)_bpAOtW?G5GYR>agmC7PQ79K%;4Nwjw}th<|XcHI#M11oCJS;HbA4cC>F8 zlu77k&{$T=hAd6wnb8z&yLRn(LvW8Z))5O)>fw{M+j18e=XBB1L4m%h2@`-8j2d&L zHK3F4NZ8KUF_t7-I?&uE^TE%Hl;*sl)G#xe9&KNg)o-p_UxaasIL;1kCFky6vc4lI zJgz5C(e47Y{@flh_w%B$5s@W_!nv5wY^985t+O*^w4!!clHmKQ&XYatwRllu!${#S zA4z!Jajiqj8a66SRLmaII#uwEUB@W3o|@?&d^FxymSU3WoEyD_G0prYq4q}m)+WdZ zhh3OBIq?J;s^O)c^tz~Qib#VZgCM5TCrac)cKRx_Eu(bVOf=nH2P+yjRYj?is|npw z&Ul$6Sqo_{c9oHuGTrqKi_KL0{E8_}n(}&(%ez6Wcih)V2Si&%BPLO#q+M{P2GnsD zC?^Ar)#=2Nm&gKh}O-TD^@!4llh*gxERfANX z`1{p^^AN(9G*TdGBBc>j^*Po%o?bcLv*y@|Jm4&4ktUYmOBfR_9LY7$>+oA=Lu+|U z!z1t7DFjix(GdQ+A38s(X%NfX%lQufUWKy9M7dM&)mW<4^`AoKyHZd->d^6p0AZ1G zeLZ==xaI#9FcX;0^uCPrt?HcjG|xS&xniMd2WJwaXwBPLw)Up9x^qf-c!oDy4OHpT<&#rvGRd#1+B z`=QO`c5yb-=q!Xfy2aukOt>M#BPQe1=wd`4K;DaoNg2lQz>+K@CVq5t2iCW`QHVFD z5e|UT6CZF~k!Q##?d z+fA_i%RG1cVQCZ_AgD!{@FW&?Ry2}g+$4q$Ne~p~TdC43&dhP{>3ZXyl3#Vy;GN3z zrSbF4#SF7c>2k?O!=%n%D6OmIeVBz2z(XJ{05pP z-2D!m&x(wb(&|<3*K0iFwnDGkx*=EE*HRY#!rD zJ4O+<8$Q8VY;-G(7`EyTGY%!E-K;w^ltQiy+!b^!*4HQk`Ml}6O%&Uej&PVFlvWOh zGY32R|AQqRexU1J(SAHkELh!Bh80R^#!}_uZMZ0)Ej75Xp0#z>!0syXt3zIO+osn- zlXR8rOPfZ^DD|zTi}y7J+^VXU%GPS$wRjVFS0aNx8tCX5HqI#g9FrM-$*_dkA7NL< zYmwCc*kbow1a4^&q5;#mT0{m}4yM3xx`yY{7(p_!4utI5@VwQV>u2R=HkD5$ibPCw z-(;2X4x5WeV65TCJKiylkFxi>P4%_P@iyjyn#veW=NAR1JKTk!8yXk7MbEXSYo?E; zEhJM?9J3R#R617fqlD9C`QGW!bHf3ml57mc?V)Q>XA7;672<8SJf$Q=3*r?4!%eez zBrhfQI`zKSHzLvRXoktuFSznDy7ILu2qij{cC)zR7dR`z-EeI8iD7OokeiJHk}_>c zTudU&kv92XH>}=fB?~P^9i8}+)>9?%L9`gblylCvDM<9+9%)@#-dk4eEN45{)P0nlFIVpD>~16>McEISka?C+tnggBhgi9 zID|Fp8ryAP&e7yfw)gjb4-}sIa<@~1g5Dx{^uH@ldk#)qT8`MRW_CE{XKIXZ7vqQp zYvTslsHAuIjqKjvzP!27dWSHQ@-OS0Rjy+&y)Ttz-XkV1;+I!*Ym1wzAE@prk~CTG zmiYaww+^|etxDX(HrUx~jYR4o%dMRCo~@y_$*xnuV*sQRwM7V;I+v{V?~Jv{K?j>Q zBPI_d+aBAS3xp=5mSzR5@va3Q$*O5{r$Nc8e7v#TBTM+aC>Aa4Xfe{He?6o0N#`o8 z;bjA}$D)@}WN0W7l+V z!9h}J*nN+^`(H?nZ1KOMQx7|9gR3%H;N>DNBPLwz(R7t%YBL9Ee%5th^|f5%w%PNz zOxcp;nA=)Zl{pnz1E)$-mbUG6AyM!1_wDZeO}Wfy*Tr(-3w13mhN{htLqBO~)-$1#+>B~!WNnFckd>zpTEpfG zn^0E{P3i9vV}BMBBH!D?o=DZ$nc+MtLf!c5+meMqk>fslZ}#ljW$p0pcfZ&+ULVQZ2pwlGr6pcD>QE1^z1^h7j8rbK{iW>8o&}cTnj(N<64} z#`BAhTPUnA!EYxzbrVVF6^0{GS+d2>bYnV&gS2iG&s=oiuH6|h=X@K1+U{7pBPI@X zJ}=JhW2VBziizLfeQLSAR(VF)_+Gzj&6CUPL>*BZh089eWZGo6k!EYoM?Bsx*NpCS z2wOQkW2z!vhu2L49jQ=*(B z7=Yq0fW)%&?9G@tIU&t4b*>^bocAogLRNmBj*(yyFVVrnApB@7^Qam~8woY n} z!(oPjaQk@>OB)94ZNs#kHEkbf z#5tV*L7QWbM-kuCXh_42z)#5o`hGMi?TDP>=sz8&mx}VkJ)wFQg0XuoS(rJt(ht#` zEqa3S+sqtT+0lE8rB)OE8vd-(FR{~o>CUcDgQi?M{j;>u@~DIE>kJ_J2izgmbEB2k z(vZOdm9r6Ha^X*)HQX&{m>HHKZiVS~op2G`s;;ul5esf3C>U(X?2aO(c22h&?VPoh z?N|^^IkXe*z!9ux9vl>Cnhji#^ zj}*j+{54Jhqm=5it;ar209zn)qZA3!>A6n%!*7PEN8yS0C=O225hu&O`-AP2Llo;H zPb;x-z!8M|XyJ5%sgy&S#%*e?e_S+(L6OqM(Yf7mvT=S@yNEe;Ktv-b7m2H^(HSy_H-gU*T;E3r?lfk7PpE$*EGCJhW#l4v5_n#soD0_$} zq->^BuSvvV=$Yfn+sAI2`!GmOrTwcyFfjnc-z^qkQ?r&b&{54Pt_+J&d&+9h%*SFp zKYdFXPFxQozu86b?b?|`ir78GT&AJL>Y_!}i1QT2)k7mD!*iPam<(K^oSY~yM1Usn zRrS-BT4DwFs@-;WJs+)Oj)~qzlI`(eMFNN$j*2aWauCJGkivfQ*iA-&<2xMmm71^^ zQS$dQ@^p4LRU;<8VvKoTD4zHS6iReqPL%nT`WM2sTH0fSdRZJ5qETpKNDa7M>dj}z6N4|BZTEH^AdbGBcgP-Po^q( z*wr)Jj>n$4-LfgB9Vzb+mbC{Dm9w^J#(eV<*~fZ%?v9JTSab`a)+1(Hb(3UPVWNRE zpb=%?(WZ)V1iJ64tWw?DK}@B_rGvE{{ao!DPTah0W>I2ABYbM25f;^esDT%dE^2V7 zNRZhoDh%z-_lV?M8L*Cv7(00ZKp_x0Z#Kyu%Zc*Z8GW;~Y(X{eh*T0Jqaf-2J8ap_ zpeSy=WBV$X;bknZE@}k6D{<&5{Bzqozv)!k6<4o+GQzH!b7Cdneg*w8x3W}Ri^ z_t(RiE5{;b!Q1@&!*PD9hqA@w?IEyIX?j zzpJ9?cj?=y{+)=zJtHO#Cv*C=C?Wek?U!lo@2L0}XOF(VhYr=c4`r$!(w(hYZ_b5)X zBFAUHt{dMS+l3QZP%bGu@;`sWQ9)wW%jtj{k?tW{KXaenP2s&-gu6S2H}*uQ;(B<_v3HqXbagC&Z-`J~ zddk5hV&VeTMxaE5$W(hB8r{Mh8@qLuMMmt*4CTnoS$e`LVZ^&pJS`?J&h*y%IWqYT>&g6je)jYd(=Y+J-j2M{&YjV9vT9D08xV~K| z<~%N^9u+6qo~t_%MFW}V?wE%2gRujXyaTt`B^RP!Z`Gjolk&8v|Ph!uHm#gc1Tx@dD9@W6g z5P@_bX^?CR!n&3}rDt{und`_B6NB59qMtGYci5X}h*IZ(Rq?Z-%#VH9dn!L1sc zk3PCG7@pCS>T>~+i7?uGE?+xeR?S^EDB9Uc6eLy~Mu(}{im)3+JJ3fOfNVW!d9Q#$ z3%?wAb?_fhtmgG7{55Z3x?;?(#+pi65UTB^sibb^=Xjew`+1y&^LimqWJ%=ZCVMPr zuav#Cn(0mJc&}3@9kX#nPcPh}s5vAMR>M{we63($Y}PAo+u61*2eqA9>VB4cA8Qg7 zVi7pn-;oBfw|uhF;(0u=9AU0C{Kfq5&#t>EY1nsoX27V}wyq;6{96!7Eb#(CMY&3= zoCM1kNOS#>b(6`Gs1tfugn2`naL5|@P)vxSIjvFF^T!UE3#`inrB&s9dv@Ws)x01uXUb)^+Y$JuKSojgK2hcNNIWYcTD5AC20BipkaOc_S#CvmSM5j7VT=)M*gX1daX8+Tit@@ytZ)&Dr>h~GW64WOLZRSCV;$|->L$_kPy26zU3CnWvej`kU|F$nF*>FL^((d zVT0-sv1|^gLo5D$ZqbF(922bD5rI^@U}G#UM64Z)>1p13;{_09+oSO#Ca&_*eae;_ zbwVC+7e1danNk`T0a}xwSk6{ZBPPy&Gr3NIcp)ay>5__JH1?51JKrx!u5JN)J{JRyG$SY}f&ok=4|_lc1vOa6kR%x!AXHfFl$v?layauf8YG@4=Q4vhKs^*WjW*0MJKXJlT5CnF|dl<6ty1P9}MLDlQ3X*H1d zhTE(tuz=wo6ck}jOh{g*lCx5-ub^rOv1COi!xp3(H-Z8vCz@BQ%FPCvAUD$?cBkI>D8n#a&2_o4kH=7bm@f@Yf_0s zN#y`gKI}!e1+XScsfl`Ixn$CXEJ)owaPxnCtOUW^1psI$9VH0nhPR9QM-%|(Idg;C zwfi+CaxWhv5p89r%x&fLGTy^uvda0kp}Kd{FL6j2io}7f$|yLlrNbGZ-7VbuLbJ|A zE+HZgFAO_3nDB%P&eyQZd1m?n(_*%od-N82Fg1BI&i2ri0aSsquHSsjG(DJJjvHPH zPb)gmNGL&UCrl87<|#z>&sy~Qp?xFbM~r7ZjU~HVVFH7MhWt=hj*Bw0lDt)M;I&B* z7#rL*H>k4F@0M|#rlG7IZZXeEHJKP4V5iCbL?{y5h|zpuu(JgcAYZ?3VyJ$~y5vSO zWi8ir_WFvcQts|WimI?b!TtZK?GC!^x+5k(wbO}_e7pM02HLazcl-a$Dx#vo953px zm18;cp}ObB5D)Pndr8^UdSU0-czBk9-iN0w;P4eiL-$}f!2Z~wPv@i~C|G{ni$_R)D=yFxRv^cbLiBPMAo zjDJ*0b&z`2^%K2%8kZM`PH1^dFimMy6A9y8eM=x$GGpAho1cOGhV+2dtdH! z+gYqOK|uI3$jLeQn_m^-N3bKk^_hbpcpJ7v*ZJ0$pZ|bVjd(Be0{TM&dfIbK+&$$ z3|NBpHAW=Eu!@K87iqzT*sx;)Qka;7VY1->f<7<_fgrjbDG*Yyq0|n^E#94ZLQ)9; zY!^t-0dh@HE@o4J0rQGGpB+&JL4)?8LYQah_D{^en!nia@ccS-Vm}b4e}ymO(pDz} zg`^-@aGcC5;fzDSEc=|F)7ABVn32>{P+?B8?x>~y!Yn*!*keADK&iu?Vmmral2>&i zo~f=JtIatynECbZpOH{oLA>IX3YE(f>)Y;ssQljF@Hc z8#PhEE_#{9+TnB}gWE>(=$fNbOQcQ}!QEZ)#p6qy7!>xFMYohnSvR=#(q?$+R@f!cLi+lfdV2#L#FtA;t!+17HE zbzJI%**682o0qL8e-ymM9XPZF$OvM2Q#zX%6wYWISfpQofLY_^lL^&0nZg9 zeOwG3u~p3uLuLgAtl|f9kYZ@^dJ;pevv0BmstbKRn0Lnc9rs27dB|%dF)|{_1teJ_ zk!0VJ2k(Z-Cna?lCvKx9B)M{E|( zBzo1~U$Z6~LG}3~=eeAB@r((?sRD>ilm*4#1dw%ZB6S z(;J2@ZhA;i6cKYGg&rQR7vr;rYIXI_d`^0*OId7MfW8j z?9`D%;)Nq9iTFOpJqM$w(ANOl06Phf74wpK>+D8G*~Ksd;S@|@c}9l-g6L0()?{k> zC><&}Zhtmbh2>!q6rJ>WdbN74?RM!scay|jsw9dGn-$%`sqORMFVVKXkFcqaF8PDs zA?kN=F5hRX89w&VbX`Q~C1e9-@D%wp5fGlbDjAuoCynQ!mLP~Ic`k$w2oJM!Oc*05 zGJ&~YH68DBbB;G`vo=@XpFI=o;jJZYquU5bNt11Z7T$pm(Cju^Ga(h~)){T8m=tUe zIGF~xV6M}u!WYV^kwN3e(`ZQ!{Z~Ozgp2$76YDds>n|?I`mNL%bdqxRPC|SxzcNP2 z_QiANZP>^On{myuI8o{#aP#u@ex_MIeikDpg}XI)WdgIN6E zTgiE1BpugGmG~2D#o-@NJx{+UTaQaTChNCnRWpJDhjyV4Qs=?Ol${x-YC1uj8hxc# z5f&Pv_2#hlAn!paB9J6RfSEu`#@&$xYl9sjZGB;*Dw%w9fDciYLJz_jnEUf$BPg5l z&$O>M_~Xny9!|90s#uSk*)jXOEo?{9`i?`IK_)CjDvblWZ#)FR79dj0g@wI`ImUJ7 z^M?P-XVHkUsO6pIXxw-!Q0w2l!e1jMnMx-4!b1}BZlz~_Zhg|5uY$FhvfaZ>N-+bM zoRv)iKwy;!;j96y@}tt#l9el>@RiMrvT#g`ndTlOLw_SEF&vwA2|9!Zqz16f2kb2( zRe84P%`pi6RC$ZQatqn+m=1PqWa2`NQY=zv7@bZ~*)keeU8PI2e;N#kE}RG~pwt+c z+!;g9f!_KFEAku;l=?O#o*J7Bd7+uJ3B2>kD0GO()f3Gw$Z+*-R`wxOH5nr&F(+DT zp(QLdh(bTNqFLg?^39M?nbc>}!o9-v)_l z1U#9`J9pa-=YS&lqP0sm;BAdDjdFJVBPfhy4y#=pX4;yQG;({(o^5Te@@+HdzB`AT zWCMmJz~|%OhBIc68E?Hw;je!<8hIU|dj1l=oAONs;QM`Z(&r*Ccyi+&%Ak3`dkCF! zh7jThBPtJ|2ozTRD-Jn<)$$L6n7waXz87zUZx)(n(PpVOOtLPdnL%K6F)-}dsZ~pY zv>BAtV6tq*olH}v^UJ0$BPQL|SAORzUktiue}8{kq)GR(zI=56I!L!Vcdn4n z@J;diNupyHA}6lknu}8%Q&)7_;atvh5V(Qco|5|*78$V)RbtWxGYNoH9bjvj;AUHD5R`SWL+ziP2J&~tOH`o4XI$Z{@xr;+hxS&SXfgEI2p#9;{J*UA{_D-% zWMm`>{a?J4n;@W7RD#MXg;_OBp=`}<`^;xf+2ZbX{H`@X&*M3>^8_Zo9k)tB&QtGb zcKOWQ$8YgFAIsl-&#J~gnE&TNwYzvzFRt^3vPe`h}1gpef?F(iUj0wMsH zDmV0gf9d}JQ@sPH1dvdR)F`y2?Dwo}`QnZM z7<`P~CSBolQd|E(`$U#L`aF_6eTFAWIA$^QJh9aVVDyp#Eft(n>r;fYu)TWdH?hpqIEe;2j8A4?t z(%*cuo0p|jfEsStEfhxwk0tX^l5W#K9%758E&kj@pO_Mc5+VY{7Ic(-8hlyWd(WjK zDEkDg6`W9B|0#tg7t8VU-Rau7LXnkTVFI9D2#GK@e}L-Q!AMX5-H>J50L&pTtAEqk zvhzeSU+G}=#3Lx`I{sIa!}w9M^O2;5#?Rx1*^L zJYeMxdouM{&T&#qSlKYnX8vI(h(^%Ru-tVsGK-VB5OH=qzzGECp0T{|ZD|nhM+gVo zZ9C;^_I|R-ejX>zqahgXC42nevxsgR{j7L^*$?dGJ{j!1poO z9r-waPoD8#i`>J>bcy1sgIMIC=h_q2xO{0lVc~}`-7eRCfdcqaX@|2S`lT)r3_>6Q z&9Xx@akN-4N5OMwH4RW#v`|bj%Ep23)7RDjzmozAcmIFJIB+h|rrO zDB}~ED6tdB#JA_lwAGK#_5F5f?b$N`eHPEeC#O*!SUjw6w%Gy@q-f29p1buci2(o+?cft+pi-uEHCjVNhhjz^ue0ID8*aij)2E3g zq^2I!k9(<3HYVVmlx5+rw59D-8+)Ca-h9;PEE{OjmP1$aM^N5Ti`i`+{2Rz>dVF4Vqa8auf3Qld7G)WBHJ z3@o~}n1ifU5mN?mVCfcRFJF+OUj=9K#vG_bBw&&De64$*TM};l>Xav?hj#O??(4H& z#MZg&{e`_QCTD4(;$zKp7)S2)nx2m5o_B{{AN$wQMGhphh>4!=!%Xyu!vt8VD6q)j zA{}uMnq}cSBPKQcCYjmzvHUD&D7LJ@#6O?BTIQ)Jyi5tx+E2v3JO6sQBDJ5Fp!>2s z_u@0;u47|cX8F&3txfTQa3Oz4^AaZDvLscw?tAonR_g~rX4Bi&Y7{fR zqxKWb--G2jsYm>8=jKKFE&O95^dl&awXo5l<44laauaC1$VezbcQ~x<+H47nr$}_} zy(F1Jw==2woEkjb+Abqghv)0h-B}kZ$It1~`0<<_8S)p3nDmFEIet2Ai}QbIemEVh z<9*4zBs;8kcWm0$V)-}Xaa)Y(Pip(BVw zd_Q=D*Nwr0tyoRxZ!C8Y-<0;zXp}N=gU0)!_XUeAU9ie*cJlJ7l&MA%QV5kL(K30w zdT&_X*wU7X`{K4##TVarjs7RLIqI>O^oq(L6RmaNIo|P2($>j&j;x73nqFI)$?*|sf36+v!0`~HQjwwT*g<0vXv^3+#*MI`TTj<;;)wtFNJb z?w5}5y`@0&F{P>&-4v6`eQeKWfz2N(HtD$NuO&BEJ@yWiDu+|Q! za+i5|@Myd#SQj&_lLmA8c~#uY3k#BtV*B*sqd^-;{)1V}BPgZZiXBu?x#FdT;`&~Y z-g|B@r%I)XK*Y{bq!o^yCS zcC-!}?7c{{#-m`abr$;w?H$!oEHn%M+nL@**~Qkw&^Sx^D?r&8W2cyXPqUGIJN`_DskJ zA>q)B#72bsVgEadxN|J9{%}T|NDIK{N^@inpS~a4$_y+jL6^9M!JCM*&X_GPH|w*8 zJ|_;dhH0cm{GhK*%4Ba=2dXaB)a#QMsrx?r%Pe6n<-z6H<$%_ z;Z+XC(^2^3p-*Z<(F~_*1t#Xr0>g_oUt4w&L3$3TS{)sP#=K9Ltgq7cr#$qAXCInu z_4hb;hJcMAhD4Im2s|KV5DS?MlmU(DWJN6yBpzE;fP+j07`3>%Fc%B}?6~>rM=qN& zL`W1wMr0BLj?bCa+B$cdxz!#0)O)53J$Awbg02Q_5!YPWI3p&^)>4l0;3Fo*!up8GL;98>N^5c~N90sTF`f95|YzJIE8_G|0(@&=*9ueMe0 z4#FxuHSGQJewiqHvY!5@Oo$kssKOrEV1^yX`gQg4MD(JN%_x9AoPVcxx*L8KRGyY` zwSBUnosoaO##a6uX>SjH&d~V>mG4|TedY2lp;+#I3GQ$`lk`I)JamO;?ZbcB_C}AU zBPO{kW2fW6ok{LEA(bt>(y4D|yJ6AgE@TubbHBymG+-^&E6@p})Q5T(U(ctLU&%V# zmDNnI?103Fz8r$X&6UQs$%)O7M^DpNE+Zzh@h&Km%z+dkK?Z3ax~2swD99rw{p07T z7GK~QH3C;J9j|bK&XTt^*Q)schV}n%ll6Q~p3NV%O!^}zo%a84mJibIBz?~8jx|pX zw?5Bz?&0-Q6xs4{wQ$K_hOck4g|VLe^-j zQAA7~PcE%Sz7z$!C?CUFT>0!aKLBu;frzP7VyVjeD)|IJ6nODbQ-0y~$?#t=AR{I} zPt`A_>V914nh?77L^{_nG4|WnM`HqCCDTqG6-&sL1*{TBS&n_o4kQUJ zzBife{K9fQbKUPXL#r2lf=d_}k?morRQ4Wjh?9GClh^4#POeL!v-m8E7%;+Xj_uZw}HV2-j$oWYP?KuY!CSK1IZ3`W*UNe&BmwQ3-h0RQ$~H$lcFE2M;bBI*XMZ z=UgR>PnV{eR1`TC!@ojD-O2sGvwnpIe%EYu=N8-+N*{lPJev&1Zo1aK)sFg&NY>>4 zv*!YR^H;&G6{>)--}Q%N)-HbHJM5jQz8$u@(?0bw+>FjKCHiYBsoY;;pQhKgqT1`G z^ihT|l1aVLj12OFU)(XF1qKHWny3G>XkjXSj7B&AAf`Xq8@CN zfS#2h-i5v++VU zv$nRym&=zmnEK(h8tKS;FR-7fugUXfg^5(dV|j1gU%gU!Fl@673qWaSpXTUxJRFs* zH}Bk?=b0VaQvNzAWof;A)0{*Wu82_+37{nee6NUmsK_Y8W$tzmK>)sdvZr)#+U5Xw zb=rJD+kQISxZ)9{k3#m1t|&ZYf;c+i=*m2F*}OHYS>REUPZ5cddu7$8F^ z?SB(HdE91S589^k|HZES@@91VojyEnPI$}1%ejZ0DI^nnNgopn`UB6$Tpe$GrOAQz zuWH0?*=~;UdgG4xm*jC3yhD_mWJ)NOU5sVEh2aLerWOgOdB289AW&U!SD3y_5 zK_sgNu%(Xp1310f<7dKV(a!UU?NxTWboL!MlU$%IkLDC;gykKJa(PtW#N zAQ_u=Uc*?W5l4mGE-UMwP17{?_1z;V)ziyLwRNuE-%L%l{9lO&(sS7kk|$?6+xsKc z+|KS8O{XLpkdKapCzkZEdWT!ZjWLnVCu$S8*;fw8!m4tJA1X|HItGqe8R?m-3Fw=1k&Dfr0V)p$+QL41vVO~W2w&G_9(9N7tR zs5G1LRFd^~N7!|~hJ#Y%I{G6f!PBm9l~(g{BPOhox}Z(2e%Q6{sD@$b zDO|!4OW+>t7qPK`pw)#%2RCMgR=M(ROpa-4QEqP-5rYG@RB%|(6Cg0XxQ%uw4kA*^ zJ%BLmw*bofowf6HG!dR|O#58`+Cv=p+P+WjviI0gGyrZw#15J5$=CE~BPOzAAjk!% z%8g?2d>Vqy>eQfakd6dT>mg|RzK}|u*^LL;`Nz&(318&XI1={p)=q~L07h5qwa){H z=9f5n6Qym8X2FH=WLEQ)0E~!Yk`O0C#}XyIbL^af z=zigs9N@O%FU_Vh=x341*+(NzCKoT0jU7F*9SVT%nbd1D1{~BX$Q#% zTjDo{%w{`$Id0v`sq^*V-I=`dWe>d0T@2;fUoMu@=lK`abx7>Q#sh_8*Su95AxgYT zG8QV`YrtUZx>XyH7|~V6I8oXyz-Hu$0|Jpb5H$kXl-qsP5M`TCfm3*Oxquwz^BMZ@ z_wRMlbxA`()$?sl85$o2#`6vR>Nrag{uHVG!!!vHMOG0Nc{k+)s;hv}X; z7PvF|-gRajF?C$-?4) zG~Wf?UWNBKSK~u!sp#+T>YEHBD3Rk{W)5W_f|FEKTG?V`MWe5xV1qI(^YwvjVcN^a z`xF~08mCC)0F(H5wpYaGI32fd@xBoC&$n{zm2=19aM2#9t`0w`dHhxE-SqGAe=vj5Trb};!EvSf&Xp9i2o`5PxBIspecdl49K6%!cA+n zj<5?9Sqp}4PA@k{=HHTPn+E5&&y4lRA6<_uy zta|JbkorKZsj9ud&>FXm_d~y(yJ_u?Jg!2GSw3Hs;jYmwpxfl9-)7m2Sj5?nzYP8J z3H%VuhAF)C=-JDrS3y{F2Z7!|HgF_I!V!c8WgCf8*AVxh{Sz|4NQLHtohtgzsN5a= z%@im<+aoAzVw>z>_`m8L`F=!!*Imw#Z-pzI61U@qmrFaqB8Sy5fx$EFA<6-(Y8WFZ z_+UAZF?LY)RFr(k$@*f*T;l>vBTzk#^R^N5qlg=qV(=p-W`@3RFbwbmldyFhOS^Z? zpxO+986g5a2@!WjKv^h=QX?ogKqo2RJg6bKkV*;bK3y0KZor79>dl)3D(Yz?C@z`7 zES;TBzH@K0;L@+Vqt7EK_u$YT_n{;ALV}N%P z|6G2=)3q<|{{8eNFLvyh9vJLEhf^QpDYQ>T;d zCfl}cyJ;rdwrx$eZF8!bY;)f4eE-6}_TKmN+-t4hV(7pDwuZawT2DoDc>Kg+TAosZ ziR4!8KCj^tSG_k5>K%Ew-yt-n1A!}sb3Y+LlI#{{2E3V~eRhQXNl!%2yxGJm5R8Ut zx9Sj+0MaUvpFY=nVwBX88wx*$;sy6o=(vZoTDUN zuA3z)qmZytRV1kwP=8~c2De-+4KvHZUSJRad}V|O+;an;NtcHl?4lth6Mvzfxy6*? z%Vbohsy3t;Fd*EKY_1dx;J-z*mp1if#-f- z1M_zSeRf<|;pM!iFOI=E5ZH2z9Nk=?2)EXnV6+KNaZWu4)tSu^_gUcJkqtU7m0grNU#DLE#BdwXkWkO1Lz_~77n`<-Y<)GSsWH4F-XLTj}T4< z&%PzFjRN^{&HbFgg|hW4@owY@k@p$ZRZ}NvyiF;^e*IvvD^98e=#rlxKku{^( zU+E5>eCfnZrnT~jA=u>VZ(RYqL0?+@bxoLkpL(XWH@_ZB-xn-Es{p8?trD*&zi&~X zyyKb>w8S4lEM9jx(O>?bZd2l(v$9(+x_R8V8CS7+Z0yFaMTIRF7H^8ff8?xIQg17} z72sK2l)($IAP-}JOF1ARuF4NV&zv{Z+`;u^^Of40+7<-_0er>^UBLyran26+v)otw z7$^T(-)p4vioEf|nSQn5klt897+y7~l2Z`pQW-OwP(9MlHCfm%VB+=bG42#S(jt_1 zR3zvA1KR)lUz$MVS6Rmri^hpOn>z^daKcq^;EI;B=c-&!w3g|!Srw(JNMF6MaLZhW zRk_qkA3XxiCunG~5jdO;^O9VLZ=bbk@!DK*8Z|WT*IrX42A*U5_$g0Vl=%Zz5$NPO zPr->sTa16`eTN|zT#JhkMR<0)r2&0se^sF{0_*x&R-Zmh{L3Hy{AYVD#QQyRnCvxb zcNGzi?C7^P2=Z-kGbqA&fP=AT|KR3LVZLU$5KkBMgzRnbCZ+VO28lLt;!vDJl-A7c zz6OiHB7eIuQMbV57*eaqGS?{6#@WB+zO`=TNe!Qgc#1@Zy^o-{c_ZOz_%2csNA(<6 z^>z9S6=Q(zv}hCrk!Q;5ShJhOHK zxfxLjs4-j2DaT!YMD%>-{1iA#SW!+>p+%qiKu!#(Fv}6S2$*okD(&L;!1By9lncU0 zo7mt}#Y3qumd4=fzw;-3KR@4YU9Ldt8nVg#j;kFibVNJ%D!xLh(zzpvN+1JB7JnpJ z2Nz`L{I@6Bm3R(>y35`8ajKx4mMb#WU2Iu^r_-}N{GZ454iKbY_r389N)DpEguLgF zM+_B?43JVd^_rEG#oKu@fF3rvmoo$f&~HK$u(9-fe(wzphO; z0p$>*8S@w{6%I&sFbpfvMwGzGuVT)mx~NR6vKrby={sEa?xDI@Awv=?9`&Zt1OofL zKu1-zD+g~u6Sq4>CS^yQrX17qn-J3SOUP=}N2kxrFAf3hXUg8cI;bHR!WqZIpT9&H zB~4{zg9`pwKX23wM&9=n#~}s87QP_JaAcn8xW6jHS1Wlwe`V$_bY-KF$IIq*k;BB| zgfW@)1SJ3W3^fK-bz6X zc{FXrbjscn_3;6`TkFo1;*sC6Io%cq2j&}2f@ssMGuAU*ClcngvaXT}tr!%`f2ziiFTMawDA3 zU4IY^?nI!V<_cVtfD3$F!(&&v{Ww%F-&vUkClk?9n5n+~2Lkth!$eUM44Drw^)n)% z!Iqg3JRwfQDOcm8j+F%wtYnS^zkU1o9%ICG(cN|aYbH6=BH9+%rnv{)fQ!~?hBS`f zGQ81R*W5k_+Age(a#!^aGmOHp9JA=R*E9R24msH1KutjZ5O->Yg%(hLwKn6w-sZW zoAYO$8Q+)I(f>w?uRv(TM2g_(vrFO=_kS3w@^V};} zZN7P(%i=uTJbz_P5y}}WYbkvjQ^lh78C6l&ZGoqlQ}4-}`SAnjjsvF;H;tk;LZDNC zN$+sRq4;~PMyml2?ImI#K-)!zL556DRq*%B@9jx{hYvOhs?LkhnXrQ<6;Kc`Ye~nB z|IYOcyNO5gR@epIpvPNf!JZalk6{6UuyR2Tp<@G&U5SSux$CkC24PibFu7YI zjci;&{UYI=WO#Ib%<8hcX3;NJ+51rwz6P4cs+ofs?z_T*Cl@dOnDaPZhL#@3FjW4I z*cFciU0we(Mkm|8f*0DD!$*x>J7AnjtyQP4{ zx4MVK@vi@b(&Xy-MV=>I_XceEz~ey~TXKyTwilkeIjX-%|>!P(&_N;$|9XlX+SoeiYHY#oy zr&F9lfTyfWK!xp3L7aww#2wKJ{J7Mj}h0Qc(97m4JX4-jD5_8?TzO|PuRK{PEivdPhJn|?C>DHu)*W-1D}DeJV?rF_D|O;Yh#DJum}TpX!sBe3b%CGi6J5DKs*E1 z_J`*$vVQt^Hr)|wH^kWJ67&&CDc#V}XOo$4oXcEkBT`!&R~zCwoLuCB?!V>^LS_d+ z9)pcCV$i>kVI7jIt0y%+ME>u;ly$R|A5{r!)OJEx|IoA}5Mq%)L$K=p9+w1cU@D41 z_0m&Zf}w1gA5!8ZuIdZ?9I02oYMHwGMfZF&2^s=p{ozhyDR1Qw&_AUsbASVr+QNJ! z19yM-0|hX31K(MB4I&e}E;KLQzOBVZmn+)HG7yL2dfr2jfAu`!DM@>{b5IZtp$X zo?1%bo}N(6_aNhPzLmLQ0H$!_MVjf~4~aOSEC^hEF-^c)sxz1xB*P`D8Xp*i`KKmB zg9BEaDuj~274V7=-~S!9fCxb_Nm~2SA7&9bpHtc*_)5tAB!alja!vWTA)wCU-3hJ< zoflOkJq9LjKB5v$XmF=MJaS>WaEWLb`Scten*Xb?6*m^X5SD)Vz;t~axqX;_O{hz? zR{i#|A`F>>gF`{2nowbfpbV`h4kWU&&NX4l%@SbAi;zR2Y-(evxT9$<;0EH%>gYKM z%QRuNxLZ(zlC-F~)3jThY1*lFS*(t0^_SMm>M2llK@gc5c+UR{3$A!NoHx-4OO3Ax z=Mtmp96{hxZUW#88wecihFc!<|2D>6E zU%9IV@Zh**LJXWcOz20oT+z_OANpFNmLd*ENZ0@z;SM7vcX$%ko2sy!KpJS2(pT6* zeBv!-hud#A3;wAQ8m&Jb?S&0CR0akhck2lY+ONydM2lekiag8^?!S zw74PWQX?#;XLZ5*+D=s{9s4;kWc8Q^QDh%YFKpU^?x?^0-6_)sXus~{{Q6TOG%Xex zrQ_v}I`w1VKV*;DW0&17trjbyjDqg*cAdY^SK353Bdu?j$J;y_WDT&K3!S;=Clff^ zZ$m_Ulbe8ZK2cMPw5h6X)t)T@tE#(Vz@QECBHs#H&3Esi2#lYg6> z30e;JFSa51{h>Mh(reN>ZgdoD#2OaVPsFduvP!JoJAUm;yL(;Eocu_MgS$Zw_nmLO zQoq9Xj8UlF=I@_Z(VC29mUEMCs{B}^0oO;rmzp?->d%{=$N|W+hR)tnQ23o(l~r4( zAm0@$WM-XZG;IMB1SuX$Pr+ZDS&km+=sV{xK=HWHWpaFa=w7xUqAnMm4QCOhnGwd{ zOg@seyH^7iRP}g`HA?g)>OJW*@AWm3JkHUK^+?S7KgIK1#5b+|S&=8q(w%f)c5w75 zpAIy&>dU4WI%P1%Q418V2R~Y6W=_4ATtO^_uE4!U;|^pn9_UDQ{m9?oNz$9$A2>x>?0^B}a7C!;N zS(Snkm4~PJ&M;3360~<|t;?s^lZ0BhvNROy=JTj~!0*TzvQ*$1q^!kImD_2zREJ`6 zDZb2ynV#awcZ;$0KIWX}z_f_V&Yaee_uyaqQ{a_`TC@!)-Exec&RS-0UPHgqP_^2+ zLG1Fuvsg9bTzaKsR8i}A^-W#j_pXvxq?pa7LEoZUPBVITWZD!F)ZMmuh+cwh|50D} zN+LBlo^eyxc?|^$VssbXR*8LAIlau)%^ZHnx;&rpHzG8y!5!n1wk^T~oP_a5!itKZ z;!Z(>E;0XhiMc8^g|Afj0{$bC-r;oH4t{3$bgQ|-e0|nG`a4+8tC3=>oPW|jQA&EJ zZhC%y?3Y5~M$_xEZcCeA%j!DK0zqDdfWUS#T7TZ!>>~m$T_`z92^7Xq*2irxtgxET zvjKxel*I8L3V?;yNJI#y4z-qoUnTCN2XWv{x z2w*<2s9HNtMPc_V#KeXj3dp!Fj+@aK#VzdshehP;-O95^rk3Kfwnb_~NWGEmiXlHN zM>Mx5F6LJ!Rc=WG_3Rv>T&Bfn`ZisSG!8ZRD1NjF4l zBXuBqVRs;%)%uG}H!MVuhha82;VBw+=$Th(hgjZy$YVjjP$A@HSr)vo+m`h&m6s4> zU=#%2dO{j7qUB~xv`BX-x02ql{(NFaVlkzt4z4b)cI8u&ocyKqWfd+ZM}2!qnXYr| zk(}Q*pD_BS^B?<0r_~^gGfbtiZy!nfb#xP^GhfQ^8mG!wO+&{3<0)THp+@QmzR4v{l8$9KZbz|BTXhEe=2orYaOhri;BX-TQjroH8vcsQ%F;3 z;iWA%s$}*UBj^neYl8a3v#l=u-F8q2?l*qD2K38be_^q@)r9?~i<2x=!EpZ!u;W+v z27bf|Dol9$8#WllX7CM@YYVpiTX)wFEo2(-Ia;{(MIS;-tyIfTM7_g|!^M%J6v*;a zTUgi95|#d1GeX}LD-H~mE2hzuqLjqmqsVYrd`WztLX4s2D#bE1F74T#OiK;{W3DqBLq zdnzqkw-Z!m9z-@*1ddBl5|tT@ssZ;(V0*>kIT@lz{oKwwp-->)e-aq?O)X^G#kI^n`JdYCYhfe_I;UKf)ivBG7xVIp<#F;?b@iH zmtS4xo?++feTELE$uzgjVx$&#SE+ay$dZVG-bAzG2&M8l$>nZQDqQ&~CQm*JbDOP; z2;Eky)uL>I2m;?)3cn>7w4#Mz^{w&Y{(cqnO1Ah6Mqdem-50^gELzH07c;(|oy zjENq0Y1t0G;(1C`jqZ0b%OH%yqt=i~DrdHDB&nDO9yck|%i^Stj=BW8f7I;R;9Vvx zJ5{Dm40AmlQZFf2N-OA@D@ctad>zMX!JYBhq(CZdhqLZrz<0Z`oL=)j-$FFa|N=y6fpsnO#V`MVnJ_R(6yHC5&Rt(QTY!g16N(G7`*;Sw z&E!;K5FFWJX;@IwxdMpE!g(&f@!n@QchW%4Lo1`H6hRQQlVVG)DnkKgbX#Jr$qsDt zvQq*glkLVVR5u|1GnEAL;k>t@eSciOz{|F8_4GAFBrRdO&y6QD&W_S*yPjS$lp6TQ zwGCuyj1ym{Pwb1%iS(sJL~-dUhitmN!k97$3Lo5dvx~yF5)(-VoGm$wVmHPAp?Pfo zre+zF2DYL18cvopQt0jbmE~Y@=5Xk7bA|F-Z=JT1B9auV^^{ev-YRGTg7G$S7OJ7S z)08_8uLj#sgeUVn&^y1{0{3OS`=i9<9CpFXT?jlj43tHmSqR3e2XvwZ4zd+*ZnI^S zu+E=Mr5MvV5SxgKNRZ*Bl+%=rd`qZguea{(N;xqg>@&@d0P-iLZvs4s6+=PRITEJk zy0sKy89F+=Oo*`E(1&DemzG@dqv#@=t-V$?qQUmS~va?E-WA4f(BQbZM_ooyEt zGPD;ChXo3ButJ;_=IOeTja)dyR+X=Ig5HR_p1FcfGtbb6LqExIC^Q!+3P;+A1yg{m z3Vf6oaAljo1w}$-&Y}xTX|eof^m!*NAJLLx!3>MEiGw0Lkl+_w$C{*ZLuFB9muxC9 z6~^5d1*hJhGc*3J^ofy8L)`@-RW)xO1Y@QzW+h3kq#3vZFh@1*MQzVb^-LL~u$Is? zLmIKxeo*9Z{>8;64o3%TPAv9j{0-+9wH~iwvq5I>79V~gr=Mq>Ll7=?c24&*_5?|6 zb{s#!kbYS>6oluar)r9Fu~rWo0&@ku&`nRm9B9-7|JXCeTZP~(Cly`rtldXH(s!3| z6V3WM;ba&g%f`#5y~8p6Nwy<}*Tq6t0L=2p=uavP^|6xF_%ebJXaFCPwt8{IRd=2J!ka(T zz~4MsX0a4o2+<|$TSNmJ2tp`Y9^HprE5r&wg`hddg22c~m?|c0O{Oi54?~LgFC>Bx zU8T$+q{^R?m0Ve^!We{r)y|g#)F?59kXQ6TbPO->=^dOq!VBf;}yxn;99m|dS(D`MU7nR ze_r*9CFB+tCYWHr1qUTX!y(US+ZK^{Ac~Cmv_q_EU+3@s$^7j2FEot&&wn&nk2t}b zNGhY!IXHDHrXt+=; z_8svp-xLX83L6_Z zgCMAv$at#ZYiFwF^E^hW=G6cUY53U02#L_~5^79 z+Jx{Rpi{h%NbC$EnhDe7KV@rFV>A+K1NFp)t8K{3J6Uhs$lzl=ThAmI}D z(=gi|Fv{xyQ419ksM?xD5cD%phw}Usv#SH&nwS+zePGOM=A40Acb80t*2KanuSAks zf(#D&FIms~o8TBP^4VgH@_e`Aok@3nijG_>m;Y6vS`ax9s|HG?8d6Hj@NiS8LF}S= z&tVuj5t2gpv>)aeqd*{H#6ThV3H=O_=nxU}Pqh#%`@o-wrd1o%w=WEzj0HT$oK&z0 z+MYOV;bpdbiw_t@`y`tRPSuz*!#iG92mXB<_T{=3iu#xVt~G!APX>02HjCa-F@wZZ zB~^oxFr!+>aX)|5r5KICxqY(kptRarZ8bUeTP&?5?n;H{ojDy`w`+(MWfA~UXdHZ}H|^lv))% zFs2$|hW}`SA`SL)q0_JKRfEY~U-B28V|fdmhMu0@CX!>0J$N-;uhhaMkrGP=B@qk5 z@WJ6_E?;u%K&n)!)oYL%ftnCY1`eCPCqM=W=Y}%a;X&?Hi+ySx3Ub&lu+-KO&ys)$Hz5PKu|0!Caa8$LV=~ghNX%;UkRhfiw;Q*^|8;3AT0@k zEx#MPv;(T4BIY#;@-K9l0>vaJ43Ry=$lC8O)t!J2Hhpt_{&t@ps;xQ3f-&wE$=ies zIfmKP#jDSFs{jj_YXM0P_Aftuh!G zpUB@To+Odq0T^2KmC0nTaugc;W~Grdk|K)}RPQt~08@+dOlUsD;(JYl!vRAEn#Bp$ zZ-uQwb)zmx<3q~xCbQX|CtXn?1+33S_6P!v)fZF7Zq7oli+!s?_veB$?b|NYHTNQ2 zMED;+F?H!k^_~uEcEmgRdf+KL9UfgGMmz+bGC=T3TwGpA$dxtxJ!C@L#Q#z~Bsllf z&Pa}aiL%K!al`7z@7^Zqn-JBT85`nqC5>0Lj1SyxfsYFL=@MSL+2Os(1^P{S9}e~N zha1+9FmE>;GeZ2qG5%Bt#TY&EAdc!!5P9@l6noz(mKVpJ?|1ZI%2$wwUN|q?i@Xq@T|41gaP# zOr5y7rYP9X_cbPQVo+$R`G&!kjcVnwnJ_mJ)V3WEy^aNlnF3J5L&8xcl@Xjyu~DhV zwJA}}{9>N@D%>g>pYtZa#aQRPh_}0!coZLwh|x0<-R;1yX`}{c!Nw63F!+>`I!*=G z-+{mcU;xW)gwy>X^598NUT>G#%biwvNo{?nY9+Vhb=#A#5QW9@e`?+(<&z;!6?X23 ztqyUe`%Wp7>v=}S3V5>L*P(|GZHRj24!7Q*pum(P1wYdoYmA!MNC;odTCwNO+I1HWzx2V%Lw%Rd&ePd>T@L&m@IM+2m4sPI3@ z^M4bn_fFHi7F0pYRcI0c$9IiGCaIHLz}RKD23rHswu=Xn&AzX%u%?Onfeqr>0Nt~q zjv$--E5(;9L&I)N`Vy&exux=NUm6!wq4Mr3V+Ra+Y=Ue*vV z_)61W1(FLVar8wHSgxpBo`)94l>2D1y1H}0s)rv}!wM=Zn2iA`BBS`e3(#U@Mu_uf zVKB~4olD^8$uXdv_j@;~V45vx+%6l!BW)}&N?NkIcfzdyy{#v=vf)fN%6bhgG%4{p za9x_<+>hy3`bW^z_C3fo?+Avwx{%tn*dz^TXAG&Db~Uy6)EXK zkB%rbv{p$Xs2fd;m+1KkpA{dWa5QAeh0R3~al`kjt+2V68wC!FpemRU-x~uEC?z9_ zG9;?y_~zq+F$%VJ;wNk74>@W$gjS|#?h57iH!2|_=WV)T5ulrsy;p*e*ka*JBTT8O zHf0vvm8=@|=p!MdF551b??x%elI-D4!r9pHR1h<}RjB(S;34pG#YC}fu5Wal#AfgH zS->n=mO-Nyc6R{A+r_V^=b=07_Vr7Q@O?p!S7(uPk^%{7P{@6xvz~N;Peqeo-BDUZ z@8pLbIf=A8zVCcApG*DwSP9jN=1y0)xqaG_yVGvFqqpkso{noJ-(Tfg(~c?AhHZO} zj4wHCH$`#^LCLanjspDXCXB$;L4a8tf*DDa@5$C02u$5|9-cYdEP$;8ZQQXxNx_dU z{;25wi9BzgKE3f_CG@M)J*YpL=+d%Ecbky6i&dX>SNl!xnZ}+KlHRr^*|Sv5vEd&C z+5v$nkth3U1PTIY1f$8ePU#N6VTaD&Er!DrU@A4_i5z4bUZ++jyG>2C7gz=aAlY(^ zpwkB6vAy_u<$Y6j9)el&!CPLq#n>RodECiJC}3XZc%cuMSe!tdB9eF3+M`m1$RPub z0+4p{Q=EfIu+6Ww>UGyo&}WdYlBm=Re@^@7JY#r<3GFnwBzz(~+s(Rp>R1?-$%wt*|J(ocwlpp3I6C_qTt3@fU0q!%%#uFm zB7en_l(zta%tQhFSh*937yNysf{rILft+#lQ2BxCh$vbd8BAmG;L7Ht+7``pHq(+i zU>EM%?3P8ztC$KJiDRgu0aa-8Y%`y#&97E7wD$$%!NX9Z4a(7btOZgVHU@ zsw`H;urVIFRgC5JX=kx)&L*kDLl*c|sG@`|`bE{ZQ+W$&)+K$=Xv(w7PcGA%KbN*_NgN0} zc?8NTrlh$3`xi(`x_!qYP}Ppty6s^)1O(2E5|rBFX4i@2UQ|<*LVdIwqziK`jwyuX zlO@>iQqG#bw{-u2iUjGCv97)?dq0^wUWn9BLUM!@>n9vME1ksjJtnr1hMg6?C^s_n z$YCERmObVuT~nH88 zjsU4S-D@Q~_Hrw}6lxqzG7S-!T^K-1JYBHWAZkKeru5rN zY5Gw-MrORfdU4Zg)PvL3urg2Fd#Z$&5}%k)Nh)*bkDa>$#oM`=YLY(wnbi#y0dP=a9dB<6 z!=*7%1*Der47|Lp0)x&QyHBfQ(e07KEx|M8GDShrND`?73sz}vsS-j`je1&&SOh`W zqJbkEF0m9tTfuroVOkC;y=Z%Zt56@7Z5NHmh`B1+hjyM^$R>YONPxN|?(j&upvXBG zg>#-I7+os^WsVAU1+%q_XOG3Jg#0%Ze4&(aR8q4+c%4RaIfJREAHH)QaSwZKQ?}Lw zuZ;8h6vDg{41P#tqIRlUW^aA|g*NsUX8 zYNO45X(3>dJY~q71Y1au3A-J^WC|5@9;h56LRL&(HfCzj zYX5ar%S+iVj{*A_#}{^g=R{62(D?nUlc@cnS@VZcJ~Ot_R)S`qZ)Rq{@%6!_iXb2e zeb?IdhuNz=jq}a-Y(-&kK|C_1%KaPNNTQSS@Y_geGOsu0Fby4BltH}853Cn5$|+xA zs4d|$UHRq59m9lf4+dJ` zk&Rd+BJ8i-QQFSZJ=4R0@|94$eM3T#XzIdcjW7;&tI?_!uw0X*Rkn$`ECmf#?T9hi zDacHwd1?wcDoaSmmYqbsX}-4;3xep%ps_njLS2_&sW3uLnk2T&BJL@DI-mkJCF5pO zHuW+B&`xxANH zjFIBV7jN}}&88d{cXL~(VKdTC57c2T?TxnetVIySVPN1ZTURc<_+Rmv4recsbVmM~ z8wtm&YUq2$gr8U7ery{yc!6=4u8Gkih28d^x|7y8x&$kb5!NKp(qd$h0HRi0on+27 zt(5$+cZ9AZGAqY0cyYtAlT5nDLd62dKpz>*{mNL_JI#$Jkr?0rRN!i>vL_kzCR^l% zhhL)bIreeIbP9X-5(GiyDm*oVt8!w7j^h4PuD`mb%>TR=+_OSN;ojcIx1ycwYw0&i zEcOuLVnaa)TZF6Dgq3hPOJF)X0GxjQ_)$#P;Z1NXkw|6_bBA(kqMe}aW~n#wkJ3J14L!2leJI!k(8dIaW+*~(Y`8~Rmklp zbRv3jb+NkI00PsPvE3bRb}TmZ@fAe#?2~q$@p4f1i+`63*3XXzn(~mAE+$idxUSb* z46=$s!spcw`tYSIGE>&0`x(q$#3R%(^c^NYzK;u0v4ZE7PMCNV^}Cz*%7C)V)^V0l z(Q;-yb<5_9Y%>fw_KjLbl0oGTZtSJPw_Ln6G!A>?V9Zp9rGdy8`Ac`|Moy6}36H$$794l>jK%T||beRXjBi0(~r z_hv}lGY}UU^i#ciKU_C$!x?3JOSF%-kNg_37Xr%irtmwC9{N+*#c}$?S5M@AS(a|k4t3p`6NPeo+HHYp+NuwW= zgvz7UWm#4Gbts~{A~oL(%N}1Fbs~>Ii=i1W)W!>CC&BkBCGJ{)oIrTQuJ@wc6xql) zs$0Ab}cUSO;}yKXl#kQ>BxVO z7N?RuVxDz2#IY*GEmx}Djw*$ilrLiX7CQ1*@pjdnv5EQz)3>dEEo;7mvkw zwrEO=KpsO^uL93kPHftArVpfLM+9S;CJas)wxxeL>lPc+n|>V&;He_bRRD+G=f{G6 zEf*(9G~87f1W%}fz?JNRoM!|Qs2!W(@QPjCZ3O6Z(ZuMwL&^K&U+{hhLay6S%ki$x zlQM#2x>;vf>-wX!8j49)Uk|Y*FqX)CscR)rD-C3YQ_4Nkb6c@8sw)|!TA@j>#TDgx z{o&Z;7}phlN6DCM=5>0jBXLhA)(Lzv=IpSv^Fv; zQeUW%8jq$}L$la?m#rm_48^SYHlkY9O(WZ(j<%@C5Z8Rxf*c%_h^C<9O8L-d+q-XM zIkF2yM_Q5gu1lMQr+?_QI;18xD%f+tIE~l#5lQ-|AjmpcVK3JpZtWyfQaZcB3-fypV7QM^uno+r52mYV{N7FRTbbuwz$ zl7^(6g>x&1nqDrR)1avrBi4iz3vkBfA64F}=mwHJmR(nLdKfZMi2Xf7bg;DP7#Ti= z!g`;B?G)X1To5zUz7J@8Ytna{n4xXASeXyDizPeqNd23Z&i<}r>0ZGYZ`I~@+k=~Titjan^oBHlgK;+ zf%PjDanLG#olMUP$2%%;L_6$6tF8EU*F7HJ2gUTEQS3e6yqLXH_nw z##AU+=pM3PKXi_*m(vW+EFmUF;c9ID^S9lW$kH5SF_`zD)v@u;<~o=W!|2u|wK+nW zE(Nem-1}9Oo2@c<&~>-F@lw?RO-P!HD^r6wEUYXzK#)B||B3M1#{_zQPVO$eOACO% zUlaTGVpDpy`Y4~6)hwG;46=)ZvvxgDAe;%M+a@xYD|BDi2MTbsjVqcd!No~#LCtkg zcZ3ylICYn0P#|7KmLeoW-{kn!Ho^>7q_x@vEd2vTec;V;rc^eA?2=8VhHSBQb;fM9 zaCEZ={*H~F6O|r$a$s2f8r;>IG5BTW=h*2Z%Q=ax$A>|p2`vwl3#t4IAO2yHY+t1% zLPr%cb;#psDnP4#F}B-_YX|~Ii1o#DZezLux~=k?7Jdt80>i8FD6{zUL6F3fs5Yc{3p1Pgt8B8JleXd#-eh7iFA?!QZ{{d3-3W!3K}O-gM(k64^1Bd+Y*CN^99YG<7z5 z*SGDoa8~0%)VW`C!>glY;uT{9GWl*qjO``fVtY4X+$3A2*1Rss)y?@V|S1&KX{xrG@Du#i zS^mgwG+{*2`qqtQfs&Lkp_0**Fv{b$vR?~H79!|a>o8n&MKbtUm{=kVU*s`g{-gD? zk@W!*!Jfb{EH!M_Bxp!jBylZ3`Sy^vfd&DBFa+D~vzX;|@+bY-ph=Od_dZW9cH_lw zTci~PPcOPkO)t8ep4Q;p@$A83NWY075L2%Er6|Z1V@a&E%#Y9Uewuu>KKiycs#hB? zzVkzEgT*f~rkhkO#0so_$YjkdYI`M2RNQ21F}$@~R+Ke1Ok_e=M?K#z%JoPL&p{Gn zpP20IX&ryT(39C@xOGIOwS+H)5GjQe)ACtZNoPWd4cY~wh{=oqim4b?yb0;~45h6t z)N&<2U=?&NyaaUKJH@I%`vdeN_Fy3PXc1+3nF0eef++ZBhPfB@GQvUa!sQU{1_cfT z0cZV_!J?`-z>&dYqS?A!?7E)mthej(>8HEU{u8uMeT~9{%Fv7od0%^VH1%EzP z-MpkPp8q8eFE0&mj}<5KSPU)!NCG6O0@cMiiwn2aB;#B|3Qr^=S<_u@Ux%rFP!F8C3B7u;#F8YXaSOHuW*y^*@ zDj!SMC*mT?(pj}=wPYe#vwFJFQE(Lt%OQE&o08}N9?Ht0u~$O>}~FCU9w@wsu!XJdCtUt*DT>beo<8H}Bb zvaK~B=~_XJg!#~s8_j(>#@UqoC-%k_pUQr7oM=#Tdv!Svtpc(Pf{^~gn1@WR z=(Z1Gx{^|&gLWp6?Bo zyKHBFt|VYsWl6!0iMEf#cO12-%@T!|u*h)hiso{=vm$G`(7-8V#N=kFgdKQ{;I~Zv z-Q6VOx5TSdi6Rh<8r}op@42AcmDNgoiQ^VR-;>f_5F|exfGz^0l2n)#WgHk(ZV&5t zpKpNoK5o%#eBYN^YotYx3z%boV`@g%6W6uanGrgd+ETE;@N44YE!;)mIk<@$>is)Q zS7WxNh_uMN$du)w2m;F4Rm;d(B*TeW*0SG)lHjC?XASCBq_ewWD>+)pPyCh<@tF+2 zq`xYGUHQ;4O4c4>!7VWEEh7b<@OA zNLRlI1lC5M6QKK55ehIG#mSTGTh!4iw8u%`pTm}2#eI!ErV9E0MKl5oFkq?&IB-{+ zkco@3-P7#f}Zoo0#SPTNy|}C)T7aZ*QEr z{j^^ACteFCuEGfd$N%s}2aoo}8bklkVHCn9h=^ENyxoLeJ7c6^MUHi{0#n@ZgC z{eW=JON?Yje>=ZAOf=$!9t7cH7)q*0(!wzq8DD}17f}%S#_+*X4`&PwQDs3p%&kH& z|E(mg)2vEH?A&P7bnTq9#xysVN{v z?RS0>AKd|o4zW!LlBf4T>@C6M*(-~ z1`Y55&Rx5M4?QH;(laSd65uPrVs8`>qjcn8M+x8PkZ7CL$(+`}+jslLOJ)WF@6|gV zOiVY;p+>tSUZKW2ZCyk;11xlGT*Wj$Pwu-F`y%(E>pV+hF){3h^Q*VJRlDN`t|{ zMA8XOJ|F0eb>%YM6qaPNc2}{intZi8Ikc^e7YYzbhykmw>^hh>3=a#)si- zz)I>&E}N)KlMAPP6~A7;z4Y2r2=DH;WAEFE!CW1!w}K~+r89J$I1;%_>bdLHQ~tnK zSikD^Ka#Hct*N(-(~Ju)7%*U@gTWl#4N8peZlt>^FYeEA>1r`$(E(jC@GiM6LSSZ z;ZjAvZ?<~{I9DmYVL6pNr3}0yRg%r5II~iZP?*Asr_wyTK@we^3jGP2wX+VSWNyeN zEQ(>S+s&~>g@BpJ?k`dQM0pW;sOK~yc$7_^JsLa@8&GaSM}{(i_=|}b=*ZsHmENBV$PqNpC-d>E z*4s5$stG5(iE25DMRo8c;Dyv|*X4Lt+z!OhC{MHVmy; zh_UUV;x8j*|MocqEdLz<0Ep3|i9>Odx<5V$*v|p3uSUcd=M8YyUaD?h)jGdUM0~Ht zbK)H5QDDa=wqzvJ#cS_lt8@6;%Mzr%cb;I%|)s#HTf#34y&O|y*>)CY2vDcN`ny3xkXtl>=>DfdLId;q*EVBn`{tV_Y#O|R+vHSs858`TZ8imCQ&6RK=&R$&YS@zJkq8iB7V` zZte`ShX~{Hsc*=n^Dv+X%SdYifxbq{nqylRf1Q8xpO%1^XER_9TTB&(<<$JvkxPb# zBO3~3k*VnmO`5GL3Wk<^lzhch3C*d?t=5?e=|-}PSPP)wx+!ZAc^NQMp_Q1QZAylG z8MH!@jZEFNsa4dqSFZn|W8@{n`oUdyhrMnAHPfkAFleCZa;JDpY7_wpX5-$t$Wq9n zgizf3N2J=%_|0h@c;U4;Rb0m9MCXj1va0-QCp>JFxpSjs{ z>V%|^Fn6@KgXx+6Tv_!OhsE2Z|2EmA7*Cju_@n5&cZo3=qQNw0FRmf`!s;uQx?--gzhJ&WqKX0#qfZ*0oT^SXWzS1C3309( z@NW1@4Za25%qD#rGLGUdvwMf&dIz*6{BeyL2(J)j42@Tqgeh3HC@|*1L{qg(<*6mU z1EVJvP4w#+c)q7uWh$W32?2`F1lQyPbmkybhYmVWW|Z&H__j^}Tw% zQ+k;A@8P}g24!#5aYa6}4dY)P`nYV*_7hpZX7P~l4~WrJb?|=GYrcZQlm=ok(=p+7 zMb9(!k_$k)ppHLMgG-La{Q)~;EVMg4v3G|f_EO5A)UJ8W7W2ZYD$xsFM>qROoBC#Ml$7%o9Y9&MJUg^7^xbwzE`3)~AfM#|p9Xxdf2pZsf}FAG05H{V0P2Rv&uCe=z)D>YqYPDU&0 zo|ZP~V1?BIfyZ~L*i>Kh$Pc75qT^1@8`KwbSOgkaR_Ep?YXt4X(^Eha;g%Es`X2jV z``i70VGb1fMD>vEDb0&r`VbP}e9jLXy=57@ys1*8&m~-?f+f}kf98WV_ajg_d!aOL z@dR&Wq#P>Wch+zF*W@|!F=-MXsds^fLZo?O*yMwkkP2byQFcjYqd4|f~Bo+)sJmj>`gWzyk*R``Jdf{l)XK!lP5e1sRH=51b+MUpE9gG z2>yIU_oX?qykivl(vrsI(`aJ1(SoWP{wgH1O$o*WViAU(rB^s)x{YDdK(cw5&B2#7 zAAHW9KA*T2pLp6>Wwa&IS^$BhIicpE8)0e6-w(O8RuU^F!{?k6F0x8>u{jvInH7n- zSurcd5{qvhPr4_(78D%?KdPUFWK<-o*w-zrel(&U6U4OBP-hJH3rzn%jg9md6x*4< z?{Aeyw_GcYW$#H6@=;*xPC2CgZ}=d))jVsbod{Q}hXkrPfdB++NUYEsI6~I|i0nkj zYYxesGa@@Q$`k7ULp+QT9k->YOKnC6Iks#)f$9d?MIMuxz5Fj})E-w!d- z!CpAPUO*CiyXM_1H8lSPafHNKx8M?6R&JE2IM;QQR-;d3wjgP|<%$r-T;8<#puiD| z3hc%6fZNEKim_b*BmsN@B7^sl%Zq$@>0T9kVuIVLt07S2eW!n8&Fa z-MT#2si%5}%6`Y&ntXlrMa6~KoWFJfn$x%foOFxzlv>rAN=;9*W`}pdgqxRzC#>Y z3a_HV4zD(sDQNhqv`vA79ZN00pc9SfOmf>XH#f9 zHddXvVq{tVSRkL|cy*t&JOw!BxlqjvSU@we762*9Zx9EEMHsXH6}_x*roR#w{+ri# zY@A@};yQj4l_IHvYHzssV;$Q*Yjjx%FECch4VjJ{>>%JIIDRF%+gqE#1t{DA?jd>k zvx;}S8c+*P+a1xUoF{jN_e2_sG{ST&82_G${q}~RA-SOFDEK$sXF06WptYd-lZwjggJ$ri+Kmv(OulxiMyN?5 zIy)9geY5bT`QN^v`}>4woZHY|_!*mY+s#aKoKu;yj)J)Dhe^zGO%vRdAMO=A#stmc z2X-5{PhJ#Q&7SgKUXupu-qHP+_v7UsU67t<{E40@8Bx?wLHb08uFkakNuir8Ld361 z;>RMMTe{r505(x56_QaO@fSoVo;(&+A~3dvN9={cSIdjto|PjsDv z9G^2)gFUMo(zxuVlzP>;s*|J=gFu6&sDx*uHjq(vqoQ5}L1}@*r+h*X_nLHd$+Z#| zuE;bjIl6-2&wy=gYe?2}xvCJ(VR{qDYUz9w;yM02+zg#`j|W9} zawREX<|DYre{SbQ;k(|G&WNom5)*?FAacHXmtk2M^PO2G!&l#9U$5MX)NBeIrmtxa zOsI}+v>=zQ&33(xg;OGeeBe69TNKEA2Zc$#EFIyHl%bBkwYr`**U`nr&1ZqTXRDQC zWS$Z?Q%UY-Z=0!)@0zqaa+SRP1h4y5*9~dZJn8XIWok_LC8W!R`w<kDQabm`N5cEhk)5Hm56#k*9eBRf+#+{0EuBuq&po$=v&`)mT8}STH zPu85NVpO0^V6KI24lF*^`g7vxm}4YI-r;ws$hf783)-=D!#}~4(g4OBpvdSq+1m_k zISdjL^cdW3@#lq146?75(CGUREWA-83ZeYEg~a3CrGI_ z6$q3>I9l!Iago1@EC`JW!y2tMdZ#}rmlB!X&jZ7;KQWW3*T{*q zZGY#fjzVQ>yO~@kTKBfTtK25MwL9BVlF0ibd@9^dM?96zL4xzC|vK9NZ55H_4hT}AWn=pajGItiPhZ$ptZI8^THpC zB!QNCP!R5w4c#fv>0nN7>sUE>j?#D}j_jiNP0@q;keg;StBwreqbnz}RH>&?^b;Rh z&8d9%Mv+OA2IJ6OGD@P6UB*L)+`74X@OzHK@r^FH(t(%63DN^JKGG+NKcC+`+W%Vp zF4kD~mUeE*PDp=_9x_qodn3s^Y;G$)Jq?A0MaS9eWjJ$7rRIc>w~!Fh7^48dP#2ls zsg>p7rDaM5AUVJy1I{=Z)|k`44^I))Y`$=WA$>X?wDoOHrLu<`ca>I!v8RBd&oFfO zVd-m0TF0*q$y;0s4YLRBf7ZP|6B0RZbG^mYjd*b8nyZh}S=T{VJW{F+$F~}Rk|*H5 z;i(2vH}CrCww46W<KvIOlx+6!@4xzY29N&tCR*L=YLl+Z zi4Tuad7cZCjMV?-dUK86h`hNS>5Q{%xQH>q3?MN3=NZj~3jH{9N{mHE=Z=qIXbM|r zR5AN!&v1_bfSMx!YV*8NB6yF1?{opR6bJLwOvl_=M{K~CsgfVp#&)&U_0wly`Tz(2 zK|E_=Uj`ym{I$Ovt=zOtBqbSG;tS5J)*ZX5A#(SCk=$45OD&Y#&)%-aTpShkDI-yp z0sM#Z(->AO;r9oNDeO{AEySnO7Meyq{G0Q09?rML1AKzQLXtdl1LsotuK2GMjmnI@)R=>%~S zcoH)j0OFkGwlZrkwp{yr6Z$vvYW9mh!IrvqW=(XCzWw}tLs}wzI9V#Lr~cTfC_{{i zN`7K5%LbC0J&hmd^e=15i7d@#WrIKnbNZ& zOC-kT*V#K^ZM)SH(W9VE4T~@f#_rm5zqCR9MD;Q!g|^ze=E@e!St?Y`h+qnQB*}t` z7zz`RI9nVE1~-RU=$!1z`dU36k9}La{b*%ji>9?!oV-HL$ZpG)*)PTAAh~M)09QQ4^ySsDvafPdW?@ z^XvRk|G0kNLWu6Xaj{onz=EPDTE0NOl-3e(k^)?EcU2g9%1Zr3`KG_L1{5s5 za_Z@w^jkT9-~}tr^;Ea-uvx{Cdwpsz)avf;{ZwFl<-PyiepNd>>O5)N;PFJe!r^6? z>zOWtUVjHi-76P-W4IWm;!4KPI_t1C(_JRm+>Fdug&NI5VQEagYym&0hLuAJWX(!X znL43rz>-!1<2jo{m89{o853izIp{rqBFXTDHDvdV+xx4(8sHGz>1soHqDc(x?Ugm) zz|Z?R;!rz5?~QDE8FKer8@*?&GK|yPZr}G`C&D&JMFNc~@f5zkzI!A2_`&5RF+Y_t z*}?}sEFv;P4KpnHjD%fimr!QxNTGTEU{ABN6ldp`Nc7C1Wc0ahze+B_3_14;g<}CX zeie$QK2^0F8s@l1@Z}3F02a+RsAD~6zu*go%6VIk4r|NN5mmY4`zh+D{}oIJ`pjksmq>|4|CXy&sX1M@X!@9rgg} z!r&yogRF`cxk>iOt{dA}YSqI9F2$ulH6En)=_nUx_4g2&G3gIOOlN_R|?6ZNTpf(#CkdELokJE*G|`*5H2Oid~Csn8Q|0)EaJfu zBC#1{drr#cB`w=%8VQ@19wAJ!nivy;>gDY1OA{=!1T?V|_G6o=P-pG^*bbsfJ{bGdnsj)$z<#1?gRY6}@mkdj)H2}gDe1xp#`Bw=~T z6Ng!I$reK$hLFgkjPnxGKK^eu~al>19#PUdI3#9 zzM<~h@31fPKMgc@%wG~NzI5=?n-9n-ls=&(*TVw*ne_)LNFjJ-Av#>;mT;mNf=(R5 z5V>A5Nv6f#zqs-M74`Bq$|FCXZsGSV>FTQE*VumyM^!Yb^=wMTR(4)ICeC7$VMRG> z$)g`O!NdIYhVpUWiejf*dY}PkV$nUpk&H3te=Za00q9SeG2 zGT$#14^dwt$?WX&M)*Sv_H}>4Vtc8&58VgzmQjRh7a&*J4rPpBjC0CkG(YDhImDXp z4{F%!`uUv=Dnk3u;)qOEpS_!Ffxn{B#FB&5>{f%C-Va`{+7leEjHUiwP6}Y^apa7s zwqDY^TnhHE4lDa+Y>YF383sl3UA}NkX1M5abS##0rn(O`Bx?K5>O7=njEkLQBnIXx zN~92@@${~`oH{S4A&H`mHmc(MLfY<57FRR@3VYY#^!b|P<1nwtz`mUc)C+oqN2oCn z@#m?NgyhvBi7H)-*1z@Y@6UA~{DTwBqy3twH7dS`>&p9qd&RfL;(^K2k&4E$5j0ba zp~$bw>>@A4)jPy71^;QzfsbS#+_uR#*=fv_zp8O*pfLV@Uz)q`6Cmzx-_Obx9}kSg z#0q%wTst-gefM39ftJ_2`z!-$7_RsLAUsnVvg+?$33HLz8~)9GHV!xwP{3O6U3VsN zE@^P+>gdya7P(v*&rDs6mN7z@V|b@mAbBI}Up~0>q3fa2U^UL0_&fDRHl~JCi_{(% zaK{SPvqGeJScSp(CG!#vH}w&+SoY+GUbbJ>gqK$M+b5j^Uy4V z>CDAe5NJK?D`}CK@I+*fg?#lwb9fLmWk`<2IuKDW3h)jN5iv!BleSE5TRuE$ZA7TPJ3J6;w+CD7{{qb&lx#)hbTU87Nco12@Ix@BHcxWPK8F zv$!!*tPDc+SWtoqZ7W_cjByJ_cCfNeUx!JUN@>-Ibgvi?a3gfZo)9{g$1n9w?d*}x z%zIR3*m2mpBh6+kUL_|{@QSv4u(j5I+gX}iuUXLpGpMJgqu`>sGBkETr=VoJQrtB! zshm=J)*|_Zc*S(f6VSSftfT;q#NCRj)_-&Tew-lidDpluGf-y0V^LR=9ijYR^2LhU9e$aUpxB=9pV^L&ve@3a(<$PGYB1$+0*s%z_1-#66FACPMyUB~KTS@3J_Xx)Azuo)(E^2$5|kjF#wJ9!2!kkw3eSEKP26&8 zEbRUJW_y+@85Q&WZN(lVg?&q~p*MCJgO9E1c0s>qZ{PMm_sCyWa||B(A^$)pjo*}o zeCm3pS*nO73O|`y2nNEH!U?&%mtE1yjHEti5q>*780o2@pv&isg2K48e&sBu(B)}u zT^`9t84OI*Y_`*%V1uKFK7{Wu}GND^m=iYN4&>(<}GT^px=FZDQ%ox>SF|40!8vK1%>d=~j& zq@)m&o2OqDvqAhu9kld7Mx&}@L^q6PC;bjgpTL2%B;$XU^5?ZmA zO6^ z)9kNK(`w=8E^X5-(O*{9I%NJWq|2lfmyI{?99y=)2*3l*0}1UV)XG{xiO@d^@lM>1 znzhj}BKxH*0V-6I(Mt^W<*CdKJeRmeWrw&p#QWpmNCk?~21+^9+$drpz+bB_as(oH zTGk50hQg`+t34gF42=x6VJ>8j#EuWf%{MH7TpTm771MSaRjGSVV<@W5$7uQCr(@eV z&n25H&wMytc1joyrn8o$L?9P8uXGp`<{3vtFtmv27(gzsLTOCN1`vo8z|`Mb3D!5z ziKZ+Wnq~lQmP#@**K=7)Y~qN@(U z)!DN6(MB-rjy~2V9m!M^Aw}M}03rHeR+P}V?yhdj!Q+?<#{cl9KnwyA`*vLHBqPJ? z6p3M>zZUouIg5b!$XD^IS}R&1LD=ky8O-n>=|zqn2}TbWrf{+p$ZF7Y!%N^%_h&?(%Sgt>Wp%}}fd|P5 zsU24nLY*fFkXD4gvA6Pw+i|_`mdxex$L?7!?bo};qq_QDrzuO4EHb{RRVvl$!qvii z{dYg+Y}D1GbkB_isQktKJJw(PK#^xqP_lY~#S%O?!`R=u{d3~Gz%rr*cdqoQJ$pqlJ@hS|4CaUTdR`xbVW`6 zqt|j|6)rV1m1aaqB+R>KM0MU{AMG@7Ra%XCkuoQk#wS8vPzjeRksQ;UvJH+70aqHT zq_?Z^mcXzm2J5X?GP(uvhf!kTb(Jvc!MGH3$bfbE;)sQ2IOctv^taz76PnSG`pG6% zd!&6_A8*b85VYUa{v`Ssv$;1G<2rN}!p6R)DB`&NCdki+D3n+AW9Uw7xjxv%m~jxL z#rqnSITy&kBrNKtnlN99^+%%U$8*3Q38Y>`p8d5ds?9EZR$t@?oG(GPLTcMYl7^xvXW6bFW!LC!s!qs{}hTbzez9;)U2sn-(7rJrzAK{A^N^ zGr`ds+__j+5~72j%jVobZIpRVMlHLu;@!4nEj!gHaBm?nqdcp8b17PD&5~wsuX}Rx zOmz~X5iAi=QjfNdZivGTR`Z1EnHFaTG!8FuN2IAc6#^M+Y2JDAv z%QG}Jkz))Jqm*B8sUfmGMp>m|x2mvqoQO4&1$it$xmi1eQL?EV8}&1 z#gGRhWf(OzGg22ykh(Sn_nDcHYX41KY~ z`K^s=2*X3YUNMlGcB$V*NoC_ENG&ZFYdZYLQahE_&A@bqJjhZ)TYSWt;ru26S7i9! z+^D8%(<6(z(4;E$A15DJd^vWWWXla1AFnuTYy8ngu+(+`XH<)uxrcK}j`b^_=}zOu zxS6GE&KCx_RUp;#6+-wbktVnveLZb?REu zE4~A@V^!BS)D|@^lO`Q~!@%}5L1WtO;y+S}%{~FD9VLJVZ^97q(*C2l;Ug|D?wTF;!h32tF0t83Q(EecT7%~0m;APQciNg-_ap~&$DMDVhokh+-s@>q)XHDKP1abQycoXUEN-CinN zv(p^F>9F9Nn#tFGvw0)xvZARYp4IRJf6b0~u?)-1hOMM!A*~LDdRsE^+t;aUb6GGj z)Wm4>19L;U>C5MBys*e<&`ijKuvpRQvA7&Ph-bRnr_m1d*SW$&Q3_u1(wZp_+^s@N zbt~!iZ&Wgbx3)7QlWD@G+y0pTZKVWVjHE)m)A|n6gX8)#15k+l&6YW#|3DG3N*OVF zF*Q2`yDYf<6Y%Ts2IVqH(~olz^jMe{(I3Su9nku-=TpF&yKmLqYn4Bf`LC5p35uoY zk61>vy8p~B{dkvdVQJoMx{Fe&WDQf#<*`<`%Z-~ab-drSF_7~_iGu;9qDaJK3BGb` z+@nrI@&qw4z|J1qY^`%e_$i94UzJP|&g|V@L;JADVG4X)nA16BBGC+of5!K?}wMq}5Un#d{wpC{yGON3y4nm8U zIG#_1;c0uT1Yrl-%qXn5?9x;*qM;^>==7^KHl_v(UXs4X@ZE&yBcAH48-yF>gaMDF zk32>QNF08iJ6+`h&*W*!(K<+IgoPtZWxPgDb-t0OSvdE)ILENCA7y;>>|jmN>X|%3 zHfSh(YNXm_-*ikHcTjnoJL`c!0@o={-Wq@W&uEgbFi~GaG#;G_Z8%Vz z-c#l>bX$htU9;$*#Myvc-@NGvNeBZJhV~^z0SIZ9_-88nABV@F$$X#Tc!Vd_H%^n= zkwr3xS@HS)5dx7FM)Z)EKEI{gJ72x=K#Gmt&6WGjB`8@t%*H-?Sbw*jWpu|w`lz(ri<4olZujaqVF%It;^57^LZYa+=iwBRS^H^-T&Bw#DWXyh4uE#21laNo=_+iCi2H2dr<| z%SU5V^(2n1n0VE;DPQ+?U)IEuM-Rr*Ho*ZXGNB-kpG;_-L4gO+Nx?B>BAZKi! zL8R0w8|e8>?Nfzqxudbd} zL}@;rN_aRu35kR`0AU5hz-aBfmVarIJ8JpWU$bC^OwZGTPo^oaL-2tP5JP%gF;{=-jQUR_4`YV3p}eC@a6D&=v? zWYS4-MOT&ETZK?((Glq1CP<37fuX|p=(=g*zkw2b5BhoWO3K{VMX31T$OGAMf#?lN zbZja`u2PVBrjI@Q9SKaRUzGtnev;M>>9ie3J+LBggf5Tolw1L~2LlN3li`iR1mWwy zdrdxzIR-f7IcoB4>i?FK8p{$xMKl|hLZOkir(}kUB@6ZM9+$)5tCABnivL>GQIm=k zK%p!}GDY1b+FVy zVl9E>)`_=pmBgJw!)1zUvj~gDpM8?NT?ONE=$m7OYmaAb5Q!Ns`~t{QY#vxMRL4Nr zzs1@UK;cUzl)X)9d3s*ddzXz64p-BL$8EscRZ*37wYH{pdQ47aE^}9=^?Mh|lrYuD zGq1m^#I81Ty)}%YX^PIMx;T3#QRoMly1ssCX+>VFXnsHW=^hoO9zP_a z`PXq~jlvgzEWyc8rlj@@U3-3Zo~gxtaTC(F-b-=#H6fub0K8{&1(1|qbqNC=7!Cv; z(uT+hNB_pfydOI#dMFfPcHPm+mbl#NT%t9>`|J1B+e;k(Hat8IfQXi-o0r>`aSR6u zKpM<%)Qu-^#NYMrF8C^WBptfZ- zs@MIg7#msvM!T`*flcsNR*|-)Mth;9!AWknZuSrCq};3%r1R6 zNAp*0+}`ksihcdBj%BAZ^$odT&nNV8DBS-LN0b2t7CU{_&ysJdpv6{9akevYrVaNT ze5;=`c}~23U|iX&uZ!1wVRBBGb^rdyklY;R5Biy-y0c27Gd(hw3*7McdUA)ui8ET8^ux`&kFWg81Y=%b%jxULvbL{CY+H>IP;je`+Fi>%P8ob^b>C zbUZ|!pr3W|_@>}5M{^xJVHu@C;?VizjbNHHQu%E%cQ^H#p6m?u>8`Gm-?f3|#-5vHLp168 z;(dX%lp(dYFEs{_QmljcnQjo@%z+xgBoSe@ z!SuH(eIPwIvf_SQ56%a=R%n69hk+gJ7Aot_Z)hg*Y6bNVV5Qrwi& z^>N2H@(M75aN?tc3vh@9R)qpRgW|QIiAJ{ng1RIJs|MCR`bnUNRwb=yx1r#_PelbZ z0&;YYUibrF1g!i8^ejYJzP&da*gM%u;?TLd_!m_5R}|!{{P)|G0qbz0?n}%wrhGJ{ z7wd><31Z+fv&7M&svLhdDP^@?$CJE`lr*iIa;V~10mWqg}%XEvkrVrgFI5GP;lTJCGu1|a?Vu_1m{06poMM8rXXB@$@RGwGvCNgf zewh2RalBp_k?piu#?*w=+8xSCAD9xQzg`;PQb#MMDnSqzd8kZWWjP_` z{5K3iwb-|=<3RmNE~)d3fmfr;Ul zc+~zbM)XjZ_Wd1_RCy%s-M>WJa60U=H(wXo9PiJ)#Q!rsTzgWI-}FwX)^fe|)n12e z$=Ybs=^lT!*v49a-ycq7)Kfnc}NL_(a|XU`WsPBwpFS;8;(CuOM8*>RiHOn@0)}buIQ`?Nm_P& z;Hwiksaci^Pr1k+_X(zjR0wgA#fQ>XLu+cT)e7WdIjPN(hQq`{`>a~&$?xY<%l>4} zW+97CZ|fhAWE9nbZ4fe7yy{^L)n+%yWCezeAzQ3PN+#n5J7p+XK7P_Bg+~cKFAu$I zyEt@a#FWK-6qg&6iB<~>KU#XJHA(;0a~L4-4csgMA6wV53*V) zQlun)8xsrForh5PV^z^97zz^4sr&XhZ{>iecI6V|p{c^Z-z6QLa;X7!s3Pez;;*%o zI2-v~G*o2Nm3=BR_g@3j08&J)rGzF$3(ShmXW8^90?NK?I%Z&KOtsVLZNKJ<21`=b zicAox;(YMp-rdgI{HaT0ymhjgk>JX6oY;vnn31tddVP&BI5OK(CNd_17z;#ijoG(^ z!60>B-C)qrJz1N@{L$M)bjR!XAelQ_W7sDPyGoERnw^|jn;zv9MP_Y;qm7|tDy~+t zd>pMZD$!#f7A~hY1eP6G1Y32^zaOu8dyOz+%}pMimN8NC`YwG6QuCI=$K(2L75wp& zW99++S9y)Z#pLdcnyZ46fx3%JGtdB7aO&sE`~PKD{nah$84{Nx+J+5%NX+niFv@xWW=a08X%cN&5XA02sIYUdYmq^3V+X5ihmF~Y`7G(6*2$cb@4g~GxTw;S4{Z$U+H^CF zG+I>NkuyvyW&Vd9SWf-fN%SL1fwtsKa9%a{g#{INORWbJ$-^2?GzSb0E#`o{YmOi) zhZoofHV@4Qw(NzOnbee>Y;0DE4>&C9C0fi_-1q15k^&{uI0nTfXB9RqD-52@@-6e+ z8cS5J4Ju~aI=Sa5xj3Pc*{FMYtdUYLl&{P$F7z77Xx>D_iHShufj7bi>je3n;?Z*# zdI%S-allJ)+=NN>*dm>p)(Jn74Pl*{i@2hiTuy{ZY$)C`GV}rp7gK8}4i9b`<_U2& z0Zb`4A#%8V(&30X{M1}Yky%-NN+}Mfk43TOy}6lO5gAt6-5g*54`3n%odLrlUvXj+ zL5e3UwU|LgQlFf-LO}xk$twi0YKa%ZTG~e%8@8f23>Syui#@W=+0NHcM(6ZH8YLvi zM)wVQQ$@9jt^DtDEvW8FRZ*v50^fk?k^glrTcRN0IZZx_6=(pBTywL9*$_mT#j>S? zDa8W=;t0`&-0-D}IAm#Kofc!Llw`R(xr&-$PUbR`Ic&*XY#=sxd`X6x*|xI!sL?Js zfy)^rUjw{&(~YIH^;i&$tbX2b1i#s?qmb`3GZd5$T(Q=4fWnU1hfvZWIVbpwm+3+R zcQK~JCZBSiwLnfYNypf+)!UOdaw`kp5d?xopDPhZB?*J0tE9tsJD)R>u|i|QI{k<3 zH$piIGnIqlsCSpih{dzj*AuCH*OvpzdS|ynE7n#(^yrjmvS`|Z$!{gYi`4HVC9M{I zg-R1|JS~gp$8za#c3$wHvxSMEA8bJoM-V=<`SeFnTPmoOk<>E^P=|2#^1f7YLblz{ z`5@+(!>Nj~2%HK=0lW-@B2X9sNeT`R0&FiaYvlOLm?`{E?y~}H+ukYPX{9;@aCSyP z!WyCZOHet8f4jgCqsHXRai47G;^v>_vfMZNjG?-tPMZWQP#6gy^pC1U@-G?8$`i*P zS?3Y1vr}^~Wb$Mcvs^FxV9Rd^^1M*t9-V04WZJ5}QR()loI|W-+lsFJPEMToI&~?| zjHH^ZeGP!WmB+|5QX;o7F=!Z#oCE^*-4%Xa4V>}Q8m*!DicG!Y4&@W$x5Li06IaT>O2 zvO+&&jiQ0Vtq4ta&TE$4qp?x8>3G^skymbki|C%em0#iUyab++fB#6iGfmpw@i86~ zZN&}Nfw?3=ac{RL1-ziJ3hsA;%)I!&dkTFBQD;Ifza}PhFjkuxfe8mC^I4QwLt*^O zFPP{ixKX-mB55CL!&-@{uwO;8=&4x2Gmf+=zausEN3k(8S=Ny#3Pl;!cOwl~vf`SM zCPuKcM=)ll5?CRbV|Q7}KB98fx^+a`ueQif8tm5B+k8Y#eYbplK2&B%jZ#4do139< z{`NM8u~5EvfAeMgV@c!|`h6(fZKu$^*azMr;GlED>KLCXF`y$D{sf3wC_Pz(sAzYtbzNLNtiUIaU3NMW54&_cNa{vo#Dnps6UOt$z7&|0~zl zx5(=$s}0YpgwAdGusl zC za=?8KX95S3p0Okd^E~OTUlLA}IKPmH*|E5bwRMT7$C?v<2Nwkq0P3s&lOV&?u{g3^ za@ed4q8tyl&<1qaWOZ;bqUNsAUuoHs3H++oZ7R^`G&LPVD9JbeU_${M6X348&rxbkyeMSv{&(`f)@x%)2W^6?;41}BnPryVGBDA zjl;eTRR`&dgE6cmxNL?{9Qm+BaH-crJ}hi?VE$o-R*LO| zEUu=|eE*HZ{l{!dAFAXo}u=|9gkSlUYsDizY}e&ptv>}^{076^>73=4w7Hx+GIHWtFvn!Z1N)G`t5>Ru?+BM93RN&HmE7h5% zgxS>Fk6&E)u>_*8iVKn1a_gGso1bhXr2Qi-OtPJWfmOU-ATK)iSJfzI&1apj(z)v- z5s&vP&BgmE!e2=h{KkDhC#-R13v$&s80TK<+pKfHk6rhoeUWZG(;!$ST$#}#lcAxu zm?RDL^tx}tL^+3^STmg6emM$r$5S{N2EIHb&+eHNCA!WDcj}Q2+zroUpBiz`rP2Jz zwZTb3`G6VjRWM<5yh;`MGsh$C#=7->PV4x1NY@zX|(C*2i56rubDy7aYtwY@xr5eN<*d7 zVEYY6AbshZL#O@Pw0!U2%A|z}5j_hdKAwlIvOfj9o8NG&{{$%rmIXF zSW>lDD_bvCwbYa>z#V&s`M%6~f7iFG+&9pb7BerD9r0nwjY8$J2;iIe^-lmZ8p1{x zmrh<`Hljb`p@9t@7M(xev93Q|7-zYAU>w(^kmMz z6G{PCf~qc^P&V|Wfx>>9QV(aIFs(&&YtZ4v$b@l6sKABgY zDr~Jwrmf-{aj3k=;8DBB9OKh{KI5JK6^7&gRuOCTzE>sxX)wFs7ibZ7Rr^)mq#3MV zFUEV(tLWG)Rb0eVZqLG;vcTJiascZ~hL)XG?LvAY|+y)l?^jNW{78Hro{=wr$n&Dn2Q zCQ?f6*kID7HTIG8P(&eNdi>pT3xXy{CeNfn=uk+`=d-Z4*xSqT0No$enGM=g`Ac^V zJ6MI|gEzXi+zewhPguoatFWJarlpttB9BzeU>;|(hTL63qPv& z&`z47^R^48Et6;3PL7=Um)lpqQi*x^)iD8MY)<9>0u>^P~6*99T(QLS(%BD(Cw1toCm16-!?E! zBPPJ141_qO15Kz=y@zRvQWycDzRDu!xP=RK)Pq6N$b>;K790w-UZW7Us8 z?X34&DF>18`&d31p#B7KgJ3a7a4>$rfsp2{UdJxg4^$kUdM@6*_&W0R_BAA6LPABT zQWN76d}WdlyY^MY#R-99CTLv)J9)^iJGOO;FI`@_SBkDMNUGkQa2zoZri7v_f#44a=H0Q1_#4^Y7)xL~woc0|AX_&bEI~*}cjT~x zx?U(#5-33dd|)yoC^9MoPy`Gv(_R;`X;jF`bIyK~JExWiI8uZ9*3B=g)<;7~vX#R? znJ9!FL~-}!8!>2(6`vf$R7D`t;i@*|i$Fg1y<-_8D6Q+_*ONh7t|=8H93aZ!WJDPn zjd75dHk`{yz|?`+);z>(BPQApP=mpyHbw!ABO6VH!8={786(P}%FSj4Yr8b|@$Ygm zuIx6#9+IfHO9+8}jR92L!Pz4wBPKzm8hO$t%Cs$=fx{x3 zj-yyMV4y}6V|G_-Y1_{3mXS3rY>o24x^WAETa{KW3DnkU@S4;H5N8mUHbKh+qh%n* zV;Ch?(y7e_wr2vshihaGp*4SGz_l=~(o+tgSfVJVrx8`C$r z8pbj4<>O%TDdD#fztOeN%^+`UPlXlWxRiA-2E z=csXe)JwD*#J1}P(au9UjJ>ZHwQGE8j5w<=k8A=<_4oa08PTYqBPc5dP|)aEMfZlC zJ%7+}C`Dp~Ql$r=KJ_Fboyi#$@yt(tslu&w7}~cAM64 z6->nvqD;%td!LD{q`X2AD8UYr2ZSGChB~DtQ5U&6{Wx)3Y7m4fI@P3Y{i%BX|!0$G9Ph=_~*bv%x^Fd4(pdeuZ zDhRPiQku3C#>dZ1Z{_O|6of@3Z9x#sF^1Ap zBUVbJnXQ!DRHT(jresYbYDS|pQ%sc^D=5lLn#`(7WTu$X)S8-V#?vtjvo<0~5D`w& z{!+j%tk^uXOQ3GGd$&$(+o<|Z(KR+Q16rx}JuX@79;8Q7;eZ2pZH+ zpkP~nKvXHF%kk!M^Mp-W^V0XzJhRX(>Z14#HsR92Rftc4sOIw{CddO|H3q_nLdmek z*7WV_#RWN8TKI+-IV70B+cpUP`PpH5UDG-|Q3H3+0!MaatN;`!d{G(~KUv5keH8aZf1Xi760 zNi^_qZJ|~HOSFQwU{7qR>u4F8DT9@(x*|5LG!U>v1sEA>G9p7b_T1oxSnHCm=}MuJ zjfZ;LBPh}%D8&p15>1dAPPik??Qp&4)#PhWy}*#&pOqmLNJAf@i#E$_Zk_2 zXrVAFGt__}%45LPGGZ78Ns`G2aL}3=40}i-BPgoP0!UAm{zo);0tQ(;nMzdyA_>6t z8HJnqQobZH9+9%o5OCK3Iy{6YoZ>lm=bf#9kkKv4k5%-R=mo|xyC~H3ADxoyWPjH?^W@x zQtIwXwkoB=?c92e@WAf(^@$=9w_szJR_I6(WM0EjLG^gaS?pIxeDd&17&37w z6^JN!8SOibE_UMeiaxvJefyQRKx09ZJy7H*b11~dE@V%;KrkfT8Y3wCzNZ1Z_BtjH zyO-T8J;*{CL&WSll==MuJAx?4q!d`7%xUnE@1A@YIXeU&0r%0f^Jl(EQgJ5 z&!MLO743LEdfo^)5w8eT`>xIYmT2J95gH*KF_mL@KMCA=p{h0K!xj!DWv96I8`HLm z@$4q zFkz`jGvI!0bjTqx5u{@@sK%1(A+2 zOk1j!v&)&$@6sJ~<_sg_WXlY7n6gO7IU^rQ*vPx+tg!7HEs8OZA$~(R>4axYPrqwW2CZtn;CQO-8<(k;g0g*}MG#n|$^oCBPO;sFq4KVnmA>M+IOY6#~f*()-X!Y$Z#Z(xvhhf z>-Ou_kq<3vW*YTs8%(+*D6->$WMo)@DsC)Yv#`37+C7&{p>r$_S7(;HNve*&Ef}W;rj8>raOwwH1H&zcVkostRP6XMN zh?%tGBPOS<8Z3WBj3Xv8G$xu+KqkpYB6SuuSw>B7%r~}O-QyIz`mSPY#hN&8O3W*a zz9fYn@zlwSYbG2J!Wsk&;=~X|8cH!XmqEa5hqGa`>CL_KwO0n9*BUR=FdY_H-vJ!q zqL-yT0|>F_s}u%$4%%d~WCe+Z);O6h6kD@LSEP`}_-hQzg=c0&76#?2!?m65qv9^3 zY<)4;9=R(rB%ii#hl1^c6EN2yFQW`JC1PCsKz=88li@e#D)X7VsxgM#t`5dA{c351wlqO1VW-vjgbsF>+=+< zoluu-8AcogB(esEZJI*qiK`ISk<5le9A0IVu~#!PfHDYe1m)gRQ%xw9RWyYW$eIqR zgF+aWU>azrJevc$w33BjM4DlKAuVZkg*# zZJfO6ma9$Uj3E*o$Ecp|IT%`$*Ka=QJ)?kf*!8@T0uhoZa|K6?K>BO{lhaFJ2prF@ zTepo==RGcWnBT%$!^!Ni%jOK3a#Iui<4c2=hPZcGeabIYgGu*oG4NZ50tXE9aARhC zY_fK?>i^8^22f6eZ=aWOAqQSF55#O)`bHfSU2+5tk6kp#ywAwe%pk^?#M5jRcOkZS zH-aiG{W0+N6o_|0w959bn`D5DyCB(|m}hNosbHZ^41UQLwPeIhDRimC$DoFi6hKY7RKC+A{(ken6iIA9Q!WsRWvV`SR3-Z8>BW#0XBPOY$ zt#DyQ%(1OXJ0ZM2xlfE*gWmunCs0%DiuAZ*F4i1p%)RYqj#Yt*a+=Kul z7Ee6Vopf01ZoE>p&DWc1Tg0gZnq?_!2AGpz2ws4DJ8c@%z>qbS3xR+uwnfaLbh&|M zDV0?FQ>Tl+dkMdfc{VWMP3L92vD$&s@F(1y!p zk{7scp%!gtu~BCD14yuDP?A=aBPd8z7~U{MVA+@)^wjagq%^vS<3BS~h?0QNF9wPr zWI~Dv>-T7@=1GqW83$#Cp@azSBfMXp`V%ajVe+9W85*BWS(P^hx*nGx&r23|5K7y3 zjI*?CG3!3rkl2%f(l(Nk6#FMC{#jA+%;kpWI5T#thLHS}=EUxXaq>?%AerS9kx})M z)Ft4wkxMm1TB@h#vm#9P681dFa{EgY>dWgqUZwWzVnBS5K<%KzOEqbvWo96$8CKNM zET)BuZIo}%v}Yd8FX|YhMR&81G}8L(O3(%2_S)!KB6`ZdLZ_A^XnrfPfWh1K@%b#ii+~^EQFxhxCVCUO>cZgx;Mbt^lleMvL%U> zV8R(eKw*cKRiV2zLqSJDCTgLvF(W7lQ@bN3X0Uo4w!>*NZkqyTG94YXMbSJth=rL4 zBPi4F33xbm2Qx}Y39v|PZ4XWfc!%rG(LKE2d56&Zk_aRp84L(|glN)RCn*wp`OVOp zi<(#@wzhSIVM{uHl3~!`T9Dz-f;6_0H6b(#j+p=_J9OrgdKZmDLLuK zm$q=foI5%W*sO%f*5xtaL?LE!rPPOpowm0s`h-?%sN_O;%+x;5*xDoIHYkzHUPwrqiZ+lWf^P0noy`+s z>cTZ|*jymUV-!GR5sE09ZKs=ZD+m;7N>-CvxFHAeBPd!ZkUt_ONACp*tRgG?S!~DO zui4qx7|1~LI}cEG5@N16P;nQ3AmW@rkO>8XLI6TRf-xJ5bEQ<^kGW9+Sv92C*)29n zYWhCbi{tp0yhgSq7M8`cG>alcfg&thuf7NeI3bY)-`=>F1jmS$1UPX8QDpxMD?uYD zq@YNNv6iOMt(!77fsuYUbc+Cq2#cA@SQiEW#M%ctDQ*aX{#|BgERQ0*%J+V}I|S_r zj+#6pCePe<2hT(5%-CD%1MyWHKKsa60p_6?_(Jd;;WvB$Omf2!nRu&;dhcJZ)kIdJ zjD&)0l|67jHOlj>8NqS3BPInbV*#Mg;Lve~=U1hY(Ig!{SE+n!9B(%wY6O8oF!PFR z05}JlQ4mrP4`QiG3r0g`YNxhp$+t7QZCP3@rlqpcAdrCqK^D)jwyr-zb)B=i+5!R} z(WtHSS*=~Qmb|Z;7v4tHl5D~5=Y6L=kCql0x-xIEh0JT$zbsV!Naq~0F@ZK=l3f7r ztk@X?O$_X26CNGmUTX9Eij;aFr>yP$fdAeEBPb5gI<#mcVHp&LDT_v^wHCh>Z>+Bx zsM0ymrB^{kRffcSMX~K8Cf3pb#!(tkVB*RNVfCg<7PVa`$8IPlE_r z0({~8746LQgdi8ea)5zT7;w^qY+PZ(<3>_{8oWpuZHhD zuPfHCO7X61)akb^#3HFitj)5`Gigm-@O8Yd>}}9ujE550P=$z2VfE`*bfMkMFhK|r z>s8bKV`iVL06#V@$eWJs8aiPmNf6(K%P=bv>Ci(Us^yu%D%&q&!~wd zt5DJqB0^u6(kXu3<)(y){X0zIB+ern5}9wh%JrsIM=leU9)w1U#Z^^TG0$HU36W31 zuz}B1jH9XoU|H$Nr)eHx_2y7kl1uvt=S~jZKYU5#bUJ*pQe9tns6BVKZ_!h38*Z3O zWFd8t?Mm$~H4?+q9D8nq>WJMZJP9f2?lg0a5OoIGz@n2aTuvCN79%EeGZw;VFzR94 zAUfvkXJu-5T7APf{Of@4=QManXhK%pi$`ImSC_|QXQR+2wG_mU=giYXVUMR8)!*@J zVIj)NU?M{FCI@8}V&Vh?0x%(o8o06Gf18Z%;({*ys3B>_6H=-Shq3I$zFCH=JwDz> zaEKCyy;NgjOU9ihSa2~YiQ0Ad(qrwRDo7W}=7*>6JituoCk5N7u0rPpkRHG;raM`{dRHa%rb=|CdC$hy&zcxKKyx}%##H~ z&brAgf+Hpvp|k^bDRuq91UED2B@Z#?FTF?K_E)}h^qhQ6R`;UV2FwtF%iYH(7VUF} zNOMUeCRqjlNBrOTfBgUN{vYps-Cy(n-#RN*^u&yx`aL$kX@V(tyVoxy!bpO9! zQ(D_D@S{z!n9h#VMM~tvx)`E|c4iTo%??ss(>LQK@?`cGCP zCY<3is?u4CBPK|ea;B!;BjYA*wn1&#BZFgF%h;^9E@n_JXdh~8{(X+eV`;F;)yJJ+ zQMA;i>V`D7&RH6)^JgAj(&?!BctOh?=E;~E72In3?Jam5b3}F#F@$?V(L1+J2Q(Px zr*UhTx|Y>|x6)kRbff;IdZ>nR4)}1}K;>onBPbbE8&KS#CP$VSRtG}_vSP%|4bt!@R@TXD2rdK1i1%Dm@!U>1>}NAn>uk_O9YS(mtKXyxGs3I z6HRXUXB2p(T;eE)Sh6fu$s;D5XiLNpkVKK`c5XK1f`OXc^z>vP`@Zga%{5h4fBt>4 zE;2@q%rMMJwL^w<0_?{lUP;0vfglJ(VnR^{p+bVSVya9?2??P{6oLl$g7#zL9y{o$ zhNy@7;vexULk@0$yRJ-F7KA-am~2`qn1n!xq3Oeyzz{vl|9%mSk|%vqd!9-A8|PGi z-gdISw>RjRF9jxA`g2>wN7q|&u5E5?Wh`NJ#abfBGAnpg5RpKr$b+jYQEA4r z!cIHj@%nJh`f4mlMsOV}UTKK`A+fPwO=NLtrBC_bEg@oux0fd7hy#)^p3|^ zc98P_k4=-Z24mNyq>Ld66KHoPWETJ6^&R+{z`^^yZs9w~U;#D`(|5$^75}CHkRXAv z*pAahSVB&K-7dAPn#q;I*Bf-&`2BwVvr%A3n73392#}17h>`$3e*?1vKYRIrfQL#E z=gvN<+373UEV00e~)E(3^Ehz18V=&C@3B(M6s$m z9+EX0%NAkF-{HT@*v!AJ{?XwD5O=w)_xSvioGJ2V>cV{+6EEBoFP4q{{j9(!F<_sT zr0Y+@=q7!1ZG-Zh(LsOtKlJ{O`FL(TD6E}Itf6R|o89hDkN=PLC}I!%z_>D!pXmfe zzPK?T>Uf6N!LybKKlt|5Ez?=MMohjnlvzRbL9E;#+so9Bod3dbZ*`DZ<=p1xu(szU zHW7u~_WJbsbY>2a8)eZ19i9LE)3Q0YfhYL-{>AW`85ryzTDB)u96yBal)t8_f+GAm l?Y1`k-?DKt`ag&A{~$nz|Ha&qP81|7Iy0HT3L`u{JqqE~HN^k` diff --git a/scripts/llvm/wscript b/scripts/llvm/wscript deleted file mode 100644 index 3d1807e7..00000000 --- a/scripts/llvm/wscript +++ /dev/null @@ -1,268 +0,0 @@ -############################################################################# -## Copyright (c) 2009-2011 Ben van Klinken. All rights reserved. -## Distributable under the terms of either the Apache License (Version 2.0) -## or the GNU Lesser General Public License. -############################################################################# - -import sys -import os -from copy import copy -import Options -import TaskGen -from Configure import conf -from TaskGen import feature, after -#import Task, ccroot - -APPNAME='Lucene++' -VERSION='3.0.2' - -top = '../../' -out = 'bin' - -source_patterns = '**/*.(c|cpp)' - -lucene_source_dirs = [ - top + 'src/core/analysis', - top + 'src/core/document', - top + 'src/core/index', - top + 'src/core/queryparser', - top + 'src/core/search', - top + 'src/core/store', - top + 'src/core/util' -] - -boost_defines = [ - 'BOOST_BUILD_THREAD_DLL', - 'BOOST_BUILD_FILESYSTEM_DLL', - 'BOOST_BUILD_REGEX_DLL', - 'BOOST_BUILD_DATE_TIME_DLL', - 'BOOST_BUILD_IOSTREAMS_DLL', -] -boost_sources_dirs = [ - 'libs/thread/src', - 'libs/filesystem/src', - 'libs/regex/src', - 'libs/date_time/src', - 'libs/iostreams/src', - 'libs/system/src' -] - -lucene_contrib_source_dirs = [ - top + 'src/contrib' -] - -lucene_include_dirs = [ - top + 'include', - top + 'src/core/include', - top + 'src/contrib/include' -] - -tester_source_dirs = [ - top + 'src/test' -] - -tester_include_dirs = [ - top + 'include', - top + 'src/core/include', - top + 'src/contrib/include', - top + 'src/test/include' -] - - -def options(opt): - opt.tool_options("boost") - opt.tool_options('compiler_cxx') - opt.tool_options('clang', tooldir = 'build') - opt.add_option( - '--debug', - default = False, - action = "store_true", - help ='debug build no optimization, etc...', - dest = 'debug') - - opt.add_option( - '--static', - default = False, - action = "store_true", - help ='fully static build', - dest = 'static') - - opt.add_option( - '--boost', - default = 'boost_1_42_0', - action = "store", - help ='boost path', - dest = 'BOOST_HOME') - - -def configure(conf): - conf.env['INCLUDES_BOOST'] = Options.options.BOOST_HOME - - conf.check_tool('g++') - conf.check_tool('gcc') - #now try with overridden clang... - conf.check_tool('clang', 'build') - conf.check_cc(lib = 'pthread', mandatory = True) - conf.check(header_name='bzlib.h', mandatory = True) - conf.env['LINKFLAGS_cshlib'] = '' - conf.env['LINKFLAGS_cxxshlib'] = '' - - conf.check_tool('boost') - conf.check_tool('clang', 'build') - conf.check_boost( - #static = 'onlystatic', - lib = ['filesystem', 'thread', 'regex', 'system', 'date_time', 'iostreams', 'unit_test_framework'] - ) - - if conf.env['HAVE_LLVM'] == False: - raise Exception("No clang found") - #if conf.path.find_dir(conf.env['INCLUDES_BOOST'] + "/libs") == None: - # raise Exception(conf.env['INCLUDES_BOOST'] + " does not have the libs directory or is not within the source path (" + top + ") - check that the path is correctly and points to a source distribution") - #if conf.path.find_dir(conf.env['INCLUDES_BOOST'] + "/boost") != None: - # raise Exception("Please remove the boost includes path, it causes problems for some unknown reason") - -def build(bld): - target_type = 'cxxstlib' - debug_define = '_DEBUG' if Options.options.debug else 'NDEBUG' - compile_flags = ['-emit-llvm'] - if Options.options.debug: - compile_flags = compile_flags + ['-O0', '-g', ] - else: - compile_flags = compile_flags + ['-O3'] - - dll_link_flags = ['-link-as-library'] - app_link_flags = ['-native', - 'scripts/llvm/liblucene++.a', - '-L/usr/lib/gcc/x86_64-linux-gnu/4.5/', - '-lsupc++', '-lstdc++', - '-lpthread', '-lm', '-lc' - ] - # 'scripts/llvm/liblucene_boost.a', - # - # - - ############### - #libraries... - ############### - - lucene_sources = [] - for source_dir in lucene_source_dirs: - source_dir = bld.path.find_dir(source_dir) - lucene_sources.extend(source_dir.ant_glob(source_patterns)) - bld( - name = 'lucene++', - features = ['cxx', 'c'] + [target_type], - source = [source.relpath_gen(bld.path) for source in lucene_sources], - target = 'lucene++', - includes = lucene_include_dirs + [bld.env["INCLUDES_BOOST"]], - cflags = compile_flags, - cxxflags = compile_flags, - linkflags = dll_link_flags, - defines = ['LPP_BUILDING_LIB', 'LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD' - ) - - lucene_contrib_sources = [] - for source_dir in lucene_contrib_source_dirs: - source_dir = bld.path.find_dir(source_dir) - lucene_contrib_sources.extend(source_dir.ant_glob(source_patterns)) - bld( - name = 'lucene_contrib', - features = ['cxx', 'c'] + [target_type], - source = [source.relpath_gen(bld.path) for source in lucene_contrib_sources], - target = 'lucene_contrib', - includes = lucene_include_dirs + [bld.env["INCLUDES_BOOST"]], - cflags = compile_flags, - cxxflags = compile_flags, - linkflags = dll_link_flags, - defines = ['LPP_BUILDING_LIB', 'LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - ) - - - #lucene_boost_sources = [] - #for source_dir in boost_sources_dirs: - # if not bld.path.find_dir(bld.env["INCLUDES_BOOST"] + "/" + source_dir): - # raise Exception(source_dir + " was not found or is not inside the lucene path") - # source_dir = bld.path.find_dir(bld.env["INCLUDES_BOOST"] + "/" + source_dir) - # lucene_boost_sources.extend(source_dir.ant_glob(source_patterns, excl='win32')) - #bld( - # name = 'lucene_boost', - # features = ['cxx', 'c'] + [target_type], - # source = [source.relpath_gen(bld.path) for source in lucene_boost_sources], - # target = 'lucene_boost', - # includes = bld.env["INCLUDES_BOOST"], - # cflags = compile_flags, - # cxxflags = compile_flags, - # linkflags = dll_link_flags, - # defines = [debug_define] + boost_defines, - #) - - ########## - # applications - ########## - - tester_sources = [] - for source_dir in tester_source_dirs: - source_dir = bld.path.find_dir(source_dir) - tester_sources.extend(source_dir.ant_glob(source_patterns)) - - #bld( - # name = 'lucene_tester', - # features = ['cxx', 'c', 'cprogram'], - # #source = [source.relpath_gen(bld.path) for source in tester_sources], - # target = 'lucene_tester', - # includes = tester_include_dirs + [bld.env["INCLUDES_BOOST"]], - # cflags = compile_flags, - # cxxflags = compile_flags, - # linkflags = app_link_flags, - # defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + ['LPP_EXPOSE_INTERNAL'] + [debug_define], - # uselib = 'PTHREAD', - # use = 'lucene++ lucene_contrib' - # ) - - bld( - name = 'deletefiles', - features = ['cxx', 'c', 'cprogram'], - source = bld.path.find_resource(top + 'src/demo/deletefiles/main.cpp').relpath_gen(bld.path), - target = 'deletefiles', - includes = [top + 'include'] + [bld.env["INCLUDES_BOOST"]], - cflags = compile_flags, - cxxflags = compile_flags, - linkflags = app_link_flags, - defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD', - uselib_local = 'lucene++' - ) - - bld( - name = 'indexfiles', - features = ['cxx', 'c', 'cprogram'], - source = bld.path.find_resource(top + 'src/demo/indexfiles/main.cpp').relpath_gen(bld.path), - target = 'indexfiles', - includes = [top + 'include'] + [bld.env["INCLUDES_BOOST"]], - cflags = compile_flags, - cxxflags = compile_flags, - linkflags = app_link_flags, - defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD', - uselib_local = 'lucene++' - ) - - bld( - name = 'searchfiles', - features = ['cxx', 'c', 'cprogram'], - source = bld.path.find_resource(top + 'src/demo/searchfiles/main.cpp').relpath_gen(bld.path), - target = 'searchfiles', - includes = [top + 'include'] + [bld.env["INCLUDES_BOOST"]], - cflags = compile_flags, - cxxflags = compile_flags, - linkflags = app_link_flags, - defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD', - uselib_local = 'lucene++' - ) - - - #Todo: - #llvm-ld -native *.so target.bc -o ntv -lsupc++ -lstdc++ -L/usr/lib/llvm-2.8/gcc-4.2/lib64 -lpthread - diff --git a/src/contrib/CMakeLists.txt b/src/contrib/CMakeLists.txt index 89e03b3b..19ff862b 100644 --- a/src/contrib/CMakeLists.txt +++ b/src/contrib/CMakeLists.txt @@ -1,55 +1,58 @@ project(lucene++-contrib) -#################################### -# THE lucene++-contrib library -#################################### -file(GLOB_RECURSE lucene_sources - ${lucene++-contrib_SOURCE_DIR}/*.cpp - ${lucene++-contrib_SOURCE_DIR}/snowball/libstemmer_c/libstemmer/libstemmer_utf8.c - ${lucene++-contrib_SOURCE_DIR}/snowball/libstemmer_c/src_c/*.c - ${lucene++-contrib_SOURCE_DIR}/snowball/libstemmer_c/runtime/*.c) -file(GLOB_RECURSE HEADERS ${lucene++-contrib_SOURCE_DIR}/include/*.h) - -ADD_DEFINITIONS(-DLPP_BUILDING_LIB) -INCLUDE_DIRECTORIES(${lucene++-base_SOURCE_DIR}/include) -INCLUDE_DIRECTORIES(${lucene++-lib_SOURCE_DIR}/include) -INCLUDE_DIRECTORIES(${lucene++-contrib_SOURCE_DIR}/include) -INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) -LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) - -install(FILES ${HEADERS} - DESTINATION include/lucene++ - COMPONENT development-contrib) - -################################# -# lucene++ static library -################################# -ADD_LIBRARY(lucene++-contrib-static STATIC EXCLUDE_FROM_ALL - ${lucene_sources} ${HEADERS} -) -#set properties on the libraries -SET_TARGET_PROPERTIES(lucene++-contrib-static PROPERTIES - VERSION ${LUCENE++_VERSION} - SOVERSION ${LUCENE++_SOVERSION} -) - -################################# -# lucene++ shared library -################################# -SET(PCH_ADDITIONAL_COMPILER_FLAGS_lucene++-contrib -DLPP_HAVE_DLL) -ADD_LIBRARY(lucene++-contrib SHARED - ${lucene_sources} ${HEADERS} -) -#set properties on the libraries -SET_TARGET_PROPERTIES(lucene++-contrib PROPERTIES - VERSION ${LUCENE++_VERSION} - SOVERSION ${LUCENE++_SOVERSION} - COMPILE_FLAGS -DLPP_HAVE_DLL -) -TARGET_LINK_LIBRARIES(lucene++-contrib +file(GLOB_RECURSE contrib_sources + analyzers/*.cpp + highlighter/*.cpp + memory/*.cpp + snowball/*.cpp + snowball/libstemmer_c/libstemmer/libstemmer_utf8.c + snowball/libstemmer_c/src_c/*.c + snowball/libstemmer_c/runtime/*.c +) + +file(GLOB_RECURSE contrib_headers + ${lucene++-contrib_SOURCE_DIR}/include/*.h +) + +add_definitions(-DLPP_BUILDING_LIB) + +include_directories( + ${lucene++_SOURCE_DIR}/include + ${lucene++-lib_SOURCE_DIR}/include + ${lucene++-contrib_SOURCE_DIR}/include + ${lucene++-contrib_SOURCE_DIR}/snowball/libstemmer_c/include + ${Boost_INCLUDE_DIRS} +) + +link_directories( + ${Boost_LIBRARY_DIRS} +) + +install(FILES ${contrib_headers} + DESTINATION + include/lucene++ + COMPONENT development-contrib +) + +set(PCH_ADDITIONAL_COMPILER_FLAGS_lucene++-contrib -DLPP_HAVE_DLL) + +add_library(lucene++-contrib SHARED + ${contrib_sources} + ${contrib_headers} +) + +set_target_properties(lucene++-contrib PROPERTIES + VERSION ${lucene++_VERSION} + SOVERSION ${lucene++_SOVERSION} + COMPILE_FLAGS -DLPP_HAVE_DLL +) + +target_link_libraries(lucene++-contrib ${CMAKE_THREAD_LIBS_INIT} - lucene++) -install(TARGETS lucene++-contrib - DESTINATION ${LIB_DESTINATION} - COMPONENT runtime ) + lucene++ +) +install(TARGETS lucene++-contrib + DESTINATION ${LIB_DESTINATION} + COMPONENT runtime +) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ce91ae94..be374090 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,78 +1,57 @@ -PROJECT (lucene++-lib) +project(lucene++-lib) -#################################### -# THE lucene++ library -#################################### -file(GLOB_RECURSE lucene_sources - ${lucene++-lib_SOURCE_DIR}/search/*.cpp - ${lucene++-lib_SOURCE_DIR}/analysis/*.cpp - ${lucene++-lib_SOURCE_DIR}/document/*.cpp - ${lucene++-lib_SOURCE_DIR}/index/*.cpp - ${lucene++-lib_SOURCE_DIR}/queryparser/*.cpp - ${lucene++-lib_SOURCE_DIR}/store/*.cpp - ${lucene++-lib_SOURCE_DIR}/util/*.cpp) +include_directories( + ${lucene++_SOURCE_DIR}/include + ${lucene++-lib_SOURCE_DIR}/include + ${Boost_INCLUDE_DIRS} +) -file(GLOB_RECURSE INTERN_HEADERS ${lucene++-libs_SOURCE_DIR}/include/*.h) -file(GLOB_RECURSE HEADERS ${lucene++-base_SOURCE_DIR}/include/*.h - ${lucene++-base_BINARY_DIR}/include/*.h) +file(GLOB_RECURSE lucene_sources + search/*.cpp + analysis/*.cpp + document/*.cpp + index/*.cpp + queryparser/*.cpp + store/*.cpp + util/*.c*) + +file(GLOB_RECURSE lucene_internal_headers + ${lucene++-lib_SOURCE_DIR}/include/*.h +) -#C sources... -file(GLOB_RECURSE lucene_c_sources - ${lucene++-lib_SOURCE_DIR}/util/*.c) +file(GLOB_RECURSE lucene_headers + include/*.h +) +add_definitions(-DLPP_BUILDING_LIB) -IF ( ENABLE_CUSTOM_ALLOCATOR ) - ADD_DEFINITIONS(-DLPP_USE_ALLOCATOR) -ENDIF() +add_library(lucene++ SHARED + ${lucene_sources} +) -IF ( ENABLE_NEDMALLOC ) - ADD_DEFINITIONS(-DLPP_USE_NEDMALLOC) -ENDIF() +set(PCH_ADDITIONAL_COMPILER_FLAGS_lucene++ -DLPP_HAVE_DLL) -LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) -INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(${lucene++-base_SOURCE_DIR}/include) -INCLUDE_DIRECTORIES(${lucene++-lib_SOURCE_DIR}/include) -ADD_DEFINITIONS(-DLPP_BUILDING_LIB) -ADD_LIBRARY(lucene++-c STATIC - ${lucene_c_sources} +add_precompiled_header(lucene++ + ${lucene++-lib_SOURCE_DIR}/include/LuceneInc.h ) -install(FILES ${HEADERS} - DESTINATION include/lucene++ - COMPONENT development) -################################# -# lucene++ shared library -################################# -ADD_LIBRARY(lucene++ SHARED - ${lucene_sources} ${HEADERS} ${INTERN_HEADERS} -) -SET(PCH_ADDITIONAL_COMPILER_FLAGS_lucene++ -DLPP_HAVE_DLL) -ADD_PRECOMPILED_HEADER(lucene++ ${lucene++-lib_SOURCE_DIR}/include/LuceneInc.h) -#set properties on the libraries -SET_TARGET_PROPERTIES(lucene++ PROPERTIES - VERSION ${LUCENE++_VERSION} - SOVERSION ${LUCENE++_SOVERSION} - COMPILE_FLAGS -DLPP_HAVE_DLL -) -TARGET_LINK_LIBRARIES(lucene++ - lucene++-c +target_link_libraries(lucene++ ${CMAKE_THREAD_LIBS_INIT} - ${LUCENE_BOOST_LIBS} ) -install(TARGETS lucene++ - DESTINATION ${LIB_DESTINATION} - COMPONENT runtime) + ${lucene_boost_libs} +) -################################# -# lucene++ static library -################################# -ADD_LIBRARY(lucene++-static STATIC EXCLUDE_FROM_ALL - ${lucene_sources} ${HEADERS} ${INTERN_HEADERS} +set_target_properties(lucene++ PROPERTIES + VERSION ${lucene++_VERSION} + SOVERSION ${lucene++_SOVERSION} + COMPILE_FLAGS -DLPP_HAVE_DLL ) -ADD_PRECOMPILED_HEADER(lucene++-static ${lucene++-lib_SOURCE_DIR}/include/LuceneInc.h) -#set properties on the libraries -SET_TARGET_PROPERTIES(lucene++-static PROPERTIES - VERSION ${LUCENE++_VERSION} - SOVERSION ${LUCENE++_SOVERSION} + +install(FILES ${lucene_headers} + DESTINATION include/lucene++ + COMPONENT development ) +install(TARGETS lucene++ + DESTINATION ${LIB_DESTINATION} + COMPONENT runtime +) diff --git a/src/core/util/LuceneAllocator.cpp b/src/core/util/LuceneAllocator.cpp index 7ffba6a3..7c2d2bb3 100644 --- a/src/core/util/LuceneAllocator.cpp +++ b/src/core/util/LuceneAllocator.cpp @@ -7,20 +7,11 @@ #include "LuceneInc.h" #include "LuceneAllocator.h" -#ifdef LPP_USE_NEDMALLOC -extern "C" -{ -#include "nedmalloc/nedmalloc.h" -} -#endif - namespace Lucene { void* AllocMemory(size_t size) { - #if defined(LPP_USE_NEDMALLOC) - return nedalloc::nedmalloc(size); - #elif (defined(_WIN32) || defined(_WIN64)) && !defined(NDEBUG) + #if (defined(_WIN32) || defined(_WIN64)) && !defined(NDEBUG) return _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__); #else return malloc(size); @@ -36,9 +27,7 @@ namespace Lucene FreeMemory(memory); return NULL; } - #if defined(LPP_USE_NEDMALLOC) - return nedalloc::nedrealloc(memory, size); - #elif defined(_WIN32) && !defined(NDEBUG) + #if defined(_WIN32) && !defined(NDEBUG) return _realloc_dbg(memory, size, _NORMAL_BLOCK, __FILE__, __LINE__); #else return realloc(memory, size); @@ -49,19 +38,10 @@ namespace Lucene { if (memory == NULL) return; - #if defined(LPP_USE_NEDMALLOC) - nedalloc::nedfree(memory); - #elif defined(_WIN32) && !defined(NDEBUG) + #if defined(_WIN32) && !defined(NDEBUG) _free_dbg(memory, _NORMAL_BLOCK); #else free(memory); #endif } - - void ReleaseThreadCache() - { - #if defined(LPP_USE_NEDMALLOC) - nedalloc::neddisablethreadcache(0); - #endif - } } diff --git a/src/core/util/LuceneThread.cpp b/src/core/util/LuceneThread.cpp index 8fcac2d5..17066315 100644 --- a/src/core/util/LuceneThread.cpp +++ b/src/core/util/LuceneThread.cpp @@ -48,7 +48,6 @@ namespace Lucene } threadObject->setRunning(false); threadObject.reset(); - ReleaseThreadCache(); } void LuceneThread::setRunning(bool running) diff --git a/src/core/util/nedmalloc/License.txt b/src/core/util/nedmalloc/License.txt deleted file mode 100644 index 36b7cd93..00000000 --- a/src/core/util/nedmalloc/License.txt +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/src/core/util/nedmalloc/malloc.c.h b/src/core/util/nedmalloc/malloc.c.h deleted file mode 100644 index 7f0458f7..00000000 --- a/src/core/util/nedmalloc/malloc.c.h +++ /dev/null @@ -1,5694 +0,0 @@ -/* - This is a version (aka dlmalloc) of malloc/free/realloc written by - Doug Lea and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. Send questions, - comments, complaints, performance data, etc to dl@cs.oswego.edu - -* Version pre-2.8.4 Mon Nov 27 11:22:37 2006 (dl at gee) - - Note: There may be an updated version of this malloc obtainable at - ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - -* Quickstart - - This library is all in one file to simplify the most common usage: - ftp it, compile it (-O3), and link it into another program. All of - the compile-time options default to reasonable values for use on - most platforms. You might later want to step through various - compile-time and dynamic tuning options. - - For convenience, an include file for code using this malloc is at: - ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.4.h - You don't really need this .h file unless you call functions not - defined in your system include files. The .h file contains only the - excerpts from this file needed for using this malloc on ANSI C/C++ - systems, so long as you haven't changed compile-time options about - naming and tuning parameters. If you do, then you can create your - own malloc.h that does include all settings by cutting at the point - indicated below. Note that you may already by default be using a C - library containing a malloc that is based on some version of this - malloc (for example in linux). You might still want to use the one - in this file to customize settings or to avoid overheads associated - with library versions. - -* Vital statistics: - - Supported pointer/size_t representation: 4 or 8 bytes - size_t MUST be an unsigned type of the same width as - pointers. (If you are using an ancient system that declares - size_t as a signed type, or need it to be a different width - than pointers, you can use a previous release of this malloc - (e.g. 2.7.2) supporting these.) - - Alignment: 8 bytes (default) - This suffices for nearly all current machines and C compilers. - However, you can define MALLOC_ALIGNMENT to be wider than this - if necessary (up to 128bytes), at the expense of using more space. - - Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) - 8 or 16 bytes (if 8byte sizes) - Each malloced chunk has a hidden word of overhead holding size - and status information, and additional cross-check word - if FOOTERS is defined. - - Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) - 8-byte ptrs: 32 bytes (including overhead) - - Even a request for zero bytes (i.e., malloc(0)) returns a - pointer to something of the minimum allocatable size. - The maximum overhead wastage (i.e., number of extra bytes - allocated than were requested in malloc) is less than or equal - to the minimum size, except for requests >= mmap_threshold that - are serviced via mmap(), where the worst case wastage is about - 32 bytes plus the remainder from a system page (the minimal - mmap unit); typically 4096 or 8192 bytes. - - Security: static-safe; optionally more or less - The "security" of malloc refers to the ability of malicious - code to accentuate the effects of errors (for example, freeing - space that is not currently malloc'ed or overwriting past the - ends of chunks) in code that calls malloc. This malloc - guarantees not to modify any memory locations below the base of - heap, i.e., static variables, even in the presence of usage - errors. The routines additionally detect most improper frees - and reallocs. All this holds as long as the static bookkeeping - for malloc itself is not corrupted by some other means. This - is only one aspect of security -- these checks do not, and - cannot, detect all possible programming errors. - - If FOOTERS is defined nonzero, then each allocated chunk - carries an additional check word to verify that it was malloced - from its space. These check words are the same within each - execution of a program using malloc, but differ across - executions, so externally crafted fake chunks cannot be - freed. This improves security by rejecting frees/reallocs that - could corrupt heap memory, in addition to the checks preventing - writes to statics that are always on. This may further improve - security at the expense of time and space overhead. (Note that - FOOTERS may also be worth using with MSPACES.) - - By default detected errors cause the program to abort (calling - "abort()"). You can override this to instead proceed past - errors by defining PROCEED_ON_ERROR. In this case, a bad free - has no effect, and a malloc that encounters a bad address - caused by user overwrites will ignore the bad address by - dropping pointers and indices to all known memory. This may - be appropriate for programs that should continue if at all - possible in the face of programming errors, although they may - run out of memory because dropped memory is never reclaimed. - - If you don't like either of these options, you can define - CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything - else. And if if you are sure that your program using malloc has - no errors or vulnerabilities, you can define INSECURE to 1, - which might (or might not) provide a small performance improvement. - - Thread-safety: NOT thread-safe unless USE_LOCKS defined - When USE_LOCKS is defined, each public call to malloc, free, - etc is surrounded with either a pthread mutex or a win32 - spinlock (depending on WIN32). This is not especially fast, and - can be a major bottleneck. It is designed only to provide - minimal protection in concurrent environments, and to provide a - basis for extensions. If you are using malloc in a concurrent - program, consider instead using nedmalloc - (http://www.nedprod.com/programs/portable/nedmalloc/) or - ptmalloc (See http://www.malloc.de), which are derived - from versions of this malloc. - - System requirements: Any combination of MORECORE and/or MMAP/MUNMAP - This malloc can use unix sbrk or any emulation (invoked using - the CALL_MORECORE macro) and/or mmap/munmap or any emulation - (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system - memory. On most unix systems, it tends to work best if both - MORECORE and MMAP are enabled. On Win32, it uses emulations - based on VirtualAlloc. It also uses common C library functions - like memset. - - Compliance: I believe it is compliant with the Single Unix Specification - (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably - others as well. - -* Overview of algorithms - - This is not the fastest, most space-conserving, most portable, or - most tunable malloc ever written. However it is among the fastest - while also being among the most space-conserving, portable and - tunable. Consistent balance across these factors results in a good - general-purpose allocator for malloc-intensive programs. - - In most ways, this malloc is a best-fit allocator. Generally, it - chooses the best-fitting existing chunk for a request, with ties - broken in approximately least-recently-used order. (This strategy - normally maintains low fragmentation.) However, for requests less - than 256bytes, it deviates from best-fit when there is not an - exactly fitting available chunk by preferring to use space adjacent - to that used for the previous small request, as well as by breaking - ties in approximately most-recently-used order. (These enhance - locality of series of small allocations.) And for very large requests - (>= 256Kb by default), it relies on system memory mapping - facilities, if supported. (This helps avoid carrying around and - possibly fragmenting memory used only for large chunks.) - - All operations (except malloc_stats and mallinfo) have execution - times that are bounded by a constant factor of the number of bits in - a size_t, not counting any clearing in calloc or copying in realloc, - or actions surrounding MORECORE and MMAP that have times - proportional to the number of non-contiguous regions returned by - system allocation routines, which is often just 1. In real-time - applications, you can optionally suppress segment traversals using - NO_SEGMENT_TRAVERSAL, which assures bounded execution even when - system allocators return non-contiguous spaces, at the typical - expense of carrying around more memory and increased fragmentation. - - The implementation is not very modular and seriously overuses - macros. Perhaps someday all C compilers will do as good a job - inlining modular code as can now be done by brute-force expansion, - but now, enough of them seem not to. - - Some compilers issue a lot of warnings about code that is - dead/unreachable only on some platforms, and also about intentional - uses of negation on unsigned types. All known cases of each can be - ignored. - - For a longer but out of date high-level description, see - http://gee.cs.oswego.edu/dl/html/malloc.html - -* MSPACES - If MSPACES is defined, then in addition to malloc, free, etc., - this file also defines mspace_malloc, mspace_free, etc. These - are versions of malloc routines that take an "mspace" argument - obtained using create_mspace, to control all internal bookkeeping. - If ONLY_MSPACES is defined, only these versions are compiled. - So if you would like to use this allocator for only some allocations, - and your system malloc for others, you can compile with - ONLY_MSPACES and then do something like... - static mspace mymspace = create_mspace(0,0); // for example - #define mymalloc(bytes) mspace_malloc(mymspace, bytes) - - (Note: If you only need one instance of an mspace, you can instead - use "USE_DL_PREFIX" to relabel the global malloc.) - - You can similarly create thread-local allocators by storing - mspaces as thread-locals. For example: - static __thread mspace tlms = 0; - void* tlmalloc(size_t bytes) { - if (tlms == 0) tlms = create_mspace(0, 0); - return mspace_malloc(tlms, bytes); - } - void tlfree(void* mem) { mspace_free(tlms, mem); } - - Unless FOOTERS is defined, each mspace is completely independent. - You cannot allocate from one and free to another (although - conformance is only weakly checked, so usage errors are not always - caught). If FOOTERS is defined, then each chunk carries around a tag - indicating its originating mspace, and frees are directed to their - originating spaces. - - ------------------------- Compile-time options --------------------------- - -Be careful in setting #define values for numerical constants of type -size_t. On some systems, literal values are not automatically extended -to size_t precision unless they are explicitly casted. You can also -use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. - -WIN32 default: defined if _WIN32 defined - Defining WIN32 sets up defaults for MS environment and compilers. - Otherwise defaults are for unix. Beware that there seem to be some - cases where this malloc might not be a pure drop-in replacement for - Win32 malloc: Random-looking failures from Win32 GDI API's (eg; - SetDIBits()) may be due to bugs in some video driver implementations - when pixel buffers are malloc()ed, and the region spans more than - one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) - default granularity, pixel buffers may straddle virtual allocation - regions more often than when using the Microsoft allocator. You can - avoid this by using VirtualAlloc() and VirtualFree() for all pixel - buffers rather than using malloc(). If this is not possible, - recompile this malloc with a larger DEFAULT_GRANULARITY. - -MALLOC_ALIGNMENT default: (size_t)8 - Controls the minimum alignment for malloc'ed chunks. It must be a - power of two and at least 8, even on machines for which smaller - alignments would suffice. It may be defined as larger than this - though. Note however that code and data structures are optimized for - the case of 8-byte alignment. - -MSPACES default: 0 (false) - If true, compile in support for independent allocation spaces. - This is only supported if HAVE_MMAP is true. - -ONLY_MSPACES default: 0 (false) - If true, only compile in mspace versions, not regular versions. - -USE_LOCKS default: 0 (false) - Causes each call to each public routine to be surrounded with - pthread or WIN32 mutex lock/unlock. (If set true, this can be - overridden on a per-mspace basis for mspace versions.) If set to a - non-zero value other than 1, locks are used, but their - implementation is left out, so lock functions must be supplied manually. - -USE_SPIN_LOCKS default: 1 iff USE_LOCKS and on x86 using gcc or MSC - If true, uses custom spin locks for locking. This is currently - supported only for x86 platforms using gcc or recent MS compilers. - Otherwise, posix locks or win32 critical sections are used. - -FOOTERS default: 0 - If true, provide extra checking and dispatching by placing - information in the footers of allocated chunks. This adds - space and time overhead. - -INSECURE default: 0 - If true, omit checks for usage errors and heap space overwrites. - -USE_DL_PREFIX default: NOT defined - Causes compiler to prefix all public routines with the string 'dl'. - This can be useful when you only want to use this malloc in one part - of a program, using your regular system malloc elsewhere. - -ABORT default: defined as abort() - Defines how to abort on failed checks. On most systems, a failed - check cannot die with an "assert" or even print an informative - message, because the underlying print routines in turn call malloc, - which will fail again. Generally, the best policy is to simply call - abort(). It's not very useful to do more than this because many - errors due to overwriting will show up as address faults (null, odd - addresses etc) rather than malloc-triggered checks, so will also - abort. Also, most compilers know that abort() does not return, so - can better optimize code conditionally calling it. - -PROCEED_ON_ERROR default: defined as 0 (false) - Controls whether detected bad addresses cause them to bypassed - rather than aborting. If set, detected bad arguments to free and - realloc are ignored. And all bookkeeping information is zeroed out - upon a detected overwrite of freed heap space, thus losing the - ability to ever return it from malloc again, but enabling the - application to proceed. If PROCEED_ON_ERROR is defined, the - static variable malloc_corruption_error_count is compiled in - and can be examined to see if errors have occurred. This option - generates slower code than the default abort policy. - -DEBUG default: NOT defined - The DEBUG setting is mainly intended for people trying to modify - this code or diagnose problems when porting to new platforms. - However, it may also be able to better isolate user errors than just - using runtime checks. The assertions in the check routines spell - out in more detail the assumptions and invariants underlying the - algorithms. The checking is fairly extensive, and will slow down - execution noticeably. Calling malloc_stats or mallinfo with DEBUG - set will attempt to check every non-mmapped allocated and free chunk - in the course of computing the summaries. - -ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) - Debugging assertion failures can be nearly impossible if your - version of the assert macro causes malloc to be called, which will - lead to a cascade of further failures, blowing the runtime stack. - ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), - which will usually make debugging easier. - -MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 - The action to take before "return 0" when malloc fails to be able to - return memory because there is none available. - -HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES - True if this system supports sbrk or an emulation of it. - -MORECORE default: sbrk - The name of the sbrk-style system routine to call to obtain more - memory. See below for guidance on writing custom MORECORE - functions. The type of the argument to sbrk/MORECORE varies across - systems. It cannot be size_t, because it supports negative - arguments, so it is normally the signed type of the same width as - size_t (sometimes declared as "intptr_t"). It doesn't much matter - though. Internally, we only call it with arguments less than half - the max value of a size_t, which should work across all reasonable - possibilities, although sometimes generating compiler warnings. - -MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE - If true, take advantage of fact that consecutive calls to MORECORE - with positive arguments always return contiguous increasing - addresses. This is true of unix sbrk. It does not hurt too much to - set it true anyway, since malloc copes with non-contiguities. - Setting it false when definitely non-contiguous saves time - and possibly wasted space it would take to discover this though. - -MORECORE_CANNOT_TRIM default: NOT defined - True if MORECORE cannot release space back to the system when given - negative arguments. This is generally necessary only if you are - using a hand-crafted MORECORE function that cannot handle negative - arguments. - -NO_SEGMENT_TRAVERSAL default: 0 - If non-zero, suppresses traversals of memory segments - returned by either MORECORE or CALL_MMAP. This disables - merging of segments that are contiguous, and selectively - releasing them to the OS if unused, but bounds execution times. - -HAVE_MMAP default: 1 (true) - True if this system supports mmap or an emulation of it. If so, and - HAVE_MORECORE is not true, MMAP is used for all system - allocation. If set and HAVE_MORECORE is true as well, MMAP is - primarily used to directly allocate very large blocks. It is also - used as a backup strategy in cases where MORECORE fails to provide - space from system. Note: A single call to MUNMAP is assumed to be - able to unmap memory that may have be allocated using multiple calls - to MMAP, so long as they are adjacent. - -HAVE_MREMAP default: 1 on linux, else 0 - If true realloc() uses mremap() to re-allocate large blocks and - extend or shrink allocation spaces. - -MMAP_CLEARS default: 1 except on WINCE. - True if mmap clears memory so calloc doesn't need to. This is true - for standard unix mmap using /dev/zero and on WIN32 except for WINCE. - -USE_BUILTIN_FFS default: 0 (i.e., not used) - Causes malloc to use the builtin ffs() function to compute indices. - Some compilers may recognize and intrinsify ffs to be faster than the - supplied C version. Also, the case of x86 using gcc is special-cased - to an asm instruction, so is already as fast as it can be, and so - this setting has no effect. Similarly for Win32 under recent MS compilers. - (On most x86s, the asm version is only slightly faster than the C version.) - -malloc_getpagesize default: derive from system includes, or 4096. - The system page size. To the extent possible, this malloc manages - memory from the system in page-size units. This may be (and - usually is) a function rather than a constant. This is ignored - if WIN32, where page size is determined using getSystemInfo during - initialization. - -USE_DEV_RANDOM default: 0 (i.e., not used) - Causes malloc to use /dev/random to initialize secure magic seed for - stamping footers. Otherwise, the current time is used. - -NO_MALLINFO default: 0 - If defined, don't compile "mallinfo". This can be a simple way - of dealing with mismatches between system declarations and - those in this file. - -MALLINFO_FIELD_TYPE default: size_t - The type of the fields in the mallinfo struct. This was originally - defined as "int" in SVID etc, but is more usefully defined as - size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set - -REALLOC_ZERO_BYTES_FREES default: not defined - This should be set if a call to realloc with zero bytes should - be the same as a call to free. Some people think it should. Otherwise, - since this malloc returns a unique pointer for malloc(0), so does - realloc(p, 0). - -LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H -LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H -LACKS_STDLIB_H default: NOT defined unless on WIN32 - Define these if your system does not have these header files. - You might need to manually insert some of the declarations they provide. - -DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, - system_info.dwAllocationGranularity in WIN32, - otherwise 64K. - Also settable using mallopt(M_GRANULARITY, x) - The unit for allocating and deallocating memory from the system. On - most systems with contiguous MORECORE, there is no reason to - make this more than a page. However, systems with MMAP tend to - either require or encourage larger granularities. You can increase - this value to prevent system allocation functions to be called so - often, especially if they are slow. The value must be at least one - page and must be a power of two. Setting to 0 causes initialization - to either page size or win32 region size. (Note: In previous - versions of malloc, the equivalent of this option was called - "TOP_PAD") - -DEFAULT_TRIM_THRESHOLD default: 2MB - Also settable using mallopt(M_TRIM_THRESHOLD, x) - The maximum amount of unused top-most memory to keep before - releasing via malloc_trim in free(). Automatic trimming is mainly - useful in long-lived programs using contiguous MORECORE. Because - trimming via sbrk can be slow on some systems, and can sometimes be - wasteful (in cases where programs immediately afterward allocate - more large chunks) the value should be high enough so that your - overall system performance would improve by releasing this much - memory. As a rough guide, you might set to a value close to the - average size of a process (program) running on your system. - Releasing this much memory would allow such a process to run in - memory. Generally, it is worth tuning trim thresholds when a - program undergoes phases where several large chunks are allocated - and released in ways that can reuse each other's storage, perhaps - mixed with phases where there are no such chunks at all. The trim - value must be greater than page size to have any useful effect. To - disable trimming completely, you can set to MAX_SIZE_T. Note that the trick - some people use of mallocing a huge space and then freeing it at - program startup, in an attempt to reserve system memory, doesn't - have the intended effect under automatic trimming, since that memory - will immediately be returned to the system. - -DEFAULT_MMAP_THRESHOLD default: 256K - Also settable using mallopt(M_MMAP_THRESHOLD, x) - The request size threshold for using MMAP to directly service a - request. Requests of at least this size that cannot be allocated - using already-existing space will be serviced via mmap. (If enough - normal freed space already exists it is used instead.) Using mmap - segregates relatively large chunks of memory so that they can be - individually obtained and released from the host system. A request - serviced through mmap is never reused by any other request (at least - not directly; the system may just so happen to remap successive - requests to the same locations). Segregating space in this way has - the benefits that: Mmapped space can always be individually released - back to the system, which helps keep the system level memory demands - of a long-lived program low. Also, mapped memory doesn't become - `locked' between other chunks, as can happen with normally allocated - chunks, which means that even trimming via malloc_trim would not - release them. However, it has the disadvantage that the space - cannot be reclaimed, consolidated, and then used to service later - requests, as happens with normal chunks. The advantages of mmap - nearly always outweigh disadvantages for "large" chunks, but the - value of "large" may vary across systems. The default is an - empirically derived value that works well in most systems. You can - disable mmap by setting to MAX_SIZE_T. - -MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP - The number of consolidated frees between checks to release - unused segments when freeing. When using non-contiguous segments, - especially with multiple mspaces, checking only for topmost space - doesn't always suffice to trigger trimming. To compensate for this, - free() will, with a period of MAX_RELEASE_CHECK_RATE (or the - current number of segments, if greater) try to release unused - segments to the OS when freeing chunks that result in - consolidation. The best value for this parameter is a compromise - between slowing down frees with relatively costly checks that - rarely trigger versus holding on to unused memory. To effectively - disable, set to MAX_SIZE_T. This may lead to a very slight speed - improvement at the expense of carrying around more memory. -*/ - -/* Version identifier to allow people to support multiple versions */ -#ifndef DLMALLOC_VERSION -#define DLMALLOC_VERSION 20804 -#endif /* DLMALLOC_VERSION */ - -#ifndef WIN32 -#ifdef _WIN32 -#define WIN32 1 -#endif /* _WIN32 */ -#ifdef _WIN32_WCE -#define LACKS_FCNTL_H -#define WIN32 1 -#endif /* _WIN32_WCE */ -#endif /* WIN32 */ -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#define _WIN32_WINNT 0x403 -#include -#define HAVE_MMAP 1 -#define HAVE_MORECORE 0 -#define LACKS_UNISTD_H -#define LACKS_SYS_PARAM_H -#define LACKS_SYS_MMAN_H -#define LACKS_STRING_H -#define LACKS_STRINGS_H -#define LACKS_SYS_TYPES_H -#define LACKS_ERRNO_H -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION -#endif /* MALLOC_FAILURE_ACTION */ -#ifdef _WIN32_WCE /* WINCE reportedly does not clear */ -#define MMAP_CLEARS 0 -#else -#define MMAP_CLEARS 1 -#endif /* _WIN32_WCE */ -#endif /* WIN32 */ - -#if defined(DARWIN) || defined(_DARWIN) -/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ -#ifndef HAVE_MORECORE -#define HAVE_MORECORE 0 -#define HAVE_MMAP 1 -/* OSX allocators provide 16 byte alignment */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)16U) -#endif -#endif /* HAVE_MORECORE */ -#endif /* DARWIN */ - -#ifndef LACKS_SYS_TYPES_H -#include /* For size_t */ -#endif /* LACKS_SYS_TYPES_H */ - -/* The maximum possible size_t value has all bits set */ -#define MAX_SIZE_T (~(size_t)0) - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 /* define to a value */ -#else -#define ONLY_MSPACES 1 -#endif /* ONLY_MSPACES */ -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)8U) -#endif /* MALLOC_ALIGNMENT */ -#ifndef FOOTERS -#define FOOTERS 0 -#endif /* FOOTERS */ -#ifndef ABORT -#define ABORT abort() -#endif /* ABORT */ -#ifndef ABORT_ON_ASSERT_FAILURE -#define ABORT_ON_ASSERT_FAILURE 1 -#endif /* ABORT_ON_ASSERT_FAILURE */ -#ifndef PROCEED_ON_ERROR -#define PROCEED_ON_ERROR 0 -#endif /* PROCEED_ON_ERROR */ -#ifndef USE_LOCKS -#define USE_LOCKS 0 -#endif /* USE_LOCKS */ -#ifndef USE_SPIN_LOCKS -#if USE_LOCKS && (defined(__GNUC__) && ((defined(__i386__) || defined(__x86_64__)))) || (defined(_MSC_VER) && _MSC_VER>=1310) -#define USE_SPIN_LOCKS 1 -#else -#define USE_SPIN_LOCKS 0 -#endif /* USE_LOCKS && ... */ -#endif /* USE_SPIN_LOCKS */ -#ifndef INSECURE -#define INSECURE 0 -#endif /* INSECURE */ -#ifndef HAVE_MMAP -#define HAVE_MMAP 1 -#endif /* HAVE_MMAP */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif /* MMAP_CLEARS */ -#ifndef HAVE_MREMAP -#ifdef linux -#define HAVE_MREMAP 1 -#else /* linux */ -#define HAVE_MREMAP 0 -#endif /* linux */ -#endif /* HAVE_MREMAP */ -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION errno = ENOMEM; -#endif /* MALLOC_FAILURE_ACTION */ -#ifndef HAVE_MORECORE -#if ONLY_MSPACES -#define HAVE_MORECORE 0 -#else /* ONLY_MSPACES */ -#define HAVE_MORECORE 1 -#endif /* ONLY_MSPACES */ -#endif /* HAVE_MORECORE */ -#if !HAVE_MORECORE -#define MORECORE_CONTIGUOUS 0 -#else /* !HAVE_MORECORE */ -#define MORECORE_DEFAULT sbrk -#ifndef MORECORE_CONTIGUOUS -#define MORECORE_CONTIGUOUS 1 -#endif /* MORECORE_CONTIGUOUS */ -#endif /* HAVE_MORECORE */ -#ifndef DEFAULT_GRANULARITY -#if (MORECORE_CONTIGUOUS || defined(WIN32)) -#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ -#else /* MORECORE_CONTIGUOUS */ -#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#endif /* MORECORE_CONTIGUOUS */ -#endif /* DEFAULT_GRANULARITY */ -#ifndef DEFAULT_TRIM_THRESHOLD -#ifndef MORECORE_CANNOT_TRIM -#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) -#else /* MORECORE_CANNOT_TRIM */ -#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#endif /* MORECORE_CANNOT_TRIM */ -#endif /* DEFAULT_TRIM_THRESHOLD */ -#ifndef DEFAULT_MMAP_THRESHOLD -#if HAVE_MMAP -#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#else /* HAVE_MMAP */ -#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* DEFAULT_MMAP_THRESHOLD */ -#ifndef MAX_RELEASE_CHECK_RATE -#if HAVE_MMAP -#define MAX_RELEASE_CHECK_RATE 4095 -#else -#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* MAX_RELEASE_CHECK_RATE */ -#ifndef USE_BUILTIN_FFS -#define USE_BUILTIN_FFS 0 -#endif /* USE_BUILTIN_FFS */ -#ifndef USE_DEV_RANDOM -#define USE_DEV_RANDOM 0 -#endif /* USE_DEV_RANDOM */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -#ifndef NO_SEGMENT_TRAVERSAL -#define NO_SEGMENT_TRAVERSAL 0 -#endif /* NO_SEGMENT_TRAVERSAL */ - -/* - mallopt tuning options. SVID/XPG defines four standard parameter - numbers for mallopt, normally defined in malloc.h. None of these - are used in this malloc, so setting them has no effect. But this - malloc does support the following options. -*/ - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - -/* ------------------------ Mallinfo declarations ------------------------ */ - -#if !NO_MALLINFO -/* - This version of malloc supports the standard SVID/XPG mallinfo - routine that returns a struct containing usage properties and - statistics. It should work on any system that has a - /usr/include/malloc.h defining struct mallinfo. The main - declaration needed is the mallinfo struct that is returned (by-copy) - by mallinfo(). The malloinfo struct contains a bunch of fields that - are not even meaningful in this version of malloc. These fields are - are instead filled by mallinfo() with other numbers that might be of - interest. - - HAVE_USR_INCLUDE_MALLOC_H should be set if you have a - /usr/include/malloc.h file that includes a declaration of struct - mallinfo. If so, it is included; else a compliant version is - declared below. These must be precisely the same for mallinfo() to - work. The original SVID version of this struct, defined on most - systems with mallinfo, declares all fields as ints. But some others - define as unsigned long. If your system defines the fields using a - type of different width than listed here, you MUST #include your - system version and #define HAVE_USR_INCLUDE_MALLOC_H. -*/ - -/* #define HAVE_USR_INCLUDE_MALLOC_H */ - -#ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" -#else /* HAVE_USR_INCLUDE_MALLOC_H */ -#ifndef STRUCT_MALLINFO_DECLARED -#define STRUCT_MALLINFO_DECLARED 1 -struct mallinfo { - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; -#endif /* STRUCT_MALLINFO_DECLARED */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* NO_MALLINFO */ - -/* - Try to persuade compilers to inline. The most critical functions for - inlining are defined as macros, so these aren't used for them. -*/ - -#ifndef FORCEINLINE - #if defined(__GNUC__) -#define FORCEINLINE __inline __attribute__ ((always_inline)) - #elif defined(_MSC_VER) - #define FORCEINLINE __forceinline - #endif -#endif -#ifndef NOINLINE - #if defined(__GNUC__) - #define NOINLINE __attribute__ ((noinline)) - #elif defined(_MSC_VER) - #define NOINLINE __declspec(noinline) - #else - #define NOINLINE - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#ifndef FORCEINLINE - #define FORCEINLINE inline -#endif -#endif /* __cplusplus */ -#ifndef FORCEINLINE - #define FORCEINLINE -#endif - -#if !ONLY_MSPACES - -/* ------------------- Declarations of public routines ------------------- */ - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign memalign -#define dlrealloc realloc -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlmalloc_max_footprint malloc_max_footprint -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ - - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -void* dlmalloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cause the current program to abort. -*/ -void dlfree(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* dlcalloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ - -void* dlrealloc(void*, size_t); - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* dlmemalign(size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* dlvalloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. To workaround the fact that mallopt is specified to use int, - not size_t parameters, the value -1 is specially treated as the - maximum unsigned size_t value. - - SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt. See below for details. Briefly, supported - parameters are as follows (listed defaults are for "typical" - configurations). - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -int dlmallopt(int, int); - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -size_t dlmalloc_footprint(void); - -/* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ -size_t dlmalloc_max_footprint(void); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ -struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -void** dlindependent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -void** dlindependent_comalloc(size_t, size_t*, void**); - - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* dlpvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -int dlmalloc_trim(size_t); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ -void dlmalloc_stats(void); - -#endif /* ONLY_MSPACES */ - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t dlmalloc_usable_size(void*); - - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -mspace create_mspace(size_t capacity, int locked); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_mmap_large_chunks controls whether requests for large chunks - are allocated in their own mmapped regions, separate from others in - this mspace. By default this is enabled, which reduces - fragmentation. However, such chunks are not necessarily released to - the system upon destroy_mspace. Disabling by setting to false may - increase fragmentation, but avoids leakage when relying on - destroy_mspace to release all memory allocated using this space. -*/ -int mspace_mmap_large_chunks(mspace msp, int enable); - - -/* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ -void* mspace_malloc(mspace msp, size_t bytes); - -/* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ -void mspace_free(mspace msp, void* mem); - -/* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ -void* mspace_realloc(mspace msp, void* mem, size_t newsize); - -/* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - -/* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); - -/* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); - -/* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); - -/* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ -size_t mspace_footprint(mspace msp); - -/* - mspace_max_footprint() returns the peak number of bytes obtained from the - system for this space. -*/ -size_t mspace_max_footprint(mspace msp); - - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - malloc_usable_size(void* p) behaves the same as malloc_usable_size; -*/ - size_t mspace_usable_size(void* mem); - -/* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ -void mspace_malloc_stats(mspace msp); - -/* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ -int mspace_trim(mspace msp, size_t pad); - -/* - An alias for mallopt. -*/ -int mspace_mallopt(int, int); - -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif /* __cplusplus */ - -/* - ======================================================================== - To make a fully customizable malloc.h header file, cut everything - above this line, put into file malloc.h, edit to suit, and #include it - on the next line, as well as in programs that use this malloc. - ======================================================================== -*/ - -/* #include "malloc.h" */ - -/*------------------------------ internal #includes ---------------------- */ - -#ifdef WIN32 -#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ -#endif /* WIN32 */ - -#include /* for printing in malloc_stats */ - -#ifndef LACKS_ERRNO_H -#include /* for MALLOC_FAILURE_ACTION */ -#endif /* LACKS_ERRNO_H */ -#if FOOTERS -#include /* for magic initialization */ -#endif /* FOOTERS */ -#ifndef LACKS_STDLIB_H -#include /* for abort() */ -#endif /* LACKS_STDLIB_H */ -#ifdef DEBUG -#if ABORT_ON_ASSERT_FAILURE -#define assert(x) if(!(x)) ABORT -#else /* ABORT_ON_ASSERT_FAILURE */ -#include -#endif /* ABORT_ON_ASSERT_FAILURE */ -#else /* DEBUG */ -#ifndef assert -#define assert(x) -#endif -#define DEBUG 0 -#endif /* DEBUG */ -#ifndef LACKS_STRING_H -#include /* for memset etc */ -#endif /* LACKS_STRING_H */ -#if USE_BUILTIN_FFS -#ifndef LACKS_STRINGS_H -#include /* for ffs */ -#endif /* LACKS_STRINGS_H */ -#endif /* USE_BUILTIN_FFS */ -#if HAVE_MMAP -#ifndef LACKS_SYS_MMAN_H -#include /* for mmap */ -#endif /* LACKS_SYS_MMAN_H */ -#ifndef LACKS_FCNTL_H -#include -#endif /* LACKS_FCNTL_H */ -#endif /* HAVE_MMAP */ -#ifndef LACKS_UNISTD_H -#include /* for sbrk, sysconf */ -#else /* LACKS_UNISTD_H */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -extern void* sbrk(ptrdiff_t); -#endif /* FreeBSD etc */ -#endif /* LACKS_UNISTD_H */ - -/* Declarations for locking */ -#if USE_LOCKS -#ifndef WIN32 -#include -#if defined (__SVR4) && defined (__sun) /* solaris */ -#include -#endif /* solaris */ -#else -#ifndef _M_AMD64 -/* These are already defined on AMD64 builds */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp); -LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _M_AMD64 */ -#pragma intrinsic (_InterlockedCompareExchange) -#pragma intrinsic (_InterlockedExchange) -#define interlockedcompareexchange _InterlockedCompareExchange -#define interlockedexchange _InterlockedExchange -#endif /* Win32 */ -#endif /* USE_LOCKS */ - -/* Declarations for bit scanning on win32 */ -#if defined(_MSC_VER) && _MSC_VER>=1300 -#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -unsigned char _BitScanForward(unsigned long *index, unsigned long mask); -unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define BitScanForward _BitScanForward -#define BitScanReverse _BitScanReverse -#pragma intrinsic(_BitScanForward) -#pragma intrinsic(_BitScanReverse) -#endif /* BitScanForward */ -#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ - -#ifndef WIN32 -#ifndef malloc_getpagesize -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -# ifndef _SC_PAGE_SIZE -# define _SC_PAGE_SIZE _SC_PAGESIZE -# endif -# endif -# ifdef _SC_PAGE_SIZE -# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -# else -# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) - extern size_t getpagesize(); -# define malloc_getpagesize getpagesize() -# else -# ifdef WIN32 /* use supplied emulation of getpagesize */ -# define malloc_getpagesize getpagesize() -# else -# ifndef LACKS_SYS_PARAM_H -# include -# endif -# ifdef EXEC_PAGESIZE -# define malloc_getpagesize EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define malloc_getpagesize NBPG -# else -# define malloc_getpagesize (NBPG * CLSIZE) -# endif -# else -# ifdef NBPC -# define malloc_getpagesize NBPC -# else -# ifdef PAGESIZE -# define malloc_getpagesize PAGESIZE -# else /* just guess */ -# define malloc_getpagesize ((size_t)4096U) -# endif -# endif -# endif -# endif -# endif -# endif -# endif -#endif -#endif - - - -/* ------------------- size_t and alignment properties -------------------- */ - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some platforms */ -#define SIZE_T_ZERO ((size_t)0) -#define SIZE_T_ONE ((size_t)1) -#define SIZE_T_TWO ((size_t)2) -#define SIZE_T_FOUR ((size_t)4) -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) -#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* True if address a has acceptable alignment */ -#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A)\ - ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ - ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) - -/* -------------------------- MMAP preliminaries ------------------------- */ - -/* - If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and - checks to fail so compiler optimizer can delete code rather than - using so many "#if"s. -*/ - - -/* MORECORE and MMAP must return MFAIL on failure */ -#define MFAIL ((void*)(MAX_SIZE_T)) -#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ - -#if HAVE_MMAP - -#ifndef WIN32 -#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) -#define MMAP_PROT (PROT_READ|PROT_WRITE) -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANON */ -#ifdef MAP_ANONYMOUS -#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) -#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) -#else /* MAP_ANONYMOUS */ -/* - Nearly all versions of mmap support MAP_ANONYMOUS, so the following - is unlikely to be needed, but is supplied just in case. -*/ -#define MMAP_FLAGS (MAP_PRIVATE) -static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ -#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ - (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) -#endif /* MAP_ANONYMOUS */ - -#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) - -#else /* WIN32 */ - -/* Win32 MMAP via VirtualAlloc */ -static FORCEINLINE void* win32mmap(size_t size) { - void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - return (ptr != 0)? ptr: MFAIL; -} - -/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static FORCEINLINE void* win32direct_mmap(size_t size) { - void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, - PAGE_READWRITE); - return (ptr != 0)? ptr: MFAIL; -} - -/* This function supports releasing coalesed segments */ -static FORCEINLINE int win32munmap(void* ptr, size_t size) { - MEMORY_BASIC_INFORMATION minfo; - char* cptr = (char*)ptr; - while (size) { - if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) - return -1; - if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || - minfo.State != MEM_COMMIT || minfo.RegionSize > size) - return -1; - if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) - return -1; - cptr += minfo.RegionSize; - size -= minfo.RegionSize; - } - return 0; -} - -#define MMAP_DEFAULT(s) win32mmap(s) -#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) -#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) -#endif /* WIN32 */ -#endif /* HAVE_MMAP */ - -#if HAVE_MREMAP -#ifndef WIN32 -#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) -#endif /* WIN32 */ -#endif /* HAVE_MREMAP */ - - -/** - * Define CALL_MORECORE - */ -#if HAVE_MORECORE - #ifdef MORECORE - #define CALL_MORECORE(S) MORECORE(S) - #else /* MORECORE */ - #define CALL_MORECORE(S) MORECORE_DEFAULT(S) - #endif /* MORECORE */ -#else /* HAVE_MORECORE */ - #define CALL_MORECORE(S) MFAIL -#endif /* HAVE_MORECORE */ - -/** - * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP - */ -#if HAVE_MMAP - #define IS_MMAPPED_BIT (SIZE_T_ONE) - #define USE_MMAP_BIT (SIZE_T_ONE) - - #ifdef MMAP - #define CALL_MMAP(s) MMAP(s) - #else /* MMAP */ - #define CALL_MMAP(s) MMAP_DEFAULT(s) - #endif /* MMAP */ - #ifdef MUNMAP - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) - #else /* MUNMAP */ - #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) - #endif /* MUNMAP */ - #ifdef DIRECT_MMAP - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #else /* DIRECT_MMAP */ - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) - #endif /* DIRECT_MMAP */ -#else /* HAVE_MMAP */ - #define IS_MMAPPED_BIT (SIZE_T_ZERO) - #define USE_MMAP_BIT (SIZE_T_ZERO) - - #define MMAP(s) MFAIL - #define MUNMAP(a, s) (-1) - #define DIRECT_MMAP(s) MFAIL - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #define CALL_MMAP(s) MMAP(s) - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) -#endif /* HAVE_MMAP */ - -/** - * Define CALL_MREMAP - */ -#if HAVE_MMAP && HAVE_MREMAP - #ifdef MREMAP - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) - #else /* MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) - #endif /* MREMAP */ -#else /* HAVE_MMAP && HAVE_MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL -#endif /* HAVE_MMAP && HAVE_MREMAP */ - -/* mstate bit set if continguous morecore disabled or failed */ -#define USE_NONCONTIGUOUS_BIT (4U) - -/* segment bit set in create_mspace_with_base */ -#define EXTERN_BIT (8U) - - -/* --------------------------- Lock preliminaries ------------------------ */ - -/* - When locks are defined, there is one global lock, plus - one per-mspace lock. - - The global lock_ensures that mparams.magic and other unique - mparams values are initialized only once. It also protects - sequences of calls to MORECORE. In many cases sys_alloc requires - two calls, that should not be interleaved with calls by other - threads. This does not protect against direct calls to MORECORE - by other threads not using this lock, so there is still code to - cope the best we can on interference. - - Per-mspace locks surround calls to malloc, free, etc. To enable use - in layered extensions, per-mspace locks are reentrant. - - Because lock-protected regions generally have bounded times, it is - OK to use the supplied simple spinlocks in the custom versions for - x86. - - If USE_LOCKS is > 1, the definitions of lock routines here are - bypassed, in which case you will need to define at least - INITIAL_LOCK, ACQUIRE_LOCK, RELEASE_LOCK and possibly TRY_LOCK - (which is not used in this malloc, but commonly needed in - extensions.) -*/ - -#if USE_LOCKS == 1 - -#if USE_SPIN_LOCKS -#ifndef WIN32 - -/* Custom pthread-style spin locks on x86 and x64 for gcc */ -struct pthread_mlock_t { - volatile unsigned int l; - volatile unsigned int c; - volatile pthread_t threadid; -}; -#define MLOCK_T struct pthread_mlock_t -#define CURRENT_THREAD pthread_self() -#define INITIAL_LOCK(sl) (memset(sl, 0, sizeof(MLOCK_T)), 0) -#define ACQUIRE_LOCK(sl) pthread_acquire_lock(sl) -#define RELEASE_LOCK(sl) pthread_release_lock(sl) -#define TRY_LOCK(sl) pthread_try_lock(sl) -#define SPINS_PER_YIELD 63 - -static MLOCK_T malloc_global_mutex = { 0, 0, 0}; - -static FORCEINLINE int pthread_acquire_lock (MLOCK_T *sl) { - int spins = 0; - volatile unsigned int* lp = &sl->l; - for (;;) { - if (*lp != 0) { - if (sl->threadid == CURRENT_THREAD) { - ++sl->c; - return 0; - } - } - else { - /* place args to cmpxchgl in locals to evade oddities in some gccs */ - int cmp = 0; - int val = 1; - int ret; - __asm__ __volatile__ ("lock; cmpxchgl %1, %2" - : "=a" (ret) - : "r" (val), "m" (*(lp)), "0"(cmp) - : "memory", "cc"); - if (!ret) { - assert(!sl->threadid); - sl->c = 1; - sl->threadid = CURRENT_THREAD; - return 0; - } - if ((++spins & SPINS_PER_YIELD) == 0) { -#if defined (__SVR4) && defined (__sun) /* solaris */ - thr_yield(); -#else -#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) - sched_yield(); -#else /* no-op yield on unknown systems */ - ; -#endif /* __linux__ || __FreeBSD__ || __APPLE__ */ -#endif /* solaris */ - } - } - } -} - -static FORCEINLINE void pthread_release_lock (MLOCK_T *sl) { - assert(sl->l != 0); - assert(sl->threadid == CURRENT_THREAD); - if (--sl->c == 0) { - sl->threadid = 0; - volatile unsigned int* lp = &sl->l; - int prev = 0; - int ret; - __asm__ __volatile__ ("lock; xchgl %0, %1" - : "=r" (ret) - : "m" (*(lp)), "0"(prev) - : "memory"); - } -} - -static FORCEINLINE int pthread_try_lock (MLOCK_T *sl) { - volatile unsigned int* lp = &sl->l; - if (*lp != 0) { - if (sl->threadid == CURRENT_THREAD) { - ++sl->c; - return 1; - } - } - else { - int cmp = 0; - int val = 1; - int ret; - __asm__ __volatile__ ("lock; cmpxchgl %1, %2" - : "=a" (ret) - : "r" (val), "m" (*(lp)), "0"(cmp) - : "memory", "cc"); - if (!ret) { - assert(!sl->threadid); - sl->c = 1; - sl->threadid = CURRENT_THREAD; - return 1; - } - } - return 0; -} - - -#else /* WIN32 */ -/* Custom win32-style spin locks on x86 and x64 for MSC */ -struct win32_mlock_t -{ - volatile long l; - volatile unsigned int c; - volatile long threadid; -}; - -#define MLOCK_T struct win32_mlock_t -#define CURRENT_THREAD win32_getcurrentthreadid() -#define INITIAL_LOCK(sl) (memset(sl, 0, sizeof(MLOCK_T)), 0) -#define ACQUIRE_LOCK(sl) win32_acquire_lock(sl) -#define RELEASE_LOCK(sl) win32_release_lock(sl) -#define TRY_LOCK(sl) win32_try_lock(sl) -#define SPINS_PER_YIELD 63 - -static MLOCK_T malloc_global_mutex = { 0, 0, 0}; - -static FORCEINLINE long win32_getcurrentthreadid() { -#ifdef _MSC_VER -#if defined(_M_IX86) - long *threadstruct=(long *)__readfsdword(0x18); - long threadid=threadstruct[0x24/sizeof(long)]; - return threadid; -#elif defined(_M_X64) - /* todo */ - return GetCurrentThreadId(); -#else - return GetCurrentThreadId(); -#endif -#else - return GetCurrentThreadId(); -#endif -} - -static FORCEINLINE int win32_acquire_lock (MLOCK_T *sl) { - int spins = 0; - for (;;) { - if (sl->l != 0) { - if (sl->threadid == CURRENT_THREAD) { - ++sl->c; - return 0; - } - } - else { - if (!interlockedexchange(&sl->l, 1)) { - assert(!sl->threadid); - sl->c=CURRENT_THREAD; - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 0; - } - } - if ((++spins & SPINS_PER_YIELD) == 0) - SleepEx(0, FALSE); - } -} - -static FORCEINLINE void win32_release_lock (MLOCK_T *sl) { - assert(sl->threadid == CURRENT_THREAD); - assert(sl->l != 0); - if (--sl->c == 0) { - sl->threadid = 0; - interlockedexchange (&sl->l, 0); - } -} - -static FORCEINLINE int win32_try_lock (MLOCK_T *sl) { - if(sl->l != 0) { - if (sl->threadid == CURRENT_THREAD) { - ++sl->c; - return 1; - } - } - else { - if (!interlockedexchange(&sl->l, 1)){ - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 1; - } - } - return 0; -} - -#endif /* WIN32 */ -#else /* USE_SPIN_LOCKS */ - -#ifndef WIN32 -/* pthreads-based locks */ - -#define MLOCK_T pthread_mutex_t -#define CURRENT_THREAD pthread_self() -#define INITIAL_LOCK(sl) pthread_init_lock(sl) -#define ACQUIRE_LOCK(sl) pthread_mutex_lock(sl) -#define RELEASE_LOCK(sl) pthread_mutex_unlock(sl) -#define TRY_LOCK(sl) (!pthread_mutex_trylock(sl)) - -static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* Cope with old-style linux recursive lock initialization by adding */ -/* skipped internal declaration from pthread.h */ -#ifdef linux -#ifndef PTHREAD_MUTEX_RECURSIVE -extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, - int __kind)); -#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP -#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) -#endif -#endif - -static int pthread_init_lock (MLOCK_T *sl) { - pthread_mutexattr_t attr; - if (pthread_mutexattr_init(&attr)) return 1; - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; - if (pthread_mutex_init(sl, &attr)) return 1; - if (pthread_mutexattr_destroy(&attr)) return 1; - return 0; -} - -#else /* WIN32 */ -/* Win32 critical sections */ -#define MLOCK_T CRITICAL_SECTION -#define CURRENT_THREAD GetCurrentThreadId() -#define INITIAL_LOCK(s) (!InitializeCriticalSectionAndSpinCount((s), 0x80000000|4000)) -#define ACQUIRE_LOCK(s) (EnterCriticalSection(s), 0) -#define RELEASE_LOCK(s) LeaveCriticalSection(s) -#define TRY_LOCK(s) TryEnterCriticalSection(s) -#define NEED_GLOBAL_LOCK_INIT - -static MLOCK_T malloc_global_mutex; -static volatile long malloc_global_mutex_status; - -/* Use spin loop to initialize global lock */ -static void init_malloc_global_mutex() { - for (;;) { - long stat = malloc_global_mutex_status; - if (stat > 0) - return; - /* transition to < 0 while initializing, then to > 0) */ - if (stat == 0 && - interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) { - InitializeCriticalSection(&malloc_global_mutex); - interlockedexchange(&malloc_global_mutex_status,1); - return; - } - SleepEx(0, FALSE); - } -} - -#endif /* WIN32 */ -#endif /* USE_SPIN_LOCKS */ -#endif /* USE_LOCKS == 1 */ - -/* ----------------------- User-defined locks ------------------------ */ - -#if USE_LOCKS > 1 -/* Define your own lock implementation here */ -/* #define INITIAL_LOCK(sl) ... */ -/* #define ACQUIRE_LOCK(sl) ... */ -/* #define RELEASE_LOCK(sl) ... */ -/* #define TRY_LOCK(sl) ... */ -/* static MLOCK_T malloc_global_mutex = ... */ -#endif /* USE_LOCKS > 1 */ - -/* ----------------------- Lock-based state ------------------------ */ - -#if USE_LOCKS -#define USE_LOCK_BIT (2U) -#else /* USE_LOCKS */ -#define USE_LOCK_BIT (0U) -#define INITIAL_LOCK(l) -#endif /* USE_LOCKS */ - -#if USE_LOCKS -#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); -#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); -#else /* USE_LOCKS */ -#define ACQUIRE_MALLOC_GLOBAL_LOCK() -#define RELEASE_MALLOC_GLOBAL_LOCK() -#endif /* USE_LOCKS */ - - -/* ----------------------- Chunk representations ------------------------ */ - -/* - (The following includes lightly edited explanations by Colin Plumb.) - - The malloc_chunk declaration below is misleading (but accurate and - necessary). It declares a "view" into memory allowing access to - necessary fields at known offsets from a given base. - - Chunks of memory are maintained using a `boundary tag' method as - originally described by Knuth. (See the paper by Paul Wilson - ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such - techniques.) Sizes of free chunks are stored both in the front of - each chunk and at the end. This makes consolidating fragmented - chunks into bigger chunks fast. The head fields also hold bits - representing whether chunks are free or in use. - - Here are some pictures to make it clearer. They are "exploded" to - show that the state of a chunk can be thought of as extending from - the high 31 bits of the head field of its header through the - prev_foot and PINUSE_BIT bit of the following chunk header. - - A chunk that's in use looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk (if P = 0) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 1| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +- -+ - | | - +- -+ - | : - +- size - sizeof(size_t) available payload bytes -+ - : | - chunk-> +- -+ - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| - | Size of next chunk (may or may not be in use) | +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - And if it's free, it looks like this: - - chunk-> +- -+ - | User payload (must be in use, or we would have merged!) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 0| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Next pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Prev pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- size - sizeof(struct chunk) unused bytes -+ - : | - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| - | Size of next chunk (must be in use, or we would have merged)| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- User payload -+ - : | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0| - +-+ - Note that since we always merge adjacent free chunks, the chunks - adjacent to a free chunk must be in use. - - Given a pointer to a chunk (which can be derived trivially from the - payload pointer) we can, in O(1) time, find out whether the adjacent - chunks are free, and if so, unlink them from the lists that they - are on and merge them with the current chunk. - - Chunks always begin on even word boundaries, so the mem portion - (which is returned to the user) is also on an even word boundary, and - thus at least double-word aligned. - - The P (PINUSE_BIT) bit, stored in the unused low-order bit of the - chunk size (which is always a multiple of two words), is an in-use - bit for the *previous* chunk. If that bit is *clear*, then the - word before the current chunk size contains the previous chunk - size, and can be used to find the front of the previous chunk. - The very first chunk allocated always has this bit set, preventing - access to non-existent (or non-owned) memory. If pinuse is set for - any given chunk, then you CANNOT determine the size of the - previous chunk, and might even get a memory addressing fault when - trying to do so. - - The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of - the chunk size redundantly records whether the current chunk is - inuse. This redundancy enables usage checks within free and realloc, - and reduces indirection when freeing and consolidating chunks. - - Each freshly allocated chunk must have both cinuse and pinuse set. - That is, each allocated chunk borders either a previously allocated - and still in-use chunk, or the base of its memory arena. This is - ensured by making all allocations from the the `lowest' part of any - found chunk. Further, no free chunk physically borders another one, - so each free chunk is known to be preceded and followed by either - inuse chunks or the ends of memory. - - Note that the `foot' of the current chunk is actually represented - as the prev_foot of the NEXT chunk. This makes it easier to - deal with alignments etc but can be very confusing when trying - to extend or adapt this code. - - The exceptions to all this are - - 1. The special chunk `top' is the top-most available chunk (i.e., - the one bordering the end of available memory). It is treated - specially. Top is never included in any bin, is used only if - no other chunk is available, and is released back to the - system if it is very large (see M_TRIM_THRESHOLD). In effect, - the top chunk is treated as larger (and thus less well - fitting) than any other available chunk. The top chunk - doesn't update its trailing size field since there is no next - contiguous chunk that would have to index off it. However, - space is still allocated for it (TOP_FOOT_SIZE) to enable - separation or merging when space is extended. - - 3. Chunks allocated via mmap, which have the lowest-order bit - (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set - PINUSE_BIT in their head fields. Because they are allocated - one-by-one, each must carry its own prev_foot field, which is - also used to hold the offset this chunk has within its mmapped - region, which is needed to preserve alignment. Each mmapped - chunk is trailed by the first two fields of a fake next-chunk - for sake of usage checks. - -*/ - -struct malloc_chunk { - size_t prev_foot; /* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk* fd; /* double links -- used only if free. */ - struct malloc_chunk* bk; -}; - -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk* mchunkptr; -typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ - -/* ------------------- Chunks sizes and alignments ----------------------- */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#if FOOTERS -#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -#else /* FOOTERS */ -#define CHUNK_OVERHEAD (SIZE_T_SIZE) -#endif /* FOOTERS */ - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE\ - ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* Bounds on request (not chunk) sizes. */ -#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) -#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* pad request, checking for minimum (but not maximum) */ -#define request2size(req) \ - (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) - - -/* ------------------ Operations on head and foot fields ----------------- */ - -/* - The head field of a chunk is or'ed with PINUSE_BIT when previous - adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in - use. If the chunk was obtained with mmap, the prev_foot field has - IS_MMAPPED_BIT set, otherwise holding the offset of the base of the - mmapped region to the base of the chunk. - - FLAG4_BIT is not used by this malloc, but might be useful in extensions. -*/ - -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define FLAG4_BIT (SIZE_T_FOUR) -#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) -#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) - -/* Head value for fenceposts */ -#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) - -/* extraction of fields from head words */ -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define chunksize(p) ((p)->head & ~(FLAG_BITS)) - -#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) -#define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT) - -/* Treat space at ptr +/- offset as a chunk */ -#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) -#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) - -/* Ptr to next or previous physical malloc_chunk. */ -#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) -#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) - -/* extract next chunk's pinuse bit */ -#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) - -/* Get/set size at footer */ -#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) -#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) - -/* Set size, pinuse bit, and foot */ -#define set_size_and_pinuse_of_free_chunk(p, s)\ - ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) - -/* Set size, pinuse bit, foot, and clear next pinuse */ -#define set_free_with_pinuse(p, s, n)\ - (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) - -#define is_mmapped(p)\ - (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p)\ - (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -/* Return true if malloced space is not necessarily cleared */ -#if MMAP_CLEARS -#define calloc_must_clear(p) (!is_mmapped(p)) -#else /* MMAP_CLEARS */ -#define calloc_must_clear(p) (1) -#endif /* MMAP_CLEARS */ - -/* ---------------------- Overlaid data structures ----------------------- */ - -/* - When chunks are not in use, they are treated as nodes of either - lists or trees. - - "Small" chunks are stored in circular doubly-linked lists, and look - like this: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space (may be 0 bytes long) . - . . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Larger chunks are kept in a form of bitwise digital trees (aka - tries) keyed on chunksizes. Because malloc_tree_chunks are only for - free chunks greater than 256 bytes, their size doesn't impose any - constraints on user chunk sizes. Each node looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to left child (child[0]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to right child (child[1]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to parent | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | bin index of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Each tree holding treenodes is a tree of unique chunk sizes. Chunks - of the same size are arranged in a circularly-linked list, with only - the oldest chunk (the next to be used, in our FIFO ordering) - actually in the tree. (Tree members are distinguished by a non-null - parent pointer.) If a chunk with the same size an an existing node - is inserted, it is linked off the existing node using pointers that - work in the same way as fd/bk pointers of small chunks. - - Each tree contains a power of 2 sized range of chunk sizes (the - smallest is 0x100 <= x < 0x180), which is is divided in half at each - tree level, with the chunks in the smaller half of the range (0x100 - <= x < 0x140 for the top nose) in the left subtree and the larger - half (0x140 <= x < 0x180) in the right subtree. This is, of course, - done by inspecting individual bits. - - Using these rules, each node's left subtree contains all smaller - sizes than its right subtree. However, the node at the root of each - subtree has no particular ordering relationship to either. (The - dividing line between the subtree sizes is based on trie relation.) - If we remove the last chunk of a given size from the interior of the - tree, we need to replace it with a leaf node. The tree ordering - rules permit a node to be replaced by any leaf below it. - - The smallest chunk in a tree (a common operation in a best-fit - allocator) can be found by walking a path to the leftmost leaf in - the tree. Unlike a usual binary tree, where we follow left child - pointers until we reach a null, here we follow the right child - pointer any time the left one is null, until we reach a leaf with - both child pointers null. The smallest chunk in the tree will be - somewhere along that path. - - The worst case number of steps to add, find, or remove a node is - bounded by the number of bits differentiating chunks within - bins. Under current bin calculations, this ranges from 6 up to 21 - (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case - is of course much better. -*/ - -struct malloc_tree_chunk { - /* The first four fields must be compatible with malloc_chunk */ - size_t prev_foot; - size_t head; - struct malloc_tree_chunk* fd; - struct malloc_tree_chunk* bk; - - struct malloc_tree_chunk* child[2]; - struct malloc_tree_chunk* parent; - bindex_t index; -}; - -typedef struct malloc_tree_chunk tchunk; -typedef struct malloc_tree_chunk* tchunkptr; -typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ - -/* A little helper macro for trees */ -#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) - -/* ----------------------------- Segments -------------------------------- */ - -/* - Each malloc space may include non-contiguous segments, held in a - list headed by an embedded malloc_segment record representing the - top-most space. Segments also include flags holding properties of - the space. Large chunks that are directly allocated by mmap are not - included in this list. They are instead independently created and - destroyed without otherwise keeping track of them. - - Segment management mainly comes into play for spaces allocated by - MMAP. Any call to MMAP might or might not return memory that is - adjacent to an existing segment. MORECORE normally contiguously - extends the current space, so this space is almost always adjacent, - which is simpler and faster to deal with. (This is why MORECORE is - used preferentially to MMAP when both are available -- see - sys_alloc.) When allocating using MMAP, we don't use any of the - hinting mechanisms (inconsistently) supported in various - implementations of unix mmap, or distinguish reserving from - committing memory. Instead, we just ask for space, and exploit - contiguity when we get it. It is probably possible to do - better than this on some systems, but no general scheme seems - to be significantly better. - - Management entails a simpler variant of the consolidation scheme - used for chunks to reduce fragmentation -- new adjacent memory is - normally prepended or appended to an existing segment. However, - there are limitations compared to chunk consolidation that mostly - reflect the fact that segment processing is relatively infrequent - (occurring only when getting memory from system) and that we - don't expect to have huge numbers of segments: - - * Segments are not indexed, so traversal requires linear scans. (It - would be possible to index these, but is not worth the extra - overhead and complexity for most programs on most platforms.) - * New segments are only appended to old ones when holding top-most - memory; if they cannot be prepended to others, they are held in - different segments. - - Except for the top-most segment of an mstate, each segment record - is kept at the tail of its segment. Segments are added by pushing - segment records onto the list headed by &mstate.seg for the - containing mstate. - - Segment flags control allocation/merge/deallocation policies: - * If EXTERN_BIT set, then we did not allocate this segment, - and so should not try to deallocate or merge with others. - (This currently holds only for the initial segment passed - into create_mspace_with_base.) - * If IS_MMAPPED_BIT set, the segment may be merged with - other surrounding mmapped segments and trimmed/de-allocated - using munmap. - * If neither bit is set, then the segment was obtained using - MORECORE so can be merged with surrounding MORECORE'd segments - and deallocated/trimmed using MORECORE with negative arguments. -*/ - -struct malloc_segment { - char* base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment* next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -#define is_mmapped_segment(S) ((S)->sflags & IS_MMAPPED_BIT) -#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) - -typedef struct malloc_segment msegment; -typedef struct malloc_segment* msegmentptr; - -/* ---------------------------- malloc_state ----------------------------- */ - -/* - A malloc_state holds all of the bookkeeping for a space. - The main fields are: - - Top - The topmost chunk of the currently active segment. Its size is - cached in topsize. The actual size of topmost space is - topsize+TOP_FOOT_SIZE, which includes space reserved for adding - fenceposts and segment records if necessary when getting more - space from the system. The size at which to autotrim top is - cached from mparams in trim_check, except that it is disabled if - an autotrim fails. - - Designated victim (dv) - This is the preferred chunk for servicing small requests that - don't have exact fits. It is normally the chunk split off most - recently to service another small request. Its size is cached in - dvsize. The link fields of this chunk are not maintained since it - is not kept in a bin. - - SmallBins - An array of bin headers for free chunks. These bins hold chunks - with sizes less than MIN_LARGE_SIZE bytes. Each bin contains - chunks of all the same size, spaced 8 bytes apart. To simplify - use in double-linked lists, each bin header acts as a malloc_chunk - pointing to the real first node, if it exists (else pointing to - itself). This avoids special-casing for headers. But to avoid - waste, we allocate only the fd/bk pointers of bins, and then use - repositioning tricks to treat these as the fields of a chunk. - - TreeBins - Treebins are pointers to the roots of trees holding a range of - sizes. There are 2 equally spaced treebins for each power of two - from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything - larger. - - Bin maps - There is one bit map for small bins ("smallmap") and one for - treebins ("treemap). Each bin sets its bit when non-empty, and - clears the bit when empty. Bit operations are then used to avoid - bin-by-bin searching -- nearly all "search" is done without ever - looking at bins that won't be selected. The bit maps - conservatively use 32 bits per map word, even if on 64bit system. - For a good description of some of the bit-based techniques used - here, see Henry S. Warren Jr's book "Hacker's Delight" (and - supplement at http://hackersdelight.org/). Many of these are - intended to reduce the branchiness of paths through malloc etc, as - well as to reduce the number of memory locations read or written. - - Segments - A list of segments headed by an embedded malloc_segment record - representing the initial space. - - Address check support - The least_addr field is the least address ever obtained from - MORECORE or MMAP. Attempted frees and reallocs of any address less - than this are trapped (unless INSECURE is defined). - - Magic tag - A cross-check field that should always hold same value as mparams.magic. - - Flags - Bits recording whether to use MMAP, locks, or contiguous MORECORE - - Statistics - Each space keeps track of current and maximum system memory - obtained via MORECORE or MMAP. - - Trim support - Fields holding the amount of unused topmost memory that should trigger - timming, and a counter to force periodic scanning to release unused - non-topmost segments. - - Locking - If USE_LOCKS is defined, the "mutex" lock is acquired and released - around every public call using this mspace. - - Extension support - A void* pointer and a size_t field that can be used to help implement - extensions to this malloc. -*/ - -/* Bin types, widths and sizes */ -#define NSMALLBINS (32U) -#define NTREEBINS (32U) -#define SMALLBIN_SHIFT (3U) -#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) -#define TREEBIN_SHIFT (8U) -#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) -#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) -#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) - -struct malloc_state { - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char* least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t release_checks; - size_t magic; - mchunkptr smallbins[(NSMALLBINS+1)*2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - flag_t mflags; -#if USE_LOCKS - MLOCK_T mutex; /* locate lock among fields that rarely change */ -#endif /* USE_LOCKS */ - msegment seg; - void* extp; /* Unused but available for extensions */ - size_t exts; -}; - -typedef struct malloc_state* mstate; - -/* ------------- Global malloc_state and malloc_params ------------------- */ - -/* - malloc_params holds global properties, including those that can be - dynamically set using mallopt. There is a single instance, mparams, - initialized in init_mparams. Note that the non-zeroness of "magic" - also serves as an initialization flag. -*/ - -struct malloc_params { - volatile size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; -}; - -static struct malloc_params mparams; - -/* Ensure mparams initialized */ -#define ensure_initialization() (mparams.magic != 0 || init_mparams()) - -#if !ONLY_MSPACES - -/* The global malloc_state used for all non-"mspace" calls */ -static struct malloc_state _gm_; -#define gm (&_gm_) -#define is_global(M) ((M) == &_gm_) - -#endif /* !ONLY_MSPACES */ - -#define is_initialized(M) ((M)->top != 0) - -/* -------------------------- system alloc setup ------------------------- */ - -/* Operations on mflags */ - -#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) -#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) -#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) - -#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) -#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) -#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) - -#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) -#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) - -#define set_lock(M,L)\ - ((M)->mflags = (L)?\ - ((M)->mflags | USE_LOCK_BIT) :\ - ((M)->mflags & ~USE_LOCK_BIT)) - -/* page-align a size */ -#define page_align(S)\ - (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) - -/* granularity-align a size */ -#define granularity_align(S)\ - (((S) + (mparams.granularity - SIZE_T_ONE))\ - & ~(mparams.granularity - SIZE_T_ONE)) - - -/* For mmap, use granularity alignment on windows, else page-align */ -#ifdef WIN32 -#define mmap_align(S) granularity_align(S) -#else -#define mmap_align(S) page_align(S) -#endif - -/* For sys_alloc, enough padding to ensure can malloc request on success */ -#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) - -#define is_page_aligned(S)\ - (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) -#define is_granularity_aligned(S)\ - (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) - -/* True if segment S holds address A */ -#define segment_holds(S, A)\ - ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) - -/* Return segment holding given address */ -static msegmentptr segment_holding(mstate m, char* addr) { - msegmentptr sp = &m->seg; - for (;;) { - if (addr >= sp->base && addr < sp->base + sp->size) - return sp; - if ((sp = sp->next) == 0) - return 0; - } -} - -/* Return true if segment contains a segment link */ -static int has_segment_link(mstate m, msegmentptr ss) { - msegmentptr sp = &m->seg; - for (;;) { - if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) - return 1; - if ((sp = sp->next) == 0) - return 0; - } -} - -#ifndef MORECORE_CANNOT_TRIM -#define should_trim(M,s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ -#define should_trim(M,s) (0) -#endif /* MORECORE_CANNOT_TRIM */ - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE\ - (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) - - -/* ------------------------------- Hooks -------------------------------- */ - -/* - PREACTION should be defined to return 0 on success, and nonzero on - failure. If you are not using locking, you can redefine these to do - anything you like. -*/ - -#if USE_LOCKS - -#define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) -#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } -#else /* USE_LOCKS */ - -#ifndef PREACTION -#define PREACTION(M) (0) -#endif /* PREACTION */ - -#ifndef POSTACTION -#define POSTACTION(M) -#endif /* POSTACTION */ - -#endif /* USE_LOCKS */ - -/* - CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. - USAGE_ERROR_ACTION is triggered on detected bad frees and - reallocs. The argument p is an address that might have triggered the - fault. It is ignored by the two predefined actions, but might be - useful in custom actions that try to help diagnose errors. -*/ - -#if PROCEED_ON_ERROR - -/* A count of the number of corruption errors causing resets */ -int malloc_corruption_error_count; - -/* default corruption action */ -static void reset_on_error(mstate m); - -#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) -#define USAGE_ERROR_ACTION(m, p) - -#else /* PROCEED_ON_ERROR */ - -#ifndef CORRUPTION_ERROR_ACTION -#define CORRUPTION_ERROR_ACTION(m) ABORT -#endif /* CORRUPTION_ERROR_ACTION */ - -#ifndef USAGE_ERROR_ACTION -#define USAGE_ERROR_ACTION(m,p) ABORT -#endif /* USAGE_ERROR_ACTION */ - -#endif /* PROCEED_ON_ERROR */ - -/* -------------------------- Debugging setup ---------------------------- */ - -#if ! DEBUG - -#define check_free_chunk(M,P) -#define check_inuse_chunk(M,P) -#define check_malloced_chunk(M,P,N) -#define check_mmapped_chunk(M,P) -#define check_malloc_state(M) -#define check_top_chunk(M,P) - -#else /* DEBUG */ -#define check_free_chunk(M,P) do_check_free_chunk(M,P) -#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) -#define check_top_chunk(M,P) do_check_top_chunk(M,P) -#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) -#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) -#define check_malloc_state(M) do_check_malloc_state(M) - -static void do_check_any_chunk(mstate m, mchunkptr p); -static void do_check_top_chunk(mstate m, mchunkptr p); -static void do_check_mmapped_chunk(mstate m, mchunkptr p); -static void do_check_inuse_chunk(mstate m, mchunkptr p); -static void do_check_free_chunk(mstate m, mchunkptr p); -static void do_check_malloced_chunk(mstate m, void* mem, size_t s); -static void do_check_tree(mstate m, tchunkptr t); -static void do_check_treebin(mstate m, bindex_t i); -static void do_check_smallbin(mstate m, bindex_t i); -static void do_check_malloc_state(mstate m); -static int bin_find(mstate m, mchunkptr x); -static size_t traverse_and_check(mstate m); -#endif /* DEBUG */ - -/* ---------------------------- Indexing Bins ---------------------------- */ - -#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) -#define small_index(s) ((s) >> SMALLBIN_SHIFT) -#define small_index2size(i) ((i) << SMALLBIN_SHIFT) -#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) - -/* addressing by index. See above about smallbin repositioning */ -#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) -#define treebin_at(M,i) (&((M)->treebins[i])) - -/* assign tree index for size S to variable I. Use x86 asm if possible */ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_tree_index(S, I)\ -{\ - unsigned int X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K;\ - __asm__("bsrl\t%1, %0\n\t" : "=r" (K) : "rm" (X));\ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} - -#elif defined (__INTEL_COMPILER) -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K = _bit_scan_reverse (X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} - -#elif defined(_MSC_VER) && _MSC_VER>=1300 -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K;\ - _BitScanReverse((DWORD *) &K, X);\ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} - -#else /* GNUC */ -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int Y = (unsigned int)X;\ - unsigned int N = ((Y - 0x100) >> 16) & 8;\ - unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ - N += K;\ - N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ - K = 14 - N + ((Y <<= K) >> 15);\ - I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ - }\ -} -#endif /* GNUC */ - -/* Bit representing maximum resolved size in a treebin at i */ -#define bit_for_tree_index(i) \ - (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) - -/* Shift placing maximum resolved bit in a treebin at i as sign bit */ -#define leftshift_for_tree_index(i) \ - ((i == NTREEBINS-1)? 0 : \ - ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) - -/* The size of the smallest chunk held in bin with index i */ -#define minsize_for_tree_index(i) \ - ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ - (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) - - -/* ------------------------ Operations on bin maps ----------------------- */ - -/* bit corresponding to given index */ -#define idx2bit(i) ((binmap_t)(1) << (i)) - -/* Mark/Clear bits with given index */ -#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) -#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) -#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) - -#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) -#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) -#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) - -/* isolate the least set bit of a bitmap */ -#define least_bit(x) ((x) & -(x)) - -/* mask with all bits to left of least bit of x on */ -#define left_bits(x) ((x<<1) | -(x<<1)) - -/* mask with all bits to left of or equal to least bit of x on */ -#define same_or_left_bits(x) ((x) | -(x)) - -/* index corresponding to given bit. Use x86 asm if possible */ - -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - __asm__("bsfl\t%1, %0\n\t" : "=r" (J) : "rm" (X));\ - I = (bindex_t)J;\ -} - -#elif defined (__INTEL_COMPILER) -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - J = _bit_scan_forward (X); \ - I = (bindex_t)J;\ -} - -#elif defined(_MSC_VER) && _MSC_VER>=1300 -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - _BitScanForward((DWORD *) &J, X);\ - I = (bindex_t)J;\ -} - -#elif USE_BUILTIN_FFS -#define compute_bit2idx(X, I) I = ffs(X)-1 - -#else -#define compute_bit2idx(X, I)\ -{\ - unsigned int Y = X - 1;\ - unsigned int K = Y >> (16-4) & 16;\ - unsigned int N = K; Y >>= K;\ - N += K = Y >> (8-3) & 8; Y >>= K;\ - N += K = Y >> (4-2) & 4; Y >>= K;\ - N += K = Y >> (2-1) & 2; Y >>= K;\ - N += K = Y >> (1-0) & 1; Y >>= K;\ - I = (bindex_t)(N + Y);\ -} -#endif /* GNUC */ - - -/* ----------------------- Runtime Check Support ------------------------- */ - -/* - For security, the main invariant is that malloc/free/etc never - writes to a static address other than malloc_state, unless static - malloc_state itself has been corrupted, which cannot occur via - malloc (because of these checks). In essence this means that we - believe all pointers, sizes, maps etc held in malloc_state, but - check all of those linked or offsetted from other embedded data - structures. These checks are interspersed with main code in a way - that tends to minimize their run-time cost. - - When FOOTERS is defined, in addition to range checking, we also - verify footer fields of inuse chunks, which can be used guarantee - that the mstate controlling malloc/free is intact. This is a - streamlined version of the approach described by William Robertson - et al in "Run-time Detection of Heap-based Overflows" LISA'03 - http://www.usenix.org/events/lisa03/tech/robertson.html The footer - of an inuse chunk holds the xor of its mstate and a random seed, - that is checked upon calls to free() and realloc(). This is - (probablistically) unguessable from outside the program, but can be - computed by any code successfully malloc'ing any chunk, so does not - itself provide protection against code that has already broken - security through some other means. Unlike Robertson et al, we - always dynamically check addresses of all offset chunks (previous, - next, etc). This turns out to be cheaper than relying on hashes. -*/ - -#if !INSECURE -/* Check if address a is at least as high as any from MORECORE or MMAP */ -#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) -/* Check if address of next chunk n is higher than base chunk p */ -#define ok_next(p, n) ((char*)(p) < (char*)(n)) -/* Check if p has its cinuse bit on */ -#define ok_cinuse(p) cinuse(p) -/* Check if p has its pinuse bit on */ -#define ok_pinuse(p) pinuse(p) - -#else /* !INSECURE */ -#define ok_address(M, a) (1) -#define ok_next(b, n) (1) -#define ok_cinuse(p) (1) -#define ok_pinuse(p) (1) -#endif /* !INSECURE */ - -#if (FOOTERS && !INSECURE) -/* Check if (alleged) mstate m has expected magic field */ -#define ok_magic(M) ((M)->magic == mparams.magic) -#else /* (FOOTERS && !INSECURE) */ -#define ok_magic(M) (1) -#endif /* (FOOTERS && !INSECURE) */ - - -/* In gcc, use __builtin_expect to minimize impact of checks */ -#if !INSECURE -#if defined(__GNUC__) && __GNUC__ >= 3 -#define RTCHECK(e) __builtin_expect(e, 1) -#else /* GNUC */ -#define RTCHECK(e) (e) -#endif /* GNUC */ -#else /* !INSECURE */ -#define RTCHECK(e) (1) -#endif /* !INSECURE */ - -/* macros to set up inuse chunks with or without footers */ - -#if !FOOTERS - -#define mark_inuse_foot(M,p,s) - -/* Set cinuse bit and pinuse bit of next chunk */ -#define set_inuse(M,p,s)\ - ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ -#define set_inuse_and_pinuse(M,p,s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set size, cinuse and pinuse bit of this chunk */ -#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) - -#else /* FOOTERS */ - -/* Set foot of inuse chunk to be xor of mstate and seed */ -#define mark_inuse_foot(M,p,s)\ - (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) - -#define get_mstate_for(p)\ - ((mstate)(((mchunkptr)((char*)(p) +\ - (chunksize(p))))->prev_foot ^ mparams.magic)) - -#define set_inuse(M,p,s)\ - ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M,p,s)) - -#define set_inuse_and_pinuse(M,p,s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ - mark_inuse_foot(M,p,s)) - -#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - mark_inuse_foot(M, p, s)) - -#endif /* !FOOTERS */ - -/* ---------------------------- setting mparams -------------------------- */ - -/* Initialize mparams */ -static int init_mparams(void) { -#ifdef NEED_GLOBAL_LOCK_INIT - if (malloc_global_mutex_status <= 0) - init_malloc_global_mutex(); -#endif - - ACQUIRE_MALLOC_GLOBAL_LOCK(); - if (mparams.magic == 0) { - size_t magic; - size_t psize; - size_t gsize; - -#ifndef WIN32 - psize = malloc_getpagesize; - gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); -#else /* WIN32 */ - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - psize = system_info.dwPageSize; - gsize = ((DEFAULT_GRANULARITY != 0)? - DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); - } -#endif /* WIN32 */ - - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if ((sizeof(size_t) != sizeof(char*)) || - (MAX_SIZE_T < MIN_CHUNK_SIZE) || - (sizeof(int) < 4) || - (MALLOC_ALIGNMENT < (size_t)8U) || - ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || - ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || - ((gsize & (gsize-SIZE_T_ONE)) != 0) || - ((psize & (psize-SIZE_T_ONE)) != 0)) - ABORT; - - mparams.granularity = gsize; - mparams.page_size = psize; - mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; -#if MORECORE_CONTIGUOUS - mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; -#else /* MORECORE_CONTIGUOUS */ - mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; -#endif /* MORECORE_CONTIGUOUS */ - -#if !ONLY_MSPACES - /* Set up lock for main malloc area */ - gm->mflags = mparams.default_mflags; - INITIAL_LOCK(&gm->mutex); -#endif - -#if (FOOTERS && !INSECURE) - { -#if USE_DEV_RANDOM - int fd; - unsigned char buf[sizeof(size_t)]; - /* Try to use /dev/urandom, else fall back on using time */ - if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && - read(fd, buf, sizeof(buf)) == sizeof(buf)) { - magic = *((size_t *) buf); - close(fd); - } - else -#endif /* USE_DEV_RANDOM */ -#ifdef WIN32 - magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); -#else - magic = (size_t)(time(0) ^ (size_t)0x55555555U); -#endif - magic |= (size_t)8U; /* ensure nonzero */ - magic &= ~(size_t)7U; /* improve chances of fault for bad values */ - } -#else /* (FOOTERS && !INSECURE) */ - magic = (size_t)0x58585858U; -#endif /* (FOOTERS && !INSECURE) */ - - mparams.magic = magic; - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - return 1; -} - -/* support for mallopt */ -static int change_mparam(int param_number, int value) { - size_t val = (value == -1)? MAX_SIZE_T : (size_t)value; - ensure_initialization(); - switch(param_number) { - case M_TRIM_THRESHOLD: - mparams.trim_threshold = val; - return 1; - case M_GRANULARITY: - if (val >= mparams.page_size && ((val & (val-1)) == 0)) { - mparams.granularity = val; - return 1; - } - else - return 0; - case M_MMAP_THRESHOLD: - mparams.mmap_threshold = val; - return 1; - default: - return 0; - } -} - -#if DEBUG -/* ------------------------- Debugging Support --------------------------- */ - -/* Check properties of any chunk, whether free, inuse, mmapped etc */ -static void do_check_any_chunk(mstate m, mchunkptr p) { - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); -} - -/* Check properties of top chunk */ -static void do_check_top_chunk(mstate m, mchunkptr p) { - msegmentptr sp = segment_holding(m, (char*)p); - size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!pinuse(chunk_plus_offset(p, sz))); -} - -/* Check properties of (inuse) mmapped chunks */ -static void do_check_mmapped_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); -} - -/* Check properties of inuse chunks */ -static void do_check_inuse_chunk(mstate m, mchunkptr p) { - do_check_any_chunk(m, p); - assert(cinuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if (is_mmapped(p)) - do_check_mmapped_chunk(m, p); -} - -/* Check properties of free chunks */ -static void do_check_free_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!cinuse(p)); - assert(!next_pinuse(p)); - assert (!is_mmapped(p)); - if (p != m->dv && p != m->top) { - if (sz >= MIN_CHUNK_SIZE) { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert (next == m->top || cinuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } - else /* markers are always of size SIZE_T_SIZE */ - assert(sz == SIZE_T_SIZE); - } -} - -/* Check properties of malloced chunks at the point they are malloced */ -static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } -} - -/* Check a tree and its subtrees. */ -static void do_check_tree(mstate m, tchunkptr t) { - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); - - do { /* traverse through chain of same-sized nodes */ - do_check_any_chunk(m, ((mchunkptr)u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!cinuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if (u->parent == 0) { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } - else { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert (u->parent->child[0] == u || - u->parent->child[1] == u || - *((tbinptr*)(u->parent)) == u); - if (u->child[0] != 0) { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if (u->child[1] != 0) { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if (u->child[0] != 0 && u->child[1] != 0) { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while (u != t); - assert(head != 0); -} - -/* Check all the chunks in a treebin. */ -static void do_check_treebin(mstate m, bindex_t i) { - tbinptr* tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if (t == 0) - assert(empty); - if (!empty) - do_check_tree(m, t); -} - -/* Check all the chunks in a smallbin. */ -static void do_check_smallbin(mstate m, bindex_t i) { - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if (p == b) - assert(empty); - if (!empty) { - for (; p != b; p = p->bk) { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if (q->head != FENCEPOST_HEAD) - do_check_inuse_chunk(m, q); - } - } -} - -/* Find x in a bin. Used in other check functions. */ -static int bin_find(mstate m, mchunkptr x) { - size_t size = chunksize(x); - if (is_small(size)) { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if (smallmap_is_marked(m, sidx)) { - mchunkptr p = b; - do { - if (p == x) - return 1; - } while ((p = p->fd) != b); - } - } - else { - bindex_t tidx; - compute_tree_index(size, tidx); - if (treemap_is_marked(m, tidx)) { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while (t != 0 && chunksize(t) != size) { - t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if (t != 0) { - tchunkptr u = t; - do { - if (u == (tchunkptr)x) - return 1; - } while ((u = u->fd) != t); - } - } - } - return 0; -} - -/* Traverse each chunk and check it; return total */ -static size_t traverse_and_check(mstate m) { - size_t sum = 0; - if (is_initialized(m)) { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - sum += chunksize(q); - if (cinuse(q)) { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } - else { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; - } - } - return sum; -} - -/* Check all properties of malloc_state. */ -static void do_check_malloc_state(mstate m) { - bindex_t i; - size_t total; - /* check bins */ - for (i = 0; i < NSMALLBINS; ++i) - do_check_smallbin(m, i); - for (i = 0; i < NTREEBINS; ++i) - do_check_treebin(m, i); - - if (m->dvsize != 0) { /* check dv chunk */ - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } - - if (m->top != 0) { /* check top chunk */ - do_check_top_chunk(m, m->top); - /*assert(m->topsize == chunksize(m->top)); redundant */ - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } - - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); -} -#endif /* DEBUG */ - -/* ----------------------------- statistics ------------------------------ */ - -#if !NO_MALLINFO -static struct mallinfo internal_mallinfo(mstate m) { - struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - ensure_initialization(); - if (!PREACTION(m)) { - check_malloc_state(m); - if (is_initialized(m)) { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = m->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &m->seg; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - size_t sz = chunksize(q); - sum += sz; - if (!cinuse(q)) { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = m->footprint - sum; - nm.usmblks = m->max_footprint; - nm.uordblks = m->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = m->topsize; - } - - POSTACTION(m); - } - return nm; -} -#endif /* !NO_MALLINFO */ - -static void internal_malloc_stats(mstate m) { - ensure_initialization(); - if (!PREACTION(m)) { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - if (!cinuse(q)) - used -= chunksize(q); - q = next_chunk(q); - } - s = s->next; - } - } - - fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); - fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); - fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); - - POSTACTION(m); - } -} - -/* ----------------------- Operations on smallbins ----------------------- */ - -/* - Various forms of linking and unlinking are defined as macros. Even - the ones for trees, which are very long but have very short typical - paths. This is ugly but reduces reliance on inlining support of - compilers. -*/ - -/* Link a free chunk into a smallbin */ -#define insert_small_chunk(M, P, S) {\ - bindex_t I = small_index(S);\ - mchunkptr B = smallbin_at(M, I);\ - mchunkptr F = B;\ - assert(S >= MIN_CHUNK_SIZE);\ - if (!smallmap_is_marked(M, I))\ - mark_smallmap(M, I);\ - else if (RTCHECK(ok_address(M, B->fd)))\ - F = B->fd;\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - B->fd = P;\ - F->bk = P;\ - P->fd = F;\ - P->bk = B;\ -} - -/* Unlink a chunk from a smallbin */ -#define unlink_small_chunk(M, P, S) {\ - mchunkptr F = P->fd;\ - mchunkptr B = P->bk;\ - bindex_t I = small_index(S);\ - assert(P != B);\ - assert(P != F);\ - assert(chunksize(P) == small_index2size(I));\ - if (F == B)\ - clear_smallmap(M, I);\ - else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\ - (B == smallbin_at(M,I) || ok_address(M, B)))) {\ - F->bk = B;\ - B->fd = F;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ -} - -/* Unlink the first chunk from a smallbin */ -#define unlink_first_small_chunk(M, B, P, I) {\ - mchunkptr F = P->fd;\ - assert(P != B);\ - assert(P != F);\ - assert(chunksize(P) == small_index2size(I));\ - if (B == F)\ - clear_smallmap(M, I);\ - else if (RTCHECK(ok_address(M, F))) {\ - B->fd = F;\ - F->bk = B;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ -} - - - -/* Replace dv node, binning the old one */ -/* Used only when dvsize known to be small */ -#define replace_dv(M, P, S) {\ - size_t DVS = M->dvsize;\ - if (DVS != 0) {\ - mchunkptr DV = M->dv;\ - assert(is_small(DVS));\ - insert_small_chunk(M, DV, DVS);\ - }\ - M->dvsize = S;\ - M->dv = P;\ -} - -/* ------------------------- Operations on trees ------------------------- */ - -/* Insert chunk into tree */ -#define insert_large_chunk(M, X, S) {\ - tbinptr* H;\ - bindex_t I;\ - compute_tree_index(S, I);\ - H = treebin_at(M, I);\ - X->index = I;\ - X->child[0] = X->child[1] = 0;\ - if (!treemap_is_marked(M, I)) {\ - mark_treemap(M, I);\ - *H = X;\ - X->parent = (tchunkptr)H;\ - X->fd = X->bk = X;\ - }\ - else {\ - tchunkptr T = *H;\ - size_t K = S << leftshift_for_tree_index(I);\ - for (;;) {\ - if (chunksize(T) != S) {\ - tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ - K <<= 1;\ - if (*C != 0)\ - T = *C;\ - else if (RTCHECK(ok_address(M, C))) {\ - *C = X;\ - X->parent = T;\ - X->fd = X->bk = X;\ - break;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - break;\ - }\ - }\ - else {\ - tchunkptr F = T->fd;\ - if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ - T->fd = F->bk = X;\ - X->fd = F;\ - X->bk = T;\ - X->parent = 0;\ - break;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - break;\ - }\ - }\ - }\ - }\ -} - -/* - Unlink steps: - - 1. If x is a chained node, unlink it from its same-sized fd/bk links - and choose its bk node as its replacement. - 2. If x was the last node of its size, but not a leaf node, it must - be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent - of x. We could use any other leaf, but this is easy to locate and - tends to counteract removal of leftmosts elsewhere, and so keeps - paths shorter than minimally guaranteed. This doesn't loop much - because on average a node in a tree is near the bottom. - 3. If x is the base of a chain (i.e., has parent links) relink - x's parent and children to x's replacement (or null if none). -*/ - -#define unlink_large_chunk(M, X) {\ - tchunkptr XP = X->parent;\ - tchunkptr R;\ - if (X->bk != X) {\ - tchunkptr F = X->fd;\ - R = X->bk;\ - if (RTCHECK(ok_address(M, F))) {\ - F->bk = R;\ - R->fd = F;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - else {\ - tchunkptr* RP;\ - if (((R = *(RP = &(X->child[1]))) != 0) ||\ - ((R = *(RP = &(X->child[0]))) != 0)) {\ - tchunkptr* CP;\ - while ((*(CP = &(R->child[1])) != 0) ||\ - (*(CP = &(R->child[0])) != 0)) {\ - R = *(RP = CP);\ - }\ - if (RTCHECK(ok_address(M, RP)))\ - *RP = 0;\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - }\ - if (XP != 0) {\ - tbinptr* H = treebin_at(M, X->index);\ - if (X == *H) {\ - if ((*H = R) == 0) \ - clear_treemap(M, X->index);\ - }\ - else if (RTCHECK(ok_address(M, XP))) {\ - if (XP->child[0] == X) \ - XP->child[0] = R;\ - else \ - XP->child[1] = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - if (R != 0) {\ - if (RTCHECK(ok_address(M, R))) {\ - tchunkptr C0, C1;\ - R->parent = XP;\ - if ((C0 = X->child[0]) != 0) {\ - if (RTCHECK(ok_address(M, C0))) {\ - R->child[0] = C0;\ - C0->parent = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - if ((C1 = X->child[1]) != 0) {\ - if (RTCHECK(ok_address(M, C1))) {\ - R->child[1] = C1;\ - C1->parent = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ -} - -/* Relays to large vs small bin operations */ - -#define insert_chunk(M, P, S)\ - if (is_small(S)) insert_small_chunk(M, P, S)\ - else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } - -#define unlink_chunk(M, P, S)\ - if (is_small(S)) unlink_small_chunk(M, P, S)\ - else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } - - -/* Relays to internal calls to malloc/free from realloc, memalign etc */ - -#if ONLY_MSPACES -#define internal_malloc(m, b) mspace_malloc(m, b) -#define internal_free(m, mem) mspace_free(m,mem); -#else /* ONLY_MSPACES */ -#if MSPACES -#define internal_malloc(m, b)\ - (m == gm)? dlmalloc(b) : mspace_malloc(m, b) -#define internal_free(m, mem)\ - if (m == gm) dlfree(mem); else mspace_free(m,mem); -#else /* MSPACES */ -#define internal_malloc(m, b) dlmalloc(b) -#define internal_free(m, mem) dlfree(mem) -#endif /* MSPACES */ -#endif /* ONLY_MSPACES */ - -/* ----------------------- Direct-mmapping chunks ----------------------- */ - -/* - Directly mmapped chunks are set up with an offset to the start of - the mmapped region stored in the prev_foot field of the chunk. This - allows reconstruction of the required argument to MUNMAP when freed, - and also allows adjustment of the returned chunk to meet alignment - requirements (especially in memalign). There is also enough space - allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain - the PINUSE bit so frees can be checked. -*/ - -/* Malloc using mmap */ -static void* mmap_alloc(mstate m, size_t nb) { - size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if (mmsize > nb) { /* Check for wrap around 0 */ - char* mm = (char*)(CALL_DIRECT_MMAP(mmsize)); - if (mm != CMFAIL) { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr)(mm + offset); - p->prev_foot = offset | IS_MMAPPED_BIT; - (p)->head = (psize|CINUSE_BIT); - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; - - if (mm < m->least_addr) - m->least_addr = mm; - if ((m->footprint += mmsize) > m->max_footprint) - m->max_footprint = m->footprint; - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } - } - return 0; -} - -/* Realloc using mmap */ -static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) { - size_t oldsize = chunksize(oldp); - if (is_small(nb)) /* Can't shrink mmap regions below small size */ - return 0; - /* Keep old chunk if big enough but not too big */ - if (oldsize >= nb + SIZE_T_SIZE && - (oldsize - nb) <= (mparams.granularity << 1)) - return oldp; - else { - size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - char* cp = (char*)(intptr_t)CALL_MREMAP((char*)oldp - offset, - oldmmsize, newmmsize, 1); - if (cp != CMFAIL) { - mchunkptr newp = (mchunkptr)(cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = (psize|CINUSE_BIT); - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; - - if (cp < m->least_addr) - m->least_addr = cp; - if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) - m->max_footprint = m->footprint; - check_mmapped_chunk(m, newp); - return newp; - } - } - return 0; -} - -/* -------------------------- mspace management -------------------------- */ - -/* Initialize top chunk and its size */ -static void init_top(mstate m, mchunkptr p, size_t psize) { - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr)((char*)p + offset); - psize -= offset; - - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = mparams.trim_threshold; /* reset on each update */ -} - -/* Initialize bins for a new mstate that is otherwise zeroed out */ -static void init_bins(mstate m) { - /* Establish circular links for smallbins */ - bindex_t i; - for (i = 0; i < NSMALLBINS; ++i) { - sbinptr bin = smallbin_at(m,i); - bin->fd = bin->bk = bin; - } -} - -#if PROCEED_ON_ERROR - -/* default corruption action */ -static void reset_on_error(mstate m) { - int i; - ++malloc_corruption_error_count; - /* Reinitialize fields to forget about all memory */ - m->smallbins = m->treebins = 0; - m->dvsize = m->topsize = 0; - m->seg.base = 0; - m->seg.size = 0; - m->seg.next = 0; - m->top = m->dv = 0; - for (i = 0; i < NTREEBINS; ++i) - *treebin_at(m, i) = 0; - init_bins(m); -} -#endif /* PROCEED_ON_ERROR */ - -/* Allocate chunk and prepend remainder with chunk in successor base. */ -static void* prepend_alloc(mstate m, char* newbase, char* oldbase, - size_t nb) { - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char*)oldfirst - (char*)p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - - assert((char*)oldfirst > (char*)q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); - - /* consolidate remainder with first chunk of old base */ - if (oldfirst == m->top) { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } - else if (oldfirst == m->dv) { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } - else { - if (!cinuse(oldfirst)) { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); - } - - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); -} - -/* Add a segment to hold a new noncontiguous region */ -static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { - /* Determine locations and sizes of segment, fenceposts, old top */ - char* old_top = (char*)m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char* old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct malloc_segment)); - char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char* asp = rawsp + offset; - char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; - mchunkptr sp = (mchunkptr)csp; - msegmentptr ss = (msegmentptr)(chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; - - /* reset top to new space */ - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; - - /* Insert trailing fenceposts */ - for (;;) { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if ((char*)(&(nextp->head)) < old_end) - p = nextp; - else - break; - } - assert(nfences >= 2); - - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if (csp != old_top) { - mchunkptr q = (mchunkptr)old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } - - check_top_chunk(m, m->top); -} - -/* -------------------------- System allocation -------------------------- */ - -/* Get memory from system using MORECORE or MMAP */ -static void* sys_alloc(mstate m, size_t nb) { - char* tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; - - ensure_initialization(); - - /* Directly map large chunks */ - if (use_mmap(m) && nb >= mparams.mmap_threshold) { - void* mem = mmap_alloc(m, nb); - if (mem != 0) - return mem; - } - - /* - Try getting memory in any of three ways (in most-preferred to - least-preferred order): - 1. A call to MORECORE that can normally contiguously extend memory. - (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or - or main space is mmapped or a previous contiguous call failed) - 2. A call to MMAP new space (disabled if not HAVE_MMAP). - Note that under the default settings, if MORECORE is unable to - fulfill a request, and HAVE_MMAP is true, then mmap is - used as a noncontiguous system allocator. This is a useful backup - strategy for systems with holes in address spaces -- in this case - sbrk cannot contiguously expand the heap, but mmap may be able to - find space. - 3. A call to MORECORE that cannot usually contiguously extend memory. - (disabled if not HAVE_MORECORE) - - In all cases, we need to request enough bytes from system to ensure - we can malloc nb bytes upon success, so pad with enough space for - top_foot, plus alignment-pad to make sure we don't lose bytes if - not on boundary, and round this up to a granularity unit. - */ - - if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { - char* br = CMFAIL; - msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); - size_t asize = 0; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - - if (ss == 0) { /* First time through or recovery */ - char* base = (char*)CALL_MORECORE(0); - if (base != CMFAIL) { - asize = granularity_align(nb + SYS_ALLOC_PADDING); - /* Adjust to end on a page boundary */ - if (!is_page_aligned(base)) - asize += (page_align((size_t)base) - (size_t)base); - /* Can't call MORECORE if size is negative when treated as signed */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == base) { - tbase = base; - tsize = asize; - } - } - } - else { - /* Subtract out existing available top space from MORECORE request. */ - asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); - /* Use mem here only if it did continuously extend old space */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { - tbase = br; - tsize = asize; - } - } - - if (tbase == CMFAIL) { /* Cope with partial failure */ - if (br != CMFAIL) { /* Try to use/extend the space we did get */ - if (asize < HALF_MAX_SIZE_T && - asize < nb + SYS_ALLOC_PADDING) { - size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize); - if (esize < HALF_MAX_SIZE_T) { - char* end = (char*)CALL_MORECORE(esize); - if (end != CMFAIL) - asize += esize; - else { /* Can't use; try to release */ - (void) CALL_MORECORE(-asize); - br = CMFAIL; - } - } - } - } - if (br != CMFAIL) { /* Use the space we did get */ - tbase = br; - tsize = asize; - } - else - disable_contiguous(m); /* Don't try contiguous path in the future */ - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - } - - if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - size_t rsize = granularity_align(nb + SYS_ALLOC_PADDING); - if (rsize > nb) { /* Fail if wraps around zero */ - char* mp = (char*)(CALL_MMAP(rsize)); - if (mp != CMFAIL) { - tbase = mp; - tsize = rsize; - mmap_flag = IS_MMAPPED_BIT; - } - } - } - - if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ - size_t asize = granularity_align(nb + SYS_ALLOC_PADDING); - if (asize < HALF_MAX_SIZE_T) { - char* br = CMFAIL; - char* end = CMFAIL; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - br = (char*)(CALL_MORECORE(asize)); - end = (char*)(CALL_MORECORE(0)); - RELEASE_MALLOC_GLOBAL_LOCK(); - if (br != CMFAIL && end != CMFAIL && br < end) { - size_t ssize = end - br; - if (ssize > nb + TOP_FOOT_SIZE) { - tbase = br; - tsize = ssize; - } - } - } - } - - if (tbase != CMFAIL) { - - if ((m->footprint += tsize) > m->max_footprint) - m->max_footprint = m->footprint; - - if (!is_initialized(m)) { /* first-time initialization */ - m->seg.base = m->least_addr = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - init_bins(m); -#if !ONLY_MSPACES - if (is_global(m)) - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - else -#endif - { - /* Offset top by embedded malloc_state */ - mchunkptr mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); - } - } - - else { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - /* Only consider most recent segment if traversal suppressed */ - while (sp != 0 && tbase != sp->base + sp->size) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & IS_MMAPPED_BIT) == mmap_flag && - segment_holds(sp, m->top)) { /* append */ - sp->size += tsize; - init_top(m, m->top, m->topsize + tsize); - } - else { - if (tbase < m->least_addr) - m->least_addr = tbase; - sp = &m->seg; - while (sp != 0 && sp->base != tbase + tsize) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) { - char* oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return prepend_alloc(m, tbase, oldbase, nb); - } - else - add_segment(m, tbase, tsize, mmap_flag); - } - } - - if (nb < m->topsize) { /* Allocate from new or extended top space */ - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); - } - } - - MALLOC_FAILURE_ACTION; - return 0; -} - -/* ----------------------- system deallocation -------------------------- */ - -/* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t release_unused_segments(mstate m) { - size_t released = 0; - int nsegs = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while (sp != 0) { - char* base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - ++nsegs; - if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { - tchunkptr tp = (tchunkptr)p; - assert(segment_holds(sp, (char*)sp)); - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } - else { - unlink_large_chunk(m, tp); - } - if (CALL_MUNMAP(base, size) == 0) { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } - else { /* back out if cannot unmap */ - insert_large_chunk(m, tp, psize); - } - } - } - if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ - break; - pred = sp; - sp = next; - } - /* Reset check counter */ - m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)? - nsegs : MAX_RELEASE_CHECK_RATE); - return released; -} - -static int sys_trim(mstate m, size_t pad) { - size_t released = 0; - ensure_initialization(); - if (pad < MAX_REQUEST && is_initialized(m)) { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - - if (m->topsize > pad) { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = mparams.granularity; - size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - - SIZE_T_ONE) * unit; - msegmentptr sp = segment_holding(m, (char*)m->top); - - if (!is_extern_segment(sp)) { - if (is_mmapped_segment(sp)) { - if (HAVE_MMAP && - sp->size >= extra && - !has_segment_link(m, sp)) { /* can't shrink if pinned */ - size_t newsize = sp->size - extra; - /* Prefer mremap, fall back to munmap */ - if (((void*)(intptr_t)CALL_MREMAP(sp->base, sp->size, newsize, 0) != (void*)MFAIL) || - (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { - released = extra; - } - } - } - else if (HAVE_MORECORE) { - if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ - extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - { - /* Make sure end of memory is where we last set it. */ - char* old_br = (char*)(CALL_MORECORE(0)); - if (old_br == sp->base + sp->size) { - char* rel_br = (char*)(CALL_MORECORE(-extra)); - char* new_br = (char*)(CALL_MORECORE(0)); - if (rel_br != CMFAIL && new_br < old_br) - released = old_br - new_br; - } - } - RELEASE_MALLOC_GLOBAL_LOCK(); - } - } - - if (released != 0) { - sp->size -= released; - m->footprint -= released; - init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); - } - } - - /* Unmap any unused mmapped segments */ - if (HAVE_MMAP) - released += release_unused_segments(m); - - /* On failure, disable autotrim to avoid repeated failed future calls */ - if (released == 0 && m->topsize > m->trim_check) - m->trim_check = MAX_SIZE_T; - } - - return (released != 0)? 1 : 0; -} - - -/* ---------------------------- malloc support --------------------------- */ - -/* allocate a large request from the best fitting chunk in a treebin */ -static void* tmalloc_large(mstate m, size_t nb) { - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); - if ((t = *treebin_at(m, idx)) != 0) { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for (;;) { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - v = t; - if ((rsize = trem) == 0) - break; - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; - if (rt != 0 && rt != t) - rst = rt; - if (t == 0) { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } - } - if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if (leftbits != 0) { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } - } - - while (t != 0) { /* find smallest of tree or subtree */ - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - t = leftmost_child(t); - } - - /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { - if (RTCHECK(ok_address(m, v))) { /* split */ - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - } - return 0; -} - -/* allocate a small request from the best fitting chunk in a treebin */ -static void* tmalloc_small(mstate m, size_t nb) { - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; - - while ((t = leftmost_child(t)) != 0) { - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - } - - if (RTCHECK(ok_address(m, v))) { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } - } - - CORRUPTION_ERROR_ACTION(m); - return 0; -} - -/* --------------------------- realloc support --------------------------- */ - -static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { - if (bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - return 0; - } - if (!PREACTION(m)) { - mchunkptr oldp = mem2chunk(oldmem); - size_t oldsize = chunksize(oldp); - mchunkptr next = chunk_plus_offset(oldp, oldsize); - mchunkptr newp = 0; - void* extra = 0; - - /* Try to either shrink or extend into top. Else malloc-copy-free */ - - if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && - ok_next(oldp, next) && ok_pinuse(next))) { - size_t nb = request2size(bytes); - if (is_mmapped(oldp)) - newp = mmap_resize(m, oldp, nb); - else if (oldsize >= nb) { /* already big enough */ - size_t rsize = oldsize - nb; - newp = oldp; - if (rsize >= MIN_CHUNK_SIZE) { - mchunkptr remainder = chunk_plus_offset(newp, nb); - set_inuse(m, newp, nb); - set_inuse(m, remainder, rsize); - extra = chunk2mem(remainder); - } - } - else if (next == m->top && oldsize + m->topsize > nb) { - /* Expand into top */ - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(oldp, nb); - set_inuse(m, oldp, nb); - newtop->head = newtopsize |PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = oldp; - } - } - else { - USAGE_ERROR_ACTION(m, oldmem); - POSTACTION(m); - return 0; - } - - POSTACTION(m); - - if (newp != 0) { - if (extra != 0) { - internal_free(m, extra); - } - check_inuse_chunk(m, newp); - return chunk2mem(newp); - } - else { - void* newmem = internal_malloc(m, bytes); - if (newmem != 0) { - size_t oc = oldsize - overhead_for(oldp); - memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); - internal_free(m, oldmem); - } - return newmem; - } - } - return 0; -} - -/* --------------------------- memalign support -------------------------- */ - -static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { - if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ - return internal_malloc(m, bytes); - if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ - alignment = MIN_CHUNK_SIZE; - if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ - size_t a = MALLOC_ALIGNMENT << 1; - while (a < alignment) a <<= 1; - alignment = a; - } - - if (bytes >= MAX_REQUEST - alignment) { - if (m != 0) { /* Test isn't needed but avoids compiler warning */ - MALLOC_FAILURE_ACTION; - } - } - else { - size_t nb = request2size(bytes); - size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - char* mem = (char*)internal_malloc(m, req); - if (mem != 0) { - void* leader = 0; - void* trailer = 0; - mchunkptr p = mem2chunk(mem); - - if (PREACTION(m)) return 0; - if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - char* br = (char*)mem2chunk((size_t)(((size_t)(mem + - alignment - - SIZE_T_ONE)) & - -alignment)); - char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? - br : br+alignment; - mchunkptr newp = (mchunkptr)pos; - size_t leadsize = pos - (char*)(p); - size_t newsize = chunksize(p) - leadsize; - - if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ - newp->prev_foot = p->prev_foot + leadsize; - newp->head = (newsize|CINUSE_BIT); - } - else { /* Otherwise, give back leader, use the rest */ - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - leader = chunk2mem(p); - } - p = newp; - } - - /* Give back spare room at the end */ - if (!is_mmapped(p)) { - size_t size = chunksize(p); - if (size > nb + MIN_CHUNK_SIZE) { - size_t remainder_size = size - nb; - mchunkptr remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - trailer = chunk2mem(remainder); - } - } - - assert (chunksize(p) >= nb); - assert((((size_t)(chunk2mem(p))) % alignment) == 0); - check_inuse_chunk(m, p); - POSTACTION(m); - if (leader != 0) { - internal_free(m, leader); - } - if (trailer != 0) { - internal_free(m, trailer); - } - return chunk2mem(p); - } - } - return 0; -} - -/* ------------------------ comalloc/coalloc support --------------------- */ - -static void** ialloc(mstate m, - size_t n_elements, - size_t* sizes, - int opts, - void* chunks[]) { - /* - This provides common support for independent_X routines, handling - all of the combinations that can result. - - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed - */ - - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size; /* total size of elements */ - size_t array_size; /* request size of pointer array */ - void* mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size; /* remaining bytes while splitting */ - void** marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; - - ensure_initialization(); - /* compute array length, if needed */ - if (chunks != 0) { - if (n_elements == 0) - return chunks; /* nothing to do */ - marray = chunks; - array_size = 0; - } - else { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) - return (void**)internal_malloc(m, 0); - marray = 0; - array_size = request2size(n_elements * (sizeof(void*))); - } - - /* compute total element size */ - if (opts & 0x1) { /* all-same-size */ - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } - else { /* add up all the sizes */ - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) - contents_size += request2size(sizes[i]); - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = internal_malloc(m, size - CHUNK_OVERHEAD); - if (was_enabled) - enable_mmap(m); - if (mem == 0) - return 0; - - if (PREACTION(m)) return 0; - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if (opts & 0x2) { /* optionally clear the elements */ - memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = (void**) (chunk2mem(array_chunk)); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0; ; ++i) { - marray[i] = chunk2mem(p); - if (i != n_elements-1) { - if (element_size != 0) - size = element_size; - else - size = request2size(sizes[i]); - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } - else { /* the final element absorbs any overallocation slop */ - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#if DEBUG - if (marray != chunks) { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) { - assert(remainder_size == element_size); - } - else { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } - for (i = 0; i != n_elements; ++i) - check_inuse_chunk(m, mem2chunk(marray[i])); - -#endif /* DEBUG */ - - POSTACTION(m); - return marray; -} - - -/* -------------------------- public routines ---------------------------- */ - -#if !ONLY_MSPACES - -void* dlmalloc(size_t bytes) { - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): - 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. - 4. If it is big enough, use the top chunk. - 5. If available, get memory from system and use it - Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. - 3. If it is big enough, use the top chunk. - 4. If request size >= mmap threshold, try to directly mmap this chunk. - 5. If available, get memory from system and use it - - The ugly goto's here ensure that postaction occurs along all paths. - */ - -#if USE_LOCKS - ensure_initialization(); /* initialize in sys_alloc if not using locks */ -#endif - - if (!PREACTION(gm)) { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = gm->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(gm, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(gm, b, p, idx); - set_inuse_and_pinuse(gm, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb > gm->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(gm, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(gm, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(gm, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - - if (nb <= gm->dvsize) { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } - else { /* exhaust dv */ - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb < gm->topsize) { /* Split top */ - size_t rsize = gm->topsize -= nb; - mchunkptr p = gm->top; - mchunkptr r = gm->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - mem = chunk2mem(p); - check_top_chunk(gm, gm->top); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - mem = sys_alloc(gm, nb); - - postaction: - POSTACTION(gm); - return mem; - } - - return 0; -} - -void dlfree(void* mem) { - /* - Consolidate freed chunks with preceeding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ - - if (mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } -#else /* FOOTERS */ -#define fm gm -#endif /* FOOTERS */ - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if ((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } - else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } - else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } - else - set_free_with_pinuse(p, psize, next); - - if (is_small(psize)) { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - release_unused_segments(fm); - } - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -#if !FOOTERS -#undef fm -#endif /* FOOTERS */ -} - -void* dlcalloc(size_t n_elements, size_t elem_size) { - void* mem; - size_t req = 0; - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = dlmalloc(req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void* dlrealloc(void* oldmem, size_t bytes) { - if (oldmem == 0) - return dlmalloc(bytes); -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - dlfree(oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { -#if ! FOOTERS - mstate m = gm; -#else /* FOOTERS */ - mstate m = get_mstate_for(mem2chunk(oldmem)); - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - return internal_realloc(m, oldmem, bytes); - } -} - -void* dlmemalign(size_t alignment, size_t bytes) { - return internal_memalign(gm, alignment, bytes); -} - -void** dlindependent_calloc(size_t n_elements, size_t elem_size, - void* chunks[]) { - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(gm, n_elements, &sz, 3, chunks); -} - -void** dlindependent_comalloc(size_t n_elements, size_t sizes[], - void* chunks[]) { - return ialloc(gm, n_elements, sizes, 0, chunks); -} - -void* dlvalloc(size_t bytes) { - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); -} - -void* dlpvalloc(size_t bytes) { - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); -} - -int dlmalloc_trim(size_t pad) { - ensure_initialization(); - int result = 0; - if (!PREACTION(gm)) { - result = sys_trim(gm, pad); - POSTACTION(gm); - } - return result; -} - -size_t dlmalloc_footprint(void) { - return gm->footprint; -} - -size_t dlmalloc_max_footprint(void) { - return gm->max_footprint; -} - -#if !NO_MALLINFO -struct mallinfo dlmallinfo(void) { - return internal_mallinfo(gm); -} -#endif /* NO_MALLINFO */ - -void dlmalloc_stats() { - internal_malloc_stats(gm); -} - -int dlmallopt(int param_number, int value) { - return change_mparam(param_number, value); -} - -#endif /* !ONLY_MSPACES */ - -size_t dlmalloc_usable_size(void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -/* ----------------------------- user mspaces ---------------------------- */ - -#if MSPACES - -static mstate init_user_mstate(char* tbase, size_t tsize) { - size_t msize = pad_request(sizeof(struct malloc_state)); - mchunkptr mn; - mchunkptr msp = align_as_chunk(tbase); - mstate m = (mstate)(chunk2mem(msp)); - memset(m, 0, msize); - INITIAL_LOCK(&m->mutex); - msp->head = (msize|PINUSE_BIT|CINUSE_BIT); - m->seg.base = m->least_addr = tbase; - m->seg.size = m->footprint = m->max_footprint = tsize; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - m->mflags = mparams.default_mflags; - m->extp = 0; - m->exts = 0; - disable_contiguous(m); - init_bins(m); - mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); - check_top_chunk(m, m->top); - return m; -} - -mspace create_mspace(size_t capacity, int locked) { - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { - size_t rs = ((capacity == 0)? mparams.granularity : - (capacity + TOP_FOOT_SIZE + msize)); - size_t tsize = granularity_align(rs); - char* tbase = (char*)(CALL_MMAP(tsize)); - if (tbase != CMFAIL) { - m = init_user_mstate(tbase, tsize); - m->seg.sflags = IS_MMAPPED_BIT; - set_lock(m, locked); - } - } - return (mspace)m; -} - -mspace create_mspace_with_base(void* base, size_t capacity, int locked) { - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - if (capacity > msize + TOP_FOOT_SIZE && - capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { - m = init_user_mstate((char*)base, capacity); - m->seg.sflags = EXTERN_BIT; - set_lock(m, locked); - } - return (mspace)m; -} - -int mspace_mmap_large_chunks(mspace msp, int enable) { - int ret = 0; - mstate ms = (mstate)msp; - if (!PREACTION(ms)) { - if (use_mmap(ms)) - ret = 1; - if (enable) - enable_mmap(ms); - else - disable_mmap(ms); - POSTACTION(ms); - } - return ret; -} - -size_t destroy_mspace(mspace msp) { - size_t freed = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - msegmentptr sp = &ms->seg; - while (sp != 0) { - char* base = sp->base; - size_t size = sp->size; - flag_t flag = sp->sflags; - sp = sp->next; - if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) && - CALL_MUNMAP(base, size) == 0) - freed += size; - } - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return freed; -} - -/* - mspace versions of routines are near-clones of the global - versions. This is not so nice but better than the alternatives. -*/ - - -void* mspace_malloc(mspace msp, size_t bytes) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - if (!PREACTION(ms)) { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = ms->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(ms, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(ms, b, p, idx); - set_inuse_and_pinuse(ms, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb > ms->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(ms, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(ms, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(ms, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(ms, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - - if (nb <= ms->dvsize) { - size_t rsize = ms->dvsize - nb; - mchunkptr p = ms->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = ms->dv = chunk_plus_offset(p, nb); - ms->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - } - else { /* exhaust dv */ - size_t dvs = ms->dvsize; - ms->dvsize = 0; - ms->dv = 0; - set_inuse_and_pinuse(ms, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb < ms->topsize) { /* Split top */ - size_t rsize = ms->topsize -= nb; - mchunkptr p = ms->top; - mchunkptr r = ms->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - mem = chunk2mem(p); - check_top_chunk(ms, ms->top); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - mem = sys_alloc(ms, nb); - - postaction: - POSTACTION(ms); - return mem; - } - - return 0; -} - -void mspace_free(mspace msp, void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); -#else /* FOOTERS */ - mstate fm = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if ((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } - else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } - else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } - else - set_free_with_pinuse(p, psize, next); - - if (is_small(psize)) { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - release_unused_segments(fm); - } - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -} - -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { - void* mem; - size_t req = 0; - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = internal_malloc(ms, req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { - if (oldmem == 0) - return mspace_malloc(msp, bytes); -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - mspace_free(msp, oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { -#if FOOTERS - mchunkptr p = mem2chunk(oldmem); - mstate ms = get_mstate_for(p); -#else /* FOOTERS */ - mstate ms = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return internal_realloc(ms, oldmem, bytes); - } -} - -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return internal_memalign(ms, alignment, bytes); -} - -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]) { - size_t sz = elem_size; /* serves as 1-element array */ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return ialloc(ms, n_elements, &sz, 3, chunks); -} - -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return ialloc(ms, n_elements, sizes, 0, chunks); -} - -int mspace_trim(mspace msp, size_t pad) { - int result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - if (!PREACTION(ms)) { - result = sys_trim(ms, pad); - POSTACTION(ms); - } - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - -void mspace_malloc_stats(mspace msp) { - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - internal_malloc_stats(ms); - } - else { - USAGE_ERROR_ACTION(ms,ms); - } -} - -size_t mspace_footprint(mspace msp) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - result = ms->footprint; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - - -size_t mspace_max_footprint(mspace msp) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - result = ms->max_footprint; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - - -#if !NO_MALLINFO -struct mallinfo mspace_mallinfo(mspace msp) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - } - return internal_mallinfo(ms); -} -#endif /* NO_MALLINFO */ - -size_t mspace_usable_size(void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -int mspace_mallopt(int param_number, int value) { - return change_mparam(param_number, value); -} - -#endif /* MSPACES */ - -/* -------------------- Alternative MORECORE functions ------------------- */ - -/* - Guidelines for creating a custom version of MORECORE: - - * For best performance, MORECORE should allocate in multiples of pagesize. - * MORECORE may allocate more memory than requested. (Or even less, - but this will usually result in a malloc failure.) - * MORECORE must not allocate memory when given argument zero, but - instead return one past the end address of memory from previous - nonzero call. - * For best performance, consecutive calls to MORECORE with positive - arguments should return increasing addresses, indicating that - space has been contiguously extended. - * Even though consecutive calls to MORECORE need not return contiguous - addresses, it must be OK for malloc'ed chunks to span multiple - regions in those cases where they do happen to be contiguous. - * MORECORE need not handle negative arguments -- it may instead - just return MFAIL when given negative arguments. - Negative arguments are always multiples of pagesize. MORECORE - must not misinterpret negative args as large positive unsigned - args. You can suppress all such calls from even occurring by defining - MORECORE_CANNOT_TRIM, - - As an example alternative MORECORE, here is a custom allocator - kindly contributed for pre-OSX macOS. It uses virtually but not - necessarily physically contiguous non-paged memory (locked in, - present and won't get swapped out). You can use it by uncommenting - this section, adding some #includes, and setting up the appropriate - defines above: - - #define MORECORE osMoreCore - - There is also a shutdown routine that should somehow be called for - cleanup upon program exit. - - #define MAX_POOL_ENTRIES 100 - #define MINIMUM_MORECORE_SIZE (64 * 1024U) - static int next_os_pool; - void *our_os_pools[MAX_POOL_ENTRIES]; - - void *osMoreCore(int size) - { - void *ptr = 0; - static void *sbrk_top = 0; - - if (size > 0) - { - if (size < MINIMUM_MORECORE_SIZE) - size = MINIMUM_MORECORE_SIZE; - if (CurrentExecutionLevel() == kTaskLevel) - ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); - if (ptr == 0) - { - return (void *) MFAIL; - } - // save ptrs so they can be freed during cleanup - our_os_pools[next_os_pool] = ptr; - next_os_pool++; - ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); - sbrk_top = (char *) ptr + size; - return ptr; - } - else if (size < 0) - { - // we don't currently support shrink behavior - return (void *) MFAIL; - } - else - { - return sbrk_top; - } - } - - // cleanup any allocated memory pools - // called as last thing before shutting down driver - - void osCleanupMem(void) - { - void **ptr; - - for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) - if (*ptr) - { - PoolDeallocate(*ptr); - *ptr = 0; - } - } - -*/ - - -/* ----------------------------------------------------------------------- -History: - V2.8.4 (not yet released) - * Add mspace_mmap_large_chunks; thanks to Jean Brouwers - * Fix insufficient sys_alloc padding when using 16byte alignment - * Fix bad error check in mspace_footprint - * Adaptations for ptmalloc, courtesy of Wolfram Gloger. - * Reentrant spin locks, courtesy of Earl Chew and others - * Win32 improvements, courtesy of Niall Douglas and Earl Chew - * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options - * Extension hook in malloc_state - * Various small adjustments to reduce warnings on some compilers - * Various configuration extensions/changes for more platforms. Thanks - to all who contributed these. - - V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) - * Add max_footprint functions - * Ensure all appropriate literals are size_t - * Fix conditional compilation problem for some #define settings - * Avoid concatenating segments with the one provided - in create_mspace_with_base - * Rename some variables to avoid compiler shadowing warnings - * Use explicit lock initialization. - * Better handling of sbrk interference. - * Simplify and fix segment insertion, trimming and mspace_destroy - * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x - * Thanks especially to Dennis Flanagan for help on these. - - V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) - * Fix memalign brace error. - - V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) - * Fix improper #endif nesting in C++ - * Add explicit casts needed for C++ - - V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) - * Use trees for large bins - * Support mspaces - * Use segments to unify sbrk-based and mmap-based system allocation, - removing need for emulation on most platforms without sbrk. - * Default safety checks - * Optional footer checks. Thanks to William Robertson for the idea. - * Internal code refactoring - * Incorporate suggestions and platform-specific changes. - Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, - Aaron Bachmann, Emery Berger, and others. - * Speed up non-fastbin processing enough to remove fastbins. - * Remove useless cfree() to avoid conflicts with other apps. - * Remove internal memcpy, memset. Compilers handle builtins better. - * Remove some options that no one ever used and rename others. - - V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - * Fix malloc_state bitmap array misdeclaration - - V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) - * Allow tuning of FIRST_SORTED_BIN_SIZE - * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. - * Better detection and support for non-contiguousness of MORECORE. - Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger - * Bypass most of malloc if no frees. Thanks To Emery Berger. - * Fix freeing of old top non-contiguous chunk im sysmalloc. - * Raised default trim and map thresholds to 256K. - * Fix mmap-related #defines. Thanks to Lubos Lunak. - * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. - * Branch-free bin calculation - * Default trim and mmap thresholds now 256K. - - V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) - * Introduce independent_comalloc and independent_calloc. - Thanks to Michael Pachos for motivation and help. - * Make optional .h file available - * Allow > 2GB requests on 32bit systems. - * new WIN32 sbrk, mmap, munmap, lock code from . - Thanks also to Andreas Mueller , - and Anonymous. - * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for - helping test this.) - * memalign: check alignment arg - * realloc: don't try to shift chunks backwards, since this - leads to more fragmentation in some programs and doesn't - seem to help in any others. - * Collect all cases in malloc requiring system memory into sysmalloc - * Use mmap as backup to sbrk - * Place all internal state in malloc_state - * Introduce fastbins (although similar to 2.5.1) - * Many minor tunings and cosmetic improvements - * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK - * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS - Thanks to Tony E. Bennett and others. - * Include errno.h to support default failure action. - - V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) - * return null for negative arguments - * Added Several WIN32 cleanups from Martin C. Fong - * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' - (e.g. WIN32 platforms) - * Cleanup header file inclusion for WIN32 platforms - * Cleanup code to avoid Microsoft Visual C++ compiler complaints - * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing - memory allocation routines - * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) - * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to - usage of 'assert' in non-WIN32 code - * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to - avoid infinite loop - * Always call 'fREe()' rather than 'free()' - - V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) - * Fixed ordering problem with boundary-stamping - - V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) - * Added pvalloc, as recommended by H.J. Liu - * Added 64bit pointer support mainly from Wolfram Gloger - * Added anonymously donated WIN32 sbrk emulation - * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen - * malloc_extend_top: fix mask error that caused wastage after - foreign sbrks - * Add linux mremap support code from HJ Liu - - V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) - * Integrated most documentation with the code. - * Add support for mmap, with help from - Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Use last_remainder in more cases. - * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold - * Eliminate block-local decls to simplify tracing and debugging. - * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. - * Rely on page size for units instead of SBRK_UNIT to - avoid surprises about sbrk alignment conventions. - * Add mallinfo, mallopt. Thanks to Raymond Nijssen - (raymond@es.ele.tue.nl) for the suggestion. - * Add `pad' argument to malloc_trim and top_pad mallopt parameter. - * More precautions for cases where other routines call sbrk, - courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Added macros etc., allowing use in linux libc from - H.J. Lu (hjl@gnu.ai.mit.edu) - * Inverted this history list - - V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) - * Re-tuned and fixed to behave more nicely with V2.6.0 changes. - * Removed all preallocation code since under current scheme - the work required to undo bad preallocations exceeds - the work saved in good cases for most test programs. - * No longer use return list or unconsolidated bins since - no scheme using them consistently outperforms those that don't - given above changes. - * Use best fit for very large chunks to prevent some worst-cases. - * Added some support for debugging - - V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) - * Removed footers when chunks are in use. Thanks to - Paul Wilson (wilson@cs.texas.edu) for the suggestion. - - V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) - * Added malloc_trim, with help from Wolfram Gloger - (wmglo@Dent.MED.Uni-Muenchen.DE). - - V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) - - V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) - * realloc: try to expand in both directions - * malloc: swap order of clean-bin strategy; - * realloc: only conditionally expand backwards - * Try not to scavenge used bins - * Use bin counts as a guide to preallocation - * Occasionally bin return list chunks in first scan - * Add a few optimizations from colin@nyx10.cs.du.edu - - V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) - * faster bin computation & slightly different binning - * merged all consolidations to one part of malloc proper - (eliminating old malloc_find_space & malloc_clean_bin) - * Scan 2 returns chunks (not just 1) - * Propagate failure in realloc if malloc returns 0 - * Add stuff to allow compilation on non-ANSI compilers - from kpv@research.att.com - - V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) - * removed potential for odd address access in prev_chunk - * removed dependency on getpagesize.h - * misc cosmetics and a bit more internal documentation - * anticosmetics: mangled names in macros to evade debugger strangeness - * tested on sparc, hp-700, dec-mips, rs6000 - with gcc & native cc (hp, dec only) allowing - Detlefs & Zorn comparison study (in SIGPLAN Notices.) - - Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) - * Based loosely on libg++-1.2X malloc. (It retains some of the overall - structure of old version, but most details differ.) - -*/ - - diff --git a/src/core/util/nedmalloc/nedmalloc.c b/src/core/util/nedmalloc/nedmalloc.c deleted file mode 100644 index 912e65f4..00000000 --- a/src/core/util/nedmalloc/nedmalloc.c +++ /dev/null @@ -1,950 +0,0 @@ -/* Alternative malloc implementation for multiple threads without -lock contention based on dlmalloc. (C) 2005-2006 Niall Douglas - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - -#ifdef _MSC_VER -/* Enable full aliasing on MSVC */ -/*#pragma optimize("a", on)*/ -#endif - -/*#define FULLSANITYCHECKS*/ - -#include "nedmalloc.h" -#ifdef WIN32 - #include -#endif -#define MSPACES 1 -#define ONLY_MSPACES 1 -#ifndef USE_LOCKS - #define USE_LOCKS 1 -#endif -#define FOOTERS 1 /* Need to enable footers so frees lock the right mspace */ -#undef DEBUG /* dlmalloc wants DEBUG either 0 or 1 */ -#ifdef _DEBUG - #define DEBUG 1 -#else - #define DEBUG 0 -#endif -#ifdef NDEBUG /* Disable assert checking on release builds */ - #undef DEBUG -#endif -/* The default of 64Kb means we spend too much time kernel-side */ -#ifndef DEFAULT_GRANULARITY -#define DEFAULT_GRANULARITY (1*1024*1024) -#endif -/*#define USE_SPIN_LOCKS 0*/ - - -/*#define FORCEINLINE*/ -#include "malloc.c.h" -#ifdef NDEBUG /* Disable assert checking on release builds */ - #undef DEBUG -#endif - -/* The maximum concurrent threads in a pool possible */ -#ifndef MAXTHREADSINPOOL -#define MAXTHREADSINPOOL 16 -#endif -/* The maximum number of threadcaches which can be allocated */ -#ifndef THREADCACHEMAXCACHES -#define THREADCACHEMAXCACHES 256 -#endif -/* The maximum size to be allocated from the thread cache */ -#ifndef THREADCACHEMAX -#define THREADCACHEMAX 8192 -#endif -#if 0 -/* The number of cache entries for finer grained bins. This is (topbitpos(THREADCACHEMAX)-4)*2 */ -#define THREADCACHEMAXBINS ((13-4)*2) -#else -/* The number of cache entries. This is (topbitpos(THREADCACHEMAX)-4) */ -#define THREADCACHEMAXBINS (13-4) -#endif -/* Point at which the free space in a thread cache is garbage collected */ -#ifndef THREADCACHEMAXFREESPACE -#define THREADCACHEMAXFREESPACE (512*1024) -#endif - - -#ifdef WIN32 - #define TLSVAR DWORD - #define TLSALLOC(k) (*(k)=TlsAlloc(), TLS_OUT_OF_INDEXES==*(k)) - #define TLSFREE(k) (!TlsFree(k)) - #define TLSGET(k) TlsGetValue(k) - #define TLSSET(k, a) (!TlsSetValue(k, a)) - #ifdef DEBUG -static LPVOID ChkedTlsGetValue(DWORD idx) -{ - LPVOID ret=TlsGetValue(idx); - assert(S_OK==GetLastError()); - return ret; -} - #undef TLSGET - #define TLSGET(k) ChkedTlsGetValue(k) - #endif -#else - #define TLSVAR pthread_key_t - #define TLSALLOC(k) pthread_key_create(k, 0) - #define TLSFREE(k) pthread_key_delete(k) - #define TLSGET(k) pthread_getspecific(k) - #define TLSSET(k, a) pthread_setspecific(k, a) -#endif - -#if 0 -/* Only enable if testing with valgrind. Causes misoperation */ -#define mspace_malloc(p, s) malloc(s) -#define mspace_realloc(p, m, s) realloc(m, s) -#define mspace_calloc(p, n, s) calloc(n, s) -#define mspace_free(p, m) free(m) -#endif - - -#if defined(__cplusplus) -#if !defined(NO_NED_NAMESPACE) -namespace nedalloc { -#else -extern "C" { -#endif -#endif - -size_t nedblksize(void *mem) THROWSPEC -{ -#if 0 - /* Only enable if testing with valgrind. Causes misoperation */ - return THREADCACHEMAX; -#else - if(mem) - { - mchunkptr p=mem2chunk(mem); - assert(cinuse(p)); /* If this fails, someone tried to free a block twice */ - if(cinuse(p)) - return chunksize(p)-overhead_for(p); - } - return 0; -#endif -} - -void nedsetvalue(void *v) THROWSPEC { nedpsetvalue(0, v); } -void * nedmalloc(size_t size) THROWSPEC { return nedpmalloc(0, size); } -void * nedcalloc(size_t no, size_t size) THROWSPEC { return nedpcalloc(0, no, size); } -void * nedrealloc(void *mem, size_t size) THROWSPEC { return nedprealloc(0, mem, size); } -void nedfree(void *mem) THROWSPEC { nedpfree(0, mem); } -void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC { return nedpmemalign(0, alignment, bytes); } -#if !NO_MALLINFO -struct mallinfo nedmallinfo(void) THROWSPEC { return nedpmallinfo(0); } -#endif -int nedmallopt(int parno, int value) THROWSPEC { return nedpmallopt(0, parno, value); } -int nedmalloc_trim(size_t pad) THROWSPEC { return nedpmalloc_trim(0, pad); } -void nedmalloc_stats() THROWSPEC { nedpmalloc_stats(0); } -size_t nedmalloc_footprint() THROWSPEC { return nedpmalloc_footprint(0); } -void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC { return nedpindependent_calloc(0, elemsno, elemsize, chunks); } -void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC { return nedpindependent_comalloc(0, elems, sizes, chunks); } - -struct threadcacheblk_t; -typedef struct threadcacheblk_t threadcacheblk; -struct threadcacheblk_t -{ /* Keep less than 16 bytes on 32 bit systems and 32 bytes on 64 bit systems */ -#ifdef FULLSANITYCHECKS - unsigned int magic; -#endif - unsigned int lastUsed, size; - threadcacheblk *next, *prev; -}; -typedef struct threadcache_t -{ -#ifdef FULLSANITYCHECKS - unsigned int magic1; -#endif - int mymspace; /* Last mspace entry this thread used */ - long threadid; - unsigned int mallocs, frees, successes; - size_t freeInCache; /* How much free space is stored in this cache */ - threadcacheblk *bins[(THREADCACHEMAXBINS+1)*2]; -#ifdef FULLSANITYCHECKS - unsigned int magic2; -#endif -} threadcache; -struct nedpool_t -{ - MLOCK_T mutex; - void *uservalue; - int threads; /* Max entries in m to use */ - threadcache *caches[THREADCACHEMAXCACHES]; - TLSVAR mycache; /* Thread cache for this thread. 0 for unset, negative for use mspace-1 directly, otherwise is cache-1 */ - mstate m[MAXTHREADSINPOOL+1]; /* mspace entries for this pool */ -}; -static nedpool syspool; - -static FORCEINLINE unsigned int size2binidx(size_t _size) THROWSPEC -{ /* 8=1000 16=10000 20=10100 24=11000 32=100000 48=110000 4096=1000000000000 */ - unsigned int topbit, size=(unsigned int)(_size>>4); - /* 16=1 20=1 24=1 32=10 48=11 64=100 96=110 128=1000 4096=100000000 */ - -#if defined(__GNUC__) - topbit = sizeof(size)*__CHAR_BIT__ - 1 - __builtin_clz(size); -#elif defined(_MSC_VER) && _MSC_VER>=1300 - { - unsigned long bsrTopBit; - - _BitScanReverse(&bsrTopBit, size); - - topbit = bsrTopBit; - } -#else -#if 0 - union { - unsigned asInt[2]; - double asDouble; - }; - int n; - - asDouble = (double)size + 0.5; - topbit = (asInt[!FOX_BIGENDIAN] >> 20) - 1023; -#else - { - unsigned int x=size; - x = x | (x >> 1); - x = x | (x >> 2); - x = x | (x >> 4); - x = x | (x >> 8); - x = x | (x >>16); - x = ~x; - x = x - ((x >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0F0F0F0F; - x = x + (x << 8); - x = x + (x << 16); - topbit=31 - (x >> 24); - } -#endif -#endif - return topbit; -} - - -#ifdef FULLSANITYCHECKS -static void tcsanitycheck(threadcacheblk **ptr) THROWSPEC -{ - assert((ptr[0] && ptr[1]) || (!ptr[0] && !ptr[1])); - if(ptr[0] && ptr[1]) - { - assert(nedblksize(ptr[0])>=sizeof(threadcacheblk)); - assert(nedblksize(ptr[1])>=sizeof(threadcacheblk)); - assert(*(unsigned int *) "NEDN"==ptr[0]->magic); - assert(*(unsigned int *) "NEDN"==ptr[1]->magic); - assert(!ptr[0]->prev); - assert(!ptr[1]->next); - if(ptr[0]==ptr[1]) - { - assert(!ptr[0]->next); - assert(!ptr[1]->prev); - } - } -} -static void tcfullsanitycheck(threadcache *tc) THROWSPEC -{ - threadcacheblk **tcbptr=tc->bins; - int n; - for(n=0; n<=THREADCACHEMAXBINS; n++, tcbptr+=2) - { - threadcacheblk *b, *ob=0; - tcsanitycheck(tcbptr); - for(b=tcbptr[0]; b; ob=b, b=b->next) - { - assert(*(unsigned int *) "NEDN"==b->magic); - assert(!ob || ob->next==b); - assert(!ob || b->prev==ob); - } - } -} -#endif - -static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned int age) THROWSPEC -{ -#ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); -#endif - if(tc->freeInCache) - { - threadcacheblk **tcbptr=tc->bins; - int n; - for(n=0; n<=THREADCACHEMAXBINS; n++, tcbptr+=2) - { - threadcacheblk **tcb=tcbptr+1; /* come from oldest end of list */ - /*tcsanitycheck(tcbptr);*/ - for(; *tcb && tc->frees-(*tcb)->lastUsed>=age; ) - { - threadcacheblk *f=*tcb; - size_t blksize=f->size; /*nedblksize(f);*/ - assert(blksize<=nedblksize(f)); - assert(blksize); -#ifdef FULLSANITYCHECKS - assert(*(unsigned int *) "NEDN"==(*tcb)->magic); -#endif - *tcb=(*tcb)->prev; - if(*tcb) - (*tcb)->next=0; - else - *tcbptr=0; - tc->freeInCache-=blksize; - assert((long) tc->freeInCache>=0); - mspace_free(0, f); - /*tcsanitycheck(tcbptr);*/ - } - } - } -#ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); -#endif -} -static void DestroyCaches(nedpool *p) THROWSPEC -{ - if(p->caches) - { - threadcache *tc; - int n; - for(n=0; ncaches[n])) - { - tc->frees++; - RemoveCacheEntries(p, tc, 0); - assert(!tc->freeInCache); - tc->mymspace=-1; - tc->threadid=0; - mspace_free(0, tc); - p->caches[n]=0; - } - } - } -} - -static NOINLINE threadcache *AllocCache(nedpool *p) THROWSPEC -{ - threadcache *tc=0; - int n, end; - ACQUIRE_LOCK(&p->mutex); - for(n=0; ncaches[n]; n++); - if(THREADCACHEMAXCACHES==n) - { /* List exhausted, so disable for this thread */ - RELEASE_LOCK(&p->mutex); - return 0; - } - tc=p->caches[n]=(threadcache *) mspace_calloc(p->m[0], 1, sizeof(threadcache)); - if(!tc) - { - RELEASE_LOCK(&p->mutex); - return 0; - } -#ifdef FULLSANITYCHECKS - tc->magic1=*(unsigned int *)"NEDMALC1"; - tc->magic2=*(unsigned int *)"NEDMALC2"; -#endif - tc->threadid=(long)(size_t)CURRENT_THREAD; - for(end=0; p->m[end]; end++); - tc->mymspace=tc->threadid % end; - RELEASE_LOCK(&p->mutex); - if(TLSSET(p->mycache, (void *)(size_t)(n+1))) abort(); - return tc; -} - -static void *threadcache_malloc(nedpool *p, threadcache *tc, size_t *size) THROWSPEC -{ - void *ret=0; - unsigned int bestsize; - unsigned int idx=size2binidx(*size); - size_t blksize=0; - threadcacheblk *blk, **binsptr; -#ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); -#endif - /* Calculate best fit bin size */ - bestsize=1<<(idx+4); -#if 0 - /* Finer grained bin fit */ - idx<<=1; - if(*size>bestsize) - { - idx++; - bestsize+=bestsize>>1; - } - if(*size>bestsize) - { - idx++; - bestsize=1<<(4+(idx>>1)); - } -#else - if(*size>bestsize) - { - idx++; - bestsize<<=1; - } -#endif - assert(bestsize>=*size); - if(*sizebins[idx*2]; - /* Try to match close, but move up a bin if necessary */ - blk=*binsptr; - if(!blk || blk->size<*size) - { /* Bump it up a bin */ - if(idxsize; /*nedblksize(blk);*/ - assert(nedblksize(blk)>=blksize); - assert(blksize>=*size); - if(blk->next) - blk->next->prev=0; - *binsptr=blk->next; - if(!*binsptr) - binsptr[1]=0; -#ifdef FULLSANITYCHECKS - blk->magic=0; -#endif - assert(binsptr[0]!=blk && binsptr[1]!=blk); - assert(nedblksize(blk)>=sizeof(threadcacheblk) && nedblksize(blk)<=THREADCACHEMAX+CHUNK_OVERHEAD); - /*printf("malloc: %p, %p, %p, %lu\n", p, tc, blk, (long) size);*/ - ret=(void *) blk; - } - ++tc->mallocs; - if(ret) - { - assert(blksize>=*size); - ++tc->successes; - tc->freeInCache-=blksize; - assert((long) tc->freeInCache>=0); - } -#if defined(DEBUG) && 0 - if(!(tc->mallocs & 0xfff)) - { - printf("*** threadcache=%u, mallocs=%u (%f), free=%u (%f), freeInCache=%u\n", (unsigned int) tc->threadid, tc->mallocs, - (float) tc->successes/tc->mallocs, tc->frees, (float) tc->successes/tc->frees, (unsigned int) tc->freeInCache); - } -#endif -#ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); -#endif - return ret; -} -static NOINLINE void ReleaseFreeInCache(nedpool *p, threadcache *tc, int mymspace) THROWSPEC -{ - unsigned int age=THREADCACHEMAXFREESPACE/8192; - /*ACQUIRE_LOCK(&p->m[mymspace]->mutex);*/ - while(age && tc->freeInCache>=THREADCACHEMAXFREESPACE) - { - RemoveCacheEntries(p, tc, age); - /*printf("*** Removing cache entries older than %u (%u)\n", age, (unsigned int) tc->freeInCache);*/ - age>>=1; - } - /*RELEASE_LOCK(&p->m[mymspace]->mutex);*/ -} -static void threadcache_free(nedpool *p, threadcache *tc, int mymspace, void *mem, size_t size) THROWSPEC -{ - unsigned int bestsize; - unsigned int idx=size2binidx(size); - threadcacheblk **binsptr, *tck=(threadcacheblk *) mem; - assert(size>=sizeof(threadcacheblk) && size<=THREADCACHEMAX+CHUNK_OVERHEAD); -#ifdef DEBUG - { /* Make sure this is a valid memory block */ - mchunkptr p = mem2chunk(mem); - mstate fm = get_mstate_for(p); - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } - } -#endif -#ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); -#endif - /* Calculate best fit bin size */ - bestsize=1<<(idx+4); -#if 0 - /* Finer grained bin fit */ - idx<<=1; - if(size>bestsize) - { - unsigned int biggerbestsize=bestsize+bestsize<<1; - if(size>=biggerbestsize) - { - idx++; - bestsize=biggerbestsize; - } - } -#endif - if(bestsize!=size) /* dlmalloc can round up, so we round down to preserve indexing */ - size=bestsize; - binsptr=&tc->bins[idx*2]; - assert(idx<=THREADCACHEMAXBINS); - if(tck==*binsptr) - { - fprintf(stderr, "Attempt to free already freed memory block %p - aborting!\n", tck); - abort(); - } -#ifdef FULLSANITYCHECKS - tck->magic=*(unsigned int *) "NEDN"; -#endif - tck->lastUsed=++tc->frees; - tck->size=(unsigned int) size; - tck->next=*binsptr; - tck->prev=0; - if(tck->next) - tck->next->prev=tck; - else - binsptr[1]=tck; - assert(!*binsptr || (*binsptr)->size==tck->size); - *binsptr=tck; - assert(tck==tc->bins[idx*2]); - assert(tc->bins[idx*2+1]==tck || binsptr[0]->next->prev==tck); - /*printf("free: %p, %p, %p, %lu\n", p, tc, mem, (long) size);*/ - tc->freeInCache+=size; -#ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); -#endif -#if 1 - if(tc->freeInCache>=THREADCACHEMAXFREESPACE) - ReleaseFreeInCache(p, tc, mymspace); -#endif -} - - - - -static NOINLINE int InitPool(nedpool *p, size_t capacity, int threads) THROWSPEC -{ /* threads is -1 for system pool */ - ensure_initialization(); - ACQUIRE_MALLOC_GLOBAL_LOCK(); - if(p->threads) goto done; - if(INITIAL_LOCK(&p->mutex)) goto err; - if(TLSALLOC(&p->mycache)) goto err; - if(!(p->m[0]=(mstate) create_mspace(capacity, 1))) goto err; - p->m[0]->extp=p; - p->threads=(threads<1 || threads>MAXTHREADSINPOOL) ? MAXTHREADSINPOOL : threads; -done: - RELEASE_MALLOC_GLOBAL_LOCK(); - return 1; -err: - if(threads<0) - abort(); /* If you can't allocate for system pool, we're screwed */ - DestroyCaches(p); - if(p->m[0]) - { - destroy_mspace(p->m[0]); - p->m[0]=0; - } - if(p->mycache) - { - if(TLSFREE(p->mycache)) abort(); - p->mycache=0; - } - RELEASE_MALLOC_GLOBAL_LOCK(); - return 0; -} -static NOINLINE mstate FindMSpace(nedpool *p, threadcache *tc, int *lastUsed, size_t size) THROWSPEC -{ /* Gets called when thread's last used mspace is in use. The strategy - is to run through the list of all available mspaces looking for an - unlocked one and if we fail, we create a new one so long as we don't - exceed p->threads */ - int n, end; - for(n=end=*lastUsed+1; p->m[n]; end=++n) - { - if(TRY_LOCK(&p->m[n]->mutex)) goto found; - } - for(n=0; n<*lastUsed && p->m[n]; n++) - { - if(TRY_LOCK(&p->m[n]->mutex)) goto found; - } - if(endthreads) - { - mstate temp; - if(!(temp=(mstate) create_mspace(size, 1))) - goto badexit; - /* Now we're ready to modify the lists, we lock */ - ACQUIRE_LOCK(&p->mutex); - while(p->m[end] && endthreads) - end++; - if(end>=p->threads) - { /* Drat, must destroy it now */ - RELEASE_LOCK(&p->mutex); - destroy_mspace((mspace) temp); - goto badexit; - } - /* We really want to make sure this goes into memory now but we - have to be careful of breaking aliasing rules, so write it twice */ - *((volatile struct malloc_state **) &p->m[end])=p->m[end]=temp; - ACQUIRE_LOCK(&p->m[end]->mutex); - /*printf("Created mspace idx %d\n", end);*/ - RELEASE_LOCK(&p->mutex); - n=end; - goto found; - } - /* Let it lock on the last one it used */ -badexit: - ACQUIRE_LOCK(&p->m[*lastUsed]->mutex); - return p->m[*lastUsed]; -found: - *lastUsed=n; - if(tc) - tc->mymspace=n; - else - { - if(TLSSET(p->mycache, (void *)(size_t)(-(n+1)))) abort(); - } - return p->m[n]; -} - -nedpool *nedcreatepool(size_t capacity, int threads) THROWSPEC -{ - nedpool *ret; - if(!(ret=(nedpool *) nedpcalloc(0, 1, sizeof(nedpool)))) return 0; - if(!InitPool(ret, capacity, threads)) - { - nedpfree(0, ret); - return 0; - } - return ret; -} -void neddestroypool(nedpool *p) THROWSPEC -{ - int n; - ACQUIRE_LOCK(&p->mutex); - DestroyCaches(p); - for(n=0; p->m[n]; n++) - { - destroy_mspace(p->m[n]); - p->m[n]=0; - } - RELEASE_LOCK(&p->mutex); - if(TLSFREE(p->mycache)) abort(); - nedpfree(0, p); -} - -void nedpsetvalue(nedpool *p, void *v) THROWSPEC -{ - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - p->uservalue=v; -} -void *nedgetvalue(nedpool **p, void *mem) THROWSPEC -{ - nedpool *np=0; - mchunkptr mcp=mem2chunk(mem); - mstate fm; - if(!(is_aligned(chunk2mem(mcp))) && mcp->head != FENCEPOST_HEAD) return 0; - if(!cinuse(mcp)) return 0; - if(!next_pinuse(mcp)) return 0; - if(!is_mmapped(mcp) && !pinuse(mcp)) - { - if(next_chunk(prev_chunk(mcp))!=mcp) return 0; - } - fm=get_mstate_for(mcp); - if(!ok_magic(fm)) return 0; - if(!ok_address(fm, mcp)) return 0; - if(!fm->extp) return 0; - np=(nedpool *) fm->extp; - if(p) *p=np; - return np->uservalue; -} - -void neddisablethreadcache(nedpool *p) THROWSPEC -{ - int mycache; - if(!p) - { - p=&syspool; - if(!syspool.threads) InitPool(&syspool, 0, -1); - } - mycache=(int)(size_t) TLSGET(p->mycache); - if(!mycache) - { /* Set to mspace 0 */ - if(TLSSET(p->mycache, (void *)-1)) abort(); - } - else if(mycache>0) - { /* Set to last used mspace */ - threadcache *tc=p->caches[mycache-1]; -#if defined(DEBUG) - printf("Threadcache utilisation: %lf%% in cache with %lf%% lost to other threads\n", - 100.0*tc->successes/tc->mallocs, 100.0*((double) tc->mallocs-tc->frees)/tc->mallocs); -#endif - if(TLSSET(p->mycache, (void *)(size_t)(-tc->mymspace))) abort(); - tc->frees++; - RemoveCacheEntries(p, tc, 0); - assert(!tc->freeInCache); - tc->mymspace=-1; - tc->threadid=0; - mspace_free(0, p->caches[mycache-1]); - p->caches[mycache-1]=0; - } -} - -#define GETMSPACE(m,p,tc,ms,s,action) \ - do \ - { \ - mstate m = GetMSpace((p),(tc),(ms),(s)); \ - action; \ - RELEASE_LOCK(&m->mutex); \ - } while (0) - -static FORCEINLINE mstate GetMSpace(nedpool *p, threadcache *tc, int mymspace, size_t size) THROWSPEC -{ /* Returns a locked and ready for use mspace */ - mstate m=p->m[mymspace]; - assert(m); - if(!TRY_LOCK(&p->m[mymspace]->mutex)) m=FindMSpace(p, tc, &mymspace, size);\ - /*assert(IS_LOCKED(&p->m[mymspace]->mutex));*/ - return m; -} -static FORCEINLINE void GetThreadCache(nedpool **p, threadcache **tc, int *mymspace, size_t *size) THROWSPEC -{ - int mycache; - if(size && *sizemycache); - if(mycache>0) - { - *tc=(*p)->caches[mycache-1]; - *mymspace=(*tc)->mymspace; - } - else if(!mycache) - { - *tc=AllocCache(*p); - if(!*tc) - { /* Disable */ - if(TLSSET((*p)->mycache, (void *)-1)) abort(); - *mymspace=0; - } - else - *mymspace=(*tc)->mymspace; - } - else - { - *tc=0; - *mymspace=-mycache-1; - } - assert(*mymspace>=0); - assert((long)(size_t)CURRENT_THREAD==(*tc)->threadid); -#ifdef FULLSANITYCHECKS - if(*tc) - { - if(*(unsigned int *)"NEDMALC1"!=(*tc)->magic1 || *(unsigned int *)"NEDMALC2"!=(*tc)->magic2) - { - abort(); - } - } -#endif -} - -void * nedpmalloc(nedpool *p, size_t size) THROWSPEC -{ - void *ret=0; - threadcache *tc; - int mymspace; - GetThreadCache(&p, &tc, &mymspace, &size); -#if THREADCACHEMAX - if(tc && size<=THREADCACHEMAX) - { /* Use the thread cache */ - ret=threadcache_malloc(p, tc, &size); - } -#endif - if(!ret) - { /* Use this thread's mspace */ - GETMSPACE(m, p, tc, mymspace, size, - ret=mspace_malloc(m, size)); - } - return ret; -} -void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC -{ - size_t rsize=size*no; - void *ret=0; - threadcache *tc; - int mymspace; - GetThreadCache(&p, &tc, &mymspace, &rsize); -#if THREADCACHEMAX - if(tc && rsize<=THREADCACHEMAX) - { /* Use the thread cache */ - if((ret=threadcache_malloc(p, tc, &rsize))) - memset(ret, 0, rsize); - } -#endif - if(!ret) - { /* Use this thread's mspace */ - GETMSPACE(m, p, tc, mymspace, rsize, - ret=mspace_calloc(m, 1, rsize)); - } - return ret; -} -void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPEC -{ - void *ret=0; - threadcache *tc; - int mymspace; - if(!mem) return nedpmalloc(p, size); - GetThreadCache(&p, &tc, &mymspace, &size); -#if THREADCACHEMAX - if(tc && size && size<=THREADCACHEMAX) - { /* Use the thread cache */ - size_t memsize=nedblksize(mem); - assert(memsize); - if((ret=threadcache_malloc(p, tc, &size))) - { - memcpy(ret, mem, memsizem[n]; n++) - { - struct mallinfo t=mspace_mallinfo(p->m[n]); - ret.arena+=t.arena; - ret.ordblks+=t.ordblks; - ret.hblkhd+=t.hblkhd; - ret.usmblks+=t.usmblks; - ret.uordblks+=t.uordblks; - ret.fordblks+=t.fordblks; - ret.keepcost+=t.keepcost; - } - return ret; -} -#endif -int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC -{ - return mspace_mallopt(parno, value); -} -int nedpmalloc_trim(nedpool *p, size_t pad) THROWSPEC -{ - int n, ret=0; - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - for(n=0; p->m[n]; n++) - { - ret+=mspace_trim(p->m[n], pad); - } - return ret; -} -void nedpmalloc_stats(nedpool *p) THROWSPEC -{ - int n; - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - for(n=0; p->m[n]; n++) - { - mspace_malloc_stats(p->m[n]); - } -} -size_t nedpmalloc_footprint(nedpool *p) THROWSPEC -{ - size_t ret=0; - int n; - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - for(n=0; p->m[n]; n++) - { - ret+=mspace_footprint(p->m[n]); - } - return ret; -} -void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_t elemsize, void **chunks) THROWSPEC -{ - void **ret; - threadcache *tc; - int mymspace; - GetThreadCache(&p, &tc, &mymspace, &elemsize); - GETMSPACE(m, p, tc, mymspace, elemsno*elemsize, - ret=mspace_independent_calloc(m, elemsno, elemsize, chunks)); - return ret; -} -void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC -{ - void **ret; - threadcache *tc; - int mymspace; - size_t i, *adjustedsizes=(size_t *) alloca(elems*sizeof(size_t)); - if(!adjustedsizes) return 0; - for(i=0; i /* for size_t */ - -#ifndef EXTSPEC - #define EXTSPEC extern -#endif - -#if defined(_MSC_VER) && _MSC_VER>=1400 - #define MALLOCATTR __declspec(restrict) -#endif -#ifdef __GNUC__ - #define MALLOCATTR __attribute__ ((malloc)) -#endif -#ifndef MALLOCATTR - #define MALLOCATTR -#endif - -#ifdef REPLACE_SYSTEM_ALLOCATOR - #define nedmalloc malloc - #define nedcalloc calloc - #define nedrealloc realloc - #define nedfree free - #define nedmemalign memalign - #define nedmallinfo mallinfo - #define nedmallopt mallopt - #define nedmalloc_trim malloc_trim - #define nedmalloc_stats malloc_stats - #define nedmalloc_footprint malloc_footprint - #define nedindependent_calloc independent_calloc - #define nedindependent_comalloc independent_comalloc - #ifdef _MSC_VER - #define nedblksize _msize - #endif -#endif - -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif - -#if !NO_MALLINFO -struct mallinfo; -#endif - -#if defined(__cplusplus) - #if !defined(NO_NED_NAMESPACE) -namespace nedalloc { - #else -extern "C" { - #endif - #define THROWSPEC throw() -#else - #define THROWSPEC -#endif - -/* These are the global functions */ - -/* Gets the usable size of an allocated block. Note this will always be bigger than what was -asked for due to rounding etc. -*/ -EXTSPEC size_t nedblksize(void *mem) THROWSPEC; - -EXTSPEC void nedsetvalue(void *v) THROWSPEC; - -EXTSPEC MALLOCATTR void * nedmalloc(size_t size) THROWSPEC; -EXTSPEC MALLOCATTR void * nedcalloc(size_t no, size_t size) THROWSPEC; -EXTSPEC MALLOCATTR void * nedrealloc(void *mem, size_t size) THROWSPEC; -EXTSPEC void nedfree(void *mem) THROWSPEC; -EXTSPEC MALLOCATTR void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC; -#if !NO_MALLINFO -EXTSPEC struct mallinfo nedmallinfo(void) THROWSPEC; -#endif -EXTSPEC int nedmallopt(int parno, int value) THROWSPEC; -EXTSPEC int nedmalloc_trim(size_t pad) THROWSPEC; -EXTSPEC void nedmalloc_stats(void) THROWSPEC; -EXTSPEC size_t nedmalloc_footprint(void) THROWSPEC; -EXTSPEC MALLOCATTR void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC; -EXTSPEC MALLOCATTR void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC; - -/* These are the pool functions */ -struct nedpool_t; -typedef struct nedpool_t nedpool; - -/* Creates a memory pool for use with the nedp* functions below. -Capacity is how much to allocate immediately (if you know you'll be allocating a lot -of memory very soon) which you can leave at zero. Threads specifies how many threads -will *normally* be accessing the pool concurrently. Setting this to zero means it -extends on demand, but be careful of this as it can rapidly consume system resources -where bursts of concurrent threads use a pool at once. -*/ -EXTSPEC MALLOCATTR nedpool *nedcreatepool(size_t capacity, int threads) THROWSPEC; - -/* Destroys a memory pool previously created by nedcreatepool(). -*/ -EXTSPEC void neddestroypool(nedpool *p) THROWSPEC; - -/* Sets a value to be associated with a pool. You can retrieve this value by passing -any memory block allocated from that pool. -*/ -EXTSPEC void nedpsetvalue(nedpool *p, void *v) THROWSPEC; -/* Gets a previously set value using nedpsetvalue() or zero if memory is unknown. -Optionally can also retrieve pool. -*/ -EXTSPEC void *nedgetvalue(nedpool **p, void *mem) THROWSPEC; - -/* Disables the thread cache for the calling thread, returning any existing cache -data to the central pool. -*/ -EXTSPEC void neddisablethreadcache(nedpool *p) THROWSPEC; - -EXTSPEC MALLOCATTR void * nedpmalloc(nedpool *p, size_t size) THROWSPEC; -EXTSPEC MALLOCATTR void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC; -EXTSPEC MALLOCATTR void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPEC; -EXTSPEC void nedpfree(nedpool *p, void *mem) THROWSPEC; -EXTSPEC MALLOCATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes) THROWSPEC; -#if !NO_MALLINFO -EXTSPEC struct mallinfo nedpmallinfo(nedpool *p) THROWSPEC; -#endif -EXTSPEC int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC; -EXTSPEC int nedpmalloc_trim(nedpool *p, size_t pad) THROWSPEC; -EXTSPEC void nedpmalloc_stats(nedpool *p) THROWSPEC; -EXTSPEC size_t nedpmalloc_footprint(nedpool *p) THROWSPEC; -EXTSPEC MALLOCATTR void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_t elemsize, void **chunks) THROWSPEC; -EXTSPEC MALLOCATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC; - -#if defined(__cplusplus) -} -#endif - -#undef MALLOCATTR -#undef EXTSPEC - -#endif diff --git a/src/demo/CMakeLists.txt b/src/demo/CMakeLists.txt index 8c848e35..642df8e6 100644 --- a/src/demo/CMakeLists.txt +++ b/src/demo/CMakeLists.txt @@ -1,30 +1,39 @@ project(lucene++-demo) -#################################### -# THE lucene++demo applications -#################################### -file(GLOB_RECURSE HEADERS ${lucene++-demo_SOURCE_DIR}/../include/*.h) -ADD_DEFINITIONS(-DLPP_HAVE_DLL) -INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(${lucene++-base_SOURCE_DIR}/include) - -ADD_EXECUTABLE(indexfiles EXCLUDE_FROM_ALL - ${lucene++-demo_SOURCE_DIR}/indexfiles/main.cpp ${HEADERS} +file(GLOB_RECURSE + demo_headers + ${lucene++-demo_SOURCE_DIR}/../include/*.h ) -TARGET_LINK_LIBRARIES(indexfiles lucene++) -ADD_EXECUTABLE(searchfiles EXCLUDE_FROM_ALL - ${lucene++-demo_SOURCE_DIR}/searchfiles/main.cpp ${HEADERS} +add_definitions(-DLPP_HAVE_DLL) + +include_directories( + ${Boost_INCLUDE_DIRS} +) +include_directories( + ${lucene++_SOURCE_DIR}/include ) -TARGET_LINK_LIBRARIES(searchfiles lucene++) -ADD_EXECUTABLE(deletefiles EXCLUDE_FROM_ALL - ${lucene++-demo_SOURCE_DIR}/deletefiles/main.cpp ${HEADERS} +add_executable(indexfiles + ${lucene++-demo_SOURCE_DIR}/indexfiles/main.cpp + ${demo_headers} +) +target_link_libraries(indexfiles + lucene++ ) -TARGET_LINK_LIBRARIES(deletefiles lucene++) -ADD_CUSTOM_TARGET( - demo - DEPENDS indexfiles searchfiles deletefiles +add_executable(searchfiles + ${lucene++-demo_SOURCE_DIR}/searchfiles/main.cpp + ${demo_headers} +) +target_link_libraries(searchfiles + lucene++ ) +add_executable(deletefiles + ${lucene++-demo_SOURCE_DIR}/deletefiles/main.cpp + ${demo_headers} +) +target_link_libraries(deletefiles + lucene++ +) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index b1e2a28f..f2b8445c 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,37 +1,44 @@ project(lucene++-tester) -#################################### -# THE lucene++tester library -#################################### -file(GLOB_RECURSE lucene_sources - ${lucene++-tester_SOURCE_DIR}/*.cpp) -file(GLOB_RECURSE HEADERS ${lucene++-tester_SOURCE_DIR}/../include/*.h) -file(GLOB_RECURSE HEADERS ${lucene++-tester_SOURCE_DIR}/include/*.h) +file(GLOB_RECURSE tester_sources + analysis/*.cpp + contrib/*.cpp + document/*.cpp + index/*.cpp + main/*.cpp + queryparser/*.cpp + search/*.cpp + store/*.cpp + util/*.cpp +) -LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) -INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(${lucene++-base_SOURCE_DIR}/include) -INCLUDE_DIRECTORIES(${lucene++-lib_SOURCE_DIR}/include) -INCLUDE_DIRECTORIES(${lucene++-contrib_SOURCE_DIR}/include) -INCLUDE_DIRECTORIES(${lucene++-tester_SOURCE_DIR}/include) -ADD_DEFINITIONS(-DLPP_EXPOSE_INTERNAL) +file(GLOB_RECURSE test_headers + ${lucene++-tester_SOURCE_DIR}/../include/*.h + ${lucene++-tester_SOURCE_DIR}/include/*.h +) -ADD_EXECUTABLE(lucene++-tester EXCLUDE_FROM_ALL - ${lucene_sources} ${HEADERS} +include_directories( + ${lucene++_SOURCE_DIR}/include + ${lucene++-lib_SOURCE_DIR}/include + ${lucene++-contrib_SOURCE_DIR}/include + ${lucene++-tester_SOURCE_DIR}/include + ${Boost_INCLUDE_DIRS} ) -#set properties on the libraries -SET_TARGET_PROPERTIES(lucene++-tester PROPERTIES - VERSION ${LUCENE++_VERSION} - SOVERSION ${LUCENE++_SOVERSION} +add_definitions(-DLPP_EXPOSE_INTERNAL) + +add_executable(lucene++-tester + ${tester_sources} + ${test_headers} ) -TARGET_LINK_LIBRARIES(lucene++-tester - lucene++-static - lucene++-c - lucene++-contrib-static - ${CMAKE_THREAD_LIBS_INIT} - ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE} - ${LUCENE_BOOST_LIBS} ) -ADD_TEST(lucene++-tester ${EXECUTABLE_OUTPUT_PATH}/lucene++-tester -p --test_dir=${lucene++-tester_SOURCE_DIR}/testfiles) +target_link_libraries(lucene++-tester + ${CMAKE_THREAD_LIBS_INIT} + lucene++ + lucene++-contrib + ${lucene_boost_libs} +) +add_test(lucene++-tester + ${EXECUTABLE_OUTPUT_PATH}/lucene++-tester -p --test_dir=${lucene++-tester_SOURCE_DIR}/testfiles +) diff --git a/waf b/waf deleted file mode 100755 index 73ad1d5d64bbeb633b015419b723402e0e931fa7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76812 zcmcG#by!sI)&`7}AY7D!Gy_8n2uMpy!_eIgLpMX0gmjmrG)Ol{i%3hCfPjcdcZc}x zLC^1;^S zw|21P2SL@8czL<`SlEG4bt^}E6IYO;iKQ1ah=Yxdn}vgoo$b*h8XB5MsxWhFSGbF{ zsT|t>JM~~Q9LH})%E6CB}U$y|w0qfjc;UE_n+yt-@A<)Fs(H#Z|bMkVrwzPsj z0)apdj&N%;7&9!U{;|Jw#Y*METUFB<^w z%-sNt{(mq75dlCf!W(l(GdFvf1N>i0Qqr zaMyc_0HyB0N(*4_56G^L7H|(l6cOqHQh;2YU}gwb0Q;;FTya70!Ql@xTwQ^n1171< zK-EBMN>b`tqN!PM)uEDV%pjcBE} zCFXmyv`2D}& zKvgBh)tMhb760BL%m*+4tdM60sVPf}LlHNU+LC~$qN+N~fY%^#B}Fw!6%Ak!FbR?n zRS=byRC@&Z|8N{YS6o9?QUPHZ;H{d5n3_6NT|-?GB(0<*aSx}Oq^c%VTvAN{B(H=3 zSPG<}CdmwFP#3*d42S>#0j2>X#5B~P_s~EU)g@I`HI&t%N{Wn+WR$c3=K&i(SCdmjy1PWLt4M2LYR!bDn3Ge{Wi{KPs)t}q{;2wZ4 z5HAo^3M49_3CI9UzF+(Zh_D*;FB^a%H4Sl@zi_kOXU|90_D+s2KzaevqN|tdqep<} zY5)vEH0-QAtZYDfl?3G75AbmCSiFGony|5(oAa8moAGd&allMX*m&8wO<%m=GobdW?g18@YGJ#vMB3?dv z1n^l(h{40eg5i-l%mQQz@nqzGgbCzIHx~zx=Ob$%k$SnZTERTsVJ?U>D9q-`$%go{ z0G9o0FDJtz%>UT^&vw@P;sOJ7-wTJixIpX?;(-J10Ea*r^w~H$_4wHBC0$$`UHCzC zuJ;3M_6#68kUb;gBTR&Dn5Q)y!v0r;n}d^ynXM6Euer4g1o%OSvp{&|1ap8OmYcX( zy6dqSFf+KAG5`|HfH?*;M;8}2Cpb`O%&dSc1cK0+GXf@iSXtY_KWLBVBASw)^P612o ztnc+BWc(2>1c1u`77`NHcVIwRjfn~Og#T}y|56G}{?Ta$fC0Dr-2~qKOzN% zgziP&TZmZAalhIWaK-k~|0#|WSnx+V@LP|apM~83aNNnx#0&;8g^05=G9zq72xa`w zagM*^F2MLBK=L0VyIKK#fE`ddOW+?ft_;i|2AC(@#l)4t;2tf2%JwFK}H_XtdZ3qm(QayZN$!eHv=;BD>1 z0s5mDSp9#9VSppf05I{_M!>$m5dBNqA5VY;@n_xtTj>6^?SBUEFTPp;c4mJtHU(OO z`$GydX9k&B!OU!dat}0eruW9Wx;fovKcLBSa)G%5EeZ_+(tm;va2^hvcp&U%a3B@^ zH(39y`hTIwePDpr@((@!VTLC_TP{9;^8jW4XF3!7&vbU5ZV|71;^qJ(09yzU1Hhku$a4?*ANC`N1*mj$uts#N ze|c?hYUYXv-XBKugZ}%lAi5|sxR(>m74+8(pg%UZvjfcdbHi#2b8&##adNP#!QfKB zxfF%}Y1v_}T7NVkvczBEz^;4o_gNYabA{hi8=%Nv+96m6^pgL_u|u4>f2Dh1)qPXfc6MT@guMtv{)f0fr{v$e07cGjKxT3M zTPQ#*!XTLE{lWNSm(cS+H3c95P+9+Y4d`H?b7i^zMifX0u#_3}w|ig){i|&N)FaM` z^?fS++aEA9Al~~i{JA{0b2KxtL%eWwg8#{_|JZL0Fr48z5RvB$z};WP|A#~W!UrMg z-ax>(`vZdjfEjdOh=Fnf2Q0Bilqm*)l$;z4_wS+@SQ!v+5&+!)OT|An09pZ!{{ull z;h(JX2=jlp0RQwWz}82PfY<<6z@UG#>k*A${E1e@rJ)1+(PxnN)Klus|Y z8E~tPgzL>2ShPh}I@#($Gnm@ME4r(tozGa+`B@ik-mWc5Hbn}NHSF}amlRcZj`1vK z9rzs`_$eGX3TJ*JTe$F;6F!Io9lSk=T7VvK?tDA2WN))yast$X=^xZEzRF?HeTXEm zn73$$@?(3Kv-4+IwU!6l^@B}!d!I(HswH=%)3YCps!uC5wi4geBRxP8QKlA4d`H=U zq*}B&jS7Z5UG`h|UKm_4T(WUEaO-IM`XhpAFTTjFWLfZLtm=GBW9l>4O?^te`|#8# z&&|)R&Gn_ugSYk5B|Zm22dyh!?Q_{vZRJ`^o63yem6IjF5af_^;pB?t_6sb{peVO- zC52+u$4kqV8=wbbn9{j;a9q7F_HT#b9v=E>xrYl|r6OPmdQ*&Cy`BwjCdz?}^SdC+ zuba4@-6K2B=lj?Z4jI0VnR5I$eeX0Y*)xSkS}&@F);vc`vNwEo)Qv29-)<~5o!J)b z_<0(fEq$$R9i_bRq3~J?Yl$=m(|0yQS6n-TcYeI6*Ka)~#pQW!HWsN>!fe2IPw#SM1Sk8*pq}wHW?xgN;)j-VoQpJVvLECyv>p|&-!PC1=cv*IwHWZ~M;v3%|@UirUWp<*9}0&bBYdhUj4WnsN7@ z<&Ag3x))Xbqr|NvDg7-TCDCuUvF8=K16AhqF*#ymcKa?mHpDyj{g$N-FJ8Ru?9bg5 zYM$%Zzi4as;5&}K8S}lEx3hYXH;Y$Rwbn9w;J)HW>+Sp1!v9qhpp^ zmux<)Va`KI0oQJ1Z~vs@1m2F^9+;$FI#anrCYqt}-lfgsc~j?Ei^^iXf!)G^w)=Rb zk|pnuYSvOq6VVIzVf~R(9qzL!#aRKr73l$w&KvvHOe*hB9rfxnwvr9wL1X5N^Jk+z zQ5|C?K7K=Og<91H`)#wKVPi&QJqmcJ$X3W!NFrABc*w?5BGcySNoooV?>Ov5!1Q2x zt|_S)u1^FRsGuM#Jg^931LIb{31WgiT|R>{FC%a>G%)x6%*M-v;{{@8U?$;Nb8$1g z6XJfUoZ&5+7ZGkHB+d<{zh6V(T|^s^pd>Q+7EK7OAS5pp8u|+T6%vZb{VWnv1Pv;Z z2xbVf`P(FV1+W4)r&JP?|C7ULH7@yF?+l*Y2L&QXq^KF;L8wR|R4cWK;uuW9C#NM1 z>5px^AB&jBkwT{AkxhujK}h{QyDN8bTQg;b&v^q(7yFqthBel32S7M%n=|=z*edE@ zK~Gg2%C=Ce-nj49n;B?&FKW(Qd_KGp11=K0Ei!DY^pFBa=QTOwNqV6^YDGWFnx6a1trQ zCy*e)k2lAFFdz+mrlEN+D$;@lhDeH@cY`6Q%CErm1!Cg%8X9Mfx=rIER-$YwPm+VI zqB#nPR67V;q)#+tQrm_eA}gO7AA^PW?xVTH6sj6g?jjaP2s9Cm zho+bLOTMTm^W+4`Mh3MeUKd@8lLZ}*h7M$sZYIS^Z>Rk#1j|AaLo%2)0mg|wlB7Tr zBQK@~hD5|GSPUklCW@rX0t8MpA4yW-=+mx~C84k7ipaN{r>8AWhelYX*UHC4H;phB z)9Xkw=W}J!%fAjLh)hnhNTDrEB2kDzhJhg>ku)4CvIAcRD?$eB>dZfxbJ3d0EXeE8 zrWMd}v2dD6A*a%Rv}5a4<;Y8rPwV3#RppROm6@FE3)Q5ZjKDYLrhmc&>VtwI*5M-D z59n(X88d?V`ou&+(#>hW=Cu;zqN-r)x-WzIk7?=XsKXbYK{-`&W9Z})*y!HLT628L zRAVeswa!S0PmGQaZ(yrQK%z@PhlViOS1jsrN;QOQ^VqQ$_VLI;>Mb;(?8PQUL8TGV zs?(~Uxk)S!QO`JF7D=?agS7Qh(+Uh^-K#?RVu~@)s4S!=@EwNGWC7PpH3?*OcKq@q+?Nl)~ebJs_2y3H`&`w zkTTPAi|9n8TPxFXsLvOZ(b(6UY7a)H$5a$1YNm6@e*Ro9%au~94s8lorBRn!u(4)I zuQ499`VuMynWCmiLnl#zK~(EBNSN~@ZFt1`Lu1k#~ zo-oc+Rnd7+X9FeX;Uu262(e3>rLn3fN;8);e^+Qrosr5|tdP(EBei-4ea#bXoiSvp zYB4Co{JBA;kw}vHbF!*Ey4Aphx$L|ojKjjBP?Z$>lZ1H%3M^8YK3~1ZOwxElr8c}k zgE5a@95N`=fNhnQ5jiBvsFEv7TPi;i`J~v+s>Yr$rj924b(9$~?Q|y8!t}|&gk+RF zomJn&6MMQ0G6_3U`J!?jFvR{zD%i|?;xShShj}5CI)c!Oh10w@%|>3nl!KHdg3G?a zG(9Fshs8uUDrB%f|yy1 zlcfkhyi|^iuwXI4SnIHpG$~5MSbZKQt^b3)dM16~Bw)m9^3Oo_)F~;*!;mXEo#X1cm=_<63 zxf6q}xiZak%~pPiUmH}{U0_WuwBE+y--hDuaFvsZ(?(a^X)*^4-o`J2>8YAne#D1e z_)OlSEA4ZjY+Ny6s)Ol;CVAFVSY5yn13anJGKrU?r@yi<98Wt2?=AwH&sMdweEAN; zu3SuJw92BkUxT)>7gzMUJ~0rHCd557w2qmbn4MFi*V+leC4aA(@io{IM*zj;sAVnw z`R3K+32Q6V$D=u_LPNV3V_x-1kS8}<)C*ZH*-BCcQZ{uKx(FFG&R<-=rLx~(il?X( z!poGSsLMU1VhPO9o9QGb-c@MK@oD*0oqLN|e%!f;`&N0vvfK53>9MMrUtiVZ{Z_6g zdDSh4C+*YKHO!m07C^?|{*f_jc#?$~8vt-HCZFh7vP`&FlYZ0#EDceSlWoHAU5Yo5!rfsie& z^>WAR7vE(2v};WVi4-zSdxgtNTgi$HNDYvD?HX2-sOQ|Q-n(q4u046eP9lS@ZCw~H zBL$|9-a>`K8b>KEmtoUYb)9E=aK@P8pBV?Y}Yo5f-!cJ zW=2Vg^vHORf1`x`i1_kQ2yKeMw?SQi>nl0A@ej;(>SCfb?kP!orwMMf6IGC7&NKi1 zDH?&zA9=kr3ej(G+>)!60^aC;YNUyk>8b|JZ-kgNsZW|sfq2hn9LAXmqYE?mH55)D zHs!y~?rv-sG=%GToIOAH&?(fIoc%h_9VDZwjdUOpDP$@)XB=kK>E9_=nTgk?tYsKR zL-nzF!$m=?c~ zCmL&eI~qOlB*~ApPk=3>kcEbJxkDl6L7{sYz6|)GY*=+FD;ADCBLjV-EVvObFOr5G z?J1a^e?rc#+Ws+owp1SUd7On?J>Ok}Q*aZ@&#rJHQuTWgMnR?NR>QK47uRE2;}z7v zpYJ0B*W)3-YE+i#5JbTnMFZ8$HwFNT^8hXXT5M7Zkha`O`bI!D9K)=wnMZ{_i| zEfaXHzYx^9%tG}kJ7}KqTHFl7Nb9-dswzeo9Ojx|>rZS;YGr!{bf~6Bmmm1AV!RE9k4c_~3d`sbs=)Gu8i}3Qit`Vss$&^YRvFr1( z-ofoxXQZ;M3L`6Y_Sij!N;B-W4r%?adwToWx~O`dZqK%HrmCq7F7*i{ z!n-@e8Oh2Sb#OYd?y}q0?a>E>6A!Ng8D2PlY31 zH=xFUdmKA>L``z$vuf0{A~%;t8Ne)+M&dFo5LdSv{nN*tL(b}aT&F-REqA`q%m$~W zuexv;9C_O|5v-(itgSsykY85zW-#w!_JzERcD$4#m|j;oNHw24o^0@-j0828{W=|s z`j~S?tD}7T*$aaatI0B((Y|=b_1pBWo%0DliV&=8*2Nvko$Y*c$yl+-s+)$UFKRYp zx^6^%zXO%zZyOr2f5Z!G&Ezyof9y?s-bv%S{Mu+O0ORnzwq!qEZuH=g;(AYJP=gl2hpq2eb3zFx>^T^~qCuc!pv%)&+KK`GB`>8q--u!Gk+dSA07k&z}JqRS`3@&66x3W4Moqv71 zEBpdC$5p#L_)^dvA55?0A)iMvn2^04#4)Dnw`Q4YTheUneB8bUrpI7(KeT)@*-YJ%5}t0Ir)7v1^Y8zvG2vZQ+>gh=nqqt(kf-A z(D$0s;FFbg+oyio3S6%rpm=B6GIl#xq^ zIb*WR36AL)JIPX^O-}TRmvYO7sb~<-z@gpigHGB_cv={-Z`v5_4*CG=3}0f{M+lkW z9I^J{V}b{GJ-1);*@~T53>Fk2e_nc6xe_3DspZ}VE?Rh_sM`GN3zp3n_#WQGHG9BX zs_E8?n*!1un8t0b+-I!S!_D>>9`7vPv={+~K2%GxrA_+7eTs>gM7>WFl~C)N!7OQi z#?Cw3({tbYSFn|w4B@sa zSi~fGN-#70%`2h90{COe%h$tYV0xA2VbM~%naQ1<(~*oWTSFn?E(=9$v?nX0*h&^f z`baAJZw4fm&vTo`)RK^CTt+KCOt&xF44ee-zoEDCG#YT59x{&>m|S%V+sfY1b5>m> zvmv=~?~yAMcEB_O(=Yi^g!h3l*kWS%^1ihwmWmt^K(R>UN?5&r-I@y-oMyg$y&YN5 z?&YAq?fb>T&_s3g;Cb z?%eZNC(AKo*z=(i(b}mLG}pw% zDH~tHNLmZfd(*k*{J%u@6r6v#jK%x-{7DSM6y3AvpW}{R!c&J~Va=r|C%iYVg3W7Q z7yFuE`t%l`!}1m-9x1ay@R4=OFvcA@O z12|#P)kX<^J6S@@jqon60+yyao)OlwY=v|$#lG>)lt{g-$(AXjDE`Ol#Ucq0cdWLe zs2Zz`D1Dz+fGsDCj!dfyYO)wfrM2e+g38?@!&il~CwKRl@L^%SX#9ynR*^~}Beq5M zjAxUxv(+RoS*ySNnzQ)qJrzWGI|Ipp_a?~c&)|}3%-8nLfi}g#tTlVRv z1!gp9K%-O2)paVFyK(3X?6Otfc2rQqiI5%h+4Ed-kk1PVNdf!hF(@Yi= zQ|ua+6y2YisJyGOudb@EvFQHGA?+&>OnF2d8||r7Yw!)y=@@b0jz&_LTd0atZ^j_) zVV-T6?JbT`&*E(!k})z8Ljl&q3SJ$>Ja2~T2 ziQ#f3yZ3a+k#Vi0aS-H#cAX>J{5Xhu2C z3I+CpmG#I~9g_KJ&YP}qce;I)CCA6A%b2b(8M$iFSt9|h>hp<|5R+#MSVlNiT1hv? z2e?&c9`KK!1u-e!szkqJb&IZUsx9Tnc-o`nVDYl*x`(0Dy+r4Y<y@-^_4&zat{8dmF<{|9z#(-C>tmle8)WaVm9j+A0alpmS8dP5; z(_ywtb-QME*!2!cwx?KOZ<&k?d#JWGeGNX|otyq0!a{GH8<6#c6BUE>bHl!QA(w(@<6%m`HaI`|GTcI*miMs)aKzL;U6w0 zS8lDg&(~o%P9uD(0>;HxnAyUbOgI#Gj@Nfp!W1P8vG)G!gOw;QyrnbBd3_-$sq(SO zpz_)X3nr!l`;BL(Oxs`pTiZJB569nZDYyOU)c?>|Q?Z5PhKXjMG*!O-?=_uo(Gkj6%}px(}r^ zcTFkIL4*sBQs(KeQ)%-Xd3as3X@Y63Q(AC=aSbH+I&1HFtTbA#a}NGYYGrcDx=h*k zc;u4wFKoW#6D{smA1^zQ-c?k5BBAaOJjAB+b;2@AR}&_P33fIXPZmwqCltbN>p2bM z_1%{ow5#7)1%cUWZinC0EiElx^N-HQfa%?}x}ZCEjUG~MSfOa-m~@U~)cw!vXEJ}W zK)y~&d|g)Z2*BY3Lqw@Mp1{Yx7y0|=7GUu=S}d&g;OBk4c_o7O)@1Vm(&G&Yp|Wtc z-MgB=S1qI-!Q)pPRq4lU1PXxk;*E;C))3B?~?Av z9|%Mu=Q0luq@OtT37Z-0{snOp4)}RTH>SzFkvAZPd>vcIrP8{QeUd2i2^|cvxnoWq ztDgBK@P2n@=eD&XJKiJoX%u=1(yIUmiaprVeVb`s>_AAc*;~w@c4m4p7z~Eo6#o#r zjAR>su2wmX7nOV0*@t}XUYvjU>1h=8le;C~Z^n<=L~f^V8v)73EO!pNd*$DKJ*?l% zU)M|_^~?S4{vGq#^eP_hX3d;)ETX?jx*X>u5xxF(Fmx85^*q7O_u$|qjc8`TiEzL> zzt|Y|tEEv4Ih6fK3F9w*hMH6rqbDURX2&H?Ee~D&B8f;|kIFPz2!K`!Ry}^P`d)Z9 z=>A$zFkp8R9&vPg9JjY?f=Y|28HdTBSNofJeJCCbDN}P6L5?xKa6}(bDMMl7^Wm+~ z=f##VH?8HvJ6>M8KKr>?^~OUw)q^5^+V3Y(PD9NH0XxO28v%LHJg9sJjoD(Ub#^@Qr8R(z6R8)Q4kK#bFw$ zM-dWtR5H`+jIr8vyoqe>h3q6?dix;4=RT0&bPX67PFp~Jb8*Q#fX`DZLqoHp0h0(P z)B0HsJgT4PWXl;+Ouzbh?s7(#zCXciazhyOYBZW6%WOXmoGlTEd`SbT21Q#@5Hrc8 zKG7#h_qU}?5Y3psF0V0lScL>cE!aYwUjzv1?8fL_{3gj8aKZqK`nskHU6QVm8v{G| zo3bHXe|!ldA;&UABbt#Zkkrx=KL2n&QTciL-CdZ+Do95yYnr#)`6b~$f_ zU)9!7r+*>M9G??f-HcqlknS@>J}JYJ8ow z;A37;%e>h89u1pA@;7fmb_1t2N&&+k;ooe_$eB9ii_z6ka$B`x->gg#)`8E3CsX6NcTZu@5B%hX`o(uir0kn#Oa69lM!);7XUZsMOupt2IZVF=gP_tjWV3 z#)~9I`e3C`j?%V0aQbE#)JWK-rC3$*m9MBod`+s4*koi&nTsI* zkM@v-7zzqlKL&ao)nM(f!Fyk0JJLx7jL&xVKDJ&+dGjgnl#~;u=jgd|(8R_1zE3=f z#jvtEabCUk!d3hrIXAC4j8vEL;Z|5g7OVxcLgPAOWlokhJF^cD-jh#tk%BqQRu2k#*cLFUzoA9{IM5FI zAcEmMUTU0j$mNu`yi`ZZB~BKXdKX!r{j;I@hxCsRyqHK8Kz4h|X)xn8M{D(Ie|^L$ zvTmYZV}*k0(rd@-+}Usb+E@DPs0e%p13@@R2z3#W*}#FZT~6 zst$_8vczMCB!eToByxl%6*oQB$^#DdZltEkT;kl_)c50STnkwb^I~=JTjL(wnKDjLQ|~l_^V8r ziXcO4BYdp>7j}(BKA+x#FO9~Kd{m0`s-NodCWS@`iVoS9%dbF4%CG~?KX*0skT8ph zsLW|T9p!*qwBM}E2hS|uk%#EIQ@OsxC?n^}`b{o@Oafx%8+@(dARV%v_i6g3y!hQf zT0*SOdNUz`Rpqir?jU!mxQbK={ce*aYHhCYLNY||ZDHxEbdAm}+B0_^yA&Qz~$hwdi z(%tQzOxgZWg-jS<$Rf9$%N5M=g=3QVtxs}qjD2<4IvPK35!WV z3$~g9a9*#B>3z%2KCnEdw8*?Q;$w@!+9f9~IOmN+6}*PYte%}ogxXiLkCNZ*MGMh% zz4VAxQK){!hPzjMI^3A>bx+rS!Wwv}sQNu{qmT6g8|iJcw~e-C1FeR)#;A2Zf zkkr*Eq&~8(Lp=ODZ!^C>gW;mor^@pXF84};uVzLct2#+M>c$lWl^%ei*M^C)o{EH49MGf_>mW9 z^m`6gqhlroAA#AA_it{Z$yd)h7yINz*U*x`vQC~Qf$2wOH|qu9Ca(s`Y&Y1gH^+`c zg`Hc$cxxg4+Q9^8<3Bq-fjD=&wEXqt4Z0&1)H{eN43Eh(FjOAYT0jX^I4mL$CI>3c z_7sMmY14^$yheSg%%ONIiq~SxCi0?a5K{@?Dnrum$p1Ht>PR$3K?Y3!Uh*5Sf|JJA z7W=oa@E$Ct%E+Wa=rpy8cA9N?`0ZnW;Njbh0E3NQ7k+l5UBhmPx}NKTgO|lr73b?sF-DNA6|h!qn4OQKtv}t#ekxaJE!pJ4I+UpI zOF7iTF^*+yhW;YnrhsYbF_h#E$B>1(&)+6gh^W%KJdUy- z=Q&Rq@1D&{&`O)bPj>bmlIp2#Yw4R0iyh}`voKPxuP%OXxzl~7b3w(2vsm6Hy)mq9 zg)#rOQ8AyK=b`a8-e(7@D6f&zKKiU&SiMnF((~7E7>E|^H013C@>YS>MttfGiPw)w zDk_=1qfZvnZMvcBzfx3oPH(@q@?>=dC@r3}EMeJL|i_ zkaz~iy0-$Q$eFsUhi9DIl01YsQ+l4vxxVuPBR5?XW%`4POzq9?dtJ+#-ys`eGs<^b z!{>Jf{w+!Ez7)PQmWd&zHn^je-16}E(jMW(cslQLXXGn_ql*#~Iiiz8ra3}A$7+9h z`-4E%3RE|u$meaBx-~IS?yH;}%e}Rm7Ta7A88GBkFy=%vG7s5UQfcUg&bQdTOJhDs z2Zqn;!eeDSmt=c)57R!rCX=vi*n3Bl4*Z`%OSBlHYDkVrpM|-a-qv)3rs=Pj9&MHL z5faW6$j7hMmG4$oj&+dk_5+OZTNkkirdBua(gWBvA-$Kv*B{t?LZ*`kBiP}5DNR;d^Flp|VX zjHEfH6nccnN8N`t5*z_>N2Z3|Td@3L^I`|C@E5ADhQSci)EUBLvb!X8d#dsgM{jP+ zGsP(-LFF(r+?@ckr;}5;eqpy5ytwtBJ{Jy{V55g#mE6j#-I&^jQB+dm?J)RNYcFAM z=j1&c(tYSIDF81)CY2>;c<=ZMR(r_sePZABt9%Rj4Y4&~8|}WP9>;*Pmhlt3Gv;9W#UkFp7?k1t zJ1XbQVRQVQz&wLy!#3uWW@y8qR?)mPei^;FrRtd2@+gFFE*Jcf(0@_VJ3oIq@o*_oHZ zD`_*WrP{4+y9?h}<2Gj8n$D}KV=Ky-GGutJ;|k@(8HN`-I@?05e~}C7QL%m>C3bDw z>xGiDbT?ldHZ9#080g?3#@P8}U6>6B+0V z@F1)B&vQ~{+i5ZAX#KogI7lHVE2ii1bcuoAq)+P8PL-DZS32WH;cb@df=`@98n{{A z{r3Gkus>5aWTXk+)k@M?j|PRnT#IiT*CwXeq2nrf#Rbs!GTlWCwq2WHD_?iIHoJ11 z`p4Am zT<;))0eZvqO4;P5(mbd9$6>{{HwjCtvtk60ykVRoBH^0}djBb`=B_zi(N1h{9KY4A zy{az#VnPjy;8(t{BxL4hho;f-;!SA!$F$8TTkL&h^hEUtMeAKwVo0UaBJhUV9CQ z@8NT%EGTEeyP+kEcZ~Vr$NU#D^r&Tu#MbV;Z=)rsw?~T z+pBB8jFxBh%^P#$9{r&m@(&ly&EAe`MYa4K(=Y$B>q|A)yt%b}kZjIwmsa|yC%EvWmYD(Dn!ARE_i>lGWjjsdk4WrJEFY71k{^P@snw8T_z0w{@ ztuK5xFivb=_i`<*9Bk-G-0ht-`kMY)Y!|(K^V&xeC06%6HAuZ=*YHO@n)&Zi+M8cXr2V+0H7~z5@OTG zWjH?DUf;se97hi;A-q~J7JQ{;Oqx_xN8>W=Fe-uYxVMv; zVi9xBs8_#@fA6+qVr758Y_3Moe&@t1KxKGmrR!OakcW>)EZ)}2d6a==grBBH{He*$ zbMK2=j$1aWEL>`JY@CnZ$z^D}(=6oT-Fc`~q+`5;U!3e`{$ewYh>ynDq%@m;iN9+C z8F~L%P)ZgL123B9)V1gEG+OBQiy?HqK4q+fpNuZC`gktBxJIo>r!UIBgFMWPHJ$?)dLPdS+0eX&%B!cy6 z>6dlEaq8vHxqDN>Slsx}lawDgIc|wRZv6eNfQKdtlhV(3ZoVaf0`LOW- zy)C;**SP5=35-`B8ob4rKcNy$=X?s$KCPfoYiP&rce>qpVlvDP zUee&`>G`Z9;VJJ}eUR1~8gq@&Yf^HPi^=8fI?T^83# zwZ;BRLl)5td-7LSbRV`r(r8aoN51Yg*nlCb^9>_JO%a`-x~D$hrcmF4zbraNN&g^y z{^J|2QMTs@kGqMq`LEpKpKfc`V2Hb@8=B8oP?uiEUNm?7^YVV44|!h#FYlHE$|qO{ zH;y(6lo+b9-+8bHGr#RGSG}cDb2^}ssy2+cYV)IX_MfhsSQ$9GkuvJ*TEi6TgRHiERxI zWuzIOcVWi9t>s>Sz|~7-lkLZwE!VIqF|E@SrZU}zN)?nvnJ+w{Z1w?)e*D_ORuh!( z@FI!w$DctykkMjD;i-d&!gG1}hdACz5C-ddng%I~n10HBmq?Ts6DX4tCu{q*tuGVp zu{PaJdO*8p%99Cj2fp&1ym}!woPXlrr~A_K>3f+-+^xF+Au3qGE_kR`zWd^?sQ7Jk zM@5*)T8p%RL`p`Q1v)4=V<5w)b>*d8^7)xdmvn6IE$ZPIxVE~W=ic&N#G!Pu->)Vi1tAG)=R~o=EL6GvWW{*J;_f5}l%YV94!;RWGL zb|KxQKNiiO+xl_@3wt>taA&!{vC?C9s&F;TfKC-PbKq%wF>XpO*j0XddU5`8|KL_w zhqC6F@-FUp`?H6Sz0lecvl0q!8Wg@i6yU@Pp>#u<)BO|g}crlz#>v; z;6|ukv}#POF2APkWVT>w&ofNF?&qGB8@C_X#(s4)Oh-GlMdO5N-5E37T$Mu zsj!-|Bgr^cQRcMhCga-tdU$v%ZDk5!Q`!)Hc!Wi{bB3b^^;Yo!sxoIGHeN>Qcd*Ah z4YK+tcpuXSp)neE;Z+HcaOsI}@~Kir(|7`#d!8laj-uzkVolABO|@Uklt)-3C4LJU z#I670M0~>;)y3iOcT3K1N05L6o@5-KQL3<_?0RL!^jqsx!|QNTu!AQq-SH@#VP?Tf zn1rRpF1i?}%nJJkSq`79Z!KxR=&}U!_AZX_HhATDOTp7-<&4*EqK5833yeiW!M?7! zS>vCj@q-h>IO%(I?H(bFj^`O(AKbVfx?r^=^Dz5paHLdNPoLsPK9{G`TYY-+*t2iN zX2~~_QH2Stnz*-o9b@HNR43}ZRG({SJecdqp5PrRi(rK(39uu5dR}M0F@r1>-I@vR zPOZ5#;-RpO>*MBJa-IEIzc4v;9s2X$I?HBEPI&%tyy$ZL%>2n|X^xVrPMW8IfNQ0^R zExT?5xJLW0obb82C3cunF&-awO8WhB> zL(P#%O#zaA&|p~BkQm*;P6pZY&UgW{&=y`~b=rEY3#QMF`5quX(MRyAsetV9Es6$C zsa&&qF_Nzlh;%79?A?4@`dhiaRS(uqiW1uPhfazHoA39RMj9F@YXy2mz)Y;)Sg*ie z7mr-?N#h&zo~A5Ny}{}zE}mN&?vKOGF}YE@@SeB(g&k=?7++YuJ2M=)MII6QLnG>H zga|f^9%{x`D+zq$jki>!%TCa*D-(vXo=LZ}T@0wnOJCN^e4VL`LeGE5o08U#-r+`I zn~f)}kP?h9*05QLWtD#Di>t`Z+bjmg8;wPqSu2tvCCf-xrCqKiS@aB0{%9q@!eaq3 zCsc8L36HgvnUjiAfpkk3M+?@W@WnW3atXPD>8&eqn#AZ`1T5A>zwlZ#aOxkRJnnB( ztclW%O&Ch+Zuly}IQeOpxTeslg0GBi0Bx0;fLkp;Eh(75`hit5o5-lMk^%%fxU(qw zameR&g7G}RoEg-S7ktk4Y|}$!Ol0UI(Zp-$FIoE2%{9Q`qG^Z23G1HU$ON!kfsPNp zS_e~1WOKmOpm{(Sh`$rt>7Vc=Ystu{YlfwjDl18AHV-Ny)2*G-0H!Ax|9W!z#lKuQ z?XWnV}u=pM>%CD!Sw3T344L7XLJ*L0ahTwXh~I!$O0@doXE;#3^(p67Khm27iu9kczQ z&6J)?Sc>|@$x^tig358x!H4|dvCmv)!u8#3+vX+zL&>c1sR)vwV7836nJB2FxvT3S zhzr*mMlwyR@;Dy9lEwb<7LCfjd$=TFwQx-Kk%}u3Rpdr%Tf_5Imy_0S?gKJg56M#9 zZNcg(Z$B#EjKb9cVnS+w-cvCe>(Nj@0}pN|WY_x5Qd5 zRa=53qFwu4J=u(ZpZF|fs&W>MeMb(9{XJbrHh~wHF0cK_jd~YmlTwh_;xQ*o1zF4v0wX9R$tXlo7E0rL zMKtvEI5#(@c7zz)TM4=wk_?6@N4siin9$*EEC@z8Ce_s=H++(!t4)e=FOH^l?u=ul z{^#FP*k^Wjwm7kyKieKcNeQs9J}(rjW=nT^~i)BGbSixlTZ$&ib#+sz%a;g`#Kf`JjjXJX__kt#JlL4zDG zb2CF>rNDy2H+9XNQS{yPO~qrT{Ce|@h4Mf;BPMD1md43VXLoX}V;Y=0nPS9}O=;YE zX0)2tkC#a(md?*uZJAK!-K{H*FxDlHNOm@JFNv3S?b9<{FA2jx$7V@&D3XpuYszZ* zj{J7tjqJhEjctiD%H?nQ)f1~C% zw$>$`-{ZZz+~m1ahxZfiuu_pze&;e7Pd`0$Q&fLz!PBPQhcQw1Vp8hqBViV>O!PXdZ(m+KKN-ScK6CPmPZjE_>X*PK!p&6>g^ zCh%$_Cg+Ejze$arELq0FcZ@9k^pgp&SyZ~rA!F{CwaW-LP*%i97LC?sP8ZG6GB*^; z6_Q3!Dr+@}W@TwU_&x^)n{s0azv<#hY@+mr`5;tEzMThKCN;~A*+vO?jPZ8J{w*8a zZ21^ls;9PAH=M$jY5TQ%XMUK>J(otplB1I!a#tOG%eP5_S8EVXBCl~=FRh5 zuck2(5;Ml6pZqrk_?S`o9# zN(uWkfp@AfIfqUh?%P=%dH)h0_58oR`djzQRl*a`BPK_KwVPfPH3GLIs+q zBPjXUx2oq*7~vA$>amY#Pp$9%PYetXe%%LJw}Oc7iy55%caNO3F4IRztKOsW%r8b& zcT9r8ip@MrtOh21hL^DI^Sgel)J=`Zg=f4elA%U%?eZ<8pCgatr2IawqvgK*g64? ze|*r++;YSw*=N{xjcF{ghNczfT7(i}i_tp985Hs+lPKQdFDxDj-{6m7yS8!qd^}E- zad}0rD?Sq*jdeufDjEXCY zk3%kRj`spNO;&$DRIN89)9&BBv+TI_eCMik^iOG>q@>G=g%;}v^vA_|_|Qj?`yJ?@ z*$GWE!5fhLI)KazZ$Fgj7|Z8O!A?g_ykNzy)_x|NZoeBifTx|Gw)LNIdJ>X)b}P{} zom-J3D4QUB;~z6Gr-U{dV6BMb;Eo07-<#yQJcE8Y{leto{Z5@0*GfNT)8|wYJ)St8 zyR#NXpR&ea^^54*xXwt>n*^WcuDGEn&BsRC8mFC%yUR)L8SC4_=3@4!G;sdD-Hdv= z`UT0AWK|Y(@qHN|c1Y)|$V)da!?~>yn+fhe`_qUL8gWav%{KuL-5BwvH(Hhqqf60p zC4(qYfuVEka8M&A(%L#2^xkD4DJGs4f*GG-%0(4{a3RyqYV>hqNM|6otkIE{b@ow~ zYSBm?4xBu@?|d#kA0sH=Men1)_bpAOtW?G5GYR>agmC7PQ79K%;4Nwjw}th<|XcHI#M11oCJS;HbA4cC>F8 zlu77k&{$T=hAd6wnb8z&yLRn(LvW8Z))5O)>fw{M+j18e=XBB1L4m%h2@`-8j2d&L zHK3F4NZ8KUF_t7-I?&uE^TE%Hl;*sl)G#xe9&KNg)o-p_UxaasIL;1kCFky6vc4lI zJgz5C(e47Y{@flh_w%B$5s@W_!nv5wY^985t+O*^w4!!clHmKQ&XYatwRllu!${#S zA4z!Jajiqj8a66SRLmaII#uwEUB@W3o|@?&d^FxymSU3WoEyD_G0prYq4q}m)+WdZ zhh3OBIq?J;s^O)c^tz~Qib#VZgCM5TCrac)cKRx_Eu(bVOf=nH2P+yjRYj?is|npw z&Ul$6Sqo_{c9oHuGTrqKi_KL0{E8_}n(}&(%ez6Wcih)V2Si&%BPLO#q+M{P2GnsD zC?^Ar)#=2Nm&gKh}O-TD^@!4llh*gxERfANX z`1{p^^AN(9G*TdGBBc>j^*Po%o?bcLv*y@|Jm4&4ktUYmOBfR_9LY7$>+oA=Lu+|U z!z1t7DFjix(GdQ+A38s(X%NfX%lQufUWKy9M7dM&)mW<4^`AoKyHZd->d^6p0AZ1G zeLZ==xaI#9FcX;0^uCPrt?HcjG|xS&xniMd2WJwaXwBPLw)Up9x^qf-c!oDy4OHpT<&#rvGRd#1+B z`=QO`c5yb-=q!Xfy2aukOt>M#BPQe1=wd`4K;DaoNg2lQz>+K@CVq5t2iCW`QHVFD z5e|UT6CZF~k!Q##?d z+fA_i%RG1cVQCZ_AgD!{@FW&?Ry2}g+$4q$Ne~p~TdC43&dhP{>3ZXyl3#Vy;GN3z zrSbF4#SF7c>2k?O!=%n%D6OmIeVBz2z(XJ{05pP z-2D!m&x(wb(&|<3*K0iFwnDGkx*=EE*HRY#!rD zJ4O+<8$Q8VY;-G(7`EyTGY%!E-K;w^ltQiy+!b^!*4HQk`Ml}6O%&Uej&PVFlvWOh zGY32R|AQqRexU1J(SAHkELh!Bh80R^#!}_uZMZ0)Ej75Xp0#z>!0syXt3zIO+osn- zlXR8rOPfZ^DD|zTi}y7J+^VXU%GPS$wRjVFS0aNx8tCX5HqI#g9FrM-$*_dkA7NL< zYmwCc*kbow1a4^&q5;#mT0{m}4yM3xx`yY{7(p_!4utI5@VwQV>u2R=HkD5$ibPCw z-(;2X4x5WeV65TCJKiylkFxi>P4%_P@iyjyn#veW=NAR1JKTk!8yXk7MbEXSYo?E; zEhJM?9J3R#R617fqlD9C`QGW!bHf3ml57mc?V)Q>XA7;672<8SJf$Q=3*r?4!%eez zBrhfQI`zKSHzLvRXoktuFSznDy7ILu2qij{cC)zR7dR`z-EeI8iD7OokeiJHk}_>c zTudU&kv92XH>}=fB?~P^9i8}+)>9?%L9`gblylCvDM<9+9%)@#-dk4eEN45{)P0nlFIVpD>~16>McEISka?C+tnggBhgi9 zID|Fp8ryAP&e7yfw)gjb4-}sIa<@~1g5Dx{^uH@ldk#)qT8`MRW_CE{XKIXZ7vqQp zYvTslsHAuIjqKjvzP!27dWSHQ@-OS0Rjy+&y)Ttz-XkV1;+I!*Ym1wzAE@prk~CTG zmiYaww+^|etxDX(HrUx~jYR4o%dMRCo~@y_$*xnuV*sQRwM7V;I+v{V?~Jv{K?j>Q zBPI_d+aBAS3xp=5mSzR5@va3Q$*O5{r$Nc8e7v#TBTM+aC>Aa4Xfe{He?6o0N#`o8 z;bjA}$D)@}WN0W7l+V z!9h}J*nN+^`(H?nZ1KOMQx7|9gR3%H;N>DNBPLwz(R7t%YBL9Ee%5th^|f5%w%PNz zOxcp;nA=)Zl{pnz1E)$-mbUG6AyM!1_wDZeO}Wfy*Tr(-3w13mhN{htLqBO~)-$1#+>B~!WNnFckd>zpTEpfG zn^0E{P3i9vV}BMBBH!D?o=DZ$nc+MtLf!c5+meMqk>fslZ}#ljW$p0pcfZ&+ULVQZ2pwlGr6pcD>QE1^z1^h7j8rbK{iW>8o&}cTnj(N<64} z#`BAhTPUnA!EYxzbrVVF6^0{GS+d2>bYnV&gS2iG&s=oiuH6|h=X@K1+U{7pBPI@X zJ}=JhW2VBziizLfeQLSAR(VF)_+Gzj&6CUPL>*BZh089eWZGo6k!EYoM?Bsx*NpCS z2wOQkW2z!vhu2L49jQ=*(B z7=Yq0fW)%&?9G@tIU&t4b*>^bocAogLRNmBj*(yyFVVrnApB@7^Qam~8woY n} z!(oPjaQk@>OB)94ZNs#kHEkbf z#5tV*L7QWbM-kuCXh_42z)#5o`hGMi?TDP>=sz8&mx}VkJ)wFQg0XuoS(rJt(ht#` zEqa3S+sqtT+0lE8rB)OE8vd-(FR{~o>CUcDgQi?M{j;>u@~DIE>kJ_J2izgmbEB2k z(vZOdm9r6Ha^X*)HQX&{m>HHKZiVS~op2G`s;;ul5esf3C>U(X?2aO(c22h&?VPoh z?N|^^IkXe*z!9ux9vl>Cnhji#^ zj}*j+{54Jhqm=5it;ar209zn)qZA3!>A6n%!*7PEN8yS0C=O225hu&O`-AP2Llo;H zPb;x-z!8M|XyJ5%sgy&S#%*e?e_S+(L6OqM(Yf7mvT=S@yNEe;Ktv-b7m2H^(HSy_H-gU*T;E3r?lfk7PpE$*EGCJhW#l4v5_n#soD0_$} zq->^BuSvvV=$Yfn+sAI2`!GmOrTwcyFfjnc-z^qkQ?r&b&{54Pt_+J&d&+9h%*SFp zKYdFXPFxQozu86b?b?|`ir78GT&AJL>Y_!}i1QT2)k7mD!*iPam<(K^oSY~yM1Usn zRrS-BT4DwFs@-;WJs+)Oj)~qzlI`(eMFNN$j*2aWauCJGkivfQ*iA-&<2xMmm71^^ zQS$dQ@^p4LRU;<8VvKoTD4zHS6iReqPL%nT`WM2sTH0fSdRZJ5qETpKNDa7M>dj}z6N4|BZTEH^AdbGBcgP-Po^q( z*wr)Jj>n$4-LfgB9Vzb+mbC{Dm9w^J#(eV<*~fZ%?v9JTSab`a)+1(Hb(3UPVWNRE zpb=%?(WZ)V1iJ64tWw?DK}@B_rGvE{{ao!DPTah0W>I2ABYbM25f;^esDT%dE^2V7 zNRZhoDh%z-_lV?M8L*Cv7(00ZKp_x0Z#Kyu%Zc*Z8GW;~Y(X{eh*T0Jqaf-2J8ap_ zpeSy=WBV$X;bknZE@}k6D{<&5{Bzqozv)!k6<4o+GQzH!b7Cdneg*w8x3W}Ri^ z_t(RiE5{;b!Q1@&!*PD9hqA@w?IEyIX?j zzpJ9?cj?=y{+)=zJtHO#Cv*C=C?Wek?U!lo@2L0}XOF(VhYr=c4`r$!(w(hYZ_b5)X zBFAUHt{dMS+l3QZP%bGu@;`sWQ9)wW%jtj{k?tW{KXaenP2s&-gu6S2H}*uQ;(B<_v3HqXbagC&Z-`J~ zddk5hV&VeTMxaE5$W(hB8r{Mh8@qLuMMmt*4CTnoS$e`LVZ^&pJS`?J&h*y%IWqYT>&g6je)jYd(=Y+J-j2M{&YjV9vT9D08xV~K| z<~%N^9u+6qo~t_%MFW}V?wE%2gRujXyaTt`B^RP!Z`Gjolk&8v|Ph!uHm#gc1Tx@dD9@W6g z5P@_bX^?CR!n&3}rDt{und`_B6NB59qMtGYci5X}h*IZ(Rq?Z-%#VH9dn!L1sc zk3PCG7@pCS>T>~+i7?uGE?+xeR?S^EDB9Uc6eLy~Mu(}{im)3+JJ3fOfNVW!d9Q#$ z3%?wAb?_fhtmgG7{55Z3x?;?(#+pi65UTB^sibb^=Xjew`+1y&^LimqWJ%=ZCVMPr zuav#Cn(0mJc&}3@9kX#nPcPh}s5vAMR>M{we63($Y}PAo+u61*2eqA9>VB4cA8Qg7 zVi7pn-;oBfw|uhF;(0u=9AU0C{Kfq5&#t>EY1nsoX27V}wyq;6{96!7Eb#(CMY&3= zoCM1kNOS#>b(6`Gs1tfugn2`naL5|@P)vxSIjvFF^T!UE3#`inrB&s9dv@Ws)x01uXUb)^+Y$JuKSojgK2hcNNIWYcTD5AC20BipkaOc_S#CvmSM5j7VT=)M*gX1daX8+Tit@@ytZ)&Dr>h~GW64WOLZRSCV;$|->L$_kPy26zU3CnWvej`kU|F$nF*>FL^((d zVT0-sv1|^gLo5D$ZqbF(922bD5rI^@U}G#UM64Z)>1p13;{_09+oSO#Ca&_*eae;_ zbwVC+7e1danNk`T0a}xwSk6{ZBPPy&Gr3NIcp)ay>5__JH1?51JKrx!u5JN)J{JRyG$SY}f&ok=4|_lc1vOa6kR%x!AXHfFl$v?layauf8YG@4=Q4vhKs^*WjW*0MJKXJlT5CnF|dl<6ty1P9}MLDlQ3X*H1d zhTE(tuz=wo6ck}jOh{g*lCx5-ub^rOv1COi!xp3(H-Z8vCz@BQ%FPCvAUD$?cBkI>D8n#a&2_o4kH=7bm@f@Yf_0s zN#y`gKI}!e1+XScsfl`Ixn$CXEJ)owaPxnCtOUW^1psI$9VH0nhPR9QM-%|(Idg;C zwfi+CaxWhv5p89r%x&fLGTy^uvda0kp}Kd{FL6j2io}7f$|yLlrNbGZ-7VbuLbJ|A zE+HZgFAO_3nDB%P&eyQZd1m?n(_*%od-N82Fg1BI&i2ri0aSsquHSsjG(DJJjvHPH zPb)gmNGL&UCrl87<|#z>&sy~Qp?xFbM~r7ZjU~HVVFH7MhWt=hj*Bw0lDt)M;I&B* z7#rL*H>k4F@0M|#rlG7IZZXeEHJKP4V5iCbL?{y5h|zpuu(JgcAYZ?3VyJ$~y5vSO zWi8ir_WFvcQts|WimI?b!TtZK?GC!^x+5k(wbO}_e7pM02HLazcl-a$Dx#vo953px zm18;cp}ObB5D)Pndr8^UdSU0-czBk9-iN0w;P4eiL-$}f!2Z~wPv@i~C|G{ni$_R)D=yFxRv^cbLiBPMAo zjDJ*0b&z`2^%K2%8kZM`PH1^dFimMy6A9y8eM=x$GGpAho1cOGhV+2dtdH! z+gYqOK|uI3$jLeQn_m^-N3bKk^_hbpcpJ7v*ZJ0$pZ|bVjd(Be0{TM&dfIbK+&$$ z3|NBpHAW=Eu!@K87iqzT*sx;)Qka;7VY1->f<7<_fgrjbDG*Yyq0|n^E#94ZLQ)9; zY!^t-0dh@HE@o4J0rQGGpB+&JL4)?8LYQah_D{^en!nia@ccS-Vm}b4e}ymO(pDz} zg`^-@aGcC5;fzDSEc=|F)7ABVn32>{P+?B8?x>~y!Yn*!*keADK&iu?Vmmral2>&i zo~f=JtIatynECbZpOH{oLA>IX3YE(f>)Y;ssQljF@Hc z8#PhEE_#{9+TnB}gWE>(=$fNbOQcQ}!QEZ)#p6qy7!>xFMYohnSvR=#(q?$+R@f!cLi+lfdV2#L#FtA;t!+17HE zbzJI%**682o0qL8e-ymM9XPZF$OvM2Q#zX%6wYWISfpQofLY_^lL^&0nZg9 zeOwG3u~p3uLuLgAtl|f9kYZ@^dJ;pevv0BmstbKRn0Lnc9rs27dB|%dF)|{_1teJ_ zk!0VJ2k(Z-Cna?lCvKx9B)M{E|( zBzo1~U$Z6~LG}3~=eeAB@r((?sRD>ilm*4#1dw%ZB6S z(;J2@ZhA;i6cKYGg&rQR7vr;rYIXI_d`^0*OId7MfW8j z?9`D%;)Nq9iTFOpJqM$w(ANOl06Phf74wpK>+D8G*~Ksd;S@|@c}9l-g6L0()?{k> zC><&}Zhtmbh2>!q6rJ>WdbN74?RM!scay|jsw9dGn-$%`sqORMFVVKXkFcqaF8PDs zA?kN=F5hRX89w&VbX`Q~C1e9-@D%wp5fGlbDjAuoCynQ!mLP~Ic`k$w2oJM!Oc*05 zGJ&~YH68DBbB;G`vo=@XpFI=o;jJZYquU5bNt11Z7T$pm(Cju^Ga(h~)){T8m=tUe zIGF~xV6M}u!WYV^kwN3e(`ZQ!{Z~Ozgp2$76YDds>n|?I`mNL%bdqxRPC|SxzcNP2 z_QiANZP>^On{myuI8o{#aP#u@ex_MIeikDpg}XI)WdgIN6E zTgiE1BpugGmG~2D#o-@NJx{+UTaQaTChNCnRWpJDhjyV4Qs=?Ol${x-YC1uj8hxc# z5f&Pv_2#hlAn!paB9J6RfSEu`#@&$xYl9sjZGB;*Dw%w9fDciYLJz_jnEUf$BPg5l z&$O>M_~Xny9!|90s#uSk*)jXOEo?{9`i?`IK_)CjDvblWZ#)FR79dj0g@wI`ImUJ7 z^M?P-XVHkUsO6pIXxw-!Q0w2l!e1jMnMx-4!b1}BZlz~_Zhg|5uY$FhvfaZ>N-+bM zoRv)iKwy;!;j96y@}tt#l9el>@RiMrvT#g`ndTlOLw_SEF&vwA2|9!Zqz16f2kb2( zRe84P%`pi6RC$ZQatqn+m=1PqWa2`NQY=zv7@bZ~*)keeU8PI2e;N#kE}RG~pwt+c z+!;g9f!_KFEAku;l=?O#o*J7Bd7+uJ3B2>kD0GO()f3Gw$Z+*-R`wxOH5nr&F(+DT zp(QLdh(bTNqFLg?^39M?nbc>}!o9-v)_l z1U#9`J9pa-=YS&lqP0sm;BAdDjdFJVBPfhy4y#=pX4;yQG;({(o^5Te@@+HdzB`AT zWCMmJz~|%OhBIc68E?Hw;je!<8hIU|dj1l=oAONs;QM`Z(&r*Ccyi+&%Ak3`dkCF! zh7jThBPtJ|2ozTRD-Jn<)$$L6n7waXz87zUZx)(n(PpVOOtLPdnL%K6F)-}dsZ~pY zv>BAtV6tq*olH}v^UJ0$BPQL|SAORzUktiue}8{kq)GR(zI=56I!L!Vcdn4n z@J;diNupyHA}6lknu}8%Q&)7_;atvh5V(Qco|5|*78$V)RbtWxGYNoH9bjvj;AUHD5R`SWL+ziP2J&~tOH`o4XI$Z{@xr;+hxS&SXfgEI2p#9;{J*UA{_D-% zWMm`>{a?J4n;@W7RD#MXg;_OBp=`}<`^;xf+2ZbX{H`@X&*M3>^8_Zo9k)tB&QtGb zcKOWQ$8YgFAIsl-&#J~gnE&TNwYzvzFRt^3vPe`h}1gpef?F(iUj0wMsH zDmV0gf9d}JQ@sPH1dvdR)F`y2?Dwo}`QnZM z7<`P~CSBolQd|E(`$U#L`aF_6eTFAWIA$^QJh9aVVDyp#Eft(n>r;fYu)TWdH?hpqIEe;2j8A4?t z(%*cuo0p|jfEsStEfhxwk0tX^l5W#K9%758E&kj@pO_Mc5+VY{7Ic(-8hlyWd(WjK zDEkDg6`W9B|0#tg7t8VU-Rau7LXnkTVFI9D2#GK@e}L-Q!AMX5-H>J50L&pTtAEqk zvhzeSU+G}=#3Lx`I{sIa!}w9M^O2;5#?Rx1*^L zJYeMxdouM{&T&#qSlKYnX8vI(h(^%Ru-tVsGK-VB5OH=qzzGECp0T{|ZD|nhM+gVo zZ9C;^_I|R-ejX>zqahgXC42nevxsgR{j7L^*$?dGJ{j!1poO z9r-waPoD8#i`>J>bcy1sgIMIC=h_q2xO{0lVc~}`-7eRCfdcqaX@|2S`lT)r3_>6Q z&9Xx@akN-4N5OMwH4RW#v`|bj%Ep23)7RDjzmozAcmIFJIB+h|rrO zDB}~ED6tdB#JA_lwAGK#_5F5f?b$N`eHPEeC#O*!SUjw6w%Gy@q-f29p1buci2(o+?cft+pi-uEHCjVNhhjz^ue0ID8*aij)2E3g zq^2I!k9(<3HYVVmlx5+rw59D-8+)Ca-h9;PEE{OjmP1$aM^N5Ti`i`+{2Rz>dVF4Vqa8auf3Qld7G)WBHJ z3@o~}n1ifU5mN?mVCfcRFJF+OUj=9K#vG_bBw&&De64$*TM};l>Xav?hj#O??(4H& z#MZg&{e`_QCTD4(;$zKp7)S2)nx2m5o_B{{AN$wQMGhphh>4!=!%Xyu!vt8VD6q)j zA{}uMnq}cSBPKQcCYjmzvHUD&D7LJ@#6O?BTIQ)Jyi5tx+E2v3JO6sQBDJ5Fp!>2s z_u@0;u47|cX8F&3txfTQa3Oz4^AaZDvLscw?tAonR_g~rX4Bi&Y7{fR zqxKWb--G2jsYm>8=jKKFE&O95^dl&awXo5l<44laauaC1$VezbcQ~x<+H47nr$}_} zy(F1Jw==2woEkjb+Abqghv)0h-B}kZ$It1~`0<<_8S)p3nDmFEIet2Ai}QbIemEVh z<9*4zBs;8kcWm0$V)-}Xaa)Y(Pip(BVw zd_Q=D*Nwr0tyoRxZ!C8Y-<0;zXp}N=gU0)!_XUeAU9ie*cJlJ7l&MA%QV5kL(K30w zdT&_X*wU7X`{K4##TVarjs7RLIqI>O^oq(L6RmaNIo|P2($>j&j;x73nqFI)$?*|sf36+v!0`~HQjwwT*g<0vXv^3+#*MI`TTj<;;)wtFNJb z?w5}5y`@0&F{P>&-4v6`eQeKWfz2N(HtD$NuO&BEJ@yWiDu+|Q! za+i5|@Myd#SQj&_lLmA8c~#uY3k#BtV*B*sqd^-;{)1V}BPgZZiXBu?x#FdT;`&~Y z-g|B@r%I)XK*Y{bq!o^yCS zcC-!}?7c{{#-m`abr$;w?H$!oEHn%M+nL@**~Qkw&^Sx^D?r&8W2cyXPqUGIJN`_DskJ zA>q)B#72bsVgEadxN|J9{%}T|NDIK{N^@inpS~a4$_y+jL6^9M!JCM*&X_GPH|w*8 zJ|_;dhH0cm{GhK*%4Ba=2dXaB)a#QMsrx?r%Pe6n<-z6H<$%_ z;Z+XC(^2^3p-*Z<(F~_*1t#Xr0>g_oUt4w&L3$3TS{)sP#=K9Ltgq7cr#$qAXCInu z_4hb;hJcMAhD4Im2s|KV5DS?MlmU(DWJN6yBpzE;fP+j07`3>%Fc%B}?6~>rM=qN& zL`W1wMr0BLj?bCa+B$cdxz!#0)O)53J$Awbg02Q_5!YPWI3p&^)>4l0;3Fo*!up8GL;98>N^5c~N90sTF`f95|YzJIE8_G|0(@&=*9ueMe0 z4#FxuHSGQJewiqHvY!5@Oo$kssKOrEV1^yX`gQg4MD(JN%_x9AoPVcxx*L8KRGyY` zwSBUnosoaO##a6uX>SjH&d~V>mG4|TedY2lp;+#I3GQ$`lk`I)JamO;?ZbcB_C}AU zBPO{kW2fW6ok{LEA(bt>(y4D|yJ6AgE@TubbHBymG+-^&E6@p})Q5T(U(ctLU&%V# zmDNnI?103Fz8r$X&6UQs$%)O7M^DpNE+Zzh@h&Km%z+dkK?Z3ax~2swD99rw{p07T z7GK~QH3C;J9j|bK&XTt^*Q)schV}n%ll6Q~p3NV%O!^}zo%a84mJibIBz?~8jx|pX zw?5Bz?&0-Q6xs4{wQ$K_hOck4g|VLe^-j zQAA7~PcE%Sz7z$!C?CUFT>0!aKLBu;frzP7VyVjeD)|IJ6nODbQ-0y~$?#t=AR{I} zPt`A_>V914nh?77L^{_nG4|WnM`HqCCDTqG6-&sL1*{TBS&n_o4kQUJ zzBife{K9fQbKUPXL#r2lf=d_}k?morRQ4Wjh?9GClh^4#POeL!v-m8E7%;+Xj_uZw}HV2-j$oWYP?KuY!CSK1IZ3`W*UNe&BmwQ3-h0RQ$~H$lcFE2M;bBI*XMZ z=UgR>PnV{eR1`TC!@ojD-O2sGvwnpIe%EYu=N8-+N*{lPJev&1Zo1aK)sFg&NY>>4 zv*!YR^H;&G6{>)--}Q%N)-HbHJM5jQz8$u@(?0bw+>FjKCHiYBsoY;;pQhKgqT1`G z^ihT|l1aVLj12OFU)(XF1qKHWny3G>XkjXSj7B&AAf`Xq8@CN zfS#2h-i5v++VU zv$nRym&=zmnEK(h8tKS;FR-7fugUXfg^5(dV|j1gU%gU!Fl@673qWaSpXTUxJRFs* zH}Bk?=b0VaQvNzAWof;A)0{*Wu82_+37{nee6NUmsK_Y8W$tzmK>)sdvZr)#+U5Xw zb=rJD+kQISxZ)9{k3#m1t|&ZYf;c+i=*m2F*}OHYS>REUPZ5cddu7$8F^ z?SB(HdE91S589^k|HZES@@91VojyEnPI$}1%ejZ0DI^nnNgopn`UB6$Tpe$GrOAQz zuWH0?*=~;UdgG4xm*jC3yhD_mWJ)NOU5sVEh2aLerWOgOdB289AW&U!SD3y_5 zK_sgNu%(Xp1310f<7dKV(a!UU?NxTWboL!MlU$%IkLDC;gykKJa(PtW#N zAQ_u=Uc*?W5l4mGE-UMwP17{?_1z;V)ziyLwRNuE-%L%l{9lO&(sS7kk|$?6+xsKc z+|KS8O{XLpkdKapCzkZEdWT!ZjWLnVCu$S8*;fw8!m4tJA1X|HItGqe8R?m-3Fw=1k&Dfr0V)p$+QL41vVO~W2w&G_9(9N7tR zs5G1LRFd^~N7!|~hJ#Y%I{G6f!PBm9l~(g{BPOhox}Z(2e%Q6{sD@$b zDO|!4OW+>t7qPK`pw)#%2RCMgR=M(ROpa-4QEqP-5rYG@RB%|(6Cg0XxQ%uw4kA*^ zJ%BLmw*bofowf6HG!dR|O#58`+Cv=p+P+WjviI0gGyrZw#15J5$=CE~BPOzAAjk!% z%8g?2d>Vqy>eQfakd6dT>mg|RzK}|u*^LL;`Nz&(318&XI1={p)=q~L07h5qwa){H z=9f5n6Qym8X2FH=WLEQ)0E~!Yk`O0C#}XyIbL^af z=zigs9N@O%FU_Vh=x341*+(NzCKoT0jU7F*9SVT%nbd1D1{~BX$Q#% zTjDo{%w{`$Id0v`sq^*V-I=`dWe>d0T@2;fUoMu@=lK`abx7>Q#sh_8*Su95AxgYT zG8QV`YrtUZx>XyH7|~V6I8oXyz-Hu$0|Jpb5H$kXl-qsP5M`TCfm3*Oxquwz^BMZ@ z_wRMlbxA`()$?sl85$o2#`6vR>Nrag{uHVG!!!vHMOG0Nc{k+)s;hv}X; z7PvF|-gRajF?C$-?4) zG~Wf?UWNBKSK~u!sp#+T>YEHBD3Rk{W)5W_f|FEKTG?V`MWe5xV1qI(^YwvjVcN^a z`xF~08mCC)0F(H5wpYaGI32fd@xBoC&$n{zm2=19aM2#9t`0w`dHhxE-SqGAe=vj5Trb};!EvSf&Xp9i2o`5PxBIspecdl49K6%!cA+n zj<5?9Sqp}4PA@k{=HHTPn+E5&&y4lRA6<_uy zta|JbkorKZsj9ud&>FXm_d~y(yJ_u?Jg!2GSw3Hs;jYmwpxfl9-)7m2Sj5?nzYP8J z3H%VuhAF)C=-JDrS3y{F2Z7!|HgF_I!V!c8WgCf8*AVxh{Sz|4NQLHtohtgzsN5a= z%@im<+aoAzVw>z>_`m8L`F=!!*Imw#Z-pzI61U@qmrFaqB8Sy5fx$EFA<6-(Y8WFZ z_+UAZF?LY)RFr(k$@*f*T;l>vBTzk#^R^N5qlg=qV(=p-W`@3RFbwbmldyFhOS^Z? zpxO+986g5a2@!WjKv^h=QX?ogKqo2RJg6bKkV*;bK3y0KZor79>dl)3D(Yz?C@z`7 zES;TBzH@K0;L@+Vqt7EK_u$YT_n{;ALV}N%P z|6G2=)3q<|{{8eNFLvyh9vJLEhf^QpDYQ>T;d zCfl}cyJ;rdwrx$eZF8!bY;)f4eE-6}_TKmN+-t4hV(7pDwuZawT2DoDc>Kg+TAosZ ziR4!8KCj^tSG_k5>K%Ew-yt-n1A!}sb3Y+LlI#{{2E3V~eRhQXNl!%2yxGJm5R8Ut zx9Sj+0MaUvpFY=nVwBX88wx*$;sy6o=(vZoTDUN zuA3z)qmZytRV1kwP=8~c2De-+4KvHZUSJRad}V|O+;an;NtcHl?4lth6Mvzfxy6*? z%Vbohsy3t;Fd*EKY_1dx;J-z*mp1if#-f- z1M_zSeRf<|;pM!iFOI=E5ZH2z9Nk=?2)EXnV6+KNaZWu4)tSu^_gUcJkqtU7m0grNU#DLE#BdwXkWkO1Lz_~77n`<-Y<)GSsWH4F-XLTj}T4< z&%PzFjRN^{&HbFgg|hW4@owY@k@p$ZRZ}NvyiF;^e*IvvD^98e=#rlxKku{^( zU+E5>eCfnZrnT~jA=u>VZ(RYqL0?+@bxoLkpL(XWH@_ZB-xn-Es{p8?trD*&zi&~X zyyKb>w8S4lEM9jx(O>?bZd2l(v$9(+x_R8V8CS7+Z0yFaMTIRF7H^8ff8?xIQg17} z72sK2l)($IAP-}JOF1ARuF4NV&zv{Z+`;u^^Of40+7<-_0er>^UBLyran26+v)otw z7$^T(-)p4vioEf|nSQn5klt897+y7~l2Z`pQW-OwP(9MlHCfm%VB+=bG42#S(jt_1 zR3zvA1KR)lUz$MVS6Rmri^hpOn>z^daKcq^;EI;B=c-&!w3g|!Srw(JNMF6MaLZhW zRk_qkA3XxiCunG~5jdO;^O9VLZ=bbk@!DK*8Z|WT*IrX42A*U5_$g0Vl=%Zz5$NPO zPr->sTa16`eTN|zT#JhkMR<0)r2&0se^sF{0_*x&R-Zmh{L3Hy{AYVD#QQyRnCvxb zcNGzi?C7^P2=Z-kGbqA&fP=AT|KR3LVZLU$5KkBMgzRnbCZ+VO28lLt;!vDJl-A7c zz6OiHB7eIuQMbV57*eaqGS?{6#@WB+zO`=TNe!Qgc#1@Zy^o-{c_ZOz_%2csNA(<6 z^>z9S6=Q(zv}hCrk!Q;5ShJhOHK zxfxLjs4-j2DaT!YMD%>-{1iA#SW!+>p+%qiKu!#(Fv}6S2$*okD(&L;!1By9lncU0 zo7mt}#Y3qumd4=fzw;-3KR@4YU9Ldt8nVg#j;kFibVNJ%D!xLh(zzpvN+1JB7JnpJ z2Nz`L{I@6Bm3R(>y35`8ajKx4mMb#WU2Iu^r_-}N{GZ454iKbY_r389N)DpEguLgF zM+_B?43JVd^_rEG#oKu@fF3rvmoo$f&~HK$u(9-fe(wzphO; z0p$>*8S@w{6%I&sFbpfvMwGzGuVT)mx~NR6vKrby={sEa?xDI@Awv=?9`&Zt1OofL zKu1-zD+g~u6Sq4>CS^yQrX17qn-J3SOUP=}N2kxrFAf3hXUg8cI;bHR!WqZIpT9&H zB~4{zg9`pwKX23wM&9=n#~}s87QP_JaAcn8xW6jHS1Wlwe`V$_bY-KF$IIq*k;BB| zgfW@)1SJ3W3^fK-bz6X zc{FXrbjscn_3;6`TkFo1;*sC6Io%cq2j&}2f@ssMGuAU*ClcngvaXT}tr!%`f2ziiFTMawDA3 zU4IY^?nI!V<_cVtfD3$F!(&&v{Ww%F-&vUkClk?9n5n+~2Lkth!$eUM44Drw^)n)% z!Iqg3JRwfQDOcm8j+F%wtYnS^zkU1o9%ICG(cN|aYbH6=BH9+%rnv{)fQ!~?hBS`f zGQ81R*W5k_+Age(a#!^aGmOHp9JA=R*E9R24msH1KutjZ5O->Yg%(hLwKn6w-sZW zoAYO$8Q+)I(f>w?uRv(TM2g_(vrFO=_kS3w@^V};} zZN7P(%i=uTJbz_P5y}}WYbkvjQ^lh78C6l&ZGoqlQ}4-}`SAnjjsvF;H;tk;LZDNC zN$+sRq4;~PMyml2?ImI#K-)!zL556DRq*%B@9jx{hYvOhs?LkhnXrQ<6;Kc`Ye~nB z|IYOcyNO5gR@epIpvPNf!JZalk6{6UuyR2Tp<@G&U5SSux$CkC24PibFu7YI zjci;&{UYI=WO#Ib%<8hcX3;NJ+51rwz6P4cs+ofs?z_T*Cl@dOnDaPZhL#@3FjW4I z*cFciU0we(Mkm|8f*0DD!$*x>J7AnjtyQP4{ zx4MVK@vi@b(&Xy-MV=>I_XceEz~ey~TXKyTwilkeIjX-%|>!P(&_N;$|9XlX+SoeiYHY#oy zr&F9lfTyfWK!xp3L7aww#2wKJ{J7Mj}h0Qc(97m4JX4-jD5_8?TzO|PuRK{PEivdPhJn|?C>DHu)*W-1D}DeJV?rF_D|O;Yh#DJum}TpX!sBe3b%CGi6J5DKs*E1 z_J`*$vVQt^Hr)|wH^kWJ67&&CDc#V}XOo$4oXcEkBT`!&R~zCwoLuCB?!V>^LS_d+ z9)pcCV$i>kVI7jIt0y%+ME>u;ly$R|A5{r!)OJEx|IoA}5Mq%)L$K=p9+w1cU@D41 z_0m&Zf}w1gA5!8ZuIdZ?9I02oYMHwGMfZF&2^s=p{ozhyDR1Qw&_AUsbASVr+QNJ! z19yM-0|hX31K(MB4I&e}E;KLQzOBVZmn+)HG7yL2dfr2jfAu`!DM@>{b5IZtp$X zo?1%bo}N(6_aNhPzLmLQ0H$!_MVjf~4~aOSEC^hEF-^c)sxz1xB*P`D8Xp*i`KKmB zg9BEaDuj~274V7=-~S!9fCxb_Nm~2SA7&9bpHtc*_)5tAB!alja!vWTA)wCU-3hJ< zoflOkJq9LjKB5v$XmF=MJaS>WaEWLb`Scten*Xb?6*m^X5SD)Vz;t~axqX;_O{hz? zR{i#|A`F>>gF`{2nowbfpbV`h4kWU&&NX4l%@SbAi;zR2Y-(evxT9$<;0EH%>gYKM z%QRuNxLZ(zlC-F~)3jThY1*lFS*(t0^_SMm>M2llK@gc5c+UR{3$A!NoHx-4OO3Ax z=Mtmp96{hxZUW#88wecihFc!<|2D>6E zU%9IV@Zh**LJXWcOz20oT+z_OANpFNmLd*ENZ0@z;SM7vcX$%ko2sy!KpJS2(pT6* zeBv!-hud#A3;wAQ8m&Jb?S&0CR0akhck2lY+ONydM2lekiag8^?!S zw74PWQX?#;XLZ5*+D=s{9s4;kWc8Q^QDh%YFKpU^?x?^0-6_)sXus~{{Q6TOG%Xex zrQ_v}I`w1VKV*;DW0&17trjbyjDqg*cAdY^SK353Bdu?j$J;y_WDT&K3!S;=Clff^ zZ$m_Ulbe8ZK2cMPw5h6X)t)T@tE#(Vz@QECBHs#H&3Esi2#lYg6> z30e;JFSa51{h>Mh(reN>ZgdoD#2OaVPsFduvP!JoJAUm;yL(;Eocu_MgS$Zw_nmLO zQoq9Xj8UlF=I@_Z(VC29mUEMCs{B}^0oO;rmzp?->d%{=$N|W+hR)tnQ23o(l~r4( zAm0@$WM-XZG;IMB1SuX$Pr+ZDS&km+=sV{xK=HWHWpaFa=w7xUqAnMm4QCOhnGwd{ zOg@seyH^7iRP}g`HA?g)>OJW*@AWm3JkHUK^+?S7KgIK1#5b+|S&=8q(w%f)c5w75 zpAIy&>dU4WI%P1%Q418V2R~Y6W=_4ATtO^_uE4!U;|^pn9_UDQ{m9?oNz$9$A2>x>?0^B}a7C!;N zS(Snkm4~PJ&M;3360~<|t;?s^lZ0BhvNROy=JTj~!0*TzvQ*$1q^!kImD_2zREJ`6 zDZb2ynV#awcZ;$0KIWX}z_f_V&Yaee_uyaqQ{a_`TC@!)-Exec&RS-0UPHgqP_^2+ zLG1Fuvsg9bTzaKsR8i}A^-W#j_pXvxq?pa7LEoZUPBVITWZD!F)ZMmuh+cwh|50D} zN+LBlo^eyxc?|^$VssbXR*8LAIlau)%^ZHnx;&rpHzG8y!5!n1wk^T~oP_a5!itKZ z;!Z(>E;0XhiMc8^g|Afj0{$bC-r;oH4t{3$bgQ|-e0|nG`a4+8tC3=>oPW|jQA&EJ zZhC%y?3Y5~M$_xEZcCeA%j!DK0zqDdfWUS#T7TZ!>>~m$T_`z92^7Xq*2irxtgxET zvjKxel*I8L3V?;yNJI#y4z-qoUnTCN2XWv{x z2w*<2s9HNtMPc_V#KeXj3dp!Fj+@aK#VzdshehP;-O95^rk3Kfwnb_~NWGEmiXlHN zM>Mx5F6LJ!Rc=WG_3Rv>T&Bfn`ZisSG!8ZRD1NjF4l zBXuBqVRs;%)%uG}H!MVuhha82;VBw+=$Th(hgjZy$YVjjP$A@HSr)vo+m`h&m6s4> zU=#%2dO{j7qUB~xv`BX-x02ql{(NFaVlkzt4z4b)cI8u&ocyKqWfd+ZM}2!qnXYr| zk(}Q*pD_BS^B?<0r_~^gGfbtiZy!nfb#xP^GhfQ^8mG!wO+&{3<0)THp+@QmzR4v{l8$9KZbz|BTXhEe=2orYaOhri;BX-TQjroH8vcsQ%F;3 z;iWA%s$}*UBj^neYl8a3v#l=u-F8q2?l*qD2K38be_^q@)r9?~i<2x=!EpZ!u;W+v z27bf|Dol9$8#WllX7CM@YYVpiTX)wFEo2(-Ia;{(MIS;-tyIfTM7_g|!^M%J6v*;a zTUgi95|#d1GeX}LD-H~mE2hzuqLjqmqsVYrd`WztLX4s2D#bE1F74T#OiK;{W3DqBLq zdnzqkw-Z!m9z-@*1ddBl5|tT@ssZ;(V0*>kIT@lz{oKwwp-->)e-aq?O)X^G#kI^n`JdYCYhfe_I;UKf)ivBG7xVIp<#F;?b@iH zmtS4xo?++feTELE$uzgjVx$&#SE+ay$dZVG-bAzG2&M8l$>nZQDqQ&~CQm*JbDOP; z2;Eky)uL>I2m;?)3cn>7w4#Mz^{w&Y{(cqnO1Ah6Mqdem-50^gELzH07c;(|oy zjENq0Y1t0G;(1C`jqZ0b%OH%yqt=i~DrdHDB&nDO9yck|%i^Stj=BW8f7I;R;9Vvx zJ5{Dm40AmlQZFf2N-OA@D@ctad>zMX!JYBhq(CZdhqLZrz<0Z`oL=)j-$FFa|N=y6fpsnO#V`MVnJ_R(6yHC5&Rt(QTY!g16N(G7`*;Sw z&E!;K5FFWJX;@IwxdMpE!g(&f@!n@QchW%4Lo1`H6hRQQlVVG)DnkKgbX#Jr$qsDt zvQq*glkLVVR5u|1GnEAL;k>t@eSciOz{|F8_4GAFBrRdO&y6QD&W_S*yPjS$lp6TQ zwGCuyj1ym{Pwb1%iS(sJL~-dUhitmN!k97$3Lo5dvx~yF5)(-VoGm$wVmHPAp?Pfo zre+zF2DYL18cvopQt0jbmE~Y@=5Xk7bA|F-Z=JT1B9auV^^{ev-YRGTg7G$S7OJ7S z)08_8uLj#sgeUVn&^y1{0{3OS`=i9<9CpFXT?jlj43tHmSqR3e2XvwZ4zd+*ZnI^S zu+E=Mr5MvV5SxgKNRZ*Bl+%=rd`qZguea{(N;xqg>@&@d0P-iLZvs4s6+=PRITEJk zy0sKy89F+=Oo*`E(1&DemzG@dqv#@=t-V$?qQUmS~va?E-WA4f(BQbZM_ooyEt zGPD;ChXo3ButJ;_=IOeTja)dyR+X=Ig5HR_p1FcfGtbb6LqExIC^Q!+3P;+A1yg{m z3Vf6oaAljo1w}$-&Y}xTX|eof^m!*NAJLLx!3>MEiGw0Lkl+_w$C{*ZLuFB9muxC9 z6~^5d1*hJhGc*3J^ofy8L)`@-RW)xO1Y@QzW+h3kq#3vZFh@1*MQzVb^-LL~u$Is? zLmIKxeo*9Z{>8;64o3%TPAv9j{0-+9wH~iwvq5I>79V~gr=Mq>Ll7=?c24&*_5?|6 zb{s#!kbYS>6oluar)r9Fu~rWo0&@ku&`nRm9B9-7|JXCeTZP~(Cly`rtldXH(s!3| z6V3WM;ba&g%f`#5y~8p6Nwy<}*Tq6t0L=2p=uavP^|6xF_%ebJXaFCPwt8{IRd=2J!ka(T zz~4MsX0a4o2+<|$TSNmJ2tp`Y9^HprE5r&wg`hddg22c~m?|c0O{Oi54?~LgFC>Bx zU8T$+q{^R?m0Ve^!We{r)y|g#)F?59kXQ6TbPO->=^dOq!VBf;}yxn;99m|dS(D`MU7nR ze_r*9CFB+tCYWHr1qUTX!y(US+ZK^{Ac~Cmv_q_EU+3@s$^7j2FEot&&wn&nk2t}b zNGhY!IXHDHrXt+=; z_8svp-xLX83L6_Z zgCMAv$at#ZYiFwF^E^hW=G6cUY53U02#L_~5^79 z+Jx{Rpi{h%NbC$EnhDe7KV@rFV>A+K1NFp)t8K{3J6Uhs$lzl=ThAmI}D z(=gi|Fv{xyQ419ksM?xD5cD%phw}Usv#SH&nwS+zePGOM=A40Acb80t*2KanuSAks zf(#D&FIms~o8TBP^4VgH@_e`Aok@3nijG_>m;Y6vS`ax9s|HG?8d6Hj@NiS8LF}S= z&tVuj5t2gpv>)aeqd*{H#6ThV3H=O_=nxU}Pqh#%`@o-wrd1o%w=WEzj0HT$oK&z0 z+MYOV;bpdbiw_t@`y`tRPSuz*!#iG92mXB<_T{=3iu#xVt~G!APX>02HjCa-F@wZZ zB~^oxFr!+>aX)|5r5KICxqY(kptRarZ8bUeTP&?5?n;H{ojDy`w`+(MWfA~UXdHZ}H|^lv))% zFs2$|hW}`SA`SL)q0_JKRfEY~U-B28V|fdmhMu0@CX!>0J$N-;uhhaMkrGP=B@qk5 z@WJ6_E?;u%K&n)!)oYL%ftnCY1`eCPCqM=W=Y}%a;X&?Hi+ySx3Ub&lu+-KO&ys)$Hz5PKu|0!Caa8$LV=~ghNX%;UkRhfiw;Q*^|8;3AT0@k zEx#MPv;(T4BIY#;@-K9l0>vaJ43Ry=$lC8O)t!J2Hhpt_{&t@ps;xQ3f-&wE$=ies zIfmKP#jDSFs{jj_YXM0P_Aftuh!G zpUB@To+Odq0T^2KmC0nTaugc;W~Grdk|K)}RPQt~08@+dOlUsD;(JYl!vRAEn#Bp$ zZ-uQwb)zmx<3q~xCbQX|CtXn?1+33S_6P!v)fZF7Zq7oli+!s?_veB$?b|NYHTNQ2 zMED;+F?H!k^_~uEcEmgRdf+KL9UfgGMmz+bGC=T3TwGpA$dxtxJ!C@L#Q#z~Bsllf z&Pa}aiL%K!al`7z@7^Zqn-JBT85`nqC5>0Lj1SyxfsYFL=@MSL+2Os(1^P{S9}e~N zha1+9FmE>;GeZ2qG5%Bt#TY&EAdc!!5P9@l6noz(mKVpJ?|1ZI%2$wwUN|q?i@Xq@T|41gaP# zOr5y7rYP9X_cbPQVo+$R`G&!kjcVnwnJ_mJ)V3WEy^aNlnF3J5L&8xcl@Xjyu~DhV zwJA}}{9>N@D%>g>pYtZa#aQRPh_}0!coZLwh|x0<-R;1yX`}{c!Nw63F!+>`I!*=G z-+{mcU;xW)gwy>X^598NUT>G#%biwvNo{?nY9+Vhb=#A#5QW9@e`?+(<&z;!6?X23 ztqyUe`%Wp7>v=}S3V5>L*P(|GZHRj24!7Q*pum(P1wYdoYmA!MNC;odTCwNO+I1HWzx2V%Lw%Rd&ePd>T@L&m@IM+2m4sPI3@ z^M4bn_fFHi7F0pYRcI0c$9IiGCaIHLz}RKD23rHswu=Xn&AzX%u%?Onfeqr>0Nt~q zjv$--E5(;9L&I)N`Vy&exux=NUm6!wq4Mr3V+Ra+Y=Ue*vV z_)61W1(FLVar8wHSgxpBo`)94l>2D1y1H}0s)rv}!wM=Zn2iA`BBS`e3(#U@Mu_uf zVKB~4olD^8$uXdv_j@;~V45vx+%6l!BW)}&N?NkIcfzdyy{#v=vf)fN%6bhgG%4{p za9x_<+>hy3`bW^z_C3fo?+Avwx{%tn*dz^TXAG&Db~Uy6)EXK zkB%rbv{p$Xs2fd;m+1KkpA{dWa5QAeh0R3~al`kjt+2V68wC!FpemRU-x~uEC?z9_ zG9;?y_~zq+F$%VJ;wNk74>@W$gjS|#?h57iH!2|_=WV)T5ulrsy;p*e*ka*JBTT8O zHf0vvm8=@|=p!MdF551b??x%elI-D4!r9pHR1h<}RjB(S;34pG#YC}fu5Wal#AfgH zS->n=mO-Nyc6R{A+r_V^=b=07_Vr7Q@O?p!S7(uPk^%{7P{@6xvz~N;Peqeo-BDUZ z@8pLbIf=A8zVCcApG*DwSP9jN=1y0)xqaG_yVGvFqqpkso{noJ-(Tfg(~c?AhHZO} zj4wHCH$`#^LCLanjspDXCXB$;L4a8tf*DDa@5$C02u$5|9-cYdEP$;8ZQQXxNx_dU z{;25wi9BzgKE3f_CG@M)J*YpL=+d%Ecbky6i&dX>SNl!xnZ}+KlHRr^*|Sv5vEd&C z+5v$nkth3U1PTIY1f$8ePU#N6VTaD&Er!DrU@A4_i5z4bUZ++jyG>2C7gz=aAlY(^ zpwkB6vAy_u<$Y6j9)el&!CPLq#n>RodECiJC}3XZc%cuMSe!tdB9eF3+M`m1$RPub z0+4p{Q=EfIu+6Ww>UGyo&}WdYlBm=Re@^@7JY#r<3GFnwBzz(~+s(Rp>R1?-$%wt*|J(ocwlpp3I6C_qTt3@fU0q!%%#uFm zB7en_l(zta%tQhFSh*937yNysf{rILft+#lQ2BxCh$vbd8BAmG;L7Ht+7``pHq(+i zU>EM%?3P8ztC$KJiDRgu0aa-8Y%`y#&97E7wD$$%!NX9Z4a(7btOZgVHU@ zsw`H;urVIFRgC5JX=kx)&L*kDLl*c|sG@`|`bE{ZQ+W$&)+K$=Xv(w7PcGA%KbN*_NgN0} zc?8NTrlh$3`xi(`x_!qYP}Ppty6s^)1O(2E5|rBFX4i@2UQ|<*LVdIwqziK`jwyuX zlO@>iQqG#bw{-u2iUjGCv97)?dq0^wUWn9BLUM!@>n9vME1ksjJtnr1hMg6?C^s_n z$YCERmObVuT~nH88 zjsU4S-D@Q~_Hrw}6lxqzG7S-!T^K-1JYBHWAZkKeru5rN zY5Gw-MrORfdU4Zg)PvL3urg2Fd#Z$&5}%k)Nh)*bkDa>$#oM`=YLY(wnbi#y0dP=a9dB<6 z!=*7%1*Der47|Lp0)x&QyHBfQ(e07KEx|M8GDShrND`?73sz}vsS-j`je1&&SOh`W zqJbkEF0m9tTfuroVOkC;y=Z%Zt56@7Z5NHmh`B1+hjyM^$R>YONPxN|?(j&upvXBG zg>#-I7+os^WsVAU1+%q_XOG3Jg#0%Ze4&(aR8q4+c%4RaIfJREAHH)QaSwZKQ?}Lw zuZ;8h6vDg{41P#tqIRlUW^aA|g*NsUX8 zYNO45X(3>dJY~q71Y1au3A-J^WC|5@9;h56LRL&(HfCzj zYX5ar%S+iVj{*A_#}{^g=R{62(D?nUlc@cnS@VZcJ~Ot_R)S`qZ)Rq{@%6!_iXb2e zeb?IdhuNz=jq}a-Y(-&kK|C_1%KaPNNTQSS@Y_geGOsu0Fby4BltH}853Cn5$|+xA zs4d|$UHRq59m9lf4+dJ` zk&Rd+BJ8i-QQFSZJ=4R0@|94$eM3T#XzIdcjW7;&tI?_!uw0X*Rkn$`ECmf#?T9hi zDacHwd1?wcDoaSmmYqbsX}-4;3xep%ps_njLS2_&sW3uLnk2T&BJL@DI-mkJCF5pO zHuW+B&`xxANH zjFIBV7jN}}&88d{cXL~(VKdTC57c2T?TxnetVIySVPN1ZTURc<_+Rmv4recsbVmM~ z8wtm&YUq2$gr8U7ery{yc!6=4u8Gkih28d^x|7y8x&$kb5!NKp(qd$h0HRi0on+27 zt(5$+cZ9AZGAqY0cyYtAlT5nDLd62dKpz>*{mNL_JI#$Jkr?0rRN!i>vL_kzCR^l% zhhL)bIreeIbP9X-5(GiyDm*oVt8!w7j^h4PuD`mb%>TR=+_OSN;ojcIx1ycwYw0&i zEcOuLVnaa)TZF6Dgq3hPOJF)X0GxjQ_)$#P;Z1NXkw|6_bBA(kqMe}aW~n#wkJ3J14L!2leJI!k(8dIaW+*~(Y`8~Rmklp zbRv3jb+NkI00PsPvE3bRb}TmZ@fAe#?2~q$@p4f1i+`63*3XXzn(~mAE+$idxUSb* z46=$s!spcw`tYSIGE>&0`x(q$#3R%(^c^NYzK;u0v4ZE7PMCNV^}Cz*%7C)V)^V0l z(Q;-yb<5_9Y%>fw_KjLbl0oGTZtSJPw_Ln6G!A>?V9Zp9rGdy8`Ac`|Moy6}36H$$794l>jK%T||beRXjBi0(~r z_hv}lGY}UU^i#ciKU_C$!x?3JOSF%-kNg_37Xr%irtmwC9{N+*#c}$?S5M@AS(a|k4t3p`6NPeo+HHYp+NuwW= zgvz7UWm#4Gbts~{A~oL(%N}1Fbs~>Ii=i1W)W!>CC&BkBCGJ{)oIrTQuJ@wc6xql) zs$0Ab}cUSO;}yKXl#kQ>BxVO z7N?RuVxDz2#IY*GEmx}Djw*$ilrLiX7CQ1*@pjdnv5EQz)3>dEEo;7mvkw zwrEO=KpsO^uL93kPHftArVpfLM+9S;CJas)wxxeL>lPc+n|>V&;He_bRRD+G=f{G6 zEf*(9G~87f1W%}fz?JNRoM!|Qs2!W(@QPjCZ3O6Z(ZuMwL&^K&U+{hhLay6S%ki$x zlQM#2x>;vf>-wX!8j49)Uk|Y*FqX)CscR)rD-C3YQ_4Nkb6c@8sw)|!TA@j>#TDgx z{o&Z;7}phlN6DCM=5>0jBXLhA)(Lzv=IpSv^Fv; zQeUW%8jq$}L$la?m#rm_48^SYHlkY9O(WZ(j<%@C5Z8Rxf*c%_h^C<9O8L-d+q-XM zIkF2yM_Q5gu1lMQr+?_QI;18xD%f+tIE~l#5lQ-|AjmpcVK3JpZtWyfQaZcB3-fypV7QM^uno+r52mYV{N7FRTbbuwz$ zl7^(6g>x&1nqDrR)1avrBi4iz3vkBfA64F}=mwHJmR(nLdKfZMi2Xf7bg;DP7#Ti= z!g`;B?G)X1To5zUz7J@8Ytna{n4xXASeXyDizPeqNd23Z&i<}r>0ZGYZ`I~@+k=~Titjan^oBHlgK;+ zf%PjDanLG#olMUP$2%%;L_6$6tF8EU*F7HJ2gUTEQS3e6yqLXH_nw z##AU+=pM3PKXi_*m(vW+EFmUF;c9ID^S9lW$kH5SF_`zD)v@u;<~o=W!|2u|wK+nW zE(Nem-1}9Oo2@c<&~>-F@lw?RO-P!HD^r6wEUYXzK#)B||B3M1#{_zQPVO$eOACO% zUlaTGVpDpy`Y4~6)hwG;46=)ZvvxgDAe;%M+a@xYD|BDi2MTbsjVqcd!No~#LCtkg zcZ3ylICYn0P#|7KmLeoW-{kn!Ho^>7q_x@vEd2vTec;V;rc^eA?2=8VhHSBQb;fM9 zaCEZ={*H~F6O|r$a$s2f8r;>IG5BTW=h*2Z%Q=ax$A>|p2`vwl3#t4IAO2yHY+t1% zLPr%cb;#psDnP4#F}B-_YX|~Ii1o#DZezLux~=k?7Jdt80>i8FD6{zUL6F3fs5Yc{3p1Pgt8B8JleXd#-eh7iFA?!QZ{{d3-3W!3K}O-gM(k64^1Bd+Y*CN^99YG<7z5 z*SGDoa8~0%)VW`C!>glY;uT{9GWl*qjO``fVtY4X+$3A2*1Rss)y?@V|S1&KX{xrG@Du#i zS^mgwG+{*2`qqtQfs&Lkp_0**Fv{b$vR?~H79!|a>o8n&MKbtUm{=kVU*s`g{-gD? zk@W!*!Jfb{EH!M_Bxp!jBylZ3`Sy^vfd&DBFa+D~vzX;|@+bY-ph=Od_dZW9cH_lw zTci~PPcOPkO)t8ep4Q;p@$A83NWY075L2%Er6|Z1V@a&E%#Y9Uewuu>KKiycs#hB? zzVkzEgT*f~rkhkO#0so_$YjkdYI`M2RNQ21F}$@~R+Ke1Ok_e=M?K#z%JoPL&p{Gn zpP20IX&ryT(39C@xOGIOwS+H)5GjQe)ACtZNoPWd4cY~wh{=oqim4b?yb0;~45h6t z)N&<2U=?&NyaaUKJH@I%`vdeN_Fy3PXc1+3nF0eef++ZBhPfB@GQvUa!sQU{1_cfT z0cZV_!J?`-z>&dYqS?A!?7E)mthej(>8HEU{u8uMeT~9{%Fv7od0%^VH1%EzP z-MpkPp8q8eFE0&mj}<5KSPU)!NCG6O0@cMiiwn2aB;#B|3Qr^=S<_u@Ux%rFP!F8C3B7u;#F8YXaSOHuW*y^*@ zDj!SMC*mT?(pj}=wPYe#vwFJFQE(Lt%OQE&o08}N9?Ht0u~$O>}~FCU9w@wsu!XJdCtUt*DT>beo<8H}Bb zvaK~B=~_XJg!#~s8_j(>#@UqoC-%k_pUQr7oM=#Tdv!Svtpc(Pf{^~gn1@WR z=(Z1Gx{^|&gLWp6?Bo zyKHBFt|VYsWl6!0iMEf#cO12-%@T!|u*h)hiso{=vm$G`(7-8V#N=kFgdKQ{;I~Zv z-Q6VOx5TSdi6Rh<8r}op@42AcmDNgoiQ^VR-;>f_5F|exfGz^0l2n)#WgHk(ZV&5t zpKpNoK5o%#eBYN^YotYx3z%boV`@g%6W6uanGrgd+ETE;@N44YE!;)mIk<@$>is)Q zS7WxNh_uMN$du)w2m;F4Rm;d(B*TeW*0SG)lHjC?XASCBq_ewWD>+)pPyCh<@tF+2 zq`xYGUHQ;4O4c4>!7VWEEh7b<@OA zNLRlI1lC5M6QKK55ehIG#mSTGTh!4iw8u%`pTm}2#eI!ErV9E0MKl5oFkq?&IB-{+ zkco@3-P7#f}Zoo0#SPTNy|}C)T7aZ*QEr z{j^^ACteFCuEGfd$N%s}2aoo}8bklkVHCn9h=^ENyxoLeJ7c6^MUHi{0#n@ZgC z{eW=JON?Yje>=ZAOf=$!9t7cH7)q*0(!wzq8DD}17f}%S#_+*X4`&PwQDs3p%&kH& z|E(mg)2vEH?A&P7bnTq9#xysVN{v z?RS0>AKd|o4zW!LlBf4T>@C6M*(-~ z1`Y55&Rx5M4?QH;(laSd65uPrVs8`>qjcn8M+x8PkZ7CL$(+`}+jslLOJ)WF@6|gV zOiVY;p+>tSUZKW2ZCyk;11xlGT*Wj$Pwu-F`y%(E>pV+hF){3h^Q*VJRlDN`t|{ zMA8XOJ|F0eb>%YM6qaPNc2}{intZi8Ikc^e7YYzbhykmw>^hh>3=a#)si- zz)I>&E}N)KlMAPP6~A7;z4Y2r2=DH;WAEFE!CW1!w}K~+r89J$I1;%_>bdLHQ~tnK zSikD^Ka#Hct*N(-(~Ju)7%*U@gTWl#4N8peZlt>^FYeEA>1r`$(E(jC@GiM6LSSZ z;ZjAvZ?<~{I9DmYVL6pNr3}0yRg%r5II~iZP?*Asr_wyTK@we^3jGP2wX+VSWNyeN zEQ(>S+s&~>g@BpJ?k`dQM0pW;sOK~yc$7_^JsLa@8&GaSM}{(i_=|}b=*ZsHmENBV$PqNpC-d>E z*4s5$stG5(iE25DMRo8c;Dyv|*X4Lt+z!OhC{MHVmy; zh_UUV;x8j*|MocqEdLz<0Ep3|i9>Odx<5V$*v|p3uSUcd=M8YyUaD?h)jGdUM0~Ht zbK)H5QDDa=wqzvJ#cS_lt8@6;%Mzr%cb;I%|)s#HTf#34y&O|y*>)CY2vDcN`ny3xkXtl>=>DfdLId;q*EVBn`{tV_Y#O|R+vHSs858`TZ8imCQ&6RK=&R$&YS@zJkq8iB7V` zZte`ShX~{Hsc*=n^Dv+X%SdYifxbq{nqylRf1Q8xpO%1^XER_9TTB&(<<$JvkxPb# zBO3~3k*VnmO`5GL3Wk<^lzhch3C*d?t=5?e=|-}PSPP)wx+!ZAc^NQMp_Q1QZAylG z8MH!@jZEFNsa4dqSFZn|W8@{n`oUdyhrMnAHPfkAFleCZa;JDpY7_wpX5-$t$Wq9n zgizf3N2J=%_|0h@c;U4;Rb0m9MCXj1va0-QCp>JFxpSjs{ z>V%|^Fn6@KgXx+6Tv_!OhsE2Z|2EmA7*Cju_@n5&cZo3=qQNw0FRmf`!s;uQx?--gzhJ&WqKX0#qfZ*0oT^SXWzS1C3309( z@NW1@4Za25%qD#rGLGUdvwMf&dIz*6{BeyL2(J)j42@Tqgeh3HC@|*1L{qg(<*6mU z1EVJvP4w#+c)q7uWh$W32?2`F1lQyPbmkybhYmVWW|Z&H__j^}Tw% zQ+k;A@8P}g24!#5aYa6}4dY)P`nYV*_7hpZX7P~l4~WrJb?|=GYrcZQlm=ok(=p+7 zMb9(!k_$k)ppHLMgG-La{Q)~;EVMg4v3G|f_EO5A)UJ8W7W2ZYD$xsFM>qROoBC#Ml$7%o9Y9&MJUg^7^xbwzE`3)~AfM#|p9Xxdf2pZsf}FAG05H{V0P2Rv&uCe=z)D>YqYPDU&0 zo|ZP~V1?BIfyZ~L*i>Kh$Pc75qT^1@8`KwbSOgkaR_Ep?YXt4X(^Eha;g%Es`X2jV z``i70VGb1fMD>vEDb0&r`VbP}e9jLXy=57@ys1*8&m~-?f+f}kf98WV_ajg_d!aOL z@dR&Wq#P>Wch+zF*W@|!F=-MXsds^fLZo?O*yMwkkP2byQFcjYqd4|f~Bo+)sJmj>`gWzyk*R``Jdf{l)XK!lP5e1sRH=51b+MUpE9gG z2>yIU_oX?qykivl(vrsI(`aJ1(SoWP{wgH1O$o*WViAU(rB^s)x{YDdK(cw5&B2#7 zAAHW9KA*T2pLp6>Wwa&IS^$BhIicpE8)0e6-w(O8RuU^F!{?k6F0x8>u{jvInH7n- zSurcd5{qvhPr4_(78D%?KdPUFWK<-o*w-zrel(&U6U4OBP-hJH3rzn%jg9md6x*4< z?{Aeyw_GcYW$#H6@=;*xPC2CgZ}=d))jVsbod{Q}hXkrPfdB++NUYEsI6~I|i0nkj zYYxesGa@@Q$`k7ULp+QT9k->YOKnC6Iks#)f$9d?MIMuxz5Fj})E-w!d- z!CpAPUO*CiyXM_1H8lSPafHNKx8M?6R&JE2IM;QQR-;d3wjgP|<%$r-T;8<#puiD| z3hc%6fZNEKim_b*BmsN@B7^sl%Zq$@>0T9kVuIVLt07S2eW!n8&Fa z-MT#2si%5}%6`Y&ntXlrMa6~KoWFJfn$x%foOFxzlv>rAN=;9*W`}pdgqxRzC#>Y z3a_HV4zD(sDQNhqv`vA79ZN00pc9SfOmf>XH#f9 zHddXvVq{tVSRkL|cy*t&JOw!BxlqjvSU@we762*9Zx9EEMHsXH6}_x*roR#w{+ri# zY@A@};yQj4l_IHvYHzssV;$Q*Yjjx%FECch4VjJ{>>%JIIDRF%+gqE#1t{DA?jd>k zvx;}S8c+*P+a1xUoF{jN_e2_sG{ST&82_G${q}~RA-SOFDEK$sXF06WptYd-lZwjggJ$ri+Kmv(OulxiMyN?5 zIy)9geY5bT`QN^v`}>4woZHY|_!*mY+s#aKoKu;yj)J)Dhe^zGO%vRdAMO=A#stmc z2X-5{PhJ#Q&7SgKUXupu-qHP+_v7UsU67t<{E40@8Bx?wLHb08uFkakNuir8Ld361 z;>RMMTe{r505(x56_QaO@fSoVo;(&+A~3dvN9={cSIdjto|PjsDv z9G^2)gFUMo(zxuVlzP>;s*|J=gFu6&sDx*uHjq(vqoQ5}L1}@*r+h*X_nLHd$+Z#| zuE;bjIl6-2&wy=gYe?2}xvCJ(VR{qDYUz9w;yM02+zg#`j|W9} zawREX<|DYre{SbQ;k(|G&WNom5)*?FAacHXmtk2M^PO2G!&l#9U$5MX)NBeIrmtxa zOsI}+v>=zQ&33(xg;OGeeBe69TNKEA2Zc$#EFIyHl%bBkwYr`**U`nr&1ZqTXRDQC zWS$Z?Q%UY-Z=0!)@0zqaa+SRP1h4y5*9~dZJn8XIWok_LC8W!R`w<kDQabm`N5cEhk)5Hm56#k*9eBRf+#+{0EuBuq&po$=v&`)mT8}STH zPu85NVpO0^V6KI24lF*^`g7vxm}4YI-r;ws$hf783)-=D!#}~4(g4OBpvdSq+1m_k zISdjL^cdW3@#lq146?75(CGUREWA-83ZeYEg~a3CrGI_ z6$q3>I9l!Iago1@EC`JW!y2tMdZ#}rmlB!X&jZ7;KQWW3*T{*q zZGY#fjzVQ>yO~@kTKBfTtK25MwL9BVlF0ibd@9^dM?96zL4xzC|vK9NZ55H_4hT}AWn=pajGItiPhZ$ptZI8^THpC zB!QNCP!R5w4c#fv>0nN7>sUE>j?#D}j_jiNP0@q;keg;StBwreqbnz}RH>&?^b;Rh z&8d9%Mv+OA2IJ6OGD@P6UB*L)+`74X@OzHK@r^FH(t(%63DN^JKGG+NKcC+`+W%Vp zF4kD~mUeE*PDp=_9x_qodn3s^Y;G$)Jq?A0MaS9eWjJ$7rRIc>w~!Fh7^48dP#2ls zsg>p7rDaM5AUVJy1I{=Z)|k`44^I))Y`$=WA$>X?wDoOHrLu<`ca>I!v8RBd&oFfO zVd-m0TF0*q$y;0s4YLRBf7ZP|6B0RZbG^mYjd*b8nyZh}S=T{VJW{F+$F~}Rk|*H5 z;i(2vH}CrCww46W<KvIOlx+6!@4xzY29N&tCR*L=YLl+Z zi4Tuad7cZCjMV?-dUK86h`hNS>5Q{%xQH>q3?MN3=NZj~3jH{9N{mHE=Z=qIXbM|r zR5AN!&v1_bfSMx!YV*8NB6yF1?{opR6bJLwOvl_=M{K~CsgfVp#&)&U_0wly`Tz(2 zK|E_=Uj`ym{I$Ovt=zOtBqbSG;tS5J)*ZX5A#(SCk=$45OD&Y#&)%-aTpShkDI-yp z0sM#Z(->AO;r9oNDeO{AEySnO7Meyq{G0Q09?rML1AKzQLXtdl1LsotuK2GMjmnI@)R=>%~S zcoH)j0OFkGwlZrkwp{yr6Z$vvYW9mh!IrvqW=(XCzWw}tLs}wzI9V#Lr~cTfC_{{i zN`7K5%LbC0J&hmd^e=15i7d@#WrIKnbNZ& zOC-kT*V#K^ZM)SH(W9VE4T~@f#_rm5zqCR9MD;Q!g|^ze=E@e!St?Y`h+qnQB*}t` z7zz`RI9nVE1~-RU=$!1z`dU36k9}La{b*%ji>9?!oV-HL$ZpG)*)PTAAh~M)09QQ4^ySsDvafPdW?@ z^XvRk|G0kNLWu6Xaj{onz=EPDTE0NOl-3e(k^)?EcU2g9%1Zr3`KG_L1{5s5 za_Z@w^jkT9-~}tr^;Ea-uvx{Cdwpsz)avf;{ZwFl<-PyiepNd>>O5)N;PFJe!r^6? z>zOWtUVjHi-76P-W4IWm;!4KPI_t1C(_JRm+>Fdug&NI5VQEagYym&0hLuAJWX(!X znL43rz>-!1<2jo{m89{o853izIp{rqBFXTDHDvdV+xx4(8sHGz>1soHqDc(x?Ugm) zz|Z?R;!rz5?~QDE8FKer8@*?&GK|yPZr}G`C&D&JMFNc~@f5zkzI!A2_`&5RF+Y_t z*}?}sEFv;P4KpnHjD%fimr!QxNTGTEU{ABN6ldp`Nc7C1Wc0ahze+B_3_14;g<}CX zeie$QK2^0F8s@l1@Z}3F02a+RsAD~6zu*go%6VIk4r|NN5mmY4`zh+D{}oIJ`pjksmq>|4|CXy&sX1M@X!@9rgg} z!r&yogRF`cxk>iOt{dA}YSqI9F2$ulH6En)=_nUx_4g2&G3gIOOlN_R|?6ZNTpf(#CkdELokJE*G|`*5H2Oid~Csn8Q|0)EaJfu zBC#1{drr#cB`w=%8VQ@19wAJ!nivy;>gDY1OA{=!1T?V|_G6o=P-pG^*bbsfJ{bGdnsj)$z<#1?gRY6}@mkdj)H2}gDe1xp#`Bw=~T z6Ng!I$reK$hLFgkjPnxGKK^eu~al>19#PUdI3#9 zzM<~h@31fPKMgc@%wG~NzI5=?n-9n-ls=&(*TVw*ne_)LNFjJ-Av#>;mT;mNf=(R5 z5V>A5Nv6f#zqs-M74`Bq$|FCXZsGSV>FTQE*VumyM^!Yb^=wMTR(4)ICeC7$VMRG> z$)g`O!NdIYhVpUWiejf*dY}PkV$nUpk&H3te=Za00q9SeG2 zGT$#14^dwt$?WX&M)*Sv_H}>4Vtc8&58VgzmQjRh7a&*J4rPpBjC0CkG(YDhImDXp z4{F%!`uUv=Dnk3u;)qOEpS_!Ffxn{B#FB&5>{f%C-Va`{+7leEjHUiwP6}Y^apa7s zwqDY^TnhHE4lDa+Y>YF383sl3UA}NkX1M5abS##0rn(O`Bx?K5>O7=njEkLQBnIXx zN~92@@${~`oH{S4A&H`mHmc(MLfY<57FRR@3VYY#^!b|P<1nwtz`mUc)C+oqN2oCn z@#m?NgyhvBi7H)-*1z@Y@6UA~{DTwBqy3twH7dS`>&p9qd&RfL;(^K2k&4E$5j0ba zp~$bw>>@A4)jPy71^;QzfsbS#+_uR#*=fv_zp8O*pfLV@Uz)q`6Cmzx-_Obx9}kSg z#0q%wTst-gefM39ftJ_2`z!-$7_RsLAUsnVvg+?$33HLz8~)9GHV!xwP{3O6U3VsN zE@^P+>gdya7P(v*&rDs6mN7z@V|b@mAbBI}Up~0>q3fa2U^UL0_&fDRHl~JCi_{(% zaK{SPvqGeJScSp(CG!#vH}w&+SoY+GUbbJ>gqK$M+b5j^Uy4V z>CDAe5NJK?D`}CK@I+*fg?#lwb9fLmWk`<2IuKDW3h)jN5iv!BleSE5TRuE$ZA7TPJ3J6;w+CD7{{qb&lx#)hbTU87Nco12@Ix@BHcxWPK8F zv$!!*tPDc+SWtoqZ7W_cjByJ_cCfNeUx!JUN@>-Ibgvi?a3gfZo)9{g$1n9w?d*}x z%zIR3*m2mpBh6+kUL_|{@QSv4u(j5I+gX}iuUXLpGpMJgqu`>sGBkETr=VoJQrtB! zshm=J)*|_Zc*S(f6VSSftfT;q#NCRj)_-&Tew-lidDpluGf-y0V^LR=9ijYR^2LhU9e$aUpxB=9pV^L&ve@3a(<$PGYB1$+0*s%z_1-#66FACPMyUB~KTS@3J_Xx)Azuo)(E^2$5|kjF#wJ9!2!kkw3eSEKP26&8 zEbRUJW_y+@85Q&WZN(lVg?&q~p*MCJgO9E1c0s>qZ{PMm_sCyWa||B(A^$)pjo*}o zeCm3pS*nO73O|`y2nNEH!U?&%mtE1yjHEti5q>*780o2@pv&isg2K48e&sBu(B)}u zT^`9t84OI*Y_`*%V1uKFK7{Wu}GND^m=iYN4&>(<}GT^px=FZDQ%ox>SF|40!8vK1%>d=~j& zq@)m&o2OqDvqAhu9kld7Mx&}@L^q6PC;bjgpTL2%B;$XU^5?ZmA zO6^ z)9kNK(`w=8E^X5-(O*{9I%NJWq|2lfmyI{?99y=)2*3l*0}1UV)XG{xiO@d^@lM>1 znzhj}BKxH*0V-6I(Mt^W<*CdKJeRmeWrw&p#QWpmNCk?~21+^9+$drpz+bB_as(oH zTGk50hQg`+t34gF42=x6VJ>8j#EuWf%{MH7TpTm771MSaRjGSVV<@W5$7uQCr(@eV z&n25H&wMytc1joyrn8o$L?9P8uXGp`<{3vtFtmv27(gzsLTOCN1`vo8z|`Mb3D!5z ziKZ+Wnq~lQmP#@**K=7)Y~qN@(U z)!DN6(MB-rjy~2V9m!M^Aw}M}03rHeR+P}V?yhdj!Q+?<#{cl9KnwyA`*vLHBqPJ? z6p3M>zZUouIg5b!$XD^IS}R&1LD=ky8O-n>=|zqn2}TbWrf{+p$ZF7Y!%N^%_h&?(%Sgt>Wp%}}fd|P5 zsU24nLY*fFkXD4gvA6Pw+i|_`mdxex$L?7!?bo};qq_QDrzuO4EHb{RRVvl$!qvii z{dYg+Y}D1GbkB_isQktKJJw(PK#^xqP_lY~#S%O?!`R=u{d3~Gz%rr*cdqoQJ$pqlJ@hS|4CaUTdR`xbVW`6 zqt|j|6)rV1m1aaqB+R>KM0MU{AMG@7Ra%XCkuoQk#wS8vPzjeRksQ;UvJH+70aqHT zq_?Z^mcXzm2J5X?GP(uvhf!kTb(Jvc!MGH3$bfbE;)sQ2IOctv^taz76PnSG`pG6% zd!&6_A8*b85VYUa{v`Ssv$;1G<2rN}!p6R)DB`&NCdki+D3n+AW9Uw7xjxv%m~jxL z#rqnSITy&kBrNKtnlN99^+%%U$8*3Q38Y>`p8d5ds?9EZR$t@?oG(GPLTcMYl7^xvXW6bFW!LC!s!qs{}hTbzez9;)U2sn-(7rJrzAK{A^N^ zGr`ds+__j+5~72j%jVobZIpRVMlHLu;@!4nEj!gHaBm?nqdcp8b17PD&5~wsuX}Rx zOmz~X5iAi=QjfNdZivGTR`Z1EnHFaTG!8FuN2IAc6#^M+Y2JDAv z%QG}Jkz))Jqm*B8sUfmGMp>m|x2mvqoQO4&1$it$xmi1eQL?EV8}&1 z#gGRhWf(OzGg22ykh(Sn_nDcHYX41KY~ z`K^s=2*X3YUNMlGcB$V*NoC_ENG&ZFYdZYLQahE_&A@bqJjhZ)TYSWt;ru26S7i9! z+^D8%(<6(z(4;E$A15DJd^vWWWXla1AFnuTYy8ngu+(+`XH<)uxrcK}j`b^_=}zOu zxS6GE&KCx_RUp;#6+-wbktVnveLZb?REu zE4~A@V^!BS)D|@^lO`Q~!@%}5L1WtO;y+S}%{~FD9VLJVZ^97q(*C2l;Ug|D?wTF;!h32tF0t83Q(EecT7%~0m;APQciNg-_ap~&$DMDVhokh+-s@>q)XHDKP1abQycoXUEN-CinN zv(p^F>9F9Nn#tFGvw0)xvZARYp4IRJf6b0~u?)-1hOMM!A*~LDdRsE^+t;aUb6GGj z)Wm4>19L;U>C5MBys*e<&`ijKuvpRQvA7&Ph-bRnr_m1d*SW$&Q3_u1(wZp_+^s@N zbt~!iZ&Wgbx3)7QlWD@G+y0pTZKVWVjHE)m)A|n6gX8)#15k+l&6YW#|3DG3N*OVF zF*Q2`yDYf<6Y%Ts2IVqH(~olz^jMe{(I3Su9nku-=TpF&yKmLqYn4Bf`LC5p35uoY zk61>vy8p~B{dkvdVQJoMx{Fe&WDQf#<*`<`%Z-~ab-drSF_7~_iGu;9qDaJK3BGb` z+@nrI@&qw4z|J1qY^`%e_$i94UzJP|&g|V@L;JADVG4X)nA16BBGC+of5!K?}wMq}5Un#d{wpC{yGON3y4nm8U zIG#_1;c0uT1Yrl-%qXn5?9x;*qM;^>==7^KHl_v(UXs4X@ZE&yBcAH48-yF>gaMDF zk32>QNF08iJ6+`h&*W*!(K<+IgoPtZWxPgDb-t0OSvdE)ILENCA7y;>>|jmN>X|%3 zHfSh(YNXm_-*ikHcTjnoJL`c!0@o={-Wq@W&uEgbFi~GaG#;G_Z8%Vz z-c#l>bX$htU9;$*#Myvc-@NGvNeBZJhV~^z0SIZ9_-88nABV@F$$X#Tc!Vd_H%^n= zkwr3xS@HS)5dx7FM)Z)EKEI{gJ72x=K#Gmt&6WGjB`8@t%*H-?Sbw*jWpu|w`lz(ri<4olZujaqVF%It;^57^LZYa+=iwBRS^H^-T&Bw#DWXyh4uE#21laNo=_+iCi2H2dr<| z%SU5V^(2n1n0VE;DPQ+?U)IEuM-Rr*Ho*ZXGNB-kpG;_-L4gO+Nx?B>BAZKi! zL8R0w8|e8>?Nfzqxudbd} zL}@;rN_aRu35kR`0AU5hz-aBfmVarIJ8JpWU$bC^OwZGTPo^oaL-2tP5JP%gF;{=-jQUR_4`YV3p}eC@a6D&=v? zWYS4-MOT&ETZK?((Glq1CP<37fuX|p=(=g*zkw2b5BhoWO3K{VMX31T$OGAMf#?lN zbZja`u2PVBrjI@Q9SKaRUzGtnev;M>>9ie3J+LBggf5Tolw1L~2LlN3li`iR1mWwy zdrdxzIR-f7IcoB4>i?FK8p{$xMKl|hLZOkir(}kUB@6ZM9+$)5tCABnivL>GQIm=k zK%p!}GDY1b+FVy zVl9E>)`_=pmBgJw!)1zUvj~gDpM8?NT?ONE=$m7OYmaAb5Q!Ns`~t{QY#vxMRL4Nr zzs1@UK;cUzl)X)9d3s*ddzXz64p-BL$8EscRZ*37wYH{pdQ47aE^}9=^?Mh|lrYuD zGq1m^#I81Ty)}%YX^PIMx;T3#QRoMly1ssCX+>VFXnsHW=^hoO9zP_a z`PXq~jlvgzEWyc8rlj@@U3-3Zo~gxtaTC(F-b-=#H6fub0K8{&1(1|qbqNC=7!Cv; z(uT+hNB_pfydOI#dMFfPcHPm+mbl#NT%t9>`|J1B+e;k(Hat8IfQXi-o0r>`aSR6u zKpM<%)Qu-^#NYMrF8C^WBptfZ- zs@MIg7#msvM!T`*flcsNR*|-)Mth;9!AWknZuSrCq};3%r1R6 zNAp*0+}`ksihcdBj%BAZ^$odT&nNV8DBS-LN0b2t7CU{_&ysJdpv6{9akevYrVaNT ze5;=`c}~23U|iX&uZ!1wVRBBGb^rdyklY;R5Biy-y0c27Gd(hw3*7McdUA)ui8ET8^ux`&kFWg81Y=%b%jxULvbL{CY+H>IP;je`+Fi>%P8ob^b>C zbUZ|!pr3W|_@>}5M{^xJVHu@C;?VizjbNHHQu%E%cQ^H#p6m?u>8`Gm-?f3|#-5vHLp168 z;(dX%lp(dYFEs{_QmljcnQjo@%z+xgBoSe@ z!SuH(eIPwIvf_SQ56%a=R%n69hk+gJ7Aot_Z)hg*Y6bNVV5Qrwi& z^>N2H@(M75aN?tc3vh@9R)qpRgW|QIiAJ{ng1RIJs|MCR`bnUNRwb=yx1r#_PelbZ z0&;YYUibrF1g!i8^ejYJzP&da*gM%u;?TLd_!m_5R}|!{{P)|G0qbz0?n}%wrhGJ{ z7wd><31Z+fv&7M&svLhdDP^@?$CJE`lr*iIa;V~10mWqg}%XEvkrVrgFI5GP;lTJCGu1|a?Vu_1m{06poMM8rXXB@$@RGwGvCNgf zewh2RalBp_k?piu#?*w=+8xSCAD9xQzg`;PQb#MMDnSqzd8kZWWjP_` z{5K3iwb-|=<3RmNE~)d3fmfr;Ul zc+~zbM)XjZ_Wd1_RCy%s-M>WJa60U=H(wXo9PiJ)#Q!rsTzgWI-}FwX)^fe|)n12e z$=Ybs=^lT!*v49a-ycq7)Kfnc}NL_(a|XU`WsPBwpFS;8;(CuOM8*>RiHOn@0)}buIQ`?Nm_P& z;Hwiksaci^Pr1k+_X(zjR0wgA#fQ>XLu+cT)e7WdIjPN(hQq`{`>a~&$?xY<%l>4} zW+97CZ|fhAWE9nbZ4fe7yy{^L)n+%yWCezeAzQ3PN+#n5J7p+XK7P_Bg+~cKFAu$I zyEt@a#FWK-6qg&6iB<~>KU#XJHA(;0a~L4-4csgMA6wV53*V) zQlun)8xsrForh5PV^z^97zz^4sr&XhZ{>iecI6V|p{c^Z-z6QLa;X7!s3Pez;;*%o zI2-v~G*o2Nm3=BR_g@3j08&J)rGzF$3(ShmXW8^90?NK?I%Z&KOtsVLZNKJ<21`=b zicAox;(YMp-rdgI{HaT0ymhjgk>JX6oY;vnn31tddVP&BI5OK(CNd_17z;#ijoG(^ z!60>B-C)qrJz1N@{L$M)bjR!XAelQ_W7sDPyGoERnw^|jn;zv9MP_Y;qm7|tDy~+t zd>pMZD$!#f7A~hY1eP6G1Y32^zaOu8dyOz+%}pMimN8NC`YwG6QuCI=$K(2L75wp& zW99++S9y)Z#pLdcnyZ46fx3%JGtdB7aO&sE`~PKD{nah$84{Nx+J+5%NX+niFv@xWW=a08X%cN&5XA02sIYUdYmq^3V+X5ihmF~Y`7G(6*2$cb@4g~GxTw;S4{Z$U+H^CF zG+I>NkuyvyW&Vd9SWf-fN%SL1fwtsKa9%a{g#{INORWbJ$-^2?GzSb0E#`o{YmOi) zhZoofHV@4Qw(NzOnbee>Y;0DE4>&C9C0fi_-1q15k^&{uI0nTfXB9RqD-52@@-6e+ z8cS5J4Ju~aI=Sa5xj3Pc*{FMYtdUYLl&{P$F7z77Xx>D_iHShufj7bi>je3n;?Z*# zdI%S-allJ)+=NN>*dm>p)(Jn74Pl*{i@2hiTuy{ZY$)C`GV}rp7gK8}4i9b`<_U2& z0Zb`4A#%8V(&30X{M1}Yky%-NN+}Mfk43TOy}6lO5gAt6-5g*54`3n%odLrlUvXj+ zL5e3UwU|LgQlFf-LO}xk$twi0YKa%ZTG~e%8@8f23>Syui#@W=+0NHcM(6ZH8YLvi zM)wVQQ$@9jt^DtDEvW8FRZ*v50^fk?k^glrTcRN0IZZx_6=(pBTywL9*$_mT#j>S? zDa8W=;t0`&-0-D}IAm#Kofc!Llw`R(xr&-$PUbR`Ic&*XY#=sxd`X6x*|xI!sL?Js zfy)^rUjw{&(~YIH^;i&$tbX2b1i#s?qmb`3GZd5$T(Q=4fWnU1hfvZWIVbpwm+3+R zcQK~JCZBSiwLnfYNypf+)!UOdaw`kp5d?xopDPhZB?*J0tE9tsJD)R>u|i|QI{k<3 zH$piIGnIqlsCSpih{dzj*AuCH*OvpzdS|ynE7n#(^yrjmvS`|Z$!{gYi`4HVC9M{I zg-R1|JS~gp$8za#c3$wHvxSMEA8bJoM-V=<`SeFnTPmoOk<>E^P=|2#^1f7YLblz{ z`5@+(!>Nj~2%HK=0lW-@B2X9sNeT`R0&FiaYvlOLm?`{E?y~}H+ukYPX{9;@aCSyP z!WyCZOHet8f4jgCqsHXRai47G;^v>_vfMZNjG?-tPMZWQP#6gy^pC1U@-G?8$`i*P zS?3Y1vr}^~Wb$Mcvs^FxV9Rd^^1M*t9-V04WZJ5}QR()loI|W-+lsFJPEMToI&~?| zjHH^ZeGP!WmB+|5QX;o7F=!Z#oCE^*-4%Xa4V>}Q8m*!DicG!Y4&@W$x5Li06IaT>O2 zvO+&&jiQ0Vtq4ta&TE$4qp?x8>3G^skymbki|C%em0#iUyab++fB#6iGfmpw@i86~ zZN&}Nfw?3=ac{RL1-ziJ3hsA;%)I!&dkTFBQD;Ifza}PhFjkuxfe8mC^I4QwLt*^O zFPP{ixKX-mB55CL!&-@{uwO;8=&4x2Gmf+=zausEN3k(8S=Ny#3Pl;!cOwl~vf`SM zCPuKcM=)ll5?CRbV|Q7}KB98fx^+a`ueQif8tm5B+k8Y#eYbplK2&B%jZ#4do139< z{`NM8u~5EvfAeMgV@c!|`h6(fZKu$^*azMr;GlED>KLCXF`y$D{sf3wC_Pz(sAzYtbzNLNtiUIaU3NMW54&_cNa{vo#Dnps6UOt$z7&|0~zl zx5(=$s}0YpgwAdGusl zC za=?8KX95S3p0Okd^E~OTUlLA}IKPmH*|E5bwRMT7$C?v<2Nwkq0P3s&lOV&?u{g3^ za@ed4q8tyl&<1qaWOZ;bqUNsAUuoHs3H++oZ7R^`G&LPVD9JbeU_${M6X348&rxbkyeMSv{&(`f)@x%)2W^6?;41}BnPryVGBDA zjl;eTRR`&dgE6cmxNL?{9Qm+BaH-crJ}hi?VE$o-R*LO| zEUu=|eE*HZ{l{!dAFAXo}u=|9gkSlUYsDizY}e&ptv>}^{076^>73=4w7Hx+GIHWtFvn!Z1N)G`t5>Ru?+BM93RN&HmE7h5% zgxS>Fk6&E)u>_*8iVKn1a_gGso1bhXr2Qi-OtPJWfmOU-ATK)iSJfzI&1apj(z)v- z5s&vP&BgmE!e2=h{KkDhC#-R13v$&s80TK<+pKfHk6rhoeUWZG(;!$ST$#}#lcAxu zm?RDL^tx}tL^+3^STmg6emM$r$5S{N2EIHb&+eHNCA!WDcj}Q2+zroUpBiz`rP2Jz zwZTb3`G6VjRWM<5yh;`MGsh$C#=7->PV4x1NY@zX|(C*2i56rubDy7aYtwY@xr5eN<*d7 zVEYY6AbshZL#O@Pw0!U2%A|z}5j_hdKAwlIvOfj9o8NG&{{$%rmIXF zSW>lDD_bvCwbYa>z#V&s`M%6~f7iFG+&9pb7BerD9r0nwjY8$J2;iIe^-lmZ8p1{x zmrh<`Hljb`p@9t@7M(xev93Q|7-zYAU>w(^kmMz z6G{PCf~qc^P&V|Wfx>>9QV(aIFs(&&YtZ4v$b@l6sKABgY zDr~Jwrmf-{aj3k=;8DBB9OKh{KI5JK6^7&gRuOCTzE>sxX)wFs7ibZ7Rr^)mq#3MV zFUEV(tLWG)Rb0eVZqLG;vcTJiascZ~hL)XG?LvAY|+y)l?^jNW{78Hro{=wr$n&Dn2Q zCQ?f6*kID7HTIG8P(&eNdi>pT3xXy{CeNfn=uk+`=d-Z4*xSqT0No$enGM=g`Ac^V zJ6MI|gEzXi+zewhPguoatFWJarlpttB9BzeU>;|(hTL63qPv& z&`z47^R^48Et6;3PL7=Um)lpqQi*x^)iD8MY)<9>0u>^P~6*99T(QLS(%BD(Cw1toCm16-!?E! zBPPJ141_qO15Kz=y@zRvQWycDzRDu!xP=RK)Pq6N$b>;K790w-UZW7Us8 z?X34&DF>18`&d31p#B7KgJ3a7a4>$rfsp2{UdJxg4^$kUdM@6*_&W0R_BAA6LPABT zQWN76d}WdlyY^MY#R-99CTLv)J9)^iJGOO;FI`@_SBkDMNUGkQa2zoZri7v_f#44a=H0Q1_#4^Y7)xL~woc0|AX_&bEI~*}cjT~x zx?U(#5-33dd|)yoC^9MoPy`Gv(_R;`X;jF`bIyK~JExWiI8uZ9*3B=g)<;7~vX#R? znJ9!FL~-}!8!>2(6`vf$R7D`t;i@*|i$Fg1y<-_8D6Q+_*ONh7t|=8H93aZ!WJDPn zjd75dHk`{yz|?`+);z>(BPQApP=mpyHbw!ABO6VH!8={786(P}%FSj4Yr8b|@$Ygm zuIx6#9+IfHO9+8}jR92L!Pz4wBPKzm8hO$t%Cs$=fx{x3 zj-yyMV4y}6V|G_-Y1_{3mXS3rY>o24x^WAETa{KW3DnkU@S4;H5N8mUHbKh+qh%n* zV;Ch?(y7e_wr2vshihaGp*4SGz_l=~(o+tgSfVJVrx8`C$r z8pbj4<>O%TDdD#fztOeN%^+`UPlXlWxRiA-2E z=csXe)JwD*#J1}P(au9UjJ>ZHwQGE8j5w<=k8A=<_4oa08PTYqBPc5dP|)aEMfZlC zJ%7+}C`Dp~Ql$r=KJ_Fboyi#$@yt(tslu&w7}~cAM64 z6->nvqD;%td!LD{q`X2AD8UYr2ZSGChB~DtQ5U&6{Wx)3Y7m4fI@P3Y{i%BX|!0$G9Ph=_~*bv%x^Fd4(pdeuZ zDhRPiQku3C#>dZ1Z{_O|6of@3Z9x#sF^1Ap zBUVbJnXQ!DRHT(jresYbYDS|pQ%sc^D=5lLn#`(7WTu$X)S8-V#?vtjvo<0~5D`w& z{!+j%tk^uXOQ3GGd$&$(+o<|Z(KR+Q16rx}JuX@79;8Q7;eZ2pZH+ zpkP~nKvXHF%kk!M^Mp-W^V0XzJhRX(>Z14#HsR92Rftc4sOIw{CddO|H3q_nLdmek z*7WV_#RWN8TKI+-IV70B+cpUP`PpH5UDG-|Q3H3+0!MaatN;`!d{G(~KUv5keH8aZf1Xi760 zNi^_qZJ|~HOSFQwU{7qR>u4F8DT9@(x*|5LG!U>v1sEA>G9p7b_T1oxSnHCm=}MuJ zjfZ;LBPh}%D8&p15>1dAPPik??Qp&4)#PhWy}*#&pOqmLNJAf@i#E$_Zk_2 zXrVAFGt__}%45LPGGZ78Ns`G2aL}3=40}i-BPgoP0!UAm{zo);0tQ(;nMzdyA_>6t z8HJnqQobZH9+9%o5OCK3Iy{6YoZ>lm=bf#9kkKv4k5%-R=mo|xyC~H3ADxoyWPjH?^W@x zQtIwXwkoB=?c92e@WAf(^@$=9w_szJR_I6(WM0EjLG^gaS?pIxeDd&17&37w z6^JN!8SOibE_UMeiaxvJefyQRKx09ZJy7H*b11~dE@V%;KrkfT8Y3wCzNZ1Z_BtjH zyO-T8J;*{CL&WSll==MuJAx?4q!d`7%xUnE@1A@YIXeU&0r%0f^Jl(EQgJ5 z&!MLO743LEdfo^)5w8eT`>xIYmT2J95gH*KF_mL@KMCA=p{h0K!xj!DWv96I8`HLm z@$4q zFkz`jGvI!0bjTqx5u{@@sK%1(A+2 zOk1j!v&)&$@6sJ~<_sg_WXlY7n6gO7IU^rQ*vPx+tg!7HEs8OZA$~(R>4axYPrqwW2CZtn;CQO-8<(k;g0g*}MG#n|$^oCBPO;sFq4KVnmA>M+IOY6#~f*()-X!Y$Z#Z(xvhhf z>-Ou_kq<3vW*YTs8%(+*D6->$WMo)@DsC)Yv#`37+C7&{p>r$_S7(;HNve*&Ef}W;rj8>raOwwH1H&zcVkostRP6XMN zh?%tGBPOS<8Z3WBj3Xv8G$xu+KqkpYB6SuuSw>B7%r~}O-QyIz`mSPY#hN&8O3W*a zz9fYn@zlwSYbG2J!Wsk&;=~X|8cH!XmqEa5hqGa`>CL_KwO0n9*BUR=FdY_H-vJ!q zqL-yT0|>F_s}u%$4%%d~WCe+Z);O6h6kD@LSEP`}_-hQzg=c0&76#?2!?m65qv9^3 zY<)4;9=R(rB%ii#hl1^c6EN2yFQW`JC1PCsKz=88li@e#D)X7VsxgM#t`5dA{c351wlqO1VW-vjgbsF>+=+< zoluu-8AcogB(esEZJI*qiK`ISk<5le9A0IVu~#!PfHDYe1m)gRQ%xw9RWyYW$eIqR zgF+aWU>azrJevc$w33BjM4DlKAuVZkg*# zZJfO6ma9$Uj3E*o$Ecp|IT%`$*Ka=QJ)?kf*!8@T0uhoZa|K6?K>BO{lhaFJ2prF@ zTepo==RGcWnBT%$!^!Ni%jOK3a#Iui<4c2=hPZcGeabIYgGu*oG4NZ50tXE9aARhC zY_fK?>i^8^22f6eZ=aWOAqQSF55#O)`bHfSU2+5tk6kp#ywAwe%pk^?#M5jRcOkZS zH-aiG{W0+N6o_|0w959bn`D5DyCB(|m}hNosbHZ^41UQLwPeIhDRimC$DoFi6hKY7RKC+A{(ken6iIA9Q!WsRWvV`SR3-Z8>BW#0XBPOY$ zt#DyQ%(1OXJ0ZM2xlfE*gWmunCs0%DiuAZ*F4i1p%)RYqj#Yt*a+=Kul z7Ee6Vopf01ZoE>p&DWc1Tg0gZnq?_!2AGpz2ws4DJ8c@%z>qbS3xR+uwnfaLbh&|M zDV0?FQ>Tl+dkMdfc{VWMP3L92vD$&s@F(1y!p zk{7scp%!gtu~BCD14yuDP?A=aBPd8z7~U{MVA+@)^wjagq%^vS<3BS~h?0QNF9wPr zWI~Dv>-T7@=1GqW83$#Cp@azSBfMXp`V%ajVe+9W85*BWS(P^hx*nGx&r23|5K7y3 zjI*?CG3!3rkl2%f(l(Nk6#FMC{#jA+%;kpWI5T#thLHS}=EUxXaq>?%AerS9kx})M z)Ft4wkxMm1TB@h#vm#9P681dFa{EgY>dWgqUZwWzVnBS5K<%KzOEqbvWo96$8CKNM zET)BuZIo}%v}Yd8FX|YhMR&81G}8L(O3(%2_S)!KB6`ZdLZ_A^XnrfPfWh1K@%b#ii+~^EQFxhxCVCUO>cZgx;Mbt^lleMvL%U> zV8R(eKw*cKRiV2zLqSJDCTgLvF(W7lQ@bN3X0Uo4w!>*NZkqyTG94YXMbSJth=rL4 zBPi4F33xbm2Qx}Y39v|PZ4XWfc!%rG(LKE2d56&Zk_aRp84L(|glN)RCn*wp`OVOp zi<(#@wzhSIVM{uHl3~!`T9Dz-f;6_0H6b(#j+p=_J9OrgdKZmDLLuK zm$q=foI5%W*sO%f*5xtaL?LE!rPPOpowm0s`h-?%sN_O;%+x;5*xDoIHYkzHUPwrqiZ+lWf^P0noy`+s z>cTZ|*jymUV-!GR5sE09ZKs=ZD+m;7N>-CvxFHAeBPd!ZkUt_ONACp*tRgG?S!~DO zui4qx7|1~LI}cEG5@N16P;nQ3AmW@rkO>8XLI6TRf-xJ5bEQ<^kGW9+Sv92C*)29n zYWhCbi{tp0yhgSq7M8`cG>alcfg&thuf7NeI3bY)-`=>F1jmS$1UPX8QDpxMD?uYD zq@YNNv6iOMt(!77fsuYUbc+Cq2#cA@SQiEW#M%ctDQ*aX{#|BgERQ0*%J+V}I|S_r zj+#6pCePe<2hT(5%-CD%1MyWHKKsa60p_6?_(Jd;;WvB$Omf2!nRu&;dhcJZ)kIdJ zjD&)0l|67jHOlj>8NqS3BPInbV*#Mg;Lve~=U1hY(Ig!{SE+n!9B(%wY6O8oF!PFR z05}JlQ4mrP4`QiG3r0g`YNxhp$+t7QZCP3@rlqpcAdrCqK^D)jwyr-zb)B=i+5!R} z(WtHSS*=~Qmb|Z;7v4tHl5D~5=Y6L=kCql0x-xIEh0JT$zbsV!Naq~0F@ZK=l3f7r ztk@X?O$_X26CNGmUTX9Eij;aFr>yP$fdAeEBPb5gI<#mcVHp&LDT_v^wHCh>Z>+Bx zsM0ymrB^{kRffcSMX~K8Cf3pb#!(tkVB*RNVfCg<7PVa`$8IPlE_r z0({~8746LQgdi8ea)5zT7;w^qY+PZ(<3>_{8oWpuZHhD zuPfHCO7X61)akb^#3HFitj)5`Gigm-@O8Yd>}}9ujE550P=$z2VfE`*bfMkMFhK|r z>s8bKV`iVL06#V@$eWJs8aiPmNf6(K%P=bv>Ci(Us^yu%D%&q&!~wd zt5DJqB0^u6(kXu3<)(y){X0zIB+ern5}9wh%JrsIM=leU9)w1U#Z^^TG0$HU36W31 zuz}B1jH9XoU|H$Nr)eHx_2y7kl1uvt=S~jZKYU5#bUJ*pQe9tns6BVKZ_!h38*Z3O zWFd8t?Mm$~H4?+q9D8nq>WJMZJP9f2?lg0a5OoIGz@n2aTuvCN79%EeGZw;VFzR94 zAUfvkXJu-5T7APf{Of@4=QManXhK%pi$`ImSC_|QXQR+2wG_mU=giYXVUMR8)!*@J zVIj)NU?M{FCI@8}V&Vh?0x%(o8o06Gf18Z%;({*ys3B>_6H=-Shq3I$zFCH=JwDz> zaEKCyy;NgjOU9ihSa2~YiQ0Ad(qrwRDo7W}=7*>6JituoCk5N7u0rPpkRHG;raM`{dRHa%rb=|CdC$hy&zcxKKyx}%##H~ z&brAgf+Hpvp|k^bDRuq91UED2B@Z#?FTF?K_E)}h^qhQ6R`;UV2FwtF%iYH(7VUF} zNOMUeCRqjlNBrOTfBgUN{vYps-Cy(n-#RN*^u&yx`aL$kX@V(tyVoxy!bpO9! zQ(D_D@S{z!n9h#VMM~tvx)`E|c4iTo%??ss(>LQK@?`cGCP zCY<3is?u4CBPK|ea;B!;BjYA*wn1&#BZFgF%h;^9E@n_JXdh~8{(X+eV`;F;)yJJ+ zQMA;i>V`D7&RH6)^JgAj(&?!BctOh?=E;~E72In3?Jam5b3}F#F@$?V(L1+J2Q(Px zr*UhTx|Y>|x6)kRbff;IdZ>nR4)}1}K;>onBPbbE8&KS#CP$VSRtG}_vSP%|4bt!@R@TXD2rdK1i1%Dm@!U>1>}NAn>uk_O9YS(mtKXyxGs3I z6HRXUXB2p(T;eE)Sh6fu$s;D5XiLNpkVKK`c5XK1f`OXc^z>vP`@Zga%{5h4fBt>4 zE;2@q%rMMJwL^w<0_?{lUP;0vfglJ(VnR^{p+bVSVya9?2??P{6oLl$g7#zL9y{o$ zhNy@7;vexULk@0$yRJ-F7KA-am~2`qn1n!xq3Oeyzz{vl|9%mSk|%vqd!9-A8|PGi z-gdISw>RjRF9jxA`g2>wN7q|&u5E5?Wh`NJ#abfBGAnpg5RpKr$b+jYQEA4r z!cIHj@%nJh`f4mlMsOV}UTKK`A+fPwO=NLtrBC_bEg@oux0fd7hy#)^p3|^ zc98P_k4=-Z24mNyq>Ld66KHoPWETJ6^&R+{z`^^yZs9w~U;#D`(|5$^75}CHkRXAv z*pAahSVB&K-7dAPn#q;I*Bf-&`2BwVvr%A3n73392#}17h>`$3e*?1vKYRIrfQL#E z=gvN<+373UEV00e~)E(3^Ehz18V=&C@3B(M6s$m z9+EX0%NAkF-{HT@*v!AJ{?XwD5O=w)_xSvioGJ2V>cV{+6EEBoFP4q{{j9(!F<_sT zr0Y+@=q7!1ZG-Zh(LsOtKlJ{O`FL(TD6E}Itf6R|o89hDkN=PLC}I!%z_>D!pXmfe zzPK?T>Uf6N!LybKKlt|5Ez?=MMohjnlvzRbL9E;#+so9Bod3dbZ*`DZ<=p1xu(szU zHW7u~_WJbsbY>2a8)eZ19i9LE)3Q0YfhYL-{>AW`85ryzTDB)u96yBal)t8_f+GAm l?Y1`k-?DKt`ag&A{~$nz|Ha&qP81|7Iy0HT3L`u{JqqE~HN^k` diff --git a/wscript b/wscript deleted file mode 100644 index 06dbfcb6..00000000 --- a/wscript +++ /dev/null @@ -1,208 +0,0 @@ -############################################################################# -## Copyright (c) 2009-2011 Alan Wright. All rights reserved. -## Distributable under the terms of either the Apache License (Version 2.0) -## or the GNU Lesser General Public License. -############################################################################# - -import sys -import os -from copy import copy -import Options -from Configure import conf -from TaskGen import feature, after -import Task - -APPNAME='Lucene++' -VERSION='3.0.5.0' - -top = '.' -out = 'bin' - -source_patterns = [ - '**/*.c', - '**/*.cpp' -] - -lucene_source_dirs = [ - 'src/core/analysis', - 'src/core/document', - 'src/core/index', - 'src/core/queryparser', - 'src/core/search', - 'src/core/store', - 'src/core/util' -] - -lucene_contrib_source_dirs = [ - 'src/contrib/analyzers', - 'src/contrib/highlighter', - 'src/contrib/memory', - 'src/contrib/snowball' -] - -lucene_include_dirs = [ - 'include', - 'src/core/include', - 'src/contrib/include', - 'src/contrib/snowball/libstemmer_c/include', - 'src/core/util/md5', - 'src/core/util/nedmalloc', - 'src/core/util/unicode' -] - -tester_source_dirs = [ - 'src/test/analysis', - 'src/test/contrib', - 'src/test/document', - 'src/test/index', - 'src/test/queryparser', - 'src/test/search', - 'src/test/store', - 'src/test/util', - 'src/test/main' -] - -tester_include_dirs = [ - 'include', - 'src/core/include', - 'src/contrib/include', - 'src/test/include' -] - - -def options(opt): - opt.tool_options("boost") - opt.tool_options('compiler_cxx') - #opt.tool_options('clang', tooldir = 'build') - #opt.tool_options('gch', tooldir = 'build') - opt.add_option( - '--debug', - default = False, - action = "store_true", - help ='debug build no optimization, etc.', - dest = 'debug') - - opt.add_option( - '--static', - default = False, - action = "store_true", - help ='fully static build', - dest = 'static') - - -def configure(conf): - conf.check_tool('g++') - conf.check_tool('gcc') - conf.check_cc(lib = 'z', mandatory = True) - conf.check_cc(lib = 'pthread', mandatory = True) - conf.check_tool('boost') - #conf.check_tool('clang', 'build') - #conf.check_tool('gch', 'build') - conf.check_boost( - static = 'onlystatic', - lib = ['filesystem', 'thread', 'regex', 'system', 'date_time', 'iostreams', 'unit_test_framework'] - ) - - -def build(bld): - target_type = 'cstlib' if Options.options.static else 'cshlib' - debug_define = '_DEBUG' if Options.options.debug else 'NDEBUG' - if Options.options.debug: - compile_flags = ['-O0', '-g'] - else: - compile_flags = ['-O2'] - lucene_sources = [] - for source_dir in lucene_source_dirs: - source_dir = bld.path.find_dir(source_dir) - lucene_sources.extend(source_dir.ant_glob(source_patterns)) - - bld( - name = 'lucene++', - features = ['cxx', 'c'] + [target_type], - source = [source.relpath_gen(bld.path) for source in lucene_sources], - target = 'lucene++', - pch = 'src/core/include/LuceneInc.h', - includes = lucene_include_dirs + bld.env["CPPPATH_BOOST"], - cflags = compile_flags, - cxxflags = compile_flags, - defines = ['LPP_BUILDING_LIB', 'LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD Z' - ) - - lucene_contrib_sources = [] - for source_dir in lucene_contrib_source_dirs: - source_dir = bld.path.find_dir(source_dir) - lucene_contrib_sources.extend(source_dir.ant_glob(source_patterns)) - - bld( - name = 'lucene_contrib', - features = ['cxx', 'c'] + [target_type], - source = [source.relpath_gen(bld.path) for source in lucene_contrib_sources], - target = 'lucene_contrib', - pch = 'src/contrib/include/ContribInc.h', - includes = lucene_include_dirs + bld.env["CPPPATH_BOOST"], - cflags = compile_flags, - cxxflags = compile_flags, - defines = ['LPP_BUILDING_LIB', 'LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD Z', - use = 'lucene++' - ) - - tester_sources = [] - for source_dir in tester_source_dirs: - source_dir = bld.path.find_dir(source_dir) - tester_sources.extend(source_dir.ant_glob(source_patterns)) - - bld( - name = 'lucene_tester', - features = ['cxx', 'c', 'cprogram'], - source = [source.relpath_gen(bld.path) for source in tester_sources], - target = 'lucene_tester', - pch = 'src/test/include/TestInc.h', - includes = tester_include_dirs + bld.env["CPPPATH_BOOST"], - cflags = compile_flags, - cxxflags = compile_flags, - defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + ['LPP_EXPOSE_INTERNAL'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS BOOST_UNIT_TEST_FRAMEWORK PTHREAD Z', - use = 'lucene++ lucene_contrib' - ) - - bld( - name = 'deletefiles', - features = ['cxx', 'c', 'cprogram'], - source = bld.path.find_resource('src/demo/deletefiles/main.cpp').relpath_gen(bld.path), - target = 'deletefiles', - includes = ['include'] + bld.env["CPPPATH_BOOST"], - cflags = compile_flags, - cxxflags = compile_flags, - defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD Z', - use = 'lucene++' - ) - - bld( - name = 'indexfiles', - features = ['cxx', 'c', 'cprogram'], - source = bld.path.find_resource('src/demo/indexfiles/main.cpp').relpath_gen(bld.path), - target = 'indexfiles', - includes = ['include'] + bld.env["CPPPATH_BOOST"], - cflags = compile_flags, - cxxflags = compile_flags, - defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD Z', - use = 'lucene++' - ) - - bld( - name = 'searchfiles', - features = ['cxx', 'c', 'cprogram'], - source = bld.path.find_resource('src/demo/searchfiles/main.cpp').relpath_gen(bld.path), - target = 'searchfiles', - includes = ['include'] + bld.env["CPPPATH_BOOST"], - cflags = compile_flags, - cxxflags = compile_flags, - defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define], - uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD Z', - use = 'lucene++' - ) - From c914c76f2f56dc1b8a2850fb7bce6d0896543d17 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sun, 9 Feb 2014 16:40:42 +0000 Subject: [PATCH 046/157] Ignore /build directory. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 59e8e10f..a9865f41 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ src/demo/searchfiles/msvc/Debug DLL src/demo/searchfiles/msvc/Debug Static CMakeCache.txt CMakeFiles/ +build/ CTestTestfile.cmake Makefile cmake_install.cmake From 61f32934b091be7b3dc2757e27a8368b9a0370f5 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sun, 9 Feb 2014 17:31:52 +0000 Subject: [PATCH 047/157] Remove test from CMakeLists.txt. --- src/test/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index f2b8445c..f7c65721 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -38,7 +38,3 @@ target_link_libraries(lucene++-tester lucene++-contrib ${lucene_boost_libs} ) - -add_test(lucene++-tester - ${EXECUTABLE_OUTPUT_PATH}/lucene++-tester -p --test_dir=${lucene++-tester_SOURCE_DIR}/testfiles -) From dcf5b9d51bc740aef6855046506593b05e1b940b Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Wed, 12 Feb 2014 00:14:22 +0000 Subject: [PATCH 048/157] Switched to using google gtest unit testing framework. --- CMakeExternal.txt | 28 + CMakeLists.txt | 7 +- README.rst | 8 +- src/core/util/CycleCheck.cpp | 13 +- src/core/util/OpenBitSet.cpp | 122 +- src/test/CMakeLists.txt | 26 +- src/test/analysis/AnalyzersTest.cpp | 18 +- src/test/analysis/BaseTokenStreamFixture.cpp | 106 +- src/test/analysis/CachingTokenFilterTest.cpp | 44 +- src/test/analysis/CharFilterTest.cpp | 24 +- src/test/analysis/KeywordAnalyzerTest.cpp | 32 +- src/test/analysis/LengthFilterTest.cpp | 20 +- src/test/analysis/MappingCharFilterTest.cpp | 50 +- src/test/analysis/NumericTokenStreamTest.cpp | 44 +- .../analysis/PerFieldAnalzyerWrapperTest.cpp | 14 +- src/test/analysis/StopAnalyzerTest.cpp | 36 +- src/test/analysis/StopFilterTest.cpp | 34 +- src/test/analysis/TeeSinkTokenFilterTest.cpp | 60 +- src/test/analysis/TokenTest.cpp | 128 +- .../standard/StandardAnalyzerTest.cpp | 74 +- .../tokenattributes/SimpleAttributeTest.cpp | 88 +- .../tokenattributes/TermAttributeTest.cpp | 88 +- .../common/analysis/ar/ArabicAnalyzerTest.cpp | 32 +- .../ar/ArabicNormalizationFilterTest.cpp | 36 +- .../analysis/ar/ArabicStemFilterTest.cpp | 50 +- .../analysis/br/BrazilianStemmerTest.cpp | 20 +- .../common/analysis/cjk/CJKTokenizerTest.cpp | 148 +- .../analysis/cn/ChineseTokenizerTest.cpp | 32 +- .../common/analysis/cz/CzechAnalyzerTest.cpp | 10 +- .../analysis/de/GermanStemFilterTest.cpp | 48 +- .../common/analysis/el/GreekAnalyzerTest.cpp | 204 +-- .../analysis/fa/PersianAnalyzerTest.cpp | 266 ++- .../fa/PersianNormalizationFilterTest.cpp | 20 +- .../common/analysis/fr/ElisionTest.cpp | 16 +- .../common/analysis/fr/FrenchAnalyzerTest.cpp | 16 +- .../common/analysis/nl/DutchStemmerTest.cpp | 18 +- .../reverse/ReverseStringFilterTest.cpp | 52 +- .../analysis/ru/RussianAnalyzerTest.cpp | 54 +- .../common/analysis/ru/RussianStemTest.cpp | 24 +- .../contrib/highlighter/HighlighterTest.cpp | 1262 +++++++------ src/test/contrib/memory/MemoryIndexTest.cpp | 52 +- src/test/contrib/snowball/SnowballTest.cpp | 12 +- src/test/document/BinaryDocumentTest.cpp | 43 +- src/test/document/DateFieldTest.cpp | 24 +- src/test/document/DateToolsTest.cpp | 178 +- src/test/document/DocumentTest.cpp | 151 +- src/test/document/NumberToolsTest.cpp | 72 +- src/test/include/LuceneGlobalFixture.h | 2 +- src/test/include/LuceneTestFixture.h | 2 +- src/test/include/test_lucene.h | 8 +- src/test/index/AddIndexesNoOptimizeTest.cpp | 167 +- src/test/index/AtomicUpdateTest.cpp | 106 +- src/test/index/BackwardsCompatibilityTest.cpp | 180 +- src/test/index/ByteSlicesTest.cpp | 38 +- src/test/index/CheckIndexTest.cpp | 64 +- src/test/index/CompoundFileTest.cpp | 244 +-- .../index/ConcurrentMergeSchedulerTest.cpp | 94 +- src/test/index/CrashTest.cpp | 56 +- src/test/index/DeletionPolicyTest.cpp | 228 ++- src/test/index/DirectoryReaderTest.cpp | 101 +- src/test/index/DocTest.cpp | 28 +- src/test/index/DocumentWriterTest.cpp | 166 +- src/test/index/FieldInfosTest.cpp | 46 +- src/test/index/FieldsReaderTest.cpp | 255 +-- src/test/index/FilterIndexReaderTest.cpp | 38 +- src/test/index/IndexCommitTest.cpp | 40 +- src/test/index/IndexFileDeleterTest.cpp | 34 +- src/test/index/IndexInputTest.cpp | 210 ++- src/test/index/IndexReaderCloneNorms.cpp | 0 src/test/index/IndexReaderCloneNormsTest.cpp | 90 +- src/test/index/IndexReaderCloneTest.cpp | 176 +- src/test/index/IndexReaderReopenTest.cpp | 421 +++-- src/test/index/IndexReaderTest.cpp | 750 ++++---- src/test/index/IndexWriterDeleteTest.cpp | 233 +-- src/test/index/IndexWriterExceptionsTest.cpp | 96 +- src/test/index/IndexWriterLockReleaseTest.cpp | 34 +- src/test/index/IndexWriterMergePolicyTest.cpp | 60 +- src/test/index/IndexWriterMergingTest.cpp | 16 +- src/test/index/IndexWriterReaderTest.cpp | 303 +-- src/test/index/IndexWriterTest.cpp | 1631 +++++++++-------- src/test/index/LazyBugTest.cpp | 61 +- src/test/index/LazyProxSkippingTest.cpp | 63 +- src/test/index/MultiLevelSkipListTest.cpp | 68 +- src/test/index/MultiReaderTest.cpp | 105 +- src/test/index/NRTReaderWithThreadsTest.cpp | 22 +- src/test/index/NormsTest.cpp | 44 +- src/test/index/OmitTfTest.cpp | 130 +- .../index/ParallelReaderEmptyIndexTest.cpp | 16 +- src/test/index/ParallelReaderTest.cpp | 101 +- src/test/index/ParallelTermEnumTest.cpp | 208 ++- src/test/index/PayloadsTest.cpp | 205 ++- .../PositionBasedTermVectorMapperTest.cpp | 38 +- src/test/index/SegmentMergerTest.cpp | 82 +- src/test/index/SegmentReaderTest.cpp | 130 +- src/test/index/SegmentTermDocsTest.cpp | 194 +- src/test/index/SegmentTermEnumTest.cpp | 40 +- src/test/index/SnapshotDeletionPolicyTest.cpp | 75 +- src/test/index/StressIndexingTest.cpp | 256 ++- src/test/index/TermDocsPerfTest.cpp | 42 +- src/test/index/TermTest.cpp | 14 +- src/test/index/TermVectorsReaderTest.cpp | 242 +-- src/test/index/ThreadedOptimizeTest.cpp | 50 +- src/test/index/TransactionRollbackTest.cpp | 64 +- src/test/index/TransactionsTest.cpp | 98 +- src/test/index/WordlistLoaderTest.cpp | 24 +- src/test/main/main.cpp | 27 +- src/test/queryparser/MultiAnalyzerTest.cpp | 104 +- .../queryparser/MultiFieldQueryParserTest.cpp | 198 +- src/test/queryparser/QueryParserTest.cpp | 354 ++-- src/test/search/BaseTestRangeFilterTest.cpp | 10 +- src/test/search/Boolean2Test.cpp | 58 +- src/test/search/BooleanMinShouldMatchTest.cpp | 100 +- src/test/search/BooleanOrTest.cpp | 46 +- src/test/search/BooleanPrefixQueryTest.cpp | 14 +- src/test/search/BooleanQueryTest.cpp | 39 +- src/test/search/BooleanScorerTest.cpp | 38 +- src/test/search/CachingSpanFilterTest.cpp | 32 +- src/test/search/CachingWrapperFilterTest.cpp | 88 +- src/test/search/CheckHits.cpp | 106 +- .../ComplexExplanationsOfNonMatchesTest.cpp | 62 +- src/test/search/ComplexExplanationsTest.cpp | 60 +- src/test/search/CustomSearcherSortTest.cpp | 46 +- src/test/search/DateFilterTest.cpp | 40 +- src/test/search/DateSortTest.cpp | 28 +- src/test/search/DisjunctionMaxQueryTest.cpp | 140 +- src/test/search/DocBoostTest.cpp | 22 +- src/test/search/DocIdSetTest.cpp | 42 +- src/test/search/ElevationComparatorTest.cpp | 48 +- src/test/search/FieldCacheRangeFilterTest.cpp | 264 ++- src/test/search/FieldCacheTermsFilterTest.cpp | 12 +- src/test/search/FieldCacheTest.cpp | 64 +- src/test/search/FilteredQueryTest.cpp | 60 +- src/test/search/FilteredSearchTest.cpp | 12 +- src/test/search/FuzzyQueryTest.cpp | 252 +-- src/test/search/MatchAllDocsQueryTest.cpp | 46 +- src/test/search/MultiPhraseQueryTest.cpp | 59 +- src/test/search/MultiSearcherRankingTest.cpp | 42 +- src/test/search/MultiSearcherTest.cpp | 86 +- .../search/MultiTermConstantScoreTest.cpp | 282 ++- .../search/MultiThreadTermVectorsTest.cpp | 34 +- .../MultiValuedNumericRangeQueryTest.cpp | 14 +- src/test/search/NotTest.cpp | 8 +- src/test/search/NumericRangeQuery32Test.cpp | 182 +- src/test/search/NumericRangeQuery64Test.cpp | 184 +- src/test/search/ParallelMultiSearcherTest.cpp | 86 +- src/test/search/PhrasePrefixQueryTest.cpp | 12 +- src/test/search/PhraseQueryTest.cpp | 160 +- src/test/search/PositionIncrementTest.cpp | 124 +- .../PositiveScoresOnlyCollectorTest.cpp | 30 +- src/test/search/PrefixFilterTest.cpp | 26 +- src/test/search/PrefixInBooleanQueryTest.cpp | 36 +- src/test/search/PrefixQueryTest.cpp | 14 +- src/test/search/QueryTermVectorTest.cpp | 26 +- src/test/search/QueryUtils.cpp | 132 +- src/test/search/QueryWrapperFilterTest.cpp | 22 +- .../search/ScoreCachingWrappingScorerTest.cpp | 48 +- src/test/search/ScorerPerfTest.cpp | 56 +- src/test/search/SearchForDuplicatesTest.cpp | 20 +- src/test/search/SearchTest.cpp | 20 +- src/test/search/SetNormTest.cpp | 24 +- src/test/search/SimilarityTest.cpp | 84 +- .../SimpleExplanationsOfNonMatchesTest.cpp | 140 +- src/test/search/SimpleExplanationsTest.cpp | 138 +- src/test/search/SloppyPhraseQueryTest.cpp | 42 +- src/test/search/SortTest.cpp | 224 ++- src/test/search/SpanQueryFilterTest.cpp | 22 +- src/test/search/TermRangeFilterTest.cpp | 174 +- src/test/search/TermRangeQueryTest.cpp | 110 +- src/test/search/TermScorerTest.cpp | 66 +- src/test/search/TermVectorsTest.cpp | 170 +- src/test/search/ThreadSafeTest.cpp | 30 +- src/test/search/TimeLimitingCollectorTest.cpp | 156 +- src/test/search/TopDocsCollectorTest.cpp | 92 +- src/test/search/TopScoreDocCollectorTest.cpp | 18 +- src/test/search/WildcardTest.cpp | 120 +- .../search/function/CustomScoreQueryTest.cpp | 82 +- src/test/search/function/DocValuesTest.cpp | 34 +- .../search/function/FieldScoreQueryTest.cpp | 76 +- src/test/search/function/OrdValuesTest.cpp | 70 +- .../search/payloads/PayloadNearQueryTest.cpp | 74 +- .../search/payloads/PayloadTermQueryTest.cpp | 108 +- src/test/search/spans/BasicSpansTest.cpp | 152 +- .../spans/FieldMaskingSpanQueryTest.cpp | 124 +- .../search/spans/NearSpansOrderedTest.cpp | 94 +- src/test/search/spans/PayloadSpansTest.cpp | 132 +- .../search/spans/SpanExplanationsTest.cpp | 64 +- src/test/search/spans/SpansAdvanced2Test.cpp | 42 +- src/test/search/spans/SpansAdvancedTest.cpp | 32 +- src/test/search/spans/SpansTest.cpp | 320 ++-- src/test/store/BufferedIndexInputTest.cpp | 303 +-- src/test/store/BufferedIndexOutputTest.cpp | 66 +- src/test/store/DirectoryTest.cpp | 124 +- src/test/store/FileSwitchDirectoryTest.cpp | 20 +- src/test/store/IndexOutputTest.cpp | 80 +- src/test/store/LockFactoryTest.cpp | 187 +- src/test/store/MMapDirectoryTest.cpp | 18 +- src/test/store/RAMDirectoryTest.cpp | 82 +- src/test/util/AttributeSourceTest.cpp | 77 +- src/test/util/Base64Test.cpp | 28 +- src/test/util/BitVectorTest.cpp | 80 +- src/test/util/BufferedReaderTest.cpp | 150 +- src/test/util/CloseableThreadLocalTest.cpp | 18 +- src/test/util/CompressionToolsTest.cpp | 12 +- src/test/util/FieldCacheSanityCheckerTest.cpp | 38 +- src/test/util/FileReaderTest.cpp | 48 +- src/test/util/FileUtilsTest.cpp | 216 ++- src/test/util/InputStreamReaderTest.cpp | 90 +- src/test/util/LuceneGlobalFixture.cpp | 4 +- src/test/util/LuceneTestFixture.cpp | 4 +- src/test/util/NumericUtilsTest.cpp | 238 +-- src/test/util/OpenBitSetTest.cpp | 116 +- src/test/util/PriorityQueueTest.cpp | 54 +- src/test/util/SimpleLRUCacheTest.cpp | 124 +- src/test/util/SortedVIntListTest.cpp | 63 +- src/test/util/StringReaderTest.cpp | 82 +- src/test/util/StringUtilsTest.cpp | 160 +- src/test/util/VersionTest.cpp | 14 +- 217 files changed, 10988 insertions(+), 10830 deletions(-) create mode 100644 CMakeExternal.txt delete mode 100644 src/test/index/IndexReaderCloneNorms.cpp diff --git a/CMakeExternal.txt b/CMakeExternal.txt new file mode 100644 index 00000000..6ad53dc3 --- /dev/null +++ b/CMakeExternal.txt @@ -0,0 +1,28 @@ +# Enable ExternalProject CMake module +include(ExternalProject) + +# main directory for external projects +set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ThirdParty) + +# GTest external project +ExternalProject_Add( + googletest + SVN_REPOSITORY http://googletest.googlecode.com/svn/tags/release-1.7.0/ + TIMEOUT 10 + CMAKE_ARGS -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} + -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} + -Dgtest_force_shared_crt=ON + # Disable update + UPDATE_COMMAND "" + # Disable install step + INSTALL_COMMAND "" + # Wrap download, configure and build steps in a script to log output + LOG_DOWNLOAD ON + LOG_CONFIGURE ON + LOG_BUILD ON) + +ExternalProject_Get_Property(googletest source_dir) +set(GTEST_DIR ${source_dir}) +set(GTEST_INCLUDE_DIR ${source_dir}/include) +ExternalProject_Get_Property(googletest binary_dir) +set(GTEST_LIB_DIR ${binary_dir}) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c84825d..4afe5d0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,9 +52,9 @@ find_package(Boost COMPONENTS regex system thread - unit_test_framework REQUIRED ) + set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_LIBS ${LUCENE_USE_STATIC_BOOST_LIBS}) @@ -118,6 +118,9 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/include ) +include(CMakeExternal.txt) +enable_testing() + add_subdirectory(src/core) add_subdirectory(src/contrib) add_subdirectory(src/demo) @@ -158,8 +161,6 @@ if(ENABLE_PACKAGING) include(CreateLucene++Packages) endif() -enable_testing() - message("** Build Summary **") message(" Version: ${lucene++_VERSION}") message(" Prefix: ${CMAKE_INSTALL_PREFIX}") diff --git a/README.rst b/README.rst index 984a3825..f0e18967 100644 --- a/README.rst +++ b/README.rst @@ -36,7 +36,6 @@ On Debian systems, the following packages are required: - libboost-regex-dev - libboost-thread-dev - libboost-iostreams-dev -- libboost-test-dev To build the library the following commands should be issued:: @@ -67,7 +66,6 @@ You'll need Boost installed. - boost::regex - boost::date_time - boost::iostreams -- boost::unit_test_framework Building Performance @@ -81,11 +79,11 @@ Use of ccache will speed up build times a lot. I found it easiest to add the ``/ To run unit test suite ---------------------- -lucene_tester is built using the `Boost Unit Test Framework `_ and is launched by the following command:: +lucene_tester is built using the `Google Testing Framework `_ and is launched by the following command:: - $ bin/lucene_tester --show_progress=yes + $ build/src/test/lucene++-tester -Other `command options `_ can be supplied. +Command options can be discovered by supplying `--help`. Acknowledgements diff --git a/src/core/util/CycleCheck.cpp b/src/core/util/CycleCheck.cpp index 2521f37b..12a9ac1d 100644 --- a/src/core/util/CycleCheck.cpp +++ b/src/core/util/CycleCheck.cpp @@ -12,11 +12,11 @@ namespace Lucene { MapStringInt CycleCheck::cycleMap; Set CycleCheck::staticRefs; - + CycleCheck::~CycleCheck() { } - + void CycleCheck::addRef(const String& className, int32_t ref) { if (!cycleMap) @@ -32,7 +32,7 @@ namespace Lucene boost::throw_exception(RuntimeException(L"invalid class reference")); } } - + void CycleCheck::addStatic(LuceneObjectPtr* staticRef) { #ifdef LPP_USE_CYCLIC_CHECK @@ -41,20 +41,19 @@ namespace Lucene staticRefs.add(staticRef); #endif } - + void CycleCheck::dumpRefs() { - SyncLock lockRef(&cycleMap); - // destroy all registered statics if (staticRefs) { for (Set::iterator staticRef = staticRefs.begin(); staticRef != staticRefs.end(); ++staticRef) (*staticRef)->reset(); } - + if (cycleMap) { + SyncLock lockRef(&cycleMap); bool reportCycles = true; for (MapStringInt::iterator classRef = cycleMap.begin(); classRef != cycleMap.end(); ++classRef) { diff --git a/src/core/util/OpenBitSet.cpp b/src/core/util/OpenBitSet.cpp index bce04a51..4646716e 100644 --- a/src/core/util/OpenBitSet.cpp +++ b/src/core/util/OpenBitSet.cpp @@ -18,66 +18,66 @@ namespace Lucene MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0LL); wlen = bits.size(); } - + OpenBitSet::OpenBitSet(LongArray bits, int32_t numWords) { this->bits = bits; this->wlen = numWords; } - + OpenBitSet::~OpenBitSet() { } - + DocIdSetIteratorPtr OpenBitSet::iterator() { return newLucene(bits, wlen); } - + bool OpenBitSet::isCacheable() { return true; } - + int64_t OpenBitSet::capacity() { return bits.size() << 6; } - + int64_t OpenBitSet::size() { return capacity(); } - + bool OpenBitSet::isEmpty() { return (cardinality() == 0); } - + LongArray OpenBitSet::getBits() { return bits; } - + void OpenBitSet::setBits(LongArray bits) { this->bits = bits; } - + int32_t OpenBitSet::getNumWords() { return wlen; } - + void OpenBitSet::setNumWords(int32_t numWords) { this->wlen = numWords; } - + bool OpenBitSet::get(int32_t index) { int32_t i = index >> 6; // div 64 - // signed shift will keep a negative index and force an array-index-out-of-bounds-exception, + // 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.size()) return false; @@ -85,17 +85,17 @@ namespace Lucene int64_t bitmask = 1LL << bit; return ((bits[i] & bitmask) != 0); } - + bool OpenBitSet::fastGet(int32_t index) { int32_t i = index >> 6; // div 64 - // signed shift will keep a negative index and force an array-index-out-of-bounds-exception, + // signed shift will keep a negative index and force an array-index-out-of-bounds-exception, // removing the need for an explicit check. int32_t bit = (index & 0x3f); // mod 64 int64_t bitmask = 1LL << bit; return ((bits[i] & bitmask) != 0); } - + bool OpenBitSet::get(int64_t index) { int32_t i = (int32_t)(index >> 6); // div 64 @@ -105,7 +105,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; return ((bits[i] & bitmask) != 0); } - + bool OpenBitSet::fastGet(int64_t index) { int32_t i = (int32_t)(index >> 6); // div 64 @@ -113,14 +113,14 @@ namespace Lucene int64_t bitmask = 1LL << bit; return ((bits[i] & bitmask) != 0); } - + int32_t OpenBitSet::getBit(int32_t index) { int32_t i = index >> 6; // div 64 int32_t bit = (index & 0x3f); // mod 64 return (int32_t)MiscUtils::unsignedShift(bits[i], (int64_t)bit) & 0x01; } - + void OpenBitSet::set(int64_t index) { int32_t wordNum = expandingWordNum(index); @@ -128,7 +128,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] |= bitmask; } - + void OpenBitSet::fastSet(int32_t index) { int32_t wordNum = index >> 6; // div 64 @@ -136,7 +136,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] |= bitmask; } - + void OpenBitSet::fastSet(int64_t index) { int32_t wordNum = (int32_t)(index >> 6); @@ -144,7 +144,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] |= bitmask; } - + void OpenBitSet::set(int64_t startIndex, int64_t endIndex) { if (endIndex <= startIndex) @@ -168,7 +168,7 @@ namespace Lucene MiscUtils::arrayFill(bits.get(), startWord + 1, endWord, -1LL); bits[endWord] |= endmask; } - + int32_t OpenBitSet::expandingWordNum(int64_t index) { int32_t wordNum = (int32_t)(index >> 6); @@ -179,7 +179,7 @@ namespace Lucene } return wordNum; } - + void OpenBitSet::fastClear(int32_t index) { int32_t wordNum = index >> 6; @@ -187,7 +187,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] &= ~bitmask; } - + void OpenBitSet::fastClear(int64_t index) { int32_t wordNum = (int32_t)(index >> 6); @@ -195,7 +195,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] &= ~bitmask; } - + void OpenBitSet::clear(int64_t index) { int32_t wordNum = (int32_t)(index >> 6); @@ -205,7 +205,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] &= ~bitmask; } - + void OpenBitSet::clear(int32_t startIndex, int32_t endIndex) { if (endIndex <= startIndex) @@ -238,7 +238,7 @@ namespace Lucene if (endWord < wlen) bits[endWord] &= endmask; } - + void OpenBitSet::clear(int64_t startIndex, int64_t endIndex) { if (endIndex <= startIndex) @@ -271,7 +271,7 @@ namespace Lucene if (endWord < wlen) bits[endWord] &= endmask; } - + bool OpenBitSet::getAndSet(int32_t index) { int32_t wordNum = index >> 6; // div 64 @@ -281,7 +281,7 @@ namespace Lucene bits[wordNum] |= bitmask; return val; } - + bool OpenBitSet::getAndSet(int64_t index) { int32_t wordNum = (int32_t)(index >> 6); // div 64 @@ -291,7 +291,7 @@ namespace Lucene bits[wordNum] |= bitmask; return val; } - + void OpenBitSet::fastFlip(int32_t index) { int32_t wordNum = index >> 6; // div 64 @@ -299,7 +299,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] ^= bitmask; } - + void OpenBitSet::fastFlip(int64_t index) { int32_t wordNum = (int32_t)(index >> 6); // div 64 @@ -307,7 +307,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] ^= bitmask; } - + void OpenBitSet::flip(int64_t index) { int32_t wordNum = expandingWordNum(index); @@ -315,7 +315,7 @@ namespace Lucene int64_t bitmask = 1LL << bit; bits[wordNum] ^= bitmask; } - + bool OpenBitSet::flipAndGet(int32_t index) { int32_t wordNum = index >> 6; // div 64 @@ -324,7 +324,7 @@ namespace Lucene bits[wordNum] ^= bitmask; return ((bits[wordNum] & bitmask) != 0); } - + bool OpenBitSet::flipAndGet(int64_t index) { int32_t wordNum = (int32_t)(index >> 6); // div 64 @@ -333,7 +333,7 @@ namespace Lucene bits[wordNum] ^= bitmask; return ((bits[wordNum] & bitmask) != 0); } - + void OpenBitSet::flip(int64_t startIndex, int64_t endIndex) { if (endIndex <= startIndex) @@ -358,17 +358,17 @@ namespace Lucene bits[i] = ~bits[i]; bits[endWord] ^= endmask; } - + int64_t OpenBitSet::cardinality() { return BitUtil::pop_array(bits.get(), 0, wlen); } - + int64_t OpenBitSet::intersectionCount(OpenBitSetPtr a, OpenBitSetPtr b) { return BitUtil::pop_intersect(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); } - + int64_t OpenBitSet::unionCount(OpenBitSetPtr a, OpenBitSetPtr b) { int64_t tot = BitUtil::pop_union(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); @@ -378,7 +378,7 @@ namespace Lucene tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); return tot; } - + int64_t OpenBitSet::andNotCount(OpenBitSetPtr a, OpenBitSetPtr b) { int64_t tot = BitUtil::pop_andnot(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); @@ -386,7 +386,7 @@ namespace Lucene tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); return tot; } - + int64_t OpenBitSet::xorCount(OpenBitSetPtr a, OpenBitSetPtr b) { int64_t tot = BitUtil::pop_xor(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); @@ -396,7 +396,7 @@ namespace Lucene tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); return tot; } - + int32_t OpenBitSet::nextSetBit(int32_t index) { int32_t i = MiscUtils::unsignedShift(index, 6); @@ -417,7 +417,7 @@ namespace Lucene return -1; } - + int64_t OpenBitSet::nextSetBit(int64_t index) { int32_t i = (int32_t)(index >> 6); @@ -438,7 +438,7 @@ namespace Lucene return -1; } - + LuceneObjectPtr OpenBitSet::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -448,7 +448,7 @@ namespace Lucene MiscUtils::arrayCopy(bits.get(), 0, cloneSet->bits.get(), 0, bits.size()); return cloneSet; } - + void OpenBitSet::intersect(OpenBitSetPtr other) { int32_t newLen= std::min(this->wlen, other->wlen); @@ -465,7 +465,7 @@ namespace Lucene } this->wlen = newLen; } - + void OpenBitSet::_union(OpenBitSetPtr other) { int32_t newLen = std::max(wlen, other->wlen); @@ -480,7 +480,7 @@ namespace Lucene MiscUtils::arrayCopy(otherArr.get(), this->wlen, thisArr.get(), this->wlen, newLen - this->wlen); this->wlen = newLen; } - + void OpenBitSet::remove(OpenBitSetPtr other) { int32_t idx = std::min(wlen, other->wlen); @@ -489,7 +489,7 @@ namespace Lucene while (--idx >= 0) thisArr[idx] &= ~otherArr[idx]; } - + void OpenBitSet::_xor(OpenBitSetPtr other) { int32_t newLen = std::max(wlen, other->wlen); @@ -504,22 +504,22 @@ namespace Lucene MiscUtils::arrayCopy(otherArr.get(), this->wlen, thisArr.get(), this->wlen, newLen - this->wlen); this->wlen = newLen; } - + void OpenBitSet::_and(OpenBitSetPtr other) { intersect(other); } - + void OpenBitSet::_or(OpenBitSetPtr other) { _union(other); } - + void OpenBitSet::andNot(OpenBitSetPtr other) { remove(other); } - + bool OpenBitSet::intersects(OpenBitSetPtr other) { int32_t pos = std::min(this->wlen, other->wlen); @@ -532,7 +532,7 @@ namespace Lucene } return false; } - + void OpenBitSet::ensureCapacityWords(int32_t numWords) { int32_t length = bits.size(); @@ -547,7 +547,7 @@ namespace Lucene { ensureCapacityWords(bits2words(numBits)); } - + void OpenBitSet::trimTrailingZeros() { int32_t idx = wlen - 1; @@ -555,12 +555,12 @@ namespace Lucene --idx; wlen = idx + 1; } - + int32_t OpenBitSet::bits2words(int64_t numBits) { return (int32_t)(MiscUtils::unsignedShift(numBits - 1, (int64_t)6) + 1); } - + bool OpenBitSet::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -578,23 +578,23 @@ namespace Lucene } else a = shared_from_this(); - + // check for any set bits out of the range of b for (int32_t i = a->wlen - 1; i >= b->wlen; --i) { if (a->bits[i] !=0 ) return false; } - + for (int32_t i = b->wlen - 1; i >= 0; --i) { if (a->bits[i] != b->bits[i]) return false; } - + return true; } - + int32_t OpenBitSet::hashCode() { // Start with a zero hash and use a mix that results in zero if the input is zero. @@ -605,7 +605,7 @@ namespace Lucene hash ^= bits[i]; hash = (hash << 1) | MiscUtils::unsignedShift(hash, (int64_t)63); // rotate left } - // Fold leftmost bits into right and add a constant to prevent empty sets from + // Fold leftmost bits into right and add a constant to prevent empty sets from // returning 0, which is too common. return (int32_t)((hash >> 32) ^ hash) + 0x98761234; } diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index f7c65721..4b36179f 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,5 +1,14 @@ project(lucene++-tester) +include_directories( + ${GTEST_INCLUDE_DIR} + ${lucene++_SOURCE_DIR}/include + ${lucene++-lib_SOURCE_DIR}/include + ${lucene++-contrib_SOURCE_DIR}/include + ${lucene++-tester_SOURCE_DIR}/include + ${Boost_INCLUDE_DIRS} +) + file(GLOB_RECURSE tester_sources analysis/*.cpp contrib/*.cpp @@ -17,24 +26,25 @@ file(GLOB_RECURSE test_headers ${lucene++-tester_SOURCE_DIR}/include/*.h ) -include_directories( - ${lucene++_SOURCE_DIR}/include - ${lucene++-lib_SOURCE_DIR}/include - ${lucene++-contrib_SOURCE_DIR}/include - ${lucene++-tester_SOURCE_DIR}/include - ${Boost_INCLUDE_DIRS} -) - add_definitions(-DLPP_EXPOSE_INTERNAL) +link_directories( + ${GTEST_LIB_DIR} +) + add_executable(lucene++-tester ${tester_sources} ${test_headers} ) +add_dependencies(lucene++-tester + googletest +) + target_link_libraries(lucene++-tester ${CMAKE_THREAD_LIBS_INIT} lucene++ lucene++-contrib + gtest ${lucene_boost_libs} ) diff --git a/src/test/analysis/AnalyzersTest.cpp b/src/test/analysis/AnalyzersTest.cpp index a71b7fee..5513a8e6 100644 --- a/src/test/analysis/AnalyzersTest.cpp +++ b/src/test/analysis/AnalyzersTest.cpp @@ -17,7 +17,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(AnalyzersTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture AnalyzersTest; static void verifyPayload(TokenStreamPtr ts) { @@ -27,11 +27,11 @@ static void verifyPayload(TokenStreamPtr ts) bool hasNext = ts->incrementToken(); if (!hasNext) break; - BOOST_CHECK_EQUAL(b, payloadAtt->getPayload()->toByteArray()[0]); + EXPECT_EQ(b, payloadAtt->getPayload()->toByteArray()[0]); } } -BOOST_AUTO_TEST_CASE(testSimple) +TEST_F(AnalyzersTest, testSimple) { AnalyzerPtr a = newLucene(); checkAnalyzesTo(a, L"foo bar FOO BAR", newCollection(L"foo", L"bar", L"foo", L"bar")); @@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(testSimple) checkAnalyzesTo(a, L"\"QUOTED\" word", newCollection(L"quoted", L"word")); } -BOOST_AUTO_TEST_CASE(testNull) +TEST_F(AnalyzersTest, testNull) { AnalyzerPtr a = newLucene(); checkAnalyzesTo(a, L"foo bar FOO BAR", newCollection(L"foo", L"bar", L"FOO", L"BAR")); @@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(testNull) checkAnalyzesTo(a, L"\"QUOTED\" word", newCollection(L"\"QUOTED\"", L"word")); } -BOOST_AUTO_TEST_CASE(testStop) +TEST_F(AnalyzersTest, testStop) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(a, L"foo bar FOO BAR", newCollection(L"foo", L"bar", L"foo", L"bar")); @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(testStop) namespace TestPayloadCopy { DECLARE_SHARED_PTR(PayloadSetter) - + class PayloadSetter : public TokenFilter { public: @@ -78,7 +78,7 @@ namespace TestPayloadCopy data[0] = 0; p = newLucene(data, 0, 1); } - + virtual ~PayloadSetter() { } @@ -102,7 +102,7 @@ namespace TestPayloadCopy } /// Make sure old style next() calls result in a new copy of payloads -BOOST_AUTO_TEST_CASE(testPayloadCopy) +TEST_F(AnalyzersTest, testPayloadCopy) { String s = L"how now brown cow"; TokenStreamPtr ts = newLucene(newLucene(s)); @@ -113,5 +113,3 @@ BOOST_AUTO_TEST_CASE(testPayloadCopy) ts = newLucene(ts); verifyPayload(ts); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/BaseTokenStreamFixture.cpp b/src/test/analysis/BaseTokenStreamFixture.cpp index 94254cfa..9fdd2845 100644 --- a/src/test/analysis/BaseTokenStreamFixture.cpp +++ b/src/test/analysis/BaseTokenStreamFixture.cpp @@ -20,46 +20,46 @@ namespace Lucene { clearCalled = false; } - + CheckClearAttributesAttribute::~CheckClearAttributesAttribute() { } - + bool CheckClearAttributesAttribute::getAndResetClearCalled() { bool _clearCalled = clearCalled; clearCalled = false; return _clearCalled; } - + void CheckClearAttributesAttribute::clear() { clearCalled = true; } - + bool CheckClearAttributesAttribute::equals(LuceneObjectPtr other) { if (Attribute::equals(other)) return true; - + CheckClearAttributesAttributePtr otherAttribute(boost::dynamic_pointer_cast(other)); if (otherAttribute) return (otherAttribute->clearCalled == clearCalled); - + return false; } - + int32_t CheckClearAttributesAttribute::hashCode() { return 76137213 ^ (clearCalled ? 1231 : 1237); } - + void CheckClearAttributesAttribute::copyTo(AttributePtr target) { CheckClearAttributesAttributePtr clearAttribute(boost::dynamic_pointer_cast(target)); clearAttribute->clear(); } - + LuceneObjectPtr CheckClearAttributesAttribute::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -67,41 +67,41 @@ namespace Lucene cloneAttribute->clearCalled = clearCalled; return cloneAttribute; } - + BaseTokenStreamFixture::~BaseTokenStreamFixture() { } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements, int32_t finalOffset) { - BOOST_CHECK(output); + EXPECT_TRUE(output); CheckClearAttributesAttributePtr checkClearAtt = ts->addAttribute(); - - BOOST_CHECK(ts->hasAttribute()); + + EXPECT_TRUE(ts->hasAttribute()); TermAttributePtr termAtt = ts->getAttribute(); - + OffsetAttributePtr offsetAtt; if (startOffsets || endOffsets || finalOffset != -1) { - BOOST_CHECK(ts->hasAttribute()); + EXPECT_TRUE(ts->hasAttribute()); offsetAtt = ts->getAttribute(); } - + TypeAttributePtr typeAtt; if (types) { - BOOST_CHECK(ts->hasAttribute()); + EXPECT_TRUE(ts->hasAttribute()); typeAtt = ts->getAttribute(); } - + PositionIncrementAttributePtr posIncrAtt; if (posIncrements) { - BOOST_CHECK(ts->hasAttribute()); + EXPECT_TRUE(ts->hasAttribute()); posIncrAtt = ts->getAttribute(); } - + ts->reset(); for (int32_t i = 0; i < output.size(); ++i) { @@ -114,130 +114,130 @@ namespace Lucene typeAtt->setType(L"bogusType"); if (posIncrAtt) posIncrAtt->setPositionIncrement(45987657); - + checkClearAtt->getAndResetClearCalled(); // reset it, because we called clearAttribute() before - BOOST_CHECK(ts->incrementToken()); - BOOST_CHECK(checkClearAtt->getAndResetClearCalled()); - - BOOST_CHECK_EQUAL(output[i], termAtt->term()); + EXPECT_TRUE(ts->incrementToken()); + EXPECT_TRUE(checkClearAtt->getAndResetClearCalled()); + + EXPECT_EQ(output[i], termAtt->term()); if (startOffsets) - BOOST_CHECK_EQUAL(startOffsets[i], offsetAtt->startOffset()); + EXPECT_EQ(startOffsets[i], offsetAtt->startOffset()); if (endOffsets) - BOOST_CHECK_EQUAL(endOffsets[i], offsetAtt->endOffset()); + EXPECT_EQ(endOffsets[i], offsetAtt->endOffset()); if (types) - BOOST_CHECK_EQUAL(types[i], typeAtt->type()); + EXPECT_EQ(types[i], typeAtt->type()); if (posIncrements) - BOOST_CHECK_EQUAL(posIncrements[i], posIncrAtt->getPositionIncrement()); + EXPECT_EQ(posIncrements[i], posIncrAtt->getPositionIncrement()); } - BOOST_CHECK(!ts->incrementToken()); + EXPECT_TRUE(!ts->incrementToken()); ts->end(); if (finalOffset != -1) - BOOST_CHECK_EQUAL(finalOffset, offsetAtt->endOffset()); + EXPECT_EQ(finalOffset, offsetAtt->endOffset()); ts->close(); } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output) { checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), Collection(), -1); } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection types) { checkTokenStreamContents(ts, output, Collection(), Collection(), types, Collection(), -1); } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection posIncrements) { checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), posIncrements, -1); } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), -1); } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), finalOffset); } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, -1); } - + void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, finalOffset); } - + void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements) { checkTokenStreamContents(analyzer->tokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); } - + void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output) { checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); } - + void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection types) { checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), types, Collection()); } - + void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements) { checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); } - + void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) { checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); } - + void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); } - + void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements) { checkTokenStreamContents(analyzer->reusableTokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); } - + void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output) { checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); } - + void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection types) { checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), types, Collection()); } - + void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements) { checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); } - + void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) { checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); } - + void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); } - + void BaseTokenStreamFixture::checkOneTerm(AnalyzerPtr analyzer, const String& input, const String& expected) { checkAnalyzesTo(analyzer, input, newCollection(expected)); } - + void BaseTokenStreamFixture::checkOneTermReuse(AnalyzerPtr analyzer, const String& input, const String& expected) { checkAnalyzesToReuse(analyzer, input, newCollection(expected)); diff --git a/src/test/analysis/CachingTokenFilterTest.cpp b/src/test/analysis/CachingTokenFilterTest.cpp index 34794d69..8447df44 100644 --- a/src/test/analysis/CachingTokenFilterTest.cpp +++ b/src/test/analysis/CachingTokenFilterTest.cpp @@ -21,7 +21,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CachingTokenFilterTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture CachingTokenFilterTest; static Collection tokens = newCollection(L"term1", L"term2", L"term3", L"term2"); @@ -30,14 +30,14 @@ static void checkTokens(TokenStreamPtr stream) int32_t count = 0; TermAttributePtr termAtt = stream->getAttribute(); - BOOST_CHECK(termAtt); + EXPECT_TRUE(termAtt); while (stream->incrementToken()) { - BOOST_CHECK(count < tokens.size()); - BOOST_CHECK_EQUAL(tokens[count], termAtt->term()); + EXPECT_TRUE(count < tokens.size()); + EXPECT_EQ(tokens[count], termAtt->term()); ++count; } - BOOST_CHECK_EQUAL(tokens.size(), count); + EXPECT_EQ(tokens.size(), count); } namespace TestCaching @@ -51,16 +51,16 @@ namespace TestCaching termAtt = addAttribute(); offsetAtt = addAttribute(); } - + virtual ~TestableTokenStream() { } - + protected: int32_t index; TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool incrementToken() { @@ -77,7 +77,7 @@ namespace TestCaching }; } -BOOST_AUTO_TEST_CASE(testCaching) +TEST_F(CachingTokenFilterTest, testCaching) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -88,35 +88,33 @@ BOOST_AUTO_TEST_CASE(testCaching) // 1) we consume all tokens twice before we add the doc to the index checkTokens(stream); - stream->reset(); + stream->reset(); checkTokens(stream); - // 2) now add the document to the index and verify if all tokens are indexed don't reset the stream here, the + // 2) now add the document to the index and verify if all tokens are indexed don't reset the stream here, the // DocumentWriter should do that implicitly writer->addDocument(doc); writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); TermPositionsPtr termPositions = reader->termPositions(newLucene(L"preanalyzed", L"term1")); - BOOST_CHECK(termPositions->next()); - BOOST_CHECK_EQUAL(1, termPositions->freq()); - BOOST_CHECK_EQUAL(0, termPositions->nextPosition()); + EXPECT_TRUE(termPositions->next()); + EXPECT_EQ(1, termPositions->freq()); + EXPECT_EQ(0, termPositions->nextPosition()); termPositions->seek(newLucene(L"preanalyzed", L"term2")); - BOOST_CHECK(termPositions->next()); - BOOST_CHECK_EQUAL(2, termPositions->freq()); - BOOST_CHECK_EQUAL(1, termPositions->nextPosition()); - BOOST_CHECK_EQUAL(3, termPositions->nextPosition()); + EXPECT_TRUE(termPositions->next()); + EXPECT_EQ(2, termPositions->freq()); + EXPECT_EQ(1, termPositions->nextPosition()); + EXPECT_EQ(3, termPositions->nextPosition()); termPositions->seek(newLucene(L"preanalyzed", L"term3")); - BOOST_CHECK(termPositions->next()); - BOOST_CHECK_EQUAL(1, termPositions->freq()); - BOOST_CHECK_EQUAL(2, termPositions->nextPosition()); + EXPECT_TRUE(termPositions->next()); + EXPECT_EQ(1, termPositions->freq()); + EXPECT_EQ(2, termPositions->nextPosition()); reader->close(); // 3) reset stream and consume tokens again stream->reset(); checkTokens(stream); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/CharFilterTest.cpp b/src/test/analysis/CharFilterTest.cpp index 2d87108c..e55da7a0 100644 --- a/src/test/analysis/CharFilterTest.cpp +++ b/src/test/analysis/CharFilterTest.cpp @@ -12,7 +12,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CharFilterTest, LuceneTestFixture) +typedef LuceneTestFixture CharFilterTest; class CharFilter1 : public CharFilter { @@ -20,7 +20,7 @@ class CharFilter1 : public CharFilter CharFilter1(CharStreamPtr in) : CharFilter(in) { } - + virtual ~CharFilter1() { } @@ -38,7 +38,7 @@ class CharFilter2 : public CharFilter CharFilter2(CharStreamPtr in) : CharFilter(in) { } - + virtual ~CharFilter2() { } @@ -50,28 +50,26 @@ class CharFilter2 : public CharFilter } }; -BOOST_AUTO_TEST_CASE(testCharFilter1) +TEST_F(CharFilterTest, testCharFilter1) { CharStreamPtr cs = newLucene(CharReader::get(newLucene(L""))); - BOOST_CHECK_EQUAL(1, cs->correctOffset(0)); + EXPECT_EQ(1, cs->correctOffset(0)); } -BOOST_AUTO_TEST_CASE(testCharFilter2) +TEST_F(CharFilterTest, testCharFilter2) { CharStreamPtr cs = newLucene(CharReader::get(newLucene(L""))); - BOOST_CHECK_EQUAL(2, cs->correctOffset(0)); + EXPECT_EQ(2, cs->correctOffset(0)); } -BOOST_AUTO_TEST_CASE(testCharFilter12) +TEST_F(CharFilterTest, testCharFilter12) { CharStreamPtr cs = newLucene(newLucene(CharReader::get(newLucene(L"")))); - BOOST_CHECK_EQUAL(3, cs->correctOffset(0)); + EXPECT_EQ(3, cs->correctOffset(0)); } -BOOST_AUTO_TEST_CASE(testCharFilter11) +TEST_F(CharFilterTest, testCharFilter11) { CharStreamPtr cs = newLucene(newLucene(CharReader::get(newLucene(L"")))); - BOOST_CHECK_EQUAL(2, cs->correctOffset(0)); + EXPECT_EQ(2, cs->correctOffset(0)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/KeywordAnalyzerTest.cpp b/src/test/analysis/KeywordAnalyzerTest.cpp index 8f340eca..0f8044f3 100644 --- a/src/test/analysis/KeywordAnalyzerTest.cpp +++ b/src/test/analysis/KeywordAnalyzerTest.cpp @@ -27,10 +27,10 @@ using namespace Lucene; -class KeywordAnalyzerTestFixture : public BaseTokenStreamFixture +class KeywordAnalyzerTest : public BaseTokenStreamFixture { public: - KeywordAnalyzerTestFixture() + KeywordAnalyzerTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -43,8 +43,8 @@ class KeywordAnalyzerTestFixture : public BaseTokenStreamFixture searcher = newLucene(directory, true); } - - virtual ~KeywordAnalyzerTestFixture() + + virtual ~KeywordAnalyzerTest() { } @@ -53,9 +53,7 @@ class KeywordAnalyzerTestFixture : public BaseTokenStreamFixture IndexSearcherPtr searcher; }; -BOOST_FIXTURE_TEST_SUITE(KeywordAnalyzerTest, KeywordAnalyzerTestFixture) - -BOOST_AUTO_TEST_CASE(testPerFieldAnalyzer) +TEST_F(KeywordAnalyzerTest, testPerFieldAnalyzer) { PerFieldAnalyzerWrapperPtr analyzer = newLucene(newLucene()); analyzer->addAnalyzer(L"partnum", newLucene()); @@ -64,11 +62,11 @@ BOOST_AUTO_TEST_CASE(testPerFieldAnalyzer) QueryPtr query = queryParser->parse(L"partnum:Q36 AND SPACE"); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(L"+partnum:Q36 +space", query->toString(L"description")); - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(L"+partnum:Q36 +space", query->toString(L"description")); + EXPECT_EQ(1, hits.size()); } -BOOST_AUTO_TEST_CASE(testMutipleDocument) +TEST_F(KeywordAnalyzerTest, testMutipleDocument) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -82,18 +80,16 @@ BOOST_AUTO_TEST_CASE(testMutipleDocument) IndexReaderPtr reader = IndexReader::open(dir, true); TermDocsPtr td = reader->termDocs(newLucene(L"partnum", L"Q36")); - BOOST_CHECK(td->next()); + EXPECT_TRUE(td->next()); td = reader->termDocs(newLucene(L"partnum", L"Q37")); - BOOST_CHECK(td->next()); + EXPECT_TRUE(td->next()); } -BOOST_AUTO_TEST_CASE(testOffsets) +TEST_F(KeywordAnalyzerTest, testOffsets) { TokenStreamPtr stream = newLucene()->tokenStream(L"field", newLucene(L"abcd")); OffsetAttributePtr offsetAtt = stream->addAttribute(); - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(0, offsetAtt->startOffset()); - BOOST_CHECK_EQUAL(4, offsetAtt->endOffset()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(0, offsetAtt->startOffset()); + EXPECT_EQ(4, offsetAtt->endOffset()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/LengthFilterTest.cpp b/src/test/analysis/LengthFilterTest.cpp index add84bba..0266953a 100644 --- a/src/test/analysis/LengthFilterTest.cpp +++ b/src/test/analysis/LengthFilterTest.cpp @@ -14,21 +14,19 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(LengthFilterTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture LengthFilterTest; -BOOST_AUTO_TEST_CASE(testFilter) +TEST_F(LengthFilterTest, testFilter) { TokenStreamPtr stream = newLucene(newLucene(L"short toolong evenmuchlongertext a ab toolong foo")); LengthFilterPtr filter = newLucene(stream, 2, 6); TermAttributePtr termAtt = filter->getAttribute(); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"short", termAtt->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"ab", termAtt->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"foo", termAtt->term()); - BOOST_CHECK(!filter->incrementToken()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"short", termAtt->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"ab", termAtt->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"foo", termAtt->term()); + EXPECT_TRUE(!filter->incrementToken()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/MappingCharFilterTest.cpp b/src/test/analysis/MappingCharFilterTest.cpp index d3c3edd0..e9b04ea7 100644 --- a/src/test/analysis/MappingCharFilterTest.cpp +++ b/src/test/analysis/MappingCharFilterTest.cpp @@ -15,10 +15,10 @@ using namespace Lucene; -class MappingCharFilterTestFixture : public BaseTokenStreamFixture +class MappingCharFilterTest : public BaseTokenStreamFixture { public: - MappingCharFilterTestFixture() + MappingCharFilterTest() { normMap = newLucene(); @@ -33,8 +33,8 @@ class MappingCharFilterTestFixture : public BaseTokenStreamFixture normMap->add(L"empty", L""); } - - virtual ~MappingCharFilterTestFixture() + + virtual ~MappingCharFilterTest() { } @@ -42,82 +42,80 @@ class MappingCharFilterTestFixture : public BaseTokenStreamFixture NormalizeCharMapPtr normMap; }; -BOOST_FIXTURE_TEST_SUITE(MappingCharFilterTest, MappingCharFilterTestFixture) - -BOOST_AUTO_TEST_CASE(testReaderReset) +TEST_F(MappingCharFilterTest, testReaderReset) { CharStreamPtr cs = newLucene(normMap, newLucene(L"x")); CharArray buf = CharArray::newInstance(10); int32_t len = cs->read(buf.get(), 0, 10); - BOOST_CHECK_EQUAL(1, len); - BOOST_CHECK_EQUAL(L'x', buf[0]) ; + EXPECT_EQ(1, len); + EXPECT_EQ(L'x', buf[0]) ; len = cs->read(buf.get(), 0, 10); - BOOST_CHECK_EQUAL(-1, len); + EXPECT_EQ(-1, len); // rewind cs->reset(); len = cs->read(buf.get(), 0, 10); - BOOST_CHECK_EQUAL(1, len); - BOOST_CHECK_EQUAL(L'x', buf[0]) ; + EXPECT_EQ(1, len); + EXPECT_EQ(L'x', buf[0]) ; } -BOOST_AUTO_TEST_CASE(testNothingChange) +TEST_F(MappingCharFilterTest, testNothingChange) { CharStreamPtr cs = newLucene(normMap, newLucene(L"x")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"x"), newCollection(0), newCollection(1)); } -BOOST_AUTO_TEST_CASE(test1to1) +TEST_F(MappingCharFilterTest, test1to1) { CharStreamPtr cs = newLucene(normMap, newLucene(L"h")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"i"), newCollection(0), newCollection(1)); } -BOOST_AUTO_TEST_CASE(test1to2) +TEST_F(MappingCharFilterTest, test1to2) { CharStreamPtr cs = newLucene(normMap, newLucene(L"j")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"jj"), newCollection(0), newCollection(1)); } -BOOST_AUTO_TEST_CASE(test1to3) +TEST_F(MappingCharFilterTest, test1to3) { CharStreamPtr cs = newLucene(normMap, newLucene(L"k")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"kkk"), newCollection(0), newCollection(1)); } -BOOST_AUTO_TEST_CASE(test2to4) +TEST_F(MappingCharFilterTest, test2to4) { CharStreamPtr cs = newLucene(normMap, newLucene(L"ll")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"llll"), newCollection(0), newCollection(2)); } -BOOST_AUTO_TEST_CASE(test2to1) +TEST_F(MappingCharFilterTest, test2to1) { CharStreamPtr cs = newLucene(normMap, newLucene(L"aa")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"a"), newCollection(0), newCollection(2)); } -BOOST_AUTO_TEST_CASE(test3to1) +TEST_F(MappingCharFilterTest, test3to1) { CharStreamPtr cs = newLucene(normMap, newLucene(L"bbb")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"b"), newCollection(0), newCollection(3)); } -BOOST_AUTO_TEST_CASE(test4to2) +TEST_F(MappingCharFilterTest, test4to2) { CharStreamPtr cs = newLucene(normMap, newLucene(L"cccc")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"cc"), newCollection(0), newCollection(4)); } -BOOST_AUTO_TEST_CASE(test5to0) +TEST_F(MappingCharFilterTest, test5to0) { CharStreamPtr cs = newLucene(normMap, newLucene(L"empty")); TokenStreamPtr ts = newLucene(cs); @@ -141,12 +139,12 @@ BOOST_AUTO_TEST_CASE(test5to0) // cccc,11,15 => cc,11,15 // bbb,16,19 => b,16,19 // aa,20,22 => a,20,22 -BOOST_AUTO_TEST_CASE(testTokenStream) +TEST_F(MappingCharFilterTest, testTokenStream) { CharStreamPtr cs = newLucene(normMap, CharReader::get(newLucene(L"h i j k ll cccc bbb aa"))); TokenStreamPtr ts = newLucene(cs); - checkTokenStreamContents(ts, newCollection(L"i", L"i", L"jj", L"kkk", L"llll", L"cc", L"b", L"a"), - newCollection(0, 2, 4, 6, 8, 11, 16, 20), + checkTokenStreamContents(ts, newCollection(L"i", L"i", L"jj", L"kkk", L"llll", L"cc", L"b", L"a"), + newCollection(0, 2, 4, 6, 8, 11, 16, 20), newCollection(1, 3, 5, 7, 10, 15, 19, 22)); } @@ -160,11 +158,9 @@ BOOST_AUTO_TEST_CASE(testTokenStream) // aaaa,0,4 => a,0,4 // ll,5,7 => llllllll,5,7 // h,8,9 => i,8,9 -BOOST_AUTO_TEST_CASE(testChained) +TEST_F(MappingCharFilterTest, testChained) { CharStreamPtr cs = newLucene(normMap, (CharStreamPtr)newLucene(normMap, CharReader::get(newLucene(L"aaaa ll h")))); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"a", L"llllllll", L"i"), newCollection(0, 5, 8), newCollection(4, 7, 9)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/NumericTokenStreamTest.cpp b/src/test/analysis/NumericTokenStreamTest.cpp index bc57abdf..6533c238 100644 --- a/src/test/analysis/NumericTokenStreamTest.cpp +++ b/src/test/analysis/NumericTokenStreamTest.cpp @@ -13,12 +13,12 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(NumericTokenStreamTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture NumericTokenStreamTest; static int64_t lvalue = 4573245871874382LL; static int32_t ivalue = 123456; -BOOST_AUTO_TEST_CASE(testLongStream) +TEST_F(NumericTokenStreamTest, testLongStream) { NumericTokenStreamPtr stream = newLucene()->setLongValue(lvalue); // use getAttribute to test if attributes really exist, if not an IAE will be thrown @@ -26,14 +26,14 @@ BOOST_AUTO_TEST_CASE(testLongStream) TypeAttributePtr typeAtt = stream->getAttribute(); for (int32_t shift = 0; shift < 64; shift += NumericUtils::PRECISION_STEP_DEFAULT) { - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(NumericUtils::longToPrefixCoded(lvalue, shift), termAtt->term()); - BOOST_CHECK_EQUAL(shift == 0 ? NumericTokenStream::TOKEN_TYPE_FULL_PREC() : NumericTokenStream::TOKEN_TYPE_LOWER_PREC(), typeAtt->type()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(NumericUtils::longToPrefixCoded(lvalue, shift), termAtt->term()); + EXPECT_EQ(shift == 0 ? NumericTokenStream::TOKEN_TYPE_FULL_PREC() : NumericTokenStream::TOKEN_TYPE_LOWER_PREC(), typeAtt->type()); } - BOOST_CHECK(!stream->incrementToken()); + EXPECT_TRUE(!stream->incrementToken()); } -BOOST_AUTO_TEST_CASE(testIntStream) +TEST_F(NumericTokenStreamTest, testIntStream) { NumericTokenStreamPtr stream = newLucene()->setIntValue(ivalue); // use getAttribute to test if attributes really exist, if not an IAE will be thrown @@ -41,18 +41,30 @@ BOOST_AUTO_TEST_CASE(testIntStream) TypeAttributePtr typeAtt = stream->getAttribute(); for (int32_t shift = 0; shift < 32; shift += NumericUtils::PRECISION_STEP_DEFAULT) { - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(NumericUtils::intToPrefixCoded(ivalue, shift), termAtt->term()); - BOOST_CHECK_EQUAL(shift == 0 ? NumericTokenStream::TOKEN_TYPE_FULL_PREC() : NumericTokenStream::TOKEN_TYPE_LOWER_PREC(), typeAtt->type()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(NumericUtils::intToPrefixCoded(ivalue, shift), termAtt->term()); + EXPECT_EQ(shift == 0 ? NumericTokenStream::TOKEN_TYPE_FULL_PREC() : NumericTokenStream::TOKEN_TYPE_LOWER_PREC(), typeAtt->type()); } - BOOST_CHECK(!stream->incrementToken()); + EXPECT_TRUE(!stream->incrementToken()); } -BOOST_AUTO_TEST_CASE(testNotInitialized) +TEST_F(NumericTokenStreamTest, testNotInitialized) { NumericTokenStreamPtr stream = newLucene(); - BOOST_CHECK_EXCEPTION(stream->reset(), IllegalStateException, check_exception(LuceneException::IllegalState)); - BOOST_CHECK_EXCEPTION(stream->incrementToken(), IllegalStateException, check_exception(LuceneException::IllegalState)); + try + { + stream->reset(); + } + catch (IllegalStateException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); + } + try + { + stream->incrementToken(); + } + catch (IllegalStateException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); + } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp b/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp index d7a2f5e8..48b2fa79 100644 --- a/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp +++ b/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp @@ -15,9 +15,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PerFieldAnalzyerWrapperTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture PerFieldAnalzyerWrapperTest; -BOOST_AUTO_TEST_CASE(testPerField) +TEST_F(PerFieldAnalzyerWrapperTest, testPerField) { String text = L"Qwerty"; PerFieldAnalyzerWrapperPtr analyzer = newLucene(newLucene()); @@ -26,13 +26,11 @@ BOOST_AUTO_TEST_CASE(testPerField) TokenStreamPtr tokenStream = analyzer->tokenStream(L"field", newLucene(text)); TermAttributePtr termAtt = tokenStream->getAttribute(); - BOOST_CHECK(tokenStream->incrementToken()); - BOOST_CHECK_EQUAL(L"Qwerty", termAtt->term()); + EXPECT_TRUE(tokenStream->incrementToken()); + EXPECT_EQ(L"Qwerty", termAtt->term()); tokenStream = analyzer->tokenStream(L"special", newLucene(text)); termAtt = tokenStream->getAttribute(); - BOOST_CHECK(tokenStream->incrementToken()); - BOOST_CHECK_EQUAL(L"qwerty", termAtt->term()); + EXPECT_TRUE(tokenStream->incrementToken()); + EXPECT_EQ(L"qwerty", termAtt->term()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/StopAnalyzerTest.cpp b/src/test/analysis/StopAnalyzerTest.cpp index 43bd430b..b0ffb662 100644 --- a/src/test/analysis/StopAnalyzerTest.cpp +++ b/src/test/analysis/StopAnalyzerTest.cpp @@ -14,18 +14,18 @@ using namespace Lucene; -class StopAnalyzerTestFixture : public BaseTokenStreamFixture +class StopAnalyzerTest : public BaseTokenStreamFixture { public: - StopAnalyzerTestFixture() + StopAnalyzerTest() { stop = newLucene(LuceneVersion::LUCENE_CURRENT); inValidTokens = HashSet::newInstance(); for (HashSet::iterator word = StopAnalyzer::ENGLISH_STOP_WORDS_SET().begin(); word != StopAnalyzer::ENGLISH_STOP_WORDS_SET().end(); ++word) inValidTokens.add(*word); } - - virtual ~StopAnalyzerTestFixture() + + virtual ~StopAnalyzerTest() { } @@ -34,21 +34,19 @@ class StopAnalyzerTestFixture : public BaseTokenStreamFixture HashSet inValidTokens; }; -BOOST_FIXTURE_TEST_SUITE(StopAnalyzerTest, StopAnalyzerTestFixture) - -BOOST_AUTO_TEST_CASE(testDefaults) +TEST_F(StopAnalyzerTest, testDefaults) { - BOOST_CHECK(stop); + EXPECT_TRUE(stop); StringReaderPtr reader = newLucene(L"This is a test of the english stop analyzer"); TokenStreamPtr stream = stop->tokenStream(L"test", reader); - BOOST_CHECK(stream); + EXPECT_TRUE(stream); TermAttributePtr termAtt = stream->getAttribute(); while (stream->incrementToken()) - BOOST_CHECK(!inValidTokens.contains(termAtt->term())); + EXPECT_TRUE(!inValidTokens.contains(termAtt->term())); } -BOOST_AUTO_TEST_CASE(testStopList) +TEST_F(StopAnalyzerTest, testStopList) { HashSet stopWordsSet = HashSet::newInstance(); stopWordsSet.add(L"good"); @@ -57,19 +55,19 @@ BOOST_AUTO_TEST_CASE(testStopList) StopAnalyzerPtr newStop = newLucene(LuceneVersion::LUCENE_24, stopWordsSet); StringReaderPtr reader = newLucene(L"This is a good test of the english stop analyzer"); TokenStreamPtr stream = newStop->tokenStream(L"test", reader); - BOOST_CHECK(stream); + EXPECT_TRUE(stream); TermAttributePtr termAtt = stream->getAttribute(); PositionIncrementAttributePtr posIncrAtt = stream->addAttribute(); while (stream->incrementToken()) { String text = termAtt->term(); - BOOST_CHECK(!stopWordsSet.contains(text)); - BOOST_CHECK_EQUAL(1, posIncrAtt->getPositionIncrement()); // in 2.4 stop tokenizer does not apply increments. + EXPECT_TRUE(!stopWordsSet.contains(text)); + EXPECT_EQ(1, posIncrAtt->getPositionIncrement()); // in 2.4 stop tokenizer does not apply increments. } } -BOOST_AUTO_TEST_CASE(testStopListPositions) +TEST_F(StopAnalyzerTest, testStopListPositions) { HashSet stopWordsSet = HashSet::newInstance(); stopWordsSet.add(L"good"); @@ -79,7 +77,7 @@ BOOST_AUTO_TEST_CASE(testStopListPositions) StringReaderPtr reader = newLucene(L"This is a good test of the english stop analyzer with positions"); Collection expectedIncr = newCollection(1, 1, 1, 3, 1, 1, 1, 2, 1); TokenStreamPtr stream = newStop->tokenStream(L"test", reader); - BOOST_CHECK(stream); + EXPECT_TRUE(stream); int32_t i = 0; TermAttributePtr termAtt = stream->getAttribute(); PositionIncrementAttributePtr posIncrAtt = stream->addAttribute(); @@ -87,9 +85,7 @@ BOOST_AUTO_TEST_CASE(testStopListPositions) while (stream->incrementToken()) { String text = termAtt->term(); - BOOST_CHECK(!stopWordsSet.contains(text)); - BOOST_CHECK_EQUAL(expectedIncr[i++], posIncrAtt->getPositionIncrement()); + EXPECT_TRUE(!stopWordsSet.contains(text)); + EXPECT_EQ(expectedIncr[i++], posIncrAtt->getPositionIncrement()); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/StopFilterTest.cpp b/src/test/analysis/StopFilterTest.cpp index f78a5d44..ef12b09e 100644 --- a/src/test/analysis/StopFilterTest.cpp +++ b/src/test/analysis/StopFilterTest.cpp @@ -16,7 +16,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(StopFilterTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture StopFilterTest; static void doTestStopPositons(StopFilterPtr stpf, bool enableIcrements) { @@ -25,15 +25,15 @@ static void doTestStopPositons(StopFilterPtr stpf, bool enableIcrements) PositionIncrementAttributePtr posIncrAtt = stpf->getAttribute(); for (int32_t i = 0; i < 20; i += 3) { - BOOST_CHECK(stpf->incrementToken()); + EXPECT_TRUE(stpf->incrementToken()); String w = intToEnglish(i); - BOOST_CHECK_EQUAL(w, termAtt->term()); - BOOST_CHECK_EQUAL(enableIcrements ? (i == 0 ? 1 : 3) : 1, posIncrAtt->getPositionIncrement()); + EXPECT_EQ(w, termAtt->term()); + EXPECT_EQ(enableIcrements ? (i == 0 ? 1 : 3) : 1, posIncrAtt->getPositionIncrement()); } - BOOST_CHECK(!stpf->incrementToken()); + EXPECT_TRUE(!stpf->incrementToken()); } -BOOST_AUTO_TEST_CASE(testExactCase) +TEST_F(StopFilterTest, testExactCase) { StringReaderPtr reader = newLucene(L"Now is The Time"); HashSet stopWords = HashSet::newInstance(); @@ -42,14 +42,14 @@ BOOST_AUTO_TEST_CASE(testExactCase) stopWords.add(L"Time"); TokenStreamPtr stream = newLucene(false, newLucene(reader), stopWords, false); TermAttributePtr termAtt = stream->getAttribute(); - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(L"Now", termAtt->term()); - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(L"The", termAtt->term()); - BOOST_CHECK(!stream->incrementToken()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(L"Now", termAtt->term()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(L"The", termAtt->term()); + EXPECT_TRUE(!stream->incrementToken()); } -BOOST_AUTO_TEST_CASE(testIgnoreCase) +TEST_F(StopFilterTest, testIgnoreCase) { StringReaderPtr reader = newLucene(L"Now is The Time"); HashSet stopWords = HashSet::newInstance(); @@ -58,12 +58,12 @@ BOOST_AUTO_TEST_CASE(testIgnoreCase) stopWords.add(L"Time"); TokenStreamPtr stream = newLucene(false, newLucene(reader), stopWords, true); TermAttributePtr termAtt = stream->getAttribute(); - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(L"Now", termAtt->term()); - BOOST_CHECK(!stream->incrementToken()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(L"Now", termAtt->term()); + EXPECT_TRUE(!stream->incrementToken()); } -BOOST_AUTO_TEST_CASE(testStopPositons) +TEST_F(StopFilterTest, testStopPositons) { StringStream buf; Collection stopWords = Collection::newInstance(); @@ -101,5 +101,3 @@ BOOST_AUTO_TEST_CASE(testStopPositons) StopFilterPtr stpf01 = newLucene(false, stpf0, stopSet1); // two stop filters concatenated! doTestStopPositons(stpf01, true); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/TeeSinkTokenFilterTest.cpp b/src/test/analysis/TeeSinkTokenFilterTest.cpp index 43f9d807..1455158d 100644 --- a/src/test/analysis/TeeSinkTokenFilterTest.cpp +++ b/src/test/analysis/TeeSinkTokenFilterTest.cpp @@ -52,24 +52,24 @@ class DogSinkFilter : public SinkFilter } }; -class TeeSinkTokenFilterTestFixture : public BaseTokenStreamFixture +class TeeSinkTokenFilterTest : public BaseTokenStreamFixture { public: - TeeSinkTokenFilterTestFixture() + TeeSinkTokenFilterTest() { tokens1 = newCollection(L"The", L"quick", L"Burgundy", L"Fox", L"jumped", L"over", L"the", L"lazy", L"Red", L"Dogs"); tokens2 = newCollection(L"The", L"Lazy", L"Dogs", L"should", L"stay", L"on", L"the", L"porch"); - + for (int32_t i = 0; i < tokens1.size(); ++i) buffer1 << tokens1[i] << L" "; for (int32_t i = 0; i < tokens2.size(); ++i) buffer2 << tokens2[i] << L" "; - + theFilter = newLucene(); dogFilter = newLucene(); } - - virtual ~TeeSinkTokenFilterTestFixture() + + virtual ~TeeSinkTokenFilterTest() { } @@ -78,19 +78,17 @@ class TeeSinkTokenFilterTestFixture : public BaseTokenStreamFixture StringStream buffer2; Collection tokens1; Collection tokens2; - + SinkFilterPtr theFilter; SinkFilterPtr dogFilter; }; -BOOST_FIXTURE_TEST_SUITE(TeeSinkTokenFilterTest, TeeSinkTokenFilterTestFixture) - -BOOST_AUTO_TEST_CASE(testGeneral) +TEST_F(TeeSinkTokenFilterTest, testGeneral) { TeeSinkTokenFilterPtr source = newLucene(newLucene(newLucene(buffer1.str()))); TokenStreamPtr sink1 = source->newSinkTokenStream(); TokenStreamPtr sink2 = source->newSinkTokenStream(theFilter); - + source->addAttribute(); sink1->addAttribute(); sink2->addAttribute(); @@ -100,13 +98,13 @@ BOOST_AUTO_TEST_CASE(testGeneral) checkTokenStreamContents(sink2, newCollection(L"The", L"the")); } -BOOST_AUTO_TEST_CASE(testMultipleSources) +TEST_F(TeeSinkTokenFilterTest, testMultipleSources) { TeeSinkTokenFilterPtr tee1 = newLucene(newLucene(newLucene(buffer1.str()))); SinkTokenStreamPtr dogDetector = tee1->newSinkTokenStream(dogFilter); SinkTokenStreamPtr theDetector = tee1->newSinkTokenStream(theFilter); TokenStreamPtr source1 = newLucene(tee1); - + tee1->addAttribute(); dogDetector->addAttribute(); theDetector->addAttribute(); @@ -115,7 +113,7 @@ BOOST_AUTO_TEST_CASE(testMultipleSources) tee2->addSinkTokenStream(dogDetector); tee2->addSinkTokenStream(theDetector); TokenStreamPtr source2 = tee2; - + checkTokenStreamContents(source1, tokens1); checkTokenStreamContents(source2, tokens2); @@ -140,15 +138,15 @@ namespace TestPerformance modCount = mc; count = 0; } - + virtual ~ModuloTokenFilter() { } - + public: int32_t modCount; int32_t count; - + public: // return every 100 tokens virtual bool incrementToken() @@ -160,7 +158,7 @@ namespace TestPerformance return hasNext; } }; - + class ModuloSinkFilter : public SinkFilter { public: @@ -169,15 +167,15 @@ namespace TestPerformance modCount = mc; count = 0; } - + virtual ~ModuloSinkFilter() { } - + public: int32_t modCount; int32_t count; - + public: virtual bool accept(AttributeSourcePtr source) { @@ -189,14 +187,14 @@ namespace TestPerformance } /// Not an explicit test, just useful to print out some info on performance -BOOST_AUTO_TEST_CASE(testPerformance) +TEST_F(TeeSinkTokenFilterTest, testPerformance) { Collection tokCount = newCollection(100, 500, 1000, 2000, 5000, 10000); Collection modCounts = newCollection(1, 2, 5, 10, 20, 50, 100, 200, 500); for (int32_t k = 0; k < tokCount.size(); ++k) { StringStream buffer; - BOOST_TEST_MESSAGE("-----Tokens: " << tokCount[k] << "-----"); + // std::cout << "-----Tokens: " << tokCount[k] << "-----"; for (int32_t i = 0; i < tokCount[k]; ++i) buffer << StringUtils::toUpper(intToEnglish(i)) << L" "; // make sure we produce the same tokens @@ -208,10 +206,10 @@ BOOST_AUTO_TEST_CASE(testPerformance) TermAttributePtr sinkTok = sink->addAttribute(); for (int32_t i = 0; stream->incrementToken(); ++i) { - BOOST_CHECK(sink->incrementToken()); - BOOST_CHECK(tfTok->equals(sinkTok)); + EXPECT_TRUE(sink->incrementToken()); + EXPECT_TRUE(tfTok->equals(sinkTok)); } - + // simulate two fields, each being analyzed once, for 20 documents for (int32_t j = 0; j < modCounts.size(); ++j) { @@ -229,7 +227,7 @@ BOOST_AUTO_TEST_CASE(testPerformance) tfPos += posIncrAtt->getPositionIncrement(); } int64_t finish = MiscUtils::currentTimeMillis(); - BOOST_TEST_MESSAGE("ModCount: " << modCounts[j] << " Two fields took " << (finish - start) << " ms"); + // std::cout << "ModCount: " << modCounts[j] << " Two fields took " << (finish - start) << " ms"; int32_t sinkPos = 0; // simulate one field with one sink start = MiscUtils::currentTimeMillis(); @@ -245,11 +243,9 @@ BOOST_AUTO_TEST_CASE(testPerformance) sinkPos += posIncrAtt->getPositionIncrement(); } finish = MiscUtils::currentTimeMillis(); - BOOST_TEST_MESSAGE("ModCount: " << modCounts[j] << " Tee fields took " << (finish - start) << " ms"); - BOOST_CHECK_EQUAL(sinkPos, tfPos); + // std::cout << "ModCount: " << modCounts[j] << " Tee fields took " << (finish - start) << " ms"; + EXPECT_EQ(sinkPos, tfPos); } - BOOST_TEST_MESSAGE("- End Tokens: " << tokCount[k] << "-----"); + // std::cout << "- End Tokens: " << tokCount[k] << "-----"; } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/TokenTest.cpp b/src/test/analysis/TokenTest.cpp index 1950c61f..58172403 100644 --- a/src/test/analysis/TokenTest.cpp +++ b/src/test/analysis/TokenTest.cpp @@ -11,13 +11,13 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(TokenTest, LuceneTestFixture) +typedef LuceneTestFixture TokenTest; static AttributePtr checkCloneIsEqual(AttributePtr att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); - BOOST_CHECK(att->equals(clone)); - BOOST_CHECK_EQUAL(att->hashCode(), clone->hashCode()); + EXPECT_TRUE(att->equals(clone)); + EXPECT_EQ(att->hashCode(), clone->hashCode()); return clone; } @@ -26,52 +26,52 @@ static AttributePtr checkCopyIsEqual(AttributePtr att) { AttributePtr copy = newLucene(); att->copyTo(copy); - BOOST_CHECK(att->equals(copy)); - BOOST_CHECK_EQUAL(att->hashCode(), copy->hashCode()); + EXPECT_TRUE(att->equals(copy)); + EXPECT_EQ(att->hashCode(), copy->hashCode()); return copy; } -BOOST_AUTO_TEST_CASE(testCtor) +TEST_F(TokenTest, testCtor) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); - BOOST_CHECK_EQUAL(L"hello", t->term()); - BOOST_CHECK_EQUAL(L"word", t->type()); - BOOST_CHECK_EQUAL(0, t->getFlags()); + EXPECT_EQ(L"hello", t->term()); + EXPECT_EQ(L"word", t->type()); + EXPECT_EQ(0, t->getFlags()); t = newLucene(6, 22); t->setTermBuffer(L"hello"); - BOOST_CHECK_EQUAL(L"hello", t->term()); - BOOST_CHECK_EQUAL(L"(hello,6,22)", t->toString()); - BOOST_CHECK_EQUAL(L"word", t->type()); - BOOST_CHECK_EQUAL(0, t->getFlags()); + EXPECT_EQ(L"hello", t->term()); + EXPECT_EQ(L"(hello,6,22)", t->toString()); + EXPECT_EQ(L"word", t->type()); + EXPECT_EQ(0, t->getFlags()); t = newLucene(6, 22, 7); t->setTermBuffer(L"hello"); - BOOST_CHECK_EQUAL(L"hello", t->term()); - BOOST_CHECK_EQUAL(L"(hello,6,22)", t->toString()); - BOOST_CHECK_EQUAL(7, t->getFlags()); + EXPECT_EQ(L"hello", t->term()); + EXPECT_EQ(L"(hello,6,22)", t->toString()); + EXPECT_EQ(7, t->getFlags()); t = newLucene(6, 22, L"junk"); t->setTermBuffer(L"hello"); - BOOST_CHECK_EQUAL(L"hello", t->term()); - BOOST_CHECK_EQUAL(L"(hello,6,22,type=junk)", t->toString()); - BOOST_CHECK_EQUAL(0, t->getFlags()); + EXPECT_EQ(L"hello", t->term()); + EXPECT_EQ(L"(hello,6,22,type=junk)", t->toString()); + EXPECT_EQ(0, t->getFlags()); } -BOOST_AUTO_TEST_CASE(testResize) +TEST_F(TokenTest, testResize) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); for (int32_t i = 0; i < 2000; ++i) { t->resizeTermBuffer(i); - BOOST_CHECK(i <= t->termBuffer().size()); - BOOST_CHECK_EQUAL(L"hello", t->term()); + EXPECT_TRUE(i <= t->termBuffer().size()); + EXPECT_EQ(L"hello", t->term()); } } -BOOST_AUTO_TEST_CASE(testGrow) +TEST_F(TokenTest, testGrow) { TokenPtr t = newLucene(); StringStream buf; @@ -80,13 +80,13 @@ BOOST_AUTO_TEST_CASE(testGrow) { String content = buf.str(); t->setTermBuffer(content); - BOOST_CHECK_EQUAL(content.length(), t->termLength()); - BOOST_CHECK_EQUAL(content, t->term()); + EXPECT_EQ(content.length(), t->termLength()); + EXPECT_EQ(content, t->term()); buf << content; } - BOOST_CHECK_EQUAL(1048576, t->termLength()); - BOOST_CHECK_EQUAL(1179654, t->termBuffer().size()); - + EXPECT_EQ(1048576, t->termLength()); + EXPECT_EQ(1179654, t->termBuffer().size()); + // Test for slow growth to a long term t = newLucene(); buf.str(L""); @@ -95,25 +95,25 @@ BOOST_AUTO_TEST_CASE(testGrow) { String content = buf.str(); t->setTermBuffer(content); - BOOST_CHECK_EQUAL(content.length(), t->termLength()); - BOOST_CHECK_EQUAL(content, t->term()); + EXPECT_EQ(content.length(), t->termLength()); + EXPECT_EQ(content, t->term()); buf << L"a"; } - BOOST_CHECK_EQUAL(20000, t->termLength()); - BOOST_CHECK_EQUAL(20167, t->termBuffer().size()); + EXPECT_EQ(20000, t->termLength()); + EXPECT_EQ(20167, t->termBuffer().size()); } -BOOST_AUTO_TEST_CASE(testToString) +TEST_F(TokenTest, testToString) { TokenPtr t = newLucene(L"", 0, 5); t->setTermBuffer(L"aloha"); - BOOST_CHECK_EQUAL(L"(aloha,0,5)", t->toString()); + EXPECT_EQ(L"(aloha,0,5)", t->toString()); t->setTermBuffer(L"hi there"); - BOOST_CHECK_EQUAL(L"(hi there,0,5)", t->toString()); + EXPECT_EQ(L"(hi there,0,5)", t->toString()); } -BOOST_AUTO_TEST_CASE(testTermBufferEquals) +TEST_F(TokenTest, testTermBufferEquals) { TokenPtr t1a = newLucene(); t1a->setTermBuffer(L"hello"); @@ -121,21 +121,21 @@ BOOST_AUTO_TEST_CASE(testTermBufferEquals) t1b->setTermBuffer(L"hello"); TokenPtr t2 = newLucene(); t2->setTermBuffer(L"hello2"); - BOOST_CHECK(t1a->equals(t1b)); - BOOST_CHECK(!t1a->equals(t2)); - BOOST_CHECK(!t2->equals(t1b)); + EXPECT_TRUE(t1a->equals(t1b)); + EXPECT_TRUE(!t1a->equals(t2)); + EXPECT_TRUE(!t2->equals(t1b)); } -BOOST_AUTO_TEST_CASE(testMixedStringArray) +TEST_F(TokenTest, testMixedStringArray) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); - BOOST_CHECK_EQUAL(t->termLength(), 5); - BOOST_CHECK_EQUAL(t->term(), L"hello"); + EXPECT_EQ(t->termLength(), 5); + EXPECT_EQ(t->term(), L"hello"); t->setTermBuffer(L"hello2"); - BOOST_CHECK_EQUAL(t->termLength(), 6); - BOOST_CHECK_EQUAL(t->term(), L"hello2"); - + EXPECT_EQ(t->termLength(), 6); + EXPECT_EQ(t->term(), L"hello2"); + CharArray test = CharArray::newInstance(6); test[0] = L'h'; test[1] = L'e'; @@ -143,23 +143,23 @@ BOOST_AUTO_TEST_CASE(testMixedStringArray) test[3] = L'l'; test[4] = L'o'; test[5] = L'3'; - + t->setTermBuffer(test.get(), 0, 6); - BOOST_CHECK_EQUAL(t->term(), L"hello3"); - + EXPECT_EQ(t->term(), L"hello3"); + CharArray buffer = t->termBuffer(); buffer[1] = L'o'; - BOOST_CHECK_EQUAL(t->term(), L"hollo3"); + EXPECT_EQ(t->term(), L"hollo3"); } -BOOST_AUTO_TEST_CASE(testClone) +TEST_F(TokenTest, testClone) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); CharArray buf = t->termBuffer(); TokenPtr clone = boost::dynamic_pointer_cast(checkCloneIsEqual(t)); - BOOST_CHECK_EQUAL(t->term(), clone->term()); - BOOST_CHECK(buf != clone->termBuffer()); + EXPECT_EQ(t->term(), clone->term()); + EXPECT_TRUE(buf != clone->termBuffer()); ByteArray payload = ByteArray::newInstance(4); payload[0] = 1; @@ -170,24 +170,24 @@ BOOST_AUTO_TEST_CASE(testClone) PayloadPtr pl = newLucene(payload); t->setPayload(pl); clone = boost::dynamic_pointer_cast(checkCloneIsEqual(t)); - BOOST_CHECK(pl->equals(clone->getPayload())); - BOOST_CHECK_NE(pl, clone->getPayload()); + EXPECT_TRUE(pl->equals(clone->getPayload())); + EXPECT_NE(pl, clone->getPayload()); } -BOOST_AUTO_TEST_CASE(testCopyTo) +TEST_F(TokenTest, testCopyTo) { TokenPtr t = newLucene(); TokenPtr copy = boost::dynamic_pointer_cast(checkCopyIsEqual(t)); - BOOST_CHECK_EQUAL(L"", t->term()); - BOOST_CHECK_EQUAL(L"", copy->term()); - + EXPECT_EQ(L"", t->term()); + EXPECT_EQ(L"", copy->term()); + t = newLucene(); t->setTermBuffer(L"hello"); CharArray buf = t->termBuffer(); copy = boost::dynamic_pointer_cast(checkCopyIsEqual(t)); - BOOST_CHECK_EQUAL(t->term(), copy->term()); - BOOST_CHECK(buf != copy->termBuffer()); - + EXPECT_EQ(t->term(), copy->term()); + EXPECT_TRUE(buf != copy->termBuffer()); + ByteArray payload = ByteArray::newInstance(4); payload[0] = 1; payload[1] = 2; @@ -197,8 +197,6 @@ BOOST_AUTO_TEST_CASE(testCopyTo) PayloadPtr pl = newLucene(payload); t->setPayload(pl); copy = boost::dynamic_pointer_cast(checkCloneIsEqual(t)); - BOOST_CHECK(pl->equals(copy->getPayload())); - BOOST_CHECK_NE(pl, copy->getPayload()); + EXPECT_TRUE(pl->equals(copy->getPayload())); + EXPECT_NE(pl, copy->getPayload()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/standard/StandardAnalyzerTest.cpp b/src/test/analysis/standard/StandardAnalyzerTest.cpp index b4cca784..ea1c7056 100644 --- a/src/test/analysis/standard/StandardAnalyzerTest.cpp +++ b/src/test/analysis/standard/StandardAnalyzerTest.cpp @@ -10,25 +10,25 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(StandardAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture StandardAnalyzerTest; -BOOST_AUTO_TEST_CASE(testMaxTermLength) +TEST_F(StandardAnalyzerTest, testMaxTermLength) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); sa->setMaxTokenLength(5); checkAnalyzesTo(sa, L"ab cd toolong xy z", newCollection(L"ab", L"cd", L"xy", L"z")); } -BOOST_AUTO_TEST_CASE(testMaxTermLength2) +TEST_F(StandardAnalyzerTest, testMaxTermLength2) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); - + checkAnalyzesTo(sa, L"ab cd toolong xy z", newCollection(L"ab", L"cd", L"toolong", L"xy", L"z")); sa->setMaxTokenLength(5); checkAnalyzesTo(sa, L"ab cd toolong xy z", newCollection(L"ab", L"cd", L"xy", L"z"), newCollection(1, 1, 2, 1)); } -BOOST_AUTO_TEST_CASE(testMaxTermLength3) +TEST_F(StandardAnalyzerTest, testMaxTermLength3) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); String longTerm(255, L'a'); @@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE(testMaxTermLength3) checkAnalyzesTo(sa, L"ab cd " + longTerm + L"a xy z", newCollection(L"ab", L"cd", L"xy", L"z")); } -BOOST_AUTO_TEST_CASE(testAlphanumeric) +TEST_F(StandardAnalyzerTest, testAlphanumeric) { // alphanumeric tokens StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(testAlphanumeric) checkAnalyzesTo(sa, L"2B", newCollection(L"2b")); } -BOOST_AUTO_TEST_CASE(testUnderscores) +TEST_F(StandardAnalyzerTest, testUnderscores) { // underscores are delimiters, but not in email addresses (below) StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(testUnderscores) checkAnalyzesTo(sa, L"word_with_underscore_and_stopwords", newCollection(L"word", L"underscore", L"stopwords")); } -BOOST_AUTO_TEST_CASE(testDelimiters) +TEST_F(StandardAnalyzerTest, testDelimiters) { // other delimiters: "-", "/", "," StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -61,11 +61,11 @@ BOOST_AUTO_TEST_CASE(testDelimiters) checkAnalyzesTo(sa, L"ac/dc", newCollection(L"ac", L"dc")); } -BOOST_AUTO_TEST_CASE(testApostrophes) +TEST_F(StandardAnalyzerTest, testApostrophes) { // internal apostrophes: O'Reilly, you're, O'Reilly's possessives are actually removed by StardardFilter, not the tokenizer StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); - + checkAnalyzesTo(sa, L"O'Reilly", newCollection(L"o'reilly")); checkAnalyzesTo(sa, L"you're", newCollection(L"you're")); checkAnalyzesTo(sa, L"she's", newCollection(L"she")); @@ -74,18 +74,18 @@ BOOST_AUTO_TEST_CASE(testApostrophes) checkAnalyzesTo(sa, L"O'Reilly's", newCollection(L"o'reilly")); } -BOOST_AUTO_TEST_CASE(testTSADash) +TEST_F(StandardAnalyzerTest, testTSADash) { // t and s had been stopwords in Lucene <= 2.0, which made it impossible to correctly search for these terms StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"s-class", newCollection(L"s", L"class")); checkAnalyzesTo(sa, L"t-com", newCollection(L"t", L"com")); - + // 'a' is still a stopword checkAnalyzesTo(sa, L"a-class", newCollection(L"class")); } -BOOST_AUTO_TEST_CASE(testCompanyNames) +TEST_F(StandardAnalyzerTest, testCompanyNames) { // internal apostrophes: O'Reilly, you're, O'Reilly's possessives are actually removed by StardardFilter, not the tokenizer StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -93,26 +93,26 @@ BOOST_AUTO_TEST_CASE(testCompanyNames) checkAnalyzesTo(sa, L"Excite@Home", newCollection(L"excite@home")); } -BOOST_AUTO_TEST_CASE(testDomainNames) +TEST_F(StandardAnalyzerTest, testDomainNames) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); - + // domain names checkAnalyzesTo(sa, L"www.nutch.org", newCollection(L"www.nutch.org")); - + // the following should be recognized as HOST - BOOST_CHECK_NO_THROW(checkAnalyzesTo(sa, L"www.nutch.org.", newCollection(L"www.nutch.org"), newCollection(L""))); - + EXPECT_NO_THROW(checkAnalyzesTo(sa, L"www.nutch.org.", newCollection(L"www.nutch.org"), newCollection(L""))); + // 2.3 should show the bug sa = newLucene(LuceneVersion::LUCENE_23); - BOOST_CHECK_NO_THROW(checkAnalyzesTo(sa, L"www.nutch.org.", newCollection(L"wwwnutchorg"), newCollection(L""))); - + EXPECT_NO_THROW(checkAnalyzesTo(sa, L"www.nutch.org.", newCollection(L"wwwnutchorg"), newCollection(L""))); + // 2.4 should not show the bug sa = newLucene(LuceneVersion::LUCENE_24); - BOOST_CHECK_NO_THROW(checkAnalyzesTo(sa, L"www.nutch.org.", newCollection(L"www.nutch.org"), newCollection(L""))); + EXPECT_NO_THROW(checkAnalyzesTo(sa, L"www.nutch.org.", newCollection(L"www.nutch.org"), newCollection(L""))); } -BOOST_AUTO_TEST_CASE(testEMailAddresses) +TEST_F(StandardAnalyzerTest, testEMailAddresses) { // email addresses, possibly with underscores, periods, etc StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(testEMailAddresses) checkAnalyzesTo(sa, L"first_lastname@example.com", newCollection(L"first_lastname@example.com")); } -BOOST_AUTO_TEST_CASE(testNumeric) +TEST_F(StandardAnalyzerTest, testNumeric) { // floating point, serial, model numbers, ip addresses, etc. // every other segment must have at least one digit @@ -134,13 +134,13 @@ BOOST_AUTO_TEST_CASE(testNumeric) checkAnalyzesTo(sa, L"R2D2 C3PO", newCollection(L"r2d2", L"c3po")); } -BOOST_AUTO_TEST_CASE(testTextWithNumbers) +TEST_F(StandardAnalyzerTest, testTextWithNumbers) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"David has 5000 bones", newCollection(L"david", L"has", L"5000", L"bones")); } -BOOST_AUTO_TEST_CASE(testVariousText) +TEST_F(StandardAnalyzerTest, testVariousText) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"C embedded developers wanted", newCollection(L"c", L"embedded", L"developers", L"wanted")); @@ -149,64 +149,62 @@ BOOST_AUTO_TEST_CASE(testVariousText) checkAnalyzesTo(sa, L"\"QUOTED\" word", newCollection(L"quoted", L"word")); } -BOOST_AUTO_TEST_CASE(testAcronyms) +TEST_F(StandardAnalyzerTest, testAcronyms) { // acronyms have their dots stripped StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"U.S.A.", newCollection(L"usa")); } -BOOST_AUTO_TEST_CASE(testCPlusPlusHash) +TEST_F(StandardAnalyzerTest, testCPlusPlusHash) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"C++", newCollection(L"c")); checkAnalyzesTo(sa, L"C#", newCollection(L"c")); } -BOOST_AUTO_TEST_CASE(testComplianceFileName) +TEST_F(StandardAnalyzerTest, testComplianceFileName) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"2004.jpg", newCollection(L"2004.jpg"), newCollection(L"")); } -BOOST_AUTO_TEST_CASE(testComplianceNumericIncorrect) +TEST_F(StandardAnalyzerTest, testComplianceNumericIncorrect) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"62.46", newCollection(L"62.46"), newCollection(L"")); } -BOOST_AUTO_TEST_CASE(testComplianceNumericLong) +TEST_F(StandardAnalyzerTest, testComplianceNumericLong) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"978-0-94045043-1", newCollection(L"978-0-94045043-1"), newCollection(L"")); } -BOOST_AUTO_TEST_CASE(testComplianceNumericFile) +TEST_F(StandardAnalyzerTest, testComplianceNumericFile) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"78academyawards/rules/rule02.html", newCollection(L"78academyawards/rules/rule02.html"), newCollection(L"")); } -BOOST_AUTO_TEST_CASE(testComplianceNumericWithUnderscores) +TEST_F(StandardAnalyzerTest, testComplianceNumericWithUnderscores) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"2006-03-11t082958z_01_ban130523_rtridst_0_ozabs", newCollection(L"2006-03-11t082958z_01_ban130523_rtridst_0_ozabs"), newCollection(L"")); } -BOOST_AUTO_TEST_CASE(testComplianceNumericWithDash) +TEST_F(StandardAnalyzerTest, testComplianceNumericWithDash) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"mid-20th", newCollection(L"mid-20th"), newCollection(L"")); } -BOOST_AUTO_TEST_CASE(testComplianceManyTokens) +TEST_F(StandardAnalyzerTest, testComplianceManyTokens) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); - checkAnalyzesTo(sa, L"/money.cnn.com/magazines/fortune/fortune_archive/2007/03/19/8402357/index.htm safari-0-sheikh-zayed-grand-mosque.jpg", - newCollection(L"money.cnn.com", L"magazines", L"fortune", L"fortune", L"archive/2007/03/19/8402357", + checkAnalyzesTo(sa, L"/money.cnn.com/magazines/fortune/fortune_archive/2007/03/19/8402357/index.htm safari-0-sheikh-zayed-grand-mosque.jpg", + newCollection(L"money.cnn.com", L"magazines", L"fortune", L"fortune", L"archive/2007/03/19/8402357", L"index.htm", L"safari-0-sheikh", L"zayed", L"grand", L"mosque.jpg"), newCollection(L"", L"", L"", L"", L"", L"", L"", L"", L"", L"")); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp index 5aa36ee8..054fc34b 100644 --- a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp @@ -16,13 +16,13 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SimpleAttributeTest, LuceneTestFixture) +typedef LuceneTestFixture SimpleAttributeTest; static AttributePtr checkCloneIsEqual(AttributePtr att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); - BOOST_CHECK(att->equals(clone)); - BOOST_CHECK_EQUAL(att->hashCode(), clone->hashCode()); + EXPECT_TRUE(att->equals(clone)); + EXPECT_EQ(att->hashCode(), clone->hashCode()); return clone; } @@ -31,45 +31,45 @@ static AttributePtr checkCopyIsEqual(AttributePtr att) { AttributePtr copy = newLucene(); att->copyTo(copy); - BOOST_CHECK(att->equals(copy)); - BOOST_CHECK_EQUAL(att->hashCode(), copy->hashCode()); + EXPECT_TRUE(att->equals(copy)); + EXPECT_EQ(att->hashCode(), copy->hashCode()); return copy; } -BOOST_AUTO_TEST_CASE(testFlagsAttribute) +TEST_F(SimpleAttributeTest, testFlagsAttribute) { FlagsAttributePtr att = newLucene(); - BOOST_CHECK_EQUAL(0, att->getFlags()); + EXPECT_EQ(0, att->getFlags()); att->setFlags(1234); - BOOST_CHECK_EQUAL(L"flags=1234", att->toString()); + EXPECT_EQ(L"flags=1234", att->toString()); FlagsAttributePtr att2 = boost::dynamic_pointer_cast(checkCloneIsEqual(att)); - BOOST_CHECK_EQUAL(1234, att2->getFlags()); + EXPECT_EQ(1234, att2->getFlags()); att2 = boost::dynamic_pointer_cast(checkCopyIsEqual(att)); - BOOST_CHECK_EQUAL(1234, att2->getFlags()); + EXPECT_EQ(1234, att2->getFlags()); att->clear(); - BOOST_CHECK_EQUAL(0, att->getFlags()); + EXPECT_EQ(0, att->getFlags()); } -BOOST_AUTO_TEST_CASE(testPositionIncrementAttribute) +TEST_F(SimpleAttributeTest, testPositionIncrementAttribute) { PositionIncrementAttributePtr att = newLucene(); - BOOST_CHECK_EQUAL(1, att->getPositionIncrement()); + EXPECT_EQ(1, att->getPositionIncrement()); att->setPositionIncrement(1234); - BOOST_CHECK_EQUAL(L"positionIncrement=1234", att->toString()); + EXPECT_EQ(L"positionIncrement=1234", att->toString()); PositionIncrementAttributePtr att2 = boost::dynamic_pointer_cast(checkCloneIsEqual(att)); - BOOST_CHECK_EQUAL(1234, att2->getPositionIncrement()); + EXPECT_EQ(1234, att2->getPositionIncrement()); att2 = boost::dynamic_pointer_cast(checkCopyIsEqual(att)); - BOOST_CHECK_EQUAL(1234, att2->getPositionIncrement()); + EXPECT_EQ(1234, att2->getPositionIncrement()); att->clear(); - BOOST_CHECK_EQUAL(1, att->getPositionIncrement()); + EXPECT_EQ(1, att->getPositionIncrement()); } namespace TestTypeAttribute @@ -80,78 +80,76 @@ namespace TestTypeAttribute virtual ~TestableTypeAttribute() { } - + LUCENE_CLASS(TestableTypeAttribute); - + public: using TypeAttribute::DEFAULT_TYPE; }; } -BOOST_AUTO_TEST_CASE(testTypeAttribute) +TEST_F(SimpleAttributeTest, testTypeAttribute) { TypeAttributePtr att = newLucene(); - BOOST_CHECK_EQUAL(TestTypeAttribute::TestableTypeAttribute::DEFAULT_TYPE(), att->type()); + EXPECT_EQ(TestTypeAttribute::TestableTypeAttribute::DEFAULT_TYPE(), att->type()); att->setType(L"hello"); - BOOST_CHECK_EQUAL(L"type=hello", att->toString()); + EXPECT_EQ(L"type=hello", att->toString()); TypeAttributePtr att2 = boost::dynamic_pointer_cast(checkCloneIsEqual(att)); - BOOST_CHECK_EQUAL(L"hello", att2->type()); + EXPECT_EQ(L"hello", att2->type()); att2 = boost::dynamic_pointer_cast(checkCopyIsEqual(att)); - BOOST_CHECK_EQUAL(L"hello", att2->type()); + EXPECT_EQ(L"hello", att2->type()); att->clear(); - BOOST_CHECK_EQUAL(TestTypeAttribute::TestableTypeAttribute::DEFAULT_TYPE(), att->type()); + EXPECT_EQ(TestTypeAttribute::TestableTypeAttribute::DEFAULT_TYPE(), att->type()); } -BOOST_AUTO_TEST_CASE(testPayloadAttribute) +TEST_F(SimpleAttributeTest, testPayloadAttribute) { PayloadAttributePtr att = newLucene(); - BOOST_CHECK(!att->getPayload()); + EXPECT_TRUE(!att->getPayload()); ByteArray payload = ByteArray::newInstance(4); payload[0] = 1; payload[1] = 2; payload[2] = 3; payload[3] = 4; - + PayloadPtr pl = newLucene(payload); att->setPayload(pl); PayloadAttributePtr att2 = boost::dynamic_pointer_cast(checkCloneIsEqual(att)); - BOOST_CHECK(pl->equals(att2->getPayload())); - BOOST_CHECK_NE(pl, att2->getPayload()); + EXPECT_TRUE(pl->equals(att2->getPayload())); + EXPECT_NE(pl, att2->getPayload()); att2 = boost::dynamic_pointer_cast(checkCopyIsEqual(att)); - BOOST_CHECK(pl->equals(att2->getPayload())); - BOOST_CHECK_NE(pl, att2->getPayload()); + EXPECT_TRUE(pl->equals(att2->getPayload())); + EXPECT_NE(pl, att2->getPayload()); att->clear(); - BOOST_CHECK(!att->getPayload()); + EXPECT_TRUE(!att->getPayload()); } -BOOST_AUTO_TEST_CASE(testOffsetAttribute) +TEST_F(SimpleAttributeTest, testOffsetAttribute) { OffsetAttributePtr att = newLucene(); - BOOST_CHECK_EQUAL(0, att->startOffset()); - BOOST_CHECK_EQUAL(0, att->endOffset()); + EXPECT_EQ(0, att->startOffset()); + EXPECT_EQ(0, att->endOffset()); att->setOffset(12, 34); // no string test here, because order unknown - + OffsetAttributePtr att2 = boost::dynamic_pointer_cast(checkCloneIsEqual(att)); - BOOST_CHECK_EQUAL(12, att2->startOffset()); - BOOST_CHECK_EQUAL(34, att2->endOffset()); + EXPECT_EQ(12, att2->startOffset()); + EXPECT_EQ(34, att2->endOffset()); att2 = boost::dynamic_pointer_cast(checkCopyIsEqual(att)); - BOOST_CHECK_EQUAL(12, att2->startOffset()); - BOOST_CHECK_EQUAL(34, att2->endOffset()); + EXPECT_EQ(12, att2->startOffset()); + EXPECT_EQ(34, att2->endOffset()); att->clear(); - BOOST_CHECK_EQUAL(0, att->startOffset()); - BOOST_CHECK_EQUAL(0, att->endOffset()); + EXPECT_EQ(0, att->startOffset()); + EXPECT_EQ(0, att->endOffset()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/analysis/tokenattributes/TermAttributeTest.cpp b/src/test/analysis/tokenattributes/TermAttributeTest.cpp index 9e70bcec..367a7693 100644 --- a/src/test/analysis/tokenattributes/TermAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/TermAttributeTest.cpp @@ -11,13 +11,13 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(TermAttributeTest, LuceneTestFixture) +typedef LuceneTestFixture TermAttributeTest; static AttributePtr checkCloneIsEqual(AttributePtr att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); - BOOST_CHECK(att->equals(clone)); - BOOST_CHECK_EQUAL(att->hashCode(), clone->hashCode()); + EXPECT_TRUE(att->equals(clone)); + EXPECT_EQ(att->hashCode(), clone->hashCode()); return clone; } @@ -26,24 +26,24 @@ static AttributePtr checkCopyIsEqual(AttributePtr att) { AttributePtr copy = newLucene(); att->copyTo(copy); - BOOST_CHECK(att->equals(copy)); - BOOST_CHECK_EQUAL(att->hashCode(), copy->hashCode()); + EXPECT_TRUE(att->equals(copy)); + EXPECT_EQ(att->hashCode(), copy->hashCode()); return copy; } -BOOST_AUTO_TEST_CASE(testResize) +TEST_F(TermAttributeTest, testResize) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"hello"); for (int32_t i = 0; i < 2000; ++i) { t->resizeTermBuffer(i); - BOOST_CHECK(i <= t->termBuffer().size()); - BOOST_CHECK_EQUAL(L"hello", t->term()); + EXPECT_TRUE(i <= t->termBuffer().size()); + EXPECT_EQ(L"hello", t->term()); } } -BOOST_AUTO_TEST_CASE(testGrow) +TEST_F(TermAttributeTest, testGrow) { TermAttributePtr t = newLucene(); StringStream buf; @@ -52,13 +52,13 @@ BOOST_AUTO_TEST_CASE(testGrow) { String content = buf.str(); t->setTermBuffer(content); - BOOST_CHECK_EQUAL(content.length(), t->termLength()); - BOOST_CHECK_EQUAL(content, t->term()); + EXPECT_EQ(content.length(), t->termLength()); + EXPECT_EQ(content, t->term()); buf << content; } - BOOST_CHECK_EQUAL(1048576, t->termLength()); - BOOST_CHECK_EQUAL(1179654, t->termBuffer().size()); - + EXPECT_EQ(1048576, t->termLength()); + EXPECT_EQ(1179654, t->termBuffer().size()); + // Test for slow growth to a long term t = newLucene(); buf.str(L""); @@ -67,34 +67,34 @@ BOOST_AUTO_TEST_CASE(testGrow) { String content = buf.str(); t->setTermBuffer(content); - BOOST_CHECK_EQUAL(content.length(), t->termLength()); - BOOST_CHECK_EQUAL(content, t->term()); + EXPECT_EQ(content.length(), t->termLength()); + EXPECT_EQ(content, t->term()); buf << L"a"; } - BOOST_CHECK_EQUAL(20000, t->termLength()); - BOOST_CHECK_EQUAL(20167, t->termBuffer().size()); + EXPECT_EQ(20000, t->termLength()); + EXPECT_EQ(20167, t->termBuffer().size()); } -BOOST_AUTO_TEST_CASE(testToString) +TEST_F(TermAttributeTest, testToString) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"aloha"); - BOOST_CHECK_EQUAL(L"term=aloha", t->toString()); + EXPECT_EQ(L"term=aloha", t->toString()); t->setTermBuffer(L"hi there"); - BOOST_CHECK_EQUAL(L"term=hi there", t->toString()); + EXPECT_EQ(L"term=hi there", t->toString()); } -BOOST_AUTO_TEST_CASE(testMixedStringArray) +TEST_F(TermAttributeTest, testMixedStringArray) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"hello"); - BOOST_CHECK_EQUAL(t->termLength(), 5); - BOOST_CHECK_EQUAL(t->term(), L"hello"); + EXPECT_EQ(t->termLength(), 5); + EXPECT_EQ(t->term(), L"hello"); t->setTermBuffer(L"hello2"); - BOOST_CHECK_EQUAL(t->termLength(), 6); - BOOST_CHECK_EQUAL(t->term(), L"hello2"); - + EXPECT_EQ(t->termLength(), 6); + EXPECT_EQ(t->term(), L"hello2"); + CharArray test = CharArray::newInstance(6); test[0] = L'h'; test[1] = L'e'; @@ -102,27 +102,27 @@ BOOST_AUTO_TEST_CASE(testMixedStringArray) test[3] = L'l'; test[4] = L'o'; test[5] = L'3'; - + t->setTermBuffer(test.get(), 0, 6); - BOOST_CHECK_EQUAL(t->term(), L"hello3"); + EXPECT_EQ(t->term(), L"hello3"); // Make sure if we get the buffer and change a character that term() reflects the change CharArray buffer = t->termBuffer(); buffer[1] = L'o'; - BOOST_CHECK_EQUAL(t->term(), L"hollo3"); + EXPECT_EQ(t->term(), L"hollo3"); } -BOOST_AUTO_TEST_CASE(testClone) +TEST_F(TermAttributeTest, testClone) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"hello"); CharArray buf = t->termBuffer(); TermAttributePtr clone = boost::dynamic_pointer_cast(checkCloneIsEqual(t)); - BOOST_CHECK_EQUAL(t->term(), clone->term()); - BOOST_CHECK(buf != clone->termBuffer()); + EXPECT_EQ(t->term(), clone->term()); + EXPECT_TRUE(buf != clone->termBuffer()); } -BOOST_AUTO_TEST_CASE(testEquals) +TEST_F(TermAttributeTest, testEquals) { TermAttributePtr t1a = newLucene(); t1a->setTermBuffer(L"hello"); @@ -130,24 +130,22 @@ BOOST_AUTO_TEST_CASE(testEquals) t1b->setTermBuffer(L"hello"); TermAttributePtr t2 = newLucene(); t2->setTermBuffer(L"hello2"); - BOOST_CHECK(t1a->equals(t1b)); - BOOST_CHECK(!t1a->equals(t2)); - BOOST_CHECK(!t2->equals(t1b)); + EXPECT_TRUE(t1a->equals(t1b)); + EXPECT_TRUE(!t1a->equals(t2)); + EXPECT_TRUE(!t2->equals(t1b)); } -BOOST_AUTO_TEST_CASE(testCopyTo) +TEST_F(TermAttributeTest, testCopyTo) { TermAttributePtr t = newLucene(); TermAttributePtr copy = boost::dynamic_pointer_cast(checkCopyIsEqual(t)); - BOOST_CHECK_EQUAL(L"", t->term()); - BOOST_CHECK_EQUAL(L"", copy->term()); - + EXPECT_EQ(L"", t->term()); + EXPECT_EQ(L"", copy->term()); + t = newLucene(); t->setTermBuffer(L"hello"); CharArray buf = t->termBuffer(); copy = boost::dynamic_pointer_cast(checkCopyIsEqual(t)); - BOOST_CHECK_EQUAL(t->term(), copy->term()); - BOOST_CHECK(buf != copy->termBuffer()); + EXPECT_EQ(t->term(), copy->term()); + EXPECT_TRUE(buf != copy->termBuffer()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp index f5613b04..b1b56277 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp @@ -10,11 +10,11 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(ArabicAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture ArabicAnalyzerTest; /// Some simple tests showing some features of the analyzer, how some regular forms will conflate -BOOST_AUTO_TEST_CASE(testBasicFeatures1) +TEST_F(ArabicAnalyzerTest, testBasicFeatures1) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; @@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures1) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures2) +TEST_F(ArabicAnalyzerTest, testBasicFeatures2) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa9}; @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures2) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures3) +TEST_F(ArabicAnalyzerTest, testBasicFeatures3) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8}; @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures3) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures4) +TEST_F(ArabicAnalyzerTest, testBasicFeatures4) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xaa}; @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures4) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures5) +TEST_F(ArabicAnalyzerTest, testBasicFeatures5) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa3, 0xd9, 0x85, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a, 0xd9, 0x8a, 0xd9, 0x86}; @@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures5) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures6) +TEST_F(ArabicAnalyzerTest, testBasicFeatures6) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a}; @@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures6) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures7) +TEST_F(ArabicAnalyzerTest, testBasicFeatures7) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8}; @@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures7) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures8) +TEST_F(ArabicAnalyzerTest, testBasicFeatures8) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8}; @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures8) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures9) +TEST_F(ArabicAnalyzerTest, testBasicFeatures9) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd8, 0xa7, 0x20, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0x20, 0xd8, 0xa3, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x85}; @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures9) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second), UTF8_TO_STRING(third))); } -BOOST_AUTO_TEST_CASE(testBasicFeatures10) +TEST_F(ArabicAnalyzerTest, testBasicFeatures10) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd9, 0x86, 0x20, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0x20, 0xd8, 0xa3, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x85}; @@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(testBasicFeatures10) } /// Simple tests to show things are getting reset correctly, etc. -BOOST_AUTO_TEST_CASE(testReusableTokenStream1) +TEST_F(ArabicAnalyzerTest, testReusableTokenStream1) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; @@ -105,7 +105,7 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream1) checkAnalyzesToReuse(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream2) +TEST_F(ArabicAnalyzerTest, testReusableTokenStream2) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa9}; @@ -114,17 +114,15 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream2) } /// Non-arabic text gets treated in a similar way as SimpleAnalyzer. -BOOST_AUTO_TEST_CASE(testEnglishInput) +TEST_F(ArabicAnalyzerTest, testEnglishInput) { checkAnalyzesTo(newLucene(LuceneVersion::LUCENE_CURRENT), L"English text.", newCollection(L"english", L"text")); } /// Test that custom stopwords work, and are not case-sensitive. -BOOST_AUTO_TEST_CASE(testCustomStopwords) +TEST_F(ArabicAnalyzerTest, testCustomStopwords) { Collection stopWords = newCollection(L"the", L"and", L"a"); ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance(stopWords.begin(), stopWords.end())); checkAnalyzesTo(a, L"The quick brown fox.", newCollection(L"quick", L"brown", L"fox")); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp index 7fa9f5a5..6ed837e0 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp @@ -12,10 +12,10 @@ using namespace Lucene; -class ArabicNormalizationFilterFixture : public BaseTokenStreamFixture +class ArabicNormalizationFilterTest : public BaseTokenStreamFixture { public: - virtual ~ArabicNormalizationFilterFixture() + virtual ~ArabicNormalizationFilterTest() { } @@ -28,104 +28,100 @@ class ArabicNormalizationFilterFixture : public BaseTokenStreamFixture } }; -BOOST_FIXTURE_TEST_SUITE(ArabicNormalizationFilterTest, ArabicNormalizationFilterFixture) - -BOOST_AUTO_TEST_CASE(testAlifMadda) +TEST_F(ArabicNormalizationFilterTest, testAlifMadda) { const uint8_t first[] = {0xd8, 0xa2, 0xd8, 0xac, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xac, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testAlifHamzaAbove) +TEST_F(ArabicNormalizationFilterTest, testAlifHamzaAbove) { const uint8_t first[] = {0xd8, 0xa3, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testAlifHamzaBelow) +TEST_F(ArabicNormalizationFilterTest, testAlifHamzaBelow) { const uint8_t first[] = {0xd8, 0xa5, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xb0}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xb0}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testAlifMaksura) +TEST_F(ArabicNormalizationFilterTest, testAlifMaksura) { const uint8_t first[] = {0xd8, 0xa8, 0xd9, 0x86, 0xd9, 0x89}; const uint8_t second[] = {0xd8, 0xa8, 0xd9, 0x86, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testTehMarbuta) +TEST_F(ArabicNormalizationFilterTest, testTehMarbuta) { const uint8_t first[] = {0xd9, 0x81, 0xd8, 0xa7, 0xd8, 0xb7, 0xd9, 0x85, 0xd8, 0xa9}; const uint8_t second[] = {0xd9, 0x81, 0xd8, 0xa7, 0xd8, 0xb7, 0xd9, 0x85, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testTatweel) +TEST_F(ArabicNormalizationFilterTest, testTatweel) { const uint8_t first[] = {0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, 0x80, 0xd9, 0x80, 0xd9, 0x80, 0xd9, 0x80, 0xd9, 0x80, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xaa}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testFatha) +TEST_F(ArabicNormalizationFilterTest, testFatha) { const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8e, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7}; const uint8_t second[] = {0xd9, 0x85, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testKasra) +TEST_F(ArabicNormalizationFilterTest, testKasra) { const uint8_t first[] = {0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x90, 0xd9, 0x8a}; const uint8_t second[] = {0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testDamma) +TEST_F(ArabicNormalizationFilterTest, testDamma) { const uint8_t first[] = {0xd8, 0xa8, 0xd9, 0x8f, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xaa}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testFathatan) +TEST_F(ArabicNormalizationFilterTest, testFathatan) { const uint8_t first[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x8b}; const uint8_t second[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd8, 0xa7}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testKasratan) +TEST_F(ArabicNormalizationFilterTest, testKasratan) { const uint8_t first[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8d}; const uint8_t second[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testDammatan) +TEST_F(ArabicNormalizationFilterTest, testDammatan) { const uint8_t first[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8c}; const uint8_t second[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testSukun) +TEST_F(ArabicNormalizationFilterTest, testSukun) { const uint8_t first[] = {0xd9, 0x86, 0xd9, 0x84, 0xd9, 0x92, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x86}; const uint8_t second[] = {0xd9, 0x86, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testShaddah) +TEST_F(ArabicNormalizationFilterTest, testShaddah) { const uint8_t first[] = {0xd9, 0x87, 0xd8, 0xaa, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x91}; const uint8_t second[] = {0xd9, 0x87, 0xd8, 0xaa, 0xd9, 0x85, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp index 7ee61d66..8236af93 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp @@ -12,10 +12,10 @@ using namespace Lucene; -class ArabicStemFilterFixture : public BaseTokenStreamFixture +class ArabicStemFilterTest : public BaseTokenStreamFixture { public: - virtual ~ArabicStemFilterFixture() + virtual ~ArabicStemFilterTest() { } @@ -28,151 +28,147 @@ class ArabicStemFilterFixture : public BaseTokenStreamFixture } }; -BOOST_FIXTURE_TEST_SUITE(ArabicStemFilterTest, ArabicStemFilterFixture) - -BOOST_AUTO_TEST_CASE(testAlPrefix) +TEST_F(ArabicStemFilterTest, testAlPrefix) { const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testWalPrefix) +TEST_F(ArabicStemFilterTest, testWalPrefix) { const uint8_t first[] = {0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testBalPrefix) +TEST_F(ArabicStemFilterTest, testBalPrefix) { const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testKalPrefix) +TEST_F(ArabicStemFilterTest, testKalPrefix) { const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testFalPrefix) +TEST_F(ArabicStemFilterTest, testFalPrefix) { const uint8_t first[] = {0xd9, 0x81, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testLlPrefix) +TEST_F(ArabicStemFilterTest, testLlPrefix) { const uint8_t first[] = {0xd9, 0x84, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xb1}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xb1}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testWaPrefix) +TEST_F(ArabicStemFilterTest, testWaPrefix) { const uint8_t first[] = {0xd9, 0x88, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testAhSuffix) +TEST_F(ArabicStemFilterTest, testAhSuffix) { const uint8_t first[] = {0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xac, 0xd9, 0x87, 0xd8, 0xa7}; const uint8_t second[] = {0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xac}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testAnSuffix) +TEST_F(ArabicStemFilterTest, testAnSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testAtSuffix) +TEST_F(ArabicStemFilterTest, testAtSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testWnSuffix) +TEST_F(ArabicStemFilterTest, testWnSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testYnSuffix) +TEST_F(ArabicStemFilterTest, testYnSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testYhSuffix) +TEST_F(ArabicStemFilterTest, testYhSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x87}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testYpSuffix) +TEST_F(ArabicStemFilterTest, testYpSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa9}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testHSuffix) +TEST_F(ArabicStemFilterTest, testHSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x87}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testPSuffix) +TEST_F(ArabicStemFilterTest, testPSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa9}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testYSuffix) +TEST_F(ArabicStemFilterTest, testYSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testComboPrefSuf) +TEST_F(ArabicStemFilterTest, testComboPrefSuf) { const uint8_t first[] = {0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testComboSuf) +TEST_F(ArabicStemFilterTest, testComboSuf) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testShouldntStem) +TEST_F(ArabicStemFilterTest, testShouldntStem) { const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x88}; const uint8_t second[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x88}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testNonArabic) +TEST_F(ArabicStemFilterTest, testNonArabic) { check(L"English", L"English"); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp index 68ad27a7..1f576773 100644 --- a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp @@ -10,10 +10,10 @@ using namespace Lucene; -class BrazilianStemmerFixture : public BaseTokenStreamFixture +class BrazilianStemmerTest : public BaseTokenStreamFixture { public: - virtual ~BrazilianStemmerFixture() + virtual ~BrazilianStemmerTest() { } @@ -22,19 +22,17 @@ class BrazilianStemmerFixture : public BaseTokenStreamFixture { checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - + void checkReuse(AnalyzerPtr a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } }; -BOOST_FIXTURE_TEST_SUITE(BrazilianStemmerTest, BrazilianStemmerFixture) - /// Test the Brazilian Stem Filter, which only modifies the term text. /// It is very similar to the snowball Portuguese algorithm but not exactly the same. -BOOST_AUTO_TEST_CASE(testWithSnowballExamples) +TEST_F(BrazilianStemmerTest, testWithSnowballExamples) { check(L"boa", L"boa"); check(L"boainain", L"boainain"); @@ -134,7 +132,7 @@ BOOST_AUTO_TEST_CASE(testWithSnowballExamples) check(L"quiosque", L"quiosqu"); } -BOOST_AUTO_TEST_CASE(testNormalization) +TEST_F(BrazilianStemmerTest, testNormalization) { check(L"Brasil", L"brasil"); // lowercase by default const uint8_t brasil[] = {0x42, 0x72, 0x61, 0x73, 0xc3, 0xad, 0x6c, 0x69, 0x61}; @@ -147,7 +145,7 @@ BOOST_AUTO_TEST_CASE(testNormalization) check(UTF8_TO_STRING(aaa), L"aaa"); // normally, diacritics are removed } -BOOST_AUTO_TEST_CASE(testReusableTokenStream) +TEST_F(BrazilianStemmerTest, testReusableTokenStream) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"boa", L"boa"); @@ -157,7 +155,7 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream) checkReuse(a, UTF8_TO_STRING(boas), L"boas"); // removes diacritic: different from snowball Portuguese } -BOOST_AUTO_TEST_CASE(testStemExclusionTable) +TEST_F(BrazilianStemmerTest, testStemExclusionTable) { BrazilianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); HashSet exclusions = HashSet::newInstance(); @@ -168,7 +166,7 @@ BOOST_AUTO_TEST_CASE(testStemExclusionTable) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -BOOST_AUTO_TEST_CASE(testExclusionTableReuse) +TEST_F(BrazilianStemmerTest, testExclusionTableReuse) { BrazilianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t quintessencia[] = {0x71, 0x75, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x73, 0xc3, 0xaa, 0x6e, 0x63, 0x69, 0x61}; @@ -178,5 +176,3 @@ BOOST_AUTO_TEST_CASE(testExclusionTableReuse) a->setStemExclusionTable(exclusions); checkReuse(a, UTF8_TO_STRING(quintessencia), UTF8_TO_STRING(quintessencia)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp index fb38a5c2..cd857fd3 100644 --- a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp @@ -11,10 +11,10 @@ using namespace Lucene; -class CJKTokenizerFixture : public BaseTokenStreamFixture +class CJKTokenizerTest : public BaseTokenStreamFixture { public: - virtual ~CJKTokenizerFixture() + virtual ~CJKTokenizerTest() { } @@ -34,7 +34,7 @@ class CJKTokenizerFixture : public BaseTokenStreamFixture int32_t end; String type; }; - + void checkCJKToken(const String& str, Collection out_tokens) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -51,7 +51,7 @@ class CJKTokenizerFixture : public BaseTokenStreamFixture } checkAnalyzesTo(analyzer, str, terms, startOffsets, endOffsets, types, Collection()); } - + void checkCJKTokenReusable(AnalyzerPtr analyzer, const String& str, Collection out_tokens) { Collection terms = Collection::newInstance(out_tokens.size()); @@ -69,14 +69,12 @@ class CJKTokenizerFixture : public BaseTokenStreamFixture } }; -BOOST_FIXTURE_TEST_SUITE(CJKTokenizerTest, CJKTokenizerFixture) - -BOOST_AUTO_TEST_CASE(testJa1) +TEST_F(CJKTokenizerTest, testJa1) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0xe4, 0xba, 0x8c, 0xe4, 0xb8, 0x89, 0xe5, 0x9b, 0x9b, 0xe4, 0xba, 0x94, 0xe5, 0x85, 0xad, 0xe4, 0xb8, 0x83, 0xe5, 0x85, 0xab, 0xe4, 0xb9, 0x9d, 0xe5, 0x8d, 0x81}; - + const uint8_t token1[] = {0xe4, 0xb8, 0x80, 0xe4, 0xba, 0x8c}; const uint8_t token2[] = {0xe4, 0xba, 0x8c, 0xe4, 0xb8, 0x89}; const uint8_t token3[] = {0xe4, 0xb8, 0x89, 0xe5, 0x9b, 0x9b}; @@ -86,13 +84,13 @@ BOOST_AUTO_TEST_CASE(testJa1) const uint8_t token7[] = {0xe4, 0xb8, 0x83, 0xe5, 0x85, 0xab}; const uint8_t token8[] = {0xe5, 0x85, 0xab, 0xe4, 0xb9, 0x9d}; const uint8_t token9[] = {0xe4, 0xb9, 0x9d, 0xe5, 0x8d, 0x81}; - + Collection out_tokens = newCollection( TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token5), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token5), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token6), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token7), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token8), 7, 9, CJKTokenizer::DOUBLE_TOKEN_TYPE), @@ -101,7 +99,7 @@ BOOST_AUTO_TEST_CASE(testJa1) checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -BOOST_AUTO_TEST_CASE(testJa2) +TEST_F(CJKTokenizerTest, testJa2) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0x20, 0xe4, 0xba, 0x8c, 0xe4, 0xb8, 0x89, 0xe5, 0x9b, 0x9b, 0x20, 0xe4, 0xba, 0x94, 0xe5, 0x85, 0xad, 0xe4, 0xb8, @@ -117,10 +115,10 @@ BOOST_AUTO_TEST_CASE(testJa2) const uint8_t token8[] = {0xe5, 0x8d, 0x81}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token2), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token3), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token5), 7, 9, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), @@ -129,22 +127,22 @@ BOOST_AUTO_TEST_CASE(testJa2) checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -BOOST_AUTO_TEST_CASE(testC) +TEST_F(CJKTokenizerTest, testC) { String str = L"abc defgh ijklmn opqrstu vwxy z"; Collection out_tokens = newCollection( - TestToken(L"abc", 0, 3, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"abc", 0, 3, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(L"defgh", 4, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(L"ijklmn", 10, 16, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"opqrstu", 17, 24, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"vwxy", 25, 29, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"opqrstu", 17, 24, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"vwxy", 25, 29, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(L"z", 30, 31, CJKTokenizer::SINGLE_TOKEN_TYPE) ); checkCJKToken(str, out_tokens); } -BOOST_AUTO_TEST_CASE(testMix) +TEST_F(CJKTokenizerTest, testMix) { const uint8_t str[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0x63, 0xe3, 0x81, 0x8b, 0xe3, @@ -158,13 +156,13 @@ BOOST_AUTO_TEST_CASE(testMix) const uint8_t token7[] = {0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f}; const uint8_t token8[] = {0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; const uint8_t token9[] = {0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93}; - + Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), @@ -173,7 +171,7 @@ BOOST_AUTO_TEST_CASE(testMix) checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -BOOST_AUTO_TEST_CASE(testMix2) +TEST_F(CJKTokenizerTest, testMix2) { const uint8_t str[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0xe3, 0x82, 0x93, 0x63, 0xe3, @@ -187,15 +185,15 @@ BOOST_AUTO_TEST_CASE(testMix2) const uint8_t token8[] = {0xe3, 0x81, 0x8b, 0xe3, 0x81, 0x8d}; const uint8_t token9[] = {0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f}; const uint8_t token10[] = {0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; - + Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token8), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token9), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token10), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) @@ -203,7 +201,7 @@ BOOST_AUTO_TEST_CASE(testMix2) checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -BOOST_AUTO_TEST_CASE(testSingleChar) +TEST_F(CJKTokenizerTest, testSingleChar) { const uint8_t str[] = {0xe4, 0xb8, 0x80}; @@ -213,25 +211,25 @@ BOOST_AUTO_TEST_CASE(testSingleChar) checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -/// Full-width text is normalized to half-width -BOOST_AUTO_TEST_CASE(testFullWidth) +/// Full-width text is normalized to half-width +TEST_F(CJKTokenizerTest, testFullWidth) { const uint8_t str[] = {0xef, 0xbc, 0xb4, 0xef, 0xbd, 0x85, 0xef, 0xbd, 0x93, 0xef, 0xbd, 0x94, 0x20, 0xef, 0xbc, 0x91, 0xef, 0xbc, 0x92, 0xef, 0xbc, 0x93, 0xef, 0xbc, 0x94}; Collection out_tokens = newCollection( - TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(L"1234", 5, 9, CJKTokenizer::SINGLE_TOKEN_TYPE) ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -/// Non-english text (not just CJK) is treated the same as CJK: C1C2 C2C3 -BOOST_AUTO_TEST_CASE(testNonIdeographic) +/// Non-english text (not just CJK) is treated the same as CJK: C1C2 C2C3 +TEST_F(CJKTokenizerTest, testNonIdeographic) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0x20, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1}; - + const uint8_t token1[] = {0xe4, 0xb8, 0x80}; const uint8_t token2[] = {0xd8, 0xb1, 0xd9, 0x88}; const uint8_t token3[] = {0xd9, 0x88, 0xd8, 0xa8}; @@ -240,27 +238,27 @@ BOOST_AUTO_TEST_CASE(testNonIdeographic) const uint8_t token6[] = {0xd9, 0x85, 0xd9, 0x88}; const uint8_t token7[] = {0xd9, 0x88, 0xd9, 0x8a}; const uint8_t token8[] = {0xd9, 0x8a, 0xd8, 0xb1}; - + Collection out_tokens = newCollection( TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token5), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token5), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE) ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -/// Non-english text with non-letters (non-spacing marks,etc) is treated as C1C2 C2C3, +/// Non-english text with non-letters (non-spacing marks,etc) is treated as C1C2 C2C3, /// except for words are split around non-letters. -BOOST_AUTO_TEST_CASE(testNonIdeographicNonLetter) +TEST_F(CJKTokenizerTest, testNonIdeographicNonLetter) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0x20, 0xd8, 0xb1, 0xd9, 0x8f, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1}; - + const uint8_t token1[] = {0xe4, 0xb8, 0x80}; const uint8_t token2[] = {0xd8, 0xb1}; const uint8_t token3[] = {0xd9, 0x88, 0xd8, 0xa8}; @@ -269,35 +267,35 @@ BOOST_AUTO_TEST_CASE(testNonIdeographicNonLetter) const uint8_t token6[] = {0xd9, 0x85, 0xd9, 0x88}; const uint8_t token7[] = {0xd9, 0x88, 0xd9, 0x8a}; const uint8_t token8[] = {0xd9, 0x8a, 0xd8, 0xb1}; - + Collection out_tokens = newCollection( TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 2, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token5), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token7), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 2, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token5), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token7), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token8), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -BOOST_AUTO_TEST_CASE(testTokenStream) +TEST_F(CJKTokenizerTest, testTokenStream) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t token1[] = {0xe4, 0xb8, 0x80, 0xe4, 0xb8, 0x81, 0xe4, 0xb8, 0x82}; const uint8_t token2[] = {0xe4, 0xb8, 0x80, 0xe4, 0xb8, 0x81}; const uint8_t token3[] = {0xe4, 0xb8, 0x81, 0xe4, 0xb8, 0x82}; - + checkAnalyzesTo(analyzer, UTF8_TO_STRING(token1), newCollection(UTF8_TO_STRING(token2), UTF8_TO_STRING(token3))); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream) +TEST_F(CJKTokenizerTest, testReusableTokenStream) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t first[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0x63, 0xe3, 0x81, 0x8b, 0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93}; @@ -312,18 +310,18 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream) const uint8_t firstToken9[] = {0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(firstToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(firstToken2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(firstToken3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(firstToken6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(firstToken7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(firstToken8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(firstToken9), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) ); checkCJKTokenReusable(analyzer, UTF8_TO_STRING(first), out_tokens); - + const uint8_t second[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0xe3, 0x82, 0x93, 0x63, 0xe3, 0x81, 0x8b, 0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; @@ -336,15 +334,15 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream) const uint8_t secondToken8[] = {0xe3, 0x81, 0x8b, 0xe3, 0x81, 0x8d}; const uint8_t secondToken9[] = {0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f}; const uint8_t secondToken10[] = {0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; - + Collection out_tokens2 = newCollection( - TestToken(UTF8_TO_STRING(secondToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(secondToken2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(secondToken3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(secondToken8), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(secondToken9), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(secondToken10), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) @@ -352,26 +350,24 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream) checkCJKTokenReusable(analyzer, UTF8_TO_STRING(second), out_tokens2); } -BOOST_AUTO_TEST_CASE(testFinalOffset) +TEST_F(CJKTokenizerTest, testFinalOffset) { const uint8_t token1[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84}; - checkCJKToken(UTF8_TO_STRING(token1), + checkCJKToken(UTF8_TO_STRING(token1), newCollection(TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE))); const uint8_t token2[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0x20, 0x20, 0x20}; - checkCJKToken(UTF8_TO_STRING(token2), + checkCJKToken(UTF8_TO_STRING(token2), newCollection(TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE))); checkCJKToken(L"test", newCollection(TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE))); checkCJKToken(L"test ", newCollection(TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE))); const uint8_t token3[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0x74, 0x65, 0x73, 0x74}; - checkCJKToken(UTF8_TO_STRING(token3), + checkCJKToken(UTF8_TO_STRING(token3), newCollection( TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), TestToken(L"test", 2, 6, CJKTokenizer::SINGLE_TOKEN_TYPE))); const uint8_t token4[] = {0x74, 0x65, 0x73, 0x74, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0x20, 0x20, 0x20, 0x20}; - checkCJKToken(UTF8_TO_STRING(token4), + checkCJKToken(UTF8_TO_STRING(token4), newCollection( TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE), TestToken(UTF8_TO_STRING(token1), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE))); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp index 843abfe0..6c8ea1ad 100644 --- a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp @@ -47,9 +47,9 @@ class JustChineseFilterAnalyzer : public Analyzer } }; -BOOST_FIXTURE_TEST_SUITE(ChineseTokenizerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture ChineseTokenizerTest; -BOOST_AUTO_TEST_CASE(testOtherLetterOffset) +TEST_F(ChineseTokenizerTest, testOtherLetterOffset) { const uint8_t token[] = {0x61, 0xe5, 0xa4, 0xa9, 0x62}; ChineseTokenizerPtr tokenizer = newLucene(newLucene(UTF8_TO_STRING(token))); @@ -59,20 +59,20 @@ BOOST_AUTO_TEST_CASE(testOtherLetterOffset) OffsetAttributePtr offsetAtt = tokenizer->getAttribute(); while (tokenizer->incrementToken()) { - BOOST_CHECK_EQUAL(correctStartOffset, offsetAtt->startOffset()); - BOOST_CHECK_EQUAL(correctEndOffset, offsetAtt->endOffset()); + EXPECT_EQ(correctStartOffset, offsetAtt->startOffset()); + EXPECT_EQ(correctEndOffset, offsetAtt->endOffset()); ++correctStartOffset; ++correctEndOffset; } } -BOOST_AUTO_TEST_CASE(testReusableTokenStream1) +TEST_F(ChineseTokenizerTest, testReusableTokenStream1) { AnalyzerPtr a = newLucene(); - + const uint8_t input[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd}; - + const uint8_t token1[] = {0xe4, 0xb8, 0xad}; const uint8_t token2[] = {0xe5, 0x8d, 0x8e}; const uint8_t token3[] = {0xe4, 0xba, 0xba}; @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream1) const uint8_t token5[] = {0xe5, 0x85, 0xb1}; const uint8_t token6[] = {0xe5, 0x92, 0x8c}; const uint8_t token7[] = {0xe5, 0x9b, 0xbd}; - + checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( UTF8_TO_STRING(token1), @@ -95,16 +95,16 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream1) newCollection(1, 2, 3, 4, 5, 6, 7)); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream2) +TEST_F(ChineseTokenizerTest, testReusableTokenStream2) { AnalyzerPtr a = newLucene(); - + const uint8_t input[] = {0xe5, 0x8c, 0x97, 0xe4, 0xba, 0xac, 0xe5, 0xb8, 0x82}; const uint8_t token1[] = {0xe5, 0x8c, 0x97}; const uint8_t token2[] = {0xe4, 0xba, 0xac}; const uint8_t token3[] = {0xe5, 0xb8, 0x82}; - + checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( UTF8_TO_STRING(token1), @@ -116,13 +116,13 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream2) } /// ChineseTokenizer tokenizes numbers as one token, but they are filtered by ChineseFilter -BOOST_AUTO_TEST_CASE(testNumerics) +TEST_F(ChineseTokenizerTest, testNumerics) { AnalyzerPtr justTokenizer = newLucene(); - + const uint8_t input[] = {0xe4, 0xb8, 0xad, 0x31, 0x32, 0x33, 0x34}; const uint8_t token1[] = {0xe4, 0xb8, 0xad}; - + checkAnalyzesTo(justTokenizer, UTF8_TO_STRING(input), newCollection(UTF8_TO_STRING(token1), L"1234")); // in this case the ChineseAnalyzer (which applies ChineseFilter) will remove the numeric token. @@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(testNumerics) /// /// ChineseFilter has an english stopword list, it also removes any single character tokens. /// The stopword list is case-sensitive. -BOOST_AUTO_TEST_CASE(testEnglish) +TEST_F(ChineseTokenizerTest, testEnglish) { AnalyzerPtr chinese = newLucene(); checkAnalyzesTo(chinese, L"This is a Test. b c d", newCollection(L"test")); @@ -146,5 +146,3 @@ BOOST_AUTO_TEST_CASE(testEnglish) AnalyzerPtr justFilter = newLucene(); checkAnalyzesTo(justFilter, L"This is a Test. b c d", newCollection(L"This", L"Test.")); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp index 81eebebe..b20abbe5 100644 --- a/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp @@ -10,21 +10,21 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CzechAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture CzechAnalyzerTest; -BOOST_AUTO_TEST_CASE(testStopWord) +TEST_F(CzechAnalyzerTest, testStopWord) { CzechAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(analyzer, L"Pokud mluvime o volnem", newCollection(L"mluvime", L"volnem")); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream1) +TEST_F(CzechAnalyzerTest, testReusableTokenStream1) { CzechAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesToReuse(analyzer, L"Pokud mluvime o volnem", newCollection(L"mluvime", L"volnem")); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream2) +TEST_F(CzechAnalyzerTest, testReusableTokenStream2) { CzechAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t input[] = {0xc4, 0x8c, 0x65, 0x73, 0x6b, 0xc3, 0xa1, 0x20, 0x52, @@ -33,5 +33,3 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream2) const uint8_t token2[] = {0x72, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b, 0x61}; checkAnalyzesToReuse(analyzer, UTF8_TO_STRING(input), newCollection(UTF8_TO_STRING(token1), UTF8_TO_STRING(token2))); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp index 9edb223f..25630270 100644 --- a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp @@ -11,10 +11,10 @@ using namespace Lucene; -class GermanStemFilterFixture : public BaseTokenStreamFixture +class GermanStemFilterTest : public BaseTokenStreamFixture { public: - virtual ~GermanStemFilterFixture() + virtual ~GermanStemFilterTest() { } @@ -23,56 +23,54 @@ class GermanStemFilterFixture : public BaseTokenStreamFixture { checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - + void checkReuse(AnalyzerPtr a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } }; -BOOST_FIXTURE_TEST_SUITE(GermanStemFilterTest, GermanStemFilterFixture) - -/// Test the German stemmer. The stemming algorithm is known to work less than perfect, as it doesn't +/// Test the German stemmer. The stemming algorithm is known to work less than perfect, as it doesn't /// use any word lists with exceptions. We also check some of the cases where the algorithm is wrong. -BOOST_AUTO_TEST_CASE(testStemming) +TEST_F(GermanStemFilterTest, testStemming) { const uint8_t haufig[] = {0x68, 0xc3, 0xa4, 0x75, 0x66, 0x69, 0x67}; check(UTF8_TO_STRING(haufig), L"haufig"); // German special characters are replaced - + const uint8_t abschliess1[] = {0x61, 0x62, 0x73, 0x63, 0x68, 0x6c, 0x69, 0x65, 0xc3, 0x9f, 0x65, 0x6e}; check(UTF8_TO_STRING(abschliess1), L"abschliess"); // here the stemmer works okay, it maps related words to the same stem - + const uint8_t abschliess2[] = {0x61, 0x62, 0x73, 0x63, 0x68, 0x6c, 0x69, 0x65, 0xc3, 0x9f, 0x65, 0x6e, 0x64, 0x65, 0x72}; check(UTF8_TO_STRING(abschliess2), L"abschliess"); // here the stemmer works okay, it maps related words to the same stem - + const uint8_t abschliess3[] = {0x61, 0x62, 0x73, 0x63, 0x68, 0x6c, 0x69, 0x65, 0xc3, 0x9f, 0x65, 0x6e, 0x64, 0x65, 0x73}; check(UTF8_TO_STRING(abschliess3), L"abschliess"); // here the stemmer works okay, it maps related words to the same stem - + const uint8_t abschliess4[] = {0x61, 0x62, 0x73, 0x63, 0x68, 0x6c, 0x69, 0x65, 0xc3, 0x9f, 0x65, 0x6e, 0x64, 0x65, 0x6e}; check(UTF8_TO_STRING(abschliess4), L"abschliess"); // here the stemmer works okay, it maps related words to the same stem - + check(L"Tisch", L"tisch"); check(L"Tische", L"tisch"); check(L"Tischen", L"tisch"); - + check(L"Haus", L"hau"); check(L"Hauses", L"hau"); - + const uint8_t hau1[] = {0x48, 0xc3, 0xa4, 0x75, 0x73, 0x65, 0x72}; check(UTF8_TO_STRING(hau1), L"hau"); - + const uint8_t hau2[] = {0x48, 0xc3, 0xa4, 0x75, 0x73, 0x65, 0x72, 0x6e}; check(UTF8_TO_STRING(hau2), L"hau"); // Here's a case where overstemming occurs, ie. a word is mapped to the same stem as unrelated words check(L"hauen", L"hau"); - - // Here's a case where understemming occurs, i.e. two related words are not mapped to the same stem. + + // Here's a case where understemming occurs, i.e. two related words are not mapped to the same stem. // This is the case with basically all irregular forms check(L"Drama", L"drama"); check(L"Dramen", L"dram"); - + const uint8_t ausmass[] = {0x41, 0x75, 0x73, 0x6d, 0x61, 0xc3, 0x9f}; check(UTF8_TO_STRING(ausmass), L"ausmass"); @@ -84,22 +82,22 @@ BOOST_AUTO_TEST_CASE(testStemming) check(L"xxxxxem", L"xxxxx"); check(L"xxxxxet", L"xxxxx"); check(L"xxxxxnd", L"xxxxx"); - + // The suffixes are also removed when combined check(L"xxxxxetende", L"xxxxx"); - + // Words that are shorter than four charcters are not changed check(L"xxe", L"xxe"); - + // -em and -er are not removed from words shorter than five characters check(L"xxem", L"xxem"); check(L"xxer", L"xxer"); - + // -nd is not removed from words shorter than six characters check(L"xxxnd", L"xxxnd"); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream) +TEST_F(GermanStemFilterTest, testReusableTokenStream) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"Tisch", L"tisch"); @@ -108,7 +106,7 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -BOOST_AUTO_TEST_CASE(testExclusionTableReuse) +TEST_F(GermanStemFilterTest, testExclusionTableReuse) { GermanAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"tischen", L"tisch"); @@ -117,5 +115,3 @@ BOOST_AUTO_TEST_CASE(testExclusionTableReuse) a->setStemExclusionTable(exclusions); checkReuse(a, L"tischen", L"tischen"); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp index 054c07ec..2df38994 100644 --- a/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp @@ -10,204 +10,202 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(GreekAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture GreekAnalyzerTest; -BOOST_AUTO_TEST_CASE(testAnalyzer1) +TEST_F(GreekAnalyzerTest, testAnalyzer1) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { - 0xce, 0x9c, 0xce, 0xaf, 0xce, 0xb1, 0x20, 0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, - 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x20, 0xce, 0xba, 0xce, 0xb1, - 0xce, 0xbb, 0xce, 0xae, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xcf, 0x80, 0xce, 0xbb, - 0xce, 0xbf, 0xcf, 0x8d, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1, 0x20, 0xcf, 0x83, 0xce, 0xb5, 0xce, - 0xb9, 0xcf, 0x81, 0xce, 0xac, 0x20, 0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, - 0xcf, 0x84, 0xce, 0xae, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd, 0x20, 0xcf, 0x84, 0xce, 0xb7, 0xcf, - 0x82, 0x20, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, - 0xce, 0xae, 0xcf, 0x82, 0x20, 0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x8e, 0xcf, 0x83, 0xcf, 0x83, 0xce, + 0xce, 0x9c, 0xce, 0xaf, 0xce, 0xb1, 0x20, 0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, + 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x20, 0xce, 0xba, 0xce, 0xb1, + 0xce, 0xbb, 0xce, 0xae, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xcf, 0x80, 0xce, 0xbb, + 0xce, 0xbf, 0xcf, 0x8d, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1, 0x20, 0xcf, 0x83, 0xce, 0xb5, 0xce, + 0xb9, 0xcf, 0x81, 0xce, 0xac, 0x20, 0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, + 0xcf, 0x84, 0xce, 0xae, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd, 0x20, 0xcf, 0x84, 0xce, 0xb7, 0xcf, + 0x82, 0x20, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, + 0xce, 0xae, 0xcf, 0x82, 0x20, 0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x8e, 0xcf, 0x83, 0xcf, 0x83, 0xce, 0xb1, 0xcf, 0x82 }; - + const uint8_t token1[] = {0xce, 0xbc, 0xce, 0xb9, 0xce, 0xb1}; - const uint8_t token2[] = {0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, + const uint8_t token2[] = {0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb1}; const uint8_t token3[] = {0xce, 0xba, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xb7}; const uint8_t token4[] = {0xcf, 0x80, 0xce, 0xbb, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1}; const uint8_t token5[] = {0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb1}; - const uint8_t token6[] = {0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, 0xcf, 0x84, + const uint8_t token6[] = {0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, 0xcf, 0x84, 0xce, 0xb7, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd}; - const uint8_t token7[] = {0xce, 0xb5, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, + const uint8_t token7[] = {0xce, 0xb5, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb7, 0xcf, 0x83}; const uint8_t token8[] = {0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x89, 0xcf, 0x83, 0xcf, 0x83, 0xce, 0xb1, 0xcf, 0x83}; - + // Verify the correct analysis of capitals and small accented letters checkAnalyzesTo(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3), - UTF8_TO_STRING(token4), - UTF8_TO_STRING(token5), - UTF8_TO_STRING(token6), - UTF8_TO_STRING(token7), + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3), + UTF8_TO_STRING(token4), + UTF8_TO_STRING(token5), + UTF8_TO_STRING(token6), + UTF8_TO_STRING(token7), UTF8_TO_STRING(token8) - )); + )); } -BOOST_AUTO_TEST_CASE(testAnalyzer2) +TEST_F(GreekAnalyzerTest, testAnalyzer2) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { - 0xce, 0xa0, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x8a, 0xcf, 0x8c, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1, - 0x20, 0x28, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0xcf, - 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xad, 0xcf, - 0x82, 0x5d, 0x09, 0x2d, 0x09, 0xce, 0x91, 0xce, 0x9d, 0xce, 0x91, 0xce, 0x93, 0xce, 0x9a, 0xce, + 0xce, 0xa0, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x8a, 0xcf, 0x8c, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1, + 0x20, 0x28, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0xcf, + 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xad, 0xcf, + 0x82, 0x5d, 0x09, 0x2d, 0x09, 0xce, 0x91, 0xce, 0x9d, 0xce, 0x91, 0xce, 0x93, 0xce, 0x9a, 0xce, 0x95, 0xce, 0xa3 }; - - const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xce, 0xbd, + + const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1}; - const uint8_t token2[] = {0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, + const uint8_t token2[] = {0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xb5, 0xcf, 0x83}; - const uint8_t token3[] = {0xce, 0xb1, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb3, 0xce, 0xba, 0xce, 0xb5, + const uint8_t token3[] = {0xce, 0xb1, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb3, 0xce, 0xba, 0xce, 0xb5, 0xcf, 0x83}; - + // Verify the correct analysis of small letters with diaeresis and the elimination of punctuation marks checkAnalyzesTo(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3) - )); + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3) + )); } -BOOST_AUTO_TEST_CASE(testAnalyzer3) +TEST_F(GreekAnalyzerTest, testAnalyzer3) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { - 0xce, 0xa0, 0xce, 0xa1, 0xce, 0x9f, 0xce, 0xab, 0xce, 0xa0, 0xce, 0x9f, 0xce, 0x98, 0xce, 0x95, - 0xce, 0xa3, 0xce, 0x95, 0xce, 0x99, 0xce, 0xa3, 0x20, 0x20, 0xce, 0x86, 0xcf, 0x88, 0xce, 0xbf, - 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x82, 0x2c, 0x20, 0xce, 0xbf, 0x20, 0xce, 0xbc, 0xce, 0xb5, 0xcf, - 0x83, 0xcf, 0x84, 0xcf, 0x8c, 0xcf, 0x82, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xce, + 0xce, 0xa0, 0xce, 0xa1, 0xce, 0x9f, 0xce, 0xab, 0xce, 0xa0, 0xce, 0x9f, 0xce, 0x98, 0xce, 0x95, + 0xce, 0xa3, 0xce, 0x95, 0xce, 0x99, 0xce, 0xa3, 0x20, 0x20, 0xce, 0x86, 0xcf, 0x88, 0xce, 0xbf, + 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x82, 0x2c, 0x20, 0xce, 0xbf, 0x20, 0xce, 0xbc, 0xce, 0xb5, 0xcf, + 0x83, 0xcf, 0x84, 0xcf, 0x8c, 0xcf, 0x82, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xce, 0xbf, 0xce, 0xb9, 0x20, 0xce, 0xac, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xbf, 0xce, 0xb9 }; - - const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x80, 0xce, 0xbf, + + const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb8, 0xce, 0xb5, 0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83}; const uint8_t token2[] = {0xce, 0xb1, 0xcf, 0x88, 0xce, 0xbf, 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token3[] = {0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token4[] = {0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xbf, 0xce, 0xb9}; - + // Verify the correct analysis of capital accented letters and capital letters with diaeresis, // as well as the elimination of stop words checkAnalyzesTo(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), UTF8_TO_STRING(token3), UTF8_TO_STRING(token4) - )); + )); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream1) +TEST_F(GreekAnalyzerTest, testReusableTokenStream1) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { - 0xce, 0x9c, 0xce, 0xaf, 0xce, 0xb1, 0x20, 0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, - 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x20, 0xce, 0xba, 0xce, 0xb1, - 0xce, 0xbb, 0xce, 0xae, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xcf, 0x80, 0xce, 0xbb, - 0xce, 0xbf, 0xcf, 0x8d, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1, 0x20, 0xcf, 0x83, 0xce, 0xb5, 0xce, - 0xb9, 0xcf, 0x81, 0xce, 0xac, 0x20, 0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, - 0xcf, 0x84, 0xce, 0xae, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd, 0x20, 0xcf, 0x84, 0xce, 0xb7, 0xcf, - 0x82, 0x20, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, - 0xce, 0xae, 0xcf, 0x82, 0x20, 0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x8e, 0xcf, 0x83, 0xcf, 0x83, 0xce, + 0xce, 0x9c, 0xce, 0xaf, 0xce, 0xb1, 0x20, 0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, + 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x20, 0xce, 0xba, 0xce, 0xb1, + 0xce, 0xbb, 0xce, 0xae, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xcf, 0x80, 0xce, 0xbb, + 0xce, 0xbf, 0xcf, 0x8d, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1, 0x20, 0xcf, 0x83, 0xce, 0xb5, 0xce, + 0xb9, 0xcf, 0x81, 0xce, 0xac, 0x20, 0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, + 0xcf, 0x84, 0xce, 0xae, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd, 0x20, 0xcf, 0x84, 0xce, 0xb7, 0xcf, + 0x82, 0x20, 0xce, 0x95, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, + 0xce, 0xae, 0xcf, 0x82, 0x20, 0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x8e, 0xcf, 0x83, 0xcf, 0x83, 0xce, 0xb1, 0xcf, 0x82 }; - + const uint8_t token1[] = {0xce, 0xbc, 0xce, 0xb9, 0xce, 0xb1}; - const uint8_t token2[] = {0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, + const uint8_t token2[] = {0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb1}; const uint8_t token3[] = {0xce, 0xba, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xb7}; const uint8_t token4[] = {0xcf, 0x80, 0xce, 0xbb, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1}; const uint8_t token5[] = {0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb1}; - const uint8_t token6[] = {0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, 0xcf, 0x84, + const uint8_t token6[] = {0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, 0xcf, 0x84, 0xce, 0xb7, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd}; - const uint8_t token7[] = {0xce, 0xb5, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, + const uint8_t token7[] = {0xce, 0xb5, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb7, 0xcf, 0x83}; const uint8_t token8[] = {0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x89, 0xcf, 0x83, 0xcf, 0x83, 0xce, 0xb1, 0xcf, 0x83}; - + // Verify the correct analysis of capitals and small accented letters checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3), - UTF8_TO_STRING(token4), - UTF8_TO_STRING(token5), - UTF8_TO_STRING(token6), - UTF8_TO_STRING(token7), + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3), + UTF8_TO_STRING(token4), + UTF8_TO_STRING(token5), + UTF8_TO_STRING(token6), + UTF8_TO_STRING(token7), UTF8_TO_STRING(token8) - )); + )); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream2) +TEST_F(GreekAnalyzerTest, testReusableTokenStream2) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { - 0xce, 0xa0, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x8a, 0xcf, 0x8c, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1, - 0x20, 0x28, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0xcf, - 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xad, 0xcf, - 0x82, 0x5d, 0x09, 0x2d, 0x09, 0xce, 0x91, 0xce, 0x9d, 0xce, 0x91, 0xce, 0x93, 0xce, 0x9a, 0xce, + 0xce, 0xa0, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x8a, 0xcf, 0x8c, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1, + 0x20, 0x28, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0xcf, + 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xad, 0xcf, + 0x82, 0x5d, 0x09, 0x2d, 0x09, 0xce, 0x91, 0xce, 0x9d, 0xce, 0x91, 0xce, 0x93, 0xce, 0x9a, 0xce, 0x95, 0xce, 0xa3 }; - - const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xce, 0xbd, + + const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1}; - const uint8_t token2[] = {0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, + const uint8_t token2[] = {0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xb5, 0xcf, 0x83}; - const uint8_t token3[] = {0xce, 0xb1, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb3, 0xce, 0xba, 0xce, 0xb5, + const uint8_t token3[] = {0xce, 0xb1, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb3, 0xce, 0xba, 0xce, 0xb5, 0xcf, 0x83}; - + // Verify the correct analysis of small letters with diaeresis and the elimination of punctuation marks checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3) - )); + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3) + )); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream3) +TEST_F(GreekAnalyzerTest, testReusableTokenStream3) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { - 0xce, 0xa0, 0xce, 0xa1, 0xce, 0x9f, 0xce, 0xab, 0xce, 0xa0, 0xce, 0x9f, 0xce, 0x98, 0xce, 0x95, - 0xce, 0xa3, 0xce, 0x95, 0xce, 0x99, 0xce, 0xa3, 0x20, 0x20, 0xce, 0x86, 0xcf, 0x88, 0xce, 0xbf, - 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x82, 0x2c, 0x20, 0xce, 0xbf, 0x20, 0xce, 0xbc, 0xce, 0xb5, 0xcf, - 0x83, 0xcf, 0x84, 0xcf, 0x8c, 0xcf, 0x82, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xce, + 0xce, 0xa0, 0xce, 0xa1, 0xce, 0x9f, 0xce, 0xab, 0xce, 0xa0, 0xce, 0x9f, 0xce, 0x98, 0xce, 0x95, + 0xce, 0xa3, 0xce, 0x95, 0xce, 0x99, 0xce, 0xa3, 0x20, 0x20, 0xce, 0x86, 0xcf, 0x88, 0xce, 0xbf, + 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x82, 0x2c, 0x20, 0xce, 0xbf, 0x20, 0xce, 0xbc, 0xce, 0xb5, 0xcf, + 0x83, 0xcf, 0x84, 0xcf, 0x8c, 0xcf, 0x82, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xce, 0xbf, 0xce, 0xb9, 0x20, 0xce, 0xac, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xbf, 0xce, 0xb9 }; - - const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x80, 0xce, 0xbf, + + const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb8, 0xce, 0xb5, 0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83}; const uint8_t token2[] = {0xce, 0xb1, 0xcf, 0x88, 0xce, 0xbf, 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token3[] = {0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token4[] = {0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xbf, 0xce, 0xb9}; - + // Verify the correct analysis of capital accented letters and capital letters with diaeresis, // as well as the elimination of stop words checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), UTF8_TO_STRING(token3), UTF8_TO_STRING(token4) - )); + )); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp index 0e13a7b8..97762529 100644 --- a/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp @@ -10,7 +10,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PersianAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture PersianAnalyzerTest; /// These tests show how the combination of tokenization (breaking on zero-width /// non-joiner), normalization (such as treating arabic YEH and farsi YEH the @@ -19,7 +19,7 @@ BOOST_FIXTURE_TEST_SUITE(PersianAnalyzerTest, BaseTokenStreamFixture) /// These verb forms are from http://en.wikipedia.org/wiki/Persian_grammar /// active present indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs1) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbs1) } /// active preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs2) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbs2) } /// active imperfective preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs3) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs3) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -46,128 +46,128 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbs3) } /// active future indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs4) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs4) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs5) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs5) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs6) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs6) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs7) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs7) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs8) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs8) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, + const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs9) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs9) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs10) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs10) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, + const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs11) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs11) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs12) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs12) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, + const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs13) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs13) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs14) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs14) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, + const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs15) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs15) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs16) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs16) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; @@ -176,144 +176,144 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbs16) } /// passive imperfective preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs17) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs17) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs18) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs18) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs19) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs19) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, - 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, + 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs20) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs20) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs21) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs21) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, - 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, + 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive future indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs22) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs22) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xae, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs23) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs23) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, - 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd9, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, + 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbs24) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs24) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, - 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, + 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs25) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs25) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs26) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs26) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs27) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs27) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, - 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, + 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs28) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs28) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs29) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs29) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, - 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, + 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbs30) +TEST_F(PersianAnalyzerTest, testBehaviorVerbs30) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbs30) /// These verb forms are from http://en.wikipedia.org/wiki/Persian_grammar /// active present subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective1) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -340,7 +340,7 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective1) } /// active preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective2) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective2) } /// active imperfective preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective3) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective3) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -358,128 +358,128 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective3) } /// active future indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective4) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective4) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective5) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective5) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective6) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective6) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective7) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective7) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective8) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective8) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, + const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective9) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective9) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective10) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective10) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, + const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective11) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective11) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective12) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective12) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, + const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective13) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective13) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective14) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective14) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, - 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, + const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, + 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective15) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective15) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective16) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective16) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; @@ -488,141 +488,141 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective16) } /// passive imperfective preterite indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective17) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective17) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective18) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective18) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective perfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective19) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective19) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective20) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective20) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective21) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective21) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive future indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective22) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective22) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xae, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective23) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective23) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, - 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, + 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite progressive indicative -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective24) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective24) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, + const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective25) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective25) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd9, 0x88, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective26) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective26) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective preterite subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective27) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective27) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, - 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, + 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective28) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective28) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective29) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective29) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, - 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, + 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present subjunctive -BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective30) +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective30) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -634,7 +634,7 @@ BOOST_AUTO_TEST_CASE(testBehaviorVerbsDefective30) /// non-joiner or space) and stopwords creates a light-stemming effect for /// nouns, removing the plural -ha. -BOOST_AUTO_TEST_CASE(testBehaviorNouns1) +TEST_F(PersianAnalyzerTest, testBehaviorNouns1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf, 0x20, 0xd9, 0x87, 0xd8, 0xa7}; @@ -642,7 +642,7 @@ BOOST_AUTO_TEST_CASE(testBehaviorNouns1) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testBehaviorNouns2) +TEST_F(PersianAnalyzerTest, testBehaviorNouns2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf, 0xe2, 0x80, 0x8c, 0xd9, 0x87, 0xd8, 0xa7}; @@ -651,23 +651,23 @@ BOOST_AUTO_TEST_CASE(testBehaviorNouns2) } /// Test showing that non-Persian text is treated very much like SimpleAnalyzer (lowercased, etc) -BOOST_AUTO_TEST_CASE(testBehaviorNonPersian) +TEST_F(PersianAnalyzerTest, testBehaviorNonPersian) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(a, L"English test.", newCollection(L"english", L"test")); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream1) +TEST_F(PersianAnalyzerTest, testReusableTokenStream1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, - 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, + const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, + 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesToReuse(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream2) +TEST_F(PersianAnalyzerTest, testReusableTokenStream2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf, 0xe2, 0x80, 0x8c, 0xd9, 0x87, 0xd8, 0xa7}; @@ -676,11 +676,9 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream2) } /// Test that custom stopwords work, and are not case-sensitive. -BOOST_AUTO_TEST_CASE(testCustomStopwords) +TEST_F(PersianAnalyzerTest, testCustomStopwords) { Collection stopWords = newCollection(L"the", L"and", L"a"); PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance(stopWords.begin(), stopWords.end())); checkAnalyzesTo(a, L"The quick brown fox.", newCollection(L"quick", L"brown", L"fox")); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp index 22298569..1e1ddca7 100644 --- a/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp @@ -12,10 +12,10 @@ using namespace Lucene; -class PersianNormalizationFilterFixture : public BaseTokenStreamFixture +class PersianNormalizationFilterTest : public BaseTokenStreamFixture { public: - virtual ~PersianNormalizationFilterFixture() + virtual ~PersianNormalizationFilterTest() { } @@ -28,48 +28,44 @@ class PersianNormalizationFilterFixture : public BaseTokenStreamFixture } }; -BOOST_FIXTURE_TEST_SUITE(PersianNormalizationFilterTest, PersianNormalizationFilterFixture) - -BOOST_AUTO_TEST_CASE(testFarsiYeh) +TEST_F(PersianNormalizationFilterTest, testFarsiYeh) { const uint8_t first[] = {0xd9, 0x87, 0xd8, 0xa7, 0xdb, 0x8c}; const uint8_t second[] = {0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testYehBarree) +TEST_F(PersianNormalizationFilterTest, testYehBarree) { const uint8_t first[] = {0xd9, 0x87, 0xd8, 0xa7, 0xdb, 0x92}; const uint8_t second[] = {0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testKeheh) +TEST_F(PersianNormalizationFilterTest, testKeheh) { const uint8_t first[] = {0xda, 0xa9, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x86}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testHehYeh) +TEST_F(PersianNormalizationFilterTest, testHehYeh) { const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xdb, 0x80}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testHehHamzaAbove) +TEST_F(PersianNormalizationFilterTest, testHehHamzaAbove) { const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x94}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -BOOST_AUTO_TEST_CASE(testHehGoal) +TEST_F(PersianNormalizationFilterTest, testHehGoal) { const uint8_t first[] = {0xd8, 0xb2, 0xd8, 0xa7, 0xd8, 0xaf, 0xdb, 0x81}; const uint8_t second[] = {0xd8, 0xb2, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp index 60eb145a..b4b5129b 100644 --- a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp @@ -13,10 +13,10 @@ using namespace Lucene; -class ElisionFixture : public BaseTokenStreamFixture +class ElisionTest : public BaseTokenStreamFixture { public: - virtual ~ElisionFixture() + virtual ~ElisionTest() { } @@ -31,9 +31,7 @@ class ElisionFixture : public BaseTokenStreamFixture } }; -BOOST_FIXTURE_TEST_SUITE(ElisionTest, ElisionFixture) - -BOOST_AUTO_TEST_CASE(testElision) +TEST_F(ElisionTest, testElision) { String test = L"Plop, juste pour voir l'embrouille avec O'brian. M'enfin."; TokenizerPtr tokenizer = newLucene(LuceneVersion::LUCENE_CURRENT, newLucene(test)); @@ -42,9 +40,7 @@ BOOST_AUTO_TEST_CASE(testElision) articles.add(L"M"); TokenFilterPtr filter = newLucene(tokenizer, articles); Collection terms = addTerms(filter); - BOOST_CHECK_EQUAL(L"embrouille", terms[4]); - BOOST_CHECK_EQUAL(L"O'brian", terms[6]); - BOOST_CHECK_EQUAL(L"enfin", terms[7]); + EXPECT_EQ(L"embrouille", terms[4]); + EXPECT_EQ(L"O'brian", terms[6]); + EXPECT_EQ(L"enfin", terms[7]); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp index 761176a3..0f6bc81a 100644 --- a/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp @@ -10,12 +10,12 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(FrenchAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture FrenchAnalyzerTest; -BOOST_AUTO_TEST_CASE(testAnalyzer) +TEST_F(FrenchAnalyzerTest, testAnalyzer) { AnalyzerPtr fa = newLucene(LuceneVersion::LUCENE_CURRENT); - + checkAnalyzesTo(fa, L"", Collection::newInstance()); checkAnalyzesTo(fa, L"chien chat cheval", newCollection(L"chien", L"chat", L"cheval")); @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(testAnalyzer) checkAnalyzesTo(fa, L"le la chien les aux chat du des \u00e0 cheval", newCollection(L"chien", L"chat", L"cheval")); // some nouns and adjectives - checkAnalyzesTo(fa, L"lances chismes habitable chiste \u00e9l\u00e9ments captifs", + checkAnalyzesTo(fa, L"lances chismes habitable chiste \u00e9l\u00e9ments captifs", newCollection( L"lanc", L"chism", L"habit", L"chist", L"\u00e9l\u00e9ment", L"captif")); // some verbs @@ -52,10 +52,10 @@ BOOST_AUTO_TEST_CASE(testAnalyzer) newCollection(L"33bis", L"1940-1945", L"1940", L"1945", L"i")); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream) +TEST_F(FrenchAnalyzerTest, testReusableTokenStream) { AnalyzerPtr fa = newLucene(LuceneVersion::LUCENE_CURRENT); - + // stopwords checkAnalyzesToReuse(fa, L"le la chien les aux chat du des \u00e0 cheval", newCollection(L"chien", L"chat", L"cheval")); @@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -BOOST_AUTO_TEST_CASE(testExclusionTableReuse) +TEST_F(FrenchAnalyzerTest, testExclusionTableReuse) { FrenchAnalyzerPtr fa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesToReuse(fa, L"habitable", newCollection(L"habit")); @@ -75,5 +75,3 @@ BOOST_AUTO_TEST_CASE(testExclusionTableReuse) fa->setStemExclusionTable(exclusions); checkAnalyzesToReuse(fa, L"habitable", newCollection(L"habitable")); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp index 0cf8d7ea..af399da1 100644 --- a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp @@ -11,10 +11,10 @@ using namespace Lucene; -class DutchStemmerFixture : public BaseTokenStreamFixture +class DutchStemmerTest : public BaseTokenStreamFixture { public: - virtual ~DutchStemmerFixture() + virtual ~DutchStemmerTest() { } @@ -23,7 +23,7 @@ class DutchStemmerFixture : public BaseTokenStreamFixture { checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - + void checkReuse(AnalyzerPtr a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); @@ -33,9 +33,7 @@ class DutchStemmerFixture : public BaseTokenStreamFixture /// Test the Dutch Stem Filter, which only modifies the term text. /// The code states that it uses the snowball algorithm, but tests reveal some differences. -BOOST_FIXTURE_TEST_SUITE(DutchStemmerTest, DutchStemmerFixture) - -BOOST_AUTO_TEST_CASE(testWithSnowballExamples) +TEST_F(DutchStemmerTest, testWithSnowballExamples) { check(L"lichaamsziek", L"lichaamsziek"); check(L"lichamelijk", L"licham"); @@ -119,9 +117,9 @@ BOOST_AUTO_TEST_CASE(testWithSnowballExamples) check(L"ophouden", L"ophoud"); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream) +TEST_F(DutchStemmerTest, testReusableTokenStream) { - AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); + AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"lichaamsziek", L"lichaamsziek"); checkReuse(a, L"lichamelijk", L"licham"); checkReuse(a, L"lichamelijke", L"licham"); @@ -129,7 +127,7 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -BOOST_AUTO_TEST_CASE(testExclusionTableReuse) +TEST_F(DutchStemmerTest, testExclusionTableReuse) { DutchAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"lichamelijk", L"licham"); @@ -138,5 +136,3 @@ BOOST_AUTO_TEST_CASE(testExclusionTableReuse) a->setStemExclusionTable(exclusions); checkReuse(a, L"lichamelijk", L"lichamelijk"); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp index cb1af25c..a160b80a 100644 --- a/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp @@ -13,42 +13,40 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(ReverseStringFilterTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture ReverseStringFilterTest; -BOOST_AUTO_TEST_CASE(testFilter) +TEST_F(ReverseStringFilterTest, testFilter) { TokenStreamPtr stream = newLucene(newLucene(L"Do have a nice day")); // 1-4 length string ReverseStringFilterPtr filter = newLucene(stream); TermAttributePtr text = filter->getAttribute(); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"oD", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"evah", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"a", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"ecin", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(L"yad", text->term()); - BOOST_CHECK(!filter->incrementToken()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"oD", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"evah", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"a", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"ecin", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(L"yad", text->term()); + EXPECT_TRUE(!filter->incrementToken()); } -BOOST_AUTO_TEST_CASE(testFilterWithMark) +TEST_F(ReverseStringFilterTest, testFilterWithMark) { TokenStreamPtr stream = newLucene(newLucene(L"Do have a nice day")); // 1-4 length string ReverseStringFilterPtr filter = newLucene(stream, (wchar_t)0x0001); TermAttributePtr text = filter->getAttribute(); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(String(1, (wchar_t)0x0001) + L"oD", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(String(1, (wchar_t)0x0001) + L"evah", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(String(1, (wchar_t)0x0001) + L"a", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(String(1, (wchar_t)0x0001) + L"ecin", text->term()); - BOOST_CHECK(filter->incrementToken()); - BOOST_CHECK_EQUAL(String(1, (wchar_t)0x0001) + L"yad", text->term()); - BOOST_CHECK(!filter->incrementToken()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(String(1, (wchar_t)0x0001) + L"oD", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(String(1, (wchar_t)0x0001) + L"evah", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(String(1, (wchar_t)0x0001) + L"a", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(String(1, (wchar_t)0x0001) + L"ecin", text->term()); + EXPECT_TRUE(filter->incrementToken()); + EXPECT_EQ(String(1, (wchar_t)0x0001) + L"yad", text->term()); + EXPECT_TRUE(!filter->incrementToken()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp index 1431194f..2f5a4b14 100644 --- a/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp @@ -17,54 +17,54 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(RussianAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture RussianAnalyzerTest; -BOOST_AUTO_TEST_CASE(testUnicode) +TEST_F(RussianAnalyzerTest, testUnicode) { RussianAnalyzerPtr ra = newLucene(LuceneVersion::LUCENE_CURRENT); - + String testFile(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"russian"), L"testUTF8.txt")); InputStreamReaderPtr inWords = newLucene(newLucene(testFile)); - + String sampleFile(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"russian"), L"resUTF8.htm")); InputStreamReaderPtr sampleUnicode = newLucene(newLucene(sampleFile)); - + TokenStreamPtr in = ra->tokenStream(L"all", inWords); RussianLetterTokenizerPtr sample = newLucene(sampleUnicode); TermAttributePtr text = in->getAttribute(); TermAttributePtr sampleText = sample->getAttribute(); - + while (true) { if (!in->incrementToken()) break; sample->incrementToken(); - BOOST_CHECK_EQUAL(text->term(), sampleText->term()); + EXPECT_EQ(text->term(), sampleText->term()); } inWords->close(); sampleUnicode->close(); } -BOOST_AUTO_TEST_CASE(testDigitsInRussianCharset) +TEST_F(RussianAnalyzerTest, testDigitsInRussianCharset) { ReaderPtr reader = newLucene(L"text 1000"); RussianAnalyzerPtr ra = newLucene(LuceneVersion::LUCENE_CURRENT); TokenStreamPtr stream = ra->tokenStream(L"", reader); TermAttributePtr termText = stream->getAttribute(); - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(L"text", termText->term()); - BOOST_CHECK(stream->incrementToken()); - BOOST_CHECK_EQUAL(L"1000", termText->term()); - BOOST_CHECK(!stream->incrementToken()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(L"text", termText->term()); + EXPECT_TRUE(stream->incrementToken()); + EXPECT_EQ(L"1000", termText->term()); + EXPECT_TRUE(!stream->incrementToken()); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream1) +TEST_F(RussianAnalyzerTest, testReusableTokenStream1) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { 0xd0, 0x92, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0x20, 0xd1, 0x81, 0x20, @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream1) 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0x20, 0xd0, 0xb5, 0xd1, 0x89, 0xd0, 0xb5 }; - + const uint8_t token1[] = {0xd0, 0xb2, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82}; const uint8_t token2[] = {0xd1, 0x81, 0xd0, 0xb8, 0xd0, 0xbb}; const uint8_t token3[] = {0xd1, 0x8d, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xba, 0xd1, 0x82, 0xd1, 0x80, 0xd0, @@ -86,21 +86,21 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream1) const uint8_t token5[] = {0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbb}; const uint8_t token6[] = {0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd}; - + checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), UTF8_TO_STRING(token3), UTF8_TO_STRING(token4), UTF8_TO_STRING(token5), UTF8_TO_STRING(token6) - )); + )); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream2) +TEST_F(RussianAnalyzerTest, testReusableTokenStream2) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - + const uint8_t input[] = { 0xd0, 0x9d, 0xd0, 0xbe, 0x20, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, @@ -108,16 +108,14 @@ BOOST_AUTO_TEST_CASE(testReusableTokenStream2) 0xbd, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x8c, 0x20, 0xd0, 0xb2, 0x20, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xb9, 0xd0, 0xbd, 0xd0, 0xb5 }; - + const uint8_t token1[] = {0xd0, 0xb7, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbd}; const uint8_t token2[] = {0xd1, 0x85, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd}; const uint8_t token3[] = {0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xb9, 0xd0, 0xbd}; checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), UTF8_TO_STRING(token3) - )); + )); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp b/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp index 7cdb210b..602f5b57 100644 --- a/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp @@ -15,31 +15,31 @@ using namespace Lucene; -class RussianStemmerFixture : public BaseTokenStreamFixture +class RussianStemmerTest : public BaseTokenStreamFixture { public: - RussianStemmerFixture() + RussianStemmerTest() { words = Collection::newInstance(); stems = Collection::newInstance(); - + String wordsFile(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"russian"), L"wordsUTF8.txt")); String stemsFile(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"russian"), L"stemsUTF8.txt")); - + BufferedReaderPtr inWords = newLucene(newLucene(newLucene(wordsFile))); String word; while (inWords->readLine(word)) words.add(word); inWords->close(); - + BufferedReaderPtr inStems = newLucene(newLucene(newLucene(stemsFile))); String stem; while (inStems->readLine(stem)) stems.add(stem); inStems->close(); } - - virtual ~RussianStemmerFixture() + + virtual ~RussianStemmerTest() { } @@ -48,16 +48,12 @@ class RussianStemmerFixture : public BaseTokenStreamFixture Collection stems; }; -BOOST_FIXTURE_TEST_SUITE(RussianStemTest, RussianStemmerFixture) - -BOOST_AUTO_TEST_CASE(testStem) +TEST_F(RussianStemmerTest, testStem) { - BOOST_CHECK_EQUAL(words.size(), stems.size()); + EXPECT_EQ(words.size(), stems.size()); for (int32_t i = 0; i < words.size(); ++i) { String realStem = RussianStemmer::stemWord(words[i]); - BOOST_CHECK_EQUAL(stems[i], realStem); + EXPECT_EQ(stems[i], realStem); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/highlighter/HighlighterTest.cpp b/src/test/contrib/highlighter/HighlighterTest.cpp index 9f8a510a..41ef09dd 100644 --- a/src/test/contrib/highlighter/HighlighterTest.cpp +++ b/src/test/contrib/highlighter/HighlighterTest.cpp @@ -55,44 +55,44 @@ #include "TermQuery.h" using namespace Lucene; -class HighlighterTestFixture; +class HighlighterTest; -namespace HighlighterTest +namespace HighlighterTestNS { class TestFormatter : public Formatter, public LuceneObject { public: - TestFormatter(HighlighterTestFixture* fixture); + TestFormatter(HighlighterTest* fixture); virtual ~TestFormatter(); - + LUCENE_CLASS(TestFormatter); - + protected: - HighlighterTestFixture* fixture; - + HighlighterTest* fixture; + public: virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); }; } -class HighlighterTestFixture : public BaseTokenStreamFixture +class HighlighterTest : public BaseTokenStreamFixture { public: - HighlighterTestFixture() + HighlighterTest() { numHighlights = 0; analyzer = newLucene(TEST_VERSION); texts = newCollection( L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot", L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy", - L"JFK has been shot", + L"JFK has been shot", L"John Kennedy has been shot", L"This text has a typo in referring to Keneddy", - L"wordx wordy wordz wordx wordy wordx worda wordb wordy wordc", - L"y z x y z a b", + L"wordx wordy wordz wordx wordy wordx worda wordb wordy wordc", + L"y z x y z a b", L"lets is a the lets is a the lets is a the lets" ); - + ramDir = newLucene(); IndexWriterPtr writer = newLucene(ramDir, newLucene(TEST_VERSION), true, IndexWriter::MaxFieldLengthUNLIMITED); for (int32_t i = 0; i < texts.size(); ++i) @@ -120,15 +120,15 @@ class HighlighterTestFixture : public BaseTokenStreamFixture writer->optimize(); writer->close(); reader = IndexReader::open(ramDir, true); - + dir = newLucene(); a = newLucene(); } - - virtual ~HighlighterTestFixture() + + virtual ~HighlighterTest() { } - + public: IndexReaderPtr reader; QueryPtr query; @@ -139,12 +139,12 @@ class HighlighterTestFixture : public BaseTokenStreamFixture int32_t numHighlights; AnalyzerPtr analyzer; TopDocsPtr hits; - + Collection texts; - + DirectoryPtr dir; AnalyzerPtr a; - + static const LuceneVersion::Version TEST_VERSION; static const String FIELD_NAME; static const String NUMERIC_FIELD_NAME; @@ -157,7 +157,7 @@ class HighlighterTestFixture : public BaseTokenStreamFixture doc->add(field); writer->addDocument(doc); } - + String highlightField(QueryPtr query, const String& fieldName, const String& text) { TokenStreamPtr tokenStream = newLucene(TEST_VERSION)->tokenStream(fieldName, newLucene(text)); @@ -170,7 +170,7 @@ class HighlighterTestFixture : public BaseTokenStreamFixture String rv = highlighter->getBestFragments(tokenStream, text, 1, L"(FIELD TEXT TRUNCATED)"); return rv.empty() ? text : rv; } - + void doSearching(const String& queryString) { QueryParserPtr parser = newLucene(TEST_VERSION, FIELD_NAME, analyzer); @@ -179,7 +179,7 @@ class HighlighterTestFixture : public BaseTokenStreamFixture query = parser->parse(queryString); doSearching(query); } - + void doSearching(QueryPtr unReWrittenQuery) { searcher = newLucene(ramDir, true); @@ -187,30 +187,30 @@ class HighlighterTestFixture : public BaseTokenStreamFixture query = unReWrittenQuery->rewrite(reader); hits = searcher->search(query, FilterPtr(), 1000); } - + void checkExpectedHighlightCount(int32_t maxNumFragmentsRequired, int32_t expectedHighlights, Collection expected) { Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); - + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + highlighter->setTextFragmenter(newLucene(40)); results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); - - BOOST_CHECK_EQUAL(numHighlights, expectedHighlights); + + EXPECT_EQ(numHighlights, expectedHighlights); } - - BOOST_CHECK_EQUAL(results.size(), expected.size()); + + EXPECT_EQ(results.size(), expected.size()); for (int32_t i = 0; i < results.size(); ++i) - BOOST_CHECK_EQUAL(results[i], expected[i]); + EXPECT_EQ(results[i], expected[i]); } - + void makeIndex() { IndexWriterPtr writer = newLucene(dir, a, IndexWriter::MaxFieldLengthLIMITED); @@ -221,21 +221,21 @@ class HighlighterTestFixture : public BaseTokenStreamFixture writer->optimize(); writer->close(); } - + DocumentPtr doc(const String& f, const String& v) { DocumentPtr doc = newLucene(); doc->add(newLucene(f, v, Field::STORE_YES, Field::INDEX_ANALYZED)); return doc; } - + void deleteDocument() { IndexWriterPtr writer = newLucene(dir, a, false, IndexWriter::MaxFieldLengthLIMITED); writer->deleteDocuments(newLucene(L"t_text1", L"del")); writer->close(); } - + void searchIndex() { String q = L"t_text1:random"; @@ -251,27 +251,27 @@ class HighlighterTestFixture : public BaseTokenStreamFixture { DocumentPtr doc = searcher->doc(hits->scoreDocs[i]->doc); String result = h->getBestFragment(a, L"t_text1", doc->get(L"t_text1")); - BOOST_CHECK_EQUAL(L"more random words for second field", result); + EXPECT_EQ(L"more random words for second field", result); } searcher->close(); } }; -const LuceneVersion::Version HighlighterTestFixture::TEST_VERSION = LuceneVersion::LUCENE_CURRENT; -const String HighlighterTestFixture::FIELD_NAME = L"contents"; -const String HighlighterTestFixture::NUMERIC_FIELD_NAME = L"nfield"; +const LuceneVersion::Version HighlighterTest::TEST_VERSION = LuceneVersion::LUCENE_CURRENT; +const String HighlighterTest::FIELD_NAME = L"contents"; +const String HighlighterTest::NUMERIC_FIELD_NAME = L"nfield"; -namespace HighlighterTest +namespace HighlighterTestNS { - TestFormatter::TestFormatter(HighlighterTestFixture* fixture) + TestFormatter::TestFormatter(HighlighterTest* fixture) { this->fixture = fixture; } - + TestFormatter::~TestFormatter() { } - + String TestFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) { if (tokenGroup->getTotalScore() <= 0) @@ -281,39 +281,39 @@ namespace HighlighterTest } DECLARE_SHARED_PTR(TestHighlightRunner) - + class TestHighlightRunner : public LuceneObject { public: - TestHighlightRunner(HighlighterTestFixture* fixture) + TestHighlightRunner(HighlighterTest* fixture) { this->fixture = fixture; mode = QUERY; frag = newLucene(20); } - + virtual ~TestHighlightRunner() { } - + LUCENE_CLASS(TestHighlightRunner); - + protected: - HighlighterTestFixture* fixture; - + HighlighterTest* fixture; + static const int32_t QUERY; static const int32_t QUERY_TERM; - + public: int32_t mode; FragmenterPtr frag; - + public: virtual HighlighterPtr getHighlighter(QueryPtr query, const String& fieldName, TokenStreamPtr stream, FormatterPtr formatter) { return getHighlighter(query, fieldName, stream, formatter, true); } - + virtual HighlighterPtr getHighlighter(QueryPtr query, const String& fieldName, TokenStreamPtr stream, FormatterPtr formatter, bool expanMultiTerm) { HighlighterScorerPtr scorer; @@ -326,11 +326,11 @@ namespace HighlighterTest else if (mode == QUERY_TERM) scorer = newLucene(query); else - BOOST_FAIL("Unknown highlight mode"); - + boost::throw_exception(IllegalArgumentException(L"Unknown highlight mode")); + return newLucene(formatter, scorer); } - + virtual HighlighterPtr getHighlighter(Collection weightedTerms, FormatterPtr formatter) { if (mode == QUERY) @@ -343,21 +343,21 @@ namespace HighlighterTest else if (mode == QUERY_TERM) return newLucene(formatter, newLucene(weightedTerms)); else - BOOST_FAIL("Unknown highlight mode"); + boost::throw_exception(IllegalArgumentException(L"Unknown highlight mode")); return HighlighterPtr(); } - + virtual void doStandardHighlights(AnalyzerPtr analyzer, IndexSearcherPtr searcher, TopDocsPtr hits, QueryPtr query, FormatterPtr formatter, Collection expected, bool expandMT = false) { Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { - String text = searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTestFixture::FIELD_NAME); + String text = searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); int32_t maxNumFragmentsRequired = 2; String fragmentSeparator = L"..."; HighlighterScorerPtr scorer; - TokenStreamPtr tokenStream = analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); + TokenStreamPtr tokenStream = analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); if (mode == QUERY) scorer = newLucene(query); else if (mode == QUERY_TERM) @@ -366,14 +366,14 @@ namespace HighlighterTest highlighter->setTextFragmenter(frag); results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, fragmentSeparator)); } - - BOOST_CHECK_EQUAL(results.size(), expected.size()); + + EXPECT_EQ(results.size(), expected.size()); for (int32_t i = 0; i < results.size(); ++i) - BOOST_CHECK_EQUAL(results[i], expected[i]); + EXPECT_EQ(results[i], expected[i]); } - + virtual void run(Collection expected) = 0; - + virtual void start(Collection expected = Collection()) { run(expected); @@ -381,14 +381,12 @@ namespace HighlighterTest run(expected); } }; - + const int32_t TestHighlightRunner::QUERY = 0; const int32_t TestHighlightRunner::QUERY_TERM = 1; } -BOOST_FIXTURE_TEST_SUITE(HighlighterTest, HighlighterTestFixture) - -BOOST_AUTO_TEST_CASE(testQueryScorerHits) +TEST_F(HighlighterTest, testQueryScorerHits) { AnalyzerPtr analyzer = newLucene(); QueryParserPtr qp = newLucene(TEST_VERSION, FIELD_NAME, analyzer); @@ -399,7 +397,7 @@ BOOST_AUTO_TEST_CASE(testQueryScorerHits) QueryScorerPtr scorer = newLucene(query, FIELD_NAME); HighlighterPtr highlighter = newLucene(scorer); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) { DocumentPtr doc = searcher->doc(hits->scoreDocs[i]->doc); @@ -412,13 +410,13 @@ BOOST_AUTO_TEST_CASE(testQueryScorerHits) results.add(highlighter->getBestFragment(stream, storedField)); } - - BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results[0], L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); + + EXPECT_EQ(results.size(), 2); + EXPECT_EQ(results[0], L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); } -BOOST_AUTO_TEST_CASE(testHighlightingWithDefaultField) +TEST_F(HighlighterTest, testHighlightingWithDefaultField) { String s1 = L"I call our world Flatland, not because we call it so,"; @@ -429,17 +427,17 @@ BOOST_AUTO_TEST_CASE(testHighlightingWithDefaultField) String expected = L"I call our world Flatland, not because we call it so,"; String observed = highlightField(q, L"SOME_FIELD_NAME", s1); - BOOST_CHECK_EQUAL(expected, observed); + EXPECT_EQ(expected, observed); - // Verify that a query against a named field does not result in any ighlighting when the query field name differs + // Verify that a query against a named field does not result in any ighlighting when the query field name differs // from the name of the field being highlighted, which in this example happens to be the default field name. q = parser->parse(L"text:\"world Flatland\"~3"); expected = s1; observed = highlightField(q, FIELD_NAME, s1); - BOOST_CHECK_EQUAL(s1, highlightField(q, FIELD_NAME, s1)); + EXPECT_EQ(s1, highlightField(q, FIELD_NAME, s1)); } -BOOST_AUTO_TEST_CASE(testSimpleSpanHighlighter) +TEST_F(HighlighterTest, testSimpleSpanHighlighter) { doSearching(L"Kennedy"); @@ -448,7 +446,7 @@ BOOST_AUTO_TEST_CASE(testSimpleSpanHighlighter) QueryScorerPtr scorer = newLucene(query, FIELD_NAME); HighlighterPtr highlighter = newLucene(scorer); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); @@ -457,14 +455,14 @@ BOOST_AUTO_TEST_CASE(testSimpleSpanHighlighter) results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 3); - BOOST_CHECK_EQUAL(results[0], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L"This piece of text refers to Kennedy... to Kennedy"); - BOOST_CHECK_EQUAL(results[2], L" kennedy has been shot"); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy... to Kennedy"); + EXPECT_EQ(results[2], L" kennedy has been shot"); } -BOOST_AUTO_TEST_CASE(testRepeatingTermsInMultBooleans) +TEST_F(HighlighterTest, testRepeatingTermsInMultBooleans) { String content = L"x y z a b c d e f g b c g"; String ph1 = L"\"a b c d\""; @@ -481,23 +479,23 @@ BOOST_AUTO_TEST_CASE(testRepeatingTermsInMultBooleans) QueryScorerPtr scorer = newLucene(query, f1); scorer->setExpandMultiTermQuery(false); - HighlighterPtr h = newLucene(newLucene(this), scorer); + HighlighterPtr h = newLucene(newLucene(this), scorer); h->getBestFragment(analyzer, f1, content); - BOOST_CHECK_EQUAL(numHighlights, 7); + EXPECT_EQ(numHighlights, 7); } -BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting) +TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting) { doSearching(L"\"very long and contains\""); int32_t maxNumFragmentsRequired = 2; QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); @@ -507,11 +505,11 @@ BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting) results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 1); - BOOST_CHECK_EQUAL(results[0], L"Hello this is a piece of text that is very long and contains too much preamble"); - - BOOST_CHECK_EQUAL(numHighlights, 3); + + EXPECT_EQ(results.size(), 1); + EXPECT_EQ(results[0], L"Hello this is a piece of text that is very long and contains too much preamble"); + + EXPECT_EQ(numHighlights, 3); numHighlights = 0; doSearching(L"\"This piece of text refers to Kennedy\""); @@ -519,7 +517,7 @@ BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting) maxNumFragmentsRequired = 2; scorer = newLucene(query, FIELD_NAME); - highlighter = newLucene(newLucene(this), scorer); + highlighter = newLucene(newLucene(this), scorer); results = Collection::newInstance(); for (int32_t i = 0; i < hits->totalHits; ++i) @@ -531,11 +529,11 @@ BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting) results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 1); - BOOST_CHECK_EQUAL(results[0], L"This piece of text refers to Kennedy at the beginning then has a longer piece"); - - BOOST_CHECK_EQUAL(numHighlights, 4); + + EXPECT_EQ(results.size(), 1); + EXPECT_EQ(results[0], L"This piece of text refers to Kennedy at the beginning then has a longer piece"); + + EXPECT_EQ(numHighlights, 4); numHighlights = 0; doSearching(L"\"lets is a the lets is a the lets is a the lets\""); @@ -543,9 +541,9 @@ BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting) maxNumFragmentsRequired = 2; scorer = newLucene(query, FIELD_NAME); - highlighter = newLucene(newLucene(this), scorer); + highlighter = newLucene(newLucene(this), scorer); results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); @@ -555,24 +553,24 @@ BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting) results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 1); - BOOST_CHECK_EQUAL(results[0], L"lets is a the lets is a the lets is a the lets"); - - BOOST_CHECK_EQUAL(numHighlights, 4); + + EXPECT_EQ(results.size(), 1); + EXPECT_EQ(results[0], L"lets is a the lets is a the lets is a the lets"); + + EXPECT_EQ(numHighlights, 4); } -BOOST_AUTO_TEST_CASE(testSpanRegexQuery) +TEST_F(HighlighterTest, testSpanRegexQuery) { // todo } -BOOST_AUTO_TEST_CASE(testRegexQuery) +TEST_F(HighlighterTest, testRegexQuery) { // todo } -BOOST_AUTO_TEST_CASE(testNumericRangeQuery) +TEST_F(HighlighterTest, testNumericRangeQuery) { // doesn't currently highlight, but make sure it doesn't cause exception either query = NumericRangeQuery::newIntRange(NUMERIC_FIELD_NAME, 2, 6, true, true); @@ -581,9 +579,9 @@ BOOST_AUTO_TEST_CASE(testNumericRangeQuery) int32_t maxNumFragmentsRequired = 2; QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(NUMERIC_FIELD_NAME); @@ -593,25 +591,25 @@ BOOST_AUTO_TEST_CASE(testNumericRangeQuery) results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results[0], L""); - BOOST_CHECK_EQUAL(results[1], L""); - - BOOST_CHECK_EQUAL(numHighlights, 0); + + EXPECT_EQ(results.size(), 2); + EXPECT_EQ(results[0], L""); + EXPECT_EQ(results[1], L""); + + EXPECT_EQ(numHighlights, 0); } -BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting2) +TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting2) { doSearching(L"\"text piece long\"~5"); int32_t maxNumFragmentsRequired = 2; QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); highlighter->setTextFragmenter(newLucene(40)); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); @@ -619,117 +617,117 @@ BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting2) results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results[0], L"Hello this is a piece of text that is very long and contains too much preamble"); - BOOST_CHECK_EQUAL(results[1], L" at the beginning then has a longer piece of text that is very long in the middle"); - - BOOST_CHECK_EQUAL(numHighlights, 6); + + EXPECT_EQ(results.size(), 2); + EXPECT_EQ(results[0], L"Hello this is a piece of text that is very long and contains too much preamble"); + EXPECT_EQ(results[1], L" at the beginning then has a longer piece of text that is very long in the middle"); + + EXPECT_EQ(numHighlights, 6); } -BOOST_AUTO_TEST_CASE(testSimpleQueryScorerPhraseHighlighting3) +TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting3) { doSearching(L"\"x y z\""); int32_t maxNumFragmentsRequired = 2; Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); - + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + highlighter->setTextFragmenter(newLucene(40)); results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); - - BOOST_CHECK_EQUAL(numHighlights, 3); + + EXPECT_EQ(numHighlights, 3); } - - BOOST_CHECK_EQUAL(results.size(), 1); - BOOST_CHECK_EQUAL(results[0], L"y z x y z a b"); + + EXPECT_EQ(results.size(), 1); + EXPECT_EQ(results[0], L"y z x y z a b"); } -BOOST_AUTO_TEST_CASE(testSimpleSpanFragmenter) +TEST_F(HighlighterTest, testSimpleSpanFragmenter) { doSearching(L"\"piece of text that is very long\""); int32_t maxNumFragmentsRequired = 2; QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); highlighter->setTextFragmenter(newLucene(scorer, 5)); - + results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results[0], L" this is a piece of text"); - BOOST_CHECK_EQUAL(results[1], L" piece of text that is very long"); - + + EXPECT_EQ(results.size(), 2); + EXPECT_EQ(results[0], L" this is a piece of text"); + EXPECT_EQ(results[1], L" piece of text that is very long"); + doSearching(L"\"been shot\""); - + maxNumFragmentsRequired = 2; scorer = newLucene(query, FIELD_NAME); - highlighter = newLucene(newLucene(this), scorer); + highlighter = newLucene(newLucene(this), scorer); results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); highlighter->setTextFragmenter(newLucene(scorer, 20)); - + results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(numHighlights, 14); - - BOOST_CHECK_EQUAL(results.size(), 3); - BOOST_CHECK_EQUAL(results[0], L"JFK has been shot"); - BOOST_CHECK_EQUAL(results[1], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[2], L" kennedy has been shot"); + + EXPECT_EQ(numHighlights, 14); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"JFK has been shot"); + EXPECT_EQ(results[1], L"John Kennedy has been shot"); + EXPECT_EQ(results[2], L" kennedy has been shot"); } /// position sensitive query added after position insensitive query -BOOST_AUTO_TEST_CASE(testPosTermStdTerm) +TEST_F(HighlighterTest, testPosTermStdTerm) { doSearching(L"y \"x y z\""); int32_t maxNumFragmentsRequired = 2; - + QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); - + highlighter->setTextFragmenter(newLucene(40)); results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); - - BOOST_CHECK_EQUAL(numHighlights, 4); + + EXPECT_EQ(numHighlights, 4); } - - BOOST_CHECK_EQUAL(results.size(), 1); - BOOST_CHECK_EQUAL(results[0], L"y z x y z a b"); + + EXPECT_EQ(results.size(), 1); + EXPECT_EQ(results[0], L"y z x y z a b"); } -BOOST_AUTO_TEST_CASE(testQueryScorerMultiPhraseQueryHighlighting) +TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlighting) { MultiPhraseQueryPtr mpq = newLucene(); @@ -740,16 +738,16 @@ BOOST_AUTO_TEST_CASE(testQueryScorerMultiPhraseQueryHighlighting) int32_t maxNumFragmentsRequired = 2; Collection expected = newCollection(L"wordx wordy wordz wordx wordy wordx worda wordb wordy wordc"); - + checkExpectedHighlightCount(maxNumFragmentsRequired, 6, expected); } -BOOST_AUTO_TEST_CASE(testQueryScorerMultiPhraseQueryHighlightingWithGap) +TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlightingWithGap) { MultiPhraseQueryPtr mpq = newLucene(); // The toString of MultiPhraseQuery doesn't work so well with these out-of-order additions, but the Query itself seems to match accurately. - + mpq->add(newCollection(newLucene(FIELD_NAME, L"wordz")), 2); mpq->add(newCollection(newLucene(FIELD_NAME, L"wordx")), 0); @@ -757,57 +755,57 @@ BOOST_AUTO_TEST_CASE(testQueryScorerMultiPhraseQueryHighlightingWithGap) int32_t maxNumFragmentsRequired = 1; int32_t expectedHighlights = 2; - + Collection expected = newCollection(L"wordx wordy wordz wordx wordy wordx"); - + checkExpectedHighlightCount(maxNumFragmentsRequired, expectedHighlights, expected); } namespace TestNearSpanSimpleQuery { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { mode = QUERY; - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); } }; } -BOOST_AUTO_TEST_CASE(testNearSpanSimpleQuery) +TEST_F(HighlighterTest, testNearSpanSimpleQuery) { doSearching(newLucene(newCollection( newLucene(newLucene(FIELD_NAME, L"beginning")), newLucene(newLucene(FIELD_NAME, L"kennedy"))), 3, false)); - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + Collection expected = newCollection(L" refers to Kennedy at the beginning"); helper->run(expected); - - BOOST_CHECK_EQUAL(numHighlights, 2); + + EXPECT_EQ(numHighlights, 2); } -BOOST_AUTO_TEST_CASE(testSimpleQueryTermScorerHighlighter) +TEST_F(HighlighterTest, testSimpleQueryTermScorerHighlighter) { doSearching(L"Kennedy"); HighlighterPtr highlighter = newLucene(newLucene(query)); highlighter->setTextFragmenter(newLucene(40)); - + int32_t maxNumFragmentsRequired = 2; Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); @@ -815,36 +813,36 @@ BOOST_AUTO_TEST_CASE(testSimpleQueryTermScorerHighlighter) results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"...")); } - - BOOST_CHECK_EQUAL(results.size(), 3); - BOOST_CHECK_EQUAL(results[0], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L"This piece of text refers to Kennedy... to Kennedy"); - BOOST_CHECK_EQUAL(results[2], L" kennedy has been shot"); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy... to Kennedy"); + EXPECT_EQ(results[2], L" kennedy has been shot"); } namespace TestSpanHighlighting { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { mode = QUERY; - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); } }; } -BOOST_AUTO_TEST_CASE(testSpanHighlighting) +TEST_F(HighlighterTest, testSpanHighlighting) { QueryPtr query1 = newLucene(newCollection( newLucene(newLucene(FIELD_NAME, L"wordx")), @@ -856,83 +854,83 @@ BOOST_AUTO_TEST_CASE(testSpanHighlighting) bquery->add(query1, BooleanClause::SHOULD); bquery->add(query2, BooleanClause::SHOULD); doSearching(bquery); - - TestHighlightRunnerPtr helper = newLucene(this); - + + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + Collection expected = newCollection(L"wordx wordy wordz wordx wordy wordx"); helper->run(expected); - - BOOST_CHECK_EQUAL(numHighlights, 7); + + EXPECT_EQ(numHighlights, 7); } namespace TestNotSpanSimpleQuery { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { mode = QUERY; - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); } }; } -BOOST_AUTO_TEST_CASE(testNotSpanSimpleQuery) +TEST_F(HighlighterTest, testNotSpanSimpleQuery) { doSearching(newLucene(newLucene(newCollection( newLucene(newLucene(FIELD_NAME, L"shot")), - newLucene(newLucene(FIELD_NAME, L"kennedy"))), 3, false), + newLucene(newLucene(FIELD_NAME, L"kennedy"))), 3, false), newLucene(newLucene(FIELD_NAME, L"john")))); - - TestHighlightRunnerPtr helper = newLucene(this); - + + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + Collection expected = newCollection( L"John Kennedy has been shot", L" kennedy has been shot" ); helper->run(expected); - - BOOST_CHECK_EQUAL(numHighlights, 4); + + EXPECT_EQ(numHighlights, 4); } namespace TestGetBestFragmentsSimpleQuery { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"Kennedy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - BOOST_CHECK_EQUAL(fixture->numHighlights, 4); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 4); } }; } -BOOST_AUTO_TEST_CASE(testGetBestFragmentsSimpleQuery) +TEST_F(HighlighterTest, testGetBestFragmentsSimpleQuery) { - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + helper->start( newCollection( L"John Kennedy has been shot", @@ -944,32 +942,32 @@ BOOST_AUTO_TEST_CASE(testGetBestFragmentsSimpleQuery) namespace TestGetFuzzyFragments { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"Kinnedy~"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected, true); - BOOST_CHECK_EQUAL(fixture->numHighlights, 5); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected, true); + EXPECT_EQ(fixture->numHighlights, 5); } }; } -BOOST_AUTO_TEST_CASE(testGetFuzzyFragments) +TEST_F(HighlighterTest, testGetFuzzyFragments) { - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + helper->start( newCollection( L"John Kennedy has been shot", @@ -982,32 +980,32 @@ BOOST_AUTO_TEST_CASE(testGetFuzzyFragments) namespace TestGetWildCardFragments { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"K?nnedy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - BOOST_CHECK_EQUAL(fixture->numHighlights, 4); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 4); } }; } -BOOST_AUTO_TEST_CASE(testGetWildCardFragments) +TEST_F(HighlighterTest, testGetWildCardFragments) { - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + helper->start( newCollection( L"John Kennedy has been shot", @@ -1019,32 +1017,32 @@ BOOST_AUTO_TEST_CASE(testGetWildCardFragments) namespace TestGetMidWildCardFragments { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"K*dy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - BOOST_CHECK_EQUAL(fixture->numHighlights, 5); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); } }; } -BOOST_AUTO_TEST_CASE(testGetMidWildCardFragments) +TEST_F(HighlighterTest, testGetMidWildCardFragments) { - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + helper->start( newCollection( L" to Keneddy", @@ -1057,39 +1055,39 @@ BOOST_AUTO_TEST_CASE(testGetMidWildCardFragments) namespace TestGetRangeFragments { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; - String queryString = HighlighterTestFixture::FIELD_NAME + L":[kannedy TO kznnedy]"; + String queryString = HighlighterTest::FIELD_NAME + L":[kannedy TO kznnedy]"; // Need to explicitly set the QueryParser property to use TermRangeQuery rather than RangeFilters - QueryParserPtr parser = newLucene(HighlighterTestFixture::TEST_VERSION, HighlighterTestFixture::FIELD_NAME, fixture->analyzer); + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, fixture->analyzer); parser->setMultiTermRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); fixture->query = parser->parse(queryString); fixture->doSearching(fixture->query); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - BOOST_CHECK_EQUAL(fixture->numHighlights, 5); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); } }; } -BOOST_AUTO_TEST_CASE(testGetRangeFragments) +TEST_F(HighlighterTest, testGetRangeFragments) { - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + helper->start( newCollection( L" to Keneddy", @@ -1100,7 +1098,7 @@ BOOST_AUTO_TEST_CASE(testGetRangeFragments) ); } -BOOST_AUTO_TEST_CASE(testConstantScoreMultiTermQuery) +TEST_F(HighlighterTest, testConstantScoreMultiTermQuery) { numHighlights = 0; @@ -1110,143 +1108,143 @@ BOOST_AUTO_TEST_CASE(testConstantScoreMultiTermQuery) // can't rewrite ConstantScore if you want to highlight it - it rewrites to ConstantScoreQuery which cannot be highlighted // query = unReWrittenQuery.rewrite(reader); hits = searcher->search(query, FilterPtr(), 1000); - + Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); int32_t maxNumFragmentsRequired = 2; String fragmentSeparator = L"..."; - + TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); QueryScorerPtr scorer = newLucene(query, FIELD_NAME); - - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); - + + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + highlighter->setTextFragmenter(newLucene(20)); results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, fragmentSeparator)); } - - BOOST_CHECK_EQUAL(numHighlights, 5); - - BOOST_CHECK_EQUAL(results.size(), 4); - BOOST_CHECK_EQUAL(results[0], L" kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L" refers to Kennedy... to Kennedy"); - BOOST_CHECK_EQUAL(results[2], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[3], L" to Keneddy"); - + + EXPECT_EQ(numHighlights, 5); + + EXPECT_EQ(results.size(), 4); + EXPECT_EQ(results[0], L" kennedy has been shot"); + EXPECT_EQ(results[1], L" refers to Kennedy... to Kennedy"); + EXPECT_EQ(results[2], L"John Kennedy has been shot"); + EXPECT_EQ(results[3], L" to Keneddy"); + // try null field - + hits = searcher->search(query, FilterPtr(), 1000); - + numHighlights = 0; - + results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); int32_t maxNumFragmentsRequired = 2; String fragmentSeparator = L"..."; - + TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); QueryScorerPtr scorer = newLucene(query, L""); - - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); - + + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + highlighter->setTextFragmenter(newLucene(20)); results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, fragmentSeparator)); } - - BOOST_CHECK_EQUAL(numHighlights, 5); - - BOOST_CHECK_EQUAL(results.size(), 4); - BOOST_CHECK_EQUAL(results[0], L" kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L" refers to Kennedy... to Kennedy"); - BOOST_CHECK_EQUAL(results[2], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[3], L" to Keneddy"); - + + EXPECT_EQ(numHighlights, 5); + + EXPECT_EQ(results.size(), 4); + EXPECT_EQ(results[0], L" kennedy has been shot"); + EXPECT_EQ(results[1], L" refers to Kennedy... to Kennedy"); + EXPECT_EQ(results[2], L"John Kennedy has been shot"); + EXPECT_EQ(results[3], L" to Keneddy"); + // try default field - + hits = searcher->search(query, FilterPtr(), 1000); - + numHighlights = 0; - + results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); int32_t maxNumFragmentsRequired = 2; String fragmentSeparator = L"..."; - + TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); QueryScorerPtr scorer = newLucene(query, L"random_field", FIELD_NAME); - - HighlighterPtr highlighter = newLucene(newLucene(this), scorer); - + + HighlighterPtr highlighter = newLucene(newLucene(this), scorer); + highlighter->setTextFragmenter(newLucene(20)); results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, fragmentSeparator)); } - - BOOST_CHECK_EQUAL(numHighlights, 5); - - BOOST_CHECK_EQUAL(results.size(), 4); - BOOST_CHECK_EQUAL(results[0], L" kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L" refers to Kennedy... to Kennedy"); - BOOST_CHECK_EQUAL(results[2], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[3], L" to Keneddy"); + + EXPECT_EQ(numHighlights, 5); + + EXPECT_EQ(results.size(), 4); + EXPECT_EQ(results[0], L" kennedy has been shot"); + EXPECT_EQ(results[1], L" refers to Kennedy... to Kennedy"); + EXPECT_EQ(results[2], L"John Kennedy has been shot"); + EXPECT_EQ(results[3], L" to Keneddy"); } namespace TestGetBestFragmentsPhrase { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"\"John Kennedy\""); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + // Currently highlights "John" and "Kennedy" separately - BOOST_CHECK_EQUAL(fixture->numHighlights, 2); + EXPECT_EQ(fixture->numHighlights, 2); } }; } -BOOST_AUTO_TEST_CASE(testGetBestFragmentsPhrase) +TEST_F(HighlighterTest, testGetBestFragmentsPhrase) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } namespace TestGetBestFragmentsQueryScorer { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1258,33 +1256,33 @@ namespace TestGetBestFragmentsQueryScorer SpanNearQueryPtr snq = newLucene(clauses, 1, true); fixture->doSearching(snq); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + // Currently highlights "John" and "Kennedy" separately - BOOST_CHECK_EQUAL(fixture->numHighlights, 2); + EXPECT_EQ(fixture->numHighlights, 2); } }; } -BOOST_AUTO_TEST_CASE(testGetBestFragmentsQueryScorer) +TEST_F(HighlighterTest, testGetBestFragmentsQueryScorer) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } namespace TestOffByOne { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1293,30 +1291,30 @@ namespace TestOffByOne hg->setTextFragmenter(newLucene()); String match = hg->getBestFragment(fixture->analyzer, L"data", L"help me [54-65]"); - BOOST_CHECK_EQUAL(L"help me [54-65]", match); + EXPECT_EQ(L"help me [54-65]", match); } }; } -BOOST_AUTO_TEST_CASE(testOffByOne) +TEST_F(HighlighterTest, testOffByOne) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestGetBestFragmentsFilteredQuery { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1330,33 +1328,33 @@ namespace TestGetBestFragmentsFilteredQuery FilteredQueryPtr fq = newLucene(snq, rf); fixture->doSearching(fq); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + // Currently highlights "John" and "Kennedy" separately - BOOST_CHECK_EQUAL(fixture->numHighlights, 2); + EXPECT_EQ(fixture->numHighlights, 2); } }; } -BOOST_AUTO_TEST_CASE(testGetBestFragmentsFilteredQuery) +TEST_F(HighlighterTest, testGetBestFragmentsFilteredQuery) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } namespace TestGetBestFragmentsFilteredPhraseQuery { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1368,48 +1366,48 @@ namespace TestGetBestFragmentsFilteredPhraseQuery FilteredQueryPtr fq = newLucene(pq, rf); fixture->doSearching(fq); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + // Currently highlights "John" and "Kennedy" separately - BOOST_CHECK_EQUAL(fixture->numHighlights, 2); + EXPECT_EQ(fixture->numHighlights, 2); } }; } -BOOST_AUTO_TEST_CASE(testGetBestFragmentsFilteredPhraseQuery) +TEST_F(HighlighterTest, testGetBestFragmentsFilteredPhraseQuery) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } namespace TestGetBestFragmentsMultiTerm { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"John Kenn*"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - BOOST_CHECK_EQUAL(fixture->numHighlights, 5); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); } }; } -BOOST_AUTO_TEST_CASE(testGetBestFragmentsMultiTerm) +TEST_F(HighlighterTest, testGetBestFragmentsMultiTerm) { - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + helper->start( newCollection( L"John Kennedy has been shot", @@ -1421,32 +1419,32 @@ BOOST_AUTO_TEST_CASE(testGetBestFragmentsMultiTerm) namespace TestGetBestFragmentsWithOr { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"JFK OR Kennedy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - BOOST_CHECK_EQUAL(fixture->numHighlights, 5); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); } }; } -BOOST_AUTO_TEST_CASE(testGetBestFragmentsWithOr) +TEST_F(HighlighterTest, testGetBestFragmentsWithOr) { - TestHighlightRunnerPtr helper = newLucene(this); - + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); + helper->start( newCollection( L"JFK has been shot", @@ -1459,97 +1457,97 @@ BOOST_AUTO_TEST_CASE(testGetBestFragmentsWithOr) namespace TestGetBestSingleFragment { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->doSearching(L"Kennedy"); fixture->numHighlights = 0; Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTestFixture::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture)); + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); highlighter->setTextFragmenter(newLucene(40)); results.add(highlighter->getBestFragment(tokenStream, text)); } - BOOST_CHECK_EQUAL(fixture->numHighlights, 4); - - BOOST_CHECK_EQUAL(results.size(), 3); - BOOST_CHECK_EQUAL(results[0], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L"This piece of text refers to Kennedy"); - BOOST_CHECK_EQUAL(results[2], L" kennedy has been shot"); - + EXPECT_EQ(fixture->numHighlights, 4); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy"); + EXPECT_EQ(results[2], L" kennedy has been shot"); + fixture->numHighlights = 0; results = Collection::newInstance(); - + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTestFixture::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture)); - results.add(highlighter->getBestFragment(fixture->analyzer, HighlighterTestFixture::FIELD_NAME, text)); + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + results.add(highlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, text)); } - BOOST_CHECK_EQUAL(fixture->numHighlights, 4); - - BOOST_CHECK_EQUAL(results.size(), 3); - BOOST_CHECK_EQUAL(results[0], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); - BOOST_CHECK_EQUAL(results[2], L" is really here which says kennedy has been shot"); - + EXPECT_EQ(fixture->numHighlights, 4); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); + EXPECT_EQ(results[2], L" is really here which says kennedy has been shot"); + fixture->numHighlights = 0; results = Collection::newInstance(); - + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTestFixture::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture)); + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); highlighter->setTextFragmenter(newLucene(40)); - Collection result = highlighter->getBestFragments(fixture->analyzer, HighlighterTestFixture::FIELD_NAME, text, 10); + Collection result = highlighter->getBestFragments(fixture->analyzer, HighlighterTest::FIELD_NAME, text, 10); results.addAll(result.begin(), result.end()); } - BOOST_CHECK_EQUAL(fixture->numHighlights, 4); - - BOOST_CHECK_EQUAL(results.size(), 3); - BOOST_CHECK_EQUAL(results[0], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy"); - BOOST_CHECK_EQUAL(results[2], L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot"); + EXPECT_EQ(fixture->numHighlights, 4); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy"); + EXPECT_EQ(results[2], L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot"); } }; } -BOOST_AUTO_TEST_CASE(testGetBestSingleFragment) +TEST_F(HighlighterTest, testGetBestSingleFragment) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestGetBestSingleFragmentWithWeights { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1563,31 +1561,31 @@ namespace TestGetBestSingleFragmentWithWeights positionSpans = newCollection(newLucene(14, 14)); boost::dynamic_pointer_cast(wTerms[1])->addPositionSpans(positionSpans); - HighlighterPtr highlighter = getHighlighter(wTerms, newLucene(fixture)); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(fixture->texts[0])); + HighlighterPtr highlighter = getHighlighter(wTerms, newLucene(fixture)); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); highlighter->setTextFragmenter(newLucene(2)); - + String result = highlighter->getBestFragment(tokenStream, fixture->texts[0]); boost::trim(result); - - BOOST_CHECK_EQUAL(L"Hello", result); - + + EXPECT_EQ(L"Hello", result); + wTerms[1]->setWeight(50.0); - tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(fixture->texts[0])); - highlighter = getHighlighter(wTerms, newLucene(fixture)); + tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); + highlighter = getHighlighter(wTerms, newLucene(fixture)); highlighter->setTextFragmenter(newLucene(2)); result = highlighter->getBestFragment(tokenStream, fixture->texts[0]); boost::trim(result); - - BOOST_CHECK_EQUAL(L"kennedy", result); + + EXPECT_EQ(L"kennedy", result); } }; } -BOOST_AUTO_TEST_CASE(testGetBestSingleFragmentWithWeights) +TEST_F(HighlighterTest, testGetBestSingleFragmentWithWeights) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } @@ -1609,11 +1607,11 @@ namespace TestOverlapAnalyzer this->posIncrAtt = addAttribute(); this->offsetAtt = addAttribute(); } - + virtual ~SynonymTokenizer() { } - + protected: TokenStreamPtr realStream; TokenPtr currentRealToken; @@ -1627,7 +1625,7 @@ namespace TestOverlapAnalyzer TermAttributePtr termAtt; PositionIncrementAttributePtr posIncrAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool incrementToken() { @@ -1670,7 +1668,7 @@ namespace TestOverlapAnalyzer } } }; - + class SynonymAnalyzer : public Analyzer { public: @@ -1678,14 +1676,14 @@ namespace TestOverlapAnalyzer { this->synonyms = synonyms; } - + virtual ~SynonymAnalyzer() { } - + protected: MapStringString synonyms; - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { @@ -1696,18 +1694,18 @@ namespace TestOverlapAnalyzer return newLucene(stream, synonyms); } }; - - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1717,167 +1715,167 @@ namespace TestOverlapAnalyzer String srchkey = L"football"; String s = L"football-soccer in the euro 2004 footie competition"; - QueryParserPtr parser = newLucene(HighlighterTestFixture::TEST_VERSION, L"bookid", analyzer); + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, L"bookid", analyzer); QueryPtr query = parser->parse(srchkey); TokenStreamPtr tokenStream = analyzer->tokenStream(L"", newLucene(s)); - - HighlighterPtr highlighter = getHighlighter(query, L"", tokenStream, newLucene(fixture)); - + + HighlighterPtr highlighter = getHighlighter(query, L"", tokenStream, newLucene(fixture)); + // Get 3 best fragments and separate with a "..." tokenStream = analyzer->tokenStream(L"", newLucene(s)); String result = highlighter->getBestFragments(tokenStream, s, 3, L"..."); String expectedResult = L"football-soccer in the euro 2004 footie competition"; - - BOOST_CHECK_EQUAL(expectedResult, result); + + EXPECT_EQ(expectedResult, result); } }; } /// tests a "complex" analyzer that produces multiple overlapping tokens -BOOST_AUTO_TEST_CASE(testOverlapAnalyzer) +TEST_F(HighlighterTest, testOverlapAnalyzer) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestGetSimpleHighlight { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"Kennedy"); - + Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTestFixture::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture)); + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); results.add(highlighter->getBestFragment(tokenStream, text)); } - BOOST_CHECK_EQUAL(fixture->numHighlights, 4); - - BOOST_CHECK_EQUAL(results.size(), 3); - BOOST_CHECK_EQUAL(results[0], L"John Kennedy has been shot"); - BOOST_CHECK_EQUAL(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); - BOOST_CHECK_EQUAL(results[2], L" is really here which says kennedy has been shot"); + EXPECT_EQ(fixture->numHighlights, 4); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); + EXPECT_EQ(results[2], L" is really here which says kennedy has been shot"); } }; } -BOOST_AUTO_TEST_CASE(testGetSimpleHighlight) +TEST_F(HighlighterTest, testGetSimpleHighlight) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestGetTextFragments { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->doSearching(L"Kennedy"); - + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTestFixture::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); - - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture)); + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); highlighter->setTextFragmenter(newLucene(20)); Collection stringResults = highlighter->getBestFragments(tokenStream, text, 10); - - tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); + + tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); Collection fragmentResults = highlighter->getBestTextFragments(tokenStream, text, true, 10); - - BOOST_CHECK_EQUAL(fragmentResults.size(), stringResults.size()); + + EXPECT_EQ(fragmentResults.size(), stringResults.size()); for (int32_t j = 0; j < stringResults.size(); ++j) - BOOST_CHECK_EQUAL(fragmentResults[j]->toString(), stringResults[j]); + EXPECT_EQ(fragmentResults[j]->toString(), stringResults[j]); } } }; } -BOOST_AUTO_TEST_CASE(testGetTextFragments) +TEST_F(HighlighterTest, testGetTextFragments) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestMaxSizeHighlight { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; fixture->doSearching(L"meat"); - - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(fixture->texts[0])); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture)); + + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); highlighter->setMaxDocCharsToAnalyze(30); - + highlighter->getBestFragment(tokenStream, fixture->texts[0]); - BOOST_CHECK_EQUAL(fixture->numHighlights, 0); + EXPECT_EQ(fixture->numHighlights, 0); } }; } -BOOST_AUTO_TEST_CASE(testMaxSizeHighlight) +TEST_F(HighlighterTest, testMaxSizeHighlight) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestMaxSizeHighlightTruncates { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1886,51 +1884,51 @@ namespace TestMaxSizeHighlightTruncates stopWords.add(L"stoppedtoken"); TermQueryPtr query = newLucene(newLucene(L"data", goodWord)); - + StringStream buffer; buffer << goodWord; - + for (int32_t i = 0; i < 10000; ++i) { // only one stopword buffer << L" " << *stopWords.begin(); } SimpleHTMLFormatterPtr fm = newLucene(); - HighlighterPtr hg = getHighlighter(query, L"data", newLucene(HighlighterTestFixture::TEST_VERSION, stopWords)->tokenStream(L"data", newLucene(buffer.str())), fm); - + HighlighterPtr hg = getHighlighter(query, L"data", newLucene(HighlighterTest::TEST_VERSION, stopWords)->tokenStream(L"data", newLucene(buffer.str())), fm); + hg->setTextFragmenter(newLucene()); hg->setMaxDocCharsToAnalyze(100); - String match = hg->getBestFragment(newLucene(HighlighterTestFixture::TEST_VERSION, stopWords), L"data", buffer.str()); - BOOST_CHECK((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); + String match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"data", buffer.str()); + EXPECT_TRUE((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); - // add another tokenized word to the overall length - but set way beyond the length of text under consideration + // add another tokenized word to the overall length - but set way beyond the length of text under consideration // (after a large slug of stop words + whitespace) buffer << L" " << goodWord; - match = hg->getBestFragment(newLucene(HighlighterTestFixture::TEST_VERSION, stopWords), L"data", buffer.str()); - BOOST_CHECK((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); + match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"data", buffer.str()); + EXPECT_TRUE((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); } }; } -BOOST_AUTO_TEST_CASE(testMaxSizeHighlightTruncates) +TEST_F(HighlighterTest, testMaxSizeHighlightTruncates) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestMaxSizeEndHighlight { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -1943,105 +1941,105 @@ namespace TestMaxSizeEndHighlight String text = L"this is a text with searchterm in it"; SimpleHTMLFormatterPtr fm = newLucene(); - HighlighterPtr hg = getHighlighter(query, L"text", newLucene(HighlighterTestFixture::TEST_VERSION, stopWords)->tokenStream(L"text", newLucene(text)), fm); - + HighlighterPtr hg = getHighlighter(query, L"text", newLucene(HighlighterTest::TEST_VERSION, stopWords)->tokenStream(L"text", newLucene(text)), fm); + hg->setTextFragmenter(newLucene()); hg->setMaxDocCharsToAnalyze(36); - String match = hg->getBestFragment(newLucene(HighlighterTestFixture::TEST_VERSION, stopWords), L"text", text); - BOOST_CHECK(boost::ends_with(match, L"in it")); + String match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"text", text); + EXPECT_TRUE(boost::ends_with(match, L"in it")); } }; } -BOOST_AUTO_TEST_CASE(testMaxSizeEndHighlight) +TEST_F(HighlighterTest, testMaxSizeEndHighlight) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestUnRewrittenQuery { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->numHighlights = 0; // test to show how rewritten query can still be used fixture->searcher = newLucene(fixture->ramDir, true); - AnalyzerPtr analyzer = newLucene(HighlighterTestFixture::TEST_VERSION); + AnalyzerPtr analyzer = newLucene(HighlighterTest::TEST_VERSION); - QueryParserPtr parser = newLucene(HighlighterTestFixture::TEST_VERSION, HighlighterTestFixture::FIELD_NAME, analyzer); + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, analyzer); QueryPtr query = parser->parse(L"JF? or Kenned*"); TopDocsPtr hits = fixture->searcher->search(query, FilterPtr(), 1000); int32_t maxNumFragmentsRequired = 3; - + for (int32_t i = 0; i < hits->totalHits; ++i) { - String text = fixture->searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTestFixture::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture), false); - + String text = fixture->searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture), false); + highlighter->setTextFragmenter(newLucene(40)); - + highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"..."); } - + // We expect to have zero highlights if the query is multi-terms and is not rewritten - BOOST_CHECK_EQUAL(fixture->numHighlights, 0); + EXPECT_EQ(fixture->numHighlights, 0); } }; } -BOOST_AUTO_TEST_CASE(testUnRewrittenQuery) +TEST_F(HighlighterTest, testUnRewrittenQuery) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } namespace TestNoFragments { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { fixture->doSearching(L"AnInvalidQueryWhichShouldYieldNoResults"); - + for (int32_t i = 0; i < fixture->texts.size(); ++i) { String text = fixture->texts[i]; - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTestFixture::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTestFixture::FIELD_NAME, tokenStream, newLucene(fixture)); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); String result = highlighter->getBestFragment(tokenStream, text); - BOOST_CHECK(result.empty()); + EXPECT_TRUE(result.empty()); } } }; } -BOOST_AUTO_TEST_CASE(testNoFragments) +TEST_F(HighlighterTest, testNoFragments) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } @@ -2053,22 +2051,22 @@ namespace TestEncoding virtual ~NullScorer() { } - + public: virtual void startFragment(TextFragmentPtr newFragment) { } - + virtual double getTokenScore() { return 0.0; } - + virtual double getFragmentScore() { return 1.0; } - + virtual TokenStreamPtr init(TokenStreamPtr tokenStream) { return TokenStreamPtr(); @@ -2077,22 +2075,22 @@ namespace TestEncoding } /// Demonstrates creation of an XHTML compliant doc using new encoding facilities. -BOOST_AUTO_TEST_CASE(testEncoding) +TEST_F(HighlighterTest, testEncoding) { String rawDocContent = L"\"Smith & sons' prices < 3 and >4\" claims article"; - + // run the highlighter on the raw content (scorer does not score any tokens for // highlighting but scores a single fragment for selection - HighlighterPtr highlighter = newLucene(newLucene(this), newLucene(), newLucene()); - + HighlighterPtr highlighter = newLucene(newLucene(this), newLucene(), newLucene()); + highlighter->setTextFragmenter(newLucene(2000)); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(rawDocContent)); String encodedSnippet = highlighter->getBestFragments(tokenStream, rawDocContent, 1, L""); - BOOST_CHECK_EQUAL(encodedSnippet, L""Smith & sons' prices < 3 and >4" claims article"); + EXPECT_EQ(encodedSnippet, L""Smith & sons' prices < 3 and >4" claims article"); } -BOOST_AUTO_TEST_CASE(testMultiSearcher) +TEST_F(HighlighterTest, testMultiSearcher) { // setup index 1 RAMDirectoryPtr ramDir1 = newLucene(); @@ -2115,7 +2113,7 @@ BOOST_AUTO_TEST_CASE(testMultiSearcher) writer2->optimize(); writer2->close(); IndexReaderPtr reader2 = IndexReader::open(ramDir2, true); - + Collection searchers = newCollection( newLucene(ramDir1, true), newLucene(ramDir2, true) @@ -2134,9 +2132,9 @@ BOOST_AUTO_TEST_CASE(testMultiSearcher) query = query->combine(expandedQueries); // create an instance of the highlighter with the tags used to surround highlighted text - HighlighterPtr highlighter = newLucene(newLucene(this), newLucene(query)); + HighlighterPtr highlighter = newLucene(newLucene(this), newLucene(query)); Collection results = Collection::newInstance(); - + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = multiSearcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); @@ -2145,45 +2143,45 @@ BOOST_AUTO_TEST_CASE(testMultiSearcher) results.add(highlightedText); } - BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results[0], L"multiOne"); - BOOST_CHECK_EQUAL(results[1], L"multiTwo"); - - BOOST_CHECK_EQUAL(numHighlights, 2); + EXPECT_EQ(results.size(), 2); + EXPECT_EQ(results[0], L"multiOne"); + EXPECT_EQ(results[1], L"multiTwo"); + + EXPECT_EQ(numHighlights, 2); } namespace TestFieldSpecificHighlighting { - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { String docMainText = L"fred is one of the people"; - QueryParserPtr parser = newLucene(HighlighterTestFixture::TEST_VERSION, HighlighterTestFixture::FIELD_NAME, fixture->analyzer); + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, fixture->analyzer); QueryPtr query = parser->parse(L"fred category:people"); // highlighting respects fieldnames used in query HighlighterScorerPtr fieldSpecificScorer; if (mode == QUERY) - fieldSpecificScorer = newLucene(query, HighlighterTestFixture::FIELD_NAME); + fieldSpecificScorer = newLucene(query, HighlighterTest::FIELD_NAME); else if (mode == QUERY_TERM) fieldSpecificScorer = newLucene(query, L"contents"); - + HighlighterPtr fieldSpecificHighlighter = newLucene(newLucene(), fieldSpecificScorer); fieldSpecificHighlighter->setTextFragmenter(newLucene()); - String result = fieldSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTestFixture::FIELD_NAME, docMainText); - BOOST_CHECK_EQUAL(result, L"fred is one of the people"); + String result = fieldSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, docMainText); + EXPECT_EQ(result, L"fred is one of the people"); // highlighting does not respect fieldnames used in query HighlighterScorerPtr fieldInSpecificScorer; @@ -2194,17 +2192,17 @@ namespace TestFieldSpecificHighlighting HighlighterPtr fieldInSpecificHighlighter = newLucene(newLucene(), fieldInSpecificScorer); fieldInSpecificHighlighter->setTextFragmenter(newLucene()); - result = fieldInSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTestFixture::FIELD_NAME, docMainText); - BOOST_CHECK_EQUAL(result, L"fred is one of the people"); + result = fieldInSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, docMainText); + EXPECT_EQ(result, L"fred is one of the people"); fixture->reader->close(); } }; } -BOOST_AUTO_TEST_CASE(testFieldSpecificHighlighting) +TEST_F(HighlighterTest, testFieldSpecificHighlighting) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } @@ -2236,18 +2234,18 @@ namespace TestOverlapAnalyzer2 lst.add(t); tokenPos = 0; } - + virtual ~TS2() { } - + protected: Collection lst; int32_t tokenPos; TermAttributePtr termAtt; PositionIncrementAttributePtr posIncrAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool incrementToken() { @@ -2262,7 +2260,7 @@ namespace TestOverlapAnalyzer2 } return false; } - + protected: TokenPtr createToken(const String& term, int32_t start, int32_t offset) { @@ -2271,7 +2269,7 @@ namespace TestOverlapAnalyzer2 return token; } }; - + /// same token-stream as above, but the bigger token comes first this time class TS2a : public TokenStream { @@ -2299,18 +2297,18 @@ namespace TestOverlapAnalyzer2 lst.add(t); tokenPos = 0; } - + virtual ~TS2a() { } - + protected: Collection lst; int32_t tokenPos; TermAttributePtr termAtt; PositionIncrementAttributePtr posIncrAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool incrementToken() { @@ -2325,7 +2323,7 @@ namespace TestOverlapAnalyzer2 } return false; } - + protected: TokenPtr createToken(const String& term, int32_t start, int32_t offset) { @@ -2334,18 +2332,18 @@ namespace TestOverlapAnalyzer2 return token; } }; - - class HelperHighlightRunner : public HighlighterTest::TestHighlightRunner + + class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { public: - HelperHighlightRunner(HighlighterTestFixture* fixture) : HighlighterTest::TestHighlightRunner(fixture) + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { } - + virtual ~HelperHighlightRunner() { } - + public: virtual void run(Collection expected) { @@ -2355,73 +2353,73 @@ namespace TestOverlapAnalyzer2 HighlighterPtr highlighter; String result; - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"foo"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"foo"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"10"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"10"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"hi"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"speed"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"speed"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); // same tests, just put the bigger overlapping token first - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"foo"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"foo"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"10"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"10"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"hi"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"speed"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"speed"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); - query = newLucene(HighlighterTestFixture::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - BOOST_CHECK_EQUAL(L"Hi-Speed10 foo", result); + EXPECT_EQ(L"Hi-Speed10 foo", result); } - + TokenStreamPtr getTS2() { return newLucene(); } - + TokenStreamPtr getTS2a() { return newLucene(); @@ -2429,17 +2427,15 @@ namespace TestOverlapAnalyzer2 }; } -BOOST_AUTO_TEST_CASE(testOverlapAnalyzer2) +TEST_F(HighlighterTest, testOverlapAnalyzer2) { - TestHighlightRunnerPtr helper = newLucene(this); + HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -BOOST_AUTO_TEST_CASE(testWeightedTermsWithDeletes) +TEST_F(HighlighterTest, testWeightedTermsWithDeletes) { makeIndex(); deleteDocument(); searchIndex(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/memory/MemoryIndexTest.cpp b/src/test/contrib/memory/MemoryIndexTest.cpp index 50c1ff8c..a4745178 100644 --- a/src/test/contrib/memory/MemoryIndexTest.cpp +++ b/src/test/contrib/memory/MemoryIndexTest.cpp @@ -29,10 +29,10 @@ using namespace Lucene; /// Verifies that Lucene MemoryIndex and RAMDirectory have the same behaviour, /// returning the same results for queries on some randomish indexes. -class MemoryIndexTestFixture : public BaseTokenStreamFixture +class MemoryIndexTest : public BaseTokenStreamFixture { public: - MemoryIndexTestFixture() + MemoryIndexTest() { fileDir = FileUtils::joinPath(getTestDir(), L"memory"); queries = HashSet::newInstance(); @@ -42,9 +42,9 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture queries.addAll(test2.begin(), test2.end()); random = newLucene(123); buffer = CharArray::newInstance(20); - - /// Some terms to be indexed, in addition to random words. - /// These terms are commonly used in the queries. + + /// Some terms to be indexed, in addition to random words. + /// These terms are commonly used in the queries. TEST_TERMS = Collection::newInstance(); TEST_TERMS.add(L"term"); TEST_TERMS.add(L"tErm"); @@ -69,8 +69,8 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture TEST_TERMS.add(L"copyright"); TEST_TERMS.add(L"Copyright"); } - - virtual ~MemoryIndexTestFixture() + + virtual ~MemoryIndexTest() { } @@ -79,10 +79,10 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture HashSet queries; RandomPtr random; CharArray buffer; - + static const int32_t ITERATIONS; Collection TEST_TERMS; - + public: /// read a set of queries from a resource file HashSet readQueries(const String& resource) @@ -97,26 +97,26 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture queries.add(line); } reader->close(); - + return queries; } - + /// Build a randomish document for both RAMDirectory and MemoryIndex, and run all the queries against it. void checkAgainstRAMDirectory() { StringStream fooField; StringStream termField; - + // add up to 250 terms to field "foo" int32_t fieldCount = random->nextInt(250) + 1; for (int32_t i = 0; i < fieldCount; ++i) fooField << L" " << randomTerm(); - + // add up to 250 terms to field "foo" int32_t termCount = random->nextInt(250) + 1; for (int32_t i = 0; i < termCount; ++i) termField << L" " << randomTerm(); - + RAMDirectoryPtr ramdir = newLucene(); AnalyzerPtr analyzer = randomAnalyzer(); IndexWriterPtr writer = newLucene(ramdir, analyzer, IndexWriter::MaxFieldLengthUNLIMITED); @@ -131,9 +131,9 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture MemoryIndexPtr memory = newLucene(); memory->addField(L"foo", fooField.str(), analyzer); memory->addField(L"term", termField.str(), analyzer); - checkAllQueries(memory, ramdir, analyzer); + checkAllQueries(memory, ramdir, analyzer); } - + void checkAllQueries(MemoryIndexPtr memory, RAMDirectoryPtr ramdir, AnalyzerPtr analyzer) { IndexSearcherPtr ram = newLucene(ramdir); @@ -143,10 +143,10 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture { TopDocsPtr ramDocs = ram->search(qp->parse(*query), 1); TopDocsPtr memDocs = mem->search(qp->parse(*query), 1); - BOOST_CHECK_EQUAL(ramDocs->totalHits, memDocs->totalHits); + EXPECT_EQ(ramDocs->totalHits, memDocs->totalHits); } } - + AnalyzerPtr randomAnalyzer() { switch (random->nextInt(3)) @@ -159,7 +159,7 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture return newLucene(LuceneVersion::LUCENE_CURRENT); } } - + /// half of the time, returns a random term from TEST_TERMS. /// the other half of the time, returns a random unicode string. String randomTerm() @@ -175,14 +175,14 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture return randomString(); } } - + /// Return a random unicode term, like StressIndexingTest. String randomString() { int32_t end = random->nextInt(20); if (buffer.size() < 1 + end) buffer.resize((int32_t)((double)(1 + end) * 1.25)); - + for (int32_t i = 0; i < end; ++i) { int32_t t = random->nextInt(5); @@ -209,7 +209,7 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture } return String(buffer.get(), end); } - + /// start is inclusive and end is exclusive int32_t nextInt(int32_t start, int32_t end) { @@ -217,15 +217,11 @@ class MemoryIndexTestFixture : public BaseTokenStreamFixture } }; -const int32_t MemoryIndexTestFixture::ITERATIONS = 100; - -BOOST_FIXTURE_TEST_SUITE(MemoryIndexTest, MemoryIndexTestFixture) +const int32_t MemoryIndexTest::ITERATIONS = 100; /// runs random tests, up to ITERATIONS times. -BOOST_AUTO_TEST_CASE(testRandomQueries) +TEST_F(MemoryIndexTest, testRandomQueries) { for (int32_t i = 0; i < ITERATIONS; ++i) checkAgainstRAMDirectory(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/contrib/snowball/SnowballTest.cpp b/src/test/contrib/snowball/SnowballTest.cpp index 5149da56..37cc7e3c 100644 --- a/src/test/contrib/snowball/SnowballTest.cpp +++ b/src/test/contrib/snowball/SnowballTest.cpp @@ -11,26 +11,24 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SnowballTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture SnowballTest; -BOOST_AUTO_TEST_CASE(testEnglish) +TEST_F(SnowballTest, testEnglish) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, L"english"); checkAnalyzesTo(a, L"he abhorred accents", newCollection(L"he", L"abhor", L"accent")); } -BOOST_AUTO_TEST_CASE(testStopwords) +TEST_F(SnowballTest, testStopwords) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, L"english", StopAnalyzer::ENGLISH_STOP_WORDS_SET()); checkAnalyzesTo(a, L"the quick brown fox jumped", newCollection(L"quick", L"brown", L"fox", L"jump")); } -BOOST_AUTO_TEST_CASE(testReusableTokenStream) +TEST_F(SnowballTest, testReusableTokenStream) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, L"english"); - + checkAnalyzesToReuse(a, L"he abhorred accents", newCollection(L"he", L"abhor", L"accent")); checkAnalyzesToReuse(a, L"she abhorred him", newCollection(L"she", L"abhor", L"him")); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/document/BinaryDocumentTest.cpp b/src/test/document/BinaryDocumentTest.cpp index 05de12eb..b815cffb 100644 --- a/src/test/document/BinaryDocumentTest.cpp +++ b/src/test/document/BinaryDocumentTest.cpp @@ -16,21 +16,28 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BinaryDocumentTest, LuceneTestFixture) +typedef LuceneTestFixture BinaryDocumentTest; static String binaryValStored = L"this text will be stored as a byte array in the index"; static String binaryValCompressed = L"this text will be also stored and compressed as a byte array in the index"; -BOOST_AUTO_TEST_CASE(testBinaryFieldInIndex) +TEST_F(BinaryDocumentTest, testBinaryFieldInIndex) { ByteArray binaryStored = ByteArray::newInstance(binaryValStored.length() * sizeof(wchar_t)); std::wcsncpy((wchar_t*)binaryStored.get(), binaryValStored.c_str(), binaryValStored.length()); - + FieldablePtr binaryFldStored = newLucene(L"binaryStored", binaryStored, Field::STORE_YES); FieldablePtr stringFldStored = newLucene(L"stringStored", binaryValStored, Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_NO); - + // binary fields with store off are not allowed - BOOST_CHECK_EXCEPTION(newLucene(L"fail", binaryStored, Field::STORE_NO), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + newLucene(L"fail", binaryStored, Field::STORE_NO); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } DocumentPtr doc = newLucene(); @@ -38,7 +45,7 @@ BOOST_AUTO_TEST_CASE(testBinaryFieldInIndex) doc->add(stringFldStored); // test for field count - BOOST_CHECK_EQUAL(2, doc->getFields().size()); + EXPECT_EQ(2, doc->getFields().size()); // add the doc to a ram index MockRAMDirectoryPtr dir = newLucene(); @@ -49,33 +56,33 @@ BOOST_AUTO_TEST_CASE(testBinaryFieldInIndex) // open a reader and fetch the document IndexReaderPtr reader = IndexReader::open(dir, false); DocumentPtr docFromReader = reader->document(0); - BOOST_CHECK(docFromReader); + EXPECT_TRUE(docFromReader); // fetch the binary stored field and compare it's content with the original one ByteArray storedTest = docFromReader->getBinaryValue(L"binaryStored"); String binaryFldStoredTest((wchar_t*)storedTest.get(), storedTest.size() / sizeof(wchar_t)); - BOOST_CHECK_EQUAL(binaryFldStoredTest, binaryValStored); + EXPECT_EQ(binaryFldStoredTest, binaryValStored); // fetch the string field and compare it's content with the original one String stringFldStoredTest = docFromReader->get(L"stringStored"); - BOOST_CHECK_EQUAL(stringFldStoredTest, binaryValStored); + EXPECT_EQ(stringFldStoredTest, binaryValStored); // delete the document from index reader->deleteDocument(0); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testCompressionTools) +TEST_F(BinaryDocumentTest, testCompressionTools) { ByteArray binaryCompressed = ByteArray::newInstance(binaryValCompressed.length() * sizeof(wchar_t)); std::wcsncpy((wchar_t*)binaryCompressed.get(), binaryValCompressed.c_str(), binaryValCompressed.length()); - + FieldablePtr binaryFldCompressed = newLucene(L"binaryCompressed", CompressionTools::compress(binaryCompressed), Field::STORE_YES); FieldablePtr stringFldCompressed = newLucene(L"stringCompressed", CompressionTools::compressString(binaryValCompressed), Field::STORE_YES); - + DocumentPtr doc = newLucene(); doc->add(binaryFldCompressed); @@ -90,17 +97,15 @@ BOOST_AUTO_TEST_CASE(testCompressionTools) // open a reader and fetch the document IndexReaderPtr reader = IndexReader::open(dir, false); DocumentPtr docFromReader = reader->document(0); - BOOST_CHECK(docFromReader); + EXPECT_TRUE(docFromReader); // fetch the binary compressed field and compare it's content with the original one ByteArray compressTest = CompressionTools::decompress(docFromReader->getBinaryValue(L"binaryCompressed")); String binaryFldCompressedTest((wchar_t*)compressTest.get(), compressTest.size() / sizeof(wchar_t)); - BOOST_CHECK_EQUAL(binaryFldCompressedTest, binaryValCompressed); - - BOOST_CHECK_EQUAL(CompressionTools::decompressString(docFromReader->getBinaryValue(L"stringCompressed")), binaryValCompressed); + EXPECT_EQ(binaryFldCompressedTest, binaryValCompressed); + + EXPECT_EQ(CompressionTools::decompressString(docFromReader->getBinaryValue(L"stringCompressed")), binaryValCompressed); reader->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/document/DateFieldTest.cpp b/src/test/document/DateFieldTest.cpp index e8f3ed96..023ba39e 100644 --- a/src/test/document/DateFieldTest.cpp +++ b/src/test/document/DateFieldTest.cpp @@ -10,31 +10,29 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DateFieldTest, LuceneTestFixture) +typedef LuceneTestFixture DateFieldTest; -BOOST_AUTO_TEST_CASE(testMinDate) +TEST_F(DateFieldTest, testMinDate) { - BOOST_CHECK_EQUAL(DateField::MIN_DATE_STRING(), L"000000000"); + EXPECT_EQ(DateField::MIN_DATE_STRING(), L"000000000"); } -BOOST_AUTO_TEST_CASE(testMaxDate) +TEST_F(DateFieldTest, testMaxDate) { - BOOST_CHECK_EQUAL(DateField::MAX_DATE_STRING(), L"zzzzzzzzz"); + EXPECT_EQ(DateField::MAX_DATE_STRING(), L"zzzzzzzzz"); } -BOOST_AUTO_TEST_CASE(testDateToString) +TEST_F(DateFieldTest, testDateToString) { - BOOST_CHECK_EQUAL(DateField::dateToString(boost::posix_time::ptime(boost::gregorian::date(2010, boost::gregorian::Jan, 14))), L"0g4erxmo0"); + EXPECT_EQ(DateField::dateToString(boost::posix_time::ptime(boost::gregorian::date(2010, boost::gregorian::Jan, 14))), L"0g4erxmo0"); } -BOOST_AUTO_TEST_CASE(testTimeToString) +TEST_F(DateFieldTest, testTimeToString) { - BOOST_CHECK_EQUAL(DateField::timeToString(1263427200000LL), L"0g4erxmo0"); + EXPECT_EQ(DateField::timeToString(1263427200000LL), L"0g4erxmo0"); } -BOOST_AUTO_TEST_CASE(testStringToTime) +TEST_F(DateFieldTest, testStringToTime) { - BOOST_CHECK_EQUAL(DateField::stringToTime(L"0g4erxmo0"), 1263427200000LL); + EXPECT_EQ(DateField::stringToTime(L"0g4erxmo0"), 1263427200000LL); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/document/DateToolsTest.cpp b/src/test/document/DateToolsTest.cpp index 8cba05b2..8e1e171e 100644 --- a/src/test/document/DateToolsTest.cpp +++ b/src/test/document/DateToolsTest.cpp @@ -14,86 +14,86 @@ using namespace Lucene; using namespace boost::posix_time; using namespace boost::gregorian; -BOOST_FIXTURE_TEST_SUITE(DateToolsTest, LuceneTestFixture) +typedef LuceneTestFixture DateToolsTest; -BOOST_AUTO_TEST_CASE(testDateToString) +TEST_F(DateToolsTest, testDateToString) { - BOOST_CHECK_EQUAL(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_YEAR), L"2010"); - BOOST_CHECK_EQUAL(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_MONTH), L"201001"); - BOOST_CHECK_EQUAL(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_DAY), L"20100114"); - BOOST_CHECK_EQUAL(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5)), DateTools::RESOLUTION_HOUR), L"2010011403"); - BOOST_CHECK_EQUAL(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5)), DateTools::RESOLUTION_MINUTE), L"201001140341"); - BOOST_CHECK_EQUAL(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5)), DateTools::RESOLUTION_SECOND), L"20100114034105"); - BOOST_CHECK_EQUAL(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MILLISECOND), L"20100114034105123"); + EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_YEAR), L"2010"); + EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_MONTH), L"201001"); + EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_DAY), L"20100114"); + EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5)), DateTools::RESOLUTION_HOUR), L"2010011403"); + EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5)), DateTools::RESOLUTION_MINUTE), L"201001140341"); + EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5)), DateTools::RESOLUTION_SECOND), L"20100114034105"); + EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MILLISECOND), L"20100114034105123"); } -BOOST_AUTO_TEST_CASE(testTimeToString) +TEST_F(DateToolsTest, testTimeToString) { - BOOST_CHECK_EQUAL(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_YEAR), L"2010"); - BOOST_CHECK_EQUAL(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_MONTH), L"201001"); - BOOST_CHECK_EQUAL(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_DAY), L"20100114"); - BOOST_CHECK_EQUAL(DateTools::timeToString(1263440465000LL, DateTools::RESOLUTION_HOUR), L"2010011403"); - BOOST_CHECK_EQUAL(DateTools::timeToString(1263440465000LL, DateTools::RESOLUTION_MINUTE), L"201001140341"); - BOOST_CHECK_EQUAL(DateTools::timeToString(1263440465000LL, DateTools::RESOLUTION_SECOND), L"20100114034105"); - BOOST_CHECK_EQUAL(DateTools::timeToString(1263440465123LL, DateTools::RESOLUTION_MILLISECOND), L"20100114034105123"); + EXPECT_EQ(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_YEAR), L"2010"); + EXPECT_EQ(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_MONTH), L"201001"); + EXPECT_EQ(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_DAY), L"20100114"); + EXPECT_EQ(DateTools::timeToString(1263440465000LL, DateTools::RESOLUTION_HOUR), L"2010011403"); + EXPECT_EQ(DateTools::timeToString(1263440465000LL, DateTools::RESOLUTION_MINUTE), L"201001140341"); + EXPECT_EQ(DateTools::timeToString(1263440465000LL, DateTools::RESOLUTION_SECOND), L"20100114034105"); + EXPECT_EQ(DateTools::timeToString(1263440465123LL, DateTools::RESOLUTION_MILLISECOND), L"20100114034105123"); } -BOOST_AUTO_TEST_CASE(testStringToTime) +TEST_F(DateToolsTest, testStringToTime) { - BOOST_CHECK_EQUAL(DateTools::stringToTime(L"2010"), 1262304000000LL); - BOOST_CHECK_EQUAL(DateTools::stringToTime(L"201001"), 1262304000000LL); - BOOST_CHECK_EQUAL(DateTools::stringToTime(L"20100114"), 1263427200000LL); - BOOST_CHECK_EQUAL(DateTools::stringToTime(L"2010011403"), 1263438000000LL); - BOOST_CHECK_EQUAL(DateTools::stringToTime(L"201001140341"), 1263440460000LL); - BOOST_CHECK_EQUAL(DateTools::stringToTime(L"20100114034105"), 1263440465000LL); - BOOST_CHECK_EQUAL(DateTools::stringToTime(L"20100114034105123"), 1263440465123LL); + EXPECT_EQ(DateTools::stringToTime(L"2010"), 1262304000000LL); + EXPECT_EQ(DateTools::stringToTime(L"201001"), 1262304000000LL); + EXPECT_EQ(DateTools::stringToTime(L"20100114"), 1263427200000LL); + EXPECT_EQ(DateTools::stringToTime(L"2010011403"), 1263438000000LL); + EXPECT_EQ(DateTools::stringToTime(L"201001140341"), 1263440460000LL); + EXPECT_EQ(DateTools::stringToTime(L"20100114034105"), 1263440465000LL); + EXPECT_EQ(DateTools::stringToTime(L"20100114034105123"), 1263440465123LL); } -BOOST_AUTO_TEST_CASE(testDateRound) +TEST_F(DateToolsTest, testDateRound) { - BOOST_CHECK_EQUAL(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_YEAR), ptime(date(2010, Jan, 1))); - BOOST_CHECK_EQUAL(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MONTH), ptime(date(2010, Feb, 1))); - BOOST_CHECK_EQUAL(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_DAY), ptime(date(2010, Feb, 16))); - BOOST_CHECK_EQUAL(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_HOUR), ptime(date(2010, Feb, 16), hours(3))); - BOOST_CHECK_EQUAL(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MINUTE), ptime(date(2010, Feb, 16), hours(3) + minutes(41))); - BOOST_CHECK_EQUAL(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_SECOND), ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5))); - BOOST_CHECK_EQUAL(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MILLISECOND), ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123))); + EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_YEAR), ptime(date(2010, Jan, 1))); + EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MONTH), ptime(date(2010, Feb, 1))); + EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_DAY), ptime(date(2010, Feb, 16))); + EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_HOUR), ptime(date(2010, Feb, 16), hours(3))); + EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MINUTE), ptime(date(2010, Feb, 16), hours(3) + minutes(41))); + EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_SECOND), ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5))); + EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MILLISECOND), ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123))); } -BOOST_AUTO_TEST_CASE(testParseDateGB) +TEST_F(DateToolsTest, testParseDateGB) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01122005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"011205"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/12/2005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/12/05"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/12/2005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/12/05"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/1/05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/Jan/05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/Jan/05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/Jan/2005"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01122005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"011205"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/12/2005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/12/05"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/12/2005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/12/05"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/1/05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/Jan/05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/Jan/05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/Jan/2005"), ptime(date(2005, 01, 01))); } -BOOST_AUTO_TEST_CASE(testParseDateUS) +TEST_F(DateToolsTest, testParseDateUS) { DateTools::setDateOrder(DateTools::DATEORDER_MDY); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12012005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"120105"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/01/2005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/01/05"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/1/2005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/1/05"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/1/05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"Jan/1/05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"Jan/01/05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"Jan/01/2005"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"12012005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"120105"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/01/2005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/01/05"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/1/2005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/1/05"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/1/05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"Jan/1/05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"Jan/01/05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"Jan/01/2005"), ptime(date(2005, 01, 01))); } -BOOST_AUTO_TEST_CASE(testParseDateLocale) +TEST_F(DateToolsTest, testParseDateLocale) { bool hasThisLocale = false; - + try { std::locale("en_GB.UTF-8"); @@ -106,16 +106,16 @@ BOOST_AUTO_TEST_CASE(testParseDateLocale) if (hasThisLocale) { DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01122005", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"011205", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/12/2005", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/12/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/12/2005", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/12/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/1/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/Jan/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/Jan/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01/Jan/2005", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01122005", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"011205", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/12/2005", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/12/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/12/2005", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/12/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/1/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/Jan/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/Jan/05", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01/Jan/2005", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); } try @@ -131,32 +131,30 @@ BOOST_AUTO_TEST_CASE(testParseDateLocale) if (hasThisLocale) { DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12012005", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"120105", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/01/2005", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/01/05", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/1/2005", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"12/1/05", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1/1/05", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"Jan/1/05", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"Jan/01/05", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"Jan/01/2005", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"12012005", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"120105", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/01/2005", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/01/05", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/1/2005", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"12/1/05", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1/1/05", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"Jan/1/05", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"Jan/01/05", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"Jan/01/2005", std::locale("en_US.UTF-8")), ptime(date(2005, 01, 01))); } } -BOOST_AUTO_TEST_CASE(testParseDateSeparator) +TEST_F(DateToolsTest, testParseDateSeparator) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01122005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"011205"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01-12-2005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01 12 05"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1.12.2005"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1.12.05"), ptime(date(2005, 12, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1 1 05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"1 Jan 05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01-Jan-05"), ptime(date(2005, 01, 01))); - BOOST_CHECK_EQUAL(DateTools::parseDate(L"01,Jan,2005"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01122005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"011205"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"01-12-2005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"01 12 05"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1.12.2005"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1.12.05"), ptime(date(2005, 12, 01))); + EXPECT_EQ(DateTools::parseDate(L"1 1 05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"1 Jan 05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01-Jan-05"), ptime(date(2005, 01, 01))); + EXPECT_EQ(DateTools::parseDate(L"01,Jan,2005"), ptime(date(2005, 01, 01))); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/document/DocumentTest.cpp b/src/test/document/DocumentTest.cpp index ae0b61f4..63b2a4f7 100644 --- a/src/test/document/DocumentTest.cpp +++ b/src/test/document/DocumentTest.cpp @@ -19,7 +19,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DocumentTest, LuceneTestFixture) +typedef LuceneTestFixture DocumentTest; static String binaryVal = L"this text will be stored as a byte array in the index"; static String binaryVal2 = L"this text will be also stored as a byte array in the index"; @@ -45,28 +45,28 @@ static void checkDocument(DocumentPtr doc, bool fromIndex) Collection unindexedFieldValues = doc->getValues(L"unindexed"); Collection unstoredFieldValues = doc->getValues(L"unstored"); - BOOST_CHECK_EQUAL(keywordFieldValues.size(), 2); - BOOST_CHECK_EQUAL(textFieldValues.size(), 2); - BOOST_CHECK_EQUAL(unindexedFieldValues.size(), 2); + EXPECT_EQ(keywordFieldValues.size(), 2); + EXPECT_EQ(textFieldValues.size(), 2); + EXPECT_EQ(unindexedFieldValues.size(), 2); // this test cannot work for documents retrieved from the index since unstored fields will obviously not be returned if (!fromIndex) - BOOST_CHECK_EQUAL(unstoredFieldValues.size(), 2); - - BOOST_CHECK_EQUAL(keywordFieldValues[0], L"test1"); - BOOST_CHECK_EQUAL(keywordFieldValues[1], L"test2"); - BOOST_CHECK_EQUAL(textFieldValues[0], L"test1"); - BOOST_CHECK_EQUAL(textFieldValues[1], L"test2"); - BOOST_CHECK_EQUAL(unindexedFieldValues[0], L"test1"); - BOOST_CHECK_EQUAL(unindexedFieldValues[1], L"test2"); + EXPECT_EQ(unstoredFieldValues.size(), 2); + + EXPECT_EQ(keywordFieldValues[0], L"test1"); + EXPECT_EQ(keywordFieldValues[1], L"test2"); + EXPECT_EQ(textFieldValues[0], L"test1"); + EXPECT_EQ(textFieldValues[1], L"test2"); + EXPECT_EQ(unindexedFieldValues[0], L"test1"); + EXPECT_EQ(unindexedFieldValues[1], L"test2"); // this test cannot work for documents retrieved from the index since unstored fields will obviously not be returned if (!fromIndex) { - BOOST_CHECK_EQUAL(unstoredFieldValues[0], L"test1"); - BOOST_CHECK_EQUAL(unstoredFieldValues[1], L"test2"); + EXPECT_EQ(unstoredFieldValues[0], L"test1"); + EXPECT_EQ(unstoredFieldValues[1], L"test2"); } } - -BOOST_AUTO_TEST_CASE(testBinaryField) + +TEST_F(DocumentTest, testBinaryField) { DocumentPtr doc = newLucene(); FieldablePtr stringFld = newLucene(L"string", binaryVal, Field::STORE_YES, Field::INDEX_NO); @@ -82,92 +82,106 @@ BOOST_AUTO_TEST_CASE(testBinaryField) doc->add(stringFld); doc->add(binaryFld); - BOOST_CHECK_EQUAL(2, doc->getFields().size()); + EXPECT_EQ(2, doc->getFields().size()); - BOOST_CHECK(binaryFld->isBinary()); - BOOST_CHECK(binaryFld->isStored()); - BOOST_CHECK(!binaryFld->isIndexed()); - BOOST_CHECK(!binaryFld->isTokenized()); + EXPECT_TRUE(binaryFld->isBinary()); + EXPECT_TRUE(binaryFld->isStored()); + EXPECT_TRUE(!binaryFld->isIndexed()); + EXPECT_TRUE(!binaryFld->isTokenized()); ByteArray bytesTest = doc->getBinaryValue(L"binary"); String binaryTest((wchar_t*)bytesTest.get(), bytesTest.size() / sizeof(wchar_t)); - BOOST_CHECK_EQUAL(binaryTest, binaryVal); + EXPECT_EQ(binaryTest, binaryVal); String stringTest = doc->get(L"string"); - BOOST_CHECK_EQUAL(binaryTest, stringTest); + EXPECT_EQ(binaryTest, stringTest); doc->add(binaryFld2); - BOOST_CHECK_EQUAL(3, doc->getFields().size()); + EXPECT_EQ(3, doc->getFields().size()); Collection binaryTests = doc->getBinaryValues(L"binary"); - BOOST_CHECK_EQUAL(2, binaryTests.size()); + EXPECT_EQ(2, binaryTests.size()); bytesTest = binaryTests[0]; binaryTest = String((wchar_t*)bytesTest.get(), bytesTest.size() / sizeof(wchar_t)); - + ByteArray bytesTest2 = binaryTests[1]; String binaryTest2((wchar_t*)bytesTest2.get(), bytesTest2.size() / sizeof(wchar_t)); - - BOOST_CHECK_NE(binaryTest, binaryTest2); - BOOST_CHECK_EQUAL(binaryTest, binaryVal); - BOOST_CHECK_EQUAL(binaryTest2, binaryVal2); + EXPECT_NE(binaryTest, binaryTest2); + + EXPECT_EQ(binaryTest, binaryVal); + EXPECT_EQ(binaryTest2, binaryVal2); doc->removeField(L"string"); - BOOST_CHECK_EQUAL(2, doc->getFields().size()); + EXPECT_EQ(2, doc->getFields().size()); doc->removeFields(L"binary"); - BOOST_CHECK_EQUAL(0, doc->getFields().size()); + EXPECT_EQ(0, doc->getFields().size()); } /// Tests {@link Document#removeField(String)} method for a brand new Document that has not been indexed yet. -BOOST_AUTO_TEST_CASE(testRemoveForNewDocument) +TEST_F(DocumentTest, testRemoveForNewDocument) { DocumentPtr doc = makeDocumentWithFields(); - BOOST_CHECK_EQUAL(8, doc->getFields().size()); + EXPECT_EQ(8, doc->getFields().size()); doc->removeFields(L"keyword"); - BOOST_CHECK_EQUAL(6, doc->getFields().size()); + EXPECT_EQ(6, doc->getFields().size()); doc->removeFields(L"doesnotexists"); // removing non-existing fields is silently ignored doc->removeFields(L"keyword"); // removing a field more than once - BOOST_CHECK_EQUAL(6, doc->getFields().size()); + EXPECT_EQ(6, doc->getFields().size()); doc->removeField(L"text"); - BOOST_CHECK_EQUAL(5, doc->getFields().size()); + EXPECT_EQ(5, doc->getFields().size()); doc->removeField(L"text"); - BOOST_CHECK_EQUAL(4, doc->getFields().size()); + EXPECT_EQ(4, doc->getFields().size()); doc->removeField(L"text"); - BOOST_CHECK_EQUAL(4, doc->getFields().size()); + EXPECT_EQ(4, doc->getFields().size()); doc->removeField(L"doesnotexists"); // removing non-existing fields is silently ignored - BOOST_CHECK_EQUAL(4, doc->getFields().size()); + EXPECT_EQ(4, doc->getFields().size()); doc->removeFields(L"unindexed"); - BOOST_CHECK_EQUAL(2, doc->getFields().size()); + EXPECT_EQ(2, doc->getFields().size()); doc->removeFields(L"unstored"); - BOOST_CHECK_EQUAL(0, doc->getFields().size()); + EXPECT_EQ(0, doc->getFields().size()); doc->removeFields(L"doesnotexists"); // removing non-existing fields is silently ignored - BOOST_CHECK_EQUAL(0, doc->getFields().size()); + EXPECT_EQ(0, doc->getFields().size()); } -BOOST_AUTO_TEST_CASE(testConstructorExceptions) +TEST_F(DocumentTest, testConstructorExceptions) { newLucene(L"name", L"value", Field::STORE_YES, Field::INDEX_NO); // ok newLucene(L"name", L"value", Field::STORE_NO, Field::INDEX_NOT_ANALYZED); // ok - - BOOST_CHECK_EXCEPTION(newLucene(L"name", L"value", Field::STORE_NO, Field::INDEX_NO), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); - + + try + { + newLucene(L"name", L"value", Field::STORE_NO, Field::INDEX_NO); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } + newLucene(L"name", L"value", Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_NO); // ok - - BOOST_CHECK_EXCEPTION(newLucene(L"name", L"value", Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_YES), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + + try + { + newLucene(L"name", L"value", Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_YES); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } /// Tests {@link Document#getValues(String)} method for a brand new Document that has not been indexed yet. -BOOST_AUTO_TEST_CASE(testGetValuesForNewDocument) +TEST_F(DocumentTest, testGetValuesForNewDocument) { checkDocument(makeDocumentWithFields(), false); } /// Tests {@link Document#getValues(String)} method for a Document retrieved from an index. -BOOST_AUTO_TEST_CASE(testGetValuesForIndexedDocument) +TEST_F(DocumentTest, testGetValuesForIndexedDocument) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -181,13 +195,13 @@ BOOST_AUTO_TEST_CASE(testGetValuesForIndexedDocument) // ensure that queries return expected results without DateFilter first Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); checkDocument(searcher->doc(hits[0]->doc), true); searcher->close(); } -BOOST_AUTO_TEST_CASE(testFieldSetValue) +TEST_F(DocumentTest, testFieldSetValue) { FieldPtr field = newLucene(L"id", L"id1", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); DocumentPtr doc = newLucene(); @@ -204,12 +218,12 @@ BOOST_AUTO_TEST_CASE(testFieldSetValue) writer->close(); SearcherPtr searcher = newLucene(dir, true); - + QueryPtr query = newLucene(newLucene(L"keyword", L"test")); // ensure that queries return expected results without DateFilter first Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); int32_t result = 0; for (int32_t i = 0; i < 3; ++i) { @@ -222,20 +236,33 @@ BOOST_AUTO_TEST_CASE(testFieldSetValue) else if (f->stringValue() == L"id3") result |= 4; else - BOOST_FAIL("unexpected id field"); + FAIL() << "unexpected id field"; } searcher->close(); dir->close(); - BOOST_CHECK_EQUAL(7, result); + EXPECT_EQ(7, result); } -BOOST_AUTO_TEST_CASE(testFieldSetValueChangeBinary) +TEST_F(DocumentTest, testFieldSetValueChangeBinary) { FieldPtr field1 = newLucene(L"field1", ByteArray::newInstance(0), Field::STORE_YES); FieldPtr field2 = newLucene(L"field2", L"", Field::STORE_YES, Field::INDEX_ANALYZED); - BOOST_CHECK_EXCEPTION(field1->setValue(L"abc"), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); - BOOST_CHECK_EXCEPTION(field2->setValue(ByteArray::newInstance(0)), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); -} + try + { + field1->setValue(L"abc"); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } -BOOST_AUTO_TEST_SUITE_END() + try + { + field2->setValue(ByteArray::newInstance(0)); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } +} diff --git a/src/test/document/NumberToolsTest.cpp b/src/test/document/NumberToolsTest.cpp index 7bc5f78f..115aa051 100644 --- a/src/test/document/NumberToolsTest.cpp +++ b/src/test/document/NumberToolsTest.cpp @@ -10,47 +10,61 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(NumberToolsTest, LuceneTestFixture) +typedef LuceneTestFixture NumberToolsTest; -BOOST_AUTO_TEST_CASE(testMinValue) +TEST_F(NumberToolsTest, testMinValue) { - BOOST_CHECK_EQUAL(NumberTools::MIN_STRING_VALUE(), L"-0000000000000"); + EXPECT_EQ(NumberTools::MIN_STRING_VALUE(), L"-0000000000000"); } -BOOST_AUTO_TEST_CASE(testMaxValue) +TEST_F(NumberToolsTest, testMaxValue) { - BOOST_CHECK_EQUAL(NumberTools::MAX_STRING_VALUE(), L"01y2p0ij32e8e7"); + EXPECT_EQ(NumberTools::MAX_STRING_VALUE(), L"01y2p0ij32e8e7"); } -BOOST_AUTO_TEST_CASE(testValueSize) +TEST_F(NumberToolsTest, testValueSize) { - BOOST_CHECK_EQUAL(NumberTools::STR_SIZE(), 14); + EXPECT_EQ(NumberTools::STR_SIZE(), 14); } -BOOST_AUTO_TEST_CASE(testLongToString) +TEST_F(NumberToolsTest, testLongToString) { - BOOST_CHECK_EQUAL(NumberTools::longToString(LLONG_MIN), L"-0000000000000"); - BOOST_CHECK_EQUAL(NumberTools::longToString(LLONG_MAX), L"01y2p0ij32e8e7"); - BOOST_CHECK_EQUAL(NumberTools::longToString(1LL), L"00000000000001"); - BOOST_CHECK_EQUAL(NumberTools::longToString(999LL), L"000000000000rr"); - BOOST_CHECK_EQUAL(NumberTools::longToString(34234LL), L"00000000000qey"); - BOOST_CHECK_EQUAL(NumberTools::longToString(4345325254LL), L"00000001zv3efa"); - BOOST_CHECK_EQUAL(NumberTools::longToString(986778657657575LL), L"00009ps7uuwdlz"); - BOOST_CHECK_EQUAL(NumberTools::longToString(23232143543434234LL), L"0006cr3vell8my"); + EXPECT_EQ(NumberTools::longToString(LLONG_MIN), L"-0000000000000"); + EXPECT_EQ(NumberTools::longToString(LLONG_MAX), L"01y2p0ij32e8e7"); + EXPECT_EQ(NumberTools::longToString(1LL), L"00000000000001"); + EXPECT_EQ(NumberTools::longToString(999LL), L"000000000000rr"); + EXPECT_EQ(NumberTools::longToString(34234LL), L"00000000000qey"); + EXPECT_EQ(NumberTools::longToString(4345325254LL), L"00000001zv3efa"); + EXPECT_EQ(NumberTools::longToString(986778657657575LL), L"00009ps7uuwdlz"); + EXPECT_EQ(NumberTools::longToString(23232143543434234LL), L"0006cr3vell8my"); } -BOOST_AUTO_TEST_CASE(testStringToLong) +TEST_F(NumberToolsTest, testStringToLong) { - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"-0000000000000"), LLONG_MIN); - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"01y2p0ij32e8e7"), LLONG_MAX); - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"00000000000001"), 1LL); - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"000000000000rr"), 999LL); - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"00000000000qey"), 34234LL); - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"00000001zv3efa"), 4345325254LL); - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"00009ps7uuwdlz"), 986778657657575LL); - BOOST_CHECK_EQUAL(NumberTools::stringToLong(L"0006cr3vell8my"), 23232143543434234LL); - BOOST_CHECK_EXCEPTION(NumberTools::stringToLong(L"32132"), LuceneException, check_exception(LuceneException::NumberFormat)); // wrong length - BOOST_CHECK_EXCEPTION(NumberTools::stringToLong(L"9006cr3vell8my"), LuceneException, check_exception(LuceneException::NumberFormat)); // wrong prefix -} + EXPECT_EQ(NumberTools::stringToLong(L"-0000000000000"), LLONG_MIN); + EXPECT_EQ(NumberTools::stringToLong(L"01y2p0ij32e8e7"), LLONG_MAX); + EXPECT_EQ(NumberTools::stringToLong(L"00000000000001"), 1LL); + EXPECT_EQ(NumberTools::stringToLong(L"000000000000rr"), 999LL); + EXPECT_EQ(NumberTools::stringToLong(L"00000000000qey"), 34234LL); + EXPECT_EQ(NumberTools::stringToLong(L"00000001zv3efa"), 4345325254LL); + EXPECT_EQ(NumberTools::stringToLong(L"00009ps7uuwdlz"), 986778657657575LL); + EXPECT_EQ(NumberTools::stringToLong(L"0006cr3vell8my"), 23232143543434234LL); + + try + { + NumberTools::stringToLong(L"32132"); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); // wrong length + } -BOOST_AUTO_TEST_SUITE_END() + try + { + NumberTools::stringToLong(L"9006cr3vell8my"); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); // wrong prefix + } +} diff --git a/src/test/include/LuceneGlobalFixture.h b/src/test/include/LuceneGlobalFixture.h index 3f10b8b5..1c28077d 100644 --- a/src/test/include/LuceneGlobalFixture.h +++ b/src/test/include/LuceneGlobalFixture.h @@ -8,7 +8,7 @@ namespace Lucene { - class LuceneGlobalFixture + class LuceneGlobalFixture : public testing::Environment { public: /// setup diff --git a/src/test/include/LuceneTestFixture.h b/src/test/include/LuceneTestFixture.h index 5fbfc956..cc0e4eb4 100644 --- a/src/test/include/LuceneTestFixture.h +++ b/src/test/include/LuceneTestFixture.h @@ -8,7 +8,7 @@ namespace Lucene { - class LuceneTestFixture + class LuceneTestFixture : public testing::Test { public: /// setup diff --git a/src/test/include/test_lucene.h b/src/test/include/test_lucene.h index 9af385c1..63f4cf79 100644 --- a/src/test/include/test_lucene.h +++ b/src/test/include/test_lucene.h @@ -10,7 +10,7 @@ #include "Lucene.h" #include "LuceneContrib.h" #include "StringUtils.h" -#include +#include namespace std { @@ -19,7 +19,7 @@ namespace std out << Lucene::StringUtils::toUTF8(s); return out; } -} +} namespace Lucene { @@ -31,9 +31,9 @@ namespace Lucene DECLARE_SHARED_PTR(MockRAMInputStream) DECLARE_SHARED_PTR(MockRAMOutputStream) DECLARE_SHARED_PTR(MockFilter) - + typedef HashMap MapStringField; - + struct check_exception { check_exception(LuceneException::ExceptionType type) : checkType(type) {} diff --git a/src/test/index/AddIndexesNoOptimizeTest.cpp b/src/test/index/AddIndexesNoOptimizeTest.cpp index 941a9e16..ba74b6ea 100644 --- a/src/test/index/AddIndexesNoOptimizeTest.cpp +++ b/src/test/index/AddIndexesNoOptimizeTest.cpp @@ -22,7 +22,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(AddIndexesNoOptimizeTest, LuceneTestFixture) +typedef LuceneTestFixture AddIndexesNoOptimizeTest; static IndexWriterPtr newWriter(DirectoryPtr dir, bool create) { @@ -54,8 +54,8 @@ static void addDocs2(IndexWriterPtr writer, int32_t numDocs) static void verifyNumDocs(DirectoryPtr dir, int32_t numDocs) { IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(reader->maxDoc(), numDocs); - BOOST_CHECK_EQUAL(reader->numDocs(), numDocs); + EXPECT_EQ(reader->maxDoc(), numDocs); + EXPECT_EQ(reader->numDocs(), numDocs); reader->close(); } @@ -66,7 +66,7 @@ static void verifyTermDocs(DirectoryPtr dir, TermPtr term, int32_t numDocs) int32_t count = 0; while (termDocs->next()) ++count; - BOOST_CHECK_EQUAL(count, numDocs); + EXPECT_EQ(count, numDocs); reader->close(); } @@ -78,8 +78,8 @@ static void setUpDirs(DirectoryPtr dir, DirectoryPtr aux) writer->setMaxBufferedDocs(1000); // add 1000 documents in 1 segment addDocs(writer, 1000); - BOOST_CHECK_EQUAL(1000, writer->maxDoc()); - BOOST_CHECK_EQUAL(1, writer->getSegmentCount()); + EXPECT_EQ(1000, writer->maxDoc()); + EXPECT_EQ(1, writer->getSegmentCount()); writer->close(); writer = newWriter(aux, true); @@ -96,12 +96,12 @@ static void setUpDirs(DirectoryPtr dir, DirectoryPtr aux) writer->setMaxBufferedDocs(100); writer->setMergeFactor(10); } - BOOST_CHECK_EQUAL(30, writer->maxDoc()); - BOOST_CHECK_EQUAL(3, writer->getSegmentCount()); + EXPECT_EQ(30, writer->maxDoc()); + EXPECT_EQ(3, writer->getSegmentCount()); writer->close(); } -BOOST_AUTO_TEST_CASE(testSimpleCase) +TEST_F(AddIndexesNoOptimizeTest, testSimpleCase) { // main directory DirectoryPtr dir = newLucene(); @@ -112,29 +112,29 @@ BOOST_AUTO_TEST_CASE(testSimpleCase) IndexWriterPtr writer = newWriter(dir, true); // add 100 documents addDocs(writer, 100); - BOOST_CHECK_EQUAL(writer->maxDoc(), 100); + EXPECT_EQ(writer->maxDoc(), 100); writer->close(); - + writer = newWriter(aux, true); writer->setUseCompoundFile(false); // use one without a compound file // add 40 documents in separate files addDocs(writer, 40); - BOOST_CHECK_EQUAL(writer->maxDoc(), 40); + EXPECT_EQ(writer->maxDoc(), 40); writer->close(); - + writer = newWriter(aux2, true); // add 40 documents in compound files addDocs2(writer, 50); - BOOST_CHECK_EQUAL(writer->maxDoc(), 50); + EXPECT_EQ(writer->maxDoc(), 50); writer->close(); // test doc count before segments are merged writer = newWriter(dir, false); - BOOST_CHECK_EQUAL(writer->maxDoc(), 100); + EXPECT_EQ(writer->maxDoc(), 100); writer->addIndexesNoOptimize(newCollection(aux, aux2)); - BOOST_CHECK_EQUAL(writer->maxDoc(), 190); + EXPECT_EQ(writer->maxDoc(), 190); writer->close(); - + // make sure the old index is correct verifyNumDocs(aux, 40); @@ -146,14 +146,14 @@ BOOST_AUTO_TEST_CASE(testSimpleCase) writer = newWriter(aux3, true); // add 40 documents addDocs(writer, 40); - BOOST_CHECK_EQUAL(writer->maxDoc(), 40); + EXPECT_EQ(writer->maxDoc(), 40); writer->close(); - + // test doc count before segments are merged/index is optimized writer = newWriter(dir, false); - BOOST_CHECK_EQUAL(writer->maxDoc(), 190); + EXPECT_EQ(writer->maxDoc(), 190); writer->addIndexesNoOptimize(newCollection(aux3)); - BOOST_CHECK_EQUAL(writer->maxDoc(), 230); + EXPECT_EQ(writer->maxDoc(), 230); writer->close(); // make sure the new index is correct @@ -182,9 +182,9 @@ BOOST_AUTO_TEST_CASE(testSimpleCase) writer->close(); writer = newWriter(dir, false); - BOOST_CHECK_EQUAL(writer->maxDoc(), 230); + EXPECT_EQ(writer->maxDoc(), 230); writer->addIndexesNoOptimize(newCollection(aux4)); - BOOST_CHECK_EQUAL(writer->maxDoc(), 231); + EXPECT_EQ(writer->maxDoc(), 231); writer->close(); verifyNumDocs(dir, 231); @@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(testSimpleCase) verifyTermDocs(dir, newLucene(L"content", L"bbb"), 51); } -BOOST_AUTO_TEST_CASE(testWithPendingDeletes) +TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes) { // main directory DirectoryPtr dir = newLucene(); @@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(testWithPendingDeletes) setUpDirs(dir, aux); IndexWriterPtr writer = newWriter(dir, false); writer->addIndexesNoOptimize(newCollection(aux)); - + // Adds 10 docs, then replaces them with another 10 docs, so 10 pending deletes for (int32_t i = 0; i < 20; ++i) { @@ -230,16 +230,16 @@ BOOST_AUTO_TEST_CASE(testWithPendingDeletes) aux->close(); } -BOOST_AUTO_TEST_CASE(testWithPendingDeletes2) +TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes2) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory DirectoryPtr aux = newLucene(); - + setUpDirs(dir, aux); IndexWriterPtr writer = newWriter(dir, false); - + // Adds 10 docs, then replaces them with another 10 docs, so 10 pending deletes for (int32_t i = 0; i < 20; ++i) { @@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE(testWithPendingDeletes2) doc->add(newLucene(L"content", L"bbb " + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->updateDocument(newLucene(L"id", StringUtils::toString(i % 10)), doc); } - + writer->addIndexesNoOptimize(newCollection(aux)); // Deletes one of the 10 added docs, leaving 9 @@ -269,16 +269,16 @@ BOOST_AUTO_TEST_CASE(testWithPendingDeletes2) aux->close(); } -BOOST_AUTO_TEST_CASE(testWithPendingDeletes3) +TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes3) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory DirectoryPtr aux = newLucene(); - + setUpDirs(dir, aux); IndexWriterPtr writer = newWriter(dir, false); - + // Adds 10 docs, then replaces them with another 10 docs, so 10 pending deletes for (int32_t i = 0; i < 20; ++i) { @@ -293,7 +293,7 @@ BOOST_AUTO_TEST_CASE(testWithPendingDeletes3) q->add(newLucene(L"content", L"bbb")); q->add(newLucene(L"content", L"14")); writer->deleteDocuments(q); - + writer->addIndexesNoOptimize(newCollection(aux)); writer->optimize(); @@ -308,17 +308,17 @@ BOOST_AUTO_TEST_CASE(testWithPendingDeletes3) aux->close(); } -BOOST_AUTO_TEST_CASE(testAddSelf) +TEST_F(AddIndexesNoOptimizeTest, testAddSelf) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory DirectoryPtr aux = newLucene(); - + IndexWriterPtr writer = newWriter(dir, true); // add 100 documents addDocs(writer, 100); - BOOST_CHECK_EQUAL(100, writer->maxDoc()); + EXPECT_EQ(100, writer->maxDoc()); writer->close(); writer = newWriter(aux, true); @@ -332,13 +332,20 @@ BOOST_AUTO_TEST_CASE(testAddSelf) writer->setMaxBufferedDocs(1000); addDocs(writer, 100); writer->close(); - + writer = newWriter(dir, false); - BOOST_CHECK_EXCEPTION(writer->addIndexesNoOptimize(newCollection(aux, dir)), LuceneException, check_exception(LuceneException::IllegalArgument)); // cannot add self - BOOST_CHECK_EQUAL(100, writer->maxDoc()); + try + { + writer->addIndexesNoOptimize(newCollection(aux, dir)); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); // cannot add self + } + EXPECT_EQ(100, writer->maxDoc()); writer->close(); - + // make sure the index is correct verifyNumDocs(dir, 100); @@ -346,7 +353,7 @@ BOOST_AUTO_TEST_CASE(testAddSelf) aux->close(); } -BOOST_AUTO_TEST_CASE(testNoTailSegments) +TEST_F(AddIndexesNoOptimizeTest, testNoTailSegments) { // main directory DirectoryPtr dir = newLucene(); @@ -361,10 +368,10 @@ BOOST_AUTO_TEST_CASE(testNoTailSegments) addDocs(writer, 10); writer->addIndexesNoOptimize(newCollection(aux)); - - BOOST_CHECK_EQUAL(1040, writer->maxDoc()); - BOOST_CHECK_EQUAL(2, writer->getSegmentCount()); - BOOST_CHECK_EQUAL(1000, writer->getDocCount(0)); + + EXPECT_EQ(1040, writer->maxDoc()); + EXPECT_EQ(2, writer->getSegmentCount()); + EXPECT_EQ(1000, writer->getDocCount(0)); writer->close(); // make sure the index is correct @@ -374,7 +381,7 @@ BOOST_AUTO_TEST_CASE(testNoTailSegments) aux->close(); } -BOOST_AUTO_TEST_CASE(testNoCopySegments) +TEST_F(AddIndexesNoOptimizeTest, testNoCopySegments) { // main directory DirectoryPtr dir = newLucene(); @@ -389,10 +396,10 @@ BOOST_AUTO_TEST_CASE(testNoCopySegments) addDocs(writer, 2); writer->addIndexesNoOptimize(newCollection(aux)); - - BOOST_CHECK_EQUAL(1032, writer->maxDoc()); - BOOST_CHECK_EQUAL(2, writer->getSegmentCount()); - BOOST_CHECK_EQUAL(1000, writer->getDocCount(0)); + + EXPECT_EQ(1032, writer->maxDoc()); + EXPECT_EQ(2, writer->getSegmentCount()); + EXPECT_EQ(1000, writer->getDocCount(0)); writer->close(); // make sure the index is correct @@ -402,7 +409,7 @@ BOOST_AUTO_TEST_CASE(testNoCopySegments) aux->close(); } -BOOST_AUTO_TEST_CASE(testNoMergeAfterCopy) +TEST_F(AddIndexesNoOptimizeTest, testNoMergeAfterCopy) { // main directory DirectoryPtr dir = newLucene(); @@ -416,9 +423,9 @@ BOOST_AUTO_TEST_CASE(testNoMergeAfterCopy) writer->setMergeFactor(4); writer->addIndexesNoOptimize(newCollection(aux, newLucene(aux))); - - BOOST_CHECK_EQUAL(1060, writer->maxDoc()); - BOOST_CHECK_EQUAL(1000, writer->getDocCount(0)); + + EXPECT_EQ(1060, writer->maxDoc()); + EXPECT_EQ(1000, writer->getDocCount(0)); writer->close(); // make sure the index is correct @@ -428,7 +435,7 @@ BOOST_AUTO_TEST_CASE(testNoMergeAfterCopy) aux->close(); } -BOOST_AUTO_TEST_CASE(testMergeAfterCopy) +TEST_F(AddIndexesNoOptimizeTest, testMergeAfterCopy) { // main directory DirectoryPtr dir = newLucene(); @@ -440,7 +447,7 @@ BOOST_AUTO_TEST_CASE(testMergeAfterCopy) IndexReaderPtr reader = IndexReader::open(aux, false); for (int32_t i = 0; i < 20; ++i) reader->deleteDocument(i); - BOOST_CHECK_EQUAL(10, reader->numDocs()); + EXPECT_EQ(10, reader->numDocs()); reader->close(); IndexWriterPtr writer = newWriter(dir, false); @@ -448,9 +455,9 @@ BOOST_AUTO_TEST_CASE(testMergeAfterCopy) writer->setMergeFactor(4); writer->addIndexesNoOptimize(newCollection(aux, newLucene(aux))); - - BOOST_CHECK_EQUAL(1020, writer->maxDoc()); - BOOST_CHECK_EQUAL(1000, writer->getDocCount(0)); + + EXPECT_EQ(1020, writer->maxDoc()); + EXPECT_EQ(1000, writer->getDocCount(0)); writer->close(); // make sure the index is correct @@ -460,7 +467,7 @@ BOOST_AUTO_TEST_CASE(testMergeAfterCopy) aux->close(); } -BOOST_AUTO_TEST_CASE(testMoreMerges) +TEST_F(AddIndexesNoOptimizeTest, testMoreMerges) { // main directory DirectoryPtr dir = newLucene(); @@ -475,33 +482,33 @@ BOOST_AUTO_TEST_CASE(testMoreMerges) writer->setMergeFactor(10); writer->addIndexesNoOptimize(newCollection(aux)); - - BOOST_CHECK_EQUAL(30, writer->maxDoc()); - BOOST_CHECK_EQUAL(3, writer->getSegmentCount()); + + EXPECT_EQ(30, writer->maxDoc()); + EXPECT_EQ(3, writer->getSegmentCount()); writer->close(); - + IndexReaderPtr reader = IndexReader::open(aux, false); for (int32_t i = 0; i < 27; ++i) reader->deleteDocument(i); - BOOST_CHECK_EQUAL(3, reader->numDocs()); + EXPECT_EQ(3, reader->numDocs()); reader->close(); - + reader = IndexReader::open(aux2, false); for (int32_t i = 0; i < 8; ++i) reader->deleteDocument(i); - BOOST_CHECK_EQUAL(22, reader->numDocs()); + EXPECT_EQ(22, reader->numDocs()); reader->close(); - + writer = newWriter(dir, false); writer->setMaxBufferedDocs(6); writer->setMergeFactor(4); - + writer->addIndexesNoOptimize(newCollection(aux, aux2)); - BOOST_CHECK_EQUAL(1025, writer->maxDoc()); - BOOST_CHECK_EQUAL(1000, writer->getDocCount(0)); + EXPECT_EQ(1025, writer->maxDoc()); + EXPECT_EQ(1000, writer->getDocCount(0)); writer->close(); - + // make sure the index is correct verifyNumDocs(dir, 1025); @@ -509,7 +516,7 @@ BOOST_AUTO_TEST_CASE(testMoreMerges) aux->close(); } -BOOST_AUTO_TEST_CASE(testHangOnClose) +TEST_F(AddIndexesNoOptimizeTest, testHangOnClose) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -520,21 +527,21 @@ BOOST_AUTO_TEST_CASE(testHangOnClose) DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - + for (int32_t i = 0; i < 60; ++i) writer->addDocument(doc); writer->setMaxBufferedDocs(200); DocumentPtr doc2 = newLucene(); - + doc2->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_NO)); doc2->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_NO)); doc2->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_NO)); doc2->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_NO)); - + for (int32_t i = 0; i < 60; ++i) writer->addDocument(doc2); writer->close(); - + DirectoryPtr dir2 = newLucene(); writer = newLucene(dir2, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); LogByteSizeMergePolicyPtr lmp = newLucene(writer); @@ -549,7 +556,7 @@ BOOST_AUTO_TEST_CASE(testHangOnClose) dir2->close(); } -BOOST_AUTO_TEST_CASE(testTargetCFS) +TEST_F(AddIndexesNoOptimizeTest, testTargetCFS) { // make sure CFS of destination indexwriter is respected when copying tail segments DirectoryPtr dir = newLucene(); @@ -562,8 +569,6 @@ BOOST_AUTO_TEST_CASE(testTargetCFS) writer = newWriter(other, true); writer->setUseCompoundFile(true); writer->addIndexesNoOptimize(newCollection(dir)); - BOOST_CHECK(writer->newestSegment()->getUseCompoundFile()); + EXPECT_TRUE(writer->newestSegment()->getUseCompoundFile()); writer->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/AtomicUpdateTest.cpp b/src/test/index/AtomicUpdateTest.cpp index 0f464208..0f8f227d 100644 --- a/src/test/index/AtomicUpdateTest.cpp +++ b/src/test/index/AtomicUpdateTest.cpp @@ -22,7 +22,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(AtomicUpdateTest, LuceneTestFixture) +typedef LuceneTestFixture AtomicUpdateTest; class MockIndexWriter : public IndexWriter { @@ -31,7 +31,7 @@ class MockIndexWriter : public IndexWriter { random = newLucene(); } - + virtual ~MockIndexWriter() { } @@ -48,37 +48,37 @@ class MockIndexWriter : public IndexWriter } }; -DECLARE_SHARED_PTR(TimedThread) -DECLARE_SHARED_PTR(IndexerThread) -DECLARE_SHARED_PTR(SearcherThread) +DECLARE_SHARED_PTR(AtomicTimedThread) +DECLARE_SHARED_PTR(AtomicIndexerThread) +DECLARE_SHARED_PTR(AtomicSearcherThread) -class TimedThread : public LuceneThread +class AtomicTimedThread : public LuceneThread { public: - TimedThread() + AtomicTimedThread() { this->failed = false; } - - virtual ~TimedThread() + + virtual ~AtomicTimedThread() { } - - LUCENE_CLASS(TimedThread); - + + LUCENE_CLASS(AtomicTimedThread); + public: bool failed; protected: static const int32_t RUN_TIME_SEC; - + public: virtual void doWork() = 0; - + virtual void run() { int64_t stopTime = MiscUtils::currentTimeMillis() + 1000 * RUN_TIME_SEC; - + try { while ((int64_t)MiscUtils::currentTimeMillis() < stopTime && !failed) @@ -87,30 +87,30 @@ class TimedThread : public LuceneThread catch (LuceneException& e) { failed = true; - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; -const int32_t TimedThread::RUN_TIME_SEC = 3; +const int32_t AtomicTimedThread::RUN_TIME_SEC = 3; -class IndexerThread : public TimedThread +class AtomicIndexerThread : public AtomicTimedThread { public: - IndexerThread(IndexWriterPtr writer) + AtomicIndexerThread(IndexWriterPtr writer) { this->writer = writer; } - - virtual ~IndexerThread() + + virtual ~AtomicIndexerThread() { } - - LUCENE_CLASS(IndexerThread); - + + LUCENE_CLASS(AtomicIndexerThread); + public: IndexWriterPtr writer; - + public: virtual void doWork() { @@ -125,29 +125,29 @@ class IndexerThread : public TimedThread } }; -class SearcherThread : public TimedThread +class AtomicSearcherThread : public AtomicTimedThread { public: - SearcherThread(DirectoryPtr directory) + AtomicSearcherThread(DirectoryPtr directory) { this->directory = directory; } - - virtual ~SearcherThread() + + virtual ~AtomicSearcherThread() { } - - LUCENE_CLASS(SearcherThread); - + + LUCENE_CLASS(AtomicSearcherThread); + protected: DirectoryPtr directory; - + public: virtual void doWork() { IndexReaderPtr r = IndexReader::open(directory, true); if (r->numDocs() != 100) - BOOST_FAIL("num docs failure"); + FAIL() << "num docs failure"; r->close(); } }; @@ -155,14 +155,14 @@ class SearcherThread : public TimedThread // Run one indexer and 2 searchers against single index as stress test. static void runTest(DirectoryPtr directory) { - Collection threads(Collection::newInstance(4)); + Collection threads(Collection::newInstance(4)); AnalyzerPtr analyzer = newLucene(); - + IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); - + writer->setMaxBufferedDocs(7); writer->setMergeFactor(3); - + // Establish a base index of 100 docs for (int32_t i = 0; i < 100; ++i) { @@ -174,42 +174,42 @@ static void runTest(DirectoryPtr directory) writer->addDocument(d); } writer->commit(); - + IndexReaderPtr r = IndexReader::open(directory, true); - BOOST_CHECK_EQUAL(100, r->numDocs()); + EXPECT_EQ(100, r->numDocs()); r->close(); - IndexerThreadPtr indexerThread1 = newLucene(writer); + AtomicIndexerThreadPtr indexerThread1 = newLucene(writer); threads[0] = indexerThread1; indexerThread1->start(); - IndexerThreadPtr indexerThread2 = newLucene(writer); + AtomicIndexerThreadPtr indexerThread2 = newLucene(writer); threads[1] = indexerThread2; indexerThread2->start(); - SearcherThreadPtr searcherThread1 = newLucene(directory); + AtomicSearcherThreadPtr searcherThread1 = newLucene(directory); threads[2] = searcherThread1; searcherThread1->start(); - SearcherThreadPtr searcherThread2 = newLucene(directory); + AtomicSearcherThreadPtr searcherThread2 = newLucene(directory); threads[3] = searcherThread2; searcherThread2->start(); - + indexerThread1->join(); indexerThread2->join(); searcherThread1->join(); searcherThread2->join(); - + writer->close(); - BOOST_CHECK(!indexerThread1->failed); // hit unexpected exception in indexer1 - BOOST_CHECK(!indexerThread2->failed); // hit unexpected exception in indexer2 - BOOST_CHECK(!searcherThread1->failed); // hit unexpected exception in search1 - BOOST_CHECK(!searcherThread2->failed); // hit unexpected exception in search2 + EXPECT_TRUE(!indexerThread1->failed); // hit unexpected exception in indexer1 + EXPECT_TRUE(!indexerThread2->failed); // hit unexpected exception in indexer2 + EXPECT_TRUE(!searcherThread1->failed); // hit unexpected exception in search1 + EXPECT_TRUE(!searcherThread2->failed); // hit unexpected exception in search2 } /// Run above stress test against RAMDirectory. -BOOST_AUTO_TEST_CASE(testAtomicUpdatesRAMDirectory) +TEST_F(AtomicUpdateTest, testAtomicUpdatesRAMDirectory) { DirectoryPtr directory = newLucene(); runTest(directory); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(testAtomicUpdatesRAMDirectory) } /// Run above stress test against FSDirectory -BOOST_AUTO_TEST_CASE(testAtomicUpdatesFSDirectory) +TEST_F(AtomicUpdateTest, testAtomicUpdatesFSDirectory) { String dirPath(getTempDir(L"lucene.test.atomic")); DirectoryPtr directory = FSDirectory::open(dirPath); @@ -225,5 +225,3 @@ BOOST_AUTO_TEST_CASE(testAtomicUpdatesFSDirectory) directory->close(); FileUtils::removeDirectory(dirPath); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/BackwardsCompatibilityTest.cpp b/src/test/index/BackwardsCompatibilityTest.cpp index 62979639..8f5d2a22 100644 --- a/src/test/index/BackwardsCompatibilityTest.cpp +++ b/src/test/index/BackwardsCompatibilityTest.cpp @@ -31,7 +31,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BackwardsCompatibilityTest, LuceneTestFixture) +typedef LuceneTestFixture BackwardsCompatibilityTest; /// Verify we can read the pre-2.1 file format, do searches against it, and add documents to it. @@ -50,17 +50,17 @@ static void addDoc(IndexWriterPtr writer, int32_t id) DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", StringUtils::toString(id), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - + const uint8_t utf8Field[] = {0x4c, 0x75, 0xf0, 0x9d, 0x84, 0x9e, 0x63, 0x65, 0xf0, 0x9d, 0x85, 0xa0, 0x6e, 0x65, 0x20, 0x00, 0x20, 0xe2, 0x98, 0xa0, 0x20, 0x61, 0x62, 0xf1, 0x95, 0xb0, 0x97, 0x63, 0x64}; - + const uint8_t utf8Field2[] = {0x66, 0x69, 0x65, 0xe2, 0xb1, 0xb7, 0x6c, 0x64}; - + doc->add(newLucene(L"autf8", UTF8_TO_STRING(utf8Field), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); doc->add(newLucene(L"utf8", UTF8_TO_STRING(utf8Field), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); doc->add(newLucene(L"content2", L"here is more content with aaa aaa aaa", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); doc->add(newLucene(UTF8_TO_STRING(utf8Field2), L"field with non-ascii name", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - + // add numeric fields, to test if flex preserves encoding doc->add(newLucene(L"trieInt", 4)->setIntValue(id)); doc->add(newLucene(L"trieLong", 4)->setLongValue(id)); @@ -93,7 +93,7 @@ static void createIndex(const String& dirName, bool doCFS) for (int32_t i = 0; i < 35; ++i) addDoc(writer, i); - BOOST_CHECK_EQUAL(35, writer->maxDoc()); + EXPECT_EQ(35, writer->maxDoc()); writer->close(); // open fresh writer so we get no prx file in the added segment @@ -107,7 +107,7 @@ static void createIndex(const String& dirName, bool doCFS) IndexReaderPtr reader = IndexReader::open(dir, false); TermPtr searchTerm = newLucene(L"id", L"7"); int32_t delCount = reader->deleteDocuments(searchTerm); - BOOST_CHECK_EQUAL(1, delCount); // delete the right number of documents + EXPECT_EQ(1, delCount); // delete the right number of documents // Set one norm so we get a .s0 file: reader->setNorm(21, L"content", 1.5); @@ -121,7 +121,7 @@ static void copyIndex(const String& dirName) FileUtils::copyDirectory(dirSource, dirDest); } -static const wchar_t* oldNames[] = +static const wchar_t* oldNames[] = { L"19.cfs", L"19.nocfs", @@ -148,9 +148,9 @@ namespace CheckCompressedFields virtual ~CompressedFieldSelector() { }; - + LUCENE_CLASS(CompressedFieldSelector); - + public: virtual FieldSelectorResult accept(const String& fieldName) { @@ -169,21 +169,21 @@ void checkCompressedFields29(DirectoryPtr dir, bool shouldStillBeCompressed) int32_t BINARY_PLAIN_LENGTH = SIZEOF_ARRAY(BINARY_TO_COMPRESS); IndexReaderPtr reader = IndexReader::open(dir, true); - + LuceneException finally; try { // look into sub readers and check if raw merge is on/off Collection readers = Collection::newInstance(); ReaderUtil::gatherSubReaders(readers, reader); - + for (Collection::iterator ir = readers.begin(); ir != readers.end(); ++ir) { FieldsReaderPtr fr = boost::dynamic_pointer_cast(*ir)->getFieldsReader(); // for a 2.9 index, FieldsReader.canReadRawDocs() must be false and other way round for a trunk index - BOOST_CHECK_NE(shouldStillBeCompressed, fr->canReadRawDocs()); + EXPECT_NE(shouldStillBeCompressed, fr->canReadRawDocs()); } - + // test that decompression works correctly for (int32_t i = 0; i < reader->maxDoc(); ++i) { @@ -196,17 +196,17 @@ void checkCompressedFields29(DirectoryPtr dir, bool shouldStillBeCompressed) FieldablePtr compressed = d->getFieldable(L"compressed"); if (StringUtils::toInt(d->get(L"id")) % 2 == 0) { - BOOST_CHECK(!compressed->isBinary()); - BOOST_CHECK_EQUAL(TEXT_TO_COMPRESS, compressed->stringValue()); // correctly decompressed string + EXPECT_TRUE(!compressed->isBinary()); + EXPECT_EQ(TEXT_TO_COMPRESS, compressed->stringValue()); // correctly decompressed string } else { - BOOST_CHECK(compressed->isBinary()); - BOOST_CHECK(std::memcmp(BINARY_TO_COMPRESS, compressed->getBinaryValue().get(), BINARY_PLAIN_LENGTH) == 0); // correctly decompressed binary + EXPECT_TRUE(compressed->isBinary()); + EXPECT_TRUE(std::memcmp(BINARY_TO_COMPRESS, compressed->getBinaryValue().get(), BINARY_PLAIN_LENGTH) == 0); // correctly decompressed binary } } } - + // check if field was decompressed after optimize for (int32_t i = 0; i < reader->maxDoc(); ++i) { @@ -222,13 +222,13 @@ void checkCompressedFields29(DirectoryPtr dir, bool shouldStillBeCompressed) int32_t compressedSize = StringUtils::toInt(d->get(L"compressedSize")); bool binary = (StringUtils::toInt(d->get(L"id")) % 2 > 0); int32_t shouldSize = shouldStillBeCompressed ? compressedSize : (binary ? BINARY_PLAIN_LENGTH : TEXT_PLAIN_LENGTH); - BOOST_CHECK_EQUAL(shouldSize, actualSize); + EXPECT_EQ(shouldSize, actualSize); if (!shouldStillBeCompressed) - BOOST_CHECK_NE(compressedSize, actualSize); - + EXPECT_NE(compressedSize, actualSize); + } } - BOOST_CHECK_EQUAL(34 * 2, count); // correct number of tests + EXPECT_EQ(34 * 2, count); // correct number of tests } catch (LuceneException& e) { @@ -241,7 +241,7 @@ void checkCompressedFields29(DirectoryPtr dir, bool shouldStillBeCompressed) static void testHits(Collection hits, int32_t expectedCount, IndexReaderPtr reader) { int32_t hitCount = hits.size(); - BOOST_CHECK_EQUAL(expectedCount, hitCount); + EXPECT_EQ(expectedCount, hitCount); for (int32_t i = 0; i < hitCount; ++i) { reader->document(hits[i]->doc); @@ -258,75 +258,75 @@ static void searchIndex(const String& dirName, const String& oldName) IndexReaderPtr reader = searcher->getIndexReader(); checkIndex(dir); - + const uint8_t utf8Field[] = {0x4c, 0x75, 0xf0, 0x9d, 0x84, 0x9e, 0x63, 0x65, 0xf0, 0x9d, 0x85, 0xa0, 0x6e, 0x65, 0x20, 0x00, 0x20, 0xe2, 0x98, 0xa0, 0x20, 0x61, 0x62, 0xf1, 0x95, 0xb0, 0x97, 0x63, 0x64}; - + const uint8_t utf8Field2[] = {0x66, 0x69, 0x65, 0xe2, 0xb1, 0xb7, 0x6c, 0x64}; - + const uint8_t utf8Lucene[] = {0x4c, 0x75, 0xf0, 0x9d, 0x84, 0x9e, 0x63, 0x65, 0xf0, 0x9d, 0x85, 0xa0, 0x6e, 0x65}; - + const uint8_t utf8Abcd[] = {0x61, 0x62, 0xf1, 0x95, 0xb0, 0x97, 0x63, 0x64}; const wchar_t _zeroField[] = {0x0000}; String zeroField(_zeroField, SIZEOF_ARRAY(_zeroField)); - + for (int32_t i = 0; i < 35; ++i) { if (!reader->isDeleted(i)) { DocumentPtr d = reader->document(i); Collection fields = d->getFields(); - if (!boost::starts_with(oldName, L"19.") && !boost::starts_with(oldName, L"20.") && + if (!boost::starts_with(oldName, L"19.") && !boost::starts_with(oldName, L"20.") && !boost::starts_with(oldName, L"21.") && !boost::starts_with(oldName, L"22.")) { if (!d->getField(L"content3")) { int32_t numFields = boost::starts_with(oldName, L"29.") ? 7 : 5; - BOOST_CHECK_EQUAL(numFields, fields.size()); - + EXPECT_EQ(numFields, fields.size()); + FieldPtr f = boost::dynamic_pointer_cast(d->getField(L"id")); - BOOST_CHECK_EQUAL(StringUtils::toString(i), f->stringValue()); - + EXPECT_EQ(StringUtils::toString(i), f->stringValue()); + f = boost::dynamic_pointer_cast(d->getField(L"utf8")); - BOOST_CHECK_EQUAL(UTF8_TO_STRING(utf8Field), f->stringValue()); - + EXPECT_EQ(UTF8_TO_STRING(utf8Field), f->stringValue()); + f = boost::dynamic_pointer_cast(d->getField(L"autf8")); - BOOST_CHECK_EQUAL(UTF8_TO_STRING(utf8Field), f->stringValue()); - + EXPECT_EQ(UTF8_TO_STRING(utf8Field), f->stringValue()); + f = boost::dynamic_pointer_cast(d->getField(L"content2")); - BOOST_CHECK_EQUAL(L"here is more content with aaa aaa aaa", f->stringValue()); - + EXPECT_EQ(L"here is more content with aaa aaa aaa", f->stringValue()); + f = boost::dynamic_pointer_cast(d->getField(UTF8_TO_STRING(utf8Field2))); - BOOST_CHECK_EQUAL(L"field with non-ascii name", f->stringValue()); + EXPECT_EQ(L"field with non-ascii name", f->stringValue()); } } } else { // Only ID 7 is deleted - BOOST_CHECK_EQUAL(7, i); + EXPECT_EQ(7, i); } } - + Collection hits = searcher->search(newLucene(newLucene(L"content", L"aaa")), FilterPtr(), 1000)->scoreDocs; - + // First document should be #21 since it's norm was increased DocumentPtr d = searcher->doc(hits[0]->doc); - BOOST_CHECK_EQUAL(L"21", d->get(L"id")); // get the right document first + EXPECT_EQ(L"21", d->get(L"id")); // get the right document first testHits(hits, 34, searcher->getIndexReader()); - - if (!boost::starts_with(oldName, L"19.") && !boost::starts_with(oldName, L"20.") && + + if (!boost::starts_with(oldName, L"19.") && !boost::starts_with(oldName, L"20.") && !boost::starts_with(oldName, L"21.") && !boost::starts_with(oldName, L"22.")) { // Test on indices >= 2.3 hits = searcher->search(newLucene(newLucene(L"utf8", zeroField)), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(34, hits.size()); + EXPECT_EQ(34, hits.size()); hits = searcher->search(newLucene(newLucene(L"utf8", UTF8_TO_STRING(utf8Lucene))), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(34, hits.size()); + EXPECT_EQ(34, hits.size()); hits = searcher->search(newLucene(newLucene(L"utf8", UTF8_TO_STRING(utf8Abcd))), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(34, hits.size()); + EXPECT_EQ(34, hits.size()); } searcher->close(); @@ -343,25 +343,25 @@ static void changeIndexNoAdds(const String& dirName) // make sure searching sees right # hits IndexSearcherPtr searcher = newLucene(dir, true); Collection hits = searcher->search(newLucene(newLucene(L"content", L"aaa")), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(34, hits.size()); // number of hits + EXPECT_EQ(34, hits.size()); // number of hits DocumentPtr d = searcher->doc(hits[0]->doc); - BOOST_CHECK_EQUAL(L"21", d->get(L"id")); // first document + EXPECT_EQ(L"21", d->get(L"id")); // first document searcher->close(); // make sure we can do a delete & setNorm against this pre-lockless segment IndexReaderPtr reader = IndexReader::open(dir, false); TermPtr searchTerm = newLucene(L"id", L"6"); int32_t delCount = reader->deleteDocuments(searchTerm); - BOOST_CHECK_EQUAL(1, delCount); // delete count + EXPECT_EQ(1, delCount); // delete count reader->setNorm(22, L"content", 2.0); reader->close(); // make sure they "took" searcher = newLucene(dir, true); hits = searcher->search(newLucene(newLucene(L"content", L"aaa")), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(33, hits.size()); // number of hits + EXPECT_EQ(33, hits.size()); // number of hits d = searcher->doc(hits[0]->doc); - BOOST_CHECK_EQUAL(L"22", d->get(L"id")); // first document + EXPECT_EQ(L"22", d->get(L"id")); // first document testHits(hits, 33, searcher->getIndexReader()); searcher->close(); @@ -372,9 +372,9 @@ static void changeIndexNoAdds(const String& dirName) searcher = newLucene(dir, true); hits = searcher->search(newLucene(newLucene(L"content", L"aaa")), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(33, hits.size()); // number of hits + EXPECT_EQ(33, hits.size()); // number of hits d = searcher->doc(hits[0]->doc); - BOOST_CHECK_EQUAL(L"22", d->get(L"id")); // first document + EXPECT_EQ(L"22", d->get(L"id")); // first document testHits(hits, 33, searcher->getIndexReader()); searcher->close(); @@ -400,14 +400,14 @@ static void changeIndexWithAdds(const String& dirName) int32_t dirNumber = StringUtils::toInt(dirName.substr(0, 2)); int32_t expected = dirNumber < 24 ? 45 : 46; - BOOST_CHECK_EQUAL(expected, writer->maxDoc()); // doc count + EXPECT_EQ(expected, writer->maxDoc()); // doc count writer->close(); // make sure searching sees right # hits IndexSearcherPtr searcher = newLucene(dir, true); Collection hits = searcher->search(newLucene(newLucene(L"content", L"aaa")), FilterPtr(), 1000)->scoreDocs; DocumentPtr d = searcher->doc(hits[0]->doc); - BOOST_CHECK_EQUAL(L"21", d->get(L"id")); // first document + EXPECT_EQ(L"21", d->get(L"id")); // first document testHits(hits, 44, searcher->getIndexReader()); searcher->close(); @@ -415,16 +415,16 @@ static void changeIndexWithAdds(const String& dirName) IndexReaderPtr reader = IndexReader::open(dir, false); TermPtr searchTerm = newLucene(L"id", L"6"); int32_t delCount = reader->deleteDocuments(searchTerm); - BOOST_CHECK_EQUAL(1, delCount); // delete count + EXPECT_EQ(1, delCount); // delete count reader->setNorm(22, L"content", 2.0); reader->close(); // make sure they "took" searcher = newLucene(dir, true); hits = searcher->search(newLucene(newLucene(L"content", L"aaa")), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(43, hits.size()); // number of hits + EXPECT_EQ(43, hits.size()); // number of hits d = searcher->doc(hits[0]->doc); - BOOST_CHECK_EQUAL(L"22", d->get(L"id")); // first document + EXPECT_EQ(L"22", d->get(L"id")); // first document testHits(hits, 43, searcher->getIndexReader()); searcher->close(); @@ -435,45 +435,45 @@ static void changeIndexWithAdds(const String& dirName) searcher = newLucene(dir, true); hits = searcher->search(newLucene(newLucene(L"content", L"aaa")), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(43, hits.size()); // number of hits + EXPECT_EQ(43, hits.size()); // number of hits d = searcher->doc(hits[0]->doc); testHits(hits, 43, searcher->getIndexReader()); - BOOST_CHECK_EQUAL(L"22", d->get(L"id")); // first document + EXPECT_EQ(L"22", d->get(L"id")); // first document searcher->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testCreateCFS) +TEST_F(BackwardsCompatibilityTest, testCreateCFS) { String dirName(L"testindex.cfs"); createIndex(dirName, true); rmDir(dirName); } -BOOST_AUTO_TEST_CASE(testCreateNoCFS) +TEST_F(BackwardsCompatibilityTest, testCreateNoCFS) { String dirName(L"testindex.nocfs"); createIndex(dirName, true); rmDir(dirName); } -BOOST_AUTO_TEST_CASE(testOptimizeOldIndex) +TEST_F(BackwardsCompatibilityTest, testOptimizeOldIndex) { int32_t hasTested29 = 0; - + for (int32_t i = 0; i < oldNamesLength; ++i) { copyIndex(oldNames[i]); String dirName(fullDir(oldNames[i])); DirectoryPtr dir = FSDirectory::open(dirName); - + if (boost::starts_with(oldNames[i], L"29.")) { checkCompressedFields29(dir, true); ++hasTested29; } - + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); w->optimize(); w->close(); @@ -489,11 +489,11 @@ BOOST_AUTO_TEST_CASE(testOptimizeOldIndex) dir->close(); rmDir(oldNames[i]); } - - BOOST_CHECK_EQUAL(4, hasTested29); // test for compressed field should have run 4 times + + EXPECT_EQ(4, hasTested29); // test for compressed field should have run 4 times } -BOOST_AUTO_TEST_CASE(testSearchOldIndex) +TEST_F(BackwardsCompatibilityTest, testSearchOldIndex) { for (int32_t i = 0; i < oldNamesLength; ++i) { @@ -504,7 +504,7 @@ BOOST_AUTO_TEST_CASE(testSearchOldIndex) } } -BOOST_AUTO_TEST_CASE(testIndexOldIndexNoAdds) +TEST_F(BackwardsCompatibilityTest, testIndexOldIndexNoAdds) { for (int32_t i = 0; i < oldNamesLength; ++i) { @@ -515,7 +515,7 @@ BOOST_AUTO_TEST_CASE(testIndexOldIndexNoAdds) } } -BOOST_AUTO_TEST_CASE(testIndexOldIndex) +TEST_F(BackwardsCompatibilityTest, testIndexOldIndex) { for (int32_t i = 0; i < oldNamesLength; ++i) { @@ -527,11 +527,11 @@ BOOST_AUTO_TEST_CASE(testIndexOldIndex) } // Verifies that the expected file names were produced -BOOST_AUTO_TEST_CASE(testExactFileNames) +TEST_F(BackwardsCompatibilityTest, testExactFileNames) { String outputDir = L"lucene.backwardscompat0.index"; rmDir(outputDir); - + LuceneException finally; try { @@ -539,18 +539,18 @@ BOOST_AUTO_TEST_CASE(testExactFileNames) IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setRAMBufferSizeMB(16.0); - + for (int32_t i = 0; i < 35; ++i) addDoc(writer, i); - - BOOST_CHECK_EQUAL(35, writer->maxDoc()); // doc count + + EXPECT_EQ(35, writer->maxDoc()); // doc count writer->close(); - + // Delete one doc so we get a .del file IndexReaderPtr reader = IndexReader::open(dir, false); TermPtr searchTerm = newLucene(L"id", L"7"); int32_t delCount = reader->deleteDocuments(searchTerm); - BOOST_CHECK_EQUAL(1, delCount); // delete the right number of documents + EXPECT_EQ(1, delCount); // delete the right number of documents // Set one norm so we get a .s0 file reader->setNorm(21, L"content", 1.5); @@ -559,7 +559,7 @@ BOOST_AUTO_TEST_CASE(testExactFileNames) CompoundFileReaderPtr cfsReader = newLucene(dir, L"_0.cfs"); FieldInfosPtr fieldInfos = newLucene(cfsReader, L"_0.fnm"); int32_t contentFieldIndex = -1; - + for (int32_t i = 0; i < fieldInfos->size(); ++i) { FieldInfoPtr fi = fieldInfos->fieldInfo(i); @@ -569,9 +569,9 @@ BOOST_AUTO_TEST_CASE(testExactFileNames) break; } } - + cfsReader->close(); - BOOST_CHECK_NE(contentFieldIndex, -1); // locate the 'content' field number in the _2.cfs segment + EXPECT_NE(contentFieldIndex, -1); // locate the 'content' field number in the _2.cfs segment // Now verify file names HashSet expected = HashSet::newInstance(); @@ -580,11 +580,11 @@ BOOST_AUTO_TEST_CASE(testExactFileNames) expected.add(L"_0_1.s" + StringUtils::toString(contentFieldIndex)); expected.add(L"segments_3"); expected.add(L"segments.gen"); - + HashSet actual = dir->listAll(); - - BOOST_CHECK_EQUAL(expected, actual); - + + EXPECT_EQ(expected, actual); + dir->close(); } catch (LuceneException& e) @@ -594,5 +594,3 @@ BOOST_AUTO_TEST_CASE(testExactFileNames) rmDir(outputDir); finally.throwException(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/ByteSlicesTest.cpp b/src/test/index/ByteSlicesTest.cpp index 1d41988b..389d0c2c 100644 --- a/src/test/index/ByteSlicesTest.cpp +++ b/src/test/index/ByteSlicesTest.cpp @@ -27,13 +27,13 @@ class TestByteBlockAllocator : public ByteBlockPoolAllocatorBase { this->freeByteBlocks = Collection::newInstance(); } - + virtual ~TestByteBlockAllocator() { } - + LUCENE_CLASS(TestByteBlockAllocator); - + public: Collection freeByteBlocks; @@ -52,14 +52,14 @@ class TestByteBlockAllocator : public ByteBlockPoolAllocatorBase b = freeByteBlocks.removeLast(); return b; } - + virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end) { SyncLock syncLock(this); for (int32_t i = start; i < end; ++i) freeByteBlocks.add(blocks[i]); } - + virtual void recycleByteBlocks(Collection blocks) { SyncLock syncLock(this); @@ -69,14 +69,14 @@ class TestByteBlockAllocator : public ByteBlockPoolAllocatorBase } }; -BOOST_FIXTURE_TEST_SUITE(ByteSlicesTest, LuceneTestFixture) +typedef LuceneTestFixture ByteSlicesTest; -BOOST_AUTO_TEST_CASE(testBasic) +TEST_F(ByteSlicesTest, testBasic) { ByteBlockPoolPtr pool = newLucene(newLucene(), false); - + int32_t NUM_STREAM = 25; - + ByteSliceWriterPtr writer = newLucene(pool); Collection starts = Collection::newInstance(NUM_STREAM); @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(testBasic) RandomPtr r = newLucene(); ByteSliceReaderPtr reader = newLucene(); - + for (int32_t ti = 0; ti < 100; ++ti) { for (int32_t stream = 0; stream < NUM_STREAM; ++stream) @@ -93,15 +93,15 @@ BOOST_AUTO_TEST_CASE(testBasic) starts[stream] = -1; counters[stream] = 0; } - + bool debug = false; - + for (int32_t iter = 0; iter < 10000; ++iter) { int32_t stream = r->nextInt(NUM_STREAM); if (debug) std::wcout << L"write stream=" << stream << L"\n"; - + if (starts[stream] == -1) { int32_t spot = pool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); @@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(testBasic) if (debug) std::wcout << L" init to " << starts[stream] << L"\n"; } - + writer->init(uptos[stream]); int32_t numValue = r->nextInt(20); for (int32_t j = 0; j < numValue; ++j) @@ -124,22 +124,20 @@ BOOST_AUTO_TEST_CASE(testBasic) if (debug) std::wcout << L" addr now " << uptos[stream] << L"\n"; } - + for (int32_t stream = 0; stream < NUM_STREAM; ++stream) { if (debug) std::wcout << L" stream=" << stream << L" count=" << counters[stream] << L"\n"; - + if (starts[stream] != uptos[stream]) { reader->init(pool, starts[stream], uptos[stream]); for (int32_t j = 0; j < counters[stream]; ++j) - BOOST_CHECK_EQUAL(j, reader->readVInt()); + EXPECT_EQ(j, reader->readVInt()); } } - + pool->reset(); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/CheckIndexTest.cpp b/src/test/index/CheckIndexTest.cpp index 5516d440..baaeb131 100644 --- a/src/test/index/CheckIndexTest.cpp +++ b/src/test/index/CheckIndexTest.cpp @@ -17,12 +17,12 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CheckIndexTest, LuceneTestFixture) +typedef LuceneTestFixture CheckIndexTest; -BOOST_AUTO_TEST_CASE(testDeletedDocs) +TEST_F(CheckIndexTest, testDeletedDocs) { MockRAMDirectoryPtr dir = newLucene(); - IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); @@ -32,42 +32,40 @@ BOOST_AUTO_TEST_CASE(testDeletedDocs) IndexReaderPtr reader = IndexReader::open(dir, false); reader->deleteDocument(5); reader->close(); - + CheckIndexPtr checker = newLucene(dir); IndexStatusPtr indexStatus = checker->checkIndex(); - BOOST_CHECK(indexStatus->clean); - + EXPECT_TRUE(indexStatus->clean); + SegmentInfoStatusPtr seg = indexStatus->segmentInfos[0]; - BOOST_CHECK(seg->openReaderPassed); - - BOOST_CHECK(seg->diagnostics); - - BOOST_CHECK(seg->fieldNormStatus); - BOOST_CHECK(seg->fieldNormStatus->error.isNull()); - BOOST_CHECK_EQUAL(1, seg->fieldNormStatus->totFields); + EXPECT_TRUE(seg->openReaderPassed); + + EXPECT_TRUE(seg->diagnostics); + + EXPECT_TRUE(seg->fieldNormStatus); + EXPECT_TRUE(seg->fieldNormStatus->error.isNull()); + EXPECT_EQ(1, seg->fieldNormStatus->totFields); - BOOST_CHECK(seg->termIndexStatus); - BOOST_CHECK(seg->termIndexStatus->error.isNull()); - BOOST_CHECK_EQUAL(1, seg->termIndexStatus->termCount); - BOOST_CHECK_EQUAL(19, seg->termIndexStatus->totFreq); - BOOST_CHECK_EQUAL(18, seg->termIndexStatus->totPos); + EXPECT_TRUE(seg->termIndexStatus); + EXPECT_TRUE(seg->termIndexStatus->error.isNull()); + EXPECT_EQ(1, seg->termIndexStatus->termCount); + EXPECT_EQ(19, seg->termIndexStatus->totFreq); + EXPECT_EQ(18, seg->termIndexStatus->totPos); - BOOST_CHECK(seg->storedFieldStatus); - BOOST_CHECK(seg->storedFieldStatus->error.isNull()); - BOOST_CHECK_EQUAL(18, seg->storedFieldStatus->docCount); - BOOST_CHECK_EQUAL(18, seg->storedFieldStatus->totFields); + EXPECT_TRUE(seg->storedFieldStatus); + EXPECT_TRUE(seg->storedFieldStatus->error.isNull()); + EXPECT_EQ(18, seg->storedFieldStatus->docCount); + EXPECT_EQ(18, seg->storedFieldStatus->totFields); + + EXPECT_TRUE(seg->termVectorStatus); + EXPECT_TRUE(seg->termVectorStatus->error.isNull()); + EXPECT_EQ(18, seg->termVectorStatus->docCount); + EXPECT_EQ(18, seg->termVectorStatus->totVectors); + + EXPECT_TRUE(!seg->diagnostics.empty()); - BOOST_CHECK(seg->termVectorStatus); - BOOST_CHECK(seg->termVectorStatus->error.isNull()); - BOOST_CHECK_EQUAL(18, seg->termVectorStatus->docCount); - BOOST_CHECK_EQUAL(18, seg->termVectorStatus->totVectors); - - BOOST_CHECK(!seg->diagnostics.empty()); - Collection onlySegments = Collection::newInstance(); onlySegments.add(L"_0"); - - BOOST_CHECK(checker->checkIndex(onlySegments)->clean); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_TRUE(checker->checkIndex(onlySegments)->clean); +} diff --git a/src/test/index/CompoundFileTest.cpp b/src/test/index/CompoundFileTest.cpp index 9379bf4e..f58b6100 100644 --- a/src/test/index/CompoundFileTest.cpp +++ b/src/test/index/CompoundFileTest.cpp @@ -19,19 +19,19 @@ using namespace Lucene; -class CompoundFileTestFixture : public LuceneTestFixture +class CompoundFileTest : public LuceneTestFixture { public: - CompoundFileTestFixture() + CompoundFileTest() { indexDir = FileUtils::joinPath(getTempDir(), L"testIndex"); FileUtils::removeDirectory(indexDir); - + // use a simple FSDir here, to be sure to have SimpleFSInputs dir = newLucene(indexDir); } - - virtual ~CompoundFileTestFixture() + + virtual ~CompoundFileTest() { dir->close(); FileUtils::removeDirectory(indexDir); @@ -51,7 +51,7 @@ class CompoundFileTestFixture : public LuceneTestFixture os->writeByte((uint8_t)r->nextInt(256)); os->close(); } - + void createSequenceFile(DirectoryPtr dir, const String& name, uint8_t start, int32_t size) { IndexOutputPtr os = dir->createOutput(name); @@ -62,14 +62,14 @@ class CompoundFileTestFixture : public LuceneTestFixture } os->close(); } - + void checkSameStreams(IndexInputPtr expected, IndexInputPtr test) { - BOOST_CHECK(expected); - BOOST_CHECK(test); - BOOST_CHECK_EQUAL(expected->length(), test->length()); - BOOST_CHECK_EQUAL(expected->getFilePointer(), test->getFilePointer()); - + EXPECT_TRUE(expected); + EXPECT_TRUE(test); + EXPECT_EQ(expected->length(), test->length()); + EXPECT_EQ(expected->getFilePointer(), test->getFilePointer()); + ByteArray expectedBuffer(ByteArray::newInstance(512)); ByteArray testBuffer(ByteArray::newInstance(expectedBuffer.size())); @@ -83,7 +83,7 @@ class CompoundFileTestFixture : public LuceneTestFixture remainder -= readLen; } } - + void checkSameStreams(IndexInputPtr expected, IndexInputPtr actual, int64_t seekTo) { if (seekTo >= 0 && seekTo < (int64_t)expected->length()) @@ -93,7 +93,7 @@ class CompoundFileTestFixture : public LuceneTestFixture checkSameStreams(expected, actual); } } - + void checkSameSeekBehavior(IndexInputPtr expected, IndexInputPtr actual) { // seek to 0 @@ -120,17 +120,17 @@ class CompoundFileTestFixture : public LuceneTestFixture point = expected->length() + 1; checkSameStreams(expected, actual, point); } - + void checkEqualArrays(ByteArray expected, ByteArray test, int32_t start, int32_t length) { - BOOST_CHECK(expected); - BOOST_CHECK(test); + EXPECT_TRUE(expected); + EXPECT_TRUE(test); for (int32_t i = start; i < length; ++i) - BOOST_CHECK_EQUAL(expected[i], test[i]); + EXPECT_EQ(expected[i], test[i]); } - - /// Setup a larger compound file with a number of components, each of which is a sequential file (so that we can - /// easily tell that we are reading in the right byte). The methods sets up 20 files - f0 to f19, the size of each + + /// Setup a larger compound file with a number of components, each of which is a sequential file (so that we can + /// easily tell that we are reading in the right byte). The methods sets up 20 files - f0 to f19, the size of each /// file is 1000 bytes. void setUpLarger() { @@ -142,7 +142,7 @@ class CompoundFileTestFixture : public LuceneTestFixture } cw->close(); } - + bool isCSIndexInputOpen(IndexInputPtr is) { if (MiscUtils::typeOf(is)) @@ -153,7 +153,7 @@ class CompoundFileTestFixture : public LuceneTestFixture else return false; } - + bool isSimpleFSIndexInputOpen(IndexInputPtr is) { if (MiscUtils::typeOf(is)) @@ -166,10 +166,8 @@ class CompoundFileTestFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(CompoundFileTest, CompoundFileTestFixture) - /// This test creates compound file based on a single file. Files of different sizes are tested: 0, 1, 10, 100 bytes. -BOOST_AUTO_TEST_CASE(testSingleFile) +TEST_F(CompoundFileTest, testSingleFile) { IntArray data(IntArray::newInstance(4)); data[0] = 0; @@ -196,7 +194,7 @@ BOOST_AUTO_TEST_CASE(testSingleFile) } /// This test creates compound file based on two files. -BOOST_AUTO_TEST_CASE(testTwoFiles) +TEST_F(CompoundFileTest, testTwoFiles) { createSequenceFile(dir, L"d1", 0, 15); createSequenceFile(dir, L"d2", 0, 114); @@ -223,10 +221,10 @@ BOOST_AUTO_TEST_CASE(testTwoFiles) csr->close(); } -/// This test creates a compound file based on a large number of files of various length. The file content is generated randomly. -/// The sizes range from 0 to 1Mb. Some of the sizes are selected to test the buffering logic in the file reading code. +/// This test creates a compound file based on a large number of files of various length. The file content is generated randomly. +/// The sizes range from 0 to 1Mb. Some of the sizes are selected to test the buffering logic in the file reading code. /// For this the chunk variable is set to the length of the buffer used internally by the compound file logic. -BOOST_AUTO_TEST_CASE(testRandomFiles) +TEST_F(CompoundFileTest, testRandomFiles) { // Setup the test segment String segment = L"test"; @@ -250,17 +248,17 @@ BOOST_AUTO_TEST_CASE(testRandomFiles) // Now test CompoundFileWriterPtr csw = newLucene(dir, L"test.cfs"); - + Collection data(Collection::newInstance()); data.add(L".zero"); data.add(L".one"); data.add(L".ten"); data.add(L".hundred"); data.add(L".big1"); data.add(L".big2"); data.add(L".big3"); data.add(L".big4"); data.add(L".big5"); data.add(L".big6"); data.add(L".big7"); - + for (Collection::iterator name = data.begin(); name != data.end(); ++name) csw->addFile(segment + *name); csw->close(); - + CompoundFileReaderPtr csr = newLucene(dir, L"test.cfs"); for (Collection::iterator name = data.begin(); name != data.end(); ++name) { @@ -274,7 +272,7 @@ BOOST_AUTO_TEST_CASE(testRandomFiles) csr->close(); } -BOOST_AUTO_TEST_CASE(testReadAfterClose) +TEST_F(CompoundFileTest, testReadAfterClose) { // Setup the test file - we need more than 1024 bytes IndexOutputPtr os = dir->createOutput(L"test"); @@ -295,28 +293,35 @@ BOOST_AUTO_TEST_CASE(testReadAfterClose) // ERROR: this call should fail, but succeeds for some reason as well in->seek(1099); - - BOOST_CHECK_EXCEPTION(in->readByte(), LuceneException, check_exception(LuceneException::IO)); + + try + { + in->readByte(); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } } -BOOST_AUTO_TEST_CASE(testClonedStreamsClosing) +TEST_F(CompoundFileTest, testClonedStreamsClosing) { setUpLarger(); - + CompoundFileReaderPtr cr = newLucene(dir, L"f.comp"); // basic clone IndexInputPtr expected = dir->openInput(L"f11"); // this test only works for FSIndexInput - BOOST_CHECK(MiscUtils::typeOf(expected)); - BOOST_CHECK(isSimpleFSIndexInputOpen(expected)); + EXPECT_TRUE(MiscUtils::typeOf(expected)); + EXPECT_TRUE(isSimpleFSIndexInputOpen(expected)); IndexInputPtr one = cr->openInput(L"f11"); - BOOST_CHECK(isCSIndexInputOpen(one)); + EXPECT_TRUE(isCSIndexInputOpen(one)); IndexInputPtr two = boost::dynamic_pointer_cast(one->clone()); - BOOST_CHECK(isCSIndexInputOpen(two)); + EXPECT_TRUE(isCSIndexInputOpen(two)); checkSameStreams(expected, one); expected->seek(0); @@ -324,9 +329,9 @@ BOOST_AUTO_TEST_CASE(testClonedStreamsClosing) // Now close the first stream one->close(); - BOOST_CHECK(isCSIndexInputOpen(one)); // Only close when cr is closed + EXPECT_TRUE(isCSIndexInputOpen(one)); // Only close when cr is closed - // The following should really fail since we couldn't expect to access a file once close has been called + // The following should really fail since we couldn't expect to access a file once close has been called // on it (regardless of buffering and/or clone magic) expected->seek(0); two->seek(0); @@ -334,8 +339,8 @@ BOOST_AUTO_TEST_CASE(testClonedStreamsClosing) // Now close the compound reader cr->close(); - BOOST_CHECK(!isCSIndexInputOpen(one)); - BOOST_CHECK(!isCSIndexInputOpen(two)); + EXPECT_TRUE(!isCSIndexInputOpen(one)); + EXPECT_TRUE(!isCSIndexInputOpen(two)); // The following may also fail since the compound stream is closed expected->seek(0); @@ -350,7 +355,7 @@ BOOST_AUTO_TEST_CASE(testClonedStreamsClosing) } /// This test opens two files from a compound stream and verifies that their file positions are independent of each other. -BOOST_AUTO_TEST_CASE(testRandomAccess) +TEST_F(CompoundFileTest, testRandomAccess) { setUpLarger(); @@ -366,60 +371,60 @@ BOOST_AUTO_TEST_CASE(testRandomAccess) // Seek the first pair e1->seek(100); a1->seek(100); - BOOST_CHECK_EQUAL(100, e1->getFilePointer()); - BOOST_CHECK_EQUAL(100, a1->getFilePointer()); + EXPECT_EQ(100, e1->getFilePointer()); + EXPECT_EQ(100, a1->getFilePointer()); uint8_t be1 = e1->readByte(); uint8_t ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); // Now seek the second pair e2->seek(1027); a2->seek(1027); - BOOST_CHECK_EQUAL(1027, e2->getFilePointer()); - BOOST_CHECK_EQUAL(1027, a2->getFilePointer()); + EXPECT_EQ(1027, e2->getFilePointer()); + EXPECT_EQ(1027, a2->getFilePointer()); uint8_t be2 = e2->readByte(); uint8_t ba2 = a2->readByte(); - BOOST_CHECK_EQUAL(be2, ba2); + EXPECT_EQ(be2, ba2); // Now make sure the first one didn't move - BOOST_CHECK_EQUAL(101, e1->getFilePointer()); - BOOST_CHECK_EQUAL(101, a1->getFilePointer()); + EXPECT_EQ(101, e1->getFilePointer()); + EXPECT_EQ(101, a1->getFilePointer()); be1 = e1->readByte(); ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); // Now more the first one again, past the buffer length e1->seek(1910); a1->seek(1910); - BOOST_CHECK_EQUAL(1910, e1->getFilePointer()); - BOOST_CHECK_EQUAL(1910, a1->getFilePointer()); + EXPECT_EQ(1910, e1->getFilePointer()); + EXPECT_EQ(1910, a1->getFilePointer()); be1 = e1->readByte(); ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); // Now make sure the second set didn't move - BOOST_CHECK_EQUAL(1028, e2->getFilePointer()); - BOOST_CHECK_EQUAL(1028, a2->getFilePointer()); + EXPECT_EQ(1028, e2->getFilePointer()); + EXPECT_EQ(1028, a2->getFilePointer()); be2 = e2->readByte(); ba2 = a2->readByte(); - BOOST_CHECK_EQUAL(be2, ba2); + EXPECT_EQ(be2, ba2); // Move the second set back, again cross the buffer size e2->seek(17); a2->seek(17); - BOOST_CHECK_EQUAL(17, e2->getFilePointer()); - BOOST_CHECK_EQUAL(17, a2->getFilePointer()); + EXPECT_EQ(17, e2->getFilePointer()); + EXPECT_EQ(17, a2->getFilePointer()); be2 = e2->readByte(); ba2 = a2->readByte(); - BOOST_CHECK_EQUAL(be2, ba2); + EXPECT_EQ(be2, ba2); // Finally, make sure the first set didn't move // Now make sure the first one didn't move - BOOST_CHECK_EQUAL(1911, e1->getFilePointer()); - BOOST_CHECK_EQUAL(1911, a1->getFilePointer()); + EXPECT_EQ(1911, e1->getFilePointer()); + EXPECT_EQ(1911, a1->getFilePointer()); be1 = e1->readByte(); ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); e1->close(); e2->close(); @@ -429,7 +434,7 @@ BOOST_AUTO_TEST_CASE(testRandomAccess) } /// This test opens two files from a compound stream and verifies that their file positions are independent of each other. -BOOST_AUTO_TEST_CASE(testRandomAccessClones) +TEST_F(CompoundFileTest, testRandomAccessClones) { setUpLarger(); @@ -441,64 +446,64 @@ BOOST_AUTO_TEST_CASE(testRandomAccessClones) IndexInputPtr a1 = boost::dynamic_pointer_cast(e1->clone()); IndexInputPtr a2 = boost::dynamic_pointer_cast(e2->clone()); - + // Seek the first pair e1->seek(100); a1->seek(100); - BOOST_CHECK_EQUAL(100, e1->getFilePointer()); - BOOST_CHECK_EQUAL(100, a1->getFilePointer()); + EXPECT_EQ(100, e1->getFilePointer()); + EXPECT_EQ(100, a1->getFilePointer()); uint8_t be1 = e1->readByte(); uint8_t ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); // Now seek the second pair e2->seek(1027); a2->seek(1027); - BOOST_CHECK_EQUAL(1027, e2->getFilePointer()); - BOOST_CHECK_EQUAL(1027, a2->getFilePointer()); + EXPECT_EQ(1027, e2->getFilePointer()); + EXPECT_EQ(1027, a2->getFilePointer()); uint8_t be2 = e2->readByte(); uint8_t ba2 = a2->readByte(); - BOOST_CHECK_EQUAL(be2, ba2); + EXPECT_EQ(be2, ba2); // Now make sure the first one didn't move - BOOST_CHECK_EQUAL(101, e1->getFilePointer()); - BOOST_CHECK_EQUAL(101, a1->getFilePointer()); + EXPECT_EQ(101, e1->getFilePointer()); + EXPECT_EQ(101, a1->getFilePointer()); be1 = e1->readByte(); ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); // Now more the first one again, past the buffer length e1->seek(1910); a1->seek(1910); - BOOST_CHECK_EQUAL(1910, e1->getFilePointer()); - BOOST_CHECK_EQUAL(1910, a1->getFilePointer()); + EXPECT_EQ(1910, e1->getFilePointer()); + EXPECT_EQ(1910, a1->getFilePointer()); be1 = e1->readByte(); ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); // Now make sure the second set didn't move - BOOST_CHECK_EQUAL(1028, e2->getFilePointer()); - BOOST_CHECK_EQUAL(1028, a2->getFilePointer()); + EXPECT_EQ(1028, e2->getFilePointer()); + EXPECT_EQ(1028, a2->getFilePointer()); be2 = e2->readByte(); ba2 = a2->readByte(); - BOOST_CHECK_EQUAL(be2, ba2); + EXPECT_EQ(be2, ba2); // Move the second set back, again cross the buffer size e2->seek(17); a2->seek(17); - BOOST_CHECK_EQUAL(17, e2->getFilePointer()); - BOOST_CHECK_EQUAL(17, a2->getFilePointer()); + EXPECT_EQ(17, e2->getFilePointer()); + EXPECT_EQ(17, a2->getFilePointer()); be2 = e2->readByte(); ba2 = a2->readByte(); - BOOST_CHECK_EQUAL(be2, ba2); + EXPECT_EQ(be2, ba2); // Finally, make sure the first set didn't move // Now make sure the first one didn't move - BOOST_CHECK_EQUAL(1911, e1->getFilePointer()); - BOOST_CHECK_EQUAL(1911, a1->getFilePointer()); + EXPECT_EQ(1911, e1->getFilePointer()); + EXPECT_EQ(1911, a1->getFilePointer()); be1 = e1->readByte(); ba1 = a1->readByte(); - BOOST_CHECK_EQUAL(be1, ba1); + EXPECT_EQ(be1, ba1); e1->close(); e2->close(); @@ -507,20 +512,27 @@ BOOST_AUTO_TEST_CASE(testRandomAccessClones) cr->close(); } -BOOST_AUTO_TEST_CASE(testFileNotFound) +TEST_F(CompoundFileTest, testFileNotFound) { setUpLarger(); CompoundFileReaderPtr cr = newLucene(dir, L"f.comp"); IndexInputPtr e1; - + // Open two files - BOOST_CHECK_EXCEPTION(e1 = cr->openInput(L"bogus"), LuceneException, check_exception(LuceneException::IO)); - + try + { + e1 = cr->openInput(L"bogus"); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + cr->close(); } -BOOST_AUTO_TEST_CASE(testReadPastEOF) +TEST_F(CompoundFileTest, testReadPastEOF) { setUpLarger(); @@ -530,33 +542,45 @@ BOOST_AUTO_TEST_CASE(testReadPastEOF) ByteArray b(ByteArray::newInstance(100)); is->readBytes(b.get(), 0, 10); uint8_t test = 0; - - BOOST_CHECK_EXCEPTION(test = is->readByte(), LuceneException, check_exception(LuceneException::IO)); - + + try + { + test = is->readByte(); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + is->seek(is->length() - 10); - - BOOST_CHECK_EXCEPTION(is->readBytes(b.get(), 0, 50), LuceneException, check_exception(LuceneException::IO)); - + + try + { + is->readBytes(b.get(), 0, 50); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + is->close(); cr->close(); } /// This test that writes larger than the size of the buffer output will correctly increment the file pointer. -BOOST_AUTO_TEST_CASE(testLargeWrites) +TEST_F(CompoundFileTest, testLargeWrites) { IndexOutputPtr os = dir->createOutput(L"testBufferStart.txt"); RandomPtr r = newLucene(); - + ByteArray largeBuf(ByteArray::newInstance(2048)); for (int32_t i = 0; i < largeBuf.size(); ++i) largeBuf[i] = (uint8_t)r->nextInt(256); - + int64_t currentPos = os->getFilePointer(); os->writeBytes(largeBuf.get(), largeBuf.size()); - - BOOST_CHECK_EQUAL(currentPos + largeBuf.size(), os->getFilePointer()); - + + EXPECT_EQ(currentPos + largeBuf.size(), os->getFilePointer()); + os->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/ConcurrentMergeSchedulerTest.cpp b/src/test/index/ConcurrentMergeSchedulerTest.cpp index fffacbe7..46c87166 100644 --- a/src/test/index/ConcurrentMergeSchedulerTest.cpp +++ b/src/test/index/ConcurrentMergeSchedulerTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(ConcurrentMergeSchedulerTest, LuceneTestFixture) +typedef LuceneTestFixture ConcurrentMergeSchedulerTest; static bool mergeCalled = false; static bool mergeThreadCreated = false; @@ -38,14 +38,14 @@ static void checkNoUnreferencedFiles(DirectoryPtr dir) infos->read(dir); IndexFileDeleterPtr deleter = newLucene(dir, newLucene(), infos, InfoStreamPtr(), DocumentsWriterPtr(), HashSet()); HashSet _endFiles = dir->listAll(); - + Collection startFiles = Collection::newInstance(_startFiles.begin(), _startFiles.end()); Collection endFiles = Collection::newInstance(_endFiles.begin(), _endFiles.end()); - + std::sort(startFiles.begin(), startFiles.end()); std::sort(endFiles.begin(), endFiles.end()); - - BOOST_CHECK(startFiles.equals(endFiles)); + + EXPECT_TRUE(startFiles.equals(endFiles)); } namespace TestFlushException @@ -61,7 +61,7 @@ namespace TestFlushException mainThread = LuceneThread::currentId(); TestPoint::clear(); } - + virtual ~FailOnlyOnFlush() { } @@ -76,13 +76,13 @@ namespace TestFlushException MockDirectoryFailure::setDoFail(); hitExc = false; } - + virtual void clearDoFail() { MockDirectoryFailure::clearDoFail(); this->doFail = false; } - + virtual void eval(MockRAMDirectoryPtr dir) { if (this->doFail && mainThread == LuceneThread::currentId() && TestPoint::getTestPoint(L"doFlush")) @@ -92,7 +92,7 @@ namespace TestFlushException } } }; - + DECLARE_SHARED_PTR(TestableIndexWriter) class TestableIndexWriter : public IndexWriter @@ -101,20 +101,20 @@ namespace TestFlushException TestableIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { } - + virtual ~TestableIndexWriter() { } - + LUCENE_CLASS(TestableIndexWriter); - + public: using IndexWriter::flush; }; } /// Make sure running background merges still work fine even when we are hitting exceptions during flushing. -BOOST_AUTO_TEST_CASE(testFlushExceptions) +TEST_F(ConcurrentMergeSchedulerTest, testFlushExceptions) { MockRAMDirectoryPtr directory = newLucene(); TestFlushException::FailOnlyOnFlushPtr failure = newLucene(); @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(testFlushExceptions) FieldPtr idField = newLucene(L"id", L"", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); doc->add(idField); int32_t extraCount = 0; - + for (int32_t i = 0; i < 10; ++i) { for (int32_t j = 0; j < 20; ++j) @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(testFlushExceptions) writer->addDocument(doc); failure->setDoFail(); writer->flush(true, false, true); - BOOST_CHECK(!failure->hitExc); + EXPECT_TRUE(!failure->hitExc); ++extraCount; } catch (LuceneException&) @@ -156,16 +156,16 @@ BOOST_AUTO_TEST_CASE(testFlushExceptions) } } } - + writer->close(); IndexReaderPtr reader = IndexReader::open(directory, true); - BOOST_CHECK_EQUAL(200 + extraCount, reader->numDocs()); + EXPECT_EQ(200 + extraCount, reader->numDocs()); reader->close(); directory->close(); } /// Test that deletes committed after a merge started and before it finishes, are correctly merged back -BOOST_AUTO_TEST_CASE(testDeleteMerging) +TEST_F(ConcurrentMergeSchedulerTest, testDeleteMerging) { RAMDirectoryPtr directory = newLucene(); @@ -189,26 +189,26 @@ BOOST_AUTO_TEST_CASE(testDeleteMerging) idField->setValue(StringUtils::toString(i * 100 + j)); writer->addDocument(doc); } - + int32_t delID = i; while (delID < 100 * (1 + i)) { writer->deleteDocuments(newLucene(L"id", StringUtils::toString(delID))); delID += 10; } - + writer->commit(); } - + writer->close(); IndexReaderPtr reader = IndexReader::open(directory, true); // Verify that we did not lose any deletes - BOOST_CHECK_EQUAL(450, reader->numDocs()); + EXPECT_EQ(450, reader->numDocs()); reader->close(); directory->close(); } -BOOST_AUTO_TEST_CASE(testNoExtraFiles) +TEST_F(ConcurrentMergeSchedulerTest, testNoExtraFiles) { RAMDirectoryPtr directory = newLucene(); @@ -233,34 +233,34 @@ BOOST_AUTO_TEST_CASE(testNoExtraFiles) // Reopen writer = newLucene(directory, newLucene(), false, IndexWriter::MaxFieldLengthUNLIMITED); } - + writer->close(); directory->close(); } -BOOST_AUTO_TEST_CASE(testNoWaitClose) +TEST_F(ConcurrentMergeSchedulerTest, testNoWaitClose) { RAMDirectoryPtr directory = newLucene(); DocumentPtr doc = newLucene(); FieldPtr idField = newLucene(L"id", L"", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); doc->add(idField); - + IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + for (int32_t i = 0; i < 10; ++i) { ConcurrentMergeSchedulerPtr cms = newLucene(); writer->setMergeScheduler(cms); writer->setMaxBufferedDocs(2); writer->setMergeFactor(100); - + for (int32_t j = 0; j < 201; ++j) { idField->setValue(StringUtils::toString(i * 201 + j)); writer->addDocument(doc); } - + int32_t delID = i * 201; for (int32_t j = 0; j < 20; ++j) { @@ -276,8 +276,8 @@ BOOST_AUTO_TEST_CASE(testNoWaitClose) writer->close(false); IndexReaderPtr reader = IndexReader::open(directory, true); - BOOST_CHECK_EQUAL((1 + i) * 182, reader->numDocs()); - + EXPECT_EQ((1 + i) * 182, reader->numDocs()); + reader->close(); // Reopen @@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(testNoWaitClose) writer->close(); directory->close(); - + // allow time for merge threads to finish LuceneThread::threadSleep(1000); } @@ -294,7 +294,7 @@ BOOST_AUTO_TEST_CASE(testNoWaitClose) namespace TestSubclassConcurrentMergeScheduler { DECLARE_SHARED_PTR(MyMergeScheduler) - + class FailOnlyOnMerge : public MockDirectoryFailure { public: @@ -302,7 +302,7 @@ namespace TestSubclassConcurrentMergeScheduler { TestPoint::clear(); } - + virtual ~FailOnlyOnMerge() { } @@ -314,7 +314,7 @@ namespace TestSubclassConcurrentMergeScheduler boost::throw_exception(IOException(L"now failing during merge")); } }; - + class MyMergeThread : public MergeThread { public: @@ -322,21 +322,21 @@ namespace TestSubclassConcurrentMergeScheduler { mergeThreadCreated = true; } - + virtual ~MyMergeThread() { } }; - + class MyMergeScheduler : public ConcurrentMergeScheduler { public: virtual ~MyMergeScheduler() { } - + LUCENE_CLASS(MyMergeScheduler); - + protected: virtual MergeThreadPtr getMergeThread(IndexWriterPtr writer, OneMergePtr merge) { @@ -344,12 +344,12 @@ namespace TestSubclassConcurrentMergeScheduler thread->setThreadPriority(getMergeThreadPriority()); return thread; } - + virtual void handleMergeException(const LuceneException& exc) { excCalled = true; } - + virtual void doMerge(OneMergePtr merge) { mergeCalled = true; @@ -358,7 +358,7 @@ namespace TestSubclassConcurrentMergeScheduler }; } -BOOST_AUTO_TEST_CASE(testSubclassConcurrentMergeScheduler) +TEST_F(ConcurrentMergeSchedulerTest, testSubclassConcurrentMergeScheduler) { MockRAMDirectoryPtr dir = newLucene(); dir->failOn(newLucene()); @@ -378,11 +378,9 @@ BOOST_AUTO_TEST_CASE(testSubclassConcurrentMergeScheduler) ms->sync(); writer->close(); - BOOST_CHECK(mergeThreadCreated); - BOOST_CHECK(mergeCalled); - BOOST_CHECK(excCalled); + EXPECT_TRUE(mergeThreadCreated); + EXPECT_TRUE(mergeCalled); + EXPECT_TRUE(excCalled); dir->close(); - BOOST_CHECK(ConcurrentMergeScheduler::anyUnhandledExceptions()); + EXPECT_TRUE(ConcurrentMergeScheduler::anyUnhandledExceptions()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/CrashTest.cpp b/src/test/index/CrashTest.cpp index 6366fde5..424f2130 100644 --- a/src/test/index/CrashTest.cpp +++ b/src/test/index/CrashTest.cpp @@ -18,13 +18,13 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CrashTest, LuceneTestFixture) +typedef LuceneTestFixture CrashTest; static IndexWriterPtr initIndex(MockRAMDirectoryPtr dir) { dir->setLockFactory(NoLockFactory::getNoLockFactory()); - IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); + IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(10); boost::dynamic_pointer_cast(writer->getMergeScheduler())->setSuppressExceptions(); @@ -52,16 +52,16 @@ static void crash(IndexWriterPtr writer) dir->clearCrash(); } -BOOST_AUTO_TEST_CASE(testCrashWhileIndexing) +TEST_F(CrashTest, testCrashWhileIndexing) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); crash(writer); IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK(reader->numDocs() < 157); + EXPECT_TRUE(reader->numDocs() < 157); } -BOOST_AUTO_TEST_CASE(testWriterAfterCrash) +TEST_F(CrashTest, testWriterAfterCrash) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); @@ -69,75 +69,73 @@ BOOST_AUTO_TEST_CASE(testWriterAfterCrash) crash(writer); writer = initIndex(); writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK(reader->numDocs() < 314); + EXPECT_TRUE(reader->numDocs() < 314); } -BOOST_AUTO_TEST_CASE(testCrashAfterReopen) +TEST_F(CrashTest, testCrashAfterReopen) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(); writer = initIndex(dir); - BOOST_CHECK_EQUAL(314, writer->maxDoc()); + EXPECT_EQ(314, writer->maxDoc()); crash(writer); - + IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK(reader->numDocs() >= 157); + EXPECT_TRUE(reader->numDocs() >= 157); } -BOOST_AUTO_TEST_CASE(testCrashAfterClose) +TEST_F(CrashTest, testCrashAfterClose) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(); dir->crash(); - + IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(157, reader->numDocs()); + EXPECT_EQ(157, reader->numDocs()); } -BOOST_AUTO_TEST_CASE(testCrashAfterCloseNoWait) +TEST_F(CrashTest, testCrashAfterCloseNoWait) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(false); dir->crash(); - + IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(157, reader->numDocs()); + EXPECT_EQ(157, reader->numDocs()); } -BOOST_AUTO_TEST_CASE(testCrashReaderDeletes) +TEST_F(CrashTest, testCrashReaderDeletes) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(false); - + IndexReaderPtr reader = IndexReader::open(dir, false); reader->deleteDocument(3); - + dir->crash(); - + reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(157, reader->numDocs()); + EXPECT_EQ(157, reader->numDocs()); } -BOOST_AUTO_TEST_CASE(testCrashReaderDeletesAfterClose) +TEST_F(CrashTest, testCrashReaderDeletesAfterClose) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(false); - + IndexReaderPtr reader = IndexReader::open(dir, false); reader->deleteDocument(3); reader->close(); - + dir->crash(); - + reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(156, reader->numDocs()); + EXPECT_EQ(156, reader->numDocs()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/DeletionPolicyTest.cpp b/src/test/index/DeletionPolicyTest.cpp index 1576e347..ea789b46 100644 --- a/src/test/index/DeletionPolicyTest.cpp +++ b/src/test/index/DeletionPolicyTest.cpp @@ -28,13 +28,13 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DeletionPolicyTest, LuceneTestFixture) +typedef LuceneTestFixture DeletionPolicyTest; static void verifyCommitOrder(Collection commits) { IndexCommitPtr firstCommit = commits[0]; int64_t last = SegmentInfos::generationFromSegmentsFileName(firstCommit->getSegmentsFileName()); - BOOST_CHECK_EQUAL(last, firstCommit->getGeneration()); + EXPECT_EQ(last, firstCommit->getGeneration()); int64_t lastVersion = firstCommit->getVersion(); int64_t lastTimestamp = firstCommit->getTimestamp(); for (int32_t i = 1; i < commits.size(); ++i) @@ -43,10 +43,10 @@ static void verifyCommitOrder(Collection commits) int64_t now = SegmentInfos::generationFromSegmentsFileName(commit->getSegmentsFileName()); int64_t nowVersion = commit->getVersion(); int64_t nowTimestamp = commit->getTimestamp(); - BOOST_CHECK(now > last); // SegmentInfos commits are out-of-order? - BOOST_CHECK(nowVersion > lastVersion); // SegmentInfos versions are out-of-order? - BOOST_CHECK(nowTimestamp >= lastTimestamp); // SegmentInfos timestamps are out-of-order? - BOOST_CHECK_EQUAL(now, commit->getGeneration()); + EXPECT_TRUE(now > last); // SegmentInfos commits are out-of-order? + EXPECT_TRUE(nowVersion > lastVersion); // SegmentInfos versions are out-of-order? + EXPECT_TRUE(nowTimestamp >= lastTimestamp); // SegmentInfos timestamps are out-of-order? + EXPECT_EQ(now, commit->getGeneration()); last = now; lastVersion = nowVersion; lastTimestamp = nowTimestamp; @@ -60,26 +60,26 @@ static void addDoc(IndexWriterPtr writer) writer->addDocument(doc); } -DECLARE_SHARED_PTR(KeepAllDeletionPolicy) +DECLARE_SHARED_PTR(DeletionPolicyKeepAllDeletionPolicy) DECLARE_SHARED_PTR(KeepNoneOnInitDeletionPolicy) DECLARE_SHARED_PTR(KeepLastNDeletionPolicy) DECLARE_SHARED_PTR(ExpirationTimeDeletionPolicy) -class KeepAllDeletionPolicy : public IndexDeletionPolicy +class DeletionPolicyKeepAllDeletionPolicy : public IndexDeletionPolicy { public: - KeepAllDeletionPolicy() + DeletionPolicyKeepAllDeletionPolicy() { numOnInit = 0; numOnCommit = 0; } - - virtual ~KeepAllDeletionPolicy() + + virtual ~DeletionPolicyKeepAllDeletionPolicy() { } - - LUCENE_CLASS(KeepAllDeletionPolicy); - + + LUCENE_CLASS(DeletionPolicyKeepAllDeletionPolicy); + public: int32_t numOnInit; int32_t numOnCommit; @@ -91,12 +91,12 @@ class KeepAllDeletionPolicy : public IndexDeletionPolicy verifyCommitOrder(commits); ++numOnInit; } - + virtual void onCommit(Collection commits) { IndexCommitPtr lastCommit = commits[commits.size() - 1]; IndexReaderPtr r = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(r->isOptimized(), lastCommit->isOptimized()); + EXPECT_EQ(r->isOptimized(), lastCommit->isOptimized()); r->close(); verifyCommitOrder(commits); ++numOnCommit; @@ -112,13 +112,13 @@ class KeepNoneOnInitDeletionPolicy : public IndexDeletionPolicy numOnInit = 0; numOnCommit = 0; } - + virtual ~KeepNoneOnInitDeletionPolicy() { } - + LUCENE_CLASS(KeepNoneOnInitDeletionPolicy); - + public: int32_t numOnInit; int32_t numOnCommit; @@ -132,10 +132,10 @@ class KeepNoneOnInitDeletionPolicy : public IndexDeletionPolicy for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { (*commit)->deleteCommit(); - BOOST_CHECK((*commit)->isDeleted()); + EXPECT_TRUE((*commit)->isDeleted()); } } - + virtual void onCommit(Collection commits) { verifyCommitOrder(commits); @@ -158,13 +158,13 @@ class KeepLastNDeletionPolicy : public IndexDeletionPolicy this->numDelete = 0; this->seen = HashSet::newInstance(); } - + virtual ~KeepLastNDeletionPolicy() { } - + LUCENE_CLASS(KeepLastNDeletionPolicy); - + public: int32_t numOnInit; int32_t numOnCommit; @@ -180,7 +180,7 @@ class KeepLastNDeletionPolicy : public IndexDeletionPolicy // do no deletions on init doDeletes(commits, false); } - + virtual void onCommit(Collection commits) { verifyCommitOrder(commits); @@ -195,7 +195,7 @@ class KeepLastNDeletionPolicy : public IndexDeletionPolicy { String fileName = commits[commits.size() - 1]->getSegmentsFileName(); if (seen.contains(fileName)) - BOOST_FAIL("onCommit was called twice on the same commit point"); + FAIL() << "onCommit was called twice on the same commit point"; seen.add(fileName); ++numOnCommit; } @@ -218,13 +218,13 @@ class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy this->expirationTimeSeconds = seconds; this->numDelete = 0; } - + virtual ~ExpirationTimeDeletionPolicy() { } - + LUCENE_CLASS(ExpirationTimeDeletionPolicy); - + public: DirectoryPtr dir; double expirationTimeSeconds; @@ -236,16 +236,16 @@ class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy verifyCommitOrder(commits); onCommit(commits); } - + virtual void onCommit(Collection commits) { verifyCommitOrder(commits); - + IndexCommitPtr lastCommit = commits[commits.size() - 1]; - + // Any commit older than expireTime should be deleted double expireTime = dir->fileModified(lastCommit->getSegmentsFileName()) / 1000.0 - expirationTimeSeconds; - + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { double modTime = dir->fileModified((*commit)->getSegmentsFileName()) / 1000.0; @@ -259,10 +259,10 @@ class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy }; /// Test "by time expiration" deletion policy -BOOST_AUTO_TEST_CASE(testExpirationTimeDeletionPolicy) +TEST_F(DeletionPolicyTest, testExpirationTimeDeletionPolicy) { const double SECONDS = 2.0; - + bool useCompoundFile = true; DirectoryPtr dir = newLucene(); @@ -285,9 +285,9 @@ BOOST_AUTO_TEST_CASE(testExpirationTimeDeletionPolicy) // Make sure to sleep long enough so that some commit points will be deleted LuceneThread::threadSleep(1000.0 * (SECONDS / 5.0)); } - + // First, make sure the policy in fact deleted something - BOOST_CHECK(policy->numDelete > 0); // no commits were deleted + EXPECT_TRUE(policy->numDelete > 0); // no commits were deleted // Then simplistic check: just verify that the segments_N's that still exist are in fact within SECONDS // seconds of the last one's mod time, and, that I can open a reader on each @@ -303,30 +303,30 @@ BOOST_AUTO_TEST_CASE(testExpirationTimeDeletionPolicy) reader->close(); fileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen); int64_t modTime = dir->fileModified(fileName); - BOOST_CHECK(lastDeleteTime - modTime <= (SECONDS * 1000)); + EXPECT_TRUE(lastDeleteTime - modTime <= (SECONDS * 1000)); } catch (IOException&) { // OK break; } - + dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); --gen; } - + dir->close(); } /// Test a silly deletion policy that keeps all commits around. -BOOST_AUTO_TEST_CASE(testKeepAllDeletionPolicy) +TEST_F(DeletionPolicyTest, testDeletionPolicyKeepAllDeletionPolicy) { for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); // Never deletes a commit - KeepAllDeletionPolicyPtr policy = newLucene(); + DeletionPolicyKeepAllDeletionPolicyPtr policy = newLucene(); DirectoryPtr dir = newLucene(); policy->dir = dir; @@ -345,23 +345,23 @@ BOOST_AUTO_TEST_CASE(testKeepAllDeletionPolicy) writer->optimize(); writer->close(); - BOOST_CHECK_EQUAL(2, policy->numOnInit); + EXPECT_EQ(2, policy->numOnInit); // If we are not auto committing then there should be exactly 2 commits (one per close above) - BOOST_CHECK_EQUAL(2, policy->numOnCommit); + EXPECT_EQ(2, policy->numOnCommit); // Test listCommits Collection commits = IndexReader::listCommits(dir); // 1 from opening writer + 2 from closing writer - BOOST_CHECK_EQUAL(3, commits.size()); - + EXPECT_EQ(3, commits.size()); + // Make sure we can open a reader on each commit for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { IndexReaderPtr r = IndexReader::open(*commit, IndexDeletionPolicyPtr(), false); r->close(); } - + // Simplistic check: just verify all segments_N's still exist, and, I can open a reader on each dir->deleteFile(IndexFileNames::SEGMENTS_GEN()); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); @@ -371,7 +371,7 @@ BOOST_AUTO_TEST_CASE(testKeepAllDeletionPolicy) reader->close(); dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); --gen; - + if (gen > 0) { // Now that we've removed a commit point, which should have orphan'd at least one index file. @@ -380,19 +380,19 @@ BOOST_AUTO_TEST_CASE(testKeepAllDeletionPolicy) writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthLIMITED); writer->close(); int32_t postCount = dir->listAll().size(); - BOOST_CHECK(postCount < preCount); + EXPECT_TRUE(postCount < preCount); } } - + dir->close(); } } -/// Uses KeepAllDeletionPolicy to keep all commits around, then, opens a new IndexWriter on a previous commit point. -BOOST_AUTO_TEST_CASE(testOpenPriorSnapshot) +/// Uses DeletionPolicyKeepAllDeletionPolicy to keep all commits around, then, opens a new IndexWriter on a previous commit point. +TEST_F(DeletionPolicyTest, testOpenPriorSnapshot) { // Never deletes a commit - KeepAllDeletionPolicyPtr policy = newLucene(); + DeletionPolicyKeepAllDeletionPolicyPtr policy = newLucene(); DirectoryPtr dir = newLucene(); policy->dir = dir; @@ -408,49 +408,49 @@ BOOST_AUTO_TEST_CASE(testOpenPriorSnapshot) writer->close(); Collection commits = IndexReader::listCommits(dir); - BOOST_CHECK_EQUAL(6, commits.size()); + EXPECT_EQ(6, commits.size()); IndexCommitPtr lastCommit; for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { if (!lastCommit || (*commit)->getGeneration() > lastCommit->getGeneration()) lastCommit = *commit; } - BOOST_CHECK(lastCommit); - + EXPECT_TRUE(lastCommit); + // Now add 1 doc and optimize writer = newLucene(dir, newLucene(), (IndexDeletionPolicyPtr)policy, IndexWriter::MaxFieldLengthLIMITED); addDoc(writer); - BOOST_CHECK_EQUAL(11, writer->numDocs()); + EXPECT_EQ(11, writer->numDocs()); writer->optimize(); writer->close(); - BOOST_CHECK_EQUAL(7, IndexReader::listCommits(dir).size()); + EXPECT_EQ(7, IndexReader::listCommits(dir).size()); // Now open writer on the commit just before optimize writer = newLucene(dir, newLucene(), policy, IndexWriter::MaxFieldLengthLIMITED, lastCommit); - BOOST_CHECK_EQUAL(10, writer->numDocs()); + EXPECT_EQ(10, writer->numDocs()); // Should undo our rollback writer->rollback(); IndexReaderPtr r = IndexReader::open(dir, true); // Still optimized, still 11 docs - BOOST_CHECK(r->isOptimized()); - BOOST_CHECK_EQUAL(11, r->numDocs()); + EXPECT_TRUE(r->isOptimized()); + EXPECT_EQ(11, r->numDocs()); r->close(); writer = newLucene(dir, newLucene(), policy, IndexWriter::MaxFieldLengthLIMITED, lastCommit); - BOOST_CHECK_EQUAL(10, writer->numDocs()); + EXPECT_EQ(10, writer->numDocs()); // Commits the rollback writer->close(); // Now 8 because we made another commit - BOOST_CHECK_EQUAL(8, IndexReader::listCommits(dir).size()); + EXPECT_EQ(8, IndexReader::listCommits(dir).size()); r = IndexReader::open(dir, true); // Not optimized because we rolled it back, and now only 10 docs - BOOST_CHECK(!r->isOptimized()); - BOOST_CHECK_EQUAL(10, r->numDocs()); + EXPECT_TRUE(!r->isOptimized()); + EXPECT_EQ(10, r->numDocs()); r->close(); // Reoptimize @@ -459,33 +459,33 @@ BOOST_AUTO_TEST_CASE(testOpenPriorSnapshot) writer->close(); r = IndexReader::open(dir, true); - BOOST_CHECK(r->isOptimized()); - BOOST_CHECK_EQUAL(10, r->numDocs()); + EXPECT_TRUE(r->isOptimized()); + EXPECT_EQ(10, r->numDocs()); r->close(); // Now open writer on the commit just before optimize, but this time keeping only the last commit writer = newLucene(dir, newLucene(), newLucene(), IndexWriter::MaxFieldLengthLIMITED, lastCommit); - BOOST_CHECK_EQUAL(10, writer->numDocs()); + EXPECT_EQ(10, writer->numDocs()); // Reader still sees optimized index, because writer opened on the prior commit has not yet committed r = IndexReader::open(dir, true); - BOOST_CHECK(r->isOptimized()); - BOOST_CHECK_EQUAL(10, r->numDocs()); + EXPECT_TRUE(r->isOptimized()); + EXPECT_EQ(10, r->numDocs()); r->close(); writer->close(); // Now reader sees unoptimized index: r = IndexReader::open(dir, true); - BOOST_CHECK(!r->isOptimized()); - BOOST_CHECK_EQUAL(10, r->numDocs()); + EXPECT_TRUE(!r->isOptimized()); + EXPECT_EQ(10, r->numDocs()); r->close(); dir->close(); } /// Test keeping NO commit points. This is a viable and useful case eg where you want to build a big index and you know there are no readers. -BOOST_AUTO_TEST_CASE(testKeepNoneOnInitDeletionPolicy) +TEST_F(DeletionPolicyTest, testKeepNoneOnInitDeletionPolicy) { for (int32_t pass = 0; pass < 2; ++pass) { @@ -503,14 +503,14 @@ BOOST_AUTO_TEST_CASE(testKeepNoneOnInitDeletionPolicy) writer->close(); writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthUNLIMITED); - + writer->setUseCompoundFile(useCompoundFile); writer->optimize(); writer->close(); - BOOST_CHECK_EQUAL(2, policy->numOnInit); + EXPECT_EQ(2, policy->numOnInit); // If we are not auto committing then there should be exactly 2 commits (one per close above) - BOOST_CHECK_EQUAL(2, policy->numOnCommit); + EXPECT_EQ(2, policy->numOnCommit); // Simplistic check: just verify the index is in fact readable IndexReaderPtr reader = IndexReader::open(dir, true); @@ -521,10 +521,10 @@ BOOST_AUTO_TEST_CASE(testKeepNoneOnInitDeletionPolicy) } /// Test a deletion policy that keeps last N commits. -BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicy) +TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicy) { int32_t N = 5; - + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); @@ -532,7 +532,7 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicy) DirectoryPtr dir = newLucene(); KeepLastNDeletionPolicyPtr policy = newLucene(N); - + for (int32_t j = 0; j < N + 1; ++j) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, policy, IndexWriter::MaxFieldLengthUNLIMITED); @@ -543,10 +543,10 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicy) writer->optimize(); writer->close(); } - - BOOST_CHECK(policy->numDelete > 0); - BOOST_CHECK_EQUAL(N + 1, policy->numOnInit); - BOOST_CHECK_EQUAL(N + 1, policy->numOnCommit); + + EXPECT_TRUE(policy->numDelete > 0); + EXPECT_EQ(N + 1, policy->numOnInit); + EXPECT_EQ(N + 1, policy->numOnCommit); // Simplistic check: just verify only the past N segments_N's still exist, and, I can open a reader on each dir->deleteFile(IndexFileNames::SEGMENTS_GEN()); @@ -558,40 +558,40 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicy) IndexReaderPtr reader = IndexReader::open(dir, true); reader->close(); if (i == N) - BOOST_FAIL("should have failed on commits prior to last"); + FAIL() << "should have failed on commits prior to last"; } catch (IOException& e) { if (i != N) - BOOST_FAIL(e.getError()); + FAIL() << e.getError(); } if (i < N) dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); --gen; } - + dir->close(); } } /// Test a deletion policy that keeps last N commits around, with reader doing deletes. -BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithReader) +TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithReader) { int32_t N = 10; - + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); KeepLastNDeletionPolicyPtr policy = newLucene(N); - + DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, policy, IndexWriter::MaxFieldLengthUNLIMITED); writer->setUseCompoundFile(useCompoundFile); writer->close(); - TermPtr searchTerm = newLucene(L"content", L"aaa"); + TermPtr searchTerm = newLucene(L"content", L"aaa"); QueryPtr query = newLucene(searchTerm); - + for (int32_t i = 0; i < N + 1; ++i) { writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthUNLIMITED); @@ -605,7 +605,7 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithReader) reader->setNorm(4 * i + 1, L"content", 2.0); IndexSearcherPtr searcher = newLucene(reader); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(16 * (1 + i), hits.size()); + EXPECT_EQ(16 * (1 + i), hits.size()); // this is a commit reader->close(); searcher->close(); @@ -617,12 +617,12 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithReader) // this is a commit writer->close(); - BOOST_CHECK_EQUAL(2 * (N + 2), policy->numOnInit); - BOOST_CHECK_EQUAL(2 * (N + 2) - 1, policy->numOnCommit); + EXPECT_EQ(2 * (N + 2), policy->numOnInit); + EXPECT_EQ(2 * (N + 2) - 1, policy->numOnCommit); IndexSearcherPtr searcher = newLucene(dir, false); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(176, hits.size()); + EXPECT_EQ(176, hits.size()); // Simplistic check: just verify only the past N segments_N's still exist, and, I can open a reader on each int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); @@ -645,45 +645,45 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithReader) else expectedCount -= 17; } - BOOST_CHECK_EQUAL(expectedCount, hits.size()); + EXPECT_EQ(expectedCount, hits.size()); searcher->close(); reader->close(); if (i == N) - BOOST_FAIL("should have failed on commits before last 5"); + FAIL() << "should have failed on commits before last 5"; } catch (IOException& e) { if (i != N) - BOOST_FAIL(e.getError()); + FAIL() << e.getError(); } if (i < N) dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); --gen; } - + dir->close(); } } /// Test a deletion policy that keeps last N commits around, through creates. -BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithCreates) +TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithCreates) { int32_t N = 10; - + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); KeepLastNDeletionPolicyPtr policy = newLucene(N); - + DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, policy, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(10); writer->setUseCompoundFile(useCompoundFile); writer->close(); - TermPtr searchTerm = newLucene(L"content", L"aaa"); + TermPtr searchTerm = newLucene(L"content", L"aaa"); QueryPtr query = newLucene(searchTerm); - + for (int32_t i = 0; i < N + 1; ++i) { writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthUNLIMITED); @@ -698,22 +698,22 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithCreates) reader->setNorm(5, L"content", 2.0); IndexSearcherPtr searcher = newLucene(reader); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(16, hits.size()); + EXPECT_EQ(16, hits.size()); // this is a commit reader->close(); searcher->close(); - + writer = newLucene(dir, newLucene(), true, policy, IndexWriter::MaxFieldLengthUNLIMITED); // This will not commit: there are no changes pending because we opened for "create" writer->close(); } - BOOST_CHECK_EQUAL(1 + 3 * (N + 1), policy->numOnInit); - BOOST_CHECK_EQUAL(3 * ( N + 1), policy->numOnCommit); + EXPECT_EQ(1 + 3 * (N + 1), policy->numOnInit); + EXPECT_EQ(3 * ( N + 1), policy->numOnCommit); IndexSearcherPtr searcher = newLucene(dir, false); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // Simplistic check: just verify only the past N segments_N's still exist, and, I can open a reader on each int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); @@ -729,7 +729,7 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithCreates) // Work backwards in commits on what the expected count should be. searcher = newLucene(reader); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(expectedCount, hits.size()); + EXPECT_EQ(expectedCount, hits.size()); searcher->close(); if (expectedCount == 0) expectedCount = 16; @@ -739,20 +739,18 @@ BOOST_AUTO_TEST_CASE(testKeepLastNDeletionPolicyWithCreates) expectedCount = 0; reader->close(); if (i == N) - BOOST_FAIL("should have failed on commits before last"); + FAIL() << "should have failed on commits before last"; } catch (IOException& e) { if (i != N) - BOOST_FAIL(e.getError()); + FAIL() << e.getError(); } if (i < N) dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); --gen; } - + dir->close(); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/DirectoryReaderTest.cpp b/src/test/index/DirectoryReaderTest.cpp index 376636ea..1ffba992 100644 --- a/src/test/index/DirectoryReaderTest.cpp +++ b/src/test/index/DirectoryReaderTest.cpp @@ -25,10 +25,10 @@ using namespace Lucene; -class DirectoryReaderTestFixture : public LuceneTestFixture, public DocHelper +class DirectoryReaderTest : public LuceneTestFixture, public DocHelper { public: - DirectoryReaderTestFixture() + DirectoryReaderTest() { readers = Collection::newInstance(2); dir = newLucene(); @@ -41,8 +41,8 @@ class DirectoryReaderTestFixture : public LuceneTestFixture, public DocHelper sis = newLucene(); sis->read(dir); } - - virtual ~DirectoryReaderTestFixture() + + virtual ~DirectoryReaderTest() { } @@ -52,99 +52,99 @@ class DirectoryReaderTestFixture : public LuceneTestFixture, public DocHelper DocumentPtr doc2; Collection readers; SegmentInfosPtr sis; - + public: void doTestDocument() { sis->read(dir); IndexReaderPtr reader = openReader(); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); DocumentPtr newDoc1 = reader->document(0); - BOOST_CHECK(newDoc1); - BOOST_CHECK(DocHelper::numFields(newDoc1) == DocHelper::numFields(doc1) - DocHelper::unstored.size()); + EXPECT_TRUE(newDoc1); + EXPECT_TRUE(DocHelper::numFields(newDoc1) == DocHelper::numFields(doc1) - DocHelper::unstored.size()); DocumentPtr newDoc2 = reader->document(1); - BOOST_CHECK(newDoc2); - BOOST_CHECK(DocHelper::numFields(newDoc2) == DocHelper::numFields(doc2) - DocHelper::unstored.size()); + EXPECT_TRUE(newDoc2); + EXPECT_TRUE(DocHelper::numFields(newDoc2) == DocHelper::numFields(doc2) - DocHelper::unstored.size()); TermFreqVectorPtr vector = reader->getTermFreqVector(0, DocHelper::TEXT_FIELD_2_KEY); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); checkNorms(reader); } - + void doTestUndeleteAll() { sis->read(dir); IndexReaderPtr reader = openReader(); - BOOST_CHECK(reader); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_TRUE(reader); + EXPECT_EQ(2, reader->numDocs()); reader->deleteDocument(0); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->numDocs()); reader->undeleteAll(); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); // Ensure undeleteAll survives commit/close/reopen reader->commit(MapStringString()); reader->close(); - + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } - + sis->read(dir); reader = openReader(); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); reader->deleteDocument(0); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->numDocs()); reader->commit(MapStringString()); reader->close(); - + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } - + sis->read(dir); reader = openReader(); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->numDocs()); } protected: IndexReaderPtr openReader() { IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK(boost::dynamic_pointer_cast(reader)); - BOOST_CHECK(dir); - BOOST_CHECK(sis); - BOOST_CHECK(reader); + EXPECT_TRUE(boost::dynamic_pointer_cast(reader)); + EXPECT_TRUE(dir); + EXPECT_TRUE(sis); + EXPECT_TRUE(reader); return reader; } - + void checkNorms(IndexReaderPtr reader) { for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) { if ((*field)->isIndexed()) { - BOOST_CHECK_EQUAL(reader->hasNorms((*field)->name()), !(*field)->getOmitNorms()); - BOOST_CHECK_EQUAL(reader->hasNorms((*field)->name()), !DocHelper::noNorms.contains((*field)->name())); + EXPECT_EQ(reader->hasNorms((*field)->name()), !(*field)->getOmitNorms()); + EXPECT_EQ(reader->hasNorms((*field)->name()), !DocHelper::noNorms.contains((*field)->name())); if (!reader->hasNorms((*field)->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms((*field)->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); - BOOST_CHECK(!norms); + EXPECT_TRUE(!norms); norms = ByteArray::newInstance(reader->maxDoc()); reader->norms((*field)->name(), norms, 0); for (int32_t j = 0; j < reader->maxDoc(); ++j) - BOOST_CHECK_EQUAL(norms[j], norm1); + EXPECT_EQ(norms[j], norm1); } } } } - + void addDoc(RAMDirectoryPtr ramDir1, const String& s, bool create) { IndexWriterPtr iw = newLucene(ramDir1, newLucene(LuceneVersion::LUCENE_CURRENT), create, IndexWriter::MaxFieldLengthLIMITED); @@ -155,31 +155,36 @@ class DirectoryReaderTestFixture : public LuceneTestFixture, public DocHelper } }; -BOOST_FIXTURE_TEST_SUITE(DirectoryReaderTest, DirectoryReaderTestFixture) - -BOOST_AUTO_TEST_CASE(testDirectoryReader) +TEST_F(DirectoryReaderTest, testDirectoryReader) { doTestDocument(); doTestUndeleteAll(); } -BOOST_AUTO_TEST_CASE(testIsCurrent) +TEST_F(DirectoryReaderTest, testIsCurrent) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); RAMDirectoryPtr ramDir2 = newLucene(); addDoc(ramDir2, L"test blah", true); MultiReaderPtr mr = newLucene(newCollection(IndexReader::open(ramDir1, false), IndexReader::open(ramDir2, false))); - BOOST_CHECK(mr->isCurrent()); // just opened, must be current + EXPECT_TRUE(mr->isCurrent()); // just opened, must be current addDoc(ramDir1, L"more text", false); - BOOST_CHECK(!mr->isCurrent()); // has been modified, not current anymore + EXPECT_TRUE(!mr->isCurrent()); // has been modified, not current anymore addDoc(ramDir2, L"even more text", false); - BOOST_CHECK(!mr->isCurrent()); // has been modified even more, not current anymore - BOOST_CHECK_EXCEPTION(mr->getVersion(), LuceneException, check_exception(LuceneException::UnsupportedOperation)); + EXPECT_TRUE(!mr->isCurrent()); // has been modified even more, not current anymore + try + { + mr->getVersion(); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); + } mr->close(); } -BOOST_AUTO_TEST_CASE(testMultiTermDocs) +TEST_F(DirectoryReaderTest, testMultiTermDocs) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); @@ -207,22 +212,20 @@ BOOST_AUTO_TEST_CASE(testMultiTermDocs) te3->close(); // really a dummy check to ensure that we got some docs and to ensure that nothing is optimized out. - BOOST_CHECK(ret > 0); + EXPECT_TRUE(ret > 0); } -BOOST_AUTO_TEST_CASE(testAllTermDocs) +TEST_F(DirectoryReaderTest, testAllTermDocs) { IndexReaderPtr reader = openReader(); int32_t NUM_DOCS = 2; TermDocsPtr td = reader->termDocs(TermPtr()); for (int32_t i = 0; i < NUM_DOCS; ++i) { - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(i, td->doc()); - BOOST_CHECK_EQUAL(1, td->freq()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(i, td->doc()); + EXPECT_EQ(1, td->freq()); } td->close(); reader->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/DocTest.cpp b/src/test/index/DocTest.cpp index 28c1d28a..1384ac79 100644 --- a/src/test/index/DocTest.cpp +++ b/src/test/index/DocTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DocTest, LuceneTestFixture) +typedef LuceneTestFixture DocTest; static SegmentInfoPtr indexDoc(IndexWriterPtr writer, const String& fileName) { @@ -37,10 +37,10 @@ static SegmentInfoPtr indexDoc(IndexWriterPtr writer, const String& fileName) static void printSegment(StringStream& out, SegmentInfoPtr si) { SegmentReaderPtr reader = SegmentReader::get(true, si, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); - + for (int32_t i = 0; i < reader->numDocs(); ++i) out << reader->document(i)->toString() << L"\n"; - + TermEnumPtr tis = reader->terms(); while (tis->next()) { @@ -83,32 +83,32 @@ static SegmentInfoPtr merge(SegmentInfoPtr si1, SegmentInfoPtr si2, const String merger->add(r2); merger->merge(); merger->closeReaders(); - + if (useCompoundFile) { HashSet filesToDelete = merger->createCompoundFile(merged + L".cfs"); for (HashSet::iterator file = filesToDelete.begin(); file != filesToDelete.end(); ++file) si1->dir->deleteFile(*file); } - + return newLucene(merged, si1->docCount + si2->docCount, si1->dir, useCompoundFile, true); } -BOOST_AUTO_TEST_CASE(testIndexAndMerge) +TEST_F(DocTest, testIndexAndMerge) { String indexDir(FileUtils::joinPath(getTempDir(), L"testDoc")); - + DirectoryPtr directory = FSDirectory::open(indexDir); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); SegmentInfoPtr si1 = indexDoc(writer, L"testdoc1.txt"); StringStream out; printSegment(out, si1); - + SegmentInfoPtr si2 = indexDoc(writer, L"testdoc2.txt"); printSegment(out, si2); writer->close(); - + SegmentInfoPtr siMerge = merge(si1, si2, L"merge", false); printSegment(out, siMerge); @@ -120,9 +120,9 @@ BOOST_AUTO_TEST_CASE(testIndexAndMerge) directory->close(); String multiFileOutput = out.str(); - + out.str(L""); - + directory = FSDirectory::open(indexDir); writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -145,8 +145,6 @@ BOOST_AUTO_TEST_CASE(testIndexAndMerge) directory->close(); String singleFileOutput = out.str(); - - BOOST_CHECK_EQUAL(multiFileOutput, singleFileOutput); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(multiFileOutput, singleFileOutput); +} diff --git a/src/test/index/DocumentWriterTest.cpp b/src/test/index/DocumentWriterTest.cpp index 70bf62e9..f177ccd8 100644 --- a/src/test/index/DocumentWriterTest.cpp +++ b/src/test/index/DocumentWriterTest.cpp @@ -35,20 +35,18 @@ using namespace Lucene; -class DocumentWriterTestFixture : public LuceneTestFixture, public DocHelper +class DocumentWriterTest : public LuceneTestFixture, public DocHelper { public: - virtual ~DocumentWriterTestFixture() + virtual ~DocumentWriterTest() { } }; -BOOST_FIXTURE_TEST_SUITE(DocumentWriterTest, DocumentWriterTestFixture) - -BOOST_AUTO_TEST_CASE(testAddDocument) +TEST_F(DocumentWriterTest, testAddDocument) { RAMDirectoryPtr dir = newLucene(); - + DocumentPtr testDoc = newLucene(); DocHelper::setupDoc(testDoc); AnalyzerPtr analyzer = newLucene(); @@ -59,60 +57,60 @@ BOOST_AUTO_TEST_CASE(testAddDocument) writer->close(); // After adding the document, we should be able to read it back in SegmentReaderPtr reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); DocumentPtr doc = reader->document(0); - BOOST_CHECK(doc); + EXPECT_TRUE(doc); Collection fields = doc->getFields(L"textField2"); - BOOST_CHECK(fields && fields.size() == 1); - BOOST_CHECK_EQUAL(fields[0]->stringValue(), DocHelper::FIELD_2_TEXT); - BOOST_CHECK(fields[0]->isTermVectorStored()); + EXPECT_TRUE(fields && fields.size() == 1); + EXPECT_EQ(fields[0]->stringValue(), DocHelper::FIELD_2_TEXT); + EXPECT_TRUE(fields[0]->isTermVectorStored()); fields = doc->getFields(L"textField1"); - BOOST_CHECK(fields && fields.size() == 1); - BOOST_CHECK_EQUAL(fields[0]->stringValue(), DocHelper::FIELD_1_TEXT); - BOOST_CHECK(!fields[0]->isTermVectorStored()); + EXPECT_TRUE(fields && fields.size() == 1); + EXPECT_EQ(fields[0]->stringValue(), DocHelper::FIELD_1_TEXT); + EXPECT_TRUE(!fields[0]->isTermVectorStored()); fields = doc->getFields(L"keyField"); - BOOST_CHECK(fields && fields.size() == 1); - BOOST_CHECK_EQUAL(fields[0]->stringValue(), DocHelper::KEYWORD_TEXT); + EXPECT_TRUE(fields && fields.size() == 1); + EXPECT_EQ(fields[0]->stringValue(), DocHelper::KEYWORD_TEXT); fields = doc->getFields(DocHelper::NO_NORMS_KEY); - BOOST_CHECK(fields && fields.size() == 1); - BOOST_CHECK_EQUAL(fields[0]->stringValue(), DocHelper::NO_NORMS_TEXT); + EXPECT_TRUE(fields && fields.size() == 1); + EXPECT_EQ(fields[0]->stringValue(), DocHelper::NO_NORMS_TEXT); fields = doc->getFields(DocHelper::TEXT_FIELD_3_KEY); - BOOST_CHECK(fields && fields.size() == 1); - BOOST_CHECK_EQUAL(fields[0]->stringValue(), DocHelper::FIELD_3_TEXT); - + EXPECT_TRUE(fields && fields.size() == 1); + EXPECT_EQ(fields[0]->stringValue(), DocHelper::FIELD_3_TEXT); + // test that the norms are not present in the segment if omitNorms is true for (int32_t i = 0; i < reader->core->fieldInfos->size(); ++i) { FieldInfoPtr fi = reader->core->fieldInfos->fieldInfo(i); if (fi->isIndexed) - BOOST_CHECK(fi->omitNorms == !reader->hasNorms(fi->name)); + EXPECT_TRUE(fi->omitNorms == !reader->hasNorms(fi->name)); } } namespace TestPositionIncrementGap { DECLARE_SHARED_PTR(TestableAnalyzer) - + class TestableAnalyzer : public Analyzer { public: virtual ~TestableAnalyzer() { } - + LUCENE_CLASS(TestableAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(reader); } - + virtual int32_t getPositionIncrementGap(const String& fieldName) { return 500; @@ -120,10 +118,10 @@ namespace TestPositionIncrementGap }; } -BOOST_AUTO_TEST_CASE(testPositionIncrementGap) +TEST_F(DocumentWriterTest, testPositionIncrementGap) { RAMDirectoryPtr dir = newLucene(); - + AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -138,18 +136,18 @@ BOOST_AUTO_TEST_CASE(testPositionIncrementGap) SegmentReaderPtr reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); TermPositionsPtr termPositions = reader->termPositions(newLucene(L"repeated", L"repeated")); - BOOST_CHECK(termPositions->next()); + EXPECT_TRUE(termPositions->next()); int32_t freq = termPositions->freq(); - BOOST_CHECK_EQUAL(2, freq); - BOOST_CHECK_EQUAL(0, termPositions->nextPosition()); - BOOST_CHECK_EQUAL(502, termPositions->nextPosition()); + EXPECT_EQ(2, freq); + EXPECT_EQ(0, termPositions->nextPosition()); + EXPECT_EQ(502, termPositions->nextPosition()); } namespace TestTokenReuse { DECLARE_SHARED_PTR(TestableTokenFilter) DECLARE_SHARED_PTR(TestableAnalyzer) - + class TestableTokenFilter : public TokenFilter { public: @@ -160,20 +158,20 @@ namespace TestTokenReuse payloadAtt = addAttribute(); posIncrAtt = addAttribute(); } - + virtual ~TestableTokenFilter() { } - + LUCENE_CLASS(TestableTokenFilter); - + public: bool first; AttributeSourceStatePtr state; TermAttributePtr termAtt; PayloadAttributePtr payloadAtt; PositionIncrementAttributePtr posIncrAtt; - + public: virtual bool incrementToken() { @@ -183,12 +181,12 @@ namespace TestTokenReuse payloadAtt->setPayload(PayloadPtr()); posIncrAtt->setPositionIncrement(0); static const wchar_t buffer[] = L"b"; - + termAtt->setTermBuffer(buffer, 0, 1); state.reset(); return true; } - + bool hasNext = input->incrementToken(); if (!hasNext) return false; @@ -198,7 +196,7 @@ namespace TestTokenReuse { ByteArray payload = ByteArray::newInstance(1); payload.get()[0] = 100; - + // set payload on first position only payloadAtt->setPayload(newLucene(payload)); first = false; @@ -208,16 +206,16 @@ namespace TestTokenReuse return true; } }; - + class TestableAnalyzer : public Analyzer { public: virtual ~TestableAnalyzer() { } - + LUCENE_CLASS(TestableAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { @@ -226,10 +224,10 @@ namespace TestTokenReuse }; } -BOOST_AUTO_TEST_CASE(testTokenReuse) +TEST_F(DocumentWriterTest, testTokenReuse) { RAMDirectoryPtr dir = newLucene(); - + AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -243,21 +241,21 @@ BOOST_AUTO_TEST_CASE(testTokenReuse) SegmentReaderPtr reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); TermPositionsPtr termPositions = reader->termPositions(newLucene(L"f1", L"a")); - BOOST_CHECK(termPositions->next()); + EXPECT_TRUE(termPositions->next()); int32_t freq = termPositions->freq(); - BOOST_CHECK_EQUAL(3, freq); - BOOST_CHECK_EQUAL(0, termPositions->nextPosition()); - BOOST_CHECK_EQUAL(true, termPositions->isPayloadAvailable()); - BOOST_CHECK_EQUAL(6, termPositions->nextPosition()); - BOOST_CHECK_EQUAL(false, termPositions->isPayloadAvailable()); - BOOST_CHECK_EQUAL(7, termPositions->nextPosition()); - BOOST_CHECK_EQUAL(false, termPositions->isPayloadAvailable()); + EXPECT_EQ(3, freq); + EXPECT_EQ(0, termPositions->nextPosition()); + EXPECT_EQ(true, termPositions->isPayloadAvailable()); + EXPECT_EQ(6, termPositions->nextPosition()); + EXPECT_EQ(false, termPositions->isPayloadAvailable()); + EXPECT_EQ(7, termPositions->nextPosition()); + EXPECT_EQ(false, termPositions->isPayloadAvailable()); } namespace TestPreAnalyzedField { DECLARE_SHARED_PTR(TestableTokenStream) - + class TestableTokenStream : public TokenStream { public: @@ -267,18 +265,18 @@ namespace TestPreAnalyzedField index = 0; termAtt = addAttribute(); } - + virtual ~TestableTokenStream() { } - + LUCENE_CLASS(TestableTokenStream); - + protected: Collection tokens; int32_t index; TermAttributePtr termAtt; - + public: virtual bool incrementToken() { @@ -294,13 +292,13 @@ namespace TestPreAnalyzedField }; } -BOOST_AUTO_TEST_CASE(testPreAnalyzedField) +TEST_F(DocumentWriterTest, testPreAnalyzedField) { RAMDirectoryPtr dir = newLucene(); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); - + doc->add(newLucene(L"preanalyzed", newLucene(), Field::TERM_VECTOR_NO)); writer->addDocument(doc); @@ -310,24 +308,24 @@ BOOST_AUTO_TEST_CASE(testPreAnalyzedField) SegmentReaderPtr reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); TermPositionsPtr termPositions = reader->termPositions(newLucene(L"preanalyzed", L"term1")); - BOOST_CHECK(termPositions->next()); - BOOST_CHECK_EQUAL(1, termPositions->freq()); - BOOST_CHECK_EQUAL(0, termPositions->nextPosition()); + EXPECT_TRUE(termPositions->next()); + EXPECT_EQ(1, termPositions->freq()); + EXPECT_EQ(0, termPositions->nextPosition()); termPositions->seek(newLucene(L"preanalyzed", L"term2")); - BOOST_CHECK(termPositions->next()); - BOOST_CHECK_EQUAL(2, termPositions->freq()); - BOOST_CHECK_EQUAL(1, termPositions->nextPosition()); - BOOST_CHECK_EQUAL(3, termPositions->nextPosition()); - + EXPECT_TRUE(termPositions->next()); + EXPECT_EQ(2, termPositions->freq()); + EXPECT_EQ(1, termPositions->nextPosition()); + EXPECT_EQ(3, termPositions->nextPosition()); + termPositions->seek(newLucene(L"preanalyzed", L"term3")); - BOOST_CHECK(termPositions->next()); - BOOST_CHECK_EQUAL(1, termPositions->freq()); - BOOST_CHECK_EQUAL(2, termPositions->nextPosition()); + EXPECT_TRUE(termPositions->next()); + EXPECT_EQ(1, termPositions->freq()); + EXPECT_EQ(2, termPositions->nextPosition()); } /// Test adding two fields with the same name, but with different term vector setting -BOOST_AUTO_TEST_CASE(testMixedTermVectorSettingsSameField) +TEST_F(DocumentWriterTest, testMixedTermVectorSettingsSameField) { RAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); @@ -347,17 +345,17 @@ BOOST_AUTO_TEST_CASE(testMixedTermVectorSettingsSameField) IndexReaderPtr reader = IndexReader::open(dir, true); // f1 TermFreqVectorPtr tfv1 = reader->getTermFreqVector(0, L"f1"); - BOOST_CHECK(tfv1); - BOOST_CHECK_EQUAL(2, tfv1->getTerms().size()); + EXPECT_TRUE(tfv1); + EXPECT_EQ(2, tfv1->getTerms().size()); // f2 TermFreqVectorPtr tfv2 = reader->getTermFreqVector(0, L"f2"); - BOOST_CHECK(tfv2); - BOOST_CHECK_EQUAL(2, tfv2->getTerms().size()); + EXPECT_TRUE(tfv2); + EXPECT_EQ(2, tfv2->getTerms().size()); } -/// Test adding two fields with the same name, one indexed the other stored only. The omitNorms and +/// Test adding two fields with the same name, one indexed the other stored only. The omitNorms and /// omitTermFreqAndPositions setting of the stored field should not affect the indexed one -BOOST_AUTO_TEST_CASE(testMixedTermVectorSettingsSameField2) +TEST_F(DocumentWriterTest, testMixedTermVectorSettingsSameField2) { RAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); @@ -380,11 +378,9 @@ BOOST_AUTO_TEST_CASE(testMixedTermVectorSettingsSameField2) SegmentReaderPtr reader = SegmentReader::getOnlySegmentReader(dir); FieldInfosPtr fi = reader->fieldInfos(); // f1 - BOOST_CHECK(!reader->hasNorms(L"f1")); - BOOST_CHECK(!fi->fieldInfo(L"f1")->omitTermFreqAndPositions); + EXPECT_TRUE(!reader->hasNorms(L"f1")); + EXPECT_TRUE(!fi->fieldInfo(L"f1")->omitTermFreqAndPositions); // f2 - BOOST_CHECK(reader->hasNorms(L"f2")); - BOOST_CHECK(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); + EXPECT_TRUE(reader->hasNorms(L"f2")); + EXPECT_TRUE(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/FieldInfosTest.cpp b/src/test/index/FieldInfosTest.cpp index 9a6afc5c..43f10c8d 100644 --- a/src/test/index/FieldInfosTest.cpp +++ b/src/test/index/FieldInfosTest.cpp @@ -16,59 +16,55 @@ using namespace Lucene; -class FieldInfosTestFixture : public LuceneTestFixture, public DocHelper +class FieldInfosTest : public LuceneTestFixture, public DocHelper { public: - virtual ~FieldInfosTestFixture() + virtual ~FieldInfosTest() { } }; -BOOST_FIXTURE_TEST_SUITE(FieldInfosTest, FieldInfosTestFixture) - -BOOST_AUTO_TEST_CASE(testFieldInfos) +TEST_F(FieldInfosTest, testFieldInfos) { DocumentPtr testDoc = newLucene(); DocHelper::setupDoc(testDoc); - + // Positive test of FieldInfos - BOOST_CHECK(testDoc); + EXPECT_TRUE(testDoc); FieldInfosPtr fieldInfos = newLucene(); fieldInfos->add(testDoc); // Since the complement is stored as well in the fields map - BOOST_CHECK(fieldInfos->size() == DocHelper::all.size()); // this is all because we are using the no-arg constructor + EXPECT_TRUE(fieldInfos->size() == DocHelper::all.size()); // this is all because we are using the no-arg constructor RAMDirectoryPtr dir = newLucene(); String name = L"testFile"; IndexOutputPtr output = dir->createOutput(name); - BOOST_CHECK(output); + EXPECT_TRUE(output); // Use a RAMOutputStream fieldInfos->write(output); output->close(); - BOOST_CHECK(output->length() > 0); + EXPECT_TRUE(output->length() > 0); FieldInfosPtr readIn = newLucene(dir, name); - BOOST_CHECK(fieldInfos->size() == readIn->size()); + EXPECT_TRUE(fieldInfos->size() == readIn->size()); FieldInfoPtr info = readIn->fieldInfo(L"textField1"); - BOOST_CHECK(info); - BOOST_CHECK(!info->storeTermVector); - BOOST_CHECK(!info->omitNorms); + EXPECT_TRUE(info); + EXPECT_TRUE(!info->storeTermVector); + EXPECT_TRUE(!info->omitNorms); info = readIn->fieldInfo(L"textField2"); - BOOST_CHECK(info); - BOOST_CHECK(info->storeTermVector); - BOOST_CHECK(!info->omitNorms); + EXPECT_TRUE(info); + EXPECT_TRUE(info->storeTermVector); + EXPECT_TRUE(!info->omitNorms); info = readIn->fieldInfo(L"textField3"); - BOOST_CHECK(info); - BOOST_CHECK(!info->storeTermVector); - BOOST_CHECK(info->omitNorms); + EXPECT_TRUE(info); + EXPECT_TRUE(!info->storeTermVector); + EXPECT_TRUE(info->omitNorms); info = readIn->fieldInfo(L"omitNorms"); - BOOST_CHECK(info); - BOOST_CHECK(!info->storeTermVector); - BOOST_CHECK(info->omitNorms); + EXPECT_TRUE(info); + EXPECT_TRUE(!info->storeTermVector); + EXPECT_TRUE(info->omitNorms); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/FieldsReaderTest.cpp b/src/test/index/FieldsReaderTest.cpp index 31e12363..317bca69 100644 --- a/src/test/index/FieldsReaderTest.cpp +++ b/src/test/index/FieldsReaderTest.cpp @@ -25,10 +25,10 @@ using namespace Lucene; -class FieldsReaderTestFixture : public LuceneTestFixture, public DocHelper +class FieldsReaderTest : public LuceneTestFixture, public DocHelper { public: - FieldsReaderTestFixture() + FieldsReaderTest() { dir = newLucene(); testDoc = newLucene(); @@ -40,8 +40,8 @@ class FieldsReaderTestFixture : public LuceneTestFixture, public DocHelper writer->addDocument(testDoc); writer->close(); } - - virtual ~FieldsReaderTestFixture() + + virtual ~FieldsReaderTest() { } @@ -49,11 +49,11 @@ class FieldsReaderTestFixture : public LuceneTestFixture, public DocHelper RAMDirectoryPtr dir; DocumentPtr testDoc; FieldInfosPtr fieldInfos; - + static String TEST_SEGMENT_NAME; }; -String FieldsReaderTestFixture::TEST_SEGMENT_NAME = L"_0"; +String FieldsReaderTest::TEST_SEGMENT_NAME = L"_0"; DECLARE_SHARED_PTR(FaultyFSDirectory) DECLARE_SHARED_PTR(FaultyIndexInput) @@ -66,45 +66,45 @@ class FaultyIndexInput : public BufferedIndexInput this->delegate = delegate; count = 0; } - + virtual ~FaultyIndexInput() { } - + LUCENE_CLASS(FaultyIndexInput); public: IndexInputPtr delegate; static bool doFail; int32_t count; - + public: virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) { simOutage(); delegate->readBytes(b, offset, length); } - + virtual void seekInternal(int64_t pos) { delegate->seek(pos); } - + virtual int64_t length() { return delegate->length(); } - + virtual void close() { delegate->close(); } - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(delegate->clone())); } - + protected: void simOutage() { @@ -123,57 +123,57 @@ class FaultyFSDirectory : public Directory fsDir = FSDirectory::open(dir); lockFactory = fsDir->getLockFactory(); } - + virtual ~FaultyFSDirectory() { } - + LUCENE_CLASS(FaultyFSDirectory); public: FSDirectoryPtr fsDir; - + public: virtual IndexInputPtr openInput(const String& name) { return newLucene(fsDir->openInput(name)); } - + virtual HashSet listAll() { return fsDir->listAll(); } - + virtual bool fileExists(const String& name) { return fsDir->fileExists(name); } - + virtual uint64_t fileModified(const String& name) { return fsDir->fileModified(name); } - + virtual void touchFile(const String& name) { fsDir->touchFile(name); } - + virtual void deleteFile(const String& name) { fsDir->deleteFile(name); } - + virtual int64_t fileLength(const String& name) { return fsDir->fileLength(name); } - + virtual IndexOutputPtr createOutput(const String& name) { return fsDir->createOutput(name); } - + virtual void close() { fsDir->close(); @@ -182,59 +182,57 @@ class FaultyFSDirectory : public Directory static void checkSizeEquals(int32_t size, const uint8_t* sizebytes) { - BOOST_CHECK_EQUAL((uint8_t)MiscUtils::unsignedShift(size, 24), sizebytes[0]); - BOOST_CHECK_EQUAL((uint8_t)MiscUtils::unsignedShift(size, 16), sizebytes[1]); - BOOST_CHECK_EQUAL((uint8_t)MiscUtils::unsignedShift(size, 8), sizebytes[2]); - BOOST_CHECK_EQUAL((uint8_t)size, sizebytes[3]); + EXPECT_EQ((uint8_t)MiscUtils::unsignedShift(size, 24), sizebytes[0]); + EXPECT_EQ((uint8_t)MiscUtils::unsignedShift(size, 16), sizebytes[1]); + EXPECT_EQ((uint8_t)MiscUtils::unsignedShift(size, 8), sizebytes[2]); + EXPECT_EQ((uint8_t)size, sizebytes[3]); } -BOOST_FIXTURE_TEST_SUITE(FieldsReaderTest, FieldsReaderTestFixture) - -BOOST_AUTO_TEST_CASE(testFieldsReader) +TEST_F(FieldsReaderTest, testFieldsReader) { - BOOST_CHECK(dir); - BOOST_CHECK(fieldInfos); + EXPECT_TRUE(dir); + EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); - BOOST_CHECK(reader); - BOOST_CHECK(reader->size() == 1); + EXPECT_TRUE(reader); + EXPECT_TRUE(reader->size() == 1); DocumentPtr doc = reader->doc(0, FieldSelectorPtr()); - BOOST_CHECK(doc); - BOOST_CHECK(doc->getField(DocHelper::TEXT_FIELD_1_KEY)); + EXPECT_TRUE(doc); + EXPECT_TRUE(doc->getField(DocHelper::TEXT_FIELD_1_KEY)); FieldablePtr field = doc->getField(DocHelper::TEXT_FIELD_2_KEY); - BOOST_CHECK(field); - BOOST_CHECK(field->isTermVectorStored()); + EXPECT_TRUE(field); + EXPECT_TRUE(field->isTermVectorStored()); - BOOST_CHECK(field->isStoreOffsetWithTermVector()); - BOOST_CHECK(field->isStorePositionWithTermVector()); - BOOST_CHECK(!field->getOmitNorms()); - BOOST_CHECK(!field->getOmitTermFreqAndPositions()); + EXPECT_TRUE(field->isStoreOffsetWithTermVector()); + EXPECT_TRUE(field->isStorePositionWithTermVector()); + EXPECT_TRUE(!field->getOmitNorms()); + EXPECT_TRUE(!field->getOmitTermFreqAndPositions()); field = doc->getField(DocHelper::TEXT_FIELD_3_KEY); - BOOST_CHECK(field); - BOOST_CHECK(!field->isTermVectorStored()); - BOOST_CHECK(!field->isStoreOffsetWithTermVector()); - BOOST_CHECK(!field->isStorePositionWithTermVector()); - BOOST_CHECK(field->getOmitNorms()); - BOOST_CHECK(!field->getOmitTermFreqAndPositions()); + EXPECT_TRUE(field); + EXPECT_TRUE(!field->isTermVectorStored()); + EXPECT_TRUE(!field->isStoreOffsetWithTermVector()); + EXPECT_TRUE(!field->isStorePositionWithTermVector()); + EXPECT_TRUE(field->getOmitNorms()); + EXPECT_TRUE(!field->getOmitTermFreqAndPositions()); field = doc->getField(DocHelper::NO_TF_KEY); - BOOST_CHECK(field); - BOOST_CHECK(!field->isTermVectorStored()); - BOOST_CHECK(!field->isStoreOffsetWithTermVector()); - BOOST_CHECK(!field->isStorePositionWithTermVector()); - BOOST_CHECK(!field->getOmitNorms()); - BOOST_CHECK(field->getOmitTermFreqAndPositions()); + EXPECT_TRUE(field); + EXPECT_TRUE(!field->isTermVectorStored()); + EXPECT_TRUE(!field->isStoreOffsetWithTermVector()); + EXPECT_TRUE(!field->isStorePositionWithTermVector()); + EXPECT_TRUE(!field->getOmitNorms()); + EXPECT_TRUE(field->getOmitTermFreqAndPositions()); reader->close(); } -BOOST_AUTO_TEST_CASE(testLazyFields) +TEST_F(FieldsReaderTest, testLazyFields) { - BOOST_CHECK(dir); - BOOST_CHECK(fieldInfos); + EXPECT_TRUE(dir); + EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); - BOOST_CHECK(reader); - BOOST_CHECK(reader->size() == 1); + EXPECT_TRUE(reader); + EXPECT_TRUE(reader->size() == 1); HashSet loadFieldNames = HashSet::newInstance(); loadFieldNames.add(DocHelper::TEXT_FIELD_1_KEY); loadFieldNames.add(DocHelper::TEXT_FIELD_UTF1_KEY); @@ -245,44 +243,44 @@ BOOST_AUTO_TEST_CASE(testLazyFields) lazyFieldNames.add(DocHelper::TEXT_FIELD_UTF2_KEY); SetBasedFieldSelectorPtr fieldSelector = newLucene(loadFieldNames, lazyFieldNames); DocumentPtr doc = reader->doc(0, fieldSelector); - BOOST_CHECK(doc); + EXPECT_TRUE(doc); FieldablePtr field = doc->getFieldable(DocHelper::LAZY_FIELD_KEY); - BOOST_CHECK(field); - BOOST_CHECK(field->isLazy()); + EXPECT_TRUE(field); + EXPECT_TRUE(field->isLazy()); String value = field->stringValue(); - BOOST_CHECK(!value.empty()); - BOOST_CHECK_EQUAL(value, DocHelper::LAZY_FIELD_TEXT); + EXPECT_TRUE(!value.empty()); + EXPECT_EQ(value, DocHelper::LAZY_FIELD_TEXT); field = doc->getFieldable(DocHelper::TEXT_FIELD_1_KEY); - BOOST_CHECK(field); - BOOST_CHECK(!field->isLazy()); + EXPECT_TRUE(field); + EXPECT_TRUE(!field->isLazy()); field = doc->getFieldable(DocHelper::TEXT_FIELD_UTF1_KEY); - BOOST_CHECK(field); - BOOST_CHECK(!field->isLazy()); - BOOST_CHECK_EQUAL(field->stringValue(), DocHelper::FIELD_UTF1_TEXT); + EXPECT_TRUE(field); + EXPECT_TRUE(!field->isLazy()); + EXPECT_EQ(field->stringValue(), DocHelper::FIELD_UTF1_TEXT); field = doc->getFieldable(DocHelper::TEXT_FIELD_UTF2_KEY); - BOOST_CHECK(field); - BOOST_CHECK(field->isLazy()); - BOOST_CHECK_EQUAL(field->stringValue(), DocHelper::FIELD_UTF2_TEXT); + EXPECT_TRUE(field); + EXPECT_TRUE(field->isLazy()); + EXPECT_EQ(field->stringValue(), DocHelper::FIELD_UTF2_TEXT); field = doc->getFieldable(DocHelper::LAZY_FIELD_BINARY_KEY); - BOOST_CHECK(field); - BOOST_CHECK(field->stringValue().empty()); + EXPECT_TRUE(field); + EXPECT_TRUE(field->stringValue().empty()); ByteArray bytes = field->getBinaryValue(); - BOOST_CHECK(bytes); - BOOST_CHECK_EQUAL(DocHelper::LAZY_FIELD_BINARY_BYTES.size(), bytes.size()); - BOOST_CHECK(bytes); - BOOST_CHECK(bytes.equals(DocHelper::LAZY_FIELD_BINARY_BYTES)); + EXPECT_TRUE(bytes); + EXPECT_EQ(DocHelper::LAZY_FIELD_BINARY_BYTES.size(), bytes.size()); + EXPECT_TRUE(bytes); + EXPECT_TRUE(bytes.equals(DocHelper::LAZY_FIELD_BINARY_BYTES)); } -BOOST_AUTO_TEST_CASE(testLazyFieldsAfterClose) +TEST_F(FieldsReaderTest, testLazyFieldsAfterClose) { - BOOST_CHECK(dir); - BOOST_CHECK(fieldInfos); + EXPECT_TRUE(dir); + EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); - BOOST_CHECK(reader); - BOOST_CHECK(reader->size() == 1); + EXPECT_TRUE(reader); + EXPECT_TRUE(reader->size() == 1); HashSet loadFieldNames = HashSet::newInstance(); loadFieldNames.add(DocHelper::TEXT_FIELD_1_KEY); loadFieldNames.add(DocHelper::TEXT_FIELD_UTF1_KEY); @@ -293,50 +291,57 @@ BOOST_AUTO_TEST_CASE(testLazyFieldsAfterClose) lazyFieldNames.add(DocHelper::TEXT_FIELD_UTF2_KEY); SetBasedFieldSelectorPtr fieldSelector = newLucene(loadFieldNames, lazyFieldNames); DocumentPtr doc = reader->doc(0, fieldSelector); - BOOST_CHECK(doc); + EXPECT_TRUE(doc); FieldablePtr field = doc->getFieldable(DocHelper::LAZY_FIELD_KEY); - BOOST_CHECK(field); - BOOST_CHECK(field->isLazy()); + EXPECT_TRUE(field); + EXPECT_TRUE(field->isLazy()); reader->close(); - BOOST_CHECK_EXCEPTION(field->stringValue(), AlreadyClosedException, check_exception(LuceneException::AlreadyClosed)); + try + { + field->stringValue(); + } + catch (AlreadyClosedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } } -BOOST_AUTO_TEST_CASE(testLoadFirst) +TEST_F(FieldsReaderTest, testLoadFirst) { - BOOST_CHECK(dir); - BOOST_CHECK(fieldInfos); + EXPECT_TRUE(dir); + EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); - BOOST_CHECK(reader); - BOOST_CHECK(reader->size() == 1); + EXPECT_TRUE(reader); + EXPECT_TRUE(reader->size() == 1); LoadFirstFieldSelectorPtr fieldSelector = newLucene(); DocumentPtr doc = reader->doc(0, fieldSelector); - BOOST_CHECK(doc); + EXPECT_TRUE(doc); int32_t count = 0; Collection fields = doc->getFields(); for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { - BOOST_CHECK(*field); + EXPECT_TRUE(*field); String sv = (*field)->stringValue(); - BOOST_CHECK(!sv.empty()); + EXPECT_TRUE(!sv.empty()); ++count; } - BOOST_CHECK_EQUAL(count, 1); + EXPECT_EQ(count, 1); } /// Not really a test per se, but we should have some way of assessing whether this is worthwhile. /// Must test using a File based directory. -BOOST_AUTO_TEST_CASE(testLazyPerformance) +TEST_F(FieldsReaderTest, testLazyPerformance) { String path(FileUtils::joinPath(getTempDir(), L"lazyDir")); FSDirectoryPtr tmpDir = FSDirectory::open(path); - BOOST_CHECK(tmpDir); + EXPECT_TRUE(tmpDir); IndexWriterPtr writer = newLucene(tmpDir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(false); writer->addDocument(testDoc); writer->close(); - BOOST_CHECK(fieldInfos); + EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader; int64_t lazyTime = 0; int64_t regularTime = 0; @@ -344,22 +349,22 @@ BOOST_AUTO_TEST_CASE(testLazyPerformance) HashSet lazyFieldNames = HashSet::newInstance(); lazyFieldNames.add(DocHelper::LARGE_LAZY_FIELD_KEY); SetBasedFieldSelectorPtr fieldSelector = newLucene(HashSet::newInstance(), lazyFieldNames); - + for (int32_t i = 0; i < length; ++i) { reader = newLucene(tmpDir, TEST_SEGMENT_NAME, fieldInfos); - BOOST_CHECK(reader); - BOOST_CHECK(reader->size() == 1); + EXPECT_TRUE(reader); + EXPECT_TRUE(reader->size() == 1); DocumentPtr doc = reader->doc(0, FieldSelectorPtr()); // Load all of them - BOOST_CHECK(doc); + EXPECT_TRUE(doc); FieldablePtr field = doc->getFieldable(DocHelper::LARGE_LAZY_FIELD_KEY); - BOOST_CHECK(!field->isLazy()); + EXPECT_TRUE(!field->isLazy()); int64_t start = MiscUtils::currentTimeMillis(); String value = field->stringValue(); int64_t finish = MiscUtils::currentTimeMillis(); // ~ 0ms - BOOST_CHECK(!value.empty()); - BOOST_CHECK(field); + EXPECT_TRUE(!value.empty()); + EXPECT_TRUE(field); regularTime += (finish - start); reader->close(); reader.reset(); @@ -367,17 +372,17 @@ BOOST_AUTO_TEST_CASE(testLazyPerformance) reader = newLucene(tmpDir, TEST_SEGMENT_NAME, fieldInfos); doc = reader->doc(0, fieldSelector); field = doc->getFieldable(DocHelper::LARGE_LAZY_FIELD_KEY); - BOOST_CHECK(field->isLazy()); + EXPECT_TRUE(field->isLazy()); start = MiscUtils::currentTimeMillis(); value = field->stringValue(); finish = MiscUtils::currentTimeMillis(); // ~ 50 - 70ms - BOOST_CHECK(!value.empty()); + EXPECT_TRUE(!value.empty()); lazyTime += (finish - start); reader->close(); } - - BOOST_TEST_MESSAGE("Average Non-lazy time (should be very close to zero): " << (regularTime / length) << " ms for " << length << " reads"); - BOOST_TEST_MESSAGE("Average Lazy Time (should be greater than zero): " << (lazyTime / length) << " ms for " << length << " reads"); + + // std::cout << "Average Non-lazy time (should be very close to zero): " << (regularTime / length) << " ms for " << length << " reads"; + // std::cout << "Average Lazy Time (should be greater than zero): " << (lazyTime / length) << " ms for " << length << " reads"; FileUtils::removeDirectory(path); } @@ -385,16 +390,16 @@ BOOST_AUTO_TEST_CASE(testLazyPerformance) namespace TestLoadSize { DECLARE_SHARED_PTR(TestableFieldSelector) - + class TestableFieldSelector : public FieldSelector { public: virtual ~TestableFieldSelector() { } - + LUCENE_CLASS(TestableFieldSelector); - + public: virtual FieldSelectorResult accept(const String& fieldName) { @@ -408,7 +413,7 @@ namespace TestLoadSize }; } -BOOST_AUTO_TEST_CASE(testLoadSize) +TEST_F(FieldsReaderTest, testLoadSize) { FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); DocumentPtr doc = reader->doc(0, newLucene()); @@ -416,17 +421,17 @@ BOOST_AUTO_TEST_CASE(testLoadSize) FieldablePtr f1 = doc->getFieldable(DocHelper::TEXT_FIELD_1_KEY); FieldablePtr f3 = doc->getFieldable(DocHelper::TEXT_FIELD_3_KEY); FieldablePtr fb = doc->getFieldable(DocHelper::LAZY_FIELD_BINARY_KEY); - BOOST_CHECK(f1->isBinary()); - BOOST_CHECK(!f3->isBinary()); - BOOST_CHECK(fb->isBinary()); + EXPECT_TRUE(f1->isBinary()); + EXPECT_TRUE(!f3->isBinary()); + EXPECT_TRUE(fb->isBinary()); checkSizeEquals(2 * String(DocHelper::FIELD_1_TEXT).length(), f1->getBinaryValue().get()); - BOOST_CHECK_EQUAL(DocHelper::FIELD_3_TEXT, f3->stringValue()); + EXPECT_EQ(DocHelper::FIELD_3_TEXT, f3->stringValue()); checkSizeEquals(DocHelper::LAZY_FIELD_BINARY_BYTES.size(), fb->getBinaryValue().get()); reader->close(); } -BOOST_AUTO_TEST_CASE(testExceptions) +TEST_F(FieldsReaderTest, testExceptions) { String indexDir(FileUtils::joinPath(getTempDir(), L"testfieldswriterexceptions")); @@ -445,7 +450,7 @@ BOOST_AUTO_TEST_CASE(testExceptions) FaultyIndexInput::doFail = true; bool exc = false; - + for (int32_t i = 0; i < 2; ++i) { try @@ -465,7 +470,7 @@ BOOST_AUTO_TEST_CASE(testExceptions) exc = true; // expected } } - BOOST_CHECK(exc); + EXPECT_TRUE(exc); reader->close(); dir->close(); } @@ -476,5 +481,3 @@ BOOST_AUTO_TEST_CASE(testExceptions) FileUtils::removeDirectory(indexDir); finally.throwException(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/FilterIndexReaderTest.cpp b/src/test/index/FilterIndexReaderTest.cpp index 6358ee5b..ef01ce2e 100644 --- a/src/test/index/FilterIndexReaderTest.cpp +++ b/src/test/index/FilterIndexReaderTest.cpp @@ -30,11 +30,11 @@ class TestTermEnum : public FilterTermEnum TestTermEnum(TermEnumPtr termEnum) : FilterTermEnum(termEnum) { } - + virtual ~TestTermEnum() { } - + LUCENE_CLASS(TestTermEnum); public: @@ -56,11 +56,11 @@ class TestTermPositions : public FilterTermPositions TestTermPositions(TermPositionsPtr in) : FilterTermPositions(in) { } - + virtual ~TestTermPositions() { } - + LUCENE_CLASS(TestTermPositions); public: @@ -81,11 +81,11 @@ class TestReader : public FilterIndexReader TestReader(IndexReaderPtr reader) : FilterIndexReader(reader) { } - + virtual ~TestReader() { } - + LUCENE_CLASS(TestReader); public: @@ -94,7 +94,7 @@ class TestReader : public FilterIndexReader { return newLucene(in->terms()); } - + /// Filter positions with TestTermPositions. virtual TermPositionsPtr termPositions() { @@ -102,10 +102,10 @@ class TestReader : public FilterIndexReader } }; -BOOST_FIXTURE_TEST_SUITE(FilterIndexReaderTest, LuceneTestFixture) +typedef LuceneTestFixture FilterIndexReaderTest; /// Tests the IndexReader::getFieldNames implementation -BOOST_AUTO_TEST_CASE(testFilterIndexReader) +TEST_F(FilterIndexReaderTest, testFilterIndexReader) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -126,29 +126,27 @@ BOOST_AUTO_TEST_CASE(testFilterIndexReader) IndexReaderPtr reader = newLucene(IndexReader::open(directory, true)); - BOOST_CHECK(reader->isOptimized()); + EXPECT_TRUE(reader->isOptimized()); TermEnumPtr terms = reader->terms(); while (terms->next()) - BOOST_CHECK_NE(terms->term()->text().find(L'e'), String::npos); + EXPECT_NE(terms->term()->text().find(L'e'), String::npos); terms->close(); - + TermPositionsPtr positions = reader->termPositions(newLucene(L"default", L"one")); while (positions->next()) - BOOST_CHECK((positions->doc() % 2) == 1); - + EXPECT_TRUE((positions->doc() % 2) == 1); + int32_t NUM_DOCS = 3; - + TermDocsPtr td = reader->termDocs(TermPtr()); for (int32_t i = 0; i < NUM_DOCS; ++i) { - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(i, td->doc()); - BOOST_CHECK_EQUAL(1, td->freq()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(i, td->doc()); + EXPECT_EQ(1, td->freq()); } td->close(); reader->close(); directory->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexCommitTest.cpp b/src/test/index/IndexCommitTest.cpp index 7c9fb941..36c1fa5a 100644 --- a/src/test/index/IndexCommitTest.cpp +++ b/src/test/index/IndexCommitTest.cpp @@ -11,7 +11,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexCommitTest, LuceneTestFixture) +typedef LuceneTestFixture IndexCommitTest; namespace TestEqualsHashCode { @@ -22,7 +22,7 @@ namespace TestEqualsHashCode { this->dir = dir; } - + virtual ~TestIndexCommit1() { } @@ -35,63 +35,63 @@ namespace TestEqualsHashCode { return L"a"; } - + virtual int64_t getVersion() { return 12; } - + virtual DirectoryPtr getDirectory() { return dir; } - + virtual HashSet getFileNames() { return HashSet(); } - + virtual void deleteCommit() { } - + virtual int64_t getGeneration() { return 0; } - + virtual int64_t getTimestamp() { return -1; } - + virtual MapStringString getUserData() { return MapStringString(); } - + virtual bool isDeleted() { return false; } - + virtual bool isOptimized() { return false; } }; - + class TestIndexCommit2 : public TestIndexCommit1 { public: TestIndexCommit2(DirectoryPtr dir) : TestIndexCommit1(dir) { } - + virtual ~TestIndexCommit2() { } - + public: virtual String getSegmentsFileName() { @@ -100,15 +100,13 @@ namespace TestEqualsHashCode }; } -BOOST_AUTO_TEST_CASE(testEqualsHashCode) +TEST_F(IndexCommitTest, testEqualsHashCode) { DirectoryPtr dir = newLucene(); - + IndexCommitPtr ic1 = newLucene(dir); IndexCommitPtr ic2 = newLucene(dir); - - BOOST_CHECK(ic1->equals(ic2)); - BOOST_CHECK_EQUAL(ic1->hashCode(), ic2->hashCode()); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_TRUE(ic1->equals(ic2)); + EXPECT_EQ(ic1->hashCode(), ic2->hashCode()); +} diff --git a/src/test/index/IndexFileDeleterTest.cpp b/src/test/index/IndexFileDeleterTest.cpp index d0fee994..c89e1628 100644 --- a/src/test/index/IndexFileDeleterTest.cpp +++ b/src/test/index/IndexFileDeleterTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexFileDeleterTest, LuceneTestFixture) +typedef LuceneTestFixture IndexFileDeleterTest; static void addDoc(IndexWriterPtr writer, int32_t id) { @@ -72,7 +72,7 @@ static HashSet difFiles(Collection files1, Collection fi return extra; } -BOOST_AUTO_TEST_CASE(testDeleteLeftoverFiles) +TEST_F(IndexFileDeleterTest, testDeleteLeftoverFiles) { DirectoryPtr dir = newLucene(); @@ -85,12 +85,12 @@ BOOST_AUTO_TEST_CASE(testDeleteLeftoverFiles) for (; i < 45; ++i) addDoc(writer, i); writer->close(); - + // Delete one doc so we get a .del file IndexReaderPtr reader = IndexReader::open(dir, false); TermPtr searchTerm = newLucene(L"id", L"7"); int32_t delCount = reader->deleteDocuments(searchTerm); - BOOST_CHECK_EQUAL(1, delCount); + EXPECT_EQ(1, delCount); // Set one norm so we get a .s0 file reader->setNorm(21, L"content", 1.5); @@ -98,8 +98,8 @@ BOOST_AUTO_TEST_CASE(testDeleteLeftoverFiles) // Now, artificially create an extra .del file and extra .s0 file HashSet _files = dir->listAll(); - - // Here we have to figure out which field number corresponds to "content", and then + + // Here we have to figure out which field number corresponds to "content", and then // set our expected file names below accordingly. CompoundFileReaderPtr cfsReader = newLucene(dir, L"_2.cfs"); FieldInfosPtr fieldInfos = newLucene(cfsReader, L"_2.fnm"); @@ -115,31 +115,31 @@ BOOST_AUTO_TEST_CASE(testDeleteLeftoverFiles) } cfsReader->close(); - BOOST_CHECK_NE(contentFieldIndex, -1); + EXPECT_NE(contentFieldIndex, -1); String normSuffix = L"s" + StringUtils::toString(contentFieldIndex); - // Create a bogus separate norms file for a segment/field that actually has a + // Create a bogus separate norms file for a segment/field that actually has a // separate norms file already copyFile(dir, L"_2_1." + normSuffix, L"_2_2." + normSuffix); - // Create a bogus separate norms file for a segment/field that actually has a + // Create a bogus separate norms file for a segment/field that actually has a // separate norms file already, using the "not compound file" extension copyFile(dir, L"_2_1." + normSuffix, L"_2_2.f" + StringUtils::toString(contentFieldIndex)); - // Create a bogus separate norms file for a segment/field that does not have a + // Create a bogus separate norms file for a segment/field that does not have a // separate norms file already copyFile(dir, L"_2_1." + normSuffix, L"_1_1." + normSuffix); - // Create a bogus separate norms file for a segment/field that does not have a + // Create a bogus separate norms file for a segment/field that does not have a // separate norms file already using the "not compound file" extension copyFile(dir, L"_2_1." + normSuffix, L"_1_1.f" + StringUtils::toString(contentFieldIndex)); - // Create a bogus separate del file for a segment that already has a separate + // Create a bogus separate del file for a segment that already has a separate // del file copyFile(dir, L"_0_1.del", L"_0_2.del"); - // Create a bogus separate del file for a segment that does not yet have a + // Create a bogus separate del file for a segment that does not yet have a // separate del file copyFile(dir, L"_0_1.del", L"_1_1.del"); @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(testDeleteLeftoverFiles) copyFile(dir, L"_2.cfs", L"_3.cfs"); HashSet filesPre = dir->listAll(); - + // Open and close a writer: it should delete the above 4 files and nothing more writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->close(); @@ -178,8 +178,6 @@ BOOST_AUTO_TEST_CASE(testDeleteLeftoverFiles) std::sort(files2.begin(), files2.end()); HashSet dif = difFiles(files, files2); - - BOOST_CHECK(dif.empty()); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_TRUE(dif.empty()); +} diff --git a/src/test/index/IndexInputTest.cpp b/src/test/index/IndexInputTest.cpp index 3adf0505..893e71d5 100644 --- a/src/test/index/IndexInputTest.cpp +++ b/src/test/index/IndexInputTest.cpp @@ -11,229 +11,229 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexInputTest, LuceneTestFixture) +typedef LuceneTestFixture IndexInputTest; -BOOST_AUTO_TEST_CASE(testReadInt) +TEST_F(IndexInputTest, testReadInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 1, 2, 3, 4 }; std::memcpy(inputBytes.get(), input, 4); IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readInt(), 16909060); + EXPECT_EQ(is->readInt(), 16909060); } -BOOST_AUTO_TEST_CASE(testReadVInt) +TEST_F(IndexInputTest, testReadVInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 200, 201, 150, 96 }; std::memcpy(inputBytes.get(), input, 4); IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readVInt(), 201696456); + EXPECT_EQ(is->readVInt(), 201696456); } -BOOST_AUTO_TEST_CASE(testReadLong) +TEST_F(IndexInputTest, testReadLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 32, 43, 32, 96, 12, 54, 22, 96 }; std::memcpy(inputBytes.get(), input, 8); IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readLong(), 2317982030106072672LL); + EXPECT_EQ(is->readLong(), 2317982030106072672LL); } -BOOST_AUTO_TEST_CASE(testReadVLong) +TEST_F(IndexInputTest, testReadVLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 213, 143, 132, 196, 172, 154, 129, 96 }; std::memcpy(inputBytes.get(), input, 8); IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readVLong(), 54048498881988565LL); + EXPECT_EQ(is->readVLong(), 54048498881988565LL); } -BOOST_AUTO_TEST_CASE(testReadString) +TEST_F(IndexInputTest, testReadString) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readString(), L"test string"); + EXPECT_EQ(is->readString(), L"test string"); } -BOOST_AUTO_TEST_CASE(testReadModifiedUTF8String) +TEST_F(IndexInputTest, testReadModifiedUTF8String) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readModifiedUTF8String(), L"test string"); + EXPECT_EQ(is->readModifiedUTF8String(), L"test string"); } -BOOST_AUTO_TEST_CASE(testReadChars) +TEST_F(IndexInputTest, testReadChars) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[11] = { 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 11); - + IndexInputPtr is = newLucene(inputBytes); - + ByteArray outputChars(ByteArray::newInstance(40 * sizeof(wchar_t))); is->readChars((wchar_t*)outputChars.get(), 0, 11); - + wchar_t expected[11] = { L't', L'e', L's', L't', L' ', L's', L't', L'r', L'i', L'n', L'g' }; - BOOST_CHECK_EQUAL(std::memcmp((wchar_t*)outputChars.get(), expected, 11 * sizeof(wchar_t)), 0); + EXPECT_EQ(std::memcmp((wchar_t*)outputChars.get(), expected, 11 * sizeof(wchar_t)), 0); } -BOOST_AUTO_TEST_CASE(testSkipOneChar) +TEST_F(IndexInputTest, testSkipOneChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); IndexInputPtr is = newLucene(inputBytes); is->skipChars(1); - BOOST_CHECK_EQUAL(is->getFilePointer(), 1); + EXPECT_EQ(is->getFilePointer(), 1); } -BOOST_AUTO_TEST_CASE(testSkipTwoChars) +TEST_F(IndexInputTest, testSkipTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); IndexInputPtr is = newLucene(inputBytes); is->skipChars(2); - BOOST_CHECK_EQUAL(is->getFilePointer(), 2); + EXPECT_EQ(is->getFilePointer(), 2); } -BOOST_AUTO_TEST_CASE(testSkipTwoCharsAdditionalChar) +TEST_F(IndexInputTest, testSkipTwoCharsAdditionalChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 132, 132, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); IndexInputPtr is = newLucene(inputBytes); is->skipChars(2); - BOOST_CHECK_EQUAL(is->getFilePointer(), 3); + EXPECT_EQ(is->getFilePointer(), 3); } -BOOST_AUTO_TEST_CASE(testSkipTwoCharsAdditionalTwoChars) +TEST_F(IndexInputTest, testSkipTwoCharsAdditionalTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 232, 232, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); IndexInputPtr is = newLucene(inputBytes); is->skipChars(2); - BOOST_CHECK_EQUAL(is->getFilePointer(), 4); + EXPECT_EQ(is->getFilePointer(), 4); } -BOOST_AUTO_TEST_CASE(testRead) +TEST_F(IndexInputTest, testRead) { ByteArray inputBytes(ByteArray::newInstance(100)); - + uint8_t input[88] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, 'L', 'u', 'c', 'e', 'n', 'e', - - // 2-byte UTF-8 (U+00BF "INVERTED QUESTION MARK") + + // 2-byte UTF-8 (U+00BF "INVERTED QUESTION MARK") 0x02, 0xc2, 0xbf, 0x0a, 'L', 'u', 0xc2, 0xbf, 'c', 'e', 0xc2, 0xbf, 'n', 'e', - - // 3-byte UTF-8 (U+2620 "SKULL AND CROSSBONES") + + // 3-byte UTF-8 (U+2620 "SKULL AND CROSSBONES") 0x03, 0xe2, 0x98, 0xa0, 0x0c, 'L', 'u', 0xe2, 0x98, 0xa0, 'c', 'e', 0xe2, 0x98, 0xa0, 'n', 'e', - + // surrogate pairs // (U+1D11E "MUSICAL SYMBOL G CLEF") // (U+1D160 "MUSICAL SYMBOL EIGHTH NOTE") 0x04, 0xf0, 0x9d, 0x84, 0x9e, 0x08, 0xf0, 0x9d, 0x84, 0x9e, 0xf0, 0x9d, 0x85, 0xa0, 0x0e, 'L', 'u', 0xf0, 0x9d, 0x84, 0x9e, 'c', 'e', 0xf0, 0x9d, 0x85, 0xa0, 'n', 'e', - + // null bytes 0x01, 0x00, 0x08, 'L', 'u', 0x00, 'c', 'e', 0x00, 'n', 'e'}; std::memcpy(inputBytes.get(), input, 88); - + IndexInputPtr is = newLucene(inputBytes); - - BOOST_CHECK_EQUAL(is->readVInt(), 128); - BOOST_CHECK_EQUAL(is->readVInt(), 16383); - BOOST_CHECK_EQUAL(is->readVInt(), 16384); - BOOST_CHECK_EQUAL(is->readVInt(), 16385); - BOOST_CHECK_EQUAL(is->readString(), L"Lucene"); - + + EXPECT_EQ(is->readVInt(), 128); + EXPECT_EQ(is->readVInt(), 16383); + EXPECT_EQ(is->readVInt(), 16384); + EXPECT_EQ(is->readVInt(), 16385); + EXPECT_EQ(is->readString(), L"Lucene"); + const uint8_t question[] = {0xc2, 0xbf}; - BOOST_CHECK_EQUAL(is->readString(), UTF8_TO_STRING(question)); + EXPECT_EQ(is->readString(), UTF8_TO_STRING(question)); const uint8_t skull[] = {0x4c, 0x75, 0xc2, 0xbf, 0x63, 0x65, 0xc2, 0xbf, 0x6e, 0x65}; - BOOST_CHECK_EQUAL(is->readString(), UTF8_TO_STRING(skull)); + EXPECT_EQ(is->readString(), UTF8_TO_STRING(skull)); const uint8_t gclef[] = {0xe2, 0x98, 0xa0}; - BOOST_CHECK_EQUAL(is->readString(), UTF8_TO_STRING(gclef)); + EXPECT_EQ(is->readString(), UTF8_TO_STRING(gclef)); const uint8_t eighthnote[] = {0x4c, 0x75, 0xe2, 0x98, 0xa0, 0x63, 0x65, 0xe2, 0x98, 0xa0, 0x6e, 0x65}; - BOOST_CHECK_EQUAL(is->readString(), UTF8_TO_STRING(eighthnote)); - + EXPECT_EQ(is->readString(), UTF8_TO_STRING(eighthnote)); + String readString(is->readString()); #ifdef LPP_UNICODE_CHAR_SIZE_2 - BOOST_CHECK_EQUAL(readString[0], 55348); - BOOST_CHECK_EQUAL(readString[1], 56606); + EXPECT_EQ(readString[0], 55348); + EXPECT_EQ(readString[1], 56606); #else - BOOST_CHECK_EQUAL(readString[0], 119070); + EXPECT_EQ(readString[0], 119070); #endif - + readString = is->readString(); #ifdef LPP_UNICODE_CHAR_SIZE_2 - BOOST_CHECK_EQUAL(readString[0], 55348); - BOOST_CHECK_EQUAL(readString[1], 56606); - BOOST_CHECK_EQUAL(readString[2], 55348); - BOOST_CHECK_EQUAL(readString[3], 56672); + EXPECT_EQ(readString[0], 55348); + EXPECT_EQ(readString[1], 56606); + EXPECT_EQ(readString[2], 55348); + EXPECT_EQ(readString[3], 56672); #else - BOOST_CHECK_EQUAL(readString[0], 119070); - BOOST_CHECK_EQUAL(readString[1], 119136); + EXPECT_EQ(readString[0], 119070); + EXPECT_EQ(readString[1], 119136); #endif - + readString = is->readString(); #ifdef LPP_UNICODE_CHAR_SIZE_2 - BOOST_CHECK_EQUAL(readString[0], L'L'); - BOOST_CHECK_EQUAL(readString[1], L'u'); - BOOST_CHECK_EQUAL(readString[2], 55348); - BOOST_CHECK_EQUAL(readString[3], 56606); - BOOST_CHECK_EQUAL(readString[4], L'c'); - BOOST_CHECK_EQUAL(readString[5], L'e'); - BOOST_CHECK_EQUAL(readString[6], 55348); - BOOST_CHECK_EQUAL(readString[7], 56672); - BOOST_CHECK_EQUAL(readString[8], L'n'); - BOOST_CHECK_EQUAL(readString[9], L'e'); + EXPECT_EQ(readString[0], L'L'); + EXPECT_EQ(readString[1], L'u'); + EXPECT_EQ(readString[2], 55348); + EXPECT_EQ(readString[3], 56606); + EXPECT_EQ(readString[4], L'c'); + EXPECT_EQ(readString[5], L'e'); + EXPECT_EQ(readString[6], 55348); + EXPECT_EQ(readString[7], 56672); + EXPECT_EQ(readString[8], L'n'); + EXPECT_EQ(readString[9], L'e'); #else - BOOST_CHECK_EQUAL(readString[0], L'L'); - BOOST_CHECK_EQUAL(readString[1], L'u'); - BOOST_CHECK_EQUAL(readString[2], 119070); - BOOST_CHECK_EQUAL(readString[3], L'c'); - BOOST_CHECK_EQUAL(readString[4], L'e'); - BOOST_CHECK_EQUAL(readString[5], 119136); - BOOST_CHECK_EQUAL(readString[6], L'n'); - BOOST_CHECK_EQUAL(readString[7], L'e'); + EXPECT_EQ(readString[0], L'L'); + EXPECT_EQ(readString[1], L'u'); + EXPECT_EQ(readString[2], 119070); + EXPECT_EQ(readString[3], L'c'); + EXPECT_EQ(readString[4], L'e'); + EXPECT_EQ(readString[5], 119136); + EXPECT_EQ(readString[6], L'n'); + EXPECT_EQ(readString[7], L'e'); #endif - + readString = is->readString(); - BOOST_CHECK_EQUAL(readString[0], 0); - + EXPECT_EQ(readString[0], 0); + readString = is->readString(); - BOOST_CHECK_EQUAL(readString[0], L'L'); - BOOST_CHECK_EQUAL(readString[1], L'u'); - BOOST_CHECK_EQUAL(readString[2], 0); - BOOST_CHECK_EQUAL(readString[3], L'c'); - BOOST_CHECK_EQUAL(readString[4], L'e'); - BOOST_CHECK_EQUAL(readString[5], 0); - BOOST_CHECK_EQUAL(readString[6], L'n'); - BOOST_CHECK_EQUAL(readString[7], L'e'); + EXPECT_EQ(readString[0], L'L'); + EXPECT_EQ(readString[1], L'u'); + EXPECT_EQ(readString[2], 0); + EXPECT_EQ(readString[3], L'c'); + EXPECT_EQ(readString[4], L'e'); + EXPECT_EQ(readString[5], 0); + EXPECT_EQ(readString[6], L'n'); + EXPECT_EQ(readString[7], L'e'); } -BOOST_AUTO_TEST_CASE(testSkipChars) +TEST_F(IndexInputTest, testSkipChars) { ByteArray inputBytes(ByteArray::newInstance(100)); uint8_t input[17] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, 'L', 'u', 'c', 'e', 'n', 'e'}; std::memcpy(inputBytes.get(), input, 17); - + IndexInputPtr is = newLucene(inputBytes); - BOOST_CHECK_EQUAL(is->readVInt(), 128); - BOOST_CHECK_EQUAL(is->readVInt(), 16383); - BOOST_CHECK_EQUAL(is->readVInt(), 16384); - BOOST_CHECK_EQUAL(is->readVInt(), 16385); - BOOST_CHECK_EQUAL(is->readVInt(), 6); + EXPECT_EQ(is->readVInt(), 128); + EXPECT_EQ(is->readVInt(), 16383); + EXPECT_EQ(is->readVInt(), 16384); + EXPECT_EQ(is->readVInt(), 16385); + EXPECT_EQ(is->readVInt(), 6); is->skipChars(3); ByteArray remainingBytes(ByteArray::newInstance(4 * sizeof(wchar_t))); is->readChars((wchar_t*)remainingBytes.get(), 0, 3); - BOOST_CHECK_EQUAL(String((wchar_t*)remainingBytes.get(), 3), L"ene"); + EXPECT_EQ(String((wchar_t*)remainingBytes.get(), 3), L"ene"); } struct lessKey @@ -244,30 +244,28 @@ struct lessKey } }; -BOOST_AUTO_TEST_CASE(testReadStringMap) +TEST_F(IndexInputTest, testReadStringMap) { ByteArray inputBytes(ByteArray::newInstance(100)); - uint8_t input[34] = { 0, 0, 0, 3, + uint8_t input[34] = { 0, 0, 0, 3, 4, 'k', 'e', 'y', '1', 4, 'v', 'a', 'l', '1', 4, 'k', 'e', 'y', '2', 4, 'v', 'a', 'l', '2', 4, 'k', 'e', 'y', '3', 4, 'v', 'a', 'l', '3' }; std::memcpy(inputBytes.get(), input, 34); IndexInputPtr is = newLucene(inputBytes); - + MapStringString map = is->readStringStringMap(); - BOOST_CHECK_EQUAL(map.size(), 3); - + EXPECT_EQ(map.size(), 3); + Collection orderedMap(Collection::newInstance(map.begin(), map.end())); - + // order map by key std::sort(orderedMap.begin(), orderedMap.end(), lessKey()); - + int32_t count = 1; for (Collection::iterator mapEntry = orderedMap.begin(); mapEntry != orderedMap.end(); ++mapEntry, ++count) { - BOOST_CHECK_EQUAL(mapEntry->first, L"key" + StringUtils::toString(count)); - BOOST_CHECK_EQUAL(mapEntry->second, L"val" + StringUtils::toString(count)); + EXPECT_EQ(mapEntry->first, L"key" + StringUtils::toString(count)); + EXPECT_EQ(mapEntry->second, L"val" + StringUtils::toString(count)); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexReaderCloneNorms.cpp b/src/test/index/IndexReaderCloneNorms.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/index/IndexReaderCloneNormsTest.cpp b/src/test/index/IndexReaderCloneNormsTest.cpp index 69f2c099..8d390e69 100644 --- a/src/test/index/IndexReaderCloneNormsTest.cpp +++ b/src/test/index/IndexReaderCloneNormsTest.cpp @@ -36,10 +36,10 @@ class SimilarityOne : public DefaultSimilarity } }; -class IndexReaderCloneNormsTestFixture : public LuceneTestFixture +class IndexReaderCloneNormsTest : public LuceneTestFixture { public: - IndexReaderCloneNormsTestFixture() + IndexReaderCloneNormsTest() { similarityOne = newLucene(); anlzr = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -47,14 +47,14 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture lastNorm = 0.0; normDelta = 0.001; } - - virtual ~IndexReaderCloneNormsTestFixture() + + virtual ~IndexReaderCloneNormsTest() { } protected: static const int32_t NUM_FIELDS; - + SimilarityPtr similarityOne; AnalyzerPtr anlzr; int32_t numDocNorms; @@ -73,8 +73,8 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture iw->setUseCompoundFile(true); iw->close(); } - - void createIndex(DirectoryPtr dir, bool multiSegment) + + void createIndex(DirectoryPtr dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -95,12 +95,12 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture IndexReaderPtr r = IndexReader::open(dir, false); if (multiSegment) - BOOST_CHECK(r->getSequentialSubReaders().size() > 1); + EXPECT_TRUE(r->getSequentialSubReaders().size() > 1); else - BOOST_CHECK_EQUAL(r->getSequentialSubReaders().size(), 1); + EXPECT_EQ(r->getSequentialSubReaders().size(), 1); r->close(); } - + DocumentPtr createDocument(int32_t n, int32_t numFields) { StringStream sb; @@ -114,7 +114,7 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture doc->add(newLucene(L"field" + StringUtils::toString(i + 1), sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED)); return doc; } - + /// try cloning and reopening the norms void doTestNorms(DirectoryPtr dir) { @@ -134,18 +134,18 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture irc3->flush(); irc3->close(); } - + void modifyNormsForF1(DirectoryPtr dir) { IndexReaderPtr ir = IndexReader::open(dir, false); modifyNormsForF1(ir); } - + void modifyNormsForF1(IndexReaderPtr ir) { int32_t n = ir->maxDoc(); for (int32_t i = 0; i < n; i += 3) // modify for every third doc - { + { int32_t k = (i * 3) % modifiedNorms.size(); double origNorm = modifiedNorms[i]; double newNorm = modifiedNorms[k]; @@ -155,7 +155,7 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture ir->setNorm(k, L"f1", origNorm); } } - + void addDocs(DirectoryPtr dir, int32_t ndocs, bool compound) { IndexWriterPtr iw = newLucene(dir, anlzr, false, IndexWriter::MaxFieldLengthLIMITED); @@ -167,7 +167,7 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture iw->addDocument(newDoc()); iw->close(); } - + DocumentPtr newDoc() { DocumentPtr d = newLucene(); @@ -202,40 +202,37 @@ class IndexReaderCloneNormsTestFixture : public LuceneTestFixture lastNorm = (norm > 10 ? 0 : norm); return norm; } - + void verifyIndex(DirectoryPtr dir) { IndexReaderPtr ir = IndexReader::open(dir, false); verifyIndex(ir); ir->close(); } - + void verifyIndex(IndexReaderPtr ir) { for (int32_t i = 0; i < NUM_FIELDS; ++i) { String field = L"f" + StringUtils::toString(i); ByteArray b = ir->norms(field); - BOOST_CHECK_EQUAL(numDocNorms, b.size()); + EXPECT_EQ(numDocNorms, b.size()); Collection storedNorms = (i == 1 ? modifiedNorms : norms); for (int32_t j = 0; j < b.size(); ++j) { double norm = Similarity::decodeNorm(b[j]); double norm1 = storedNorms[j]; - BOOST_CHECK_EQUAL(norm, norm1); // 0.000001 ?? + EXPECT_EQ(norm, norm1); // 0.000001 ?? } } } }; -const int32_t IndexReaderCloneNormsTestFixture::NUM_FIELDS = 10; - -/// Tests cloning IndexReader norms -BOOST_FIXTURE_TEST_SUITE(IndexReaderCloneNormsTest, IndexReaderCloneNormsTestFixture) +const int32_t IndexReaderCloneNormsTest::NUM_FIELDS = 10; -/// Test that norms values are preserved as the index is maintained. Including separate norms. +/// Test that norms values are preserved as the index is maintained. Including separate norms. /// Including merging indexes with separate norms. Including optimize. -BOOST_AUTO_TEST_CASE(testNorms) +TEST_F(IndexReaderCloneNormsTest, testNorms) { // test with a single index: index1 String indexDir1(FileUtils::joinPath(getTempDir(), L"lucenetestindex1")); @@ -259,14 +256,14 @@ BOOST_AUTO_TEST_CASE(testNorms) String indexDir2(FileUtils::joinPath(getTempDir(), L"lucenetestindex2")); DirectoryPtr dir2 = FSDirectory::open(indexDir2); - + createIndex(dir2); doTestNorms(dir2); // add index1 and index2 to a third index: index3 String indexDir3(FileUtils::joinPath(getTempDir(), L"lucenetestindex3")); DirectoryPtr dir3 = FSDirectory::open(indexDir3); - + createIndex(dir3); IndexWriterPtr iw = newLucene(dir3, anlzr, false, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); @@ -298,7 +295,7 @@ BOOST_AUTO_TEST_CASE(testNorms) dir3->close(); } -BOOST_AUTO_TEST_CASE(testNormsClose) +TEST_F(IndexReaderCloneNormsTest, testNormsClose) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -307,15 +304,15 @@ BOOST_AUTO_TEST_CASE(testNormsClose) NormPtr r1norm = reader1->_norms.get(L"field1"); SegmentReaderRefPtr r1BytesRef = r1norm->bytesRef(); SegmentReaderPtr reader2 = boost::dynamic_pointer_cast(reader1->clone()); - BOOST_CHECK_EQUAL(2, r1norm->bytesRef()->refCount()); + EXPECT_EQ(2, r1norm->bytesRef()->refCount()); reader1->close(); - BOOST_CHECK_EQUAL(1, r1BytesRef->refCount()); + EXPECT_EQ(1, r1BytesRef->refCount()); reader2->norms(L"field1"); reader2->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testNormsRefCounting) +TEST_F(IndexReaderCloneNormsTest, testNormsRefCounting) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -326,33 +323,40 @@ BOOST_AUTO_TEST_CASE(testNormsRefCounting) SegmentReaderPtr segmentReader2C = SegmentReader::getOnlySegmentReader(reader2C); segmentReader2C->norms(L"field1"); // load the norms for the field NormPtr reader2CNorm = segmentReader2C->_norms.get(L"field1"); - BOOST_CHECK_EQUAL(2, reader2CNorm->bytesRef()->refCount()); + EXPECT_EQ(2, reader2CNorm->bytesRef()->refCount()); IndexReaderPtr reader3C = boost::dynamic_pointer_cast(reader2C->clone()); SegmentReaderPtr segmentReader3C = SegmentReader::getOnlySegmentReader(reader3C); NormPtr reader3CCNorm = segmentReader3C->_norms.get(L"field1"); - BOOST_CHECK_EQUAL(3, reader3CCNorm->bytesRef()->refCount()); + EXPECT_EQ(3, reader3CCNorm->bytesRef()->refCount()); // edit a norm and the refcount should be 1 IndexReaderPtr reader4C = boost::dynamic_pointer_cast(reader3C->clone()); SegmentReaderPtr segmentReader4C = SegmentReader::getOnlySegmentReader(reader4C); - BOOST_CHECK_EQUAL(4, reader3CCNorm->bytesRef()->refCount()); + EXPECT_EQ(4, reader3CCNorm->bytesRef()->refCount()); reader4C->setNorm(5, L"field1", 0.33); - + // generate a cannot update exception in reader1 - BOOST_CHECK_EXCEPTION(reader3C->setNorm(1, L"field1", 0.99), LockObtainFailedException, check_exception(LuceneException::LockObtainFailed)); + try + { + reader3C->setNorm(1, L"field1", 0.99); + } + catch (LockObtainFailedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } - // norm values should be different - BOOST_CHECK_NE(Similarity::decodeNorm(segmentReader3C->norms(L"field1")[5]), Similarity::decodeNorm(segmentReader4C->norms(L"field1")[5])); + // norm values should be different + EXPECT_NE(Similarity::decodeNorm(segmentReader3C->norms(L"field1")[5]), Similarity::decodeNorm(segmentReader4C->norms(L"field1")[5])); NormPtr reader4CCNorm = segmentReader4C->_norms.get(L"field1"); - BOOST_CHECK_EQUAL(3, reader3CCNorm->bytesRef()->refCount()); - BOOST_CHECK_EQUAL(1, reader4CCNorm->bytesRef()->refCount()); + EXPECT_EQ(3, reader3CCNorm->bytesRef()->refCount()); + EXPECT_EQ(1, reader4CCNorm->bytesRef()->refCount()); IndexReaderPtr reader5C = boost::dynamic_pointer_cast(reader4C->clone()); SegmentReaderPtr segmentReader5C = SegmentReader::getOnlySegmentReader(reader5C); NormPtr reader5CCNorm = segmentReader5C->_norms.get(L"field1"); reader5C->setNorm(5, L"field1", 0.7); - BOOST_CHECK_EQUAL(1, reader5CCNorm->bytesRef()->refCount()); + EXPECT_EQ(1, reader5CCNorm->bytesRef()->refCount()); reader5C->close(); reader4C->close(); @@ -361,5 +365,3 @@ BOOST_AUTO_TEST_CASE(testNormsRefCounting) reader1->close(); dir1->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexReaderCloneTest.cpp b/src/test/index/IndexReaderCloneTest.cpp index 112d9f72..9de1d880 100644 --- a/src/test/index/IndexReaderCloneTest.cpp +++ b/src/test/index/IndexReaderCloneTest.cpp @@ -27,9 +27,9 @@ using namespace Lucene; -/// Tests cloning multiple types of readers, modifying the deletedDocs and norms and verifies copy on write semantics +/// Tests cloning multiple types of readers, modifying the deletedDocs and norms and verifies copy on write semantics /// of the deletedDocs and norms is implemented properly -BOOST_FIXTURE_TEST_SUITE(IndexReaderCloneTest, LuceneTestFixture) +typedef LuceneTestFixture IndexReaderCloneTest; static DocumentPtr createDocument(int32_t n, int32_t numFields) { @@ -45,7 +45,7 @@ static DocumentPtr createDocument(int32_t n, int32_t numFields) return doc; } -static void createIndex(DirectoryPtr dir, bool multiSegment) +static void createIndex(DirectoryPtr dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -66,9 +66,9 @@ static void createIndex(DirectoryPtr dir, bool multiSegment) IndexReaderPtr r = IndexReader::open(dir, false); if (multiSegment) - BOOST_CHECK(r->getSequentialSubReaders().size() > 1); + EXPECT_TRUE(r->getSequentialSubReaders().size() > 1); else - BOOST_CHECK_EQUAL(r->getSequentialSubReaders().size(), 1); + EXPECT_EQ(r->getSequentialSubReaders().size(), 1); r->close(); } @@ -92,11 +92,11 @@ static bool deleteWorked(int32_t doc, IndexReaderPtr r) return !exception; } -/// 1. Get a norm from the original reader -/// 2. Clone the original reader -/// 3. Delete a document and set the norm of the cloned reader -/// 4. Verify the norms are not the same on each reader -/// 5. Verify the doc deleted is only in the cloned reader +/// 1. Get a norm from the original reader +/// 2. Clone the original reader +/// 3. Delete a document and set the norm of the cloned reader +/// 4. Verify the norms are not the same on each reader +/// 5. Verify the doc deleted is only in the cloned reader /// 6. Try to delete a document in the original reader, an exception should be thrown static void performDefaultTests(IndexReaderPtr r1) { @@ -105,14 +105,21 @@ static void performDefaultTests(IndexReaderPtr r1) IndexReaderPtr pr1Clone = boost::dynamic_pointer_cast(r1->clone()); pr1Clone->deleteDocument(10); pr1Clone->setNorm(4, L"field1", 0.5); - BOOST_CHECK(Similarity::decodeNorm(r1->norms(L"field1")[4]) == norm1); - BOOST_CHECK_NE(Similarity::decodeNorm(pr1Clone->norms(L"field1")[4]), norm1); + EXPECT_TRUE(Similarity::decodeNorm(r1->norms(L"field1")[4]) == norm1); + EXPECT_NE(Similarity::decodeNorm(pr1Clone->norms(L"field1")[4]), norm1); + + EXPECT_TRUE(!r1->isDeleted(10)); + EXPECT_TRUE(pr1Clone->isDeleted(10)); - BOOST_CHECK(!r1->isDeleted(10)); - BOOST_CHECK(pr1Clone->isDeleted(10)); - // try to update the original reader, which should throw an exception - BOOST_CHECK_EXCEPTION(r1->deleteDocument(11), LuceneException, check_exception(LuceneException::Null)); + try + { + r1->deleteDocument(11); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::Null)(e)); + } pr1Clone->close(); } @@ -174,145 +181,145 @@ static void modifyIndex(int32_t i, DirectoryPtr dir) static void checkDelDocsRefCountEquals(int32_t refCount, SegmentReaderPtr reader) { - BOOST_CHECK_EQUAL(refCount, reader->deletedDocsRef->refCount()); + EXPECT_EQ(refCount, reader->deletedDocsRef->refCount()); } static void checkDocDeleted(SegmentReaderPtr reader, SegmentReaderPtr reader2, int32_t doc) { - BOOST_CHECK_EQUAL(reader->isDeleted(doc), reader2->isDeleted(doc)); + EXPECT_EQ(reader->isDeleted(doc), reader2->isDeleted(doc)); } -BOOST_AUTO_TEST_CASE(testCloneReadOnlySegmentReader) +TEST_F(IndexReaderCloneTest, testCloneReadOnlySegmentReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr reader = IndexReader::open(dir1, false); IndexReaderPtr readOnlyReader = boost::dynamic_pointer_cast(reader->clone(true)); - BOOST_CHECK(isReadOnly(readOnlyReader)); - BOOST_CHECK(!deleteWorked(1, readOnlyReader)); + EXPECT_TRUE(isReadOnly(readOnlyReader)); + EXPECT_TRUE(!deleteWorked(1, readOnlyReader)); reader->close(); readOnlyReader->close(); dir1->close(); } /// Open non-readOnly reader1, clone to non-readOnly reader2, make sure we can change reader2 -BOOST_AUTO_TEST_CASE(testCloneNoChangesStillReadOnly) +TEST_F(IndexReaderCloneTest, testCloneNoChangesStillReadOnly) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr r1 = IndexReader::open(dir1, false); IndexReaderPtr r2 = boost::dynamic_pointer_cast(r1->clone(false)); - BOOST_CHECK(deleteWorked(1, r2)); + EXPECT_TRUE(deleteWorked(1, r2)); r1->close(); r2->close(); dir1->close(); } /// Open non-readOnly reader1, clone to non-readOnly reader2, make sure we can change reader1 -BOOST_AUTO_TEST_CASE(testCloneWriteToOrig) +TEST_F(IndexReaderCloneTest, testCloneWriteToOrig) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr r1 = IndexReader::open(dir1, false); IndexReaderPtr r2 = boost::dynamic_pointer_cast(r1->clone(false)); - BOOST_CHECK(deleteWorked(1, r1)); + EXPECT_TRUE(deleteWorked(1, r1)); r1->close(); r2->close(); dir1->close(); } /// Open non-readOnly reader1, clone to non-readOnly reader2, make sure we can change reader2 -BOOST_AUTO_TEST_CASE(testCloneWriteToClone) +TEST_F(IndexReaderCloneTest, testCloneWriteToClone) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr r1 = IndexReader::open(dir1, false); IndexReaderPtr r2 = boost::dynamic_pointer_cast(r1->clone(false)); - BOOST_CHECK(deleteWorked(1, r2)); + EXPECT_TRUE(deleteWorked(1, r2)); // should fail because reader1 holds the write lock - BOOST_CHECK(!deleteWorked(1, r1)); + EXPECT_TRUE(!deleteWorked(1, r1)); r2->close(); // should fail because we are now stale (reader1 committed changes) - BOOST_CHECK(!deleteWorked(1, r1)); + EXPECT_TRUE(!deleteWorked(1, r1)); r1->close(); dir1->close(); } /// Create single-segment index, open non-readOnly SegmentReader, add docs, reopen to multireader, then do delete -BOOST_AUTO_TEST_CASE(testReopenSegmentReaderToMultiReader) +TEST_F(IndexReaderCloneTest, testReopenSegmentReaderToMultiReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr reader1 = IndexReader::open(dir1, false); - + modifyIndex(5, dir1); IndexReaderPtr reader2 = reader1->reopen(); - BOOST_CHECK_NE(reader1, reader2); + EXPECT_NE(reader1, reader2); - BOOST_CHECK(deleteWorked(1, reader2)); + EXPECT_TRUE(deleteWorked(1, reader2)); reader1->close(); reader2->close(); dir1->close(); } /// Open non-readOnly reader1, clone to readOnly reader2 -BOOST_AUTO_TEST_CASE(testCloneWriteableToReadOnly) +TEST_F(IndexReaderCloneTest, testCloneWriteableToReadOnly) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader = IndexReader::open(dir1, false); IndexReaderPtr readOnlyReader = boost::dynamic_pointer_cast(reader->clone(true)); - - BOOST_CHECK(isReadOnly(readOnlyReader)); - BOOST_CHECK(!deleteWorked(1, readOnlyReader)); - BOOST_CHECK(!readOnlyReader->hasChanges()); - + + EXPECT_TRUE(isReadOnly(readOnlyReader)); + EXPECT_TRUE(!deleteWorked(1, readOnlyReader)); + EXPECT_TRUE(!readOnlyReader->hasChanges()); + reader->close(); readOnlyReader->close(); dir1->close(); } /// Open non-readOnly reader1, reopen to readOnly reader2 -BOOST_AUTO_TEST_CASE(testReopenWriteableToReadOnly) +TEST_F(IndexReaderCloneTest, testReopenWriteableToReadOnly) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader = IndexReader::open(dir1, false); int32_t docCount = reader->numDocs(); - BOOST_CHECK(deleteWorked(1, reader)); - BOOST_CHECK_EQUAL(docCount - 1, reader->numDocs()); - + EXPECT_TRUE(deleteWorked(1, reader)); + EXPECT_EQ(docCount - 1, reader->numDocs()); + IndexReaderPtr readOnlyReader = reader->reopen(true); - BOOST_CHECK(isReadOnly(readOnlyReader)); - BOOST_CHECK(!deleteWorked(1, readOnlyReader)); - BOOST_CHECK_EQUAL(docCount - 1, readOnlyReader->numDocs()); + EXPECT_TRUE(isReadOnly(readOnlyReader)); + EXPECT_TRUE(!deleteWorked(1, readOnlyReader)); + EXPECT_EQ(docCount - 1, readOnlyReader->numDocs()); reader->close(); readOnlyReader->close(); dir1->close(); } /// Open readOnly reader1, clone to non-readOnly reader2 -BOOST_AUTO_TEST_CASE(testCloneReadOnlyToWriteable) +TEST_F(IndexReaderCloneTest, testCloneReadOnlyToWriteable) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader1 = IndexReader::open(dir1, true); IndexReaderPtr reader2 = boost::dynamic_pointer_cast(reader1->clone(false)); - - BOOST_CHECK(!isReadOnly(reader2)); - BOOST_CHECK(!deleteWorked(1, reader1)); + + EXPECT_TRUE(!isReadOnly(reader2)); + EXPECT_TRUE(!deleteWorked(1, reader1)); // this readonly reader shouldn't yet have a write lock - BOOST_CHECK(!reader2->hasChanges()); - BOOST_CHECK(deleteWorked(1, reader2)); + EXPECT_TRUE(!reader2->hasChanges()); + EXPECT_TRUE(deleteWorked(1, reader2)); reader1->close(); reader2->close(); dir1->close(); } /// Open non-readOnly reader1 on multi-segment index, then optimize the index, then clone to readOnly reader2 -BOOST_AUTO_TEST_CASE(testReadOnlyCloneAfterOptimize) +TEST_F(IndexReaderCloneTest, testReadOnlyCloneAfterOptimize) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); @@ -321,31 +328,31 @@ BOOST_AUTO_TEST_CASE(testReadOnlyCloneAfterOptimize) w->optimize(); w->close(); IndexReaderPtr reader2 = boost::dynamic_pointer_cast(reader1->clone(true)); - BOOST_CHECK(isReadOnly(reader2)); + EXPECT_TRUE(isReadOnly(reader2)); reader1->close(); reader2->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testCloneReadOnlyDirectoryReader) +TEST_F(IndexReaderCloneTest, testCloneReadOnlyDirectoryReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader = IndexReader::open(dir1, false); IndexReaderPtr readOnlyReader = boost::dynamic_pointer_cast(reader->clone(true)); - BOOST_CHECK(isReadOnly(readOnlyReader)); + EXPECT_TRUE(isReadOnly(readOnlyReader)); reader->close(); readOnlyReader->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testParallelReader) +TEST_F(IndexReaderCloneTest, testParallelReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); createIndex(dir2, true); - + IndexReaderPtr r1 = IndexReader::open(dir1, false); IndexReaderPtr r2 = IndexReader::open(dir2, false); @@ -359,7 +366,7 @@ BOOST_AUTO_TEST_CASE(testParallelReader) dir2->close(); } -BOOST_AUTO_TEST_CASE(testMixedReaders) +TEST_F(IndexReaderCloneTest, testMixedReaders) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); @@ -368,7 +375,7 @@ BOOST_AUTO_TEST_CASE(testMixedReaders) IndexReaderPtr r1 = IndexReader::open(dir1, false); IndexReaderPtr r2 = IndexReader::open(dir2, false); - + Collection multiReaders = newCollection(r1, r2); MultiReaderPtr multiReader = newLucene(multiReaders); performDefaultTests(multiReader); @@ -377,7 +384,7 @@ BOOST_AUTO_TEST_CASE(testMixedReaders) dir2->close(); } -BOOST_AUTO_TEST_CASE(testSegmentReaderUndeleteall) +TEST_F(IndexReaderCloneTest, testSegmentReaderUndeleteall) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -385,13 +392,13 @@ BOOST_AUTO_TEST_CASE(testSegmentReaderUndeleteall) origSegmentReader->deleteDocument(10); checkDelDocsRefCountEquals(1, origSegmentReader); origSegmentReader->undeleteAll(); - BOOST_CHECK(!origSegmentReader->deletedDocsRef); + EXPECT_TRUE(!origSegmentReader->deletedDocsRef); origSegmentReader->close(); // need to test norms? dir1->close(); } -BOOST_AUTO_TEST_CASE(testSegmentReaderCloseReferencing) +TEST_F(IndexReaderCloneTest, testSegmentReaderCloseReferencing) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -405,19 +412,19 @@ BOOST_AUTO_TEST_CASE(testSegmentReaderCloseReferencing) checkDelDocsRefCountEquals(1, origSegmentReader); // check the norm refs NormPtr norm = clonedSegmentReader->_norms.get(L"field1"); - BOOST_CHECK_EQUAL(1, norm->bytesRef()->refCount()); + EXPECT_EQ(1, norm->bytesRef()->refCount()); clonedSegmentReader->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testSegmentReaderDelDocsReferenceCounting) +TEST_F(IndexReaderCloneTest, testSegmentReaderDelDocsReferenceCounting) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr origReader = IndexReader::open(dir1, false); SegmentReaderPtr origSegmentReader = SegmentReader::getOnlySegmentReader(origReader); // deletedDocsRef should be null because nothing has updated yet - BOOST_CHECK(!origSegmentReader->deletedDocsRef); + EXPECT_TRUE(!origSegmentReader->deletedDocsRef); // we deleted a document, so there is now a deletedDocs bitvector and a reference to it origReader->deleteDocument(1); @@ -433,13 +440,20 @@ BOOST_AUTO_TEST_CASE(testSegmentReaderDelDocsReferenceCounting) checkDelDocsRefCountEquals(1, clonedSegmentReader); // make sure the deletedocs objects are different (copy on write) - BOOST_CHECK_NE(origSegmentReader->deletedDocs, clonedSegmentReader->deletedDocs); + EXPECT_NE(origSegmentReader->deletedDocs, clonedSegmentReader->deletedDocs); checkDocDeleted(origSegmentReader, clonedSegmentReader, 1); - BOOST_CHECK(!origSegmentReader->isDeleted(2)); // doc 2 should not be deleted in original segmentreader - BOOST_CHECK(clonedSegmentReader->isDeleted(2)); // doc 2 should be deleted in cloned segmentreader + EXPECT_TRUE(!origSegmentReader->isDeleted(2)); // doc 2 should not be deleted in original segmentreader + EXPECT_TRUE(clonedSegmentReader->isDeleted(2)); // doc 2 should be deleted in cloned segmentreader - BOOST_CHECK_EXCEPTION(origReader->deleteDocument(4), LockObtainFailedException, check_exception(LuceneException::LockObtainFailed)); + try + { + origReader->deleteDocument(4); + } + catch (LockObtainFailedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } origReader->close(); // try closing the original segment reader to see if it affects the clonedSegmentReader @@ -459,7 +473,7 @@ BOOST_AUTO_TEST_CASE(testSegmentReaderDelDocsReferenceCounting) dir1->close(); } -BOOST_AUTO_TEST_CASE(testCloneWithDeletes) +TEST_F(IndexReaderCloneTest, testCloneWithDeletes) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -471,19 +485,19 @@ BOOST_AUTO_TEST_CASE(testCloneWithDeletes) clonedReader->close(); IndexReaderPtr r = IndexReader::open(dir1, false); - BOOST_CHECK(r->isDeleted(1)); + EXPECT_TRUE(r->isDeleted(1)); r->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testCloneWithSetNorm) +TEST_F(IndexReaderCloneTest, testCloneWithSetNorm) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr orig = IndexReader::open(dir1, false); orig->setNorm(1, L"field1", 17.0); uint8_t encoded = Similarity::encodeNorm(17.0); - BOOST_CHECK_EQUAL(encoded, orig->norms(L"field1")[1]); + EXPECT_EQ(encoded, orig->norms(L"field1")[1]); // the cloned segmentreader should have 2 references, 1 to itself, and 1 to the original segmentreader IndexReaderPtr clonedReader = boost::dynamic_pointer_cast(orig->clone()); @@ -491,20 +505,20 @@ BOOST_AUTO_TEST_CASE(testCloneWithSetNorm) clonedReader->close(); IndexReaderPtr r = IndexReader::open(dir1, false); - BOOST_CHECK_EQUAL(encoded, r->norms(L"field1")[1]); + EXPECT_EQ(encoded, r->norms(L"field1")[1]); r->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testCloneSubreaders) +TEST_F(IndexReaderCloneTest, testCloneSubreaders) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); - + IndexReaderPtr reader = IndexReader::open(dir1, false); reader->deleteDocument(1); // acquire write lock Collection subs = reader->getSequentialSubReaders(); - BOOST_CHECK(subs.size() > 1); + EXPECT_TRUE(subs.size() > 1); Collection clones = Collection::newInstance(subs.size()); for (int32_t x = 0; x < subs.size(); ++x) @@ -515,7 +529,7 @@ BOOST_AUTO_TEST_CASE(testCloneSubreaders) dir1->close(); } -BOOST_AUTO_TEST_CASE(testIncDecRef) +TEST_F(IndexReaderCloneTest, testIncDecRef) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -533,7 +547,7 @@ BOOST_AUTO_TEST_CASE(testIncDecRef) dir1->close(); } -BOOST_AUTO_TEST_CASE(testCloseStoredFields) +TEST_F(IndexReaderCloneTest, testCloseStoredFields) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -548,5 +562,3 @@ BOOST_AUTO_TEST_CASE(testCloseStoredFields) r2->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexReaderReopenTest.cpp b/src/test/index/IndexReaderReopenTest.cpp index ac3b9bbb..bf5b0d3f 100644 --- a/src/test/index/IndexReaderReopenTest.cpp +++ b/src/test/index/IndexReaderReopenTest.cpp @@ -39,7 +39,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexReaderReopenTest, LuceneTestFixture) +typedef LuceneTestFixture IndexReaderReopenTest; namespace TestReopen { @@ -47,14 +47,14 @@ namespace TestReopen DECLARE_SHARED_PTR(ReaderCouple) DECLARE_SHARED_PTR(ReaderThread) DECLARE_SHARED_PTR(ReaderThreadTask) - + class TestableReopen { public: virtual ~TestableReopen() { } - + public: virtual IndexReaderPtr openReader() = 0; virtual void modifyIndex(int32_t i) = 0; @@ -68,7 +68,7 @@ namespace TestReopen newReader = r1; refreshedReader = r2; } - + virtual ~ReaderCouple() { } @@ -85,11 +85,11 @@ namespace TestReopen { stopped = false; } - + virtual ~ReaderThreadTask() { } - + LUCENE_CLASS(ReaderThreadTask); protected: @@ -100,7 +100,7 @@ namespace TestReopen { stopped = true; } - + virtual void run() = 0; }; @@ -111,22 +111,22 @@ namespace TestReopen { this->task = task; } - + virtual ~ReaderThread() { } - + LUCENE_CLASS(ReaderThread); - + protected: ReaderThreadTaskPtr task; - + public: void stopThread() { task->stop(); } - + virtual void run() { try @@ -135,7 +135,7 @@ namespace TestReopen } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; @@ -168,7 +168,7 @@ static void createIndex(DirectoryPtr dir, bool multiSegment) if (multiSegment && (i % 10) == 0) w->commit(); } - + if (!multiSegment) w->optimize(); @@ -176,9 +176,9 @@ static void createIndex(DirectoryPtr dir, bool multiSegment) IndexReaderPtr r = IndexReader::open(dir, false); if (multiSegment) - BOOST_CHECK(r->getSequentialSubReaders().size() > 1); + EXPECT_TRUE(r->getSequentialSubReaders().size() > 1); else - BOOST_CHECK_EQUAL(r->getSequentialSubReaders().size(), 1); + EXPECT_EQ(r->getSequentialSubReaders().size(), 1); r->close(); } @@ -240,10 +240,10 @@ static void _modifyIndex(int32_t i, DirectoryPtr dir) static void checkIndexEquals(IndexReaderPtr index1, IndexReaderPtr index2) { - BOOST_CHECK_EQUAL(index1->numDocs(), index2->numDocs()); - BOOST_CHECK_EQUAL(index1->maxDoc(), index2->maxDoc()); - BOOST_CHECK_EQUAL(index1->hasDeletions(), index2->hasDeletions()); - BOOST_CHECK_EQUAL(index1->isOptimized(), index2->isOptimized()); + EXPECT_EQ(index1->numDocs(), index2->numDocs()); + EXPECT_EQ(index1->maxDoc(), index2->maxDoc()); + EXPECT_EQ(index1->hasDeletions(), index2->hasDeletions()); + EXPECT_EQ(index1->isOptimized(), index2->isOptimized()); // check field names HashSet _fields1 = index1->getFieldNames(IndexReader::FIELD_OPTION_ALL); @@ -252,10 +252,10 @@ static void checkIndexEquals(IndexReaderPtr index1, IndexReaderPtr index2) HashSet _fields2 = index1->getFieldNames(IndexReader::FIELD_OPTION_ALL); Collection fields2 = Collection::newInstance(_fields2.begin(), _fields2.end()); std::sort(fields2.begin(), fields2.end()); - BOOST_CHECK_EQUAL(fields1.size(), fields2.size()); - + EXPECT_EQ(fields1.size(), fields2.size()); + for (int32_t i = 0; i < fields1.size(); ++i) - BOOST_CHECK_EQUAL(fields1[i], fields2[i]); + EXPECT_EQ(fields1[i], fields2[i]); // check norms for (int32_t i = 0; i < fields1.size(); ++i) @@ -265,16 +265,16 @@ static void checkIndexEquals(IndexReaderPtr index1, IndexReaderPtr index2) ByteArray norms2 = index2->norms(curField); if (norms1 && norms2) { - BOOST_CHECK(norms1.equals(norms2)); + EXPECT_TRUE(norms1.equals(norms2)); } else - BOOST_CHECK(norms1 == norms2); + EXPECT_TRUE(norms1 == norms2); } - + // check deletions for (int32_t i = 0; i < index1->maxDoc(); ++i) - BOOST_CHECK_EQUAL(index1->isDeleted(i), index2->isDeleted(i)); - + EXPECT_EQ(index1->isDeleted(i), index2->isDeleted(i)); + // check stored fields for (int32_t i = 0; i < index1->maxDoc(); ++i) { @@ -284,45 +284,45 @@ static void checkIndexEquals(IndexReaderPtr index1, IndexReaderPtr index2) DocumentPtr doc2 = index2->document(i); Collection storedFields1 = doc1->getFields(); Collection storedFields2 = doc2->getFields(); - BOOST_CHECK_EQUAL(storedFields1.size(), storedFields2.size()); + EXPECT_EQ(storedFields1.size(), storedFields2.size()); for (int32_t j = 0; j < storedFields1.size(); ++j) { - BOOST_CHECK_EQUAL(storedFields1[j]->name(), storedFields2[j]->name()); - BOOST_CHECK_EQUAL(storedFields1[j]->stringValue(), storedFields2[j]->stringValue()); + EXPECT_EQ(storedFields1[j]->name(), storedFields2[j]->name()); + EXPECT_EQ(storedFields1[j]->stringValue(), storedFields2[j]->stringValue()); } - } + } } - + // check dictionary and posting lists TermEnumPtr enum1 = index1->terms(); TermEnumPtr enum2 = index2->terms(); TermPositionsPtr tp1 = index1->termPositions(); TermPositionsPtr tp2 = index2->termPositions(); - + while (enum1->next()) { - BOOST_CHECK(enum2->next()); - BOOST_CHECK(enum1->term()->equals(enum2->term())); + EXPECT_TRUE(enum2->next()); + EXPECT_TRUE(enum1->term()->equals(enum2->term())); tp1->seek(enum1->term()); tp2->seek(enum1->term()); while (tp1->next()) { - BOOST_CHECK(tp2->next()); - BOOST_CHECK_EQUAL(tp1->doc(), tp2->doc()); - BOOST_CHECK_EQUAL(tp1->freq(), tp2->freq()); + EXPECT_TRUE(tp2->next()); + EXPECT_EQ(tp1->doc(), tp2->doc()); + EXPECT_EQ(tp1->freq(), tp2->freq()); for (int32_t i = 0; i < tp1->freq(); ++i) - BOOST_CHECK_EQUAL(tp1->nextPosition(), tp2->nextPosition()); + EXPECT_EQ(tp1->nextPosition(), tp2->nextPosition()); } } } static void checkReaderClosed(IndexReaderPtr reader, bool checkSubReaders, bool checkNormsClosed) { - BOOST_CHECK_EQUAL(0, reader->getRefCount()); - + EXPECT_EQ(0, reader->getRefCount()); + if (checkNormsClosed && MiscUtils::typeOf(reader)) - BOOST_CHECK(boost::dynamic_pointer_cast(reader)->normsClosed()); - + EXPECT_TRUE(boost::dynamic_pointer_cast(reader)->normsClosed()); + if (checkSubReaders) { if (MiscUtils::typeOf(reader)) @@ -331,14 +331,14 @@ static void checkReaderClosed(IndexReaderPtr reader, bool checkSubReaders, bool for (int32_t i = 0; i < subReaders.size(); ++i) checkReaderClosed(subReaders[i], checkSubReaders, checkNormsClosed); } - + if (MiscUtils::typeOf(reader)) { Collection subReaders = reader->getSequentialSubReaders(); for (int32_t i = 0; i < subReaders.size(); ++i) checkReaderClosed(subReaders[i], checkSubReaders, checkNormsClosed); } - + if (MiscUtils::typeOf(reader)) { Collection subReaders = boost::dynamic_pointer_cast(reader)->getSubReaders(); @@ -358,7 +358,7 @@ static TestReopen::ReaderCouplePtr refreshReader(IndexReaderPtr reader, TestReop test->modifyIndex(modify); r = test->openReader(); } - + IndexReaderPtr refreshed; LuceneException finally; try @@ -375,18 +375,18 @@ static TestReopen::ReaderCouplePtr refreshReader(IndexReaderPtr reader, TestReop r->close(); } finally.throwException(); - + if (hasChanges) { if (refreshed == reader) - BOOST_FAIL("No new IndexReader instance created during refresh."); + boost::throw_exception(IllegalArgumentException(L"No new IndexReader instance created during refresh.")); } else { if (refreshed != reader) - BOOST_FAIL("New IndexReader instance created during refresh even though index had no changes."); + boost::throw_exception(IllegalArgumentException(L"New IndexReader instance created during refresh even though index had no changes.")); } - + return newInstance(r, refreshed); } @@ -404,7 +404,7 @@ static void performDefaultTests(TestReopen::TestableReopenPtr test) // verify that reopen() does not return a new reader instance in case the index has no changes TestReopen::ReaderCouplePtr couple = refreshReader(index2, false); - BOOST_CHECK_EQUAL(couple->refreshedReader, index2); + EXPECT_EQ(couple->refreshedReader, index2); couple = refreshReader(index2, test, 0, true); index1->close(); @@ -447,8 +447,15 @@ static void performTestsWithExceptionInReopen(TestReopen::TestableReopenPtr test checkIndexEquals(index1, index2); - BOOST_CHECK_EXCEPTION(refreshReader(index1, test, 0, true), LuceneException, check_exception(LuceneException::Null)); - + try + { + refreshReader(index1, test, 0, true); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::Null)(e)); + } + // index2 should still be usable and unaffected by the failed reopen() call checkIndexEquals(index1, index2); @@ -458,7 +465,7 @@ static void performTestsWithExceptionInReopen(TestReopen::TestableReopenPtr test static void checkRefCountEquals(int32_t refCount, IndexReaderPtr reader) { - BOOST_CHECK_EQUAL(refCount, reader->getRefCount()); + EXPECT_EQ(refCount, reader->getRefCount()); } namespace TestReopen @@ -470,20 +477,20 @@ namespace TestReopen { this->dir = dir; } - + virtual ~BasicReopen() { } - + protected: DirectoryPtr dir; - + public: virtual IndexReaderPtr openReader() { return IndexReader::open(dir, false); } - + virtual void modifyIndex(int32_t i) { _modifyIndex(i, dir); @@ -491,13 +498,13 @@ namespace TestReopen }; } -BOOST_AUTO_TEST_CASE(testReopen) +TEST_F(IndexReaderReopenTest, testReopen) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); performDefaultTests(newInstance(dir1)); dir1->close(); - + DirectoryPtr dir2 = newLucene(); createIndex(dir2, true); performDefaultTests(newInstance(dir2)); @@ -514,15 +521,15 @@ namespace TestParallelReaderReopen this->dir1 = dir1; this->dir2 = dir2; } - + virtual ~FirstReopen() { } - + protected: DirectoryPtr dir1; DirectoryPtr dir2; - + public: virtual IndexReaderPtr openReader() { @@ -531,14 +538,14 @@ namespace TestParallelReaderReopen pr->add(IndexReader::open(dir2, false)); return pr; } - + virtual void modifyIndex(int32_t i) { _modifyIndex(i, dir1); _modifyIndex(i, dir2); } }; - + class SecondReopen : public TestReopen::TestableReopen { public: @@ -547,15 +554,15 @@ namespace TestParallelReaderReopen this->dir3 = dir3; this->dir4 = dir4; } - + virtual ~SecondReopen() { } - + protected: DirectoryPtr dir3; DirectoryPtr dir4; - + public: virtual IndexReaderPtr openReader() { @@ -566,7 +573,7 @@ namespace TestParallelReaderReopen pr->add(newLucene(IndexReader::open(dir3, false))); return pr; } - + virtual void modifyIndex(int32_t i) { _modifyIndex(i, dir3); @@ -575,15 +582,15 @@ namespace TestParallelReaderReopen }; } -BOOST_AUTO_TEST_CASE(testParallelReaderReopen) +TEST_F(IndexReaderReopenTest, testParallelReaderReopen) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); createIndex(dir2, true); - + performDefaultTests(newInstance(dir1, dir2)); - + dir1->close(); dir2->close(); @@ -591,9 +598,9 @@ BOOST_AUTO_TEST_CASE(testParallelReaderReopen) createIndex(dir3, true); DirectoryPtr dir4 = newLucene(); createIndex(dir4, true); - + performTestsWithExceptionInReopen(newInstance(dir3, dir4)); - + dir3->close(); dir4->close(); } @@ -603,7 +610,7 @@ static void doTestReopenWithCommit(DirectoryPtr dir, bool withReopen) IndexWriterPtr iwriter = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); iwriter->setMergeScheduler(newLucene()); IndexReaderPtr reader = IndexReader::open(dir, false); - + LuceneException finally; try { @@ -622,9 +629,9 @@ static void doTestReopenWithCommit(DirectoryPtr dir, bool withReopen) int32_t k = i - 1; int32_t n = j + k * M; DocumentPtr prevItereationDoc = reader->document(n); - BOOST_CHECK(prevItereationDoc); + EXPECT_TRUE(prevItereationDoc); String id = prevItereationDoc->get(L"id"); - BOOST_CHECK_EQUAL(StringUtils::toString(k) + L"_" + StringUtils::toString(j), id); + EXPECT_EQ(StringUtils::toString(k) + L"_" + StringUtils::toString(j), id); } } iwriter->commit(); @@ -657,9 +664,9 @@ static void doTestReopenWithCommit(DirectoryPtr dir, bool withReopen) /// IndexWriter.commit() does not update the index version populate an index in iterations. /// At the end of every iteration, commit the index and reopen/recreate the reader. -/// In each iteration verify the work of previous iteration. +/// In each iteration verify the work of previous iteration. /// Try this once with reopen once recreate, on both RAMDir and FSDir. -BOOST_AUTO_TEST_CASE(testCommitReopenFS) +TEST_F(IndexReaderReopenTest, testCommitReopenFS) { String indexDir(FileUtils::joinPath(getTempDir(), L"IndexReaderReopen")); DirectoryPtr dir = FSDirectory::open(indexDir); @@ -667,7 +674,7 @@ BOOST_AUTO_TEST_CASE(testCommitReopenFS) dir->close(); } -BOOST_AUTO_TEST_CASE(testCommitRecreateFS) +TEST_F(IndexReaderReopenTest, testCommitRecreateFS) { String indexDir(FileUtils::joinPath(getTempDir(), L"IndexReaderReopen")); DirectoryPtr dir = FSDirectory::open(indexDir); @@ -675,7 +682,7 @@ BOOST_AUTO_TEST_CASE(testCommitRecreateFS) dir->close(); } -BOOST_AUTO_TEST_CASE(testCommitRecreateRAM) +TEST_F(IndexReaderReopenTest, testCommitRecreateRAM) { DirectoryPtr dir = newLucene(); doTestReopenWithCommit(dir, false); @@ -692,25 +699,25 @@ namespace TestMultiReaderReopen this->dir1 = dir1; this->dir2 = dir2; } - + protected: DirectoryPtr dir1; DirectoryPtr dir2; - + public: virtual IndexReaderPtr openReader() { Collection readers = newCollection(IndexReader::open(dir1, false), IndexReader::open(dir2, false)); return newLucene(readers); } - + virtual void modifyIndex(int32_t i) { _modifyIndex(i, dir1); _modifyIndex(i, dir2); } }; - + class SecondReopen : public TestReopen::TestableReopen { public: @@ -719,11 +726,11 @@ namespace TestMultiReaderReopen this->dir3 = dir3; this->dir4 = dir4; } - + protected: DirectoryPtr dir3; DirectoryPtr dir4; - + public: virtual IndexReaderPtr openReader() { @@ -734,7 +741,7 @@ namespace TestMultiReaderReopen readers[2] = newLucene(IndexReader::open(dir3, false)); return newLucene(readers); } - + virtual void modifyIndex(int32_t i) { _modifyIndex(i, dir3); @@ -743,15 +750,15 @@ namespace TestMultiReaderReopen }; } -BOOST_AUTO_TEST_CASE(testMultiReaderReopen) +TEST_F(IndexReaderReopenTest, testMultiReaderReopen) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); createIndex(dir2, true); - + performDefaultTests(newInstance(dir1, dir2)); - + dir1->close(); dir2->close(); @@ -759,9 +766,9 @@ BOOST_AUTO_TEST_CASE(testMultiReaderReopen) createIndex(dir3, true); DirectoryPtr dir4 = newLucene(); createIndex(dir4, true); - + performTestsWithExceptionInReopen(newInstance(dir3, dir4)); - + dir3->close(); dir4->close(); } @@ -779,41 +786,41 @@ namespace TestMixedReaders this->dir4 = dir4; this->dir5 = dir5; } - + protected: DirectoryPtr dir1; DirectoryPtr dir2; DirectoryPtr dir3; DirectoryPtr dir4; DirectoryPtr dir5; - + public: virtual IndexReaderPtr openReader() { ParallelReaderPtr pr = newLucene(); pr->add(IndexReader::open(dir1, false)); pr->add(IndexReader::open(dir2, false)); - + Collection readers = newCollection(IndexReader::open(dir3, false), IndexReader::open(dir4, false)); MultiReaderPtr mr = newLucene(readers); - + Collection mixedReaders = newCollection(pr, mr, IndexReader::open(dir5, false)); return newLucene(mixedReaders); } - + virtual void modifyIndex(int32_t i) { - // only change norms in this index to maintain the same number of docs + // only change norms in this index to maintain the same number of docs // for each of ParallelReader's subreaders if (i == 1) - _modifyIndex(i, dir1); + _modifyIndex(i, dir1); _modifyIndex(i, dir4); _modifyIndex(i, dir5); } }; } -BOOST_AUTO_TEST_CASE(testMixedReaders) +TEST_F(IndexReaderReopenTest, testMixedReaders) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); @@ -825,9 +832,9 @@ BOOST_AUTO_TEST_CASE(testMixedReaders) createIndex(dir4, true); DirectoryPtr dir5 = newLucene(); createIndex(dir5, false); - + performDefaultTests(newInstance(dir1, dir2, dir3, dir4, dir5)); - + dir1->close(); dir2->close(); dir3->close(); @@ -835,7 +842,7 @@ BOOST_AUTO_TEST_CASE(testMixedReaders) dir5->close(); } -BOOST_AUTO_TEST_CASE(testReferenceCounting) +TEST_F(IndexReaderReopenTest, testReferenceCounting) { for (int32_t mode = 0; mode < 4; ++mode) { @@ -845,21 +852,21 @@ BOOST_AUTO_TEST_CASE(testReferenceCounting) IndexReaderPtr reader0 = IndexReader::open(dir1, false); checkRefCountEquals(1, reader0); - BOOST_CHECK(MiscUtils::typeOf(reader0)); + EXPECT_TRUE(MiscUtils::typeOf(reader0)); Collection subReaders0 = reader0->getSequentialSubReaders(); - + for (int32_t i = 0; i < subReaders0.size(); ++i) checkRefCountEquals(1, subReaders0[i]); - + // delete first document, so that only one of the subReaders have to be re-opened IndexReaderPtr modifier = IndexReader::open(dir1, false); modifier->deleteDocument(0); modifier->close(); IndexReaderPtr reader1 = refreshReader(reader0, true)->refreshedReader; - BOOST_CHECK(MiscUtils::typeOf(reader1)); + EXPECT_TRUE(MiscUtils::typeOf(reader1)); Collection subReaders1 = reader1->getSequentialSubReaders(); - BOOST_CHECK_EQUAL(subReaders0.size(), subReaders1.size()); + EXPECT_EQ(subReaders0.size(), subReaders1.size()); for (int32_t i = 0; i < subReaders0.size(); ++i) { if (subReaders0[i] != subReaders1[i]) @@ -870,17 +877,17 @@ BOOST_AUTO_TEST_CASE(testReferenceCounting) else checkRefCountEquals(2, subReaders0[i]); } - + // delete first document, so that only one of the subReaders have to be re-opened modifier = IndexReader::open(dir1, false); modifier->deleteDocument(1); modifier->close(); IndexReaderPtr reader2 = refreshReader(reader1, true)->refreshedReader; - BOOST_CHECK(MiscUtils::typeOf(reader2)); + EXPECT_TRUE(MiscUtils::typeOf(reader2)); Collection subReaders2 = reader2->getSequentialSubReaders(); - BOOST_CHECK_EQUAL(subReaders1.size(), subReaders2.size()); - + EXPECT_EQ(subReaders1.size(), subReaders2.size()); + for (int32_t i = 0; i < subReaders2.size(); ++i) { if (subReaders2[i] == subReaders1[i]) @@ -905,12 +912,12 @@ BOOST_AUTO_TEST_CASE(testReferenceCounting) } } } - + IndexReaderPtr reader3 = refreshReader(reader0, true)->refreshedReader; - BOOST_CHECK(MiscUtils::typeOf(reader3)); + EXPECT_TRUE(MiscUtils::typeOf(reader3)); Collection subReaders3 = reader3->getSequentialSubReaders(); - BOOST_CHECK_EQUAL(subReaders3.size(), subReaders0.size()); - + EXPECT_EQ(subReaders3.size(), subReaders0.size()); + // try some permutations switch (mode) { @@ -939,7 +946,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCounting) reader0->close(); break; } - + checkReaderClosed(reader0, true, true); checkReaderClosed(reader1, true, true); checkReaderClosed(reader2, true, true); @@ -949,7 +956,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCounting) } } -BOOST_AUTO_TEST_CASE(testReferenceCountingMultiReader) +TEST_F(IndexReaderReopenTest, testReferenceCountingMultiReader) { for (int32_t mode = 0; mode <= 1; ++mode) { @@ -974,7 +981,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCountingMultiReader) _modifyIndex(0, dir1); IndexReaderPtr reader2 = reader1->reopen(); checkRefCountEquals(2 + mode, reader1); - + if (mode == 1) initReader2->close(); @@ -988,7 +995,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCountingMultiReader) multiReader1->close(); checkRefCountEquals(1 + mode, reader1); - + if (mode == 1) initReader2->close(); @@ -1020,7 +1027,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCountingMultiReader) } } -BOOST_AUTO_TEST_CASE(testReferenceCountingParallelReader) +TEST_F(IndexReaderReopenTest, testReferenceCountingParallelReader) { for (int32_t mode = 0; mode <= 1; ++mode) { @@ -1047,7 +1054,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCountingParallelReader) _modifyIndex(0, dir2); IndexReaderPtr reader2 = reader1->reopen(); checkRefCountEquals(2 + mode, reader1); - + if (mode == 1) initReader2->close(); @@ -1061,7 +1068,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCountingParallelReader) parallelReader1->close(); checkRefCountEquals(1 + mode, reader1); - + if (mode == 1) initReader2->close(); @@ -1093,7 +1100,7 @@ BOOST_AUTO_TEST_CASE(testReferenceCountingParallelReader) } } -BOOST_AUTO_TEST_CASE(testNormsRefCounting) +TEST_F(IndexReaderReopenTest, testNormsRefCounting) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -1126,39 +1133,39 @@ BOOST_AUTO_TEST_CASE(testNormsRefCounting) // Now reader2-reader5 references reader1. reader1 and reader2 // share the same norms. reader3, reader4, reader5 also share norms. checkRefCountEquals(1, reader1); - BOOST_CHECK(!segmentReader1->normsClosed()); + EXPECT_TRUE(!segmentReader1->normsClosed()); reader1->close(); checkRefCountEquals(0, reader1); - BOOST_CHECK(!segmentReader1->normsClosed()); + EXPECT_TRUE(!segmentReader1->normsClosed()); reader2->close(); checkRefCountEquals(0, reader1); // now the norms for field1 and field2 should be closed - BOOST_CHECK(segmentReader1->normsClosed(L"field1")); - BOOST_CHECK(segmentReader1->normsClosed(L"field2")); + EXPECT_TRUE(segmentReader1->normsClosed(L"field1")); + EXPECT_TRUE(segmentReader1->normsClosed(L"field2")); // but the norms for field3 and field4 should still be open - BOOST_CHECK(!segmentReader1->normsClosed(L"field3")); - BOOST_CHECK(!segmentReader1->normsClosed(L"field4")); + EXPECT_TRUE(!segmentReader1->normsClosed(L"field3")); + EXPECT_TRUE(!segmentReader1->normsClosed(L"field4")); reader3->close(); checkRefCountEquals(0, reader1); - BOOST_CHECK(!segmentReader3->normsClosed()); + EXPECT_TRUE(!segmentReader3->normsClosed()); reader5->close(); checkRefCountEquals(0, reader1); - BOOST_CHECK(!segmentReader3->normsClosed()); + EXPECT_TRUE(!segmentReader3->normsClosed()); reader4->close(); checkRefCountEquals(0, reader1); // and now all norms that reader1 used should be closed - BOOST_CHECK(segmentReader1->normsClosed()); + EXPECT_TRUE(segmentReader1->normsClosed()); - // now that reader3, reader4 and reader5 are closed, the norms that those three + // now that reader3, reader4 and reader5 are closed, the norms that those three // readers shared should be closed as well - BOOST_CHECK(segmentReader3->normsClosed()); + EXPECT_TRUE(segmentReader3->normsClosed()); dir1->close(); } @@ -1173,17 +1180,17 @@ namespace TestReopen this->dir = dir; this->n = n; } - + protected: DirectoryPtr dir; int32_t n; - + public: virtual IndexReaderPtr openReader() { return IndexReader::open(dir, false); } - + virtual void modifyIndex(int32_t i) { if (i % 3 == 0) @@ -1206,7 +1213,7 @@ namespace TestReopen } } }; - + class FirstThreadTask : public ReaderThreadTask { public: @@ -1219,11 +1226,11 @@ namespace TestReopen this->readers = readers; this->rnd = newLucene(); } - + virtual ~FirstThreadTask() { } - + protected: IndexReaderPtr r; TestableReopenPtr test; @@ -1231,7 +1238,7 @@ namespace TestReopen HashSet readersToClose; Collection readers; RandomPtr rnd; - + public: virtual void run() { @@ -1262,12 +1269,12 @@ namespace TestReopen Collection hits = searcher->search(newLucene(newLucene(L"field1", L"a" + StringUtils::toString(rnd->nextInt(refreshed->maxDoc())))), FilterPtr(), 1000)->scoreDocs; if (!hits.empty()) searcher->doc(hits[0]->doc); - - // r might have changed because this is not a synchronized method. However we don't want to make it synchronized to test + + // r might have changed because this is not a synchronized method. However we don't want to make it synchronized to test // thread-safety of IndexReader.close(). That's why we add refreshed also to readersToClose, because double closing is fine. if (refreshed != r) refreshed->close(); - + { SyncLock readersLock(&readersToClose); readersToClose.add(refreshed); @@ -1277,7 +1284,7 @@ namespace TestReopen } } }; - + class SecondThreadTask : public ReaderThreadTask { public: @@ -1290,11 +1297,11 @@ namespace TestReopen this->readers = readers; this->rnd = newLucene(); } - + virtual ~SecondThreadTask() { } - + protected: IndexReaderPtr r; TestableReopenPtr test; @@ -1302,7 +1309,7 @@ namespace TestReopen HashSet readersToClose; Collection readers; RandomPtr rnd; - + public: virtual void run() { @@ -1322,34 +1329,34 @@ namespace TestReopen SyncLock readersLock(checkIndexMutex); checkIndexEquals(c->newReader, c->refreshedReader); } - + LuceneThread::threadSleep(100); } } }; } -BOOST_AUTO_TEST_CASE(testThreadSafety) +TEST_F(IndexReaderReopenTest, testThreadSafety) { DirectoryPtr dir = newLucene(); int32_t n = 150; - + IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < n; ++i) writer->addDocument(createDocument(i, 3)); writer->optimize(); writer->close(); - + TestReopen::TestableReopenPtr test = newInstance(dir, n); - + Collection readers = Collection::newInstance(); IndexReaderPtr firstReader = IndexReader::open(dir, false); IndexReaderPtr reader = firstReader; RandomPtr rnd = newLucene(); - + Collection threads = Collection::newInstance(n); HashSet readersToClose = HashSet::newInstance(); - + for (int32_t i = 0; i < n; ++i) { if (i % 10 == 0) @@ -1363,34 +1370,34 @@ BOOST_AUTO_TEST_CASE(testThreadSafety) reader = refreshed; } IndexReaderPtr r = reader; - + int32_t index = i; - + TestReopen::ReaderThreadTaskPtr task; - + if (i < 20 ||( i >= 50 && i < 70) || i > 90) task = newLucene(r, test, index, readersToClose, readers); else task = newLucene(r, test, index, readersToClose, readers); - + threads[i] = newLucene(task); threads[i]->start(); } - + LuceneThread::threadSleep(15000); - + for (int32_t i = 0; i < n; ++i) { if (threads[i]) threads[i]->stopThread(); } - + for (int32_t i = 0; i < n; ++i) { if (threads[i]) threads[i]->join(); } - + { SyncLock readersLock(&readersToClose); for (HashSet::iterator reader = readersToClose.begin(); reader != readersToClose.end(); ++reader) @@ -1399,20 +1406,20 @@ BOOST_AUTO_TEST_CASE(testThreadSafety) firstReader->close(); reader->close(); - + { SyncLock readersLock(&readersToClose); for (HashSet::iterator reader = readersToClose.begin(); reader != readersToClose.end(); ++reader) checkReaderClosed(*reader, true, true); } - + checkReaderClosed(reader, true, true); checkReaderClosed(firstReader, true, true); dir->close(); } -BOOST_AUTO_TEST_CASE(testCloseOrig) +TEST_F(IndexReaderReopenTest, testCloseOrig) { DirectoryPtr dir = newLucene(); createIndex(dir, false); @@ -1422,16 +1429,23 @@ BOOST_AUTO_TEST_CASE(testCloseOrig) r2->close(); IndexReaderPtr r3 = r1->reopen(); - BOOST_CHECK_NE(r1, r3); + EXPECT_NE(r1, r3); r1->close(); - - BOOST_CHECK_EXCEPTION(r1->document(2), AlreadyClosedException, check_exception(LuceneException::AlreadyClosed)); + + try + { + r1->document(2); + } + catch (AlreadyClosedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } r3->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDeletes) +TEST_F(IndexReaderReopenTest, testDeletes) { DirectoryPtr dir = newLucene(); createIndex(dir, false); // Create an index with a bunch of docs (1 segment) @@ -1444,35 +1458,35 @@ BOOST_AUTO_TEST_CASE(testDeletes) _modifyIndex(5, dir); // Add another doc (3 segments) IndexReaderPtr r2 = r1->reopen(); - BOOST_CHECK_NE(r1, r2); + EXPECT_NE(r1, r2); // Get SRs for the first segment from original SegmentReaderPtr sr1 = boost::dynamic_pointer_cast(r1->getSequentialSubReaders()[0]); - + // and reopened IRs SegmentReaderPtr sr2 = boost::dynamic_pointer_cast(r2->getSequentialSubReaders()[0]); // At this point they share the same BitVector - BOOST_CHECK_EQUAL(sr1->deletedDocs, sr2->deletedDocs); + EXPECT_EQ(sr1->deletedDocs, sr2->deletedDocs); r2->deleteDocument(0); // r1 should not see the delete - BOOST_CHECK(!r1->isDeleted(0)); + EXPECT_TRUE(!r1->isDeleted(0)); // Now r2 should have made a private copy of deleted docs: - BOOST_CHECK_NE(sr1->deletedDocs, sr2->deletedDocs); + EXPECT_NE(sr1->deletedDocs, sr2->deletedDocs); r1->close(); r2->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDeletes2) +TEST_F(IndexReaderReopenTest, testDeletes2) { DirectoryPtr dir = newLucene(); createIndex(dir, false); - + // Get delete bitVector _modifyIndex(0, dir); IndexReaderPtr r1 = IndexReader::open(dir, false); @@ -1481,7 +1495,7 @@ BOOST_AUTO_TEST_CASE(testDeletes2) _modifyIndex(5, dir); IndexReaderPtr r2 = r1->reopen(); - BOOST_CHECK_NE(r1, r2); + EXPECT_NE(r1, r2); Collection rs2 = r2->getSequentialSubReaders(); @@ -1489,12 +1503,12 @@ BOOST_AUTO_TEST_CASE(testDeletes2) SegmentReaderPtr sr2 = boost::dynamic_pointer_cast(rs2[0]); // At this point they share the same BitVector - BOOST_CHECK_EQUAL(sr1->deletedDocs, sr2->deletedDocs); + EXPECT_EQ(sr1->deletedDocs, sr2->deletedDocs); BitVectorPtr delDocs = sr1->deletedDocs; r1->close(); r2->deleteDocument(0); - BOOST_CHECK_EQUAL(delDocs, sr2->deletedDocs); + EXPECT_EQ(delDocs, sr2->deletedDocs); r2->close(); dir->close(); } @@ -1507,21 +1521,21 @@ namespace TestReopen virtual ~KeepAllCommits() { } - + LUCENE_CLASS(KeepAllCommits); - + public: virtual void onInit(Collection commits) { } - + virtual void onCommit(Collection commits) { } }; } -BOOST_AUTO_TEST_CASE(testReopenOnCommit) +TEST_F(IndexReaderReopenTest, testReopenOnCommit) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), (IndexDeletionPolicyPtr)newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -1542,32 +1556,37 @@ BOOST_AUTO_TEST_CASE(testReopenOnCommit) writer->commit(data); } writer->close(); - + IndexReaderPtr r = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(0, r->numDocs()); - BOOST_CHECK_EQUAL(4, r->maxDoc()); - + EXPECT_EQ(0, r->numDocs()); + EXPECT_EQ(4, r->maxDoc()); + Collection commits = IndexReader::listCommits(dir); for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { IndexReaderPtr r2 = r->reopen(*commit); - BOOST_CHECK_NE(r2, r); - - BOOST_CHECK_EXCEPTION(r2->deleteDocument(0), UnsupportedOperationException, check_exception(LuceneException::UnsupportedOperation)); - + EXPECT_NE(r2, r); + + try + { + r2->deleteDocument(0); + } + catch (UnsupportedOperationException& e) + { + EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); + } + MapStringString s = (*commit)->getUserData(); int32_t v = s.empty() ? -1 : StringUtils::toInt(s.get(L"index")); - + if (v < 4) - BOOST_CHECK_EQUAL(1 + v, r2->numDocs()); + EXPECT_EQ(1 + v, r2->numDocs()); else - BOOST_CHECK_EQUAL(7 - v, r2->numDocs()); - + EXPECT_EQ(7 - v, r2->numDocs()); + r->close(); r = r2; } r->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexReaderTest.cpp b/src/test/index/IndexReaderTest.cpp index e1b1f2db..58c82615 100644 --- a/src/test/index/IndexReaderTest.cpp +++ b/src/test/index/IndexReaderTest.cpp @@ -39,7 +39,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexReaderTest, LuceneTestFixture) +typedef LuceneTestFixture IndexReaderTest; static void addDocumentWithFields(IndexWriterPtr writer) { @@ -87,11 +87,11 @@ static void checkTermDocsCount(IndexReaderPtr reader, TermPtr term, int32_t expe try { tdocs = reader->termDocs(term); - BOOST_CHECK(tdocs); + EXPECT_TRUE(tdocs); int32_t count = 0; while (tdocs->next()) ++count; - BOOST_CHECK_EQUAL(expected, count); + EXPECT_EQ(expected, count); } catch (LuceneException& e) { @@ -113,8 +113,8 @@ static DocumentPtr createDocument(const String& id) doc->add(newLucene(L"id", id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS)); return doc; } - -BOOST_AUTO_TEST_CASE(testCommitUserData) + +TEST_F(IndexReaderTest, testCommitUserData) { RAMDirectoryPtr d = newLucene(); @@ -138,16 +138,16 @@ BOOST_AUTO_TEST_CASE(testCommitUserData) IndexReaderPtr r2 = IndexReader::open(d, false); IndexCommitPtr c = r->getIndexCommit(); MapStringString expectedData = c->getUserData(); - - BOOST_CHECK_EQUAL(expectedData.size(), commitUserData.size()); + + EXPECT_EQ(expectedData.size(), commitUserData.size()); for (MapStringString::iterator expected = expectedData.begin(); expected != expectedData.end(); ++expected) - BOOST_CHECK(commitUserData.find(expected->first) != commitUserData.end()); + EXPECT_TRUE(commitUserData.find(expected->first) != commitUserData.end()); for (MapStringString::iterator commit = commitUserData.begin(); commit != commitUserData.end(); ++commit) - BOOST_CHECK(expectedData.find(commit->first) != expectedData.end()); + EXPECT_TRUE(expectedData.find(commit->first) != expectedData.end()); - BOOST_CHECK_EQUAL(sis->getCurrentSegmentFileName(), c->getSegmentsFileName()); + EXPECT_EQ(sis->getCurrentSegmentFileName(), c->getSegmentsFileName()); - BOOST_CHECK(c->equals(r->getIndexCommit())); + EXPECT_TRUE(c->equals(r->getIndexCommit())); // Change the index writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); @@ -157,8 +157,8 @@ BOOST_AUTO_TEST_CASE(testCommitUserData) writer->close(); IndexReaderPtr r3 = r2->reopen(); - BOOST_CHECK(!c->equals(r3->getIndexCommit())); - BOOST_CHECK(!r2->getIndexCommit()->isOptimized()); + EXPECT_TRUE(!c->equals(r3->getIndexCommit())); + EXPECT_TRUE(!r2->getIndexCommit()->isOptimized()); r3->close(); writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); @@ -166,13 +166,13 @@ BOOST_AUTO_TEST_CASE(testCommitUserData) writer->close(); r3 = r2->reopen(); - BOOST_CHECK(r3->getIndexCommit()->isOptimized()); + EXPECT_TRUE(r3->getIndexCommit()->isOptimized()); r2->close(); r3->close(); d->close(); } -BOOST_AUTO_TEST_CASE(testIsCurrent) +TEST_F(IndexReaderTest, testIsCurrent) { RAMDirectoryPtr d = newLucene(); IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -180,22 +180,22 @@ BOOST_AUTO_TEST_CASE(testIsCurrent) writer->close(); // set up reader IndexReaderPtr reader = IndexReader::open(d, false); - BOOST_CHECK(reader->isCurrent()); + EXPECT_TRUE(reader->isCurrent()); // modify index by adding another document writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); writer->close(); - BOOST_CHECK(!reader->isCurrent()); + EXPECT_TRUE(!reader->isCurrent()); // re-create index writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); writer->close(); - BOOST_CHECK(!reader->isCurrent()); + EXPECT_TRUE(!reader->isCurrent()); reader->close(); d->close(); } -BOOST_AUTO_TEST_CASE(testGetFieldNames) +TEST_F(IndexReaderTest, testGetFieldNames) { RAMDirectoryPtr d = newLucene(); // set up writer @@ -204,12 +204,12 @@ BOOST_AUTO_TEST_CASE(testGetFieldNames) writer->close(); // set up reader IndexReaderPtr reader = IndexReader::open(d, false); - BOOST_CHECK(reader->isCurrent()); + EXPECT_TRUE(reader->isCurrent()); HashSet fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_ALL); - BOOST_CHECK(fieldNames.contains(L"keyword")); - BOOST_CHECK(fieldNames.contains(L"text")); - BOOST_CHECK(fieldNames.contains(L"unindexed")); - BOOST_CHECK(fieldNames.contains(L"unstored")); + EXPECT_TRUE(fieldNames.contains(L"keyword")); + EXPECT_TRUE(fieldNames.contains(L"text")); + EXPECT_TRUE(fieldNames.contains(L"unindexed")); + EXPECT_TRUE(fieldNames.contains(L"unstored")); reader->close(); // add more documents writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); @@ -222,68 +222,68 @@ BOOST_AUTO_TEST_CASE(testGetFieldNames) // new termvector fields for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) addDocumentWithTermVectorFields(writer); - + writer->close(); // verify fields again reader = IndexReader::open(d, false); fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_ALL); - BOOST_CHECK_EQUAL(13, fieldNames.size()); // the following fields - BOOST_CHECK(fieldNames.contains(L"keyword")); - BOOST_CHECK(fieldNames.contains(L"text")); - BOOST_CHECK(fieldNames.contains(L"unindexed")); - BOOST_CHECK(fieldNames.contains(L"unstored")); - BOOST_CHECK(fieldNames.contains(L"keyword2")); - BOOST_CHECK(fieldNames.contains(L"text2")); - BOOST_CHECK(fieldNames.contains(L"unindexed2")); - BOOST_CHECK(fieldNames.contains(L"unstored2")); - BOOST_CHECK(fieldNames.contains(L"tvnot")); - BOOST_CHECK(fieldNames.contains(L"termvector")); - BOOST_CHECK(fieldNames.contains(L"tvposition")); - BOOST_CHECK(fieldNames.contains(L"tvoffset")); - BOOST_CHECK(fieldNames.contains(L"tvpositionoffset")); + EXPECT_EQ(13, fieldNames.size()); // the following fields + EXPECT_TRUE(fieldNames.contains(L"keyword")); + EXPECT_TRUE(fieldNames.contains(L"text")); + EXPECT_TRUE(fieldNames.contains(L"unindexed")); + EXPECT_TRUE(fieldNames.contains(L"unstored")); + EXPECT_TRUE(fieldNames.contains(L"keyword2")); + EXPECT_TRUE(fieldNames.contains(L"text2")); + EXPECT_TRUE(fieldNames.contains(L"unindexed2")); + EXPECT_TRUE(fieldNames.contains(L"unstored2")); + EXPECT_TRUE(fieldNames.contains(L"tvnot")); + EXPECT_TRUE(fieldNames.contains(L"termvector")); + EXPECT_TRUE(fieldNames.contains(L"tvposition")); + EXPECT_TRUE(fieldNames.contains(L"tvoffset")); + EXPECT_TRUE(fieldNames.contains(L"tvpositionoffset")); // verify that only indexed fields were returned fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_INDEXED); - BOOST_CHECK_EQUAL(11, fieldNames.size()); // 6 original + the 5 termvector fields - BOOST_CHECK(fieldNames.contains(L"keyword")); - BOOST_CHECK(fieldNames.contains(L"text")); - BOOST_CHECK(fieldNames.contains(L"unstored")); - BOOST_CHECK(fieldNames.contains(L"keyword2")); - BOOST_CHECK(fieldNames.contains(L"text2")); - BOOST_CHECK(fieldNames.contains(L"unstored2")); - BOOST_CHECK(fieldNames.contains(L"tvnot")); - BOOST_CHECK(fieldNames.contains(L"termvector")); - BOOST_CHECK(fieldNames.contains(L"tvposition")); - BOOST_CHECK(fieldNames.contains(L"tvoffset")); - BOOST_CHECK(fieldNames.contains(L"tvpositionoffset")); + EXPECT_EQ(11, fieldNames.size()); // 6 original + the 5 termvector fields + EXPECT_TRUE(fieldNames.contains(L"keyword")); + EXPECT_TRUE(fieldNames.contains(L"text")); + EXPECT_TRUE(fieldNames.contains(L"unstored")); + EXPECT_TRUE(fieldNames.contains(L"keyword2")); + EXPECT_TRUE(fieldNames.contains(L"text2")); + EXPECT_TRUE(fieldNames.contains(L"unstored2")); + EXPECT_TRUE(fieldNames.contains(L"tvnot")); + EXPECT_TRUE(fieldNames.contains(L"termvector")); + EXPECT_TRUE(fieldNames.contains(L"tvposition")); + EXPECT_TRUE(fieldNames.contains(L"tvoffset")); + EXPECT_TRUE(fieldNames.contains(L"tvpositionoffset")); // verify that only unindexed fields were returned fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_UNINDEXED); - BOOST_CHECK_EQUAL(2, fieldNames.size()); // the following fields - BOOST_CHECK(fieldNames.contains(L"unindexed")); - BOOST_CHECK(fieldNames.contains(L"unindexed2")); + EXPECT_EQ(2, fieldNames.size()); // the following fields + EXPECT_TRUE(fieldNames.contains(L"unindexed")); + EXPECT_TRUE(fieldNames.contains(L"unindexed2")); - // verify index term vector fields + // verify index term vector fields fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR); - BOOST_CHECK_EQUAL(1, fieldNames.size()); // 1 field has term vector only - BOOST_CHECK(fieldNames.contains(L"termvector")); + EXPECT_EQ(1, fieldNames.size()); // 1 field has term vector only + EXPECT_TRUE(fieldNames.contains(L"termvector")); fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_POSITION); - BOOST_CHECK_EQUAL(1, fieldNames.size()); // 4 fields are indexed with term vectors - BOOST_CHECK(fieldNames.contains(L"tvposition")); + EXPECT_EQ(1, fieldNames.size()); // 4 fields are indexed with term vectors + EXPECT_TRUE(fieldNames.contains(L"tvposition")); fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_OFFSET); - BOOST_CHECK_EQUAL(1, fieldNames.size()); // 4 fields are indexed with term vectors - BOOST_CHECK(fieldNames.contains(L"tvoffset")); + EXPECT_EQ(1, fieldNames.size()); // 4 fields are indexed with term vectors + EXPECT_TRUE(fieldNames.contains(L"tvoffset")); fieldNames = reader->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET); - BOOST_CHECK_EQUAL(1, fieldNames.size()); // 4 fields are indexed with term vectors - BOOST_CHECK(fieldNames.contains(L"tvpositionoffset")); + EXPECT_EQ(1, fieldNames.size()); // 4 fields are indexed with term vectors + EXPECT_TRUE(fieldNames.contains(L"tvpositionoffset")); reader->close(); d->close(); } -BOOST_AUTO_TEST_CASE(testTermVectors) +TEST_F(IndexReaderTest, testTermVectors) { RAMDirectoryPtr d = newLucene(); // set up writer @@ -305,14 +305,14 @@ BOOST_AUTO_TEST_CASE(testTermVectors) FieldSortedTermVectorMapperPtr mapper = newLucene(TermVectorEntryFreqSortedComparator::compare); reader->getTermFreqVector(0, mapper); MapStringCollectionTermVectorEntry map = mapper->getFieldToTerms(); - BOOST_CHECK(map); - BOOST_CHECK_EQUAL(map.size(), 4); + EXPECT_TRUE(map); + EXPECT_EQ(map.size(), 4); Collection set = map.get(L"termvector"); for (Collection::iterator entry = set.begin(); entry != set.end(); ++entry) - BOOST_CHECK(*entry); + EXPECT_TRUE(*entry); } -BOOST_AUTO_TEST_CASE(testBasicDelete) +TEST_F(IndexReaderTest, testBasicDelete) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -322,11 +322,11 @@ BOOST_AUTO_TEST_CASE(testBasicDelete) for (int32_t i = 0; i < 100; ++i) addDoc(writer, searchTerm->text()); writer->close(); - + // open reader at this point - this should fix the view of the // index at the point of having 100 "aaa" documents and 0 "bbb" IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); + EXPECT_EQ(100, reader->docFreq(searchTerm)); checkTermDocsCount(reader, searchTerm, 100); reader->close(); @@ -334,31 +334,31 @@ BOOST_AUTO_TEST_CASE(testBasicDelete) int32_t deleted = 0; reader = IndexReader::open(dir, false); deleted = reader->deleteDocuments(searchTerm); - BOOST_CHECK_EQUAL(100, deleted); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); + EXPECT_EQ(100, deleted); + EXPECT_EQ(100, reader->docFreq(searchTerm)); checkTermDocsCount(reader, searchTerm, 0); - // open a 2nd reader to make sure first reader can commit its changes (.del) + // open a 2nd reader to make sure first reader can commit its changes (.del) // while second reader is open IndexReaderPtr reader2 = IndexReader::open(dir, false); reader->close(); // create a new reader and re-test reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); + EXPECT_EQ(100, reader->docFreq(searchTerm)); checkTermDocsCount(reader, searchTerm, 0); reader->close(); reader2->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testBinaryFields) +TEST_F(IndexReaderTest, testBinaryFields) { DirectoryPtr dir = newLucene(); uint8_t _bin[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ByteArray bin(ByteArray::newInstance(10)); std::memcpy(bin.get(), _bin, 10); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); for (int32_t i = 0; i < 10; ++i) { @@ -377,28 +377,28 @@ BOOST_AUTO_TEST_CASE(testBinaryFields) IndexReaderPtr reader = IndexReader::open(dir, false); doc = reader->document(reader->maxDoc() - 1); Collection fields = doc->getFields(L"bin1"); - BOOST_CHECK(fields); - BOOST_CHECK_EQUAL(1, fields.size()); + EXPECT_TRUE(fields); + EXPECT_EQ(1, fields.size()); FieldPtr b1 = fields[0]; - BOOST_CHECK(b1->isBinary()); + EXPECT_TRUE(b1->isBinary()); ByteArray data1 = b1->getBinaryValue(); - BOOST_CHECK_EQUAL(bin.size(), b1->getBinaryLength()); - BOOST_CHECK(std::memcmp(bin.get(), data1.get() + b1->getBinaryOffset(), bin.size()) == 0); + EXPECT_EQ(bin.size(), b1->getBinaryLength()); + EXPECT_TRUE(std::memcmp(bin.get(), data1.get() + b1->getBinaryOffset(), bin.size()) == 0); HashSet lazyFields = HashSet::newInstance(); lazyFields.add(L"bin1"); FieldSelectorPtr sel = newLucene(HashSet::newInstance(), lazyFields); doc = reader->document(reader->maxDoc() - 1, sel); Collection fieldables = doc->getFieldables(L"bin1"); - BOOST_CHECK(fieldables); - BOOST_CHECK_EQUAL(1, fieldables.size()); + EXPECT_TRUE(fieldables); + EXPECT_EQ(1, fieldables.size()); FieldablePtr fb1 = fieldables[0]; - BOOST_CHECK(fb1->isBinary()); - BOOST_CHECK_EQUAL(bin.size(), fb1->getBinaryLength()); + EXPECT_TRUE(fb1->isBinary()); + EXPECT_EQ(bin.size(), fb1->getBinaryLength()); data1 = fb1->getBinaryValue(); - BOOST_CHECK_EQUAL(bin.size(), fb1->getBinaryLength()); - BOOST_CHECK(std::memcmp(bin.get(), data1.get() + fb1->getBinaryOffset(), bin.size()) == 0); + EXPECT_EQ(bin.size(), fb1->getBinaryLength()); + EXPECT_TRUE(std::memcmp(bin.get(), data1.get() + fb1->getBinaryOffset(), bin.size()) == 0); reader->close(); - + // force optimize writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->optimize(); @@ -406,94 +406,136 @@ BOOST_AUTO_TEST_CASE(testBinaryFields) reader = IndexReader::open(dir, false); doc = reader->document(reader->maxDoc() - 1); fields = doc->getFields(L"bin1"); - BOOST_CHECK(fields); - BOOST_CHECK_EQUAL(1, fields.size()); + EXPECT_TRUE(fields); + EXPECT_EQ(1, fields.size()); b1 = fields[0]; - BOOST_CHECK(b1->isBinary()); + EXPECT_TRUE(b1->isBinary()); data1 = b1->getBinaryValue(); - BOOST_CHECK_EQUAL(bin.size(), b1->getBinaryLength()); - BOOST_CHECK(std::memcmp(bin.get(), data1.get() + b1->getBinaryOffset(), bin.size()) == 0); + EXPECT_EQ(bin.size(), b1->getBinaryLength()); + EXPECT_TRUE(std::memcmp(bin.get(), data1.get() + b1->getBinaryOffset(), bin.size()) == 0); reader->close(); } /// Make sure attempts to make changes after reader is closed throws IOException -BOOST_AUTO_TEST_CASE(testChangesAfterClose) +TEST_F(IndexReaderTest, testChangesAfterClose) { DirectoryPtr dir = newLucene(); TermPtr searchTerm = newLucene(L"content", L"aaa"); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 11 documents with term : aaa for (int32_t i = 0; i < 11; ++i) addDoc(writer, searchTerm->text()); writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, false); // Close reader reader->close(); - + // Then, try to make changes - BOOST_CHECK_EXCEPTION(reader->deleteDocument(4), AlreadyClosedException, check_exception(LuceneException::AlreadyClosed)); - BOOST_CHECK_EXCEPTION(reader->setNorm(5, L"aaa", 2.0), AlreadyClosedException, check_exception(LuceneException::AlreadyClosed)); - BOOST_CHECK_EXCEPTION(reader->undeleteAll(), AlreadyClosedException, check_exception(LuceneException::AlreadyClosed)); + try + { + reader->deleteDocument(4); + } + catch (AlreadyClosedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } + try + { + reader->setNorm(5, L"aaa", 2.0); + } + catch (AlreadyClosedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } + try + { + reader->undeleteAll(); + } + catch (AlreadyClosedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } } /// Make sure we get lock obtain failed exception with 2 writers -BOOST_AUTO_TEST_CASE(testLockObtainFailed) +TEST_F(IndexReaderTest, testLockObtainFailed) { DirectoryPtr dir = newLucene(); TermPtr searchTerm = newLucene(L"content", L"aaa"); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 11 documents with term : aaa for (int32_t i = 0; i < 11; ++i) addDoc(writer, searchTerm->text()); - + IndexReaderPtr reader = IndexReader::open(dir, false); - + // Try to make changes - BOOST_CHECK_EXCEPTION(reader->deleteDocument(4), LockObtainFailedException, check_exception(LuceneException::LockObtainFailed)); - BOOST_CHECK_EXCEPTION(reader->setNorm(5, L"aaa", 2.0), LockObtainFailedException, check_exception(LuceneException::LockObtainFailed)); - BOOST_CHECK_EXCEPTION(reader->undeleteAll(), LockObtainFailedException, check_exception(LuceneException::LockObtainFailed)); + try + { + reader->deleteDocument(4); + } + catch (LockObtainFailedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } + try + { + reader->setNorm(5, L"aaa", 2.0); + } + catch (LockObtainFailedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } + try + { + reader->undeleteAll(); + } + catch (LockObtainFailedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } writer->close(); reader->close(); } -BOOST_AUTO_TEST_CASE(testWritingNorms) +TEST_F(IndexReaderTest, testWritingNorms) { String indexDir(FileUtils::joinPath(getTempDir(), L"lucenetestnormwriter")); DirectoryPtr dir = FSDirectory::open(indexDir); TermPtr searchTerm = newLucene(L"content", L"aaa"); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(writer, searchTerm->text()); writer->close(); - + // now open reader & set norm for doc 0 IndexReaderPtr reader = IndexReader::open(dir, false); reader->setNorm(0, L"content", 2.0); // we should be holding the write lock now - BOOST_CHECK(IndexWriter::isLocked(dir)); + EXPECT_TRUE(IndexWriter::isLocked(dir)); reader->commit(MapStringString()); // we should not be holding the write lock now - BOOST_CHECK(!IndexWriter::isLocked(dir)); + EXPECT_TRUE(!IndexWriter::isLocked(dir)); // open a 2nd reader IndexReaderPtr reader2 = IndexReader::open(dir, false); // set norm again for doc 0 reader->setNorm(0, L"content", 3.0); - BOOST_CHECK(IndexWriter::isLocked(dir)); + EXPECT_TRUE(IndexWriter::isLocked(dir)); reader->close(); // we should not be holding the write lock now - BOOST_CHECK(!IndexWriter::isLocked(dir)); + EXPECT_TRUE(!IndexWriter::isLocked(dir)); reader2->close(); dir->close(); @@ -502,14 +544,14 @@ BOOST_AUTO_TEST_CASE(testWritingNorms) } /// Make sure you can set norms and commit, and there are no extra norms files left -BOOST_AUTO_TEST_CASE(testWritingNormsNoReader) +TEST_F(IndexReaderTest, testWritingNormsNoReader) { RAMDirectoryPtr dir = newLucene(); - + // add 1 documents with term : aaa IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); TermPtr searchTerm = newLucene(L"content", L"aaa"); - + writer->setUseCompoundFile(false); addDoc(writer, searchTerm->text()); writer->close(); @@ -523,7 +565,7 @@ BOOST_AUTO_TEST_CASE(testWritingNormsNoReader) reader = IndexReader::open(dir, false); reader->setNorm(0, L"content", 2.0); reader->close(); - BOOST_CHECK(!dir->fileExists(L"_0_1.s0")); + EXPECT_TRUE(!dir->fileExists(L"_0_1.s0")); dir->close(); } @@ -541,11 +583,11 @@ static void deleteReaderWriterConflict(bool optimize) addDoc(writer, searchTerm->text()); writer->close(); - // open reader at this point - this should fix the view of the index at the point of + // open reader at this point - this should fix the view of the index at the point of // having 100 "aaa" documents and 0 "bbb" IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); - BOOST_CHECK_EQUAL(0, reader->docFreq(searchTerm2)); + EXPECT_EQ(100, reader->docFreq(searchTerm)); + EXPECT_EQ(0, reader->docFreq(searchTerm2)); checkTermDocsCount(reader, searchTerm, 100); checkTermDocsCount(reader, searchTerm2, 0); @@ -553,7 +595,7 @@ static void deleteReaderWriterConflict(bool optimize) writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < 100; ++i) addDoc(writer, searchTerm2->text()); - + // request optimization // This causes a new segment to become current for all subsequent // searchers. Because of this, deletions made via a previously open @@ -564,52 +606,59 @@ static void deleteReaderWriterConflict(bool optimize) writer->close(); // The reader should not see the new data - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); - BOOST_CHECK_EQUAL(0, reader->docFreq(searchTerm2)); + EXPECT_EQ(100, reader->docFreq(searchTerm)); + EXPECT_EQ(0, reader->docFreq(searchTerm2)); checkTermDocsCount(reader, searchTerm, 100); checkTermDocsCount(reader, searchTerm2, 0); - + // delete documents containing term: aaa // NOTE: the reader was created when only "aaa" documents were in int32_t deleted = 0; - BOOST_CHECK_EXCEPTION(deleted = reader->deleteDocuments(searchTerm), StaleReaderException, check_exception(LuceneException::StaleReader)); + try + { + deleted = reader->deleteDocuments(searchTerm); + } + catch (StaleReaderException& e) + { + EXPECT_TRUE(check_exception(LuceneException::StaleReader)(e)); + } // Re-open index reader and try again. This time it should see the new data. reader->close(); reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm2)); + EXPECT_EQ(100, reader->docFreq(searchTerm)); + EXPECT_EQ(100, reader->docFreq(searchTerm2)); checkTermDocsCount(reader, searchTerm, 100); checkTermDocsCount(reader, searchTerm2, 100); deleted = reader->deleteDocuments(searchTerm); - BOOST_CHECK_EQUAL(100, deleted); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm2)); + EXPECT_EQ(100, deleted); + EXPECT_EQ(100, reader->docFreq(searchTerm)); + EXPECT_EQ(100, reader->docFreq(searchTerm2)); checkTermDocsCount(reader, searchTerm, 0); checkTermDocsCount(reader, searchTerm2, 100); reader->close(); // create a new reader and re-test reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm)); - BOOST_CHECK_EQUAL(100, reader->docFreq(searchTerm2)); + EXPECT_EQ(100, reader->docFreq(searchTerm)); + EXPECT_EQ(100, reader->docFreq(searchTerm2)); checkTermDocsCount(reader, searchTerm, 0); checkTermDocsCount(reader, searchTerm2, 100); reader->close(); } -BOOST_AUTO_TEST_CASE(testDeleteReaderWriterConflictUnoptimized) +TEST_F(IndexReaderTest, testDeleteReaderWriterConflictUnoptimized) { deleteReaderWriterConflict(false); } -BOOST_AUTO_TEST_CASE(testDeleteReaderWriterConflictOptimized) +TEST_F(IndexReaderTest, testDeleteReaderWriterConflictOptimized) { deleteReaderWriterConflict(true); } -BOOST_AUTO_TEST_CASE(testFilesOpenClose) +TEST_F(IndexReaderTest, testFilesOpenClose) { // Create initial data set String dirFile = FileUtils::joinPath(getTempDir(), L"testIndex"); @@ -636,10 +685,10 @@ BOOST_AUTO_TEST_CASE(testFilesOpenClose) dir->close(); // The following will fail if reader did not close all files - BOOST_CHECK(FileUtils::removeDirectory(dirFile)); + EXPECT_TRUE(FileUtils::removeDirectory(dirFile)); } -BOOST_AUTO_TEST_CASE(testLastModified) +TEST_F(IndexReaderTest, testLastModified) { String fileDir = FileUtils::joinPath(getTempDir(), L"testIndex"); for (int32_t i = 0; i < 2; ++i) @@ -648,22 +697,22 @@ BOOST_AUTO_TEST_CASE(testLastModified) try { DirectoryPtr dir = i == 0 ? newLucene() : getDirectory(); - BOOST_CHECK(!IndexReader::indexExists(dir)); + EXPECT_TRUE(!IndexReader::indexExists(dir)); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); - BOOST_CHECK(IndexWriter::isLocked(dir)); // writer open, so dir is locked + EXPECT_TRUE(IndexWriter::isLocked(dir)); // writer open, so dir is locked writer->close(); - BOOST_CHECK(IndexReader::indexExists(dir)); + EXPECT_TRUE(IndexReader::indexExists(dir)); IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK(!IndexWriter::isLocked(dir)); // reader only, no lock + EXPECT_TRUE(!IndexWriter::isLocked(dir)); // reader only, no lock int64_t version = IndexReader::lastModified(dir); if (i == 1) { int64_t version2 = IndexReader::lastModified(dir); - BOOST_CHECK_EQUAL(version, version2); + EXPECT_EQ(version, version2); } reader->close(); - + // modify index and check version has been incremented LuceneThread::threadSleep(1000); @@ -671,7 +720,7 @@ BOOST_AUTO_TEST_CASE(testLastModified) addDocumentWithFields(writer); writer->close(); reader = IndexReader::open(dir, false); - BOOST_CHECK(version <= IndexReader::lastModified(dir)); + EXPECT_TRUE(version <= IndexReader::lastModified(dir)); reader->close(); dir->close(); } @@ -680,22 +729,22 @@ BOOST_AUTO_TEST_CASE(testLastModified) finally = e; } if (i == 1) - BOOST_CHECK(FileUtils::removeDirectory(fileDir)); + EXPECT_TRUE(FileUtils::removeDirectory(fileDir)); finally.throwException(); } } -BOOST_AUTO_TEST_CASE(testVersion) +TEST_F(IndexReaderTest, testVersion) { DirectoryPtr dir = newLucene(); - BOOST_CHECK(!IndexReader::indexExists(dir)); + EXPECT_TRUE(!IndexReader::indexExists(dir)); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); - BOOST_CHECK(IndexWriter::isLocked(dir)); // writer open, so dir is locked + EXPECT_TRUE(IndexWriter::isLocked(dir)); // writer open, so dir is locked writer->close(); - BOOST_CHECK(IndexReader::indexExists(dir)); + EXPECT_TRUE(IndexReader::indexExists(dir)); IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK(!IndexWriter::isLocked(dir)); // reader only, no lock + EXPECT_TRUE(!IndexWriter::isLocked(dir)); // reader only, no lock int64_t version = IndexReader::getCurrentVersion(dir); reader->close(); // modify index and check version has been incremented @@ -703,12 +752,12 @@ BOOST_AUTO_TEST_CASE(testVersion) addDocumentWithFields(writer); writer->close(); reader = IndexReader::open(dir, false); - BOOST_CHECK(version < IndexReader::getCurrentVersion(dir)); + EXPECT_TRUE(version < IndexReader::getCurrentVersion(dir)); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testLock) +TEST_F(IndexReaderTest, testLock) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -716,15 +765,22 @@ BOOST_AUTO_TEST_CASE(testLock) writer->close(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); IndexReaderPtr reader = IndexReader::open(dir, false); - BOOST_CHECK_EXCEPTION(reader->deleteDocument(0), LockObtainFailedException, check_exception(LuceneException::LockObtainFailed)); - IndexWriter::unlock(dir); // this should not be done in the real world! + try + { + reader->deleteDocument(0); + } + catch (LockObtainFailedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } + IndexWriter::unlock(dir); // this should not be done in the real world! reader->deleteDocument(0); reader->close(); writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testUndeleteAll) +TEST_F(IndexReaderTest, testUndeleteAll) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -737,12 +793,12 @@ BOOST_AUTO_TEST_CASE(testUndeleteAll) reader->undeleteAll(); reader->close(); reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(2, reader->numDocs()); // nothing has really been deleted thanks to undeleteAll() + EXPECT_EQ(2, reader->numDocs()); // nothing has really been deleted thanks to undeleteAll() reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testUndeleteAllAfterClose) +TEST_F(IndexReaderTest, testUndeleteAllAfterClose) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -755,12 +811,12 @@ BOOST_AUTO_TEST_CASE(testUndeleteAllAfterClose) reader->close(); reader = IndexReader::open(dir, false); reader->undeleteAll(); - BOOST_CHECK_EQUAL(2, reader->numDocs()); // nothing has really been deleted thanks to undeleteAll() + EXPECT_EQ(2, reader->numDocs()); // nothing has really been deleted thanks to undeleteAll() reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testUndeleteAllAfterCloseThenReopen) +TEST_F(IndexReaderTest, testUndeleteAllAfterCloseThenReopen) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -775,7 +831,7 @@ BOOST_AUTO_TEST_CASE(testUndeleteAllAfterCloseThenReopen) reader->undeleteAll(); reader->close(); reader = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(2, reader->numDocs()); // nothing has really been deleted thanks to undeleteAll() + EXPECT_EQ(2, reader->numDocs()); // nothing has really been deleted thanks to undeleteAll() reader->close(); dir->close(); } @@ -787,7 +843,7 @@ static void deleteReaderReaderConflict(bool optimize) TermPtr searchTerm1 = newLucene(L"content", L"aaa"); TermPtr searchTerm2 = newLucene(L"content", L"bbb"); TermPtr searchTerm3 = newLucene(L"content", L"ccc"); - + // add 100 documents with term : aaa // add 100 documents with term : bbb // add 100 documents with term : ccc @@ -805,17 +861,17 @@ static void deleteReaderReaderConflict(bool optimize) // open two readers // both readers get segment info as exists at this time IndexReaderPtr reader1 = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm1)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm2)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm3)); + EXPECT_EQ(100, reader1->docFreq(searchTerm1)); + EXPECT_EQ(100, reader1->docFreq(searchTerm2)); + EXPECT_EQ(100, reader1->docFreq(searchTerm3)); checkTermDocsCount(reader1, searchTerm1, 100); checkTermDocsCount(reader1, searchTerm2, 100); checkTermDocsCount(reader1, searchTerm3, 100); IndexReaderPtr reader2 = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm1)); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm2)); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm3)); + EXPECT_EQ(100, reader2->docFreq(searchTerm1)); + EXPECT_EQ(100, reader2->docFreq(searchTerm2)); + EXPECT_EQ(100, reader2->docFreq(searchTerm3)); checkTermDocsCount(reader2, searchTerm1, 100); checkTermDocsCount(reader2, searchTerm2, 100); checkTermDocsCount(reader2, searchTerm3, 100); @@ -825,40 +881,47 @@ static void deleteReaderReaderConflict(bool optimize) // when the reader is closed, the segment info is updated and // the first reader is now stale reader2->deleteDocuments(searchTerm1); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm1)); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm2)); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm3)); + EXPECT_EQ(100, reader2->docFreq(searchTerm1)); + EXPECT_EQ(100, reader2->docFreq(searchTerm2)); + EXPECT_EQ(100, reader2->docFreq(searchTerm3)); checkTermDocsCount(reader2, searchTerm1, 0); checkTermDocsCount(reader2, searchTerm2, 100); checkTermDocsCount(reader2, searchTerm3, 100); reader2->close(); // Make sure reader 1 is unchanged since it was open earlier - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm1)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm2)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm3)); + EXPECT_EQ(100, reader1->docFreq(searchTerm1)); + EXPECT_EQ(100, reader1->docFreq(searchTerm2)); + EXPECT_EQ(100, reader1->docFreq(searchTerm3)); checkTermDocsCount(reader1, searchTerm1, 100); checkTermDocsCount(reader1, searchTerm2, 100); checkTermDocsCount(reader1, searchTerm3, 100); - + // attempt to delete from stale reader // delete documents containing term: bbb - BOOST_CHECK_EXCEPTION(reader1->deleteDocuments(searchTerm2), StaleReaderException, check_exception(LuceneException::StaleReader)); + try + { + reader1->deleteDocuments(searchTerm2); + } + catch (StaleReaderException& e) + { + EXPECT_TRUE(check_exception(LuceneException::StaleReader)(e)); + } // recreate reader and try again reader1->close(); reader1 = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm1)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm2)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm3)); + EXPECT_EQ(100, reader1->docFreq(searchTerm1)); + EXPECT_EQ(100, reader1->docFreq(searchTerm2)); + EXPECT_EQ(100, reader1->docFreq(searchTerm3)); checkTermDocsCount(reader1, searchTerm1, 0); checkTermDocsCount(reader1, searchTerm2, 100); checkTermDocsCount(reader1, searchTerm3, 100); reader1->deleteDocuments(searchTerm2); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm1)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm2)); - BOOST_CHECK_EQUAL(100, reader1->docFreq(searchTerm3)); + EXPECT_EQ(100, reader1->docFreq(searchTerm1)); + EXPECT_EQ(100, reader1->docFreq(searchTerm2)); + EXPECT_EQ(100, reader1->docFreq(searchTerm3)); checkTermDocsCount(reader1, searchTerm1, 0); checkTermDocsCount(reader1, searchTerm2, 0); checkTermDocsCount(reader1, searchTerm3, 100); @@ -866,9 +929,9 @@ static void deleteReaderReaderConflict(bool optimize) // Open another reader to confirm that everything is deleted reader2 = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm1)); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm2)); - BOOST_CHECK_EQUAL(100, reader2->docFreq(searchTerm3)); + EXPECT_EQ(100, reader2->docFreq(searchTerm1)); + EXPECT_EQ(100, reader2->docFreq(searchTerm2)); + EXPECT_EQ(100, reader2->docFreq(searchTerm3)); checkTermDocsCount(reader2, searchTerm1, 0); checkTermDocsCount(reader2, searchTerm2, 0); checkTermDocsCount(reader2, searchTerm3, 100); @@ -877,23 +940,23 @@ static void deleteReaderReaderConflict(bool optimize) dir->close(); } -BOOST_AUTO_TEST_CASE(testDeleteReaderReaderConflictUnoptimized) +TEST_F(IndexReaderTest, testDeleteReaderReaderConflictUnoptimized) { deleteReaderReaderConflict(false); } -BOOST_AUTO_TEST_CASE(testDeleteReaderReaderConflictOptimized) +TEST_F(IndexReaderTest, testDeleteReaderReaderConflictOptimized) { deleteReaderReaderConflict(true); } /// Make sure if reader tries to commit but hits disk full that reader remains consistent and usable. -BOOST_AUTO_TEST_CASE(testDiskFull) +TEST_F(IndexReaderTest, testDiskFull) { TermPtr searchTerm = newLucene(L"content", L"aaa"); int32_t START_COUNT = 157; int32_t END_COUNT = 144; - + // First build up a starting index RAMDirectoryPtr startDir = newLucene(); IndexWriterPtr writer = newLucene(startDir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -905,19 +968,19 @@ BOOST_AUTO_TEST_CASE(testDiskFull) writer->addDocument(doc); } writer->close(); - + int64_t diskUsage = startDir->sizeInBytes(); - int64_t diskFree = diskUsage + 100; + int64_t diskFree = diskUsage + 100; LuceneException err; bool done = false; - + // Iterate with ever increasing free disk space while (!done) { MockRAMDirectoryPtr dir = newLucene(startDir); - + // If IndexReader hits disk full, it can write to the same files again. dir->setPreventDoubleWrite(false); @@ -927,14 +990,14 @@ BOOST_AUTO_TEST_CASE(testDiskFull) // disk full; after, give it infinite disk space and turn off random IOExceptions and // retry with same reader bool success = false; - + for (int32_t x = 0; x < 2; ++x) { double rate = 0.05; double diskRatio = ((double)diskFree) / (double)diskUsage; int64_t thisDiskFree = 0; String testName; - + if (x == 0) { thisDiskFree = diskFree; @@ -952,10 +1015,10 @@ BOOST_AUTO_TEST_CASE(testDiskFull) rate = 0.0; testName = L"reader re-use after disk full"; } - + dir->setMaxSizeInBytes(thisDiskFree); dir->setRandomIOExceptionRate(rate, diskFree); - + try { if (x == 0) @@ -977,11 +1040,11 @@ BOOST_AUTO_TEST_CASE(testDiskFull) { err = e; if (x == 1) - BOOST_FAIL(testName << " hit IOException after disk space was freed up"); + FAIL() << testName << " hit IOException after disk space was freed up"; } - + // Whether we succeeded or failed, check that all un-referenced files were in fact deleted (ie, - // we did not create garbage). Just create a new IndexFileDeleter, have it delete unreferenced + // we did not create garbage). Just create a new IndexFileDeleter, have it delete unreferenced // files, then verify that in fact no files were deleted HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); @@ -994,51 +1057,51 @@ BOOST_AUTO_TEST_CASE(testDiskFull) std::sort(startFiles.begin(), startFiles.end()); std::sort(endFiles.begin(), endFiles.end()); - + if (!startFiles.equals(endFiles)) { String successStr = success ? L"success" : L"IOException"; - BOOST_FAIL("reader.close() failed to delete unreferenced files after " << successStr << " (" << diskFree << " bytes)"); + FAIL() << "reader.close() failed to delete unreferenced files after " << successStr << " (" << diskFree << " bytes)"; } - + // Finally, verify index is not corrupt, and, if we succeeded, we see all docs changed, and if // we failed, we see either all docs or no docs changed (transactional semantics) IndexReaderPtr newReader; - BOOST_CHECK_NO_THROW(newReader = IndexReader::open(dir, false)); - + EXPECT_NO_THROW(newReader = IndexReader::open(dir, false)); + IndexSearcherPtr searcher = newLucene(newReader); Collection hits; - BOOST_CHECK_NO_THROW(hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs); + EXPECT_NO_THROW(hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs); int32_t result2 = hits.size(); if (success) { if (result2 != END_COUNT) - BOOST_FAIL(testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT); + FAIL() << testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT; } else { // On hitting exception we still may have added all docs if (result2 != START_COUNT && result2 != END_COUNT) - BOOST_FAIL(testName << ": method did throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT); + FAIL() << testName << ": method did throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT; } - + searcher->close(); newReader->close(); if (result2 == END_COUNT) break; } - + dir->close(); - + // Try again with 10 more bytes of free space diskFree += 10; } - + startDir->close(); } -BOOST_AUTO_TEST_CASE(testDocsOutOfOrder) +TEST_F(IndexReaderTest, testDocsOutOfOrder) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1046,63 +1109,98 @@ BOOST_AUTO_TEST_CASE(testDocsOutOfOrder) addDoc(writer, L"aaa"); writer->close(); IndexReaderPtr reader = IndexReader::open(dir, false); - + // Try to delete an invalid docId, yet, within range of the final bits of the BitVector - BOOST_CHECK_EXCEPTION(reader->deleteDocument(11), IndexOutOfBoundsException, check_exception(LuceneException::IndexOutOfBounds)); - + try + { + reader->deleteDocument(11); + } + catch (IndexOutOfBoundsException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); + } + reader->close(); - + writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); - + // We must add more docs to get a new segment written for (int32_t i = 0; i < 11; ++i) addDoc(writer, L"aaa"); - - BOOST_CHECK_NO_THROW(writer->optimize()); + + EXPECT_NO_THROW(writer->optimize()); writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testExceptionReleaseWriteLock) +TEST_F(IndexReaderTest, testExceptionReleaseWriteLock) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(writer, L"aaa"); writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, false); - - BOOST_CHECK_EXCEPTION(reader->deleteDocument(1), IndexOutOfBoundsException, check_exception(LuceneException::IndexOutOfBounds)); - + + try + { + reader->deleteDocument(1); + } + catch (IndexOutOfBoundsException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); + } + reader->close(); - - BOOST_CHECK(!IndexWriter::isLocked(dir)); - + + EXPECT_TRUE(!IndexWriter::isLocked(dir)); + reader = IndexReader::open(dir, false); - - BOOST_CHECK_EXCEPTION(reader->setNorm(1, L"content", 2.0), IndexOutOfBoundsException, check_exception(LuceneException::IndexOutOfBounds)); - + + try + { + reader->setNorm(1, L"content", 2.0); + } + catch (IndexOutOfBoundsException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); + } + reader->close(); - - BOOST_CHECK(!IndexWriter::isLocked(dir)); - + + EXPECT_TRUE(!IndexWriter::isLocked(dir)); + dir->close(); } -BOOST_AUTO_TEST_CASE(testOpenReaderAfterDelete) +TEST_F(IndexReaderTest, testOpenReaderAfterDelete) { String indexDir(FileUtils::joinPath(getTempDir(), L"deletetest")); DirectoryPtr dir = FSDirectory::open(indexDir); - BOOST_CHECK_EXCEPTION(IndexReader::open(dir, false), NoSuchDirectoryException, check_exception(LuceneException::NoSuchDirectory)); - + try + { + IndexReader::open(dir, false); + } + catch (NoSuchDirectoryException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); + } + FileUtils::removeDirectory(indexDir); - - BOOST_CHECK_EXCEPTION(IndexReader::open(dir, false), NoSuchDirectoryException, check_exception(LuceneException::NoSuchDirectory)); - + + try + { + IndexReader::open(dir, false); + } + catch (NoSuchDirectoryException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); + } + dir->close(); } -BOOST_AUTO_TEST_CASE(testGetIndexCommit) +TEST_F(IndexReaderTest, testGetIndexCommit) { RAMDirectoryPtr d = newLucene(); // set up writer @@ -1117,9 +1215,9 @@ BOOST_AUTO_TEST_CASE(testGetIndexCommit) IndexReaderPtr r = IndexReader::open(d, false); IndexCommitPtr c = r->getIndexCommit(); - BOOST_CHECK_EQUAL(sis->getCurrentSegmentFileName(), c->getSegmentsFileName()); + EXPECT_EQ(sis->getCurrentSegmentFileName(), c->getSegmentsFileName()); - BOOST_CHECK(c->equals(r->getIndexCommit())); + EXPECT_TRUE(c->equals(r->getIndexCommit())); // Change the index writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); @@ -1129,8 +1227,8 @@ BOOST_AUTO_TEST_CASE(testGetIndexCommit) writer->close(); IndexReaderPtr r2 = r->reopen(); - BOOST_CHECK(!c->equals(r2->getIndexCommit())); - BOOST_CHECK(!r2->getIndexCommit()->isOptimized()); + EXPECT_TRUE(!c->equals(r2->getIndexCommit())); + EXPECT_TRUE(!r2->getIndexCommit()->isOptimized()); r2->close(); writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); @@ -1138,14 +1236,14 @@ BOOST_AUTO_TEST_CASE(testGetIndexCommit) writer->close(); r2 = r->reopen(); - BOOST_CHECK(r2->getIndexCommit()->isOptimized()); + EXPECT_TRUE(r2->getIndexCommit()->isOptimized()); r->close(); r2->close(); d->close(); } -BOOST_AUTO_TEST_CASE(testReadOnly) +TEST_F(IndexReaderTest, testReadOnly) { RAMDirectoryPtr d = newLucene(); IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1155,30 +1253,51 @@ BOOST_AUTO_TEST_CASE(testReadOnly) writer->close(); IndexReaderPtr r = IndexReader::open(d, true); - BOOST_CHECK_EXCEPTION(r->deleteDocument(0), UnsupportedOperationException, check_exception(LuceneException::UnsupportedOperation)); - + try + { + r->deleteDocument(0); + } + catch (UnsupportedOperationException& e) + { + EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); + } + writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); writer->close(); - + // Make sure reopen is still readonly IndexReaderPtr r2 = r->reopen(); r->close(); - BOOST_CHECK_NE(r, r2); - BOOST_CHECK_EXCEPTION(r2->deleteDocument(0), UnsupportedOperationException, check_exception(LuceneException::UnsupportedOperation)); - + EXPECT_NE(r, r2); + try + { + r2->deleteDocument(0); + } + catch (UnsupportedOperationException& e) + { + EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); + } + writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); writer->optimize(); writer->close(); - + // Make sure reopen to a single segment is still readonly IndexReaderPtr r3 = r2->reopen(); r2->close(); - BOOST_CHECK_NE(r, r2); - BOOST_CHECK_EXCEPTION(r3->deleteDocument(0), UnsupportedOperationException, check_exception(LuceneException::UnsupportedOperation)); - + EXPECT_NE(r, r2); + try + { + r3->deleteDocument(0); + } + catch (UnsupportedOperationException& e) + { + EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); + } + // Make sure write lock isn't held writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); writer->close(); @@ -1186,7 +1305,7 @@ BOOST_AUTO_TEST_CASE(testReadOnly) r3->close(); } -BOOST_AUTO_TEST_CASE(testIndexReader) +TEST_F(IndexReaderTest, testIndexReader) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthUNLIMITED); @@ -1202,7 +1321,7 @@ BOOST_AUTO_TEST_CASE(testIndexReader) IndexReader::open(dir, true)->close(); } -BOOST_AUTO_TEST_CASE(testIndexReaderUnDeleteAll) +TEST_F(IndexReaderTest, testIndexReaderUnDeleteAll) { MockRAMDirectoryPtr dir = newLucene(); dir->setPreventDoubleWrite(false); @@ -1223,15 +1342,22 @@ BOOST_AUTO_TEST_CASE(testIndexReaderUnDeleteAll) } /// Make sure on attempting to open an IndexReader on a non-existent directory, you get a good exception -BOOST_AUTO_TEST_CASE(testNoDir) +TEST_F(IndexReaderTest, testNoDir) { String indexDir(FileUtils::joinPath(getTempDir(), L"doesnotexist")); DirectoryPtr dir = FSDirectory::open(indexDir); - BOOST_CHECK_EXCEPTION(IndexReader::open(dir, true), NoSuchDirectoryException, check_exception(LuceneException::NoSuchDirectory)); + try + { + IndexReader::open(dir, true); + } + catch (NoSuchDirectoryException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); + } dir->close(); } -BOOST_AUTO_TEST_CASE(testNoDupCommitFileNames) +TEST_F(IndexReaderTest, testNoDupCommitFileNames) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -1240,7 +1366,7 @@ BOOST_AUTO_TEST_CASE(testNoDupCommitFileNames) writer->addDocument(createDocument(L"a")); writer->addDocument(createDocument(L"a")); writer->close(); - + Collection commits = IndexReader::listCommits(dir); for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { @@ -1248,16 +1374,16 @@ BOOST_AUTO_TEST_CASE(testNoDupCommitFileNames) HashSet seen = HashSet::newInstance(); for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { - BOOST_CHECK(!seen.contains(*fileName)); + EXPECT_TRUE(!seen.contains(*fileName)); seen.add(*fileName); } } - + dir->close(); } /// Ensure that on a cloned reader, segments reuse the doc values arrays in FieldCache -BOOST_AUTO_TEST_CASE(testFieldCacheReuseAfterClone) +TEST_F(IndexReaderTest, testFieldCacheReuseAfterClone) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -1269,25 +1395,25 @@ BOOST_AUTO_TEST_CASE(testFieldCacheReuseAfterClone) // Open reader IndexReaderPtr r = SegmentReader::getOnlySegmentReader(dir); Collection ints = FieldCache::DEFAULT()->getInts(r, L"number"); - BOOST_CHECK_EQUAL(1, ints.size()); - BOOST_CHECK_EQUAL(17, ints[0]); + EXPECT_EQ(1, ints.size()); + EXPECT_EQ(17, ints[0]); // Clone reader IndexReaderPtr r2 = boost::dynamic_pointer_cast(r->clone()); r->close(); - BOOST_CHECK_NE(r2, r); + EXPECT_NE(r2, r); Collection ints2 = FieldCache::DEFAULT()->getInts(r2, L"number"); r2->close(); - BOOST_CHECK_EQUAL(1, ints2.size()); - BOOST_CHECK_EQUAL(17, ints2[0]); - BOOST_CHECK(ints.equals(ints2)); + EXPECT_EQ(1, ints2.size()); + EXPECT_EQ(17, ints2[0]); + EXPECT_TRUE(ints.equals(ints2)); dir->close(); } /// Ensure that on a reopened reader, that any shared segments reuse the doc values arrays in FieldCache -BOOST_AUTO_TEST_CASE(testFieldCacheReuseAfterReopen) +TEST_F(IndexReaderTest, testFieldCacheReuseAfterReopen) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -1295,13 +1421,13 @@ BOOST_AUTO_TEST_CASE(testFieldCacheReuseAfterReopen) doc->add(newLucene(L"number", L"17", Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); writer->commit(); - + // Open reader1 IndexReaderPtr r = IndexReader::open(dir, false); IndexReaderPtr r1 = SegmentReader::getOnlySegmentReader(r); Collection ints = FieldCache::DEFAULT()->getInts(r1, L"number"); - BOOST_CHECK_EQUAL(1, ints.size()); - BOOST_CHECK_EQUAL(17, ints[0]); + EXPECT_EQ(1, ints.size()); + EXPECT_EQ(17, ints[0]); // Add new segment writer->addDocument(doc); @@ -1313,13 +1439,13 @@ BOOST_AUTO_TEST_CASE(testFieldCacheReuseAfterReopen) IndexReaderPtr sub0 = r2->getSequentialSubReaders()[0]; Collection ints2 = FieldCache::DEFAULT()->getInts(sub0, L"number"); r2->close(); - BOOST_CHECK(ints.equals(ints2)); + EXPECT_TRUE(ints.equals(ints2)); dir->close(); } /// Make sure all SegmentReaders are new when reopen switches readOnly -BOOST_AUTO_TEST_CASE(testReopenChangeReadonly) +TEST_F(IndexReaderTest, testReopenChangeReadonly) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -1327,18 +1453,18 @@ BOOST_AUTO_TEST_CASE(testReopenChangeReadonly) doc->add(newLucene(L"number", L"17", Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); writer->commit(); - + // Open reader1 IndexReaderPtr r = IndexReader::open(dir, false); - BOOST_CHECK(boost::dynamic_pointer_cast(r)); + EXPECT_TRUE(boost::dynamic_pointer_cast(r)); IndexReaderPtr r1 = SegmentReader::getOnlySegmentReader(r); Collection ints = FieldCache::DEFAULT()->getInts(r1, L"number"); - BOOST_CHECK_EQUAL(1, ints.size()); - BOOST_CHECK_EQUAL(17, ints[0]); + EXPECT_EQ(1, ints.size()); + EXPECT_EQ(17, ints[0]); // Reopen to readonly with no chnages IndexReaderPtr r3 = r->reopen(true); - BOOST_CHECK(boost::dynamic_pointer_cast(r3)); + EXPECT_TRUE(boost::dynamic_pointer_cast(r3)); r3->close(); // Add new segment @@ -1348,19 +1474,19 @@ BOOST_AUTO_TEST_CASE(testReopenChangeReadonly) // Reopen reader1 --> reader2 IndexReaderPtr r2 = r->reopen(true); r->close(); - BOOST_CHECK(boost::dynamic_pointer_cast(r2)); + EXPECT_TRUE(boost::dynamic_pointer_cast(r2)); Collection subs = r2->getSequentialSubReaders(); Collection ints2 = FieldCache::DEFAULT()->getInts(subs[0], L"number"); r2->close(); - BOOST_CHECK(boost::dynamic_pointer_cast(subs[0])); - BOOST_CHECK(boost::dynamic_pointer_cast(subs[1])); - BOOST_CHECK(ints.equals(ints2)); + EXPECT_TRUE(boost::dynamic_pointer_cast(subs[0])); + EXPECT_TRUE(boost::dynamic_pointer_cast(subs[1])); + EXPECT_TRUE(ints.equals(ints2)); dir->close(); } -BOOST_AUTO_TEST_CASE(testUniqueTermCount) +TEST_F(IndexReaderTest, testUniqueTermCount) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -1370,25 +1496,32 @@ BOOST_AUTO_TEST_CASE(testUniqueTermCount) writer->addDocument(doc); writer->addDocument(doc); writer->commit(); - + IndexReaderPtr r = IndexReader::open(dir, false); IndexReaderPtr r1 = SegmentReader::getOnlySegmentReader(r); - BOOST_CHECK_EQUAL(36, r1->getUniqueTermCount()); + EXPECT_EQ(36, r1->getUniqueTermCount()); writer->addDocument(doc); writer->commit(); IndexReaderPtr r2 = r->reopen(); r->close(); - BOOST_CHECK_EXCEPTION(r2->getUniqueTermCount(), UnsupportedOperationException, check_exception(LuceneException::UnsupportedOperation)); + try + { + r2->getUniqueTermCount(); + } + catch (UnsupportedOperationException& e) + { + EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); + } Collection subs = r2->getSequentialSubReaders(); for (Collection::iterator sub = subs.begin(); sub != subs.end(); ++sub) - BOOST_CHECK_EQUAL(36, (*sub)->getUniqueTermCount()); + EXPECT_EQ(36, (*sub)->getUniqueTermCount()); r2->close(); writer->close(); dir->close(); } /// don't load terms index -BOOST_AUTO_TEST_CASE(testNoTermsIndex) +TEST_F(IndexReaderTest, testNoTermsIndex) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -1398,11 +1531,18 @@ BOOST_AUTO_TEST_CASE(testNoTermsIndex) writer->addDocument(doc); writer->addDocument(doc); writer->close(); - + IndexReaderPtr r = IndexReader::open(dir, IndexDeletionPolicyPtr(), true, -1); - BOOST_CHECK_EXCEPTION(r->docFreq(newLucene(L"field", L"f")), IllegalStateException, check_exception(LuceneException::IllegalState)); - BOOST_CHECK(!boost::dynamic_pointer_cast(r->getSequentialSubReaders()[0])->termsIndexLoaded()); - BOOST_CHECK_EQUAL(-1, boost::dynamic_pointer_cast(r->getSequentialSubReaders()[0])->getTermInfosIndexDivisor()); + try + { + r->docFreq(newLucene(L"field", L"f")); + } + catch (IllegalStateException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); + } + EXPECT_TRUE(!boost::dynamic_pointer_cast(r->getSequentialSubReaders()[0])->termsIndexLoaded()); + EXPECT_EQ(-1, boost::dynamic_pointer_cast(r->getSequentialSubReaders()[0])->getTermInfosIndexDivisor()); writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); writer->addDocument(doc); writer->close(); @@ -1411,34 +1551,32 @@ BOOST_AUTO_TEST_CASE(testNoTermsIndex) IndexReaderPtr r2 = r->reopen(); r->close(); Collection subReaders = r2->getSequentialSubReaders(); - BOOST_CHECK_EQUAL(2, subReaders.size()); + EXPECT_EQ(2, subReaders.size()); for (Collection::iterator sub = subReaders.begin(); sub != subReaders.end(); ++sub) { SegmentReaderPtr subReader = boost::dynamic_pointer_cast(*sub); - BOOST_CHECK(!subReader->termsIndexLoaded()); + EXPECT_TRUE(!subReader->termsIndexLoaded()); } r2->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testPrepareCommitIsCurrent) +TEST_F(IndexReaderTest, testPrepareCommitIsCurrent) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); writer->addDocument(doc); IndexReaderPtr r = IndexReader::open(dir, true); - BOOST_CHECK(r->isCurrent()); + EXPECT_TRUE(r->isCurrent()); writer->addDocument(doc); writer->prepareCommit(); - BOOST_CHECK(r->isCurrent()); + EXPECT_TRUE(r->isCurrent()); IndexReaderPtr r2 = r->reopen(); - BOOST_CHECK(r == r2); + EXPECT_TRUE(r == r2); writer->commit(); - BOOST_CHECK(!r->isCurrent()); + EXPECT_TRUE(!r->isCurrent()); writer->close(); r->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexWriterDeleteTest.cpp b/src/test/index/IndexWriterDeleteTest.cpp index 676256bc..8e02d98d 100644 --- a/src/test/index/IndexWriterDeleteTest.cpp +++ b/src/test/index/IndexWriterDeleteTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexWriterDeleteTest, LuceneTestFixture) +typedef LuceneTestFixture IndexWriterDeleteTest; DECLARE_SHARED_PTR(FailOnlyOnDeleteFlush) @@ -35,7 +35,7 @@ class FailOnlyOnDeleteFlush : public MockDirectoryFailure sawMaybe = false; failed = false; } - + virtual ~FailOnlyOnDeleteFlush() { } @@ -51,7 +51,7 @@ class FailOnlyOnDeleteFlush : public MockDirectoryFailure failed = false; return shared_from_this(); } - + virtual void eval(MockRAMDirectoryPtr dir) { if (sawMaybe && !failed) @@ -80,7 +80,7 @@ class FailOnlyOnAdd : public MockDirectoryFailure { failed = false; } - + virtual ~FailOnlyOnAdd() { } @@ -94,7 +94,7 @@ class FailOnlyOnAdd : public MockDirectoryFailure failed = false; return shared_from_this(); } - + virtual void eval(MockRAMDirectoryPtr dir) { if (!failed) @@ -138,29 +138,29 @@ static void checkNoUnreferencedFiles(DirectoryPtr dir) infos->read(dir); IndexFileDeleterPtr deleter = newLucene(dir, newLucene(), infos, InfoStreamPtr(), DocumentsWriterPtr(), HashSet()); HashSet _endFiles = dir->listAll(); - + Collection startFiles = Collection::newInstance(_startFiles.begin(), _startFiles.end()); Collection endFiles = Collection::newInstance(_endFiles.begin(), _endFiles.end()); - + std::sort(startFiles.begin(), startFiles.end()); std::sort(endFiles.begin(), endFiles.end()); - - BOOST_CHECK(startFiles.equals(endFiles)); + + EXPECT_TRUE(startFiles.equals(endFiles)); } -BOOST_AUTO_TEST_CASE(testSimpleCase) +TEST_F(IndexWriterDeleteTest, testSimpleCase) { Collection keywords = newCollection(L"1", L"2"); Collection unindexed = newCollection(L"Netherlands", L"Italy"); Collection unstored = newCollection(L"Amsterdam has lots of bridges", L"Venice has lots of canals"); Collection text = newCollection(L"Amsterdam", L"Venice"); - + DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + modifier->setUseCompoundFile(true); modifier->setMaxBufferedDeleteTerms(1); - + for (int32_t i = 0; i < keywords.size(); ++i) { DocumentPtr doc = newLucene(); @@ -175,39 +175,39 @@ BOOST_AUTO_TEST_CASE(testSimpleCase) TermPtr term = newLucene(L"city", L"Amsterdam"); int32_t hitCount = getHitCount(dir, term); - BOOST_CHECK_EQUAL(1, hitCount); + EXPECT_EQ(1, hitCount); modifier->deleteDocuments(term); modifier->commit(); hitCount = getHitCount(dir, term); - BOOST_CHECK_EQUAL(0, hitCount); + EXPECT_EQ(0, hitCount); modifier->close(); dir->close(); } /// test when delete terms only apply to disk segments -BOOST_AUTO_TEST_CASE(testNonRAMDelete) +TEST_F(IndexWriterDeleteTest, testNonRAMDelete) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + modifier->setMaxBufferedDocs(2); modifier->setMaxBufferedDeleteTerms(2); int32_t id = 0; int32_t value = 100; - + for (int32_t i = 0; i < 7; ++i) addDoc(modifier, ++id, value); modifier->commit(); - BOOST_CHECK_EQUAL(0, modifier->getNumBufferedDocuments()); - BOOST_CHECK(0 < modifier->getSegmentCount()); + EXPECT_EQ(0, modifier->getNumBufferedDocuments()); + EXPECT_TRUE(0 < modifier->getSegmentCount()); modifier->commit(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); modifier->deleteDocuments(newLucene(L"value", StringUtils::toString(value))); @@ -215,13 +215,13 @@ BOOST_AUTO_TEST_CASE(testNonRAMDelete) modifier->commit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); modifier->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testMaxBufferedDeletes) +TEST_F(IndexWriterDeleteTest, testMaxBufferedDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -229,19 +229,19 @@ BOOST_AUTO_TEST_CASE(testMaxBufferedDeletes) writer->deleteDocuments(newLucene(L"foobar", L"1")); writer->deleteDocuments(newLucene(L"foobar", L"1")); writer->deleteDocuments(newLucene(L"foobar", L"1")); - BOOST_CHECK_EQUAL(3, writer->getFlushDeletesCount()); + EXPECT_EQ(3, writer->getFlushDeletesCount()); writer->close(); dir->close(); } /// test when delete terms only apply to ram segments -BOOST_AUTO_TEST_CASE(testRAMDeletes) +TEST_F(IndexWriterDeleteTest, testRAMDeletes) { for (int32_t t = 0; t < 2; ++t) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + modifier->setMaxBufferedDocs(4); modifier->setMaxBufferedDeleteTerms(4); @@ -257,23 +257,23 @@ BOOST_AUTO_TEST_CASE(testRAMDeletes) if (t == 0) { modifier->deleteDocuments(newLucene(L"value", StringUtils::toString(value))); - BOOST_CHECK_EQUAL(2, modifier->getNumBufferedDeleteTerms()); - BOOST_CHECK_EQUAL(1, modifier->getBufferedDeleteTermsSize()); + EXPECT_EQ(2, modifier->getNumBufferedDeleteTerms()); + EXPECT_EQ(1, modifier->getBufferedDeleteTermsSize()); } else modifier->deleteDocuments(newLucene(newLucene(L"value", StringUtils::toString(value)))); addDoc(modifier, ++id, value); - BOOST_CHECK_EQUAL(0, modifier->getSegmentCount()); + EXPECT_EQ(0, modifier->getSegmentCount()); modifier->commit(); modifier->commit(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->numDocs()); int32_t hitCount = getHitCount(dir, newLucene(L"id", StringUtils::toString(id))); - BOOST_CHECK_EQUAL(1, hitCount); + EXPECT_EQ(1, hitCount); reader->close(); modifier->close(); dir->close(); @@ -281,7 +281,7 @@ BOOST_AUTO_TEST_CASE(testRAMDeletes) } /// test when delete terms apply to both disk and ram segments -BOOST_AUTO_TEST_CASE(testBothDeletes) +TEST_F(IndexWriterDeleteTest, testBothDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -293,32 +293,32 @@ BOOST_AUTO_TEST_CASE(testBothDeletes) int32_t value = 100; for (int32_t i = 0; i < 5; ++i) addDoc(modifier, ++id, value); - + value = 200; for (int32_t i = 0; i < 5; ++i) addDoc(modifier, ++id, value); - + modifier->commit(); - + for (int32_t i = 0; i < 5; ++i) addDoc(modifier, ++id, value); - + modifier->deleteDocuments(newLucene(L"value", StringUtils::toString(value))); modifier->commit(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(5, reader->numDocs()); + EXPECT_EQ(5, reader->numDocs()); modifier->close(); reader->close(); } /// test that batched delete terms are flushed together -BOOST_AUTO_TEST_CASE(testBatchDeletes) +TEST_F(IndexWriterDeleteTest, testBatchDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + modifier->setMaxBufferedDocs(100); modifier->setMaxBufferedDeleteTerms(100); @@ -327,21 +327,21 @@ BOOST_AUTO_TEST_CASE(testBatchDeletes) for (int32_t i = 0; i < 7; ++i) addDoc(modifier, ++id, value); modifier->commit(); - + IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); - + id = 0; modifier->deleteDocuments(newLucene(L"id", StringUtils::toString(++id))); modifier->deleteDocuments(newLucene(L"id", StringUtils::toString(++id))); - + modifier->commit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(5, reader->numDocs()); + EXPECT_EQ(5, reader->numDocs()); reader->close(); - + Collection terms = Collection::newInstance(3); for (int32_t i = 0; i < terms.size(); ++i) terms[i] = newLucene(L"id", StringUtils::toString(++id)); @@ -349,18 +349,18 @@ BOOST_AUTO_TEST_CASE(testBatchDeletes) modifier->deleteDocuments(terms); modifier->commit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); reader->close(); modifier->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDeleteAll) +TEST_F(IndexWriterDeleteTest, testDeleteAll) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + modifier->setMaxBufferedDocs(2); modifier->setMaxBufferedDeleteTerms(2); @@ -371,7 +371,7 @@ BOOST_AUTO_TEST_CASE(testDeleteAll) modifier->commit(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); // Add 1 doc (so we will have something buffered) @@ -382,7 +382,7 @@ BOOST_AUTO_TEST_CASE(testDeleteAll) // Delete all shouldn't be on disk yet reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); // Add a doc and update a doc (after the deleteAll, before the commit) @@ -394,18 +394,18 @@ BOOST_AUTO_TEST_CASE(testDeleteAll) // Validate there are no docs left reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); reader->close(); modifier->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDeleteAllRollback) +TEST_F(IndexWriterDeleteTest, testDeleteAllRollback) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + modifier->setMaxBufferedDocs(2); modifier->setMaxBufferedDeleteTerms(2); @@ -418,7 +418,7 @@ BOOST_AUTO_TEST_CASE(testDeleteAllRollback) addDoc(modifier, 99, value); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); // Delete all @@ -430,18 +430,18 @@ BOOST_AUTO_TEST_CASE(testDeleteAllRollback) // Validate that the docs are still there reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); dir->close(); } /// test deleteAll() with near real-time reader -BOOST_AUTO_TEST_CASE(testDeleteAllNRT) +TEST_F(IndexWriterDeleteTest, testDeleteAllNRT) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + modifier->setMaxBufferedDocs(2); modifier->setMaxBufferedDeleteTerms(2); @@ -452,17 +452,17 @@ BOOST_AUTO_TEST_CASE(testDeleteAllNRT) modifier->commit(); IndexReaderPtr reader = modifier->getReader(); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); addDoc(modifier, ++id, value); addDoc(modifier, ++id, value); // Delete all - modifier->deleteAll(); + modifier->deleteAll(); reader = modifier->getReader(); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); // Roll it back @@ -471,20 +471,20 @@ BOOST_AUTO_TEST_CASE(testDeleteAllNRT) // Validate that the docs are still there reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(7, reader->numDocs()); + EXPECT_EQ(7, reader->numDocs()); reader->close(); dir->close(); } /// Make sure if modifier tries to commit but hits disk full that modifier -/// remains consistent and usable. +/// remains consistent and usable. static void testOperationsOnDiskFull(bool updates) { TermPtr searchTerm = newLucene(L"content", L"aaa"); int32_t START_COUNT = 157; int32_t END_COUNT = 144; - + // First build up a starting index RAMDirectoryPtr startDir = newLucene(); IndexWriterPtr writer = newLucene(startDir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -496,19 +496,19 @@ static void testOperationsOnDiskFull(bool updates) writer->addDocument(doc); } writer->close(); - + int64_t diskUsage = startDir->sizeInBytes(); int64_t diskFree = diskUsage + 10; LuceneException err; bool done = false; - + // Iterate with ever increasing free disk space while (!done) { MockRAMDirectoryPtr dir = newLucene(startDir); - + // If IndexReader hits disk full, it can write to the same files again. dir->setPreventDoubleWrite(false); @@ -521,14 +521,14 @@ static void testOperationsOnDiskFull(bool updates) // disk full; after, give it infinite disk space and turn off random IOExceptions and // retry with same reader bool success = false; - + for (int32_t x = 0; x < 2; ++x) { double rate = 0.1; double diskRatio = ((double)diskFree) / (double)diskUsage; int64_t thisDiskFree = 0; String testName; - + if (x == 0) { thisDiskFree = diskFree; @@ -546,10 +546,10 @@ static void testOperationsOnDiskFull(bool updates) rate = 0.0; testName = L"reader re-use after disk full"; } - + dir->setMaxSizeInBytes(thisDiskFree); dir->setRandomIOExceptionRate(rate, diskFree); - + try { if (x == 0) @@ -578,9 +578,9 @@ static void testOperationsOnDiskFull(bool updates) { err = e; if (x == 1) - BOOST_FAIL(testName << " hit IOException after disk space was freed up"); + FAIL() << testName << " hit IOException after disk space was freed up"; } - + // If the close() succeeded, make sure there are no unreferenced files. if (success) { @@ -591,82 +591,82 @@ static void testOperationsOnDiskFull(bool updates) // Finally, verify index is not corrupt, and, if we succeeded, we see all docs changed, and if // we failed, we see either all docs or no docs changed (transactional semantics): IndexReaderPtr newReader; - + try { newReader = IndexReader::open(dir, true); } catch (IOException& e) { - BOOST_FAIL(testName << ":exception when creating IndexReader after disk full during close:" << e.getError()); + FAIL() << testName << ":exception when creating IndexReader after disk full during close:" << e.getError(); } - + IndexSearcherPtr searcher = newLucene(newReader); Collection hits; - BOOST_CHECK_NO_THROW(hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs); + EXPECT_NO_THROW(hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs); int32_t result2 = hits.size(); if (success) { if (x == 0 && result2 != END_COUNT) - BOOST_FAIL(testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT); + FAIL() << testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT; else if (x == 1 && result2 != START_COUNT && result2 != END_COUNT) { // It's possible that the first exception was "recoverable" wrt pending deletes, in which // case the pending deletes are retained and then re-flushing (with plenty of disk space) // will succeed in flushing the deletes - BOOST_FAIL(testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << START_COUNT << " or " << END_COUNT); + FAIL() << testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << START_COUNT << " or " << END_COUNT; } } else { // On hitting exception we still may have added all docs if (result2 != START_COUNT && result2 != END_COUNT) - BOOST_FAIL(testName << ": method did throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << START_COUNT << " or " << END_COUNT); + FAIL() << testName << ": method did throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << START_COUNT << " or " << END_COUNT; } - + searcher->close(); newReader->close(); if (result2 == END_COUNT) break; } - + dir->close(); - + // Try again with 10 more bytes of free space diskFree += 10; } - + startDir->close(); } -BOOST_AUTO_TEST_CASE(testDeletesOnDiskFull) +TEST_F(IndexWriterDeleteTest, testDeletesOnDiskFull) { testOperationsOnDiskFull(false); } -BOOST_AUTO_TEST_CASE(testUpdatesOnDiskFull) +TEST_F(IndexWriterDeleteTest, testUpdatesOnDiskFull) { testOperationsOnDiskFull(true); } /// This test tests that buffered deletes are cleared when an Exception is hit during flush. -BOOST_AUTO_TEST_CASE(testErrorAfterApplyDeletes) +TEST_F(IndexWriterDeleteTest, testErrorAfterApplyDeletes) { Collection keywords = newCollection(L"1", L"2"); Collection unindexed = newCollection(L"Netherlands", L"Italy"); Collection unstored = newCollection(L"Amsterdam has lots of bridges", L"Venice has lots of canals"); Collection text = newCollection(L"Amsterdam", L"Venice"); - + MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); modifier->setUseCompoundFile(true); modifier->setMaxBufferedDeleteTerms(2); - + FailOnlyOnDeleteFlushPtr failure = newLucene(); dir->failOn(failure->reset()); - + for (int32_t i = 0; i < keywords.size(); ++i) { DocumentPtr doc = newLucene(); @@ -676,59 +676,66 @@ BOOST_AUTO_TEST_CASE(testErrorAfterApplyDeletes) doc->add(newLucene(L"city", text[i], Field::STORE_YES, Field::INDEX_ANALYZED)); modifier->addDocument(doc); } - + modifier->optimize(); modifier->commit(); TermPtr term = newLucene(L"city", L"Amsterdam"); int32_t hitCount = getHitCount(dir, term); - BOOST_CHECK_EQUAL(1, hitCount); - + EXPECT_EQ(1, hitCount); + modifier->deleteDocuments(term); - + DocumentPtr doc = newLucene(); modifier->addDocument(doc); - - // The failure object will fail on the first write after the del file gets created when + + // The failure object will fail on the first write after the del file gets created when // processing the buffered delete - - // In the ac case, this will be when writing the new segments files so we really don't + + // In the ac case, this will be when writing the new segments files so we really don't // need the new doc, but it's harmless - // In the !ac case, a new segments file won't be created but in this case, creation of - // the cfs file happens next so we need the doc (to test that it's okay that we don't + // In the !ac case, a new segments file won't be created but in this case, creation of + // the cfs file happens next so we need the doc (to test that it's okay that we don't // lose deletes if failing while creating the cfs file) - - BOOST_CHECK_EXCEPTION(modifier->commit(), IOException, check_exception(LuceneException::IO)); - - // The commit above failed, so we need to retry it (which will succeed, because the + + try + { + modifier->commit(); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + + // The commit above failed, so we need to retry it (which will succeed, because the // failure is a one-shot) - + modifier->commit(); hitCount = getHitCount(dir, term); - + // Make sure the delete was successfully flushed - BOOST_CHECK_EQUAL(0, hitCount); + EXPECT_EQ(0, hitCount); modifier->close(); dir->close(); } -/// This test tests that the files created by the docs writer before a segment is written are +/// This test tests that the files created by the docs writer before a segment is written are /// cleaned up if there's an i/o error -BOOST_AUTO_TEST_CASE(testErrorInDocsWriterAdd) +TEST_F(IndexWriterDeleteTest, testErrorInDocsWriterAdd) { Collection keywords = newCollection(L"1", L"2"); Collection unindexed = newCollection(L"Netherlands", L"Italy"); Collection unstored = newCollection(L"Amsterdam has lots of bridges", L"Venice has lots of canals"); Collection text = newCollection(L"Amsterdam", L"Venice"); - + MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); FailOnlyOnAddPtr failure = newLucene(); dir->failOn(failure->reset()); - + for (int32_t i = 0; i < keywords.size(); ++i) { DocumentPtr doc = newLucene(); @@ -736,7 +743,7 @@ BOOST_AUTO_TEST_CASE(testErrorInDocsWriterAdd) doc->add(newLucene(L"country", unindexed[i], Field::STORE_YES, Field::INDEX_NO)); doc->add(newLucene(L"contents", unstored[i], Field::STORE_NO, Field::INDEX_ANALYZED)); doc->add(newLucene(L"city", text[i], Field::STORE_YES, Field::INDEX_ANALYZED)); - + try { modifier->addDocument(doc); @@ -746,11 +753,9 @@ BOOST_AUTO_TEST_CASE(testErrorInDocsWriterAdd) break; } } - + checkNoUnreferencedFiles(dir); modifier->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexWriterExceptionsTest.cpp b/src/test/index/IndexWriterExceptionsTest.cpp index 3910dd5c..2cbb003d 100644 --- a/src/test/index/IndexWriterExceptionsTest.cpp +++ b/src/test/index/IndexWriterExceptionsTest.cpp @@ -22,19 +22,19 @@ using namespace Lucene; -class IndexWriterExceptionsTestFixture : public LuceneTestFixture +class IndexWriterExceptionsTest : public LuceneTestFixture { public: - IndexWriterExceptionsTestFixture() + IndexWriterExceptionsTest() { random = newLucene(); tvSettings = newCollection( - Field::TERM_VECTOR_NO, Field::TERM_VECTOR_YES, Field::TERM_VECTOR_WITH_OFFSETS, - Field::TERM_VECTOR_WITH_POSITIONS, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS + Field::TERM_VECTOR_NO, Field::TERM_VECTOR_YES, Field::TERM_VECTOR_WITH_OFFSETS, + Field::TERM_VECTOR_WITH_POSITIONS, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS ); } - - virtual ~IndexWriterExceptionsTestFixture() + + virtual ~IndexWriterExceptionsTest() { } @@ -49,31 +49,29 @@ class IndexWriterExceptionsTestFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(IndexWriterExceptionsTest, IndexWriterExceptionsTestFixture) - static CloseableThreadLocal doFail; -DECLARE_SHARED_PTR(IndexerThread) +DECLARE_SHARED_PTR(ExceptionsIndexerThread) -class IndexerThread : public LuceneThread +class ExceptionsIndexerThread : public LuceneThread { public: - IndexerThread(IndexWriterPtr writer, IndexWriterExceptionsTestFixture* fixture) + ExceptionsIndexerThread(IndexWriterPtr writer, IndexWriterExceptionsTest* fixture) { this->writer = writer; this->fixture = fixture; this->r = newLucene(47); } - - virtual ~IndexerThread() + + virtual ~ExceptionsIndexerThread() { } - - LUCENE_CLASS(IndexerThread); - + + LUCENE_CLASS(ExceptionsIndexerThread); + public: IndexWriterPtr writer; - IndexWriterExceptionsTestFixture* fixture; + IndexWriterExceptionsTest* fixture; LuceneException failure; RandomPtr r; @@ -85,17 +83,17 @@ class IndexerThread : public LuceneThread doc->add(newLucene(L"content6", L"aaa bbb ccc ddd", Field::STORE_NO, Field::INDEX_ANALYZED, fixture->randomTVSetting())); doc->add(newLucene(L"content2", L"aaa bbb ccc ddd", Field::STORE_YES, Field::INDEX_NOT_ANALYZED, fixture->randomTVSetting())); doc->add(newLucene(L"content3", L"aaa bbb ccc ddd", Field::STORE_YES, Field::INDEX_NO)); - + doc->add(newLucene(L"content4", L"aaa bbb ccc ddd", Field::STORE_NO, Field::INDEX_ANALYZED, fixture->randomTVSetting())); doc->add(newLucene(L"content5", L"aaa bbb ccc ddd", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, fixture->randomTVSetting())); - + doc->add(newLucene(L"content7", L"aaa bbb ccc ddd", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, fixture->randomTVSetting())); - + FieldPtr idField = newLucene(L"id", L"", Field::STORE_YES, Field::INDEX_NOT_ANALYZED, fixture->randomTVSetting()); doc->add(idField); - + int64_t stopTime = MiscUtils::currentTimeMillis() + 3000; - + while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) { doFail.set(shared_from_this()); @@ -123,10 +121,10 @@ class IndexerThread : public LuceneThread failure = e; break; } - + doFail.set(LuceneThreadPtr()); - - // After a possible exception (above) I should be able to add a new document + + // After a possible exception (above) I should be able to add a new document // without hitting an exception try { @@ -148,7 +146,7 @@ class MockIndexWriter : public IndexWriter { this->r = newLucene(17); } - + virtual ~MockIndexWriter() { } @@ -165,22 +163,22 @@ class MockIndexWriter : public IndexWriter } }; -BOOST_AUTO_TEST_CASE(testRandomExceptions) +TEST_F(IndexWriterExceptionsTest, testRandomExceptions) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); boost::dynamic_pointer_cast(writer->getMergeScheduler())->setSuppressExceptions(); - + writer->setRAMBufferSizeMB(0.1); - - IndexerThreadPtr thread = newLucene(writer, this); + + ExceptionsIndexerThreadPtr thread = newLucene(writer, this); thread->run(); - + if (!thread->failure.isNull()) - BOOST_FAIL("thread hit unexpected failure"); - + FAIL() << "thread hit unexpected failure"; + writer->commit(); - + try { writer->close(); @@ -189,43 +187,43 @@ BOOST_AUTO_TEST_CASE(testRandomExceptions) { writer->rollback(); } - + // Confirm that when doc hits exception partway through tokenization, it's deleted IndexReaderPtr r2 = IndexReader::open(dir, true); int32_t count = r2->docFreq(newLucene(L"content4", L"aaa")); int32_t count2 = r2->docFreq(newLucene(L"content4", L"ddd")); - BOOST_CHECK_EQUAL(count, count2); + EXPECT_EQ(count, count2); r2->close(); checkIndex(dir); } -BOOST_AUTO_TEST_CASE(testRandomExceptionsThreads) +TEST_F(IndexWriterExceptionsTest, testRandomExceptionsThreads) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); boost::dynamic_pointer_cast(writer->getMergeScheduler())->setSuppressExceptions(); - + writer->setRAMBufferSizeMB(0.2); - + int32_t NUM_THREADS = 4; - - Collection threads = Collection::newInstance(NUM_THREADS); + + Collection threads = Collection::newInstance(NUM_THREADS); for (int32_t i = 0; i < NUM_THREADS; ++i) { - threads[i] = newLucene(writer, this); + threads[i] = newLucene(writer, this); threads[i]->start(); } - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->join(); - + for (int32_t i = 0; i < NUM_THREADS; ++i) { if (!threads[i]->failure.isNull()) - BOOST_FAIL("thread hit unexpected failure: " << threads[i]->failure.getError()); + FAIL() << "thread hit unexpected failure: " << threads[i]->failure.getError(); } - + writer->commit(); try @@ -236,15 +234,13 @@ BOOST_AUTO_TEST_CASE(testRandomExceptionsThreads) { writer->rollback(); } - + // Confirm that when doc hits exception partway through tokenization, it's deleted IndexReaderPtr r2 = IndexReader::open(dir, true); int32_t count = r2->docFreq(newLucene(L"content4", L"aaa")); int32_t count2 = r2->docFreq(newLucene(L"content4", L"ddd")); - BOOST_CHECK_EQUAL(count, count2); + EXPECT_EQ(count, count2); r2->close(); checkIndex(dir); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexWriterLockReleaseTest.cpp b/src/test/index/IndexWriterLockReleaseTest.cpp index 63e2d82a..39f6b661 100644 --- a/src/test/index/IndexWriterLockReleaseTest.cpp +++ b/src/test/index/IndexWriterLockReleaseTest.cpp @@ -14,23 +14,35 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexWriterLockReleaseTest, LuceneTestFixture) +typedef LuceneTestFixture IndexWriterLockReleaseTest; -BOOST_AUTO_TEST_CASE(testIndexWriterLockRelease) +TEST_F(IndexWriterLockReleaseTest, testIndexWriterLockRelease) { String testDir(getTempDir(L"testIndexWriter")); FileUtils::createDirectory(testDir); - + DirectoryPtr dir = FSDirectory::open(testDir); IndexWriterPtr im; - - BOOST_CHECK_EXCEPTION(im = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED), FileNotFoundException, check_exception(LuceneException::FileNotFound)); - - BOOST_CHECK_EXCEPTION(im = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED), FileNotFoundException, check_exception(LuceneException::FileNotFound)); - + + try + { + im = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); + } + catch (FileNotFoundException& e) + { + EXPECT_TRUE(check_exception(LuceneException::FileNotFound)(e)); + } + + try + { + im = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); + } + catch (FileNotFoundException& e) + { + EXPECT_TRUE(check_exception(LuceneException::FileNotFound)(e)); + } + dir->close(); - + FileUtils::removeDirectory(testDir); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexWriterMergePolicyTest.cpp b/src/test/index/IndexWriterMergePolicyTest.cpp index f2438c23..7e94d507 100644 --- a/src/test/index/IndexWriterMergePolicyTest.cpp +++ b/src/test/index/IndexWriterMergePolicyTest.cpp @@ -19,7 +19,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexWriterMergePolicyTest, LuceneTestFixture) +typedef LuceneTestFixture IndexWriterMergePolicyTest; static void addDoc(IndexWriterPtr writer) { @@ -36,7 +36,7 @@ static void checkInvariants(IndexWriterPtr writer) int32_t maxMergeDocs = writer->getMaxMergeDocs(); int32_t ramSegmentCount = writer->getNumBufferedDocuments(); - BOOST_CHECK(ramSegmentCount < maxBufferedDocs); + EXPECT_TRUE(ramSegmentCount < maxBufferedDocs); int32_t lowerBound = -1; int32_t upperBound = maxBufferedDocs; @@ -46,15 +46,15 @@ static void checkInvariants(IndexWriterPtr writer) for (int32_t i = segmentCount - 1; i >= 0; --i) { int32_t docCount = writer->getDocCount(i); - BOOST_CHECK(docCount > lowerBound); + EXPECT_TRUE(docCount > lowerBound); if (docCount <= upperBound) ++numSegments; else { if (upperBound * mergeFactor <= maxMergeDocs) - BOOST_CHECK(numSegments < mergeFactor); - + EXPECT_TRUE(numSegments < mergeFactor); + do { lowerBound = upperBound; @@ -65,10 +65,10 @@ static void checkInvariants(IndexWriterPtr writer) } } if (upperBound * mergeFactor <= maxMergeDocs) - BOOST_CHECK(numSegments < mergeFactor); + EXPECT_TRUE(numSegments < mergeFactor); } -BOOST_AUTO_TEST_CASE(testNormalCase) +TEST_F(IndexWriterMergePolicyTest, testNormalCase) { DirectoryPtr dir = newLucene(); @@ -76,17 +76,17 @@ BOOST_AUTO_TEST_CASE(testNormalCase) writer->setMaxBufferedDocs(10); writer->setMergeFactor(10); writer->setMergePolicy(newLucene(writer)); - + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); checkInvariants(writer); } - + writer->close(); } -BOOST_AUTO_TEST_CASE(testNoOverMerge) +TEST_F(IndexWriterMergePolicyTest, testNoOverMerge) { DirectoryPtr dir = newLucene(); @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(testNoOverMerge) writer->setMaxBufferedDocs(10); writer->setMergeFactor(10); writer->setMergePolicy(newLucene(writer)); - + bool noOverMerge = false; for (int32_t i = 0; i < 100; ++i) { @@ -103,14 +103,14 @@ BOOST_AUTO_TEST_CASE(testNoOverMerge) if (writer->getNumBufferedDocuments() + writer->getSegmentCount() >= 18) noOverMerge = true; } - - BOOST_CHECK(noOverMerge); - + + EXPECT_TRUE(noOverMerge); + writer->close(); } /// Test the case where flush is forced after every addDoc -BOOST_AUTO_TEST_CASE(testForceFlush) +TEST_F(IndexWriterMergePolicyTest, testForceFlush) { DirectoryPtr dir = newLucene(); @@ -120,7 +120,7 @@ BOOST_AUTO_TEST_CASE(testForceFlush) LogDocMergePolicyPtr mp = newLucene(writer); mp->setMinMergeDocs(100); writer->setMergePolicy(mp); - + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); @@ -133,12 +133,12 @@ BOOST_AUTO_TEST_CASE(testForceFlush) writer->setMergeFactor(10); checkInvariants(writer); } - + writer->close(); } /// Test the case where mergeFactor changes -BOOST_AUTO_TEST_CASE(testMergeFactorChange) +TEST_F(IndexWriterMergePolicyTest, testMergeFactorChange) { DirectoryPtr dir = newLucene(); @@ -146,25 +146,25 @@ BOOST_AUTO_TEST_CASE(testMergeFactorChange) writer->setMaxBufferedDocs(10); writer->setMergeFactor(100); writer->setMergePolicy(newLucene(writer)); - + for (int32_t i = 0; i < 250; ++i) { addDoc(writer); checkInvariants(writer); } - + writer->setMergeFactor(5); // merge policy only fixes segments on levels where merges have been triggered, so check invariants after all adds for (int32_t i = 0; i < 10; ++i) addDoc(writer); checkInvariants(writer); - + writer->close(); } /// Test the case where both mergeFactor and maxBufferedDocs change -BOOST_AUTO_TEST_CASE(testMaxBufferedDocsChange) +TEST_F(IndexWriterMergePolicyTest, testMaxBufferedDocsChange) { DirectoryPtr dir = newLucene(); @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(testMaxBufferedDocsChange) writer->setMaxBufferedDocs(101); writer->setMergeFactor(101); writer->setMergePolicy(newLucene(writer)); - + // leftmost* segment has 1 doc // rightmost* segment has 100 docs for (int32_t i = 1; i <= 100; ++i) @@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(testMaxBufferedDocsChange) writer->setMergeFactor(101); writer->setMergePolicy(newLucene(writer)); } - + writer->setMaxBufferedDocs(10); writer->setMergeFactor(10); @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(testMaxBufferedDocsChange) for (int32_t i = 0; i < 100; ++i) addDoc(writer); checkInvariants(writer); - + for (int32_t i = 100; i < 1000; ++i) addDoc(writer); writer->commit(); @@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(testMaxBufferedDocsChange) } /// Test the case where a merge results in no doc at all -BOOST_AUTO_TEST_CASE(testMergeDocCount0) +TEST_F(IndexWriterMergePolicyTest, testMergeDocCount0) { DirectoryPtr dir = newLucene(); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(testMergeDocCount0) writer->setMergePolicy(newLucene(writer)); writer->setMaxBufferedDocs(10); writer->setMergeFactor(100); - + for (int32_t i = 0; i < 250; ++i) { addDoc(writer); @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(testMergeDocCount0) writer->setMergePolicy(newLucene(writer)); writer->setMaxBufferedDocs(10); writer->setMergeFactor(5); - + // merge factor is changed, so check invariants after all adds for (int32_t i = 0; i < 10; ++i) addDoc(writer); @@ -241,9 +241,7 @@ BOOST_AUTO_TEST_CASE(testMergeDocCount0) boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); writer->commit(); checkInvariants(writer); - BOOST_CHECK_EQUAL(10, writer->maxDoc()); + EXPECT_EQ(10, writer->maxDoc()); writer->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexWriterMergingTest.cpp b/src/test/index/IndexWriterMergingTest.cpp index 9454df9f..77425383 100644 --- a/src/test/index/IndexWriterMergingTest.cpp +++ b/src/test/index/IndexWriterMergingTest.cpp @@ -16,7 +16,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexWriterMergingTest, LuceneTestFixture) +typedef LuceneTestFixture IndexWriterMergingTest; static bool verifyIndex(DirectoryPtr directory, int32_t startAt) { @@ -39,7 +39,7 @@ static void fillIndex(DirectoryPtr dir, int32_t start, int32_t numDocs) IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMergeFactor(2); writer->setMaxBufferedDocs(2); - + for (int32_t i = start; i < (start + numDocs); ++i) { DocumentPtr temp = newLucene(); @@ -50,7 +50,7 @@ static void fillIndex(DirectoryPtr dir, int32_t start, int32_t numDocs) } /// Tests that index merging (specifically addIndexesNoOptimize()) doesn't change the index order of documents. -BOOST_AUTO_TEST_CASE(testIndexWriterMerging) +TEST_F(IndexWriterMergingTest, testIndexWriterMerging) { int32_t num = 100; @@ -58,10 +58,10 @@ BOOST_AUTO_TEST_CASE(testIndexWriterMerging) DirectoryPtr indexB = newLucene(); fillIndex(indexA, 0, num); - BOOST_CHECK(!verifyIndex(indexA, 0)); - + EXPECT_TRUE(!verifyIndex(indexA, 0)); + fillIndex(indexB, num, num); - BOOST_CHECK(!verifyIndex(indexB, num)); + EXPECT_TRUE(!verifyIndex(indexB, num)); DirectoryPtr merged = newLucene(); @@ -72,8 +72,6 @@ BOOST_AUTO_TEST_CASE(testIndexWriterMerging) writer->optimize(); writer->close(); - BOOST_CHECK(!verifyIndex(merged, 0)); + EXPECT_TRUE(!verifyIndex(merged, 0)); merged->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexWriterReaderTest.cpp b/src/test/index/IndexWriterReaderTest.cpp index 0899599d..f8ea578e 100644 --- a/src/test/index/IndexWriterReaderTest.cpp +++ b/src/test/index/IndexWriterReaderTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexWriterReaderTest, LuceneTestFixture) +typedef LuceneTestFixture IndexWriterReaderTest; DECLARE_SHARED_PTR(TestableIndexWriter) DECLARE_SHARED_PTR(AddDirectoriesThread) @@ -66,20 +66,20 @@ static int32_t count(TermPtr t, IndexReaderPtr r) td->close(); return count; } - + class TestableIndexWriter : public IndexWriter { public: TestableIndexWriter(DirectoryPtr d, AnalyzerPtr a, int32_t mfl) : IndexWriter(d, a, mfl) { } - + virtual ~TestableIndexWriter() { } - + LUCENE_CLASS(TestableIndexWriter); - + public: using IndexWriter::flush; }; @@ -91,10 +91,10 @@ class HeavyAtomicInt : public LuceneObject { value = start; } - + virtual ~HeavyAtomicInt() { - + } protected: @@ -107,13 +107,13 @@ class HeavyAtomicInt : public LuceneObject value += inc; return value; } - + int32_t incrementAndGet() { SyncLock syncLock(this); return ++value; } - + int32_t intValue() { SyncLock syncLock(this); @@ -129,17 +129,17 @@ class AddDirectoriesThread : public LuceneThread this->_addDirectories = addDirectories; this->numIter = numIter; } - + virtual ~AddDirectoriesThread() { } - + LUCENE_CLASS(AddDirectoriesThread); - + protected: AddDirectoriesThreadsWeakPtr _addDirectories; int32_t numIter; - + public: virtual void run(); }; @@ -164,24 +164,24 @@ class AddDirectoriesThreads : public LuceneObject DocumentPtr doc = createDocument(i, L"addindex", 4); writer->addDocument(doc); } - + writer->close(); - + readers = Collection::newInstance(numDirs); for (int32_t i = 0; i < numDirs; ++i) readers[i] = IndexReader::open(addDir, false); } - + virtual ~AddDirectoriesThreads() { } - + LUCENE_CLASS(AddDirectoriesThreads); public: static const int32_t NUM_THREADS; static const int32_t NUM_INIT_DOCS; - + DirectoryPtr addDir; int32_t numDirs; Collection threads; @@ -198,27 +198,27 @@ class AddDirectoriesThreads : public LuceneObject for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->join(); } - + void close(bool doWait) { didClose = true; mainWriter->close(doWait); } - + void closeDir() { for (int32_t i = 0; i < numDirs; ++i) readers[i]->close(); addDir->close(); } - + void handle(const LuceneException& t) { - BOOST_FAIL(t.getError()); + FAIL() << t.getError(); SyncLock syncLock(&failures); failures.add(t); } - + void launchThreads(int32_t numIter) { for (int32_t i = 0; i < NUM_THREADS; ++i) @@ -226,7 +226,7 @@ class AddDirectoriesThreads : public LuceneObject for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->start(); } - + void doBody(int32_t j, Collection dirs) { switch (j % 4) @@ -256,7 +256,7 @@ const int32_t AddDirectoriesThreads::NUM_INIT_DOCS = 100; void AddDirectoriesThread::run() { AddDirectoriesThreadsPtr addDirectories(_addDirectories); - + try { Collection dirs = Collection::newInstance(addDirectories->numDirs); @@ -274,7 +274,7 @@ void AddDirectoriesThread::run() } } -BOOST_AUTO_TEST_CASE(testUpdateDocument) +TEST_F(IndexWriterReaderTest, testUpdateDocument) { bool optimize = true; @@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(testUpdateDocument) // get a reader IndexReaderPtr r1 = writer->getReader(); - BOOST_CHECK(r1->isCurrent()); + EXPECT_TRUE(r1->isCurrent()); String id10 = r1->document(10)->getField(L"id")->stringValue(); @@ -294,34 +294,34 @@ BOOST_AUTO_TEST_CASE(testUpdateDocument) newDoc->removeField(L"id"); newDoc->add(newLucene(L"id", StringUtils::toString(8000), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->updateDocument(newLucene(L"id", id10), newDoc); - BOOST_CHECK(!r1->isCurrent()); + EXPECT_TRUE(!r1->isCurrent()); IndexReaderPtr r2 = writer->getReader(); - BOOST_CHECK(r2->isCurrent()); - BOOST_CHECK_EQUAL(0, count(newLucene(L"id", id10), r2)); - BOOST_CHECK_EQUAL(1, count(newLucene(L"id", StringUtils::toString(8000)), r2)); + EXPECT_TRUE(r2->isCurrent()); + EXPECT_EQ(0, count(newLucene(L"id", id10), r2)); + EXPECT_EQ(1, count(newLucene(L"id", StringUtils::toString(8000)), r2)); r1->close(); writer->close(); - BOOST_CHECK(r2->isCurrent()); + EXPECT_TRUE(r2->isCurrent()); IndexReaderPtr r3 = IndexReader::open(dir1, true); - BOOST_CHECK(r3->isCurrent()); - BOOST_CHECK(r2->isCurrent()); - BOOST_CHECK_EQUAL(0, count(newLucene(L"id", id10), r3)); - BOOST_CHECK_EQUAL(1, count(newLucene(L"id", StringUtils::toString(8000)), r3)); + EXPECT_TRUE(r3->isCurrent()); + EXPECT_TRUE(r2->isCurrent()); + EXPECT_EQ(0, count(newLucene(L"id", id10), r3)); + EXPECT_EQ(1, count(newLucene(L"id", StringUtils::toString(8000)), r3)); writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); - BOOST_CHECK(r2->isCurrent()); - BOOST_CHECK(r3->isCurrent()); + EXPECT_TRUE(r2->isCurrent()); + EXPECT_TRUE(r3->isCurrent()); writer->close(); - BOOST_CHECK(!r2->isCurrent()); - BOOST_CHECK(!r3->isCurrent()); + EXPECT_TRUE(!r2->isCurrent()); + EXPECT_TRUE(!r3->isCurrent()); r2->close(); r3->close(); @@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(testUpdateDocument) dir1->close(); } -BOOST_AUTO_TEST_CASE(testAddIndexes) +TEST_F(IndexWriterReaderTest, testAddIndexes) { bool optimize = false; @@ -339,7 +339,7 @@ BOOST_AUTO_TEST_CASE(testAddIndexes) // create the index createIndexNoClose(!optimize, L"index1", writer); writer->flush(false, true, true); - + // create a 2nd index DirectoryPtr dir2 = newLucene(); TestableIndexWriterPtr writer2 = newLucene(dir2, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -347,35 +347,35 @@ BOOST_AUTO_TEST_CASE(testAddIndexes) writer2->close(); IndexReaderPtr r0 = writer->getReader(); - BOOST_CHECK(r0->isCurrent()); - + EXPECT_TRUE(r0->isCurrent()); + writer->addIndexesNoOptimize(newCollection(dir2)); - BOOST_CHECK(!r0->isCurrent()); + EXPECT_TRUE(!r0->isCurrent()); r0->close(); IndexReaderPtr r1 = writer->getReader(); - BOOST_CHECK(r1->isCurrent()); + EXPECT_TRUE(r1->isCurrent()); writer->commit(); - BOOST_CHECK(!r1->isCurrent()); + EXPECT_TRUE(!r1->isCurrent()); - BOOST_CHECK_EQUAL(200, r1->maxDoc()); + EXPECT_EQ(200, r1->maxDoc()); int32_t index2df = r1->docFreq(newLucene(L"indexname", L"index2")); - BOOST_CHECK_EQUAL(100, index2df); + EXPECT_EQ(100, index2df); // verify the docs are from different indexes DocumentPtr doc5 = r1->document(5); - BOOST_CHECK_EQUAL(L"index1", doc5->get(L"indexname")); + EXPECT_EQ(L"index1", doc5->get(L"indexname")); DocumentPtr doc150 = r1->document(150); - BOOST_CHECK_EQUAL(L"index2", doc150->get(L"indexname")); + EXPECT_EQ(L"index2", doc150->get(L"indexname")); r1->close(); writer->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testAddIndexes2) +TEST_F(IndexWriterReaderTest, testAddIndexes2) { bool optimize = false; @@ -386,9 +386,9 @@ BOOST_AUTO_TEST_CASE(testAddIndexes2) IndexWriterPtr writer2 = newLucene(dir2, newLucene(), IndexWriter::MaxFieldLengthLIMITED); createIndexNoClose(!optimize, L"index2", writer2); writer2->close(); - + Collection dirs = newCollection(dir2); - + writer->addIndexesNoOptimize(dirs); writer->addIndexesNoOptimize(dirs); writer->addIndexesNoOptimize(dirs); @@ -396,14 +396,14 @@ BOOST_AUTO_TEST_CASE(testAddIndexes2) writer->addIndexesNoOptimize(dirs); IndexReaderPtr r1 = writer->getReader(); - BOOST_CHECK_EQUAL(500, r1->maxDoc()); + EXPECT_EQ(500, r1->maxDoc()); r1->close(); writer->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testDeleteFromIndexWriter) +TEST_F(IndexWriterReaderTest, testDeleteFromIndexWriter) { bool optimize = true; @@ -414,32 +414,32 @@ BOOST_AUTO_TEST_CASE(testDeleteFromIndexWriter) // create the index createIndexNoClose(!optimize, L"index1", writer); writer->flush(false, true, true); - + // get a reader IndexReaderPtr r1 = writer->getReader(); - + String id10 = r1->document(10)->getField(L"id")->stringValue(); // deleted IW docs should not show up in the next getReader writer->deleteDocuments(newLucene(L"id", id10)); IndexReaderPtr r2 = writer->getReader(); - BOOST_CHECK_EQUAL(1, count(newLucene(L"id", id10), r1)); - BOOST_CHECK_EQUAL(0, count(newLucene(L"id", id10), r2)); + EXPECT_EQ(1, count(newLucene(L"id", id10), r1)); + EXPECT_EQ(0, count(newLucene(L"id", id10), r2)); String id50 = r1->document(50)->getField(L"id")->stringValue(); - BOOST_CHECK_EQUAL(1, count(newLucene(L"id", id50), r1)); + EXPECT_EQ(1, count(newLucene(L"id", id50), r1)); writer->deleteDocuments(newLucene(L"id", id50)); IndexReaderPtr r3 = writer->getReader(); - BOOST_CHECK_EQUAL(0, count(newLucene(L"id", id10), r3)); - BOOST_CHECK_EQUAL(0, count(newLucene(L"id", id50), r3)); + EXPECT_EQ(0, count(newLucene(L"id", id10), r3)); + EXPECT_EQ(0, count(newLucene(L"id", id50), r3)); String id75 = r1->document(75)->getField(L"id")->stringValue(); writer->deleteDocuments(newLucene(newLucene(L"id", id75))); IndexReaderPtr r4 = writer->getReader(); - BOOST_CHECK_EQUAL(1, count(newLucene(L"id", id75), r3)); - BOOST_CHECK_EQUAL(0, count(newLucene(L"id", id75), r4)); + EXPECT_EQ(1, count(newLucene(L"id", id75), r3)); + EXPECT_EQ(0, count(newLucene(L"id", id75), r4)); r1->close(); r2->close(); @@ -450,33 +450,33 @@ BOOST_AUTO_TEST_CASE(testDeleteFromIndexWriter) // reopen the writer to verify the delete made it to the directory writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); IndexReaderPtr w2r1 = writer->getReader(); - BOOST_CHECK_EQUAL(0, count(newLucene(L"id", id10), w2r1)); + EXPECT_EQ(0, count(newLucene(L"id", id10), w2r1)); w2r1->close(); writer->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testAddIndexesAndDoDeletesThreads) +TEST_F(IndexWriterReaderTest, testAddIndexesAndDoDeletesThreads) { int32_t numIter = 5; int32_t numDirs = 3; - + DirectoryPtr mainDir = newLucene(); IndexWriterPtr mainWriter = newLucene(mainDir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); AddDirectoriesThreadsPtr addDirThreads = newLucene(numIter, mainWriter); addDirThreads->launchThreads(numDirs); addDirThreads->joinThreads(); - BOOST_CHECK_EQUAL(addDirThreads->count->intValue(), addDirThreads->mainWriter->numDocs()); + EXPECT_EQ(addDirThreads->count->intValue(), addDirThreads->mainWriter->numDocs()); addDirThreads->close(true); - BOOST_CHECK(addDirThreads->failures.empty()); + EXPECT_TRUE(addDirThreads->failures.empty()); checkIndex(mainDir); IndexReaderPtr reader = IndexReader::open(mainDir, true); - BOOST_CHECK_EQUAL(addDirThreads->count->intValue(), reader->numDocs()); + EXPECT_EQ(addDirThreads->count->intValue(), reader->numDocs()); reader->close(); addDirThreads->closeDir(); @@ -488,18 +488,18 @@ static void doTestIndexWriterReopenSegment(bool optimize) { DirectoryPtr dir1 = newLucene(); TestableIndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - + IndexReaderPtr r1 = writer->getReader(); - BOOST_CHECK_EQUAL(0, r1->maxDoc()); + EXPECT_EQ(0, r1->maxDoc()); createIndexNoClose(false, L"index1", writer); writer->flush(!optimize, true, true); IndexReaderPtr iwr1 = writer->getReader(); - BOOST_CHECK_EQUAL(100, iwr1->maxDoc()); + EXPECT_EQ(100, iwr1->maxDoc()); IndexReaderPtr r2 = writer->getReader(); - BOOST_CHECK_EQUAL(100, r2->maxDoc()); - + EXPECT_EQ(100, r2->maxDoc()); + // add 100 documents for (int32_t x = 10000; x < 10000 + 100; ++x) { @@ -509,12 +509,12 @@ static void doTestIndexWriterReopenSegment(bool optimize) writer->flush(false, true, true); // verify the reader was reopened internally IndexReaderPtr iwr2 = writer->getReader(); - BOOST_CHECK_NE(iwr2, r1); - BOOST_CHECK_EQUAL(200, iwr2->maxDoc()); + EXPECT_NE(iwr2, r1); + EXPECT_EQ(200, iwr2->maxDoc()); // should have flushed out a segment IndexReaderPtr r3 = writer->getReader(); - BOOST_CHECK_NE(r2, r3); - BOOST_CHECK_EQUAL(200, r3->maxDoc()); + EXPECT_NE(r2, r3); + EXPECT_EQ(200, r3->maxDoc()); // dec ref the readers rather than close them because closing flushes changes to the writer r1->close(); @@ -528,19 +528,19 @@ static void doTestIndexWriterReopenSegment(bool optimize) writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); IndexReaderPtr w2r1 = writer->getReader(); // insure the deletes were actually flushed to the directory - BOOST_CHECK_EQUAL(200, w2r1->maxDoc()); + EXPECT_EQ(200, w2r1->maxDoc()); w2r1->close(); writer->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testIndexWriterReopenSegmentOptimize) +TEST_F(IndexWriterReaderTest, testIndexWriterReopenSegmentOptimize) { doTestIndexWriterReopenSegment(true); } -BOOST_AUTO_TEST_CASE(testIndexWriterReopenSegment) +TEST_F(IndexWriterReaderTest, testIndexWriterReopenSegment) { doTestIndexWriterReopenSegment(false); } @@ -548,7 +548,7 @@ BOOST_AUTO_TEST_CASE(testIndexWriterReopenSegment) namespace TestMergeWarmer { DECLARE_SHARED_PTR(MyWarmer) - + class MyWarmer : public IndexReaderWarmer { public: @@ -556,16 +556,16 @@ namespace TestMergeWarmer { warmCount = 0; } - + virtual ~MyWarmer() { } - + LUCENE_CLASS(MyWarmer); - + public: int32_t warmCount; - + public: virtual void warm(IndexReaderPtr reader) { @@ -574,11 +574,11 @@ namespace TestMergeWarmer }; } -BOOST_AUTO_TEST_CASE(testMergeWarmer) +TEST_F(IndexWriterReaderTest, testMergeWarmer) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - + // create the index createIndexNoClose(false, L"test", writer); @@ -590,29 +590,29 @@ BOOST_AUTO_TEST_CASE(testMergeWarmer) writer->setMergedSegmentWarmer(warmer); writer->setMergeFactor(2); writer->setMaxBufferedDocs(2); - + for (int32_t i = 0; i < 100; ++i) writer->addDocument(createDocument(i, L"test", 4)); - + boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); - BOOST_CHECK(warmer->warmCount > 0); + EXPECT_TRUE(warmer->warmCount > 0); int32_t count = warmer->warmCount; writer->addDocument(createDocument(17, L"test", 4)); writer->optimize(); - BOOST_CHECK(warmer->warmCount > count); + EXPECT_TRUE(warmer->warmCount > count); writer->close(); r1->close(); dir1->close(); } -BOOST_AUTO_TEST_CASE(testAfterCommit) +TEST_F(IndexWriterReaderTest, testAfterCommit) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - + // create the index createIndexNoClose(false, L"test", writer); @@ -621,11 +621,11 @@ BOOST_AUTO_TEST_CASE(testAfterCommit) checkIndex(dir1); writer->commit(); checkIndex(dir1); - BOOST_CHECK_EQUAL(100, r1->numDocs()); - + EXPECT_EQ(100, r1->numDocs()); + for (int32_t i = 0; i < 10; ++i) writer->addDocument(createDocument(i, L"test", 4)); - + boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); IndexReaderPtr r2 = r1->reopen(); @@ -634,19 +634,19 @@ BOOST_AUTO_TEST_CASE(testAfterCommit) r1->close(); r1 = r2; } - - BOOST_CHECK_EQUAL(110, r1->numDocs()); + + EXPECT_EQ(110, r1->numDocs()); writer->close(); r1->close(); dir1->close(); } /// Make sure reader remains usable even if IndexWriter closes -BOOST_AUTO_TEST_CASE(testAfterClose) +TEST_F(IndexWriterReaderTest, testAfterClose) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - + // create the index createIndexNoClose(false, L"test", writer); @@ -656,11 +656,18 @@ BOOST_AUTO_TEST_CASE(testAfterClose) checkIndex(dir1); // reader should remain usable even after IndexWriter is closed - BOOST_CHECK_EQUAL(100, r->numDocs()); + EXPECT_EQ(100, r->numDocs()); QueryPtr q = newLucene(newLucene(L"indexname", L"test")); - BOOST_CHECK_EQUAL(100, newLucene(r)->search(q, 10)->totalHits); + EXPECT_EQ(100, newLucene(r)->search(q, 10)->totalHits); - BOOST_CHECK_EXCEPTION(r->reopen(), AlreadyClosedException, check_exception(LuceneException::AlreadyClosed)); + try + { + r->reopen(); + } + catch (AlreadyClosedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } r->close(); dir1->close(); @@ -677,18 +684,18 @@ namespace TestDuringAddIndexes this->writer = writer; this->dirs = dirs; } - + virtual ~AddIndexesThread() { } - + LUCENE_CLASS(AddIndexesThread); - + protected: int64_t endTime; IndexWriterPtr writer; Collection dirs; - + public: virtual void run() { @@ -700,7 +707,7 @@ namespace TestDuringAddIndexes } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } } @@ -708,34 +715,34 @@ namespace TestDuringAddIndexes } /// Stress test reopen during addIndexes -BOOST_AUTO_TEST_CASE(testDuringAddIndexes) +TEST_F(IndexWriterReaderTest, testDuringAddIndexes) { MockRAMDirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMergeFactor(2); - + // create the index createIndexNoClose(false, L"test", writer); writer->commit(); - + Collection dirs = Collection::newInstance(10); for (int32_t i = 0; i < 10; ++i) dirs[i] = newLucene(dir1); - + IndexReaderPtr r = writer->getReader(); int32_t NUM_THREAD = 5; int32_t SECONDS = 3; int64_t endTime = MiscUtils::currentTimeMillis() + 1000 * SECONDS; - + Collection threads = Collection::newInstance(NUM_THREAD); for (int32_t i = 0; i < NUM_THREAD; ++i) { threads[i] = newLucene(endTime, writer, dirs); threads[i]->start(); } - + int32_t lastCount = 0; while ((int64_t)MiscUtils::currentTimeMillis() < endTime) { @@ -747,16 +754,16 @@ BOOST_AUTO_TEST_CASE(testDuringAddIndexes) } QueryPtr q = newLucene(newLucene(L"indexname", L"test")); int32_t count = newLucene(r)->search(q, 10)->totalHits; - BOOST_CHECK(count >= lastCount); + EXPECT_TRUE(count >= lastCount); lastCount = count; } - + for (int32_t i = 0; i < NUM_THREAD; ++i) threads[i]->join(); writer->close(); r->close(); - BOOST_CHECK_EQUAL(0, dir1->getOpenDeletedFiles().size()); + EXPECT_EQ(0, dir1->getOpenDeletedFiles().size()); checkIndex(dir1); dir1->close(); @@ -773,18 +780,18 @@ namespace TestDuringAddDelete this->writer = writer; this->random = newLucene(); } - + virtual ~AddDeleteThread() { } - + LUCENE_CLASS(AddDeleteThread); - + protected: int64_t endTime; IndexWriterPtr writer; RandomPtr random; - + public: virtual void run() { @@ -805,7 +812,7 @@ namespace TestDuringAddDelete } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } } @@ -813,30 +820,30 @@ namespace TestDuringAddDelete } /// Stress test reopen during add/delete -BOOST_AUTO_TEST_CASE(testDuringAddDelete) +TEST_F(IndexWriterReaderTest, testDuringAddDelete) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMergeFactor(2); - + // create the index createIndexNoClose(false, L"test", writer); writer->commit(); - + IndexReaderPtr r = writer->getReader(); int32_t NUM_THREAD = 5; int32_t SECONDS = 3; int64_t endTime = MiscUtils::currentTimeMillis() + 1000 * SECONDS; - + Collection threads = Collection::newInstance(NUM_THREAD); for (int32_t i = 0; i < NUM_THREAD; ++i) { threads[i] = newLucene(endTime, writer); threads[i]->start(); } - + int32_t sum = 0; while ((int64_t)MiscUtils::currentTimeMillis() < endTime) { @@ -849,11 +856,11 @@ BOOST_AUTO_TEST_CASE(testDuringAddDelete) QueryPtr q = newLucene(newLucene(L"indexname", L"test")); sum += newLucene(r)->search(q, 10)->totalHits; } - + for (int32_t i = 0; i < NUM_THREAD; ++i) threads[i]->join(); - BOOST_CHECK(sum > 0); + EXPECT_TRUE(sum > 0); writer->close(); @@ -862,11 +869,11 @@ BOOST_AUTO_TEST_CASE(testDuringAddDelete) dir1->close(); } -BOOST_AUTO_TEST_CASE(testExpungeDeletes) +TEST_F(IndexWriterReaderTest, testExpungeDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - + DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED)); FieldPtr id = newLucene(L"id", L"", Field::STORE_NO, Field::INDEX_ANALYZED); @@ -882,13 +889,13 @@ BOOST_AUTO_TEST_CASE(testExpungeDeletes) w->close(); r->close(); r = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(1, r->numDocs()); - BOOST_CHECK(!r->hasDeletions()); + EXPECT_EQ(1, r->numDocs()); + EXPECT_TRUE(!r->hasDeletions()); r->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDeletesNumDocs) +TEST_F(IndexWriterReaderTest, testDeletesNumDocs) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -901,17 +908,17 @@ BOOST_AUTO_TEST_CASE(testDeletesNumDocs) id->setValue(L"1"); w->addDocument(doc); IndexReaderPtr r = w->getReader(); - BOOST_CHECK_EQUAL(2, r->numDocs()); + EXPECT_EQ(2, r->numDocs()); r->close(); w->deleteDocuments(newLucene(L"id", L"0")); r = w->getReader(); - BOOST_CHECK_EQUAL(1, r->numDocs()); + EXPECT_EQ(1, r->numDocs()); r->close(); w->deleteDocuments(newLucene(L"id", L"1")); r = w->getReader(); - BOOST_CHECK_EQUAL(0, r->numDocs()); + EXPECT_EQ(0, r->numDocs()); r->close(); w->close(); @@ -921,35 +928,35 @@ BOOST_AUTO_TEST_CASE(testDeletesNumDocs) namespace TestSegmentWarmer { DECLARE_SHARED_PTR(SegmentWarmer) - + class SegmentWarmer : public IndexReaderWarmer { public: virtual ~SegmentWarmer() { } - + LUCENE_CLASS(SegmentWarmer); - + public: virtual void warm(IndexReaderPtr reader) { IndexSearcherPtr s = newLucene(reader); TopDocsPtr hits = s->search(newLucene(newLucene(L"foo", L"bar")), 10); - BOOST_CHECK_EQUAL(20, hits->totalHits); + EXPECT_EQ(20, hits->totalHits); } }; } -BOOST_AUTO_TEST_CASE(testSegmentWarmer) +TEST_F(IndexWriterReaderTest, testSegmentWarmer) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); w->setMaxBufferedDocs(2); w->getReader()->close(); - + w->setMergedSegmentWarmer(newLucene()); - + DocumentPtr doc = newLucene(); doc->add(newLucene(L"foo", L"bar", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); for (int32_t i = 0; i < 20; ++i) @@ -958,5 +965,3 @@ BOOST_AUTO_TEST_CASE(testSegmentWarmer) w->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/IndexWriterTest.cpp b/src/test/index/IndexWriterTest.cpp index ac9a92f6..5fdc90e3 100644 --- a/src/test/index/IndexWriterTest.cpp +++ b/src/test/index/IndexWriterTest.cpp @@ -57,7 +57,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexWriterTest, LuceneTestFixture) +typedef LuceneTestFixture IndexWriterTest; static void addDoc(IndexWriterPtr writer) { @@ -81,14 +81,14 @@ static void checkNoUnreferencedFiles(DirectoryPtr dir) infos->read(dir); IndexFileDeleterPtr deleter = newLucene(dir, newLucene(), infos, InfoStreamPtr(), DocumentsWriterPtr(), HashSet()); HashSet _endFiles = dir->listAll(); - + Collection startFiles = Collection::newInstance(_startFiles.begin(), _startFiles.end()); Collection endFiles = Collection::newInstance(_endFiles.begin(), _endFiles.end()); - + std::sort(startFiles.begin(), startFiles.end()); std::sort(endFiles.begin(), endFiles.end()); - - BOOST_CHECK(startFiles.equals(endFiles)); + + EXPECT_TRUE(startFiles.equals(endFiles)); } DECLARE_SHARED_PTR(FailOnlyOnFlush) @@ -106,7 +106,7 @@ class FailOnlyOnFlush : public MockDirectoryFailure count = 0; TestPoint::clear(); } - + virtual ~FailOnlyOnFlush() { } @@ -119,7 +119,7 @@ class FailOnlyOnFlush : public MockDirectoryFailure { if (this->doFail) { - if (TestPoint::getTestPoint(L"FreqProxTermsWriter", L"appendPostings") && + if (TestPoint::getTestPoint(L"FreqProxTermsWriter", L"appendPostings") && TestPoint::getTestPoint(L"doFlush") && count++ >= 30) { doFail = false; @@ -137,7 +137,7 @@ class FailOnlyOnAbortOrFlush : public MockDirectoryFailure { onlyOnce = false; } - + virtual ~FailOnlyOnAbortOrFlush() { } @@ -168,7 +168,7 @@ class FailOnlyInCloseDocStore : public MockDirectoryFailure { onlyOnce = false; } - + virtual ~FailOnlyInCloseDocStore() { } @@ -199,7 +199,7 @@ class FailOnlyInWriteSegment : public MockDirectoryFailure { onlyOnce = false; } - + virtual ~FailOnlyInWriteSegment() { } @@ -230,7 +230,7 @@ class FailOnlyInSync : public MockDirectoryFailure { didFail = false; } - + virtual ~FailOnlyInSync() { } @@ -260,7 +260,7 @@ class FailOnlyInCommit : public MockDirectoryFailure fail1 = false; fail2 = false; } - + virtual ~FailOnlyInCommit() { } @@ -274,7 +274,7 @@ class FailOnlyInCommit : public MockDirectoryFailure { bool isCommit = TestPoint::getTestPoint(L"SegmentInfos", L"prepareCommit"); bool isDelete = TestPoint::getTestPoint(L"MockRAMDirectory", L"deleteFile"); - + if (isCommit) { if (!isDelete) @@ -299,7 +299,7 @@ class CrashingFilter : public TokenFilter this->count = 0; this->fieldName = fieldName; } - + virtual ~CrashingFilter() { } @@ -317,7 +317,7 @@ class CrashingFilter : public TokenFilter boost::throw_exception(IOException(L"now failing on purpose")); return input->incrementToken(); } - + virtual void reset() { TokenFilter::reset(); @@ -336,28 +336,28 @@ class IndexerThread : public LuceneThread this->noErrors = noErrors; this->addCount = 0; } - + virtual ~IndexerThread() { } - + LUCENE_CLASS(IndexerThread); - + public: IndexWriterPtr writer; bool noErrors; int32_t addCount; - + public: virtual void run() { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa bbb ccc ddd eee fff ggg hhh iii jjj", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - + int32_t idUpto = 0; int32_t fullCount = 0; int64_t stopTime = MiscUtils::currentTimeMillis() + 500; - + while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) { try @@ -376,14 +376,14 @@ class IndexerThread : public LuceneThread else { if (noErrors) - BOOST_FAIL("Unexpected exception"); + FAIL() << "Unexpected exception"; break; } } catch (...) { if (noErrors) - BOOST_FAIL("Unexpected exception"); + FAIL() << "Unexpected exception"; break; } } @@ -398,16 +398,16 @@ class RunAddIndexesThreads : public LuceneObject public: RunAddIndexesThreads(int32_t numCopy); virtual ~RunAddIndexesThreads(); - + LUCENE_CLASS(RunAddIndexesThreads); public: DirectoryPtr dir; DirectoryPtr dir2; - + static const int32_t NUM_INIT_DOCS; static const int32_t NUM_THREADS; - + IndexWriterPtr writer2; bool didClose; Collection readers; @@ -420,7 +420,7 @@ class RunAddIndexesThreads : public LuceneObject void joinThreads(); void close(bool doWait); void closeDir(); - + virtual void doBody(int32_t j, Collection dirs) = 0; virtual void handle(LuceneException& e) = 0; }; @@ -438,7 +438,7 @@ class RunAddThread : public LuceneThread this->numCopy = numCopy; this->dir = dir; } - + virtual ~RunAddThread() { } @@ -457,9 +457,9 @@ class RunAddThread : public LuceneThread Collection dirs = Collection::newInstance(numCopy); for (int32_t k = 0; k < numCopy; ++k) dirs[k] = newLucene(dir); - + int32_t j = 0; - + while (true) { if (numIter > 0 && j == numIter) @@ -480,7 +480,7 @@ RunAddIndexesThreads::RunAddIndexesThreads(int32_t numCopy) didClose = false; NUM_COPY = numCopy; dir = newLucene(); - + IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); for (int32_t i = 0; i < NUM_INIT_DOCS; ++i) @@ -496,7 +496,7 @@ RunAddIndexesThreads::RunAddIndexesThreads(int32_t numCopy) for (int32_t i = 0; i < NUM_COPY; ++i) readers[i] = IndexReader::open(dir, true); } - + RunAddIndexesThreads::~RunAddIndexesThreads() { } @@ -528,12 +528,12 @@ void RunAddIndexesThreads::closeDir() dir2->close(); } -BOOST_AUTO_TEST_CASE(testDocCount) +TEST_F(IndexWriterTest, testDocCount) { DirectoryPtr dir = newLucene(); IndexWriter::setDefaultWriteLockTimeout(2000); - BOOST_CHECK_EQUAL(2000, IndexWriter::getDefaultWriteLockTimeout()); + EXPECT_EQ(2000, IndexWriter::getDefaultWriteLockTimeout()); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -542,7 +542,7 @@ BOOST_AUTO_TEST_CASE(testDocCount) // add 100 documents for (int32_t i = 0; i < 100; ++i) addDoc(writer); - BOOST_CHECK_EQUAL(100, writer->maxDoc()); + EXPECT_EQ(100, writer->maxDoc()); writer->close(); // delete 40 documents @@ -553,40 +553,40 @@ BOOST_AUTO_TEST_CASE(testDocCount) // test doc count before segments are merged/index is optimized writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - BOOST_CHECK_EQUAL(100, writer->maxDoc()); + EXPECT_EQ(100, writer->maxDoc()); writer->close(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(100, reader->maxDoc()); - BOOST_CHECK_EQUAL(60, reader->numDocs()); + EXPECT_EQ(100, reader->maxDoc()); + EXPECT_EQ(60, reader->numDocs()); reader->close(); // optimize the index and check that the new doc count is correct writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); - BOOST_CHECK_EQUAL(100, writer->maxDoc()); - BOOST_CHECK_EQUAL(60, writer->numDocs()); + EXPECT_EQ(100, writer->maxDoc()); + EXPECT_EQ(60, writer->numDocs()); writer->optimize(); - BOOST_CHECK_EQUAL(60, writer->maxDoc()); - BOOST_CHECK_EQUAL(60, writer->numDocs()); + EXPECT_EQ(60, writer->maxDoc()); + EXPECT_EQ(60, writer->numDocs()); writer->close(); // check that the index reader gives the same numbers reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(60, reader->maxDoc()); - BOOST_CHECK_EQUAL(60, reader->numDocs()); + EXPECT_EQ(60, reader->maxDoc()); + EXPECT_EQ(60, reader->numDocs()); reader->close(); // make sure opening a new index for create over this existing one works correctly writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - BOOST_CHECK_EQUAL(0, writer->maxDoc()); - BOOST_CHECK_EQUAL(0, writer->numDocs()); + EXPECT_EQ(0, writer->maxDoc()); + EXPECT_EQ(0, writer->numDocs()); writer->close(); } /// Test: make sure when we run out of disk space or hit random IOExceptions in any of the addIndexesNoOptimize(*) calls /// that 1) index is not corrupt (searcher can open/search it) and 2) transactional semantics are followed: /// either all or none of the incoming documents were in fact added. -BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) +TEST_F(IndexWriterTest, testAddIndexOnDiskFull) { int32_t START_COUNT = 57; int32_t NUM_DIR = 50; @@ -615,20 +615,20 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) writer->close(); // Make sure starting index seems to be working properly - TermPtr searchTerm = newLucene(L"content", L"aaa"); + TermPtr searchTerm = newLucene(L"content", L"aaa"); IndexReaderPtr reader = IndexReader::open(startDir, true); - BOOST_CHECK_EQUAL(57, reader->docFreq(searchTerm)); + EXPECT_EQ(57, reader->docFreq(searchTerm)); IndexSearcherPtr searcher = newLucene(reader); Collection hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(57, hits.size()); + EXPECT_EQ(57, hits.size()); searcher->close(); reader->close(); // Iterate with larger and larger amounts of free disk space. With little free disk space, - // addIndexesNoOptimize will certainly run out of space and fail. Verify that when this - // happens, index is not corrupt and index in fact has added no documents. Then, we increase - // disk space by 2000 bytes each iteration. At some point there is enough free disk space + // addIndexesNoOptimize will certainly run out of space and fail. Verify that when this + // happens, index is not corrupt and index in fact has added no documents. Then, we increase + // disk space by 2000 bytes each iteration. At some point there is enough free disk space // and addIndexesNoOptimize should succeed and index should show all documents were added. int64_t diskUsage = startDir->sizeInBytes(); @@ -640,7 +640,7 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) for (int32_t iter = 0; iter < 3; ++iter) { - BOOST_TEST_MESSAGE("TEST: iter=" << iter); + // std::cout << "TEST: iter=" << iter; // Start with 100 bytes more than we are currently using: int64_t diskFree = diskUsage + 100; @@ -701,7 +701,7 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) testName = L"disk full test " + methodName + L" with unlimited disk space"; } - BOOST_TEST_MESSAGE("\ncycle: " << testName); + // std::cout << "\ncycle: " << testName; dir->setMaxSizeInBytes(thisDiskFree); dir->setRandomIOExceptionRate(rate, diskFree); @@ -735,7 +735,7 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) writer->addIndexesNoOptimize(dirs); success = true; - BOOST_TEST_MESSAGE(" success!"); + // std::cout << " success!"; if (x == 0) done = true; @@ -743,16 +743,16 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) catch (IOException& e) { success = false; - BOOST_TEST_MESSAGE(" hit IOException: " << e.getError()); + // std::cout << " hit IOException: " << e.getError(); if (x == 1) - BOOST_FAIL(methodName << " hit IOException after disk space was freed up"); + FAIL() << methodName << " hit IOException after disk space was freed up"; } // Make sure all threads from ConcurrentMergeScheduler are done syncConcurrentMerges(writer); - BOOST_TEST_MESSAGE(" now test readers"); + // std::cout << " now test readers"; // Finally, verify index is not corrupt, and, if we succeeded, we see all docs added, and if we // failed, we see either all docs or no docs added (transactional semantics) @@ -762,19 +762,19 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) } catch (IOException& e) { - BOOST_FAIL(testName << ": exception when creating IndexReader: " << e.getError()); + FAIL() << testName << ": exception when creating IndexReader: " << e.getError(); } int32_t result = reader->docFreq(searchTerm); if (success) { if (result != START_COUNT) - BOOST_FAIL(testName << ": method did not throw exception but docFreq('aaa') is " << result << " instead of expected " << START_COUNT); + FAIL() << testName << ": method did not throw exception but docFreq('aaa') is " << result << " instead of expected " << START_COUNT; } else { // On hitting exception we still may have added all docs if (result != START_COUNT && result != END_COUNT) - BOOST_FAIL(testName << ": method did throw exception but docFreq('aaa') is " << result << " instead of expected " << START_COUNT << " or " << END_COUNT); + FAIL() << testName << ": method did throw exception but docFreq('aaa') is " << result << " instead of expected " << START_COUNT << " or " << END_COUNT; } searcher = newLucene(reader); @@ -784,35 +784,35 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) } catch (IOException& e) { - BOOST_FAIL(testName << ": exception when searching: " << e.getError()); + FAIL() << testName << ": exception when searching: " << e.getError(); } int32_t result2 = hits.size(); if (success) { if (result2 != result) - BOOST_FAIL(testName << ": method did not throw exception but hits.length for search on term 'aaa' is " << result2 << " instead of expected " << result); + FAIL() << testName << ": method did not throw exception but hits.length for search on term 'aaa' is " << result2 << " instead of expected " << result; } else { // On hitting exception we still may have added all docs if (result2 != result) - BOOST_FAIL(testName << ": method did throw exception but hits.length for search on term 'aaa' is " << result2 << " instead of expected " << result); + FAIL() << testName << ": method did throw exception but hits.length for search on term 'aaa' is " << result2 << " instead of expected " << result; } searcher->close(); reader->close(); - BOOST_TEST_MESSAGE(" count is " << result); + // std::cout << " count is " << result; if (done || result == END_COUNT) break; } - BOOST_TEST_MESSAGE(" start disk = " << startDiskUsage << "; input disk = " << inputDiskUsage << "; max used = " << dir->getMaxUsedSizeInBytes()); + // std::cout << " start disk = " << startDiskUsage << "; input disk = " << inputDiskUsage << "; max used = " << dir->getMaxUsedSizeInBytes(); if (done) { // Make sure that temp free Directory space required is at most 3X total input size of indices - BOOST_CHECK((dir->getMaxUsedSizeInBytes() - startDiskUsage) < 3 * (startDiskUsage + inputDiskUsage)); + EXPECT_TRUE((dir->getMaxUsedSizeInBytes() - startDiskUsage) < 3 * (startDiskUsage + inputDiskUsage)); } // Make sure we don't hit disk full during close below @@ -835,16 +835,16 @@ BOOST_AUTO_TEST_CASE(testAddIndexOnDiskFull) } /// Make sure IndexWriter cleans up on hitting a disk full exception in addDocument. -BOOST_AUTO_TEST_CASE(testAddDocumentOnDiskFull) +TEST_F(IndexWriterTest, testAddDocumentOnDiskFull) { for (int32_t pass = 0; pass < 2; ++pass) { - BOOST_TEST_MESSAGE("TEST: pass=" << pass); + // std::cout << "TEST: pass=" << pass; bool doAbort = (pass == 1); int64_t diskFree = 200; while (true) { - BOOST_TEST_MESSAGE("TEST: cycle: diskFree=" << diskFree); + // std::cout << "TEST: cycle: diskFree=" << diskFree; MockRAMDirectoryPtr dir = newLucene(); dir->setMaxSizeInBytes(diskFree); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -852,7 +852,7 @@ BOOST_AUTO_TEST_CASE(testAddDocumentOnDiskFull) MergeSchedulerPtr ms = writer->getMergeScheduler(); if (MiscUtils::typeOf(ms)) boost::dynamic_pointer_cast(ms)->setSuppressExceptions(); - + bool hitError = false; try { @@ -861,10 +861,10 @@ BOOST_AUTO_TEST_CASE(testAddDocumentOnDiskFull) } catch (IOException&) { - BOOST_TEST_MESSAGE("TEST: exception on addDoc"); + // std::cout << "TEST: exception on addDoc"; hitError = true; } - + if (hitError) { if (doAbort) @@ -877,12 +877,12 @@ BOOST_AUTO_TEST_CASE(testAddDocumentOnDiskFull) } catch (IOException&) { - BOOST_TEST_MESSAGE("TEST: exception on close"); + // std::cout << "TEST: exception on close"; dir->setMaxSizeInBytes(0); writer->close(); } } - + syncConcurrentMerges(ms); checkNoUnreferencedFiles(dir); @@ -906,7 +906,7 @@ BOOST_AUTO_TEST_CASE(testAddDocumentOnDiskFull) } /// Make sure we skip wicked long terms. -BOOST_AUTO_TEST_CASE(testWickedLongTerm) +TEST_F(IndexWriterTest, testWickedLongTerm) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -928,19 +928,19 @@ BOOST_AUTO_TEST_CASE(testWickedLongTerm) IndexReaderPtr reader = IndexReader::open(dir, true); // Make sure all terms < max size were indexed - BOOST_CHECK_EQUAL(2, reader->docFreq(newLucene(L"content", L"abc"))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"content", L"bbb"))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"content", L"term"))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"content", L"another"))); + EXPECT_EQ(2, reader->docFreq(newLucene(L"content", L"abc"))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"content", L"bbb"))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"content", L"term"))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"content", L"another"))); // Make sure position is still incremented when massive term is skipped TermPositionsPtr tps = reader->termPositions(newLucene(L"content", L"another")); - BOOST_CHECK(tps->next()); - BOOST_CHECK_EQUAL(1, tps->freq()); - BOOST_CHECK_EQUAL(3, tps->nextPosition()); + EXPECT_TRUE(tps->next()); + EXPECT_EQ(1, tps->freq()); + EXPECT_EQ(3, tps->nextPosition()); // Make sure the doc that has the massive term is in the index - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); reader->close(); @@ -953,19 +953,19 @@ BOOST_AUTO_TEST_CASE(testWickedLongTerm) writer->addDocument(doc); writer->close(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"content", bigTerm))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"content", bigTerm))); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testOptimizeMaxNumSegments) +TEST_F(IndexWriterTest, testOptimizeMaxNumSegments) { MockRAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED)); - + for (int32_t numDocs = 38; numDocs < 500; numDocs += 38) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -991,15 +991,15 @@ BOOST_AUTO_TEST_CASE(testOptimizeMaxNumSegments) sis = newLucene(); sis->read(dir); int32_t optSegCount = sis->size(); - + if (segCount < 3) - BOOST_CHECK_EQUAL(segCount, optSegCount); + EXPECT_EQ(segCount, optSegCount); else - BOOST_CHECK_EQUAL(3, optSegCount); + EXPECT_EQ(3, optSegCount); } } -BOOST_AUTO_TEST_CASE(testOptimizeMaxNumSegments2) +TEST_F(IndexWriterTest, testOptimizeMaxNumSegments2) { MockRAMDirectoryPtr dir = newLucene(); @@ -1012,12 +1012,12 @@ BOOST_AUTO_TEST_CASE(testOptimizeMaxNumSegments2) writer->setMergePolicy(ldmp); writer->setMergeFactor(4); writer->setMaxBufferedDocs(2); - + for (int32_t iter = 0; iter < 10; ++iter) { for (int32_t i = 0; i < 19; ++i) writer->addDocument(doc); - + writer->commit(); writer->waitForMerges(); writer->commit(); @@ -1036,14 +1036,14 @@ BOOST_AUTO_TEST_CASE(testOptimizeMaxNumSegments2) int32_t optSegCount = sis->size(); if (segCount < 7) - BOOST_CHECK_EQUAL(segCount, optSegCount); + EXPECT_EQ(segCount, optSegCount); else - BOOST_CHECK_EQUAL(7, optSegCount); + EXPECT_EQ(7, optSegCount); } } /// Make sure optimize doesn't use any more than 1X starting index size as its temporary free space required. -BOOST_AUTO_TEST_CASE(testOptimizeTempSpaceUsage) +TEST_F(IndexWriterTest, testOptimizeTempSpaceUsage) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1053,35 +1053,35 @@ BOOST_AUTO_TEST_CASE(testOptimizeTempSpaceUsage) // force one extra segment w/ different doc store so we see the doc stores get merged writer->commit(); addDocWithIndex(writer, 500); - + writer->close(); - + int64_t startDiskUsage = 0; HashSet files = dir->listAll(); for (HashSet::iterator file = files.begin(); file != files.end(); ++file) startDiskUsage += dir->fileLength(*file); - + dir->resetMaxUsedSizeInBytes(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->optimize(); writer->close(); int64_t maxDiskUsage = dir->getMaxUsedSizeInBytes(); - BOOST_CHECK(maxDiskUsage <= 4 * startDiskUsage); - + EXPECT_TRUE(maxDiskUsage <= 4 * startDiskUsage); + dir->close(); } /// Make sure we can open an index for create even when a reader holds it open (this fails pre lock-less commits on windows) -BOOST_AUTO_TEST_CASE(testCreateWithReader) +TEST_F(IndexWriterTest, testCreateWithReader) { String indexDir(FileUtils::joinPath(getTempDir(), L"lucenetestindexwriter")); - + LuceneException finally; try { DirectoryPtr dir = FSDirectory::open(indexDir); - + // add one document and close writer IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(writer); @@ -1089,17 +1089,17 @@ BOOST_AUTO_TEST_CASE(testCreateWithReader) // now open reader IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(reader->numDocs(), 1); + EXPECT_EQ(reader->numDocs(), 1); // now open index for create writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - BOOST_CHECK_EQUAL(writer->maxDoc(), 0); + EXPECT_EQ(writer->maxDoc(), 0); addDoc(writer); writer->close(); - BOOST_CHECK_EQUAL(reader->numDocs(), 1); + EXPECT_EQ(reader->numDocs(), 1); IndexReaderPtr reader2 = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(reader2->numDocs(), 1); + EXPECT_EQ(reader2->numDocs(), 1); reader->close(); reader2->close(); } @@ -1108,14 +1108,14 @@ BOOST_AUTO_TEST_CASE(testCreateWithReader) finally = e; } FileUtils::removeDirectory(indexDir); - + if (!finally.isNull()) - BOOST_FAIL(finally.getError()); + FAIL() << finally.getError(); } /// Simulate a writer that crashed while writing segments file: make sure we can still open the index (ie, /// gracefully fallback to the previous segments file), and that we can add to the index -BOOST_AUTO_TEST_CASE(testSimulatedCrashedWriter) +TEST_F(IndexWriterTest, testSimulatedCrashedWriter) { DirectoryPtr dir = newLucene(); @@ -1127,7 +1127,7 @@ BOOST_AUTO_TEST_CASE(testSimulatedCrashedWriter) writer->close(); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); - BOOST_CHECK(gen > 1); + EXPECT_TRUE(gen > 1); // Make the next segments file, with last byte missing, to simulate a writer that crashed while // writing segments file @@ -1142,10 +1142,10 @@ BOOST_AUTO_TEST_CASE(testSimulatedCrashedWriter) out->close(); IndexReaderPtr reader; - BOOST_CHECK_NO_THROW(reader = IndexReader::open(dir, true)); + EXPECT_NO_THROW(reader = IndexReader::open(dir, true)); reader->close(); - BOOST_CHECK_NO_THROW(writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); + EXPECT_NO_THROW(writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); // add 100 documents for (int32_t i = 0; i < 100; ++i) @@ -1155,7 +1155,7 @@ BOOST_AUTO_TEST_CASE(testSimulatedCrashedWriter) /// Simulate a corrupt index by removing last byte of latest segments file and make sure we get an /// IOException trying to open the index -BOOST_AUTO_TEST_CASE(testSimulatedCorruptIndex1) +TEST_F(IndexWriterTest, testSimulatedCorruptIndex1) { DirectoryPtr dir = newLucene(); @@ -1165,9 +1165,9 @@ BOOST_AUTO_TEST_CASE(testSimulatedCorruptIndex1) for (int32_t i = 0; i < 100; ++i) addDoc(writer); writer->close(); - + int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); - BOOST_CHECK(gen > 1); + EXPECT_TRUE(gen > 1); String fileNameIn = SegmentInfos::getCurrentSegmentFileName(dir); String fileNameOut = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", 1 + gen); @@ -1181,13 +1181,20 @@ BOOST_AUTO_TEST_CASE(testSimulatedCorruptIndex1) dir->deleteFile(fileNameIn); IndexReaderPtr reader; - BOOST_CHECK_EXCEPTION(reader = IndexReader::open(dir, true), IOException, check_exception(LuceneException::IO)); - + try + { + reader = IndexReader::open(dir, true); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + if (reader) reader->close(); } -BOOST_AUTO_TEST_CASE(testChangesAfterClose) +TEST_F(IndexWriterTest, testChangesAfterClose) { DirectoryPtr dir = newLucene(); @@ -1195,12 +1202,19 @@ BOOST_AUTO_TEST_CASE(testChangesAfterClose) addDoc(writer); writer->close(); - - BOOST_CHECK_EXCEPTION(addDoc(writer), AlreadyClosedException, check_exception(LuceneException::AlreadyClosed)); + + try + { + addDoc(writer); + } + catch (AlreadyClosedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } } /// Simulate a corrupt index by removing one of the cfs files and make sure we get an IOException trying to open the index -BOOST_AUTO_TEST_CASE(testSimulatedCorruptIndex2) +TEST_F(IndexWriterTest, testSimulatedCorruptIndex2) { DirectoryPtr dir = newLucene(); @@ -1210,9 +1224,9 @@ BOOST_AUTO_TEST_CASE(testSimulatedCorruptIndex2) for (int32_t i = 0; i < 100; ++i) addDoc(writer); writer->close(); - + int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); - BOOST_CHECK(gen > 1); + EXPECT_TRUE(gen > 1); HashSet files = dir->listAll(); for (HashSet::iterator file = files.begin(); file != files.end(); ++file) @@ -1223,17 +1237,24 @@ BOOST_AUTO_TEST_CASE(testSimulatedCorruptIndex2) break; } } - + IndexReaderPtr reader; - BOOST_CHECK_EXCEPTION(reader = IndexReader::open(dir, true), FileNotFoundException, check_exception(LuceneException::FileNotFound)); - + try + { + reader = IndexReader::open(dir, true); + } + catch (FileNotFoundException& e) + { + EXPECT_TRUE(check_exception(LuceneException::FileNotFound)(e)); + } + if (reader) reader->close(); } -/// Simple test for "commit on close": open writer then add a bunch of docs, making sure reader does +/// Simple test for "commit on close": open writer then add a bunch of docs, making sure reader does /// not see these docs until writer is closed. -BOOST_AUTO_TEST_CASE(testCommitOnClose) +TEST_F(IndexWriterTest, testCommitOnClose) { DirectoryPtr dir = newLucene(); @@ -1241,11 +1262,11 @@ BOOST_AUTO_TEST_CASE(testCommitOnClose) for (int32_t i = 0; i < 14; ++i) addDoc(writer); writer->close(); - - TermPtr searchTerm = newLucene(L"content", L"aaa"); + + TermPtr searchTerm = newLucene(L"content", L"aaa"); IndexSearcherPtr searcher = newLucene(dir, false); Collection hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(14, hits.size()); + EXPECT_EQ(14, hits.size()); searcher->close(); IndexReaderPtr reader = IndexReader::open(dir, true); @@ -1257,22 +1278,22 @@ BOOST_AUTO_TEST_CASE(testCommitOnClose) addDoc(writer); searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(14, hits.size()); + EXPECT_EQ(14, hits.size()); searcher->close(); - BOOST_CHECK(reader->isCurrent()); + EXPECT_TRUE(reader->isCurrent()); } - + // Now, close the writer writer->close(); - BOOST_CHECK(!reader->isCurrent()); + EXPECT_TRUE(!reader->isCurrent()); searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(47, hits.size()); + EXPECT_EQ(47, hits.size()); searcher->close(); } -BOOST_AUTO_TEST_CASE(testCommitOnCloseAbort) +TEST_F(IndexWriterTest, testCommitOnCloseAbort) { MockRAMDirectoryPtr dir = newLucene(); @@ -1281,26 +1302,26 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseAbort) for (int32_t i = 0; i < 14; ++i) addDoc(writer); writer->close(); - - TermPtr searchTerm = newLucene(L"content", L"aaa"); + + TermPtr searchTerm = newLucene(L"content", L"aaa"); IndexSearcherPtr searcher = newLucene(dir, false); Collection hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(14, hits.size()); + EXPECT_EQ(14, hits.size()); searcher->close(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); for (int32_t i = 0; i < 17; ++i) addDoc(writer); - + // Delete all docs writer->deleteDocuments(searchTerm); - + searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(14, hits.size()); + EXPECT_EQ(14, hits.size()); searcher->close(); - + // Now, close the writer writer->rollback(); @@ -1308,30 +1329,30 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseAbort) searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(14, hits.size()); + EXPECT_EQ(14, hits.size()); searcher->close(); // Now make sure we can re-open the index, add docs, and all is good writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - + // On abort, writer in fact may write to the same segments_N file dir->setPreventDoubleWrite(false); - + for (int32_t i = 0; i < 12; ++i) { for (int32_t j = 0; j < 17; ++j) addDoc(writer); searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(14, hits.size()); + EXPECT_EQ(14, hits.size()); searcher->close(); } - + writer->close(); searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(218, hits.size()); + EXPECT_EQ(218, hits.size()); searcher->close(); dir->close(); @@ -1340,7 +1361,7 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseAbort) /// Verify that a writer with "commit on close" indeed cleans up the temp segments created after opening /// that are not referenced by the starting segments file. We check this by using MockRAMDirectory to /// measure max temp disk space used. -BOOST_AUTO_TEST_CASE(testCommitOnCloseDiskUsage) +TEST_F(IndexWriterTest, testCommitOnCloseDiskUsage) { MockRAMDirectoryPtr dir = newLucene(); @@ -1350,7 +1371,7 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseDiskUsage) addDocWithIndex(writer, j); writer->close(); dir->resetMaxUsedSizeInBytes(); - + int64_t startDiskUsage = dir->getMaxUsedSizeInBytes(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); @@ -1367,15 +1388,15 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseDiskUsage) int64_t endDiskUsage = dir->getMaxUsedSizeInBytes(); // Ending index is 50X as large as starting index; due to 3X disk usage normally we allow 150X max - // transient usage. If something is wrong with deleter and it doesn't delete intermediate segments + // transient usage. If something is wrong with deleter and it doesn't delete intermediate segments // then it will exceed this 150X - BOOST_CHECK(midDiskUsage < 150 * startDiskUsage); - BOOST_CHECK(endDiskUsage < 150 * startDiskUsage); + EXPECT_TRUE(midDiskUsage < 150 * startDiskUsage); + EXPECT_TRUE(endDiskUsage < 150 * startDiskUsage); } -/// Verify that calling optimize when writer is open for "commit on close" works correctly both for +/// Verify that calling optimize when writer is open for "commit on close" works correctly both for /// rollback() and close(). -BOOST_AUTO_TEST_CASE(testCommitOnCloseOptimize) +TEST_F(IndexWriterTest, testCommitOnCloseOptimize) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1383,7 +1404,7 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseOptimize) for (int32_t j = 0; j < 17; ++j) addDocWithIndex(writer, j); writer->close(); - + writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->optimize(); @@ -1391,7 +1412,7 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseOptimize) IndexReaderPtr reader = IndexReader::open(dir, true); // Reader should see index as unoptimized at this point - BOOST_CHECK(!reader->isOptimized()); + EXPECT_TRUE(!reader->isOptimized()); reader->close(); // Abort the writer @@ -1402,7 +1423,7 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseOptimize) reader = IndexReader::open(dir, true); // Reader should still see index as unoptimized - BOOST_CHECK(!reader->isOptimized()); + EXPECT_TRUE(!reader->isOptimized()); reader->close(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); @@ -1414,11 +1435,11 @@ BOOST_AUTO_TEST_CASE(testCommitOnCloseOptimize) reader = IndexReader::open(dir, true); // Reader should still see index as unoptimized: - BOOST_CHECK(reader->isOptimized()); + EXPECT_TRUE(reader->isOptimized()); reader->close(); } -BOOST_AUTO_TEST_CASE(testIndexNoDocuments) +TEST_F(IndexWriterTest, testIndexNoDocuments) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1426,8 +1447,8 @@ BOOST_AUTO_TEST_CASE(testIndexNoDocuments) writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->maxDoc()); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->maxDoc()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); @@ -1435,12 +1456,12 @@ BOOST_AUTO_TEST_CASE(testIndexNoDocuments) writer->close(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->maxDoc()); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->maxDoc()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); } -BOOST_AUTO_TEST_CASE(testManyFields) +TEST_F(IndexWriterTest, testManyFields) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1457,25 +1478,25 @@ BOOST_AUTO_TEST_CASE(testManyFields) writer->addDocument(doc); } writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(100, reader->maxDoc()); - BOOST_CHECK_EQUAL(100, reader->numDocs()); - + EXPECT_EQ(100, reader->maxDoc()); + EXPECT_EQ(100, reader->numDocs()); + for (int32_t j = 0; j < 100; ++j) { - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"a" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"b" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"c" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"d" + StringUtils::toString(j), L"aaa"))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"e" + StringUtils::toString(j), L"aaa"))); - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"f" + StringUtils::toString(j), L"aaa"))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"a" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"b" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"c" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"d" + StringUtils::toString(j), L"aaa"))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"e" + StringUtils::toString(j), L"aaa"))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"f" + StringUtils::toString(j), L"aaa"))); } reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testSmallRAMBuffer) +TEST_F(IndexWriterTest, testSmallRAMBuffer) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1488,7 +1509,7 @@ BOOST_AUTO_TEST_CASE(testSmallRAMBuffer) writer->addDocument(doc); int32_t numFile = dir->listAll().size(); // Verify that with a tiny RAM buffer we see new segment after every doc - BOOST_CHECK(numFile > lastNumFile); + EXPECT_TRUE(numFile > lastNumFile); lastNumFile = numFile; } writer->close(); @@ -1496,13 +1517,13 @@ BOOST_AUTO_TEST_CASE(testSmallRAMBuffer) } /// Make sure it's OK to change RAM buffer size and maxBufferedDocs in a write session -BOOST_AUTO_TEST_CASE(testChangingRAMBuffer) +TEST_F(IndexWriterTest, testChangingRAMBuffer) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - + int32_t lastFlushCount = -1; for (int32_t j = 1; j < 52; ++j) { @@ -1516,18 +1537,18 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer) else if (j < 10) { // No new files should be created - BOOST_CHECK_EQUAL(flushCount, lastFlushCount); + EXPECT_EQ(flushCount, lastFlushCount); } else if (j == 10) { - BOOST_CHECK(flushCount > lastFlushCount); + EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; writer->setRAMBufferSizeMB(0.000001); writer->setMaxBufferedDocs(IndexWriter::DISABLE_AUTO_FLUSH); } else if (j < 20) { - BOOST_CHECK(flushCount > lastFlushCount); + EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; } else if (j == 20) @@ -1537,7 +1558,7 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer) lastFlushCount = flushCount; } else if (j < 30) - BOOST_CHECK_EQUAL(flushCount, lastFlushCount); + EXPECT_EQ(flushCount, lastFlushCount); else if (j == 30) { writer->setRAMBufferSizeMB(0.000001); @@ -1545,7 +1566,7 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer) } else if (j < 40) { - BOOST_CHECK(flushCount> lastFlushCount); + EXPECT_TRUE(flushCount> lastFlushCount); lastFlushCount = flushCount; } else if (j == 40) @@ -1556,32 +1577,32 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer) } else if (j < 50) { - BOOST_CHECK_EQUAL(flushCount, lastFlushCount); + EXPECT_EQ(flushCount, lastFlushCount); writer->setMaxBufferedDocs(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); } else if (j == 50) - BOOST_CHECK(flushCount > lastFlushCount); + EXPECT_TRUE(flushCount > lastFlushCount); } writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testChangingRAMBuffer2) +TEST_F(IndexWriterTest, testChangingRAMBuffer2) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); writer->setMaxBufferedDeleteTerms(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - + for (int32_t j = 1; j < 52; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + int32_t lastFlushCount = -1; for (int32_t j = 1; j < 52; ++j) { @@ -1593,18 +1614,18 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer2) else if (j < 10) { // No new files should be created - BOOST_CHECK_EQUAL(flushCount, lastFlushCount); + EXPECT_EQ(flushCount, lastFlushCount); } else if (j == 10) { - BOOST_CHECK(flushCount > lastFlushCount); + EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; writer->setRAMBufferSizeMB(0.000001); writer->setMaxBufferedDeleteTerms(1); } else if (j < 20) { - BOOST_CHECK(flushCount > lastFlushCount); + EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; } else if (j == 20) @@ -1614,7 +1635,7 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer2) lastFlushCount = flushCount; } else if (j < 30) - BOOST_CHECK_EQUAL(flushCount, lastFlushCount); + EXPECT_EQ(flushCount, lastFlushCount); else if (j == 30) { writer->setRAMBufferSizeMB(0.000001); @@ -1623,7 +1644,7 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer2) } else if (j < 40) { - BOOST_CHECK(flushCount> lastFlushCount); + EXPECT_TRUE(flushCount> lastFlushCount); lastFlushCount = flushCount; } else if (j == 40) @@ -1634,24 +1655,24 @@ BOOST_AUTO_TEST_CASE(testChangingRAMBuffer2) } else if (j < 50) { - BOOST_CHECK_EQUAL(flushCount, lastFlushCount); + EXPECT_EQ(flushCount, lastFlushCount); writer->setMaxBufferedDeleteTerms(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); } else if (j == 50) - BOOST_CHECK(flushCount > lastFlushCount); + EXPECT_TRUE(flushCount > lastFlushCount); } writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDiverseDocs) +TEST_F(IndexWriterTest, testDiverseDocs) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setRAMBufferSizeMB(0.5); RandomPtr rand = newLucene(); - + for (int32_t i = 0; i < 3; ++i) { // First, docs where every term is unique (heavy on Posting instances) @@ -1662,7 +1683,7 @@ BOOST_AUTO_TEST_CASE(testDiverseDocs) doc->add(newLucene(L"field", StringUtils::toString(rand->nextInt()), Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + // Next, many single term docs where only one term occurs (heavy on byte blocks) for (int32_t j = 0; j < 100; ++j) { @@ -1670,7 +1691,7 @@ BOOST_AUTO_TEST_CASE(testDiverseDocs) doc->add(newLucene(L"field", L"aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + // Next, many single term docs where only one term occurs but the terms are very long (heavy on char[] arrays) for (int32_t j = 0; j < 100; ++j) { @@ -1678,28 +1699,28 @@ BOOST_AUTO_TEST_CASE(testDiverseDocs) for (int32_t k = 0; k < 1000; ++k) buffer << j << L"."; String longTerm = buffer.str(); - + DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", longTerm, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } } writer->close(); - + IndexSearcherPtr searcher = newLucene(dir, false); Collection hits = searcher->search(newLucene(newLucene(L"field", L"aaa")), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(300, hits.size()); + EXPECT_EQ(300, hits.size()); searcher->close(); - + dir->close(); } -BOOST_AUTO_TEST_CASE(testEnablingNorms) +TEST_F(IndexWriterTest, testEnablingNorms) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - + // Enable norms for only 1 doc, pre flush for (int32_t j = 0; j < 10; ++j) { @@ -1716,12 +1737,12 @@ BOOST_AUTO_TEST_CASE(testEnablingNorms) IndexSearcherPtr searcher = newLucene(dir, false); Collection hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(10, hits.size()); + EXPECT_EQ(10, hits.size()); searcher->close(); writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - + // Enable norms for only 1 doc, post flush for (int32_t j = 0; j < 27; ++j) { @@ -1732,21 +1753,21 @@ BOOST_AUTO_TEST_CASE(testEnablingNorms) doc->add(f); writer->addDocument(doc); } - + writer->close(); searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(27, hits.size()); + EXPECT_EQ(27, hits.size()); searcher->close(); - + IndexReaderPtr reader = IndexReader::open(dir, true); reader->close(); - + dir->close(); } -BOOST_AUTO_TEST_CASE(testHighFreqTerm) +TEST_F(IndexWriterTest, testHighFreqTerm) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, 100000000); @@ -1766,13 +1787,13 @@ BOOST_AUTO_TEST_CASE(testHighFreqTerm) writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(1, reader->maxDoc()); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->maxDoc()); + EXPECT_EQ(1, reader->numDocs()); TermPtr t = newLucene(L"field", L"a"); - BOOST_CHECK_EQUAL(1, reader->docFreq(t)); + EXPECT_EQ(1, reader->docFreq(t)); TermDocsPtr td = reader->termDocs(t); td->next(); - BOOST_CHECK_EQUAL(128 * 1024, td->freq()); + EXPECT_EQ(128 * 1024, td->freq()); reader->close(); dir->close(); } @@ -1787,16 +1808,16 @@ namespace TestNullLockFactory lockFactory.reset(); myLockFactory = newLucene(); } - + virtual ~MyRAMDirectory() { } - + LUCENE_CLASS(MyRAMDirectory); - + protected: LockFactoryPtr myLockFactory; - + public: virtual LockPtr makeLock(const String& name) { @@ -1807,18 +1828,18 @@ namespace TestNullLockFactory /// Make sure that a Directory implementation that does not use LockFactory at all (ie overrides makeLock and /// implements its own private locking) works OK. This was raised on java-dev as loss of backwards compatibility. -BOOST_AUTO_TEST_CASE(testNullLockFactory) +TEST_F(IndexWriterTest, testNullLockFactory) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < 100; ++i) addDoc(writer); - + writer->close(); - TermPtr searchTerm = newLucene(L"content", L"aaa"); + TermPtr searchTerm = newLucene(L"content", L"aaa"); IndexSearcherPtr searcher = newLucene(dir, false); Collection hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(100, hits.size()); + EXPECT_EQ(100, hits.size()); writer->close(); writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1830,26 +1851,26 @@ BOOST_AUTO_TEST_CASE(testNullLockFactory) namespace TestFlushWithNoMerging { DECLARE_SHARED_PTR(TestableIndexWriter) - + class TestableIndexWriter : public IndexWriter { public: TestableIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { } - + virtual ~TestableIndexWriter() { } - + LUCENE_CLASS(TestableIndexWriter); - + public: using IndexWriter::flush; }; } -BOOST_AUTO_TEST_CASE(testFlushWithNoMerging) +TEST_F(IndexWriterTest, testFlushWithNoMerging) { DirectoryPtr dir = newLucene(); TestFlushWithNoMerging::TestableIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1863,11 +1884,11 @@ BOOST_AUTO_TEST_CASE(testFlushWithNoMerging) SegmentInfosPtr sis = newLucene(); sis->read(dir); // Since we flushed without allowing merging we should now have 10 segments - BOOST_CHECK_EQUAL(sis->size(), 10); + EXPECT_EQ(sis->size(), 10); } /// Make sure we can flush segment with norms, then add empty doc (no norms) and flush -BOOST_AUTO_TEST_CASE(testEmptyDocAfterFlushingRealDoc) +TEST_F(IndexWriterTest, testEmptyDocAfterFlushingRealDoc) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1879,12 +1900,12 @@ BOOST_AUTO_TEST_CASE(testEmptyDocAfterFlushingRealDoc) writer->close(); checkIndex(dir); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); } /// Test calling optimize(false) whereby optimize is kicked off but we don't wait for it to finish (but /// writer.close()) does wait -BOOST_AUTO_TEST_CASE(testBackgroundOptimize) +TEST_F(IndexWriterTest, testBackgroundOptimize) { DirectoryPtr dir = newLucene(); for (int32_t pass = 0; pass < 2; ++pass) @@ -1898,12 +1919,12 @@ BOOST_AUTO_TEST_CASE(testBackgroundOptimize) for (int32_t i = 0; i < 200; ++i) writer->addDocument(doc); writer->optimize(false); - + if (pass == 0) { writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK(reader->isOptimized()); + EXPECT_TRUE(reader->isOptimized()); reader->close(); } else @@ -1914,35 +1935,35 @@ BOOST_AUTO_TEST_CASE(testBackgroundOptimize) writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK(!reader->isOptimized()); + EXPECT_TRUE(!reader->isOptimized()); reader->close(); SegmentInfosPtr infos = newLucene(); infos->read(dir); - BOOST_CHECK_EQUAL(2, infos->size()); + EXPECT_EQ(2, infos->size()); } } dir->close(); - + // allow time for merge threads to finish LuceneThread::threadSleep(1000); } -/// Test that no NullPointerException will be raised, when adding one document with a single, empty +/// Test that no NullPointerException will be raised, when adding one document with a single, empty /// field and term vectors enabled. -BOOST_AUTO_TEST_CASE(testBadSegment) +TEST_F(IndexWriterTest, testBadSegment) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); - BOOST_CHECK_NO_THROW(doc->add(newLucene(L"tvtest", L"", Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES))); + EXPECT_NO_THROW(doc->add(newLucene(L"tvtest", L"", Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES))); writer->addDocument(doc); writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testNoTermVectorAfterTermVector) +TEST_F(IndexWriterTest, testNoTermVectorAfterTermVector) { MockRAMDirectoryPtr dir = newLucene(); @@ -1955,19 +1976,19 @@ BOOST_AUTO_TEST_CASE(testNoTermVectorAfterTermVector) writer->addDocument(doc); // Make first segment writer->commit(); - + doc->add(newLucene(L"tvtest", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); writer->addDocument(doc); - + // Make 2nd segment writer->commit(); - + writer->optimize(); writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testNoTermVectorAfterTermVectorMerge) +TEST_F(IndexWriterTest, testNoTermVectorAfterTermVectorMerge) { MockRAMDirectoryPtr dir = newLucene(); @@ -1976,22 +1997,22 @@ BOOST_AUTO_TEST_CASE(testNoTermVectorAfterTermVectorMerge) doc->add(newLucene(L"tvtest", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); writer->addDocument(doc); writer->commit(); - + doc = newLucene(); doc->add(newLucene(L"tvtest", L"x y z", Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO)); writer->addDocument(doc); // Make first segment writer->commit(); - + writer->optimize(); - + doc->add(newLucene(L"tvtest", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); writer->addDocument(doc); - + // Make 2nd segment writer->commit(); writer->optimize(); - + writer->close(); dir->close(); } @@ -2005,9 +2026,9 @@ namespace TestMaxThreadPriority virtual ~MyMergeScheduler() { } - + LUCENE_CLASS(MyMergeScheduler); - + public: virtual void merge(IndexWriterPtr writer) { @@ -2017,18 +2038,18 @@ namespace TestMaxThreadPriority if (!merge) break; for (int32_t i = 0; i < merge->segments->size(); ++i) - BOOST_CHECK(merge->segments->info(i)->docCount < 20); + EXPECT_TRUE(merge->segments->info(i)->docCount < 20); writer->merge(merge); } } - + virtual void close() { } }; } -BOOST_AUTO_TEST_CASE(testMaxThreadPriority) +TEST_F(IndexWriterTest, testMaxThreadPriority) { MockRAMDirectoryPtr dir = newLucene(); @@ -2054,16 +2075,16 @@ namespace TestExceptionFromTokenStream { count = 0; } - + virtual ~ExceptionTokenFilter() { } - + LUCENE_CLASS(ExceptionTokenFilter); - + protected: int32_t count; - + public: virtual bool incrementToken() { @@ -2072,16 +2093,16 @@ namespace TestExceptionFromTokenStream return input->incrementToken(); } }; - + class ExceptionAnalyzer : public Analyzer { public: virtual ~ExceptionAnalyzer() { } - + LUCENE_CLASS(ExceptionAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { @@ -2090,21 +2111,28 @@ namespace TestExceptionFromTokenStream }; } -BOOST_AUTO_TEST_CASE(testExceptionFromTokenStream) +TEST_F(IndexWriterTest, testExceptionFromTokenStream) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); String contents = L"aa bb cc dd ee ff gg hh ii jj kk"; doc->add(newLucene(L"content", contents, Field::STORE_NO, Field::INDEX_ANALYZED)); - - BOOST_CHECK_EXCEPTION(writer->addDocument(doc), IOException, check_exception(LuceneException::IO)); - + + try + { + writer->addDocument(doc); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + // Make sure we can add another normal document doc = newLucene(); doc->add(newLucene(L"content", L"aa bb cc dd", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); - + // Make sure we can add another normal document doc = newLucene(); doc->add(newLucene(L"content", L"aa bb cc dd", Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -2113,22 +2141,22 @@ BOOST_AUTO_TEST_CASE(testExceptionFromTokenStream) writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); TermPtr t = newLucene(L"content", L"aa"); - BOOST_CHECK_EQUAL(reader->docFreq(t), 3); + EXPECT_EQ(reader->docFreq(t), 3); // Make sure the doc that hit the exception was marked as deleted TermDocsPtr tdocs = reader->termDocs(t); int32_t count = 0; while (tdocs->next()) ++count; - - BOOST_CHECK_EQUAL(2, count); - BOOST_CHECK_EQUAL(reader->docFreq(newLucene(L"content", L"gg")), 0); + EXPECT_EQ(2, count); + + EXPECT_EQ(reader->docFreq(newLucene(L"content", L"gg")), 0); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDocumentsWriterAbort) +TEST_F(IndexWriterTest, testDocumentsWriterAbort) { MockRAMDirectoryPtr dir = newLucene(); FailOnlyOnFlushPtr failure = newLucene(); @@ -2150,14 +2178,14 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterAbort) catch (IOException&) { // only one flush should fail - BOOST_CHECK(!hitError); + EXPECT_TRUE(!hitError); hitError = true; } } - BOOST_CHECK(hitError); + EXPECT_TRUE(hitError); writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(198, reader->docFreq(newLucene(L"content", L"aa"))); + EXPECT_EQ(198, reader->docFreq(newLucene(L"content", L"aa"))); reader->close(); } @@ -2169,9 +2197,9 @@ namespace TestDocumentsWriterExceptions virtual ~CrashAnalyzer() { } - + LUCENE_CLASS(CrashAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { @@ -2180,10 +2208,10 @@ namespace TestDocumentsWriterExceptions }; } -BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptions) +TEST_F(IndexWriterTest, testDocumentsWriterExceptions) { AnalyzerPtr analyzer = newLucene(); - + for (int32_t i = 0; i < 2; ++i) { MockRAMDirectoryPtr dir = newLucene(); @@ -2194,9 +2222,16 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptions) writer->addDocument(doc); doc->add(newLucene(L"crash", L"this should crash after 4 terms", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); doc->add(newLucene(L"other", L"this will not get indexed", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - - BOOST_CHECK_EXCEPTION(writer->addDocument(doc), IOException, check_exception(LuceneException::IO)); - + + try + { + writer->addDocument(doc); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + if (i == 0) { doc = newLucene(); @@ -2205,11 +2240,11 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptions) writer->addDocument(doc); } writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, true); int32_t expected = 3 + (1 - i) * 2; - BOOST_CHECK_EQUAL(expected, reader->docFreq(newLucene(L"contents", L"here"))); - BOOST_CHECK_EQUAL(expected, reader->maxDoc()); + EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); + EXPECT_EQ(expected, reader->maxDoc()); int32_t numDel = 0; for (int32_t j = 0; j < reader->maxDoc(); ++j) { @@ -2223,7 +2258,7 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptions) } reader->close(); - BOOST_CHECK_EQUAL(1, numDel); + EXPECT_EQ(1, numDel); writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); @@ -2236,8 +2271,8 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptions) reader = IndexReader::open(dir, true); expected = 19 + (1 - i) * 2; - BOOST_CHECK_EQUAL(expected, reader->docFreq(newLucene(L"contents", L"here"))); - BOOST_CHECK_EQUAL(expected, reader->maxDoc()); + EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); + EXPECT_EQ(expected, reader->maxDoc()); numDel = 0; for (int32_t j = 0; j < reader->maxDoc(); ++j) { @@ -2250,7 +2285,7 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptions) } } reader->close(); - BOOST_CHECK_EQUAL(0, numDel); + EXPECT_EQ(0, numDel); dir->close(); } @@ -2264,16 +2299,16 @@ namespace TestDocumentsWriterExceptionThreads virtual ~CrashAnalyzer() { } - + LUCENE_CLASS(CrashAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(fieldName, newLucene(reader)); } }; - + class ExceptionThread : public LuceneThread { public: @@ -2283,18 +2318,18 @@ namespace TestDocumentsWriterExceptionThreads this->numIter = numIter; this->finalI = finalI; } - + virtual ~ExceptionThread() { } - + LUCENE_CLASS(ExceptionThread); - + protected: IndexWriterPtr writer; int32_t numIter; int32_t finalI; - + public: virtual void run() { @@ -2312,12 +2347,12 @@ namespace TestDocumentsWriterExceptionThreads try { writer->addDocument(doc); - BOOST_FAIL("did not hit expected exception"); + FAIL() << "did not hit expected exception"; } catch (IOException&) { } - + if (finalI == 0) { doc = newLucene(); @@ -2329,44 +2364,44 @@ namespace TestDocumentsWriterExceptionThreads } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; } -BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptionThreads) +TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) { AnalyzerPtr analyzer = newLucene(); - + int32_t NUM_THREAD = 3; int32_t NUM_ITER = 100; - + for (int32_t i = 0; i < 2; ++i) { MockRAMDirectoryPtr dir = newLucene(); - + { IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); int32_t finalI = i; - + Collection threads = Collection::newInstance(NUM_THREAD); for (int32_t t = 0; t < NUM_THREAD; ++t) { threads[t] = newLucene(writer, NUM_ITER, finalI); threads[t]->start(); } - + for (int32_t t = 0; t < NUM_THREAD; ++t) threads[t]->join(); - + writer->close(); } - + IndexReaderPtr reader = IndexReader::open(dir, true); int32_t expected = (3 + (1 - i) * 2) * NUM_THREAD * NUM_ITER; - BOOST_CHECK_EQUAL(expected, reader->docFreq(newLucene(L"contents", L"here"))); - BOOST_CHECK_EQUAL(expected, reader->maxDoc()); + EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); + EXPECT_EQ(expected, reader->maxDoc()); int32_t numDel = 0; for (int32_t j = 0; j < reader->maxDoc(); ++j) { @@ -2380,7 +2415,7 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptionThreads) } reader->close(); - BOOST_CHECK_EQUAL(NUM_THREAD * NUM_ITER, numDel); + EXPECT_EQ(NUM_THREAD * NUM_ITER, numDel); IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); @@ -2393,8 +2428,8 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptionThreads) reader = IndexReader::open(dir, true); expected += 17 - NUM_THREAD * NUM_ITER; - BOOST_CHECK_EQUAL(expected, reader->docFreq(newLucene(L"contents", L"here"))); - BOOST_CHECK_EQUAL(expected, reader->maxDoc()); + EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); + EXPECT_EQ(expected, reader->maxDoc()); numDel = 0; for (int32_t j = 0; j < reader->maxDoc(); ++j) { @@ -2407,17 +2442,17 @@ BOOST_AUTO_TEST_CASE(testDocumentsWriterExceptionThreads) } } reader->close(); - BOOST_CHECK_EQUAL(0, numDel); + EXPECT_EQ(0, numDel); dir->close(); } } -BOOST_AUTO_TEST_CASE(testVariableSchema) +TEST_F(IndexWriterTest, testVariableSchema) { MockRAMDirectoryPtr dir = newLucene(); int32_t delID = 0; - + for (int32_t i = 0; i < 20; ++i) { IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -2426,7 +2461,7 @@ BOOST_AUTO_TEST_CASE(testVariableSchema) writer->setUseCompoundFile(false); DocumentPtr doc = newLucene(); String contents = L"aa bb cc dd ee ff gg hh ii jj kk"; - + if (i == 7) { // Add empty docs here @@ -2445,15 +2480,15 @@ BOOST_AUTO_TEST_CASE(testVariableSchema) doc->add(newLucene(L"content3", L"", Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(L"content5", L"", storeVal, Field::INDEX_ANALYZED)); } - + for (int32_t j = 0; j < 4; ++j) writer->addDocument(doc); - + writer->close(); IndexReaderPtr reader = IndexReader::open(dir, false); reader->deleteDocument(delID++); reader->close(); - + if (i % 4 == 0) { writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -2474,17 +2509,17 @@ namespace TestNoWaitClose this->finalWriter = finalWriter; this->doc = doc; } - + virtual ~NoWaitThread() { } - + LUCENE_CLASS(NoWaitThread); - + protected: IndexWriterPtr finalWriter; DocumentPtr doc; - + public: virtual void run() { @@ -2509,7 +2544,7 @@ namespace TestNoWaitClose } catch (...) { - BOOST_FAIL("Unexpected exception"); + FAIL() << "Unexpected exception"; done = true; break; } @@ -2520,18 +2555,18 @@ namespace TestNoWaitClose }; } -BOOST_AUTO_TEST_CASE(testNoWaitClose) +TEST_F(IndexWriterTest, testNoWaitClose) { MockRAMDirectoryPtr dir = newLucene(); - + DocumentPtr doc = newLucene(); FieldPtr idField = newLucene(L"id", L"", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); doc->add(idField); - + for (int32_t pass = 0; pass < 2; ++pass) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + for (int32_t iter = 0; iter < 10; ++iter) { MergeSchedulerPtr ms; @@ -2539,24 +2574,24 @@ BOOST_AUTO_TEST_CASE(testNoWaitClose) ms = newLucene(); else ms = newLucene(); - + writer->setMergeScheduler(ms); writer->setMaxBufferedDocs(2); writer->setMergeFactor(100); - + for (int32_t j = 0; j < 199; ++j) { idField->setValue(StringUtils::toString(iter * 201 + j)); writer->addDocument(doc); } - + int32_t delID = iter * 199; for (int32_t j = 0; j < 20; ++j) { writer->deleteDocuments(newLucene(L"id", StringUtils::toString(delID))); delID += 5; } - + // Force a bunch of merge threads to kick off so we stress out aborting them on close writer->setMergeFactor(2); @@ -2581,16 +2616,16 @@ BOOST_AUTO_TEST_CASE(testNoWaitClose) } /// Make sure we can close() even while threads are trying to add documents. -BOOST_AUTO_TEST_CASE(testCloseWithThreads) +TEST_F(IndexWriterTest, testCloseWithThreads) { int32_t NUM_THREADS = 3; - + for (int32_t iter = 0; iter < 20; ++iter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); ConcurrentMergeSchedulerPtr cms = newLucene(); - + // We expect AlreadyClosedException cms->setSuppressExceptions(); @@ -2599,13 +2634,13 @@ BOOST_AUTO_TEST_CASE(testCloseWithThreads) writer->setMergeFactor(4); Collection threads = Collection::newInstance(NUM_THREADS); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i] = newLucene(writer, false); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->start(); - + bool done = false; while (!done) { @@ -2620,24 +2655,24 @@ BOOST_AUTO_TEST_CASE(testCloseWithThreads) } } } - + writer->close(false); - + // Make sure threads that are adding docs are not hung for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); if (threads[i]->isAlive()) - BOOST_FAIL("thread seems to be hung"); + FAIL() << "thread seems to be hung"; } - + // Quick test to make sure index is not corrupt IndexReaderPtr reader = IndexReader::open(dir, true); TermDocsPtr tdocs = reader->termDocs(newLucene(L"field", L"aaa")); int32_t count = 0; while (tdocs->next()) ++count; - BOOST_CHECK(count > 0); + EXPECT_TRUE(count > 0); reader->close(); dir->close(); @@ -2645,7 +2680,7 @@ BOOST_AUTO_TEST_CASE(testCloseWithThreads) } /// Make sure immediate disk full on creating an IndexWriter (hit during DW.ThreadState.init()) is OK -BOOST_AUTO_TEST_CASE(testImmediateDiskFull) +TEST_F(IndexWriterTest, testImmediateDiskFull) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -2653,23 +2688,44 @@ BOOST_AUTO_TEST_CASE(testImmediateDiskFull) writer->setMaxBufferedDocs(2); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa bbb ccc ddd eee fff ggg hhh iii jjj", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - BOOST_CHECK_EXCEPTION(writer->addDocument(doc), IOException, check_exception(LuceneException::IO)); - BOOST_CHECK_EXCEPTION(writer->addDocument(doc), IOException, check_exception(LuceneException::IO)); - BOOST_CHECK_EXCEPTION(writer->close(false), IOException, check_exception(LuceneException::IO)); + try + { + writer->addDocument(doc); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + try + { + writer->addDocument(doc); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + try + { + writer->close(false); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } } -/// Make sure immediate disk full on creating an IndexWriter (hit during DW.ThreadState.init()), +/// Make sure immediate disk full on creating an IndexWriter (hit during DW.ThreadState.init()), /// with multiple threads, is OK -BOOST_AUTO_TEST_CASE(testImmediateDiskFullWithThreads) +TEST_F(IndexWriterTest, testImmediateDiskFullWithThreads) { int32_t NUM_THREADS = 3; - + for (int32_t iter = 0; iter < 10; ++iter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); ConcurrentMergeSchedulerPtr cms = newLucene(); - + // We expect AlreadyClosedException cms->setSuppressExceptions(); @@ -2677,18 +2733,18 @@ BOOST_AUTO_TEST_CASE(testImmediateDiskFullWithThreads) writer->setMaxBufferedDocs(2); writer->setMergeFactor(4); dir->setMaxSizeInBytes(4 * 1024 + 20 * iter); - + Collection threads = Collection::newInstance(NUM_THREADS); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i] = newLucene(writer, true); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->start(); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->join(); - + try { writer->close(false); @@ -2696,10 +2752,10 @@ BOOST_AUTO_TEST_CASE(testImmediateDiskFullWithThreads) catch (IOException&) { } - + // allow time for merge threads to finish LuceneThread::threadSleep(1000); - + dir->close(); } } @@ -2714,7 +2770,7 @@ static void _testSingleThreadFailure(MockDirectoryFailurePtr failure) for (int32_t i = 0; i < 6; ++i) writer->addDocument(doc); - + dir->failOn(failure); failure->setDoFail(); try @@ -2722,7 +2778,7 @@ static void _testSingleThreadFailure(MockDirectoryFailurePtr failure) writer->addDocument(doc); writer->addDocument(doc); writer->commit(); - BOOST_FAIL("did not hit exception"); + FAIL() << "did not hit exception"; } catch (IOException&) { @@ -2735,38 +2791,38 @@ static void _testSingleThreadFailure(MockDirectoryFailurePtr failure) static void _testMultipleThreadsFailure(MockDirectoryFailurePtr failure) { int32_t NUM_THREADS = 3; - + for (int32_t iter = 0; iter < 5; ++iter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); ConcurrentMergeSchedulerPtr cms = newLucene(); - + // We expect disk full exceptions in the merge threads cms->setSuppressExceptions(); writer->setMergeScheduler(cms); writer->setMaxBufferedDocs(2); writer->setMergeFactor(4); - + Collection threads = Collection::newInstance(NUM_THREADS); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i] = newLucene(writer, true); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->start(); - + LuceneThread::threadSleep(10); - + dir->failOn(failure); failure->setDoFail(); - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->join(); - + bool success = false; - + try { writer->close(false); @@ -2777,7 +2833,7 @@ static void _testMultipleThreadsFailure(MockDirectoryFailurePtr failure) failure->clearDoFail(); writer->close(false); } - + if (success) { IndexReaderPtr reader = IndexReader::open(dir, true); @@ -2791,90 +2847,90 @@ static void _testMultipleThreadsFailure(MockDirectoryFailurePtr failure) } reader->close(); } - + // allow time for merge threads to finish LuceneThread::threadSleep(1000); - + dir->close(); } } /// Make sure initial IOException, and then 2nd IOException during rollback(), is OK -BOOST_AUTO_TEST_CASE(testIOExceptionDuringAbort) +TEST_F(IndexWriterTest, testIOExceptionDuringAbort) { _testSingleThreadFailure(newLucene(false)); } /// Make sure initial IOException, and then 2nd IOException during rollback(), is OK -BOOST_AUTO_TEST_CASE(testIOExceptionDuringAbortOnlyOnce) +TEST_F(IndexWriterTest, testIOExceptionDuringAbortOnlyOnce) { _testSingleThreadFailure(newLucene(true)); } -/// Make sure initial IOException, and then 2nd IOException during rollback(), with +/// Make sure initial IOException, and then 2nd IOException during rollback(), with /// multiple threads, is OK -BOOST_AUTO_TEST_CASE(testIOExceptionDuringAbortWithThreads) +TEST_F(IndexWriterTest, testIOExceptionDuringAbortWithThreads) { _testMultipleThreadsFailure(newLucene(false)); } -/// Make sure initial IOException, and then 2nd IOException during rollback(), with +/// Make sure initial IOException, and then 2nd IOException during rollback(), with /// multiple threads, is OK -BOOST_AUTO_TEST_CASE(testIOExceptionDuringAbortWithThreadsOnlyOnce) +TEST_F(IndexWriterTest, testIOExceptionDuringAbortWithThreadsOnlyOnce) { _testMultipleThreadsFailure(newLucene(true)); } /// Test IOException in closeDocStore -BOOST_AUTO_TEST_CASE(testIOExceptionDuringCloseDocStore) +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStore) { _testSingleThreadFailure(newLucene(false)); } /// Test IOException in closeDocStore -BOOST_AUTO_TEST_CASE(testIOExceptionDuringCloseDocStoreOnlyOnce) +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreOnlyOnce) { _testSingleThreadFailure(newLucene(true)); } /// Test IOException in closeDocStore, with threads -BOOST_AUTO_TEST_CASE(testIOExceptionDuringCloseDocStoreWithThreads) +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreWithThreads) { _testMultipleThreadsFailure(newLucene(false)); } /// Test IOException in closeDocStore, with threads -BOOST_AUTO_TEST_CASE(testIOExceptionDuringCloseDocStoreWithThreadsOnlyOnce) +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreWithThreadsOnlyOnce) { _testMultipleThreadsFailure(newLucene(true)); } /// Test IOException in writeSegment -BOOST_AUTO_TEST_CASE(testIOExceptionDuringWriteSegment) +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegment) { _testSingleThreadFailure(newLucene(false)); } /// Test IOException in writeSegment -BOOST_AUTO_TEST_CASE(testIOExceptionDuringWriteSegmentOnlyOnce) +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentOnlyOnce) { _testSingleThreadFailure(newLucene(true)); } /// Test IOException in writeSegment, with threads -BOOST_AUTO_TEST_CASE(testIOExceptionDuringWriteSegmentWithThreads) +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentWithThreads) { _testMultipleThreadsFailure(newLucene(false)); } /// Test IOException in writeSegment, with threads -BOOST_AUTO_TEST_CASE(testIOExceptionDuringWriteSegmentWithThreadsOnlyOnce) +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentWithThreadsOnlyOnce) { _testMultipleThreadsFailure(newLucene(true)); } /// Test unlimited field length -BOOST_AUTO_TEST_CASE(testUnlimitedMaxFieldLength) +TEST_F(IndexWriterTest, testUnlimitedMaxFieldLength) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -2886,27 +2942,27 @@ BOOST_AUTO_TEST_CASE(testUnlimitedMaxFieldLength) doc->add(newLucene(L"field", buffer.str(), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, true); TermPtr t = newLucene(L"field", L"x"); - BOOST_CHECK_EQUAL(1, reader->docFreq(t)); + EXPECT_EQ(1, reader->docFreq(t)); reader->close(); dir->close(); } /// Simulate checksum error in segments_N -BOOST_AUTO_TEST_CASE(testSegmentsChecksumError) +TEST_F(IndexWriterTest, testSegmentsChecksumError) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - + // add 100 documents for (int32_t i = 0; i < 100; ++i) addDoc(writer); writer->close(); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); - BOOST_CHECK(gen > 1); + EXPECT_TRUE(gen > 1); String segmentsFileName = SegmentInfos::getCurrentSegmentFileName(dir); IndexInputPtr in = dir->openInput(segmentsFileName); @@ -2916,82 +2972,91 @@ BOOST_AUTO_TEST_CASE(testSegmentsChecksumError) out->writeByte((uint8_t)(1 + b)); out->close(); in->close(); - + IndexReaderPtr reader; - BOOST_CHECK_NO_THROW(reader = IndexReader::open(dir, true)); + EXPECT_NO_THROW(reader = IndexReader::open(dir, true)); reader->close(); } /// Test writer.commit() when ac=false -BOOST_AUTO_TEST_CASE(testForceCommit) +TEST_F(IndexWriterTest, testForceCommit) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(5); - + for (int32_t i = 0; i < 23; ++i) addDoc(writer); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); writer->commit(); IndexReaderPtr reader2 = reader->reopen(); - BOOST_CHECK_EQUAL(0, reader->numDocs()); - BOOST_CHECK_EQUAL(23, reader2->numDocs()); + EXPECT_EQ(0, reader->numDocs()); + EXPECT_EQ(23, reader2->numDocs()); reader->close(); - + for (int32_t i = 0; i < 17; ++i) addDoc(writer); - BOOST_CHECK_EQUAL(23, reader2->numDocs()); + EXPECT_EQ(23, reader2->numDocs()); reader2->close(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(23, reader->numDocs()); + EXPECT_EQ(23, reader->numDocs()); reader->close(); writer->commit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(40, reader->numDocs()); + EXPECT_EQ(40, reader->numDocs()); reader->close(); writer->close(); dir->close(); } /// Test exception during sync -BOOST_AUTO_TEST_CASE(testExceptionDuringSync) +TEST_F(IndexWriterTest, testExceptionDuringSync) { MockRAMDirectoryPtr dir = newLucene(); FailOnlyInSyncPtr failure = newLucene(); dir->failOn(failure); - + IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); failure->setDoFail(); ConcurrentMergeSchedulerPtr cms = newLucene(); cms->setSuppressExceptions(); writer->setMergeScheduler(cms); - + writer->setMaxBufferedDocs(2); writer->setMergeFactor(5); - + for (int32_t i = 0; i < 23; ++i) { addDoc(writer); if ((i - 1) % 2 == 0) - BOOST_CHECK_EXCEPTION(writer->commit(), IOException, check_exception(LuceneException::IO)); + { + try + { + writer->commit(); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + } } - + cms->sync(); - BOOST_CHECK(failure->didFail); + EXPECT_TRUE(failure->didFail); failure->clearDoFail(); writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(23, reader->numDocs()); + EXPECT_EQ(23, reader->numDocs()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testTermVectorCorruption) +TEST_F(IndexWriterTest, testTermVectorCorruption) { DirectoryPtr dir = newLucene(); for (int32_t iter = 0; iter < 2; ++iter) @@ -3003,7 +3068,7 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption) writer->setMergePolicy(newLucene(writer)); DocumentPtr document = newLucene(); - + FieldPtr storedField = newLucene(L"stored", L"stored", Field::STORE_YES, Field::INDEX_NO); document->add(storedField); writer->addDocument(document); @@ -3039,7 +3104,7 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption) dir->close(); } -BOOST_AUTO_TEST_CASE(testTermVectorCorruption2) +TEST_F(IndexWriterTest, testTermVectorCorruption2) { DirectoryPtr dir = newLucene(); for (int32_t iter = 0; iter < 2; ++iter) @@ -3051,7 +3116,7 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption2) writer->setMergePolicy(newLucene(writer)); DocumentPtr document = newLucene(); - + FieldPtr storedField = newLucene(L"stored", L"stored", Field::STORE_YES, Field::INDEX_NO); document->add(storedField); writer->addDocument(document); @@ -3067,15 +3132,15 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption2) writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK(!reader->getTermFreqVectors(0)); - BOOST_CHECK(!reader->getTermFreqVectors(1)); - BOOST_CHECK(reader->getTermFreqVectors(2)); + EXPECT_TRUE(!reader->getTermFreqVectors(0)); + EXPECT_TRUE(!reader->getTermFreqVectors(1)); + EXPECT_TRUE(reader->getTermFreqVectors(2)); reader->close(); } dir->close(); } -BOOST_AUTO_TEST_CASE(testTermVectorCorruption3) +TEST_F(IndexWriterTest, testTermVectorCorruption3) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -3085,7 +3150,7 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption3) writer->setMergePolicy(newLucene(writer)); DocumentPtr document = newLucene(); - + FieldPtr storedField = newLucene(L"stored", L"stored", Field::STORE_YES, Field::INDEX_NO); document->add(storedField); @@ -3095,7 +3160,7 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption3) for (int32_t i = 0; i < 10; ++i) writer->addDocument(document); writer->close(); - + writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); @@ -3103,7 +3168,7 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption3) writer->setMergePolicy(newLucene(writer)); for (int32_t i = 0; i < 6; ++i) writer->addDocument(document); - + writer->optimize(); writer->close(); @@ -3118,11 +3183,11 @@ BOOST_AUTO_TEST_CASE(testTermVectorCorruption3) } /// Test user-specified field length -BOOST_AUTO_TEST_CASE(testUserSpecifiedMaxFieldLength) +TEST_F(IndexWriterTest, testUserSpecifiedMaxFieldLength) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), 100000); - + DocumentPtr doc = newLucene(); StringStream buffer; for (int32_t i = 0; i < 10000; ++i) @@ -3131,144 +3196,144 @@ BOOST_AUTO_TEST_CASE(testUserSpecifiedMaxFieldLength) doc->add(newLucene(L"field", buffer.str(), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, true); TermPtr t = newLucene(L"field", L"x"); - BOOST_CHECK_EQUAL(1, reader->docFreq(t)); + EXPECT_EQ(1, reader->docFreq(t)); reader->close(); dir->close(); } /// Test expungeDeletes, when 2 singular merges are required -BOOST_AUTO_TEST_CASE(testExpungeDeletes) +TEST_F(IndexWriterTest, testExpungeDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - + DocumentPtr document = newLucene(); - + FieldPtr storedField = newLucene(L"stored", L"stored", Field::STORE_YES, Field::INDEX_NO); document->add(storedField); FieldPtr termVectorField = newLucene(L"termVector", L"termVector", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); document->add(termVectorField); - + for (int32_t i = 0; i < 10; ++i) writer->addDocument(document); writer->close(); IndexReaderPtr ir = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(10, ir->maxDoc()); - BOOST_CHECK_EQUAL(10, ir->numDocs()); + EXPECT_EQ(10, ir->maxDoc()); + EXPECT_EQ(10, ir->numDocs()); ir->deleteDocument(0); ir->deleteDocument(7); - BOOST_CHECK_EQUAL(8, ir->numDocs()); + EXPECT_EQ(8, ir->numDocs()); ir->close(); - + writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); - - BOOST_CHECK_EQUAL(8, writer->numDocs()); - BOOST_CHECK_EQUAL(10, writer->maxDoc()); + + EXPECT_EQ(8, writer->numDocs()); + EXPECT_EQ(10, writer->maxDoc()); writer->expungeDeletes(); - BOOST_CHECK_EQUAL(8, writer->numDocs()); + EXPECT_EQ(8, writer->numDocs()); writer->close(); ir = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(8, ir->maxDoc()); - BOOST_CHECK_EQUAL(8, ir->numDocs()); + EXPECT_EQ(8, ir->maxDoc()); + EXPECT_EQ(8, ir->numDocs()); ir->close(); dir->close(); } /// Test expungeDeletes, when many adjacent merges are required -BOOST_AUTO_TEST_CASE(testExpungeDeletes2) +TEST_F(IndexWriterTest, testExpungeDeletes2) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(50); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - + DocumentPtr document = newLucene(); - + FieldPtr storedField = newLucene(L"stored", L"stored", Field::STORE_YES, Field::INDEX_NO); document->add(storedField); FieldPtr termVectorField = newLucene(L"termVector", L"termVector", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); document->add(termVectorField); - + for (int32_t i = 0; i < 98; ++i) writer->addDocument(document); writer->close(); IndexReaderPtr ir = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(98, ir->maxDoc()); - BOOST_CHECK_EQUAL(98, ir->numDocs()); + EXPECT_EQ(98, ir->maxDoc()); + EXPECT_EQ(98, ir->numDocs()); for (int32_t i = 0; i < 98; i += 2) ir->deleteDocument(i); - BOOST_CHECK_EQUAL(49, ir->numDocs()); + EXPECT_EQ(49, ir->numDocs()); ir->close(); - + writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); - + writer->setMergeFactor(3); - BOOST_CHECK_EQUAL(49, writer->numDocs()); + EXPECT_EQ(49, writer->numDocs()); writer->expungeDeletes(); writer->close(); ir = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(49, ir->maxDoc()); - BOOST_CHECK_EQUAL(49, ir->numDocs()); + EXPECT_EQ(49, ir->maxDoc()); + EXPECT_EQ(49, ir->numDocs()); ir->close(); dir->close(); } /// Test expungeDeletes without waiting, when many adjacent merges are required -BOOST_AUTO_TEST_CASE(testExpungeDeletes3) +TEST_F(IndexWriterTest, testExpungeDeletes3) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(50); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - + DocumentPtr document = newLucene(); - + FieldPtr storedField = newLucene(L"stored", L"stored", Field::STORE_YES, Field::INDEX_NO); document->add(storedField); FieldPtr termVectorField = newLucene(L"termVector", L"termVector", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); document->add(termVectorField); - + for (int32_t i = 0; i < 98; ++i) writer->addDocument(document); writer->close(); IndexReaderPtr ir = IndexReader::open(dir, false); - BOOST_CHECK_EQUAL(98, ir->maxDoc()); - BOOST_CHECK_EQUAL(98, ir->numDocs()); + EXPECT_EQ(98, ir->maxDoc()); + EXPECT_EQ(98, ir->numDocs()); for (int32_t i = 0; i < 98; i += 2) ir->deleteDocument(i); - BOOST_CHECK_EQUAL(49, ir->numDocs()); + EXPECT_EQ(49, ir->numDocs()); ir->close(); - + writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); - + writer->setMergeFactor(3); writer->expungeDeletes(false); writer->close(); ir = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(49, ir->maxDoc()); - BOOST_CHECK_EQUAL(49, ir->numDocs()); + EXPECT_EQ(49, ir->maxDoc()); + EXPECT_EQ(49, ir->numDocs()); ir->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEmptyFieldName) +TEST_F(IndexWriterTest, testEmptyFieldName) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); - + DocumentPtr doc = newLucene(); doc->add(newLucene(L"", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -3278,7 +3343,7 @@ BOOST_AUTO_TEST_CASE(testEmptyFieldName) namespace TestExceptionDocumentsWriterInit { DECLARE_SHARED_PTR(MockIndexWriter) - + class MockIndexWriter : public IndexWriter { public: @@ -3286,16 +3351,16 @@ namespace TestExceptionDocumentsWriterInit { doFail = false; } - + virtual ~MockIndexWriter() { } - + LUCENE_CLASS(MockIndexWriter); - + public: bool doFail; - + public: virtual bool testPoint(const String& name) { @@ -3306,7 +3371,7 @@ namespace TestExceptionDocumentsWriterInit }; } -BOOST_AUTO_TEST_CASE(testExceptionDocumentsWriterInit) +TEST_F(IndexWriterTest, testExceptionDocumentsWriterInit) { MockRAMDirectoryPtr dir = newLucene(); TestExceptionDocumentsWriterInit::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -3314,7 +3379,14 @@ BOOST_AUTO_TEST_CASE(testExceptionDocumentsWriterInit) doc->add(newLucene(L"field", L"a field", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); writer->doFail = true; - BOOST_CHECK_EXCEPTION(writer->addDocument(doc), RuntimeException, check_exception(LuceneException::Runtime)); + try + { + writer->addDocument(doc); + } + catch (RuntimeException& e) + { + EXPECT_TRUE(check_exception(LuceneException::Runtime)(e)); + } writer->close(); checkIndex(dir); dir->close(); @@ -3323,7 +3395,7 @@ BOOST_AUTO_TEST_CASE(testExceptionDocumentsWriterInit) namespace TestExceptionJustBeforeFlush { DECLARE_SHARED_PTR(MockIndexWriter) - + class MockIndexWriter : public IndexWriter { public: @@ -3331,16 +3403,16 @@ namespace TestExceptionJustBeforeFlush { doFail = false; } - + virtual ~MockIndexWriter() { } - + LUCENE_CLASS(MockIndexWriter); - + public: bool doFail; - + public: virtual bool testPoint(const String& name) { @@ -3349,16 +3421,16 @@ namespace TestExceptionJustBeforeFlush return true; } }; - + class CrashAnalyzer : public Analyzer { public: virtual ~CrashAnalyzer() { } - + LUCENE_CLASS(CrashAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { @@ -3367,21 +3439,28 @@ namespace TestExceptionJustBeforeFlush }; } -BOOST_AUTO_TEST_CASE(testExceptionJustBeforeFlush) +TEST_F(IndexWriterTest, testExceptionJustBeforeFlush) { MockRAMDirectoryPtr dir = newLucene(); TestExceptionJustBeforeFlush::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); - + DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"a field", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); - + AnalyzerPtr analyzer = newLucene(); DocumentPtr crashDoc = newLucene(); crashDoc->add(newLucene(L"crash", L"do it on token 4", Field::STORE_YES, Field::INDEX_ANALYZED)); - - BOOST_CHECK_EXCEPTION(writer->addDocument(crashDoc, analyzer), IOException, check_exception(LuceneException::IO)); + + try + { + writer->addDocument(crashDoc, analyzer); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } writer->addDocument(doc); writer->close(); dir->close(); @@ -3390,7 +3469,7 @@ BOOST_AUTO_TEST_CASE(testExceptionJustBeforeFlush) namespace TestExceptionOnMergeInit { DECLARE_SHARED_PTR(MockIndexWriter) - + class MockIndexWriter : public IndexWriter { public: @@ -3399,17 +3478,17 @@ namespace TestExceptionOnMergeInit doFail = false; failed = false; } - + virtual ~MockIndexWriter() { } - + LUCENE_CLASS(MockIndexWriter); - + public: bool doFail; bool failed; - + public: virtual bool testPoint(const String& name) { @@ -3423,7 +3502,7 @@ namespace TestExceptionOnMergeInit }; } -BOOST_AUTO_TEST_CASE(testExceptionOnMergeInit) +TEST_F(IndexWriterTest, testExceptionOnMergeInit) { MockRAMDirectoryPtr dir = newLucene(); TestExceptionOnMergeInit::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -3445,7 +3524,7 @@ BOOST_AUTO_TEST_CASE(testExceptionOnMergeInit) } } boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); - BOOST_CHECK(writer->failed); + EXPECT_TRUE(writer->failed); writer->close(); dir->close(); } @@ -3453,7 +3532,7 @@ BOOST_AUTO_TEST_CASE(testExceptionOnMergeInit) namespace TestDoBeforeAfterFlush { DECLARE_SHARED_PTR(MockIndexWriter) - + class MockIndexWriter : public IndexWriter { public: @@ -3462,23 +3541,23 @@ namespace TestDoBeforeAfterFlush afterWasCalled = false; beforeWasCalled = false; } - + virtual ~MockIndexWriter() { } - + LUCENE_CLASS(MockIndexWriter); - + public: bool afterWasCalled; bool beforeWasCalled; - + protected: virtual void doAfterFlush() { afterWasCalled = true; } - + virtual void doBeforeFlush() { beforeWasCalled = true; @@ -3486,7 +3565,7 @@ namespace TestDoBeforeAfterFlush }; } -BOOST_AUTO_TEST_CASE(testDoBeforeAfterFlush) +TEST_F(IndexWriterTest, testDoBeforeAfterFlush) { MockRAMDirectoryPtr dir = newLucene(); TestDoBeforeAfterFlush::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -3494,25 +3573,25 @@ BOOST_AUTO_TEST_CASE(testDoBeforeAfterFlush) doc->add(newLucene(L"field", L"a field", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); writer->commit(); - BOOST_CHECK(writer->beforeWasCalled); - BOOST_CHECK(writer->afterWasCalled); + EXPECT_TRUE(writer->beforeWasCalled); + EXPECT_TRUE(writer->afterWasCalled); writer->beforeWasCalled = false; writer->afterWasCalled = false; writer->deleteDocuments(newLucene(L"field", L"field")); writer->commit(); - BOOST_CHECK(writer->beforeWasCalled); - BOOST_CHECK(writer->afterWasCalled); + EXPECT_TRUE(writer->beforeWasCalled); + EXPECT_TRUE(writer->afterWasCalled); writer->close(); IndexReaderPtr ir = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(1, ir->maxDoc()); - BOOST_CHECK_EQUAL(0, ir->numDocs()); + EXPECT_EQ(1, ir->maxDoc()); + EXPECT_EQ(0, ir->numDocs()); ir->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testExceptionsDuringCommit) +TEST_F(IndexWriterTest, testExceptionsDuringCommit) { MockRAMDirectoryPtr dir = newLucene(); FailOnlyInCommitPtr failure = newLucene(); @@ -3521,8 +3600,15 @@ BOOST_AUTO_TEST_CASE(testExceptionsDuringCommit) doc->add(newLucene(L"field", L"a field", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); dir->failOn(failure); - BOOST_CHECK_EXCEPTION(writer->close(), RuntimeException, check_exception(LuceneException::Runtime)); - BOOST_CHECK(failure->fail1 && failure->fail2); + try + { + writer->close(); + } + catch (RuntimeException& e) + { + EXPECT_TRUE(check_exception(LuceneException::Runtime)(e)); + } + EXPECT_TRUE(failure->fail1 && failure->fail2); writer->rollback(); dir->close(); } @@ -3540,18 +3626,18 @@ namespace TestNegativePositions tokenIter = tokens.begin(); first = true; } - + virtual ~NegativeTokenStream() { } - + public: TermAttributePtr termAtt; PositionIncrementAttributePtr posIncrAtt; Collection tokens; Collection::iterator tokenIter; bool first; - + public: virtual bool incrementToken() { @@ -3566,7 +3652,7 @@ namespace TestNegativePositions }; } -BOOST_AUTO_TEST_CASE(testNegativePositions) +TEST_F(IndexWriterTest, testNegativePositions) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -3582,23 +3668,23 @@ BOOST_AUTO_TEST_CASE(testNegativePositions) pq->add(newLucene(L"field", L"b")); pq->add(newLucene(L"field", L"c")); Collection hits = s->search(pq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryPtr q = newLucene(newLucene(L"field", L"a")); hits = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); TermPositionsPtr tps = s->getIndexReader()->termPositions(newLucene(L"field", L"a")); - BOOST_CHECK(tps->next()); - BOOST_CHECK_EQUAL(1, tps->freq()); - BOOST_CHECK_EQUAL(0, tps->nextPosition()); + EXPECT_TRUE(tps->next()); + EXPECT_EQ(1, tps->freq()); + EXPECT_EQ(0, tps->nextPosition()); writer->close(); - BOOST_CHECK(checkIndex(dir)); + EXPECT_TRUE(checkIndex(dir)); s->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testPrepareCommit) +TEST_F(IndexWriterTest, testPrepareCommit) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -3609,50 +3695,50 @@ BOOST_AUTO_TEST_CASE(testPrepareCommit) addDoc(writer); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); writer->prepareCommit(); IndexReaderPtr reader2 = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader2->numDocs()); + EXPECT_EQ(0, reader2->numDocs()); writer->commit(); IndexReaderPtr reader3 = reader->reopen(); - BOOST_CHECK_EQUAL(0, reader->numDocs()); - BOOST_CHECK_EQUAL(0, reader2->numDocs()); - BOOST_CHECK_EQUAL(23, reader3->numDocs()); + EXPECT_EQ(0, reader->numDocs()); + EXPECT_EQ(0, reader2->numDocs()); + EXPECT_EQ(23, reader3->numDocs()); reader->close(); reader2->close(); for (int32_t i = 0; i < 17; ++i) addDoc(writer); - - BOOST_CHECK_EQUAL(23, reader3->numDocs()); + + EXPECT_EQ(23, reader3->numDocs()); reader3->close(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(23, reader->numDocs()); + EXPECT_EQ(23, reader->numDocs()); reader->close(); writer->prepareCommit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(23, reader->numDocs()); + EXPECT_EQ(23, reader->numDocs()); reader->close(); writer->commit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(40, reader->numDocs()); + EXPECT_EQ(40, reader->numDocs()); reader->close(); writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testPrepareCommitRollback) +TEST_F(IndexWriterTest, testPrepareCommitRollback) { MockRAMDirectoryPtr dir = newLucene(); dir->setPreventDoubleWrite(false); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(5); @@ -3661,57 +3747,57 @@ BOOST_AUTO_TEST_CASE(testPrepareCommitRollback) addDoc(writer); IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); writer->prepareCommit(); IndexReaderPtr reader2 = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader2->numDocs()); + EXPECT_EQ(0, reader2->numDocs()); writer->rollback(); IndexReaderPtr reader3 = reader->reopen(); - BOOST_CHECK_EQUAL(0, reader->numDocs()); - BOOST_CHECK_EQUAL(0, reader2->numDocs()); - BOOST_CHECK_EQUAL(0, reader3->numDocs()); + EXPECT_EQ(0, reader->numDocs()); + EXPECT_EQ(0, reader2->numDocs()); + EXPECT_EQ(0, reader3->numDocs()); reader->close(); reader2->close(); writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < 17; ++i) addDoc(writer); - - BOOST_CHECK_EQUAL(0, reader3->numDocs()); + + EXPECT_EQ(0, reader3->numDocs()); reader3->close(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); writer->prepareCommit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); writer->commit(); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(17, reader->numDocs()); + EXPECT_EQ(17, reader->numDocs()); reader->close(); writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testPrepareCommitNoChanges) +TEST_F(IndexWriterTest, testPrepareCommitNoChanges) { MockRAMDirectoryPtr dir = newLucene(); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->prepareCommit(); writer->commit(); writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(0, reader->numDocs()); + EXPECT_EQ(0, reader->numDocs()); reader->close(); dir->close(); } @@ -3719,24 +3805,24 @@ BOOST_AUTO_TEST_CASE(testPrepareCommitNoChanges) namespace TestAddIndexesWithThreads { DECLARE_SHARED_PTR(CommitAndAddIndexes) - + class CommitAndAddIndexes : public RunAddIndexesThreads { public: CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { } - + virtual ~CommitAndAddIndexes() { } - + public: virtual void handle(LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } - + virtual void doBody(int32_t j, Collection dirs) { switch (j % 4) @@ -3760,7 +3846,7 @@ namespace TestAddIndexesWithThreads } /// Test simultaneous addIndexes & commits from multiple threads -BOOST_AUTO_TEST_CASE(testAddIndexesWithThreads) +TEST_F(IndexWriterTest, testAddIndexesWithThreads) { static const int32_t NUM_ITER = 12; static const int32_t NUM_COPY = 3; @@ -3772,14 +3858,14 @@ BOOST_AUTO_TEST_CASE(testAddIndexesWithThreads) c->joinThreads(); - BOOST_CHECK_EQUAL(100 + NUM_COPY * (3 * NUM_ITER / 4) * c->NUM_THREADS * c->NUM_INIT_DOCS, c->writer2->numDocs()); + EXPECT_EQ(100 + NUM_COPY * (3 * NUM_ITER / 4) * c->NUM_THREADS * c->NUM_INIT_DOCS, c->writer2->numDocs()); c->close(true); checkIndex(c->dir2); IndexReaderPtr reader = IndexReader::open(c->dir2, true); - BOOST_CHECK_EQUAL(100 + NUM_COPY * (3 * NUM_ITER / 4) * c->NUM_THREADS * c->NUM_INIT_DOCS, reader->numDocs()); + EXPECT_EQ(100 + NUM_COPY * (3 * NUM_ITER / 4) * c->NUM_THREADS * c->NUM_INIT_DOCS, reader->numDocs()); reader->close(); c->closeDir(); @@ -3788,25 +3874,25 @@ BOOST_AUTO_TEST_CASE(testAddIndexesWithThreads) namespace TestAddIndexesWithClose { DECLARE_SHARED_PTR(CommitAndAddIndexes) - + class CommitAndAddIndexes : public RunAddIndexesThreads { public: CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { } - + virtual ~CommitAndAddIndexes() { } - + public: virtual void handle(LuceneException& e) { if (e.getType() != LuceneException::AlreadyClosed && e.getType() != LuceneException::NullPointer) - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } - + virtual void doBody(int32_t j, Collection dirs) { switch (j % 4) @@ -3830,7 +3916,7 @@ namespace TestAddIndexesWithClose } /// Test simultaneous addIndexes & close -BOOST_AUTO_TEST_CASE(testAddIndexesWithClose) +TEST_F(IndexWriterTest, testAddIndexesWithClose) { static const int32_t NUM_COPY = 3; TestAddIndexesWithClose::CommitAndAddIndexesPtr c = newLucene(NUM_COPY); @@ -3838,9 +3924,9 @@ BOOST_AUTO_TEST_CASE(testAddIndexesWithClose) // Close without first stopping/joining the threads c->close(true); - + c->joinThreads(); - + checkIndex(c->dir2); c->closeDir(); @@ -3849,18 +3935,18 @@ BOOST_AUTO_TEST_CASE(testAddIndexesWithClose) namespace TestAddIndexesWithCloseNoWait { DECLARE_SHARED_PTR(CommitAndAddIndexes) - + class CommitAndAddIndexes : public RunAddIndexesThreads { public: CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { } - + virtual ~CommitAndAddIndexes() { } - + public: virtual void handle(LuceneException& e) { @@ -3870,9 +3956,9 @@ namespace TestAddIndexesWithCloseNoWait else if (e.getType() == LuceneException::IO) report = !didClose; if (report) - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } - + virtual void doBody(int32_t j, Collection dirs) { switch (j % 5) @@ -3898,19 +3984,19 @@ namespace TestAddIndexesWithCloseNoWait } /// Test simultaneous addIndexes and close -BOOST_AUTO_TEST_CASE(testAddIndexesWithCloseNoWait) +TEST_F(IndexWriterTest, testAddIndexesWithCloseNoWait) { static const int32_t NUM_COPY = 50; TestAddIndexesWithCloseNoWait::CommitAndAddIndexesPtr c = newLucene(NUM_COPY); c->launchThreads(-1); - + LuceneThread::threadSleep(500); // Close without first stopping/joining the threads c->close(false); - + c->joinThreads(); - + checkIndex(c->dir2); c->closeDir(); @@ -3919,18 +4005,18 @@ BOOST_AUTO_TEST_CASE(testAddIndexesWithCloseNoWait) namespace TestAddIndexesWithRollback { DECLARE_SHARED_PTR(CommitAndAddIndexes) - + class CommitAndAddIndexes : public RunAddIndexesThreads { public: CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { } - + virtual ~CommitAndAddIndexes() { } - + public: virtual void handle(LuceneException& e) { @@ -3940,9 +4026,9 @@ namespace TestAddIndexesWithRollback else if (e.getType() == LuceneException::IO) report = !didClose; if (report) - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } - + virtual void doBody(int32_t j, Collection dirs) { switch (j % 5) @@ -3968,20 +4054,20 @@ namespace TestAddIndexesWithRollback } /// Test simultaneous addIndexes and close -BOOST_AUTO_TEST_CASE(testAddIndexesWithRollback) +TEST_F(IndexWriterTest, testAddIndexesWithRollback) { static const int32_t NUM_COPY = 50; TestAddIndexesWithRollback::CommitAndAddIndexesPtr c = newLucene(NUM_COPY); c->launchThreads(-1); - + LuceneThread::threadSleep(500); // Close without first stopping/joining the threads c->didClose = true; c->writer2->rollback(); - + c->joinThreads(); - + checkIndex(c->dir2); c->closeDir(); @@ -3990,7 +4076,7 @@ BOOST_AUTO_TEST_CASE(testAddIndexesWithRollback) namespace TestRollbackExceptionHang { DECLARE_SHARED_PTR(MockIndexWriter) - + class MockIndexWriter : public IndexWriter { public: @@ -3998,16 +4084,16 @@ namespace TestRollbackExceptionHang { doFail = false; } - + virtual ~MockIndexWriter() { } - + LUCENE_CLASS(MockIndexWriter); - + public: bool doFail; - + public: virtual bool testPoint(const String& name) { @@ -4018,20 +4104,27 @@ namespace TestRollbackExceptionHang }; } -BOOST_AUTO_TEST_CASE(testRollbackExceptionHang) +TEST_F(IndexWriterTest, testRollbackExceptionHang) { MockRAMDirectoryPtr dir = newLucene(); TestRollbackExceptionHang::MockIndexWriterPtr w = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(w); w->doFail = true; - BOOST_CHECK_EXCEPTION(w->rollback(), RuntimeException, check_exception(LuceneException::Runtime)); + try + { + w->rollback(); + } + catch (RuntimeException& e) + { + EXPECT_TRUE(check_exception(LuceneException::Runtime)(e)); + } w->doFail = false; w->rollback(); } -BOOST_AUTO_TEST_CASE(testBinaryFieldOffsetLength) +TEST_F(IndexWriterTest, testBinaryFieldOffsetLength) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -4042,10 +4135,10 @@ BOOST_AUTO_TEST_CASE(testBinaryFieldOffsetLength) DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"binary", b, 10, 17, Field::STORE_YES); ByteArray bx = f->getBinaryValue(); - BOOST_CHECK(bx); - BOOST_CHECK_EQUAL(50, bx.size()); - BOOST_CHECK_EQUAL(10, f->getBinaryOffset()); - BOOST_CHECK_EQUAL(17, f->getBinaryLength()); + EXPECT_TRUE(bx); + EXPECT_EQ(50, bx.size()); + EXPECT_EQ(10, f->getBinaryOffset()); + EXPECT_EQ(17, f->getBinaryLength()); doc->add(f); writer->addDocument(doc); writer->close(); @@ -4054,14 +4147,14 @@ BOOST_AUTO_TEST_CASE(testBinaryFieldOffsetLength) doc = reader->document(0); f = doc->getField(L"binary"); b = f->getBinaryValue(); - BOOST_CHECK(b); - BOOST_CHECK_EQUAL(17, b.size()); - BOOST_CHECK_EQUAL(87, b[0]); + EXPECT_TRUE(b); + EXPECT_EQ(17, b.size()); + EXPECT_EQ(87, b[0]); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testCommitUserData) +TEST_F(IndexWriterTest, testCommitUserData) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -4070,11 +4163,11 @@ BOOST_AUTO_TEST_CASE(testCommitUserData) addDoc(writer); writer->close(); - BOOST_CHECK_EQUAL(0, IndexReader::getCommitUserData(dir).size()); + EXPECT_EQ(0, IndexReader::getCommitUserData(dir).size()); IndexReaderPtr reader = IndexReader::open(dir, true); // commit(Map) never called for this index - BOOST_CHECK_EQUAL(0, reader->getCommitUserData().size()); + EXPECT_EQ(0, reader->getCommitUserData().size()); reader->close(); writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -4086,22 +4179,22 @@ BOOST_AUTO_TEST_CASE(testCommitUserData) writer->commit(data); writer->close(); - BOOST_CHECK_EQUAL(L"test1", IndexReader::getCommitUserData(dir).get(L"label")); + EXPECT_EQ(L"test1", IndexReader::getCommitUserData(dir).get(L"label")); reader = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(L"test1", reader->getCommitUserData().get(L"label")); + EXPECT_EQ(L"test1", reader->getCommitUserData().get(L"label")); reader->close(); writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->optimize(); writer->close(); - BOOST_CHECK_EQUAL(L"test1", IndexReader::getCommitUserData(dir).get(L"label")); + EXPECT_EQ(L"test1", IndexReader::getCommitUserData(dir).get(L"label")); dir->close(); } -BOOST_AUTO_TEST_CASE(testOptimizeExceptions) +TEST_F(IndexWriterTest, testOptimizeExceptions) { MockRAMDirectoryPtr startDir = newLucene(); IndexWriterPtr writer = newLucene(startDir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -4118,11 +4211,18 @@ BOOST_AUTO_TEST_CASE(testOptimizeExceptions) boost::dynamic_pointer_cast(writer->getMergeScheduler())->setSuppressExceptions(); dir->setRandomIOExceptionRate(0.5, 100); - BOOST_CHECK_EXCEPTION(writer->optimize(), IOException, check_exception(LuceneException::IO)); - + try + { + writer->optimize(); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + // Make sure we don't hit random exception during close below dir->setRandomIOExceptionRate(0.0, 0); - + writer->close(); dir->close(); } @@ -4137,16 +4237,16 @@ namespace TestOutOfMemoryErrorCausesCloseToFail { thrown = false; } - + virtual ~MemoryIndexWriter() { } - + LUCENE_CLASS(MemoryIndexWriter); - + protected: bool thrown; - + public: virtual void message(const String& message) { @@ -4159,18 +4259,25 @@ namespace TestOutOfMemoryErrorCausesCloseToFail }; } -BOOST_AUTO_TEST_CASE(testOutOfMemoryErrorCausesCloseToFail) +TEST_F(IndexWriterTest, testOutOfMemoryErrorCausesCloseToFail) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setInfoStream(newLucene()); - - BOOST_CHECK_EXCEPTION(writer->close(), OutOfMemoryError, check_exception(LuceneException::OutOfMemory)); + + try + { + writer->close(); + } + catch (OutOfMemoryError& e) + { + EXPECT_TRUE(check_exception(LuceneException::OutOfMemory)(e)); + } writer->close(); } -BOOST_AUTO_TEST_CASE(testDoubleOffsetCounting) +TEST_F(IndexWriterTest, testDoubleOffsetCounting) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -4188,24 +4295,24 @@ BOOST_AUTO_TEST_CASE(testDoubleOffsetCounting) Collection termOffsets = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field"))->getOffsets(0); // Token "" occurred once - BOOST_CHECK_EQUAL(1, termOffsets.size()); - BOOST_CHECK_EQUAL(8, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(8, termOffsets[0]->getEndOffset()); + EXPECT_EQ(1, termOffsets.size()); + EXPECT_EQ(8, termOffsets[0]->getStartOffset()); + EXPECT_EQ(8, termOffsets[0]->getEndOffset()); // Token "abcd" occurred three times termOffsets = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field"))->getOffsets(1); - BOOST_CHECK_EQUAL(3, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[1]->getStartOffset()); - BOOST_CHECK_EQUAL(8, termOffsets[1]->getEndOffset()); - BOOST_CHECK_EQUAL(8, termOffsets[2]->getStartOffset()); - BOOST_CHECK_EQUAL(12, termOffsets[2]->getEndOffset()); + EXPECT_EQ(3, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(4, termOffsets[1]->getStartOffset()); + EXPECT_EQ(8, termOffsets[1]->getEndOffset()); + EXPECT_EQ(8, termOffsets[2]->getStartOffset()); + EXPECT_EQ(12, termOffsets[2]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testDoubleOffsetCounting2) +TEST_F(IndexWriterTest, testDoubleOffsetCounting2) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -4218,16 +4325,16 @@ BOOST_AUTO_TEST_CASE(testDoubleOffsetCounting2) IndexReaderPtr reader = IndexReader::open(dir, true); Collection termOffsets = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field"))->getOffsets(0); - BOOST_CHECK_EQUAL(2, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); - BOOST_CHECK_EQUAL(5, termOffsets[1]->getStartOffset()); - BOOST_CHECK_EQUAL(9, termOffsets[1]->getEndOffset()); + EXPECT_EQ(2, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(5, termOffsets[1]->getStartOffset()); + EXPECT_EQ(9, termOffsets[1]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEndOffsetPositionCharAnalyzer) +TEST_F(IndexWriterTest, testEndOffsetPositionCharAnalyzer) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -4241,16 +4348,16 @@ BOOST_AUTO_TEST_CASE(testEndOffsetPositionCharAnalyzer) IndexReaderPtr reader = IndexReader::open(dir, true); Collection termOffsets = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field"))->getOffsets(0); - BOOST_CHECK_EQUAL(2, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); - BOOST_CHECK_EQUAL(8, termOffsets[1]->getStartOffset()); - BOOST_CHECK_EQUAL(12, termOffsets[1]->getEndOffset()); + EXPECT_EQ(2, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(8, termOffsets[1]->getStartOffset()); + EXPECT_EQ(12, termOffsets[1]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEndOffsetPositionWithCachingTokenFilter) +TEST_F(IndexWriterTest, testEndOffsetPositionWithCachingTokenFilter) { MockRAMDirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(); @@ -4266,16 +4373,16 @@ BOOST_AUTO_TEST_CASE(testEndOffsetPositionWithCachingTokenFilter) IndexReaderPtr reader = IndexReader::open(dir, true); Collection termOffsets = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field"))->getOffsets(0); - BOOST_CHECK_EQUAL(2, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); - BOOST_CHECK_EQUAL(8, termOffsets[1]->getStartOffset()); - BOOST_CHECK_EQUAL(12, termOffsets[1]->getEndOffset()); + EXPECT_EQ(2, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(8, termOffsets[1]->getStartOffset()); + EXPECT_EQ(12, termOffsets[1]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEndOffsetPositionWithTeeSinkTokenFilter) +TEST_F(IndexWriterTest, testEndOffsetPositionWithTeeSinkTokenFilter) { MockRAMDirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(); @@ -4293,16 +4400,16 @@ BOOST_AUTO_TEST_CASE(testEndOffsetPositionWithTeeSinkTokenFilter) IndexReaderPtr reader = IndexReader::open(dir, true); Collection termOffsets = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field"))->getOffsets(0); - BOOST_CHECK_EQUAL(2, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); - BOOST_CHECK_EQUAL(8, termOffsets[1]->getStartOffset()); - BOOST_CHECK_EQUAL(12, termOffsets[1]->getEndOffset()); + EXPECT_EQ(2, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(8, termOffsets[1]->getStartOffset()); + EXPECT_EQ(12, termOffsets[1]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEndOffsetPositionStopFilter) +TEST_F(IndexWriterTest, testEndOffsetPositionStopFilter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -4316,16 +4423,16 @@ BOOST_AUTO_TEST_CASE(testEndOffsetPositionStopFilter) IndexReaderPtr reader = IndexReader::open(dir, true); Collection termOffsets = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field"))->getOffsets(0); - BOOST_CHECK_EQUAL(2, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); - BOOST_CHECK_EQUAL(9, termOffsets[1]->getStartOffset()); - BOOST_CHECK_EQUAL(13, termOffsets[1]->getEndOffset()); + EXPECT_EQ(2, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(9, termOffsets[1]->getStartOffset()); + EXPECT_EQ(13, termOffsets[1]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEndOffsetPositionStandard) +TEST_F(IndexWriterTest, testEndOffsetPositionStandard) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -4341,20 +4448,20 @@ BOOST_AUTO_TEST_CASE(testEndOffsetPositionStandard) TermPositionVectorPtr tpv = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field")); Collection termOffsets = tpv->getOffsets(0); - BOOST_CHECK_EQUAL(1, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(1, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); termOffsets = tpv->getOffsets(1); - BOOST_CHECK_EQUAL(11, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(17, termOffsets[0]->getEndOffset()); + EXPECT_EQ(11, termOffsets[0]->getStartOffset()); + EXPECT_EQ(17, termOffsets[0]->getEndOffset()); termOffsets = tpv->getOffsets(2); - BOOST_CHECK_EQUAL(18, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(21, termOffsets[0]->getEndOffset()); + EXPECT_EQ(18, termOffsets[0]->getStartOffset()); + EXPECT_EQ(21, termOffsets[0]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEndOffsetPositionStandardEmptyField) +TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -4370,17 +4477,17 @@ BOOST_AUTO_TEST_CASE(testEndOffsetPositionStandardEmptyField) TermPositionVectorPtr tpv = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field")); Collection termOffsets = tpv->getOffsets(0); - BOOST_CHECK_EQUAL(1, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(6, termOffsets[0]->getEndOffset()); + EXPECT_EQ(1, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(6, termOffsets[0]->getEndOffset()); termOffsets = tpv->getOffsets(1); - BOOST_CHECK_EQUAL(7, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(10, termOffsets[0]->getEndOffset()); + EXPECT_EQ(7, termOffsets[0]->getStartOffset()); + EXPECT_EQ(10, termOffsets[0]->getEndOffset()); reader->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEndOffsetPositionStandardEmptyField2) +TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField2) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -4397,22 +4504,22 @@ BOOST_AUTO_TEST_CASE(testEndOffsetPositionStandardEmptyField2) TermPositionVectorPtr tpv = boost::dynamic_pointer_cast(reader->getTermFreqVector(0, L"field")); Collection termOffsets = tpv->getOffsets(0); - BOOST_CHECK_EQUAL(1, termOffsets.size()); - BOOST_CHECK_EQUAL(0, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(4, termOffsets[0]->getEndOffset()); + EXPECT_EQ(1, termOffsets.size()); + EXPECT_EQ(0, termOffsets[0]->getStartOffset()); + EXPECT_EQ(4, termOffsets[0]->getEndOffset()); termOffsets = tpv->getOffsets(1); - BOOST_CHECK_EQUAL(5, termOffsets[0]->getStartOffset()); - BOOST_CHECK_EQUAL(11, termOffsets[0]->getEndOffset()); + EXPECT_EQ(5, termOffsets[0]->getStartOffset()); + EXPECT_EQ(11, termOffsets[0]->getEndOffset()); reader->close(); dir->close(); } /// Make sure opening an IndexWriter with create=true does not remove non-index files -BOOST_AUTO_TEST_CASE(testOtherFiles) +TEST_F(IndexWriterTest, testOtherFiles) { String indexDir(FileUtils::joinPath(getTempDir(), L"otherfiles")); DirectoryPtr dir = FSDirectory::open(indexDir); - + LuceneException finally; try { @@ -4424,11 +4531,11 @@ BOOST_AUTO_TEST_CASE(testOtherFiles) IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->close(); - BOOST_CHECK(dir->fileExists(L"myrandomfile")); + EXPECT_TRUE(dir->fileExists(L"myrandomfile")); // Make sure this does not copy myrandomfile DirectoryPtr dir2 = newLucene(dir); - BOOST_CHECK(!dir2->fileExists(L"myrandomfile")); + EXPECT_TRUE(!dir2->fileExists(L"myrandomfile")); } catch (LuceneException& e) { @@ -4439,7 +4546,7 @@ BOOST_AUTO_TEST_CASE(testOtherFiles) finally.throwException(); } -BOOST_AUTO_TEST_CASE(testDeadlock) +TEST_F(IndexWriterTest, testDeadlock) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -4459,12 +4566,12 @@ BOOST_AUTO_TEST_CASE(testDeadlock) IndexReaderPtr r1 = IndexReader::open(dir2, true); IndexReaderPtr r2 = boost::dynamic_pointer_cast(r1->clone()); - + writer->addIndexes(newCollection(r1, r2)); writer->close(); IndexReaderPtr r3 = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(5, r3->numDocs()); + EXPECT_EQ(5, r3->numDocs()); r3->close(); r1->close(); @@ -4474,7 +4581,7 @@ BOOST_AUTO_TEST_CASE(testDeadlock) dir->close(); } -BOOST_AUTO_TEST_CASE(testIndexStoreCombos) +TEST_F(IndexWriterTest, testIndexStoreCombos) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -4501,7 +4608,7 @@ BOOST_AUTO_TEST_CASE(testIndexStoreCombos) f->setTokenStream(newLucene(newLucene(L"doc3field1"))); f2->setTokenStream(newLucene(newLucene(L"doc3field2"))); - + writer->addDocument(doc); writer->commit(); writer->optimize(); // force segment merge. @@ -4510,32 +4617,32 @@ BOOST_AUTO_TEST_CASE(testIndexStoreCombos) doc = reader->document(0); f = doc->getField(L"binary"); b = f->getBinaryValue(); - BOOST_CHECK(b); - BOOST_CHECK_EQUAL(17, b.size()); - BOOST_CHECK_EQUAL(87, b[0]); + EXPECT_TRUE(b); + EXPECT_EQ(17, b.size()); + EXPECT_EQ(87, b[0]); - BOOST_CHECK(reader->document(0)->getFieldable(L"binary")->isBinary()); - BOOST_CHECK(reader->document(1)->getFieldable(L"binary")->isBinary()); - BOOST_CHECK(reader->document(2)->getFieldable(L"binary")->isBinary()); + EXPECT_TRUE(reader->document(0)->getFieldable(L"binary")->isBinary()); + EXPECT_TRUE(reader->document(1)->getFieldable(L"binary")->isBinary()); + EXPECT_TRUE(reader->document(2)->getFieldable(L"binary")->isBinary()); - BOOST_CHECK_EQUAL(L"value", reader->document(0)->get(L"string")); - BOOST_CHECK_EQUAL(L"value", reader->document(1)->get(L"string")); - BOOST_CHECK_EQUAL(L"value", reader->document(2)->get(L"string")); + EXPECT_EQ(L"value", reader->document(0)->get(L"string")); + EXPECT_EQ(L"value", reader->document(1)->get(L"string")); + EXPECT_EQ(L"value", reader->document(2)->get(L"string")); // test that the terms were indexed. - BOOST_CHECK(reader->termDocs(newLucene(L"binary", L"doc1field1"))->next()); - BOOST_CHECK(reader->termDocs(newLucene(L"binary", L"doc2field1"))->next()); - BOOST_CHECK(reader->termDocs(newLucene(L"binary", L"doc3field1"))->next()); - BOOST_CHECK(reader->termDocs(newLucene(L"string", L"doc1field2"))->next()); - BOOST_CHECK(reader->termDocs(newLucene(L"string", L"doc2field2"))->next()); - BOOST_CHECK(reader->termDocs(newLucene(L"string", L"doc3field2"))->next()); + EXPECT_TRUE(reader->termDocs(newLucene(L"binary", L"doc1field1"))->next()); + EXPECT_TRUE(reader->termDocs(newLucene(L"binary", L"doc2field1"))->next()); + EXPECT_TRUE(reader->termDocs(newLucene(L"binary", L"doc3field1"))->next()); + EXPECT_TRUE(reader->termDocs(newLucene(L"string", L"doc1field2"))->next()); + EXPECT_TRUE(reader->termDocs(newLucene(L"string", L"doc2field2"))->next()); + EXPECT_TRUE(reader->termDocs(newLucene(L"string", L"doc3field2"))->next()); reader->close(); dir->close(); } /// Make sure doc fields are stored in order -BOOST_AUTO_TEST_CASE(testStoredFieldsOrder) +TEST_F(IndexWriterTest, testStoredFieldsOrder) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -4547,41 +4654,41 @@ BOOST_AUTO_TEST_CASE(testStoredFieldsOrder) IndexReaderPtr reader = writer->getReader(); doc = reader->document(0); Collection fields = doc->getFields(); - - BOOST_CHECK_EQUAL(3, fields.size()); - BOOST_CHECK_EQUAL(fields[0]->name(), L"zzz"); - BOOST_CHECK_EQUAL(fields[0]->stringValue(), L"a b c"); - BOOST_CHECK_EQUAL(fields[1]->name(), L"aaa"); - BOOST_CHECK_EQUAL(fields[1]->stringValue(), L"a b c"); - BOOST_CHECK_EQUAL(fields[2]->name(), L"zzz"); - BOOST_CHECK_EQUAL(fields[2]->stringValue(), L"1 2 3"); + + EXPECT_EQ(3, fields.size()); + EXPECT_EQ(fields[0]->name(), L"zzz"); + EXPECT_EQ(fields[0]->stringValue(), L"a b c"); + EXPECT_EQ(fields[1]->name(), L"aaa"); + EXPECT_EQ(fields[1]->stringValue(), L"a b c"); + EXPECT_EQ(fields[2]->name(), L"zzz"); + EXPECT_EQ(fields[2]->stringValue(), L"1 2 3"); reader->close(); writer->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEmbeddedFFFF) +TEST_F(IndexWriterTest, testEmbeddedFFFF) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); - + const wchar_t _field[] = {L'a', L' ', L'a', UTF8Base::UNICODE_TERMINATOR, L'b'}; String field(_field, SIZEOF_ARRAY(_field)); - + doc->add(newLucene(L"field", field, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); - + doc = newLucene(); doc->add(newLucene(L"field", L"a", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); writer->close(); - + checkIndex(dir); dir->close(); } -BOOST_AUTO_TEST_CASE(testNoDocsIndex) +TEST_F(IndexWriterTest, testNoDocsIndex) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -4605,19 +4712,19 @@ namespace TestCommitThreadSafety this->dir = dir; this->endTime = endTime; } - + virtual ~CommitThread() { } - + LUCENE_CLASS(CommitThread); - + protected: int32_t finalI; IndexWriterPtr writer; DirectoryPtr dir; int64_t endTime; - + public: virtual void run() { @@ -4637,24 +4744,24 @@ namespace TestCommitThreadSafety writer->addDocument(doc); writer->commit(); IndexReaderPtr reader2 = reader->reopen(); - BOOST_CHECK_NE(reader2, reader); + EXPECT_NE(reader2, reader); reader->close(); reader = reader2; - BOOST_CHECK_EQUAL(1, reader->docFreq(newLucene(L"f", s))); + EXPECT_EQ(1, reader->docFreq(newLucene(L"f", s))); } } reader->close(); } catch (...) { - BOOST_FAIL("Unexpected exception"); + FAIL() << "Unexpected exception"; } } }; } /// make sure with multiple threads commit doesn't return until all changes are in fact in the index -BOOST_AUTO_TEST_CASE(testCommitThreadSafety) +TEST_F(IndexWriterTest, testCommitThreadSafety) { static const int32_t NUM_THREADS = 5; double RUN_SEC = 0.5; @@ -4674,7 +4781,7 @@ BOOST_AUTO_TEST_CASE(testCommitThreadSafety) namespace TestCorruptionAfterDiskFullDuringMerge { DECLARE_SHARED_PTR(FailTwiceDuringMerge) - + class FailTwiceDuringMerge : public MockDirectoryFailure { public: @@ -4683,7 +4790,7 @@ namespace TestCorruptionAfterDiskFullDuringMerge didFail1 = false; didFail2 = false; } - + virtual ~FailTwiceDuringMerge() { } @@ -4711,13 +4818,13 @@ namespace TestCorruptionAfterDiskFullDuringMerge }; } -BOOST_AUTO_TEST_CASE(testCorruptionAfterDiskFullDuringMerge) +TEST_F(IndexWriterTest, testCorruptionAfterDiskFullDuringMerge) { MockRAMDirectoryPtr dir = newLucene(); dir->setPreventDoubleWrite(false); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); w->setMergeScheduler(newLucene()); - + boost::dynamic_pointer_cast(w->getMergePolicy())->setMergeFactor(2); DocumentPtr doc = newLucene(); @@ -4733,18 +4840,18 @@ BOOST_AUTO_TEST_CASE(testCorruptionAfterDiskFullDuringMerge) TestCorruptionAfterDiskFullDuringMerge::FailTwiceDuringMergePtr ftdm = newLucene(); ftdm->setDoFail(); dir->failOn(ftdm); - + try { w->commit(); - BOOST_FAIL("fake disk full IOExceptions not hit"); + FAIL() << "fake disk full IOExceptions not hit"; } catch (IOException&) { } - - BOOST_CHECK(ftdm->didFail1 || ftdm->didFail2); - + + EXPECT_TRUE(ftdm->didFail1 || ftdm->didFail2); + checkIndex(dir); ftdm->clearDoFail(); w->addDocument(doc); @@ -4762,21 +4869,21 @@ namespace TestFutureCommit virtual ~NoDeletionPolicy() { } - + LUCENE_CLASS(NoDeletionPolicy); - + public: virtual void onInit(Collection commits) { } - + virtual void onCommit(Collection commits) { } }; } -BOOST_AUTO_TEST_CASE(testFutureCommit) +TEST_F(IndexWriterTest, testFutureCommit) { MockRAMDirectoryPtr dir = newLucene(); @@ -4788,13 +4895,13 @@ BOOST_AUTO_TEST_CASE(testFutureCommit) MapStringString commitData = MapStringString::newInstance(); commitData.put(L"tag", L"first"); w->commit(commitData); - + // commit to "second" w->addDocument(doc); commitData.put(L"tag", L"second"); w->commit(commitData); w->close(); - + // open "first" with IndexWriter IndexCommitPtr commit; Collection commits = IndexReader::listCommits(dir); @@ -4807,12 +4914,12 @@ BOOST_AUTO_TEST_CASE(testFutureCommit) break; } } - - BOOST_CHECK(commit); - + + EXPECT_TRUE(commit); + w = newLucene(dir, newLucene(), newLucene(), IndexWriter::MaxFieldLengthUNLIMITED, commit); - BOOST_CHECK_EQUAL(1, w->numDocs()); + EXPECT_EQ(1, w->numDocs()); // commit IndexWriter to "third" w->addDocument(doc); @@ -4832,22 +4939,22 @@ BOOST_AUTO_TEST_CASE(testFutureCommit) break; } } - - BOOST_CHECK(commit); - + + EXPECT_TRUE(commit); + IndexReaderPtr r = IndexReader::open(commit, true); - BOOST_CHECK_EQUAL(2, r->numDocs()); + EXPECT_EQ(2, r->numDocs()); r->close(); // open "second", with writeable IndexReader & commit r = IndexReader::open(commit, newLucene(), false); - BOOST_CHECK_EQUAL(2, r->numDocs()); + EXPECT_EQ(2, r->numDocs()); r->deleteDocument(0); r->deleteDocument(1); commitData.put(L"tag", L"fourth"); r->commit(commitData); r->close(); - + // make sure "third" commit is still there commit.reset(); commits = IndexReader::listCommits(dir); @@ -4860,13 +4967,13 @@ BOOST_AUTO_TEST_CASE(testFutureCommit) break; } } - - BOOST_CHECK(commit); - + + EXPECT_TRUE(commit); + dir->close(); } -BOOST_AUTO_TEST_CASE(testNoUnwantedTVFiles) +TEST_F(IndexWriterTest, testNoUnwantedTVFiles) { DirectoryPtr dir = newLucene(); IndexWriterPtr indexWriter = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -4875,7 +4982,7 @@ BOOST_AUTO_TEST_CASE(testNoUnwantedTVFiles) String BIG = L"alskjhlaksjghlaksjfhalksvjepgjioefgjnsdfjgefgjhelkgjhqewlrkhgwlekgrhwelkgjhwelkgrhwlkejg"; BIG += BIG + BIG + BIG; - + for (int32_t i = 0; i < 2; ++i) { DocumentPtr doc = newLucene(); @@ -4894,12 +5001,10 @@ BOOST_AUTO_TEST_CASE(testNoUnwantedTVFiles) HashSet files = dir->listAll(); for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { - BOOST_CHECK(!boost::ends_with(*file, IndexFileNames::VECTORS_FIELDS_EXTENSION())); - BOOST_CHECK(!boost::ends_with(*file, IndexFileNames::VECTORS_INDEX_EXTENSION())); - BOOST_CHECK(!boost::ends_with(*file, IndexFileNames::VECTORS_DOCUMENTS_EXTENSION())); + EXPECT_TRUE(!boost::ends_with(*file, IndexFileNames::VECTORS_FIELDS_EXTENSION())); + EXPECT_TRUE(!boost::ends_with(*file, IndexFileNames::VECTORS_INDEX_EXTENSION())); + EXPECT_TRUE(!boost::ends_with(*file, IndexFileNames::VECTORS_DOCUMENTS_EXTENSION())); } - + dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/LazyBugTest.cpp b/src/test/index/LazyBugTest.cpp index 38aa081b..60cebc31 100644 --- a/src/test/index/LazyBugTest.cpp +++ b/src/test/index/LazyBugTest.cpp @@ -18,10 +18,10 @@ using namespace Lucene; -class LazyBugTestFixture : public LuceneTestFixture +class LazyBugTest : public LuceneTestFixture { public: - virtual ~LazyBugTestFixture() + virtual ~LazyBugTest() { } @@ -46,7 +46,7 @@ class LazyBugTestFixture : public LuceneTestFixture } return _data; } - + HashSet dataset() { static HashSet _dataset; @@ -57,14 +57,14 @@ class LazyBugTestFixture : public LuceneTestFixture } return _dataset; } - + String MAGIC_FIELD() { return L"f" + StringUtils::toString((double)NUM_FIELDS / 3); } - + DECLARE_SHARED_PTR(LazyBugSelector) - + class LazyBugSelector : public FieldSelector { public: @@ -72,16 +72,16 @@ class LazyBugTestFixture : public LuceneTestFixture { this->magicField = magicField; } - + virtual ~LazyBugSelector() { } - + LUCENE_CLASS(LazyBugSelector); - + protected: String magicField; - + public: virtual FieldSelectorResult accept(const String& fieldName) { @@ -91,25 +91,25 @@ class LazyBugTestFixture : public LuceneTestFixture return FieldSelector::SELECTOR_LAZY_LOAD; } }; - + FieldSelectorPtr SELECTOR() { return newLucene(MAGIC_FIELD()); } - + DirectoryPtr makeIndex() { DirectoryPtr dir = newLucene(); RandomPtr rand = newLucene(); - + try { AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); - + writer->setUseCompoundFile(false); Collection _data = data(); - + for (int32_t d = 1; d <= NUM_DOCS; ++d) { DocumentPtr doc = newLucene(); @@ -121,22 +121,22 @@ class LazyBugTestFixture : public LuceneTestFixture } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + boost::throw_exception(RuntimeException(L"Unexpected exception: " + e.getError())); } return dir; } - + void doTest(Collection docs) { DirectoryPtr dir = makeIndex(); IndexReaderPtr reader = IndexReader::open(dir, true); HashSet _dataset = dataset(); - + for (int32_t i = 0; i < docs.size(); ++i) { DocumentPtr d = reader->document(docs[i], SELECTOR()); d->get(MAGIC_FIELD()); - + Collection fields = d->getFields(); for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { @@ -144,16 +144,16 @@ class LazyBugTestFixture : public LuceneTestFixture { String fname = (*field)->name(); String fval = (*field)->stringValue(); - BOOST_CHECK(!fval.empty()); - + EXPECT_TRUE(!fval.empty()); + Collection vals = StringUtils::split(fval, L"#"); - BOOST_CHECK_EQUAL(vals.size(), 2); + EXPECT_EQ(vals.size(), 2); if (!_dataset.contains(vals[0]) || !_dataset.contains(vals[1])) - BOOST_FAIL("FIELD:" << fname << ",VAL:" << fval); + FAIL() << "FIELD:" << fname << ",VAL:" << fval; } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } } @@ -161,25 +161,22 @@ class LazyBugTestFixture : public LuceneTestFixture } }; -const int32_t LazyBugTestFixture::NUM_DOCS = 500; -const int32_t LazyBugTestFixture::NUM_FIELDS = 100; +const int32_t LazyBugTest::NUM_DOCS = 500; +const int32_t LazyBugTest::NUM_FIELDS = 100; /// Test demonstrating EOF bug on the last field of the last doc if other docs have already been accessed. -BOOST_FIXTURE_TEST_SUITE(LazyBugTest, LazyBugTestFixture) -BOOST_AUTO_TEST_CASE(testLazyWorks) +TEST_F(LazyBugTest, testLazyWorks) { doTest(newCollection(399)); } -BOOST_AUTO_TEST_CASE(testLazyAlsoWorks) +TEST_F(LazyBugTest, testLazyAlsoWorks) { doTest(newCollection(399, 150)); } -BOOST_AUTO_TEST_CASE(testLazyBroken) +TEST_F(LazyBugTest, testLazyBroken) { doTest(newCollection(150, 399)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/LazyProxSkippingTest.cpp b/src/test/index/LazyProxSkippingTest.cpp index edb74150..d6055306 100644 --- a/src/test/index/LazyProxSkippingTest.cpp +++ b/src/test/index/LazyProxSkippingTest.cpp @@ -35,11 +35,11 @@ class SeeksCountingStream : public IndexInput { this->input = input; } - + virtual ~SeeksCountingStream() { } - + LUCENE_CLASS(SeeksCountingStream); protected: @@ -50,29 +50,29 @@ class SeeksCountingStream : public IndexInput { return input->readByte(); } - + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) { input->readBytes(b, offset, length); } - + virtual void close() { input->close(); } - + virtual int64_t getFilePointer() { return input->getFilePointer(); } - + virtual void seek(int64_t pos); // implemented below - + virtual int64_t length() { return input->length(); } - + LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(input->clone())); @@ -99,10 +99,10 @@ class SeekCountingDirectory : public RAMDirectory } }; -class LazyProxSkippingFixture : public LuceneTestFixture +class LazyProxSkippingTest : public LuceneTestFixture { public: - LazyProxSkippingFixture() + LazyProxSkippingTest() { seeksCounter = 0; field = L"tokens"; @@ -110,14 +110,14 @@ class LazyProxSkippingFixture : public LuceneTestFixture term2 = L"yy"; term3 = L"zz"; } - - virtual ~LazyProxSkippingFixture() + + virtual ~LazyProxSkippingTest() { } protected: SearcherPtr searcher; - + String field; String term1; String term2; @@ -154,19 +154,19 @@ class LazyProxSkippingFixture : public LuceneTestFixture // add a document that contains term2 but not term 1 content = term3 + L" " + term2; } - + doc->add(newLucene(field, content, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + // make sure the index has only a single segment writer->optimize(); writer->close(); SegmentReaderPtr reader = SegmentReader::getOnlySegmentReader(directory); - searcher = newLucene(reader); + searcher = newLucene(reader); } - + Collection search() { // create PhraseQuery "term1 term2" and search @@ -175,40 +175,39 @@ class LazyProxSkippingFixture : public LuceneTestFixture pq->add(newLucene(field, term2)); return searcher->search(pq, FilterPtr(), 1000)->scoreDocs; } - + void performTest(int32_t numHits) { createIndex(numHits); seeksCounter = 0; Collection hits = search(); // verify that the right number of docs was found - BOOST_CHECK_EQUAL(numHits, hits.size()); + EXPECT_EQ(numHits, hits.size()); // check if the number of calls of seek() does not exceed the number of hits - BOOST_CHECK(seeksCounter > 0); - BOOST_CHECK(seeksCounter <= numHits + 1); + EXPECT_TRUE(seeksCounter > 0); + EXPECT_TRUE(seeksCounter <= numHits + 1); } }; -int32_t LazyProxSkippingFixture::seeksCounter = 0; +int32_t LazyProxSkippingTest::seeksCounter = 0; void SeeksCountingStream::seek(int64_t pos) { - ++LazyProxSkippingFixture::seeksCounter; + ++LazyProxSkippingTest::seeksCounter; input->seek(pos); } /// Tests lazy skipping on the proximity file. -BOOST_FIXTURE_TEST_SUITE(LazyProxSkippingTest, LazyProxSkippingFixture) -BOOST_AUTO_TEST_CASE(testLazySkipping) +TEST_F(LazyProxSkippingTest, testLazySkipping) { // test whether only the minimum amount of seeks() are performed performTest(5); performTest(10); } -BOOST_AUTO_TEST_CASE(testSeek) +TEST_F(LazyProxSkippingTest, testSeek) { DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -218,7 +217,7 @@ BOOST_AUTO_TEST_CASE(testSeek) doc->add(newLucene(field, L"a b", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + writer->close(); IndexReaderPtr reader = IndexReader::open(directory, true); TermPositionsPtr tp = reader->termPositions(); @@ -226,16 +225,14 @@ BOOST_AUTO_TEST_CASE(testSeek) for (int32_t i = 0; i < 10; ++i) { tp->next(); - BOOST_CHECK_EQUAL(tp->doc(), i); - BOOST_CHECK_EQUAL(tp->nextPosition(), 1); + EXPECT_EQ(tp->doc(), i); + EXPECT_EQ(tp->nextPosition(), 1); } tp->seek(newLucene(field, L"a")); for (int32_t i = 0; i < 10; ++i) { tp->next(); - BOOST_CHECK_EQUAL(tp->doc(), i); - BOOST_CHECK_EQUAL(tp->nextPosition(), 0); + EXPECT_EQ(tp->doc(), i); + EXPECT_EQ(tp->nextPosition(), 0); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/MultiLevelSkipListTest.cpp b/src/test/index/MultiLevelSkipListTest.cpp index 8fc80c1a..69994d17 100644 --- a/src/test/index/MultiLevelSkipListTest.cpp +++ b/src/test/index/MultiLevelSkipListTest.cpp @@ -25,35 +25,35 @@ using namespace Lucene; -/// This testcase tests whether multi-level skipping is being used to reduce I/O while -/// skipping through posting lists. Skipping in general is already covered by +/// This testcase tests whether multi-level skipping is being used to reduce I/O while +/// skipping through posting lists. Skipping in general is already covered by /// several other testcases. -BOOST_FIXTURE_TEST_SUITE(MultiLevelSkipListTest, LuceneTestFixture) +typedef LuceneTestFixture MultiLevelSkipListTest; -class PayloadFilter : public TokenFilter +class MultiLevelSkipListPayloadFilter : public TokenFilter { public: - PayloadFilter(TokenStreamPtr input) : TokenFilter(input) + MultiLevelSkipListPayloadFilter(TokenStreamPtr input) : TokenFilter(input) { payloadAtt = addAttribute(); } - - virtual ~PayloadFilter() + + virtual ~MultiLevelSkipListPayloadFilter() { } - - LUCENE_CLASS(PayloadFilter); + + LUCENE_CLASS(MultiLevelSkipListPayloadFilter); public: static int32_t count; PayloadAttributePtr payloadAtt; - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { - return newLucene(newLucene(reader)); + return newLucene(newLucene(reader)); } - + virtual bool incrementToken() { bool hasNext = input->incrementToken(); @@ -67,21 +67,21 @@ class PayloadFilter : public TokenFilter } }; -int32_t PayloadFilter::count = 0; +int32_t MultiLevelSkipListPayloadFilter::count = 0; -class PayloadAnalyzer : public Analyzer +class MultiLevelSkipListPayloadAnalyzer : public Analyzer { public: - virtual ~PayloadAnalyzer() + virtual ~MultiLevelSkipListPayloadAnalyzer() { } - - LUCENE_CLASS(PayloadAnalyzer); + + LUCENE_CLASS(MultiLevelSkipListPayloadAnalyzer); public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { - return newLucene(newLucene(reader)); + return newLucene(newLucene(reader)); } }; @@ -94,11 +94,11 @@ class CountingStream : public IndexInput { this->input = input; } - + virtual ~CountingStream() { } - + LUCENE_CLASS(CountingStream); protected: @@ -110,33 +110,33 @@ class CountingStream : public IndexInput ++counter; return input->readByte(); } - + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) { counter += length; input->readBytes(b, offset, length); } - + virtual void close() { input->close(); } - + virtual int64_t getFilePointer() { return input->getFilePointer(); } - + virtual void seek(int64_t pos) { input->seek(pos); } - + virtual int64_t length() { return input->length(); } - + LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(input->clone())); @@ -147,20 +147,20 @@ static void checkSkipTo(TermPositionsPtr tp, int32_t target, int32_t maxCounter) { tp->skipTo(target); if (maxCounter < counter) - BOOST_FAIL("Too many bytes read: " << counter); + FAIL() << "Too many bytes read: " << counter; - BOOST_CHECK_EQUAL(target, tp->doc()); - BOOST_CHECK_EQUAL(1, tp->freq()); + EXPECT_EQ(target, tp->doc()); + EXPECT_EQ(1, tp->freq()); tp->nextPosition(); ByteArray b = ByteArray::newInstance(1); tp->getPayload(b, 0); - BOOST_CHECK_EQUAL((uint8_t)target, b[0]); + EXPECT_EQ((uint8_t)target, b[0]); } -BOOST_AUTO_TEST_CASE(testSimpleSkip) +TEST_F(MultiLevelSkipListTest, testSimpleSkip) { DirectoryPtr dir = newLucene(); - IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); TermPtr term = newLucene(L"test", L"a"); for (int32_t i = 0; i < 5000; ++i) { @@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(testSimpleSkip) d1->add(newLucene(term->field(), term->text(), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(d1); } - + writer->commit(); writer->optimize(); writer->close(); @@ -190,5 +190,3 @@ BOOST_AUTO_TEST_CASE(testSimpleSkip) checkSkipTo(tp, 4800, 250);// one skip on level 2 } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/MultiReaderTest.cpp b/src/test/index/MultiReaderTest.cpp index b29d2b54..44f5d2d0 100644 --- a/src/test/index/MultiReaderTest.cpp +++ b/src/test/index/MultiReaderTest.cpp @@ -26,10 +26,10 @@ using namespace Lucene; -class MultiReaderTestFixture : public LuceneTestFixture, public DocHelper +class MultiReaderTest : public LuceneTestFixture, public DocHelper { public: - MultiReaderTestFixture() + MultiReaderTest() { readers = Collection::newInstance(2); dir = newLucene(); @@ -42,8 +42,8 @@ class MultiReaderTestFixture : public LuceneTestFixture, public DocHelper sis = newLucene(); sis->read(dir); } - - virtual ~MultiReaderTestFixture() + + virtual ~MultiReaderTest() { } @@ -53,63 +53,63 @@ class MultiReaderTestFixture : public LuceneTestFixture, public DocHelper DocumentPtr doc2; Collection readers; SegmentInfosPtr sis; - + public: void doTestDocument() { sis->read(dir); IndexReaderPtr reader = openReader(); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); DocumentPtr newDoc1 = reader->document(0); - BOOST_CHECK(newDoc1); - BOOST_CHECK(DocHelper::numFields(newDoc1) == DocHelper::numFields(doc1) - DocHelper::unstored.size()); + EXPECT_TRUE(newDoc1); + EXPECT_TRUE(DocHelper::numFields(newDoc1) == DocHelper::numFields(doc1) - DocHelper::unstored.size()); DocumentPtr newDoc2 = reader->document(1); - BOOST_CHECK(newDoc2); - BOOST_CHECK(DocHelper::numFields(newDoc2) == DocHelper::numFields(doc2) - DocHelper::unstored.size()); + EXPECT_TRUE(newDoc2); + EXPECT_TRUE(DocHelper::numFields(newDoc2) == DocHelper::numFields(doc2) - DocHelper::unstored.size()); TermFreqVectorPtr vector = reader->getTermFreqVector(0, DocHelper::TEXT_FIELD_2_KEY); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); checkNorms(reader); } - + void doTestUndeleteAll() { sis->read(dir); IndexReaderPtr reader = openReader(); - BOOST_CHECK(reader); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_TRUE(reader); + EXPECT_EQ(2, reader->numDocs()); reader->deleteDocument(0); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->numDocs()); reader->undeleteAll(); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); // Ensure undeleteAll survives commit/close/reopen reader->commit(MapStringString()); reader->close(); - + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } - + sis->read(dir); reader = openReader(); - BOOST_CHECK_EQUAL(2, reader->numDocs()); + EXPECT_EQ(2, reader->numDocs()); reader->deleteDocument(0); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->numDocs()); reader->commit(MapStringString()); reader->close(); - + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } - + sis->read(dir); reader = openReader(); - BOOST_CHECK_EQUAL(1, reader->numDocs()); + EXPECT_EQ(1, reader->numDocs()); } protected: @@ -120,41 +120,41 @@ class MultiReaderTestFixture : public LuceneTestFixture, public DocHelper SegmentReaderPtr reader2 = SegmentReader::get(false, sis->info(1), IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); readers[0] = reader1; readers[1] = reader2; - BOOST_CHECK(reader1); - BOOST_CHECK(reader2); - + EXPECT_TRUE(reader1); + EXPECT_TRUE(reader2); + IndexReaderPtr reader = newLucene(readers); - BOOST_CHECK(dir); - BOOST_CHECK(sis); - BOOST_CHECK(reader); + EXPECT_TRUE(dir); + EXPECT_TRUE(sis); + EXPECT_TRUE(reader); return reader; } - + void checkNorms(IndexReaderPtr reader) { for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) { if ((*field)->isIndexed()) { - BOOST_CHECK_EQUAL(reader->hasNorms((*field)->name()), !(*field)->getOmitNorms()); - BOOST_CHECK_EQUAL(reader->hasNorms((*field)->name()), !DocHelper::noNorms.contains((*field)->name())); + EXPECT_EQ(reader->hasNorms((*field)->name()), !(*field)->getOmitNorms()); + EXPECT_EQ(reader->hasNorms((*field)->name()), !DocHelper::noNorms.contains((*field)->name())); if (!reader->hasNorms((*field)->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms((*field)->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); - BOOST_CHECK(!norms); + EXPECT_TRUE(!norms); norms = ByteArray::newInstance(reader->maxDoc()); reader->norms((*field)->name(), norms, 0); for (int32_t j = 0; j < reader->maxDoc(); ++j) - BOOST_CHECK_EQUAL(norms[j], norm1); + EXPECT_EQ(norms[j], norm1); } } } } - + void addDoc(RAMDirectoryPtr ramDir1, const String& s, bool create) { IndexWriterPtr iw = newLucene(ramDir1, newLucene(LuceneVersion::LUCENE_CURRENT), create, IndexWriter::MaxFieldLengthLIMITED); @@ -165,31 +165,36 @@ class MultiReaderTestFixture : public LuceneTestFixture, public DocHelper } }; -BOOST_FIXTURE_TEST_SUITE(MultiReaderTest, MultiReaderTestFixture) - -BOOST_AUTO_TEST_CASE(testTestMultiReader) +TEST_F(MultiReaderTest, testTestMultiReader) { doTestDocument(); doTestUndeleteAll(); } -BOOST_AUTO_TEST_CASE(testIsCurrent) +TEST_F(MultiReaderTest, testIsCurrent) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); RAMDirectoryPtr ramDir2 = newLucene(); addDoc(ramDir2, L"test blah", true); MultiReaderPtr mr = newLucene(newCollection(IndexReader::open(ramDir1, false), IndexReader::open(ramDir2, false))); - BOOST_CHECK(mr->isCurrent()); // just opened, must be current + EXPECT_TRUE(mr->isCurrent()); // just opened, must be current addDoc(ramDir1, L"more text", false); - BOOST_CHECK(!mr->isCurrent()); // has been modified, not current anymore + EXPECT_TRUE(!mr->isCurrent()); // has been modified, not current anymore addDoc(ramDir2, L"even more text", false); - BOOST_CHECK(!mr->isCurrent()); // has been modified even more, not current anymore - BOOST_CHECK_EXCEPTION(mr->getVersion(), LuceneException, check_exception(LuceneException::UnsupportedOperation)); + EXPECT_TRUE(!mr->isCurrent()); // has been modified even more, not current anymore + try + { + mr->getVersion(); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); + } mr->close(); } -BOOST_AUTO_TEST_CASE(testMultiTermDocs) +TEST_F(MultiReaderTest, testMultiTermDocs) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); @@ -217,22 +222,20 @@ BOOST_AUTO_TEST_CASE(testMultiTermDocs) te3->close(); // really a dummy check to ensure that we got some docs and to ensure that nothing is optimized out. - BOOST_CHECK(ret > 0); + EXPECT_TRUE(ret > 0); } -BOOST_AUTO_TEST_CASE(testAllTermDocs) +TEST_F(MultiReaderTest, testAllTermDocs) { IndexReaderPtr reader = openReader(); int32_t NUM_DOCS = 2; TermDocsPtr td = reader->termDocs(TermPtr()); for (int32_t i = 0; i < NUM_DOCS; ++i) { - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(i, td->doc()); - BOOST_CHECK_EQUAL(1, td->freq()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(i, td->doc()); + EXPECT_EQ(1, td->freq()); } td->close(); reader->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/NRTReaderWithThreadsTest.cpp b/src/test/index/NRTReaderWithThreadsTest.cpp index ffd7e398..d91002ed 100644 --- a/src/test/index/NRTReaderWithThreadsTest.cpp +++ b/src/test/index/NRTReaderWithThreadsTest.cpp @@ -21,7 +21,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(NRTReaderWithThreadsTest, LuceneTestFixture) +typedef LuceneTestFixture NRTReaderWithThreadsTest; DECLARE_SHARED_PTR(RunThread) DECLARE_SHARED_PTR(HeavyAtomicInt) @@ -60,10 +60,10 @@ class HeavyAtomicInt : public LuceneObject { value = start; } - + virtual ~HeavyAtomicInt() { - + } protected: @@ -76,13 +76,13 @@ class HeavyAtomicInt : public LuceneObject value += inc; return value; } - + int32_t incrementAndGet() { SyncLock syncLock(this); return ++value; } - + int32_t intValue() { SyncLock syncLock(this); @@ -103,13 +103,13 @@ class RunThread : public LuceneThread this->seq = seq; this->rand = newLucene(); } - + virtual ~RunThread() { } - + LUCENE_CLASS(RunThread); - + public: HeavyAtomicIntPtr seq; IndexWriterPtr writer; @@ -150,12 +150,12 @@ class RunThread : public LuceneThread catch (LuceneException& e) { _run = false; - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; -BOOST_AUTO_TEST_CASE(testIndexing) +TEST_F(NRTReaderWithThreadsTest, testIndexing) { HeavyAtomicIntPtr seq = newLucene(1); DirectoryPtr mainDir = newLucene(); @@ -188,5 +188,3 @@ BOOST_AUTO_TEST_CASE(testIndexing) writer->close(); mainDir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/NormsTest.cpp b/src/test/index/NormsTest.cpp index 4a7691c2..4a2efd63 100644 --- a/src/test/index/NormsTest.cpp +++ b/src/test/index/NormsTest.cpp @@ -24,7 +24,7 @@ class SimilarityOne : public DefaultSimilarity virtual ~SimilarityOne() { } - + LUCENE_CLASS(SimilarityOne); public: @@ -35,32 +35,32 @@ class SimilarityOne : public DefaultSimilarity }; /// Test that norms info is preserved during index life - including separate norms, addDocument, addIndexesNoOptimize, optimize. -class NormTestFixture : public LuceneTestFixture +class NormsTest : public LuceneTestFixture { public: - NormTestFixture() + NormsTest() { similarityOne = newLucene(); lastNorm = 0.0; normDelta = 0.001; numDocNorms = 0; } - - virtual ~NormTestFixture() + + virtual ~NormsTest() { } protected: static const int32_t NUM_FIELDS; - + SimilarityPtr similarityOne; int32_t numDocNorms; - Collection norms; + Collection norms; Collection modifiedNorms; - + double lastNorm; double normDelta; - + public: /// return unique norm values that are unchanged by encoding/decoding double nextNorm() @@ -97,7 +97,7 @@ class NormTestFixture : public LuceneTestFixture } return d; } - + void verifyIndex(DirectoryPtr dir) { IndexReaderPtr ir = IndexReader::open(dir, false); @@ -105,13 +105,13 @@ class NormTestFixture : public LuceneTestFixture { String field = L"f" + StringUtils::toString(i); ByteArray b = ir->norms(field); - BOOST_CHECK_EQUAL(numDocNorms, b.size()); + EXPECT_EQ(numDocNorms, b.size()); Collection storedNorms = (i == 1 ? modifiedNorms : norms); for (int32_t j = 0; j < b.size(); ++j) { double norm = Similarity::decodeNorm(b[j]); double norm1 = storedNorms[j]; - BOOST_CHECK_EQUAL(norm, norm1); // 0.000001 + EXPECT_EQ(norm, norm1); // 0.000001 } } } @@ -127,7 +127,7 @@ class NormTestFixture : public LuceneTestFixture iw->addDocument(newDoc()); iw->close(); } - + void modifyNormsForF1(DirectoryPtr dir) { IndexReaderPtr ir = IndexReader::open(dir, false); @@ -139,8 +139,8 @@ class NormTestFixture : public LuceneTestFixture double newNorm = modifiedNorms[k]; modifiedNorms[i] = newNorm; modifiedNorms[k] = origNorm; - ir->setNorm(i, L"f1", newNorm); - ir->setNorm(k, L"f1", origNorm); + ir->setNorm(i, L"f1", newNorm); + ir->setNorm(k, L"f1", origNorm); } ir->close(); } @@ -171,15 +171,13 @@ class NormTestFixture : public LuceneTestFixture } }; -const int32_t NormTestFixture::NUM_FIELDS = 10; - -BOOST_FIXTURE_TEST_SUITE(NormsTest, NormTestFixture) +const int32_t NormsTest::NUM_FIELDS = 10; /// Test that norms values are preserved as the index is maintained. /// Including separate norms. -/// Including merging indexes with separate norms. -/// Including optimize. -BOOST_AUTO_TEST_CASE(testNorms) +/// Including merging indexes with separate norms. +/// Including optimize. +TEST_F(NormsTest, testNorms) { // test with a single index: index1 String indexDir1(FileUtils::joinPath(getTempDir(), L"lucenetestindex1")); @@ -214,7 +212,7 @@ BOOST_AUTO_TEST_CASE(testNorms) IndexWriterPtr iw = newLucene(dir3, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); iw->setMergeFactor(3); - + iw->addIndexesNoOptimize(newCollection(dir1, dir2)); iw->optimize(); iw->close(); @@ -241,5 +239,3 @@ BOOST_AUTO_TEST_CASE(testNorms) dir2->close(); dir3->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/OmitTfTest.cpp b/src/test/index/OmitTfTest.cpp index cd17ceda..f5e20757 100644 --- a/src/test/index/OmitTfTest.cpp +++ b/src/test/index/OmitTfTest.cpp @@ -27,7 +27,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(OmitTfTest, LuceneTestFixture) +typedef LuceneTestFixture OmitTfTest; DECLARE_SHARED_PTR(CountingHitCollector) @@ -45,7 +45,7 @@ class SimpleIDFExplanation : public IDFExplanation { return 1.0; } - + virtual String explain() { return L"Inexplicable"; @@ -58,7 +58,7 @@ class SimpleSimilarity : public Similarity virtual ~SimpleSimilarity() { } - + LUCENE_CLASS(SimpleSimilarity); public: @@ -66,32 +66,32 @@ class SimpleSimilarity : public Similarity { return 1.0; } - + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - + virtual double tf(double freq) { return freq; } - + virtual double sloppyFreq(int32_t distance) { return 2.0; } - + virtual double idf(int32_t docFreq, int32_t numDocs) { return 1.0; } - + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - + virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher) { return newLucene(); @@ -107,13 +107,13 @@ class CountingHitCollector : public Collector sum = 0; docBase = -1; } - + virtual ~CountingHitCollector() { } - + LUCENE_CLASS(CountingHitCollector); - + public: int32_t count; int32_t sum; @@ -125,18 +125,18 @@ class CountingHitCollector : public Collector virtual void setScorer(ScorerPtr scorer) { } - + virtual void collect(int32_t doc) { ++count; sum += doc + docBase; // use it to avoid any possibility of being optimized away } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { this->docBase = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -147,11 +147,11 @@ static void checkNoPrx(DirectoryPtr dir) { HashSet files = dir->listAll(); for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - BOOST_CHECK(!boost::ends_with(*file, L".prx")); + EXPECT_TRUE(!boost::ends_with(*file, L".prx")); } /// Tests whether the DocumentWriter correctly enable the omitTermFreqAndPositions bit in the FieldInfo -BOOST_AUTO_TEST_CASE(testOmitTermFreqAndPositions) +TEST_F(OmitTfTest, testOmitTermFreqAndPositions) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -176,7 +176,7 @@ BOOST_AUTO_TEST_CASE(testOmitTermFreqAndPositions) f1->setOmitTermFreqAndPositions(true); d->add(f1); - f2->setOmitTermFreqAndPositions(false); + f2->setOmitTermFreqAndPositions(false); d->add(f2); writer->addDocument(d); @@ -188,15 +188,15 @@ BOOST_AUTO_TEST_CASE(testOmitTermFreqAndPositions) SegmentReaderPtr reader = SegmentReader::getOnlySegmentReader(ram); FieldInfosPtr fi = reader->fieldInfos(); - BOOST_CHECK(fi->fieldInfo(L"f1")->omitTermFreqAndPositions); - BOOST_CHECK(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); + EXPECT_TRUE(fi->fieldInfo(L"f1")->omitTermFreqAndPositions); + EXPECT_TRUE(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); reader->close(); ram->close(); } /// Tests whether merging of docs that have different omitTermFreqAndPositions for the same field works -BOOST_AUTO_TEST_CASE(testMixedMerge) +TEST_F(OmitTfTest, testMixedMerge) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(testMixedMerge) for (int32_t i = 0; i < 30; ++i) writer->addDocument(d); - + // now we add another document which has term freq for field f2 and not for f1 and verify if the SegmentMerger keep things constant d = newLucene(); @@ -224,9 +224,9 @@ BOOST_AUTO_TEST_CASE(testMixedMerge) f1->setOmitTermFreqAndPositions(true); d->add(f1); - f2->setOmitTermFreqAndPositions(false); + f2->setOmitTermFreqAndPositions(false); d->add(f2); - + for (int32_t i = 0; i < 30; ++i) writer->addDocument(d); @@ -239,16 +239,16 @@ BOOST_AUTO_TEST_CASE(testMixedMerge) SegmentReaderPtr reader = SegmentReader::getOnlySegmentReader(ram); FieldInfosPtr fi = reader->fieldInfos(); - BOOST_CHECK(fi->fieldInfo(L"f1")->omitTermFreqAndPositions); - BOOST_CHECK(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); - + EXPECT_TRUE(fi->fieldInfo(L"f1")->omitTermFreqAndPositions); + EXPECT_TRUE(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); + reader->close(); ram->close(); } -/// Make sure first adding docs that do not omitTermFreqAndPositions for field X, then adding docs that do +/// Make sure first adding docs that do not omitTermFreqAndPositions for field X, then adding docs that do /// omitTermFreqAndPositions for that same field -BOOST_AUTO_TEST_CASE(testMixedRAM) +TEST_F(OmitTfTest, testMixedRAM) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -256,7 +256,7 @@ BOOST_AUTO_TEST_CASE(testMixedRAM) writer->setMaxBufferedDocs(10); writer->setMergeFactor(2); DocumentPtr d = newLucene(); - + // this field will have Tf FieldPtr f1 = newLucene(L"f1", L"This field has term freqs", Field::STORE_NO, Field::INDEX_ANALYZED); d->add(f1); @@ -264,10 +264,10 @@ BOOST_AUTO_TEST_CASE(testMixedRAM) // this field will NOT have Tf FieldPtr f2 = newLucene(L"f2", L"This field has NO Tf in all docs", Field::STORE_NO, Field::INDEX_ANALYZED); d->add(f2); - + for (int32_t i = 0; i < 5; ++i) writer->addDocument(d); - + f2->setOmitTermFreqAndPositions(true); for (int32_t i = 0; i < 20; ++i) @@ -283,15 +283,15 @@ BOOST_AUTO_TEST_CASE(testMixedRAM) SegmentReaderPtr reader = SegmentReader::getOnlySegmentReader(ram); FieldInfosPtr fi = reader->fieldInfos(); - BOOST_CHECK(!fi->fieldInfo(L"f1")->omitTermFreqAndPositions); - BOOST_CHECK(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); + EXPECT_TRUE(!fi->fieldInfo(L"f1")->omitTermFreqAndPositions); + EXPECT_TRUE(fi->fieldInfo(L"f2")->omitTermFreqAndPositions); reader->close(); ram->close(); } /// Verifies no *.prx exists when all fields omit term freq -BOOST_AUTO_TEST_CASE(testNoPrxFile) +TEST_F(OmitTfTest, testNoPrxFile) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -300,12 +300,12 @@ BOOST_AUTO_TEST_CASE(testNoPrxFile) writer->setMergeFactor(2); writer->setUseCompoundFile(false); DocumentPtr d = newLucene(); - + // this field will have Tf FieldPtr f1 = newLucene(L"f1", L"This field has term freqs", Field::STORE_NO, Field::INDEX_ANALYZED); f1->setOmitTermFreqAndPositions(true); d->add(f1); - + for (int32_t i = 0; i < 30; ++i) writer->addDocument(d); @@ -329,78 +329,78 @@ namespace TestBasic { protected: ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL(scorer->score(), 1.0); + EXPECT_EQ(scorer->score(), 1.0); CountingHitCollector::collect(doc); } }; - + class CountingHitCollectorQ2 : public CountingHitCollector { protected: ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL(scorer->score(), 1.0 + (double)doc); + EXPECT_EQ(scorer->score(), 1.0 + (double)doc); CountingHitCollector::collect(doc); } }; - + class CountingHitCollectorQ3 : public CountingHitCollector { protected: ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL(scorer->score(), 1.0); - BOOST_CHECK_NE(doc % 2, 0); + EXPECT_EQ(scorer->score(), 1.0); + EXPECT_NE(doc % 2, 0); CountingHitCollector::collect(doc); } }; - + class CountingHitCollectorQ4 : public CountingHitCollector { protected: ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL(scorer->score(), 1.0); - BOOST_CHECK_EQUAL(doc % 2, 0); + EXPECT_EQ(scorer->score(), 1.0); + EXPECT_EQ(doc % 2, 0); CountingHitCollector::collect(doc); } }; } -BOOST_AUTO_TEST_CASE(testBasic) +TEST_F(OmitTfTest, testBasic) { DirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -409,7 +409,7 @@ BOOST_AUTO_TEST_CASE(testBasic) writer->setMergeFactor(2); writer->setMaxBufferedDocs(2); writer->setSimilarity(newLucene()); - + StringStream sb; for (int32_t i = 0; i < 30; ++i) { @@ -425,7 +425,7 @@ BOOST_AUTO_TEST_CASE(testBasic) writer->addDocument(d); } - + writer->optimize(); // flush writer->close(); @@ -445,24 +445,22 @@ BOOST_AUTO_TEST_CASE(testBasic) TermQueryPtr q4 = newLucene(d); searcher->search(q1, newLucene()); - + searcher->search(q2, newLucene()); - + searcher->search(q3, newLucene()); - + searcher->search(q4, newLucene()); BooleanQueryPtr bq = newLucene(); bq->add(q1, BooleanClause::MUST); bq->add(q4, BooleanClause::MUST); - + CountingHitCollectorPtr collector = newLucene(); - + searcher->search(bq, collector); - BOOST_CHECK_EQUAL(15, collector->count); - + EXPECT_EQ(15, collector->count); + searcher->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/ParallelReaderEmptyIndexTest.cpp b/src/test/index/ParallelReaderEmptyIndexTest.cpp index ece7d36a..5b134e64 100644 --- a/src/test/index/ParallelReaderEmptyIndexTest.cpp +++ b/src/test/index/ParallelReaderEmptyIndexTest.cpp @@ -17,11 +17,11 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(ParallelReaderEmptyIndexTest, LuceneTestFixture) +typedef LuceneTestFixture ParallelReaderEmptyIndexTest; -/// Creates two empty indexes and wraps a ParallelReader around. +/// Creates two empty indexes and wraps a ParallelReader around. /// Adding this reader to a new index should not throw any exception. -BOOST_AUTO_TEST_CASE(testEmptyIndex) +TEST_F(ParallelReaderEmptyIndexTest, testEmptyIndex) { RAMDirectoryPtr rd1 = newLucene(); IndexWriterPtr iw = newLucene(rd1, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -45,9 +45,9 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) rd2->close(); } -/// This method creates an empty index (numFields=0, numDocs=0) but is marked to have TermVectors. +/// This method creates an empty index (numFields=0, numDocs=0) but is marked to have TermVectors. /// Adding this index to another index should not throw any exception. -BOOST_AUTO_TEST_CASE(testEmptyIndexWithVectors) +TEST_F(ParallelReaderEmptyIndexTest, testEmptyIndexWithVectors) { RAMDirectoryPtr rd1 = newLucene(); { @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndexWithVectors) iw->optimize(); iw->close(); } - + RAMDirectoryPtr rd2 = newLucene(); { IndexWriterPtr iw = newLucene(rd2, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndexWithVectors) ParallelReaderPtr pr = newLucene(); pr->add(IndexReader::open(rd1, true)); pr->add(IndexReader::open(rd2, true)); - + iwOut->addIndexes(newCollection(pr)); // ParallelReader closes any IndexReader you added to it @@ -97,5 +97,3 @@ BOOST_AUTO_TEST_CASE(testEmptyIndexWithVectors) checkIndex(rdOut); rdOut->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/ParallelReaderTest.cpp b/src/test/index/ParallelReaderTest.cpp index e0bf617c..f89c33d1 100644 --- a/src/test/index/ParallelReaderTest.cpp +++ b/src/test/index/ParallelReaderTest.cpp @@ -25,16 +25,16 @@ using namespace Lucene; -class ParallelReaderTestFixture : public LuceneTestFixture +class ParallelReaderTest : public LuceneTestFixture { public: - ParallelReaderTestFixture() + ParallelReaderTest() { single = createSingle(); parallel = createParallel(); } - - virtual ~ParallelReaderTestFixture() + + virtual ~ParallelReaderTest() { } @@ -63,7 +63,7 @@ class ParallelReaderTestFixture : public LuceneTestFixture w->close(); return newLucene(dir, false); } - + /// Fields 1 & 2 in one index, 3 & 4 in other, with ParallelReader SearcherPtr createParallel() { @@ -74,7 +74,7 @@ class ParallelReaderTestFixture : public LuceneTestFixture pr->add(IndexReader::open(dir2, false)); return newLucene(pr); } - + DirectoryPtr getDir1() { DirectoryPtr dir1 = newLucene(); @@ -90,7 +90,7 @@ class ParallelReaderTestFixture : public LuceneTestFixture w1->close(); return dir1; } - + DirectoryPtr getDir2() { DirectoryPtr dir2 = newLucene(); @@ -106,28 +106,26 @@ class ParallelReaderTestFixture : public LuceneTestFixture w2->close(); return dir2; } - + void queryTest(QueryPtr query) { Collection parallelHits = parallel->search(query, FilterPtr(), 1000)->scoreDocs; Collection singleHits = single->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(parallelHits.size(), singleHits.size()); + EXPECT_EQ(parallelHits.size(), singleHits.size()); for (int32_t i = 0; i < parallelHits.size(); ++i) { - BOOST_CHECK_CLOSE_FRACTION(parallelHits[i]->score, singleHits[i]->score, 0.001); + EXPECT_NEAR(parallelHits[i]->score, singleHits[i]->score, 0.001); DocumentPtr docParallel = parallel->doc(parallelHits[i]->doc); DocumentPtr docSingle = single->doc(singleHits[i]->doc); - BOOST_CHECK_EQUAL(docParallel->get(L"f1"), docSingle->get(L"f1")); - BOOST_CHECK_EQUAL(docParallel->get(L"f2"), docSingle->get(L"f2")); - BOOST_CHECK_EQUAL(docParallel->get(L"f3"), docSingle->get(L"f3")); - BOOST_CHECK_EQUAL(docParallel->get(L"f4"), docSingle->get(L"f4")); + EXPECT_EQ(docParallel->get(L"f1"), docSingle->get(L"f1")); + EXPECT_EQ(docParallel->get(L"f2"), docSingle->get(L"f2")); + EXPECT_EQ(docParallel->get(L"f3"), docSingle->get(L"f3")); + EXPECT_EQ(docParallel->get(L"f4"), docSingle->get(L"f4")); } } }; -BOOST_FIXTURE_TEST_SUITE(ParallelReaderTest, ParallelReaderTestFixture) - -BOOST_AUTO_TEST_CASE(testQueries) +TEST_F(ParallelReaderTest, testQueries) { queryTest(newLucene(newLucene(L"f1", L"v1"))); queryTest(newLucene(newLucene(L"f2", L"v1"))); @@ -143,7 +141,7 @@ BOOST_AUTO_TEST_CASE(testQueries) queryTest(bq1); } -BOOST_AUTO_TEST_CASE(testFieldNames) +TEST_F(ParallelReaderTest, testFieldNames) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); @@ -151,14 +149,14 @@ BOOST_AUTO_TEST_CASE(testFieldNames) pr->add(IndexReader::open(dir1, false)); pr->add(IndexReader::open(dir2, false)); HashSet fieldNames = pr->getFieldNames(IndexReader::FIELD_OPTION_ALL); - BOOST_CHECK_EQUAL(4, fieldNames.size()); - BOOST_CHECK(fieldNames.contains(L"f1")); - BOOST_CHECK(fieldNames.contains(L"f2")); - BOOST_CHECK(fieldNames.contains(L"f3")); - BOOST_CHECK(fieldNames.contains(L"f4")); + EXPECT_EQ(4, fieldNames.size()); + EXPECT_TRUE(fieldNames.contains(L"f1")); + EXPECT_TRUE(fieldNames.contains(L"f2")); + EXPECT_TRUE(fieldNames.contains(L"f3")); + EXPECT_TRUE(fieldNames.contains(L"f4")); } -BOOST_AUTO_TEST_CASE(testDocument) +TEST_F(ParallelReaderTest, testDocument) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); @@ -174,17 +172,17 @@ BOOST_AUTO_TEST_CASE(testDocument) DocumentPtr doc24 = pr->document(1, newLucene(fields2)); DocumentPtr doc223 = pr->document(1, newLucene(fields3)); - BOOST_CHECK_EQUAL(1, doc11->getFields().size()); - BOOST_CHECK_EQUAL(1, doc24->getFields().size()); - BOOST_CHECK_EQUAL(2, doc223->getFields().size()); + EXPECT_EQ(1, doc11->getFields().size()); + EXPECT_EQ(1, doc24->getFields().size()); + EXPECT_EQ(2, doc223->getFields().size()); - BOOST_CHECK_EQUAL(L"v1", doc11->get(L"f1")); - BOOST_CHECK_EQUAL(L"v2", doc24->get(L"f4")); - BOOST_CHECK_EQUAL(L"v2", doc223->get(L"f2")); - BOOST_CHECK_EQUAL(L"v2", doc223->get(L"f3")); + EXPECT_EQ(L"v1", doc11->get(L"f1")); + EXPECT_EQ(L"v2", doc24->get(L"f4")); + EXPECT_EQ(L"v2", doc223->get(L"f2")); + EXPECT_EQ(L"v2", doc223->get(L"f3")); } -BOOST_AUTO_TEST_CASE(testIncompatibleIndexes) +TEST_F(ParallelReaderTest, testIncompatibleIndexes) { // two documents DirectoryPtr dir1 = getDir1(); @@ -199,11 +197,18 @@ BOOST_AUTO_TEST_CASE(testIncompatibleIndexes) ParallelReaderPtr pr = newLucene(); pr->add(IndexReader::open(dir1, false)); - - BOOST_CHECK_EXCEPTION(pr->add(IndexReader::open(dir2, false)), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + + try + { + pr->add(IndexReader::open(dir2, false)); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } -BOOST_AUTO_TEST_CASE(testIsCurrent) +TEST_F(ParallelReaderTest, testIsCurrent) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); @@ -211,23 +216,23 @@ BOOST_AUTO_TEST_CASE(testIsCurrent) pr->add(IndexReader::open(dir1, false)); pr->add(IndexReader::open(dir2, false)); - BOOST_CHECK(pr->isCurrent()); + EXPECT_TRUE(pr->isCurrent()); IndexReaderPtr modifier = IndexReader::open(dir1, false); modifier->setNorm(0, L"f1", (uint8_t)100); modifier->close(); // one of the two IndexReaders which ParallelReader is using is not current anymore - BOOST_CHECK(!pr->isCurrent()); + EXPECT_TRUE(!pr->isCurrent()); modifier = IndexReader::open(dir2, false); modifier->setNorm(0, L"f3", (uint8_t)100); modifier->close(); // now both are not current anymore - BOOST_CHECK(!pr->isCurrent()); + EXPECT_TRUE(!pr->isCurrent()); } -BOOST_AUTO_TEST_CASE(testIsOptimized) +TEST_F(ParallelReaderTest, testIsOptimized) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); @@ -248,7 +253,7 @@ BOOST_AUTO_TEST_CASE(testIsOptimized) ParallelReaderPtr pr = newLucene(); pr->add(IndexReader::open(dir1, false)); pr->add(IndexReader::open(dir2, false)); - BOOST_CHECK(!pr->isOptimized()); + EXPECT_TRUE(!pr->isOptimized()); pr->close(); modifier = newLucene(dir1, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -259,7 +264,7 @@ BOOST_AUTO_TEST_CASE(testIsOptimized) pr->add(IndexReader::open(dir1, false)); pr->add(IndexReader::open(dir2, false)); // just one of the two indexes are optimized - BOOST_CHECK(!pr->isOptimized()); + EXPECT_TRUE(!pr->isOptimized()); pr->close(); modifier = newLucene(dir2, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -270,15 +275,15 @@ BOOST_AUTO_TEST_CASE(testIsOptimized) pr->add(IndexReader::open(dir1, false)); pr->add(IndexReader::open(dir2, false)); // now both indexes are optimized - BOOST_CHECK(pr->isOptimized()); + EXPECT_TRUE(pr->isOptimized()); pr->close(); } -BOOST_AUTO_TEST_CASE(testAllTermDocs) +TEST_F(ParallelReaderTest, testAllTermDocs) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); - + ParallelReaderPtr pr = newLucene(); pr->add(IndexReader::open(dir1, false)); pr->add(IndexReader::open(dir2, false)); @@ -286,14 +291,12 @@ BOOST_AUTO_TEST_CASE(testAllTermDocs) TermDocsPtr td = pr->termDocs(TermPtr()); for (int32_t i = 0; i < NUM_DOCS; ++i) { - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(i, td->doc()); - BOOST_CHECK_EQUAL(1, td->freq()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(i, td->doc()); + EXPECT_EQ(1, td->freq()); } td->close(); pr->close(); dir1->close(); dir2->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/ParallelTermEnumTest.cpp b/src/test/index/ParallelTermEnumTest.cpp index 9384471b..fbfa60e3 100644 --- a/src/test/index/ParallelTermEnumTest.cpp +++ b/src/test/index/ParallelTermEnumTest.cpp @@ -20,10 +20,10 @@ using namespace Lucene; -class ParallelTermEnumTestFixture : public LuceneTestFixture +class ParallelTermEnumTest : public LuceneTestFixture { public: - ParallelTermEnumTestFixture() + ParallelTermEnumTest() { RAMDirectoryPtr rd1 = newLucene(); IndexWriterPtr iw1 = newLucene(rd1, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -49,8 +49,8 @@ class ParallelTermEnumTestFixture : public LuceneTestFixture this->ir1 = IndexReader::open(rd1, true); this->ir2 = IndexReader::open(rd2, true); } - - virtual ~ParallelTermEnumTestFixture() + + virtual ~ParallelTermEnumTest() { ir1->close(); ir2->close(); @@ -61,9 +61,7 @@ class ParallelTermEnumTestFixture : public LuceneTestFixture IndexReaderPtr ir2; }; -BOOST_FIXTURE_TEST_SUITE(ParallelTermEnumTest, ParallelTermEnumTestFixture) - -BOOST_AUTO_TEST_CASE(testParallelTermEnum) +TEST_F(ParallelTermEnumTest, testParallelTermEnum) { ParallelReaderPtr pr = newLucene(); pr->add(ir1); @@ -72,103 +70,101 @@ BOOST_AUTO_TEST_CASE(testParallelTermEnum) TermDocsPtr td = pr->termDocs(); TermEnumPtr te = pr->terms(); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field1:brown", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field1:fox", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field1:jumps", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field1:quick", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field1:the", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field2:brown", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field2:fox", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field2:jumps", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field2:quick", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field2:the", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field3:dog", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field3:fox", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field3:jumps", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field3:lazy", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field3:over", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(te->next()); - BOOST_CHECK_EQUAL(L"field3:the", te->term()->toString()); - td->seek(te->term()); - BOOST_CHECK(td->next()); - BOOST_CHECK_EQUAL(0, td->doc()); - BOOST_CHECK(!td->next()); - BOOST_CHECK(!te->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field1:brown", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field1:fox", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field1:jumps", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field1:quick", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field1:the", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field2:brown", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field2:fox", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field2:jumps", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field2:quick", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field2:the", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field3:dog", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field3:fox", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field3:jumps", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field3:lazy", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field3:over", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(te->next()); + EXPECT_EQ(L"field3:the", te->term()->toString()); + td->seek(te->term()); + EXPECT_TRUE(td->next()); + EXPECT_EQ(0, td->doc()); + EXPECT_TRUE(!td->next()); + EXPECT_TRUE(!te->next()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/PayloadsTest.cpp b/src/test/index/PayloadsTest.cpp index e3d46ae5..75578016 100644 --- a/src/test/index/PayloadsTest.cpp +++ b/src/test/index/PayloadsTest.cpp @@ -33,7 +33,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PayloadsTest, LuceneTestFixture) +typedef LuceneTestFixture PayloadsTest; DECLARE_SHARED_PTR(PayloadData) DECLARE_SHARED_PTR(PayloadFilter) @@ -49,11 +49,11 @@ class PayloadData : public LuceneObject this->offset = offset; this->length = length; } - + virtual ~PayloadData() { } - + LUCENE_CLASS(PayloadData); public: @@ -75,11 +75,11 @@ class PayloadFilter : public TokenFilter this->offset = offset; this->payloadAtt = addAttribute(); } - + virtual ~PayloadFilter() { } - + LUCENE_CLASS(PayloadFilter); public: @@ -117,11 +117,11 @@ class PayloadAnalyzer : public Analyzer { fieldToData = HashMap::newInstance(); } - + virtual ~PayloadAnalyzer() { } - + LUCENE_CLASS(PayloadAnalyzer); public: @@ -132,12 +132,13 @@ class PayloadAnalyzer : public Analyzer { fieldToData.put(field, newLucene(0, data, offset, length)); } - + void setPayloadData(const String& field, int32_t numFieldInstancesToSkip, ByteArray data, int32_t offset, int32_t length) { - fieldToData.put(field, newLucene(numFieldInstancesToSkip, data, offset, length)); + PayloadDataPtr payload = newLucene(numFieldInstancesToSkip, data, offset, length); + fieldToData.put(field, payload); } - + virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { PayloadDataPtr payload = fieldToData.get(fieldName); @@ -183,42 +184,56 @@ static Collection generateTerms(const String& fieldName, int32_t n) } /// Simple tests to test the Payload class -BOOST_AUTO_TEST_CASE(testPayload) +TEST_F(PayloadsTest, testPayload) { ByteArray testData(ByteArray::newInstance(15)); uint8_t input[15] = { 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '!' }; std::memcpy(testData.get(), input, 15); PayloadPtr payload = newLucene(testData); - BOOST_CHECK_EQUAL(testData.size(), payload->length()); - + EXPECT_EQ(testData.size(), payload->length()); + // test copyTo() ByteArray target(ByteArray::newInstance(testData.size() - 1)); - BOOST_CHECK_EXCEPTION(payload->copyTo(target, 0), IndexOutOfBoundsException, check_exception(LuceneException::IndexOutOfBounds)); - + try + { + payload->copyTo(target, 0); + } + catch (IndexOutOfBoundsException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); + } + target.resize(testData.size() + 3); payload->copyTo(target, 3); - + for (int32_t i = 0; i < testData.size(); ++i) - BOOST_CHECK_EQUAL(testData[i], target[i + 3]); - + EXPECT_EQ(testData[i], target[i + 3]); + // test toByteArray() target = payload->toByteArray(); - BOOST_CHECK(testData.equals(target)); - + EXPECT_TRUE(testData.equals(target)); + // test byteAt() for (int32_t i = 0; i < testData.size(); ++i) - BOOST_CHECK_EQUAL(payload->byteAt(i), testData[i]); - - BOOST_CHECK_EXCEPTION(payload->byteAt(testData.size() + 1), IndexOutOfBoundsException, check_exception(LuceneException::IndexOutOfBounds)); - + EXPECT_EQ(payload->byteAt(i), testData[i]); + + try + { + payload->byteAt(testData.size() + 1); + } + catch (IndexOutOfBoundsException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); + } + PayloadPtr clone = boost::dynamic_pointer_cast(payload->clone()); - BOOST_CHECK_EQUAL(payload->length(), clone->length()); + EXPECT_EQ(payload->length(), clone->length()); for (int32_t i = 0; i < payload->length(); ++i) - BOOST_CHECK_EQUAL(payload->byteAt(i), clone->byteAt(i)); + EXPECT_EQ(payload->byteAt(i), clone->byteAt(i)); } /// Tests whether the DocumentWriter and SegmentMerger correctly enable the payload bit in the FieldInfo -BOOST_AUTO_TEST_CASE(testPayloadFieldBit) +TEST_F(PayloadsTest, testPayloadFieldBit) { DirectoryPtr ram = newLucene(); PayloadAnalyzerPtr analyzer = newLucene(); @@ -231,25 +246,26 @@ BOOST_AUTO_TEST_CASE(testPayloadFieldBit) // even if only some term positions have payloads d->add(newLucene(L"f2", L"This field has payloads in all docs", Field::STORE_NO, Field::INDEX_ANALYZED)); d->add(newLucene(L"f2", L"This field has payloads in all docs", Field::STORE_NO, Field::INDEX_ANALYZED)); - // this field is used to verify if the SegmentMerger enables payloads for a field if it has payloads + // this field is used to verify if the SegmentMerger enables payloads for a field if it has payloads // enabled in only some documents d->add(newLucene(L"f3", L"This field has payloads in some docs", Field::STORE_NO, Field::INDEX_ANALYZED)); // only add payload data for field f2 - + ByteArray someData(ByteArray::newInstance(8)); uint8_t input[8] = { 's', 'o', 'm', 'e', 'd', 'a', 't', 'a' }; std::memcpy(someData.get(), input, 8); - + analyzer->setPayloadData(L"f2", 1, someData, 0, 1); + writer->addDocument(d); // flush - writer->close(); + writer->close(); SegmentReaderPtr reader = SegmentReader::getOnlySegmentReader(ram); FieldInfosPtr fi = reader->fieldInfos(); - BOOST_CHECK(!fi->fieldInfo(L"f1")->storePayloads); - BOOST_CHECK(fi->fieldInfo(L"f2")->storePayloads); - BOOST_CHECK(!fi->fieldInfo(L"f3")->storePayloads); + EXPECT_TRUE(!fi->fieldInfo(L"f1")->storePayloads); + EXPECT_TRUE(fi->fieldInfo(L"f2")->storePayloads); + EXPECT_TRUE(!fi->fieldInfo(L"f3")->storePayloads); reader->close(); // now we add another document which has payloads for field f3 and verify if the SegmentMerger @@ -271,13 +287,13 @@ BOOST_AUTO_TEST_CASE(testPayloadFieldBit) reader = SegmentReader::getOnlySegmentReader(ram); fi = reader->fieldInfos(); - BOOST_CHECK(!fi->fieldInfo(L"f1")->storePayloads); - BOOST_CHECK(fi->fieldInfo(L"f2")->storePayloads); - BOOST_CHECK(fi->fieldInfo(L"f3")->storePayloads); + EXPECT_TRUE(!fi->fieldInfo(L"f1")->storePayloads); + EXPECT_TRUE(fi->fieldInfo(L"f2")->storePayloads); + EXPECT_TRUE(fi->fieldInfo(L"f3")->storePayloads); reader->close(); } -/// Builds an index with payloads in the given Directory and performs different +/// Builds an index with payloads in the given Directory and performs different /// tests to verify the payload encoding static void encodingTest(DirectoryPtr dir) { @@ -290,7 +306,7 @@ static void encodingTest(DirectoryPtr dir) int32_t numTerms = 5; String fieldName = L"f1"; - int32_t numDocs = skipInterval + 1; + int32_t numDocs = skipInterval + 1; // create content for the test documents with just a few terms Collection terms = generateTerms(fieldName, numTerms); StringStream sb; @@ -303,7 +319,7 @@ static void encodingTest(DirectoryPtr dir) DocumentPtr d = newLucene(); d->add(newLucene(fieldName, content, Field::STORE_NO, Field::INDEX_ANALYZED)); - + // add the same document multiple times to have the same payload lengths for all // occurrences within two consecutive skip intervals int32_t offset = 0; @@ -313,10 +329,10 @@ static void encodingTest(DirectoryPtr dir) offset += numTerms; writer->addDocument(d); } - + // make sure we create more than one segment to test merging writer->commit(); - + for (int32_t i = 0; i < numDocs; ++i) { analyzer->setPayloadData(fieldName, payloadData, offset, i); @@ -336,13 +352,13 @@ static void encodingTest(DirectoryPtr dir) Collection tps = Collection::newInstance(numTerms); for (int32_t i = 0; i < numTerms; ++i) tps[i] = reader->termPositions(terms[i]); - + while (tps[0]->next()) { for (int32_t i = 1; i < numTerms; ++i) tps[i]->next(); int32_t freq = tps[0]->freq(); - + for (int32_t i = 0; i < freq; ++i) { for (int32_t j = 0; j < numTerms; ++j) @@ -353,50 +369,57 @@ static void encodingTest(DirectoryPtr dir) } } } - + for (int32_t i = 0; i < numTerms; ++i) tps[i]->close(); - - BOOST_CHECK(payloadData.equals(verifyPayloadData)); - + + EXPECT_TRUE(payloadData.equals(verifyPayloadData)); + // test lazy skipping TermPositionsPtr tp = reader->termPositions(terms[0]); tp->next(); tp->nextPosition(); // now we don't read this payload tp->nextPosition(); - BOOST_CHECK_EQUAL(1, tp->getPayloadLength()); + EXPECT_EQ(1, tp->getPayloadLength()); ByteArray payload = tp->getPayload(ByteArray(), 0); - BOOST_CHECK_EQUAL(payload[0], payloadData[numTerms]); + EXPECT_EQ(payload[0], payloadData[numTerms]); tp->nextPosition(); // we don't read this payload and skip to a different document tp->skipTo(5); tp->nextPosition(); - BOOST_CHECK_EQUAL(1, tp->getPayloadLength()); + EXPECT_EQ(1, tp->getPayloadLength()); payload = tp->getPayload(ByteArray(), 0); - BOOST_CHECK_EQUAL(payload[0], payloadData[5 * numTerms]); - + EXPECT_EQ(payload[0], payloadData[5 * numTerms]); + // Test different lengths at skip points tp->seek(terms[1]); tp->next(); tp->nextPosition(); - BOOST_CHECK_EQUAL(1, tp->getPayloadLength()); + EXPECT_EQ(1, tp->getPayloadLength()); tp->skipTo(skipInterval - 1); tp->nextPosition(); - BOOST_CHECK_EQUAL(1, tp->getPayloadLength()); + EXPECT_EQ(1, tp->getPayloadLength()); tp->skipTo(2 * skipInterval - 1); tp->nextPosition(); - BOOST_CHECK_EQUAL(1, tp->getPayloadLength()); + EXPECT_EQ(1, tp->getPayloadLength()); tp->skipTo(3 * skipInterval - 1); tp->nextPosition(); - BOOST_CHECK_EQUAL(3 * skipInterval - 2 * numDocs - 1, tp->getPayloadLength()); - + EXPECT_EQ(3 * skipInterval - 2 * numDocs - 1, tp->getPayloadLength()); + // Test multiple call of getPayload() tp->getPayload(ByteArray(), 0); - + // it is forbidden to call getPayload() more than once without calling nextPosition() - BOOST_CHECK_EXCEPTION(tp->getPayload(ByteArray(), 0), IOException, check_exception(LuceneException::IO)); + try + { + tp->getPayload(ByteArray(), 0); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } reader->close(); @@ -426,13 +449,13 @@ static void encodingTest(DirectoryPtr dir) ByteArray portion(ByteArray::newInstance(1500)); MiscUtils::arrayCopy(payloadData.get(), 100, portion.get(), 0, 1500); - BOOST_CHECK(portion.equals(verifyPayloadData)); - + EXPECT_TRUE(portion.equals(verifyPayloadData)); + reader->close(); } /// Tests if payloads are correctly stored and loaded using both RamDirectory and FSDirectory -BOOST_AUTO_TEST_CASE(testPayloadsEncoding) +TEST_F(PayloadsTest, testPayloadsEncoding) { // first perform the test using a RAMDirectory DirectoryPtr dir = newLucene(); @@ -448,7 +471,7 @@ BOOST_AUTO_TEST_CASE(testPayloadsEncoding) namespace TestThreadSafety { DECLARE_SHARED_PTR(ByteArrayPool) - + class ByteArrayPool : public LuceneObject { public: @@ -458,42 +481,42 @@ namespace TestThreadSafety for (int32_t i = 0; i < capacity; ++i) pool.add(ByteArray::newInstance(size)); } - + virtual ~ByteArrayPool() { } - + LUCENE_CLASS(ByteArrayPool); - + public: Collection pool; - + public: String bytesToString(ByteArray bytes) { SyncLock syncLock(this); return Base64::encode(bytes); } - + ByteArray get() { SyncLock syncLock(this); return pool.removeFirst(); } - + void release(ByteArray b) { SyncLock syncLock(this); pool.add(b); } - + int32_t size() { SyncLock syncLock(this); return pool.size(); } }; - + class PoolingPayloadTokenStream : public TokenStream { public: @@ -507,13 +530,13 @@ namespace TestThreadSafety payloadAtt = addAttribute(); termAtt = addAttribute(); } - + virtual ~PoolingPayloadTokenStream() { } - + LUCENE_CLASS(PoolingPayloadTokenStream); - + public: ByteArray payload; bool first; @@ -522,7 +545,7 @@ namespace TestThreadSafety TermAttributePtr termAtt; PayloadAttributePtr payloadAtt; - + public: virtual bool incrementToken() { @@ -534,13 +557,13 @@ namespace TestThreadSafety payloadAtt->setPayload(newLucene(payload)); return true; } - + virtual void close() { pool->release(payload); } }; - + class IngesterThread : public LuceneThread { public: @@ -550,18 +573,18 @@ namespace TestThreadSafety this->pool = pool; this->writer = writer; } - + virtual ~IngesterThread() { } - + LUCENE_CLASS(IngesterThread); - + protected: int32_t numDocs; ByteArrayPoolPtr pool; IndexWriterPtr writer; - + public: virtual void run() { @@ -576,13 +599,13 @@ namespace TestThreadSafety } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; } -BOOST_AUTO_TEST_CASE(testThreadSafety) +TEST_F(PayloadsTest, testThreadSafety) { int32_t numThreads = 5; int32_t numDocs = 50; @@ -590,17 +613,17 @@ BOOST_AUTO_TEST_CASE(testThreadSafety) DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - + Collection ingesters = Collection::newInstance(numThreads); for (int32_t i = 0; i < numThreads; ++i) { ingesters[i] = newLucene(numDocs, pool, writer); ingesters[i]->start(); } - + for (int32_t i = 0; i < numThreads; ++i) ingesters[i]->join(); - + writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); TermEnumPtr terms = reader->terms(); @@ -613,16 +636,14 @@ BOOST_AUTO_TEST_CASE(testThreadSafety) for (int32_t i = 0; i < freq; ++i) { tp->nextPosition(); - BOOST_CHECK_EQUAL(pool->bytesToString(tp->getPayload(ByteArray::newInstance(5), 0)), terms->term()->text()); + EXPECT_EQ(pool->bytesToString(tp->getPayload(ByteArray::newInstance(5), 0)), terms->term()->text()); } } tp->close(); } - + terms->close(); reader->close(); - BOOST_CHECK_EQUAL(pool->size(), numThreads); + EXPECT_EQ(pool->size(), numThreads); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/PositionBasedTermVectorMapperTest.cpp b/src/test/index/PositionBasedTermVectorMapperTest.cpp index 1238526f..7e55e7bc 100644 --- a/src/test/index/PositionBasedTermVectorMapperTest.cpp +++ b/src/test/index/PositionBasedTermVectorMapperTest.cpp @@ -13,22 +13,22 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PositionBasedTermVectorMapperTest, LuceneTestFixture) +typedef LuceneTestFixture PositionBasedTermVectorMapperTest; -BOOST_AUTO_TEST_CASE(testPayload) +TEST_F(PositionBasedTermVectorMapperTest, testPayload) { Collection tokens = newCollection(L"here", L"is", L"some", L"text", L"to", L"test", L"extra"); Collection< Collection > thePositions = Collection< Collection >::newInstance(tokens.size()); Collection< Collection > offsets = Collection< Collection >::newInstance(tokens.size()); int32_t numPositions = 0; - + // save off the last one so we can add it with the same positions as some of the others, but in a predictable way for (int32_t i = 0; i < tokens.size() - 1; ++i) { thePositions[i] = Collection::newInstance(2 * i + 1); // give 'em all some positions for (int32_t j = 0; j < thePositions[i].size(); ++j) thePositions[i][j] = numPositions++; - + offsets[i] = Collection::newInstance(thePositions[i].size()); for (int32_t j = 0; j < offsets[i].size(); ++j) offsets[i][j] = newLucene(j, j + 1); // the actual value here doesn't much matter @@ -38,10 +38,10 @@ BOOST_AUTO_TEST_CASE(testPayload) thePositions[tokens.size() - 1][0] = 0; // put this at the same position as "here" offsets[tokens.size() - 1] = Collection::newInstance(1); offsets[tokens.size() - 1][0] = newLucene(0, 1); - + PositionBasedTermVectorMapperPtr mapper = newLucene(); mapper->setExpectations(L"test", tokens.size(), true, true); - + // Test single position for (int32_t i = 0; i < tokens.size(); ++i) { @@ -50,32 +50,30 @@ BOOST_AUTO_TEST_CASE(testPayload) } MapStringMapIntTermVectorsPositionInfo map = mapper->getFieldToTerms(); - BOOST_CHECK(map); - BOOST_CHECK_EQUAL(map.size(), 1); + EXPECT_TRUE(map); + EXPECT_EQ(map.size(), 1); MapIntTermVectorsPositionInfo positions = map.get(L"test"); - BOOST_CHECK(positions); + EXPECT_TRUE(positions); - BOOST_CHECK_EQUAL(positions.size(), numPositions); + EXPECT_EQ(positions.size(), numPositions); BitSetPtr bits = newLucene(numPositions); for (MapIntTermVectorsPositionInfo::iterator entry = positions.begin(); entry != positions.end(); ++entry) { - BOOST_CHECK(entry->second); + EXPECT_TRUE(entry->second); int32_t pos = entry->first; bits->set(pos); - BOOST_CHECK_EQUAL(entry->second->getPosition(), pos); - BOOST_CHECK(entry->second->getOffsets()); + EXPECT_EQ(entry->second->getPosition(), pos); + EXPECT_TRUE(entry->second->getOffsets()); if (pos == 0) { - BOOST_CHECK_EQUAL(entry->second->getTerms().size(), 2); // need a test for multiple terms at one pos - BOOST_CHECK_EQUAL(entry->second->getOffsets().size(), 2); + EXPECT_EQ(entry->second->getTerms().size(), 2); // need a test for multiple terms at one pos + EXPECT_EQ(entry->second->getOffsets().size(), 2); } else { - BOOST_CHECK_EQUAL(entry->second->getTerms().size(), 1); // need a test for multiple terms at one pos - BOOST_CHECK_EQUAL(entry->second->getOffsets().size(), 1); + EXPECT_EQ(entry->second->getTerms().size(), 1); // need a test for multiple terms at one pos + EXPECT_EQ(entry->second->getOffsets().size(), 1); } } - BOOST_CHECK_EQUAL(bits->cardinality(), numPositions); + EXPECT_EQ(bits->cardinality(), numPositions); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/SegmentMergerTest.cpp b/src/test/index/SegmentMergerTest.cpp index 97f69e53..2ee5050a 100644 --- a/src/test/index/SegmentMergerTest.cpp +++ b/src/test/index/SegmentMergerTest.cpp @@ -23,10 +23,10 @@ using namespace Lucene; -class SegmentMergerTestFixture : public LuceneTestFixture, public DocHelper +class SegmentMergerTest : public LuceneTestFixture, public DocHelper { public: - SegmentMergerTestFixture() + SegmentMergerTest() { mergedDir = newLucene(); mergedSegment = L"test"; @@ -34,7 +34,7 @@ class SegmentMergerTestFixture : public LuceneTestFixture, public DocHelper doc1 = newLucene(); merge2Dir = newLucene(); doc2 = newLucene(); - + DocHelper::setupDoc(doc1); SegmentInfoPtr info1 = DocHelper::writeDoc(merge1Dir, doc1); DocHelper::setupDoc(doc2); @@ -42,8 +42,8 @@ class SegmentMergerTestFixture : public LuceneTestFixture, public DocHelper reader1 = SegmentReader::get(true, info1, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); reader2 = SegmentReader::get(true, info2, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); } - - virtual ~SegmentMergerTestFixture() + + virtual ~SegmentMergerTest() { } @@ -51,12 +51,12 @@ class SegmentMergerTestFixture : public LuceneTestFixture, public DocHelper // The variables for the new merged segment DirectoryPtr mergedDir; String mergedSegment; - + // First segment to be merged DirectoryPtr merge1Dir; DocumentPtr doc1; SegmentReaderPtr reader1; - + // Second Segment to be merged DirectoryPtr merge2Dir; DocumentPtr doc2; @@ -71,79 +71,75 @@ class SegmentMergerTestFixture : public LuceneTestFixture, public DocHelper FieldPtr f = DocHelper::fields[i]; if (f->isIndexed()) { - BOOST_CHECK_EQUAL(reader->hasNorms(f->name()), !f->getOmitNorms()); - BOOST_CHECK_EQUAL(reader->hasNorms(f->name()), !DocHelper::noNorms.contains(f->name())); - + EXPECT_EQ(reader->hasNorms(f->name()), !f->getOmitNorms()); + EXPECT_EQ(reader->hasNorms(f->name()), !DocHelper::noNorms.contains(f->name())); + if (!reader->hasNorms(f->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms(f->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); - BOOST_CHECK(!norms); + EXPECT_TRUE(!norms); norms.resize(reader->maxDoc()); reader->norms(f->name(), norms, 0); for (int32_t j = 0; j < reader->maxDoc(); ++j) - BOOST_CHECK_EQUAL(norms[j], norm1); + EXPECT_EQ(norms[j], norm1); } } } } }; -BOOST_FIXTURE_TEST_SUITE(SegmentMergerTest, SegmentMergerTestFixture) - -BOOST_AUTO_TEST_CASE(testMerge) +TEST_F(SegmentMergerTest, testMerge) { SegmentMergerPtr merger = newLucene(mergedDir, mergedSegment); merger->add(reader1); merger->add(reader2); int32_t docsMerged = merger->merge(); merger->closeReaders(); - BOOST_CHECK_EQUAL(docsMerged, 2); - + EXPECT_EQ(docsMerged, 2); + // Should be able to open a new SegmentReader against the new directory SegmentReaderPtr mergedReader = SegmentReader::get(true, newLucene(mergedSegment, docsMerged, mergedDir, false, true), IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); - BOOST_CHECK(mergedReader); - BOOST_CHECK_EQUAL(mergedReader->numDocs(), 2); + EXPECT_TRUE(mergedReader); + EXPECT_EQ(mergedReader->numDocs(), 2); DocumentPtr newDoc1 = mergedReader->document(0); - BOOST_CHECK(newDoc1); - + EXPECT_TRUE(newDoc1); + // There are 2 unstored fields on the document - BOOST_CHECK_EQUAL(DocHelper::numFields(newDoc1), DocHelper::numFields(doc1) - DocHelper::unstored.size()); + EXPECT_EQ(DocHelper::numFields(newDoc1), DocHelper::numFields(doc1) - DocHelper::unstored.size()); DocumentPtr newDoc2 = mergedReader->document(1); - BOOST_CHECK(newDoc2); - BOOST_CHECK_EQUAL(DocHelper::numFields(newDoc2), DocHelper::numFields(doc2) - DocHelper::unstored.size()); + EXPECT_TRUE(newDoc2); + EXPECT_EQ(DocHelper::numFields(newDoc2), DocHelper::numFields(doc2) - DocHelper::unstored.size()); TermDocsPtr termDocs = mergedReader->termDocs(newLucene(DocHelper::TEXT_FIELD_2_KEY, L"field")); - BOOST_CHECK(termDocs); - BOOST_CHECK(termDocs->next()); + EXPECT_TRUE(termDocs); + EXPECT_TRUE(termDocs->next()); HashSet stored = mergedReader->getFieldNames(IndexReader::FIELD_OPTION_INDEXED_WITH_TERMVECTOR); - BOOST_CHECK(stored); - - BOOST_CHECK_EQUAL(stored.size(), 3); + EXPECT_TRUE(stored); + + EXPECT_EQ(stored.size(), 3); TermFreqVectorPtr vector = mergedReader->getTermFreqVector(0, DocHelper::TEXT_FIELD_2_KEY); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); Collection terms = vector->getTerms(); - BOOST_CHECK(terms); - - BOOST_CHECK_EQUAL(terms.size(), 3); + EXPECT_TRUE(terms); + + EXPECT_EQ(terms.size(), 3); Collection freqs = vector->getTermFrequencies(); - BOOST_CHECK(freqs); - - BOOST_CHECK(boost::dynamic_pointer_cast(vector)); - + EXPECT_TRUE(freqs); + + EXPECT_TRUE(boost::dynamic_pointer_cast(vector)); + for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; int32_t freq = freqs[i]; - - BOOST_CHECK(String(DocHelper::FIELD_2_TEXT).find(term) != String::npos); - BOOST_CHECK_EQUAL(DocHelper::FIELD_2_FREQS[i], freq); + + EXPECT_TRUE(String(DocHelper::FIELD_2_TEXT).find(term) != String::npos); + EXPECT_EQ(DocHelper::FIELD_2_FREQS[i], freq); } - + checkNorms(mergedReader); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/SegmentReaderTest.cpp b/src/test/index/SegmentReaderTest.cpp index 198c6cd5..dbb2ae44 100644 --- a/src/test/index/SegmentReaderTest.cpp +++ b/src/test/index/SegmentReaderTest.cpp @@ -22,10 +22,10 @@ using namespace Lucene; -class SegmentReaderTestFixture : public LuceneTestFixture, public DocHelper +class SegmentReaderTest : public LuceneTestFixture, public DocHelper { public: - SegmentReaderTestFixture() + SegmentReaderTest() { dir = newLucene(); testDoc = newLucene(); @@ -33,8 +33,8 @@ class SegmentReaderTestFixture : public LuceneTestFixture, public DocHelper SegmentInfoPtr info = DocHelper::writeDoc(dir, testDoc); reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); } - - virtual ~SegmentReaderTestFixture() + + virtual ~SegmentReaderTest() { } @@ -44,102 +44,100 @@ class SegmentReaderTestFixture : public LuceneTestFixture, public DocHelper SegmentReaderPtr reader; }; -BOOST_FIXTURE_TEST_SUITE(SegmentReaderTest, SegmentReaderTestFixture) - -BOOST_AUTO_TEST_CASE(testSegmentReader) +TEST_F(SegmentReaderTest, testSegmentReader) { - BOOST_CHECK(dir); - BOOST_CHECK(reader); - BOOST_CHECK(DocHelper::nameValues.size() > 0); - BOOST_CHECK_EQUAL(DocHelper::numFields(testDoc), DocHelper::all.size()); + EXPECT_TRUE(dir); + EXPECT_TRUE(reader); + EXPECT_TRUE(DocHelper::nameValues.size() > 0); + EXPECT_EQ(DocHelper::numFields(testDoc), DocHelper::all.size()); } -BOOST_AUTO_TEST_CASE(testDocument) +TEST_F(SegmentReaderTest, testDocument) { - BOOST_CHECK_EQUAL(reader->numDocs(), 1); - BOOST_CHECK(reader->maxDoc() >= 1); + EXPECT_EQ(reader->numDocs(), 1); + EXPECT_TRUE(reader->maxDoc() >= 1); DocumentPtr result = reader->document(0); - BOOST_CHECK(result); - + EXPECT_TRUE(result); + // There are 2 unstored fields on the document that are not preserved across writing - BOOST_CHECK_EQUAL(DocHelper::numFields(result), DocHelper::numFields(testDoc) - DocHelper::unstored.size()); + EXPECT_EQ(DocHelper::numFields(result), DocHelper::numFields(testDoc) - DocHelper::unstored.size()); Collection fields = result->getFields(); for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { - BOOST_CHECK(*field); - BOOST_CHECK(DocHelper::nameValues.contains((*field)->name())); + EXPECT_TRUE(*field); + EXPECT_TRUE(DocHelper::nameValues.contains((*field)->name())); } } -BOOST_AUTO_TEST_CASE(testDelete) +TEST_F(SegmentReaderTest, testDelete) { DocumentPtr docToDelete = newLucene(); DocHelper::setupDoc(docToDelete); SegmentInfoPtr info = DocHelper::writeDoc(dir, docToDelete); SegmentReaderPtr deleteReader = SegmentReader::get(false, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); - BOOST_CHECK(deleteReader); - BOOST_CHECK_EQUAL(deleteReader->numDocs(), 1); + EXPECT_TRUE(deleteReader); + EXPECT_EQ(deleteReader->numDocs(), 1); deleteReader->deleteDocument(0); - BOOST_CHECK(deleteReader->isDeleted(0)); - BOOST_CHECK(deleteReader->hasDeletions()); - BOOST_CHECK_EQUAL(deleteReader->numDocs(), 0); + EXPECT_TRUE(deleteReader->isDeleted(0)); + EXPECT_TRUE(deleteReader->hasDeletions()); + EXPECT_EQ(deleteReader->numDocs(), 0); } -BOOST_AUTO_TEST_CASE(testGetFieldNameVariations) +TEST_F(SegmentReaderTest, testGetFieldNameVariations) { HashSet result = reader->getFieldNames(IndexReader::FIELD_OPTION_ALL); - BOOST_CHECK(result); - BOOST_CHECK_EQUAL(result.size(), DocHelper::all.size()); + EXPECT_TRUE(result); + EXPECT_EQ(result.size(), DocHelper::all.size()); for (HashSet::iterator field = result.begin(); field != result.end(); ++field) - BOOST_CHECK(DocHelper::nameValues.contains(*field) || field->empty()); + EXPECT_TRUE(DocHelper::nameValues.contains(*field) || field->empty()); result = reader->getFieldNames(IndexReader::FIELD_OPTION_INDEXED); - BOOST_CHECK(result); - BOOST_CHECK_EQUAL(result.size(), DocHelper::indexed.size()); + EXPECT_TRUE(result); + EXPECT_EQ(result.size(), DocHelper::indexed.size()); for (HashSet::iterator field = result.begin(); field != result.end(); ++field) - BOOST_CHECK(DocHelper::indexed.contains(*field) || field->empty()); + EXPECT_TRUE(DocHelper::indexed.contains(*field) || field->empty()); result = reader->getFieldNames(IndexReader::FIELD_OPTION_UNINDEXED); - BOOST_CHECK(result); - BOOST_CHECK_EQUAL(result.size(), DocHelper::unindexed.size()); - + EXPECT_TRUE(result); + EXPECT_EQ(result.size(), DocHelper::unindexed.size()); + // Get all indexed fields that are storing term vectors result = reader->getFieldNames(IndexReader::FIELD_OPTION_INDEXED_WITH_TERMVECTOR); - BOOST_CHECK(result); - BOOST_CHECK_EQUAL(result.size(), DocHelper::termvector.size()); + EXPECT_TRUE(result); + EXPECT_EQ(result.size(), DocHelper::termvector.size()); result = reader->getFieldNames(IndexReader::FIELD_OPTION_INDEXED_NO_TERMVECTOR); - BOOST_CHECK(result); - BOOST_CHECK_EQUAL(result.size(), DocHelper::notermvector.size()); + EXPECT_TRUE(result); + EXPECT_EQ(result.size(), DocHelper::notermvector.size()); } -BOOST_AUTO_TEST_CASE(testTerms) +TEST_F(SegmentReaderTest, testTerms) { TermEnumPtr terms = reader->terms(); - BOOST_CHECK(terms); + EXPECT_TRUE(terms); while (terms->next()) { TermPtr term = terms->term(); - BOOST_CHECK(term); + EXPECT_TRUE(term); String fieldValue = DocHelper::nameValues.get(term->field()); - BOOST_CHECK_NE(fieldValue.find(term->text()), -1); + EXPECT_NE(fieldValue.find(term->text()), -1); } TermDocsPtr termDocs = reader->termDocs(); - BOOST_CHECK(termDocs); + EXPECT_TRUE(termDocs); termDocs->seek(newLucene(DocHelper::TEXT_FIELD_1_KEY, L"field")); - BOOST_CHECK(termDocs->next()); + EXPECT_TRUE(termDocs->next()); termDocs->seek(newLucene(DocHelper::NO_NORMS_KEY, DocHelper::NO_NORMS_TEXT)); - BOOST_CHECK(termDocs->next()); + EXPECT_TRUE(termDocs->next()); TermPositionsPtr positions = reader->termPositions(); positions->seek(newLucene(DocHelper::TEXT_FIELD_1_KEY, L"field")); - BOOST_CHECK(positions); - BOOST_CHECK_EQUAL(positions->doc(), 0); - BOOST_CHECK(positions->nextPosition() >= 0); + EXPECT_TRUE(positions); + EXPECT_EQ(positions->doc(), 0); + EXPECT_TRUE(positions->nextPosition() >= 0); } -BOOST_AUTO_TEST_CASE(testNorms) +TEST_F(SegmentReaderTest, testNorms) { // test omit norms for (int32_t i = 0; i < DocHelper::fields.size(); ++i) @@ -150,45 +148,43 @@ BOOST_AUTO_TEST_CASE(testNorms) bool a = reader->hasNorms(f->name()); bool b = !f->getOmitNorms(); - BOOST_CHECK_EQUAL(reader->hasNorms(f->name()), !f->getOmitNorms()); - BOOST_CHECK_EQUAL(reader->hasNorms(f->name()), !DocHelper::noNorms.contains(f->name())); - + EXPECT_EQ(reader->hasNorms(f->name()), !f->getOmitNorms()); + EXPECT_EQ(reader->hasNorms(f->name()), !DocHelper::noNorms.contains(f->name())); + if (!reader->hasNorms(f->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms(f->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); - BOOST_CHECK(!norms); + EXPECT_TRUE(!norms); norms.resize(reader->maxDoc()); reader->norms(f->name(), norms, 0); for (int32_t j = 0; j < reader->maxDoc(); ++j) - BOOST_CHECK_EQUAL(norms[j], norm1); + EXPECT_EQ(norms[j], norm1); } } } } -BOOST_AUTO_TEST_CASE(testTermVectors) +TEST_F(SegmentReaderTest, testTermVectors) { TermFreqVectorPtr result = reader->getTermFreqVector(0, DocHelper::TEXT_FIELD_2_KEY); - BOOST_CHECK(result); + EXPECT_TRUE(result); Collection terms = result->getTerms(); Collection freqs = result->getTermFrequencies(); - BOOST_CHECK(terms); - BOOST_CHECK_EQUAL(terms.size(), 3); - BOOST_CHECK(freqs); - BOOST_CHECK_EQUAL(freqs.size(), 3); + EXPECT_TRUE(terms); + EXPECT_EQ(terms.size(), 3); + EXPECT_TRUE(freqs); + EXPECT_EQ(freqs.size(), 3); for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; int32_t freq = freqs[i]; - BOOST_CHECK_NE(String(DocHelper::FIELD_2_TEXT).find(term), -1); - BOOST_CHECK(freq > 0); + EXPECT_NE(String(DocHelper::FIELD_2_TEXT).find(term), -1); + EXPECT_TRUE(freq > 0); } Collection results = reader->getTermFreqVectors(0); - BOOST_CHECK(results); - BOOST_CHECK_EQUAL(results.size(), 3); + EXPECT_TRUE(results); + EXPECT_EQ(results.size(), 3); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/SegmentTermDocsTest.cpp b/src/test/index/SegmentTermDocsTest.cpp index 8693aa30..35512e4f 100644 --- a/src/test/index/SegmentTermDocsTest.cpp +++ b/src/test/index/SegmentTermDocsTest.cpp @@ -22,18 +22,18 @@ using namespace Lucene; -class SegmentTermDocsTestFixture : public LuceneTestFixture, public DocHelper +class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper { public: - SegmentTermDocsTestFixture() + SegmentTermDocsTest() { testDoc = newLucene(); dir = newLucene(); DocHelper::setupDoc(testDoc); info = DocHelper::writeDoc(dir, testDoc); } - - virtual ~SegmentTermDocsTestFixture() + + virtual ~SegmentTermDocsTest() { } @@ -47,45 +47,45 @@ class SegmentTermDocsTestFixture : public LuceneTestFixture, public DocHelper { // After adding the document, we should be able to read it back in SegmentReaderPtr reader = SegmentReader::get(true, info, indexDivisor); - BOOST_CHECK(reader); - BOOST_CHECK_EQUAL(indexDivisor, reader->getTermInfosIndexDivisor()); + EXPECT_TRUE(reader); + EXPECT_EQ(indexDivisor, reader->getTermInfosIndexDivisor()); SegmentTermDocsPtr segTermDocs = newLucene(reader); - BOOST_CHECK(segTermDocs); + EXPECT_TRUE(segTermDocs); segTermDocs->seek(newLucene(DocHelper::TEXT_FIELD_2_KEY, L"field")); if (segTermDocs->next()) { int32_t docId = segTermDocs->doc(); - BOOST_CHECK_EQUAL(docId, 0); + EXPECT_EQ(docId, 0); int32_t freq = segTermDocs->freq(); - BOOST_CHECK_EQUAL(freq, 3); + EXPECT_EQ(freq, 3); } reader->close(); } - + void checkBadSeek(int32_t indexDivisor) { { // After adding the document, we should be able to read it back in SegmentReaderPtr reader = SegmentReader::get(true, info, indexDivisor); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); SegmentTermDocsPtr segTermDocs = newLucene(reader); - BOOST_CHECK(segTermDocs); + EXPECT_TRUE(segTermDocs); segTermDocs->seek(newLucene(L"textField2", L"bad")); - BOOST_CHECK(!segTermDocs->next()); + EXPECT_TRUE(!segTermDocs->next()); reader->close(); } { // After adding the document, we should be able to read it back in SegmentReaderPtr reader = SegmentReader::get(true, info, indexDivisor); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); SegmentTermDocsPtr segTermDocs = newLucene(reader); - BOOST_CHECK(segTermDocs); + EXPECT_TRUE(segTermDocs); segTermDocs->seek(newLucene(L"junk", L"bad")); - BOOST_CHECK(!segTermDocs->next()); + EXPECT_TRUE(!segTermDocs->next()); reader->close(); } } - + void checkSkipTo(int32_t indexDivisor) { DirectoryPtr dir = newLucene(); @@ -103,7 +103,7 @@ class SegmentTermDocsTestFixture : public LuceneTestFixture, public DocHelper for (int32_t i = 0; i < 50; ++i) addDoc(writer, L"ccc ccc ccc ccc"); - // assure that we deal with a single segment + // assure that we deal with a single segment writer->optimize(); writer->close(); @@ -115,103 +115,103 @@ class SegmentTermDocsTestFixture : public LuceneTestFixture, public DocHelper // with next tdocs->seek(ta); - BOOST_CHECK(tdocs->next()); - BOOST_CHECK_EQUAL(0, tdocs->doc()); - BOOST_CHECK_EQUAL(4, tdocs->freq()); - BOOST_CHECK(tdocs->next()); - BOOST_CHECK_EQUAL(1, tdocs->doc()); - BOOST_CHECK_EQUAL(4, tdocs->freq()); - BOOST_CHECK(tdocs->skipTo(0)); - BOOST_CHECK_EQUAL(2, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(4)); - BOOST_CHECK_EQUAL(4, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(9)); - BOOST_CHECK_EQUAL(9, tdocs->doc()); - BOOST_CHECK(!tdocs->skipTo(10)); + EXPECT_TRUE(tdocs->next()); + EXPECT_EQ(0, tdocs->doc()); + EXPECT_EQ(4, tdocs->freq()); + EXPECT_TRUE(tdocs->next()); + EXPECT_EQ(1, tdocs->doc()); + EXPECT_EQ(4, tdocs->freq()); + EXPECT_TRUE(tdocs->skipTo(0)); + EXPECT_EQ(2, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(4)); + EXPECT_EQ(4, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(9)); + EXPECT_EQ(9, tdocs->doc()); + EXPECT_TRUE(!tdocs->skipTo(10)); // without next tdocs->seek(ta); - BOOST_CHECK(tdocs->skipTo(0)); - BOOST_CHECK_EQUAL(0, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(4)); - BOOST_CHECK_EQUAL(4, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(9)); - BOOST_CHECK_EQUAL(9, tdocs->doc()); - BOOST_CHECK(!tdocs->skipTo(10)); + EXPECT_TRUE(tdocs->skipTo(0)); + EXPECT_EQ(0, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(4)); + EXPECT_EQ(4, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(9)); + EXPECT_EQ(9, tdocs->doc()); + EXPECT_TRUE(!tdocs->skipTo(10)); // exactly skipInterval documents and therefore with optimization // with next tdocs->seek(tb); - BOOST_CHECK(tdocs->next()); - BOOST_CHECK_EQUAL(10, tdocs->doc()); - BOOST_CHECK_EQUAL(4, tdocs->freq()); - BOOST_CHECK(tdocs->next()); - BOOST_CHECK_EQUAL(11, tdocs->doc()); - BOOST_CHECK_EQUAL(4, tdocs->freq()); - BOOST_CHECK(tdocs->skipTo(5)); - BOOST_CHECK_EQUAL(12, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(15)); - BOOST_CHECK_EQUAL(15, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(24)); - BOOST_CHECK_EQUAL(24, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(25)); - BOOST_CHECK_EQUAL(25, tdocs->doc()); - BOOST_CHECK(!tdocs->skipTo(26)); + EXPECT_TRUE(tdocs->next()); + EXPECT_EQ(10, tdocs->doc()); + EXPECT_EQ(4, tdocs->freq()); + EXPECT_TRUE(tdocs->next()); + EXPECT_EQ(11, tdocs->doc()); + EXPECT_EQ(4, tdocs->freq()); + EXPECT_TRUE(tdocs->skipTo(5)); + EXPECT_EQ(12, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(15)); + EXPECT_EQ(15, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(24)); + EXPECT_EQ(24, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(25)); + EXPECT_EQ(25, tdocs->doc()); + EXPECT_TRUE(!tdocs->skipTo(26)); // without next tdocs->seek(tb); - BOOST_CHECK(tdocs->skipTo(5)); - BOOST_CHECK_EQUAL(10, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(15)); - BOOST_CHECK_EQUAL(15, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(24)); - BOOST_CHECK_EQUAL(24, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(25)); - BOOST_CHECK_EQUAL(25, tdocs->doc()); - BOOST_CHECK(!tdocs->skipTo(26)); + EXPECT_TRUE(tdocs->skipTo(5)); + EXPECT_EQ(10, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(15)); + EXPECT_EQ(15, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(24)); + EXPECT_EQ(24, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(25)); + EXPECT_EQ(25, tdocs->doc()); + EXPECT_TRUE(!tdocs->skipTo(26)); // much more than skipInterval documents and therefore with optimization // with next tdocs->seek(tc); - BOOST_CHECK(tdocs->next()); - BOOST_CHECK_EQUAL(26, tdocs->doc()); - BOOST_CHECK_EQUAL(4, tdocs->freq()); - BOOST_CHECK(tdocs->next()); - BOOST_CHECK_EQUAL(27, tdocs->doc()); - BOOST_CHECK_EQUAL(4, tdocs->freq()); - BOOST_CHECK(tdocs->skipTo(5)); - BOOST_CHECK_EQUAL(28, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(40)); - BOOST_CHECK_EQUAL(40, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(57)); - BOOST_CHECK_EQUAL(57, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(74)); - BOOST_CHECK_EQUAL(74, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(75)); - BOOST_CHECK_EQUAL(75, tdocs->doc()); - BOOST_CHECK(!tdocs->skipTo(76)); + EXPECT_TRUE(tdocs->next()); + EXPECT_EQ(26, tdocs->doc()); + EXPECT_EQ(4, tdocs->freq()); + EXPECT_TRUE(tdocs->next()); + EXPECT_EQ(27, tdocs->doc()); + EXPECT_EQ(4, tdocs->freq()); + EXPECT_TRUE(tdocs->skipTo(5)); + EXPECT_EQ(28, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(40)); + EXPECT_EQ(40, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(57)); + EXPECT_EQ(57, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(74)); + EXPECT_EQ(74, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(75)); + EXPECT_EQ(75, tdocs->doc()); + EXPECT_TRUE(!tdocs->skipTo(76)); // without next tdocs->seek(tc); - BOOST_CHECK(tdocs->skipTo(5)); - BOOST_CHECK_EQUAL(26, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(40)); - BOOST_CHECK_EQUAL(40, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(57)); - BOOST_CHECK_EQUAL(57, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(74)); - BOOST_CHECK_EQUAL(74, tdocs->doc()); - BOOST_CHECK(tdocs->skipTo(75)); - BOOST_CHECK_EQUAL(75, tdocs->doc()); - BOOST_CHECK(!tdocs->skipTo(76)); + EXPECT_TRUE(tdocs->skipTo(5)); + EXPECT_EQ(26, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(40)); + EXPECT_EQ(40, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(57)); + EXPECT_EQ(57, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(74)); + EXPECT_EQ(74, tdocs->doc()); + EXPECT_TRUE(tdocs->skipTo(75)); + EXPECT_EQ(75, tdocs->doc()); + EXPECT_TRUE(!tdocs->skipTo(76)); tdocs->close(); reader->close(); dir->close(); } - + void addDoc(IndexWriterPtr writer, const String& value) { DocumentPtr doc = newLucene(); @@ -220,24 +220,22 @@ class SegmentTermDocsTestFixture : public LuceneTestFixture, public DocHelper } }; -BOOST_FIXTURE_TEST_SUITE(SegmentTermDocsTest, SegmentTermDocsTestFixture) - -BOOST_AUTO_TEST_CASE(testTermDocs) +TEST_F(SegmentTermDocsTest, testTermDocs) { checkTermDocs(1); } -BOOST_AUTO_TEST_CASE(testBadSeek) +TEST_F(SegmentTermDocsTest, testBadSeek) { checkBadSeek(1); } -BOOST_AUTO_TEST_CASE(testSkipTo) +TEST_F(SegmentTermDocsTest, testSkipTo) { checkSkipTo(1); } -BOOST_AUTO_TEST_CASE(testIndexDivisor) +TEST_F(SegmentTermDocsTest, testIndexDivisor) { dir = newLucene(); testDoc = newLucene(); @@ -247,5 +245,3 @@ BOOST_AUTO_TEST_CASE(testIndexDivisor) checkBadSeek(2); checkSkipTo(2); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/SegmentTermEnumTest.cpp b/src/test/index/SegmentTermEnumTest.cpp index d4e6d5b4..391e5a8d 100644 --- a/src/test/index/SegmentTermEnumTest.cpp +++ b/src/test/index/SegmentTermEnumTest.cpp @@ -20,7 +20,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SegmentTermEnumTest, LuceneTestFixture) +typedef LuceneTestFixture SegmentTermEnumTest; static void addDoc(IndexWriterPtr writer, const String& value) { @@ -38,35 +38,35 @@ static void verifyDocFreq(DirectoryPtr dir) // go to the first term (aaa) termEnum->next(); // assert that term is 'aaa' - BOOST_CHECK_EQUAL(L"aaa", termEnum->term()->text()); - BOOST_CHECK_EQUAL(200, termEnum->docFreq()); + EXPECT_EQ(L"aaa", termEnum->term()->text()); + EXPECT_EQ(200, termEnum->docFreq()); // go to the second term (bbb) termEnum->next(); // assert that term is 'bbb' - BOOST_CHECK_EQUAL(L"bbb", termEnum->term()->text()); - BOOST_CHECK_EQUAL(100, termEnum->docFreq()); + EXPECT_EQ(L"bbb", termEnum->term()->text()); + EXPECT_EQ(100, termEnum->docFreq()); termEnum->close(); // create enumeration of terms after term 'aaa', including 'aaa' termEnum = reader->terms(newLucene(L"content", L"aaa")); // assert that term is 'aaa' - BOOST_CHECK_EQUAL(L"aaa", termEnum->term()->text()); - BOOST_CHECK_EQUAL(200, termEnum->docFreq()); + EXPECT_EQ(L"aaa", termEnum->term()->text()); + EXPECT_EQ(200, termEnum->docFreq()); // go to term 'bbb' termEnum->next(); // assert that term is 'bbb' - BOOST_CHECK_EQUAL(L"bbb", termEnum->term()->text()); - BOOST_CHECK_EQUAL(100, termEnum->docFreq()); + EXPECT_EQ(L"bbb", termEnum->term()->text()); + EXPECT_EQ(100, termEnum->docFreq()); termEnum->close(); } -BOOST_AUTO_TEST_CASE(testTermEnum) +TEST_F(SegmentTermEnumTest, testTermEnum) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - + // ADD 100 documents with term : aaa // add 100 documents with terms: aaa bbb // Therefore, term 'aaa' has document frequency of 200 and term 'bbb' 100 @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(testTermEnum) verifyDocFreq(dir); } -BOOST_AUTO_TEST_CASE(testPrevTermAtEnd) +TEST_F(SegmentTermEnumTest, testPrevTermAtEnd) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -98,13 +98,11 @@ BOOST_AUTO_TEST_CASE(testPrevTermAtEnd) writer->close(); SegmentReaderPtr reader = SegmentReader::getOnlySegmentReader(dir); SegmentTermEnumPtr termEnum = boost::dynamic_pointer_cast(reader->terms()); - BOOST_CHECK(termEnum->next()); - BOOST_CHECK_EQUAL(L"aaa", termEnum->term()->text()); - BOOST_CHECK(termEnum->next()); - BOOST_CHECK_EQUAL(L"aaa", termEnum->prev()->text()); - BOOST_CHECK_EQUAL(L"bbb", termEnum->term()->text()); - BOOST_CHECK(!termEnum->next()); - BOOST_CHECK_EQUAL(L"bbb", termEnum->prev()->text()); + EXPECT_TRUE(termEnum->next()); + EXPECT_EQ(L"aaa", termEnum->term()->text()); + EXPECT_TRUE(termEnum->next()); + EXPECT_EQ(L"aaa", termEnum->prev()->text()); + EXPECT_EQ(L"bbb", termEnum->term()->text()); + EXPECT_TRUE(!termEnum->next()); + EXPECT_EQ(L"bbb", termEnum->prev()->text()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/SnapshotDeletionPolicyTest.cpp b/src/test/index/SnapshotDeletionPolicyTest.cpp index a0227360..aea64e58 100644 --- a/src/test/index/SnapshotDeletionPolicyTest.cpp +++ b/src/test/index/SnapshotDeletionPolicyTest.cpp @@ -31,7 +31,7 @@ class SnapshotThread : public LuceneThread this->stopTime = stopTime; this->writer = writer; } - + virtual ~SnapshotThread() { } @@ -63,20 +63,20 @@ class SnapshotThread : public LuceneThread } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; -class SnapshotDeletionPolicyFixture : public LuceneTestFixture +class SnapshotDeletionPolicyTest : public LuceneTestFixture { public: - SnapshotDeletionPolicyFixture() + SnapshotDeletionPolicyTest() { buffer = ByteArray::newInstance(4096); } - - virtual ~SnapshotDeletionPolicyFixture() + + virtual ~SnapshotDeletionPolicyTest() { } @@ -95,10 +95,10 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture // Force frequent flushes writer->setMaxBufferedDocs(2); - + LuceneThreadPtr thread = newLucene(stopTime, writer); thread->start(); - + // While the above indexing thread is running, take many backups do { @@ -108,7 +108,7 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture break; } while ((int64_t)MiscUtils::currentTimeMillis() < stopTime); - + thread->join(); // Add one more document to force writer to commit a final segment, so deletion policy has a chance to delete again @@ -120,9 +120,9 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture writer->close(); checkNoUnreferencedFiles(dir); } - - /// Example showing how to use the SnapshotDeletionPolicy to take a backup. This method does not - /// really do a backup; instead, it reads every byte of every file just to test that the files + + /// Example showing how to use the SnapshotDeletionPolicy to take a backup. This method does not + /// really do a backup; instead, it reads every byte of every file just to test that the files /// indeed exist and are readable even while the index is changing. void backupIndex(DirectoryPtr dir, SnapshotDeletionPolicyPtr dp) { @@ -136,13 +136,13 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture { finally = e; } - - // Make sure to release the snapshot, otherwise these files will never be deleted during this + + // Make sure to release the snapshot, otherwise these files will never be deleted during this // IndexWriter session dp->release(); finally.throwException(); } - + void copyFiles(DirectoryPtr dir, IndexCommitPtr cp) { // While we hold the snapshot, and nomatter how long we take to do the backup, the IndexWriter will @@ -151,16 +151,16 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { // NOTE: in a real backup you would not use readFile; you would need to use something else - // that copies the file to a backup location. This could even be a spawned shell process + // that copies the file to a backup location. This could even be a spawned shell process // (eg "tar", "zip") that takes the list of files and builds a backup. readFile(dir, *fileName); } } - + void readFile(DirectoryPtr dir, const String& name) { IndexInputPtr input = dir->openInput(name); - + LuceneException finally; try { @@ -172,8 +172,8 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture input->readBytes(buffer.get(), 0, numToRead, false); bytesLeft -= numToRead; } - // Don't do this in your real backups! This is just to force a backup to take a somewhat - // long time, to make sure we are exercising the fact that the IndexWriter should not delete + // Don't do this in your real backups! This is just to force a backup to take a somewhat + // long time, to make sure we are exercising the fact that the IndexWriter should not delete // this file even when I take my time reading it. LuceneThread::threadSleep(1); } @@ -184,7 +184,7 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture input->close(); finally.throwException(); } - + void checkNoUnreferencedFiles(DirectoryPtr dir) { HashSet _startFiles = dir->listAll(); @@ -192,25 +192,23 @@ class SnapshotDeletionPolicyFixture : public LuceneTestFixture infos->read(dir); IndexFileDeleterPtr deleter = newLucene(dir, newLucene(), infos, InfoStreamPtr(), DocumentsWriterPtr(), HashSet()); HashSet _endFiles = dir->listAll(); - + Collection startFiles = Collection::newInstance(_startFiles.begin(), _startFiles.end()); Collection endFiles = Collection::newInstance(_endFiles.begin(), _endFiles.end()); - + std::sort(startFiles.begin(), startFiles.end()); std::sort(endFiles.begin(), endFiles.end()); - - BOOST_CHECK(startFiles.equals(endFiles)); + + EXPECT_TRUE(startFiles.equals(endFiles)); } }; -const String SnapshotDeletionPolicyFixture::INDEX_PATH = L"test.snapshots"; - -BOOST_FIXTURE_TEST_SUITE(SnapshotDeletionPolicyTest, SnapshotDeletionPolicyFixture) +const String SnapshotDeletionPolicyTest::INDEX_PATH = L"test.snapshots"; -BOOST_AUTO_TEST_CASE(testSnapshotDeletionPolicy) +TEST_F(SnapshotDeletionPolicyTest, testSnapshotDeletionPolicy) { String dir = getTempDir(INDEX_PATH); - + LuceneException finally; try { @@ -224,18 +222,23 @@ BOOST_AUTO_TEST_CASE(testSnapshotDeletionPolicy) } FileUtils::removeDirectory(dir); finally.throwException(); - + MockRAMDirectoryPtr dir2 = newLucene(); runTest(dir2); dir2->close(); } -BOOST_AUTO_TEST_CASE(testNoCommits) +TEST_F(SnapshotDeletionPolicyTest, testNoCommits) { - // Tests that if there were no commits when snapshot() is called, then + // Tests that if there were no commits when snapshot() is called, then // IllegalStateException is thrown rather than NPE. SnapshotDeletionPolicyPtr sdp = newLucene(newLucene()); - BOOST_CHECK_EXCEPTION(sdp->snapshot(), IllegalStateException, check_exception(LuceneException::IllegalState)); + try + { + sdp->snapshot(); + } + catch (IllegalStateException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); + } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/StressIndexingTest.cpp b/src/test/index/StressIndexingTest.cpp index 5b38ceae..074156b3 100644 --- a/src/test/index/StressIndexingTest.cpp +++ b/src/test/index/StressIndexingTest.cpp @@ -32,7 +32,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(StressIndexingTest, LuceneTestFixture) +typedef LuceneTestFixture StressIndexingTest; DECLARE_SHARED_PTR(DocsAndWriter) @@ -42,9 +42,9 @@ class DocsAndWriter : public LuceneObject virtual ~DocsAndWriter() { } - + LUCENE_CLASS(DocsAndWriter); - + public: HashMap docs; IndexWriterPtr writer; @@ -57,11 +57,11 @@ class MockIndexWriter : public IndexWriter { rand = newLucene(); } - + virtual ~MockIndexWriter() { } - + LUCENE_CLASS(MockIndexWriter); protected: @@ -105,13 +105,13 @@ class IndexingThread : public LuceneThread buffer.resize(100); r = newLucene(); } - + virtual ~IndexingThread() { } - + LUCENE_CLASS(IndexingThread); - + public: IndexWriterPtr w; int32_t base; @@ -126,19 +126,19 @@ class IndexingThread : public LuceneThread { return r->nextInt(limit); } - + /// start is inclusive and end is exclusive int32_t nextInt(int32_t start, int32_t end) { return start + r->nextInt(end - start); } - + int32_t addUTF8Token(int32_t start) { int32_t end = start + nextInt(20); if (buffer.size() < 1 + end) buffer.resize((int32_t)((double)(1 + end) * 1.25)); - + for (int32_t i = start; i < end; ++i) { int32_t t = nextInt(5); @@ -163,19 +163,19 @@ class IndexingThread : public LuceneThread else if (t == 4) buffer[i] = (wchar_t)nextInt(0xe000, 0xfff0); } - + buffer[end] = L' '; return 1 + end; } - + String getString(int32_t tokens) { tokens = tokens != 0 ? tokens : r->nextInt(4) + 1; - + // Half the time make a random UTF8 string if (nextInt() % 2 == 1) return getUTF8String(tokens); - + CharArray arr(CharArray::newInstance(tokens * 2)); for (int32_t i = 0; i < tokens; ++i) { @@ -184,7 +184,7 @@ class IndexingThread : public LuceneThread } return String(arr.get(), arr.size()); } - + String getUTF8String(int32_t tokens) { int32_t upto = 0; @@ -193,19 +193,19 @@ class IndexingThread : public LuceneThread upto = addUTF8Token(upto); return String(buffer.get(), upto); } - + String getIdString() { return StringUtils::toString(base + nextInt(range)); } - + void indexDoc() { DocumentPtr d = newLucene(); - Collection fields = Collection::newInstance(); + Collection fields = Collection::newInstance(); String idString = getIdString(); - + FieldPtr idField = newLucene(newLucene(L"id", L"")->field(), idString, Field::STORE_YES, Field::INDEX_ANALYZED_NO_NORMS); fields.add(idField); @@ -256,25 +256,25 @@ class IndexingThread : public LuceneThread for (int32_t i = 0; i < fields.size(); ++i) d->add(fields[i]); - + w->updateDocument(newLucene(L"id", L"")->createTerm(idString), d); docs.put(idString, d); } - + void deleteDoc() { String idString = getIdString(); w->deleteDocuments(newLucene(L"id", L"")->createTerm(idString)); docs.remove(idString); } - + void deleteByQuery() { String idString = getIdString(); w->deleteDocuments(newLucene(newLucene(L"id", L"")->createTerm(idString))); docs.remove(idString); } - + virtual void run() { try @@ -293,7 +293,7 @@ class IndexingThread : public LuceneThread } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; @@ -314,7 +314,7 @@ static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iteratio w->setMergeFactor(mergeFactor); w->setRAMBufferSizeMB(0.1); w->setMaxBufferedDocs(maxBufferedDocs); - + Collection threads = Collection::newInstance(numThreads); for (int32_t i = 0; i < threads.size(); ++i) { @@ -325,19 +325,19 @@ static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iteratio th->iterations = iterations; threads[i] = th; } - + for (int32_t i = 0; i < threads.size(); ++i) threads[i]->start(); for (int32_t i = 0; i < threads.size(); ++i) threads[i]->join(); - + for (int32_t i = 0; i < threads.size(); ++i) { IndexingThreadPtr th = threads[i]; SyncLock syncLock(th); docs.putAll(th->docs.begin(), th->docs.end()); } - + checkIndex(dir); DocsAndWriterPtr dw = newLucene(); dw->docs = docs; @@ -348,7 +348,7 @@ static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iteratio static HashMap indexRandom(int32_t numThreads, int32_t iterations, int32_t range, DirectoryPtr dir) { HashMap docs = HashMap::newInstance(); - + for (int32_t iter = 0; iter < 3; ++iter) { IndexWriterPtr w = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -374,9 +374,9 @@ static HashMap indexRandom(int32_t numThreads, int32_t iter threads[i]->start(); for (int32_t i = 0; i < threads.size(); ++i) threads[i]->join(); - + w->close(); - + for (int32_t i = 0; i < threads.size(); ++i) { IndexingThreadPtr th = threads[i]; @@ -384,9 +384,9 @@ static HashMap indexRandom(int32_t numThreads, int32_t iter docs.putAll(th->docs.begin(), th->docs.end()); } } - + checkIndex(dir); - + return docs; } @@ -399,10 +399,10 @@ static void indexSerial(HashMap docs, DirectoryPtr dir) { DocumentPtr d = iter->second; Collection fields = d->getFields(); - + // put fields in same order each time std::sort(fields.begin(), fields.end(), lessFieldName()); - + DocumentPtr d1 = newLucene(); d1->setBoost(d->getBoost()); for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) @@ -430,7 +430,7 @@ static void verifyEquals(DirectoryPtr dir1, DirectoryPtr dir2, const String& idF static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idField) { - BOOST_CHECK_EQUAL(r1->numDocs(), r2->numDocs()); + EXPECT_EQ(r1->numDocs(), r2->numDocs()); bool hasDeletes = !(r1->maxDoc() == r2->maxDoc() && r1->numDocs() == r1->maxDoc()); Collection r2r1 = Collection::newInstance(r2->maxDoc()); // r2 id to r1 id mapping @@ -446,34 +446,34 @@ static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idF TermPtr term = termEnum->term(); if (!term || term->field() != idField) break; - + termDocs1->seek(termEnum); if (!termDocs1->next()) { // This doc is deleted and wasn't replaced termDocs2->seek(termEnum); - BOOST_CHECK(!termDocs2->next()); + EXPECT_TRUE(!termDocs2->next()); continue; } - + int32_t id1 = termDocs1->doc(); - BOOST_CHECK(!termDocs1->next()); + EXPECT_TRUE(!termDocs1->next()); termDocs2->seek(termEnum); - BOOST_CHECK(termDocs2->next()); + EXPECT_TRUE(termDocs2->next()); int32_t id2 = termDocs2->doc(); - BOOST_CHECK(!termDocs2->next()); + EXPECT_TRUE(!termDocs2->next()); r2r1[id2] = id1; - + // verify stored fields are equivalent - BOOST_CHECK_NO_THROW(verifyEquals(r1->document(id1), r2->document(id2))); - + EXPECT_NO_THROW(verifyEquals(r1->document(id1), r2->document(id2))); + // verify term vectors are equivalent - BOOST_CHECK_NO_THROW(verifyEquals(r1->getTermFreqVectors(id1), r2->getTermFreqVectors(id2))); + EXPECT_NO_THROW(verifyEquals(r1->getTermFreqVectors(id1), r2->getTermFreqVectors(id2))); } while (termEnum->next()); - + termEnum->close(); // Verify postings @@ -488,7 +488,7 @@ static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idF { TermPtr term1; TermPtr term2; - + // iterate until we get some docs int32_t len1 = 0; while (true) @@ -510,7 +510,7 @@ static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idF if (!termEnum1->next()) break; } - + // iterate until we get some docs int32_t len2 = 0; while (true) @@ -532,22 +532,22 @@ static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idF if (!termEnum2->next()) break; } - + if (!hasDeletes) - BOOST_CHECK_EQUAL(termEnum1->docFreq(), termEnum2->docFreq()); - - BOOST_CHECK_EQUAL(len1, len2); + EXPECT_EQ(termEnum1->docFreq(), termEnum2->docFreq()); + + EXPECT_EQ(len1, len2); if (len1 == 0) break; // no more terms - BOOST_CHECK_EQUAL(term1, term2); + EXPECT_EQ(term1, term2); // sort info2 to get it into ascending docid std::sort(info2.begin(), info2.begin() + len2); // now compare for (int32_t i = 0; i < len1; ++i) - BOOST_CHECK_EQUAL(info1[i], info2[i]); + EXPECT_EQ(info1[i], info2[i]); termEnum1->next(); termEnum2->next(); @@ -558,20 +558,20 @@ static void verifyEquals(DocumentPtr d1, DocumentPtr d2) { Collection ff1 = d1->getFields(); Collection ff2 = d2->getFields(); - + std::sort(ff1.begin(), ff1.end(), lessFieldName()); std::sort(ff2.begin(), ff2.end(), lessFieldName()); - BOOST_CHECK_EQUAL(ff1.size(), ff2.size()); - + EXPECT_EQ(ff1.size(), ff2.size()); + for (int32_t i = 0; i < ff1.size(); ++i) { FieldablePtr f1 = ff1[i]; FieldablePtr f2 = ff2[i]; if (f1->isBinary()) - BOOST_CHECK(f2->isBinary()); + EXPECT_TRUE(f2->isBinary()); else - BOOST_CHECK_EQUAL(f1->stringValue(), f2->stringValue()); + EXPECT_EQ(f1->stringValue(), f2->stringValue()); } } @@ -579,18 +579,18 @@ static void verifyEquals(Collection d1, Collectionsize(), v2->size()); + EXPECT_EQ(v1->size(), v2->size()); int32_t numTerms = v1->size(); Collection terms1 = v1->getTerms(); Collection terms2 = v2->getTerms(); @@ -598,32 +598,32 @@ static void verifyEquals(Collection d1, Collection freq2 = v2->getTermFrequencies(); for (int32_t j = 0; j < numTerms; ++j) { - BOOST_CHECK_EQUAL(terms1[j], terms2[j]); - BOOST_CHECK_EQUAL(freq1[j], freq2[j]); + EXPECT_EQ(terms1[j], terms2[j]); + EXPECT_EQ(freq1[j], freq2[j]); } if (boost::dynamic_pointer_cast(v1)) { - BOOST_CHECK(boost::dynamic_pointer_cast(v2)); + EXPECT_TRUE(boost::dynamic_pointer_cast(v2)); SegmentTermPositionVectorPtr tpv1 = boost::dynamic_pointer_cast(v1); SegmentTermPositionVectorPtr tpv2 = boost::dynamic_pointer_cast(v2); for (int32_t j = 0; j < numTerms; ++j) { Collection pos1 = tpv1->getTermPositions(j); Collection pos2 = tpv2->getTermPositions(j); - BOOST_CHECK_EQUAL(pos1.size(), pos2.size()); + EXPECT_EQ(pos1.size(), pos2.size()); Collection offsets1 = tpv1->getOffsets(j); Collection offsets2 = tpv2->getOffsets(j); if (!offsets1) - BOOST_CHECK(!offsets2); + EXPECT_TRUE(!offsets2); else - BOOST_CHECK(offsets2); + EXPECT_TRUE(offsets2); for (int32_t k = 0; k < pos1.size(); ++k) { - BOOST_CHECK_EQUAL(pos1[k], pos2[k]); + EXPECT_EQ(pos1[k], pos2[k]); if (offsets1) { - BOOST_CHECK_EQUAL(offsets1[k]->getStartOffset(), offsets2[k]->getStartOffset()); - BOOST_CHECK_EQUAL(offsets1[k]->getEndOffset(), offsets2[k]->getEndOffset()); + EXPECT_EQ(offsets1[k]->getStartOffset(), offsets2[k]->getStartOffset()); + EXPECT_EQ(offsets1[k]->getEndOffset(), offsets2[k]->getEndOffset()); } } } @@ -633,40 +633,40 @@ static void verifyEquals(Collection d1, Collectionfailed = false; this->RUN_TIME_SEC = 6; this->rand = newLucene(); } - - virtual ~TimedThread() + + virtual ~StressTimedThread() { } - - LUCENE_CLASS(TimedThread); - + + LUCENE_CLASS(StressTimedThread); + public: bool failed; protected: int32_t RUN_TIME_SEC; RandomPtr rand; - + public: virtual void doWork() = 0; - + virtual void run() { int64_t stopTime = MiscUtils::currentTimeMillis() + 1000 * RUN_TIME_SEC; - + try { while ((int64_t)MiscUtils::currentTimeMillis() < stopTime && !failed) @@ -675,30 +675,30 @@ namespace RunStressTest catch (LuceneException& e) { failed = true; - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; - class IndexerThread : public TimedThread + class StressIndexerThread : public StressTimedThread { public: - IndexerThread(IndexWriterPtr writer) + StressIndexerThread(IndexWriterPtr writer) { this->writer = writer; this->nextID = 0; } - - virtual ~IndexerThread() + + virtual ~StressIndexerThread() { } - - LUCENE_CLASS(IndexerThread); - + + LUCENE_CLASS(StressIndexerThread); + public: IndexWriterPtr writer; int32_t nextID; - + public: virtual void doWork() { @@ -710,7 +710,7 @@ namespace RunStressTest d->add(newLucene(L"contents", intToEnglish(rand->nextInt()), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(d); } - + // Delete 5 docs int32_t deleteID = nextID - 1; for (int32_t i = 0; i < 5; ++i) @@ -721,23 +721,23 @@ namespace RunStressTest } }; - class SearcherThread : public TimedThread + class StressSearcherThread : public StressTimedThread { public: - SearcherThread(DirectoryPtr directory) + StressSearcherThread(DirectoryPtr directory) { this->directory = directory; } - - virtual ~SearcherThread() + + virtual ~StressSearcherThread() { } - - LUCENE_CLASS(SearcherThread); - + + LUCENE_CLASS(StressSearcherThread); + protected: DirectoryPtr directory; - + public: virtual void doWork() { @@ -754,43 +754,43 @@ static void runStressTest(DirectoryPtr directory, MergeSchedulerPtr mergeSchedul IndexWriterPtr modifier = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); modifier->setMaxBufferedDocs(10); - - Collection threads = Collection::newInstance(4); + + Collection threads = Collection::newInstance(4); int32_t numThread = 0; - + if (mergeScheduler) modifier->setMergeScheduler(mergeScheduler); - + // One modifier that writes 10 docs then removes 5, over and over - RunStressTest::IndexerThreadPtr indexerThread1 = newLucene(modifier); + RunStressTest::StressIndexerThreadPtr indexerThread1 = newLucene(modifier); threads[numThread++] = indexerThread1; indexerThread1->start(); - RunStressTest::IndexerThreadPtr indexerThread2 = newLucene(modifier); + RunStressTest::StressIndexerThreadPtr indexerThread2 = newLucene(modifier); threads[numThread++] = indexerThread2; indexerThread2->start(); // Two searchers that constantly just re-instantiate the searcher - RunStressTest::SearcherThreadPtr searcherThread1 = newLucene(directory); + RunStressTest::StressSearcherThreadPtr searcherThread1 = newLucene(directory); threads[numThread++] = searcherThread1; searcherThread1->start(); - RunStressTest::SearcherThreadPtr searcherThread2 = newLucene(directory); + RunStressTest::StressSearcherThreadPtr searcherThread2 = newLucene(directory); threads[numThread++] = searcherThread2; searcherThread2->start(); - + for (int32_t i = 0; i < numThread; ++i) threads[i]->join(); - + modifier->close(); - - BOOST_CHECK(!indexerThread1->failed); // hit unexpected exception in indexer1 - BOOST_CHECK(!indexerThread2->failed); // hit unexpected exception in indexer2 - BOOST_CHECK(!searcherThread1->failed); // hit unexpected exception in search1 - BOOST_CHECK(!searcherThread2->failed); // hit unexpected exception in search2 + + EXPECT_TRUE(!indexerThread1->failed); // hit unexpected exception in indexer1 + EXPECT_TRUE(!indexerThread2->failed); // hit unexpected exception in indexer2 + EXPECT_TRUE(!searcherThread1->failed); // hit unexpected exception in search1 + EXPECT_TRUE(!searcherThread2->failed); // hit unexpected exception in search2 } -BOOST_AUTO_TEST_CASE(testStressIndexAndSearching) +TEST_F(StressIndexingTest, testStressIndexAndSearching) { // With ConcurrentMergeScheduler, in RAMDir DirectoryPtr directory = newLucene(); @@ -800,14 +800,14 @@ BOOST_AUTO_TEST_CASE(testStressIndexAndSearching) // With ConcurrentMergeScheduler, in FSDir String dirPath(FileUtils::joinPath(getTempDir(), L"lucene.test.stress")); directory = FSDirectory::open(dirPath); - + runStressTest(directory, newLucene()); directory->close(); FileUtils::removeDirectory(dirPath); } -BOOST_AUTO_TEST_CASE(testRandomIWReader) +TEST_F(StressIndexingTest, testRandomIWReader) { DirectoryPtr dir = newLucene(); @@ -820,7 +820,7 @@ BOOST_AUTO_TEST_CASE(testRandomIWReader) dir->close(); } -BOOST_AUTO_TEST_CASE(testRandom) +TEST_F(StressIndexingTest, testRandom) { DirectoryPtr dir1 = newLucene(); DirectoryPtr dir2 = newLucene(); @@ -831,7 +831,7 @@ BOOST_AUTO_TEST_CASE(testRandom) verifyEquals(dir1, dir2, L"id"); } -BOOST_AUTO_TEST_CASE(testMultiConfig) +TEST_F(StressIndexingTest, testMultiConfig) { RandomPtr r = newLucene(); // test lots of smaller different params together @@ -852,5 +852,3 @@ BOOST_AUTO_TEST_CASE(testMultiConfig) verifyEquals(dir1, dir2, L"id"); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/TermDocsPerfTest.cpp b/src/test/index/TermDocsPerfTest.cpp index 6750a8e6..9f75bac2 100644 --- a/src/test/index/TermDocsPerfTest.cpp +++ b/src/test/index/TermDocsPerfTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(TermDocsPerfTest, LuceneTestFixture) +typedef LuceneTestFixture TermDocsPerfTest; DECLARE_SHARED_PTR(RepeatingTokenStream) @@ -36,13 +36,13 @@ class RepeatingTokenStream : public TokenStream this->value = val; this->termAtt = addAttribute(); } - + virtual ~RepeatingTokenStream() { } - + LUCENE_CLASS(RepeatingTokenStream); - + public: int32_t num; TermAttributePtr termAtt; @@ -62,22 +62,22 @@ class RepeatingTokenStream : public TokenStream } }; -class TestAnalyzer : public Analyzer +class TermDocsPerfTestAnalyzer : public Analyzer { public: - TestAnalyzer(RepeatingTokenStreamPtr ts, RandomPtr random, int32_t maxTF, double percentDocs) + TermDocsPerfTestAnalyzer(RepeatingTokenStreamPtr ts, RandomPtr random, int32_t maxTF, double percentDocs) { this->ts = ts; this->random = random; this->maxTF = maxTF; this->percentDocs = percentDocs; } - - virtual ~TestAnalyzer() + + virtual ~TermDocsPerfTestAnalyzer() { } - - LUCENE_CLASS(TestAnalyzer); + + LUCENE_CLASS(TermDocsPerfTestAnalyzer); protected: RepeatingTokenStreamPtr ts; @@ -100,35 +100,35 @@ static void addDocs(DirectoryPtr dir, int32_t numDocs, const String& field, cons { RepeatingTokenStreamPtr ts = newLucene(val); RandomPtr random = newLucene(); - AnalyzerPtr analyzer = newLucene(ts, random, maxTF, percentDocs); - + AnalyzerPtr analyzer = newLucene(ts, random, maxTF, percentDocs); + DocumentPtr doc = newLucene(); doc->add(newLucene(field, val, Field::STORE_NO, Field::INDEX_NOT_ANALYZED_NO_NORMS)); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(100); writer->setMergeFactor(100); - + for (int32_t i = 0; i < numDocs; ++i) writer->addDocument(doc); - + writer->optimize(); writer->close(); } -BOOST_AUTO_TEST_CASE(testTermDocsPerf) +TEST_F(TermDocsPerfTest, testTermDocsPerf) { static const int32_t iter = 100000; static const int32_t numDocs = 10000; static const int32_t maxTF = 3; static const double percentDocs = 0.1; - + DirectoryPtr dir = newLucene(); int64_t start = MiscUtils::currentTimeMillis(); addDocs(dir, numDocs, L"foo", L"val", maxTF, percentDocs); int64_t end = MiscUtils::currentTimeMillis(); - - BOOST_TEST_MESSAGE("Milliseconds for creation of " << numDocs << " docs = " << (end - start)); + + // std::cout << "Milliseconds for creation of " << numDocs << " docs = " << (end - start); IndexReaderPtr reader = IndexReader::open(dir, true); TermEnumPtr termEnum = reader->terms(newLucene(L"foo", L"val")); @@ -142,9 +142,7 @@ BOOST_AUTO_TEST_CASE(testTermDocsPerf) while (termDocs->next()) termDocs->doc(); } - + end = MiscUtils::currentTimeMillis(); - BOOST_TEST_MESSAGE("Milliseconds for " << iter << " TermDocs iteration: " << (end - start)); + // std::cout << "Milliseconds for " << iter << " TermDocs iteration: " << (end - start); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/TermTest.cpp b/src/test/index/TermTest.cpp index 49a26c9b..b0d603ad 100644 --- a/src/test/index/TermTest.cpp +++ b/src/test/index/TermTest.cpp @@ -11,18 +11,16 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(TermTest, LuceneTestFixture) +typedef LuceneTestFixture TermTest; -BOOST_AUTO_TEST_CASE(testEquals) +TEST_F(TermTest, testEquals) { TermPtr base = newLucene(L"same", L"same"); TermPtr same = newLucene(L"same", L"same"); TermPtr differentField = newLucene(L"different", L"same"); TermPtr differentText = newLucene(L"same", L"different"); - BOOST_CHECK(base->equals(base)); - BOOST_CHECK(base->equals(same)); - BOOST_CHECK(!base->equals(differentField)); - BOOST_CHECK(!base->equals(differentText)); + EXPECT_TRUE(base->equals(base)); + EXPECT_TRUE(base->equals(same)); + EXPECT_TRUE(!base->equals(differentField)); + EXPECT_TRUE(!base->equals(differentText)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/TermVectorsReaderTest.cpp b/src/test/index/TermVectorsReaderTest.cpp index 130f606f..6d021800 100644 --- a/src/test/index/TermVectorsReaderTest.cpp +++ b/src/test/index/TermVectorsReaderTest.cpp @@ -44,11 +44,11 @@ class TestToken : public LuceneObject startOffset = 0; endOffset = 0; } - + virtual ~TestToken() { } - + LUCENE_CLASS(TestToken); public: @@ -70,17 +70,17 @@ class MyTokenStream : public TokenStream MyTokenStream(Collection tokens) { this->tokens = tokens; - + tokenUpto = 0; termAtt = addAttribute(); posIncrAtt = addAttribute(); offsetAtt = addAttribute(); } - + virtual ~MyTokenStream() { } - + LUCENE_CLASS(MyTokenStream); protected: @@ -120,16 +120,16 @@ class MyAnalyzer : public Analyzer { this->tokens = tokens; } - + virtual ~MyAnalyzer() { } - + LUCENE_CLASS(MyAnalyzer); protected: Collection tokens; - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { @@ -146,57 +146,57 @@ class DocNumAwareMapper : public TermVectorMapper { documentNumber = -1; } - + virtual ~DocNumAwareMapper() { } - + LUCENE_CLASS(DocNumAwareMapper); protected: int32_t documentNumber; - + public: virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { if (documentNumber == -1) - BOOST_FAIL("Documentnumber should be set at this point!"); + FAIL() << "Documentnumber should be set at this point!"; } - + virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions) { if (documentNumber == -1) - BOOST_FAIL("Documentnumber should be set at this point!"); + FAIL() << "Documentnumber should be set at this point!"; } - + virtual int32_t getDocumentNumber() { return documentNumber; } - + virtual void setDocumentNumber(int32_t documentNumber) { this->documentNumber = documentNumber; } }; -class TermVectorsReaderTestFixture : public LuceneTestFixture +class TermVectorsReaderTest : public LuceneTestFixture { public: - TermVectorsReaderTestFixture() + TermVectorsReaderTest() { // Must be lexicographically sorted, will do in setup, versus trying to maintain here testFields = newCollection(L"f1", L"f2", L"f3", L"f4"); testFieldsStorePos = newCollection(true, false, true, false); testFieldsStoreOff = newCollection(true, false, false, true); testTerms = newCollection(L"this", L"is", L"a", L"test"); - + positions = Collection< Collection >::newInstance(testTerms.size()); offsets = Collection< Collection >::newInstance(testTerms.size()); dir = newLucene(); tokens = Collection::newInstance(testTerms.size() * TERM_FREQ); RandomPtr random = newLucene(); - + std::sort(testTerms.begin(), testTerms.end()); int32_t tokenUpto = 0; for (int32_t i = 0; i < testTerms.size(); ++i) @@ -219,7 +219,7 @@ class TermVectorsReaderTestFixture : public LuceneTestFixture } } std::sort(tokens.begin(), tokens.end(), luceneCompare()); - + IndexWriterPtr writer = newLucene(dir, newLucene(tokens), true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(false); DocumentPtr doc = newLucene(); @@ -234,19 +234,19 @@ class TermVectorsReaderTestFixture : public LuceneTestFixture tv = Field::TERM_VECTOR_WITH_OFFSETS; doc->add(newLucene(testFields[i], L"", Field::STORE_NO, Field::INDEX_ANALYZED, tv)); } - + // Create 5 documents for testing, they all have the same terms for (int32_t j = 0; j < 5; ++j) writer->addDocument(doc); - + writer->commit(); seg = writer->newestSegment()->name; writer->close(); fieldInfos = newLucene(dir, seg + L"." + IndexFileNames::FIELD_INFOS_EXTENSION()); } - - virtual ~TermVectorsReaderTestFixture() + + virtual ~TermVectorsReaderTest() { } @@ -261,244 +261,254 @@ class TermVectorsReaderTestFixture : public LuceneTestFixture String seg; FieldInfosPtr fieldInfos; Collection tokens; - + static const int32_t TERM_FREQ; }; -const int32_t TermVectorsReaderTestFixture::TERM_FREQ = 3; - -BOOST_FIXTURE_TEST_SUITE(TermVectorsReaderTest, TermVectorsReaderTestFixture) +const int32_t TermVectorsReaderTest::TERM_FREQ = 3; -BOOST_AUTO_TEST_CASE(testReader) +TEST_F(TermVectorsReaderTest, testReader) { // Check to see the files were created properly in setup - BOOST_CHECK(dir->fileExists(seg + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION())); - BOOST_CHECK(dir->fileExists(seg + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION())); + EXPECT_TRUE(dir->fileExists(seg + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION())); + EXPECT_TRUE(dir->fileExists(seg + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION())); TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); - BOOST_CHECK(reader); - + EXPECT_TRUE(reader); + for (int32_t j = 0; j < 5; ++j) { TermFreqVectorPtr vector = reader->get(j, testFields[0]); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); Collection terms = vector->getTerms(); - BOOST_CHECK(terms); - BOOST_CHECK_EQUAL(terms.size(), testTerms.size()); + EXPECT_TRUE(terms); + EXPECT_EQ(terms.size(), testTerms.size()); for (int32_t i = 0; i < terms.size(); ++i) - BOOST_CHECK_EQUAL(terms[i], testTerms[i]); + EXPECT_EQ(terms[i], testTerms[i]); } } -BOOST_AUTO_TEST_CASE(testPositionReader) +TEST_F(TermVectorsReaderTest, testPositionReader) { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); TermPositionVectorPtr vector = boost::dynamic_pointer_cast(reader->get(0, testFields[0])); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); Collection terms = vector->getTerms(); - BOOST_CHECK(terms); - BOOST_CHECK_EQUAL(terms.size(), testTerms.size()); + EXPECT_TRUE(terms); + EXPECT_EQ(terms.size(), testTerms.size()); for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; - BOOST_CHECK_EQUAL(term, testTerms[i]); + EXPECT_EQ(term, testTerms[i]); Collection positions = vector->getTermPositions(i); - BOOST_CHECK(positions); - BOOST_CHECK_EQUAL(positions.size(), this->positions[i].size()); + EXPECT_TRUE(positions); + EXPECT_EQ(positions.size(), this->positions[i].size()); for (int32_t j = 0; j < positions.size(); ++j) - BOOST_CHECK_EQUAL(positions[j], this->positions[i][j]); + EXPECT_EQ(positions[j], this->positions[i][j]); Collection offset = vector->getOffsets(i); - BOOST_CHECK(offset); - BOOST_CHECK_EQUAL(offset.size(), this->offsets[i].size()); + EXPECT_TRUE(offset); + EXPECT_EQ(offset.size(), this->offsets[i].size()); for (int32_t j = 0; j < offset.size(); ++j) { TermVectorOffsetInfoPtr termVectorOffsetInfo = offset[j]; - BOOST_CHECK(termVectorOffsetInfo->equals(offsets[i][j])); + EXPECT_TRUE(termVectorOffsetInfo->equals(offsets[i][j])); } } TermFreqVectorPtr freqVector = reader->get(0, testFields[1]); // no pos, no offset - BOOST_CHECK(freqVector); - BOOST_CHECK(boost::dynamic_pointer_cast(freqVector)); + EXPECT_TRUE(freqVector); + EXPECT_TRUE(boost::dynamic_pointer_cast(freqVector)); terms = freqVector->getTerms(); - BOOST_CHECK(terms); - BOOST_CHECK_EQUAL(terms.size(), testTerms.size()); + EXPECT_TRUE(terms); + EXPECT_EQ(terms.size(), testTerms.size()); for (int32_t i = 0; i < terms.size(); ++i) - BOOST_CHECK_EQUAL(terms[i], testTerms[i]); + EXPECT_EQ(terms[i], testTerms[i]); } -BOOST_AUTO_TEST_CASE(testOffsetReader) +TEST_F(TermVectorsReaderTest, testOffsetReader) { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); TermPositionVectorPtr vector = boost::dynamic_pointer_cast(reader->get(0, testFields[0])); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); Collection terms = vector->getTerms(); - BOOST_CHECK(terms); - BOOST_CHECK_EQUAL(terms.size(), testTerms.size()); + EXPECT_TRUE(terms); + EXPECT_EQ(terms.size(), testTerms.size()); for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; - BOOST_CHECK_EQUAL(term, testTerms[i]); + EXPECT_EQ(term, testTerms[i]); Collection positions = vector->getTermPositions(i); - BOOST_CHECK(positions); - BOOST_CHECK_EQUAL(positions.size(), this->positions[i].size()); + EXPECT_TRUE(positions); + EXPECT_EQ(positions.size(), this->positions[i].size()); for (int32_t j = 0; j < positions.size(); ++j) - BOOST_CHECK_EQUAL(positions[j], this->positions[i][j]); + EXPECT_EQ(positions[j], this->positions[i][j]); Collection offset = vector->getOffsets(i); - BOOST_CHECK(offset); - BOOST_CHECK_EQUAL(offset.size(), this->offsets[i].size()); + EXPECT_TRUE(offset); + EXPECT_EQ(offset.size(), this->offsets[i].size()); for (int32_t j = 0; j < offset.size(); ++j) { TermVectorOffsetInfoPtr termVectorOffsetInfo = offset[j]; - BOOST_CHECK(termVectorOffsetInfo->equals(offsets[i][j])); + EXPECT_TRUE(termVectorOffsetInfo->equals(offsets[i][j])); } } } -BOOST_AUTO_TEST_CASE(testMapper) +TEST_F(TermVectorsReaderTest, testMapper) { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); SortedTermVectorMapperPtr mapper = newLucene(TermVectorEntryFreqSortedComparator::compare); reader->get(0, mapper); Collection entrySet = mapper->getTermVectorEntrySet(); - BOOST_CHECK(entrySet); + EXPECT_TRUE(entrySet); // three fields, 4 terms, all terms are the same - BOOST_CHECK_EQUAL(entrySet.size(), 4); + EXPECT_EQ(entrySet.size(), 4); // check offsets and positions for (Collection::iterator tve = entrySet.begin(); tve != entrySet.end(); ++tve) { - BOOST_CHECK(*tve); - BOOST_CHECK((*tve)->getOffsets()); - BOOST_CHECK((*tve)->getPositions()); + EXPECT_TRUE(*tve); + EXPECT_TRUE((*tve)->getOffsets()); + EXPECT_TRUE((*tve)->getPositions()); } - + mapper = newLucene(TermVectorEntryFreqSortedComparator::compare); reader->get(1, mapper); entrySet = mapper->getTermVectorEntrySet(); - BOOST_CHECK(entrySet); + EXPECT_TRUE(entrySet); // three fields, 4 terms, all terms are the same - BOOST_CHECK_EQUAL(entrySet.size(), 4); + EXPECT_EQ(entrySet.size(), 4); // should have offsets and positions because we are munging all the fields together for (Collection::iterator tve = entrySet.begin(); tve != entrySet.end(); ++tve) { - BOOST_CHECK(*tve); - BOOST_CHECK((*tve)->getOffsets()); - BOOST_CHECK((*tve)->getPositions()); + EXPECT_TRUE(*tve); + EXPECT_TRUE((*tve)->getOffsets()); + EXPECT_TRUE((*tve)->getPositions()); } - + FieldSortedTermVectorMapperPtr fsMapper = newLucene(TermVectorEntryFreqSortedComparator::compare); reader->get(0, fsMapper); MapStringCollectionTermVectorEntry map = fsMapper->getFieldToTerms(); - BOOST_CHECK_EQUAL(map.size(), testFields.size()); + EXPECT_EQ(map.size(), testFields.size()); for (MapStringCollectionTermVectorEntry::iterator entry = map.begin(); entry != map.end(); ++entry) { Collection termVectorEntries = entry->second; - BOOST_CHECK_EQUAL(termVectorEntries.size(), 4); + EXPECT_EQ(termVectorEntries.size(), 4); for (Collection::iterator tve = termVectorEntries.begin(); tve != termVectorEntries.end(); ++tve) { - BOOST_CHECK(*tve); + EXPECT_TRUE(*tve); // Check offsets and positions. String field = (*tve)->getField(); if (field == testFields[0]) { // should have offsets - BOOST_CHECK((*tve)->getOffsets()); - BOOST_CHECK((*tve)->getPositions()); + EXPECT_TRUE((*tve)->getOffsets()); + EXPECT_TRUE((*tve)->getPositions()); } else if (field == testFields[1]) { // should not have offsets - BOOST_CHECK(!(*tve)->getOffsets()); - BOOST_CHECK(!(*tve)->getPositions()); + EXPECT_TRUE(!(*tve)->getOffsets()); + EXPECT_TRUE(!(*tve)->getPositions()); } } } - + // Try mapper that ignores offs and positions fsMapper = newLucene(true, true, TermVectorEntryFreqSortedComparator::compare); reader->get(0, fsMapper); map = fsMapper->getFieldToTerms(); - BOOST_CHECK_EQUAL(map.size(), testFields.size()); + EXPECT_EQ(map.size(), testFields.size()); for (MapStringCollectionTermVectorEntry::iterator entry = map.begin(); entry != map.end(); ++entry) { Collection termVectorEntries = entry->second; - BOOST_CHECK_EQUAL(termVectorEntries.size(), 4); + EXPECT_EQ(termVectorEntries.size(), 4); for (Collection::iterator tve = termVectorEntries.begin(); tve != termVectorEntries.end(); ++tve) { - BOOST_CHECK(*tve); + EXPECT_TRUE(*tve); // Check offsets and positions. String field = (*tve)->getField(); if (field == testFields[0]) { // should have offsets - BOOST_CHECK(!(*tve)->getOffsets()); - BOOST_CHECK(!(*tve)->getPositions()); + EXPECT_TRUE(!(*tve)->getOffsets()); + EXPECT_TRUE(!(*tve)->getPositions()); } else if (field == testFields[1]) { // should not have offsets - BOOST_CHECK(!(*tve)->getOffsets()); - BOOST_CHECK(!(*tve)->getPositions()); + EXPECT_TRUE(!(*tve)->getOffsets()); + EXPECT_TRUE(!(*tve)->getPositions()); } } } - + // test setDocumentNumber() IndexReaderPtr ir = IndexReader::open(dir, true); DocNumAwareMapperPtr docNumAwareMapper = newLucene(); - BOOST_CHECK_EQUAL(-1, docNumAwareMapper->getDocumentNumber()); + EXPECT_EQ(-1, docNumAwareMapper->getDocumentNumber()); ir->getTermFreqVector(0, docNumAwareMapper); - BOOST_CHECK_EQUAL(0, docNumAwareMapper->getDocumentNumber()); + EXPECT_EQ(0, docNumAwareMapper->getDocumentNumber()); docNumAwareMapper->setDocumentNumber(-1); ir->getTermFreqVector(1, docNumAwareMapper); - BOOST_CHECK_EQUAL(1, docNumAwareMapper->getDocumentNumber()); + EXPECT_EQ(1, docNumAwareMapper->getDocumentNumber()); docNumAwareMapper->setDocumentNumber(-1); ir->getTermFreqVector(0, L"f1", docNumAwareMapper); - BOOST_CHECK_EQUAL(0, docNumAwareMapper->getDocumentNumber()); + EXPECT_EQ(0, docNumAwareMapper->getDocumentNumber()); docNumAwareMapper->setDocumentNumber(-1); ir->getTermFreqVector(1, L"f2", docNumAwareMapper); - BOOST_CHECK_EQUAL(1, docNumAwareMapper->getDocumentNumber()); + EXPECT_EQ(1, docNumAwareMapper->getDocumentNumber()); docNumAwareMapper->setDocumentNumber(-1); ir->getTermFreqVector(0, L"f1", docNumAwareMapper); - BOOST_CHECK_EQUAL(0, docNumAwareMapper->getDocumentNumber()); + EXPECT_EQ(0, docNumAwareMapper->getDocumentNumber()); ir->close(); } /// Make sure exceptions and bad params are handled appropriately -BOOST_AUTO_TEST_CASE(testBadParams) +TEST_F(TermVectorsReaderTest, testBadParams) { { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); // Bad document number, good field number - BOOST_CHECK_EXCEPTION(reader->get(50, testFields[0]), IOException, check_exception(LuceneException::IO)); + try + { + reader->get(50, testFields[0]); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } } - + { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); - BOOST_CHECK(reader); + EXPECT_TRUE(reader); // Bad document number, no field - BOOST_CHECK_EXCEPTION(reader->get(50), IOException, check_exception(LuceneException::IO)); + try + { + reader->get(50); + } + catch (IOException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } } - + { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); - BOOST_CHECK(reader); - + EXPECT_TRUE(reader); + // Good document number, bad field number TermFreqVectorPtr vector; - BOOST_CHECK_NO_THROW(vector = reader->get(0, L"f50")); - BOOST_CHECK(!vector); + EXPECT_NO_THROW(vector = reader->get(0, L"f50")); + EXPECT_TRUE(!vector); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/ThreadedOptimizeTest.cpp b/src/test/index/ThreadedOptimizeTest.cpp index 3a7f25c3..616361e8 100644 --- a/src/test/index/ThreadedOptimizeTest.cpp +++ b/src/test/index/ThreadedOptimizeTest.cpp @@ -33,7 +33,7 @@ class OptimizeThread : public LuceneThread this->writer = writer; this->writerFinal = writerFinal; } - + virtual ~OptimizeThread() { } @@ -46,7 +46,7 @@ class OptimizeThread : public LuceneThread int32_t iFinal; IndexWriterPtr writer; IndexWriterPtr writerFinal; - + public: virtual void run() { @@ -69,20 +69,20 @@ class OptimizeThread : public LuceneThread } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; -class ThreadedOptimizeTestFixture : public LuceneTestFixture +class ThreadedOptimizeTest : public LuceneTestFixture { public: - ThreadedOptimizeTestFixture() + ThreadedOptimizeTest() { analyzer = newLucene(); } - - virtual ~ThreadedOptimizeTestFixture() + + virtual ~ThreadedOptimizeTest() { } @@ -90,7 +90,7 @@ class ThreadedOptimizeTestFixture : public LuceneTestFixture static const int32_t NUM_THREADS; static const int32_t NUM_ITER; static const int32_t NUM_ITER2; - + AnalyzerPtr analyzer; public: @@ -100,13 +100,13 @@ class ThreadedOptimizeTestFixture : public LuceneTestFixture writer->setMaxBufferedDocs(2); if (merger) writer->setMergeScheduler(merger); - + for (int32_t iter = 0; iter < NUM_ITER; ++iter) { int32_t iterFinal = iter; writer->setMergeFactor(1000); - + for (int32_t i = 0; i < 200; ++i) { DocumentPtr d = newLucene(); @@ -114,53 +114,51 @@ class ThreadedOptimizeTestFixture : public LuceneTestFixture d->add(newLucene(L"contents", intToEnglish(i), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(d); } - + writer->setMergeFactor(4); - + Collection threads = Collection::newInstance(NUM_THREADS); - + for (int32_t i = 0; i < NUM_THREADS; ++i) { int32_t iFinal = i; IndexWriterPtr writerFinal = writer; threads[i] = newLucene(NUM_ITER2, iterFinal, iFinal, writer, writerFinal); } - + for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->start(); for (int32_t i = 0; i < NUM_THREADS; ++i) threads[i]->join(); - + int32_t expectedDocCount = (int32_t)((1 + iter) * (200 + 8 * NUM_ITER2 * (int32_t)(((double)NUM_THREADS / 2.0) * (double)(1 + NUM_THREADS)))); - BOOST_CHECK_EQUAL(expectedDocCount, writer->maxDoc()); + EXPECT_EQ(expectedDocCount, writer->maxDoc()); writer->close(); writer = newLucene(directory, analyzer, false, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); IndexReaderPtr reader = IndexReader::open(directory, true); - BOOST_CHECK(reader->isOptimized()); - BOOST_CHECK_EQUAL(expectedDocCount, reader->numDocs()); + EXPECT_TRUE(reader->isOptimized()); + EXPECT_EQ(expectedDocCount, reader->numDocs()); reader->close(); } writer->close(); } }; -const int32_t ThreadedOptimizeTestFixture::NUM_THREADS = 3; -const int32_t ThreadedOptimizeTestFixture::NUM_ITER = 1; -const int32_t ThreadedOptimizeTestFixture::NUM_ITER2 = 1; +const int32_t ThreadedOptimizeTest::NUM_THREADS = 3; +const int32_t ThreadedOptimizeTest::NUM_ITER = 1; +const int32_t ThreadedOptimizeTest::NUM_ITER2 = 1; -BOOST_FIXTURE_TEST_SUITE(ThreadedOptimizeTest, ThreadedOptimizeTestFixture) - -BOOST_AUTO_TEST_CASE(testThreadedOptimize) +TEST_F(ThreadedOptimizeTest, testThreadedOptimize) { DirectoryPtr directory = newLucene(); runTest(directory, newLucene()); runTest(directory, newLucene()); directory->close(); - + String dirName(FileUtils::joinPath(getTempDir(), L"luceneTestThreadedOptimize")); directory = FSDirectory::open(dirName); runTest(directory, newLucene()); @@ -168,5 +166,3 @@ BOOST_AUTO_TEST_CASE(testThreadedOptimize) directory->close(); FileUtils::removeDirectory(dirName); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/TransactionRollbackTest.cpp b/src/test/index/TransactionRollbackTest.cpp index e24f6f6a..09b7c88b 100644 --- a/src/test/index/TransactionRollbackTest.cpp +++ b/src/test/index/TransactionRollbackTest.cpp @@ -21,20 +21,20 @@ using namespace Lucene; /// Keeps all commit points (used to build index) -class KeepAllDeletionPolicy : public IndexDeletionPolicy +class TransactionRollbackKeepAllDeletionPolicy : public IndexDeletionPolicy { public: - virtual ~KeepAllDeletionPolicy() + virtual ~TransactionRollbackKeepAllDeletionPolicy() { } - - LUCENE_CLASS(KeepAllDeletionPolicy); - + + LUCENE_CLASS(TransactionRollbackKeepAllDeletionPolicy); + public: virtual void onInit(Collection commits) { } - + virtual void onCommit(Collection commits) { } @@ -48,16 +48,16 @@ class RollbackDeletionPolicy : public IndexDeletionPolicy { this->rollbackPoint = rollbackPoint; } - + virtual ~RollbackDeletionPolicy() { } - + LUCENE_CLASS(RollbackDeletionPolicy); - + protected: int32_t rollbackPoint; - + public: virtual void onInit(Collection commits) { @@ -76,7 +76,7 @@ class RollbackDeletionPolicy : public IndexDeletionPolicy } } } - + virtual void onCommit(Collection commits) { } @@ -88,15 +88,15 @@ class DeleteLastCommitPolicy : public IndexDeletionPolicy virtual ~DeleteLastCommitPolicy() { } - + LUCENE_CLASS(DeleteLastCommitPolicy); - + public: virtual void onInit(Collection commits) { commits[commits.size() - 1]->deleteCommit(); } - + virtual void onCommit(Collection commits) { } @@ -106,22 +106,22 @@ class DeleteLastCommitPolicy : public IndexDeletionPolicy /// This test case creates an index of records 1 to 100, introducing a commit point every 10 records. /// /// A "keep all" deletion policy is used to ensure we keep all commit points for testing purposes -class TransactionRollbackTestFixture : public LuceneTestFixture +class TransactionRollbackTest : public LuceneTestFixture { public: - TransactionRollbackTestFixture() + TransactionRollbackTest() { FIELD_RECORD_ID = L"record_id"; dir = newLucene(); // Build index, of records 1 to 100, committing after each batch of 10 - IndexDeletionPolicyPtr sdp = newLucene(); + IndexDeletionPolicyPtr sdp = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), sdp, IndexWriter::MaxFieldLengthUNLIMITED); for (int32_t currentRecordId = 1; currentRecordId <= 100; ++currentRecordId) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD_RECORD_ID, StringUtils::toString(currentRecordId), Field::STORE_YES, Field::INDEX_ANALYZED)); w->addDocument(doc); - + if (currentRecordId % 10 == 0) { MapStringString data = MapStringString::newInstance(); @@ -129,11 +129,11 @@ class TransactionRollbackTestFixture : public LuceneTestFixture w->commit(data); } } - + w->close(); } - - virtual ~TransactionRollbackTestFixture() + + virtual ~TransactionRollbackTest() { } @@ -157,16 +157,16 @@ class TransactionRollbackTestFixture : public LuceneTestFixture last = *commit; } } - - BOOST_CHECK(last); - + + EXPECT_TRUE(last); + IndexWriterPtr w = newLucene(dir, newLucene(), newLucene(id), IndexWriter::MaxFieldLengthUNLIMITED, last); MapStringString data = MapStringString::newInstance(); data.put(L"index", L"Rolled back to 1-" + StringUtils::toString(id)); w->commit(data); w->close(); } - + void checkExpecteds(BitSetPtr expecteds) { IndexReaderPtr r = IndexReader::open(dir, true); @@ -180,19 +180,17 @@ class TransactionRollbackTestFixture : public LuceneTestFixture if (!sval.empty()) { int32_t val = StringUtils::toInt(sval); - BOOST_CHECK(expecteds->get(val)); + EXPECT_TRUE(expecteds->get(val)); expecteds->set(val, false); } } } r->close(); - BOOST_CHECK_EQUAL(0, expecteds->cardinality()); + EXPECT_EQ(0, expecteds->cardinality()); } }; -BOOST_FIXTURE_TEST_SUITE(TransactionRollbackTest, TransactionRollbackTestFixture) - -BOOST_AUTO_TEST_CASE(testRepeatedRollBacks) +TEST_F(TransactionRollbackTest, testRepeatedRollBacks) { int32_t expectedLastRecordId = 100; while (expectedLastRecordId > 10) @@ -206,16 +204,14 @@ BOOST_AUTO_TEST_CASE(testRepeatedRollBacks) } } -BOOST_AUTO_TEST_CASE(testRollbackDeletionPolicy) +TEST_F(TransactionRollbackTest, testRollbackDeletionPolicy) { for (int32_t i = 0; i < 2; ++i) { // Unless you specify a prior commit point, rollback should not work newLucene(dir, newLucene(), (IndexDeletionPolicyPtr)newLucene(), IndexWriter::MaxFieldLengthUNLIMITED)->close(); IndexReaderPtr r = IndexReader::open(dir, true); - BOOST_CHECK_EQUAL(100, r->numDocs()); + EXPECT_EQ(100, r->numDocs()); r->close(); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/TransactionsTest.cpp b/src/test/index/TransactionsTest.cpp index 7b957dc8..d43e7425 100644 --- a/src/test/index/TransactionsTest.cpp +++ b/src/test/index/TransactionsTest.cpp @@ -20,37 +20,37 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(TransactionsTest, LuceneTestFixture) +typedef LuceneTestFixture TransactionsTest; static bool doFail = false; -DECLARE_SHARED_PTR(TimedThread) -DECLARE_SHARED_PTR(IndexerThread) -DECLARE_SHARED_PTR(SearcherThread) +DECLARE_SHARED_PTR(TransactionsTimedThread) +DECLARE_SHARED_PTR(TransactionsIndexerThread) +DECLARE_SHARED_PTR(TransactionsSearcherThread) -class TimedThread : public LuceneThread +class TransactionsTimedThread : public LuceneThread { public: - TimedThread() + TransactionsTimedThread() { } - - virtual ~TimedThread() + + virtual ~TransactionsTimedThread() { } - - LUCENE_CLASS(TimedThread); - + + LUCENE_CLASS(TransactionsTimedThread); + protected: static const int32_t RUN_TIME_SEC; - + public: virtual void doWork() = 0; - + virtual void run() { int64_t stopTime = MiscUtils::currentTimeMillis() + 1000 * RUN_TIME_SEC; - + try { while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) @@ -58,17 +58,17 @@ class TimedThread : public LuceneThread } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } }; -const int32_t TimedThread::RUN_TIME_SEC = 6; +const int32_t TransactionsTimedThread::RUN_TIME_SEC = 6; -class IndexerThread : public TimedThread +class TransactionsIndexerThread : public TransactionsTimedThread { public: - IndexerThread(SynchronizePtr lock, DirectoryPtr dir1, DirectoryPtr dir2) + TransactionsIndexerThread(SynchronizePtr lock, DirectoryPtr dir1, DirectoryPtr dir2) { this->lock = lock; this->dir1 = dir1; @@ -76,20 +76,20 @@ class IndexerThread : public TimedThread this->nextID = 0; this->random = newLucene(); } - - virtual ~IndexerThread() + + virtual ~TransactionsIndexerThread() { } - - LUCENE_CLASS(IndexerThread); - + + LUCENE_CLASS(TransactionsIndexerThread); + public: DirectoryPtr dir1; DirectoryPtr dir2; SynchronizePtr lock; int32_t nextID; RandomPtr random; - + public: virtual void doWork() { @@ -106,10 +106,10 @@ class IndexerThread : public TimedThread update(writer1); update(writer2); - + doFail = true; bool continueWork = true; - + LuceneException finally; try { @@ -143,14 +143,14 @@ class IndexerThread : public TimedThread } doFail = false; finally.throwException(); - + if (!continueWork) return; - + writer1->close(); writer2->close(); } - + void update(IndexWriterPtr writer) { // Add 10 docs @@ -161,7 +161,7 @@ class IndexerThread : public TimedThread d->add(newLucene(L"contents", intToEnglish(random->nextInt()), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(d); } - + // Delete 5 docs int32_t deleteID = nextID - 1; for (int32_t j = 0; j < 5; ++j) @@ -172,27 +172,27 @@ class IndexerThread : public TimedThread } }; -class SearcherThread : public TimedThread +class TransactionsSearcherThread : public TransactionsTimedThread { public: - SearcherThread(SynchronizePtr lock, DirectoryPtr dir1, DirectoryPtr dir2) + TransactionsSearcherThread(SynchronizePtr lock, DirectoryPtr dir1, DirectoryPtr dir2) { this->lock = lock; this->dir1 = dir1; this->dir2 = dir2; } - - virtual ~SearcherThread() + + virtual ~TransactionsSearcherThread() { } - - LUCENE_CLASS(SearcherThread); - + + LUCENE_CLASS(TransactionsSearcherThread); + protected: DirectoryPtr dir1; DirectoryPtr dir2; SynchronizePtr lock; - + public: virtual void doWork() { @@ -204,7 +204,7 @@ class SearcherThread : public TimedThread r2 = IndexReader::open(dir2, true); } if (r1->numDocs() != r2->numDocs()) - BOOST_FAIL("doc counts differ"); + FAIL() << "doc counts differ"; r1->close(); r2->close(); } @@ -219,14 +219,14 @@ class RandomFailure : public MockDirectoryFailure { random = newLucene(); } - + virtual ~RandomFailure() { } protected: RandomPtr random; - + public: virtual void eval(MockRAMDirectoryPtr dir) { @@ -248,7 +248,7 @@ static void initIndex(DirectoryPtr dir) writer->close(); } -BOOST_AUTO_TEST_CASE(testTransactions) +TEST_F(TransactionsTest, testTransactions) { MockRAMDirectoryPtr dir1 = newLucene(); MockRAMDirectoryPtr dir2 = newLucene(); @@ -260,25 +260,23 @@ BOOST_AUTO_TEST_CASE(testTransactions) initIndex(dir1); initIndex(dir2); - Collection threads = Collection::newInstance(3); + Collection threads = Collection::newInstance(3); int32_t numThread = 0; - + SynchronizePtr lock = newInstance(); - IndexerThreadPtr indexerThread = newLucene(lock, dir1, dir2); + TransactionsIndexerThreadPtr indexerThread = newLucene(lock, dir1, dir2); threads[numThread++] = indexerThread; indexerThread->start(); - SearcherThreadPtr searcherThread1 = newLucene(lock, dir1, dir2); + TransactionsSearcherThreadPtr searcherThread1 = newLucene(lock, dir1, dir2); threads[numThread++] = searcherThread1; searcherThread1->start(); - SearcherThreadPtr searcherThread2 = newLucene(lock, dir1, dir2); + TransactionsSearcherThreadPtr searcherThread2 = newLucene(lock, dir1, dir2); threads[numThread++] = searcherThread2; searcherThread2->start(); - + for (int32_t i = 0; i < numThread; ++i) threads[i]->join(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/index/WordlistLoaderTest.cpp b/src/test/index/WordlistLoaderTest.cpp index 9249a343..a634ea4c 100644 --- a/src/test/index/WordlistLoaderTest.cpp +++ b/src/test/index/WordlistLoaderTest.cpp @@ -13,19 +13,19 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(WordlistLoaderTest, LuceneTestFixture) +typedef LuceneTestFixture WordlistLoaderTest; static void checkSet(HashSet wordset) { - BOOST_CHECK_EQUAL(3, wordset.size()); - BOOST_CHECK(wordset.contains(L"ONE")); // case is not modified - BOOST_CHECK(!wordset.contains(L"one")); // case is not modified - BOOST_CHECK(wordset.contains(L"two")); // surrounding whitespace is removed - BOOST_CHECK(wordset.contains(L"three")); - BOOST_CHECK(!wordset.contains(L"four")); + EXPECT_EQ(3, wordset.size()); + EXPECT_TRUE(wordset.contains(L"ONE")); // case is not modified + EXPECT_TRUE(!wordset.contains(L"one")); // case is not modified + EXPECT_TRUE(wordset.contains(L"two")); // surrounding whitespace is removed + EXPECT_TRUE(wordset.contains(L"three")); + EXPECT_TRUE(!wordset.contains(L"four")); } -BOOST_AUTO_TEST_CASE(testWordlistLoading) +TEST_F(WordlistLoaderTest, testWordlistLoading) { String s = L"ONE\n two \nthree"; HashSet wordSet1 = WordlistLoader::getWordSet(newLucene(s)); @@ -34,13 +34,11 @@ BOOST_AUTO_TEST_CASE(testWordlistLoading) checkSet(wordSet2); } -BOOST_AUTO_TEST_CASE(testComments) +TEST_F(WordlistLoaderTest, testComments) { String s = L"ONE\n two \nthree\n#comment"; HashSet wordSet1 = WordlistLoader::getWordSet(newLucene(s), L"#"); checkSet(wordSet1); - BOOST_CHECK(!wordSet1.contains(L"#comment")); - BOOST_CHECK(!wordSet1.contains(L"comment")); + EXPECT_TRUE(!wordSet1.contains(L"#comment")); + EXPECT_TRUE(!wordSet1.contains(L"comment")); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/main/main.cpp b/src/test/main/main.cpp index 493ff7a8..032c9e2d 100644 --- a/src/test/main/main.cpp +++ b/src/test/main/main.cpp @@ -21,11 +21,10 @@ #include "MiscUtils.h" #include "FileUtils.h" #include "StringUtils.h" +#include "LuceneGlobalFixture.h" -#define BOOST_TEST_MODULE "Lucene" -#define BOOST_TEST_NO_MAIN +#include -#include #include using namespace Lucene; @@ -33,8 +32,7 @@ using namespace Lucene; int main(int argc, char* argv[]) { String testDir; - uint64_t startTime = MiscUtils::currentTimeMillis(); - + for (int32_t i = 0; i < argc; ++i) { if (strncmp(argv[i], "--test_dir", 9) == 0) @@ -50,9 +48,9 @@ int main(int argc, char* argv[]) } } } - + if (testDir.empty()) - { + { testDir = L"../../src/test/testfiles"; if (!FileUtils::isDirectory(testDir)) { @@ -61,18 +59,17 @@ int main(int argc, char* argv[]) testDir = L"./src/test/testfiles"; } } - + if (!FileUtils::isDirectory(testDir)) { std::wcout << L"Test directory not found. (override default by using --test_dir=\"./src/test/testfiles\")\n"; return 1; } - + setTestDir(testDir); - - int testMain = boost::unit_test::unit_test_main(init_unit_test_suite, argc, argv); - - std::wcout << L"*** Test duration: " << (MiscUtils::currentTimeMillis() - startTime) / 1000 << L" sec\n"; - - return testMain; + + testing::InitGoogleTest(&argc, argv); + testing::AddGlobalTestEnvironment(new LuceneGlobalFixture()); + + return RUN_ALL_TESTS(); } diff --git a/src/test/queryparser/MultiAnalyzerTest.cpp b/src/test/queryparser/MultiAnalyzerTest.cpp index a06fdaa8..4ad90ba1 100644 --- a/src/test/queryparser/MultiAnalyzerTest.cpp +++ b/src/test/queryparser/MultiAnalyzerTest.cpp @@ -19,22 +19,22 @@ using namespace Lucene; -/// Test QueryParser's ability to deal with Analyzers that return more than one token per +/// Test QueryParser's ability to deal with Analyzers that return more than one token per /// position or that return tokens with a position increment > 1. -BOOST_FIXTURE_TEST_SUITE(MultiAnalyzerTest, BaseTokenStreamFixture) +typedef BaseTokenStreamFixture MultiAnalyzerTest; static int32_t multiToken = 0; DECLARE_SHARED_PTR(MultiAnalyzer) -DECLARE_SHARED_PTR(TestFilter) +DECLARE_SHARED_PTR(MultiAnalyzerTestFilter) DECLARE_SHARED_PTR(DumbQueryWrapper) DECLARE_SHARED_PTR(DumbQueryParser) DECLARE_SHARED_PTR(TestPosIncrementFilter) -class TestFilter : public TokenFilter +class MultiAnalyzerTestFilter : public TokenFilter { public: - TestFilter(TokenStreamPtr in) : TokenFilter(in) + MultiAnalyzerTestFilter(TokenStreamPtr in) : TokenFilter(in) { prevStartOffset = 0; prevEndOffset = 0; @@ -43,12 +43,12 @@ class TestFilter : public TokenFilter offsetAtt = addAttribute(); typeAtt = addAttribute(); } - - virtual ~TestFilter() + + virtual ~MultiAnalyzerTestFilter() { } - - LUCENE_CLASS(TestFilter); + + LUCENE_CLASS(MultiAnalyzerTestFilter); protected: String prevType; @@ -103,14 +103,14 @@ class MultiAnalyzer : public Analyzer virtual ~MultiAnalyzer() { } - + LUCENE_CLASS(MultiAnalyzer); public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(LuceneVersion::LUCENE_CURRENT, reader); - result = newLucene(result); + result = newLucene(result); result = newLucene(result); return result; } @@ -124,11 +124,11 @@ class DumbQueryWrapper : public Query { this->q = q; } - + virtual ~DumbQueryWrapper() { } - + LUCENE_CLASS(DumbQueryWrapper); protected: @@ -148,11 +148,11 @@ class DumbQueryParser : public QueryParser DumbQueryParser(const String& f, AnalyzerPtr a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { } - + virtual ~DumbQueryParser() { } - + LUCENE_CLASS(DumbQueryParser); public: @@ -170,11 +170,11 @@ class TestPosIncrementFilter : public TokenFilter termAtt = addAttribute(); posIncrAtt = addAttribute(); } - + virtual ~TestPosIncrementFilter() { } - + LUCENE_CLASS(TestPosIncrementFilter); protected: @@ -213,7 +213,7 @@ class PosIncrementAnalyzer : public Analyzer virtual ~PosIncrementAnalyzer() { } - + LUCENE_CLASS(PosIncrementAnalyzer); public: @@ -226,75 +226,73 @@ class PosIncrementAnalyzer : public Analyzer } }; -BOOST_AUTO_TEST_CASE(testMultiAnalyzer) +TEST_F(MultiAnalyzerTest, testMultiAnalyzer) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"", newLucene()); // trivial, no multiple tokens - BOOST_CHECK_EQUAL(L"foo", qp->parse(L"foo")->toString()); - BOOST_CHECK_EQUAL(L"foo", qp->parse(L"\"foo\"")->toString()); - BOOST_CHECK_EQUAL(L"foo foobar", qp->parse(L"foo foobar")->toString()); - BOOST_CHECK_EQUAL(L"\"foo foobar\"", qp->parse(L"\"foo foobar\"")->toString()); - BOOST_CHECK_EQUAL(L"\"foo foobar blah\"", qp->parse(L"\"foo foobar blah\"")->toString()); + EXPECT_EQ(L"foo", qp->parse(L"foo")->toString()); + EXPECT_EQ(L"foo", qp->parse(L"\"foo\"")->toString()); + EXPECT_EQ(L"foo foobar", qp->parse(L"foo foobar")->toString()); + EXPECT_EQ(L"\"foo foobar\"", qp->parse(L"\"foo foobar\"")->toString()); + EXPECT_EQ(L"\"foo foobar blah\"", qp->parse(L"\"foo foobar blah\"")->toString()); // two tokens at the same position - BOOST_CHECK_EQUAL(L"(multi multi2) foo", qp->parse(L"multi foo")->toString()); - BOOST_CHECK_EQUAL(L"foo (multi multi2)", qp->parse(L"foo multi")->toString()); - BOOST_CHECK_EQUAL(L"(multi multi2) (multi multi2)", qp->parse(L"multi multi")->toString()); - BOOST_CHECK_EQUAL(L"+(foo (multi multi2)) +(bar (multi multi2))", qp->parse(L"+(foo multi) +(bar multi)")->toString()); - BOOST_CHECK_EQUAL(L"+(foo (multi multi2)) field:\"bar (multi multi2)\"", qp->parse(L"+(foo multi) field:\"bar multi\"")->toString()); + EXPECT_EQ(L"(multi multi2) foo", qp->parse(L"multi foo")->toString()); + EXPECT_EQ(L"foo (multi multi2)", qp->parse(L"foo multi")->toString()); + EXPECT_EQ(L"(multi multi2) (multi multi2)", qp->parse(L"multi multi")->toString()); + EXPECT_EQ(L"+(foo (multi multi2)) +(bar (multi multi2))", qp->parse(L"+(foo multi) +(bar multi)")->toString()); + EXPECT_EQ(L"+(foo (multi multi2)) field:\"bar (multi multi2)\"", qp->parse(L"+(foo multi) field:\"bar multi\"")->toString()); // phrases - BOOST_CHECK_EQUAL(L"\"(multi multi2) foo\"", qp->parse(L"\"multi foo\"")->toString()); - BOOST_CHECK_EQUAL(L"\"foo (multi multi2)\"", qp->parse(L"\"foo multi\"")->toString()); - BOOST_CHECK_EQUAL(L"\"foo (multi multi2) foobar (multi multi2)\"", qp->parse(L"\"foo multi foobar multi\"")->toString()); + EXPECT_EQ(L"\"(multi multi2) foo\"", qp->parse(L"\"multi foo\"")->toString()); + EXPECT_EQ(L"\"foo (multi multi2)\"", qp->parse(L"\"foo multi\"")->toString()); + EXPECT_EQ(L"\"foo (multi multi2) foobar (multi multi2)\"", qp->parse(L"\"foo multi foobar multi\"")->toString()); // fields - BOOST_CHECK_EQUAL(L"(field:multi field:multi2) field:foo", qp->parse(L"field:multi field:foo")->toString()); - BOOST_CHECK_EQUAL(L"field:\"(multi multi2) foo\"", qp->parse(L"field:\"multi foo\"")->toString()); + EXPECT_EQ(L"(field:multi field:multi2) field:foo", qp->parse(L"field:multi field:foo")->toString()); + EXPECT_EQ(L"field:\"(multi multi2) foo\"", qp->parse(L"field:\"multi foo\"")->toString()); // three tokens at one position - BOOST_CHECK_EQUAL(L"triplemulti multi3 multi2", qp->parse(L"triplemulti")->toString()); - BOOST_CHECK_EQUAL(L"foo (triplemulti multi3 multi2) foobar", qp->parse(L"foo triplemulti foobar")->toString()); + EXPECT_EQ(L"triplemulti multi3 multi2", qp->parse(L"triplemulti")->toString()); + EXPECT_EQ(L"foo (triplemulti multi3 multi2) foobar", qp->parse(L"foo triplemulti foobar")->toString()); // phrase with non-default slop - BOOST_CHECK_EQUAL(L"\"(multi multi2) foo\"~10", qp->parse(L"\"multi foo\"~10")->toString()); - + EXPECT_EQ(L"\"(multi multi2) foo\"~10", qp->parse(L"\"multi foo\"~10")->toString()); + // phrase with non-default boost - BOOST_CHECK_EQUAL(L"\"(multi multi2) foo\"^2.0", qp->parse(L"\"multi foo\"^2")->toString()); + EXPECT_EQ(L"\"(multi multi2) foo\"^2.0", qp->parse(L"\"multi foo\"^2")->toString()); // phrase after changing default slop qp->setPhraseSlop(99); - BOOST_CHECK_EQUAL(L"\"(multi multi2) foo\"~99 bar", qp->parse(L"\"multi foo\" bar")->toString()); - BOOST_CHECK_EQUAL(L"\"(multi multi2) foo\"~99 \"foo bar\"~2", qp->parse(L"\"multi foo\" \"foo bar\"~2")->toString()); + EXPECT_EQ(L"\"(multi multi2) foo\"~99 bar", qp->parse(L"\"multi foo\" bar")->toString()); + EXPECT_EQ(L"\"(multi multi2) foo\"~99 \"foo bar\"~2", qp->parse(L"\"multi foo\" \"foo bar\"~2")->toString()); qp->setPhraseSlop(0); // non-default operator qp->setDefaultOperator(QueryParser::AND_OPERATOR); - BOOST_CHECK_EQUAL(L"+(multi multi2) +foo", qp->parse(L"multi foo")->toString()); + EXPECT_EQ(L"+(multi multi2) +foo", qp->parse(L"multi foo")->toString()); } -BOOST_AUTO_TEST_CASE(testMultiAnalyzerWithSubclassOfQueryParser) +TEST_F(MultiAnalyzerTest, testMultiAnalyzerWithSubclassOfQueryParser) { DumbQueryParserPtr qp = newLucene(L"", newLucene()); qp->setPhraseSlop(99); // modified default slop // direct call to getFieldQuery to demonstrate difference between phrase and multiphrase with modified default slop - BOOST_CHECK_EQUAL(L"\"foo bar\"~99", qp->getFieldQuery(L"", L"foo bar")->toString()); - BOOST_CHECK_EQUAL(L"\"(multi multi2) bar\"~99", qp->getFieldQuery(L"", L"multi bar")->toString()); + EXPECT_EQ(L"\"foo bar\"~99", qp->getFieldQuery(L"", L"foo bar")->toString()); + EXPECT_EQ(L"\"(multi multi2) bar\"~99", qp->getFieldQuery(L"", L"multi bar")->toString()); // ask subclass to parse phrase with modified default slop - BOOST_CHECK_EQUAL(L"\"(multi multi2) foo\"~99 bar", qp->parse(L"\"multi foo\" bar")->toString()); + EXPECT_EQ(L"\"(multi multi2) foo\"~99 bar", qp->parse(L"\"multi foo\" bar")->toString()); } -BOOST_AUTO_TEST_CASE(testPosIncrementAnalyzer) +TEST_F(MultiAnalyzerTest, testPosIncrementAnalyzer) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_24, L"", newLucene()); - BOOST_CHECK_EQUAL(L"quick brown", qp->parse(L"the quick brown")->toString()); - BOOST_CHECK_EQUAL(L"\"quick brown\"", qp->parse(L"\"the quick brown\"")->toString()); - BOOST_CHECK_EQUAL(L"quick brown fox", qp->parse(L"the quick brown fox")->toString()); - BOOST_CHECK_EQUAL(L"\"quick brown fox\"", qp->parse(L"\"the quick brown fox\"")->toString()); + EXPECT_EQ(L"quick brown", qp->parse(L"the quick brown")->toString()); + EXPECT_EQ(L"\"quick brown\"", qp->parse(L"\"the quick brown\"")->toString()); + EXPECT_EQ(L"quick brown fox", qp->parse(L"the quick brown fox")->toString()); + EXPECT_EQ(L"\"quick brown fox\"", qp->parse(L"\"the quick brown fox\"")->toString()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/queryparser/MultiFieldQueryParserTest.cpp b/src/test/queryparser/MultiFieldQueryParserTest.cpp index debb46ea..67220a13 100644 --- a/src/test/queryparser/MultiFieldQueryParserTest.cpp +++ b/src/test/queryparser/MultiFieldQueryParserTest.cpp @@ -24,16 +24,16 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(MultiFieldQueryParserTest, LuceneTestFixture) +typedef LuceneTestFixture MultiFieldQueryParserTest; -DECLARE_SHARED_PTR(TestAnalyzer) -DECLARE_SHARED_PTR(TestFilter) +DECLARE_SHARED_PTR(MultiFieldQueryParserTestAnalyzer) +DECLARE_SHARED_PTR(MultiFieldQueryParserTestFilter) /// Filter which discards the token 'stop' and which expands the token 'phrase' into 'phrase1 phrase2' -class TestFilter : public TokenFilter +class MultiFieldQueryParserTestFilter : public TokenFilter { public: - TestFilter(TokenStreamPtr in) : TokenFilter(in) + MultiFieldQueryParserTestFilter(TokenStreamPtr in) : TokenFilter(in) { termAtt = addAttribute(); offsetAtt = addAttribute(); @@ -41,12 +41,12 @@ class TestFilter : public TokenFilter savedStart = 0; savedEnd = 0; } - - virtual ~TestFilter() + + virtual ~MultiFieldQueryParserTestFilter() { } - - LUCENE_CLASS(TestFilter); + + LUCENE_CLASS(MultiFieldQueryParserTestFilter); public: bool inPhrase; @@ -86,20 +86,20 @@ class TestFilter : public TokenFilter } }; -class TestAnalyzer : public Analyzer +class MultiFieldQueryParserTestAnalyzer : public Analyzer { public: - virtual ~TestAnalyzer() + virtual ~MultiFieldQueryParserTestAnalyzer() { } - - LUCENE_CLASS(TestAnalyzer); + + LUCENE_CLASS(MultiFieldQueryParserTestAnalyzer); public: // Filters LowerCaseTokenizer with StopFilter. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { - return newLucene(newLucene(reader)); + return newLucene(newLucene(reader)); } }; @@ -109,7 +109,7 @@ class EmptyTokenStream : public TokenStream virtual ~EmptyTokenStream() { } - + LUCENE_CLASS(EmptyTokenStream); public: @@ -127,11 +127,11 @@ class AnalyzerReturningNull : public Analyzer { standardAnalyzer = newLucene(LuceneVersion::LUCENE_CURRENT); } - + virtual ~AnalyzerReturningNull() { } - + LUCENE_CLASS(AnalyzerReturningNull); protected: @@ -152,88 +152,88 @@ static void checkStopQueryEquals(const String& qtxt, const String& expectedRes) { Collection fields = newCollection(L"b", L"t"); Collection occur = newCollection(BooleanClause::SHOULD, BooleanClause::SHOULD); - TestAnalyzerPtr a = newLucene(); + MultiFieldQueryParserTestAnalyzerPtr a = newLucene(); MultiFieldQueryParserPtr mfqp = newLucene(LuceneVersion::LUCENE_CURRENT, fields, a); QueryPtr q = mfqp->parse(qtxt); - BOOST_CHECK_EQUAL(expectedRes, q->toString()); + EXPECT_EQ(expectedRes, q->toString()); q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, qtxt, fields, occur, a); - BOOST_CHECK_EQUAL(expectedRes, q->toString()); + EXPECT_EQ(expectedRes, q->toString()); } /// test stop words arising for both the non static form, and for the corresponding static form (qtxt, fields[]). -BOOST_AUTO_TEST_CASE(testStopwordsParsing) +TEST_F(MultiFieldQueryParserTest, testStopwordsParsing) { - checkStopQueryEquals(L"one", L"b:one t:one"); - checkStopQueryEquals(L"one stop", L"b:one t:one"); - checkStopQueryEquals(L"one (stop)", L"b:one t:one"); - checkStopQueryEquals(L"one ((stop))", L"b:one t:one"); - checkStopQueryEquals(L"stop", L""); - checkStopQueryEquals(L"(stop)", L""); - checkStopQueryEquals(L"((stop))", L""); + checkStopQueryEquals(L"one", L"b:one t:one"); + checkStopQueryEquals(L"one stop", L"b:one t:one"); + checkStopQueryEquals(L"one (stop)", L"b:one t:one"); + checkStopQueryEquals(L"one ((stop))", L"b:one t:one"); + checkStopQueryEquals(L"stop", L""); + checkStopQueryEquals(L"(stop)", L""); + checkStopQueryEquals(L"((stop))", L""); } -BOOST_AUTO_TEST_CASE(testSimple) +TEST_F(MultiFieldQueryParserTest, testSimple) { Collection fields = newCollection(L"b", L"t"); MultiFieldQueryParserPtr mfqp = newLucene(LuceneVersion::LUCENE_CURRENT, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); QueryPtr q = mfqp->parse(L"one"); - BOOST_CHECK_EQUAL(L"b:one t:one", q->toString()); + EXPECT_EQ(L"b:one t:one", q->toString()); q = mfqp->parse(L"one two"); - BOOST_CHECK_EQUAL(L"(b:one t:one) (b:two t:two)", q->toString()); + EXPECT_EQ(L"(b:one t:one) (b:two t:two)", q->toString()); q = mfqp->parse(L"+one +two"); - BOOST_CHECK_EQUAL(L"+(b:one t:one) +(b:two t:two)", q->toString()); + EXPECT_EQ(L"+(b:one t:one) +(b:two t:two)", q->toString()); q = mfqp->parse(L"+one -two -three"); - BOOST_CHECK_EQUAL(L"+(b:one t:one) -(b:two t:two) -(b:three t:three)", q->toString()); + EXPECT_EQ(L"+(b:one t:one) -(b:two t:two) -(b:three t:three)", q->toString()); q = mfqp->parse(L"one^2 two"); - BOOST_CHECK_EQUAL(L"((b:one t:one)^2.0) (b:two t:two)", q->toString()); + EXPECT_EQ(L"((b:one t:one)^2.0) (b:two t:two)", q->toString()); q = mfqp->parse(L"one~ two"); - BOOST_CHECK_EQUAL(L"(b:one~0.5 t:one~0.5) (b:two t:two)", q->toString()); + EXPECT_EQ(L"(b:one~0.5 t:one~0.5) (b:two t:two)", q->toString()); q = mfqp->parse(L"one~0.8 two^2"); - BOOST_CHECK_EQUAL(L"(b:one~0.8 t:one~0.8) ((b:two t:two)^2.0)", q->toString()); + EXPECT_EQ(L"(b:one~0.8 t:one~0.8) ((b:two t:two)^2.0)", q->toString()); q = mfqp->parse(L"one* two*"); - BOOST_CHECK_EQUAL(L"(b:one* t:one*) (b:two* t:two*)", q->toString()); + EXPECT_EQ(L"(b:one* t:one*) (b:two* t:two*)", q->toString()); q = mfqp->parse(L"[a TO c] two"); - BOOST_CHECK_EQUAL(L"(b:[a TO c] t:[a TO c]) (b:two t:two)", q->toString()); + EXPECT_EQ(L"(b:[a TO c] t:[a TO c]) (b:two t:two)", q->toString()); q = mfqp->parse(L"w?ldcard"); - BOOST_CHECK_EQUAL(L"b:w?ldcard t:w?ldcard", q->toString()); + EXPECT_EQ(L"b:w?ldcard t:w?ldcard", q->toString()); q = mfqp->parse(L"\"foo bar\""); - BOOST_CHECK_EQUAL(L"b:\"foo bar\" t:\"foo bar\"", q->toString()); + EXPECT_EQ(L"b:\"foo bar\" t:\"foo bar\"", q->toString()); q = mfqp->parse(L"\"aa bb cc\" \"dd ee\""); - BOOST_CHECK_EQUAL(L"(b:\"aa bb cc\" t:\"aa bb cc\") (b:\"dd ee\" t:\"dd ee\")", q->toString()); + EXPECT_EQ(L"(b:\"aa bb cc\" t:\"aa bb cc\") (b:\"dd ee\" t:\"dd ee\")", q->toString()); q = mfqp->parse(L"\"foo bar\"~4"); - BOOST_CHECK_EQUAL(L"b:\"foo bar\"~4 t:\"foo bar\"~4", q->toString()); + EXPECT_EQ(L"b:\"foo bar\"~4 t:\"foo bar\"~4", q->toString()); - q = mfqp->parse(L"b:\"foo bar\"~4"); - BOOST_CHECK_EQUAL(L"b:\"foo bar\"~4", q->toString()); + q = mfqp->parse(L"b:\"foo bar\"~4"); + EXPECT_EQ(L"b:\"foo bar\"~4", q->toString()); // make sure that terms which have a field are not touched q = mfqp->parse(L"one f:two"); - BOOST_CHECK_EQUAL(L"(b:one t:one) f:two", q->toString()); + EXPECT_EQ(L"(b:one t:one) f:two", q->toString()); // AND mode mfqp->setDefaultOperator(QueryParser::AND_OPERATOR); q = mfqp->parse(L"one two"); - BOOST_CHECK_EQUAL(L"+(b:one t:one) +(b:two t:two)", q->toString()); + EXPECT_EQ(L"+(b:one t:one) +(b:two t:two)", q->toString()); q = mfqp->parse(L"\"aa bb cc\" \"dd ee\""); - BOOST_CHECK_EQUAL(L"+(b:\"aa bb cc\" t:\"aa bb cc\") +(b:\"dd ee\" t:\"dd ee\")", q->toString()); + EXPECT_EQ(L"+(b:\"aa bb cc\" t:\"aa bb cc\") +(b:\"dd ee\" t:\"dd ee\")", q->toString()); } -BOOST_AUTO_TEST_CASE(testBoostsSimple) +TEST_F(MultiFieldQueryParserTest, testBoostsSimple) { MapStringDouble boosts = MapStringDouble::newInstance(); boosts.put(L"b", 5.0); @@ -243,121 +243,149 @@ BOOST_AUTO_TEST_CASE(testBoostsSimple) // Check for simple QueryPtr q = mfqp->parse(L"one"); - BOOST_CHECK_EQUAL(L"b:one^5.0 t:one^10.0", q->toString()); + EXPECT_EQ(L"b:one^5.0 t:one^10.0", q->toString()); // Check for AND q = mfqp->parse(L"one AND two"); - BOOST_CHECK_EQUAL(L"+(b:one^5.0 t:one^10.0) +(b:two^5.0 t:two^10.0)", q->toString()); + EXPECT_EQ(L"+(b:one^5.0 t:one^10.0) +(b:two^5.0 t:two^10.0)", q->toString()); // Check for OR q = mfqp->parse(L"one OR two"); - BOOST_CHECK_EQUAL(L"(b:one^5.0 t:one^10.0) (b:two^5.0 t:two^10.0)", q->toString()); + EXPECT_EQ(L"(b:one^5.0 t:one^10.0) (b:two^5.0 t:two^10.0)", q->toString()); // Check for AND and a field q = mfqp->parse(L"one AND two AND foo:test"); - BOOST_CHECK_EQUAL(L"+(b:one^5.0 t:one^10.0) +(b:two^5.0 t:two^10.0) +foo:test", q->toString()); + EXPECT_EQ(L"+(b:one^5.0 t:one^10.0) +(b:two^5.0 t:two^10.0) +foo:test", q->toString()); q = mfqp->parse(L"one^3 AND two^4"); - BOOST_CHECK_EQUAL(L"+((b:one^5.0 t:one^10.0)^3.0) +((b:two^5.0 t:two^10.0)^4.0)", q->toString()); + EXPECT_EQ(L"+((b:one^5.0 t:one^10.0)^3.0) +((b:two^5.0 t:two^10.0)^4.0)", q->toString()); } -BOOST_AUTO_TEST_CASE(testStaticMethod1) +TEST_F(MultiFieldQueryParserTest, testStaticMethod1) { Collection fields = newCollection(L"b", L"t"); Collection queries = newCollection(L"one", L"two"); QueryPtr q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"b:one t:two", q->toString()); + EXPECT_EQ(L"b:one t:two", q->toString()); Collection queries2 = newCollection(L"+one", L"+two"); q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries2, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"(+b:one) (+t:two)", q->toString()); + EXPECT_EQ(L"(+b:one) (+t:two)", q->toString()); Collection queries3 = newCollection(L"one", L"+two"); q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries3, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"b:one (+t:two)", q->toString()); + EXPECT_EQ(L"b:one (+t:two)", q->toString()); Collection queries4 = newCollection(L"one +more", L"+two"); q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries4, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"(b:one +b:more) (+t:two)", q->toString()); + EXPECT_EQ(L"(b:one +b:more) (+t:two)", q->toString()); Collection queries5 = newCollection(L"blah"); - + // expected exception, array length differs - BOOST_CHECK_EXCEPTION(q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries5, fields, newLucene(LuceneVersion::LUCENE_CURRENT)), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries5, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } // check also with stop words for this static form (qtxts[], fields[]). - TestAnalyzerPtr stopA = newLucene(); + MultiFieldQueryParserTestAnalyzerPtr stopA = newLucene(); Collection queries6 = newCollection(L"((+stop))", L"+((stop))"); q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries6, fields, stopA); - BOOST_CHECK_EQUAL(L"", q->toString()); + EXPECT_EQ(L"", q->toString()); Collection queries7 = newCollection(L"one ((+stop)) +more", L"+((stop)) +two"); q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries7, fields, stopA); - BOOST_CHECK_EQUAL(L"(b:one +b:more) (+t:two)", q->toString()); + EXPECT_EQ(L"(b:one +b:more) (+t:two)", q->toString()); } -BOOST_AUTO_TEST_CASE(testStaticMethod2) +TEST_F(MultiFieldQueryParserTest, testStaticMethod2) { Collection fields = newCollection(L"b", L"t"); Collection flags = newCollection(BooleanClause::MUST, BooleanClause::MUST_NOT); QueryPtr q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, L"one", fields, flags, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"+b:one -t:one", q->toString()); + EXPECT_EQ(L"+b:one -t:one", q->toString()); q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, L"one two", fields, flags, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"+(b:one b:two) -(t:one t:two)", q->toString()); + EXPECT_EQ(L"+(b:one b:two) -(t:one t:two)", q->toString()); Collection flags2 = newCollection(BooleanClause::MUST); - + // expected exception, array length differs - BOOST_CHECK_EXCEPTION(q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, L"blah", fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, L"blah", fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } -BOOST_AUTO_TEST_CASE(testStaticMethod3) +TEST_F(MultiFieldQueryParserTest, testStaticMethod3) { Collection queries = newCollection(L"one", L"two", L"three"); Collection fields = newCollection(L"f1", L"f2", L"f3"); Collection flags = newCollection(BooleanClause::MUST, BooleanClause::MUST_NOT, BooleanClause::SHOULD); QueryPtr q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"+f1:one -f2:two f3:three", q->toString()); + EXPECT_EQ(L"+f1:one -f2:two f3:three", q->toString()); Collection flags2 = newCollection(BooleanClause::MUST); - + // expected exception, array length differs - BOOST_CHECK_EXCEPTION(q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } -BOOST_AUTO_TEST_CASE(testStaticMethod3Old) +TEST_F(MultiFieldQueryParserTest, testStaticMethod3Old) { Collection queries = newCollection(L"one", L"two"); Collection fields = newCollection(L"b", L"t"); Collection flags = newCollection(BooleanClause::MUST, BooleanClause::MUST_NOT); QueryPtr q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags, newLucene(LuceneVersion::LUCENE_CURRENT)); - BOOST_CHECK_EQUAL(L"+b:one -t:two", q->toString()); + EXPECT_EQ(L"+b:one -t:two", q->toString()); Collection flags2 = newCollection(BooleanClause::MUST); - + // expected exception, array length differs - BOOST_CHECK_EXCEPTION(q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } -BOOST_AUTO_TEST_CASE(testAnalyzerReturningNull) +TEST_F(MultiFieldQueryParserTest, testAnalyzerReturningNull) { Collection fields = newCollection(L"f1", L"f2", L"f3"); MultiFieldQueryParserPtr parser = newLucene(LuceneVersion::LUCENE_CURRENT, fields, newLucene()); QueryPtr q = parser->parse(L"bla AND blo"); - BOOST_CHECK_EQUAL(L"+(f2:bla f3:bla) +(f2:blo f3:blo)", q->toString()); - + EXPECT_EQ(L"+(f2:bla f3:bla) +(f2:blo f3:blo)", q->toString()); + // the following queries are not affected as their terms are not analyzed anyway q = parser->parse(L"bla*"); - BOOST_CHECK_EQUAL(L"f1:bla* f2:bla* f3:bla*", q->toString()); + EXPECT_EQ(L"f1:bla* f2:bla* f3:bla*", q->toString()); q = parser->parse(L"bla~"); - BOOST_CHECK_EQUAL(L"f1:bla~0.5 f2:bla~0.5 f3:bla~0.5", q->toString()); + EXPECT_EQ(L"f1:bla~0.5 f2:bla~0.5 f3:bla~0.5", q->toString()); q = parser->parse(L"[a TO c]"); - BOOST_CHECK_EQUAL(L"f1:[a TO c] f2:[a TO c] f3:[a TO c]", q->toString()); + EXPECT_EQ(L"f1:[a TO c] f2:[a TO c] f3:[a TO c]", q->toString()); } -BOOST_AUTO_TEST_CASE(testStopWordSearching) +TEST_F(MultiFieldQueryParserTest, testStopWordSearching) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); DirectoryPtr ramDir = newLucene(); @@ -372,8 +400,6 @@ BOOST_AUTO_TEST_CASE(testStopWordSearching) QueryPtr q = mfqp->parse(L"the footest"); IndexSearcherPtr is = newLucene(ramDir, true); Collection hits = is->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); is->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/queryparser/QueryParserTest.cpp b/src/test/queryparser/QueryParserTest.cpp index 5679122c..5d0c704b 100644 --- a/src/test/queryparser/QueryParserTest.cpp +++ b/src/test/queryparser/QueryParserTest.cpp @@ -43,15 +43,15 @@ using namespace Lucene; using namespace boost::posix_time; using namespace boost::gregorian; -DECLARE_SHARED_PTR(TestAnalyzer) -DECLARE_SHARED_PTR(TestFilter) +DECLARE_SHARED_PTR(QueryParserTestAnalyzer) +DECLARE_SHARED_PTR(QueryParserTestFilter) DECLARE_SHARED_PTR(TestParser) /// Filter which discards the token 'stop' and which expands the token 'phrase' into 'phrase1 phrase2' -class TestFilter : public TokenFilter +class QueryParserTestFilter : public TokenFilter { public: - TestFilter(TokenStreamPtr in) : TokenFilter(in) + QueryParserTestFilter(TokenStreamPtr in) : TokenFilter(in) { termAtt = addAttribute(); offsetAtt = addAttribute(); @@ -59,12 +59,12 @@ class TestFilter : public TokenFilter savedStart = 0; savedEnd = 0; } - - virtual ~TestFilter() + + virtual ~QueryParserTestFilter() { } - - LUCENE_CLASS(TestFilter); + + LUCENE_CLASS(QueryParserTestFilter); public: bool inPhrase; @@ -105,20 +105,20 @@ class TestFilter : public TokenFilter } }; -class TestAnalyzer : public Analyzer +class QueryParserTestAnalyzer : public Analyzer { public: - virtual ~TestAnalyzer() + virtual ~QueryParserTestAnalyzer() { } - - LUCENE_CLASS(TestAnalyzer); + + LUCENE_CLASS(QueryParserTestAnalyzer); public: // Filters LowerCaseTokenizer with StopFilter. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { - return newLucene(newLucene(reader)); + return newLucene(newLucene(reader)); } }; @@ -128,11 +128,11 @@ class TestParser : public QueryParser TestParser(const String& f, AnalyzerPtr a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { } - + virtual ~TestParser() { } - + LUCENE_CLASS(TestParser); public: @@ -141,7 +141,7 @@ class TestParser : public QueryParser boost::throw_exception(QueryParserError(L"Fuzzy queries not allowed")); return QueryPtr(); } - + virtual QueryPtr getWildcardQuery(const String& field, const String& termStr) { boost::throw_exception(QueryParserError(L"Wildcard queries not allowed")); @@ -149,23 +149,23 @@ class TestParser : public QueryParser } }; -class QueryParserTestFixture : public LuceneTestFixture +class QueryParserTest : public LuceneTestFixture { public: - QueryParserTestFixture() + QueryParserTest() { originalMaxClauses = BooleanQuery::getMaxClauseCount(); DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); } - - virtual ~QueryParserTestFixture() + + virtual ~QueryParserTest() { BooleanQuery::setMaxClauseCount(originalMaxClauses); } protected: int32_t originalMaxClauses; - + QueryParserPtr getParser(AnalyzerPtr a) { if (!a) @@ -174,33 +174,40 @@ class QueryParserTestFixture : public LuceneTestFixture qp->setDefaultOperator(QueryParser::OR_OPERATOR); return qp; } - + QueryPtr getQuery(const String& query, AnalyzerPtr a) { return getParser(a)->parse(query); } - + void checkQueryEquals(const String& query, AnalyzerPtr a, const String& result) { QueryPtr q = getQuery(query, a); String s = q->toString(L"field"); if (s != result) - BOOST_FAIL("Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""); + FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - + void checkQueryEquals(QueryParserPtr qp, const String& field, const String& query, const String& result) { QueryPtr q = qp->parse(query); String s = q->toString(field); if (s != result) - BOOST_FAIL("Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""); + FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - + void checkParseException(const String& queryString) { - BOOST_CHECK_EXCEPTION(getQuery(queryString, AnalyzerPtr()), QueryParserError, check_exception(LuceneException::QueryParser)); + try + { + getQuery(queryString, AnalyzerPtr()); + } + catch (QueryParserError& e) + { + EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); + } } - + void checkWildcardQueryEquals(const String& query, bool lowercase, const String& result, bool allowLeadingWildcard = false) { QueryParserPtr qp = getParser(AnalyzerPtr()); @@ -209,18 +216,18 @@ class QueryParserTestFixture : public LuceneTestFixture QueryPtr q = qp->parse(query); String s = q->toString(L"field"); if (s != result) - BOOST_FAIL("WildcardQuery \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""); + FAIL() << "WildcardQuery \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - + void checkWildcardQueryEquals(const String& query, const String& result) { QueryParserPtr qp = getParser(AnalyzerPtr()); QueryPtr q = qp->parse(query); String s = q->toString(L"field"); if (s != result) - BOOST_FAIL("WildcardQuery \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""); + FAIL() << "WildcardQuery \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - + void checkEscapedQueryEquals(const String& query, AnalyzerPtr a, const String& result) { class TestableQueryParser : public QueryParser @@ -228,12 +235,12 @@ class QueryParserTestFixture : public LuceneTestFixture public: using QueryParser::escape; }; - + String escapedQuery = TestableQueryParser::escape(query); if (escapedQuery != result) - BOOST_FAIL("Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(escapedQuery) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""); + FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(escapedQuery) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - + QueryPtr getQueryDOA(const String& query, AnalyzerPtr a) { if (!a) @@ -242,15 +249,15 @@ class QueryParserTestFixture : public LuceneTestFixture qp->setDefaultOperator(QueryParser::AND_OPERATOR); return qp->parse(query); } - + void checkQueryEqualsDOA(const String& query, AnalyzerPtr a, const String& result) { QueryPtr q = getQueryDOA(query, a); String s = q->toString(L"field"); if (s != result) - BOOST_FAIL("Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""); + FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - + void addDateDoc(const String& content, boost::posix_time::ptime date, IndexWriterPtr iw) { DocumentPtr d = newLucene(); @@ -258,27 +265,25 @@ class QueryParserTestFixture : public LuceneTestFixture d->add(newLucene(L"date", DateField::dateToString(date), Field::STORE_YES, Field::INDEX_ANALYZED)); iw->addDocument(d); } - + void checkHits(int32_t expected, const String& query, IndexSearcherPtr is) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"date", newLucene()); qp->setLocale(std::locale()); QueryPtr q = qp->parse(query); Collection hits = is->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(expected, hits.size()); + EXPECT_EQ(expected, hits.size()); } }; -BOOST_FIXTURE_TEST_SUITE(QueryParserTest, QueryParserTestFixture) - -BOOST_AUTO_TEST_CASE(testSimple) +TEST_F(QueryParserTest, testSimple) { checkQueryEquals(L"term term term", AnalyzerPtr(), L"term term term"); - + const uint8_t term[] = {0x74, 0xc3, 0xbc, 0x72, 0x6d, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x20, 0x74, 0x65, 0x72, 0x6d}; String termText = UTF8_TO_STRING(term); checkQueryEquals(termText, newLucene(), termText); - + const uint8_t umlaut[] = {0xc3, 0xbc, 0x6d, 0x6c, 0x61, 0x75, 0x74}; String umlautText = UTF8_TO_STRING(umlaut); checkQueryEquals(umlautText, newLucene(), umlautText); @@ -305,9 +310,9 @@ BOOST_AUTO_TEST_CASE(testSimple) checkQueryEquals(L"foo:term AND field:anotherTerm", AnalyzerPtr(), L"+foo:term +anotherterm"); checkQueryEquals(L"term AND \"phrase phrase\"", AnalyzerPtr(), L"+term +\"phrase phrase\""); checkQueryEquals(L"\"hello there\"", AnalyzerPtr(), L"\"hello there\""); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"a AND b", AnalyzerPtr()))); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"hello", AnalyzerPtr()))); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"\"hello there\"", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"a AND b", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"hello", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"\"hello there\"", AnalyzerPtr()))); checkQueryEquals(L"germ term^2.0", AnalyzerPtr(), L"germ term^2.0"); checkQueryEquals(L"(term)^2.0", AnalyzerPtr(), L"term^2.0"); @@ -323,16 +328,16 @@ BOOST_AUTO_TEST_CASE(testSimple) checkQueryEquals(L"+title:(dog OR cat) -author:\"bob dole\"", AnalyzerPtr(), L"+(title:dog title:cat) -author:\"bob dole\""); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene(LuceneVersion::LUCENE_CURRENT)); - + // make sure OR is the default - BOOST_CHECK_EQUAL(QueryParser::OR_OPERATOR, qp->getDefaultOperator()); + EXPECT_EQ(QueryParser::OR_OPERATOR, qp->getDefaultOperator()); qp->setDefaultOperator(QueryParser::AND_OPERATOR); - BOOST_CHECK_EQUAL(QueryParser::AND_OPERATOR, qp->getDefaultOperator()); + EXPECT_EQ(QueryParser::AND_OPERATOR, qp->getDefaultOperator()); qp->setDefaultOperator(QueryParser::OR_OPERATOR); - BOOST_CHECK_EQUAL(QueryParser::OR_OPERATOR, qp->getDefaultOperator()); + EXPECT_EQ(QueryParser::OR_OPERATOR, qp->getDefaultOperator()); } -BOOST_AUTO_TEST_CASE(testPunct) +TEST_F(QueryParserTest, testPunct) { AnalyzerPtr a = newLucene(); checkQueryEquals(L"a&b", a, L"a&b"); @@ -340,7 +345,7 @@ BOOST_AUTO_TEST_CASE(testPunct) checkQueryEquals(L".NET", a, L".NET"); } -BOOST_AUTO_TEST_CASE(testSlop) +TEST_F(QueryParserTest, testSlop) { checkQueryEquals(L"\"term germ\"~2", AnalyzerPtr(), L"\"term germ\"~2"); checkQueryEquals(L"\"term germ\"~2 flork", AnalyzerPtr(), L"\"term germ\"~2 flork"); @@ -349,7 +354,7 @@ BOOST_AUTO_TEST_CASE(testSlop) checkQueryEquals(L"\"term germ\"~2^2", AnalyzerPtr(), L"\"term germ\"~2^2.0"); } -BOOST_AUTO_TEST_CASE(testNumber) +TEST_F(QueryParserTest, testNumber) { // The numbers go away because SimpleAnalzyer ignores them checkQueryEquals(L"3", AnalyzerPtr(), L""); @@ -362,7 +367,7 @@ BOOST_AUTO_TEST_CASE(testNumber) checkQueryEquals(L"term term1 term2", a, L"term term1 term2"); } -BOOST_AUTO_TEST_CASE(testWildcard) +TEST_F(QueryParserTest, testWildcard) { checkQueryEquals(L"term*", AnalyzerPtr(), L"term*"); checkQueryEquals(L"term*^2", AnalyzerPtr(), L"term*^2.0"); @@ -373,20 +378,20 @@ BOOST_AUTO_TEST_CASE(testWildcard) checkQueryEquals(L"term*germ", AnalyzerPtr(), L"term*germ"); checkQueryEquals(L"term*germ^3", AnalyzerPtr(), L"term*germ^3.0"); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"term*", AnalyzerPtr()))); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"term*^2", AnalyzerPtr()))); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"term~", AnalyzerPtr()))); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"term~0.7", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term*", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term*^2", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term~", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term~0.7", AnalyzerPtr()))); FuzzyQueryPtr fq = boost::dynamic_pointer_cast(getQuery(L"term~0.7", AnalyzerPtr())); - BOOST_CHECK_CLOSE_FRACTION(0.7, fq->getMinSimilarity(), 0.1); - BOOST_CHECK_EQUAL(FuzzyQuery::defaultPrefixLength, fq->getPrefixLength()); + EXPECT_NEAR(0.7, fq->getMinSimilarity(), 0.1); + EXPECT_EQ(FuzzyQuery::defaultPrefixLength, fq->getPrefixLength()); fq = boost::dynamic_pointer_cast(getQuery(L"term~", AnalyzerPtr())); - BOOST_CHECK_CLOSE_FRACTION(0.5, fq->getMinSimilarity(), 0.1); - BOOST_CHECK_EQUAL(FuzzyQuery::defaultPrefixLength, fq->getPrefixLength()); + EXPECT_NEAR(0.5, fq->getMinSimilarity(), 0.1); + EXPECT_EQ(FuzzyQuery::defaultPrefixLength, fq->getPrefixLength()); checkParseException(L"term~1.1"); // value > 1, throws exception - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"term*germ", AnalyzerPtr()))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term*germ", AnalyzerPtr()))); // Tests to see that wild card terms are (or are not) properly lower-cased with propery parser configuration @@ -423,27 +428,41 @@ BOOST_AUTO_TEST_CASE(testWildcard) checkWildcardQueryEquals(L"[A TO C]", true, L"[a TO c]"); checkWildcardQueryEquals(L"[A TO C]", false, L"[A TO C]"); // Test suffix queries: first disallow - BOOST_CHECK_EXCEPTION(checkWildcardQueryEquals(L"*Term", true, L"*term"), QueryParserError, check_exception(LuceneException::QueryParser)); - BOOST_CHECK_EXCEPTION(checkWildcardQueryEquals(L"?Term", true, L"?term"), QueryParserError, check_exception(LuceneException::QueryParser)); + try + { + checkWildcardQueryEquals(L"*Term", true, L"*term"); + } + catch (QueryParserError& e) + { + EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); + } + try + { + checkWildcardQueryEquals(L"?Term", true, L"?term"); + } + catch (QueryParserError& e) + { + EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); + } // Test suffix queries: then allow checkWildcardQueryEquals(L"*Term", true, L"*term", true); checkWildcardQueryEquals(L"?Term", true, L"?term", true); } -BOOST_AUTO_TEST_CASE(testLeadingWildcardType) +TEST_F(QueryParserTest, testLeadingWildcardType) { QueryParserPtr qp = getParser(AnalyzerPtr()); qp->setAllowLeadingWildcard(true); - BOOST_CHECK(MiscUtils::typeOf(qp->parse(L"t*erm*"))); - BOOST_CHECK(MiscUtils::typeOf(qp->parse(L"?term*"))); - BOOST_CHECK(MiscUtils::typeOf(qp->parse(L"*term*"))); + EXPECT_TRUE(MiscUtils::typeOf(qp->parse(L"t*erm*"))); + EXPECT_TRUE(MiscUtils::typeOf(qp->parse(L"?term*"))); + EXPECT_TRUE(MiscUtils::typeOf(qp->parse(L"*term*"))); } -BOOST_AUTO_TEST_CASE(testQPA) +TEST_F(QueryParserTest, testQPA) { - AnalyzerPtr qpAnalyzer = newLucene(); - + AnalyzerPtr qpAnalyzer = newLucene(); + checkQueryEquals(L"term term^3.0 term", qpAnalyzer, L"term term^3.0 term"); checkQueryEquals(L"term stop^3.0 term", qpAnalyzer, L"term term"); @@ -466,18 +485,18 @@ BOOST_AUTO_TEST_CASE(testQPA) checkQueryEquals(L"((stop)^3)", qpAnalyzer, L""); checkQueryEquals(L"(stop)", qpAnalyzer, L""); checkQueryEquals(L"((stop))", qpAnalyzer, L""); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"term term term", qpAnalyzer))); - BOOST_CHECK(MiscUtils::typeOf(getQuery(L"term +stop", qpAnalyzer))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term term term", qpAnalyzer))); + EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term +stop", qpAnalyzer))); } -BOOST_AUTO_TEST_CASE(testRange) +TEST_F(QueryParserTest, testRange) { checkQueryEquals(L"[ a TO z]", AnalyzerPtr(), L"[a TO z]"); - BOOST_CHECK_EQUAL(MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(), boost::dynamic_pointer_cast(getQuery(L"[ a TO z]", AnalyzerPtr()))->getRewriteMethod()); + EXPECT_EQ(MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(), boost::dynamic_pointer_cast(getQuery(L"[ a TO z]", AnalyzerPtr()))->getRewriteMethod()); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); qp->setMultiTermRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); - BOOST_CHECK_EQUAL(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE(), boost::dynamic_pointer_cast(qp->parse(L"[ a TO z]"))->getRewriteMethod()); + EXPECT_EQ(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE(), boost::dynamic_pointer_cast(qp->parse(L"[ a TO z]"))->getRewriteMethod()); checkQueryEquals(L"[ a TO z ]", AnalyzerPtr(), L"[a TO z]"); checkQueryEquals(L"{ a TO z}", AnalyzerPtr(), L"{a TO z}"); @@ -489,14 +508,14 @@ BOOST_AUTO_TEST_CASE(testRange) checkQueryEquals(L"gack ( bar blar { a TO z}) ", AnalyzerPtr(), L"gack (bar blar {a TO z})"); } -BOOST_AUTO_TEST_CASE(testLegacyDateRange) +TEST_F(QueryParserTest, testLegacyDateRange) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); checkQueryEquals(L"[01/02/02 TO 04/02/02]", AnalyzerPtr(), L"[0cx597uo0 TO 0cxayz9bz]"); checkQueryEquals(L"{01/02/02 04/02/02}", AnalyzerPtr(), L"{0cx597uo0 TO 0cx9jjeo0}"); } -BOOST_AUTO_TEST_CASE(testDateRange) +TEST_F(QueryParserTest, testDateRange) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); @@ -511,11 +530,11 @@ BOOST_AUTO_TEST_CASE(testDateRange) // DateField should still be used for defaultField checkQueryEquals(qp, L"default", L"default:[01/02/02 TO 04/02/02]", L"[0cx597uo0 TO 0cxayz9bz]"); checkQueryEquals(qp, L"default", L"default:{01/02/02 TO 04/02/02}", L"{0cx597uo0 TO 0cx9jjeo0}"); - + // set default date resolution to MILLISECOND qp->setDateResolution(DateTools::RESOLUTION_MILLISECOND); - // set second field specific date resolution + // set second field specific date resolution qp->setDateResolution(L"hour", DateTools::RESOLUTION_HOUR); // for this field no field specific date resolution has been set, so verify if the default resolution is used @@ -525,12 +544,12 @@ BOOST_AUTO_TEST_CASE(testDateRange) // verify if field specific date resolutions are used for these two fields checkQueryEquals(qp, L"month", L"month:[01/02/02 TO 04/02/02]", L"[200202 TO 200202]"); checkQueryEquals(qp, L"month", L"month:{01/02/02 TO 04/02/02}", L"{200202 TO 200202}"); - + checkQueryEquals(qp, L"hour", L"hour:[01/02/02 TO 04/02/02]", L"[2002020100 TO 2002020423]"); checkQueryEquals(qp, L"hour", L"hour:{01/02/02 TO 04/02/02}", L"{2002020100 TO 2002020400}"); } -BOOST_AUTO_TEST_CASE(testEscaped) +TEST_F(QueryParserTest, testEscaped) { AnalyzerPtr a = newLucene(); @@ -589,7 +608,7 @@ BOOST_AUTO_TEST_CASE(testEscaped) checkParseException(L"XY\\u005"); // test incomplete escaped unicode sequence checkQueryEquals(L"(item:\\\\ item:ABCD\\\\)", a, L"item:\\ item:ABCD\\"); - checkParseException(L"(item:\\\\ item:ABCD\\\\))"); // unmatched closing parenthesis + checkParseException(L"(item:\\\\ item:ABCD\\\\))"); // unmatched closing parenthesis checkQueryEquals(L"\\*", a, L"*"); checkQueryEquals(L"\\\\", a, L"\\"); // escaped backslash @@ -598,7 +617,7 @@ BOOST_AUTO_TEST_CASE(testEscaped) checkQueryEquals(L"(\"a\\\\\") or (\"b\")", a, L"a\\ or b"); } -BOOST_AUTO_TEST_CASE(testQueryStringEscaping) +TEST_F(QueryParserTest, testQueryStringEscaping) { AnalyzerPtr a = newLucene(); @@ -637,7 +656,7 @@ BOOST_AUTO_TEST_CASE(testQueryStringEscaping) checkEscapedQueryEquals(L"&& abc &&", a, L"\\&\\& abc \\&\\&"); } -BOOST_AUTO_TEST_CASE(testTabNewlineCarriageReturn) +TEST_F(QueryParserTest, testTabNewlineCarriageReturn) { checkQueryEqualsDOA(L"+weltbank +worlbank", AnalyzerPtr(), L"+weltbank +worlbank"); @@ -659,7 +678,7 @@ BOOST_AUTO_TEST_CASE(testTabNewlineCarriageReturn) checkQueryEqualsDOA(L"weltbank \t +worlbank", AnalyzerPtr(), L"+weltbank +worlbank"); } -BOOST_AUTO_TEST_CASE(testSimpleDAO) +TEST_F(QueryParserTest, testSimpleDAO) { checkQueryEqualsDOA(L"term term term", AnalyzerPtr(), L"+term +term +term"); checkQueryEqualsDOA(L"term +term term", AnalyzerPtr(), L"+term +term +term"); @@ -668,33 +687,33 @@ BOOST_AUTO_TEST_CASE(testSimpleDAO) checkQueryEqualsDOA(L"-term term term", AnalyzerPtr(), L"-term +term +term"); } -BOOST_AUTO_TEST_CASE(testBoost) +TEST_F(QueryParserTest, testBoost) { HashSet stopWords = HashSet::newInstance(); stopWords.add(L"on"); StandardAnalyzerPtr oneStopAnalyzer = newLucene(LuceneVersion::LUCENE_CURRENT, stopWords); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", oneStopAnalyzer); QueryPtr q = qp->parse(L"on^1.0"); - BOOST_CHECK(q); + EXPECT_TRUE(q); q = qp->parse(L"\"hello\"^2.0"); - BOOST_CHECK(q); - BOOST_CHECK_CLOSE_FRACTION(q->getBoost(), 2.0, 0.5); + EXPECT_TRUE(q); + EXPECT_NEAR(q->getBoost(), 2.0, 0.5); q = qp->parse(L"hello^2.0"); - BOOST_CHECK(q); - BOOST_CHECK_CLOSE_FRACTION(q->getBoost(), 2.0, 0.5); + EXPECT_TRUE(q); + EXPECT_NEAR(q->getBoost(), 2.0, 0.5); q = qp->parse(L"\"on\"^1.0"); - BOOST_CHECK(q); + EXPECT_TRUE(q); QueryParserPtr qp2 = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene(LuceneVersion::LUCENE_CURRENT)); q = qp2->parse(L"the^3"); - + // "the" is a stop word so the result is an empty query - BOOST_CHECK(q); - BOOST_CHECK(q->toString().empty()); - BOOST_CHECK_CLOSE_FRACTION(1.0, q->getBoost(), 0.01); + EXPECT_TRUE(q); + EXPECT_TRUE(q->toString().empty()); + EXPECT_NEAR(1.0, q->getBoost(), 0.01); } -BOOST_AUTO_TEST_CASE(testException) +TEST_F(QueryParserTest, testException) { checkParseException(L"\"some phrase"); checkParseException(L"(foo bar"); @@ -704,34 +723,55 @@ BOOST_AUTO_TEST_CASE(testException) checkParseException(L"secret AND illegal) AND access:confidential"); } -BOOST_AUTO_TEST_CASE(testCustomQueryParserWildcard) +TEST_F(QueryParserTest, testCustomQueryParserWildcard) { - BOOST_CHECK_EXCEPTION(newLucene(L"contents", newLucene())->parse(L"a?t"), QueryParserError, check_exception(LuceneException::QueryParser)); + try + { + newLucene(L"contents", newLucene())->parse(L"a?t"); + } + catch (QueryParserError& e) + { + EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); + } } -BOOST_AUTO_TEST_CASE(testCustomQueryParserFuzzy) +TEST_F(QueryParserTest, testCustomQueryParserFuzzy) { - BOOST_CHECK_EXCEPTION(newLucene(L"contents", newLucene())->parse(L"xunit~"), QueryParserError, check_exception(LuceneException::QueryParser)); + try + { + newLucene(L"contents", newLucene())->parse(L"xunit~"); + } + catch (QueryParserError& e) + { + EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); + } } -BOOST_AUTO_TEST_CASE(testBooleanQuery) +TEST_F(QueryParserTest, testBooleanQuery) { BooleanQuery::setMaxClauseCount(2); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); - + // too many boolean clauses, so ParseException is expected - BOOST_CHECK_EXCEPTION(qp->parse(L"one two three"), QueryParserError, check_exception(LuceneException::QueryParser)); + try + { + qp->parse(L"one two three"); + } + catch (QueryParserError& e) + { + EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); + } } -BOOST_AUTO_TEST_CASE(testPrecedence) +TEST_F(QueryParserTest, testPrecedence) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); QueryPtr query1 = qp->parse(L"A AND B OR C AND D"); QueryPtr query2 = qp->parse(L"+A +B +C +D"); - BOOST_CHECK(query1->equals(query2)); + EXPECT_TRUE(query1->equals(query2)); } -BOOST_AUTO_TEST_CASE(testLocalDateFormat) +TEST_F(QueryParserTest, testLocalDateFormat) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); RAMDirectoryPtr ramDir = newLucene(); @@ -752,7 +792,7 @@ BOOST_AUTO_TEST_CASE(testLocalDateFormat) namespace TestStarParsing { DECLARE_SHARED_PTR(StarParser) - + class StarParser : public QueryParser { public: @@ -760,13 +800,13 @@ namespace TestStarParsing { type = Collection::newInstance(1); } - + virtual ~StarParser() { } - + LUCENE_CLASS(StarParser); - + public: Collection type; @@ -777,14 +817,14 @@ namespace TestStarParsing type[0] = 1; return newLucene(newLucene(field, termStr)); } - + virtual QueryPtr getPrefixQuery(const String& field, const String& termStr) { // override error checking of superclass type[0] = 2; return newLucene(newLucene(field, termStr)); } - + virtual QueryPtr getFieldQuery(const String& field, const String& queryText) { type[0] = 3; @@ -793,61 +833,61 @@ namespace TestStarParsing }; } -BOOST_AUTO_TEST_CASE(testStarParsing) +TEST_F(QueryParserTest, testStarParsing) { TestStarParsing::StarParserPtr qp = newLucene(L"field", newLucene()); TermQueryPtr tq = boost::dynamic_pointer_cast(qp->parse(L"foo:zoo*")); - BOOST_CHECK_EQUAL(L"zoo", tq->getTerm()->text()); - BOOST_CHECK_EQUAL(2, qp->type[0]); + EXPECT_EQ(L"zoo", tq->getTerm()->text()); + EXPECT_EQ(2, qp->type[0]); tq = boost::dynamic_pointer_cast(qp->parse(L"foo:zoo*^2")); - BOOST_CHECK_EQUAL(L"zoo", tq->getTerm()->text()); - BOOST_CHECK_EQUAL(2, qp->type[0]); - BOOST_CHECK_EQUAL(tq->getBoost(), 2); + EXPECT_EQ(L"zoo", tq->getTerm()->text()); + EXPECT_EQ(2, qp->type[0]); + EXPECT_EQ(tq->getBoost(), 2); tq = boost::dynamic_pointer_cast(qp->parse(L"foo:*")); - BOOST_CHECK_EQUAL(L"*", tq->getTerm()->text()); - BOOST_CHECK_EQUAL(1, qp->type[0]); // could be a valid prefix query in the future too + EXPECT_EQ(L"*", tq->getTerm()->text()); + EXPECT_EQ(1, qp->type[0]); // could be a valid prefix query in the future too tq = boost::dynamic_pointer_cast(qp->parse(L"foo:*^2")); - BOOST_CHECK_EQUAL(L"*", tq->getTerm()->text()); - BOOST_CHECK_EQUAL(1, qp->type[0]); - BOOST_CHECK_EQUAL(tq->getBoost(), 2); + EXPECT_EQ(L"*", tq->getTerm()->text()); + EXPECT_EQ(1, qp->type[0]); + EXPECT_EQ(tq->getBoost(), 2); tq = boost::dynamic_pointer_cast(qp->parse(L"*:foo")); - BOOST_CHECK_EQUAL(L"*", tq->getTerm()->field()); - BOOST_CHECK_EQUAL(L"foo", tq->getTerm()->text()); - BOOST_CHECK_EQUAL(3, qp->type[0]); + EXPECT_EQ(L"*", tq->getTerm()->field()); + EXPECT_EQ(L"foo", tq->getTerm()->text()); + EXPECT_EQ(3, qp->type[0]); tq = boost::dynamic_pointer_cast(qp->parse(L"*:*")); - BOOST_CHECK_EQUAL(L"*", tq->getTerm()->field()); - BOOST_CHECK_EQUAL(L"*", tq->getTerm()->text()); - BOOST_CHECK_EQUAL(1, qp->type[0]); // could be handled as a prefix query in the future + EXPECT_EQ(L"*", tq->getTerm()->field()); + EXPECT_EQ(L"*", tq->getTerm()->text()); + EXPECT_EQ(1, qp->type[0]); // could be handled as a prefix query in the future tq = boost::dynamic_pointer_cast(qp->parse(L"(*:*)")); - BOOST_CHECK_EQUAL(L"*", tq->getTerm()->field()); - BOOST_CHECK_EQUAL(L"*", tq->getTerm()->text()); - BOOST_CHECK_EQUAL(1, qp->type[0]); + EXPECT_EQ(L"*", tq->getTerm()->field()); + EXPECT_EQ(L"*", tq->getTerm()->text()); + EXPECT_EQ(1, qp->type[0]); } -BOOST_AUTO_TEST_CASE(testStopwords) +TEST_F(QueryParserTest, testStopwords) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"a", newLucene(LuceneVersion::LUCENE_CURRENT, StopFilter::makeStopSet(newCollection(L"the", L"foo")))); QueryPtr result = qp->parse(L"a:the OR a:foo"); - BOOST_CHECK(result); - BOOST_CHECK(MiscUtils::typeOf(result)); - BOOST_CHECK(boost::dynamic_pointer_cast(result)->getClauses().empty()); + EXPECT_TRUE(result); + EXPECT_TRUE(MiscUtils::typeOf(result)); + EXPECT_TRUE(boost::dynamic_pointer_cast(result)->getClauses().empty()); result = qp->parse(L"a:woo OR a:the"); - BOOST_CHECK(result); - BOOST_CHECK(MiscUtils::typeOf(result)); + EXPECT_TRUE(result); + EXPECT_TRUE(MiscUtils::typeOf(result)); result = qp->parse(L"(fieldX:xxxxx OR fieldy:xxxxxxxx)^2 AND (fieldx:the OR fieldy:foo)"); - BOOST_CHECK(result); - BOOST_CHECK(MiscUtils::typeOf(result)); - BOOST_CHECK_EQUAL(boost::dynamic_pointer_cast(result)->getClauses().size(), 2); + EXPECT_TRUE(result); + EXPECT_TRUE(MiscUtils::typeOf(result)); + EXPECT_EQ(boost::dynamic_pointer_cast(result)->getClauses().size(), 2); } -BOOST_AUTO_TEST_CASE(testPositionIncrement) +TEST_F(QueryParserTest, testPositionIncrement) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"a", newLucene(LuceneVersion::LUCENE_CURRENT, StopFilter::makeStopSet(newCollection(L"the", L"in", L"are", L"this")))); qp->setEnablePositionIncrements(true); @@ -858,20 +898,20 @@ BOOST_AUTO_TEST_CASE(testPositionIncrement) Collection t = pq->getTerms(); Collection pos = pq->getPositions(); for (int32_t i = 0; i < t.size(); ++i) - BOOST_CHECK_EQUAL(expectedPositions[i], pos[i]); + EXPECT_EQ(expectedPositions[i], pos[i]); } -BOOST_AUTO_TEST_CASE(testMatchAllDocs) +TEST_F(QueryParserTest, testMatchAllDocs) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); - BOOST_CHECK(newLucene()->equals(qp->parse(L"*:*"))); - BOOST_CHECK(newLucene()->equals(qp->parse(L"(*:*)"))); + EXPECT_TRUE(newLucene()->equals(qp->parse(L"*:*"))); + EXPECT_TRUE(newLucene()->equals(qp->parse(L"(*:*)"))); BooleanQueryPtr bq = boost::dynamic_pointer_cast(qp->parse(L"+*:* -*:*")); - BOOST_CHECK(MiscUtils::typeOf(bq->getClauses()[0]->getQuery())); - BOOST_CHECK(MiscUtils::typeOf(bq->getClauses()[1]->getQuery())); + EXPECT_TRUE(MiscUtils::typeOf(bq->getClauses()[0]->getQuery())); + EXPECT_TRUE(MiscUtils::typeOf(bq->getClauses()[1]->getQuery())); } -BOOST_AUTO_TEST_CASE(testPositionIncrements) +TEST_F(QueryParserTest, testPositionIncrements) { DirectoryPtr dir = newLucene(); AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -884,9 +924,7 @@ BOOST_AUTO_TEST_CASE(testPositionIncrements) IndexSearcherPtr s = newLucene(r); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"f", a); QueryPtr q = qp->parse(L"\"wizard of ozzy\""); - BOOST_CHECK_EQUAL(1, s->search(q, 1)->totalHits); + EXPECT_EQ(1, s->search(q, 1)->totalHits); r->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/BaseTestRangeFilterTest.cpp b/src/test/search/BaseTestRangeFilterTest.cpp index b6a758e0..4ab5137e 100644 --- a/src/test/search/BaseTestRangeFilterTest.cpp +++ b/src/test/search/BaseTestRangeFilterTest.cpp @@ -9,9 +9,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BaseTestRangeFilterTest, BaseTestRangeFilterFixture) +typedef BaseTestRangeFilterFixture BaseTestRangeFilterTest; -BOOST_AUTO_TEST_CASE(testPad) +TEST_F(BaseTestRangeFilterTest, testPad) { Collection tests = newCollection(-9999999, -99560, -100, -1, 0, 3, 9, 10, 1000, 999999999); for (int32_t i = 0; i < tests.size() - 1; ++i) @@ -20,9 +20,7 @@ BOOST_AUTO_TEST_CASE(testPad) int32_t b = tests[i + 1]; String aa = pad(a); String bb = pad(b); - BOOST_CHECK_EQUAL(aa.length(), bb.length()); - BOOST_CHECK(aa.compare(bb) < 0); + EXPECT_EQ(aa.length(), bb.length()); + EXPECT_TRUE(aa.compare(bb) < 0); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/Boolean2Test.cpp b/src/test/search/Boolean2Test.cpp index 4248b2ca..7521bbe0 100644 --- a/src/test/search/Boolean2Test.cpp +++ b/src/test/search/Boolean2Test.cpp @@ -34,10 +34,10 @@ using namespace Lucene; /// Test BooleanQuery2 against BooleanQuery by overriding the standard query parser. /// This also tests the scoring order of BooleanQuery. -class Boolean2Fixture : public LuceneTestFixture +class Boolean2Test : public LuceneTestFixture { public: - Boolean2Fixture() + Boolean2Test() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -68,7 +68,7 @@ class Boolean2Fixture : public LuceneTestFixture mulFactor *= 2; } while (docCount < 3000); - + IndexWriterPtr w = newLucene(dir2, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field2", L"xxx", Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -84,8 +84,8 @@ class Boolean2Fixture : public LuceneTestFixture w->close(); bigSearcher = newLucene(reader); } - - virtual ~Boolean2Fixture() + + virtual ~Boolean2Test() { reader->close(); dir2->close(); @@ -98,7 +98,7 @@ class Boolean2Fixture : public LuceneTestFixture DirectoryPtr dir2; int32_t mulFactor; Collection docFields; - + public: static const int32_t NUM_EXTRA_DOCS; static const String field; @@ -108,7 +108,7 @@ class Boolean2Fixture : public LuceneTestFixture { return newLucene(LuceneVersion::LUCENE_CURRENT, field, newLucene())->parse(queryText); } - + void queriesTest(const String& queryText, Collection expDocNrs) { QueryPtr query1 = makeQuery(queryText); @@ -121,11 +121,11 @@ class Boolean2Fixture : public LuceneTestFixture searcher->search(query2, FilterPtr(), collector); Collection hits2 = collector->topDocs()->scoreDocs; - BOOST_CHECK_EQUAL(mulFactor * collector->getTotalHits(), bigSearcher->search(query1, 1)->totalHits); + EXPECT_EQ(mulFactor * collector->getTotalHits(), bigSearcher->search(query1, 1)->totalHits); CheckHits::checkHitsQuery(query2, hits1, hits2, expDocNrs); } - + /// Random rnd is passed in so that the exact same random query may be created more than once. BooleanQueryPtr randBoolQuery(RandomPtr rnd, bool allowMust, int32_t level, const String& field, Collection vals) { @@ -142,7 +142,7 @@ class Boolean2Fixture : public LuceneTestFixture q = newLucene(newLucene(field, L"w*")); else q = randBoolQuery(rnd, allowMust, level - 1, field, vals); - + int32_t r = rnd->nextInt(10); BooleanClause::Occur occur = BooleanClause::SHOULD; if (r < 2) @@ -154,75 +154,73 @@ class Boolean2Fixture : public LuceneTestFixture else occur = BooleanClause::SHOULD; } - + current->add(q, occur); } return current; } }; -const String Boolean2Fixture::field = L"field"; -const int32_t Boolean2Fixture::NUM_EXTRA_DOCS = 6000; - -BOOST_FIXTURE_TEST_SUITE(Boolean2Test, Boolean2Fixture) +const String Boolean2Test::field = L"field"; +const int32_t Boolean2Test::NUM_EXTRA_DOCS = 6000; -BOOST_AUTO_TEST_CASE(testQueries01) +TEST_F(Boolean2Test, testQueries01) { String queryText = L"+w3 +xx"; Collection expDocNrs = newCollection(2, 3); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries02) +TEST_F(Boolean2Test, testQueries02) { String queryText = L"+w3 xx"; Collection expDocNrs = newCollection(2, 3, 1, 0); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries03) +TEST_F(Boolean2Test, testQueries03) { String queryText = L"w3 xx"; Collection expDocNrs = newCollection(2, 3, 1, 0); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries04) +TEST_F(Boolean2Test, testQueries04) { String queryText = L"w3 -xx"; Collection expDocNrs = newCollection(1, 0); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries05) +TEST_F(Boolean2Test, testQueries05) { String queryText = L"+w3 -xx"; Collection expDocNrs = newCollection(1, 0); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries06) +TEST_F(Boolean2Test, testQueries06) { String queryText = L"+w3 -xx -w5"; Collection expDocNrs = newCollection(1); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries07) +TEST_F(Boolean2Test, testQueries07) { String queryText = L"-w3 -xx -w5"; Collection expDocNrs = Collection::newInstance(); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries08) +TEST_F(Boolean2Test, testQueries08) { String queryText = L"+w3 xx -w5"; Collection expDocNrs = newCollection(2, 3, 1); queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testQueries09) +TEST_F(Boolean2Test, testQueries09) { String queryText = L"+w3 +xx +w2 zz"; Collection expDocNrs = newCollection(2, 3); @@ -237,7 +235,7 @@ namespace TestQueries10 virtual ~OverlapSimilarity() { } - + public: virtual double coord(int32_t overlap, int32_t maxOverlap) { @@ -246,16 +244,16 @@ namespace TestQueries10 }; } -BOOST_AUTO_TEST_CASE(testQueries10) +TEST_F(Boolean2Test, testQueries10) { String queryText = L"+w3 +xx +w2 zz"; Collection expDocNrs = newCollection(2, 3); searcher->setSimilarity(newLucene()); - + queriesTest(queryText, expDocNrs); } -BOOST_AUTO_TEST_CASE(testRandomQueries) +TEST_F(Boolean2Test, testRandomQueries) { RandomPtr rnd = newLucene(17); Collection vals = newCollection(L"w1", L"w2", L"w3", L"w4", L"w5", L"xx", L"yy", L"zzz"); @@ -286,8 +284,6 @@ BOOST_AUTO_TEST_CASE(testRandomQueries) q3->add(q1, BooleanClause::SHOULD); q3->add(newLucene(newLucene(L"field2", L"b")), BooleanClause::SHOULD); TopDocsPtr hits4 = bigSearcher->search(q3, 1); - BOOST_CHECK_EQUAL(mulFactor * collector->getTotalHits() + NUM_EXTRA_DOCS / 2, hits4->totalHits); + EXPECT_EQ(mulFactor * collector->getTotalHits() + NUM_EXTRA_DOCS / 2, hits4->totalHits); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/BooleanMinShouldMatchTest.cpp b/src/test/search/BooleanMinShouldMatchTest.cpp index 88e7d7cf..cb8f15b9 100644 --- a/src/test/search/BooleanMinShouldMatchTest.cpp +++ b/src/test/search/BooleanMinShouldMatchTest.cpp @@ -25,10 +25,10 @@ using namespace Lucene; -class BooleanMinShouldMatchFixture : public LuceneTestFixture +class BooleanMinShouldMatchTest : public LuceneTestFixture { public: - BooleanMinShouldMatchFixture() + BooleanMinShouldMatchTest() { Collection data = newCollection( L"A 1 2 3 4 5 6", @@ -59,8 +59,8 @@ class BooleanMinShouldMatchFixture : public LuceneTestFixture r = IndexReader::open(index, true); s = newLucene(r); } - - virtual ~BooleanMinShouldMatchFixture() + + virtual ~BooleanMinShouldMatchTest() { } @@ -73,10 +73,10 @@ class BooleanMinShouldMatchFixture : public LuceneTestFixture void verifyNrHits(QueryPtr q, int32_t expected) { Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(expected, h.size()); + EXPECT_EQ(expected, h.size()); QueryUtils::check(q, s); } - + /// Random rnd is passed in so that the exact same random query may be created more than once. BooleanQueryPtr randBoolQuery(RandomPtr rnd, bool allowMust, int32_t level, const String& field, Collection vals) { @@ -93,7 +93,7 @@ class BooleanMinShouldMatchFixture : public LuceneTestFixture q = newLucene(newLucene(field, L"w*")); else q = randBoolQuery(rnd, allowMust, level - 1, field, vals); - + int32_t r = rnd->nextInt(10); BooleanClause::Occur occur = BooleanClause::SHOULD; if (r < 2) @@ -105,12 +105,12 @@ class BooleanMinShouldMatchFixture : public LuceneTestFixture else occur = BooleanClause::SHOULD; } - + current->add(q, occur); } return current; } - + void minNrCB(RandomPtr rnd, BooleanQueryPtr q) { Collection c = q->getClauses(); @@ -124,9 +124,7 @@ class BooleanMinShouldMatchFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(BooleanMinShouldMatchTest, BooleanMinShouldMatchFixture) - -BOOST_AUTO_TEST_CASE(testAllOptional) +TEST_F(BooleanMinShouldMatchTest, testAllOptional) { BooleanQueryPtr q = newLucene(); for (int32_t i = 1; i <= 4; ++i) @@ -135,7 +133,7 @@ BOOST_AUTO_TEST_CASE(testAllOptional) verifyNrHits(q, 2); } -BOOST_AUTO_TEST_CASE(testOneReqAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testOneReqAndSomeOptional) { // one required, some optional BooleanQueryPtr q = newLucene(); @@ -144,12 +142,12 @@ BOOST_AUTO_TEST_CASE(testOneReqAndSomeOptional) q->add(newLucene(newLucene(L"data", L"4")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"3")), BooleanClause::SHOULD); - q->setMinimumNumberShouldMatch(2); // 2 of 3 optional + q->setMinimumNumberShouldMatch(2); // 2 of 3 optional verifyNrHits(q, 5); } -BOOST_AUTO_TEST_CASE(testSomeReqAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testSomeReqAndSomeOptional) { // two required, some optional BooleanQueryPtr q = newLucene(); @@ -159,12 +157,12 @@ BOOST_AUTO_TEST_CASE(testSomeReqAndSomeOptional) q->add(newLucene(newLucene(L"data", L"4")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"3")), BooleanClause::SHOULD); - q->setMinimumNumberShouldMatch(2); // 2 of 3 optional + q->setMinimumNumberShouldMatch(2); // 2 of 3 optional verifyNrHits(q, 5); } -BOOST_AUTO_TEST_CASE(testOneProhibAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testOneProhibAndSomeOptional) { // one prohibited, some optional BooleanQueryPtr q = newLucene(); @@ -173,12 +171,12 @@ BOOST_AUTO_TEST_CASE(testOneProhibAndSomeOptional) q->add(newLucene(newLucene(L"data", L"3")), BooleanClause::MUST_NOT); q->add(newLucene(newLucene(L"data", L"4")), BooleanClause::SHOULD); - q->setMinimumNumberShouldMatch(2); // 2 of 3 optional + q->setMinimumNumberShouldMatch(2); // 2 of 3 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testSomeProhibAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testSomeProhibAndSomeOptional) { // two prohibited, some optional BooleanQueryPtr q = newLucene(); @@ -188,12 +186,12 @@ BOOST_AUTO_TEST_CASE(testSomeProhibAndSomeOptional) q->add(newLucene(newLucene(L"data", L"4")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"C")), BooleanClause::MUST_NOT); - q->setMinimumNumberShouldMatch(2); // 2 of 3 optional + q->setMinimumNumberShouldMatch(2); // 2 of 3 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testOneReqOneProhibAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testOneReqOneProhibAndSomeOptional) { // one required, one prohibited, some optional BooleanQueryPtr q = newLucene(); @@ -204,12 +202,12 @@ BOOST_AUTO_TEST_CASE(testOneReqOneProhibAndSomeOptional) q->add(newLucene(newLucene(L"data", L"2")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"1")), BooleanClause::SHOULD); - q->setMinimumNumberShouldMatch(3); // 3 of 4 optional + q->setMinimumNumberShouldMatch(3); // 3 of 4 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testSomeReqOneProhibAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testSomeReqOneProhibAndSomeOptional) { // two required, one prohibited, some optional BooleanQueryPtr q = newLucene(); @@ -221,12 +219,12 @@ BOOST_AUTO_TEST_CASE(testSomeReqOneProhibAndSomeOptional) q->add(newLucene(newLucene(L"data", L"2")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"1")), BooleanClause::SHOULD); - q->setMinimumNumberShouldMatch(3); // 3 of 4 optional + q->setMinimumNumberShouldMatch(3); // 3 of 4 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testOneReqSomeProhibAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testOneReqSomeProhibAndSomeOptional) { // one required, two prohibited, some optional BooleanQueryPtr q = newLucene(); @@ -238,12 +236,12 @@ BOOST_AUTO_TEST_CASE(testOneReqSomeProhibAndSomeOptional) q->add(newLucene(newLucene(L"data", L"1")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"C")), BooleanClause::MUST_NOT); - q->setMinimumNumberShouldMatch(3); // 3 of 4 optional + q->setMinimumNumberShouldMatch(3); // 3 of 4 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testSomeReqSomeProhibAndSomeOptional) +TEST_F(BooleanMinShouldMatchTest, testSomeReqSomeProhibAndSomeOptional) { // two required, two prohibited, some optional BooleanQueryPtr q = newLucene(); @@ -256,12 +254,12 @@ BOOST_AUTO_TEST_CASE(testSomeReqSomeProhibAndSomeOptional) q->add(newLucene(newLucene(L"data", L"1")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"C")), BooleanClause::MUST_NOT); - q->setMinimumNumberShouldMatch(3); // 3 of 4 optional + q->setMinimumNumberShouldMatch(3); // 3 of 4 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testMinHigherThenNumOptional) +TEST_F(BooleanMinShouldMatchTest, testMinHigherThenNumOptional) { // two required, two prohibited, some optional BooleanQueryPtr q = newLucene(); @@ -274,12 +272,12 @@ BOOST_AUTO_TEST_CASE(testMinHigherThenNumOptional) q->add(newLucene(newLucene(L"data", L"1")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"C")), BooleanClause::MUST_NOT); - q->setMinimumNumberShouldMatch(90); // 90 of 4 optional + q->setMinimumNumberShouldMatch(90); // 90 of 4 optional verifyNrHits(q, 0); } -BOOST_AUTO_TEST_CASE(testMinEqualToNumOptional) +TEST_F(BooleanMinShouldMatchTest, testMinEqualToNumOptional) { // two required, two optional BooleanQueryPtr q = newLucene(); @@ -288,12 +286,12 @@ BOOST_AUTO_TEST_CASE(testMinEqualToNumOptional) q->add(newLucene(newLucene(L"data", L"3")), BooleanClause::MUST); q->add(newLucene(newLucene(L"data", L"2")), BooleanClause::SHOULD); - q->setMinimumNumberShouldMatch(2); // 2 of 2 optional + q->setMinimumNumberShouldMatch(2); // 2 of 2 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testOneOptionalEqualToMin) +TEST_F(BooleanMinShouldMatchTest, testOneOptionalEqualToMin) { // two required, one optional BooleanQueryPtr q = newLucene(); @@ -301,38 +299,38 @@ BOOST_AUTO_TEST_CASE(testOneOptionalEqualToMin) q->add(newLucene(newLucene(L"data", L"3")), BooleanClause::SHOULD); q->add(newLucene(newLucene(L"data", L"2")), BooleanClause::MUST); - q->setMinimumNumberShouldMatch(1); // 1 of 1 optional + q->setMinimumNumberShouldMatch(1); // 1 of 1 optional verifyNrHits(q, 1); } -BOOST_AUTO_TEST_CASE(testNoOptionalButMin) +TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin) { // two required, no optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); q->add(newLucene(newLucene(L"data", L"2")), BooleanClause::MUST); - q->setMinimumNumberShouldMatch(1); // 1 of 0 optional + q->setMinimumNumberShouldMatch(1); // 1 of 0 optional verifyNrHits(q, 0); } -BOOST_AUTO_TEST_CASE(testNoOptionalButMin2) +TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin2) { // one required, no optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); - q->setMinimumNumberShouldMatch(1); // 1 of 0 optional + q->setMinimumNumberShouldMatch(1); // 1 of 0 optional verifyNrHits(q, 0); } -BOOST_AUTO_TEST_CASE(testRandomQueries) +TEST_F(BooleanMinShouldMatchTest, testRandomQueries) { RandomPtr rnd = newLucene(17); - + String field = L"data"; Collection vals = Collection::newInstance(); vals.add(L"1"); @@ -349,33 +347,33 @@ BOOST_AUTO_TEST_CASE(testRandomQueries) vals.add(L"X"); vals.add(L"foo"); int32_t maxLev = 4; - + // increase number of iterations for more complete testing for (int32_t i = 0; i < 1000; ++i) { int32_t lev = rnd->nextInt(maxLev); int32_t seed = rnd->nextInt(); - + RandomPtr rndQuery = newLucene(); rndQuery->setSeed(seed); BooleanQueryPtr q1 = randBoolQuery(rndQuery, true, lev, field, vals); rndQuery->setSeed(seed); BooleanQueryPtr q2 = randBoolQuery(rndQuery, true, lev, field, vals); - + // only set minimumNumberShouldMatch on the top level query since setting at a lower level can change the score. minNrCB(rnd, q2); - // Can't use Hits because normalized scores will mess things up. + // Can't use Hits because normalized scores will mess things up. // The non-sorting version of search() that returns TopDocs will not normalize scores. TopDocsPtr top1 = s->search(q1, FilterPtr(), 100); TopDocsPtr top2 = s->search(q2, FilterPtr(), 100); QueryUtils::check(q1, s); QueryUtils::check(q2, s); - + // The constrained query should be a superset to the unconstrained query. - BOOST_CHECK(top2->totalHits <= top1->totalHits); - + EXPECT_TRUE(top2->totalHits <= top1->totalHits); + for (int32_t hit = 0; hit < top2->totalHits; ++hit) { int32_t id = top2->scoreDocs[hit]->doc; @@ -389,14 +387,12 @@ BOOST_AUTO_TEST_CASE(testRandomQueries) found = true; double otherScore = top1->scoreDocs[other]->score; // check if scores match - BOOST_CHECK_CLOSE_FRACTION(otherScore, score, 1.0e-6f); + EXPECT_NEAR(otherScore, score, 1.0e-6f); } } - + // check if subset - BOOST_CHECK(found); + EXPECT_TRUE(found); } } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/BooleanOrTest.cpp b/src/test/search/BooleanOrTest.cpp index e68279d4..34b578ce 100644 --- a/src/test/search/BooleanOrTest.cpp +++ b/src/test/search/BooleanOrTest.cpp @@ -20,16 +20,16 @@ using namespace Lucene; -class BooleanOrFixture : public LuceneTestFixture +class BooleanOrTest : public LuceneTestFixture { public: - BooleanOrFixture() + BooleanOrTest() { t1 = newLucene(newLucene(FIELD_T, L"files")); t2 = newLucene(newLucene(FIELD_T, L"deleting")); c1 = newLucene(newLucene(FIELD_C, L"production")); c2 = newLucene(newLucene(FIELD_C, L"optimize")); - + RAMDirectoryPtr rd = newLucene(); IndexWriterPtr writer = newLucene(rd, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -41,8 +41,8 @@ class BooleanOrFixture : public LuceneTestFixture writer->close(); searcher = newLucene(rd, true); } - - virtual ~BooleanOrFixture() + + virtual ~BooleanOrTest() { } @@ -54,7 +54,7 @@ class BooleanOrFixture : public LuceneTestFixture TermQueryPtr t2; TermQueryPtr c1; TermQueryPtr c2; - + IndexSearcherPtr searcher; public: @@ -65,30 +65,28 @@ class BooleanOrFixture : public LuceneTestFixture } }; -const String BooleanOrFixture::FIELD_T = L"T"; -const String BooleanOrFixture::FIELD_C = L"C"; +const String BooleanOrTest::FIELD_T = L"T"; +const String BooleanOrTest::FIELD_C = L"C"; -BOOST_FIXTURE_TEST_SUITE(BooleanOrTest, BooleanOrFixture) - -BOOST_AUTO_TEST_CASE(testElements) +TEST_F(BooleanOrTest, testElements) { - BOOST_CHECK_EQUAL(1, search(t1)); - BOOST_CHECK_EQUAL(1, search(t2)); - BOOST_CHECK_EQUAL(1, search(c1)); - BOOST_CHECK_EQUAL(1, search(c2)); + EXPECT_EQ(1, search(t1)); + EXPECT_EQ(1, search(t2)); + EXPECT_EQ(1, search(c1)); + EXPECT_EQ(1, search(c2)); } -BOOST_AUTO_TEST_CASE(testFlat) +TEST_F(BooleanOrTest, testFlat) { BooleanQueryPtr q = newLucene(); q->add(newLucene(t1, BooleanClause::SHOULD)); q->add(newLucene(t2, BooleanClause::SHOULD)); q->add(newLucene(c1, BooleanClause::SHOULD)); q->add(newLucene(c2, BooleanClause::SHOULD)); - BOOST_CHECK_EQUAL(1, search(q)); + EXPECT_EQ(1, search(q)); } -BOOST_AUTO_TEST_CASE(testParenthesisMust) +TEST_F(BooleanOrTest, testParenthesisMust) { BooleanQueryPtr q3 = newLucene(); q3->add(newLucene(t1, BooleanClause::SHOULD)); @@ -99,10 +97,10 @@ BOOST_AUTO_TEST_CASE(testParenthesisMust) BooleanQueryPtr q2 = newLucene(); q2->add(q3, BooleanClause::SHOULD); q2->add(q4, BooleanClause::SHOULD); - BOOST_CHECK_EQUAL(1, search(q2)); + EXPECT_EQ(1, search(q2)); } -BOOST_AUTO_TEST_CASE(testParenthesisMust2) +TEST_F(BooleanOrTest, testParenthesisMust2) { BooleanQueryPtr q3 = newLucene(); q3->add(newLucene(t1, BooleanClause::SHOULD)); @@ -113,10 +111,10 @@ BOOST_AUTO_TEST_CASE(testParenthesisMust2) BooleanQueryPtr q2 = newLucene(); q2->add(q3, BooleanClause::SHOULD); q2->add(q4, BooleanClause::MUST); - BOOST_CHECK_EQUAL(1, search(q2)); + EXPECT_EQ(1, search(q2)); } -BOOST_AUTO_TEST_CASE(testParenthesisShould) +TEST_F(BooleanOrTest, testParenthesisShould) { BooleanQueryPtr q3 = newLucene(); q3->add(newLucene(t1, BooleanClause::SHOULD)); @@ -127,7 +125,5 @@ BOOST_AUTO_TEST_CASE(testParenthesisShould) BooleanQueryPtr q2 = newLucene(); q2->add(q3, BooleanClause::SHOULD); q2->add(q4, BooleanClause::SHOULD); - BOOST_CHECK_EQUAL(1, search(q2)); + EXPECT_EQ(1, search(q2)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/BooleanPrefixQueryTest.cpp b/src/test/search/BooleanPrefixQueryTest.cpp index d9c3865f..6bb7d268 100644 --- a/src/test/search/BooleanPrefixQueryTest.cpp +++ b/src/test/search/BooleanPrefixQueryTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BooleanPrefixQueryTest, LuceneTestFixture) +typedef LuceneTestFixture BooleanPrefixQueryTest; static int32_t getCount(IndexReaderPtr r, QueryPtr q) { @@ -39,12 +39,12 @@ static int32_t getCount(IndexReaderPtr r, QueryPtr q) } else { - BOOST_FAIL("unexpected query"); + boost::throw_exception(RuntimeException(L"unexpected query")); return 0; } } -BOOST_AUTO_TEST_CASE(testMethod) +TEST_F(BooleanPrefixQueryTest, testMethod) { RAMDirectoryPtr directory = newLucene(); @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(testMethod) writer->addDocument(doc); } writer->close(); - + IndexReaderPtr reader = IndexReader::open(directory, true); PrefixQueryPtr query = newLucene(newLucene(L"category", L"foo")); QueryPtr rw1 = query->rewrite(reader); @@ -67,8 +67,6 @@ BOOST_AUTO_TEST_CASE(testMethod) bq->add(query, BooleanClause::MUST); QueryPtr rw2 = bq->rewrite(reader); - - BOOST_CHECK_EQUAL(getCount(reader, rw1), getCount(reader, rw2)); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(getCount(reader, rw1), getCount(reader, rw2)); +} diff --git a/src/test/search/BooleanQueryTest.cpp b/src/test/search/BooleanQueryTest.cpp index 01c19c0c..7814ff0b 100644 --- a/src/test/search/BooleanQueryTest.cpp +++ b/src/test/search/BooleanQueryTest.cpp @@ -22,9 +22,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BooleanQueryTest, LuceneTestFixture) +typedef LuceneTestFixture BooleanQueryTest; -BOOST_AUTO_TEST_CASE(testEquality) +TEST_F(BooleanQueryTest, testEquality) { BooleanQueryPtr bq1 = newLucene(); bq1->add(newLucene(newLucene(L"field", L"value1")), BooleanClause::SHOULD); @@ -42,33 +42,40 @@ BOOST_AUTO_TEST_CASE(testEquality) nested2->add(newLucene(newLucene(L"field", L"nestedvalue2")), BooleanClause::SHOULD); bq2->add(nested2, BooleanClause::SHOULD); - BOOST_CHECK(bq1->equals(bq2)); + EXPECT_TRUE(bq1->equals(bq2)); } -BOOST_AUTO_TEST_CASE(testException) +TEST_F(BooleanQueryTest, testException) { - BOOST_CHECK_EXCEPTION(BooleanQuery::setMaxClauseCount(0), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + BooleanQuery::setMaxClauseCount(0); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } -BOOST_AUTO_TEST_CASE(testNullOrSubScorer) +TEST_F(BooleanQueryTest, testNullOrSubScorer) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"a b c d", Field::STORE_NO, Field::INDEX_ANALYZED)); w->addDocument(doc); - + IndexReaderPtr r = w->getReader(); IndexSearcherPtr s = newLucene(r); BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"field", L"a")), BooleanClause::SHOULD); - + double score = s->search(q, 10)->getMaxScore(); QueryPtr subQuery = newLucene(newLucene(L"field", L"not_in_index")); subQuery->setBoost(0); q->add(subQuery, BooleanClause::SHOULD); double score2 = s->search(q, 10)->getMaxScore(); - BOOST_CHECK_CLOSE_FRACTION(score * 0.5, score2, 1e-6); + EXPECT_NEAR(score * 0.5, score2, 1e-6); BooleanQueryPtr qq = boost::dynamic_pointer_cast(q->clone()); PhraseQueryPtr phrase = newLucene(); @@ -77,35 +84,33 @@ BOOST_AUTO_TEST_CASE(testNullOrSubScorer) phrase->setBoost(0); qq->add(phrase, BooleanClause::SHOULD); score2 = s->search(qq, 10)->getMaxScore(); - BOOST_CHECK_CLOSE_FRACTION(score * (1.0 / 3), score2, 1e-6); - + EXPECT_NEAR(score * (1.0 / 3), score2, 1e-6); + // now test BooleanScorer2 subQuery = newLucene(newLucene(L"field", L"b")); subQuery->setBoost(0); q->add(subQuery, BooleanClause::MUST); score2 = s->search(q, 10)->getMaxScore(); - BOOST_CHECK_CLOSE_FRACTION(score * (2.0 / 3), score2, 1e-6); + EXPECT_NEAR(score * (2.0 / 3), score2, 1e-6); // PhraseQuery with no terms added returns a null scorer PhraseQueryPtr pq = newLucene(); q->add(pq, BooleanClause::SHOULD); - BOOST_CHECK_EQUAL(1, s->search(q, 10)->totalHits); + EXPECT_EQ(1, s->search(q, 10)->totalHits); // A required clause which returns null scorer should return null scorer to IndexSearcher. q = newLucene(); pq = newLucene(); q->add(newLucene(newLucene(L"field", L"a")), BooleanClause::SHOULD); q->add(pq, BooleanClause::MUST); - BOOST_CHECK_EQUAL(0, s->search(q, 10)->totalHits); + EXPECT_EQ(0, s->search(q, 10)->totalHits); DisjunctionMaxQueryPtr dmq = newLucene(1.0); dmq->add(newLucene(newLucene(L"field", L"a"))); dmq->add(pq); - BOOST_CHECK_EQUAL(1, s->search(dmq, 10)->totalHits); + EXPECT_EQ(1, s->search(dmq, 10)->totalHits); r->close(); w->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/BooleanScorerTest.cpp b/src/test/search/BooleanScorerTest.cpp index ad8c56ba..2453f092 100644 --- a/src/test/search/BooleanScorerTest.cpp +++ b/src/test/search/BooleanScorerTest.cpp @@ -22,15 +22,15 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BooleanScorerTest, LuceneTestFixture) +typedef LuceneTestFixture BooleanScorerTest; -BOOST_AUTO_TEST_CASE(testMethod) +TEST_F(BooleanScorerTest, testMethod) { static const String FIELD = L"category"; - + RAMDirectoryPtr directory = newLucene(); Collection values = newCollection(L"1", L"2", L"3", L"4"); - + IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < values.size(); ++i) { @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(testMethod) writer->addDocument(doc); } writer->close(); - + BooleanQueryPtr booleanQuery1 = newLucene(); booleanQuery1->add(newLucene(newLucene(FIELD, L"1")), BooleanClause::SHOULD); booleanQuery1->add(newLucene(newLucene(FIELD, L"2")), BooleanClause::SHOULD); @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(testMethod) IndexSearcherPtr indexSearcher = newLucene(directory, true); Collection hits = indexSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); } namespace TestEmptyBucketWithMoreDocs @@ -62,31 +62,31 @@ namespace TestEmptyBucketWithMoreDocs { doc = -1; } - + virtual ~EmptyScorer() { } - + protected: int32_t doc; - + public: virtual double score() { return 0.0; } - + virtual int32_t docID() { return doc; } - + virtual int32_t nextDoc() { doc = doc == -1 ? 3000 : NO_MORE_DOCS; return doc; } - + virtual int32_t advance(int32_t target) { doc = target <= 3000 ? 3000 : NO_MORE_DOCS; @@ -95,18 +95,16 @@ namespace TestEmptyBucketWithMoreDocs }; } -BOOST_AUTO_TEST_CASE(testEmptyBucketWithMoreDocs) +TEST_F(BooleanScorerTest, testEmptyBucketWithMoreDocs) { - // This test checks the logic of nextDoc() when all sub scorers have docs beyond the first bucket - // (for example). Currently, the code relies on the 'more' variable to work properly, and this + // This test checks the logic of nextDoc() when all sub scorers have docs beyond the first bucket + // (for example). Currently, the code relies on the 'more' variable to work properly, and this // test ensures that if the logic changes, we have a test to back it up. SimilarityPtr sim = Similarity::getDefault(); Collection scorers = newCollection(newLucene(sim)); - + BooleanScorerPtr bs = newLucene(sim, 1, scorers, Collection()); - BOOST_CHECK_EQUAL(3000, bs->nextDoc()); - BOOST_CHECK_EQUAL(DocIdSetIterator::NO_MORE_DOCS, bs->nextDoc()); + EXPECT_EQ(3000, bs->nextDoc()); + EXPECT_EQ(DocIdSetIterator::NO_MORE_DOCS, bs->nextDoc()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/CachingSpanFilterTest.cpp b/src/test/search/CachingSpanFilterTest.cpp index 0f029e32..5625b4f4 100644 --- a/src/test/search/CachingSpanFilterTest.cpp +++ b/src/test/search/CachingSpanFilterTest.cpp @@ -27,7 +27,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CachingSpanFilterTest, LuceneTestFixture) +typedef LuceneTestFixture CachingSpanFilterTest; static IndexReaderPtr refreshReader(IndexReaderPtr reader) { @@ -38,7 +38,7 @@ static IndexReaderPtr refreshReader(IndexReaderPtr reader) return reader; } -BOOST_AUTO_TEST_CASE(testEnforceDeletions) +TEST_F(CachingSpanFilterTest, testEnforceDeletions) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -54,18 +54,18 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); TopDocsPtr docs = searcher->search(newLucene(), 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); SpanFilterPtr startFilter = newLucene(newLucene(newLucene(L"id", L"1"))); // ignore deletions CachingSpanFilterPtr filter = newLucene(startFilter, CachingWrapperFilter::DELETES_IGNORE); - + docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); ConstantScoreQueryPtr constantScore = newLucene(filter); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); // now delete the doc, refresh the reader, and see that it's not there writer->deleteDocuments(newLucene(L"id", L"1")); @@ -74,10 +74,10 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(0, docs->totalHits); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); // force cache to regenerate filter = newLucene(startFilter, CachingWrapperFilter::DELETES_RECACHE); @@ -87,21 +87,21 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); constantScore = newLucene(filter); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); // make sure we get a cache hit when we reopen readers that had no new deletions IndexReaderPtr newReader = refreshReader(reader); - BOOST_CHECK_NE(reader, newReader); + EXPECT_NE(reader, newReader); reader = newReader; searcher = newLucene(reader); int32_t missCount = filter->missCount; docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); - BOOST_CHECK_EQUAL(missCount, filter->missCount); + EXPECT_EQ(1, docs->totalHits); + EXPECT_EQ(missCount, filter->missCount); // now delete the doc, refresh the reader, and see that it's not there writer->deleteDocuments(newLucene(L"id", L"1")); @@ -110,10 +110,8 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(0, docs->totalHits); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(0, docs->totalHits); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/CachingWrapperFilterTest.cpp b/src/test/search/CachingWrapperFilterTest.cpp index 928c0be3..18125b50 100644 --- a/src/test/search/CachingWrapperFilterTest.cpp +++ b/src/test/search/CachingWrapperFilterTest.cpp @@ -32,19 +32,19 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CachingWrapperFilterTest, LuceneTestFixture) +typedef LuceneTestFixture CachingWrapperFilterTest; static void checkDocIdSetCacheable(IndexReaderPtr reader, FilterPtr filter, bool shouldCacheable) { CachingWrapperFilterPtr cacher = newLucene(filter); DocIdSetPtr originalSet = filter->getDocIdSet(reader); DocIdSetPtr cachedSet = cacher->getDocIdSet(reader); - BOOST_CHECK(cachedSet->isCacheable()); - BOOST_CHECK_EQUAL(shouldCacheable, originalSet->isCacheable()); + EXPECT_TRUE(cachedSet->isCacheable()); + EXPECT_EQ(shouldCacheable, originalSet->isCacheable()); if (originalSet->isCacheable()) - BOOST_CHECK(MiscUtils::equalTypes(originalSet, cachedSet)); + EXPECT_TRUE(MiscUtils::equalTypes(originalSet, cachedSet)); else - BOOST_CHECK(MiscUtils::typeOf(cachedSet)); + EXPECT_TRUE(MiscUtils::typeOf(cachedSet)); } static IndexReaderPtr refreshReader(IndexReaderPtr reader) @@ -56,7 +56,7 @@ static IndexReaderPtr refreshReader(IndexReaderPtr reader) return reader; } -BOOST_AUTO_TEST_CASE(testCachingWorks) +TEST_F(CachingWrapperFilterTest, testCachingWorks) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(testCachingWorks) // first time, nested filter is called cacher->getDocIdSet(reader); - BOOST_CHECK(filter->wasCalled()); + EXPECT_TRUE(filter->wasCalled()); // make sure no exception if cache is holding the wrong docIdSet cacher->getDocIdSet(reader); @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(testCachingWorks) // second time, nested filter should not be called filter->clear(); cacher->getDocIdSet(reader); - BOOST_CHECK(!filter->wasCalled()); + EXPECT_TRUE(!filter->wasCalled()); reader->close(); } @@ -90,7 +90,7 @@ namespace TestNullDocIdSet virtual ~NullDocIdSetFilter() { } - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) { @@ -99,7 +99,7 @@ namespace TestNullDocIdSet }; } -BOOST_AUTO_TEST_CASE(testNullDocIdSet) +TEST_F(CachingWrapperFilterTest, testNullDocIdSet) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -110,8 +110,8 @@ BOOST_AUTO_TEST_CASE(testNullDocIdSet) CachingWrapperFilterPtr cacher = newLucene(filter); // the caching filter should return the empty set constant - BOOST_CHECK_EQUAL(DocIdSet::EMPTY_DOCIDSET(), cacher->getDocIdSet(reader)); - + EXPECT_EQ(DocIdSet::EMPTY_DOCIDSET(), cacher->getDocIdSet(reader)); + reader->close(); } @@ -123,21 +123,21 @@ namespace TestNullDocIdSetIterator virtual ~NullDocIdSetIterator() { } - + public: virtual DocIdSetIteratorPtr iterator() { return DocIdSetIteratorPtr(); } }; - + class NullDocIdSetIteratorFilter : public Filter { public: virtual ~NullDocIdSetIteratorFilter() { } - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) { @@ -146,7 +146,7 @@ namespace TestNullDocIdSetIterator }; } -BOOST_AUTO_TEST_CASE(testNullDocIdSetIterator) +TEST_F(CachingWrapperFilterTest, testNullDocIdSetIterator) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -157,8 +157,8 @@ BOOST_AUTO_TEST_CASE(testNullDocIdSetIterator) CachingWrapperFilterPtr cacher = newLucene(filter); // the caching filter should return the empty set constant - BOOST_CHECK_EQUAL(DocIdSet::EMPTY_DOCIDSET(), cacher->getDocIdSet(reader)); - + EXPECT_EQ(DocIdSet::EMPTY_DOCIDSET(), cacher->getDocIdSet(reader)); + reader->close(); } @@ -170,7 +170,7 @@ namespace TestIsCacheable virtual ~OpenBitSetFilter() { } - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) { @@ -179,28 +179,28 @@ namespace TestIsCacheable }; } -BOOST_AUTO_TEST_CASE(testIsCacheable) +TEST_F(CachingWrapperFilterTest, testIsCacheable) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - + // not cacheable checkDocIdSetCacheable(reader, newLucene(newLucene(newLucene(L"test", L"value"))), false); - + // returns default empty docidset, always cacheable checkDocIdSetCacheable(reader, NumericRangeFilter::newIntRange(L"test", 10000, -10000, true, true), true); - + // is cacheable checkDocIdSetCacheable(reader, FieldCacheRangeFilter::newIntRange(L"test", 10, 20, true, true), true); - + // a openbitset filter is always cacheable checkDocIdSetCacheable(reader, newLucene(), true); } -BOOST_AUTO_TEST_CASE(testEnforceDeletions) +TEST_F(CachingWrapperFilterTest, testEnforceDeletions) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); TopDocsPtr docs = searcher->search(newLucene(), 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); FilterPtr startFilter = newLucene(newLucene(newLucene(L"id", L"1"))); @@ -224,10 +224,10 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) CachingWrapperFilterPtr filter = newLucene(startFilter, CachingWrapperFilter::DELETES_IGNORE); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); ConstantScoreQueryPtr constantScore = newLucene(filter); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); // now delete the doc, refresh the reader, and see that it's not there writer->deleteDocuments(newLucene(L"id", L"1")); @@ -236,10 +236,10 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(0, docs->totalHits); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); // force cache to regenerate filter = newLucene(startFilter, CachingWrapperFilter::DELETES_RECACHE); @@ -249,21 +249,21 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); constantScore = newLucene(filter); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); // make sure we get a cache hit when we reopen reader that had no change to deletions IndexReaderPtr newReader = refreshReader(reader); - BOOST_CHECK_NE(reader, newReader); + EXPECT_NE(reader, newReader); reader = newReader; searcher = newLucene(reader); int32_t missCount = filter->missCount; docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); - BOOST_CHECK_EQUAL(missCount, filter->missCount); + EXPECT_EQ(1, docs->totalHits); + EXPECT_EQ(missCount, filter->missCount); // now delete the doc, refresh the reader, and see that it's not there writer->deleteDocuments(newLucene(L"id", L"1")); @@ -273,10 +273,10 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) missCount = filter->missCount; docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(missCount + 1, filter->missCount); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(missCount + 1, filter->missCount); + EXPECT_EQ(0, docs->totalHits); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(0, docs->totalHits); // apply deletions dynamically filter = newLucene(startFilter, CachingWrapperFilter::DELETES_DYNAMIC); @@ -286,10 +286,10 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); constantScore = newLucene(filter); docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(1, docs->totalHits); + EXPECT_EQ(1, docs->totalHits); // now delete the doc, refresh the reader, and see that it's not there writer->deleteDocuments(newLucene(L"id", L"1")); @@ -298,14 +298,12 @@ BOOST_AUTO_TEST_CASE(testEnforceDeletions) searcher = newLucene(reader); docs = searcher->search(newLucene(), filter, 1); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(0, docs->totalHits); missCount = filter->missCount; docs = searcher->search(constantScore, 1); - BOOST_CHECK_EQUAL(0, docs->totalHits); + EXPECT_EQ(0, docs->totalHits); // doesn't count as a miss - BOOST_CHECK_EQUAL(missCount, filter->missCount); + EXPECT_EQ(missCount, filter->missCount); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/CheckHits.cpp b/src/test/search/CheckHits.cpp index 30c986a9..923a71b1 100644 --- a/src/test/search/CheckHits.cpp +++ b/src/test/search/CheckHits.cpp @@ -21,10 +21,10 @@ namespace Lucene { - /// Some explains methods calculate their values though a slightly different order of operations + /// Some explains methods calculate their values though a slightly different order of operations /// from the actual scoring method - this allows for a small amount of variation const double CheckHits::EXPLAIN_SCORE_TOLERANCE_DELTA = 0.00005; - + class SetCollector : public Collector { public: @@ -33,38 +33,38 @@ namespace Lucene this->bag = bag; this->base = 0; } - + virtual ~SetCollector() { } - + public: Set bag; - + protected: int32_t base; - + public: virtual void setScorer(ScorerPtr scorer) { } - + virtual void collect(int32_t doc) { bag.add(doc + base); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; } }; - + /// Asserts that the score explanation for every document matching a query corresponds with the true score. /// /// NOTE: this HitCollector should only be used with the Query and Searcher specified at when it is constructed. @@ -79,154 +79,154 @@ namespace Lucene this->deep=deep; this->base = 0; } - + virtual ~ExplanationAsserter() { } - + public: QueryPtr q; SearcherPtr s; String d; bool deep; ScorerPtr scorer; - + protected: int32_t base; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { doc = doc + base; ExplanationPtr exp = s->explain(q, doc); - BOOST_CHECK(exp); + EXPECT_TRUE(exp); CheckHits::verifyExplanation(d, doc, scorer->score(), deep, exp); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; } }; - + CheckHits::~CheckHits() { } - + void CheckHits::checkNoMatchExplanations(QueryPtr q, const String& defaultFieldName, SearcherPtr searcher, Collection results) { String d = q->toString(defaultFieldName); Set ignore = Set::newInstance(); for (int32_t i = 0; i < results.size(); ++i) ignore.add(results[i]); - + int32_t maxDoc = searcher->maxDoc(); for (int32_t doc = 0; doc < maxDoc; ++doc) { if (ignore.contains(doc)) continue; - + ExplanationPtr exp = searcher->explain(q, doc); - BOOST_CHECK(exp); - BOOST_CHECK_EQUAL(0.0, exp->getValue()); + EXPECT_TRUE(exp); + EXPECT_EQ(0.0, exp->getValue()); } } - + void CheckHits::checkHitCollector(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results) { QueryUtils::check(query, searcher); Set correct = Set::newInstance(); for (int32_t i = 0; i < results.size(); ++i) correct.add(results[i]); - + Set actual = Set::newInstance(); CollectorPtr c = newLucene(actual); - + searcher->search(query, c); - BOOST_CHECK(correct.equals(actual)); - + EXPECT_TRUE(correct.equals(actual)); + for (int32_t i = -1; i < 2; ++i) { actual.clear(); QueryUtils::wrapSearcher(searcher, i)->search(query, c); - BOOST_CHECK(correct.equals(actual)); + EXPECT_TRUE(correct.equals(actual)); } - + if (!MiscUtils::typeOf(searcher)) return; - + for (int32_t i = -1; i < 2; ++i) { actual.clear(); QueryUtils::wrapUnderlyingReader(boost::dynamic_pointer_cast(searcher), i)->search(query, c); - BOOST_CHECK(correct.equals(actual)); + EXPECT_TRUE(correct.equals(actual)); } } - + void CheckHits::checkHits(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results) { if (!MiscUtils::typeOf(searcher)) QueryUtils::check(query, searcher); - + Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; Set correct = Set::newInstance(); for (int32_t i = 0; i < results.size(); ++i) correct.add(results[i]); - + Set actual = Set::newInstance(); for (int32_t i = 0; i < hits.size(); ++i) actual.add(hits[i]->doc); - - BOOST_CHECK(correct.equals(actual)); + + EXPECT_TRUE(correct.equals(actual)); QueryUtils::check(query, searcher); } - + void CheckHits::checkDocIds(Collection results, Collection hits) { - BOOST_CHECK_EQUAL(hits.size(), results.size()); + EXPECT_EQ(hits.size(), results.size()); for (int32_t i = 0; i < results.size(); ++i) - BOOST_CHECK_EQUAL(results[i], hits[i]->doc); + EXPECT_EQ(results[i], hits[i]->doc); } - + void CheckHits::checkHitsQuery(QueryPtr query, Collection hits1, Collection hits2, Collection results) { checkDocIds(results, hits1); checkDocIds(results, hits2); checkEqual(query, hits1, hits2); } - + void CheckHits::checkEqual(QueryPtr query, Collection hits1, Collection hits2) { double scoreTolerance = 1.0e-6; - BOOST_CHECK_EQUAL(hits1.size(), hits2.size()); + EXPECT_EQ(hits1.size(), hits2.size()); for (int32_t i = 0; i < hits1.size(); ++i) { - BOOST_CHECK_EQUAL(hits1[i]->doc, hits2[i]->doc); - BOOST_CHECK_CLOSE_FRACTION(hits1[i]->score, hits2[i]->score, scoreTolerance); + EXPECT_EQ(hits1[i]->doc, hits2[i]->doc); + EXPECT_NEAR(hits1[i]->score, hits2[i]->score, scoreTolerance); } } - + void CheckHits::checkExplanations(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, bool deep) { searcher->search(query, newLucene(query, defaultFieldName, searcher, deep)); } - + void CheckHits::verifyExplanation(const String& q, int32_t doc, double score, bool deep, ExplanationPtr expl) { double value = expl->getValue(); - BOOST_CHECK_CLOSE_FRACTION(score, value, EXPLAIN_SCORE_TOLERANCE_DELTA); + EXPECT_NEAR(score, value, EXPLAIN_SCORE_TOLERANCE_DELTA); if (!deep) return; @@ -265,7 +265,7 @@ namespace Lucene maxTimesOthers = true; } } - BOOST_CHECK(productOf || sumOf || maxOf || maxTimesOthers); + EXPECT_TRUE(productOf || sumOf || maxOf || maxTimesOthers); double sum = 0.0; double product = 1.0; double max = 0.0; @@ -287,9 +287,9 @@ namespace Lucene else if (maxTimesOthers) combined = max + x * (sum - max); else - BOOST_FAIL("should never get here!"); - - BOOST_CHECK_CLOSE_FRACTION(combined, value, EXPLAIN_SCORE_TOLERANCE_DELTA); + FAIL() << "should never get here!"; + + EXPECT_NEAR(combined, value, EXPLAIN_SCORE_TOLERANCE_DELTA); } } } diff --git a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp index ae11a171..16a88703 100644 --- a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp @@ -45,11 +45,11 @@ class ItemizedFilter : public FieldCacheTermsFilter ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - + virtual ~ItemizedFilter() { } @@ -64,17 +64,17 @@ class ItemizedFilter : public FieldCacheTermsFilter } }; -/// TestExplanations subclass that builds up super crazy complex queries on the assumption that +/// TestExplanations subclass that builds up super crazy complex queries on the assumption that /// if the explanations work out right for them, they should work for anything. -class ComplexExplanationsOfNonMatchesFixture : public ExplanationsFixture +class ComplexExplanationsOfNonMatchesTest : public ExplanationsFixture { public: - ComplexExplanationsOfNonMatchesFixture() + ComplexExplanationsOfNonMatchesTest() { searcher->setSimilarity(createQnorm1Similarity()); } - - virtual ~ComplexExplanationsOfNonMatchesFixture() + + virtual ~ComplexExplanationsOfNonMatchesTest() { } @@ -86,7 +86,7 @@ class ComplexExplanationsOfNonMatchesFixture : public ExplanationsFixture public: using ExplanationsFixture::qtest; - + /// ignore matches and focus on non-matches virtual void qtest(QueryPtr q, Collection expDocNrs) { @@ -94,9 +94,7 @@ class ComplexExplanationsOfNonMatchesFixture : public ExplanationsFixture } }; -BOOST_FIXTURE_TEST_SUITE(ComplexExplanationsOfNonMatchesTest, ComplexExplanationsOfNonMatchesFixture) - -BOOST_AUTO_TEST_CASE(test1) +TEST_F(ComplexExplanationsOfNonMatchesTest, test1) { BooleanQueryPtr q = newLucene(); @@ -137,7 +135,7 @@ BOOST_AUTO_TEST_CASE(test1) qtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(test2) +TEST_F(ComplexExplanationsOfNonMatchesTest, test2) { BooleanQueryPtr q = newLucene(); @@ -179,31 +177,31 @@ BOOST_AUTO_TEST_CASE(test2) qtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testT3) +TEST_F(ComplexExplanationsOfNonMatchesTest, testT3) { bqtest(L"w1^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMA3) +TEST_F(ComplexExplanationsOfNonMatchesTest, testMA3) { QueryPtr q = newLucene(); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ5) +TEST_F(ComplexExplanationsOfNonMatchesTest, testFQ5) { bqtest(newLucene(qp->parse(L"xx^0"), newLucene(newCollection(1, 3))), newCollection(3)); } -BOOST_AUTO_TEST_CASE(testCSQ4) +TEST_F(ComplexExplanationsOfNonMatchesTest, testCSQ4) { QueryPtr q = newLucene(newLucene(newCollection(3))); q->setBoost(0); bqtest(q, newCollection(3)); } -BOOST_AUTO_TEST_CASE(testDMQ10) +TEST_F(ComplexExplanationsOfNonMatchesTest, testDMQ10) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); @@ -212,7 +210,7 @@ BOOST_AUTO_TEST_CASE(testDMQ10) bqtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ7) +TEST_F(ComplexExplanationsOfNonMatchesTest, testMPQ7) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -222,74 +220,74 @@ BOOST_AUTO_TEST_CASE(testMPQ7) bqtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testBQ12) +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ12) { qtest(L"w1 w2^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ13) +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ13) { qtest(L"w1 -w5^0.0", newCollection(1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ18) +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ18) { qtest(L"+w1^0.0 w2", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ21) +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ21) { bqtest(L"(+w1 w2)^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ22) +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ22) { bqtest(L"(+w1^0.0 w2)^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testST3) +TEST_F(ComplexExplanationsOfNonMatchesTest, testST3) { SpanQueryPtr q = st(L"w1"); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testST6) +TEST_F(ComplexExplanationsOfNonMatchesTest, testST6) { SpanQueryPtr q = st(L"xx"); q->setBoost(0); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSF3) +TEST_F(ComplexExplanationsOfNonMatchesTest, testSF3) { SpanQueryPtr q = sf(L"w1", 1); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSF7) +TEST_F(ComplexExplanationsOfNonMatchesTest, testSF7) { SpanQueryPtr q = sf(L"xx", 3); q->setBoost(0); bqtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot3) +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot3) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot6) +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot6) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot8) +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot8) { SpanQueryPtr f = snear(L"w1", L"w3", 10, true); f->setBoost(0); @@ -297,12 +295,10 @@ BOOST_AUTO_TEST_CASE(testSNot8) qtest(q, newCollection(0, 1, 3)); } -BOOST_AUTO_TEST_CASE(testSNot9) +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot9) { SpanQueryPtr t = st(L"xx"); t->setBoost(0); SpanQueryPtr q = snot(snear(L"w1", L"w3", 10, true), t); qtest(q, newCollection(0, 1, 3)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/ComplexExplanationsTest.cpp b/src/test/search/ComplexExplanationsTest.cpp index 3edb8a62..d30af4f1 100644 --- a/src/test/search/ComplexExplanationsTest.cpp +++ b/src/test/search/ComplexExplanationsTest.cpp @@ -44,11 +44,11 @@ class ItemizedFilter : public FieldCacheTermsFilter ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - + virtual ~ItemizedFilter() { } @@ -63,17 +63,17 @@ class ItemizedFilter : public FieldCacheTermsFilter } }; -/// TestExplanations subclass that builds up super crazy complex queries on the assumption that +/// TestExplanations subclass that builds up super crazy complex queries on the assumption that /// if the explanations work out right for them, they should work for anything. -class ComplexExplanationsFixture : public ExplanationsFixture +class ComplexExplanationsTest : public ExplanationsFixture { public: - ComplexExplanationsFixture() + ComplexExplanationsTest() { searcher->setSimilarity(createQnorm1Similarity()); } - - virtual ~ComplexExplanationsFixture() + + virtual ~ComplexExplanationsTest() { } @@ -84,9 +84,7 @@ class ComplexExplanationsFixture : public ExplanationsFixture } }; -BOOST_FIXTURE_TEST_SUITE(ComplexExplanationsTest, ComplexExplanationsFixture) - -BOOST_AUTO_TEST_CASE(test1) +TEST_F(ComplexExplanationsTest, test1) { BooleanQueryPtr q = newLucene(); @@ -127,7 +125,7 @@ BOOST_AUTO_TEST_CASE(test1) qtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(test2) +TEST_F(ComplexExplanationsTest, test2) { BooleanQueryPtr q = newLucene(); @@ -169,31 +167,31 @@ BOOST_AUTO_TEST_CASE(test2) qtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testT3) +TEST_F(ComplexExplanationsTest, testT3) { bqtest(L"w1^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMA3) +TEST_F(ComplexExplanationsTest, testMA3) { QueryPtr q = newLucene(); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ5) +TEST_F(ComplexExplanationsTest, testFQ5) { bqtest(newLucene(qp->parse(L"xx^0"), newLucene(newCollection(1, 3))), newCollection(3)); } -BOOST_AUTO_TEST_CASE(testCSQ4) +TEST_F(ComplexExplanationsTest, testCSQ4) { QueryPtr q = newLucene(newLucene(newCollection(3))); q->setBoost(0); bqtest(q, newCollection(3)); } -BOOST_AUTO_TEST_CASE(testDMQ10) +TEST_F(ComplexExplanationsTest, testDMQ10) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); @@ -202,7 +200,7 @@ BOOST_AUTO_TEST_CASE(testDMQ10) bqtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ7) +TEST_F(ComplexExplanationsTest, testMPQ7) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -212,74 +210,74 @@ BOOST_AUTO_TEST_CASE(testMPQ7) bqtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testBQ12) +TEST_F(ComplexExplanationsTest, testBQ12) { qtest(L"w1 w2^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ13) +TEST_F(ComplexExplanationsTest, testBQ13) { qtest(L"w1 -w5^0.0", newCollection(1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ18) +TEST_F(ComplexExplanationsTest, testBQ18) { qtest(L"+w1^0.0 w2", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ21) +TEST_F(ComplexExplanationsTest, testBQ21) { bqtest(L"(+w1 w2)^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ22) +TEST_F(ComplexExplanationsTest, testBQ22) { bqtest(L"(+w1^0.0 w2)^0.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testST3) +TEST_F(ComplexExplanationsTest, testST3) { SpanQueryPtr q = st(L"w1"); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testST6) +TEST_F(ComplexExplanationsTest, testST6) { SpanQueryPtr q = st(L"xx"); q->setBoost(0); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSF3) +TEST_F(ComplexExplanationsTest, testSF3) { SpanQueryPtr q = sf(L"w1", 1); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSF7) +TEST_F(ComplexExplanationsTest, testSF7) { SpanQueryPtr q = sf(L"xx", 3); q->setBoost(0); bqtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot3) +TEST_F(ComplexExplanationsTest, testSNot3) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot6) +TEST_F(ComplexExplanationsTest, testSNot6) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot8) +TEST_F(ComplexExplanationsTest, testSNot8) { SpanQueryPtr f = snear(L"w1", L"w3", 10, true); f->setBoost(0); @@ -287,12 +285,10 @@ BOOST_AUTO_TEST_CASE(testSNot8) qtest(q, newCollection(0, 1, 3)); } -BOOST_AUTO_TEST_CASE(testSNot9) +TEST_F(ComplexExplanationsTest, testSNot9) { SpanQueryPtr t = st(L"xx"); t->setBoost(0); SpanQueryPtr q = snot(snear(L"w1", L"w3", 10, true), t); qtest(q, newCollection(0, 1, 3)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/CustomSearcherSortTest.cpp b/src/test/search/CustomSearcherSortTest.cpp index 49de26b0..fc692ae1 100644 --- a/src/test/search/CustomSearcherSortTest.cpp +++ b/src/test/search/CustomSearcherSortTest.cpp @@ -35,12 +35,12 @@ class CustomSearcher : public IndexSearcher { this->switcher = switcher; } - + CustomSearcher(IndexReaderPtr r, int32_t switcher) : IndexSearcher(r) { this->switcher = switcher; } - + virtual ~CustomSearcher() { } @@ -56,7 +56,7 @@ class CustomSearcher : public IndexSearcher bq->add(newLucene(newLucene(L"mandant", StringUtils::toString(switcher))), BooleanClause::MUST); return IndexSearcher::search(bq, filter, n, sort); } - + virtual TopDocsPtr search(QueryPtr query, FilterPtr filter, int32_t n) { BooleanQueryPtr bq = newLucene(); @@ -66,17 +66,17 @@ class CustomSearcher : public IndexSearcher } }; -class CustomSearcherSortFixture : public LuceneTestFixture +class CustomSearcherSortTest : public LuceneTestFixture { public: - CustomSearcherSortFixture() + CustomSearcherSortTest() { random = newLucene(); index = getIndex(); query = newLucene(newLucene(L"content", L"test")); } - - virtual ~CustomSearcherSortFixture() + + virtual ~CustomSearcherSortTest() { } @@ -84,7 +84,7 @@ class CustomSearcherSortFixture : public LuceneTestFixture DirectoryPtr index; QueryPtr query; RandomPtr random; - + static const int32_t INDEX_SIZE; public: @@ -107,14 +107,14 @@ class CustomSearcherSortFixture : public LuceneTestFixture writer->close(); return indexStore; } - + String getLuceneDate() { DateTools::setDateOrder(DateTools::DATEORDER_DMY); boost::posix_time::ptime base = DateTools::parseDate(L"01/01/1980"); return DateTools::timeToString(MiscUtils::getTimeMillis(base) + random->nextInt() - INT_MIN, DateTools::RESOLUTION_DAY); } - + /// make sure the documents returned by the search match the expected list void matchHits(SearcherPtr searcher, SortPtr sort) { @@ -129,19 +129,19 @@ class CustomSearcherSortFixture : public LuceneTestFixture // now make a query using the sort criteria Collection resultSort = searcher->search (query, FilterPtr(), 1000, sort)->scoreDocs; checkHits(resultSort); // check for duplicates - + // besides the sorting both sets of hits must be identical for (int32_t hitid = 0; hitid < resultSort.size(); ++hitid) { int32_t idHitDate = resultSort[hitid]->doc; // document ID from sorted search - BOOST_CHECK(resultMap.contains(idHitDate)); // same ID must be in the Map from the rank-sorted search + EXPECT_TRUE(resultMap.contains(idHitDate)); // same ID must be in the Map from the rank-sorted search // every hit must appear once in both result sets --> remove it from the Map. // At the end the Map must be empty! resultMap.remove(idHitDate); } - BOOST_CHECK(resultMap.empty()); + EXPECT_TRUE(resultMap.empty()); } - + void checkHits(Collection hits) { if (hits) @@ -150,19 +150,17 @@ class CustomSearcherSortFixture : public LuceneTestFixture for (int32_t docnum = 0; docnum < hits.size(); ++docnum) { int32_t luceneId = hits[docnum]->doc; - BOOST_CHECK(!idMap.contains(luceneId)); + EXPECT_TRUE(!idMap.contains(luceneId)); idMap.put(luceneId, docnum); } } } }; -const int32_t CustomSearcherSortFixture::INDEX_SIZE = 2000; - -BOOST_FIXTURE_TEST_SUITE(CustomSearcherSortTest, CustomSearcherSortFixture) +const int32_t CustomSearcherSortTest::INDEX_SIZE = 2000; /// Run the test using two CustomSearcher instances. -BOOST_AUTO_TEST_CASE(testFieldSortCustomSearcher) +TEST_F(CustomSearcherSortTest, testFieldSortCustomSearcher) { SortPtr custSort = newLucene(newCollection(newLucene(L"publicationDate_", SortField::STRING), SortField::FIELD_SCORE())); SearcherPtr searcher = newLucene(index, 2); @@ -170,8 +168,8 @@ BOOST_AUTO_TEST_CASE(testFieldSortCustomSearcher) matchHits(searcher, custSort); } -/// Run the test using one CustomSearcher wrapped by a MultiSearcher. -BOOST_AUTO_TEST_CASE(testFieldSortSingleSearcher) +/// Run the test using one CustomSearcher wrapped by a MultiSearcher. +TEST_F(CustomSearcherSortTest, testFieldSortSingleSearcher) { SortPtr custSort = newLucene(newCollection(newLucene(L"publicationDate_", SortField::STRING), SortField::FIELD_SCORE())); SearcherPtr searcher = newLucene(newCollection(newLucene(index, 2))); @@ -179,13 +177,11 @@ BOOST_AUTO_TEST_CASE(testFieldSortSingleSearcher) matchHits(searcher, custSort); } -/// Run the test using two CustomSearcher instances. -BOOST_AUTO_TEST_CASE(testFieldSortMultiCustomSearcher) +/// Run the test using two CustomSearcher instances. +TEST_F(CustomSearcherSortTest, testFieldSortMultiCustomSearcher) { SortPtr custSort = newLucene(newCollection(newLucene(L"publicationDate_", SortField::STRING), SortField::FIELD_SCORE())); SearcherPtr searcher = newLucene(newCollection(newLucene(index, 0), newLucene(index, 2))); // search and check hits matchHits(searcher, custSort); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/DateFilterTest.cpp b/src/test/search/DateFilterTest.cpp index 765e53ca..bd8a3030 100644 --- a/src/test/search/DateFilterTest.cpp +++ b/src/test/search/DateFilterTest.cpp @@ -22,9 +22,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DateFilterTest, LuceneTestFixture) +typedef LuceneTestFixture DateFilterTest; -BOOST_AUTO_TEST_CASE(testBefore) +TEST_F(DateFilterTest, testBefore) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(testBefore) // filter that should discard matches TermRangeFilterPtr df2 = newLucene(L"datefield", DateTools::timeToString(0, DateTools::RESOLUTION_MILLISECOND), DateTools::timeToString(now - 2000, DateTools::RESOLUTION_MILLISECOND), true, false); - + // search something that doesn't exist with DateFilter QueryPtr query1 = newLucene(newLucene(L"body", L"NoMatchForThis")); @@ -56,26 +56,26 @@ BOOST_AUTO_TEST_CASE(testBefore) // ensure that queries return expected results without DateFilter first Collection result = searcher->search(query1, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = searcher->search(query2, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); // run queries with DateFilter result = searcher->search(query1, df1, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = searcher->search(query1, df2, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = searcher->search(query2, df1, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); - + EXPECT_EQ(1, result.size()); + result = searcher->search(query2, df2, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); } -BOOST_AUTO_TEST_CASE(testAfter) +TEST_F(DateFilterTest, testAfter) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(testAfter) // filter that should discard matches TermRangeFilterPtr df2 = newLucene(L"datefield", DateTools::timeToString(now + 999999, DateTools::RESOLUTION_MILLISECOND), DateTools::timeToString(now + 999999999, DateTools::RESOLUTION_MILLISECOND), false, true); - + // search something that doesn't exist with DateFilter QueryPtr query1 = newLucene(newLucene(L"body", L"NoMatchForThis")); @@ -107,23 +107,21 @@ BOOST_AUTO_TEST_CASE(testAfter) // ensure that queries return expected results without DateFilter first Collection result = searcher->search(query1, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = searcher->search(query2, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); // run queries with DateFilter result = searcher->search(query1, df1, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = searcher->search(query1, df2, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = searcher->search(query2, df1, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); - + EXPECT_EQ(1, result.size()); + result = searcher->search(query2, df2, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/DateSortTest.cpp b/src/test/search/DateSortTest.cpp index 50b24655..bd8c2a54 100644 --- a/src/test/search/DateSortTest.cpp +++ b/src/test/search/DateSortTest.cpp @@ -22,10 +22,10 @@ using namespace Lucene; -class DateSortFixture : public LuceneTestFixture +class DateSortTest : public LuceneTestFixture { public: - DateSortFixture() + DateSortTest() { // Create an index writer. directory = newLucene(); @@ -34,9 +34,9 @@ class DateSortFixture : public LuceneTestFixture // oldest doc: // Add the first document. text = "Document 1" dateTime = Oct 10 03:25:22 EDT 2007 writer->addDocument(createDocument(L"Document 1", 1192001122000LL)); - // Add the second document. text = "Document 2" dateTime = Oct 10 03:25:26 EDT 2007 + // Add the second document. text = "Document 2" dateTime = Oct 10 03:25:26 EDT 2007 writer->addDocument(createDocument(L"Document 2", 1192001126000LL)); - // Add the third document. text = "Document 3" dateTime = Oct 11 07:12:13 EDT 2007 + // Add the third document. text = "Document 3" dateTime = Oct 11 07:12:13 EDT 2007 writer->addDocument(createDocument(L"Document 3", 1192101133000LL)); // Add the fourth document. text = "Document 4" dateTime = Oct 11 08:02:09 EDT 2007 writer->addDocument(createDocument(L"Document 4", 1192104129000LL)); @@ -47,15 +47,15 @@ class DateSortFixture : public LuceneTestFixture writer->optimize(); writer->close(); } - - virtual ~DateSortFixture() + + virtual ~DateSortTest() { } protected: static const String TEXT_FIELD; static const String DATE_TIME_FIELD; - + DirectoryPtr directory; public: @@ -76,12 +76,10 @@ class DateSortFixture : public LuceneTestFixture } }; -const String DateSortFixture::TEXT_FIELD = L"text"; -const String DateSortFixture::DATE_TIME_FIELD = L"dateTime"; - -BOOST_FIXTURE_TEST_SUITE(DateSortTest, DateSortFixture) +const String DateSortTest::TEXT_FIELD = L"text"; +const String DateSortTest::DATE_TIME_FIELD = L"dateTime"; -BOOST_AUTO_TEST_CASE(testReverseDateSort) +TEST_F(DateSortTest, testReverseDateSort) { IndexSearcherPtr searcher = newLucene(directory, true); @@ -100,7 +98,7 @@ BOOST_AUTO_TEST_CASE(testReverseDateSort) actualOrder[i] = text; } searcher->close(); - + // Set up the expected order (ie. Document 5, 4, 3, 2, 1). Collection expectedOrder = Collection::newInstance(5); expectedOrder[0] = L"Document 5"; @@ -109,7 +107,5 @@ BOOST_AUTO_TEST_CASE(testReverseDateSort) expectedOrder[3] = L"Document 2"; expectedOrder[4] = L"Document 1"; - BOOST_CHECK(expectedOrder.equals(actualOrder)); + EXPECT_TRUE(expectedOrder.equals(actualOrder)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/DisjunctionMaxQueryTest.cpp b/src/test/search/DisjunctionMaxQueryTest.cpp index e2a585f5..734e22fc 100644 --- a/src/test/search/DisjunctionMaxQueryTest.cpp +++ b/src/test/search/DisjunctionMaxQueryTest.cpp @@ -43,22 +43,22 @@ class DisjunctionMaxSimilarity : public DefaultSimilarity else return 0.0; } - + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - + virtual double idf(int32_t docFreq, int32_t numDocs) { return 1.0; } }; -class DisjunctionMaxQueryFixture : public LuceneTestFixture +class DisjunctionMaxQueryTest : public LuceneTestFixture { public: - DisjunctionMaxQueryFixture() + DisjunctionMaxQueryTest() { sim = newLucene(); @@ -67,7 +67,7 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture writer->setSimilarity(sim); // hed is the most important field, dek is secondary - + // d1 is an "ok" match for: albino elephant { DocumentPtr d1 = newLucene(); @@ -76,7 +76,7 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture d1->add(newLucene(L"dek", L"elephant", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(d1); } - + // d2 is a "good" match for: albino elephant { DocumentPtr d2 = newLucene(); @@ -86,7 +86,7 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture d2->add(newLucene(L"dek", L"elephant", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(d2); } - + // d3 is a "better" match for: albino elephant { DocumentPtr d3 = newLucene(); @@ -95,7 +95,7 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture d3->add(newLucene(L"hed", L"elephant", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(d3); } - + // d4 is the "best" match for: albino elephant { DocumentPtr d4 = newLucene(); @@ -105,15 +105,15 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture d4->add(newLucene(L"dek", L"albino", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(d4); } - + writer->close(); r = IndexReader::open(index, true); s = newLucene(r); s->setSimilarity(sim); } - - virtual ~DisjunctionMaxQueryFixture() + + virtual ~DisjunctionMaxQueryTest() { } @@ -122,7 +122,7 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture DirectoryPtr index; IndexReaderPtr r; IndexSearcherPtr s; - + static const double SCORE_COMP_THRESH; protected: @@ -130,7 +130,7 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture { return newLucene(newLucene(f, t)); } - + QueryPtr tq(const String& f, const String& t, double b) { QueryPtr q = tq(f, t); @@ -139,11 +139,9 @@ class DisjunctionMaxQueryFixture : public LuceneTestFixture } }; -const double DisjunctionMaxQueryFixture::SCORE_COMP_THRESH = 0.00001; +const double DisjunctionMaxQueryTest::SCORE_COMP_THRESH = 0.00001; -BOOST_FIXTURE_TEST_SUITE(DisjunctionMaxQueryTest, DisjunctionMaxQueryFixture) - -BOOST_AUTO_TEST_CASE(testSkipToFirsttimeMiss) +TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeMiss) { DisjunctionMaxQueryPtr dq = newLucene(0.0); dq->add(tq(L"id", L"d1")); @@ -153,10 +151,10 @@ BOOST_AUTO_TEST_CASE(testSkipToFirsttimeMiss) WeightPtr dw = dq->weight(s); ScorerPtr ds = dw->scorer(r, true, false); - BOOST_CHECK_EQUAL(ds->advance(3), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(ds->advance(3), DocIdSetIterator::NO_MORE_DOCS); } -BOOST_AUTO_TEST_CASE(testSkipToFirsttimeHit) +TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeHit) { DisjunctionMaxQueryPtr dq = newLucene(0.0); dq->add(tq(L"dek", L"albino")); @@ -166,11 +164,11 @@ BOOST_AUTO_TEST_CASE(testSkipToFirsttimeHit) WeightPtr dw = dq->weight(s); ScorerPtr ds = dw->scorer(r, true, false); - BOOST_CHECK_NE(ds->advance(3), DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_EQUAL(L"d4", r->document(ds->docID())->get(L"id")); + EXPECT_NE(ds->advance(3), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(L"d4", r->document(ds->docID())->get(L"id")); } -BOOST_AUTO_TEST_CASE(testSimpleEqualScores1) +TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores1) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(tq(L"hed", L"albino")); @@ -179,14 +177,14 @@ BOOST_AUTO_TEST_CASE(testSimpleEqualScores1) QueryUtils::check(q, s); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, h.size()); - + EXPECT_EQ(4, h.size()); + double score = h[0]->score; for (int32_t i = 1; i < h.size(); ++i) - BOOST_CHECK_CLOSE_FRACTION(score, h[i]->score, SCORE_COMP_THRESH); + EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); } -BOOST_AUTO_TEST_CASE(testSimpleEqualScores2) +TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores2) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(tq(L"dek", L"albino")); @@ -195,14 +193,14 @@ BOOST_AUTO_TEST_CASE(testSimpleEqualScores2) QueryUtils::check(q, s); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, h.size()); - + EXPECT_EQ(3, h.size()); + double score = h[0]->score; for (int32_t i = 1; i < h.size(); ++i) - BOOST_CHECK_CLOSE_FRACTION(score, h[i]->score, SCORE_COMP_THRESH); + EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); } -BOOST_AUTO_TEST_CASE(testSimpleEqualScores3) +TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores3) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(tq(L"hed", L"albino")); @@ -213,14 +211,14 @@ BOOST_AUTO_TEST_CASE(testSimpleEqualScores3) QueryUtils::check(q, s); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, h.size()); - + EXPECT_EQ(4, h.size()); + double score = h[0]->score; for (int32_t i = 1; i < h.size(); ++i) - BOOST_CHECK_CLOSE_FRACTION(score, h[i]->score, SCORE_COMP_THRESH); + EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); } -BOOST_AUTO_TEST_CASE(testSimpleTiebreaker) +TEST_F(DisjunctionMaxQueryTest, testSimpleTiebreaker) { DisjunctionMaxQueryPtr q = newLucene(0.01); q->add(tq(L"dek", L"albino")); @@ -229,16 +227,16 @@ BOOST_AUTO_TEST_CASE(testSimpleTiebreaker) QueryUtils::check(q, s); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, h.size()); - BOOST_CHECK_EQUAL(L"d2", s->doc(h[0]->doc)->get(L"id")); + EXPECT_EQ(3, h.size()); + EXPECT_EQ(L"d2", s->doc(h[0]->doc)->get(L"id")); double score0 = h[0]->score; double score1 = h[1]->score; double score2 = h[2]->score; - BOOST_CHECK(score0 > score1); - BOOST_CHECK_CLOSE_FRACTION(score1, score2, SCORE_COMP_THRESH); + EXPECT_TRUE(score0 > score1); + EXPECT_NEAR(score1, score2, SCORE_COMP_THRESH); } -BOOST_AUTO_TEST_CASE(testBooleanRequiredEqualScores) +TEST_F(DisjunctionMaxQueryTest, testBooleanRequiredEqualScores) { BooleanQueryPtr q = newLucene(); { @@ -255,17 +253,17 @@ BOOST_AUTO_TEST_CASE(testBooleanRequiredEqualScores) q->add(q2, BooleanClause::MUST); QueryUtils::check(q2, s); } - + QueryUtils::check(q, s); - + Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, h.size()); + EXPECT_EQ(3, h.size()); double score = h[0]->score; for (int32_t i = 1; i < h.size(); ++i) - BOOST_CHECK_CLOSE_FRACTION(score, h[i]->score, SCORE_COMP_THRESH); + EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); } -BOOST_AUTO_TEST_CASE(testBooleanOptionalNoTiebreaker) +TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalNoTiebreaker) { BooleanQueryPtr q = newLucene(); { @@ -280,20 +278,20 @@ BOOST_AUTO_TEST_CASE(testBooleanOptionalNoTiebreaker) q2->add(tq(L"dek", L"elephant")); q->add(q2, BooleanClause::SHOULD); } - + QueryUtils::check(q, s); - + Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, h.size()); + EXPECT_EQ(4, h.size()); double score = h[0]->score; for (int32_t i = 1; i < h.size() - 1; ++i) - BOOST_CHECK_CLOSE_FRACTION(score, h[i]->score, SCORE_COMP_THRESH); - BOOST_CHECK_EQUAL(L"d1", s->doc(h[h.size() - 1]->doc)->get(L"id")); + EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); + EXPECT_EQ(L"d1", s->doc(h[h.size() - 1]->doc)->get(L"id")); double score1 = h[h.size() - 1]->score; - BOOST_CHECK(score > score1); + EXPECT_TRUE(score > score1); } -BOOST_AUTO_TEST_CASE(testBooleanOptionalWithTiebreaker) +TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalWithTiebreaker) { BooleanQueryPtr q = newLucene(); { @@ -308,12 +306,12 @@ BOOST_AUTO_TEST_CASE(testBooleanOptionalWithTiebreaker) q2->add(tq(L"dek", L"elephant")); q->add(q2, BooleanClause::SHOULD); } - + QueryUtils::check(q, s); - + Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, h.size()); - + EXPECT_EQ(4, h.size()); + double score0 = h[0]->score; double score1 = h[1]->score; double score2 = h[2]->score; @@ -324,17 +322,17 @@ BOOST_AUTO_TEST_CASE(testBooleanOptionalWithTiebreaker) String doc2 = s->doc(h[2]->doc)->get(L"id"); String doc3 = s->doc(h[3]->doc)->get(L"id"); - BOOST_CHECK(doc0 == L"d2" || doc0 == L"d4"); - BOOST_CHECK(doc1 == L"d2" || doc1 == L"d4"); - BOOST_CHECK_CLOSE_FRACTION(score0, score1, SCORE_COMP_THRESH); - BOOST_CHECK_EQUAL(L"d3", doc2); - BOOST_CHECK(score1 > score2); + EXPECT_TRUE(doc0 == L"d2" || doc0 == L"d4"); + EXPECT_TRUE(doc1 == L"d2" || doc1 == L"d4"); + EXPECT_NEAR(score0, score1, SCORE_COMP_THRESH); + EXPECT_EQ(L"d3", doc2); + EXPECT_TRUE(score1 > score2); - BOOST_CHECK_EQUAL(L"d1", doc3); - BOOST_CHECK(score2 > score3); + EXPECT_EQ(L"d1", doc3); + EXPECT_TRUE(score2 > score3); } -BOOST_AUTO_TEST_CASE(testBooleanOptionalWithTiebreakerAndBoost) +TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalWithTiebreakerAndBoost) { BooleanQueryPtr q = newLucene(); { @@ -349,12 +347,12 @@ BOOST_AUTO_TEST_CASE(testBooleanOptionalWithTiebreakerAndBoost) q2->add(tq(L"dek", L"elephant")); q->add(q2, BooleanClause::SHOULD); } - + QueryUtils::check(q, s); - + Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, h.size()); - + EXPECT_EQ(4, h.size()); + double score0 = h[0]->score; double score1 = h[1]->score; double score2 = h[2]->score; @@ -365,9 +363,7 @@ BOOST_AUTO_TEST_CASE(testBooleanOptionalWithTiebreakerAndBoost) String doc2 = s->doc(h[2]->doc)->get(L"id"); String doc3 = s->doc(h[3]->doc)->get(L"id"); - BOOST_CHECK(score0 > score1); - BOOST_CHECK(score1 > score2); - BOOST_CHECK(score2 > score3); + EXPECT_TRUE(score0 > score1); + EXPECT_TRUE(score1 > score2); + EXPECT_TRUE(score2 > score3); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/DocBoostTest.cpp b/src/test/search/DocBoostTest.cpp index 2877d485..89347dec 100644 --- a/src/test/search/DocBoostTest.cpp +++ b/src/test/search/DocBoostTest.cpp @@ -19,7 +19,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DocBoostTest, LuceneTestFixture) +typedef LuceneTestFixture DocBoostTest; namespace TestDocBoost { @@ -31,32 +31,32 @@ namespace TestDocBoost this->scores = scores; this->base = 0; } - + virtual ~BoostCollector() { } - + public: Collection scores; int32_t base; ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { scores[doc + base] = scorer->score(); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -64,7 +64,7 @@ namespace TestDocBoost }; } -BOOST_AUTO_TEST_CASE(testDocBoost) +TEST_F(DocBoostTest, testDocBoost) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -95,13 +95,11 @@ BOOST_AUTO_TEST_CASE(testDocBoost) Collection scores = Collection::newInstance(4); IndexSearcherPtr searcher = newLucene(store, true); searcher->search(newLucene(newLucene(L"field", L"word")), newLucene(scores)); - + double lastScore = 0.0; for (int32_t i = 0; i < 4; ++i) { - BOOST_CHECK(scores[i] > lastScore); + EXPECT_TRUE(scores[i] > lastScore); lastScore = scores[i]; } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/DocIdSetTest.cpp b/src/test/search/DocIdSetTest.cpp index 3fea8212..935eaa6f 100644 --- a/src/test/search/DocIdSetTest.cpp +++ b/src/test/search/DocIdSetTest.cpp @@ -21,7 +21,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DocIdSetTest, LuceneTestFixture) +typedef LuceneTestFixture DocIdSetTest; static const int32_t maxdoc = 10; @@ -34,25 +34,25 @@ namespace TestFilteredDocIdSet { docid = -1; } - + virtual ~TestDocIdSetIterator() { } - + public: int32_t docid; - + public: virtual int32_t docID() { return docid; } - + virtual int32_t nextDoc() { return ++docid < maxdoc ? docid : (docid = NO_MORE_DOCS); } - + virtual int32_t advance(int32_t target) { while (nextDoc() < target) @@ -61,32 +61,32 @@ namespace TestFilteredDocIdSet return docid; } }; - + class TestDocIdSet : public DocIdSet { public: virtual ~TestDocIdSet() { } - + public: virtual DocIdSetIteratorPtr iterator() { return newLucene(); } }; - + class TestFilteredDocIdSet : public FilteredDocIdSet { public: TestFilteredDocIdSet(DocIdSetPtr innerSet) : FilteredDocIdSet(innerSet) { } - + virtual ~TestFilteredDocIdSet() { } - + protected: virtual bool match(int32_t docid) { @@ -95,11 +95,11 @@ namespace TestFilteredDocIdSet }; } -BOOST_AUTO_TEST_CASE(testFilteredDocIdSet) +TEST_F(DocIdSetTest, testFilteredDocIdSet) { DocIdSetPtr innerSet = newLucene(); DocIdSetPtr filteredSet = newLucene(innerSet); - + DocIdSetIteratorPtr iter = filteredSet->iterator(); Collection docs = Collection::newInstance(); int32_t doc = iter->advance(3); @@ -109,9 +109,9 @@ BOOST_AUTO_TEST_CASE(testFilteredDocIdSet) while((doc = iter->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) docs.add(doc); } - + Collection answer = newCollection(4, 6, 8); - BOOST_CHECK(docs.equals(answer)); + EXPECT_TRUE(docs.equals(answer)); } namespace TestNullDocIdSet @@ -122,7 +122,7 @@ namespace TestNullDocIdSet virtual ~TestFilter() { } - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) { @@ -132,7 +132,7 @@ namespace TestNullDocIdSet } /// Tests that if a Filter produces a null DocIdSet, which is given to IndexSearcher, everything works fine -BOOST_AUTO_TEST_CASE(testNullDocIdSet) +TEST_F(DocIdSetTest, testNullDocIdSet) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -143,12 +143,10 @@ BOOST_AUTO_TEST_CASE(testNullDocIdSet) // First verify the document is searchable. IndexSearcherPtr searcher = newLucene(dir, true); - BOOST_CHECK_EQUAL(1, searcher->search(newLucene(), 10)->totalHits); - + EXPECT_EQ(1, searcher->search(newLucene(), 10)->totalHits); + // Now search with a Filter which returns a null DocIdSet FilterPtr f = newLucene(); - BOOST_CHECK_EQUAL(0, searcher->search(newLucene(), f, 10)->totalHits); + EXPECT_EQ(0, searcher->search(newLucene(), f, 10)->totalHits); searcher->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/ElevationComparatorTest.cpp b/src/test/search/ElevationComparatorTest.cpp index 7c06a82e..77bb7816 100644 --- a/src/test/search/ElevationComparatorTest.cpp +++ b/src/test/search/ElevationComparatorTest.cpp @@ -38,7 +38,7 @@ class ElevationFieldComparator : public FieldComparator this->values = Collection::newInstance(numHits); this->bottomVal = 0; } - + virtual ~ElevationFieldComparator() { } @@ -55,27 +55,27 @@ class ElevationFieldComparator : public FieldComparator { return values[slot2] - values[slot1]; // values will be small enough that there is no overflow concern } - + virtual void setBottom(int32_t slot) { bottomVal = values[slot]; } - + virtual int32_t compareBottom(int32_t doc) { return docVal(doc) - bottomVal; } - + virtual void copy(int32_t slot, int32_t doc) { values[slot] = docVal(doc); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { idIndex = FieldCache::DEFAULT()->getStringIndex(reader, fieldname); } - + virtual ComparableValue value(int32_t slot) { return values[slot]; @@ -96,7 +96,7 @@ class ElevationComparatorSource : public FieldComparatorSource { this->priority = priority; } - + virtual ~ElevationComparatorSource() { } @@ -111,15 +111,15 @@ class ElevationComparatorSource : public FieldComparatorSource } }; -class ElevationComparatorFixture : public LuceneTestFixture +class ElevationComparatorTest : public LuceneTestFixture { public: - ElevationComparatorFixture() + ElevationComparatorTest() { priority = MapStringInt::newInstance(); } - - virtual ~ElevationComparatorFixture() + + virtual ~ElevationComparatorTest() { } @@ -134,7 +134,7 @@ class ElevationComparatorFixture : public LuceneTestFixture doc->add(newLucene(vals[i], vals[i + 1], Field::STORE_YES, Field::INDEX_ANALYZED)); return doc; } - + void runTest(IndexSearcherPtr searcher, bool reversed) { BooleanQueryPtr newq = newLucene(false); @@ -154,24 +154,24 @@ class ElevationComparatorFixture : public LuceneTestFixture TopDocsPtr topDocs = topCollector->topDocs(0, 10); int32_t numDocsReturned = topDocs->scoreDocs.size(); - BOOST_CHECK_EQUAL(4, numDocsReturned); + EXPECT_EQ(4, numDocsReturned); // 0 and 3 were elevated - BOOST_CHECK_EQUAL(0, topDocs->scoreDocs[0]->doc); - BOOST_CHECK_EQUAL(3, topDocs->scoreDocs[1]->doc); - + EXPECT_EQ(0, topDocs->scoreDocs[0]->doc); + EXPECT_EQ(3, topDocs->scoreDocs[1]->doc); + if (reversed) { - BOOST_CHECK_EQUAL(2, topDocs->scoreDocs[2]->doc); - BOOST_CHECK_EQUAL(1, topDocs->scoreDocs[3]->doc); + EXPECT_EQ(2, topDocs->scoreDocs[2]->doc); + EXPECT_EQ(1, topDocs->scoreDocs[3]->doc); } else { - BOOST_CHECK_EQUAL(1, topDocs->scoreDocs[2]->doc); - BOOST_CHECK_EQUAL(2, topDocs->scoreDocs[3]->doc); + EXPECT_EQ(1, topDocs->scoreDocs[2]->doc); + EXPECT_EQ(2, topDocs->scoreDocs[3]->doc); } } - + QueryPtr getElevatedQuery(Collection vals) { BooleanQueryPtr q = newLucene(false); @@ -186,9 +186,7 @@ class ElevationComparatorFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(ElevationComparatorTest, ElevationComparatorFixture) - -BOOST_AUTO_TEST_CASE(testSorting) +TEST_F(ElevationComparatorTest, testSorting) { DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -213,5 +211,3 @@ BOOST_AUTO_TEST_CASE(testSorting) r->close(); directory->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/FieldCacheRangeFilterTest.cpp b/src/test/search/FieldCacheRangeFilterTest.cpp index 1b55c14c..ccf14360 100644 --- a/src/test/search/FieldCacheRangeFilterTest.cpp +++ b/src/test/search/FieldCacheRangeFilterTest.cpp @@ -24,9 +24,9 @@ using namespace Lucene; /// A basic 'positive' Unit test class for the FieldCacheRangeFilter class. -BOOST_FIXTURE_TEST_SUITE(FieldCacheRangeFilterTest, BaseTestRangeFilterFixture) +typedef BaseTestRangeFilterFixture FieldCacheRangeFilterTest; -BOOST_AUTO_TEST_CASE(testRangeFilterId) +TEST_F(FieldCacheRangeFilterTest, testRangeFilterId) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -39,79 +39,79 @@ BOOST_AUTO_TEST_CASE(testRangeFilterId) int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + EXPECT_EQ(numDocs, 1 + maxId - minId); QueryPtr q = newLucene(newLucene(L"body", L"body")); // test id, bounded on both ends - + FieldCacheRangeFilterPtr fcrf = FieldCacheRangeFilter::newStringRange(L"id", minIP, maxIP, true, true); Collection result = search->search(q, fcrf, numDocs)->scoreDocs; - BOOST_CHECK(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_TRUE(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, maxIP, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, maxIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, maxIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", medIP, maxIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + maxId - medId, result.size()); + EXPECT_EQ(1 + maxId - medId, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, medIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + medId - minId, result.size()); + EXPECT_EQ(1 + medId - minId, result.size()); // unbounded id result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", L"", L"", true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, L"", true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", L"", maxIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, L"", false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", L"", maxIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", medIP, maxIP, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(maxId - medId, result.size()); + EXPECT_EQ(maxId - medId, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, medIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(medId - minId, result.size()); + EXPECT_EQ(medId - minId, result.size()); // very small sets result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, minIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", medIP, medIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", maxIP, maxIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", minIP, minIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", L"", minIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", maxIP, maxIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", maxIP, L"", true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"id", medIP, medIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testFieldCacheRangeFilterRand) +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterRand) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -123,224 +123,224 @@ BOOST_AUTO_TEST_CASE(testFieldCacheRangeFilterRand) int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + EXPECT_EQ(numDocs, 1 + maxId - minId); QueryPtr q = newLucene(newLucene(L"body", L"body")); // test extremes, bounded on both ends - + Collection result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, maxRP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, maxRP, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, maxRP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, maxRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); // unbounded result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, L"", true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", L"", maxRP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, L"", false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", L"", maxRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); // very small sets result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, minRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); - + EXPECT_EQ(0, result.size()); + result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", maxRP, maxRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); - + EXPECT_EQ(0, result.size()); + result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", minRP, minRP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); - + EXPECT_EQ(1, result.size()); + result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", L"", minRP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); - + EXPECT_EQ(1, result.size()); + result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", maxRP, maxRP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); - + EXPECT_EQ(1, result.size()); + result = search->search(q, FieldCacheRangeFilter::newStringRange(L"rand", maxRP, L"", true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testFieldCacheRangeFilterInts) +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterInts) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); int32_t numDocs = reader->numDocs(); int32_t medId = ((maxId - minId) / 2); - - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + + EXPECT_EQ(numDocs, 1 + maxId - minId); QueryPtr q = newLucene(newLucene(L"body", L"body")); - + // test id, bounded on both ends - + FieldCacheRangeFilterPtr fcrf = FieldCacheRangeFilter::newIntRange(L"id", minId, maxId, true, true); Collection result = search->search(q, fcrf, numDocs)->scoreDocs; - BOOST_CHECK(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_TRUE(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(numDocs, result.size()); // test extremes, bounded on both ends - + result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, maxId, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, maxId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, maxId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", medId, maxId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + maxId - medId, result.size()); + EXPECT_EQ(1 + maxId - medId, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, medId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + medId - minId, result.size()); + EXPECT_EQ(1 + medId - minId, result.size()); // unbounded id result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", INT_MIN, INT_MAX, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, INT_MAX, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", INT_MIN, maxId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, INT_MAX, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", INT_MIN, maxId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", medId, maxId, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(maxId - medId, result.size()); + EXPECT_EQ(maxId - medId, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, medId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(medId - minId, result.size()); + EXPECT_EQ(medId - minId, result.size()); // very small sets result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, minId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", medId, medId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", maxId, maxId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", minId, minId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", INT_MIN, minId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", maxId, maxId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", maxId, INT_MAX, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newIntRange(L"id", medId, medId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testFieldCacheRangeFilterLongs) +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterLongs) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); int32_t numDocs = reader->numDocs(); int64_t medId = ((maxId - minId) / 2); - - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + + EXPECT_EQ(numDocs, 1 + maxId - minId); QueryPtr q = newLucene(newLucene(L"body", L"body")); - + // test id, bounded on both ends - + FieldCacheRangeFilterPtr fcrf = FieldCacheRangeFilter::newLongRange(L"id", minId, maxId, true, true); Collection result = search->search(q, fcrf, numDocs)->scoreDocs; - BOOST_CHECK(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_TRUE(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(numDocs, result.size()); // test extremes, bounded on both ends - + result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, (int64_t)maxId, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, (int64_t)maxId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, (int64_t)maxId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", medId, (int64_t)maxId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + maxId - medId, result.size()); + EXPECT_EQ(1 + maxId - medId, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, medId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + medId - minId, result.size()); + EXPECT_EQ(1 + medId - minId, result.size()); // unbounded id result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", LLONG_MIN, LLONG_MAX, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, LLONG_MAX, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", LLONG_MIN, (int64_t)maxId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, LLONG_MAX, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", LLONG_MIN, (int64_t)maxId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", medId, (int64_t)maxId, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(maxId - medId, result.size()); + EXPECT_EQ(maxId - medId, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, medId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(medId - minId, result.size()); + EXPECT_EQ(medId - minId, result.size()); // very small sets result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, (int64_t)minId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", medId, medId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)maxId, (int64_t)maxId, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)minId, (int64_t)minId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", LLONG_MIN, (int64_t)minId, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)maxId, (int64_t)maxId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", (int64_t)maxId, LLONG_MAX, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, FieldCacheRangeFilter::newLongRange(L"id", medId, medId, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testFieldCacheRangeFilterDoubles) +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterDoubles) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -348,29 +348,29 @@ BOOST_AUTO_TEST_CASE(testFieldCacheRangeFilterDoubles) int32_t numDocs = reader->numDocs(); double minIdO = (double)minId + 0.5; double medIdO = minIdO + (double)(maxId - minId) / 2.0; - + QueryPtr q = newLucene(newLucene(L"body", L"body")); Collection result = search->search(q, FieldCacheRangeFilter::newDoubleRange(L"id", minIdO, medIdO, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs / 2, result.size()); - + EXPECT_EQ(numDocs / 2, result.size()); + int32_t count = 0; result = search->search(q, FieldCacheRangeFilter::newDoubleRange(L"id", -DBL_MAX, medIdO, false, true), numDocs)->scoreDocs; count += result.size(); result = search->search(q, FieldCacheRangeFilter::newDoubleRange(L"id", medIdO, DBL_MAX, false, false), numDocs)->scoreDocs; count += result.size(); - BOOST_CHECK_EQUAL(numDocs, count); + EXPECT_EQ(numDocs, count); result = search->search(q, FieldCacheRangeFilter::newDoubleRange(L"id", std::numeric_limits::infinity(), DBL_MAX, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, FieldCacheRangeFilter::newDoubleRange(L"id", -DBL_MAX, -std::numeric_limits::infinity(), false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); } -BOOST_AUTO_TEST_CASE(testSparseIndex) +TEST_F(FieldCacheRangeFilterTest, testSparseIndex) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - + for (int32_t d = -20; d <= 20; ++d) { DocumentPtr doc = newLucene(); @@ -382,37 +382,35 @@ BOOST_AUTO_TEST_CASE(testSparseIndex) writer->optimize(); writer->deleteDocuments(newLucene(L"id", L"0")); writer->close(); - + IndexReaderPtr reader = IndexReader::open(dir, true); IndexSearcherPtr search = newLucene(reader); - BOOST_CHECK(reader->hasDeletions()); - + EXPECT_TRUE(reader->hasDeletions()); + QueryPtr q = newLucene(newLucene(L"body", L"body")); - + FieldCacheRangeFilterPtr fcrf = FieldCacheRangeFilter::newIntRange(L"id", -20, 20, true, true); Collection result = search->search(q, fcrf, 100)->scoreDocs; - BOOST_CHECK(!fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(40, result.size()); - + EXPECT_TRUE(!fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(40, result.size()); + fcrf = FieldCacheRangeFilter::newIntRange(L"id", 0, 20, true, true); result = search->search(q, fcrf, 100)->scoreDocs; - BOOST_CHECK(!fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(20, result.size()); - + EXPECT_TRUE(!fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(20, result.size()); + fcrf = FieldCacheRangeFilter::newIntRange(L"id", -20, 0, true, true); result = search->search(q, fcrf, 100)->scoreDocs; - BOOST_CHECK(!fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(20, result.size()); - + EXPECT_TRUE(!fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(20, result.size()); + fcrf = FieldCacheRangeFilter::newIntRange(L"id", 10, 20, true, true); result = search->search(q, fcrf, 100)->scoreDocs; - BOOST_CHECK(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(11, result.size()); - + EXPECT_TRUE(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(11, result.size()); + fcrf = FieldCacheRangeFilter::newIntRange(L"id", -20, -10, true, true); result = search->search(q, fcrf, 100)->scoreDocs; - BOOST_CHECK(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); - BOOST_CHECK_EQUAL(11, result.size()); + EXPECT_TRUE(fcrf->getDocIdSet(reader->getSequentialSubReaders()[0])->isCacheable()); + EXPECT_EQ(11, result.size()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/FieldCacheTermsFilterTest.cpp b/src/test/search/FieldCacheTermsFilterTest.cpp index 33a39340..32e845bc 100644 --- a/src/test/search/FieldCacheTermsFilterTest.cpp +++ b/src/test/search/FieldCacheTermsFilterTest.cpp @@ -20,9 +20,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(FieldCacheTermsFilterTest, LuceneTestFixture) +typedef LuceneTestFixture FieldCacheTermsFilterTest; -BOOST_AUTO_TEST_CASE(testMissingTerms) +TEST_F(FieldCacheTermsFilterTest, testMissingTerms) { String fieldName = L"field1"; MockRAMDirectoryPtr rd = newLucene(); @@ -42,16 +42,14 @@ BOOST_AUTO_TEST_CASE(testMissingTerms) MatchAllDocsQueryPtr q = newLucene(); Collection results = searcher->search(q, newLucene(fieldName, newCollection(L"5")), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, results.size()); + EXPECT_EQ(0, results.size()); results = searcher->search(q, newLucene(fieldName, newCollection(L"10")), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, results.size()); + EXPECT_EQ(1, results.size()); results = searcher->search(q, newLucene(fieldName, newCollection(L"10", L"20")), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(2, results.size()); + EXPECT_EQ(2, results.size()); reader->close(); rd->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/FieldCacheTest.cpp b/src/test/search/FieldCacheTest.cpp index 6bef9cbf..ae509ab2 100644 --- a/src/test/search/FieldCacheTest.cpp +++ b/src/test/search/FieldCacheTest.cpp @@ -17,10 +17,10 @@ using namespace Lucene; -class FieldCacheFixture : public LuceneTestFixture +class FieldCacheTest : public LuceneTestFixture { public: - FieldCacheFixture() + FieldCacheTest() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -40,52 +40,56 @@ class FieldCacheFixture : public LuceneTestFixture writer->close(); reader = IndexReader::open(directory, true); } - - virtual ~FieldCacheFixture() + + virtual ~FieldCacheTest() { } protected: IndexReaderPtr reader; - + public: static const int32_t NUM_DOCS; }; -const int32_t FieldCacheFixture::NUM_DOCS = 1000; - -BOOST_FIXTURE_TEST_SUITE(FieldCacheTest, FieldCacheFixture) +const int32_t FieldCacheTest::NUM_DOCS = 1000; -BOOST_AUTO_TEST_CASE(testFieldCache) +TEST_F(FieldCacheTest, testFieldCache) { FieldCachePtr cache = FieldCache::DEFAULT(); Collection doubles = cache->getDoubles(reader, L"theDouble"); - BOOST_CHECK_EQUAL(doubles.hashCode(), cache->getDoubles(reader, L"theDouble").hashCode()); - BOOST_CHECK_EQUAL(doubles.hashCode(), cache->getDoubles(reader, L"theDouble", FieldCache::DEFAULT_DOUBLE_PARSER()).hashCode()); - BOOST_CHECK_EQUAL(doubles.size(), NUM_DOCS); + EXPECT_EQ(doubles.hashCode(), cache->getDoubles(reader, L"theDouble").hashCode()); + EXPECT_EQ(doubles.hashCode(), cache->getDoubles(reader, L"theDouble", FieldCache::DEFAULT_DOUBLE_PARSER()).hashCode()); + EXPECT_EQ(doubles.size(), NUM_DOCS); for (int32_t i = 0; i < doubles.size(); ++i) - BOOST_CHECK_CLOSE_FRACTION(doubles[i], (DBL_MAX - i), 0.00001); - + { + StringStream first; + first.precision(5); + first << doubles[i]; + StringStream second; + second.precision(5); + second << (DBL_MAX - i); + EXPECT_EQ(first.str(), second.str()); + } + Collection longs = cache->getLongs(reader, L"theLong"); - BOOST_CHECK_EQUAL(longs.hashCode(), cache->getLongs(reader, L"theLong").hashCode()); - BOOST_CHECK_EQUAL(longs.hashCode(), cache->getLongs(reader, L"theLong", FieldCache::DEFAULT_LONG_PARSER()).hashCode()); - BOOST_CHECK_EQUAL(longs.size(), NUM_DOCS); + EXPECT_EQ(longs.hashCode(), cache->getLongs(reader, L"theLong").hashCode()); + EXPECT_EQ(longs.hashCode(), cache->getLongs(reader, L"theLong", FieldCache::DEFAULT_LONG_PARSER()).hashCode()); + EXPECT_EQ(longs.size(), NUM_DOCS); for (int32_t i = 0; i < longs.size(); ++i) - BOOST_CHECK_EQUAL(longs[i], (LLONG_MAX - i)); - + EXPECT_EQ(longs[i], (LLONG_MAX - i)); + Collection bytes = cache->getBytes(reader, L"theByte"); - BOOST_CHECK_EQUAL(bytes.hashCode(), cache->getBytes(reader, L"theByte").hashCode()); - BOOST_CHECK_EQUAL(bytes.hashCode(), cache->getBytes(reader, L"theByte", FieldCache::DEFAULT_BYTE_PARSER()).hashCode()); - BOOST_CHECK_EQUAL(bytes.size(), NUM_DOCS); + EXPECT_EQ(bytes.hashCode(), cache->getBytes(reader, L"theByte").hashCode()); + EXPECT_EQ(bytes.hashCode(), cache->getBytes(reader, L"theByte", FieldCache::DEFAULT_BYTE_PARSER()).hashCode()); + EXPECT_EQ(bytes.size(), NUM_DOCS); for (int32_t i = 0; i < bytes.size(); ++i) - BOOST_CHECK_EQUAL(bytes[i], (uint8_t)(UCHAR_MAX - i)); - + EXPECT_EQ(bytes[i], (uint8_t)(UCHAR_MAX - i)); + Collection ints = cache->getInts(reader, L"theInt"); - BOOST_CHECK_EQUAL(ints.hashCode(), cache->getInts(reader, L"theInt").hashCode()); - BOOST_CHECK_EQUAL(ints.hashCode(), cache->getInts(reader, L"theInt", FieldCache::DEFAULT_INT_PARSER()).hashCode()); - BOOST_CHECK_EQUAL(ints.size(), NUM_DOCS); + EXPECT_EQ(ints.hashCode(), cache->getInts(reader, L"theInt").hashCode()); + EXPECT_EQ(ints.hashCode(), cache->getInts(reader, L"theInt", FieldCache::DEFAULT_INT_PARSER()).hashCode()); + EXPECT_EQ(ints.size(), NUM_DOCS); for (int32_t i = 0; i < ints.size(); ++i) - BOOST_CHECK_EQUAL(ints[i], (INT_MAX - i)); + EXPECT_EQ(ints[i], (INT_MAX - i)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/FilteredQueryTest.cpp b/src/test/search/FilteredQueryTest.cpp index c99ab363..eb1c0067 100644 --- a/src/test/search/FilteredQueryTest.cpp +++ b/src/test/search/FilteredQueryTest.cpp @@ -71,7 +71,7 @@ class SingleDocTestFilter : public Filter { this->doc = doc; } - + virtual ~SingleDocTestFilter() { } @@ -88,10 +88,10 @@ class SingleDocTestFilter : public Filter } }; -class FilteredQueryFixture : public LuceneTestFixture +class FilteredQueryTest : public LuceneTestFixture { public: - FilteredQueryFixture() + FilteredQueryTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -123,8 +123,8 @@ class FilteredQueryFixture : public LuceneTestFixture query = newLucene(newLucene(L"field", L"three")); filter = newStaticFilterB(); } - - virtual ~FilteredQueryFixture() + + virtual ~FilteredQueryTest() { searcher->close(); directory->close(); @@ -141,52 +141,50 @@ class FilteredQueryFixture : public LuceneTestFixture { return newLucene(); } - + FilterPtr newStaticFilterB() { return newLucene(); } - + void checkScoreEquals(QueryPtr q1, QueryPtr q2) { Collection hits1 = searcher->search(q1, FilterPtr(), 1000)->scoreDocs; Collection hits2 = searcher->search (q2, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(hits1.size(), hits2.size()); - + EXPECT_EQ(hits1.size(), hits2.size()); + for (int32_t i = 0; i < hits1.size(); ++i) - BOOST_CHECK_CLOSE_FRACTION(hits1[i]->score, hits2[i]->score, 0.0000001); + EXPECT_NEAR(hits1[i]->score, hits2[i]->score, 0.0000001); } }; -BOOST_FIXTURE_TEST_SUITE(FilteredQueryTest, FilteredQueryFixture) - -BOOST_AUTO_TEST_CASE(testFilteredQuery) +TEST_F(FilteredQueryTest, testFilteredQuery) { QueryPtr filteredquery = newLucene(query, filter); Collection hits = searcher->search(filteredquery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(1, hits[0]->doc); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(1, hits[0]->doc); QueryUtils::check(filteredquery, searcher); hits = searcher->search(filteredquery, FilterPtr(), 1000, newLucene(newLucene(L"sorter", SortField::STRING)))->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(1, hits[0]->doc); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(1, hits[0]->doc); filteredquery = newLucene(newLucene(newLucene(L"field", L"one")), filter); hits = searcher->search(filteredquery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); QueryUtils::check(filteredquery, searcher); - + filteredquery = newLucene(newLucene(newLucene(L"field", L"x")), filter); hits = searcher->search(filteredquery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(3, hits[0]->doc); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(3, hits[0]->doc); QueryUtils::check(filteredquery, searcher); filteredquery = newLucene(newLucene(newLucene(L"field", L"y")), filter); hits = searcher->search(filteredquery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(filteredquery, searcher); // test boost @@ -207,21 +205,21 @@ BOOST_AUTO_TEST_CASE(testFilteredQuery) bq2->add(newLucene(newLucene(L"field", L"five")), BooleanClause::MUST); checkScoreEquals(bq1, bq2); - BOOST_CHECK_EQUAL(boost, filteredquery->getBoost()); - BOOST_CHECK_EQUAL(1.0, tq->getBoost()); // the boost value of the underlying query shouldn't have changed + EXPECT_EQ(boost, filteredquery->getBoost()); + EXPECT_EQ(1.0, tq->getBoost()); // the boost value of the underlying query shouldn't have changed } -BOOST_AUTO_TEST_CASE(testRangeQuery) +TEST_F(FilteredQueryTest, testRangeQuery) { TermRangeQueryPtr rq = newLucene(L"sorter", L"b", L"d", true, true); QueryPtr filteredquery = newLucene(rq, filter); Collection hits = searcher->search(filteredquery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); QueryUtils::check(filteredquery, searcher); } -BOOST_AUTO_TEST_CASE(testBoolean) +TEST_F(FilteredQueryTest, testBoolean) { BooleanQueryPtr bq = newLucene(); QueryPtr query = newLucene(newLucene(), newLucene(0)); @@ -229,20 +227,18 @@ BOOST_AUTO_TEST_CASE(testBoolean) query = newLucene(newLucene(), newLucene(1)); bq->add(query, BooleanClause::MUST); Collection hits = searcher->search(bq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); } /// Make sure BooleanQuery, which does out-of-order scoring, inside FilteredQuery, works -BOOST_AUTO_TEST_CASE(testBoolean2) +TEST_F(FilteredQueryTest, testBoolean2) { BooleanQueryPtr bq = newLucene(); QueryPtr query = newLucene(bq, newLucene(0)); bq->add(newLucene(newLucene(L"field", L"one")), BooleanClause::SHOULD); bq->add(newLucene(newLucene(L"field", L"two")), BooleanClause::SHOULD); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/FilteredSearchTest.cpp b/src/test/search/FilteredSearchTest.cpp index 974d2bcd..a833b9c2 100644 --- a/src/test/search/FilteredSearchTest.cpp +++ b/src/test/search/FilteredSearchTest.cpp @@ -34,7 +34,7 @@ class SimpleDocIdSetFilter : public Filter this->docBase = 0; this->index = 0; } - + virtual ~SimpleDocIdSetFilter() { } @@ -59,7 +59,7 @@ class SimpleDocIdSetFilter : public Filter docBase = limit; return set->isEmpty() ? DocIdSetPtr() : set; } - + void reset() { index = 0; @@ -87,12 +87,12 @@ static void searchFiltered(IndexWriterPtr writer, DirectoryPtr directory, Filter IndexSearcherPtr indexSearcher = newLucene(directory, true); Collection hits = indexSearcher->search(booleanQuery, filter, 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); } -BOOST_FIXTURE_TEST_SUITE(FilteredSearchTest, LuceneTestFixture) +typedef LuceneTestFixture FilteredSearchTest; -BOOST_AUTO_TEST_CASE(testFilteredSearch) +TEST_F(FilteredSearchTest, testFilteredSearch) { bool enforceSingleSegment = true; RAMDirectoryPtr directory = newLucene(); @@ -109,5 +109,3 @@ BOOST_AUTO_TEST_CASE(testFilteredSearch) writer->setMaxBufferedDocs(10); searchFiltered(writer, directory, filter, enforceSingleSegment); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/FuzzyQueryTest.cpp b/src/test/search/FuzzyQueryTest.cpp index 2acecbcb..c95b607d 100644 --- a/src/test/search/FuzzyQueryTest.cpp +++ b/src/test/search/FuzzyQueryTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(FuzzyQueryTest, LuceneTestFixture) +typedef LuceneTestFixture FuzzyQueryTest; static void addDoc(const String& text, IndexWriterPtr writer) { @@ -32,7 +32,7 @@ static void addDoc(const String& text, IndexWriterPtr writer) writer->addDocument(doc); } -BOOST_AUTO_TEST_CASE(testFuzziness) +TEST_F(FuzzyQueryTest, testFuzziness) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -49,146 +49,146 @@ BOOST_AUTO_TEST_CASE(testFuzziness) FuzzyQueryPtr query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 0); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); // same with prefix query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 1); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 2); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 3); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 4); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 5); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 6); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - + EXPECT_EQ(1, hits.size()); + // test scoring - query = newLucene(newLucene(L"field", L"bbbbb"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"bbbbb"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); Collection order = newCollection(L"bbbbb", L"abbbb", L"aabbb"); for (int32_t i = 0; i < hits.size(); ++i) { String term = searcher->doc(hits[i]->doc)->get(L"field"); - BOOST_CHECK_EQUAL(order[i], term); + EXPECT_EQ(order[i], term); } // test BooleanQuery.maxClauseCount int32_t savedClauseCount = BooleanQuery::getMaxClauseCount(); - + BooleanQuery::setMaxClauseCount(2); // This query would normally return 3 documents, because 3 terms match (see above) - query = newLucene(newLucene(L"field", L"bbbbb"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"bbbbb"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); order = newCollection(L"bbbbb", L"abbbb"); - + for (int32_t i = 0; i < hits.size(); ++i) { String term = searcher->doc(hits[i]->doc)->get(L"field"); - BOOST_CHECK_EQUAL(order[i], term); + EXPECT_EQ(order[i], term); } - + BooleanQuery::setMaxClauseCount(savedClauseCount); // not similar enough query = newLucene(newLucene(L"field", L"xxxxx"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); query = newLucene(newLucene(L"field", L"aaccc"), FuzzyQuery::defaultMinSimilarity(), 0); // edit distance to "aaaaa" = 3 hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // query identical to a word in the index - query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"aaaaa"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); + EXPECT_EQ(3, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); // default allows for up to two edits - BOOST_CHECK_EQUAL(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); - BOOST_CHECK_EQUAL(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); + EXPECT_EQ(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); + EXPECT_EQ(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); // query similar to a word in the index - query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); - BOOST_CHECK_EQUAL(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); - BOOST_CHECK_EQUAL(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); + EXPECT_EQ(3, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); + EXPECT_EQ(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); + EXPECT_EQ(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); // now with prefix - query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 1); + query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 1); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); - BOOST_CHECK_EQUAL(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); - BOOST_CHECK_EQUAL(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); - query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 2); + EXPECT_EQ(3, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); + EXPECT_EQ(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); + EXPECT_EQ(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); + query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 2); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); - BOOST_CHECK_EQUAL(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); - BOOST_CHECK_EQUAL(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); - query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 3); + EXPECT_EQ(3, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); + EXPECT_EQ(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); + EXPECT_EQ(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); + query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 3); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); - BOOST_CHECK_EQUAL(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); - BOOST_CHECK_EQUAL(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); - query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 4); + EXPECT_EQ(3, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); + EXPECT_EQ(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); + EXPECT_EQ(searcher->doc(hits[2]->doc)->get(L"field"), L"aaabb"); + query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 4); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); - BOOST_CHECK_EQUAL(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); - query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 5); + EXPECT_EQ(2, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaa"); + EXPECT_EQ(searcher->doc(hits[1]->doc)->get(L"field"), L"aaaab"); + query = newLucene(newLucene(L"field", L"aaaac"), FuzzyQuery::defaultMinSimilarity(), 5); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); - query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); // now with prefix - query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 1); + query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 1); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); - query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 2); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); + query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 2); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); - query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 3); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); + query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 3); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); - query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 4); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); + query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 4); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); - query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 5); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"ddddd"); + query = newLucene(newLucene(L"field", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 5); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // different field = no match - query = newLucene(newLucene(L"anotherfield", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"anotherfield", L"ddddX"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); searcher->close(); directory->close(); } -BOOST_AUTO_TEST_CASE(testFuzzinessLong) +TEST_F(FuzzyQueryTest, testFuzzinessLong) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -199,74 +199,88 @@ BOOST_AUTO_TEST_CASE(testFuzzinessLong) IndexSearcherPtr searcher = newLucene(directory, true); // not similar enough - FuzzyQueryPtr query = newLucene(newLucene(L"field", L"xxxxx"), FuzzyQuery::defaultMinSimilarity(), 0); + FuzzyQueryPtr query = newLucene(newLucene(L"field", L"xxxxx"), FuzzyQuery::defaultMinSimilarity(), 0); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // edit distance to "aaaaaaa" = 3, this matches because the string is longer than // in testDefaultFuzziness so a bigger difference is allowed - query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaaaa"); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaaaa"); // now with prefix - query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 1); + query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 1); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaaaa"); - query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 4); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaaaa"); + query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 4); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaaaa"); - query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 5); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(searcher->doc(hits[0]->doc)->get(L"field"), L"aaaaaaa"); + query = newLucene(newLucene(L"field", L"aaaaccc"), FuzzyQuery::defaultMinSimilarity(), 5); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // no match, more than half of the characters is wrong - query = newLucene(newLucene(L"field", L"aaacccc"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"aaacccc"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // now with prefix - query = newLucene(newLucene(L"field", L"aaacccc"), FuzzyQuery::defaultMinSimilarity(), 2); + query = newLucene(newLucene(L"field", L"aaacccc"), FuzzyQuery::defaultMinSimilarity(), 2); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // "student" and "stellent" are indeed similar to "segment" by default - query = newLucene(newLucene(L"field", L"student"), FuzzyQuery::defaultMinSimilarity(), 0); + query = newLucene(newLucene(L"field", L"student"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - query = newLucene(newLucene(L"field", L"stellent"), FuzzyQuery::defaultMinSimilarity(), 0); + EXPECT_EQ(1, hits.size()); + query = newLucene(newLucene(L"field", L"stellent"), FuzzyQuery::defaultMinSimilarity(), 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); // now with prefix - query = newLucene(newLucene(L"field", L"student"), FuzzyQuery::defaultMinSimilarity(), 1); + query = newLucene(newLucene(L"field", L"student"), FuzzyQuery::defaultMinSimilarity(), 1); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - query = newLucene(newLucene(L"field", L"stellent"), FuzzyQuery::defaultMinSimilarity(), 1); + EXPECT_EQ(1, hits.size()); + query = newLucene(newLucene(L"field", L"stellent"), FuzzyQuery::defaultMinSimilarity(), 1); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - query = newLucene(newLucene(L"field", L"student"), FuzzyQuery::defaultMinSimilarity(), 2); + EXPECT_EQ(1, hits.size()); + query = newLucene(newLucene(L"field", L"student"), FuzzyQuery::defaultMinSimilarity(), 2); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); - query = newLucene(newLucene(L"field", L"stellent"), FuzzyQuery::defaultMinSimilarity(), 2); + EXPECT_EQ(0, hits.size()); + query = newLucene(newLucene(L"field", L"stellent"), FuzzyQuery::defaultMinSimilarity(), 2); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // "student" doesn't match anymore thanks to increased minimum similarity - query = newLucene(newLucene(L"field", L"student"), 0.6, 0); + query = newLucene(newLucene(L"field", L"student"), 0.6, 0); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); - - BOOST_CHECK_EXCEPTION(query = newLucene(newLucene(L"field", L"student"), 1.1), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); - BOOST_CHECK_EXCEPTION(query = newLucene(newLucene(L"field", L"student"), -0.1), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + EXPECT_EQ(0, hits.size()); + + try + { + query = newLucene(newLucene(L"field", L"student"), 1.1); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } + try + { + query = newLucene(newLucene(L"field", L"student"), -0.1); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } searcher->close(); directory->close(); } -BOOST_AUTO_TEST_CASE(testTokenLengthOpt) +TEST_F(FuzzyQueryTest, testTokenLengthOpt) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -279,28 +293,28 @@ BOOST_AUTO_TEST_CASE(testTokenLengthOpt) // term not over 10 chars, so optimization shortcuts FuzzyQueryPtr query = newLucene(newLucene(L"field", L"1234569"), 0.9); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); - + EXPECT_EQ(0, hits.size()); + // 10 chars, so no optimization query = newLucene(newLucene(L"field", L"1234567891"), 0.9); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); - + EXPECT_EQ(0, hits.size()); + // over 10 chars, so no optimization query = newLucene(newLucene(L"field", L"12345678911"), 0.9); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - + EXPECT_EQ(1, hits.size()); + // over 10 chars, no match query = newLucene(newLucene(L"field", L"sdfsdfsdfsdf"), 0.9); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); } -BOOST_AUTO_TEST_CASE(testGiga) +TEST_F(FuzzyQueryTest, testGiga) { StandardAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); - + DirectoryPtr index = newLucene(); IndexWriterPtr w = newLucene(index, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -327,9 +341,7 @@ BOOST_AUTO_TEST_CASE(testGiga) IndexSearcherPtr searcher = newLucene(r); Collection hits = searcher->search(q, 10)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(L"Giga byte", searcher->doc(hits[0]->doc)->get(L"field")); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(L"Giga byte", searcher->doc(hits[0]->doc)->get(L"field")); r->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/MatchAllDocsQueryTest.cpp b/src/test/search/MatchAllDocsQueryTest.cpp index 83b2183e..c7d1dcb4 100644 --- a/src/test/search/MatchAllDocsQueryTest.cpp +++ b/src/test/search/MatchAllDocsQueryTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(MatchAllDocsQueryTest, LuceneTestFixture) +typedef LuceneTestFixture MatchAllDocsQueryTest; static void addDoc(const String& text, IndexWriterPtr iw, double boost) { @@ -34,7 +34,7 @@ static void addDoc(const String& text, IndexWriterPtr iw, double boost) iw->addDocument(doc); } -BOOST_AUTO_TEST_CASE(testQuery) +TEST_F(MatchAllDocsQueryTest, testQuery) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); RAMDirectoryPtr dir = newLucene(); @@ -50,72 +50,70 @@ BOOST_AUTO_TEST_CASE(testQuery) // assert with norms scoring turned off Collection hits = is->search(newLucene(), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); - BOOST_CHECK_EQUAL(L"one", ir->document(hits[0]->doc)->get(L"key")); - BOOST_CHECK_EQUAL(L"two", ir->document(hits[1]->doc)->get(L"key")); - BOOST_CHECK_EQUAL(L"three four", ir->document(hits[2]->doc)->get(L"key")); + EXPECT_EQ(3, hits.size()); + EXPECT_EQ(L"one", ir->document(hits[0]->doc)->get(L"key")); + EXPECT_EQ(L"two", ir->document(hits[1]->doc)->get(L"key")); + EXPECT_EQ(L"three four", ir->document(hits[2]->doc)->get(L"key")); // assert with norms scoring turned on MatchAllDocsQueryPtr normsQuery = newLucene(L"key"); hits = is->search(normsQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); - BOOST_CHECK_EQUAL(L"three four", ir->document(hits[0]->doc)->get(L"key")); - BOOST_CHECK_EQUAL(L"two", ir->document(hits[1]->doc)->get(L"key")); - BOOST_CHECK_EQUAL(L"one", ir->document(hits[2]->doc)->get(L"key")); + EXPECT_EQ(L"three four", ir->document(hits[0]->doc)->get(L"key")); + EXPECT_EQ(L"two", ir->document(hits[1]->doc)->get(L"key")); + EXPECT_EQ(L"one", ir->document(hits[2]->doc)->get(L"key")); // change norm & retest ir->setNorm(0, L"key", 400.0); normsQuery = newLucene(L"key"); hits = is->search(normsQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); - BOOST_CHECK_EQUAL(L"one", ir->document(hits[0]->doc)->get(L"key")); - BOOST_CHECK_EQUAL(L"three four", ir->document(hits[1]->doc)->get(L"key")); - BOOST_CHECK_EQUAL(L"two", ir->document(hits[2]->doc)->get(L"key")); + EXPECT_EQ(L"one", ir->document(hits[0]->doc)->get(L"key")); + EXPECT_EQ(L"three four", ir->document(hits[1]->doc)->get(L"key")); + EXPECT_EQ(L"two", ir->document(hits[2]->doc)->get(L"key")); // some artificial queries to trigger the use of skipTo() BooleanQueryPtr bq = newLucene(); bq->add(newLucene(), BooleanClause::MUST); bq->add(newLucene(), BooleanClause::MUST); hits = is->search(bq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); bq = newLucene(); bq->add(newLucene(), BooleanClause::MUST); bq->add(newLucene(newLucene(L"key", L"three")), BooleanClause::MUST); hits = is->search(bq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); // delete a document is->getIndexReader()->deleteDocument(0); hits = is->search(newLucene(), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); // test parsable toString() QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"key", analyzer); hits = is->search(qp->parse(newLucene()->toString()), FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); // test parsable toString() with non default boost QueryPtr maq = newLucene(); maq->setBoost(2.3); QueryPtr pq = qp->parse(maq->toString()); hits = is->search(pq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); is->close(); ir->close(); dir->close(); } -BOOST_AUTO_TEST_CASE(testEquals) +TEST_F(MatchAllDocsQueryTest, testEquals) { QueryPtr q1 = newLucene(); QueryPtr q2 = newLucene(); - BOOST_CHECK(q1->equals(q2)); + EXPECT_TRUE(q1->equals(q2)); q1->setBoost(1.5); - BOOST_CHECK(!q1->equals(q2)); + EXPECT_TRUE(!q1->equals(q2)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/MultiPhraseQueryTest.cpp b/src/test/search/MultiPhraseQueryTest.cpp index f4434576..0b7cfb27 100644 --- a/src/test/search/MultiPhraseQueryTest.cpp +++ b/src/test/search/MultiPhraseQueryTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(MultiPhraseQueryTest, LuceneTestFixture) +typedef LuceneTestFixture MultiPhraseQueryTest; static void add(const String& s, IndexWriterPtr writer) { @@ -42,7 +42,7 @@ static void add(const String& s, const String& type, IndexWriterPtr writer) writer->addDocument(doc); } -BOOST_AUTO_TEST_CASE(testPhrasePrefix) +TEST_F(MultiPhraseQueryTest, testPhrasePrefix) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -79,14 +79,14 @@ BOOST_AUTO_TEST_CASE(testPhrasePrefix) while (te->next()); query1->add(termsWithPrefix); - BOOST_CHECK_EQUAL(L"body:\"blueberry (piccadilly pie pizza)\"", query1->toString()); + EXPECT_EQ(L"body:\"blueberry (piccadilly pie pizza)\"", query1->toString()); query2->add(termsWithPrefix); - BOOST_CHECK_EQUAL(L"body:\"strawberry (piccadilly pie pizza)\"", query2->toString()); + EXPECT_EQ(L"body:\"strawberry (piccadilly pie pizza)\"", query2->toString()); Collection result = searcher->search(query1, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, result.size()); + EXPECT_EQ(2, result.size()); result = searcher->search(query2, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); // search for "blue* pizza" MultiPhraseQueryPtr query3 = newLucene(); @@ -104,23 +104,30 @@ BOOST_AUTO_TEST_CASE(testPhrasePrefix) query3->add(newLucene(L"body", L"pizza")); result = searcher->search(query3, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, result.size()); // blueberry pizza, bluebird pizza - BOOST_CHECK_EQUAL(L"body:\"(blueberry bluebird) pizza\"", query3->toString()); + EXPECT_EQ(2, result.size()); // blueberry pizza, bluebird pizza + EXPECT_EQ(L"body:\"(blueberry bluebird) pizza\"", query3->toString()); // test slop query3->setSlop(1); result = searcher->search(query3, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, result.size()); // blueberry pizza, bluebird pizza, bluebird foobar pizza + EXPECT_EQ(3, result.size()); // blueberry pizza, bluebird pizza, bluebird foobar pizza MultiPhraseQueryPtr query4 = newLucene(); query4->add(newLucene(L"field1", L"foo")); - BOOST_CHECK_EXCEPTION(query4->add(newLucene(L"field2", L"foobar")), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); - + try + { + query4->add(newLucene(L"field2", L"foobar")); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } + searcher->close(); indexStore->close(); } -BOOST_AUTO_TEST_CASE(testBooleanQueryContainingSingleTermPrefixQuery) +TEST_F(MultiPhraseQueryTest, testBooleanQueryContainingSingleTermPrefixQuery) { // In order to cause the bug, the outer query must have more than one term and all terms required. // The contained PhraseMultiQuery must contain exactly one term array. @@ -144,11 +151,11 @@ BOOST_AUTO_TEST_CASE(testBooleanQueryContainingSingleTermPrefixQuery) Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); searcher->close(); } -BOOST_AUTO_TEST_CASE(testPhrasePrefixWithBooleanQuery) +TEST_F(MultiPhraseQueryTest, testPhrasePrefixWithBooleanQuery) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance()), true, IndexWriter::MaxFieldLengthLIMITED); @@ -168,38 +175,36 @@ BOOST_AUTO_TEST_CASE(testPhrasePrefixWithBooleanQuery) q->add(mpq, BooleanClause::MUST); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - - BOOST_CHECK_EQUAL(0, hits.size()); + + EXPECT_EQ(0, hits.size()); searcher->close(); } -BOOST_AUTO_TEST_CASE(testHashCodeAndEquals) +TEST_F(MultiPhraseQueryTest, testHashCodeAndEquals) { MultiPhraseQueryPtr query1 = newLucene(); MultiPhraseQueryPtr query2 = newLucene(); - BOOST_CHECK_EQUAL(query1->hashCode(), query2->hashCode()); - BOOST_CHECK(query1->equals(query2)); + EXPECT_EQ(query1->hashCode(), query2->hashCode()); + EXPECT_TRUE(query1->equals(query2)); TermPtr term1 = newLucene(L"someField", L"someText"); query1->add(term1); query2->add(term1); - BOOST_CHECK_EQUAL(query1->hashCode(), query2->hashCode()); - BOOST_CHECK(query1->equals(query2)); + EXPECT_EQ(query1->hashCode(), query2->hashCode()); + EXPECT_TRUE(query1->equals(query2)); TermPtr term2 = newLucene(L"someField", L"someMoreText"); query1->add(term2); - BOOST_CHECK_NE(query1->hashCode(), query2->hashCode()); - BOOST_CHECK(!query1->equals(query2)); + EXPECT_NE(query1->hashCode(), query2->hashCode()); + EXPECT_TRUE(!query1->equals(query2)); query2->add(term2); - BOOST_CHECK_EQUAL(query1->hashCode(), query2->hashCode()); - BOOST_CHECK(query1->equals(query2)); + EXPECT_EQ(query1->hashCode(), query2->hashCode()); + EXPECT_TRUE(query1->equals(query2)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/MultiSearcherRankingTest.cpp b/src/test/search/MultiSearcherRankingTest.cpp index 87535d5b..eaac9c60 100644 --- a/src/test/search/MultiSearcherRankingTest.cpp +++ b/src/test/search/MultiSearcherRankingTest.cpp @@ -20,10 +20,10 @@ using namespace Lucene; -class MultiSearcherRankingFixture : public LuceneTestFixture +class MultiSearcherRankingTest : public LuceneTestFixture { public: - MultiSearcherRankingFixture() + MultiSearcherRankingTest() { // create MultiSearcher from two separate searchers DirectoryPtr d1 = newLucene(); @@ -46,8 +46,8 @@ class MultiSearcherRankingFixture : public LuceneTestFixture iw->close(); singleSearcher = newLucene(d, true); } - - virtual ~MultiSearcherRankingFixture() + + virtual ~MultiSearcherRankingTest() { } @@ -66,7 +66,7 @@ class MultiSearcherRankingFixture : public LuceneTestFixture add(L"blueberry strudel", iw); add(L"blueberry pizza", iw); } - + void addCollection2(IndexWriterPtr iw) { add(L"two blah three", iw); @@ -77,15 +77,15 @@ class MultiSearcherRankingFixture : public LuceneTestFixture add(L"bluebird foobar pizza", iw); add(L"piccadilly circus", iw); } - + void add(const String& value, IndexWriterPtr iw) { DocumentPtr d = newLucene(); d->add(newLucene(FIELD_NAME, value, Field::STORE_YES, Field::INDEX_ANALYZED)); iw->addDocument(d); } - - /// checks if a query yields the same result when executed on a single IndexSearcher containing all + + /// checks if a query yields the same result when executed on a single IndexSearcher containing all /// documents and on MultiSearcher aggregating sub-searchers /// @param queryStr the query to check. void checkQuery(const String& queryStr) @@ -94,54 +94,50 @@ class MultiSearcherRankingFixture : public LuceneTestFixture QueryPtr query = queryParser->parse(queryStr); Collection multiSearcherHits = multiSearcher->search(query, FilterPtr(), 1000)->scoreDocs; Collection singleSearcherHits = singleSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(multiSearcherHits.size(), singleSearcherHits.size()); + EXPECT_EQ(multiSearcherHits.size(), singleSearcherHits.size()); for (int32_t i = 0; i < multiSearcherHits.size(); ++i) { DocumentPtr docMulti = multiSearcher->doc(multiSearcherHits[i]->doc); DocumentPtr docSingle = singleSearcher->doc(singleSearcherHits[i]->doc); - BOOST_CHECK_CLOSE_FRACTION(multiSearcherHits[i]->score, singleSearcherHits[i]->score, 0.001); - BOOST_CHECK_EQUAL(docMulti->get(FIELD_NAME), docSingle->get(FIELD_NAME)); + EXPECT_NEAR(multiSearcherHits[i]->score, singleSearcherHits[i]->score, 0.001); + EXPECT_EQ(docMulti->get(FIELD_NAME), docSingle->get(FIELD_NAME)); } } }; -const String MultiSearcherRankingFixture::FIELD_NAME = L"body"; - -BOOST_FIXTURE_TEST_SUITE(MultiSearcherRankingTest, MultiSearcherRankingFixture) +const String MultiSearcherRankingTest::FIELD_NAME = L"body"; -BOOST_AUTO_TEST_CASE(testOneTermQuery) +TEST_F(MultiSearcherRankingTest, testOneTermQuery) { checkQuery(L"three"); } -BOOST_AUTO_TEST_CASE(testTwoTermQuery) +TEST_F(MultiSearcherRankingTest, testTwoTermQuery) { checkQuery(L"three foo"); } -BOOST_AUTO_TEST_CASE(testPrefixQuery) +TEST_F(MultiSearcherRankingTest, testPrefixQuery) { checkQuery(L"multi*"); } -BOOST_AUTO_TEST_CASE(testFuzzyQuery) +TEST_F(MultiSearcherRankingTest, testFuzzyQuery) { checkQuery(L"multiThree~"); } -BOOST_AUTO_TEST_CASE(testRangeQuery) +TEST_F(MultiSearcherRankingTest, testRangeQuery) { checkQuery(L"{multiA TO multiP}"); } -BOOST_AUTO_TEST_CASE(testMultiPhraseQuery) +TEST_F(MultiSearcherRankingTest, testMultiPhraseQuery) { checkQuery(L"\"blueberry pi*\""); } -BOOST_AUTO_TEST_CASE(testNoMatchQuery) +TEST_F(MultiSearcherRankingTest, testNoMatchQuery) { checkQuery(L"+three +nomatch"); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/MultiSearcherTest.cpp b/src/test/search/MultiSearcherTest.cpp index f52dd1bc..daddf33f 100644 --- a/src/test/search/MultiSearcherTest.cpp +++ b/src/test/search/MultiSearcherTest.cpp @@ -28,7 +28,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(MultiSearcherTest, LuceneTestFixture) +typedef LuceneTestFixture MultiSearcherTest; static MultiSearcherPtr getMultiSearcherInstance(Collection searchers) { @@ -53,7 +53,7 @@ static void initIndex(DirectoryPtr directory, int32_t numDocs, bool create, cons indexWriter->close(); } -BOOST_AUTO_TEST_CASE(testEmptyIndex) +TEST_F(MultiSearcherTest, testEmptyIndex) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); @@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // performing the search Collection hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); // iterating over the hit documents for (int32_t i = 0; i < hits.size(); ++i) @@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // performing the same search Collection hits2 = mSearcher2->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, hits2.size()); + EXPECT_EQ(4, hits2.size()); // iterating over the hit documents for (int32_t i = 0; i < hits2.size(); ++i) @@ -141,13 +141,13 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // test the subSearcher() method QueryPtr subSearcherQuery = parser->parse(L"id:doc1"); hits2 = mSearcher2->search(subSearcherQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits2.size()); - BOOST_CHECK_EQUAL(0, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[0] - BOOST_CHECK_EQUAL(1, mSearcher2->subSearcher(hits2[1]->doc)); // hit from searchers2[1] + EXPECT_EQ(2, hits2.size()); + EXPECT_EQ(0, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[0] + EXPECT_EQ(1, mSearcher2->subSearcher(hits2[1]->doc)); // hit from searchers2[1] subSearcherQuery = parser->parse(L"id:doc2"); hits2 = mSearcher2->search(subSearcherQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits2.size()); - BOOST_CHECK_EQUAL(1, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[1] + EXPECT_EQ(1, hits2.size()); + EXPECT_EQ(1, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[1] mSearcher2->close(); //-------------------------------------------------------------------- @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // performing the same search Collection hits3 = mSearcher3->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits3.size()); + EXPECT_EQ(3, hits3.size()); // iterating over the hit documents @@ -184,11 +184,11 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) indexStoreB->close(); } -BOOST_AUTO_TEST_CASE(testFieldSelector) +TEST_F(MultiSearcherTest, testFieldSelector) { RAMDirectoryPtr ramDirectory1 = newLucene(); RAMDirectoryPtr ramDirectory2 = newLucene(); - + QueryPtr query = newLucene(newLucene(L"contents", L"doc0")); // Now put the documents in a different index @@ -199,35 +199,35 @@ BOOST_AUTO_TEST_CASE(testFieldSelector) IndexSearcherPtr indexSearcher2 = newLucene(ramDirectory2, true); MultiSearcherPtr searcher = getMultiSearcherInstance(newCollection(indexSearcher1, indexSearcher2)); - BOOST_CHECK(searcher); + EXPECT_TRUE(searcher); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits.size(), 2); + EXPECT_TRUE(hits); + EXPECT_EQ(hits.size(), 2); DocumentPtr document = searcher->doc(hits[0]->doc); - BOOST_CHECK(document); - BOOST_CHECK_EQUAL(document->getFields().size(), 2); + EXPECT_TRUE(document); + EXPECT_EQ(document->getFields().size(), 2); // Should be one document from each directory they both have two fields, contents and other HashSet ftl = HashSet::newInstance(); ftl.add(L"other"); SetBasedFieldSelectorPtr fs = newLucene(ftl, HashSet::newInstance()); document = searcher->doc(hits[0]->doc, fs); - BOOST_CHECK(document); - BOOST_CHECK_EQUAL(document->getFields().size(), 1); + EXPECT_TRUE(document); + EXPECT_EQ(document->getFields().size(), 1); String value = document->get(L"contents"); - BOOST_CHECK(value.empty()); + EXPECT_TRUE(value.empty()); value = document->get(L"other"); - BOOST_CHECK(!value.empty()); + EXPECT_TRUE(!value.empty()); ftl.clear(); ftl.add(L"contents"); fs = newLucene(ftl, HashSet::newInstance()); document = searcher->doc(hits[1]->doc, fs); value = document->get(L"contents"); - BOOST_CHECK(!value.empty()); + EXPECT_TRUE(!value.empty()); value = document->get(L"other"); - BOOST_CHECK(value.empty()); + EXPECT_TRUE(value.empty()); } -BOOST_AUTO_TEST_CASE(testNormalization) +TEST_F(MultiSearcherTest, testNormalization) { int32_t numDocs = 10; @@ -242,11 +242,11 @@ BOOST_AUTO_TEST_CASE(testNormalization) indexSearcher1->setDefaultFieldSortScoring(true, true); Collection hits = indexSearcher1->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); // Store the scores for use later Collection scores = newCollection(hits[0]->score, hits[1]->score); - BOOST_CHECK(scores[0] > scores[1]); + EXPECT_TRUE(scores[0] > scores[1]); indexSearcher1->close(); ramDirectory1->close(); @@ -268,19 +268,19 @@ BOOST_AUTO_TEST_CASE(testNormalization) hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); // The scores should be the same (within reason) - BOOST_CHECK_CLOSE_FRACTION(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 - BOOST_CHECK_CLOSE_FRACTION(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 + EXPECT_NEAR(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 + EXPECT_NEAR(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 // Adding a Sort.RELEVANCE object should not change anything hits = searcher->search(query, FilterPtr(), 1000, Sort::RELEVANCE())->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); - BOOST_CHECK_CLOSE_FRACTION(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 - BOOST_CHECK_CLOSE_FRACTION(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 + EXPECT_NEAR(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 + EXPECT_NEAR(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 searcher->close(); @@ -296,33 +296,33 @@ namespace TestCustomSimilarity virtual ~CustomSimilarity() { } - + public: virtual double idf(int32_t docFreq, int32_t numDocs) { return 100.0; } - + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - + virtual double sloppyFreq(int32_t distance) { return 1.0; } - + virtual double tf(double freq) { return 1.0; @@ -330,7 +330,7 @@ namespace TestCustomSimilarity }; } -BOOST_AUTO_TEST_CASE(testCustomSimilarity) +TEST_F(MultiSearcherTest, testCustomSimilarity) { RAMDirectoryPtr dir = newLucene(); initIndex(dir, 10, true, L"x"); // documents with two tokens "doc0" and "x", "doc1" and x, etc... @@ -352,10 +352,10 @@ BOOST_AUTO_TEST_CASE(testCustomSimilarity) double scoreN = topDocs->maxScore; // The scores from the IndexSearcher and Multisearcher should be the same if the same similarity is used. - BOOST_CHECK_CLOSE_FRACTION(score1, scoreN, 1e-6); + EXPECT_NEAR(score1, scoreN, 1e-6); } -BOOST_AUTO_TEST_CASE(testDocFreq) +TEST_F(MultiSearcherTest, testDocFreq) { RAMDirectoryPtr dir1 = newLucene(); RAMDirectoryPtr dir2 = newLucene(); @@ -366,7 +366,5 @@ BOOST_AUTO_TEST_CASE(testDocFreq) IndexSearcherPtr searcher2 = newLucene(dir2, true); MultiSearcherPtr multiSearcher = getMultiSearcherInstance(newCollection(searcher1, searcher2)); - BOOST_CHECK_EQUAL(15, multiSearcher->docFreq(newLucene(L"contents", L"x"))); + EXPECT_EQ(15, multiSearcher->docFreq(newLucene(L"contents", L"x"))); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/MultiTermConstantScoreTest.cpp b/src/test/search/MultiTermConstantScoreTest.cpp index d01301eb..3a239168 100644 --- a/src/test/search/MultiTermConstantScoreTest.cpp +++ b/src/test/search/MultiTermConstantScoreTest.cpp @@ -28,17 +28,17 @@ using namespace Lucene; -class MultiTermConstantScoreFixture : public BaseTestRangeFilterFixture +class MultiTermConstantScoreTest : public BaseTestRangeFilterFixture { public: - MultiTermConstantScoreFixture() + MultiTermConstantScoreTest() { Collection data = newCollection( L"A 1 2 3 4 5 6", L"Z 4 5 6", L"", - L"B 2 4 5 6", - L"Y 3 5 6", + L"B 2 4 5 6", + L"Y 3 5 6", L"", L"C 3 6", L"X 4 5 6" @@ -46,7 +46,7 @@ class MultiTermConstantScoreFixture : public BaseTestRangeFilterFixture small = newLucene(); IndexWriterPtr writer = newLucene(small, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - + for (int32_t i = 0; i < data.size(); ++i) { DocumentPtr doc = newLucene(); @@ -56,18 +56,18 @@ class MultiTermConstantScoreFixture : public BaseTestRangeFilterFixture doc->add(newLucene(L"data", data[i], Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + writer->optimize(); writer->close(); } - - virtual ~MultiTermConstantScoreFixture() + + virtual ~MultiTermConstantScoreTest() { } public: static const double SCORE_COMP_THRESH; - + DirectoryPtr small; public: @@ -77,28 +77,28 @@ class MultiTermConstantScoreFixture : public BaseTestRangeFilterFixture query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - + QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, RewriteMethodPtr method) { TermRangeQueryPtr query = newLucene(f, l, h, il, ih); query->setRewriteMethod(method); return query; } - + QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, CollatorPtr c) { TermRangeQueryPtr query = newLucene(f, l, h, il, ih, c); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - + QueryPtr cspq(TermPtr prefix) { PrefixQueryPtr query = newLucene(prefix); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - + QueryPtr cswcq(TermPtr wild) { WildcardQueryPtr query = newLucene(wild); @@ -108,11 +108,9 @@ class MultiTermConstantScoreFixture : public BaseTestRangeFilterFixture }; /// threshold for comparing doubles -const double MultiTermConstantScoreFixture::SCORE_COMP_THRESH = 1e-6f; - -BOOST_FIXTURE_TEST_SUITE(MultiTermConstantScoreTest, MultiTermConstantScoreFixture) +const double MultiTermConstantScoreTest::SCORE_COMP_THRESH = 1e-6f; -BOOST_AUTO_TEST_CASE(testBasics) +TEST_F(MultiTermConstantScoreTest, testBasics) { QueryUtils::check(csrq(L"data", L"1", L"6", true, true)); QueryUtils::check(csrq(L"data", L"A", L"Z", true, true)); @@ -125,7 +123,7 @@ BOOST_AUTO_TEST_CASE(testBasics) QueryUtils::checkUnequal(cswcq(newLucene(L"data", L"pre*n?t")), cswcq(newLucene(L"data", L"pr*t?j"))); } -BOOST_AUTO_TEST_CASE(testBasicsRngCollating) +TEST_F(MultiTermConstantScoreTest, testBasicsRngCollating) { CollatorPtr c = newLucene(std::locale()); QueryUtils::check(csrq(L"data", L"1", L"6", true, true, c)); @@ -133,7 +131,7 @@ BOOST_AUTO_TEST_CASE(testBasicsRngCollating) QueryUtils::checkUnequal(csrq(L"data", L"1", L"6", true, true, c), csrq(L"data", L"A", L"Z", true, true, c)); } -BOOST_AUTO_TEST_CASE(testEqualScores) +TEST_F(MultiTermConstantScoreTest, testEqualScores) { IndexReaderPtr reader = IndexReader::open(small, true); IndexSearcherPtr search = newLucene(reader); @@ -141,16 +139,16 @@ BOOST_AUTO_TEST_CASE(testEqualScores) // some hits match more terms then others, score should be the same Collection result = search->search(csrq(L"data", L"1", L"6", true, true), FilterPtr(), 1000)->scoreDocs; int32_t numHits = result.size(); - BOOST_CHECK_EQUAL(6, numHits); + EXPECT_EQ(6, numHits); double score = result[0]->score; for (int32_t i = 1; i < numHits; ++i) - BOOST_CHECK_EQUAL(score, result[i]->score); - + EXPECT_EQ(score, result[i]->score); + result = search->search(csrq(L"data", L"1", L"6", true, true, MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()), FilterPtr(), 1000)->scoreDocs; numHits = result.size(); - BOOST_CHECK_EQUAL(6, numHits); + EXPECT_EQ(6, numHits); for (int32_t i = 0; i < numHits; ++i) - BOOST_CHECK_EQUAL(score, result[i]->score); + EXPECT_EQ(score, result[i]->score); } namespace TestBoost @@ -162,31 +160,31 @@ namespace TestBoost { base = 0; } - + virtual ~TestCollector() { } - + protected: int32_t base; ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL(1.0, scorer->score()); + EXPECT_EQ(1.0, scorer->score()); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -194,7 +192,7 @@ namespace TestBoost }; } -BOOST_AUTO_TEST_CASE(testBoost) +TEST_F(MultiTermConstantScoreTest, testBoost) { IndexReaderPtr reader = IndexReader::open(small, true); IndexSearcherPtr search = newLucene(reader); @@ -203,9 +201,9 @@ BOOST_AUTO_TEST_CASE(testBoost) // must use a non score normalizing method for this. QueryPtr q = csrq(L"data", L"1", L"6", true, true); q->setBoost(100); - + search->search(q, FilterPtr(), newLucene()); - + // Ensure that boosting works to score one clause of a query higher than another. QueryPtr q1 = csrq(L"data", L"A", L"A", true, true); // matches document #0 q1->setBoost(0.1); @@ -215,9 +213,9 @@ BOOST_AUTO_TEST_CASE(testBoost) bq->add(q2, BooleanClause::SHOULD); Collection hits = search->search(bq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits[0]->doc); - BOOST_CHECK_EQUAL(0, hits[1]->doc); - BOOST_CHECK(hits[0]->score > hits[1]->score); + EXPECT_EQ(1, hits[0]->doc); + EXPECT_EQ(0, hits[1]->doc); + EXPECT_TRUE(hits[0]->score > hits[1]->score); q1 = csrq(L"data", L"A", L"A", true, true, MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); // matches document #0 q1->setBoost(0.1); @@ -227,9 +225,9 @@ BOOST_AUTO_TEST_CASE(testBoost) bq->add(q2, BooleanClause::SHOULD); hits = search->search(bq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits[0]->doc); - BOOST_CHECK_EQUAL(0, hits[1]->doc); - BOOST_CHECK(hits[0]->score > hits[1]->score); + EXPECT_EQ(1, hits[0]->doc); + EXPECT_EQ(0, hits[1]->doc); + EXPECT_TRUE(hits[0]->score > hits[1]->score); q1 = csrq(L"data", L"A", L"A", true, true); // matches document #0 q1->setBoost(10.0); @@ -239,16 +237,16 @@ BOOST_AUTO_TEST_CASE(testBoost) bq->add(q2, BooleanClause::SHOULD); hits = search->search(bq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits[0]->doc); - BOOST_CHECK_EQUAL(1, hits[1]->doc); - BOOST_CHECK(hits[0]->score > hits[1]->score); + EXPECT_EQ(0, hits[0]->doc); + EXPECT_EQ(1, hits[1]->doc); + EXPECT_TRUE(hits[0]->score > hits[1]->score); } -BOOST_AUTO_TEST_CASE(testBooleanOrderUnAffected) +TEST_F(MultiTermConstantScoreTest, testBooleanOrderUnAffected) { IndexReaderPtr reader = IndexReader::open(small, true); IndexSearcherPtr search = newLucene(reader); - + // first do a regular TermRangeQuery which uses term expansion so docs with more terms in range get higher scores QueryPtr rq = newLucene(L"data", L"1", L"4", true, true); @@ -263,12 +261,12 @@ BOOST_AUTO_TEST_CASE(testBooleanOrderUnAffected) Collection actual = search->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(numHits, actual.size()); + EXPECT_EQ(numHits, actual.size()); for (int32_t i = 0; i < numHits; ++i) - BOOST_CHECK_EQUAL(expected[i]->doc, actual[i]->doc); + EXPECT_EQ(expected[i]->doc, actual[i]->doc); } -BOOST_AUTO_TEST_CASE(testRangeQueryId) +TEST_F(MultiTermConstantScoreTest, testRangeQueryId) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -277,125 +275,125 @@ BOOST_AUTO_TEST_CASE(testRangeQueryId) String nullMin = StringUtils::toString(INT_MIN); String nullMax = StringUtils::toString(INT_MAX); - + String minIP = pad(minId); String maxIP = pad(maxId); String medIP = pad(medId); int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + EXPECT_EQ(numDocs, 1 + maxId - minId); // test id, bounded on both ends Collection result = search->search(csrq(L"id", minIP, maxIP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"id", minIP, maxIP, true, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"id", minIP, maxIP, true, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", minIP, maxIP, true, false, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", minIP, maxIP, false, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", minIP, maxIP, false, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", minIP, maxIP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); result = search->search(csrq(L"id", minIP, maxIP, false, false, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); result = search->search(csrq(L"id", medIP, maxIP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + maxId - medId, result.size()); + EXPECT_EQ(1 + maxId - medId, result.size()); result = search->search(csrq(L"id", medIP, maxIP, true, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + maxId - medId, result.size()); + EXPECT_EQ(1 + maxId - medId, result.size()); result = search->search(csrq(L"id", minIP, medIP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + medId - minId, result.size()); + EXPECT_EQ(1 + medId - minId, result.size()); result = search->search(csrq(L"id", minIP, medIP, true, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + medId - minId, result.size()); + EXPECT_EQ(1 + medId - minId, result.size()); // unbounded id result = search->search(csrq(L"id", minIP, nullMax, true, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"id", nullMin, maxIP, false, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"id", minIP, nullMax, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", nullMin, maxIP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", medIP, maxIP, true, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(maxId - medId, result.size()); + EXPECT_EQ(maxId - medId, result.size()); result = search->search(csrq(L"id", minIP, medIP, false, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(medId - minId, result.size()); + EXPECT_EQ(medId - minId, result.size()); // very small sets result = search->search(csrq(L"id", minIP, minIP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", minIP, minIP, false, false, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", medIP, medIP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", medIP, medIP, false, false, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", maxIP, maxIP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", maxIP, maxIP, false, false, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", minIP, minIP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", minIP, minIP, true, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", nullMin, minIP, false, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", nullMin, minIP, false, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", maxIP, maxIP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", maxIP, maxIP, true, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", maxIP, nullMax, true, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", maxIP, nullMax, true, false, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", medIP, medIP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", medIP, medIP, true, true, MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testRangeQueryIdCollating) +TEST_F(MultiTermConstantScoreTest, testRangeQueryIdCollating) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -404,142 +402,142 @@ BOOST_AUTO_TEST_CASE(testRangeQueryIdCollating) String nullMin = StringUtils::toString(INT_MIN); String nullMax = StringUtils::toString(INT_MAX); - + String minIP = pad(minId); String maxIP = pad(maxId); String medIP = pad(medId); int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + EXPECT_EQ(numDocs, 1 + maxId - minId); CollatorPtr c = newLucene(std::locale()); // test id, bounded on both ends Collection result = search->search(csrq(L"id", minIP, maxIP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"id", minIP, maxIP, true, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", minIP, maxIP, false, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", minIP, maxIP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); result = search->search(csrq(L"id", medIP, maxIP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + maxId - medId, result.size()); + EXPECT_EQ(1 + maxId - medId, result.size()); result = search->search(csrq(L"id", minIP, medIP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + medId - minId, result.size()); + EXPECT_EQ(1 + medId - minId, result.size()); // unbounded id result = search->search(csrq(L"id", minIP, nullMax, true, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"id", nullMin, maxIP, false, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"id", minIP, nullMax, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", nullMin, maxIP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"id", medIP, maxIP, true, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(maxId - medId, result.size()); + EXPECT_EQ(maxId - medId, result.size()); result = search->search(csrq(L"id", minIP, medIP, false, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(medId - minId, result.size()); + EXPECT_EQ(medId - minId, result.size()); // very small sets result = search->search(csrq(L"id", minIP, minIP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", medIP, medIP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", maxIP, maxIP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"id", minIP, minIP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", nullMin, minIP, false, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", maxIP, maxIP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", maxIP, nullMax, true, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"id", medIP, medIP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testRangeQueryRand) +TEST_F(MultiTermConstantScoreTest, testRangeQueryRand) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); String nullMin = StringUtils::toString(INT_MIN); String nullMax = StringUtils::toString(INT_MAX); - + String minRP = pad(signedIndex->minR); String maxRP = pad(signedIndex->maxR); int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + EXPECT_EQ(numDocs, 1 + maxId - minId); // test extremes, bounded on both ends Collection result = search->search(csrq(L"rand", minRP, maxRP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"rand", minRP, maxRP, true, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"rand", minRP, maxRP, false, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"rand", minRP, maxRP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); // unbounded result = search->search(csrq(L"rand", minRP, nullMax, true, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"rand", nullMin, maxRP, false, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"rand", minRP, nullMax, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"rand", nullMin, maxRP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); // very small sets result = search->search(csrq(L"rand", minRP, minRP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"rand", maxRP, maxRP, false, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"rand", minRP, minRP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"rand", nullMin, minRP, false, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"rand", maxRP, maxRP, true, true), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"rand", maxRP, nullMax, true, false), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testRangeQueryRandCollating) +TEST_F(MultiTermConstantScoreTest, testRangeQueryRandCollating) { // using the unsigned index because collation seems to ignore hyphens IndexReaderPtr reader = IndexReader::open(unsignedIndex->index, true); @@ -547,60 +545,58 @@ BOOST_AUTO_TEST_CASE(testRangeQueryRandCollating) String nullMin = StringUtils::toString(INT_MIN); String nullMax = StringUtils::toString(INT_MAX); - + String minRP = pad(unsignedIndex->minR); String maxRP = pad(unsignedIndex->maxR); int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + EXPECT_EQ(numDocs, 1 + maxId - minId); CollatorPtr c = newLucene(std::locale()); // test extremes, bounded on both ends Collection result = search->search(csrq(L"rand", minRP, maxRP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"rand", minRP, maxRP, true, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"rand", minRP, maxRP, false, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"rand", minRP, maxRP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); // unbounded result = search->search(csrq(L"rand", minRP, nullMax, true, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"rand", nullMin, maxRP, false, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(csrq(L"rand", minRP, nullMax, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(csrq(L"rand", nullMin, maxRP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); // very small sets result = search->search(csrq(L"rand", minRP, minRP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"rand", maxRP, maxRP, false, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(csrq(L"rand", minRP, minRP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"rand", nullMin, minRP, false, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"rand", maxRP, maxRP, true, true, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(csrq(L"rand", maxRP, nullMax, true, false, c), FilterPtr(), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/MultiThreadTermVectorsTest.cpp b/src/test/search/MultiThreadTermVectorsTest.cpp index 46839922..b5dcda91 100644 --- a/src/test/search/MultiThreadTermVectorsTest.cpp +++ b/src/test/search/MultiThreadTermVectorsTest.cpp @@ -29,7 +29,7 @@ class MultiThreadTermVectorsReader : public LuceneThread this->reader = reader; timeElapsed = 0; } - + virtual ~MultiThreadTermVectorsReader() { } @@ -41,7 +41,7 @@ class MultiThreadTermVectorsReader : public LuceneThread int64_t timeElapsed; static const int32_t runsToDo; - + public: virtual void run() { @@ -52,7 +52,7 @@ class MultiThreadTermVectorsReader : public LuceneThread } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } @@ -79,7 +79,7 @@ class MultiThreadTermVectorsReader : public LuceneThread verifyVectors(vectors, docId); } } - + void verifyVectors(Collection vectors, int32_t num) { StringStream temp; @@ -90,23 +90,23 @@ class MultiThreadTermVectorsReader : public LuceneThread for (int32_t z = 0; z < terms.size(); ++z) temp << terms[z]; } - + if (intToEnglish(num) != temp.str()) - BOOST_FAIL(intToEnglish(num) << "!=" << temp.str()); + FAIL() << intToEnglish(num) << "!=" << temp.str(); } }; const int32_t MultiThreadTermVectorsReader::runsToDo = 100; -class MultiThreadTermVectorsFixture : public LuceneTestFixture +class MultiThreadTermVectorsTest : public LuceneTestFixture { public: - MultiThreadTermVectorsFixture() + MultiThreadTermVectorsTest() { directory = newLucene(); numDocs = 100; numThreads = 3; - + IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < numDocs; ++i) { @@ -117,8 +117,8 @@ class MultiThreadTermVectorsFixture : public LuceneTestFixture } writer->close(); } - - virtual ~MultiThreadTermVectorsFixture() + + virtual ~MultiThreadTermVectorsTest() { } @@ -136,18 +136,16 @@ class MultiThreadTermVectorsFixture : public LuceneTestFixture mtr[i] = newLucene(reader); mtr[i]->start(); } - + for (int32_t i = 0; i < threadCount; ++i) mtr[i]->join(); } }; -BOOST_FIXTURE_TEST_SUITE(MultiThreadTermVectorsTest, MultiThreadTermVectorsFixture) - -BOOST_AUTO_TEST_CASE(testMultiThreadTermVectors) +TEST_F(MultiThreadTermVectorsTest, testMultiThreadTermVectors) { IndexReaderPtr reader; - + try { reader = IndexReader::open(directory, true); @@ -156,8 +154,6 @@ BOOST_AUTO_TEST_CASE(testMultiThreadTermVectors) } catch (LuceneException& e) { - BOOST_FAIL(e.getError()); + FAIL() << e.getError(); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/MultiValuedNumericRangeQueryTest.cpp b/src/test/search/MultiValuedNumericRangeQueryTest.cpp index f7e441fa..2612c3d4 100644 --- a/src/test/search/MultiValuedNumericRangeQueryTest.cpp +++ b/src/test/search/MultiValuedNumericRangeQueryTest.cpp @@ -20,12 +20,12 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(MultiValuedNumericRangeQueryTest, LuceneTestFixture) +typedef LuceneTestFixture MultiValuedNumericRangeQueryTest; static String pad(int32_t n) { int32_t intLength = String(L"00000000000").length(); - + StringStream buf; String p = L"0"; if (n < 0) @@ -38,10 +38,10 @@ static String pad(int32_t n) for (int32_t i = s.length(); i <= intLength; ++i) buf << L"0"; buf << s; - return buf.str(); + return buf.str(); } -BOOST_AUTO_TEST_CASE(testMultiValuedNRQ) +TEST_F(MultiValuedNumericRangeQueryTest, testMultiValuedNRQ) { RandomPtr rnd = newLucene(); @@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(testMultiValuedNRQ) writer->addDocument(doc); } writer->close(); - + SearcherPtr searcher = newLucene(directory, true); for (int32_t i = 0; i < 50; ++i) { @@ -72,9 +72,7 @@ BOOST_AUTO_TEST_CASE(testMultiValuedNRQ) NumericRangeQueryPtr tq = NumericRangeQuery::newIntRange(L"trie", lower, upper, true, true); TopDocsPtr trTopDocs = searcher->search(cq, 1); TopDocsPtr nrTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(trTopDocs->totalHits, nrTopDocs->totalHits); + EXPECT_EQ(trTopDocs->totalHits, nrTopDocs->totalHits); } searcher->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/NotTest.cpp b/src/test/search/NotTest.cpp index 4bc8f2b5..c1f81462 100644 --- a/src/test/search/NotTest.cpp +++ b/src/test/search/NotTest.cpp @@ -19,9 +19,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(NotTest, LuceneTestFixture) +typedef LuceneTestFixture NotTest; -BOOST_AUTO_TEST_CASE(testNot) +TEST_F(NotTest, testNot) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -37,7 +37,5 @@ BOOST_AUTO_TEST_CASE(testNot) QueryParserPtr parser = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); QueryPtr query = parser->parse(L"a NOT b"); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/NumericRangeQuery32Test.cpp b/src/test/search/NumericRangeQuery32Test.cpp index f7f54b05..b4fad67c 100644 --- a/src/test/search/NumericRangeQuery32Test.cpp +++ b/src/test/search/NumericRangeQuery32Test.cpp @@ -33,10 +33,10 @@ using namespace Lucene; -class NumericRangeQuery32Fixture : public LuceneTestFixture +class NumericRangeQuery32Test : public LuceneTestFixture { public: - NumericRangeQuery32Fixture() + NumericRangeQuery32Test() { static bool setupRequired = true; if (setupRequired) @@ -45,21 +45,21 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture setupRequired = false; } } - - virtual ~NumericRangeQuery32Fixture() + + virtual ~NumericRangeQuery32Test() { } protected: // distance of entries static const int32_t distance; - + // shift the starting of the values to the left, to also have negative values static const int32_t startOffset; - + // number of docs to generate for testing static const int32_t noDocs; - + static RAMDirectoryPtr directory; static IndexSearcherPtr searcher; @@ -82,18 +82,18 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture NumericFieldPtr ascfield2 = newLucene(L"ascfield2", 2, Field::STORE_NO, true); DocumentPtr doc = newLucene(); - + // add fields, that have a distance to test general functionality doc->add(field8); - doc->add(field4); - doc->add(field2); + doc->add(field4); + doc->add(field2); doc->add(fieldNoTrie); - + // add ascending fields with a distance of 1, beginning at -noDocs/2 to test the correct splitting of range and inclusive/exclusive doc->add(ascfield8); doc->add(ascfield4); doc->add(ascfield2); - + // Add a series of noDocs docs with increasing int values for (int32_t l = 0; l < noDocs; ++l) { @@ -109,12 +109,12 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture ascfield2->setIntValue(val); writer->addDocument(doc); } - + writer->optimize(); writer->close(); searcher = newLucene(directory, true); } - + public: /// test for both constant score and boolean query, the other tests only use the constant score mode void testRange(int32_t precisionStep) @@ -123,7 +123,7 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture int32_t count = 3000; int32_t lower = (distance * 3 / 2) + startOffset; int32_t upper = lower + count * distance + (distance / 3); - + NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, true, true); NumericRangeFilterPtr f = NumericRangeFilter::newIntRange(field, precisionStep, lower, upper, true, true); int32_t lastTerms = 0; @@ -156,20 +156,20 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture default: return; } - BOOST_TEST_MESSAGE("Found " << terms << " distinct terms in range for field '" << field << "'" << type << "."); + // std::cout << "Found " << terms << " distinct terms in range for field '" << field << "'" << type << "."; Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(count, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(count, sd.size()); DocumentPtr doc = searcher->doc(sd[0]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString(2 * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString(2 * distance + startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString((1 + count) * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString((1 + count) * distance + startOffset), doc->get(field)); if (i > 0) - BOOST_CHECK_EQUAL(lastTerms, terms); + EXPECT_EQ(lastTerms, terms); lastTerms = terms; } } - + void testLeftOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); @@ -178,14 +178,14 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(field, precisionStep, INT_MIN, upper, true, true); TopDocsPtr topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(count, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(count, sd.size()); DocumentPtr doc = searcher->doc(sd[0]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString(startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString(startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString((count - 1) * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString((count - 1) * distance + startOffset), doc->get(field)); } - + void testRightOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); @@ -194,14 +194,14 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(field, precisionStep, lower, INT_MAX, true, true); TopDocsPtr topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(noDocs - count, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(noDocs - count, sd.size()); DocumentPtr doc = searcher->doc(sd[0]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString(count * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString(count * distance + startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString((noDocs - 1) * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString((noDocs - 1) * distance + startOffset), doc->get(field)); } - + void testRandomTrieAndClassicRangeQuery(int32_t precisionStep) { RandomPtr rnd = newLucene(); @@ -219,7 +219,7 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture TermRangeQueryPtr cq = newLucene(field, NumericUtils::intToPrefixCoded(lower), NumericUtils::intToPrefixCoded(upper), true, true); TopDocsPtr tTopDocs = searcher->search(tq, 1); TopDocsPtr cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); // test exclusive range @@ -227,7 +227,7 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture cq = newLucene(field, NumericUtils::intToPrefixCoded(lower), NumericUtils::intToPrefixCoded(upper), false, false); tTopDocs = searcher->search(tq, 1); cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); // test left exclusive range @@ -235,7 +235,7 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture cq = newLucene(field, NumericUtils::intToPrefixCoded(lower), NumericUtils::intToPrefixCoded(upper), false, true); tTopDocs = searcher->search(tq, 1); cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); // test right exclusive range @@ -243,14 +243,14 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture cq = newLucene(field, NumericUtils::intToPrefixCoded(lower), NumericUtils::intToPrefixCoded(upper), true, false); tTopDocs = searcher->search(tq, 1); cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); } if (precisionStep == INT_MAX) - BOOST_CHECK_EQUAL(termCountT, termCountC); + EXPECT_EQ(termCountT, termCountC); } - + void testRangeSplit(int32_t precisionStep) { RandomPtr rnd = newLucene(); @@ -265,22 +265,22 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture // test inclusive range QueryPtr tq = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, true, true); TopDocsPtr tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(upper - lower + 1, tTopDocs->totalHits); + EXPECT_EQ(upper - lower + 1, tTopDocs->totalHits); // test exclusive range tq = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, false, false); tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(std::max(upper - lower - 1, (int32_t)0), tTopDocs->totalHits); + EXPECT_EQ(std::max(upper - lower - 1, (int32_t)0), tTopDocs->totalHits); // test left exclusive range tq = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, false, true); tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(upper - lower, tTopDocs->totalHits); + EXPECT_EQ(upper - lower, tTopDocs->totalHits); // test right exclusive range tq = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, true, false); tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(upper - lower, tTopDocs->totalHits); + EXPECT_EQ(upper - lower, tTopDocs->totalHits); } } - + void testSorting(int32_t precisionStep) { RandomPtr rnd = newLucene(); @@ -297,17 +297,17 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture if (topDocs->totalHits == 0) continue; Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); + EXPECT_TRUE(sd); int32_t last = StringUtils::toInt(searcher->doc(sd[0]->doc)->get(field)); for (int32_t j = 1; j < sd.size(); ++j) { int32_t act = StringUtils::toInt(searcher->doc(sd[j]->doc)->get(field)); - BOOST_CHECK(last > act); + EXPECT_TRUE(last > act); last = act; } } } - + void testEnumRange(int32_t lower, int32_t upper) { NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(L"field4", 4, lower, upper, true, true); @@ -318,147 +318,145 @@ class NumericRangeQuery32Fixture : public LuceneTestFixture if (t) { int32_t val = NumericUtils::prefixCodedToInt(t->text()); - BOOST_CHECK(val >= lower && val <= upper); + EXPECT_TRUE(val >= lower && val <= upper); } else break; } while (termEnum->next()); - BOOST_CHECK(!termEnum->next()); + EXPECT_TRUE(!termEnum->next()); termEnum->close(); } }; // distance of entries -const int32_t NumericRangeQuery32Fixture::distance = 6666; - +const int32_t NumericRangeQuery32Test::distance = 6666; + // shift the starting of the values to the left, to also have negative values -const int32_t NumericRangeQuery32Fixture::startOffset = -1 << 15; +const int32_t NumericRangeQuery32Test::startOffset = -1 << 15; // number of docs to generate for testing -const int32_t NumericRangeQuery32Fixture::noDocs = 10000; - -RAMDirectoryPtr NumericRangeQuery32Fixture::directory; -IndexSearcherPtr NumericRangeQuery32Fixture::searcher; +const int32_t NumericRangeQuery32Test::noDocs = 10000; -BOOST_FIXTURE_TEST_SUITE(NumericRangeQuery32Test, NumericRangeQuery32Fixture) +RAMDirectoryPtr NumericRangeQuery32Test::directory; +IndexSearcherPtr NumericRangeQuery32Test::searcher; -BOOST_AUTO_TEST_CASE(testRange_8bit) +TEST_F(NumericRangeQuery32Test, testRange_8bit) { testRange(8); } -BOOST_AUTO_TEST_CASE(testRange_4bit) +TEST_F(NumericRangeQuery32Test, testRange_4bit) { testRange(4); } -BOOST_AUTO_TEST_CASE(testRange_2bit) +TEST_F(NumericRangeQuery32Test, testRange_2bit) { testRange(2); } -BOOST_AUTO_TEST_CASE(testInverseRange) +TEST_F(NumericRangeQuery32Test, testInverseRange) { NumericRangeFilterPtr f = NumericRangeFilter::newIntRange(L"field8", 8, 1000, -1000, true, true); - BOOST_CHECK_EQUAL(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); + EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); f = NumericRangeFilter::newIntRange(L"field8", 8, INT_MAX, INT_MIN, false, false); - BOOST_CHECK_EQUAL(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); + EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); f = NumericRangeFilter::newIntRange(L"field8", 8, INT_MIN, INT_MIN, false, false); - BOOST_CHECK_EQUAL(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); + EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); } -BOOST_AUTO_TEST_CASE(testOneMatchQuery) +TEST_F(NumericRangeQuery32Test, testOneMatchQuery) { NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(L"ascfield8", 8, 1000, 1000, true, true); - BOOST_CHECK_EQUAL(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(), q->getRewriteMethod()); + EXPECT_EQ(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(), q->getRewriteMethod()); TopDocsPtr topDocs = searcher->search(q, noDocs); Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(1, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(1, sd.size()); } -BOOST_AUTO_TEST_CASE(testLeftOpenRange_8bit) +TEST_F(NumericRangeQuery32Test, testLeftOpenRange_8bit) { testLeftOpenRange(8); } -BOOST_AUTO_TEST_CASE(testLeftOpenRange_4bit) +TEST_F(NumericRangeQuery32Test, testLeftOpenRange_4bit) { testLeftOpenRange(4); } -BOOST_AUTO_TEST_CASE(testLeftOpenRange_2bit) +TEST_F(NumericRangeQuery32Test, testLeftOpenRange_2bit) { testLeftOpenRange(2); } -BOOST_AUTO_TEST_CASE(testRightOpenRange_8bit) +TEST_F(NumericRangeQuery32Test, testRightOpenRange_8bit) { testRightOpenRange(8); } -BOOST_AUTO_TEST_CASE(testRightOpenRange_4bit) +TEST_F(NumericRangeQuery32Test, testRightOpenRange_4bit) { testRightOpenRange(4); } -BOOST_AUTO_TEST_CASE(testRightOpenRange_2bit) +TEST_F(NumericRangeQuery32Test, testRightOpenRange_2bit) { testRightOpenRange(2); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_8bit) +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_8bit) { testRandomTrieAndClassicRangeQuery(8); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_4bit) +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_4bit) { testRandomTrieAndClassicRangeQuery(4); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_2bit) +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_2bit) { testRandomTrieAndClassicRangeQuery(2); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_NoTrie) +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_NoTrie) { testRandomTrieAndClassicRangeQuery(INT_MAX); } -BOOST_AUTO_TEST_CASE(testRangeSplit_8bit) +TEST_F(NumericRangeQuery32Test, testRangeSplit_8bit) { testRangeSplit(8); } -BOOST_AUTO_TEST_CASE(testRangeSplit_4bit) +TEST_F(NumericRangeQuery32Test, testRangeSplit_4bit) { testRangeSplit(4); } -BOOST_AUTO_TEST_CASE(testRangeSplit_2bit) +TEST_F(NumericRangeQuery32Test, testRangeSplit_2bit) { testRangeSplit(2); } -BOOST_AUTO_TEST_CASE(testSorting_8bit) +TEST_F(NumericRangeQuery32Test, testSorting_8bit) { testSorting(8); } -BOOST_AUTO_TEST_CASE(testSorting_4bit) +TEST_F(NumericRangeQuery32Test, testSorting_4bit) { testSorting(4); } -BOOST_AUTO_TEST_CASE(testSorting_2bit) +TEST_F(NumericRangeQuery32Test, testSorting_2bit) { testSorting(2); } -BOOST_AUTO_TEST_CASE(testEqualsAndHash) +TEST_F(NumericRangeQuery32Test, testEqualsAndHash) { QueryUtils::checkHashEquals(NumericRangeQuery::newIntRange(L"test1", 4, 10, 20, true, true)); QueryUtils::checkHashEquals(NumericRangeQuery::newIntRange(L"test2", 4, 10, 20, false, true)); @@ -473,30 +471,28 @@ BOOST_AUTO_TEST_CASE(testEqualsAndHash) QueryUtils::checkUnequal(NumericRangeQuery::newIntRange(L"test11", 4, 10, 20, true, true), NumericRangeQuery::newIntRange(L"test11", 4, 20, 10, true, true)); QueryUtils::checkUnequal(NumericRangeQuery::newIntRange(L"test12", 4, 10, 20, true, true), NumericRangeQuery::newIntRange(L"test12", 4, 10, 20, false, true)); QueryUtils::checkUnequal(NumericRangeQuery::newIntRange(L"test13", 4, 10, 20, true, true), NumericRangeQuery::newDoubleRange(L"test13", 4, 10.0, 20.0, true, true)); - + // the following produces a hash collision, because Long and Integer have the same hashcode, so only test equality QueryPtr q1 = NumericRangeQuery::newIntRange(L"test14", 4, 10, 20, true, true); QueryPtr q2 = NumericRangeQuery::newLongRange(L"test14", 4, 10, 20, true, true); - BOOST_CHECK(!q1->equals(q2)); - BOOST_CHECK(!q2->equals(q1)); + EXPECT_TRUE(!q1->equals(q2)); + EXPECT_TRUE(!q2->equals(q1)); } -BOOST_AUTO_TEST_CASE(testEnum) +TEST_F(NumericRangeQuery32Test, testEnum) { int32_t count = 3000; int32_t lower= (distance * 3 / 2) + startOffset; int32_t upper = lower + count * distance + (distance / 3); - + // test enum with values testEnumRange(lower, upper); - + // test empty enum testEnumRange(upper, lower); - + // test empty enum outside of bounds lower = distance * noDocs + startOffset; upper = 2 * lower; testEnumRange(lower, upper); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/NumericRangeQuery64Test.cpp b/src/test/search/NumericRangeQuery64Test.cpp index a4792c5e..fdfbb948 100644 --- a/src/test/search/NumericRangeQuery64Test.cpp +++ b/src/test/search/NumericRangeQuery64Test.cpp @@ -32,10 +32,10 @@ using namespace Lucene; -class NumericRangeQuery64Fixture : public LuceneTestFixture +class NumericRangeQuery64Test : public LuceneTestFixture { public: - NumericRangeQuery64Fixture() + NumericRangeQuery64Test() { static bool setupRequired = true; if (setupRequired) @@ -44,21 +44,21 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture setupRequired = false; } } - - virtual ~NumericRangeQuery64Fixture() + + virtual ~NumericRangeQuery64Test() { } protected: // distance of entries static const int64_t distance; - + // shift the starting of the values to the left, to also have negative values static const int64_t startOffset; - + // number of docs to generate for testing static const int32_t noDocs; - + static RAMDirectoryPtr directory; static IndexSearcherPtr searcher; @@ -83,20 +83,20 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture NumericFieldPtr ascfield2 = newLucene(L"ascfield2", 2, Field::STORE_NO, true); DocumentPtr doc = newLucene(); - + // add fields, that have a distance to test general functionality doc->add(field8); doc->add(field6); doc->add(field4); - doc->add(field2); + doc->add(field2); doc->add(fieldNoTrie); - + // add ascending fields with a distance of 1, beginning at -noDocs/2 to test the correct splitting of range and inclusive/exclusive doc->add(ascfield8); doc->add(ascfield6); doc->add(ascfield4); doc->add(ascfield2); - + // Add a series of noDocs docs with increasing int values for (int32_t l = 0; l < noDocs; ++l) { @@ -114,12 +114,12 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture ascfield2->setLongValue(val); writer->addDocument(doc); } - + writer->optimize(); writer->close(); searcher = newLucene(directory, true); } - + public: /// test for both constant score and boolean query, the other tests only use the constant score mode void testRange(int32_t precisionStep) @@ -128,7 +128,7 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture int32_t count = 3000; int64_t lower = (distance * 3 / 2) + startOffset; int64_t upper = lower + count * distance + (distance / 3); - + NumericRangeQueryPtr q = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, true, true); NumericRangeFilterPtr f = NumericRangeFilter::newLongRange(field, precisionStep, lower, upper, true, true); int32_t lastTerms = 0; @@ -161,20 +161,20 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture default: return; } - BOOST_TEST_MESSAGE("Found " << terms << " distinct terms in range for field '" << field << "'" << type << "."); + // std::cout << "Found " << terms << " distinct terms in range for field '" << field << "'" << type << "."; Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(count, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(count, sd.size()); DocumentPtr doc = searcher->doc(sd[0]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString(2 * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString(2 * distance + startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString((1 + count) * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString((1 + count) * distance + startOffset), doc->get(field)); if (i > 0) - BOOST_CHECK_EQUAL(lastTerms, terms); + EXPECT_EQ(lastTerms, terms); lastTerms = terms; } } - + void testLeftOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); @@ -184,14 +184,14 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture NumericRangeQueryPtr q = NumericRangeQuery::newLongRange(field, precisionStep, LLONG_MIN, upper, true, true); TopDocsPtr topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(count, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(count, sd.size()); DocumentPtr doc = searcher->doc(sd[0]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString(startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString(startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString((count - 1) * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString((count - 1) * distance + startOffset), doc->get(field)); } - + void testRightOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); @@ -200,14 +200,14 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture NumericRangeQueryPtr q = NumericRangeQuery::newLongRange(field, precisionStep, lower, LLONG_MAX, true, true); TopDocsPtr topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(noDocs - count, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(noDocs - count, sd.size()); DocumentPtr doc = searcher->doc(sd[0]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString(count * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString(count * distance + startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString((noDocs - 1) * distance + startOffset), doc->get(field)); + EXPECT_EQ(StringUtils::toString((noDocs - 1) * distance + startOffset), doc->get(field)); } - + void testRandomTrieAndClassicRangeQuery(int32_t precisionStep) { RandomPtr rnd = newLucene(); @@ -225,7 +225,7 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture TermRangeQueryPtr cq = newLucene(field, NumericUtils::longToPrefixCoded(lower), NumericUtils::longToPrefixCoded(upper), true, true); TopDocsPtr tTopDocs = searcher->search(tq, 1); TopDocsPtr cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); // test exclusive range @@ -233,7 +233,7 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture cq = newLucene(field, NumericUtils::longToPrefixCoded(lower), NumericUtils::longToPrefixCoded(upper), false, false); tTopDocs = searcher->search(tq, 1); cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); // test left exclusive range @@ -241,7 +241,7 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture cq = newLucene(field, NumericUtils::longToPrefixCoded(lower), NumericUtils::longToPrefixCoded(upper), false, true); tTopDocs = searcher->search(tq, 1); cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); // test right exclusive range @@ -249,14 +249,14 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture cq = newLucene(field, NumericUtils::longToPrefixCoded(lower), NumericUtils::longToPrefixCoded(upper), true, false); tTopDocs = searcher->search(tq, 1); cTopDocs = searcher->search(cq, 1); - BOOST_CHECK_EQUAL(cTopDocs->totalHits, tTopDocs->totalHits); + EXPECT_EQ(cTopDocs->totalHits, tTopDocs->totalHits); termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); } if (precisionStep == INT_MAX) - BOOST_CHECK_EQUAL(termCountT, termCountC); + EXPECT_EQ(termCountT, termCountC); } - + void testRangeSplit(int32_t precisionStep) { RandomPtr rnd = newLucene(); @@ -271,22 +271,22 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture // test inclusive range QueryPtr tq = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, true, true); TopDocsPtr tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(upper - lower + 1, tTopDocs->totalHits); + EXPECT_EQ(upper - lower + 1, tTopDocs->totalHits); // test exclusive range tq = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, false, false); tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(std::max(upper - lower - 1, (int64_t)0), tTopDocs->totalHits); + EXPECT_EQ(std::max(upper - lower - 1, (int64_t)0), tTopDocs->totalHits); // test left exclusive range tq = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, false, true); tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(upper - lower, tTopDocs->totalHits); + EXPECT_EQ(upper - lower, tTopDocs->totalHits); // test right exclusive range tq = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, true, false); tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(upper - lower, tTopDocs->totalHits); + EXPECT_EQ(upper - lower, tTopDocs->totalHits); } } - + void testDoubleRange(int32_t precisionStep) { String field = L"ascfield" + StringUtils::toString(precisionStep); @@ -295,13 +295,13 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture QueryPtr tq = NumericRangeQuery::newDoubleRange(field, precisionStep, NumericUtils::sortableLongToDouble(lower), NumericUtils::sortableLongToDouble(upper), true, true); TopDocsPtr tTopDocs = searcher->search(tq, 1); - BOOST_CHECK_EQUAL(upper - lower + 1, tTopDocs->totalHits); + EXPECT_EQ(upper - lower + 1, tTopDocs->totalHits); FilterPtr tf = NumericRangeFilter::newDoubleRange(field, precisionStep, NumericUtils::sortableLongToDouble(lower), NumericUtils::sortableLongToDouble(upper), true, true); tTopDocs = searcher->search(newLucene(), tf, 1); - BOOST_CHECK_EQUAL(upper - lower + 1, tTopDocs->totalHits); + EXPECT_EQ(upper - lower + 1, tTopDocs->totalHits); } - + void testSorting(int32_t precisionStep) { RandomPtr rnd = newLucene(); @@ -318,12 +318,12 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture if (topDocs->totalHits == 0) continue; Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); + EXPECT_TRUE(sd); int64_t last = StringUtils::toInt(searcher->doc(sd[0]->doc)->get(field)); for (int32_t j = 1; j < sd.size(); ++j) { int64_t act = StringUtils::toLong(searcher->doc(sd[j]->doc)->get(field)); - BOOST_CHECK(last > act); + EXPECT_TRUE(last > act); last = act; } } @@ -331,185 +331,183 @@ class NumericRangeQuery64Fixture : public LuceneTestFixture }; // distance of entries -const int64_t NumericRangeQuery64Fixture::distance = 66666; +const int64_t NumericRangeQuery64Test::distance = 66666; // shift the starting of the values to the left, to also have negative values -const int64_t NumericRangeQuery64Fixture::startOffset = (int64_t)-1 << 31; +const int64_t NumericRangeQuery64Test::startOffset = (int64_t)-1 << 31; // number of docs to generate for testing -const int32_t NumericRangeQuery64Fixture::noDocs = 10000; +const int32_t NumericRangeQuery64Test::noDocs = 10000; -RAMDirectoryPtr NumericRangeQuery64Fixture::directory; -IndexSearcherPtr NumericRangeQuery64Fixture::searcher; +RAMDirectoryPtr NumericRangeQuery64Test::directory; +IndexSearcherPtr NumericRangeQuery64Test::searcher; -BOOST_FIXTURE_TEST_SUITE(NumericRangeQuery64Test, NumericRangeQuery64Fixture) - -BOOST_AUTO_TEST_CASE(testRange_8bit) +TEST_F(NumericRangeQuery64Test, testRange_8bit) { testRange(8); } -BOOST_AUTO_TEST_CASE(testRange_6bit) +TEST_F(NumericRangeQuery64Test, testRange_6bit) { testRange(6); } -BOOST_AUTO_TEST_CASE(testRange_4bit) +TEST_F(NumericRangeQuery64Test, testRange_4bit) { testRange(4); } -BOOST_AUTO_TEST_CASE(testRange_2bit) +TEST_F(NumericRangeQuery64Test, testRange_2bit) { testRange(2); } -BOOST_AUTO_TEST_CASE(testInverseRange) +TEST_F(NumericRangeQuery64Test, testInverseRange) { NumericRangeFilterPtr f = NumericRangeFilter::newLongRange(L"field8", 8, 1000, -1000, true, true); - BOOST_CHECK_EQUAL(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); + EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); f = NumericRangeFilter::newLongRange(L"field8", 8, LLONG_MAX, LLONG_MIN, false, false); - BOOST_CHECK_EQUAL(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); + EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); f = NumericRangeFilter::newLongRange(L"field8", 8, LLONG_MIN, LLONG_MIN, false, false); - BOOST_CHECK_EQUAL(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); + EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); } -BOOST_AUTO_TEST_CASE(testOneMatchQuery) +TEST_F(NumericRangeQuery64Test, testOneMatchQuery) { NumericRangeQueryPtr q = NumericRangeQuery::newLongRange(L"ascfield8", 8, 1000, 1000, true, true); - BOOST_CHECK_EQUAL(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(), q->getRewriteMethod()); + EXPECT_EQ(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(), q->getRewriteMethod()); TopDocsPtr topDocs = searcher->search(q, noDocs); Collection sd = topDocs->scoreDocs; - BOOST_CHECK(sd); - BOOST_CHECK_EQUAL(1, sd.size()); + EXPECT_TRUE(sd); + EXPECT_EQ(1, sd.size()); } -BOOST_AUTO_TEST_CASE(testLeftOpenRange_8bit) +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_8bit) { testLeftOpenRange(8); } -BOOST_AUTO_TEST_CASE(testLeftOpenRange_6bit) +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_6bit) { testLeftOpenRange(6); } -BOOST_AUTO_TEST_CASE(testLeftOpenRange_4bit) +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_4bit) { testLeftOpenRange(4); } -BOOST_AUTO_TEST_CASE(testLeftOpenRange_2bit) +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_2bit) { testLeftOpenRange(2); } -BOOST_AUTO_TEST_CASE(testRightOpenRange_8bit) +TEST_F(NumericRangeQuery64Test, testRightOpenRange_8bit) { testRightOpenRange(8); } -BOOST_AUTO_TEST_CASE(testRightOpenRange_6bit) +TEST_F(NumericRangeQuery64Test, testRightOpenRange_6bit) { testRightOpenRange(6); } -BOOST_AUTO_TEST_CASE(testRightOpenRange_4bit) +TEST_F(NumericRangeQuery64Test, testRightOpenRange_4bit) { testRightOpenRange(4); } -BOOST_AUTO_TEST_CASE(testRightOpenRange_2bit) +TEST_F(NumericRangeQuery64Test, testRightOpenRange_2bit) { testRightOpenRange(2); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_8bit) +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_8bit) { testRandomTrieAndClassicRangeQuery(8); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_6bit) +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_6bit) { testRandomTrieAndClassicRangeQuery(6); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_4bit) +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_4bit) { testRandomTrieAndClassicRangeQuery(4); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_2bit) +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_2bit) { testRandomTrieAndClassicRangeQuery(2); } -BOOST_AUTO_TEST_CASE(testRandomTrieAndClassicRangeQuery_NoTrie) +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_NoTrie) { testRandomTrieAndClassicRangeQuery(INT_MAX); } -BOOST_AUTO_TEST_CASE(testRangeSplit_8bit) +TEST_F(NumericRangeQuery64Test, testRangeSplit_8bit) { testRangeSplit(8); } -BOOST_AUTO_TEST_CASE(testRangeSplit_6bit) +TEST_F(NumericRangeQuery64Test, testRangeSplit_6bit) { testRangeSplit(6); } -BOOST_AUTO_TEST_CASE(testRangeSplit_4bit) +TEST_F(NumericRangeQuery64Test, testRangeSplit_4bit) { testRangeSplit(4); } -BOOST_AUTO_TEST_CASE(testRangeSplit_2bit) +TEST_F(NumericRangeQuery64Test, testRangeSplit_2bit) { testRangeSplit(2); } -BOOST_AUTO_TEST_CASE(testDoubleRange_8bit) +TEST_F(NumericRangeQuery64Test, testDoubleRange_8bit) { testDoubleRange(8); } -BOOST_AUTO_TEST_CASE(testDoubleRange_6bit) +TEST_F(NumericRangeQuery64Test, testDoubleRange_6bit) { testDoubleRange(6); } -BOOST_AUTO_TEST_CASE(testDoubleRange_4bit) +TEST_F(NumericRangeQuery64Test, testDoubleRange_4bit) { testDoubleRange(4); } -BOOST_AUTO_TEST_CASE(testDoubleRange_2bit) +TEST_F(NumericRangeQuery64Test, testDoubleRange_2bit) { testDoubleRange(2); } -BOOST_AUTO_TEST_CASE(testSorting_8bit) +TEST_F(NumericRangeQuery64Test, testSorting_8bit) { testSorting(8); } -BOOST_AUTO_TEST_CASE(testSorting_6bit) +TEST_F(NumericRangeQuery64Test, testSorting_6bit) { testSorting(6); } -BOOST_AUTO_TEST_CASE(testSorting_4bit) +TEST_F(NumericRangeQuery64Test, testSorting_4bit) { testSorting(4); } -BOOST_AUTO_TEST_CASE(testSorting_2bit) +TEST_F(NumericRangeQuery64Test, testSorting_2bit) { testSorting(2); } -BOOST_AUTO_TEST_CASE(testEqualsAndHash) +TEST_F(NumericRangeQuery64Test, testEqualsAndHash) { QueryUtils::checkHashEquals(NumericRangeQuery::newLongRange(L"test1", 4, 10, 20, true, true)); QueryUtils::checkHashEquals(NumericRangeQuery::newLongRange(L"test2", 4, 10, 20, false, true)); @@ -525,5 +523,3 @@ BOOST_AUTO_TEST_CASE(testEqualsAndHash) QueryUtils::checkUnequal(NumericRangeQuery::newLongRange(L"test12", 4, 10, 20, true, true), NumericRangeQuery::newLongRange(L"test12", 4, 10, 20, false, true)); QueryUtils::checkUnequal(NumericRangeQuery::newLongRange(L"test13", 4, 10, 20, true, true), NumericRangeQuery::newDoubleRange(L"test13", 4, 10.0, 20.0, true, true)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/ParallelMultiSearcherTest.cpp b/src/test/search/ParallelMultiSearcherTest.cpp index da9b40f1..0e45c0de 100644 --- a/src/test/search/ParallelMultiSearcherTest.cpp +++ b/src/test/search/ParallelMultiSearcherTest.cpp @@ -28,7 +28,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(ParallelMultiSearcherTest, LuceneTestFixture) +typedef LuceneTestFixture ParallelMultiSearcherTest; static MultiSearcherPtr getMultiSearcherInstance(Collection searchers) { @@ -53,7 +53,7 @@ static void initIndex(DirectoryPtr directory, int32_t numDocs, bool create, cons indexWriter->close(); } -BOOST_AUTO_TEST_CASE(testEmptyIndex) +TEST_F(ParallelMultiSearcherTest, testEmptyIndex) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); @@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // performing the search Collection hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); // iterating over the hit documents for (int32_t i = 0; i < hits.size(); ++i) @@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // performing the same search Collection hits2 = mSearcher2->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, hits2.size()); + EXPECT_EQ(4, hits2.size()); // iterating over the hit documents for (int32_t i = 0; i < hits2.size(); ++i) @@ -141,13 +141,13 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // test the subSearcher() method QueryPtr subSearcherQuery = parser->parse(L"id:doc1"); hits2 = mSearcher2->search(subSearcherQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits2.size()); - BOOST_CHECK_EQUAL(0, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[0] - BOOST_CHECK_EQUAL(1, mSearcher2->subSearcher(hits2[1]->doc)); // hit from searchers2[1] + EXPECT_EQ(2, hits2.size()); + EXPECT_EQ(0, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[0] + EXPECT_EQ(1, mSearcher2->subSearcher(hits2[1]->doc)); // hit from searchers2[1] subSearcherQuery = parser->parse(L"id:doc2"); hits2 = mSearcher2->search(subSearcherQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits2.size()); - BOOST_CHECK_EQUAL(1, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[1] + EXPECT_EQ(1, hits2.size()); + EXPECT_EQ(1, mSearcher2->subSearcher(hits2[0]->doc)); // hit from searchers2[1] mSearcher2->close(); //-------------------------------------------------------------------- @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) // performing the same search Collection hits3 = mSearcher3->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits3.size()); + EXPECT_EQ(3, hits3.size()); // iterating over the hit documents for (int32_t i = 0; i < hits3.size(); ++i) @@ -183,11 +183,11 @@ BOOST_AUTO_TEST_CASE(testEmptyIndex) indexStoreB->close(); } -BOOST_AUTO_TEST_CASE(testFieldSelector) +TEST_F(ParallelMultiSearcherTest, testFieldSelector) { RAMDirectoryPtr ramDirectory1 = newLucene(); RAMDirectoryPtr ramDirectory2 = newLucene(); - + QueryPtr query = newLucene(newLucene(L"contents", L"doc0")); // Now put the documents in a different index @@ -198,35 +198,35 @@ BOOST_AUTO_TEST_CASE(testFieldSelector) IndexSearcherPtr indexSearcher2 = newLucene(ramDirectory2, true); MultiSearcherPtr searcher = getMultiSearcherInstance(newCollection(indexSearcher1, indexSearcher2)); - BOOST_CHECK(searcher); + EXPECT_TRUE(searcher); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits.size(), 2); + EXPECT_TRUE(hits); + EXPECT_EQ(hits.size(), 2); DocumentPtr document = searcher->doc(hits[0]->doc); - BOOST_CHECK(document); - BOOST_CHECK_EQUAL(document->getFields().size(), 2); + EXPECT_TRUE(document); + EXPECT_EQ(document->getFields().size(), 2); // Should be one document from each directory they both have two fields, contents and other HashSet ftl = HashSet::newInstance(); ftl.add(L"other"); SetBasedFieldSelectorPtr fs = newLucene(ftl, HashSet::newInstance()); document = searcher->doc(hits[0]->doc, fs); - BOOST_CHECK(document); - BOOST_CHECK_EQUAL(document->getFields().size(), 1); + EXPECT_TRUE(document); + EXPECT_EQ(document->getFields().size(), 1); String value = document->get(L"contents"); - BOOST_CHECK(value.empty()); + EXPECT_TRUE(value.empty()); value = document->get(L"other"); - BOOST_CHECK(!value.empty()); + EXPECT_TRUE(!value.empty()); ftl.clear(); ftl.add(L"contents"); fs = newLucene(ftl, HashSet::newInstance()); document = searcher->doc(hits[1]->doc, fs); value = document->get(L"contents"); - BOOST_CHECK(!value.empty()); + EXPECT_TRUE(!value.empty()); value = document->get(L"other"); - BOOST_CHECK(value.empty()); + EXPECT_TRUE(value.empty()); } -BOOST_AUTO_TEST_CASE(testNormalization) +TEST_F(ParallelMultiSearcherTest, testNormalization) { int32_t numDocs = 10; @@ -241,11 +241,11 @@ BOOST_AUTO_TEST_CASE(testNormalization) indexSearcher1->setDefaultFieldSortScoring(true, true); Collection hits = indexSearcher1->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); // Store the scores for use later Collection scores = newCollection(hits[0]->score, hits[1]->score); - BOOST_CHECK(scores[0] > scores[1]); + EXPECT_TRUE(scores[0] > scores[1]); indexSearcher1->close(); ramDirectory1->close(); @@ -267,19 +267,19 @@ BOOST_AUTO_TEST_CASE(testNormalization) hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); // The scores should be the same (within reason) - BOOST_CHECK_CLOSE_FRACTION(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 - BOOST_CHECK_CLOSE_FRACTION(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 + EXPECT_NEAR(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 + EXPECT_NEAR(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 // Adding a Sort.RELEVANCE object should not change anything hits = searcher->search(query, FilterPtr(), 1000, Sort::RELEVANCE())->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); - BOOST_CHECK_CLOSE_FRACTION(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 - BOOST_CHECK_CLOSE_FRACTION(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 + EXPECT_NEAR(scores[0], hits[0]->score, 1e-6); // This will a document from ramDirectory1 + EXPECT_NEAR(scores[1], hits[1]->score, 1e-6); // This will a document from ramDirectory2 searcher->close(); @@ -295,33 +295,33 @@ namespace TestCustomSimilarity virtual ~CustomSimilarity() { } - + public: virtual double idf(int32_t docFreq, int32_t numDocs) { return 100.0; } - + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - + virtual double sloppyFreq(int32_t distance) { return 1.0; } - + virtual double tf(double freq) { return 1.0; @@ -329,7 +329,7 @@ namespace TestCustomSimilarity }; } -BOOST_AUTO_TEST_CASE(testCustomSimilarity) +TEST_F(ParallelMultiSearcherTest, testCustomSimilarity) { RAMDirectoryPtr dir = newLucene(); initIndex(dir, 10, true, L"x"); // documents with two tokens "doc0" and "x", "doc1" and x, etc... @@ -351,10 +351,10 @@ BOOST_AUTO_TEST_CASE(testCustomSimilarity) double scoreN = topDocs->maxScore; // The scores from the IndexSearcher and Multisearcher should be the same if the same similarity is used. - BOOST_CHECK_CLOSE_FRACTION(score1, scoreN, 1e-6); + EXPECT_NEAR(score1, scoreN, 1e-6); } -BOOST_AUTO_TEST_CASE(testDocFreq) +TEST_F(ParallelMultiSearcherTest, testDocFreq) { RAMDirectoryPtr dir1 = newLucene(); RAMDirectoryPtr dir2 = newLucene(); @@ -365,7 +365,5 @@ BOOST_AUTO_TEST_CASE(testDocFreq) IndexSearcherPtr searcher2 = newLucene(dir2, true); MultiSearcherPtr multiSearcher = getMultiSearcherInstance(newCollection(searcher1, searcher2)); - BOOST_CHECK_EQUAL(15, multiSearcher->docFreq(newLucene(L"contents", L"x"))); + EXPECT_EQ(15, multiSearcher->docFreq(newLucene(L"contents", L"x"))); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/PhrasePrefixQueryTest.cpp b/src/test/search/PhrasePrefixQueryTest.cpp index c2b7a033..2049e4e1 100644 --- a/src/test/search/PhrasePrefixQueryTest.cpp +++ b/src/test/search/PhrasePrefixQueryTest.cpp @@ -22,9 +22,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PhrasePrefixQueryTest, LuceneTestFixture) +typedef LuceneTestFixture PhrasePrefixQueryTest; -BOOST_AUTO_TEST_CASE(testPhrasePrefix) +TEST_F(PhrasePrefixQueryTest, testPhrasePrefix) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -65,15 +65,13 @@ BOOST_AUTO_TEST_CASE(testPhrasePrefix) termsWithPrefix.add(te->term()); } while (te->next()); - + query1->add(termsWithPrefix); query2->add(termsWithPrefix); Collection result = searcher->search(query1, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, result.size()); + EXPECT_EQ(2, result.size()); result = searcher->search(query2, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/PhraseQueryTest.cpp b/src/test/search/PhraseQueryTest.cpp index 311246cf..861926ba 100644 --- a/src/test/search/PhraseQueryTest.cpp +++ b/src/test/search/PhraseQueryTest.cpp @@ -38,17 +38,17 @@ class PhraseQueryAnalyzer : public Analyzer { return newLucene(reader); } - + virtual int32_t getPositionIncrementGap(const String& fieldName) { return 100; } }; -class PhraseQueryFixture : public LuceneTestFixture +class PhraseQueryTest : public LuceneTestFixture { public: - PhraseQueryFixture() + PhraseQueryTest() { directory = newLucene(); AnalyzerPtr analyzer = newLucene(); @@ -76,8 +76,8 @@ class PhraseQueryFixture : public LuceneTestFixture searcher = newLucene(directory, true); query = newLucene(); } - - virtual ~PhraseQueryFixture() + + virtual ~PhraseQueryTest() { searcher->close(); directory->close(); @@ -93,56 +93,54 @@ class PhraseQueryFixture : public LuceneTestFixture RAMDirectoryPtr directory; }; -const double PhraseQueryFixture::SCORE_COMP_THRESH = 1e-6f; +const double PhraseQueryTest::SCORE_COMP_THRESH = 1e-6f; -BOOST_FIXTURE_TEST_SUITE(PhraseQueryTest, PhraseQueryFixture) - -BOOST_AUTO_TEST_CASE(testNotCloseEnough) +TEST_F(PhraseQueryTest, testNotCloseEnough) { query->setSlop(2); query->add(newLucene(L"field", L"one")); query->add(newLucene(L"field", L"five")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); } -BOOST_AUTO_TEST_CASE(testBarelyCloseEnough) +TEST_F(PhraseQueryTest, testBarelyCloseEnough) { query->setSlop(3); query->add(newLucene(L"field", L"one")); query->add(newLucene(L"field", L"five")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); } /// Ensures slop of 0 works for exact matches, but not reversed -BOOST_AUTO_TEST_CASE(testExact) +TEST_F(PhraseQueryTest, testExact) { // slop is zero by default query->add(newLucene(L"field", L"four")); query->add(newLucene(L"field", L"five")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); query = newLucene(); query->add(newLucene(L"field", L"two")); query->add(newLucene(L"field", L"one")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); } -BOOST_AUTO_TEST_CASE(testSlop1) +TEST_F(PhraseQueryTest, testSlop1) { // Ensures slop of 1 works with terms in order. query->setSlop(1); query->add(newLucene(L"field", L"one")); query->add(newLucene(L"field", L"two")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); // Ensures slop of 1 does not work for phrases out of order; must be at least 2 @@ -151,19 +149,19 @@ BOOST_AUTO_TEST_CASE(testSlop1) query->add(newLucene(L"field", L"two")); query->add(newLucene(L"field", L"one")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); } /// As long as slop is at least 2, terms can be reversed -BOOST_AUTO_TEST_CASE(testOrderDoesntMatter) +TEST_F(PhraseQueryTest, testOrderDoesntMatter) { // must be at least two for reverse order match query->setSlop(2); query->add(newLucene(L"field", L"two")); query->add(newLucene(L"field", L"one")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); query = newLucene(); @@ -171,19 +169,19 @@ BOOST_AUTO_TEST_CASE(testOrderDoesntMatter) query->add(newLucene(L"field", L"three")); query->add(newLucene(L"field", L"one")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); } /// Slop is the total number of positional moves allowed to line up a phrase -BOOST_AUTO_TEST_CASE(testMulipleTerms) +TEST_F(PhraseQueryTest, testMulipleTerms) { query->setSlop(2); query->add(newLucene(L"field", L"one")); query->add(newLucene(L"field", L"three")); query->add(newLucene(L"field", L"five")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); query = newLucene(); @@ -192,16 +190,16 @@ BOOST_AUTO_TEST_CASE(testMulipleTerms) query->add(newLucene(L"field", L"three")); query->add(newLucene(L"field", L"one")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); - + query->setSlop(6); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); } -BOOST_AUTO_TEST_CASE(testPhraseQueryWithStopAnalyzer) +TEST_F(PhraseQueryTest, testPhraseQueryWithStopAnalyzer) { RAMDirectoryPtr directory = newLucene(); StopAnalyzerPtr stopAnalyzer = newLucene(LuceneVersion::LUCENE_24); @@ -218,7 +216,7 @@ BOOST_AUTO_TEST_CASE(testPhraseQueryWithStopAnalyzer) query->add(newLucene(L"field", L"stop")); query->add(newLucene(L"field", L"words")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); // StopAnalyzer as of 2.4 does not leave "holes", so this matches. @@ -226,13 +224,13 @@ BOOST_AUTO_TEST_CASE(testPhraseQueryWithStopAnalyzer) query->add(newLucene(L"field", L"words")); query->add(newLucene(L"field", L"here")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); searcher->close(); } -BOOST_AUTO_TEST_CASE(testPhraseQueryInConjunctionScorer) +TEST_F(PhraseQueryTest, testPhraseQueryInConjunctionScorer) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -243,7 +241,7 @@ BOOST_AUTO_TEST_CASE(testPhraseQueryInConjunctionScorer) doc = newLucene(); doc->add(newLucene(L"contents", L"foobar", Field::STORE_YES, Field::INDEX_ANALYZED)); - doc->add(newLucene(L"source", L"marketing info", Field::STORE_YES, Field::INDEX_ANALYZED)); + doc->add(newLucene(L"source", L"marketing info", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); writer->optimize(); @@ -255,7 +253,7 @@ BOOST_AUTO_TEST_CASE(testPhraseQueryInConjunctionScorer) phraseQuery->add(newLucene(L"source", L"marketing")); phraseQuery->add(newLucene(L"source", L"info")); Collection hits = searcher->search(phraseQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); QueryUtils::check(phraseQuery, searcher); TermQueryPtr termQuery = newLucene(newLucene(L"contents", L"foobar")); @@ -263,7 +261,7 @@ BOOST_AUTO_TEST_CASE(testPhraseQueryInConjunctionScorer) booleanQuery->add(termQuery, BooleanClause::MUST); booleanQuery->add(phraseQuery, BooleanClause::MUST); hits = searcher->search(booleanQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(termQuery, searcher); searcher->close(); @@ -292,28 +290,28 @@ BOOST_AUTO_TEST_CASE(testPhraseQueryInConjunctionScorer) phraseQuery->add(newLucene(L"contents", L"entry")); hits = searcher->search(termQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); hits = searcher->search(phraseQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); booleanQuery = newLucene(); booleanQuery->add(termQuery, BooleanClause::MUST); booleanQuery->add(phraseQuery, BooleanClause::MUST); hits = searcher->search(booleanQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); booleanQuery = newLucene(); booleanQuery->add(phraseQuery, BooleanClause::MUST); booleanQuery->add(termQuery, BooleanClause::MUST); hits = searcher->search(booleanQuery, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); QueryUtils::check(booleanQuery, searcher); searcher->close(); directory->close(); } -BOOST_AUTO_TEST_CASE(testSlopScoring) +TEST_F(PhraseQueryTest, testSlopScoring) { DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -339,29 +337,29 @@ BOOST_AUTO_TEST_CASE(testSlopScoring) query->add(newLucene(L"field", L"lastname")); query->setSlop(INT_MAX); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); // Make sure that those matches where the terms appear closer to each other get a higher score - BOOST_CHECK_CLOSE_FRACTION(0.71, hits[0]->score, 0.01); - BOOST_CHECK_EQUAL(0, hits[0]->doc); - BOOST_CHECK_CLOSE_FRACTION(0.44, hits[1]->score, 0.01); - BOOST_CHECK_EQUAL(1, hits[1]->doc); - BOOST_CHECK_CLOSE_FRACTION(0.31, hits[2]->score, 0.01); - BOOST_CHECK_EQUAL(2, hits[2]->doc); - QueryUtils::check(query, searcher); + EXPECT_NEAR(0.71, hits[0]->score, 0.01); + EXPECT_EQ(0, hits[0]->doc); + EXPECT_NEAR(0.44, hits[1]->score, 0.01); + EXPECT_EQ(1, hits[1]->doc); + EXPECT_NEAR(0.31, hits[2]->score, 0.01); + EXPECT_EQ(2, hits[2]->doc); + QueryUtils::check(query, searcher); } -BOOST_AUTO_TEST_CASE(testToString) +TEST_F(PhraseQueryTest, testToString) { StopAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", analyzer); qp->setEnablePositionIncrements(true); PhraseQueryPtr q = boost::dynamic_pointer_cast(qp->parse(L"\"this hi this is a test is\"")); - BOOST_CHECK_EQUAL(L"field:\"? hi ? ? ? test\"", q->toString()); + EXPECT_EQ(L"field:\"? hi ? ? ? test\"", q->toString()); q->add(newLucene(L"field", L"hello"), 1); - BOOST_CHECK_EQUAL(L"field:\"? hi|hello ? ? ? test\"", q->toString()); + EXPECT_EQ(L"field:\"? hi|hello ? ? ? test\"", q->toString()); } -BOOST_AUTO_TEST_CASE(testWrappedPhrase) +TEST_F(PhraseQueryTest, testWrappedPhrase) { query->add(newLucene(L"repeated", L"first")); query->add(newLucene(L"repeated", L"part")); @@ -370,18 +368,18 @@ BOOST_AUTO_TEST_CASE(testWrappedPhrase) query->setSlop(100); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); query->setSlop(99); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); } /// work on two docs like this: "phrase exist notexist exist found" -BOOST_AUTO_TEST_CASE(testNonExistingPhrase) +TEST_F(PhraseQueryTest, testNonExistingPhrase) { // phrase without repetitions that exists in 2 docs query->add(newLucene(L"nonexist", L"phrase")); @@ -390,7 +388,7 @@ BOOST_AUTO_TEST_CASE(testNonExistingPhrase) query->setSlop(2); // would be found this way Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); QueryUtils::check(query, searcher); // phrase with repetitions that exists in 2 docs @@ -398,10 +396,10 @@ BOOST_AUTO_TEST_CASE(testNonExistingPhrase) query->add(newLucene(L"nonexist", L"phrase")); query->add(newLucene(L"nonexist", L"exist")); query->add(newLucene(L"nonexist", L"exist")); - query->setSlop(1); // would be found + query->setSlop(1); // would be found hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); QueryUtils::check(query, searcher); // phrase I with repetitions that does not exist in any doc @@ -412,7 +410,7 @@ BOOST_AUTO_TEST_CASE(testNonExistingPhrase) query->setSlop(1000); // would not be found no matter how high the slop is hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); // phrase II with repetitions that does not exist in any doc @@ -424,33 +422,33 @@ BOOST_AUTO_TEST_CASE(testNonExistingPhrase) query->setSlop(1000); // would not be found no matter how high the slop is hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); QueryUtils::check(query, searcher); } /// Working on a 2 fields like this: /// Field(L"field", L"one two three four five") /// Field(L"palindrome", L"one two three two one") -/// Phrase of size 2 occurring twice, once in order and once in reverse, because doc is a palindrome, is counted twice. -/// Also, in this case order in query does not matter. Also, when an exact match is found, both sloppy scorer and -/// exact scorer scores the same. -BOOST_AUTO_TEST_CASE(testPalindrome2) +/// Phrase of size 2 occurring twice, once in order and once in reverse, because doc is a palindrome, is counted twice. +/// Also, in this case order in query does not matter. Also, when an exact match is found, both sloppy scorer and +/// exact scorer scores the same. +TEST_F(PhraseQueryTest, testPalindrome2) { // search on non palindrome, find phrase with no slop, using exact phrase scorer query->setSlop(0); // to use exact phrase scorer query->add(newLucene(L"field", L"two")); query->add(newLucene(L"field", L"three")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); double score0 = hits[0]->score; QueryUtils::check(query, searcher); // search on non palindrome, find phrase with slop 2, though no slop required here. - query->setSlop(2); // to use sloppy scorer + query->setSlop(2); // to use sloppy scorer hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); double score1 = hits[0]->score; - BOOST_CHECK_CLOSE_FRACTION(score0, score1, SCORE_COMP_THRESH); + EXPECT_NEAR(score0, score1, SCORE_COMP_THRESH); QueryUtils::check(query, searcher); // search ordered in palindrome, find it twice @@ -459,7 +457,7 @@ BOOST_AUTO_TEST_CASE(testPalindrome2) query->add(newLucene(L"palindrome", L"two")); query->add(newLucene(L"palindrome", L"three")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); // search reversed in palindrome, find it twice @@ -468,17 +466,17 @@ BOOST_AUTO_TEST_CASE(testPalindrome2) query->add(newLucene(L"palindrome", L"three")); query->add(newLucene(L"palindrome", L"two")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); } /// Working on a 2 fields like this: /// Field(L"field", L"one two three four five") /// Field(L"palindrome", L"one two three two one") -/// Phrase of size 3 occurring twice, once in order and once in reverse, because doc is a palindrome, is counted twice. -/// Also, in this case order in query does not matter. Also, when an exact match is found, both sloppy scorer and exact -/// scorer scores the same. -BOOST_AUTO_TEST_CASE(testPalindrome3) +/// Phrase of size 3 occurring twice, once in order and once in reverse, because doc is a palindrome, is counted twice. +/// Also, in this case order in query does not matter. Also, when an exact match is found, both sloppy scorer and exact +/// scorer scores the same. +TEST_F(PhraseQueryTest, testPalindrome3) { // search on non palindrome, find phrase with no slop, using exact phrase scorer query->setSlop(0); // to use exact phrase scorer @@ -486,16 +484,16 @@ BOOST_AUTO_TEST_CASE(testPalindrome3) query->add(newLucene(L"field", L"two")); query->add(newLucene(L"field", L"three")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); double score0 = hits[0]->score; QueryUtils::check(query, searcher); // search on non palindrome, find phrase with slop 3, though no slop required here. - query->setSlop(4); // to use sloppy scorer + query->setSlop(4); // to use sloppy scorer hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); double score1 = hits[0]->score; - BOOST_CHECK_CLOSE_FRACTION(score0, score1, SCORE_COMP_THRESH); + EXPECT_NEAR(score0, score1, SCORE_COMP_THRESH); QueryUtils::check(query, searcher); // search ordered in palindrome, find it twice @@ -505,7 +503,7 @@ BOOST_AUTO_TEST_CASE(testPalindrome3) query->add(newLucene(L"palindrome", L"two")); query->add(newLucene(L"palindrome", L"three")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); // search reversed in palindrome, find it twice @@ -515,15 +513,13 @@ BOOST_AUTO_TEST_CASE(testPalindrome3) query->add(newLucene(L"palindrome", L"two")); query->add(newLucene(L"palindrome", L"one")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); QueryUtils::check(query, searcher); } -BOOST_AUTO_TEST_CASE(testEmptyPhraseQuery) +TEST_F(PhraseQueryTest, testEmptyPhraseQuery) { BooleanQueryPtr q2 = newLucene(); q2->add(newLucene(), BooleanClause::MUST); - BOOST_CHECK_EQUAL(q2->toString(), L"+\"?\""); + EXPECT_EQ(q2->toString(), L"+\"?\""); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/PositionIncrementTest.cpp b/src/test/search/PositionIncrementTest.cpp index b4e89164..9001897d 100644 --- a/src/test/search/PositionIncrementTest.cpp +++ b/src/test/search/PositionIncrementTest.cpp @@ -39,7 +39,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PositionIncrementTest, LuceneTestFixture) +typedef LuceneTestFixture PositionIncrementTest; namespace TestSetPosition { @@ -51,25 +51,25 @@ namespace TestSetPosition TOKENS = newCollection(L"1", L"2", L"3", L"4", L"5"); INCREMENTS = newCollection(0, 2, 1, 0, 1); i = 0; - + posIncrAtt = addAttribute(); termAtt = addAttribute(); offsetAtt = addAttribute(); } - + virtual ~SetPositionTokenStream() { } - + protected: Collection TOKENS; Collection INCREMENTS; int32_t i; - + PositionIncrementAttributePtr posIncrAtt; TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool incrementToken() { @@ -83,7 +83,7 @@ namespace TestSetPosition return true; } }; - + class SetPositionAnalyzer : public Analyzer { public: @@ -97,7 +97,7 @@ namespace TestSetPosition return newLucene(); } }; - + class StopWhitespaceAnalyzer : public Analyzer { public: @@ -106,11 +106,11 @@ namespace TestSetPosition this->enablePositionIncrements = enablePositionIncrements; this->a = newLucene(); } - + virtual ~StopWhitespaceAnalyzer() { } - + public: bool enablePositionIncrements; WhitespaceAnalyzerPtr a; @@ -124,7 +124,7 @@ namespace TestSetPosition }; } -BOOST_AUTO_TEST_CASE(testSetPosition) +TEST_F(PositionIncrementTest, testSetPosition) { AnalyzerPtr analyzer = newLucene(); DirectoryPtr store = newLucene(); @@ -140,120 +140,120 @@ BOOST_AUTO_TEST_CASE(testSetPosition) TermPositionsPtr pos = searcher->getIndexReader()->termPositions(newLucene(L"field", L"1")); pos->next(); // first token should be at position 0 - BOOST_CHECK_EQUAL(0, pos->nextPosition()); + EXPECT_EQ(0, pos->nextPosition()); pos = searcher->getIndexReader()->termPositions(newLucene(L"field", L"2")); pos->next(); // second token should be at position 2 - BOOST_CHECK_EQUAL(2, pos->nextPosition()); + EXPECT_EQ(2, pos->nextPosition()); PhraseQueryPtr q = newLucene(); q->add(newLucene(L"field", L"1")); q->add(newLucene(L"field", L"2")); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // same as previous, just specify positions explicitely. - q = newLucene(); + q = newLucene(); q->add(newLucene(L"field", L"1"), 0); q->add(newLucene(L"field", L"2"), 1); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // specifying correct positions should find the phrase. q = newLucene(); q->add(newLucene(L"field", L"1"), 0); q->add(newLucene(L"field", L"2"), 2); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); q = newLucene(); q->add(newLucene(L"field", L"2")); q->add(newLucene(L"field", L"3")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); q = newLucene(); q->add(newLucene(L"field", L"3")); q->add(newLucene(L"field", L"4")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); - // phrase query would find it when correct positions are specified. + // phrase query would find it when correct positions are specified. q = newLucene(); q->add(newLucene(L"field", L"3"), 0); q->add(newLucene(L"field", L"4"), 0); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); - // phrase query should fail for non existing searched term - // even if there exist another searched terms in the same searched position. + // phrase query should fail for non existing searched term + // even if there exist another searched terms in the same searched position. q = newLucene(); q->add(newLucene(L"field", L"3"), 0); q->add(newLucene(L"field", L"9"), 0); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // multi-phrase query should succeed for non existing searched term - // because there exist another searched terms in the same searched position. + // because there exist another searched terms in the same searched position. MultiPhraseQueryPtr mq = newLucene(); mq->add(newCollection(newLucene(L"field", L"3"), newLucene(L"field", L"9")), 0); hits = searcher->search(mq, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); q = newLucene(); q->add(newLucene(L"field", L"2")); q->add(newLucene(L"field", L"4")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); q = newLucene(); q->add(newLucene(L"field", L"3")); q->add(newLucene(L"field", L"5")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); q = newLucene(); q->add(newLucene(L"field", L"4")); q->add(newLucene(L"field", L"5")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); q = newLucene(); q->add(newLucene(L"field", L"2")); q->add(newLucene(L"field", L"5")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // should not find "1 2" because there is a gap of 1 in the index QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene(false)); q = boost::dynamic_pointer_cast(qp->parse(L"\"1 2\"")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); - // omitted stop word cannot help because stop filter swallows the increments. + // omitted stop word cannot help because stop filter swallows the increments. q = boost::dynamic_pointer_cast(qp->parse(L"\"1 stop 2\"")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); - // query parser alone won't help, because stop filter swallows the increments. + // query parser alone won't help, because stop filter swallows the increments. qp->setEnablePositionIncrements(true); q = boost::dynamic_pointer_cast(qp->parse(L"\"1 stop 2\"")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); - // stop filter alone won't help, because query parser swallows the increments. + // stop filter alone won't help, because query parser swallows the increments. qp->setEnablePositionIncrements(false); q = boost::dynamic_pointer_cast(qp->parse(L"\"1 stop 2\"")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // when both qp and stopFilter propagate increments, we should find the doc. qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene(true)); qp->setEnablePositionIncrements(true); q = boost::dynamic_pointer_cast(qp->parse(L"\"1 stop 2\"")); hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); } namespace TestPayloadsPos0 @@ -270,11 +270,11 @@ namespace TestPayloadsPos0 this->payloadAttr = input->addAttribute(); this->termAttr = input->addAttribute(); } - + virtual ~TestPayloadFilter() { } - + public: String fieldName; int32_t pos; @@ -283,7 +283,7 @@ namespace TestPayloadsPos0 PositionIncrementAttributePtr posIncrAttr; PayloadAttributePtr payloadAttr; TermAttributePtr termAttr; - + public: virtual bool incrementToken() { @@ -303,7 +303,7 @@ namespace TestPayloadsPos0 return false; } }; - + class TestPayloadAnalyzer : public Analyzer { public: @@ -320,7 +320,7 @@ namespace TestPayloadsPos0 }; } -BOOST_AUTO_TEST_CASE(testPayloadsPos0) +TEST_F(PositionIncrementTest, testPayloadsPos0) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -332,23 +332,23 @@ BOOST_AUTO_TEST_CASE(testPayloadsPos0) TermPositionsPtr tp = r->termPositions(newLucene(L"content", L"a")); int32_t count = 0; - BOOST_CHECK(tp->next()); + EXPECT_TRUE(tp->next()); // "a" occurs 4 times - BOOST_CHECK_EQUAL(4, tp->freq()); + EXPECT_EQ(4, tp->freq()); int32_t expected = 0; - BOOST_CHECK_EQUAL(expected, tp->nextPosition()); - BOOST_CHECK_EQUAL(1, tp->nextPosition()); - BOOST_CHECK_EQUAL(3, tp->nextPosition()); - BOOST_CHECK_EQUAL(6, tp->nextPosition()); + EXPECT_EQ(expected, tp->nextPosition()); + EXPECT_EQ(1, tp->nextPosition()); + EXPECT_EQ(3, tp->nextPosition()); + EXPECT_EQ(6, tp->nextPosition()); // only one doc has "a" - BOOST_CHECK(!tp->next()); + EXPECT_TRUE(!tp->next()); IndexSearcherPtr is = newLucene(r); SpanTermQueryPtr stq1 = newLucene(newLucene(L"content", L"a")); SpanTermQueryPtr stq2 = newLucene(newLucene(L"content", L"k")); - + Collection sqs = newCollection(stq1, stq2); SpanNearQueryPtr snq = newLucene(sqs, 30, false); @@ -363,8 +363,8 @@ BOOST_AUTO_TEST_CASE(testPayloadsPos0) count += payloads.size(); } - BOOST_CHECK_EQUAL(5, count); - BOOST_CHECK(sawZero); + EXPECT_EQ(5, count); + EXPECT_TRUE(sawZero); SpansPtr spans = snq->getSpans(is->getIndexReader()); count = 0; @@ -375,10 +375,10 @@ BOOST_AUTO_TEST_CASE(testPayloadsPos0) if (spans->start() == 0) sawZero = true; } - - BOOST_CHECK_EQUAL(4, count); - BOOST_CHECK(sawZero); - + + EXPECT_EQ(4, count); + EXPECT_TRUE(sawZero); + sawZero = false; PayloadSpanUtilPtr psu = newLucene(is->getIndexReader()); Collection pls = psu->getPayloadsForQuery(snq); @@ -389,13 +389,11 @@ BOOST_AUTO_TEST_CASE(testPayloadsPos0) if (s == L"pos: 0") sawZero = true; } - - BOOST_CHECK_EQUAL(5, count); - BOOST_CHECK(sawZero); - + + EXPECT_EQ(5, count); + EXPECT_TRUE(sawZero); + writer->close(); is->getIndexReader()->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/PositiveScoresOnlyCollectorTest.cpp b/src/test/search/PositiveScoresOnlyCollectorTest.cpp index b630fbf1..dbb08539 100644 --- a/src/test/search/PositiveScoresOnlyCollectorTest.cpp +++ b/src/test/search/PositiveScoresOnlyCollectorTest.cpp @@ -14,7 +14,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PositiveScoresOnlyCollectorTest, LuceneTestFixture) +typedef LuceneTestFixture PositiveScoresOnlyCollectorTest; namespace TestNegativeScores { @@ -26,31 +26,31 @@ namespace TestNegativeScores this->scores = scores; idx = -1; } - + virtual ~SimpleScorer() { } - + public: int32_t idx; Collection scores; - + public: virtual double score() { return idx == scores.size() ? std::numeric_limits::quiet_NaN() : scores[idx]; } - + virtual int32_t docID() { return idx; } - + virtual int32_t nextDoc() { return ++idx != scores.size() ? idx : DocIdSetIterator::NO_MORE_DOCS; } - + virtual int32_t advance(int32_t target) { idx = target; @@ -59,7 +59,7 @@ namespace TestNegativeScores }; } -BOOST_AUTO_TEST_CASE(testNegativeScores) +TEST_F(PositiveScoresOnlyCollectorTest, testNegativeScores) { // The scores must have positive as well as negative values Collection scores = Collection::newInstance(); @@ -76,9 +76,9 @@ BOOST_AUTO_TEST_CASE(testNegativeScores) scores.add(2.2423935); scores.add(-7.285586); scores.add(4.6699767); - - // The Top*Collectors previously filtered out documents with <= scores. This behaviour has changed. - // This test checks that if PositiveOnlyScoresFilter wraps one of these collectors, documents with + + // The Top*Collectors previously filtered out documents with <= scores. This behaviour has changed. + // This test checks that if PositiveOnlyScoresFilter wraps one of these collectors, documents with // <= 0 scores are indeed filtered. int32_t numPositiveScores = 0; @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(testNegativeScores) if (scores[i] > 0) ++numPositiveScores; } - + ScorerPtr s = newLucene(scores); TopDocsCollectorPtr tdc = TopScoreDocCollector::create(scores.size(), true); CollectorPtr c = newLucene(tdc); @@ -97,9 +97,7 @@ BOOST_AUTO_TEST_CASE(testNegativeScores) TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; - BOOST_CHECK_EQUAL(numPositiveScores, td->totalHits); + EXPECT_EQ(numPositiveScores, td->totalHits); for (int32_t i = 0; i < sd.size(); ++i) - BOOST_CHECK(sd[i]->score > 0); + EXPECT_TRUE(sd[i]->score > 0); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/PrefixFilterTest.cpp b/src/test/search/PrefixFilterTest.cpp index 867e4b1e..ffdccbae 100644 --- a/src/test/search/PrefixFilterTest.cpp +++ b/src/test/search/PrefixFilterTest.cpp @@ -20,9 +20,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PrefixFilterTest, LuceneTestFixture) +typedef LuceneTestFixture PrefixFilterTest; -BOOST_AUTO_TEST_CASE(testPrefixFilter) +TEST_F(PrefixFilterTest, testPrefixFilter) { RAMDirectoryPtr directory = newLucene(); @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(testPrefixFilter) doc->add(newLucene(L"category", categories[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } - + writer->close(); // PrefixFilter combined with ConstantScoreQuery @@ -47,55 +47,53 @@ BOOST_AUTO_TEST_CASE(testPrefixFilter) QueryPtr query = newLucene(filter); IndexSearcherPtr searcher = newLucene(directory, true); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, hits.size()); + EXPECT_EQ(4, hits.size()); // test middle of values filter = newLucene(newLucene(L"category", L"/Computers/Mac")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); // test start of values filter = newLucene(newLucene(L"category", L"/Computers/Linux")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); // test end of values filter = newLucene(newLucene(L"category", L"/Computers/Windows")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); // test non-existent filter = newLucene(newLucene(L"category", L"/Computers/ObsoleteOS")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // test non-existent, before values filter = newLucene(newLucene(L"category", L"/Computers/AAA")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // test non-existent, after values filter = newLucene(newLucene(L"category", L"/Computers/ZZZ")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); // test zero length prefix filter = newLucene(newLucene(L"category", L"")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(4, hits.size()); + EXPECT_EQ(4, hits.size()); // test non existent field filter = newLucene(newLucene(L"nonexistentfield", L"/Computers")); query = newLucene(filter); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/PrefixInBooleanQueryTest.cpp b/src/test/search/PrefixInBooleanQueryTest.cpp index a2f09f75..4a52efa1 100644 --- a/src/test/search/PrefixInBooleanQueryTest.cpp +++ b/src/test/search/PrefixInBooleanQueryTest.cpp @@ -20,14 +20,14 @@ using namespace Lucene; -class PrefixInBooleanQueryFixture : public LuceneTestFixture +class PrefixInBooleanQueryTest : public LuceneTestFixture { public: - PrefixInBooleanQueryFixture() + PrefixInBooleanQueryTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - + for (int32_t i = 0; i < 5137; ++i) { DocumentPtr doc = newLucene(); @@ -39,7 +39,7 @@ class PrefixInBooleanQueryFixture : public LuceneTestFixture doc->add(newLucene(FIELD, L"tangfulin", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } - + for (int32_t i = 5138; i < 11377; ++i) { DocumentPtr doc = newLucene(); @@ -51,11 +51,11 @@ class PrefixInBooleanQueryFixture : public LuceneTestFixture doc->add(newLucene(FIELD, L"tangfulin", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } - + writer->close(); } - - virtual ~PrefixInBooleanQueryFixture() + + virtual ~PrefixInBooleanQueryTest() { } @@ -66,40 +66,36 @@ class PrefixInBooleanQueryFixture : public LuceneTestFixture static const String FIELD; }; -const String PrefixInBooleanQueryFixture::FIELD = L"name"; - -BOOST_FIXTURE_TEST_SUITE(PrefixInBooleanQueryTest, PrefixInBooleanQueryFixture) +const String PrefixInBooleanQueryTest::FIELD = L"name"; -BOOST_AUTO_TEST_CASE(testPrefixQuery) +TEST_F(PrefixInBooleanQueryTest, testPrefixQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); QueryPtr query = newLucene(newLucene(FIELD, L"tang")); - BOOST_CHECK_EQUAL(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); + EXPECT_EQ(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); } -BOOST_AUTO_TEST_CASE(testTermQuery) +TEST_F(PrefixInBooleanQueryTest, testTermQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); QueryPtr query = newLucene(newLucene(FIELD, L"tangfulin")); - BOOST_CHECK_EQUAL(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); + EXPECT_EQ(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); } -BOOST_AUTO_TEST_CASE(testTermBooleanQuery) +TEST_F(PrefixInBooleanQueryTest, testTermBooleanQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(FIELD, L"tangfulin")), BooleanClause::SHOULD); query->add(newLucene(newLucene(FIELD, L"notexistnames")), BooleanClause::SHOULD); - BOOST_CHECK_EQUAL(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); + EXPECT_EQ(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); } -BOOST_AUTO_TEST_CASE(testPrefixBooleanQuery) +TEST_F(PrefixInBooleanQueryTest, testPrefixBooleanQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(FIELD, L"tang")), BooleanClause::SHOULD); query->add(newLucene(newLucene(FIELD, L"notexistnames")), BooleanClause::SHOULD); - BOOST_CHECK_EQUAL(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); + EXPECT_EQ(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/PrefixQueryTest.cpp b/src/test/search/PrefixQueryTest.cpp index aa6333eb..e9cdfe91 100644 --- a/src/test/search/PrefixQueryTest.cpp +++ b/src/test/search/PrefixQueryTest.cpp @@ -19,9 +19,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PrefixQueryTest, LuceneTestFixture) +typedef LuceneTestFixture PrefixQueryTest; -BOOST_AUTO_TEST_CASE(testPrefixQuery) +TEST_F(PrefixQueryTest, testPrefixQuery) { RAMDirectoryPtr directory = newLucene(); @@ -37,17 +37,15 @@ BOOST_AUTO_TEST_CASE(testPrefixQuery) doc->add(newLucene(L"category", categories[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } - + writer->close(); - + PrefixQueryPtr query = newLucene(newLucene(L"category", L"/Computers")); IndexSearcherPtr searcher = newLucene(directory, true); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); query = newLucene(newLucene(L"category", L"/Computers/Mac")); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/QueryTermVectorTest.cpp b/src/test/search/QueryTermVectorTest.cpp index 73c5dbbb..476d5719 100644 --- a/src/test/search/QueryTermVectorTest.cpp +++ b/src/test/search/QueryTermVectorTest.cpp @@ -11,41 +11,39 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(QueryTermVectorTest, LuceneTestFixture) +typedef LuceneTestFixture QueryTermVectorTest; static void checkGold(Collection terms, Collection gold, Collection freq, Collection goldFreqs) { for (int32_t i = 0; i < terms.size(); ++i) { - BOOST_CHECK_EQUAL(terms[i], gold[i]); - BOOST_CHECK_EQUAL(freq[i], goldFreqs[i]); + EXPECT_EQ(terms[i], gold[i]); + EXPECT_EQ(freq[i], goldFreqs[i]); } } -BOOST_AUTO_TEST_CASE(testConstructor) +TEST_F(QueryTermVectorTest, testConstructor) { Collection queryTerm = newCollection(L"foo", L"bar", L"foo", L"again", L"foo", L"bar", L"go", L"go", L"go"); - + // Items are sorted lexicographically Collection gold = newCollection(L"again", L"bar", L"foo", L"go"); Collection goldFreqs = newCollection(1, 2, 3, 3); QueryTermVectorPtr result = newLucene(queryTerm); - BOOST_CHECK(result); + EXPECT_TRUE(result); Collection terms = result->getTerms(); - BOOST_CHECK_EQUAL(terms.size(), 4); + EXPECT_EQ(terms.size(), 4); Collection freq = result->getTermFrequencies(); - BOOST_CHECK_EQUAL(freq.size(), 4); + EXPECT_EQ(freq.size(), 4); checkGold(terms, gold, freq, goldFreqs); result = newLucene(Collection()); - BOOST_CHECK_EQUAL(result->getTerms().size(), 0); + EXPECT_EQ(result->getTerms().size(), 0); result = newLucene(L"foo bar foo again foo bar go go go", newLucene()); - BOOST_CHECK(result); + EXPECT_TRUE(result); terms = result->getTerms(); - BOOST_CHECK_EQUAL(terms.size(), 4); + EXPECT_EQ(terms.size(), 4); freq = result->getTermFrequencies(); - BOOST_CHECK_EQUAL(freq.size(), 4); + EXPECT_EQ(freq.size(), 4); checkGold(terms, gold, freq, goldFreqs); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/QueryUtils.cpp b/src/test/search/QueryUtils.cpp index 76afeec7..b7e596eb 100644 --- a/src/test/search/QueryUtils.cpp +++ b/src/test/search/QueryUtils.cpp @@ -28,25 +28,25 @@ namespace Lucene QueryUtils::~QueryUtils() { } - + void QueryUtils::check(QueryPtr q) { checkHashEquals(q); } - + class WhackyQuery : public Query { public: virtual ~WhackyQuery() { } - + public: virtual String toString(const String& field) { return L"My Whacky Query"; } - + virtual bool equals(LuceneObjectPtr other) { if (!MiscUtils::typeOf(other)) @@ -54,7 +54,7 @@ namespace Lucene return Query::equals(other); } }; - + void QueryUtils::checkHashEquals(QueryPtr q) { QueryPtr q2 = boost::dynamic_pointer_cast(q->clone()); @@ -69,33 +69,33 @@ namespace Lucene whacky->setBoost(q->getBoost()); checkUnequal(q, whacky); } - + void QueryUtils::checkEqual(QueryPtr q1, QueryPtr q2) { - BOOST_CHECK(q1->equals(q2)); - BOOST_CHECK_EQUAL(q1->hashCode(), q2->hashCode()); + EXPECT_TRUE(q1->equals(q2)); + EXPECT_EQ(q1->hashCode(), q2->hashCode()); } - + void QueryUtils::checkUnequal(QueryPtr q1, QueryPtr q2) { - BOOST_CHECK(!q1->equals(q2)); - BOOST_CHECK(!q2->equals(q1)); - - // possible this test can fail on a hash collision... if that happens, please change + EXPECT_TRUE(!q1->equals(q2)); + EXPECT_TRUE(!q2->equals(q1)); + + // possible this test can fail on a hash collision... if that happens, please change // test to use a different example. - BOOST_CHECK_NE(q1->hashCode(), q2->hashCode()); + EXPECT_NE(q1->hashCode(), q2->hashCode()); } - + void QueryUtils::checkExplanations(QueryPtr q, SearcherPtr s) { CheckHits::checkExplanations(q, L"", s, true); } - + void QueryUtils::check(QueryPtr q1, SearcherPtr s) { check(q1, s, true); } - + void QueryUtils::check(QueryPtr q1, SearcherPtr s, bool wrap) { check(q1); @@ -125,7 +125,7 @@ namespace Lucene checkEqual(s->rewrite(q1), s->rewrite(q2)); } } - + IndexSearcherPtr QueryUtils::wrapUnderlyingReader(IndexSearcherPtr s, int32_t edge) { IndexReaderPtr r = s->getIndexReader(); @@ -151,7 +151,7 @@ namespace Lucene out->setSimilarity(s->getSimilarity()); return out; } - + MultiSearcherPtr QueryUtils::wrapSearcher(SearcherPtr s, int32_t edge) { // we can't put deleted docs before the nested reader, because it will through off the docIds @@ -174,7 +174,7 @@ namespace Lucene out->setSimilarity(s->getSimilarity()); return out; } - + RAMDirectoryPtr QueryUtils::makeEmptyIndex(int32_t numDeletedDocs) { RAMDirectoryPtr d = newLucene(); @@ -186,17 +186,17 @@ namespace Lucene w->commit(); if (0 < numDeletedDocs) - BOOST_CHECK(w->hasDeletions()); + EXPECT_TRUE(w->hasDeletions()); - BOOST_CHECK_EQUAL(numDeletedDocs, w->maxDoc()); - BOOST_CHECK_EQUAL(0, w->numDocs()); + EXPECT_EQ(numDeletedDocs, w->maxDoc()); + EXPECT_EQ(0, w->numDocs()); w->close(); IndexReaderPtr r = IndexReader::open(d, true); - BOOST_CHECK_EQUAL(numDeletedDocs, r->numDeletedDocs()); + EXPECT_EQ(numDeletedDocs, r->numDeletedDocs()); r->close(); return d; } - + namespace CheckSkipTo { class SkipCollector : public Collector @@ -211,29 +211,29 @@ namespace Lucene this->opidx = opidx; this->lastReader = lastReader; } - + virtual ~SkipCollector() { } - + protected: QueryPtr q; IndexSearcherPtr s; Collection lastDoc; Collection order; Collection opidx; - + ScorerPtr sc; IndexReaderPtr reader; ScorerPtr scorer; Collection lastReader; - + public: virtual void setScorer(ScorerPtr scorer) { this->sc = scorer; } - + virtual void collect(int32_t doc) { double score = sc->score(); @@ -243,14 +243,14 @@ namespace Lucene WeightPtr w = q->weight(s); scorer = w->scorer(reader, true, false); } - + int32_t skip_op = 0; int32_t next_op = 1; double maxDiff = 1e-5; - + int32_t op = order[(opidx[0]++) % order.size()]; - bool more = op == skip_op ? - (scorer->advance(scorer->docID() + 1) != DocIdSetIterator::NO_MORE_DOCS) : + bool more = op == skip_op ? + (scorer->advance(scorer->docID() + 1) != DocIdSetIterator::NO_MORE_DOCS) : (scorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); int32_t scorerDoc = scorer->docID(); double scorerScore = scorer->score(); @@ -264,23 +264,23 @@ namespace Lucene sbord << (order[i] == skip_op ? L" skip()" : L" next()"); StringStream message; message << L"ERROR matching docs:\n\t" - << (doc != scorerDoc ? L"--> " : L"") + << (doc != scorerDoc ? L"--> " : L"") << L"doc=" << doc << L", scorerDoc=" << scorerDoc - << L"\n\t" << (!more ? L"--> " : L"") << L"tscorer.more=" + << L"\n\t" << (!more ? L"--> " : L"") << L"tscorer.more=" << more << L"\n\t" << (scoreDiff > maxDiff ? L"--> " : L"") - << L"scorerScore=" << scorerScore << L" scoreDiff=" + << L"scorerScore=" << scorerScore << L" scoreDiff=" << scoreDiff << L" maxDiff=" << maxDiff << L"\n\t" << (scorerDiff > maxDiff ? L"--> " : L"") << L"scorerScore2=" << scorerScore2 << L" scorerDiff=" << scorerDiff - << L"\n\thitCollector.doc=" << doc << L" score=" + << L"\n\thitCollector.doc=" << doc << L" score=" << score << L"\n\t Scorer=" << scorer << L"\n\t Query=" << q->toString() + L" " << L"\n\t Searcher=" + s->toString() << L"\n\t Order=" << sbord.str() << L"\n\t Op=" << (op == skip_op ? L" skip()" : L" next()"); - BOOST_FAIL(StringUtils::toUTF8(message.str())); + FAIL() << StringUtils::toUTF8(message.str()); } } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS @@ -292,26 +292,26 @@ namespace Lucene if (scorer) { bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK(!more); + EXPECT_TRUE(!more); } } this->reader = reader; this->scorer.reset(); lastDoc[0] = -1; } - + virtual bool acceptsDocsOutOfOrder() { return true; } }; } - + void QueryUtils::checkSkipTo(QueryPtr q, IndexSearcherPtr s) { if (q->weight(s)->scoresDocsOutOfOrder()) return; // in this case order of skipTo() might differ from that of next(). - + int32_t skip_op = 0; int32_t next_op = 1; Collection< Collection > orders = newCollection< Collection >( @@ -323,17 +323,17 @@ namespace Lucene newCollection(next_op, next_op, skip_op, skip_op), newCollection(skip_op, skip_op, skip_op, next_op, next_op) ); - + Collection lastReader = Collection::newInstance(1); - + for (int32_t k = 0; k < orders.size(); ++k) { Collection order = orders[k]; Collection opidx = newCollection(0); Collection lastDoc = newCollection(-1); - + s->search(q, newLucene(q, s, lastDoc, order, opidx, lastReader)); - + if (lastReader[0]) { // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS @@ -343,12 +343,12 @@ namespace Lucene if (scorer) { bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK(!more); + EXPECT_TRUE(!more); } } } } - + namespace CheckFirstSkipTo { class SkipCollector : public Collector @@ -361,26 +361,26 @@ namespace Lucene this->lastDoc = lastDoc; this->lastReader = lastReader; } - + virtual ~SkipCollector() { } - + protected: QueryPtr q; IndexSearcherPtr s; Collection lastDoc; Collection lastReader; - + ScorerPtr scorer; IndexReaderPtr reader; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { double score = scorer->score(); @@ -389,15 +389,15 @@ namespace Lucene { WeightPtr w = q->weight(s); ScorerPtr scorer = w->scorer(reader, true, false); - BOOST_CHECK(scorer->advance(i) != DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_EQUAL(doc, scorer->docID()); + EXPECT_TRUE(scorer->advance(i) != DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(doc, scorer->docID()); double skipToScore = scorer->score(); - BOOST_CHECK_CLOSE_FRACTION(skipToScore, scorer->score(), 1e-5); - BOOST_CHECK_CLOSE_FRACTION(score, skipToScore, 1e-5); + EXPECT_NEAR(skipToScore, scorer->score(), 1e-5); + EXPECT_NEAR(score, skipToScore, 1e-5); } lastDoc[0] = doc; } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS @@ -409,7 +409,7 @@ namespace Lucene if (scorer) { bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK(!more); + EXPECT_TRUE(!more); } } @@ -417,21 +417,21 @@ namespace Lucene this->reader = reader; lastDoc[0] = -1; } - + virtual bool acceptsDocsOutOfOrder() { return false; } }; } - + void QueryUtils::checkFirstSkipTo(QueryPtr q, IndexSearcherPtr s) { Collection lastDoc = newCollection(-1); Collection lastReader = Collection::newInstance(1); - + s->search(q, newLucene(q, s, lastDoc, lastReader)); - + if (lastReader[0]) { // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS @@ -441,7 +441,7 @@ namespace Lucene if (scorer) { bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK(!more); + EXPECT_TRUE(!more); } } } diff --git a/src/test/search/QueryWrapperFilterTest.cpp b/src/test/search/QueryWrapperFilterTest.cpp index 5da4a14f..444dfd9b 100644 --- a/src/test/search/QueryWrapperFilterTest.cpp +++ b/src/test/search/QueryWrapperFilterTest.cpp @@ -24,9 +24,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(QueryWrapperFilterTest, LuceneTestFixture) +typedef LuceneTestFixture QueryWrapperFilterTest; -BOOST_AUTO_TEST_CASE(testBasic) +TEST_F(QueryWrapperFilterTest, testBasic) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -42,9 +42,9 @@ BOOST_AUTO_TEST_CASE(testBasic) IndexSearcherPtr searcher = newLucene(dir, true); TopDocsPtr hits = searcher->search(newLucene(), qwf, 10); - BOOST_CHECK_EQUAL(1, hits->totalHits); + EXPECT_EQ(1, hits->totalHits); hits = searcher->search(newLucene(), newLucene(qwf), 10); - BOOST_CHECK_EQUAL(1, hits->totalHits); + EXPECT_EQ(1, hits->totalHits); // should not throw exception with complex primitive query BooleanQueryPtr booleanQuery = newLucene(); @@ -53,25 +53,23 @@ BOOST_AUTO_TEST_CASE(testBasic) qwf = newLucene(termQuery); hits = searcher->search(newLucene(), qwf, 10); - BOOST_CHECK_EQUAL(1, hits->totalHits); + EXPECT_EQ(1, hits->totalHits); hits = searcher->search(newLucene(), newLucene(qwf), 10); - BOOST_CHECK_EQUAL(1, hits->totalHits); + EXPECT_EQ(1, hits->totalHits); // should not throw exception with non primitive Query (doesn't implement Query#createWeight) qwf = newLucene(newLucene(newLucene(L"field", L"valu"))); hits = searcher->search(newLucene(), qwf, 10); - BOOST_CHECK_EQUAL(1, hits->totalHits); + EXPECT_EQ(1, hits->totalHits); hits = searcher->search(newLucene(), newLucene(qwf), 10); - BOOST_CHECK_EQUAL(1, hits->totalHits); + EXPECT_EQ(1, hits->totalHits); // test a query with no hits termQuery = newLucene(newLucene(L"field", L"not_exist")); qwf = newLucene(termQuery); hits = searcher->search(newLucene(), qwf, 10); - BOOST_CHECK_EQUAL(0, hits->totalHits); + EXPECT_EQ(0, hits->totalHits); hits = searcher->search(newLucene(), newLucene(qwf), 10); - BOOST_CHECK_EQUAL(0, hits->totalHits); + EXPECT_EQ(0, hits->totalHits); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/ScoreCachingWrappingScorerTest.cpp b/src/test/search/ScoreCachingWrappingScorerTest.cpp index 1dbc4b3c..e4e20e0a 100644 --- a/src/test/search/ScoreCachingWrappingScorerTest.cpp +++ b/src/test/search/ScoreCachingWrappingScorerTest.cpp @@ -14,7 +14,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(ScoreCachingWrappingScorerTest, LuceneTestFixture) +typedef LuceneTestFixture ScoreCachingWrappingScorerTest; namespace TestGetScores { @@ -27,44 +27,44 @@ namespace TestGetScores idx = 0; doc = -1; } - + virtual ~SimpleScorer() { } - + public: int32_t idx; int32_t doc; Collection scores; - + public: virtual double score() { - // Advance idx on purpose, so that consecutive calls to score will get different results. - // This is to emulate computation of a score. If ScoreCachingWrappingScorer is used, this + // Advance idx on purpose, so that consecutive calls to score will get different results. + // This is to emulate computation of a score. If ScoreCachingWrappingScorer is used, this // should not be called more than once per document. return idx == scores.size() ? std::numeric_limits::quiet_NaN() : scores[idx++]; } - + virtual int32_t docID() { return doc; } - + virtual int32_t nextDoc() { return ++doc < scores.size() ? doc : DocIdSetIterator::NO_MORE_DOCS; } - + virtual int32_t advance(int32_t target) { doc = target; return doc < scores.size() ? doc : DocIdSetIterator::NO_MORE_DOCS; } }; - + DECLARE_SHARED_PTR(ScoreCachingCollector) - + class ScoreCachingCollector : public Collector { public: @@ -73,39 +73,39 @@ namespace TestGetScores idx = 0; mscores = Collection::newInstance(numToCollect); } - + virtual ~ScoreCachingCollector() { } - + public: int32_t idx; ScorerPtr scorer; Collection mscores; - + public: virtual void collect(int32_t doc) { // just a sanity check to avoid IOOB. if (idx == mscores.size()) - return; - + return; + // just call score() a couple of times and record the score. mscores[idx] = scorer->score(); mscores[idx] = scorer->score(); mscores[idx] = scorer->score(); ++idx; } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { } - + virtual void setScorer(ScorerPtr scorer) { this->scorer = newLucene(scorer); } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -113,7 +113,7 @@ namespace TestGetScores }; } -BOOST_AUTO_TEST_CASE(testGetScores) +TEST_F(ScoreCachingWrappingScorerTest, testGetScores) { Collection scores = Collection::newInstance(); scores.add(0.7767749); @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(testGetScores) scores.add(2.2423935); scores.add(7.285586); scores.add(4.6699767); - + ScorerPtr s = newLucene(scores); TestGetScores::ScoreCachingCollectorPtr scc = newLucene(scores.size()); scc->setScorer(s); @@ -138,9 +138,7 @@ BOOST_AUTO_TEST_CASE(testGetScores) int32_t doc; while ((doc = s->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) scc->collect(doc); - + for (int32_t i = 0; i < scores.size(); ++i) - BOOST_CHECK_EQUAL(scores[i], scc->mscores[i]); + EXPECT_EQ(scores[i], scc->mscores[i]); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/ScorerPerfTest.cpp b/src/test/search/ScorerPerfTest.cpp index fd593078..05a6bd52 100644 --- a/src/test/search/ScorerPerfTest.cpp +++ b/src/test/search/ScorerPerfTest.cpp @@ -33,7 +33,7 @@ class CountingHitCollector : public Collector sum = 0; docBase = 0; } - + virtual ~CountingHitCollector() { } @@ -47,28 +47,28 @@ class CountingHitCollector : public Collector virtual void setScorer(ScorerPtr scorer) { } - + virtual void collect(int32_t doc) { ++count; sum += docBase + doc; // use it to avoid any possibility of being optimized away } - + int32_t getCount() { return count; } - + int32_t getSum() { return sum; } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { this->docBase = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -83,7 +83,7 @@ class MatchingHitCollector : public CountingHitCollector this->answer = answer; this->pos = -1; } - + virtual ~MatchingHitCollector() { } @@ -109,14 +109,14 @@ class AddClauseFilter : public Filter { this->rnd = rnd; } - + virtual ~AddClauseFilter() { } protected: BitSetPtr rnd; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) { @@ -124,16 +124,16 @@ class AddClauseFilter : public Filter } }; -class ScorerPerfFixture : public LuceneTestFixture +class ScorerPerfTest : public LuceneTestFixture { public: - ScorerPerfFixture() + ScorerPerfTest() { r = newLucene(); createDummySearcher(); } - - virtual ~ScorerPerfFixture() + + virtual ~ScorerPerfTest() { s->close(); } @@ -154,7 +154,7 @@ class ScorerPerfFixture : public LuceneTestFixture iw->close(); s = newLucene(rd, true); } - + BitSetPtr randBitSet(int32_t sz, int32_t numBitsToSet) { BitSetPtr set = newLucene(sz); @@ -162,7 +162,7 @@ class ScorerPerfFixture : public LuceneTestFixture set->set(r->nextInt(sz)); return set; } - + Collection randBitSets(int32_t numSets, int32_t setSize) { Collection sets = Collection::newInstance(numSets); @@ -170,7 +170,7 @@ class ScorerPerfFixture : public LuceneTestFixture sets[i] = randBitSet(setSize, r->nextInt(setSize)); return sets; } - + void doConjunctions(int32_t iter, int32_t maxClauses) { for (int32_t i = 0; i < iter; ++i) @@ -180,14 +180,14 @@ class ScorerPerfFixture : public LuceneTestFixture BitSetPtr result; for (int32_t j = 0; j < numClauses; ++j) result = addClause(bq, result); - + CountingHitCollectorPtr hc = newLucene(result); s->search(bq, hc); - - BOOST_CHECK_EQUAL(result->cardinality(), hc->getCount()); + + EXPECT_EQ(result->cardinality(), hc->getCount()); } } - + void doNestedConjunctions(int32_t iter, int32_t maxOuterClauses, int32_t maxClauses) { for (int32_t i = 0; i < iter; ++i) @@ -195,7 +195,7 @@ class ScorerPerfFixture : public LuceneTestFixture int32_t oClauses = r->nextInt(maxOuterClauses - 1) + 2; BooleanQueryPtr oq = newLucene(); BitSetPtr result; - + for (int32_t o = 0; o < oClauses; ++o) { int32_t numClauses = r->nextInt(maxClauses - 1) + 2; // min 2 clauses @@ -204,14 +204,14 @@ class ScorerPerfFixture : public LuceneTestFixture result = addClause(bq, result); oq->add(bq, BooleanClause::MUST); } - + CountingHitCollectorPtr hc = newLucene(result); s->search(oq, hc); - - BOOST_CHECK_EQUAL(result->cardinality(), hc->getCount()); + + EXPECT_EQ(result->cardinality(), hc->getCount()); } } - + BitSetPtr addClause(BooleanQueryPtr bq, BitSetPtr result) { BitSetPtr rnd = sets[r->nextInt(sets.size())]; @@ -225,14 +225,10 @@ class ScorerPerfFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(ScorerPerfTest, ScorerPerfFixture) - -BOOST_AUTO_TEST_CASE(testConjunctions) +TEST_F(ScorerPerfTest, testConjunctions) { // test many small sets... the bugs will be found on boundary conditions sets = randBitSets(1000, 10); doConjunctions(10000, 5); doNestedConjunctions(10000, 3, 3); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/SearchForDuplicatesTest.cpp b/src/test/search/SearchForDuplicatesTest.cpp index 02ec271f..db12d3d4 100644 --- a/src/test/search/SearchForDuplicatesTest.cpp +++ b/src/test/search/SearchForDuplicatesTest.cpp @@ -19,7 +19,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SearchForDuplicatesTest, LuceneTestFixture) +typedef LuceneTestFixture SearchForDuplicatesTest; static const String PRIORITY_FIELD = L"priority"; static const String ID_FIELD = L"id"; @@ -42,13 +42,13 @@ static void printHits(StringStream& out, Collection hits, SearcherP static void checkHits(Collection hits, int32_t expectedCount, SearcherPtr searcher) { - BOOST_CHECK_EQUAL(expectedCount, hits.size()); + EXPECT_EQ(expectedCount, hits.size()); for (int32_t i = 0; i < hits.size(); ++i) { if (i < 10 || (i > 94 && i < 105)) { DocumentPtr doc = searcher->doc(hits[i]->doc); - BOOST_CHECK_EQUAL(StringUtils::toString(i), doc->get(ID_FIELD)); + EXPECT_EQ(StringUtils::toString(i), doc->get(ID_FIELD)); } } } @@ -60,7 +60,7 @@ static void doTest(StringStream& out, bool useCompoundFile) IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(useCompoundFile); - + int32_t MAX_DOCS = 225; for (int32_t j = 0; j < MAX_DOCS; ++j) @@ -88,7 +88,7 @@ static void doTest(StringStream& out, bool useCompoundFile) // try a new search with OR searcher = newLucene(directory, true); - + parser = newLucene(LuceneVersion::LUCENE_CURRENT, PRIORITY_FIELD, analyzer); query = parser->parse(HIGH_PRIORITY + L" OR " + MED_PRIORITY); @@ -101,15 +101,13 @@ static void doTest(StringStream& out, bool useCompoundFile) searcher->close(); } -BOOST_AUTO_TEST_CASE(testRun) +TEST_F(SearchForDuplicatesTest, testRun) { StringStream multiFileOutput; doTest(multiFileOutput, false); - + StringStream singleFileOutput; doTest(singleFileOutput, true); - - BOOST_CHECK_EQUAL(multiFileOutput.str(), singleFileOutput.str()); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(multiFileOutput.str(), singleFileOutput.str()); +} diff --git a/src/test/search/SearchTest.cpp b/src/test/search/SearchTest.cpp index 5daeee1d..647e997e 100644 --- a/src/test/search/SearchTest.cpp +++ b/src/test/search/SearchTest.cpp @@ -19,7 +19,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SearchTest, LuceneTestFixture) +typedef LuceneTestFixture SearchTest; static void doTestSearch(StringStream& out, bool useCompoundFile) { @@ -45,9 +45,9 @@ static void doTestSearch(StringStream& out, bool useCompoundFile) writer->addDocument(doc); } writer->close(); - + SearcherPtr searcher = newLucene(directory, true); - + Collection queries = newCollection( L"a b", L"\"a b\"", @@ -63,9 +63,9 @@ static void doTestSearch(StringStream& out, bool useCompoundFile) { QueryPtr query = parser->parse(queries[j]); out << L"Query: " << query->toString(L"contents") << L"\n"; - + Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - + out << hits.size() << L" total results\n"; for (int32_t i = 0; i < hits.size() && i < 10; ++i) { @@ -76,15 +76,13 @@ static void doTestSearch(StringStream& out, bool useCompoundFile) searcher->close(); } -BOOST_AUTO_TEST_CASE(testSearch) +TEST_F(SearchTest, testSearch) { StringStream multiFileOutput; doTestSearch(multiFileOutput, false); - + StringStream singleFileOutput; doTestSearch(singleFileOutput, true); - - BOOST_CHECK_EQUAL(multiFileOutput.str(), singleFileOutput.str()); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(multiFileOutput.str(), singleFileOutput.str()); +} diff --git a/src/test/search/SetNormTest.cpp b/src/test/search/SetNormTest.cpp index 1ae2f5df..c75db5a9 100644 --- a/src/test/search/SetNormTest.cpp +++ b/src/test/search/SetNormTest.cpp @@ -20,7 +20,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SetNormTest, LuceneTestFixture) +typedef LuceneTestFixture SetNormTest; namespace TestSetNorm { @@ -32,32 +32,32 @@ namespace TestSetNorm this->scores = scores; this->base = 0; } - + virtual ~SetNormCollector() { } - + protected: int32_t base; ScorerPtr scorer; Collection scores; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { scores[doc + base] = scorer->score(); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -65,7 +65,7 @@ namespace TestSetNorm }; } -BOOST_AUTO_TEST_CASE(testSetNorm) +TEST_F(SetNormTest, testSetNorm) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -90,16 +90,14 @@ BOOST_AUTO_TEST_CASE(testSetNorm) // check that searches are ordered by this boost Collection scores = Collection::newInstance(4); - + IndexSearcherPtr searcher = newLucene(store, true); searcher->search(newLucene(newLucene(L"field", L"word")), newLucene(scores)); - + double lastScore = 0.0; for (int32_t i = 0; i < 4; ++i) { - BOOST_CHECK(scores[i] > lastScore); + EXPECT_TRUE(scores[i] > lastScore); lastScore = scores[i]; } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/SimilarityTest.cpp b/src/test/search/SimilarityTest.cpp index be86e603..02f2e8ed 100644 --- a/src/test/search/SimilarityTest.cpp +++ b/src/test/search/SimilarityTest.cpp @@ -23,7 +23,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SimilarityTest, LuceneTestFixture) +typedef LuceneTestFixture SimilarityTest; namespace TestSimilarity { @@ -33,94 +33,94 @@ namespace TestSimilarity virtual ~SimpleIDFExplanation() { } - + public: virtual double getIdf() { return 1.0; } - + virtual String explain() { return L"Inexplicable"; } }; - + class SimpleSimilarity : public Similarity { public: virtual ~SimpleSimilarity() { } - + public: virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - + virtual double tf(double freq) { return freq; } - + virtual double sloppyFreq(int32_t distance) { return 2.0; } - + virtual double idf(int32_t docFreq, int32_t numDocs) { return 1.0; } - + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - + virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher) { return newLucene(); } }; - + class TermQueryCollector : public Collector { public: virtual ~TermQueryCollector() { } - + protected: ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL(1.0, scorer->score()); + EXPECT_EQ(1.0, scorer->score()); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { } - + virtual bool acceptsDocsOutOfOrder() { return true; } }; - + class BooleanQueryCollector : public Collector { public: @@ -128,37 +128,37 @@ namespace TestSimilarity { this->base = 0; } - + virtual ~BooleanQueryCollector() { } - + protected: int32_t base; ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL((double)doc + (double)base + 1.0, scorer->score()); + EXPECT_EQ((double)doc + (double)base + 1.0, scorer->score()); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; } }; - + class PhraseQueryCollector : public Collector { public: @@ -166,30 +166,30 @@ namespace TestSimilarity { this->expectedScore = expectedScore; } - + virtual ~PhraseQueryCollector() { } - + protected: double expectedScore; ScorerPtr scorer; - + public: virtual void setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + virtual void collect(int32_t doc) { - BOOST_CHECK_EQUAL(expectedScore, scorer->score()); + EXPECT_EQ(expectedScore, scorer->score()); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -197,7 +197,7 @@ namespace TestSimilarity }; } -BOOST_AUTO_TEST_CASE(testSimilarity) +TEST_F(SimilarityTest, testSimilarity) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -220,24 +220,22 @@ BOOST_AUTO_TEST_CASE(testSimilarity) TermPtr a = newLucene(L"field", L"a"); TermPtr b = newLucene(L"field", L"b"); TermPtr c = newLucene(L"field", L"c"); - + searcher->search(newLucene(b), newLucene()); - + BooleanQueryPtr bq = newLucene(); bq->add(newLucene(a), BooleanClause::SHOULD); bq->add(newLucene(b), BooleanClause::SHOULD); - + searcher->search(bq, newLucene()); PhraseQueryPtr pq = newLucene(); pq->add(a); pq->add(c); - + searcher->search(pq, newLucene(1.0)); - + pq->setSlop(2); - + searcher->search(pq, newLucene(2.0)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp index d21fc7c3..3e7b2b7c 100644 --- a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp @@ -38,11 +38,11 @@ class ItemizedFilter : public FieldCacheTermsFilter ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - + virtual ~ItemizedFilter() { } @@ -58,20 +58,20 @@ class ItemizedFilter : public FieldCacheTermsFilter }; /// TestExplanations subclass focusing on basic query types -class SimpleExplanationsOfNonMatchesFixture : public ExplanationsFixture +class SimpleExplanationsOfNonMatchesTest : public ExplanationsFixture { public: - SimpleExplanationsOfNonMatchesFixture() + SimpleExplanationsOfNonMatchesTest() { } - - virtual ~SimpleExplanationsOfNonMatchesFixture() + + virtual ~SimpleExplanationsOfNonMatchesTest() { } public: using ExplanationsFixture::qtest; - + /// ignore matches and focus on non-matches virtual void qtest(QueryPtr q, Collection expDocNrs) { @@ -79,112 +79,110 @@ class SimpleExplanationsOfNonMatchesFixture : public ExplanationsFixture } }; -BOOST_FIXTURE_TEST_SUITE(SimpleExplanationsOfNonMatchesTest, SimpleExplanationsOfNonMatchesFixture) - -BOOST_AUTO_TEST_CASE(testT1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testT1) { qtest(L"w1", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testT2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testT2) { qtest(L"w1^1000", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMA1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMA1) { qtest(newLucene(), newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMA2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMA2) { QueryPtr q = newLucene(); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testP1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testP1) { qtest(L"\"w1 w2\"", newCollection(0)); } -BOOST_AUTO_TEST_CASE(testP2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testP2) { qtest(L"\"w1 w3\"", newCollection(1, 3)); } -BOOST_AUTO_TEST_CASE(testP3) +TEST_F(SimpleExplanationsOfNonMatchesTest, testP3) { qtest(L"\"w1 w2\"~1", newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testP4) +TEST_F(SimpleExplanationsOfNonMatchesTest, testP4) { qtest(L"\"w2 w3\"~1", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testP5) +TEST_F(SimpleExplanationsOfNonMatchesTest, testP5) { qtest(L"\"w3 w2\"~1", newCollection(1, 3)); } -BOOST_AUTO_TEST_CASE(testP6) +TEST_F(SimpleExplanationsOfNonMatchesTest, testP6) { qtest(L"\"w3 w2\"~2", newCollection(0, 1, 3)); } -BOOST_AUTO_TEST_CASE(testP7) +TEST_F(SimpleExplanationsOfNonMatchesTest, testP7) { qtest(L"\"w3 w2\"~3", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ1) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 1, 2, 3))), newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ2) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 2, 3))), newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ3) +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ3) { qtest(newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))), newCollection(3)); } -BOOST_AUTO_TEST_CASE(testFQ4) +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ4) { qtest(newLucene(qp->parse(L"xx^1000"), newLucene(newCollection(1, 3))), newCollection(3)); } -BOOST_AUTO_TEST_CASE(testFQ6) +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ6) { QueryPtr q = newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))); q->setBoost(1000); qtest(q, newCollection(3)); } -BOOST_AUTO_TEST_CASE(testCSQ1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ1) { QueryPtr q = newLucene(newLucene(newCollection(0, 1, 2, 3))); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testCSQ2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ2) { QueryPtr q = newLucene(newLucene(newCollection(1, 3))); qtest(q, newCollection(1, 3)); } -BOOST_AUTO_TEST_CASE(testCSQ3) +TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ3) { QueryPtr q = newLucene(newLucene(newCollection(0, 2))); q->setBoost(1000); qtest(q, newCollection(0, 2)); } -BOOST_AUTO_TEST_CASE(testDMQ1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ1) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(qp->parse(L"w1")); @@ -192,7 +190,7 @@ BOOST_AUTO_TEST_CASE(testDMQ1) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ2) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"w1")); @@ -200,7 +198,7 @@ BOOST_AUTO_TEST_CASE(testDMQ2) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ3) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ3) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); @@ -208,7 +206,7 @@ BOOST_AUTO_TEST_CASE(testDMQ3) qtest(q, newCollection(0)); } -BOOST_AUTO_TEST_CASE(testDMQ4) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ4) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); @@ -216,7 +214,7 @@ BOOST_AUTO_TEST_CASE(testDMQ4) qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ5) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ5) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy -QQ")); @@ -224,7 +222,7 @@ BOOST_AUTO_TEST_CASE(testDMQ5) qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ6) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ6) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); @@ -232,7 +230,7 @@ BOOST_AUTO_TEST_CASE(testDMQ6) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ7) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ7) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); @@ -240,7 +238,7 @@ BOOST_AUTO_TEST_CASE(testDMQ7) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ8) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ8) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); @@ -248,7 +246,7 @@ BOOST_AUTO_TEST_CASE(testDMQ8) qtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ9) +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ9) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); @@ -256,7 +254,7 @@ BOOST_AUTO_TEST_CASE(testDMQ9) qtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ1) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -264,7 +262,7 @@ BOOST_AUTO_TEST_CASE(testMPQ1) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ2) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -272,7 +270,7 @@ BOOST_AUTO_TEST_CASE(testMPQ2) qtest(q, newCollection(0, 1, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ3) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ3) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"xx"))); @@ -280,7 +278,7 @@ BOOST_AUTO_TEST_CASE(testMPQ3) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ4) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ4) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -288,7 +286,7 @@ BOOST_AUTO_TEST_CASE(testMPQ4) qtest(q, newCollection(0)); } -BOOST_AUTO_TEST_CASE(testMPQ5) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ5) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -297,7 +295,7 @@ BOOST_AUTO_TEST_CASE(testMPQ5) qtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testMPQ6) +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ6) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"w3"))); @@ -306,62 +304,62 @@ BOOST_AUTO_TEST_CASE(testMPQ6) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ1) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ1) { qtest(L"+w1 +w2", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ2) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ2) { qtest(L"+yy +w3", newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ3) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ3) { qtest(L"yy +w3", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ4) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ4) { qtest(L"w1 (-xx w2)", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ5) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ5) { qtest(L"w1 (+qq w2)", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ6) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ6) { qtest(L"w1 -(-qq w5)", newCollection(1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ7) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ7) { qtest(L"+w1 +(qq (xx -w2) (+w3 +w4))", newCollection(0)); } -BOOST_AUTO_TEST_CASE(testBQ8) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ8) { qtest(L"+w1 (qq (xx -w2) (+w3 +w4))", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ9) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ9) { qtest(L"+w1 (qq (-xx w2) -(+w3 +w4))", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ10) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ10) { qtest(L"+w1 +(qq (-xx w2) -(+w3 +w4))", newCollection(1)); } -BOOST_AUTO_TEST_CASE(testBQ11) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ11) { qtest(L"w1 w2^1000.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ14) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ14) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); @@ -369,7 +367,7 @@ BOOST_AUTO_TEST_CASE(testBQ14) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ15) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ15) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::MUST_NOT); @@ -377,7 +375,7 @@ BOOST_AUTO_TEST_CASE(testBQ15) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ16) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ16) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); @@ -385,7 +383,7 @@ BOOST_AUTO_TEST_CASE(testBQ16) qtest(q, newCollection(0, 1)); } -BOOST_AUTO_TEST_CASE(testBQ17) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ17) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"w2"), BooleanClause::SHOULD); @@ -393,12 +391,12 @@ BOOST_AUTO_TEST_CASE(testBQ17) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ19) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ19) { qtest(L"-yy w3", newCollection(0, 1)); } -BOOST_AUTO_TEST_CASE(testBQ20) +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ20) { BooleanQueryPtr q = newLucene(); q->setMinimumNumberShouldMatch(2); @@ -410,7 +408,7 @@ BOOST_AUTO_TEST_CASE(testBQ20) qtest(q, newCollection(0, 3)); } -BOOST_AUTO_TEST_CASE(testTermQueryMultiSearcherExplain) +TEST_F(SimpleExplanationsOfNonMatchesTest, testTermQueryMultiSearcherExplain) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); @@ -444,33 +442,31 @@ BOOST_AUTO_TEST_CASE(testTermQueryMultiSearcherExplain) SearcherPtr mSearcher = newLucene(searchers); Collection hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); ExplanationPtr explain = mSearcher->explain(query, hits[0]->doc); String exp = explain->toString(); - BOOST_CHECK(exp.find(L"maxDocs=3") != String::npos); - BOOST_CHECK(exp.find(L"docFreq=3") != String::npos); + EXPECT_TRUE(exp.find(L"maxDocs=3") != String::npos); + EXPECT_TRUE(exp.find(L"docFreq=3") != String::npos); query = parser->parse(L"handle:\"1 2\""); hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); explain = mSearcher->explain(query, hits[0]->doc); exp = explain->toString(); - BOOST_CHECK(exp.find(L"1=3") != String::npos); - BOOST_CHECK(exp.find(L"2=3") != String::npos); + EXPECT_TRUE(exp.find(L"1=3") != String::npos); + EXPECT_TRUE(exp.find(L"2=3") != String::npos); query = newLucene(newCollection(newLucene(newLucene(L"handle", L"1")), newLucene(newLucene(L"handle", L"2"))), 0, true); hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); explain = mSearcher->explain(query, hits[0]->doc); exp = explain->toString(); - BOOST_CHECK(exp.find(L"1=3") != String::npos); - BOOST_CHECK(exp.find(L"2=3") != String::npos); + EXPECT_TRUE(exp.find(L"1=3") != String::npos); + EXPECT_TRUE(exp.find(L"2=3") != String::npos); mSearcher->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/SimpleExplanationsTest.cpp b/src/test/search/SimpleExplanationsTest.cpp index cfafd83d..fe6c9d2f 100644 --- a/src/test/search/SimpleExplanationsTest.cpp +++ b/src/test/search/SimpleExplanationsTest.cpp @@ -37,11 +37,11 @@ class ItemizedFilter : public FieldCacheTermsFilter ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - + virtual ~ItemizedFilter() { } @@ -57,124 +57,122 @@ class ItemizedFilter : public FieldCacheTermsFilter }; /// TestExplanations subclass focusing on basic query types -class SimpleExplanationsFixture : public ExplanationsFixture +class SimpleExplanationsTest : public ExplanationsFixture { public: - SimpleExplanationsFixture() + SimpleExplanationsTest() { } - - virtual ~SimpleExplanationsFixture() + + virtual ~SimpleExplanationsTest() { } }; -BOOST_FIXTURE_TEST_SUITE(SimpleExplanationsTest, SimpleExplanationsFixture) - -BOOST_AUTO_TEST_CASE(testT1) +TEST_F(SimpleExplanationsTest, testT1) { qtest(L"w1", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testT2) +TEST_F(SimpleExplanationsTest, testT2) { qtest(L"w1^1000", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMA1) +TEST_F(SimpleExplanationsTest, testMA1) { qtest(newLucene(), newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMA2) +TEST_F(SimpleExplanationsTest, testMA2) { QueryPtr q = newLucene(); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testP1) +TEST_F(SimpleExplanationsTest, testP1) { qtest(L"\"w1 w2\"", newCollection(0)); } -BOOST_AUTO_TEST_CASE(testP2) +TEST_F(SimpleExplanationsTest, testP2) { qtest(L"\"w1 w3\"", newCollection(1, 3)); } -BOOST_AUTO_TEST_CASE(testP3) +TEST_F(SimpleExplanationsTest, testP3) { qtest(L"\"w1 w2\"~1", newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testP4) +TEST_F(SimpleExplanationsTest, testP4) { qtest(L"\"w2 w3\"~1", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testP5) +TEST_F(SimpleExplanationsTest, testP5) { qtest(L"\"w3 w2\"~1", newCollection(1, 3)); } -BOOST_AUTO_TEST_CASE(testP6) +TEST_F(SimpleExplanationsTest, testP6) { qtest(L"\"w3 w2\"~2", newCollection(0, 1, 3)); } -BOOST_AUTO_TEST_CASE(testP7) +TEST_F(SimpleExplanationsTest, testP7) { qtest(L"\"w3 w2\"~3", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ1) +TEST_F(SimpleExplanationsTest, testFQ1) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 1, 2, 3))), newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ2) +TEST_F(SimpleExplanationsTest, testFQ2) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 2, 3))), newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testFQ3) +TEST_F(SimpleExplanationsTest, testFQ3) { qtest(newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))), newCollection(3)); } -BOOST_AUTO_TEST_CASE(testFQ4) +TEST_F(SimpleExplanationsTest, testFQ4) { qtest(newLucene(qp->parse(L"xx^1000"), newLucene(newCollection(1, 3))), newCollection(3)); } -BOOST_AUTO_TEST_CASE(testFQ6) +TEST_F(SimpleExplanationsTest, testFQ6) { QueryPtr q = newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))); q->setBoost(1000); qtest(q, newCollection(3)); } -BOOST_AUTO_TEST_CASE(testCSQ1) +TEST_F(SimpleExplanationsTest, testCSQ1) { QueryPtr q = newLucene(newLucene(newCollection(0, 1, 2, 3))); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testCSQ2) +TEST_F(SimpleExplanationsTest, testCSQ2) { QueryPtr q = newLucene(newLucene(newCollection(1, 3))); qtest(q, newCollection(1, 3)); } -BOOST_AUTO_TEST_CASE(testCSQ3) +TEST_F(SimpleExplanationsTest, testCSQ3) { QueryPtr q = newLucene(newLucene(newCollection(0, 2))); q->setBoost(1000); qtest(q, newCollection(0, 2)); } -BOOST_AUTO_TEST_CASE(testDMQ1) +TEST_F(SimpleExplanationsTest, testDMQ1) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(qp->parse(L"w1")); @@ -182,7 +180,7 @@ BOOST_AUTO_TEST_CASE(testDMQ1) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ2) +TEST_F(SimpleExplanationsTest, testDMQ2) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"w1")); @@ -190,7 +188,7 @@ BOOST_AUTO_TEST_CASE(testDMQ2) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ3) +TEST_F(SimpleExplanationsTest, testDMQ3) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); @@ -198,7 +196,7 @@ BOOST_AUTO_TEST_CASE(testDMQ3) qtest(q, newCollection(0)); } -BOOST_AUTO_TEST_CASE(testDMQ4) +TEST_F(SimpleExplanationsTest, testDMQ4) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); @@ -206,7 +204,7 @@ BOOST_AUTO_TEST_CASE(testDMQ4) qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ5) +TEST_F(SimpleExplanationsTest, testDMQ5) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy -QQ")); @@ -214,7 +212,7 @@ BOOST_AUTO_TEST_CASE(testDMQ5) qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ6) +TEST_F(SimpleExplanationsTest, testDMQ6) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); @@ -222,7 +220,7 @@ BOOST_AUTO_TEST_CASE(testDMQ6) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ7) +TEST_F(SimpleExplanationsTest, testDMQ7) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); @@ -230,7 +228,7 @@ BOOST_AUTO_TEST_CASE(testDMQ7) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ8) +TEST_F(SimpleExplanationsTest, testDMQ8) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); @@ -238,7 +236,7 @@ BOOST_AUTO_TEST_CASE(testDMQ8) qtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testDMQ9) +TEST_F(SimpleExplanationsTest, testDMQ9) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); @@ -246,7 +244,7 @@ BOOST_AUTO_TEST_CASE(testDMQ9) qtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ1) +TEST_F(SimpleExplanationsTest, testMPQ1) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -254,7 +252,7 @@ BOOST_AUTO_TEST_CASE(testMPQ1) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ2) +TEST_F(SimpleExplanationsTest, testMPQ2) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -262,7 +260,7 @@ BOOST_AUTO_TEST_CASE(testMPQ2) qtest(q, newCollection(0, 1, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ3) +TEST_F(SimpleExplanationsTest, testMPQ3) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"xx"))); @@ -270,7 +268,7 @@ BOOST_AUTO_TEST_CASE(testMPQ3) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testMPQ4) +TEST_F(SimpleExplanationsTest, testMPQ4) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -278,7 +276,7 @@ BOOST_AUTO_TEST_CASE(testMPQ4) qtest(q, newCollection(0)); } -BOOST_AUTO_TEST_CASE(testMPQ5) +TEST_F(SimpleExplanationsTest, testMPQ5) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); @@ -287,7 +285,7 @@ BOOST_AUTO_TEST_CASE(testMPQ5) qtest(q, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testMPQ6) +TEST_F(SimpleExplanationsTest, testMPQ6) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"w3"))); @@ -296,62 +294,62 @@ BOOST_AUTO_TEST_CASE(testMPQ6) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ1) +TEST_F(SimpleExplanationsTest, testBQ1) { qtest(L"+w1 +w2", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ2) +TEST_F(SimpleExplanationsTest, testBQ2) { qtest(L"+yy +w3", newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ3) +TEST_F(SimpleExplanationsTest, testBQ3) { qtest(L"yy +w3", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ4) +TEST_F(SimpleExplanationsTest, testBQ4) { qtest(L"w1 (-xx w2)", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ5) +TEST_F(SimpleExplanationsTest, testBQ5) { qtest(L"w1 (+qq w2)", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ6) +TEST_F(SimpleExplanationsTest, testBQ6) { qtest(L"w1 -(-qq w5)", newCollection(1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ7) +TEST_F(SimpleExplanationsTest, testBQ7) { qtest(L"+w1 +(qq (xx -w2) (+w3 +w4))", newCollection(0)); } -BOOST_AUTO_TEST_CASE(testBQ8) +TEST_F(SimpleExplanationsTest, testBQ8) { qtest(L"+w1 (qq (xx -w2) (+w3 +w4))", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ9) +TEST_F(SimpleExplanationsTest, testBQ9) { qtest(L"+w1 (qq (-xx w2) -(+w3 +w4))", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ10) +TEST_F(SimpleExplanationsTest, testBQ10) { qtest(L"+w1 +(qq (-xx w2) -(+w3 +w4))", newCollection(1)); } -BOOST_AUTO_TEST_CASE(testBQ11) +TEST_F(SimpleExplanationsTest, testBQ11) { qtest(L"w1 w2^1000.0", newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ14) +TEST_F(SimpleExplanationsTest, testBQ14) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); @@ -359,7 +357,7 @@ BOOST_AUTO_TEST_CASE(testBQ14) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ15) +TEST_F(SimpleExplanationsTest, testBQ15) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::MUST_NOT); @@ -367,7 +365,7 @@ BOOST_AUTO_TEST_CASE(testBQ15) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ16) +TEST_F(SimpleExplanationsTest, testBQ16) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); @@ -375,7 +373,7 @@ BOOST_AUTO_TEST_CASE(testBQ16) qtest(q, newCollection(0, 1)); } -BOOST_AUTO_TEST_CASE(testBQ17) +TEST_F(SimpleExplanationsTest, testBQ17) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"w2"), BooleanClause::SHOULD); @@ -383,12 +381,12 @@ BOOST_AUTO_TEST_CASE(testBQ17) qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testBQ19) +TEST_F(SimpleExplanationsTest, testBQ19) { qtest(L"-yy w3", newCollection(0, 1)); } -BOOST_AUTO_TEST_CASE(testBQ20) +TEST_F(SimpleExplanationsTest, testBQ20) { BooleanQueryPtr q = newLucene(); q->setMinimumNumberShouldMatch(2); @@ -400,7 +398,7 @@ BOOST_AUTO_TEST_CASE(testBQ20) qtest(q, newCollection(0, 3)); } -BOOST_AUTO_TEST_CASE(testTermQueryMultiSearcherExplain) +TEST_F(SimpleExplanationsTest, testTermQueryMultiSearcherExplain) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); @@ -434,33 +432,31 @@ BOOST_AUTO_TEST_CASE(testTermQueryMultiSearcherExplain) SearcherPtr mSearcher = newLucene(searchers); Collection hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); ExplanationPtr explain = mSearcher->explain(query, hits[0]->doc); String exp = explain->toString(); - BOOST_CHECK(exp.find(L"maxDocs=3") != String::npos); - BOOST_CHECK(exp.find(L"docFreq=3") != String::npos); + EXPECT_TRUE(exp.find(L"maxDocs=3") != String::npos); + EXPECT_TRUE(exp.find(L"docFreq=3") != String::npos); query = parser->parse(L"handle:\"1 2\""); hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); explain = mSearcher->explain(query, hits[0]->doc); exp = explain->toString(); - BOOST_CHECK(exp.find(L"1=3") != String::npos); - BOOST_CHECK(exp.find(L"2=3") != String::npos); + EXPECT_TRUE(exp.find(L"1=3") != String::npos); + EXPECT_TRUE(exp.find(L"2=3") != String::npos); query = newLucene(newCollection(newLucene(newLucene(L"handle", L"1")), newLucene(newLucene(L"handle", L"2"))), 0, true); hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); explain = mSearcher->explain(query, hits[0]->doc); exp = explain->toString(); - BOOST_CHECK(exp.find(L"1=3") != String::npos); - BOOST_CHECK(exp.find(L"2=3") != String::npos); + EXPECT_TRUE(exp.find(L"1=3") != String::npos); + EXPECT_TRUE(exp.find(L"2=3") != String::npos); mSearcher->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/SloppyPhraseQueryTest.cpp b/src/test/search/SloppyPhraseQueryTest.cpp index 040ded3d..488bf0a5 100644 --- a/src/test/search/SloppyPhraseQueryTest.cpp +++ b/src/test/search/SloppyPhraseQueryTest.cpp @@ -18,14 +18,14 @@ using namespace Lucene; -class SloppyPhraseQueryFixture : public LuceneTestFixture +class SloppyPhraseQueryTest : public LuceneTestFixture { public: - SloppyPhraseQueryFixture() + SloppyPhraseQueryTest() { S_1 = L"A A A"; S_2 = L"A 1 2 3 A 4 5 6 A"; - + DOC_1 = makeDocument(L"X " + S_1 + L" Y"); DOC_2 = makeDocument(L"X " + S_2 + L" Y"); DOC_3 = makeDocument(L"X " + S_1 + L" A Y"); @@ -33,13 +33,13 @@ class SloppyPhraseQueryFixture : public LuceneTestFixture DOC_2_B = makeDocument(L"X " + S_2 + L" Y N N N N " + S_2 + L" Z"); DOC_3_B = makeDocument(L"X " + S_1 + L" A Y N N N N " + S_1 + L" A Y"); DOC_4 = makeDocument(L"A A X A X B A X B B A A X B A A"); - + QUERY_1 = makePhraseQuery(S_1); QUERY_2 = makePhraseQuery(S_2); QUERY_4 = makePhraseQuery(L"X A A"); } - - virtual ~SloppyPhraseQueryFixture() + + virtual ~SloppyPhraseQueryTest() { } @@ -54,7 +54,7 @@ class SloppyPhraseQueryFixture : public LuceneTestFixture DocumentPtr DOC_2_B; DocumentPtr DOC_3_B; DocumentPtr DOC_4; - + PhraseQueryPtr QUERY_1; PhraseQueryPtr QUERY_2; PhraseQueryPtr QUERY_4; @@ -68,7 +68,7 @@ class SloppyPhraseQueryFixture : public LuceneTestFixture doc->add(f); return doc; } - + PhraseQueryPtr makePhraseQuery(const String& terms) { PhraseQueryPtr query = newLucene(); @@ -77,7 +77,7 @@ class SloppyPhraseQueryFixture : public LuceneTestFixture query->add(newLucene(L"f", tokens[i])); return query; } - + double checkPhraseQuery(DocumentPtr doc, PhraseQueryPtr query, int32_t slop, int32_t expectedNumResults) { query->setSlop(slop); @@ -90,7 +90,7 @@ class SloppyPhraseQueryFixture : public LuceneTestFixture IndexSearcherPtr searcher = newLucene(ramDir, true); TopDocsPtr td = searcher->search(query, FilterPtr(), 10); - BOOST_CHECK_EQUAL(expectedNumResults, td->totalHits); + EXPECT_EQ(expectedNumResults, td->totalHits); searcher->close(); ramDir->close(); @@ -99,12 +99,10 @@ class SloppyPhraseQueryFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(SloppyPhraseQueryTest, SloppyPhraseQueryFixture) - /// Test DOC_4 and QUERY_4. /// QUERY_4 has a fuzzy (len=1) match to DOC_4, so all slop values > 0 should succeed. /// But only the 3rd sequence of A's in DOC_4 will do. -BOOST_AUTO_TEST_CASE(testDoc4Query4AllSlopsShouldMatch) +TEST_F(SloppyPhraseQueryTest, testDoc4Query4AllSlopsShouldMatch) { for (int32_t slop = 0; slop < 30; ++slop) { @@ -115,19 +113,19 @@ BOOST_AUTO_TEST_CASE(testDoc4Query4AllSlopsShouldMatch) /// Test DOC_1 and QUERY_1. /// QUERY_1 has an exact match to DOC_1, so all slop values should succeed. -BOOST_AUTO_TEST_CASE(testDoc1Query1AllSlopsShouldMatch) +TEST_F(SloppyPhraseQueryTest, testDoc1Query1AllSlopsShouldMatch) { for (int32_t slop = 0; slop < 30; ++slop) { double score1 = checkPhraseQuery(DOC_1, QUERY_1, slop, 1); double score2 = checkPhraseQuery(DOC_1_B, QUERY_1, slop, 1); - BOOST_CHECK(score2 > score1); + EXPECT_TRUE(score2 > score1); } } /// Test DOC_2 and QUERY_1. /// 6 should be the minimum slop to make QUERY_1 match DOC_2. -BOOST_AUTO_TEST_CASE(testDoc2Query1Slop6OrMoreShouldMatch) +TEST_F(SloppyPhraseQueryTest, testDoc2Query1Slop6OrMoreShouldMatch) { for (int32_t slop = 0; slop < 30; ++slop) { @@ -136,33 +134,31 @@ BOOST_AUTO_TEST_CASE(testDoc2Query1Slop6OrMoreShouldMatch) if (numResultsExpected > 0) { double score2 = checkPhraseQuery(DOC_2_B, QUERY_1, slop, 1); - BOOST_CHECK(score2 > score1); + EXPECT_TRUE(score2 > score1); } } } /// Test DOC_2 and QUERY_2. /// QUERY_2 has an exact match to DOC_2, so all slop values should succeed. -BOOST_AUTO_TEST_CASE(testDoc2Query2AllSlopsShouldMatch) +TEST_F(SloppyPhraseQueryTest, testDoc2Query2AllSlopsShouldMatch) { for (int32_t slop = 0; slop < 30; ++slop) { double score1 = checkPhraseQuery(DOC_2, QUERY_2, slop, 1); double score2 = checkPhraseQuery(DOC_2_B, QUERY_2, slop, 1); - BOOST_CHECK(score2 > score1); + EXPECT_TRUE(score2 > score1); } } /// Test DOC_3 and QUERY_1. /// QUERY_1 has an exact match to DOC_3, so all slop values should succeed. -BOOST_AUTO_TEST_CASE(testDoc3Query1AllSlopsShouldMatch) +TEST_F(SloppyPhraseQueryTest, testDoc3Query1AllSlopsShouldMatch) { for (int32_t slop = 0; slop < 30; ++slop) { double score1 = checkPhraseQuery(DOC_3, QUERY_1, slop, 1); double score2 = checkPhraseQuery(DOC_3_B, QUERY_1, slop, 1); - BOOST_CHECK(score2 > score1); + EXPECT_TRUE(score2 > score1); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/SortTest.cpp b/src/test/search/SortTest.cpp index 7867c757..2b735f0c 100644 --- a/src/test/search/SortTest.cpp +++ b/src/test/search/SortTest.cpp @@ -37,20 +37,20 @@ using namespace Lucene; -class SortFixture : public LuceneTestFixture +class SortTest : public LuceneTestFixture { public: - SortFixture() + SortTest() { r = newLucene(); - + // document data: // the tracer field is used to determine which document was hit the contents field is used to search and sort by relevance - // the int field to sort by int the double field to sort by double the string field to sort by string the i18n field + // the int field to sort by int the double field to sort by double the string field to sort by string the i18n field // includes accented characters for testing locale-specific sorting data = Collection< Collection >::newInstance(14); // tracer contents int double string custom i18n long byte encoding - + data[0] = newCollection(L"A", L"x a", L"5", L"4.0", L"c", L"A-3", L"p\u00EAche", L"10", L"177", L"J"); data[1] = newCollection(L"B", L"y a", L"5", L"3.4028235E38", L"i", L"B-10", L"HAT", L"1000000000", L"52", L"I"); data[2] = newCollection(L"C", L"x a b c", L"2147483647", L"1.0", L"j", L"A-2", L"p\u00E9ch\u00E9", L"99999999", L"66", L"H"); @@ -65,7 +65,7 @@ class SortFixture : public LuceneTestFixture data[11] = newCollection(L"X", L"g", L"1", L"0.1", L"", L"", L"", L"", L"", L""); data[12] = newCollection(L"Y", L"g", L"1", L"0.2", L"", L"", L"", L"", L"", L""); data[13] = newCollection(L"Z", L"f g", L"", L"", L"", L"", L"", L"", L"", L""); - + full = getFullIndex(); searchX = getXIndex(); searchY = getYIndex(); @@ -77,14 +77,14 @@ class SortFixture : public LuceneTestFixture queryG = newLucene(newLucene(L"contents", L"g")); sort = newLucene(); } - - virtual ~SortFixture() + + virtual ~SortTest() { } protected: static const int32_t NUM_STRINGS; - + SearcherPtr full; SearcherPtr searchX; SearcherPtr searchY; @@ -96,7 +96,7 @@ class SortFixture : public LuceneTestFixture QueryPtr queryG; SortPtr sort; RandomPtr r; - + Collection< Collection > data; protected: @@ -104,22 +104,22 @@ class SortFixture : public LuceneTestFixture { return getIndex(true, true); } - + SearcherPtr getXIndex() { return getIndex(true, false); } - + SearcherPtr getYIndex() { return getIndex(false, true); } - + SearcherPtr getEmptyIndex() { return getIndex(false, false); } - + SearcherPtr getIndex(bool even, bool odd) { RAMDirectoryPtr indexStore = newLucene(); @@ -158,7 +158,7 @@ class SortFixture : public LuceneTestFixture s->setDefaultFieldSortScoring(true, true); return s; } - + MapStringDouble getScores(Collection hits, SearcherPtr searcher) { MapStringDouble scoreMap = MapStringDouble::newInstance(); @@ -167,31 +167,31 @@ class SortFixture : public LuceneTestFixture { DocumentPtr doc = searcher->doc(hits[i]->doc); Collection v = doc->getValues(L"tracer"); - BOOST_CHECK_EQUAL(v.size(), 1); + EXPECT_EQ(v.size(), 1); scoreMap.put(v[0], hits[i]->score); } return scoreMap; } - + void checkSameValues(MapStringDouble m1, MapStringDouble m2) { int32_t n = m1.size(); int32_t m = m2.size(); - BOOST_CHECK_EQUAL(n, m); + EXPECT_EQ(n, m); for (MapStringDouble::iterator key = m1.begin(); key != m1.end(); ++key) { double o1 = m1.get(key->first); double o2 = m2.get(key->first); - BOOST_CHECK_CLOSE_FRACTION(o1, o2, 1e-6); + EXPECT_NEAR(o1, o2, 1e-6); } } - + /// make sure the documents returned by the search match the expected list void checkMatches(SearcherPtr searcher, QueryPtr query, SortPtr sort, const String& expectedResult) { TopDocsPtr hits = searcher->search(query, FilterPtr(), expectedResult.length(), sort); Collection result = hits->scoreDocs; - BOOST_CHECK_EQUAL(hits->totalHits, expectedResult.length()); + EXPECT_EQ(hits->totalHits, expectedResult.length()); StringStream buff; int32_t n = result.size(); for (int32_t i = 0; i < n; ++i) @@ -201,9 +201,9 @@ class SortFixture : public LuceneTestFixture for (int32_t j = 0; j < v.size(); ++j) buff << v[j]; } - BOOST_CHECK_EQUAL(expectedResult, buff.str()); + EXPECT_EQ(expectedResult, buff.str()); } - + IndexSearcherPtr getFullStrings() { RAMDirectoryPtr indexStore = newLucene(); @@ -226,7 +226,7 @@ class SortFixture : public LuceneTestFixture writer->close(); return newLucene(indexStore, true); } - + String getRandomNumberString(int32_t num, int32_t low, int32_t high) { StringStream buff; @@ -234,12 +234,12 @@ class SortFixture : public LuceneTestFixture buff << getRandomNumber(low, high); return buff.str(); } - + String getRandomCharString(int32_t num) { return getRandomCharString(num, 48, 122); } - + String getRandomCharString(int32_t num, int32_t start, int32_t end) { static const wchar_t* alphanum = L"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz"; @@ -248,19 +248,19 @@ class SortFixture : public LuceneTestFixture buff << alphanum[getRandomNumber(start, end)]; return buff.str(); } - + int32_t getRandomNumber(int32_t low, int32_t high) { return (std::abs(r->nextInt()) % (high - low)) + low; } - + void checkSaneFieldCaches() { Collection entries = FieldCache::DEFAULT()->getCacheEntries(); Collection insanity = FieldCacheSanityChecker::checkSanity(entries); - BOOST_CHECK_EQUAL(0, insanity.size()); + EXPECT_EQ(0, insanity.size()); } - + /// runs a variety of sorts useful for multisearchers void runMultiSorts(SearcherPtr multi, bool isFull) { @@ -320,10 +320,10 @@ class SortFixture : public LuceneTestFixture sort->setSort(newCollection(newLucene(L"string", SortField::STRING, true))); checkMatches(multi, queryF, sort, L"IJZ"); - // up to this point, all of the searches should have "sane" FieldCache behavior, and should have reused + // up to this point, all of the searches should have "sane" FieldCache behavior, and should have reused // the cache in several cases checkSaneFieldCaches(); - + // next we'll check Locale based (Collection) for 'string', so purge first FieldCache::DEFAULT()->purgeAllCaches(); @@ -341,12 +341,10 @@ class SortFixture : public LuceneTestFixture } }; -const int32_t SortFixture::NUM_STRINGS = 6000; - -BOOST_FIXTURE_TEST_SUITE(SortTest, SortFixture) +const int32_t SortTest::NUM_STRINGS = 6000; /// test the sorts by score and document number -BOOST_AUTO_TEST_CASE(testBuiltInSorts) +TEST_F(SortTest, testBuiltInSorts) { sort = newLucene(); checkMatches(full, queryX, sort, L"ACEGI"); @@ -358,7 +356,7 @@ BOOST_AUTO_TEST_CASE(testBuiltInSorts) } /// test sorts where the type of field is specified -BOOST_AUTO_TEST_CASE(testTypedSort) +TEST_F(SortTest, testTypedSort) { sort->setSort(newCollection(newLucene(L"int", SortField::INT), SortField::FIELD_DOC())); checkMatches(full, queryX, sort, L"IGAEC"); @@ -382,7 +380,7 @@ BOOST_AUTO_TEST_CASE(testTypedSort) } /// Test String sorting: small queue to many matches, multi field sort, reverse sort -BOOST_AUTO_TEST_CASE(testStringSort) +TEST_F(SortTest, testStringSort) { IndexSearcherPtr searcher = getFullStrings(); sort->setSort(newCollection(newLucene(L"string", SortField::STRING), newLucene(L"string2", SortField::STRING, true), SortField::FIELD_DOC())); @@ -404,18 +402,18 @@ BOOST_AUTO_TEST_CASE(testStringSort) { int32_t cmp = v[j].compare(last); if (cmp < 0) - BOOST_FAIL("first field out of order"); + FAIL() << "first field out of order"; if (cmp == 0) // ensure second field is in reverse order { cmp = v2[j].compare(lastSub); if (cmp > 0) - BOOST_FAIL("second field out of order"); + FAIL() << "second field out of order"; else if (cmp == 0) // ensure docid is in order { if (result[x]->doc < lastDocId) - BOOST_FAIL("docid out of order"); + FAIL() << "docid out of order"; } - + } } last = v[j]; @@ -434,49 +432,49 @@ namespace TestCustomFieldParserSort virtual ~CustomIntParser() { } - + public: virtual int32_t parseInt(const String& string) { return (string[0] - L'A') * 123456; } }; - + class CustomDoubleParser : public DoubleParser { public: virtual ~CustomDoubleParser() { } - + public: virtual double parseDouble(const String& string) { return std::sqrt((double)string[0]); } }; - + class CustomLongParser : public LongParser { public: virtual ~CustomLongParser() { } - + public: virtual int64_t parseLong(const String& string) { return (string[0] - L'A') * (int64_t)1234567890; } }; - + class CustomByteParser : public ByteParser { public: virtual ~CustomByteParser() { } - + public: virtual uint8_t parseByte(const String& string) { @@ -485,24 +483,24 @@ namespace TestCustomFieldParserSort }; } -/// Test sorts where the type of field is specified and a custom field parser is used, that uses a simple char encoding. -/// The sorted string contains a character beginning from 'A' that is mapped to a numeric value using some "funny" +/// Test sorts where the type of field is specified and a custom field parser is used, that uses a simple char encoding. +/// The sorted string contains a character beginning from 'A' that is mapped to a numeric value using some "funny" /// algorithm to be different for each data type. -BOOST_AUTO_TEST_CASE(testCustomFieldParserSort) +TEST_F(SortTest, testCustomFieldParserSort) { // since tests explicitly uses different parsers on the same field name we explicitly check/purge the FieldCache between each assertMatch FieldCachePtr fc = FieldCache::DEFAULT(); - + sort->setSort(newCollection(newLucene(L"parser", newLucene()), SortField::FIELD_DOC())); checkMatches(full, queryA, sort, L"JIHGFEDCBA"); checkSaneFieldCaches(); fc->purgeAllCaches(); - + sort->setSort(newCollection(newLucene(L"parser", newLucene()), SortField::FIELD_DOC())); checkMatches(full, queryA, sort, L"JIHGFEDCBA"); checkSaneFieldCaches(); fc->purgeAllCaches(); - + sort->setSort(newCollection(newLucene(L"parser", newLucene()), SortField::FIELD_DOC())); checkMatches(full, queryA, sort, L"JIHGFEDCBA"); checkSaneFieldCaches(); @@ -515,7 +513,7 @@ BOOST_AUTO_TEST_CASE(testCustomFieldParserSort) } /// test sorts when there's nothing in the index -BOOST_AUTO_TEST_CASE(testEmptyIndex) +TEST_F(SortTest, testEmptyIndex) { SearcherPtr empty = getEmptyIndex(); @@ -543,14 +541,14 @@ namespace TestNewCustomFieldParserSort virtual ~MyIntParser() { } - + public: virtual int32_t parseInt(const String& string) { return (string[0] - L'A') * 123456; } }; - + class MyFieldComparator : public FieldComparator { public: @@ -559,55 +557,55 @@ namespace TestNewCustomFieldParserSort slotValues = Collection::newInstance(numHits); bottomValue = 0; } - + virtual ~MyFieldComparator() { } - + public: Collection docValues; Collection slotValues; int32_t bottomValue; - + public: virtual void copy(int32_t slot, int32_t doc) { slotValues[slot] = docValues[doc]; } - + virtual int32_t compare(int32_t slot1, int32_t slot2) { return slotValues[slot1] - slotValues[slot2]; } - + virtual int32_t compareBottom(int32_t doc) { return bottomValue - docValues[doc]; } - + virtual void setBottom(int32_t slot) { bottomValue = slotValues[slot]; } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { docValues = FieldCache::DEFAULT()->getInts(reader, L"parser", newLucene()); } - + virtual ComparableValue value(int32_t slot) { return slotValues[slot]; } }; - + class MyFieldComparatorSource : public FieldComparatorSource { public: virtual ~MyFieldComparatorSource() { } - + public: virtual FieldComparatorPtr newComparator(const String& fieldname, int32_t numHits, int32_t sortPos, bool reversed) { @@ -617,14 +615,14 @@ namespace TestNewCustomFieldParserSort } // Test sorting with custom FieldComparator -BOOST_AUTO_TEST_CASE(testNewCustomFieldParserSort) +TEST_F(SortTest, testNewCustomFieldParserSort) { sort->setSort(newCollection(newLucene(L"parser", newLucene()))); checkMatches(full, queryA, sort, L"JIHGFEDCBA"); } /// test sorts in reverse -BOOST_AUTO_TEST_CASE(testReverseSort) +TEST_F(SortTest, testReverseSort) { sort->setSort(newCollection(newLucene(L"", SortField::SCORE, true), SortField::FIELD_DOC())); checkMatches(full, queryX, sort, L"IEGCA"); @@ -648,7 +646,7 @@ BOOST_AUTO_TEST_CASE(testReverseSort) } /// test sorting when the sort field is empty (undefined) for some of the documents -BOOST_AUTO_TEST_CASE(testEmptyFieldSort) +TEST_F(SortTest, testEmptyFieldSort) { sort->setSort(newCollection(newLucene(L"string", SortField::STRING))); checkMatches(full, queryF, sort, L"ZJI"); @@ -694,7 +692,7 @@ BOOST_AUTO_TEST_CASE(testEmptyFieldSort) sort->setSort(newCollection(newLucene(L"int", SortField::INT), newLucene(L"string", SortField::STRING), newLucene(L"double", SortField::DOUBLE, true))); checkMatches(multiSearcher, queryG, sort, L"ZYXW"); - + // Don't close the multiSearcher. it would close the full searcher too! // Do the same for a ParallelMultiSearcher @@ -708,7 +706,7 @@ BOOST_AUTO_TEST_CASE(testEmptyFieldSort) } /// test sorts using a series of fields -BOOST_AUTO_TEST_CASE(testSortCombos) +TEST_F(SortTest, testSortCombos) { sort->setSort(newCollection(newLucene(L"int", SortField::INT), newLucene(L"double", SortField::DOUBLE))); checkMatches(full, queryX, sort, L"IGEAC"); @@ -721,7 +719,7 @@ BOOST_AUTO_TEST_CASE(testSortCombos) } /// test using a Locale for sorting strings -BOOST_AUTO_TEST_CASE(testLocaleSort) +TEST_F(SortTest, testLocaleSort) { sort->setSort(newCollection(newLucene(L"string", std::locale()))); checkMatches(full, queryX, sort, L"AIGEC"); @@ -733,21 +731,21 @@ BOOST_AUTO_TEST_CASE(testLocaleSort) } /// test a variety of sorts using more than one searcher -BOOST_AUTO_TEST_CASE(testMultiSort) +TEST_F(SortTest, testMultiSort) { MultiSearcherPtr searcher = newLucene(newCollection(searchX, searchY)); runMultiSorts(searcher, false); } /// test a variety of sorts using a parallel multisearcher -BOOST_AUTO_TEST_CASE(testParallelMultiSort) +TEST_F(SortTest, testParallelMultiSort) { MultiSearcherPtr searcher = newLucene(newCollection(searchX, searchY)); runMultiSorts(searcher, false); } // test that the relevancy scores are the same even if hits are sorted -BOOST_AUTO_TEST_CASE(testNormalizedScores) +TEST_F(SortTest, testNormalizedScores) { // capture relevancy scores MapStringDouble scoresX = getScores(full->search(queryX, FilterPtr(), 1000)->scoreDocs, full); @@ -834,14 +832,14 @@ namespace TestTopDocsScores { this->docs = docs; } - + virtual ~TopDocsFilter() { } - + protected: TopDocsPtr docs; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) { @@ -853,22 +851,22 @@ namespace TestTopDocsScores }; } -BOOST_AUTO_TEST_CASE(testTopDocsScores) +TEST_F(SortTest, testTopDocsScores) { SortPtr sort = newLucene(); int32_t numDocs = 10; // try to pick a query that will result in an unnormalized score greater than 1 to test for correct normalization TopDocsPtr docs1 = full->search(queryE, FilterPtr(), numDocs, sort); - + // a filter that only allows through the first hit FilterPtr filter = newLucene(docs1); TopDocsPtr docs2 = full->search(queryE, filter, numDocs, sort); - BOOST_CHECK_CLOSE_FRACTION(docs1->scoreDocs[0]->score, docs2->scoreDocs[0]->score, 1e-6); + EXPECT_NEAR(docs1->scoreDocs[0]->score, docs2->scoreDocs[0]->score, 1e-6); } -BOOST_AUTO_TEST_CASE(testSortWithoutFillFields) +TEST_F(SortTest, testSortWithoutFillFields) { Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); for (int32_t i = 0; i < sort.size(); ++i) @@ -880,11 +878,11 @@ BOOST_AUTO_TEST_CASE(testSortWithoutFillFields) Collection sd = tdc->topDocs()->scoreDocs; for (int32_t j = 1; j < sd.size(); ++j) - BOOST_CHECK_NE(sd[j]->doc, sd[j - 1]->doc); + EXPECT_NE(sd[j]->doc, sd[j - 1]->doc); } } -BOOST_AUTO_TEST_CASE(testSortWithoutScoreTracking) +TEST_F(SortTest, testSortWithoutScoreTracking) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); @@ -898,12 +896,12 @@ BOOST_AUTO_TEST_CASE(testSortWithoutScoreTracking) TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; for (int32_t j = 1; j < sd.size(); ++j) - BOOST_CHECK(MiscUtils::isNaN(sd[j]->score)); - BOOST_CHECK(MiscUtils::isNaN(td->maxScore)); + EXPECT_TRUE(MiscUtils::isNaN(sd[j]->score)); + EXPECT_TRUE(MiscUtils::isNaN(td->maxScore)); } } -BOOST_AUTO_TEST_CASE(testSortWithScoreNoMaxScoreTracking) +TEST_F(SortTest, testSortWithScoreNoMaxScoreTracking) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); @@ -917,12 +915,12 @@ BOOST_AUTO_TEST_CASE(testSortWithScoreNoMaxScoreTracking) TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; for (int32_t j = 1; j < sd.size(); ++j) - BOOST_CHECK(!MiscUtils::isNaN(sd[j]->score)); - BOOST_CHECK(MiscUtils::isNaN(td->maxScore)); + EXPECT_TRUE(!MiscUtils::isNaN(sd[j]->score)); + EXPECT_TRUE(MiscUtils::isNaN(td->maxScore)); } } -BOOST_AUTO_TEST_CASE(testSortWithScoreAndMaxScoreTracking) +TEST_F(SortTest, testSortWithScoreAndMaxScoreTracking) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); @@ -936,12 +934,12 @@ BOOST_AUTO_TEST_CASE(testSortWithScoreAndMaxScoreTracking) TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; for (int32_t j = 1; j < sd.size(); ++j) - BOOST_CHECK(!MiscUtils::isNaN(sd[j]->score)); - BOOST_CHECK(!MiscUtils::isNaN(td->maxScore)); + EXPECT_TRUE(!MiscUtils::isNaN(sd[j]->score)); + EXPECT_TRUE(!MiscUtils::isNaN(td->maxScore)); } } -BOOST_AUTO_TEST_CASE(testOutOfOrderDocsScoringSort) +TEST_F(SortTest, testOutOfOrderDocsScoringSort) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); @@ -956,21 +954,21 @@ BOOST_AUTO_TEST_CASE(testOutOfOrderDocsScoringSort) newCollection(true, true, true) ); Collection actualTFCClasses = newCollection( - L"OutOfOrderOneComparatorNonScoringCollector", - L"OutOfOrderOneComparatorScoringMaxScoreCollector", - L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", - L"OutOfOrderOneComparatorScoringMaxScoreCollector", - L"OutOfOrderOneComparatorNonScoringCollector", - L"OutOfOrderOneComparatorScoringMaxScoreCollector", - L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", + L"OutOfOrderOneComparatorNonScoringCollector", + L"OutOfOrderOneComparatorScoringMaxScoreCollector", + L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", + L"OutOfOrderOneComparatorScoringMaxScoreCollector", + L"OutOfOrderOneComparatorNonScoringCollector", + L"OutOfOrderOneComparatorScoringMaxScoreCollector", + L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", L"OutOfOrderOneComparatorScoringMaxScoreCollector" ); - + BooleanQueryPtr bq = newLucene(); - // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 which delegates to + // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 which delegates to // BS if there are no mandatory clauses. bq->add(newLucene(), BooleanClause::SHOULD); - // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return the clause + // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return the clause // instead of BQ. bq->setMinimumNumberShouldMatch(1); for (int32_t i = 0; i < sort.size(); ++i) @@ -979,18 +977,18 @@ BOOST_AUTO_TEST_CASE(testOutOfOrderDocsScoringSort) { TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, tfcOptions[j][0] == 1, tfcOptions[j][1] == 1, tfcOptions[j][2] == 1, false); - BOOST_CHECK_EQUAL(tdc->getClassName(), actualTFCClasses[j]); - + EXPECT_EQ(tdc->getClassName(), actualTFCClasses[j]); + full->search(bq, tdc); TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; - BOOST_CHECK_EQUAL(10, sd.size()); + EXPECT_EQ(10, sd.size()); } } } -BOOST_AUTO_TEST_CASE(testSortWithScoreAndMaxScoreTrackingNoResults) +TEST_F(SortTest, testSortWithScoreAndMaxScoreTrackingNoResults) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); @@ -998,12 +996,12 @@ BOOST_AUTO_TEST_CASE(testSortWithScoreAndMaxScoreTrackingNoResults) { TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, true, true, true, true); TopDocsPtr td = tdc->topDocs(); - BOOST_CHECK_EQUAL(0, td->totalHits); - BOOST_CHECK(MiscUtils::isNaN(td->maxScore)); + EXPECT_EQ(0, td->totalHits); + EXPECT_TRUE(MiscUtils::isNaN(td->maxScore)); } } -BOOST_AUTO_TEST_CASE(testSortWithStringNoException) +TEST_F(SortTest, testSortWithStringNoException) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1021,5 +1019,3 @@ BOOST_AUTO_TEST_CASE(testSortWithStringNoException) IndexSearcherPtr is = newLucene(indexStore, true); is->search(newLucene(), FilterPtr(), 500, sort); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/SpanQueryFilterTest.cpp b/src/test/search/SpanQueryFilterTest.cpp index b1b82e4c..dda33450 100644 --- a/src/test/search/SpanQueryFilterTest.cpp +++ b/src/test/search/SpanQueryFilterTest.cpp @@ -22,7 +22,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SpanQueryFilterTest, LuceneTestFixture) +typedef LuceneTestFixture SpanQueryFilterTest; static int32_t getDocIdSetSize(DocIdSetPtr docIdSet) { @@ -36,11 +36,11 @@ static int32_t getDocIdSetSize(DocIdSetPtr docIdSet) static void checkContainsDocId(DocIdSetPtr docIdSet, int32_t docId) { DocIdSetIteratorPtr it = docIdSet->iterator(); - BOOST_CHECK_NE(it->advance(docId), DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_EQUAL(it->docID(), docId); + EXPECT_NE(it->advance(docId), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(it->docID(), docId); } -BOOST_AUTO_TEST_CASE(testFilterWorks) +TEST_F(SpanQueryFilterTest, testFilterWorks) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(testFilterWorks) document->add(newLucene(L"field", intToEnglish(i) + L" equals " + intToEnglish(i), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(document); } - + writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); @@ -59,21 +59,19 @@ BOOST_AUTO_TEST_CASE(testFilterWorks) SpanQueryFilterPtr filter = newLucene(query); SpanFilterResultPtr result = filter->bitSpans(reader); DocIdSetPtr docIdSet = result->getDocIdSet(); - BOOST_CHECK(docIdSet); + EXPECT_TRUE(docIdSet); checkContainsDocId(docIdSet, 10); Collection spans = result->getPositions(); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); int32_t size = getDocIdSetSize(docIdSet); - BOOST_CHECK_EQUAL(spans.size(), size); + EXPECT_EQ(spans.size(), size); for (Collection::iterator info = spans.begin(); info != spans.end(); ++info) { - BOOST_CHECK(*info); + EXPECT_TRUE(*info); // The doc should indicate the bit is on checkContainsDocId(docIdSet, (*info)->getDoc()); // There should be two positions in each - BOOST_CHECK_EQUAL((*info)->getPositions().size(), 2); + EXPECT_EQ((*info)->getPositions().size(), 2); } reader->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/TermRangeFilterTest.cpp b/src/test/search/TermRangeFilterTest.cpp index 5d62802e..cf525f16 100644 --- a/src/test/search/TermRangeFilterTest.cpp +++ b/src/test/search/TermRangeFilterTest.cpp @@ -19,17 +19,15 @@ using namespace Lucene; -class TermRangeFilterFixture : public BaseTestRangeFilterFixture +class TermRangeFilterTest : public BaseTestRangeFilterFixture { public: - virtual ~TermRangeFilterFixture() + virtual ~TermRangeFilterTest() { } }; -BOOST_FIXTURE_TEST_SUITE(TermRangeFilterTest, TermRangeFilterFixture) - -BOOST_AUTO_TEST_CASE(testRangeFilterId) +TEST_F(TermRangeFilterTest, testRangeFilterId) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -42,80 +40,80 @@ BOOST_AUTO_TEST_CASE(testRangeFilterId) int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); + EXPECT_EQ(numDocs, 1 + maxId - minId); QueryPtr q = newLucene(newLucene(L"body", L"body")); // test id, bounded on both ends - + Collection result = search->search(q, newLucene(L"id", minIP, maxIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, newLucene(L"id", minIP, maxIP, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, newLucene(L"id", minIP, maxIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, newLucene(L"id", minIP, maxIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); result = search->search(q, newLucene(L"id", medIP, maxIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + maxId - medId, result.size()); + EXPECT_EQ(1 + maxId - medId, result.size()); result = search->search(q, newLucene(L"id", minIP, medIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1 + medId - minId, result.size()); + EXPECT_EQ(1 + medId - minId, result.size()); // unbounded id result = search->search(q, newLucene(L"id", minIP, VariantUtils::null(), true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, newLucene(L"id", VariantUtils::null(), maxIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, newLucene(L"id", minIP, VariantUtils::null(), false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, newLucene(L"id", VariantUtils::null(), maxIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, newLucene(L"id", medIP, maxIP, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(maxId - medId, result.size()); + EXPECT_EQ(maxId - medId, result.size()); result = search->search(q, newLucene(L"id", minIP, medIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(medId - minId, result.size()); + EXPECT_EQ(medId - minId, result.size()); // very small sets result = search->search(q, newLucene(L"id", minIP, minIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, newLucene(L"id", medIP, medIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, newLucene(L"id", maxIP, maxIP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, newLucene(L"id", minIP, minIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, newLucene(L"id", VariantUtils::null(), minIP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, newLucene(L"id", maxIP, maxIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, newLucene(L"id", maxIP, VariantUtils::null(), true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, newLucene(L"id", medIP, medIP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testRangeFilterIdCollating) +TEST_F(TermRangeFilterTest, testRangeFilterIdCollating) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); CollatorPtr c = newLucene(std::locale()); - + int32_t medId = ((maxId - minId) / 2); String minIP = pad(minId); @@ -124,74 +122,74 @@ BOOST_AUTO_TEST_CASE(testRangeFilterIdCollating) int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); - + EXPECT_EQ(numDocs, 1 + maxId - minId); + QueryPtr q = newLucene(newLucene(L"body", L"body")); // test id, bounded on both ends int32_t numHits = search->search(q, newLucene(L"id", minIP, maxIP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs, numHits); + EXPECT_EQ(numDocs, numHits); numHits = search->search(q, newLucene(L"id", minIP, maxIP, true, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); numHits = search->search(q, newLucene(L"id", minIP, maxIP, false, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); numHits = search->search(q, newLucene(L"id", minIP, maxIP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 2, numHits); + EXPECT_EQ(numDocs - 2, numHits); numHits = search->search(q, newLucene(L"id", medIP, maxIP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1 + maxId - medId, numHits); + EXPECT_EQ(1 + maxId - medId, numHits); numHits = search->search(q, newLucene(L"id", minIP, medIP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1 + medId - minId, numHits); + EXPECT_EQ(1 + medId - minId, numHits); // unbounded id numHits = search->search(q, newLucene(L"id", minIP, VariantUtils::null(), true, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs, numHits); + EXPECT_EQ(numDocs, numHits); numHits = search->search(q, newLucene(L"id", VariantUtils::null(), maxIP, false, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs, numHits); + EXPECT_EQ(numDocs, numHits); numHits = search->search(q, newLucene(L"id", minIP, VariantUtils::null(), false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); numHits = search->search(q, newLucene(L"id", VariantUtils::null(), maxIP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); numHits = search->search(q, newLucene(L"id", medIP, maxIP, true, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(maxId - medId, numHits); + EXPECT_EQ(maxId - medId, numHits); numHits = search->search(q, newLucene(L"id", minIP, medIP, false, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(medId - minId, numHits); + EXPECT_EQ(medId - minId, numHits); // very small sets numHits = search->search(q, newLucene(L"id", minIP, minIP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(0, numHits); + EXPECT_EQ(0, numHits); numHits = search->search(q, newLucene(L"id", medIP, medIP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(0, numHits); + EXPECT_EQ(0, numHits); numHits = search->search(q, newLucene(L"id", maxIP, maxIP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(0, numHits); + EXPECT_EQ(0, numHits); numHits = search->search(q, newLucene(L"id", minIP, minIP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); numHits = search->search(q, newLucene(L"id", VariantUtils::null(), minIP, false, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); numHits = search->search(q, newLucene(L"id", maxIP, maxIP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); numHits = search->search(q, newLucene(L"id", maxIP, VariantUtils::null(), true, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); numHits = search->search(q, newLucene(L"id", medIP, medIP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); } -BOOST_AUTO_TEST_CASE(testRangeFilterRand) +TEST_F(TermRangeFilterTest, testRangeFilterRand) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -201,57 +199,57 @@ BOOST_AUTO_TEST_CASE(testRangeFilterRand) int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); - + EXPECT_EQ(numDocs, 1 + maxId - minId); + QueryPtr q = newLucene(newLucene(L"body", L"body")); - + // test extremes, bounded on both ends Collection result = search->search(q, newLucene(L"rand", minRP, maxRP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, newLucene(L"rand", minRP, maxRP, true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, newLucene(L"rand", minRP, maxRP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, newLucene(L"rand", minRP, maxRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 2, result.size()); + EXPECT_EQ(numDocs - 2, result.size()); // unbounded result = search->search(q, newLucene(L"rand", minRP, VariantUtils::null(), true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, newLucene(L"rand", VariantUtils::null(), maxRP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs, result.size()); + EXPECT_EQ(numDocs, result.size()); result = search->search(q, newLucene(L"rand", minRP, VariantUtils::null(), false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); result = search->search(q, newLucene(L"rand", VariantUtils::null(), maxRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(numDocs - 1, result.size()); + EXPECT_EQ(numDocs - 1, result.size()); // very small sets result = search->search(q, newLucene(L"rand", minRP, minRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, newLucene(L"rand", maxRP, maxRP, false, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(0, result.size()); + EXPECT_EQ(0, result.size()); result = search->search(q, newLucene(L"rand", minRP, minRP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, newLucene(L"rand", VariantUtils::null(), minRP, false, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, newLucene(L"rand", maxRP, maxRP, true, true), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); result = search->search(q, newLucene(L"rand", maxRP, VariantUtils::null(), true, false), numDocs)->scoreDocs; - BOOST_CHECK_EQUAL(1, result.size()); + EXPECT_EQ(1, result.size()); } -BOOST_AUTO_TEST_CASE(testRangeFilterRandCollating) +TEST_F(TermRangeFilterTest, testRangeFilterRandCollating) { // using the unsigned index because collation seems to ignore hyphens IndexReaderPtr reader = IndexReader::open(unsignedIndex->index, true); @@ -264,54 +262,52 @@ BOOST_AUTO_TEST_CASE(testRangeFilterRandCollating) int32_t numDocs = reader->numDocs(); - BOOST_CHECK_EQUAL(numDocs, 1 + maxId - minId); - + EXPECT_EQ(numDocs, 1 + maxId - minId); + QueryPtr q = newLucene(newLucene(L"body", L"body")); - + // test extremes, bounded on both ends int32_t numHits = search->search(q, newLucene(L"rand", minRP, maxRP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs, numHits); + EXPECT_EQ(numDocs, numHits); numHits = search->search(q, newLucene(L"rand", minRP, maxRP, true, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); numHits = search->search(q, newLucene(L"rand", minRP, maxRP, false, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); numHits = search->search(q, newLucene(L"rand", minRP, maxRP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 2, numHits); + EXPECT_EQ(numDocs - 2, numHits); // unbounded numHits = search->search(q, newLucene(L"rand", minRP, VariantUtils::null(), true, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs, numHits); + EXPECT_EQ(numDocs, numHits); numHits = search->search(q, newLucene(L"rand", VariantUtils::null(), maxRP, false, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs, numHits); + EXPECT_EQ(numDocs, numHits); numHits = search->search(q, newLucene(L"rand", minRP, VariantUtils::null(), false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); numHits = search->search(q, newLucene(L"rand", VariantUtils::null(), maxRP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(numDocs - 1, numHits); + EXPECT_EQ(numDocs - 1, numHits); // very small sets numHits = search->search(q, newLucene(L"rand", minRP, minRP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(0, numHits); + EXPECT_EQ(0, numHits); numHits = search->search(q, newLucene(L"rand", maxRP, maxRP, false, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(0, numHits); + EXPECT_EQ(0, numHits); numHits = search->search(q, newLucene(L"rand", minRP, minRP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); numHits = search->search(q, newLucene(L"rand", VariantUtils::null(), minRP, false, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); numHits = search->search(q, newLucene(L"rand", maxRP, maxRP, true, true, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); numHits = search->search(q, newLucene(L"rand", maxRP, VariantUtils::null(), true, false, c), 1000)->totalHits; - BOOST_CHECK_EQUAL(1, numHits); + EXPECT_EQ(1, numHits); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/TermRangeQueryTest.cpp b/src/test/search/TermRangeQueryTest.cpp index b8e12607..5485a2e3 100644 --- a/src/test/search/TermRangeQueryTest.cpp +++ b/src/test/search/TermRangeQueryTest.cpp @@ -32,7 +32,7 @@ class SingleCharTokenizer : public Tokenizer buffer = CharArray::newInstance(1); done = false; } - + virtual ~SingleCharTokenizer() { } @@ -62,7 +62,7 @@ class SingleCharTokenizer : public Tokenizer return true; } } - + virtual void reset(ReaderPtr input) { Tokenizer::reset(input); @@ -90,23 +90,23 @@ class SingleCharAnalyzer : public Analyzer tokenizer->reset(reader); return tokenizer; } - + virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(reader); } }; -class TermRangeQueryFixture : public LuceneTestFixture +class TermRangeQueryTest : public LuceneTestFixture { public: - TermRangeQueryFixture() + TermRangeQueryTest() { docCount = 0; dir = newLucene(); } - - virtual ~TermRangeQueryFixture() + + virtual ~TermRangeQueryTest() { } @@ -119,7 +119,7 @@ class TermRangeQueryFixture : public LuceneTestFixture { initializeIndex(values, newLucene()); } - + void initializeIndex(Collection values, AnalyzerPtr analyzer) { IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -127,14 +127,14 @@ class TermRangeQueryFixture : public LuceneTestFixture insertDoc(writer, values[i]); writer->close(); } - + void addDoc(const String& content) { IndexWriterPtr writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); insertDoc(writer, content); writer->close(); } - + void insertDoc(IndexWriterPtr writer, const String& content) { DocumentPtr doc = newLucene(); @@ -145,54 +145,52 @@ class TermRangeQueryFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(TermRangeQueryTest, TermRangeQueryFixture) - -BOOST_AUTO_TEST_CASE(testExclusive) +TEST_F(TermRangeQueryTest, testExclusive) { QueryPtr query = newLucene(L"content", L"A", L"C", false, false); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); IndexSearcherPtr searcher = newLucene(dir, true); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); searcher->close(); initializeIndex(newCollection(L"A", L"B", L"D")); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); searcher->close(); addDoc(L"C"); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); searcher->close(); } -BOOST_AUTO_TEST_CASE(testInclusive) +TEST_F(TermRangeQueryTest, testInclusive) { QueryPtr query = newLucene(L"content", L"A", L"C", true, true); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); IndexSearcherPtr searcher = newLucene(dir, true); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); searcher->close(); initializeIndex(newCollection(L"A", L"B", L"D")); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); searcher->close(); addDoc(L"C"); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); searcher->close(); } -BOOST_AUTO_TEST_CASE(testEqualsHashcode) +TEST_F(TermRangeQueryTest, testEqualsHashcode) { QueryPtr query = newLucene(L"content", L"A", L"C", true, true); @@ -200,133 +198,131 @@ BOOST_AUTO_TEST_CASE(testEqualsHashcode) QueryPtr other = newLucene(L"content", L"A", L"C", true, true); other->setBoost(1.0); - BOOST_CHECK(query->equals(query)); - BOOST_CHECK(query->equals(other)); - BOOST_CHECK_EQUAL(query->hashCode(), other->hashCode()); + EXPECT_TRUE(query->equals(query)); + EXPECT_TRUE(query->equals(other)); + EXPECT_EQ(query->hashCode(), other->hashCode()); other->setBoost(2.0); - BOOST_CHECK(!query->equals(other)); + EXPECT_TRUE(!query->equals(other)); other = newLucene(L"notcontent", L"A", L"C", true, true); - BOOST_CHECK(!query->equals(other)); + EXPECT_TRUE(!query->equals(other)); other = newLucene(L"content", L"X", L"C", true, true); - BOOST_CHECK(!query->equals(other)); + EXPECT_TRUE(!query->equals(other)); other = newLucene(L"content", L"A", L"Z", true, true); - BOOST_CHECK(!query->equals(other)); + EXPECT_TRUE(!query->equals(other)); query = newLucene(L"content", L"", L"C", true, true); other = newLucene(L"content", L"", L"C", true, true); - BOOST_CHECK(query->equals(other)); - BOOST_CHECK_EQUAL(query->hashCode(), other->hashCode()); + EXPECT_TRUE(query->equals(other)); + EXPECT_EQ(query->hashCode(), other->hashCode()); query = newLucene(L"content", L"C", L"", true, true); other = newLucene(L"content", L"C", L"", true, true); - BOOST_CHECK(query->equals(other)); - BOOST_CHECK_EQUAL(query->hashCode(), other->hashCode()); + EXPECT_TRUE(query->equals(other)); + EXPECT_EQ(query->hashCode(), other->hashCode()); query = newLucene(L"content", L"", L"C", true, true); other = newLucene(L"content", L"C", L"", true, true); - BOOST_CHECK(!query->equals(other)); + EXPECT_TRUE(!query->equals(other)); query = newLucene(L"content", L"A", L"C", false, false); other = newLucene(L"content", L"A", L"C", true, true); - BOOST_CHECK(!query->equals(other)); + EXPECT_TRUE(!query->equals(other)); query = newLucene(L"content", L"A", L"C", false, false); other = newLucene(L"content", L"A", L"C", false, false, newLucene(std::locale())); - BOOST_CHECK(!query->equals(other)); + EXPECT_TRUE(!query->equals(other)); } -BOOST_AUTO_TEST_CASE(testExclusiveCollating) +TEST_F(TermRangeQueryTest, testExclusiveCollating) { QueryPtr query = newLucene(L"content", L"A", L"C", false, false, newLucene(std::locale())); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); IndexSearcherPtr searcher = newLucene(dir, true); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); searcher->close(); initializeIndex(newCollection(L"A", L"B", L"D")); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); searcher->close(); addDoc(L"C"); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); searcher->close(); } -BOOST_AUTO_TEST_CASE(testInclusiveCollating) +TEST_F(TermRangeQueryTest, testInclusiveCollating) { QueryPtr query = newLucene(L"content", L"A", L"C", true, true, newLucene(std::locale())); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); IndexSearcherPtr searcher = newLucene(dir, true); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); searcher->close(); initializeIndex(newCollection(L"A", L"B", L"D")); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(2, hits.size()); + EXPECT_EQ(2, hits.size()); searcher->close(); addDoc(L"C"); searcher = newLucene(dir, true); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(3, hits.size()); + EXPECT_EQ(3, hits.size()); searcher->close(); } -BOOST_AUTO_TEST_CASE(testExclusiveLowerNull) +TEST_F(TermRangeQueryTest, testExclusiveLowerNull) { AnalyzerPtr analyzer = newLucene(); QueryPtr query = newLucene(L"content", VariantUtils::null(), L"C", false, false); initializeIndex(newCollection(L"A", L"B", L"", L"C", L"D"), analyzer); IndexSearcherPtr searcher = newLucene(dir, true); int32_t numHits = searcher->search(query, FilterPtr(), 1000)->totalHits; - BOOST_CHECK_EQUAL(3, numHits); + EXPECT_EQ(3, numHits); searcher->close(); - + initializeIndex(newCollection(L"A", L"B", L"", L"D"), analyzer); searcher = newLucene(dir, true); numHits = searcher->search(query, FilterPtr(), 1000)->totalHits; - BOOST_CHECK_EQUAL(3, numHits); + EXPECT_EQ(3, numHits); searcher->close(); - + addDoc(L"C"); searcher = newLucene(dir, true); numHits = searcher->search(query, FilterPtr(), 1000)->totalHits; - BOOST_CHECK_EQUAL(3, numHits); + EXPECT_EQ(3, numHits); searcher->close(); } -BOOST_AUTO_TEST_CASE(testInclusiveLowerNull) +TEST_F(TermRangeQueryTest, testInclusiveLowerNull) { AnalyzerPtr analyzer = newLucene(); QueryPtr query = newLucene(L"content", VariantUtils::null(), L"C", true, true); initializeIndex(newCollection(L"A", L"B", L"", L"C", L"D"), analyzer); IndexSearcherPtr searcher = newLucene(dir, true); int32_t numHits = searcher->search(query, FilterPtr(), 1000)->totalHits; - BOOST_CHECK_EQUAL(4, numHits); + EXPECT_EQ(4, numHits); searcher->close(); - + initializeIndex(newCollection(L"A", L"B", L"", L"D"), analyzer); searcher = newLucene(dir, true); numHits = searcher->search(query, FilterPtr(), 1000)->totalHits; - BOOST_CHECK_EQUAL(3, numHits); + EXPECT_EQ(3, numHits); searcher->close(); - + addDoc(L"C"); searcher = newLucene(dir, true); numHits = searcher->search(query, FilterPtr(), 1000)->totalHits; - BOOST_CHECK_EQUAL(4, numHits); + EXPECT_EQ(4, numHits); searcher->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/TermScorerTest.cpp b/src/test/search/TermScorerTest.cpp index 2969cea3..9181c79f 100644 --- a/src/test/search/TermScorerTest.cpp +++ b/src/test/search/TermScorerTest.cpp @@ -32,7 +32,7 @@ class TestHit : public LuceneObject this->doc = doc; this->score = score; } - + virtual ~TestHit() { } @@ -48,10 +48,10 @@ class TestHit : public LuceneObject } }; -class TermScorerFixture : public LuceneTestFixture +class TermScorerTest : public LuceneTestFixture { public: - TermScorerFixture() + TermScorerTest() { values = newCollection(L"all", L"dogs dogs", L"like", L"playing", L"fetch", L"all"); directory = newLucene(); @@ -66,23 +66,21 @@ class TermScorerFixture : public LuceneTestFixture indexSearcher = newLucene(directory, false); indexReader = indexSearcher->getIndexReader(); } - - virtual ~TermScorerFixture() + + virtual ~TermScorerTest() { } protected: static const String FIELD; - + RAMDirectoryPtr directory; Collection values; IndexSearcherPtr indexSearcher; IndexReaderPtr indexReader; }; -const String TermScorerFixture::FIELD = L"field"; - -BOOST_FIXTURE_TEST_SUITE(TermScorerTest, TermScorerFixture) +const String TermScorerTest::FIELD = L"field"; namespace TestTermScorer { @@ -94,36 +92,36 @@ namespace TestTermScorer this->docs = docs; this->base = 0; } - + virtual ~TestCollector() { } - + protected: int32_t base; ScorerPtr scorer; Collection docs; - + public: virtual void setScorer(ScorerPtr scorer) { - this->scorer = scorer; + this->scorer = scorer; } - + virtual void collect(int32_t doc) { double score = scorer->score(); doc = doc + base; docs.add(newLucene(doc, score)); - BOOST_CHECK(score > 0); - BOOST_CHECK(doc == 0 || doc == 5); + EXPECT_TRUE(score > 0); + EXPECT_TRUE(doc == 0 || doc == 5); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return true; @@ -131,7 +129,7 @@ namespace TestTermScorer }; } -BOOST_AUTO_TEST_CASE(testTermScorer) +TEST_F(TermScorerTest, testTermScorer) { TermPtr allTerm = newLucene(FIELD, L"all"); TermQueryPtr termQuery = newLucene(allTerm); @@ -139,18 +137,18 @@ BOOST_AUTO_TEST_CASE(testTermScorer) WeightPtr weight = termQuery->weight(indexSearcher); TermScorerPtr ts = newLucene(weight, indexReader->termDocs(allTerm), indexSearcher->getSimilarity(), indexReader->norms(FIELD)); - + // we have 2 documents with the term all in them, one document for all the other values Collection docs = Collection::newInstance(); ts->score(newLucene(docs)); - - BOOST_CHECK_EQUAL(docs.size(), 2); - BOOST_CHECK_EQUAL(docs[0]->score, docs[1]->score); - BOOST_CHECK_CLOSE_FRACTION(docs[0]->score, 1.6931472, 0.000001); + + EXPECT_EQ(docs.size(), 2); + EXPECT_EQ(docs[0]->score, docs[1]->score); + EXPECT_NEAR(docs[0]->score, 1.6931472, 0.000001); } -BOOST_AUTO_TEST_CASE(testNext) +TEST_F(TermScorerTest, testNext) { TermPtr allTerm = newLucene(FIELD, L"all"); TermQueryPtr termQuery = newLucene(allTerm); @@ -158,14 +156,14 @@ BOOST_AUTO_TEST_CASE(testNext) WeightPtr weight = termQuery->weight(indexSearcher); TermScorerPtr ts = newLucene(weight, indexReader->termDocs(allTerm), indexSearcher->getSimilarity(), indexReader->norms(FIELD)); - BOOST_CHECK_NE(ts->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_CLOSE_FRACTION(ts->score(), 1.6931472, 0.000001); - BOOST_CHECK_NE(ts->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_CLOSE_FRACTION(ts->score(), 1.6931472, 0.000001); - BOOST_CHECK_EQUAL(ts->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_NE(ts->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_NEAR(ts->score(), 1.6931472, 0.000001); + EXPECT_NE(ts->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_NEAR(ts->score(), 1.6931472, 0.000001); + EXPECT_EQ(ts->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); } -BOOST_AUTO_TEST_CASE(testSkipTo) +TEST_F(TermScorerTest, testSkipTo) { TermPtr allTerm = newLucene(FIELD, L"all"); TermQueryPtr termQuery = newLucene(allTerm); @@ -173,8 +171,6 @@ BOOST_AUTO_TEST_CASE(testSkipTo) WeightPtr weight = termQuery->weight(indexSearcher); TermScorerPtr ts = newLucene(weight, indexReader->termDocs(allTerm), indexSearcher->getSimilarity(), indexReader->norms(FIELD)); - BOOST_CHECK_NE(ts->advance(3), DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_EQUAL(ts->docID(), 5); + EXPECT_NE(ts->advance(3), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(ts->docID(), 5); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/TermVectorsTest.cpp b/src/test/search/TermVectorsTest.cpp index bcffc050..d0fe9645 100644 --- a/src/test/search/TermVectorsTest.cpp +++ b/src/test/search/TermVectorsTest.cpp @@ -31,10 +31,10 @@ using namespace Lucene; -class TermVectorsFixture : public LuceneTestFixture +class TermVectorsTest : public LuceneTestFixture { public: - TermVectorsFixture() + TermVectorsTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -58,8 +58,8 @@ class TermVectorsFixture : public LuceneTestFixture writer->close(); searcher = newLucene(directory, true); } - - virtual ~TermVectorsFixture() + + virtual ~TermVectorsTest() { } @@ -75,22 +75,20 @@ class TermVectorsFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(TermVectorsTest, TermVectorsFixture) - -BOOST_AUTO_TEST_CASE(testTermVectors) +TEST_F(TermVectorsTest, testTermVectors) { QueryPtr query = newLucene(newLucene(L"field", L"seventy")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(100, hits.size()); + EXPECT_EQ(100, hits.size()); for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); - BOOST_CHECK(vector); - BOOST_CHECK_EQUAL(vector.size(), 1); + EXPECT_TRUE(vector); + EXPECT_EQ(vector.size(), 1); } } -BOOST_AUTO_TEST_CASE(testTermVectorsFieldOrder) +TEST_F(TermVectorsTest, testTermVectorsFieldOrder) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -103,98 +101,98 @@ BOOST_AUTO_TEST_CASE(testTermVectorsFieldOrder) writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); Collection v = reader->getTermFreqVectors(0); - BOOST_CHECK_EQUAL(4, v.size()); + EXPECT_EQ(4, v.size()); Collection expectedFields = newCollection(L"a", L"b", L"c", L"x"); Collection expectedPositions = newCollection(1, 2, 0); for (int32_t i = 0; i < v.size(); ++i) { TermPositionVectorPtr posVec = boost::dynamic_pointer_cast(v[i]); - BOOST_CHECK_EQUAL(expectedFields[i], posVec->getField()); + EXPECT_EQ(expectedFields[i], posVec->getField()); Collection terms = posVec->getTerms(); - BOOST_CHECK_EQUAL(3, terms.size()); - BOOST_CHECK_EQUAL(L"content", terms[0]); - BOOST_CHECK_EQUAL(L"here", terms[1]); - BOOST_CHECK_EQUAL(L"some", terms[2]); + EXPECT_EQ(3, terms.size()); + EXPECT_EQ(L"content", terms[0]); + EXPECT_EQ(L"here", terms[1]); + EXPECT_EQ(L"some", terms[2]); for (int32_t j = 0; j < 3; ++j) { Collection positions = posVec->getTermPositions(j); - BOOST_CHECK_EQUAL(1, positions.size()); - BOOST_CHECK_EQUAL(expectedPositions[j], positions[0]); + EXPECT_EQ(1, positions.size()); + EXPECT_EQ(expectedPositions[j], positions[0]); } } } -BOOST_AUTO_TEST_CASE(testTermPositionVectors) +TEST_F(TermVectorsTest, testTermPositionVectors) { QueryPtr query = newLucene(newLucene(L"field", L"zero")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - + EXPECT_EQ(1, hits.size()); + for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); - BOOST_CHECK(vector); - BOOST_CHECK_EQUAL(vector.size(), 1); + EXPECT_TRUE(vector); + EXPECT_EQ(vector.size(), 1); bool shouldBePosVector = (hits[i]->doc % 2 == 0); - BOOST_CHECK(!shouldBePosVector || (shouldBePosVector && boost::dynamic_pointer_cast(vector[0]))); + EXPECT_TRUE(!shouldBePosVector || (shouldBePosVector && boost::dynamic_pointer_cast(vector[0]))); bool shouldBeOffVector = (hits[i]->doc % 3 == 0); - BOOST_CHECK(!shouldBeOffVector || (shouldBeOffVector && boost::dynamic_pointer_cast(vector[0]))); - + EXPECT_TRUE(!shouldBeOffVector || (shouldBeOffVector && boost::dynamic_pointer_cast(vector[0]))); + if (shouldBePosVector || shouldBeOffVector) { TermPositionVectorPtr posVec = boost::dynamic_pointer_cast(vector[0]); Collection terms = posVec->getTerms(); - BOOST_CHECK(terms && !terms.empty()); - + EXPECT_TRUE(terms && !terms.empty()); + for (int32_t j = 0; j < terms.size(); ++j) { Collection positions = posVec->getTermPositions(j); Collection offsets = posVec->getOffsets(j); - + if (shouldBePosVector) { - BOOST_CHECK(positions); - BOOST_CHECK(!positions.empty()); + EXPECT_TRUE(positions); + EXPECT_TRUE(!positions.empty()); } else - BOOST_CHECK(!positions); - + EXPECT_TRUE(!positions); + if (shouldBeOffVector) { - BOOST_CHECK(offsets); - BOOST_CHECK(!offsets.empty()); + EXPECT_TRUE(offsets); + EXPECT_TRUE(!offsets.empty()); } else - BOOST_CHECK(!offsets); + EXPECT_TRUE(!offsets); } } else { - BOOST_CHECK(!boost::dynamic_pointer_cast(vector[0])); + EXPECT_TRUE(!boost::dynamic_pointer_cast(vector[0])); TermFreqVectorPtr freqVec = boost::dynamic_pointer_cast(vector[0]); Collection terms = freqVec->getTerms(); - BOOST_CHECK(terms && !terms.empty()); + EXPECT_TRUE(terms && !terms.empty()); } } } -BOOST_AUTO_TEST_CASE(testTermOffsetVectors) +TEST_F(TermVectorsTest, testTermOffsetVectors) { QueryPtr query = newLucene(newLucene(L"field", L"fifty")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(100, hits.size()); - + EXPECT_EQ(100, hits.size()); + for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); - BOOST_CHECK(vector); - BOOST_CHECK_EQUAL(vector.size(), 1); + EXPECT_TRUE(vector); + EXPECT_EQ(vector.size(), 1); } } -BOOST_AUTO_TEST_CASE(testKnownSetOfDocuments) +TEST_F(TermVectorsTest, testKnownSetOfDocuments) { String test1 = L"eating chocolate in a computer lab"; // 6 terms String test2 = L"computer in a computer lab"; // 5 terms @@ -223,15 +221,15 @@ BOOST_AUTO_TEST_CASE(testKnownSetOfDocuments) setupDoc(testDoc4, test4); DirectoryPtr dir = newLucene(); - + IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - BOOST_CHECK(writer); + EXPECT_TRUE(writer); writer->addDocument(testDoc1); writer->addDocument(testDoc2); writer->addDocument(testDoc3); writer->addDocument(testDoc4); writer->close(); - + IndexSearcherPtr knownSearcher = newLucene(dir, true); TermEnumPtr termEnum = knownSearcher->reader->terms(); TermDocsPtr termDocs = knownSearcher->reader->termDocs(); @@ -250,68 +248,68 @@ BOOST_AUTO_TEST_CASE(testKnownSetOfDocuments) double idf = sim->idf(knownSearcher->docFreq(term), knownSearcher->maxDoc()); // This is fine since we don't have stop words double lNorm = sim->lengthNorm(L"field", vector->getTerms().size()); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); Collection vTerms = vector->getTerms(); Collection freqs = vector->getTermFrequencies(); for (int32_t i = 0; i < vTerms.size(); ++i) { if (term->text() == vTerms[i]) - BOOST_CHECK_EQUAL(freqs[i], freq); + EXPECT_EQ(freqs[i], freq); } } } QueryPtr query = newLucene(newLucene(L"field", L"chocolate")); Collection hits = knownSearcher->search(query, FilterPtr(), 1000)->scoreDocs; // doc 3 should be the first hit because it is the shortest match - BOOST_CHECK_EQUAL(hits.size(), 3); + EXPECT_EQ(hits.size(), 3); double score = hits[0]->score; - BOOST_CHECK_EQUAL(hits[0]->doc, 2); - BOOST_CHECK_EQUAL(hits[1]->doc, 3); - BOOST_CHECK_EQUAL(hits[2]->doc, 0); + EXPECT_EQ(hits[0]->doc, 2); + EXPECT_EQ(hits[1]->doc, 3); + EXPECT_EQ(hits[2]->doc, 0); TermFreqVectorPtr vector = knownSearcher->reader->getTermFreqVector(hits[1]->doc, L"field"); - BOOST_CHECK(vector); + EXPECT_TRUE(vector); Collection terms = vector->getTerms(); Collection freqs = vector->getTermFrequencies(); - BOOST_CHECK(terms && terms.size() == 10); + EXPECT_TRUE(terms && terms.size() == 10); for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; int32_t freq = freqs[i]; - BOOST_CHECK(test4.find(term) != String::npos); - BOOST_CHECK(test4Map.contains(term)); - BOOST_CHECK_EQUAL(test4Map[term], freq); + EXPECT_TRUE(test4.find(term) != String::npos); + EXPECT_TRUE(test4Map.contains(term)); + EXPECT_EQ(test4Map[term], freq); } SortedTermVectorMapperPtr mapper = newLucene(TermVectorEntryFreqSortedComparator::compare); knownSearcher->reader->getTermFreqVector(hits[1]->doc, mapper); Collection vectorEntrySet = mapper->getTermVectorEntrySet(); - BOOST_CHECK_EQUAL(vectorEntrySet.size(), 10); + EXPECT_EQ(vectorEntrySet.size(), 10); TermVectorEntryPtr last; for (Collection::iterator tve = vectorEntrySet.begin(); tve != vectorEntrySet.end(); ++tve) { if (*tve && last) { - BOOST_CHECK(last->getFrequency() >= (*tve)->getFrequency()); + EXPECT_TRUE(last->getFrequency() >= (*tve)->getFrequency()); int32_t expectedFreq = test4Map.get((*tve)->getTerm()); // we expect double the expectedFreq, since there are two fields with the exact same text and we are collapsing all fields - BOOST_CHECK_EQUAL((*tve)->getFrequency(), 2 * expectedFreq); + EXPECT_EQ((*tve)->getFrequency(), 2 * expectedFreq); } last = *tve; } FieldSortedTermVectorMapperPtr fieldMapper = newLucene(TermVectorEntryFreqSortedComparator::compare); knownSearcher->reader->getTermFreqVector(hits[1]->doc, fieldMapper); MapStringCollectionTermVectorEntry map = fieldMapper->getFieldToTerms(); - BOOST_CHECK_EQUAL(map.size(), 2); + EXPECT_EQ(map.size(), 2); vectorEntrySet = map.get(L"field"); - BOOST_CHECK(vectorEntrySet); - BOOST_CHECK_EQUAL(vectorEntrySet.size(), 10); + EXPECT_TRUE(vectorEntrySet); + EXPECT_EQ(vectorEntrySet.size(), 10); knownSearcher->close(); } /// Test only a few docs having vectors -BOOST_AUTO_TEST_CASE(testRareVectors) +TEST_F(TermVectorsTest, testRareVectors) { IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - + for (int32_t i = 0; i < 100; ++i) { DocumentPtr doc = newLucene(); @@ -325,23 +323,23 @@ BOOST_AUTO_TEST_CASE(testRareVectors) doc->add(newLucene(L"field", intToEnglish(100 + i), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); writer->addDocument(doc); } - + writer->close(); searcher = newLucene(directory, true); QueryPtr query = newLucene(newLucene(L"field", L"hundred")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(10, hits.size()); + EXPECT_EQ(10, hits.size()); for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); - BOOST_CHECK(vector); - BOOST_CHECK_EQUAL(vector.size(), 1); + EXPECT_TRUE(vector); + EXPECT_EQ(vector.size(), 1); } } /// In a single doc, for the same field, mix the term vectors up -BOOST_AUTO_TEST_CASE(testMixedVectrosVectors) +TEST_F(TermVectorsTest, testMixedVectrosVectors) { IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -352,34 +350,32 @@ BOOST_AUTO_TEST_CASE(testMixedVectrosVectors) doc->add(newLucene(L"field", L"one", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); writer->addDocument(doc); writer->close(); - + searcher = newLucene(directory, true); QueryPtr query = newLucene(newLucene(L"field", L"one")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); + EXPECT_EQ(1, hits.size()); Collection vector = searcher->reader->getTermFreqVectors(hits[0]->doc); - BOOST_CHECK(vector); - BOOST_CHECK_EQUAL(vector.size(), 1); + EXPECT_TRUE(vector); + EXPECT_EQ(vector.size(), 1); TermPositionVectorPtr tfv = boost::dynamic_pointer_cast(vector[0]); - BOOST_CHECK_EQUAL(tfv->getField(), L"field"); + EXPECT_EQ(tfv->getField(), L"field"); Collection terms = tfv->getTerms(); - BOOST_CHECK_EQUAL(1, terms.size()); - BOOST_CHECK_EQUAL(terms[0], L"one"); - BOOST_CHECK_EQUAL(5, tfv->getTermFrequencies()[0]); + EXPECT_EQ(1, terms.size()); + EXPECT_EQ(terms[0], L"one"); + EXPECT_EQ(5, tfv->getTermFrequencies()[0]); Collection positions = tfv->getTermPositions(0); - BOOST_CHECK_EQUAL(5, positions.size()); + EXPECT_EQ(5, positions.size()); for (int32_t i = 0; i < 5; ++i) - BOOST_CHECK_EQUAL(i, positions[i]); + EXPECT_EQ(i, positions[i]); Collection offsets = tfv->getOffsets(0); - BOOST_CHECK_EQUAL(5, offsets.size()); + EXPECT_EQ(5, offsets.size()); for (int32_t i = 0; i < 5; ++i) { - BOOST_CHECK_EQUAL(4 * i, offsets[i]->getStartOffset()); - BOOST_CHECK_EQUAL(4 * i + 3, offsets[i]->getEndOffset()); + EXPECT_EQ(4 * i, offsets[i]->getStartOffset()); + EXPECT_EQ(4 * i + 3, offsets[i]->getEndOffset()); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/ThreadSafeTest.cpp b/src/test/search/ThreadSafeTest.cpp index 628cf48d..15f9930e 100644 --- a/src/test/search/ThreadSafeTest.cpp +++ b/src/test/search/ThreadSafeTest.cpp @@ -26,14 +26,14 @@ class TestFieldSelector : public FieldSelector { this->rand = rand; } - + virtual ~TestFieldSelector() { } protected: RandomPtr rand; - + public: virtual FieldSelectorResult accept(const String& fieldName) { @@ -58,7 +58,7 @@ class TestThread : public LuceneThread this->rand = rand; this->reader = reader; } - + virtual ~TestThread() { } @@ -80,7 +80,7 @@ class TestThread : public LuceneThread } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } @@ -91,26 +91,26 @@ class TestThread : public LuceneThread for (int32_t i = 0; i < fields.size(); ++i) validateField(fields[i]); } - + void validateField(FieldablePtr f) { String val = f->stringValue(); if (!boost::starts_with(val, L"^") || !boost::ends_with(val, L"$")) - BOOST_FAIL("Invalid field"); + FAIL() << "Invalid field"; } }; -class ThreadSafeFixture : public LuceneTestFixture +class ThreadSafeTest : public LuceneTestFixture { public: - ThreadSafeFixture() + ThreadSafeTest() { r = newLucene(17); dir = newLucene(); words = StringUtils::split(L"now is the time for all good men to come to the aid of their country", L" "); } - - virtual ~ThreadSafeFixture() + + virtual ~ThreadSafeTest() { } @@ -143,7 +143,7 @@ class ThreadSafeFixture : public LuceneTestFixture } writer->close(); } - + void doTest(int32_t iter, int32_t numThreads) { Collection threads = Collection::newInstance(numThreads); @@ -157,13 +157,11 @@ class ThreadSafeFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(ThreadSafeTest, ThreadSafeFixture) - -BOOST_AUTO_TEST_CASE(testLazyLoadThreadSafety) +TEST_F(ThreadSafeTest, testLazyLoadThreadSafety) { // test with field sizes bigger than the buffer of an index input buildDir(dir, 15, 5, 2000); - + // do many small tests so the thread locals go away in between for (int32_t i = 0; i < 100; ++i) { @@ -171,5 +169,3 @@ BOOST_AUTO_TEST_CASE(testLazyLoadThreadSafety) doTest(10, 100); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/TimeLimitingCollectorTest.cpp b/src/test/search/TimeLimitingCollectorTest.cpp index 259b968b..d3dac7e5 100644 --- a/src/test/search/TimeLimitingCollectorTest.cpp +++ b/src/test/search/TimeLimitingCollectorTest.cpp @@ -33,7 +33,7 @@ class MyHitCollector : public Collector lastDocCollected = -1; docBase = 0; } - + virtual ~MyHitCollector() { } @@ -50,51 +50,51 @@ class MyHitCollector : public Collector { slowdown = milliseconds; } - + int32_t hitCount() { return bits->cardinality(); } - + int32_t getLastDocCollected() { return lastDocCollected; } - + virtual void setScorer(ScorerPtr scorer) { // scorer is not needed } - + virtual void collect(int32_t doc) { int32_t docId = doc + docBase; if (slowdown > 0) LuceneThread::threadSleep(slowdown); if (docId < 0) - BOOST_FAIL("Invalid doc"); + FAIL() << "Invalid doc"; bits->set(docId); lastDocCollected = docId; } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { this->docBase = docBase; } - + virtual bool acceptsDocsOutOfOrder() { return false; } }; -class TimeLimitingCollectorFixture; +class TimeLimitingCollectorTest; class TimeLimitingThread : public LuceneThread { public: - TimeLimitingThread(bool withTimeout, TimeLimitingCollectorFixture* fixture); - + TimeLimitingThread(bool withTimeout, TimeLimitingCollectorTest* fixture); + virtual ~TimeLimitingThread() { } @@ -103,18 +103,18 @@ class TimeLimitingThread : public LuceneThread protected: bool withTimeout; - TimeLimitingCollectorFixture* fixture; + TimeLimitingCollectorTest* fixture; public: virtual void run(); }; -/// Tests the {@link TimeLimitingCollector}. +/// Tests the {@link TimeLimitingCollector}. /// This test checks (1) search correctness (regardless of timeout), (2) expected timeout behaviour, and (3) a sanity test with multiple searching threads. -class TimeLimitingCollectorFixture : public LuceneTestFixture +class TimeLimitingCollectorTest : public LuceneTestFixture { public: - TimeLimitingCollectorFixture() + TimeLimitingCollectorTest() { Collection docText = newCollection( L"docThatNeverMatchesSoWeCanRequireLastDocCollectedToBeGreaterThanZero", @@ -126,10 +126,10 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture L"blueberry strudel", L"blueberry pizza" ); - + DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - + for (int32_t i = 0; i < N_DOCS; ++i) add(docText[i % docText.size()], writer); writer->close(); @@ -145,8 +145,8 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture // warm the searcher searcher->search(query, FilterPtr(), 1000); } - - virtual ~TimeLimitingCollectorFixture() + + virtual ~TimeLimitingCollectorTest() { searcher->close(); TimeLimitingCollector::setResolution(TimeLimitingCollector::DEFAULT_RESOLUTION); @@ -157,16 +157,16 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture static const int32_t SLOW_DOWN; static const int64_t TIME_ALLOWED; // so searches can find about 17 docs. - // max time allowed is relaxed for multi-threading tests. - // the multi-thread case fails when setting this to 1 (no slack) and launching many threads (>2000). + // max time allowed is relaxed for multi-threading tests. + // the multi-thread case fails when setting this to 1 (no slack) and launching many threads (>2000). // but this is not a real failure, just noise. - static const int32_t MULTI_THREAD_SLACK; + static const int32_t MULTI_THREAD_SLACK; static const int32_t N_DOCS; static const int32_t N_THREADS; static const String FIELD_NAME; - + SearcherPtr searcher; QueryPtr query; @@ -177,12 +177,12 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture doc->add(newLucene(FIELD_NAME, value, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + void doTestSearch() { int32_t totalResults = 0; int32_t totalTLCResults = 0; - + MyHitCollectorPtr myHc = newLucene(); search(myHc); totalResults = myHc->hitCount(); @@ -192,11 +192,11 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture CollectorPtr tlCollector = createTimedCollector(myHc, oneHour, false); search(tlCollector); totalTLCResults = myHc->hitCount(); - + if (totalResults != totalTLCResults) - BOOST_CHECK_EQUAL(totalResults, totalTLCResults); + EXPECT_EQ(totalResults, totalTLCResults); } - + void doTestTimeout(bool multiThreaded, bool greedy) { MyHitCollectorPtr myHc = newLucene(); @@ -204,7 +204,7 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture CollectorPtr tlCollector = createTimedCollector(myHc, TIME_ALLOWED, greedy); TimeExceededException timoutException; - + // search try { @@ -216,62 +216,62 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } - + // must get exception if (timoutException.isNull()) - BOOST_CHECK(!timoutException.isNull()); - + EXPECT_TRUE(!timoutException.isNull()); + String message = timoutException.getError(); String::size_type last = message.find_last_of(L":"); if (last == String::npos) - BOOST_CHECK_NE(last, String::npos); - + EXPECT_NE(last, String::npos); + // greediness affect last doc collected int32_t exceptionDoc = StringUtils::toInt(message.substr(last + 1)); - int32_t lastCollected = myHc->getLastDocCollected(); + int32_t lastCollected = myHc->getLastDocCollected(); if (exceptionDoc <= 0) - BOOST_CHECK(exceptionDoc > 0); + EXPECT_TRUE(exceptionDoc > 0); if (greedy) { if (exceptionDoc != lastCollected) - BOOST_CHECK_EQUAL(exceptionDoc, lastCollected); + EXPECT_EQ(exceptionDoc, lastCollected); if (myHc->hitCount() <= 0) - BOOST_CHECK(myHc->hitCount() > 0); + EXPECT_TRUE(myHc->hitCount() > 0); } else if (exceptionDoc <= lastCollected) - BOOST_CHECK(exceptionDoc > lastCollected); + EXPECT_TRUE(exceptionDoc > lastCollected); String::size_type allowed = message.find_first_of(L":"); if (allowed == String::npos) - BOOST_CHECK_NE(allowed, String::npos); + EXPECT_NE(allowed, String::npos); int32_t timeAllowed = StringUtils::toInt(message.substr(allowed + 1)); - + String::size_type elapsed = message.find_first_of(L":", allowed + 1); if (elapsed == String::npos) - BOOST_CHECK_NE(elapsed, String::npos); + EXPECT_NE(elapsed, String::npos); int32_t timeElapsed = StringUtils::toInt(message.substr(elapsed + 1)); - + // verify that elapsed time at exception is within valid limits if (timeAllowed != TIME_ALLOWED) - BOOST_CHECK_EQUAL(timeAllowed, TIME_ALLOWED); + EXPECT_EQ(timeAllowed, TIME_ALLOWED); // a) Not too early if (timeElapsed <= TIME_ALLOWED - TimeLimitingCollector::getResolution()) - BOOST_CHECK(timeElapsed > TIME_ALLOWED - TimeLimitingCollector::getResolution()); + EXPECT_TRUE(timeElapsed > TIME_ALLOWED - TimeLimitingCollector::getResolution()); // b) Not too late. // This part is problematic in a busy test system, so we just print a warning. // We already verified that a timeout occurred, we just can't be picky about how long it took. if (timeElapsed > maxTime(multiThreaded)) { - BOOST_TEST_MESSAGE("Informative: timeout exceeded (no action required: most probably just " << - "because the test machine is slower than usual): " << - "lastDoc = " << exceptionDoc << - ", && allowed = " << timeAllowed << - ", && elapsed = " << timeElapsed << " >= " << StringUtils::toUTF8(maxTimeStr(multiThreaded))); + // std::cout << "Informative: timeout exceeded (no action required: most probably just " << + // "because the test machine is slower than usual): " << + // "lastDoc = " << exceptionDoc << + // ", && allowed = " << timeAllowed << + // ", && elapsed = " << timeElapsed << " >= " << StringUtils::toUTF8(maxTimeStr(multiThreaded))); } } - + void doTestMultiThreads(bool withTimeout) { Collection threads = Collection::newInstance(N_THREADS); @@ -283,7 +283,7 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture for (int32_t i = 0; i < threads.size(); ++i) threads[i]->join(); } - + int64_t maxTime(bool multiThreaded) { int64_t res = 2 * TimeLimitingCollector::getResolution() + TIME_ALLOWED + SLOW_DOWN; // some slack for less noise in this test @@ -291,7 +291,7 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture res *= (int64_t)MULTI_THREAD_SLACK; // larger slack return res; } - + String maxTimeStr(bool multiThreaded) { StringStream buf; @@ -300,26 +300,26 @@ class TimeLimitingCollectorFixture : public LuceneTestFixture buf << L" * " << MULTI_THREAD_SLACK; return StringUtils::toString(maxTime(multiThreaded)) + L" = " + buf.str(); } - + CollectorPtr createTimedCollector(MyHitCollectorPtr hc, int64_t timeAllowed, bool greedy) { TimeLimitingCollectorPtr res = newLucene(hc, timeAllowed); res->setGreedy(greedy); // set to true to make sure at least one doc is collected. return res; } - + void search(CollectorPtr collector) { searcher->search(query, collector); } }; -TimeLimitingThread::TimeLimitingThread(bool withTimeout, TimeLimitingCollectorFixture* fixture) +TimeLimitingThread::TimeLimitingThread(bool withTimeout, TimeLimitingCollectorTest* fixture) { this->withTimeout = withTimeout; this->fixture = fixture; } - + void TimeLimitingThread::run() { try @@ -331,73 +331,69 @@ void TimeLimitingThread::run() } catch (LuceneException& e) { - BOOST_FAIL("Unexpected exception: " << e.getError()); + FAIL() << "Unexpected exception: " << e.getError(); } } -const int32_t TimeLimitingCollectorFixture::SLOW_DOWN = 47; -const int64_t TimeLimitingCollectorFixture::TIME_ALLOWED = 17 * TimeLimitingCollectorFixture::SLOW_DOWN; // so searches can find about 17 docs. +const int32_t TimeLimitingCollectorTest::SLOW_DOWN = 47; +const int64_t TimeLimitingCollectorTest::TIME_ALLOWED = 17 * TimeLimitingCollectorTest::SLOW_DOWN; // so searches can find about 17 docs. -// max time allowed is relaxed for multi-threading tests. -// the multi-thread case fails when setting this to 1 (no slack) and launching many threads (>2000). +// max time allowed is relaxed for multi-threading tests. +// the multi-thread case fails when setting this to 1 (no slack) and launching many threads (>2000). // but this is not a real failure, just noise. -const int32_t TimeLimitingCollectorFixture::MULTI_THREAD_SLACK = 7; +const int32_t TimeLimitingCollectorTest::MULTI_THREAD_SLACK = 7; -const int32_t TimeLimitingCollectorFixture::N_DOCS = 3000; -const int32_t TimeLimitingCollectorFixture::N_THREADS = 50; - -const String TimeLimitingCollectorFixture::FIELD_NAME = L"body"; +const int32_t TimeLimitingCollectorTest::N_DOCS = 3000; +const int32_t TimeLimitingCollectorTest::N_THREADS = 50; -BOOST_FIXTURE_TEST_SUITE(TimeLimitingCollectorTest, TimeLimitingCollectorFixture) +const String TimeLimitingCollectorTest::FIELD_NAME = L"body"; /// test search correctness with no timeout -BOOST_AUTO_TEST_CASE(testSearch) +TEST_F(TimeLimitingCollectorTest, testSearch) { doTestSearch(); } /// Test that timeout is obtained, and soon enough -BOOST_AUTO_TEST_CASE(testTimeoutGreedy) +TEST_F(TimeLimitingCollectorTest, testTimeoutGreedy) { doTestTimeout(false, true); } /// Test that timeout is obtained, and soon enough -BOOST_AUTO_TEST_CASE(testTimeoutNotGreedy) +TEST_F(TimeLimitingCollectorTest, testTimeoutNotGreedy) { doTestTimeout(false, false); } /// Test timeout behavior when resolution is modified. -BOOST_AUTO_TEST_CASE(testModifyResolution) +TEST_F(TimeLimitingCollectorTest, testModifyResolution) { // increase and test int64_t resolution = 20 * TimeLimitingCollector::DEFAULT_RESOLUTION; // 400 TimeLimitingCollector::setResolution(resolution); - BOOST_CHECK_EQUAL(resolution, TimeLimitingCollector::getResolution()); + EXPECT_EQ(resolution, TimeLimitingCollector::getResolution()); doTestTimeout(false, true); // decrease much and test resolution = 5; TimeLimitingCollector::setResolution(resolution); - BOOST_CHECK_EQUAL(resolution, TimeLimitingCollector::getResolution()); + EXPECT_EQ(resolution, TimeLimitingCollector::getResolution()); doTestTimeout(false, true); // return to default and test resolution = TimeLimitingCollector::DEFAULT_RESOLUTION; TimeLimitingCollector::setResolution(resolution); - BOOST_CHECK_EQUAL(resolution, TimeLimitingCollector::getResolution()); + EXPECT_EQ(resolution, TimeLimitingCollector::getResolution()); doTestTimeout(false, true); } /// Test correctness with multiple searching threads. -BOOST_AUTO_TEST_CASE(testSearchMultiThreaded) +TEST_F(TimeLimitingCollectorTest, testSearchMultiThreaded) { doTestMultiThreads(false); } /// Test correctness with multiple searching threads. -BOOST_AUTO_TEST_CASE(testTimeoutMultiThreaded) +TEST_F(TimeLimitingCollectorTest, testTimeoutMultiThreaded) { doTestMultiThreads(true); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/TopDocsCollectorTest.cpp b/src/test/search/TopDocsCollectorTest.cpp index 4b71328e..4c5988fc 100644 --- a/src/test/search/TopDocsCollectorTest.cpp +++ b/src/test/search/TopDocsCollectorTest.cpp @@ -28,7 +28,7 @@ class MyTopsDocCollector : public TopDocsCollector this->idx = 0; this->base = 0; } - + virtual ~MyTopsDocCollector() { } @@ -43,7 +43,7 @@ class MyTopsDocCollector : public TopDocsCollector { if (!results) return EMPTY_TOPDOCS(); - + double maxScore = std::numeric_limits::quiet_NaN(); if (start == 0) maxScore = results[0]->score; @@ -55,48 +55,48 @@ class MyTopsDocCollector : public TopDocsCollector } return newLucene(totalHits, results, maxScore); } - + virtual void collect(int32_t doc) { ++totalHits; pq->addOverflow(newLucene(doc + base, scores[idx++])); } - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) { base = docBase; } - + virtual void setScorer(ScorerPtr scorer) { // Don't do anything. Assign scores in random } - + virtual bool acceptsDocsOutOfOrder() { return true; } }; -class TopDocsCollectorFixture : public LuceneTestFixture +class TopDocsCollectorTest : public LuceneTestFixture { public: - TopDocsCollectorFixture() + TopDocsCollectorTest() { MAX_SCORE = 9.17561; - + // Scores array to be used by MyTopDocsCollector. If it is changed, MAX_SCORE must also change. const double _scores[] = { - 0.7767749, 1.7839992, 8.9925785, 7.9608946, 0.07948637, 2.6356435, - 7.4950366, 7.1490803, 8.108544, 4.961808, 2.2423935, 7.285586, - 4.6699767, 2.9655676, 6.953706, 5.383931, 6.9916306, 8.365894, - 7.888485, 8.723962, 3.1796896, 0.39971232, 1.3077754, 6.8489285, + 0.7767749, 1.7839992, 8.9925785, 7.9608946, 0.07948637, 2.6356435, + 7.4950366, 7.1490803, 8.108544, 4.961808, 2.2423935, 7.285586, + 4.6699767, 2.9655676, 6.953706, 5.383931, 6.9916306, 8.365894, + 7.888485, 8.723962, 3.1796896, 0.39971232, 1.3077754, 6.8489285, 9.17561, 5.060466, 7.9793315, 8.601509, 4.1858315, 0.28146625 }; scores = Collection::newInstance(_scores, _scores + SIZEOF_ARRAY(_scores)); - + dir = newLucene(); - + // populate an index with 30 documents, this should be enough for the test. // The documents have no content - the test uses MatchAllDocsQuery(). IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -104,8 +104,8 @@ class TopDocsCollectorFixture : public LuceneTestFixture writer->addDocument(newLucene()); writer->close(); } - - virtual ~TopDocsCollectorFixture() + + virtual ~TopDocsCollectorTest() { dir->close(); } @@ -127,97 +127,93 @@ class TopDocsCollectorFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(TopDocsCollectorTest, TopDocsCollectorFixture) - -BOOST_AUTO_TEST_CASE(testInvalidArguments) +TEST_F(TopDocsCollectorTest, testInvalidArguments) { int32_t numResults = 5; TopDocsCollectorPtr tdc = doSearch(numResults); // start < 0 - BOOST_CHECK_EQUAL(0, tdc->topDocs(-1)->scoreDocs.size()); + EXPECT_EQ(0, tdc->topDocs(-1)->scoreDocs.size()); // start > pq.size() - BOOST_CHECK_EQUAL(0, tdc->topDocs(numResults + 1)->scoreDocs.size()); + EXPECT_EQ(0, tdc->topDocs(numResults + 1)->scoreDocs.size()); // start == pq.size() - BOOST_CHECK_EQUAL(0, tdc->topDocs(numResults)->scoreDocs.size()); + EXPECT_EQ(0, tdc->topDocs(numResults)->scoreDocs.size()); // howMany < 0 - BOOST_CHECK_EQUAL(0, tdc->topDocs(0, -1)->scoreDocs.size()); + EXPECT_EQ(0, tdc->topDocs(0, -1)->scoreDocs.size()); // howMany == 0 - BOOST_CHECK_EQUAL(0, tdc->topDocs(0, 0)->scoreDocs.size()); + EXPECT_EQ(0, tdc->topDocs(0, 0)->scoreDocs.size()); } -BOOST_AUTO_TEST_CASE(testZeroResults) +TEST_F(TopDocsCollectorTest, testZeroResults) { TopDocsCollectorPtr tdc = newLucene(5, scores); - BOOST_CHECK_EQUAL(0, tdc->topDocs(0, 1)->scoreDocs.size()); + EXPECT_EQ(0, tdc->topDocs(0, 1)->scoreDocs.size()); } -BOOST_AUTO_TEST_CASE(testFirstResultsPage) +TEST_F(TopDocsCollectorTest, testFirstResultsPage) { TopDocsCollectorPtr tdc = doSearch(15); - BOOST_CHECK_EQUAL(10, tdc->topDocs(0, 10)->scoreDocs.size()); + EXPECT_EQ(10, tdc->topDocs(0, 10)->scoreDocs.size()); } -BOOST_AUTO_TEST_CASE(testSecondResultsPages) +TEST_F(TopDocsCollectorTest, testSecondResultsPages) { TopDocsCollectorPtr tdc = doSearch(15); - + // ask for more results than are available - BOOST_CHECK_EQUAL(5, tdc->topDocs(10, 10)->scoreDocs.size()); + EXPECT_EQ(5, tdc->topDocs(10, 10)->scoreDocs.size()); // ask for 5 results (exactly what there should be tdc = doSearch(15); - BOOST_CHECK_EQUAL(5, tdc->topDocs(10, 5)->scoreDocs.size()); + EXPECT_EQ(5, tdc->topDocs(10, 5)->scoreDocs.size()); // ask for less results than there are tdc = doSearch(15); - BOOST_CHECK_EQUAL(4, tdc->topDocs(10, 4)->scoreDocs.size()); + EXPECT_EQ(4, tdc->topDocs(10, 4)->scoreDocs.size()); } -BOOST_AUTO_TEST_CASE(testGetAllResults) +TEST_F(TopDocsCollectorTest, testGetAllResults) { TopDocsCollectorPtr tdc = doSearch(15); - BOOST_CHECK_EQUAL(15, tdc->topDocs()->scoreDocs.size()); + EXPECT_EQ(15, tdc->topDocs()->scoreDocs.size()); } -BOOST_AUTO_TEST_CASE(testGetResultsFromStart) +TEST_F(TopDocsCollectorTest, testGetResultsFromStart) { TopDocsCollectorPtr tdc = doSearch(15); // should bring all results - BOOST_CHECK_EQUAL(15, tdc->topDocs(0)->scoreDocs.size()); + EXPECT_EQ(15, tdc->topDocs(0)->scoreDocs.size()); tdc = doSearch(15); // get the last 5 only. - BOOST_CHECK_EQUAL(5, tdc->topDocs(10)->scoreDocs.size()); + EXPECT_EQ(5, tdc->topDocs(10)->scoreDocs.size()); } -BOOST_AUTO_TEST_CASE(testMaxScore) +TEST_F(TopDocsCollectorTest, testMaxScore) { // ask for all results TopDocsCollectorPtr tdc = doSearch(15); TopDocsPtr td = tdc->topDocs(); - BOOST_CHECK_EQUAL(MAX_SCORE, td->maxScore); + EXPECT_EQ(MAX_SCORE, td->maxScore); // ask for 5 last results tdc = doSearch(15); td = tdc->topDocs(10); - BOOST_CHECK_EQUAL(MAX_SCORE, td->maxScore); + EXPECT_EQ(MAX_SCORE, td->maxScore); } -/// This does not test the PQ's correctness, but whether topDocs() implementations +/// This does not test the PQ's correctness, but whether topDocs() implementations /// return the results in decreasing score order. -BOOST_AUTO_TEST_CASE(testResultsOrder) +TEST_F(TopDocsCollectorTest, testResultsOrder) { TopDocsCollectorPtr tdc = doSearch(15); Collection sd = tdc->topDocs()->scoreDocs; - BOOST_CHECK_EQUAL(MAX_SCORE, sd[0]->score); + EXPECT_EQ(MAX_SCORE, sd[0]->score); for (int32_t i = 1; i < sd.size(); ++i) - BOOST_CHECK(sd[i - 1]->score >= sd[i]->score); + EXPECT_TRUE(sd[i - 1]->score >= sd[i]->score); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/TopScoreDocCollectorTest.cpp b/src/test/search/TopScoreDocCollectorTest.cpp index 09f5df8e..ec8cf61a 100644 --- a/src/test/search/TopScoreDocCollectorTest.cpp +++ b/src/test/search/TopScoreDocCollectorTest.cpp @@ -19,9 +19,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(TopScoreDocCollectorTest, LuceneTestFixture) +typedef LuceneTestFixture TopScoreDocCollectorTest; -BOOST_AUTO_TEST_CASE(testOutOfOrderCollection) +TEST_F(TopScoreDocCollectorTest, testOutOfOrderCollection) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, AnalyzerPtr(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -29,31 +29,29 @@ BOOST_AUTO_TEST_CASE(testOutOfOrderCollection) writer->addDocument(newLucene()); writer->commit(); writer->close(); - + Collection inOrder = newCollection(false, true); Collection actualTSDCClass = newCollection(L"OutOfOrderTopScoreDocCollector", L"InOrderTopScoreDocCollector"); BooleanQueryPtr bq = newLucene(); - + // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 // which delegates to BS if there are no mandatory clauses. bq->add(newLucene(), BooleanClause::SHOULD); - + // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return the clause instead of BQ. bq->setMinimumNumberShouldMatch(1); IndexSearcherPtr searcher = newLucene(dir, true); for (int32_t i = 0; i < inOrder.size(); ++i) { TopDocsCollectorPtr tdc = TopScoreDocCollector::create(3, inOrder[i] == 1); - BOOST_CHECK_EQUAL(actualTSDCClass[i], tdc->getClassName()); + EXPECT_EQ(actualTSDCClass[i], tdc->getClassName()); searcher->search(newLucene(), tdc); Collection sd = tdc->topDocs()->scoreDocs; - BOOST_CHECK_EQUAL(3, sd.size()); + EXPECT_EQ(3, sd.size()); for (int32_t j = 0; j < sd.size(); ++j) - BOOST_CHECK_EQUAL(j, sd[j]->doc); + EXPECT_EQ(j, sd[j]->doc); } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/WildcardTest.cpp b/src/test/search/WildcardTest.cpp index 0e22db62..8d427abd 100644 --- a/src/test/search/WildcardTest.cpp +++ b/src/test/search/WildcardTest.cpp @@ -27,7 +27,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(WildcardTest, LuceneTestFixture) +typedef LuceneTestFixture WildcardTest; static RAMDirectoryPtr getIndexStore(const String& field, Collection contents) { @@ -48,34 +48,34 @@ static RAMDirectoryPtr getIndexStore(const String& field, Collection con static void checkMatches(IndexSearcherPtr searcher, QueryPtr q, int32_t expectedMatches) { Collection result = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(expectedMatches, result.size()); + EXPECT_EQ(expectedMatches, result.size()); } -BOOST_AUTO_TEST_CASE(testEquals) +TEST_F(WildcardTest, testEquals) { WildcardQueryPtr wq1 = newLucene(newLucene(L"field", L"b*a")); WildcardQueryPtr wq2 = newLucene(newLucene(L"field", L"b*a")); WildcardQueryPtr wq3 = newLucene(newLucene(L"field", L"b*a")); - + // reflexive? - BOOST_CHECK(wq1->equals(wq2)); - BOOST_CHECK(wq2->equals(wq1)); - + EXPECT_TRUE(wq1->equals(wq2)); + EXPECT_TRUE(wq2->equals(wq1)); + // transitive? - BOOST_CHECK(wq2->equals(wq3)); - BOOST_CHECK(wq1->equals(wq3)); - - BOOST_CHECK(!wq1->equals(WildcardQueryPtr())); + EXPECT_TRUE(wq2->equals(wq3)); + EXPECT_TRUE(wq1->equals(wq3)); + + EXPECT_TRUE(!wq1->equals(WildcardQueryPtr())); FuzzyQueryPtr fq = newLucene(newLucene(L"field", L"b*a")); - BOOST_CHECK(!wq1->equals(fq)); - BOOST_CHECK(!fq->equals(wq1)); + EXPECT_TRUE(!wq1->equals(fq)); + EXPECT_TRUE(!fq->equals(wq1)); } -/// Tests if a WildcardQuery that has no wildcard in the term is rewritten to a single TermQuery. -/// The boost should be preserved, and the rewrite should return a ConstantScoreQuery if the +/// Tests if a WildcardQuery that has no wildcard in the term is rewritten to a single TermQuery. +/// The boost should be preserved, and the rewrite should return a ConstantScoreQuery if the /// WildcardQuery had a ConstantScore rewriteMethod. -BOOST_AUTO_TEST_CASE(testTermWithoutWildcard) +TEST_F(WildcardTest, testTermWithoutWildcard) { RAMDirectoryPtr indexStore = getIndexStore(L"field", newCollection(L"nowildcard", L"nowildcardx")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -86,30 +86,30 @@ BOOST_AUTO_TEST_CASE(testTermWithoutWildcard) wq->setRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); wq->setBoost(0.1); QueryPtr q = searcher->rewrite(wq); - BOOST_CHECK(MiscUtils::typeOf(q)); - BOOST_CHECK_EQUAL(q->getBoost(), wq->getBoost()); + EXPECT_TRUE(MiscUtils::typeOf(q)); + EXPECT_EQ(q->getBoost(), wq->getBoost()); wq->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); wq->setBoost(0.2); q = searcher->rewrite(wq); - BOOST_CHECK(MiscUtils::typeOf(q)); - BOOST_CHECK_EQUAL(q->getBoost(), wq->getBoost()); + EXPECT_TRUE(MiscUtils::typeOf(q)); + EXPECT_EQ(q->getBoost(), wq->getBoost()); wq->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()); wq->setBoost(0.3); q = searcher->rewrite(wq); - BOOST_CHECK(MiscUtils::typeOf(q)); - BOOST_CHECK_EQUAL(q->getBoost(), wq->getBoost()); + EXPECT_TRUE(MiscUtils::typeOf(q)); + EXPECT_EQ(q->getBoost(), wq->getBoost()); wq->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); wq->setBoost(0.4); q = searcher->rewrite(wq); - BOOST_CHECK(MiscUtils::typeOf(q)); - BOOST_CHECK_EQUAL(q->getBoost(), wq->getBoost()); + EXPECT_TRUE(MiscUtils::typeOf(q)); + EXPECT_EQ(q->getBoost(), wq->getBoost()); } /// Tests if a WildcardQuery with an empty term is rewritten to an empty BooleanQuery -BOOST_AUTO_TEST_CASE(testEmptyTerm) +TEST_F(WildcardTest, testEmptyTerm) { RAMDirectoryPtr indexStore = getIndexStore(L"field", newCollection(L"nowildcard", L"nowildcardx")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -118,12 +118,12 @@ BOOST_AUTO_TEST_CASE(testEmptyTerm) wq->setRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); checkMatches(searcher, wq, 0); BooleanQueryPtr expected = newLucene(true); - BOOST_CHECK(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); + EXPECT_TRUE(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); } -/// Tests if a WildcardQuery that has only a trailing * in the term is rewritten to a +/// Tests if a WildcardQuery that has only a trailing * in the term is rewritten to a /// single PrefixQuery. The boost and rewriteMethod should be preserved. -BOOST_AUTO_TEST_CASE(testPrefixTerm) +TEST_F(WildcardTest, testPrefixTerm) { RAMDirectoryPtr indexStore = getIndexStore(L"field", newCollection(L"prefix", L"prefixx")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -136,28 +136,28 @@ BOOST_AUTO_TEST_CASE(testPrefixTerm) wq->setBoost(0.1); expected->setRewriteMethod(wq->getRewriteMethod()); expected->setBoost(wq->getBoost()); - BOOST_CHECK(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); + EXPECT_TRUE(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); wq->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); wq->setBoost(0.2); expected->setRewriteMethod(wq->getRewriteMethod()); expected->setBoost(wq->getBoost()); - BOOST_CHECK(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); + EXPECT_TRUE(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); wq->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()); wq->setBoost(0.3); expected->setRewriteMethod(wq->getRewriteMethod()); expected->setBoost(wq->getBoost()); - BOOST_CHECK(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); + EXPECT_TRUE(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); wq->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); wq->setBoost(0.4); expected->setRewriteMethod(wq->getRewriteMethod()); expected->setBoost(wq->getBoost()); - BOOST_CHECK(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); + EXPECT_TRUE(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); } -BOOST_AUTO_TEST_CASE(testAsterisk) +TEST_F(WildcardTest, testAsterisk) { RAMDirectoryPtr indexStore = getIndexStore(L"body", newCollection(L"metal", L"metals")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(testAsterisk) checkMatches(searcher, newLucene(newLucene(L"body", L"*tal*")), 2); } -BOOST_AUTO_TEST_CASE(testLotsOfAsterisks) +TEST_F(WildcardTest, testLotsOfAsterisks) { RAMDirectoryPtr indexStore = getIndexStore(L"body", newCollection(L"metal", L"metals")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(testLotsOfAsterisks) indexStore->close(); } -BOOST_AUTO_TEST_CASE(testQuestionmark) +TEST_F(WildcardTest, testQuestionmark) { RAMDirectoryPtr indexStore = getIndexStore(L"body", newCollection(L"metal", L"metals", L"mXtals", L"mXtXls")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(testQuestionmark) QueryPtr query5 = newLucene(newLucene(L"body", L"M?t?ls")); QueryPtr query6 = newLucene(newLucene(L"body", L"meta??")); - checkMatches(searcher, query1, 1); + checkMatches(searcher, query1, 1); checkMatches(searcher, query2, 1); checkMatches(searcher, query3, 0); checkMatches(searcher, query4, 3); @@ -225,37 +225,37 @@ BOOST_AUTO_TEST_CASE(testQuestionmark) checkMatches(searcher, query6, 1); // Query: 'meta??' matches 'metals' not 'metal' } -/// Test that wild card queries are parsed to the correct type and are searched correctly. -/// This test looks at both parsing and execution of wildcard queries. Although placed -/// here, it also tests prefix queries, verifying that prefix queries are not parsed into +/// Test that wild card queries are parsed to the correct type and are searched correctly. +/// This test looks at both parsing and execution of wildcard queries. Although placed +/// here, it also tests prefix queries, verifying that prefix queries are not parsed into /// wild card queries, and vice-versa. -BOOST_AUTO_TEST_CASE(testParsingAndSearching) +TEST_F(WildcardTest, testParsingAndSearching) { String field = L"content"; QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, field, newLucene()); qp->setAllowLeadingWildcard(true); Collection docs = newCollection(L"\\ abcdefg1", L"\\79 hijklmn1", L"\\\\ opqrstu1"); - + // queries that should find all docs Collection matchAll = newCollection(L"*", L"*1", L"**1", L"*?", L"*?1", L"?*1", L"**", L"***", L"\\\\*"); - + // queries that should find no docs Collection matchNone = newCollection(L"a*h", L"a?h", L"*a*h", L"?a", L"a?"); - + // queries that should be parsed to prefix queries Collection< Collection > matchOneDocPrefix = newCollection< Collection >( - newCollection(L"a*", L"ab*", L"abc*"), // these should find only doc 0 + newCollection(L"a*", L"ab*", L"abc*"), // these should find only doc 0 newCollection(L"h*", L"hi*", L"hij*", L"\\\\7*"), // these should find only doc 1 newCollection(L"o*", L"op*", L"opq*", L"\\\\\\\\*") // these should find only doc 2 ); - + // queries that should be parsed to wildcard queries Collection< Collection > matchOneDocWild = newCollection< Collection >( newCollection(L"*a*", L"*ab*", L"*abc**", L"ab*e*", L"*g?", L"*f?1", L"abc**"), // these should find only doc 0 newCollection(L"*h*", L"*hi*", L"*hij**", L"hi*k*", L"*n?", L"*m?1", L"hij**"), // these should find only doc 1 newCollection(L"*o*", L"*op*", L"*opq**", L"op*q*", L"*u?", L"*t?1", L"opq**") // these should find only doc 2 ); - + // prepare the index RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -268,25 +268,25 @@ BOOST_AUTO_TEST_CASE(testParsingAndSearching) writer->close(); IndexSearcherPtr searcher = newLucene(dir, true); - + // test queries that must find all for (int32_t i = 0; i < matchAll.size(); ++i) { String qtxt = matchAll[i]; QueryPtr q = qp->parse(qtxt); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(docs.size(), hits.size()); + EXPECT_EQ(docs.size(), hits.size()); } - + // test queries that must find none for (int32_t i = 0; i < matchNone.size(); ++i) { String qtxt = matchNone[i]; QueryPtr q = qp->parse(qtxt); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(0, hits.size()); + EXPECT_EQ(0, hits.size()); } - + // test queries that must be prefix queries and must find only one doc for (int32_t i = 0; i < matchOneDocPrefix.size(); ++i) { @@ -294,13 +294,13 @@ BOOST_AUTO_TEST_CASE(testParsingAndSearching) { String qtxt = matchOneDocPrefix[i][j]; QueryPtr q = qp->parse(qtxt); - BOOST_CHECK(MiscUtils::typeOf(q)); + EXPECT_TRUE(MiscUtils::typeOf(q)); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(i, hits[0]->doc); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(i, hits[0]->doc); } } - + // test queries that must be wildcard queries and must find only one doc for (int32_t i = 0; i < matchOneDocPrefix.size(); ++i) { @@ -308,14 +308,12 @@ BOOST_AUTO_TEST_CASE(testParsingAndSearching) { String qtxt = matchOneDocWild[i][j]; QueryPtr q = qp->parse(qtxt); - BOOST_CHECK(MiscUtils::typeOf(q)); + EXPECT_TRUE(MiscUtils::typeOf(q)); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(1, hits.size()); - BOOST_CHECK_EQUAL(i, hits[0]->doc); + EXPECT_EQ(1, hits.size()); + EXPECT_EQ(i, hits[0]->doc); } } - + searcher->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/function/CustomScoreQueryTest.cpp b/src/test/search/function/CustomScoreQueryTest.cpp index 72955a89..2ef7ab51 100644 --- a/src/test/search/function/CustomScoreQueryTest.cpp +++ b/src/test/search/function/CustomScoreQueryTest.cpp @@ -28,7 +28,7 @@ class CustomAddScoreProvider : public CustomScoreProvider CustomAddScoreProvider(IndexReaderPtr reader) : CustomScoreProvider(reader) { } - + virtual ~CustomAddScoreProvider() { } @@ -38,7 +38,7 @@ class CustomAddScoreProvider : public CustomScoreProvider { return subQueryScore + valSrcScore; } - + virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) { double valSrcScore = valSrcExpl ? valSrcExpl->getValue() : 0.0; @@ -56,7 +56,7 @@ class CustomAddQuery : public CustomScoreQuery CustomAddQuery(QueryPtr q, ValueSourceQueryPtr qValSrc) : CustomScoreQuery(q, qValSrc) { } - + virtual ~CustomAddQuery() { } @@ -80,7 +80,7 @@ class CustomMulAddScoreProvider : public CustomScoreProvider CustomMulAddScoreProvider(IndexReaderPtr reader) : CustomScoreProvider(reader) { } - + virtual ~CustomMulAddScoreProvider() { } @@ -95,7 +95,7 @@ class CustomMulAddScoreProvider : public CustomScoreProvider // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know there are two } - + virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) { if (valSrcExpls.empty()) @@ -121,7 +121,7 @@ class CustomMulAddQuery : public CustomScoreQuery CustomMulAddQuery(QueryPtr q, ValueSourceQueryPtr qValSrc1, ValueSourceQueryPtr qValSrc2) : CustomScoreQuery(q, newCollection(qValSrc1, qValSrc2)) { } - + virtual ~CustomMulAddQuery() { } @@ -146,7 +146,7 @@ class CustomExternalScoreProvider : public CustomScoreProvider { this->values = values; } - + virtual ~CustomExternalScoreProvider() { } @@ -157,7 +157,7 @@ class CustomExternalScoreProvider : public CustomScoreProvider public: virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore) { - BOOST_CHECK(doc <= reader->maxDoc()); + EXPECT_TRUE(doc <= reader->maxDoc()); return (double)values[doc]; } }; @@ -168,7 +168,7 @@ class CustomExternalQuery : public CustomScoreQuery CustomExternalQuery(QueryPtr q) : CustomScoreQuery(q) { } - + virtual ~CustomExternalQuery() { } @@ -181,19 +181,19 @@ class CustomExternalQuery : public CustomScoreQuery } }; -class CustomScoreQueryFixture : public FunctionFixture +class CustomScoreQueryTest : public FunctionFixture { public: - CustomScoreQueryFixture() : FunctionFixture(true) + CustomScoreQueryTest() : FunctionFixture(true) { } - - virtual ~CustomScoreQueryFixture() + + virtual ~CustomScoreQueryTest() { } public: - /// since custom scoring modifies the order of docs, map results by doc ids so that we can later compare/verify them + /// since custom scoring modifies the order of docs, map results by doc ids so that we can later compare/verify them MapIntDouble topDocsToMap(TopDocsPtr td) { MapIntDouble h = MapIntDouble::newInstance(); @@ -202,35 +202,35 @@ class CustomScoreQueryFixture : public FunctionFixture return h; } - void verifyResults(double boost, IndexSearcherPtr s, MapIntDouble h1, MapIntDouble h2customNeutral, MapIntDouble h3CustomMul, + void verifyResults(double boost, IndexSearcherPtr s, MapIntDouble h1, MapIntDouble h2customNeutral, MapIntDouble h3CustomMul, MapIntDouble h4CustomAdd, MapIntDouble h5CustomMulAdd, QueryPtr q1, QueryPtr q2, QueryPtr q3, QueryPtr q4, QueryPtr q5) { // verify numbers of matches - BOOST_CHECK_EQUAL(h1.size(), h2customNeutral.size()); - BOOST_CHECK_EQUAL(h1.size(), h3CustomMul.size()); - BOOST_CHECK_EQUAL(h1.size(), h4CustomAdd.size()); - BOOST_CHECK_EQUAL(h1.size(), h5CustomMulAdd.size()); - + EXPECT_EQ(h1.size(), h2customNeutral.size()); + EXPECT_EQ(h1.size(), h3CustomMul.size()); + EXPECT_EQ(h1.size(), h4CustomAdd.size()); + EXPECT_EQ(h1.size(), h5CustomMulAdd.size()); + // verify scores ratios for (MapIntDouble::iterator it = h1.begin(); it != h1.end(); ++it) { int32_t doc = it->first; double fieldScore = expectedFieldScore(s->getIndexReader()->document(doc)->get(ID_FIELD)); - BOOST_CHECK(fieldScore > 0); + EXPECT_TRUE(fieldScore > 0); double score1 = it->second; double score2 = h2customNeutral.get(doc); - BOOST_CHECK_CLOSE_FRACTION(boost * score1, score2, TEST_SCORE_TOLERANCE_DELTA); + EXPECT_NEAR(boost * score1, score2, TEST_SCORE_TOLERANCE_DELTA); double score3 = h3CustomMul.get(doc); - BOOST_CHECK_CLOSE_FRACTION(boost * fieldScore * score1, score3, TEST_SCORE_TOLERANCE_DELTA); + EXPECT_NEAR(boost * fieldScore * score1, score3, TEST_SCORE_TOLERANCE_DELTA); double score4 = h4CustomAdd.get(doc); - BOOST_CHECK_CLOSE_FRACTION(boost * (fieldScore + score1), score4, TEST_SCORE_TOLERANCE_DELTA); + EXPECT_NEAR(boost * (fieldScore + score1), score4, TEST_SCORE_TOLERANCE_DELTA); double score5 = h5CustomMulAdd.get(doc); - BOOST_CHECK_CLOSE_FRACTION(boost * fieldScore * (score1 + fieldScore), score5, TEST_SCORE_TOLERANCE_DELTA); + EXPECT_NEAR(boost * fieldScore * (score1 + fieldScore), score5, TEST_SCORE_TOLERANCE_DELTA); } } @@ -239,11 +239,11 @@ class CustomScoreQueryFixture : public FunctionFixture { IndexSearcherPtr s = newLucene(dir, true); FieldScoreQueryPtr qValSrc = newLucene(field, tp); // a query that would score by the field - QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, TEXT_FIELD, anlzr); + QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, TEXT_FIELD, anlzr); String qtxt = L"first aid text"; // regular (boolean) query. - QueryPtr q1 = qp->parse(qtxt); + QueryPtr q1 = qp->parse(qtxt); // custom query, that should score the same as q1. CustomScoreQueryPtr q2CustomNeutral = newLucene(q1); @@ -255,7 +255,7 @@ class CustomScoreQueryFixture : public FunctionFixture q3CustomMul->setBoost(boost); // custom query, that should add the scores of q1 to that of the field - CustomScoreQueryPtr q4CustomAdd = newLucene(q1,qValSrc); + CustomScoreQueryPtr q4CustomAdd = newLucene(q1,qValSrc); q4CustomAdd->setStrict(true); q4CustomAdd->setBoost(boost); @@ -264,7 +264,7 @@ class CustomScoreQueryFixture : public FunctionFixture q5CustomMulAdd->setStrict(true); q5CustomMulAdd->setBoost(boost); - // do al the searches + // do al the searches TopDocsPtr td1 = s->search(q1, FilterPtr(), 1000); TopDocsPtr td2CustomNeutral = s->search(q2CustomNeutral, FilterPtr(), 1000); TopDocsPtr td3CustomMul = s->search(q3CustomMul, FilterPtr(), 1000); @@ -278,35 +278,33 @@ class CustomScoreQueryFixture : public FunctionFixture MapIntDouble h4CustomAdd = topDocsToMap(td4CustomAdd); MapIntDouble h5CustomMulAdd = topDocsToMap(td5CustomMulAdd); - verifyResults(boost, s, h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd, + verifyResults(boost, s, h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd, q1, q2CustomNeutral, q3CustomMul, q4CustomAdd, q5CustomMulAdd); } }; -BOOST_FIXTURE_TEST_SUITE(CustomScoreQueryTest, CustomScoreQueryFixture) - -BOOST_AUTO_TEST_CASE(testCustomExternalQuery) +TEST_F(CustomScoreQueryTest, testCustomExternalQuery) { - QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, TEXT_FIELD, anlzr); + QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, TEXT_FIELD, anlzr); String qtxt = L"first aid text"; // from the doc texts in FunctionFixture. - QueryPtr q1 = qp->parse(qtxt); + QueryPtr q1 = qp->parse(qtxt); QueryPtr q = newLucene(q1); - + IndexSearcherPtr s = newLucene(dir); TopDocsPtr hits = s->search(q, 1000); - BOOST_CHECK_EQUAL(N_DOCS, hits->totalHits); + EXPECT_EQ(N_DOCS, hits->totalHits); for (int32_t i = 0; i < N_DOCS; ++i) { int32_t doc = hits->scoreDocs[i]->doc; double score = hits->scoreDocs[i]->score; - BOOST_CHECK_CLOSE_FRACTION((double)(1 + (4 * doc) % N_DOCS), score, 0.0001); + EXPECT_NEAR((double)(1 + (4 * doc) % N_DOCS), score, 0.0001); } s->close(); } /// Test that CustomScoreQuery of Type.BYTE returns the expected scores. -BOOST_AUTO_TEST_CASE(testCustomScoreByte) +TEST_F(CustomScoreQueryTest, testCustomScoreByte) { // INT field values are small enough to be parsed as byte doTestCustomScore(INT_FIELD, FieldScoreQuery::BYTE, 1.0); @@ -314,7 +312,7 @@ BOOST_AUTO_TEST_CASE(testCustomScoreByte) } /// Test that CustomScoreQuery of Type.INT returns the expected scores. -BOOST_AUTO_TEST_CASE(testCustomScoreInt) +TEST_F(CustomScoreQueryTest, testCustomScoreInt) { // INT field values are small enough to be parsed as int doTestCustomScore(INT_FIELD, FieldScoreQuery::INT, 1.0); @@ -322,7 +320,7 @@ BOOST_AUTO_TEST_CASE(testCustomScoreInt) } /// Test that CustomScoreQuery of Type.DOUBLE returns the expected scores. -BOOST_AUTO_TEST_CASE(testCustomScoreDouble) +TEST_F(CustomScoreQueryTest, testCustomScoreDouble) { // INT field can be parsed as double doTestCustomScore(INT_FIELD, FieldScoreQuery::DOUBLE, 1.0); @@ -331,5 +329,3 @@ BOOST_AUTO_TEST_CASE(testCustomScoreDouble) doTestCustomScore(DOUBLE_FIELD, FieldScoreQuery::DOUBLE, 1.0); doTestCustomScore(DOUBLE_FIELD, FieldScoreQuery::DOUBLE, 6.0); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/function/DocValuesTest.cpp b/src/test/search/function/DocValuesTest.cpp index 4e8ae04b..f5aaf3e2 100644 --- a/src/test/search/function/DocValuesTest.cpp +++ b/src/test/search/function/DocValuesTest.cpp @@ -12,7 +12,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DocValuesTest, LuceneTestFixture) +typedef LuceneTestFixture DocValuesTest; DECLARE_SHARED_PTR(TestableDocValues) @@ -23,7 +23,7 @@ class TestableDocValues : public DocValues { this->innerArray = innerArray; } - + virtual ~TestableDocValues() { } @@ -38,64 +38,62 @@ class TestableDocValues : public DocValues boost::throw_exception(IndexOutOfBoundsException()); return innerArray[doc]; } - + virtual String toString(int32_t doc) { return StringUtils::toString(doc); } }; -BOOST_AUTO_TEST_CASE(testGetMinValue) +TEST_F(DocValuesTest, testGetMinValue) { Collection innerArray = newCollection(1.0, 2.0, -1.0, 100.0); TestableDocValuesPtr docValues = newLucene(innerArray); - BOOST_CHECK_EQUAL(-1.0, docValues->getMinValue()); + EXPECT_EQ(-1.0, docValues->getMinValue()); // test with without values - NaN innerArray = Collection::newInstance(); docValues = newLucene(innerArray); - BOOST_CHECK(MiscUtils::isNaN(docValues->getMinValue())); + EXPECT_TRUE(MiscUtils::isNaN(docValues->getMinValue())); } -BOOST_AUTO_TEST_CASE(testGetMaxValue) +TEST_F(DocValuesTest, testGetMaxValue) { Collection innerArray = newCollection(1.0, 2.0, -1.0, 10.0); TestableDocValuesPtr docValues = newLucene(innerArray); - BOOST_CHECK_EQUAL(10.0, docValues->getMaxValue()); + EXPECT_EQ(10.0, docValues->getMaxValue()); innerArray = newCollection(-3.0, -1.0, -100.0); docValues = newLucene(innerArray); - BOOST_CHECK_EQUAL(-1.0, docValues->getMaxValue()); + EXPECT_EQ(-1.0, docValues->getMaxValue()); innerArray = newCollection(-3.0, -1.0, -100.0, DBL_MAX, DBL_MAX - 1); docValues = newLucene(innerArray); - BOOST_CHECK_EQUAL(DBL_MAX, docValues->getMaxValue()); + EXPECT_EQ(DBL_MAX, docValues->getMaxValue()); // test with without values - NaN innerArray = Collection::newInstance(); docValues = newLucene(innerArray); - BOOST_CHECK(MiscUtils::isNaN(docValues->getMaxValue())); + EXPECT_TRUE(MiscUtils::isNaN(docValues->getMaxValue())); } -BOOST_AUTO_TEST_CASE(testGetAverageValue) +TEST_F(DocValuesTest, testGetAverageValue) { Collection innerArray = newCollection(1.0, 1.0, 1.0, 1.0); TestableDocValuesPtr docValues = newLucene(innerArray); - BOOST_CHECK_EQUAL(1.0, docValues->getAverageValue()); + EXPECT_EQ(1.0, docValues->getAverageValue()); innerArray = newCollection(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); docValues = newLucene(innerArray); - BOOST_CHECK_EQUAL(3.5, docValues->getAverageValue()); + EXPECT_EQ(3.5, docValues->getAverageValue()); // test with negative values innerArray = newCollection(-1.0, 2.0); docValues = newLucene(innerArray); - BOOST_CHECK_EQUAL(0.5, docValues->getAverageValue()); + EXPECT_EQ(0.5, docValues->getAverageValue()); // test with without values - NaN innerArray = Collection::newInstance(); docValues = newLucene(innerArray); - BOOST_CHECK(MiscUtils::isNaN(docValues->getAverageValue())); + EXPECT_TRUE(MiscUtils::isNaN(docValues->getAverageValue())); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/function/FieldScoreQueryTest.cpp b/src/test/search/function/FieldScoreQueryTest.cpp index 5de09a02..5d10e28c 100644 --- a/src/test/search/function/FieldScoreQueryTest.cpp +++ b/src/test/search/function/FieldScoreQueryTest.cpp @@ -19,21 +19,21 @@ using namespace Lucene; -/// Tests here create an index with a few documents, each having an int value indexed -/// field and a double value indexed field. The values of these fields are later used +/// Tests here create an index with a few documents, each having an int value indexed +/// field and a double value indexed field. The values of these fields are later used /// for scoring. /// /// The rank tests use Hits to verify that docs are ordered (by score) as expected. /// -/// The exact score tests use TopDocs top to verify the exact score. -class FieldScoreQueryFixture : public FunctionFixture +/// The exact score tests use TopDocs top to verify the exact score. +class FieldScoreQueryTest : public FunctionFixture { public: - FieldScoreQueryFixture() : FunctionFixture(true) + FieldScoreQueryTest() : FunctionFixture(true) { } - - virtual ~FieldScoreQueryFixture() + + virtual ~FieldScoreQueryTest() { } @@ -43,37 +43,37 @@ class FieldScoreQueryFixture : public FunctionFixture { IndexSearcherPtr s = newLucene(dir, true); QueryPtr q = newLucene(field,tp); - + QueryUtils::check(q, s); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(N_DOCS, h.size()); + EXPECT_EQ(N_DOCS, h.size()); String prevID = L"ID" + StringUtils::toString(N_DOCS + 1); // greater than all ids of docs in this test for (int32_t i = 0; i < h.size(); ++i) { String resID = s->doc(h[i]->doc)->get(ID_FIELD); - BOOST_CHECK(resID.compare(prevID) < 0); + EXPECT_TRUE(resID.compare(prevID) < 0); prevID = resID; } } - + /// Test that FieldScoreQuery returns docs with expected score. void doTestExactScore(const String& field, FieldScoreQuery::Type tp) { IndexSearcherPtr s = newLucene(dir, true); QueryPtr q = newLucene(field, tp); TopDocsPtr td = s->search(q, FilterPtr(), 1000); - BOOST_CHECK_EQUAL(N_DOCS, td->totalHits); + EXPECT_EQ(N_DOCS, td->totalHits); Collection sd = td->scoreDocs; for (int32_t i = 0; i < sd.size(); ++i) { double score = sd[i]->score; String id = s->getIndexReader()->document(sd[i]->doc)->get(ID_FIELD); double expectedScore = expectedFieldScore(id); // "ID7" --> 7.0 - BOOST_CHECK_CLOSE_FRACTION(expectedScore, score, TEST_SCORE_TOLERANCE_DELTA); + EXPECT_NEAR(expectedScore, score, TEST_SCORE_TOLERANCE_DELTA); } } - - /// Test that values loaded for FieldScoreQuery are cached properly and consumes + + /// Test that values loaded for FieldScoreQuery are cached properly and consumes /// the proper RAM resources. void doTestCaching(const String& field, FieldScoreQuery::Type tp) { @@ -85,13 +85,13 @@ class FieldScoreQueryFixture : public FunctionFixture IndexSearcherPtr s = newLucene(dir, true); Collection innerArray = Collection::newInstance(s->getIndexReader()->getSequentialSubReaders().size()); - + bool warned = false; // print warning once. for (int32_t i = 0; i < 10; ++i) { FieldScoreQueryPtr q = newLucene(field, tp); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(N_DOCS, h.size()); + EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); for (int32_t j = 0; j < readers.size(); ++j) { @@ -101,40 +101,40 @@ class FieldScoreQueryFixture : public FunctionFixture if (i == 0) { innerArray[j] = q->valSrc->getValues(reader)->getInnerArray(); - BOOST_CHECK(VariantUtils::equalsType(innerArray[j], expectedArrayTypes.get(tp))); + EXPECT_TRUE(VariantUtils::equalsType(innerArray[j], expectedArrayTypes.get(tp))); } else - BOOST_CHECK(VariantUtils::equals(innerArray[j], q->valSrc->getValues(reader)->getInnerArray())); + EXPECT_TRUE(VariantUtils::equals(innerArray[j], q->valSrc->getValues(reader)->getInnerArray())); } catch (UnsupportedOperationException&) { if (!warned) { - BOOST_TEST_MESSAGE("WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString())); + // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } } } } - + // verify new values are reloaded (not reused) for a new reader s = newLucene(dir, true); FieldScoreQueryPtr q = newLucene(field, tp); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(N_DOCS, h.size()); + EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; try { - BOOST_CHECK(!equalCollectionValues(innerArray[j], q->valSrc->getValues(reader)->getInnerArray())); + EXPECT_TRUE(!equalCollectionValues(innerArray[j], q->valSrc->getValues(reader)->getInnerArray())); } catch (UnsupportedOperationException&) { if (!warned) { - BOOST_TEST_MESSAGE("WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString())); + // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } } @@ -142,23 +142,21 @@ class FieldScoreQueryFixture : public FunctionFixture } }; -BOOST_FIXTURE_TEST_SUITE(FieldScoreQueryTest, FieldScoreQueryFixture) - /// Test that FieldScoreQuery of Type.BYTE returns docs in expected order. -BOOST_AUTO_TEST_CASE(testRankByte) +TEST_F(FieldScoreQueryTest, testRankByte) { // INT field values are small enough to be parsed as byte doTestRank(INT_FIELD, FieldScoreQuery::BYTE); } /// Test that FieldScoreQuery of Type.INT returns docs in expected order. -BOOST_AUTO_TEST_CASE(testRankInt) +TEST_F(FieldScoreQueryTest, testRankInt) { doTestRank(INT_FIELD, FieldScoreQuery::INT); } /// Test that FieldScoreQuery of Type.DOUBLE returns docs in expected order. -BOOST_AUTO_TEST_CASE(testRankDouble) +TEST_F(FieldScoreQueryTest, testRankDouble) { // INT field can be parsed as double doTestRank(INT_FIELD, FieldScoreQuery::DOUBLE); @@ -167,21 +165,21 @@ BOOST_AUTO_TEST_CASE(testRankDouble) } /// Test that FieldScoreQuery of Type.BYTE returns the expected scores. -BOOST_AUTO_TEST_CASE(testExactScoreByte) +TEST_F(FieldScoreQueryTest, testExactScoreByte) { // INT field values are small enough to be parsed as byte doTestExactScore(INT_FIELD, FieldScoreQuery::BYTE); } /// Test that FieldScoreQuery of Type.INT returns the expected scores. -BOOST_AUTO_TEST_CASE(testExactScoreInt) +TEST_F(FieldScoreQueryTest, testExactScoreInt) { // INT field values are small enough to be parsed as byte doTestExactScore(INT_FIELD, FieldScoreQuery::INT); } /// Test that FieldScoreQuery of Type.DOUBLE returns the expected scores. -BOOST_AUTO_TEST_CASE(testExactScoreDouble) +TEST_F(FieldScoreQueryTest, testExactScoreDouble) { // INT field can be parsed as double doTestExactScore(INT_FIELD, FieldScoreQuery::DOUBLE); @@ -189,30 +187,28 @@ BOOST_AUTO_TEST_CASE(testExactScoreDouble) doTestExactScore(DOUBLE_FIELD, FieldScoreQuery::DOUBLE); } -/// Test that FieldScoreQuery of Type.BYTE caches/reuses loaded values and consumes +/// Test that FieldScoreQuery of Type.BYTE caches/reuses loaded values and consumes /// the proper RAM resources. -BOOST_AUTO_TEST_CASE(testCachingByte) +TEST_F(FieldScoreQueryTest, testCachingByte) { // INT field values are small enough to be parsed as byte doTestCaching(INT_FIELD, FieldScoreQuery::BYTE); } -/// Test that FieldScoreQuery of Type.INT caches/reuses loaded values and consumes +/// Test that FieldScoreQuery of Type.INT caches/reuses loaded values and consumes /// the proper RAM resources. -BOOST_AUTO_TEST_CASE(testCachingInt) +TEST_F(FieldScoreQueryTest, testCachingInt) { // INT field values are small enough to be parsed as byte doTestCaching(INT_FIELD, FieldScoreQuery::INT); } -/// Test that FieldScoreQuery of Type.DOUBLE caches/reuses loaded values and consumes +/// Test that FieldScoreQuery of Type.DOUBLE caches/reuses loaded values and consumes /// the proper RAM resources. -BOOST_AUTO_TEST_CASE(testCachingDouble) +TEST_F(FieldScoreQueryTest, testCachingDouble) { // INT field values can be parsed as float doTestCaching(INT_FIELD, FieldScoreQuery::DOUBLE); // same values, but in double format doTestCaching(DOUBLE_FIELD, FieldScoreQuery::DOUBLE); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/function/OrdValuesTest.cpp b/src/test/search/function/OrdValuesTest.cpp index 1ece6a85..5b988b1c 100644 --- a/src/test/search/function/OrdValuesTest.cpp +++ b/src/test/search/function/OrdValuesTest.cpp @@ -29,14 +29,14 @@ using namespace Lucene; /// The order tests use Hits to verify that docs are ordered as expected. /// /// The exact score tests use TopDocs top to verify the exact score. -class OrdValuesFixture : public FunctionFixture +class OrdValuesTest : public FunctionFixture { public: - OrdValuesFixture() : FunctionFixture(false) + OrdValuesTest() : FunctionFixture(false) { } - - virtual ~OrdValuesFixture() + + virtual ~OrdValuesTest() { } @@ -52,21 +52,21 @@ class OrdValuesFixture : public FunctionFixture QueryPtr q = newLucene(vs); QueryUtils::check(q, s); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(N_DOCS, h.size()); - String prevID = inOrder ? + EXPECT_EQ(N_DOCS, h.size()); + String prevID = inOrder ? L"IE" : // greater than all ids of docs in this test ("ID0001", etc.) L"IC"; // smaller than all ids of docs in this test ("ID0001", etc.) for (int32_t i = 0; i < h.size(); ++i) { String resID = s->doc(h[i]->doc)->get(ID_FIELD); if (inOrder) - BOOST_CHECK(resID.compare(prevID) < 0); + EXPECT_TRUE(resID.compare(prevID) < 0); else - BOOST_CHECK(resID.compare(prevID) > 0); + EXPECT_TRUE(resID.compare(prevID) > 0); prevID = resID; } } - + void doTestExactScore(const String& field, bool inOrder) { IndexSearcherPtr s = newLucene(dir, true); @@ -77,21 +77,21 @@ class OrdValuesFixture : public FunctionFixture vs = newLucene(field); QueryPtr q = newLucene(vs); TopDocsPtr td = s->search(q, FilterPtr(),1000); - BOOST_CHECK_EQUAL(N_DOCS, td->totalHits); + EXPECT_EQ(N_DOCS, td->totalHits); Collection sd = td->scoreDocs; for (int32_t i = 0; i < sd.size(); ++i) { double score = sd[i]->score; String id = s->getIndexReader()->document(sd[i]->doc)->get(ID_FIELD); double expectedScore = N_DOCS - i; - BOOST_CHECK_CLOSE_FRACTION(expectedScore, score, TEST_SCORE_TOLERANCE_DELTA); + EXPECT_NEAR(expectedScore, score, TEST_SCORE_TOLERANCE_DELTA); String expectedId = inOrder ? - id2String(N_DOCS - i) : // in-order ==> larger values first - id2String(i + 1); // reverse ==> smaller values first - BOOST_CHECK_EQUAL(expectedId, id); + id2String(N_DOCS - i) : // in-order ==> larger values first + id2String(i + 1); // reverse ==> smaller values first + EXPECT_EQ(expectedId, id); } } - + void doTestCaching(const String& field, bool inOrder) { IndexSearcherPtr s = newLucene(dir, true); @@ -108,7 +108,7 @@ class OrdValuesFixture : public FunctionFixture Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; try { - BOOST_CHECK_EQUAL(N_DOCS, h.size()); + EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); for (int32_t j = 0; j < readers.size(); ++j) { @@ -116,22 +116,22 @@ class OrdValuesFixture : public FunctionFixture if (i == 0) innerArray = q->valSrc->getValues(reader)->getInnerArray(); else - BOOST_CHECK(equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); + EXPECT_TRUE(equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); } } catch (UnsupportedOperationException&) { if (!warned) { - BOOST_TEST_MESSAGE("WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString())); + // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } } } - + // verify that different values are loaded for a different field String field2 = INT_FIELD; - BOOST_CHECK_NE(field, field2); // otherwise this test is meaningless. + EXPECT_NE(field, field2); // otherwise this test is meaningless. ValueSourcePtr vs; if (inOrder) vs = newLucene(field2); @@ -139,25 +139,25 @@ class OrdValuesFixture : public FunctionFixture vs = newLucene(field2); ValueSourceQueryPtr q = newLucene(vs); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(N_DOCS, h.size()); + EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; try { - BOOST_CHECK(!equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); + EXPECT_TRUE(!equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); } catch (UnsupportedOperationException&) { if (!warned) { - BOOST_TEST_MESSAGE("WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString())); + // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } } } - + // verify new values are reloaded (not reused) for a new reader s = newLucene(dir, true); if (inOrder) @@ -166,20 +166,20 @@ class OrdValuesFixture : public FunctionFixture vs = newLucene(field); q = newLucene(vs); h = s->search(q, FilterPtr(), 1000)->scoreDocs; - BOOST_CHECK_EQUAL(N_DOCS, h.size()); + EXPECT_EQ(N_DOCS, h.size()); readers = s->getIndexReader()->getSequentialSubReaders(); for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; try { - BOOST_CHECK(!equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); + EXPECT_TRUE(!equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); } catch (UnsupportedOperationException&) { if (!warned) { - BOOST_TEST_MESSAGE("WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString())); + // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } } @@ -187,36 +187,32 @@ class OrdValuesFixture : public FunctionFixture } }; -BOOST_FIXTURE_TEST_SUITE(OrdValuesTest, OrdValuesFixture) - -BOOST_AUTO_TEST_CASE(testOrdFieldRank) +TEST_F(OrdValuesTest, testOrdFieldRank) { doTestRank(ID_FIELD, true); } -BOOST_AUTO_TEST_CASE(testReverseOrdFieldRank) +TEST_F(OrdValuesTest, testReverseOrdFieldRank) { doTestRank(ID_FIELD, false); } -BOOST_AUTO_TEST_CASE(testOrdFieldExactScore) +TEST_F(OrdValuesTest, testOrdFieldExactScore) { doTestExactScore(ID_FIELD, true); } -BOOST_AUTO_TEST_CASE(testReverseOrdFieldExactScore) +TEST_F(OrdValuesTest, testReverseOrdFieldExactScore) { doTestExactScore(ID_FIELD, false); } -BOOST_AUTO_TEST_CASE(testCachingOrd) +TEST_F(OrdValuesTest, testCachingOrd) { doTestCaching(ID_FIELD, true); } -BOOST_AUTO_TEST_CASE(testCachingReverseOrd) +TEST_F(OrdValuesTest, testCachingReverseOrd) { doTestCaching(ID_FIELD, false); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/payloads/PayloadNearQueryTest.cpp b/src/test/search/payloads/PayloadNearQueryTest.cpp index 4fd691b0..7af5c032 100644 --- a/src/test/search/payloads/PayloadNearQueryTest.cpp +++ b/src/test/search/payloads/PayloadNearQueryTest.cpp @@ -45,7 +45,7 @@ class BoostingNearIDFExplanation : public IDFExplanation { return 1.0; } - + virtual String explain() { return L"Inexplicable"; @@ -65,32 +65,32 @@ class BoostingNearSimilarity : public DefaultSimilarity // we know it is size 4 here, so ignore the offset/length return (double)payload[0]; } - + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - + virtual double sloppyFreq(int32_t distance) { return 1.0; } - + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - + virtual double tf(double freq) { return 1.0; } - + virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher) { return newLucene(); @@ -108,11 +108,11 @@ class PayloadNearFilter : public TokenFilter this->fieldName = fieldName; this->payAtt = addAttribute(); } - + virtual ~PayloadNearFilter() { } - + LUCENE_CLASS(PayloadNearFilter); public: @@ -147,11 +147,11 @@ class PayloadNearAnalyzer : public Analyzer this->payload2 = payload2; this->payload4 = payload4; } - + virtual ~PayloadNearAnalyzer() { } - + LUCENE_CLASS(PayloadNearAnalyzer); protected: @@ -167,17 +167,17 @@ class PayloadNearAnalyzer : public Analyzer } }; -class PayloadNearQueryFixture : public LuceneTestFixture +class PayloadNearQueryTest : public LuceneTestFixture { public: - PayloadNearQueryFixture() + PayloadNearQueryTest() { similarity = newLucene(); payload2 = ByteArray::newInstance(1); payload2[0] = 2; payload4 = ByteArray::newInstance(1); payload4[0] = 4; - + RAMDirectoryPtr directory = newLucene(); PayloadNearAnalyzerPtr analyzer = newLucene(payload2, payload4); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -196,8 +196,8 @@ class PayloadNearQueryFixture : public LuceneTestFixture searcher = newLucene(directory, true); searcher->setSimilarity(similarity); } - - virtual ~PayloadNearQueryFixture() + + virtual ~PayloadNearQueryTest() { } @@ -221,7 +221,7 @@ class PayloadNearQueryFixture : public LuceneTestFixture } return newLucene(clauses, 0, inOrder); } - + SpanNearQueryPtr spanNearQuery(const String& fieldName, const String& words) { std::wstring phraseClauses(words.c_str()); @@ -237,58 +237,56 @@ class PayloadNearQueryFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(PayloadNearQueryTest, PayloadNearQueryFixture) - -BOOST_AUTO_TEST_CASE(testSetup) +TEST_F(PayloadNearQueryTest, testSetup) { PayloadNearQueryPtr query = newPhraseQuery(L"field", L"twenty two", true); QueryUtils::check(query); // all 10 hits should have score = 3 because adjacent terms have payloads of 2, 4 and all the similarity factors are set to 1 TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits->totalHits, 10); + EXPECT_TRUE(hits); + EXPECT_EQ(hits->totalHits, 10); for (int32_t j = 0; j < hits->scoreDocs.size(); ++j) { ScoreDocPtr doc = hits->scoreDocs[j]; - BOOST_CHECK_EQUAL(doc->score, 3); + EXPECT_EQ(doc->score, 3); } for (int32_t i = 1; i < 10; ++i) { query = newPhraseQuery(L"field", intToEnglish(i) + L" hundred", true); // all should have score = 3 because adjacent terms have payloads of 2, 4 and all the similarity factors are set to 1 hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits->totalHits, 100); + EXPECT_TRUE(hits); + EXPECT_EQ(hits->totalHits, 100); for (int32_t j = 0; j < hits->scoreDocs.size(); ++j) { ScoreDocPtr doc = hits->scoreDocs[j]; - BOOST_CHECK_EQUAL(doc->score, 3); + EXPECT_EQ(doc->score, 3); } } } -BOOST_AUTO_TEST_CASE(testPayloadNear) +TEST_F(PayloadNearQueryTest, testPayloadNear) { SpanNearQueryPtr q1 = spanNearQuery(L"field2", L"twenty two"); SpanNearQueryPtr q2 = spanNearQuery(L"field2", L"twenty three"); Collection clauses = newCollection(q1, q2); - PayloadNearQueryPtr query = newLucene(clauses, 10, false); - BOOST_CHECK_EQUAL(12, searcher->search(query, FilterPtr(), 100)->totalHits); + PayloadNearQueryPtr query = newLucene(clauses, 10, false); + EXPECT_EQ(12, searcher->search(query, FilterPtr(), 100)->totalHits); } -BOOST_AUTO_TEST_CASE(testLongerSpan) +TEST_F(PayloadNearQueryTest, testLongerSpan) { SpanNearQueryPtr query = newPhraseQuery(L"field", L"nine hundred ninety nine", true); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); + EXPECT_TRUE(hits); ScoreDocPtr doc = hits->scoreDocs[0]; - BOOST_CHECK_EQUAL(hits->totalHits, 1); + EXPECT_EQ(hits->totalHits, 1); // should have score = 3 because adjacent terms have payloads of 2,4 - BOOST_CHECK_EQUAL(doc->score, 3); + EXPECT_EQ(doc->score, 3); } -BOOST_AUTO_TEST_CASE(testComplexNested) +TEST_F(PayloadNearQueryTest, testComplexNested) { // combine ordered and unordered spans with some nesting to make sure all payloads are counted SpanQueryPtr q1 = newPhraseQuery(L"field", L"nine hundred", true); @@ -301,12 +299,10 @@ BOOST_AUTO_TEST_CASE(testComplexNested) ); PayloadNearQueryPtr query = newLucene(clauses, 0, false); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); + EXPECT_TRUE(hits); // should be only 1 hit - doc 999 - BOOST_CHECK_EQUAL(hits->scoreDocs.size(), 1); + EXPECT_EQ(hits->scoreDocs.size(), 1); // the score should be 3 - the average of all the underlying payloads ScoreDocPtr doc = hits->scoreDocs[0]; - BOOST_CHECK_EQUAL(doc->score, 3); + EXPECT_EQ(doc->score, 3); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/payloads/PayloadTermQueryTest.cpp b/src/test/search/payloads/PayloadTermQueryTest.cpp index d2b1f188..d9ef33b2 100644 --- a/src/test/search/payloads/PayloadTermQueryTest.cpp +++ b/src/test/search/payloads/PayloadTermQueryTest.cpp @@ -51,32 +51,32 @@ class BoostingTermSimilarity : public DefaultSimilarity // we know it is size 4 here, so ignore the offset/length return (double)payload[0]; } - + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - + virtual double sloppyFreq(int32_t distance) { return 1.0; } - + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - + virtual double idf(int32_t docFreq, int32_t numDocs) { return 1.0; } - + virtual double tf(double freq) { return freq == 0.0 ? 0.0 : 1.0; @@ -110,11 +110,11 @@ class PayloadTermFilter : public TokenFilter this->fieldName = fieldName; this->payloadAtt = addAttribute(); } - + virtual ~PayloadTermFilter() { } - + LUCENE_CLASS(PayloadTermFilter); public: @@ -157,11 +157,11 @@ class PayloadTermAnalyzer : public Analyzer this->payloadMultiField1 = payloadMultiField1; this->payloadMultiField2 = payloadMultiField2; } - + virtual ~PayloadTermAnalyzer() { } - + LUCENE_CLASS(PayloadTermAnalyzer); protected: @@ -178,10 +178,10 @@ class PayloadTermAnalyzer : public Analyzer } }; -class PayloadTermQueryFixture : public LuceneTestFixture +class PayloadTermQueryTest : public LuceneTestFixture { public: - PayloadTermQueryFixture() + PayloadTermQueryTest() { similarity = newLucene(); payloadField = ByteArray::newInstance(1); @@ -190,7 +190,7 @@ class PayloadTermQueryFixture : public LuceneTestFixture payloadMultiField1[0] = 2; payloadMultiField2 = ByteArray::newInstance(1); payloadMultiField2[0] = 4; - + directory = newLucene(); PayloadTermAnalyzerPtr analyzer = newLucene(payloadField, payloadMultiField1, payloadMultiField2); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -210,8 +210,8 @@ class PayloadTermQueryFixture : public LuceneTestFixture searcher = newLucene(directory, true); searcher->setSimilarity(similarity); } - - virtual ~PayloadTermQueryFixture() + + virtual ~PayloadTermQueryTest() { } @@ -224,51 +224,49 @@ class PayloadTermQueryFixture : public LuceneTestFixture RAMDirectoryPtr directory; }; -BOOST_FIXTURE_TEST_SUITE(PayloadTermQueryTest, PayloadTermQueryFixture) - -BOOST_AUTO_TEST_CASE(testSetup) +TEST_F(PayloadTermQueryTest, testSetup) { PayloadTermQueryPtr query = newLucene(newLucene(L"field", L"seventy"), newLucene()); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits->totalHits, 100); + EXPECT_TRUE(hits); + EXPECT_EQ(hits->totalHits, 100); // they should all have the exact same score, because they all contain seventy once, and we set all the other similarity factors to be 1 - BOOST_CHECK_EQUAL(hits->getMaxScore(), 1); + EXPECT_EQ(hits->getMaxScore(), 1); for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) { ScoreDocPtr doc = hits->scoreDocs[i]; - BOOST_CHECK_EQUAL(doc->score, 1); + EXPECT_EQ(doc->score, 1); } CheckHits::checkExplanations(query, PayloadHelper::FIELD, searcher, true); SpansPtr spans = query->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); - BOOST_CHECK(MiscUtils::typeOf(spans)); + EXPECT_TRUE(spans); + EXPECT_TRUE(MiscUtils::typeOf(spans)); } -BOOST_AUTO_TEST_CASE(testQuery) +TEST_F(PayloadTermQueryTest, testQuery) { PayloadTermQueryPtr BoostingTermFuncTermQuery = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy"), newLucene()); QueryUtils::check(BoostingTermFuncTermQuery); SpanTermQueryPtr spanTermQuery = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy")); - BOOST_CHECK(BoostingTermFuncTermQuery->equals(spanTermQuery) == spanTermQuery->equals(BoostingTermFuncTermQuery)); + EXPECT_TRUE(BoostingTermFuncTermQuery->equals(spanTermQuery) == spanTermQuery->equals(BoostingTermFuncTermQuery)); PayloadTermQueryPtr BoostingTermFuncTermQuery2 = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy"), newLucene()); QueryUtils::checkUnequal(BoostingTermFuncTermQuery, BoostingTermFuncTermQuery2); } -BOOST_AUTO_TEST_CASE(testMultipleMatchesPerDoc) +TEST_F(PayloadTermQueryTest, testMultipleMatchesPerDoc) { PayloadTermQueryPtr query = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy"), newLucene()); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits->totalHits, 100); + EXPECT_TRUE(hits); + EXPECT_EQ(hits->totalHits, 100); // they should all have the exact same score, because they all contain seventy once, and we set all the other similarity factors to be 1 - BOOST_CHECK_EQUAL(hits->getMaxScore(), 4.0); - + EXPECT_EQ(hits->getMaxScore(), 4.0); + // there should be exactly 10 items that score a 4, all the rest should score a 2 // The 10 items are: 70 + i*100 where i in [0-9] int32_t numTens = 0; @@ -278,37 +276,37 @@ BOOST_AUTO_TEST_CASE(testMultipleMatchesPerDoc) if (doc->doc % 10 == 0) { ++numTens; - BOOST_CHECK_EQUAL(doc->score, 4.0); + EXPECT_EQ(doc->score, 4.0); } else - BOOST_CHECK_EQUAL(doc->score, 2.0); + EXPECT_EQ(doc->score, 2.0); } - BOOST_CHECK_EQUAL(numTens, 10); + EXPECT_EQ(numTens, 10); CheckHits::checkExplanations(query, L"field", searcher, true); SpansPtr spans = query->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); - BOOST_CHECK(MiscUtils::typeOf(spans)); + EXPECT_TRUE(spans); + EXPECT_TRUE(MiscUtils::typeOf(spans)); // should be two matches per document int32_t count = 0; // 100 hits times 2 matches per hit, we should have 200 in count while (spans->next()) ++count; - BOOST_CHECK_EQUAL(count, 200); + EXPECT_EQ(count, 200); } -BOOST_AUTO_TEST_CASE(testIgnoreSpanScorer) +TEST_F(PayloadTermQueryTest, testIgnoreSpanScorer) { PayloadTermQueryPtr query = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy"), newLucene(), false); IndexSearcherPtr theSearcher = newLucene(directory, true); theSearcher->setSimilarity(newLucene()); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits->totalHits, 100); + EXPECT_TRUE(hits); + EXPECT_EQ(hits->totalHits, 100); // they should all have the exact same score, because they all contain seventy once, and we set all the other similarity factors to be 1 - BOOST_CHECK_EQUAL(hits->getMaxScore(), 4.0); - + EXPECT_EQ(hits->getMaxScore(), 4.0); + // there should be exactly 10 items that score a 4, all the rest should score a 2 // The 10 items are: 70 + i*100 where i in [0-9] int32_t numTens = 0; @@ -318,33 +316,33 @@ BOOST_AUTO_TEST_CASE(testIgnoreSpanScorer) if (doc->doc % 10 == 0) { ++numTens; - BOOST_CHECK_EQUAL(doc->score, 4.0); + EXPECT_EQ(doc->score, 4.0); } else - BOOST_CHECK_EQUAL(doc->score, 2.0); + EXPECT_EQ(doc->score, 2.0); } - BOOST_CHECK_EQUAL(numTens, 10); + EXPECT_EQ(numTens, 10); CheckHits::checkExplanations(query, L"field", searcher, true); SpansPtr spans = query->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); - BOOST_CHECK(MiscUtils::typeOf(spans)); + EXPECT_TRUE(spans); + EXPECT_TRUE(MiscUtils::typeOf(spans)); // should be two matches per document int32_t count = 0; // 100 hits times 2 matches per hit, we should have 200 in count while (spans->next()) ++count; - BOOST_CHECK_EQUAL(count, 200); + EXPECT_EQ(count, 200); } -BOOST_AUTO_TEST_CASE(testNoMatch) +TEST_F(PayloadTermQueryTest, testNoMatch) { PayloadTermQueryPtr query = newLucene(newLucene(PayloadHelper::FIELD, L"junk"), newLucene()); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits->totalHits, 0); + EXPECT_TRUE(hits); + EXPECT_EQ(hits->totalHits, 0); } -BOOST_AUTO_TEST_CASE(testNoPayload) +TEST_F(PayloadTermQueryTest, testNoPayload) { PayloadTermQueryPtr q1 = newLucene(newLucene(PayloadHelper::NO_PAYLOAD_FIELD, L"zero"), newLucene()); PayloadTermQueryPtr q2 = newLucene(newLucene(PayloadHelper::NO_PAYLOAD_FIELD, L"foo"), newLucene()); @@ -354,10 +352,8 @@ BOOST_AUTO_TEST_CASE(testNoPayload) query->add(c1); query->add(c2); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); - BOOST_CHECK(hits); - BOOST_CHECK_EQUAL(hits->totalHits, 1); + EXPECT_TRUE(hits); + EXPECT_EQ(hits->totalHits, 1); Collection results = newCollection(0); CheckHits::checkHitCollector(query, PayloadHelper::NO_PAYLOAD_FIELD, searcher, results); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/BasicSpansTest.cpp b/src/test/search/spans/BasicSpansTest.cpp index 5d465ffb..ac807456 100644 --- a/src/test/search/spans/BasicSpansTest.cpp +++ b/src/test/search/spans/BasicSpansTest.cpp @@ -30,16 +30,16 @@ using namespace Lucene; /// Tests basic search capabilities. /// -/// Uses a collection of 1000 documents, each the english rendition of their document number. +/// Uses a collection of 1000 documents, each the english rendition of their document number. /// For example, the document numbered 333 has text "three hundred thirty three". /// -/// Tests are each a single query, and its hits are checked to ensure that all and only the -/// correct documents are returned, thus providing end-to-end testing of the indexing and +/// Tests are each a single query, and its hits are checked to ensure that all and only the +/// correct documents are returned, thus providing end-to-end testing of the indexing and /// search code. -class BasicSpansFixture : public LuceneTestFixture +class BasicSpansTest : public LuceneTestFixture { public: - BasicSpansFixture() + BasicSpansTest() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -53,8 +53,8 @@ class BasicSpansFixture : public LuceneTestFixture writer->close(); searcher = newLucene(directory, true); } - - virtual ~BasicSpansFixture() + + virtual ~BasicSpansTest() { } @@ -66,7 +66,7 @@ class BasicSpansFixture : public LuceneTestFixture { CheckHits::checkHits(query, L"field", searcher, results); } - + bool skipTo(SpansPtr s, int32_t target) { do @@ -79,13 +79,11 @@ class BasicSpansFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(BasicSpansTest, BasicSpansFixture) - -BOOST_AUTO_TEST_CASE(testTerm) +TEST_F(BasicSpansTest, testTerm) { QueryPtr query = newLucene(newLucene(L"field", L"seventy")); - - static const int32_t results[] = + + static const int32_t results[] = { 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, @@ -98,23 +96,23 @@ BOOST_AUTO_TEST_CASE(testTerm) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testTerm2) +TEST_F(BasicSpansTest, testTerm2) { QueryPtr query = newLucene(newLucene(L"field", L"seventish")); checkHits(query, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testPhrase) +TEST_F(BasicSpansTest, testPhrase) { PhraseQueryPtr query = newLucene(); query->add(newLucene(L"field", L"seventy")); query->add(newLucene(L"field", L"seven")); - + static const int32_t results[] = {77, 177, 277, 377, 477, 577, 677, 777, 877, 977}; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testPhrase2) +TEST_F(BasicSpansTest, testPhrase2) { PhraseQueryPtr query = newLucene(); query->add(newLucene(L"field", L"seventish")); @@ -122,12 +120,12 @@ BOOST_AUTO_TEST_CASE(testPhrase2) checkHits(query, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testBoolean) +TEST_F(BasicSpansTest, testBoolean) { BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(L"field", L"seventy")), BooleanClause::MUST); query->add(newLucene(newLucene(L"field", L"seven")), BooleanClause::MUST); - + static const int32_t results[] = { 77, 777, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775, 776, 778, 779, 877, 977 @@ -135,7 +133,7 @@ BOOST_AUTO_TEST_CASE(testBoolean) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testBoolean2) +TEST_F(BasicSpansTest, testBoolean2) { BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(L"field", L"sevento")), BooleanClause::MUST); @@ -143,24 +141,24 @@ BOOST_AUTO_TEST_CASE(testBoolean2) checkHits(query, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testSpanNearExact) +TEST_F(BasicSpansTest, testSpanNearExact) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"seventy")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"seven")); SpanNearQueryPtr query = newLucene(newCollection(term1, term2), 0, true); - + static const int32_t results[] = {77, 177, 277, 377, 477, 577, 677, 777, 877, 977}; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - - BOOST_CHECK(searcher->explain(query, 77)->getValue() > 0.0); - BOOST_CHECK(searcher->explain(query, 977)->getValue() > 0.0); + + EXPECT_TRUE(searcher->explain(query, 77)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 977)->getValue() > 0.0); QueryUtils::check(term1); QueryUtils::check(term2); QueryUtils::checkUnequal(term1, term2); } -BOOST_AUTO_TEST_CASE(testSpanNearUnordered) +TEST_F(BasicSpansTest, testSpanNearUnordered) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"nine")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"six")); @@ -170,7 +168,7 @@ BOOST_AUTO_TEST_CASE(testSpanNearUnordered) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testSpanNearOrdered) +TEST_F(BasicSpansTest, testSpanNearOrdered) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"nine")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"six")); @@ -180,28 +178,28 @@ BOOST_AUTO_TEST_CASE(testSpanNearOrdered) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testSpanNot) +TEST_F(BasicSpansTest, testSpanNot) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 4, true); - + SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"forty")); SpanNotQueryPtr query = newLucene(near1, term3); static const int32_t results[] = {801, 821, 831, 851, 861, 871, 881, 891}; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - BOOST_CHECK(searcher->explain(query, 801)->getValue() > 0.0); - BOOST_CHECK(searcher->explain(query, 891)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 801)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -BOOST_AUTO_TEST_CASE(testSpanWithMultipleNotSingle) +TEST_F(BasicSpansTest, testSpanWithMultipleNotSingle) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 4, true); - + SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"forty")); SpanOrQueryPtr or1 = newLucene(newCollection(term3)); @@ -210,11 +208,11 @@ BOOST_AUTO_TEST_CASE(testSpanWithMultipleNotSingle) static const int32_t results[] = {801, 821, 831, 851, 861, 871, 881, 891}; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - BOOST_CHECK(searcher->explain(query, 801)->getValue() > 0.0); - BOOST_CHECK(searcher->explain(query, 891)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 801)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -BOOST_AUTO_TEST_CASE(testSpanWithMultipleNotMany) +TEST_F(BasicSpansTest, testSpanWithMultipleNotMany) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); @@ -222,7 +220,7 @@ BOOST_AUTO_TEST_CASE(testSpanWithMultipleNotMany) SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"forty")); SpanTermQueryPtr term4 = newLucene(newLucene(L"field", L"sixty")); SpanTermQueryPtr term5 = newLucene(newLucene(L"field", L"eighty")); - + SpanOrQueryPtr or1 = newLucene(newCollection(term3, term4, term5)); SpanNotQueryPtr query = newLucene(near1, or1); @@ -230,11 +228,11 @@ BOOST_AUTO_TEST_CASE(testSpanWithMultipleNotMany) static const int32_t results[] = {801, 821, 831, 851, 871, 891}; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - BOOST_CHECK(searcher->explain(query, 801)->getValue() > 0.0); - BOOST_CHECK(searcher->explain(query, 891)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 801)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -BOOST_AUTO_TEST_CASE(testNpeInSpanNearWithSpanNot) +TEST_F(BasicSpansTest, testNpeInSpanNearWithSpanNot) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); @@ -242,23 +240,23 @@ BOOST_AUTO_TEST_CASE(testNpeInSpanNearWithSpanNot) SpanTermQueryPtr hun = newLucene(newLucene(L"field", L"hundred")); SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"forty")); SpanNearQueryPtr exclude1 = newLucene(newCollection(hun, term3), 1, true); - + SpanNotQueryPtr query = newLucene(near1, exclude1); static const int32_t results[] = {801, 821, 831, 851, 861, 871, 881, 891}; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - BOOST_CHECK(searcher->explain(query, 801)->getValue() > 0.0); - BOOST_CHECK(searcher->explain(query, 891)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 801)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -BOOST_AUTO_TEST_CASE(testNpeInSpanNearInSpanFirstInSpanNot) +TEST_F(BasicSpansTest, testNpeInSpanNearInSpanFirstInSpanNot) { int32_t n = 5; SpanTermQueryPtr hun = newLucene(newLucene(L"field", L"hundred")); SpanTermQueryPtr term40 = newLucene(newLucene(L"field", L"forty")); SpanTermQueryPtr term40c = boost::dynamic_pointer_cast(term40->clone()); - + SpanFirstQueryPtr include = newLucene(term40, n); SpanNearQueryPtr near1 = newLucene(newCollection(hun, term40c), n - 1, true); SpanFirstQueryPtr exclude = newLucene(near1, n - 1); @@ -268,12 +266,12 @@ BOOST_AUTO_TEST_CASE(testNpeInSpanNearInSpanFirstInSpanNot) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testSpanFirst) +TEST_F(BasicSpansTest, testSpanFirst) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"five")); SpanFirstQueryPtr query = newLucene(term1, 1); - - static const int32_t results[] = + + static const int32_t results[] = { 5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, @@ -286,11 +284,11 @@ BOOST_AUTO_TEST_CASE(testSpanFirst) }; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - BOOST_CHECK(searcher->explain(query, 5)->getValue() > 0.0); - BOOST_CHECK(searcher->explain(query, 599)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 5)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 599)->getValue() > 0.0); } -BOOST_AUTO_TEST_CASE(testSpanOr) +TEST_F(BasicSpansTest, testSpanOr) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"thirty")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"three")); @@ -298,7 +296,7 @@ BOOST_AUTO_TEST_CASE(testSpanOr) SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"forty")); SpanTermQueryPtr term4 = newLucene(newLucene(L"field", L"seven")); SpanNearQueryPtr near2 = newLucene(newCollection(term3, term4), 0, true); - + SpanOrQueryPtr query = newLucene(newCollection(near1, near2)); static const int32_t results[] = @@ -307,11 +305,11 @@ BOOST_AUTO_TEST_CASE(testSpanOr) }; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - BOOST_CHECK(searcher->explain(query, 33)->getValue() > 0.0); - BOOST_CHECK(searcher->explain(query, 947)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 33)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 947)->getValue() > 0.0); } -BOOST_AUTO_TEST_CASE(testSpanExactNested) +TEST_F(BasicSpansTest, testSpanExactNested) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"three")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"hundred")); @@ -319,84 +317,82 @@ BOOST_AUTO_TEST_CASE(testSpanExactNested) SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"thirty")); SpanTermQueryPtr term4 = newLucene(newLucene(L"field", L"three")); SpanNearQueryPtr near2 = newLucene(newCollection(term3, term4), 0, true); - + SpanNearQueryPtr query = newLucene(newCollection(near1, near2), 0, true); static const int32_t results[] = {333}; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); - BOOST_CHECK(searcher->explain(query, 333)->getValue() > 0.0); + EXPECT_TRUE(searcher->explain(query, 333)->getValue() > 0.0); } -BOOST_AUTO_TEST_CASE(testSpanNearOr) +TEST_F(BasicSpansTest, testSpanNearOr) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"six")); SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"seven")); - + SpanTermQueryPtr term5 = newLucene(newLucene(L"field", L"seven")); SpanTermQueryPtr term6 = newLucene(newLucene(L"field", L"six")); - + SpanOrQueryPtr to1 = newLucene(newCollection(term1, term3)); SpanOrQueryPtr to2 = newLucene(newCollection(term5, term6)); - + SpanNearQueryPtr query = newLucene(newCollection(to1, to2), 10, true); static const int32_t results[] = { - 606, 607, 626, 627, 636, 637, 646, 647, 656, + 606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677, 686, 687, 696, 697, - 706, 707, 726, 727, 736, 737, 746, 747, 756, + 706, 707, 726, 727, 736, 737, 746, 747, 756, 757, 766, 767, 776, 777, 786, 787, 796, 797 }; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testSpanComplex1) +TEST_F(BasicSpansTest, testSpanComplex1) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"six")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"hundred")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 0, true); - + SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"seven")); SpanTermQueryPtr term4 = newLucene(newLucene(L"field", L"hundred")); SpanNearQueryPtr near2 = newLucene(newCollection(term3, term4), 0, true); - + SpanTermQueryPtr term5 = newLucene(newLucene(L"field", L"seven")); SpanTermQueryPtr term6 = newLucene(newLucene(L"field", L"six")); - + SpanOrQueryPtr to1 = newLucene(newCollection(near1, near2)); SpanOrQueryPtr to2 = newLucene(newCollection(term5, term6)); - + SpanNearQueryPtr query = newLucene(newCollection(to1, to2), 100, true); static const int32_t results[] = { - 606, 607, 626, 627, 636, 637, 646, 647, 656, + 606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677, 686, 687, 696, 697, - 706, 707, 726, 727, 736, 737, 746, 747, 756, + 706, 707, 726, 727, 736, 737, 746, 747, 756, 757, 766, 767, 776, 777, 786, 787, 796, 797 }; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -BOOST_AUTO_TEST_CASE(testSpansSkipTo) +TEST_F(BasicSpansTest, testSpansSkipTo) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"seventy")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"seventy")); SpansPtr spans1 = term1->getSpans(searcher->getIndexReader()); SpansPtr spans2 = term2->getSpans(searcher->getIndexReader()); - - BOOST_CHECK(spans1->next()); - BOOST_CHECK(spans2->next()); + + EXPECT_TRUE(spans1->next()); + EXPECT_TRUE(spans2->next()); bool hasMore = true; do { hasMore = skipTo(spans1, spans2->doc()); - BOOST_CHECK_EQUAL(hasMore, spans2->skipTo(spans2->doc())); - BOOST_CHECK_EQUAL(spans1->doc(), spans2->doc()); + EXPECT_EQ(hasMore, spans2->skipTo(spans2->doc())); + EXPECT_EQ(spans1->doc(), spans2->doc()); } while (hasMore); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp index 5208005a..1273f149 100644 --- a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp +++ b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp @@ -23,10 +23,10 @@ using namespace Lucene; -class FieldMaskingSpanQueryFixture : public LuceneTestFixture +class FieldMaskingSpanQueryTest : public LuceneTestFixture { public: - FieldMaskingSpanQueryFixture() + FieldMaskingSpanQueryTest() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -47,7 +47,7 @@ class FieldMaskingSpanQueryFixture : public LuceneTestFixture field(L"first", L"sally"), field(L"last", L"jones"))) ); - + writer->addDocument(doc(newCollection( field(L"id", L"2"), field(L"gender", L"female"), @@ -87,8 +87,8 @@ class FieldMaskingSpanQueryFixture : public LuceneTestFixture writer->close(); searcher = newLucene(directory, true); } - - virtual ~FieldMaskingSpanQueryFixture() + + virtual ~FieldMaskingSpanQueryTest() { searcher->close(); } @@ -104,31 +104,29 @@ class FieldMaskingSpanQueryFixture : public LuceneTestFixture doc->add(fields[i]); return doc; } - + FieldPtr field(const String& name, const String& value) { return newLucene(name, value, Field::STORE_NO, Field::INDEX_ANALYZED); } - + void check(SpanQueryPtr q, Collection docs) { CheckHits::checkHitCollector(q, L"", searcher, docs); } - + String str(SpansPtr span) { return str(span->doc(), span->start(), span->end()); } - + String str(int32_t doc, int32_t start, int32_t end) { return L"s(" + StringUtils::toString(doc) + L"," + StringUtils::toString(start) + L"," + StringUtils::toString(end) + L")"; } }; -BOOST_FIXTURE_TEST_SUITE(FieldMaskingSpanQueryTest, FieldMaskingSpanQueryFixture) - -BOOST_AUTO_TEST_CASE(testRewrite0) +TEST_F(FieldMaskingSpanQueryTest, testRewrite0) { SpanQueryPtr q = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); q->setBoost(8.7654321); @@ -138,7 +136,7 @@ BOOST_AUTO_TEST_CASE(testRewrite0) SetTerm terms = SetTerm::newInstance(); qr->extractTerms(terms); - BOOST_CHECK_EQUAL(1, terms.size()); + EXPECT_EQ(1, terms.size()); } namespace TestRewrite @@ -149,23 +147,23 @@ namespace TestRewrite TestableFieldMaskingSpanQuery(SpanQueryPtr maskedQuery, const String& maskedField) : FieldMaskingSpanQuery(maskedQuery, maskedField) { } - + virtual ~TestableFieldMaskingSpanQuery() { } - + public: virtual QueryPtr rewrite(IndexReaderPtr reader) { return newLucene(newCollection( - newLucene(newLucene(L"first", L"sally")), + newLucene(newLucene(L"first", L"sally")), newLucene(newLucene(L"first", L"james"))) ); } }; } -BOOST_AUTO_TEST_CASE(testRewrite1) +TEST_F(FieldMaskingSpanQueryTest, testRewrite1) { // mask an anon SpanQuery class that rewrites to something else. SpanQueryPtr q = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); @@ -175,10 +173,10 @@ BOOST_AUTO_TEST_CASE(testRewrite1) SetTerm terms = SetTerm::newInstance(); qr->extractTerms(terms); - BOOST_CHECK_EQUAL(2, terms.size()); + EXPECT_EQ(2, terms.size()); } -BOOST_AUTO_TEST_CASE(testRewrite2) +TEST_F(FieldMaskingSpanQueryTest, testRewrite2) { SpanQueryPtr q1 = newLucene(newLucene(L"last", L"smith")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"jones")); @@ -187,10 +185,10 @@ BOOST_AUTO_TEST_CASE(testRewrite2) QueryUtils::checkEqual(q, qr); SetTerm terms = SetTerm::newInstance(); qr->extractTerms(terms); - BOOST_CHECK_EQUAL(2, terms.size()); + EXPECT_EQ(2, terms.size()); } -BOOST_AUTO_TEST_CASE(testEquality1) +TEST_F(FieldMaskingSpanQueryTest, testEquality1) { SpanQueryPtr q1 = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); SpanQueryPtr q2 = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); @@ -210,14 +208,14 @@ BOOST_AUTO_TEST_CASE(testEquality1) QueryUtils::checkEqual(qA, qB); } -BOOST_AUTO_TEST_CASE(testNoop0) +TEST_F(FieldMaskingSpanQueryTest, testNoop0) { SpanQueryPtr q1 = newLucene(newLucene(L"last", L"sally")); SpanQueryPtr q = newLucene(q1, L"first"); check(q, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testNoop1) +TEST_F(FieldMaskingSpanQueryTest, testNoop1) { SpanQueryPtr q1 = newLucene(newLucene(L"last", L"smith")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"jones")); @@ -227,7 +225,7 @@ BOOST_AUTO_TEST_CASE(testNoop1) check(q, newCollection(1, 2)); } -BOOST_AUTO_TEST_CASE(testSimple1) +TEST_F(FieldMaskingSpanQueryTest, testSimple1) { SpanQueryPtr q1 = newLucene(newLucene(L"first", L"james")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"jones")); @@ -241,7 +239,7 @@ BOOST_AUTO_TEST_CASE(testSimple1) check(q, newCollection(0, 2)); } -BOOST_AUTO_TEST_CASE(testSimple2) +TEST_F(FieldMaskingSpanQueryTest, testSimple2) { SpanQueryPtr q1 = newLucene(newLucene(L"gender", L"female")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"smith")); @@ -251,7 +249,7 @@ BOOST_AUTO_TEST_CASE(testSimple2) check(q, newCollection(2, 4)); } -BOOST_AUTO_TEST_CASE(testSpans0) +TEST_F(FieldMaskingSpanQueryTest, testSpans0) { SpanQueryPtr q1 = newLucene(newLucene(L"gender", L"female")); SpanQueryPtr q2 = newLucene(newLucene(L"first", L"james")); @@ -260,37 +258,37 @@ BOOST_AUTO_TEST_CASE(testSpans0) SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(0, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(0, 0, 1), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(1, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(1, 0, 1), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(1, 1, 2), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(1, 1, 2), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(2, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(2, 0, 1), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(2, 1, 2), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(2, 1, 2), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(2, 2, 3), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(2, 2, 3), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(3, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(3, 0, 1), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(4, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(4, 0, 1), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(4, 1, 2), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(4, 1, 2), str(span)); - BOOST_CHECK(!span->next()); + EXPECT_TRUE(!span->next()); } -BOOST_AUTO_TEST_CASE(testSpans1) +TEST_F(FieldMaskingSpanQueryTest, testSpans1) { SpanQueryPtr q1 = newLucene(newLucene(L"first", L"sally")); SpanQueryPtr q2 = newLucene(newLucene(L"first", L"james")); @@ -302,16 +300,16 @@ BOOST_AUTO_TEST_CASE(testSpans1) SpansPtr spanA = qA->getSpans(searcher->getIndexReader()); SpansPtr spanB = qB->getSpans(searcher->getIndexReader()); - + while (spanA->next()) { - BOOST_CHECK(spanB->next()); - BOOST_CHECK_EQUAL(str(spanA), str(spanB)); + EXPECT_TRUE(spanB->next()); + EXPECT_EQ(str(spanA), str(spanB)); } - BOOST_CHECK(!(spanB->next())); + EXPECT_TRUE(!(spanB->next())); } -BOOST_AUTO_TEST_CASE(testSpans2) +TEST_F(FieldMaskingSpanQueryTest, testSpans2) { SpanQueryPtr qA1 = newLucene(newLucene(L"gender", L"female")); SpanQueryPtr qA2 = newLucene(newLucene(L"first", L"james")); @@ -322,22 +320,20 @@ BOOST_AUTO_TEST_CASE(testSpans2) SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(0, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(0, 0, 1), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(1, 1, 2), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(1, 1, 2), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(2, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(2, 0, 1), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(2, 2, 3), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(2, 2, 3), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(3, 0, 1), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(3, 0, 1), str(span)); - BOOST_CHECK(!span->next()); + EXPECT_TRUE(!span->next()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/NearSpansOrderedTest.cpp b/src/test/search/spans/NearSpansOrderedTest.cpp index 785fbfc7..6dc9ed3b 100644 --- a/src/test/search/spans/NearSpansOrderedTest.cpp +++ b/src/test/search/spans/NearSpansOrderedTest.cpp @@ -24,10 +24,10 @@ using namespace Lucene; -class NearSpansOrderedFixture : public LuceneTestFixture +class NearSpansOrderedTest : public LuceneTestFixture { public: - NearSpansOrderedFixture() + NearSpansOrderedTest() { qp = newLucene(LuceneVersion::LUCENE_CURRENT, FIELD, newLucene()); docFields = newCollection(L"w1 w2 w3 w4 w5", L"w1 w3 w2 w3 zz", L"w1 xx w2 yy w3", L"w1 w3 xx w2 yy w3 zz"); @@ -42,8 +42,8 @@ class NearSpansOrderedFixture : public LuceneTestFixture writer->close(); searcher = newLucene(directory, true); } - - virtual ~NearSpansOrderedFixture() + + virtual ~NearSpansOrderedTest() { searcher->close(); } @@ -52,7 +52,7 @@ class NearSpansOrderedFixture : public LuceneTestFixture IndexSearcherPtr searcher; QueryParserPtr qp; Collection docFields; - + public: static const String FIELD; @@ -65,113 +65,109 @@ class NearSpansOrderedFixture : public LuceneTestFixture newLucene(newLucene(FIELD, s3)) ), slop, inOrder); } - + SpanNearQueryPtr makeQuery() { return makeQuery(L"w1", L"w2", L"w3", 1, true); } - + String str(SpansPtr span) { return str(span->doc(), span->start(), span->end()); } - + String str(int32_t doc, int32_t start, int32_t end) { return L"s(" + StringUtils::toString(doc) + L"," + StringUtils::toString(start) + L"," + StringUtils::toString(end) + L")"; } }; -const String NearSpansOrderedFixture::FIELD = L"field"; - -BOOST_FIXTURE_TEST_SUITE(NearSpansOrderedTest, NearSpansOrderedFixture) +const String NearSpansOrderedTest::FIELD = L"field"; -BOOST_AUTO_TEST_CASE(testSpanNearQuery) +TEST_F(NearSpansOrderedTest, testSpanNearQuery) { SpanNearQueryPtr q = makeQuery(); CheckHits::checkHits(q, FIELD, searcher, newCollection(0, 1)); } -BOOST_AUTO_TEST_CASE(testNearSpansNext) +TEST_F(NearSpansOrderedTest, testNearSpansNext) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(0, 0, 3), str(span)); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(1, 0, 4), str(span)); - BOOST_CHECK(!span->next()); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(0, 0, 3), str(span)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(1, 0, 4), str(span)); + EXPECT_TRUE(!span->next()); } -/// test does not imply that skipTo(doc+1) should work exactly the same as next -- it's only applicable in this case +/// test does not imply that skipTo(doc+1) should work exactly the same as next -- it's only applicable in this case /// since we know doc does not contain more than one span -BOOST_AUTO_TEST_CASE(testNearSpansSkipToLikeNext) +TEST_F(NearSpansOrderedTest, testNearSpansSkipToLikeNext) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->skipTo(0)); - BOOST_CHECK_EQUAL(str(0, 0, 3), str(span)); - BOOST_CHECK(span->skipTo(1)); - BOOST_CHECK_EQUAL(str(1, 0, 4), str(span)); - BOOST_CHECK(!span->skipTo(2)); + EXPECT_TRUE(span->skipTo(0)); + EXPECT_EQ(str(0, 0, 3), str(span)); + EXPECT_TRUE(span->skipTo(1)); + EXPECT_EQ(str(1, 0, 4), str(span)); + EXPECT_TRUE(!span->skipTo(2)); } -BOOST_AUTO_TEST_CASE(testNearSpansNextThenSkipTo) +TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipTo) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(0, 0, 3), str(span)); - BOOST_CHECK(span->skipTo(1)); - BOOST_CHECK_EQUAL(str(1, 0, 4), str(span)); - BOOST_CHECK(!span->next()); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(0, 0, 3), str(span)); + EXPECT_TRUE(span->skipTo(1)); + EXPECT_EQ(str(1, 0, 4), str(span)); + EXPECT_TRUE(!span->next()); } -BOOST_AUTO_TEST_CASE(testNearSpansNextThenSkipPast) +TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipPast) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->next()); - BOOST_CHECK_EQUAL(str(0, 0, 3), str(span)); - BOOST_CHECK(!span->skipTo(2)); + EXPECT_TRUE(span->next()); + EXPECT_EQ(str(0, 0, 3), str(span)); + EXPECT_TRUE(!span->skipTo(2)); } -BOOST_AUTO_TEST_CASE(testNearSpansSkipPast) +TEST_F(NearSpansOrderedTest, testNearSpansSkipPast) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(!span->skipTo(2)); + EXPECT_TRUE(!span->skipTo(2)); } -BOOST_AUTO_TEST_CASE(testNearSpansSkipTo0) +TEST_F(NearSpansOrderedTest, testNearSpansSkipTo0) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->skipTo(0)); - BOOST_CHECK_EQUAL(str(0, 0, 3), str(span)); + EXPECT_TRUE(span->skipTo(0)); + EXPECT_EQ(str(0, 0, 3), str(span)); } -BOOST_AUTO_TEST_CASE(testNearSpansSkipTo1) +TEST_F(NearSpansOrderedTest, testNearSpansSkipTo1) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); - BOOST_CHECK(span->skipTo(1)); - BOOST_CHECK_EQUAL(str(1, 0, 4), str(span)); + EXPECT_TRUE(span->skipTo(1)); + EXPECT_EQ(str(1, 0, 4), str(span)); } -BOOST_AUTO_TEST_CASE(testSpanNearScorerSkipTo1) +TEST_F(NearSpansOrderedTest, testSpanNearScorerSkipTo1) { SpanNearQueryPtr q = makeQuery(); WeightPtr w = q->weight(searcher); ScorerPtr s = w->scorer(searcher->getIndexReader(), true, false); - BOOST_CHECK_EQUAL(1, s->advance(1)); + EXPECT_EQ(1, s->advance(1)); } -BOOST_AUTO_TEST_CASE(testSpanNearScorerExplain) +TEST_F(NearSpansOrderedTest, testSpanNearScorerExplain) { SpanNearQueryPtr q = makeQuery(); ExplanationPtr e = q->weight(searcher)->explain(searcher->getIndexReader(), 1); - BOOST_CHECK(0.0 < e->getValue()); + EXPECT_TRUE(0.0 < e->getValue()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/PayloadSpansTest.cpp b/src/test/search/spans/PayloadSpansTest.cpp index 5b6f68cd..82f3f015 100644 --- a/src/test/search/spans/PayloadSpansTest.cpp +++ b/src/test/search/spans/PayloadSpansTest.cpp @@ -53,11 +53,11 @@ class PayloadSpansFilter : public TokenFilter this->posIncrAtt = addAttribute(); this->payloadAtt = addAttribute(); } - + virtual ~PayloadSpansFilter() { } - + LUCENE_CLASS(PayloadSpansFilter); public: @@ -67,7 +67,7 @@ class PayloadSpansFilter : public TokenFilter int32_t pos; PayloadAttributePtr payloadAtt; TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncrAtt; + PositionIncrementAttributePtr posIncrAtt; public: virtual bool incrementToken() @@ -75,7 +75,7 @@ class PayloadSpansFilter : public TokenFilter if (input->incrementToken()) { String token(termAtt->termBuffer().get(), termAtt->termLength()); - + if (!nopayload.contains(token)) { StringStream buf; @@ -103,7 +103,7 @@ class PayloadSpansAnalyzer : public Analyzer virtual ~PayloadSpansAnalyzer() { } - + LUCENE_CLASS(PayloadSpansAnalyzer); public: @@ -115,17 +115,17 @@ class PayloadSpansAnalyzer : public Analyzer } }; -class PayloadSpansFixture : public LuceneTestFixture +class PayloadSpansTest : public LuceneTestFixture { public: - PayloadSpansFixture() + PayloadSpansTest() { similarity = newLucene(); searcher = PayloadHelper::setUp(similarity, 1000); indexReader = searcher->getIndexReader(); } - - virtual ~PayloadSpansFixture() + + virtual ~PayloadSpansTest() { } @@ -137,31 +137,31 @@ class PayloadSpansFixture : public LuceneTestFixture public: void checkSpans(SpansPtr spans, int32_t expectedNumSpans, int32_t expectedNumPayloads, int32_t expectedPayloadLength, int32_t expectedFirstByte) { - BOOST_CHECK(spans); + EXPECT_TRUE(spans); int32_t seen = 0; while (spans->next()) { // if we expect payloads, then isPayloadAvailable should be true if (expectedNumPayloads > 0) - BOOST_CHECK(spans->isPayloadAvailable()); + EXPECT_TRUE(spans->isPayloadAvailable()); else - BOOST_CHECK(!spans->isPayloadAvailable()); + EXPECT_TRUE(!spans->isPayloadAvailable()); // See payload helper, for the PayloadHelper::FIELD field, there is a single byte payload at every token if (spans->isPayloadAvailable()) { Collection payload = spans->getPayload(); - BOOST_CHECK_EQUAL(payload.size(), expectedNumPayloads); + EXPECT_EQ(payload.size(), expectedNumPayloads); for (Collection::iterator thePayload = payload.begin(); thePayload != payload.end(); ++thePayload) { - BOOST_CHECK_EQUAL(thePayload->size(), expectedPayloadLength); - BOOST_CHECK_EQUAL((*thePayload)[0], expectedFirstByte); + EXPECT_EQ(thePayload->size(), expectedPayloadLength); + EXPECT_EQ((*thePayload)[0], expectedFirstByte); } } ++seen; } - BOOST_CHECK_EQUAL(seen, expectedNumSpans); + EXPECT_EQ(seen, expectedNumSpans); } - + void checkSpans(SpansPtr spans, int32_t numSpans, Collection numPayloads) { int32_t cnt = 0; @@ -170,14 +170,14 @@ class PayloadSpansFixture : public LuceneTestFixture if (spans->isPayloadAvailable()) { Collection payload = spans->getPayload(); - BOOST_CHECK_EQUAL(numPayloads[cnt], payload.size()); + EXPECT_EQ(numPayloads[cnt], payload.size()); } else - BOOST_CHECK(numPayloads.size() <= 0 || numPayloads[cnt] <= 0); + EXPECT_TRUE(numPayloads.size() <= 0 || numPayloads[cnt] <= 0); } ++cnt; } - + IndexSearcherPtr getSpanNotSearcher() { RAMDirectoryPtr directory = newLucene(); @@ -194,19 +194,19 @@ class PayloadSpansFixture : public LuceneTestFixture searcher->setSimilarity(similarity); return searcher; } - + IndexSearcherPtr getSearcher() { RAMDirectoryPtr directory = newLucene(); PayloadSpansAnalyzerPtr analyzer = newLucene(); Collection docs = newCollection( - L"xx rr yy mm pp", L"xx yy mm rr pp", L"nopayload qq ss pp np", - L"one two three four five six seven eight nine ten eleven", + L"xx rr yy mm pp", L"xx yy mm rr pp", L"nopayload qq ss pp np", + L"one two three four five six seven eight nine ten eleven", L"nine one two three four five six seven eight eleven ten" ); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setSimilarity(similarity); - + for (int32_t i = 0; i < docs.size(); ++i) { DocumentPtr doc = newLucene(); @@ -221,22 +221,20 @@ class PayloadSpansFixture : public LuceneTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(PayloadSpansTest, PayloadSpansFixture) - -BOOST_AUTO_TEST_CASE(testSpanTermQuery) +TEST_F(PayloadSpansTest, testSpanTermQuery) { SpanTermQueryPtr stq = newLucene(newLucene(PayloadHelper::FIELD, L"seventy")); SpansPtr spans = stq->getSpans(indexReader); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 100, 1, 1, 1); - stq = newLucene(newLucene(PayloadHelper::NO_PAYLOAD_FIELD, L"seventy")); + stq = newLucene(newLucene(PayloadHelper::NO_PAYLOAD_FIELD, L"seventy")); spans = stq->getSpans(indexReader); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 100, 0, 0, 0); } -BOOST_AUTO_TEST_CASE(testSpanFirst) +TEST_F(PayloadSpansTest, testSpanFirst) { SpanQueryPtr match = newLucene(newLucene(PayloadHelper::FIELD, L"one")); SpanFirstQueryPtr sfq = newLucene(match, 2); @@ -256,7 +254,7 @@ BOOST_AUTO_TEST_CASE(testSpanFirst) checkSpans(sfq->getSpans(indexReader), 100, 2, 1, 1); } -BOOST_AUTO_TEST_CASE(testSpanNot) +TEST_F(PayloadSpansTest, testSpanNot) { Collection clauses = newCollection( newLucene(newLucene(PayloadHelper::FIELD, L"one")), @@ -267,12 +265,12 @@ BOOST_AUTO_TEST_CASE(testSpanNot) checkSpans(snq->getSpans(getSpanNotSearcher()->getIndexReader()), 1, newCollection(2)); } -BOOST_AUTO_TEST_CASE(testNestedSpans) +TEST_F(PayloadSpansTest, testNestedSpans) { IndexSearcherPtr searcher = getSearcher(); SpanTermQueryPtr stq = newLucene(newLucene(PayloadHelper::FIELD, L"mark")); SpansPtr spans = stq->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 0, Collection()); Collection clauses = newCollection( @@ -283,24 +281,24 @@ BOOST_AUTO_TEST_CASE(testNestedSpans) SpanNearQueryPtr spanNearQuery = newLucene(clauses, 12, false); spans = spanNearQuery->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 2, newCollection(3, 3)); clauses[0] = newLucene(newLucene(PayloadHelper::FIELD, L"xx")); clauses[1] = newLucene(newLucene(PayloadHelper::FIELD, L"rr")); clauses[2] = newLucene(newLucene(PayloadHelper::FIELD, L"yy")); - + spanNearQuery = newLucene(clauses, 6, true); spans = spanNearQuery->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 1, newCollection(3)); - + clauses = newCollection( newLucene(newLucene(PayloadHelper::FIELD, L"xx")), newLucene(newLucene(PayloadHelper::FIELD, L"rr")) ); - + spanNearQuery = newLucene(clauses, 6, true); // xx within 6 of rr @@ -308,16 +306,16 @@ BOOST_AUTO_TEST_CASE(testNestedSpans) newLucene(newLucene(PayloadHelper::FIELD, L"yy")), spanNearQuery ); - + SpanNearQueryPtr nestedSpanNearQuery = newLucene(clauses2, 6, false); // yy within 6 of xx within 6 of rr spans = nestedSpanNearQuery->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 2, newCollection(3, 3)); } -BOOST_AUTO_TEST_CASE(testFirstClauseWithoutPayload) +TEST_F(PayloadSpansTest, testFirstClauseWithoutPayload) { IndexSearcherPtr searcher = getSearcher(); Collection clauses = newCollection( @@ -338,15 +336,15 @@ BOOST_AUTO_TEST_CASE(testFirstClauseWithoutPayload) newLucene(newLucene(PayloadHelper::FIELD, L"np")), snq ); - + SpanNearQueryPtr nestedSpanNearQuery = newLucene(clauses3, 6, false); SpansPtr spans = nestedSpanNearQuery->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 1, newCollection(3)); } -BOOST_AUTO_TEST_CASE(testHeavilyNestedSpanQuery) +TEST_F(PayloadSpansTest, testHeavilyNestedSpanQuery) { IndexSearcherPtr searcher = getSearcher(); Collection clauses = newCollection( @@ -355,32 +353,32 @@ BOOST_AUTO_TEST_CASE(testHeavilyNestedSpanQuery) newLucene(newLucene(PayloadHelper::FIELD, L"three")) ); SpanNearQueryPtr spanNearQuery = newLucene(clauses, 5, true); - + clauses[0] = spanNearQuery; clauses[1] = newLucene(newLucene(PayloadHelper::FIELD, L"five")); clauses[2] = newLucene(newLucene(PayloadHelper::FIELD, L"six")); - + SpanNearQueryPtr spanNearQuery2 = newLucene(clauses, 6, true); - + Collection clauses2 = newCollection( newLucene(newLucene(PayloadHelper::FIELD, L"eleven")), newLucene(newLucene(PayloadHelper::FIELD, L"ten")) ); SpanNearQueryPtr spanNearQuery3 = newLucene(clauses2, 2, false); - + Collection clauses3 = newCollection( newLucene(newLucene(PayloadHelper::FIELD, L"nine")), spanNearQuery2, spanNearQuery3 ); SpanNearQueryPtr nestedSpanNearQuery = newLucene(clauses3, 6, false); - + SpansPtr spans = nestedSpanNearQuery->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans); + EXPECT_TRUE(spans); checkSpans(spans, 2, newCollection(8, 8)); } -BOOST_AUTO_TEST_CASE(testShrinkToAfterShortestMatch) +TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -408,12 +406,12 @@ BOOST_AUTO_TEST_CASE(testShrinkToAfterShortestMatch) payloadSet.add(String((wchar_t*)it->get(), it->size() / sizeof(wchar_t))); } } - BOOST_CHECK_EQUAL(2, payloadSet.size()); - BOOST_CHECK(payloadSet.contains(L"a:Noise:10")); - BOOST_CHECK(payloadSet.contains(L"k:Noise:11")); + EXPECT_EQ(2, payloadSet.size()); + EXPECT_TRUE(payloadSet.contains(L"a:Noise:10")); + EXPECT_TRUE(payloadSet.contains(L"k:Noise:11")); } -BOOST_AUTO_TEST_CASE(testShrinkToAfterShortestMatch2) +TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch2) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -441,12 +439,12 @@ BOOST_AUTO_TEST_CASE(testShrinkToAfterShortestMatch2) payloadSet.add(String((wchar_t*)it->get(), it->size() / sizeof(wchar_t))); } } - BOOST_CHECK_EQUAL(2, payloadSet.size()); - BOOST_CHECK(payloadSet.contains(L"a:Noise:10")); - BOOST_CHECK(payloadSet.contains(L"k:Noise:11")); + EXPECT_EQ(2, payloadSet.size()); + EXPECT_TRUE(payloadSet.contains(L"a:Noise:10")); + EXPECT_TRUE(payloadSet.contains(L"k:Noise:11")); } -BOOST_AUTO_TEST_CASE(testShrinkToAfterShortestMatch3) +TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch3) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -474,12 +472,12 @@ BOOST_AUTO_TEST_CASE(testShrinkToAfterShortestMatch3) payloadSet.add(String((wchar_t*)it->get(), it->size() / sizeof(wchar_t))); } } - BOOST_CHECK_EQUAL(2, payloadSet.size()); - BOOST_CHECK(payloadSet.contains(L"a:Noise:10")); - BOOST_CHECK(payloadSet.contains(L"k:Noise:11")); + EXPECT_EQ(2, payloadSet.size()); + EXPECT_TRUE(payloadSet.contains(L"a:Noise:10")); + EXPECT_TRUE(payloadSet.contains(L"k:Noise:11")); } -BOOST_AUTO_TEST_CASE(testPayloadSpanUtil) +TEST_F(PayloadSpansTest, testPayloadSpanUtil) { RAMDirectoryPtr directory = newLucene(); PayloadSpansAnalyzerPtr analyzer = newLucene(); @@ -496,8 +494,6 @@ BOOST_AUTO_TEST_CASE(testPayloadSpanUtil) PayloadSpanUtilPtr psu = newLucene(reader); Collection payloads = psu->getPayloadsForQuery(newLucene(newLucene(PayloadHelper::FIELD, L"rr"))); - BOOST_CHECK_EQUAL(1, payloads.size()); - BOOST_CHECK_EQUAL(String((wchar_t*)(payloads[0].get()), payloads[0].size() / sizeof(wchar_t)), L"rr:Noise:1"); + EXPECT_EQ(1, payloads.size()); + EXPECT_EQ(String((wchar_t*)(payloads[0].get()), payloads[0].size() / sizeof(wchar_t)), L"rr:Noise:1"); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/SpanExplanationsTest.cpp b/src/test/search/spans/SpanExplanationsTest.cpp index 3f5c0a20..f48137fb 100644 --- a/src/test/search/spans/SpanExplanationsTest.cpp +++ b/src/test/search/spans/SpanExplanationsTest.cpp @@ -15,183 +15,183 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SpanExplanationsTest, ExplanationsFixture) +typedef ExplanationsFixture SpanExplanationsTest; -BOOST_AUTO_TEST_CASE(testST1) +TEST_F(SpanExplanationsTest, testST1) { SpanQueryPtr q = st(L"w1"); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testST2) +TEST_F(SpanExplanationsTest, testST2) { SpanQueryPtr q = st(L"w1"); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testST4) +TEST_F(SpanExplanationsTest, testST4) { SpanQueryPtr q = st(L"xx"); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testST5) +TEST_F(SpanExplanationsTest, testST5) { SpanQueryPtr q = st(L"xx"); q->setBoost(1000); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSF1) +TEST_F(SpanExplanationsTest, testSF1) { SpanQueryPtr q = sf(L"w1", 1); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSF2) +TEST_F(SpanExplanationsTest, testSF2) { SpanQueryPtr q = sf(L"w1", 1); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSF4) +TEST_F(SpanExplanationsTest, testSF4) { SpanQueryPtr q = sf(L"xx", 2); qtest(q, newCollection(2)); } -BOOST_AUTO_TEST_CASE(testSF5) +TEST_F(SpanExplanationsTest, testSF5) { SpanQueryPtr q = sf(L"yy", 2); qtest(q, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testSF6) +TEST_F(SpanExplanationsTest, testSF6) { SpanQueryPtr q = sf(L"yy", 4); q->setBoost(1000); qtest(q, newCollection(2)); } -BOOST_AUTO_TEST_CASE(testSO1) +TEST_F(SpanExplanationsTest, testSO1) { SpanQueryPtr q = sor(L"w1", L"QQ"); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSO2) +TEST_F(SpanExplanationsTest, testSO2) { SpanQueryPtr q = sor(L"w1", L"w3", L"zz"); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSO3) +TEST_F(SpanExplanationsTest, testSO3) { SpanQueryPtr q = sor(L"w5", L"QQ", L"yy"); qtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSO4) +TEST_F(SpanExplanationsTest, testSO4) { SpanQueryPtr q = sor(L"w5", L"QQ", L"yy"); qtest(q, newCollection(0, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNear1) +TEST_F(SpanExplanationsTest, testSNear1) { SpanQueryPtr q = snear(L"w1", L"QQ", 100, true); qtest(q, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testSNear2) +TEST_F(SpanExplanationsTest, testSNear2) { SpanQueryPtr q = snear(L"w1", L"xx", 100, true); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSNear3) +TEST_F(SpanExplanationsTest, testSNear3) { SpanQueryPtr q = snear(L"w1", L"xx", 0, true); qtest(q, newCollection(2)); } -BOOST_AUTO_TEST_CASE(testSNear4) +TEST_F(SpanExplanationsTest, testSNear4) { SpanQueryPtr q = snear(L"w1", L"xx", 1, true); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSNear5) +TEST_F(SpanExplanationsTest, testSNear5) { SpanQueryPtr q = snear(L"xx", L"w1", 0, false); qtest(q, newCollection(2)); } -BOOST_AUTO_TEST_CASE(testSNear6) +TEST_F(SpanExplanationsTest, testSNear6) { SpanQueryPtr q = snear(L"w1", L"w2", L"QQ", 100, true); qtest(q, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testSNear7) +TEST_F(SpanExplanationsTest, testSNear7) { SpanQueryPtr q = snear(L"w1", L"xx", L"w2", 100, true); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSNear8) +TEST_F(SpanExplanationsTest, testSNear8) { SpanQueryPtr q = snear(L"w1", L"xx", L"w2", 0, true); qtest(q, newCollection(2)); } -BOOST_AUTO_TEST_CASE(testSNear9) +TEST_F(SpanExplanationsTest, testSNear9) { SpanQueryPtr q = snear(L"w1", L"xx", L"w2", 1, true); qtest(q, newCollection(2, 3)); } -BOOST_AUTO_TEST_CASE(testSNear10) +TEST_F(SpanExplanationsTest, testSNear10) { SpanQueryPtr q = snear(L"xx", L"w1", L"w2", 0, false); qtest(q, newCollection(2)); } -BOOST_AUTO_TEST_CASE(testSNear11) +TEST_F(SpanExplanationsTest, testSNear11) { SpanQueryPtr q = snear(L"w1", L"w2", L"w3", 1, true); qtest(q, newCollection(0, 1)); } -BOOST_AUTO_TEST_CASE(testSNot1) +TEST_F(SpanExplanationsTest, testSNot1) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot2) +TEST_F(SpanExplanationsTest, testSNot2) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot4) +TEST_F(SpanExplanationsTest, testSNot4) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot5) +TEST_F(SpanExplanationsTest, testSNot5) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSNot7) +TEST_F(SpanExplanationsTest, testSNot7) { SpanQueryPtr f = snear(L"w1", L"w3", 10, true); f->setBoost(1000); @@ -199,12 +199,10 @@ BOOST_AUTO_TEST_CASE(testSNot7) qtest(q, newCollection(0, 1, 3)); } -BOOST_AUTO_TEST_CASE(testSNot10) +TEST_F(SpanExplanationsTest, testSNot10) { SpanQueryPtr t = st(L"xx"); t->setBoost(10000); SpanQueryPtr q = snot(snear(L"w1", L"w3", 10, true), t); qtest(q, newCollection(0, 1, 3)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/SpansAdvanced2Test.cpp b/src/test/search/spans/SpansAdvanced2Test.cpp index e1ecfd9b..e2668257 100644 --- a/src/test/search/spans/SpansAdvanced2Test.cpp +++ b/src/test/search/spans/SpansAdvanced2Test.cpp @@ -23,10 +23,10 @@ using namespace Lucene; -class SpansAdvanced2Fixture : public LuceneTestFixture +class SpansAdvanced2Test : public LuceneTestFixture { public: - SpansAdvanced2Fixture() + SpansAdvanced2Test() { // create test index directory = newLucene(); @@ -41,12 +41,12 @@ class SpansAdvanced2Fixture : public LuceneTestFixture addDocument(writer, L"D", L"Should we, should we, should we."); writer->close(); searcher = newLucene(directory, true); - + // re-open the searcher since we added more docs searcher2 = newLucene(directory, true); } - - virtual ~SpansAdvanced2Fixture() + + virtual ~SpansAdvanced2Test() { searcher->close(); searcher2->close(); @@ -61,7 +61,7 @@ class SpansAdvanced2Fixture : public LuceneTestFixture DirectoryPtr directory; IndexSearcherPtr searcher; IndexSearcherPtr searcher2; - + void addDocument(IndexWriterPtr writer, const String& id, const String& text) { DocumentPtr document = newLucene(); @@ -69,7 +69,7 @@ class SpansAdvanced2Fixture : public LuceneTestFixture document->add(newLucene(FIELD_TEXT, text, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(document); } - + void checkHits(SearcherPtr s, QueryPtr query, const String& description, Collection expectedIds, Collection expectedScores) { QueryUtils::check(query, s); @@ -80,37 +80,35 @@ class SpansAdvanced2Fixture : public LuceneTestFixture TopDocsPtr topdocs = s->search(query, FilterPtr(), 10000); // did we get the hits we expected - BOOST_CHECK_EQUAL(expectedIds.size(), topdocs->totalHits); - + EXPECT_EQ(expectedIds.size(), topdocs->totalHits); + for (int32_t i = 0; i < topdocs->totalHits; ++i) { int32_t id = topdocs->scoreDocs[i]->doc; double score = topdocs->scoreDocs[i]->score; DocumentPtr doc = s->doc(id); - BOOST_CHECK_EQUAL(expectedIds[i], doc->get(FIELD_ID)); + EXPECT_EQ(expectedIds[i], doc->get(FIELD_ID)); bool scoreEq = (std::abs(expectedScores[i] - score) < tolerance); if (scoreEq) { - BOOST_CHECK_CLOSE_FRACTION(expectedScores[i], score, tolerance); - BOOST_CHECK_CLOSE_FRACTION(s->explain(query, id)->getValue(), score, tolerance); + EXPECT_NEAR(expectedScores[i], score, tolerance); + EXPECT_NEAR(s->explain(query, id)->getValue(), score, tolerance); } } } }; -const String SpansAdvanced2Fixture::FIELD_ID = L"ID"; -const String SpansAdvanced2Fixture::FIELD_TEXT = L"TEXT"; - -BOOST_FIXTURE_TEST_SUITE(SpansAdvanced2Test, SpansAdvanced2Fixture) +const String SpansAdvanced2Test::FIELD_ID = L"ID"; +const String SpansAdvanced2Test::FIELD_TEXT = L"TEXT"; -BOOST_AUTO_TEST_CASE(testVerifyIndex) +TEST_F(SpansAdvanced2Test, testVerifyIndex) { IndexReaderPtr reader = IndexReader::open(directory, true); - BOOST_CHECK_EQUAL(8, reader->numDocs()); + EXPECT_EQ(8, reader->numDocs()); reader->close(); } -BOOST_AUTO_TEST_CASE(testSingleSpanQuery) +TEST_F(SpansAdvanced2Test, testSingleSpanQuery) { QueryPtr spanQuery = newLucene(newLucene(FIELD_TEXT, L"should")); Collection expectedIds = newCollection(L"B", L"D", L"1", L"2", L"3", L"4", L"A"); @@ -118,7 +116,7 @@ BOOST_AUTO_TEST_CASE(testSingleSpanQuery) checkHits(searcher2, spanQuery, L"single span query", expectedIds, expectedScores); } -BOOST_AUTO_TEST_CASE(testMultipleDifferentSpanQueries) +TEST_F(SpansAdvanced2Test, testMultipleDifferentSpanQueries) { QueryPtr spanQuery1 = newLucene(newLucene(FIELD_TEXT, L"should")); QueryPtr spanQuery2 = newLucene(newLucene(FIELD_TEXT, L"we")); @@ -130,7 +128,7 @@ BOOST_AUTO_TEST_CASE(testMultipleDifferentSpanQueries) checkHits(searcher2, query, L"multiple different span queries", expectedIds, expectedScores); } -BOOST_AUTO_TEST_CASE(testBooleanQueryWithSpanQueries) +TEST_F(SpansAdvanced2Test, testBooleanQueryWithSpanQueries) { double expectedScore = 0.73500174; QueryPtr spanQuery = newLucene(newLucene(FIELD_TEXT, L"work")); @@ -141,5 +139,3 @@ BOOST_AUTO_TEST_CASE(testBooleanQueryWithSpanQueries) Collection expectedScores = newCollection(expectedScore, expectedScore, expectedScore, expectedScore); checkHits(searcher2, query, L"two span queries", expectedIds, expectedScores); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/SpansAdvancedTest.cpp b/src/test/search/spans/SpansAdvancedTest.cpp index 4c6b3c31..50e0b907 100644 --- a/src/test/search/spans/SpansAdvancedTest.cpp +++ b/src/test/search/spans/SpansAdvancedTest.cpp @@ -22,10 +22,10 @@ using namespace Lucene; -class SpansAdvancedFixture : public LuceneTestFixture +class SpansAdvancedTest : public LuceneTestFixture { public: - SpansAdvancedFixture() + SpansAdvancedTest() { // create test index directory = newLucene(); @@ -37,8 +37,8 @@ class SpansAdvancedFixture : public LuceneTestFixture writer->close(); searcher = newLucene(directory, true); } - - virtual ~SpansAdvancedFixture() + + virtual ~SpansAdvancedTest() { searcher->close(); directory->close(); @@ -51,7 +51,7 @@ class SpansAdvancedFixture : public LuceneTestFixture protected: DirectoryPtr directory; IndexSearcherPtr searcher; - + void addDocument(IndexWriterPtr writer, const String& id, const String& text) { DocumentPtr document = newLucene(); @@ -59,7 +59,7 @@ class SpansAdvancedFixture : public LuceneTestFixture document->add(newLucene(FIELD_TEXT, text, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(document); } - + void checkHits(SearcherPtr s, QueryPtr query, const String& description, Collection expectedIds, Collection expectedScores) { QueryUtils::check(query, s); @@ -70,30 +70,28 @@ class SpansAdvancedFixture : public LuceneTestFixture TopDocsPtr topdocs = s->search(query, FilterPtr(), 10000); // did we get the hits we expected - BOOST_CHECK_EQUAL(expectedIds.size(), topdocs->totalHits); - + EXPECT_EQ(expectedIds.size(), topdocs->totalHits); + for (int32_t i = 0; i < topdocs->totalHits; ++i) { int32_t id = topdocs->scoreDocs[i]->doc; double score = topdocs->scoreDocs[i]->score; DocumentPtr doc = s->doc(id); - BOOST_CHECK_EQUAL(expectedIds[i], doc->get(FIELD_ID)); + EXPECT_EQ(expectedIds[i], doc->get(FIELD_ID)); bool scoreEq = (std::abs(expectedScores[i] - score) < tolerance); if (scoreEq) { - BOOST_CHECK_CLOSE_FRACTION(expectedScores[i], score, tolerance); - BOOST_CHECK_CLOSE_FRACTION(s->explain(query, id)->getValue(), score, tolerance); + EXPECT_NEAR(expectedScores[i], score, tolerance); + EXPECT_NEAR(s->explain(query, id)->getValue(), score, tolerance); } } } }; -const String SpansAdvancedFixture::FIELD_ID = L"ID"; -const String SpansAdvancedFixture::FIELD_TEXT = L"TEXT"; - -BOOST_FIXTURE_TEST_SUITE(SpansAdvancedTest, SpansAdvancedFixture) +const String SpansAdvancedTest::FIELD_ID = L"ID"; +const String SpansAdvancedTest::FIELD_TEXT = L"TEXT"; -BOOST_AUTO_TEST_CASE(testBooleanQueryWithSpanQueries) +TEST_F(SpansAdvancedTest, testBooleanQueryWithSpanQueries) { double expectedScore = 0.3884282; QueryPtr spanQuery = newLucene(newLucene(FIELD_TEXT, L"work")); @@ -104,5 +102,3 @@ BOOST_AUTO_TEST_CASE(testBooleanQueryWithSpanQueries) Collection expectedScores = newCollection(expectedScore, expectedScore, expectedScore, expectedScore); checkHits(searcher, query, L"two span queries", expectedIds, expectedScores); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/search/spans/SpansTest.cpp b/src/test/search/spans/SpansTest.cpp index 025b5fcf..c3913fbd 100644 --- a/src/test/search/spans/SpansTest.cpp +++ b/src/test/search/spans/SpansTest.cpp @@ -30,10 +30,10 @@ using namespace Lucene; -class SpansFixture : public LuceneTestFixture +class SpansTest : public LuceneTestFixture { public: - SpansFixture() + SpansTest() { docFields = Collection::newInstance(); docFields.add(L"w1 w2 w3 w4 w5"); @@ -59,8 +59,8 @@ class SpansFixture : public LuceneTestFixture writer->close(); searcher = newLucene(directory, true); } - - virtual ~SpansFixture() + + virtual ~SpansTest() { searcher->close(); } @@ -68,7 +68,7 @@ class SpansFixture : public LuceneTestFixture protected: IndexSearcherPtr searcher; Collection docFields; - + public: static const String field; @@ -77,34 +77,34 @@ class SpansFixture : public LuceneTestFixture { return newLucene(newLucene(field, text)); } - + void checkHits(QueryPtr query, Collection results) { CheckHits::checkHits(query, field, searcher, results); } - + void orderedSlopTest3SQ(SpanQueryPtr q1, SpanQueryPtr q2, SpanQueryPtr q3, int32_t slop, Collection expectedDocs) { bool ordered = true; SpanNearQueryPtr snq = newLucene(newCollection(q1, q2, q3), slop, ordered); checkHits(snq, expectedDocs); } - + void orderedSlopTest3(int32_t slop, Collection expectedDocs) { orderedSlopTest3SQ(makeSpanTermQuery(L"w1"), makeSpanTermQuery(L"w2"), makeSpanTermQuery(L"w3"), slop, expectedDocs); } - + void orderedSlopTest3Equal(int32_t slop, Collection expectedDocs) { orderedSlopTest3SQ(makeSpanTermQuery(L"w1"), makeSpanTermQuery(L"w3"), makeSpanTermQuery(L"w3"), slop, expectedDocs); } - + void orderedSlopTest1Equal(int32_t slop, Collection expectedDocs) { orderedSlopTest3SQ(makeSpanTermQuery(L"u2"), makeSpanTermQuery(L"u2"), makeSpanTermQuery(L"u1"), slop, expectedDocs); } - + SpansPtr orSpans(Collection terms) { Collection sqa = Collection::newInstance(terms.size()); @@ -112,15 +112,15 @@ class SpansFixture : public LuceneTestFixture sqa[i] = makeSpanTermQuery(terms[i]); return newLucene(sqa)->getSpans(searcher->getIndexReader()); } - + void checkNextSpans(SpansPtr spans, int32_t doc, int32_t start, int32_t end) { - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(doc, spans->doc()); - BOOST_CHECK_EQUAL(start, spans->start()); - BOOST_CHECK_EQUAL(end, spans->end()); + EXPECT_TRUE(spans->next()); + EXPECT_EQ(doc, spans->doc()); + EXPECT_EQ(start, spans->start()); + EXPECT_EQ(end, spans->end()); } - + void addDoc(IndexWriterPtr writer, const String& id, const String& text) { DocumentPtr doc = newLucene(); @@ -128,268 +128,266 @@ class SpansFixture : public LuceneTestFixture doc->add(newLucene(L"text", text, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + int32_t hitCount(SearcherPtr searcher, const String& word) { return searcher->search(newLucene(newLucene(L"text", word)), 10)->totalHits; } - + SpanQueryPtr createSpan(const String& value) { return newLucene(newLucene(L"text", value)); } - + SpanQueryPtr createSpan(int32_t slop, bool ordered, Collection clauses) { return newLucene(clauses, slop, ordered); } - + SpanQueryPtr createSpan(int32_t slop, bool ordered, const String& term1, const String& term2) { return createSpan(slop, ordered, newCollection(createSpan(term1), createSpan(term2))); } }; -const String SpansFixture::field = L"field"; +const String SpansTest::field = L"field"; -BOOST_FIXTURE_TEST_SUITE(SpansTest, SpansFixture) - -BOOST_AUTO_TEST_CASE(testSpanNearOrdered01) +TEST_F(SpansTest, testSpanNearOrdered01) { orderedSlopTest3(0, newCollection(0)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrdered02) +TEST_F(SpansTest, testSpanNearOrdered02) { orderedSlopTest3(1, newCollection(0, 1)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrdered03) +TEST_F(SpansTest, testSpanNearOrdered03) { orderedSlopTest3(2, newCollection(0, 1, 2)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrdered04) +TEST_F(SpansTest, testSpanNearOrdered04) { orderedSlopTest3(3, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrdered05) +TEST_F(SpansTest, testSpanNearOrdered05) { orderedSlopTest3(4, newCollection(0, 1, 2, 3)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual01) +TEST_F(SpansTest, testSpanNearOrderedEqual01) { orderedSlopTest3Equal(0, Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual02) +TEST_F(SpansTest, testSpanNearOrderedEqual02) { orderedSlopTest3Equal(1, newCollection(1)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual03) +TEST_F(SpansTest, testSpanNearOrderedEqual03) { orderedSlopTest3Equal(2, newCollection(1)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual04) +TEST_F(SpansTest, testSpanNearOrderedEqual04) { orderedSlopTest3Equal(3, newCollection(1, 3)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual11) +TEST_F(SpansTest, testSpanNearOrderedEqual11) { orderedSlopTest1Equal(0, newCollection(4)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual12) +TEST_F(SpansTest, testSpanNearOrderedEqual12) { orderedSlopTest1Equal(0, newCollection(4)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual13) +TEST_F(SpansTest, testSpanNearOrderedEqual13) { orderedSlopTest1Equal(1, newCollection(4, 5, 6)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual14) +TEST_F(SpansTest, testSpanNearOrderedEqual14) { orderedSlopTest1Equal(2, newCollection(4, 5, 6, 7)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedEqual15) +TEST_F(SpansTest, testSpanNearOrderedEqual15) { orderedSlopTest1Equal(3, newCollection(4, 5, 6, 7)); } -BOOST_AUTO_TEST_CASE(testSpanNearOrderedOverlap) +TEST_F(SpansTest, testSpanNearOrderedOverlap) { bool ordered = true; int32_t slop = 1; SpanNearQueryPtr snq = newLucene(newCollection(makeSpanTermQuery(L"t1"), makeSpanTermQuery(L"t2"), makeSpanTermQuery(L"t3")), slop, ordered); SpansPtr spans = snq->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(11, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); + EXPECT_TRUE(spans->next()); + EXPECT_EQ(11, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(4, spans->end()); - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(11, spans->doc()); - BOOST_CHECK_EQUAL(2, spans->start()); - BOOST_CHECK_EQUAL(6, spans->end()); + EXPECT_TRUE(spans->next()); + EXPECT_EQ(11, spans->doc()); + EXPECT_EQ(2, spans->start()); + EXPECT_EQ(6, spans->end()); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(!spans->next()); } -BOOST_AUTO_TEST_CASE(testSpanNearUnOrdered) +TEST_F(SpansTest, testSpanNearUnOrdered) { SpanNearQueryPtr snq = newLucene(newCollection(makeSpanTermQuery(L"u1"), makeSpanTermQuery(L"u2")), 0, false); SpansPtr spans = snq->getSpans(searcher->getIndexReader()); - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(4, spans->doc()); - BOOST_CHECK_EQUAL(1, spans->start()); - BOOST_CHECK_EQUAL(3, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(5, spans->doc()); - BOOST_CHECK_EQUAL(2, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(8, spans->doc()); - BOOST_CHECK_EQUAL(2, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(9, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(2, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(10, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(2, spans->end()); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(spans->next()); + EXPECT_EQ(4, spans->doc()); + EXPECT_EQ(1, spans->start()); + EXPECT_EQ(3, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(5, spans->doc()); + EXPECT_EQ(2, spans->start()); + EXPECT_EQ(4, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(8, spans->doc()); + EXPECT_EQ(2, spans->start()); + EXPECT_EQ(4, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(9, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(2, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(10, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(2, spans->end()); + EXPECT_TRUE(!spans->next()); SpanNearQueryPtr u1u2 = newLucene(newCollection(makeSpanTermQuery(L"u1"), makeSpanTermQuery(L"u2")), 0, false); snq = newLucene(newCollection(u1u2, makeSpanTermQuery(L"u2")), 1, false); spans = snq->getSpans(searcher->getIndexReader()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(4, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(3, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(4, spans->doc()); - BOOST_CHECK_EQUAL(1, spans->start()); - BOOST_CHECK_EQUAL(3, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(5, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(5, spans->doc()); - BOOST_CHECK_EQUAL(2, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(8, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(8, spans->doc()); - BOOST_CHECK_EQUAL(2, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(9, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(2, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(9, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(4, spans->end()); - - BOOST_CHECK(spans->next()); - BOOST_CHECK_EQUAL(10, spans->doc()); - BOOST_CHECK_EQUAL(0, spans->start()); - BOOST_CHECK_EQUAL(2, spans->end()); - - BOOST_CHECK(!spans->next()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(4, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(3, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(4, spans->doc()); + EXPECT_EQ(1, spans->start()); + EXPECT_EQ(3, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(5, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(4, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(5, spans->doc()); + EXPECT_EQ(2, spans->start()); + EXPECT_EQ(4, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(8, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(4, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(8, spans->doc()); + EXPECT_EQ(2, spans->start()); + EXPECT_EQ(4, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(9, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(2, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(9, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(4, spans->end()); + + EXPECT_TRUE(spans->next()); + EXPECT_EQ(10, spans->doc()); + EXPECT_EQ(0, spans->start()); + EXPECT_EQ(2, spans->end()); + + EXPECT_TRUE(!spans->next()); } -BOOST_AUTO_TEST_CASE(testSpanOrEmpty) +TEST_F(SpansTest, testSpanOrEmpty) { SpansPtr spans = orSpans(Collection::newInstance()); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(!spans->next()); SpanOrQueryPtr a = newLucene(Collection::newInstance()); SpanOrQueryPtr b = newLucene(Collection::newInstance()); - BOOST_CHECK(a->equals(b)); + EXPECT_TRUE(a->equals(b)); } -BOOST_AUTO_TEST_CASE(testSpanOrSingle) +TEST_F(SpansTest, testSpanOrSingle) { SpansPtr spans = orSpans(newCollection(L"w5")); checkNextSpans(spans, 0, 4, 5); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(!spans->next()); } -BOOST_AUTO_TEST_CASE(testSpanOrMovesForward) +TEST_F(SpansTest, testSpanOrMovesForward) { SpansPtr spans = orSpans(newCollection(L"w1", L"xx")); - BOOST_CHECK(spans->next()); + EXPECT_TRUE(spans->next()); int32_t doc = spans->doc(); - BOOST_CHECK_EQUAL(0, doc); + EXPECT_EQ(0, doc); - BOOST_CHECK(spans->skipTo(0)); + EXPECT_TRUE(spans->skipTo(0)); doc = spans->doc(); - BOOST_CHECK_EQUAL(1, doc); + EXPECT_EQ(1, doc); } -BOOST_AUTO_TEST_CASE(testSpanOrDouble) +TEST_F(SpansTest, testSpanOrDouble) { SpansPtr spans = orSpans(newCollection(L"w5", L"yy")); checkNextSpans(spans, 0, 4, 5); checkNextSpans(spans, 2, 3, 4); checkNextSpans(spans, 3, 4, 5); checkNextSpans(spans, 7, 3, 4); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(!spans->next()); } -BOOST_AUTO_TEST_CASE(testSpanOrDoubleSkip) +TEST_F(SpansTest, testSpanOrDoubleSkip) { SpansPtr spans = orSpans(newCollection(L"w5", L"yy")); - BOOST_CHECK(spans->skipTo(3)); - BOOST_CHECK_EQUAL(3, spans->doc()); - BOOST_CHECK_EQUAL(4, spans->start()); - BOOST_CHECK_EQUAL(5, spans->end()); + EXPECT_TRUE(spans->skipTo(3)); + EXPECT_EQ(3, spans->doc()); + EXPECT_EQ(4, spans->start()); + EXPECT_EQ(5, spans->end()); checkNextSpans(spans, 7, 3, 4); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(!spans->next()); } -BOOST_AUTO_TEST_CASE(testSpanOrUnused) +TEST_F(SpansTest, testSpanOrUnused) { SpansPtr spans = orSpans(newCollection(L"w5", L"unusedTerm", L"yy")); checkNextSpans(spans, 0, 4, 5); checkNextSpans(spans, 2, 3, 4); checkNextSpans(spans, 3, 4, 5); checkNextSpans(spans, 7, 3, 4); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(!spans->next()); } -BOOST_AUTO_TEST_CASE(testSpanOrTripleSameDoc) +TEST_F(SpansTest, testSpanOrTripleSameDoc) { SpansPtr spans = orSpans(newCollection(L"t1", L"t2", L"t3")); checkNextSpans(spans, 11, 0, 1); @@ -398,7 +396,7 @@ BOOST_AUTO_TEST_CASE(testSpanOrTripleSameDoc) checkNextSpans(spans, 11, 3, 4); checkNextSpans(spans, 11, 4, 5); checkNextSpans(spans, 11, 5, 6); - BOOST_CHECK(!spans->next()); + EXPECT_TRUE(!spans->next()); } namespace TestSpanScorerZeroSloppyFreq @@ -409,14 +407,14 @@ namespace TestSpanScorerZeroSloppyFreq virtual ~SloppyFreqSimilarity() { } - + public: virtual double sloppyFreq(int32_t distance) { return 0.0; } }; - + class SloppyFreqSpanNearQuery : public SpanNearQuery { public: @@ -424,14 +422,14 @@ namespace TestSpanScorerZeroSloppyFreq { this->sim = sim; } - + virtual ~SloppyFreqSpanNearQuery() { } - + protected: SimilarityPtr sim; - + public: virtual SimilarityPtr getSimilarity(SearcherPtr searcher) { @@ -440,23 +438,23 @@ namespace TestSpanScorerZeroSloppyFreq }; } -BOOST_AUTO_TEST_CASE(testSpanScorerZeroSloppyFreq) +TEST_F(SpansTest, testSpanScorerZeroSloppyFreq) { bool ordered = true; int32_t slop = 1; - + SimilarityPtr sim = newLucene(); SpanNearQueryPtr snq = newLucene(sim, newCollection(makeSpanTermQuery(L"t1"), makeSpanTermQuery(L"t2")), slop, ordered); ScorerPtr spanScorer = snq->weight(searcher)->scorer(searcher->getIndexReader(), true, false); - BOOST_CHECK_NE(spanScorer->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_EQUAL(spanScorer->docID(), 11); + EXPECT_NE(spanScorer->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(spanScorer->docID(), 11); double score = spanScorer->score(); - BOOST_CHECK_EQUAL(score, 0.0); - BOOST_CHECK_EQUAL(spanScorer->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(score, 0.0); + EXPECT_EQ(spanScorer->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); } -BOOST_AUTO_TEST_CASE(testNPESpanQuery) +TEST_F(SpansTest, testNPESpanQuery) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance()), IndexWriter::MaxFieldLengthLIMITED); @@ -473,15 +471,13 @@ BOOST_AUTO_TEST_CASE(testNPESpanQuery) IndexSearcherPtr searcher = newLucene(reader); // Control (make sure docs indexed) - BOOST_CHECK_EQUAL(2, hitCount(searcher, L"the")); - BOOST_CHECK_EQUAL(1, hitCount(searcher, L"cat")); - BOOST_CHECK_EQUAL(1, hitCount(searcher, L"dogs")); - BOOST_CHECK_EQUAL(0, hitCount(searcher, L"rabbit")); + EXPECT_EQ(2, hitCount(searcher, L"the")); + EXPECT_EQ(1, hitCount(searcher, L"cat")); + EXPECT_EQ(1, hitCount(searcher, L"dogs")); + EXPECT_EQ(0, hitCount(searcher, L"rabbit")); // This throws exception (it shouldn't) - BOOST_CHECK_EQUAL(1, searcher->search(createSpan(0, true, newCollection(createSpan(4, false, L"chased", L"cat"), createSpan(L"ate"))), 10)->totalHits); + EXPECT_EQ(1, searcher->search(createSpan(0, true, newCollection(createSpan(4, false, L"chased", L"cat"), createSpan(L"ate"))), 10)->totalHits); reader->close(); dir->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/store/BufferedIndexInputTest.cpp b/src/test/store/BufferedIndexInputTest.cpp index a4f1c37a..5fe0998d 100644 --- a/src/test/store/BufferedIndexInputTest.cpp +++ b/src/test/store/BufferedIndexInputTest.cpp @@ -28,7 +28,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BufferedIndexInputTest, LuceneTestFixture) +typedef LuceneTestFixture BufferedIndexInputTest; class TestableBufferedIndexInputRead : public BufferedIndexInput { @@ -36,7 +36,7 @@ class TestableBufferedIndexInputRead : public BufferedIndexInput TestableBufferedIndexInputRead(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) { } - + virtual ~TestableBufferedIndexInputRead() { } @@ -52,246 +52,246 @@ class TestableBufferedIndexInputRead : public BufferedIndexInput std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); nextByte += length; } - + virtual void seekInternal(int64_t pos) { } - + virtual int64_t length() { return inputLength; } - + virtual IndexInputPtr clone() { return IndexInputPtr(); } }; -BOOST_AUTO_TEST_CASE(testReadInt) +TEST_F(BufferedIndexInputTest, testReadInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 1, 2, 3, 4 }; std::memcpy(inputBytes.get(), input, 4); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 4); - BOOST_CHECK_EQUAL(indexInput.readInt(), 16909060); + EXPECT_EQ(indexInput.readInt(), 16909060); } -BOOST_AUTO_TEST_CASE(testReadVInt) +TEST_F(BufferedIndexInputTest, testReadVInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 200, 201, 150, 96 }; std::memcpy(inputBytes.get(), input, 4); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 4); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 201696456); + EXPECT_EQ(indexInput.readVInt(), 201696456); } -BOOST_AUTO_TEST_CASE(testReadLong) +TEST_F(BufferedIndexInputTest, testReadLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 32, 43, 32, 96, 12, 54, 22, 96 }; std::memcpy(inputBytes.get(), input, 8); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 8); - BOOST_CHECK_EQUAL(indexInput.readLong(), 2317982030106072672LL); + EXPECT_EQ(indexInput.readLong(), 2317982030106072672LL); } -BOOST_AUTO_TEST_CASE(testReadVLong) +TEST_F(BufferedIndexInputTest, testReadVLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 213, 143, 132, 196, 172, 154, 129, 96 }; std::memcpy(inputBytes.get(), input, 8); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 8); - BOOST_CHECK_EQUAL(indexInput.readVLong(), 54048498881988565LL); + EXPECT_EQ(indexInput.readVLong(), 54048498881988565LL); } -BOOST_AUTO_TEST_CASE(testReadString) +TEST_F(BufferedIndexInputTest, testReadString) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 12); - BOOST_CHECK_EQUAL(indexInput.readString(), L"test string"); + EXPECT_EQ(indexInput.readString(), L"test string"); } -BOOST_AUTO_TEST_CASE(testReadModifiedUTF8String) +TEST_F(BufferedIndexInputTest, testReadModifiedUTF8String) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 12); - BOOST_CHECK_EQUAL(indexInput.readModifiedUTF8String(), L"test string"); + EXPECT_EQ(indexInput.readModifiedUTF8String(), L"test string"); } -BOOST_AUTO_TEST_CASE(testReadChars) +TEST_F(BufferedIndexInputTest, testReadChars) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[11] = { 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 11); - + TestableBufferedIndexInputRead indexInput(inputBytes.get(), 11); - + ByteArray outputChars(ByteArray::newInstance(30 * sizeof(wchar_t))); indexInput.readChars((wchar_t*)outputChars.get(), 0, 11); - + wchar_t expected[11] = { L't', L'e', L's', L't', L' ', L's', L't', L'r', L'i', L'n', L'g' }; - BOOST_CHECK_EQUAL(std::memcmp(outputChars.get(), expected, 11 * sizeof(wchar_t)), 0); + EXPECT_EQ(std::memcmp(outputChars.get(), expected, 11 * sizeof(wchar_t)), 0); } -BOOST_AUTO_TEST_CASE(testSkipOneChar) +TEST_F(BufferedIndexInputTest, testSkipOneChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 5); indexInput.skipChars(1); - BOOST_CHECK_EQUAL(indexInput.getFilePointer(), 1); + EXPECT_EQ(indexInput.getFilePointer(), 1); } -BOOST_AUTO_TEST_CASE(testSkipTwoChars) +TEST_F(BufferedIndexInputTest, testSkipTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 5); indexInput.skipChars(2); - BOOST_CHECK_EQUAL(indexInput.getFilePointer(), 2); + EXPECT_EQ(indexInput.getFilePointer(), 2); } -BOOST_AUTO_TEST_CASE(testSkipTwoCharsAdditionalChar) +TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 132, 132, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 5); indexInput.skipChars(2); - BOOST_CHECK_EQUAL(indexInput.getFilePointer(), 3); + EXPECT_EQ(indexInput.getFilePointer(), 3); } -BOOST_AUTO_TEST_CASE(testSkipTwoCharsAdditionalTwoChars) +TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 232, 232, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 5); indexInput.skipChars(2); - BOOST_CHECK_EQUAL(indexInput.getFilePointer(), 4); + EXPECT_EQ(indexInput.getFilePointer(), 4); } -BOOST_AUTO_TEST_CASE(testReadCollection) +TEST_F(BufferedIndexInputTest, testReadCollection) { ByteArray inputBytes(ByteArray::newInstance(100)); - + uint8_t input[88] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, 'L', 'u', 'c', 'e', 'n', 'e', - - // 2-byte UTF-8 (U+00BF "INVERTED QUESTION MARK") + + // 2-byte UTF-8 (U+00BF "INVERTED QUESTION MARK") 0x02, 0xc2, 0xbf, 0x0a, 'L', 'u', 0xc2, 0xbf, 'c', 'e', 0xc2, 0xbf, 'n', 'e', - - // 3-byte UTF-8 (U+2620 "SKULL AND CROSSBONES") + + // 3-byte UTF-8 (U+2620 "SKULL AND CROSSBONES") 0x03, 0xe2, 0x98, 0xa0, 0x0c, 'L', 'u', 0xe2, 0x98, 0xa0, 'c', 'e', 0xe2, 0x98, 0xa0, 'n', 'e', - + // surrogate pairs // (U+1D11E "MUSICAL SYMBOL G CLEF") // (U+1D160 "MUSICAL SYMBOL EIGHTH NOTE") 0x04, 0xf0, 0x9d, 0x84, 0x9e, 0x08, 0xf0, 0x9d, 0x84, 0x9e, 0xf0, 0x9d, 0x85, 0xa0, 0x0e, 'L', 'u', 0xf0, 0x9d, 0x84, 0x9e, 'c', 'e', 0xf0, 0x9d, 0x85, 0xa0, 'n', 'e', - + // null bytes 0x01, 0x00, 0x08, 'L', 'u', 0x00, 'c', 'e', 0x00, 'n', 'e'}; std::memcpy(inputBytes.get(), input, 88); - + TestableBufferedIndexInputRead indexInput(inputBytes.get(), 88); indexInput.setBufferSize(10); - - BOOST_CHECK_EQUAL(indexInput.readVInt(), 128); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 16383); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 16384); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 16385); - BOOST_CHECK_EQUAL(indexInput.readString(), L"Lucene"); - + + EXPECT_EQ(indexInput.readVInt(), 128); + EXPECT_EQ(indexInput.readVInt(), 16383); + EXPECT_EQ(indexInput.readVInt(), 16384); + EXPECT_EQ(indexInput.readVInt(), 16385); + EXPECT_EQ(indexInput.readString(), L"Lucene"); + const uint8_t question[] = {0xc2, 0xbf}; - BOOST_CHECK_EQUAL(indexInput.readString(), UTF8_TO_STRING(question)); + EXPECT_EQ(indexInput.readString(), UTF8_TO_STRING(question)); const uint8_t skull[] = {0x4c, 0x75, 0xc2, 0xbf, 0x63, 0x65, 0xc2, 0xbf, 0x6e, 0x65}; - BOOST_CHECK_EQUAL(indexInput.readString(), UTF8_TO_STRING(skull)); + EXPECT_EQ(indexInput.readString(), UTF8_TO_STRING(skull)); const uint8_t gclef[] = {0xe2, 0x98, 0xa0}; - BOOST_CHECK_EQUAL(indexInput.readString(), UTF8_TO_STRING(gclef)); + EXPECT_EQ(indexInput.readString(), UTF8_TO_STRING(gclef)); const uint8_t eighthnote[] = {0x4c, 0x75, 0xe2, 0x98, 0xa0, 0x63, 0x65, 0xe2, 0x98, 0xa0, 0x6e, 0x65}; - BOOST_CHECK_EQUAL(indexInput.readString(), UTF8_TO_STRING(eighthnote)); - + EXPECT_EQ(indexInput.readString(), UTF8_TO_STRING(eighthnote)); + String readString(indexInput.readString()); - + #ifdef LPP_UNICODE_CHAR_SIZE_2 - BOOST_CHECK_EQUAL(readString[0], 55348); - BOOST_CHECK_EQUAL(readString[1], 56606); + EXPECT_EQ(readString[0], 55348); + EXPECT_EQ(readString[1], 56606); #else - BOOST_CHECK_EQUAL(readString[0], 119070); + EXPECT_EQ(readString[0], 119070); #endif - + readString = indexInput.readString(); - + #ifdef LPP_UNICODE_CHAR_SIZE_2 - BOOST_CHECK_EQUAL(readString[0], 55348); - BOOST_CHECK_EQUAL(readString[1], 56606); - BOOST_CHECK_EQUAL(readString[2], 55348); - BOOST_CHECK_EQUAL(readString[3], 56672); + EXPECT_EQ(readString[0], 55348); + EXPECT_EQ(readString[1], 56606); + EXPECT_EQ(readString[2], 55348); + EXPECT_EQ(readString[3], 56672); #else - BOOST_CHECK_EQUAL(readString[0], 119070); - BOOST_CHECK_EQUAL(readString[1], 119136); + EXPECT_EQ(readString[0], 119070); + EXPECT_EQ(readString[1], 119136); #endif - + readString = indexInput.readString(); #ifdef LPP_UNICODE_CHAR_SIZE_2 - BOOST_CHECK_EQUAL(readString[0], L'L'); - BOOST_CHECK_EQUAL(readString[1], L'u'); - BOOST_CHECK_EQUAL(readString[2], 55348); - BOOST_CHECK_EQUAL(readString[3], 56606); - BOOST_CHECK_EQUAL(readString[4], L'c'); - BOOST_CHECK_EQUAL(readString[5], L'e'); - BOOST_CHECK_EQUAL(readString[6], 55348); - BOOST_CHECK_EQUAL(readString[7], 56672); - BOOST_CHECK_EQUAL(readString[8], L'n'); - BOOST_CHECK_EQUAL(readString[9], L'e'); + EXPECT_EQ(readString[0], L'L'); + EXPECT_EQ(readString[1], L'u'); + EXPECT_EQ(readString[2], 55348); + EXPECT_EQ(readString[3], 56606); + EXPECT_EQ(readString[4], L'c'); + EXPECT_EQ(readString[5], L'e'); + EXPECT_EQ(readString[6], 55348); + EXPECT_EQ(readString[7], 56672); + EXPECT_EQ(readString[8], L'n'); + EXPECT_EQ(readString[9], L'e'); #else - BOOST_CHECK_EQUAL(readString[0], L'L'); - BOOST_CHECK_EQUAL(readString[1], L'u'); - BOOST_CHECK_EQUAL(readString[2], 119070); - BOOST_CHECK_EQUAL(readString[3], L'c'); - BOOST_CHECK_EQUAL(readString[4], L'e'); - BOOST_CHECK_EQUAL(readString[5], 119136); - BOOST_CHECK_EQUAL(readString[6], L'n'); - BOOST_CHECK_EQUAL(readString[7], L'e'); + EXPECT_EQ(readString[0], L'L'); + EXPECT_EQ(readString[1], L'u'); + EXPECT_EQ(readString[2], 119070); + EXPECT_EQ(readString[3], L'c'); + EXPECT_EQ(readString[4], L'e'); + EXPECT_EQ(readString[5], 119136); + EXPECT_EQ(readString[6], L'n'); + EXPECT_EQ(readString[7], L'e'); #endif - + readString = indexInput.readString(); - BOOST_CHECK_EQUAL(readString[0], 0); - + EXPECT_EQ(readString[0], 0); + readString = indexInput.readString(); - BOOST_CHECK_EQUAL(readString[0], L'L'); - BOOST_CHECK_EQUAL(readString[1], L'u'); - BOOST_CHECK_EQUAL(readString[2], 0); - BOOST_CHECK_EQUAL(readString[3], L'c'); - BOOST_CHECK_EQUAL(readString[4], L'e'); - BOOST_CHECK_EQUAL(readString[5], 0); - BOOST_CHECK_EQUAL(readString[6], L'n'); - BOOST_CHECK_EQUAL(readString[7], L'e'); + EXPECT_EQ(readString[0], L'L'); + EXPECT_EQ(readString[1], L'u'); + EXPECT_EQ(readString[2], 0); + EXPECT_EQ(readString[3], L'c'); + EXPECT_EQ(readString[4], L'e'); + EXPECT_EQ(readString[5], 0); + EXPECT_EQ(readString[6], L'n'); + EXPECT_EQ(readString[7], L'e'); } -BOOST_AUTO_TEST_CASE(testSkipCollection) +TEST_F(BufferedIndexInputTest, testSkipCollection) { ByteArray inputBytes(ByteArray::newInstance(100)); uint8_t input[17] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, 'L', 'u', 'c', 'e', 'n', 'e'}; std::memcpy(inputBytes.get(), input, 17); - + TestableBufferedIndexInputRead indexInput(inputBytes.get(), 17); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 128); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 16383); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 16384); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 16385); - BOOST_CHECK_EQUAL(indexInput.readVInt(), 6); + EXPECT_EQ(indexInput.readVInt(), 128); + EXPECT_EQ(indexInput.readVInt(), 16383); + EXPECT_EQ(indexInput.readVInt(), 16384); + EXPECT_EQ(indexInput.readVInt(), 16385); + EXPECT_EQ(indexInput.readVInt(), 6); indexInput.skipChars(3); ByteArray remainingBytes(ByteArray::newInstance(4 * sizeof(wchar_t))); indexInput.readChars((wchar_t*)remainingBytes.get(), 0, 3); - BOOST_CHECK_EQUAL(String((wchar_t*)remainingBytes.get(), 3), L"ene"); + EXPECT_EQ(String((wchar_t*)remainingBytes.get(), 3), L"ene"); } // byten emulates a file - byten(n) returns the n'th byte in that file. @@ -317,7 +317,7 @@ class MyBufferedIndexInput : public BufferedIndexInput this->len = LLONG_MAX; // an infinite file this->pos = 0; } - + MyBufferedIndexInput(int64_t len) { this->len = len; @@ -330,7 +330,7 @@ class MyBufferedIndexInput : public BufferedIndexInput for (int32_t i = offset; i < (offset + length); ++i) b[i] = byten(pos++); } - + virtual void seekInternal(int64_t pos) { this->pos = pos; @@ -340,7 +340,7 @@ class MyBufferedIndexInput : public BufferedIndexInput virtual void close() { } - + virtual int64_t length() { return len; @@ -355,37 +355,37 @@ DECLARE_SHARED_PTR(MyBufferedIndexInput) // Call readByte() repeatedly, past the buffer boundary, and see that it is working as expected. // Our input comes from a dynamically generated/ "file" - see MyBufferedIndexInput. -BOOST_AUTO_TEST_CASE(testReadByte) +TEST_F(BufferedIndexInputTest, testReadByte) { MyBufferedIndexInputPtr input(newLucene()); for (int32_t i = 0; i < BufferedIndexInput::BUFFER_SIZE * 10; ++i) - BOOST_CHECK_EQUAL(input->readByte(), byten(i)); + EXPECT_EQ(input->readByte(), byten(i)); } void checkReadBytes(IndexInputPtr input, int32_t size, int32_t pos) { - // Just to see that "offset" is treated properly in readBytes(), we add an arbitrary offset at + // Just to see that "offset" is treated properly in readBytes(), we add an arbitrary offset at // the beginning of the array int32_t offset = size % 10; // arbitrary ByteArray buffer(ByteArray::newInstance(10)); buffer.resize(MiscUtils::getNextSize(offset + size)); - BOOST_CHECK_EQUAL(pos, input->getFilePointer()); + EXPECT_EQ(pos, input->getFilePointer()); int64_t left = TEST_FILE_LENGTH - input->getFilePointer(); if (left <= 0) return; else if (left < size) size = (int32_t)left; input->readBytes(buffer.get(), offset, size); - BOOST_CHECK_EQUAL(pos + size, input->getFilePointer()); + EXPECT_EQ(pos + size, input->getFilePointer()); for (int32_t i = 0; i < size; ++i) - BOOST_CHECK_EQUAL(byten(pos + i), buffer[offset + i]); + EXPECT_EQ(byten(pos + i), buffer[offset + i]); } void runReadBytes(IndexInputPtr input, int32_t bufferSize) { int32_t pos = 0; RandomPtr random = newLucene(); - + // gradually increasing size for (int32_t size = 1; size < bufferSize * 10; size = size + size / 200 + 1) { @@ -440,58 +440,79 @@ void runReadBytesAndClose(IndexInputPtr input, int32_t bufferSize) finally.throwException(); } -// Call readBytes() repeatedly, with various chunk sizes (from 1 byte to larger than the buffer size), and see +// Call readBytes() repeatedly, with various chunk sizes (from 1 byte to larger than the buffer size), and see // that it returns the bytes we expect. Our input comes from a dynamically generated "file" - see MyBufferedIndexInput. -BOOST_AUTO_TEST_CASE(testReadBytes) +TEST_F(BufferedIndexInputTest, testReadBytes) { MyBufferedIndexInputPtr input(newLucene()); runReadBytes(input, BufferedIndexInput::BUFFER_SIZE); - + int32_t inputBufferSize = 128; String tmpInputFile(getTempDir(L"IndexInput")); std::ofstream file(StringUtils::toUTF8(tmpInputFile).c_str(), std::ios::binary | std::ios::out); writeBytes(file, TEST_FILE_LENGTH); - + // run test with chunk size of 10 bytes runReadBytesAndClose(newLucene(tmpInputFile, inputBufferSize, 10), inputBufferSize); - + // run test with chunk size of 100 MB - default runReadBytesAndClose(newLucene(tmpInputFile, inputBufferSize, FSDirectory::DEFAULT_READ_CHUNK_SIZE), inputBufferSize); - + FileUtils::removeFile(tmpInputFile); } -// This tests that attempts to readBytes() past an EOF will fail, while reads up to the EOF will succeed. The +// This tests that attempts to readBytes() past an EOF will fail, while reads up to the EOF will succeed. The // EOF is determined by the BufferedIndexInput's arbitrary length() value. -BOOST_AUTO_TEST_CASE(testEOF) +TEST_F(BufferedIndexInputTest, testEOF) { MyBufferedIndexInputPtr input(newLucene(1024)); - + // see that we can read all the bytes at one go checkReadBytes(input, (int32_t)input->length(), 0); - + // go back and see that we can't read more than that, for small and large overflows int32_t pos = (int32_t)input->length() - 10; input->seek(pos); checkReadBytes(input, 10, pos); input->seek(pos); - - BOOST_CHECK_EXCEPTION(checkReadBytes(input, 11, pos), LuceneException, check_exception(LuceneException::IO)); - + + try + { + checkReadBytes(input, 11, pos); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + input->seek(pos); - - BOOST_CHECK_EXCEPTION(checkReadBytes(input, 50, pos), LuceneException, check_exception(LuceneException::IO)); - + + try + { + checkReadBytes(input, 50, pos); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } + input->seek(pos); - - BOOST_CHECK_EXCEPTION(checkReadBytes(input, 100000, pos), LuceneException, check_exception(LuceneException::IO)); + + try + { + checkReadBytes(input, 100000, pos); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IO)(e)); + } } -BOOST_AUTO_TEST_CASE(testSetBufferSize) +TEST_F(BufferedIndexInputTest, testSetBufferSize) { String indexDir(getTempDir(L"testSetBufferSize")); MockFSDirectoryPtr dir = newLucene(indexDir); - + LuceneException finally; try { @@ -505,32 +526,32 @@ BOOST_AUTO_TEST_CASE(testSetBufferSize) writer->addDocument(doc); } writer->close(); - + dir->allIndexInputs.clear(); - + IndexReaderPtr reader = IndexReader::open(dir, false); TermPtr aaa = newLucene(L"content", L"aaa"); TermPtr bbb = newLucene(L"content", L"bbb"); TermPtr ccc = newLucene(L"content", L"ccc"); - BOOST_CHECK_EQUAL(reader->docFreq(ccc), 37); + EXPECT_EQ(reader->docFreq(ccc), 37); reader->deleteDocument(0); - BOOST_CHECK_EQUAL(reader->docFreq(aaa), 37); + EXPECT_EQ(reader->docFreq(aaa), 37); dir->tweakBufferSizes(); reader->deleteDocument(4); - BOOST_CHECK_EQUAL(reader->docFreq(bbb), 37); + EXPECT_EQ(reader->docFreq(bbb), 37); dir->tweakBufferSizes(); - + IndexSearcherPtr searcher = newLucene(reader); Collection hits = searcher->search(newLucene(bbb), FilterPtr(), 1000)->scoreDocs; dir->tweakBufferSizes(); - BOOST_CHECK_EQUAL(hits.size(), 35); + EXPECT_EQ(hits.size(), 35); dir->tweakBufferSizes(); hits = searcher->search(newLucene(newLucene(L"id", L"33")), FilterPtr(), 1000)->scoreDocs; dir->tweakBufferSizes(); - BOOST_CHECK_EQUAL(hits.size(), 1); + EXPECT_EQ(hits.size(), 1); hits = searcher->search(newLucene(aaa), FilterPtr(), 1000)->scoreDocs; dir->tweakBufferSizes(); - BOOST_CHECK_EQUAL(hits.size(), 35); + EXPECT_EQ(hits.size(), 35); searcher->close(); reader->close(); } @@ -541,5 +562,3 @@ BOOST_AUTO_TEST_CASE(testSetBufferSize) FileUtils::removeDirectory(indexDir); finally.throwException(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/store/BufferedIndexOutputTest.cpp b/src/test/store/BufferedIndexOutputTest.cpp index ab5bf177..6c091090 100644 --- a/src/test/store/BufferedIndexOutputTest.cpp +++ b/src/test/store/BufferedIndexOutputTest.cpp @@ -11,23 +11,23 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BufferedIndexOutputTest, LuceneTestFixture) +typedef LuceneTestFixture BufferedIndexOutputTest; class TestableBufferedIndexOutput : public BufferedIndexOutput { public: using BufferedIndexOutput::writeBytes; - + TestableBufferedIndexOutput(uint8_t* b, int32_t length) : outputBytes(b), outputLength(length), nextByte(0) { } - + virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length) { std::copy(b + offset, b + offset + length, outputBytes + nextByte + offset); nextByte += length; } - + virtual int64_t length() { return outputLength; @@ -39,70 +39,70 @@ class TestableBufferedIndexOutput : public BufferedIndexOutput int32_t nextByte; }; -BOOST_AUTO_TEST_CASE(testWriteInt) +TEST_F(BufferedIndexOutputTest, testWriteInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeInt(1234); indexOutput.flush(); - BOOST_CHECK_EQUAL(indexOutput.getFilePointer(), 4); + EXPECT_EQ(indexOutput.getFilePointer(), 4); uint8_t expected[4] = { 0, 0, 4, 210 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 4), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 4), 0); } -BOOST_AUTO_TEST_CASE(testWriteVInt) +TEST_F(BufferedIndexOutputTest, testWriteVInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVInt(1234); indexOutput.flush(); - BOOST_CHECK_EQUAL(indexOutput.getFilePointer(), 2); + EXPECT_EQ(indexOutput.getFilePointer(), 2); uint8_t expected[2] = { 210, 9 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 2), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 2), 0); } -BOOST_AUTO_TEST_CASE(testWriteLong) +TEST_F(BufferedIndexOutputTest, testWriteLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeLong(1234123412341234LL); indexOutput.flush(); - BOOST_CHECK_EQUAL(indexOutput.getFilePointer(), 8); + EXPECT_EQ(indexOutput.getFilePointer(), 8); uint8_t expected[8] = { 0, 4, 98, 109, 191, 154, 1, 242 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 8), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -BOOST_AUTO_TEST_CASE(testWriteVLong) +TEST_F(BufferedIndexOutputTest, testWriteVLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVLong(1234123412341234LL); indexOutput.flush(); - BOOST_CHECK_EQUAL(indexOutput.getFilePointer(), 8); + EXPECT_EQ(indexOutput.getFilePointer(), 8); uint8_t expected[8] = { 242, 131, 232, 252, 219, 205, 152, 2 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 8), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -BOOST_AUTO_TEST_CASE(testWriteString) +TEST_F(BufferedIndexOutputTest, testWriteString) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeString(L"test string"); indexOutput.flush(); - BOOST_CHECK_EQUAL(indexOutput.getFilePointer(), 12); + EXPECT_EQ(indexOutput.getFilePointer(), 12); uint8_t expected[12] = { 11, 116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 103 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 12), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 12), 0); } -BOOST_AUTO_TEST_CASE(testWriteChars) +TEST_F(BufferedIndexOutputTest, testWriteChars) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeChars(L"test string", 5, 6); indexOutput.flush(); - BOOST_CHECK_EQUAL(indexOutput.getFilePointer(), 6); + EXPECT_EQ(indexOutput.getFilePointer(), 6); uint8_t expected[6] = { 115, 116, 114, 105, 110, 103 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 6), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 6), 0); } namespace TestCopyBytes @@ -113,27 +113,27 @@ namespace TestCopyBytes SourceIndexInput(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) { } - + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) { std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); nextByte += length; } - + virtual void seekInternal(int64_t pos) { } - + virtual int64_t length() { return inputLength; } - + virtual IndexInputPtr clone() { return IndexInputPtr(); } - + protected: const uint8_t* inputBytes; int32_t inputLength; @@ -141,19 +141,17 @@ namespace TestCopyBytes }; } -BOOST_AUTO_TEST_CASE(testCopyBytes) +TEST_F(BufferedIndexOutputTest, testCopyBytes) { ByteArray sourceBytes(ByteArray::newInstance(32768)); std::generate(sourceBytes.get(), sourceBytes.get() + 32768, rand); BufferedIndexInputPtr indexSource(newLucene(sourceBytes.get(), 32768)); - + ByteArray outputBytes(ByteArray::newInstance(32768)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 32768); - + indexOutput.copyBytes(indexSource, 20000); indexOutput.flush(); - - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), sourceBytes.get(), 20000), 0); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(memcmp(outputBytes.get(), sourceBytes.get(), 20000), 0); +} diff --git a/src/test/store/DirectoryTest.cpp b/src/test/store/DirectoryTest.cpp index c07fca56..8b8542b3 100644 --- a/src/test/store/DirectoryTest.cpp +++ b/src/test/store/DirectoryTest.cpp @@ -19,70 +19,91 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(DirectoryTest, LuceneTestFixture) +typedef LuceneTestFixture DirectoryTest; -BOOST_AUTO_TEST_CASE(testDetectDirectoryClose) +TEST_F(DirectoryTest, testDetectDirectoryClose) { RAMDirectoryPtr dir(newLucene()); dir->close(); - BOOST_CHECK_EXCEPTION(dir->createOutput(L"test"), LuceneException, check_exception(LuceneException::AlreadyClosed)); + try + { + dir->createOutput(L"test"); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } } -BOOST_AUTO_TEST_CASE(testDetectFSDirectoryClose) +TEST_F(DirectoryTest, testDetectFSDirectoryClose) { DirectoryPtr dir = FSDirectory::open(getTempDir()); dir->close(); - BOOST_CHECK_EXCEPTION(dir->createOutput(L"test"), LuceneException, check_exception(LuceneException::AlreadyClosed)); + try + { + dir->createOutput(L"test"); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); + } } template < class FSDirectory1, class FSDirectory2 > void TestInstantiationPair(FSDirectory1& first, FSDirectory2& second, const String& fileName, const String& lockName) { - BOOST_CHECK_NO_THROW(first.ensureOpen()); - + EXPECT_NO_THROW(first.ensureOpen()); + IndexOutputPtr out = first.createOutput(fileName); - BOOST_CHECK_NO_THROW(out->writeByte(123)); - BOOST_CHECK_NO_THROW(out->close()); - - BOOST_CHECK_NO_THROW(first.ensureOpen()); - BOOST_CHECK(first.fileExists(fileName)); - BOOST_CHECK_EQUAL(first.fileLength(fileName), 1); - + EXPECT_NO_THROW(out->writeByte(123)); + EXPECT_NO_THROW(out->close()); + + EXPECT_NO_THROW(first.ensureOpen()); + EXPECT_TRUE(first.fileExists(fileName)); + EXPECT_EQ(first.fileLength(fileName), 1); + // don't test read on MMapDirectory, since it can't really be closed and will cause a failure to delete the file. if (!first.isMMapDirectory()) { IndexInputPtr input = first.openInput(fileName); - BOOST_CHECK_EQUAL(input->readByte(), 123); - BOOST_CHECK_NO_THROW(input->close()); + EXPECT_EQ(input->readByte(), 123); + EXPECT_NO_THROW(input->close()); } - - BOOST_CHECK_NO_THROW(second.ensureOpen()); - BOOST_CHECK(second.fileExists(fileName)); - BOOST_CHECK_EQUAL(second.fileLength(fileName), 1); - + + EXPECT_NO_THROW(second.ensureOpen()); + EXPECT_TRUE(second.fileExists(fileName)); + EXPECT_EQ(second.fileLength(fileName), 1); + if (!second.isMMapDirectory()) { IndexInputPtr input = second.openInput(fileName); - BOOST_CHECK_EQUAL(input->readByte(), 123); - BOOST_CHECK_NO_THROW(input->close()); + EXPECT_EQ(input->readByte(), 123); + EXPECT_NO_THROW(input->close()); } - + // delete with a different dir second.deleteFile(fileName); - - BOOST_CHECK(!first.fileExists(fileName)); - BOOST_CHECK(!second.fileExists(fileName)); - + + EXPECT_TRUE(!first.fileExists(fileName)); + EXPECT_TRUE(!second.fileExists(fileName)); + LockPtr lock = first.makeLock(lockName); - BOOST_CHECK(lock->obtain()); - + EXPECT_TRUE(lock->obtain()); + LockPtr lock2 = first.makeLock(lockName); - BOOST_CHECK_EXCEPTION(lock2->obtain(1), LuceneException, check_exception(LuceneException::LockObtainFailed)); - + try + { + lock2->obtain(1); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } + lock->release(); - + lock = second.makeLock(lockName); - BOOST_CHECK(lock->obtain()); + EXPECT_TRUE(lock->obtain()); lock->release(); } @@ -109,7 +130,7 @@ namespace TestDirectInstantiation // Test that different instances of FSDirectory can coexist on the same // path, can read, write, and lock files. -BOOST_AUTO_TEST_CASE(testDirectInstantiation) +TEST_F(DirectoryTest, testDirectInstantiation) { TestDirectInstantiation::TestableSimpleFSDirectory fsDir(getTempDir()); fsDir.ensureOpen(); @@ -121,14 +142,14 @@ BOOST_AUTO_TEST_CASE(testDirectInstantiation) TestInstantiationPair(mmapDir, fsDir, L"foo.1", L"foo1.lck"); } -BOOST_AUTO_TEST_CASE(testDontCreate) +TEST_F(DirectoryTest, testDontCreate) { String path(FileUtils::joinPath(getTempDir(), L"doesnotexist")); try { - BOOST_CHECK(!FileUtils::fileExists(path)); + EXPECT_TRUE(!FileUtils::fileExists(path)); SimpleFSDirectoryPtr fsDir(newLucene(path)); - BOOST_CHECK(!FileUtils::fileExists(path)); + EXPECT_TRUE(!FileUtils::fileExists(path)); } catch (...) { @@ -140,22 +161,22 @@ void checkDirectoryFilter(DirectoryPtr dir) { String name(L"file"); dir->createOutput(name)->close(); - BOOST_CHECK(dir->fileExists(name)); + EXPECT_TRUE(dir->fileExists(name)); HashSet dirFiles(dir->listAll()); - BOOST_CHECK(dirFiles.contains(name)); + EXPECT_TRUE(dirFiles.contains(name)); } -BOOST_AUTO_TEST_CASE(testRAMDirectoryFilter) +TEST_F(DirectoryTest, testRAMDirectoryFilter) { checkDirectoryFilter(newLucene()); } -BOOST_AUTO_TEST_CASE(testFSDirectoryFilter) +TEST_F(DirectoryTest, testFSDirectoryFilter) { checkDirectoryFilter(newLucene(getTempDir())); } -BOOST_AUTO_TEST_CASE(testCopySubdir) +TEST_F(DirectoryTest, testCopySubdir) { String path(FileUtils::joinPath(getTempDir(), L"testsubdir")); try @@ -164,7 +185,7 @@ BOOST_AUTO_TEST_CASE(testCopySubdir) String subpath(FileUtils::joinPath(path, L"subdir")); FileUtils::createDirectory(subpath); SimpleFSDirectoryPtr fsDir(newLucene(path)); - BOOST_CHECK(newLucene(fsDir)->listAll().empty()); + EXPECT_TRUE(newLucene(fsDir)->listAll().empty()); } catch (...) { @@ -172,7 +193,7 @@ BOOST_AUTO_TEST_CASE(testCopySubdir) FileUtils::removeDirectory(path); } -BOOST_AUTO_TEST_CASE(testNotDirectory) +TEST_F(DirectoryTest, testNotDirectory) { String path(FileUtils::joinPath(getTempDir(), L"testnotdir")); SimpleFSDirectoryPtr fsDir(newLucene(path)); @@ -180,13 +201,18 @@ BOOST_AUTO_TEST_CASE(testNotDirectory) { IndexOutputPtr out = fsDir->createOutput(L"afile"); out->close(); - BOOST_CHECK(fsDir->fileExists(L"afile")); - BOOST_CHECK_EXCEPTION(newLucene(FileUtils::joinPath(path, L"afile")), LuceneException, check_exception(LuceneException::NoSuchDirectory)); + EXPECT_TRUE(fsDir->fileExists(L"afile")); + try + { + newLucene(FileUtils::joinPath(path, L"afile")); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); + } } catch (...) { } FileUtils::removeDirectory(path); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/store/FileSwitchDirectoryTest.cpp b/src/test/store/FileSwitchDirectoryTest.cpp index 6acb19e6..6dc80e39 100644 --- a/src/test/store/FileSwitchDirectoryTest.cpp +++ b/src/test/store/FileSwitchDirectoryTest.cpp @@ -16,7 +16,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(FileSwitchDirectoryTest, LuceneTestFixture) +typedef LuceneTestFixture FileSwitchDirectoryTest; static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t numFields) { @@ -41,7 +41,7 @@ static void createIndexNoClose(bool multiSegment, const String& indexName, Index } // Test if writing doc stores to disk and everything else to ram works. -BOOST_AUTO_TEST_CASE(testBasic) +TEST_F(FileSwitchDirectoryTest, testBasic) { HashSet fileExtensions(HashSet::newInstance()); fileExtensions.add(L"fdt"); @@ -49,37 +49,35 @@ BOOST_AUTO_TEST_CASE(testBasic) DirectoryPtr primaryDir(newLucene()); RAMDirectoryPtr secondaryDir(newLucene()); - + FileSwitchDirectoryPtr fsd(newLucene(fileExtensions, primaryDir, secondaryDir, true)); IndexWriterPtr writer(newLucene(fsd, newLucene(), IndexWriter::MaxFieldLengthLIMITED)); writer->setUseCompoundFile(false); createIndexNoClose(true, L"ram", writer); IndexReaderPtr reader = writer->getReader(); - BOOST_CHECK_EQUAL(reader->maxDoc(), 100); + EXPECT_EQ(reader->maxDoc(), 100); writer->commit(); // we should see only fdx,fdt files here HashSet files = primaryDir->listAll(); - BOOST_CHECK(!files.empty()); + EXPECT_TRUE(!files.empty()); for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { String ext = FileSwitchDirectory::getExtension(*file); - BOOST_CHECK(fileExtensions.contains(ext)); + EXPECT_TRUE(fileExtensions.contains(ext)); } files = secondaryDir->listAll(); - BOOST_CHECK(!files.empty()); + EXPECT_TRUE(!files.empty()); // we should not see fdx,fdt files here for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { String ext = FileSwitchDirectory::getExtension(*file); - BOOST_CHECK(!fileExtensions.contains(ext)); + EXPECT_TRUE(!fileExtensions.contains(ext)); } reader->close(); writer->close(); files = fsd->listAll(); for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - BOOST_CHECK(!file->empty()); + EXPECT_TRUE(!file->empty()); fsd->close(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/store/IndexOutputTest.cpp b/src/test/store/IndexOutputTest.cpp index dd506af1..03136428 100644 --- a/src/test/store/IndexOutputTest.cpp +++ b/src/test/store/IndexOutputTest.cpp @@ -11,36 +11,36 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(IndexOutputTest, LuceneTestFixture) +typedef LuceneTestFixture IndexOutputTest; class TestableIndexOutput : public IndexOutput { public: using IndexOutput::writeBytes; - + TestableIndexOutput(uint8_t* b, int32_t length) : outputBytes(b), outputLength(length), nextByte(0) { } - + virtual ~TestableIndexOutput() { } - + virtual void writeByte(uint8_t b) { outputBytes[nextByte++] = b; } - + virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length) { std::copy(b + offset, b + offset + length, outputBytes + nextByte + offset); nextByte += length; } - + virtual void flush() { } - + virtual void close() { } @@ -49,16 +49,16 @@ class TestableIndexOutput : public IndexOutput { return 0; } - + virtual void seek(int64_t pos) { } - + virtual int64_t length() { return 0; } - + int32_t getNextPosition() { return nextByte; @@ -70,64 +70,64 @@ class TestableIndexOutput : public IndexOutput int32_t nextByte; }; -BOOST_AUTO_TEST_CASE(testWriteInt) +TEST_F(IndexOutputTest, testWriteInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeInt(1234); - BOOST_CHECK_EQUAL(indexOutput.getNextPosition(), 4); + EXPECT_EQ(indexOutput.getNextPosition(), 4); uint8_t expected[4] = { 0, 0, 4, 210 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 4), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 4), 0); } -BOOST_AUTO_TEST_CASE(testWriteVInt) +TEST_F(IndexOutputTest, testWriteVInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVInt(1234); - BOOST_CHECK_EQUAL(indexOutput.getNextPosition(), 2); + EXPECT_EQ(indexOutput.getNextPosition(), 2); uint8_t expected[2] = { 210, 9 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 2), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 2), 0); } -BOOST_AUTO_TEST_CASE(testWriteLong) +TEST_F(IndexOutputTest, testWriteLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeLong(1234123412341234LL); - BOOST_CHECK_EQUAL(indexOutput.getNextPosition(), 8); + EXPECT_EQ(indexOutput.getNextPosition(), 8); uint8_t expected[8] = { 0, 4, 98, 109, 191, 154, 1, 242 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 8), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -BOOST_AUTO_TEST_CASE(testWriteVLong) +TEST_F(IndexOutputTest, testWriteVLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVLong(1234123412341234LL); - BOOST_CHECK_EQUAL(indexOutput.getNextPosition(), 8); + EXPECT_EQ(indexOutput.getNextPosition(), 8); uint8_t expected[8] = { 242, 131, 232, 252, 219, 205, 152, 2 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 8), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -BOOST_AUTO_TEST_CASE(testWriteString) +TEST_F(IndexOutputTest, testWriteString) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeString(L"test string"); - BOOST_CHECK_EQUAL(indexOutput.getNextPosition(), 12); + EXPECT_EQ(indexOutput.getNextPosition(), 12); uint8_t expected[12] = { 11, 116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 103 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 12), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 12), 0); } -BOOST_AUTO_TEST_CASE(testWriteChars) +TEST_F(IndexOutputTest, testWriteChars) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeChars(L"test string", 5, 6); - BOOST_CHECK_EQUAL(indexOutput.getNextPosition(), 6); + EXPECT_EQ(indexOutput.getNextPosition(), 6); uint8_t expected[6] = { 115, 116, 114, 105, 110, 103 }; - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), expected, 6), 0); + EXPECT_EQ(memcmp(outputBytes.get(), expected, 6), 0); } namespace TestCopyBytes @@ -138,18 +138,18 @@ namespace TestCopyBytes SourceIndexInput(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) { } - + virtual uint8_t readByte() { return 0; } - + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) { std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); nextByte += length; } - + virtual void close() { } @@ -158,16 +158,16 @@ namespace TestCopyBytes { return 0; } - + virtual void seek(int64_t pos) { } - + virtual int64_t length() { return 0; } - + virtual IndexInputPtr clone() { return IndexInputPtr(); @@ -180,18 +180,16 @@ namespace TestCopyBytes }; } -BOOST_AUTO_TEST_CASE(testCopyBytes) +TEST_F(IndexOutputTest, testCopyBytes) { ByteArray sourceBytes(ByteArray::newInstance(32768)); std::generate(sourceBytes.get(), sourceBytes.get() + 32768, rand); IndexInputPtr indexSource(newLucene(sourceBytes.get(), 32768)); - + ByteArray outputBytes(ByteArray::newInstance(32768)); TestableIndexOutput indexOutput(outputBytes.get(), 32768); - + indexOutput.copyBytes(indexSource, 20000); - - BOOST_CHECK_EQUAL(memcmp(outputBytes.get(), sourceBytes.get(), 20000), 0); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(memcmp(outputBytes.get(), sourceBytes.get(), 20000), 0); +} diff --git a/src/test/store/LockFactoryTest.cpp b/src/test/store/LockFactoryTest.cpp index c4899a6a..c0b19aaa 100644 --- a/src/test/store/LockFactoryTest.cpp +++ b/src/test/store/LockFactoryTest.cpp @@ -30,7 +30,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(LockFactoryTest, LuceneTestFixture) +typedef LuceneTestFixture LockFactoryTest; static void addDoc(IndexWriterPtr writer) { @@ -41,49 +41,49 @@ static void addDoc(IndexWriterPtr writer) // Verify: we can provide our own LockFactory implementation, the right // methods are called at the right time, locks are created, etc. -BOOST_AUTO_TEST_CASE(testCustomLockFactory) +TEST_F(LockFactoryTest, testCustomLockFactory) { DirectoryPtr dir(newLucene()); MockLockFactoryPtr lf(newLucene()); dir->setLockFactory(lf); - + // Lock prefix should have been set - BOOST_CHECK(lf->lockPrefixSet); - + EXPECT_TRUE(lf->lockPrefixSet); + IndexWriterPtr writer(newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); - + // add 100 documents (so that commit lock is used) for (int32_t i = 0; i < 100; ++i) addDoc(writer); - + // Both write lock and commit lock should have been created - BOOST_CHECK_EQUAL(lf->locksCreated.size(), 1); // # of unique locks created (after instantiating IndexWriter) - BOOST_CHECK(lf->makeLockCount >= 1); // # calls to makeLock is 0 (after instantiating IndexWriter) - + EXPECT_EQ(lf->locksCreated.size(), 1); // # of unique locks created (after instantiating IndexWriter) + EXPECT_TRUE(lf->makeLockCount >= 1); // # calls to makeLock is 0 (after instantiating IndexWriter) + for (MapStringLock::iterator lockName = lf->locksCreated.begin(); lockName != lf->locksCreated.end(); ++lockName) { MockLockPtr lock(boost::dynamic_pointer_cast(lockName->second)); - BOOST_CHECK(lock->lockAttempts > 0); // # calls to Lock.obtain is 0 (after instantiating IndexWriter) + EXPECT_TRUE(lock->lockAttempts > 0); // # calls to Lock.obtain is 0 (after instantiating IndexWriter) } - + writer->close(); } // Verify: we can use the NoLockFactory with RAMDirectory with no exceptions raised // Verify: NoLockFactory allows two IndexWriters -BOOST_AUTO_TEST_CASE(testRAMDirectoryNoLocking) +TEST_F(LockFactoryTest, testRAMDirectoryNoLocking) { DirectoryPtr dir(newLucene()); dir->setLockFactory(NoLockFactory::getNoLockFactory()); - - BOOST_CHECK(dir->getLockFactory()); - + + EXPECT_TRUE(dir->getLockFactory()); + IndexWriterPtr writer(newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); - + IndexWriterPtr writer2; - + // Create a 2nd IndexWriter. This is normally not allowed but it should run through since we're not using any locks - BOOST_CHECK_NO_THROW(writer2 = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED)); + EXPECT_NO_THROW(writer2 = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED)); writer->close(); if (writer2) @@ -92,18 +92,25 @@ BOOST_AUTO_TEST_CASE(testRAMDirectoryNoLocking) // Verify: SingleInstanceLockFactory is the default lock for RAMDirectory // Verify: RAMDirectory does basic locking correctly (can't create two IndexWriters) -BOOST_AUTO_TEST_CASE(testDefaultRAMDirectory) +TEST_F(LockFactoryTest, testDefaultRAMDirectory) { DirectoryPtr dir(newLucene()); LockFactoryPtr lockFactory(dir->getLockFactory()); - BOOST_CHECK(boost::dynamic_pointer_cast(lockFactory)); - + EXPECT_TRUE(boost::dynamic_pointer_cast(lockFactory)); + IndexWriterPtr writer(newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); - + IndexWriterPtr writer2; - + // Create a 2nd IndexWriter - This should fail - BOOST_CHECK_EXCEPTION(writer2 = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED), LuceneException, check_exception(LuceneException::LockObtainFailed)); + try + { + writer2 = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); + } + catch (LuceneException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); + } writer->close(); if (writer2) @@ -111,16 +118,16 @@ BOOST_AUTO_TEST_CASE(testDefaultRAMDirectory) } // test string file instantiation -BOOST_AUTO_TEST_CASE(testSimpleFSLockFactory) +TEST_F(LockFactoryTest, testSimpleFSLockFactory) { - BOOST_CHECK_NO_THROW(newLucene(L"test")); + EXPECT_NO_THROW(newLucene(L"test")); } -namespace LockFactoryTest +namespace LockFactoryTestNS { DECLARE_SHARED_PTR(WriterThread) - DECLARE_SHARED_PTR(SearcherThread) - + DECLARE_SHARED_PTR(LockFactorySearcherThread) + class WriterThread : public LuceneThread { public: @@ -130,20 +137,20 @@ namespace LockFactoryTest this->dir = dir; this->hitException = false; } - + virtual ~WriterThread() { } - + LUCENE_CLASS(WriterThread); - + public: bool hitException; - + protected: DirectoryPtr dir; int32_t numIteration; - + public: virtual void run() { @@ -160,7 +167,7 @@ namespace LockFactoryTest if (e.getError().find(L" timed out:") == String::npos) { hitException = true; - BOOST_FAIL("Stress Test Index Writer: creation hit unexpected IO exception: " << e.getError()); + FAIL() << "Stress Test Index Writer: creation hit unexpected IO exception: " << e.getError(); break; } else @@ -171,7 +178,7 @@ namespace LockFactoryTest catch (LuceneException& e) { hitException = true; - BOOST_FAIL("Stress Test Index Writer: creation hit unexpected exception: " << e.getError()); + FAIL() << "Stress Test Index Writer: creation hit unexpected exception: " << e.getError(); break; } if (writer) @@ -183,7 +190,7 @@ namespace LockFactoryTest catch (LuceneException& e) { hitException = true; - BOOST_FAIL("Stress Test Index Writer: addDoc hit unexpected exception: " << e.getError()); + FAIL() << "Stress Test Index Writer: addDoc hit unexpected exception: " << e.getError(); break; } try @@ -193,7 +200,7 @@ namespace LockFactoryTest catch (LuceneException& e) { hitException = true; - BOOST_FAIL("Stress Test Index Writer: close hit unexpected exception: " << e.getError()); + FAIL() << "Stress Test Index Writer: close hit unexpected exception: " << e.getError(); break; } } @@ -201,25 +208,25 @@ namespace LockFactoryTest } }; - class SearcherThread : public LuceneThread + class LockFactorySearcherThread : public LuceneThread { public: - SearcherThread(int32_t numIteration, DirectoryPtr dir) + LockFactorySearcherThread(int32_t numIteration, DirectoryPtr dir) { this->numIteration = numIteration; this->dir = dir; this->hitException = false; } - - virtual ~SearcherThread() + + virtual ~LockFactorySearcherThread() { } - - LUCENE_CLASS(SearcherThread); - + + LUCENE_CLASS(LockFactorySearcherThread); + public: bool hitException; - + protected: DirectoryPtr dir; int32_t numIteration; @@ -239,7 +246,7 @@ namespace LockFactoryTest catch (LuceneException& e) { hitException = true; - BOOST_FAIL("Stress Test Index Searcher: creation hit unexpected exception: " << e.getError()); + FAIL() << "Stress Test Index Searcher: creation hit unexpected exception: " << e.getError(); break; } if (searcher) @@ -252,7 +259,7 @@ namespace LockFactoryTest catch (LuceneException& e) { hitException = true; - BOOST_FAIL("Stress Test Index Searcher: search hit unexpected exception: " << e.getError()); + FAIL() << "Stress Test Index Searcher: search hit unexpected exception: " << e.getError(); break; } try @@ -262,7 +269,7 @@ namespace LockFactoryTest catch (LuceneException& e) { hitException = true; - BOOST_FAIL("Stress Test Index Searcher: close hit unexpected exception: " << e.getError()); + FAIL() << "Stress Test Index Searcher: close hit unexpected exception: " << e.getError(); break; } } @@ -274,43 +281,43 @@ namespace LockFactoryTest static void _testStressLocks(LockFactoryPtr lockFactory, const String& indexDir) { FSDirectoryPtr fs1 = FSDirectory::open(indexDir, lockFactory); - + // First create a 1 doc index IndexWriterPtr w = newLucene(fs1, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(w); w->close(); - - LockFactoryTest::WriterThreadPtr writer = newLucene(100, fs1); - LockFactoryTest::SearcherThreadPtr searcher = newLucene(100, fs1); + + LockFactoryTestNS::WriterThreadPtr writer = newLucene(100, fs1); + LockFactoryTestNS::LockFactorySearcherThreadPtr searcher = newLucene(100, fs1); writer->start(); searcher->start(); - + writer->join(); searcher->join(); - - BOOST_CHECK(!writer->hitException); - BOOST_CHECK(!searcher->hitException); + + EXPECT_TRUE(!writer->hitException); + EXPECT_TRUE(!searcher->hitException); FileUtils::removeDirectory(indexDir); } // Verify: do stress test, by opening IndexReaders and IndexWriters over and over in 2 threads and making sure // no unexpected exceptions are raised -BOOST_AUTO_TEST_CASE(testStressLocks) +TEST_F(LockFactoryTest, testStressLocks) { _testStressLocks(LockFactoryPtr(), getTempDir(L"index.TestLockFactory6")); } // Verify: do stress test, by opening IndexReaders and IndexWriters over and over in 2 threads and making sure // no unexpected exceptions are raised, but use NativeFSLockFactory -BOOST_AUTO_TEST_CASE(testStressLocksNativeFSLockFactory) +TEST_F(LockFactoryTest, testStressLocksNativeFSLockFactory) { String dir(getTempDir(L"index.TestLockFactory7")); _testStressLocks(newLucene(dir), dir); } // Verify: NativeFSLockFactory works correctly -BOOST_AUTO_TEST_CASE(testNativeFSLockFactory) +TEST_F(LockFactoryTest, testNativeFSLockFactory) { NativeFSLockFactoryPtr f(newLucene(getTempDir())); @@ -318,24 +325,24 @@ BOOST_AUTO_TEST_CASE(testNativeFSLockFactory) LockPtr l(f->makeLock(L"commit")); LockPtr l2(f->makeLock(L"commit")); - BOOST_CHECK(l->obtain()); - BOOST_CHECK(!l2->obtain()); + EXPECT_TRUE(l->obtain()); + EXPECT_TRUE(!l2->obtain()); l->release(); - BOOST_CHECK(l2->obtain()); + EXPECT_TRUE(l2->obtain()); l2->release(); // Make sure we can obtain first one again, test isLocked() - BOOST_CHECK(l->obtain()); - BOOST_CHECK(l->isLocked()); - BOOST_CHECK(l2->isLocked()); + EXPECT_TRUE(l->obtain()); + EXPECT_TRUE(l->isLocked()); + EXPECT_TRUE(l2->isLocked()); l->release(); - BOOST_CHECK(!l->isLocked()); - BOOST_CHECK(!l2->isLocked()); + EXPECT_TRUE(!l->isLocked()); + EXPECT_TRUE(!l2->isLocked()); } // Verify: NativeFSLockFactory works correctly if the lock file exists -BOOST_AUTO_TEST_CASE(testNativeFSLockFactoryLockExists) +TEST_F(LockFactoryTest, testNativeFSLockFactoryLockExists) { String lockFile = getTempDir(L"test.lock"); std::ofstream lockStream; @@ -343,14 +350,14 @@ BOOST_AUTO_TEST_CASE(testNativeFSLockFactoryLockExists) lockStream.close(); LockPtr l = newLucene(getTempDir())->makeLock(L"test.lock"); - BOOST_CHECK(l->obtain()); + EXPECT_TRUE(l->obtain()); l->release(); - BOOST_CHECK(!l->isLocked()); + EXPECT_TRUE(!l->isLocked()); if (FileUtils::fileExists(lockFile)) FileUtils::removeFile(lockFile); } -BOOST_AUTO_TEST_CASE(testNativeFSLockReleaseByOtherLock) +TEST_F(LockFactoryTest, testNativeFSLockReleaseByOtherLock) { NativeFSLockFactoryPtr f = newLucene(getTempDir()); @@ -358,46 +365,52 @@ BOOST_AUTO_TEST_CASE(testNativeFSLockReleaseByOtherLock) LockPtr l = f->makeLock(L"commit"); LockPtr l2 = f->makeLock(L"commit"); - BOOST_CHECK(l->obtain()); - BOOST_CHECK(l2->isLocked()); - - BOOST_CHECK_EXCEPTION(l2->release(), LockReleaseFailedException, check_exception(LuceneException::LockReleaseFailed)); + EXPECT_TRUE(l->obtain()); + EXPECT_TRUE(l2->isLocked()); + + try + { + l2->release(); + } + catch (LockReleaseFailedException& e) + { + EXPECT_TRUE(check_exception(LuceneException::LockReleaseFailed)(e)); + } + l->release(); } // Verify: NativeFSLockFactory assigns null as lockPrefix if the lockDir is inside directory -BOOST_AUTO_TEST_CASE(testNativeFSLockFactoryPrefix) +TEST_F(LockFactoryTest, testNativeFSLockFactoryPrefix) { String fdir1(getTempDir(L"TestLockFactory.8")); String fdir2(getTempDir(L"TestLockFactory.8.Lockdir")); - + DirectoryPtr dir1(FSDirectory::open(fdir1, newLucene(fdir1))); // same directory, but locks are stored somewhere else. The prefix of the lock factory should != null DirectoryPtr dir2(FSDirectory::open(fdir1, newLucene(fdir2))); String prefix1(dir1->getLockFactory()->getLockPrefix()); - BOOST_CHECK(prefix1.empty()); // Lock prefix for lockDir same as directory should be null - + EXPECT_TRUE(prefix1.empty()); // Lock prefix for lockDir same as directory should be null + String prefix2(dir2->getLockFactory()->getLockPrefix()); - BOOST_CHECK(!prefix2.empty()); // Lock prefix for lockDir outside of directory should be not null + EXPECT_TRUE(!prefix2.empty()); // Lock prefix for lockDir outside of directory should be not null FileUtils::removeDirectory(fdir1); FileUtils::removeDirectory(fdir2); } // Verify: default LockFactory has no prefix (ie write.lock is stored in index) -BOOST_AUTO_TEST_CASE(testDefaultFSLockFactoryPrefix) +TEST_F(LockFactoryTest, testDefaultFSLockFactoryPrefix) { // Make sure we get null prefix String dirName(getTempDir(L"TestLockFactory.10")); DirectoryPtr dir(FSDirectory::open(dirName)); String prefix(dir->getLockFactory()->getLockPrefix()); - - BOOST_CHECK(prefix.empty()); // Default lock prefix should be null + + EXPECT_TRUE(prefix.empty()); // Default lock prefix should be null FileUtils::removeDirectory(dirName); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/store/MMapDirectoryTest.cpp b/src/test/store/MMapDirectoryTest.cpp index c3d527e2..d774fa00 100644 --- a/src/test/store/MMapDirectoryTest.cpp +++ b/src/test/store/MMapDirectoryTest.cpp @@ -19,7 +19,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(MMapDirectoryTest, LuceneTestFixture) +typedef LuceneTestFixture MMapDirectoryTest; static RandomPtr rndToken = newLucene(); @@ -42,18 +42,18 @@ String randomField() return fb.str(); } -BOOST_AUTO_TEST_CASE(testMmapIndex) +TEST_F(MMapDirectoryTest, testMmapIndex) { String storePathname(FileUtils::joinPath(getTempDir(), L"testLuceneMmap")); - + FSDirectoryPtr storeDirectory(newLucene(storePathname)); - + // plan to add a set of useful stopwords, consider changing some of the interior filters. StandardAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT, HashSet()); - + IndexWriterPtr writer = newLucene(storeDirectory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); IndexSearcherPtr searcher = newLucene(storeDirectory, true); - + for (int32_t dx = 0; dx < 1000; ++dx) { String f(randomField()); @@ -61,11 +61,9 @@ BOOST_AUTO_TEST_CASE(testMmapIndex) doc->add(newLucene(L"data", f, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - + searcher->close(); writer->close(); - + FileUtils::removeDirectory(storePathname); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/store/RAMDirectoryTest.cpp b/src/test/store/RAMDirectoryTest.cpp index 9fbc2b45..64aaff55 100644 --- a/src/test/store/RAMDirectoryTest.cpp +++ b/src/test/store/RAMDirectoryTest.cpp @@ -25,18 +25,18 @@ using namespace Lucene; -class RAMDirectoryTestFixture : public LuceneTestFixture +class RAMDirectoryTest : public LuceneTestFixture { public: - RAMDirectoryTestFixture() + RAMDirectoryTest() { indexDir = FileUtils::joinPath(getTempDir(), L"RAMDirIndex"); DirectoryPtr dir(FSDirectory::open(indexDir)); IndexWriterPtr writer(newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); - + // add enough document so that the index will be larger than RAMDirectory::READ_BUFFER_SIZE docsToAdd = 500; - + // add some documents for (int32_t i = 0; i < docsToAdd; ++i) { @@ -44,13 +44,13 @@ class RAMDirectoryTestFixture : public LuceneTestFixture doc->add(newLucene(L"content", intToEnglish(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } - BOOST_CHECK_EQUAL(docsToAdd, writer->maxDoc()); - + EXPECT_EQ(docsToAdd, writer->maxDoc()); + writer->close(); dir->close(); } - - virtual ~RAMDirectoryTestFixture() + + virtual ~RAMDirectoryTest() { FileUtils::removeDirectory(indexDir); } @@ -68,7 +68,7 @@ class TestRAMDirectoryThread : public LuceneThread this->writer = writer; this->num = num; } - + LUCENE_CLASS(TestRAMDirectoryThread); public: @@ -78,7 +78,7 @@ class TestRAMDirectoryThread : public LuceneThread protected: IndexWriterPtr writer; int32_t num; - + public: virtual void run() { @@ -112,7 +112,7 @@ class DenseRAMFile : public RAMFile capacity = 0; singleBuffers = MapIntByteArray::newInstance(); } - + LUCENE_CLASS(DenseRAMFile); public: @@ -145,31 +145,29 @@ const int64_t DenseRAMFile::MAX_VALUE = 2 * (int64_t)INT_MAX; typedef boost::shared_ptr DenseRAMFilePtr; -BOOST_FIXTURE_TEST_SUITE(RAMDirectoryTest, RAMDirectoryTestFixture) - -BOOST_AUTO_TEST_CASE(testRAMDirectory) +TEST_F(RAMDirectoryTest, testRAMDirectory) { DirectoryPtr dir(FSDirectory::open(indexDir)); MockRAMDirectoryPtr ramDir(newLucene(dir)); - + // close the underlaying directory dir->close(); - + // Check size - BOOST_CHECK_EQUAL(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); - + EXPECT_EQ(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); + // open reader to test document count IndexReaderPtr reader(IndexReader::open(ramDir, true)); - BOOST_CHECK_EQUAL(docsToAdd, reader->numDocs()); - + EXPECT_EQ(docsToAdd, reader->numDocs()); + // open search to check if all doc's are there IndexSearcherPtr searcher = newLucene(reader); - + // search for all documents for (int32_t i = 0; i < docsToAdd; ++i) { DocumentPtr doc = searcher->doc(i); - BOOST_CHECK(doc->getField(L"content")); + EXPECT_TRUE(doc->getField(L"content")); } // cleanup @@ -177,33 +175,33 @@ BOOST_AUTO_TEST_CASE(testRAMDirectory) searcher->close(); } -BOOST_AUTO_TEST_CASE(testRAMDirectorySize) +TEST_F(RAMDirectoryTest, testRAMDirectorySize) { DirectoryPtr dir(FSDirectory::open(indexDir)); MockRAMDirectoryPtr ramDir(newLucene(dir)); dir->close(); - + IndexWriterPtr writer(newLucene(ramDir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED)); writer->optimize(); - - BOOST_CHECK_EQUAL(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); - + + EXPECT_EQ(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); + Collection threads(Collection::newInstance(TestRAMDirectoryThread::numThreads)); for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) threads[i] = newLucene(writer, i); - + for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) threads[i]->start(); for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) threads[i]->join(); - + writer->optimize(); - BOOST_CHECK_EQUAL(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); - + EXPECT_EQ(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); + writer->close(); } -BOOST_AUTO_TEST_CASE(testIllegalEOF) +TEST_F(RAMDirectoryTest, testIllegalEOF) { RAMDirectoryPtr dir(newLucene()); IndexOutputPtr o(dir->createOutput(L"out")); @@ -217,27 +215,27 @@ BOOST_AUTO_TEST_CASE(testIllegalEOF) } /// Test huge RAMFile with more than INT_MAX bytes. -BOOST_AUTO_TEST_CASE(testHugeFile) +TEST_F(RAMDirectoryTest, testHugeFile) { DenseRAMFilePtr f(newLucene()); - + // output part RAMOutputStreamPtr out(newLucene(f)); ByteArray b1(ByteArray::newInstance(RAMOutputStream::BUFFER_SIZE)); ByteArray b2(ByteArray::newInstance(RAMOutputStream::BUFFER_SIZE / 3)); - + for (int32_t i = 0; i < b1.size(); ++i) b1[i] = (uint8_t)(i & 0x0007f); for (int32_t i = 0; i < b2.size(); ++i) b2[i] = (uint8_t)(i & 0x0003f); int64_t n = 0; - BOOST_CHECK_EQUAL(n, out->length()); // output length must match + EXPECT_EQ(n, out->length()); // output length must match while (n <= DenseRAMFile::MAX_VALUE - b1.size()) { out->writeBytes(b1.get(), 0, b1.size()); out->flush(); n += b1.size(); - BOOST_CHECK_EQUAL(n, out->length()); // output length must match + EXPECT_EQ(n, out->length()); // output length must match } int32_t m = b2.size(); int64_t l = 12; @@ -245,16 +243,16 @@ BOOST_AUTO_TEST_CASE(testHugeFile) { for (int32_t i = 0; i < b2.size(); ++i) b2[i]++; - + out->writeBytes(b2.get(), 0, m); out->flush(); n += m; - BOOST_CHECK_EQUAL(n, out->length()); // output length must match + EXPECT_EQ(n, out->length()); // output length must match } out->close(); // input part RAMInputStreamPtr in(newLucene(f)); - BOOST_CHECK_EQUAL(n, in->length()); // input length must match + EXPECT_EQ(n, in->length()); // input length must match for (int32_t j = 0; j < l; ++j) { int64_t loc = n - (l - j) * m; @@ -264,9 +262,7 @@ BOOST_AUTO_TEST_CASE(testHugeFile) { uint8_t bt = in->readByte(); uint8_t expected = (uint8_t)(1 + j + (i & 0x0003f)); - BOOST_CHECK_EQUAL(expected, bt); // must read same value that was written + EXPECT_EQ(expected, bt); // must read same value that was written } } } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/AttributeSourceTest.cpp b/src/test/util/AttributeSourceTest.cpp index 0a709355..63552a0e 100644 --- a/src/test/util/AttributeSourceTest.cpp +++ b/src/test/util/AttributeSourceTest.cpp @@ -17,9 +17,9 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(AttributeSourceTest, LuceneTestFixture) +typedef LuceneTestFixture AttributeSourceTest; -BOOST_AUTO_TEST_CASE(testCaptureState) +TEST_F(AttributeSourceTest, testCaptureState) { // init a first instance AttributeSourcePtr src = newLucene(); @@ -34,20 +34,20 @@ BOOST_AUTO_TEST_CASE(testCaptureState) // modify the attributes termAtt->setTermBuffer(L"AnotherTestTerm"); typeAtt->setType(L"AnotherTestType"); - BOOST_CHECK_NE(hashCode, src->hashCode()); + EXPECT_NE(hashCode, src->hashCode()); src->restoreState(state); - BOOST_CHECK_EQUAL(L"TestTerm", termAtt->term()); - BOOST_CHECK_EQUAL(L"TestType", typeAtt->type()); - BOOST_CHECK_EQUAL(hashCode, src->hashCode()); + EXPECT_EQ(L"TestTerm", termAtt->term()); + EXPECT_EQ(L"TestType", typeAtt->type()); + EXPECT_EQ(hashCode, src->hashCode()); // restore into an exact configured copy AttributeSourcePtr copy = newLucene(); copy->addAttribute(); copy->addAttribute(); copy->restoreState(state); - BOOST_CHECK_EQUAL(src->hashCode(), copy->hashCode()); - BOOST_CHECK(src->equals(copy)); + EXPECT_EQ(src->hashCode(), copy->hashCode()); + EXPECT_TRUE(src->equals(copy)); // init a second instance (with attributes in different order and one additional attribute) AttributeSourcePtr src2 = newLucene(); @@ -57,17 +57,24 @@ BOOST_AUTO_TEST_CASE(testCaptureState) flagsAtt->setFlags(12345); src2->restoreState(state); - BOOST_CHECK_EQUAL(L"TestTerm", termAtt->term()); - BOOST_CHECK_EQUAL(L"TestType", typeAtt->type()); - BOOST_CHECK_EQUAL(12345, flagsAtt->getFlags()); + EXPECT_EQ(L"TestTerm", termAtt->term()); + EXPECT_EQ(L"TestType", typeAtt->type()); + EXPECT_EQ(12345, flagsAtt->getFlags()); // init a third instance missing one Attribute AttributeSourcePtr src3 = newLucene(); termAtt = src3->addAttribute(); - BOOST_CHECK_EXCEPTION(src3->restoreState(state), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + src3->restoreState(state); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } -BOOST_AUTO_TEST_CASE(testCloneAttributes) +TEST_F(AttributeSourceTest, testCloneAttributes) { AttributeSourcePtr src = newLucene(); TermAttributePtr termAtt = src->addAttribute(); @@ -77,42 +84,40 @@ BOOST_AUTO_TEST_CASE(testCloneAttributes) AttributeSourcePtr clone = src->cloneAttributes(); Collection attributes = clone->getAttributes(); - BOOST_CHECK_EQUAL(2, attributes.size()); - BOOST_CHECK(MiscUtils::typeOf(attributes[0])); - BOOST_CHECK(MiscUtils::typeOf(attributes[1])); - + EXPECT_EQ(2, attributes.size()); + EXPECT_TRUE(MiscUtils::typeOf(attributes[0])); + EXPECT_TRUE(MiscUtils::typeOf(attributes[1])); + TermAttributePtr termAtt2 = clone->getAttribute(); TypeAttributePtr typeAtt2 = clone->getAttribute(); - BOOST_CHECK(termAtt2 != termAtt); - BOOST_CHECK(typeAtt2 != typeAtt); - BOOST_CHECK(termAtt2->equals(termAtt)); - BOOST_CHECK(typeAtt2->equals(typeAtt)); + EXPECT_TRUE(termAtt2 != termAtt); + EXPECT_TRUE(typeAtt2 != typeAtt); + EXPECT_TRUE(termAtt2->equals(termAtt)); + EXPECT_TRUE(typeAtt2->equals(typeAtt)); } -BOOST_AUTO_TEST_CASE(testToStringAndMultiAttributeImplementations) +TEST_F(AttributeSourceTest, testToStringAndMultiAttributeImplementations) { AttributeSourcePtr src = newLucene(); TermAttributePtr termAtt = src->addAttribute(); TypeAttributePtr typeAtt = src->addAttribute(); termAtt->setTermBuffer(L"TestTerm"); typeAtt->setType(L"TestType"); - - BOOST_CHECK_EQUAL(L"(" + termAtt->toString() + L"," + typeAtt->toString() + L")", src->toString()); + + EXPECT_EQ(L"(" + termAtt->toString() + L"," + typeAtt->toString() + L")", src->toString()); Collection attributes = src->getAttributes(); - BOOST_CHECK_EQUAL(2, attributes.size()); - BOOST_CHECK(attributes[0]->equals(termAtt)); - BOOST_CHECK(attributes[1]->equals(typeAtt)); + EXPECT_EQ(2, attributes.size()); + EXPECT_TRUE(attributes[0]->equals(termAtt)); + EXPECT_TRUE(attributes[1]->equals(typeAtt)); } -BOOST_AUTO_TEST_CASE(testDefaultAttributeFactory) +TEST_F(AttributeSourceTest, testDefaultAttributeFactory) { AttributeSourcePtr src = newLucene(); - BOOST_CHECK(MiscUtils::typeOf(src->addAttribute())); - BOOST_CHECK(MiscUtils::typeOf(src->addAttribute())); - BOOST_CHECK(MiscUtils::typeOf(src->addAttribute())); - BOOST_CHECK(MiscUtils::typeOf(src->addAttribute())); - BOOST_CHECK(MiscUtils::typeOf(src->addAttribute())); - BOOST_CHECK(MiscUtils::typeOf(src->addAttribute())); + EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); + EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); + EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); + EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); + EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); + EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/Base64Test.cpp b/src/test/util/Base64Test.cpp index 33c916ac..05a775c0 100644 --- a/src/test/util/Base64Test.cpp +++ b/src/test/util/Base64Test.cpp @@ -11,16 +11,16 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(Base64Test, LuceneTestFixture) +typedef LuceneTestFixture Base64Test; -BOOST_AUTO_TEST_CASE(testEncodeSmall) +TEST_F(Base64Test, testEncodeSmall) { SingleString testBinary = "this is test binary"; String encode = Base64::encode((uint8_t*)testBinary.c_str(), testBinary.length()); - BOOST_CHECK_EQUAL(encode, L"dGhpcyBpcyB0ZXN0IGJpbmFyeQ=="); + EXPECT_EQ(encode, L"dGhpcyBpcyB0ZXN0IGJpbmFyeQ=="); } -BOOST_AUTO_TEST_CASE(testEncodeLarge) +TEST_F(Base64Test, testEncodeLarge) { SingleString testBinary = "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64 " @@ -28,26 +28,26 @@ BOOST_AUTO_TEST_CASE(testEncodeLarge) "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64"; String encode = Base64::encode((uint8_t*)testBinary.c_str(), testBinary.length()); - + String expected = L"VGhpcyBpcyBhIGxhcmdlciB0ZXN0IHN0cmluZyB0aGF0IHNob3VsZCBjb252ZXJ0IGludG8gYmFz" L"ZTY0IFRoaXMgaXMgYSBsYXJnZXIgdGVzdCBzdHJpbmcgdGhhdCBzaG91bGQgY29udmVydCBpbnRv" L"IGJhc2U2NCBUaGlzIGlzIGEgbGFyZ2VyIHRlc3Qgc3RyaW5nIHRoYXQgc2hvdWxkIGNvbnZlcnQg" L"aW50byBiYXNlNjQgVGhpcyBpcyBhIGxhcmdlciB0ZXN0IHN0cmluZyB0aGF0IHNob3VsZCBjb252" L"ZXJ0IGludG8gYmFzZTY0IFRoaXMgaXMgYSBsYXJnZXIgdGVzdCBzdHJpbmcgdGhhdCBzaG91bGQg" L"Y29udmVydCBpbnRvIGJhc2U2NA=="; - - BOOST_CHECK_EQUAL(encode, expected); + + EXPECT_EQ(encode, expected); } -BOOST_AUTO_TEST_CASE(testDecodeSmall) +TEST_F(Base64Test, testDecodeSmall) { String testString = L"dGhpcyBpcyB0ZXN0IGJpbmFyeQ=="; ByteArray decode = Base64::decode(testString); SingleString decodeBinary((char*)decode.get(), decode.size()); - BOOST_CHECK_EQUAL(decodeBinary, "this is test binary"); + EXPECT_EQ(decodeBinary, "this is test binary"); } -BOOST_AUTO_TEST_CASE(testDecodeLaarge) +TEST_F(Base64Test, testDecodeLaarge) { String testString = L"VGhpcyBpcyBhIGxhcmdlciB0ZXN0IHN0cmluZyB0aGF0IHNob3VsZCBjb252ZXJ0IGludG8gYmFz" L"ZTY0IFRoaXMgaXMgYSBsYXJnZXIgdGVzdCBzdHJpbmcgdGhhdCBzaG91bGQgY29udmVydCBpbnRv" @@ -57,14 +57,12 @@ BOOST_AUTO_TEST_CASE(testDecodeLaarge) L"Y29udmVydCBpbnRvIGJhc2U2NA=="; ByteArray decode = Base64::decode(testString); SingleString decodeBinary((char*)decode.get(), decode.size()); - + SingleString expected = "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64"; - - BOOST_CHECK_EQUAL(decodeBinary, expected); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(decodeBinary, expected); +} diff --git a/src/test/util/BitVectorTest.cpp b/src/test/util/BitVectorTest.cpp index b93629a7..9d8ddaef 100644 --- a/src/test/util/BitVectorTest.cpp +++ b/src/test/util/BitVectorTest.cpp @@ -11,7 +11,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BitVectorTest, LuceneTestFixture) +typedef LuceneTestFixture BitVectorTest; static const int32_t subsetPattern[] = {1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1}; @@ -29,11 +29,11 @@ static bool compareBitVectors(BitVectorPtr bv, BitVectorPtr compare) static void doTestConstructOfSize(int32_t n) { BitVectorPtr bv = newLucene(n); - BOOST_CHECK_EQUAL(n, bv->size()); + EXPECT_EQ(n, bv->size()); } /// Test the default constructor on BitVectors of various sizes. -BOOST_AUTO_TEST_CASE(testConstructSize) +TEST_F(BitVectorTest, testConstructSize) { doTestConstructOfSize(8); doTestConstructOfSize(20); @@ -46,14 +46,14 @@ static void doTestGetSetVectorOfSize(int32_t n) BitVectorPtr bv = newLucene(n); for (int32_t i = 0; i < bv->size(); ++i) { - BOOST_CHECK(!bv->get(i)); + EXPECT_TRUE(!bv->get(i)); bv->set(i); - BOOST_CHECK(bv->get(i)); + EXPECT_TRUE(bv->get(i)); } } /// Test the get() and set() methods on BitVectors of various sizes. -BOOST_AUTO_TEST_CASE(testGetSet) +TEST_F(BitVectorTest, testGetSet) { doTestGetSetVectorOfSize(8); doTestGetSetVectorOfSize(20); @@ -66,16 +66,16 @@ static void doTestClearVectorOfSize(int32_t n) BitVectorPtr bv = newLucene(n); for (int32_t i = 0; i < bv->size(); ++i) { - BOOST_CHECK(!bv->get(i)); + EXPECT_TRUE(!bv->get(i)); bv->set(i); - BOOST_CHECK(bv->get(i)); + EXPECT_TRUE(bv->get(i)); bv->clear(i); - BOOST_CHECK(!bv->get(i)); + EXPECT_TRUE(!bv->get(i)); } } /// Test the clear() method on BitVectors of various sizes. -BOOST_AUTO_TEST_CASE(testClear) +TEST_F(BitVectorTest, testClear) { doTestClearVectorOfSize(8); doTestClearVectorOfSize(20); @@ -89,30 +89,30 @@ static void doTestCountVectorOfSize(int32_t n) // test count when incrementally setting bits for (int32_t i = 0; i < bv->size(); ++i) { - BOOST_CHECK(!bv->get(i)); - BOOST_CHECK_EQUAL(i, bv->count()); + EXPECT_TRUE(!bv->get(i)); + EXPECT_EQ(i, bv->count()); bv->set(i); - BOOST_CHECK(bv->get(i)); - BOOST_CHECK_EQUAL(i + 1, bv->count()); + EXPECT_TRUE(bv->get(i)); + EXPECT_EQ(i + 1, bv->count()); } - + bv = newLucene(n); // test count when setting then clearing bits for (int32_t i = 0; i < bv->size(); ++i) { - BOOST_CHECK(!bv->get(i)); - BOOST_CHECK_EQUAL(0, bv->count()); + EXPECT_TRUE(!bv->get(i)); + EXPECT_EQ(0, bv->count()); bv->set(i); - BOOST_CHECK(bv->get(i)); - BOOST_CHECK_EQUAL(1, bv->count()); + EXPECT_TRUE(bv->get(i)); + EXPECT_EQ(1, bv->count()); bv->clear(i); - BOOST_CHECK(!bv->get(i)); - BOOST_CHECK_EQUAL(0, bv->count()); + EXPECT_TRUE(!bv->get(i)); + EXPECT_EQ(0, bv->count()); } } /// Test the count() method on BitVectors of various sizes. -BOOST_AUTO_TEST_CASE(testCount) +TEST_F(BitVectorTest, testCount) { doTestCountVectorOfSize(8); doTestCountVectorOfSize(20); @@ -127,20 +127,20 @@ static void doTestWriteRead(int32_t n) // test count when incrementally setting bits for (int32_t i = 0; i < bv->size(); ++i) { - BOOST_CHECK(!bv->get(i)); - BOOST_CHECK_EQUAL(i, bv->count()); + EXPECT_TRUE(!bv->get(i)); + EXPECT_EQ(i, bv->count()); bv->set(i); - BOOST_CHECK(bv->get(i)); - BOOST_CHECK_EQUAL(i + 1, bv->count()); + EXPECT_TRUE(bv->get(i)); + EXPECT_EQ(i + 1, bv->count()); bv->write(d, L"TESTBV"); BitVectorPtr compare = newLucene(d, L"TESTBV"); // compare bit vectors with bits set incrementally - BOOST_CHECK(compareBitVectors(bv, compare)); + EXPECT_TRUE(compareBitVectors(bv, compare)); } } /// Test writing and construction to/from Directory. -BOOST_AUTO_TEST_CASE(testWriteRead) +TEST_F(BitVectorTest, testWriteRead) { doTestWriteRead(8); doTestWriteRead(20); @@ -155,33 +155,33 @@ static void doTestDgaps(int32_t size, int32_t count1, int32_t count2) for (int32_t i = 0; i < count1; ++i) { bv->set(i); - BOOST_CHECK_EQUAL(i + 1, bv->count()); + EXPECT_EQ(i + 1, bv->count()); } bv->write(d, L"TESTBV"); // gradually increase number of set bits for (int32_t i = count1; i < count2; ++i) { BitVectorPtr bv2 = newLucene(d, L"TESTBV"); - BOOST_CHECK(compareBitVectors(bv, bv2)); + EXPECT_TRUE(compareBitVectors(bv, bv2)); bv = bv2; bv->set(i); - BOOST_CHECK_EQUAL(i + 1, bv->count()); + EXPECT_EQ(i + 1, bv->count()); bv->write(d, L"TESTBV"); } // now start decreasing number of set bits for (int32_t i = count2 - 1; i >= count1; --i) { BitVectorPtr bv2 = newLucene(d, L"TESTBV"); - BOOST_CHECK(compareBitVectors(bv, bv2)); + EXPECT_TRUE(compareBitVectors(bv, bv2)); bv = bv2; bv->clear(i); - BOOST_CHECK_EQUAL(i, bv->count()); + EXPECT_EQ(i, bv->count()); bv->write(d, L"TESTBV"); } } /// Test r/w when size/count cause switching between bit-set and d-gaps file formats. -BOOST_AUTO_TEST_CASE(testDgaps) +TEST_F(BitVectorTest, testDgaps) { doTestDgaps(1, 0, 1); doTestDgaps(10, 0, 1); @@ -209,23 +209,23 @@ static void doTestSubset(int32_t start, int32_t end) { BitVectorPtr full = createSubsetTestVector(); BitVectorPtr subset = full->subset(start, end); - BOOST_CHECK_EQUAL(end - start, subset->size()); + EXPECT_EQ(end - start, subset->size()); int32_t count = 0; for (int32_t i = start, j = 0; i < end; ++i, ++j) { if (subsetPattern[i] == 1) { ++count; - BOOST_CHECK(subset->get(j)); + EXPECT_TRUE(subset->get(j)); } else - BOOST_CHECK(!subset->get(j)); + EXPECT_TRUE(!subset->get(j)); } - BOOST_CHECK_EQUAL(count, subset->count()); + EXPECT_EQ(count, subset->count()); } /// Tests BitVector.subset() against a pattern -BOOST_AUTO_TEST_CASE(testSubset) +TEST_F(BitVectorTest, testSubset) { doTestSubset(0, 0); doTestSubset(0, 20); @@ -256,5 +256,3 @@ BOOST_AUTO_TEST_CASE(testSubset) doTestSubset(12, 20); doTestSubset(13, 20); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/BufferedReaderTest.cpp b/src/test/util/BufferedReaderTest.cpp index e714627e..c6a85461 100644 --- a/src/test/util/BufferedReaderTest.cpp +++ b/src/test/util/BufferedReaderTest.cpp @@ -14,135 +14,133 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(BufferedReaderTest, LuceneTestFixture) +typedef LuceneTestFixture BufferedReaderTest; -BOOST_AUTO_TEST_CASE(testBufferedReaderChar) +TEST_F(BufferedReaderTest, testBufferedReaderChar) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'e'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L's'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L' '); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'f'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'i'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'l'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'e'); + EXPECT_EQ((wchar_t)reader->read(), L't'); + EXPECT_EQ((wchar_t)reader->read(), L'e'); + EXPECT_EQ((wchar_t)reader->read(), L's'); + EXPECT_EQ((wchar_t)reader->read(), L't'); + EXPECT_EQ((wchar_t)reader->read(), L' '); + EXPECT_EQ((wchar_t)reader->read(), L'f'); + EXPECT_EQ((wchar_t)reader->read(), L'i'); + EXPECT_EQ((wchar_t)reader->read(), L'l'); + EXPECT_EQ((wchar_t)reader->read(), L'e'); } -BOOST_AUTO_TEST_CASE(testBufferedReaderRead) +TEST_F(BufferedReaderTest, testBufferedReaderRead) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); - + wchar_t buffer[80]; int32_t length = reader->read(buffer, 0, 80); String bufferString(buffer, length); - + boost::replace_all(bufferString, L"\r\n", L"\n"); // account for windows newline characters - - BOOST_CHECK_EQUAL(bufferString, L"test file\nthat contains\nmultiple lines of text\n\n\n1 2 3 4\n"); - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 1), FileReader::FILE_EOF); + + EXPECT_EQ(bufferString, L"test file\nthat contains\nmultiple lines of text\n\n\n1 2 3 4\n"); + EXPECT_EQ(reader->read(buffer, 0, 1), FileReader::FILE_EOF); } -BOOST_AUTO_TEST_CASE(testBufferedReaderReadLine) +TEST_F(BufferedReaderTest, testBufferedReaderReadLine) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); - + Collection readLines = Collection::newInstance(); String line; - + while (reader->readLine(line)) readLines.add(line); - - BOOST_CHECK_EQUAL(reader->read(), FileReader::FILE_EOF); - BOOST_CHECK_EQUAL(readLines.size(), 6); - BOOST_CHECK_EQUAL(readLines[0], L"test file"); - BOOST_CHECK_EQUAL(readLines[1], L"that contains"); - BOOST_CHECK_EQUAL(readLines[2], L"multiple lines of text"); - BOOST_CHECK_EQUAL(readLines[3], L""); - BOOST_CHECK_EQUAL(readLines[4], L""); - BOOST_CHECK_EQUAL(readLines[5], L"1 2 3 4"); + + EXPECT_EQ(reader->read(), FileReader::FILE_EOF); + EXPECT_EQ(readLines.size(), 6); + EXPECT_EQ(readLines[0], L"test file"); + EXPECT_EQ(readLines[1], L"that contains"); + EXPECT_EQ(readLines[2], L"multiple lines of text"); + EXPECT_EQ(readLines[3], L""); + EXPECT_EQ(readLines[4], L""); + EXPECT_EQ(readLines[5], L"1 2 3 4"); } -BOOST_AUTO_TEST_CASE(testBufferedReaderReset) +TEST_F(BufferedReaderTest, testBufferedReaderReset) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); - + wchar_t buffer[20]; - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 9), 9); - BOOST_CHECK_EQUAL(String(buffer, 9), L"test file"); + EXPECT_EQ(reader->read(buffer, 0, 9), 9); + EXPECT_EQ(String(buffer, 9), L"test file"); reader->reset(); - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 9), 9); - BOOST_CHECK_EQUAL(String(buffer, 9), L"test file"); + EXPECT_EQ(reader->read(buffer, 0, 9), 9); + EXPECT_EQ(String(buffer, 9), L"test file"); } -BOOST_AUTO_TEST_CASE(testBufferedReaderCharsSmallBuffer) +TEST_F(BufferedReaderTest, testBufferedReaderCharsSmallBuffer) { static const int32_t bufferSize = 5; - + BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); - - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'e'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L's'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L' '); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'f'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'i'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'l'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'e'); + + EXPECT_EQ((wchar_t)reader->read(), L't'); + EXPECT_EQ((wchar_t)reader->read(), L'e'); + EXPECT_EQ((wchar_t)reader->read(), L's'); + EXPECT_EQ((wchar_t)reader->read(), L't'); + EXPECT_EQ((wchar_t)reader->read(), L' '); + EXPECT_EQ((wchar_t)reader->read(), L'f'); + EXPECT_EQ((wchar_t)reader->read(), L'i'); + EXPECT_EQ((wchar_t)reader->read(), L'l'); + EXPECT_EQ((wchar_t)reader->read(), L'e'); } -BOOST_AUTO_TEST_CASE(testBufferedReaderReadSmallBuffer) +TEST_F(BufferedReaderTest, testBufferedReaderReadSmallBuffer) { static const int32_t bufferSize = 5; - + BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); - + wchar_t buffer[80]; int32_t length = reader->read(buffer, 0, 80); String bufferString(buffer, length); - + boost::replace_all(bufferString, L"\r\n", L"\n"); // account for windows newline characters - - BOOST_CHECK_EQUAL(bufferString, L"test file\nthat contains\nmultiple lines of text\n\n\n1 2 3 4\n"); - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 1), FileReader::FILE_EOF); + + EXPECT_EQ(bufferString, L"test file\nthat contains\nmultiple lines of text\n\n\n1 2 3 4\n"); + EXPECT_EQ(reader->read(buffer, 0, 1), FileReader::FILE_EOF); } -BOOST_AUTO_TEST_CASE(testBufferedReaderResetSmallBuffer) +TEST_F(BufferedReaderTest, testBufferedReaderResetSmallBuffer) { static const int32_t bufferSize = 5; - + BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); - + wchar_t buffer[20]; - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 9), 9); - BOOST_CHECK_EQUAL(String(buffer, 9), L"test file"); + EXPECT_EQ(reader->read(buffer, 0, 9), 9); + EXPECT_EQ(String(buffer, 9), L"test file"); reader->reset(); - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 9), 9); - BOOST_CHECK_EQUAL(String(buffer, 9), L"test file"); + EXPECT_EQ(reader->read(buffer, 0, 9), 9); + EXPECT_EQ(String(buffer, 9), L"test file"); } -BOOST_AUTO_TEST_CASE(testBufferedReaderReadLineSmallBuffer) +TEST_F(BufferedReaderTest, testBufferedReaderReadLineSmallBuffer) { static const int32_t bufferSize = 5; - + BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); - + Collection readLines = Collection::newInstance(); String line; - + while (reader->readLine(line)) readLines.add(line); - - BOOST_CHECK_EQUAL(reader->read(), FileReader::FILE_EOF); - BOOST_CHECK_EQUAL(readLines.size(), 6); - BOOST_CHECK_EQUAL(readLines[0], L"test file"); - BOOST_CHECK_EQUAL(readLines[1], L"that contains"); - BOOST_CHECK_EQUAL(readLines[2], L"multiple lines of text"); - BOOST_CHECK_EQUAL(readLines[3], L""); - BOOST_CHECK_EQUAL(readLines[4], L""); - BOOST_CHECK_EQUAL(readLines[5], L"1 2 3 4"); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(reader->read(), FileReader::FILE_EOF); + EXPECT_EQ(readLines.size(), 6); + EXPECT_EQ(readLines[0], L"test file"); + EXPECT_EQ(readLines[1], L"that contains"); + EXPECT_EQ(readLines[2], L"multiple lines of text"); + EXPECT_EQ(readLines[3], L""); + EXPECT_EQ(readLines[4], L""); + EXPECT_EQ(readLines[5], L"1 2 3 4"); +} diff --git a/src/test/util/CloseableThreadLocalTest.cpp b/src/test/util/CloseableThreadLocalTest.cpp index 90c7f792..701e2081 100644 --- a/src/test/util/CloseableThreadLocalTest.cpp +++ b/src/test/util/CloseableThreadLocalTest.cpp @@ -10,11 +10,11 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CloseableThreadLocalTest, LuceneTestFixture) +typedef LuceneTestFixture CloseableThreadLocalTest; static const String TEST_VALUE = L"initvaluetest"; -BOOST_AUTO_TEST_CASE(testInitValue) +TEST_F(CloseableThreadLocalTest, testInitValue) { class InitValueThreadLocal : public CloseableThreadLocal { @@ -32,23 +32,21 @@ BOOST_AUTO_TEST_CASE(testInitValue) InitValueThreadLocal tl; String str = *(tl.get()); - BOOST_CHECK_EQUAL(TEST_VALUE, str); + EXPECT_EQ(TEST_VALUE, str); } /// Tests that null can be set as a valid value. -BOOST_AUTO_TEST_CASE(testNullValue) +TEST_F(CloseableThreadLocalTest, testNullValue) { CloseableThreadLocal ctl; ctl.set(boost::shared_ptr()); - BOOST_CHECK(!ctl.get()); + EXPECT_TRUE(!ctl.get()); } /// Make sure default get returns null, twice in a row -BOOST_AUTO_TEST_CASE(testDefaultValueWithoutSetting) +TEST_F(CloseableThreadLocalTest, testDefaultValueWithoutSetting) { CloseableThreadLocal ctl; - BOOST_CHECK(!ctl.get()); - BOOST_CHECK(!ctl.get()); + EXPECT_TRUE(!ctl.get()); + EXPECT_TRUE(!ctl.get()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/CompressionToolsTest.cpp b/src/test/util/CompressionToolsTest.cpp index 07620348..967b7eca 100644 --- a/src/test/util/CompressionToolsTest.cpp +++ b/src/test/util/CompressionToolsTest.cpp @@ -10,15 +10,13 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(CompressionToolsTest, LuceneTestFixture) +typedef LuceneTestFixture CompressionToolsTest; -BOOST_AUTO_TEST_CASE(testCompressDecompress) +TEST_F(CompressionToolsTest, testCompressDecompress) { ByteArray compress(CompressionTools::compressString(L"test compressed string")); - BOOST_CHECK(compress.size() > 0); - + EXPECT_TRUE(compress.size() > 0); + String decompress(CompressionTools::decompressString(compress)); - BOOST_CHECK_EQUAL(decompress, L"test compressed string"); + EXPECT_EQ(decompress, L"test compressed string"); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/FieldCacheSanityCheckerTest.cpp b/src/test/util/FieldCacheSanityCheckerTest.cpp index 97bdbba7..3d5942e9 100644 --- a/src/test/util/FieldCacheSanityCheckerTest.cpp +++ b/src/test/util/FieldCacheSanityCheckerTest.cpp @@ -19,10 +19,10 @@ using namespace Lucene; -class FieldCacheSanityCheckerTestFixture : public LuceneTestFixture +class FieldCacheSanityCheckerTest : public LuceneTestFixture { public: - FieldCacheSanityCheckerTestFixture() + FieldCacheSanityCheckerTest() { RAMDirectoryPtr dirA = newLucene(); RAMDirectoryPtr dirB = newLucene(); @@ -52,8 +52,8 @@ class FieldCacheSanityCheckerTestFixture : public LuceneTestFixture readerB = IndexReader::open(dirB, true); readerX = newLucene(newCollection(readerA, readerB)); } - - virtual ~FieldCacheSanityCheckerTestFixture() + + virtual ~FieldCacheSanityCheckerTest() { readerA->close(); readerB->close(); @@ -68,11 +68,9 @@ class FieldCacheSanityCheckerTestFixture : public LuceneTestFixture static const int32_t NUM_DOCS; }; -const int32_t FieldCacheSanityCheckerTestFixture::NUM_DOCS = 1000; - -BOOST_FIXTURE_TEST_SUITE(FieldCacheSanityCheckerTest, FieldCacheSanityCheckerTestFixture) +const int32_t FieldCacheSanityCheckerTest::NUM_DOCS = 1000; -BOOST_AUTO_TEST_CASE(testSanity) +TEST_F(FieldCacheSanityCheckerTest, testSanity) { FieldCachePtr cache = FieldCache::DEFAULT(); cache->purgeAllCaches(); @@ -85,12 +83,12 @@ BOOST_AUTO_TEST_CASE(testSanity) ints = cache->getInts(readerX, L"theInt", FieldCache::DEFAULT_INT_PARSER()); Collection insanity = FieldCacheSanityChecker::checkSanity(cache->getCacheEntries()); - - BOOST_CHECK_EQUAL(0, insanity.size()); + + EXPECT_EQ(0, insanity.size()); cache->purgeAllCaches(); } -BOOST_AUTO_TEST_CASE(testInsanity1) +TEST_F(FieldCacheSanityCheckerTest, testInsanity1) { FieldCachePtr cache = FieldCache::DEFAULT(); cache->purgeAllCaches(); @@ -103,15 +101,15 @@ BOOST_AUTO_TEST_CASE(testInsanity1) Collection insanity = FieldCacheSanityChecker::checkSanity(cache->getCacheEntries()); - BOOST_CHECK_EQUAL(1, insanity.size()); - BOOST_CHECK_EQUAL(FieldCacheSanityChecker::VALUEMISMATCH, insanity[0]->getType()); - BOOST_CHECK_EQUAL(2, insanity[0]->getCacheEntries().size()); + EXPECT_EQ(1, insanity.size()); + EXPECT_EQ(FieldCacheSanityChecker::VALUEMISMATCH, insanity[0]->getType()); + EXPECT_EQ(2, insanity[0]->getCacheEntries().size()); // we expect bad things, don't let tearDown complain about them cache->purgeAllCaches(); } -BOOST_AUTO_TEST_CASE(testInsanity2) +TEST_F(FieldCacheSanityCheckerTest, testInsanity2) { FieldCachePtr cache = FieldCache::DEFAULT(); cache->purgeAllCaches(); @@ -119,18 +117,16 @@ BOOST_AUTO_TEST_CASE(testInsanity2) Collection strings = cache->getStrings(readerA, L"theString"); strings = cache->getStrings(readerB, L"theString"); strings = cache->getStrings(readerX, L"theString"); - + // this one is ok Collection bytes = cache->getBytes(readerX, L"theByte"); Collection insanity = FieldCacheSanityChecker::checkSanity(cache->getCacheEntries()); - BOOST_CHECK_EQUAL(1, insanity.size()); - BOOST_CHECK_EQUAL(FieldCacheSanityChecker::SUBREADER, insanity[0]->getType()); - BOOST_CHECK_EQUAL(3, insanity[0]->getCacheEntries().size()); + EXPECT_EQ(1, insanity.size()); + EXPECT_EQ(FieldCacheSanityChecker::SUBREADER, insanity[0]->getType()); + EXPECT_EQ(3, insanity[0]->getCacheEntries().size()); // we expect bad things, don't let tearDown complain about them cache->purgeAllCaches(); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/FileReaderTest.cpp b/src/test/util/FileReaderTest.cpp index f738c622..400ae76d 100644 --- a/src/test/util/FileReaderTest.cpp +++ b/src/test/util/FileReaderTest.cpp @@ -13,46 +13,44 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(FileReaderTest, LuceneTestFixture) +typedef LuceneTestFixture FileReaderTest; -BOOST_AUTO_TEST_CASE(testFileReaderChar) +TEST_F(FileReaderTest, testFileReaderChar) { FileReaderPtr reader = newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'e'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L's'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L' '); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'f'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'i'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'l'); - BOOST_CHECK_EQUAL((wchar_t)reader->read(), L'e'); + EXPECT_EQ((wchar_t)reader->read(), L't'); + EXPECT_EQ((wchar_t)reader->read(), L'e'); + EXPECT_EQ((wchar_t)reader->read(), L's'); + EXPECT_EQ((wchar_t)reader->read(), L't'); + EXPECT_EQ((wchar_t)reader->read(), L' '); + EXPECT_EQ((wchar_t)reader->read(), L'f'); + EXPECT_EQ((wchar_t)reader->read(), L'i'); + EXPECT_EQ((wchar_t)reader->read(), L'l'); + EXPECT_EQ((wchar_t)reader->read(), L'e'); } -BOOST_AUTO_TEST_CASE(testFileReaderRead) +TEST_F(FileReaderTest, testFileReaderRead) { FileReaderPtr reader = newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")); - + wchar_t buffer[80]; int32_t length = reader->read(buffer, 0, 80); String bufferString(buffer, length); - + boost::replace_all(bufferString, L"\r\n", L"\n"); // account for windows newline characters - - BOOST_CHECK_EQUAL(bufferString, L"test file\nthat contains\nmultiple lines of text\n\n\n1 2 3 4\n"); - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 1), FileReader::FILE_EOF); + + EXPECT_EQ(bufferString, L"test file\nthat contains\nmultiple lines of text\n\n\n1 2 3 4\n"); + EXPECT_EQ(reader->read(buffer, 0, 1), FileReader::FILE_EOF); } -BOOST_AUTO_TEST_CASE(testFileReaderReset) +TEST_F(FileReaderTest, testFileReaderReset) { FileReaderPtr reader = newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")); - + wchar_t buffer[20]; - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 9), 9); - BOOST_CHECK_EQUAL(String(buffer, 9), L"test file"); + EXPECT_EQ(reader->read(buffer, 0, 9), 9); + EXPECT_EQ(String(buffer, 9), L"test file"); reader->reset(); - BOOST_CHECK_EQUAL(reader->read(buffer, 0, 9), 9); - BOOST_CHECK_EQUAL(String(buffer, 9), L"test file"); + EXPECT_EQ(reader->read(buffer, 0, 9), 9); + EXPECT_EQ(String(buffer, 9), L"test file"); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/FileUtilsTest.cpp b/src/test/util/FileUtilsTest.cpp index f7f7324d..5ca6ffbf 100644 --- a/src/test/util/FileUtilsTest.cpp +++ b/src/test/util/FileUtilsTest.cpp @@ -12,210 +12,208 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(FileUtilsTest, LuceneTestFixture) +typedef LuceneTestFixture FileUtilsTest; -BOOST_AUTO_TEST_CASE(testFileExists) +TEST_F(FileUtilsTest, testFileExists) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); - BOOST_CHECK(FileUtils::fileExists(fileDir)); + EXPECT_TRUE(FileUtils::fileExists(fileDir)); } -BOOST_AUTO_TEST_CASE(testFileModified) +TEST_F(FileUtilsTest, testFileModified) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); - + uint64_t fileModified = FileUtils::fileModified(fileDir); - BOOST_CHECK_NE(fileModified, 0); - + EXPECT_NE(fileModified, 0); + struct tm *fileTime = localtime((const time_t*)&fileModified); - BOOST_CHECK(fileTime != NULL); + EXPECT_TRUE(fileTime != NULL); } -BOOST_AUTO_TEST_CASE(testInvalidFileModified) +TEST_F(FileUtilsTest, testInvalidFileModified) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); - BOOST_CHECK_EQUAL(FileUtils::fileModified(fileDir), 0); + EXPECT_EQ(FileUtils::fileModified(fileDir), 0); } -BOOST_AUTO_TEST_CASE(testTouchFile) +TEST_F(FileUtilsTest, testTouchFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); - - BOOST_CHECK(FileUtils::touchFile(fileDir)); - + + EXPECT_TRUE(FileUtils::touchFile(fileDir)); + uint64_t fileModified = FileUtils::fileModified(fileDir); - BOOST_CHECK_NE(fileModified, 0); - + EXPECT_NE(fileModified, 0); + struct tm *fileTime = localtime((const time_t*)&fileModified); - BOOST_CHECK(fileTime != NULL); - + EXPECT_TRUE(fileTime != NULL); + time_t current = time(NULL); struct tm *currentTime = localtime((const time_t*)¤t); - - BOOST_CHECK_EQUAL(fileTime->tm_year, currentTime->tm_year); - BOOST_CHECK_EQUAL(fileTime->tm_mon, currentTime->tm_mon); - BOOST_CHECK_EQUAL(fileTime->tm_mday, currentTime->tm_mday); + + EXPECT_EQ(fileTime->tm_year, currentTime->tm_year); + EXPECT_EQ(fileTime->tm_mon, currentTime->tm_mon); + EXPECT_EQ(fileTime->tm_mday, currentTime->tm_mday); } -BOOST_AUTO_TEST_CASE(testInvalidTouchFile) +TEST_F(FileUtilsTest, testInvalidTouchFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); - BOOST_CHECK(!FileUtils::touchFile(fileDir)); + EXPECT_TRUE(!FileUtils::touchFile(fileDir)); } -BOOST_AUTO_TEST_CASE(testFileLength) +TEST_F(FileUtilsTest, testFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfilesize1.txt")); int64_t fileLength = FileUtils::fileLength(fileDir); - BOOST_CHECK_EQUAL(fileLength, 29); + EXPECT_EQ(fileLength, 29); } -BOOST_AUTO_TEST_CASE(testInvalidFileLength) +TEST_F(FileUtilsTest, testInvalidFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); - BOOST_CHECK_EQUAL(FileUtils::fileLength(fileDir), 0); + EXPECT_EQ(FileUtils::fileLength(fileDir), 0); } -BOOST_AUTO_TEST_CASE(testSetFileLength) +TEST_F(FileUtilsTest, testSetFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfilesize2.txt")); - - BOOST_CHECK(FileUtils::setFileLength(fileDir, 1234)); - + + EXPECT_TRUE(FileUtils::setFileLength(fileDir, 1234)); + int64_t fileLengthGrow = FileUtils::fileLength(fileDir); - BOOST_CHECK_EQUAL(fileLengthGrow, 1234); - - BOOST_CHECK(FileUtils::setFileLength(fileDir, 29)); - + EXPECT_EQ(fileLengthGrow, 1234); + + EXPECT_TRUE(FileUtils::setFileLength(fileDir, 29)); + int64_t fileLengthShrink = FileUtils::fileLength(fileDir); - BOOST_CHECK_EQUAL(fileLengthShrink, 29); + EXPECT_EQ(fileLengthShrink, 29); } -BOOST_AUTO_TEST_CASE(testInvalidSetFileLength) +TEST_F(FileUtilsTest, testInvalidSetFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); - BOOST_CHECK(!FileUtils::setFileLength(fileDir, 1234)); + EXPECT_TRUE(!FileUtils::setFileLength(fileDir, 1234)); } -BOOST_AUTO_TEST_CASE(testRemoveFile) +TEST_F(FileUtilsTest, testRemoveFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testdelete.txt")); - + std::ofstream f(StringUtils::toUTF8(fileDir).c_str(), std::ios::binary | std::ios::out); f.close(); - - BOOST_CHECK(FileUtils::fileExists(fileDir)); - BOOST_CHECK(FileUtils::removeFile(fileDir)); - BOOST_CHECK(!FileUtils::fileExists(fileDir)); + + EXPECT_TRUE(FileUtils::fileExists(fileDir)); + EXPECT_TRUE(FileUtils::removeFile(fileDir)); + EXPECT_TRUE(!FileUtils::fileExists(fileDir)); } -BOOST_AUTO_TEST_CASE(testInvalidRemoveFile) +TEST_F(FileUtilsTest, testInvalidRemoveFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); - BOOST_CHECK(!FileUtils::removeFile(fileDir)); + EXPECT_TRUE(!FileUtils::removeFile(fileDir)); } -BOOST_AUTO_TEST_CASE(testIsDirectory) +TEST_F(FileUtilsTest, testIsDirectory) { String fileDir(FileUtils::joinPath(getTestDir(), L"testdirectory")); - BOOST_CHECK(FileUtils::isDirectory(fileDir)); + EXPECT_TRUE(FileUtils::isDirectory(fileDir)); } -BOOST_AUTO_TEST_CASE(testNotDirectory) +TEST_F(FileUtilsTest, testNotDirectory) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); - BOOST_CHECK(!FileUtils::isDirectory(fileDir)); + EXPECT_TRUE(!FileUtils::isDirectory(fileDir)); } -BOOST_AUTO_TEST_CASE(testNotDirectoryEmpty) +TEST_F(FileUtilsTest, testNotDirectoryEmpty) { - BOOST_CHECK(!FileUtils::isDirectory(L"")); + EXPECT_TRUE(!FileUtils::isDirectory(L"")); } -BOOST_AUTO_TEST_CASE(testListDirectory) +TEST_F(FileUtilsTest, testListDirectory) { String fileDir(FileUtils::joinPath(getTestDir(), L"testdirectory")); - + HashSet list(HashSet::newInstance()); - BOOST_CHECK(FileUtils::listDirectory(fileDir, false, list)); - + EXPECT_TRUE(FileUtils::listDirectory(fileDir, false, list)); + Collection expectedList(Collection::newInstance(list.begin(), list.end())); std::sort(expectedList.begin(), expectedList.end()); - - BOOST_CHECK_EQUAL(expectedList.size(), 6); - BOOST_CHECK_EQUAL(expectedList[0], L"subdirectory"); - BOOST_CHECK_EQUAL(expectedList[1], L"testfile1.txt"); - BOOST_CHECK_EQUAL(expectedList[2], L"testfile2.txt"); - BOOST_CHECK_EQUAL(expectedList[3], L"testfile3.txt"); - BOOST_CHECK_EQUAL(expectedList[4], L"testfilesize1.txt"); - BOOST_CHECK_EQUAL(expectedList[5], L"testfilesize2.txt"); + + EXPECT_EQ(expectedList.size(), 6); + EXPECT_EQ(expectedList[0], L"subdirectory"); + EXPECT_EQ(expectedList[1], L"testfile1.txt"); + EXPECT_EQ(expectedList[2], L"testfile2.txt"); + EXPECT_EQ(expectedList[3], L"testfile3.txt"); + EXPECT_EQ(expectedList[4], L"testfilesize1.txt"); + EXPECT_EQ(expectedList[5], L"testfilesize2.txt"); } -BOOST_AUTO_TEST_CASE(testListDirectoryFiles) +TEST_F(FileUtilsTest, testListDirectoryFiles) { String fileDir(FileUtils::joinPath(getTestDir(), L"testdirectory")); - + HashSet list(HashSet::newInstance()); - BOOST_CHECK(FileUtils::listDirectory(fileDir, true, list)); - + EXPECT_TRUE(FileUtils::listDirectory(fileDir, true, list)); + Collection expectedList(Collection::newInstance(list.begin(), list.end())); std::sort(expectedList.begin(), expectedList.end()); - - BOOST_CHECK_EQUAL(expectedList.size(), 5); - BOOST_CHECK_EQUAL(expectedList[0], L"testfile1.txt"); - BOOST_CHECK_EQUAL(expectedList[1], L"testfile2.txt"); - BOOST_CHECK_EQUAL(expectedList[2], L"testfile3.txt"); - BOOST_CHECK_EQUAL(expectedList[3], L"testfilesize1.txt"); - BOOST_CHECK_EQUAL(expectedList[4], L"testfilesize2.txt"); + + EXPECT_EQ(expectedList.size(), 5); + EXPECT_EQ(expectedList[0], L"testfile1.txt"); + EXPECT_EQ(expectedList[1], L"testfile2.txt"); + EXPECT_EQ(expectedList[2], L"testfile3.txt"); + EXPECT_EQ(expectedList[3], L"testfilesize1.txt"); + EXPECT_EQ(expectedList[4], L"testfilesize2.txt"); } -BOOST_AUTO_TEST_CASE(testJoinPath) +TEST_F(FileUtilsTest, testJoinPath) { #if defined(_WIN32) || defined(_WIN64) - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"c:\\test", L"\\testfile.txt"), L"c:\\test\\testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"c:\\test", L"testfile.txt"), L"c:\\test\\testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"c:\\test", L""), L"c:\\test"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"\\test", L"\\testfile.txt"), L"\\test\\testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"\\test", L"testfile.txt"), L"\\test\\testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"\\test", L""), L"\\test"); + EXPECT_EQ(FileUtils::joinPath(L"c:\\test", L"\\testfile.txt"), L"c:\\test\\testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"c:\\test", L"testfile.txt"), L"c:\\test\\testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"c:\\test", L""), L"c:\\test"); + EXPECT_EQ(FileUtils::joinPath(L"\\test", L"\\testfile.txt"), L"\\test\\testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"\\test", L"testfile.txt"), L"\\test\\testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"\\test", L""), L"\\test"); #else - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"/test", L"/testfile.txt"), L"/test/testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"/test", L"testfile.txt"), L"/test/testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::joinPath(L"/test", L""), L"/test"); + EXPECT_EQ(FileUtils::joinPath(L"/test", L"/testfile.txt"), L"/test/testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"/test", L"testfile.txt"), L"/test/testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); + EXPECT_EQ(FileUtils::joinPath(L"/test", L""), L"/test"); #endif } -BOOST_AUTO_TEST_CASE(testExtractPath) +TEST_F(FileUtilsTest, testExtractPath) { #if defined(_WIN32) || defined(_WIN64) - BOOST_CHECK_EQUAL(FileUtils::extractPath(L"c:\\test"), L"c:\\"); - BOOST_CHECK_EQUAL(FileUtils::extractPath(L"c:\\test\\testfile.txt"), L"c:\\test"); - BOOST_CHECK_EQUAL(FileUtils::extractPath(L""), L""); - BOOST_CHECK_EQUAL(FileUtils::extractPath(L"\\test"), L"\\"); - BOOST_CHECK_EQUAL(FileUtils::extractPath(L"\\test\\testfile.txt"), L"\\test"); + EXPECT_EQ(FileUtils::extractPath(L"c:\\test"), L"c:\\"); + EXPECT_EQ(FileUtils::extractPath(L"c:\\test\\testfile.txt"), L"c:\\test"); + EXPECT_EQ(FileUtils::extractPath(L""), L""); + EXPECT_EQ(FileUtils::extractPath(L"\\test"), L"\\"); + EXPECT_EQ(FileUtils::extractPath(L"\\test\\testfile.txt"), L"\\test"); #else - BOOST_CHECK_EQUAL(FileUtils::extractPath(L"/test"), L"/"); - BOOST_CHECK_EQUAL(FileUtils::extractPath(L"/test/testfile.txt"), L"/test"); - BOOST_CHECK_EQUAL(FileUtils::extractPath(L""), L""); + EXPECT_EQ(FileUtils::extractPath(L"/test"), L"/"); + EXPECT_EQ(FileUtils::extractPath(L"/test/testfile.txt"), L"/test"); + EXPECT_EQ(FileUtils::extractPath(L""), L""); #endif } -BOOST_AUTO_TEST_CASE(testExtractFile) +TEST_F(FileUtilsTest, testExtractFile) { #if defined(_WIN32) || defined(_WIN64) - BOOST_CHECK_EQUAL(FileUtils::extractFile(L"c:\\test"), L"test"); - BOOST_CHECK_EQUAL(FileUtils::extractFile(L"c:\\test\\testfile.txt"), L"testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::extractFile(L""), L""); - BOOST_CHECK_EQUAL(FileUtils::extractFile(L"\\test"), L"test"); - BOOST_CHECK_EQUAL(FileUtils::extractFile(L"\\test\\testfile.txt"), L"testfile.txt"); + EXPECT_EQ(FileUtils::extractFile(L"c:\\test"), L"test"); + EXPECT_EQ(FileUtils::extractFile(L"c:\\test\\testfile.txt"), L"testfile.txt"); + EXPECT_EQ(FileUtils::extractFile(L""), L""); + EXPECT_EQ(FileUtils::extractFile(L"\\test"), L"test"); + EXPECT_EQ(FileUtils::extractFile(L"\\test\\testfile.txt"), L"testfile.txt"); #else - BOOST_CHECK_EQUAL(FileUtils::extractFile(L"/test"), L"test"); - BOOST_CHECK_EQUAL(FileUtils::extractFile(L"/test/testfile.txt"), L"testfile.txt"); - BOOST_CHECK_EQUAL(FileUtils::extractFile(L""), L""); + EXPECT_EQ(FileUtils::extractFile(L"/test"), L"test"); + EXPECT_EQ(FileUtils::extractFile(L"/test/testfile.txt"), L"testfile.txt"); + EXPECT_EQ(FileUtils::extractFile(L""), L""); #endif } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/InputStreamReaderTest.cpp b/src/test/util/InputStreamReaderTest.cpp index 42f1abce..54587f87 100644 --- a/src/test/util/InputStreamReaderTest.cpp +++ b/src/test/util/InputStreamReaderTest.cpp @@ -14,81 +14,79 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(InputStreamReaderTest, LuceneTestFixture) +typedef LuceneTestFixture InputStreamReaderTest; -BOOST_AUTO_TEST_CASE(testInputStreamReaderChar) +TEST_F(InputStreamReaderTest, testInputStreamReaderChar) { InputStreamReaderPtr stream = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L'e'); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L's'); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L' '); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L'f'); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L'i'); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L'l'); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), L'e'); + EXPECT_EQ((wchar_t)stream->read(), L't'); + EXPECT_EQ((wchar_t)stream->read(), L'e'); + EXPECT_EQ((wchar_t)stream->read(), L's'); + EXPECT_EQ((wchar_t)stream->read(), L't'); + EXPECT_EQ((wchar_t)stream->read(), L' '); + EXPECT_EQ((wchar_t)stream->read(), L'f'); + EXPECT_EQ((wchar_t)stream->read(), L'i'); + EXPECT_EQ((wchar_t)stream->read(), L'l'); + EXPECT_EQ((wchar_t)stream->read(), L'e'); } -BOOST_AUTO_TEST_CASE(testInputStreamReaderCharUtf8) +TEST_F(InputStreamReaderTest, testInputStreamReaderCharUtf8) { InputStreamReaderPtr stream = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_uft8.txt"))); - - const uint8_t chinese[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, + + const uint8_t chinese[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd}; String expectedChinese(UTF8_TO_STRING(chinese)); - - BOOST_CHECK_EQUAL((wchar_t)stream->read(), expectedChinese[0]); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), expectedChinese[1]); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), expectedChinese[2]); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), expectedChinese[3]); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), expectedChinese[4]); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), expectedChinese[5]); - BOOST_CHECK_EQUAL((wchar_t)stream->read(), expectedChinese[6]); + + EXPECT_EQ((wchar_t)stream->read(), expectedChinese[0]); + EXPECT_EQ((wchar_t)stream->read(), expectedChinese[1]); + EXPECT_EQ((wchar_t)stream->read(), expectedChinese[2]); + EXPECT_EQ((wchar_t)stream->read(), expectedChinese[3]); + EXPECT_EQ((wchar_t)stream->read(), expectedChinese[4]); + EXPECT_EQ((wchar_t)stream->read(), expectedChinese[5]); + EXPECT_EQ((wchar_t)stream->read(), expectedChinese[6]); } -BOOST_AUTO_TEST_CASE(testInputStreamReaderReadLine) +TEST_F(InputStreamReaderTest, testInputStreamReaderReadLine) { BufferedReaderPtr reader = newLucene(newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")))); - + Collection readLines = Collection::newInstance(); String line; - + while (reader->readLine(line)) readLines.add(line); - - BOOST_CHECK_EQUAL(reader->read(), FileReader::FILE_EOF); - BOOST_CHECK_EQUAL(readLines.size(), 6); - BOOST_CHECK_EQUAL(readLines[0], L"test file"); - BOOST_CHECK_EQUAL(readLines[1], L"that contains"); - BOOST_CHECK_EQUAL(readLines[2], L"multiple lines of text"); - BOOST_CHECK_EQUAL(readLines[3], L""); - BOOST_CHECK_EQUAL(readLines[4], L""); - BOOST_CHECK_EQUAL(readLines[5], L"1 2 3 4"); + + EXPECT_EQ(reader->read(), FileReader::FILE_EOF); + EXPECT_EQ(readLines.size(), 6); + EXPECT_EQ(readLines[0], L"test file"); + EXPECT_EQ(readLines[1], L"that contains"); + EXPECT_EQ(readLines[2], L"multiple lines of text"); + EXPECT_EQ(readLines[3], L""); + EXPECT_EQ(readLines[4], L""); + EXPECT_EQ(readLines[5], L"1 2 3 4"); } -BOOST_AUTO_TEST_CASE(testInputStreamReaderReadLineUtf8) +TEST_F(InputStreamReaderTest, testInputStreamReaderReadLineUtf8) { BufferedReaderPtr reader = newLucene(newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_uft8.txt")))); - + Collection readLines = Collection::newInstance(); String line; - + while (reader->readLine(line)) readLines.add(line); - const uint8_t chinese[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, + const uint8_t chinese[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd}; - + const uint8_t persian[] = {0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87}; - + const uint8_t russian[] = {0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x81, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8e}; - BOOST_CHECK_EQUAL(readLines.size(), 80); - BOOST_CHECK_EQUAL(readLines[0], UTF8_TO_STRING(chinese)); - BOOST_CHECK_EQUAL(readLines[1], UTF8_TO_STRING(persian)); - BOOST_CHECK_EQUAL(readLines[2], UTF8_TO_STRING(russian)); + EXPECT_EQ(readLines.size(), 80); + EXPECT_EQ(readLines[0], UTF8_TO_STRING(chinese)); + EXPECT_EQ(readLines[1], UTF8_TO_STRING(persian)); + EXPECT_EQ(readLines[2], UTF8_TO_STRING(russian)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/LuceneGlobalFixture.cpp b/src/test/util/LuceneGlobalFixture.cpp index 680a7de2..24ab7c50 100644 --- a/src/test/util/LuceneGlobalFixture.cpp +++ b/src/test/util/LuceneGlobalFixture.cpp @@ -18,12 +18,10 @@ namespace Lucene FileUtils::createDirectory(getTempDir()); TestPoint::enableTestPoints(); } - + LuceneGlobalFixture::~LuceneGlobalFixture() { FileUtils::removeDirectory(getTempDir()); Lucene::CycleCheck::dumpRefs(); } - - BOOST_GLOBAL_FIXTURE(LuceneGlobalFixture); } diff --git a/src/test/util/LuceneTestFixture.cpp b/src/test/util/LuceneTestFixture.cpp index c24ae379..3f34a390 100644 --- a/src/test/util/LuceneTestFixture.cpp +++ b/src/test/util/LuceneTestFixture.cpp @@ -16,7 +16,7 @@ namespace Lucene DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); ConcurrentMergeScheduler::setTestMode(); } - + LuceneTestFixture::~LuceneTestFixture() { DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); @@ -24,7 +24,7 @@ namespace Lucene { // Clear the failure so that we don't just keep failing subsequent test cases ConcurrentMergeScheduler::clearUnhandledExceptions(); - BOOST_FAIL("ConcurrentMergeScheduler hit unhandled exceptions"); + FAIL() << "ConcurrentMergeScheduler hit unhandled exceptions"; } } } diff --git a/src/test/util/NumericUtilsTest.cpp b/src/test/util/NumericUtilsTest.cpp index 8516e95b..51f06f5b 100644 --- a/src/test/util/NumericUtilsTest.cpp +++ b/src/test/util/NumericUtilsTest.cpp @@ -13,12 +13,12 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(NumericUtilsTest, LuceneTestFixture) +typedef LuceneTestFixture NumericUtilsTest; class CheckLongRangeBuilder : public LongRangeBuilder { public: - CheckLongRangeBuilder(int64_t lower, int64_t upper, OpenBitSetPtr bits, + CheckLongRangeBuilder(int64_t lower, int64_t upper, OpenBitSetPtr bits, Collection::iterator neededBoundsFirst, Collection::iterator neededBoundsLast, Collection::iterator neededShiftsFirst, @@ -32,7 +32,7 @@ class CheckLongRangeBuilder : public LongRangeBuilder this->neededShiftsFirst = neededShiftsFirst; this->neededShiftsLast = neededShiftsLast; } - + virtual ~CheckLongRangeBuilder() { } @@ -49,49 +49,49 @@ class CheckLongRangeBuilder : public LongRangeBuilder public: virtual void addRange(int64_t min, int64_t max, int32_t shift) { - BOOST_CHECK(min >= lower && min <= upper && max >= lower && max <= upper); + EXPECT_TRUE(min >= lower && min <= upper && max >= lower && max <= upper); if (bits) { for (int64_t l = min; l <= max; ++l) { - if (bits->getAndSet((int32_t)(l - lower))) - BOOST_FAIL("getAndSet failure"); + if (bits->getAndSet((int64_t)(l - lower))) + FAIL() << "getAndSet failure"; // extra exit condition to prevent overflow on MAX_VALUE if (l == max) break; } } - + if (neededBoundsFirst == neededBoundsLast || neededShiftsFirst == neededShiftsLast) return; - + // make unsigned longs for easier display and understanding min ^= 0x8000000000000000LL; max ^= 0x8000000000000000LL; - - BOOST_CHECK_EQUAL(*neededShiftsFirst++, shift); - BOOST_CHECK_EQUAL(*neededBoundsFirst++, MiscUtils::unsignedShift(min, (int64_t)shift)); // inner min bound - BOOST_CHECK_EQUAL(*neededBoundsFirst++, MiscUtils::unsignedShift(max, (int64_t)shift)); // inner max bound + + EXPECT_EQ(*neededShiftsFirst++, shift); + EXPECT_EQ(*neededBoundsFirst++, MiscUtils::unsignedShift(min, (int64_t)shift)); // inner min bound + EXPECT_EQ(*neededBoundsFirst++, MiscUtils::unsignedShift(max, (int64_t)shift)); // inner max bound } }; static void checkLongRangeSplit(int64_t lower, int64_t upper, int32_t precisionStep, bool useBitSet, Collection neededBounds, Collection neededShifts) { - OpenBitSetPtr bits = useBitSet ? newLucene((int32_t)(upper - lower + 1)) : OpenBitSetPtr(); + OpenBitSetPtr bits = useBitSet ? newLucene((int64_t)(upper - lower + 1)) : OpenBitSetPtr(); NumericUtils::splitLongRange(newLucene(lower, upper, bits, neededBounds.begin(), neededBounds.end(), neededShifts.begin(), neededShifts.end()), precisionStep, lower, upper); - + if (useBitSet) { // after flipping all bits in the range, the cardinality should be zero - bits->flip(0, (int32_t)(upper - lower + 1)); - BOOST_CHECK(bits->isEmpty()); + bits->flip(0, (int64_t)(upper - lower + 1)); + EXPECT_TRUE(bits->isEmpty()); } } class CheckIntRangeBuilder : public IntRangeBuilder { public: - CheckIntRangeBuilder(int32_t lower, int32_t upper, OpenBitSetPtr bits, + CheckIntRangeBuilder(int32_t lower, int32_t upper, OpenBitSetPtr bits, Collection::iterator neededBoundsFirst, Collection::iterator neededBoundsLast, Collection::iterator neededShiftsFirst, @@ -105,7 +105,7 @@ class CheckIntRangeBuilder : public IntRangeBuilder this->neededShiftsFirst = neededShiftsFirst; this->neededShiftsLast = neededShiftsLast; } - + virtual ~CheckIntRangeBuilder() { } @@ -122,29 +122,29 @@ class CheckIntRangeBuilder : public IntRangeBuilder public: virtual void addRange(int32_t min, int32_t max, int32_t shift) { - BOOST_CHECK(min >= lower && min <= upper && max >= lower && max <= upper); + EXPECT_TRUE(min >= lower && min <= upper && max >= lower && max <= upper); if (bits) { for (int32_t l = min; l <= max; ++l) { if (bits->getAndSet((int32_t)(l - lower))) - BOOST_FAIL("getAndSet failure"); + FAIL() << "getAndSet failure"; // extra exit condition to prevent overflow on MAX_VALUE if (l == max) break; } } - + if (neededBoundsFirst == neededBoundsLast || neededShiftsFirst == neededShiftsLast) return; // make unsigned longs for easier display and understanding min ^= 0x80000000; max ^= 0x80000000; - - BOOST_CHECK_EQUAL(*neededShiftsFirst++, shift); - BOOST_CHECK_EQUAL(*neededBoundsFirst++, MiscUtils::unsignedShift(min, shift)); // inner min bound - BOOST_CHECK_EQUAL(*neededBoundsFirst++, MiscUtils::unsignedShift(max, shift)); // inner max bound + + EXPECT_EQ(*neededShiftsFirst++, shift); + EXPECT_EQ(*neededBoundsFirst++, MiscUtils::unsignedShift(min, shift)); // inner min bound + EXPECT_EQ(*neededBoundsFirst++, MiscUtils::unsignedShift(max, shift)); // inner max bound } }; @@ -152,16 +152,16 @@ static void checkIntRangeSplit(int32_t lower, int32_t upper, int32_t precisionSt { OpenBitSetPtr bits = useBitSet ? newLucene((int32_t)(upper - lower + 1)) : OpenBitSetPtr(); NumericUtils::splitIntRange(newLucene(lower, upper, bits, neededBounds.begin(), neededBounds.end(), neededShifts.begin(), neededShifts.end()), precisionStep, lower, upper); - + if (useBitSet) { // after flipping all bits in the range, the cardinality should be zero bits->flip(0, (int32_t)(upper - lower + 1)); - BOOST_CHECK(bits->isEmpty()); + EXPECT_TRUE(bits->isEmpty()); } } - -BOOST_AUTO_TEST_CASE(testLongConversionAndOrdering) + +TEST_F(NumericUtilsTest, testLongConversionAndOrdering) { // generate a series of encoded longs, each numerical one bigger than the one before String last; @@ -172,16 +172,16 @@ BOOST_AUTO_TEST_CASE(testLongConversionAndOrdering) { // test if smaller if (last.compare(act) >= 0) - BOOST_FAIL("compare failure"); + FAIL() << "compare failure"; } // test is back and forward conversion works - BOOST_CHECK_EQUAL(l, NumericUtils::prefixCodedToLong(act)); + EXPECT_EQ(l, NumericUtils::prefixCodedToLong(act)); // next step last = act; } } -BOOST_AUTO_TEST_CASE(testIntConversionAndOrdering) +TEST_F(NumericUtilsTest, testIntConversionAndOrdering) { // generate a series of encoded ints, each numerical one bigger than the one before String last; @@ -192,19 +192,19 @@ BOOST_AUTO_TEST_CASE(testIntConversionAndOrdering) { // test if smaller if (last.compare(act) >= 0) - BOOST_FAIL("compare failure"); + FAIL() << "compare failure"; } // test is back and forward conversion works - BOOST_CHECK_EQUAL(l, NumericUtils::prefixCodedToInt(act)); + EXPECT_EQ(l, NumericUtils::prefixCodedToInt(act)); // next step last = act; } } -BOOST_AUTO_TEST_CASE(testLongSpecialValues) +TEST_F(NumericUtilsTest, testLongSpecialValues) { - static const int64_t vals[] = {LLONG_MIN, LLONG_MIN + 1, LLONG_MIN + 2, -5003400000000LL, -4000LL, -3000LL, - -2000LL, -1000LL, -1LL, 0LL, 1LL, 10LL, 300LL, 50006789999999999LL, + static const int64_t vals[] = {LLONG_MIN, LLONG_MIN + 1, LLONG_MIN + 2, -5003400000000LL, -4000LL, -3000LL, + -2000LL, -1000LL, -1LL, 0LL, 1LL, 10LL, 300LL, 50006789999999999LL, LLONG_MAX - 2, LLONG_MAX - 1, LLONG_MAX}; int32_t length = SIZEOF_ARRAY(vals); Collection prefixVals = Collection::newInstance(length); @@ -213,17 +213,24 @@ BOOST_AUTO_TEST_CASE(testLongSpecialValues) prefixVals[i] = NumericUtils::longToPrefixCoded(vals[i]); // check forward and back conversion - BOOST_CHECK_EQUAL(vals[i], NumericUtils::prefixCodedToLong(prefixVals[i])); - + EXPECT_EQ(vals[i], NumericUtils::prefixCodedToLong(prefixVals[i])); + // test if decoding values as long fails correctly - BOOST_CHECK_EXCEPTION(NumericUtils::prefixCodedToInt(prefixVals[i]), NumberFormatException, check_exception(LuceneException::NumberFormat)); + try + { + NumericUtils::prefixCodedToInt(prefixVals[i]); + } + catch (NumberFormatException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); + } } - + // check sort order (prefixVals should be ascending) for (int32_t i = 1; i < prefixVals.size(); ++i) - BOOST_CHECK(prefixVals[i - 1].compare(prefixVals[i]) < 0); - - // check the prefix encoding, lower precision should have the difference to original + EXPECT_TRUE(prefixVals[i - 1].compare(prefixVals[i]) < 0); + + // check the prefix encoding, lower precision should have the difference to original // value equal to the lower removed bits for (int32_t i = 0; i < length; ++i) { @@ -231,12 +238,12 @@ BOOST_AUTO_TEST_CASE(testLongSpecialValues) { int64_t prefixVal = NumericUtils::prefixCodedToLong(NumericUtils::longToPrefixCoded(vals[i], j)); int64_t mask = ((int64_t)1 << j) - 1; - BOOST_CHECK_EQUAL(vals[i] & mask, vals[i] - prefixVal); + EXPECT_EQ(vals[i] & mask, vals[i] - prefixVal); } } } -BOOST_AUTO_TEST_CASE(testIntSpecialValues) +TEST_F(NumericUtilsTest, testIntSpecialValues) { static const int32_t vals[] = {INT_MIN, INT_MIN + 1, INT_MIN + 2, -64765767, -4000, -3000, -2000, -1000, -1, 0, 1, 10, 300, 765878989, INT_MAX - 2, INT_MAX- 1, INT_MAX}; @@ -247,17 +254,24 @@ BOOST_AUTO_TEST_CASE(testIntSpecialValues) prefixVals[i] = NumericUtils::intToPrefixCoded(vals[i]); // check forward and back conversion - BOOST_CHECK_EQUAL(vals[i], NumericUtils::prefixCodedToInt(prefixVals[i])); - + EXPECT_EQ(vals[i], NumericUtils::prefixCodedToInt(prefixVals[i])); + // test if decoding values as long fails correctly - BOOST_CHECK_EXCEPTION(NumericUtils::prefixCodedToLong(prefixVals[i]), NumberFormatException, check_exception(LuceneException::NumberFormat)); + try + { + NumericUtils::prefixCodedToLong(prefixVals[i]); + } + catch (NumberFormatException& e) + { + EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); + } } - + // check sort order (prefixVals should be ascending) for (int32_t i = 1; i < prefixVals.size(); ++i) - BOOST_CHECK(prefixVals[i - 1].compare(prefixVals[i]) < 0); - - // check the prefix encoding, lower precision should have the difference to original + EXPECT_TRUE(prefixVals[i - 1].compare(prefixVals[i]) < 0); + + // check the prefix encoding, lower precision should have the difference to original // value equal to the lower removed bits for (int32_t i = 0; i < length; ++i) { @@ -265,71 +279,71 @@ BOOST_AUTO_TEST_CASE(testIntSpecialValues) { int32_t prefixVal = NumericUtils::prefixCodedToInt(NumericUtils::intToPrefixCoded(vals[i], j)); int32_t mask = ((int32_t)1 << j) - 1; - BOOST_CHECK_EQUAL(vals[i] & mask, vals[i] - prefixVal); + EXPECT_EQ(vals[i] & mask, vals[i] - prefixVal); } } } -BOOST_AUTO_TEST_CASE(testDoubles) +TEST_F(NumericUtilsTest, testDoubles) { - static const double vals[] = {-std::numeric_limits::infinity(), -2.3E25, -1.0E15, -1.0, - -1.0E-1, -1.0E-2, -0.0, +0.0, 1.0E-2, 1.0E-1, 1.0, 1.0E15, 2.3E25, + static const double vals[] = {-std::numeric_limits::infinity(), -2.3E25, -1.0E15, -1.0, + -1.0E-1, -1.0E-2, -0.0, +0.0, 1.0E-2, 1.0E-1, 1.0, 1.0E15, 2.3E25, std::numeric_limits::infinity()}; int32_t length = SIZEOF_ARRAY(vals); Collection longVals = Collection::newInstance(length); - + // check forward and back conversion for (int32_t i = 0; i < length; ++i) { longVals[i] = NumericUtils::doubleToSortableLong(vals[i]); - BOOST_CHECK_EQUAL(vals[i], NumericUtils::sortableLongToDouble(longVals[i])); + EXPECT_EQ(vals[i], NumericUtils::sortableLongToDouble(longVals[i])); } - + // check sort order (longVals should be ascending) for (int32_t i = 1; i < longVals.size(); ++i) - BOOST_CHECK(longVals[i - 1] < longVals[i]); + EXPECT_TRUE(longVals[i - 1] < longVals[i]); } /// NumericRangeQuery errors with endpoints near long min and max values -BOOST_AUTO_TEST_CASE(testLongExtremeValues) +TEST_F(NumericUtilsTest, testLongExtremeValues) { // upper end extremes - checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 1, true, + checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 1, true, newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), newCollection(0) ); - checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 2, true, + checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 2, true, newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), newCollection(0) ); - checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 4, true, + checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 4, true, newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), newCollection(0) ); - checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 6, true, + checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 6, true, newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), newCollection(0) ); - checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 8, true, + checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 8, true, newCollection(0xffffffffffffffffLL ,0xffffffffffffffffLL), newCollection(0) ); - checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 64, true, + checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 64, true, newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), newCollection(0) ); - checkLongRangeSplit(LLONG_MAX - 0xfLL, LLONG_MAX, 4, true, + checkLongRangeSplit(LLONG_MAX - 0xfLL, LLONG_MAX, 4, true, newCollection(0xfffffffffffffffLL, 0xfffffffffffffffLL), newCollection(4) ); - checkLongRangeSplit(LLONG_MAX - 0x10LL, LLONG_MAX, 4, true, + checkLongRangeSplit(LLONG_MAX - 0x10LL, LLONG_MAX, 4, true, newCollection(0xffffffffffffffefLL, 0xffffffffffffffefLL, 0xfffffffffffffffLL, 0xfffffffffffffffLL), newCollection(0, 4) ); // lower end extremes - checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 1, true, + checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 1, true, newCollection(0x0000000000000000LL,0x0000000000000000LL), newCollection(0) ); @@ -337,7 +351,7 @@ BOOST_AUTO_TEST_CASE(testLongExtremeValues) newCollection(0x0000000000000000LL, 0x0000000000000000LL), newCollection(0) ); - checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 4, true, + checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 4, true, newCollection(0x0000000000000000LL, 0x0000000000000000LL), newCollection(0) ); @@ -345,11 +359,11 @@ BOOST_AUTO_TEST_CASE(testLongExtremeValues) newCollection(0x0000000000000000LL, 0x0000000000000000LL), newCollection(0) ); - checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 8, true, + checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 8, true, newCollection(0x0000000000000000LL, 0x0000000000000000LL), newCollection(0) ); - checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 64, true, + checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 64, true, newCollection(0x0000000000000000LL, 0x0000000000000000LL), newCollection(0) ); @@ -358,7 +372,7 @@ BOOST_AUTO_TEST_CASE(testLongExtremeValues) newCollection(0x000000000000000LL, 0x000000000000000LL), newCollection(4) ); - checkLongRangeSplit(LLONG_MIN, LLONG_MIN + 0x10LL, 4, true, + checkLongRangeSplit(LLONG_MIN, LLONG_MIN + 0x10LL, 4, true, newCollection(0x0000000000000010LL, 0x0000000000000010LL, 0x000000000000000LL, 0x000000000000000LL), newCollection(0, 4) ); @@ -378,9 +392,9 @@ static int64_t randomLong(RandomPtr random) default: val = (int64_t)random->nextInt(); } - + val += random->nextInt(5) - 2; - + if (random->nextInt() % 2 == 1) { if (random->nextInt() % 2 == 1) @@ -392,7 +406,7 @@ static int64_t randomLong(RandomPtr random) if (random->nextInt() % 2 == 1) val = MiscUtils::unsignedShift(val, (int64_t)1); } - + return val; } @@ -405,14 +419,14 @@ static void executeOneRandomSplit(RandomPtr random) checkLongRangeSplit(lower, lower + len, random->nextInt(64) + 1, true, Collection::newInstance(), Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(testRandomSplit) +TEST_F(NumericUtilsTest, testRandomSplit) { RandomPtr random = newLucene(123); - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 20; ++i) executeOneRandomSplit(random); } -BOOST_AUTO_TEST_CASE(testSplitLongRange) +TEST_F(NumericUtilsTest, testSplitLongRange) { Collection neededBounds = Collection::newInstance(14); neededBounds[0] = 0x7fffffffffffec78LL; @@ -429,7 +443,7 @@ BOOST_AUTO_TEST_CASE(testSplitLongRange) neededBounds[11] = 0x80000000000024LL; neededBounds[12] = 0x7ffffffffffffLL; neededBounds[13] = 0x8000000000001LL; - + // a hard-coded "standard" range checkLongRangeSplit(-5000, 9500, 4, true, neededBounds, newCollection(0, 0, 4, 4, 8, 8, 12)); @@ -438,50 +452,50 @@ BOOST_AUTO_TEST_CASE(testSplitLongRange) newCollection(0x7fffffffffffec78LL, 0x800000000000251cLL), newCollection(0) ); - + // this tests optimized range splitting, if one of the inner bounds // is also the bound of the next lower precision, it should be used completely - checkLongRangeSplit(0, 1024 + 63, 4, true, + checkLongRangeSplit(0, 1024 + 63, 4, true, newCollection(0x800000000000040LL, 0x800000000000043LL, 0x80000000000000LL, 0x80000000000003LL), newCollection(4, 8) ); - - // the full long range should only consist of a lowest precision range; + + // the full long range should only consist of a lowest precision range; // no bitset testing here, as too much memory needed - checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 8, false, + checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 8, false, newCollection(0x00LL, 0xffLL), newCollection(56) ); - + // the same with precisionStep=4 - checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 4, false, + checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 4, false, newCollection(0x00LL, 0xfLL), newCollection(60) ); - + // the same with precisionStep=2 checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 2, false, newCollection(0x00LL, 0x3LL), newCollection(62) ); - + // the same with precisionStep=1 - checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 1, false, + checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 1, false, newCollection(0x00LL, 0x1LL), newCollection(63) ); - + // a inverse range should produce no sub-ranges checkLongRangeSplit(9500, -5000, 4, false, Collection::newInstance(), Collection::newInstance()); - + // a 0-length range should reproduce the range itself - checkLongRangeSplit(9500, 9500, 4, false, + checkLongRangeSplit(9500, 9500, 4, false, newCollection(0x800000000000251cLL, 0x800000000000251cLL), newCollection(0) ); } -BOOST_AUTO_TEST_CASE(testSplitIntRange) +TEST_F(NumericUtilsTest, testSplitIntRange) { Collection neededBounds = Collection::newInstance(14); neededBounds[0] = 0x7fffec78; @@ -498,56 +512,54 @@ BOOST_AUTO_TEST_CASE(testSplitIntRange) neededBounds[11] = 0x800024; neededBounds[12] = 0x7ffff; neededBounds[13] = 0x80001; - + // a hard-coded "standard" range checkIntRangeSplit(-5000, 9500, 4, true, neededBounds, newCollection(0, 0, 4, 4, 8, 8, 12)); // the same with no range splitting - checkIntRangeSplit(-5000, 9500, 32, true, + checkIntRangeSplit(-5000, 9500, 32, true, newCollection(0x7fffec78, 0x8000251c), newCollection(0) ); - + // this tests optimized range splitting, if one of the inner bounds // is also the bound of the next lower precision, it should be used completely - checkIntRangeSplit(0, 1024 + 63, 4, true, + checkIntRangeSplit(0, 1024 + 63, 4, true, newCollection(0x8000040, 0x8000043, 0x800000, 0x800003), newCollection(4, 8) ); - - // the full int range should only consist of a lowest precision range; + + // the full int range should only consist of a lowest precision range; // no bitset testing here, as too much memory needed - checkIntRangeSplit(INT_MIN, INT_MAX, 8, false, + checkIntRangeSplit(INT_MIN, INT_MAX, 8, false, newCollection(0x00, 0xff), newCollection(24) ); - + // the same with precisionStep=4 - checkIntRangeSplit(INT_MIN, INT_MAX, 4, false, + checkIntRangeSplit(INT_MIN, INT_MAX, 4, false, newCollection(0x00, 0xf), newCollection(28) ); - + // the same with precisionStep=2 checkIntRangeSplit(INT_MIN, INT_MAX, 2, false, newCollection(0x00, 0x3), newCollection(30) ); - + // the same with precisionStep=1 - checkIntRangeSplit(INT_MIN, INT_MAX, 1, false, + checkIntRangeSplit(INT_MIN, INT_MAX, 1, false, newCollection(0x00, 0x1), newCollection(31) ); - + // a inverse range should produce no sub-ranges checkIntRangeSplit(9500, -5000, 4, false, Collection::newInstance(), Collection::newInstance()); - + // a 0-length range should reproduce the range itself - checkIntRangeSplit(9500, 9500, 4, false, + checkIntRangeSplit(9500, 9500, 4, false, newCollection(0x8000251c, 0x8000251c), newCollection(0) ); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/OpenBitSetTest.cpp b/src/test/util/OpenBitSetTest.cpp index e0bd55d4..021a34fa 100644 --- a/src/test/util/OpenBitSetTest.cpp +++ b/src/test/util/OpenBitSetTest.cpp @@ -15,7 +15,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(OpenBitSetTest, LuceneTestFixture) +typedef LuceneTestFixture OpenBitSetTest; static RandomPtr randBitSet = newLucene(123); @@ -23,7 +23,7 @@ static void doGet(BitSetPtr a, OpenBitSetPtr b) { int32_t max = a->size(); for (int32_t i = 0; i < max; ++i) - BOOST_CHECK_EQUAL(a->get(i), b->get(i)); + EXPECT_EQ(a->get(i), b->get(i)); } static void doNextSetBit(BitSetPtr a, OpenBitSetPtr b) @@ -34,7 +34,7 @@ static void doNextSetBit(BitSetPtr a, OpenBitSetPtr b) { aa = a->nextSetBit(aa + 1); bb = b->nextSetBit(bb + 1); - BOOST_CHECK_EQUAL(aa, bb); + EXPECT_EQ(aa, bb); } while (aa >= 0); } @@ -48,7 +48,7 @@ static void doIterate1(BitSetPtr a, OpenBitSetPtr b) { aa = a->nextSetBit(aa + 1); bb = (randBitSet->nextInt() % 2 == 0) ? iterator->nextDoc() : iterator->advance(bb + 1); - BOOST_CHECK_EQUAL(aa == -1 ? DocIdSetIterator::NO_MORE_DOCS : aa, bb); + EXPECT_EQ(aa == -1 ? DocIdSetIterator::NO_MORE_DOCS : aa, bb); } while (aa >= 0); } @@ -62,7 +62,7 @@ static void doIterate2(BitSetPtr a, OpenBitSetPtr b) { aa = a->nextSetBit(aa + 1); bb = (randBitSet->nextInt() % 2 == 0) ? iterator->nextDoc() : iterator->advance(bb + 1); - BOOST_CHECK_EQUAL(aa == -1 ? DocIdSetIterator::NO_MORE_DOCS : aa, bb); + EXPECT_EQ(aa == -1 ? DocIdSetIterator::NO_MORE_DOCS : aa, bb); } while (aa >= 0); } @@ -79,13 +79,13 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) { BitSetPtr a0; OpenBitSetPtr b0; - + for (int32_t i = 0; i < iter; ++i) { int32_t sz = randBitSet->nextInt(maxSize); BitSetPtr a = newLucene(sz); OpenBitSetPtr b = newLucene(sz); - + // test the various ways of setting bits if (sz > 0) { @@ -104,21 +104,21 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) bool val = b->flipAndGet(idx); bool val2 = b->flipAndGet(idx); - BOOST_CHECK_NE(val, val2); + EXPECT_NE(val, val2); val = b->getAndSet(idx); - BOOST_CHECK_EQUAL(val2, val); - BOOST_CHECK(b->get(idx)); - + EXPECT_EQ(val2, val); + EXPECT_TRUE(b->get(idx)); + if (!val) b->fastClear(idx); - BOOST_CHECK_EQUAL(b->get(idx), val); + EXPECT_EQ(b->get(idx), val); } } // test that the various ways of accessing the bits are equivalent doGet(a, b); - + // test ranges, including possible extension int32_t fromIndex = randBitSet->nextInt(sz + 80); int32_t toIndex = fromIndex + randBitSet->nextInt((sz >> 1) + 1); @@ -126,7 +126,7 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) aa->flip(fromIndex, toIndex); OpenBitSetPtr bb = boost::dynamic_pointer_cast(b->clone()); bb->flip(fromIndex, toIndex); - + doIterate(aa, bb, mode); // a problem here is from flip or doIterate fromIndex = randBitSet->nextInt(sz + 80); @@ -146,11 +146,11 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) bb->set(fromIndex, toIndex); doNextSetBit(aa, bb); // a problem here is from set() or nextSetBit - + if (a0) { - BOOST_CHECK_EQUAL(a->equals(a0), b->equals(b0)); - BOOST_CHECK_EQUAL(a->cardinality(), b->cardinality()); + EXPECT_EQ(a->equals(a0), b->equals(b0)); + EXPECT_EQ(a->cardinality(), b->cardinality()); BitSetPtr a_and = boost::dynamic_pointer_cast(a->clone()); a_and->_and(a0); @@ -162,7 +162,7 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) a_andn->andNot(a0); OpenBitSetPtr b_and = boost::dynamic_pointer_cast(b->clone()); - BOOST_CHECK(b->equals(b_and)); + EXPECT_TRUE(b->equals(b_and)); b_and->_and(b0); OpenBitSetPtr b_or = boost::dynamic_pointer_cast(b->clone()); b_or->_or(b0); @@ -175,25 +175,25 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) doIterate(a_or, b_or, mode); doIterate(a_xor, b_xor, mode); doIterate(a_andn, b_andn, mode); - - BOOST_CHECK_EQUAL(a_and->cardinality(), b_and->cardinality()); - BOOST_CHECK_EQUAL(a_or->cardinality(), b_or->cardinality()); - BOOST_CHECK_EQUAL(a_xor->cardinality(), b_xor->cardinality()); - BOOST_CHECK_EQUAL(a_andn->cardinality(), b_andn->cardinality()); - + + EXPECT_EQ(a_and->cardinality(), b_and->cardinality()); + EXPECT_EQ(a_or->cardinality(), b_or->cardinality()); + EXPECT_EQ(a_xor->cardinality(), b_xor->cardinality()); + EXPECT_EQ(a_andn->cardinality(), b_andn->cardinality()); + // test non-mutating popcounts - BOOST_CHECK_EQUAL(b_and->cardinality(), OpenBitSet::intersectionCount(b, b0)); - BOOST_CHECK_EQUAL(b_or->cardinality(), OpenBitSet::unionCount(b, b0)); - BOOST_CHECK_EQUAL(b_xor->cardinality(), OpenBitSet::xorCount(b, b0)); - BOOST_CHECK_EQUAL(b_andn->cardinality(), OpenBitSet::andNotCount(b, b0)); + EXPECT_EQ(b_and->cardinality(), OpenBitSet::intersectionCount(b, b0)); + EXPECT_EQ(b_or->cardinality(), OpenBitSet::unionCount(b, b0)); + EXPECT_EQ(b_xor->cardinality(), OpenBitSet::xorCount(b, b0)); + EXPECT_EQ(b_andn->cardinality(), OpenBitSet::andNotCount(b, b0)); } - + a0=a; b0=b; } } -BOOST_AUTO_TEST_CASE(testSmall) +TEST_F(OpenBitSetTest, testSmall) { randBitSet->setSeed(17); doRandomSets(1200, 1000, 1); @@ -201,7 +201,7 @@ BOOST_AUTO_TEST_CASE(testSmall) } /* -BOOST_AUTO_TEST_CASE(testBig) +TEST_F(OpenBitSetTest, testBig) { randBitSet->setSeed(17); doRandomSets(2000, 200000, 1); @@ -209,57 +209,55 @@ BOOST_AUTO_TEST_CASE(testBig) } */ -BOOST_AUTO_TEST_CASE(testEquals) +TEST_F(OpenBitSetTest, testEquals) { randBitSet->setSeed(17); OpenBitSetPtr b1 = newLucene(1111); OpenBitSetPtr b2 = newLucene(2222); - BOOST_CHECK(b1->equals(b2)); - BOOST_CHECK(b2->equals(b1)); + EXPECT_TRUE(b1->equals(b2)); + EXPECT_TRUE(b2->equals(b1)); b1->set(10); - BOOST_CHECK(!b1->equals(b2)); - BOOST_CHECK(!b2->equals(b1)); + EXPECT_TRUE(!b1->equals(b2)); + EXPECT_TRUE(!b2->equals(b1)); b2->set(10); - BOOST_CHECK(b1->equals(b2)); - BOOST_CHECK(b2->equals(b1)); + EXPECT_TRUE(b1->equals(b2)); + EXPECT_TRUE(b2->equals(b1)); b2->set(2221); - BOOST_CHECK(!b1->equals(b2)); - BOOST_CHECK(!b2->equals(b1)); + EXPECT_TRUE(!b1->equals(b2)); + EXPECT_TRUE(!b2->equals(b1)); b1->set(2221); - BOOST_CHECK(b1->equals(b2)); - BOOST_CHECK(b2->equals(b1)); + EXPECT_TRUE(b1->equals(b2)); + EXPECT_TRUE(b2->equals(b1)); } -BOOST_AUTO_TEST_CASE(testBitUtils) +TEST_F(OpenBitSetTest, testBitUtils) { randBitSet->setSeed(17); int64_t num = 100000; - BOOST_CHECK_EQUAL(5, BitUtil::ntz(num)); - BOOST_CHECK_EQUAL(5, BitUtil::ntz2(num)); - BOOST_CHECK_EQUAL(5, BitUtil::ntz3(num)); + EXPECT_EQ(5, BitUtil::ntz(num)); + EXPECT_EQ(5, BitUtil::ntz2(num)); + EXPECT_EQ(5, BitUtil::ntz3(num)); num = 10; - BOOST_CHECK_EQUAL(1, BitUtil::ntz(num)); - BOOST_CHECK_EQUAL(1, BitUtil::ntz2(num)); - BOOST_CHECK_EQUAL(1, BitUtil::ntz3(num)); - + EXPECT_EQ(1, BitUtil::ntz(num)); + EXPECT_EQ(1, BitUtil::ntz2(num)); + EXPECT_EQ(1, BitUtil::ntz3(num)); + for (int32_t i = 0; i < 64; ++i) { num = (int64_t)1 << i; - BOOST_CHECK_EQUAL(i, BitUtil::ntz(num)); - BOOST_CHECK_EQUAL(i, BitUtil::ntz2(num)); - BOOST_CHECK_EQUAL(i, BitUtil::ntz3(num)); + EXPECT_EQ(i, BitUtil::ntz(num)); + EXPECT_EQ(i, BitUtil::ntz2(num)); + EXPECT_EQ(i, BitUtil::ntz3(num)); } } -BOOST_AUTO_TEST_CASE(testHashCodeEquals) +TEST_F(OpenBitSetTest, testHashCodeEquals) { OpenBitSetPtr bs1 = newLucene(200); OpenBitSetPtr bs2 = newLucene(64); bs1->set(3); - bs2->set(3); - BOOST_CHECK(bs1->equals(bs2)); - BOOST_CHECK_EQUAL(bs1->hashCode(), bs2->hashCode()); + bs2->set(3); + EXPECT_TRUE(bs1->equals(bs2)); + EXPECT_EQ(bs1->hashCode(), bs2->hashCode()); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/PriorityQueueTest.cpp b/src/test/util/PriorityQueueTest.cpp index 3121bd6e..3c637224 100644 --- a/src/test/util/PriorityQueueTest.cpp +++ b/src/test/util/PriorityQueueTest.cpp @@ -11,7 +11,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(PriorityQueueTest, LuceneTestFixture) +typedef LuceneTestFixture PriorityQueueTest; DECLARE_SHARED_PTR(IntegerQueue) @@ -21,7 +21,7 @@ class IntegerQueue : public PriorityQueue IntegerQueue(int32_t maxSize) : PriorityQueue(maxSize) { } - + virtual ~IntegerQueue() { } @@ -36,7 +36,7 @@ class IntegerPtrQueue : public PriorityQueue IntegerPtrQueue(int32_t maxSize) : PriorityQueue(maxSize) { } - + virtual ~IntegerPtrQueue() { } @@ -48,34 +48,34 @@ class IntegerPtrQueue : public PriorityQueue } }; -BOOST_AUTO_TEST_CASE(testPriorityQueue) +TEST_F(PriorityQueueTest, testPriorityQueue) { IntegerQueuePtr testQueue = newLucene(10000); int64_t sum = 0; RandomPtr random = newLucene(); - + for (int32_t i = 0; i < 10000; ++i) { int32_t next = random->nextInt(); sum += next; testQueue->add(next); } - + int32_t last = INT_MIN; int64_t sum2 = 0; - + for (int32_t i = 0; i < 10000; ++i) { int32_t next = testQueue->pop(); - BOOST_CHECK(next >= last); + EXPECT_TRUE(next >= last); last = next; sum2 += last; } - BOOST_CHECK_EQUAL(sum, sum2); + EXPECT_EQ(sum, sum2); } -BOOST_AUTO_TEST_CASE(testPriorityQueueOverflow) +TEST_F(PriorityQueueTest, testPriorityQueueOverflow) { IntegerQueuePtr testQueue = newLucene(3); testQueue->addOverflow(2); @@ -84,22 +84,22 @@ BOOST_AUTO_TEST_CASE(testPriorityQueueOverflow) testQueue->addOverflow(5); testQueue->addOverflow(7); testQueue->addOverflow(1); - BOOST_CHECK_EQUAL(testQueue->size(), 3); - BOOST_CHECK_EQUAL(3, testQueue->top()); + EXPECT_EQ(testQueue->size(), 3); + EXPECT_EQ(3, testQueue->top()); } -BOOST_AUTO_TEST_CASE(testPriorityQueueClear) +TEST_F(PriorityQueueTest, testPriorityQueueClear) { IntegerQueuePtr testQueue = newLucene(3); testQueue->add(2); testQueue->add(3); testQueue->add(1); - BOOST_CHECK_EQUAL(testQueue->size(), 3); + EXPECT_EQ(testQueue->size(), 3); testQueue->clear(); - BOOST_CHECK(testQueue->empty()); + EXPECT_TRUE(testQueue->empty()); } -BOOST_AUTO_TEST_CASE(testPriorityQueueUpdate) +TEST_F(PriorityQueueTest, testPriorityQueueUpdate) { IntegerPtrQueuePtr testQueue = newLucene(1024); testQueue->add(newInstance(2)); @@ -107,19 +107,17 @@ BOOST_AUTO_TEST_CASE(testPriorityQueueUpdate) testQueue->add(newInstance(1)); testQueue->add(newInstance(4)); testQueue->add(newInstance(5)); - BOOST_CHECK_EQUAL(testQueue->size(), 5); - + EXPECT_EQ(testQueue->size(), 5); + IntPtr top = testQueue->top(); - BOOST_CHECK_EQUAL(*top, 1); - + EXPECT_EQ(*top, 1); + *top = 6; testQueue->updateTop(); - - BOOST_CHECK_EQUAL(*testQueue->pop(), 2); - BOOST_CHECK_EQUAL(*testQueue->pop(), 3); - BOOST_CHECK_EQUAL(*testQueue->pop(), 4); - BOOST_CHECK_EQUAL(*testQueue->pop(), 5); - BOOST_CHECK_EQUAL(*testQueue->pop(), 6); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(*testQueue->pop(), 2); + EXPECT_EQ(*testQueue->pop(), 3); + EXPECT_EQ(*testQueue->pop(), 4); + EXPECT_EQ(*testQueue->pop(), 5); + EXPECT_EQ(*testQueue->pop(), 6); +} diff --git a/src/test/util/SimpleLRUCacheTest.cpp b/src/test/util/SimpleLRUCacheTest.cpp index 8f1b2952..ad468d63 100644 --- a/src/test/util/SimpleLRUCacheTest.cpp +++ b/src/test/util/SimpleLRUCacheTest.cpp @@ -14,151 +14,149 @@ using namespace Lucene; typedef SimpleLRUCache TestLRUSimpleCache; typedef SimpleLRUCache< TermPtr, int32_t, luceneHash, luceneEquals > TestLRUTermCache; -BOOST_FIXTURE_TEST_SUITE(SimpleLRUCacheTest, LuceneTestFixture) +typedef LuceneTestFixture SimpleLRUCacheTest; -BOOST_AUTO_TEST_CASE(testCachePut) +TEST_F(SimpleLRUCacheTest, testCachePut) { TestLRUSimpleCache testCache(5); - + testCache.put(1, L"test 1"); testCache.put(2, L"test 2"); testCache.put(3, L"test 3"); testCache.put(4, L"test 4"); testCache.put(5, L"test 5"); testCache.put(6, L"test 6"); // this should pop off "1" because size = 5 - - BOOST_CHECK_EQUAL(testCache.size(), 5); - + + EXPECT_EQ(testCache.size(), 5); + int32_t expectedKey = 6; - + // lru = 6, 5, 4, 3, 2 for (TestLRUSimpleCache::const_iterator cache = testCache.begin(); cache != testCache.end(); ++cache) - BOOST_CHECK_EQUAL(cache->first, expectedKey--); + EXPECT_EQ(cache->first, expectedKey--); } -BOOST_AUTO_TEST_CASE(testCacheGet) +TEST_F(SimpleLRUCacheTest, testCacheGet) { TestLRUSimpleCache testCache(5); - + testCache.put(1, L"test 1"); testCache.put(2, L"test 2"); testCache.put(3, L"test 3"); testCache.put(4, L"test 4"); testCache.put(5, L"test 5"); - - BOOST_CHECK_EQUAL(testCache.size(), 5); - BOOST_CHECK_EQUAL(testCache.get(2), L"test 2"); - BOOST_CHECK_EQUAL(testCache.get(3), L"test 3"); + + EXPECT_EQ(testCache.size(), 5); + EXPECT_EQ(testCache.get(2), L"test 2"); + EXPECT_EQ(testCache.get(3), L"test 3"); } -BOOST_AUTO_TEST_CASE(testCacheExists) +TEST_F(SimpleLRUCacheTest, testCacheExists) { TestLRUSimpleCache testCache(5); - + testCache.put(1, L"test 1"); testCache.put(2, L"test 2"); testCache.put(3, L"test 3"); testCache.put(4, L"test 4"); testCache.put(5, L"test 5"); - - BOOST_CHECK(testCache.contains(1)); - BOOST_CHECK(!testCache.contains(7)); + + EXPECT_TRUE(testCache.contains(1)); + EXPECT_TRUE(!testCache.contains(7)); } -BOOST_AUTO_TEST_CASE(testCachePutGet) +TEST_F(SimpleLRUCacheTest, testCachePutGet) { TestLRUSimpleCache testCache(5); - + testCache.put(1, L"test 1"); testCache.put(2, L"test 2"); testCache.put(3, L"test 3"); testCache.put(4, L"test 4"); testCache.put(5, L"test 5"); - - BOOST_CHECK_EQUAL(testCache.size(), 5); - - BOOST_CHECK_EQUAL(testCache.get(2), L"test 2"); - BOOST_CHECK_EQUAL(testCache.get(3), L"test 3"); - + + EXPECT_EQ(testCache.size(), 5); + + EXPECT_EQ(testCache.get(2), L"test 2"); + EXPECT_EQ(testCache.get(3), L"test 3"); + testCache.put(6, L"test 6"); testCache.put(7, L"test 7"); testCache.put(8, L"test 8"); - + Collection expectedLRU = Collection::newInstance(); for (TestLRUSimpleCache::const_iterator cache = testCache.begin(); cache != testCache.end(); ++cache) expectedLRU.add(cache->first); - - BOOST_CHECK_EQUAL(expectedLRU.size(), 5); - + + EXPECT_EQ(expectedLRU.size(), 5); + // lru = 8, 7, 6, 3, 2 - BOOST_CHECK_EQUAL(expectedLRU[0], 8); - BOOST_CHECK_EQUAL(expectedLRU[1], 7); - BOOST_CHECK_EQUAL(expectedLRU[2], 6); - BOOST_CHECK_EQUAL(expectedLRU[3], 3); - BOOST_CHECK_EQUAL(expectedLRU[4], 2); + EXPECT_EQ(expectedLRU[0], 8); + EXPECT_EQ(expectedLRU[1], 7); + EXPECT_EQ(expectedLRU[2], 6); + EXPECT_EQ(expectedLRU[3], 3); + EXPECT_EQ(expectedLRU[4], 2); } -BOOST_AUTO_TEST_CASE(testRandomAccess) +TEST_F(SimpleLRUCacheTest, testRandomAccess) { const int32_t n = 100; TestLRUSimpleCache cache(n); String value = L"test"; - + for (int32_t i = 0; i < n; ++i) cache.put(i, value); // access every 2nd item in cache for (int32_t i = 0; i < n; i += 2) - BOOST_CHECK_NE(cache.get(i), L""); + EXPECT_NE(cache.get(i), L""); // add n/2 elements to cache, the ones that weren't touched in the previous loop should now be thrown away for (int32_t i = n; i < n + (n / 2); ++i) cache.put(i, value); - + // access every 4th item in cache for (int32_t i = 0; i < n; i += 4) - BOOST_CHECK_NE(cache.get(i), L""); - + EXPECT_NE(cache.get(i), L""); + // add 3/4n elements to cache, the ones that weren't touched in the previous loops should now be thrown away for (int32_t i = n; i < n + (n * 3 / 4); ++i) cache.put(i, value); - + // access every 4th item in cache for (int32_t i = 0; i < n; i += 4) - BOOST_CHECK_NE(cache.get(i), L""); + EXPECT_NE(cache.get(i), L""); } -BOOST_AUTO_TEST_CASE(testTermCache) +TEST_F(SimpleLRUCacheTest, testTermCache) { TestLRUTermCache testCache(5); - + testCache.put(newLucene(L"field1", L"text1"), 1); testCache.put(newLucene(L"field2", L"text2"), 2); testCache.put(newLucene(L"field3", L"text3"), 3); testCache.put(newLucene(L"field4", L"text4"), 4); testCache.put(newLucene(L"field5", L"text5"), 5); - - BOOST_CHECK_EQUAL(testCache.size(), 5); - - BOOST_CHECK_EQUAL(testCache.get(newLucene(L"field2", L"text2")), 2); - BOOST_CHECK_EQUAL(testCache.get(newLucene(L"field3", L"text3")), 3); - + + EXPECT_EQ(testCache.size(), 5); + + EXPECT_EQ(testCache.get(newLucene(L"field2", L"text2")), 2); + EXPECT_EQ(testCache.get(newLucene(L"field3", L"text3")), 3); + testCache.put(newLucene(L"field6", L"text6"), 6); testCache.put(newLucene(L"field7", L"text7"), 7); testCache.put(newLucene(L"field8", L"text8"), 8); - + Collection expectedLRU = Collection::newInstance(); for (TestLRUTermCache::const_iterator cache = testCache.begin(); cache != testCache.end(); ++cache) expectedLRU.add(cache->first); - - BOOST_CHECK_EQUAL(expectedLRU.size(), 5); - + + EXPECT_EQ(expectedLRU.size(), 5); + // lru = field8, field7, field6, field3, field2 - BOOST_CHECK(expectedLRU[0]->equals(newLucene(L"field8", L"text8"))); - BOOST_CHECK(expectedLRU[1]->equals(newLucene(L"field7", L"text7"))); - BOOST_CHECK(expectedLRU[2]->equals(newLucene(L"field6", L"text6"))); - BOOST_CHECK(expectedLRU[3]->equals(newLucene(L"field3", L"text3"))); - BOOST_CHECK(expectedLRU[4]->equals(newLucene(L"field2", L"text2"))); + EXPECT_TRUE(expectedLRU[0]->equals(newLucene(L"field8", L"text8"))); + EXPECT_TRUE(expectedLRU[1]->equals(newLucene(L"field7", L"text7"))); + EXPECT_TRUE(expectedLRU[2]->equals(newLucene(L"field6", L"text6"))); + EXPECT_TRUE(expectedLRU[3]->equals(newLucene(L"field3", L"text3"))); + EXPECT_TRUE(expectedLRU[4]->equals(newLucene(L"field2", L"text2"))); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/SortedVIntListTest.cpp b/src/test/util/SortedVIntListTest.cpp index a2997019..e3362de3 100644 --- a/src/test/util/SortedVIntListTest.cpp +++ b/src/test/util/SortedVIntListTest.cpp @@ -12,7 +12,7 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(SortedVIntListTest, LuceneTestFixture) +typedef LuceneTestFixture SortedVIntListTest; static const int32_t VB1 = 0x7F; static const int32_t BIT_SHIFT = 7; @@ -22,7 +22,7 @@ static const int32_t VB4 = (VB3 << BIT_SHIFT) | VB1; static int32_t vIntByteSize(int32_t i) { - BOOST_CHECK(i >= 0); + EXPECT_TRUE(i >= 0); if (i <= VB1) return 1; if (i <= VB2) @@ -56,16 +56,16 @@ static void tstIterator(SortedVIntListPtr vintList, Collection ints) DocIdSetIteratorPtr m = vintList->iterator(); for (int32_t i = 0; i < ints.size(); ++i) { - BOOST_CHECK(m->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); - BOOST_CHECK_EQUAL(ints[i], m->docID()); + EXPECT_TRUE(m->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(ints[i], m->docID()); } - BOOST_CHECK_EQUAL(m->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(m->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); } static void tstVIntList(SortedVIntListPtr vintList, Collection ints, int32_t expectedByteSize) { - BOOST_CHECK_EQUAL(ints.size(), vintList->size()); - BOOST_CHECK_EQUAL(expectedByteSize, vintList->getByteSize()); + EXPECT_EQ(ints.size(), vintList->size()); + EXPECT_EQ(expectedByteSize, vintList->getByteSize()); tstIterator(vintList, ints); } @@ -85,7 +85,7 @@ static void tstViaBitSet(Collection ints, int32_t expectedByteSize) tstVIntList(svil, ints, expectedByteSize); tstVIntList(newLucene(svil->iterator()), ints, expectedByteSize); } - + static void tstInts(Collection ints) { int32_t expectedByteSize = vIntListByteSize(ints); @@ -114,97 +114,102 @@ static Collection reverseDiffs(Collection ints) static void tstIllegalArgExc(Collection ints) { - BOOST_CHECK_EXCEPTION(newLucene(ints), IllegalArgumentException, check_exception(LuceneException::IllegalArgument)); + try + { + newLucene(ints); + } + catch (IllegalArgumentException& e) + { + EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); + } } -BOOST_AUTO_TEST_CASE(test01) +TEST_F(SortedVIntListTest, test01) { tstInts(Collection::newInstance()); } -BOOST_AUTO_TEST_CASE(test02) +TEST_F(SortedVIntListTest, test02) { tstInts(newCollection(0)); } -BOOST_AUTO_TEST_CASE(test04a) +TEST_F(SortedVIntListTest, test04a) { tstInts(newCollection(0, VB2 - 1)); } -BOOST_AUTO_TEST_CASE(test04b) +TEST_F(SortedVIntListTest, test04b) { tstInts(newCollection(0, VB2)); } -BOOST_AUTO_TEST_CASE(test04c) +TEST_F(SortedVIntListTest, test04c) { tstInts(newCollection(0, VB2 + 1)); } -BOOST_AUTO_TEST_CASE(test05) +TEST_F(SortedVIntListTest, test05) { tstInts(fibArray(0, 1, 7)); // includes duplicate value 1 } -BOOST_AUTO_TEST_CASE(test05b) +TEST_F(SortedVIntListTest, test05b) { tstInts(reverseDiffs(fibArray(0, 1, 7))); // includes duplicate value 1 } -BOOST_AUTO_TEST_CASE(test06) +TEST_F(SortedVIntListTest, test06) { tstInts(fibArray(1, 2, 45)); // no duplicates, size 46 exceeds max int. } -BOOST_AUTO_TEST_CASE(test06b) +TEST_F(SortedVIntListTest, test06b) { tstInts(reverseDiffs(fibArray(1, 2, 45))); // includes duplicate value 1 } -BOOST_AUTO_TEST_CASE(test07a) +TEST_F(SortedVIntListTest, test07a) { tstInts(newCollection(0, VB3)); } -BOOST_AUTO_TEST_CASE(test07b) +TEST_F(SortedVIntListTest, test07b) { tstInts(newCollection(1, VB3 + 2)); } -BOOST_AUTO_TEST_CASE(test07c) +TEST_F(SortedVIntListTest, test07c) { tstInts(newCollection(2, VB3 + 4)); } -BOOST_AUTO_TEST_CASE(test08a) +TEST_F(SortedVIntListTest, test08a) { tstInts(newCollection(0, VB4 + 1)); } -BOOST_AUTO_TEST_CASE(test08b) +TEST_F(SortedVIntListTest, test08b) { tstInts(newCollection(1, VB4 + 1)); } -BOOST_AUTO_TEST_CASE(test08c) +TEST_F(SortedVIntListTest, test08c) { tstInts(newCollection(2, VB4 + 1)); } -BOOST_AUTO_TEST_CASE(test10) +TEST_F(SortedVIntListTest, test10) { tstIllegalArgExc(newCollection(-1)); } -BOOST_AUTO_TEST_CASE(test11) +TEST_F(SortedVIntListTest, test11) { tstIllegalArgExc(newCollection(1, 0)); } -BOOST_AUTO_TEST_CASE(test12) +TEST_F(SortedVIntListTest, test12) { tstIllegalArgExc(newCollection(0, 1, 1, 2, 3, 5, 8, 0)); } - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/StringReaderTest.cpp b/src/test/util/StringReaderTest.cpp index 0e3e02fc..eb27bfec 100644 --- a/src/test/util/StringReaderTest.cpp +++ b/src/test/util/StringReaderTest.cpp @@ -10,65 +10,63 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(StringReaderTest, LuceneTestFixture) +typedef LuceneTestFixture StringReaderTest; -BOOST_AUTO_TEST_CASE(testStringReaderChar) +TEST_F(StringReaderTest, testStringReaderChar) { StringReader reader(L"Test string"); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L'T'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L'e'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L's'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L' '); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L's'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L't'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L'r'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L'i'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L'n'); - BOOST_CHECK_EQUAL((wchar_t)reader.read(), L'g'); - BOOST_CHECK_EQUAL(reader.read(), StringReader::READER_EOF); + EXPECT_EQ((wchar_t)reader.read(), L'T'); + EXPECT_EQ((wchar_t)reader.read(), L'e'); + EXPECT_EQ((wchar_t)reader.read(), L's'); + EXPECT_EQ((wchar_t)reader.read(), L't'); + EXPECT_EQ((wchar_t)reader.read(), L' '); + EXPECT_EQ((wchar_t)reader.read(), L's'); + EXPECT_EQ((wchar_t)reader.read(), L't'); + EXPECT_EQ((wchar_t)reader.read(), L'r'); + EXPECT_EQ((wchar_t)reader.read(), L'i'); + EXPECT_EQ((wchar_t)reader.read(), L'n'); + EXPECT_EQ((wchar_t)reader.read(), L'g'); + EXPECT_EQ(reader.read(), StringReader::READER_EOF); } -BOOST_AUTO_TEST_CASE(testStringReaderBuffer) +TEST_F(StringReaderTest, testStringReaderBuffer) { StringReader reader(L"Longer test string"); - + wchar_t buffer[50]; - - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 6), 6); - BOOST_CHECK_EQUAL(String(buffer, 6), L"Longer"); - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 1), 1); - BOOST_CHECK_EQUAL(String(buffer, 1), L" "); - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 4), 4); - BOOST_CHECK_EQUAL(String(buffer, 4), L"test"); - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 1), 1); - BOOST_CHECK_EQUAL(String(buffer, 1), L" "); - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 6), 6); - BOOST_CHECK_EQUAL(String(buffer, 6), L"string"); - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 1), StringReader::READER_EOF); + + EXPECT_EQ(reader.read(buffer, 0, 6), 6); + EXPECT_EQ(String(buffer, 6), L"Longer"); + EXPECT_EQ(reader.read(buffer, 0, 1), 1); + EXPECT_EQ(String(buffer, 1), L" "); + EXPECT_EQ(reader.read(buffer, 0, 4), 4); + EXPECT_EQ(String(buffer, 4), L"test"); + EXPECT_EQ(reader.read(buffer, 0, 1), 1); + EXPECT_EQ(String(buffer, 1), L" "); + EXPECT_EQ(reader.read(buffer, 0, 6), 6); + EXPECT_EQ(String(buffer, 6), L"string"); + EXPECT_EQ(reader.read(buffer, 0, 1), StringReader::READER_EOF); } -BOOST_AUTO_TEST_CASE(testStringReaderReset) +TEST_F(StringReaderTest, testStringReaderReset) { StringReader reader(L"Longer test string"); - + wchar_t buffer[50]; - - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 6), 6); - BOOST_CHECK_EQUAL(String(buffer, 6), L"Longer"); + + EXPECT_EQ(reader.read(buffer, 0, 6), 6); + EXPECT_EQ(String(buffer, 6), L"Longer"); reader.reset(); - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 6), 6); - BOOST_CHECK_EQUAL(String(buffer, 6), L"Longer"); + EXPECT_EQ(reader.read(buffer, 0, 6), 6); + EXPECT_EQ(String(buffer, 6), L"Longer"); } -BOOST_AUTO_TEST_CASE(testStringReaderPastEOF) +TEST_F(StringReaderTest, testStringReaderPastEOF) { StringReader reader(L"Short string"); - + wchar_t buffer[50]; - - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 20), 12); - BOOST_CHECK_EQUAL(reader.read(buffer, 0, 1), StringReader::READER_EOF); -} -BOOST_AUTO_TEST_SUITE_END() + EXPECT_EQ(reader.read(buffer, 0, 20), 12); + EXPECT_EQ(reader.read(buffer, 0, 1), StringReader::READER_EOF); +} diff --git a/src/test/util/StringUtilsTest.cpp b/src/test/util/StringUtilsTest.cpp index 486936ad..3c7c6c8a 100644 --- a/src/test/util/StringUtilsTest.cpp +++ b/src/test/util/StringUtilsTest.cpp @@ -12,184 +12,182 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(StringUtilsTest, LuceneTestFixture) +typedef LuceneTestFixture StringUtilsTest; -BOOST_AUTO_TEST_CASE(testToUtf8) +TEST_F(StringUtilsTest, testToUtf8) { String testString(L"this is a ascii string"); - BOOST_CHECK_EQUAL(StringUtils::toUTF8(testString), "this is a ascii string"); + EXPECT_EQ(StringUtils::toUTF8(testString), "this is a ascii string"); } -BOOST_AUTO_TEST_CASE(testToUtf8CharArray) +TEST_F(StringUtilsTest, testToUtf8CharArray) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(testString.length())); std::copy(testString.begin(), testString.end(), testArray.get()); ByteArray expectedUft8(ByteArray::newInstance(30)); - BOOST_CHECK_EQUAL(StringUtils::toUTF8(testArray.get(), testArray.size(), expectedUft8), 22); - BOOST_CHECK_EQUAL(SingleString((char*)expectedUft8.get(), 22), "this is a ascii string"); + EXPECT_EQ(StringUtils::toUTF8(testArray.get(), testArray.size(), expectedUft8), 22); + EXPECT_EQ(SingleString((char*)expectedUft8.get(), 22), "this is a ascii string"); } -BOOST_AUTO_TEST_CASE(testToUtf8ArrayWithOffset) +TEST_F(StringUtilsTest, testToUtf8ArrayWithOffset) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(testString.size())); std::copy(testString.begin(), testString.end(), testArray.get()); ByteArray expectedUft8(ByteArray::newInstance(30)); int32_t offset = 10; // "ascii string" - BOOST_CHECK_EQUAL(StringUtils::toUTF8(testArray.get() + offset, testArray.size() - offset, expectedUft8), 12); - BOOST_CHECK_EQUAL(SingleString((char*)expectedUft8.get(), 12), "ascii string"); + EXPECT_EQ(StringUtils::toUTF8(testArray.get() + offset, testArray.size() - offset, expectedUft8), 12); + EXPECT_EQ(SingleString((char*)expectedUft8.get(), 12), "ascii string"); } -BOOST_AUTO_TEST_CASE(testToUtf8Result) +TEST_F(StringUtilsTest, testToUtf8Result) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(testString.size())); std::copy(testString.begin(), testString.end(), testArray.get()); UTF8ResultPtr utf8Result(newLucene()); StringUtils::toUTF8(testArray.get(), testArray.size(), utf8Result); - BOOST_CHECK_EQUAL(utf8Result->length, 22); - BOOST_CHECK_EQUAL(SingleString((char*)utf8Result->result.get(), 22), "this is a ascii string"); + EXPECT_EQ(utf8Result->length, 22); + EXPECT_EQ(SingleString((char*)utf8Result->result.get(), 22), "this is a ascii string"); } -BOOST_AUTO_TEST_CASE(testToUtf8ArrayWithTerminator) +TEST_F(StringUtilsTest, testToUtf8ArrayWithTerminator) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(50)); std::copy(testString.begin(), testString.end(), testArray.get()); testArray[testString.size()] = UTF8Base::UNICODE_TERMINATOR; // terminator ByteArray expectedUft8(ByteArray::newInstance(30)); - BOOST_CHECK_EQUAL(StringUtils::toUTF8(testArray.get(), testArray.size(), expectedUft8), 22); - BOOST_CHECK_EQUAL(SingleString((char*)expectedUft8.get(), 22), "this is a ascii string"); + EXPECT_EQ(StringUtils::toUTF8(testArray.get(), testArray.size(), expectedUft8), 22); + EXPECT_EQ(SingleString((char*)expectedUft8.get(), 22), "this is a ascii string"); } -BOOST_AUTO_TEST_CASE(testToUnicode) +TEST_F(StringUtilsTest, testToUnicode) { SingleString testString("this is a unicode string"); - BOOST_CHECK_EQUAL(StringUtils::toUnicode(testString), L"this is a unicode string"); + EXPECT_EQ(StringUtils::toUnicode(testString), L"this is a unicode string"); } -BOOST_AUTO_TEST_CASE(testToUnicodeResult) +TEST_F(StringUtilsTest, testToUnicodeResult) { SingleString testString("this is a unicode string"); ByteArray testArray(ByteArray::newInstance(testString.length())); std::copy(testString.begin(), testString.end(), testArray.get()); UnicodeResultPtr unicodeResult(newLucene()); StringUtils::toUnicode(testArray.get(), testArray.size(), unicodeResult); - BOOST_CHECK_EQUAL(unicodeResult->length, 24); - BOOST_CHECK_EQUAL(String(unicodeResult->result.get(), 24), L"this is a unicode string"); + EXPECT_EQ(unicodeResult->length, 24); + EXPECT_EQ(String(unicodeResult->result.get(), 24), L"this is a unicode string"); } -BOOST_AUTO_TEST_CASE(testToStringInteger) +TEST_F(StringUtilsTest, testToStringInteger) { - BOOST_CHECK_EQUAL(StringUtils::toString((int32_t)1234), L"1234"); + EXPECT_EQ(StringUtils::toString((int32_t)1234), L"1234"); } -BOOST_AUTO_TEST_CASE(testToStringLong) +TEST_F(StringUtilsTest, testToStringLong) { - BOOST_CHECK_EQUAL(StringUtils::toString((int64_t)1234), L"1234"); + EXPECT_EQ(StringUtils::toString((int64_t)1234), L"1234"); } -BOOST_AUTO_TEST_CASE(testToStringBase) +TEST_F(StringUtilsTest, testToStringBase) { - BOOST_CHECK_EQUAL(StringUtils::toString(1234, 4), L"103102"); - BOOST_CHECK_EQUAL(StringUtils::toString(1234, 10), L"1234"); - BOOST_CHECK_EQUAL(StringUtils::toString(1234, 16), L"4d2"); - BOOST_CHECK_EQUAL(StringUtils::toString(1234, StringUtils::CHARACTER_MAX_RADIX), L"ya"); + EXPECT_EQ(StringUtils::toString(1234, 4), L"103102"); + EXPECT_EQ(StringUtils::toString(1234, 10), L"1234"); + EXPECT_EQ(StringUtils::toString(1234, 16), L"4d2"); + EXPECT_EQ(StringUtils::toString(1234, StringUtils::CHARACTER_MAX_RADIX), L"ya"); } -BOOST_AUTO_TEST_CASE(testToLongBase) +TEST_F(StringUtilsTest, testToLongBase) { - BOOST_CHECK_EQUAL(StringUtils::toLong(L"1234", 4), 112); - BOOST_CHECK_EQUAL(StringUtils::toLong(L"1234", 10), 1234); - BOOST_CHECK_EQUAL(StringUtils::toLong(L"1234", 16), 4660); - BOOST_CHECK_EQUAL(StringUtils::toLong(L"1234", StringUtils::CHARACTER_MAX_RADIX), 49360); + EXPECT_EQ(StringUtils::toLong(L"1234", 4), 112); + EXPECT_EQ(StringUtils::toLong(L"1234", 10), 1234); + EXPECT_EQ(StringUtils::toLong(L"1234", 16), 4660); + EXPECT_EQ(StringUtils::toLong(L"1234", StringUtils::CHARACTER_MAX_RADIX), 49360); } -BOOST_AUTO_TEST_CASE(testToStringLongBase) +TEST_F(StringUtilsTest, testToStringLongBase) { - BOOST_CHECK_EQUAL(StringUtils::toString(1234, 4), L"103102"); - BOOST_CHECK_EQUAL(StringUtils::toLong(L"103102", 4), 1234); - - BOOST_CHECK_EQUAL(StringUtils::toString(1234, 10), L"1234"); - BOOST_CHECK_EQUAL(StringUtils::toLong(L"1234", 10), 1234); - - BOOST_CHECK_EQUAL(StringUtils::toString(1234, 16), L"4d2"); - BOOST_CHECK_EQUAL(StringUtils::toLong(L"4d2", 16), 1234); - - BOOST_CHECK_EQUAL(StringUtils::toString(1234, StringUtils::CHARACTER_MAX_RADIX), L"ya"); - BOOST_CHECK_EQUAL(StringUtils::toLong(L"ya", StringUtils::CHARACTER_MAX_RADIX), 1234); + EXPECT_EQ(StringUtils::toString(1234, 4), L"103102"); + EXPECT_EQ(StringUtils::toLong(L"103102", 4), 1234); + + EXPECT_EQ(StringUtils::toString(1234, 10), L"1234"); + EXPECT_EQ(StringUtils::toLong(L"1234", 10), 1234); + + EXPECT_EQ(StringUtils::toString(1234, 16), L"4d2"); + EXPECT_EQ(StringUtils::toLong(L"4d2", 16), 1234); + + EXPECT_EQ(StringUtils::toString(1234, StringUtils::CHARACTER_MAX_RADIX), L"ya"); + EXPECT_EQ(StringUtils::toLong(L"ya", StringUtils::CHARACTER_MAX_RADIX), 1234); } -BOOST_AUTO_TEST_CASE(testToHash) +TEST_F(StringUtilsTest, testToHash) { - BOOST_CHECK_EQUAL(StringUtils::hashCode(L"test"), 3556498); - BOOST_CHECK_EQUAL(StringUtils::hashCode(L"string"), -891985903); + EXPECT_EQ(StringUtils::hashCode(L"test"), 3556498); + EXPECT_EQ(StringUtils::hashCode(L"string"), -891985903); } -BOOST_AUTO_TEST_CASE(testUTF8Performance) +TEST_F(StringUtilsTest, testUTF8Performance) { uint64_t startTime = MiscUtils::currentTimeMillis(); static const int32_t maxIter = 1000000; - + String unicode = L"this is a unicode string"; - + for (int32_t i = 0; i < maxIter; ++i) StringUtils::toUTF8(unicode); - - BOOST_TEST_MESSAGE("Encode utf8 (string): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"); - + + // std::cout << "Encode utf8 (string): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; + const wchar_t* unicodeChar = unicode.c_str(); int32_t unicodeLength = (int32_t)unicode.length(); - + startTime = MiscUtils::currentTimeMillis(); - + for (int32_t i = 0; i < maxIter; ++i) StringUtils::toUTF8(unicodeChar, unicodeLength); - - BOOST_TEST_MESSAGE("Encode utf8 (pointer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"); - + + // std::cout << "Encode utf8 (pointer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; + ByteArray utf8 = ByteArray::newInstance(unicodeLength * StringUtils::MAX_ENCODING_UTF8_SIZE); - + startTime = MiscUtils::currentTimeMillis(); - + for (int32_t i = 0; i < maxIter; ++i) StringUtils::toUTF8(unicodeChar, unicodeLength, utf8); - - BOOST_TEST_MESSAGE("Encode utf8 (buffer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"); + + // std::cout << "Encode utf8 (buffer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; } -BOOST_AUTO_TEST_CASE(testUnicodePerformance) +TEST_F(StringUtilsTest, testUnicodePerformance) { uint64_t startTime = MiscUtils::currentTimeMillis(); static const int32_t maxIter = 1000000; - + SingleString utf8 = "this is a utf8 string"; - + for (int32_t i = 0; i < maxIter; ++i) StringUtils::toUnicode(utf8); - - BOOST_TEST_MESSAGE("Decode utf8 (string): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"); - + + // std::cout << "Decode utf8 (string): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; + const uint8_t* utf8Char = (const uint8_t*)utf8.c_str(); int32_t utf8Length = (int32_t)utf8.length(); - + startTime = MiscUtils::currentTimeMillis(); - + for (int32_t i = 0; i < maxIter; ++i) StringUtils::toUnicode(utf8Char, utf8Length); - - BOOST_TEST_MESSAGE("Decode utf8 (pointer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"); - + + // std::cout << "Decode utf8 (pointer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; + CharArray unicode = CharArray::newInstance(utf8Length); - + startTime = MiscUtils::currentTimeMillis(); - + for (int32_t i = 0; i < maxIter; ++i) StringUtils::toUnicode(utf8Char, utf8Length, unicode); - - BOOST_TEST_MESSAGE("Decode utf8 (buffer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"); -} -BOOST_AUTO_TEST_SUITE_END() + // std::cout << "Decode utf8 (buffer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; +} diff --git a/src/test/util/VersionTest.cpp b/src/test/util/VersionTest.cpp index 0ffc90c7..b49a3ce2 100644 --- a/src/test/util/VersionTest.cpp +++ b/src/test/util/VersionTest.cpp @@ -9,15 +9,13 @@ using namespace Lucene; -BOOST_FIXTURE_TEST_SUITE(VersionTest, LuceneTestFixture) +typedef LuceneTestFixture VersionTest; -BOOST_AUTO_TEST_CASE(testVersion) +TEST_F(VersionTest, testVersion) { for (int32_t version = (int32_t)LuceneVersion::LUCENE_20; version <= (int32_t)LuceneVersion::LUCENE_CURRENT; ++version) - BOOST_CHECK(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_CURRENT, (LuceneVersion::Version)version)); - BOOST_CHECK(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_30, LuceneVersion::LUCENE_29)); - BOOST_CHECK(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_30, LuceneVersion::LUCENE_30)); - BOOST_CHECK(!LuceneVersion::onOrAfter(LuceneVersion::LUCENE_29, LuceneVersion::LUCENE_30)); + EXPECT_TRUE(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_CURRENT, (LuceneVersion::Version)version)); + EXPECT_TRUE(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_30, LuceneVersion::LUCENE_29)); + EXPECT_TRUE(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_30, LuceneVersion::LUCENE_30)); + EXPECT_TRUE(!LuceneVersion::onOrAfter(LuceneVersion::LUCENE_29, LuceneVersion::LUCENE_30)); } - -BOOST_AUTO_TEST_SUITE_END() From 2c65b5a404a794a9cccf7227f43820a0f724bb0c Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Wed, 12 Feb 2014 11:14:06 +0000 Subject: [PATCH 049/157] Subversion required for building gtest. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4afe5d0b..01c64aa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ option(ENABLE_CYCLIC_CHECK # bootstrap #################################### +find_package(Subversion REQUIRED) find_package(Threads REQUIRED) find_package(Boost COMPONENTS date_time From 59e5c65bfeaf68d3f62bb0299e9c9e78c26e77de Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Wed, 12 Feb 2014 11:18:28 +0000 Subject: [PATCH 050/157] Update copyright year and remove all trailing whitespace. --- include/ASCIIFoldingFilter.h | 18 +- include/AbstractAllTermDocs.h | 10 +- include/AbstractField.h | 152 +- include/AllTermDocs.h | 8 +- include/Analyzer.h | 38 +- include/Array.h | 40 +- include/Attribute.h | 18 +- include/AttributeSource.h | 110 +- include/AveragePayloadFunction.h | 8 +- include/Base64.h | 8 +- include/BaseCharFilter.h | 12 +- include/BitSet.h | 2 +- include/BitUtil.h | 40 +- include/BitVector.h | 52 +- include/BooleanClause.h | 26 +- include/BooleanQuery.h | 52 +- include/BooleanScorer.h | 66 +- include/BooleanScorer2.h | 80 +- include/BufferedDeletes.h | 20 +- include/BufferedIndexInput.h | 40 +- include/BufferedIndexOutput.h | 32 +- include/BufferedReader.h | 24 +- include/ByteBlockPool.h | 30 +- include/ByteFieldSource.h | 16 +- include/ByteSliceReader.h | 26 +- include/ByteSliceWriter.h | 16 +- include/CachingSpanFilter.h | 18 +- include/CachingTokenFilter.h | 14 +- include/CachingWrapperFilter.h | 42 +- include/CharArraySet.h | 28 +- include/CharBlockPool.h | 12 +- include/CharFilter.h | 16 +- include/CharFolder.h | 2 +- include/CharReader.h | 12 +- include/CharStream.h | 12 +- include/CharTokenizer.h | 20 +- include/CheckIndex.h | 168 +-- include/ChecksumIndexInput.h | 24 +- include/ChecksumIndexOutput.h | 30 +- include/CloseableThreadLocal.h | 16 +- include/Collator.h | 8 +- include/Collection.h | 2 +- include/Collector.h | 60 +- include/ComplexExplanation.h | 18 +- include/CompoundFileReader.h | 50 +- include/CompoundFileWriter.h | 34 +- include/CompressionTools.h | 20 +- include/ConcurrentMergeScheduler.h | 66 +- include/Config.h.cmake | 2 +- include/ConjunctionScorer.h | 10 +- include/ConstantScoreQuery.h | 22 +- include/Constants.h | 50 +- include/CustomScoreProvider.h | 40 +- include/CustomScoreQuery.h | 82 +- include/CycleCheck.h | 14 +- include/DateField.h | 30 +- include/DateTools.h | 56 +- include/DefaultSimilarity.h | 28 +- include/DefaultSkipListReader.h | 28 +- include/DefaultSkipListWriter.h | 16 +- include/Directory.h | 74 +- include/DirectoryReader.h | 202 +-- include/DisjunctionMaxQuery.h | 68 +- include/DisjunctionMaxScorer.h | 26 +- include/DisjunctionSumScorer.h | 60 +- include/DocConsumer.h | 6 +- include/DocConsumerPerThread.h | 8 +- include/DocFieldConsumer.h | 18 +- include/DocFieldConsumerPerField.h | 8 +- include/DocFieldConsumerPerThread.h | 6 +- include/DocFieldConsumers.h | 30 +- include/DocFieldConsumersPerField.h | 10 +- include/DocFieldConsumersPerThread.h | 12 +- include/DocFieldProcessor.h | 12 +- include/DocFieldProcessorPerField.h | 12 +- include/DocFieldProcessorPerThread.h | 34 +- include/DocIdBitSet.h | 16 +- include/DocIdSet.h | 16 +- include/DocIdSetIterator.h | 32 +- include/DocInverter.h | 18 +- include/DocInverterPerField.h | 14 +- include/DocInverterPerThread.h | 22 +- include/DocValues.h | 56 +- include/Document.h | 94 +- include/DocumentsWriter.h | 310 ++-- include/DocumentsWriterThreadState.h | 10 +- include/DoubleFieldSource.h | 24 +- include/ExactPhraseScorer.h | 6 +- include/Explanation.h | 34 +- include/FSDirectory.h | 82 +- include/FSLockFactory.h | 16 +- include/FastCharStream.h | 20 +- include/Field.h | 88 +- include/FieldCache.h | 140 +- include/FieldCacheImpl.h | 86 +- include/FieldCacheRangeFilter.h | 84 +- include/FieldCacheSanityChecker.h | 80 +- include/FieldCacheSource.h | 30 +- include/FieldCacheTermsFilter.h | 38 +- include/FieldComparator.h | 174 +-- include/FieldComparatorSource.h | 4 +- include/FieldDoc.h | 18 +- include/FieldDocSortedHitQueue.h | 26 +- include/FieldInfo.h | 22 +- include/FieldInfos.h | 72 +- include/FieldInvertState.h | 24 +- include/FieldMaskingSpanQuery.h | 26 +- include/FieldScoreQuery.h | 32 +- include/FieldSelector.h | 50 +- include/FieldSortedTermVectorMapper.h | 18 +- include/FieldValueHitQueue.h | 28 +- include/Fieldable.h | 72 +- include/FieldsReader.h | 88 +- include/FieldsWriter.h | 26 +- include/FileReader.h | 18 +- include/FileSwitchDirectory.h | 50 +- include/FileUtils.h | 30 +- include/Filter.h | 16 +- include/FilterIndexReader.h | 50 +- include/FilterManager.h | 36 +- include/FilteredDocIdSet.h | 22 +- include/FilteredDocIdSetIterator.h | 10 +- include/FilteredQuery.h | 28 +- include/FilteredTermEnum.h | 30 +- include/FlagsAttribute.h | 24 +- include/FormatPostingsDocsConsumer.h | 8 +- include/FormatPostingsDocsWriter.h | 22 +- include/FormatPostingsFieldsConsumer.h | 8 +- include/FormatPostingsFieldsWriter.h | 12 +- include/FormatPostingsPositionsConsumer.h | 8 +- include/FormatPostingsPositionsWriter.h | 18 +- include/FormatPostingsTermsConsumer.h | 10 +- include/FormatPostingsTermsWriter.h | 18 +- include/FreqProxFieldMergeState.h | 18 +- include/FreqProxTermsWriter.h | 20 +- include/FreqProxTermsWriterPerField.h | 8 +- include/FreqProxTermsWriterPerThread.h | 8 +- include/FuzzyQuery.h | 44 +- include/FuzzyTermEnum.h | 54 +- include/HashMap.h | 2 +- include/HashSet.h | 2 +- include/HitQueue.h | 10 +- include/HitQueueBase.h | 22 +- include/ISOLatin1AccentFilter.h | 12 +- include/IndexCommit.h | 38 +- include/IndexDeletionPolicy.h | 46 +- include/IndexFileDeleter.h | 104 +- include/IndexFileNameFilter.h | 10 +- include/IndexFileNames.h | 70 +- include/IndexInput.h | 58 +- include/IndexOutput.h | 52 +- include/IndexReader.h | 448 +++--- include/IndexSearcher.h | 54 +- include/IndexWriter.h | 848 +++++------ include/InfoStream.h | 22 +- include/InputStreamReader.h | 16 +- include/IntBlockPool.h | 14 +- include/IntFieldSource.h | 16 +- include/InvertedDocConsumer.h | 18 +- include/InvertedDocConsumerPerField.h | 16 +- include/InvertedDocConsumerPerThread.h | 6 +- include/InvertedDocEndConsumer.h | 6 +- include/InvertedDocEndConsumerPerField.h | 6 +- include/InvertedDocEndConsumerPerThread.h | 6 +- include/KeepOnlyLastCommitDeletionPolicy.h | 10 +- include/KeywordAnalyzer.h | 8 +- include/KeywordTokenizer.h | 14 +- include/LengthFilter.h | 10 +- include/LetterTokenizer.h | 16 +- include/LoadFirstFieldSelector.h | 6 +- include/Lock.h | 22 +- include/LockFactory.h | 20 +- include/LogByteSizeMergePolicy.h | 36 +- include/LogDocMergePolicy.h | 22 +- include/LogMergePolicy.h | 100 +- include/LowerCaseFilter.h | 8 +- include/LowerCaseTokenizer.h | 20 +- include/Lucene.h | 2 +- include/LuceneAllocator.h | 2 +- include/LuceneException.h | 14 +- include/LuceneFactory.h | 2 +- include/LuceneHeaders.h | 2 +- include/LuceneObject.h | 16 +- include/LuceneSignal.h | 10 +- include/LuceneSync.h | 18 +- include/LuceneThread.h | 38 +- include/LuceneTypes.h | 18 +- include/MMapDirectory.h | 20 +- include/Map.h | 2 +- include/MapFieldSelector.h | 14 +- include/MapOfSets.h | 14 +- include/MappingCharFilter.h | 14 +- include/MatchAllDocsQuery.h | 14 +- include/MaxPayloadFunction.h | 6 +- include/MergeDocIDRemapper.h | 14 +- include/MergePolicy.h | 80 +- include/MergeScheduler.h | 8 +- include/MinPayloadFunction.h | 6 +- include/MiscUtils.h | 82 +- include/MultiFieldQueryParser.h | 40 +- include/MultiLevelSkipListReader.h | 72 +- include/MultiLevelSkipListWriter.h | 38 +- include/MultiPhraseQuery.h | 38 +- include/MultiReader.h | 82 +- include/MultiSearcher.h | 26 +- include/MultiTermQuery.h | 106 +- include/MultiTermQueryWrapperFilter.h | 22 +- include/MultipleTermPositions.h | 20 +- include/NativeFSLockFactory.h | 18 +- include/NearSpansOrdered.h | 44 +- include/NearSpansUnordered.h | 26 +- include/NoLockFactory.h | 14 +- include/NormalizeCharMap.h | 10 +- include/NormsWriter.h | 18 +- include/NormsWriterPerField.h | 18 +- include/NormsWriterPerThread.h | 10 +- include/NumberTools.h | 28 +- include/NumericField.h | 88 +- include/NumericRangeFilter.h | 50 +- include/NumericRangeQuery.h | 140 +- include/NumericTokenStream.h | 50 +- include/NumericUtils.h | 86 +- include/OffsetAttribute.h | 22 +- include/OpenBitSet.h | 132 +- include/OpenBitSetDISI.h | 30 +- include/OpenBitSetIterator.h | 16 +- include/OrdFieldSource.h | 22 +- include/ParallelMultiSearcher.h | 18 +- include/ParallelReader.h | 132 +- include/Payload.h | 50 +- include/PayloadAttribute.h | 18 +- include/PayloadFunction.h | 12 +- include/PayloadNearQuery.h | 44 +- include/PayloadSpanUtil.h | 14 +- include/PayloadTermQuery.h | 16 +- include/PerFieldAnalyzerWrapper.h | 28 +- include/PhrasePositions.h | 10 +- include/PhraseQuery.h | 38 +- include/PhraseQueue.h | 6 +- include/PhraseScorer.h | 40 +- include/PorterStemFilter.h | 14 +- include/PorterStemmer.h | 58 +- include/PositionBasedTermVectorMapper.h | 40 +- include/PositionIncrementAttribute.h | 26 +- include/PositiveScoresOnlyCollector.h | 10 +- include/PrefixFilter.h | 8 +- include/PrefixQuery.h | 20 +- include/PrefixTermEnum.h | 14 +- include/PriorityQueue.h | 2 +- include/Query.h | 52 +- include/QueryParseError.h | 22 +- include/QueryParser.h | 264 ++-- include/QueryParserCharStream.h | 38 +- include/QueryParserConstants.h | 10 +- include/QueryParserToken.h | 48 +- include/QueryParserTokenManager.h | 38 +- include/QueryTermVector.h | 14 +- include/QueryWrapperFilter.h | 16 +- include/RAMDirectory.h | 42 +- include/RAMFile.h | 24 +- include/RAMInputStream.h | 26 +- include/RAMOutputStream.h | 28 +- include/Random.h | 2 +- include/RawPostingList.h | 16 +- include/ReadOnlyDirectoryReader.h | 10 +- include/ReadOnlySegmentReader.h | 8 +- include/Reader.h | 22 +- include/ReaderUtil.h | 12 +- include/ReqExclScorer.h | 16 +- include/ReqOptSumScorer.h | 16 +- include/ReusableStringReader.h | 16 +- include/ReverseOrdFieldSource.h | 22 +- include/ScoreCachingWrappingScorer.h | 16 +- include/ScoreDoc.h | 10 +- include/Scorer.h | 22 +- include/ScorerDocQueue.h | 40 +- include/Searchable.h | 36 +- include/Searcher.h | 46 +- include/SegmentInfo.h | 116 +- include/SegmentInfoCollection.h | 10 +- include/SegmentInfos.h | 112 +- include/SegmentMergeInfo.h | 12 +- include/SegmentMergeQueue.h | 8 +- include/SegmentMerger.h | 80 +- include/SegmentReader.h | 124 +- include/SegmentTermDocs.h | 38 +- include/SegmentTermEnum.h | 38 +- include/SegmentTermPositionVector.h | 14 +- include/SegmentTermPositions.h | 44 +- include/SegmentTermVector.h | 22 +- include/SegmentWriteState.h | 12 +- include/SerialMergeScheduler.h | 8 +- include/Set.h | 2 +- include/SetBasedFieldSelector.h | 16 +- include/Similarity.h | 230 +-- include/SimilarityDelegator.h | 10 +- include/SimpleAnalyzer.h | 6 +- include/SimpleFSDirectory.h | 10 +- include/SimpleFSLockFactory.h | 16 +- include/SimpleLRUCache.h | 2 +- include/SingleInstanceLockFactory.h | 14 +- include/SingleTermEnum.h | 12 +- include/SloppyPhraseScorer.h | 38 +- include/SmallDouble.h | 8 +- include/SnapshotDeletionPolicy.h | 22 +- include/Sort.h | 64 +- include/SortField.h | 78 +- include/SortedTermVectorMapper.h | 22 +- include/SortedVIntList.h | 42 +- include/SpanFilter.h | 12 +- include/SpanFilterResult.h | 32 +- include/SpanFirstQuery.h | 18 +- include/SpanNearQuery.h | 24 +- include/SpanNotQuery.h | 16 +- include/SpanOrQuery.h | 16 +- include/SpanQuery.h | 8 +- include/SpanQueryFilter.h | 20 +- include/SpanScorer.h | 16 +- include/SpanTermQuery.h | 12 +- include/SpanWeight.h | 12 +- include/Spans.h | 32 +- include/StandardAnalyzer.h | 38 +- include/StandardFilter.h | 10 +- include/StandardTokenizer.h | 44 +- include/StandardTokenizerImpl.h | 100 +- include/StopAnalyzer.h | 22 +- include/StopFilter.h | 32 +- include/StoredFieldsWriter.h | 24 +- include/StoredFieldsWriterPerThread.h | 8 +- include/StringReader.h | 16 +- include/StringUtils.h | 50 +- include/Synchronize.h | 24 +- include/TeeSinkTokenFilter.h | 66 +- include/Term.h | 32 +- include/TermAttribute.h | 54 +- include/TermBuffer.h | 22 +- include/TermDocs.h | 20 +- include/TermEnum.h | 14 +- include/TermFreqVector.h | 30 +- include/TermInfo.h | 8 +- include/TermInfosReader.h | 42 +- include/TermInfosWriter.h | 56 +- include/TermPositionVector.h | 10 +- include/TermPositions.h | 24 +- include/TermQuery.h | 22 +- include/TermRangeFilter.h | 34 +- include/TermRangeQuery.h | 40 +- include/TermRangeTermEnum.h | 24 +- include/TermScorer.h | 30 +- include/TermSpans.h | 10 +- include/TermVectorEntry.h | 14 +- include/TermVectorEntryFreqSortedComparator.h | 6 +- include/TermVectorMapper.h | 32 +- include/TermVectorOffsetInfo.h | 18 +- include/TermVectorsReader.h | 78 +- include/TermVectorsTermsWriter.h | 34 +- include/TermVectorsTermsWriterPerField.h | 20 +- include/TermVectorsTermsWriterPerThread.h | 12 +- include/TermVectorsWriter.h | 14 +- include/TermsHash.h | 32 +- include/TermsHashConsumer.h | 10 +- include/TermsHashConsumerPerField.h | 6 +- include/TermsHashConsumerPerThread.h | 6 +- include/TermsHashPerField.h | 46 +- include/TermsHashPerThread.h | 24 +- include/TestPoint.h | 10 +- include/ThreadPool.h | 28 +- include/TimeLimitingCollector.h | 58 +- include/Token.h | 192 +-- include/TokenFilter.h | 12 +- include/TokenStream.h | 66 +- include/Tokenizer.h | 34 +- include/TopDocs.h | 20 +- include/TopDocsCollector.h | 58 +- include/TopFieldCollector.h | 40 +- include/TopFieldDocs.h | 8 +- include/TopScoreDocCollector.h | 22 +- include/TypeAttribute.h | 14 +- include/UTF8Stream.h | 66 +- include/UnicodeUtils.h | 38 +- include/ValueSource.h | 22 +- include/ValueSourceQuery.h | 16 +- include/VariantUtils.h | 20 +- include/Weight.h | 38 +- include/WhitespaceAnalyzer.h | 6 +- include/WhitespaceTokenizer.h | 14 +- include/WildcardQuery.h | 24 +- include/WildcardTermEnum.h | 20 +- include/WordlistLoader.h | 14 +- include/targetver.h | 2 +- .../common/analysis/ar/ArabicAnalyzer.cpp | 120 +- .../analysis/ar/ArabicLetterTokenizer.cpp | 10 +- .../analysis/ar/ArabicNormalizationFilter.cpp | 6 +- .../common/analysis/ar/ArabicNormalizer.cpp | 16 +- .../common/analysis/ar/ArabicStemFilter.cpp | 6 +- .../common/analysis/ar/ArabicStemmer.cpp | 22 +- .../common/analysis/br/BrazilianAnalyzer.cpp | 38 +- .../analysis/br/BrazilianStemFilter.cpp | 8 +- .../common/analysis/br/BrazilianStemmer.cpp | 60 +- .../common/analysis/cjk/CJKAnalyzer.cpp | 28 +- .../common/analysis/cjk/CJKTokenizer.cpp | 34 +- .../common/analysis/cn/ChineseAnalyzer.cpp | 8 +- .../common/analysis/cn/ChineseFilter.cpp | 12 +- .../common/analysis/cn/ChineseTokenizer.cpp | 32 +- .../common/analysis/cz/CzechAnalyzer.cpp | 120 +- .../common/analysis/de/GermanAnalyzer.cpp | 34 +- .../common/analysis/de/GermanStemFilter.cpp | 12 +- .../common/analysis/de/GermanStemmer.cpp | 24 +- .../common/analysis/el/GreekAnalyzer.cpp | 96 +- .../analysis/el/GreekLowerCaseFilter.cpp | 34 +- .../common/analysis/fa/PersianAnalyzer.cpp | 352 ++--- .../fa/PersianNormalizationFilter.cpp | 6 +- .../common/analysis/fa/PersianNormalizer.cpp | 12 +- .../common/analysis/fr/ElisionFilter.cpp | 18 +- .../common/analysis/fr/FrenchAnalyzer.cpp | 58 +- .../common/analysis/fr/FrenchStemFilter.cpp | 12 +- .../common/analysis/fr/FrenchStemmer.cpp | 74 +- .../common/analysis/nl/DutchAnalyzer.cpp | 40 +- .../common/analysis/nl/DutchStemFilter.cpp | 18 +- .../common/analysis/nl/DutchStemmer.cpp | 48 +- .../analysis/reverse/ReverseStringFilter.cpp | 22 +- .../common/analysis/ru/RussianAnalyzer.cpp | 104 +- .../analysis/ru/RussianLetterTokenizer.cpp | 10 +- .../analysis/ru/RussianLowerCaseFilter.cpp | 6 +- .../common/analysis/ru/RussianStemFilter.cpp | 8 +- .../common/analysis/ru/RussianStemmer.cpp | 84 +- src/contrib/highlighter/DefaultEncoder.cpp | 4 +- src/contrib/highlighter/Encoder.cpp | 4 +- src/contrib/highlighter/Formatter.cpp | 4 +- src/contrib/highlighter/Fragmenter.cpp | 6 +- src/contrib/highlighter/GradientFormatter.cpp | 24 +- src/contrib/highlighter/Highlighter.cpp | 74 +- src/contrib/highlighter/HighlighterScorer.cpp | 8 +- .../highlighter/MapWeightedSpanTerm.cpp | 14 +- src/contrib/highlighter/NullFragmenter.cpp | 6 +- src/contrib/highlighter/QueryScorer.cpp | 40 +- .../highlighter/QueryTermExtractor.cpp | 16 +- src/contrib/highlighter/QueryTermScorer.cpp | 28 +- src/contrib/highlighter/SimpleFragmenter.cpp | 16 +- src/contrib/highlighter/SimpleHTMLEncoder.cpp | 18 +- .../highlighter/SimpleHTMLFormatter.cpp | 10 +- .../highlighter/SimpleSpanFragmenter.cpp | 28 +- .../highlighter/SpanGradientFormatter.cpp | 8 +- src/contrib/highlighter/TextFragment.cpp | 26 +- src/contrib/highlighter/TokenGroup.cpp | 26 +- src/contrib/highlighter/TokenSources.cpp | 34 +- src/contrib/highlighter/WeightedSpanTerm.cpp | 20 +- .../highlighter/WeightedSpanTermExtractor.cpp | 86 +- src/contrib/highlighter/WeightedTerm.cpp | 12 +- src/contrib/include/ArabicAnalyzer.h | 32 +- src/contrib/include/ArabicLetterTokenizer.h | 12 +- .../include/ArabicNormalizationFilter.h | 8 +- src/contrib/include/ArabicNormalizer.h | 18 +- src/contrib/include/ArabicStemFilter.h | 8 +- src/contrib/include/ArabicStemmer.h | 22 +- src/contrib/include/BrazilianAnalyzer.h | 38 +- src/contrib/include/BrazilianStemFilter.h | 12 +- src/contrib/include/BrazilianStemmer.h | 42 +- src/contrib/include/CJKAnalyzer.h | 26 +- src/contrib/include/CJKTokenizer.h | 32 +- src/contrib/include/ChineseAnalyzer.h | 14 +- src/contrib/include/ChineseFilter.h | 12 +- src/contrib/include/ChineseTokenizer.h | 28 +- src/contrib/include/ContribInc.h | 2 +- src/contrib/include/CzechAnalyzer.h | 30 +- src/contrib/include/DefaultEncoder.h | 4 +- src/contrib/include/DutchAnalyzer.h | 42 +- src/contrib/include/DutchStemFilter.h | 36 +- src/contrib/include/DutchStemmer.h | 52 +- src/contrib/include/ElisionFilter.h | 16 +- src/contrib/include/Encoder.h | 4 +- src/contrib/include/Formatter.h | 6 +- src/contrib/include/Fragmenter.h | 16 +- src/contrib/include/FrenchAnalyzer.h | 38 +- src/contrib/include/FrenchStemFilter.h | 28 +- src/contrib/include/FrenchStemmer.h | 78 +- src/contrib/include/GermanAnalyzer.h | 40 +- src/contrib/include/GermanStemFilter.h | 24 +- src/contrib/include/GermanStemmer.h | 30 +- src/contrib/include/GradientFormatter.h | 20 +- src/contrib/include/GreekAnalyzer.h | 30 +- src/contrib/include/GreekLowerCaseFilter.h | 14 +- src/contrib/include/Highlighter.h | 74 +- src/contrib/include/HighlighterScorer.h | 22 +- src/contrib/include/LuceneContrib.h | 10 +- src/contrib/include/MapWeightedSpanTerm.h | 8 +- src/contrib/include/MemoryIndex.h | 198 +-- src/contrib/include/NullFragmenter.h | 6 +- src/contrib/include/PersianAnalyzer.h | 36 +- .../include/PersianNormalizationFilter.h | 8 +- src/contrib/include/PersianNormalizer.h | 14 +- src/contrib/include/QueryScorer.h | 40 +- src/contrib/include/QueryTermExtractor.h | 24 +- src/contrib/include/QueryTermScorer.h | 36 +- src/contrib/include/ReverseStringFilter.h | 36 +- src/contrib/include/RussianAnalyzer.h | 28 +- src/contrib/include/RussianLetterTokenizer.h | 16 +- src/contrib/include/RussianLowerCaseFilter.h | 10 +- src/contrib/include/RussianStemFilter.h | 16 +- src/contrib/include/RussianStemmer.h | 44 +- src/contrib/include/SimpleFragmenter.h | 16 +- src/contrib/include/SimpleHTMLEncoder.h | 6 +- src/contrib/include/SimpleHTMLFormatter.h | 16 +- src/contrib/include/SimpleSpanFragmenter.h | 16 +- src/contrib/include/SnowballAnalyzer.h | 28 +- src/contrib/include/SnowballFilter.h | 8 +- src/contrib/include/SpanGradientFormatter.h | 10 +- src/contrib/include/TextFragment.h | 22 +- src/contrib/include/TokenGroup.h | 26 +- src/contrib/include/TokenSources.h | 40 +- src/contrib/include/WeightedSpanTerm.h | 20 +- .../include/WeightedSpanTermExtractor.h | 54 +- src/contrib/include/WeightedTerm.h | 14 +- src/contrib/memory/MemoryIndex.cpp | 194 +-- src/contrib/msvc/ContribInc.cpp | 2 +- src/contrib/msvc/dllmain.cpp | 2 +- src/contrib/snowball/SnowballAnalyzer.cpp | 12 +- src/contrib/snowball/SnowballFilter.cpp | 6 +- src/core/analysis/ASCIIFoldingFilter.cpp | 20 +- src/core/analysis/Analyzer.cpp | 14 +- src/core/analysis/BaseCharFilter.cpp | 20 +- src/core/analysis/CachingTokenFilter.cpp | 16 +- src/core/analysis/CharArraySet.cpp | 24 +- src/core/analysis/CharFilter.cpp | 18 +- src/core/analysis/CharReader.cpp | 18 +- src/core/analysis/CharStream.cpp | 2 +- src/core/analysis/CharTokenizer.cpp | 36 +- src/core/analysis/ISOLatin1AccentFilter.cpp | 22 +- src/core/analysis/KeywordAnalyzer.cpp | 6 +- src/core/analysis/KeywordTokenizer.cpp | 20 +- src/core/analysis/LengthFilter.cpp | 6 +- src/core/analysis/LetterTokenizer.cpp | 10 +- src/core/analysis/LowerCaseFilter.cpp | 6 +- src/core/analysis/LowerCaseTokenizer.cpp | 10 +- src/core/analysis/MappingCharFilter.cpp | 22 +- src/core/analysis/NormalizeCharMap.cpp | 6 +- src/core/analysis/NumericTokenStream.cpp | 30 +- src/core/analysis/PerFieldAnalyzerWrapper.cpp | 18 +- src/core/analysis/PorterStemFilter.cpp | 8 +- src/core/analysis/PorterStemmer.cpp | 50 +- src/core/analysis/SimpleAnalyzer.cpp | 6 +- src/core/analysis/StopAnalyzer.cpp | 26 +- src/core/analysis/StopFilter.cpp | 16 +- src/core/analysis/TeeSinkTokenFilter.cpp | 46 +- src/core/analysis/Token.cpp | 132 +- src/core/analysis/TokenFilter.cpp | 10 +- src/core/analysis/TokenStream.cpp | 14 +- src/core/analysis/Tokenizer.cpp | 20 +- src/core/analysis/WhitespaceAnalyzer.cpp | 6 +- src/core/analysis/WhitespaceTokenizer.cpp | 10 +- src/core/analysis/WordlistLoader.cpp | 8 +- .../analysis/standard/StandardAnalyzer.cpp | 28 +- src/core/analysis/standard/StandardFilter.cpp | 16 +- .../analysis/standard/StandardTokenizer.cpp | 38 +- .../standard/StandardTokenizerImpl.cpp | 98 +- .../tokenattributes/FlagsAttribute.cpp | 24 +- .../tokenattributes/OffsetAttribute.cpp | 26 +- .../tokenattributes/PayloadAttribute.cpp | 26 +- .../PositionIncrementAttribute.cpp | 24 +- .../tokenattributes/TermAttribute.cpp | 50 +- .../tokenattributes/TypeAttribute.cpp | 28 +- src/core/document/AbstractField.cpp | 60 +- src/core/document/CompressionTools.cpp | 58 +- src/core/document/DateField.cpp | 18 +- src/core/document/DateTools.cpp | 62 +- src/core/document/Document.cpp | 36 +- src/core/document/Field.cpp | 146 +- src/core/document/FieldSelector.cpp | 2 +- src/core/document/Fieldable.cpp | 46 +- src/core/document/LoadFirstFieldSelector.cpp | 4 +- src/core/document/MapFieldSelector.cpp | 8 +- src/core/document/NumberTools.cpp | 32 +- src/core/document/NumericField.cpp | 28 +- src/core/document/SetBasedFieldSelector.cpp | 6 +- src/core/include/LuceneInc.h | 2 +- src/core/include/_BooleanQuery.h | 16 +- src/core/include/_ByteFieldSource.h | 8 +- src/core/include/_CachingSpanFilter.h | 4 +- src/core/include/_CachingWrapperFilter.h | 18 +- src/core/include/_CheckIndex.h | 8 +- src/core/include/_ConcurrentMergeScheduler.h | 8 +- src/core/include/_ConstantScoreQuery.h | 16 +- src/core/include/_CustomScoreQuery.h | 28 +- src/core/include/_DirectoryReader.h | 18 +- src/core/include/_DisjunctionMaxQuery.h | 24 +- src/core/include/_DocIdBitSet.h | 8 +- src/core/include/_DocIdSet.h | 8 +- src/core/include/_FieldCache.h | 28 +- src/core/include/_FieldCacheRangeFilter.h | 104 +- src/core/include/_FieldCacheSanityChecker.h | 8 +- src/core/include/_FieldCacheTermsFilter.h | 18 +- src/core/include/_FieldValueHitQueue.h | 14 +- src/core/include/_FilterManager.h | 22 +- src/core/include/_FilteredDocIdSet.h | 8 +- src/core/include/_FilteredQuery.h | 20 +- src/core/include/_FuzzyQuery.h | 12 +- src/core/include/_IndexReader.h | 6 +- src/core/include/_IndexWriter.h | 38 +- src/core/include/_IntFieldSource.h | 8 +- src/core/include/_MMapDirectory.h | 20 +- src/core/include/_MatchAllDocsQuery.h | 18 +- src/core/include/_MultiPhraseQuery.h | 8 +- src/core/include/_MultiSearcher.h | 36 +- src/core/include/_MultiTermQuery.h | 16 +- src/core/include/_MultipleTermPositions.h | 20 +- src/core/include/_NativeFSLockFactory.h | 12 +- src/core/include/_NearSpansUnordered.h | 18 +- src/core/include/_NoLockFactory.h | 6 +- src/core/include/_NumericRangeQuery.h | 38 +- src/core/include/_OrdFieldSource.h | 8 +- src/core/include/_ParallelReader.h | 28 +- src/core/include/_PayloadTermQuery.h | 28 +- src/core/include/_PhraseQuery.h | 8 +- src/core/include/_QueryWrapperFilter.h | 8 +- src/core/include/_ReverseOrdFieldSource.h | 8 +- src/core/include/_ScorerDocQueue.h | 8 +- src/core/include/_SegmentInfos.h | 30 +- src/core/include/_SegmentReader.h | 74 +- src/core/include/_Similarity.h | 10 +- src/core/include/_SimpleFSDirectory.h | 42 +- src/core/include/_SimpleFSLockFactory.h | 16 +- src/core/include/_SingleInstanceLockFactory.h | 14 +- src/core/include/_SnapshotDeletionPolicy.h | 28 +- src/core/include/_SortedVIntList.h | 10 +- src/core/include/_SpanFirstQuery.h | 8 +- src/core/include/_SpanNotQuery.h | 8 +- src/core/include/_SpanOrQuery.h | 16 +- src/core/include/_StandardAnalyzer.h | 4 +- src/core/include/_StopAnalyzer.h | 6 +- src/core/include/_TermQuery.h | 8 +- src/core/include/_TimeLimitingCollector.h | 12 +- src/core/include/_TopFieldCollector.h | 94 +- src/core/include/_TopScoreDocCollector.h | 12 +- src/core/include/_ValueSourceQuery.h | 20 +- src/core/index/AbstractAllTermDocs.cpp | 20 +- src/core/index/AllTermDocs.cpp | 6 +- src/core/index/BufferedDeletes.cpp | 44 +- src/core/index/ByteBlockPool.cpp | 42 +- src/core/index/ByteSliceReader.cpp | 42 +- src/core/index/ByteSliceWriter.cpp | 16 +- src/core/index/CharBlockPool.cpp | 10 +- src/core/index/CheckIndex.cpp | 232 +-- src/core/index/CompoundFileReader.cpp | 80 +- src/core/index/CompoundFileWriter.cpp | 2 +- src/core/index/ConcurrentMergeScheduler.cpp | 106 +- src/core/index/DefaultSkipListReader.cpp | 30 +- src/core/index/DefaultSkipListWriter.cpp | 26 +- src/core/index/DirectoryReader.cpp | 354 ++--- src/core/index/DocConsumer.cpp | 2 +- src/core/index/DocConsumerPerThread.cpp | 2 +- src/core/index/DocFieldConsumer.cpp | 4 +- src/core/index/DocFieldConsumerPerField.cpp | 2 +- src/core/index/DocFieldConsumerPerThread.cpp | 2 +- src/core/index/DocFieldConsumers.cpp | 38 +- src/core/index/DocFieldConsumersPerField.cpp | 8 +- src/core/index/DocFieldConsumersPerThread.cpp | 16 +- src/core/index/DocFieldProcessor.cpp | 18 +- src/core/index/DocFieldProcessorPerField.cpp | 6 +- src/core/index/DocFieldProcessorPerThread.cpp | 96 +- src/core/index/DocInverter.cpp | 24 +- src/core/index/DocInverterPerField.cpp | 60 +- src/core/index/DocInverterPerThread.cpp | 20 +- src/core/index/DocumentsWriter.cpp | 468 +++--- src/core/index/DocumentsWriterThreadState.cpp | 8 +- src/core/index/FieldInfo.cpp | 18 +- src/core/index/FieldInfos.cpp | 74 +- src/core/index/FieldInvertState.cpp | 18 +- .../index/FieldSortedTermVectorMapper.cpp | 14 +- src/core/index/FieldsReader.cpp | 136 +- src/core/index/FieldsWriter.cpp | 36 +- src/core/index/FilterIndexReader.cpp | 114 +- src/core/index/FormatPostingsDocsConsumer.cpp | 2 +- src/core/index/FormatPostingsDocsWriter.cpp | 36 +- .../index/FormatPostingsFieldsConsumer.cpp | 2 +- src/core/index/FormatPostingsFieldsWriter.cpp | 10 +- .../index/FormatPostingsPositionsConsumer.cpp | 2 +- .../index/FormatPostingsPositionsWriter.cpp | 22 +- .../index/FormatPostingsTermsConsumer.cpp | 4 +- src/core/index/FormatPostingsTermsWriter.cpp | 22 +- src/core/index/FreqProxFieldMergeState.cpp | 28 +- src/core/index/FreqProxTermsWriter.cpp | 104 +- .../index/FreqProxTermsWriterPerField.cpp | 40 +- .../index/FreqProxTermsWriterPerThread.cpp | 12 +- src/core/index/IndexCommit.cpp | 8 +- src/core/index/IndexDeletionPolicy.cpp | 2 +- src/core/index/IndexFileDeleter.cpp | 150 +- src/core/index/IndexFileNameFilter.cpp | 6 +- src/core/index/IndexFileNames.cpp | 60 +- src/core/index/IndexReader.cpp | 132 +- src/core/index/IndexWriter.cpp | 1284 ++++++++--------- src/core/index/IntBlockPool.cpp | 12 +- src/core/index/InvertedDocConsumer.cpp | 4 +- .../index/InvertedDocConsumerPerField.cpp | 2 +- .../index/InvertedDocConsumerPerThread.cpp | 2 +- src/core/index/InvertedDocEndConsumer.cpp | 2 +- .../index/InvertedDocEndConsumerPerField.cpp | 2 +- .../index/InvertedDocEndConsumerPerThread.cpp | 2 +- .../KeepOnlyLastCommitDeletionPolicy.cpp | 6 +- src/core/index/LogByteSizeMergePolicy.cpp | 18 +- src/core/index/LogDocMergePolicy.cpp | 14 +- src/core/index/LogMergePolicy.cpp | 124 +- src/core/index/MergeDocIDRemapper.cpp | 22 +- src/core/index/MergePolicy.cpp | 30 +- src/core/index/MergeScheduler.cpp | 2 +- src/core/index/MultiLevelSkipListReader.cpp | 2 +- src/core/index/MultiLevelSkipListWriter.cpp | 34 +- src/core/index/MultiReader.cpp | 88 +- src/core/index/MultipleTermPositions.cpp | 2 +- src/core/index/NormsWriter.cpp | 64 +- src/core/index/NormsWriterPerField.cpp | 14 +- src/core/index/NormsWriterPerThread.cpp | 14 +- src/core/index/ParallelReader.cpp | 172 +-- src/core/index/Payload.cpp | 36 +- .../index/PositionBasedTermVectorMapper.cpp | 24 +- src/core/index/RawPostingList.cpp | 6 +- src/core/index/ReadOnlyDirectoryReader.cpp | 20 +- src/core/index/ReadOnlySegmentReader.cpp | 8 +- src/core/index/ReusableStringReader.cpp | 10 +- src/core/index/SegmentInfo.cpp | 118 +- src/core/index/SegmentInfoCollection.cpp | 28 +- src/core/index/SegmentInfos.cpp | 224 +-- src/core/index/SegmentMergeInfo.cpp | 16 +- src/core/index/SegmentMergeQueue.cpp | 8 +- src/core/index/SegmentMerger.cpp | 186 +-- src/core/index/SegmentReader.cpp | 358 ++--- src/core/index/SegmentTermDocs.cpp | 58 +- src/core/index/SegmentTermEnum.cpp | 66 +- src/core/index/SegmentTermPositionVector.cpp | 14 +- src/core/index/SegmentTermPositions.cpp | 44 +- src/core/index/SegmentTermVector.cpp | 18 +- src/core/index/SegmentWriteState.cpp | 10 +- src/core/index/SerialMergeScheduler.cpp | 6 +- src/core/index/SnapshotDeletionPolicy.cpp | 38 +- src/core/index/SortedTermVectorMapper.cpp | 16 +- src/core/index/StoredFieldsWriter.cpp | 64 +- .../index/StoredFieldsWriterPerThread.cpp | 16 +- src/core/index/Term.cpp | 20 +- src/core/index/TermBuffer.cpp | 26 +- src/core/index/TermDocs.cpp | 18 +- src/core/index/TermEnum.cpp | 2 +- src/core/index/TermFreqVector.cpp | 16 +- src/core/index/TermInfo.cpp | 10 +- src/core/index/TermInfosReader.cpp | 78 +- src/core/index/TermInfosWriter.cpp | 48 +- src/core/index/TermPositionVector.cpp | 8 +- src/core/index/TermPositions.cpp | 12 +- src/core/index/TermVectorEntry.cpp | 32 +- .../TermVectorEntryFreqSortedComparator.cpp | 4 +- src/core/index/TermVectorMapper.cpp | 10 +- src/core/index/TermVectorOffsetInfo.cpp | 18 +- src/core/index/TermVectorsReader.cpp | 164 +-- src/core/index/TermVectorsTermsWriter.cpp | 100 +- .../index/TermVectorsTermsWriterPerField.cpp | 108 +- .../index/TermVectorsTermsWriterPerThread.cpp | 16 +- src/core/index/TermVectorsWriter.cpp | 52 +- src/core/index/TermsHash.cpp | 70 +- src/core/index/TermsHashConsumer.cpp | 4 +- src/core/index/TermsHashConsumerPerField.cpp | 2 +- src/core/index/TermsHashConsumerPerThread.cpp | 2 +- src/core/index/TermsHashPerField.cpp | 148 +- src/core/index/TermsHashPerThread.cpp | 28 +- src/core/msvc/LuceneInc.cpp | 2 +- src/core/msvc/dllmain.cpp | 2 +- src/core/queryparser/FastCharStream.cpp | 36 +- .../queryparser/MultiFieldQueryParser.cpp | 26 +- src/core/queryparser/QueryParseError.cpp | 10 +- src/core/queryparser/QueryParser.cpp | 240 +-- .../queryparser/QueryParserCharStream.cpp | 24 +- src/core/queryparser/QueryParserConstants.cpp | 6 +- src/core/queryparser/QueryParserToken.cpp | 8 +- .../queryparser/QueryParserTokenManager.cpp | 110 +- src/core/search/BooleanClause.cpp | 22 +- src/core/search/BooleanQuery.cpp | 110 +- src/core/search/BooleanScorer.cpp | 94 +- src/core/search/BooleanScorer2.cpp | 66 +- src/core/search/CachingSpanFilter.cpp | 34 +- src/core/search/CachingWrapperFilter.cpp | 60 +- src/core/search/Collector.cpp | 2 +- src/core/search/ComplexExplanation.cpp | 12 +- src/core/search/ConjunctionScorer.cpp | 40 +- src/core/search/ConstantScoreQuery.cpp | 56 +- src/core/search/DefaultSimilarity.cpp | 22 +- src/core/search/DisjunctionMaxQuery.cpp | 48 +- src/core/search/DisjunctionMaxScorer.cpp | 28 +- src/core/search/DisjunctionSumScorer.cpp | 32 +- src/core/search/DocIdSet.cpp | 20 +- src/core/search/DocIdSetIterator.cpp | 4 +- src/core/search/ExactPhraseScorer.cpp | 12 +- src/core/search/Explanation.cpp | 28 +- src/core/search/FieldCache.cpp | 130 +- src/core/search/FieldCacheImpl.cpp | 130 +- src/core/search/FieldCacheRangeFilter.cpp | 128 +- src/core/search/FieldCacheTermsFilter.cpp | 26 +- src/core/search/FieldComparator.cpp | 122 +- src/core/search/FieldComparatorSource.cpp | 2 +- src/core/search/FieldDoc.cpp | 6 +- src/core/search/FieldDocSortedHitQueue.cpp | 18 +- src/core/search/FieldValueHitQueue.cpp | 54 +- src/core/search/Filter.cpp | 2 +- src/core/search/FilterManager.cpp | 38 +- src/core/search/FilteredDocIdSet.cpp | 14 +- src/core/search/FilteredDocIdSetIterator.cpp | 10 +- src/core/search/FilteredQuery.cpp | 54 +- src/core/search/FilteredTermEnum.cpp | 12 +- src/core/search/FuzzyQuery.cpp | 56 +- src/core/search/FuzzyTermEnum.cpp | 66 +- src/core/search/HitQueue.cpp | 10 +- src/core/search/HitQueueBase.cpp | 32 +- src/core/search/IndexSearcher.cpp | 54 +- src/core/search/MatchAllDocsQuery.cpp | 46 +- src/core/search/MultiPhraseQuery.cpp | 110 +- src/core/search/MultiSearcher.cpp | 136 +- src/core/search/MultiTermQuery.cpp | 88 +- .../search/MultiTermQueryWrapperFilter.cpp | 18 +- src/core/search/NumericRangeFilter.cpp | 30 +- src/core/search/NumericRangeQuery.cpp | 106 +- src/core/search/ParallelMultiSearcher.cpp | 26 +- src/core/search/PhrasePositions.cpp | 14 +- src/core/search/PhraseQuery.cpp | 102 +- src/core/search/PhraseQueue.cpp | 10 +- src/core/search/PhraseScorer.cpp | 36 +- .../search/PositiveScoresOnlyCollector.cpp | 12 +- src/core/search/PrefixFilter.cpp | 8 +- src/core/search/PrefixQuery.cpp | 16 +- src/core/search/PrefixTermEnum.cpp | 14 +- src/core/search/Query.cpp | 36 +- src/core/search/QueryTermVector.cpp | 26 +- src/core/search/QueryWrapperFilter.cpp | 20 +- src/core/search/ReqExclScorer.cpp | 14 +- src/core/search/ReqOptSumScorer.cpp | 16 +- .../search/ScoreCachingWrappingScorer.cpp | 18 +- src/core/search/ScoreDoc.cpp | 6 +- src/core/search/Scorer.cpp | 10 +- src/core/search/Searchable.cpp | 22 +- src/core/search/Searcher.cpp | 24 +- src/core/search/Similarity.cpp | 36 +- src/core/search/SimilarityDelegator.cpp | 20 +- src/core/search/SingleTermEnum.cpp | 10 +- src/core/search/SloppyPhraseScorer.cpp | 46 +- src/core/search/Sort.cpp | 26 +- src/core/search/SortField.cpp | 50 +- src/core/search/SpanFilter.cpp | 2 +- src/core/search/SpanFilterResult.cpp | 26 +- src/core/search/SpanQueryFilter.cpp | 18 +- src/core/search/TermQuery.cpp | 72 +- src/core/search/TermRangeFilter.cpp | 26 +- src/core/search/TermRangeQuery.cpp | 28 +- src/core/search/TermRangeTermEnum.cpp | 26 +- src/core/search/TermScorer.cpp | 28 +- src/core/search/TimeLimitingCollector.cpp | 40 +- src/core/search/TopDocs.cpp | 10 +- src/core/search/TopDocsCollector.cpp | 42 +- src/core/search/TopFieldCollector.cpp | 218 +-- src/core/search/TopFieldDocs.cpp | 4 +- src/core/search/TopScoreDocCollector.cpp | 48 +- src/core/search/Weight.cpp | 4 +- src/core/search/WildcardQuery.cpp | 22 +- src/core/search/WildcardTermEnum.cpp | 34 +- src/core/search/function/ByteFieldSource.cpp | 26 +- .../search/function/CustomScoreProvider.cpp | 10 +- src/core/search/function/CustomScoreQuery.cpp | 90 +- src/core/search/function/DocValues.cpp | 24 +- .../search/function/DoubleFieldSource.cpp | 22 +- src/core/search/function/FieldCacheSource.cpp | 12 +- src/core/search/function/FieldScoreQuery.cpp | 6 +- src/core/search/function/IntFieldSource.cpp | 24 +- src/core/search/function/OrdFieldSource.cpp | 24 +- .../search/function/ReverseOrdFieldSource.cpp | 26 +- src/core/search/function/ValueSource.cpp | 4 +- src/core/search/function/ValueSourceQuery.cpp | 50 +- .../payloads/AveragePayloadFunction.cpp | 10 +- .../search/payloads/MaxPayloadFunction.cpp | 10 +- .../search/payloads/MinPayloadFunction.cpp | 10 +- src/core/search/payloads/PayloadFunction.cpp | 2 +- src/core/search/payloads/PayloadNearQuery.cpp | 46 +- src/core/search/payloads/PayloadSpanUtil.cpp | 28 +- src/core/search/payloads/PayloadTermQuery.cpp | 52 +- .../search/spans/FieldMaskingSpanQuery.cpp | 38 +- src/core/search/spans/NearSpansOrdered.cpp | 56 +- src/core/search/spans/NearSpansUnordered.cpp | 90 +- src/core/search/spans/SpanFirstQuery.cpp | 48 +- src/core/search/spans/SpanNearQuery.cpp | 42 +- src/core/search/spans/SpanNotQuery.cpp | 72 +- src/core/search/spans/SpanOrQuery.cpp | 72 +- src/core/search/spans/SpanQuery.cpp | 4 +- src/core/search/spans/SpanScorer.cpp | 22 +- src/core/search/spans/SpanTermQuery.cpp | 20 +- src/core/search/spans/SpanWeight.cpp | 46 +- src/core/search/spans/Spans.cpp | 2 +- src/core/search/spans/TermSpans.cpp | 28 +- src/core/store/BufferedIndexInput.cpp | 42 +- src/core/store/BufferedIndexOutput.cpp | 22 +- src/core/store/ChecksumIndexInput.cpp | 20 +- src/core/store/ChecksumIndexOutput.cpp | 28 +- src/core/store/Directory.cpp | 32 +- src/core/store/FSDirectory.cpp | 74 +- src/core/store/FSLockFactory.cpp | 6 +- src/core/store/FileSwitchDirectory.cpp | 32 +- src/core/store/IndexInput.cpp | 32 +- src/core/store/IndexOutput.cpp | 24 +- src/core/store/Lock.cpp | 8 +- src/core/store/LockFactory.cpp | 6 +- src/core/store/MMapDirectory.cpp | 26 +- src/core/store/NativeFSLockFactory.cpp | 68 +- src/core/store/NoLockFactory.cpp | 20 +- src/core/store/RAMDirectory.cpp | 32 +- src/core/store/RAMFile.cpp | 26 +- src/core/store/RAMInputStream.cpp | 30 +- src/core/store/RAMOutputStream.cpp | 38 +- src/core/store/SimpleFSDirectory.cpp | 86 +- src/core/store/SimpleFSLockFactory.cpp | 22 +- src/core/store/SingleInstanceLockFactory.cpp | 22 +- src/core/util/Attribute.cpp | 8 +- src/core/util/AttributeSource.cpp | 74 +- src/core/util/Base64.cpp | 22 +- src/core/util/BitSet.cpp | 74 +- src/core/util/BitUtil.cpp | 254 ++-- src/core/util/BitVector.cpp | 44 +- src/core/util/BufferedReader.cpp | 26 +- src/core/util/CharFolder.cpp | 10 +- src/core/util/Collator.cpp | 6 +- src/core/util/Constants.cpp | 2 +- src/core/util/CycleCheck.cpp | 2 +- src/core/util/DocIdBitSet.cpp | 28 +- src/core/util/FieldCacheSanityChecker.cpp | 98 +- src/core/util/FileReader.cpp | 18 +- src/core/util/FileUtils.cpp | 34 +- src/core/util/InfoStream.cpp | 18 +- src/core/util/InputStreamReader.cpp | 14 +- src/core/util/LuceneAllocator.cpp | 2 +- src/core/util/LuceneException.cpp | 12 +- src/core/util/LuceneObject.cpp | 14 +- src/core/util/LuceneSignal.cpp | 10 +- src/core/util/LuceneSync.cpp | 14 +- src/core/util/LuceneThread.cpp | 2 +- src/core/util/MiscUtils.cpp | 44 +- src/core/util/NumericUtils.cpp | 66 +- src/core/util/OpenBitSet.cpp | 2 +- src/core/util/OpenBitSetDISI.cpp | 14 +- src/core/util/OpenBitSetIterator.cpp | 66 +- src/core/util/Random.cpp | 14 +- src/core/util/Reader.cpp | 16 +- src/core/util/ReaderUtil.cpp | 10 +- src/core/util/ScorerDocQueue.cpp | 42 +- src/core/util/SmallDouble.cpp | 6 +- src/core/util/SortedVIntList.cpp | 48 +- src/core/util/StringReader.cpp | 14 +- src/core/util/StringUtils.cpp | 52 +- src/core/util/Synchronize.cpp | 20 +- src/core/util/TestPoint.cpp | 18 +- src/core/util/ThreadPool.cpp | 10 +- src/core/util/UTF8Stream.cpp | 2 +- src/core/util/UnicodeUtils.cpp | 26 +- src/core/util/unicode/guniprop.cpp | 82 +- src/core/util/unicode/guniprop.h | 8 +- src/demo/deletefiles/main.cpp | 2 +- src/demo/indexfiles/main.cpp | 14 +- src/demo/searchfiles/main.cpp | 18 +- src/test/analysis/AnalyzersTest.cpp | 2 +- src/test/analysis/BaseTokenStreamFixture.cpp | 2 +- src/test/analysis/CachingTokenFilterTest.cpp | 2 +- src/test/analysis/CharFilterTest.cpp | 2 +- src/test/analysis/KeywordAnalyzerTest.cpp | 2 +- src/test/analysis/LengthFilterTest.cpp | 2 +- src/test/analysis/MappingCharFilterTest.cpp | 2 +- src/test/analysis/NumericTokenStreamTest.cpp | 2 +- .../analysis/PerFieldAnalzyerWrapperTest.cpp | 2 +- src/test/analysis/StopAnalyzerTest.cpp | 2 +- src/test/analysis/StopFilterTest.cpp | 2 +- src/test/analysis/TeeSinkTokenFilterTest.cpp | 2 +- src/test/analysis/TokenTest.cpp | 2 +- .../standard/StandardAnalyzerTest.cpp | 2 +- .../tokenattributes/SimpleAttributeTest.cpp | 2 +- .../tokenattributes/TermAttributeTest.cpp | 2 +- .../common/analysis/ar/ArabicAnalyzerTest.cpp | 2 +- .../ar/ArabicNormalizationFilterTest.cpp | 2 +- .../analysis/ar/ArabicStemFilterTest.cpp | 2 +- .../analysis/br/BrazilianStemmerTest.cpp | 2 +- .../common/analysis/cjk/CJKTokenizerTest.cpp | 2 +- .../analysis/cn/ChineseTokenizerTest.cpp | 2 +- .../common/analysis/cz/CzechAnalyzerTest.cpp | 2 +- .../analysis/de/GermanStemFilterTest.cpp | 2 +- .../common/analysis/el/GreekAnalyzerTest.cpp | 2 +- .../analysis/fa/PersianAnalyzerTest.cpp | 2 +- .../fa/PersianNormalizationFilterTest.cpp | 2 +- .../common/analysis/fr/ElisionTest.cpp | 2 +- .../common/analysis/fr/FrenchAnalyzerTest.cpp | 2 +- .../common/analysis/nl/DutchStemmerTest.cpp | 2 +- .../reverse/ReverseStringFilterTest.cpp | 2 +- .../analysis/ru/RussianAnalyzerTest.cpp | 2 +- .../common/analysis/ru/RussianStemTest.cpp | 2 +- .../contrib/highlighter/HighlighterTest.cpp | 2 +- src/test/contrib/memory/MemoryIndexTest.cpp | 2 +- src/test/contrib/snowball/SnowballTest.cpp | 2 +- src/test/document/BinaryDocumentTest.cpp | 2 +- src/test/document/DateFieldTest.cpp | 2 +- src/test/document/DateToolsTest.cpp | 2 +- src/test/document/DocumentTest.cpp | 2 +- src/test/document/NumberToolsTest.cpp | 2 +- src/test/include/BaseTestRangeFilterFixture.h | 20 +- src/test/include/BaseTokenStreamFixture.h | 24 +- src/test/include/CheckHits.h | 32 +- src/test/include/DocHelper.h | 44 +- src/test/include/ExplanationsFixture.h | 14 +- src/test/include/FunctionFixture.h | 18 +- src/test/include/LuceneGlobalFixture.h | 2 +- src/test/include/LuceneTestFixture.h | 2 +- src/test/include/MockFSDirectory.h | 14 +- src/test/include/MockFilter.h | 10 +- src/test/include/MockIndexInput.h | 10 +- src/test/include/MockLock.h | 8 +- src/test/include/MockLockFactory.h | 8 +- src/test/include/MockRAMDirectory.h | 74 +- src/test/include/MockRAMInputStream.h | 12 +- src/test/include/MockRAMOutputStream.h | 10 +- src/test/include/PayloadHelper.h | 6 +- src/test/include/QueryUtils.h | 40 +- src/test/include/TestInc.h | 2 +- src/test/include/TestUtils.h | 20 +- src/test/include/test_lucene.h | 2 +- src/test/index/AddIndexesNoOptimizeTest.cpp | 2 +- src/test/index/AtomicUpdateTest.cpp | 2 +- src/test/index/BackwardsCompatibilityTest.cpp | 2 +- src/test/index/ByteSlicesTest.cpp | 2 +- src/test/index/CheckIndexTest.cpp | 2 +- src/test/index/CompoundFileTest.cpp | 2 +- .../index/ConcurrentMergeSchedulerTest.cpp | 2 +- src/test/index/CrashTest.cpp | 2 +- src/test/index/DeletionPolicyTest.cpp | 2 +- src/test/index/DirectoryReaderTest.cpp | 2 +- src/test/index/DocHelper.cpp | 58 +- src/test/index/DocTest.cpp | 2 +- src/test/index/DocumentWriterTest.cpp | 2 +- src/test/index/FieldInfosTest.cpp | 2 +- src/test/index/FieldsReaderTest.cpp | 2 +- src/test/index/FilterIndexReaderTest.cpp | 2 +- src/test/index/IndexCommitTest.cpp | 2 +- src/test/index/IndexFileDeleterTest.cpp | 2 +- src/test/index/IndexInputTest.cpp | 2 +- src/test/index/IndexReaderCloneNormsTest.cpp | 2 +- src/test/index/IndexReaderCloneTest.cpp | 2 +- src/test/index/IndexReaderReopenTest.cpp | 2 +- src/test/index/IndexReaderTest.cpp | 2 +- src/test/index/IndexWriterDeleteTest.cpp | 2 +- src/test/index/IndexWriterExceptionsTest.cpp | 2 +- src/test/index/IndexWriterLockReleaseTest.cpp | 2 +- src/test/index/IndexWriterMergePolicyTest.cpp | 2 +- src/test/index/IndexWriterMergingTest.cpp | 2 +- src/test/index/IndexWriterReaderTest.cpp | 2 +- src/test/index/IndexWriterTest.cpp | 2 +- src/test/index/LazyBugTest.cpp | 2 +- src/test/index/LazyProxSkippingTest.cpp | 2 +- src/test/index/MockIndexInput.cpp | 12 +- src/test/index/MultiLevelSkipListTest.cpp | 2 +- src/test/index/MultiReaderTest.cpp | 2 +- src/test/index/NRTReaderWithThreadsTest.cpp | 2 +- src/test/index/NormsTest.cpp | 2 +- src/test/index/OmitTfTest.cpp | 2 +- .../index/ParallelReaderEmptyIndexTest.cpp | 2 +- src/test/index/ParallelReaderTest.cpp | 2 +- src/test/index/ParallelTermEnumTest.cpp | 2 +- src/test/index/PayloadsTest.cpp | 2 +- .../PositionBasedTermVectorMapperTest.cpp | 2 +- src/test/index/SegmentMergerTest.cpp | 2 +- src/test/index/SegmentReaderTest.cpp | 2 +- src/test/index/SegmentTermDocsTest.cpp | 2 +- src/test/index/SegmentTermEnumTest.cpp | 2 +- src/test/index/SnapshotDeletionPolicyTest.cpp | 2 +- src/test/index/StressIndexingTest.cpp | 2 +- src/test/index/TermDocsPerfTest.cpp | 2 +- src/test/index/TermTest.cpp | 2 +- src/test/index/TermVectorsReaderTest.cpp | 2 +- src/test/index/ThreadedOptimizeTest.cpp | 2 +- src/test/index/TransactionRollbackTest.cpp | 2 +- src/test/index/TransactionsTest.cpp | 2 +- src/test/index/WordlistLoaderTest.cpp | 2 +- src/test/main/main.cpp | 2 +- src/test/msvc/TestInc.cpp | 2 +- src/test/queryparser/MultiAnalyzerTest.cpp | 2 +- .../queryparser/MultiFieldQueryParserTest.cpp | 2 +- src/test/queryparser/QueryParserTest.cpp | 2 +- .../search/BaseTestRangeFilterFixture.cpp | 18 +- src/test/search/BaseTestRangeFilterTest.cpp | 2 +- src/test/search/Boolean2Test.cpp | 2 +- src/test/search/BooleanMinShouldMatchTest.cpp | 2 +- src/test/search/BooleanOrTest.cpp | 2 +- src/test/search/BooleanPrefixQueryTest.cpp | 2 +- src/test/search/BooleanQueryTest.cpp | 2 +- src/test/search/BooleanScorerTest.cpp | 2 +- src/test/search/CachingSpanFilterTest.cpp | 2 +- src/test/search/CachingWrapperFilterTest.cpp | 2 +- src/test/search/CheckHits.cpp | 2 +- .../ComplexExplanationsOfNonMatchesTest.cpp | 2 +- src/test/search/ComplexExplanationsTest.cpp | 2 +- src/test/search/CustomSearcherSortTest.cpp | 2 +- src/test/search/DateFilterTest.cpp | 2 +- src/test/search/DateSortTest.cpp | 2 +- src/test/search/DisjunctionMaxQueryTest.cpp | 2 +- src/test/search/DocBoostTest.cpp | 2 +- src/test/search/DocIdSetTest.cpp | 2 +- src/test/search/ElevationComparatorTest.cpp | 2 +- src/test/search/ExplanationsFixture.cpp | 52 +- src/test/search/FieldCacheRangeFilterTest.cpp | 2 +- src/test/search/FieldCacheTermsFilterTest.cpp | 2 +- src/test/search/FieldCacheTest.cpp | 2 +- src/test/search/FilteredQueryTest.cpp | 2 +- src/test/search/FilteredSearchTest.cpp | 2 +- src/test/search/FuzzyQueryTest.cpp | 2 +- src/test/search/MatchAllDocsQueryTest.cpp | 2 +- src/test/search/MockFilter.cpp | 10 +- src/test/search/MultiPhraseQueryTest.cpp | 2 +- src/test/search/MultiSearcherRankingTest.cpp | 2 +- src/test/search/MultiSearcherTest.cpp | 2 +- .../search/MultiTermConstantScoreTest.cpp | 2 +- .../search/MultiThreadTermVectorsTest.cpp | 2 +- .../MultiValuedNumericRangeQueryTest.cpp | 2 +- src/test/search/NotTest.cpp | 2 +- src/test/search/NumericRangeQuery32Test.cpp | 2 +- src/test/search/NumericRangeQuery64Test.cpp | 2 +- src/test/search/ParallelMultiSearcherTest.cpp | 2 +- src/test/search/PhrasePrefixQueryTest.cpp | 2 +- src/test/search/PhraseQueryTest.cpp | 2 +- src/test/search/PositionIncrementTest.cpp | 2 +- .../PositiveScoresOnlyCollectorTest.cpp | 2 +- src/test/search/PrefixFilterTest.cpp | 2 +- src/test/search/PrefixInBooleanQueryTest.cpp | 2 +- src/test/search/PrefixQueryTest.cpp | 2 +- src/test/search/QueryTermVectorTest.cpp | 2 +- src/test/search/QueryUtils.cpp | 2 +- src/test/search/QueryWrapperFilterTest.cpp | 2 +- .../search/ScoreCachingWrappingScorerTest.cpp | 2 +- src/test/search/ScorerPerfTest.cpp | 2 +- src/test/search/SearchForDuplicatesTest.cpp | 2 +- src/test/search/SearchTest.cpp | 2 +- src/test/search/SetNormTest.cpp | 2 +- src/test/search/SimilarityTest.cpp | 2 +- .../SimpleExplanationsOfNonMatchesTest.cpp | 2 +- src/test/search/SimpleExplanationsTest.cpp | 2 +- src/test/search/SloppyPhraseQueryTest.cpp | 2 +- src/test/search/SortTest.cpp | 2 +- src/test/search/SpanQueryFilterTest.cpp | 2 +- src/test/search/TermRangeFilterTest.cpp | 2 +- src/test/search/TermRangeQueryTest.cpp | 2 +- src/test/search/TermScorerTest.cpp | 2 +- src/test/search/TermVectorsTest.cpp | 2 +- src/test/search/ThreadSafeTest.cpp | 2 +- src/test/search/TimeLimitingCollectorTest.cpp | 2 +- src/test/search/TopDocsCollectorTest.cpp | 2 +- src/test/search/TopScoreDocCollectorTest.cpp | 2 +- src/test/search/WildcardTest.cpp | 2 +- .../search/function/CustomScoreQueryTest.cpp | 2 +- src/test/search/function/DocValuesTest.cpp | 2 +- .../search/function/FieldScoreQueryTest.cpp | 2 +- src/test/search/function/FunctionFixture.cpp | 28 +- src/test/search/function/OrdValuesTest.cpp | 2 +- src/test/search/payloads/PayloadHelper.cpp | 22 +- .../search/payloads/PayloadNearQueryTest.cpp | 2 +- .../search/payloads/PayloadTermQueryTest.cpp | 2 +- src/test/search/spans/BasicSpansTest.cpp | 2 +- .../spans/FieldMaskingSpanQueryTest.cpp | 2 +- .../search/spans/NearSpansOrderedTest.cpp | 2 +- src/test/search/spans/PayloadSpansTest.cpp | 2 +- .../search/spans/SpanExplanationsTest.cpp | 2 +- src/test/search/spans/SpansAdvanced2Test.cpp | 2 +- src/test/search/spans/SpansAdvancedTest.cpp | 2 +- src/test/search/spans/SpansTest.cpp | 2 +- src/test/store/BufferedIndexInputTest.cpp | 2 +- src/test/store/BufferedIndexOutputTest.cpp | 2 +- src/test/store/DirectoryTest.cpp | 2 +- src/test/store/FileSwitchDirectoryTest.cpp | 2 +- src/test/store/IndexOutputTest.cpp | 2 +- src/test/store/LockFactoryTest.cpp | 2 +- src/test/store/MMapDirectoryTest.cpp | 2 +- src/test/store/MockFSDirectory.cpp | 26 +- src/test/store/MockLock.cpp | 12 +- src/test/store/MockLockFactory.cpp | 10 +- src/test/store/MockRAMDirectory.cpp | 76 +- src/test/store/MockRAMInputStream.cpp | 10 +- src/test/store/MockRAMOutputStream.cpp | 24 +- src/test/store/RAMDirectoryTest.cpp | 2 +- src/test/util/AttributeSourceTest.cpp | 2 +- src/test/util/Base64Test.cpp | 2 +- src/test/util/BitVectorTest.cpp | 2 +- src/test/util/BufferedReaderTest.cpp | 2 +- src/test/util/CloseableThreadLocalTest.cpp | 2 +- src/test/util/CompressionToolsTest.cpp | 2 +- src/test/util/FieldCacheSanityCheckerTest.cpp | 2 +- src/test/util/FileReaderTest.cpp | 2 +- src/test/util/FileUtilsTest.cpp | 2 +- src/test/util/InputStreamReaderTest.cpp | 2 +- src/test/util/LuceneGlobalFixture.cpp | 2 +- src/test/util/LuceneTestFixture.cpp | 2 +- src/test/util/NumericUtilsTest.cpp | 2 +- src/test/util/OpenBitSetTest.cpp | 2 +- src/test/util/PriorityQueueTest.cpp | 2 +- src/test/util/SimpleLRUCacheTest.cpp | 2 +- src/test/util/SortedVIntListTest.cpp | 2 +- src/test/util/StringReaderTest.cpp | 2 +- src/test/util/StringUtilsTest.cpp | 2 +- src/test/util/TestUtils.cpp | 24 +- src/test/util/VersionTest.cpp | 2 +- 1201 files changed, 18074 insertions(+), 18074 deletions(-) diff --git a/include/ASCIIFoldingFilter.h b/include/ASCIIFoldingFilter.h index f3ece736..109449dd 100644 --- a/include/ASCIIFoldingFilter.h +++ b/include/ASCIIFoldingFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,10 +11,10 @@ namespace Lucene { - /// This class converts alphabetic, numeric, and symbolic Unicode characters which are not in the first 127 ASCII + /// This class converts alphabetic, numeric, and symbolic Unicode characters which are not in the first 127 ASCII /// characters (the "Basic Latin" Unicode block) into their ASCII equivalents, if one exists. /// - /// Characters from the following Unicode blocks are converted; however, only those characters with reasonable ASCII + /// Characters from the following Unicode blocks are converted; however, only those characters with reasonable ASCII /// alternatives are converted: /// /// C1 Controls and Latin-1 Supplement: http://www.unicode.org/charts/PDF/U0080.pdf @@ -36,7 +36,7 @@ namespace Lucene /// /// See: http://en.wikipedia.org/wiki/Latin_characters_in_Unicode /// - /// The set of character conversions supported by this class is a superset of those supported by Lucene's {@link + /// The set of character conversions supported by this class is a superset of those supported by Lucene's {@link /// ISOLatin1AccentFilter} which strips accents from Latin1 characters. For example, 'à' will be replaced by 'a'. /// class LPPAPI ASCIIFoldingFilter : public TokenFilter @@ -44,18 +44,18 @@ namespace Lucene public: ASCIIFoldingFilter(TokenStreamPtr input); virtual ~ASCIIFoldingFilter(); - + LUCENE_CLASS(ASCIIFoldingFilter); - + protected: CharArray output; int32_t outputPos; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); - - /// Converts characters above ASCII to their ASCII equivalents. For example, accents are removed from + + /// Converts characters above ASCII to their ASCII equivalents. For example, accents are removed from /// accented characters. /// @param input The string to fold /// @param length The number of characters in the input string diff --git a/include/AbstractAllTermDocs.h b/include/AbstractAllTermDocs.h index f2662124..b1c672ac 100644 --- a/include/AbstractAllTermDocs.h +++ b/include/AbstractAllTermDocs.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,20 +13,20 @@ namespace Lucene { /// Base class for enumerating all but deleted docs. /// - /// NOTE: this class is meant only to be used internally by Lucene; it's only public so it + /// NOTE: this class is meant only to be used internally by Lucene; it's only public so it /// can be shared across packages. class LPPAPI AbstractAllTermDocs : public TermDocs, public LuceneObject { public: AbstractAllTermDocs(int32_t maxDoc); virtual ~AbstractAllTermDocs(); - + LUCENE_CLASS(AbstractAllTermDocs); - + protected: int32_t maxDoc; int32_t _doc; - + public: virtual void seek(TermPtr term); virtual void seek(TermEnumPtr termEnum); diff --git a/include/AbstractField.h b/include/AbstractField.h index 5cb2649f..35097596 100644 --- a/include/AbstractField.h +++ b/include/AbstractField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,75 +17,75 @@ namespace Lucene /// Specifies whether and how a field should be stored. enum Store { - /// Store the original field value in the index. This is useful for short texts like a document's title - /// which should be displayed with the results. The value is stored in its original form, ie. no analyzer + /// Store the original field value in the index. This is useful for short texts like a document's title + /// which should be displayed with the results. The value is stored in its original form, ie. no analyzer /// is used before it is stored. STORE_YES, - + /// Do not store the field value in the index. STORE_NO }; - + /// Specifies whether and how a field should be indexed. enum Index { - /// Do not index the field value. This field can thus not be searched, but one can still access its + /// Do not index the field value. This field can thus not be searched, but one can still access its /// contents provided it is {@link Field.Store stored}. INDEX_NO, - - /// Index the tokens produced by running the field's value through an Analyzer. This is useful for + + /// Index the tokens produced by running the field's value through an Analyzer. This is useful for /// common text. INDEX_ANALYZED, - - /// Index the field's value without using an Analyzer, so it can be searched. As no analyzer is used - /// the value will be stored as a single term. This is useful for unique Ids like product numbers. + + /// Index the field's value without using an Analyzer, so it can be searched. As no analyzer is used + /// the value will be stored as a single term. This is useful for unique Ids like product numbers. INDEX_NOT_ANALYZED, - - /// Index the field's value without an Analyzer, and also disable the storing of norms. Note that you - /// can also separately enable/disable norms by calling {@link Field#setOmitNorms}. No norms means - /// that index-time field and document boosting and field length normalization are disabled. The benefit - /// is less memory usage as norms take up one byte of RAM per indexed field for every document in the - /// index, during searching. Note that once you index a given field with norms enabled, disabling norms - /// will have no effect. In other words, for this to have the above described effect on a field, all + + /// Index the field's value without an Analyzer, and also disable the storing of norms. Note that you + /// can also separately enable/disable norms by calling {@link Field#setOmitNorms}. No norms means + /// that index-time field and document boosting and field length normalization are disabled. The benefit + /// is less memory usage as norms take up one byte of RAM per indexed field for every document in the + /// index, during searching. Note that once you index a given field with norms enabled, disabling norms + /// will have no effect. In other words, for this to have the above described effect on a field, all /// instances of that field must be indexed with NOT_ANALYZED_NO_NORMS from the beginning. INDEX_NOT_ANALYZED_NO_NORMS, - - /// Index the tokens produced by running the field's value through an Analyzer, and also separately - /// disable the storing of norms. See {@link #NOT_ANALYZED_NO_NORMS} for what norms are and why you + + /// Index the tokens produced by running the field's value through an Analyzer, and also separately + /// disable the storing of norms. See {@link #NOT_ANALYZED_NO_NORMS} for what norms are and why you /// may want to disable them. INDEX_ANALYZED_NO_NORMS }; - + /// Specifies whether and how a field should have term vectors. enum TermVector { /// Do not store term vectors. TERM_VECTOR_NO, - - /// Store the term vectors of each document. A term vector is a list of the document's terms and their + + /// Store the term vectors of each document. A term vector is a list of the document's terms and their /// number of occurrences in that document. TERM_VECTOR_YES, - - /// Store the term vector + token position information + + /// Store the term vector + token position information /// @see #YES TERM_VECTOR_WITH_POSITIONS, - - /// Store the term vector + token offset information + + /// Store the term vector + token offset information /// @see #YES TERM_VECTOR_WITH_OFFSETS, - + /// Store the term vector + token position and offset information /// @see #YES /// @see #WITH_POSITIONS /// @see #WITH_OFFSETS TERM_VECTOR_WITH_POSITIONS_OFFSETS }; - + public: virtual ~AbstractField(); - + LUCENE_CLASS(AbstractField); - + protected: AbstractField(); AbstractField(const String& name, Store store, Index index, TermVector termVector); @@ -102,26 +102,26 @@ namespace Lucene bool lazy; bool omitTermFreqAndPositions; double boost; - + // the data object for all different kind of field values FieldsData fieldsData; - + // pre-analyzed tokenStream for indexed fields TokenStreamPtr tokenStream; - + // length/offset for all primitive types int32_t binaryLength; int32_t binaryOffset; - + public: - /// Sets the boost factor hits on this field. This value will be multiplied into the score of all + /// Sets the boost factor hits on this field. This value will be multiplied into the score of all /// hits on this this field of this document. /// - /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. - /// If a document has multiple fields with the same name, all such values are multiplied together. + /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. + /// If a document has multiple fields with the same name, all such values are multiplied together. /// This product is then used to compute the norm factor for the field. By default, in the {@link - /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the - /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} + /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the + /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} /// before it is stored in the index. One should attempt to ensure that this product does not overflow /// the range of that encoding. /// @@ -129,93 +129,93 @@ namespace Lucene /// @see Similarity#computeNorm(String, FieldInvertState) /// @see Similarity#encodeNorm(double) virtual void setBoost(double boost); - + /// Returns the boost factor for hits for this field. /// /// The default value is 1.0. /// - /// Note: this value is not stored directly with the document in the index. Documents returned from - /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value + /// Note: this value is not stored directly with the document in the index. Documents returned from + /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value /// present as when this field was indexed. virtual double getBoost(); - + /// Returns the name of the field as an interned string. For example "date", "title", "body", ... virtual String name(); - - /// True if the value of the field is to be stored in the index for return with search hits. It is an + + /// True if the value of the field is to be stored in the index for return with search hits. It is an /// error for this to be true if a field is Reader-valued. virtual bool isStored(); - + /// True if the value of the field is to be indexed, so that it may be searched on. virtual bool isIndexed(); - - /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields + + /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields /// are indexed as a single word and may not be Reader-valued. virtual bool isTokenized(); - - /// True if the term or terms used to index this field are stored as a term vector, available from - /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the + + /// True if the term or terms used to index this field are stored as a term vector, available from + /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the /// original content of the field, only to terms used to index it. If the original content must be /// preserved, use the stored attribute instead. virtual bool isTermVectorStored(); - - /// True if terms are stored as term vector together with their offsets (start and end position in + + /// True if terms are stored as term vector together with their offsets (start and end position in /// source text). virtual bool isStoreOffsetWithTermVector(); - + /// True if terms are stored as term vector together with their token positions. virtual bool isStorePositionWithTermVector(); - + /// True if the value of the field is stored as binary. virtual bool isBinary(); - - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. /// @return reference to the Field value as byte[]. virtual ByteArray getBinaryValue(); - - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. /// @return reference to the Field value as byte[]. virtual ByteArray getBinaryValue(ByteArray result); - - /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is + + /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is /// undefined. /// @return length of byte[] segment that represents this Field value. virtual int32_t getBinaryLength(); - - /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is + + /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is /// undefined. /// @return index of the first character in byte[] segment that represents this Field value. virtual int32_t getBinaryOffset(); - + /// True if norms are omitted for this indexed field. virtual bool getOmitNorms(); - + /// @see #setOmitTermFreqAndPositions virtual bool getOmitTermFreqAndPositions(); - + /// If set, omit normalization factors associated with this indexed field. /// This effectively disables indexing boosts and length normalization for this field. virtual void setOmitNorms(bool omitNorms); - + /// If set, omit term freq, positions and payloads from postings for this field. /// - /// NOTE: While this option reduces storage space required in the index, it also means any query requiring - /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail + /// NOTE: While this option reduces storage space required in the index, it also means any query requiring + /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail /// to find results. virtual void setOmitTermFreqAndPositions(bool omitTermFreqAndPositions); - - /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field - /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} + + /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field + /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} /// is only valid as long as the {@link IndexReader} that retrieved the {@link Document} is still open. /// /// @return true if this field can be loaded lazily virtual bool isLazy(); - + /// Prints a Field for human consumption. virtual String toString(); - + protected: void setStoreTermVector(TermVector termVector); }; diff --git a/include/AllTermDocs.h b/include/AllTermDocs.h index 4b865806..d34ef9b3 100644 --- a/include/AllTermDocs.h +++ b/include/AllTermDocs.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,12 +16,12 @@ namespace Lucene public: AllTermDocs(SegmentReaderPtr parent); virtual ~AllTermDocs(); - + LUCENE_CLASS(AllTermDocs); - + protected: BitVectorWeakPtr _deletedDocs; - + public: virtual bool isDeleted(int32_t doc); }; diff --git a/include/Analyzer.h b/include/Analyzer.h index 2b6d1c15..909fdf2a 100644 --- a/include/Analyzer.h +++ b/include/Analyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,57 +11,57 @@ namespace Lucene { - /// An Analyzer builds TokenStreams, which analyze text. It thus represents a policy for extracting index terms + /// An Analyzer builds TokenStreams, which analyze text. It thus represents a policy for extracting index terms /// from text. /// - /// Typical implementations first build a Tokenizer, which breaks the stream of characters from the Reader into + /// Typical implementations first build a Tokenizer, which breaks the stream of characters from the Reader into /// raw Tokens. One or more TokenFilters may then be applied to the output of the Tokenizer. class LPPAPI Analyzer : public LuceneObject { public: virtual ~Analyzer(); LUCENE_CLASS(Analyzer); - + protected: CloseableThreadLocal tokenStreams; - + public: - /// Creates a TokenStream which tokenizes all the text in the provided Reader. Must be able to handle null + /// Creates a TokenStream which tokenizes all the text in the provided Reader. Must be able to handle null /// field name for backward compatibility. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) = 0; - + /// Creates a TokenStream that is allowed to be re-used from the previous time that the same thread called - /// this method. Callers that do not need to use more than one TokenStream at the same time from this analyzer + /// this method. Callers that do not need to use more than one TokenStream at the same time from this analyzer /// should use this method for better performance. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); - - /// Invoked before indexing a Fieldable instance if terms have already been added to that field. This allows - /// custom analyzers to place an automatic position increment gap between Fieldable instances using the same - /// field name. The default value position increment gap is 0. With a 0 position increment gap and the typical - /// default token position increment of 1, all terms in a field, including across Fieldable instances, are in + + /// Invoked before indexing a Fieldable instance if terms have already been added to that field. This allows + /// custom analyzers to place an automatic position increment gap between Fieldable instances using the same + /// field name. The default value position increment gap is 0. With a 0 position increment gap and the typical + /// default token position increment of 1, all terms in a field, including across Fieldable instances, are in /// successive positions, allowing exact PhraseQuery matches, for instance, across Fieldable instance boundaries. /// /// @param fieldName Fieldable name being indexed. /// @return position increment gap, added to the next token emitted from {@link #tokenStream(String,Reader)} virtual int32_t getPositionIncrementGap(const String& fieldName); - + /// Just like {@link #getPositionIncrementGap}, except for Token offsets instead. By default this returns 1 for - /// tokenized fields and, as if the fields were joined with an extra space character, and 0 for un-tokenized + /// tokenized fields and, as if the fields were joined with an extra space character, and 0 for un-tokenized /// fields. This method is only called if the field produced at least one token for indexing. /// /// @param field the field just indexed /// @return offset gap, added to the next token emitted from {@link #tokenStream(String,Reader)} virtual int32_t getOffsetGap(FieldablePtr field); - + /// Frees persistent resources used by this Analyzer virtual void close(); - + protected: /// Used by Analyzers that implement reusableTokenStream to retrieve previously saved TokenStreams for re-use /// by the same thread. virtual LuceneObjectPtr getPreviousTokenStream(); - - /// Used by Analyzers that implement reusableTokenStream to save a TokenStream for later re-use by the + + /// Used by Analyzers that implement reusableTokenStream to save a TokenStream for later re-use by the /// same thread. virtual void setPreviousTokenStream(LuceneObjectPtr stream); }; diff --git a/include/Array.h b/include/Array.h index 46f38aa3..5bf83d2e 100644 --- a/include/Array.h +++ b/include/Array.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - template + template class ArrayData { public: @@ -21,16 +21,16 @@ namespace Lucene data = NULL; resize(size); } - + ~ArrayData() { resize(0); } - + public: TYPE* data; int32_t size; - + public: void resize(int32_t size) { @@ -46,7 +46,7 @@ namespace Lucene this->size = size; } }; - + /// Utility template class to handle sharable arrays of simple data types template class Array @@ -59,11 +59,11 @@ namespace Lucene { array = NULL; } - + protected: boost::shared_ptr container; array_type* array; - + public: static this_type newInstance(int32_t size) { @@ -72,12 +72,12 @@ namespace Lucene instance.array = instance.container.get(); return instance; } - + void reset() { resize(0); } - + void resize(int32_t size) { if (size == 0) @@ -88,56 +88,56 @@ namespace Lucene container->resize(size); array = container.get(); } - + TYPE* get() const { return array->data; } - + int32_t size() const { return array->size; } - + bool equals(const this_type& other) const { if (array->size != other.array->size) return false; return (std::memcmp(array->data, other.array->data, array->size) == 0); } - + int32_t hashCode() const { return (int32_t)(int64_t)array; } - + TYPE& operator[] (int32_t i) const { BOOST_ASSERT(i >= 0 && i < array->size); return array->data[i]; } - + operator bool () const { return container.get() != NULL; } - + bool operator! () const { return !container; } - + bool operator== (const Array& other) { return (container == other.container); } - + bool operator!= (const Array& other) { return (container != other.container); } }; - + template inline std::size_t hash_value(const Array& value) { diff --git a/include/Attribute.h b/include/Attribute.h index feed4081..03eb626d 100644 --- a/include/Attribute.h +++ b/include/Attribute.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,19 +13,19 @@ namespace Lucene { /// Base class for Attributes that can be added to a {@link AttributeSource}. /// - /// Attributes are used to add data in a dynamic, yet type-safe way to a source of usually streamed objects, + /// Attributes are used to add data in a dynamic, yet type-safe way to a source of usually streamed objects, /// eg. a {@link TokenStream}. class LPPAPI Attribute : public LuceneObject { public: virtual ~Attribute(); LUCENE_CLASS(Attribute); - + public: - /// Clears the values in this Attribute and resets it to its default value. If this implementation + /// Clears the values in this Attribute and resets it to its default value. If this implementation /// implements more than one Attribute interface it clears all. virtual void clear() = 0; - + /// Subclasses must implement this method and should compute a hashCode similar to this: /// /// int32_t hashCode() @@ -37,16 +37,16 @@ namespace Lucene /// /// see also {@link #equals(Object)} virtual int32_t hashCode() = 0; - + /// All values used for computation of {@link #hashCode()} should be checked here for equality. /// /// see also {@link LuceneObject#equals(Object)} virtual bool equals(LuceneObjectPtr other) = 0; - - /// Copies the values from this Attribute into the passed-in target attribute. The target implementation + + /// Copies the values from this Attribute into the passed-in target attribute. The target implementation /// must support all the Attributes this implementation supports. virtual void copyTo(AttributePtr target) = 0; - + /// Shallow clone. Subclasses must override this if they need to clone any members deeply. /// @param base clone reference - null when called initially, then set in top virtual override. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) = 0; diff --git a/include/AttributeSource.h b/include/AttributeSource.h index 13f716e9..2257053f 100644 --- a/include/AttributeSource.h +++ b/include/AttributeSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,28 +18,28 @@ namespace Lucene public: virtual ~AttributeFactory(); - + LUCENE_CLASS(AttributeFactory); - + public: /// returns an {@link Attribute}. virtual AttributePtr createAttributeInstance(const String& className); - + template AttributePtr createInstance(const String& className) { AttributePtr attrImpl = createAttributeInstance(className); return attrImpl ? attrImpl : newLucene(); } - - /// This is the default factory that creates {@link Attribute}s using the class name of the supplied + + /// This is the default factory that creates {@link Attribute}s using the class name of the supplied /// {@link Attribute} interface class by appending Impl to it. - static AttributeFactoryPtr DEFAULT_ATTRIBUTE_FACTORY(); + static AttributeFactoryPtr DEFAULT_ATTRIBUTE_FACTORY(); }; - - /// An AttributeSource contains a list of different {@link Attribute}s, and methods to add and get them. + + /// An AttributeSource contains a list of different {@link Attribute}s, and methods to add and get them. /// There can only be a single instance of an attribute in the same AttributeSource instance. This is ensured - /// by passing in the actual type of the Attribute (Class) to the {@link #addAttribute(Class)}, + /// by passing in the actual type of the Attribute (Class) to the {@link #addAttribute(Class)}, /// which then checks if an instance of that type is already present. If yes, it returns the instance, otherwise /// it creates a new instance and returns it. class LPPAPI AttributeSource : public LuceneObject @@ -47,33 +47,33 @@ namespace Lucene public: /// An AttributeSource using the default attribute factory {@link DefaultAttributeFactory}. AttributeSource(); - + /// An AttributeSource that uses the same attributes as the supplied one. AttributeSource(AttributeSourcePtr input); - - /// An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} + + /// An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} /// instances. - AttributeSource(AttributeFactoryPtr factory); - + AttributeSource(AttributeFactoryPtr factory); + virtual ~AttributeSource(); - + LUCENE_CLASS(AttributeSource); - + protected: AttributeFactoryPtr factory; MapStringAttribute attributes; AttributeSourceStatePtr currentState; - + public: /// returns the used AttributeFactory. AttributeFactoryPtr getAttributeFactory(); - - /// This method first checks if an instance of that class is already in this AttributeSource and returns it. + + /// This method first checks if an instance of that class is already in this AttributeSource and returns it. /// Otherwise a new instance is created, added to this AttributeSource and returned. template boost::shared_ptr addAttribute() { - String className(ATTR::_getClassName()); + String className(ATTR::_getClassName()); boost::shared_ptr attrImpl(boost::dynamic_pointer_cast(getAttribute(className))); if (!attrImpl) { @@ -84,20 +84,20 @@ namespace Lucene } return attrImpl; } - + /// Adds a custom Attribute instance. void addAttribute(const String& className, AttributePtr attrImpl); - + /// Returns true if this AttributeSource has any attributes. bool hasAttributes(); - + /// Returns true, if this AttributeSource contains the passed-in Attribute. template bool hasAttribute() { return getAttribute(ATTR::_getClassName()).get() != NULL; } - + /// Returns the instance of the passed in Attribute contained in this AttributeSource. template boost::shared_ptr getAttribute() @@ -108,66 +108,66 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"This AttributeSource does not have the attribute '" + className + L"'.")); return attr; } - - /// Resets all Attributes in this AttributeSource by calling {@link AttributeImpl#clear()} on each Attribute + + /// Resets all Attributes in this AttributeSource by calling {@link AttributeImpl#clear()} on each Attribute /// implementation. void clearAttributes(); - - /// Captures the state of all Attributes. The return value can be passed to {@link #restoreState} to restore + + /// Captures the state of all Attributes. The return value can be passed to {@link #restoreState} to restore /// the state of this or another AttributeSource. AttributeSourceStatePtr captureState(); - - /// Restores this state by copying the values of all attribute implementations that this state contains into - /// the attributes implementations of the targetStream. The targetStream must contain a corresponding instance - /// for each argument contained in this state (eg. it is not possible to restore the state of an AttributeSource + + /// Restores this state by copying the values of all attribute implementations that this state contains into + /// the attributes implementations of the targetStream. The targetStream must contain a corresponding instance + /// for each argument contained in this state (eg. it is not possible to restore the state of an AttributeSource /// containing a TermAttribute into a AttributeSource using a Token instance as implementation). /// - /// Note that this method does not affect attributes of the targetStream that are not contained in this state. + /// Note that this method does not affect attributes of the targetStream that are not contained in this state. /// In other words, if for example the targetStream contains an OffsetAttribute, but this state doesn't, then - /// the value of the OffsetAttribute remains unchanged. It might be desirable to reset its value to the default, - /// in which case the caller should first call {@link TokenStream#clearAttributes()} on the targetStream. + /// the value of the OffsetAttribute remains unchanged. It might be desirable to reset its value to the default, + /// in which case the caller should first call {@link TokenStream#clearAttributes()} on the targetStream. void restoreState(AttributeSourceStatePtr state); - + /// Return hash code for this object. virtual int32_t hashCode(); - + /// Return whether two objects are equal virtual bool equals(LuceneObjectPtr other); - + /// Returns a string representation of the object virtual String toString(); - - /// Performs a clone of all {@link AttributeImpl} instances returned in a new AttributeSource instance. This - /// method can be used to eg. create another TokenStream with exactly the same attributes (using {@link + + /// Performs a clone of all {@link AttributeImpl} instances returned in a new AttributeSource instance. This + /// method can be used to eg. create another TokenStream with exactly the same attributes (using {@link /// #AttributeSource(AttributeSource)}) AttributeSourcePtr cloneAttributes(); - + /// Return a vector of attributes based on currentState. Collection getAttributes(); - + protected: /// The caller must pass in a className value. - /// This method checks if an instance of that class is already in this AttributeSource and returns it. + /// This method checks if an instance of that class is already in this AttributeSource and returns it. AttributePtr getAttribute(const String& className); - + /// Returns true, if this AttributeSource contains the passed-in Attribute. bool hasAttribute(const String& className); - + void computeCurrentState(); }; - + class LPPAPI DefaultAttributeFactory : public AttributeFactory { public: virtual ~DefaultAttributeFactory(); - + LUCENE_CLASS(DefaultAttributeFactory); - + public: /// returns an {@link Attribute}. virtual AttributePtr createAttributeInstance(const String& className); }; - + /// This class holds the state of an AttributeSource. /// @see #captureState /// @see #restoreState @@ -175,16 +175,16 @@ namespace Lucene { public: virtual ~AttributeSourceState(); - + LUCENE_CLASS(AttributeSourceState); - + protected: AttributePtr attribute; AttributeSourceStatePtr next; - + public: virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + friend class AttributeSource; }; } diff --git a/include/AveragePayloadFunction.h b/include/AveragePayloadFunction.h index 2424abcd..a5e80705 100644 --- a/include/AveragePayloadFunction.h +++ b/include/AveragePayloadFunction.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,15 +13,15 @@ namespace Lucene { /// Calculate the final score as the average score of all payloads seen. /// - /// Is thread safe and completely reusable. + /// Is thread safe and completely reusable. class LPPAPI AveragePayloadFunction : public PayloadFunction { public: virtual ~AveragePayloadFunction(); LUCENE_CLASS(AveragePayloadFunction); - + public: - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, double currentScore, double currentPayloadScore); virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); virtual int32_t hashCode(); diff --git a/include/Base64.h b/include/Base64.h index 72a6e0ef..36a8e5a0 100644 --- a/include/Base64.h +++ b/include/Base64.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,15 +16,15 @@ namespace Lucene public: virtual ~Base64(); LUCENE_CLASS(Base64); - + protected: static const String BASE64_CHARS; - + public: static String encode(ByteArray bytes); static String encode(const uint8_t* bytes, int32_t length); static ByteArray decode(const String& str); - + protected: static bool isBase64(wchar_t ch); }; diff --git a/include/BaseCharFilter.h b/include/BaseCharFilter.h index ddbb2546..bd50179b 100644 --- a/include/BaseCharFilter.h +++ b/include/BaseCharFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,25 +11,25 @@ namespace Lucene { - /// Base utility class for implementing a {@link CharFilter}. You subclass this, and then record mappings by + /// Base utility class for implementing a {@link CharFilter}. You subclass this, and then record mappings by /// calling {@link #addOffCorrectMap}, and then invoke the correct method to correct an offset. class LPPAPI BaseCharFilter : public CharFilter { public: BaseCharFilter(CharStreamPtr in); virtual ~BaseCharFilter(); - + LUCENE_CLASS(BaseCharFilter); - + protected: IntArray offsets; IntArray diffs; int32_t size; - + protected: /// Retrieve the corrected offset. virtual int32_t correct(int32_t currentOff); - + int32_t getLastCumulativeDiff(); void addOffCorrectMap(int32_t off, int32_t cumulativeDiff); }; diff --git a/include/BitSet.h b/include/BitSet.h index c7c72f15..2e565f5c 100644 --- a/include/BitSet.h +++ b/include/BitSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/BitUtil.h b/include/BitUtil.h index 6fde2cc3..69a5149d 100644 --- a/include/BitUtil.h +++ b/include/BitUtil.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,60 +15,60 @@ namespace Lucene class LPPAPI BitUtil : public LuceneObject { public: - virtual ~BitUtil(); + virtual ~BitUtil(); LUCENE_CLASS(BitUtil); - + public: /// Table of number of trailing zeros in a byte - static const uint8_t ntzTable[]; - + static const uint8_t ntzTable[]; + public: /// Returns the number of bits set in the long static int32_t pop(int64_t x); - + /// Returns the number of set bits in an array of longs. static int64_t pop_array(const int64_t* A, int32_t wordOffset, int32_t numWords); - + /// Returns the popcount or cardinality of the two sets after an intersection. Neither array is modified. static int64_t pop_intersect(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - + /// Returns the popcount or cardinality of the union of two sets. Neither array is modified. static int64_t pop_union(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - + /// Returns the popcount or cardinality of A & ~B. Neither array is modified. static int64_t pop_andnot(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - + /// Returns the popcount or cardinality of A ^ B. Neither array is modified. static int64_t pop_xor(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - + /// Returns number of trailing zeros in a 64 bit long value. static int32_t ntz(int64_t val); - + /// Returns number of trailing zeros in a 32 bit int value. static int32_t ntz(int32_t val); - + /// Returns 0 based index of first set bit (only works for x!=0) /// This is an alternate implementation of ntz() static int32_t ntz2(int64_t x); - + /// Returns 0 based index of first set bit. /// This is an alternate implementation of ntz() static int32_t ntz3(int64_t x); - + /// Returns true if v is a power of two or zero. static bool isPowerOfTwo(int32_t v); - + /// Returns true if v is a power of two or zero. static bool isPowerOfTwo(int64_t v); - + /// Returns the next highest power of two, or the current value if it's already a power of two or zero. static int32_t nextHighestPowerOfTwo(int32_t v); - + /// Returns the next highest power of two, or the current value if it's already a power of two or zero. static int64_t nextHighestPowerOfTwo(int64_t v); - + protected: - inline static void CSA(int64_t& h, int64_t& l, int64_t a, int64_t b, int64_t c); + inline static void CSA(int64_t& h, int64_t& l, int64_t a, int64_t b, int64_t c); }; } diff --git a/include/BitVector.h b/include/BitVector.h index b91d63f4..4e724c4c 100644 --- a/include/BitVector.h +++ b/include/BitVector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,76 +17,76 @@ namespace Lucene public: /// Constructs a vector capable of holding n bits. BitVector(int32_t n = 0); - + BitVector(ByteArray bits, int32_t size); - - /// Constructs a bit vector from the file name in Directory d, + + /// Constructs a bit vector from the file name in Directory d, /// as written by the {@link #write} method. BitVector(DirectoryPtr d, const String& name); - + virtual ~BitVector(); - + LUCENE_CLASS(BitVector); - + protected: ByteArray bits; int32_t _size; int32_t _count; - + static const uint8_t BYTE_COUNTS[]; // table of bits/byte - + public: /// Clone this vector virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Sets the value of bit to one. void set(int32_t bit); - + /// Sets the value of bit to true, and returns true if bit was already set. bool getAndSet(int32_t bit); - + /// Sets the value of bit to zero. void clear(int32_t bit); - + /// Returns true if bit is one and false if it is zero. bool get(int32_t bit); - + /// Returns the number of bits in this vector. This is also one greater than /// the number of the largest valid bit number. int32_t size(); - + /// Returns the total number of one bits in this vector. This is efficiently - /// computed and cached, so that, if the vector is not changed, no recomputation + /// computed and cached, so that, if the vector is not changed, no recomputation /// is done for repeated calls. int32_t count(); - + /// For testing int32_t getRecomputedCount(); - - /// Writes this vector to the file name in Directory d, in a format that can + + /// Writes this vector to the file name in Directory d, in a format that can /// be read by the constructor {@link #BitVector(DirectoryPtr, const String&)}. void write(DirectoryPtr d, const String& name); - + /// Retrieve a subset of this BitVector. /// @param start starting index, inclusive /// @param end ending index, exclusive /// @return subset BitVectorPtr subset(int32_t start, int32_t end); - + protected: /// Write as a bit set. void writeBits(IndexOutputPtr output); - + /// Write as a d-gaps list. void writeDgaps(IndexOutputPtr output); - - /// Indicates if the bit vector is sparse and should be saved as a d-gaps list, + + /// Indicates if the bit vector is sparse and should be saved as a d-gaps list, /// or dense, and should be saved as a bit set. bool isSparse(); - + /// Read as a bit set. void readBits(IndexInputPtr input); - + /// Read as a d-gaps list. void readDgaps(IndexInputPtr input); }; diff --git a/include/BooleanClause.h b/include/BooleanClause.h index 287af56b..5a16b7e7 100644 --- a/include/BooleanClause.h +++ b/include/BooleanClause.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,39 +19,39 @@ namespace Lucene enum Occur { /// Use this operator for clauses that must appear in the matching documents. - MUST, - - /// Use this operator for clauses that should appear in the matching documents. For a BooleanQuery + MUST, + + /// Use this operator for clauses that should appear in the matching documents. For a BooleanQuery /// with no MUST clauses one or more SHOULD clauses must match a document for the BooleanQuery to match. /// @see BooleanQuery#setMinimumNumberShouldMatch SHOULD, - - /// Use this operator for clauses that must not appear in the matching documents. Note that it is not + + /// Use this operator for clauses that must not appear in the matching documents. Note that it is not /// possible to search for queries that only consist of a MUST_NOT clause. MUST_NOT }; - + public: BooleanClause(QueryPtr query, Occur occur); virtual ~BooleanClause(); - + LUCENE_CLASS(BooleanClause); - + protected: /// The query whose matching documents are combined by the boolean query. QueryPtr query; Occur occur; - + public: Occur getOccur(); void setOccur(Occur occur); - + QueryPtr getQuery(); void setQuery(QueryPtr query); - + bool isProhibited(); bool isRequired(); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual String toString(); diff --git a/include/BooleanQuery.h b/include/BooleanQuery.h index 38112691..8938a6f0 100644 --- a/include/BooleanQuery.h +++ b/include/BooleanQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,88 +13,88 @@ namespace Lucene { - /// A Query that matches documents matching boolean combinations of other queries, eg. {@link TermQuery}s, + /// A Query that matches documents matching boolean combinations of other queries, eg. {@link TermQuery}s, /// {@link PhraseQuery}s or other BooleanQuerys. class LPPAPI BooleanQuery : public Query { public: /// Constructs an empty boolean query. /// - /// {@link Similarity#coord(int32_t, int32_t)} may be disabled in scoring, as appropriate. For example, - /// this score factor does not make sense for most automatically generated queries, like {@link WildcardQuery} + /// {@link Similarity#coord(int32_t, int32_t)} may be disabled in scoring, as appropriate. For example, + /// this score factor does not make sense for most automatically generated queries, like {@link WildcardQuery} /// and {@link FuzzyQuery}. /// /// @param disableCoord disables {@link Similarity#coord(int32_t, int32_t)} in scoring. BooleanQuery(bool disableCoord = false); virtual ~BooleanQuery(); - + LUCENE_CLASS(BooleanQuery); - + protected: static int32_t maxClauseCount; - + Collection clauses; bool disableCoord; int32_t minNrShouldMatch; - + public: using Query::toString; - - /// Return the maximum number of clauses permitted, 1024 by default. Attempts to add more than the permitted + + /// Return the maximum number of clauses permitted, 1024 by default. Attempts to add more than the permitted /// number of clauses cause TooManyClauses to be thrown. /// @see #setMaxClauseCount(int32_t) static int32_t getMaxClauseCount(); - + /// Set the maximum number of clauses permitted per BooleanQuery. Default value is 1024. static void setMaxClauseCount(int32_t maxClauseCount); - + /// Returns true if {@link Similarity#coord(int32_t, int32_t)} is disabled in scoring for this query instance. /// @see #BooleanQuery(bool) bool isCoordDisabled(); - + /// Implement coord disabling. virtual SimilarityPtr getSimilarity(SearcherPtr searcher); - + /// Specifies a minimum number of the optional BooleanClauses which must be satisfied. /// - /// By default no optional clauses are necessary for a match (unless there are no required clauses). If this + /// By default no optional clauses are necessary for a match (unless there are no required clauses). If this /// method is used, then the specified number of clauses is required. /// - /// Use of this method is totally independent of specifying that any specific clauses are required (or prohibited). + /// Use of this method is totally independent of specifying that any specific clauses are required (or prohibited). /// This number will only be compared against the number of matching optional clauses. /// /// @param min the number of optional clauses that must match void setMinimumNumberShouldMatch(int32_t min); - + /// Gets the minimum number of the optional BooleanClauses which must be satisfied. int32_t getMinimumNumberShouldMatch(); - + /// Adds a clause to a boolean query. /// @see #getMaxClauseCount() void add(QueryPtr query, BooleanClause::Occur occur); - + /// Adds a clause to a boolean query. /// @see #getMaxClauseCount() void add(BooleanClausePtr clause); - + /// Returns the set of clauses in this query. Collection getClauses(); - + /// Returns an iterator on the clauses in this query. Collection::iterator begin(); Collection::iterator end(); - + virtual WeightPtr createWeight(SearcherPtr searcher); - + virtual QueryPtr rewrite(IndexReaderPtr reader); - + virtual void extractTerms(SetTerm terms); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual String toString(const String& field); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + friend class BooleanWeight; }; } diff --git a/include/BooleanScorer.h b/include/BooleanScorer.h index 98665d3b..98ac5086 100644 --- a/include/BooleanScorer.h +++ b/include/BooleanScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,28 +13,28 @@ namespace Lucene { /// BooleanScorer uses a ~16k array to score windows of docs. So it scores docs 0-16k first, then docs 16-32k, - /// etc. For each window it iterates through all query terms and accumulates a score in table[doc%16k]. It also - /// stores in the table a bitmask representing which terms contributed to the score. Non-zero scores are chained - /// in a linked list. At the end of scoring each window it then iterates through the linked list and, if the - /// bitmask matches the boolean constraints, collects a hit. For boolean queries with lots of frequent terms this - /// can be much faster, since it does not need to update a priority queue for each posting, instead performing - /// constant-time operations per posting. The only downside is that it results in hits being delivered out-of-order + /// etc. For each window it iterates through all query terms and accumulates a score in table[doc%16k]. It also + /// stores in the table a bitmask representing which terms contributed to the score. Non-zero scores are chained + /// in a linked list. At the end of scoring each window it then iterates through the linked list and, if the + /// bitmask matches the boolean constraints, collects a hit. For boolean queries with lots of frequent terms this + /// can be much faster, since it does not need to update a priority queue for each posting, instead performing + /// constant-time operations per posting. The only downside is that it results in hits being delivered out-of-order /// within the window, which means it cannot be nested within other scorers. But it works well as a top-level scorer. /// /// The new BooleanScorer2 implementation instead works by merging priority queues of postings, albeit with some /// clever tricks. For example, a pure conjunction (all terms required) does not require a priority queue. Instead it /// sorts the posting streams at the start, then repeatedly skips the first to to the last. If the first ever equals /// the last, then there's a hit. When some terms are required and some terms are optional, the conjunction can - /// be evaluated first, then the optional terms can all skip to the match and be added to the score. Thus the + /// be evaluated first, then the optional terms can all skip to the match and be added to the score. Thus the /// conjunction can reduce the number of priority queue updates for the optional terms. class BooleanScorer : public Scorer { public: BooleanScorer(SimilarityPtr similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers); virtual ~BooleanScorer(); - + LUCENE_CLASS(BooleanScorer); - + protected: SubScorerPtr scorers; BucketTablePtr bucketTable; @@ -47,11 +47,11 @@ namespace Lucene int32_t end; BucketPtr current; int32_t doc; - + protected: // firstDocID is ignored since nextDoc() initializes 'current' virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); - + public: virtual int32_t advance(int32_t target); virtual int32_t docID(); @@ -60,28 +60,28 @@ namespace Lucene virtual void score(CollectorPtr collector); virtual String toString(); }; - + class BooleanScorerCollector : public Collector { public: BooleanScorerCollector(int32_t mask, BucketTablePtr bucketTable); virtual ~BooleanScorerCollector(); - + LUCENE_CLASS(BooleanScorerCollector); - + protected: BucketTableWeakPtr _bucketTable; int32_t mask; ScorerWeakPtr _scorer; - + public: virtual void collect(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); virtual void setScorer(ScorerPtr scorer); virtual bool acceptsDocsOutOfOrder(); }; - - // An internal class which is used in score(Collector, int32_t) for setting the current score. This is required + + // An internal class which is used in score(Collector, int32_t) for setting the current score. This is required // since Collector exposes a setScorer method and implementations that need the score will call scorer->score(). // Therefore the only methods that are implemented are score() and doc(). class BucketScorer : public Scorer @@ -89,28 +89,28 @@ namespace Lucene public: BucketScorer(); virtual ~BucketScorer(); - + LUCENE_CLASS(BucketScorer); - + public: double _score; int32_t doc; - + public: virtual int32_t advance(int32_t target); virtual int32_t docID(); virtual int32_t nextDoc(); virtual double score(); }; - + class Bucket : public LuceneObject { public: Bucket(); virtual ~Bucket(); - + LUCENE_CLASS(Bucket); - + public: int32_t doc; // tells if bucket is valid double score; // incremental score @@ -118,36 +118,36 @@ namespace Lucene int32_t coord; // count of terms in score BucketWeakPtr _next; // next valid bucket }; - + /// A simple hash table of document scores within a range. class BucketTable : public LuceneObject { public: BucketTable(); virtual ~BucketTable(); - + LUCENE_CLASS(BucketTable); - + public: static const int32_t SIZE; static const int32_t MASK; - + Collection buckets; BucketPtr first; // head of valid list - + public: CollectorPtr newCollector(int32_t mask); int32_t size(); }; - + class SubScorer : public LuceneObject { public: SubScorer(ScorerPtr scorer, bool required, bool prohibited, CollectorPtr collector, SubScorerPtr next); virtual ~SubScorer(); - + LUCENE_CLASS(SubScorer); - + public: ScorerPtr scorer; bool required; diff --git a/include/BooleanScorer2.h b/include/BooleanScorer2.h index 1a9f9785..24477b4b 100644 --- a/include/BooleanScorer2.h +++ b/include/BooleanScorer2.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,148 +20,148 @@ namespace Lucene class BooleanScorer2 : public Scorer { public: - /// Creates a {@link Scorer} with the given similarity and lists of required, prohibited and optional + /// Creates a {@link Scorer} with the given similarity and lists of required, prohibited and optional /// scorers. In no required scorers are added, at least one of the optional scorers will have to match /// during the search. /// /// @param similarity The similarity to be used. - /// @param minNrShouldMatch The minimum number of optional added scorers that should match during the search. - /// In case no required scorers are added, at least one of the optional scorers will have to match during + /// @param minNrShouldMatch The minimum number of optional added scorers that should match during the search. + /// In case no required scorers are added, at least one of the optional scorers will have to match during /// the search. /// @param required The list of required scorers. /// @param prohibited The list of prohibited scorers. /// @param optional The list of optional scorers. BooleanScorer2(SimilarityPtr similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional); - + virtual ~BooleanScorer2(); - + LUCENE_CLASS(BooleanScorer2); - + protected: Collection requiredScorers; Collection optionalScorers; Collection prohibitedScorers; - + CoordinatorPtr coordinator; - + /// The scorer to which all scoring will be delegated, except for computing and using the coordination factor. ScorerPtr countingSumScorer; - + int32_t minNrShouldMatch; int32_t doc; - + public: virtual void initialize(); - + /// Scores and collects all matching documents. /// @param collector The collector to which all matching documents are passed through. virtual void score(CollectorPtr collector); - + virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); virtual int32_t docID(); virtual int32_t nextDoc(); virtual double score(); virtual int32_t advance(int32_t target); - + protected: ScorerPtr countingDisjunctionSumScorer(Collection scorers, int32_t minNrShouldMatch); ScorerPtr countingConjunctionSumScorer(Collection requiredScorers); ScorerPtr dualConjunctionSumScorer(ScorerPtr req1, ScorerPtr req2); - - /// Returns the scorer to be used for match counting and score summing. Uses requiredScorers, optionalScorers + + /// Returns the scorer to be used for match counting and score summing. Uses requiredScorers, optionalScorers /// and prohibitedScorers. - ScorerPtr makeCountingSumScorer(); + ScorerPtr makeCountingSumScorer(); ScorerPtr makeCountingSumScorerNoReq(); ScorerPtr makeCountingSumScorerSomeReq(); - - /// Returns the scorer to be used for match counting and score summing. Uses the given required scorer and + + /// Returns the scorer to be used for match counting and score summing. Uses the given required scorer and /// the prohibitedScorers. /// @param requiredCountingSumScorer A required scorer already built. ScorerPtr addProhibitedScorers(ScorerPtr requiredCountingSumScorer); - + friend class CountingDisjunctionSumScorer; friend class CountingConjunctionSumScorer; }; - + class Coordinator : public LuceneObject { public: Coordinator(BooleanScorer2Ptr scorer); virtual ~Coordinator(); - + LUCENE_CLASS(Coordinator); - + public: BooleanScorer2WeakPtr _scorer; Collection coordFactors; int32_t maxCoord; // to be increased for each non prohibited scorer int32_t nrMatchers; // to be increased by score() of match counting scorers. - + public: void init(); // use after all scorers have been added. - + friend class BooleanScorer2; }; - + /// Count a scorer as a single match. class SingleMatchScorer : public Scorer { public: SingleMatchScorer(ScorerPtr scorer, CoordinatorPtr coordinator); virtual ~SingleMatchScorer(); - + LUCENE_CLASS(SingleMatchScorer); - + protected: ScorerPtr scorer; CoordinatorPtr coordinator; int32_t lastScoredDoc; double lastDocScore; - + public: virtual double score(); virtual int32_t docID(); virtual int32_t nextDoc(); virtual int32_t advance(int32_t target); }; - + class CountingDisjunctionSumScorer : public DisjunctionSumScorer { public: CountingDisjunctionSumScorer(BooleanScorer2Ptr scorer, Collection subScorers, int32_t minimumNrMatchers); virtual ~CountingDisjunctionSumScorer(); - + LUCENE_CLASS(CountingDisjunctionSumScorer); - + protected: BooleanScorer2WeakPtr _scorer; int32_t lastScoredDoc; - + // Save the score of lastScoredDoc, so that we don't compute it more than once in score(). double lastDocScore; - + public: virtual double score(); - + friend class BooleanScorer2; }; - + class CountingConjunctionSumScorer : public ConjunctionScorer { public: CountingConjunctionSumScorer(BooleanScorer2Ptr scorer, SimilarityPtr similarity, Collection scorers); virtual ~CountingConjunctionSumScorer(); - + LUCENE_CLASS(CountingConjunctionSumScorer); - + protected: BooleanScorer2WeakPtr _scorer; int32_t lastScoredDoc; int32_t requiredNrMatchers; - + // Save the score of lastScoredDoc, so that we don't compute it more than once in score(). double lastDocScore; - + public: virtual double score(); }; diff --git a/include/BufferedDeletes.h b/include/BufferedDeletes.h index aa79c001..ff75158c 100644 --- a/include/BufferedDeletes.h +++ b/include/BufferedDeletes.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,25 +12,25 @@ namespace Lucene { - /// Holds buffered deletes, by docID, term or query. We hold two instances of this class: one for - /// the deletes prior to the last flush, the other for deletes after the last flush. This is so if - /// we need to abort (discard all buffered docs) we can also discard the buffered deletes yet keep + /// Holds buffered deletes, by docID, term or query. We hold two instances of this class: one for + /// the deletes prior to the last flush, the other for deletes after the last flush. This is so if + /// we need to abort (discard all buffered docs) we can also discard the buffered deletes yet keep /// the deletes done during previously flushed segments. class BufferedDeletes : public LuceneObject { public: BufferedDeletes(bool doTermSort); virtual ~BufferedDeletes(); - + LUCENE_CLASS(BufferedDeletes); - + public: int32_t numTerms; MapTermNum terms; MapQueryInt queries; Collection docIDs; int64_t bytesUsed; - + public: int32_t size(); void update(BufferedDeletesPtr in); @@ -39,16 +39,16 @@ namespace Lucene bool any(); void remap(MergeDocIDRemapperPtr mapper, SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergedDocCount); }; - + /// Number of documents a delete term applies to. class Num : public LuceneObject { public: Num(int32_t num); - + protected: int32_t num; - + public: int32_t getNum(); void setNum(int32_t num); diff --git a/include/BufferedIndexInput.h b/include/BufferedIndexInput.h index d100a11a..125564b3 100644 --- a/include/BufferedIndexInput.h +++ b/include/BufferedIndexInput.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,9 +18,9 @@ namespace Lucene /// Construct BufferedIndexInput with a specific bufferSize. BufferedIndexInput(int32_t bufferSize = BUFFER_SIZE); virtual ~BufferedIndexInput(); - + LUCENE_CLASS(BufferedIndexInput); - + public: /// Default buffer size. static const int32_t BUFFER_SIZE; @@ -31,19 +31,19 @@ namespace Lucene int32_t bufferLength; // end of valid bytes int32_t bufferPosition; // next byte to read ByteArray buffer; - + public: /// Reads and returns a single byte. /// @see IndexOutput#writeByte(uint8_t) virtual uint8_t readByte(); - + /// Change the buffer size used by this IndexInput. void setBufferSize(int32_t newSize); - + /// Returns buffer size. /// @see #setBufferSize int32_t getBufferSize(); - + /// Reads a specified number of bytes into an array at the specified offset. /// @param b the array to read bytes into. /// @param offset the offset in the array to start storing bytes. @@ -51,9 +51,9 @@ namespace Lucene /// @see IndexOutput#writeBytes(const uint8_t*,int) /// @see #readInternal(uint8_t*, int32_t, int32_t) virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - - /// Reads a specified number of bytes into an array at the specified offset with control over whether the - /// read should be buffered (callers who have their own buffer should pass in "false" for useBuffer). + + /// Reads a specified number of bytes into an array at the specified offset with control over whether the + /// read should be buffered (callers who have their own buffer should pass in "false" for useBuffer). /// Currently only {@link BufferedIndexInput} respects this parameter. /// @param b the array to read bytes into. /// @param offset the offset in the array to start storing bytes. @@ -62,39 +62,39 @@ namespace Lucene /// @see IndexOutput#writeBytes(const uint8_t*,int) /// @see #readInternal(uint8_t*, int32_t, int32_t) virtual void readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer); - + /// Closes the stream to further operations. virtual void close(); - + /// Returns the current position in this file, where the next read will occur. /// @see #seek(int64_t) virtual int64_t getFilePointer(); - + /// Sets current position in this file, where the next read will occur. /// @see #getFilePointer() /// @see #seekInternal(int64_t) virtual void seek(int64_t pos); - + /// Returns a clone of this stream. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + protected: virtual void newBuffer(ByteArray newBuffer); - + void checkBufferSize(int32_t bufferSize); - + /// Refill buffer in preparation for reading. /// @see #readInternal(uint8_t*, int32_t, int32_t) /// @see #seekInternal(int64_t) virtual void refill(); - + /// Implements buffer refill. Reads bytes from the current position in the input. /// @param b the array to read bytes into. /// @param offset the offset in the array to start storing bytes. /// @param length the number of bytes to read. virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) = 0; - - /// Implements seek. Sets current position in this file, where the next {@link + + /// Implements seek. Sets current position in this file, where the next {@link /// #readInternal(uint8_t*, int32_t, int32_t)} will occur. /// @param pos position to set next write. /// @see #readInternal(uint8_t*, int32_t, int32_t) diff --git a/include/BufferedIndexOutput.h b/include/BufferedIndexOutput.h index 4d474050..8e0d6820 100644 --- a/include/BufferedIndexOutput.h +++ b/include/BufferedIndexOutput.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,54 +17,54 @@ namespace Lucene public: BufferedIndexOutput(); virtual ~BufferedIndexOutput(); - + LUCENE_CLASS(BufferedIndexOutput); - - public: + + public: static const int32_t BUFFER_SIZE; - + protected: int64_t bufferStart; // position in file of buffer int32_t bufferPosition; // position in buffer ByteArray buffer; - + public: /// Writes a single byte. /// @see IndexInput#readByte() virtual void writeByte(uint8_t b); - + /// Writes an array of bytes. /// @param b the bytes to write. /// @param length the number of bytes to write. /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - + /// Forces any buffered output to be written. virtual void flush(); - - /// Implements buffer write. Writes bytes at the current + + /// Implements buffer write. Writes bytes at the current /// position in the output. /// @param b the bytes to write. /// @param offset the offset in the byte array. /// @param length the number of bytes to write. virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length); - + /// Closes this stream to further operations. virtual void close(); - + /// Returns the current position in this file, where the next write will occur. /// @see #seek(long) virtual int64_t getFilePointer(); - + /// Sets current position in this file, where the next write will occur. /// @see #getFilePointer() virtual void seek(int64_t pos); - + /// The number of bytes in the file. virtual int64_t length() = 0; - + protected: - /// Implements buffer write. Writes bytes at the current + /// Implements buffer write. Writes bytes at the current /// position in the output. /// @param b the bytes to write. /// @param length the number of bytes to write. diff --git a/include/BufferedReader.h b/include/BufferedReader.h index 60f49cb3..04c387d1 100644 --- a/include/BufferedReader.h +++ b/include/BufferedReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// Read text from a character-input stream, buffering characters so as to provide + /// Read text from a character-input stream, buffering characters so as to provide /// for the efficient reading of characters, arrays, and lines. class LPPAPI BufferedReader : public Reader { @@ -19,42 +19,42 @@ namespace Lucene /// Create a buffering character-input stream. BufferedReader(ReaderPtr reader, int32_t size = READER_BUFFER); virtual ~BufferedReader(); - + LUCENE_CLASS(BufferedReader); - + protected: ReaderPtr reader; int32_t bufferSize; int32_t bufferLength; // end of valid bytes int32_t bufferPosition; // next byte to read CharArray buffer; - + public: static const int32_t READER_BUFFER; - + public: /// Read a single character. virtual int32_t read(); - + /// Read characters into a portion of an array. virtual int32_t read(wchar_t* b, int32_t offset, int32_t length); - + /// Read a line of text. virtual bool readLine(String& line); /// Close the stream. virtual void close(); - + /// Tell whether this stream supports the mark() operation virtual bool markSupported(); - + /// Reset the stream. virtual void reset(); - + protected: /// Refill buffer in preparation for reading. int32_t refill(); - + /// Read a single character without moving position. int32_t peek(); }; diff --git a/include/ByteBlockPool.h b/include/ByteBlockPool.h index 9126784c..c00d0c8c 100644 --- a/include/ByteBlockPool.h +++ b/include/ByteBlockPool.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,53 +12,53 @@ namespace Lucene { /// Class that Posting and PostingVector use to write byte streams into shared fixed-size byte[] arrays. - /// The idea is to allocate slices of increasing lengths. For example, the first slice is 5 bytes, the - /// next slice is 14, etc. We start by writing our bytes into the first 5 bytes. When we hit the end of - /// the slice, we allocate the next slice and then write the address of the new slice into the last 4 + /// The idea is to allocate slices of increasing lengths. For example, the first slice is 5 bytes, the + /// next slice is 14, etc. We start by writing our bytes into the first 5 bytes. When we hit the end of + /// the slice, we allocate the next slice and then write the address of the new slice into the last 4 /// bytes of the previous slice (the "forwarding address"). /// /// Each slice is filled with 0's initially, and we mark the end with a non-zero byte. This way the methods - /// that are writing into the slice don't need to record its length and instead allocate a new slice once + /// that are writing into the slice don't need to record its length and instead allocate a new slice once /// they hit a non-zero byte. class ByteBlockPool : public LuceneObject { public: ByteBlockPool(ByteBlockPoolAllocatorBasePtr allocator, bool trackAllocations); virtual ~ByteBlockPool(); - + LUCENE_CLASS(ByteBlockPool); - + public: Collection buffers; int32_t bufferUpto; // Which buffer we are up to int32_t byteUpto; // Where we are in head buffer - + ByteArray buffer; int32_t byteOffset; - + static const int32_t nextLevelArray[]; static const int32_t levelSizeArray[]; - + protected: bool trackAllocations; ByteBlockPoolAllocatorBasePtr allocator; - + public: static int32_t FIRST_LEVEL_SIZE(); - + void reset(); void nextBuffer(); int32_t newSlice(int32_t size); int32_t allocSlice(ByteArray slice, int32_t upto); }; - + class ByteBlockPoolAllocatorBase : public LuceneObject { public: virtual ~ByteBlockPoolAllocatorBase(); - + LUCENE_CLASS(ByteBlockPoolAllocatorBase); - + public: virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end) = 0; virtual void recycleByteBlocks(Collection blocks) = 0; diff --git a/include/ByteFieldSource.h b/include/ByteFieldSource.h index 5fca05df..7f960f8f 100644 --- a/include/ByteFieldSource.h +++ b/include/ByteFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,15 +11,15 @@ namespace Lucene { - /// Obtains byte field values from the {@link FieldCache} using getBytes() and makes those values available + /// Obtains byte field values from the {@link FieldCache} using getBytes() and makes those values available /// as other numeric types, casting as needed. /// /// @see FieldCacheSource for requirements on the field. /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite + /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU + /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, + /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU /// per lookup but will not consume double the FieldCache RAM. class LPPAPI ByteFieldSource : public FieldCacheSource { @@ -27,12 +27,12 @@ namespace Lucene /// Create a cached byte field source with a specific string-to-byte parser. ByteFieldSource(const String& field, ByteParserPtr parser = ByteParserPtr()); virtual ~ByteFieldSource(); - + LUCENE_CLASS(ByteFieldSource); - + protected: ByteParserPtr parser; - + public: virtual String description(); virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader); diff --git a/include/ByteSliceReader.h b/include/ByteSliceReader.h index 26b7eacb..53cbd457 100644 --- a/include/ByteSliceReader.h +++ b/include/ByteSliceReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,16 +11,16 @@ namespace Lucene { - /// IndexInput that knows how to read the byte slices written by Posting and PostingVector. We read the bytes in each slice + /// IndexInput that knows how to read the byte slices written by Posting and PostingVector. We read the bytes in each slice /// until we hit the end of that slice at which point we read the forwarding address of the next slice and then jump to it. class ByteSliceReader : public IndexInput { public: ByteSliceReader(); virtual ~ByteSliceReader(); - + LUCENE_CLASS(ByteSliceReader); - + public: ByteBlockPoolPtr pool; int32_t bufferUpto; @@ -30,30 +30,30 @@ namespace Lucene int32_t level; int32_t bufferOffset; int32_t endIndex; - + public: void init(ByteBlockPoolPtr pool, int32_t startIndex, int32_t endIndex); bool eof(); - + /// Reads and returns a single byte. virtual uint8_t readByte(); - + int64_t writeTo(IndexOutputPtr out); - + void nextSlice(); - + /// Reads a specified number of bytes into an array at the specified offset. virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - + /// Not implemented virtual int64_t getFilePointer(); - + /// Not implemented virtual int64_t length(); - + /// Not implemented virtual void seek(int64_t pos); - + /// Not implemented virtual void close(); }; diff --git a/include/ByteSliceWriter.h b/include/ByteSliceWriter.h index 3dc9c97c..0c93a98b 100644 --- a/include/ByteSliceWriter.h +++ b/include/ByteSliceWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,31 +11,31 @@ namespace Lucene { - /// Class to write byte streams into slices of shared byte[]. This is used by DocumentsWriter to hold + /// Class to write byte streams into slices of shared byte[]. This is used by DocumentsWriter to hold /// the posting list for many terms in RAM. class ByteSliceWriter : public LuceneObject { public: ByteSliceWriter(ByteBlockPoolPtr pool); virtual ~ByteSliceWriter(); - + LUCENE_CLASS(ByteSliceWriter); - + protected: ByteArray slice; int32_t upto; ByteBlockPoolPtr pool; - + public: int32_t offset0; - + public: /// Set up the writer to write at address. void init(int32_t address); - + /// Write byte into byte slice stream void writeByte(uint8_t b); - + void writeBytes(const uint8_t* b, int32_t offset, int32_t length); int32_t getAddress(); void writeVInt(int32_t i); diff --git a/include/CachingSpanFilter.h b/include/CachingSpanFilter.h index 6b2802ef..59f111fb 100644 --- a/include/CachingSpanFilter.h +++ b/include/CachingSpanFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// Wraps another SpanFilter's result and caches it. The purpose is to allow filters to simply filter, + /// Wraps another SpanFilter's result and caches it. The purpose is to allow filters to simply filter, /// and then wrap with this class to add caching. class LPPAPI CachingSpanFilter : public SpanFilter { @@ -20,26 +20,26 @@ namespace Lucene /// New deletions always result in a cache miss, by default ({@link CachingWrapperFilter#RECACHE}. CachingSpanFilter(SpanFilterPtr filter, CachingWrapperFilter::DeletesMode deletesMode = CachingWrapperFilter::DELETES_RECACHE); virtual ~CachingSpanFilter(); - + LUCENE_CLASS(CachingSpanFilter); - + protected: - SpanFilterPtr filter; + SpanFilterPtr filter; FilterCachePtr cache; - + public: // for testing int32_t hitCount; int32_t missCount; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); virtual SpanFilterResultPtr bitSpans(IndexReaderPtr reader); - + virtual String toString(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + protected: SpanFilterResultPtr getCachedResult(IndexReaderPtr reader); }; diff --git a/include/CachingTokenFilter.h b/include/CachingTokenFilter.h index 3d1f2e44..15c78faa 100644 --- a/include/CachingTokenFilter.h +++ b/include/CachingTokenFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,29 +11,29 @@ namespace Lucene { - /// This class can be used if the token attributes of a TokenStream are intended to be consumed more than once. + /// This class can be used if the token attributes of a TokenStream are intended to be consumed more than once. /// It caches all token attribute states locally in a List. /// - /// CachingTokenFilter implements the optional method {@link TokenStream#reset()}, which repositions the stream + /// CachingTokenFilter implements the optional method {@link TokenStream#reset()}, which repositions the stream /// to the first Token. class LPPAPI CachingTokenFilter : public TokenFilter { public: CachingTokenFilter(TokenStreamPtr input); virtual ~CachingTokenFilter(); - + LUCENE_CLASS(CachingTokenFilter); - + protected: Collection cache; Collection::iterator iterator; AttributeSourceStatePtr finalState; - + public: virtual bool incrementToken(); virtual void end(); virtual void reset(); - + protected: void fillCache(); }; diff --git a/include/CachingWrapperFilter.h b/include/CachingWrapperFilter.h index 782abd59..830cf0ee 100644 --- a/include/CachingWrapperFilter.h +++ b/include/CachingWrapperFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,55 +11,55 @@ namespace Lucene { - /// Wraps another filter's result and caches it. The purpose is to allow filters to simply filter, and + /// Wraps another filter's result and caches it. The purpose is to allow filters to simply filter, and /// then wrap with this class to add caching. class LPPAPI CachingWrapperFilter : public Filter { public: /// Specifies how new deletions against a reopened reader should be handled. /// - /// The default is IGNORE, which means the cache entry will be re-used for a given segment, even when - /// that segment has been reopened due to changes in deletions. This is a big performance gain, - /// especially with near-real-timer readers, since you don't hit a cache miss on every reopened reader + /// The default is IGNORE, which means the cache entry will be re-used for a given segment, even when + /// that segment has been reopened due to changes in deletions. This is a big performance gain, + /// especially with near-real-timer readers, since you don't hit a cache miss on every reopened reader /// for prior segments. /// - /// However, in some cases this can cause invalid query results, allowing deleted documents to be - /// returned. This only happens if the main query does not rule out deleted documents on its own, - /// such as a toplevel ConstantScoreQuery. To fix this, use RECACHE to re-create the cached filter - /// (at a higher per-reopen cost, but at faster subsequent search performance), or use DYNAMIC to + /// However, in some cases this can cause invalid query results, allowing deleted documents to be + /// returned. This only happens if the main query does not rule out deleted documents on its own, + /// such as a toplevel ConstantScoreQuery. To fix this, use RECACHE to re-create the cached filter + /// (at a higher per-reopen cost, but at faster subsequent search performance), or use DYNAMIC to /// dynamically intersect deleted docs (fast reopen time but some hit to search performance). enum DeletesMode { DELETES_IGNORE, DELETES_RECACHE, DELETES_DYNAMIC }; - - /// New deletes are ignored by default, which gives higher cache hit rate on reopened readers. - /// Most of the time this is safe, because the filter will be AND'd with a Query that fully enforces - /// deletions. If instead you need this filter to always enforce deletions, pass either {@link + + /// New deletes are ignored by default, which gives higher cache hit rate on reopened readers. + /// Most of the time this is safe, because the filter will be AND'd with a Query that fully enforces + /// deletions. If instead you need this filter to always enforce deletions, pass either {@link /// DeletesMode#RECACHE} or {@link DeletesMode#DYNAMIC}. CachingWrapperFilter(FilterPtr filter, DeletesMode deletesMode = DELETES_IGNORE); - + virtual ~CachingWrapperFilter(); - + LUCENE_CLASS(CachingWrapperFilter); - + INTERNAL: FilterPtr filter; - + // for testing int32_t hitCount; int32_t missCount; - + protected: /// A Filter cache FilterCachePtr cache; /// Provide the DocIdSet to be cached, using the DocIdSet provided by the wrapped Filter. /// - /// This implementation returns the given {@link DocIdSet}, if {@link DocIdSet#isCacheable} returns + /// This implementation returns the given {@link DocIdSet}, if {@link DocIdSet#isCacheable} returns /// true, else it copies the {@link DocIdSetIterator} into an {@link OpenBitSetDISI}. DocIdSetPtr docIdSetToCache(DocIdSetPtr docIdSet, IndexReaderPtr reader); - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); - + virtual String toString(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); diff --git a/include/CharArraySet.h b/include/CharArraySet.h index 45135a39..909a5d80 100644 --- a/include/CharArraySet.h +++ b/include/CharArraySet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,43 +11,43 @@ namespace Lucene { - /// A simple class that stores Strings as char[]'s in a hash table. Note that this is not a general purpose class. - /// For example, it cannot remove items from the set, nor does it resize its hash table to be smaller, etc. It is + /// A simple class that stores Strings as char[]'s in a hash table. Note that this is not a general purpose class. + /// For example, it cannot remove items from the set, nor does it resize its hash table to be smaller, etc. It is /// designed to be quick to test if a char[] is in the set without the necessity of converting it to a String first. class LPPAPI CharArraySet : public LuceneObject { public: CharArraySet(bool ignoreCase); - + /// Create set from a set of strings. CharArraySet(HashSet entries, bool ignoreCase); - + /// Create set from a collection of strings. CharArraySet(Collection entries, bool ignoreCase); - + virtual ~CharArraySet(); - + LUCENE_CLASS(CharArraySet); - + protected: HashSet entries; bool ignoreCase; - + public: virtual bool contains(const String& text); - + /// True if the length chars of text starting at offset are in the set virtual bool contains(const wchar_t* text, int32_t offset, int32_t length); - + /// Add this String into the set virtual bool add(const String& text); - + /// Add this char[] into the set. virtual bool add(CharArray text); - + virtual int32_t size(); virtual bool isEmpty(); - + HashSet::iterator begin(); HashSet::iterator end(); }; diff --git a/include/CharBlockPool.h b/include/CharBlockPool.h index ea726a33..bb867260 100644 --- a/include/CharBlockPool.h +++ b/include/CharBlockPool.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,21 +16,21 @@ namespace Lucene public: CharBlockPool(DocumentsWriterPtr docWriter); virtual ~CharBlockPool(); - + LUCENE_CLASS(CharBlockPool); - + public: Collection buffers; int32_t numBuffer; int32_t bufferUpto; // Which buffer we are up to int32_t charUpto; // Where we are in head buffer - + CharArray buffer; // Current head buffer int32_t charOffset; // Current head offset - + protected: DocumentsWriterWeakPtr _docWriter; - + public: void reset(); void nextBuffer(); diff --git a/include/CharFilter.h b/include/CharFilter.h index 05f83792..9aed7095 100644 --- a/include/CharFilter.h +++ b/include/CharFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,8 +11,8 @@ namespace Lucene { - /// Subclasses of CharFilter can be chained to filter CharStream. They can be used as {@link Reader} with - /// additional offset correction. {@link Tokenizer}s will automatically use {@link #correctOffset} if a + /// Subclasses of CharFilter can be chained to filter CharStream. They can be used as {@link Reader} with + /// additional offset correction. {@link Tokenizer}s will automatically use {@link #correctOffset} if a /// CharFilter/CharStream subclass is used. class LPPAPI CharFilter : public CharStream { @@ -20,21 +20,21 @@ namespace Lucene CharFilter(CharStreamPtr in); public: virtual ~CharFilter(); - + LUCENE_CLASS(CharFilter); - + protected: CharStreamPtr input; - + protected: /// Subclass may want to override to correct the current offset. /// @param currentOff current offset /// @return corrected offset virtual int32_t correct(int32_t currentOff); - + /// Chains the corrected offset through the input CharFilter. virtual int32_t correctOffset(int32_t currentOff); - + virtual void close(); virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); virtual bool markSupported(); diff --git a/include/CharFolder.h b/include/CharFolder.h index e9f7630e..cf1b1e2e 100644 --- a/include/CharFolder.h +++ b/include/CharFolder.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/CharReader.h b/include/CharReader.h index 2de76d55..4418cb62 100644 --- a/include/CharReader.h +++ b/include/CharReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,17 +18,17 @@ namespace Lucene public: CharReader(ReaderPtr in); virtual ~CharReader(); - + LUCENE_CLASS(CharReader); - + protected: ReaderPtr input; - + public: using CharStream::read; - + static CharStreamPtr get(ReaderPtr input); - + virtual int32_t correctOffset(int32_t currentOff); virtual void close(); virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); diff --git a/include/CharStream.h b/include/CharStream.h index a7c92d6e..c99ed2da 100644 --- a/include/CharStream.h +++ b/include/CharStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,16 +11,16 @@ namespace Lucene { - /// CharStream adds {@link #correctOffset} functionality over {@link Reader}. All Tokenizers accept a CharStream - /// instead of {@link Reader} as input, which enables arbitrary character based filtering before tokenization. - /// The {@link #correctOffset} method fixed offsets to account for removal or insertion of characters, so that the + /// CharStream adds {@link #correctOffset} functionality over {@link Reader}. All Tokenizers accept a CharStream + /// instead of {@link Reader} as input, which enables arbitrary character based filtering before tokenization. + /// The {@link #correctOffset} method fixed offsets to account for removal or insertion of characters, so that the /// offsets reported in the tokens match the character offsets of the original Reader. class LPPAPI CharStream : public Reader { public: - virtual ~CharStream(); + virtual ~CharStream(); LUCENE_CLASS(CharStream); - + public: /// Called by CharFilter(s) and Tokenizer to correct token offset. /// diff --git a/include/CharTokenizer.h b/include/CharTokenizer.h index e5298823..8b946604 100644 --- a/include/CharTokenizer.h +++ b/include/CharTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,33 +19,33 @@ namespace Lucene CharTokenizer(AttributeSourcePtr source, ReaderPtr input); CharTokenizer(AttributeFactoryPtr factory, ReaderPtr input); virtual ~CharTokenizer(); - + LUCENE_CLASS(CharTokenizer); - + protected: int32_t offset; int32_t bufferIndex; int32_t dataLen; - + static const int32_t MAX_WORD_LEN; static const int32_t IO_BUFFER_SIZE; - + CharArray ioBuffer; TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool incrementToken(); virtual void end(); virtual void reset(ReaderPtr input); - + protected: - /// Returns true if a character should be included in a token. This tokenizer generates as tokens adjacent + /// Returns true if a character should be included in a token. This tokenizer generates as tokens adjacent /// sequences of characters which satisfy this predicate. Characters for which this is false are used to /// define token boundaries and are not included in tokens. virtual bool isTokenChar(wchar_t c) = 0; - - /// Called on each token character to normalize it before it is added to the token. The default implementation + + /// Called on each token character to normalize it before it is added to the token. The default implementation /// does nothing. Subclasses may use this to, eg., lowercase tokens. virtual wchar_t normalize(wchar_t c); }; diff --git a/include/CheckIndex.h b/include/CheckIndex.h index 8d3ba52f..935dc2ba 100644 --- a/include/CheckIndex.h +++ b/include/CheckIndex.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,26 +23,26 @@ namespace Lucene /// Create a new CheckIndex on the directory. CheckIndex(DirectoryPtr dir); virtual ~CheckIndex(); - + LUCENE_CLASS(CheckIndex); - + protected: InfoStreamPtr infoStream; DirectoryPtr dir; - + static bool _assertsOn; - + public: /// Set infoStream where messages should go. If null, no messages are printed void setInfoStream(InfoStreamPtr out); - + /// Returns a {@link IndexStatus} instance detailing the state of the index. /// /// As this method checks every byte in the index, on a large index it can take quite a long time to run. /// /// WARNING: make sure you only call this when the index is not opened by any writer. IndexStatusPtr checkIndex(); - + /// Returns a {@link IndexStatus} instance detailing the state of the index. /// /// @param onlySegments list of specific segment names to check @@ -52,20 +52,20 @@ namespace Lucene /// /// WARNING: make sure you only call this when the index is not opened by any writer. IndexStatusPtr checkIndex(Collection onlySegments); - + /// Repairs the index using previously returned result from {@link #checkIndex}. Note that this does not - /// remove any of the unreferenced files after it's done; you must separately open an {@link IndexWriter}, + /// remove any of the unreferenced files after it's done; you must separately open an {@link IndexWriter}, /// which deletes unreferenced files when it's created. /// - /// WARNING: this writes a new segments file into the index, effectively removing all documents in broken + /// WARNING: this writes a new segments file into the index, effectively removing all documents in broken /// segments from the index. BE CAREFUL. /// /// WARNING: Make sure you only call this when the index is not opened by any writer. void fixIndex(IndexStatusPtr result); - + static bool testAsserts(); static bool assertsOn(); - + /// Command-line interface to check and fix an index. /// /// Run it like this: @@ -74,244 +74,244 @@ namespace Lucene /// -fix: actually write a new segments_N file, removing any problematic segments /// /// -segment X: only check the specified segment(s). This can be specified multiple times, - /// to check more than one segment, eg -segment _2 -segment _a. + /// to check more than one segment, eg -segment _2 -segment _a. /// You can't use this with the -fix option. /// - /// WARNING: -fix should only be used on an emergency basis as it will cause documents (perhaps many) - /// to be permanently removed from the index. Always make a backup copy of your index before running + /// WARNING: -fix should only be used on an emergency basis as it will cause documents (perhaps many) + /// to be permanently removed from the index. Always make a backup copy of your index before running /// this! Do not run this tool on an index that is actively being written to. You have been warned! /// - /// Run without -fix, this tool will open the index, report version information and report any exceptions - /// it hits and what action it would take if -fix were specified. With -fix, this tool will remove any - /// segments that have issues and write a new segments_N file. This means all documents contained in the + /// Run without -fix, this tool will open the index, report version information and report any exceptions + /// it hits and what action it would take if -fix were specified. With -fix, this tool will remove any + /// segments that have issues and write a new segments_N file. This means all documents contained in the /// affected segments will be removed. /// /// This tool exits with exit code 1 if the index cannot be opened or has any corruption, else 0. static int main(Collection args); - + protected: void msg(const String& msg); - + /// Test field norms. FieldNormStatusPtr testFieldNorms(Collection fieldNames, SegmentReaderPtr reader); - + /// Test the term index. TermIndexStatusPtr testTermIndex(SegmentInfoPtr info, SegmentReaderPtr reader); - + /// Test stored fields for a segment. StoredFieldStatusPtr testStoredFields(SegmentInfoPtr info, SegmentReaderPtr reader); - + /// Test term vectors for a segment. TermVectorStatusPtr testTermVectors(SegmentInfoPtr info, SegmentReaderPtr reader); }; - + /// Returned from {@link #checkIndex()} detailing the health and status of the index. class LPPAPI IndexStatus : public LuceneObject { public: IndexStatus(); virtual ~IndexStatus(); - + LUCENE_CLASS(IndexStatus); - + public: /// True if no problems were found with the index. bool clean; - + /// True if we were unable to locate and load the segments_N file. bool missingSegments; - + /// True if we were unable to open the segments_N file. bool cantOpenSegments; - + /// True if we were unable to read the version number from segments_N file. bool missingSegmentVersion; - + /// Name of latest segments_N file in the index. String segmentsFileName; - + /// Number of segments in the index. int32_t numSegments; - + /// String description of the version of the index. String segmentFormat; - + /// Empty unless you passed specific segments list to check as optional 3rd argument. /// @see CheckIndex#checkIndex(List) Collection segmentsChecked; - + /// True if the index was created with a newer version of Lucene than the CheckIndex tool. bool toolOutOfDate; - + /// List of {@link SegmentInfoStatus} instances, detailing status of each segment. Collection segmentInfos; - + /// Directory index is in. DirectoryPtr dir; - - /// SegmentInfos instance containing only segments that had no problems (this is used with the - /// {@link CheckIndex#fixIndex} method to repair the index. + + /// SegmentInfos instance containing only segments that had no problems (this is used with the + /// {@link CheckIndex#fixIndex} method to repair the index. SegmentInfosPtr newSegments; - + /// How many documents will be lost to bad segments. int32_t totLoseDocCount; - + /// How many bad segments were found. int32_t numBadSegments; - + /// True if we checked only specific segments ({@link #checkIndex(List)}) was called with non-null argument). bool partial; - + /// Holds the userData of the last commit in the index MapStringString userData; }; - + /// Holds the status of each segment in the index. See {@link #segmentInfos}. class LPPAPI SegmentInfoStatus : public LuceneObject { public: SegmentInfoStatus(); virtual ~SegmentInfoStatus(); - + LUCENE_CLASS(SegmentInfoStatus); - + public: /// Name of the segment. String name; - + /// Document count (does not take deletions into account). int32_t docCount; - + /// True if segment is compound file format. bool compound; - + /// Number of files referenced by this segment. int32_t numFiles; - + /// Net size (MB) of the files referenced by this segment. double sizeMB; - + /// Doc store offset, if this segment shares the doc store files (stored fields and term vectors) with /// other segments. This is -1 if it does not share. int32_t docStoreOffset; - + /// String of the shared doc store segment, or null if this segment does not share the doc store files. String docStoreSegment; - + /// True if the shared doc store files are compound file format. bool docStoreCompoundFile; - + /// True if this segment has pending deletions. bool hasDeletions; - + /// Name of the current deletions file name. String deletionsFileName; - + /// Number of deleted documents. int32_t numDeleted; - + /// True if we were able to open a SegmentReader on this segment. bool openReaderPassed; - + /// Number of fields in this segment. int32_t numFields; - + /// True if at least one of the fields in this segment does not omitTermFreqAndPositions. /// @see AbstractField#setOmitTermFreqAndPositions bool hasProx; - + /// Map that includes certain debugging details that IndexWriter records into each segment it creates MapStringString diagnostics; - + /// Status for testing of field norms (null if field norms could not be tested). FieldNormStatusPtr fieldNormStatus; - + /// Status for testing of indexed terms (null if indexed terms could not be tested). TermIndexStatusPtr termIndexStatus; - + /// Status for testing of stored fields (null if stored fields could not be tested). StoredFieldStatusPtr storedFieldStatus; - + /// Status for testing of term vectors (null if term vectors could not be tested). TermVectorStatusPtr termVectorStatus; }; - + /// Status from testing field norms. class LPPAPI FieldNormStatus : public LuceneObject { public: FieldNormStatus(); virtual ~FieldNormStatus(); - + LUCENE_CLASS(FieldNormStatus); - + public: /// Number of fields successfully tested int64_t totFields; - + /// Exception thrown during term index test (null on success) LuceneException error; }; - + /// Status from testing term index. class LPPAPI TermIndexStatus : public LuceneObject { public: TermIndexStatus(); virtual ~TermIndexStatus(); - + LUCENE_CLASS(TermIndexStatus); - + public: /// Total term count int64_t termCount; - + /// Total frequency across all terms. int64_t totFreq; - + /// Total number of positions. int64_t totPos; - + /// Exception thrown during term index test (null on success) LuceneException error; }; - + /// Status from testing stored fields. class LPPAPI StoredFieldStatus : public LuceneObject { public: StoredFieldStatus(); virtual ~StoredFieldStatus(); - + LUCENE_CLASS(StoredFieldStatus); - + public: /// Number of documents tested. int32_t docCount; - + /// Total number of stored fields tested. int64_t totFields; - + /// Exception thrown during stored fields test (null on success) LuceneException error; }; - + /// Status from testing stored fields. class LPPAPI TermVectorStatus : public LuceneObject { public: TermVectorStatus(); virtual ~TermVectorStatus(); - + LUCENE_CLASS(TermVectorStatus); - + public: /// Number of documents tested. int32_t docCount; - + /// Total number of term vectors tested. int64_t totVectors; - + /// Exception thrown during term vector test (null on success) LuceneException error; }; diff --git a/include/ChecksumIndexInput.h b/include/ChecksumIndexInput.h index cdf4d61c..5739f6b9 100644 --- a/include/ChecksumIndexInput.h +++ b/include/ChecksumIndexInput.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,49 +12,49 @@ namespace Lucene { - /// Writes bytes through to a primary IndexInput, computing checksum as it goes. + /// Writes bytes through to a primary IndexInput, computing checksum as it goes. /// Note that you cannot use seek(). class LPPAPI ChecksumIndexInput : public IndexInput { public: ChecksumIndexInput(IndexInputPtr main); virtual ~ChecksumIndexInput(); - + LUCENE_CLASS(ChecksumIndexInput); - + protected: IndexInputPtr main; boost::crc_32_type checksum; - + public: /// Reads and returns a single byte. /// @see IndexOutput#writeByte(uint8_t) virtual uint8_t readByte(); - + /// Reads a specified number of bytes into an array at the specified offset. /// @param b the array to read bytes into. /// @param offset the offset in the array to start storing bytes. /// @param length the number of bytes to read. /// @see IndexOutput#writeBytes(const uint8_t*,int) virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - + /// Return calculated checksum. int64_t getChecksum(); - + /// Closes the stream to further operations. virtual void close(); - + /// Returns the current position in this file, where the next read will occur. /// @see #seek(int64_t) virtual int64_t getFilePointer(); - + /// Sets current position in this file, where the next read will occur. /// @see #getFilePointer() virtual void seek(int64_t pos); - + /// The number of bytes in the file. virtual int64_t length(); - + /// Returns a clone of this stream. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); }; diff --git a/include/ChecksumIndexOutput.h b/include/ChecksumIndexOutput.h index fa01910b..ef91724d 100644 --- a/include/ChecksumIndexOutput.h +++ b/include/ChecksumIndexOutput.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,49 +19,49 @@ namespace Lucene public: ChecksumIndexOutput(IndexOutputPtr main); virtual ~ChecksumIndexOutput(); - + LUCENE_CLASS(ChecksumIndexOutput); - + protected: IndexOutputPtr main; boost::crc_32_type checksum; - + public: /// Writes a single byte. /// @see IndexInput#readByte() virtual void writeByte(uint8_t b); - + /// Writes an array of bytes. /// @param b the bytes to write. /// @param length the number of bytes to write. /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - + /// Return calculated checksum. int64_t getChecksum(); - + /// Forces any buffered output to be written. virtual void flush(); - + /// Closes the stream to further operations. virtual void close(); - + /// Returns the current position in this file, where the next write will occur. /// @see #seek(int64_t) virtual int64_t getFilePointer(); - + /// Sets current position in this file, where the next write will occur. /// @see #getFilePointer() virtual void seek(int64_t pos); - - /// Starts but does not complete the commit of this file (= writing of - /// the final checksum at the end). After this is called must call + + /// Starts but does not complete the commit of this file (= writing of + /// the final checksum at the end). After this is called must call /// {@link #finishCommit} and the {@link #close} to complete the commit. void prepareCommit(); - + /// See {@link #prepareCommit} void finishCommit(); - + /// The number of bytes in the file. virtual int64_t length(); }; diff --git a/include/CloseableThreadLocal.h b/include/CloseableThreadLocal.h index cabeaee7..decf013f 100644 --- a/include/CloseableThreadLocal.h +++ b/include/CloseableThreadLocal.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,13 +18,13 @@ namespace Lucene public: typedef boost::shared_ptr localDataPtr; typedef Map MapLocalData; - + CloseableThreadLocal() { localData = MapLocalData::newInstance(); } - - public: + + public: localDataPtr get() { SyncLock syncLock(this); @@ -36,22 +36,22 @@ namespace Lucene localData.put(LuceneThread::currentId(), initial); return initial; } - + void set(localDataPtr data) { SyncLock syncLock(this); localData.put(LuceneThread::currentId(), data); } - + void close() { SyncLock syncLock(this); localData.remove(LuceneThread::currentId()); } - + protected: MapLocalData localData; - + virtual localDataPtr initialValue() { return localDataPtr(); // override diff --git a/include/Collator.h b/include/Collator.h index 0931c630..4d173eb7 100644 --- a/include/Collator.h +++ b/include/Collator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,12 +18,12 @@ namespace Lucene /// Creates a new Collator, given the file to read from. Collator(std::locale locale); virtual ~Collator(); - + LUCENE_CLASS(Collator); - + protected: const std::collate& collate; - + public: int32_t compare(const String& first, const String& second); }; diff --git a/include/Collection.h b/include/Collection.h index 48155c1f..9a52118b 100644 --- a/include/Collection.h +++ b/include/Collection.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/Collector.h b/include/Collector.h index 95c72071..93ea39c0 100644 --- a/include/Collector.h +++ b/include/Collector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,37 +14,37 @@ namespace Lucene /// Collectors are primarily meant to be used to gather raw results from a search, and implement sorting /// or custom result filtering, collation, etc. /// - /// Lucene's core collectors are derived from Collector. Likely your application can use one of these + /// Lucene's core collectors are derived from Collector. Likely your application can use one of these /// classes, or subclass {@link TopDocsCollector}, instead of implementing Collector directly: /// ///
    ///
  • {@link TopDocsCollector} is an abstract base class that assumes you will retrieve the top N docs, /// according to some criteria, after collection is done. /// - ///
  • {@link TopScoreDocCollector} is a concrete subclass {@link TopDocsCollector} and sorts according - /// to score + docID. This is used internally by the {@link IndexSearcher} search methods that do not take + ///
  • {@link TopScoreDocCollector} is a concrete subclass {@link TopDocsCollector} and sorts according + /// to score + docID. This is used internally by the {@link IndexSearcher} search methods that do not take /// an explicit {@link Sort}. It is likely the most frequently used collector. /// ///
  • {@link TopFieldCollector} subclasses {@link TopDocsCollector} and sorts according to a specified /// {@link Sort} object (sort by field). This is used internally by the {@link IndexSearcher} search methods /// that take an explicit {@link Sort}. /// - ///
  • {@link TimeLimitingCollector}, which wraps any other Collector and aborts the search if it's taken too + ///
  • {@link TimeLimitingCollector}, which wraps any other Collector and aborts the search if it's taken too /// much time. /// - ///
  • {@link PositiveScoresOnlyCollector} wraps any other Collector and prevents collection of hits whose + ///
  • {@link PositiveScoresOnlyCollector} wraps any other Collector and prevents collection of hits whose /// score is <= 0.0 /// ///
- /// + /// /// Collector decouples the score from the collected doc: the score computation is skipped entirely if it's not /// needed. Collectors that do need the score should implement the {@link #setScorer} method, to hold onto the /// passed {@link Scorer} instance, and call {@link Scorer#score()} within the collect method to compute the /// current hit's score. If your collector may request the score for a single hit multiple times, you should use /// {@link ScoreCachingWrappingScorer}. /// - /// NOTE: The doc that is passed to the collect method is relative to the current reader. If your collector needs - /// to resolve this to the docID space of the Multi*Reader, you must re-base it by recording the docBase from the + /// NOTE: The doc that is passed to the collect method is relative to the current reader. If your collector needs + /// to resolve this to the docID space of the Multi*Reader, you must re-base it by recording the docBase from the /// most recent setNextReader call. Here's a simple example showing how to collect docIDs into a BitSet: /// ///
@@ -56,77 +56,77 @@ namespace Lucene
     ///         this->bits = bits;
     ///         this->docBase = 0;
     ///     }
-    /// 
+    ///
     /// protected:
     ///     BitSetPtr bits;
     ///     int32_t docBase;
-    /// 
+    ///
     /// public:
     ///     virtual void setScorer(ScorerPtr scorer)
     ///     {
     ///         // ignore scorer
     ///     }
-    ///     
+    ///
     ///     virtual void collect(int32_t doc)
     ///     {
     ///         bits->set(doc + docBase);
     ///     }
-    ///     
+    ///
     ///     virtual void setNextReader(IndexReaderPtr reader, int32_t docBase)
     ///     {
     ///         this->docBase = docBase;
     ///     }
-    ///     
+    ///
     ///     virtual bool acceptsDocsOutOfOrder()
     ///     {
     ///         return true; // accept docs out of order (for a BitSet it doesn't matter)
     ///     }
     /// };
-    /// 
+    ///
     /// ...
-    /// 
+    ///
     /// SearcherPtr searcher = newLucene(indexReader);
     /// BitSetPtr bits = newLucene(indexReader->maxDoc());
     /// searcher->search(query, newLucene(bits));
     ///
     /// 
- /// Not all collectors will need to rebase the docID. For example, a collector that simply counts the + /// Not all collectors will need to rebase the docID. For example, a collector that simply counts the /// total number of hits would skip it. /// /// NOTE: Prior to 2.9, Lucene silently filtered out hits with score <= 0. As of 2.9, the core Collectors - /// no longer do that. It's very unusual to have such hits (a negative query boost, or function query + /// no longer do that. It's very unusual to have such hits (a negative query boost, or function query /// returning negative custom scores, could cause it to happen). If you need that behavior, use {@link /// PositiveScoresOnlyCollector}. class LPPAPI Collector : public LuceneObject { public: - virtual ~Collector(); + virtual ~Collector(); LUCENE_CLASS(Collector); - + public: - /// Called before successive calls to {@link #collect(int32_t)}. Implementations that need the score - /// of the current document (passed-in to {@link #collect(int32_t)}), should save the passed-in Scorer + /// Called before successive calls to {@link #collect(int32_t)}. Implementations that need the score + /// of the current document (passed-in to {@link #collect(int32_t)}), should save the passed-in Scorer /// and call scorer.score() when needed. virtual void setScorer(ScorerPtr scorer) = 0; - + /// Called once for every document matching a query, with the unbased document number. /// - /// Note: This is called in an inner search loop. For good search performance, implementations of this - /// method should not call {@link Searcher#doc(int32_t)} or {@link IndexReader#document(int32_t)} on + /// Note: This is called in an inner search loop. For good search performance, implementations of this + /// method should not call {@link Searcher#doc(int32_t)} or {@link IndexReader#document(int32_t)} on /// every hit. Doing so can slow searches by an order of magnitude or more. virtual void collect(int32_t doc) = 0; - - /// Called before collecting from each IndexReader. All doc ids in {@link #collect(int32_t)} will + + /// Called before collecting from each IndexReader. All doc ids in {@link #collect(int32_t)} will /// correspond to reader. Add docBase to the current IndexReaders internal document id to re-base ids /// in {@link #collect(int32_t)}. /// @param reader next IndexReader /// @param docBase virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) = 0; - - /// Return true if this collector does not require the matching docIDs to be delivered in int sort + + /// Return true if this collector does not require the matching docIDs to be delivered in int sort /// order (smallest to largest) to {@link #collect}. /// - /// Most Lucene Query implementations will visit matching docIDs in order. However, some queries + /// Most Lucene Query implementations will visit matching docIDs in order. However, some queries /// (currently limited to certain cases of {@link BooleanQuery}) can achieve faster searching if the /// Collector allows them to deliver the docIDs out of order. /// diff --git a/include/ComplexExplanation.h b/include/ComplexExplanation.h index a267b9ef..8df9b5e4 100644 --- a/include/ComplexExplanation.h +++ b/include/ComplexExplanation.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,34 +11,34 @@ namespace Lucene { - /// Describes the score computation for document and query, and can distinguish a match independent + /// Describes the score computation for document and query, and can distinguish a match independent /// of a positive value. class LPPAPI ComplexExplanation : public Explanation { public: ComplexExplanation(bool match = false, double value = 0, const String& description = EmptyString); virtual ~ComplexExplanation(); - + LUCENE_CLASS(ComplexExplanation); - + protected: bool match; - + public: /// The match status of this explanation node. bool getMatch(); - + /// Sets the match status assigned to this explanation node. void setMatch(bool match); - + /// Indicates whether or not this Explanation models a good match. /// - /// If the match status is explicitly set this method uses it; otherwise it defers to the + /// If the match status is explicitly set this method uses it; otherwise it defers to the /// superclass. /// /// @see #getMatch virtual bool isMatch(); - + protected: virtual String getSummary(); }; diff --git a/include/CompoundFileReader.h b/include/CompoundFileReader.h index c5618557..7f1037af 100644 --- a/include/CompoundFileReader.h +++ b/include/CompoundFileReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,9 +21,9 @@ namespace Lucene CompoundFileReader(DirectoryPtr dir, const String& name); CompoundFileReader(DirectoryPtr dir, const String& name, int32_t readBufferSize); virtual ~CompoundFileReader(); - + LUCENE_CLASS(CompoundFileReader); - + protected: struct FileEntry { @@ -37,52 +37,52 @@ namespace Lucene }; typedef boost::shared_ptr FileEntryPtr; typedef HashMap MapStringFileEntryPtr; - + DirectoryPtr directory; String fileName; int32_t readBufferSize; IndexInputPtr stream; MapStringFileEntryPtr entries; - + protected: void ConstructReader(DirectoryPtr dir, const String& name, int32_t readBufferSize); - + public: DirectoryPtr getDirectory(); String getName(); virtual void close(); virtual IndexInputPtr openInput(const String& name); virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - + /// Returns an array of strings, one for each file in the directory. virtual HashSet listAll(); - + /// Returns true if a file with the given name exists. virtual bool fileExists(const String& name); - + /// Returns the time the compound file was last modified. virtual uint64_t fileModified(const String& name); - + /// Set the modified time of the compound file to now. virtual void touchFile(const String& name); - + /// Not implemented virtual void deleteFile(const String& name); - + /// Not implemented virtual void renameFile(const String& from, const String& to); - + /// Returns the length of a file in the directory. virtual int64_t fileLength(const String& name); - + /// Not implemented virtual IndexOutputPtr createOutput(const String& name); - + /// Not implemented virtual LockPtr makeLock(const String& name); }; - - /// Implementation of an IndexInput that reads from a portion of the compound file. + + /// Implementation of an IndexInput that reads from a portion of the compound file. class CSIndexInput : public BufferedIndexInput { public: @@ -90,31 +90,31 @@ namespace Lucene CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length); CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length, int32_t readBufferSize); virtual ~CSIndexInput(); - + LUCENE_CLASS(CSIndexInput); - + public: IndexInputPtr base; int64_t fileOffset; int64_t _length; - + public: /// Closes the stream to further operations. virtual void close(); - + virtual int64_t length(); - + /// Returns a clone of this stream. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + protected: /// Implements buffer refill. Reads bytes from the current position in the input. /// @param b the array to read bytes into /// @param offset the offset in the array to start storing bytes /// @param len the number of bytes to read virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); - - /// Implements seek. Sets current position in this file, where the next {@link + + /// Implements seek. Sets current position in this file, where the next {@link /// #readInternal(byte[],int,int)} will occur. virtual void seekInternal(int64_t pos); }; diff --git a/include/CompoundFileWriter.h b/include/CompoundFileWriter.h index 0ed42a9d..ea0d234b 100644 --- a/include/CompoundFileWriter.h +++ b/include/CompoundFileWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,55 +21,55 @@ namespace Lucene /// {File Data} /// fileCount entries with the raw data of the corresponding file /// - /// The fileCount integer indicates how many files are contained in this compound file. The {directory} - /// that follows has that many entries. Each directory entry contains a long pointer to the start of + /// The fileCount integer indicates how many files are contained in this compound file. The {directory} + /// that follows has that many entries. Each directory entry contains a long pointer to the start of /// this file's data section, and a string with that file's name. class CompoundFileWriter : public LuceneObject { public: CompoundFileWriter(DirectoryPtr dir, const String& name, CheckAbortPtr checkAbort = CheckAbortPtr()); virtual ~CompoundFileWriter(); - + LUCENE_CLASS(CompoundFileWriter); - + protected: struct FileEntry { /// source file String file; - + /// temporary holder for the start of directory entry for this file int64_t directoryOffset; - + /// temporary holder for the start of this file's data section int64_t dataOffset; }; - + DirectoryWeakPtr _directory; String fileName; HashSet ids; Collection entries; bool merged; CheckAbortPtr checkAbort; - + public: /// Returns the directory of the compound file. DirectoryPtr getDirectory(); - + /// Returns the name of the compound file. String getName(); - - /// Add a source stream. file is the string by which the sub-stream will be known in the + + /// Add a source stream. file is the string by which the sub-stream will be known in the /// compound stream. void addFile(const String& file); - - /// Merge files with the extensions added up to now. All files with these extensions are - /// combined sequentially into the compound stream. After successful merge, the source + + /// Merge files with the extensions added up to now. All files with these extensions are + /// combined sequentially into the compound stream. After successful merge, the source /// are deleted.files void close(); - + protected: - /// Copy the contents of the file with specified extension into the provided output stream. + /// Copy the contents of the file with specified extension into the provided output stream. /// Use the provided buffer for moving data to reduce memory allocation. void copyFile(const FileEntry& source, IndexOutputPtr os, ByteArray buffer); }; diff --git a/include/CompressionTools.h b/include/CompressionTools.h index 934ef038..0457258c 100644 --- a/include/CompressionTools.h +++ b/include/CompressionTools.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,31 +16,31 @@ namespace Lucene { public: virtual ~CompressionTools(); - + LUCENE_CLASS(CompressionTools); - + public: /// Compresses the specified byte range using the specified compressionLevel static ByteArray compress(uint8_t* value, int32_t offset, int32_t length, int32_t compressionLevel); - + /// Compresses the specified byte range, with default BEST_COMPRESSION level static ByteArray compress(uint8_t* value, int32_t offset, int32_t length); - + /// Compresses all bytes in the array, with default BEST_COMPRESSION level static ByteArray compress(ByteArray value); - + /// Compresses the String value, with default BEST_COMPRESSION level static ByteArray compressString(const String& value); - + /// Compresses the String value using the specified compressionLevel static ByteArray compressString(const String& value, int32_t compressionLevel); - + /// Decompress the byte array previously returned by compress static ByteArray decompress(ByteArray value); - + /// Decompress the byte array previously returned by compressString back into a String static String decompressString(ByteArray value); - + protected: static const int32_t COMPRESS_BUFFER; }; diff --git a/include/ConcurrentMergeScheduler.h b/include/ConcurrentMergeScheduler.h index 8c0cb804..0a560399 100644 --- a/include/ConcurrentMergeScheduler.h +++ b/include/ConcurrentMergeScheduler.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,88 +11,88 @@ namespace Lucene { - /// A {@link MergeScheduler} that runs each merge using a separate thread, up until a - /// maximum number of threads ({@link #setMaxThreadCount}) at which when a merge is needed, - /// the thread(s) that are updating the index will pause until one or more merges completes. - /// This is a simple way to use concurrency in the indexing process without having to create + /// A {@link MergeScheduler} that runs each merge using a separate thread, up until a + /// maximum number of threads ({@link #setMaxThreadCount}) at which when a merge is needed, + /// the thread(s) that are updating the index will pause until one or more merges completes. + /// This is a simple way to use concurrency in the indexing process without having to create /// and manage application level threads. class LPPAPI ConcurrentMergeScheduler : public MergeScheduler { public: ConcurrentMergeScheduler(); virtual ~ConcurrentMergeScheduler(); - + LUCENE_CLASS(ConcurrentMergeScheduler); - + protected: int32_t mergeThreadPriority; - + SetMergeThread mergeThreads; - + /// Max number of threads allowed to be merging at once int32_t maxThreadCount; - + DirectoryPtr dir; - + bool closed; IndexWriterWeakPtr _writer; - + static Collection allInstances; - + bool suppressExceptions; static bool anyExceptions; - + public: virtual void initialize(); - - /// Sets the max # simultaneous threads that may be running. If a merge is necessary yet - /// we already have this many threads running, the incoming thread (that is calling + + /// Sets the max # simultaneous threads that may be running. If a merge is necessary yet + /// we already have this many threads running, the incoming thread (that is calling /// add/updateDocument) will block until a merge thread has completed. virtual void setMaxThreadCount(int32_t count); - + /// Get the max # simultaneous threads that may be running. @see #setMaxThreadCount. virtual int32_t getMaxThreadCount(); - - /// Return the priority that merge threads run at. By default the priority is 1 plus the + + /// Return the priority that merge threads run at. By default the priority is 1 plus the /// priority of (ie, slightly higher priority than) the first thread that calls merge. virtual int32_t getMergeThreadPriority(); - + /// Set the priority that merge threads run at. virtual void setMergeThreadPriority(int32_t pri); - + virtual void close(); - + virtual void sync(); - + virtual void merge(IndexWriterPtr writer); - + /// Used for testing static bool anyUnhandledExceptions(); static void clearUnhandledExceptions(); - + /// Used for testing void setSuppressExceptions(); void clearSuppressExceptions(); - + /// Used for testing static void setTestMode(); - + protected: virtual bool verbose(); virtual void message(const String& message); virtual void initMergeThreadPriority(); virtual int32_t mergeThreadCount(); - + /// Does the actual merge, by calling {@link IndexWriter#merge} virtual void doMerge(OneMergePtr merge); - + virtual MergeThreadPtr getMergeThread(IndexWriterPtr writer, OneMergePtr merge); - + /// Called when an exception is hit in a background merge thread virtual void handleMergeException(const LuceneException& exc); - + virtual void addMyself(); - + friend class MergeThread; }; } diff --git a/include/Config.h.cmake b/include/Config.h.cmake index eba35441..742021ef 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/ConjunctionScorer.h b/include/ConjunctionScorer.h index f2c62eba..6f7ed360 100644 --- a/include/ConjunctionScorer.h +++ b/include/ConjunctionScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,20 +17,20 @@ namespace Lucene public: ConjunctionScorer(SimilarityPtr similarity, Collection scorers); virtual ~ConjunctionScorer(); - + LUCENE_CLASS(ConjunctionScorer); - + protected: Collection scorers; double coord; int32_t lastDoc; - + public: virtual int32_t advance(int32_t target); virtual int32_t docID(); virtual int32_t nextDoc(); virtual double score(); - + protected: int32_t doNext(); }; diff --git a/include/ConstantScoreQuery.h b/include/ConstantScoreQuery.h index 53bfcd37..22d5074b 100644 --- a/include/ConstantScoreQuery.h +++ b/include/ConstantScoreQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,37 +13,37 @@ namespace Lucene { - /// A query that wraps a filter and simply returns a constant score equal to the query boost for every + /// A query that wraps a filter and simply returns a constant score equal to the query boost for every /// document in the filter. class LPPAPI ConstantScoreQuery : public Query { public: ConstantScoreQuery(FilterPtr filter); virtual ~ConstantScoreQuery(); - + LUCENE_CLASS(ConstantScoreQuery); - + protected: FilterPtr filter; - + public: using Query::toString; - + /// Returns the encapsulated filter FilterPtr getFilter(); - + virtual QueryPtr rewrite(IndexReaderPtr reader); virtual void extractTerms(SetTerm terms); - + virtual WeightPtr createWeight(SearcherPtr searcher); - + /// Prints a user-readable version of this query. virtual String toString(const String& field); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + friend class ConstantWeight; friend class ConstantScorer; }; diff --git a/include/Constants.h b/include/Constants.h index 06337d96..915736dd 100644 --- a/include/Constants.h +++ b/include/Constants.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,16 +16,16 @@ namespace Lucene { private: Constants(); - + public: virtual ~Constants(); - + public: static String OS_NAME; static String LUCENE_MAIN_VERSION; - static String LUCENE_VERSION; + static String LUCENE_VERSION; }; - + /// Use by certain classes to match version compatibility across releases of Lucene. /// /// WARNING: When changing the version parameter that you supply to components in Lucene, do not simply @@ -34,55 +34,55 @@ namespace Lucene { private: LuceneVersion(); - + public: virtual ~LuceneVersion(); - + public: enum Version { /// Match settings and bugs in Lucene's 2.0 release. LUCENE_20 = 0, - + /// Match settings and bugs in Lucene's 2.1 release. LUCENE_21, - + /// Match settings and bugs in Lucene's 2.2 release. LUCENE_22, - + /// Match settings and bugs in Lucene's 2.3 release. LUCENE_23, - + /// Match settings and bugs in Lucene's 2.4 release. LUCENE_24, - + /// Match settings and bugs in Lucene's 2.9 release. LUCENE_29, - - /// Match settings and bugs in Lucene's 3.0 release. + + /// Match settings and bugs in Lucene's 3.0 release. /// /// Use this to get the latest & greatest settings, bug fixes, etc, for Lucene. LUCENE_30, - + /// Add new constants for later versions **here** to respect order! - /// Warning: If you use this setting, and then upgrade to a newer release of Lucene, - /// sizable changes may happen. If backwards compatibility is important then you + /// Warning: If you use this setting, and then upgrade to a newer release of Lucene, + /// sizable changes may happen. If backwards compatibility is important then you /// should instead explicitly specify an actual version. /// - /// If you use this constant then you may need to re-index all of your documents - /// when upgrading Lucene, as the way text is indexed may have changed. Additionally, - /// you may need to re-test your entire application to ensure it behaves as - /// expected, as some defaults may have changed and may break functionality in your - /// application. + /// If you use this constant then you may need to re-index all of your documents + /// when upgrading Lucene, as the way text is indexed may have changed. Additionally, + /// you may need to re-test your entire application to ensure it behaves as + /// expected, as some defaults may have changed and may break functionality in your + /// application. /// - /// Deprecated: Use an actual version instead. + /// Deprecated: Use an actual version instead. LUCENE_CURRENT }; - + public: static bool onOrAfter(LuceneVersion::Version first, LuceneVersion::Version second); - }; + }; } #endif diff --git a/include/CustomScoreProvider.h b/include/CustomScoreProvider.h index a3361184..2a257a86 100644 --- a/include/CustomScoreProvider.h +++ b/include/CustomScoreProvider.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,26 +11,26 @@ namespace Lucene { - /// An instance of this subclass should be returned by {@link CustomScoreQuery#getCustomScoreProvider}, + /// An instance of this subclass should be returned by {@link CustomScoreQuery#getCustomScoreProvider}, /// if you want to modify the custom score calculation of a {@link CustomScoreQuery}. /// - /// Since Lucene 2.9, queries operate on each segment of an Index separately, so overriding the similar - /// (now deprecated) methods in {@link CustomScoreQuery} is no longer suitable, as the supplied doc ID - /// is per-segment and without knowledge of the IndexReader you cannot access the document or {@link + /// Since Lucene 2.9, queries operate on each segment of an Index separately, so overriding the similar + /// (now deprecated) methods in {@link CustomScoreQuery} is no longer suitable, as the supplied doc ID + /// is per-segment and without knowledge of the IndexReader you cannot access the document or {@link /// FieldCache}. class LPPAPI CustomScoreProvider : public LuceneObject { public: /// Creates a new instance of the provider class for the given {@link IndexReader}. CustomScoreProvider(IndexReaderPtr reader); - + virtual ~CustomScoreProvider(); - + LUCENE_CLASS(CustomScoreProvider); - + protected: IndexReaderPtr reader; - + public: /// Compute a custom score by the subQuery score and a number of ValueSourceQuery scores. /// @@ -39,39 +39,39 @@ namespace Lucene /// If your custom scoring is different than the default herein you should override at least one of /// the two customScore() methods. If the number of ValueSourceQueries is always < 2 it is /// sufficient to override the other {@link #customScore(int32_t, double, double) customScore()} - /// method, which is simpler. + /// method, which is simpler. /// /// The default computation herein is a multiplication of given scores: ///
         /// ModifiedScore = valSrcScore * valSrcScores[0] * valSrcScores[1] * ...
         /// 
/// - /// @param doc id of scored doc. + /// @param doc id of scored doc. /// @param subQueryScore score of that doc by the subQuery. /// @param valSrcScores scores of that doc by the ValueSourceQuery. /// @return custom score. virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); - + /// Compute a custom score by the subQuery score and the ValueSourceQuery score. /// /// Subclasses can override this method to modify the custom score. /// - /// If your custom scoring is different than the default herein you should override at least one of the - /// two customScore() methods. If the number of ValueSourceQueries is always < 2 it is sufficient to - /// override this customScore() method, which is simpler. + /// If your custom scoring is different than the default herein you should override at least one of the + /// two customScore() methods. If the number of ValueSourceQueries is always < 2 it is sufficient to + /// override this customScore() method, which is simpler. /// /// The default computation herein is a multiplication of the two scores: ///
         /// ModifiedScore = subQueryScore * valSrcScore
         /// 
/// - /// @param doc id of scored doc. + /// @param doc id of scored doc. /// @param subQueryScore score of that doc by the subQuery. /// @param valSrcScore score of that doc by the ValueSourceQuery. /// @return custom score. virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); - - /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, Collection)}, + + /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, Collection)}, /// this method should also be overridden to provide the correct explanation for the part of the custom scoring. /// /// @param doc doc being explained. @@ -79,8 +79,8 @@ namespace Lucene /// @param valSrcExpls explanation for the value source part. /// @return an explanation for the custom score virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls); - - /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, double)}, + + /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, double)}, /// this method should also be overridden to provide the correct explanation for the part of the custom scoring. /// @param doc doc being explained. /// @param subQueryExpl explanation for the sub-query part. diff --git a/include/CustomScoreQuery.h b/include/CustomScoreQuery.h index 7b108912..c9e6a09f 100644 --- a/include/CustomScoreQuery.h +++ b/include/CustomScoreQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene /// Query that sets document score as a programmatic function of several (sub) scores: ///
    ///
  1. the score of its subQuery (any query) - ///
  2. (optional) the score of its ValueSourceQuery (or queries). For most simple/convenient use cases + ///
  3. (optional) the score of its ValueSourceQuery (or queries). For most simple/convenient use cases /// this query is likely to be a {@link FieldScoreQuery} ///
/// Subclasses can modify the computation by overriding {@link #getCustomScoreProvider}. @@ -22,108 +22,108 @@ namespace Lucene { public: /// Create a CustomScoreQuery over input subQuery. - /// @param subQuery the sub query whose scored is being customed. Must not be null. + /// @param subQuery the sub query whose scored is being customed. Must not be null. CustomScoreQuery(QueryPtr subQuery); - + /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. /// @param subQuery the sub query whose score is being customized. Must not be null. - /// @param valSrcQuery a value source query whose scores are used in the custom score computation. For - /// most simple/convenient use case this would be a {@link FieldScoreQuery}. This parameter is + /// @param valSrcQuery a value source query whose scores are used in the custom score computation. For + /// most simple/convenient use case this would be a {@link FieldScoreQuery}. This parameter is /// optional - it can be null. CustomScoreQuery(QueryPtr subQuery, ValueSourceQueryPtr valSrcQuery); - + /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. /// @param subQuery the sub query whose score is being customized. Must not be null. - /// @param valSrcQueries value source queries whose scores are used in the custom score computation. - /// For most simple/convenient use case these would be {@link FieldScoreQueries}. This parameter is + /// @param valSrcQueries value source queries whose scores are used in the custom score computation. + /// For most simple/convenient use case these would be {@link FieldScoreQueries}. This parameter is /// optional - it can be null or even an empty array. CustomScoreQuery(QueryPtr subQuery, Collection valSrcQueries); - + virtual ~CustomScoreQuery(); - + LUCENE_CLASS(CustomScoreQuery); - + protected: QueryPtr subQuery; Collection valSrcQueries; // never null (empty array if there are no valSrcQueries). bool strict; // if true, valueSource part of query does not take part in weights normalization. - + public: using Query::toString; - + virtual QueryPtr rewrite(IndexReaderPtr reader); virtual void extractTerms(SetTerm terms); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual String toString(const String& field); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + /// Compute a custom score by the subQuery score and a number of ValueSourceQuery scores. /// /// Deprecated: Will be removed in Lucene 3.1. /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} /// for the given {@link IndexReader}. virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); - + /// Compute a custom score by the subQuery score and the ValueSourceQuery score. /// /// Deprecated: Will be removed in Lucene 3.1. /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment - /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// search (since Lucene 2.9). + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} /// for the given {@link IndexReader}. virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); - + /// Explain the custom score. /// /// Deprecated: Will be removed in Lucene 3.1. /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} /// for the given {@link IndexReader}. virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls); - + /// Explain the custom score. /// /// Deprecated Will be removed in Lucene 3.1. /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} /// for the given {@link IndexReader}. virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl); - + virtual WeightPtr createWeight(SearcherPtr searcher); - - /// Checks if this is strict custom scoring. In strict custom scoring, the ValueSource part does not - /// participate in weight normalization. This may be useful when one wants full control over how scores - /// are modified, and does not care about normalizing by the ValueSource part. One particular case where - /// this is useful if for testing this query. + + /// Checks if this is strict custom scoring. In strict custom scoring, the ValueSource part does not + /// participate in weight normalization. This may be useful when one wants full control over how scores + /// are modified, and does not care about normalizing by the ValueSource part. One particular case where + /// this is useful if for testing this query. /// /// Note: only has effect when the ValueSource part is not null. virtual bool isStrict(); - - /// Set the strict mode of this query. + + /// Set the strict mode of this query. /// @param strict The strict mode to set. /// @see #isStrict() virtual void setStrict(bool strict); - + /// A short name of this query, used in {@link #toString(String)}. virtual String name(); - + protected: void ConstructQuery(QueryPtr subQuery, Collection valSrcQueries); - - /// Returns a {@link CustomScoreProvider} that calculates the custom scores for the given {@link - /// IndexReader}. The default implementation returns a default implementation as specified in + + /// Returns a {@link CustomScoreProvider} that calculates the custom scores for the given {@link + /// IndexReader}. The default implementation returns a default implementation as specified in /// the docs of {@link CustomScoreProvider}. virtual CustomScoreProviderPtr getCustomScoreProvider(IndexReaderPtr reader); - + friend class CustomWeight; friend class CustomScorer; }; diff --git a/include/CycleCheck.h b/include/CycleCheck.h index 8f3df4bb..14052415 100644 --- a/include/CycleCheck.h +++ b/include/CycleCheck.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,25 +16,25 @@ namespace Lucene { public: virtual ~CycleCheck(); - + protected: static MapStringInt cycleMap; static Set staticRefs; - + protected: void addRef(const String& className, int32_t ref); static void addStatic(LuceneObjectPtr* staticRef); - + public: template static void addStatic(TYPE& staticRef) { addStatic(reinterpret_cast(&staticRef)); } - + static void dumpRefs(); }; - + template class CycleCheckT : public CycleCheck { @@ -43,7 +43,7 @@ namespace Lucene { addRef(TYPE::_getClassName(), 1); } - + virtual ~CycleCheckT() { addRef(TYPE::_getClassName(), -1); diff --git a/include/DateField.h b/include/DateField.h index bdf6ecd4..5262b3cc 100644 --- a/include/DateField.h +++ b/include/DateField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,43 +11,43 @@ namespace Lucene { - /// Provides support for converting dates to strings and vice-versa. The strings are structured so that + /// Provides support for converting dates to strings and vice-versa. The strings are structured so that /// lexicographic sorting orders by date, which makes them suitable for use as field values and search terms. /// - /// Note that this class saves dates with millisecond granularity, which is bad for {@link TermRangeQuery} and - /// {@link PrefixQuery}, as those queries are expanded to a BooleanQuery with a potentially large number of terms + /// Note that this class saves dates with millisecond granularity, which is bad for {@link TermRangeQuery} and + /// {@link PrefixQuery}, as those queries are expanded to a BooleanQuery with a potentially large number of terms /// when searching. Thus you might want to use {@link DateTools} instead. /// - /// Note: dates before 1970 cannot be used, and therefore cannot be indexed when using this class. See {@link + /// Note: dates before 1970 cannot be used, and therefore cannot be indexed when using this class. See {@link /// DateTools} for an alternative without such a limitation. /// - /// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) - /// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix - /// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric + /// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) + /// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix + /// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric /// value with {@link NumericField} and use {@link NumericRangeQuery} to query it. /// - /// @deprecated If you build a new index, use {@link DateTools} or {@link NumericField} instead. This class is + /// @deprecated If you build a new index, use {@link DateTools} or {@link NumericField} instead. This class is /// included for use with existing indices and will be removed in a future release (possibly Lucene 4.0). class LPPAPI DateField : public LuceneObject { public: virtual ~DateField(); - + LUCENE_CLASS(DateField); - + protected: static int32_t DATE_LEN(); - + public: static const String& MIN_DATE_STRING(); static const String& MAX_DATE_STRING(); - + /// Converts a Date to a string suitable for indexing. static String dateToString(const boost::posix_time::ptime& date); - + /// Converts a millisecond time to a string suitable for indexing. static String timeToString(int64_t time); - + /// Converts a string-encoded date into a millisecond time. static int64_t stringToTime(const String& s); }; diff --git a/include/DateTools.h b/include/DateTools.h index f93f5832..aab645b4 100644 --- a/include/DateTools.h +++ b/include/DateTools.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,27 +11,27 @@ namespace Lucene { - /// Provides support for converting dates to strings and vice-versa. The strings are structured so that - /// lexicographic sorting orders them by date, which makes them suitable for use as field values and search + /// Provides support for converting dates to strings and vice-versa. The strings are structured so that + /// lexicographic sorting orders them by date, which makes them suitable for use as field values and search /// terms. /// - /// This class also helps you to limit the resolution of your dates. Do not save dates with a finer resolution + /// This class also helps you to limit the resolution of your dates. Do not save dates with a finer resolution /// than you really need, as then RangeQuery and PrefixQuery will require more memory and become slower. /// - /// Compared to {@link DateField} the strings generated by the methods in this class take slightly more space, + /// Compared to {@link DateField} the strings generated by the methods in this class take slightly more space, /// unless your selected resolution is set to Resolution.DAY or lower. /// - /// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) - /// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix - /// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric + /// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) + /// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix + /// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric /// value with {@link NumericField} and use {@link NumericRangeQuery} to query it. class LPPAPI DateTools : public LuceneObject { public: virtual ~DateTools(); - + LUCENE_CLASS(DateTools); - + public: enum Resolution { @@ -44,7 +44,7 @@ namespace Lucene RESOLUTION_SECOND, RESOLUTION_MILLISECOND }; - + enum DateOrder { DATEORDER_LOCALE, @@ -52,57 +52,57 @@ namespace Lucene DATEORDER_DMY, DATEORDER_MDY }; - + protected: static DateOrder dateOrder; - + public: /// Converts a Date to a string suitable for indexing. /// @param date the date to be converted /// @param resolution the desired resolution - /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone + /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone static String dateToString(const boost::posix_time::ptime& date, Resolution resolution); - + /// Converts a millisecond time to a string suitable for indexing. /// @param time the date expressed as milliseconds since January 1, 1970, 00:00:00 GMT /// @param resolution the desired resolution - /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone + /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone static String timeToString(int64_t time, Resolution resolution); - - /// Converts a string produced by timeToString or dateToString back to a time, represented as the number of + + /// Converts a string produced by timeToString or dateToString back to a time, represented as the number of /// milliseconds since January 1, 1970, 00:00:00 GMT. /// @param dateString the date string to be converted /// @return the number of milliseconds since January 1, 1970, 00:00:00 GMT static int64_t stringToTime(const String& dateString); - + /// Converts a string produced by timeToString or dateToString back to a time, represented as a ptime object. /// @param dateString the date string to be converted - /// @return the parsed time as a ptime object + /// @return the parsed time as a ptime object static boost::posix_time::ptime stringToDate(const String& dateString); - + /// Limit a date's resolution. For example, the date 2004-09-21 13:50:11 will be changed to 2004-09-01 00:00:00 /// when using Resolution.MONTH. /// @param resolution The desired resolution of the date to be returned /// @return the date with all values more precise than resolution set to 0 or 1 static boost::posix_time::ptime round(const boost::posix_time::ptime& date, Resolution resolution); - - /// Limit a date's resolution. For example, the date 1095767411000 (which represents 2004-09-21 13:50:11) will + + /// Limit a date's resolution. For example, the date 1095767411000 (which represents 2004-09-21 13:50:11) will /// be changed to 1093989600000 (2004-09-01 00:00:00) when using Resolution.MONTH. /// @param resolution The desired resolution of the date to be returned - /// @return the date with all values more precise than resolution set to 0 or 1, expressed as milliseconds + /// @return the date with all values more precise than resolution set to 0 or 1, expressed as milliseconds /// since January 1, 1970, 00:00:00 GMT static int64_t round(int64_t time, Resolution resolution); - + /// Allow overriding of date ordering. static void setDateOrder(DateTools::DateOrder order); - + /// Return date ordering based on given locale (or overridden in {@link #setDateOrder(DateTools::DateOrder)}). static DateTools::DateOrder getDateOrder(std::locale locale = std::locale()); - + /// Parse a given date using locale date format /// @param dateString the date string to be converted /// @param locale the locale to use for parsing - /// @return the parsed time as a ptime object + /// @return the parsed time as a ptime object static boost::posix_time::ptime parseDate(const String& dateString, std::locale locale = std::locale()); }; } diff --git a/include/DefaultSimilarity.h b/include/DefaultSimilarity.h index 8e0b63ba..ad12ca68 100644 --- a/include/DefaultSimilarity.h +++ b/include/DefaultSimilarity.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,41 +17,41 @@ namespace Lucene public: DefaultSimilarity(); virtual ~DefaultSimilarity(); - + LUCENE_CLASS(DefaultSimilarity); - + protected: bool discountOverlaps; // Default false - + public: - /// Implemented as state->getBoost() * lengthNorm(numTerms), where numTerms is {@link - /// FieldInvertState#getLength()} if {@link #setDiscountOverlaps} is false, else it's {@link + /// Implemented as state->getBoost() * lengthNorm(numTerms), where numTerms is {@link + /// FieldInvertState#getLength()} if {@link #setDiscountOverlaps} is false, else it's {@link /// FieldInvertState#getLength()} - {@link FieldInvertState#getNumOverlap()}. virtual double computeNorm(const String& fieldName, FieldInvertStatePtr state); - + /// Implemented as 1 / sqrt(numTerms). virtual double lengthNorm(const String& fieldName, int32_t numTokens); - + /// Implemented as 1 / sqrt(sumOfSquaredWeights). virtual double queryNorm(double sumOfSquaredWeights); - + /// Implemented as sqrt(freq). virtual double tf(double freq); - + /// Implemented as 1 / (distance + 1). virtual double sloppyFreq(int32_t distance); - + /// Implemented as log(numDocs / (docFreq + 1)) + 1. virtual double idf(int32_t docFreq, int32_t numDocs); - + /// Implemented as overlap / maxOverlap. virtual double coord(int32_t overlap, int32_t maxOverlap); - + /// Determines whether overlap tokens (Tokens with 0 position increment) are ignored when computing /// norm. By default this is false, meaning overlap tokens are counted just like non-overlap tokens. /// @see #computeNorm void setDiscountOverlaps(bool v); - + /// @see #setDiscountOverlaps bool getDiscountOverlaps(); }; diff --git a/include/DefaultSkipListReader.h b/include/DefaultSkipListReader.h index 811ef343..c0a29b99 100644 --- a/include/DefaultSkipListReader.h +++ b/include/DefaultSkipListReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,41 +17,41 @@ namespace Lucene public: DefaultSkipListReader(IndexInputPtr skipStream, int32_t maxSkipLevels, int32_t skipInterval); virtual ~DefaultSkipListReader(); - + LUCENE_CLASS(DefaultSkipListReader); - + protected: bool currentFieldStoresPayloads; Collection freqPointer; Collection proxPointer; Collection payloadLength; - + int64_t lastFreqPointer; int64_t lastProxPointer; int32_t lastPayloadLength; - + public: void init(int64_t skipPointer, int64_t freqBasePointer, int64_t proxBasePointer, int32_t df, bool storesPayloads); - - /// Returns the freq pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} + + /// Returns the freq pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} /// has skipped. int64_t getFreqPointer(); - - /// Returns the prox pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} + + /// Returns the prox pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} /// has skipped. int64_t getProxPointer(); - - /// Returns the payload length of the payload stored just before the doc to which the last call of {@link + + /// Returns the payload length of the payload stored just before the doc to which the last call of {@link /// MultiLevelSkipListReader#skipTo(int)} has skipped. int32_t getPayloadLength(); - + protected: /// Seeks the skip entry on the given level virtual void seekChild(int32_t level); - + /// Copies the values of the last read skip entry on this level virtual void setLastSkipData(int32_t level); - + /// Subclasses must implement the actual skip data encoding in this method. virtual int32_t readSkipData(int32_t level, IndexInputPtr skipStream); }; diff --git a/include/DefaultSkipListWriter.h b/include/DefaultSkipListWriter.h index ae627fff..48f443e9 100644 --- a/include/DefaultSkipListWriter.h +++ b/include/DefaultSkipListWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,31 +17,31 @@ namespace Lucene public: DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, IndexOutputPtr freqOutput, IndexOutputPtr proxOutput); virtual ~DefaultSkipListWriter(); - + LUCENE_CLASS(DefaultSkipListWriter); - + protected: Collection lastSkipDoc; Collection lastSkipPayloadLength; Collection lastSkipFreqPointer; Collection lastSkipProxPointer; - + IndexOutputPtr freqOutput; IndexOutputPtr proxOutput; - + int32_t curDoc; bool curStorePayloads; int32_t curPayloadLength; int64_t curFreqPointer; int64_t curProxPointer; - + public: void setFreqOutput(IndexOutputPtr freqOutput); void setProxOutput(IndexOutputPtr proxOutput); - + /// Sets the values for the current skip data. void setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength); - + protected: virtual void resetSkip(); virtual void writeSkipData(int32_t level, IndexOutputPtr skipBuffer); diff --git a/include/Directory.h b/include/Directory.h index a0c32f12..81f86ae3 100644 --- a/include/Directory.h +++ b/include/Directory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,96 +11,96 @@ namespace Lucene { - /// A Directory is a flat list of files. Files may be written once, when they are created. Once a file - /// is created it may only be opened for read, or deleted. Random access is permitted both when reading - /// and writing. Directory locking is implemented by an instance of {@link LockFactory}, and can be changed + /// A Directory is a flat list of files. Files may be written once, when they are created. Once a file + /// is created it may only be opened for read, or deleted. Random access is permitted both when reading + /// and writing. Directory locking is implemented by an instance of {@link LockFactory}, and can be changed /// for each Directory instance using {@link #setLockFactory}. class LPPAPI Directory : public LuceneObject { public: Directory(); virtual ~Directory(); - + LUCENE_CLASS(Directory); - + protected: bool isOpen; - + /// Holds the LockFactory instance (implements locking for this Directory instance). LockFactoryPtr lockFactory; - + public: /// Returns an array of strings, one for each file in the directory. virtual HashSet listAll() = 0; - + /// Returns true if a file with the given name exists. virtual bool fileExists(const String& name) = 0; - + /// Returns the time the named file was last modified. virtual uint64_t fileModified(const String& name) = 0; - + /// Set the modified time of an existing file to now. virtual void touchFile(const String& name) = 0; - + /// Removes an existing file in the directory. virtual void deleteFile(const String& name) = 0; - + /// Returns the length of a file in the directory. virtual int64_t fileLength(const String& name) = 0; - + /// Creates a new, empty file in the directory with the given name. /// Returns a stream writing this file. virtual IndexOutputPtr createOutput(const String& name) = 0; - + /// Returns a stream reading an existing file. virtual IndexInputPtr openInput(const String& name) = 0; - + /// Closes the store. virtual void close() = 0; - - /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit + + /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit /// changes to the index, to prevent a machine/OS crash from corrupting the index. virtual void sync(const String& name); - - /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory - /// implementation may ignore the buffer size. Currently the only Directory implementations that respect + + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory + /// implementation may ignore the buffer size. Currently the only Directory implementations that respect /// this parameter are {@link FSDirectory} and {@link CompoundFileReader}. virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - + /// Construct a {@link Lock}. /// @param name the name of the lock file. virtual LockPtr makeLock(const String& name); - - /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you + + /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you /// are certain this lock is no longer in use. /// @param name name of the lock to be cleared. void clearLock(const String& name); - - /// Set the LockFactory that this Directory instance should use for its locking implementation. Each * instance - /// of LockFactory should only be used for one directory (ie, do not share a single instance across multiple + + /// Set the LockFactory that this Directory instance should use for its locking implementation. Each * instance + /// of LockFactory should only be used for one directory (ie, do not share a single instance across multiple /// Directories). /// @param lockFactory instance of {@link LockFactory}. void setLockFactory(LockFactoryPtr lockFactory); - - /// Get the LockFactory that this Directory instance is using for its locking implementation. Note that this - /// may be null for Directory implementations that provide their own locking implementation. + + /// Get the LockFactory that this Directory instance is using for its locking implementation. Note that this + /// may be null for Directory implementations that provide their own locking implementation. LockFactoryPtr getLockFactory(); - - /// Return a string identifier that uniquely differentiates this Directory instance from other Directory - /// instances. This ID should be the same if two Directory instances are considered "the same index". + + /// Return a string identifier that uniquely differentiates this Directory instance from other Directory + /// instances. This ID should be the same if two Directory instances are considered "the same index". /// This is how locking "scopes" to the right index. virtual String getLockID(); - + virtual String toString(); - - /// Copy contents of a directory src to a directory dest. If a file in src already exists in dest then the one + + /// Copy contents of a directory src to a directory dest. If a file in src already exists in dest then the one /// in dest will be blindly overwritten. NOTE: the source directory cannot change while this method is running. /// Otherwise the results are undefined. /// @param src source directory. /// @param dest destination directory. /// @param closeDirSrc if true, call {@link #close()} method on source directory. static void copy(DirectoryPtr src, DirectoryPtr dest, bool closeDirSrc); - + protected: /// @throws AlreadyClosed if this Directory is closed. void ensureOpen(); diff --git a/include/DirectoryReader.h b/include/DirectoryReader.h index bfd3cc26..524d10e9 100644 --- a/include/DirectoryReader.h +++ b/include/DirectoryReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,19 +21,19 @@ namespace Lucene public: /// Construct reading the named set of readers. DirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); - + /// Used by near real-time search. DirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor); - + /// This constructor is only used for {@link #reopen()} - DirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, - Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, + DirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, + Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, bool doClone, int32_t termInfosIndexDivisor); - + virtual ~DirectoryReader(); - + LUCENE_CLASS(DirectoryReader); - + protected: DirectoryPtr _directory; bool readOnly; @@ -45,272 +45,272 @@ namespace Lucene SegmentInfosPtr segmentInfosStart; bool stale; int32_t termInfosIndexDivisor; - + bool rollbackHasChanges; - + Collection subReaders; Collection starts; // 1st docno for each segment MapStringByteArray normsCache; int32_t _maxDoc; int32_t _numDocs; bool _hasDeletions; - - // Max version in index as of when we opened; this can be > our current segmentInfos version + + // Max version in index as of when we opened; this can be > our current segmentInfos version // in case we were opened on a past IndexCommit int64_t maxIndexVersion; - + public: void _initialize(Collection subReaders); - + static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual LuceneObjectPtr clone(bool openReadOnly, LuceneObjectPtr other = LuceneObjectPtr()); - + virtual IndexReaderPtr reopen(); virtual IndexReaderPtr reopen(bool openReadOnly); virtual IndexReaderPtr reopen(IndexCommitPtr commit); - + /// Version number when this IndexReader was opened. virtual int64_t getVersion(); - + /// Return an array of term frequency vectors for the specified document. virtual Collection getTermFreqVectors(int32_t docNumber); - + /// Return a term frequency vector for the specified document and field. virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays of the {@link TermFreqVector}. virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); - + /// Map all the term vectors for all fields in a Document virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); - + /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented in the IndexReader base class. /// @return true if the index is optimized; false otherwise virtual bool isOptimized(); - + /// Returns the number of documents in this index. virtual int32_t numDocs(); - + /// Returns one greater than the largest possible document number. virtual int32_t maxDoc(); - - /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what {@link Field}s to load and how they should be loaded. + + /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what {@link Field}s to load and how they should be loaded. virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); - - /// Returns true if document n has been deleted + + /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n); - + /// Returns true if any documents have been deleted virtual bool hasDeletions(); - + /// Find reader for doc n static int32_t readerIndex(int32_t n, Collection starts, int32_t numSubReaders); - + /// Returns true if there are norms stored for this field. virtual bool hasNorms(const String& field); - + /// Returns the byte-encoded normalization factor for the named field of every document. virtual ByteArray norms(const String& field); - + /// Reads the byte-encoded normalization factor for the named field of every document. virtual void norms(const String& field, ByteArray norms, int32_t offset); - + /// Returns an enumeration of all the terms in the index. virtual TermEnumPtr terms(); - + /// Returns an enumeration of all terms starting at a given term. virtual TermEnumPtr terms(TermPtr t); - + /// Returns the number of documents containing the term t. virtual int32_t docFreq(TermPtr t); - + /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs(); - + /// Returns an unpositioned {@link TermPositions} enumerator. virtual TermPositionsPtr termPositions(); - - /// Tries to acquire the WriteLock on this directory. this method is only valid if this + + /// Tries to acquire the WriteLock on this directory. this method is only valid if this /// IndexReader is directory owner. virtual void acquireWriteLock(); - + void startCommit(); void rollbackCommit(); - + /// Retrieve the String userData optionally passed to IndexWriter#commit. virtual MapStringString getCommitUserData(); - + /// Check whether any new changes have occurred to the index since this reader was opened. virtual bool isCurrent(); - - /// Get a list of unique field names that exist in this index and have the specified field + + /// Get a list of unique field names that exist in this index and have the specified field /// option information. virtual HashSet getFieldNames(FieldOption fieldOption); - + static HashSet getFieldNames(FieldOption fieldOption, Collection subReaders); - + /// Returns the sequential sub readers that this reader is logically composed of. virtual Collection getSequentialSubReaders(); - + /// Returns the directory this index resides in. virtual DirectoryPtr directory(); - + virtual int32_t getTermInfosIndexDivisor(); - + /// Return the IndexCommit that this reader has opened. virtual IndexCommitPtr getIndexCommit(); - + /// Returns all commit points that exist in the Directory. static Collection listCommits(DirectoryPtr dir); - + protected: IndexReaderPtr doReopenFromWriter(bool openReadOnly, IndexCommitPtr commit); IndexReaderPtr doReopen(bool openReadOnly, IndexCommitPtr commit); IndexReaderPtr doReopenNoWriter(bool openReadOnly, IndexCommitPtr commit); DirectoryReaderPtr doReopen(SegmentInfosPtr infos, bool doClone, bool openReadOnly); - + /// Implements deletion of the document numbered docNum. virtual void doDelete(int32_t docNum); - + /// Implements actual undeleteAll() in subclass. virtual void doUndeleteAll(); - + int32_t readerIndex(int32_t n); - + /// Implements setNorm in subclass. virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - + /// Commit changes resulting from delete, undeleteAll, or setNorm operations /// /// If an exception is hit, then either no changes or all changes will have been committed to the index (transactional semantics). virtual void doCommit(MapStringString commitUserData); - + /// Implements close. virtual void doClose(); - + friend class FindSegmentsReopen; }; - + class MultiTermEnum : public TermEnum { public: MultiTermEnum(IndexReaderPtr topReader, Collection readers, Collection starts, TermPtr t); virtual ~MultiTermEnum(); - + LUCENE_CLASS(MultiTermEnum); - + protected: SegmentMergeQueuePtr queue; TermPtr _term; int32_t _docFreq; - + public: IndexReaderWeakPtr _topReader; Collection matchingSegments; // null terminated array of matching segments - + public: /// Increments the enumeration to the next element. True if one exists. virtual bool next(); - + /// Returns the current Term in the enumeration. virtual TermPtr term(); - + /// Returns the docFreq of the current Term in the enumeration. virtual int32_t docFreq(); - + /// Closes the enumeration to further activity, freeing resources. virtual void close(); }; - + class MultiTermDocs : public TermPositions, public LuceneObject { public: MultiTermDocs(IndexReaderPtr topReader, Collection r, Collection s); virtual ~MultiTermDocs(); - + LUCENE_CLASS(MultiTermDocs); - + protected: IndexReaderWeakPtr _topReader; // used for matching TermEnum to TermDocs Collection readers; Collection starts; TermPtr term; - + int32_t base; int32_t pointer; - + Collection readerTermDocs; TermDocsPtr current; MultiTermEnumPtr tenum; // the term enum used for seeking int32_t matchingSegmentPos; // position into the matching segments from tenum SegmentMergeInfoPtr smi; // current segment mere info - + public: /// Returns the current document number. virtual int32_t doc(); - + /// Returns the frequency of the term within the current document. virtual int32_t freq(); /// Sets this to the data for a term. virtual void seek(TermPtr term); - + /// Sets this to the data for the current term in a {@link TermEnum}. virtual void seek(TermEnumPtr termEnum); - + /// Moves to the next pair in the enumeration. virtual bool next(); - - /// Attempts to read multiple entries from the enumeration, up to length of docs. + + /// Attempts to read multiple entries from the enumeration, up to length of docs. /// Optimized implementation. virtual int32_t read(Collection docs, Collection freqs); - + /// Skips entries to the first beyond the current whose document number is greater than or equal to target. virtual bool skipTo(int32_t target); - + /// Frees associated resources. virtual void close(); - + protected: virtual TermDocsPtr termDocs(int32_t i); virtual TermDocsPtr termDocs(IndexReaderPtr reader); }; - + class MultiTermPositions : public MultiTermDocs { public: MultiTermPositions(IndexReaderPtr topReader, Collection r, Collection s); virtual ~MultiTermPositions(); - + LUCENE_CLASS(MultiTermPositions); - + public: /// Returns next position in the current document. virtual int32_t nextPosition(); - + /// Returns the length of the payload at the current term position. virtual int32_t getPayloadLength(); - + /// Returns the payload data at the current term position. virtual ByteArray getPayload(ByteArray data, int32_t offset); - + /// Checks if a payload can be loaded at this position. virtual bool isPayloadAvailable(); - + protected: virtual TermDocsPtr termDocs(IndexReaderPtr reader); }; - + class ReaderCommit : public IndexCommit { public: ReaderCommit(SegmentInfosPtr infos, DirectoryPtr dir); virtual ~ReaderCommit(); - + LUCENE_CLASS(ReaderCommit); - + protected: String segmentsFileName; HashSet files; @@ -319,33 +319,33 @@ namespace Lucene int64_t version; bool _isOptimized; MapStringString userData; - + public: virtual String toString(); - + /// Returns true if this commit is an optimized index. virtual bool isOptimized(); - + /// Two IndexCommits are equal if both their Directory and versions are equal. virtual String getSegmentsFileName(); - + /// Returns all index files referenced by this commit point. virtual HashSet getFileNames(); - + /// Returns the {@link Directory} for the index. virtual DirectoryPtr getDirectory(); - + /// Returns the version for this IndexCommit. virtual int64_t getVersion(); - + /// Returns the generation (the _N in segments_N) for this IndexCommit. virtual int64_t getGeneration(); - + virtual bool isDeleted(); - + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. virtual MapStringString getUserData(); - + virtual void deleteCommit(); }; } diff --git a/include/DisjunctionMaxQuery.h b/include/DisjunctionMaxQuery.h index 5645ee75..9cbebc14 100644 --- a/include/DisjunctionMaxQuery.h +++ b/include/DisjunctionMaxQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,86 +11,86 @@ namespace Lucene { - /// A query that generates the union of documents produced by its subqueries, and that scores each - /// document with the maximum score for that document as produced by any subquery, plus a tie breaking - /// increment for any additional matching subqueries. This is useful when searching for a word in - /// multiple fields with different boost factors (so that the fields cannot be combined equivalently - /// into a single search field). We want the primary score to be the one associated with the highest - /// boost, not the sum of the field scores (as BooleanQuery would give). If the query is "albino - /// elephant" this ensures that "albino" matching one field and "elephant" matching another gets a - /// higher score than "albino" matching both fields. To get this result, use both BooleanQuery and - /// DisjunctionMaxQuery: for each term a DisjunctionMaxQuery searches for it in each field, while the - /// set of these DisjunctionMaxQuery's is combined into a BooleanQuery. The tie breaker capability + /// A query that generates the union of documents produced by its subqueries, and that scores each + /// document with the maximum score for that document as produced by any subquery, plus a tie breaking + /// increment for any additional matching subqueries. This is useful when searching for a word in + /// multiple fields with different boost factors (so that the fields cannot be combined equivalently + /// into a single search field). We want the primary score to be the one associated with the highest + /// boost, not the sum of the field scores (as BooleanQuery would give). If the query is "albino + /// elephant" this ensures that "albino" matching one field and "elephant" matching another gets a + /// higher score than "albino" matching both fields. To get this result, use both BooleanQuery and + /// DisjunctionMaxQuery: for each term a DisjunctionMaxQuery searches for it in each field, while the + /// set of these DisjunctionMaxQuery's is combined into a BooleanQuery. The tie breaker capability /// allows results that include the same term in multiple fields to be judged better than results that - /// include this term in only the best of those multiple fields, without confusing this with the better + /// include this term in only the best of those multiple fields, without confusing this with the better /// case of two different terms in the multiple fields. class LPPAPI DisjunctionMaxQuery : public Query { public: /// Creates a new empty DisjunctionMaxQuery. Use add() to add the subqueries. - /// @param tieBreakerMultiplier the score of each non-maximum disjunct for a document is multiplied - /// by this weight and added into the final score. If non-zero, the value should be small, on the - /// order of 0.1, which says that 10 occurrences of word in a lower-scored field that is also in a - /// higher scored field is just as good as a unique word in the lower scored field (ie., one that is + /// @param tieBreakerMultiplier the score of each non-maximum disjunct for a document is multiplied + /// by this weight and added into the final score. If non-zero, the value should be small, on the + /// order of 0.1, which says that 10 occurrences of word in a lower-scored field that is also in a + /// higher scored field is just as good as a unique word in the lower scored field (ie., one that is /// not in any higher scored field. DisjunctionMaxQuery(double tieBreakerMultiplier = 0.0); - + /// Creates a new DisjunctionMaxQuery /// @param disjuncts A Collection of all the disjuncts to add /// @param tieBreakerMultiplier The weight to give to each matching non-maximum disjunct DisjunctionMaxQuery(Collection disjuncts, double tieBreakerMultiplier); - + virtual ~DisjunctionMaxQuery(); - + LUCENE_CLASS(DisjunctionMaxQuery); - + protected: /// The subqueries Collection disjuncts; - + /// Multiple of the non-max disjunct scores added into our final score. Non-zero values support tie-breaking. double tieBreakerMultiplier; - + public: using Query::toString; - + /// Add a subquery to this disjunction /// @param query the disjunct added void add(QueryPtr query); - + /// Add a collection of disjuncts to this disjunction void add(Collection disjuncts); - + /// An iterator over the disjuncts Collection::iterator begin(); Collection::iterator end(); - + /// Create the Weight used to score us virtual WeightPtr createWeight(SearcherPtr searcher); - + /// Optimize our representation and our subqueries representations /// @param reader the IndexReader we query /// @return an optimized copy of us (which may not be a copy if there is nothing to optimize) virtual QueryPtr rewrite(IndexReaderPtr reader); - + /// Create a shallow copy of us - used in rewriting if necessary /// @return a copy of us (but reuse, don't copy, our subqueries) virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Adds all terms occurring in this query to the terms set. virtual void extractTerms(SetTerm terms); - + /// Pretty print us. /// @param field the field to which we are applied /// @return a string that shows what we do, of the form "(disjunct1 | disjunct2 | ... | disjunctn)^boost" virtual String toString(const String& field); - - /// @return true if other is a DisjunctionMaxQuery with the same boost and the same subqueries, in the + + /// @return true if other is a DisjunctionMaxQuery with the same boost and the same subqueries, in the /// same order, as us virtual bool equals(LuceneObjectPtr other); - + virtual int32_t hashCode(); - + friend class DisjunctionMaxWeight; }; } diff --git a/include/DisjunctionMaxScorer.h b/include/DisjunctionMaxScorer.h index 905727b7..abd6ecee 100644 --- a/include/DisjunctionMaxScorer.h +++ b/include/DisjunctionMaxScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,40 +20,40 @@ namespace Lucene public: DisjunctionMaxScorer(double tieBreakerMultiplier, SimilarityPtr similarity, Collection subScorers, int32_t numScorers); virtual ~DisjunctionMaxScorer(); - + LUCENE_CLASS(DisjunctionMaxScorer); - + protected: /// The scorers for subqueries that have remaining docs, kept as a min heap by number of next doc. Collection subScorers; int32_t numScorers; - + /// Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. double tieBreakerMultiplier; - + int32_t doc; - + public: virtual int32_t nextDoc(); virtual int32_t docID(); - + /// Determine the current document score. Initially invalid, until {@link #next()} is called the first time. /// @return the score of the current generated document virtual double score(); - + virtual int32_t advance(int32_t target); - + protected: /// Recursively iterate all subScorers that generated last doc computing sum and max void scoreAll(int32_t root, int32_t size, int32_t doc, Collection sum, Collection max); - + /// Organize subScorers into a min heap with scorers generating the earliest document on top. void heapify(); - - /// The subtree of subScorers at root is a min heap except possibly for its root element. Bubble the root + + /// The subtree of subScorers at root is a min heap except possibly for its root element. Bubble the root /// down as required to make the subtree a heap. void heapAdjust(int32_t root); - + /// Remove the root Scorer from subScorers and re-establish it as a heap void heapRemoveRoot(); }; diff --git a/include/DisjunctionSumScorer.h b/include/DisjunctionSumScorer.h index 1bcbbec3..9b603250 100644 --- a/include/DisjunctionSumScorer.h +++ b/include/DisjunctionSumScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,82 +11,82 @@ namespace Lucene { - /// A Scorer for OR like queries, counterpart of ConjunctionScorer. This Scorer implements {@link - /// Scorer#skipTo(int32_t)} and uses skipTo() on the given Scorers. + /// A Scorer for OR like queries, counterpart of ConjunctionScorer. This Scorer implements {@link + /// Scorer#skipTo(int32_t)} and uses skipTo() on the given Scorers. class DisjunctionSumScorer : public Scorer { public: DisjunctionSumScorer(Collection subScorers, int32_t minimumNrMatchers = 1); virtual ~DisjunctionSumScorer(); - + LUCENE_CLASS(DisjunctionSumScorer); - + protected: /// The number of subscorers. int32_t nrScorers; - + /// The subscorers. Collection subScorers; - + /// The minimum number of scorers that should match. int32_t minimumNrMatchers; - - /// The scorerDocQueue contains all subscorers ordered by their current doc(), with the minimum at - /// the top. The scorerDocQueue is initialized the first time next() or skipTo() is called. An exhausted + + /// The scorerDocQueue contains all subscorers ordered by their current doc(), with the minimum at + /// the top. The scorerDocQueue is initialized the first time next() or skipTo() is called. An exhausted /// scorer is immediately removed from the scorerDocQueue. If less than the minimumNrMatchers scorers /// remain in the scorerDocQueue next() and skipTo() return false. /// /// After each to call to next() or skipTo() currentSumScore is the total score of the current matching doc, /// nrMatchers is the number of matching scorers, and all scorers are after the matching doc, or are exhausted. ScorerDocQueuePtr scorerDocQueue; - + /// The document number of the current match. int32_t currentDoc; - + /// The number of subscorers that provide the current match. int32_t _nrMatchers; - + double currentScore; - + public: virtual void initialize(); - + virtual void score(CollectorPtr collector); virtual int32_t nextDoc(); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} + + /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} /// is called the first time. virtual double score(); - + virtual int32_t docID(); - - /// Returns the number of subscorers matching the current document. Initially invalid, until {@link #next()} + + /// Returns the number of subscorers matching the current document. Initially invalid, until {@link #next()} /// is called the first time. int32_t nrMatchers(); - - /// Advances to the first match beyond the current whose document number is greater than or equal to a given + + /// Advances to the first match beyond the current whose document number is greater than or equal to a given /// target. The implementation uses the skipTo() method on the subscorers. /// /// @param target The target document number. /// @return the document whose number is greater than or equal to the given target, or -1 if none exist. virtual int32_t advance(int32_t target); - + protected: /// Called the first time next() or skipTo() is called to initialize scorerDocQueue. void initScorerDocQueue(); - - /// Collects matching documents in a range. Hook for optimization. Note that {@link #next()} must be + + /// Collects matching documents in a range. Hook for optimization. Note that {@link #next()} must be /// called once before this method is called for the first time. /// @param collector The collector to which all matching documents are passed through. /// @param max Do not score documents past this. /// @return true if more matching documents may remain. virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); - - /// Advance all subscorers after the current document determined by the top of the scorerDocQueue. Repeat - /// until at least the minimum number of subscorers match on the same document and all subscorers are after - /// that document or are exhausted. On entry the scorerDocQueue has at least minimumNrMatchers available. + + /// Advance all subscorers after the current document determined by the top of the scorerDocQueue. Repeat + /// until at least the minimum number of subscorers match on the same document and all subscorers are after + /// that document or are exhausted. On entry the scorerDocQueue has at least minimumNrMatchers available. /// At least the scorer with the minimum document number will be advanced. - /// @return true if there is a match. In case there is a match, currentDoc, currentSumScore and nrMatchers + /// @return true if there is a match. In case there is a match, currentDoc, currentSumScore and nrMatchers /// describe the match. bool advanceAfterCurrent(); }; diff --git a/include/DocConsumer.h b/include/DocConsumer.h index e0c5e768..71b4ba2d 100644 --- a/include/DocConsumer.h +++ b/include/DocConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~DocConsumer(); - + LUCENE_CLASS(DocConsumer); - + public: virtual DocConsumerPerThreadPtr addThread(DocumentsWriterThreadStatePtr perThread) = 0; virtual void flush(Collection threads, SegmentWriteStatePtr state) = 0; diff --git a/include/DocConsumerPerThread.h b/include/DocConsumerPerThread.h index 7988c2d5..aba9275a 100644 --- a/include/DocConsumerPerThread.h +++ b/include/DocConsumerPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,15 +15,15 @@ namespace Lucene { public: virtual ~DocConsumerPerThread(); - + LUCENE_CLASS(DocConsumerPerThread); - + public: /// Process the document. If there is something for this document to be done in docID order, /// you should encapsulate that as a DocWriter and return it. /// DocumentsWriter then calls finish() on this object when it's its turn. virtual DocWriterPtr processDocument() = 0; - + virtual void abort() = 0; }; } diff --git a/include/DocFieldConsumer.h b/include/DocFieldConsumer.h index cd14243e..2e2974b9 100644 --- a/include/DocFieldConsumer.h +++ b/include/DocFieldConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,29 +15,29 @@ namespace Lucene { public: virtual ~DocFieldConsumer(); - + LUCENE_CLASS(DocFieldConsumer); - + protected: FieldInfosPtr fieldInfos; - + public: /// Called when DocumentsWriter decides to create a new segment virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; - + /// Called when DocumentsWriter decides to close the doc stores virtual void closeDocStore(SegmentWriteStatePtr state) = 0; - + /// Called when an aborting exception is hit virtual void abort() = 0; - + /// Add a new thread virtual DocFieldConsumerPerThreadPtr addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread) = 0; - + /// Called when DocumentsWriter is using too much RAM. The consumer should free RAM, if possible, returning /// true if any RAM was in fact freed. virtual bool freeRAM() = 0; - + virtual void setFieldInfos(FieldInfosPtr fieldInfos); }; } diff --git a/include/DocFieldConsumerPerField.h b/include/DocFieldConsumerPerField.h index 2e8866a9..46d15194 100644 --- a/include/DocFieldConsumerPerField.h +++ b/include/DocFieldConsumerPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,13 +15,13 @@ namespace Lucene { public: virtual ~DocFieldConsumerPerField(); - + LUCENE_CLASS(DocFieldConsumerPerField); - + public: /// Processes all occurrences of a single field virtual void processFields(Collection fields, int32_t count) = 0; - + virtual void abort() = 0; }; } diff --git a/include/DocFieldConsumerPerThread.h b/include/DocFieldConsumerPerThread.h index ab701262..d00b3ebd 100644 --- a/include/DocFieldConsumerPerThread.h +++ b/include/DocFieldConsumerPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~DocFieldConsumerPerThread(); - + LUCENE_CLASS(DocFieldConsumerPerThread); - + public: virtual void startDocument() = 0; virtual DocWriterPtr finishDocument() = 0; diff --git a/include/DocFieldConsumers.h b/include/DocFieldConsumers.h index e6949ac6..ce915e87 100644 --- a/include/DocFieldConsumers.h +++ b/include/DocFieldConsumers.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,51 +18,51 @@ namespace Lucene public: DocFieldConsumers(DocFieldConsumerPtr one, DocFieldConsumerPtr two); virtual ~DocFieldConsumers(); - + LUCENE_CLASS(DocFieldConsumers); - + public: DocFieldConsumerPtr one; DocFieldConsumerPtr two; - + Collection docFreeList; int32_t freeCount; int32_t allocCount; - + public: virtual void setFieldInfos(FieldInfosPtr fieldInfos); - + /// Called when DocumentsWriter decides to create a new segment virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state); - + /// Called when DocumentsWriter decides to close the doc stores virtual void closeDocStore(SegmentWriteStatePtr state); - + /// Called when DocumentsWriter is using too much RAM. virtual bool freeRAM(); - + /// Add a new thread virtual DocFieldConsumerPerThreadPtr addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread); - + DocFieldConsumersPerDocPtr getPerDoc(); void freePerDoc(DocFieldConsumersPerDocPtr perDoc); }; - + class DocFieldConsumersPerDoc : public DocWriter { public: DocFieldConsumersPerDoc(DocFieldConsumersPtr fieldConsumers); virtual ~DocFieldConsumersPerDoc(); - + LUCENE_CLASS(DocFieldConsumersPerDoc); - + protected: DocFieldConsumersWeakPtr _fieldConsumers; - + public: DocWriterPtr one; DocWriterPtr two; - + public: virtual int64_t sizeInBytes(); virtual void finish(); diff --git a/include/DocFieldConsumersPerField.h b/include/DocFieldConsumersPerField.h index e01bb10d..5bca578b 100644 --- a/include/DocFieldConsumersPerField.h +++ b/include/DocFieldConsumersPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,18 +16,18 @@ namespace Lucene public: DocFieldConsumersPerField(DocFieldConsumersPerThreadPtr perThread, DocFieldConsumerPerFieldPtr one, DocFieldConsumerPerFieldPtr two); virtual ~DocFieldConsumersPerField(); - + LUCENE_CLASS(DocFieldConsumersPerField); - + public: DocFieldConsumerPerFieldPtr one; DocFieldConsumerPerFieldPtr two; DocFieldConsumersPerThreadWeakPtr _perThread; - + public: /// Processes all occurrences of a single field virtual void processFields(Collection fields, int32_t count); - + virtual void abort(); }; } diff --git a/include/DocFieldConsumersPerThread.h b/include/DocFieldConsumersPerThread.h index e8c86a8f..b2eb8c85 100644 --- a/include/DocFieldConsumersPerThread.h +++ b/include/DocFieldConsumersPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,23 +14,23 @@ namespace Lucene class DocFieldConsumersPerThread : public DocFieldConsumerPerThread { public: - DocFieldConsumersPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, DocFieldConsumersPtr parent, + DocFieldConsumersPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, DocFieldConsumersPtr parent, DocFieldConsumerPerThreadPtr one, DocFieldConsumerPerThreadPtr two); virtual ~DocFieldConsumersPerThread(); - + LUCENE_CLASS(DocFieldConsumersPerThread); - + public: DocFieldConsumerPerThreadPtr one; DocFieldConsumerPerThreadPtr two; DocFieldConsumersWeakPtr _parent; DocStatePtr docState; - + public: virtual void startDocument(); virtual void abort(); virtual DocWriterPtr finishDocument(); - virtual DocFieldConsumerPerFieldPtr addField(FieldInfoPtr fi); + virtual DocFieldConsumerPerFieldPtr addField(FieldInfoPtr fi); }; } diff --git a/include/DocFieldProcessor.h b/include/DocFieldProcessor.h index 3bfcd05d..8dcfbf8a 100644 --- a/include/DocFieldProcessor.h +++ b/include/DocFieldProcessor.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,23 +11,23 @@ namespace Lucene { - /// This is a DocConsumer that gathers all fields under the same name, and calls per-field consumers to process - /// field by field. This class doesn't doesn't do any "real" work of its own: it just forwards the fields to a + /// This is a DocConsumer that gathers all fields under the same name, and calls per-field consumers to process + /// field by field. This class doesn't doesn't do any "real" work of its own: it just forwards the fields to a /// DocFieldConsumer. class DocFieldProcessor : public DocConsumer { public: DocFieldProcessor(DocumentsWriterPtr docWriter, DocFieldConsumerPtr consumer); virtual ~DocFieldProcessor(); - + LUCENE_CLASS(DocFieldProcessor); - + public: DocumentsWriterWeakPtr _docWriter; FieldInfosPtr fieldInfos; DocFieldConsumerPtr consumer; StoredFieldsWriterPtr fieldsWriter; - + public: virtual void closeDocStore(SegmentWriteStatePtr state); virtual void flush(Collection threads, SegmentWriteStatePtr state); diff --git a/include/DocFieldProcessorPerField.h b/include/DocFieldProcessorPerField.h index 08f6f50f..3ca88838 100644 --- a/include/DocFieldProcessorPerField.h +++ b/include/DocFieldProcessorPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,19 +17,19 @@ namespace Lucene public: DocFieldProcessorPerField(DocFieldProcessorPerThreadPtr perThread, FieldInfoPtr fieldInfo); virtual ~DocFieldProcessorPerField(); - + LUCENE_CLASS(DocFieldProcessorPerField); - + public: DocFieldConsumerPerFieldPtr consumer; FieldInfoPtr fieldInfo; - + DocFieldProcessorPerFieldPtr next; int32_t lastGen; - + int32_t fieldCount; Collection fields; - + public: virtual void abort(); }; diff --git a/include/DocFieldProcessorPerThread.h b/include/DocFieldProcessorPerThread.h index 2b3f9067..05e57dbd 100644 --- a/include/DocFieldProcessorPerThread.h +++ b/include/DocFieldProcessorPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// Gathers all Fieldables for a document under the same name, updates FieldInfos, and calls per-field + /// Gathers all Fieldables for a document under the same name, updates FieldInfos, and calls per-field /// consumers to process field by field. /// /// Currently, only a single thread visits the fields, sequentially, for processing. @@ -21,9 +21,9 @@ namespace Lucene public: DocFieldProcessorPerThread(DocumentsWriterThreadStatePtr threadState, DocFieldProcessorPtr docFieldProcessor); virtual ~DocFieldProcessorPerThread(); - + LUCENE_CLASS(DocFieldProcessorPerThread); - + public: double docBoost; int32_t fieldGen; @@ -32,50 +32,50 @@ namespace Lucene DocFieldConsumerPerThreadPtr consumer; Collection _fields; // Holds all fields seen in current doc int32_t fieldCount; - + Collection fieldHash; // Hash table for all fields ever seen int32_t hashMask; int32_t totalFieldCount; - + StoredFieldsWriterPerThreadPtr fieldsWriter; DocStatePtr docState; - + Collection docFreeList; int32_t freeCount; int32_t allocCount; - + public: virtual void initialize(); virtual void abort(); Collection fields(); - + // If there are fields we've seen but did not see again in the last run, then free them up. void trimFields(SegmentWriteStatePtr state); - + virtual DocWriterPtr processDocument(); - + DocFieldProcessorPerThreadPerDocPtr getPerDoc(); void freePerDoc(DocFieldProcessorPerThreadPerDocPtr perDoc); - + protected: void rehash(); }; - + class DocFieldProcessorPerThreadPerDoc : public DocWriter { public: DocFieldProcessorPerThreadPerDoc(DocFieldProcessorPerThreadPtr docProcessor); virtual ~DocFieldProcessorPerThreadPerDoc(); - + LUCENE_CLASS(DocFieldProcessorPerThreadPerDoc); - + public: DocWriterPtr one; DocWriterPtr two; - + protected: DocFieldProcessorPerThreadWeakPtr _docProcessor; - + public: virtual int64_t sizeInBytes(); virtual void finish(); diff --git a/include/DocIdBitSet.h b/include/DocIdBitSet.h index f6a1140a..1d620b80 100644 --- a/include/DocIdBitSet.h +++ b/include/DocIdBitSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,23 +17,23 @@ namespace Lucene public: DocIdBitSet(); DocIdBitSet(BitSetPtr bitSet); - + virtual ~DocIdBitSet(); - + LUCENE_CLASS(DocIdBitSet); - + protected: BitSetPtr bitSet; - + public: virtual DocIdSetIteratorPtr iterator(); - + /// This DocIdSet implementation is cacheable. virtual bool isCacheable(); - + /// Returns the underlying BitSet. BitSetPtr getBitSet(); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); diff --git a/include/DocIdSet.h b/include/DocIdSet.h index c4022cca..f4fe9e64 100644 --- a/include/DocIdSet.h +++ b/include/DocIdSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,25 +11,25 @@ namespace Lucene { - /// A DocIdSet contains a set of doc ids. Implementing classes must only implement {@link #iterator} to - /// provide access to the set. + /// A DocIdSet contains a set of doc ids. Implementing classes must only implement {@link #iterator} to + /// provide access to the set. class LPPAPI DocIdSet : public LuceneObject { public: virtual ~DocIdSet(); LUCENE_CLASS(DocIdSet); - + public: /// Provides a {@link DocIdSetIterator} to access the set. This implementation can return null or /// {@link #EmptyDocIdSet}.iterator() if there are no docs that match. virtual DocIdSetIteratorPtr iterator() = 0; - - /// This method is a hint for {@link CachingWrapperFilter}, if this DocIdSet should be cached without + + /// This method is a hint for {@link CachingWrapperFilter}, if this DocIdSet should be cached without /// copying it into a BitSet. The default is to return false. If you have an own DocIdSet implementation - /// that does its iteration very effective and fast without doing disk I/O, override this method and + /// that does its iteration very effective and fast without doing disk I/O, override this method and /// return true. virtual bool isCacheable(); - + /// An empty {@code DocIdSet} instance for easy use, eg. in Filters that hit no documents. static DocIdSetPtr EMPTY_DOCIDSET(); }; diff --git a/include/DocIdSetIterator.h b/include/DocIdSetIterator.h index 69fac733..4835aafa 100644 --- a/include/DocIdSetIterator.h +++ b/include/DocIdSetIterator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,21 +11,21 @@ namespace Lucene { - /// This abstract class defines methods to iterate over a set of non-decreasing doc ids. Note that this class - /// assumes it iterates on doc Ids, and therefore {@link #NO_MORE_DOCS} is set to {@value #NO_MORE_DOCS} in order to + /// This abstract class defines methods to iterate over a set of non-decreasing doc ids. Note that this class + /// assumes it iterates on doc Ids, and therefore {@link #NO_MORE_DOCS} is set to {@value #NO_MORE_DOCS} in order to /// be used as a sentinel object. Implementations of this class are expected to consider INT_MAX as an invalid value. class LPPAPI DocIdSetIterator : public LuceneObject { public: virtual ~DocIdSetIterator(); - + LUCENE_CLASS(DocIdSetIterator); - + public: - /// When returned by {@link #nextDoc()}, {@link #advance(int)} and {@link #docID()} it means there are no more + /// When returned by {@link #nextDoc()}, {@link #advance(int)} and {@link #docID()} it means there are no more /// docs in the iterator. static const int32_t NO_MORE_DOCS; - + public: /// Returns the following: ///
    @@ -34,15 +34,15 @@ namespace Lucene ///
  • Otherwise it should return the doc ID it is currently on. ///
virtual int32_t docID() = 0; - - /// Advances to the next document in the set and returns the doc it is currently on, or {@link #NO_MORE_DOCS} + + /// Advances to the next document in the set and returns the doc it is currently on, or {@link #NO_MORE_DOCS} /// if there are no more docs in the set. /// - /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted + /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted /// behaviour. virtual int32_t nextDoc() = 0; - - /// Advances to the first beyond the current whose document number is greater than or equal to target. Returns + + /// Advances to the first beyond the current whose document number is greater than or equal to target. Returns /// the current document number or {@link #NO_MORE_DOCS} if there are no more docs in the set. /// /// Behaves as if written: @@ -59,14 +59,14 @@ namespace Lucene /// /// Some implementations are considerably more efficient than that. /// - /// NOTE: certain implementations may return a different value (each time) if called several times in a row + /// NOTE: certain implementations may return a different value (each time) if called several times in a row /// with the same target. /// - /// NOTE: this method may be called with {@value #NO_MORE_DOCS} for efficiency by some Scorers. If your - /// implementation cannot efficiently determine that it should exhaust, it is recommended that you check for + /// NOTE: this method may be called with {@value #NO_MORE_DOCS} for efficiency by some Scorers. If your + /// implementation cannot efficiently determine that it should exhaust, it is recommended that you check for /// that value in each call to this method. /// - /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted + /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted /// behaviour. virtual int32_t advance(int32_t target) = 0; }; diff --git a/include/DocInverter.h b/include/DocInverter.h index 321bd85a..f9c67ca0 100644 --- a/include/DocInverter.h +++ b/include/DocInverter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,28 +18,28 @@ namespace Lucene public: DocInverter(InvertedDocConsumerPtr consumer, InvertedDocEndConsumerPtr endConsumer); virtual ~DocInverter(); - + LUCENE_CLASS(DocInverter); - + public: InvertedDocConsumerPtr consumer; InvertedDocEndConsumerPtr endConsumer; - + public: virtual void setFieldInfos(FieldInfosPtr fieldInfos); - + /// Called when DocumentsWriter decides to create a new segment virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state); - + /// Called when DocumentsWriter decides to close the doc stores virtual void closeDocStore(SegmentWriteStatePtr state); - + /// Called when an aborting exception is hit virtual void abort(); - + /// Called when DocumentsWriter is using too much RAM. virtual bool freeRAM(); - + /// Add a new thread virtual DocFieldConsumerPerThreadPtr addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread); }; diff --git a/include/DocInverterPerField.h b/include/DocInverterPerField.h index bdb0c92e..01c855b2 100644 --- a/include/DocInverterPerField.h +++ b/include/DocInverterPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// Holds state for inverting all occurrences of a single field in the document. This class doesn't do + /// Holds state for inverting all occurrences of a single field in the document. This class doesn't do /// anything itself; instead, it forwards the tokens produced by analysis to its own consumer /// (InvertedDocConsumerPerField). It also interacts with an endConsumer (InvertedDocEndConsumerPerField). class DocInverterPerField : public DocFieldConsumerPerField @@ -19,23 +19,23 @@ namespace Lucene public: DocInverterPerField(DocInverterPerThreadPtr perThread, FieldInfoPtr fieldInfo); virtual ~DocInverterPerField(); - + LUCENE_CLASS(DocInverterPerField); - + protected: DocInverterPerThreadWeakPtr _perThread; FieldInfoPtr fieldInfo; - + public: InvertedDocConsumerPerFieldPtr consumer; InvertedDocEndConsumerPerFieldPtr endConsumer; DocStatePtr docState; FieldInvertStatePtr fieldState; - + public: virtual void initialize(); virtual void abort(); - + /// Processes all occurrences of a single field virtual void processFields(Collection fields, int32_t count); }; diff --git a/include/DocInverterPerThread.h b/include/DocInverterPerThread.h index 76886009..c5adaa9e 100644 --- a/include/DocInverterPerThread.h +++ b/include/DocInverterPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,41 +19,41 @@ namespace Lucene public: DocInverterPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, DocInverterPtr docInverter); virtual ~DocInverterPerThread(); - + LUCENE_CLASS(DocInverterPerThread); - + public: DocInverterWeakPtr _docInverter; InvertedDocConsumerPerThreadPtr consumer; InvertedDocEndConsumerPerThreadPtr endConsumer; SingleTokenAttributeSourcePtr singleToken; - + DocStatePtr docState; FieldInvertStatePtr fieldState; - + /// Used to read a string value for a field ReusableStringReaderPtr stringReader; - + public: virtual void initialize(); virtual void startDocument(); virtual DocWriterPtr finishDocument(); virtual void abort(); - virtual DocFieldConsumerPerFieldPtr addField(FieldInfoPtr fi); + virtual DocFieldConsumerPerFieldPtr addField(FieldInfoPtr fi); }; - + class SingleTokenAttributeSource : public AttributeSource { public: SingleTokenAttributeSource(); virtual ~SingleTokenAttributeSource(); - + LUCENE_CLASS(SingleTokenAttributeSource); - + public: TermAttributePtr termAttribute; OffsetAttributePtr offsetAttribute; - + public: void reinit(const String& stringValue, int32_t startOffset, int32_t endOffset); }; diff --git a/include/DocValues.h b/include/DocValues.h index fd82aa26..5f5d87a6 100644 --- a/include/DocValues.h +++ b/include/DocValues.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,57 +11,57 @@ namespace Lucene { - /// Represents field values as different types. Normally created via a {@link ValueSuorce} for a + /// Represents field values as different types. Normally created via a {@link ValueSuorce} for a /// particular field and reader. /// - /// DocValues is distinct from ValueSource because there needs to be an object created at query + /// DocValues is distinct from ValueSource because there needs to be an object created at query /// evaluation time that is not referenced by the query itself because: /// - Query objects should be MT safe - /// - For caching, Query objects are often used as keys... you don't want the Query carrying around + /// - For caching, Query objects are often used as keys... you don't want the Query carrying around /// big objects class LPPAPI DocValues : public LuceneObject { public: DocValues(); virtual ~DocValues(); - + LUCENE_CLASS(DocValues); - + protected: double minVal; double maxVal; double avgVal; bool computed; - + public: using LuceneObject::toString; - - /// Return doc value as a double. - /// Mandatory: every DocValues implementation must implement at least this method. - /// @param doc document whose double value is requested. + + /// Return doc value as a double. + /// Mandatory: every DocValues implementation must implement at least this method. + /// @param doc document whose double value is requested. virtual double doubleVal(int32_t doc) = 0; - - /// Return doc value as an int. - /// Optional: DocValues implementation can (but don't have to) override this method. + + /// Return doc value as an int. + /// Optional: DocValues implementation can (but don't have to) override this method. /// @param doc document whose int value is requested. virtual int32_t intVal(int32_t doc); - - /// Return doc value as a long. - /// Optional: DocValues implementation can (but don't have to) override this method. + + /// Return doc value as a long. + /// Optional: DocValues implementation can (but don't have to) override this method. /// @param doc document whose long value is requested. virtual int64_t longVal(int32_t doc); - - /// Return doc value as a string. - /// Optional: DocValues implementation can (but don't have to) override this method. + + /// Return doc value as a string. + /// Optional: DocValues implementation can (but don't have to) override this method. /// @param doc document whose string value is requested. virtual String strVal(int32_t doc); - + /// Return a string representation of a doc value, as required for Explanations. virtual String toString(int32_t doc) = 0; - + /// Explain the scoring value for the input doc. virtual ExplanationPtr explain(int32_t doc); - + /// For test purposes only, return the inner array of values, or null if not applicable. /// /// Allows tests to verify that loaded values are: @@ -70,25 +70,25 @@ namespace Lucene ///
  • stored in the expected size/type (byte/short/int/float). /// /// - /// Note: implementations of DocValues must override this method for these test elements to be tested, + /// Note: implementations of DocValues must override this method for these test elements to be tested, /// Otherwise the test would not fail, just print a warning. virtual CollectionValue getInnerArray(); - + /// Returns the minimum of all values or NaN if this DocValues instance does not contain any value. /// This operation is optional /// @return the minimum of all values or NaN if this DocValues instance does not contain any value. virtual double getMinValue(); - + /// Returns the maximum of all values or NaN if this DocValues instance does not contain any value. /// This operation is optional /// @return the maximum of all values or NaN if this DocValues instance does not contain any value. virtual double getMaxValue(); - + /// Returns the average of all values or NaN if this DocValues instance does not contain any value. /// This operation is optional /// @return the average of all values or NaN if this DocValues instance does not contain any value. virtual double getAverageValue(); - + protected: /// Compute optional values void compute(); diff --git a/include/Document.h b/include/Document.h index 328ed61a..d61bfbeb 100644 --- a/include/Document.h +++ b/include/Document.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,12 +13,12 @@ namespace Lucene { /// Documents are the unit of indexing and search. /// - /// A Document is a set of fields. Each field has a name and a textual value. A field may be {@link - /// Fieldable#isStored() stored} with the document, in which case it is returned with search hits on the - /// document. Thus each document should typically contain one or more stored fields which uniquely + /// A Document is a set of fields. Each field has a name and a textual value. A field may be {@link + /// Fieldable#isStored() stored} with the document, in which case it is returned with search hits on the + /// document. Thus each document should typically contain one or more stored fields which uniquely /// identify it. /// - /// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents + /// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents /// retrieved from the index, eg. with {@link ScoreDoc#doc}, {@link Searcher#doc(int)} or {@link /// IndexReader#document(int)}. class LPPAPI Document : public LuceneObject @@ -26,114 +26,114 @@ namespace Lucene public: /// Constructs a new document with no fields. Document(); - + virtual ~Document(); - + LUCENE_CLASS(Document); - + protected: Collection fields; double boost; - + public: - /// Sets a boost factor for hits on any field of this document. This value will be multiplied into the + /// Sets a boost factor for hits on any field of this document. This value will be multiplied into the /// score of all hits on this document. /// /// The default value is 1.0. /// - /// Values are multiplied into the value of {@link Fieldable#getBoost()} of each field in this document. + /// Values are multiplied into the value of {@link Fieldable#getBoost()} of each field in this document. /// Thus, this method in effect sets a default boost for the fields of this document. /// /// @see Fieldable#setBoost(double) void setBoost(double boost); - - /// Returns, at indexing time, the boost factor as set by {@link #setBoost(double)}. + + /// Returns, at indexing time, the boost factor as set by {@link #setBoost(double)}. /// - /// Note that once a document is indexed this value is no longer available from the index. At search time, - /// for retrieved documents, this method always returns 1. This however does not mean that the boost value - /// set at indexing time was ignored - it was just combined with other indexing time factors and stored - /// elsewhere, for better indexing and search performance. (For more information see the "norm(t,d)" part + /// Note that once a document is indexed this value is no longer available from the index. At search time, + /// for retrieved documents, this method always returns 1. This however does not mean that the boost value + /// set at indexing time was ignored - it was just combined with other indexing time factors and stored + /// elsewhere, for better indexing and search performance. (For more information see the "norm(t,d)" part /// of the scoring formula in {@link Similarity}.) /// /// @see #setBoost(double) double getBoost(); - - /// Adds a field to a document. Several fields may be added with the same name. In this case, if the fields + + /// Adds a field to a document. Several fields may be added with the same name. In this case, if the fields /// are indexed, their text is treated as though appended for the purposes of search. /// - /// Note that add like the removeField(s) methods only makes sense prior to adding a document to an index. - /// These methods cannot be used to change the content of an existing index! In order to achieve this, a + /// Note that add like the removeField(s) methods only makes sense prior to adding a document to an index. + /// These methods cannot be used to change the content of an existing index! In order to achieve this, a /// document has to be deleted from an index and a new changed version of that document has to be added. void add(FieldablePtr field); - - /// Removes field with the specified name from the document. If multiple fields exist with this name, this - /// method removes the first field that has been added. If there is no field with the specified name, the + + /// Removes field with the specified name from the document. If multiple fields exist with this name, this + /// method removes the first field that has been added. If there is no field with the specified name, the /// document remains unchanged. /// - /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to - /// an index. These methods cannot be used to change the content of an existing index! In order to achieve + /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to + /// an index. These methods cannot be used to change the content of an existing index! In order to achieve /// this, a document has to be deleted from an index and a new changed version of that document has to be added. void removeField(const String& name); - - /// Removes all fields with the given name from the document. If there is no field with the specified name, + + /// Removes all fields with the given name from the document. If there is no field with the specified name, /// the document remains unchanged. /// - /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to an + /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to an /// index. These methods cannot be used to change the content of an existing index! In order to achieve this, /// a document has to be deleted from an index and a new changed version of that document has to be added. void removeFields(const String& name); - - /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with + + /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with /// this name, this method returns the first value added. /// Do not use this method with lazy loaded fields. FieldPtr getField(const String& name); - - /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with + + /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with /// this name, this method returns the first value added. FieldablePtr getFieldable(const String& name); - - /// Returns the string value of the field with the given name if any exist in this document, or null. If multiple + + /// Returns the string value of the field with the given name if any exist in this document, or null. If multiple /// fields exist with this name, this method returns the first value added. If only binary fields with this name /// exist, returns null. String get(const String& name); - + /// Returns a List of all the fields in a document. /// - /// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents + /// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents /// retrieved from the index, eg. {@link Searcher#doc(int)} or {@link IndexReader#document(int)}. Collection getFields(); - - /// Returns an array of {@link Field}s with the given name. Do not use with lazy loaded fields. This method + + /// Returns an array of {@link Field}s with the given name. Do not use with lazy loaded fields. This method /// returns an empty array when there are no matching fields. It never returns null. /// @param name the name of the field /// @return a Field[] array Collection getFields(const String& name); - + /// Returns an array of {@link Fieldable}s with the given name. /// This method returns an empty array when there are no matching fields. It never returns null. /// @param name the name of the field /// @return a Fieldable[] array Collection getFieldables(const String& name); - + /// Returns an array of values of the field specified as the method parameter. /// This method returns an empty array when there are no matching fields. It never returns null. /// @param name the name of the field /// @return a String[] of field values Collection getValues(const String& name); - - /// Returns an array of byte arrays for of the fields that have the name specified as the method parameter. + + /// Returns an array of byte arrays for of the fields that have the name specified as the method parameter. /// This method returns an empty array when there are no matching fields. It never returns null. /// @param name the name of the field /// @return a byte[][] of binary field values Collection getBinaryValues(const String& name); - - /// Returns an array of bytes for the first (or only) field that has the name specified as the method parameter. - /// This method will return null if no binary fields with the specified name are available. There may be + + /// Returns an array of bytes for the first (or only) field that has the name specified as the method parameter. + /// This method will return null if no binary fields with the specified name are available. There may be /// non-binary fields with the same name. /// @param name the name of the field. /// @return a byte[] containing the binary field value or null ByteArray getBinaryValue(const String& name); - + /// Returns a string representation of the object virtual String toString(); }; diff --git a/include/DocumentsWriter.h b/include/DocumentsWriter.h index 1f2d8de5..7d22aa25 100644 --- a/include/DocumentsWriter.h +++ b/include/DocumentsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,14 +13,14 @@ namespace Lucene { /// This class accepts multiple added documents and directly writes a single segment file. It does this more - /// efficiently than creating a single segment per document (with DocumentWriter) and doing standard merges on + /// efficiently than creating a single segment per document (with DocumentWriter) and doing standard merges on /// those segments. /// - /// Each added document is passed to the {@link DocConsumer}, which in turn processes the document and interacts + /// Each added document is passed to the {@link DocConsumer}, which in turn processes the document and interacts /// with other consumers in the indexing chain. Certain consumers, like {@link StoredFieldsWriter} and {@link /// TermVectorsTermsWriter}, digest a document and immediately write bytes to the "doc store" files (ie, /// they do not consume RAM per document, except while they are processing the document). - /// + /// /// Other consumers, eg {@link FreqProxTermsWriter} and {@link NormsWriter}, buffer bytes in RAM and flush only /// when a new segment is produced. /// @@ -28,128 +28,128 @@ namespace Lucene /// flushing by doc count instead of RAM usage), we create a real segment and flush it to the Directory. /// /// Threads: - /// Multiple threads are allowed into addDocument at once. There is an initial synchronized call to - /// getThreadState which allocates a ThreadState for this thread. The same thread will get the same ThreadState - /// over time (thread affinity) so that if there are consistent patterns (for example each thread is indexing a - /// different content source) then we make better use of RAM. Then processDocument is called on that ThreadState - /// without synchronization (most of the "heavy lifting" is in this call). Finally the synchronized + /// Multiple threads are allowed into addDocument at once. There is an initial synchronized call to + /// getThreadState which allocates a ThreadState for this thread. The same thread will get the same ThreadState + /// over time (thread affinity) so that if there are consistent patterns (for example each thread is indexing a + /// different content source) then we make better use of RAM. Then processDocument is called on that ThreadState + /// without synchronization (most of the "heavy lifting" is in this call). Finally the synchronized /// "finishDocument" is called to flush changes to the directory. /// - /// When flush is called by IndexWriter we forcefully idle all threads and flush only once they are all idle. - /// This means you can call flush with a given thread even while other threads are actively adding/deleting + /// When flush is called by IndexWriter we forcefully idle all threads and flush only once they are all idle. + /// This means you can call flush with a given thread even while other threads are actively adding/deleting /// documents. /// /// Exceptions: /// Because this class directly updates in-memory posting lists, and flushes stored fields and term vectors /// directly to files in the directory, there are certain limited times when an exception can corrupt this state. - /// For example, a disk full while flushing stored fields leaves this file in a corrupt state. Or, an - /// std::bad_alloc exception while appending to the in-memory posting lists can corrupt that posting list. - /// We call such exceptions "aborting exceptions". In these cases we must call abort() to discard all docs added + /// For example, a disk full while flushing stored fields leaves this file in a corrupt state. Or, an + /// std::bad_alloc exception while appending to the in-memory posting lists can corrupt that posting list. + /// We call such exceptions "aborting exceptions". In these cases we must call abort() to discard all docs added /// since the last flush. /// /// All other exceptions ("non-aborting exceptions") can still partially update the index structures. These /// updates are consistent, but, they represent only a part of the document seen up until the exception was hit. - /// When this happens, we immediately mark the document as deleted so that the document is always atomically + /// When this happens, we immediately mark the document as deleted so that the document is always atomically /// ("all or none") added to the index. class DocumentsWriter : public LuceneObject { public: DocumentsWriter(DirectoryPtr directory, IndexWriterPtr writer, IndexingChainPtr indexingChain); virtual ~DocumentsWriter(); - + LUCENE_CLASS(DocumentsWriter); - + protected: String docStoreSegment; // Current doc-store segment we are writing int32_t docStoreOffset; // Current starting doc-store offset of current segment - + int32_t nextDocID; // Next docID to be added int32_t numDocsInRAM; // # docs buffered in RAM - + /// Max # ThreadState instances; if there are more threads than this they share ThreadStates static const int32_t MAX_THREAD_STATE; Collection threadStates; MapThreadDocumentsWriterThreadState threadBindings; - + int32_t pauseThreads; // Non-zero when we need all threads to pause (eg to flush) bool aborting; // True if an abort is pending - + DocFieldProcessorPtr docFieldProcessor; - + /// Deletes done after the last flush; these are discarded on abort BufferedDeletesPtr deletesInRAM; - + /// Deletes done before the last flush; these are still kept on abort BufferedDeletesPtr deletesFlushed; - + /// The max number of delete terms that can be buffered before they must be flushed to disk. int32_t maxBufferedDeleteTerms; - + /// How much RAM we can use before flushing. This is 0 if we are flushing by doc count instead. int64_t ramBufferSize; int64_t waitQueuePauseBytes; int64_t waitQueueResumeBytes; - + /// If we've allocated 5% over our RAM budget, we then free down to 95% int64_t freeTrigger; int64_t freeLevel; - + /// Flush @ this number of docs. If ramBufferSize is non-zero we will flush by RAM usage instead. int32_t maxBufferedDocs; - + /// How many docs already flushed to index int32_t flushedDocCount; - + bool closed; - + /// List of files that were written before last abort() HashSet _abortedFiles; SegmentWriteStatePtr flushState; - + Collection freeIntBlocks; Collection freeCharBlocks; - + public: /// Coarse estimates used to measure RAM usage of buffered deletes static const int32_t OBJECT_HEADER_BYTES; static const int32_t POINTER_NUM_BYTE; static const int32_t INT_NUM_BYTE; static const int32_t CHAR_NUM_BYTE; - - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is - /// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since - /// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). + + /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object + /// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is + /// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since + /// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). /// BufferedDeletes.num is OBJ_HEADER + INT. static const int32_t BYTES_PER_DEL_TERM; - - /// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is + + /// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is /// OBJ_HEADER + int static const int32_t BYTES_PER_DEL_DOCID; - - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount + + /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object + /// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount /// (say 24 bytes). Integer is OBJ_HEADER + INT. static const int32_t BYTES_PER_DEL_QUERY; - + /// Initial chunks size of the shared byte[] blocks used to store postings data static const int32_t BYTE_BLOCK_SHIFT; static const int32_t BYTE_BLOCK_SIZE; static const int32_t BYTE_BLOCK_MASK; static const int32_t BYTE_BLOCK_NOT_MASK; - + /// Initial chunk size of the shared char[] blocks used to store term text static const int32_t CHAR_BLOCK_SHIFT; static const int32_t CHAR_BLOCK_SIZE; static const int32_t CHAR_BLOCK_MASK; - + static const int32_t MAX_TERM_LENGTH; - + /// Initial chunks size of the shared int[] blocks used to store postings data static const int32_t INT_BLOCK_SHIFT; static const int32_t INT_BLOCK_SIZE; static const int32_t INT_BLOCK_MASK; - + static const int32_t PER_DOC_BLOCK_SIZE; INTERNAL: @@ -157,211 +157,211 @@ namespace Lucene DirectoryPtr directory; IndexingChainPtr indexingChain; String segment; // Current segment we are working on - + int32_t numDocsInStore; // # docs written to doc stores - + bool flushPending; // True when a thread has decided to flush bool bufferIsFull; // True when it's time to write segment - + InfoStreamPtr infoStream; int32_t maxFieldLength; SimilarityPtr similarity; - + DocConsumerPtr consumer; - + HashSet _openFiles; HashSet _closedFiles; - + WaitQueuePtr waitQueue; SkipDocWriterPtr skipDocWriter; - + ByteBlockAllocatorPtr byteBlockAllocator; ByteBlockAllocatorPtr perDocAllocator; - + int64_t numBytesAlloc; int64_t numBytesUsed; - + // used only by assert TermPtr lastDeleteTerm; - + public: virtual void initialize(); - + /// Create and return a new DocWriterBuffer. PerDocBufferPtr newPerDocBuffer(); - + static IndexingChainPtr getDefaultIndexingChain(); - + void updateFlushedDocCount(int32_t n); int32_t getFlushedDocCount(); void setFlushedDocCount(int32_t n); - + /// Returns true if any of the fields in the current buffered docs have omitTermFreqAndPositions==false bool hasProx(); - + /// If non-null, various details of indexing are printed here. void setInfoStream(InfoStreamPtr infoStream); - + void setMaxFieldLength(int32_t maxFieldLength); void setSimilarity(SimilarityPtr similarity); - + /// Set how much RAM we can use before flushing. void setRAMBufferSizeMB(double mb); double getRAMBufferSizeMB(); - + /// Set max buffered docs, which means we will flush by doc count instead of by RAM usage. void setMaxBufferedDocs(int32_t count); int32_t getMaxBufferedDocs(); - + /// Get current segment name we are writing. String getSegment(); - + /// Returns how many docs are currently buffered in RAM. int32_t getNumDocsInRAM(); - + /// Returns the current doc store segment we are writing to. String getDocStoreSegment(); - + /// Returns the doc offset into the shared doc store for the current buffered docs. int32_t getDocStoreOffset(); - - /// Closes the current open doc stores an returns the doc store segment name. This returns null if there + + /// Closes the current open doc stores an returns the doc store segment name. This returns null if there /// are no buffered documents. String closeDocStore(); - + HashSet abortedFiles(); - + void message(const String& message); - + /// Returns Collection of files in use by this instance, including any flushed segments. HashSet openFiles(); HashSet closedFiles(); - + void addOpenFile(const String& name); void removeOpenFile(const String& name); - + void setAborting(); - + /// Called if we hit an exception at a bad time (when updating the index files) and must discard all /// currently buffered docs. This resets our state, discarding any docs added since last flush. void abort(); - + /// Returns true if an abort is in progress bool pauseAllThreads(); void resumeAllThreads(); - + bool anyChanges(); - + void initFlushState(bool onlyDocStore); - + /// Flush all pending docs to a new segment int32_t flush(bool _closeDocStore); - + HashSet getFlushedFiles(); - + /// Build compound file for the segment we just flushed void createCompoundFile(const String& segment); - - /// Set flushPending if it is not already set and returns whether it was set. This is used by IndexWriter + + /// Set flushPending if it is not already set and returns whether it was set. This is used by IndexWriter /// to trigger a single flush even when multiple threads are trying to do so. bool setFlushPending(); void clearFlushPending(); - + void pushDeletes(); - + void close(); - + void initSegmentName(bool onlyDocStore); - - /// Returns a free (idle) ThreadState that may be used for indexing this one document. This call also - /// pauses if a flush is pending. If delTerm is non-null then we buffer this deleted term after the + + /// Returns a free (idle) ThreadState that may be used for indexing this one document. This call also + /// pauses if a flush is pending. If delTerm is non-null then we buffer this deleted term after the /// thread state has been acquired. DocumentsWriterThreadStatePtr getThreadState(DocumentPtr doc, TermPtr delTerm); - + /// Returns true if the caller (IndexWriter) should now flush. bool addDocument(DocumentPtr doc, AnalyzerPtr analyzer); - + bool updateDocument(TermPtr t, DocumentPtr doc, AnalyzerPtr analyzer); bool updateDocument(DocumentPtr doc, AnalyzerPtr analyzer, TermPtr delTerm); - + int32_t getNumBufferedDeleteTerms(); // for testing MapTermNum getBufferedDeleteTerms(); // for testing - + /// Called whenever a merge has completed and the merged segments had deletions void remapDeletes(SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergeDocCount); - + bool bufferDeleteTerms(Collection terms); bool bufferDeleteTerm(TermPtr term); bool bufferDeleteQueries(Collection queries); bool bufferDeleteQuery(QueryPtr query); bool deletesFull(); bool doApplyDeletes(); - + void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); int32_t getMaxBufferedDeleteTerms(); - + bool hasDeletes(); bool applyDeletes(SegmentInfosPtr infos); bool doBalanceRAM(); - + void waitForWaitQueue(); - + int64_t getRAMUsed(); - + IntArray getIntBlock(bool trackAllocations); void bytesAllocated(int64_t numBytes); void bytesUsed(int64_t numBytes); void recycleIntBlocks(Collection blocks, int32_t start, int32_t end); - + CharArray getCharBlock(); void recycleCharBlocks(Collection blocks, int32_t numBlocks); - + String toMB(int64_t v); - + /// We have four pools of RAM: Postings, byte blocks (holds freq/prox posting data), char blocks (holds - /// characters in the term) and per-doc buffers (stored fields/term vectors). Different docs require + /// characters in the term) and per-doc buffers (stored fields/term vectors). Different docs require /// varying amount of storage from these four classes. /// /// For example, docs with many unique single-occurrence short terms will use up the Postings - /// RAM and hardly any of the other two. Whereas docs with very large terms will use alot of char blocks - /// RAM and relatively less of the other two. This method just frees allocations from the pools once we + /// RAM and hardly any of the other two. Whereas docs with very large terms will use alot of char blocks + /// RAM and relatively less of the other two. This method just frees allocations from the pools once we /// are over-budget, which balances the pools to match the current docs. void balanceRAM(); - + protected: /// Reset after a flush void doAfterFlush(); - + bool allThreadsIdle(); - + void waitReady(DocumentsWriterThreadStatePtr state); - + bool timeToFlushDeletes(); - + // used only by assert bool checkDeleteTerm(TermPtr term); - + bool applyDeletes(IndexReaderPtr reader, int32_t docIDStart); void addDeleteTerm(TermPtr term, int32_t docCount); - + /// Buffer a specific docID for deletion. Currently only used when we hit a exception when adding a document void addDeleteDocID(int32_t docID); void addDeleteQuery(QueryPtr query, int32_t docID); - + /// Does the synchronized work to finish/flush the inverted document. void finishDocument(DocumentsWriterThreadStatePtr perThread, DocWriterPtr docWriter); - + friend class WaitQueue; }; - + class DocState : public LuceneObject { public: DocState(); virtual ~DocState(); - + LUCENE_CLASS(DocState); - + public: DocumentsWriterWeakPtr _docWriter; AnalyzerPtr analyzer; @@ -371,70 +371,70 @@ namespace Lucene int32_t docID; DocumentPtr doc; String maxTermPrefix; - + public: /// Only called by asserts virtual bool testPoint(const String& name); - + void clear(); }; - + /// RAMFile buffer for DocWriters. class PerDocBuffer : public RAMFile { public: PerDocBuffer(DocumentsWriterPtr docWriter); virtual ~PerDocBuffer(); - + LUCENE_CLASS(PerDocBuffer); - + protected: DocumentsWriterWeakPtr _docWriter; - + public: /// Recycle the bytes used. void recycle(); - + protected: /// Allocate bytes used from shared pool. virtual ByteArray newBuffer(int32_t size); }; - - /// Consumer returns this on each doc. This holds any state that must be flushed synchronized + + /// Consumer returns this on each doc. This holds any state that must be flushed synchronized /// "in docID order". We gather these and flush them in order. class DocWriter : public LuceneObject { public: DocWriter(); virtual ~DocWriter(); - + LUCENE_CLASS(DocWriter); - + public: DocWriterPtr next; int32_t docID; - + public: virtual void finish() = 0; virtual void abort() = 0; virtual int64_t sizeInBytes() = 0; - + virtual void setNext(DocWriterPtr next); }; - - /// The IndexingChain must define the {@link #getChain(DocumentsWriter)} method which returns the DocConsumer - /// that the DocumentsWriter calls to process the documents. + + /// The IndexingChain must define the {@link #getChain(DocumentsWriter)} method which returns the DocConsumer + /// that the DocumentsWriter calls to process the documents. class IndexingChain : public LuceneObject { public: virtual ~IndexingChain(); - + LUCENE_CLASS(IndexingChain); - + public: virtual DocConsumerPtr getChain(DocumentsWriterPtr documentsWriter) = 0; }; - + /// This is the current indexing chain: /// DocConsumer / DocConsumerPerThread /// --> code: DocFieldProcessor / DocFieldProcessorPerThread @@ -453,74 +453,74 @@ namespace Lucene { public: virtual ~DefaultIndexingChain(); - + LUCENE_CLASS(DefaultIndexingChain); - + public: virtual DocConsumerPtr getChain(DocumentsWriterPtr documentsWriter); }; - + class SkipDocWriter : public DocWriter { public: virtual ~SkipDocWriter(); - + LUCENE_CLASS(SkipDocWriter); - + public: virtual void finish(); virtual void abort(); virtual int64_t sizeInBytes(); }; - + class WaitQueue : public LuceneObject { public: WaitQueue(DocumentsWriterPtr docWriter); virtual ~WaitQueue(); - + LUCENE_CLASS(WaitQueue); - + protected: DocumentsWriterWeakPtr _docWriter; - + public: Collection waiting; int32_t nextWriteDocID; int32_t nextWriteLoc; int32_t numWaiting; int64_t waitingBytes; - + public: void reset(); bool doResume(); bool doPause(); void abort(); bool add(DocWriterPtr doc); - + protected: void writeDocument(DocWriterPtr doc); }; - + class ByteBlockAllocator : public ByteBlockPoolAllocatorBase { public: ByteBlockAllocator(DocumentsWriterPtr docWriter, int32_t blockSize); virtual ~ByteBlockAllocator(); - + LUCENE_CLASS(ByteBlockAllocator); - + protected: DocumentsWriterWeakPtr _docWriter; - + public: int32_t blockSize; Collection freeByteBlocks; - + public: /// Allocate another byte[] from the shared pool virtual ByteArray getByteBlock(bool trackAllocations); - + /// Return byte[]'s to the pool virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end); virtual void recycleByteBlocks(Collection blocks); diff --git a/include/DocumentsWriterThreadState.h b/include/DocumentsWriterThreadState.h index 5cec49bd..b8b2b267 100644 --- a/include/DocumentsWriterThreadState.h +++ b/include/DocumentsWriterThreadState.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,16 +12,16 @@ namespace Lucene { /// Used by DocumentsWriter to maintain per-thread state. - /// We keep a separate Posting hash and other state for each thread and then merge postings + /// We keep a separate Posting hash and other state for each thread and then merge postings /// hashes from all threads when writing the segment. class DocumentsWriterThreadState : public LuceneObject { public: DocumentsWriterThreadState(DocumentsWriterPtr docWriter); virtual ~DocumentsWriterThreadState(); - + LUCENE_CLASS(DocumentsWriterThreadState); - + public: bool isIdle; // false if this is currently in use by a thread int32_t numThreads; // Number of threads that share this instance @@ -29,7 +29,7 @@ namespace Lucene DocConsumerPerThreadPtr consumer; DocStatePtr docState; DocumentsWriterWeakPtr _docWriter; - + public: virtual void initialize(); void doAfterFlush(); diff --git a/include/DoubleFieldSource.h b/include/DoubleFieldSource.h index e7e80591..6fa2fbe0 100644 --- a/include/DoubleFieldSource.h +++ b/include/DoubleFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,15 +12,15 @@ namespace Lucene { - /// Obtains double field values from the {@link FieldCache} using getDoubles() and makes those values available + /// Obtains double field values from the {@link FieldCache} using getDoubles() and makes those values available /// as other numeric types, casting as needed. /// /// @see FieldCacheSource for requirements on the field. /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite + /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU + /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, + /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU /// per lookup but will not consume double the FieldCache RAM. class DoubleFieldSource : public FieldCacheSource { @@ -28,31 +28,31 @@ namespace Lucene /// Create a cached double field source with a specific string-to-double parser. DoubleFieldSource(const String& field, DoubleParserPtr parser = DoubleParserPtr()); virtual ~DoubleFieldSource(); - + LUCENE_CLASS(DoubleFieldSource); - + protected: DoubleParserPtr parser; - + public: virtual String description(); virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader); virtual bool cachedFieldSourceEquals(FieldCacheSourcePtr other); virtual int32_t cachedFieldSourceHashCode(); }; - + class DoubleDocValues : public DocValues { public: DoubleDocValues(DoubleFieldSourcePtr source, Collection arr); virtual ~DoubleDocValues(); - + LUCENE_CLASS(DoubleDocValues); - + protected: DoubleFieldSourceWeakPtr _source; Collection arr; - + public: virtual double doubleVal(int32_t doc); virtual String toString(int32_t doc); diff --git a/include/ExactPhraseScorer.h b/include/ExactPhraseScorer.h index 31e6c48e..3d50d664 100644 --- a/include/ExactPhraseScorer.h +++ b/include/ExactPhraseScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: ExactPhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, ByteArray norms); virtual ~ExactPhraseScorer(); - + LUCENE_CLASS(ExactPhraseScorer); - + protected: virtual double phraseFreq(); }; diff --git a/include/Explanation.h b/include/Explanation.h index fc2a2779..b1703f4e 100644 --- a/include/Explanation.h +++ b/include/Explanation.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,14 +17,14 @@ namespace Lucene public: Explanation(double value = 0, const String& description = EmptyString); virtual ~Explanation(); - + LUCENE_CLASS(Explanation); - + protected: double value; // the value of this node String description; // what it represents Collection details; // sub-explanations - + public: /// Indicates whether or not this Explanation models a good match. /// @@ -32,39 +32,39 @@ namespace Lucene /// /// @see #getValue virtual bool isMatch(); - + /// The value assigned to this explanation node. virtual double getValue(); - + /// Sets the value assigned to this explanation node. virtual void setValue(double value); - + /// A description of this explanation node. virtual String getDescription(); - + /// Sets the description of this explanation node. virtual void setDescription(const String& description); - + /// The sub-nodes of this explanation node. virtual Collection getDetails(); /// Adds a sub-node to this explanation node. virtual void addDetail(ExplanationPtr detail); - + /// Render an explanation as text. virtual String toString(); - + /// Render an explanation as HTML. virtual String toHtml(); - + protected: - /// A short one line summary which should contain all high level information about this Explanation, + /// A short one line summary which should contain all high level information about this Explanation, /// without the "Details" virtual String getSummary(); - + virtual String toString(int32_t depth); }; - + /// Small Util class used to pass both an idf factor as well as an explanation for that factor. /// /// This class will likely be held on a {@link Weight}, so be aware before storing any large fields. @@ -73,11 +73,11 @@ namespace Lucene public: virtual ~IDFExplanation(); LUCENE_CLASS(IDFExplanation); - + public: /// @return the idf factor virtual double getIdf() = 0; - + /// This should be calculated lazily if possible. /// @return the explanation for the idf factor. virtual String explain() = 0; diff --git a/include/FSDirectory.h b/include/FSDirectory.h index 84824ff9..63dc4269 100644 --- a/include/FSDirectory.h +++ b/include/FSDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,19 +11,19 @@ namespace Lucene { - /// Base class for Directory implementations that store index files in the file system. There are currently three + /// Base class for Directory implementations that store index files in the file system. There are currently three /// core subclasses: /// /// {@link SimpleFSDirectory} is a straightforward implementation using std::ofstream and std::ifstream. /// - /// {@link MMapDirectory} uses memory-mapped IO when reading. This is a good choice if you have plenty of virtual - /// memory relative to your index size, eg if you are running on a 64 bit operating system, oryour index sizes are + /// {@link MMapDirectory} uses memory-mapped IO when reading. This is a good choice if you have plenty of virtual + /// memory relative to your index size, eg if you are running on a 64 bit operating system, oryour index sizes are /// small enough to fit into the virtual memory space. /// - /// For users who have no reason to prefer a specific implementation, it's best to simply use {@link #open}. For + /// For users who have no reason to prefer a specific implementation, it's best to simply use {@link #open}. For /// all others, you should instantiate the desired implementation directly. /// - /// The locking implementation is by default {@link NativeFSLockFactory}, but can be changed by passing in a custom + /// The locking implementation is by default {@link NativeFSLockFactory}, but can be changed by passing in a custom /// {@link LockFactory} instance. /// @see Directory class LPPAPI FSDirectory : public Directory @@ -33,97 +33,97 @@ namespace Lucene /// @param path the path of the directory. /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) FSDirectory(const String& path, LockFactoryPtr lockFactory); - + public: virtual ~FSDirectory(); - + LUCENE_CLASS(FSDirectory); - - public: + + public: /// Default read chunk size. This is a conditional default based on operating system. /// @see #setReadChunkSize static const int32_t DEFAULT_READ_CHUNK_SIZE; - + protected: bool checked; - + /// The underlying filesystem directory. String directory; - + /// @see #DEFAULT_READ_CHUNK_SIZE int32_t chunkSize; - + public: /// Creates an FSDirectory instance. static FSDirectoryPtr open(const String& path); - + /// Just like {@link #open(File)}, but allows you to also specify a custom {@link LockFactory}. static FSDirectoryPtr open(const String& path, LockFactoryPtr lockFactory); - + /// Lists all files (not subdirectories) in the directory. /// @throws NoSuchDirectoryException if the directory does not exist, or does exist but is not a directory. static HashSet listAll(const String& dir); - + /// Returns the time the named file was last modified. static uint64_t fileModified(const String& directory, const String& name); - + /// Create file system directory. void createDir(); - + /// Return file system directory. String getFile(); - - /// Sets the maximum number of bytes read at once from the underlying file during {@link IndexInput#readBytes}. - /// The default value is {@link #DEFAULT_READ_CHUNK_SIZE}. Changes to this value will not impact any already-opened - /// {@link IndexInput}s. You should call this before attempting to open an index on the directory. This value should + + /// Sets the maximum number of bytes read at once from the underlying file during {@link IndexInput#readBytes}. + /// The default value is {@link #DEFAULT_READ_CHUNK_SIZE}. Changes to this value will not impact any already-opened + /// {@link IndexInput}s. You should call this before attempting to open an index on the directory. This value should /// be as large as possible to reduce any possible performance impact. void setReadChunkSize(int32_t chunkSize); - + /// The maximum number of bytes to read at once from the underlying file during {@link IndexInput#readBytes}. /// @see #setReadChunkSize int32_t getReadChunkSize(); - + /// Lists all files (not subdirectories) in the directory. /// @see #listAll(const String&) virtual HashSet listAll(); - + /// Returns true if a file with the given name exists. virtual bool fileExists(const String& name); - + /// Returns the time the named file was last modified. virtual uint64_t fileModified(const String& name); - + /// Set the modified time of an existing file to now. virtual void touchFile(const String& name); - + /// Removes an existing file in the directory. virtual void deleteFile(const String& name); - + /// Returns the length in bytes of a file in the directory. virtual int64_t fileLength(const String& name); - - /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit changes to + + /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit changes to /// the index, to prevent a machine/OS crash from corrupting the index. virtual void sync(const String& name); - - /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory + + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory /// implementation may ignore the buffer size. virtual IndexInputPtr openInput(const String& name); - - /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory - /// implementation may ignore the buffer size. Currently the only Directory implementations that respect this parameter + + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory + /// implementation may ignore the buffer size. Currently the only Directory implementations that respect this parameter /// are {@link FSDirectory} and {@link CompoundFileReader}. virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - + /// Return a string identifier that uniquely differentiates this Directory instance from other Directory instances. virtual String getLockID(); - + /// Closes the store to future operations. virtual void close(); - + /// For debug output. virtual String toString(); - + protected: /// Initializes the directory to create a new file with the given name. This method should be used in {@link #createOutput}. void initOutput(const String& name); diff --git a/include/FSLockFactory.h b/include/FSLockFactory.h index f91c0d0a..162cead8 100644 --- a/include/FSLockFactory.h +++ b/include/FSLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,23 +16,23 @@ namespace Lucene { protected: FSLockFactory(); - + public: virtual ~FSLockFactory(); - + LUCENE_CLASS(FSLockFactory); - + protected: /// Directory for the lock files. String lockDir; - + public: - /// Set the lock directory. This method can be only called once to + /// Set the lock directory. This method can be only called once to /// initialize the lock directory. It is used by {@link FSDirectory} - /// to set the lock directory to itself. Subclasses can also use + /// to set the lock directory to itself. Subclasses can also use /// this method to set the directory in the constructor. void setLockDir(const String& lockDir); - + /// Retrieve the lock directory. String getLockDir(); }; diff --git a/include/FastCharStream.h b/include/FastCharStream.h index a962d265..f15448e9 100644 --- a/include/FastCharStream.h +++ b/include/FastCharStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,9 +11,9 @@ namespace Lucene { - /// An efficient implementation of QueryParserCharStream interface. + /// An efficient implementation of QueryParserCharStream interface. /// - /// Note that this does not do line-number counting, but instead keeps track of the character position of + /// Note that this does not do line-number counting, but instead keeps track of the character position of /// the token in the input, as required by Lucene's {@link Token} API. class LPPAPI FastCharStream : public QueryParserCharStream, public LuceneObject { @@ -21,20 +21,20 @@ namespace Lucene /// Constructs from a Reader. FastCharStream(ReaderPtr reader); virtual ~FastCharStream(); - + LUCENE_CLASS(FastCharStream); - + public: CharArray buffer; - + int32_t bufferLength; // end of valid chars int32_t bufferPosition; // next char to read - + int32_t tokenStart; // offset in buffer int32_t bufferStart; // position in file of buffer - + ReaderPtr input; // source of chars - + public: virtual wchar_t readChar(); virtual wchar_t BeginToken(); @@ -48,7 +48,7 @@ namespace Lucene virtual int32_t getEndLine(); virtual int32_t getBeginColumn(); virtual int32_t getBeginLine(); - + protected: void refill(); }; diff --git a/include/Field.h b/include/Field.h index 46f5deb7..b6242660 100644 --- a/include/Field.h +++ b/include/Field.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene class LPPAPI Field : public AbstractField { public: - /// Create a field by specifying its name, value and how it will be saved in the index. Term vectors + /// Create a field by specifying its name, value and how it will be saved in the index. Term vectors /// will not be stored in the index. /// /// @param name The name of the field @@ -22,8 +22,8 @@ namespace Lucene /// @param store Whether value should be stored in the index /// @param index Whether the field should be indexed, and if so, if it should be tokenized before indexing Field(const String& name, const String& value, Store store, Index index); - - /// Create a field by specifying its name, value and how it will be saved in the index. + + /// Create a field by specifying its name, value and how it will be saved in the index. /// /// @param name The name of the field /// @param value The string to process @@ -31,48 +31,48 @@ namespace Lucene /// @param index Whether the field should be indexed, and if so, if it should be tokenized before indexing /// @param termVector Whether term vector should be stored Field(const String& name, const String& value, Store store, Index index, TermVector termVector); - - /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. The Reader is - /// read only when the Document is added to the index, ie. you may not close the Reader until {@link + + /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. The Reader is + /// read only when the Document is added to the index, ie. you may not close the Reader until {@link /// IndexWriter#addDocument(Document)} has been called. /// /// @param name The name of the field /// @param reader The reader with the content Field(const String& name, ReaderPtr reader); - - /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. The - /// Reader is read only when the Document is added to the index, ie. you may not close the Reader until + + /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. The + /// Reader is read only when the Document is added to the index, ie. you may not close the Reader until /// {@link IndexWriter#addDocument(Document)} has been called. /// /// @param name The name of the field /// @param reader The reader with the content /// @param termVector Whether term vector should be stored Field(const String& name, ReaderPtr reader, TermVector termVector); - - /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. This is useful - /// for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, ie. you + + /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. This is useful + /// for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, ie. you /// may not close the TokenStream until {@link IndexWriter#addDocument(Document)} has been called. /// /// @param name The name of the field /// @param tokenStream The TokenStream with the content Field(const String& name, TokenStreamPtr tokenStream); - - /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. This is + + /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. This is /// useful for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, /// ie. you may not close the TokenStream until {@link IndexWriter#addDocument(Document)} has been called. - /// + /// /// @param name The name of the field /// @param tokenStream The TokenStream with the content /// @param termVector Whether term vector should be stored Field(const String& name, TokenStreamPtr tokenStream, TermVector termVector); - + /// Create a stored field with binary value. Optionally the value may be compressed. /// /// @param name The name of the field /// @param value The binary value /// @param store How value should be stored (compressed or not) Field(const String& name, ByteArray value, Store store); - + /// Create a stored field with binary value. Optionally the value may be compressed. /// /// @param name The name of the field @@ -81,69 +81,69 @@ namespace Lucene /// @param length Number of bytes to use for this Field, starting at offset /// @param store How value should be stored (compressed or not) Field(const String& name, ByteArray value, int32_t offset, int32_t length, Store store); - + virtual ~Field(); - + LUCENE_CLASS(Field); - + public: using AbstractField::isStored; - using AbstractField::isIndexed; - + using AbstractField::isIndexed; + /// Specifies whether and how a field should be stored. static bool isStored(Store store); - + /// Specifies whether and how a field should be indexed. static bool isIndexed(Index index); static bool isAnalyzed(Index index); static bool omitNorms(Index index); - + /// Get the best representation of the index given the flags. static Field::Index toIndex(bool indexed, bool analyzed); - + /// Get the best representation of the index given the flags. static Field::Index toIndex(bool indexed, bool analyzed, bool omitNorms); - + /// Specifies whether and how a field should have term vectors. static bool isStored(TermVector termVector); static bool withPositions(TermVector termVector); static bool withOffsets(TermVector termVector); - + /// Get the best representation of the index given the flags. static Field::TermVector toTermVector(bool stored, bool withOffsets, bool withPositions); - - /// The value of the field as a String, or null. If null, the Reader value or binary value is used. + + /// The value of the field as a String, or null. If null, the Reader value or binary value is used. /// Exactly one of stringValue(), readerValue(), and getBinaryValue() must be set. virtual String stringValue(); - - /// The value of the field as a Reader, or null. If null, the String value or binary value is used. + + /// The value of the field as a Reader, or null. If null, the String value or binary value is used. /// Exactly one of stringValue(), readerValue(), and getBinaryValue() must be set. virtual ReaderPtr readerValue(); - - /// The value of the field as a TokesStream, or null. If null, the Reader value or String value is + + /// The value of the field as a TokesStream, or null. If null, the Reader value or String value is /// analyzed to produce the indexed tokens. virtual TokenStreamPtr tokenStreamValue(); - - /// Change the value of this field. This can be used during indexing to re-use a single Field instance - /// to improve indexing speed. Typically a single {@link Document} instance is re-used as well. This + + /// Change the value of this field. This can be used during indexing to re-use a single Field instance + /// to improve indexing speed. Typically a single {@link Document} instance is re-used as well. This /// helps most on small documents. - /// + /// /// Each Field instance should only be used once within a single {@link Document} instance. virtual void setValue(const String& value); - + /// Change the value of this field. virtual void setValue(ReaderPtr value); - + /// Change the value of this field. virtual void setValue(ByteArray value); - + /// Change the value of this field. virtual void setValue(ByteArray value, int32_t offset, int32_t length); - - /// Sets the token stream to be used for indexing and causes isIndexed() and isTokenized() to return + + /// Sets the token stream to be used for indexing and causes isIndexed() and isTokenized() to return /// true. May be combined with stored values from stringValue() or getBinaryValue() virtual void setTokenStream(TokenStreamPtr tokenStream); - + protected: void ConstructField(const String& name, const String& value, Store store, Index index, TermVector termVector); void ConstructField(const String& name, ReaderPtr reader, TermVector termVector); diff --git a/include/FieldCache.h b/include/FieldCache.h index a61eea09..9de7e961 100644 --- a/include/FieldCache.h +++ b/include/FieldCache.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,7 +19,7 @@ namespace Lucene public: virtual ~FieldCache(); LUCENE_INTERFACE(FieldCache); - + public: /// Specifies whether and how a field should be stored. enum CacheType @@ -31,174 +31,174 @@ namespace Lucene CACHE_STRING, CACHE_STRING_INDEX }; - + /// Indicator for StringIndex values in the cache. /// NOTE: the value assigned to this constant must not be the same as any of those in SortField static const int32_t STRING_INDEX; - + public: /// The cache used internally by sorting and range query classes. static FieldCachePtr DEFAULT(); - + /// The default parser for byte values, which are encoded by StringUtils::toInt static ByteParserPtr DEFAULT_BYTE_PARSER(); - + /// The default parser for int values, which are encoded by StringUtils::toInt static IntParserPtr DEFAULT_INT_PARSER(); - + /// The default parser for int values, which are encoded by StringUtils::toLong static LongParserPtr DEFAULT_LONG_PARSER(); - + /// The default parser for double values, which are encoded by StringUtils::toDouble static DoubleParserPtr DEFAULT_DOUBLE_PARSER(); - - /// A parser instance for int values encoded by {@link NumericUtils#prefixCodedToInt(String)}, + + /// A parser instance for int values encoded by {@link NumericUtils#prefixCodedToInt(String)}, /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. static IntParserPtr NUMERIC_UTILS_INT_PARSER(); - - /// A parser instance for long values encoded by {@link NumericUtils#prefixCodedToLong(String)}, + + /// A parser instance for long values encoded by {@link NumericUtils#prefixCodedToLong(String)}, /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. static LongParserPtr NUMERIC_UTILS_LONG_PARSER(); - - /// A parser instance for double values encoded by {@link NumericUtils}, + + /// A parser instance for double values encoded by {@link NumericUtils}, /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. static DoubleParserPtr NUMERIC_UTILS_DOUBLE_PARSER(); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as a single byte and returns an array of size reader.maxDoc() of the value each document /// has in the given field. /// @param reader Used to get field values. /// @param field Which field contains the single byte values. /// @return The values in the given field for each document. virtual Collection getBytes(IndexReaderPtr reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as bytes and returns an array of size reader.maxDoc() of the value each document has in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as bytes and returns an array of size reader.maxDoc() of the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the bytes. /// @param parser Computes byte for string values. /// @return The values in the given field for each document. virtual Collection getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as integers and returns an array of size reader.maxDoc() of the value each document has in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as integers and returns an array of size reader.maxDoc() of the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the integers. /// @return The values in the given field for each document. virtual Collection getInts(IndexReaderPtr reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as integers and returns an array of size reader.maxDoc() of the value each document has in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as integers and returns an array of size reader.maxDoc() of the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the integers. /// @param parser Computes integer for string values. /// @return The values in the given field for each document. virtual Collection getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as longs and returns an array of size reader.maxDoc() of the value each document has in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as longs and returns an array of size reader.maxDoc() of the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the longs. /// @return The values in the given field for each document. virtual Collection getLongs(IndexReaderPtr reader, const String& field); - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as longs and returns an array of size reader.maxDoc() of the value each document has in + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as longs and returns an array of size reader.maxDoc() of the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the longs. /// @param parser Computes long for string values. /// @return The values in the given field for each document. virtual Collection getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as integers and returns an array of size reader.maxDoc() of the value each document has in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as integers and returns an array of size reader.maxDoc() of the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the doubles. /// @return The values in the given field for each document. virtual Collection getDoubles(IndexReaderPtr reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as doubles and returns an array of size reader.maxDoc() of the value each document has in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as doubles and returns an array of size reader.maxDoc() of the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the doubles. /// @param parser Computes double for string values. /// @return The values in the given field for each document. virtual Collection getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the term values in - /// field and returns an array of size reader.maxDoc() containing the value each document has in + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the term values in + /// field and returns an array of size reader.maxDoc() containing the value each document has in /// the given field. /// @param reader Used to get field values. /// @param field Which field contains the strings. /// @return The values in the given field for each document. virtual Collection getStrings(IndexReaderPtr reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found reads the term values in - /// field and returns an array of them in natural order, along with an array telling which element in + + /// Checks the internal cache for an appropriate entry, and if none are found reads the term values in + /// field and returns an array of them in natural order, along with an array telling which element in /// the term array each document uses. /// @param reader Used to get field values. /// @param field Which field contains the strings. /// @return Array of terms and index into the array for each document. virtual StringIndexPtr getStringIndex(IndexReaderPtr reader, const String& field); - + /// Generates an array of CacheEntry objects representing all items currently in the FieldCache. virtual Collection getCacheEntries() = 0; - - /// Instructs the FieldCache to forcibly expunge all entries from the underlying caches. This is intended - /// only to be used for test methods as a way to ensure a known base state of the Cache. It should not be + + /// Instructs the FieldCache to forcibly expunge all entries from the underlying caches. This is intended + /// only to be used for test methods as a way to ensure a known base state of the Cache. It should not be /// relied on for "Cache maintenance" in general application code. virtual void purgeAllCaches() = 0; - - /// Drops all cache entries associated with this reader. NOTE: this reader must precisely match the reader + + /// Drops all cache entries associated with this reader. NOTE: this reader must precisely match the reader /// that the cache entry is keyed on. If you pass a top-level reader, it usually will have no effect as /// Lucene now caches at the segment reader level. virtual void purge(IndexReaderPtr r) = 0; - - /// If non-null, FieldCacheImpl will warn whenever entries are created that are not sane according to + + /// If non-null, FieldCacheImpl will warn whenever entries are created that are not sane according to /// {@link FieldCacheSanityChecker}. virtual void setInfoStream(InfoStreamPtr stream); - + /// @see #setInfoStream virtual InfoStreamPtr getInfoStream(); }; - + class LPPAPI CreationPlaceholder : public LuceneObject { public: virtual ~CreationPlaceholder(); LUCENE_CLASS(CreationPlaceholder); - + public: boost::any value; }; - + /// Stores term text values and document ordering data. class LPPAPI StringIndex : public LuceneObject { public: StringIndex(Collection values, Collection lookup); virtual ~StringIndex(); - + LUCENE_CLASS(StringIndex); - + public: /// All the term values, in natural order. Collection lookup; - + /// For each document, an index into the lookup array. Collection order; - + public: int32_t binarySearchLookup(const String& key); }; - + /// Marker interface as super-interface to all parsers. It is used to specify a custom parser to {@link /// SortField#SortField(String, Parser)}. class LPPAPI Parser : public LuceneObject @@ -207,7 +207,7 @@ namespace Lucene virtual ~Parser(); LUCENE_CLASS(Parser); }; - + /// Interface to parse bytes from document fields. /// @see FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr) class LPPAPI ByteParser : public Parser @@ -215,12 +215,12 @@ namespace Lucene public: virtual ~ByteParser(); LUCENE_CLASS(ByteParser); - + public: /// Return a single Byte representation of this field's value. virtual uint8_t parseByte(const String& string); }; - + /// Interface to parse ints from document fields. /// @see FieldCache#getInts(IndexReaderPtr, String, IntParserPtr) class LPPAPI IntParser : public Parser @@ -228,12 +228,12 @@ namespace Lucene public: virtual ~IntParser(); LUCENE_CLASS(IntParser); - + public: /// Return a integer representation of this field's value. virtual int32_t parseInt(const String& string); }; - + /// Interface to parse longs from document fields. /// @see FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr) class LPPAPI LongParser : public Parser @@ -241,12 +241,12 @@ namespace Lucene public: virtual ~LongParser(); LUCENE_CLASS(LongParser); - + public: /// Return a long representation of this field's value. virtual int64_t parseLong(const String& string); }; - + /// Interface to parse doubles from document fields. /// @see FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr) class LPPAPI DoubleParser : public Parser @@ -254,26 +254,26 @@ namespace Lucene public: virtual ~DoubleParser(); LUCENE_CLASS(DoubleParser); - + public: /// Return a double representation of this field's value. virtual double parseDouble(const String& string); }; - + /// A unique Identifier/Description for each item in the FieldCache. Can be useful for logging/debugging. class LPPAPI FieldCacheEntry : public LuceneObject { public: virtual ~FieldCacheEntry(); LUCENE_CLASS(FieldCacheEntry); - + public: virtual LuceneObjectPtr getReaderKey() = 0; virtual String getFieldName() = 0; virtual int32_t getCacheType() = 0; virtual boost::any getCustom() = 0; virtual boost::any getValue() = 0; - + virtual String toString(); }; } diff --git a/include/FieldCacheImpl.h b/include/FieldCacheImpl.h index 0689c63d..5ac8ee80 100644 --- a/include/FieldCacheImpl.h +++ b/include/FieldCacheImpl.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,170 +17,170 @@ namespace Lucene public: FieldCacheImpl(); virtual ~FieldCacheImpl(); - + LUCENE_CLASS(FieldCacheImpl); - + protected: MapStringCache caches; InfoStreamPtr infoStream; - + public: virtual void initialize(); virtual void purgeAllCaches(); virtual void purge(IndexReaderPtr r); virtual Collection getCacheEntries(); - + virtual Collection getBytes(IndexReaderPtr reader, const String& field); virtual Collection getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser); - + virtual Collection getInts(IndexReaderPtr reader, const String& field); virtual Collection getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser); - + virtual Collection getLongs(IndexReaderPtr reader, const String& field); virtual Collection getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser); - + virtual Collection getDoubles(IndexReaderPtr reader, const String& field); virtual Collection getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser); - + virtual Collection getStrings(IndexReaderPtr reader, const String& field); virtual StringIndexPtr getStringIndex(IndexReaderPtr reader, const String& field); - + virtual void setInfoStream(InfoStreamPtr stream); virtual InfoStreamPtr getInfoStream(); }; - + class Entry : public LuceneObject { public: /// Creates one of these objects for a custom comparator/parser. Entry(const String& field, boost::any custom); virtual ~Entry(); - + LUCENE_CLASS(Entry); - + public: String field; // which Fieldable boost::any custom; // which custom comparator or parser - + public: /// Two of these are equal if they reference the same field and type. virtual bool equals(LuceneObjectPtr other); - + /// Composes a hashcode based on the field and type. virtual int32_t hashCode(); }; - + /// Internal cache. class Cache : public LuceneObject { public: Cache(FieldCachePtr wrapper = FieldCachePtr()); virtual ~Cache(); - + LUCENE_CLASS(Cache); - + public: FieldCacheWeakPtr _wrapper; WeakMapLuceneObjectMapEntryAny readerCache; - + protected: virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key) = 0; - + public: /// Remove this reader from the cache, if present. virtual void purge(IndexReaderPtr r); - + virtual boost::any get(IndexReaderPtr reader, EntryPtr key); virtual void printNewInsanity(InfoStreamPtr infoStream, boost::any value); }; - + class ByteCache : public Cache { public: ByteCache(FieldCachePtr wrapper = FieldCachePtr()); virtual ~ByteCache(); - + LUCENE_CLASS(ByteCache); - + protected: virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); }; - + class IntCache : public Cache { public: IntCache(FieldCachePtr wrapper = FieldCachePtr()); virtual ~IntCache(); - + LUCENE_CLASS(IntCache); - + protected: virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); }; - + class LongCache : public Cache { public: LongCache(FieldCachePtr wrapper = FieldCachePtr()); virtual ~LongCache(); - + LUCENE_CLASS(LongCache); - + protected: virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); }; - + class DoubleCache : public Cache { public: DoubleCache(FieldCachePtr wrapper = FieldCachePtr()); virtual ~DoubleCache(); - + LUCENE_CLASS(DoubleCache); - + protected: virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); }; - + class StringCache : public Cache { public: StringCache(FieldCachePtr wrapper = FieldCachePtr()); virtual ~StringCache(); - + LUCENE_CLASS(StringCache); - + protected: virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); }; - + class StringIndexCache : public Cache { public: StringIndexCache(FieldCachePtr wrapper = FieldCachePtr()); virtual ~StringIndexCache(); - + LUCENE_CLASS(StringIndexCache); - + protected: virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); }; - + class FieldCacheEntryImpl : public FieldCacheEntry { public: FieldCacheEntryImpl(LuceneObjectPtr readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value); virtual ~FieldCacheEntryImpl(); - + LUCENE_CLASS(FieldCacheEntryImpl); - + protected: LuceneObjectPtr readerKey; String fieldName; int32_t cacheType; boost::any custom; boost::any value; - + public: virtual LuceneObjectPtr getReaderKey(); virtual String getFieldName(); diff --git a/include/FieldCacheRangeFilter.h b/include/FieldCacheRangeFilter.h index 8e589752..85702a79 100644 --- a/include/FieldCacheRangeFilter.h +++ b/include/FieldCacheRangeFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,99 +14,99 @@ namespace Lucene { /// A range filter built on top of a cached single term field (in {@link FieldCache}). /// - /// FieldCacheRangeFilter builds a single cache for the field the first time it is used. Each subsequent - /// FieldCacheRangeFilter on the same field then reuses this cache, even if the range itself changes. + /// FieldCacheRangeFilter builds a single cache for the field the first time it is used. Each subsequent + /// FieldCacheRangeFilter on the same field then reuses this cache, even if the range itself changes. /// - /// This means that FieldCacheRangeFilter is much faster (sometimes more than 100x as fast) as building a - /// {@link TermRangeFilter}, if using a {@link #newStringRange}. However, if the range never changes it is + /// This means that FieldCacheRangeFilter is much faster (sometimes more than 100x as fast) as building a + /// {@link TermRangeFilter}, if using a {@link #newStringRange}. However, if the range never changes it is /// slower (around 2x as slow) than building a CachingWrapperFilter on top of a single {@link TermRangeFilter}. /// - /// For numeric data types, this filter may be significantly faster than {@link NumericRangeFilter}. - /// Furthermore, it does not need the numeric values encoded by {@link NumericField}. But it has the problem + /// For numeric data types, this filter may be significantly faster than {@link NumericRangeFilter}. + /// Furthermore, it does not need the numeric values encoded by {@link NumericField}. But it has the problem /// that it only works with exact one value/document (see below). /// - /// As with all {@link FieldCache} based functionality, FieldCacheRangeFilter is only valid for fields which - /// exact one term for each document (except for {@link #newStringRange} where 0 terms are also allowed). Due - /// to a restriction of {@link FieldCache}, for numeric ranges all terms that do not have a numeric value, 0 + /// As with all {@link FieldCache} based functionality, FieldCacheRangeFilter is only valid for fields which + /// exact one term for each document (except for {@link #newStringRange} where 0 terms are also allowed). Due + /// to a restriction of {@link FieldCache}, for numeric ranges all terms that do not have a numeric value, 0 /// is assumed. /// - /// Thus it works on dates, prices and other single value fields but will not work on regular text fields. It - /// is preferable to use a NOT_ANALYZED field to ensure that there is only a single term. + /// Thus it works on dates, prices and other single value fields but will not work on regular text fields. It + /// is preferable to use a NOT_ANALYZED field to ensure that there is only a single term. /// - /// Do not instantiate this template directly, use one of the static factory methods available, that create a + /// Do not instantiate this template directly, use one of the static factory methods available, that create a /// correct instance for different data types supported by {@link FieldCache}. class LPPAPI FieldCacheRangeFilter : public Filter { public: FieldCacheRangeFilter(const String& field, ParserPtr parser, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilter(); - + LUCENE_CLASS(FieldCacheRangeFilter); - + INTERNAL: String field; ParserPtr parser; bool includeLower; bool includeUpper; - + public: - /// Creates a string range filter using {@link FieldCache#getStringIndex}. This works with all fields containing + /// Creates a string range filter using {@link FieldCache#getStringIndex}. This works with all fields containing /// zero or one term in the field. The range can be half-open by setting one of the values to null. static FieldCacheRangeFilterPtr newStringRange(const String& field, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); - + /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String)}. This works with all - /// byte fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// byte fields containing exactly one numeric term in the field. The range can be half-open by setting one of the /// values to null. static FieldCacheRangeFilterPtr newByteRange(const String& field, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr)}. This - /// works with all byte fields containing exactly one numeric term in the field. The range can be half-open by + + /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr)}. This + /// works with all byte fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. static FieldCacheRangeFilterPtr newByteRange(const String& field, ByteParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); - + /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String)}. This works with all - /// int fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// int fields containing exactly one numeric term in the field. The range can be half-open by setting one of the /// values to null. static FieldCacheRangeFilterPtr newIntRange(const String& field, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String, IntParserPtr)}. This - /// works with all int fields containing exactly one numeric term in the field. The range can be half-open by + + /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String, IntParserPtr)}. This + /// works with all int fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. static FieldCacheRangeFilterPtr newIntRange(const String& field, IntParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); - + /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String)}. This works with all - /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the /// values to null. static FieldCacheRangeFilterPtr newLongRange(const String& field, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr)}. This - /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by + + /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr)}. This + /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. static FieldCacheRangeFilterPtr newLongRange(const String& field, LongParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); - + /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String)}. This works with all - /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the /// values to null. static FieldCacheRangeFilterPtr newDoubleRange(const String& field, double lowerVal, double upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr)}. This - /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by + + /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr)}. This + /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. static FieldCacheRangeFilterPtr newDoubleRange(const String& field, DoubleParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); - + virtual String toString() = 0; virtual bool equals(LuceneObjectPtr other) = 0; virtual int32_t hashCode() = 0; - + /// Returns the field name for this filter virtual String getField(); - + /// Returns true if the lower endpoint is inclusive virtual bool includesLower(); - + /// Returns true if the upper endpoint is inclusive virtual bool includesUpper(); - + /// Returns the current numeric parser virtual ParserPtr getParser(); }; diff --git a/include/FieldCacheSanityChecker.h b/include/FieldCacheSanityChecker.h index d046d731..7957b185 100644 --- a/include/FieldCacheSanityChecker.h +++ b/include/FieldCacheSanityChecker.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,12 +14,12 @@ namespace Lucene { /// Provides methods for sanity checking that entries in the FieldCache are not wasteful or inconsistent. /// - /// Lucene 2.9 Introduced numerous enhancements into how the FieldCache is used by the low levels of Lucene - /// searching (for Sorting and ValueSourceQueries) to improve both the speed for Sorting, as well as reopening - /// of IndexReaders. But these changes have shifted the usage of FieldCache from "top level" IndexReaders - /// (frequently a MultiReader or DirectoryReader) down to the leaf level SegmentReaders. As a result, - /// existing applications that directly access the FieldCache may find RAM usage increase significantly when - /// upgrading to 2.9 or later. This class provides an API for these applications (or their Unit tests) to + /// Lucene 2.9 Introduced numerous enhancements into how the FieldCache is used by the low levels of Lucene + /// searching (for Sorting and ValueSourceQueries) to improve both the speed for Sorting, as well as reopening + /// of IndexReaders. But these changes have shifted the usage of FieldCache from "top level" IndexReaders + /// (frequently a MultiReader or DirectoryReader) down to the leaf level SegmentReaders. As a result, + /// existing applications that directly access the FieldCache may find RAM usage increase significantly when + /// upgrading to 2.9 or later. This class provides an API for these applications (or their Unit tests) to /// check at run time if the FieldCache contains "insane" usages of the FieldCache. /// /// @see FieldCache @@ -30,94 +30,94 @@ namespace Lucene public: FieldCacheSanityChecker(); virtual ~FieldCacheSanityChecker(); - + LUCENE_CLASS(FieldCacheSanityChecker); - + public: typedef MapOfSets< int32_t, boost::hash, std::equal_to, FieldCacheEntryPtr, luceneHash, luceneEquals > MapSetIntFieldCacheEntry; typedef MapOfSets< ReaderFieldPtr, luceneHash, luceneEquals, int32_t, boost::hash, std::equal_to > MapSetReaderFieldInt; typedef MapOfSets< ReaderFieldPtr, luceneHash, luceneEquals, ReaderFieldPtr, luceneHash, luceneEquals > MapSetReaderFieldReaderField; - + /// An Enumeration of the different types of "insane" behaviour that may be detected in a FieldCache. enum InsanityType { /// Indicates an overlap in cache usage on a given field in sub/super readers. SUBREADER, - - /// Indicates entries have the same reader+fieldname but different cached values. This can happen - /// if different datatypes, or parsers are used -- and while it's not necessarily a bug it's + + /// Indicates entries have the same reader+fieldname but different cached values. This can happen + /// if different datatypes, or parsers are used -- and while it's not necessarily a bug it's /// typically an indication of a possible problem. /// - /// NOTE: Only the reader, fieldname, and cached value are actually tested -- if two cache entries - /// have different parsers or datatypes but the cached values are the same Object (== not just equal()) - /// this method does not consider that a red flag. This allows for subtle variations in the way a + /// NOTE: Only the reader, fieldname, and cached value are actually tested -- if two cache entries + /// have different parsers or datatypes but the cached values are the same Object (== not just equal()) + /// this method does not consider that a red flag. This allows for subtle variations in the way a /// Parser is specified (null vs DEFAULT_LONG_PARSER, etc...) VALUEMISMATCH, - - /// Indicates an expected bit of "insanity". This may be useful for clients that wish to preserve/log - /// information about insane usage but indicate that it was expected. + + /// Indicates an expected bit of "insanity". This may be useful for clients that wish to preserve/log + /// information about insane usage but indicate that it was expected. EXPECTED }; - + /// Quick and dirty convenience method /// @see #check static Collection checkSanity(FieldCachePtr cache); - - /// Quick and dirty convenience method that instantiates an instance with "good defaults" and uses it to + + /// Quick and dirty convenience method that instantiates an instance with "good defaults" and uses it to /// test the CacheEntrys. /// @see #check static Collection checkSanity(Collection cacheEntries); - + /// Tests a CacheEntry[] for indication of "insane" cache usage. /// NOTE: FieldCache CreationPlaceholder objects are ignored. Collection check(Collection cacheEntries); - + protected: - /// Internal helper method used by check that iterates over valMismatchKeys and generates a Collection of - /// Insanity instances accordingly. The MapOfSets are used to populate the Insanity objects. + /// Internal helper method used by check that iterates over valMismatchKeys and generates a Collection of + /// Insanity instances accordingly. The MapOfSets are used to populate the Insanity objects. /// @see InsanityType#VALUEMISMATCH - Collection checkValueMismatch(MapSetIntFieldCacheEntry valIdToItems, + Collection checkValueMismatch(MapSetIntFieldCacheEntry valIdToItems, MapSetReaderFieldInt readerFieldToValIds, SetReaderField valMismatchKeys); - - /// Internal helper method used by check that iterates over the keys of readerFieldToValIds and generates a - /// Collection of Insanity instances whenever two (or more) ReaderField instances are found that have an + + /// Internal helper method used by check that iterates over the keys of readerFieldToValIds and generates a + /// Collection of Insanity instances whenever two (or more) ReaderField instances are found that have an /// ancestry relationships. /// @see InsanityType#SUBREADER Collection checkSubreaders(MapSetIntFieldCacheEntry valIdToItems, MapSetReaderFieldInt readerFieldToValIds); - /// Checks if the seed is an IndexReader, and if so will walk the hierarchy of subReaders building up a + /// Checks if the seed is an IndexReader, and if so will walk the hierarchy of subReaders building up a /// list of the objects returned by obj.getFieldCacheKey() Collection getAllDecendentReaderKeys(LuceneObjectPtr seed); }; - - /// Simple container for a collection of related CacheEntry objects that in conjunction with each other + + /// Simple container for a collection of related CacheEntry objects that in conjunction with each other /// represent some "insane" usage of the FieldCache. class LPPAPI Insanity : public LuceneObject { public: Insanity(FieldCacheSanityChecker::InsanityType type, const String& msg, Collection entries); virtual ~Insanity(); - + LUCENE_CLASS(Insanity); - + protected: FieldCacheSanityChecker::InsanityType type; String msg; Collection entries; - + public: /// Type of insane behavior this object represents FieldCacheSanityChecker::InsanityType getType(); - + /// Description of the insane behaviour String getMsg(); - + /// CacheEntry objects which suggest a problem Collection getCacheEntries(); - - /// Multi-Line representation of this Insanity object, starting with the Type and Msg, followed by each + + /// Multi-Line representation of this Insanity object, starting with the Type and Msg, followed by each /// CacheEntry.toString() on it's own line prefaced by a tab character virtual String toString(); }; diff --git a/include/FieldCacheSource.h b/include/FieldCacheSource.h index b5860e7a..e3d52507 100644 --- a/include/FieldCacheSource.h +++ b/include/FieldCacheSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,18 +11,18 @@ namespace Lucene { - /// A base class for ValueSource implementations that retrieve values for a single field from the + /// A base class for ValueSource implementations that retrieve values for a single field from the /// {@link FieldCache}. /// /// Fields used herein must be indexed (doesn't matter if these fields are stored or not). /// /// It is assumed that each such indexed field is untokenized, or at least has a single token in a document. - /// For documents with multiple tokens of the same field, behavior is undefined (It is likely that current + /// For documents with multiple tokens of the same field, behavior is undefined (It is likely that current /// code would use the value of one of these tokens, but this is not guaranteed). /// - /// Document with no tokens in this field are assigned the Zero value. + /// Document with no tokens in this field are assigned the Zero value. /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite + /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's /// best to switch your application to pass only atomic (single segment) readers to this API. class LPPAPI FieldCacheSource : public ValueSource @@ -31,30 +31,30 @@ namespace Lucene /// Create a cached field source for the input field. FieldCacheSource(const String& field); virtual ~FieldCacheSource(); - + LUCENE_CLASS(FieldCacheSource); - + protected: String field; - + public: virtual DocValuesPtr getValues(IndexReaderPtr reader); virtual String description(); - + /// Return cached DocValues for input field and reader. /// @param cache FieldCache so that values of a field are loaded once per reader (RAM allowing) /// @param field Field for which values are required. /// @see ValueSource virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) = 0; - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - - /// Check if equals to another {@link FieldCacheSource}, already knowing that cache and field are equal. + + /// Check if equals to another {@link FieldCacheSource}, already knowing that cache and field are equal. virtual bool cachedFieldSourceEquals(FieldCacheSourcePtr other) = 0; - - /// Return a hash code of a {@link FieldCacheSource}, without the hash-codes of the field and the cache - /// (those are taken care of elsewhere). + + /// Return a hash code of a {@link FieldCacheSource}, without the hash-codes of the field and the cache + /// (those are taken care of elsewhere). virtual int32_t cachedFieldSourceHashCode() = 0; }; } diff --git a/include/FieldCacheTermsFilter.h b/include/FieldCacheTermsFilter.h index 6a561fb5..6e0b6d9f 100644 --- a/include/FieldCacheTermsFilter.h +++ b/include/FieldCacheTermsFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,35 +11,35 @@ namespace Lucene { - /// A {@link Filter} that only accepts documents whose single term value in the specified field is contained + /// A {@link Filter} that only accepts documents whose single term value in the specified field is contained /// in the provided set of allowed terms. /// /// This is the same functionality as TermsFilter (from contrib/queries), except this filter requires that the - /// field contains only a single term for all documents. Because of drastically different implementations, + /// field contains only a single term for all documents. Because of drastically different implementations, /// they also have different performance characteristics, as described below. /// /// The first invocation of this filter on a given field will be slower, since a {@link StringIndex} must be - /// created. Subsequent invocations using the same field will re-use this cache. However, as with all - /// functionality based on {@link FieldCache}, persistent RAM is consumed to hold the cache, and is not freed + /// created. Subsequent invocations using the same field will re-use this cache. However, as with all + /// functionality based on {@link FieldCache}, persistent RAM is consumed to hold the cache, and is not freed /// until the {@link IndexReader} is closed. In contrast, TermsFilter has no persistent RAM consumption. /// - /// With each search, this filter translates the specified set of Terms into a private {@link OpenBitSet} keyed - /// by term number per unique {@link IndexReader} (normally one reader per segment). Then, during matching, - /// the term number for each docID is retrieved from the cache and then checked for inclusion using the {@link - /// OpenBitSet}. Since all testing is done using RAM resident data structures, performance should be very fast, - /// most likely fast enough to not require further caching of the DocIdSet for each possible combination of - /// terms. However, because docIDs are simply scanned linearly, an index with a great many small documents may + /// With each search, this filter translates the specified set of Terms into a private {@link OpenBitSet} keyed + /// by term number per unique {@link IndexReader} (normally one reader per segment). Then, during matching, + /// the term number for each docID is retrieved from the cache and then checked for inclusion using the {@link + /// OpenBitSet}. Since all testing is done using RAM resident data structures, performance should be very fast, + /// most likely fast enough to not require further caching of the DocIdSet for each possible combination of + /// terms. However, because docIDs are simply scanned linearly, an index with a great many small documents may /// find this linear scan too costly. /// - /// In contrast, TermsFilter builds up an {@link OpenBitSet}, keyed by docID, every time it's created, by + /// In contrast, TermsFilter builds up an {@link OpenBitSet}, keyed by docID, every time it's created, by /// enumerating through all matching docs using {@link TermDocs} to seek and scan through each term's docID list. - /// While there is no linear scan of all docIDs, besides the allocation of the underlying array in the {@link - /// OpenBitSet}, this approach requires a number of "disk seeks" in proportion to the number of terms, which can + /// While there is no linear scan of all docIDs, besides the allocation of the underlying array in the {@link + /// OpenBitSet}, this approach requires a number of "disk seeks" in proportion to the number of terms, which can /// be exceptionally costly when there are cache misses in the OS's IO cache. /// /// Generally, this filter will be slower on the first invocation for a given field, but subsequent invocations, /// even if you change the allowed set of Terms, should be faster than TermsFilter, especially as the number of - /// Terms being matched increases. If you are matching only a very small number of terms, and those terms in + /// Terms being matched increases. If you are matching only a very small number of terms, and those terms in /// turn match a very small number of documents, TermsFilter may perform faster. /// /// Which filter is best is very application dependent. @@ -48,16 +48,16 @@ namespace Lucene public: FieldCacheTermsFilter(const String& field, Collection terms); virtual ~FieldCacheTermsFilter(); - + LUCENE_CLASS(FieldCacheTermsFilter); - + protected: String field; Collection terms; - + public: FieldCachePtr getFieldCache(); - + virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); }; } diff --git a/include/FieldComparator.h b/include/FieldComparator.h index 0c61fb44..8c6b905a 100644 --- a/include/FieldComparator.h +++ b/include/FieldComparator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,11 +11,11 @@ namespace Lucene { - /// A FieldComparator compares hits so as to determine their sort order when collecting the top results with + /// A FieldComparator compares hits so as to determine their sort order when collecting the top results with /// {@link TopFieldCollector}. The concrete public FieldComparator classes here correspond to the SortField types. /// /// This API is designed to achieve high performance sorting, by exposing a tight interaction with {@link - /// FieldValueHitQueue} as it visits hits. Whenever a hit is competitive, it's enrolled into a virtual slot, + /// FieldValueHitQueue} as it visits hits. Whenever a hit is competitive, it's enrolled into a virtual slot, /// which is an int ranging from 0 to numHits-1. The {@link FieldComparator} is made aware of segment transitions /// during searching in case any internal state it's tracking needs to be recomputed during these transitions. /// @@ -23,74 +23,74 @@ namespace Lucene ///
      ///
    • {@link #compare} Compare a hit at 'slot a' with hit 'slot b'. /// - ///
    • {@link #setBottom} This method is called by {@link FieldValueHitQueue} to notify the FieldComparator of - /// the current weakest ("bottom") slot. Note that this slot may not hold the weakest value according to your - /// comparator, in cases where your comparator is not the primary one (ie, is only used to break ties from the + ///
    • {@link #setBottom} This method is called by {@link FieldValueHitQueue} to notify the FieldComparator of + /// the current weakest ("bottom") slot. Note that this slot may not hold the weakest value according to your + /// comparator, in cases where your comparator is not the primary one (ie, is only used to break ties from the /// comparators before it). /// ///
    • {@link #compareBottom} Compare a new hit (docID) against the "weakest" (bottom) entry in the queue. /// - ///
    • {@link #copy} Installs a new hit into the priority queue. The {@link FieldValueHitQueue} calls this + ///
    • {@link #copy} Installs a new hit into the priority queue. The {@link FieldValueHitQueue} calls this /// method when a new hit is competitive. /// - ///
    • {@link #setNextReader} Invoked when the search is switching to the next segment. You may need to update + ///
    • {@link #setNextReader} Invoked when the search is switching to the next segment. You may need to update /// internal state of the comparator, for example retrieving new values from the {@link FieldCache}. /// - ///
    • {@link #value} Return the sort value stored in the specified slot. This is only called at the end of + ///
    • {@link #value} Return the sort value stored in the specified slot. This is only called at the end of /// the search, in order to populate {@link FieldDoc#fields} when returning the top results. ///
    class LPPAPI FieldComparator : public LuceneObject { public: - virtual ~FieldComparator(); + virtual ~FieldComparator(); LUCENE_CLASS(FieldComparator); - + public: /// Compare hit at slot1 with hit at slot2. /// @param slot1 first slot to compare /// @param slot2 second slot to compare - /// @return any N < 0 if slot2's value is sorted after slot1, any N > 0 if the slot2's value is sorted + /// @return any N < 0 if slot2's value is sorted after slot1, any N > 0 if the slot2's value is sorted /// before slot1 and 0 if they are equal virtual int32_t compare(int32_t slot1, int32_t slot2) = 0; - - /// Set the bottom slot, ie the "weakest" (sorted last) entry in the queue. When {@link #compareBottom} + + /// Set the bottom slot, ie the "weakest" (sorted last) entry in the queue. When {@link #compareBottom} /// is called, you should compare against this slot. This will always be called before {@link #compareBottom}. /// @param slot the currently weakest (sorted last) slot in the queue virtual void setBottom(int32_t slot) = 0; - - /// Compare the bottom of the queue with doc. This will only invoked after setBottom has been called. + + /// Compare the bottom of the queue with doc. This will only invoked after setBottom has been called. /// This should return the same result as {@link #compare(int,int)}} as if bottom were slot1 and the new /// document were slot 2. /// /// For a search that hits many results, this method will be the hotspot (invoked by far the most frequently). /// /// @param doc that was hit - /// @return any N < 0 if the doc's value is sorted after the bottom entry (not competitive), any N > 0 if + /// @return any N < 0 if the doc's value is sorted after the bottom entry (not competitive), any N > 0 if /// the doc's value is sorted before the bottom entry and 0 if they are equal. virtual int32_t compareBottom(int32_t doc) = 0; - - /// This method is called when a new hit is competitive. You should copy any state associated with this + + /// This method is called when a new hit is competitive. You should copy any state associated with this /// document that will be required for future comparisons, into the specified slot. /// @param slot which slot to copy the hit to /// @param doc docID relative to current reader virtual void copy(int32_t slot, int32_t doc) = 0; - + /// Set a new Reader. All doc correspond to the current Reader. /// /// @param reader current reader - /// @param docBase docBase of this reader + /// @param docBase docBase of this reader virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) = 0; - + /// Sets the Scorer to use in case a document's score is needed. /// @param scorer Scorer instance that you should use to obtain the current hit's score, if necessary. virtual void setScorer(ScorerPtr scorer); - + /// Return the actual value in the slot. /// @param slot the value /// @return value in this slot upgraded to ComparableValue virtual ComparableValue value(int32_t slot) = 0; }; - + template class NumericComparator : public FieldComparator { @@ -101,146 +101,146 @@ namespace Lucene this->field = field; this->bottom = 0; } - + virtual ~NumericComparator() { } - + protected: Collection values; Collection currentReaderValues; String field; TYPE bottom; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2) { return (int32_t)(values[slot1] - values[slot2]); } - + virtual int32_t compareBottom(int32_t doc) { return (int32_t)(bottom - currentReaderValues[doc]); } - + virtual void copy(int32_t slot, int32_t doc) { values[slot] = currentReaderValues[doc]; } - + virtual void setBottom(int32_t slot) { bottom = values[slot]; } - + virtual ComparableValue value(int32_t slot) { return ComparableValue(values[slot]); } }; - + /// Parses field's values as byte (using {@link FieldCache#getBytes} and sorts by ascending value. class LPPAPI ByteComparator : public NumericComparator { public: ByteComparator(int32_t numHits, const String& field, ParserPtr parser); - virtual ~ByteComparator(); - + virtual ~ByteComparator(); + LUCENE_CLASS(ByteComparator); - + protected: ByteParserPtr parser; - + public: virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); }; - + /// Sorts by ascending docID class LPPAPI DocComparator : public NumericComparator { public: DocComparator(int32_t numHits); - virtual ~DocComparator(); - + virtual ~DocComparator(); + LUCENE_CLASS(DocComparator); - + protected: int32_t docBase; - + public: virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); }; - + /// Parses field's values as double (using {@link FieldCache#getDoubles} and sorts by ascending value class LPPAPI DoubleComparator : public NumericComparator { public: DoubleComparator(int32_t numHits, const String& field, ParserPtr parser); - virtual ~DoubleComparator(); - + virtual ~DoubleComparator(); + LUCENE_CLASS(DoubleComparator); - + protected: DoubleParserPtr parser; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); }; - + /// Parses field's values as int (using {@link FieldCache#getInts} and sorts by ascending value class LPPAPI IntComparator : public NumericComparator { public: IntComparator(int32_t numHits, const String& field, ParserPtr parser); - virtual ~IntComparator(); - + virtual ~IntComparator(); + LUCENE_CLASS(IntComparator); - + protected: IntParserPtr parser; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); }; - + /// Parses field's values as long (using {@link FieldCache#getLongs} and sorts by ascending value class LPPAPI LongComparator : public NumericComparator { public: LongComparator(int32_t numHits, const String& field, ParserPtr parser); - virtual ~LongComparator(); - + virtual ~LongComparator(); + LUCENE_CLASS(LongComparator); - + protected: LongParserPtr parser; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); }; - - /// Sorts by descending relevance. NOTE: if you are sorting only by descending relevance and then secondarily - /// by ascending docID, performance is faster using {@link TopScoreDocCollector} directly (which {@link + + /// Sorts by descending relevance. NOTE: if you are sorting only by descending relevance and then secondarily + /// by ascending docID, performance is faster using {@link TopScoreDocCollector} directly (which {@link /// IndexSearcher#search} uses when no {@link Sort} is specified). class LPPAPI RelevanceComparator : public NumericComparator { public: RelevanceComparator(int32_t numHits); - virtual ~RelevanceComparator(); - + virtual ~RelevanceComparator(); + LUCENE_CLASS(RelevanceComparator); - + protected: ScorerPtr scorer; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); @@ -248,99 +248,99 @@ namespace Lucene virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); virtual void setScorer(ScorerPtr scorer); }; - + /// Sorts by a field's value using the Collator for a given Locale. class LPPAPI StringComparatorLocale : public FieldComparator { public: StringComparatorLocale(int32_t numHits, const String& field, const std::locale& locale); - virtual ~StringComparatorLocale(); - + virtual ~StringComparatorLocale(); + LUCENE_CLASS(StringComparatorLocale); - + protected: Collection values; Collection currentReaderValues; String field; CollatorPtr collator; String bottom; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setBottom(int32_t slot); + virtual void setBottom(int32_t slot); virtual ComparableValue value(int32_t slot); }; - + /// Sorts by field's natural String sort order, using ordinals. This is functionally equivalent to {@link - /// StringValComparator}, but it first resolves the string to their relative ordinal positions (using the - /// index returned by {@link FieldCache#getStringIndex}), and does most comparisons using the ordinals. - /// For medium to large results, this comparator will be much faster than {@link StringValComparator}. For + /// StringValComparator}, but it first resolves the string to their relative ordinal positions (using the + /// index returned by {@link FieldCache#getStringIndex}), and does most comparisons using the ordinals. + /// For medium to large results, this comparator will be much faster than {@link StringValComparator}. For /// very small result sets it may be slower. class LPPAPI StringOrdValComparator : public FieldComparator { public: StringOrdValComparator(int32_t numHits, const String& field, int32_t sortPos, bool reversed); - virtual ~StringOrdValComparator(); - + virtual ~StringOrdValComparator(); + LUCENE_CLASS(StringOrdValComparator); - + protected: Collection ords; Collection values; Collection readerGen; - + int32_t currentReaderGen; Collection lookup; Collection order; String field; - + int32_t bottomSlot; int32_t bottomOrd; String bottomValue; bool reversed; int32_t sortPos; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setBottom(int32_t slot); + virtual void setBottom(int32_t slot); virtual ComparableValue value(int32_t slot); virtual Collection getValues(); virtual int32_t getBottomSlot(); virtual String getField(); - + protected: void convert(int32_t slot); int32_t binarySearch(Collection lookup, const String& key, int32_t low, int32_t high); }; - + /// Sorts by field's natural String sort order. All comparisons are done using String.compare, which is /// slow for medium to large result sets but possibly very fast for very small results sets. class LPPAPI StringValComparator : public FieldComparator { public: StringValComparator(int32_t numHits, const String& field); - virtual ~StringValComparator(); - + virtual ~StringValComparator(); + LUCENE_CLASS(StringOrdValComparator); - + protected: Collection values; Collection currentReaderValues; String field; String bottom; - + public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setBottom(int32_t slot); + virtual void setBottom(int32_t slot); virtual ComparableValue value(int32_t slot); }; } diff --git a/include/FieldComparatorSource.h b/include/FieldComparatorSource.h index aeade930..59a7a193 100644 --- a/include/FieldComparatorSource.h +++ b/include/FieldComparatorSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,7 +17,7 @@ namespace Lucene public: virtual ~FieldComparatorSource(); LUCENE_CLASS(FieldComparatorSource); - + public: /// Creates a comparator for the field in the given index. /// @param fieldname Name of the field to create comparator for. diff --git a/include/FieldDoc.h b/include/FieldDoc.h index 1e3c7b1a..9add14af 100644 --- a/include/FieldDoc.h +++ b/include/FieldDoc.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,27 +12,27 @@ namespace Lucene { /// A ScoreDoc which also contains information about how to sort the referenced document. In addition to the - /// document number and score, this object contains an array of values for the document from the field(s) used + /// document number and score, this object contains an array of values for the document from the field(s) used /// to sort. For example, if the sort criteria was to sort by fields "a", "b" then "c", the fields object array - /// will have three elements, corresponding respectively to the term values for the document in fields "a", "b" - /// and "c". The class of each element in the array will be either Integer, Double or String depending on the + /// will have three elements, corresponding respectively to the term values for the document in fields "a", "b" + /// and "c". The class of each element in the array will be either Integer, Double or String depending on the /// type of values in the terms of each field. class LPPAPI FieldDoc : public ScoreDoc { public: FieldDoc(int32_t doc, double score, Collection fields = Collection()); virtual ~FieldDoc(); - + LUCENE_CLASS(FieldDoc); - + public: - /// The values which are used to sort the referenced document. The order of these will match the original - /// sort criteria given by a Sort object. Each Object will be either an Integer, Double or String, depending + /// The values which are used to sort the referenced document. The order of these will match the original + /// sort criteria given by a Sort object. Each Object will be either an Integer, Double or String, depending /// on the type of values in the terms of the original field. /// @see Sort /// @see Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr) Collection fields; - + public: virtual String toString(); }; diff --git a/include/FieldDocSortedHitQueue.h b/include/FieldDocSortedHitQueue.h index cb1b4c0f..4a73b3b8 100644 --- a/include/FieldDocSortedHitQueue.h +++ b/include/FieldDocSortedHitQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,39 +11,39 @@ namespace Lucene { - /// Collects sorted results from Searchable's and collates them. + /// Collects sorted results from Searchable's and collates them. /// The elements put into this queue must be of type FieldDoc. class FieldDocSortedHitQueue : public PriorityQueue { public: FieldDocSortedHitQueue(int32_t size); virtual ~FieldDocSortedHitQueue(); - + LUCENE_CLASS(FieldDocSortedHitQueue); - + public: Collection fields; - + // used in the case where the fields are sorted by locale based strings Collection collators; - + public: - /// Allows redefinition of sort fields if they are null. This is to handle the case using - /// ParallelMultiSearcher where the original list contains AUTO and we don't know the actual sort - /// type until the values come back. The fields can only be set once. This method should be + /// Allows redefinition of sort fields if they are null. This is to handle the case using + /// ParallelMultiSearcher where the original list contains AUTO and we don't know the actual sort + /// type until the values come back. The fields can only be set once. This method should be /// synchronized external like all other PQ methods. void setFields(Collection fields); - + /// Returns the fields being used to sort. Collection getFields(); - + protected: - /// Returns an array of collators, possibly null. The collators correspond to any SortFields which + /// Returns an array of collators, possibly null. The collators correspond to any SortFields which /// were given a specific locale. /// @param fields Array of sort fields. /// @return Array, possibly null. Collection hasCollators(Collection fields); - + /// Returns whether first is less relevant than second. virtual bool lessThan(const FieldDocPtr& first, const FieldDocPtr& second); }; diff --git a/include/FieldInfo.h b/include/FieldInfo.h index 012cc664..deff6480 100644 --- a/include/FieldInfo.h +++ b/include/FieldInfo.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,31 +14,31 @@ namespace Lucene class FieldInfo : public LuceneObject { public: - FieldInfo(const String& na, bool tk, int32_t nu, bool storeTermVector, bool storePositionWithTermVector, + FieldInfo(const String& na, bool tk, int32_t nu, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); virtual ~FieldInfo(); - + LUCENE_CLASS(FieldInfo); - + public: String name; bool isIndexed; int32_t number; - + // true if term vector for this field should be stored bool storeTermVector; bool storeOffsetWithTermVector; bool storePositionWithTermVector; - - bool omitNorms; // omit norms associated with indexed fields + + bool omitNorms; // omit norms associated with indexed fields bool omitTermFreqAndPositions; - + bool storePayloads; // whether this field stores payloads together with term positions - + public: virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - - void update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, + + void update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); }; } diff --git a/include/FieldInfos.h b/include/FieldInfos.h index 475eb561..aa6e8977 100644 --- a/include/FieldInfos.h +++ b/include/FieldInfos.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,28 +11,28 @@ namespace Lucene { - /// Access to the Fieldable Info file that describes document fields and whether or not they are indexed. - /// Each segment has a separate Fieldable Info file. Objects of this class are thread-safe for multiple + /// Access to the Fieldable Info file that describes document fields and whether or not they are indexed. + /// Each segment has a separate Fieldable Info file. Objects of this class are thread-safe for multiple /// readers, but only one thread can be adding documents at a time, with no other reader or writer threads /// accessing this object. class FieldInfos : public LuceneObject { public: FieldInfos(); - + /// Construct a FieldInfos object using the directory and the name of the file IndexInput /// @param d The directory to open the IndexInput from /// @param name The name of the file to open the IndexInput from in the Directory FieldInfos(DirectoryPtr d, const String& name); - + virtual ~FieldInfos(); - + LUCENE_CLASS(FieldInfos); - + public: // Used internally (ie not written to *.fnm files) for pre-2.9 files static const int32_t FORMAT_PRE; - + // First used in 2.9; prior to 2.9 there was no format header static const int32_t FORMAT_START; @@ -45,49 +45,49 @@ namespace Lucene static const uint8_t OMIT_NORMS; static const uint8_t STORE_PAYLOADS; static const uint8_t OMIT_TERM_FREQ_AND_POSITIONS; - + protected: Collection byNumber; MapStringFieldInfo byName; int32_t format; - + public: /// Returns a deep clone of this FieldInfos instance. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Adds field info for a Document. void add(DocumentPtr doc); - + /// Returns true if any fields do not omitTermFreqAndPositions bool hasProx(); - + /// Add fields that are indexed. Whether they have termvectors has to be specified. /// @param names The names of the fields /// @param storeTermVectors Whether the fields store term vectors or not /// @param storePositionWithTermVector true if positions should be stored. /// @param storeOffsetWithTermVector true if offsets should be stored void addIndexed(HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector); - + /// Assumes the fields are not storing term vectors. /// @param names The names of the fields /// @param isIndexed Whether the fields are indexed or not /// @see #add(const String&, bool) void add(HashSet names, bool isIndexed); - + /// Calls 5 parameter add with false for all TermVector parameters. /// @param name The name of the Fieldable /// @param isIndexed true if the field is indexed /// @see #add(const String&, bool, bool, bool, bool) void add(const String& name, bool isIndexed); - + /// Calls 5 parameter add with false for term vector positions and offsets. /// @param name The name of the field /// @param isIndexed true if the field is indexed /// @param storeTermVector true if the term vector should be stored void add(const String& name, bool isIndexed, bool storeTermVector); - - /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag - /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes + + /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag + /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes /// for the TermVector parameters. /// @param name The name of the field /// @param isIndexed true if the field is indexed @@ -95,9 +95,9 @@ namespace Lucene /// @param storePositionWithTermVector true if the term vector with positions should be stored /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored void add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector); - - /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag - /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes + + /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag + /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes /// for the TermVector parameters. /// @param name The name of the field /// @param isIndexed true if the field is indexed @@ -105,11 +105,11 @@ namespace Lucene /// @param storePositionWithTermVector true if the term vector with positions should be stored /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored /// @param omitNorms true if the norms for the indexed field should be omitted - void add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + void add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms); - - /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed - /// flag is the same as was given previously for this field. If not - marks it as being indexed. + + /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed + /// flag is the same as was given previously for this field. If not - marks it as being indexed. /// Same goes for the TermVector parameters. /// @param name The name of the field /// @param isIndexed true if the field is indexed @@ -119,31 +119,31 @@ namespace Lucene /// @param omitNorms true if the norms for the indexed field should be omitted /// @param storePayloads true if payloads should be stored for this field /// @param omitTermFreqAndPositions true if term freqs should be omitted for this field - FieldInfoPtr add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + FieldInfoPtr add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); - + int32_t fieldNumber(const String& fieldName); FieldInfoPtr fieldInfo(const String& fieldName); - + /// Return the fieldName identified by its number. /// @return the fieldName or an empty string when the field with the given number doesn't exist. String fieldName(int32_t fieldNumber); - + /// Return the fieldinfo object referenced by the fieldNumber. /// @return the FieldInfo object or null when the given fieldNumber doesn't exist. FieldInfoPtr fieldInfo(int32_t fieldNumber); - + int32_t size(); - + bool hasVectors(); - + void write(DirectoryPtr d, const String& name); void write(IndexOutputPtr output); - + protected: - FieldInfoPtr addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + FieldInfoPtr addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); - + void read(IndexInputPtr input, const String& fileName); }; } diff --git a/include/FieldInvertState.h b/include/FieldInvertState.h index b74283ed..53cd0b01 100644 --- a/include/FieldInvertState.h +++ b/include/FieldInvertState.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,16 +11,16 @@ namespace Lucene { - /// This class tracks the number and position / offset parameters of terms being added to the index. + /// This class tracks the number and position / offset parameters of terms being added to the index. /// The information collected in this class is also used to calculate the normalization factor for a field. class LPPAPI FieldInvertState : public LuceneObject { public: FieldInvertState(int32_t position = 0, int32_t length = 0, int32_t numOverlap = 0, int32_t offset = 0, double boost = 0); virtual ~FieldInvertState(); - + LUCENE_CLASS(FieldInvertState); - + INTERNAL: int32_t position; int32_t length; @@ -28,33 +28,33 @@ namespace Lucene int32_t offset; double boost; AttributeSourcePtr attributeSource; - + public: /// Re-initialize the state, using this boost value. /// @param docBoost boost value to use. void reset(double docBoost); - + /// Get the last processed term position. /// @return the position int32_t getPosition(); - + /// Get total number of terms in this field. /// @return the length int32_t getLength(); - + /// Get the number of terms with positionIncrement == 0. /// @return the numOverlap int32_t getNumOverlap(); - + /// Get end offset of the last processed term. /// @return the offset int32_t getOffset(); - - /// Get boost value. This is the cumulative product of document boost and field boost for all field + + /// Get boost value. This is the cumulative product of document boost and field boost for all field /// instances sharing the same field name. /// @return the boost double getBoost(); - + AttributeSourcePtr getAttributeSource(); }; } diff --git a/include/FieldMaskingSpanQuery.h b/include/FieldMaskingSpanQuery.h index 5dd97fcd..09fb1f6b 100644 --- a/include/FieldMaskingSpanQuery.h +++ b/include/FieldMaskingSpanQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,14 +11,14 @@ namespace Lucene { - /// Wrapper to allow {@link SpanQuery} objects participate in composite single-field SpanQueries by - /// 'lying' about their search field. That is, the masked SpanQuery will function as normal, but + /// Wrapper to allow {@link SpanQuery} objects participate in composite single-field SpanQueries by + /// 'lying' about their search field. That is, the masked SpanQuery will function as normal, but /// {@link SpanQuery#getField()} simply hands back the value supplied in this class's constructor. /// - /// This can be used to support Queries like {@link SpanNearQuery} or {@link SpanOrQuery} across + /// This can be used to support Queries like {@link SpanNearQuery} or {@link SpanOrQuery} across /// different fields, which is not ordinarily permitted. /// - /// This can be useful for denormalized relational data: for example, when indexing a document with + /// This can be useful for denormalized relational data: for example, when indexing a document with /// conceptually many 'children': /// ///
    @@ -44,26 +44,26 @@ namespace Lucene
         ///
         /// QueryPtr q = newLucene(span, -1, false);
         /// 
    - /// to search for 'studentfirstname:james studentsurname:jones' and find teacherid 1 without matching + /// to search for 'studentfirstname:james studentsurname:jones' and find teacherid 1 without matching /// teacherid 2 (which has a 'james' in position 0 and 'jones' in position 1). /// - /// Note: as {@link #getField()} returns the masked field, scoring will be done using the norms of the + /// Note: as {@link #getField()} returns the masked field, scoring will be done using the norms of the /// field name supplied. This may lead to unexpected scoring behaviour. class LPPAPI FieldMaskingSpanQuery : public SpanQuery { public: FieldMaskingSpanQuery(SpanQueryPtr maskedQuery, const String& maskedField); virtual ~FieldMaskingSpanQuery(); - + LUCENE_CLASS(FieldMaskingSpanQuery); - + protected: SpanQueryPtr maskedQuery; String field; - + public: using SpanQuery::toString; - + virtual String getField(); SpanQueryPtr getMaskedQuery(); virtual SpansPtr getSpans(IndexReaderPtr reader); @@ -71,11 +71,11 @@ namespace Lucene virtual WeightPtr createWeight(SearcherPtr searcher); virtual SimilarityPtr getSimilarity(SearcherPtr searcher); virtual QueryPtr rewrite(IndexReaderPtr reader); - + virtual String toString(const String& field); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + /// Returns a clone of this query. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); }; diff --git a/include/FieldScoreQuery.h b/include/FieldScoreQuery.h index 8c7cb9d4..ae6fe785 100644 --- a/include/FieldScoreQuery.h +++ b/include/FieldScoreQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene { /// A query that scores each document as the value of the numeric input field. /// - /// The query matches all documents, and scores each document according to the numeric value of that field. + /// The query matches all documents, and scores each document according to the numeric value of that field. /// /// It is assumed, and expected, that: ///
      @@ -22,23 +22,23 @@ namespace Lucene ///
    • That token is parseable to the selected type. ///
    /// - /// Combining this query in a FunctionQuery allows much freedom in affecting document scores. Note, that - /// with this freedom comes responsibility: it is more than likely that the default Lucene scoring is superior - /// in quality to scoring modified as explained here. However, in some cases, and certainly for research + /// Combining this query in a FunctionQuery allows much freedom in affecting document scores. Note, that + /// with this freedom comes responsibility: it is more than likely that the default Lucene scoring is superior + /// in quality to scoring modified as explained here. However, in some cases, and certainly for research /// experiments, this capability may turn useful. /// /// When constructing this query, select the appropriate type. That type should match the data stored in the - /// field. So in fact the "right" type should be selected before indexing. Type selection has effect on the - /// RAM usage: + /// field. So in fact the "right" type should be selected before indexing. Type selection has effect on the + /// RAM usage: ///
      ///
    • Byte consumes 1 * maxDocs bytes. ///
    • Int consumes 4 * maxDocs bytes. ///
    • Double consumes 8 * maxDocs bytes. ///
    /// - /// Caching: Values for the numeric field are loaded once and cached in memory for further use with the same + /// Caching: Values for the numeric field are loaded once and cached in memory for further use with the same /// IndexReader. To take advantage of this, it is extremely important to reuse index-readers or index- - /// searchers, otherwise, for instance if for each query a new index reader is opened, large penalties would + /// searchers, otherwise, for instance if for each query a new index reader is opened, large penalties would /// be paid for loading the field values into memory over and over again. class LPPAPI FieldScoreQuery : public ValueSourceQuery { @@ -48,26 +48,26 @@ namespace Lucene { /// Field values are interpreted as numeric byte values. BYTE, - + /// Field values are interpreted as numeric integer values. INT, - + /// Field values are interpreted as numeric double values. DOUBLE }; - + /// Create a FieldScoreQuery - a query that scores each document as the value of the numeric input field. /// The type param tells how to parse the field string values into a numeric score value. /// @param field the numeric field to be used. /// @param type the type of the field. FieldScoreQuery(const String& field, Type type); - + virtual ~FieldScoreQuery(); - + LUCENE_CLASS(FieldScoreQuery); - + public: - /// Create the appropriate (cached) field value source. + /// Create the appropriate (cached) field value source. static ValueSourcePtr getValueSource(const String& field, Type type); }; } diff --git a/include/FieldSelector.h b/include/FieldSelector.h index 628cc51c..fc56e567 100644 --- a/include/FieldSelector.h +++ b/include/FieldSelector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// The FieldSelector allows one to make decisions about what Fields get loaded on a {@link Document} by + /// The FieldSelector allows one to make decisions about what Fields get loaded on a {@link Document} by /// {@link IndexReader#document(int32_t, FieldSelector)} class LPPAPI FieldSelector : public LuceneObject { @@ -20,52 +20,52 @@ namespace Lucene public: virtual ~FieldSelector(); - + LUCENE_CLASS(FieldSelector); - + public: - /// Provides information about what should be done with this Field + /// Provides information about what should be done with this Field enum FieldSelectorResult { /// Null value SELECTOR_NULL, - - /// Load this {@link Field} every time the {@link Document} is loaded, reading in the data as it is - /// encountered. {@link Document#getField(String)} and {@link Document#getFieldable(String)} should + + /// Load this {@link Field} every time the {@link Document} is loaded, reading in the data as it is + /// encountered. {@link Document#getField(String)} and {@link Document#getFieldable(String)} should /// not return null. /// {@link Document#add(Fieldable)} should be called by the Reader. SELECTOR_LOAD, - - /// Lazily load this {@link Field}. This means the {@link Field} is valid, but it may not actually - /// contain its data until invoked. {@link Document#getField(String)} SHOULD NOT BE USED. {@link - /// Document#getFieldable(String)} is safe to use and should return a valid instance of a {@link + + /// Lazily load this {@link Field}. This means the {@link Field} is valid, but it may not actually + /// contain its data until invoked. {@link Document#getField(String)} SHOULD NOT BE USED. {@link + /// Document#getFieldable(String)} is safe to use and should return a valid instance of a {@link /// Fieldable}. /// {@link Document#add(Fieldable)} should be called by the Reader. SELECTOR_LAZY_LOAD, - - /// Do not load the {@link Field}. {@link Document#getField(String)} and {@link + + /// Do not load the {@link Field}. {@link Document#getField(String)} and {@link /// Document#getFieldable(String)} should return null. {@link Document#add(Fieldable)} is not called. /// {@link Document#add(Fieldable)} should not be called by the Reader. SELECTOR_NO_LOAD, - - /// Load this field as in the {@link #LOAD} case, but immediately return from {@link Field} loading - /// for the {@link Document}. Thus, the Document may not have its complete set of Fields. {@link - /// Document#getField(String)} and {@link Document#getFieldable(String)} should both be valid for + + /// Load this field as in the {@link #LOAD} case, but immediately return from {@link Field} loading + /// for the {@link Document}. Thus, the Document may not have its complete set of Fields. {@link + /// Document#getField(String)} and {@link Document#getFieldable(String)} should both be valid for /// this {@link Field} /// {@link Document#add(Fieldable)} should be called by the Reader. SELECTOR_LOAD_AND_BREAK, - - /// Load the size of this {@link Field} rather than its value. Size is measured as number of bytes - /// required to store the field == bytes for a binary or any compressed value, and 2*chars for a String - /// value. The size is stored as a binary value, represented as an int in a byte[], with the higher + + /// Load the size of this {@link Field} rather than its value. Size is measured as number of bytes + /// required to store the field == bytes for a binary or any compressed value, and 2*chars for a String + /// value. The size is stored as a binary value, represented as an int in a byte[], with the higher /// order byte first in [0] SELECTOR_SIZE, - - /// Like {@link #SIZE} but immediately break from the field loading loop, i.e., stop loading further + + /// Like {@link #SIZE} but immediately break from the field loading loop, i.e., stop loading further /// fields, after the size is loaded SELECTOR_SIZE_AND_BREAK }; - + public: virtual FieldSelectorResult accept(const String& fieldName) = 0; }; diff --git a/include/FieldSortedTermVectorMapper.h b/include/FieldSortedTermVectorMapper.h index 7e00c42f..ef1f79ff 100644 --- a/include/FieldSortedTermVectorMapper.h +++ b/include/FieldSortedTermVectorMapper.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,13 +19,13 @@ namespace Lucene public: /// @param comparator A Comparator for sorting {@link TermVectorEntry}s FieldSortedTermVectorMapper(TermVectorEntryComparator comparator); - + FieldSortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator); - + virtual ~FieldSortedTermVectorMapper(); - + LUCENE_CLASS(FieldSortedTermVectorMapper); - + protected: MapStringCollectionTermVectorEntry fieldToTerms; Collection currentSet; @@ -35,15 +35,15 @@ namespace Lucene public: /// Map the Term Vector information into your own structure virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); - + /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); - + /// Get the mapping between fields and terms, sorted by the comparator - /// @return A map between field names and {@link java.util.SortedSet}s per field. SortedSet entries are + /// @return A map between field names and {@link java.util.SortedSet}s per field. SortedSet entries are /// {@link TermVectorEntry} MapStringCollectionTermVectorEntry getFieldToTerms(); - + TermVectorEntryComparator getComparator(); }; } diff --git a/include/FieldValueHitQueue.h b/include/FieldValueHitQueue.h index c7331aaa..4ba1f33a 100644 --- a/include/FieldValueHitQueue.h +++ b/include/FieldValueHitQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,48 +23,48 @@ namespace Lucene public: virtual ~FieldValueHitQueue(); - + LUCENE_CLASS(FieldValueHitQueue); - + protected: /// Stores the sort criteria being used. Collection fields; Collection comparators; Collection reverseMul; - + public: /// Creates a hit queue sorted by the given list of fields. - /// @param fields SortField array we are sorting by in priority order (highest priority first); cannot + /// @param fields SortField array we are sorting by in priority order (highest priority first); cannot /// be null or empty. /// @param size The number of hits to retain. Must be greater than zero. static FieldValueHitQueuePtr create(Collection fields, int32_t size); - + Collection getComparators(); Collection getReverseMul(); - - /// Given a queue Entry, creates a corresponding FieldDoc that contains the values used to sort the given - /// document. These values are not the raw values out of the index, but the internal representation of + + /// Given a queue Entry, creates a corresponding FieldDoc that contains the values used to sort the given + /// document. These values are not the raw values out of the index, but the internal representation of /// them. This is so the given search hit can be collated by a MultiSearcher with other search hits. /// @param entry The Entry used to create a FieldDoc /// @return The newly created FieldDoc /// @see Searchable#search(WeightPtr, FilterPtr, int32_t, SortPtr) FieldDocPtr fillFields(FieldValueHitQueueEntryPtr entry); - + /// Returns the SortFields being used by this hit queue. Collection getFields(); }; - + class LPPAPI FieldValueHitQueueEntry : public ScoreDoc { public: FieldValueHitQueueEntry(int32_t slot, int32_t doc, double score); virtual ~FieldValueHitQueueEntry(); - + LUCENE_CLASS(FieldValueHitQueueEntry); - + public: int32_t slot; - + public: virtual String toString(); }; diff --git a/include/Fieldable.h b/include/Fieldable.h index 8fa9b59b..bdb7f2a0 100644 --- a/include/Fieldable.h +++ b/include/Fieldable.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,24 +13,24 @@ namespace Lucene { /// Synonymous with {@link Field}. /// - /// WARNING: This interface may change within minor versions, despite Lucene's backward compatibility - /// requirements. This means new methods may be added from version to version. This change only - /// affects the Fieldable API; other backwards compatibility promises remain intact. For example, Lucene + /// WARNING: This interface may change within minor versions, despite Lucene's backward compatibility + /// requirements. This means new methods may be added from version to version. This change only + /// affects the Fieldable API; other backwards compatibility promises remain intact. For example, Lucene /// can still read and write indices created within the same major version. class LPPAPI Fieldable { public: LUCENE_INTERFACE(Fieldable); - + public: - /// Sets the boost factor hits on this field. This value will be multiplied into the score of all + /// Sets the boost factor hits on this field. This value will be multiplied into the score of all /// hits on this this field of this document. /// - /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. - /// If a document has multiple fields with the same name, all such values are multiplied together. + /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. + /// If a document has multiple fields with the same name, all such values are multiplied together. /// This product is then used to compute the norm factor for the field. By default, in the {@link - /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the - /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} + /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the + /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} /// before it is stored in the index. One should attempt to ensure that this product does not overflow /// the range of that encoding. /// @@ -38,55 +38,55 @@ namespace Lucene /// @see Similarity#computeNorm(String, FieldInvertState) /// @see Similarity#encodeNorm(double) virtual void setBoost(double boost) = 0; - + /// Returns the boost factor for hits for this field. /// /// The default value is 1.0. /// - /// Note: this value is not stored directly with the document in the index. Documents returned from - /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value + /// Note: this value is not stored directly with the document in the index. Documents returned from + /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value /// present as when this field was indexed. virtual double getBoost() = 0; - + /// Returns the name of the field as an interned string. For example "date", "title", "body", ... virtual String name() = 0; - + /// The value of the field as a String, or empty. /// /// For indexing, if isStored()==true, the stringValue() will be used as the stored field value /// unless isBinary()==true, in which case getBinaryValue() will be used. /// /// If isIndexed()==true and isTokenized()==false, this String value will be indexed as a single token. - /// If isIndexed()==true and isTokenized()==true, then tokenStreamValue() will be used to generate - /// indexed tokens if not null, else readerValue() will be used to generate indexed tokens if not null, + /// If isIndexed()==true and isTokenized()==true, then tokenStreamValue() will be used to generate + /// indexed tokens if not null, else readerValue() will be used to generate indexed tokens if not null, /// else stringValue() will be used to generate tokens. virtual String stringValue() = 0; - + /// The value of the field as a Reader, which can be used at index time to generate indexed tokens. /// @see #stringValue() virtual ReaderPtr readerValue() = 0; - + /// The TokenStream for this field to be used when indexing, or null. /// @see #stringValue() virtual TokenStreamPtr tokenStreamValue() = 0; - + /// True if the value of the field is to be stored in the index for return with search hits. virtual bool isStored() = 0; /// True if the value of the field is to be indexed, so that it may be searched on. virtual bool isIndexed() = 0; - /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields + /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields /// are indexed as a single word and may not be Reader-valued. virtual bool isTokenized() = 0; - /// True if the term or terms used to index this field are stored as a term vector, available from - /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the + /// True if the term or terms used to index this field are stored as a term vector, available from + /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the /// original content of the field, only to terms used to index it. If the original content must be /// preserved, use the stored attribute instead. virtual bool isTermVectorStored() = 0; - /// True if terms are stored as term vector together with their offsets (start and end position in + /// True if terms are stored as term vector together with their offsets (start and end position in /// source text). virtual bool isStoreOffsetWithTermVector() = 0; @@ -103,35 +103,35 @@ namespace Lucene /// This effectively disables indexing boosts and length normalization for this field. virtual void setOmitNorms(bool omitNorms) = 0; - /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field - /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} + /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field + /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} /// is only valid as long as the {@link IndexReader} that retrieved the {@link Document} is still open. /// /// @return true if this field can be loaded lazily virtual bool isLazy() = 0; - /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is + /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is /// undefined. /// @return index of the first character in byte[] segment that represents this Field value. virtual int32_t getBinaryOffset() = 0; - /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is + /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is /// undefined. /// @return length of byte[] segment that represents this Field value. virtual int32_t getBinaryLength() = 0; - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. /// @return reference to the Field value as byte[]. virtual ByteArray getBinaryValue() = 0; - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. /// - /// About reuse: if you pass in the result byte[] and it is used, likely the underlying implementation will - /// hold onto this byte[] and return it in future calls to {@link #getBinaryValue()}. So if you subsequently - /// re-use the same byte[] elsewhere it will alter this Fieldable's value. - /// @param result User defined buffer that will be used if possible. If this is null or not large enough, + /// About reuse: if you pass in the result byte[] and it is used, likely the underlying implementation will + /// hold onto this byte[] and return it in future calls to {@link #getBinaryValue()}. So if you subsequently + /// re-use the same byte[] elsewhere it will alter this Fieldable's value. + /// @param result User defined buffer that will be used if possible. If this is null or not large enough, /// a new buffer is allocated /// @return reference to the Field value as byte[]. virtual ByteArray getBinaryValue(ByteArray result) = 0; @@ -141,8 +141,8 @@ namespace Lucene /// If set, omit term freq, positions and payloads from postings for this field. /// - /// NOTE: While this option reduces storage space required in the index, it also means any query requiring - /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail + /// NOTE: While this option reduces storage space required in the index, it also means any query requiring + /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail /// to find results. virtual void setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) = 0; }; diff --git a/include/FieldsReader.h b/include/FieldsReader.h index 50e3048e..94500c0a 100644 --- a/include/FieldsReader.h +++ b/include/FieldsReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,21 +21,21 @@ namespace Lucene int32_t docStoreOffset, IndexInputPtr cloneableFieldsStream, IndexInputPtr cloneableIndexStream); FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn); FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); - + virtual ~FieldsReader(); - + LUCENE_CLASS(FieldsReader); - + protected: FieldInfosPtr fieldInfos; - + // The main fieldStream, used only for cloning. IndexInputPtr cloneableFieldsStream; - - // This is a clone of cloneableFieldsStream used for reading documents. It should not be cloned outside of a + + // This is a clone of cloneableFieldsStream used for reading documents. It should not be cloned outside of a // synchronized context. IndexInputPtr fieldsStream; - + IndexInputPtr cloneableIndexStream; IndexInputPtr indexStream; int32_t numTotalDocs; @@ -43,96 +43,96 @@ namespace Lucene bool closed; int32_t format; int32_t formatSize; - + // The docID offset where our docs begin in the index file. This will be 0 if we have our own private file. int32_t docStoreOffset; - + CloseableThreadLocal fieldsStreamTL; bool isOriginal; - + public: - /// Returns a cloned FieldsReader that shares open IndexInputs with the original one. It is the caller's job not to + /// Returns a cloned FieldsReader that shares open IndexInputs with the original one. It is the caller's job not to /// close the original FieldsReader until all clones are called (eg, currently SegmentReader manages this logic). virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - - /// Closes the underlying {@link IndexInput} streams, including any ones associated with a lazy implementation of a + + /// Closes the underlying {@link IndexInput} streams, including any ones associated with a lazy implementation of a /// Field. This means that the Fields values will not be accessible. void close(); - + int32_t size(); - + bool canReadRawDocs(); - + DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector); - - /// Returns the length in bytes of each raw document in a contiguous range of length numDocs starting with startDocID. + + /// Returns the length in bytes of each raw document in a contiguous range of length numDocs starting with startDocID. /// Returns the IndexInput (the fieldStream), already seeked to the starting point for startDocID. IndexInputPtr rawDocs(Collection lengths, int32_t startDocID, int32_t numDocs); - + protected: void ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); - + void ensureOpen(); - + void seekIndex(int32_t docID); - - /// Skip the field. We still have to read some of the information about the field, but can skip past the actual content. + + /// Skip the field. We still have to read some of the information about the field, but can skip past the actual content. /// This will have the most payoff on large fields. void skipField(bool binary, bool compressed); void skipField(bool binary, bool compressed, int32_t toRead); - + void addFieldLazy(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize); void addField(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize); - - /// Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes). - /// Read just the size - caller must skip the field content to continue reading fields. Return the size in bytes or chars, + + /// Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes). + /// Read just the size - caller must skip the field content to continue reading fields. Return the size in bytes or chars, /// depending on field type. int32_t addFieldSize(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed); - + ByteArray uncompress(ByteArray b); String uncompressString(ByteArray b); - + friend class LazyField; }; - + class LazyField : public AbstractField { public: LazyField(FieldsReaderPtr reader, const String& name, Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); LazyField(FieldsReaderPtr reader, const String& name, Store store, Index index, TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); virtual ~LazyField(); - + LUCENE_CLASS(LazyField); - + protected: - FieldsReaderWeakPtr _reader; + FieldsReaderWeakPtr _reader; int32_t toRead; int64_t pointer; - + /// @deprecated Only kept for backward-compatibility with <3.0 indexes. bool isCompressed; - + public: - /// The value of the field as a Reader, or null. If null, the String value, binary value, or TokenStream value is used. + /// The value of the field as a Reader, or null. If null, the String value, binary value, or TokenStream value is used. /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. ReaderPtr readerValue(); - - /// The value of the field as a TokenStream, or null. If null, the Reader value, String value, or binary value is used. + + /// The value of the field as a TokenStream, or null. If null, the Reader value, String value, or binary value is used. /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. TokenStreamPtr tokenStreamValue(); - - /// The value of the field as a String, or null. If null, the Reader value, binary value, or TokenStream value is used. + + /// The value of the field as a String, or null. If null, the Reader value, binary value, or TokenStream value is used. /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. String stringValue(); - + int64_t getPointer(); void setPointer(int64_t pointer); int32_t getToRead(); void setToRead(int32_t toRead); - + /// Return the raw byte[] for the binary field. virtual ByteArray getBinaryValue(ByteArray result); - + protected: IndexInputPtr getFieldStream(); }; diff --git a/include/FieldsWriter.h b/include/FieldsWriter.h index f503123d..87bb5f1c 100644 --- a/include/FieldsWriter.h +++ b/include/FieldsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,44 +17,44 @@ namespace Lucene FieldsWriter(DirectoryPtr d, const String& segment, FieldInfosPtr fn); FieldsWriter(IndexOutputPtr fdx, IndexOutputPtr fdt, FieldInfosPtr fn); virtual ~FieldsWriter(); - + LUCENE_CLASS(FieldsWriter); - + protected: FieldInfosPtr fieldInfos; IndexOutputPtr fieldsStream; IndexOutputPtr indexStream; bool doClose; - + public: static const uint8_t FIELD_IS_TOKENIZED; static const uint8_t FIELD_IS_BINARY; static const uint8_t FIELD_IS_COMPRESSED; - + static const int32_t FORMAT; // Original format static const int32_t FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; // Changed strings to UTF8 static const int32_t FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS; // Lucene 3.0: Removal of compressed fields - + // NOTE: if you introduce a new format, make it 1 higher than the current one, and always change this // if you switch to a new format! static const int32_t FORMAT_CURRENT; - + public: void setFieldsStream(IndexOutputPtr stream); - - /// Writes the contents of buffer into the fields stream and adds a new entry for this document into the index + + /// Writes the contents of buffer into the fields stream and adds a new entry for this document into the index /// stream. This assumes the buffer was already written in the correct fields format. void flushDocument(int32_t numStoredFields, RAMOutputStreamPtr buffer); - + void skipDocument(); void flush(); void close(); void writeField(FieldInfoPtr fi, FieldablePtr field); - - /// Bulk write a contiguous series of documents. The lengths array is the length (in bytes) of each raw document. + + /// Bulk write a contiguous series of documents. The lengths array is the length (in bytes) of each raw document. /// The stream IndexInput is the fieldsStream from which we should bulk-copy all bytes. void addRawDocuments(IndexInputPtr stream, Collection lengths, int32_t numDocs); - + void addDocument(DocumentPtr doc); }; } diff --git a/include/FileReader.h b/include/FileReader.h index 7e6f8259..ecdf3ac5 100644 --- a/include/FileReader.h +++ b/include/FileReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,34 +18,34 @@ namespace Lucene /// Creates a new FileReader, given the file name to read from. FileReader(const String& fileName); virtual ~FileReader(); - + LUCENE_CLASS(FileReader); - + protected: ifstreamPtr file; int64_t _length; ByteArray fileBuffer; - + public: static const int32_t FILE_EOF; static const int32_t FILE_ERROR; - + public: /// Read a single character. virtual int32_t read(); /// Read characters into a portion of an array. virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - + /// Close the stream. virtual void close(); - + /// Tell whether this stream supports the mark() operation virtual bool markSupported(); - + /// Reset the stream. virtual void reset(); - + /// The number of bytes in the file. virtual int64_t length(); }; diff --git a/include/FileSwitchDirectory.h b/include/FileSwitchDirectory.h index 05282c90..f37942d8 100644 --- a/include/FileSwitchDirectory.h +++ b/include/FileSwitchDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,74 +11,74 @@ namespace Lucene { - /// A Directory instance that switches files between two other + /// A Directory instance that switches files between two other /// Directory instances. /// - /// Files with the specified extensions are placed in the primary - /// directory; others are placed in the secondary directory. The - /// provided Set must not change once passed to this class, and + /// Files with the specified extensions are placed in the primary + /// directory; others are placed in the secondary directory. The + /// provided Set must not change once passed to this class, and /// must allow multiple threads to call contains at once. class LPPAPI FileSwitchDirectory : public Directory { public: FileSwitchDirectory(HashSet primaryExtensions, DirectoryPtr primaryDir, DirectoryPtr secondaryDir, bool doClose); virtual ~FileSwitchDirectory(); - + LUCENE_CLASS(FileSwitchDirectory); - + protected: HashSet primaryExtensions; DirectoryPtr primaryDir; DirectoryPtr secondaryDir; bool doClose; - + public: /// Return the primary directory. DirectoryPtr getPrimaryDir(); - + /// Return the secondary directory. DirectoryPtr getSecondaryDir(); - + /// Closes the store. virtual void close(); - + /// Returns an array of strings, one for each file in the directory. virtual HashSet listAll(); - + /// Utility method to return a file's extension. static String getExtension(const String& name); - + /// Returns true if a file with the given name exists. virtual bool fileExists(const String& name); - + /// Returns the time the named file was last modified. virtual uint64_t fileModified(const String& name); - + /// Set the modified time of an existing file to now. virtual void touchFile(const String& name); - + /// Removes an existing file in the directory. virtual void deleteFile(const String& name); - + /// Returns the length of a file in the directory. virtual int64_t fileLength(const String& name); - + /// Creates a new, empty file in the directory with the given name. /// Returns a stream writing this file. virtual IndexOutputPtr createOutput(const String& name); - + /// Ensure that any writes to this file are moved to stable storage. - /// Lucene uses this to properly commit changes to the index, to + /// Lucene uses this to properly commit changes to the index, to /// prevent a machine/OS crash from corrupting the index. virtual void sync(const String& name); - - /// Returns a stream reading an existing file, with the specified - /// read buffer size. The particular Directory implementation may + + /// Returns a stream reading an existing file, with the specified + /// read buffer size. The particular Directory implementation may /// ignore the buffer size. virtual IndexInputPtr openInput(const String& name); - + protected: - DirectoryPtr getDirectory(const String& name); + DirectoryPtr getDirectory(const String& name); }; } diff --git a/include/FileUtils.h b/include/FileUtils.h index 1a6944ee..27b9f070 100644 --- a/include/FileUtils.h +++ b/include/FileUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,49 +15,49 @@ namespace Lucene { /// Return true if given file or directory exists. LPPAPI bool fileExists(const String& path); - + /// Return file last modified date and time. LPPAPI uint64_t fileModified(const String& path); - + /// Set file last modified date and time to now. LPPAPI bool touchFile(const String& path); - + /// Return file length in bytes. LPPAPI int64_t fileLength(const String& path); - + /// Set new file length, truncating or expanding as required. LPPAPI bool setFileLength(const String& path, int64_t length); - + /// Delete file from file system. LPPAPI bool removeFile(const String& path); - + /// Copy a file to/from file system. LPPAPI bool copyFile(const String& source, const String& dest); - + /// Create new directory under given location. LPPAPI bool createDirectory(const String& path); - + /// Delete directory from file system. LPPAPI bool removeDirectory(const String& path); - + /// Return true if given path points to a directory. LPPAPI bool isDirectory(const String& path); - + /// Return list of files (and/or directories) under given directory. /// @param path path to list directory. /// @param filesOnly if true the exclude sub-directories. /// @param dirList list of files to return. LPPAPI bool listDirectory(const String& path, bool filesOnly, HashSet dirList); - + /// Copy a directory to/from file system. LPPAPI bool copyDirectory(const String& source, const String& dest); - + /// Return complete path after joining given directory and file name. LPPAPI String joinPath(const String& path, const String& file); - + /// Extract parent path from given path. LPPAPI String extractPath(const String& path); - + /// Extract file name from given path. LPPAPI String extractFile(const String& path); } diff --git a/include/Filter.h b/include/Filter.h index afee41f0..2a25b7c2 100644 --- a/include/Filter.h +++ b/include/Filter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,21 +15,21 @@ namespace Lucene class LPPAPI Filter : public LuceneObject { public: - virtual ~Filter(); + virtual ~Filter(); LUCENE_CLASS(Filter); - + public: - /// Creates a {@link DocIdSet} enumerating the documents that should be permitted in search results. + /// Creates a {@link DocIdSet} enumerating the documents that should be permitted in search results. /// /// Note: null can be returned if no documents are accepted by this Filter. /// - /// Note: This method will be called once per segment in the index during searching. The returned + /// Note: This method will be called once per segment in the index during searching. The returned /// {@link DocIdSet} must refer to document IDs for that segment, not for the top-level reader. /// - /// @param reader a {@link IndexReader} instance opened on the index currently searched on. Note, - /// it is likely that the provided reader does not represent the whole underlying index ie. if the + /// @param reader a {@link IndexReader} instance opened on the index currently searched on. Note, + /// it is likely that the provided reader does not represent the whole underlying index ie. if the /// index has more than one segment the given reader only represents a single segment. - /// @return a DocIdSet that provides the documents which should be permitted or prohibited in search + /// @return a DocIdSet that provides the documents which should be permitted or prohibited in search /// results. NOTE: null can be returned if no documents will be accepted by this Filter. /// /// @see DocIdBitSet diff --git a/include/FilterIndexReader.h b/include/FilterIndexReader.h index 05b4bdbc..fd2fd7b8 100644 --- a/include/FilterIndexReader.h +++ b/include/FilterIndexReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,28 +13,28 @@ namespace Lucene { - /// A FilterIndexReader contains another IndexReader, which it uses as its basic source of data, possibly - /// transforming the data along the way or providing additional functionality. The class FilterIndexReader - /// itself simply implements all abstract methods of IndexReader with versions that pass all requests to - /// the contained index reader. Subclasses of FilterIndexReader may further override some of these methods + /// A FilterIndexReader contains another IndexReader, which it uses as its basic source of data, possibly + /// transforming the data along the way or providing additional functionality. The class FilterIndexReader + /// itself simply implements all abstract methods of IndexReader with versions that pass all requests to + /// the contained index reader. Subclasses of FilterIndexReader may further override some of these methods /// and may also provide additional methods and fields. class LPPAPI FilterIndexReader : public IndexReader { public: - /// Construct a FilterIndexReader based on the specified base reader. Directory locking for delete, + /// Construct a FilterIndexReader based on the specified base reader. Directory locking for delete, /// undeleteAll, and setNorm operations is left to the base reader. /// /// Note that base reader is closed if this FilterIndexReader is closed. /// @param in specified base reader. FilterIndexReader(IndexReaderPtr in); - + virtual ~FilterIndexReader(); - + LUCENE_CLASS(FilterIndexReader); - + protected: IndexReaderPtr in; - + public: virtual DirectoryPtr directory(); virtual Collection getTermFreqVectors(int32_t docNumber); @@ -60,15 +60,15 @@ namespace Lucene virtual bool isCurrent(); virtual bool isOptimized(); virtual Collection getSequentialSubReaders(); - - /// If the subclass of FilteredIndexReader modifies the contents of the FieldCache, you must + + /// If the subclass of FilteredIndexReader modifies the contents of the FieldCache, you must /// override this method to provide a different key virtual LuceneObjectPtr getFieldCacheKey(); - - /// If the subclass of FilteredIndexReader modifies the deleted docs, you must override this + + /// If the subclass of FilteredIndexReader modifies the deleted docs, you must override this /// method to provide a different key virtual LuceneObjectPtr getDeletesCacheKey(); - + protected: virtual void doUndeleteAll(); virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); @@ -76,19 +76,19 @@ namespace Lucene virtual void doCommit(MapStringString commitUserData); virtual void doClose(); }; - + /// Base class for filtering {@link TermDocs} implementations. class LPPAPI FilterTermDocs : public TermPositions, public LuceneObject { public: FilterTermDocs(TermDocsPtr in); virtual ~FilterTermDocs(); - + LUCENE_CLASS(FilterTermDocs); - + protected: TermDocsPtr in; - + public: virtual void seek(TermPtr term); virtual void seek(TermEnumPtr termEnum); @@ -106,28 +106,28 @@ namespace Lucene public: FilterTermPositions(TermPositionsPtr in); virtual ~FilterTermPositions(); - + LUCENE_CLASS(FilterTermPositions); - + public: virtual int32_t nextPosition(); virtual int32_t getPayloadLength(); virtual ByteArray getPayload(ByteArray data, int32_t offset); virtual bool isPayloadAvailable(); }; - + /// Base class for filtering {@link TermEnum} implementations. class LPPAPI FilterTermEnum : public TermEnum { public: FilterTermEnum(TermEnumPtr in); virtual ~FilterTermEnum(); - + LUCENE_CLASS(FilterTermEnum); - + protected: TermEnumPtr in; - + public: virtual bool next(); virtual TermPtr term(); diff --git a/include/FilterManager.h b/include/FilterManager.h index 5f6b6736..01ff9726 100644 --- a/include/FilterManager.h +++ b/include/FilterManager.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,11 +11,11 @@ namespace Lucene { - /// Filter caching singleton. It can be used to save filters locally for reuse. Also could be used as a - /// persistent storage for any filter as long as the filter provides a proper hashCode(), as that is used + /// Filter caching singleton. It can be used to save filters locally for reuse. Also could be used as a + /// persistent storage for any filter as long as the filter provides a proper hashCode(), as that is used /// as the key in the cache. /// - /// The cache is periodically cleaned up from a separate thread to ensure the cache doesn't exceed the + /// The cache is periodically cleaned up from a separate thread to ensure the cache doesn't exceed the /// maximum size. class LPPAPI FilterManager : public LuceneObject { @@ -23,47 +23,47 @@ namespace Lucene /// Sets up the FilterManager singleton. FilterManager(); virtual ~FilterManager(); - + LUCENE_CLASS(FilterManager); - + protected: /// The default maximum number of Filters in the cache static const int32_t DEFAULT_CACHE_CLEAN_SIZE; - + /// The default frequency of cache cleanup static const int64_t DEFAULT_CACHE_SLEEP_TIME; - + /// The cache itself MapIntFilterItem cache; - + /// Maximum allowed cache size int32_t cacheCleanSize; - + /// Cache cleaning frequency int64_t cleanSleepTime; - + /// Cache cleaner that runs in a separate thread FilterCleanerPtr filterCleaner; - + public: virtual void initialize(); - + static FilterManagerPtr getInstance(); - + /// Sets the max size that cache should reach before it is cleaned up /// @param cacheCleanSize maximum allowed cache size void setCacheSize(int32_t cacheCleanSize); - + /// Sets the cache cleaning frequency in milliseconds. /// @param cleanSleepTime cleaning frequency in milliseconds void setCleanThreadSleepTime(int64_t cleanSleepTime); - - /// Returns the cached version of the filter. Allows the caller to pass up a small filter but this will + + /// Returns the cached version of the filter. Allows the caller to pass up a small filter but this will /// keep a persistent version around and allow the caching filter to do its job. /// @param filter The input filter /// @return The cached version of the filter FilterPtr getFilter(FilterPtr filter); - + friend class FilterCleaner; }; } diff --git a/include/FilteredDocIdSet.h b/include/FilteredDocIdSet.h index c95bdd9d..5075e068 100644 --- a/include/FilteredDocIdSet.h +++ b/include/FilteredDocIdSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,10 +14,10 @@ namespace Lucene /// Abstract decorator class for a DocIdSet implementation that provides on-demand filtering/validation /// mechanism on a given DocIdSet. /// - /// Technically, this same functionality could be achieved with ChainedFilter (under contrib/misc), however - /// the benefit of this class is it never materializes the full bitset for the filter. Instead, the {@link - /// #match} method is invoked on-demand, per docID visited during searching. If you know few docIDs will - /// be visited, and the logic behind {@link #match} is relatively costly, this may be a better way to filter + /// Technically, this same functionality could be achieved with ChainedFilter (under contrib/misc), however + /// the benefit of this class is it never materializes the full bitset for the filter. Instead, the {@link + /// #match} method is invoked on-demand, per docID visited during searching. If you know few docIDs will + /// be visited, and the logic behind {@link #match} is relatively costly, this may be a better way to filter /// than ChainedFilter. /// @see DocIdSet class LPPAPI FilteredDocIdSet : public DocIdSet @@ -26,27 +26,27 @@ namespace Lucene /// @param innerSet Underlying DocIdSet FilteredDocIdSet(DocIdSetPtr innerSet); virtual ~FilteredDocIdSet(); - + LUCENE_CLASS(FilteredDocIdSet); - + protected: DocIdSetPtr innerSet; - + public: /// This DocIdSet implementation is cacheable if the inner set is cacheable. virtual bool isCacheable(); - + /// Implementation of the contract to build a DocIdSetIterator. /// @see DocIdSetIterator /// @see FilteredDocIdSetIterator virtual DocIdSetIteratorPtr iterator(); - + protected: /// Validation method to determine whether a docid should be in the result set. /// @param docid docid to be tested /// @return true if input docid should be in the result set, false otherwise. virtual bool match(int32_t docid) = 0; - + friend class DefaultFilteredDocIdSetIterator; }; } diff --git a/include/FilteredDocIdSetIterator.h b/include/FilteredDocIdSetIterator.h index 98d2daa7..9782fe75 100644 --- a/include/FilteredDocIdSetIterator.h +++ b/include/FilteredDocIdSetIterator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,18 +19,18 @@ namespace Lucene /// @param innerIter Underlying DocIdSetIterator. FilteredDocIdSetIterator(DocIdSetIteratorPtr innerIter); virtual ~FilteredDocIdSetIterator(); - + LUCENE_CLASS(FilteredDocIdSetIterator); - + protected: DocIdSetIteratorPtr innerIter; int32_t doc; - + public: virtual int32_t docID(); virtual int32_t nextDoc(); virtual int32_t advance(int32_t target); - + protected: /// Validation method to determine whether a docid should be in the result set. /// @param doc docid to be tested diff --git a/include/FilteredQuery.h b/include/FilteredQuery.h index 75a66f4b..0d3a4220 100644 --- a/include/FilteredQuery.h +++ b/include/FilteredQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,49 +13,49 @@ namespace Lucene { /// A query that applies a filter to the results of another query. /// - /// Note: the bits are retrieved from the filter each time this query is used in a search - use a + /// Note: the bits are retrieved from the filter each time this query is used in a search - use a /// CachingWrapperFilter to avoid regenerating the bits every time. /// /// @see CachingWrapperFilter class LPPAPI FilteredQuery : public Query { public: - /// Constructs a new query which applies a filter to the results of the original query. + /// Constructs a new query which applies a filter to the results of the original query. /// Filter::getDocIdSet() will be called every time this query is used in a search. /// @param query Query to be filtered, cannot be null. /// @param filter Filter to apply to query results, cannot be null. FilteredQuery(QueryPtr query, FilterPtr filter); - + virtual ~FilteredQuery(); - + LUCENE_CLASS(FilteredQuery); - + private: QueryPtr query; FilterPtr filter; - + public: using Query::toString; - + /// Returns a Weight that applies the filter to the enclosed query's Weight. /// This is accomplished by overriding the Scorer returned by the Weight. virtual WeightPtr createWeight(SearcherPtr searcher); - + /// Rewrites the wrapped query. virtual QueryPtr rewrite(IndexReaderPtr reader); - + QueryPtr getQuery(); FilterPtr getFilter(); - + virtual void extractTerms(SetTerm terms); - + /// Prints a user-readable version of this query. virtual String toString(const String& field); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + friend class FilteredQueryWeight; }; } diff --git a/include/FilteredTermEnum.h b/include/FilteredTermEnum.h index b10fd217..9f4f1ae3 100644 --- a/include/FilteredTermEnum.h +++ b/include/FilteredTermEnum.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,49 +11,49 @@ namespace Lucene { - /// Abstract class for enumerating a subset of all terms. + /// Abstract class for enumerating a subset of all terms. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than + /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than /// all that precede it. class LPPAPI FilteredTermEnum : public TermEnum { public: - virtual ~FilteredTermEnum(); + virtual ~FilteredTermEnum(); LUCENE_CLASS(FilteredTermEnum); - + protected: /// The current term TermPtr currentTerm; - + /// The delegate enum - to set this member use {@link #setEnum} TermEnumPtr actualEnum; - + public: /// Equality measure on the term virtual double difference() = 0; - + /// Returns the docFreq of the current Term in the enumeration. /// Returns -1 if no Term matches or all terms have been enumerated. virtual int32_t docFreq(); - + /// Increments the enumeration to the next element. True if one exists. virtual bool next(); - + /// Returns the current Term in the enumeration. /// Returns null if no Term matches or all terms have been enumerated. virtual TermPtr term(); - + /// Closes the enumeration to further activity, freeing resources. virtual void close(); - + protected: /// Equality compare on the term virtual bool termCompare(TermPtr term) = 0; - + /// Indicates the end of the enumeration has been reached virtual bool endEnum() = 0; - - /// Use this method to set the actual TermEnum (eg. in ctor), it will be automatically positioned + + /// Use this method to set the actual TermEnum (eg. in ctor), it will be automatically positioned /// on the first matching term. virtual void setEnum(TermEnumPtr actualEnum); }; diff --git a/include/FlagsAttribute.h b/include/FlagsAttribute.h index be7478e3..70de4ac2 100644 --- a/include/FlagsAttribute.h +++ b/include/FlagsAttribute.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,32 +11,32 @@ namespace Lucene { - /// This attribute can be used to pass different flags down the tokenizer chain, eg from one TokenFilter - /// to another one. + /// This attribute can be used to pass different flags down the tokenizer chain, eg from one TokenFilter + /// to another one. class LPPAPI FlagsAttribute : public Attribute { public: FlagsAttribute(); virtual ~FlagsAttribute(); - + LUCENE_CLASS(FlagsAttribute); - + protected: int32_t flags; - + public: virtual String toString(); - - /// Get the bitset for any bits that have been set. This is completely distinct from {@link - /// TypeAttribute#type()}, although they do share similar purposes. The flags can be used to encode + + /// Get the bitset for any bits that have been set. This is completely distinct from {@link + /// TypeAttribute#type()}, although they do share similar purposes. The flags can be used to encode /// information about the token for use by other {@link TokenFilter}s. virtual int32_t getFlags(); - + /// @see #getFlags() virtual void setFlags(int32_t flags); - + virtual void clear(); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual void copyTo(AttributePtr target); diff --git a/include/FormatPostingsDocsConsumer.h b/include/FormatPostingsDocsConsumer.h index 111931a0..44ffb1c8 100644 --- a/include/FormatPostingsDocsConsumer.h +++ b/include/FormatPostingsDocsConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,13 +15,13 @@ namespace Lucene { public: virtual ~FormatPostingsDocsConsumer(); - + LUCENE_CLASS(FormatPostingsDocsConsumer); - + public: /// Adds a new doc in this term. If this returns null then we just skip consuming positions/payloads. virtual FormatPostingsPositionsConsumerPtr addDoc(int32_t docID, int32_t termDocFreq) = 0; - + /// Called when we are done adding docs to this term virtual void finish() = 0; }; diff --git a/include/FormatPostingsDocsWriter.h b/include/FormatPostingsDocsWriter.h index ea02d983..0f33c123 100644 --- a/include/FormatPostingsDocsWriter.h +++ b/include/FormatPostingsDocsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene public: FormatPostingsDocsWriter(SegmentWriteStatePtr state, FormatPostingsTermsWriterPtr parent); virtual ~FormatPostingsDocsWriter(); - + LUCENE_CLASS(FormatPostingsDocsWriter); - + public: IndexOutputPtr out; FormatPostingsTermsWriterWeakPtr _parent; @@ -28,29 +28,29 @@ namespace Lucene DefaultSkipListWriterPtr skipListWriter; int32_t skipInterval; int32_t totalNumDocs; - + bool omitTermFreqAndPositions; bool storePayloads; int64_t freqStart; FieldInfoPtr fieldInfo; - + int32_t lastDocID; int32_t df; - + TermInfoPtr termInfo; // minimize consing UTF8ResultPtr utf8; - + public: virtual void initialize(); - + void setField(FieldInfoPtr fieldInfo); - + /// Adds a new doc in this term. If this returns null then we just skip consuming positions/payloads. virtual FormatPostingsPositionsConsumerPtr addDoc(int32_t docID, int32_t termDocFreq); - + /// Called when we are done adding docs to this term virtual void finish(); - + void close(); }; } diff --git a/include/FormatPostingsFieldsConsumer.h b/include/FormatPostingsFieldsConsumer.h index 416fa7b1..6f6cc7e5 100644 --- a/include/FormatPostingsFieldsConsumer.h +++ b/include/FormatPostingsFieldsConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,13 +17,13 @@ namespace Lucene { public: virtual ~FormatPostingsFieldsConsumer(); - + LUCENE_CLASS(FormatPostingsFieldsConsumer); - + public: /// Add a new field. virtual FormatPostingsTermsConsumerPtr addField(FieldInfoPtr field) = 0; - + /// Called when we are done adding everything. virtual void finish() = 0; }; diff --git a/include/FormatPostingsFieldsWriter.h b/include/FormatPostingsFieldsWriter.h index e61d686c..a4a57ad5 100644 --- a/include/FormatPostingsFieldsWriter.h +++ b/include/FormatPostingsFieldsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: FormatPostingsFieldsWriter(SegmentWriteStatePtr state, FieldInfosPtr fieldInfos); virtual ~FormatPostingsFieldsWriter(); - + LUCENE_CLASS(FormatPostingsFieldsWriter); - + public: DirectoryPtr dir; String segment; @@ -28,13 +28,13 @@ namespace Lucene FormatPostingsTermsWriterPtr termsWriter; DefaultSkipListWriterPtr skipListWriter; int32_t totalNumDocs; - + public: virtual void initialize(); - + /// Add a new field. virtual FormatPostingsTermsConsumerPtr addField(FieldInfoPtr field); - + /// Called when we are done adding everything. virtual void finish(); }; diff --git a/include/FormatPostingsPositionsConsumer.h b/include/FormatPostingsPositionsConsumer.h index 35d3c43d..a047b975 100644 --- a/include/FormatPostingsPositionsConsumer.h +++ b/include/FormatPostingsPositionsConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,13 +15,13 @@ namespace Lucene { public: virtual ~FormatPostingsPositionsConsumer(); - + LUCENE_CLASS(FormatPostingsPositionsConsumer); - + public: /// Add a new position & payload. If payloadLength > 0 you must read those bytes from the IndexInput. virtual void addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength) = 0; - + /// Called when we are done adding positions & payloads. virtual void finish() = 0; }; diff --git a/include/FormatPostingsPositionsWriter.h b/include/FormatPostingsPositionsWriter.h index 7a0e9add..c1410b9b 100644 --- a/include/FormatPostingsPositionsWriter.h +++ b/include/FormatPostingsPositionsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,28 +16,28 @@ namespace Lucene public: FormatPostingsPositionsWriter(SegmentWriteStatePtr state, FormatPostingsDocsWriterPtr parent); virtual ~FormatPostingsPositionsWriter(); - + LUCENE_CLASS(FormatPostingsPositionsWriter); - + public: FormatPostingsDocsWriterWeakPtr _parent; IndexOutputPtr out; - + bool omitTermFreqAndPositions; bool storePayloads; int32_t lastPayloadLength; - + int32_t lastPosition; - + public: /// Add a new position & payload virtual void addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength); - + void setField(FieldInfoPtr fieldInfo); - + /// Called when we are done adding positions & payloads virtual void finish(); - + void close(); }; } diff --git a/include/FormatPostingsTermsConsumer.h b/include/FormatPostingsTermsConsumer.h index cfe5f513..3d2245b4 100644 --- a/include/FormatPostingsTermsConsumer.h +++ b/include/FormatPostingsTermsConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,17 +15,17 @@ namespace Lucene { public: virtual ~FormatPostingsTermsConsumer(); - + LUCENE_CLASS(FormatPostingsTermsConsumer); - + public: CharArray termBuffer; - + public: /// Adds a new term in this field virtual FormatPostingsDocsConsumerPtr addTerm(CharArray text, int32_t start) = 0; virtual FormatPostingsDocsConsumerPtr addTerm(const String& text); - + /// Called when we are done adding terms to this field virtual void finish() = 0; }; diff --git a/include/FormatPostingsTermsWriter.h b/include/FormatPostingsTermsWriter.h index 4b5aee7f..3df0f5eb 100644 --- a/include/FormatPostingsTermsWriter.h +++ b/include/FormatPostingsTermsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,33 +16,33 @@ namespace Lucene public: FormatPostingsTermsWriter(SegmentWriteStatePtr state, FormatPostingsFieldsWriterPtr parent); virtual ~FormatPostingsTermsWriter(); - + LUCENE_CLASS(FormatPostingsTermsWriter); - + public: FormatPostingsFieldsWriterWeakPtr _parent; SegmentWriteStatePtr state; FormatPostingsDocsWriterPtr docsWriter; TermInfosWriterPtr termsOut; FieldInfoPtr fieldInfo; - + CharArray currentTerm; int32_t currentTermStart; int64_t freqStart; int64_t proxStart; - + public: virtual void initialize(); - + void setField(FieldInfoPtr fieldInfo); - + /// Adds a new term in this field virtual FormatPostingsDocsConsumerPtr addTerm(CharArray text, int32_t start); - + /// Called when we are done adding terms to this field virtual void finish(); - + void close(); }; } diff --git a/include/FreqProxFieldMergeState.h b/include/FreqProxFieldMergeState.h index c430cafd..c5ced70d 100644 --- a/include/FreqProxFieldMergeState.h +++ b/include/FreqProxFieldMergeState.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,31 +17,31 @@ namespace Lucene public: FreqProxFieldMergeState(FreqProxTermsWriterPerFieldPtr field); virtual ~FreqProxFieldMergeState(); - + LUCENE_CLASS(FreqProxFieldMergeState); - + public: FreqProxTermsWriterPerFieldPtr field; int32_t numPostings; CharBlockPoolPtr charPool; Collection postings; - + FreqProxTermsWriterPostingListPtr p; CharArray text; int32_t textOffset; - + ByteSliceReaderPtr freq; ByteSliceReaderPtr prox; - + int32_t docID; int32_t termFreq; - + protected: int32_t postingUpto; - + public: bool nextTerm(); - bool nextDoc(); + bool nextDoc(); }; } diff --git a/include/FreqProxTermsWriter.h b/include/FreqProxTermsWriter.h index 95e96965..12dcb163 100644 --- a/include/FreqProxTermsWriter.h +++ b/include/FreqProxTermsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,37 +16,37 @@ namespace Lucene { public: virtual ~FreqProxTermsWriter(); - + LUCENE_CLASS(FreqProxTermsWriter); - + protected: ByteArray payloadBuffer; - + public: virtual TermsHashConsumerPerThreadPtr addThread(TermsHashPerThreadPtr perThread); virtual void createPostings(Collection postings, int32_t start, int32_t count); virtual void closeDocStore(SegmentWriteStatePtr state); virtual void abort(); virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state); - + /// Walk through all unique text tokens (Posting instances) found in this field and serialize them /// into a single RAM segment. void appendPostings(Collection fields, FormatPostingsFieldsConsumerPtr consumer); - + virtual int32_t bytesPerPosting(); - + protected: static int32_t compareText(const wchar_t* text1, int32_t pos1, const wchar_t* text2, int32_t pos2); }; - + class FreqProxTermsWriterPostingList : public RawPostingList { public: FreqProxTermsWriterPostingList(); virtual ~FreqProxTermsWriterPostingList(); - + LUCENE_CLASS(FreqProxTermsWriterPostingList); - + public: int32_t docFreq; // # times this term occurs in the current doc int32_t lastDocID; // Last docID where this term occurred diff --git a/include/FreqProxTermsWriterPerField.h b/include/FreqProxTermsWriterPerField.h index d7f00c68..844eaac8 100644 --- a/include/FreqProxTermsWriterPerField.h +++ b/include/FreqProxTermsWriterPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: FreqProxTermsWriterPerField(TermsHashPerFieldPtr termsHashPerField, FreqProxTermsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo); virtual ~FreqProxTermsWriterPerField(); - + LUCENE_CLASS(FreqProxTermsWriterPerField); - + public: FreqProxTermsWriterPerThreadWeakPtr _perThread; TermsHashPerFieldWeakPtr _termsHashPerField; @@ -28,7 +28,7 @@ namespace Lucene bool omitTermFreqAndPositions; PayloadAttributePtr payloadAttribute; bool hasPayloads; - + public: virtual int32_t getStreamCount(); virtual void finish(); diff --git a/include/FreqProxTermsWriterPerThread.h b/include/FreqProxTermsWriterPerThread.h index 46fcb648..0bb3d119 100644 --- a/include/FreqProxTermsWriterPerThread.h +++ b/include/FreqProxTermsWriterPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,13 +16,13 @@ namespace Lucene public: FreqProxTermsWriterPerThread(TermsHashPerThreadPtr perThread); virtual ~FreqProxTermsWriterPerThread(); - + LUCENE_CLASS(FreqProxTermsWriterPerThread); - + public: TermsHashPerThreadWeakPtr _termsHashPerThread; DocStatePtr docState; - + public: virtual TermsHashConsumerPerFieldPtr addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo); virtual void startDocument(); diff --git a/include/FuzzyQuery.h b/include/FuzzyQuery.h index b12376c7..011701e8 100644 --- a/include/FuzzyQuery.h +++ b/include/FuzzyQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,66 +11,66 @@ namespace Lucene { - /// Implements the fuzzy search query. The similarity measurement is based on the Levenshtein (edit + /// Implements the fuzzy search query. The similarity measurement is based on the Levenshtein (edit /// distance) algorithm. /// - /// Warning: this query is not very scalable with its default prefix length of 0 - in this case, *every* + /// Warning: this query is not very scalable with its default prefix length of 0 - in this case, *every* /// term will be enumerated and cause an edit score calculation. class LPPAPI FuzzyQuery : public MultiTermQuery { public: - /// Create a new FuzzyQuery that will match terms with a similarity of at least minimumSimilarity + /// Create a new FuzzyQuery that will match terms with a similarity of at least minimumSimilarity /// to term. If a prefixLength > 0 is specified, a common prefix of that length is also required. /// @param term The term to search for - /// @param minimumSimilarity A value between 0 and 1 to set the required similarity between the query - /// term and the matching terms. For example, for a minimumSimilarity of 0.5 a term of the same - /// length as the query term is considered similar to the query term if the edit distance between + /// @param minimumSimilarity A value between 0 and 1 to set the required similarity between the query + /// term and the matching terms. For example, for a minimumSimilarity of 0.5 a term of the same + /// length as the query term is considered similar to the query term if the edit distance between /// both terms is less than length(term) * 0.5 /// @param prefixLength Length of common (non-fuzzy) prefix FuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength); FuzzyQuery(TermPtr term, double minimumSimilarity); FuzzyQuery(TermPtr term); - + virtual ~FuzzyQuery(); - + LUCENE_CLASS(FuzzyQuery); - + protected: double minimumSimilarity; int32_t prefixLength; bool termLongEnough; - + TermPtr term; - + public: static double defaultMinSimilarity(); static const int32_t defaultPrefixLength; - + public: using MultiTermQuery::toString; - + /// Returns the minimum similarity that is required for this query to match. /// @return float value between 0.0 and 1.0 double getMinSimilarity(); - - /// Returns the non-fuzzy prefix length. This is the number of characters at the start of a term that - /// must be identical (not fuzzy) to the query term if the query is to match that term. + + /// Returns the non-fuzzy prefix length. This is the number of characters at the start of a term that + /// must be identical (not fuzzy) to the query term if the query is to match that term. int32_t getPrefixLength(); - + /// Returns the pattern term. TermPtr getTerm(); - + virtual void setRewriteMethod(RewriteMethodPtr method); virtual QueryPtr rewrite(IndexReaderPtr reader); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual String toString(const String& field); virtual int32_t hashCode(); virtual bool equals(LuceneObjectPtr other); - + protected: void ConstructQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength); - + virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); }; } diff --git a/include/FuzzyTermEnum.h b/include/FuzzyTermEnum.h index 29f14c84..bf3dcfdf 100644 --- a/include/FuzzyTermEnum.h +++ b/include/FuzzyTermEnum.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,16 +13,16 @@ namespace Lucene { /// Subclass of FilteredTermEnum for enumerating all terms that are similar to the specified filter term. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater + /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater /// than all that precede it. class LPPAPI FuzzyTermEnum : public FilteredTermEnum { public: - /// Constructor for enumeration of all terms from specified reader which share a prefix of length + /// Constructor for enumeration of all terms from specified reader which share a prefix of length /// prefixLength with term and which have a fuzzy similarity > minSimilarity. /// - /// After calling the constructor the enumeration is already pointing to the first valid term if - /// such a term exists. + /// After calling the constructor the enumeration is already pointing to the first valid term if + /// such a term exists. /// @param reader Delivers terms. /// @param term Pattern term. /// @param minSimilarity Minimum required similarity for terms from the reader. Default value is 0.5. @@ -30,43 +30,43 @@ namespace Lucene FuzzyTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity, int32_t prefixLength); FuzzyTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity); FuzzyTermEnum(IndexReaderPtr reader, TermPtr term); - + virtual ~FuzzyTermEnum(); - + LUCENE_CLASS(FuzzyTermEnum); - + protected: /// Allows us save time required to create a new array every time similarity is called. Collection p; Collection d; - + double _similarity; bool _endEnum; - + TermPtr searchTerm; String field; String text; String prefix; - + double minimumSimilarity; double scale_factor; - + public: virtual double difference(); virtual bool endEnum(); virtual void close(); - + protected: void ConstructTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity, int32_t prefixLength); - - /// The termCompare method in FuzzyTermEnum uses Levenshtein distance to calculate the distance between - /// the given term and the comparing term. + + /// The termCompare method in FuzzyTermEnum uses Levenshtein distance to calculate the distance between + /// the given term and the comparing term. virtual bool termCompare(TermPtr term); - + /// /// Compute Levenshtein distance /// - /// Similarity returns a number that is 1.0f or less (including negative numbers) based on how similar the + /// Similarity returns a number that is 1.0f or less (including negative numbers) based on how similar the /// Term is compared to a target term. It returns exactly 0.0 when ///
             /// editDistance > maximumEditDistance
    @@ -76,10 +76,10 @@ namespace Lucene
             /// 
             /// 1 - (editDistance / length)
             /// 
    - /// where length is the length of the shortest term (text or target) including a prefix that are identical + /// where length is the length of the shortest term (text or target) including a prefix that are identical /// and editDistance is the Levenshtein distance for the two words. /// - /// Embedded within this algorithm is a fail-fast Levenshtein distance algorithm. The fail-fast algorithm + /// Embedded within this algorithm is a fail-fast Levenshtein distance algorithm. The fail-fast algorithm /// differs from the standard Levenshtein distance algorithm in that it is aborted if it is discovered that /// the minimum distance between the words is greater than some threshold. /// @@ -87,8 +87,8 @@ namespace Lucene ///
             /// (1 - minimumSimilarity) * length
             /// 
    - /// where length is the shortest term including any prefix that is not part of the similarity comparison. - /// This formula was derived by solving for what maximum value of distance returns false for the following + /// where length is the shortest term including any prefix that is not part of the similarity comparison. + /// This formula was derived by solving for what maximum value of distance returns false for the following /// statements: ///
             /// similarity = 1 - ((double)distance / (double)(prefixLength + std::min(textlen, targetlen)));
    @@ -96,16 +96,16 @@ namespace Lucene
             /// 
    /// where distance is the Levenshtein distance for the two words. /// - /// Levenshtein distance (also known as edit distance) is a measure of similarity between two strings where - /// the distance is measured as the number of character deletions, insertions or substitutions required to + /// Levenshtein distance (also known as edit distance) is a measure of similarity between two strings where + /// the distance is measured as the number of character deletions, insertions or substitutions required to /// transform one string to the other string. /// /// @param target The target word or phrase. - /// @return the similarity, 0.0 or less indicates that it matches less than the required threshold and 1.0 + /// @return the similarity, 0.0 or less indicates that it matches less than the required threshold and 1.0 /// indicates that the text and target are identical. double similarity(const String& target); - - /// The max Distance is the maximum Levenshtein distance for the text compared to some other value that + + /// The max Distance is the maximum Levenshtein distance for the text compared to some other value that /// results in score that is better than the minimum similarity. /// @param m The length of the "other value" /// @return The maximum Levenshtein distance that we care about diff --git a/include/HashMap.h b/include/HashMap.h index 3363667b..4b355ef6 100644 --- a/include/HashMap.h +++ b/include/HashMap.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/HashSet.h b/include/HashSet.h index fbeebf66..be2068cd 100644 --- a/include/HashSet.h +++ b/include/HashSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/HitQueue.h b/include/HitQueue.h index 19cb44a6..38d0691a 100644 --- a/include/HitQueue.h +++ b/include/HitQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,15 +17,15 @@ namespace Lucene /// Creates a new instance with size elements. HitQueue(int32_t size, bool prePopulate); virtual ~HitQueue(); - + LUCENE_CLASS(HitQueue); - + protected: bool prePopulate; - + protected: virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); - + /// Returns null if prePopulate is false. virtual ScoreDocPtr getSentinelObject(); }; diff --git a/include/HitQueueBase.h b/include/HitQueueBase.h index 487fa6c1..6298fa58 100644 --- a/include/HitQueueBase.h +++ b/include/HitQueueBase.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: HitQueueBase(int32_t size); virtual ~HitQueueBase(); - + LUCENE_CLASS(HitQueueBase); - + public: virtual ScoreDocPtr add(ScoreDocPtr scoreDoc); virtual ScoreDocPtr addOverflow(ScoreDocPtr scoreDoc); @@ -28,32 +28,32 @@ namespace Lucene virtual int32_t size(); virtual bool empty(); virtual void clear(); - + protected: PriorityQueueScoreDocsPtr queue; int32_t queueSize; - + public: virtual void initialize(); - + protected: virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) = 0; virtual ScoreDocPtr getSentinelObject(); - + friend class PriorityQueueScoreDocs; }; - + class LPPAPI PriorityQueueScoreDocs : public PriorityQueue { public: PriorityQueueScoreDocs(HitQueueBasePtr hitQueue, int32_t size); virtual ~PriorityQueueScoreDocs(); - + LUCENE_CLASS(PriorityQueueScoreDocs); - + protected: HitQueueBaseWeakPtr _hitQueue; - + protected: virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); virtual ScoreDocPtr getSentinelObject(); diff --git a/include/ISOLatin1AccentFilter.h b/include/ISOLatin1AccentFilter.h index 282396d5..d24d816f 100644 --- a/include/ISOLatin1AccentFilter.h +++ b/include/ISOLatin1AccentFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// A filter that replaces accented characters in the ISO Latin 1 character set (ISO-8859-1) by their unaccented + /// A filter that replaces accented characters in the ISO Latin 1 character set (ISO-8859-1) by their unaccented /// equivalent. The case will not be altered. /// /// For instance, 'à' will be replaced by 'a'. @@ -23,17 +23,17 @@ namespace Lucene public: ISOLatin1AccentFilter(TokenStreamPtr input); virtual ~ISOLatin1AccentFilter(); - + LUCENE_CLASS(ISOLatin1AccentFilter); - + protected: CharArray output; int32_t outputPos; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); - + /// To replace accented characters in a String by unaccented equivalents. void removeAccents(const wchar_t* input, int32_t length); }; diff --git a/include/IndexCommit.h b/include/IndexCommit.h index e0eea7d7..b03cc2fb 100644 --- a/include/IndexCommit.h +++ b/include/IndexCommit.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene /// Represents a single commit into an index as seen by the {@link IndexDeletionPolicy} or {@link IndexReader}. /// /// Changes to the content of an index are made visible only after the writer who made that change commits by - /// writing a new segments file (segments_N). This point in time, when the action of writing of a new segments + /// writing a new segments file (segments_N). This point in time, when the action of writing of a new segments /// file to the directory is completed, is an index commit. /// /// Each index commit point has a unique segments file associated with it. The segments file associated with a @@ -23,50 +23,50 @@ namespace Lucene { public: virtual ~IndexCommit(); - + LUCENE_CLASS(IndexCommit); - + public: /// Get the segments file (segments_N) associated with this commit point. virtual String getSegmentsFileName() = 0; - + /// Returns all index files referenced by this commit point. virtual HashSet getFileNames() = 0; - + /// Returns the {@link Directory} for the index. virtual DirectoryPtr getDirectory() = 0; - + /// Delete this commit point. This only applies when using the commit point in the context of IndexWriter's /// IndexDeletionPolicy. /// - /// Upon calling this, the writer is notified that this commit point should be deleted. + /// Upon calling this, the writer is notified that this commit point should be deleted. /// /// Decision that a commit-point should be deleted is taken by the {@link IndexDeletionPolicy} in effect - /// and therefore this should only be called by its {@link IndexDeletionPolicy#onInit onInit()} or + /// and therefore this should only be called by its {@link IndexDeletionPolicy#onInit onInit()} or /// {@link IndexDeletionPolicy#onCommit onCommit()} methods. virtual void deleteCommit() = 0; - + virtual bool isDeleted() = 0; - + /// Returns true if this commit is an optimized index. virtual bool isOptimized() = 0; - + /// Two IndexCommits are equal if both their Directory and versions are equal. virtual bool equals(LuceneObjectPtr other); - + virtual int32_t hashCode(); - - /// Returns the version for this IndexCommit. This is the same value that {@link IndexReader#getVersion} + + /// Returns the version for this IndexCommit. This is the same value that {@link IndexReader#getVersion} /// would return if it were opened on this commit. virtual int64_t getVersion() = 0; - + /// Returns the generation (the _N in segments_N) for this IndexCommit. virtual int64_t getGeneration() = 0; - - /// Convenience method that returns the last modified time of the segments_N file corresponding to this + + /// Convenience method that returns the last modified time of the segments_N file corresponding to this /// index commit, equivalent to getDirectory()->fileModified(getSegmentsFileName()). virtual int64_t getTimestamp(); - + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. Map is /// String -> String. virtual MapStringString getUserData() = 0; diff --git a/include/IndexDeletionPolicy.h b/include/IndexDeletionPolicy.h index c2927629..4bc480f0 100644 --- a/include/IndexDeletionPolicy.h +++ b/include/IndexDeletionPolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,17 +11,17 @@ namespace Lucene { - /// Policy for deletion of stale {@link IndexCommit index commits}. - /// Implement this interface, and pass + /// Policy for deletion of stale {@link IndexCommit index commits}. + /// Implement this interface, and pass /// it to one of the {@link IndexWriter} or {@link IndexReader} constructors, to customize when older - /// {@link IndexCommit point-in-time commits} are deleted from the index directory. The default deletion - /// policy is {@link KeepOnlyLastCommitDeletionPolicy}, which always removes old commits as soon as a new + /// {@link IndexCommit point-in-time commits} are deleted from the index directory. The default deletion + /// policy is {@link KeepOnlyLastCommitDeletionPolicy}, which always removes old commits as soon as a new /// commit is done (this matches the behavior before 2.2). /// - /// One expected use case for this (and the reason why it was first created) is to work around problems - /// with an index directory accessed via filesystems like NFS because NFS does not provide the "delete on - /// last close" semantics that Lucene's "point in time" search normally relies on. By implementing a - /// custom deletion policy, such as "a commit is only removed once it has been stale for more than X + /// One expected use case for this (and the reason why it was first created) is to work around problems + /// with an index directory accessed via filesystems like NFS because NFS does not provide the "delete on + /// last close" semantics that Lucene's "point in time" search normally relies on. By implementing a + /// custom deletion policy, such as "a commit is only removed once it has been stale for more than X /// minutes", you can give your readers time to refresh to the new commit before {@link IndexWriter} /// removes the old commits. Note that doing so will increase the storage requirements of the index. class LPPAPI IndexDeletionPolicy : public LuceneObject @@ -31,36 +31,36 @@ namespace Lucene public: virtual ~IndexDeletionPolicy(); - + LUCENE_CLASS(IndexDeletionPolicy); - + public: /// This is called once when a writer is first instantiated to give the policy a chance to remove old /// commit points. /// - /// The writer locates all index commits present in the index directory and calls this method. The - /// policy may choose to delete some of the commit points, doing so by calling method {@link + /// The writer locates all index commits present in the index directory and calls this method. The + /// policy may choose to delete some of the commit points, doing so by calling method {@link /// IndexCommit#delete delete()} of {@link IndexCommit}. /// - /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to - /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the - /// index content while doing that. + /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to + /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the + /// index content while doing that. /// - /// @param commits List of current {@link IndexCommit point-in-time commits}, sorted by age (the 0th + /// @param commits List of current {@link IndexCommit point-in-time commits}, sorted by age (the 0th /// one is the oldest commit). virtual void onInit(Collection commits) = 0; - - /// This is called each time the writer completed a commit. This gives the policy a chance to remove + + /// This is called each time the writer completed a commit. This gives the policy a chance to remove /// old commit points with each commit. /// - /// The policy may now choose to delete old commit points by calling method {@link + /// The policy may now choose to delete old commit points by calling method {@link /// IndexCommit#delete delete()} of {@link IndexCommit}. /// - /// This method is only called when {@link IndexWriter#commit} or {@link IndexWriter#close} is called, + /// This method is only called when {@link IndexWriter#commit} or {@link IndexWriter#close} is called, /// or possibly not at all if the {@link IndexWriter#rollback} is called. /// - /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to - /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the + /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to + /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the /// index content while doing that. /// /// @param commits List of {@link IndexCommit}, sorted by age (the 0th one is the oldest commit). diff --git a/include/IndexFileDeleter.h b/include/IndexFileDeleter.h index fb300a77..626e6b33 100644 --- a/include/IndexFileDeleter.h +++ b/include/IndexFileDeleter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,19 +17,19 @@ namespace Lucene /// counting to map the live SegmentInfos instances to individual files in the Directory. /// /// The same directory file may be referenced by more than one IndexCommit, i.e. more than one SegmentInfos. - /// Therefore we count how many commits reference each file. When all the commits referencing a certain file have + /// Therefore we count how many commits reference each file. When all the commits referencing a certain file have /// been deleted, the refcount for that file becomes zero, and the file is deleted. /// - /// A separate deletion policy interface (IndexDeletionPolicy) is consulted on creation (onInit) and once per + /// A separate deletion policy interface (IndexDeletionPolicy) is consulted on creation (onInit) and once per /// commit (onCommit), to decide when a commit should be removed. - /// + /// /// It is the business of the IndexDeletionPolicy to choose when to delete commit points. The actual mechanics of /// file deletion, retrying, etc, derived from the deletion of commit points is the business of the IndexFileDeleter. /// - /// The current default deletion policy is {@link KeepOnlyLastCommitDeletionPolicy}, which removes all prior commits + /// The current default deletion policy is {@link KeepOnlyLastCommitDeletionPolicy}, which removes all prior commits /// when a new commit has completed. This matches the behavior before 2.2. /// - /// Note that you must hold the write.lock before instantiating this class. It opens segments_N file(s) directly + /// Note that you must hold the write.lock before instantiating this class. It opens segments_N file(s) directly /// with no retry logic. class IndexFileDeleter : public LuceneObject { @@ -38,65 +38,65 @@ namespace Lucene /// the policy to let it delete commits. This will remove any files not referenced by any of the commits. IndexFileDeleter(DirectoryPtr directory, IndexDeletionPolicyPtr policy, SegmentInfosPtr segmentInfos, InfoStreamPtr infoStream, DocumentsWriterPtr docWriter, HashSet synced); virtual ~IndexFileDeleter(); - + LUCENE_CLASS(IndexFileDeleter); - + protected: /// Files that we tried to delete but failed (likely because they are open and we are running on Windows), /// so we will retry them again later HashSet deletable; - + /// Reference count for all files in the index. Counts how many existing commits reference a file. MapStringRefCount refCounts; - + /// Holds all commits (segments_N) currently in the index. This will have just 1 commit if you are using the - /// default delete policy (KeepOnlyLastCommitDeletionPolicy). Other policies may leave commit points live for + /// default delete policy (KeepOnlyLastCommitDeletionPolicy). Other policies may leave commit points live for /// longer in which case this list would be longer than 1 Collection commits; - + /// Holds files we had incref'd from the previous non-commit checkpoint Collection< HashSet > lastFiles; - + /// Commits that the IndexDeletionPolicy have decided to delete Collection commitsToDelete; - + InfoStreamPtr infoStream; DirectoryPtr directory; IndexDeletionPolicyPtr policy; DocumentsWriterPtr docWriter; - + SegmentInfosPtr lastSegmentInfos; HashSet synced; - + /// Change to true to see details of reference counts when infoStream != null static bool VERBOSE_REF_COUNTS; - + public: bool startingCommitDeleted; - + protected: void message(const String& message); - + /// Remove the CommitPoints in the commitsToDelete List by DecRef'ing all files from each SegmentInfos. void deleteCommits(); - + void deletePendingFiles(); - + RefCountPtr getRefCount(const String& fileName); - + public: void setInfoStream(InfoStreamPtr infoStream); - + SegmentInfosPtr getLastSegmentInfos(); - + /// Writer calls this when it has hit an error and had to roll back, to tell us that there may now be - /// unreferenced files in the filesystem. So we re-list the filesystem and delete such files. If + /// unreferenced files in the filesystem. So we re-list the filesystem and delete such files. If /// segmentName is non-null, we will only delete files corresponding to that segment. void refresh(const String& segmentName); void refresh(); - + void close(); - + /// For definition of "check point" see IndexWriter comments: "Clarification: Check Points (and commits)". /// Writer calls this when it has made a "consistent change" to the index, meaning new files are written to /// the index and the in-memory SegmentInfos have been modified to point to those files. @@ -106,46 +106,46 @@ namespace Lucene /// We simply incref the files referenced by the new SegmentInfos and decref the files we had previously /// seen (if any). /// - /// If this is a commit, we also call the policy to give it a chance to remove other commits. If any + /// If this is a commit, we also call the policy to give it a chance to remove other commits. If any /// commits are removed, we decref their files as well. void checkpoint(SegmentInfosPtr segmentInfos, bool isCommit); - + void incRef(SegmentInfosPtr segmentInfos, bool isCommit); void incRef(HashSet files); void incRef(const String& fileName); void decRef(HashSet files); void decRef(const String& fileName); void decRef(SegmentInfosPtr segmentInfos); - + bool exists(const String& fileName); - + void deleteFiles(HashSet files); - + /// Deletes the specified files, but only if they are new (have not yet been incref'd). void deleteNewFiles(HashSet files); - + void deleteFile(const String& fileName); }; - + /// Tracks the reference count for a single index file class RefCount : public LuceneObject { public: RefCount(const String& fileName); virtual ~RefCount(); - + LUCENE_CLASS(RefCount); - + public: String fileName; // fileName used only for better assert error messages bool initDone; int32_t count; - + public: int32_t IncRef(); int32_t DecRef(); - }; - + }; + /// Holds details for each commit point. This class is also passed to the deletion policy. Note: this class /// has a natural ordering that is inconsistent with equals. class CommitPoint : public IndexCommit @@ -153,9 +153,9 @@ namespace Lucene public: CommitPoint(Collection commitsToDelete, DirectoryPtr directory, SegmentInfosPtr segmentInfos); virtual ~CommitPoint(); - + LUCENE_CLASS(CommitPoint); - + public: int64_t gen; HashSet files; @@ -167,36 +167,36 @@ namespace Lucene int64_t generation; bool _isOptimized; MapStringString userData; - + public: virtual String toString(); - + /// Returns true if this commit is an optimized index. virtual bool isOptimized(); - + /// Get the segments file (segments_N) associated with this commit point. virtual String getSegmentsFileName(); - + /// Returns all index files referenced by this commit point. virtual HashSet getFileNames(); - + /// Returns the {@link Directory} for the index. virtual DirectoryPtr getDirectory(); - + /// Returns the version for this IndexCommit. virtual int64_t getVersion(); - + /// Returns the generation (the _N in segments_N) for this IndexCommit. virtual int64_t getGeneration(); - + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. virtual MapStringString getUserData(); - + /// Called only be the deletion policy, to remove this commit point from the index. virtual void deleteCommit(); - + virtual bool isDeleted(); - + virtual int32_t compareTo(LuceneObjectPtr other); }; } diff --git a/include/IndexFileNameFilter.h b/include/IndexFileNameFilter.h index f80a27d9..1ba2c399 100644 --- a/include/IndexFileNameFilter.h +++ b/include/IndexFileNameFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,12 +17,12 @@ namespace Lucene public: /// Returns true if this is a file known to be a Lucene index file. static bool accept(const String& directory, const String& name); - - /// Returns true if this is a file that would be contained in a CFS file. - /// This function should only be called on files that pass the + + /// Returns true if this is a file that would be contained in a CFS file. + /// This function should only be called on files that pass the /// {@link #accept} (ie, are already known to be a Lucene index file). static bool isCFSFile(const String& name); - + /// Return singleton IndexFileNameFilter static IndexFileNameFilterPtr getFilter(); }; diff --git a/include/IndexFileNames.h b/include/IndexFileNames.h index 990a224f..6495d14c 100644 --- a/include/IndexFileNames.h +++ b/include/IndexFileNames.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,99 +15,99 @@ namespace Lucene class IndexFileNames : public LuceneObject { public: - virtual ~IndexFileNames(); + virtual ~IndexFileNames(); LUCENE_CLASS(IndexFileNames); - + public: /// Name of the index segment file. static const String& SEGMENTS(); - + /// Name of the generation reference file name. static const String& SEGMENTS_GEN(); - + /// Name of the index deletable file (only used in pre-lockless indices). static const String& DELETABLE(); - + /// Extension of norms file. static const String& NORMS_EXTENSION(); - + /// Extension of freq postings file. static const String& FREQ_EXTENSION(); - + /// Extension of prox postings file. static const String& PROX_EXTENSION(); - + /// Extension of terms file. static const String& TERMS_EXTENSION(); - + /// Extension of terms index file. static const String& TERMS_INDEX_EXTENSION(); - + /// Extension of stored fields index file. static const String& FIELDS_INDEX_EXTENSION(); - + /// Extension of stored fields file. static const String& FIELDS_EXTENSION(); - + /// Extension of vectors fields file. static const String& VECTORS_FIELDS_EXTENSION(); - + /// Extension of vectors documents file. static const String& VECTORS_DOCUMENTS_EXTENSION(); - + /// Extension of vectors index file. static const String& VECTORS_INDEX_EXTENSION(); - + /// Extension of compound file. static const String& COMPOUND_FILE_EXTENSION(); - + /// Extension of compound file for doc store files. static const String& COMPOUND_FILE_STORE_EXTENSION(); - + /// Extension of deletes. static const String& DELETES_EXTENSION(); - + /// Extension of field infos. static const String& FIELD_INFOS_EXTENSION(); - + /// Extension of plain norms. static const String& PLAIN_NORMS_EXTENSION(); - + /// Extension of separate norms. static const String& SEPARATE_NORMS_EXTENSION(); - + /// Extension of gen file. static const String& GEN_EXTENSION(); - - /// This array contains all filename extensions used by Lucene's index - /// files, with two exceptions, namely the extension made up from + + /// This array contains all filename extensions used by Lucene's index + /// files, with two exceptions, namely the extension made up from /// ".f" + number and from ".s" + number. Also note that Lucene's /// "segments_N" files do not have any filename extension. static const HashSet INDEX_EXTENSIONS(); - - /// File extensions that are added to a compound file (same as + + /// File extensions that are added to a compound file (same as /// {@link #INDEX_EXTENSIONS}, minus "del", "gen", "cfs"). static const HashSet INDEX_EXTENSIONS_IN_COMPOUND_FILE(); - + static const HashSet STORE_INDEX_EXTENSIONS(); static const HashSet NON_STORE_INDEX_EXTENSIONS(); - + /// File extensions of old-style index files. static const HashSet COMPOUND_EXTENSIONS(); - + /// File extensions for term vector support. static const HashSet VECTOR_EXTENSIONS(); - - /// Computes the full file name from base, extension and generation. + + /// Computes the full file name from base, extension and generation. /// If the generation is {@link SegmentInfo#NO}, the file name is null. /// If it's {@link SegmentInfo#WITHOUT_GEN} the file name is base+extension. /// If it's > 0, the file name is base_generation+extension. static String fileNameFromGeneration(const String& base, const String& extension, int64_t gen); - - /// Returns true if the provided filename is one of the doc store files + + /// Returns true if the provided filename is one of the doc store files /// (ends with an extension in STORE_INDEX_EXTENSIONS). static bool isDocStoreFile(const String& fileName); - + /// Return segment file name. static String segmentFileName(const String& segmentName, const String& ext); }; diff --git a/include/IndexInput.h b/include/IndexInput.h index 33c7902a..964545ba 100644 --- a/include/IndexInput.h +++ b/include/IndexInput.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,26 +19,26 @@ namespace Lucene public: IndexInput(); virtual ~IndexInput(); - + LUCENE_CLASS(IndexInput); - + protected: bool preUTF8Strings; // true if we are reading old (modified UTF8) string format - + public: /// Reads and returns a single byte. /// @see IndexOutput#writeByte(uint8_t) virtual uint8_t readByte() = 0; - + /// Reads a specified number of bytes into an array at the specified offset. /// @param b the array to read bytes into. /// @param offset the offset in the array to start storing bytes. /// @param length the number of bytes to read. /// @see IndexOutput#writeBytes(const uint8_t*, int) virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) = 0; - - /// Reads a specified number of bytes into an array at the specified offset - /// with control over whether the read should be buffered (callers who have + + /// Reads a specified number of bytes into an array at the specified offset + /// with control over whether the read should be buffered (callers who have /// their own buffer should pass in "false" for useBuffer). Currently only /// {@link BufferedIndexInput} respects this parameter. /// @param b the array to read bytes into. @@ -47,75 +47,75 @@ namespace Lucene /// @param useBuffer set to false if the caller will handle buffering. /// @see IndexOutput#writeBytes(const uint8_t*,int) virtual void readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer); - + /// Reads four bytes and returns an int. /// @see IndexOutput#writeInt(int32_t) virtual int32_t readInt(); - + /// Reads an int stored in variable-length format. Reads between one and five /// bytes. Smaller values take fewer bytes. Negative numbers are not supported. /// @see IndexOutput#writeVInt(int32_t) virtual int32_t readVInt(); - + /// Reads eight bytes and returns a int64. /// @see IndexOutput#writeLong(int64_t) virtual int64_t readLong(); - - /// Reads a int64 stored in variable-length format. Reads between one and nine + + /// Reads a int64 stored in variable-length format. Reads between one and nine /// bytes. Smaller values take fewer bytes. Negative numbers are not supported. virtual int64_t readVLong(); - - /// Call this if readString should read characters stored in the old modified + + /// Call this if readString should read characters stored in the old modified /// UTF8 format. This is used for indices written pre-2.4. virtual void setModifiedUTF8StringsMode(); - + /// Reads a string. /// @see IndexOutput#writeString(const String&) virtual String readString(); - + /// Reads a modified UTF8 format string. virtual String readModifiedUTF8String(); - + /// Reads Lucene's old "modified UTF-8" encoded characters into an array. /// @param buffer the array to read characters into. /// @param start the offset in the array to start storing characters. /// @param length the number of characters to read. /// @see IndexOutput#writeChars(const String& s, int32_t, int32_t) virtual int32_t readChars(wchar_t* buffer, int32_t start, int32_t length); - - /// Similar to {@link #readChars(wchar_t*, int32_t, int32_t)} but does not + + /// Similar to {@link #readChars(wchar_t*, int32_t, int32_t)} but does not /// do any conversion operations on the bytes it is reading in. It still /// has to invoke {@link #readByte()} just as {@link #readChars(wchar_t*, int32_t, int32_t)} /// does, but it does not need a buffer to store anything and it does not have - /// to do any of the bitwise operations, since we don't actually care what is + /// to do any of the bitwise operations, since we don't actually care what is /// in the byte except to determine how many more bytes to read. /// @param length The number of chars to read. /// @deprecated this method operates on old "modified utf8" encoded strings. virtual void skipChars(int32_t length); - + /// Closes the stream to further operations. virtual void close() = 0; - + /// Returns the current position in this file, where the next read will occur. /// @see #seek(int64_t) virtual int64_t getFilePointer() = 0; - + /// Sets current position in this file, where the next read will occur. /// @see #getFilePointer() virtual void seek(int64_t pos) = 0; - + /// The number of bytes in the file. virtual int64_t length() = 0; - + /// Returns a clone of this stream. /// - /// Clones of a stream access the same data, and are positioned at the same + /// Clones of a stream access the same data, and are positioned at the same /// point as the stream they were cloned from. /// - /// Subclasses must ensure that clones may be positioned at different points + /// Subclasses must ensure that clones may be positioned at different points /// in the input from each other and from the stream they were cloned from. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Read string map as a series of key/value pairs. virtual MapStringString readStringStringMap(); }; diff --git a/include/IndexOutput.h b/include/IndexOutput.h index 29f1700f..edcdfd15 100644 --- a/include/IndexOutput.h +++ b/include/IndexOutput.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// Abstract base class for output to a file in a Directory. A random-access output stream. Used for all + /// Abstract base class for output to a file in a Directory. A random-access output stream. Used for all /// Lucene index output operations. /// @see Directory /// @see IndexInput @@ -19,86 +19,86 @@ namespace Lucene { public: virtual ~IndexOutput(); - + LUCENE_CLASS(IndexOutput); - + protected: static const int32_t COPY_BUFFER_SIZE; ByteArray copyBuffer; - + public: /// Writes a single byte. /// @see IndexInput#readByte() virtual void writeByte(uint8_t b) = 0; - + /// Writes an array of bytes. /// @param b the bytes to write. /// @param length the number of bytes to write. /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length) = 0; - + /// Forces any buffered output to be written. virtual void flush() = 0; - + /// Closes this stream to further operations. virtual void close() = 0; - + /// Returns the current position in this file, where the next write will occur. virtual int64_t getFilePointer() = 0; - + /// Sets current position in this file, where the next write will occur. /// @see #getFilePointer() virtual void seek(int64_t pos) = 0; - + /// The number of bytes in the file. virtual int64_t length() = 0; - + public: /// Writes an array of bytes. /// @param b the bytes to write. /// @param length the number of bytes to write. /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) void writeBytes(const uint8_t* b, int32_t length); - + /// Writes an int as four bytes. /// @see IndexInput#readInt() void writeInt(int32_t i); - - /// Writes an int in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. + + /// Writes an int in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. /// Negative numbers are not supported. /// @see IndexInput#readVInt() void writeVInt(int32_t i); - + /// Writes a int64 as eight bytes. /// @see IndexInput#readLong() void writeLong(int64_t i); - - /// Writes an int64 in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. + + /// Writes an int64 in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. /// Negative numbers are not supported. /// @see IndexInput#readVLong() void writeVLong(int64_t i); - + /// Writes a string. /// @see IndexInput#readString() void writeString(const String& s); - + /// Writes a sub sequence of characters from s as the old format (modified UTF-8 encoded bytes). /// @param s the source of the characters. /// @param start the first character in the sequence. /// @param length the number of characters in the sequence. /// @deprecated -- please use {@link #writeString} void writeChars(const String& s, int32_t start, int32_t length); - + /// Copy numBytes bytes from input to ourself. void copyBytes(IndexInputPtr input, int64_t numBytes); - - /// Set the file length. By default, this method does nothing (it's optional for a Directory to implement it). - /// But, certain Directory implementations (for example @see FSDirectory) can use this to inform the underlying IO - /// system to pre-allocate the file to the specified size. If the length is longer than the current file length, + + /// Set the file length. By default, this method does nothing (it's optional for a Directory to implement it). + /// But, certain Directory implementations (for example @see FSDirectory) can use this to inform the underlying IO + /// system to pre-allocate the file to the specified size. If the length is longer than the current file length, /// the bytes added to the file are undefined. Otherwise the file is truncated. /// @param length file length. void setLength(int64_t length); - + /// Write string map as a series of key/value pairs. /// @param map map of string-string key-values. void writeStringStringMap(MapStringString map); diff --git a/include/IndexReader.h b/include/IndexReader.h index ef515267..80353db3 100644 --- a/include/IndexReader.h +++ b/include/IndexReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,40 +11,40 @@ namespace Lucene { - /// IndexReader is an abstract class, providing an interface for accessing an index. Search of an index is done + /// IndexReader is an abstract class, providing an interface for accessing an index. Search of an index is done /// entirely through this abstract interface, so that any subclass which implements it is searchable. /// - /// Concrete subclasses of IndexReader are usually constructed with a call to one of the static open methods, + /// Concrete subclasses of IndexReader are usually constructed with a call to one of the static open methods, /// eg. {@link #open(DirectoryPtr, bool)}. /// - /// For efficiency, in this API documents are often referred to via document numbers, non-negative integers which - /// each name a unique document in the index. These document numbers are ephemeral -they may change as documents - /// are added to and deleted from an index. Clients should thus not rely on a given document having the same number + /// For efficiency, in this API documents are often referred to via document numbers, non-negative integers which + /// each name a unique document in the index. These document numbers are ephemeral -they may change as documents + /// are added to and deleted from an index. Clients should thus not rely on a given document having the same number /// between sessions. - /// - /// An IndexReader can be opened on a directory for which an IndexWriter is opened already, but it cannot be used + /// + /// An IndexReader can be opened on a directory for which an IndexWriter is opened already, but it cannot be used /// to delete documents from the index then. /// - /// NOTE: for backwards API compatibility, several methods are not listed as abstract, but have no useful implementations - /// in this base class and instead always throw UnsupportedOperation exception. Subclasses are strongly encouraged to + /// NOTE: for backwards API compatibility, several methods are not listed as abstract, but have no useful implementations + /// in this base class and instead always throw UnsupportedOperation exception. Subclasses are strongly encouraged to /// override these methods, but in many cases may not need to. /// - /// NOTE: as of 2.4, it's possible to open a read-only IndexReader using the static open methods that accept the bool - /// readOnly parameter. Such a reader has better concurrency as it's not necessary to synchronize on the isDeleted + /// NOTE: as of 2.4, it's possible to open a read-only IndexReader using the static open methods that accept the bool + /// readOnly parameter. Such a reader has better concurrency as it's not necessary to synchronize on the isDeleted /// method. You must specify false if you want to make changes with the resulting IndexReader. /// - /// NOTE: {@link IndexReader} instances are completely thread safe, meaning multiple threads can call any of its methods, - /// concurrently. If your application requires external synchronization, you should not synchronize on the IndexReader + /// NOTE: {@link IndexReader} instances are completely thread safe, meaning multiple threads can call any of its methods, + /// concurrently. If your application requires external synchronization, you should not synchronize on the IndexReader /// instance; use your own (non-Lucene) objects instead. class LPPAPI IndexReader : public LuceneObject { public: IndexReader(); virtual ~IndexReader(); - + LUCENE_CLASS(IndexReader); - - public: + + public: /// Constants describing field properties, for example used for {@link IndexReader#getFieldNames(FieldOption)}. enum FieldOption { @@ -71,116 +71,116 @@ namespace Lucene /// All fields with termvectors with offset values and position values enabled FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET }; - + static const int32_t DEFAULT_TERMS_INDEX_DIVISOR; - + protected: bool closed; bool _hasChanges; int32_t refCount; - + public: /// Returns the current refCount for this reader int32_t getRefCount(); - - /// Increments the refCount of this IndexReader instance. RefCounts are used to determine when a reader can be - /// closed safely, i.e. as soon as there are no more references. Be sure to always call a corresponding {@link - /// #decRef}, in a finally clause; otherwise the reader may never be closed. Note that {@link #close} simply - /// calls decRef(), which means that the IndexReader will not really be closed until {@link #decRef} has been + + /// Increments the refCount of this IndexReader instance. RefCounts are used to determine when a reader can be + /// closed safely, i.e. as soon as there are no more references. Be sure to always call a corresponding {@link + /// #decRef}, in a finally clause; otherwise the reader may never be closed. Note that {@link #close} simply + /// calls decRef(), which means that the IndexReader will not really be closed until {@link #decRef} has been /// called for all outstanding references. /// @see #decRef void incRef(); - - /// Decreases the refCount of this IndexReader instance. If the refCount drops to 0, then pending changes + + /// Decreases the refCount of this IndexReader instance. If the refCount drops to 0, then pending changes /// (if any) are committed to the index and this reader is closed. /// @see #incRef void decRef(); - + /// Returns a IndexReader reading the index in the given Directory, with readOnly = true. /// @param directory the index directory static IndexReaderPtr open(DirectoryPtr directory); - - /// Returns an IndexReader reading the index in the given Directory. You should pass readOnly = true, since it - /// gives much better concurrent performance, unless you intend to do write operations (delete documents or change + + /// Returns an IndexReader reading the index in the given Directory. You should pass readOnly = true, since it + /// gives much better concurrent performance, unless you intend to do write operations (delete documents or change /// norms) with the reader. /// @param directory the index directory /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader static IndexReaderPtr open(DirectoryPtr directory, bool readOnly); - - /// Returns an IndexReader reading the index in the given {@link IndexCommit}. You should pass readOnly = true, - /// since it gives much better concurrent performance, unless you intend to do write operations (delete documents + + /// Returns an IndexReader reading the index in the given {@link IndexCommit}. You should pass readOnly = true, + /// since it gives much better concurrent performance, unless you intend to do write operations (delete documents /// or change norms) with the reader. /// @param commit the commit point to open /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader static IndexReaderPtr open(IndexCommitPtr commit, bool readOnly); - - /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. - /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write + + /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. + /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write /// operations (delete documents or change norms) with the reader. /// @param directory the index directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform /// deletes or to set norms); see {@link IndexWriter} for details. /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly); - - /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. - /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write + + /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. + /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write /// operations (delete documents or change norms) with the reader. /// @param directory the index directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform /// deletes or to set norms); see {@link IndexWriter} for details. /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the - /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at - /// indexing time while this setting can be set per reader. When set to N, then one in every - /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 - /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. The + /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the + /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at + /// indexing time while this setting can be set per reader. When set to N, then one in every + /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 + /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. The /// default value is 1. Set this to -1 to skip loading the terms index entirely. static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); - - /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom - /// {@link IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, + + /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom + /// {@link IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, /// unless you intend to do write operations (delete documents or change norms) with the reader. - /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to list all + /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to list all /// commits in a directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform /// deletes or to set norms); see {@link IndexWriter} for details. /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader static IndexReaderPtr open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly); - - /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom {@link - /// IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, unless + + /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom {@link + /// IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, unless /// you intend to do write operations (delete documents or change norms) with the reader. - /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to + /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to /// list all commits in a directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform deletes + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform deletes /// or to set norms); see {@link IndexWriter} for details. /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the same effect as - /// {@link IndexWriter#setTermIndexInterval} except that setting must be done at indexing time while this setting can - /// be set per reader. When set to N, then one in every N * termIndexInterval terms in the index is loaded into - /// memory. By setting this to a value > 1 you can reduce memory usage, at the expense of higher latency when loading + /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the same effect as + /// {@link IndexWriter#setTermIndexInterval} except that setting must be done at indexing time while this setting can + /// be set per reader. When set to N, then one in every N * termIndexInterval terms in the index is loaded into + /// memory. By setting this to a value > 1 you can reduce memory usage, at the expense of higher latency when loading /// a TermInfo. The default value is 1. Set this to -1 to skip loading the terms index entirely. static IndexReaderPtr open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); - + /// Refreshes an IndexReader if the index has changed since this instance was (re)opened. /// - /// Opening an IndexReader is an expensive operation. This method can be used to refresh an existing IndexReader to - /// reduce these costs. This method tries to only load segments that have changed or were created after the + /// Opening an IndexReader is an expensive operation. This method can be used to refresh an existing IndexReader to + /// reduce these costs. This method tries to only load segments that have changed or were created after the /// IndexReader was (re)opened. /// - /// If the index has not changed since this instance was (re)opened, then this call is a NOOP and returns this + /// If the index has not changed since this instance was (re)opened, then this call is a NOOP and returns this /// instance. Otherwise, a new instance is returned. The old instance is not closed and remains usable. /// - /// If the reader is reopened, even though they share resources internally, it's safe to make changes (deletions, - /// norms) with the new reader. All shared mutable state obeys "copy on write" semantics to ensure the changes are + /// If the reader is reopened, even though they share resources internally, it's safe to make changes (deletions, + /// norms) with the new reader. All shared mutable state obeys "copy on write" semantics to ensure the changes are /// not seen by other readers. /// - /// You can determine whether a reader was actually reopened by comparing the old instance with the + /// You can determine whether a reader was actually reopened by comparing the old instance with the /// instance returned by this method: /// ///
    -        /// IndexReaderPtr reader = ... 
    +        /// IndexReaderPtr reader = ...
             /// ...
             /// IndexReaderPtr newReader = r.reopen();
             /// if (newReader != reader)
    @@ -192,166 +192,166 @@ namespace Lucene
             /// ...
             /// 
    /// - /// Be sure to synchronize that code so that other threads, if present, can never use reader after it has been - /// closed and before it's switched to newReader. If this reader is a near real-time reader (obtained from + /// Be sure to synchronize that code so that other threads, if present, can never use reader after it has been + /// closed and before it's switched to newReader. If this reader is a near real-time reader (obtained from /// {@link IndexWriter#getReader()}, reopen() will simply call writer.getReader() again for you, though this /// may change in the future. virtual IndexReaderPtr reopen(); - - /// Just like {@link #reopen()}, except you can change the readOnly of the original reader. If the index is + + /// Just like {@link #reopen()}, except you can change the readOnly of the original reader. If the index is /// unchanged but readOnly is different then a new reader will be returned. virtual IndexReaderPtr reopen(bool openReadOnly); - - /// Reopen this reader on a specific commit point. This always returns a readOnly reader. If the specified commit - /// point matches what this reader is already on, and this reader is already readOnly, then this same instance is + + /// Reopen this reader on a specific commit point. This always returns a readOnly reader. If the specified commit + /// point matches what this reader is already on, and this reader is already readOnly, then this same instance is /// returned; if it is not already readOnly, a readOnly clone is returned. virtual IndexReaderPtr reopen(IndexCommitPtr commit); - + /// Efficiently clones the IndexReader (sharing most internal state). /// - /// On cloning a reader with pending changes (deletions, norms), the original reader transfers its write lock to the - /// cloned reader. This means only the cloned reader may make further changes to the index, and commit the changes + /// On cloning a reader with pending changes (deletions, norms), the original reader transfers its write lock to the + /// cloned reader. This means only the cloned reader may make further changes to the index, and commit the changes /// to the index on close, but the old reader still reflects all changes made up until it was cloned. /// - /// Like {@link #reopen()}, it's safe to make changes to either the original or the cloned reader: all shared mutable + /// Like {@link #reopen()}, it's safe to make changes to either the original or the cloned reader: all shared mutable /// state obeys "copy on write" semantics to ensure the changes are not seen by other readers. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Clones the IndexReader and optionally changes readOnly. A readOnly reader cannot open a writable reader. virtual LuceneObjectPtr clone(bool openReadOnly, LuceneObjectPtr other = LuceneObjectPtr()); - - /// Returns the directory associated with this index. The default implementation returns the directory specified by + + /// Returns the directory associated with this index. The default implementation returns the directory specified by /// subclasses when delegating to the IndexReader(Directory) constructor, or throws an UnsupportedOperation exception /// if one was not specified. virtual DirectoryPtr directory(); - - /// Returns the time the index in the named directory was last modified. Do not use this to check - /// whether the reader is still up-to-date, use {@link #isCurrent()} instead. + + /// Returns the time the index in the named directory was last modified. Do not use this to check + /// whether the reader is still up-to-date, use {@link #isCurrent()} instead. static int64_t lastModified(DirectoryPtr directory2); - - /// Reads version number from segments files. The version number is initialized with a timestamp + + /// Reads version number from segments files. The version number is initialized with a timestamp /// and then increased by one for each change of the index. /// @param directory where the index resides. /// @return version number. static int64_t getCurrentVersion(DirectoryPtr directory); - - /// Reads commitUserData, previously passed to {@link IndexWriter#commit(MapStringString)}, from - /// current index segments file. This will return null if {@link IndexWriter#commit(MapStringString)} + + /// Reads commitUserData, previously passed to {@link IndexWriter#commit(MapStringString)}, from + /// current index segments file. This will return null if {@link IndexWriter#commit(MapStringString)} /// has never been called for this index. static MapStringString getCommitUserData(DirectoryPtr directory); - + /// Version number when this IndexReader was opened. Not implemented in the IndexReader base class. /// - /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link - /// #reopen} on a reader based on a Directory), then this method returns the version recorded in the - /// commit that the reader opened. This version is advanced every time {@link IndexWriter#commit} + /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link + /// #reopen} on a reader based on a Directory), then this method returns the version recorded in the + /// commit that the reader opened. This version is advanced every time {@link IndexWriter#commit} /// is called. /// - /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link - /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this - /// method returns the version of the last commit done by the writer. Note that even as further - /// changes are made with the writer, the version will not changed until a commit is completed. + /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link + /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this + /// method returns the version of the last commit done by the writer. Note that even as further + /// changes are made with the writer, the version will not changed until a commit is completed. /// Thus, you should not rely on this method to determine when a near real-time reader should be /// opened. Use {@link #isCurrent} instead. virtual int64_t getVersion(); - - /// Retrieve the String userData optionally passed to IndexWriter#commit. This will return null if + + /// Retrieve the String userData optionally passed to IndexWriter#commit. This will return null if /// {@link IndexWriter#commit(MapStringString)} has never been called for this index. virtual MapStringString getCommitUserData(); - + /// Check whether any new changes have occurred to the index since this reader was opened. /// - /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link - /// #reopen} on a reader based on a Directory), then this method checks if any further commits (see + /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link + /// #reopen} on a reader based on a Directory), then this method checks if any further commits (see /// {@link IndexWriter#commit} have occurred in that directory). /// - /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link - /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this - /// method checks if either a new commit has occurred, or any new uncommitted changes have taken - /// place via the writer. Note that even if the writer has only performed merging, this method + /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link + /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this + /// method checks if either a new commit has occurred, or any new uncommitted changes have taken + /// place via the writer. Note that even if the writer has only performed merging, this method /// will still return false. /// - /// In any event, if this returns false, you should call {@link #reopen} to get a new reader that + /// In any event, if this returns false, you should call {@link #reopen} to get a new reader that /// sees the changes. virtual bool isCurrent(); - /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented + /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented /// in the IndexReader base class. /// @return true if the index is optimized; false otherwise virtual bool isOptimized(); - - /// Return an array of term frequency vectors for the specified document. The array contains a - /// vector for each vectorized field in the document. Each vector contains terms and frequencies - /// for all terms in a given vectorized field. If no such fields existed, the method returns null. - /// The term vectors that are returned may either be of type {@link TermFreqVector} or of type + + /// Return an array of term frequency vectors for the specified document. The array contains a + /// vector for each vectorized field in the document. Each vector contains terms and frequencies + /// for all terms in a given vectorized field. If no such fields existed, the method returns null. + /// The term vectors that are returned may either be of type {@link TermFreqVector} or of type /// {@link TermPositionVector} if positions or offsets have been stored. /// /// @param docNumber document for which term frequency vectors are returned - /// @return array of term frequency vectors. May be null if no term vectors have been stored for the + /// @return array of term frequency vectors. May be null if no term vectors have been stored for the /// specified document. virtual Collection getTermFreqVectors(int32_t docNumber) = 0; - - /// Return a term frequency vector for the specified document and field. The returned vector contains - /// terms and frequencies for the terms in the specified field of this document, if the field had the - /// storeTermVector flag set. If termvectors had been stored with positions or offsets, a + + /// Return a term frequency vector for the specified document and field. The returned vector contains + /// terms and frequencies for the terms in the specified field of this document, if the field had the + /// storeTermVector flag set. If termvectors had been stored with positions or offsets, a /// {@link TermPositionVector} is returned. - /// + /// /// @param docNumber document for which the term frequency vector is returned. /// @param field field for which the term frequency vector is returned. - /// @return term frequency vector May be null if field does not exist in the specified document or + /// @return term frequency vector May be null if field does not exist in the specified document or /// term vector was not stored. virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field) = 0; - - /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays + + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays /// of the {@link TermFreqVector}. /// @param docNumber The number of the document to load the vector for /// @param field The name of the field to load /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) = 0; - + /// Map all the term vectors for all fields in a Document /// @param docNumber The number of the document to load the vector for /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) = 0; - - /// Returns true if an index exists at the specified directory. If the directory does not exist or + + /// Returns true if an index exists at the specified directory. If the directory does not exist or /// if there is no index in it. /// @param directory the directory to check for an index /// @return true if an index exists; false otherwise static bool indexExists(DirectoryPtr directory); - + /// Returns the number of documents in this index. virtual int32_t numDocs() = 0; - - /// Returns one greater than the largest possible document number. This may be used to, eg., determine + + /// Returns one greater than the largest possible document number. This may be used to, eg., determine /// how big to allocate an array which will have an element for every document number in an index. virtual int32_t maxDoc() = 0; - + /// Returns the number of deleted documents. int32_t numDeletedDocs(); - + /// Returns the stored fields of the n'th Document in this index. /// - /// NOTE: for performance reasons, this method does not check if the requested document is deleted, and - /// therefore asking for a deleted document may yield unspecified results. Usually this is not required, - /// however you can call {@link #isDeleted(int)} with the requested document ID to verify the document + /// NOTE: for performance reasons, this method does not check if the requested document is deleted, and + /// therefore asking for a deleted document may yield unspecified results. Usually this is not required, + /// however you can call {@link #isDeleted(int)} with the requested document ID to verify the document /// is not deleted. virtual DocumentPtr document(int32_t n); - + /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine - /// what {@link Field}s to load and how they should be loaded. + /// what {@link Field}s to load and how they should be loaded. /// NOTE: If this Reader (more specifically, the underlying FieldsReader) is closed before the lazy - /// {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} - /// to be available after closing you must explicitly load it or fetch the Document again with a new + /// {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} + /// to be available after closing you must explicitly load it or fetch the Document again with a new /// loader. /// - /// NOTE: for performance reasons, this method does not check if the requested document is deleted, - /// and therefore asking for a deleted document may yield unspecified results. Usually this is not + /// NOTE: for performance reasons, this method does not check if the requested document is deleted, + /// and therefore asking for a deleted document may yield unspecified results. Usually this is not /// required, however you can call {@link #isDeleted(int32_t)} with the requested document ID to verify /// the document is not deleted. /// /// @param n Get the document at the n'th position - /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on + /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on /// the Document. May be null, in which case all Fields will be loaded. /// @return The stored fields of the {@link Document} at the n'th position /// @see Fieldable @@ -359,31 +359,31 @@ namespace Lucene /// @see SetBasedFieldSelector /// @see LoadFirstFieldSelector virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector) = 0; - - /// Returns true if document n has been deleted + + /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n) = 0; - + /// Returns true if any documents have been deleted virtual bool hasDeletions() = 0; - + /// Used for testing virtual bool hasChanges(); - + /// Returns true if there are norms stored for this field. virtual bool hasNorms(const String& field); - - /// Returns the byte-encoded normalization factor for the named field of every document. This is used + + /// Returns the byte-encoded normalization factor for the named field of every document. This is used /// by the search code to score documents. /// @see Field#setBoost(double) virtual ByteArray norms(const String& field) = 0; - - /// Reads the byte-encoded normalization factor for the named field of every document. This is used + + /// Reads the byte-encoded normalization factor for the named field of every document. This is used /// by the search code to score documents. /// @see Field#setBoost(double) virtual void norms(const String& field, ByteArray norms, int32_t offset) = 0; - - /// Resets the normalization factor for the named field of the named document. The norm represents - /// the product of the field's {@link Fieldable#setBoost(double) boost} and its {@link + + /// Resets the normalization factor for the named field of the named document. The norm represents + /// the product of the field's {@link Fieldable#setBoost(double) boost} and its {@link /// Similarity#lengthNorm(String, int) length normalization}. Thus, to preserve the length normalization /// values when resetting this, one should base the new value upon the old. /// @@ -392,164 +392,164 @@ namespace Lucene /// @see #norms(String) /// @see Similarity#decodeNorm(byte) virtual void setNorm(int32_t doc, const String& field, uint8_t value); - + /// Resets the normalization factor for the named field of the named document. /// /// @see #norms(String) /// @see Similarity#decodeNorm(byte) virtual void setNorm(int32_t doc, const String& field, double value); - - /// Returns an enumeration of all the terms in the index. The enumeration is ordered by - /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. - /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting + + /// Returns an enumeration of all the terms in the index. The enumeration is ordered by + /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. + /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting /// enumeration before calling other methods such as {@link TermEnum#term()}. virtual TermEnumPtr terms() = 0; - - /// Returns an enumeration of all terms starting at a given term. If the given term does not - /// exist, the enumeration is positioned at the first term greater than the supplied term. - /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede + + /// Returns an enumeration of all terms starting at a given term. If the given term does not + /// exist, the enumeration is positioned at the first term greater than the supplied term. + /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede /// it in the enumeration. virtual TermEnumPtr terms(TermPtr t) = 0; - + /// Returns the number of documents containing the term t. virtual int32_t docFreq(TermPtr t) = 0; - - /// Returns an enumeration of all the documents which contain term. For each document, the + + /// Returns an enumeration of all the documents which contain term. For each document, the /// document number, the frequency of the term in that document is also provided, for use in /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. - /// The enumeration is ordered by document number. Each document number is greater than all + /// The enumeration is ordered by document number. Each document number is greater than all /// that precede it in the enumeration. virtual TermDocsPtr termDocs(TermPtr term); - + /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs() = 0; - - /// Returns an enumeration of all the documents which contain term. For each document, in - /// addition to the document number and frequency of the term in that document, a list of all + + /// Returns an enumeration of all the documents which contain term. For each document, in + /// addition to the document number and frequency of the term in that document, a list of all /// of the ordinal positions of the term in the document is available. Thus, this method - /// positions of the term in the document is available. + /// positions of the term in the document is available. /// This positional information facilitates phrase and proximity searching. - /// The enumeration is ordered by document number. Each document number is greater than all + /// The enumeration is ordered by document number. Each document number is greater than all /// that precede it in the enumeration. virtual TermPositionsPtr termPositions(TermPtr term); - + /// Returns an unpositioned {@link TermPositions} enumerator. virtual TermPositionsPtr termPositions() = 0; - - /// Deletes the document numbered docNum. Once a document is deleted it will not appear in - /// TermDocs or TermPostitions enumerations. Attempts to read its field with the {@link + + /// Deletes the document numbered docNum. Once a document is deleted it will not appear in + /// TermDocs or TermPostitions enumerations. Attempts to read its field with the {@link /// #document} method will result in an error. The presence of this document may still be - /// reflected in the {@link #docFreq} statistic, though this will be corrected eventually as + /// reflected in the {@link #docFreq} statistic, though this will be corrected eventually as /// the index is further modified. virtual void deleteDocument(int32_t docNum); - - /// Deletes all documents that have a given term indexed. This is useful if one uses a - /// document field to hold a unique ID string for the document. Then to delete such a - /// document, one merely constructs a term with the appropriate field and the unique ID string - /// as its text and passes it to this method. See {@link #deleteDocument(int)} for information + + /// Deletes all documents that have a given term indexed. This is useful if one uses a + /// document field to hold a unique ID string for the document. Then to delete such a + /// document, one merely constructs a term with the appropriate field and the unique ID string + /// as its text and passes it to this method. See {@link #deleteDocument(int)} for information /// about when this deletion will become effective. /// @return the number of documents deleted virtual int32_t deleteDocuments(TermPtr term); - + /// Undeletes all documents currently marked as deleted in this index. virtual void undeleteAll(); - + void flush(); - - /// @param commitUserData Opaque Map (String -> String) that's recorded into the segments file + + /// @param commitUserData Opaque Map (String -> String) that's recorded into the segments file /// in the index, and retrievable by {@link IndexReader#getCommitUserData}. void flush(MapStringString commitUserData); - + /// Commit changes resulting from delete, undeleteAll, or setNorm operations. - /// If an exception is hit, then either no changes or all changes will have been committed to + /// If an exception is hit, then either no changes or all changes will have been committed to /// the index (transactional semantics). void commit(MapStringString commitUserData); - + /// Closes files associated with this index. Also saves any new deletions to disk. /// No other methods should be called after this has been called. void close(); - + /// Get a list of unique field names that exist in this index and have the specified field option information. /// @param fieldOption specifies which field option should be available for the returned fields /// @return Collection of Strings indicating the names of the fields. virtual HashSet getFieldNames(FieldOption fieldOption) = 0; - + /// Return the IndexCommit that this reader has opened. This method is only implemented by those /// readers that correspond to a Directory with its own segments_N file. virtual IndexCommitPtr getIndexCommit(); - - /// Prints the filename and size of each file within a given compound file. Add the -extract flag - /// to extract files to the current working directory. In order to make the extracted version of - /// the index work, you have to copy the segments file from the compound index into the directory + + /// Prints the filename and size of each file within a given compound file. Add the -extract flag + /// to extract files to the current working directory. In order to make the extracted version of + /// the index work, you have to copy the segments file from the compound index into the directory /// where the extracted files are stored. /// @param args Usage: IndexReader [-extract] static void main(Collection args); - + /// Returns all commit points that exist in the Directory. Normally, because the default is {@link - /// KeepOnlyLastCommitDeletionPolicy}, there would be only one commit point. But if you're using a - /// custom {@link IndexDeletionPolicy} then there could be many commits. Once you have a given + /// KeepOnlyLastCommitDeletionPolicy}, there would be only one commit point. But if you're using a + /// custom {@link IndexDeletionPolicy} then there could be many commits. Once you have a given /// commit, you can open a reader on it by calling {@link IndexReader#open(IndexCommit,bool)}. - /// There must be at least one commit in the Directory, else this method throws an exception. - /// Note that if a commit is in progress while this method is running, that commit may or may not + /// There must be at least one commit in the Directory, else this method throws an exception. + /// Note that if a commit is in progress while this method is running, that commit may or may not /// be returned array. static Collection listCommits(DirectoryPtr dir); - + /// Returns the sequential sub readers that this reader is logically composed of. For example, - /// IndexSearcher uses this API to drive searching by one sub reader at a time. If this reader is - /// not composed of sequential child readers, it should return null. If this method returns an empty + /// IndexSearcher uses this API to drive searching by one sub reader at a time. If this reader is + /// not composed of sequential child readers, it should return null. If this method returns an empty /// array, that means this reader is a null reader (for example a MultiReader that has no sub readers). /// - /// NOTE: You should not try using sub-readers returned by this method to make any changes (setNorm, - /// deleteDocument, etc.). While this might succeed for one composite reader (like MultiReader), it + /// NOTE: You should not try using sub-readers returned by this method to make any changes (setNorm, + /// deleteDocument, etc.). While this might succeed for one composite reader (like MultiReader), it /// will most likely lead to index corruption for other readers (like DirectoryReader obtained /// through {@link #open}. Use the parent reader directly. virtual Collection getSequentialSubReaders(); - + virtual LuceneObjectPtr getFieldCacheKey(); - + /// This returns null if the reader has no deletions. virtual LuceneObjectPtr getDeletesCacheKey(); - + /// Returns the number of unique terms (across all fields) in this reader. /// - /// This method returns int64_t, even though internally Lucene cannot handle more than 2^31 unique + /// This method returns int64_t, even though internally Lucene cannot handle more than 2^31 unique /// terms, for a possible future when this limitation is removed. virtual int64_t getUniqueTermCount(); - - /// For IndexReader implementations that use TermInfosReader to read terms, this returns the current + + /// For IndexReader implementations that use TermInfosReader to read terms, this returns the current /// indexDivisor as specified when the reader was opened. virtual int32_t getTermInfosIndexDivisor(); - + protected: void ensureOpen(); - + static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor); - + /// Implements setNorm in subclass. virtual void doSetNorm(int32_t doc, const String& field, uint8_t value) = 0; - + /// Implements deletion of the document numbered docNum. /// Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}. virtual void doDelete(int32_t docNum) = 0; - + /// Implements actual undeleteAll() in subclass. virtual void doUndeleteAll() = 0; - - /// Does nothing by default. Subclasses that require a write lock for index modifications must + + /// Does nothing by default. Subclasses that require a write lock for index modifications must /// implement this method. virtual void acquireWriteLock(); - + /// Commit changes resulting from delete, undeleteAll, or setNorm operations. - /// If an exception is hit, then either no changes or all changes will have been committed to + /// If an exception is hit, then either no changes or all changes will have been committed to /// the index (transactional semantics). void commit(); - + /// Implements commit. virtual void doCommit(MapStringString commitUserData) = 0; - + /// Implements close. virtual void doClose() = 0; - + friend class DirectoryReader; friend class ParallelReader; }; diff --git a/include/IndexSearcher.h b/include/IndexSearcher.h index 7282d45c..e5731db6 100644 --- a/include/IndexSearcher.h +++ b/include/IndexSearcher.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,85 +13,85 @@ namespace Lucene { /// Implements search over a single IndexReader. /// - /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link - /// #search(QueryPtr, FilterPtr, int32_t)} methods. For performance reasons it is recommended to open only + /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link + /// #search(QueryPtr, FilterPtr, int32_t)} methods. For performance reasons it is recommended to open only /// one IndexSearcher and use it for all of your searches. /// - /// NOTE: {@link IndexSearcher} instances are completely thread safe, meaning multiple threads can call any + /// NOTE: {@link IndexSearcher} instances are completely thread safe, meaning multiple threads can call any /// of its methods, concurrently. If your application requires external synchronization, you should not /// synchronize on the IndexSearcher instance; use your own (non-Lucene) objects instead. class LPPAPI IndexSearcher : public Searcher { public: - /// Creates a searcher searching the index in the named directory. You should pass readOnly = true, - /// since it gives much better concurrent performance, unless you intend to do write operations (delete + /// Creates a searcher searching the index in the named directory. You should pass readOnly = true, + /// since it gives much better concurrent performance, unless you intend to do write operations (delete /// documents or change norms) with the underlying IndexReader. /// @param path Directory where IndexReader will be opened /// @param readOnly If true, the underlying IndexReader will be opened readOnly IndexSearcher(DirectoryPtr path, bool readOnly = true); - + /// Creates a searcher searching the provided index. IndexSearcher(IndexReaderPtr reader); - + /// Directly specify the reader, subReaders and their docID starts. IndexSearcher(IndexReaderPtr reader, Collection subReaders, Collection docStarts); - + virtual ~IndexSearcher(); - + LUCENE_CLASS(IndexSearcher); - + public: IndexReaderPtr reader; - + protected: bool closeReader; - + Collection subReaders; Collection docStarts; - + bool fieldSortDoTrackScores; bool fieldSortDoMaxScore; - + public: /// Return the {@link IndexReader} this searches. IndexReaderPtr getIndexReader(); - - /// Note that the underlying IndexReader is not closed, if IndexSearcher was constructed with - /// IndexSearcher(IndexReaderPtr reader). If the IndexReader was supplied implicitly by specifying a + + /// Note that the underlying IndexReader is not closed, if IndexSearcher was constructed with + /// IndexSearcher(IndexReaderPtr reader). If the IndexReader was supplied implicitly by specifying a /// directory, then the IndexReader gets closed. virtual void close(); - + virtual int32_t docFreq(TermPtr term); virtual DocumentPtr doc(int32_t n); virtual DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector); virtual int32_t maxDoc(); - + using Searcher::search; using Searcher::explain; - + virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n); virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort); - - /// Just like {@link #search(WeightPtr, FilterPtr, int32_t, SortPtr)}, but you choose whether or not the + + /// Just like {@link #search(WeightPtr, FilterPtr, int32_t, SortPtr)}, but you choose whether or not the /// fields in the returned {@link FieldDoc} instances should be set by specifying fillFields. /// /// NOTE: this does not compute scores by default. If you need scores, create a {@link TopFieldCollector} /// instance by calling {@link TopFieldCollector#create} and then pass that to {@link #search(WeightPtr, /// FilterPtr, CollectorPtr)}. virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort, bool fillFields); - + virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr results); virtual QueryPtr rewrite(QueryPtr query); virtual ExplanationPtr explain(WeightPtr weight, int32_t doc); - + /// By default, no scores are computed when sorting by field (using {@link #search(QueryPtr, FilterPtr, - /// int32_t, SortPtr)}). You can change that, per IndexSearcher instance, by calling this method. Note + /// int32_t, SortPtr)}). You can change that, per IndexSearcher instance, by calling this method. Note /// that this will incur a CPU cost. /// /// @param doTrackScores If true, then scores are returned for every matching document in {@link TopFieldDocs}. /// @param doMaxScore If true, then the max score for all matching docs is computed. virtual void setDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore); - + protected: void ConstructSearcher(IndexReaderPtr reader, bool closeReader); void gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader); diff --git a/include/IndexWriter.h b/include/IndexWriter.h index cd820abc..bdb9df59 100644 --- a/include/IndexWriter.h +++ b/include/IndexWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,84 +14,84 @@ namespace Lucene /// An IndexWriter creates and maintains an index. /// /// The create argument to the {@link #IndexWriter(DirectoryPtr, AnalyzerPtr, bool, int32_t) constructor} - /// determines whether a new index is created, or whether an existing index is opened. Note that you can + /// determines whether a new index is created, or whether an existing index is opened. Note that you can /// open an index with create=true even while readers are using the index. The old readers will continue - /// to search the "point in time" snapshot they had opened, and won't see the newly created index until + /// to search the "point in time" snapshot they had opened, and won't see the newly created index until /// they re-open. There are also {@link #IndexWriter(DirectoryPtr, AnalyzerPtr, int32_t) constructors} - /// with no create argument which will create a new index if there is not already an index at the provided + /// with no create argument which will create a new index if there is not already an index at the provided /// path and otherwise open the existing index. /// - /// In either case, documents are added with {@link #addDocument(DocumentPtr) addDocument} and removed - /// with {@link #deleteDocuments(TermPtr)} or {@link #deleteDocuments(QueryPtr)}. A document can be updated - /// with {@link #updateDocument(TermPtr, DocumentPtr) updateDocument} (which just deletes and then adds + /// In either case, documents are added with {@link #addDocument(DocumentPtr) addDocument} and removed + /// with {@link #deleteDocuments(TermPtr)} or {@link #deleteDocuments(QueryPtr)}. A document can be updated + /// with {@link #updateDocument(TermPtr, DocumentPtr) updateDocument} (which just deletes and then adds /// the entire document). When finished adding, deleting and updating documents, {@link #close() close} /// should be called. /// - /// These changes are buffered in memory and periodically flushed to the {@link Directory} (during the - /// above method calls). A flush is triggered when there are enough buffered deletes (see - /// {@link #setMaxBufferedDeleteTerms}) or enough added documents since the last flush, whichever is - /// sooner. For the added documents, flushing is triggered either by RAM usage of the documents (see - /// {@link #setRAMBufferSizeMB}) or the number of added documents. The default is to flush when RAM usage - /// hits 16 MB. For best indexing speed you should flush by RAM usage with a large RAM buffer. Note that - /// flushing just moves the internal buffered state in IndexWriter into the index, but these changes are + /// These changes are buffered in memory and periodically flushed to the {@link Directory} (during the + /// above method calls). A flush is triggered when there are enough buffered deletes (see + /// {@link #setMaxBufferedDeleteTerms}) or enough added documents since the last flush, whichever is + /// sooner. For the added documents, flushing is triggered either by RAM usage of the documents (see + /// {@link #setRAMBufferSizeMB}) or the number of added documents. The default is to flush when RAM usage + /// hits 16 MB. For best indexing speed you should flush by RAM usage with a large RAM buffer. Note that + /// flushing just moves the internal buffered state in IndexWriter into the index, but these changes are /// not visible to IndexReader until either {@link #commit()} or {@link #close} is called. A flush may - /// also trigger one or more segment merges which by default run with a background thread so as not to + /// also trigger one or more segment merges which by default run with a background thread so as not to /// block the addDocument calls (see mergePolicy below for changing the {@link MergeScheduler}). /// - /// If an index will not have more documents added for a while and optimal search performance is desired, - /// then either the full {@link #optimize() optimize} method or partial {@link #optimize(int32_t)} method + /// If an index will not have more documents added for a while and optimal search performance is desired, + /// then either the full {@link #optimize() optimize} method or partial {@link #optimize(int32_t)} method /// should be called before the index is closed. /// /// Opening an IndexWriter creates a lock file for the directory in use. Trying to open another IndexWriter /// on the same directory will lead to a LockObtainFailed exception. The LockObtainFailed exception is also /// thrown if an IndexReader on the same directory is used to delete documents from the index. /// - /// IndexWriter allows an optional {@link IndexDeletionPolicy} implementation to be specified. You can use - /// this to control when prior commits are deleted from the index. The default policy is {@link - /// KeepOnlyLastCommitDeletionPolicy} which removes all prior commits as soon as a new commit is done (this - /// matches behavior before 2.2). Creating your own policy can allow you to explicitly keep previous - /// "point in time" commits alive in the index for some time, to allow readers to refresh to the new commit - /// without having the old commit deleted out from under them. This is necessary on file systems like NFS - /// that do not support "delete on last close" semantics, which Lucene's "point in time" search normally + /// IndexWriter allows an optional {@link IndexDeletionPolicy} implementation to be specified. You can use + /// this to control when prior commits are deleted from the index. The default policy is {@link + /// KeepOnlyLastCommitDeletionPolicy} which removes all prior commits as soon as a new commit is done (this + /// matches behavior before 2.2). Creating your own policy can allow you to explicitly keep previous + /// "point in time" commits alive in the index for some time, to allow readers to refresh to the new commit + /// without having the old commit deleted out from under them. This is necessary on file systems like NFS + /// that do not support "delete on last close" semantics, which Lucene's "point in time" search normally /// relies on. /// /// IndexWriter allows you to separately change the {@link MergePolicy} and the {@link MergeScheduler}. - /// The {@link MergePolicy} is invoked whenever there are changes to the segments in the index. Its role - /// is to select which merges to do, if any, and return a {@link MergePolicy.MergeSpecification} describing - /// the merges. It also selects merges to do for optimize(). (The default is {@link LogByteSizeMergePolicy}. - /// Then, the {@link MergeScheduler} is invoked with the requested merges and it decides when and how to run + /// The {@link MergePolicy} is invoked whenever there are changes to the segments in the index. Its role + /// is to select which merges to do, if any, and return a {@link MergePolicy.MergeSpecification} describing + /// the merges. It also selects merges to do for optimize(). (The default is {@link LogByteSizeMergePolicy}. + /// Then, the {@link MergeScheduler} is invoked with the requested merges and it decides when and how to run /// the merges. The default is {@link ConcurrentMergeScheduler}. /// - /// NOTE: if you hit an std::bad_alloc then IndexWriter will quietly record this fact and block all future - /// segment commits. This is a defensive measure in case any internal state (buffered documents and - /// deletions) were corrupted. Any subsequent calls to {@link #commit()} will throw an IllegalState + /// NOTE: if you hit an std::bad_alloc then IndexWriter will quietly record this fact and block all future + /// segment commits. This is a defensive measure in case any internal state (buffered documents and + /// deletions) were corrupted. Any subsequent calls to {@link #commit()} will throw an IllegalState /// exception. The only course of action is to call {@link #close()}, which internally will call {@link - /// #rollback()}, to undo any changes to the index since the last commit. You can also just call {@link + /// #rollback()}, to undo any changes to the index since the last commit. You can also just call {@link /// #rollback()} directly. /// - /// NOTE: {@link IndexWriter} instances are completely thread safe, meaning multiple threads can call any of - /// its methods, concurrently. If your application requires external synchronization, you should not + /// NOTE: {@link IndexWriter} instances are completely thread safe, meaning multiple threads can call any of + /// its methods, concurrently. If your application requires external synchronization, you should not /// synchronize on the IndexWriter instance as this may cause deadlock; use your own (non-Lucene) objects /// instead. /// /// Clarification: Check Points (and commits) - /// IndexWriter writes new index files to the directory without writing a new segments_N file which - /// references these new files. It also means that the state of the in memory SegmentInfos object is different + /// IndexWriter writes new index files to the directory without writing a new segments_N file which + /// references these new files. It also means that the state of the in memory SegmentInfos object is different /// than the most recent segments_N file written to the directory. /// - /// Each time the SegmentInfos is changed, and matches the (possibly modified) directory files, we have a new + /// Each time the SegmentInfos is changed, and matches the (possibly modified) directory files, we have a new /// "check point". If the modified/new SegmentInfos is written to disk - as a new (generation of) segments_N /// file - this check point is also an IndexCommit. /// - /// A new checkpoint always replaces the previous checkpoint and becomes the new "front" of the index. This - /// allows the IndexFileDeleter to delete files that are referenced only by stale checkpoints (files that were - /// created since the last commit, but are no longer referenced by the "front" of the index). For this, + /// A new checkpoint always replaces the previous checkpoint and becomes the new "front" of the index. This + /// allows the IndexFileDeleter to delete files that are referenced only by stale checkpoints (files that were + /// created since the last commit, but are no longer referenced by the "front" of the index). For this, /// IndexFileDeleter keeps track of the last non commit checkpoint. class LPPAPI IndexWriter : public LuceneObject { protected: IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexingChainPtr indexingChain, IndexCommitPtr commit); - + public: IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl); IndexWriter(DirectoryPtr d, AnalyzerPtr a, int32_t mfl); @@ -99,56 +99,56 @@ namespace Lucene IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl); IndexWriter(DirectoryPtr d, AnalyzerPtr a, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexCommitPtr commit); virtual ~IndexWriter(); - + LUCENE_CLASS(IndexWriter); - + protected: int64_t writeLockTimeout; - - /// The normal read buffer size defaults to 1024, but increasing this during merging seems to - /// yield performance gains. However we don't want to increase it too much because there are + + /// The normal read buffer size defaults to 1024, but increasing this during merging seems to + /// yield performance gains. However we don't want to increase it too much because there are /// quite a few BufferedIndexInputs created during merging. static const int32_t MERGE_READ_BUFFER_SIZE; - + SynchronizePtr messageIDLock; static int32_t MESSAGE_ID; int32_t messageID; bool hitOOM; - + DirectoryPtr directory; // where this index resides AnalyzerPtr analyzer; // how to analyze text - + bool create; IndexDeletionPolicyPtr deletionPolicy; IndexingChainPtr indexingChain; IndexCommitPtr indexCommit; - + SimilarityPtr similarity; // how to normalize - + int64_t changeCount; // increments every time a change is completed int64_t lastCommitChangeCount; // last changeCount that was committed - + SegmentInfosPtr rollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails MapSegmentInfoInt rollbackSegments; - + SegmentInfosPtr localRollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails int32_t localFlushedDocCount; - + SegmentInfosPtr segmentInfos; // the segments - + DocumentsWriterPtr docWriter; IndexFileDeleterPtr deleter; - + SetSegmentInfo segmentsToOptimize; // used by optimize to note those needing optimization int32_t optimizeMaxNumSegments; - + LockPtr writeLock; - + int32_t termIndexInterval; - + bool closed; bool closing; - + SetSegmentInfo mergingSegments; MergePolicyPtr mergePolicy; MergeSchedulerPtr mergeScheduler; @@ -157,47 +157,47 @@ namespace Lucene Collection mergeExceptions; int64_t mergeGen; bool stopMerges; - + int32_t flushCount; int32_t flushDeletesCount; - + /// Used to only allow one addIndexes to proceed at once int32_t readCount; // count of how many threads are holding read lock int64_t writeThread; // non-null if any thread holds write lock int32_t upgradeCount; - + int32_t readerTermsIndexDivisor; - - // This is a "write once" variable (like the organic dye on a DVD-R that may or may not - // be heated by a laser and then cooled to permanently record the event): it's false, - // until getReader() is called for the first time, at which point it's switched to true - // and never changes back to false. Once this is true, we hold open and reuse SegmentReader + + // This is a "write once" variable (like the organic dye on a DVD-R that may or may not + // be heated by a laser and then cooled to permanently record the event): it's false, + // until getReader() is called for the first time, at which point it's switched to true + // and never changes back to false. Once this is true, we hold open and reuse SegmentReader // instances internally for applying deletes, doing merges, and reopening near real-time readers. bool poolReaders; - - /// The maximum number of terms that will be indexed for a single field in a document. This - /// limits the amount of memory required for indexing, so that collections with very large files + + /// The maximum number of terms that will be indexed for a single field in a document. This + /// limits the amount of memory required for indexing, so that collections with very large files /// will not crash the indexing process by running out of memory. - /// Note that this effectively truncates large documents, excluding from the index terms that - /// occur further in the document. If you know your source documents are large, be sure to set - /// this value high enough to accommodate the expected size. If you set it to INT_MAX, then the - /// only limit is your memory, but you should anticipate an std::bad_alloc. By default, no more + /// Note that this effectively truncates large documents, excluding from the index terms that + /// occur further in the document. If you know your source documents are large, be sure to set + /// this value high enough to accommodate the expected size. If you set it to INT_MAX, then the + /// only limit is your memory, but you should anticipate an std::bad_alloc. By default, no more /// than 10,000 terms will be indexed for a field. /// /// @see #setMaxFieldLength(int32_t) int32_t maxFieldLength; - + InfoStreamPtr infoStream; static InfoStreamPtr defaultInfoStream; - + HashSet synced; // files that have been sync'd already HashSet syncing; // files that are now being sync'd - + IndexReaderWarmerPtr mergedSegmentWarmer; - + /// Used only by commit; lock order is commitLock -> IW SynchronizePtr commitLock; - + INTERNAL: SegmentInfosPtr pendingCommit; // set when a commit is pending (after prepareCommit() & before commit()) int64_t pendingCommitChangeCount; @@ -208,72 +208,72 @@ namespace Lucene /// Default value for the write lock timeout (1,000). /// @see #setDefaultWriteLockTimeout static int64_t WRITE_LOCK_TIMEOUT; - + static const String WRITE_LOCK_NAME; - + /// Value to denote a flush trigger is disabled. static const int32_t DISABLE_AUTO_FLUSH; - - /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using + + /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using /// {@link #setMaxBufferedDocs(int32_t)}. static const int32_t DEFAULT_MAX_BUFFERED_DOCS; - - /// Default value is 16 MB (which means flush when buffered docs consume 16 MB RAM). + + /// Default value is 16 MB (which means flush when buffered docs consume 16 MB RAM). /// Change using {@link #setRAMBufferSizeMB}. static const double DEFAULT_RAM_BUFFER_SIZE_MB; - - /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using + + /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using /// {@link #setMaxBufferedDeleteTerms(int32_t)}. static const int32_t DEFAULT_MAX_BUFFERED_DELETE_TERMS; - + /// Default value is 10,000. Change using {@link #setMaxFieldLength(int32_t)}. static const int32_t DEFAULT_MAX_FIELD_LENGTH; - + /// Default value is 128. Change using {@link #setTermIndexInterval(int32_t)}. static const int32_t DEFAULT_TERM_INDEX_INTERVAL; - - /// Absolute hard maximum length for a term. If a term arrives from the analyzer longer than - /// this length, it is skipped and a message is printed to infoStream, if set (see {@link + + /// Absolute hard maximum length for a term. If a term arrives from the analyzer longer than + /// this length, it is skipped and a message is printed to infoStream, if set (see {@link /// #setInfoStream}). static int32_t MAX_TERM_LENGTH(); - + /// Sets the maximum field length to INT_MAX static const int32_t MaxFieldLengthUNLIMITED; - + /// Sets the maximum field length to {@link #DEFAULT_MAX_FIELD_LENGTH} static const int32_t MaxFieldLengthLIMITED; - + public: virtual void initialize(); - - /// Returns a read-only reader, covering all committed as well as un-committed changes to the - /// index. This provides "near real-time" searching, in that changes made during an IndexWriter - /// session can be quickly made available for searching without closing the writer nor calling + + /// Returns a read-only reader, covering all committed as well as un-committed changes to the + /// index. This provides "near real-time" searching, in that changes made during an IndexWriter + /// session can be quickly made available for searching without closing the writer nor calling /// {@link #commit}. /// - /// Note that this is functionally equivalent to calling {#commit} and then using {@link - /// IndexReader#open} to open a new reader. But the turnaround time of this method should be + /// Note that this is functionally equivalent to calling {#commit} and then using {@link + /// IndexReader#open} to open a new reader. But the turnaround time of this method should be /// faster since it avoids the potentially costly {@link #commit}. /// /// You must close the {@link IndexReader} returned by this method once you are done using it. /// - /// It's near real-time because there is no hard guarantee on how quickly you can get a new - /// reader after making changes with IndexWriter. You'll have to experiment in your situation - /// to determine if it's fast enough. As this is a new and experimental feature, please report + /// It's near real-time because there is no hard guarantee on how quickly you can get a new + /// reader after making changes with IndexWriter. You'll have to experiment in your situation + /// to determine if it's fast enough. As this is a new and experimental feature, please report /// back on your findings so we can learn, improve and iterate. /// /// The resulting reader supports {@link IndexReader#reopen}, but that call will simply forward /// back to this method (though this may change in the future). /// - /// The very first time this method is called, this writer instance will make every effort to - /// pool the readers that it opens for doing merges, applying deletes, etc. This means additional + /// The very first time this method is called, this writer instance will make every effort to + /// pool the readers that it opens for doing merges, applying deletes, etc. This means additional /// resources (RAM, file descriptors, CPU time) will be consumed. /// /// For lower latency on reopening a reader, you should call {@link #setMergedSegmentWarmer} to - /// pre-warm a newly merged segment before it's committed to the index. This is important for + /// pre-warm a newly merged segment before it's committed to the index. This is important for /// minimizing index-to-search delay after a large merge. /// - /// If an addIndexes* call is running in another thread, then this reader will only search those + /// If an addIndexes* call is running in another thread, then this reader will only search those /// segments from the foreign index that have been successfully copied over, so far. /// /// NOTE: Once the writer is closed, any outstanding readers may continue to be used. However, @@ -281,320 +281,320 @@ namespace Lucene /// /// NOTE: This API is experimental and might change in incompatible ways in the next release. /// - /// @return IndexReader that covers entire index plus all changes made so far by this IndexWriter + /// @return IndexReader that covers entire index plus all changes made so far by this IndexWriter /// instance virtual IndexReaderPtr getReader(); - + /// Like {@link #getReader}, except you can specify which termInfosIndexDivisor should be used for /// any newly opened readers. /// - /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the - /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at + /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the + /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at /// indexing time while this setting can be set per reader. When set to N, then one in every - /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 - /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. + /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 + /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. /// The default value is 1. Set this to -1 to skip loading the terms index entirely. virtual IndexReaderPtr getReader(int32_t termInfosIndexDivisor); - - /// Obtain the number of deleted docs for a pooled reader. If the reader isn't being pooled, + + /// Obtain the number of deleted docs for a pooled reader. If the reader isn't being pooled, /// the segmentInfo's delCount is returned. virtual int32_t numDeletedDocs(SegmentInfoPtr info); - + virtual void acquireWrite(); virtual void releaseWrite(); virtual void acquireRead(); - - /// Allows one readLock to upgrade to a writeLock even if there are other readLocks as long + + /// Allows one readLock to upgrade to a writeLock even if there are other readLocks as long /// as all other readLocks are also blocked in this method virtual void upgradeReadToWrite(); - + virtual void releaseRead(); virtual bool isOpen(bool includePendingClose); virtual void message(const String& message); - + /// Get the current setting of whether newly flushed segments will use the compound file format. - /// Note that this just returns the value previously set with setUseCompoundFile(bool), or the + /// Note that this just returns the value previously set with setUseCompoundFile(bool), or the /// default value (true). You cannot use this to query the status of previously flushed segments. /// - /// Note that this method is a convenience method: it just calls mergePolicy.getUseCompoundFile + /// Note that this method is a convenience method: it just calls mergePolicy.getUseCompoundFile /// as long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument /// exception is thrown. /// @see #setUseCompoundFile(bool) virtual bool getUseCompoundFile(); - - /// Setting to turn on usage of a compound file. When on, multiple files for each segment are + + /// Setting to turn on usage of a compound file. When on, multiple files for each segment are /// merged into a single file when a new segment is flushed. /// - /// Note that this method is a convenience method: it just calls mergePolicy.setUseCompoundFile + /// Note that this method is a convenience method: it just calls mergePolicy.setUseCompoundFile /// as long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument /// exception is thrown. virtual void setUseCompoundFile(bool value); - - /// Set the Similarity implementation used by this IndexWriter. + + /// Set the Similarity implementation used by this IndexWriter. virtual void setSimilarity(SimilarityPtr similarity); - + /// Return the Similarity implementation used by this IndexWriter. /// This defaults to the current value of {@link Similarity#getDefault()}. virtual SimilarityPtr getSimilarity(); - - /// Set the interval between indexed terms. Large values cause less memory to be used by - /// IndexReader, but slow random-access to terms. Small values cause more memory to be used by + + /// Set the interval between indexed terms. Large values cause less memory to be used by + /// IndexReader, but slow random-access to terms. Small values cause more memory to be used by /// an IndexReader, and speed random-access to terms. /// - /// This parameter determines the amount of computation required per query term, regardless of - /// the number of documents that contain that term. In particular, it is the maximum number of - /// other terms that must be scanned before a term is located and its frequency and position - /// information may be processed. In a large index with user-entered query terms, query - /// processing time is likely to be dominated not by term lookup but rather by the processing of - /// frequency and positional data. In a small index or when many uncommon query terms are + /// This parameter determines the amount of computation required per query term, regardless of + /// the number of documents that contain that term. In particular, it is the maximum number of + /// other terms that must be scanned before a term is located and its frequency and position + /// information may be processed. In a large index with user-entered query terms, query + /// processing time is likely to be dominated not by term lookup but rather by the processing of + /// frequency and positional data. In a small index or when many uncommon query terms are /// generated (eg., by wildcard queries) term lookup may become a dominant cost. /// - /// In particular, numUniqueTerms/interval terms are read into memory by an IndexReader, and on + /// In particular, numUniqueTerms/interval terms are read into memory by an IndexReader, and on /// average, interval/2 terms must be scanned for each random term access. /// /// @see #DEFAULT_TERM_INDEX_INTERVAL virtual void setTermIndexInterval(int32_t interval); - + /// Return the interval between indexed terms. /// @see #setTermIndexInterval(int32_t) virtual int32_t getTermIndexInterval(); - + /// Set the merge policy used by this writer. virtual void setMergePolicy(MergePolicyPtr mp); - + /// Returns the current MergePolicy in use by this writer. /// @see #setMergePolicy virtual MergePolicyPtr getMergePolicy(); - + /// Set the merge scheduler used by this writer. virtual void setMergeScheduler(MergeSchedulerPtr mergeScheduler); - + /// Returns the current MergePolicy in use by this writer. /// @see #setMergePolicy virtual MergeSchedulerPtr getMergeScheduler(); - - /// Determines the largest segment (measured by document count) that may be merged with other - /// segments. Small values (eg., less than 10,000) are best for interactive indexing, as this - /// limits the length of pauses while indexing to a few seconds. Larger values are best for + + /// Determines the largest segment (measured by document count) that may be merged with other + /// segments. Small values (eg., less than 10,000) are best for interactive indexing, as this + /// limits the length of pauses while indexing to a few seconds. Larger values are best for /// batched indexing and speedier searches. /// /// The default value is INT_MAX. /// - /// Note that this method is a convenience method: it just calls mergePolicy.setMaxMergeDocs as + /// Note that this method is a convenience method: it just calls mergePolicy.setMaxMergeDocs as /// long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument /// exception is thrown. /// - /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit + /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit /// by net size (in MB) of the segment, using {@link LogByteSizeMergePolicy#setMaxMergeMB}. virtual void setMaxMergeDocs(int32_t maxMergeDocs); - - /// Returns the largest segment (measured by document count) that may be merged with other - /// segments. + + /// Returns the largest segment (measured by document count) that may be merged with other + /// segments. /// - /// Note that this method is a convenience method: it just calls mergePolicy.getMaxMergeDocs as + /// Note that this method is a convenience method: it just calls mergePolicy.getMaxMergeDocs as /// long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument /// exception is thrown. /// /// @see #setMaxMergeDocs virtual int32_t getMaxMergeDocs(); - - /// The maximum number of terms that will be indexed for a single field in a document. This - /// limits the amount of memory required for indexing, so that collections with very large files - /// will not crash the indexing process by running out of memory. This setting refers to the + + /// The maximum number of terms that will be indexed for a single field in a document. This + /// limits the amount of memory required for indexing, so that collections with very large files + /// will not crash the indexing process by running out of memory. This setting refers to the /// number of running terms, not to the number of different terms. - /// Note: this silently truncates large documents, excluding from the index all terms that occur - /// further in the document. If you know your source documents are large, be sure to set this - /// value high enough to accommodate the expected size. If you set it to INT_MAX, then the only + /// Note: this silently truncates large documents, excluding from the index all terms that occur + /// further in the document. If you know your source documents are large, be sure to set this + /// value high enough to accommodate the expected size. If you set it to INT_MAX, then the only /// limit is your memory, but you should anticipate an std::bad_alloc. /// By default, no more than {@link #DEFAULT_MAX_FIELD_LENGTH} terms will be indexed for a field. virtual void setMaxFieldLength(int32_t maxFieldLength); - + /// Returns the maximum number of terms that will be indexed for a single field in a document. /// @see #setMaxFieldLength virtual int32_t getMaxFieldLength(); - - /// Sets the termsIndexDivisor passed to any readers that IndexWriter opens, for example when - /// applying deletes or creating a near-real-time reader in {@link IndexWriter#getReader}. + + /// Sets the termsIndexDivisor passed to any readers that IndexWriter opens, for example when + /// applying deletes or creating a near-real-time reader in {@link IndexWriter#getReader}. /// Default value is {@link IndexReader#DEFAULT_TERMS_INDEX_DIVISOR}. virtual void setReaderTermsIndexDivisor(int32_t divisor); - + /// @see #setReaderTermsIndexDivisor() virtual int32_t getReaderTermsIndexDivisor(); - - /// Determines the minimal number of documents required before the buffered in-memory documents + + /// Determines the minimal number of documents required before the buffered in-memory documents /// are flushed as a new Segment. Large values generally gives faster indexing. /// - /// When this is set, the writer will flush every maxBufferedDocs added documents. Pass in - /// {@link #DISABLE_AUTO_FLUSH} to prevent triggering a flush due to number of buffered - /// documents. Note that if flushing by RAM usage is also enabled, then the flush will be + /// When this is set, the writer will flush every maxBufferedDocs added documents. Pass in + /// {@link #DISABLE_AUTO_FLUSH} to prevent triggering a flush due to number of buffered + /// documents. Note that if flushing by RAM usage is also enabled, then the flush will be /// triggered by whichever comes first. /// /// Disabled by default (writer flushes by RAM usage). /// /// @see #setRAMBufferSizeMB virtual void setMaxBufferedDocs(int32_t maxBufferedDocs); - + /// Returns the number of buffered added documents that will trigger a flush if enabled. /// @see #setMaxBufferedDocs virtual int32_t getMaxBufferedDocs(); - - /// Determines the amount of RAM that may be used for buffering added documents and deletions + + /// Determines the amount of RAM that may be used for buffering added documents and deletions /// before they are flushed to the Directory. Generally for faster indexing performance it's /// best to flush by RAM usage instead of document count and use as large a RAM buffer as you can. /// - /// When this is set, the writer will flush whenever buffered documents and deletions use this + /// When this is set, the writer will flush whenever buffered documents and deletions use this /// much RAM. Pass in {@link #DISABLE_AUTO_FLUSH} to prevent triggering a flush due to RAM usage. - /// Note that if flushing by document count is also enabled, then the flush will be triggered by + /// Note that if flushing by document count is also enabled, then the flush will be triggered by /// whichever comes first. /// - /// Note: the account of RAM usage for pending deletions is only approximate. Specifically, if - /// you delete by Query, Lucene currently has no way to measure the RAM usage if individual - /// Queries so the accounting will under-estimate and you should compensate by either calling - /// commit() periodically yourself, or by using {@link #setMaxBufferedDeleteTerms} to flush by + /// Note: the account of RAM usage for pending deletions is only approximate. Specifically, if + /// you delete by Query, Lucene currently has no way to measure the RAM usage if individual + /// Queries so the accounting will under-estimate and you should compensate by either calling + /// commit() periodically yourself, or by using {@link #setMaxBufferedDeleteTerms} to flush by /// count instead of RAM usage (each buffered delete Query counts as one). /// - /// Note: because IndexWriter uses int32_t when managing its internal storage, the absolute + /// Note: because IndexWriter uses int32_t when managing its internal storage, the absolute /// maximum value for this setting is somewhat less than 2048 MB. The precise limit depends on /// various factors, such as how large your documents are, how many fields have norms, etc., so /// it's best to set this value comfortably under 2048. /// /// The default value is {@link #DEFAULT_RAM_BUFFER_SIZE_MB}. virtual void setRAMBufferSizeMB(double mb); - + /// Returns the value set by {@link #setRAMBufferSizeMB} if enabled. virtual double getRAMBufferSizeMB(); - - /// Determines the minimal number of delete terms required before the buffered in-memory delete - /// terms are applied and flushed. If there are documents buffered in memory at the time, they + + /// Determines the minimal number of delete terms required before the buffered in-memory delete + /// terms are applied and flushed. If there are documents buffered in memory at the time, they /// are merged and a new segment is created. /// /// Disabled by default (writer flushes by RAM usage). - /// @see #setRAMBufferSizeMB + /// @see #setRAMBufferSizeMB virtual void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); - + /// Returns the number of buffered deleted terms that will trigger a flush if enabled. /// @see #setMaxBufferedDeleteTerms virtual int32_t getMaxBufferedDeleteTerms(); - - /// Determines how often segment indices are merged by addDocument(). With smaller values, less - /// RAM is used while indexing, and searches on unoptimized indices are faster, but indexing - /// speed is slower. With larger values, more RAM is used during indexing, and while searches + + /// Determines how often segment indices are merged by addDocument(). With smaller values, less + /// RAM is used while indexing, and searches on unoptimized indices are faster, but indexing + /// speed is slower. With larger values, more RAM is used during indexing, and while searches /// on unoptimized indices are slower, indexing is faster. Thus larger values (> 10) are best /// for batch index creation, and smaller values (< 10) for indices that are interactively maintained. /// - /// Note that this method is a convenience method: it just calls mergePolicy.setMergeFactor as long - /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception + /// Note that this method is a convenience method: it just calls mergePolicy.setMergeFactor as long + /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception /// is thrown. This must never be less than 2. The default value is 10. virtual void setMergeFactor(int32_t mergeFactor); - - /// Returns the number of segments that are merged at once and also controls the total number of + + /// Returns the number of segments that are merged at once and also controls the total number of /// segments allowed to accumulate in the index. /// - /// Note that this method is a convenience method: it just calls mergePolicy.getMergeFactor as long - /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception + /// Note that this method is a convenience method: it just calls mergePolicy.getMergeFactor as long + /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception /// is thrown. /// @see #setMergeFactor virtual int32_t getMergeFactor(); - + /// If non-null, this will be the default infoStream used by a newly instantiated IndexWriter. /// @see #setInfoStream static void setDefaultInfoStream(InfoStreamPtr infoStream); - + /// Returns the current default infoStream for newly instantiated IndexWriters. /// @see #setDefaultInfoStream static InfoStreamPtr getDefaultInfoStream(); - - /// If non-null, information about merges, deletes and a message when maxFieldLength is reached + + /// If non-null, information about merges, deletes and a message when maxFieldLength is reached /// will be printed to this. virtual void setInfoStream(InfoStreamPtr infoStream); - + /// Returns the current infoStream in use by this writer. /// @see #setInfoStream virtual InfoStreamPtr getInfoStream(); - + /// Returns true if verbosing is enabled (i.e., infoStream != null). virtual bool verbose(); - - /// Sets the maximum time to wait for a write lock (in milliseconds) for this instance of - /// IndexWriter. @see #setDefaultWriteLockTimeout to change the default value for all instances + + /// Sets the maximum time to wait for a write lock (in milliseconds) for this instance of + /// IndexWriter. @see #setDefaultWriteLockTimeout to change the default value for all instances /// of IndexWriter. virtual void setWriteLockTimeout(int64_t writeLockTimeout); - + /// Returns allowed timeout when acquiring the write lock. /// @see #setWriteLockTimeout virtual int64_t getWriteLockTimeout(); - - /// Sets the default (for any instance of IndexWriter) maximum time to wait for a write lock + + /// Sets the default (for any instance of IndexWriter) maximum time to wait for a write lock /// (in milliseconds). static void setDefaultWriteLockTimeout(int64_t writeLockTimeout); - + /// Returns default write lock timeout for newly instantiated IndexWriters. /// @see #setDefaultWriteLockTimeout static int64_t getDefaultWriteLockTimeout(); - - /// Commits all changes to an index and closes all associated files. Note that this may be - /// a costly operation, so try to re-use a single writer instead of closing and opening a + + /// Commits all changes to an index and closes all associated files. Note that this may be + /// a costly operation, so try to re-use a single writer instead of closing and opening a /// new one. See {@link #commit()} for caveats about write caching done by some IO devices. /// - /// If an Exception is hit during close, eg due to disk full or some other reason, then both + /// If an Exception is hit during close, eg due to disk full or some other reason, then both /// the on-disk index and the internal state of the IndexWriter instance will be consistent. /// However, the close will not be complete even though part of it (flushing buffered documents) /// may have succeeded, so the write lock will still be held. /// - /// If you can correct the underlying cause (eg free up some disk space) then you can call + /// If you can correct the underlying cause (eg free up some disk space) then you can call /// close() again. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer, again. virtual void close(); - - /// Closes the index with or without waiting for currently running merges to finish. This is + + /// Closes the index with or without waiting for currently running merges to finish. This is /// only meaningful when using a MergeScheduler that runs merges in background threads. - /// + /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer, again. /// /// NOTE: it is dangerous to always call close(false), especially when IndexWriter is not open - /// for very long, because this can result in "merge starvation" whereby long merges will never + /// for very long, because this can result in "merge starvation" whereby long merges will never /// have a chance to finish. This will cause too many segments in your index over time. /// - /// @param waitForMerges if true, this call will block until all merges complete; else, it will + /// @param waitForMerges if true, this call will block until all merges complete; else, it will /// ask all running merges to abort, wait until those merges have finished (which should be at /// most a few seconds), and then return. virtual void close(bool waitForMerges); - + /// Returns the Directory used by this index. virtual DirectoryPtr getDirectory(); - + /// Returns the analyzer used by this index. virtual AnalyzerPtr getAnalyzer(); - - /// Returns total number of docs in this index, including docs not yet flushed (still in the + + /// Returns total number of docs in this index, including docs not yet flushed (still in the /// RAM buffer), not counting deletions. /// @see #numDocs virtual int32_t maxDoc(); - - /// Returns total number of docs in this index, including docs not yet flushed (still in the + + /// Returns total number of docs in this index, including docs not yet flushed (still in the /// RAM buffer), and including deletions. - /// NOTE: buffered deletions are not counted. If you really need these to be counted you should + /// NOTE: buffered deletions are not counted. If you really need these to be counted you should /// call {@link #commit()} first. virtual int32_t numDocs(); - + virtual bool hasDeletions(); - - /// Adds a document to this index. If the document contains more than {@link + + /// Adds a document to this index. If the document contains more than {@link /// #setMaxFieldLength(int32_t)} terms for a given field, the remainder are discarded. - /// - /// Note that if an Exception is hit (for example disk full) then the index will be consistent, - /// but this document may not have been added. Furthermore, it's possible the index will have - /// one segment in non-compound format even when using compound files (when a merge has partially + /// + /// Note that if an Exception is hit (for example disk full) then the index will be consistent, + /// but this document may not have been added. Furthermore, it's possible the index will have + /// one segment in non-compound format even when using compound files (when a merge has partially /// succeeded). /// - /// This method periodically flushes pending documents to the Directory, and also periodically + /// This method periodically flushes pending documents to the Directory, and also periodically /// triggers segment merges in the index according to the {@link MergePolicy} in use. /// - /// Merges temporarily consume space in the directory. The amount of space required is up to 1X + /// Merges temporarily consume space in the directory. The amount of space required is up to 1X /// the size of all segments being merged, when no size of all segments being merged, when no - /// 2X the size of all segments being merged when readers/searchers are open against the index - /// (see {@link #optimize()} for details). The sequence of primitive merge operations performed + /// 2X the size of all segments being merged when readers/searchers are open against the index + /// (see {@link #optimize()} for details). The sequence of primitive merge operations performed /// is governed by the merge policy. /// /// Note that each term in the document can be no longer than 16383 characters, otherwise an @@ -602,12 +602,12 @@ namespace Lucene /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void addDocument(DocumentPtr doc); - - /// Adds a document to this index, using the provided analyzer instead of the value of {@link - /// #getAnalyzer()}. If the document contains more than {@link #setMaxFieldLength(int32_t)} terms + + /// Adds a document to this index, using the provided analyzer instead of the value of {@link + /// #getAnalyzer()}. If the document contains more than {@link #setMaxFieldLength(int32_t)} terms /// for a given field, the remainder are discarded. /// - /// See {@link #addDocument(DocumentPtr)} for details on index and IndexWriter state after an + /// See {@link #addDocument(DocumentPtr)} for details on index and IndexWriter state after an /// exception, and flushing/merging temporary free space requirements. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. @@ -619,31 +619,31 @@ namespace Lucene /// /// @param term the term to identify the documents to be deleted virtual void deleteDocuments(TermPtr term); - + /// Deletes the document(s) containing any of the terms. All deletes are flushed at the same time. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// /// @param terms array of terms to identify the documents to be deleted virtual void deleteDocuments(Collection terms); - + /// Deletes the document(s) matching the provided query. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// /// @param query the query to identify the documents to be deleted virtual void deleteDocuments(QueryPtr query); - - /// Deletes the document(s) matching any of the provided queries. All deletes are flushed at + + /// Deletes the document(s) matching any of the provided queries. All deletes are flushed at /// the same time. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// /// @param queries array of queries to identify the documents to be deleted virtual void deleteDocuments(Collection queries); - + /// Updates a document by first deleting the document(s) containing term and then adding the new - /// document. The delete and then add are atomic as seen by a reader on the same index (flush + /// document. The delete and then add are atomic as seen by a reader on the same index (flush /// may happen only after the add). /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. @@ -651,9 +651,9 @@ namespace Lucene /// @param term the term to identify the document(s) to be deleted /// @param doc the document to be added virtual void updateDocument(TermPtr term, DocumentPtr doc); - + /// Updates a document by first deleting the document(s) containing term and then adding the new - /// document. The delete and then add are atomic as seen by a reader on the same index (flush + /// document. The delete and then add are atomic as seen by a reader on the same index (flush /// may happen only after the add). /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. @@ -662,212 +662,212 @@ namespace Lucene /// @param doc the document to be added /// @param analyzer the analyzer to use when analyzing the document virtual void updateDocument(TermPtr term, DocumentPtr doc, AnalyzerPtr analyzer); - + virtual int32_t getSegmentCount(); virtual int32_t getNumBufferedDocuments(); virtual int32_t getDocCount(int32_t i); virtual int32_t getFlushCount(); virtual int32_t getFlushDeletesCount(); - + virtual String newSegmentName(); - - /// Requests an "optimize" operation on an index, priming the index for the fastest available - /// search. Traditionally this has meant merging all segments into a single segment as is done in + + /// Requests an "optimize" operation on an index, priming the index for the fastest available + /// search. Traditionally this has meant merging all segments into a single segment as is done in /// the default merge policy, but individual merge policies may implement optimize in different ways. /// - /// It is recommended that this method be called upon completion of indexing. In environments with - /// frequent updates, optimize is best done during low volume times, if at all. + /// It is recommended that this method be called upon completion of indexing. In environments with + /// frequent updates, optimize is best done during low volume times, if at all. /// - /// Note that optimize requires 2X the index size free space in your Directory (3X if you're using - /// compound file format). For example, if your index size is 10 MB then you need 20 MB free for + /// Note that optimize requires 2X the index size free space in your Directory (3X if you're using + /// compound file format). For example, if your index size is 10 MB then you need 20 MB free for /// optimize to complete (30 MB if you're using compound file format). /// /// If some but not all readers re-open while an optimize is underway, this will cause > 2X temporary - /// space to be consumed as those new readers will then hold open the partially optimized segments at + /// space to be consumed as those new readers will then hold open the partially optimized segments at /// that time. It is best not to re-open readers while optimize is running. /// /// The actual temporary usage could be much less than these figures (it depends on many factors). /// - /// In general, once the optimize completes, the total size of the index will be less than the size + /// In general, once the optimize completes, the total size of the index will be less than the size /// of the starting index. It could be quite a bit smaller (if there were many pending deletes) or /// just slightly smaller. /// - /// If an Exception is hit during optimize(), for example due to disk full, the index will not be - /// corrupt and no documents will have been lost. However, it may have been partially optimized - /// (some segments were merged but not all), and it's possible that one of the segments in the index + /// If an Exception is hit during optimize(), for example due to disk full, the index will not be + /// corrupt and no documents will have been lost. However, it may have been partially optimized + /// (some segments were merged but not all), and it's possible that one of the segments in the index /// will be in non-compound format even when using compound file format. This will occur when the /// exception is hit during conversion of the segment into compound format. /// - /// This call will optimize those segments present in the index when the call started. If other - /// threads are still adding documents and flushing segments, those newly created segments will not + /// This call will optimize those segments present in the index when the call started. If other + /// threads are still adding documents and flushing segments, those newly created segments will not /// be optimized unless you call optimize again. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// /// @see LogMergePolicy#findMergesForOptimize virtual void optimize(); - - /// Optimize the index down to <= maxNumSegments. If maxNumSegments==1 then this is the same as + + /// Optimize the index down to <= maxNumSegments. If maxNumSegments==1 then this is the same as /// {@link #optimize()}. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// /// @param maxNumSegments maximum number of segments left in the index after optimization finishes virtual void optimize(int32_t maxNumSegments); - - /// Just like {@link #optimize()}, except you can specify whether the call should block until the - /// optimize completes. This is only meaningful with a {@link MergeScheduler} that is able to run + + /// Just like {@link #optimize()}, except you can specify whether the call should block until the + /// optimize completes. This is only meaningful with a {@link MergeScheduler} that is able to run /// merges in background threads. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void optimize(bool doWait); - /// Just like {@link #optimize(int32_t)}, except you can specify whether the call should block - /// until the optimize completes. This is only meaningful with a {@link MergeScheduler} that is + /// Just like {@link #optimize(int32_t)}, except you can specify whether the call should block + /// until the optimize completes. This is only meaningful with a {@link MergeScheduler} that is /// able to run merges in background threads. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void optimize(int32_t maxNumSegments, bool doWait); - /// Just like {@link #expungeDeletes()}, except you can specify whether the call should block - /// until the operation completes. This is only meaningful with a {@link MergeScheduler} that + /// Just like {@link #expungeDeletes()}, except you can specify whether the call should block + /// until the operation completes. This is only meaningful with a {@link MergeScheduler} that /// is able to run merges in background threads. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void expungeDeletes(bool doWait); - - /// Expunges all deletes from the index. When an index has many document deletions (or updates - /// to existing documents), it's best to either call optimize or expungeDeletes to remove all + + /// Expunges all deletes from the index. When an index has many document deletions (or updates + /// to existing documents), it's best to either call optimize or expungeDeletes to remove all /// unused data in the index associated with the deleted documents. To see how many deletions - /// you have pending in your index, call {@link IndexReader#numDeletedDocs}. This saves disk - /// space and memory usage while searching. expungeDeletes should be somewhat faster than - /// optimize since it does not insist on reducing the index to a single segment (though, this - /// depends on the {@link MergePolicy}; see {@link MergePolicy#findMergesToExpungeDeletes}.). - /// Note that this call does not first commit any buffered documents, so you must do so yourself + /// you have pending in your index, call {@link IndexReader#numDeletedDocs}. This saves disk + /// space and memory usage while searching. expungeDeletes should be somewhat faster than + /// optimize since it does not insist on reducing the index to a single segment (though, this + /// depends on the {@link MergePolicy}; see {@link MergePolicy#findMergesToExpungeDeletes}.). + /// Note that this call does not first commit any buffered documents, so you must do so yourself /// if necessary. See also {@link #expungeDeletes(bool)} /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void expungeDeletes(); - - /// Asks the mergePolicy whether any merges are necessary now and if so, runs the requested + + /// Asks the mergePolicy whether any merges are necessary now and if so, runs the requested /// merges and then iterate (test again if merges are needed) until no more merges are returned /// by the mergePolicy. - /// - /// Explicit calls to maybeMerge() are usually not necessary. The most common case is when merge + /// + /// Explicit calls to maybeMerge() are usually not necessary. The most common case is when merge /// policy parameters have changed. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void maybeMerge(); - - /// The {@link MergeScheduler} calls this method to retrieve the next merge requested by the + + /// The {@link MergeScheduler} calls this method to retrieve the next merge requested by the /// MergePolicy. virtual OneMergePtr getNextMerge(); - + /// Close the IndexWriter without committing any changes that have occurred since the last commit - /// (or since it was opened, if commit hasn't been called). This removes any temporary files that - /// had been created, after which the state of the index will be the same as it was when commit() - /// was last called or when this writer was first opened. This also clears a previous call to + /// (or since it was opened, if commit hasn't been called). This removes any temporary files that + /// had been created, after which the state of the index will be the same as it was when commit() + /// was last called or when this writer was first opened. This also clears a previous call to /// {@link #prepareCommit}. virtual void rollback(); - + /// Delete all documents in the index. /// - /// This method will drop all buffered documents and will remove all segments from the index. This + /// This method will drop all buffered documents and will remove all segments from the index. This /// change will not be visible until a {@link #commit()} has been called. This method can be rolled /// back using {@link #rollback()}. /// /// NOTE: this method is much faster than using {@link #deleteDocuments()}. /// - /// NOTE: this method will forcefully abort all merges in progress. If other threads are running - /// {@link #optimize()} or any of the addIndexes methods, they will receive {@link + /// NOTE: this method will forcefully abort all merges in progress. If other threads are running + /// {@link #optimize()} or any of the addIndexes methods, they will receive {@link /// MergePolicy.MergeAbortedException} virtual void deleteAll(); - + /// Wait for any currently outstanding merges to finish. /// - /// It is guaranteed that any merges started prior to calling this method will have completed once + /// It is guaranteed that any merges started prior to calling this method will have completed once /// this method completes. virtual void waitForMerges(); - + /// Merges all segments from an array of indexes into this index. /// - /// This may be used to parallelize batch indexing. A large document collection can be broken into - /// sub-collections. Each sub-collection can be indexed in parallel, on a different thread, process - /// or machine. The complete index can then be created by merging sub-collection indexes with this + /// This may be used to parallelize batch indexing. A large document collection can be broken into + /// sub-collections. Each sub-collection can be indexed in parallel, on a different thread, process + /// or machine. The complete index can then be created by merging sub-collection indexes with this /// method. /// /// NOTE: the index in each Directory must not be changed (opened by a writer) while this method is - /// running. This method does not acquire a write lock in each input Directory, so it is up to the + /// running. This method does not acquire a write lock in each input Directory, so it is up to the /// caller to enforce this. /// - /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will + /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will /// be paused until this method completes. /// - /// This method is transactional in how exceptions are handled: it does not commit a new segments_N - /// file until all indexes are added. This means if an exception occurs (for example disk full), + /// This method is transactional in how exceptions are handled: it does not commit a new segments_N + /// file until all indexes are added. This means if an exception occurs (for example disk full), /// then either no indexes will have been added or they all will have been. /// - /// Note that this requires temporary free space in the Directory up to 2X the sum of all input - /// indexes (including the starting index). If readers/searchers are open against the starting index, - /// then temporary free space required will be higher by the size of the starting index (see + /// Note that this requires temporary free space in the Directory up to 2X the sum of all input + /// indexes (including the starting index). If readers/searchers are open against the starting index, + /// then temporary free space required will be higher by the size of the starting index (see /// {@link #optimize()} for details). /// - /// Once this completes, the final size of the index will be less than the sum of all input index - /// sizes (including the starting index). It could be quite a bit smaller (if there were many pending + /// Once this completes, the final size of the index will be less than the sum of all input index + /// sizes (including the starting index). It could be quite a bit smaller (if there were many pending /// deletes) or just slightly smaller. /// /// This requires this index not be among those to be added. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void addIndexesNoOptimize(Collection dirs); - + /// Merges the provided indexes into this index. /// After this completes, the index is optimized. The provided IndexReaders are not closed. /// - /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will + /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will /// be paused until this method completes. /// - /// See {@link #addIndexesNoOptimize} for details on transactional semantics, temporary free space + /// See {@link #addIndexesNoOptimize} for details on transactional semantics, temporary free space /// required in the Directory, and non-CFS segments on an exception. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void addIndexes(Collection readers); - + /// Prepare for commit. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// @see #prepareCommit(MapStringString) virtual void prepareCommit(); - - /// Prepare for commit, specifying commitUserData Map (String -> String). This does the first phase - /// of 2-phase commit. This method does all steps necessary to commit changes since this writer was - /// opened: flushes pending added and deleted docs, syncs the index files, writes most of next - /// segments_N file. After calling this you must call either {@link #commit()} to finish the commit, + + /// Prepare for commit, specifying commitUserData Map (String -> String). This does the first phase + /// of 2-phase commit. This method does all steps necessary to commit changes since this writer was + /// opened: flushes pending added and deleted docs, syncs the index files, writes most of next + /// segments_N file. After calling this you must call either {@link #commit()} to finish the commit, /// or {@link #rollback()} to revert the commit and undo all changes done since the writer was opened. /// - /// You can also just call {@link #commit(Map)} directly without prepareCommit first in which case + /// You can also just call {@link #commit(Map)} directly without prepareCommit first in which case /// that method will internally call prepareCommit. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// - /// @param commitUserData Opaque Map (String->String) that's recorded into the segments file in the - /// index, and retrievable by {@link IndexReader#getCommitUserData}. Note that when IndexWriter - /// commits itself during {@link #close}, the commitUserData is unchanged (just carried over from the - /// prior commit). If this is null then the previous commitUserData is kept. Also, the commitUserData + /// @param commitUserData Opaque Map (String->String) that's recorded into the segments file in the + /// index, and retrievable by {@link IndexReader#getCommitUserData}. Note that when IndexWriter + /// commits itself during {@link #close}, the commitUserData is unchanged (just carried over from the + /// prior commit). If this is null then the previous commitUserData is kept. Also, the commitUserData // will only "stick" if there are actually changes in the index to commit. virtual void prepareCommit(MapStringString commitUserData); - + /// Commits all pending changes (added & deleted documents, optimizations, segment merges, added - /// indexes, etc.) to the index, and syncs all referenced index files, such that a reader will see the - /// changes and the index updates will survive an OS or machine crash or power loss. Note that this - /// does not wait for any running background merges to finish. This may be a costly operation, so you + /// indexes, etc.) to the index, and syncs all referenced index files, such that a reader will see the + /// changes and the index updates will survive an OS or machine crash or power loss. Note that this + /// does not wait for any running background merges to finish. This may be a costly operation, so you /// should test the cost in your application and do it only when really necessary. /// - /// Note that this operation calls Directory.sync on the index files. That call should not return until - /// the file contents & metadata are on stable storage. For FSDirectory, this calls the OS's fsync. - /// But, beware: some hardware devices may in fact cache writes even during fsync, and return before the - /// bits are actually on stable storage, to give the appearance of faster performance. If you have such - /// a device, and it does not have a battery backup (for example) then on power loss it may still lose + /// Note that this operation calls Directory.sync on the index files. That call should not return until + /// the file contents & metadata are on stable storage. For FSDirectory, this calls the OS's fsync. + /// But, beware: some hardware devices may in fact cache writes even during fsync, and return before the + /// bits are actually on stable storage, to give the appearance of faster performance. If you have such + /// a device, and it does not have a battery backup (for example) then on power loss it may still lose /// data. Lucene cannot guarantee consistency on such devices. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. @@ -875,67 +875,67 @@ namespace Lucene /// @see #prepareCommit /// @see #commit(MapStringString) virtual void commit(); - + /// Commits all changes to the index, specifying a commitUserData Map (String -> String). This just - /// calls {@link #prepareCommit(MapStringString)} (if you didn't already call it) and then + /// calls {@link #prepareCommit(MapStringString)} (if you didn't already call it) and then /// {@link #finishCommit}. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. virtual void commit(MapStringString commitUserData); - - /// Return the total size of all index files currently cached in memory. Useful for size management + + /// Return the total size of all index files currently cached in memory. Useful for size management /// with flushRamDocs() virtual int64_t ramSizeInBytes(); - + /// Return the number of documents currently buffered in RAM. virtual int32_t numRamDocs(); - + /// Merges the indicated segments, replacing them in the stack with a single segment. virtual void merge(OneMergePtr merge); - + /// Hook that's called when the specified merge is complete. virtual void mergeSuccess(OneMergePtr merge); - - /// Checks whether this merge involves any segments already participating in a merge. If not, this - /// merge is "registered", meaning we record that its segments are now participating in a merge, + + /// Checks whether this merge involves any segments already participating in a merge. If not, this + /// merge is "registered", meaning we record that its segments are now participating in a merge, /// and true is returned. Else (the merge conflicts) false is returned. virtual bool registerMerge(OneMergePtr merge); - - /// Does initial setup for a merge, which is fast but holds the synchronized lock on IndexWriter + + /// Does initial setup for a merge, which is fast but holds the synchronized lock on IndexWriter /// instance. virtual void mergeInit(OneMergePtr merge); - + /// Does finishing for a merge, which is fast but holds the synchronized lock on IndexWriter instance. virtual void mergeFinish(OneMergePtr merge); - + virtual void addMergeException(OneMergePtr merge); - + /// For test purposes. virtual int32_t getBufferedDeleteTermsSize(); - + /// For test purposes. virtual int32_t getNumBufferedDeleteTerms(); - + /// Utility routines for tests virtual SegmentInfoPtr newestSegment(); - + virtual String segString(); - + /// Returns true if the index in the named directory is currently locked. /// @param directory the directory to check for a lock static bool isLocked(DirectoryPtr directory); - + /// Forcibly unlocks the index in the named directory. - /// Caution: this should only be used by failure recovery code, when it is known that no other process + /// Caution: this should only be used by failure recovery code, when it is known that no other process /// nor thread is in fact currently accessing this index. static void unlock(DirectoryPtr directory); - + /// Set the merged segment warmer. See {@link IndexReaderWarmer}. virtual void setMergedSegmentWarmer(IndexReaderWarmerPtr warmer); - + /// Returns the current merged segment warmer. See {@link IndexReaderWarmer}. virtual IndexReaderWarmerPtr getMergedSegmentWarmer(); - + /// Used only by assert for testing. Current points: /// startDoFlush /// startCommitMerge @@ -950,94 +950,94 @@ namespace Lucene /// startMergeInit /// startMergeInit virtual bool testPoint(const String& name); - + virtual bool nrtIsCurrent(SegmentInfosPtr infos); virtual bool isClosed(); - + protected: virtual void ensureOpen(bool includePendingClose); virtual void ensureOpen(); virtual void setMessageID(InfoStreamPtr infoStream); - - /// Casts current mergePolicy to LogMergePolicy, and throws an exception if the + + /// Casts current mergePolicy to LogMergePolicy, and throws an exception if the /// mergePolicy is not a LogMergePolicy. virtual LogMergePolicyPtr getLogMergePolicy(); - + virtual void setRollbackSegmentInfos(SegmentInfosPtr infos); - - /// If we are flushing by doc count (not by RAM usage), and using LogDocMergePolicy then push + + /// If we are flushing by doc count (not by RAM usage), and using LogDocMergePolicy then push /// maxBufferedDocs down as its minMergeDocs, to keep backwards compatibility. virtual void pushMaxBufferedDocs(); - + virtual void messageState(); - - /// Returns true if this thread should attempt to close, or false if IndexWriter is now closed; + + /// Returns true if this thread should attempt to close, or false if IndexWriter is now closed; /// else, waits until another thread finishes closing virtual bool shouldClose(); virtual void closeInternal(bool waitForMerges); - - /// Tells the docWriter to close its currently open shared doc stores (stored fields & vectors + + /// Tells the docWriter to close its currently open shared doc stores (stored fields & vectors /// files). Return value specifies whether new doc store files are compound or not. virtual bool flushDocStores(); - + /// Returns true if any merges in pendingMerges or runningMerges are optimization merges. virtual bool optimizeMergesPending(); - + virtual void maybeMerge(bool optimize); virtual void maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize); virtual void updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize); - + /// Like {@link #getNextMerge()} except only returns a merge if it's external. virtual OneMergePtr getNextExternalMerge(); - - /// Begin a transaction. During a transaction, any segment merges that happen (or ram segments + + /// Begin a transaction. During a transaction, any segment merges that happen (or ram segments /// flushed) will not write a new segments file and will not remove any files that were present - /// at the start of the transaction. You must make a matched call to commitTransaction() or + /// at the start of the transaction. You must make a matched call to commitTransaction() or /// rollbackTransaction() to finish the transaction. /// - /// Note that buffered documents and delete terms are not handled within the transactions, so + /// Note that buffered documents and delete terms are not handled within the transactions, so /// they must be flushed before the transaction is started. virtual void startTransaction(bool haveReadLock); - + /// Rolls back the transaction and restores state to where we were at the start. virtual void rollbackTransaction(); - - /// Commits the transaction. This will write the new segments file and remove and pending + + /// Commits the transaction. This will write the new segments file and remove and pending /// deletions we have accumulated during the transaction. virtual void commitTransaction(); virtual void rollbackInternal(); - + virtual void finishMerges(bool waitForMerges); - - /// Called whenever the SegmentInfos has been updated and the index files referenced exist + + /// Called whenever the SegmentInfos has been updated and the index files referenced exist /// (correctly) in the index directory. virtual void checkpoint(); - + virtual void finishAddIndexes(); virtual void blockAddIndexes(bool includePendingClose); virtual void resumeAddIndexes(); virtual void resetMergeExceptions(); virtual void noDupDirs(Collection dirs); - + virtual bool hasExternalSegments(); - - /// If any of our segments are using a directory != ours then we have to either copy them over one - /// by one, merge them (if merge policy has chosen to) or wait until currently running merges (in + + /// If any of our segments are using a directory != ours then we have to either copy them over one + /// by one, merge them (if merge policy has chosen to) or wait until currently running merges (in /// the background) complete. We don't return until the SegmentInfos has no more external segments. /// Currently this is only used by addIndexesNoOptimize(). virtual void resolveExternalSegments(); - - /// A hook for extending classes to execute operations after pending added and deleted documents have + + /// A hook for extending classes to execute operations after pending added and deleted documents have /// been flushed to the Directory but before the change is committed (new segments_N file written). virtual void doAfterFlush(); - - /// A hook for extending classes to execute operations before pending added and deleted documents are + + /// A hook for extending classes to execute operations before pending added and deleted documents are /// flushed to the Directory. virtual void doBeforeFlush(); - + virtual void commit(int64_t sizeInBytes); virtual void finishCommit(); - + /// Flush all in-memory buffered updates (adds and deletes) to the Directory. /// @param triggerMerge if true, we may merge segments (if deletes or docs were flushed) if necessary /// @param flushDocStores if false we are allowed to keep doc stores open to share with the next segment @@ -1045,56 +1045,56 @@ namespace Lucene virtual void flush(bool triggerMerge, bool flushDocStores, bool flushDeletes); virtual bool doFlush(bool flushDocStores, bool flushDeletes); virtual bool doFlushInternal(bool flushDocStores, bool flushDeletes); - + virtual int32_t ensureContiguousMerge(OneMergePtr merge); - - /// Carefully merges deletes for the segments we just merged. This is tricky because, although merging - /// will clear all deletes (compacts the documents), new deletes may have been flushed to the segments - /// since the merge was started. This method "carries over" such new deletes onto the newly merged + + /// Carefully merges deletes for the segments we just merged. This is tricky because, although merging + /// will clear all deletes (compacts the documents), new deletes may have been flushed to the segments + /// since the merge was started. This method "carries over" such new deletes onto the newly merged /// segment, and saves the resulting deletes file (incrementing the delete generation for merge.info). /// If no deletes were flushed, no new deletes file is saved. virtual void commitMergedDeletes(OneMergePtr merge, SegmentReaderPtr mergeReader); virtual bool commitMerge(OneMergePtr merge, SegmentMergerPtr merger, int32_t mergedDocCount, SegmentReaderPtr mergedReader); - + virtual LuceneException handleMergeException(const LuceneException& exc, OneMergePtr merge); - + virtual void _mergeInit(OneMergePtr merge); - + virtual void setDiagnostics(SegmentInfoPtr info, const String& source); virtual void setDiagnostics(SegmentInfoPtr info, const String& source, MapStringString details); - + virtual void setMergeDocStoreIsCompoundFile(OneMergePtr merge); virtual void closeMergeReaders(OneMergePtr merge, bool suppressExceptions); - - /// Does the actual (time-consuming) work of the merge, but without holding synchronized lock on + + /// Does the actual (time-consuming) work of the merge, but without holding synchronized lock on /// IndexWriter instance. - virtual int32_t mergeMiddle(OneMergePtr merge); - + virtual int32_t mergeMiddle(OneMergePtr merge); + /// Apply buffered deletes to all segments. virtual bool applyDeletes(); - + virtual String segString(SegmentInfosPtr infos); - + virtual bool startSync(const String& fileName, HashSet pending); virtual void finishSync(const String& fileName, bool success); - + /// Blocks until all files in syncing are sync'd bool waitForAllSynced(HashSet syncing); void doWait(); - - /// Walk through all files referenced by the current segmentInfos and ask the Directory to sync each - /// file, if it wasn't already. If that succeeds, then we prepare a new segments_N file but do not + + /// Walk through all files referenced by the current segmentInfos and ask the Directory to sync each + /// file, if it wasn't already. If that succeeds, then we prepare a new segments_N file but do not /// fully commit it. virtual void startCommit(int64_t sizeInBytes, MapStringString commitUserData); - + virtual LuceneException handleOOM(const std::bad_alloc& oom, const String& location); - + friend class ReaderPool; }; - - /// If {@link #getReader} has been called (ie, this writer is in near real-time mode), then after - /// a merge completes, this class can be invoked to warm the reader on the newly merged segment, - /// before the merge commits. This is not required for near real-time search, but will reduce + + /// If {@link #getReader} has been called (ie, this writer is in near real-time mode), then after + /// a merge completes, this class can be invoked to warm the reader on the newly merged segment, + /// before the merge commits. This is not required for near real-time search, but will reduce /// search latency on opening a new near real-time reader after a merge completes. /// /// NOTE: warm is called before any deletes have been carried over to the merged segment. @@ -1102,10 +1102,10 @@ namespace Lucene { public: virtual ~IndexReaderWarmer(); - + LUCENE_CLASS(IndexReaderWarmer); - - public: + + public: virtual void warm(IndexReaderPtr reader) = 0; }; } diff --git a/include/InfoStream.h b/include/InfoStream.h index 273c1b40..a15020b6 100644 --- a/include/InfoStream.h +++ b/include/InfoStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,49 +17,49 @@ namespace Lucene { protected: InfoStream(); - + public: virtual ~InfoStream(); LUCENE_CLASS(InfoStream); - + public: virtual InfoStream& operator<< (const String& t) = 0; }; - + /// Stream override to write messages to a file. class LPPAPI InfoStreamFile : public InfoStream { public: InfoStreamFile(const String& path); virtual ~InfoStreamFile(); - + LUCENE_CLASS(InfoStreamFile); - + protected: boost::filesystem::wofstream file; - + public: virtual InfoStreamFile& operator<< (const String& t); }; - + /// Stream override to write messages to a std::cout. class LPPAPI InfoStreamOut : public InfoStream { public: virtual ~InfoStreamOut(); LUCENE_CLASS(InfoStreamOut); - + public: virtual InfoStreamOut& operator<< (const String& t); }; - + /// Null stream override to eat messages. class LPPAPI InfoStreamNull : public InfoStream { public: virtual ~InfoStreamNull(); LUCENE_CLASS(InfoStreamNull); - + public: virtual InfoStreamNull& operator<< (const String& t); }; diff --git a/include/InputStreamReader.h b/include/InputStreamReader.h index eaa3a70c..561c6827 100644 --- a/include/InputStreamReader.h +++ b/include/InputStreamReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,26 +18,26 @@ namespace Lucene /// Create an InputStreamReader that uses the utf8 charset. InputStreamReader(ReaderPtr reader); virtual ~InputStreamReader(); - + LUCENE_CLASS(InputStreamReader); - + protected: ReaderPtr reader; UTF8DecoderStreamPtr decoder; - + public: /// Read a single character. virtual int32_t read(); - + /// Read characters into a portion of an array. virtual int32_t read(wchar_t* b, int32_t offset, int32_t length); - + /// Close the stream. virtual void close(); - + /// Tell whether this stream supports the mark() operation virtual bool markSupported(); - + /// Reset the stream. virtual void reset(); }; diff --git a/include/IntBlockPool.h b/include/IntBlockPool.h index 08926595..722138fa 100644 --- a/include/IntBlockPool.h +++ b/include/IntBlockPool.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,22 +16,22 @@ namespace Lucene public: IntBlockPool(DocumentsWriterPtr docWriter, bool trackAllocations); virtual ~IntBlockPool(); - + LUCENE_CLASS(IntBlockPool); - + public: Collection buffers; - + int32_t bufferUpto; // Which buffer we are upto int32_t intUpto; // Where we are in head buffer - + IntArray buffer; // Current head buffer int32_t intOffset; // Current head offset bool trackAllocations; - + protected: DocumentsWriterWeakPtr _docWriter; - + public: void reset(); void nextBuffer(); diff --git a/include/IntFieldSource.h b/include/IntFieldSource.h index 22056433..5373339e 100644 --- a/include/IntFieldSource.h +++ b/include/IntFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,15 +11,15 @@ namespace Lucene { - /// Obtains int field values from the {@link FieldCache} using getInts() and makes those values available + /// Obtains int field values from the {@link FieldCache} using getInts() and makes those values available /// as other numeric types, casting as needed. /// /// @see FieldCacheSource for requirements on the field. /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite + /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU + /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, + /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU /// per lookup but will not consume double the FieldCache RAM. class LPPAPI IntFieldSource : public FieldCacheSource { @@ -27,12 +27,12 @@ namespace Lucene /// Create a cached int field source with a specific string-to-int parser. IntFieldSource(const String& field, IntParserPtr parser = IntParserPtr()); virtual ~IntFieldSource(); - + LUCENE_CLASS(IntFieldSource); - + protected: IntParserPtr parser; - + public: virtual String description(); virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader); diff --git a/include/InvertedDocConsumer.h b/include/InvertedDocConsumer.h index efc68d5a..cbc5bf9b 100644 --- a/include/InvertedDocConsumer.h +++ b/include/InvertedDocConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,28 +15,28 @@ namespace Lucene { public: virtual ~InvertedDocConsumer(); - + LUCENE_CLASS(InvertedDocConsumer); - + public: FieldInfosPtr fieldInfos; - + public: /// Add a new thread virtual InvertedDocConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread) = 0; - + /// Abort (called after hitting AbortException) virtual void abort() = 0; - + /// Flush a new segment virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; - + /// Close doc stores virtual void closeDocStore(SegmentWriteStatePtr state) = 0; - + /// Attempt to free RAM, returning true if any RAM was freed virtual bool freeRAM() = 0; - + virtual void setFieldInfos(FieldInfosPtr fieldInfos); }; } diff --git a/include/InvertedDocConsumerPerField.h b/include/InvertedDocConsumerPerField.h index bf227d4e..54cc01ce 100644 --- a/include/InvertedDocConsumerPerField.h +++ b/include/InvertedDocConsumerPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,23 +15,23 @@ namespace Lucene { public: virtual ~InvertedDocConsumerPerField(); - + LUCENE_CLASS(InvertedDocConsumerPerField); - + public: - /// Called once per field, and is given all Fieldable occurrences for this field in the document. + /// Called once per field, and is given all Fieldable occurrences for this field in the document. /// Return true if you wish to see inverted tokens for these fields virtual bool start(Collection fields, int32_t count) = 0; - + /// Called before a field instance is being processed virtual void start(FieldablePtr field) = 0; - + /// Called once per inverted token virtual void add() = 0; - + /// Called once per field per document, after all Fieldable occurrences are inverted virtual void finish() = 0; - + /// Called on hitting an aborting exception virtual void abort() = 0; }; diff --git a/include/InvertedDocConsumerPerThread.h b/include/InvertedDocConsumerPerThread.h index 6b538851..35649015 100644 --- a/include/InvertedDocConsumerPerThread.h +++ b/include/InvertedDocConsumerPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~InvertedDocConsumerPerThread(); - + LUCENE_CLASS(InvertedDocConsumerPerThread); - + public: virtual void startDocument() = 0; virtual InvertedDocConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) = 0; diff --git a/include/InvertedDocEndConsumer.h b/include/InvertedDocEndConsumer.h index 6a251d97..65b92a18 100644 --- a/include/InvertedDocEndConsumer.h +++ b/include/InvertedDocEndConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~InvertedDocEndConsumer(); - + LUCENE_CLASS(InvertedDocEndConsumer); - + public: virtual InvertedDocEndConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread) = 0; virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; diff --git a/include/InvertedDocEndConsumerPerField.h b/include/InvertedDocEndConsumerPerField.h index 3ce6e336..dc437336 100644 --- a/include/InvertedDocEndConsumerPerField.h +++ b/include/InvertedDocEndConsumerPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~InvertedDocEndConsumerPerField(); - + LUCENE_CLASS(InvertedDocEndConsumerPerField); - + public: virtual void finish() = 0; virtual void abort() = 0; diff --git a/include/InvertedDocEndConsumerPerThread.h b/include/InvertedDocEndConsumerPerThread.h index d827b64c..6d2af130 100644 --- a/include/InvertedDocEndConsumerPerThread.h +++ b/include/InvertedDocEndConsumerPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~InvertedDocEndConsumerPerThread(); - + LUCENE_CLASS(InvertedDocEndConsumerPerThread); - + public: virtual void startDocument() = 0; virtual InvertedDocEndConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) = 0; diff --git a/include/KeepOnlyLastCommitDeletionPolicy.h b/include/KeepOnlyLastCommitDeletionPolicy.h index ed808fcd..e015666e 100644 --- a/include/KeepOnlyLastCommitDeletionPolicy.h +++ b/include/KeepOnlyLastCommitDeletionPolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,19 +11,19 @@ namespace Lucene { - /// This {@link IndexDeletionPolicy} implementation that keeps only the most recent commit and immediately + /// This {@link IndexDeletionPolicy} implementation that keeps only the most recent commit and immediately /// removes all prior commits after a new commit is done. This is the default deletion policy. class LPPAPI KeepOnlyLastCommitDeletionPolicy : public IndexDeletionPolicy { public: virtual ~KeepOnlyLastCommitDeletionPolicy(); - + LUCENE_CLASS(KeepOnlyLastCommitDeletionPolicy); - + public: /// Deletes all commits except the most recent one. virtual void onInit(Collection commits); - + /// Deletes all commits except the most recent one. virtual void onCommit(Collection commits); }; diff --git a/include/KeywordAnalyzer.h b/include/KeywordAnalyzer.h index e666f20b..fa4d5cfe 100644 --- a/include/KeywordAnalyzer.h +++ b/include/KeywordAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,15 +11,15 @@ namespace Lucene { - /// Tokenizes the entire stream as a single token. This is useful for data like zip codes, ids, and some + /// Tokenizes the entire stream as a single token. This is useful for data like zip codes, ids, and some /// product names. class LPPAPI KeywordAnalyzer : public Analyzer { public: virtual ~KeywordAnalyzer(); - + LUCENE_CLASS(KeywordAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); diff --git a/include/KeywordTokenizer.h b/include/KeywordTokenizer.h index 03294871..639b86cb 100644 --- a/include/KeywordTokenizer.h +++ b/include/KeywordTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,22 +19,22 @@ namespace Lucene KeywordTokenizer(ReaderPtr input, int32_t bufferSize); KeywordTokenizer(AttributeSourcePtr source, ReaderPtr input, int32_t bufferSize); KeywordTokenizer(AttributeFactoryPtr factory, ReaderPtr input, int32_t bufferSize); - + virtual ~KeywordTokenizer(); - + LUCENE_CLASS(KeywordTokenizer); - + protected: static const int32_t DEFAULT_BUFFER_SIZE; - + bool done; int32_t finalOffset; TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; - + protected: void init(int32_t bufferSize); - + public: virtual bool incrementToken(); virtual void end(); diff --git a/include/LengthFilter.h b/include/LengthFilter.h index e140d3c0..f50405a2 100644 --- a/include/LengthFilter.h +++ b/include/LengthFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,16 +18,16 @@ namespace Lucene /// Build a filter that removes words that are too long or too short from the text. LengthFilter(TokenStreamPtr input, int32_t min, int32_t max); virtual ~LengthFilter(); - + LUCENE_CLASS(LengthFilter); - + public: int32_t min; int32_t max; - + protected: TermAttributePtr termAtt; - + public: /// Returns the next input Token whose term() is the right len virtual bool incrementToken(); diff --git a/include/LetterTokenizer.h b/include/LetterTokenizer.h index 2a78a565..88964d77 100644 --- a/include/LetterTokenizer.h +++ b/include/LetterTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,27 +11,27 @@ namespace Lucene { - /// A LetterTokenizer is a tokenizer that divides text at non-letters. That's to say, it defines tokens as maximal + /// A LetterTokenizer is a tokenizer that divides text at non-letters. That's to say, it defines tokens as maximal /// strings of adjacent letters, as defined UnicodeUtil::isAlpha(c) predicate. /// - /// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, where + /// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, where /// words are not separated by spaces. class LPPAPI LetterTokenizer : public CharTokenizer { public: /// Construct a new LetterTokenizer. LetterTokenizer(ReaderPtr input); - + /// Construct a new LetterTokenizer using a given {@link AttributeSource}. LetterTokenizer(AttributeSourcePtr source, ReaderPtr input); - + /// Construct a new LetterTokenizer using a given {@link AttributeFactory}. LetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~LetterTokenizer(); - + LUCENE_CLASS(LetterTokenizer); - + public: /// Collects only characters which satisfy UnicodeUtil::isAlpha(c). virtual bool isTokenChar(wchar_t c); diff --git a/include/LoadFirstFieldSelector.h b/include/LoadFirstFieldSelector.h index 62c21fd3..45572aae 100644 --- a/include/LoadFirstFieldSelector.h +++ b/include/LoadFirstFieldSelector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene { public: virtual ~LoadFirstFieldSelector(); - + LUCENE_CLASS(LoadFirstFieldSelector); - + public: virtual FieldSelectorResult accept(const String& fieldName); }; diff --git a/include/Lock.h b/include/Lock.h index 184daae2..29840e61 100644 --- a/include/Lock.h +++ b/include/Lock.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,31 +16,31 @@ namespace Lucene class LPPAPI Lock : public LuceneObject { public: - virtual ~Lock(); + virtual ~Lock(); LUCENE_CLASS(Lock); - - public: + + public: /// How long {@link #obtain(int64_t)} waits, in milliseconds, in between attempts to acquire the lock. static const int32_t LOCK_OBTAIN_WAIT_FOREVER; - + /// Pass this value to {@link #obtain(int64_t)} to try forever to obtain the lock. static const int32_t LOCK_POLL_INTERVAL; - + public: /// Attempts to obtain exclusive access and immediately return upon success or failure. /// @return true if exclusive access is obtained. virtual bool obtain() = 0; - + /// Releases exclusive access. virtual void release() = 0; - - /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} + + /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} /// before using the resource. virtual bool isLocked() = 0; - + /// Attempts to obtain an exclusive lock within amount of time given. Polls once per {@link #LOCK_POLL_INTERVAL} /// (currently 1000) milliseconds until lockWaitTimeout is passed. - /// @param lockWaitTimeout length of time to wait in milliseconds or {@link #LOCK_OBTAIN_WAIT_FOREVER} + /// @param lockWaitTimeout length of time to wait in milliseconds or {@link #LOCK_OBTAIN_WAIT_FOREVER} /// to retry forever. /// @return true if lock was obtained. bool obtain(int32_t lockWaitTimeout); diff --git a/include/LockFactory.h b/include/LockFactory.h index 387445fe..56ce224b 100644 --- a/include/LockFactory.h +++ b/include/LockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,27 +24,27 @@ namespace Lucene { public: virtual ~LockFactory(); - + LUCENE_CLASS(LockFactory); - + protected: String lockPrefix; - + public: /// Set the prefix in use for all locks created in this LockFactory. This is normally called once, when a - /// Directory gets this LockFactory instance. However, you can also call this (after this instance is - /// assigned to a Directory) to override the prefix in use. This is helpful if you're running Lucene on + /// Directory gets this LockFactory instance. However, you can also call this (after this instance is + /// assigned to a Directory) to override the prefix in use. This is helpful if you're running Lucene on /// machines that have different mount points for the same shared directory. virtual void setLockPrefix(const String& lockPrefix); - + /// Get the prefix in use for all locks created in this LockFactory. virtual String getLockPrefix(); - + /// Return a new Lock instance identified by lockName. /// @param lockName name of the lock to be created. virtual LockPtr makeLock(const String& lockName) = 0; - - /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you + + /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you /// are certain this lock is no longer in use. /// @param lockName name of the lock to be cleared. virtual void clearLock(const String& lockName) = 0; diff --git a/include/LogByteSizeMergePolicy.h b/include/LogByteSizeMergePolicy.h index a600f83b..3304121e 100644 --- a/include/LogByteSizeMergePolicy.h +++ b/include/LogByteSizeMergePolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,48 +11,48 @@ namespace Lucene { - /// This is a {@link LogMergePolicy} that measures size of a segment as the total byte size of the + /// This is a {@link LogMergePolicy} that measures size of a segment as the total byte size of the /// segment's files. class LPPAPI LogByteSizeMergePolicy : public LogMergePolicy { public: LogByteSizeMergePolicy(IndexWriterPtr writer); virtual ~LogByteSizeMergePolicy(); - + LUCENE_CLASS(LogByteSizeMergePolicy); - + public: /// Default minimum segment size. @see setMinMergeMB. static const double DEFAULT_MIN_MERGE_MB; - + /// Default maximum segment size. A segment of this size or larger will never be merged. /// @see setMaxMergeMB static const double DEFAULT_MAX_MERGE_MB; - + protected: virtual int64_t size(SegmentInfoPtr info); - + public: - /// Determines the largest segment (measured by total byte size of the segment's files, in MB) - /// that may be merged with other segments. Small values (eg., less than 50 MB) are best for - /// interactive indexing, as this limits the length of pauses while indexing to a few seconds. + /// Determines the largest segment (measured by total byte size of the segment's files, in MB) + /// that may be merged with other segments. Small values (eg., less than 50 MB) are best for + /// interactive indexing, as this limits the length of pauses while indexing to a few seconds. /// Larger values are best for batched indexing and speedier searches. /// /// Note that {@link #setMaxMergeDocs} is also used to check whether a segment is too large for /// merging (it's either or). void setMaxMergeMB(double mb); - /// Returns the largest segment (measured by total byte size of the segment's files, in MB) that - /// may be merged with other segments. @see #setMaxMergeMB + /// Returns the largest segment (measured by total byte size of the segment's files, in MB) that + /// may be merged with other segments. @see #setMaxMergeMB double getMaxMergeMB(); - - /// Sets the minimum size for the lowest level segments. Any segments below this size are - /// considered to be on the same level (even if they vary drastically in size) and will be merged - /// whenever there are mergeFactor of them. This effectively truncates the "long tail" of small - /// segments that would otherwise be created into a single level. If you set this too large, it + + /// Sets the minimum size for the lowest level segments. Any segments below this size are + /// considered to be on the same level (even if they vary drastically in size) and will be merged + /// whenever there are mergeFactor of them. This effectively truncates the "long tail" of small + /// segments that would otherwise be created into a single level. If you set this too large, it /// could greatly increase the merging cost during indexing (if you flush many small segments). void setMinMergeMB(double mb); - + /// Get the minimum size for a segment to remain un-merged. @see #setMinMergeMB double getMinMergeMB(); }; diff --git a/include/LogDocMergePolicy.h b/include/LogDocMergePolicy.h index f40bb2b3..156a6d6b 100644 --- a/include/LogDocMergePolicy.h +++ b/include/LogDocMergePolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,31 +11,31 @@ namespace Lucene { - /// This is a {@link LogMergePolicy} that measures size of a segment as the number of documents + /// This is a {@link LogMergePolicy} that measures size of a segment as the number of documents /// (not taking deletions into account). class LPPAPI LogDocMergePolicy : public LogMergePolicy { public: LogDocMergePolicy(IndexWriterPtr writer); virtual ~LogDocMergePolicy(); - + LUCENE_CLASS(LogDocMergePolicy); - + public: /// Default minimum segment size. @see setMinMergeDocs static const int32_t DEFAULT_MIN_MERGE_DOCS; - + protected: virtual int64_t size(SegmentInfoPtr info); - + public: - /// Sets the minimum size for the lowest level segments. Any segments below this size are considered - /// to be on the same level (even if they vary drastically in size) and will be merged whenever there - /// are mergeFactor of them. This effectively truncates the "long tail" of small segments that would - /// otherwise be created into a single level. If you set this too large, it could greatly increase the + /// Sets the minimum size for the lowest level segments. Any segments below this size are considered + /// to be on the same level (even if they vary drastically in size) and will be merged whenever there + /// are mergeFactor of them. This effectively truncates the "long tail" of small segments that would + /// otherwise be created into a single level. If you set this too large, it could greatly increase the /// merging cost during indexing (if you flush many small segments). void setMinMergeDocs(int32_t minMergeDocs); - + /// Get the minimum size for a segment to remain un-merged. @see #setMinMergeDocs int32_t getMinMergeDocs(); }; diff --git a/include/LogMergePolicy.h b/include/LogMergePolicy.h index 9b268901..f2126bbc 100644 --- a/include/LogMergePolicy.h +++ b/include/LogMergePolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,148 +12,148 @@ namespace Lucene { /// This class implements a {@link MergePolicy} that tries to merge segments into levels of exponentially - /// increasing size, where each level has fewer segments than the value of the merge factor. Whenever extra - /// segments (beyond the merge factor upper bound) are encountered, all segments within the level are merged. - /// You can get or set the merge factor using {@link #getMergeFactor()} and {@link #setMergeFactor(int)} + /// increasing size, where each level has fewer segments than the value of the merge factor. Whenever extra + /// segments (beyond the merge factor upper bound) are encountered, all segments within the level are merged. + /// You can get or set the merge factor using {@link #getMergeFactor()} and {@link #setMergeFactor(int)} /// respectively. /// /// This class is abstract and requires a subclass to define the {@link #size} method which specifies how a - /// segment's size is determined. {@link LogDocMergePolicy} is one subclass that measures size by document - /// count in the segment. {@link LogByteSizeMergePolicy} is another subclass that measures size as the total + /// segment's size is determined. {@link LogDocMergePolicy} is one subclass that measures size by document + /// count in the segment. {@link LogByteSizeMergePolicy} is another subclass that measures size as the total /// byte size of the file(s) for the segment. class LPPAPI LogMergePolicy : public MergePolicy { public: LogMergePolicy(IndexWriterPtr writer); virtual ~LogMergePolicy(); - + LUCENE_CLASS(LogMergePolicy); - + protected: int32_t mergeFactor; - + double noCFSRatio; - + bool calibrateSizeByDeletes; bool _useCompoundFile; bool _useCompoundDocStore; - + public: /// Defines the allowed range of log(size) for each level. A level is computed by taking the max segment /// log size, minus LEVEL_LOG_SPAN, and finding all segments falling within that range. static const double LEVEL_LOG_SPAN; - + /// Default merge factor, which is how many segments are merged at a time. static const int32_t DEFAULT_MERGE_FACTOR; - - /// Default maximum segment size. A segment of this size or larger will never be merged. + + /// Default maximum segment size. A segment of this size or larger will never be merged. /// @see setMaxMergeDocs static const int32_t DEFAULT_MAX_MERGE_DOCS; - + /// Default noCFSRatio. If a merge's size is >= 10% of the index, then we disable compound file for it. /// @see #setNoCFSRatio static const double DEFAULT_NO_CFS_RATIO; - + int64_t minMergeSize; int64_t maxMergeSize; int32_t maxMergeDocs; - + public: /// @see #setNoCFSRatio double getNoCFSRatio(); - + /// If a merged segment will be more than this percentage of the total size of the index, leave the segment as /// non-compound file even if compound file is enabled. Set to 1.0 to always use CFS regardless of merge size. void setNoCFSRatio(double noCFSRatio); - + /// Returns the number of segments that are merged at once and also controls the total number of segments /// allowed to accumulate in the index. int32_t getMergeFactor(); - + /// Determines how often segment indices are merged by addDocument(). With smaller values, less RAM is - /// used while indexing, and searches on unoptimized indices are faster, but indexing speed is slower. - /// With larger values, more RAM is used during indexing, and while searches on unoptimized indices are - /// slower, indexing is faster. Thus larger values (> 10) are best for batch index creation, and smaller + /// used while indexing, and searches on unoptimized indices are faster, but indexing speed is slower. + /// With larger values, more RAM is used during indexing, and while searches on unoptimized indices are + /// slower, indexing is faster. Thus larger values (> 10) are best for batch index creation, and smaller /// values (< 10) for indices that are interactively maintained. void setMergeFactor(int32_t mergeFactor); - + /// Returns true if a newly flushed (not from merge) segment should use the compound file format. virtual bool useCompoundFile(SegmentInfosPtr segments, SegmentInfoPtr newSegment); - + /// Sets whether compound file format should be used for newly flushed and newly merged segments. void setUseCompoundFile(bool useCompoundFile); - - /// Returns true if newly flushed and newly merge segments are written in compound file format. + + /// Returns true if newly flushed and newly merge segments are written in compound file format. /// @see #setUseCompoundFile bool getUseCompoundFile(); - + /// Returns true if the doc store files should use the compound file format. virtual bool useCompoundDocStore(SegmentInfosPtr segments); - + /// Sets whether compound file format should be used for newly flushed and newly merged doc store /// segment files (term vectors and stored fields). void setUseCompoundDocStore(bool useCompoundDocStore); - + /// Returns true if newly flushed and newly merge doc store segment files (term vectors and stored fields) /// are written in compound file format. @see #setUseCompoundDocStore bool getUseCompoundDocStore(); - - /// Sets whether the segment size should be calibrated by the number of deletes when choosing segments + + /// Sets whether the segment size should be calibrated by the number of deletes when choosing segments /// for merge. void setCalibrateSizeByDeletes(bool calibrateSizeByDeletes); - - /// Returns true if the segment size should be calibrated by the number of deletes when choosing segments + + /// Returns true if the segment size should be calibrated by the number of deletes when choosing segments /// for merge. bool getCalibrateSizeByDeletes(); - + /// Release all resources for the policy. virtual void close(); - - /// Returns the merges necessary to optimize the index. This merge policy defines "optimized" to mean only + + /// Returns the merges necessary to optimize the index. This merge policy defines "optimized" to mean only /// one segment in the index, where that segment has no deletions pending nor separate norms, and it is in /// compound file format if the current useCompoundFile setting is true. This method returns multiple merges /// (mergeFactor at a time) so the {@link MergeScheduler} in use may make use of concurrency. virtual MergeSpecificationPtr findMergesForOptimize(SegmentInfosPtr segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize); - + /// Finds merges necessary to expunge all deletes from the index. We simply merge adjacent segments that have /// deletes, up to mergeFactor at a time. virtual MergeSpecificationPtr findMergesToExpungeDeletes(SegmentInfosPtr segmentInfos); - + /// Checks if any merges are now necessary and returns a {@link MergePolicy.MergeSpecification} if so. A merge - /// is necessary when there are more than {@link #setMergeFactor} segments at a given level. When multiple - /// levels have too many segments, this method will return multiple merges, allowing the {@link MergeScheduler} + /// is necessary when there are more than {@link #setMergeFactor} segments at a given level. When multiple + /// levels have too many segments, this method will return multiple merges, allowing the {@link MergeScheduler} /// to use concurrency. virtual MergeSpecificationPtr findMerges(SegmentInfosPtr segmentInfos); - + /// Determines the largest segment (measured by document count) that may be merged with other segments. /// Small values (eg., less than 10,000) are best for interactive indexing, as this limits the length of /// pauses while indexing to a few seconds. Larger values are best for batched indexing and speedier searches. /// /// The default value is INT_MAX. /// - /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit by net size + /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit by net size /// (in MB) of the segment, using {@link LogByteSizeMergePolicy#setMaxMergeMB}. void setMaxMergeDocs(int32_t maxMergeDocs); - + /// Returns the largest segment (measured by document count) that may be merged with other segments. /// @see #setMaxMergeDocs int32_t getMaxMergeDocs(); - + protected: bool verbose(); void message(const String& message); - + virtual int64_t size(SegmentInfoPtr info) = 0; - + int64_t sizeDocs(SegmentInfoPtr info); int64_t sizeBytes(SegmentInfoPtr info); - + bool isOptimized(SegmentInfosPtr infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize); - + /// Returns true if this single info is optimized (has no pending norms or deletes, is in the same dir as the /// writer, and matches the current compound file setting bool isOptimized(SegmentInfoPtr info); - + OneMergePtr makeOneMerge(SegmentInfosPtr infos, SegmentInfosPtr infosToMerge); }; } diff --git a/include/LowerCaseFilter.h b/include/LowerCaseFilter.h index fae528e4..cf8d6228 100644 --- a/include/LowerCaseFilter.h +++ b/include/LowerCaseFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,12 +17,12 @@ namespace Lucene public: LowerCaseFilter(TokenStreamPtr input); virtual ~LowerCaseFilter(); - + LUCENE_CLASS(LowerCaseFilter); - + protected: TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/include/LowerCaseTokenizer.h b/include/LowerCaseTokenizer.h index 909bec71..8d768116 100644 --- a/include/LowerCaseTokenizer.h +++ b/include/LowerCaseTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,29 +11,29 @@ namespace Lucene { - /// LowerCaseTokenizer performs the function of LetterTokenizer and LowerCaseFilter together. It divides text at - /// non-letters and converts them to lower case. While it is functionally equivalent to the combination of - /// LetterTokenizer and LowerCaseFilter, there is a performance advantage to doing the two tasks at once, hence + /// LowerCaseTokenizer performs the function of LetterTokenizer and LowerCaseFilter together. It divides text at + /// non-letters and converts them to lower case. While it is functionally equivalent to the combination of + /// LetterTokenizer and LowerCaseFilter, there is a performance advantage to doing the two tasks at once, hence /// this (redundant) implementation. /// - /// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, + /// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, /// where words are not separated by spaces. class LPPAPI LowerCaseTokenizer : public LetterTokenizer { public: /// Construct a new LowerCaseTokenizer. LowerCaseTokenizer(ReaderPtr input); - + /// Construct a new LowerCaseTokenizer using a given {@link AttributeSource}. LowerCaseTokenizer(AttributeSourcePtr source, ReaderPtr input); - + /// Construct a new LowerCaseTokenizer using a given {@link AttributeFactory}. LowerCaseTokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~LowerCaseTokenizer(); - + LUCENE_CLASS(LowerCaseTokenizer); - + public: /// Converts char to lower case CharFolder::toLower. virtual wchar_t normalize(wchar_t c); diff --git a/include/Lucene.h b/include/Lucene.h index 4b4a3769..149a975f 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/LuceneAllocator.h b/include/LuceneAllocator.h index 0bc7ad9a..c78ac7d6 100644 --- a/include/LuceneAllocator.h +++ b/include/LuceneAllocator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/LuceneException.h b/include/LuceneException.h index 073bfe0e..00a55f23 100644 --- a/include/LuceneException.h +++ b/include/LuceneException.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,7 +22,7 @@ namespace Lucene Compression, CorruptIndex, FieldReader, - FileNotFound, + FileNotFound, IllegalArgument, IllegalState, IndexOutOfBounds, @@ -46,21 +46,21 @@ namespace Lucene TooManyClauses, UnsupportedOperation }; - + LuceneException(const String& error = EmptyString, LuceneException::ExceptionType type = Null) throw(); ~LuceneException() throw(); - + protected: ExceptionType type; String error; - + public: ExceptionType getType() const; String getError() const; bool isNull() const; void throwException(); }; - + template class ExceptionTemplate : public ParentException { @@ -69,7 +69,7 @@ namespace Lucene { } }; - + typedef ExceptionTemplate RuntimeException; typedef ExceptionTemplate OutOfMemoryError; typedef ExceptionTemplate TemporaryException; diff --git a/include/LuceneFactory.h b/include/LuceneFactory.h index dfd9cb19..993ebe9f 100644 --- a/include/LuceneFactory.h +++ b/include/LuceneFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/LuceneHeaders.h b/include/LuceneHeaders.h index 76759cc6..aa58d632 100644 --- a/include/LuceneHeaders.h +++ b/include/LuceneHeaders.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/LuceneObject.h b/include/LuceneObject.h index af10f7f9..d7ba5c94 100644 --- a/include/LuceneObject.h +++ b/include/LuceneObject.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -32,28 +32,28 @@ namespace Lucene { public: virtual ~LuceneObject(); - + protected: LuceneObject(); public: - /// Called directly after instantiation to create objects that depend on this object being + /// Called directly after instantiation to create objects that depend on this object being /// fully constructed. virtual void initialize(); - + /// Return clone of this object /// @param other clone reference - null when called initially, then set in top virtual override. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Return hash code for this object. virtual int32_t hashCode(); - + /// Return whether two objects are equal virtual bool equals(LuceneObjectPtr other); - + /// Compare two objects virtual int32_t compareTo(LuceneObjectPtr other); - + /// Returns a string representation of the object virtual String toString(); }; diff --git a/include/LuceneSignal.h b/include/LuceneSignal.h index 11559e32..093a7d44 100644 --- a/include/LuceneSignal.h +++ b/include/LuceneSignal.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,19 +18,19 @@ namespace Lucene public: LuceneSignal(SynchronizePtr objectLock = SynchronizePtr()); virtual ~LuceneSignal(); - + protected: boost::mutex waitMutex; boost::condition signalCondition; SynchronizePtr objectLock; - + public: /// create a new LuceneSignal instance atomically. static void createSignal(LuceneSignalPtr& signal, SynchronizePtr objectLock); - + /// Wait for signal using an optional timeout. void wait(int32_t timeout = 0); - + /// Notify all threads waiting for signal. void notifyAll(); }; diff --git a/include/LuceneSync.h b/include/LuceneSync.h index 0d2826bc..4bb2e12e 100644 --- a/include/LuceneSync.h +++ b/include/LuceneSync.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,30 +16,30 @@ namespace Lucene { public: virtual ~LuceneSync(); - + protected: SynchronizePtr objectLock; LuceneSignalPtr objectSignal; - + public: /// Return this object synchronize lock. virtual SynchronizePtr getSync(); - + /// Return this object signal. virtual LuceneSignalPtr getSignal(); - + /// Lock this object using an optional timeout. virtual void lock(int32_t timeout = 0); - + /// Unlock this object. virtual void unlock(); - + /// Returns true if this object is currently locked by current thread. virtual bool holdsLock(); - + /// Wait for signal using an optional timeout. virtual void wait(int32_t timeout = 0); - + /// Notify all threads waiting for signal. virtual void notifyAll(); }; diff --git a/include/LuceneThread.h b/include/LuceneThread.h index 985e0598..b7e92364 100644 --- a/include/LuceneThread.h +++ b/include/LuceneThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,59 +25,59 @@ namespace Lucene public: LuceneThread(); virtual ~LuceneThread(); - + LUCENE_CLASS(LuceneThread); - - public: + + public: static const int32_t MAX_PRIORITY; static const int32_t NORM_PRIORITY; static const int32_t MIN_PRIORITY; - + protected: threadPtr thread; - + /// Flag to indicate running thread. /// @see #isAlive bool running; - + public: /// start thread see {@link #run}. virtual void start(); - + /// return whether thread is current running. virtual bool isAlive(); - + /// set running thread priority. virtual void setPriority(int32_t priority); - + /// return running thread priority. virtual int32_t getPriority(); - + /// wait for thread to finish using an optional timeout. virtual bool join(int32_t timeout = 0); - + /// causes the currently executing thread object to temporarily pause and allow other threads to execute. virtual void yield(); - + /// override to provide the body of the thread. virtual void run() = 0; - + /// Return representation of current execution thread. static int64_t currentId(); - + /// Suspends current execution thread for a given time. static void threadSleep(int32_t time); - + /// Yield current execution thread. static void threadYield(); - + protected: /// set thread running state. void setRunning(bool running); - + /// return thread running state. bool isRunning(); - + /// function that controls the lifetime of the running thread. static void runThread(LuceneThread* thread); }; diff --git a/include/LuceneTypes.h b/include/LuceneTypes.h index 71c93f32..75a9563b 100644 --- a/include/LuceneTypes.h +++ b/include/LuceneTypes.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ class Type; \ typedef boost::shared_ptr Type##Ptr; \ typedef boost::weak_ptr Type##WeakPtr; - + namespace Lucene { // analysis @@ -42,7 +42,7 @@ namespace Lucene DECLARE_SHARED_PTR(PerFieldAnalyzerWrapper) DECLARE_SHARED_PTR(PorterStemFilter) DECLARE_SHARED_PTR(PorterStemmer) - DECLARE_SHARED_PTR(PositionIncrementAttribute) + DECLARE_SHARED_PTR(PositionIncrementAttribute) DECLARE_SHARED_PTR(SimpleAnalyzer) DECLARE_SHARED_PTR(SinkFilter) DECLARE_SHARED_PTR(SinkTokenStream) @@ -65,7 +65,7 @@ namespace Lucene DECLARE_SHARED_PTR(WhitespaceAnalyzer) DECLARE_SHARED_PTR(WhitespaceTokenizer) DECLARE_SHARED_PTR(WordlistLoader) - + // document DECLARE_SHARED_PTR(AbstractField) DECLARE_SHARED_PTR(CompressionTools) @@ -263,7 +263,7 @@ namespace Lucene DECLARE_SHARED_PTR(TermVectorsWriter) DECLARE_SHARED_PTR(TermVectorsPositionInfo) DECLARE_SHARED_PTR(WaitQueue) - + // query parser DECLARE_SHARED_PTR(FastCharStream) DECLARE_SHARED_PTR(MultiFieldQueryParser) @@ -272,7 +272,7 @@ namespace Lucene DECLARE_SHARED_PTR(QueryParserConstants) DECLARE_SHARED_PTR(QueryParserToken) DECLARE_SHARED_PTR(QueryParserTokenManager) - + // search DECLARE_SHARED_PTR(AveragePayloadFunction) DECLARE_SHARED_PTR(BooleanClause) @@ -286,7 +286,7 @@ namespace Lucene DECLARE_SHARED_PTR(BucketTable) DECLARE_SHARED_PTR(ByteCache) DECLARE_SHARED_PTR(ByteFieldSource) - DECLARE_SHARED_PTR(ByteParser) + DECLARE_SHARED_PTR(ByteParser) DECLARE_SHARED_PTR(Cache) DECLARE_SHARED_PTR(CachedDfSource) DECLARE_SHARED_PTR(CachingSpanFilter) @@ -480,7 +480,7 @@ namespace Lucene DECLARE_SHARED_PTR(Weight) DECLARE_SHARED_PTR(WildcardQuery) DECLARE_SHARED_PTR(WildcardTermEnum) - + // store DECLARE_SHARED_PTR(BufferedIndexInput) DECLARE_SHARED_PTR(BufferedIndexOutput) @@ -513,7 +513,7 @@ namespace Lucene DECLARE_SHARED_PTR(SimpleFSLockFactory) DECLARE_SHARED_PTR(SingleInstanceLock) DECLARE_SHARED_PTR(SingleInstanceLockFactory) - + // util DECLARE_SHARED_PTR(Attribute) DECLARE_SHARED_PTR(AttributeFactory) diff --git a/include/MMapDirectory.h b/include/MMapDirectory.h index e3104b1f..0cd77d47 100644 --- a/include/MMapDirectory.h +++ b/include/MMapDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,12 +13,12 @@ namespace Lucene { /// File-based {@link Directory} implementation that uses mmap for reading, and {@link SimpleFSIndexOutput} for writing. /// - /// NOTE: memory mapping uses up a portion of the virtual memory address space in your process equal to the size of the + /// NOTE: memory mapping uses up a portion of the virtual memory address space in your process equal to the size of the /// file being mapped. Before using this class, be sure your have plenty of virtual address space. /// - /// NOTE: Accessing this class either directly or indirectly from a thread while it's interrupted can close the - /// underlying channel immediately if at the same time the thread is blocked on IO. The channel will remain closed and - /// subsequent access to {@link MMapDirectory} will throw an exception. + /// NOTE: Accessing this class either directly or indirectly from a thread while it's interrupted can close the + /// underlying channel immediately if at the same time the thread is blocked on IO. The channel will remain closed and + /// subsequent access to {@link MMapDirectory} will throw an exception. class LPPAPI MMapDirectory : public FSDirectory { public: @@ -26,17 +26,17 @@ namespace Lucene /// @param path the path of the directory. /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) MMapDirectory(const String& path, LockFactoryPtr lockFactory = LockFactoryPtr()); - + virtual ~MMapDirectory(); - + LUCENE_CLASS(MMapDirectory); - + public: using FSDirectory::openInput; - + /// Creates an IndexInput for the file with the given name. virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - + /// Creates an IndexOutput for the file with the given name. virtual IndexOutputPtr createOutput(const String& name); }; diff --git a/include/Map.h b/include/Map.h index 3d97d10c..31a24cac 100644 --- a/include/Map.h +++ b/include/Map.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/MapFieldSelector.h b/include/MapFieldSelector.h index f633c207..4d8fc1d2 100644 --- a/include/MapFieldSelector.h +++ b/include/MapFieldSelector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { typedef HashMap MapStringFieldSelectorResult; - + /// A {@link FieldSelector} based on a Map of field names to {@link FieldSelectorResult}s class LPPAPI MapFieldSelector : public FieldSelector { @@ -20,18 +20,18 @@ namespace Lucene /// Create a MapFieldSelector /// @param fieldSelections maps from field names (String) to {@link FieldSelectorResult}s MapFieldSelector(MapStringFieldSelectorResult fieldSelections); - + /// Create a MapFieldSelector /// @param fields fields to LOAD. List of Strings. All other fields are NO_LOAD. MapFieldSelector(Collection fields); - + virtual ~MapFieldSelector(); - + LUCENE_CLASS(MapFieldSelector); - + public: MapStringFieldSelectorResult fieldSelections; - + public: /// Load field according to its associated value in fieldSelections /// @param field a field name diff --git a/include/MapOfSets.h b/include/MapOfSets.h index 768671f4..622855a3 100644 --- a/include/MapOfSets.h +++ b/include/MapOfSets.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,22 +18,22 @@ namespace Lucene public: typedef HashSet set_type; typedef HashMap map_type; - + MapOfSets(map_type m) { theMap = m; } - + protected: map_type theMap; - + public: /// @return direct access to the map backing this object. map_type getMap() { return theMap; } - + /// Adds val to the HashSet associated with key in the HashMap. If key is not already in the map, /// a new HashSet will first be created. /// @return the size of the HashSet associated with key once val is added to it. @@ -53,8 +53,8 @@ namespace Lucene return 1; } } - - /// Adds multiple vals to the HashSet associated with key in the HashMap. If key is not already in + + /// Adds multiple vals to the HashSet associated with key in the HashMap. If key is not already in /// the map, a new HashSet will first be created. /// @return the size of the HashSet associated with key once val is added to it. int32_t putAll(MAPKEY key, set_type vals) diff --git a/include/MappingCharFilter.h b/include/MappingCharFilter.h index b65093e4..cbadcd9f 100644 --- a/include/MappingCharFilter.h +++ b/include/MappingCharFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,25 +18,25 @@ namespace Lucene public: /// Default constructor that takes a {@link CharStream}. MappingCharFilter(NormalizeCharMapPtr normMap, CharStreamPtr in); - + /// Easy-use constructor that takes a {@link Reader}. MappingCharFilter(NormalizeCharMapPtr normMap, ReaderPtr in); - + virtual ~MappingCharFilter(); - + LUCENE_CLASS(MappingCharFilter); - + protected: NormalizeCharMapPtr normMap; Collection buffer; String replacement; int32_t charPointer; int32_t nextCharCounter; - + public: virtual int32_t read(); virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - + protected: int32_t nextChar(); void pushChar(int32_t c); diff --git a/include/MatchAllDocsQuery.h b/include/MatchAllDocsQuery.h index 63df02c8..116fd888 100644 --- a/include/MatchAllDocsQuery.h +++ b/include/MatchAllDocsQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,24 +17,24 @@ namespace Lucene public: /// @param normsField Field used for normalization factor (document boost). Null if nothing. MatchAllDocsQuery(const String& normsField = EmptyString); - + virtual ~MatchAllDocsQuery(); - + LUCENE_CLASS(MatchAllDocsQuery); - + protected: String normsField; - + public: using Query::toString; - + virtual WeightPtr createWeight(SearcherPtr searcher); virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + friend class MatchAllDocsWeight; }; } diff --git a/include/MaxPayloadFunction.h b/include/MaxPayloadFunction.h index a69aa479..e51ae4aa 100644 --- a/include/MaxPayloadFunction.h +++ b/include/MaxPayloadFunction.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,9 +19,9 @@ namespace Lucene public: virtual ~MaxPayloadFunction(); LUCENE_CLASS(MaxPayloadFunction); - + public: - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, double currentScore, double currentPayloadScore); virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); virtual int32_t hashCode(); diff --git a/include/MergeDocIDRemapper.h b/include/MergeDocIDRemapper.h index 3f0e1f3a..6b27d6b2 100644 --- a/include/MergeDocIDRemapper.h +++ b/include/MergeDocIDRemapper.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,17 +11,17 @@ namespace Lucene { - /// Remaps docIDs after a merge has completed, where the merged segments had at least one deletion. - /// This is used to renumber the buffered deletes in IndexWriter when a merge of segments with deletions + /// Remaps docIDs after a merge has completed, where the merged segments had at least one deletion. + /// This is used to renumber the buffered deletes in IndexWriter when a merge of segments with deletions /// commits. class MergeDocIDRemapper : public LuceneObject { public: MergeDocIDRemapper(SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergedDocCount); virtual ~MergeDocIDRemapper(); - + LUCENE_CLASS(MergeDocIDRemapper); - + public: Collection starts; // used for binary search of mapped docID Collection newStarts; // starts, minus the deletes @@ -29,8 +29,8 @@ namespace Lucene int32_t minDocID; // minimum docID that needs renumbering int32_t maxDocID; // 1+ the max docID that needs renumbering int32_t docShift; // total # deleted docs that were compacted by this merge - - public: + + public: int32_t remap(int32_t oldDocID); }; } diff --git a/include/MergePolicy.h b/include/MergePolicy.h index 5ba5beb6..469f3bae 100644 --- a/include/MergePolicy.h +++ b/include/MergePolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,15 +14,15 @@ namespace Lucene /// A MergePolicy determines the sequence of primitive merge operations to be used for overall merge /// and optimize operations. /// - /// Whenever the segments in an index have been altered by {@link IndexWriter}, either the addition of - /// a newly flushed segment, addition of many segments from addIndexes* calls, or a previous merge that - /// may now need to cascade, {@link IndexWriter} invokes {@link #findMerges} to give the MergePolicy a - /// chance to pick merges that are now required. This method returns a {@link MergeSpecification} - /// instance describing the set of merges that should be done, or null if no merges are necessary. - /// When IndexWriter.optimize is called, it calls {@link #findMergesForOptimize} and the MergePolicy + /// Whenever the segments in an index have been altered by {@link IndexWriter}, either the addition of + /// a newly flushed segment, addition of many segments from addIndexes* calls, or a previous merge that + /// may now need to cascade, {@link IndexWriter} invokes {@link #findMerges} to give the MergePolicy a + /// chance to pick merges that are now required. This method returns a {@link MergeSpecification} + /// instance describing the set of merges that should be done, or null if no merges are necessary. + /// When IndexWriter.optimize is called, it calls {@link #findMergesForOptimize} and the MergePolicy /// should then return the necessary merges. /// - /// Note that the policy can return more than one merge at a time. In this case, if the writer is using + /// Note that the policy can return more than one merge at a time. In this case, if the writer is using /// {@link SerialMergeScheduler}, the merges will be run sequentially but if it is using {@link /// ConcurrentMergeScheduler} they will be run concurrently. /// @@ -34,54 +34,54 @@ namespace Lucene public: MergePolicy(IndexWriterPtr writer); virtual ~MergePolicy(); - + LUCENE_CLASS(MergePolicy); - + protected: IndexWriterWeakPtr _writer; - + public: - /// Determine what set of merge operations are now necessary on the index. {@link IndexWriter} calls - /// this whenever there is a change to the segments. This call is always synchronized on the {@link + /// Determine what set of merge operations are now necessary on the index. {@link IndexWriter} calls + /// this whenever there is a change to the segments. This call is always synchronized on the {@link /// IndexWriter} instance so only one thread at a time will call this method. /// @param segmentInfos the total set of segments in the index virtual MergeSpecificationPtr findMerges(SegmentInfosPtr segmentInfos) = 0; - - /// Determine what set of merge operations is necessary in order to optimize the index. {@link - /// IndexWriter} calls this when its {@link IndexWriter#optimize()} method is called. This call is - /// always synchronized on the {@link IndexWriter} instance so only one thread at a time will call + + /// Determine what set of merge operations is necessary in order to optimize the index. {@link + /// IndexWriter} calls this when its {@link IndexWriter#optimize()} method is called. This call is + /// always synchronized on the {@link IndexWriter} instance so only one thread at a time will call /// this method. /// @param segmentInfos the total set of segments in the index /// @param maxSegmentCount requested maximum number of segments in the index (currently this is always 1) - /// @param segmentsToOptimize contains the specific SegmentInfo instances that must be merged away. + /// @param segmentsToOptimize contains the specific SegmentInfo instances that must be merged away. /// This may be a subset of all SegmentInfos. virtual MergeSpecificationPtr findMergesForOptimize(SegmentInfosPtr segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) = 0; - + /// Determine what set of merge operations is necessary in order to expunge all deletes from the index. /// @param segmentInfos the total set of segments in the index virtual MergeSpecificationPtr findMergesToExpungeDeletes(SegmentInfosPtr segmentInfos) = 0; - + /// Release all resources for the policy. virtual void close() = 0; - + /// Returns true if a newly flushed (not from merge) segment should use the compound file format. virtual bool useCompoundFile(SegmentInfosPtr segments, SegmentInfoPtr newSegment) = 0; - + /// Returns true if the doc store files should use the compound file format. - virtual bool useCompoundDocStore(SegmentInfosPtr segments) = 0; + virtual bool useCompoundDocStore(SegmentInfosPtr segments) = 0; }; - + /// OneMerge provides the information necessary to perform an individual primitive merge operation, - /// resulting in a single new segment. The merge spec includes the subset of segments to be merged - /// as well as whether the new segment should use the compound file format. + /// resulting in a single new segment. The merge spec includes the subset of segments to be merged + /// as well as whether the new segment should use the compound file format. class LPPAPI OneMerge : public LuceneObject { public: OneMerge(SegmentInfosPtr segments, bool useCompoundFile); virtual ~OneMerge(); - + LUCENE_CLASS(OneMerge); - + public: SegmentInfoPtr info; // used by IndexWriter bool mergeDocStores; // used by IndexWriter @@ -92,43 +92,43 @@ namespace Lucene int32_t maxNumSegmentsOptimize; // used by IndexWriter Collection readers; // used by IndexWriter Collection readersClone; // used by IndexWriter - + SegmentInfosPtr segments; bool useCompoundFile; bool aborted; LuceneException error; - + public: /// Record that an exception occurred while executing this merge void setException(const LuceneException& error); - + /// Retrieve previous exception set by {@link #setException}. LuceneException getException(); - + /// Mark this merge as aborted. If this is called before the merge is committed then the merge will not be committed. void abort(); - + /// Returns true if this merge was aborted. bool isAborted(); - + void checkAborted(DirectoryPtr dir); - + String segString(DirectoryPtr dir); }; - - /// A MergeSpecification instance provides the information necessary to perform multiple merges. + + /// A MergeSpecification instance provides the information necessary to perform multiple merges. /// It simply contains a list of {@link OneMerge} instances. class LPPAPI MergeSpecification : public LuceneObject { public: MergeSpecification(); virtual ~MergeSpecification(); - + LUCENE_CLASS(MergeSpecification); - + public: Collection merges; - + public: void add(OneMergePtr merge); String segString(DirectoryPtr dir); diff --git a/include/MergeScheduler.h b/include/MergeScheduler.h index 25825dcd..88bf762b 100644 --- a/include/MergeScheduler.h +++ b/include/MergeScheduler.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,13 +17,13 @@ namespace Lucene { public: virtual ~MergeScheduler(); - + LUCENE_CLASS(MergeScheduler); - + public: /// Run the merges provided by {@link IndexWriter#getNextMerge()}. virtual void merge(IndexWriterPtr writer) = 0; - + /// Close this MergeScheduler. virtual void close() = 0; }; diff --git a/include/MinPayloadFunction.h b/include/MinPayloadFunction.h index c15c098a..e5558c19 100644 --- a/include/MinPayloadFunction.h +++ b/include/MinPayloadFunction.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene public: virtual ~MinPayloadFunction(); LUCENE_CLASS(MinPayloadFunction); - + public: - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, double currentScore, double currentPayloadScore); virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); virtual int32_t hashCode(); diff --git a/include/MiscUtils.h b/include/MiscUtils.h index 7227b930..29f2b744 100644 --- a/include/MiscUtils.h +++ b/include/MiscUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,43 +22,43 @@ namespace Lucene static const uint64_t DOUBLE_EXPONENT_MASK; static const uint64_t DOUBLE_MANTISSA_MASK; static const uint64_t DOUBLE_NAN_BITS; - + public: /// Return given time in milliseconds. static uint64_t getTimeMillis(boost::posix_time::ptime time); - + /// Returns the current time in milliseconds. static uint64_t currentTimeMillis(); - - /// This over-allocates proportional to the list size, making room for additional growth. + + /// 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(). /// The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... static int32_t getNextSize(int32_t targetSize); - - /// Only reallocate if we are "substantially" smaller. This saves us from "running hot" (constantly + + /// Only reallocate if we are "substantially" smaller. This saves us from "running hot" (constantly /// making a bit bigger then a bit smaller, over and over) static int32_t getShrinkSize(int32_t currentSize, int32_t targetSize); - - /// Compares two byte[] arrays, element by element, and returns the number of elements common to + + /// Compares two byte[] arrays, element by element, and returns the number of elements common to /// both arrays. /// @param bytes1 The first byte[] to compare /// @param bytes2 The second byte[] to compare /// @return The number of common elements. static int32_t bytesDifference(uint8_t* bytes1, int32_t len1, uint8_t* bytes2, int32_t len2); - + template static int32_t hashLucene(TYPE type) { return type->hashCode(); } - + template static int32_t hashNumeric(TYPE type) { return type; } - + template static int32_t hashCode(ITER first, ITER last, PRED pred) { @@ -67,73 +67,73 @@ namespace Lucene code = code * 31 + pred(*hash); return code; } - + /// Returns hash of chars in range start (inclusive) to end (inclusive) static int32_t hashCode(const wchar_t* array, int32_t start, int32_t end); - + /// Returns hash of bytes in range start (inclusive) to end (inclusive) static int32_t hashCode(const uint8_t* array, int32_t start, int32_t end); - + /// Returns hash code of given boolean static int32_t hashCode(bool value); - + /// Copy elements from on buffer to another template static void arrayCopy(SOURCE source, int32_t sourceOffset, DEST dest, int32_t destOffset, int32_t length) { std::copy(source + sourceOffset, source + sourceOffset + length, dest + destOffset); } - + /// Fill buffer with given element template static void arrayFill(DEST dest, int32_t destFrom, int32_t destTo, FILL value) { std::fill(dest + destFrom, dest + destTo, value); } - - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "single format" bit layout. + + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "single format" bit layout. static int32_t doubleToIntBits(double value); - - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "single format" bit layout, preserving Not-a-Number (NaN) values. + + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "single format" bit layout, preserving Not-a-Number (NaN) values. static int32_t doubleToRawIntBits(double value); - - /// Returns the float value corresponding to a given bit representation. The argument is considered to be a - /// representation of a floating-point value according to the IEEE 754 floating-point "single format" bit layout. + + /// Returns the float value corresponding to a given bit representation. The argument is considered to be a + /// representation of a floating-point value according to the IEEE 754 floating-point "single format" bit layout. static double intBitsToDouble(int32_t bits); - - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "double format" bit layout. + + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "double format" bit layout. static int64_t doubleToLongBits(double value); - - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "double format" bit layout, preserving Not-a-Number (NaN) values. + + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "double format" bit layout, preserving Not-a-Number (NaN) values. static int64_t doubleToRawLongBits(double value); - - /// Returns the double value corresponding to a given bit representation. The argument is considered to be a - /// representation of a floating-point value according to the IEEE 754 floating-point "double format" bit layout. + + /// Returns the double value corresponding to a given bit representation. The argument is considered to be a + /// representation of a floating-point value according to the IEEE 754 floating-point "double format" bit layout. static double longBitsToDouble(int64_t bits); - + /// Returns true if the specified number is infinitely large in magnitude, false otherwise. static bool isInfinite(double value); - + /// Returns true if this Double value is a Not-a-Number (NaN), false otherwise. static bool isNaN(double value); - + /// Return whether given Lucene object is of a specified type template static bool typeOf(LuceneObjectPtr object) { return boost::dynamic_pointer_cast(object).get() != NULL; } - + /// Return whether given Lucene objects are of equal type. static bool equalTypes(LuceneObjectPtr first, LuceneObjectPtr second); - + /// Perform unsigned right-shift (left bits are zero filled) static int64_t unsignedShift(int64_t num, int64_t shift); - + /// Perform unsigned right-shift (left bits are zero filled) static int32_t unsignedShift(int32_t num, int32_t shift); }; diff --git a/include/MultiFieldQueryParser.h b/include/MultiFieldQueryParser.h index 252e75bb..bcf72c5a 100644 --- a/include/MultiFieldQueryParser.h +++ b/include/MultiFieldQueryParser.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,10 +16,10 @@ namespace Lucene class LPPAPI MultiFieldQueryParser : public QueryParser { public: - /// Creates a MultiFieldQueryParser. Allows passing of a map with term to Boost, and the boost to + /// Creates a MultiFieldQueryParser. Allows passing of a map with term to Boost, and the boost to /// apply to each term. /// - /// It will, when parse(String query) is called, construct a query like this (assuming the query + /// It will, when parse(String query) is called, construct a query like this (assuming the query /// consists of two terms and you specify the two fields title and body): ///
             /// (title:term1 body:term1) (title:term2 body:term2)
    @@ -29,18 +29,18 @@ namespace Lucene
             /// 
             /// +(title:term1 body:term1) +(title:term2 body:term2)
             /// 
    - /// + /// /// When you pass a boost (title=>5 body=>10) you can get: ///
             /// +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
             /// 
    /// - /// In other words, all the query's terms must appear, but it doesn't matter in what fields they + /// In other words, all the query's terms must appear, but it doesn't matter in what fields they /// appear. MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, AnalyzerPtr analyzer, MapStringDouble boosts); - - /// Creates a MultiFieldQueryParser. It will, when parse(String query) is called, construct a - /// query like this (assuming the query consists of two terms and you specify the two fields + + /// Creates a MultiFieldQueryParser. It will, when parse(String query) is called, construct a + /// query like this (assuming the query consists of two terms and you specify the two fields /// title and body): ///
             /// (title:term1 body:term1) (title:term2 body:term2)
    @@ -51,21 +51,21 @@ namespace Lucene
             /// +(title:term1 body:term1) +(title:term2 body:term2)
             /// 
    /// - /// In other words, all the query's terms must appear, but it doesn't matter in what fields they + /// In other words, all the query's terms must appear, but it doesn't matter in what fields they /// appear. MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, AnalyzerPtr analyzer); - + virtual ~MultiFieldQueryParser(); - + LUCENE_CLASS(MultiFieldQueryParser); - + protected: Collection fields; MapStringDouble boosts; - + public: using QueryParser::parse; - + /// Parses a query which searches on the fields specified. /// /// If x fields are specified, this effectively constructs: @@ -77,8 +77,8 @@ namespace Lucene /// @param fields Fields to search on /// @param analyzer Analyzer to use static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, AnalyzerPtr analyzer); - - /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as + + /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as /// required, and others as prohibited. /// ///
    @@ -99,8 +99,8 @@ namespace Lucene
             /// @param flags Flags describing the fields
             /// @param analyzer Analyzer to use
             static QueryPtr parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, AnalyzerPtr analyzer);
    -        
    -        /// Parses a query, searching on the fields specified.  Use this if you need to specify certain fields as 
    +
    +        /// Parses a query, searching on the fields specified.  Use this if you need to specify certain fields as
             /// required, and others as prohibited.
             ///
             /// 
    @@ -122,12 +122,12 @@ namespace Lucene
             /// @param flags Flags describing the fields
             /// @param analyzer Analyzer to use
             static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, AnalyzerPtr analyzer);
    -    
    +
         protected:
             virtual QueryPtr getFieldQuery(const String& field, const String& queryText, int32_t slop);
             virtual QueryPtr getFieldQuery(const String& field, const String& queryText);
             void applySlop(QueryPtr query, int32_t slop);
    -        
    +
             virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity);
             virtual QueryPtr getPrefixQuery(const String& field, const String& termStr);
             virtual QueryPtr getWildcardQuery(const String& field, const String& termStr);
    diff --git a/include/MultiLevelSkipListReader.h b/include/MultiLevelSkipListReader.h
    index ae0f0ce8..e1358046 100644
    --- a/include/MultiLevelSkipListReader.h
    +++ b/include/MultiLevelSkipListReader.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -13,108 +13,108 @@ namespace Lucene
     {
         /// This abstract class reads skip lists with multiple levels.
         ///
    -    /// See {@link MultiLevelSkipListWriter} for the information about the encoding of the multi level skip lists. 
    +    /// See {@link MultiLevelSkipListWriter} for the information about the encoding of the multi level skip lists.
         ///
    -    /// Subclasses must implement the abstract method {@link #readSkipData(int, IndexInput)} which defines the 
    +    /// Subclasses must implement the abstract method {@link #readSkipData(int, IndexInput)} which defines the
         /// actual format of the skip data.
         class MultiLevelSkipListReader : public LuceneObject
         {
         public:
             MultiLevelSkipListReader(IndexInputPtr skipStream, int32_t maxSkipLevels, int32_t skipInterval);
             virtual ~MultiLevelSkipListReader();
    -        
    +
             LUCENE_CLASS(MultiLevelSkipListReader);
    -    
    +
         protected:
             /// the maximum number of skip levels possible for this index
    -        int32_t maxNumberOfSkipLevels; 
    -        
    +        int32_t maxNumberOfSkipLevels;
    +
             /// number of levels in this skip list
             int32_t numberOfSkipLevels;
    -        
    -        /// Defines the number of top skip levels to buffer in memory.  Reducing this number results in less 
    -        /// memory usage, but possibly slower performance due to more random I/Os.  Please notice that the space 
    -        /// each level occupies is limited by the skipInterval. The top level can not contain more than 
    +
    +        /// Defines the number of top skip levels to buffer in memory.  Reducing this number results in less
    +        /// memory usage, but possibly slower performance due to more random I/Os.  Please notice that the space
    +        /// each level occupies is limited by the skipInterval. The top level can not contain more than
             /// skipLevel entries, the second top level can not contain more than skipLevel^2 entries and so forth.
             int32_t numberOfLevelsToBuffer;
    -        
    +
             int32_t docCount;
             bool haveSkipped;
    -        
    +
             Collection skipStream; // skipStream for each level
             Collection skipPointer; // the start pointer of each skip level
             Collection skipInterval; // skipInterval of each level
             Collection numSkipped; // number of docs skipped per level
    -        
    -        Collection skipDoc; // doc id of current skip entry per level 
    +
    +        Collection skipDoc; // doc id of current skip entry per level
             int32_t lastDoc; // doc id of last read skip entry with docId <= target
             Collection childPointer; // child pointer of current skip entry per level
             int64_t lastChildPointer; // childPointer of last read skip entry with docId <= target
    -        
    +
             bool inputIsBuffered;
    -    
    +
         public:
             /// Returns the id of the doc to which the last call of {@link #skipTo(int)} has skipped.
             virtual int32_t getDoc();
    -        
    -        /// Skips entries to the first beyond the current whose document number is greater than or equal to 
    -        /// target. Returns the current doc count. 
    +
    +        /// Skips entries to the first beyond the current whose document number is greater than or equal to
    +        /// target. Returns the current doc count.
             virtual int32_t skipTo(int32_t target);
    -        
    +
             virtual void close();
    -        
    +
             /// Initializes the reader.
             virtual void init(int64_t skipPointer, int32_t df);
    -    
    +
         protected:
             virtual bool loadNextSkip(int32_t level);
    -        
    +
             /// Seeks the skip entry on the given level
             virtual void seekChild(int32_t level);
    -        
    +
             /// Loads the skip levels
             virtual void loadSkipLevels();
    -        
    +
             /// Subclasses must implement the actual skip data encoding in this method.
             ///
             /// @param level the level skip data shall be read from
             /// @param skipStream the skip stream to read from
             virtual int32_t readSkipData(int32_t level, IndexInputPtr skipStream) = 0;
    -        
    +
             /// Copies the values of the last read skip entry on this level
             virtual void setLastSkipData(int32_t level);
         };
    -    
    +
         /// Used to buffer the top skip levels
         class SkipBuffer : public IndexInput
         {
         public:
             SkipBuffer(IndexInputPtr input, int32_t length);
             virtual ~SkipBuffer();
    -        
    +
             LUCENE_CLASS(SkipBuffer);
    -            
    +
         protected:
             ByteArray data;
             int64_t pointer;
             int32_t pos;
    -        
    +
         public:
             /// Closes the stream to further operations.
             virtual void close();
    -        
    +
             /// Returns the current position in this file, where the next read will occur.
             virtual int64_t getFilePointer();
    -        
    +
             /// The number of bytes in the file.
             virtual int64_t length();
    -        
    +
             /// Reads and returns a single byte.
             virtual uint8_t readByte();
    -        
    +
             /// Reads a specified number of bytes into an array at the specified offset.
             virtual void readBytes(uint8_t* b, int32_t offset, int32_t length);
    -        
    +
             /// Sets current position in this file, where the next read will occur.
             virtual void seek(int64_t pos);
         };
    diff --git a/include/MultiLevelSkipListWriter.h b/include/MultiLevelSkipListWriter.h
    index e1b3a501..e8b57bec 100644
    --- a/include/MultiLevelSkipListWriter.h
    +++ b/include/MultiLevelSkipListWriter.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -16,56 +16,56 @@ namespace Lucene
         /// Example for skipInterval = 3:
         ///
         ///                                                     c            (skip level 2)
    -    ///                 c                 c                 c            (skip level 1) 
    +    ///                 c                 c                 c            (skip level 1)
         ///     x     x     x     x     x     x     x     x     x     x      (skip level 0)
         /// d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d  (posting list)
         ///     3     6     9     12    15    18    21    24    27    30     (df)
    -    /// 
    +    ///
         /// d - document
         /// x - skip data
         /// c - skip data with child pointer
    -    /// 
    +    ///
         /// Skip level i contains every skipInterval-th entry from skip level i-1.
         /// Therefore the number of entries on level i is: floor(df / ((skipInterval ^ (i + 1))).
    -    /// 
    +    ///
         /// Each skip entry on a level i>0 contains a pointer to the corresponding skip entry in list i-1.
         /// This guarantees a logarithmic amount of skips to find the target document.
    -    /// 
    -    /// While this class takes care of writing the different skip levels, subclasses must define the 
    +    ///
    +    /// While this class takes care of writing the different skip levels, subclasses must define the
         /// actual format of the skip data.
         class MultiLevelSkipListWriter : public LuceneObject
         {
         public:
             MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df);
             virtual ~MultiLevelSkipListWriter();
    -        
    +
             LUCENE_CLASS(MultiLevelSkipListWriter);
    -    
    +
         protected:
             /// number of levels in this skip list
             int32_t numberOfSkipLevels;
    -        
    +
             /// the skip interval in the list with level = 0
             int32_t skipInterval;
    -        
    -        /// for every skip level a different buffer is used 
    +
    +        /// for every skip level a different buffer is used
             Collection skipBuffer;
    -    
    +
         public:
             /// Writes the current skip data to the buffers. The current document frequency determines
    -        /// the max level is skip data is to be written to. 
    -        /// @param df the current document frequency 
    +        /// the max level is skip data is to be written to.
    +        /// @param df the current document frequency
             void bufferSkip(int32_t df);
    -        
    +
             /// Writes the buffered skip lists to the given output.
    -        /// @param output the IndexOutput the skip lists shall be written to 
    +        /// @param output the IndexOutput the skip lists shall be written to
             /// @return the pointer the skip list starts
             int64_t writeSkip(IndexOutputPtr output);
    -    
    +
         protected:
             void init();
             virtual void resetSkip();
    -        
    +
             /// Subclasses must implement the actual skip data encoding in this method.
             /// @param level the level skip data shall be writing for
             /// @param skipBuffer the skip buffer to write to
    diff --git a/include/MultiPhraseQuery.h b/include/MultiPhraseQuery.h
    index 52656288..bd8f422f 100644
    --- a/include/MultiPhraseQuery.h
    +++ b/include/MultiPhraseQuery.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -12,67 +12,67 @@
     namespace Lucene
     {
         /// MultiPhraseQuery is a generalized version of PhraseQuery, with an added method {@link #add(Term[])}.
    -    /// To use this class, to search for the phrase "Microsoft app*" first use add(Term) on the term "Microsoft", 
    -    /// then find all terms that have "app" as prefix using IndexReader.terms(Term), and use 
    +    /// To use this class, to search for the phrase "Microsoft app*" first use add(Term) on the term "Microsoft",
    +    /// then find all terms that have "app" as prefix using IndexReader.terms(Term), and use
         /// MultiPhraseQuery.add(Term[] terms) to add them to the query.
         class LPPAPI MultiPhraseQuery : public Query
         {
         public:
             MultiPhraseQuery();
             virtual ~MultiPhraseQuery();
    -    
    +
             LUCENE_CLASS(MultiPhraseQuery);
    -    
    +
         protected:
             String field;
             Collection< Collection > termArrays;
    -        Collection positions;        
    +        Collection positions;
             int32_t slop;
    -    
    +
         public:
             using Query::toString;
    -        
    +
             /// Sets the phrase slop for this query.
             /// @see PhraseQuery#setSlop(int32_t)
             void setSlop(int32_t s);
    -        
    +
             /// Gets the phrase slop for this query.
             /// @see PhraseQuery#getSlop()
             int32_t getSlop();
    -        
    +
             /// Add a single term at the next position in the phrase.
             /// @see PhraseQuery#add(Term)
             void add(TermPtr term);
    -        
    +
             /// Add multiple terms at the next position in the phrase.  Any of the terms may match.
             /// @see PhraseQuery#add(Term)
             void add(Collection terms);
    -        
    +
             /// Allows to specify the relative position of terms within the phrase.
             /// @see PhraseQuery#add(Term, int)
             void add(Collection terms, int32_t position);
    -        
    +
             /// Returns a List of the terms in the multiphrase. Do not modify the List or its contents.
             Collection< Collection > getTermArrays();
    -        
    +
             /// Returns the relative positions of terms in this phrase.
             Collection getPositions();
    -        
    +
             virtual void extractTerms(SetTerm terms);
             virtual QueryPtr rewrite(IndexReaderPtr reader);
             virtual WeightPtr createWeight(SearcherPtr searcher);
    -        
    +
             /// Prints a user-readable version of this query.
             virtual String toString(const String& field);
    -        
    +
             virtual bool equals(LuceneObjectPtr other);
             virtual int32_t hashCode();
             virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr());
    -    
    +
         protected:
             int32_t termArraysHashCode();
             bool termArraysEquals(Collection< Collection > first, Collection< Collection > second);
    -        
    +
             friend class MultiPhraseWeight;
         };
     }
    diff --git a/include/MultiReader.h b/include/MultiReader.h
    index 138507bb..6264966e 100644
    --- a/include/MultiReader.h
    +++ b/include/MultiReader.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -15,16 +15,16 @@ namespace Lucene
         class LPPAPI MultiReader : public IndexReader
         {
         public:
    -        /// Construct a MultiReader aggregating the named set of (sub)readers.  Directory locking for delete, 
    +        /// Construct a MultiReader aggregating the named set of (sub)readers.  Directory locking for delete,
             /// undeleteAll, and setNorm operations is left to the subreaders.
             /// @param closeSubReaders indicates whether the subreaders should be closed when this MultiReader is closed
             /// @param subReaders set of (sub)readers
             MultiReader(Collection subReaders, bool closeSubReaders = true);
    -        
    +
             virtual ~MultiReader();
    -        
    +
             LUCENE_CLASS(MultiReader);
    -            
    +
         protected:
             Collection subReaders;
             Collection starts; // 1st docno for each segment
    @@ -33,107 +33,107 @@ namespace Lucene
             int32_t _maxDoc;
             int32_t _numDocs;
             bool _hasDeletions;
    -    
    +
         public:
             /// Tries to reopen the subreaders.
             ///
    -        /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader), 
    +        /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader),
             /// then a new MultiReader instance is returned, otherwise this instance is returned.
             ///
    -        /// A re-opened instance might share one or more subreaders with the old instance. Index modification 
    -        /// operations result in undefined behavior when performed before the old instance is closed. (see {@link 
    +        /// A re-opened instance might share one or more subreaders with the old instance. Index modification
    +        /// operations result in undefined behavior when performed before the old instance is closed. (see {@link
             /// IndexReader#reopen()}).
             ///
    -        /// If subreaders are shared, then the reference count of those readers is increased to ensure that the 
    +        /// If subreaders are shared, then the reference count of those readers is increased to ensure that the
             /// subreaders remain open until the last referring reader is closed.
             virtual IndexReaderPtr reopen();
    -        
    +
             /// Clones the subreaders. (see {@link IndexReader#clone()}).
             ///
    -        /// If subreaders are shared, then the reference count of those readers is increased to ensure that the 
    +        /// If subreaders are shared, then the reference count of those readers is increased to ensure that the
             /// subreaders remain open until the last referring reader is closed.
             virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr());
    -        
    +
             virtual Collection getTermFreqVectors(int32_t docNumber);
             virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field);
             virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper);
             virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper);
    -        
    +
             virtual bool isOptimized();
    -        
    +
             /// Returns the number of documents in this index.
             virtual int32_t numDocs();
    -        
    +
             /// Returns one greater than the largest possible document number.
             virtual int32_t maxDoc();
    -        
    +
             /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine
    -        /// what {@link Field}s to load and how they should be loaded. 
    +        /// what {@link Field}s to load and how they should be loaded.
             virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector);
    -        
    -        /// Returns true if document n has been deleted 
    +
    +        /// Returns true if document n has been deleted
             virtual bool isDeleted(int32_t n);
    -        
    +
             /// Returns true if any documents have been deleted
             virtual bool hasDeletions();
    -        
    +
             /// Returns true if there are norms stored for this field.
             virtual bool hasNorms(const String& field);
    -        
    +
             /// Returns the byte-encoded normalization factor for the named field of every document.
             virtual ByteArray norms(const String& field);
    -        
    +
             /// Reads the byte-encoded normalization factor for the named field of every document.
             virtual void norms(const String& field, ByteArray norms, int32_t offset);
    -        
    +
             /// Returns an enumeration of all the terms in the index.
             virtual TermEnumPtr terms();
    -        
    +
             /// Returns an enumeration of all terms starting at a given term.
             virtual TermEnumPtr terms(TermPtr t);
    -        
    +
             /// Returns the number of documents containing the term t.
             virtual int32_t docFreq(TermPtr t);
    -        
    +
             /// Returns an unpositioned {@link TermDocs} enumerator.
             virtual TermDocsPtr termDocs();
    -        
    +
             /// Returns an unpositioned {@link TermPositions} enumerator.
             virtual TermPositionsPtr termPositions();
    -        
    -        /// Get a list of unique field names that exist in this index and have the specified field option 
    +
    +        /// Get a list of unique field names that exist in this index and have the specified field option
             /// information.
             virtual HashSet getFieldNames(FieldOption fieldOption);
    -        
    +
             /// Checks recursively if all subreaders are up to date.
             virtual bool isCurrent();
    -        
    +
             /// Not implemented.
             virtual int64_t getVersion();
    -        
    +
             /// Returns the sequential sub readers that this reader is logically composed of.
             virtual Collection getSequentialSubReaders();
    -        
    +
         protected:
             /// If clone is true then we clone each of the subreaders
             /// @param doClone
             /// @return New IndexReader, or same one (this) if reopen/clone is not necessary
             IndexReaderPtr doReopen(bool doClone);
    -        
    +
             /// Implements deletion of the document numbered docNum.
             virtual void doDelete(int32_t docNum);
    -        
    +
             /// Implements actual undeleteAll() in subclass.
             virtual void doUndeleteAll();
    -        
    +
             /// Find reader for doc n
             int32_t readerIndex(int32_t n);
    -        
    +
             /// Implements setNorm in subclass.
             virtual void doSetNorm(int32_t doc, const String& field, uint8_t value);
    -        
    +
             virtual void doCommit(MapStringString commitUserData);
    -        
    +
             /// Implements close.
             virtual void doClose();
         };
    diff --git a/include/MultiSearcher.h b/include/MultiSearcher.h
    index 1a7e7b31..d79a1efd 100644
    --- a/include/MultiSearcher.h
    +++ b/include/MultiSearcher.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -14,50 +14,50 @@ namespace Lucene
     {
         /// Implements search over a set of Searchables.
         ///
    -    /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link 
    +    /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link
         /// #search(QueryPtr, FilterPtr, int32_t)} methods.
         class LPPAPI MultiSearcher : public Searcher
         {
         public:
             /// Creates a searcher which searches searchers.
             MultiSearcher(Collection searchables);
    -        
    +
             virtual ~MultiSearcher();
    -    
    +
             LUCENE_CLASS(MultiSearcher);
    -    
    +
         protected:
             Collection searchables;
             Collection starts;
             int32_t _maxDoc;
    -    
    +
         public:
             using Searcher::search;
    -        
    +
             /// Return the array of {@link Searchable}s this searches.
             Collection getSearchables();
    -        
    +
             virtual void close();
             virtual int32_t docFreq(TermPtr term);
             virtual DocumentPtr doc(int32_t n);
             virtual DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector);
    -        
    +
             /// Returns index of the searcher for document n in the array used to construct this searcher.
             int32_t subSearcher(int32_t n);
    -        
    +
             /// Returns the document number of document n within its sub-index.
             int32_t subDoc(int32_t n);
    -        
    +
             virtual int32_t maxDoc();
             virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n);
             virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort);
             virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr results);
             virtual QueryPtr rewrite(QueryPtr query);
             virtual ExplanationPtr explain(WeightPtr weight, int32_t doc);
    -        
    +
         protected:
             Collection getStarts();
    -        
    +
             /// Create weight in multiple index scenario.
             ///
             /// Distributed query processing is done in the following steps:
    diff --git a/include/MultiTermQuery.h b/include/MultiTermQuery.h
    index 1ffece5b..c43e928b 100644
    --- a/include/MultiTermQuery.h
    +++ b/include/MultiTermQuery.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -14,124 +14,124 @@ namespace Lucene
         /// An abstract {@link Query} that matches documents containing a subset of terms provided by a {@link
         /// FilteredTermEnum} enumeration.
         ///
    -    /// This query cannot be used directly; you must subclass it and define {@link #getEnum} to provide a 
    +    /// This query cannot be used directly; you must subclass it and define {@link #getEnum} to provide a
         /// {@link FilteredTermEnum} that iterates through the terms to be matched.
         ///
         /// NOTE: if {@link #setRewriteMethod} is either {@link #CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE} or {@link
    -    /// #SCORING_BOOLEAN_QUERY_REWRITE}, you may encounter a {@link BooleanQuery.TooManyClauses} exception 
    -    /// during searching, which happens when the number of terms to be searched exceeds {@link 
    -    /// BooleanQuery#getMaxClauseCount()}.  Setting {@link #setRewriteMethod} to {@link 
    +    /// #SCORING_BOOLEAN_QUERY_REWRITE}, you may encounter a {@link BooleanQuery.TooManyClauses} exception
    +    /// during searching, which happens when the number of terms to be searched exceeds {@link
    +    /// BooleanQuery#getMaxClauseCount()}.  Setting {@link #setRewriteMethod} to {@link
         /// #CONSTANT_SCORE_FILTER_REWRITE} prevents this.
         ///
         /// The recommended rewrite method is {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT}: it doesn't spend CPU
         /// computing unhelpful scores, and it tries to pick the most performant rewrite method given the query.
         ///
    -    /// Note that {@link QueryParser} produces MultiTermQueries using {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} 
    +    /// Note that {@link QueryParser} produces MultiTermQueries using {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT}
         /// by default.
         class LPPAPI MultiTermQuery : public Query
         {
         public:
             MultiTermQuery();
             virtual ~MultiTermQuery();
    -    
    +
             LUCENE_CLASS(MultiTermQuery);
    -    
    +
         protected:
             RewriteMethodPtr rewriteMethod;
             int32_t numberOfTerms;
    -    
    +
         public:
    -        /// A rewrite method that first creates a private Filter, by visiting each term in sequence and marking 
    +        /// A rewrite method that first creates a private Filter, by visiting each term in sequence and marking
             /// all docs for that term.  Matching documents are assigned a constant score equal to the query's boost.
             ///
    -        /// This method is faster than the BooleanQuery rewrite methods when the number of matched terms or matched 
    +        /// This method is faster than the BooleanQuery rewrite methods when the number of matched terms or matched
             /// documents is non-trivial.  Also, it will never hit an errant TooManyClauses exception.
             ///
             /// @see #setRewriteMethod
             static RewriteMethodPtr CONSTANT_SCORE_FILTER_REWRITE();
    -        
    +
             /// A rewrite method that first translates each term into {@link BooleanClause.Occur#SHOULD} clause in a
             /// BooleanQuery, and keeps the scores as computed by the query.  Note that typically such scores are
    -        /// meaningless to the user, and require non-trivial CPU to compute, so it's almost always better to use 
    +        /// meaningless to the user, and require non-trivial CPU to compute, so it's almost always better to use
             /// {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} instead.
             ///
    -        /// NOTE: This rewrite method will hit {@link BooleanQuery.TooManyClauses} if the number of terms exceeds 
    +        /// NOTE: This rewrite method will hit {@link BooleanQuery.TooManyClauses} if the number of terms exceeds
             /// {@link BooleanQuery#getMaxClauseCount}.
             ///
             /// @see #setRewriteMethod
             static RewriteMethodPtr SCORING_BOOLEAN_QUERY_REWRITE();
    -        
    +
             /// Like {@link #SCORING_BOOLEAN_QUERY_REWRITE} except scores are not computed.  Instead, each matching
             /// document receives a constant score equal to the query's boost.
             ///
    -        /// NOTE: This rewrite method will hit TooManyClauses if the number of terms exceeds {@link 
    +        /// NOTE: This rewrite method will hit TooManyClauses if the number of terms exceeds {@link
             /// BooleanQuery#getMaxClauseCount}.
             ///
             /// @see #setRewriteMethod
             static RewriteMethodPtr CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE();
    -        
    -        /// Read-only default instance of {@link ConstantScoreAutoRewrite}, with {@link 
    +
    +        /// Read-only default instance of {@link ConstantScoreAutoRewrite}, with {@link
             /// ConstantScoreAutoRewrite#setTermCountCutoff} set to {@link ConstantScoreAutoRewrite#DEFAULT_TERM_COUNT_CUTOFF}
             /// and {@link ConstantScoreAutoRewrite#setDocCountPercent} set to {@link
    -        /// ConstantScoreAutoRewrite#DEFAULT_DOC_COUNT_PERCENT}.  Note that you cannot alter the configuration of 
    +        /// ConstantScoreAutoRewrite#DEFAULT_DOC_COUNT_PERCENT}.  Note that you cannot alter the configuration of
             /// this instance; you'll need to create a private instance instead.
             static RewriteMethodPtr CONSTANT_SCORE_AUTO_REWRITE_DEFAULT();
    -        
    -        /// Return the number of unique terms visited during execution of the query.  If there are many of them, 
    +
    +        /// Return the number of unique terms visited during execution of the query.  If there are many of them,
             /// you may consider using another query type or optimize your total term count in index.
             ///
    -        /// This method is not thread safe, be sure to only call it when no query is running!  If you re-use the 
    -        /// same query instance for another search, be sure to first reset the term counter with {@link 
    +        /// This method is not thread safe, be sure to only call it when no query is running!  If you re-use the
    +        /// same query instance for another search, be sure to first reset the term counter with {@link
             /// #clearTotalNumberOfTerms}.
             ///
    -        /// On optimized indexes / no MultiReaders, you get the correct number of unique terms for the whole index. 
    -        /// Use this number to compare different queries.  For non-optimized indexes this number can also be achieved 
    -        /// in non-constant-score mode.  In constant-score mode you get the total number of terms seeked for all 
    +        /// On optimized indexes / no MultiReaders, you get the correct number of unique terms for the whole index.
    +        /// Use this number to compare different queries.  For non-optimized indexes this number can also be achieved
    +        /// in non-constant-score mode.  In constant-score mode you get the total number of terms seeked for all
             /// segments / sub-readers.
             /// @see #clearTotalNumberOfTerms
             int32_t getTotalNumberOfTerms();
    -        
    +
             /// Resets the counting of unique terms.  Do this before executing the query/filter.
             /// @see #getTotalNumberOfTerms
             void clearTotalNumberOfTerms();
    -        
    +
             virtual QueryPtr rewrite(IndexReaderPtr reader);
    -        
    +
             /// @see #setRewriteMethod
             virtual RewriteMethodPtr getRewriteMethod();
    -        
    -        /// Sets the rewrite method to be used when executing the query.  You can use one of the four core methods, 
    +
    +        /// Sets the rewrite method to be used when executing the query.  You can use one of the four core methods,
             /// or implement your own subclass of {@link RewriteMethod}.
             virtual void setRewriteMethod(RewriteMethodPtr method);
    -        
    +
             virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr());
             virtual int32_t hashCode();
             virtual bool equals(LuceneObjectPtr other);
    -    
    +
         protected:
             /// Construct the enumeration to be used, expanding the pattern term.
             virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader) = 0;
    -        
    +
             void incTotalNumberOfTerms(int32_t inc);
    -        
    +
             friend class MultiTermQueryWrapperFilter;
             friend class ScoringBooleanQueryRewrite;
             friend class ConstantScoreAutoRewrite;
         };
    -    
    +
         /// Abstract class that defines how the query is rewritten.
         class LPPAPI RewriteMethod : public LuceneObject
         {
         public:
             virtual ~RewriteMethod();
             LUCENE_CLASS(RewriteMethod);
    -    
    +
         public:
             virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) = 0;
         };
    -    
    -    /// A rewrite method that tries to pick the best constant-score rewrite method based on term and document 
    -    /// counts from the query.  If both the number of terms and documents is small enough, then {@link 
    +
    +    /// A rewrite method that tries to pick the best constant-score rewrite method based on term and document
    +    /// counts from the query.  If both the number of terms and documents is small enough, then {@link
         /// #CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE} is used.  Otherwise, {@link #CONSTANT_SCORE_FILTER_REWRITE} is
         /// used.
         class LPPAPI ConstantScoreAutoRewrite : public RewriteMethod
    @@ -139,39 +139,39 @@ namespace Lucene
         public:
             ConstantScoreAutoRewrite();
             virtual ~ConstantScoreAutoRewrite();
    -        
    +
             LUCENE_CLASS(ConstantScoreAutoRewrite);
    -    
    +
         public:
    -        // Defaults derived from rough tests with a 20.0 million doc Wikipedia index.  With more than 350 terms 
    +        // Defaults derived from rough tests with a 20.0 million doc Wikipedia index.  With more than 350 terms
             // in the query, the filter method is fastest
             static const int32_t DEFAULT_TERM_COUNT_CUTOFF;
    -        
    +
             // If the query will hit more than 1 in 1000 of the docs in the index (0.1%), the filter method is fastest
             static const double DEFAULT_DOC_COUNT_PERCENT;
    -    
    +
         protected:
             int32_t termCountCutoff;
             double docCountPercent;
    -    
    +
         public:
    -        /// If the number of terms in this query is equal to or larger than this setting then {@link 
    +        /// If the number of terms in this query is equal to or larger than this setting then {@link
             /// #CONSTANT_SCORE_FILTER_REWRITE} is used.
             virtual void setTermCountCutoff(int32_t count);
    -        
    +
             /// @see #setTermCountCutoff
             virtual int32_t getTermCountCutoff();
    -        
    -        /// If the number of documents to be visited in the postings exceeds this specified percentage of the 
    +
    +        /// If the number of documents to be visited in the postings exceeds this specified percentage of the
             /// maxDoc() for the index, then {@link #CONSTANT_SCORE_FILTER_REWRITE} is used.
             /// @param percent 0.0 to 100.0
             virtual void setDocCountPercent(double percent);
    -        
    +
             /// @see #setDocCountPercent
             virtual double getDocCountPercent();
    -        
    +
             virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query);
    -        
    +
             virtual int32_t hashCode();
             virtual bool equals(LuceneObjectPtr other);
         };
    diff --git a/include/MultiTermQueryWrapperFilter.h b/include/MultiTermQueryWrapperFilter.h
    index 8026a3aa..afc0f361 100644
    --- a/include/MultiTermQueryWrapperFilter.h
    +++ b/include/MultiTermQueryWrapperFilter.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -13,7 +13,7 @@ namespace Lucene
     {
         /// A wrapper for {@link MultiTermQuery}, that exposes its functionality as a {@link Filter}.
         ///
    -    /// MultiTermQueryWrapperFilter is not designed to be used by itself. Normally you subclass it to 
    +    /// MultiTermQueryWrapperFilter is not designed to be used by itself. Normally you subclass it to
         /// provide a Filter counterpart for a {@link MultiTermQuery} subclass.
         ///
         /// For example, {@link TermRangeFilter} and {@link PrefixFilter} extend MultiTermQueryWrapperFilter.
    @@ -24,33 +24,33 @@ namespace Lucene
         INTERNAL:
             /// Wrap a {@link MultiTermQuery} as a Filter.
             MultiTermQueryWrapperFilter(MultiTermQueryPtr query);
    -        
    +
         public:
             virtual ~MultiTermQueryWrapperFilter();
    -    
    +
             LUCENE_CLASS(MultiTermQueryWrapperFilter);
    -    
    +
         protected:
             MultiTermQueryPtr query;
    -    
    +
         public:
             virtual String toString();
             virtual bool equals(LuceneObjectPtr other);
             virtual int32_t hashCode();
    -        
    +
             /// Return the number of unique terms visited during execution of the filter.  If there are many of them,
             /// you may consider using another filter type or optimize your total term count in index.
             ///
    -        /// This method is not thread safe, be sure to only call it when no filter is running!  If you re-use the 
    -        /// same filter instance for another search, be sure to first reset the term counter with {@link 
    +        /// This method is not thread safe, be sure to only call it when no filter is running!  If you re-use the
    +        /// same filter instance for another search, be sure to first reset the term counter with {@link
             /// #clearTotalNumberOfTerms}.
             /// @see #clearTotalNumberOfTerms
             int32_t getTotalNumberOfTerms();
    -        
    +
             /// Resets the counting of unique terms. Do this before executing the filter.
             /// @see #getTotalNumberOfTerms
             void clearTotalNumberOfTerms();
    -        
    +
             /// Returns a DocIdSet with documents that should be permitted in search results.
             virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader);
         };
    diff --git a/include/MultipleTermPositions.h b/include/MultipleTermPositions.h
    index 18a44427..1dc5a08b 100644
    --- a/include/MultipleTermPositions.h
    +++ b/include/MultipleTermPositions.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -11,22 +11,22 @@
     
     namespace Lucene
     {
    -    /// Allows you to iterate over the {@link TermPositions} for multiple {@link Term}s as a single 
    +    /// Allows you to iterate over the {@link TermPositions} for multiple {@link Term}s as a single
         /// {@link TermPositions}.
         class LPPAPI MultipleTermPositions : public TermPositions, public LuceneObject
         {
         public:
             MultipleTermPositions(IndexReaderPtr indexReader, Collection terms);
             virtual ~MultipleTermPositions();
    -        
    +
             LUCENE_CLASS(MultipleTermPositions);
    -            
    +
         protected:
             int32_t _doc;
             int32_t _freq;
             TermPositionsQueuePtr termPositionsQueue;
             IntQueuePtr posList;
    -    
    +
         public:
             virtual bool next();
             virtual int32_t nextPosition();
    @@ -34,19 +34,19 @@ namespace Lucene
             virtual int32_t doc();
             virtual int32_t freq();
             virtual void close();
    -        
    +
             /// Not implemented.
             virtual void seek(TermPtr term);
    -        
    +
             /// Not implemented.
             virtual void seek(TermEnumPtr termEnum);
    -        
    +
             /// Not implemented.
             virtual int32_t read(Collection docs, Collection freqs);
    -        
    +
             /// Not implemented.
             virtual ByteArray getPayload(ByteArray data, int32_t offset);
    -        
    +
             /// @return false
             virtual bool isPayloadAvailable();
         };
    diff --git a/include/NativeFSLockFactory.h b/include/NativeFSLockFactory.h
    index 75ccb305..8fa8f324 100644
    --- a/include/NativeFSLockFactory.h
    +++ b/include/NativeFSLockFactory.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -16,29 +16,29 @@ namespace Lucene
         class LPPAPI NativeFSLockFactory : public FSLockFactory
         {
         public:
    -        /// Create a NativeFSLockFactory instance, storing lock files into 
    +        /// Create a NativeFSLockFactory instance, storing lock files into
             /// the specified lockDirName.
             /// @param lockDirName where lock files are created.
             NativeFSLockFactory(const String& lockDirName = EmptyString);
             virtual ~NativeFSLockFactory();
    -        
    +
             LUCENE_CLASS(NativeFSLockFactory);
    -                
    +
         public:
             /// Return a new Lock instance identified by lockName.
             /// @param lockName name of the lock to be created.
             virtual LockPtr makeLock(const String& lockName);
    -        
    +
             /// Attempt to clear (forcefully unlock and remove) the
             /// specified lock.  Only call this at a time when you are
             /// certain this lock is no longer in use.
             /// @param lockName name of the lock to be cleared.
             virtual void clearLock(const String& lockName);
    -    
    +
         protected:
    -        /// Simple test to verify locking system is "working".  On NFS, if 
    -        /// it's mis-configured, you can hit long (35 second) timeouts which 
    -        /// cause Lock.obtain to take far too long (it assumes the obtain() 
    +        /// Simple test to verify locking system is "working".  On NFS, if
    +        /// it's mis-configured, you can hit long (35 second) timeouts which
    +        /// cause Lock.obtain to take far too long (it assumes the obtain()
             /// call takes zero time).
             void acquireTestLock();
         };
    diff --git a/include/NearSpansOrdered.h b/include/NearSpansOrdered.h
    index 1345fc76..d34d8d01 100644
    --- a/include/NearSpansOrdered.h
    +++ b/include/NearSpansOrdered.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -11,16 +11,16 @@
     
     namespace Lucene
     {
    -    /// A Spans that is formed from the ordered subspans of a SpanNearQuery where the subspans do not overlap 
    +    /// A Spans that is formed from the ordered subspans of a SpanNearQuery where the subspans do not overlap
         /// and have a maximum slop between them.
         ///
    -    /// The formed spans only contains minimum slop matches.  The matching slop is computed from the distance(s) 
    +    /// The formed spans only contains minimum slop matches.  The matching slop is computed from the distance(s)
         /// between the non overlapping matching Spans.
         ///
         /// Successive matches are always formed from the successive Spans of the SpanNearQuery.
         ///
         /// The formed spans may contain overlaps when the slop is at least 1.  For example, when querying using
    -    /// 
    t1 t2 t3
    + ///
    t1 t2 t3
    /// with slop at least 1, the fragment: ///
    t1 t2 t1 t3 t2 t3
    /// matches twice: @@ -33,64 +33,64 @@ namespace Lucene public: NearSpansOrdered(SpanNearQueryPtr spanNearQuery, IndexReaderPtr reader, bool collectPayloads = true); virtual ~NearSpansOrdered(); - + LUCENE_CLASS(NearSpansOrdered); - + protected: int32_t allowedSlop; bool firstTime; bool more; - + /// The spans in the same order as the SpanNearQuery Collection subSpans; - + /// Indicates that all subSpans have same doc() bool inSameDoc; - + int32_t matchDoc; int32_t matchStart; int32_t matchEnd; Collection matchPayload; - + Collection subSpansByDoc; SpanNearQueryPtr query; bool collectPayloads; - + public: virtual int32_t doc(); virtual int32_t start(); virtual int32_t end(); - + Collection getSubSpans(); - + virtual Collection getPayload(); virtual bool isPayloadAvailable(); virtual bool next(); virtual bool skipTo(int32_t target); - + /// Check whether two Spans in the same document are ordered. - /// @return true if spans1 starts before spans2 or the spans start at the same position, and + /// @return true if spans1 starts before spans2 or the spans start at the same position, and /// spans1 ends before spans2. static bool docSpansOrdered(SpansPtr spans1, SpansPtr spans2); - + virtual String toString(); - + protected: - /// Advances the subSpans to just after an ordered match with a minimum slop that is smaller than the + /// Advances the subSpans to just after an ordered match with a minimum slop that is smaller than the /// slop allowed by the SpanNearQuery. /// @return true if there is such a match. bool advanceAfterOrdered(); - + /// Advance the subSpans to the same document. bool toSameDoc(); // Like {@link #docSpansOrdered(SpansPtr, SpansPtr)}, but use the spans starts and ends as parameters. static bool docSpansOrdered(int32_t start1, int32_t end1, int32_t start2, int32_t end2); - + /// Order the subSpans within the same document by advancing all later spans after the previous one. bool stretchToOrder(); - - /// The subSpans are ordered in the same doc, so there is a possible match. Compute the slop while + + /// The subSpans are ordered in the same doc, so there is a possible match. Compute the slop while /// making the match as short as possible by advancing all subSpans except the last one in reverse order. bool shrinkToAfterShortestMatch(); }; diff --git a/include/NearSpansUnordered.h b/include/NearSpansUnordered.h index e1ca899e..2fa08173 100644 --- a/include/NearSpansUnordered.h +++ b/include/NearSpansUnordered.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,33 +19,33 @@ namespace Lucene public: NearSpansUnordered(SpanNearQueryPtr query, IndexReaderPtr reader); virtual ~NearSpansUnordered(); - + LUCENE_CLASS(NearSpansUnordered); - + protected: SpanNearQueryPtr query; IndexReaderPtr reader; - + Collection ordered; // spans in query order Collection subSpans; int32_t slop; // from query - + SpansCellPtr first; // linked list of spans SpansCellPtr last; // sorted by doc only - + int32_t totalLength; // sum of current lengths - + CellQueuePtr queue; // sorted queue of spans SpansCellPtr max; // max element in queue - + bool more; // true if not done bool firstTime; // true before first next() - + public: virtual void initialize(); - + Collection getSubSpans(); - + virtual bool next(); virtual bool skipTo(int32_t target); virtual int32_t doc(); @@ -54,7 +54,7 @@ namespace Lucene virtual Collection getPayload(); virtual bool isPayloadAvailable(); virtual String toString(); - + protected: SpansCellPtr min(); void initList(bool next); @@ -63,7 +63,7 @@ namespace Lucene void queueToList(); void listToQueue(); bool atMatch(); - + friend class SpansCell; }; } diff --git a/include/NoLockFactory.h b/include/NoLockFactory.h index 96a0c0f5..f12626d8 100644 --- a/include/NoLockFactory.h +++ b/include/NoLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// Use this {@link LockFactory} to disable locking entirely. Only one instance of this lock is created. + /// Use this {@link LockFactory} to disable locking entirely. Only one instance of this lock is created. /// You should call {@link #getNoLockFactory()} to get the instance. /// /// @see LockFactory @@ -19,19 +19,19 @@ namespace Lucene { public: virtual ~NoLockFactory(); - + LUCENE_CLASS(NoLockFactory); - + private: static NoLockPtr getSingletonLock(); public: static NoLockFactoryPtr getNoLockFactory(); - + /// Return a new Lock instance identified by lockName. virtual LockPtr makeLock(const String& lockName); - - /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you + + /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you /// are certain this lock is no longer in use. virtual void clearLock(const String& lockName); }; diff --git a/include/NormalizeCharMap.h b/include/NormalizeCharMap.h index dfe0e968..bd0fb1a3 100644 --- a/include/NormalizeCharMap.h +++ b/include/NormalizeCharMap.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,16 +17,16 @@ namespace Lucene public: NormalizeCharMap(); virtual ~NormalizeCharMap(); - + LUCENE_CLASS(NormalizeCharMap); - + public: MapCharNormalizeCharMap submap; String normStr; int32_t diff; - + public: - /// Records a replacement to be applied to the inputs stream. Whenever singleMatch occurs in the input, it + /// Records a replacement to be applied to the inputs stream. Whenever singleMatch occurs in the input, it /// will be replaced with replacement. /// /// @param singleMatch input String to be replaced diff --git a/include/NormsWriter.h b/include/NormsWriter.h index 5dce5a1d..74c9de6d 100644 --- a/include/NormsWriter.h +++ b/include/NormsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,32 +11,32 @@ namespace Lucene { - /// Writes norms. Each thread X field accumulates the norms for the doc/fields it saw, then the flush method + /// Writes norms. Each thread X field accumulates the norms for the doc/fields it saw, then the flush method /// below merges all of these together into a single _X.nrm file. class NormsWriter : public InvertedDocEndConsumer { public: NormsWriter(); virtual ~NormsWriter(); - + LUCENE_CLASS(NormsWriter); - + protected: FieldInfosPtr fieldInfos; - + public: virtual InvertedDocEndConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread); virtual void abort(); - + // We only write the _X.nrm file at flush virtual void files(HashSet files); - + virtual void setFieldInfos(FieldInfosPtr fieldInfos); - + /// Produce _X.nrm if any document had a field with norms not disabled virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, SegmentWriteStatePtr state); virtual void closeDocStore(SegmentWriteStatePtr state); - + protected: static uint8_t getDefaultNorm(); }; diff --git a/include/NormsWriterPerField.h b/include/NormsWriterPerField.h index 15cbe40c..a72ef958 100644 --- a/include/NormsWriterPerField.h +++ b/include/NormsWriterPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,35 +11,35 @@ namespace Lucene { - /// Taps into DocInverter, as an InvertedDocEndConsumer, which is called at the end of inverting each field. + /// Taps into DocInverter, as an InvertedDocEndConsumer, which is called at the end of inverting each field. /// We just look at the length for the field (docState.length) and record the norm. class NormsWriterPerField : public InvertedDocEndConsumerPerField { public: NormsWriterPerField(DocInverterPerFieldPtr docInverterPerField, NormsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo); virtual ~NormsWriterPerField(); - + LUCENE_CLASS(NormsWriterPerField); - + public: NormsWriterPerThreadWeakPtr _perThread; FieldInfoPtr fieldInfo; DocStatePtr docState; - + // Holds all docID/norm pairs we've seen Collection docIDs; ByteArray norms; int32_t upto; - + FieldInvertStatePtr fieldState; - + public: void reset(); virtual void abort(); - + /// Compare two objects virtual int32_t compareTo(LuceneObjectPtr other); - + virtual void finish(); }; } diff --git a/include/NormsWriterPerThread.h b/include/NormsWriterPerThread.h index eb80ea57..1e9d4b53 100644 --- a/include/NormsWriterPerThread.h +++ b/include/NormsWriterPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,19 +16,19 @@ namespace Lucene public: NormsWriterPerThread(DocInverterPerThreadPtr docInverterPerThread, NormsWriterPtr normsWriter); virtual ~NormsWriterPerThread(); - + LUCENE_CLASS(NormsWriterPerThread); - + public: NormsWriterWeakPtr _normsWriter; DocStatePtr docState; - + public: virtual InvertedDocEndConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo); virtual void abort(); virtual void startDocument(); virtual void finishDocument(); - + bool freeRAM(); }; } diff --git a/include/NumberTools.h b/include/NumberTools.h index 7c871030..684a2dab 100644 --- a/include/NumberTools.h +++ b/include/NumberTools.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,46 +11,46 @@ namespace Lucene { - /// Provides support for converting longs to Strings, and back again. The strings are structured so that + /// Provides support for converting longs to Strings, and back again. The strings are structured so that /// lexicographic sorting order is preserved. /// - /// That is, if l1 is less than l2 for any two longs l1 and l2, then NumberTools.longToString(l1) is + /// That is, if l1 is less than l2 for any two longs l1 and l2, then NumberTools.longToString(l1) is /// lexicographically less than NumberTools.longToString(l2). (Similarly for "greater than" and "equals".) /// /// This class handles all long values (unlike {@link DateField}). /// - /// @deprecated For new indexes use {@link NumericUtils} instead, which provides a sortable binary representation + /// @deprecated For new indexes use {@link NumericUtils} instead, which provides a sortable binary representation /// (prefix encoded) of numeric values. - /// To index and efficiently query numeric values use {@link NumericField} and {@link NumericRangeQuery}. This + /// To index and efficiently query numeric values use {@link NumericField} and {@link NumericRangeQuery}. This /// class is included for use with existing indices and will be removed in a future release (possibly Lucene 4.0). class LPPAPI NumberTools : public LuceneObject { public: virtual ~NumberTools(); - + LUCENE_CLASS(NumberTools); - + protected: static const int32_t RADIX; - + static const wchar_t NEGATIVE_PREFIX; - + // NB: NEGATIVE_PREFIX must be < POSITIVE_PREFIX static const wchar_t POSITIVE_PREFIX; - + public: /// Equivalent to longToString(LLONG_MIN) static const String& MIN_STRING_VALUE(); - + /// Equivalent to longToString(LLONG_MAX) static const String& MAX_STRING_VALUE(); - + /// The length of (all) strings returned by {@link #longToString} static int32_t STR_SIZE(); - + /// Converts a long to a String suitable for indexing. static String longToString(int64_t l); - + /// Converts a String that was returned by {@link #longToString} back to a long. static int64_t stringToLong(const String& str); }; diff --git a/include/NumericField.h b/include/NumericField.h index b7a07a3e..e8fe1901 100644 --- a/include/NumericField.h +++ b/include/NumericField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,117 +13,117 @@ namespace Lucene { /// This class provides a {@link Field} that enables indexing of numeric values for efficient range filtering and /// sorting. The native types int32_t, int64_t and double are directly supported. However, any value that can be - /// converted into these native types can also be indexed. For example, date/time values represented by a {@link + /// converted into these native types can also be indexed. For example, date/time values represented by a {@link /// Date} can be translated into a int64_t value. If you don't need millisecond precision, you can quantize the /// value, either by dividing the result or using the separate getters (for year, month, etc.) to construct an int32_t /// or int64_t value. /// - /// To perform range querying or filtering against a NumericField, use {@link NumericRangeQuery} or {@link - /// NumericRangeFilter}. To sort according to a NumericField, use the normal numeric sort types, eg {@link + /// To perform range querying or filtering against a NumericField, use {@link NumericRangeQuery} or {@link + /// NumericRangeFilter}. To sort according to a NumericField, use the normal numeric sort types, eg {@link /// SortField#INT}. NumericField values can also be loaded directly from {@link FieldCache}. /// - /// By default, a NumericField's value is not stored but is indexed for range filtering and sorting. You can use the + /// By default, a NumericField's value is not stored but is indexed for range filtering and sorting. You can use the /// {@link #NumericField(String,Field.Store,boolean)} constructor if you need to change these defaults. /// - /// You may add the same field name as a NumericField to the same document more than once. Range querying and - /// filtering will be the logical OR of all values; so a range query will hit all documents that have at least one - /// value in the range. However sort behavior is not defined. If you need to sort, you should separately index a + /// You may add the same field name as a NumericField to the same document more than once. Range querying and + /// filtering will be the logical OR of all values; so a range query will hit all documents that have at least one + /// value in the range. However sort behavior is not defined. If you need to sort, you should separately index a /// single-valued NumericField. /// - /// A NumericField will consume somewhat more disk space in the index than an ordinary single-valued field. However, - /// for a typical index that includes substantial textual content per document, this increase will likely be in the + /// A NumericField will consume somewhat more disk space in the index than an ordinary single-valued field. However, + /// for a typical index that includes substantial textual content per document, this increase will likely be in the /// noise. /// - /// Within Lucene, each numeric value is indexed as a trie structure, where each term is logically assigned to larger - /// and larger pre-defined brackets (which are simply lower-precision representations of the value). The step size - /// between each successive bracket is called the precisionStep, measured in bits. Smaller precisionStep values - /// result in larger number of brackets, which consumes more disk space in the index but may result in faster range - /// search performance. The default value 4 was selected for a reasonable trade off of disk space consumption versus + /// Within Lucene, each numeric value is indexed as a trie structure, where each term is logically assigned to larger + /// and larger pre-defined brackets (which are simply lower-precision representations of the value). The step size + /// between each successive bracket is called the precisionStep, measured in bits. Smaller precisionStep values + /// result in larger number of brackets, which consumes more disk space in the index but may result in faster range + /// search performance. The default value 4 was selected for a reasonable trade off of disk space consumption versus /// performance. You can use the expert constructor {@link #NumericField(String,int,Field.Store,boolean)} if you'd - /// like to change the value. Note that you must also specify a congruent value when creating {@link NumericRangeQuery} - /// or {@link NumericRangeFilter}. For low cardinality fields larger precision steps are good. If the cardinality + /// like to change the value. Note that you must also specify a congruent value when creating {@link NumericRangeQuery} + /// or {@link NumericRangeFilter}. For low cardinality fields larger precision steps are good. If the cardinality /// is < 100, it is fair to use {@link INT_MAX}, which produces one term per value. /// - /// For more information on the internals of numeric trie indexing, including the precisionStep configuration, see + /// For more information on the internals of numeric trie indexing, including the precisionStep configuration, see /// {@link NumericRangeQuery}. The format of indexed values is described in {@link NumericUtils}. /// - /// If you only need to sort by numeric value, and never run range querying/filtering, you can index using a + /// If you only need to sort by numeric value, and never run range querying/filtering, you can index using a /// precisionStep of {@link MAX_INT}. This will minimize disk space consumed. /// - /// More advanced users can instead use {@link NumericTokenStream} directly, when indexing numbers. This class is a + /// More advanced users can instead use {@link NumericTokenStream} directly, when indexing numbers. This class is a /// wrapper around this token stream type for easier, more intuitive usage. /// - /// NOTE: This class is only used during indexing. When retrieving the stored field value from a {@link Document} - /// instance after search, you will get a conventional {@link Fieldable} instance where the numeric values are + /// NOTE: This class is only used during indexing. When retrieving the stored field value from a {@link Document} + /// instance after search, you will get a conventional {@link Fieldable} instance where the numeric values are /// returned as strings (according to toString(value) of the used data type). class LPPAPI NumericField : public AbstractField { public: - /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} + /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} /// (4). The instance is not yet initialized with a numeric value, before indexing a document containing this field, /// set a value using the various set???Value() methods. /// This constructor creates an indexed, but not stored field. /// @param name the field name NumericField(const String& name); - - /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} + + /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} /// (4). The instance is not yet initialized with a numeric value, before indexing a document containing this field, /// set a value using the various set???Value() methods. /// This constructor creates an indexed, but not stored field. /// @param name the field name - /// @param store if the field should be stored in plain text form (according to toString(value) of the used + /// @param store if the field should be stored in plain text form (according to toString(value) of the used /// data type) /// @param index if the field should be indexed using {@link NumericTokenStream} NumericField(const String& name, Field::Store store, bool index); - - /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with - /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() + + /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with + /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() /// methods. This constructor creates an indexed, but not stored field. /// @param name the field name /// @param precisionStep the used precision step NumericField(const String& name, int32_t precisionStep); - - /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with - /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() + + /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with + /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() /// methods. This constructor creates an indexed, but not stored field. /// @param name the field name /// @param precisionStep the used precision step - /// @param store if the field should be stored in plain text form (according to toString(value) of the used + /// @param store if the field should be stored in plain text form (according to toString(value) of the used /// data type) /// @param index if the field should be indexed using {@link NumericTokenStream} NumericField(const String& name, int32_t precisionStep, Field::Store store, bool index); - + virtual ~NumericField(); - + LUCENE_CLASS(NumericField); - + protected: NumericTokenStreamPtr tokenStream; - + public: /// Returns a {@link NumericTokenStream} for indexing the numeric value. virtual TokenStreamPtr tokenStreamValue(); - + /// Returns always null for numeric fields virtual ByteArray getBinaryValue(ByteArray result); - + /// Returns always null for numeric fields virtual ReaderPtr readerValue(); - + /// Returns the numeric value as a string (how it is stored, when {@link Field.Store#YES} is chosen). virtual String stringValue(); - + /// Returns the current numeric value. virtual int64_t getNumericValue(); - + /// Initializes the field with the supplied long value. /// @param value the numeric value virtual NumericFieldPtr setLongValue(int64_t value); - + /// Initializes the field with the supplied int value. /// @param value the numeric value virtual NumericFieldPtr setIntValue(int32_t value); - + /// Initializes the field with the supplied double value. /// @param value the numeric value virtual NumericFieldPtr setDoubleValue(double value); diff --git a/include/NumericRangeFilter.h b/include/NumericRangeFilter.h index 6f99077a..faacfeef 100644 --- a/include/NumericRangeFilter.h +++ b/include/NumericRangeFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// A {@link Filter} that only accepts numeric values within a specified range. To use this, you must first + /// A {@link Filter} that only accepts numeric values within a specified range. To use this, you must first /// index the numeric values using {@link NumericField} ({@link NumericTokenStream}). /// /// You create a new NumericRangeFilter with the static factory methods, eg: @@ -26,55 +26,55 @@ namespace Lucene public: NumericRangeFilter(NumericRangeQueryPtr query); virtual ~NumericRangeFilter(); - + LUCENE_CLASS(NumericRangeFilter); - + public: /// Factory that creates a NumericRangeFilter, that filters a long range using the given precisionStep. static NumericRangeFilterPtr newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep + + /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). static NumericRangeFilterPtr newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - + /// Factory that creates a NumericRangeFilter, that filters a int range using the given precisionStep. static NumericRangeFilterPtr newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep + + /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). static NumericRangeFilterPtr newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - + /// Factory that creates a NumericRangeFilter, that filters a double range using the given precisionStep. static NumericRangeFilterPtr newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep + + /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). static NumericRangeFilterPtr newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int, long or double range using the given - /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min - /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents + + /// Factory that creates a NumericRangeFilter, that filters a int, long or double range using the given + /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min + /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents /// excluding the bounds, with inclusive on the boundaries are hits, too. static NumericRangeFilterPtr newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int, long or double range range using the default - /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which are in - /// fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting inclusive to false + + /// Factory that creates a NumericRangeFilter, that filters a int, long or double range range using the default + /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which are in + /// fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting inclusive to false /// it will match all documents excluding the bounds, with inclusive on the boundaries are hits, too. static NumericRangeFilterPtr newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - + /// Returns the field name for this filter String getField(); - + /// Returns true if the lower endpoint is inclusive bool includesMin(); - + /// Returns true if the upper endpoint is inclusive bool includesMax(); - + /// Returns the lower value of this range filter NumericValue getMin(); - + /// Returns the upper value of this range filter NumericValue getMax(); }; diff --git a/include/NumericRangeQuery.h b/include/NumericRangeQuery.h index b66826e7..914a9c88 100644 --- a/include/NumericRangeQuery.h +++ b/include/NumericRangeQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,9 +13,9 @@ namespace Lucene { - /// A {@link Query} that matches numeric values within a specified range. To use this, you must first - /// index the numeric values using {@link NumericField} (expert: {@link NumericTokenStream}). If your - /// terms are instead textual, you should use {@link TermRangeQuery}. {@link NumericRangeFilter} is the + /// A {@link Query} that matches numeric values within a specified range. To use this, you must first + /// index the numeric values using {@link NumericField} (expert: {@link NumericTokenStream}). If your + /// terms are instead textual, you should use {@link TermRangeQuery}. {@link NumericRangeFilter} is the /// filter equivalent of this query. /// /// You create a new NumericRangeQuery with the static factory methods, eg: @@ -24,24 +24,24 @@ namespace Lucene ///
    /// matches all documents whose double valued "weight" field ranges from 0.3 to 0.10, inclusive. /// - /// The performance of NumericRangeQuery is much better than the corresponding {@link TermRangeQuery} - /// because the number of terms that must be searched is usually far fewer, thanks to trie indexing, + /// The performance of NumericRangeQuery is much better than the corresponding {@link TermRangeQuery} + /// because the number of terms that must be searched is usually far fewer, thanks to trie indexing, /// described below. /// /// You can optionally specify a precisionStep when creating this query. This is necessary if you've - /// changed this configuration from its default (4) during indexing. Lower values consume more disk - /// space but speed up searching. Suitable values are between 1 and 8. A good starting point to test + /// changed this configuration from its default (4) during indexing. Lower values consume more disk + /// space but speed up searching. Suitable values are between 1 and 8. A good starting point to test /// is 4, which is the default value for all Numeric* classes. See below for details. /// - /// This query defaults to {@linkplain MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} for 32 bit + /// This query defaults to {@linkplain MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} for 32 bit /// integer ranges with precisionStep <=8 and 64 bit (long/double) ranges with precisionStep <=6. - /// Otherwise it uses {@linkplain MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE} as the number of terms - /// is likely to be high. With precision steps of <=4, this query can be run with one of the BooleanQuery + /// Otherwise it uses {@linkplain MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE} as the number of terms + /// is likely to be high. With precision steps of <=4, this query can be run with one of the BooleanQuery /// rewrite methods without changing BooleanQuery's default max clause count. /// /// How it works /// - /// See the publication about panFMP, where this + /// See the publication about panFMP, where this /// algorithm was described (referred to as TrieRangeQuery): ///
    Schindler, U, Diepenbroek, M, 2008. /// Generic XML-based Framework for Metadata Portals. @@ -49,38 +49,38 @@ namespace Lucene /// doi:10.1016/j.cageo.2008.02.023
    /// - /// A quote from this paper: Because Apache Lucene is a full-text search engine and not a conventional - /// database, it cannot handle numerical ranges (eg., field value is inside user defined bounds, even - /// dates are numerical values). We have developed an extension to Apache Lucene that stores the - /// numerical values in a special string-encoded format with variable precision (all numerical values like - /// doubles, longs, and ints are converted to lexicographic sortable string representations and stored - /// with different precisions (for a more detailed description of how the values are stored, see {@link + /// A quote from this paper: Because Apache Lucene is a full-text search engine and not a conventional + /// database, it cannot handle numerical ranges (eg., field value is inside user defined bounds, even + /// dates are numerical values). We have developed an extension to Apache Lucene that stores the + /// numerical values in a special string-encoded format with variable precision (all numerical values like + /// doubles, longs, and ints are converted to lexicographic sortable string representations and stored + /// with different precisions (for a more detailed description of how the values are stored, see {@link /// NumericUtils}). A range is then divided recursively into multiple intervals for searching: - /// The center of the range is searched only with the lowest possible precision in the trie, while the + /// The center of the range is searched only with the lowest possible precision in the trie, while the /// boundaries are matched more exactly. This reduces the number of terms dramatically. /// - /// For the variant that stores long values in 8 different precisions (each reduced by 8 bits) that uses a - /// lowest precision of 1 byte, the index contains only a maximum of 256 distinct values in the lowest - /// precision. Overall, a range could consist of a theoretical maximum of 7*255*2 + 255 = 3825 distinct - /// terms (when there is a term for every distinct value of an 8-byte-number in the index and the range - /// covers almost all of them; a maximum of 255 distinct values is used because it would always be possible - /// to reduce the full 256 values to one term with degraded precision). In practice, we have seen up to + /// For the variant that stores long values in 8 different precisions (each reduced by 8 bits) that uses a + /// lowest precision of 1 byte, the index contains only a maximum of 256 distinct values in the lowest + /// precision. Overall, a range could consist of a theoretical maximum of 7*255*2 + 255 = 3825 distinct + /// terms (when there is a term for every distinct value of an 8-byte-number in the index and the range + /// covers almost all of them; a maximum of 255 distinct values is used because it would always be possible + /// to reduce the full 256 values to one term with degraded precision). In practice, we have seen up to /// 300 terms in most cases (index with 500,000 metadata records and a uniform value distribution). /// /// Precision Step: - /// You can choose any precisionStep when encoding values. Lower step values mean more precisions and so - /// more terms in index (and index gets larger). On the other hand, the maximum number of terms to match + /// You can choose any precisionStep when encoding values. Lower step values mean more precisions and so + /// more terms in index (and index gets larger). On the other hand, the maximum number of terms to match /// reduces, which optimized query speed. The formula to calculate the maximum term count is: ///
         /// n = [ (bitsPerValue/precisionStep - 1) * (2 ^ precisionStep - 1 ) * 2 ] + (2 ^ precisionStep - 1 )
         /// 
    /// - /// (this formula is only correct, when bitsPerValue/precisionStep is an integer; in other cases, the value + /// (this formula is only correct, when bitsPerValue/precisionStep is an integer; in other cases, the value /// must be rounded up and the last summand must contain the modulo of the division as precision step). - /// For longs stored using a precision step of 4, n = 15*15*2 + 15 = 465, and for a precision step of 2, - /// n = 31*3*2 + 3 = 189. But the faster search speed is reduced by more seeking in the term enum of the - /// index. Because of this, the ideal precisionStep value can only be found out by testing. Important: You - /// can index with a lower precision step value and test search speed using a multiple of the original step + /// For longs stored using a precision step of 4, n = 15*15*2 + 15 = 465, and for a precision step of 2, + /// n = 31*3*2 + 3 = 189. But the faster search speed is reduced by more seeking in the term enum of the + /// index. Because of this, the ideal precisionStep value can only be found out by testing. Important: You + /// can index with a lower precision step value and test search speed using a multiple of the original step /// value. /// /// Good values for precisionStep are depending on usage and data type: @@ -90,29 +90,29 @@ namespace Lucene ///
  • Ideal value in most cases for 32 bit data types (int) is 4. ///
  • For low cardinality fields larger precision steps are good. If the cardinality is < 100, it is /// fair to use {@link Integer#MAX_VALUE} (see below). - ///
  • Steps >=64 for long/double and >=32 for int/float produces one token per value in the index and - /// querying is as slow as a conventional {@link TermRangeQuery}. But it can be used to produce fields, - /// that are solely used for sorting (in this case simply use {@link Integer#MAX_VALUE} as precisionStep). - /// Using {@link NumericField NumericFields} for sorting is ideal, because building the field cache is much - /// faster than with text-only numbers. These fields have one term per value and therefore also work with + ///
  • Steps >=64 for long/double and >=32 for int/float produces one token per value in the index and + /// querying is as slow as a conventional {@link TermRangeQuery}. But it can be used to produce fields, + /// that are solely used for sorting (in this case simply use {@link Integer#MAX_VALUE} as precisionStep). + /// Using {@link NumericField NumericFields} for sorting is ideal, because building the field cache is much + /// faster than with text-only numbers. These fields have one term per value and therefore also work with /// term enumeration for building distinct lists (eg. facets / preselected values to search for). /// Sorting is also possible with range query optimized fields using one of the above precisionSteps. /// /// - /// Comparisons of the different types of RangeQueries on an index with about 500,000 docs showed that - /// {@link TermRangeQuery} in boolean rewrite mode (with raised {@link BooleanQuery} clause count) took + /// Comparisons of the different types of RangeQueries on an index with about 500,000 docs showed that + /// {@link TermRangeQuery} in boolean rewrite mode (with raised {@link BooleanQuery} clause count) took /// about 30-40 secs to complete, {@link TermRangeQuery} in constant score filter rewrite mode took 5 secs - /// and executing this class took <100ms to complete (on an Opteron64 machine, 8 bit precision step). This - /// query type was developed for a geographic portal, where the performance for eg. bounding boxes or exact + /// and executing this class took <100ms to complete (on an Opteron64 machine, 8 bit precision step). This + /// query type was developed for a geographic portal, where the performance for eg. bounding boxes or exact /// date/time stamps is important. class LPPAPI NumericRangeQuery : public MultiTermQuery { public: NumericRangeQuery(const String& field, int32_t precisionStep, int32_t valSize, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); virtual ~NumericRangeQuery(); - + LUCENE_CLASS(NumericRangeQuery); - + INTERNAL: String field; int32_t precisionStep; @@ -121,67 +121,67 @@ namespace Lucene NumericValue max; bool minInclusive; bool maxInclusive; - + public: using MultiTermQuery::toString; - + /// Factory that creates a NumericRangeFilter, that filters a long range using the given precisionStep. static NumericRangeQueryPtr newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep + + /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). static NumericRangeQueryPtr newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - + /// Factory that creates a NumericRangeFilter, that filters a int range using the given precisionStep. static NumericRangeQueryPtr newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep + + /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). static NumericRangeQueryPtr newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - + /// Factory that creates a NumericRangeFilter, that filters a double range using the given precisionStep. static NumericRangeQueryPtr newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep + + /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). static NumericRangeQueryPtr newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the given - /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min - /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents + + /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the given + /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min + /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents /// excluding the bounds, with inclusive on the boundaries are hits, too. static NumericRangeQueryPtr newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the default - /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which - /// are in fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting - /// inclusive to false it will match all documents excluding the bounds, with inclusive on the boundaries + + /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the default + /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which + /// are in fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting + /// inclusive to false it will match all documents excluding the bounds, with inclusive on the boundaries /// are hits, too. static NumericRangeQueryPtr newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - + /// Returns the field name for this query String getField(); - + /// Returns true if the lower endpoint is inclusive bool includesMin(); - + /// Returns true if the upper endpoint is inclusive bool includesMax(); - + /// Returns the lower value of this range query NumericValue getMin(); - + /// Returns the upper value of this range query NumericValue getMax(); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual String toString(const String& field); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + protected: virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); - + friend class NumericRangeTermEnum; }; } diff --git a/include/NumericTokenStream.h b/include/NumericTokenStream.h index 0e1269d5..28a5ea7d 100644 --- a/include/NumericTokenStream.h +++ b/include/NumericTokenStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,10 +11,10 @@ namespace Lucene { - /// This class provides a {@link TokenStream} for indexing numeric values that can be used by {@link NumericRangeQuery} + /// This class provides a {@link TokenStream} for indexing numeric values that can be used by {@link NumericRangeQuery} /// or {@link NumericRangeFilter}. /// - /// Note that for simple usage, {@link NumericField} is recommended. {@link NumericField} disables norms and term freqs, + /// Note that for simple usage, {@link NumericField} is recommended. {@link NumericField} disables norms and term freqs, /// as they are not usually needed during searching. If you need to change these settings, you should use this class. /// /// See {@link NumericField} for capabilities of fields indexed numerically. @@ -44,7 +44,7 @@ namespace Lucene /// This stream is not intended to be used in analyzers; it's more for iterating the different precisions during /// indexing a specific numeric value. /// - /// NOTE: as token streams are only consumed once the document is added to the index, if you index more than one + /// NOTE: as token streams are only consumed once the document is added to the index, if you index more than one /// numeric field, use a separate NumericTokenStream * instance for each. /// /// See {@link NumericRangeQuery} for more details on the precisionStep @@ -52,65 +52,65 @@ namespace Lucene class LPPAPI NumericTokenStream : public TokenStream { public: - /// Creates a token stream for numeric values using the default precisionStep {@link - /// NumericUtils#PRECISION_STEP_DEFAULT} (4). The stream is not yet initialized, before using set a + /// Creates a token stream for numeric values using the default precisionStep {@link + /// NumericUtils#PRECISION_STEP_DEFAULT} (4). The stream is not yet initialized, before using set a /// value using the various setValue() methods. NumericTokenStream(); - - /// Creates a token stream for numeric values with the specified precisionStep. The stream is not yet + + /// Creates a token stream for numeric values with the specified precisionStep. The stream is not yet /// initialized, before using set a value using the various setValue() methods. NumericTokenStream(int32_t precisionStep); - - /// Creates a token stream for numeric values with the specified precisionStep using the given {@link - /// AttributeSource}. The stream is not yet initialized, before using set a value using the various + + /// Creates a token stream for numeric values with the specified precisionStep using the given {@link + /// AttributeSource}. The stream is not yet initialized, before using set a value using the various /// setValue() methods. NumericTokenStream(AttributeSourcePtr source, int32_t precisionStep); - - /// Creates a token stream for numeric values with the specified precisionStep using the given {@link - /// AttributeFactory}. The stream is not yet initialized, before using set a value using the various + + /// Creates a token stream for numeric values with the specified precisionStep using the given {@link + /// AttributeFactory}. The stream is not yet initialized, before using set a value using the various /// setValue() methods. NumericTokenStream(AttributeFactoryPtr factory, int32_t precisionStep); - + virtual ~NumericTokenStream(); - + LUCENE_CLASS(NumericTokenStream); - + protected: TermAttributePtr termAtt; TypeAttributePtr typeAtt; PositionIncrementAttributePtr posIncrAtt; - + int32_t shift; int32_t valSize; // valSize == 0 means not initialized int32_t precisionStep; - + int64_t value; - + public: /// The full precision token gets this token type assigned. static const String& TOKEN_TYPE_FULL_PREC(); - + /// The lower precision tokens gets this token type assigned. static const String& TOKEN_TYPE_LOWER_PREC(); - + /// Initializes the token stream with the supplied long value. /// @param value the value, for which this TokenStream should enumerate tokens. /// @return this instance, because of this you can use it the following way: /// newLucene(name, newLucene(precisionStep)->setLongValue(value)) NumericTokenStreamPtr setLongValue(int64_t value); - + /// Initializes the token stream with the supplied int value. /// @param value the value, for which this TokenStream should enumerate tokens. /// @return this instance, because of this you can use it the following way: /// newLucene(name, newLucene(precisionStep)->setIntValue(value)) NumericTokenStreamPtr setIntValue(int32_t value); - + /// Initializes the token stream with the supplied double value. /// @param value the value, for which this TokenStream should enumerate tokens. /// @return this instance, because of this you can use it the following way: /// newLucene(name, newLucene(precisionStep)->setDoubleValue(value)) NumericTokenStreamPtr setDoubleValue(double value); - + virtual void reset(); virtual bool incrementToken(); virtual String toString(); diff --git a/include/NumericUtils.h b/include/NumericUtils.h index bc7763ca..720cb79f 100644 --- a/include/NumericUtils.h +++ b/include/NumericUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,78 +11,78 @@ namespace Lucene { - /// This is a helper class to generate prefix-encoded representations for numerical values and supplies converters + /// This is a helper class to generate prefix-encoded representations for numerical values and supplies converters /// to represent double values as sortable integers/longs. /// - /// To quickly execute range queries in Apache Lucene, a range is divided recursively into multiple intervals for - /// searching: The center of the range is searched only with the lowest possible precision in the trie, while the + /// To quickly execute range queries in Apache Lucene, a range is divided recursively into multiple intervals for + /// searching: The center of the range is searched only with the lowest possible precision in the trie, while the /// boundaries are matched more exactly. This reduces the number of terms dramatically. /// - /// This class generates terms to achieve this: First the numerical integer values need to be converted to strings. + /// This class generates terms to achieve this: First the numerical integer values need to be converted to strings. /// For that integer values (32 bit or 64 bit) are made unsigned and the bits are converted to ASCII chars with each - /// 7 bit. The resulting string is sortable like the original integer value. Each value is also prefixed (in the + /// 7 bit. The resulting string is sortable like the original integer value. Each value is also prefixed (in the /// first char) by the shift value (number of bits removed) used during encoding. /// - /// To also index floating point numbers, this class supplies two methods to convert them to integer values by - /// changing their bit layout: {@link #doubleToSortableLong}, {@link #doubleToSortableInt}. You will have no precision - /// loss by converting floating point numbers to integers and back (only that the integer form is not usable). Other + /// To also index floating point numbers, this class supplies two methods to convert them to integer values by + /// changing their bit layout: {@link #doubleToSortableLong}, {@link #doubleToSortableInt}. You will have no precision + /// loss by converting floating point numbers to integers and back (only that the integer form is not usable). Other /// data types like dates can easily converted to longs or ints (eg. date to long). /// - /// For easy usage, the trie algorithm is implemented for indexing inside {@link NumericTokenStream} that can index - /// int, long, and double. For querying, {@link NumericRangeQuery} and {@link NumericRangeFilter} implement the query + /// For easy usage, the trie algorithm is implemented for indexing inside {@link NumericTokenStream} that can index + /// int, long, and double. For querying, {@link NumericRangeQuery} and {@link NumericRangeFilter} implement the query /// part for the same data types. /// - /// This class can also be used, to generate lexicographically sortable (according {@link std::string#compare}) + /// This class can also be used, to generate lexicographically sortable (according {@link std::string#compare}) /// representations of numeric data types for other usages (eg. sorting). class LPPAPI NumericUtils : public LuceneObject { public: virtual ~NumericUtils(); - + LUCENE_CLASS(NumericUtils); - + public: - /// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, + /// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, /// and {@link NumericRangeFilter} as default. static const int32_t PRECISION_STEP_DEFAULT; - - /// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + + + /// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + /// shift in the first character. static const wchar_t SHIFT_START_LONG; - + /// The maximum term length (used for char[] buffer size) for encoding long values. /// @see #longToPrefixCoded(long,int,char[]) static const int32_t BUF_SIZE_LONG; - + /// Integers are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_INT + /// shift in the first character. static const wchar_t SHIFT_START_INT; - + /// The maximum term length (used for char[] buffer size) for encoding int values. /// @see #intToPrefixCoded(int,int,char[]) static const int32_t BUF_SIZE_INT; - + public: - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by /// {@link NumericTokenStream}. /// @param val the numeric value /// @param shift how many bits to strip from the right /// @param buffer that will contain the encoded chars, must be at least of {@link #BUF_SIZE_LONG} length /// @return number of chars written to buffer static int32_t longToPrefixCoded(int64_t val, int32_t shift, CharArray buffer); - - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by + + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by /// {@link LongRangeBuilder}. /// @param val the numeric value /// @param shift how many bits to strip from the right static String longToPrefixCoded(int64_t val, int32_t shift); - /// This is a convenience method, that returns prefix coded bits of a long without reducing the precision. + /// This is a convenience method, that returns prefix coded bits of a long without reducing the precision. /// It can be used to store the full precision value as a stored field in index. /// To decode, use {@link #prefixCodedToLong}. static String longToPrefixCoded(int64_t val); - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link /// NumericTokenStream}. /// @param val the numeric value /// @param shift how many bits to strip from the right @@ -90,13 +90,13 @@ namespace Lucene /// @return number of chars written to buffer static int32_t intToPrefixCoded(int32_t val, int32_t shift, CharArray buffer); - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link /// IntRangeBuilder}. /// @param val the numeric value /// @param shift how many bits to strip from the right static String intToPrefixCoded(int32_t val, int32_t shift); - /// This is a convenience method, that returns prefix coded bits of an int without reducing the precision. + /// This is a convenience method, that returns prefix coded bits of an int without reducing the precision. /// It can be used to store the full precision value as a stored field in index. /// To decode, use {@link #prefixCodedToInt}. static String intToPrefixCoded(int32_t val); @@ -111,8 +111,8 @@ namespace Lucene /// @see #intToPrefixCoded(int32_t) static int32_t prefixCodedToInt(const String& prefixCoded); - /// Converts a double value to a sortable signed long. The value is converted by getting their IEEE 754 - /// floating-point "double format" bit layout and then some bits are swapped, to be able to compare the + /// Converts a double value to a sortable signed long. The value is converted by getting their IEEE 754 + /// floating-point "double format" bit layout and then some bits are swapped, to be able to compare the /// result as int64_t. By this the precision is not reduced, but the value can easily used as a int64_t. /// @see #sortableLongToDouble static int64_t doubleToSortableLong(double val); @@ -120,19 +120,19 @@ namespace Lucene /// Convenience method: this just returns: longToPrefixCoded(doubleToSortableLong(val)) static String doubleToPrefixCoded(double val); - /// Converts a sortable long back to a double. + /// Converts a sortable long back to a double. /// @see #doubleToSortableLong static double sortableLongToDouble(int64_t val); /// Convenience method: this just returns: sortableLongToDouble(prefixCodedToLong(val)) static double prefixCodedToDouble(const String& val); - /// Splits a int64_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} + /// Splits a int64_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} /// for each call to its {@link LongRangeBuilder#addRange(String,String)} method. /// This method is used by {@link NumericRangeQuery}. static void splitLongRange(LongRangeBuilderPtr builder, int32_t precisionStep, int64_t minBound, int64_t maxBound); - /// Splits an int32_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} + /// Splits an int32_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} /// for each call to its {@link IntRangeBuilder#addRange(String,String)} method. /// This method is used by {@link NumericRangeQuery}. static void splitIntRange(IntRangeBuilderPtr builder, int32_t precisionStep, int32_t minBound, int32_t maxBound); @@ -143,35 +143,35 @@ namespace Lucene /// Helper that delegates to correct range builder static void addRange(LuceneObjectPtr builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift); }; - + /// Callback for {@link #splitLongRange}. You need to overwrite only one of the methods. /// NOTE: This is a very low-level interface, the method signatures may change in later versions. class LPPAPI LongRangeBuilder : public LuceneObject { public: virtual ~LongRangeBuilder(); - + public: - /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build + /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build /// classical (inclusive) range queries from them. virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); - - /// Overwrite this method, if you like to receive the raw long range bounds. You can use this for eg. debugging + + /// Overwrite this method, if you like to receive the raw long range bounds. You can use this for eg. debugging /// purposes (print out range bounds). virtual void addRange(int64_t min, int64_t max, int32_t shift); }; - + class LPPAPI IntRangeBuilder : public LuceneObject { public: virtual ~IntRangeBuilder(); - + public: - /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build + /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build /// classical range (inclusive) queries from them. virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); - - /// Overwrite this method, if you like to receive the raw int range bounds. You can use this for eg. debugging + + /// Overwrite this method, if you like to receive the raw int range bounds. You can use this for eg. debugging /// purposes (print out range bounds). virtual void addRange(int32_t min, int32_t max, int32_t shift); }; diff --git a/include/OffsetAttribute.h b/include/OffsetAttribute.h index a2e9c256..e53c275b 100644 --- a/include/OffsetAttribute.h +++ b/include/OffsetAttribute.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,31 +17,31 @@ namespace Lucene public: OffsetAttribute(); virtual ~OffsetAttribute(); - + LUCENE_CLASS(OffsetAttribute); - + protected: int32_t _startOffset; int32_t _endOffset; - + public: virtual String toString(); - - /// Returns this Token's starting offset, the position of the first character corresponding to this token + + /// Returns this Token's starting offset, the position of the first character corresponding to this token /// in the source text. /// - /// Note that the difference between endOffset() and startOffset() may not be equal to termText.length(), + /// Note that the difference between endOffset() and startOffset() may not be equal to termText.length(), /// as the term text may have been altered by a stemmer or some other filter. virtual int32_t startOffset(); - + /// Set the starting and ending offset. /// @see #startOffset() and #endOffset() virtual void setOffset(int32_t startOffset, int32_t endOffset); - - /// Returns this Token's ending offset, one greater than the position of the last character corresponding + + /// Returns this Token's ending offset, one greater than the position of the last character corresponding /// to this token in the source text. The length of the token in the source text is (endOffset - startOffset). virtual int32_t endOffset(); - + virtual void clear(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); diff --git a/include/OpenBitSet.h b/include/OpenBitSet.h index ce121c7b..ba49ed06 100644 --- a/include/OpenBitSet.h +++ b/include/OpenBitSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,221 +13,221 @@ namespace Lucene { /// An "open" BitSet implementation that allows direct access to the array of words storing the bits. /// - /// The goals of OpenBitSet are the fastest implementation possible, and maximum code reuse. Extra - /// safety and encapsulation may always be built on top, but if that's built in, the cost can never + /// The goals of OpenBitSet are the fastest implementation possible, and maximum code reuse. Extra + /// safety and encapsulation may always be built on top, but if that's built in, the cost can never /// be removed (and hence people re-implement their own version in order to get better performance). class LPPAPI OpenBitSet : public DocIdSet { public: /// Constructs an OpenBitSet large enough to hold numBits. OpenBitSet(int64_t numBits = 64); - + /// Constructs an OpenBitSet from an existing LongArray. - /// - /// 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], + /// + /// 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 <= bits.length(), and any existing words in the array at position >= /// numWords should be zero. OpenBitSet(LongArray bits, int32_t numWords); - + virtual ~OpenBitSet(); - + LUCENE_CLASS(OpenBitSet); - + protected: LongArray bits; int32_t wlen; // number of words (elements) used in the array - + public: virtual DocIdSetIteratorPtr iterator(); - + /// This DocIdSet implementation is cacheable. virtual bool isCacheable(); - + /// Returns the current capacity in bits (1 greater than the index of the last bit) int64_t capacity(); - - /// Returns the current capacity of this set. Included for compatibility. This is *not* + + /// Returns the current capacity of this set. Included for compatibility. This is *not* /// equal to {@link #cardinality} int64_t size(); - + /// Returns true if there are no set bits bool isEmpty(); - + /// Returns the long[] storing the bits LongArray getBits(); - + /// Sets a new long[] to use as the bit storage void setBits(LongArray bits); - + /// Gets the number of longs in the array that are in use int32_t getNumWords(); - + /// Sets the number of longs in the array that are in use void setNumWords(int32_t numWords); - + /// Returns true or false for the specified bit index. bool get(int32_t index); - + /// Returns true or false for the specified bit index. /// The index should be less than the OpenBitSet size bool fastGet(int32_t index); - + /// Returns true or false for the specified bit index bool get(int64_t index); - + /// Returns true or false for the specified bit index. /// The index should be less than the OpenBitSet size. bool fastGet(int64_t index); - + /// Returns 1 if the bit is set, 0 if not. /// The index should be less than the OpenBitSet size int32_t getBit(int32_t index); - + /// Sets a bit, expanding the set size if necessary void set(int64_t index); - + /// Sets the bit at the specified index. /// The index should be less than the OpenBitSet size. void fastSet(int32_t index); - + /// Sets the bit at the specified index. /// The index should be less than the OpenBitSet size. void fastSet(int64_t index); - + /// Sets a range of bits, expanding the set size if necessary /// @param startIndex lower index /// @param endIndex one-past the last bit to set void set(int64_t startIndex, int64_t endIndex); - + /// Clears a bit. /// The index should be less than the OpenBitSet size. void fastClear(int32_t index); - + /// Clears a bit. /// The index should be less than the OpenBitSet size. void fastClear(int64_t index); - + /// Clears a bit, allowing access beyond the current set size without changing the size. void clear(int64_t index); - + /// 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 void clear(int32_t startIndex, int32_t endIndex); - + /// 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 void clear(int64_t startIndex, int64_t endIndex); - + /// Sets a bit and returns the previous value. /// The index should be less than the OpenBitSet size. bool getAndSet(int32_t index); - + /// Sets a bit and returns the previous value. /// The index should be less than the OpenBitSet size. bool getAndSet(int64_t index); - + /// Flips a bit. /// The index should be less than the OpenBitSet size. void fastFlip(int32_t index); - + /// Flips a bit. /// The index should be less than the OpenBitSet size. void fastFlip(int64_t index); - + /// Flips a bit, expanding the set size if necessary void flip(int64_t index); - + /// Flips a bit and returns the resulting bit value. /// The index should be less than the OpenBitSet size. bool flipAndGet(int32_t index); - + /// Flips a bit and returns the resulting bit value. /// The index should be less than the OpenBitSet size. bool flipAndGet(int64_t index); - + /// Flips a range of bits, expanding the set size if necessary /// @param startIndex lower index /// @param endIndex one-past the last bit to flip void flip(int64_t startIndex, int64_t endIndex); - + /// @return the number of set bits int64_t cardinality(); - + /// Returns the popcount or cardinality of the intersection of the two sets. /// Neither set is modified. static int64_t intersectionCount(OpenBitSetPtr a, OpenBitSetPtr b); - + /// Returns the popcount or cardinality of the union of the two sets. /// Neither set is modified. static int64_t unionCount(OpenBitSetPtr a, OpenBitSetPtr b); - + /// Returns the popcount or cardinality of "a and not b" or "intersection(a, not(b))". /// Neither set is modified. static int64_t andNotCount(OpenBitSetPtr a, OpenBitSetPtr b); - + /// Returns the popcount or cardinality of the exclusive-or of the two sets. /// Neither set is modified. static int64_t xorCount(OpenBitSetPtr a, OpenBitSetPtr b); - + /// Returns the index of the first set bit starting at the index specified. /// -1 is returned if there are no more set bits. int32_t nextSetBit(int32_t index); - + /// Returns the index of the first set bit starting at the index specified. /// -1 is returned if there are no more set bits. int64_t nextSetBit(int64_t index); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// this = this AND other void intersect(OpenBitSetPtr other); - + /// this = this OR other void _union(OpenBitSetPtr other); - + /// Remove all elements set in other. this = this AND_NOT other void remove(OpenBitSetPtr other); - + /// this = this XOR other void _xor(OpenBitSetPtr other); - + /// see {@link intersect} void _and(OpenBitSetPtr other); - + /// see {@link union} void _or(OpenBitSetPtr other); - + /// see {@link remove} void andNot(OpenBitSetPtr other); - + /// Returns true if the sets have any elements in common bool intersects(OpenBitSetPtr other); - + /// Expand the LongArray with the size given as a number of words (64 bit longs). /// getNumWords() is unchanged by this call. void ensureCapacityWords(int32_t numWords); - + /// Ensure that the LongArray is big enough to hold numBits, expanding it if necessary. /// getNumWords() is unchanged by this call. void ensureCapacity(int64_t numBits); - + /// Lowers numWords, the number of words in use, by checking for trailing zero words. void trimTrailingZeros(); - + /// Returns the number of 64 bit words it would take to hold numBits. static int32_t bits2words(int64_t numBits); - + /// Returns true if both sets have the same bits set virtual bool equals(LuceneObjectPtr other); - + virtual int32_t hashCode(); - + protected: int32_t expandingWordNum(int64_t index); }; diff --git a/include/OpenBitSetDISI.h b/include/OpenBitSetDISI.h index 6068d8e5..3a1428d9 100644 --- a/include/OpenBitSetDISI.h +++ b/include/OpenBitSetDISI.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,33 +15,33 @@ namespace Lucene { public: /// Construct an OpenBitSetDISI with its bits set from the doc ids of the given DocIdSetIterator. - /// Also give a maximum size one larger than the largest doc id for which a bit may ever be set on + /// Also give a maximum size one larger than the largest doc id for which a bit may ever be set on /// this OpenBitSetDISI. OpenBitSetDISI(DocIdSetIteratorPtr disi, int32_t maxSize); - - /// Construct an OpenBitSetDISI with no bits set, and a given maximum size one larger than the largest + + /// Construct an OpenBitSetDISI with no bits set, and a given maximum size one larger than the largest /// doc id for which a bit may ever be set on this OpenBitSetDISI. OpenBitSetDISI(int32_t maxSize); - + virtual ~OpenBitSetDISI(); - + LUCENE_CLASS(OpenBitSetDISI); - + public: - /// Perform an in-place OR with the doc ids from a given DocIdSetIterator, setting the bit for each + /// Perform an in-place OR with the doc ids from a given DocIdSetIterator, setting the bit for each /// such doc id. These doc ids should be smaller than the maximum size passed to the constructor. void inPlaceOr(DocIdSetIteratorPtr disi); - - /// Perform an in-place AND with the doc ids from a given DocIdSetIterator, leaving only the bits set - /// for which the doc ids are in common. These doc ids should be smaller than the maximum size passed + + /// Perform an in-place AND with the doc ids from a given DocIdSetIterator, leaving only the bits set + /// for which the doc ids are in common. These doc ids should be smaller than the maximum size passed /// to the constructor. void inPlaceAnd(DocIdSetIteratorPtr disi); - - /// Perform an in-place NOT with the doc ids from a given DocIdSetIterator, clearing all the bits for + + /// Perform an in-place NOT with the doc ids from a given DocIdSetIterator, clearing all the bits for /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. void inPlaceNot(DocIdSetIteratorPtr disi); - - /// Perform an inplace XOR with the doc ids from a given DocIdSetIterator, flipping all the bits for + + /// Perform an inplace XOR with the doc ids from a given DocIdSetIterator, flipping all the bits for /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. void inPlaceXor(DocIdSetIteratorPtr disi); }; diff --git a/include/OpenBitSetIterator.h b/include/OpenBitSetIterator.h index e0a50693..1acbb3b8 100644 --- a/include/OpenBitSetIterator.h +++ b/include/OpenBitSetIterator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,9 +20,9 @@ namespace Lucene OpenBitSetIterator(OpenBitSetPtr bitSet); OpenBitSetIterator(LongArray bits, int32_t numWords); virtual ~OpenBitSetIterator(); - + LUCENE_CLASS(OpenBitSetIterator); - + protected: LongArray arr; int32_t words; @@ -31,18 +31,18 @@ namespace Lucene int32_t wordShift; int32_t indexArray; int32_t curDocId; - - /// The General Idea: instead of having an array per byte that has the offsets of the + + /// 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 + /// That should be faster than accessing an array for each index, and the total array /// size is kept smaller (256*sizeof(int32_t))=1K static const int32_t bitlist[]; - + public: virtual int32_t nextDoc(); virtual int32_t advance(int32_t target); virtual int32_t docID(); - + protected: /// 64 bit shifts void shift(); diff --git a/include/OrdFieldSource.h b/include/OrdFieldSource.h index c2b730b4..5db257dd 100644 --- a/include/OrdFieldSource.h +++ b/include/OrdFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,30 +17,30 @@ namespace Lucene /// /// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1. /// Example: - /// If there were only three field values: "apple","banana","pear" then ord("apple")=1, ord("banana")=2, + /// If there were only three field values: "apple","banana","pear" then ord("apple")=1, ord("banana")=2, /// ord("pear")=3 /// - /// WARNING: ord() depends on the position in an index and can thus change when other documents are inserted - /// or deleted, or if a MultiSearcher is used. + /// WARNING: ord() depends on the position in an index and can thus change when other documents are inserted + /// or deleted, or if a MultiSearcher is used. /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite + /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU + /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, + /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU /// per lookup but will not consume double the FieldCache RAM. class LPPAPI OrdFieldSource : public ValueSource { public: /// Constructor for a certain field. - ///@param field field whose values order is used. + ///@param field field whose values order is used. OrdFieldSource(const String& field); virtual ~OrdFieldSource(); - + LUCENE_CLASS(OrdFieldSource); - + protected: String field; - + public: virtual String description(); virtual DocValuesPtr getValues(IndexReaderPtr reader); diff --git a/include/ParallelMultiSearcher.h b/include/ParallelMultiSearcher.h index 25471c13..d616ec2e 100644 --- a/include/ParallelMultiSearcher.h +++ b/include/ParallelMultiSearcher.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene { /// Implements parallel search over a set of Searchables. /// - /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or + /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or /// {@link #search(QueryPtr, FilterPtr, int32_t)} methods. class LPPAPI ParallelMultiSearcher : public MultiSearcher { @@ -21,19 +21,19 @@ namespace Lucene /// Creates a {@link Searchable} which searches searchables. ParallelMultiSearcher(Collection searchables); virtual ~ParallelMultiSearcher(); - + LUCENE_CLASS(ParallelMultiSearcher); - + public: - /// Executes each {@link Searchable}'s docFreq() in its own thread and waits for each search to + /// Executes each {@link Searchable}'s docFreq() in its own thread and waits for each search to /// complete and merge the results back together. virtual int32_t docFreq(TermPtr term); - - /// A search implementation which executes each {@link Searchable} in its own thread and waits + + /// A search implementation which executes each {@link Searchable} in its own thread and waits /// for each search to complete and merge the results back together. virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n); - - /// A search implementation allowing sorting which spans a new thread for each Searchable, waits + + /// A search implementation allowing sorting which spans a new thread for each Searchable, waits /// for each search to complete and merges the results back together. virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort); }; diff --git a/include/ParallelReader.h b/include/ParallelReader.h index 0b3a173e..873f9e0a 100644 --- a/include/ParallelReader.h +++ b/include/ParallelReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,30 +11,30 @@ namespace Lucene { - /// An IndexReader which reads multiple, parallel indexes. Each index added must have the same number of - /// documents, but typically each contains different fields. Each document contains the union of the fields - /// of all documents with the same document number. When searching, matches for a query term are from the + /// An IndexReader which reads multiple, parallel indexes. Each index added must have the same number of + /// documents, but typically each contains different fields. Each document contains the union of the fields + /// of all documents with the same document number. When searching, matches for a query term are from the /// first index added that has the field. /// - /// This is useful, eg., with collections that have large fields which change rarely and small fields that - /// change more frequently. The smaller fields may be re-indexed in a new index and both indexes may be + /// This is useful, eg., with collections that have large fields which change rarely and small fields that + /// change more frequently. The smaller fields may be re-indexed in a new index and both indexes may be /// searched together. /// - /// Warning: It is up to you to make sure all indexes are created and modified the same way. For example, - /// if you add documents to one index, you need to add the same documents in the same order to the other + /// Warning: It is up to you to make sure all indexes are created and modified the same way. For example, + /// if you add documents to one index, you need to add the same documents in the same order to the other /// indexes. Failure to do so will result in undefined behavior class LPPAPI ParallelReader : public IndexReader { public: /// Construct a ParallelReader. - /// @param closeSubReaders indicates whether the subreaders should be closed when this ParallelReader + /// @param closeSubReaders indicates whether the subreaders should be closed when this ParallelReader /// is closed ParallelReader(bool closeSubReaders = true); - + virtual ~ParallelReader(); - + LUCENE_CLASS(ParallelReader); - + protected: Collection readers; Collection decrefOnClose; // remember which subreaders to decRef on close @@ -42,136 +42,136 @@ namespace Lucene MapStringIndexReader fieldToReader; MapIndexReaderSetString readerToFields; Collection storedFieldReaders; - + int32_t _maxDoc; int32_t _numDocs; bool _hasDeletions; - + public: /// Add an IndexReader. void add(IndexReaderPtr reader); - - /// Add an IndexReader whose stored fields will not be returned. This can accelerate search when stored + + /// Add an IndexReader whose stored fields will not be returned. This can accelerate search when stored /// fields are only needed from a subset of the IndexReaders. void add(IndexReaderPtr reader, bool ignoreStoredFields); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Tries to reopen the subreaders. /// - /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader), + /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader), /// then a new ParallelReader instance is returned, otherwise this instance is returned. /// - /// A re-opened instance might share one or more subreaders with the old instance. Index modification + /// A re-opened instance might share one or more subreaders with the old instance. Index modification /// operations result in undefined behavior when performed before the old instance is closed. /// (see {@link IndexReader#reopen()}). /// - /// If subreaders are shared, then the reference count of those readers is increased to ensure that the + /// If subreaders are shared, then the reference count of those readers is increased to ensure that the /// subreaders remain open until the last referring reader is closed. virtual IndexReaderPtr reopen(); - + /// Returns the number of documents in this index. virtual int32_t numDocs(); - - /// Returns one greater than the largest possible document number. This may be used to, eg., determine + + /// Returns one greater than the largest possible document number. This may be used to, eg., determine /// how big to allocate an array which will have an element for every document number in an index. virtual int32_t maxDoc(); - + /// Returns true if any documents have been deleted virtual bool hasDeletions(); - - /// Returns true if document n has been deleted + + /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n); - + /// Get the {@link Document} at the n'th position. virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); - + /// Return an array of term frequency vectors for the specified document. virtual Collection getTermFreqVectors(int32_t docNumber); - + /// Return a term frequency vector for the specified document and field. virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - - /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays + + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays /// of the {@link TermFreqVector}. virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); - + /// Map all the term vectors for all fields in a Document virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); - + /// Returns true if there are norms stored for this field. virtual bool hasNorms(const String& field); - + /// Returns the byte-encoded normalization factor for the named field of every document. virtual ByteArray norms(const String& field); - + /// Reads the byte-encoded normalization factor for the named field of every document. virtual void norms(const String& field, ByteArray norms, int32_t offset); - - /// Returns an enumeration of all the terms in the index. The enumeration is ordered by - /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. - /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting + + /// Returns an enumeration of all the terms in the index. The enumeration is ordered by + /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. + /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting /// enumeration before calling other methods such as {@link TermEnum#term()}. virtual TermEnumPtr terms(); - - /// Returns an enumeration of all terms starting at a given term. If the given term does not - /// exist, the enumeration is positioned at the first term greater than the supplied term. - /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede + + /// Returns an enumeration of all terms starting at a given term. If the given term does not + /// exist, the enumeration is positioned at the first term greater than the supplied term. + /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede /// it in the enumeration. virtual TermEnumPtr terms(TermPtr t); - + /// Returns the number of documents containing the term t. virtual int32_t docFreq(TermPtr t); - - /// Returns an enumeration of all the documents which contain term. For each document, the + + /// Returns an enumeration of all the documents which contain term. For each document, the /// document number, the frequency of the term in that document is also provided, for use in /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. - /// The enumeration is ordered by document number. Each document number is greater than all + /// The enumeration is ordered by document number. Each document number is greater than all /// that precede it in the enumeration. virtual TermDocsPtr termDocs(TermPtr term); - + /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs(); - + /// Returns an enumeration of all the documents which contain term. virtual TermPositionsPtr termPositions(TermPtr term); - + /// Returns an unpositioned {@link TermPositions} enumerator. virtual TermPositionsPtr termPositions(); - - /// Checks recursively if all subreaders are up to date. + + /// Checks recursively if all subreaders are up to date. virtual bool isCurrent(); - - /// Checks recursively if all subindexes are optimized + + /// Checks recursively if all subindexes are optimized virtual bool isOptimized(); - + /// Not implemented. virtual int64_t getVersion(); - + Collection getSubReaders(); - - /// Get a list of unique field names that exist in this index and have the specified field option + + /// Get a list of unique field names that exist in this index and have the specified field option /// information. virtual HashSet getFieldNames(FieldOption fieldOption); - + protected: IndexReaderPtr doReopen(bool doClone); - + /// Implements deletion of the document numbered docNum. virtual void doDelete(int32_t docNum); - + /// Implements actual undeleteAll(). virtual void doUndeleteAll(); - + /// Implements setNorm in subclass. virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - + /// Implements commit. virtual void doCommit(MapStringString commitUserData); - + /// Implements close. virtual void doClose(); - + friend class ParallelTermEnum; friend class ParallelTermDocs; friend class ParallelTermPositions; diff --git a/include/Payload.h b/include/Payload.h index a05ddf8a..df31ed24 100644 --- a/include/Payload.h +++ b/include/Payload.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,75 +11,75 @@ namespace Lucene { - /// A Payload is metadata that can be stored together with each occurrence of a term. This metadata is stored + /// A Payload is metadata that can be stored together with each occurrence of a term. This metadata is stored /// inline in the posting list of the specific term. /// /// To store payloads in the index a {@link TokenStream} has to be used that produces payload data. /// - /// Use {@link TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve + /// Use {@link TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve /// the payloads from the index. class LPPAPI Payload : public LuceneObject { public: /// Creates an empty payload and does not allocate a byte array. Payload(); - - /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, + + /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, /// ie. no copy is made. /// @param data the data of this payload Payload(ByteArray data); - - /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, + + /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, /// ie. no copy is made. /// @param data the data of this payload /// @param offset the offset in the data byte array /// @param length the length of the data Payload(ByteArray data, int32_t offset, int32_t length); - + virtual ~Payload(); - + LUCENE_CLASS(Payload); - + protected: /// the byte array containing the payload data ByteArray data; - + /// the offset within the byte array int32_t offset; - + /// the length of the payload data int32_t _length; - + public: /// Sets this payloads data. A reference to the passed-in array is held, ie. no copy is made. void setData(ByteArray data); - + /// Sets this payloads data. A reference to the passed-in array is held, ie. no copy is made. void setData(ByteArray data, int32_t offset, int32_t length); - + /// Returns a reference to the underlying byte array that holds this payloads data. ByteArray getData(); - - /// Returns the offset in the underlying byte array + + /// Returns the offset in the underlying byte array int32_t getOffset(); - - /// Returns the length of the payload data. + + /// Returns the length of the payload data. int32_t length(); - + /// Returns the byte at the given index. uint8_t byteAt(int32_t index); - - /// Allocates a new byte array, copies the payload data into it and returns it. + + /// Allocates a new byte array, copies the payload data into it and returns it. ByteArray toByteArray(); - + /// Copies the payload data to a byte array. /// @param target the target byte array /// @param targetOffset the offset in the target byte array void copyTo(ByteArray target, int32_t targetOffset); - + /// Clones this payload by creating a copy of the underlying byte array. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); }; diff --git a/include/PayloadAttribute.h b/include/PayloadAttribute.h index 92a567ff..7dff4d32 100644 --- a/include/PayloadAttribute.h +++ b/include/PayloadAttribute.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,26 +17,26 @@ namespace Lucene public: /// Initialize this attribute with no payload. PayloadAttribute(); - + /// Initialize this attribute with the given payload. PayloadAttribute(PayloadPtr payload); - + virtual ~PayloadAttribute(); - + LUCENE_CLASS(PayloadAttribute); - + protected: PayloadPtr payload; - + public: virtual String toString(); - + /// Returns this Token's payload. virtual PayloadPtr getPayload(); - + /// Sets this Token's payload. virtual void setPayload(PayloadPtr payload); - + virtual void clear(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual bool equals(LuceneObjectPtr other); diff --git a/include/PayloadFunction.h b/include/PayloadFunction.h index d5243597..26abcb7f 100644 --- a/include/PayloadFunction.h +++ b/include/PayloadFunction.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// An abstract class that defines a way for Payload*Query instances to transform the cumulative + /// An abstract class that defines a way for Payload*Query instances to transform the cumulative /// effects of payload scores for a document. /// /// @see PayloadTermQuery for more information @@ -23,7 +23,7 @@ namespace Lucene public: virtual ~PayloadFunction(); LUCENE_CLASS(PayloadFunction); - + public: /// Calculate the score up to this point for this doc and field /// @param docId The current doc @@ -36,7 +36,7 @@ namespace Lucene /// @return The new current Score /// /// @see Spans - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) = 0; /// Calculate the final score for all the payloads seen so far for this doc/field @@ -46,10 +46,10 @@ namespace Lucene /// @param payloadScore The raw score for those payloads /// @return The final score for the payloads virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) = 0; - + /// Return hash code for this object. virtual int32_t hashCode() = 0; - + /// Return whether two objects are equal virtual bool equals(LuceneObjectPtr other) = 0; }; diff --git a/include/PayloadNearQuery.h b/include/PayloadNearQuery.h index baef4cbd..ed8560bd 100644 --- a/include/PayloadNearQuery.h +++ b/include/PayloadNearQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,10 +13,10 @@ namespace Lucene { - /// This class is very similar to {@link SpanNearQuery} except that it factors in the value of the payloads + /// This class is very similar to {@link SpanNearQuery} except that it factors in the value of the payloads /// located at each of the positions where the {@link TermSpans} occurs. /// - /// In order to take advantage of this, you must override {@link Similarity#scorePayload} which returns 1 + /// In order to take advantage of this, you must override {@link Similarity#scorePayload} which returns 1 /// by default. /// /// Payload scores are aggregated using a pluggable {@link PayloadFunction}. @@ -27,72 +27,72 @@ namespace Lucene public: PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder); PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, PayloadFunctionPtr function); - + virtual ~PayloadNearQuery(); - + LUCENE_CLASS(PayloadNearQuery); - + protected: String fieldName; PayloadFunctionPtr function; - + public: using SpanNearQuery::toString; - + virtual WeightPtr createWeight(SearcherPtr searcher); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual String toString(const String& field); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + friend class PayloadNearSpanWeight; friend class PayloadNearSpanScorer; }; - + class LPPAPI PayloadNearSpanWeight : public SpanWeight { public: PayloadNearSpanWeight(SpanQueryPtr query, SearcherPtr searcher); virtual ~PayloadNearSpanWeight(); - + LUCENE_CLASS(PayloadNearSpanWeight); - + public: virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); }; - + class LPPAPI PayloadNearSpanScorer : public SpanScorer { public: PayloadNearSpanScorer(SpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms); virtual ~PayloadNearSpanScorer(); - + LUCENE_CLASS(PayloadNearSpanScorer); - + public: SpansPtr spans; SimilarityPtr similarity; - + protected: double payloadScore; int32_t payloadsSeen; - + public: /// Get the payloads associated with all underlying subspans void getPayloads(Collection subSpans); - + virtual double score(); - + protected: - /// By default, uses the {@link PayloadFunction} to score the payloads, but can be overridden to do + /// By default, uses the {@link PayloadFunction} to score the payloads, but can be overridden to do /// other things. /// @param payLoads The payloads /// @param start The start position of the span being scored /// @param end The end position of the span being scored /// @see Spans void processPayloads(Collection payLoads, int32_t start, int32_t end); - + virtual bool setFreqCurrentDoc(); virtual ExplanationPtr explain(int32_t doc); }; diff --git a/include/PayloadSpanUtil.h b/include/PayloadSpanUtil.h index 2817c382..225c0203 100644 --- a/include/PayloadSpanUtil.h +++ b/include/PayloadSpanUtil.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,26 +11,26 @@ namespace Lucene { - /// Experimental class to get set of payloads for most standard Lucene queries. Operates like Highlighter - + /// Experimental class to get set of payloads for most standard Lucene queries. Operates like Highlighter - /// IndexReader should only contain doc of interest, best to use MemoryIndex. class LPPAPI PayloadSpanUtil : public LuceneObject { public: /// @param reader That contains doc with payloads to extract PayloadSpanUtil(IndexReaderPtr reader); - + virtual ~PayloadSpanUtil(); - + LUCENE_CLASS(PayloadSpanUtil); - + protected: IndexReaderPtr reader; - + public: /// Query should be rewritten for wild/fuzzy support. /// @return payloads Collection Collection getPayloadsForQuery(QueryPtr query); - + protected: void queryToSpanQuery(QueryPtr query, Collection payloads); void getPayloads(Collection payloads, SpanQueryPtr query); diff --git a/include/PayloadTermQuery.h b/include/PayloadTermQuery.h index 7a9f16a1..dcfb7f31 100644 --- a/include/PayloadTermQuery.h +++ b/include/PayloadTermQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,10 +11,10 @@ namespace Lucene { - /// This class is very similar to {@link SpanTermQuery} except that it factors in the value of the payload + /// This class is very similar to {@link SpanTermQuery} except that it factors in the value of the payload /// located at each of the positions where the {@link Term} occurs. /// - /// In order to take advantage of this, you must override {@link Similarity#scorePayload(int32_t, const String&, + /// In order to take advantage of this, you must override {@link Similarity#scorePayload(int32_t, const String&, /// int32_t, int32_t, ByteArray, int32_t, int32_t)} which returns 1 by default. /// /// Payload scores are aggregated using a pluggable {@link PayloadFunction}. @@ -23,20 +23,20 @@ namespace Lucene public: PayloadTermQuery(TermPtr term, PayloadFunctionPtr function, bool includeSpanScore = true); virtual ~PayloadTermQuery(); - + LUCENE_CLASS(PayloadTermQuery); - + protected: PayloadFunctionPtr function; bool includeSpanScore; - + public: virtual WeightPtr createWeight(SearcherPtr searcher); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + friend class PayloadTermWeight; friend class PayloadTermSpanScorer; }; diff --git a/include/PerFieldAnalyzerWrapper.h b/include/PerFieldAnalyzerWrapper.h index 71f67248..88006bfd 100644 --- a/include/PerFieldAnalyzerWrapper.h +++ b/include/PerFieldAnalyzerWrapper.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// This analyzer is used to facilitate scenarios where different fields require different analysis techniques. + /// This analyzer is used to facilitate scenarios where different fields require different analysis techniques. /// Use {@link #addAnalyzer} to add a non-default analyzer on a field name basis. /// /// Example usage: @@ -22,7 +22,7 @@ namespace Lucene /// aWrapper->addAnalyzer(L"lastname", newLucene()); ///
  • /// - /// In this example, StandardAnalyzer will be used for all fields except "firstname" and "lastname", for which + /// In this example, StandardAnalyzer will be used for all fields except "firstname" and "lastname", for which /// KeywordAnalyzer will be used. /// /// A PerFieldAnalyzerWrapper can be used like any other analyzer, for both indexing and query parsing. @@ -30,38 +30,38 @@ namespace Lucene { public: /// Constructs with default analyzer. - /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the + /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the /// one provided here. PerFieldAnalyzerWrapper(AnalyzerPtr defaultAnalyzer); - + /// Constructs with default analyzer and a map of analyzers to use for specific fields. /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the one provided here. - /// @param fieldAnalyzers a Map (String field name to the Analyzer) to be used for those fields + /// @param fieldAnalyzers a Map (String field name to the Analyzer) to be used for those fields PerFieldAnalyzerWrapper(AnalyzerPtr defaultAnalyzer, MapStringAnalyzer fieldAnalyzers); - + virtual ~PerFieldAnalyzerWrapper(); - + LUCENE_CLASS(PerFieldAnalyzerWrapper); - + protected: AnalyzerPtr defaultAnalyzer; MapStringAnalyzer analyzerMap; - + public: /// Defines an analyzer to use for the specified field. /// @param fieldName field name requiring a non-default analyzer /// @param analyzer non-default analyzer to use for field void addAnalyzer(const String& fieldName, AnalyzerPtr analyzer); - + virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); - + /// Return the positionIncrementGap from the analyzer assigned to fieldName. virtual int32_t getPositionIncrementGap(const String& fieldName); - + /// Return the offsetGap from the analyzer assigned to field virtual int32_t getOffsetGap(FieldablePtr field); - + virtual String toString(); }; } diff --git a/include/PhrasePositions.h b/include/PhrasePositions.h index df7b5d1e..a2201e0d 100644 --- a/include/PhrasePositions.h +++ b/include/PhrasePositions.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene public: PhrasePositions(TermPositionsPtr t, int32_t o); virtual ~PhrasePositions(); - + LUCENE_CLASS(PhrasePositions); - + public: int32_t doc; // current doc int32_t position; // position in doc @@ -27,8 +27,8 @@ namespace Lucene int32_t offset; // position in phrase TermPositionsPtr tp; // stream of positions PhrasePositionsPtr _next; // used to make lists - bool repeats; // there's other pp for same term (eg. query="1st word 2nd word"~1) - + bool repeats; // there's other pp for same term (eg. query="1st word 2nd word"~1) + public: bool next(); bool skipTo(int32_t target); diff --git a/include/PhraseQuery.h b/include/PhraseQuery.h index 097129fd..3d8b4285 100644 --- a/include/PhraseQuery.h +++ b/include/PhraseQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// A Query that matches documents containing a particular sequence of terms. A PhraseQuery is built by + /// A Query that matches documents containing a particular sequence of terms. A PhraseQuery is built by /// QueryParser for input like "new york". /// /// This query may be combined with other terms or queries with a {@link BooleanQuery}. @@ -21,60 +21,60 @@ namespace Lucene /// Constructs an empty phrase query. PhraseQuery(); virtual ~PhraseQuery(); - + LUCENE_CLASS(PhraseQuery); - + protected: String field; Collection terms; Collection positions; int32_t maxPosition; int32_t slop; - + public: using Query::toString; - - /// Sets the number of other words permitted between words in query phrase. If zero, then this is an + + /// Sets the number of other words permitted between words in query phrase. If zero, then this is an /// exact phrase search. For larger values this works like a WITHIN or NEAR operator. /// - /// The slop is in fact an edit-distance, where the units correspond to moves of terms in the query phrase - /// out of position. For example, to switch the order of two words requires two moves (the first move + /// The slop is in fact an edit-distance, where the units correspond to moves of terms in the query phrase + /// out of position. For example, to switch the order of two words requires two moves (the first move /// places the words atop one another), so to permit re-orderings of phrases, the slop must be at least two. /// /// More exact matches are scored higher than sloppier matches, thus search results are sorted by exactness. /// /// The slop is zero by default, requiring exact matches. void setSlop(int32_t slop); - + /// Returns the slop. /// @see #setSlop() int32_t getSlop(); - + /// Adds a term to the end of the query phrase. /// The relative position of the term is the one immediately after the last term added. void add(TermPtr term); - + /// Adds a term to the end of the query phrase. - /// The relative position of the term within the phrase is specified explicitly. This allows eg. phrases + /// The relative position of the term within the phrase is specified explicitly. This allows eg. phrases /// with more than one term at the same position or phrases with gaps (eg. in connection with stopwords). void add(TermPtr term, int32_t position); - + /// Returns the set of terms in this phrase. Collection getTerms(); - + /// Returns the relative positions of terms in this phrase. Collection getPositions(); - + virtual WeightPtr createWeight(SearcherPtr searcher); virtual void extractTerms(SetTerm terms); - + /// Prints a user-readable version of this query. virtual String toString(const String& field); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + friend class PhraseWeight; }; } diff --git a/include/PhraseQueue.h b/include/PhraseQueue.h index f1e2a6cd..89436c28 100644 --- a/include/PhraseQueue.h +++ b/include/PhraseQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: PhraseQueue(int32_t size); virtual ~PhraseQueue(); - + LUCENE_CLASS(PhraseQueue); - + protected: virtual bool lessThan(const PhrasePositionsPtr& first, const PhrasePositionsPtr& second); }; diff --git a/include/PhraseScorer.h b/include/PhraseScorer.h index d4d21023..a1fd2090 100644 --- a/include/PhraseScorer.h +++ b/include/PhraseScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,56 +11,56 @@ namespace Lucene { - /// Scoring functionality for phrase queries. A document is considered matching if it contains the - /// phrase-query terms at "valid" positions. What "valid positions" are depends on the type of the - /// phrase query: for an exact phrase query terms are required to appear in adjacent locations, while - /// for a sloppy phrase query some distance between the terms is allowed. The abstract method {@link - /// #phraseFreq()} of extending classes is invoked for each document containing all the phrase query + /// Scoring functionality for phrase queries. A document is considered matching if it contains the + /// phrase-query terms at "valid" positions. What "valid positions" are depends on the type of the + /// phrase query: for an exact phrase query terms are required to appear in adjacent locations, while + /// for a sloppy phrase query some distance between the terms is allowed. The abstract method {@link + /// #phraseFreq()} of extending classes is invoked for each document containing all the phrase query /// terms, in order to compute the frequency of the phrase query in that document. A non zero frequency - /// means a match. + /// means a match. class PhraseScorer : public Scorer { public: PhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, ByteArray norms); virtual ~PhraseScorer(); - + LUCENE_CLASS(PhraseScorer); - + protected: WeightPtr weight; ByteArray norms; double value; - + bool firstTime; bool more; PhraseQueuePtr pq; PhrasePositionsPtr first; PhrasePositionsPtr last; - + double freq; // phrase frequency in current doc as computed by phraseFreq(). - + public: virtual int32_t docID(); virtual int32_t nextDoc(); virtual double score(); virtual int32_t advance(int32_t target); - + /// Phrase frequency in current doc as computed by phraseFreq(). double currentFreq(); - + virtual String toString(); - + protected: /// Next without initial increment bool doNext(); - - /// For a document containing all the phrase query terms, compute the frequency of the phrase in + + /// For a document containing all the phrase query terms, compute the frequency of the phrase in /// that document. A non zero frequency means a match. - /// Note, that containing all phrase terms does not guarantee a match - they have to be found in + /// Note, that containing all phrase terms does not guarantee a match - they have to be found in /// matching locations. - /// @return frequency of the phrase in current doc, 0 if not found. + /// @return frequency of the phrase in current doc, 0 if not found. virtual double phraseFreq() = 0; - + void init(); void sort(); void pqToList(); diff --git a/include/PorterStemFilter.h b/include/PorterStemFilter.h index 7807b5a9..90d5b88f 100644 --- a/include/PorterStemFilter.h +++ b/include/PorterStemFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,11 +11,11 @@ namespace Lucene { - /// Transforms the token stream as per the Porter stemming algorithm. Note: the input to the stemming filter must - /// already be in lower case, so you will need to use LowerCaseFilter or LowerCaseTokenizer further down the Tokenizer + /// Transforms the token stream as per the Porter stemming algorithm. Note: the input to the stemming filter must + /// already be in lower case, so you will need to use LowerCaseFilter or LowerCaseTokenizer further down the Tokenizer /// chain in order for this to work properly. /// - /// To use this filter with other analyzers, you'll want to write an Analyzer class that sets up the TokenStream chain + /// To use this filter with other analyzers, you'll want to write an Analyzer class that sets up the TokenStream chain /// as you want it. To use this with LowerCaseTokenizer, for example, you'd write an analyzer like this: /// ///
    @@ -33,13 +33,13 @@ namespace Lucene
         public:
             PorterStemFilter(TokenStreamPtr input);
             virtual ~PorterStemFilter();
    -        
    +
             LUCENE_CLASS(PorterStemFilter);
    -    
    +
         protected:
             PorterStemmerPtr stemmer;
             TermAttributePtr termAtt;
    -    
    +
         public:
             virtual bool incrementToken();
         };
    diff --git a/include/PorterStemmer.h b/include/PorterStemmer.h
    index fd619c5e..95e85248 100644
    --- a/include/PorterStemmer.h
    +++ b/include/PorterStemmer.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -13,13 +13,13 @@ namespace Lucene
     {
         /// This is the Porter stemming algorithm, coded up as thread-safe ANSI C by the author.
         ///
    -    /// It may be be regarded as canonical, in that it follows the algorithm presented in Porter, 1980, An algorithm 
    +    /// It may be be regarded as canonical, in that it follows the algorithm presented in Porter, 1980, An algorithm
         /// for suffix stripping, Program, Vol. 14, no. 3, pp 130-137, only differing from it at the points marked DEPARTURE.
         ///
         /// See also http://www.tartarus.org/~martin/PorterStemmer
         ///
    -    /// The algorithm as described in the paper could be exactly replicated by adjusting the points of DEPARTURE, but 
    -    /// this is barely necessary, because (a) the points of DEPARTURE are definitely improvements, and (b) no encoding 
    +    /// The algorithm as described in the paper could be exactly replicated by adjusting the points of DEPARTURE, but
    +    /// this is barely necessary, because (a) the points of DEPARTURE are definitely improvements, and (b) no encoding
         /// of the Porter stemmer I have seen is anything like as exact as this version, even with the points of DEPARTURE!
         ///
         /// Release 2 (the more old-fashioned, non-thread-safe version may be regarded as release 1.)
    @@ -28,32 +28,32 @@ namespace Lucene
         public:
             PorterStemmer();
             virtual ~PorterStemmer();
    -        
    +
             LUCENE_CLASS(PorterStemmer);
    -    
    +
         protected:
             wchar_t* b; // buffer for word to be stemmed
             int32_t k; // offset to the end of the string
             int32_t j; // a general offset into the string
             int32_t i; // initial length of word
             bool dirty;
    -    
    +
         public:
             bool stem(CharArray word);
    -        
    -        /// In stem(b, k), b is a char pointer, and the string to be stemmed is from b[0] to b[k] inclusive.  
    -        /// Possibly b[k+1] == '\0', but it is not important. The stemmer adjusts the characters b[0] ... b[k] and 
    +
    +        /// In stem(b, k), b is a char pointer, and the string to be stemmed is from b[0] to b[k] inclusive.
    +        /// Possibly b[k+1] == '\0', but it is not important. The stemmer adjusts the characters b[0] ... b[k] and
             /// stores the new end-point of the string, k'. Stemming never increases word length, so 0 <= k' <= k.
             bool stem(wchar_t* b, int32_t k);
    -        
    +
             wchar_t* getResultBuffer();
             int32_t getResultLength();
    -    
    +
         protected:
             /// Returns true if b[i] is a consonant. ('b' means 'z->b', but here and below we drop 'z->' in comments.
             bool cons(int32_t i);
    -        
    -        /// Measures the number of consonant sequences between 0 and j.  If c is a consonant sequence and v a vowel 
    +
    +        /// Measures the number of consonant sequences between 0 and j.  If c is a consonant sequence and v a vowel
             /// sequence, and <..> indicates arbitrary presence,
             ///
             ///        gives 0
    @@ -62,28 +62,28 @@ namespace Lucene
             /// vcvcvc gives 3
             /// ...
             int32_t m();
    -        
    +
             /// Return true if 0,...j contains a vowel
             bool vowelinstem();
    -        
    +
             /// Return true if j,(j-1) contain a double consonant.
             bool doublec(int32_t j);
    -        
    -        /// Return true if i-2,i-1,i has the form consonant - vowel - consonant and also if the second c is not w,x or y. 
    -        /// This is used when trying to restore an e at the end of a short word. 
    +
    +        /// Return true if i-2,i-1,i has the form consonant - vowel - consonant and also if the second c is not w,x or y.
    +        /// This is used when trying to restore an e at the end of a short word.
             ///
             /// eg. cav(e), lov(e), hop(e), crim(e), but
             /// snow, box, tray.
             bool cvc(int32_t i);
    -        
    +
             /// Returns true if 0,...k ends with the string s.
             bool ends(const wchar_t* s);
    -        
    +
             /// Sets (j+1),...k to the characters in the string s, readjusting k.
             void setto(const wchar_t* s);
    -        
    +
             void r(const wchar_t* s);
    -        
    +
             /// step1ab() gets rid of plurals and -ed or -ing. eg.
             ///
             /// caresses  ->  caress
    @@ -104,20 +104,20 @@ namespace Lucene
             ///
             /// meetings  ->  meet
             void step1ab();
    -        
    +
             /// Turns terminal y to i when there is another vowel in the stem.
             void step1c();
    -        
    -        /// Maps double suffices to single ones. so -ization ( = -ize plus -ation) maps to -ize etc. note that the 
    +
    +        /// Maps double suffices to single ones. so -ization ( = -ize plus -ation) maps to -ize etc. note that the
             /// string before the suffix must give m() > 0.
             void step2();
    -        
    +
             /// Deals with -ic-, -full, -ness etc. similar strategy to step2.
             void step3();
    -        
    +
             /// Takes off -ant, -ence etc., in context vcvc.
             void step4();
    -        
    +
             /// Removes a final -e if m() > 1, and changes -ll to -l if m() > 1.
             void step5();
         };
    diff --git a/include/PositionBasedTermVectorMapper.h b/include/PositionBasedTermVectorMapper.h
    index 8be2aa7b..7aa72816 100644
    --- a/include/PositionBasedTermVectorMapper.h
    +++ b/include/PositionBasedTermVectorMapper.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -16,61 +16,61 @@ namespace Lucene
         public:
             PositionBasedTermVectorMapper(bool ignoringOffsets = false);
             virtual ~PositionBasedTermVectorMapper();
    -        
    +
             LUCENE_CLASS(PositionBasedTermVectorMapper);
    -            
    +
         protected:
             MapStringMapIntTermVectorsPositionInfo fieldToTerms;
    -        
    +
             String currentField;
    -        
    +
             /// A Map of Integer and TermVectorsPositionInfo
             MapIntTermVectorsPositionInfo currentPositions;
    -        
    +
             bool storeOffsets;
    -    
    +
         public:
             /// Never ignores positions.  This mapper doesn't make much sense unless there are positions.
             /// @return false
             virtual bool isIgnoringPositions();
    -        
    -        /// Callback for the TermVectorReader. 
    +
    +        /// Callback for the TermVectorReader.
             virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions);
    -        
    +
             /// Callback mechanism used by the TermVectorReader.
             virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions);
    -        
    +
             /// Get the mapping between fields and terms, sorted by the comparator
    -        /// @return A map between field names and a Map.  The sub-Map key is the position as the integer, the value is 
    +        /// @return A map between field names and a Map.  The sub-Map key is the position as the integer, the value is
             /// {@link PositionBasedTermVectorMapper}.
             MapStringMapIntTermVectorsPositionInfo getFieldToTerms();
         };
    -    
    +
         /// Container for a term at a position
         class LPPAPI TermVectorsPositionInfo : public LuceneObject
         {
         public:
             TermVectorsPositionInfo(int32_t position, bool storeOffsets);
             virtual ~TermVectorsPositionInfo();
    -        
    +
             LUCENE_CLASS(TermVectorsPositionInfo);
    -            
    +
         protected:
             int32_t position;
             Collection terms;
             Collection offsets;
    -    
    +
         public:
             void addTerm(const String& term, TermVectorOffsetInfoPtr info);
    -        
    +
             /// @return The position of the term
             int32_t getPosition();
    -        
    +
             /// Note, there may be multiple terms at the same position
             /// @return A List of Strings
             Collection getTerms();
    -        
    -        /// Parallel list (to {@link #getTerms()}) of TermVectorOffsetInfo objects.  There may be multiple 
    +
    +        /// Parallel list (to {@link #getTerms()}) of TermVectorOffsetInfo objects.  There may be multiple
             /// entries since there may be multiple terms at a position.
             /// @return A List of TermVectorOffsetInfo objects, if offsets are stored.
             Collection getOffsets();
    diff --git a/include/PositionIncrementAttribute.h b/include/PositionIncrementAttribute.h
    index 37235746..3e3b8abd 100644
    --- a/include/PositionIncrementAttribute.h
    +++ b/include/PositionIncrementAttribute.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -11,21 +11,21 @@
     
     namespace Lucene
     {
    -    /// The positionIncrement determines the position of this token relative to the previous Token in a 
    +    /// The positionIncrement determines the position of this token relative to the previous Token in a
         /// TokenStream, used in phrase searching.
         ///
         /// The default value is one.
         ///
         /// Some common uses for this are:
         ///
    -    /// Set it to zero to put multiple terms in the same position.  This is useful if, eg., a word has multiple 
    +    /// Set it to zero to put multiple terms in the same position.  This is useful if, eg., a word has multiple
         /// stems.  Searches for phrases including either stem will match.  In this case, all but the first stem's
    -    /// increment should be set to zero: the increment of the first instance should be one.  Repeating a token 
    +    /// increment should be set to zero: the increment of the first instance should be one.  Repeating a token
         /// with an increment of zero can also be used to boost the scores of matches on that token.
         ///
    -    /// Set it to values greater than one to inhibit exact phrase matches.  If, for example, one does not want 
    -    /// phrases to match across removed stop words, then one could build a stop word filter that removes stop 
    -    /// words and also sets the increment to the number of stop words removed before each non-stop word.  Then 
    +    /// Set it to values greater than one to inhibit exact phrase matches.  If, for example, one does not want
    +    /// phrases to match across removed stop words, then one could build a stop word filter that removes stop
    +    /// words and also sets the increment to the number of stop words removed before each non-stop word.  Then
         /// exact phrase queries will only match when the terms occur with no intervening stop words.
         ///
         /// @see TermPositions
    @@ -34,23 +34,23 @@ namespace Lucene
         public:
             PositionIncrementAttribute();
             virtual ~PositionIncrementAttribute();
    -        
    +
             LUCENE_CLASS(PositionIncrementAttribute);
    -        
    +
         protected:
             int32_t positionIncrement;
    -    
    +
         public:
             virtual String toString();
    -        
    +
             /// Set the position increment. The default value is one.
             /// @param positionIncrement the distance from the prior term
             virtual void setPositionIncrement(int32_t positionIncrement);
    -        
    +
             /// Returns the position increment of this Token.
             /// @see #setPositionIncrement
             virtual int32_t getPositionIncrement();
    -        
    +
             virtual void clear();
             virtual bool equals(LuceneObjectPtr other);
             virtual int32_t hashCode();
    diff --git a/include/PositiveScoresOnlyCollector.h b/include/PositiveScoresOnlyCollector.h
    index 43f3efad..2582e0f5 100644
    --- a/include/PositiveScoresOnlyCollector.h
    +++ b/include/PositiveScoresOnlyCollector.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -11,20 +11,20 @@
     
     namespace Lucene
     {
    -    /// A {@link Collector} implementation which wraps another {@link Collector} and makes sure only 
    +    /// A {@link Collector} implementation which wraps another {@link Collector} and makes sure only
         /// documents with scores > 0 are collected.
         class LPPAPI PositiveScoresOnlyCollector : public Collector
         {
         public:
             PositiveScoresOnlyCollector(CollectorPtr c);
             virtual ~PositiveScoresOnlyCollector();
    -    
    +
             LUCENE_CLASS(PositiveScoresOnlyCollector);
    -    
    +
         protected:
             CollectorPtr collector;
             ScorerPtr scorer;
    -    
    +
         public:
             virtual void collect(int32_t doc);
             virtual void setNextReader(IndexReaderPtr reader, int32_t docBase);
    diff --git a/include/PrefixFilter.h b/include/PrefixFilter.h
    index f9ebae72..2ddda2f1 100644
    --- a/include/PrefixFilter.h
    +++ b/include/PrefixFilter.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -17,12 +17,12 @@ namespace Lucene
         public:
             PrefixFilter(TermPtr prefix);
             virtual ~PrefixFilter();
    -    
    +
             LUCENE_CLASS(PrefixFilter);
    -    
    +
         public:
             TermPtr getPrefix();
    -        
    +
             virtual String toString();
         };
     }
    diff --git a/include/PrefixQuery.h b/include/PrefixQuery.h
    index 0acf7e4e..27b40bb7 100644
    --- a/include/PrefixQuery.h
    +++ b/include/PrefixQuery.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -11,7 +11,7 @@
     
     namespace Lucene
     {
    -    /// A Query that matches documents containing terms with a specified prefix. A PrefixQuery is built by 
    +    /// A Query that matches documents containing terms with a specified prefix. A PrefixQuery is built by
         /// QueryParser for input like app*.
         ///
         /// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method.
    @@ -20,27 +20,27 @@ namespace Lucene
         public:
             /// Constructs a query for terms starting with prefix.
             PrefixQuery(TermPtr prefix);
    -        
    +
             virtual ~PrefixQuery();
    -    
    +
             LUCENE_CLASS(PrefixQuery);
    -    
    +
         protected:
             TermPtr prefix;
    -    
    +
         public:
             using MultiTermQuery::toString;
    -        
    +
             /// Returns the prefix of this query.
             TermPtr getPrefix();
    -        
    +
             /// Prints a user-readable version of this query.
             virtual String toString(const String& field);
    -        
    +
             virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr());
             virtual int32_t hashCode();
             virtual bool equals(LuceneObjectPtr other);
    -    
    +
         protected:
             virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader);
         };
    diff --git a/include/PrefixTermEnum.h b/include/PrefixTermEnum.h
    index b639fa9d..b0aa6769 100644
    --- a/include/PrefixTermEnum.h
    +++ b/include/PrefixTermEnum.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -13,27 +13,27 @@ namespace Lucene
     {
         /// Subclass of FilteredTermEnum for enumerating all terms that match the specified prefix filter term.
         ///
    -    /// Term enumerations are always ordered by Term.compareTo().  Each term in the enumeration is greater than 
    +    /// Term enumerations are always ordered by Term.compareTo().  Each term in the enumeration is greater than
         /// all that precede it.
         class LPPAPI PrefixTermEnum : public FilteredTermEnum
         {
         public:
             PrefixTermEnum(IndexReaderPtr reader, TermPtr prefix);
             virtual ~PrefixTermEnum();
    -    
    +
             LUCENE_CLASS(PrefixTermEnum);
    -    
    +
         protected:
             TermPtr prefix;
             bool _endEnum;
    -    
    +
         public:
             virtual double difference();
    -    
    +
         protected:
             virtual bool endEnum();
             virtual bool termCompare(TermPtr term);
    -        
    +
             TermPtr getPrefixTerm();
         };
     }
    diff --git a/include/PriorityQueue.h b/include/PriorityQueue.h
    index 6d3ffb31..2675412f 100644
    --- a/include/PriorityQueue.h
    +++ b/include/PriorityQueue.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    diff --git a/include/Query.h b/include/Query.h
    index ba992686..8ec8ce23 100644
    --- a/include/Query.h
    +++ b/include/Query.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -33,77 +33,77 @@ namespace Lucene
         public:
             Query();
             virtual ~Query();
    -        
    +
             LUCENE_CLASS(Query);
    -    
    +
         protected:
             double boost; // query boost factor
    -            
    +
         public:
    -        /// Sets the boost for this query clause to b.  Documents matching this clause will (in addition to 
    +        /// Sets the boost for this query clause to b.  Documents matching this clause will (in addition to
             /// the normal weightings) have their score multiplied by b.
             virtual void setBoost(double b);
    -        
    +
             /// Gets the boost for this clause.  Documents matching this clause will (in addition to the normal
             /// weightings) have their score multiplied by b.   The boost is 1.0 by default.
             virtual double getBoost();
    -        
    +
             /// Prints a query to a string, with field assumed to be the default field and omitted.
             ///
             /// The representation used is one that is supposed to be readable by {@link QueryParser}. However,
             /// there are the following limitations:
             ///
    -        /// If the query was created by the parser, the printed representation may not be exactly what was 
    -        /// parsed. For example, characters that need to be escaped will be represented without the required 
    +        /// If the query was created by the parser, the printed representation may not be exactly what was
    +        /// parsed. For example, characters that need to be escaped will be represented without the required
             /// backslash.
             ///
    -        /// Some of the more complicated queries (eg. span queries) don't have a representation that can be 
    +        /// Some of the more complicated queries (eg. span queries) don't have a representation that can be
             /// parsed by QueryParser.
             virtual String toString(const String& field);
    -        
    +
             /// Prints a query to a string.
             virtual String toString();
    -        
    +
             /// Constructs an appropriate Weight implementation for this query.
             /// Only implemented by primitive queries, which re-write to themselves.
             virtual WeightPtr createWeight(SearcherPtr searcher);
    -        
    +
             /// Constructs and initializes a Weight for a top-level query.
             virtual WeightPtr weight(SearcherPtr searcher);
    -        
    -        /// Called to re-write queries into primitive queries.  For example, a PrefixQuery will be rewritten 
    +
    +        /// Called to re-write queries into primitive queries.  For example, a PrefixQuery will be rewritten
             /// into a BooleanQuery that consists of TermQuerys.
             virtual QueryPtr rewrite(IndexReaderPtr reader);
    -        
    +
             /// Called when re-writing queries under MultiSearcher.
             ///
    -        /// Create a single query suitable for use by all subsearchers (in 1-1 correspondence with queries). 
    +        /// Create a single query suitable for use by all subsearchers (in 1-1 correspondence with queries).
             /// This is an optimization of the OR of all queries. We handle the common optimization cases of equal
             /// queries and overlapping clauses of boolean OR queries (as generated by MultiTermQuery.rewrite()).
    -        /// Be careful overriding this method as queries[0] determines which method will be called and is not 
    +        /// Be careful overriding this method as queries[0] determines which method will be called and is not
             /// necessarily of the same type as the other queries.
             virtual QueryPtr combine(Collection queries);
    -        
    -        /// Adds all terms occurring in this query to the terms set.  Only works if this query is in its 
    +
    +        /// Adds all terms occurring in this query to the terms set.  Only works if this query is in its
             /// {@link #rewrite rewritten} form.
             virtual void extractTerms(SetTerm terms);
    -        
    +
             /// Merges the clauses of a set of BooleanQuery's into a single BooleanQuery.
             ///
             /// A utility for use by {@link #combine(Query[])} implementations.
             static QueryPtr mergeBooleanQueries(Collection queries);
    -        
    -        /// Returns the Similarity implementation to be used for this query.  Subclasses may override this method 
    +
    +        /// Returns the Similarity implementation to be used for this query.  Subclasses may override this method
             /// to specify their own Similarity implementation, perhaps one that delegates through that of the Searcher.
             /// By default the Searcher's Similarity implementation is returned.
             virtual SimilarityPtr getSimilarity(SearcherPtr searcher);
    -        
    +
             /// Returns a clone of this query.
             virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr());
    -        
    +
             virtual int32_t hashCode();
             virtual bool equals(LuceneObjectPtr other);
    -        
    +
             /// Return given boost value as a string.
             String boostString();
         };
    diff --git a/include/QueryParseError.h b/include/QueryParseError.h
    index 32bfa42d..d4de3cbf 100644
    --- a/include/QueryParseError.h
    +++ b/include/QueryParseError.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -17,9 +17,9 @@ namespace Lucene
         public:
             virtual ~QueryParseError();
             LUCENE_CLASS(QueryParseError);
    -    
    +
         public:
    -        /// Returns a detailed message for the Error when it is thrown by the token manager to indicate a 
    +        /// Returns a detailed message for the Error when it is thrown by the token manager to indicate a
             /// lexical error.
             /// @param EOFSeen Indicates if EOF caused the lexical error
             /// @param curLexState Lexical state in which this error occurred
    @@ -27,24 +27,24 @@ namespace Lucene
             /// @param errorColumn Column number when the error occurred
             /// @param errorAfter Prefix that was seen before this error occurred
             /// @param curChar The offending character
    -        static String lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, 
    +        static String lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn,
                                        const String& errorAfter, wchar_t curChar);
     
             /// Generate a parse error message and returns it.
    -        /// @param currentToken This is the last token that has been consumed successfully.  If this object 
    -        /// has been created due to a parse error, the token following this token will (therefore) be the first 
    +        /// @param currentToken This is the last token that has been consumed successfully.  If this object
    +        /// has been created due to a parse error, the token following this token will (therefore) be the first
             /// error token.
    -        /// @param expectedTokenSequences Each entry in this array is an array of integers.  Each array of 
    -        /// integers represents a sequence of tokens (by their ordinal values) that is expected at this point 
    +        /// @param expectedTokenSequences Each entry in this array is an array of integers.  Each array of
    +        /// integers represents a sequence of tokens (by their ordinal values) that is expected at this point
             /// of the parse.
    -        /// @param tokenImage This is a reference to the "tokenImage" array of the generated parser within 
    +        /// @param tokenImage This is a reference to the "tokenImage" array of the generated parser within
             /// which the parse error occurred.
             static String parseError(QueryParserTokenPtr currentToken, Collection< Collection > expectedTokenSequences,
                                      Collection tokenImage);
     
    -    
    +
         protected:
    -        /// Replaces unprintable characters by their escaped (or unicode escaped) equivalents in the 
    +        /// Replaces unprintable characters by their escaped (or unicode escaped) equivalents in the
             /// given string
             static String addEscapes(const String& str);
         };
    diff --git a/include/QueryParser.h b/include/QueryParser.h
    index 792be977..b976e353 100644
    --- a/include/QueryParser.h
    +++ b/include/QueryParser.h
    @@ -1,5 +1,5 @@
     /////////////////////////////////////////////////////////////////////////////
    -// Copyright (c) 2009-2011 Alan Wright. All rights reserved.
    +// Copyright (c) 2009-2014 Alan Wright. All rights reserved.
     // Distributable under the terms of either the Apache License (Version 2.0)
     // or the GNU Lesser General Public License.
     /////////////////////////////////////////////////////////////////////////////
    @@ -14,7 +14,7 @@
     namespace Lucene
     {
         typedef HashMap MapStringResolution;
    -    
    +
         /// The most important method is {@link #parse(const String&)}.
         ///
         /// The syntax for query strings is as follows:
    @@ -22,14 +22,14 @@ namespace Lucene
         /// A clause may be prefixed by:
         /// 
      ///
    • a plus (+) or a minus (-) sign, indicating that the clause is required or prohibited respectively; or - ///
    • a term followed by a colon, indicating the field to be searched. This enables one to construct queries + ///
    • a term followed by a colon, indicating the field to be searched. This enables one to construct queries /// which search multiple fields. ///
    /// /// A clause may be either: ///
      ///
    • a term, indicating all the documents that contain this term; or - ///
    • a nested query, enclosed in parentheses. Note that this may be used with a +/- prefix to require any + ///
    • a nested query, enclosed in parentheses. Note that this may be used with a +/- prefix to require any /// of a set of terms. ///
    /// @@ -41,21 +41,21 @@ namespace Lucene /// /// Examples of appropriately formatted queries can be found in the query syntax documentation. /// - /// In {@link TermRangeQuery}s, QueryParser tries to detect date values, eg. - /// date:[6/1/2005 TO 6/4/2005] produces a range query that searches for "date" fields between - /// 2005-06-01 and 2005-06-04. Note that the format of the accepted input depends on {@link #setLocale(Locale) + /// In {@link TermRangeQuery}s, QueryParser tries to detect date values, eg. + /// date:[6/1/2005 TO 6/4/2005] produces a range query that searches for "date" fields between + /// 2005-06-01 and 2005-06-04. Note that the format of the accepted input depends on {@link #setLocale(Locale) /// the locale}. /// - /// By default a date is converted into a search term using the deprecated {@link DateField} for compatibility + /// By default a date is converted into a search term using the deprecated {@link DateField} for compatibility /// reasons. To use the new {@link DateTools} to convert dates, a {@link Resolution} has to be set. /// /// The date resolution that shall be used for RangeQueries can be set using {@link #setDateResolution(Resolution)} - /// or {@link #setDateResolution(const String&, Resolution)}. The former sets the default date resolution for + /// or {@link #setDateResolution(const String&, Resolution)}. The former sets the default date resolution for /// all fields, whereas the latter can be used to set field specific date resolutions. Field specific date /// resolutions take, if set, precedence over the default date resolution. /// - /// If you use neither {@link DateField} nor {@link DateTools} in your index, you can create your own query - /// parser that inherits QueryParser and overwrites {@link #getRangeQuery(const String&, const String&, + /// If you use neither {@link DateField} nor {@link DateTools} in your index, you can create your own query + /// parser that inherits QueryParser and overwrites {@link #getRangeQuery(const String&, const String&, /// const String&, bool)} to use a different method for date conversion. /// /// Note that QueryParser is not thread-safe. @@ -75,47 +75,47 @@ namespace Lucene /// @param field The default field for query terms. /// @param analyzer Used to find terms in the query text. QueryParser(LuceneVersion::Version matchVersion, const String& field, AnalyzerPtr analyzer); - + /// Constructor with user supplied QueryParserCharStream. QueryParser(QueryParserCharStreamPtr stream); - + /// Constructor with generated Token Manager. QueryParser(QueryParserTokenManagerPtr tokenMgr); - + virtual ~QueryParser(); - + LUCENE_CLASS(QueryParser); - + /// The default operator for parsing queries. Use {@link QueryParser#setDefaultOperator} to change it. enum Operator { OR_OPERATOR, AND_OPERATOR }; - + protected: static const int32_t CONJ_NONE; static const int32_t CONJ_AND; static const int32_t CONJ_OR; - + static const int32_t MOD_NONE; static const int32_t MOD_NOT; static const int32_t MOD_REQ; - + /// The actual operator that parser uses to combine query terms Operator _operator; - + /// Next token. int32_t _jj_ntk; QueryParserTokenPtr jj_scanpos; QueryParserTokenPtr jj_lastpos; - + int32_t jj_la; int32_t jj_gen; Collection jj_la1; - + static const int32_t jj_la1_0[]; static const int32_t jj_la1_1[]; - + struct JJCalls; typedef boost::shared_ptr JJCallsPtr; - + struct JJCalls { JJCalls() @@ -123,253 +123,253 @@ namespace Lucene gen = 0; arg = 0; } - + int32_t gen; QueryParserTokenPtr first; int32_t arg; JJCallsPtr next; }; - + Collection jj_2_rtns; bool jj_rescan; int32_t jj_gc; - + Collection< Collection > jj_expentries; Collection jj_expentry; int32_t jj_kind; Collection jj_lasttokens; int32_t jj_endpos; - + public: bool lowercaseExpandedTerms; RewriteMethodPtr multiTermRewriteMethod; bool allowLeadingWildcard; bool enablePositionIncrements; - + AnalyzerPtr analyzer; String field; int32_t phraseSlop; double fuzzyMinSim; int32_t fuzzyPrefixLength; std::locale locale; - + // the default date resolution DateTools::Resolution dateResolution; - + // maps field names to date resolutions MapStringResolution fieldToDateResolution; - + // The collator to use when determining range inclusion, for use when constructing RangeQuerys CollatorPtr rangeCollator; - + /// Generated Token Manager. QueryParserTokenManagerPtr token_source; - + /// Current token. QueryParserTokenPtr token; - + /// Next token. - QueryParserTokenPtr jj_nt; - + QueryParserTokenPtr jj_nt; + public: /// Parses a query string, returning a {@link Query}. /// @param query The query string to be parsed. QueryPtr parse(const String& query); - + /// @return Returns the analyzer. AnalyzerPtr getAnalyzer(); - + /// @return Returns the field. String getField(); - + /// Get the minimal similarity for fuzzy queries. double getFuzzyMinSim(); - + /// Set the minimum similarity for fuzzy queries. Default is 0.5. void setFuzzyMinSim(double fuzzyMinSim); - - /// Get the prefix length for fuzzy queries. + + /// Get the prefix length for fuzzy queries. /// @return Returns the fuzzyPrefixLength. int32_t getFuzzyPrefixLength(); - + /// Set the prefix length for fuzzy queries. Default is 0. /// @param fuzzyPrefixLength The fuzzyPrefixLength to set. void setFuzzyPrefixLength(int32_t fuzzyPrefixLength); - - /// Sets the default slop for phrases. If zero, then exact phrase matches are required. + + /// Sets the default slop for phrases. If zero, then exact phrase matches are required. /// Default value is zero. void setPhraseSlop(int32_t phraseSlop); - + /// Gets the default slop for phrases. int32_t getPhraseSlop(); - + /// Set to true to allow leading wildcard characters. /// /// When set, * or ? are allowed as the first character of a PrefixQuery and WildcardQuery. /// Note that this can produce very slow queries on big indexes. Default: false. void setAllowLeadingWildcard(bool allowLeadingWildcard); - + /// @see #setAllowLeadingWildcard(bool) bool getAllowLeadingWildcard(); - + /// Set to true to enable position increments in result query. /// /// When set, result phrase and multi-phrase queries will be aware of position increments. - /// Useful when eg. a StopFilter increases the position increment of the token that follows an + /// Useful when eg. a StopFilter increases the position increment of the token that follows an /// omitted token. Default: false. void setEnablePositionIncrements(bool enable); - + /// @see #setEnablePositionIncrements(bool) bool getEnablePositionIncrements(); - - /// Sets the boolean operator of the QueryParser. In default mode (OR_OPERATOR) terms without - /// any modifiers are considered optional: for example capital of Hungary is equal to capital + + /// Sets the boolean operator of the QueryParser. In default mode (OR_OPERATOR) terms without + /// any modifiers are considered optional: for example capital of Hungary is equal to capital /// OR of OR Hungary. - /// In AND_OPERATOR mode terms are considered to be in conjunction: the above mentioned query is + /// In AND_OPERATOR mode terms are considered to be in conjunction: the above mentioned query is /// parsed as capital AND of AND Hungary void setDefaultOperator(Operator op); - + /// Gets implicit operator setting, which will be either AND_OPERATOR or OR_OPERATOR. Operator getDefaultOperator(); - - /// Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically lower-cased + + /// Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically lower-cased /// or not. Default is true. void setLowercaseExpandedTerms(bool lowercaseExpandedTerms); - + /// @see #setLowercaseExpandedTerms(bool) bool getLowercaseExpandedTerms(); - - /// By default QueryParser uses {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} when - /// creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable - /// because it a) Runs faster b) Does not have the scarcity of terms unduly influence score c) avoids + + /// By default QueryParser uses {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} when + /// creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable + /// because it a) Runs faster b) Does not have the scarcity of terms unduly influence score c) avoids /// any "TooManyClauses" exception. However, if your application really needs to use the old- - /// fashioned BooleanQuery expansion rewriting and the above points are not relevant then use this + /// fashioned BooleanQuery expansion rewriting and the above points are not relevant then use this /// to change the rewrite method. void setMultiTermRewriteMethod(RewriteMethodPtr method); - + /// @see #setMultiTermRewriteMethod RewriteMethodPtr getMultiTermRewriteMethod(); - + /// Set locale used by date range parsing. void setLocale(std::locale locale); - + /// Returns current locale, allowing access by subclasses. std::locale getLocale(); - - /// Sets the default date resolution used by RangeQueries for fields for which no specific date - /// resolutions has been set. Field specific resolutions can be set with {@link + + /// Sets the default date resolution used by RangeQueries for fields for which no specific date + /// resolutions has been set. Field specific resolutions can be set with {@link /// #setDateResolution(const String&, DateTools::Resolution)}. /// @param dateResolution The default date resolution to set void setDateResolution(DateTools::Resolution dateResolution); - + /// Sets the date resolution used by RangeQueries for a specific field. - /// @param fieldName Field for which the date resolution is to be set + /// @param fieldName Field for which the date resolution is to be set /// @param dateResolution Date resolution to set void setDateResolution(const String& fieldName, DateTools::Resolution dateResolution); - - /// Returns the date resolution that is used by RangeQueries for the given field. Returns null, if + + /// Returns the date resolution that is used by RangeQueries for the given field. Returns null, if /// no default or field specific date resolution has been set for the given field. DateTools::Resolution getDateResolution(const String& fieldName); - + /// Sets the collator used to determine index term inclusion in ranges for RangeQuerys. /// - /// WARNING: Setting the rangeCollator to a non-null collator using this method will cause every - /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending + /// WARNING: Setting the rangeCollator to a non-null collator using this method will cause every + /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending /// on the number of index Terms in this Field, the operation could be very slow. /// @param rc The collator to use when constructing RangeQuerys void setRangeCollator(CollatorPtr rc); - + /// @return the collator used to determine index term inclusion in ranges for RangeQuerys. CollatorPtr getRangeCollator(); - + /// Command line tool to test QueryParser, using {@link SimpleAnalyzer}. static int main(Collection args); - + /// Query ::= ( Clause )* /// Clause ::= ["+", "-"] [ ":"] ( | "(" Query ")" ) int32_t Conjunction(); int32_t Modifiers(); - + /// This makes sure that there is no garbage after the query string virtual QueryPtr TopLevelQuery(const String& field); - + virtual QueryPtr ParseQuery(const String& field); virtual QueryPtr ParseClause(const String& field); virtual QueryPtr ParseTerm(const String& field); - + /// Reinitialise. virtual void ReInit(QueryParserCharStreamPtr stream); - + /// Reinitialise. virtual void ReInit(QueryParserTokenManagerPtr tokenMgr); - + /// Get the next Token. virtual QueryParserTokenPtr getNextToken(); - + /// Get the specific Token. virtual QueryParserTokenPtr getToken(int32_t index); - + /// Generate QueryParserError exception. virtual void generateParseException(); - + /// Enable tracing. virtual void enable_tracing(); - + /// Disable tracing. virtual void disable_tracing(); - + protected: /// Construct query parser with supplied QueryParserCharStream or TokenManager void ConstructParser(QueryParserCharStreamPtr stream, QueryParserTokenManagerPtr tokenMgr); - + virtual void addClause(Collection clauses, int32_t conj, int32_t mods, QueryPtr q); - - /// Use the analyzer to get all the tokens, and then build a TermQuery, PhraseQuery, or nothing + + /// Use the analyzer to get all the tokens, and then build a TermQuery, PhraseQuery, or nothing /// based on the term count. virtual QueryPtr getFieldQuery(const String& field, const String& queryText); - + /// Base implementation delegates to {@link #getFieldQuery(const String&, const String&)}. /// This method may be overridden, for example, to return a SpanNearQuery instead of a PhraseQuery. virtual QueryPtr getFieldQuery(const String& field, const String& queryText, int32_t slop); - + /// Builds a new TermRangeQuery instance for given min/max parts virtual QueryPtr getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); - + /// Builds a new BooleanQuery instance /// @param disableCoord disable coord BooleanQueryPtr newBooleanQuery(bool disableCoord); - + /// Builds a new BooleanClause instance /// @param q sub query /// @param occur how this clause should occur when matching documents /// @return new BooleanClause instance BooleanClausePtr newBooleanClause(QueryPtr q, BooleanClause::Occur occur); - + /// Builds a new TermQuery instance /// @param term term /// @return new TermQuery instance QueryPtr newTermQuery(TermPtr term); - + /// Builds a new PhraseQuery instance /// @return new PhraseQuery instance PhraseQueryPtr newPhraseQuery(); - + /// Builds a new MultiPhraseQuery instance /// @return new MultiPhraseQuery instance MultiPhraseQueryPtr newMultiPhraseQuery(); - + /// Builds a new PrefixQuery instance /// @param prefix Prefix term /// @return new PrefixQuery instance QueryPtr newPrefixQuery(TermPtr prefix); - + /// Builds a new FuzzyQuery instance /// @param term Term /// @param minimumSimilarity minimum similarity /// @param prefixLength prefix length /// @return new FuzzyQuery Instance QueryPtr newFuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength); - + /// Builds a new TermRangeQuery instance /// @param field Field /// @param part1 min @@ -377,17 +377,17 @@ namespace Lucene /// @param inclusive true if range is inclusive /// @return new TermRangeQuery instance QueryPtr newRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); - + /// Builds a new MatchAllDocsQuery instance /// @return new MatchAllDocsQuery instance QueryPtr newMatchAllDocsQuery(); - + /// Builds a new WildcardQuery instance /// @param t wildcard term /// @return new WildcardQuery instance QueryPtr newWildcardQuery(TermPtr term); - - /// Factory method for generating query, given a set of clauses. By default creates a boolean query + + /// Factory method for generating query, given a set of clauses. By default creates a boolean query /// composed of clauses passed in. /// /// Can be overridden by extending classes, to modify query being returned. @@ -395,8 +395,8 @@ namespace Lucene /// @param clauses List that contains {@link BooleanClause} instances to join. /// @return Resulting {@link Query} object. virtual QueryPtr getBooleanQuery(Collection clauses); - - /// Factory method for generating query, given a set of clauses. By default creates a boolean query + + /// Factory method for generating query, given a set of clauses. By default creates a boolean query /// composed of clauses passed in. /// /// Can be overridden by extending classes, to modify query being returned. @@ -405,64 +405,64 @@ namespace Lucene /// @param disableCoord true if coord scoring should be disabled. /// @return Resulting {@link Query} object. virtual QueryPtr getBooleanQuery(Collection clauses, bool disableCoord); - - /// Factory method for generating a query. Called when parser parses an input term token that contains - /// one or more wildcard characters (? and *), but is not a prefix term token (one that has just a + + /// Factory method for generating a query. Called when parser parses an input term token that contains + /// one or more wildcard characters (? and *), but is not a prefix term token (one that has just a /// single * character at the end) /// - /// Depending on settings, prefix term may be lower-cased automatically. It will not go through the - /// default Analyzer, however, since normal Analyzers are unlikely to work properly with wildcard + /// Depending on settings, prefix term may be lower-cased automatically. It will not go through the + /// default Analyzer, however, since normal Analyzers are unlikely to work properly with wildcard /// templates. /// - /// Can be overridden by extending classes, to provide custom handling for wildcard queries, which may + /// Can be overridden by extending classes, to provide custom handling for wildcard queries, which may /// be necessary due to missing analyzer calls. /// /// @param field Name of the field query will use. - /// @param termStr Term token that contains one or more wild card characters (? or *), but is not simple + /// @param termStr Term token that contains one or more wild card characters (? or *), but is not simple /// prefix term /// @return Resulting {@link Query} built for the term virtual QueryPtr getWildcardQuery(const String& field, const String& termStr); - - /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser - /// parses an input term token that uses prefix notation; that is, contains a single '*' wildcard - /// character as its last character. Since this is a special case of generic wildcard term, and such + + /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser + /// parses an input term token that uses prefix notation; that is, contains a single '*' wildcard + /// character as its last character. Since this is a special case of generic wildcard term, and such /// a query can be optimized easily, this usually results in a different query object. /// - /// Depending on settings, a prefix term may be lower-cased automatically. It will not go through the + /// Depending on settings, a prefix term may be lower-cased automatically. It will not go through the /// default Analyzer, however, since normal Analyzers are unlikely to work properly with wildcard templates. /// - /// Can be overridden by extending classes, to provide custom handling for wild card queries, which may be + /// Can be overridden by extending classes, to provide custom handling for wild card queries, which may be /// necessary due to missing analyzer calls. /// /// @param field Name of the field query will use. /// @param termStr Term token to use for building term for the query (without trailing '*' character) /// @return Resulting {@link Query} built for the term virtual QueryPtr getPrefixQuery(const String& field, const String& termStr); - - /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser + + /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser /// parses an input term token that has the fuzzy suffix (~) appended. /// /// @param field Name of the field query will use. /// @param termStr Term token to use for building term for the query /// @return Resulting {@link Query} built for the term virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity); - - /// Returns a String where the escape char has been removed, or kept only once if there was a double + + /// Returns a String where the escape char has been removed, or kept only once if there was a double /// escape. Supports escaped unicode characters, eg. translates \\u0041 to A. String discardEscapeChar(const String& input); - + /// Returns the numeric value of the hexadecimal character static int32_t hexToInt(wchar_t c); - - /// Returns a String where those characters that QueryParser expects to be escaped are escaped by + + /// Returns a String where those characters that QueryParser expects to be escaped are escaped by /// a preceding \. static String escape(const String& s); - + bool jj_2_1(int32_t xla); bool jj_3R_2(); bool jj_3_1(); bool jj_3R_3(); - + QueryParserTokenPtr jj_consume_token(int32_t kind); bool jj_scan_token(int32_t kind); int32_t jj_ntk(); diff --git a/include/QueryParserCharStream.h b/include/QueryParserCharStream.h index c442014b..8df69a47 100644 --- a/include/QueryParserCharStream.h +++ b/include/QueryParserCharStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,21 +11,21 @@ namespace Lucene { - /// This interface describes a character stream that maintains line and column number positions of - /// the characters. It also has the capability to backup the stream to some extent. An implementation + /// This interface describes a character stream that maintains line and column number positions of + /// the characters. It also has the capability to backup the stream to some extent. An implementation /// of this interface is used in the QueryParserTokenManager. /// - /// All the methods except backup can be implemented in any fashion. backup needs to be implemented - /// correctly for the correct operation of the lexer. Rest of the methods are all used to get information - /// like line number, column number and the String that constitutes a token and are not used by the lexer. + /// All the methods except backup can be implemented in any fashion. backup needs to be implemented + /// correctly for the correct operation of the lexer. Rest of the methods are all used to get information + /// like line number, column number and the String that constitutes a token and are not used by the lexer. /// Hence their implementation won't affect the generated lexer's operation. class LPPAPI QueryParserCharStream { public: LUCENE_INTERFACE(QueryParserCharStream); - + public: - /// Returns the next character from the selected input. The method of selecting the input is the + /// Returns the next character from the selected input. The method of selecting the input is the /// responsibility of the class implementing this interface. virtual wchar_t readChar() = 0; @@ -39,42 +39,42 @@ namespace Lucene /// @see #getEndLine virtual int32_t getLine() = 0; - /// Returns the column number of the last character for current token (being matched after the last + /// Returns the column number of the last character for current token (being matched after the last /// call to BeginToken). virtual int32_t getEndColumn() = 0; - /// Returns the line number of the last character for current token (being matched after the last call + /// Returns the line number of the last character for current token (being matched after the last call /// to BeginToken). virtual int32_t getEndLine() = 0; - /// Returns the column number of the first character for current token (being matched after the last + /// Returns the column number of the first character for current token (being matched after the last /// call to BeginToken). virtual int32_t getBeginColumn() = 0; - /// Returns the line number of the first character for current token (being matched after the last call + /// Returns the line number of the first character for current token (being matched after the last call /// to BeginToken). virtual int32_t getBeginLine() = 0; - /// Backs up the input stream by amount steps. Lexer calls this method if it had already read some - /// characters, but could not use them to match a (longer) token. So, they will be used again as the + /// Backs up the input stream by amount steps. Lexer calls this method if it had already read some + /// characters, but could not use them to match a (longer) token. So, they will be used again as the /// prefix of the next token and it is the implementation's's responsibility to do this right. virtual void backup(int32_t amount) = 0; - /// Returns the next character that marks the beginning of the next token. All characters must remain + /// Returns the next character that marks the beginning of the next token. All characters must remain /// in the buffer between two successive calls to this method to implement backup correctly. virtual wchar_t BeginToken() = 0; /// Returns a string made up of characters from the marked token beginning to the current buffer position. - /// Implementations have the choice of returning anything that they want to. For example, for efficiency, + /// Implementations have the choice of returning anything that they want to. For example, for efficiency, /// one might decide to just return null, which is a valid implementation. virtual String GetImage() = 0; - /// Returns an array of characters that make up the suffix of length for the currently matched token. + /// Returns an array of characters that make up the suffix of length for the currently matched token. /// This is used to build up the matched string for use in actions in the case of MORE. virtual CharArray GetSuffix(int32_t length) = 0; - /// The lexer calls this function to indicate that it is done with the stream and hence implementations - /// can free any resources held by this class. Again, the body of this function can be just empty and it + /// The lexer calls this function to indicate that it is done with the stream and hence implementations + /// can free any resources held by this class. Again, the body of this function can be just empty and it /// will not affect the lexer's operation. virtual void Done() = 0; }; diff --git a/include/QueryParserConstants.h b/include/QueryParserConstants.h index f9bf3b42..db65e916 100644 --- a/include/QueryParserConstants.h +++ b/include/QueryParserConstants.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,7 +20,7 @@ namespace Lucene public: virtual ~QueryParserConstants(); LUCENE_INTERFACE(QueryParserConstants); - + public: enum RegularExpressionId { @@ -58,7 +58,7 @@ namespace Lucene RANGEEX_QUOTED = 32, RANGEEX_GOOP = 33 }; - + enum LexicalState { Boost = 0, @@ -66,10 +66,10 @@ namespace Lucene RangeIn = 2, DEFAULT = 3 }; - + /// Literal token values. static Collection tokenImage; - + protected: /// Literal token values. static const wchar_t* _tokenImage[]; diff --git a/include/QueryParserToken.h b/include/QueryParserToken.h index 32705db6..aab2c1b5 100644 --- a/include/QueryParserToken.h +++ b/include/QueryParserToken.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,51 +17,51 @@ namespace Lucene public: /// Constructs a new token for the specified Image and Kind. QueryParserToken(int32_t kind = 0, const String& image = EmptyString); - + virtual ~QueryParserToken(); - + LUCENE_CLASS(QueryParserToken); - + public: /// An integer that describes the kind of this token. int32_t kind; - + /// The line number of the first character of this Token. int32_t beginLine; - + /// The column number of the first character of this Token. int32_t beginColumn; - + /// The line number of the last character of this Token. int32_t endLine; - + /// The column number of the last character of this Token. int32_t endColumn; - + /// The string image of the token. String image; - - /// A reference to the next regular (non-special) token from the input stream. If this is the last - /// token from the input stream, or if the token manager has not read tokens beyond this one, this - /// field is set to null. This is true only if this token is also a regular token. Otherwise, see + + /// A reference to the next regular (non-special) token from the input stream. If this is the last + /// token from the input stream, or if the token manager has not read tokens beyond this one, this + /// field is set to null. This is true only if this token is also a regular token. Otherwise, see /// below for a description of the contents of this field. QueryParserTokenPtr next; - - /// This field is used to access special tokens that occur prior to this token, but after the - /// immediately preceding regular (non-special) token. If there are no such special tokens, this - /// field is set to null. When there are more than one such special token, this field refers to the - /// last of these special tokens, which in turn refers to the next previous special token through - /// its specialToken field, and so on until the first special token (whose specialToken field is - /// null). The next fields of special tokens refer to other special tokens that immediately follow + + /// This field is used to access special tokens that occur prior to this token, but after the + /// immediately preceding regular (non-special) token. If there are no such special tokens, this + /// field is set to null. When there are more than one such special token, this field refers to the + /// last of these special tokens, which in turn refers to the next previous special token through + /// its specialToken field, and so on until the first special token (whose specialToken field is + /// null). The next fields of special tokens refer to other special tokens that immediately follow /// it (without an intervening regular token). If there is no such token, this field is null. QueryParserTokenPtr specialToken; - + public: /// Returns the image. virtual String toString(); - - /// Returns a new Token object, by default. However, if you want, you can create and return subclass - /// objects based on the value of ofKind. Simply add the cases to the switch for all those special + + /// Returns a new Token object, by default. However, if you want, you can create and return subclass + /// objects based on the value of ofKind. Simply add the cases to the switch for all those special /// cases. static QueryParserTokenPtr newToken(int32_t ofKind, const String& image = EmptyString); }; diff --git a/include/QueryParserTokenManager.h b/include/QueryParserTokenManager.h index 884cd413..13943292 100644 --- a/include/QueryParserTokenManager.h +++ b/include/QueryParserTokenManager.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,61 +17,61 @@ namespace Lucene public: QueryParserTokenManager(QueryParserCharStreamPtr stream); QueryParserTokenManager(QueryParserCharStreamPtr stream, int32_t lexState); - + virtual ~QueryParserTokenManager(); - + LUCENE_CLASS(QueryParserTokenManager); - + public: /// Debug output. InfoStreamPtr debugStream; - + protected: static const int64_t jjbitVec0[]; static const int64_t jjbitVec1[]; static const int64_t jjbitVec3[]; static const int64_t jjbitVec4[]; static const int32_t jjnextStates[]; - + /// Token literal values. static const wchar_t* jjstrLiteralImages[]; - + /// Lexer state names. static const wchar_t* lexStateNames[]; - + /// Lex State array. static const int32_t jjnewLexState[]; static const int64_t jjtoToken[]; static const int64_t jjtoSkip[]; - + int32_t curLexState; int32_t defaultLexState; int32_t jjnewStateCnt; int32_t jjround; int32_t jjmatchedPos; int32_t jjmatchedKind; - + QueryParserCharStreamPtr input_stream; IntArray jjrounds; IntArray jjstateSet; wchar_t curChar; - + public: /// Set debug output. void setDebugStream(InfoStreamPtr debugStream); - + /// Reinitialise parser. void ReInit(QueryParserCharStreamPtr stream); - + /// Reinitialise parser. void ReInit(QueryParserCharStreamPtr stream, int32_t lexState); - + /// Switch to specified lex state. void SwitchTo(int32_t lexState); - + /// Get the next Token. QueryParserTokenPtr getNextToken(); - + protected: int32_t jjStopStringLiteralDfa_3(int32_t pos, int64_t active0); int32_t jjStartNfa_3(int32_t pos, int64_t active0); @@ -93,14 +93,14 @@ namespace Lucene int32_t jjMoveStringLiteralDfa1_2(int64_t active0); int32_t jjStartNfaWithStates_2(int32_t pos, int32_t kind, int32_t state); int32_t jjMoveNfa_2(int32_t startState, int32_t curPos); - + static bool jjCanMove_0(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); static bool jjCanMove_1(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); static bool jjCanMove_2(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); - + void ReInitRounds(); QueryParserTokenPtr jjFillToken(); - + void jjCheckNAdd(int32_t state); void jjAddStates(int32_t start, int32_t end); void jjCheckNAddTwoStates(int32_t state1, int32_t state2); diff --git a/include/QueryTermVector.h b/include/QueryTermVector.h index 21ff3a36..5b64c123 100644 --- a/include/QueryTermVector.h +++ b/include/QueryTermVector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,24 +17,24 @@ namespace Lucene /// @param queryTerms The original list of terms from the query, can contain duplicates QueryTermVector(Collection queryTerms); QueryTermVector(const String& queryString, AnalyzerPtr analyzer); - + virtual ~QueryTermVector(); - + LUCENE_CLASS(QueryTermVector); - + protected: Collection terms; Collection termFreqs; - + public: virtual String toString(); - + int32_t size(); Collection getTerms(); Collection getTermFrequencies(); int32_t indexOf(const String& term); Collection indexesOf(Collection terms, int32_t start, int32_t length); - + protected: void processTerms(Collection queryTerms); }; diff --git a/include/QueryWrapperFilter.h b/include/QueryWrapperFilter.h index 071b22ee..92b4de9f 100644 --- a/include/QueryWrapperFilter.h +++ b/include/QueryWrapperFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,10 +11,10 @@ namespace Lucene { - /// Constrains search results to only match those which also match a provided query. + /// Constrains search results to only match those which also match a provided query. /// - /// This could be used, for example, with a {@link TermRangeQuery} on a suitably formatted date field to - /// implement date filtering. One could re-use a single QueryFilter that matches, eg., only documents + /// This could be used, for example, with a {@link TermRangeQuery} on a suitably formatted date field to + /// implement date filtering. One could re-use a single QueryFilter that matches, eg., only documents /// modified within the last week. The QueryFilter and TermRangeQuery would only need to be reconstructed /// once per day. class LPPAPI QueryWrapperFilter : public Filter @@ -22,14 +22,14 @@ namespace Lucene public: /// Constructs a filter which only matches documents matching query. QueryWrapperFilter(QueryPtr query); - + virtual ~QueryWrapperFilter(); - + LUCENE_CLASS(QueryWrapperFilter); - + protected: QueryPtr query; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); virtual String toString(); diff --git a/include/RAMDirectory.h b/include/RAMDirectory.h index cd3648b0..0795226e 100644 --- a/include/RAMDirectory.h +++ b/include/RAMDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// A memory-resident {@link Directory} implementation. Locking implementation is by default the + /// A memory-resident {@link Directory} implementation. Locking implementation is by default the /// {@link SingleInstanceLockFactory} but can be changed with {@link #setLockFactory}. /// Lock acquisition sequence: RAMDirectory, then RAMFile class LPPAPI RAMDirectory : public Directory @@ -19,24 +19,24 @@ namespace Lucene public: /// Constructs an empty {@link Directory}. RAMDirectory(); - + /// Creates a new RAMDirectory instance from a different Directory implementation. /// This can be used to load a disk-based index into memory. /// /// This should be used only with indices that can fit into memory. /// - /// Note that the resulting RAMDirectory instance is fully independent from the + /// Note that the resulting RAMDirectory instance is fully independent from the /// original Directory (it is a complete copy). Any subsequent changes to the /// original Directory will not be visible in the RAMDirectory instance. /// @param dir a Directory value RAMDirectory(DirectoryPtr dir); - + RAMDirectory(DirectoryPtr dir, bool closeDir); - + virtual ~RAMDirectory(); - + LUCENE_CLASS(RAMDirectory); - + INTERNAL: int64_t _sizeInBytes; MapStringRAMFile fileMap; @@ -45,39 +45,39 @@ namespace Lucene DirectoryWeakPtr _dirSource; bool copyDirectory; bool closeDir; - + public: virtual void initialize(); - + /// Returns an array of strings, one for each file in the directory. virtual HashSet listAll(); - + /// Returns true if a file with the given name exists. virtual bool fileExists(const String& name); - + /// Returns the time the named file was last modified. virtual uint64_t fileModified(const String& name); - + /// Set the modified time of an existing file to now. virtual void touchFile(const String& name); - + /// Returns the length of a file in the directory. virtual int64_t fileLength(const String& name); - - /// Return total size in bytes of all files in this directory. + + /// Return total size in bytes of all files in this directory. /// This is currently quantized to RAMOutputStream::BUFFER_SIZE. - int64_t sizeInBytes(); - + int64_t sizeInBytes(); + /// Removes an existing file in the directory. virtual void deleteFile(const String& name); - + /// Creates a new, empty file in the directory with the given name. /// Returns a stream writing this file. virtual IndexOutputPtr createOutput(const String& name); - + /// Returns a stream reading an existing file. virtual IndexInputPtr openInput(const String& name); - + /// Closes the store. virtual void close(); }; diff --git a/include/RAMFile.h b/include/RAMFile.h index 59e6a6d7..55e43542 100644 --- a/include/RAMFile.h +++ b/include/RAMFile.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,38 +18,38 @@ namespace Lucene RAMFile(); // File used as buffer, in no RAMDirectory RAMFile(RAMDirectoryPtr directory); virtual ~RAMFile(); - + LUCENE_CLASS(RAMFile); - + INTERNAL: int64_t length; RAMDirectoryWeakPtr _directory; protected: Collection buffers; - + int64_t sizeInBytes; - + /// This is publicly modifiable via Directory.touchFile(), so direct access not supported int64_t lastModified; - + public: /// For non-stream access from thread that might be concurrent with writing. - int64_t getLength(); + int64_t getLength(); void setLength(int64_t length); - + /// For non-stream access from thread that might be concurrent with writing int64_t getLastModified(); void setLastModified(int64_t lastModified); - + int64_t getSizeInBytes(); - + ByteArray addBuffer(int32_t size); ByteArray getBuffer(int32_t index); int32_t numBuffers(); - + protected: - /// Allocate a new buffer. Subclasses can allocate differently. + /// Allocate a new buffer. Subclasses can allocate differently. virtual ByteArray newBuffer(int32_t size); }; } diff --git a/include/RAMInputStream.h b/include/RAMInputStream.h index 049a52b2..ea3feb2c 100644 --- a/include/RAMInputStream.h +++ b/include/RAMInputStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,12 +18,12 @@ namespace Lucene RAMInputStream(); RAMInputStream(RAMFilePtr f); virtual ~RAMInputStream(); - + LUCENE_CLASS(RAMInputStream); - - public: + + public: static const int32_t BUFFER_SIZE; - + protected: RAMFilePtr file; int64_t _length; @@ -32,36 +32,36 @@ namespace Lucene int32_t bufferPosition; int64_t bufferStart; int32_t bufferLength; - + public: /// Closes the stream to further operations. virtual void close(); - + /// The number of bytes in the file. virtual int64_t length(); - + /// Reads and returns a single byte. /// @see IndexOutput#writeByte(uint8_t) virtual uint8_t readByte(); - + /// Reads a specified number of bytes into an array at the specified offset. /// @param b the array to read bytes into. /// @param offset the offset in the array to start storing bytes. /// @param length the number of bytes to read. /// @see IndexOutput#writeBytes(const uint8_t*,int) virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - + /// Returns the current position in this file, where the next read will occur. /// @see #seek(int64_t) virtual int64_t getFilePointer(); - + /// Sets current position in this file, where the next read will occur. /// @see #getFilePointer() virtual void seek(int64_t pos); - + /// Returns a clone of this stream. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + protected: void switchCurrentBuffer(bool enforceEOF); }; diff --git a/include/RAMOutputStream.h b/include/RAMOutputStream.h index 3dd68c96..3634dac3 100644 --- a/include/RAMOutputStream.h +++ b/include/RAMOutputStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,12 +19,12 @@ namespace Lucene RAMOutputStream(); RAMOutputStream(RAMFilePtr f); virtual ~RAMOutputStream(); - + LUCENE_CLASS(RAMOutputStream); public: static const int32_t BUFFER_SIZE; - + protected: RAMFilePtr file; ByteArray currentBuffer; @@ -32,43 +32,43 @@ namespace Lucene int32_t bufferPosition; int64_t bufferStart; int32_t bufferLength; - + public: /// Copy the current contents of this buffer to the named output. void writeTo(IndexOutputPtr out); - + /// Resets this to an empty file. void reset(); - + /// Closes this stream to further operations. virtual void close(); - + /// Sets current position in this file, where the next write will occur. /// @see #getFilePointer() virtual void seek(int64_t pos); - + /// The number of bytes in the file. virtual int64_t length(); - + /// Writes a single byte. /// @see IndexInput#readByte() virtual void writeByte(uint8_t b); - + /// Writes an array of bytes. /// @param b the bytes to write. /// @param length the number of bytes to write. /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - + /// Forces any buffered output to be written. virtual void flush(); - + /// Returns the current position in this file, where the next write will occur. virtual int64_t getFilePointer(); - + /// Returns byte usage of all buffers. int64_t sizeInBytes(); - + protected: void switchCurrentBuffer(); void setFileLength(); diff --git a/include/Random.h b/include/Random.h index e36d7017..0fc3031e 100644 --- a/include/Random.h +++ b/include/Random.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/RawPostingList.h b/include/RawPostingList.h index 10ae9f33..6440371d 100644 --- a/include/RawPostingList.h +++ b/include/RawPostingList.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,22 +11,22 @@ namespace Lucene { - /// This is the base class for an in-memory posting list, keyed by a Token. {@link TermsHash} maintains a - /// hash table holding one instance of this per unique Token. Consumers of TermsHash ({@link TermsHashConsumer}) - /// must subclass this class with its own concrete class. FreqProxTermsWriterPostingList is a private inner - /// class used for the freq/prox postings, and TermVectorsTermsWriterPostingList is a private inner class used + /// This is the base class for an in-memory posting list, keyed by a Token. {@link TermsHash} maintains a + /// hash table holding one instance of this per unique Token. Consumers of TermsHash ({@link TermsHashConsumer}) + /// must subclass this class with its own concrete class. FreqProxTermsWriterPostingList is a private inner + /// class used for the freq/prox postings, and TermVectorsTermsWriterPostingList is a private inner class used /// to hold TermVectors postings. class RawPostingList : public LuceneObject { public: RawPostingList(); virtual ~RawPostingList(); - + LUCENE_CLASS(RawPostingList); - + public: static const int32_t BYTES_SIZE; - + int32_t textStart; int32_t intStart; int32_t byteStart; diff --git a/include/ReadOnlyDirectoryReader.h b/include/ReadOnlyDirectoryReader.h index 71e88728..9828bc7f 100644 --- a/include/ReadOnlyDirectoryReader.h +++ b/include/ReadOnlyDirectoryReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,15 +15,15 @@ namespace Lucene { public: ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor); - ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, + ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, Collection oldStarts, MapStringByteArray oldNormsCache, bool doClone, int32_t termInfosIndexDivisor); ReadOnlyDirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor); virtual ~ReadOnlyDirectoryReader(); - + LUCENE_CLASS(ReadOnlyDirectoryReader); - + public: - /// Tries to acquire the WriteLock on this directory. this method is only valid if this + /// Tries to acquire the WriteLock on this directory. this method is only valid if this /// IndexReader is directory owner. virtual void acquireWriteLock(); }; diff --git a/include/ReadOnlySegmentReader.h b/include/ReadOnlySegmentReader.h index e4c3c991..6df79c91 100644 --- a/include/ReadOnlySegmentReader.h +++ b/include/ReadOnlySegmentReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,12 +15,12 @@ namespace Lucene { public: virtual ~ReadOnlySegmentReader(); - + LUCENE_CLASS(ReadOnlySegmentReader); - + public: static void noWrite(); - + virtual void acquireWriteLock(); virtual bool isDeleted(int32_t n); }; diff --git a/include/Reader.h b/include/Reader.h index 3bc164e4..c8ca1c77 100644 --- a/include/Reader.h +++ b/include/Reader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,34 +20,34 @@ namespace Lucene public: virtual ~Reader(); LUCENE_CLASS(Reader); - + public: static const int32_t READER_EOF; - + /// Read a single character. virtual int32_t read(); /// Read characters into a portion of an array. virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length) = 0; - + /// Skip characters. virtual int64_t skip(int64_t n); - + /// Close the stream. virtual void close() = 0; - + /// Tell whether this stream supports the mark() operation virtual bool markSupported(); - - /// Mark the present position in the stream. Subsequent calls to reset() will attempt to reposition the + + /// Mark the present position in the stream. Subsequent calls to reset() will attempt to reposition the /// stream to this point. virtual void mark(int32_t readAheadLimit); - - /// Reset the stream. If the stream has been marked, then attempt to reposition it at the mark. If the stream + + /// Reset the stream. If the stream has been marked, then attempt to reposition it at the mark. If the stream /// has not been marked, then attempt to reset it in some way appropriate to the particular stream, for example /// by repositioning it to its starting point. virtual void reset(); - + /// The number of bytes in the stream. virtual int64_t length(); }; diff --git a/include/ReaderUtil.h b/include/ReaderUtil.h index 080eb315..ab2f2dcb 100644 --- a/include/ReaderUtil.h +++ b/include/ReaderUtil.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,26 +17,26 @@ namespace Lucene public: virtual ~ReaderUtil(); LUCENE_CLASS(ReaderUtil); - + public: /// Gathers sub-readers from reader into a List. static void gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader); - + /// Returns sub IndexReader that contains the given document id. /// /// @param doc Id of document /// @param reader Parent reader /// @return Sub reader of parent which contains the specified doc id static IndexReaderPtr subReader(int32_t doc, IndexReaderPtr reader); - + /// Returns sub-reader subIndex from reader. /// /// @param reader Parent reader /// @param subIndex Index of desired sub reader /// @return The subreader at subIndex static IndexReaderPtr subReader(IndexReaderPtr reader, int32_t subIndex); - - /// Returns index of the searcher/reader for document n in the array used to construct this + + /// Returns index of the searcher/reader for document n in the array used to construct this /// searcher/reader. static int32_t subIndex(int32_t n, Collection docStarts); }; diff --git a/include/ReqExclScorer.h b/include/ReqExclScorer.h index 56ebee05..fd47a648 100644 --- a/include/ReqExclScorer.h +++ b/include/ReqExclScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,25 +21,25 @@ namespace Lucene /// @param exclDisi indicates exclusion. ReqExclScorer(ScorerPtr reqScorer, DocIdSetIteratorPtr exclDisi); virtual ~ReqExclScorer(); - + LUCENE_CLASS(ReqExclScorer); - + protected: ScorerPtr reqScorer; DocIdSetIteratorPtr exclDisi; int32_t doc; - + public: virtual int32_t nextDoc(); virtual int32_t docID(); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} + + /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} /// is called the first time. /// @return The score of the required scorer. virtual double score(); - + virtual int32_t advance(int32_t target); - + protected: /// Advance to non excluded doc. /// diff --git a/include/ReqOptSumScorer.h b/include/ReqOptSumScorer.h index 6d1820b4..0c907506 100644 --- a/include/ReqOptSumScorer.h +++ b/include/ReqOptSumScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,28 +11,28 @@ namespace Lucene { - /// A Scorer for queries with a required part and an optional part. Delays skipTo() on the optional part + /// A Scorer for queries with a required part and an optional part. Delays skipTo() on the optional part /// until a score() is needed. This Scorer implements {@link Scorer#skipTo(int32_t)}. class ReqOptSumScorer : public Scorer { public: ReqOptSumScorer(ScorerPtr reqScorer, ScorerPtr optScorer); virtual ~ReqOptSumScorer(); - + LUCENE_CLASS(ReqOptSumScorer); - + protected: ScorerPtr reqScorer; ScorerPtr optScorer; - + public: virtual int32_t nextDoc(); virtual int32_t advance(int32_t target); virtual int32_t docID(); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} + + /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} /// is called the first time. - /// @return The score of the required scorer, eventually increased by the score of the optional scorer when + /// @return The score of the required scorer, eventually increased by the score of the optional scorer when /// it also matches the current document. virtual double score(); }; diff --git a/include/ReusableStringReader.h b/include/ReusableStringReader.h index 06daa073..172f1d18 100644 --- a/include/ReusableStringReader.h +++ b/include/ReusableStringReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,29 +11,29 @@ namespace Lucene { - /// Used by DocumentsWriter to implemented a StringReader that can be reset to a new string; we use this + /// Used by DocumentsWriter to implemented a StringReader that can be reset to a new string; we use this /// when tokenizing the string value from a Field. class ReusableStringReader : public Reader { public: ReusableStringReader(); virtual ~ReusableStringReader(); - + LUCENE_CLASS(ReusableStringReader); - + public: int32_t upto; int32_t left; String s; - + public: virtual void init(const String& s); - + using Reader::read; - + /// Read characters into a portion of an array. virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - + /// Close the stream. virtual void close(); }; diff --git a/include/ReverseOrdFieldSource.h b/include/ReverseOrdFieldSource.h index 30f1f1ad..4f215381 100644 --- a/include/ReverseOrdFieldSource.h +++ b/include/ReverseOrdFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,31 +16,31 @@ namespace Lucene /// /// The native lucene index order is used to assign an ordinal value for each field value. /// - /// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1. Example + /// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1. Example /// of reverse ordinal (rord): /// - /// If there were only three field values: "apple","banana","pear" then rord("apple")=3, rord("banana")=2, + /// If there were only three field values: "apple","banana","pear" then rord("apple")=3, rord("banana")=2, /// ord("pear")=1 /// - /// WARNING: rord() depends on the position in an index and can thus change when other documents are inserted - /// or deleted, or if a MultiSearcher is used. + /// WARNING: rord() depends on the position in an index and can thus change when other documents are inserted + /// or deleted, or if a MultiSearcher is used. /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite + /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's /// best to switch your application to pass only atomic (single segment) readers to this API. class LPPAPI ReverseOrdFieldSource : public ValueSource { public: /// Constructor for a certain field. - /// @param field field whose values reverse order is used. - ReverseOrdFieldSource(const String& field); + /// @param field field whose values reverse order is used. + ReverseOrdFieldSource(const String& field); virtual ~ReverseOrdFieldSource(); - + LUCENE_CLASS(ReverseOrdFieldSource); - + protected: String field; - + public: virtual String description(); virtual DocValuesPtr getValues(IndexReaderPtr reader); diff --git a/include/ScoreCachingWrappingScorer.h b/include/ScoreCachingWrappingScorer.h index 4907d84f..516e185d 100644 --- a/include/ScoreCachingWrappingScorer.h +++ b/include/ScoreCachingWrappingScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,12 +11,12 @@ namespace Lucene { - /// A {@link Scorer} which wraps another scorer and caches the score of the current document. Successive + /// A {@link Scorer} which wraps another scorer and caches the score of the current document. Successive /// calls to {@link #score()} will return the same result and will not invoke the wrapped Scorer's score() /// method, unless the current document has changed. /// - /// This class might be useful due to the changes done to the {@link Collector} interface, in which the - /// score is not computed for a document by default, only if the collector requests it. Some collectors + /// This class might be useful due to the changes done to the {@link Collector} interface, in which the + /// score is not computed for a document by default, only if the collector requests it. Some collectors /// may need to use the score in several places, however all they have in hand is a {@link Scorer} object, /// and might end up computing the score of a document more than once. class LPPAPI ScoreCachingWrappingScorer : public Scorer @@ -25,14 +25,14 @@ namespace Lucene /// Creates a new instance by wrapping the given scorer. ScoreCachingWrappingScorer(ScorerPtr scorer); virtual ~ScoreCachingWrappingScorer(); - + LUCENE_CLASS(ScoreCachingWrappingScorer); - + protected: ScorerWeakPtr _scorer; int32_t curDoc; double curScore; - + public: SimilarityPtr getSimilarity(); virtual double score(); @@ -40,7 +40,7 @@ namespace Lucene virtual int32_t nextDoc(); virtual void score(CollectorPtr collector); virtual int32_t advance(int32_t target); - + protected: virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); }; diff --git a/include/ScoreDoc.h b/include/ScoreDoc.h index e7516a87..5b35f652 100644 --- a/include/ScoreDoc.h +++ b/include/ScoreDoc.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,17 +18,17 @@ namespace Lucene public: ScoreDoc(int32_t doc, double score); virtual ~ScoreDoc(); - + LUCENE_CLASS(ScoreDoc); - + public: /// The score of this document for the query. double score; - + /// A hit document's number. /// @see Searcher#doc(int32_t) int32_t doc; - + public: virtual String toString(); }; diff --git a/include/Scorer.h b/include/Scorer.h index adc0c746..063fbb44 100644 --- a/include/Scorer.h +++ b/include/Scorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,34 +17,34 @@ namespace Lucene /// /// Document scores are computed using a given Similarity implementation. /// - /// NOTE: The values NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. Certain collectors + /// NOTE: The values NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. Certain collectors /// (eg {@link TopScoreDocCollector}) will not properly collect hits with these scores. class LPPAPI Scorer : public DocIdSetIterator { public: /// Constructs a Scorer. /// @param similarity The Similarity implementation used by this scorer. - Scorer(SimilarityPtr similarity); + Scorer(SimilarityPtr similarity); virtual ~Scorer(); - + LUCENE_CLASS(Scorer); - + protected: SimilarityPtr similarity; - + public: /// Returns the Similarity implementation used by this scorer. SimilarityPtr getSimilarity(); - + /// Scores and collects all matching documents. /// @param collector The collector to which all matching documents are passed. virtual void score(CollectorPtr collector); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link + + /// Returns the score of the current document matching the query. Initially invalid, until {@link /// #nextDoc()} or {@link #advance(int32_t)} is called the first time, or when called from within /// {@link Collector#collect}. virtual double score() = 0; - + protected: /// Collects matching documents in a range. Hook for optimization. /// Note, firstDocID is added to ensure that {@link #nextDoc()} was called before this method. @@ -54,7 +54,7 @@ namespace Lucene /// @param firstDocID The first document ID (ensures {@link #nextDoc()} is called before this method. /// @return true if more matching documents may remain. virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); - + friend class BooleanScorer; friend class ScoreCachingWrappingScorer; }; diff --git a/include/ScorerDocQueue.h b/include/ScorerDocQueue.h index b36c5140..9652a0dc 100644 --- a/include/ScorerDocQueue.h +++ b/include/ScorerDocQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,64 +11,64 @@ namespace Lucene { - /// A ScorerDocQueue maintains a partial ordering of its Scorers such that the least Scorer can always be + /// A ScorerDocQueue maintains a partial ordering of its Scorers such that the least Scorer can always be /// found in constant time. Put()'s and pop()'s require log(size) time. The ordering is by Scorer::doc(). class LPPAPI ScorerDocQueue : public LuceneObject { public: ScorerDocQueue(int32_t maxSize); virtual ~ScorerDocQueue(); - + LUCENE_CLASS(ScorerDocQueue); - + protected: Collection heap; int32_t maxSize; int32_t _size; HeapedScorerDocPtr topHSD; // same as heap[1], only for speed - + public: /// Adds a Scorer to a ScorerDocQueue in log(size) time. If one tries to add more Scorers than maxSize /// ArrayIndexOutOfBound exception is thrown. void put(ScorerPtr scorer); - - /// Adds a Scorer to the ScorerDocQueue in log(size) time if either the ScorerDocQueue is not full, or + + /// Adds a Scorer to the ScorerDocQueue in log(size) time if either the ScorerDocQueue is not full, or /// not lessThan(scorer, top()). /// @return true if scorer is added, false otherwise. bool insert(ScorerPtr scorer); - - /// Returns the least Scorer of the ScorerDocQueue in constant time. Should not be used when the queue + + /// Returns the least Scorer of the ScorerDocQueue in constant time. Should not be used when the queue /// is empty. ScorerPtr top(); - + /// Returns document number of the least Scorer of the ScorerDocQueue in constant time. /// Should not be used when the queue is empty. int32_t topDoc(); - + double topScore(); bool topNextAndAdjustElsePop(); bool topSkipToAndAdjustElsePop(int32_t target); - - /// Removes and returns the least scorer of the ScorerDocQueue in log(size) time. Should not be used + + /// Removes and returns the least scorer of the ScorerDocQueue in log(size) time. Should not be used /// when the queue is empty. ScorerPtr pop(); - + /// Should be called when the scorer at top changes doc() value. void adjustTop(); - + /// Returns the number of scorers currently stored in the ScorerDocQueue. int32_t size(); - + /// Removes all entries from the ScorerDocQueue. void clear(); - + protected: bool checkAdjustElsePop(bool cond); - - /// Removes the least scorer of the ScorerDocQueue in log(size) time. Should not be used when the + + /// Removes the least scorer of the ScorerDocQueue in log(size) time. Should not be used when the /// queue is empty. void popNoResult(); - + void upHeap(); void downHeap(); }; diff --git a/include/Searchable.h b/include/Searchable.h index f987e58e..eb042c26 100644 --- a/include/Searchable.h +++ b/include/Searchable.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,27 +13,27 @@ namespace Lucene { /// The interface for search implementations. /// - /// Searchable is the abstract network protocol for searching. Implementations provide search over a single + /// Searchable is the abstract network protocol for searching. Implementations provide search over a single /// index, over multiple indices, and over indices on remote servers. /// - /// Queries, filters and sort criteria are designed to be compact so that they may be efficiently passed to a + /// Queries, filters and sort criteria are designed to be compact so that they may be efficiently passed to a /// remote index, with only the top-scoring hits being returned, rather than every matching hit. /// - /// NOTE: this interface is kept public for convenience. Since it is not expected to be implemented directly, + /// NOTE: this interface is kept public for convenience. Since it is not expected to be implemented directly, /// it may be changed unexpectedly between releases. class LPPAPI Searchable { public: LUCENE_INTERFACE(Searchable); - + public: /// Lower-level search API. /// - /// {@link Collector#collect(int32_t)} is called for every document. Collector-based access to remote + /// {@link Collector#collect(int32_t)} is called for every document. Collector-based access to remote /// indexes is discouraged. /// - /// Applications should only use this if they need all of the matching documents. The high-level search - /// API ({@link Searcher#search(QueryPtr, int32_t)}) is usually more efficient, as it skips non-high-scoring + /// Applications should only use this if they need all of the matching documents. The high-level search + /// API ({@link Searcher#search(QueryPtr, int32_t)}) is usually more efficient, as it skips non-high-scoring /// hits. /// /// @param weight To match documents @@ -41,7 +41,7 @@ namespace Lucene /// @param collector To receive hits virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr collector) = 0; - /// Frees resources associated with this Searcher. Be careful not to call this method while you are still + /// Frees resources associated with this Searcher. Be careful not to call this method while you are still /// using objects that reference this Searchable. virtual void close() = 0; @@ -49,7 +49,7 @@ namespace Lucene /// @see IndexReader#docFreq(TermPtr) virtual int32_t docFreq(TermPtr term) = 0; - /// For each term in the terms array, calculates the number of documents containing term. Returns an array + /// For each term in the terms array, calculates the number of documents containing term. Returns an array /// with these document frequencies. Used to minimize number of remote calls. virtual Collection docFreqs(Collection terms) = 0; @@ -58,7 +58,7 @@ namespace Lucene virtual int32_t maxDoc() = 0; /// Low-level search implementation. Finds the top n hits for query, applying filter if non-null. - /// Applications should usually call {@link Searcher#search(QueryPtr, int32_t)} or {@link + /// Applications should usually call {@link Searcher#search(QueryPtr, int32_t)} or {@link /// Searcher#search(QueryPtr, FilterPtr, int32_t)} instead. virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n) = 0; @@ -66,15 +66,15 @@ namespace Lucene /// @see IndexReader#document(int32_t) virtual DocumentPtr doc(int32_t n) = 0; - /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what + /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what /// {@link Field}s to load and how they should be loaded. /// - /// NOTE: If the underlying Reader (more specifically, the underlying FieldsReader) is closed before the - /// lazy {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} + /// NOTE: If the underlying Reader (more specifically, the underlying FieldsReader) is closed before the + /// lazy {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} /// to be available after closing you must explicitly load it or fetch the Document again with a new loader. /// /// @param n Get the document at the n'th position - /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on the + /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on the /// Document. May be null, in which case all Fields will be loaded. /// @return The stored fields of the {@link Document} at the n'th position /// @@ -90,14 +90,14 @@ namespace Lucene /// Low-level implementation method. Returns an Explanation that describes how doc scored against weight. /// - /// This is intended to be used in developing Similarity implementations, and for good performance, should - /// not be displayed with every hit. Computing an explanation is as expensive as executing the query over + /// This is intended to be used in developing Similarity implementations, and for good performance, should + /// not be displayed with every hit. Computing an explanation is as expensive as executing the query over /// the entire index. /// /// Applications should call {@link Searcher#explain(QueryPtr, int32_t)}. virtual ExplanationPtr explain(WeightPtr weight, int32_t doc) = 0; - /// Low-level search implementation with arbitrary sorting. Finds the top n hits for query, applying filter + /// Low-level search implementation with arbitrary sorting. Finds the top n hits for query, applying filter /// if non-null, and sorting the hits by the criteria in sort. /// /// Applications should usually call {@link Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr)} instead. diff --git a/include/Searcher.h b/include/Searcher.h index a91b10c3..f517e059 100644 --- a/include/Searcher.h +++ b/include/Searcher.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,46 +13,46 @@ namespace Lucene { /// An abstract base class for search implementations. Implements the main search methods. /// - /// Note that you can only access hits from a Searcher as long as it is not yet closed, otherwise an IO + /// Note that you can only access hits from a Searcher as long as it is not yet closed, otherwise an IO /// exception will be thrown. class LPPAPI Searcher : public Searchable, public LuceneObject { public: Searcher(); virtual ~Searcher(); - + LUCENE_CLASS(Searcher); - + protected: /// The Similarity implementation used by this searcher. SimilarityPtr similarity; - + public: - /// Search implementation with arbitrary sorting. Finds the top n hits for query, applying filter if + /// Search implementation with arbitrary sorting. Finds the top n hits for query, applying filter if /// non-null, and sorting the hits by the criteria in sort. /// - /// NOTE: this does not compute scores by default; use {@link IndexSearcher#setDefaultFieldSortScoring} + /// NOTE: this does not compute scores by default; use {@link IndexSearcher#setDefaultFieldSortScoring} /// to enable scoring. virtual TopFieldDocsPtr search(QueryPtr query, FilterPtr filter, int32_t n, SortPtr sort); - + /// Lower-level search API. /// /// {@link Collector#collect(int32_t)} is called for every matching document. /// - /// Applications should only use this if they need all of the matching documents. The high-level + /// Applications should only use this if they need all of the matching documents. The high-level /// search API ({@link Searcher#search(QueryPtr, int32_t)}) is usually more efficient, as it skips /// non-high-scoring hits. /// - /// Note: The score passed to this method is a raw score. In other words, the score will not necessarily + /// Note: The score passed to this method is a raw score. In other words, the score will not necessarily /// be a double whose value is between 0 and 1. virtual void search(QueryPtr query, CollectorPtr results); - + /// Lower-level search API. /// - /// {@link Collector#collect(int32_t)} is called for every matching document. Collector-based access to + /// {@link Collector#collect(int32_t)} is called for every matching document. Collector-based access to /// remote indexes is discouraged. /// - /// Applications should only use this if they need all of the matching documents. The high-level search + /// Applications should only use this if they need all of the matching documents. The high-level search /// API ({@link Searcher#search(QueryPtr, FilterPtr, int32_t)}) is usually more efficient, as it skips /// non-high-scoring hits. /// @@ -60,30 +60,30 @@ namespace Lucene /// @param filter If non-null, used to permit documents to be collected. /// @param results To receive hits virtual void search(QueryPtr query, FilterPtr filter, CollectorPtr results); - + /// Finds the top n hits for query, applying filter if non-null. virtual TopDocsPtr search(QueryPtr query, FilterPtr filter, int32_t n); - + /// Finds the top n hits for query. virtual TopDocsPtr search(QueryPtr query, int32_t n); - + /// Returns an Explanation that describes how doc scored against query. /// - /// This is intended to be used in developing Similarity implementations, and for good performance, - /// should not be displayed with every hit. Computing an explanation is as expensive as executing the + /// This is intended to be used in developing Similarity implementations, and for good performance, + /// should not be displayed with every hit. Computing an explanation is as expensive as executing the /// query over the entire index. virtual ExplanationPtr explain(QueryPtr query, int32_t doc); - + /// Set the Similarity implementation used by this Searcher. virtual void setSimilarity(SimilarityPtr similarity); - + /// Return the Similarity implementation used by this Searcher. /// /// This defaults to the current value of {@link Similarity#getDefault()}. virtual SimilarityPtr getSimilarity(); - + virtual Collection docFreqs(Collection terms); - + virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr results) = 0; virtual void close() = 0; virtual int32_t docFreq(TermPtr term) = 0; @@ -94,7 +94,7 @@ namespace Lucene virtual QueryPtr rewrite(QueryPtr query) = 0; virtual ExplanationPtr explain(WeightPtr weight, int32_t doc) = 0; virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) = 0; - + protected: /// Creates a weight for query. /// @return New weight diff --git a/include/SegmentInfo.h b/include/SegmentInfo.h index 86bb0313..0e1cb459 100644 --- a/include/SegmentInfo.h +++ b/include/SegmentInfo.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,130 +11,130 @@ namespace Lucene { - /// Information about a segment such as it's name, directory, and files + /// Information about a segment such as it's name, directory, and files /// related to the segment. class LPPAPI SegmentInfo : public LuceneObject { public: SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir); - + SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, bool hasSingleNormFile); - - SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, + + SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, bool hasSingleNormFile, int32_t docStoreOffset, const String& docStoreSegment, bool docStoreIsCompoundFile, bool hasProx); - + /// Construct a new SegmentInfo instance by reading a previously saved SegmentInfo from input. /// @param dir directory to load from. /// @param format format of the segments info file. /// @param input input handle to read segment info from. SegmentInfo(DirectoryPtr dir, int32_t format, IndexInputPtr input); - + virtual ~SegmentInfo(); - + LUCENE_CLASS(SegmentInfo); - - public: + + public: static const int32_t NO; // no norms; no deletes; static const int32_t YES; // have norms; have deletes; static const int32_t CHECK_DIR; // must check dir to see if there are norms/deletions - static const int32_t WITHOUT_GEN; // a file name that has no GEN in it. - + static const int32_t WITHOUT_GEN; // a file name that has no GEN in it. + protected: // true if this is a segments file written before lock-less commits (2.1) bool preLockless; - - // current generation of del file; NO if there are no deletes; CHECK_DIR if it's a pre-2.1 segment + + // current generation of del file; NO if there are no deletes; CHECK_DIR if it's a pre-2.1 segment // (and we must check filesystem); YES or higher if there are deletes at generation N - int64_t delGen; + int64_t delGen; - // current generation of each field's norm file. If this array is null, for lockLess this means no - // separate norms. For preLockLess this means we must check filesystem. If this array is not null, - // its values mean: NO says this field has no separate norms; CHECK_DIR says it is a preLockLess - // segment and filesystem must be checked; >= YES says this field has separate norms with the + // current generation of each field's norm file. If this array is null, for lockLess this means no + // separate norms. For preLockLess this means we must check filesystem. If this array is not null, + // its values mean: NO says this field has no separate norms; CHECK_DIR says it is a preLockLess + // segment and filesystem must be checked; >= YES says this field has separate norms with the // specified generation Collection normGen; - - // NO if it is not; YES if it is; CHECK_DIR if it's pre-2.1 (ie, must check file system to see if + + // NO if it is not; YES if it is; CHECK_DIR if it's pre-2.1 (ie, must check file system to see if // .cfs and .nrm exist) uint8_t isCompoundFile; - - // true if this segment maintains norms in a single file; false otherwise this is currently false for - // segments populated by DocumentWriter and true for newly created merged segments (both compound and + + // true if this segment maintains norms in a single file; false otherwise this is currently false for + // segments populated by DocumentWriter and true for newly created merged segments (both compound and // non compound). bool hasSingleNormFile; - + // cached list of files that this segment uses in the Directory HashSet _files; - + // total byte size of all of our files (computed on demand) int64_t _sizeInBytes; - - // if this segment shares stored fields & vectors, this offset is where in that file this segment's + + // if this segment shares stored fields & vectors, this offset is where in that file this segment's // docs begin int32_t docStoreOffset; - + // name used to derive fields/vectors file we share with other segments String docStoreSegment; - + // whether doc store files are stored in compound file (*.cfx) bool docStoreIsCompoundFile; - + // How many deleted docs in this segment, or -1 if not yet known (if it's an older index) int32_t delCount; - + // True if this segment has any fields with omitTermFreqAndPositions == false bool hasProx; - + MapStringString diagnostics; - + public: String name; // unique name in dir int32_t docCount; // number of docs in seg DirectoryPtr dir; // where segment resides - + public: /// Copy everything from src SegmentInfo into our instance. void reset(SegmentInfoPtr src); - + void setDiagnostics(MapStringString diagnostics); MapStringString getDiagnostics(); - + void setNumFields(int32_t numFields); - + /// Returns total size in bytes of all of files used by this segment. int64_t sizeInBytes(); - + bool hasDeletions(); void advanceDelGen(); void clearDelGen(); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + String getDelFileName(); - + /// Returns true if this field for this segment has saved a separate norms file (__N.sX). /// @param fieldNumber the field index to check bool hasSeparateNorms(int32_t fieldNumber); - + /// Returns true if any fields in this segment have separate norms. bool hasSeparateNorms(); - + /// Increment the generation count for the norms file for this field. /// @param fieldIndex field whose norm file will be rewritten void advanceNormGen(int32_t fieldIndex); - + /// Get the file name for the norms file for this field. /// @param number field index String getNormFileName(int32_t number); - + /// Mark whether this segment is stored as a compound file. /// @param isCompoundFile true if this is a compound file; else, false void setUseCompoundFile(bool isCompoundFile); - + /// Returns true if this segment is stored as a compound file; else, false. bool getUseCompoundFile(); - + int32_t getDelCount(); void setDelCount(int32_t delCount); int32_t getDocStoreOffset(); @@ -143,28 +143,28 @@ namespace Lucene String getDocStoreSegment(); void setDocStoreOffset(int32_t offset); void setDocStore(int32_t offset, const String& segment, bool isCompoundFile); - + /// Save this segment's info. void write(IndexOutputPtr output); - + void setHasProx(bool hasProx); bool getHasProx(); - - /// Return all files referenced by this SegmentInfo. The returns List is a locally cached List so + + /// Return all files referenced by this SegmentInfo. The returns List is a locally cached List so /// you should not modify it. HashSet files(); - + /// Used for debugging. String segString(DirectoryPtr dir); - + /// We consider another SegmentInfo instance equal if it has the same dir and same name. - virtual bool equals(LuceneObjectPtr other); - + virtual bool equals(LuceneObjectPtr other); + virtual int32_t hashCode(); - + protected: void addIfExists(HashSet files, const String& fileName); - + /// Called whenever any change is made that affects which files this segment has. void clearFiles(); }; diff --git a/include/SegmentInfoCollection.h b/include/SegmentInfoCollection.h index 52a4785f..9e7b379e 100644 --- a/include/SegmentInfoCollection.h +++ b/include/SegmentInfoCollection.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,12 +17,12 @@ namespace Lucene public: SegmentInfoCollection(); virtual ~SegmentInfoCollection(); - + LUCENE_CLASS(SegmentInfoCollection); - + protected: Collection segmentInfos; - + public: int32_t size(); bool empty(); @@ -35,7 +35,7 @@ namespace Lucene bool contains(SegmentInfoPtr info); void remove(int32_t pos); void remove(int32_t start, int32_t end); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); }; } diff --git a/include/SegmentInfos.h b/include/SegmentInfos.h index 68f9f31e..49ae6d1d 100644 --- a/include/SegmentInfos.h +++ b/include/SegmentInfos.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,44 +17,44 @@ namespace Lucene public: SegmentInfos(); virtual ~SegmentInfos(); - + LUCENE_CLASS(SegmentInfos); - - public: + + public: /// The file format version, a negative number. Works since counter, the old 1st entry, is always >= 0 static const int32_t FORMAT; - + /// This format adds details used for lockless commits. It differs slightly from the previous format in that file names - /// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, - /// segments_2, etc. This allows us to not use a commit lock. + /// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, + /// segments_2, etc. This allows us to not use a commit lock. /// See fileformats for details. static const int32_t FORMAT_LOCKLESS; - + /// This format adds a "hasSingleNormFile" flag into each segment info. static const int32_t FORMAT_SINGLE_NORM_FILE; - + /// This format allows multiple segments to share a single vectors and stored fields file. static const int32_t FORMAT_SHARED_DOC_STORE; - + /// This format adds a checksum at the end of the file to ensure all bytes were successfully written. static const int32_t FORMAT_CHECKSUM; - + /// This format adds the deletion count for each segment. This way IndexWriter can efficiently report numDocs(). static const int32_t FORMAT_DEL_COUNT; - + /// This format adds the boolean hasProx to record if any fields in the segment store prox information (ie, have /// omitTermFreqAndPositions == false) static const int32_t FORMAT_HAS_PROX; - + /// This format adds optional commit userData storage. static const int32_t FORMAT_USER_DATA; - + /// This format adds optional per-segment string diagnostics storage, and switches userData to Map static const int32_t FORMAT_DIAGNOSTICS; - + /// This must always point to the most recent file format. static const int32_t CURRENT_FORMAT; - + int32_t counter; // used to name new segments private: @@ -62,120 +62,120 @@ namespace Lucene static int32_t defaultGenFileRetryCount; static int32_t defaultGenFileRetryPauseMsec; static int32_t defaultGenLookaheadCount; - + /// Counts how often the index has been changed by adding or deleting docs. /// Starting with the current time in milliseconds forces to create unique version numbers. int64_t version; int64_t generation; // generation of the "segments_N" for the next commit - + int64_t lastGeneration; // generation of the "segments_N" file we last successfully read // or wrote; this is normally the same as generation except if // there was an exception that had interrupted a commit - + MapStringString userData; // Opaque map that user can specify during IndexWriter::commit - + static MapStringString singletonUserData; - + static InfoStreamPtr infoStream; ChecksumIndexOutputPtr pendingSegnOutput; - + public: SegmentInfoPtr info(int32_t i); String getCurrentSegmentFileName(); String getNextSegmentFileName(); - + /// Read a particular segmentFileName. Note that this may throw an IOException if a commit is in process. void read(DirectoryPtr directory, const String& segmentFileName); - + /// This version of read uses the retry logic (for lock-less commits) to find the right segments file to load. void read(DirectoryPtr directory); - + /// Returns a copy of this instance, also copying each SegmentInfo. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Version number when this SegmentInfos was generated. int64_t getVersion(); int64_t getGeneration(); int64_t getLastGeneration(); - - /// Returns a new SegmentInfos containing the SegmentInfo instances in the specified range first (inclusive) to + + /// Returns a new SegmentInfos containing the SegmentInfo instances in the specified range first (inclusive) to /// last (exclusive), so total number of segments returned is last-first. SegmentInfosPtr range(int32_t first, int32_t last); - + /// Carry over generation numbers from another SegmentInfos. void updateGeneration(SegmentInfosPtr other); - + void rollbackCommit(DirectoryPtr dir); - - /// Call this to start a commit. This writes the new segments file, but writes an invalid checksum at the end, so + + /// Call this to start a commit. This writes the new segments file, but writes an invalid checksum at the end, so /// that it is not visible to readers. Once this is called you must call. - /// {@link #finishCommit} to complete the commit or + /// {@link #finishCommit} to complete the commit or /// {@link #rollbackCommit} to abort it. void prepareCommit(DirectoryPtr dir); - - /// Returns all file names referenced by SegmentInfo instances matching the provided Directory (ie files associated + + /// Returns all file names referenced by SegmentInfo instances matching the provided Directory (ie files associated /// with any "external" segments are skipped). The returned collection is recomputed on each invocation. HashSet files(DirectoryPtr dir, bool includeSegmentsFile); - + void finishCommit(DirectoryPtr dir); - + /// Writes & syncs to the Directory dir, taking care to remove the segments file on exception. void commit(DirectoryPtr dir); - + String segString(DirectoryPtr directory); MapStringString getUserData(); void setUserData(MapStringString data); - - /// Replaces all segments in this instance, but keeps generation, version, counter so that future commits remain + + /// Replaces all segments in this instance, but keeps generation, version, counter so that future commits remain /// write once. void replace(SegmentInfosPtr other); - + bool hasExternalSegments(DirectoryPtr dir); - + static int64_t getCurrentSegmentGeneration(HashSet files); static int64_t getCurrentSegmentGeneration(DirectoryPtr directory); static String getCurrentSegmentFileName(HashSet files); static String getCurrentSegmentFileName(DirectoryPtr directory); static int64_t generationFromSegmentsFileName(const String& fileName); - + /// Current version number from segments file. static int64_t readCurrentVersion(DirectoryPtr directory); - + /// Returns userData from latest segments file. static MapStringString readCurrentUserData(DirectoryPtr directory); - + /// If non-null, information about retries when loading the segments file will be printed to this. static void setInfoStream(InfoStreamPtr infoStream); - - /// Set how many times to try loading the segments.gen file contents to determine current segment generation. This file + + /// Set how many times to try loading the segments.gen file contents to determine current segment generation. This file /// is only referenced when the primary method (listing the directory) fails. static void setDefaultGenFileRetryCount(int32_t count); - + /// @see #setDefaultGenFileRetryCount static int32_t getDefaultGenFileRetryCount(); - + /// Set how many milliseconds to pause in between attempts to load the segments.gen file. static void setDefaultGenFileRetryPauseMsec(int32_t msec); - + /// @see #setDefaultGenFileRetryPauseMsec static int32_t getDefaultGenFileRetryPauseMsec(); - + /// Set how many times to try incrementing the gen when loading the segments file. This only runs if the primary /// (listing directory) and secondary (opening segments.gen file) methods fail to find the segments file. static void setDefaultGenLookaheadCount(int32_t count); - + /// @see #setDefaultGenLookaheadCount static int32_t getDefaultGenLookahedCount(); - + /// @see #setInfoStream static InfoStreamPtr getInfoStream(); - + static void message(const String& message); - + protected: void write(DirectoryPtr directory); - + friend class FindSegmentsFile; }; } diff --git a/include/SegmentMergeInfo.h b/include/SegmentMergeInfo.h index b749ff52..6bade2ab 100644 --- a/include/SegmentMergeInfo.h +++ b/include/SegmentMergeInfo.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,21 +16,21 @@ namespace Lucene public: SegmentMergeInfo(int32_t b, TermEnumPtr te, IndexReaderPtr r); virtual ~SegmentMergeInfo(); - + LUCENE_CLASS(SegmentMergeInfo); - + protected: TermPositionsPtr postings; // use getPositions() Collection docMap; // use getDocMap() - + public: TermPtr term; int32_t base; int32_t ord; // the position of the segment in a MultiReader TermEnumPtr termEnum; IndexReaderWeakPtr _reader; - int32_t delCount; - + int32_t delCount; + public: Collection getDocMap(); TermPositionsPtr getPositions(); diff --git a/include/SegmentMergeQueue.h b/include/SegmentMergeQueue.h index 52182256..573c7dbd 100644 --- a/include/SegmentMergeQueue.h +++ b/include/SegmentMergeQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,12 +16,12 @@ namespace Lucene public: SegmentMergeQueue(int32_t size); virtual ~SegmentMergeQueue(); - + LUCENE_CLASS(SegmentMergeQueue); - + public: void close(); - + protected: virtual bool lessThan(const SegmentMergeInfoPtr& first, const SegmentMergeInfoPtr& second); }; diff --git a/include/SegmentMerger.h b/include/SegmentMerger.h index 8ba3aa21..381a7c91 100644 --- a/include/SegmentMerger.h +++ b/include/SegmentMerger.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// The SegmentMerger class combines two or more Segments, represented by an IndexReader ({@link #add}, into a single + /// The SegmentMerger class combines two or more Segments, represented by an IndexReader ({@link #add}, into a single /// Segment. After adding the appropriate readers, call the merge method to combine the segments. /// /// If the compoundFile flag is set, then the segments will be merged into a compound file. @@ -23,131 +23,131 @@ namespace Lucene SegmentMerger(DirectoryPtr dir, const String& name); SegmentMerger(IndexWriterPtr writer, const String& name, OneMergePtr merge); virtual ~SegmentMerger(); - + LUCENE_CLASS(SegmentMerger); - + protected: DirectoryPtr directory; String segment; int32_t termIndexInterval; - + Collection readers; FieldInfosPtr fieldInfos; - + int32_t mergedDocs; CheckAbortPtr checkAbort; - - /// Whether we should merge doc stores (stored fields and vectors files). When all segments we + + /// Whether we should merge doc stores (stored fields and vectors files). When all segments we /// are merging already share the same doc store files, we don't need to merge the doc stores. bool mergeDocStores; - + /// Maximum number of contiguous documents to bulk-copy when merging stored fields static const int32_t MAX_RAW_MERGE_DOCS; - + Collection matchingSegmentReaders; Collection rawDocLengths; Collection rawDocLengths2; - + SegmentMergeQueuePtr queue; bool omitTermFreqAndPositions; - + ByteArray payloadBuffer; Collection< Collection > docMaps; Collection delCounts; - + public: /// norms header placeholder static const uint8_t NORMS_HEADER[]; static const int32_t NORMS_HEADER_LENGTH; - + public: bool hasProx(); - + /// Add an IndexReader to the collection of readers that are to be merged void add(IndexReaderPtr reader); - + /// @param i The index of the reader to return /// @return The i'th reader to be merged IndexReaderPtr segmentReader(int32_t i); - + /// Merges the readers specified by the {@link #add} method into the directory passed to the constructor. /// @return The number of documents that were merged int32_t merge(); - + /// Merges the readers specified by the {@link #add} method into the directory passed to the constructor. /// @param mergeDocStores if false, we will not merge the stored fields nor vectors files /// @return The number of documents that were merged int32_t merge(bool mergeDocStores); - + /// close all IndexReaders that have been added. Should not be called before merge(). void closeReaders(); - + HashSet getMergedFiles(); HashSet createCompoundFile(const String& fileName); - + /// @return The number of documents in all of the readers int32_t mergeFields(); - + Collection< Collection > getDocMaps(); Collection getDelCounts(); - + protected: void addIndexed(IndexReaderPtr reader, FieldInfosPtr fInfos, HashSet names, bool storeTermVectors, - bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool storePayloads, + bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool storePayloads, bool omitTFAndPositions); - + void setMatchingSegmentReaders(); int32_t copyFieldsWithDeletions(FieldsWriterPtr fieldsWriter, IndexReaderPtr reader, FieldsReaderPtr matchingFieldsReader); int32_t copyFieldsNoDeletions(FieldsWriterPtr fieldsWriter, IndexReaderPtr reader, FieldsReaderPtr matchingFieldsReader); - + /// Merge the TermVectors from each of the segments into the new one. void mergeVectors(); - + void copyVectorsWithDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader); void copyVectorsNoDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader); - + void mergeTerms(); - + void mergeTermInfos(FormatPostingsFieldsConsumerPtr consumer); - - /// Process postings from multiple segments all positioned on the same term. Writes out merged entries + + /// Process postings from multiple segments all positioned on the same term. Writes out merged entries /// into freqOutput and the proxOutput streams. /// @param smis array of segments /// @param n number of cells in the array actually occupied /// @return number of documents across all segments where this term was found int32_t appendPostings(FormatPostingsTermsConsumerPtr termsConsumer, Collection smis, int32_t n); - + void mergeNorms(); }; - + class CheckAbort : public LuceneObject { public: CheckAbort(OneMergePtr merge, DirectoryPtr dir); virtual ~CheckAbort(); - + LUCENE_CLASS(CheckAbort); - + protected: double workCount; OneMergePtr merge; DirectoryWeakPtr _dir; - + public: /// Records the fact that roughly units amount of work have been done since this method was last called. - /// When adding time-consuming code into SegmentMerger, you should test different values for units to + /// When adding time-consuming code into SegmentMerger, you should test different values for units to /// ensure that the time in between calls to merge.checkAborted is up to ~ 1 second. virtual void work(double units); }; - + class CheckAbortNull : public CheckAbort { public: CheckAbortNull(); virtual ~CheckAbortNull(); - + LUCENE_CLASS(CheckAbortNull); - + public: /// do nothing virtual void work(double units); diff --git a/include/SegmentReader.h b/include/SegmentReader.h index 7c79627a..956f2cc2 100644 --- a/include/SegmentReader.h +++ b/include/SegmentReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,7 +17,7 @@ namespace Lucene public: SegmentReader(); virtual ~SegmentReader(); - + LUCENE_CLASS(SegmentReader); protected: @@ -46,172 +46,172 @@ namespace Lucene bool deletedDocsDirty; bool normsDirty; int32_t pendingDeleteCount; - + bool rollbackHasChanges; bool rollbackDeletedDocsDirty; bool rollbackNormsDirty; int32_t rollbackPendingDeleteCount; - + // optionally used for the .nrm file shared by multiple norms IndexInputPtr singleNormStream; SegmentReaderRefPtr singleNormRef; - + public: virtual void initialize(); - + using IndexReader::document; using IndexReader::termPositions; - + static SegmentReaderPtr get(bool readOnly, SegmentInfoPtr si, int32_t termInfosIndexDivisor); static SegmentReaderPtr get(bool readOnly, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor); - + void openDocStores(); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual LuceneObjectPtr clone(bool openReadOnly, LuceneObjectPtr other = LuceneObjectPtr()); SegmentReaderPtr reopenSegment(SegmentInfoPtr si, bool doClone, bool openReadOnly); - + static bool hasDeletions(SegmentInfoPtr si); - + /// Returns true if any documents have been deleted virtual bool hasDeletions(); - + static bool usesCompoundFile(SegmentInfoPtr si); static bool hasSeparateNorms(SegmentInfoPtr si); - + HashSet files(); - + /// Returns an enumeration of all the terms in the index. virtual TermEnumPtr terms(); - + /// Returns an enumeration of all terms starting at a given term. virtual TermEnumPtr terms(TermPtr t); - + /// Get the {@link Document} at the n'th position. virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); - - /// Returns true if document n has been deleted + + /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n); - + /// Returns an enumeration of all the documents which contain term. virtual TermDocsPtr termDocs(TermPtr term); - + /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs(); - + /// Returns an unpositioned {@link TermPositions} enumerator. virtual TermPositionsPtr termPositions(); - + /// Returns the number of documents containing the term t. virtual int32_t docFreq(TermPtr t); - + /// Returns the number of documents in this index. virtual int32_t numDocs(); - + /// Returns one greater than the largest possible document number. virtual int32_t maxDoc(); - + /// Get a list of unique field names that exist in this index and have the specified field option information. virtual HashSet getFieldNames(FieldOption fieldOption); - + /// Returns true if there are norms stored for this field. virtual bool hasNorms(const String& field); - + /// Returns the byte-encoded normalization factor for the named field of every document. virtual ByteArray norms(const String& field); - + /// Read norms into a pre-allocated array. virtual void norms(const String& field, ByteArray norms, int32_t offset); - + bool termsIndexLoaded(); - - /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, sharing a + + /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, sharing a /// segment that's still being merged. This method is not thread safe, and relies on the synchronization in IndexWriter void loadTermsIndex(int32_t termsIndexDivisor); - + bool normsClosed(); // for testing only bool normsClosed(const String& field); // for testing only - - /// Return a term frequency vector for the specified document and field. The vector returned contains term - /// numbers and frequencies for all terms in the specified field of this document, if the field had + + /// Return a term frequency vector for the specified document and field. The vector returned contains term + /// numbers and frequencies for all terms in the specified field of this document, if the field had /// storeTermVector flag set. If the flag was not set, the method returns null. virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - - /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays + + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays /// of the {@link TermFreqVector}. virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); - + /// Map all the term vectors for all fields in a Document virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); - - /// Return an array of term frequency vectors for the specified document. The array contains a vector for - /// each vectorized field in the document. Each vector vector contains term numbers and frequencies for all + + /// Return an array of term frequency vectors for the specified document. The array contains a vector for + /// each vectorized field in the document. Each vector vector contains term numbers and frequencies for all /// terms in a given vectorized field. If no such fields existed, the method returns null. virtual Collection getTermFreqVectors(int32_t docNumber); - + /// Return the name of the segment this reader is reading. String getSegmentName(); - + /// Return the SegmentInfo of the segment this reader is reading. SegmentInfoPtr getSegmentInfo(); void setSegmentInfo(SegmentInfoPtr info); - + void startCommit(); void rollbackCommit(); - + /// Returns the directory this index resides in. virtual DirectoryPtr directory(); - - /// This is necessary so that cloned SegmentReaders (which share the underlying postings data) + + /// This is necessary so that cloned SegmentReaders (which share the underlying postings data) /// will map to the same entry in the FieldCache. virtual LuceneObjectPtr getFieldCacheKey(); virtual LuceneObjectPtr getDeletesCacheKey(); - + /// Returns the number of unique terms (across all fields) in this reader. virtual int64_t getUniqueTermCount(); - + static SegmentReaderPtr getOnlySegmentReader(DirectoryPtr dir); static SegmentReaderPtr getOnlySegmentReader(IndexReaderPtr reader); - + virtual int32_t getTermInfosIndexDivisor(); - + protected: bool checkDeletedCounts(); void loadDeletedDocs(); - + /// Clones the norm bytes. May be overridden by subclasses. /// @param bytes Byte array to clone /// @return New BitVector virtual ByteArray cloneNormBytes(ByteArray bytes); - + /// Clones the deleteDocs BitVector. May be overridden by subclasses. /// @param bv BitVector to clone /// @return New BitVector virtual BitVectorPtr cloneDeletedDocs(BitVectorPtr bv); - + /// Implements commit. virtual void doCommit(MapStringString commitUserData); - + virtual void commitChanges(MapStringString commitUserData); - + /// Implements close. virtual void doClose(); - + /// Implements deletion of the document numbered docNum. /// Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}. virtual void doDelete(int32_t docNum); - + /// Implements actual undeleteAll() in subclass. virtual void doUndeleteAll(); - + /// can return null if norms aren't stored ByteArray getNorms(const String& field); - + /// Implements setNorm in subclass. virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - + void openNorms(DirectoryPtr cfsDir, int32_t readBufferSize); - + friend class ReaderPool; friend class IndexWriter; friend class Norm; diff --git a/include/SegmentTermDocs.h b/include/SegmentTermDocs.h index 4db8b26d..8e45e836 100644 --- a/include/SegmentTermDocs.h +++ b/include/SegmentTermDocs.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: SegmentTermDocs(SegmentReaderPtr parent); virtual ~SegmentTermDocs(); - + LUCENE_CLASS(SegmentTermDocs); - + protected: SegmentReaderWeakPtr _parent; IndexInputPtr _freqStream; @@ -27,54 +27,54 @@ namespace Lucene BitVectorPtr deletedDocs; int32_t _doc; int32_t _freq; - + int32_t skipInterval; int32_t maxSkipLevels; DefaultSkipListReaderPtr skipListReader; - + int64_t freqBasePointer; int64_t proxBasePointer; - + int64_t skipPointer; bool haveSkipped; - + bool currentFieldStoresPayloads; bool currentFieldOmitTermFreqAndPositions; - + public: /// Sets this to the data for a term. virtual void seek(TermPtr term); - + /// Sets this to the data for the current term in a {@link TermEnum}. virtual void seek(TermEnumPtr termEnum); - + virtual void seek(TermInfoPtr ti, TermPtr term); - + virtual void close(); - + /// Returns the current document number. virtual int32_t doc(); - + /// Returns the frequency of the term within the current document. virtual int32_t freq(); - + /// Moves to the next pair in the enumeration. virtual bool next(); - + /// Optimized implementation. virtual int32_t read(Collection docs, Collection freqs); - + /// Optimized implementation. virtual bool skipTo(int32_t target); - + /// Used for testing virtual IndexInputPtr freqStream(); virtual void freqStream(IndexInputPtr freqStream); - + protected: virtual void skippingDoc(); virtual int32_t readNoTf(Collection docs, Collection freqs, int32_t length); - + /// Overridden by SegmentTermPositions to skip in prox stream. virtual void skipProx(int64_t proxPointer, int32_t payloadLength); }; diff --git a/include/SegmentTermEnum.h b/include/SegmentTermEnum.h index 5a40f4e8..baaf3517 100644 --- a/include/SegmentTermEnum.h +++ b/include/SegmentTermEnum.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,69 +17,69 @@ namespace Lucene SegmentTermEnum(); SegmentTermEnum(IndexInputPtr i, FieldInfosPtr fis, bool isi); virtual ~SegmentTermEnum(); - + LUCENE_CLASS(SegmentTermEnum); - + protected: IndexInputPtr input; TermBufferPtr termBuffer; TermBufferPtr prevBuffer; TermBufferPtr scanBuffer; // used for scanning - + TermInfoPtr _termInfo; - + int32_t format; bool isIndex; int32_t formatM1SkipInterval; - + public: FieldInfosPtr fieldInfos; int64_t size; int64_t position; - + int64_t indexPointer; int32_t indexInterval; int32_t skipInterval; int32_t maxSkipLevels; - + public: virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + void seek(int64_t pointer, int64_t p, TermPtr t, TermInfoPtr ti); - + /// Increments the enumeration to the next element. True if one exists. virtual bool next(); - + /// Optimized scan, without allocating new terms. Return number of invocations to next(). int32_t scanTo(TermPtr term); - + /// Returns the current Term in the enumeration. /// Initially invalid, valid after next() called for the first time. virtual TermPtr term(); - + /// Returns the previous Term enumerated. Initially null. TermPtr prev(); - + /// Returns the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. TermInfoPtr termInfo(); - + /// Sets the argument to the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. void termInfo(TermInfoPtr ti); - + /// Returns the docFreq of the current Term in the enumeration. /// Initially invalid, valid after next() called for the first time. virtual int32_t docFreq(); - + /// Returns the freqPointer from the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. int64_t freqPointer(); - + /// Returns the proxPointer from the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. int64_t proxPointer(); - + /// Closes the enumeration to further activity, freeing resources. virtual void close(); }; diff --git a/include/SegmentTermPositionVector.h b/include/SegmentTermPositionVector.h index 31339e7b..68414932 100644 --- a/include/SegmentTermPositionVector.h +++ b/include/SegmentTermPositionVector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,25 +14,25 @@ namespace Lucene class SegmentTermPositionVector : public SegmentTermVector { public: - SegmentTermPositionVector(const String& field, Collection terms, Collection termFreqs, + SegmentTermPositionVector(const String& field, Collection terms, Collection termFreqs, Collection< Collection > positions, Collection< Collection > offsets); virtual ~SegmentTermPositionVector(); - + LUCENE_CLASS(SegmentTermPositionVector); - + protected: Collection< Collection > positions; Collection< Collection > offsets; - + protected: static const Collection EMPTY_TERM_POS(); - + public: /// Returns an array of TermVectorOffsetInfo in which the term is found. /// @param index The position in the array to get the offsets from /// @return An array of TermVectorOffsetInfo objects or the empty list virtual Collection getOffsets(int32_t index); - + /// Returns an array of positions in which the term is found. /// Terms are identified by the index at which its number appears in the term String array obtained from the indexOf method. virtual Collection getTermPositions(int32_t index); diff --git a/include/SegmentTermPositions.h b/include/SegmentTermPositions.h index e9018001..4af0c99f 100644 --- a/include/SegmentTermPositions.h +++ b/include/SegmentTermPositions.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,62 +16,62 @@ namespace Lucene public: SegmentTermPositions(SegmentReaderPtr parent); virtual ~SegmentTermPositions(); - + LUCENE_CLASS(SegmentTermPositions); - + protected: IndexInputPtr proxStream; int32_t proxCount; int32_t position; - + /// The current payload length int32_t payloadLength; - + /// Indicates whether the payload of the current position has been read from the proxStream yet bool needToLoadPayload; - + // these variables are being used to remember information for a lazy skip int64_t lazySkipPointer; int32_t lazySkipProxCount; - + public: using SegmentTermDocs::seek; - + virtual void seek(TermInfoPtr ti, TermPtr term); virtual void close(); - + /// Returns next position in the current document. virtual int32_t nextPosition(); - + /// Moves to the next pair in the enumeration. virtual bool next(); - + /// Not supported virtual int32_t read(Collection docs, Collection freqs); - + /// Returns the length of the payload at the current term position. virtual int32_t getPayloadLength(); - + /// Returns the payload data at the current term position. virtual ByteArray getPayload(ByteArray data, int32_t offset); - + /// Checks if a payload can be loaded at this position. virtual bool isPayloadAvailable(); - + protected: int32_t readDeltaPosition(); - + virtual void skippingDoc(); - + virtual void skipProx(int64_t proxPointer, int32_t payloadLength); virtual void skipPositions(int32_t n); virtual void skipPayload(); - - /// It is not always necessary to move the prox pointer to a new document after the freq pointer has - /// been moved. Consider for example a phrase query with two terms: the freq pointer for term 1 has to - /// move to document x to answer the question if the term occurs in that document. But only if term 2 + + /// It is not always necessary to move the prox pointer to a new document after the freq pointer has + /// been moved. Consider for example a phrase query with two terms: the freq pointer for term 1 has to + /// move to document x to answer the question if the term occurs in that document. But only if term 2 /// also matches document x, the positions have to be read to figure out if term 1 and term 2 appear next - /// to each other in document x and thus satisfy the query. So we move the prox pointer lazily to the + /// to each other in document x and thus satisfy the query. So we move the prox pointer lazily to the /// document as soon as positions are requested. virtual void lazySkip(); }; diff --git a/include/SegmentTermVector.h b/include/SegmentTermVector.h index 814b9ecb..47dbdc63 100644 --- a/include/SegmentTermVector.h +++ b/include/SegmentTermVector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,33 +16,33 @@ namespace Lucene public: SegmentTermVector(const String& field, Collection terms, Collection termFreqs); virtual ~SegmentTermVector(); - + LUCENE_CLASS(SegmentTermVector); - + protected: String field; Collection terms; Collection termFreqs; - + public: /// @return The number of the field this vector is associated with virtual String getField(); - + virtual String toString(); - + /// @return The number of terms in the term vector. virtual int32_t size(); - + /// @return An Array of term texts in ascending order. virtual Collection getTerms(); - + /// @return Array of term frequencies. virtual Collection getTermFrequencies(); - - /// Return an index in the term numbers array returned from getTerms at which the term with the + + /// Return an index in the term numbers array returned from getTerms at which the term with the /// specified term appears. virtual int32_t indexOf(const String& term); - + /// Just like indexOf(int) but searches for a number of terms at the same time. virtual Collection indexesOf(Collection termNumbers, int32_t start, int32_t length); }; diff --git a/include/SegmentWriteState.h b/include/SegmentWriteState.h index 0a037657..b9d6781b 100644 --- a/include/SegmentWriteState.h +++ b/include/SegmentWriteState.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,13 +14,13 @@ namespace Lucene class SegmentWriteState : public LuceneObject { public: - SegmentWriteState(DocumentsWriterPtr docWriter, DirectoryPtr directory, const String& segmentName, - const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, + SegmentWriteState(DocumentsWriterPtr docWriter, DirectoryPtr directory, const String& segmentName, + const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, int32_t termIndexInterval); virtual ~SegmentWriteState(); - + LUCENE_CLASS(SegmentWriteState); - + public: DocumentsWriterWeakPtr _docWriter; DirectoryPtr directory; @@ -30,7 +30,7 @@ namespace Lucene int32_t termIndexInterval; int32_t numDocsInStore; HashSet flushedFiles; - + public: String segmentFileName(const String& ext); }; diff --git a/include/SerialMergeScheduler.h b/include/SerialMergeScheduler.h index 28e21fd7..14d04a25 100644 --- a/include/SerialMergeScheduler.h +++ b/include/SerialMergeScheduler.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,14 +16,14 @@ namespace Lucene { public: virtual ~SerialMergeScheduler(); - + LUCENE_CLASS(SerialMergeScheduler); - + public: /// Just do the merges in sequence. We do this "synchronized" so that even if the application is using /// multiple threads, only one merge may run at a time. virtual void merge(IndexWriterPtr writer); - + /// Close this MergeScheduler. virtual void close(); }; diff --git a/include/Set.h b/include/Set.h index 90ca7027..17a688e7 100644 --- a/include/Set.h +++ b/include/Set.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/SetBasedFieldSelector.h b/include/SetBasedFieldSelector.h index 5e840c7e..181b6c4e 100644 --- a/include/SetBasedFieldSelector.h +++ b/include/SetBasedFieldSelector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,22 +15,22 @@ namespace Lucene class LPPAPI SetBasedFieldSelector : public FieldSelector { public: - /// Pass in the Set of {@link Field} names to load and the Set of {@link Field} names to load lazily. - /// If both are null, the Document will not have any {@link Field} on it. + /// Pass in the Set of {@link Field} names to load and the Set of {@link Field} names to load lazily. + /// If both are null, the Document will not have any {@link Field} on it. /// @param fieldsToLoad A Set of {@link String} field names to load. May be empty, but not null /// @param lazyFieldsToLoad A Set of {@link String} field names to load lazily. May be empty, but not null SetBasedFieldSelector(HashSet fieldsToLoad, HashSet lazyFieldsToLoad); - + virtual ~SetBasedFieldSelector(); - + LUCENE_CLASS(SetBasedFieldSelector); - + protected: HashSet fieldsToLoad; HashSet lazyFieldsToLoad; - + public: - /// Indicate whether to load the field with the given name or not. If the {@link Field#name()} is not in + /// Indicate whether to load the field with the given name or not. If the {@link Field#name()} is not in /// either of the initializing Sets, then {@link FieldSelectorResult#NO_LOAD} is returned. If a Field name /// is in both fieldsToLoad and lazyFieldsToLoad, lazy has precedence. /// @param fieldName The {@link Field} name to check diff --git a/include/Similarity.h b/include/Similarity.h index ddc74f01..c50dd4de 100644 --- a/include/Similarity.h +++ b/include/Similarity.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,32 +13,32 @@ namespace Lucene { /// Scoring API. /// - /// Similarity defines the components of Lucene scoring. Overriding computation of these components is + /// Similarity defines the components of Lucene scoring. Overriding computation of these components is /// a convenient way to alter Lucene scoring. /// /// Suggested reading: /// Introduction To Information Retrieval, Chapter 6. /// - /// The following describes how Lucene scoring evolves from underlying information retrieval models to - /// (efficient) implementation. We first brief on VSM Score, then derive from it Lucene's Conceptual Scoring + /// The following describes how Lucene scoring evolves from underlying information retrieval models to + /// (efficient) implementation. We first brief on VSM Score, then derive from it Lucene's Conceptual Scoring /// Formula, from which, finally, evolves Lucene's Practical Scoring Function (the latter is connected directly /// with Lucene classes and methods). /// - /// Lucene combines Boolean model (BM) of - /// Information Retrieval with Vector Space Model + /// Lucene combines Boolean model (BM) of + /// Information Retrieval with Vector Space Model /// (VSM) of Information Retrieval - documents "approved" by BM are scored by VSM. /// - /// In VSM, documents and queries are represented as weighted vectors in a multi-dimensional space, where each + /// In VSM, documents and queries are represented as weighted vectors in a multi-dimensional space, where each /// distinct index term is a dimension, and weights are Tf-idf /// values. /// - /// VSM does not require weights to be Tf-idf values, but Tf-idf values are believed to produce search results - /// of high quality, and so Lucene is using Tf-idf. Tf and Idf are described in more detail below, but for now, - /// for completion, let's just say that for given term t and document (or query) x, Tf(t,x) varies with the - /// number of occurrences of term t in x (when one increases so does the other) and idf(t) similarly varies with + /// VSM does not require weights to be Tf-idf values, but Tf-idf values are believed to produce search results + /// of high quality, and so Lucene is using Tf-idf. Tf and Idf are described in more detail below, but for now, + /// for completion, let's just say that for given term t and document (or query) x, Tf(t,x) varies with the + /// number of occurrences of term t in x (when one increases so does the other) and idf(t) similarly varies with /// the inverse of the number of index documents containing term t. /// - /// VSM score of document d for query q is the Cosine + /// VSM score of document d for query q is the Cosine /// Similarity of the weighted query vectors V(q) and V(d): /// ///
     
    @@ -69,38 +69,38 @@ namespace Lucene /// ///
     
    /// - /// Where V(q) · V(d) is the dot product of the - /// weighted vectors, and |V(q)| and |V(d)| are their + /// Where V(q) · V(d) is the dot product of the + /// weighted vectors, and |V(q)| and |V(d)| are their /// Euclidean norms. /// - /// Note: the above equation can be viewed as the dot product of the normalized weighted vectors, in the sense + /// Note: the above equation can be viewed as the dot product of the normalized weighted vectors, in the sense /// that dividing V(q) by its euclidean norm is normalizing it to a unit vector. /// /// Lucene refines VSM score for both search quality and usability: ///
      - ///
    • Normalizing V(d) to the unit vector is known to be problematic in that it removes all document length - /// information. For some documents removing this info is probably ok, eg. a document made by duplicating a - /// certain paragraph 10 times, especially if that paragraph is made of distinct terms. But for a document which - /// contains no duplicated paragraphs, this might be wrong. To avoid this problem, a different document length - /// normalization factor is used, which normalizes to a vector equal to or larger than the unit vector: + ///
    • Normalizing V(d) to the unit vector is known to be problematic in that it removes all document length + /// information. For some documents removing this info is probably ok, eg. a document made by duplicating a + /// certain paragraph 10 times, especially if that paragraph is made of distinct terms. But for a document which + /// contains no duplicated paragraphs, this might be wrong. To avoid this problem, a different document length + /// normalization factor is used, which normalizes to a vector equal to or larger than the unit vector: /// doc-len-norm(d). ///
    • - ///
    • At indexing, users can specify that certain documents are more important than others, by assigning a + ///
    • At indexing, users can specify that certain documents are more important than others, by assigning a /// document boost. For this, the score of each document is also multiplied by its boost value doc-boost(d). ///
    • - ///
    • Lucene is field based, hence each query term applies to a single field, document length normalization - /// is by the length of the certain field, and in addition to document boost there are also document fields + ///
    • Lucene is field based, hence each query term applies to a single field, document length normalization + /// is by the length of the certain field, and in addition to document boost there are also document fields /// boosts. ///
    • - ///
    • The same field can be added to a document during indexing several times, and so the boost of that field + ///
    • The same field can be added to a document during indexing several times, and so the boost of that field /// is the multiplication of the boosts of the separate additions (or parts) of that field within the document. ///
    • - ///
    • At search time users can specify boosts to each query, sub-query, and each query term, hence the - /// contribution of a query term to the score of a document is multiplied by the boost of that query term + ///
    • At search time users can specify boosts to each query, sub-query, and each query term, hence the + /// contribution of a query term to the score of a document is multiplied by the boost of that query term /// query-boost(q). ///
    • - ///
    • A document may match a multi term query without containing all the terms of that query (this is correct - /// for some of the queries), and users can further reward documents matching more query terms through a + ///
    • A document may match a multi term query without containing all the terms of that query (this is correct + /// for some of the queries), and users can further reward documents matching more query terms through a /// coordination factor, which is usually larger when more terms are matched: coord-factor(q,d). ///
    • ///
    @@ -141,42 +141,42 @@ namespace Lucene /// ///
     
    /// - /// The conceptual formula is a simplification in the sense that (1) terms and documents are fielded and (2) + /// The conceptual formula is a simplification in the sense that (1) terms and documents are fielded and (2) /// boosts are usually per query term rather than per query. /// - /// We now describe how Lucene implements this conceptual scoring formula, and derive from it Lucene's Practical + /// We now describe how Lucene implements this conceptual scoring formula, and derive from it Lucene's Practical /// Scoring Function. /// /// For efficient score computation some scoring components are computed and aggregated in advance: ///
      ///
    • Query-boost for the query (actually for each query term) is known when search starts. ///
    • - ///
    • Query Euclidean norm |V(q)| can be computed when search starts, as it is independent of the document - /// being scored. From search optimization perspective, it is a valid question why bother to normalize the - /// query at all, because all scored documents will be multiplied by the same |V(q)|, and hence documents ranks - /// (their order by score) will not be affected by this normalization. There are two good reasons to keep this + ///
    • Query Euclidean norm |V(q)| can be computed when search starts, as it is independent of the document + /// being scored. From search optimization perspective, it is a valid question why bother to normalize the + /// query at all, because all scored documents will be multiplied by the same |V(q)|, and hence documents ranks + /// (their order by score) will not be affected by this normalization. There are two good reasons to keep this /// normalization: ///
        - ///
      • Recall that Cosine Similarity can be used - /// find how similar two documents are. One can use Lucene for eg. clustering, and use a document as a query to + ///
      • Recall that Cosine Similarity can be used + /// find how similar two documents are. One can use Lucene for eg. clustering, and use a document as a query to /// compute its similarity to other documents. In this use case it is important that the score of document d3 - /// for query d1 is comparable to the score of document d3 for query d2. In other words, scores of a document for - /// two distinct queries should be comparable. There are other applications that may require this. And this is - /// exactly what normalizing the query vector V(q) provides: comparability (to a certain extent) of two or more + /// for query d1 is comparable to the score of document d3 for query d2. In other words, scores of a document for + /// two distinct queries should be comparable. There are other applications that may require this. And this is + /// exactly what normalizing the query vector V(q) provides: comparability (to a certain extent) of two or more /// queries. ///
      • - ///
      • Applying query normalization on the scores helps to keep the scores around the unit vector, hence preventing + ///
      • Applying query normalization on the scores helps to keep the scores around the unit vector, hence preventing /// loss of score data because of floating point precision limitations. ///
      • ///
      ///
    • - ///
    • Document length norm doc-len-norm(d) and document boost doc-boost(d) are known at indexing time. They are - /// computed in advance and their multiplication is saved as a single value in the index: norm(d). (In the equations + ///
    • Document length norm doc-len-norm(d) and document boost doc-boost(d) are known at indexing time. They are + /// computed in advance and their multiplication is saved as a single value in the index: norm(d). (In the equations /// below, norm(t in d) means norm(field(t) in doc d) where field(t) is the field associated with term t.) ///
    • ///
    /// - /// Lucene's Practical Scoring Function is derived from the above. The color codes demonstrate how it relates to + /// Lucene's Practical Scoring Function is derived from the above. The color codes demonstrate how it relates to /// those of the conceptual formula: /// /// @@ -215,13 +215,13 @@ namespace Lucene ///
    Lucene Practical Scoring Function
    /// ///
    - /// + /// /// where ///
      ///
    1. /// /// tf(t in d) - /// correlates to the term's frequency, defined as the number of times term t appears in the currently + /// correlates to the term's frequency, defined as the number of times term t appears in the currently /// scored document d. Documents that have more occurrences of a given term receive a higher score. /// Note that tf(t in q) is assumed to be 1 and therefore it does not appear in this equation, /// However if a query contains twice the same term, there will be two term-queries with that same term @@ -276,9 +276,9 @@ namespace Lucene ///
    2. /// /// coord(q,d) - /// is a score factor based on how many of the query terms are found in the specified document. Typically, a - /// document that contains more of the query's terms will receive a higher score than another document with - /// fewer query terms. This is a search time factor computed in {@link #coord(int, int) coord(q,d)} by the + /// is a score factor based on how many of the query terms are found in the specified document. Typically, a + /// document that contains more of the query's terms will receive a higher score than another document with + /// fewer query terms. This is a search time factor computed in {@link #coord(int, int) coord(q,d)} by the /// Similarity in effect at search time. ///
       
      ///
    3. @@ -287,9 +287,9 @@ namespace Lucene /// /// queryNorm(q) /// - /// is a normalizing factor used to make scores between queries comparable. This factor does not affect - /// document ranking (since all ranked documents are multiplied by the same factor), but rather just attempts - /// to make scores from different queries (or even different indexes) comparable. This is a search time + /// is a normalizing factor used to make scores between queries comparable. This factor does not affect + /// document ranking (since all ranked documents are multiplied by the same factor), but rather just attempts + /// to make scores from different queries (or even different indexes) comparable. This is a search time /// factor computed by the Similarity in effect at search time. /// /// The default computation in {@link DefaultSimilarity#queryNorm(float) DefaultSimilarity} @@ -315,7 +315,7 @@ namespace Lucene /// ///
       
      /// - /// The sum of squared weights (of the query terms) is computed by the query {@link Weight} object. For example, + /// The sum of squared weights (of the query terms) is computed by the query {@link Weight} object. For example, /// a {@link BooleanQuery boolean query} computes this value as: /// ///
       
      @@ -349,8 +349,8 @@ namespace Lucene ///
    4. /// /// t.getBoost() - /// is a search time boost of term t in the query q as specified in the query text or as set by application - /// calls to {@link Query#setBoost(float) setBoost()}. Notice that there is really no direct API for accessing + /// is a search time boost of term t in the query q as specified in the query text or as set by application + /// calls to {@link Query#setBoost(float) setBoost()}. Notice that there is really no direct API for accessing /// a boost of one term in a multi term query, but rather multi terms are represented in a query as multi /// {@link TermQuery TermQuery} objects, and so the boost of a term in the query is accessible by calling /// the sub-query {@link Query#getBoost() getBoost()}. @@ -370,7 +370,7 @@ namespace Lucene /// {@link Fieldable#setBoost(float) field.setBoost()} /// before adding the field to a document. ///
    5. - ///
    6. {@link #lengthNorm(String, int) lengthNorm(field)} - computed when the document is added to + ///
    7. {@link #lengthNorm(String, int) lengthNorm(field)} - computed when the document is added to /// the index in accordance with the number of tokens of this field in the document, so that shorter fields /// contribute more to the score. LengthNorm is computed by the Similarity class in effect at indexing. ///
    8. @@ -404,18 +404,18 @@ namespace Lucene /// ///
       
      /// However the resulted norm value is {@link #encodeNorm(float) encoded} as a single byte before being stored. - /// At search time, the norm byte value is read from the index {@link Directory directory} and {@link - /// #decodeNorm(byte) decoded} back to a float norm value. This encoding/decoding, while reducing index size, - /// comes with the price of precision loss - it is not guaranteed that decode(encode(x)) = x. For instance, + /// At search time, the norm byte value is read from the index {@link Directory directory} and {@link + /// #decodeNorm(byte) decoded} back to a float norm value. This encoding/decoding, while reducing index size, + /// comes with the price of precision loss - it is not guaranteed that decode(encode(x)) = x. For instance, /// decode(encode(0.89)) = 0.75. ///
       
      - /// Compression of norm values to a single byte saves memory at search time, because once a field is referenced + /// Compression of norm values to a single byte saves memory at search time, because once a field is referenced /// at search time, its norms - for all documents - are maintained in memory. ///
       
      - /// The rationale supporting such lossy compression of norm values is that given the difficulty (and inaccuracy) + /// The rationale supporting such lossy compression of norm values is that given the difficulty (and inaccuracy) /// of users to express their true information need by a query, only big differences matter. ///
       
      - /// Last, note that search time is too late to modify this norm part of scoring, eg. by using a different + /// Last, note that search time is too late to modify this norm part of scoring, eg. by using a different /// {@link Similarity} for search. ///
       
      /// @@ -429,53 +429,53 @@ namespace Lucene public: Similarity(); virtual ~Similarity(); - + LUCENE_CLASS(Similarity); - + protected: static const int32_t NO_DOC_ID_PROVIDED; - + protected: static const Collection NORM_TABLE(); - + public: /// Return the default Similarity implementation used by indexing and search code. /// This is initially an instance of {@link DefaultSimilarity}. /// @see Searcher#setSimilarity(SimilarityPtr) /// @see IndexWriter#setSimilarity(SimilarityPtr) static SimilarityPtr getDefault(); - + /// Decodes a normalization factor stored in an index. /// @see #encodeNorm(double) static double decodeNorm(uint8_t b); - + /// Returns a table for decoding normalization bytes. /// @see #encodeNorm(double) static const Collection getNormDecoder(); - - /// Compute the normalization value for a field, given the accumulated state of term processing for this + + /// Compute the normalization value for a field, given the accumulated state of term processing for this /// field (see {@link FieldInvertState}). /// /// Implementations should calculate a float value based on the field state and then return that value. /// /// For backward compatibility this method by default calls {@link #lengthNorm(String, int32_t)} passing - /// {@link FieldInvertState#getLength()} as the second argument, and then multiplies this value by {@link + /// {@link FieldInvertState#getLength()} as the second argument, and then multiplies this value by {@link /// FieldInvertState#getBoost()}. /// /// @param field Field name /// @param state Current processing state for this field /// @return The calculated float norm virtual double computeNorm(const String& fieldName, FieldInvertStatePtr state); - - /// Computes the normalization value for a field given the total number of terms contained in a field. - /// These values, together with field boosts, are stored in an index and multiplied into scores for hits + + /// Computes the normalization value for a field given the total number of terms contained in a field. + /// These values, together with field boosts, are stored in an index and multiplied into scores for hits /// on each field by the search code. /// - /// Matches in longer fields are less precise, so implementations of this method usually return smaller + /// Matches in longer fields are less precise, so implementations of this method usually return smaller /// values when numTokens is large, and larger values when numTokens is small. /// - /// Note that the return values are computed under {@link IndexWriter#addDocument(DocumentPtr)} and then - /// stored using {@link #encodeNorm(double)}. Thus they have limited precision, and documents must be + /// Note that the return values are computed under {@link IndexWriter#addDocument(DocumentPtr)} and then + /// stored using {@link #encodeNorm(double)}. Thus they have limited precision, and documents must be /// re-indexed if this method is altered. /// /// @param fieldName The name of the field @@ -483,36 +483,36 @@ namespace Lucene /// @return A normalization factor for hits on this field of this document /// @see Field#setBoost(double) virtual double lengthNorm(const String& fieldName, int32_t numTokens) = 0; - - /// Computes the normalization value for a query given the sum of the squared weights of each of the query - /// terms. This value is multiplied into the weight of each query term. While the classic query - /// normalization factor is computed as 1/sqrt(sumOfSquaredWeights), other implementations might completely + + /// Computes the normalization value for a query given the sum of the squared weights of each of the query + /// terms. This value is multiplied into the weight of each query term. While the classic query + /// normalization factor is computed as 1/sqrt(sumOfSquaredWeights), other implementations might completely /// ignore sumOfSquaredWeights (ie return 1). /// - /// This does not affect ranking, but the default implementation does make scores from different queries - /// more comparable than they would be by eliminating the magnitude of the Query vector as a factor in the + /// This does not affect ranking, but the default implementation does make scores from different queries + /// more comparable than they would be by eliminating the magnitude of the Query vector as a factor in the /// score. /// /// @param sumOfSquaredWeights The sum of the squares of query term weights /// @return a normalization factor for query weights virtual double queryNorm(double sumOfSquaredWeights) = 0; - + /// Encodes a normalization factor for storage in an index. /// /// The encoding uses a three-bit mantissa, a five-bit exponent, and the zero-exponent point at 15, thus - /// representing values from around 7x10^9 to 2x10^-9 with about one significant decimal digit of accuracy. + /// representing values from around 7x10^9 to 2x10^-9 with about one significant decimal digit of accuracy. /// Zero is also represented. Negative numbers are rounded up to zero. Values too large to represent - /// are rounded down to the largest representable value. Positive values too small to represent are rounded + /// are rounded down to the largest representable value. Positive values too small to represent are rounded /// up to the smallest positive representable value. /// /// @see Field#setBoost(double) static uint8_t encodeNorm(double f); - - /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied - /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then + + /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied + /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then /// summed to form the initial score for a document. /// - /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this + /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this /// method usually return larger values when freq is large, and smaller values when freq is small. /// /// The default implementation calls {@link #tf(double)}. @@ -520,30 +520,30 @@ namespace Lucene /// @param freq The frequency of a term within a document /// @return A score factor based on a term's within-document frequency virtual double tf(int32_t freq); - - /// Computes the amount of a sloppy phrase match, based on an edit distance. This value is summed for + + /// Computes the amount of a sloppy phrase match, based on an edit distance. This value is summed for /// each sloppy phrase match in a document to form the frequency that is passed to {@link #tf(double)}. /// - /// A phrase match with a small edit distance to a document passage more closely matches the document, so - /// implementations of this method usually return larger values when the edit distance is small and + /// A phrase match with a small edit distance to a document passage more closely matches the document, so + /// implementations of this method usually return larger values when the edit distance is small and /// smaller values when it is large. /// /// @see PhraseQuery#setSlop(int32_t) /// @param distance The edit distance of this sloppy phrase match /// @return The frequency increment for this match virtual double sloppyFreq(int32_t distance) = 0; - - /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied - /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then + + /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied + /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then /// summed to form the initial score for a document. /// - /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this + /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this /// method usually return larger values when freq is large, and smaller values when freq is small. /// /// @param freq The frequency of a term within a document /// @return A score factor based on a term's within-document frequency virtual double tf(double freq) = 0; - + /// Computes a score factor for a simple term and returns an explanation for that score factor. /// /// The default implementation uses: @@ -551,58 +551,58 @@ namespace Lucene /// idf(searcher->docFreq(term), searcher->maxDoc()); ///
    /// - /// Note that {@link Searcher#maxDoc()} is used instead of {@link IndexReader#numDocs() IndexReader#numDocs()} - /// because also {@link Searcher#docFreq(TermPtr)} is used, and when the latter is inaccurate, so is {@link - /// Searcher#maxDoc()}, and in the same direction. In addition, {@link Searcher#maxDoc()} is more efficient + /// Note that {@link Searcher#maxDoc()} is used instead of {@link IndexReader#numDocs() IndexReader#numDocs()} + /// because also {@link Searcher#docFreq(TermPtr)} is used, and when the latter is inaccurate, so is {@link + /// Searcher#maxDoc()}, and in the same direction. In addition, {@link Searcher#maxDoc()} is more efficient /// to compute. /// /// @param term The term in question /// @param searcher The document collection being searched /// @return An IDFExplain object that includes both an idf score factor and an explanation for the term. virtual IDFExplanationPtr idfExplain(TermPtr term, SearcherPtr searcher); - + /// Computes a score factor for a phrase. /// /// The default implementation sums the idf factor for each term in the phrase. /// /// @param terms The terms in the phrase /// @param searcher The document collection being searched - /// @return An IDFExplain object that includes both an idf score factor for the phrase and an explanation + /// @return An IDFExplain object that includes both an idf score factor for the phrase and an explanation /// for each term. virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher); - - /// Computes a score factor based on a term's document frequency (the number of documents which contain the - /// term). This value is multiplied by the {@link #tf(int32_t)} factor for each term in the query and these + + /// Computes a score factor based on a term's document frequency (the number of documents which contain the + /// term). This value is multiplied by the {@link #tf(int32_t)} factor for each term in the query and these /// products are then summed to form the initial score for a document. /// - /// Terms that occur in fewer documents are better indicators of topic, so implementations of this method + /// Terms that occur in fewer documents are better indicators of topic, so implementations of this method /// usually return larger values for rare terms, and smaller values for common terms. /// /// @param docFreq The number of documents which contain the term /// @param numDocs The total number of documents in the collection /// @return A score factor based on the term's document frequency virtual double idf(int32_t docFreq, int32_t numDocs) = 0; - - /// Computes a score factor based on the fraction of all query terms that a document contains. This value + + /// Computes a score factor based on the fraction of all query terms that a document contains. This value /// is multiplied into scores. /// - /// The presence of a large portion of the query terms indicates a better match with the query, so - /// implementations of this method usually return larger values when the ratio between these parameters is + /// The presence of a large portion of the query terms indicates a better match with the query, so + /// implementations of this method usually return larger values when the ratio between these parameters is /// large and smaller values when the ratio between them is small. /// /// @param overlap The number of query terms matched in the document /// @param maxOverlap The total number of terms in the query /// @return A score factor based on term overlap with the query virtual double coord(int32_t overlap, int32_t maxOverlap) = 0; - - /// Calculate a scoring factor based on the data in the payload. Overriding implementations are responsible + + /// Calculate a scoring factor based on the data in the payload. Overriding implementations are responsible /// for interpreting what is in the payload. Lucene makes no assumptions about what is in the byte array. /// /// The default implementation returns 1. /// - /// @param docId The docId currently being scored. If this value is {@link #NO_DOC_ID_PROVIDED}, then it + /// @param docId The docId currently being scored. If this value is {@link #NO_DOC_ID_PROVIDED}, then it /// should be assumed that the PayloadQuery implementation does not provide document information - /// @param fieldName The fieldName of the term this payload belongs to + /// @param fieldName The fieldName of the term this payload belongs to /// @param start The start position of the payload /// @param end The end position of the payload /// @param payload The payload byte array to be scored diff --git a/include/SimilarityDelegator.h b/include/SimilarityDelegator.h index a5e6f51d..72b4e5d2 100644 --- a/include/SimilarityDelegator.h +++ b/include/SimilarityDelegator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,19 +11,19 @@ namespace Lucene { - /// Delegating scoring implementation. Useful in {@link Query#getSimilarity(Searcher)} implementations, + /// Delegating scoring implementation. Useful in {@link Query#getSimilarity(Searcher)} implementations, /// to override only certain methods of a Searcher's Similarity implementation. class LPPAPI SimilarityDelegator : public Similarity { public: SimilarityDelegator(SimilarityPtr delegee); virtual ~SimilarityDelegator(); - + LUCENE_CLASS(SimilarityDelegator); - + protected: SimilarityPtr delegee; - + public: virtual double computeNorm(const String& field, FieldInvertStatePtr state); virtual double lengthNorm(const String& fieldName, int32_t numTokens); diff --git a/include/SimpleAnalyzer.h b/include/SimpleAnalyzer.h index 46ad2eec..14e7db83 100644 --- a/include/SimpleAnalyzer.h +++ b/include/SimpleAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene { public: virtual ~SimpleAnalyzer(); - + LUCENE_CLASS(SimpleAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); diff --git a/include/SimpleFSDirectory.h b/include/SimpleFSDirectory.h index ac224555..d81a06c9 100644 --- a/include/SimpleFSDirectory.h +++ b/include/SimpleFSDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,16 +20,16 @@ namespace Lucene /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) SimpleFSDirectory(const String& path, LockFactoryPtr lockFactory = LockFactoryPtr()); virtual ~SimpleFSDirectory(); - + LUCENE_CLASS(SimpleFSDirectory); - + public: /// Creates an IndexOutput for the file with the given name. virtual IndexOutputPtr createOutput(const String& name); - + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory implementation may ignore the buffer size. virtual IndexInputPtr openInput(const String& name); - + /// Creates an IndexInput for the file with the given name. virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); }; diff --git a/include/SimpleFSLockFactory.h b/include/SimpleFSLockFactory.h index aa0b9799..a5f215e8 100644 --- a/include/SimpleFSLockFactory.h +++ b/include/SimpleFSLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,23 +17,23 @@ namespace Lucene class LPPAPI SimpleFSLockFactory : public FSLockFactory { public: - /// Create a SimpleFSLockFactory instance, with null (unset) lock directory. When you pass this factory - /// to a {@link FSDirectory} subclass, the lock directory is automatically set to the directory itself. + /// Create a SimpleFSLockFactory instance, with null (unset) lock directory. When you pass this factory + /// to a {@link FSDirectory} subclass, the lock directory is automatically set to the directory itself. /// Be sure to create one instance for each directory your create! SimpleFSLockFactory(); - + /// Instantiate using the provided directory name. /// @param lockDir where lock files should be created. SimpleFSLockFactory(const String& lockDir); - + virtual ~SimpleFSLockFactory(); - + LUCENE_CLASS(SimpleFSLockFactory); - + public: /// Return a new Lock instance identified by lockName. virtual LockPtr makeLock(const String& lockName); - + /// Attempt to clear (forcefully unlock and remove) the specified lock. virtual void clearLock(const String& lockName); }; diff --git a/include/SimpleLRUCache.h b/include/SimpleLRUCache.h index 33ff4d0e..f077184d 100644 --- a/include/SimpleLRUCache.h +++ b/include/SimpleLRUCache.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/include/SingleInstanceLockFactory.h b/include/SingleInstanceLockFactory.h index 0eb1ed92..00a61fd6 100644 --- a/include/SingleInstanceLockFactory.h +++ b/include/SingleInstanceLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,10 +11,10 @@ namespace Lucene { - /// Implements {@link LockFactory} for a single in-process instance, meaning all - /// locking will take place through this one instance. Only use this {@link LockFactory} + /// Implements {@link LockFactory} for a single in-process instance, meaning all + /// locking will take place through this one instance. Only use this {@link LockFactory} /// when you are certain all IndexReaders and IndexWriters for a given index are running - /// against a single shared in-process Directory instance. This is currently the + /// against a single shared in-process Directory instance. This is currently the /// default locking for RAMDirectory. /// @see LockFactory class LPPAPI SingleInstanceLockFactory : public LockFactory @@ -22,17 +22,17 @@ namespace Lucene public: SingleInstanceLockFactory(); virtual ~SingleInstanceLockFactory(); - + LUCENE_CLASS(SingleInstanceLockFactory); protected: HashSet locks; - + public: /// Return a new Lock instance identified by lockName. /// @param lockName name of the lock to be created. virtual LockPtr makeLock(const String& lockName); - + /// Attempt to clear (forcefully unlock and remove) the /// specified lock. Only call this at a time when you are /// certain this lock is no longer in use. diff --git a/include/SingleTermEnum.h b/include/SingleTermEnum.h index ba366de5..055fe583 100644 --- a/include/SingleTermEnum.h +++ b/include/SingleTermEnum.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,23 +13,23 @@ namespace Lucene { /// Subclass of FilteredTermEnum for enumerating a single term. /// - /// This can be used by {@link MultiTermQuery}s that need only visit one term, but want to preserve + /// This can be used by {@link MultiTermQuery}s that need only visit one term, but want to preserve /// MultiTermQuery semantics such as {@link MultiTermQuery#rewriteMethod}. class LPPAPI SingleTermEnum : public FilteredTermEnum { public: SingleTermEnum(IndexReaderPtr reader, TermPtr singleTerm); virtual ~SingleTermEnum(); - + LUCENE_CLASS(SingleTermEnum); - + protected: TermPtr singleTerm; bool _endEnum; - + public: virtual double difference(); - + protected: virtual bool endEnum(); virtual bool termCompare(TermPtr term); diff --git a/include/SloppyPhraseScorer.h b/include/SloppyPhraseScorer.h index b8cdb571..bdeaa639 100644 --- a/include/SloppyPhraseScorer.h +++ b/include/SloppyPhraseScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,35 +16,35 @@ namespace Lucene public: SloppyPhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, int32_t slop, ByteArray norms); virtual ~SloppyPhraseScorer(); - + LUCENE_CLASS(SloppyPhraseScorer); - + protected: int32_t slop; Collection repeats; Collection tmpPos; // for flipping repeating pps bool checkedRepeats; - + public: - /// Score a candidate doc for all slop-valid position-combinations (matches) encountered while - /// traversing/hopping the PhrasePositions. The score contribution of a match depends on the distance: + /// Score a candidate doc for all slop-valid position-combinations (matches) encountered while + /// traversing/hopping the PhrasePositions. The score contribution of a match depends on the distance: /// - highest score for distance=0 (exact match). /// - score gets lower as distance gets higher. - /// Example: for query "a b"~2, a document "x a b a y" can be scored twice: once for "a b" (distance=0), + /// Example: for query "a b"~2, a document "x a b a y" can be scored twice: once for "a b" (distance=0), /// and once for "b a" (distance=2). - /// Possibly not all valid combinations are encountered, because for efficiency we always propagate the - /// least PhrasePosition. This allows to base on PriorityQueue and move forward faster. - /// As result, for example, document "a b c b a" would score differently for queries "a b c"~4 and - /// "c b a"~4, although they really are equivalent. Similarly, for doc "a b c b a f g", query "c b"~2 - /// would get same score as "g f"~2, although "c b"~2 could be matched twice. We may want to fix this + /// Possibly not all valid combinations are encountered, because for efficiency we always propagate the + /// least PhrasePosition. This allows to base on PriorityQueue and move forward faster. + /// As result, for example, document "a b c b a" would score differently for queries "a b c"~4 and + /// "c b a"~4, although they really are equivalent. Similarly, for doc "a b c b a f g", query "c b"~2 + /// would get same score as "g f"~2, although "c b"~2 could be matched twice. We may want to fix this /// in the future (currently not, for performance reasons). virtual double phraseFreq(); - + protected: /// Flip pp2 and pp in the queue: pop until finding pp2, insert back all but pp2, insert pp back. /// Assumes: pp!=pp2, pp2 in pq, pp not in pq. Called only when there are repeating pps. PhrasePositionsPtr flip(PhrasePositionsPtr pp, PhrasePositionsPtr pp2); - + /// Init PhrasePositions in place. /// There is a one time initialization for this scorer: /// - Put in repeats[] each pp that has another pp with same position in the doc. @@ -54,13 +54,13 @@ namespace Lucene /// - Example 1 - query with no repetitions: "ho my"~2 /// - Example 2 - query with repetitions: "ho my my"~2 /// - Example 3 - query with repetitions: "my ho my"~2 - /// Init per doc with repeats in query, includes propagating some repeating pp's to avoid false phrase detection. - /// @return end (max position), or -1 if any term ran out (ie. done) + /// Init per doc with repeats in query, includes propagating some repeating pp's to avoid false phrase detection. + /// @return end (max position), or -1 if any term ran out (ie. done) int32_t initPhrasePositions(); - - /// We disallow two pp's to have the same TermPosition, thereby verifying multiple occurrences in the query + + /// We disallow two pp's to have the same TermPosition, thereby verifying multiple occurrences in the query /// of the same word would go elsewhere in the matched doc. - /// @return null if differ (i.e. valid) otherwise return the higher offset PhrasePositions out of the first + /// @return null if differ (i.e. valid) otherwise return the higher offset PhrasePositions out of the first /// two PPs found to not differ. PhrasePositionsPtr termPositionsDiffer(PhrasePositionsPtr pp); }; diff --git a/include/SmallDouble.h b/include/SmallDouble.h index 5956f8e6..de6d1ad1 100644 --- a/include/SmallDouble.h +++ b/include/SmallDouble.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,16 +15,16 @@ namespace Lucene class SmallDouble : public LuceneObject { public: - virtual ~SmallDouble(); + virtual ~SmallDouble(); LUCENE_CLASS(SmallDouble); - + public: /// Converts a floating point number to an 8 bit float. /// Values less than zero are all mapped to zero. /// Values are truncated (rounded down) to the nearest 8 bit value. /// Values between zero and the smallest representable value are rounded up. static uint8_t doubleToByte(double f); - + /// Converts an 8 bit floating point number to a double. static double byteToDouble(uint8_t b); }; diff --git a/include/SnapshotDeletionPolicy.h b/include/SnapshotDeletionPolicy.h index 35030dbe..b99b1f6d 100644 --- a/include/SnapshotDeletionPolicy.h +++ b/include/SnapshotDeletionPolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,36 +16,36 @@ namespace Lucene public: SnapshotDeletionPolicy(IndexDeletionPolicyPtr primary); virtual ~SnapshotDeletionPolicy(); - + LUCENE_CLASS(SnapshotDeletionPolicy); - + protected: IndexCommitPtr lastCommit; IndexDeletionPolicyPtr primary; String _snapshot; - + public: /// This is called once when a writer is first instantiated to give the policy a chance to remove old /// commit points. virtual void onInit(Collection commits); - - /// This is called each time the writer completed a commit. This gives the policy a chance to remove + + /// This is called each time the writer completed a commit. This gives the policy a chance to remove /// old commit points with each commit. virtual void onCommit(Collection commits); - + /// Take a snapshot of the most recent commit to the index. You must call release() to free this snapshot. /// Note that while the snapshot is held, the files it references will not be deleted, which will consume /// additional disk space in your index. If you take a snapshot at a particularly bad time (say just before - /// you call optimize()) then in the worst case this could consume an extra 1X of your total index size, + /// you call optimize()) then in the worst case this could consume an extra 1X of your total index size, /// until you release the snapshot. virtual IndexCommitPtr snapshot(); - + /// Release the currently held snapshot. virtual void release(); - + protected: Collection wrapCommits(Collection commits); - + friend class MyCommitPoint; }; } diff --git a/include/Sort.h b/include/Sort.h index b4e3bc23..55bfa807 100644 --- a/include/Sort.h +++ b/include/Sort.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,9 +13,9 @@ namespace Lucene { /// Encapsulates sort criteria for returned hits. /// - /// The fields used to determine sort order must be carefully chosen. Documents must contain a single term - /// in such a field, and the value of the term should indicate the document's relative position in a given - /// sort order. The field must be indexed, but should not be tokenized, and does not need to be stored + /// The fields used to determine sort order must be carefully chosen. Documents must contain a single term + /// in such a field, and the value of the term should indicate the document's relative position in a given + /// sort order. The field must be indexed, but should not be tokenized, and does not need to be stored /// (unless you happen to want it back with the rest of your document data). In other words: /// ///
    @@ -24,25 +24,25 @@ namespace Lucene
         ///
         /// Valid Types of Values
         ///
    -    /// There are four possible kinds of term values which may be put into sorting fields: Integers, Longs, Doubles, 
    -    /// or Strings.  Unless {@link SortField SortField} objects are specified, the type of value in the field is 
    +    /// There are four possible kinds of term values which may be put into sorting fields: Integers, Longs, Doubles,
    +    /// or Strings.  Unless {@link SortField SortField} objects are specified, the type of value in the field is
         /// determined by parsing the first term in the field.
         ///
    -    /// Integer term values should contain only digits and an optional preceding negative sign.  Values must be base 
    -    /// 10 and in the range INT_MIN and INT_MAX inclusive.  Documents which should appear first in the sort should 
    -    /// have low value integers, later documents high values (ie. the documents should be numbered 1..n where 1 is 
    +    /// Integer term values should contain only digits and an optional preceding negative sign.  Values must be base
    +    /// 10 and in the range INT_MIN and INT_MAX inclusive.  Documents which should appear first in the sort should
    +    /// have low value integers, later documents high values (ie. the documents should be numbered 1..n where 1 is
         /// the first and n the last).
         ///
    -    /// Long term values should contain only digits and an optional preceding negative sign.  Values must be base 10 
    -    /// and in the range LLONG_MIN and LLONG_MAX inclusive.  Documents which should appear first in the sort should 
    +    /// Long term values should contain only digits and an optional preceding negative sign.  Values must be base 10
    +    /// and in the range LLONG_MIN and LLONG_MAX inclusive.  Documents which should appear first in the sort should
         /// have low value integers, later documents high values.
         ///
         /// Double term values should conform to values accepted by Double (except that NaN and Infinity are not
    -    /// supported).  Documents which should appear first in the sort should have low values, later documents high 
    +    /// supported).  Documents which should appear first in the sort should have low values, later documents high
         /// values.
         ///
    -    /// String term values can contain any valid String, but should not be tokenized.  The values are sorted according 
    -    /// to their comparable natural order.  Note that using this type of term value has higher memory requirements 
    +    /// String term values can contain any valid String, but should not be tokenized.  The values are sorted according
    +    /// to their comparable natural order.  Note that using this type of term value has higher memory requirements
         /// than the other two types.
         ///
         /// Object Reuse
    @@ -52,60 +52,60 @@ namespace Lucene
         ///
         /// Memory Usage
         ///
    -    /// Sorting uses of caches of term values maintained by the internal HitQueue(s).  The cache is static and 
    -    /// contains an integer or double array of length IndexReader::maxDoc() for each field name for which a sort is 
    +    /// Sorting uses of caches of term values maintained by the internal HitQueue(s).  The cache is static and
    +    /// contains an integer or double array of length IndexReader::maxDoc() for each field name for which a sort is
         /// performed.  In other words, the size of the cache in bytes is:
         ///
         /// 
         /// 4 * IndexReader::maxDoc() * (# of different fields actually used to sort)
         /// 
    /// - /// For String fields, the cache is larger: in addition to the above array, the value of every term in the + /// For String fields, the cache is larger: in addition to the above array, the value of every term in the /// field is kept in memory. If there are many unique terms in the field, this could be quite large. /// - /// Note that the size of the cache is not affected by how many fields are in the index and might be used to + /// Note that the size of the cache is not affected by how many fields are in the index and might be used to /// sort - only by the ones actually used to sort a result set. class LPPAPI Sort : public LuceneObject { public: - /// Sorts by computed relevance. This is the same sort criteria as calling {@link - /// Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly more + /// Sorts by computed relevance. This is the same sort criteria as calling {@link + /// Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly more /// overhead. Sort(); - + /// Sorts by the criteria in the given SortField. Sort(SortFieldPtr field); - + /// Sorts in succession by the criteria in each SortField. Sort(Collection fields); - + virtual ~Sort(); - + LUCENE_CLASS(Sort); - + public: /// Internal representation of the sort criteria Collection fields; - + public: /// Represents sorting by computed relevance. Using this sort criteria returns the same results as calling - /// {@link Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly + /// {@link Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly /// more overhead. static SortPtr RELEVANCE(); - + /// Represents sorting by index order. static SortPtr INDEXORDER(); - + /// Sets the sort to the given criteria. void setSort(SortFieldPtr field); - + /// Sets the sort to the given criteria in succession. void setSort(Collection fields); - + /// Representation of the sort criteria. /// @return Array of SortField objects used in this sort criteria Collection getSort(); - + virtual String toString(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); diff --git a/include/SortField.h b/include/SortField.h index c63bb97d..15c212dc 100644 --- a/include/SortField.h +++ b/include/SortField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// Stores information about how to sort documents by terms in an individual field. Fields must be indexed + /// Stores information about how to sort documents by terms in an individual field. Fields must be indexed /// in order to sort by them. class LPPAPI SortField : public LuceneObject { @@ -21,124 +21,124 @@ namespace Lucene /// @param type Type of values in the terms. /// @param reverse True if natural order should be reversed. SortField(const String& field, int32_t type, bool reverse = false); - - /// Creates a sort, possibly in reverse, by terms in the given field, parsed to numeric values using a + + /// Creates a sort, possibly in reverse, by terms in the given field, parsed to numeric values using a /// custom {@link Parser}. /// @param field Name of field to sort by - /// @param parser Instance of a {@link Parser}, which must subclass one of the existing numeric parsers from + /// @param parser Instance of a {@link Parser}, which must subclass one of the existing numeric parsers from /// {@link FieldCache}. Sort type is inferred by testing which numeric parser the parser subclasses. /// @param reverse True if natural order should be reversed. SortField(const String& field, ParserPtr parser, bool reverse = false); - + /// Creates a sort, possibly in reverse, by terms in the given field sorted according to the given locale. /// @param field Name of field to sort by, cannot be null. /// @param locale Locale of values in the field. /// @param reverse True if natural order should be reversed. SortField(const String& field, const std::locale& locale, bool reverse = false); - + /// Creates a sort, possibly in reverse, with a custom comparison function. /// @param field Name of field to sort by; cannot be null. /// @param comparator Returns a comparator for sorting hits. /// @param reverse True if natural order should be reversed. SortField(const String& field, FieldComparatorSourcePtr comparator, bool reverse = false); - + virtual ~SortField(); - + LUCENE_CLASS(SortField); - + public: /// Sort by document score (relevancy). Sort values are Double and higher values are at the front. static const int32_t SCORE; - + /// Sort by document number (index order). Sort values are Integer and lower values are at the front. static const int32_t DOC; - + /// Sort using term values as Strings. Sort values are String and lower values are at the front. static const int32_t STRING; - + /// Sort using term values as Integers. Sort values are Integer and lower values are at the front. static const int32_t INT; - + /// Sort using term values as Floats. Sort values are Float and lower values are at the front. static const int32_t FLOAT; - + /// Sort using term values as Longs. Sort values are Long and lower values are at the front. static const int32_t LONG; - + /// Sort using term values as Doubles. Sort values are Double and lower values are at the front. static const int32_t DOUBLE; - + /// Sort using term values as Shorts. Sort values are Short and lower values are at the front. static const int32_t SHORT; - - /// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according + + /// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according /// to natural order. static const int32_t CUSTOM; - + /// Sort using term values as Bytes. Sort values are Byte and lower values are at the front. static const int32_t BYTE; - + /// Sort using term values as Strings, but comparing by value (using String::compare) for all comparisons. /// This is typically slower than {@link #STRING}, which uses ordinals to do the sorting. static const int32_t STRING_VAL; - + INTERNAL: bool reverse; // defaults to natural order - + String field; int32_t type; // defaults to determining type dynamically localePtr locale; // defaults to "natural order" (no Locale) ParserPtr parser; - + private: /// Used for CUSTOM sort FieldComparatorSourcePtr comparatorSource; - + public: /// Represents sorting by document score (relevancy). static SortFieldPtr FIELD_SCORE(); - + /// Represents sorting by document number (index order). static SortFieldPtr FIELD_DOC(); - + /// Returns the name of the field. Could return null if the sort is by SCORE or DOC. /// @return Name of field, possibly null. String getField(); - + /// Returns the type of contents in the field. /// @return One of the constants SCORE, DOC, STRING, INT or DOUBLE. int32_t getType(); - + /// Returns the Locale by which term values are interpreted. localePtr getLocale(); - - /// Returns the instance of a {@link FieldCache} parser that fits to the given sort type. May return null + + /// Returns the instance of a {@link FieldCache} parser that fits to the given sort type. May return null /// if no parser was specified. Sorting is using the default parser then. /// @return An instance of a parser, or null. ParserPtr getParser(); - + /// Returns whether the sort should be reversed. /// @return True if natural order should be reversed. bool getReverse(); - + /// Returns the {@link FieldComparatorSource} used for custom sorting FieldComparatorSourcePtr getComparatorSource(); - + virtual String toString(); - - /// Returns true if other is equal to this. If a {@link FieldComparatorSource} or {@link Parser} was provided, + + /// Returns true if other is equal to this. If a {@link FieldComparatorSource} or {@link Parser} was provided, /// it must properly implement equals (unless a singleton is always used). virtual bool equals(LuceneObjectPtr other); - + virtual int32_t hashCode(); - + /// Returns the {@link FieldComparator} to use for sorting. /// @param numHits number of top hits the queue will store /// @param sortPos position of this SortField within {@link Sort}. The comparator is primary if sortPos == 0, /// secondary if sortPos == 1, etc. Some comparators can optimize themselves when they are the primary sort. /// @return {@link FieldComparator} to use when sorting FieldComparatorPtr getComparator(int32_t numHits, int32_t sortPos); - + protected: /// Sets field and type, and ensures field is not NULL unless type is SCORE or DOC void initFieldType(const String& field, int32_t type); diff --git a/include/SortedTermVectorMapper.h b/include/SortedTermVectorMapper.h index 9ade70d9..66f7fb83 100644 --- a/include/SortedTermVectorMapper.h +++ b/include/SortedTermVectorMapper.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// Store a sorted collection of {@link TermVectorEntry}s. Collects all term information into a single, + /// Store a sorted collection of {@link TermVectorEntry}s. Collects all term information into a single, /// sorted set. /// /// NOTE: This Mapper ignores all Field information for the Document. This means that if you are using offset/ @@ -24,31 +24,31 @@ namespace Lucene public: /// @param comparator A Comparator for sorting {@link TermVectorEntry}s SortedTermVectorMapper(TermVectorEntryComparator comparator); - + SortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator); - + virtual ~SortedTermVectorMapper(); - + LUCENE_CLASS(SortedTermVectorMapper); - + protected: Collection currentSet; MapStringTermVectorEntry termToTVE; bool storeOffsets; bool storePositions; TermVectorEntryComparator comparator; - + public: static const wchar_t* ALL; - + public: /// Map the Term Vector information into your own structure virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); - + /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); - - /// The TermVectorEntrySet. A SortedSet of {@link TermVectorEntry} objects. Sort is by the comparator passed + + /// The TermVectorEntrySet. A SortedSet of {@link TermVectorEntry} objects. Sort is by the comparator passed /// into the constructor. /// /// This set will be empty until after the mapping process takes place. diff --git a/include/SortedVIntList.h b/include/SortedVIntList.h index 2aff6bac..1f8cb8b5 100644 --- a/include/SortedVIntList.h +++ b/include/SortedVIntList.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,11 +13,11 @@ namespace Lucene { /// Stores and iterate on sorted integers in compressed form in RAM. /// - /// The code for compressing the differences between ascending integers was borrowed from {@link IndexInput} + /// The code for compressing the differences between ascending integers was borrowed from {@link IndexInput} /// and {@link IndexOutput}. /// - /// NOTE: this class assumes the stored integers are doc Ids (hence why it extends {@link DocIdSet}). Therefore - /// its {@link #iterator()} assumes {@link DocIdSetIterator#NO_MORE_DOCS} can be used as sentinel. If you + /// NOTE: this class assumes the stored integers are doc Ids (hence why it extends {@link DocIdSet}). Therefore + /// its {@link #iterator()} assumes {@link DocIdSetIterator#NO_MORE_DOCS} can be used as sentinel. If you /// intend to use this value, then make sure it's not used during search flow. class LPPAPI SortedVIntList : public DocIdSet { @@ -25,62 +25,62 @@ namespace Lucene /// Create a SortedVIntList from all elements of an array of integers. /// @param sortedInts A sorted array of non negative integers. SortedVIntList(Collection sortedInts); - + /// Create a SortedVIntList from an array of integers. /// @param sortedInts A sorted array of non negative integers. /// @param inputSize The number of integers to be used from the array. SortedVIntList(Collection sortedInts, int32_t inputSize); - + /// Create a SortedVIntList from a BitSet. /// @param bits A bit set representing a set of integers. SortedVIntList(BitSetPtr bits); - + /// Create a SortedVIntList from an OpenBitSet. /// @param bits A bit set representing a set of integers. SortedVIntList(OpenBitSetPtr bits); - + /// Create a SortedVIntList. /// @param docIdSetIterator An iterator providing document numbers as a set of integers. - /// This DocIdSetIterator is iterated completely when this constructor is called and it must provide the + /// This DocIdSetIterator is iterated completely when this constructor is called and it must provide the /// integers in non decreasing order. SortedVIntList(DocIdSetIteratorPtr docIdSetIterator); - + virtual ~SortedVIntList(); - + LUCENE_CLASS(SortedVIntList); - + public: - /// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the + /// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the /// index numbers of the set bits will be smaller than that BitSet. static const int32_t BITS2VINTLIST_SIZE; - + protected: static const int32_t VB1; static const int32_t BIT_SHIFT; static const int32_t MAX_BYTES_PER_INT; - + int32_t _size; ByteArray bytes; int32_t lastBytePos; int32_t lastInt; - + public: /// @return The total number of sorted integers. int32_t size(); - + /// @return The size of the byte array storing the compressed sorted integers. int32_t getByteSize(); - + /// This DocIdSet implementation is cacheable. virtual bool isCacheable(); - + /// @return An iterator over the sorted integers. virtual DocIdSetIteratorPtr iterator(); - + protected: void initBytes(); void addInt(int32_t nextInt); - + friend class SortedDocIdSetIterator; }; } diff --git a/include/SpanFilter.h b/include/SpanFilter.h index d05236e1..326c17fe 100644 --- a/include/SpanFilter.h +++ b/include/SpanFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,21 +11,21 @@ namespace Lucene { - /// Abstract base class providing a mechanism to restrict searches to a subset of an index and also maintains + /// Abstract base class providing a mechanism to restrict searches to a subset of an index and also maintains /// and returns position information. /// /// This is useful if you want to compare the positions from a SpanQuery with the positions of items in a filter. - /// For instance, if you had a SpanFilter that marked all the occurrences of the word "foo" in documents, and - /// then you entered a new SpanQuery containing bar, you could not only filter by the word foo, but you could + /// For instance, if you had a SpanFilter that marked all the occurrences of the word "foo" in documents, and + /// then you entered a new SpanQuery containing bar, you could not only filter by the word foo, but you could /// then compare position information for post processing. class LPPAPI SpanFilter : public Filter { public: virtual ~SpanFilter(); LUCENE_CLASS(SpanFilter); - + public: - /// Returns a SpanFilterResult with true for documents which should be permitted in search results, and + /// Returns a SpanFilterResult with true for documents which should be permitted in search results, and /// false for those that should not and Spans for where the true docs match. /// @param reader The {@link IndexReader} to load position and DocIdSet information from /// @return A {@link SpanFilterResult} diff --git a/include/SpanFilterResult.h b/include/SpanFilterResult.h index c42ef9d3..9ff5b5de 100644 --- a/include/SpanFilterResult.h +++ b/include/SpanFilterResult.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,59 +18,59 @@ namespace Lucene /// @param docIdSet The DocIdSet for the Filter /// @param positions A List of {@link PositionInfo} objects SpanFilterResult(DocIdSetPtr docIdSet, Collection positions); - + virtual ~SpanFilterResult(); - + LUCENE_CLASS(SpanFilterResult); - + protected: DocIdSetPtr docIdSet; Collection positions; // Spans spans - + public: - /// The first entry in the array corresponds to the first "on" bit. Entries are increasing by + /// The first entry in the array corresponds to the first "on" bit. Entries are increasing by /// document order. /// @return A List of PositionInfo objects Collection getPositions(); - + /// Returns the docIdSet DocIdSetPtr getDocIdSet(); }; - + class LPPAPI PositionInfo : public LuceneObject { public: PositionInfo(int32_t doc); virtual ~PositionInfo(); - + LUCENE_CLASS(PositionInfo); - + protected: int32_t doc; Collection positions; - + public: void addPosition(int32_t start, int32_t end); int32_t getDoc(); Collection getPositions(); }; - + class LPPAPI StartEnd : public LuceneObject { public: StartEnd(int32_t start, int32_t end); virtual ~StartEnd(); - + LUCENE_CLASS(StartEnd); - + protected: int32_t start; int32_t end; - + public: /// @return The end position of this match int32_t getEnd(); - + /// @return The start position of this match int32_t getStart(); }; diff --git a/include/SpanFirstQuery.h b/include/SpanFirstQuery.h index 02f2cfd9..860a21cd 100644 --- a/include/SpanFirstQuery.h +++ b/include/SpanFirstQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,32 +19,32 @@ namespace Lucene /// Construct a SpanFirstQuery matching spans in match whose end position is less than or equal to end. SpanFirstQuery(SpanQueryPtr match, int32_t end); virtual ~SpanFirstQuery(); - + LUCENE_CLASS(SpanFirstQuery); - + protected: SpanQueryPtr match; int32_t end; - + public: using SpanQuery::toString; - + /// Return the SpanQuery whose matches are filtered. SpanQueryPtr getMatch(); - + /// Return the maximum end position permitted in a match. int32_t getEnd(); - + virtual String getField(); virtual String toString(const String& field); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual void extractTerms(SetTerm terms); virtual SpansPtr getSpans(IndexReaderPtr reader); virtual QueryPtr rewrite(IndexReaderPtr reader); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + friend class FirstSpans; }; } diff --git a/include/SpanNearQuery.h b/include/SpanNearQuery.h index bc4810f5..8b5d17c2 100644 --- a/include/SpanNearQuery.h +++ b/include/SpanNearQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,39 +11,39 @@ namespace Lucene { - /// Matches spans which are near one another. One can specify slop, the maximum number of intervening + /// Matches spans which are near one another. One can specify slop, the maximum number of intervening /// unmatched positions, as well as whether matches are required to be in-order. class LPPAPI SpanNearQuery : public SpanQuery { public: - /// Construct a SpanNearQuery. Matches spans matching a span from each clause, with up to slop total - /// unmatched positions between them. * When inOrder is true, the spans from each clause must be + /// Construct a SpanNearQuery. Matches spans matching a span from each clause, with up to slop total + /// unmatched positions between them. * When inOrder is true, the spans from each clause must be /// ordered as in clauses. SpanNearQuery(Collection clauses, int32_t slop, bool inOrder, bool collectPayloads = true); virtual ~SpanNearQuery(); - + LUCENE_CLASS(SpanNearQuery); - + protected: Collection clauses; int32_t slop; bool inOrder; - + String field; bool collectPayloads; - + public: using SpanQuery::toString; - + /// Return the clauses whose spans are matched. Collection getClauses(); - + /// Return the maximum number of intervening unmatched positions permitted. int32_t getSlop(); - + /// Return true if matches are required to be in-order. bool isInOrder(); - + virtual String getField(); virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); diff --git a/include/SpanNotQuery.h b/include/SpanNotQuery.h index cb7ef203..d133d87d 100644 --- a/include/SpanNotQuery.h +++ b/include/SpanNotQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,29 +18,29 @@ namespace Lucene /// Construct a SpanNotQuery matching spans from include which have no overlap with spans from exclude. SpanNotQuery(SpanQueryPtr include, SpanQueryPtr exclude); virtual ~SpanNotQuery(); - + LUCENE_CLASS(SpanNotQuery); - + protected: SpanQueryPtr include; SpanQueryPtr exclude; - + public: using SpanQuery::toString; - + /// Return the SpanQuery whose matches are filtered. SpanQueryPtr getInclude(); - + /// Return the SpanQuery whose matches must not overlap those returned. SpanQueryPtr getExclude(); - + virtual String getField(); virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual SpansPtr getSpans(IndexReaderPtr reader); virtual QueryPtr rewrite(IndexReaderPtr reader); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); }; diff --git a/include/SpanOrQuery.h b/include/SpanOrQuery.h index 178f5be1..492d207a 100644 --- a/include/SpanOrQuery.h +++ b/include/SpanOrQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,28 +18,28 @@ namespace Lucene /// Construct a SpanOrQuery merging the provided clauses. SpanOrQuery(Collection clauses); virtual ~SpanOrQuery(); - + LUCENE_CLASS(SpanOrQuery); - + protected: Collection clauses; String field; - + public: using SpanQuery::toString; - + /// Return the clauses whose spans are matched. Collection getClauses(); - + virtual String getField(); virtual void extractTerms(SetTerm terms); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual QueryPtr rewrite(IndexReaderPtr reader); virtual String toString(const String& field); virtual bool equals(LuceneObjectPtr other); - virtual int32_t hashCode(); + virtual int32_t hashCode(); virtual SpansPtr getSpans(IndexReaderPtr reader); - + friend class OrSpans; }; } diff --git a/include/SpanQuery.h b/include/SpanQuery.h index 4106d37b..8ffb8c89 100644 --- a/include/SpanQuery.h +++ b/include/SpanQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,14 +17,14 @@ namespace Lucene public: virtual ~SpanQuery(); LUCENE_CLASS(SpanQuery); - + public: /// Returns the matches for this query in an index. Used internally to search for spans. virtual SpansPtr getSpans(IndexReaderPtr reader) = 0; - + /// Returns the name of the field matched by this query. virtual String getField() = 0; - + virtual WeightPtr createWeight(SearcherPtr searcher); }; } diff --git a/include/SpanQueryFilter.h b/include/SpanQueryFilter.h index aee8a45d..37e5663e 100644 --- a/include/SpanQueryFilter.h +++ b/include/SpanQueryFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,9 +11,9 @@ namespace Lucene { - /// Constrains search results to only match those which also match a provided query. Also provides position - /// information about where each document matches at the cost of extra space compared with the - /// QueryWrapperFilter. There is an added cost to this above what is stored in a {@link QueryWrapperFilter}. + /// Constrains search results to only match those which also match a provided query. Also provides position + /// information about where each document matches at the cost of extra space compared with the + /// QueryWrapperFilter. There is an added cost to this above what is stored in a {@link QueryWrapperFilter}. /// Namely, the position information for each matching document is stored. /// /// This filter does not cache. See the {@link CachingSpanFilter} for a wrapper that caches. @@ -23,20 +23,20 @@ namespace Lucene /// Constructs a filter which only matches documents matching query. /// @param query The {@link SpanQuery} to use as the basis for the Filter. SpanQueryFilter(SpanQueryPtr query = SpanQueryPtr()); - + virtual ~SpanQueryFilter(); - + LUCENE_CLASS(SpanQueryFilter); - + protected: SpanQueryPtr query; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); virtual SpanFilterResultPtr bitSpans(IndexReaderPtr reader); - + SpanQueryPtr getQuery(); - + virtual String toString(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); diff --git a/include/SpanScorer.h b/include/SpanScorer.h index f0269aff..7fcc7b3f 100644 --- a/include/SpanScorer.h +++ b/include/SpanScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene public: SpanScorer(SpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms); virtual ~SpanScorer(); - + LUCENE_CLASS(SpanScorer); - + protected: SpansPtr spans; WeightPtr weight; @@ -28,20 +28,20 @@ namespace Lucene bool more; int32_t doc; double freq; - + public: virtual int32_t nextDoc(); virtual int32_t advance(int32_t target); virtual int32_t docID(); virtual double score(); - + protected: virtual bool setFreqCurrentDoc(); - - /// This method is no longer an official member of {@link Scorer}, but it is needed by SpanWeight + + /// This method is no longer an official member of {@link Scorer}, but it is needed by SpanWeight /// to build an explanation. virtual ExplanationPtr explain(int32_t doc); - + friend class SpanWeight; friend class PayloadNearSpanWeight; }; diff --git a/include/SpanTermQuery.h b/include/SpanTermQuery.h index cb8a2afc..16f08e66 100644 --- a/include/SpanTermQuery.h +++ b/include/SpanTermQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,18 +18,18 @@ namespace Lucene /// Construct a SpanTermQuery matching the named term's spans. SpanTermQuery(TermPtr term); virtual ~SpanTermQuery(); - + LUCENE_CLASS(SpanTermQuery); - + protected: TermPtr term; - + public: using SpanQuery::toString; - + /// Return the term whose spans are matched. TermPtr getTerm(); - + virtual String getField(); virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); diff --git a/include/SpanWeight.h b/include/SpanWeight.h index 58496930..ae1ee955 100644 --- a/include/SpanWeight.h +++ b/include/SpanWeight.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,20 +17,20 @@ namespace Lucene public: SpanWeight(SpanQueryPtr query, SearcherPtr searcher); virtual ~SpanWeight(); - + LUCENE_CLASS(SpanWeight); - + protected: SimilarityPtr similarity; double value; double idf; double queryNorm; double queryWeight; - + SetTerm terms; SpanQueryPtr query; IDFExplanationPtr idfExp; - + public: virtual QueryPtr getQuery(); virtual double getValue(); @@ -38,7 +38,7 @@ namespace Lucene virtual void normalize(double norm); virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); - + friend class PayloadNearSpanScorer; friend class PayloadTermSpanScorer; }; diff --git a/include/Spans.h b/include/Spans.h index 9a4794b8..ed266e1d 100644 --- a/include/Spans.h +++ b/include/Spans.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// An enumeration of span matches. Used to implement span searching. Each span represents a range of term + /// An enumeration of span matches. Used to implement span searching. Each span represents a range of term /// positions within a document. Matches are enumerated in order, by increasing document number, within that /// by increasing start position and finally by increasing end position. class LPPAPI Spans : public LuceneObject @@ -19,16 +19,16 @@ namespace Lucene public: virtual ~Spans(); LUCENE_CLASS(Spans); - + public: /// Move to the next match, returning true if any such exists. virtual bool next() = 0; - + /// Skips to the first match beyond the current, whose document number is greater than or equal to target. /// /// Returns true if there is such a match. /// - /// Behaves as if written: + /// Behaves as if written: ///
             /// bool skipTo(int32_t target)
             /// {
    @@ -43,29 +43,29 @@ namespace Lucene
             /// 
    /// Most implementations are considerably more efficient than that. virtual bool skipTo(int32_t target) = 0; - + /// Returns the document number of the current match. Initially invalid. virtual int32_t doc() = 0; - + /// Returns the start position of the current match. Initially invalid. virtual int32_t start() = 0; - + /// Returns the end position of the current match. Initially invalid. virtual int32_t end() = 0; - - /// Returns the payload data for the current span. This is invalid until {@link #next()} is called for the - /// first time. This method must not be called more than once after each call of {@link #next()}. However, - /// most payloads are loaded lazily, so if the payload data for the current position is not needed, this - /// method may not be called at all for performance reasons. An ordered SpanQuery does not lazy load, so - /// if you have payloads in your index and you do not want ordered SpanNearQuerys to collect payloads, you + + /// Returns the payload data for the current span. This is invalid until {@link #next()} is called for the + /// first time. This method must not be called more than once after each call of {@link #next()}. However, + /// most payloads are loaded lazily, so if the payload data for the current position is not needed, this + /// method may not be called at all for performance reasons. An ordered SpanQuery does not lazy load, so + /// if you have payloads in your index and you do not want ordered SpanNearQuerys to collect payloads, you /// can disable collection with a constructor option. /// /// Note that the return type is a collection, thus the ordering should not be relied upon. /// - /// @return a List of byte arrays containing the data of this payload, otherwise null if isPayloadAvailable + /// @return a List of byte arrays containing the data of this payload, otherwise null if isPayloadAvailable /// is false virtual Collection getPayload() = 0; - + /// Checks if a payload can be loaded at this position. /// /// Payloads can only be loaded once per call to {@link #next()}. diff --git a/include/StandardAnalyzer.h b/include/StandardAnalyzer.h index 8cd53c42..4d868ef2 100644 --- a/include/StandardAnalyzer.h +++ b/include/StandardAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter} and {@link StopFilter}, using + /// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter} and {@link StopFilter}, using /// a list of English stop words. /// /// You must specify the required {@link Version} compatibility when creating StandardAnalyzer: @@ -26,59 +26,59 @@ namespace Lucene /// Builds an analyzer with the default stop words ({@link #STOP_WORDS_SET}). /// @param matchVersion Lucene version to match. StandardAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. /// @param matchVersion Lucene version to match. /// @param stopWords stop words StandardAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords); - + /// Builds an analyzer with the stop words from the given file. /// @see WordlistLoader#getWordSet(const String&, const String&) /// @param matchVersion Lucene version to match. /// @param stopwords File to read stop words from. StandardAnalyzer(LuceneVersion::Version matchVersion, const String& stopwords); - + /// Builds an analyzer with the stop words from the given reader. /// @see WordlistLoader#getWordSet(ReaderPtr, const String&) /// @param matchVersion Lucene version to match. /// @param stopwords Reader to read stop words from. StandardAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords); - + virtual ~StandardAnalyzer(); - + LUCENE_CLASS(StandardAnalyzer); - + public: /// Default maximum allowed token length static const int32_t DEFAULT_MAX_TOKEN_LENGTH; - + protected: HashSet stopSet; - + /// Specifies whether deprecated acronyms should be replaced with HOST type. bool replaceInvalidAcronym; bool enableStopPositionIncrements; - + LuceneVersion::Version matchVersion; - + int32_t maxTokenLength; - + protected: /// Construct an analyzer with the given stop words. void ConstructAnalyser(LuceneVersion::Version matchVersion, HashSet stopWords); - + public: - /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter} + /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter} /// and a {@link StopFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Set maximum allowed token length. If a token is seen that exceeds this length then it is discarded. This setting + + /// Set maximum allowed token length. If a token is seen that exceeds this length then it is discarded. This setting /// only takes effect the next time tokenStream or reusableTokenStream is called. void setMaxTokenLength(int32_t length); - + /// @see #setMaxTokenLength int32_t getMaxTokenLength(); - + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; } diff --git a/include/StandardFilter.h b/include/StandardFilter.h index ab1eee4a..551bfe45 100644 --- a/include/StandardFilter.h +++ b/include/StandardFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,17 +18,17 @@ namespace Lucene /// Construct filtering input. StandardFilter(TokenStreamPtr input); virtual ~StandardFilter(); - + LUCENE_CLASS(StandardFilter); - + protected: TypeAttributePtr typeAtt; TermAttributePtr termAtt; - + protected: static const String& APOSTROPHE_TYPE(); static const String& ACRONYM_TYPE(); - + public: /// Returns the next token in the stream, or null at EOS. /// diff --git a/include/StandardTokenizer.h b/include/StandardTokenizer.h index 7f01c77b..55630219 100644 --- a/include/StandardTokenizer.h +++ b/include/StandardTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,14 +16,14 @@ namespace Lucene /// This should be a good tokenizer for most European-language documents: /// ///
      - ///
    • Splits words at punctuation characters, removing punctuation. However, a dot that's not followed by + ///
    • Splits words at punctuation characters, removing punctuation. However, a dot that's not followed by /// whitespace is considered part of a token. - ///
    • Splits words at hyphens, unless there's a number in the token, in which case the whole token is interpreted + ///
    • Splits words at hyphens, unless there's a number in the token, in which case the whole token is interpreted /// as a product number and is not split. ///
    • Recognizes email addresses and internet hostnames as one token. ///
    /// - /// Many applications have specific tokenizer needs. If this tokenizer does not suit your application, please consider + /// Many applications have specific tokenizer needs. If this tokenizer does not suit your application, please consider /// copying this source code directory to your project and maintaining your own grammar-based tokenizer. /// /// You must specify the required {@link Version} compatibility when creating StandardAnalyzer: @@ -37,30 +37,30 @@ namespace Lucene /// Creates a new instance of the {@link StandardTokenizer}. Attaches the input to the newly created scanner. /// @param input The input reader StandardTokenizer(LuceneVersion::Version matchVersion, ReaderPtr input); - + /// Creates a new StandardTokenizer with a given {@link AttributeSource}. StandardTokenizer(LuceneVersion::Version matchVersion, AttributeSourcePtr source, ReaderPtr input); - + /// Creates a new StandardTokenizer with a given {@link AttributeSource.AttributeFactory} StandardTokenizer(LuceneVersion::Version matchVersion, AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~StandardTokenizer(); - + LUCENE_CLASS(StandardTokenizer); - + protected: /// A private instance of the scanner StandardTokenizerImplPtr scanner; - + bool replaceInvalidAcronym; int32_t maxTokenLength; - + // this tokenizer generates three attributes: offset, positionIncrement and type TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; PositionIncrementAttributePtr posIncrAtt; TypeAttributePtr typeAtt; - + public: static const int32_t ALPHANUM; static const int32_t APOSTROPHE; @@ -70,34 +70,34 @@ namespace Lucene static const int32_t HOST; static const int32_t NUM; static const int32_t CJ; - + /// @deprecated this solves a bug where HOSTs that end with '.' are identified as ACRONYMs. static const int32_t ACRONYM_DEP; - + /// String token types that correspond to token type int constants static const Collection TOKEN_TYPES(); - + protected: void init(ReaderPtr input, LuceneVersion::Version matchVersion); - + public: /// Set the max allowed token length. Any token longer than this is skipped. void setMaxTokenLength(int32_t length); - + /// @see #setMaxTokenLength int32_t getMaxTokenLength(); - + /// @see TokenStream#next() virtual bool incrementToken(); - + virtual void end(); - + virtual void reset(ReaderPtr input); - + /// @return true if StandardTokenizer now returns these tokens as Hosts, otherwise false /// @deprecated Remove in 3.X and make true the only valid value bool isReplaceInvalidAcronym(); - + /// @param replaceInvalidAcronym Set to true to replace mischaracterized acronyms as HOST. /// @deprecated Remove in 3.X and make true the only valid value void setReplaceInvalidAcronym(bool replaceInvalidAcronym); diff --git a/include/StandardTokenizerImpl.h b/include/StandardTokenizerImpl.h index c418236f..564d9958 100644 --- a/include/StandardTokenizerImpl.h +++ b/include/StandardTokenizerImpl.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,136 +17,136 @@ namespace Lucene /// Creates a new scanner /// @param in the Reader to read input from. StandardTokenizerImpl(ReaderPtr in); - + virtual ~StandardTokenizerImpl(); - + LUCENE_CLASS(StandardTokenizerImpl); - + protected: /// Initial size of the lookahead buffer static const int32_t ZZ_BUFFERSIZE; - + /// Translates characters to character classes static CharArray _ZZ_CMAP; static const wchar_t ZZ_CMAP_PACKED[]; static const int32_t ZZ_CMAP_LENGTH; static const int32_t ZZ_CMAP_PACKED_LENGTH; - + /// Translates characters to character classes static void ZZ_CMAP_INIT(); static const wchar_t* ZZ_CMAP(); - + /// Translates DFA states to action switch labels. static IntArray _ZZ_ACTION; static const wchar_t ZZ_ACTION_PACKED_0[]; static const int32_t ZZ_ACTION_LENGTH; static const int32_t ZZ_ACTION_PACKED_LENGTH; - + /// Translates DFA states to action switch labels. static void ZZ_ACTION_INIT(); static const int32_t* ZZ_ACTION(); - + /// Translates a state to a row index in the transition table static IntArray _ZZ_ROWMAP; static const wchar_t ZZ_ROWMAP_PACKED_0[]; static const int32_t ZZ_ROWMAP_LENGTH; static const int32_t ZZ_ROWMAP_PACKED_LENGTH; - + /// Translates a state to a row index in the transition table static void ZZ_ROWMAP_INIT(); static const int32_t* ZZ_ROWMAP(); - + /// The transition table of the DFA static IntArray _ZZ_TRANS; static const wchar_t ZZ_TRANS_PACKED_0[]; static const int32_t ZZ_TRANS_LENGTH; static const int32_t ZZ_TRANS_PACKED_LENGTH; - + /// The transition table of the DFA static void ZZ_TRANS_INIT(); static const int32_t* ZZ_TRANS(); - + // error codes static const int32_t ZZ_UNKNOWN_ERROR; static const int32_t ZZ_NO_MATCH; static const int32_t ZZ_PUSHBACK_2BIG; - + static const wchar_t* ZZ_ERROR_MSG[]; - + /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState static IntArray _ZZ_ATTRIBUTE; static const wchar_t ZZ_ATTRIBUTE_PACKED_0[]; static const int32_t ZZ_ATTRIBUTE_LENGTH; static const int32_t ZZ_ATTRIBUTE_PACKED_LENGTH; - + /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState static void ZZ_ATTRIBUTE_INIT(); static const int32_t* ZZ_ATTRIBUTE(); - + /// The input device ReaderPtr zzReader; - + /// The current state of the DFA int32_t zzState; - + /// The current lexical state int32_t zzLexicalState; - + /// This buffer contains the current text to be matched and is the source of the yytext() string CharArray zzBuffer; - + /// The text position at the last accepting state int32_t zzMarkedPos; - + /// The text position at the last state to be included in yytext int32_t zzPushbackPos; - + /// The current text position in the buffer int32_t zzCurrentPos; - + /// StartRead marks the beginning of the yytext() string in the buffer int32_t zzStartRead; - + /// EndRead marks the last character in the buffer, that has been read from input int32_t zzEndRead; - + /// Number of newlines encountered up to the start of the matched text int32_t yyline; - + /// The number of characters up to the start of the matched text int32_t _yychar; - + /// The number of characters from the last newline up to the start of the matched text int32_t yycolumn; - + /// zzAtBOL == true if the scanner is currently at the beginning of a line bool zzAtBOL; - + /// zzAtEOF == true if the scanner is at the EOF bool zzAtEOF; - + public: /// This character denotes the end of file static const int32_t YYEOF; - + /// Lexical states static const int32_t YYINITIAL; - + public: int32_t yychar(); - + /// Resets the Tokenizer to a new Reader. void reset(ReaderPtr r); - + /// Fills Lucene token with the current token text. void getText(TokenPtr t); - + /// Fills TermAttribute with the current token text. void getText(TermAttributePtr t); - + /// Closes the input stream. void yyclose(); - + /// Resets the scanner to read from a new input stream. Does not close the old reader. /// /// All internal variables are reset, the old input stream cannot be reused (internal buffer is discarded and lost). @@ -154,45 +154,45 @@ namespace Lucene /// /// @param reader the new input stream. void yyreset(ReaderPtr reader); - + /// Returns the current lexical state. int32_t yystate(); - + /// Enters a new lexical state /// @param newState the new lexical state. void yybegin(int32_t newState); - + /// Returns the text matched by the current regular expression. String yytext(); - - /// Returns the character at position pos from the matched text. + + /// Returns the character at position pos from the matched text. /// /// It is equivalent to yytext()[pos], but faster /// @param pos the position of the character to fetch. A value from 0 to yylength() - 1. /// @return the character at position pos. wchar_t yycharat(int32_t pos); - + /// Returns the length of the matched text region. int32_t yylength(); - + /// Pushes the specified amount of characters back into the input stream. /// /// They will be read again by then next call of the scanning method /// @param number the number of characters to be read again. This number must not be greater than yylength() void yypushback(int32_t number); - + /// Resumes scanning until the next regular expression is matched, the end of input is encountered or an I/O- /// Error occurs. int32_t getNextToken(); - + protected: /// Refills the input buffer. bool zzRefill(); - + /// Reports an error that occurred while scanning. /// - /// In a well-formed scanner (no or only correct usage of yypushback(int32_t) and a match-all fallback rule) - /// this method will only be called with things that "Can't Possibly Happen". If this method is called, + /// In a well-formed scanner (no or only correct usage of yypushback(int32_t) and a match-all fallback rule) + /// this method will only be called with things that "Can't Possibly Happen". If this method is called, /// something is seriously wrong. /// /// Usual syntax/scanner level error handling should be done in error fallback rules. diff --git a/include/StopAnalyzer.h b/include/StopAnalyzer.h index 4ae74e2e..18c1677e 100644 --- a/include/StopAnalyzer.h +++ b/include/StopAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,37 +13,37 @@ namespace Lucene { /// Filters {@link LetterTokenizer} with {@link LowerCaseFilter} and {@link StopFilter}. /// - /// You must specify the required {@link Version} compatibility when creating StopAnalyzer: As of 2.9, position + /// You must specify the required {@link Version} compatibility when creating StopAnalyzer: As of 2.9, position /// increments are preserved class LPPAPI StopAnalyzer : public Analyzer { public: /// Builds an analyzer which removes words in {@link #ENGLISH_STOP_WORDS_SET}. StopAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the stop words from the given set. StopAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords); - + /// Builds an analyzer with the stop words from the given file. StopAnalyzer(LuceneVersion::Version matchVersion, const String& stopwordsFile); - + /// Builds an analyzer with the stop words from the given reader. StopAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords); - + virtual ~StopAnalyzer(); - + LUCENE_CLASS(StopAnalyzer); - + protected: HashSet stopWords; bool enablePositionIncrements; - + static const wchar_t* _ENGLISH_STOP_WORDS_SET[]; - + public: /// An unmodifiable set containing some common English words that are usually not useful for searching. static const HashSet ENGLISH_STOP_WORDS_SET(); - + virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; diff --git a/include/StopFilter.h b/include/StopFilter.h index b16eabed..59320fa0 100644 --- a/include/StopFilter.h +++ b/include/StopFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,11 +15,11 @@ namespace Lucene class LPPAPI StopFilter : public TokenFilter { public: - /// Construct a token stream filtering the given input. If stopWords is an instance of {@link CharArraySet} - /// (true if makeStopSet() was used to construct the set) it will be directly used and ignoreCase will be + /// Construct a token stream filtering the given input. If stopWords is an instance of {@link CharArraySet} + /// (true if makeStopSet() was used to construct the set) it will be directly used and ignoreCase will be /// ignored since CharArraySet directly controls case sensitivity. /// - /// If stopWords is not an instance of {@link CharArraySet}, a new CharArraySet will be constructed and + /// If stopWords is not an instance of {@link CharArraySet}, a new CharArraySet will be constructed and /// ignoreCase will be used to specify the case sensitivity of that set. /// /// @param enablePositionIncrements true if token positions should record the removed stop words @@ -28,34 +28,34 @@ namespace Lucene /// @param ignoreCase if true, all words are lower cased first StopFilter(bool enablePositionIncrements, TokenStreamPtr input, HashSet stopWords, bool ignoreCase = false); StopFilter(bool enablePositionIncrements, TokenStreamPtr input, CharArraySetPtr stopWords, bool ignoreCase = false); - + virtual ~StopFilter(); - + LUCENE_CLASS(StopFilter); - + protected: CharArraySetPtr stopWords; bool enablePositionIncrements; - + TermAttributePtr termAtt; PositionIncrementAttributePtr posIncrAtt; - + public: /// Builds a Set from an array of stop words, appropriate for passing into the StopFilter constructor. static HashSet makeStopSet(Collection stopWords); - + /// Returns the next input Token whose term() is not a stop word. virtual bool incrementToken(); - - /// Returns version-dependent default for enablePositionIncrements. Analyzers that embed StopFilter use this + + /// Returns version-dependent default for enablePositionIncrements. Analyzers that embed StopFilter use this /// method when creating the StopFilter. Prior to 2.9, this returns false. On 2.9 or later, it returns true. static bool getEnablePositionIncrementsVersionDefault(LuceneVersion::Version matchVersion); - + /// @see #setEnablePositionIncrements(bool). bool getEnablePositionIncrements(); - - /// If true, this StopFilter will preserve positions of the incoming tokens (ie, accumulate and set position - /// increments of the removed stop tokens). Generally, true is best as it does not lose information (positions + + /// If true, this StopFilter will preserve positions of the incoming tokens (ie, accumulate and set position + /// increments of the removed stop tokens). Generally, true is best as it does not lose information (positions /// of the original tokens) during indexing. /// /// When set, when a token is stopped (omitted), the position increment of the following token is incremented. diff --git a/include/StoredFieldsWriter.h b/include/StoredFieldsWriter.h index 87f74c6b..9b932147 100644 --- a/include/StoredFieldsWriter.h +++ b/include/StoredFieldsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene public: StoredFieldsWriter(DocumentsWriterPtr docWriter, FieldInfosPtr fieldInfos); virtual ~StoredFieldsWriter(); - + LUCENE_CLASS(StoredFieldsWriter); - + public: FieldsWriterPtr fieldsWriter; DocumentsWriterWeakPtr _docWriter; @@ -29,41 +29,41 @@ namespace Lucene Collection docFreeList; int32_t freeCount; int32_t allocCount; - + public: StoredFieldsWriterPerThreadPtr addThread(DocStatePtr docState); void flush(SegmentWriteStatePtr state); void closeDocStore(SegmentWriteStatePtr state); StoredFieldsWriterPerDocPtr getPerDoc(); void abort(); - + /// Fills in any hole in the docIDs void fill(int32_t docID); - + void finishDocument(StoredFieldsWriterPerDocPtr perDoc); bool freeRAM(); void free(StoredFieldsWriterPerDocPtr perDoc); - + protected: void initFieldsWriter(); }; - + class StoredFieldsWriterPerDoc : public DocWriter { public: StoredFieldsWriterPerDoc(StoredFieldsWriterPtr fieldsWriter); virtual ~StoredFieldsWriterPerDoc(); - + LUCENE_CLASS(StoredFieldsWriterPerDoc); - + protected: StoredFieldsWriterWeakPtr _fieldsWriter; - + public: PerDocBufferPtr buffer; RAMOutputStreamPtr fdt; int32_t numStoredFields; - + public: void reset(); virtual void abort(); diff --git a/include/StoredFieldsWriterPerThread.h b/include/StoredFieldsWriterPerThread.h index 8a569532..22e72ce8 100644 --- a/include/StoredFieldsWriterPerThread.h +++ b/include/StoredFieldsWriterPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,16 +16,16 @@ namespace Lucene public: StoredFieldsWriterPerThread(DocStatePtr docState, StoredFieldsWriterPtr storedFieldsWriter); virtual ~StoredFieldsWriterPerThread(); - + LUCENE_CLASS(StoredFieldsWriterPerThread); - + public: FieldsWriterPtr localFieldsWriter; StoredFieldsWriterWeakPtr _storedFieldsWriter; DocStatePtr docState; StoredFieldsWriterPerDocPtr doc; - + public: void startDocument(); void addField(FieldablePtr field, FieldInfoPtr fieldInfo); diff --git a/include/StringReader.h b/include/StringReader.h index dbfcc275..e048cf2f 100644 --- a/include/StringReader.h +++ b/include/StringReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,29 +18,29 @@ namespace Lucene /// Creates a new StringReader, given the String to read from. StringReader(const String& str); virtual ~StringReader(); - + LUCENE_CLASS(StringReader); - + protected: String str; int32_t position; - + public: /// Read a single character. virtual int32_t read(); /// Read characters into a portion of an array. virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - + /// Close the stream. virtual void close(); - + /// Tell whether this stream supports the mark() operation virtual bool markSupported(); - + /// Reset the stream. virtual void reset(); - + /// The number of bytes in the stream. virtual int64_t length(); }; diff --git a/include/StringUtils.h b/include/StringUtils.h index 2468b0cc..72db1b8a 100644 --- a/include/StringUtils.h +++ b/include/StringUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,71 +16,71 @@ namespace Lucene public: /// Maximum length of UTF encoding. static const int32_t MAX_ENCODING_UTF8_SIZE; - + /// Default character radix. static const int32_t CHARACTER_MAX_RADIX; - - public: + + public: /// Convert uft8 buffer into unicode. static int32_t toUnicode(const uint8_t* utf8, int32_t length, CharArray unicode); - + /// Convert uft8 buffer into unicode. static int32_t toUnicode(const uint8_t* utf8, int32_t length, UnicodeResultPtr unicodeResult); - + /// Convert uft8 buffer into unicode. static String toUnicode(const uint8_t* utf8, int32_t length); - + /// Convert uft8 string into unicode. static String toUnicode(const SingleString& s); - + /// Convert unicode buffer into uft8. static int32_t toUTF8(const wchar_t* unicode, int32_t length, ByteArray utf8); - + /// Convert unicode buffer into uft8. static int32_t toUTF8(const wchar_t* unicode, int32_t length, UTF8ResultPtr utf8Result); - + /// Convert unicode buffer into uft8. static SingleString toUTF8(const wchar_t* unicode, int32_t length); - + /// Convert unicode string into uft8. static SingleString toUTF8(const String& s); - + /// Convert given string to lower case using current locale static void toLower(String& str); - + /// Convert given string to lower case using current locale static String toLower(const String& str); - + /// Convert given string to upper case using current locale static void toUpper(String& str); - + /// Convert given string to upper case using current locale static String toUpper(const String& str); - + /// Compare two strings ignoring case differences static int32_t compareCase(const String& first, const String& second); - + /// Splits string using given delimiters static Collection split(const String& str, const String& delim); - + /// Convert the given string to int32_t. static int32_t toInt(const String& value); - + /// Convert the given string to int64_t. static int64_t toLong(const String& value); - + /// Return given value as a long integer using base unit. static int64_t toLong(const String& value, int32_t base); - + /// Convert the given string to double. static double toDouble(const String& value); - + /// Compute the hash code from string. static int32_t hashCode(const String& value); - + /// Return given value as a string using base unit. static String toString(int64_t value, int32_t base); - + /// Convert any given type to a {@link String}. template static String toString(const TYPE& value) @@ -90,7 +90,7 @@ namespace Lucene return os.str(); } }; - + #define UTF8_TO_STRING(utf8) StringUtils::toUnicode(utf8, SIZEOF_ARRAY(utf8)) } diff --git a/include/Synchronize.h b/include/Synchronize.h index 0d3f0afd..269fde4b 100644 --- a/include/Synchronize.h +++ b/include/Synchronize.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,47 +18,47 @@ namespace Lucene public: Synchronize(); virtual ~Synchronize(); - + protected: boost::recursive_timed_mutex mutexSynchronize; int64_t lockThread; int32_t recursionCount; - + public: /// create a new Synchronize instance atomically. static void createSync(SynchronizePtr& sync); - + /// Lock mutex using an optional timeout. void lock(int32_t timeout = 0); - + /// Unlock mutex. void unlock(); - + /// Unlock all recursive mutex. int32_t unlockAll(); - + /// Returns true if mutex is currently locked by current thread. bool holdsLock(); }; - + /// Utility class to support scope locking. class LPPAPI SyncLock { public: SyncLock(SynchronizePtr sync, int32_t timeout = 0); - + template SyncLock(OBJECT object, int32_t timeout = 0) { this->sync = object->getSync(); lock(timeout); } - + virtual ~SyncLock(); - + protected: SynchronizePtr sync; - + protected: void lock(int32_t timeout); }; diff --git a/include/TeeSinkTokenFilter.h b/include/TeeSinkTokenFilter.h index c22653b7..69e8b4e4 100644 --- a/include/TeeSinkTokenFilter.h +++ b/include/TeeSinkTokenFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,10 +12,10 @@ namespace Lucene { - /// This TokenFilter provides the ability to set aside attribute states that have already been analyzed. This is + /// This TokenFilter provides the ability to set aside attribute states that have already been analyzed. This is /// useful in situations where multiple fields share many common analysis steps and then go their separate ways. /// - /// It is also useful for doing things like entity extraction or proper noun analysis as part of the analysis workflow + /// It is also useful for doing things like entity extraction or proper noun analysis as part of the analysis workflow /// and saving off those tokens for use in another field. /// ///
    @@ -40,8 +40,8 @@ namespace Lucene
         ///
         /// In this example, sink1 and sink2 will both get tokens from both reader1 and reader2 after whitespace tokenizer
         /// and now we can further wrap any of these in extra analysis, and more "sources" can be inserted if desired.
    -    /// It is important, that tees are consumed before sinks (in the above example, the field names must be less the 
    -    /// sink's field names). If you are not sure, which stream is consumed first, you can simply add another sink and 
    +    /// It is important, that tees are consumed before sinks (in the above example, the field names must be less the
    +    /// sink's field names). If you are not sure, which stream is consumed first, you can simply add another sink and
         /// then pass all tokens to the sinks at once using {@link #consumeAllTokens}.
         ///
         /// This TokenFilter is exhausted after this. In the above example, change the example above to:
    @@ -55,7 +55,7 @@ namespace Lucene
         /// ...
         /// 
    /// - /// In this case, the fields can be added in any order, because the sources are not used anymore and all sinks are + /// In this case, the fields can be added in any order, because the sources are not used anymore and all sinks are /// ready. /// /// Note, the EntityDetect and URLDetect TokenStreams are for the example and do not currently exist in Lucene. @@ -65,86 +65,86 @@ namespace Lucene /// Instantiates a new TeeSinkTokenFilter. TeeSinkTokenFilter(TokenStreamPtr input); virtual ~TeeSinkTokenFilter(); - + LUCENE_CLASS(TeeSinkTokenFilter); - + protected: Collection sinks; - + public: /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream. SinkTokenStreamPtr newSinkTokenStream(); - - /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream that pass + + /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream that pass /// the supplied filter. /// @see SinkFilter SinkTokenStreamPtr newSinkTokenStream(SinkFilterPtr filter); - - /// Adds a {@link SinkTokenStream} created by another TeeSinkTokenFilter to this one. The supplied stream will + + /// Adds a {@link SinkTokenStream} created by another TeeSinkTokenFilter to this one. The supplied stream will /// also receive all consumed tokens. This method can be used to pass tokens from two different tees to one sink. void addSinkTokenStream(SinkTokenStreamPtr sink); - - /// TeeSinkTokenFilter passes all tokens to the added sinks when itself is consumed. To be sure, that all tokens - /// from the input stream are passed to the sinks, you can call this methods. This instance is exhausted after this, + + /// TeeSinkTokenFilter passes all tokens to the added sinks when itself is consumed. To be sure, that all tokens + /// from the input stream are passed to the sinks, you can call this methods. This instance is exhausted after this, /// but all sinks are instant available. void consumeAllTokens(); - + virtual bool incrementToken(); virtual void end(); }; - + class LPPAPI SinkFilter : public LuceneObject { public: virtual ~SinkFilter(); - + LUCENE_CLASS(SinkFilter); - + public: - /// Returns true, if the current state of the passed-in {@link AttributeSource} shall be stored in the sink. + /// Returns true, if the current state of the passed-in {@link AttributeSource} shall be stored in the sink. virtual bool accept(AttributeSourcePtr source) = 0; - + /// Called by {@link SinkTokenStream#reset()}. This method does nothing by default and can optionally be overridden. virtual void reset(); }; - + class LPPAPI AcceptAllSinkFilter : public SinkFilter { public: virtual ~AcceptAllSinkFilter(); - + LUCENE_CLASS(AcceptAllSinkFilter); - + public: - virtual bool accept(AttributeSourcePtr source); + virtual bool accept(AttributeSourcePtr source); }; - + /// A filter that decides which {@link AttributeSource} states to store in the sink. class LPPAPI SinkTokenStream : public TokenStream { public: SinkTokenStream(AttributeSourcePtr source, SinkFilterPtr filter); virtual ~SinkTokenStream(); - + LUCENE_CLASS(SinkTokenStream); - + protected: Collection cachedStates; AttributeSourceStatePtr finalState; - bool initIterator; + bool initIterator; Collection::iterator it; SinkFilterPtr filter; - + protected: bool accept(AttributeSourcePtr source); void addState(AttributeSourceStatePtr state); void setFinalState(AttributeSourceStatePtr finalState); - + public: virtual bool incrementToken(); virtual void end(); virtual void reset(); - + friend class TeeSinkTokenFilter; }; } diff --git a/include/Term.h b/include/Term.h index 09bc1450..7de42e45 100644 --- a/include/Term.h +++ b/include/Term.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,11 +11,11 @@ namespace Lucene { - /// A Term represents a word from text. This is the unit of search. It is composed of two elements, - /// the text of the word, as a string, and the name of the field that the text occurred in, an interned + /// A Term represents a word from text. This is the unit of search. It is composed of two elements, + /// the text of the word, as a string, and the name of the field that the text occurred in, an interned /// string. /// - /// Note that terms may represent more than words from text fields, but also things like dates, email + /// Note that terms may represent more than words from text fields, but also things like dates, email /// addresses, urls, etc. class LPPAPI Term : public LuceneObject { @@ -23,38 +23,38 @@ namespace Lucene /// Constructs a Term with the given field and text. Term(const String& fld, const String& txt = EmptyString); virtual ~Term(); - + LUCENE_CLASS(Term); - + public: String _field; String _text; - + public: - /// Returns the field of this term, an interned string. The field indicates the part of a document + /// Returns the field of this term, an interned string. The field indicates the part of a document /// which this term came from. String field(); - - /// Returns the text of this term. In the case of words, this is simply the text of the word. In + + /// Returns the text of this term. In the case of words, this is simply the text of the word. In /// the case of dates and other types, this is an encoding of the object as a string. String text(); - + /// Optimized construction of new Terms by reusing same field as this Term /// @param text The text of the new term (field is implicitly same as this Term instance) /// @return A new Term TermPtr createTerm(const String& text); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - - /// Compares two terms, returning a negative integer if this term belongs before the argument, zero + + /// Compares two terms, returning a negative integer if this term belongs before the argument, zero /// if this term is equal to the argument, and a positive integer if this term belongs after the argument. /// /// The ordering of terms is first by field, then by text. virtual int32_t compareTo(LuceneObjectPtr other); - + void set(const String& fld, const String& txt); - + virtual String toString(); }; } diff --git a/include/TermAttribute.h b/include/TermAttribute.h index 2453fef4..b580a37e 100644 --- a/include/TermAttribute.h +++ b/include/TermAttribute.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,74 +17,74 @@ namespace Lucene public: TermAttribute(); virtual ~TermAttribute(); - + LUCENE_CLASS(TermAttribute); - + protected: static const int32_t MIN_BUFFER_SIZE; - + CharArray _termBuffer; int32_t _termLength; - + public: virtual String toString(); - + /// Returns the Token's term text. /// - /// This method has a performance penalty because the text is stored internally in a char[]. If possible, - /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use - /// this method, which is nothing more than a convenience call to new String(token.termBuffer(), 0, + /// This method has a performance penalty because the text is stored internally in a char[]. If possible, + /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use + /// this method, which is nothing more than a convenience call to new String(token.termBuffer(), 0, /// token.termLength()) virtual String term(); - + /// Copies the contents of buffer, starting at offset for length characters, into the termBuffer array. /// @param buffer the buffer to copy /// @param offset the index in the buffer of the first character to copy /// @param length the number of characters to copy virtual void setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length); - + /// Copies the contents of buffer into the termBuffer array. /// @param buffer the buffer to copy virtual void setTermBuffer(const String& buffer); - - /// Returns the internal termBuffer character array which you can then directly alter. If the array is - /// too small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer - /// be sure to call {@link #setTermLength} to record the number of valid characters that were placed into + + /// Returns the internal termBuffer character array which you can then directly alter. If the array is + /// too small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer + /// be sure to call {@link #setTermLength} to record the number of valid characters that were placed into /// the termBuffer. virtual CharArray termBuffer(); - + /// Optimized implementation of termBuffer. virtual wchar_t* termBufferArray(); - - /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next + + /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next /// operation is to change the contents of the term buffer use {@link #setTermBuffer(char[], int, int)}, - /// {@link #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the + /// {@link #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the /// resize with the setting of the termBuffer. /// @param newSize minimum size of the new termBuffer /// @return newly created termBuffer with length >= newSize virtual CharArray resizeTermBuffer(int32_t newSize); - + /// Return number of valid characters (length of the term) in the termBuffer array. virtual int32_t termLength(); - - /// Set number of valid characters (length of the term) in the termBuffer array. Use this to truncate the - /// termBuffer or to synchronize with external manipulation of the termBuffer. Note: to grow the size of + + /// Set number of valid characters (length of the term) in the termBuffer array. Use this to truncate the + /// termBuffer or to synchronize with external manipulation of the termBuffer. Note: to grow the size of /// the array, use {@link #resizeTermBuffer(int)} first. /// @param length the truncated length virtual void setTermLength(int32_t length); - + virtual int32_t hashCode(); virtual void clear(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual bool equals(LuceneObjectPtr other); virtual void copyTo(AttributePtr target); - + protected: - /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always + /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always /// used in places that set the content. /// @param newSize minimum size of the buffer void growTermBuffer(int32_t newSize); - + void initTermBuffer(); }; } diff --git a/include/TermBuffer.h b/include/TermBuffer.h index 2766c70a..907b1890 100644 --- a/include/TermBuffer.h +++ b/include/TermBuffer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,33 +16,33 @@ namespace Lucene public: TermBuffer(); virtual ~TermBuffer(); - + LUCENE_CLASS(TermBuffer); - + protected: String field; TermPtr term; // cached bool preUTF8Strings; // true if strings are stored in modified UTF8 encoding - + UnicodeResultPtr text; UTF8ResultPtr bytes; - + public: virtual int32_t compareTo(LuceneObjectPtr other); - + /// Call this if the IndexInput passed to {@link #read} stores terms in the "modified UTF8" format. void setPreUTF8Strings(); - + void read(IndexInputPtr input, FieldInfosPtr fieldInfos); - + void set(TermPtr term); void set(TermBufferPtr other); void reset(); - + TermPtr toTerm(); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + protected: int32_t compareChars(wchar_t* chars1, int32_t len1, wchar_t* chars2, int32_t len2); }; diff --git a/include/TermDocs.h b/include/TermDocs.h index d0d65589..0de10d44 100644 --- a/include/TermDocs.h +++ b/include/TermDocs.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,9 +11,9 @@ namespace Lucene { - /// TermDocs provides an interface for enumerating ; pairs for a term. The document - /// portion names each document containing the term. Documents are indicated by number. The frequency - /// portion gives the number of times the term occurred in each document. The pairs are ordered by document + /// TermDocs provides an interface for enumerating ; pairs for a term. The document + /// portion names each document containing the term. Documents are indicated by number. The frequency + /// portion gives the number of times the term occurred in each document. The pairs are ordered by document /// number. /// @see IndexReader#termDocs() class LPPAPI TermDocs @@ -23,11 +23,11 @@ namespace Lucene public: LUCENE_INTERFACE(TermDocs); - + public: /// Sets this to the data for a term. The enumeration is reset to the start of the data for this term. virtual void seek(TermPtr term) = 0; - + /// Sets this to the data for the current term in a {@link TermEnum}. /// This may be optimized in some implementations. virtual void seek(TermEnumPtr termEnum) = 0; @@ -35,19 +35,19 @@ namespace Lucene /// Returns the current document number. This is invalid until {@link #next()} is called for the first time. virtual int32_t doc() = 0; - /// Returns the frequency of the term within the current document. This is invalid until {@link #next()} is + /// Returns the frequency of the term within the current document. This is invalid until {@link #next()} is /// called for the first time. virtual int32_t freq() = 0; /// Moves to the next pair in the enumeration. Returns true if there is such a next pair in the enumeration. virtual bool next() = 0; - /// Attempts to read multiple entries from the enumeration, up to length of docs. Document numbers are stored - /// in docs, and term frequencies are stored in freqs. Returns the number of entries read. Zero is only + /// Attempts to read multiple entries from the enumeration, up to length of docs. Document numbers are stored + /// in docs, and term frequencies are stored in freqs. Returns the number of entries read. Zero is only /// returned when the stream has been exhausted. virtual int32_t read(Collection docs, Collection freqs) = 0; - /// Skips entries to the first beyond the current whose document number is greater than or equal to target. + /// Skips entries to the first beyond the current whose document number is greater than or equal to target. /// Returns true if there is such an entry. virtual bool skipTo(int32_t target) = 0; diff --git a/include/TermEnum.h b/include/TermEnum.h index 7260f802..7372cae7 100644 --- a/include/TermEnum.h +++ b/include/TermEnum.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,24 +13,24 @@ namespace Lucene { /// Abstract class for enumerating terms. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater + /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater /// than all that precede it. class LPPAPI TermEnum : public LuceneObject { public: - virtual ~TermEnum(); + virtual ~TermEnum(); LUCENE_CLASS(TermEnum); - + public: /// Increments the enumeration to the next element. True if one exists. virtual bool next() = 0; - + /// Returns the current Term in the enumeration. virtual TermPtr term() = 0; - + /// Returns the docFreq of the current Term in the enumeration. virtual int32_t docFreq() = 0; - + /// Closes the enumeration to further activity, freeing resources. virtual void close() = 0; }; diff --git a/include/TermFreqVector.h b/include/TermFreqVector.h index 846b1532..34d4a131 100644 --- a/include/TermFreqVector.h +++ b/include/TermFreqVector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,9 +11,9 @@ namespace Lucene { - /// Provides access to stored term vector of a document field. The vector consists of the name of the field, an - /// array of the terms that occur in the field of the {@link Document} and a parallel array of frequencies. Thus, - /// getTermFrequencies()[5] corresponds with the frequency of getTerms()[5], assuming there are at least 5 terms + /// Provides access to stored term vector of a document field. The vector consists of the name of the field, an + /// array of the terms that occur in the field of the {@link Document} and a parallel array of frequencies. Thus, + /// getTermFrequencies()[5] corresponds with the frequency of getTerms()[5], assuming there are at least 5 terms /// in the Document. class LPPAPI TermFreqVector { @@ -21,30 +21,30 @@ namespace Lucene TermFreqVector(); public: - virtual ~TermFreqVector(); + virtual ~TermFreqVector(); LUCENE_INTERFACE(TermFreqVector); - + public: - /// The {@link Fieldable} name. + /// The {@link Fieldable} name. /// @return The name of the field this vector is associated with. virtual String getField(); - + /// @return The number of terms in the term vector. virtual int32_t size(); - + /// @return An Array of term texts in ascending order. virtual Collection getTerms(); - - /// Array of term frequencies. Locations of the array correspond one to one to the terms in the array obtained from + + /// Array of term frequencies. Locations of the array correspond one to one to the terms in the array obtained from /// getTerms method. Each location in the array contains the number of times this term occurs in the document or the /// document field. virtual Collection getTermFrequencies(); - - /// Return an index in the term numbers array returned from getTerms at which the term with the specified term appears. + + /// Return an index in the term numbers array returned from getTerms at which the term with the specified term appears. /// If this term does not appear in the array, return -1. virtual int32_t indexOf(const String& term); - - /// Just like indexOf(int) but searches for a number of terms at the same time. Returns an array that has the same size + + /// Just like indexOf(int) but searches for a number of terms at the same time. Returns an array that has the same size /// as the number of terms searched for, each slot containing the result of searching for that term number. /// /// @param terms array containing terms to look for diff --git a/include/TermInfo.h b/include/TermInfo.h index a0b706a8..14f851be 100644 --- a/include/TermInfo.h +++ b/include/TermInfo.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,16 +18,16 @@ namespace Lucene TermInfo(TermInfoPtr ti); TermInfo(int32_t df = 0, int64_t fp = 0, int64_t pp = 0); virtual ~TermInfo(); - + LUCENE_CLASS(TermInfo); - + public: /// The number of documents which contain the term. int32_t docFreq; int64_t freqPointer; int64_t proxPointer; int32_t skipOffset; - + public: void set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer, int32_t skipOffset); void set(TermInfoPtr ti); diff --git a/include/TermInfosReader.h b/include/TermInfosReader.h index b03c0081..fa4e3b15 100644 --- a/include/TermInfosReader.h +++ b/include/TermInfosReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,16 +12,16 @@ namespace Lucene { - /// This stores a monotonically increasing set of pairs in a Directory. Pairs are + /// This stores a monotonically increasing set of pairs in a Directory. Pairs are /// accessed either by Term or by ordinal position the set. class TermInfosReader : public LuceneObject { public: TermInfosReader(DirectoryPtr dir, const String& seg, FieldInfosPtr fis, int32_t readBufferSize, int32_t indexDivisor); virtual ~TermInfosReader(); - + LUCENE_CLASS(TermInfosReader); - + protected: DirectoryPtr directory; String segment; @@ -33,55 +33,55 @@ namespace Lucene Collection indexTerms; Collection indexInfos; Collection indexPointers; - + int32_t totalIndexInterval; - + static const int32_t DEFAULT_CACHE_SIZE; - + public: int32_t getSkipInterval(); int32_t getMaxSkipLevels(); void close(); - + /// Returns the number of term/value pairs in the set. int64_t size(); - + /// Returns the TermInfo for a Term in the set, or null. TermInfoPtr get(TermPtr term); - + /// Returns the position of a Term in the set or -1. int64_t getPosition(TermPtr term); - + /// Returns an enumeration of all the Terms and TermInfos in the set. SegmentTermEnumPtr terms(); - + /// Returns an enumeration of terms starting at or after the named term. SegmentTermEnumPtr terms(TermPtr term); - + protected: TermInfosReaderThreadResourcesPtr getThreadResources(); - + /// Returns the offset of the greatest index entry which is less than or equal to term. int32_t getIndexOffset(TermPtr term); - + void seekEnum(SegmentTermEnumPtr enumerator, int32_t indexOffset); - + /// Returns the TermInfo for a Term in the set, or null. TermInfoPtr get(TermPtr term, bool useCache); - + void ensureIndexIsRead(); }; - + class TermInfosReaderThreadResources : public LuceneObject { public: virtual ~TermInfosReaderThreadResources(); - + LUCENE_CLASS(TermInfosReaderThreadResources); - + public: SegmentTermEnumPtr termEnum; - + // Used for caching the least recently looked-up Terms TermInfoCachePtr termInfoCache; }; diff --git a/include/TermInfosWriter.h b/include/TermInfosWriter.h index 79804259..22c45dfe 100644 --- a/include/TermInfosWriter.h +++ b/include/TermInfosWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// This stores a monotonically increasing set of pairs in a Directory. A TermInfos + /// This stores a monotonically increasing set of pairs in a Directory. A TermInfos /// can be written once, in order. class TermInfosWriter : public LuceneObject { @@ -19,75 +19,75 @@ namespace Lucene TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval); TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isIndex); virtual ~TermInfosWriter(); - + LUCENE_CLASS(TermInfosWriter); - + public: /// The file format version, a negative number. static const int32_t FORMAT; - + /// Changed strings to true utf8 with length-in-bytes not length-in-chars. static const int32_t FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; - + /// NOTE: always change this if you switch to a new format. static const int32_t FORMAT_CURRENT; - - /// The fraction of terms in the "dictionary" which should be stored in RAM. Smaller values use more memory, but - /// make searching slightly faster, while larger values use less memory and make searching slightly slower. + + /// The fraction of terms in the "dictionary" which should be stored in RAM. Smaller values use more memory, but + /// make searching slightly faster, while larger values use less memory and make searching slightly slower. /// Searching is typically not dominated by dictionary lookup, so tweaking this is rarely useful. int32_t indexInterval; - - /// The fraction of {@link TermDocs} entries stored in skip tables, used to accelerate {@link TermDocs#skipTo(int)}. - /// Larger values result in smaller indexes, greater acceleration, but fewer accelerable cases, while smaller values - /// result in bigger indexes, less acceleration and more accelerable cases. More detailed experiments would be useful + + /// The fraction of {@link TermDocs} entries stored in skip tables, used to accelerate {@link TermDocs#skipTo(int)}. + /// Larger values result in smaller indexes, greater acceleration, but fewer accelerable cases, while smaller values + /// result in bigger indexes, less acceleration and more accelerable cases. More detailed experiments would be useful /// here. int32_t skipInterval; - - /// The maximum number of skip levels. Smaller values result in slightly smaller indexes, but slower skipping + + /// The maximum number of skip levels. Smaller values result in slightly smaller indexes, but slower skipping /// in big posting lists. int32_t maxSkipLevels; - + protected: FieldInfosPtr fieldInfos; IndexOutputPtr output; TermInfoPtr lastTi; int64_t size; - + int64_t lastIndexPointer; bool isIndex; ByteArray lastTermBytes; int32_t lastTermBytesLength; int32_t lastFieldNumber; - + TermInfosWriterPtr otherWriter; TermInfosWriterWeakPtr _other; UTF8ResultPtr utf8Result; - + // Currently used only by assert statements UnicodeResultPtr unicodeResult1; UnicodeResultPtr unicodeResult2; - + public: virtual void initialize(); - + void add(TermPtr term, TermInfoPtr ti); - - /// Adds a new <, TermInfo> pair to the set. Term must be lexicographically + + /// Adds a new <, TermInfo> pair to the set. Term must be lexicographically /// greater than all previous Terms added. TermInfo pointers must be positive and greater than all previous. void add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, TermInfoPtr ti); - + /// Called to complete TermInfos creation. void close(); - + protected: void initialize(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isi); - + /// Currently used only by assert statements bool initUnicodeResults(); - + /// Currently used only by assert statement int32_t compareToLastTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength); - + void writeTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength); }; } diff --git a/include/TermPositionVector.h b/include/TermPositionVector.h index b5a925eb..e1ba24d4 100644 --- a/include/TermPositionVector.h +++ b/include/TermPositionVector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// Extends TermFreqVector to provide additional information about positions in which each of the terms is found. A TermPositionVector not necessarily + /// Extends TermFreqVector to provide additional information about positions in which each of the terms is found. A TermPositionVector not necessarily /// contains both positions and offsets, but at least one of these arrays exists. class LPPAPI TermPositionVector : public TermFreqVector { @@ -21,12 +21,12 @@ namespace Lucene public: virtual ~TermPositionVector(); LUCENE_INTERFACE(TermPositionVector); - + public: - /// Returns an array of positions in which the term is found. Terms are identified by the index at which its number appears in the term String + /// Returns an array of positions in which the term is found. Terms are identified by the index at which its number appears in the term String /// array obtained from the indexOf method. May return null if positions have not been stored. virtual Collection getTermPositions(int32_t index); - + /// Returns an array of TermVectorOffsetInfo in which the term is found. May return null if offsets have not been stored. /// @see Token /// @param index The position in the array to get the offsets from diff --git a/include/TermPositions.h b/include/TermPositions.h index 72643ea3..7b35b3b5 100644 --- a/include/TermPositions.h +++ b/include/TermPositions.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,8 +11,8 @@ namespace Lucene { - /// TermPositions provides an interface for enumerating the *> - /// tuples for a term. The document and frequency are the same as for a TermDocs. The positions portion + /// TermPositions provides an interface for enumerating the *> + /// tuples for a term. The document and frequency are the same as for a TermDocs. The positions portion /// lists the ordinal positions of each occurrence of a term in a document. /// @see IndexReader#termPositions() class LPPAPI TermPositions : public TermDocs @@ -21,30 +21,30 @@ namespace Lucene TermPositions(); public: - virtual ~TermPositions(); + virtual ~TermPositions(); LUCENE_INTERFACE(TermPositions); - + public: - /// Returns next position in the current document. It is an error to call this more than {@link #freq()} + /// Returns next position in the current document. It is an error to call this more than {@link #freq()} /// times without calling {@link #next()}. This is invalid until {@link #next()} is called for // the first time. virtual int32_t nextPosition(); - - /// Returns the length of the payload at the current term position. This is invalid until {@link + + /// Returns the length of the payload at the current term position. This is invalid until {@link /// #nextPosition()} is called for the first time. /// @return length of the current payload in number of bytes virtual int32_t getPayloadLength(); - - /// Returns the payload data at the current term position. This is invalid until {@link #nextPosition()} + + /// Returns the payload data at the current term position. This is invalid until {@link #nextPosition()} /// is called for the first time. - /// This method must not be called more than once after each call of {@link #nextPosition()}. However, + /// This method must not be called more than once after each call of {@link #nextPosition()}. However, /// payloads are loaded lazily, so if the payload data for the current position is not needed, /// this method may not be called at all for performance reasons. /// @param data the array into which the data of this payload is to be stored /// @param offset the offset in the array into which the data of this payload is to be stored. /// @return a byte array containing the data of this payload virtual ByteArray getPayload(ByteArray data, int32_t offset); - + /// Checks if a payload can be loaded at this position. /// Payloads can only be loaded once per call to {@link #nextPosition()}. /// @return true if there is a payload available at this position that can be loaded diff --git a/include/TermQuery.h b/include/TermQuery.h index b334d20e..c66a07d9 100644 --- a/include/TermQuery.h +++ b/include/TermQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,37 +11,37 @@ namespace Lucene { - /// A Query that matches documents containing a term. This may be combined with other terms with a + /// A Query that matches documents containing a term. This may be combined with other terms with a /// {@link BooleanQuery}. class LPPAPI TermQuery : public Query { public: /// Constructs a query for the term. TermQuery(TermPtr term); - + virtual ~TermQuery(); - + LUCENE_CLASS(TermQuery); - + protected: TermPtr term; - + public: using Query::toString; - + /// Returns the term of this query. TermPtr getTerm(); - + virtual WeightPtr createWeight(SearcherPtr searcher); virtual void extractTerms(SetTerm terms); - + /// Prints a user-readable version of this query. virtual String toString(const String& field); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + friend class TermWeight; }; } diff --git a/include/TermRangeFilter.h b/include/TermRangeFilter.h index fa10c123..7707dcfc 100644 --- a/include/TermRangeFilter.h +++ b/include/TermRangeFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,52 +14,52 @@ namespace Lucene /// A Filter that restricts search results to a range of term values in a given field. /// /// This filter matches the documents looking for terms that fall into the supplied range according to {@link - /// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link + /// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link /// NumericRangeFilter} instead. /// - /// If you construct a large number of range filters with different ranges but on the same field, {@link + /// If you construct a large number of range filters with different ranges but on the same field, {@link /// FieldCacheRangeFilter} may have significantly better performance. class LPPAPI TermRangeFilter : public MultiTermQueryWrapperFilter { public: - /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause - /// every single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending + /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause + /// every single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending /// on the number of index Terms in this Field, the operation could be very slow. /// @param lowerTerm The lower bound on this range /// @param upperTerm The upper bound on this range /// @param includeLower Does this range include the lower bound? /// @param includeUpper Does this range include the upper bound? - /// @param collator The collator to use when determining range inclusion; set to null to use Unicode code + /// @param collator The collator to use when determining range inclusion; set to null to use Unicode code /// point ordering instead of collation. - TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, bool includeUpper, CollatorPtr collator = CollatorPtr()); - + virtual ~TermRangeFilter(); - + LUCENE_CLASS(TermRangeFilter); - + public: /// Constructs a filter for field fieldName matching less than or equal to upperTerm. static TermRangeFilterPtr Less(const String& fieldName, StringValue upperTerm); - + /// Constructs a filter for field fieldName matching greater than or equal to lowerTerm. static TermRangeFilterPtr More(const String& fieldName, StringValue lowerTerm); - + /// Returns the field name for this filter String getField(); - + /// Returns the lower value of this range filter String getLowerTerm(); - + /// Returns the upper value of this range filter String getUpperTerm(); - + /// Returns true if the lower endpoint is inclusive bool includesLower(); - + /// Returns true if the upper endpoint is inclusive bool includesUpper(); - + /// Returns the collator used to determine range inclusion, if any. CollatorPtr getCollator(); }; diff --git a/include/TermRangeQuery.h b/include/TermRangeQuery.h index 6978f8f4..5c2c7c2e 100644 --- a/include/TermRangeQuery.h +++ b/include/TermRangeQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene /// A Query that matches documents within an range of terms. /// /// This query matches the documents looking for terms that fall into the supplied range according to {@link - /// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link + /// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link /// NumericRangeQuery} instead. /// /// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. @@ -23,30 +23,30 @@ namespace Lucene public: /// Constructs a query selecting all terms greater/equal than lowerTerm but less/equal than upperTerm. /// - /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints - /// may not be exclusive (you can't select all but the first or last term without explicitly specifying the + /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints + /// may not be exclusive (you can't select all but the first or last term without explicitly specifying the /// term to exclude.) /// - /// If collator is not null, it will be used to decide whether index terms are within the given range, rather + /// If collator is not null, it will be used to decide whether index terms are within the given range, rather /// than using the Unicode code point order in which index terms are stored. /// - /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause every - /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending on the + /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause every + /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending on the /// number of index Terms in this Field, the operation could be very slow. /// /// @param lowerTerm The Term text at the lower end of the range /// @param upperTerm The Term text at the upper end of the range /// @param includeLower If true, the lowerTerm is included in the range. /// @param includeUpper If true, the upperTerm is included in the range. - /// @param collator The collator to use to collate index Terms, to determine their membership in the range + /// @param collator The collator to use to collate index Terms, to determine their membership in the range /// bounded by lowerTerm and upperTerm. - TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, bool includeUpper, CollatorPtr collator = CollatorPtr()); virtual ~TermRangeQuery(); - + LUCENE_CLASS(TermRangeQuery); - + protected: StringValue lowerTerm; StringValue upperTerm; @@ -54,33 +54,33 @@ namespace Lucene String field; bool includeLower; bool includeUpper; - + public: using MultiTermQuery::toString; - + /// Returns the field name for this query String getField(); - + /// Returns the lower value of this range query String getLowerTerm(); - + /// Returns the upper value of this range query String getUpperTerm(); - + /// Returns true if the lower endpoint is inclusive bool includesLower(); - + /// Returns true if the upper endpoint is inclusive bool includesUpper(); - + /// Returns the collator used to determine range inclusion, if any. CollatorPtr getCollator(); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual String toString(const String& field); virtual int32_t hashCode(); virtual bool equals(LuceneObjectPtr other); - + protected: virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); }; diff --git a/include/TermRangeTermEnum.h b/include/TermRangeTermEnum.h index 074093be..abf0fe9f 100644 --- a/include/TermRangeTermEnum.h +++ b/include/TermRangeTermEnum.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,15 +13,15 @@ namespace Lucene { /// Subclass of FilteredTermEnum for enumerating all terms that match the specified range parameters. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than + /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than /// all that precede it. class LPPAPI TermRangeTermEnum : public FilteredTermEnum { public: - /// Enumerates all terms greater/equal than lowerTerm but less/equal than upperTerm. + /// Enumerates all terms greater/equal than lowerTerm but less/equal than upperTerm. /// - /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints - /// may not be exclusive (you can't select all but the first or last term without explicitly specifying + /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints + /// may not be exclusive (you can't select all but the first or last term without explicitly specifying /// the term to exclude.) /// /// @param reader @@ -30,15 +30,15 @@ namespace Lucene /// @param upperTermText The term text at the upper end of the range /// @param includeLower If true, the lowerTerm is included in the range. /// @param includeUpper If true, the upperTerm is included in the range. - /// @param collator The collator to use to collate index Terms, to determine their membership in the range + /// @param collator The collator to use to collate index Terms, to determine their membership in the range /// bounded by lowerTerm and upperTerm. - TermRangeTermEnum(IndexReaderPtr reader, const String& field, StringValue lowerTermText, StringValue upperTermText, + TermRangeTermEnum(IndexReaderPtr reader, const String& field, StringValue lowerTermText, StringValue upperTermText, bool includeLower, bool includeUpper, CollatorPtr collator); - + virtual ~TermRangeTermEnum(); - + LUCENE_CLASS(TermRangeTermEnum); - + protected: CollatorPtr collator; bool _endEnum; @@ -47,10 +47,10 @@ namespace Lucene StringValue lowerTermText; bool includeLower; bool includeUpper; - + public: virtual double difference(); - + protected: virtual bool endEnum(); virtual bool termCompare(TermPtr term); diff --git a/include/TermScorer.h b/include/TermScorer.h index ab0932bd..ec2e75be 100644 --- a/include/TermScorer.h +++ b/include/TermScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,50 +21,50 @@ namespace Lucene /// @param similarity The Similarity implementation to be used for score computations. /// @param norms The field norms of the document fields for the Term. TermScorer(WeightPtr weight, TermDocsPtr td, SimilarityPtr similarity, ByteArray norms); - + virtual ~TermScorer(); - + LUCENE_CLASS(TermScorer); - + protected: WeightPtr weight; TermDocsPtr termDocs; ByteArray norms; double weightValue; int32_t doc; - + Collection docs; // buffered doc numbers Collection freqs; // buffered term freqs int32_t pointer; int32_t pointerMax; - + static const int32_t SCORE_CACHE_SIZE; Collection scoreCache; - + public: virtual void score(CollectorPtr collector); virtual int32_t docID(); - + /// Advances to the next document matching the query. - /// The iterator over the matching documents is buffered using {@link + /// The iterator over the matching documents is buffered using {@link /// TermDocs#read(Collection, Collection)}. /// @return the document matching the query or -1 if there are no more documents. virtual int32_t nextDoc(); - + virtual double score(); - - /// Advances to the first match beyond the current whose document number is greater than or equal to a + + /// Advances to the first match beyond the current whose document number is greater than or equal to a /// given target. The implementation uses {@link TermDocs#skipTo(int32_t)}. /// @param target The target document number. /// @return the matching document or -1 if none exist. virtual int32_t advance(int32_t target); - + /// Returns a string representation of this TermScorer. virtual String toString(); - + protected: static const Collection SIM_NORM_DECODER(); - + virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); }; } diff --git a/include/TermSpans.h b/include/TermSpans.h index b16010ce..34273613 100644 --- a/include/TermSpans.h +++ b/include/TermSpans.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene public: TermSpans(TermPositionsPtr positions, TermPtr term); virtual ~TermSpans(); - + LUCENE_CLASS(TermSpans); - + protected: TermPositionsPtr positions; TermPtr term; @@ -27,7 +27,7 @@ namespace Lucene int32_t freq; int32_t count; int32_t position; - + public: virtual bool next(); virtual bool skipTo(int32_t target); @@ -37,7 +37,7 @@ namespace Lucene virtual Collection getPayload(); virtual bool isPayloadAvailable(); virtual String toString(); - + TermPositionsPtr getPositions(); }; } diff --git a/include/TermVectorEntry.h b/include/TermVectorEntry.h index a937ad34..16e2c3d1 100644 --- a/include/TermVectorEntry.h +++ b/include/TermVectorEntry.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,31 +15,31 @@ namespace Lucene class LPPAPI TermVectorEntry : public LuceneObject { public: - TermVectorEntry(const String& field = EmptyString, const String& term = EmptyString, int32_t frequency = 0, + TermVectorEntry(const String& field = EmptyString, const String& term = EmptyString, int32_t frequency = 0, Collection offsets = Collection(), Collection positions = Collection()); virtual ~TermVectorEntry(); - + LUCENE_CLASS(TermVectorEntry); - + protected: String field; String term; int32_t frequency; Collection offsets; Collection positions; - + public: String getField(); int32_t getFrequency(); Collection getOffsets(); Collection getPositions(); String getTerm(); - + void setFrequency(int32_t frequency); void setOffsets(Collection offsets); void setPositions(Collection positions); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual String toString(); diff --git a/include/TermVectorEntryFreqSortedComparator.h b/include/TermVectorEntryFreqSortedComparator.h index d09572ef..7e517977 100644 --- a/include/TermVectorEntryFreqSortedComparator.h +++ b/include/TermVectorEntryFreqSortedComparator.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene { public: virtual ~TermVectorEntryFreqSortedComparator(); - + LUCENE_CLASS(TermVectorEntryFreqSortedComparator); - + public: static bool compare(const TermVectorEntryPtr& first, const TermVectorEntryPtr& second); }; diff --git a/include/TermVectorMapper.h b/include/TermVectorMapper.h index 622e380a..39d33691 100644 --- a/include/TermVectorMapper.h +++ b/include/TermVectorMapper.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,26 +11,26 @@ namespace Lucene { - /// The TermVectorMapper can be used to map Term Vectors into your own structure instead of the parallel + /// The TermVectorMapper can be used to map Term Vectors into your own structure instead of the parallel /// array structure used by {@link IndexReader#getTermFreqVector(int,String)}. /// /// It is up to the implementation to make sure it is thread-safe. class LPPAPI TermVectorMapper : public LuceneObject { public: - /// @param ignoringPositions true if this mapper should tell Lucene to ignore positions even if + /// @param ignoringPositions true if this mapper should tell Lucene to ignore positions even if /// they are stored. - /// @param ignoringOffsets similar to ignoringPositions + /// @param ignoringOffsets similar to ignoringPositions TermVectorMapper(bool ignoringPositions = false, bool ignoringOffsets = false); - + virtual ~TermVectorMapper(); - + LUCENE_CLASS(TermVectorMapper); - + protected: bool ignoringPositions; bool ignoringOffsets; - + public: /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. /// This method will be called once before retrieving the vector for a field. @@ -41,26 +41,26 @@ namespace Lucene /// @param storeOffsets true if the mapper should expect offset information /// @param storePositions true if the mapper should expect positions info virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) = 0; - + /// Map the Term Vector information into your own structure /// @param term The term to add to the vector /// @param frequency The frequency of the term in the document /// @param offsets null if the offset is not specified, otherwise the offset into the field of the term /// @param positions null if the position is not specified, otherwise the position in the field of the term virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions) = 0; - - /// Indicate to Lucene that even if there are positions stored, this mapper is not interested in them and - /// they can be skipped over. Derived classes should set this to true if they want to ignore positions. + + /// Indicate to Lucene that even if there are positions stored, this mapper is not interested in them and + /// they can be skipped over. Derived classes should set this to true if they want to ignore positions. /// The default is false, meaning positions will be loaded if they are stored. virtual bool isIgnoringPositions(); - + /// @see #isIgnoringPositions() Same principal as {@link #isIgnoringPositions()}, but applied to offsets. virtual bool isIgnoringOffsets(); - - /// Passes down the index of the document whose term vector is currently being mapped, once for each top + + /// Passes down the index of the document whose term vector is currently being mapped, once for each top /// level call to a term vector reader. /// - /// Default implementation IGNORES the document number. Override if your implementation needs the document + /// Default implementation IGNORES the document number. Override if your implementation needs the document /// number. /// /// NOTE: Document numbers are internal to Lucene and subject to change depending on indexing operations. diff --git a/include/TermVectorOffsetInfo.h b/include/TermVectorOffsetInfo.h index d1f49a20..478b9c36 100644 --- a/include/TermVectorOffsetInfo.h +++ b/include/TermVectorOffsetInfo.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,36 +12,36 @@ namespace Lucene { /// The TermVectorOffsetInfo class holds information pertaining to a Term in a {@link TermPositionVector}'s - /// offset information. This offset information is the character offset as set during the Analysis phase + /// offset information. This offset information is the character offset as set during the Analysis phase /// (and thus may not be the actual offset in the original content). class LPPAPI TermVectorOffsetInfo : public LuceneObject { public: TermVectorOffsetInfo(int32_t startOffset = 0, int32_t endOffset = 0); virtual ~TermVectorOffsetInfo(); - + LUCENE_CLASS(TermVectorOffsetInfo); - + protected: int32_t startOffset; int32_t endOffset; - + public: /// Convenience declaration when creating a {@link TermPositionVector} that stores only position information. static const Collection EMPTY_OFFSET_INFO(); - + /// The accessor for the ending offset for the term int32_t getEndOffset(); void setEndOffset(int32_t endOffset); - + /// The accessor for the starting offset of the term. int32_t getStartOffset(); void setStartOffset(int32_t startOffset); - + /// Two TermVectorOffsetInfos are equals if both the start and end offsets are the same. /// @return true if both {@link #getStartOffset()} and {@link #getEndOffset()} are the same for both objects. virtual bool equals(LuceneObjectPtr other); - + virtual int32_t hashCode(); }; } diff --git a/include/TermVectorsReader.h b/include/TermVectorsReader.h index 69dc23f8..b9a04107 100644 --- a/include/TermVectorsReader.h +++ b/include/TermVectorsReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,32 +15,32 @@ namespace Lucene { public: TermVectorsReader(); - TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos); - TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, + TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos); + TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); virtual ~TermVectorsReader(); - + LUCENE_CLASS(TermVectorsReader); - + public: /// NOTE: if you make a new format, it must be larger than the current format static const int32_t FORMAT_VERSION; - + /// Changes to speed up bulk merging of term vectors static const int32_t FORMAT_VERSION2; - + /// Changed strings to UTF8 with length-in-bytes not length-in-chars static const int32_t FORMAT_UTF8_LENGTH_IN_BYTES; - + /// NOTE: always change this if you switch to a new format. static const int32_t FORMAT_CURRENT; - - /// The size in bytes that the FORMAT_VERSION will take up at the beginning of each file + + /// The size in bytes that the FORMAT_VERSION will take up at the beginning of each file static const int32_t FORMAT_SIZE; - + static const uint8_t STORE_POSITIONS_WITH_TERMVECTOR; static const uint8_t STORE_OFFSET_WITH_TERMVECTOR; - + protected: FieldInfosPtr fieldInfos; @@ -49,81 +49,81 @@ namespace Lucene IndexInputPtr tvf; int32_t _size; int32_t numTotalDocs; - + /// The docID offset where our docs begin in the index file. This will be 0 if we have our own private file. int32_t docStoreOffset; - + int32_t format; - + public: /// Used for bulk copy when merging IndexInputPtr getTvdStream(); - + /// Used for bulk copy when merging IndexInputPtr getTvfStream(); - + bool canReadRawDocs(); - + /// Retrieve the length (in bytes) of the tvd and tvf entries for the next numDocs starting with /// startDocID. This is used for bulk copying when merging segments, if the field numbers are /// congruent. Once this returns, the tvf & tvd streams are seeked to the startDocID. void rawDocs(Collection tvdLengths, Collection tvfLengths, int32_t startDocID, int32_t numDocs); - + void close(); - + /// @return The number of documents in the reader int32_t size(); - + void get(int32_t docNum, const String& field, TermVectorMapperPtr mapper); - + /// Retrieve the term vector for the given document and field /// @param docNum The document number to retrieve the vector for /// @param field The field within the document to retrieve - /// @return The TermFreqVector for the document and field or null if there is no termVector for + /// @return The TermFreqVector for the document and field or null if there is no termVector for /// this field. TermFreqVectorPtr get(int32_t docNum, const String& field); - + /// Return all term vectors stored for this document or null if the could not be read in. /// /// @param docNum The document number to retrieve the vector for /// @return All term frequency vectors Collection get(int32_t docNum); - + void get(int32_t docNumber, TermVectorMapperPtr mapper); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + protected: void ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); - + void seekTvx(int32_t docNum); - + int32_t checkValidFormat(IndexInputPtr in); - + /// Reads the String[] fields; you have to pre-seek tvd to the right point Collection readFields(int32_t fieldCount); - + /// Reads the long[] offsets into TVF; you have to pre-seek tvx/tvd to the right point Collection readTvfPointers(int32_t fieldCount); - + Collection readTermVectors(int32_t docNum, Collection fields, Collection tvfPointers); void readTermVectors(Collection fields, Collection tvfPointers, TermVectorMapperPtr mapper); - + /// @param field The field to read in /// @param tvfPointer The pointer within the tvf file where we should start reading /// @param mapper The mapper used to map the TermVector void readTermVector(const String& field, int64_t tvfPointer, TermVectorMapperPtr mapper); }; - + /// Models the existing parallel array structure class ParallelArrayTermVectorMapper : public TermVectorMapper { public: ParallelArrayTermVectorMapper(); virtual ~ParallelArrayTermVectorMapper(); - + LUCENE_CLASS(ParallelArrayTermVectorMapper); - + protected: Collection terms; Collection termFreqs; @@ -133,15 +133,15 @@ namespace Lucene bool storingOffsets; bool storingPositions; String field; - + public: /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. /// This method will be called once before retrieving the vector for a field. virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); - + /// Map the Term Vector information into your own structure virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); - + /// Construct the vector /// @return The {@link TermFreqVector} based on the mappings. TermFreqVectorPtr materializeVector(); diff --git a/include/TermVectorsTermsWriter.h b/include/TermVectorsTermsWriter.h index f263169d..3797490a 100644 --- a/include/TermVectorsTermsWriter.h +++ b/include/TermVectorsTermsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,9 +18,9 @@ namespace Lucene public: TermVectorsTermsWriter(DocumentsWriterPtr docWriter); virtual ~TermVectorsTermsWriter(); - + LUCENE_CLASS(TermVectorsTermsWriter); - + public: DocumentsWriterWeakPtr _docWriter; TermVectorsWriterPtr termVectorsWriter; @@ -31,46 +31,46 @@ namespace Lucene IndexOutputPtr tvf; int32_t lastDocID; int32_t allocCount; - + public: virtual TermsHashConsumerPerThreadPtr addThread(TermsHashPerThreadPtr perThread); virtual void createPostings(Collection postings, int32_t start, int32_t count); virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state); virtual void closeDocStore(SegmentWriteStatePtr state); - + TermVectorsTermsWriterPerDocPtr getPerDoc(); - + /// Fills in no-term-vectors for all docs we haven't seen since the last doc that had term vectors. void fill(int32_t docID); - + void initTermVectorsWriter(); void finishDocument(TermVectorsTermsWriterPerDocPtr perDoc); bool freeRAM(); void free(TermVectorsTermsWriterPerDocPtr doc); - + virtual void abort(); virtual int32_t bytesPerPosting(); }; - + class TermVectorsTermsWriterPerDoc : public DocWriter { public: TermVectorsTermsWriterPerDoc(TermVectorsTermsWriterPtr termsWriter = TermVectorsTermsWriterPtr()); virtual ~TermVectorsTermsWriterPerDoc(); - + LUCENE_CLASS(TermVectorsTermsWriterPerDoc); - + protected: TermVectorsTermsWriterWeakPtr _termsWriter; - + public: PerDocBufferPtr buffer; RAMOutputStreamPtr perDocTvf; int32_t numVectorFields; - + Collection fieldNumbers; Collection fieldPointers; - + public: void reset(); virtual void abort(); @@ -78,15 +78,15 @@ namespace Lucene virtual int64_t sizeInBytes(); virtual void finish(); }; - + class TermVectorsTermsWriterPostingList : public RawPostingList { public: TermVectorsTermsWriterPostingList(); virtual ~TermVectorsTermsWriterPostingList(); - + LUCENE_CLASS(TermVectorsTermsWriterPostingList); - + public: int32_t freq; // How many times this term occurred in the current doc int32_t lastOffset; // Last offset we saw diff --git a/include/TermVectorsTermsWriterPerField.h b/include/TermVectorsTermsWriterPerField.h index 298353b7..1ac34e3b 100644 --- a/include/TermVectorsTermsWriterPerField.h +++ b/include/TermVectorsTermsWriterPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: TermVectorsTermsWriterPerField(TermsHashPerFieldPtr termsHashPerField, TermVectorsTermsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo); virtual ~TermVectorsTermsWriterPerField(); - + LUCENE_CLASS(TermVectorsTermsWriterPerField); - + public: TermVectorsTermsWriterPerThreadWeakPtr _perThread; TermsHashPerFieldWeakPtr _termsHashPerField; @@ -26,25 +26,25 @@ namespace Lucene FieldInfoPtr fieldInfo; DocStateWeakPtr _docState; FieldInvertStateWeakPtr _fieldState; - + bool doVectors; bool doVectorPositions; bool doVectorOffsets; - + int32_t maxNumPostings; OffsetAttributePtr offsetAttribute; - + public: virtual int32_t getStreamCount(); virtual bool start(Collection fields, int32_t count); virtual void abort(); - - /// Called once per field per document if term vectors are enabled, to write the vectors to RAMOutputStream, + + /// Called once per field per document if term vectors are enabled, to write the vectors to RAMOutputStream, /// which is then quickly flushed to the real term vectors files in the Directory. virtual void finish(); - + void shrinkHash(); - + virtual void start(FieldablePtr field); virtual void newTerm(RawPostingListPtr p0); virtual void addTerm(RawPostingListPtr p0); diff --git a/include/TermVectorsTermsWriterPerThread.h b/include/TermVectorsTermsWriterPerThread.h index 675b685e..a95def4c 100644 --- a/include/TermVectorsTermsWriterPerThread.h +++ b/include/TermVectorsTermsWriterPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,25 +16,25 @@ namespace Lucene public: TermVectorsTermsWriterPerThread(TermsHashPerThreadPtr termsHashPerThread, TermVectorsTermsWriterPtr termsWriter); virtual ~TermVectorsTermsWriterPerThread(); - + LUCENE_CLASS(TermVectorsTermsWriterPerThread); - + public: TermVectorsTermsWriterWeakPtr _termsWriter; TermsHashPerThreadWeakPtr _termsHashPerThread; DocStateWeakPtr _docState; - + TermVectorsTermsWriterPerDocPtr doc; ByteSliceReaderPtr vectorSliceReader; Collection utf8Results; String lastVectorFieldName; - + public: virtual void startDocument(); virtual DocWriterPtr finishDocument(); virtual TermsHashConsumerPerFieldPtr addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo); virtual void abort(); - + /// Called only by assert bool clearLastVectorFieldName(); bool vectorFieldsInOrder(FieldInfoPtr fi); diff --git a/include/TermVectorsWriter.h b/include/TermVectorsWriter.h index 15f79f69..e6d4bd71 100644 --- a/include/TermVectorsWriter.h +++ b/include/TermVectorsWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: TermVectorsWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fieldInfos); virtual ~TermVectorsWriter(); - + LUCENE_CLASS(TermVectorsWriter); - + protected: IndexOutputPtr tvx; IndexOutputPtr tvd; @@ -27,14 +27,14 @@ namespace Lucene Collection utf8Results; public: - /// Add a complete document specified by all its term vectors. If document has no term vectors, + /// Add a complete document specified by all its term vectors. If document has no term vectors, /// add value for tvx. void addAllDocVectors(Collection vectors); - - /// Do a bulk copy of numDocs documents from reader to our streams. This is used to expedite merging, + + /// Do a bulk copy of numDocs documents from reader to our streams. This is used to expedite merging, /// if the field numbers are congruent. void addRawDocuments(TermVectorsReaderPtr reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs); - + /// Close all streams. void close(); }; diff --git a/include/TermsHash.h b/include/TermsHash.h index e2b071d8..8feeb86e 100644 --- a/include/TermsHash.h +++ b/include/TermsHash.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,8 +11,8 @@ namespace Lucene { - /// This class implements {@link InvertedDocConsumer}, which is passed each token produced by the analyzer on - /// each field. It stores these tokens in a hash table, and allocates separate byte streams per token. Consumers + /// This class implements {@link InvertedDocConsumer}, which is passed each token produced by the analyzer on + /// each field. It stores these tokens in a hash table, and allocates separate byte streams per token. Consumers /// of this class, eg {@link FreqProxTermsWriter} and {@link TermVectorsTermsWriter}, write their own byte streams /// under each term. class TermsHash : public InvertedDocConsumer @@ -20,9 +20,9 @@ namespace Lucene public: TermsHash(DocumentsWriterPtr docWriter, bool trackAllocations, TermsHashConsumerPtr consumer, TermsHashPtr nextTermsHash); virtual ~TermsHash(); - + LUCENE_CLASS(TermsHash); - + public: TermsHashConsumerPtr consumer; TermsHashPtr nextTermsHash; @@ -30,37 +30,37 @@ namespace Lucene int32_t postingsFreeChunk; DocumentsWriterWeakPtr _docWriter; bool trackAllocations; - + protected: Collection postingsFreeList; int32_t postingsFreeCount; int32_t postingsAllocCount; - + public: /// Add a new thread virtual InvertedDocConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread); virtual TermsHashPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread, TermsHashPerThreadPtr primaryPerThread); - + virtual void setFieldInfos(FieldInfosPtr fieldInfos); - + /// Abort (called after hitting AbortException) - /// NOTE: do not make this sync'd; it's not necessary (DW ensures all other threads are idle), and it + /// NOTE: do not make this sync'd; it's not necessary (DW ensures all other threads are idle), and it /// leads to deadlock virtual void abort(); - + void shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state); - + /// Close doc stores virtual void closeDocStore(SegmentWriteStatePtr state); - + /// Flush a new segment virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state); - + /// Attempt to free RAM, returning true if any RAM was freed virtual bool freeRAM(); - + void recyclePostings(Collection postings, int32_t numPostings); - + void getPostings(Collection postings); }; } diff --git a/include/TermsHashConsumer.h b/include/TermsHashConsumer.h index 9bd63bd7..ef178bb5 100644 --- a/include/TermsHashConsumer.h +++ b/include/TermsHashConsumer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,12 +15,12 @@ namespace Lucene { public: virtual ~TermsHashConsumer(); - + LUCENE_CLASS(TermsHashConsumer); - + public: FieldInfosPtr fieldInfos; - + public: virtual int32_t bytesPerPosting() = 0; virtual void createPostings(Collection postings, int32_t start, int32_t count) = 0; @@ -28,7 +28,7 @@ namespace Lucene virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; virtual void abort() = 0; virtual void closeDocStore(SegmentWriteStatePtr state) = 0; - + virtual void setFieldInfos(FieldInfosPtr fieldInfos); }; } diff --git a/include/TermsHashConsumerPerField.h b/include/TermsHashConsumerPerField.h index 960e51ea..2f7405d2 100644 --- a/include/TermsHashConsumerPerField.h +++ b/include/TermsHashConsumerPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,9 +17,9 @@ namespace Lucene { public: virtual ~TermsHashConsumerPerField(); - + LUCENE_CLASS(TermsHashConsumerPerField); - + public: virtual bool start(Collection fields, int32_t count) = 0; virtual void finish() = 0; diff --git a/include/TermsHashConsumerPerThread.h b/include/TermsHashConsumerPerThread.h index 883c915f..575fc4f9 100644 --- a/include/TermsHashConsumerPerThread.h +++ b/include/TermsHashConsumerPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~TermsHashConsumerPerThread(); - + LUCENE_CLASS(TermsHashConsumerPerThread); - + public: virtual void startDocument() = 0; virtual DocWriterPtr finishDocument() = 0; diff --git a/include/TermsHashPerField.h b/include/TermsHashPerField.h index 1b06b50d..5e411343 100644 --- a/include/TermsHashPerField.h +++ b/include/TermsHashPerField.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: TermsHashPerField(DocInverterPerFieldPtr docInverterPerField, TermsHashPerThreadPtr perThread, TermsHashPerThreadPtr nextPerThread, FieldInfoPtr fieldInfo); virtual ~TermsHashPerField(); - + LUCENE_CLASS(TermsHashPerField); - + public: TermsHashConsumerPerFieldPtr consumer; TermsHashPerFieldPtr nextPerField; @@ -28,23 +28,23 @@ namespace Lucene DocStatePtr docState; FieldInvertStatePtr fieldState; TermAttributePtr termAtt; - + // Copied from our perThread CharBlockPoolPtr charPool; IntBlockPoolPtr intPool; ByteBlockPoolPtr bytePool; - + int32_t streamCount; int32_t numPostingInt; - + FieldInfoPtr fieldInfo; - + bool postingsCompacted; int32_t numPostings; - + IntArray intUptos; int32_t intUptoStart; - + protected: int32_t postingsHashSize; int32_t postingsHashHalfSize; @@ -53,44 +53,44 @@ namespace Lucene RawPostingListPtr p; bool doCall; bool doNextCall; - + public: virtual void initialize(); void shrinkHash(int32_t targetSize); void reset(); - + /// Called on hitting an aborting exception virtual void abort(); - + void initReader(ByteSliceReaderPtr reader, RawPostingListPtr p, int32_t stream); - + /// Collapse the hash table and sort in-place. Collection sortPostings(); - + /// Called before a field instance is being processed virtual void start(FieldablePtr field); - - /// Called once per field, and is given all Fieldable occurrences for this field in the document. + + /// Called once per field, and is given all Fieldable occurrences for this field in the document. virtual bool start(Collection fields, int32_t count); - + void add(int32_t textStart); - + /// Primary entry point (for first TermsHash) virtual void add(); - + void writeByte(int32_t stream, int8_t b); void writeBytes(int32_t stream, const uint8_t* b, int32_t offset, int32_t length); void writeVInt(int32_t stream, int32_t i); - + /// Called once per field per document, after all Fieldable occurrences are inverted virtual void finish(); - + /// Called when postings hash is too small (> 50% occupied) or too large (< 20% occupied). void rehashPostings(int32_t newSize); - + protected: void compactPostings(); - + /// Test whether the text for current RawPostingList p equals current tokenText. bool postingEquals(const wchar_t* tokenText, int32_t tokenTextLen); }; diff --git a/include/TermsHashPerThread.h b/include/TermsHashPerThread.h index e05d7daa..ae0d6875 100644 --- a/include/TermsHashPerThread.h +++ b/include/TermsHashPerThread.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: TermsHashPerThread(DocInverterPerThreadPtr docInverterPerThread, TermsHashPtr termsHash, TermsHashPtr nextTermsHash, TermsHashPerThreadPtr primaryPerThread); virtual ~TermsHashPerThread(); - + LUCENE_CLASS(TermsHashPerThread); - + public: DocInverterPerThreadWeakPtr _docInverterPerThread; TermsHashWeakPtr _termsHash; @@ -26,31 +26,31 @@ namespace Lucene TermsHashPerThreadWeakPtr _primaryPerThread; TermsHashConsumerPerThreadPtr consumer; TermsHashPerThreadPtr nextPerThread; - + CharBlockPoolPtr charPool; IntBlockPoolPtr intPool; ByteBlockPoolPtr bytePool; bool primary; DocStatePtr docState; - + Collection freePostings; int32_t freePostingsCount; - + public: virtual void initialize(); - + virtual InvertedDocConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo); virtual void abort(); - + /// perField calls this when it needs more postings void morePostings(); - + virtual void startDocument(); virtual DocWriterPtr finishDocument(); - + /// Clear all state - void reset(bool recyclePostings); - + void reset(bool recyclePostings); + protected: static bool noNullPostings(Collection postings, int32_t count, const String& details); }; diff --git a/include/TestPoint.h b/include/TestPoint.h index 86a85d29..da1ac3dd 100644 --- a/include/TestPoint.h +++ b/include/TestPoint.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene { public: virtual ~TestPoint(); - + protected: static MapStringInt testMethods; static bool enable; - + public: static void enableTestPoints(); static void clear(); @@ -28,13 +28,13 @@ namespace Lucene static bool getTestPoint(const String& object, const String& method); static bool getTestPoint(const String& method); }; - + class TestScope { public: TestScope(const String& object, const String& method); virtual ~TestScope(); - + protected: String object; String method; diff --git a/include/ThreadPool.h b/include/ThreadPool.h index ce58bfd1..50454646 100644 --- a/include/ThreadPool.h +++ b/include/ThreadPool.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,25 +15,25 @@ namespace Lucene { typedef boost::shared_ptr workPtr; - - /// A Future represents the result of an asynchronous computation. Methods are provided to check if the computation - /// is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be + + /// A Future represents the result of an asynchronous computation. Methods are provided to check if the computation + /// is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be /// retrieved using method get when the computation has completed, blocking if necessary until it is ready. class Future : public LuceneObject { public: virtual ~Future(); - + protected: boost::any value; - + public: void set(const boost::any& value) { SyncLock syncLock(this); this->value = value; } - + template TYPE get() { @@ -43,27 +43,27 @@ namespace Lucene return value.empty() ? TYPE() : boost::any_cast(value); } }; - + /// Utility class to handle a pool of threads. class ThreadPool : public LuceneObject { public: ThreadPool(); virtual ~ThreadPool(); - + LUCENE_CLASS(ThreadPool); - + protected: boost::asio::io_service io_service; workPtr work; boost::thread_group threadGroup; - + static const int32_t THREADPOOL_SIZE; - + public: /// Get singleton thread pool instance. static ThreadPoolPtr getInstance(); - + template FuturePtr scheduleTask(FUNC func) { @@ -71,7 +71,7 @@ namespace Lucene io_service.post(boost::bind(&ThreadPool::execute, this, func, future)); return future; } - + protected: // this will be executed when one of the threads is available template diff --git a/include/TimeLimitingCollector.h b/include/TimeLimitingCollector.h index 00285521..c417eaf1 100644 --- a/include/TimeLimitingCollector.h +++ b/include/TimeLimitingCollector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { - /// The {@link TimeLimitingCollector} is used to timeout search requests that take longer than the maximum + /// The {@link TimeLimitingCollector} is used to timeout search requests that take longer than the maximum /// allowed search time limit. After this time is exceeded, the search thread is stopped by throwing a /// {@link TimeExceededException}. class LPPAPI TimeLimitingCollector : public Collector @@ -21,75 +21,75 @@ namespace Lucene /// @param collector the wrapped {@link Collector} /// @param timeAllowed max time allowed for collecting hits after which TimeExceeded exception is thrown TimeLimitingCollector(CollectorPtr collector, int64_t timeAllowed); - + virtual ~TimeLimitingCollector(); - + LUCENE_CLASS(TimeLimitingCollector); - + public: /// Default timer resolution. - /// @see #setResolution(int64_t) + /// @see #setResolution(int64_t) static const int32_t DEFAULT_RESOLUTION; - + /// Default for {@link #isGreedy()}. /// @see #isGreedy() bool DEFAULT_GREEDY; - + protected: static int64_t resolution; bool greedy; - + int64_t t0; int64_t timeout; CollectorPtr collector; - + int32_t docBase; - + public: /// Return the timer resolution. /// @see #setResolution(int64_t) static int64_t getResolution(); - + /// Set the timer resolution. - /// The default timer resolution is 20 milliseconds. - /// This means that a search required to take no longer than 800 milliseconds may be stopped after - /// 780 to 820 milliseconds. Note that: + /// The default timer resolution is 20 milliseconds. + /// This means that a search required to take no longer than 800 milliseconds may be stopped after + /// 780 to 820 milliseconds. Note that: ///
      ///
    • Finer (smaller) resolution is more accurate but less efficient. ///
    • Setting resolution to less than 5 milliseconds will be silently modified to 5 milliseconds. - ///
    • Setting resolution smaller than current resolution might take effect only after current resolution. - /// (Assume current resolution of 20 milliseconds is modified to 5 milliseconds, then it can take up to 20 + ///
    • Setting resolution smaller than current resolution might take effect only after current resolution. + /// (Assume current resolution of 20 milliseconds is modified to 5 milliseconds, then it can take up to 20 /// milliseconds for the change to have effect. - ///
    + /// static void setResolution(int64_t newResolution); - + /// Stop timer thread. static void stopTimer(); - - /// Checks if this time limited collector is greedy in collecting the last hit. A non greedy collector, - /// upon a timeout, would throw a TimeExceeded without allowing the wrapped collector to collect current - /// doc. A greedy one would first allow the wrapped hit collector to collect current doc and only then + + /// Checks if this time limited collector is greedy in collecting the last hit. A non greedy collector, + /// upon a timeout, would throw a TimeExceeded without allowing the wrapped collector to collect current + /// doc. A greedy one would first allow the wrapped hit collector to collect current doc and only then /// throw a TimeExceeded exception. /// @see #setGreedy(boolean) bool isGreedy(); - + /// Sets whether this time limited collector is greedy. /// @param greedy true to make this time limited greedy /// @see #isGreedy() void setGreedy(bool greedy); - - /// Calls {@link Collector#collect(int)} on the decorated {@link Collector} unless the allowed time has + + /// Calls {@link Collector#collect(int)} on the decorated {@link Collector} unless the allowed time has /// passed, in which case it throws an exception. virtual void collect(int32_t doc); - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); virtual void setScorer(ScorerPtr scorer); virtual bool acceptsDocsOutOfOrder(); - + protected: /// Initialize a single static timer thread to be used by all TimeLimitedCollector instances. static TimerThreadPtr TIMER_THREAD(); - + friend class TimerThread; }; } diff --git a/include/Token.h b/include/Token.h index 0491328a..15171d70 100644 --- a/include/Token.h +++ b/include/Token.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,34 +12,34 @@ namespace Lucene { - /// A Token is an occurrence of a term from the text of a field. It consists of a term's text, the start and end + /// A Token is an occurrence of a term from the text of a field. It consists of a term's text, the start and end /// offset of the term in the text of the field and a type string. /// - /// The start and end offsets permit applications to re-associate a token with its source text, eg., to display - /// highlighted query terms in a document browser, or to show matching text fragments in a + /// The start and end offsets permit applications to re-associate a token with its source text, eg., to display + /// highlighted query terms in a document browser, or to show matching text fragments in a /// KWIC display, etc. /// - /// The type is a string, assigned by a lexical analyzer (a.k.a. tokenizer), naming the lexical or syntactic class + /// The type is a string, assigned by a lexical analyzer (a.k.a. tokenizer), naming the lexical or syntactic class /// that the token belongs to. For example an end of sentence marker token might be implemented with type "eos". /// The default token type is "word". /// - /// A Token can optionally have metadata (a.k.a. Payload) in the form of a variable length byte array. Use {@link - /// TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve the payloads + /// A Token can optionally have metadata (a.k.a. Payload) in the form of a variable length byte array. Use {@link + /// TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve the payloads /// from the index. /// - /// Tokenizers and TokenFilters should try to re-use a Token instance when possible for best performance, by implementing - /// the {@link TokenStream#incrementToken()} API. Failing that, to create a new Token you should first use one of - /// the constructors that starts with null text. To load the token from a char[] use - /// {@link #setTermBuffer(char[], int, int)}. To load from a String use {@link #setTermBuffer(String)} or {@link - /// #setTermBuffer(String, int, int)}. Alternatively you can get the Token's termBuffer by calling either {@link - /// #termBuffer()}, if you know that your text is shorter than the capacity of the termBuffer or {@link - /// #resizeTermBuffer(int)}, if there is any possibility that you may need to grow the buffer. Fill in the characters + /// Tokenizers and TokenFilters should try to re-use a Token instance when possible for best performance, by implementing + /// the {@link TokenStream#incrementToken()} API. Failing that, to create a new Token you should first use one of + /// the constructors that starts with null text. To load the token from a char[] use + /// {@link #setTermBuffer(char[], int, int)}. To load from a String use {@link #setTermBuffer(String)} or {@link + /// #setTermBuffer(String, int, int)}. Alternatively you can get the Token's termBuffer by calling either {@link + /// #termBuffer()}, if you know that your text is shorter than the capacity of the termBuffer or {@link + /// #resizeTermBuffer(int)}, if there is any possibility that you may need to grow the buffer. Fill in the characters /// of your term into this buffer, with {@link String#getChars(int, int, char[], int)} if loading from a string, /// or with {@link System#arraycopy(Object, int, Object, int, int)}, and finally call {@link #setTermLength(int)} to /// set the length of the term text. /// /// Typical Token reuse patterns: - /// + /// /// Copying text from a string (type is reset to {@link #DEFAULT_TYPE} if not specified): ///
         /// return reusableToken->reinit(string, startOffset, endOffset[, type]);
    @@ -66,10 +66,10 @@ namespace Lucene
         /// 
    /// /// A few things to note: - /// clear() initializes all of the fields to default values. This was changed in contrast to Lucene 2.4, but + /// clear() initializes all of the fields to default values. This was changed in contrast to Lucene 2.4, but /// should affect no one. - /// Because TokenStreams can be chained, one cannot assume that the Token's current type is correct. The startOffset - /// and endOffset represent the start and offset in the source text, so be careful in adjusting them. When caching a + /// Because TokenStreams can be chained, one cannot assume that the Token's current type is correct. The startOffset + /// and endOffset represent the start and offset in the source text, so be careful in adjusting them. When caching a /// reusable token, clone it. When injecting a cached token into a stream that can be reset, clone it again. /// /// @see Payload @@ -78,31 +78,31 @@ namespace Lucene public: /// Constructs a Token will null text. Token(); - + /// Constructs a Token with null text and start and end offsets. /// @param start start offset in the source text /// @param end end offset in the source text Token(int32_t start, int32_t end); - + /// Constructs a Token with null text and start and end offsets plus the Token type. /// @param start start offset in the source text /// @param end end offset in the source text /// @param type the lexical type of this Token Token(int32_t start, int32_t end, const String& type); - + /// Constructs a Token with null text and start and end offsets plus flags. /// @param start start offset in the source text /// @param end end offset in the source text /// @param flags The bits to set for this token Token(int32_t start, int32_t end, int32_t flags); - + /// Constructs a Token with the given term text, start and end offsets. The type defaults to "word." /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. /// @param text term text /// @param start start offset in the source text /// @param end end offset in the source text Token(const String& text, int32_t start, int32_t end); - + /// Constructs a Token with the given term text, start and end offsets and type. /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. /// @param text term text @@ -110,7 +110,7 @@ namespace Lucene /// @param end end offset in the source text /// @param type the lexical type of this Token Token(const String& text, int32_t start, int32_t end, const String& type); - + /// Constructs a Token with the given term text, start and end offsets and flags. /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. /// @param text term text @@ -118,20 +118,20 @@ namespace Lucene /// @param end end offset in the source text /// @param flags The bits to set for this token Token(const String& text, int32_t start, int32_t end, int32_t flags); - + /// Constructs a Token with the given term buffer (offset and length), start and end offsets Token(CharArray startTermBuffer, int32_t termBufferOffset, int32_t termBufferLength, int32_t start, int32_t end); - + virtual ~Token(); - + LUCENE_CLASS(Token); - + public: static const String& DEFAULT_TYPE(); - + protected: static const int32_t MIN_BUFFER_SIZE; - + CharArray _termBuffer; int32_t _termLength; int32_t _startOffset; @@ -140,213 +140,213 @@ namespace Lucene int32_t flags; PayloadPtr payload; int32_t positionIncrement; - + public: - /// Set the position increment. This determines the position of this token relative to the previous Token + /// Set the position increment. This determines the position of this token relative to the previous Token /// in a {@link TokenStream}, used in phrase searching. /// /// The default value is one. /// /// Some common uses for this are: /// - /// Set it to zero to put multiple terms in the same position. This is useful if, eg., a word has multiple + /// Set it to zero to put multiple terms in the same position. This is useful if, eg., a word has multiple /// stems. Searches for phrases including either stem will match. In this case, all but the first stem's - /// increment should be set to zero: the increment of the first instance should be one. Repeating a token + /// increment should be set to zero: the increment of the first instance should be one. Repeating a token /// with an increment of zero can also be used to boost the scores of matches on that token. /// - /// Set it to values greater than one to inhibit exact phrase matches. If, for example, one does not want - /// phrases to match across removed stop words, then one could build a stop word filter that removes stop - /// words and also sets the increment to the number of stop words removed before each non-stop word. Then + /// Set it to values greater than one to inhibit exact phrase matches. If, for example, one does not want + /// phrases to match across removed stop words, then one could build a stop word filter that removes stop + /// words and also sets the increment to the number of stop words removed before each non-stop word. Then /// exact phrase queries will only match when the terms occur with no intervening stop words. /// /// @param positionIncrement the distance from the prior term /// @see TermPositions virtual void setPositionIncrement(int32_t positionIncrement); - + /// Returns the position increment of this Token. /// @see #setPositionIncrement virtual int32_t getPositionIncrement(); /// Returns the Token's term text. /// - /// This method has a performance penalty because the text is stored internally in a char[]. If possible, - /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use + /// This method has a performance penalty because the text is stored internally in a char[]. If possible, + /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use /// this method, which is nothing more than a convenience call to String(token->termBuffer(), token->termLength()) virtual String term(); - + /// Copies the contents of buffer, starting at offset for length characters, into the termBuffer array. /// @param buffer the buffer to copy /// @param offset the index in the buffer of the first character to copy /// @param length the number of characters to copy virtual void setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length); - + /// Copies the contents of buffer into the termBuffer array. /// @param buffer the buffer to copy virtual void setTermBuffer(const String& buffer); - + /// Copies the contents of buffer, starting at offset and continuing for length characters, into the termBuffer array. /// @param buffer the buffer to copy /// @param offset the index in the buffer of the first character to copy /// @param length the number of characters to copy virtual void setTermBuffer(const String& buffer, int32_t offset, int32_t length); - + /// Returns the internal termBuffer character array which you can then directly alter. If the array is too - /// small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer be sure + /// small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer be sure /// to call {@link #setTermLength} to record the number of valid characters that were placed into the termBuffer. virtual CharArray termBuffer(); - + /// Optimized implementation of termBuffer. virtual wchar_t* termBufferArray(); - - /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next operation is - /// to change the contents of the term buffer use {@link #setTermBuffer(char[], int, int)}, {@link - /// #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the resize with the + + /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next operation is + /// to change the contents of the term buffer use {@link #setTermBuffer(char[], int, int)}, {@link + /// #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the resize with the /// setting of the termBuffer. /// @param newSize minimum size of the new termBuffer /// @return newly created termBuffer with length >= newSize virtual CharArray resizeTermBuffer(int32_t newSize); - + /// Return number of valid characters (length of the term) in the termBuffer array. virtual int32_t termLength(); - + /// Set number of valid characters (length of the term) in the termBuffer array. Use this to truncate the termBuffer - /// or to synchronize with external manipulation of the termBuffer. Note: to grow the size of the array, use {@link + /// or to synchronize with external manipulation of the termBuffer. Note: to grow the size of the array, use {@link /// #resizeTermBuffer(int)} first. /// @param length the truncated length virtual void setTermLength(int32_t length); - - /// Returns this Token's starting offset, the position of the first character corresponding to this token in the + + /// Returns this Token's starting offset, the position of the first character corresponding to this token in the /// source text. /// - /// Note that the difference between endOffset() and startOffset() may not be equal to {@link #termLength}, as the + /// Note that the difference between endOffset() and startOffset() may not be equal to {@link #termLength}, as the /// term text may have been altered by a stemmer or some other filter. virtual int32_t startOffset(); - + /// Set the starting offset. /// @see #startOffset() virtual void setStartOffset(int32_t offset); - - /// Returns this Token's ending offset, one greater than the position of the last character corresponding to this + + /// Returns this Token's ending offset, one greater than the position of the last character corresponding to this /// token in the source text. The length of the token in the source text is (endOffset - startOffset). virtual int32_t endOffset(); - + /// Set the ending offset. /// @see #endOffset() virtual void setEndOffset(int32_t offset); - + /// Set the starting and ending offset. /// @see #startOffset() and #endOffset() virtual void setOffset(int32_t startOffset, int32_t endOffset); - + /// Returns this Token's lexical type. Defaults to "word". virtual String type(); - + /// Set the lexical type. /// @see #type() virtual void setType(const String& type); - - /// Get the bitset for any bits that have been set. This is completely distinct from {@link #type()}, although - /// they do share similar purposes. The flags can be used to encode information about the token for use by other + + /// Get the bitset for any bits that have been set. This is completely distinct from {@link #type()}, although + /// they do share similar purposes. The flags can be used to encode information about the token for use by other /// {@link TokenFilter}s. /// /// @return The bits virtual int32_t getFlags(); - + /// @see #getFlags() virtual void setFlags(int32_t flags); - + /// Returns this Token's payload. virtual PayloadPtr getPayload(); - + /// Sets this Token's payload. virtual void setPayload(PayloadPtr payload); - + virtual String toString(); - + /// Resets the term text, payload, flags, and positionIncrement, startOffset, endOffset and token type to default. virtual void clear(); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - - /// Makes a clone, but replaces the term buffer and start/end offset in the process. This is more efficient than + + /// Makes a clone, but replaces the term buffer and start/end offset in the process. This is more efficient than /// doing a full clone (and then calling setTermBuffer) because it saves a wasted copy of the old termBuffer. TokenPtr clone(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); - + virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); - + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(char[], int, int)}, {@link #setStartOffset}, /// {@link #setEndOffset}, {@link #setType} /// @return this Token instance TokenPtr reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType); - + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(char[], int, int)}, {@link #setStartOffset}, /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE /// @return this Token instance TokenPtr reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); - + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, /// {@link #setEndOffset}, {@link #setType} /// @return this Token instance TokenPtr reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset, const String& newType); - + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, /// {@link #setEndOffset}, {@link #setType} /// @return this Token instance TokenPtr reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType); - + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE /// @return this Token instance TokenPtr reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset); - + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String, int, int)}, {@link #setStartOffset}, /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE /// @return this Token instance TokenPtr reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); - + /// Copy the prototype token's fields into this one. Note: Payloads are shared. void reinit(TokenPtr prototype); - + /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. void reinit(TokenPtr prototype, const String& newTerm); - + /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. void reinit(TokenPtr prototype, CharArray newTermBuffer, int32_t offset, int32_t length); - + virtual void copyTo(AttributePtr target); - + /// Convenience factory that returns Token as implementation for the basic attributes static AttributeFactoryPtr TOKEN_ATTRIBUTE_FACTORY(); - + protected: /// Construct Token and initialize values void ConstructToken(int32_t start, int32_t end, const String& type, int32_t flags); - - /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always used in + + /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always used in /// places that set the content. /// @param newSize minimum size of the buffer void growTermBuffer(int32_t newSize); - + void initTermBuffer(); - + /// Like clear() but doesn't clear termBuffer/text void clearNoTermBuffer(); }; - - /// Creates a TokenAttributeFactory returning {@link Token} as instance for the basic attributes and for all other + + /// Creates a TokenAttributeFactory returning {@link Token} as instance for the basic attributes and for all other /// attributes calls the given delegate factory. class LPPAPI TokenAttributeFactory : public AttributeFactory { public: TokenAttributeFactory(AttributeFactoryPtr delegate); virtual ~TokenAttributeFactory(); - + LUCENE_CLASS(TokenAttributeFactory); - + protected: AttributeFactoryPtr delegate; - + public: virtual AttributePtr createAttributeInstance(const String& className); virtual bool equals(LuceneObjectPtr other); diff --git a/include/TokenFilter.h b/include/TokenFilter.h index e97d415c..95702e4b 100644 --- a/include/TokenFilter.h +++ b/include/TokenFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,21 +23,21 @@ namespace Lucene public: virtual ~TokenFilter(); - + LUCENE_CLASS(TokenFilter); - + protected: /// The source of tokens for this filter. TokenStreamPtr input; - + public: /// Performs end-of-stream operations, if any, and calls then end() on the input TokenStream. /// NOTE: Be sure to call TokenFilter::end() first when overriding this method. virtual void end(); - + /// Close the input TokenStream. virtual void close(); - + /// Reset the filter as well as the input TokenStream. virtual void reset(); }; diff --git a/include/TokenStream.h b/include/TokenStream.h index d9be75a5..4e930d2b 100644 --- a/include/TokenStream.h +++ b/include/TokenStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,19 +11,19 @@ namespace Lucene { - /// A TokenStream enumerates the sequence of tokens, either from {@link Field}s of a {@link Document} or from + /// A TokenStream enumerates the sequence of tokens, either from {@link Field}s of a {@link Document} or from /// query text. /// - /// This is an abstract class; concrete subclasses are: {@link Tokenizer}, a TokenStream whose input is a Reader; + /// This is an abstract class; concrete subclasses are: {@link Tokenizer}, a TokenStream whose input is a Reader; /// and {@link TokenFilter}, a TokenStream whose input is another TokenStream. /// - /// A new TokenStream API has been introduced with Lucene 2.9. This API has moved from being {@link Token}-based + /// A new TokenStream API has been introduced with Lucene 2.9. This API has moved from being {@link Token}-based /// to {@link Attribute}-based. While {@link Token} still exists in 2.9 as a convenience class, the preferred way /// to store the information of a {@link Token} is to use {@link Attribute}s. /// - /// TokenStream now extends {@link AttributeSource}, which provides access to all of the token {@link Attribute}s - /// for the TokenStream. Note that only one instance per {@link Attribute} is created and reused for every - /// token. This approach reduces object creation and allows local caching of references to the {@link Attribute}s. + /// TokenStream now extends {@link AttributeSource}, which provides access to all of the token {@link Attribute}s + /// for the TokenStream. Note that only one instance per {@link Attribute} is created and reused for every + /// token. This approach reduces object creation and allows local caching of references to the {@link Attribute}s. /// See {@link #incrementToken()} for further details. /// /// The workflow of the new TokenStream API is as follows: @@ -34,67 +34,67 @@ namespace Lucene /// - The consumer calls {@link #end()} so that any end-of-stream operations can be performed. /// - The consumer calls {@link #close()} to release any resource when finished using the TokenStream. /// - /// To make sure that filters and consumers know which attributes are available, the attributes must be added during - /// instantiation. Filters and consumers are not required to check for availability of attributes in {@link + /// To make sure that filters and consumers know which attributes are available, the attributes must be added during + /// instantiation. Filters and consumers are not required to check for availability of attributes in {@link /// #incrementToken()}. /// - /// Sometimes it is desirable to capture a current state of a TokenStream, eg., for buffering purposes (see {@link - /// CachingTokenFilter}, {@link TeeSinkTokenFilter}). For this use case {@link AttributeSource#captureState} and {@link + /// Sometimes it is desirable to capture a current state of a TokenStream, eg., for buffering purposes (see {@link + /// CachingTokenFilter}, {@link TeeSinkTokenFilter}). For this use case {@link AttributeSource#captureState} and {@link /// AttributeSource#restoreState} can be used. class LPPAPI TokenStream : public AttributeSource { protected: /// A TokenStream using the default attribute factory. TokenStream(); - + /// A TokenStream that uses the same attributes as the supplied one. TokenStream(AttributeSourcePtr input); - + /// A TokenStream using the supplied AttributeFactory for creating new {@link Attribute} instances. TokenStream(AttributeFactoryPtr factory); - + public: virtual ~TokenStream(); - + LUCENE_CLASS(TokenStream); - + public: - /// Consumers (ie., {@link IndexWriter}) use this method to advance the stream to the next token. Implementing + /// Consumers (ie., {@link IndexWriter}) use this method to advance the stream to the next token. Implementing /// classes must implement this method and update the appropriate {@link Attribute}s with the attributes of /// the next token. /// - /// The producer must make no assumptions about the attributes after the method has been returned: the caller may - /// arbitrarily change it. If the producer needs to preserve the state for subsequent calls, it can use {@link + /// The producer must make no assumptions about the attributes after the method has been returned: the caller may + /// arbitrarily change it. If the producer needs to preserve the state for subsequent calls, it can use {@link /// #captureState} to create a copy of the current attribute state. /// - /// This method is called for every token of a document, so an efficient implementation is crucial for good - /// performance. To avoid calls to {@link #addAttribute(Class)} and {@link #getAttribute(Class)}, references to + /// This method is called for every token of a document, so an efficient implementation is crucial for good + /// performance. To avoid calls to {@link #addAttribute(Class)} and {@link #getAttribute(Class)}, references to /// all {@link Attribute}s that this stream uses should be retrieved during instantiation. /// - /// To ensure that filters and consumers know which attributes are available, the attributes must be added during - /// instantiation. Filters and consumers are not required to check for availability of attributes in {@link + /// To ensure that filters and consumers know which attributes are available, the attributes must be added during + /// instantiation. Filters and consumers are not required to check for availability of attributes in {@link /// #incrementToken()}. /// /// @return false for end of stream; true otherwise virtual bool incrementToken() = 0; - - /// This method is called by the consumer after the last token has been consumed, after {@link #incrementToken()} - /// returned false (using the new TokenStream API). Streams implementing the old API should upgrade to use this + + /// This method is called by the consumer after the last token has been consumed, after {@link #incrementToken()} + /// returned false (using the new TokenStream API). Streams implementing the old API should upgrade to use this /// feature. /// - /// This method can be used to perform any end-of-stream operations, such as setting the final offset of a stream. + /// This method can be used to perform any end-of-stream operations, such as setting the final offset of a stream. /// The final offset of a stream might differ from the offset of the last token eg in case one or more whitespaces /// followed after the last token, but a {@link WhitespaceTokenizer} was used. virtual void end(); - - /// Resets this stream to the beginning. This is an optional operation, so subclasses may or may not implement - /// this method. {@link #reset()} is not needed for the standard indexing process. However, if the tokens of a + + /// Resets this stream to the beginning. This is an optional operation, so subclasses may or may not implement + /// this method. {@link #reset()} is not needed for the standard indexing process. However, if the tokens of a /// TokenStream are intended to be consumed more than once, it is necessary to implement {@link #reset()}. Note that - /// if your TokenStream caches tokens and feeds them back again after a reset, it is imperative that you clone the - /// tokens when you store them away (on the first pass) as well as when you return them (on future passes after + /// if your TokenStream caches tokens and feeds them back again after a reset, it is imperative that you clone the + /// tokens when you store them away (on the first pass) as well as when you return them (on future passes after /// {@link #reset()}). virtual void reset(); - + /// Releases resources associated with this stream. virtual void close(); }; diff --git a/include/Tokenizer.h b/include/Tokenizer.h index 49f5efb1..ef23fd4b 100644 --- a/include/Tokenizer.h +++ b/include/Tokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,53 +15,53 @@ namespace Lucene /// /// This is an abstract class; subclasses must override {@link #incrementToken()} /// - /// Note: Subclasses overriding {@link #incrementToken()} must call {@link AttributeSource#clearAttributes()} + /// Note: Subclasses overriding {@link #incrementToken()} must call {@link AttributeSource#clearAttributes()} /// before setting attributes. class LPPAPI Tokenizer : public TokenStream { protected: /// Construct a tokenizer with null input. Tokenizer(); - + /// Construct a token stream processing the given input. Tokenizer(ReaderPtr input); - + /// Construct a tokenizer with null input using the given AttributeFactory. Tokenizer(AttributeFactoryPtr factory); - + /// Construct a token stream processing the given input using the given AttributeFactory. Tokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + /// Construct a token stream processing the given input using the given AttributeSource. Tokenizer(AttributeSourcePtr source); - + /// Construct a token stream processing the given input using the given AttributeSource. Tokenizer(AttributeSourcePtr source, ReaderPtr input); - + public: virtual ~Tokenizer(); - + LUCENE_CLASS(Tokenizer); - + protected: /// The text source for this Tokenizer. ReaderPtr input; CharStreamPtr charStream; - + public: /// By default, closes the input Reader. virtual void close(); - - /// Return the corrected offset. If {@link #input} is a {@link CharStream} subclass this method calls - /// {@link CharStream#correctOffset}, else returns currentOff. + + /// Return the corrected offset. If {@link #input} is a {@link CharStream} subclass this method calls + /// {@link CharStream#correctOffset}, else returns currentOff. /// @param currentOff offset as seen in the output /// @return corrected offset based on the input /// @see CharStream#correctOffset virtual int32_t correctOffset(int32_t currentOff); - + using TokenStream::reset; - - /// Reset the tokenizer to a new reader. Typically, an analyzer (in its reusableTokenStream method) will + + /// Reset the tokenizer to a new reader. Typically, an analyzer (in its reusableTokenStream method) will /// use this to re-use a previously created tokenizer. virtual void reset(ReaderPtr input); }; diff --git a/include/TopDocs.h b/include/TopDocs.h index 7834ad8e..bca1e0fc 100644 --- a/include/TopDocs.h +++ b/include/TopDocs.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,29 +18,29 @@ namespace Lucene public: /// Constructs a TopDocs with a default maxScore = double.NaN. TopDocs(int32_t totalHits, Collection scoreDocs); - + /// Constructs a TopDocs. TopDocs(int32_t totalHits, Collection scoreDocs, double maxScore); - + virtual ~TopDocs(); - + LUCENE_CLASS(TopDocs); - + public: /// The total number of hits for the query. int32_t totalHits; - + /// The top hits for the query. Collection scoreDocs; - + /// Stores the maximum score value encountered, needed for normalizing. double maxScore; - + public: - /// Returns the maximum score value encountered. Note that in case scores are not tracked, + /// Returns the maximum score value encountered. Note that in case scores are not tracked, /// this returns NaN. double getMaxScore(); - + /// Sets the maximum score value encountered. void setMaxScore(double maxScore); }; diff --git a/include/TopDocsCollector.h b/include/TopDocsCollector.h index b2cc3e14..9adea4ea 100644 --- a/include/TopDocsCollector.h +++ b/include/TopDocsCollector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,69 +12,69 @@ namespace Lucene { - /// A base class for all collectors that return a {@link TopDocs} output. This collector allows easy extension - /// by providing a single constructor which accepts a {@link PriorityQueue} as well as protected members for + /// A base class for all collectors that return a {@link TopDocs} output. This collector allows easy extension + /// by providing a single constructor which accepts a {@link PriorityQueue} as well as protected members for /// that priority queue and a counter of the number of total hits. /// - /// Extending classes can override {@link #topDocs(int32_t, int32_t)} and {@link #getTotalHits()} in order to - /// provide their own implementation. + /// Extending classes can override {@link #topDocs(int32_t, int32_t)} and {@link #getTotalHits()} in order to + /// provide their own implementation. class LPPAPI TopDocsCollector : public Collector { public: TopDocsCollector(HitQueueBasePtr pq); virtual ~TopDocsCollector(); - + LUCENE_CLASS(TopDocsCollector); - + protected: - /// The priority queue which holds the top documents. Note that different implementations of PriorityQueue - /// give different meaning to 'top documents'. HitQueue for example aggregates the top scoring documents, + /// The priority queue which holds the top documents. Note that different implementations of PriorityQueue + /// give different meaning to 'top documents'. HitQueue for example aggregates the top scoring documents, /// while other PQ implementations may hold documents sorted by other criteria. HitQueueBasePtr pq; - + /// The total number of documents that the collector encountered. int32_t totalHits; - + public: /// The total number of documents that matched this query. virtual int32_t getTotalHits(); - + /// Returns the top docs that were collected by this collector. virtual TopDocsPtr topDocs(); - - /// Returns the documents in the range [start .. pq.size()) that were collected by this collector. Note that + + /// Returns the documents in the range [start .. pq.size()) that were collected by this collector. Note that /// if start >= pq.size(), an empty TopDocs is returned. /// - /// This method is convenient to call if the application always asks for the last results, starting from the + /// This method is convenient to call if the application always asks for the last results, starting from the /// last 'page'. /// - /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more - /// than once, passing each time a different start, you should call {@link #topDocs()} and work with the + /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more + /// than once, passing each time a different start, you should call {@link #topDocs()} and work with the /// returned {@link TopDocs} object, which will contain all the results this search execution collected. virtual TopDocsPtr topDocs(int32_t start); - - /// Returns the documents in the rage [start .. start + howMany) that were collected by this collector. Note - /// that if start >= pq.size(), an empty TopDocs is returned, and if pq.size() - start < howMany, then only + + /// Returns the documents in the rage [start .. start + howMany) that were collected by this collector. Note + /// that if start >= pq.size(), an empty TopDocs is returned, and if pq.size() - start < howMany, then only /// the available documents in [start .. pq.size()) are returned. /// - /// This method is useful to call in case pagination of search results is allowed by the search application, + /// This method is useful to call in case pagination of search results is allowed by the search application, /// as well as it attempts to optimize the memory used by allocating only as much as requested by howMany. /// - /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more - /// than once, passing each time a different range, you should call {@link #topDocs()} and work with the + /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more + /// than once, passing each time a different range, you should call {@link #topDocs()} and work with the /// returned {@link TopDocs} object, which will contain all the results this search execution collected. virtual TopDocsPtr topDocs(int32_t start, int32_t howMany); - + protected: /// This is used in case topDocs() is called with illegal parameters, or there simply aren't (enough) results. static TopDocsPtr EMPTY_TOPDOCS(); - - /// Populates the results array with the ScoreDoc instances. This can be overridden in case a different + + /// Populates the results array with the ScoreDoc instances. This can be overridden in case a different /// ScoreDoc type should be returned. virtual void populateResults(Collection results, int32_t howMany); - - /// Returns a {@link TopDocs} instance containing the given results. If results is null it means there are - /// no results to return, either because there were 0 calls to collect() or because the arguments to topDocs + + /// Returns a {@link TopDocs} instance containing the given results. If results is null it means there are + /// no results to return, either because there were 0 calls to collect() or because the arguments to topDocs /// were invalid. virtual TopDocsPtr newTopDocs(Collection results, int32_t start); }; diff --git a/include/TopFieldCollector.h b/include/TopFieldCollector.h index 2f85351b..8871c942 100644 --- a/include/TopFieldCollector.h +++ b/include/TopFieldCollector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,21 +19,21 @@ namespace Lucene public: TopFieldCollector(HitQueueBasePtr pq, int32_t numHits, bool fillFields); virtual ~TopFieldCollector(); - + LUCENE_CLASS(TopFieldCollector); - + protected: bool fillFields; - - /// Stores the maximum score value encountered, needed for normalizing. If document scores are not tracked, + + /// Stores the maximum score value encountered, needed for normalizing. If document scores are not tracked, /// this value is initialized to NaN. double maxScore; - + int32_t numHits; FieldValueHitQueueEntryPtr bottom; bool queueFull; int32_t docBase; - + public: /// Creates a new {@link TopFieldCollector} from the given arguments. /// @@ -42,30 +42,30 @@ namespace Lucene /// @param sort The sort criteria (SortFields). /// @param numHits The number of results to collect. /// @param fillFields Specifies whether the actual field values should be returned on the results (FieldDoc). - /// @param trackDocScores Specifies whether document scores should be tracked and set on the results. Note - /// that if set to false, then the results' scores will be set to NaN. Setting this to true affects - /// performance, as it incurs the score computation on each competitive result. Therefore if document scores + /// @param trackDocScores Specifies whether document scores should be tracked and set on the results. Note + /// that if set to false, then the results' scores will be set to NaN. Setting this to true affects + /// performance, as it incurs the score computation on each competitive result. Therefore if document scores /// are not required by the application, it is recommended to set it to false. - /// @param trackMaxScore Specifies whether the query's maxScore should be tracked and set on the resulting + /// @param trackMaxScore Specifies whether the query's maxScore should be tracked and set on the resulting /// {@link TopDocs}. Note that if set to false, {@link TopDocs#getMaxScore()} returns NaN. Setting this to - /// true affects performance as it incurs the score computation on each result. Also, setting this true + /// true affects performance as it incurs the score computation on each result. Also, setting this true /// automatically sets trackDocScores to true as well. - /// @param docsScoredInOrder Specifies whether documents are scored in doc Id order or not by the given - /// {@link Scorer} in {@link #setScorer(ScorerPtr)}. + /// @param docsScoredInOrder Specifies whether documents are scored in doc Id order or not by the given + /// {@link Scorer} in {@link #setScorer(ScorerPtr)}. /// @return a {@link TopFieldCollector} instance which will sort the results by the sort criteria. static TopFieldCollectorPtr create(SortPtr sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder); - + virtual void add(int32_t slot, int32_t doc, double score); - + virtual bool acceptsDocsOutOfOrder(); - + protected: static const Collection EMPTY_SCOREDOCS(); - - /// Only the following callback methods need to be overridden since topDocs(int32_t, int32_t) calls them to + + /// Only the following callback methods need to be overridden since topDocs(int32_t, int32_t) calls them to /// return the results. virtual void populateResults(Collection results, int32_t howMany); - + virtual TopDocsPtr newTopDocs(Collection results, int32_t start); }; } diff --git a/include/TopFieldDocs.h b/include/TopFieldDocs.h index 157f0d61..a06a46ae 100644 --- a/include/TopFieldDocs.h +++ b/include/TopFieldDocs.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,11 +20,11 @@ namespace Lucene /// @param fields The sort criteria used to find the top hits. /// @param maxScore The maximum score encountered. TopFieldDocs(int32_t totalHits, Collection scoreDocs, Collection fields, double maxScore); - + virtual ~TopFieldDocs(); - + LUCENE_CLASS(TopFieldDocs); - + public: /// The fields which were used to sort results by. Collection fields; diff --git a/include/TopScoreDocCollector.h b/include/TopScoreDocCollector.h index f1667589..4fa2e010 100644 --- a/include/TopScoreDocCollector.h +++ b/include/TopScoreDocCollector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,36 +11,36 @@ namespace Lucene { - /// A {@link Collector} implementation that collects the top-scoring hits, returning them as a {@link TopDocs}. - /// This is used by {@link IndexSearcher} to implement {@link TopDocs}-based search. Hits are sorted by score - /// descending and then (when the scores are tied) docID ascending. When you create an instance of this + /// A {@link Collector} implementation that collects the top-scoring hits, returning them as a {@link TopDocs}. + /// This is used by {@link IndexSearcher} to implement {@link TopDocs}-based search. Hits are sorted by score + /// descending and then (when the scores are tied) docID ascending. When you create an instance of this /// collector you should know in advance whether documents are going to be collected in doc Id order or not. /// - /// NOTE: The values Nan, NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. This collector will + /// NOTE: The values Nan, NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. This collector will /// not properly collect hits with such scores. class LPPAPI TopScoreDocCollector : public TopDocsCollector { public: TopScoreDocCollector(int32_t numHits); virtual ~TopScoreDocCollector(); - + LUCENE_CLASS(TopScoreDocCollector); - + INTERNAL: ScoreDocPtr pqTop; int32_t docBase; ScorerWeakPtr _scorer; - + public: - /// Creates a new {@link TopScoreDocCollector} given the number of hits to collect and whether documents + /// Creates a new {@link TopScoreDocCollector} given the number of hits to collect and whether documents /// are scored in order by the input {@link Scorer} to {@link #setScorer(ScorerPtr)}. /// /// NOTE: The instances returned by this method pre-allocate a full array of length numHits. static TopScoreDocCollectorPtr create(int32_t numHits, bool docsScoredInOrder); - + virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); virtual void setScorer(ScorerPtr scorer); - + protected: virtual TopDocsPtr newTopDocs(Collection results, int32_t start); }; diff --git a/include/TypeAttribute.h b/include/TypeAttribute.h index ea2e8e05..32f51ad5 100644 --- a/include/TypeAttribute.h +++ b/include/TypeAttribute.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,23 +18,23 @@ namespace Lucene TypeAttribute(); TypeAttribute(const String& type); virtual ~TypeAttribute(); - + LUCENE_CLASS(TypeAttribute); - + protected: String _type; static const String& DEFAULT_TYPE(); - + public: virtual String toString(); - + /// Returns this Token's lexical type. Defaults to "word". String type(); - + /// Set the lexical type. /// @see #type() void setType(const String& type); - + virtual void clear(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); diff --git a/include/UTF8Stream.h b/include/UTF8Stream.h index 6d424b5f..884adf3a 100644 --- a/include/UTF8Stream.h +++ b/include/UTF8Stream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,7 +16,7 @@ namespace Lucene public: virtual ~UTF8Base(); LUCENE_CLASS(UTF8Base); - + public: static const uint16_t LEAD_SURROGATE_MIN; static const uint16_t LEAD_SURROGATE_MAX; @@ -25,13 +25,13 @@ namespace Lucene static const uint16_t LEAD_OFFSET; static const uint32_t SURROGATE_OFFSET; static const uint32_t CODE_POINT_MAX; - + static const wchar_t UNICODE_REPLACEMENT_CHAR; static const wchar_t UNICODE_TERMINATOR; - + protected: virtual uint32_t readNext() = 0; - + uint8_t mask8(uint32_t b); uint16_t mask16(uint32_t c); bool isTrail(uint32_t b); @@ -41,105 +41,105 @@ namespace Lucene bool isValidCodePoint(uint32_t cp); bool isOverlongSequence(uint32_t cp, int32_t length); }; - + class UTF8Encoder : public UTF8Base { public: UTF8Encoder(const wchar_t* unicodeBegin, const wchar_t* unicodeEnd); virtual ~UTF8Encoder(); - + LUCENE_CLASS(UTF8Encoder); - + protected: const wchar_t* unicodeBegin; const wchar_t* unicodeEnd; - + public: int32_t encode(uint8_t* utf8, int32_t length); - + int32_t utf16to8(uint8_t* utf8, int32_t length); int32_t utf32to8(uint8_t* utf8, int32_t length); - + protected: virtual uint32_t readNext(); - + uint8_t* appendChar(uint8_t* utf8, uint32_t cp); }; - + class UTF8EncoderStream : public UTF8Encoder { public: UTF8EncoderStream(ReaderPtr reader); virtual ~UTF8EncoderStream(); - + LUCENE_CLASS(UTF8EncoderStream); - + protected: ReaderPtr reader; - + protected: virtual uint32_t readNext(); }; - + class UTF8Decoder : public UTF8Base { public: UTF8Decoder(const uint8_t* utf8Begin, const uint8_t* utf8End); virtual ~UTF8Decoder(); - + LUCENE_CLASS(UTF8Decoder); - + protected: const uint8_t* utf8Begin; const uint8_t* utf8End; - + public: int32_t decode(wchar_t* unicode, int32_t length); - + int32_t utf8to16(wchar_t* unicode, int32_t length); int32_t utf8to32(wchar_t* unicode, int32_t length); - + protected: virtual uint32_t readNext(); - + int32_t sequenceLength(uint32_t cp); bool getSequence(uint32_t& cp, int32_t length); bool isValidNext(uint32_t& cp); }; - + class UTF8DecoderStream : public UTF8Decoder { public: UTF8DecoderStream(ReaderPtr reader); virtual ~UTF8DecoderStream(); - + LUCENE_CLASS(UTF8DecoderStream); - + protected: ReaderPtr reader; - + protected: virtual uint32_t readNext(); }; - + class UTF16Decoder : public UTF8Base { public: UTF16Decoder(const uint16_t* utf16Begin, const uint16_t* utf16End); virtual ~UTF16Decoder(); - + LUCENE_CLASS(UTF16Decoder); - + protected: const uint16_t* utf16Begin; const uint16_t* utf16End; - + public: int32_t decode(wchar_t* unicode, int32_t length); - + int32_t utf16to16(wchar_t* unicode, int32_t length); int32_t utf16to32(wchar_t* unicode, int32_t length); - + protected: virtual uint32_t readNext(); }; diff --git a/include/UnicodeUtils.h b/include/UnicodeUtils.h index 7fdb1331..7e6a40a7 100644 --- a/include/UnicodeUtils.h +++ b/include/UnicodeUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,41 +15,41 @@ namespace Lucene { public: virtual ~UnicodeUtil(); - + public: /// Return true if supplied character is alpha-numeric. static bool isAlnum(wchar_t c); - + /// Return true if supplied character is alphabetic. static bool isAlpha(wchar_t c); - + /// Return true if supplied character is numeric. static bool isDigit(wchar_t c); - + /// Return true if supplied character is a space. static bool isSpace(wchar_t c); - + /// Return true if supplied character is uppercase. static bool isUpper(wchar_t c); - + /// Return true if supplied character is lowercase. static bool isLower(wchar_t c); - + /// Return true if supplied character is other type of letter. static bool isOther(wchar_t c); - + /// Return true if supplied character is non-spacing. static bool isNonSpacing(wchar_t c); - + /// Return uppercase representation of a given character. static wchar_t toUpper(wchar_t c); - + /// Return lowercase representation of a given character. static wchar_t toLower(wchar_t c); }; - + /// Utility class that contains utf8 and unicode translations. - template + template class TranslationResult : public LuceneObject { public: @@ -58,11 +58,11 @@ namespace Lucene result = Array::newInstance(10); length = 0; } - + public: Array result; int32_t length; - + public: void setLength(int32_t length) { @@ -72,13 +72,13 @@ namespace Lucene result.resize((int32_t)(1.5 * (double)length)); this->length = length; } - + void copyText(const TranslationResult& other) { setLength(other.length); MiscUtils::arrayCopy(other.result.get(), 0, result.get(), 0, other.length); } - + void copyText(boost::shared_ptr< TranslationResult > other) { copyText(*other); @@ -90,12 +90,12 @@ namespace Lucene public: virtual ~UTF8Result(); }; - + class LPPAPI UnicodeResult : public TranslationResult { public: virtual ~UnicodeResult(); - }; + }; } #endif diff --git a/include/ValueSource.h b/include/ValueSource.h index 8fe985e2..0b4ef465 100644 --- a/include/ValueSource.h +++ b/include/ValueSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,28 +16,28 @@ namespace Lucene /// At its default/simplest form, values - one per doc - are used as the score of that doc. /// /// Values are instantiated as {@link DocValues} for a particular reader. - /// ValueSource implementations differ in RAM requirements: it would always be a factor of the number of - /// documents, but for each document the number of bytes can be 1, 2, 4, or 8. + /// ValueSource implementations differ in RAM requirements: it would always be a factor of the number of + /// documents, but for each document the number of bytes can be 1, 2, 4, or 8. class LPPAPI ValueSource : public LuceneObject { public: virtual ~ValueSource(); LUCENE_CLASS(ValueSource); - + public: /// Return the DocValues used by the function query. - /// @param reader The IndexReader used to read these values. If any caching is involved, that caching - /// would also be IndexReader based. + /// @param reader The IndexReader used to read these values. If any caching is involved, that caching + /// would also be IndexReader based. virtual DocValuesPtr getValues(IndexReaderPtr reader) = 0; - - /// Description of field, used in explain() + + /// Description of field, used in explain() virtual String description() = 0; - + virtual String toString(); - + /// Needed for possible caching of query results - used by {@link ValueSourceQuery#equals(LuceneObjectPtr)}. virtual bool equals(LuceneObjectPtr other) = 0; - + /// Needed for possible caching of query results - used by {@link ValueSourceQuery#hashCode()}. virtual int32_t hashCode() = 0; }; diff --git a/include/ValueSourceQuery.h b/include/ValueSourceQuery.h index 56514845..6d2bda92 100644 --- a/include/ValueSourceQuery.h +++ b/include/ValueSourceQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,8 +15,8 @@ namespace Lucene /// /// This query provides a score for each and every undeleted document in the index. /// - /// The value source can be based on a (cached) value of an indexed field, but it can also be based on an - /// external source, eg. values read from an external database. + /// The value source can be based on a (cached) value of an indexed field, but it can also be based on an + /// external source, eg. values read from an external database. /// /// Score is set as: Score(doc,query) = (query.getBoost() * query.getBoost()) * valueSource(doc). class LPPAPI ValueSourceQuery : public Query @@ -25,17 +25,17 @@ namespace Lucene /// Create a value source query /// @param valSrc provides the values defines the function to be used for scoring ValueSourceQuery(ValueSourcePtr valSrc); - + virtual ~ValueSourceQuery(); - + LUCENE_CLASS(ValueSourceQuery); - + public: ValueSourcePtr valSrc; - + public: using Query::toString; - + virtual QueryPtr rewrite(IndexReaderPtr reader); virtual void extractTerms(SetTerm terms); virtual WeightPtr createWeight(SearcherPtr searcher); diff --git a/include/VariantUtils.h b/include/VariantUtils.h index 1400449a..4d610a5a 100644 --- a/include/VariantUtils.h +++ b/include/VariantUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,35 +21,35 @@ namespace Lucene { return var.type() == typeid(TYPE) ? boost::any_cast(var) : TYPE(); } - + template static TYPE get(VAR var) { return var.type() == typeid(TYPE) ? boost::get(var) : TYPE(); } - + template static bool typeOf(VAR var) { return (var.type() == typeid(TYPE)); } - + static VariantNull null() { return VariantNull(); } - + static bool isNull(boost::any var) { return var.empty(); } - + template static bool isNull(VAR var) { return typeOf(var); } - + template static int32_t hashCode(VAR var) { @@ -78,19 +78,19 @@ namespace Lucene return get(var)->hashCode(); return 0; } - + template static bool equalsType(FIRST first, SECOND second) { return (first.type() == second.type()); } - + template static bool equals(FIRST first, SECOND second) { return first.type() == second.type() ? (first == second) : false; } - + template static int32_t compareTo(VAR first, VAR second) { diff --git a/include/Weight.h b/include/Weight.h index d573627f..1aff3f09 100644 --- a/include/Weight.h +++ b/include/Weight.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene { /// Calculate query weights and build query scorers. /// - /// The purpose of {@link Weight} is to ensure searching does not modify a {@link Query}, so that a + /// The purpose of {@link Weight} is to ensure searching does not modify a {@link Query}, so that a /// {@link Query} instance can be reused. /// {@link Searcher} dependent state of the query should reside in the {@link Weight}. /// {@link IndexReader} dependent state should reside in the {@link Scorer}. @@ -21,59 +21,59 @@ namespace Lucene /// Weight is used in the following way: ///
      ///
    1. A Weight is constructed by a top-level query, given a Searcher ({@link Query#createWeight(Searcher)}). - ///
    2. The {@link #sumOfSquaredWeights()} method is called on the Weight to compute the query normalization + ///
    3. The {@link #sumOfSquaredWeights()} method is called on the Weight to compute the query normalization /// factor {@link Similarity#queryNorm(float)} of the query clauses contained in the query. - ///
    4. The query normalization factor is passed to {@link #normalize(float)}. At this point the weighting is + ///
    5. The query normalization factor is passed to {@link #normalize(float)}. At this point the weighting is /// complete. ///
    6. A Scorer is constructed by {@link #scorer(IndexReaderPtr, bool, bool)}. ///
    class LPPAPI Weight : public LuceneObject { public: - virtual ~Weight(); + virtual ~Weight(); LUCENE_CLASS(Weight); - + public: /// An explanation of the score computation for the named document. /// @param reader sub-reader containing the give doc /// @param doc - /// @return an Explanation for the score + /// @return an Explanation for the score virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc) = 0; - + /// The query that this concerns. virtual QueryPtr getQuery() = 0; - + /// The weight for this query. virtual double getValue() = 0; - + /// Assigns the query normalization factor to this. virtual void normalize(double norm) = 0; - + /// Returns a {@link Scorer} which scores documents in/out-of order according to scoreDocsInOrder. /// - /// NOTE: even if scoreDocsInOrder is false, it is recommended to check whether the returned Scorer + /// NOTE: even if scoreDocsInOrder is false, it is recommended to check whether the returned Scorer /// indeed scores documents out of order (ie., call {@link #scoresDocsOutOfOrder()}), as some Scorer /// implementations will always return documents in-order. /// /// NOTE: null can be returned if no documents will be scored by this query. /// /// @param reader The {@link IndexReader} for which to return the {@link Scorer}. - /// @param scoreDocsInOrder Specifies whether in-order scoring of documents is required. Note that if + /// @param scoreDocsInOrder Specifies whether in-order scoring of documents is required. Note that if /// set to false (i.e., out-of-order scoring is required), this method can return whatever scoring mode /// it supports, as every in-order scorer is also an out-of-order one. However, an out-of-order scorer - /// may not support {@link Scorer#nextDoc()} and/or {@link Scorer#advance(int)}, therefore it is + /// may not support {@link Scorer#nextDoc()} and/or {@link Scorer#advance(int)}, therefore it is /// recommended to request an in-order scorer if use of these methods is required. - /// @param topScorer If true, {@link Scorer#score(CollectorPtr)} will be called; if false, {@link + /// @param topScorer If true, {@link Scorer#score(CollectorPtr)} will be called; if false, {@link /// Scorer#nextDoc()} and/or {@link Scorer#advance(int)} will be called. /// @return a {@link Scorer} which scores documents in/out-of order. virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) = 0; - + /// The sum of squared weights of contained query clauses. virtual double sumOfSquaredWeights() = 0; - - /// Returns true if this implementation scores docs only out of order. This method is used in conjunction + + /// Returns true if this implementation scores docs only out of order. This method is used in conjunction /// with {@link Collector}'s {@link Collector#acceptsDocsOutOfOrder() acceptsDocsOutOfOrder} and - /// {@link #scorer(IndexReaderPtr, bool, bool)} to create a matching {@link Scorer} instance for a given + /// {@link #scorer(IndexReaderPtr, bool, bool)} to create a matching {@link Scorer} instance for a given /// {@link Collector}, or vice versa. /// /// NOTE: the default implementation returns false, ie. the Scorer scores documents in-order. diff --git a/include/WhitespaceAnalyzer.h b/include/WhitespaceAnalyzer.h index a51f42dc..53e3b4e0 100644 --- a/include/WhitespaceAnalyzer.h +++ b/include/WhitespaceAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene { public: virtual ~WhitespaceAnalyzer(); - + LUCENE_CLASS(WhitespaceAnalyzer); - + public: virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); diff --git a/include/WhitespaceTokenizer.h b/include/WhitespaceTokenizer.h index ff3a39e6..105269eb 100644 --- a/include/WhitespaceTokenizer.h +++ b/include/WhitespaceTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,24 +11,24 @@ namespace Lucene { - /// A WhitespaceTokenizer is a tokenizer that divides text at whitespace. Adjacent sequences of non-Whitespace + /// A WhitespaceTokenizer is a tokenizer that divides text at whitespace. Adjacent sequences of non-Whitespace /// characters form tokens. class LPPAPI WhitespaceTokenizer : public CharTokenizer { public: /// Construct a new WhitespaceTokenizer. WhitespaceTokenizer(ReaderPtr input); - + /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource}. WhitespaceTokenizer(AttributeSourcePtr source, ReaderPtr input); - + /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource.AttributeFactory}. WhitespaceTokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~WhitespaceTokenizer(); - + LUCENE_CLASS(WhitespaceTokenizer); - + public: /// Collects only characters which do not satisfy {@link Character#isWhitespace(char)}. virtual bool isTokenChar(wchar_t c); diff --git a/include/WildcardQuery.h b/include/WildcardQuery.h index cd5b10d0..e044bd01 100644 --- a/include/WildcardQuery.h +++ b/include/WildcardQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,9 +11,9 @@ namespace Lucene { - /// Implements the wildcard search query. Supported wildcards are *, which matches any character sequence - /// (including the empty one), and ?, which matches any single character. Note this query can be slow, as - /// it needs to iterate over many terms. In order to prevent extremely slow WildcardQueries, a Wildcard + /// Implements the wildcard search query. Supported wildcards are *, which matches any character sequence + /// (including the empty one), and ?, which matches any single character. Note this query can be slow, as + /// it needs to iterate over many terms. In order to prevent extremely slow WildcardQueries, a Wildcard /// term should not start with one of the wildcards * or ?. /// /// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. @@ -23,29 +23,29 @@ namespace Lucene public: WildcardQuery(TermPtr term); virtual ~WildcardQuery(); - + LUCENE_CLASS(WildcardQuery); - + protected: bool termContainsWildcard; bool termIsPrefix; TermPtr term; - + public: using MultiTermQuery::toString; - + /// Returns the pattern term. TermPtr getTerm(); - + virtual QueryPtr rewrite(IndexReaderPtr reader); - + /// Prints a user-readable version of this query. virtual String toString(const String& field); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); virtual int32_t hashCode(); virtual bool equals(LuceneObjectPtr other); - + protected: virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); }; diff --git a/include/WildcardTermEnum.h b/include/WildcardTermEnum.h index 633373e4..3db3b5f5 100644 --- a/include/WildcardTermEnum.h +++ b/include/WildcardTermEnum.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,38 +13,38 @@ namespace Lucene { /// Subclass of FilteredTermEnum for enumerating all terms that match the specified wildcard filter term. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than + /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than /// all that precede it. class LPPAPI WildcardTermEnum : public FilteredTermEnum { public: /// Creates a new WildcardTermEnum. /// - /// After calling the constructor the enumeration is already pointing to the first valid term if such + /// After calling the constructor the enumeration is already pointing to the first valid term if such /// a term exists. WildcardTermEnum(IndexReaderPtr reader, TermPtr term); - + virtual ~WildcardTermEnum(); - + LUCENE_CLASS(WildcardTermEnum); - + public: static const wchar_t WILDCARD_STRING; static const wchar_t WILDCARD_CHAR; - + TermPtr searchTerm; String field; String text; String pre; int32_t preLen; bool _endEnum; - + public: virtual double difference(); - + /// Determines if a word matches a wildcard pattern. static bool wildcardEquals(const String& pattern, int32_t patternIdx, const String& string, int32_t stringIdx); - + protected: virtual bool termCompare(TermPtr term); virtual bool endEnum(); diff --git a/include/WordlistLoader.h b/include/WordlistLoader.h index e7e14cc5..c61527d4 100644 --- a/include/WordlistLoader.h +++ b/include/WordlistLoader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene { public: virtual ~WordlistLoader(); - + LUCENE_CLASS(WordlistLoader); - + public: - /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). + /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). /// Every line of the file should contain only one word. The words need to be in lowercase if you make use of an /// Analyzer which uses LowerCaseFilter (like StandardAnalyzer). /// @@ -28,8 +28,8 @@ namespace Lucene /// @param comment The comment string to ignore /// @return A set with the file's words static HashSet getWordSet(const String& wordfile, const String& comment = EmptyString); - - /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). + + /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). /// Every line of the file should contain only one word. The words need to be in lowercase if you make use of an /// Analyzer which uses LowerCaseFilter (like StandardAnalyzer). /// @@ -37,7 +37,7 @@ namespace Lucene /// @param comment The comment string to ignore /// @return A set with the file's words static HashSet getWordSet(ReaderPtr reader, const String& comment = EmptyString); - + /// Reads a stem dictionary. Each line contains: ///
    word\tstem
    /// (ie. two tab separated words) diff --git a/include/targetver.h b/include/targetver.h index fd70e9ef..c7f57484 100644 --- a/include/targetver.h +++ b/include/targetver.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp index 55479dfe..8fffc42b 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,78 +19,78 @@ namespace Lucene /// /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html /// The stopword list is BSD-Licensed. - const uint8_t ArabicAnalyzer::DEFAULT_STOPWORD_FILE[] = + const uint8_t ArabicAnalyzer::DEFAULT_STOPWORD_FILE[] = { - 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x86, - 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, - 0x0a, 0xd9, 0x88, 0xd9, 0x81, 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, - 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0x0a, 0xd8, 0xab, - 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0x0a, 0xd8, 0xa3, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, 0x0a, - 0xd8, 0xa8, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0x0a, 0xd8, - 0xa3, 0x0a, 0xd8, 0xa7, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, - 0x0a, 0xd8, 0xa3, 0xd9, 0x89, 0x0a, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd8, - 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, - 0xd8, 0xa5, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x86, 0x0a, 0xd9, 0x85, - 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa7, - 0x0a, 0xd9, 0x81, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd8, - 0xb9, 0x0a, 0xd8, 0xa7, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, - 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, 0xd8, - 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, - 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, - 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, - 0xa8, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, - 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, - 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, - 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, - 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, - 0xb0, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, - 0xa7, 0xd9, 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xa5, 0xd9, - 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa5, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, - 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, - 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, - 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, - 0xb6, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xb6, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, - 0x84, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x88, - 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x84, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x86, - 0x0a, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x87, 0xd9, 0x88, 0x0a, - 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, - 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x81, 0xd9, 0x87, - 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, - 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x84, 0xd9, - 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb0, 0xd9, 0x87, 0x0a, - 0xd9, 0x87, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd8, 0xb0, - 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x83, 0x0a, 0xd9, 0x83, - 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x8a, - 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, - 0xd9, 0x88, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd8, - 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, - 0xb6, 0x0a, 0xd9, 0x82, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xad, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, - 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, - 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb0, 0x0a, 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd8, 0xad, - 0xd9, 0x8a, 0xd8, 0xab, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, - 0xd9, 0x84, 0xd8, 0xa2, 0xd9, 0x86, 0x0a, 0xd8, 0xae, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, - 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd8, 0xad, - 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, - 0xd8, 0xaf, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x89, 0x0a, 0xd8, 0xac, + 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x86, + 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, + 0x0a, 0xd9, 0x88, 0xd9, 0x81, 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, + 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0x0a, 0xd8, 0xab, + 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0x0a, 0xd8, 0xa3, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, 0x0a, + 0xd8, 0xa8, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0x0a, 0xd8, + 0xa3, 0x0a, 0xd8, 0xa7, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, + 0x0a, 0xd8, 0xa3, 0xd9, 0x89, 0x0a, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd8, + 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, + 0xd8, 0xa5, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x86, 0x0a, 0xd9, 0x85, + 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa7, + 0x0a, 0xd9, 0x81, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd8, + 0xb9, 0x0a, 0xd8, 0xa7, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, + 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, 0xd8, + 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, + 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, + 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, + 0xa8, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, + 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, + 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, + 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb0, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xa5, 0xd9, + 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa5, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, + 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, + 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, + 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, + 0xb6, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xb6, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, + 0x84, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x88, + 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x84, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x86, + 0x0a, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x87, 0xd9, 0x88, 0x0a, + 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, + 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x81, 0xd9, 0x87, + 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, + 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x84, 0xd9, + 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb0, 0xd9, 0x87, 0x0a, + 0xd9, 0x87, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd8, 0xb0, + 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x83, 0x0a, 0xd9, 0x83, + 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x8a, + 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, + 0xd9, 0x88, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd8, + 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, + 0xb6, 0x0a, 0xd9, 0x82, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xad, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, + 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, + 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb0, 0x0a, 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd8, 0xad, + 0xd9, 0x8a, 0xd8, 0xab, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xa2, 0xd9, 0x86, 0x0a, 0xd8, 0xae, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, + 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd8, 0xad, + 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, + 0xd8, 0xaf, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x89, 0x0a, 0xd8, 0xac, 0xd9, 0x85, 0xd9, 0x8a, 0xd8, 0xb9, 0x0a }; - + ArabicAnalyzer::ArabicAnalyzer(LuceneVersion::Version matchVersion) { this->stoptable = getDefaultStopSet(); this->matchVersion = matchVersion; } - + ArabicAnalyzer::ArabicAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stoptable = stopwords; this->matchVersion = matchVersion; } - + ArabicAnalyzer::~ArabicAnalyzer() { } - + const HashSet ArabicAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -102,7 +102,7 @@ namespace Lucene } return stopSet; } - + TokenStreamPtr ArabicAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(reader); @@ -113,7 +113,7 @@ namespace Lucene result = newLucene(result); return result; } - + TokenStreamPtr ArabicAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { ArabicAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -132,7 +132,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + ArabicAnalyzerSavedStreams::~ArabicAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp index 3888872c..faa0dcb8 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,19 +14,19 @@ namespace Lucene ArabicLetterTokenizer::ArabicLetterTokenizer(ReaderPtr input) : LetterTokenizer(input) { } - + ArabicLetterTokenizer::ArabicLetterTokenizer(AttributeSourcePtr source, ReaderPtr input) : LetterTokenizer(source, input) { } - + ArabicLetterTokenizer::ArabicLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : LetterTokenizer(factory, input) { } - + ArabicLetterTokenizer::~ArabicLetterTokenizer() { } - + bool ArabicLetterTokenizer::isTokenChar(wchar_t c) { return LetterTokenizer::isTokenChar(c) || UnicodeUtil::isNonSpacing(c); diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp index 4b7bd7fd..18d8eed8 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene normalizer = newLucene(); termAtt = addAttribute(); } - + ArabicNormalizationFilter::~ArabicNormalizationFilter() { } - + bool ArabicNormalizationFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp index 18685ca5..c0b8d805 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,15 +14,15 @@ namespace Lucene const wchar_t ArabicNormalizer::ALEF_MADDA = (wchar_t)0x0622; const wchar_t ArabicNormalizer::ALEF_HAMZA_ABOVE = (wchar_t)0x0623; const wchar_t ArabicNormalizer::ALEF_HAMZA_BELOW = (wchar_t)0x0625; - + const wchar_t ArabicNormalizer::YEH = (wchar_t)0x064a; const wchar_t ArabicNormalizer::DOTLESS_YEH = (wchar_t)0x0649; - + const wchar_t ArabicNormalizer::TEH_MARBUTA = (wchar_t)0x0629; const wchar_t ArabicNormalizer::HEH = (wchar_t)0x0647; - + const wchar_t ArabicNormalizer::TATWEEL = (wchar_t)0x0640; - + const wchar_t ArabicNormalizer::FATHATAN = (wchar_t)0x064b; const wchar_t ArabicNormalizer::DAMMATAN = (wchar_t)0x064c; const wchar_t ArabicNormalizer::KASRATAN = (wchar_t)0x064d; @@ -31,11 +31,11 @@ namespace Lucene const wchar_t ArabicNormalizer::KASRA = (wchar_t)0x0650; const wchar_t ArabicNormalizer::SHADDA = (wchar_t)0x0651; const wchar_t ArabicNormalizer::SUKUN = (wchar_t)0x0652; - + ArabicNormalizer::~ArabicNormalizer() { } - + int32_t ArabicNormalizer::normalize(wchar_t* s, int32_t len) { for (int32_t i = 0; i < len; ++i) @@ -70,7 +70,7 @@ namespace Lucene } return len; } - + int32_t ArabicNormalizer::deleteChar(wchar_t* s, int32_t pos, int32_t len) { if (pos < len) diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp index 605847c2..a4dd4a4a 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene stemmer = newLucene(); termAtt = addAttribute(); } - + ArabicStemFilter::~ArabicStemFilter() { } - + bool ArabicStemFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp index ba5fd1d9..576d498b 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,11 +21,11 @@ namespace Lucene const wchar_t ArabicStemmer::HEH = (wchar_t)0x0647; const wchar_t ArabicStemmer::WAW = (wchar_t)0x0648; const wchar_t ArabicStemmer::YEH = (wchar_t)0x064a; - + ArabicStemmer::~ArabicStemmer() { } - + const Collection ArabicStemmer::prefixes() { static Collection _prefixes; @@ -42,7 +42,7 @@ namespace Lucene } return _prefixes; } - + const Collection ArabicStemmer::suffixes() { static Collection _suffixes; @@ -62,14 +62,14 @@ namespace Lucene } return _suffixes; } - + int32_t ArabicStemmer::stem(wchar_t* s, int32_t len) { len = stemPrefix(s, len); len = stemSuffix(s, len); return len; } - + int32_t ArabicStemmer::stemPrefix(wchar_t* s, int32_t len) { Collection stemPrefixes(prefixes()); @@ -80,7 +80,7 @@ namespace Lucene } return len; } - + int32_t ArabicStemmer::stemSuffix(wchar_t* s, int32_t len) { Collection stemSuffixes(suffixes()); @@ -91,7 +91,7 @@ namespace Lucene } return len; } - + bool ArabicStemmer::startsWith(wchar_t* s, int32_t len, const String& prefix) { if (prefix.length() == 1 && len < 4) // wa- prefix requires at least 3 characters @@ -108,7 +108,7 @@ namespace Lucene return true; } } - + bool ArabicStemmer::endsWith(wchar_t* s, int32_t len, const String& suffix) { if (len < (int32_t)suffix.length() + 2) // all suffixes require at least 2 characters after stemming @@ -123,14 +123,14 @@ namespace Lucene return true; } } - + int32_t ArabicStemmer::deleteChars(wchar_t* s, int32_t pos, int32_t len, int32_t chars) { for (int32_t i = 0; i < chars; ++i) len = deleteChar(s, pos, len); return len; } - + int32_t ArabicStemmer::deleteChar(wchar_t* s, int32_t pos, int32_t len) { if (pos < len) diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp index 6b0249cf..ea1bef11 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene { - const wchar_t* BrazilianAnalyzer::_BRAZILIAN_STOP_WORDS[] = + const wchar_t* BrazilianAnalyzer::_BRAZILIAN_STOP_WORDS[] = { L"a", L"ainda", L"alem", L"ambas", L"ambos", L"antes", L"ao", L"aonde", L"aos", L"apos", L"aquele", L"aqueles", @@ -27,41 +27,41 @@ namespace Lucene L"essa", L"essas", L"esse", L"esses", L"esta", L"estas", L"este", L"estes", L"ha", L"isso", L"isto", L"logo", L"mais", L"mas", L"mediante", L"menos", L"mesma", L"mesmas", L"mesmo", - L"mesmos", L"na", L"nas", L"nao", L"nas", L"nem", L"nesse", - L"neste", L"nos", L"o", L"os", L"ou", L"outra", L"outras", - L"outro", L"outros", L"pelas", L"pelas", L"pelo", L"pelos", - L"perante", L"pois", L"por", L"porque", L"portanto", - L"proprio", L"propios", L"quais", L"qual", L"qualquer", - L"quando", L"quanto", L"que", L"quem", L"quer", L"se", L"seja", + L"mesmos", L"na", L"nas", L"nao", L"nas", L"nem", L"nesse", + L"neste", L"nos", L"o", L"os", L"ou", L"outra", L"outras", + L"outro", L"outros", L"pelas", L"pelas", L"pelo", L"pelos", + L"perante", L"pois", L"por", L"porque", L"portanto", + L"proprio", L"propios", L"quais", L"qual", L"qualquer", + L"quando", L"quanto", L"que", L"quem", L"quer", L"se", L"seja", L"sem", L"sendo", L"seu", L"seus", L"sob", L"sobre", L"sua", - L"suas", L"tal", L"tambem", L"teu", L"teus", L"toda", L"todas", - L"todo", L"todos", L"tua", L"tuas", L"tudo", L"um", L"uma", + L"suas", L"tal", L"tambem", L"teu", L"teus", L"toda", L"todas", + L"todo", L"todos", L"tua", L"tuas", L"tudo", L"um", L"uma", L"umas", L"uns" }; - + BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion) { this->stoptable = getDefaultStopSet(); this->matchVersion = matchVersion; } - + BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stoptable = stopwords; this->matchVersion = matchVersion; } - + BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { this->stoptable = stopwords; this->excltable = exclusions; this->matchVersion = matchVersion; } - + BrazilianAnalyzer::~BrazilianAnalyzer() { } - + const HashSet BrazilianAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -69,13 +69,13 @@ namespace Lucene stopSet = HashSet::newInstance(_BRAZILIAN_STOP_WORDS, _BRAZILIAN_STOP_WORDS + SIZEOF_ARRAY(_BRAZILIAN_STOP_WORDS)); return stopSet; } - + void BrazilianAnalyzer::setStemExclusionTable(HashSet exclusions) { excltable = exclusions; setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - + TokenStreamPtr BrazilianAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(matchVersion, reader); @@ -85,7 +85,7 @@ namespace Lucene result = newLucene(result, excltable); return result; } - + TokenStreamPtr BrazilianAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { BrazilianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -103,7 +103,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + BrazilianAnalyzerSavedStreams::~BrazilianAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp index e2f80319..65f26e36 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,18 +16,18 @@ namespace Lucene stemmer = newLucene(); termAtt = addAttribute(); } - + BrazilianStemFilter::BrazilianStemFilter(TokenStreamPtr input, HashSet exclusiontable) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); exclusions = exclusiontable; } - + BrazilianStemFilter::~BrazilianStemFilter() { } - + bool BrazilianStemFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp index 5f6307c2..57daac78 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene BrazilianStemmer::~BrazilianStemmer() { } - + String BrazilianStemmer::stem(const String& term) { // creates CT @@ -44,7 +44,7 @@ namespace Lucene return CT; } - + bool BrazilianStemmer::isStemmable(const String& term) { for (int32_t c = 0; c < (int32_t)term.length(); ++c) @@ -55,17 +55,17 @@ namespace Lucene } return true; } - + bool BrazilianStemmer::isIndexable(const String& term) { return (term.length() < 30) && (term.length() > 2); } - + bool BrazilianStemmer::isVowel(wchar_t value) { return (value == L'a' || value == L'e' || value == L'i' || value == L'o' || value == L'u'); } - + String BrazilianStemmer::getR1(const String& value) { if (value.empty()) @@ -95,7 +95,7 @@ namespace Lucene return value.substr(j + 1); } - + String BrazilianStemmer::getRV(const String& value) { if (value.empty()) @@ -133,14 +133,14 @@ namespace Lucene if (j < i) return value.substr(j + 1); } - + // RV - AND otherwise (consonant-vowel case) RV is the region after the third letter. if (i > 2) return value.substr(3); - + return L""; } - + String BrazilianStemmer::changeTerm(const String& value) { if (value.empty()) @@ -148,7 +148,7 @@ namespace Lucene String lowerValue(StringUtils::toLower(value)); String r; - + for (int32_t j = 0; j < (int32_t)value.length(); ++j) { if (value[j] == 0x00e1 || value[j] == 0x00e2 || value[j] == 0x00e3) @@ -192,7 +192,7 @@ namespace Lucene return r ; } - + bool BrazilianStemmer::checkSuffix(const String& value, const String& suffix) { if (value.empty() || suffix.empty()) @@ -201,34 +201,34 @@ namespace Lucene return false; return (value.substr(value.length() - suffix.length()) == suffix); } - + String BrazilianStemmer::replaceSuffix(const String& value, const String& toReplace, const String& changeTo) { if (value.empty() || toReplace.empty() || changeTo.empty()) return value; - + String vvalue = removeSuffix(value, toReplace); - + if (value == vvalue) return value; else return vvalue + changeTo; } - + String BrazilianStemmer::removeSuffix(const String& value, const String& toRemove) { if (value.empty() || toRemove.empty() || !checkSuffix(value, toRemove)) return value; return value.substr(0, value.length() - toRemove.length()); } - + bool BrazilianStemmer::suffixPreceded(const String& value, const String& suffix, const String& preceded) { if (value.empty() || suffix.empty() || preceded.empty() || !checkSuffix(value, suffix)) return false; return checkSuffix(removeSuffix(value, suffix), preceded); } - + void BrazilianStemmer::createCT(const String& term) { CT = changeTerm(term); @@ -250,12 +250,12 @@ namespace Lucene CT[CT.length() - 1] == L'\'' || CT[CT.length() - 1] == L'"') CT = CT.substr(0, CT.length() - 1); } - + bool BrazilianStemmer::step1() { if (CT.empty()) return false; - + // suffix length = 7 if (checkSuffix(CT, L"uciones") && checkSuffix(R2, L"uciones")) { @@ -286,7 +286,7 @@ namespace Lucene CT = removeSuffix(CT, L"adoras"); return true; } - if (checkSuffix(CT, L"logias") && checkSuffix(R2, L"logias")) + if (checkSuffix(CT, L"logias") && checkSuffix(R2, L"logias")) { replaceSuffix(CT, L"logias", L"log"); return true; @@ -491,12 +491,12 @@ namespace Lucene // no ending was removed by step1 return false; } - + bool BrazilianStemmer::step2() { if (RV.empty()) return false; - + // suffix lenght = 7 if (RV.length() >= 7) { @@ -601,7 +601,7 @@ namespace Lucene return true; } } - + // suffix length = 5 if (RV.length() >= 5) { @@ -1100,21 +1100,21 @@ namespace Lucene // no ending was removed by step2 return false; } - + void BrazilianStemmer::step3() { if (RV.empty()) return; - + if (checkSuffix(RV, L"i") && suffixPreceded(RV, L"i", L"c")) CT = removeSuffix(CT, L"i"); } - + void BrazilianStemmer::step4() { if (RV.empty()) return; - + if (checkSuffix(RV, L"os")) { CT = removeSuffix(CT, L"os"); @@ -1136,12 +1136,12 @@ namespace Lucene return; } } - + void BrazilianStemmer::step5() { if (RV.empty()) return; - + if (checkSuffix(RV, L"e")) { if (suffixPreceded(RV, L"e", L"gu")) diff --git a/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp index 27372f19..93fe48a0 100644 --- a/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,33 +11,33 @@ namespace Lucene { - const wchar_t* CJKAnalyzer::_STOP_WORDS[] = + const wchar_t* CJKAnalyzer::_STOP_WORDS[] = { L"a", L"and", L"are", L"as", L"at", L"be", - L"but", L"by", L"for", L"if", L"in", L"into", - L"is", L"it", L"no", L"not", L"of", L"on", - L"or", L"s", L"such", L"t", L"that", L"the", - L"their", L"then", L"there", L"these", - L"they", L"this", L"to", L"was", L"will", + L"but", L"by", L"for", L"if", L"in", L"into", + L"is", L"it", L"no", L"not", L"of", L"on", + L"or", L"s", L"such", L"t", L"that", L"the", + L"their", L"then", L"there", L"these", + L"they", L"this", L"to", L"was", L"will", L"with", L"", L"www" }; - + CJKAnalyzer::CJKAnalyzer(LuceneVersion::Version matchVersion) { this->stoptable = getDefaultStopSet(); this->matchVersion = matchVersion; } - + CJKAnalyzer::CJKAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stoptable = stopwords; this->matchVersion = matchVersion; } - + CJKAnalyzer::~CJKAnalyzer() { } - + const HashSet CJKAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -45,12 +45,12 @@ namespace Lucene stopSet = HashSet::newInstance(_STOP_WORDS, _STOP_WORDS + SIZEOF_ARRAY(_STOP_WORDS)); return stopSet; } - + TokenStreamPtr CJKAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), newLucene(reader), stoptable); } - + TokenStreamPtr CJKAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { CJKAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -65,7 +65,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + CJKAnalyzerSavedStreams::~CJKAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp b/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp index f04a4fc1..57f428c5 100644 --- a/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,36 +18,36 @@ namespace Lucene { /// Word token type const int32_t CJKTokenizer::WORD_TYPE = 0; - + /// Single byte token type const int32_t CJKTokenizer::SINGLE_TOKEN_TYPE = 1; - + /// Double byte token type const int32_t CJKTokenizer::DOUBLE_TOKEN_TYPE = 2; /// Names for token types const wchar_t* CJKTokenizer::TOKEN_TYPE_NAMES[] = {L"word", L"single", L"double"}; - + const int32_t CJKTokenizer::MAX_WORD_LEN = 255; const int32_t CJKTokenizer::IO_BUFFER_SIZE = 256; - + CJKTokenizer::CJKTokenizer(ReaderPtr input) : Tokenizer(input) { } - + CJKTokenizer::CJKTokenizer(AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source, input) { } - + CJKTokenizer::CJKTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory, input) { } - + CJKTokenizer::~CJKTokenizer() { } - + void CJKTokenizer::initialize() { offset = 0; @@ -57,12 +57,12 @@ namespace Lucene ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); tokenType = WORD_TYPE; preIsTokened = false; - + termAtt = addAttribute(); offsetAtt = addAttribute(); typeAtt = addAttribute(); } - + CJKTokenizer::UnicodeBlock CJKTokenizer::unicodeBlock(wchar_t c) { if (c >= 0x0000 && c <= 0x007f) @@ -71,7 +71,7 @@ namespace Lucene return HALFWIDTH_AND_FULLWIDTH_FORMS; return NONE; } - + bool CJKTokenizer::incrementToken() { clearAttributes(); @@ -119,7 +119,7 @@ namespace Lucene { // get current character c = ioBuffer[bufferIndex++]; - + // get the UnicodeBlock of the current character ub = unicodeBlock(c); } @@ -148,7 +148,7 @@ namespace Lucene // letter start = offset - 1; } - else if (tokenType == DOUBLE_TOKEN_TYPE) + else if (tokenType == DOUBLE_TOKEN_TYPE) { // "javaC1C2C3C4linux"
    // ^--: the previous non-ASCII @@ -252,14 +252,14 @@ namespace Lucene // Cycle back and try for the next token (don't return an empty string) } } - + void CJKTokenizer::end() { // set final offset int32_t finalOffset = correctOffset(offset); offsetAtt->setOffset(finalOffset, finalOffset); } - + void CJKTokenizer::reset() { Tokenizer::reset(); @@ -269,7 +269,7 @@ namespace Lucene preIsTokened = false; tokenType = WORD_TYPE; } - + void CJKTokenizer::reset(ReaderPtr input) { Tokenizer::reset(input); diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp index 810b3581..0060a254 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,14 +14,14 @@ namespace Lucene ChineseAnalyzer::~ChineseAnalyzer() { } - + TokenStreamPtr ChineseAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result); return result; } - + TokenStreamPtr ChineseAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { ChineseAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -36,7 +36,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + ChineseAnalyzerSavedStreams::~ChineseAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp index d068bf4d..fd9067cd 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - const wchar_t* ChineseFilter::STOP_WORDS[] = + const wchar_t* ChineseFilter::STOP_WORDS[] = { L"and", L"are", L"as", L"at", L"be", L"but", L"by", L"for", L"if", L"in", L"into", L"is", L"it", @@ -20,23 +20,23 @@ namespace Lucene L"that", L"the", L"their", L"then", L"there", L"these", L"they", L"this", L"to", L"was", L"will", L"with" }; - + ChineseFilter::ChineseFilter(TokenStreamPtr input) : TokenFilter(input) { stopTable = HashSet::newInstance(STOP_WORDS, STOP_WORDS + SIZEOF_ARRAY(STOP_WORDS)); termAtt = addAttribute(); } - + ChineseFilter::~ChineseFilter() { } - + bool ChineseFilter::incrementToken() { while (input->incrementToken()) { String text(termAtt->term()); - + if (!stopTable.contains(text)) { if (UnicodeUtil::isLower(text[0]) || UnicodeUtil::isUpper(text[0])) diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp index 67d856b0..86c51dcd 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,23 +17,23 @@ namespace Lucene { const int32_t ChineseTokenizer::MAX_WORD_LEN = 255; const int32_t ChineseTokenizer::IO_BUFFER_SIZE = 1024; - + ChineseTokenizer::ChineseTokenizer(ReaderPtr input) : Tokenizer(input) { } - + ChineseTokenizer::ChineseTokenizer(AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source, input) { } - + ChineseTokenizer::ChineseTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory, input) { } - + ChineseTokenizer::~ChineseTokenizer() { } - + void ChineseTokenizer::initialize() { offset = 0; @@ -43,18 +43,18 @@ namespace Lucene ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); length = 0; start = 0; - + termAtt = addAttribute(); offsetAtt = addAttribute(); } - + void ChineseTokenizer::push(wchar_t c) { if (length == 0) start = offset - 1; // start of token buffer[length++] = CharFolder::toLower(c); // buffer it } - + bool ChineseTokenizer::flush() { if (length > 0) @@ -66,7 +66,7 @@ namespace Lucene else return false; } - + bool ChineseTokenizer::incrementToken() { clearAttributes(); @@ -78,13 +78,13 @@ namespace Lucene { wchar_t c; ++offset; - + if (bufferIndex >= dataLen) { dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); bufferIndex = 0; } - + if (dataLen == -1) { --offset; @@ -92,7 +92,7 @@ namespace Lucene } else c = ioBuffer[bufferIndex++]; - + if (UnicodeUtil::isDigit(c) || UnicodeUtil::isLower(c) || UnicodeUtil::isUpper(c)) { push(c); @@ -114,14 +114,14 @@ namespace Lucene return flush(); } } - + void ChineseTokenizer::end() { // set final offset int32_t finalOffset = correctOffset(offset); offsetAtt->setOffset(finalOffset, finalOffset); } - + void ChineseTokenizer::reset() { Tokenizer::reset(); @@ -129,7 +129,7 @@ namespace Lucene bufferIndex = 0; dataLen = 0; } - + void ChineseTokenizer::reset(ReaderPtr input) { Tokenizer::reset(input); diff --git a/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp index a78313f7..b95afba6 100644 --- a/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,79 +15,79 @@ namespace Lucene { /// Default Czech stopwords in UTF-8 format. - const uint8_t CzechAnalyzer::_CZECH_STOP_WORDS[] = + const uint8_t CzechAnalyzer::_CZECH_STOP_WORDS[] = { - 0x61, 0x0a, 0x73, 0x0a, 0x6b, 0x0a, 0x6f, 0x0a, 0x69, 0x0a, 0x75, 0x0a, 0x76, 0x0a, 0x7a, 0x0a, - 0x64, 0x6e, 0x65, 0x73, 0x0a, 0x63, 0x7a, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x74, 0x6f, 0x0a, 0x62, - 0x75, 0x64, 0x65, 0xc5, 0xa1, 0x0a, 0x62, 0x75, 0x64, 0x65, 0x6d, 0x0a, 0x62, 0x79, 0x6c, 0x69, - 0x0a, 0x6a, 0x73, 0x65, 0xc5, 0xa1, 0x0a, 0x6d, 0x75, 0x6a, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, - 0x0a, 0x74, 0x61, 0x0a, 0x74, 0x6f, 0x6d, 0x74, 0x6f, 0x0a, 0x74, 0x6f, 0x68, 0x6c, 0x65, 0x0a, - 0x74, 0x75, 0x74, 0x6f, 0x0a, 0x74, 0x79, 0x74, 0x6f, 0x0a, 0x6a, 0x65, 0x6a, 0x0a, 0x7a, 0x64, - 0x61, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x0a, 0x6d, 0xc3, 0xa1, 0x74, 0x65, 0x0a, 0x74, 0x61, 0x74, - 0x6f, 0x0a, 0x6b, 0x61, 0x6d, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x64, 0x6f, - 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xad, 0x0a, 0x6d, 0x69, 0x0a, 0x6e, 0xc3, 0xa1, 0x6d, 0x0a, - 0x74, 0x6f, 0x6d, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x74, 0x6f, 0x0a, 0x6d, 0xc3, 0xad, 0x74, 0x0a, - 0x6e, 0x69, 0x63, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0x6f, 0x75, - 0x0a, 0x62, 0x79, 0x6c, 0x61, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0xc5, 0xbe, 0x65, 0x0a, 0x61, 0x73, 0x69, 0x0a, 0x68, 0x6f, 0x0a, 0x6e, 0x61, 0xc5, 0xa1, 0x69, - 0x0a, 0x6e, 0x61, 0x70, 0x69, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x72, 0x65, 0x0a, 0x63, 0x6f, 0xc5, - 0xbe, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x0a, 0x74, 0x61, 0x6b, 0xc5, 0xbe, 0x65, 0x0a, 0x73, 0x76, - 0xc3, 0xbd, 0x63, 0x68, 0x0a, 0x6a, 0x65, 0x6a, 0xc3, 0xad, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, - 0x69, 0x0a, 0x6a, 0x73, 0x74, 0x65, 0x0a, 0x61, 0x6a, 0x0a, 0x74, 0x75, 0x0a, 0x74, 0x65, 0x64, - 0x79, 0x0a, 0x74, 0x65, 0x74, 0x6f, 0x0a, 0x62, 0x79, 0x6c, 0x6f, 0x0a, 0x6b, 0x64, 0x65, 0x0a, - 0x6b, 0x65, 0x0a, 0x70, 0x72, 0x61, 0x76, 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x0a, 0x6e, 0x61, 0x64, - 0x0a, 0x6e, 0x65, 0x6a, 0x73, 0x6f, 0x75, 0x0a, 0x63, 0x69, 0x0a, 0x70, 0x6f, 0x64, 0x0a, 0x74, - 0xc3, 0xa9, 0x6d, 0x61, 0x0a, 0x6d, 0x65, 0x7a, 0x69, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x0a, 0x74, - 0x79, 0x0a, 0x70, 0x61, 0x6b, 0x0a, 0x76, 0xc3, 0xa1, 0x6d, 0x0a, 0x61, 0x6e, 0x69, 0x0a, 0x6b, - 0x64, 0x79, 0xc5, 0xbe, 0x0a, 0x76, 0xc5, 0xa1, 0x61, 0x6b, 0x0a, 0x6e, 0x65, 0x67, 0x0a, 0x6a, - 0x73, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6e, 0x74, 0x6f, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, - 0x75, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, 0x79, 0x0a, 0x61, 0x62, 0x79, 0x0a, 0x6a, 0x73, - 0x6d, 0x65, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x0a, 0x70, 0x74, 0x61, 0x0a, 0x6a, 0x65, 0x6a, 0x69, - 0x63, 0x68, 0x0a, 0x62, 0x79, 0x6c, 0x0a, 0x6a, 0x65, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x61, 0xc5, - 0xbe, 0x0a, 0x62, 0x65, 0x7a, 0x0a, 0x74, 0x61, 0x6b, 0xc3, 0xa9, 0x0a, 0x70, 0x6f, 0x75, 0x7a, - 0x65, 0x0a, 0x70, 0x72, 0x76, 0x6e, 0xc3, 0xad, 0x0a, 0x76, 0x61, 0xc5, 0xa1, 0x65, 0x0a, 0x6b, - 0x74, 0x65, 0x72, 0xc3, 0xa1, 0x0a, 0x6e, 0xc3, 0xa1, 0x73, 0x0a, 0x6e, 0x6f, 0x76, 0xc3, 0xbd, - 0x0a, 0x74, 0x69, 0x70, 0x79, 0x0a, 0x70, 0x6f, 0x6b, 0x75, 0x64, 0x0a, 0x6d, 0x75, 0xc5, 0xbe, - 0x65, 0x0a, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x61, 0x0a, 0x6a, 0x65, 0x68, 0x6f, 0x0a, 0x73, 0x76, - 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x6e, 0xc3, 0xa9, 0x0a, 0x7a, 0x70, 0x72, 0xc3, 0xa1, 0x76, 0x79, + 0x61, 0x0a, 0x73, 0x0a, 0x6b, 0x0a, 0x6f, 0x0a, 0x69, 0x0a, 0x75, 0x0a, 0x76, 0x0a, 0x7a, 0x0a, + 0x64, 0x6e, 0x65, 0x73, 0x0a, 0x63, 0x7a, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x74, 0x6f, 0x0a, 0x62, + 0x75, 0x64, 0x65, 0xc5, 0xa1, 0x0a, 0x62, 0x75, 0x64, 0x65, 0x6d, 0x0a, 0x62, 0x79, 0x6c, 0x69, + 0x0a, 0x6a, 0x73, 0x65, 0xc5, 0xa1, 0x0a, 0x6d, 0x75, 0x6a, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, + 0x0a, 0x74, 0x61, 0x0a, 0x74, 0x6f, 0x6d, 0x74, 0x6f, 0x0a, 0x74, 0x6f, 0x68, 0x6c, 0x65, 0x0a, + 0x74, 0x75, 0x74, 0x6f, 0x0a, 0x74, 0x79, 0x74, 0x6f, 0x0a, 0x6a, 0x65, 0x6a, 0x0a, 0x7a, 0x64, + 0x61, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x0a, 0x6d, 0xc3, 0xa1, 0x74, 0x65, 0x0a, 0x74, 0x61, 0x74, + 0x6f, 0x0a, 0x6b, 0x61, 0x6d, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x64, 0x6f, + 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xad, 0x0a, 0x6d, 0x69, 0x0a, 0x6e, 0xc3, 0xa1, 0x6d, 0x0a, + 0x74, 0x6f, 0x6d, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x74, 0x6f, 0x0a, 0x6d, 0xc3, 0xad, 0x74, 0x0a, + 0x6e, 0x69, 0x63, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0x6f, 0x75, + 0x0a, 0x62, 0x79, 0x6c, 0x61, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0xc5, 0xbe, 0x65, 0x0a, 0x61, 0x73, 0x69, 0x0a, 0x68, 0x6f, 0x0a, 0x6e, 0x61, 0xc5, 0xa1, 0x69, + 0x0a, 0x6e, 0x61, 0x70, 0x69, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x72, 0x65, 0x0a, 0x63, 0x6f, 0xc5, + 0xbe, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x0a, 0x74, 0x61, 0x6b, 0xc5, 0xbe, 0x65, 0x0a, 0x73, 0x76, + 0xc3, 0xbd, 0x63, 0x68, 0x0a, 0x6a, 0x65, 0x6a, 0xc3, 0xad, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, + 0x69, 0x0a, 0x6a, 0x73, 0x74, 0x65, 0x0a, 0x61, 0x6a, 0x0a, 0x74, 0x75, 0x0a, 0x74, 0x65, 0x64, + 0x79, 0x0a, 0x74, 0x65, 0x74, 0x6f, 0x0a, 0x62, 0x79, 0x6c, 0x6f, 0x0a, 0x6b, 0x64, 0x65, 0x0a, + 0x6b, 0x65, 0x0a, 0x70, 0x72, 0x61, 0x76, 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x0a, 0x6e, 0x61, 0x64, + 0x0a, 0x6e, 0x65, 0x6a, 0x73, 0x6f, 0x75, 0x0a, 0x63, 0x69, 0x0a, 0x70, 0x6f, 0x64, 0x0a, 0x74, + 0xc3, 0xa9, 0x6d, 0x61, 0x0a, 0x6d, 0x65, 0x7a, 0x69, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x0a, 0x74, + 0x79, 0x0a, 0x70, 0x61, 0x6b, 0x0a, 0x76, 0xc3, 0xa1, 0x6d, 0x0a, 0x61, 0x6e, 0x69, 0x0a, 0x6b, + 0x64, 0x79, 0xc5, 0xbe, 0x0a, 0x76, 0xc5, 0xa1, 0x61, 0x6b, 0x0a, 0x6e, 0x65, 0x67, 0x0a, 0x6a, + 0x73, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6e, 0x74, 0x6f, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, + 0x75, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, 0x79, 0x0a, 0x61, 0x62, 0x79, 0x0a, 0x6a, 0x73, + 0x6d, 0x65, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x0a, 0x70, 0x74, 0x61, 0x0a, 0x6a, 0x65, 0x6a, 0x69, + 0x63, 0x68, 0x0a, 0x62, 0x79, 0x6c, 0x0a, 0x6a, 0x65, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x61, 0xc5, + 0xbe, 0x0a, 0x62, 0x65, 0x7a, 0x0a, 0x74, 0x61, 0x6b, 0xc3, 0xa9, 0x0a, 0x70, 0x6f, 0x75, 0x7a, + 0x65, 0x0a, 0x70, 0x72, 0x76, 0x6e, 0xc3, 0xad, 0x0a, 0x76, 0x61, 0xc5, 0xa1, 0x65, 0x0a, 0x6b, + 0x74, 0x65, 0x72, 0xc3, 0xa1, 0x0a, 0x6e, 0xc3, 0xa1, 0x73, 0x0a, 0x6e, 0x6f, 0x76, 0xc3, 0xbd, + 0x0a, 0x74, 0x69, 0x70, 0x79, 0x0a, 0x70, 0x6f, 0x6b, 0x75, 0x64, 0x0a, 0x6d, 0x75, 0xc5, 0xbe, + 0x65, 0x0a, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x61, 0x0a, 0x6a, 0x65, 0x68, 0x6f, 0x0a, 0x73, 0x76, + 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x6e, 0xc3, 0xa9, 0x0a, 0x7a, 0x70, 0x72, 0xc3, 0xa1, 0x76, 0x79, 0x0a, 0x6e, 0x6f, 0x76, 0xc3, 0xa9, 0x0a, 0x6e, 0x65, 0x6e, 0xc3, 0xad, 0x0a, 0x76, 0xc3, 0xa1, 0x73, 0x0a, 0x6a, 0x65, 0x6e, 0x0a, 0x70, 0x6f, 0x64, 0x6c, 0x65, 0x0a, 0x7a, 0x64, 0x65, 0x0a, - 0x75, 0xc5, 0xbe, 0x0a, 0x62, 0xc3, 0xbd, 0x74, 0x0a, 0x76, 0xc3, 0xad, 0x63, 0x65, 0x0a, 0x62, - 0x75, 0x64, 0x65, 0x0a, 0x6a, 0x69, 0xc5, 0xbe, 0x0a, 0x6e, 0x65, 0xc5, 0xbe, 0x0a, 0x6b, 0x74, - 0x65, 0x72, 0xc3, 0xbd, 0x0a, 0x62, 0x79, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xa9, 0x0a, 0x63, - 0x6f, 0x0a, 0x6e, 0x65, 0x62, 0x6f, 0x0a, 0x74, 0x65, 0x6e, 0x0a, 0x74, 0x61, 0x6b, 0x0a, 0x6d, - 0xc3, 0xa1, 0x0a, 0x70, 0x72, 0x69, 0x0a, 0x6f, 0x64, 0x0a, 0x70, 0x6f, 0x0a, 0x6a, 0x73, 0x6f, - 0x75, 0x0a, 0x6a, 0x61, 0x6b, 0x0a, 0x64, 0x61, 0x6c, 0xc5, 0xa1, 0xc3, 0xad, 0x0a, 0x61, 0x6c, - 0x65, 0x0a, 0x73, 0x69, 0x0a, 0x73, 0x65, 0x0a, 0x76, 0x65, 0x0a, 0x74, 0x6f, 0x0a, 0x6a, 0x61, - 0x6b, 0x6f, 0x0a, 0x7a, 0x61, 0x0a, 0x7a, 0x70, 0x65, 0x74, 0x0a, 0x7a, 0x65, 0x0a, 0x64, 0x6f, - 0x0a, 0x70, 0x72, 0x6f, 0x0a, 0x6a, 0x65, 0x0a, 0x6e, 0x61, 0x0a, 0x61, 0x74, 0x64, 0x0a, 0x61, - 0x74, 0x70, 0x0a, 0x6a, 0x61, 0x6b, 0x6d, 0x69, 0x6c, 0x65, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x6d, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xa1, 0x0a, 0x6f, 0x6e, 0x0a, 0x6f, 0x6e, 0x61, 0x0a, 0x6f, - 0x6e, 0x6f, 0x0a, 0x6f, 0x6e, 0x69, 0x0a, 0x6f, 0x6e, 0x79, 0x0a, 0x6d, 0x79, 0x0a, 0x76, 0x79, - 0x0a, 0x6a, 0xc3, 0xad, 0x0a, 0x6a, 0x69, 0x0a, 0x6d, 0x65, 0x0a, 0x6d, 0x6e, 0x65, 0x0a, 0x6a, - 0x65, 0x6d, 0x75, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x0a, 0x74, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6d, - 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, - 0x68, 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xad, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0x6c, 0x69, 0x6b, - 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0xc5, 0xbe, 0x0a, 0x6a, 0x61, 0x6b, 0x6f, 0xc5, 0xbe, 0x0a, + 0x75, 0xc5, 0xbe, 0x0a, 0x62, 0xc3, 0xbd, 0x74, 0x0a, 0x76, 0xc3, 0xad, 0x63, 0x65, 0x0a, 0x62, + 0x75, 0x64, 0x65, 0x0a, 0x6a, 0x69, 0xc5, 0xbe, 0x0a, 0x6e, 0x65, 0xc5, 0xbe, 0x0a, 0x6b, 0x74, + 0x65, 0x72, 0xc3, 0xbd, 0x0a, 0x62, 0x79, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xa9, 0x0a, 0x63, + 0x6f, 0x0a, 0x6e, 0x65, 0x62, 0x6f, 0x0a, 0x74, 0x65, 0x6e, 0x0a, 0x74, 0x61, 0x6b, 0x0a, 0x6d, + 0xc3, 0xa1, 0x0a, 0x70, 0x72, 0x69, 0x0a, 0x6f, 0x64, 0x0a, 0x70, 0x6f, 0x0a, 0x6a, 0x73, 0x6f, + 0x75, 0x0a, 0x6a, 0x61, 0x6b, 0x0a, 0x64, 0x61, 0x6c, 0xc5, 0xa1, 0xc3, 0xad, 0x0a, 0x61, 0x6c, + 0x65, 0x0a, 0x73, 0x69, 0x0a, 0x73, 0x65, 0x0a, 0x76, 0x65, 0x0a, 0x74, 0x6f, 0x0a, 0x6a, 0x61, + 0x6b, 0x6f, 0x0a, 0x7a, 0x61, 0x0a, 0x7a, 0x70, 0x65, 0x74, 0x0a, 0x7a, 0x65, 0x0a, 0x64, 0x6f, + 0x0a, 0x70, 0x72, 0x6f, 0x0a, 0x6a, 0x65, 0x0a, 0x6e, 0x61, 0x0a, 0x61, 0x74, 0x64, 0x0a, 0x61, + 0x74, 0x70, 0x0a, 0x6a, 0x61, 0x6b, 0x6d, 0x69, 0x6c, 0x65, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, + 0x6d, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xa1, 0x0a, 0x6f, 0x6e, 0x0a, 0x6f, 0x6e, 0x61, 0x0a, 0x6f, + 0x6e, 0x6f, 0x0a, 0x6f, 0x6e, 0x69, 0x0a, 0x6f, 0x6e, 0x79, 0x0a, 0x6d, 0x79, 0x0a, 0x76, 0x79, + 0x0a, 0x6a, 0xc3, 0xad, 0x0a, 0x6a, 0x69, 0x0a, 0x6d, 0x65, 0x0a, 0x6d, 0x6e, 0x65, 0x0a, 0x6a, + 0x65, 0x6d, 0x75, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x0a, 0x74, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6d, + 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, + 0x68, 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xad, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0x6c, 0x69, 0x6b, + 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0xc5, 0xbe, 0x0a, 0x6a, 0x61, 0x6b, 0x6f, 0xc5, 0xbe, 0x0a, 0x6e, 0x61, 0x63, 0x65, 0xc5, 0xbe, 0x0a }; - + CzechAnalyzer::CzechAnalyzer(LuceneVersion::Version matchVersion) { this->stoptable = getDefaultStopSet(); this->matchVersion = matchVersion; } - + CzechAnalyzer::CzechAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stoptable = stopwords; this->matchVersion = matchVersion; } - + CzechAnalyzer::~CzechAnalyzer() { } - + const HashSet CzechAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -99,7 +99,7 @@ namespace Lucene } return stopSet; } - + TokenStreamPtr CzechAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(matchVersion, reader); @@ -108,7 +108,7 @@ namespace Lucene result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); return result; } - + TokenStreamPtr CzechAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { CzechAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -117,7 +117,7 @@ namespace Lucene streams = newLucene(); streams->source = newLucene(matchVersion, reader); streams->result = newLucene(streams->source); - streams->result = newLucene(streams->result); + streams->result = newLucene(streams->result); streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); setPreviousTokenStream(streams); } @@ -125,7 +125,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + CzechAnalyzerSavedStreams::~CzechAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp b/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp index ddcbadfc..a5de612f 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,40 +14,40 @@ namespace Lucene { - const wchar_t* GermanAnalyzer::_GERMAN_STOP_WORDS[] = + const wchar_t* GermanAnalyzer::_GERMAN_STOP_WORDS[] = { - L"einer", L"eine", L"eines", L"einem", L"einen", L"der", L"die", - L"das", L"dass", L"da\x00df", L"du", L"er", L"sie", L"es", L"was", - L"wer", L"wie", L"wir", L"und", L"oder", L"ohne", L"mit", L"am", + L"einer", L"eine", L"eines", L"einem", L"einen", L"der", L"die", + L"das", L"dass", L"da\x00df", L"du", L"er", L"sie", L"es", L"was", + L"wer", L"wie", L"wir", L"und", L"oder", L"ohne", L"mit", L"am", L"im", L"in", L"aus", L"auf", L"ist", L"sein", L"war", L"wird", - L"ihr", L"ihre", L"ihres", L"als", L"f\x00fcr", L"von", L"mit", - L"dich", L"dir", L"mich", L"mir", L"mein", L"sein", L"kein", + L"ihr", L"ihre", L"ihres", L"als", L"f\x00fcr", L"von", L"mit", + L"dich", L"dir", L"mich", L"mir", L"mein", L"sein", L"kein", L"durch", L"wegen", L"wird" }; - + GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion) { this->stopSet = getDefaultStopSet(); this->matchVersion = matchVersion; } - + GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stopSet = stopwords; this->matchVersion = matchVersion; } - + GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { this->stopSet = stopwords; this->exclusionSet = exclusions; this->matchVersion = matchVersion; } - + GermanAnalyzer::~GermanAnalyzer() { } - + const HashSet GermanAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -55,23 +55,23 @@ namespace Lucene stopSet = HashSet::newInstance(_GERMAN_STOP_WORDS, _GERMAN_STOP_WORDS + SIZEOF_ARRAY(_GERMAN_STOP_WORDS)); return stopSet; } - + void GermanAnalyzer::setStemExclusionTable(HashSet exclusions) { exclusionSet = exclusions; setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - + TokenStreamPtr GermanAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); - result = newLucene(result); + result = newLucene(result); result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); result = newLucene(result, exclusionSet); return result; } - + TokenStreamPtr GermanAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { GermanAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -89,7 +89,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + GermanAnalyzerSavedStreams::~GermanAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp b/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp index 8694e70c..7b2ff52b 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,18 +16,18 @@ namespace Lucene stemmer = newLucene(); termAtt = addAttribute(); } - + GermanStemFilter::GermanStemFilter(TokenStreamPtr input, HashSet exclusionSet) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); this->exclusionSet = exclusionSet; } - + GermanStemFilter::~GermanStemFilter() { } - + bool GermanStemFilter::incrementToken() { if (input->incrementToken()) @@ -46,13 +46,13 @@ namespace Lucene else return false; } - + void GermanStemFilter::setStemmer(GermanStemmerPtr stemmer) { if (stemmer) this->stemmer = stemmer; } - + void GermanStemFilter::setExclusionSet(HashSet exclusionSet) { this->exclusionSet = exclusionSet; diff --git a/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp b/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp index 0c6f2679..9cbd81af 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,28 +17,28 @@ namespace Lucene { substCount = 0; } - + GermanStemmer::~GermanStemmer() { } - + String GermanStemmer::stem(const String& term) { // Use lowercase for medium stemming. buffer = StringUtils::toLower(term); if (!isStemmable()) return buffer; - + // Stemming starts here substitute(); strip(); optimize(); resubstitute(); removeParticleDenotion(); - + return buffer; } - + bool GermanStemmer::isStemmable() { for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) @@ -48,7 +48,7 @@ namespace Lucene } return true; } - + void GermanStemmer::strip() { bool doMore = true; @@ -73,7 +73,7 @@ namespace Lucene doMore = false; } } - + void GermanStemmer::optimize() { // Additional step for female plurals of professions and inhabitants. @@ -82,12 +82,12 @@ namespace Lucene buffer.resize(buffer.length() - 1); strip(); } - + // Additional step for irregular plural nouns like "Matrizen -> Matrix". if (buffer[buffer.length() - 1] == L'z') buffer[buffer.length() - 1] = L'x'; } - + void GermanStemmer::removeParticleDenotion() { if (buffer.length() > 4) @@ -102,7 +102,7 @@ namespace Lucene } } } - + void GermanStemmer::substitute() { substCount = 0; @@ -168,7 +168,7 @@ namespace Lucene } } } - + void GermanStemmer::resubstitute() { for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) diff --git a/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp b/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp index 330d9978..be4ee05b 100644 --- a/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,67 +14,67 @@ namespace Lucene { /// Default Greek stopwords in UTF-8 format. - const uint8_t GreekAnalyzer::_GREEK_STOP_WORDS[] = + const uint8_t GreekAnalyzer::_GREEK_STOP_WORDS[] = { 0xce, 0xbf, 0x0a, 0xce, 0xb7, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xce, 0xbf, 0xce, 0xb9, 0x0a, - 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x84, 0xce, 0xb7, - 0xcf, 0x83, 0x0a, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xbd, - 0x0a, 0xcf, 0x84, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, - 0xba, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, 0xce, - 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, - 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, - 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x84, 0xce, - 0xb5, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xce, - 0xbd, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0xce, - 0xbd, 0x0a, 0xce, 0xbc, 0xce, 0xb1, 0x0a, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0x0a, - 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbf, 0x0a, 0xce, 0xb3, 0xce, 0xb9, 0xce, 0xb1, 0x0a, 0xcf, 0x80, - 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0x0a, 0xcf, 0x83, 0xce, 0xb5, - 0x0a, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0x0a, 0xce, - 0xb1, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xcf, 0x84, 0xce, 0xb1, - 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb8, 0xce, 0xb1, 0x0a, 0xce, - 0xbd, 0xce, 0xb1, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0xce, 0xbd, 0x0a, - 0xce, 0xbc, 0xce, 0xb7, 0x0a, 0xce, 0xbc, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xb5, 0xcf, 0x80, - 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xbd, 0xcf, 0x89, 0x0a, 0xce, 0xb5, 0xce, 0xb1, 0xce, 0xbd, - 0x0a, 0xce, 0xb1, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xcf, - 0x80, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, - 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb1, - 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, - 0xce, 0xbf, 0xce, 0xb9, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb5, 0xcf, 0x83, 0x0a, - 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, - 0xb9, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, - 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xce, 0xb1, 0xcf, 0x85, - 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xb9, 0x0a, - 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, - 0x84, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb5, - 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb5, 0xce, 0xba, - 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, - 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb7, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, - 0xce, 0xbd, 0xce, 0xbf, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, - 0xbf, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb5, - 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0x0a, - 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, - 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, - 0xce, 0xbf, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xce, 0xbc, 0xcf, 0x89, 0xcf, - 0x83, 0x0a, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xcf, 0x83, 0xce, + 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x84, 0xce, 0xb7, + 0xcf, 0x83, 0x0a, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xbd, + 0x0a, 0xcf, 0x84, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, + 0xba, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, 0xce, + 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, + 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, + 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x84, 0xce, + 0xb5, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xce, + 0xbd, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0xce, + 0xbd, 0x0a, 0xce, 0xbc, 0xce, 0xb1, 0x0a, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0x0a, + 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbf, 0x0a, 0xce, 0xb3, 0xce, 0xb9, 0xce, 0xb1, 0x0a, 0xcf, 0x80, + 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0x0a, 0xcf, 0x83, 0xce, 0xb5, + 0x0a, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0x0a, 0xce, + 0xb1, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xcf, 0x84, 0xce, 0xb1, + 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb8, 0xce, 0xb1, 0x0a, 0xce, + 0xbd, 0xce, 0xb1, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0xce, 0xbd, 0x0a, + 0xce, 0xbc, 0xce, 0xb7, 0x0a, 0xce, 0xbc, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xb5, 0xcf, 0x80, + 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xbd, 0xcf, 0x89, 0x0a, 0xce, 0xb5, 0xce, 0xb1, 0xce, 0xbd, + 0x0a, 0xce, 0xb1, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xcf, + 0x80, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, + 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb1, + 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, + 0xce, 0xbf, 0xce, 0xb9, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb5, 0xcf, 0x83, 0x0a, + 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, + 0xb9, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, + 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xce, 0xb1, 0xcf, 0x85, + 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xb9, 0x0a, + 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, + 0x84, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb5, + 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb5, 0xce, 0xba, + 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, + 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb7, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, + 0xce, 0xbd, 0xce, 0xbf, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, + 0xbf, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb5, + 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0x0a, + 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, + 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, + 0xce, 0xbf, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xce, 0xbc, 0xcf, 0x89, 0xcf, + 0x83, 0x0a, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xcf, 0x83, 0xce, 0xbf, 0x0a, 0xce, 0xbf, 0xcf, 0x84, 0xce, 0xb9, 0x0a }; - + GreekAnalyzer::GreekAnalyzer(LuceneVersion::Version matchVersion) { this->stopSet = getDefaultStopSet(); this->matchVersion = matchVersion; } - + GreekAnalyzer::GreekAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stopSet = stopwords; this->matchVersion = matchVersion; } - + GreekAnalyzer::~GreekAnalyzer() { } - + const HashSet GreekAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -86,7 +86,7 @@ namespace Lucene } return stopSet; } - + TokenStreamPtr GreekAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(matchVersion, reader); @@ -94,7 +94,7 @@ namespace Lucene result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); return result; } - + TokenStreamPtr GreekAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { GreekAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -110,7 +110,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + GreekAnalyzerSavedStreams::~GreekAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp b/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp index 0255a559..e27a083d 100644 --- a/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,77 +15,77 @@ namespace Lucene { termAtt = addAttribute(); } - + GreekLowerCaseFilter::~GreekLowerCaseFilter() { } - + bool GreekLowerCaseFilter::incrementToken() { if (input->incrementToken()) { wchar_t* chArray = termAtt->termBufferArray(); int32_t chLen = termAtt->termLength(); - + for (int32_t i = 0; i < chLen; ++i) chArray[i] = lowerCase(chArray[i]); - + return true; } else return false; } - + wchar_t GreekLowerCaseFilter::lowerCase(wchar_t codepoint) { switch (codepoint) { case L'\x03c2': // small final sigma return 0x03c3; // small sigma - + // Some Greek characters contain diacritics. // This filter removes these, converting to the lowercase base form. - + case L'\x0386': // capital alpha with tonos case L'\x03ac': // small alpha with tonos return L'\x03b1'; // small alpha - + case L'\x0388': // capital epsilon with tonos case L'\x03ad': // small epsilon with tonos return L'\x03b5'; // small epsilon - + case L'\x0389': // capital eta with tonos case L'\x03ae': // small eta with tonos return L'\x03b7'; // small eta - + case L'\x038a': // capital iota with tonos case L'\x03aa': // capital iota with dialytika case L'\x03af': // small iota with tonos case L'\x03ca': // small iota with dialytika case L'\x0390': // small iota with dialytika and tonos return L'\x03b9'; // small iota - + case L'\x038e': // capital upsilon with tonos case L'\x03ab': // capital upsilon with dialytika case L'\x03cd': // small upsilon with tonos case L'\x03cb': // small upsilon with dialytika case L'\x03b0': // small upsilon with dialytika and tonos return L'\x03c5'; // small upsilon - + case L'\x038c': // capital omicron with tonos case L'\x03cc': // small omicron with tonos return L'\x03bf'; // small omicron - + case L'\x038f': // capital omega with tonos case L'\x03ce': // small omega with tonos return L'\x03c9'; // small omega - + // The previous implementation did the conversion below. // Only implemented for backwards compatibility with old indexes. - + case L'\x03a2': // reserved return L'\x03c2'; // small final sigma - + default: return CharFolder::toLower(codepoint); } diff --git a/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp index c6d50688..b73c5f6d 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,194 +19,194 @@ namespace Lucene /// /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html /// The stopword list is BSD-Licensed. - const uint8_t PersianAnalyzer::DEFAULT_STOPWORD_FILE[] = + const uint8_t PersianAnalyzer::DEFAULT_STOPWORD_FILE[] = { - 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, - 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xb1, - 0x0a, 0xd8, 0xae, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xb4, - 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x83, - 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, 0xaa, 0xd8, - 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x85, 0x0a, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, - 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x88, 0x0a, - 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, 0xd8, - 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, - 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0xda, 0xaf, 0xd8, 0xb2, 0x0a, 0xd9, 0xbe, 0xd9, - 0x86, 0xd8, 0xac, 0x0a, 0xd9, 0x86, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, - 0x85, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, - 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd8, 0xb7, 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, - 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, - 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xda, - 0x86, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, - 0xb7, 0x0a, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x82, - 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb1, 0xd9, 0x81, - 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, 0x86, - 0xd9, 0x86, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x87, 0xd8, 0xb2, - 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, - 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, - 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, - 0xd8, 0xb1, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, - 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, - 0x86, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, - 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, - 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x88, 0xd9, - 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, - 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, 0xd8, 0xac, 0xd8, 0xb2, - 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd8, 0xaf, - 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xaa, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, - 0xd8, 0xb1, 0xd8, 0xae, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, - 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd9, - 0x84, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd9, 0x82, - 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd9, 0x88, - 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, - 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xb8, 0xd9, 0x8a, 0xd8, - 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, - 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, - 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, - 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, - 0xb4, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, - 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, - 0xd8, 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, - 0xda, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, - 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x83, - 0xd8, 0xac, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, - 0xaf, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, - 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, - 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, - 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd8, 0xa7, 0x0a, - 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xda, - 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, - 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd9, 0x86, - 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, - 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, - 0x0a, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, - 0x86, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd8, - 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaf, - 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xab, - 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, - 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, - 0xaa, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, - 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb3, - 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, - 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb6, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, - 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, - 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, - 0xd9, 0x88, 0x0a, 0xd8, 0xac, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, - 0xd9, 0x88, 0xd9, 0x84, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, - 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, - 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, 0xd8, 0xaf, 0xd8, - 0xaa, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, - 0xa7, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0x0a, 0xd8, - 0xaa, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, - 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, - 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd9, - 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xaf, - 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, - 0xd9, 0x85, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, - 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xb5, 0xd8, 0xaf, 0x0a, 0xd9, - 0x81, 0xd9, 0x82, 0xd8, 0xb7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x8a, - 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, - 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, - 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xb7, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x85, 0x0a, - 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, - 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, - 0x81, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, - 0x83, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, - 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb7, - 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, - 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, - 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, 0xd9, - 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb7, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, - 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb2, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, - 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, - 0xb4, 0xd8, 0xaa, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xd8, 0xb7, 0xd8, 0xb1, 0xd9, - 0x8a, 0xd9, 0x82, 0x0a, 0xd8, 0xa7, 0xd8, 0xb4, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, - 0xaa, 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, - 0x8a, 0xd8, 0xaf, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, - 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, - 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, - 0xa7, 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, - 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, - 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, - 0xaf, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, - 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, - 0x87, 0xd9, 0x85, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0xbe, 0xd8, 0xa7, - 0xd8, 0xb9, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0x0a, 0xd8, 0xad, 0xd8, 0xaf, - 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x81, 0x0a, - 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, - 0xb2, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, - 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xb6, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, - 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, - 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, - 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xb3, 0xd9, 0x8a, - 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xae, - 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xda, 0x86, 0xd9, 0x88, 0xd9, - 0x86, 0x0a, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xac, 0x0a, 0xd8, 0xb4, 0xd8, 0xb4, 0x0a, - 0xd9, 0x87, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaa, 0x0a, - 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, - 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x83, 0xd8, - 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0xbe, 0xd9, - 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd9, - 0x88, 0xd8, 0xb2, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, - 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, - 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x88, - 0xd9, 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xda, 0x86, 0xd9, 0x86, - 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, - 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, - 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xaf, - 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0x0a, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaf, - 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd8, 0xaa, 0xd9, 0x8a, - 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, - 0xd9, 0x82, 0xd8, 0xa8, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, - 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, - 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x87, 0x0a, - 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, - 0xd9, 0x85, 0xd8, 0xab, 0xd9, 0x84, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, - 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, - 0xd9, 0x87, 0x0a, 0xd8, 0xb7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, - 0x0a, 0xd8, 0xa7, 0xda, 0xaf, 0xd8, 0xb1, 0x0a, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaa, - 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, - 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, - 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, - 0x86, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, - 0x0a, 0xd9, 0x84, 0xd8, 0xb7, 0xd9, 0x81, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, - 0xaf, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd9, 0x86, - 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x8a, - 0xd9, 0x86, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, - 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd8, - 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, - 0x87, 0xd9, 0x85, 0x0a, 0xd9, 0x81, 0xd9, 0x88, 0xd9, 0x82, 0x0a, 0xd9, 0x86, 0xd9, 0x87, 0x0a, - 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x88, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, - 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, - 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd9, 0x84, 0x0a, - 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd9, - 0x87, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, - 0x85, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, - 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x83, 0xd9, - 0x86, 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, - 0xb2, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, - 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd9, 0x84, 0xd9, - 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, + 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, + 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xb1, + 0x0a, 0xd8, 0xae, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xb4, + 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x83, + 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, 0xaa, 0xd8, + 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x85, 0x0a, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, + 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x88, 0x0a, + 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, 0xd8, + 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, + 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0xda, 0xaf, 0xd8, 0xb2, 0x0a, 0xd9, 0xbe, 0xd9, + 0x86, 0xd8, 0xac, 0x0a, 0xd9, 0x86, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, + 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, + 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd8, 0xb7, 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, + 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, + 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xda, + 0x86, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, + 0xb7, 0x0a, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x82, + 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb1, 0xd9, 0x81, + 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, 0x86, + 0xd9, 0x86, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x87, 0xd8, 0xb2, + 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, + 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, + 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, + 0xd8, 0xb1, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, + 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, + 0x86, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, + 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, + 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x88, 0xd9, + 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, + 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, 0xd8, 0xac, 0xd8, 0xb2, + 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, + 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd8, 0xaf, + 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xaa, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, + 0xd8, 0xb1, 0xd8, 0xae, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, + 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd9, + 0x84, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd9, 0x82, + 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd9, 0x88, + 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, + 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xb8, 0xd9, 0x8a, 0xd8, + 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, + 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, + 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, + 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, + 0xb4, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, + 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, + 0xd8, 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, + 0xda, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, + 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x83, + 0xd8, 0xac, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, + 0xaf, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, + 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, + 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, + 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd8, 0xa7, 0x0a, + 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xda, + 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, + 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd9, 0x86, + 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, + 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, + 0x0a, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, + 0x86, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd8, + 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaf, + 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xab, + 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, + 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, + 0xaa, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, + 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb3, + 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, + 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb6, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, + 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, + 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, + 0xd9, 0x88, 0x0a, 0xd8, 0xac, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, + 0xd9, 0x88, 0xd9, 0x84, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, + 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, 0xd8, 0xaf, 0xd8, + 0xaa, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, + 0xa7, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0x0a, 0xd8, + 0xaa, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, + 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, + 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd9, + 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xaf, + 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, + 0xd9, 0x85, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, + 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xb5, 0xd8, 0xaf, 0x0a, 0xd9, + 0x81, 0xd9, 0x82, 0xd8, 0xb7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x8a, + 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, + 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, + 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xb7, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x85, 0x0a, + 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, + 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, + 0x81, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, + 0x83, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, + 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb7, + 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, + 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, + 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb7, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, + 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb2, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, + 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, + 0xb4, 0xd8, 0xaa, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xd8, 0xb7, 0xd8, 0xb1, 0xd9, + 0x8a, 0xd9, 0x82, 0x0a, 0xd8, 0xa7, 0xd8, 0xb4, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, + 0xaa, 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, + 0x8a, 0xd8, 0xaf, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, + 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, + 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, + 0xa7, 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, + 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, + 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, + 0xaf, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, + 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, + 0x87, 0xd9, 0x85, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0xbe, 0xd8, 0xa7, + 0xd8, 0xb9, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0x0a, 0xd8, 0xad, 0xd8, 0xaf, + 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x81, 0x0a, + 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, + 0xb2, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, + 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xb6, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, + 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, + 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, + 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xb3, 0xd9, 0x8a, + 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xae, + 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xda, 0x86, 0xd9, 0x88, 0xd9, + 0x86, 0x0a, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xac, 0x0a, 0xd8, 0xb4, 0xd8, 0xb4, 0x0a, + 0xd9, 0x87, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaa, 0x0a, + 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, + 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x83, 0xd8, + 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0xbe, 0xd9, + 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd9, + 0x88, 0xd8, 0xb2, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, + 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x88, + 0xd9, 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xda, 0x86, 0xd9, 0x86, + 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, + 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, + 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xaf, + 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0x0a, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaf, + 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd8, 0xaa, 0xd9, 0x8a, + 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, + 0xd9, 0x82, 0xd8, 0xa8, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, + 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, + 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x87, 0x0a, + 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, + 0xd9, 0x85, 0xd8, 0xab, 0xd9, 0x84, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x87, 0x0a, 0xd8, 0xb7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, + 0x0a, 0xd8, 0xa7, 0xda, 0xaf, 0xd8, 0xb1, 0x0a, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaa, + 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, + 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, + 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, + 0x86, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, + 0x0a, 0xd9, 0x84, 0xd8, 0xb7, 0xd9, 0x81, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, + 0xaf, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd9, 0x86, + 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x8a, + 0xd9, 0x86, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, + 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd8, + 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, + 0x87, 0xd9, 0x85, 0x0a, 0xd9, 0x81, 0xd9, 0x88, 0xd9, 0x82, 0x0a, 0xd9, 0x86, 0xd9, 0x87, 0x0a, + 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x88, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd9, 0x84, 0x0a, + 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd9, + 0x87, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, + 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x83, 0xd9, + 0x86, 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, + 0xb2, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, + 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd9, 0x84, 0xd9, + 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0x0a }; - + PersianAnalyzer::PersianAnalyzer(LuceneVersion::Version matchVersion) { this->stoptable = getDefaultStopSet(); this->matchVersion = matchVersion; } - + PersianAnalyzer::PersianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stoptable = stopwords; this->matchVersion = matchVersion; } - + PersianAnalyzer::~PersianAnalyzer() { } - + const HashSet PersianAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -218,7 +218,7 @@ namespace Lucene } return stopSet; } - + TokenStreamPtr PersianAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(reader); @@ -230,7 +230,7 @@ namespace Lucene result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); return result; } - + TokenStreamPtr PersianAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { PersianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -250,7 +250,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + PersianAnalyzerSavedStreams::~PersianAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp b/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp index d855ff04..59971923 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene normalizer = newLucene(); termAtt = addAttribute(); } - + PersianNormalizationFilter::~PersianNormalizationFilter() { } - + bool PersianNormalizationFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp b/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp index 7e8d1dd1..b0883b88 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,17 +13,17 @@ namespace Lucene const wchar_t PersianNormalizer::YEH = (wchar_t)0x064a; const wchar_t PersianNormalizer::FARSI_YEH = (wchar_t)0x06cc; const wchar_t PersianNormalizer::YEH_BARREE = (wchar_t)0x06d2; - const wchar_t PersianNormalizer::KEHEH = (wchar_t)0x06a9; + const wchar_t PersianNormalizer::KEHEH = (wchar_t)0x06a9; const wchar_t PersianNormalizer::KAF = (wchar_t)0x0643; - const wchar_t PersianNormalizer::HAMZA_ABOVE = (wchar_t)0x0654; + const wchar_t PersianNormalizer::HAMZA_ABOVE = (wchar_t)0x0654; const wchar_t PersianNormalizer::HEH_YEH = (wchar_t)0x06c0; const wchar_t PersianNormalizer::HEH_GOAL = (wchar_t)0x06c1; const wchar_t PersianNormalizer::HEH = (wchar_t)0x0647; - + PersianNormalizer::~PersianNormalizer() { } - + int32_t PersianNormalizer::normalize(wchar_t* s, int32_t len) { for (int32_t i = 0; i < len; ++i) @@ -50,7 +50,7 @@ namespace Lucene } return len; } - + int32_t PersianNormalizer::deleteChar(wchar_t* s, int32_t pos, int32_t len) { if (pos < len) diff --git a/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp b/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp index 30f70099..36224bc3 100644 --- a/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,35 +12,35 @@ namespace Lucene { const wchar_t ElisionFilter::apostrophes[] = {L'\'', L'\x2019'}; - + ElisionFilter::ElisionFilter(TokenStreamPtr input) : TokenFilter(input) { articles = newLucene(newCollection(L"l", L"m", L"t", L"qu", L"n", L"s", L"j"), true); termAtt = addAttribute(); } - + ElisionFilter::ElisionFilter(TokenStreamPtr input, HashSet articles) : TokenFilter(input) { setArticles(articles); termAtt = addAttribute(); } - + ElisionFilter::~ElisionFilter() { } - + void ElisionFilter::setArticles(HashSet articles) { this->articles = newLucene(articles, true); } - + bool ElisionFilter::incrementToken() { if (input->incrementToken()) { wchar_t* termBuffer = termAtt->termBufferArray(); int32_t termLength = termAtt->termLength(); - + int32_t minPoz = INT_MAX; for (int32_t i = 0; i < SIZEOF_ARRAY(apostrophes); ++i) { @@ -54,11 +54,11 @@ namespace Lucene } } } - + // An apostrophe has been found. If the prefix is an article strip it off. if (minPoz != INT_MAX && articles->contains(termBuffer, 0, minPoz)) termAtt->setTermBuffer(termBuffer, minPoz + 1, termLength - (minPoz + 1)); - + return true; } else diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp index 7f2b57a6..1b94e487 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,56 +14,56 @@ namespace Lucene { - const wchar_t* FrenchAnalyzer::_FRENCH_STOP_WORDS[] = + const wchar_t* FrenchAnalyzer::_FRENCH_STOP_WORDS[] = { L"a", L"afin", L"ai", L"ainsi", L"apr\x00e8s", L"attendu", L"au", L"aujourd", L"auquel", L"aussi", L"autre", L"autres", L"aux", L"auxquelles", L"auxquels", L"avait", L"avant", L"avec", L"avoir", L"c", L"car", L"ce", L"ceci", L"cela", L"celle", L"celles", L"celui", L"cependant", L"certain", L"certaine", L"certaines", L"certains", L"ces", L"cet", L"cette", L"ceux", L"chez", L"ci", L"combien", L"comme", L"comment", L"concernant", L"contre", L"d", L"dans", L"de", L"debout", - L"dedans", L"dehors", L"del\x00e0", L"depuis", L"derri\x00e8re", L"des", L"d\x00e9sormais", - L"desquelles", L"desquels", L"dessous", L"dessus", L"devant", L"devers", L"devra", L"divers", - L"diverse", L"diverses", L"doit", L"donc", L"dont", L"du", L"duquel", L"durant", L"d\x00e8s", - L"elle", L"elles", L"en", L"entre", L"environ", L"est", L"et", L"etc", L"etre", L"eu", L"eux", - L"except\x00e9", L"hormis", L"hors", L"h\x00e9las", L"hui", L"il", L"ils", L"j", L"je", L"jusqu", - L"jusque", L"l", L"la", L"laquelle", L"le", L"lequel", L"les", L"lesquelles", L"lesquels", L"leur", - L"leurs", L"lorsque", L"lui", L"l\x00e0", L"ma", L"mais", L"malgr\x00e9", L"me", L"merci", L"mes", - L"mien", L"mienne", L"miennes", L"miens", L"moi", L"moins", L"mon", L"moyennant", L"m\x00eame", - L"m\x00eames", L"n", L"ne", L"ni", L"non", L"nos", L"notre", L"nous", L"n\x00e9anmoins", - L"n\x00f4tre", L"n\x00f4tres", L"on", L"ont", L"ou", L"outre", L"o\x00f9", L"par", L"parmi", + L"dedans", L"dehors", L"del\x00e0", L"depuis", L"derri\x00e8re", L"des", L"d\x00e9sormais", + L"desquelles", L"desquels", L"dessous", L"dessus", L"devant", L"devers", L"devra", L"divers", + L"diverse", L"diverses", L"doit", L"donc", L"dont", L"du", L"duquel", L"durant", L"d\x00e8s", + L"elle", L"elles", L"en", L"entre", L"environ", L"est", L"et", L"etc", L"etre", L"eu", L"eux", + L"except\x00e9", L"hormis", L"hors", L"h\x00e9las", L"hui", L"il", L"ils", L"j", L"je", L"jusqu", + L"jusque", L"l", L"la", L"laquelle", L"le", L"lequel", L"les", L"lesquelles", L"lesquels", L"leur", + L"leurs", L"lorsque", L"lui", L"l\x00e0", L"ma", L"mais", L"malgr\x00e9", L"me", L"merci", L"mes", + L"mien", L"mienne", L"miennes", L"miens", L"moi", L"moins", L"mon", L"moyennant", L"m\x00eame", + L"m\x00eames", L"n", L"ne", L"ni", L"non", L"nos", L"notre", L"nous", L"n\x00e9anmoins", + L"n\x00f4tre", L"n\x00f4tres", L"on", L"ont", L"ou", L"outre", L"o\x00f9", L"par", L"parmi", L"partant", L"pas", L"pass\x00e9", L"pendant", L"plein", L"plus", L"plusieurs", L"pour", L"pourquoi", - L"proche", L"pr\x00e8s", L"puisque", L"qu", L"quand", L"que", L"quel", L"quelle", L"quelles", - L"quels", L"qui", L"quoi", L"quoique", L"revoici", L"revoil\x00e0", L"s", L"sa", L"sans", L"sauf", - L"se", L"selon", L"seront", L"ses", L"si", L"sien", L"sienne", L"siennes", L"siens", L"sinon", - L"soi", L"soit", L"son", L"sont", L"sous", L"suivant", L"sur", L"ta", L"te", L"tes", L"tien", - L"tienne", L"tiennes", L"tiens", L"toi", L"ton", L"tous", L"tout", L"toute", L"toutes", L"tu", L"un", - L"une", L"va", L"vers", L"voici", L"voil\x00e0", L"vos", L"votre", L"vous", L"vu", L"v\x00f4tre", + L"proche", L"pr\x00e8s", L"puisque", L"qu", L"quand", L"que", L"quel", L"quelle", L"quelles", + L"quels", L"qui", L"quoi", L"quoique", L"revoici", L"revoil\x00e0", L"s", L"sa", L"sans", L"sauf", + L"se", L"selon", L"seront", L"ses", L"si", L"sien", L"sienne", L"siennes", L"siens", L"sinon", + L"soi", L"soit", L"son", L"sont", L"sous", L"suivant", L"sur", L"ta", L"te", L"tes", L"tien", + L"tienne", L"tiennes", L"tiens", L"toi", L"ton", L"tous", L"tout", L"toute", L"toutes", L"tu", L"un", + L"une", L"va", L"vers", L"voici", L"voil\x00e0", L"vos", L"votre", L"vous", L"vu", L"v\x00f4tre", L"v\x00f4tres", L"y", L"\x00e0", L"\x00e7a", L"\x00e8s", L"\x00e9t\x00e9", L"\x00eatre", L"\x00f4" }; - + FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion) { this->stoptable = getDefaultStopSet(); this->matchVersion = matchVersion; } - + FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stoptable = stopwords; this->matchVersion = matchVersion; } - + FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { this->stoptable = stopwords; this->excltable = exclusions; this->matchVersion = matchVersion; } - + FrenchAnalyzer::~FrenchAnalyzer() { } - + const HashSet FrenchAnalyzer::getDefaultStopSet() { static HashSet stoptable; @@ -71,13 +71,13 @@ namespace Lucene stoptable = HashSet::newInstance(_FRENCH_STOP_WORDS, _FRENCH_STOP_WORDS + SIZEOF_ARRAY(_FRENCH_STOP_WORDS)); return stoptable; } - + void FrenchAnalyzer::setStemExclusionTable(HashSet exclusions) { excltable = exclusions; setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - + TokenStreamPtr FrenchAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(matchVersion, reader); @@ -85,10 +85,10 @@ namespace Lucene result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); result = newLucene(result, excltable); // Convert to lowercase after stemming - result = newLucene(result); + result = newLucene(result); return result; } - + TokenStreamPtr FrenchAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { FrenchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -100,14 +100,14 @@ namespace Lucene streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); streams->result = newLucene(streams->result, excltable); // Convert to lowercase after stemming - streams->result = newLucene(streams->result); + streams->result = newLucene(streams->result); setPreviousTokenStream(streams); } else streams->source->reset(reader); return streams->result; } - + FrenchAnalyzerSavedStreams::~FrenchAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp index 822b508f..d7062d6d 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,18 +16,18 @@ namespace Lucene stemmer = newLucene(); termAtt = addAttribute(); } - + FrenchStemFilter::FrenchStemFilter(TokenStreamPtr input, HashSet exclusiontable) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); this->exclusions = exclusiontable; } - + FrenchStemFilter::~FrenchStemFilter() { } - + bool FrenchStemFilter::incrementToken() { if (input->incrementToken()) @@ -46,13 +46,13 @@ namespace Lucene else return false; } - + void FrenchStemFilter::setStemmer(FrenchStemmerPtr stemmer) { if (stemmer) this->stemmer = stemmer; } - + void FrenchStemFilter::setExclusionSet(HashSet exclusiontable) { this->exclusions = exclusiontable; diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp index d4349eb0..6d0e176b 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,16 +18,16 @@ namespace Lucene suite = false; modified = false; } - + FrenchStemmer::~FrenchStemmer() { } - + String FrenchStemmer::stem(const String& term) { if (!isStemmable(term)) return term; - + // Use lowercase for medium stemming. stringBuffer = StringUtils::toLower(term); @@ -62,7 +62,7 @@ namespace Lucene return stringBuffer; } - + void FrenchStemmer::setStrings() { // set the strings @@ -77,7 +77,7 @@ namespace Lucene else R2.clear(); } - + void FrenchStemmer::step1() { Collection suffix = newCollection(L"ances", L"iqUes", L"ismes", L"ables", L"istes", L"ance", L"iqUe", L"isme", L"able", L"iste"); @@ -123,56 +123,56 @@ namespace Lucene if (deleteFromIfTestVowelBeforeIn(RV, newCollection(L"ments", L"ment"), true, RV)) suite = true; } - + bool FrenchStemmer::step2a() { static Collection search; if (!search) { - static const wchar_t* _search[] = + static const wchar_t* _search[] = { L"\x00eemes", L"\x00eetes", L"iraIent", L"irait", L"irais", L"irai", L"iras", L"ira", - L"irent", L"iriez", L"irez", L"irions", L"irons", L"iront", L"issaIent", - L"issais", L"issantes", L"issante", L"issants", L"issant", L"issait", - L"issais", L"issions", L"issons", L"issiez", L"issez", L"issent", L"isses", + L"irent", L"iriez", L"irez", L"irions", L"irons", L"iront", L"issaIent", + L"issais", L"issantes", L"issante", L"issants", L"issant", L"issait", + L"issais", L"issions", L"issons", L"issiez", L"issez", L"issent", L"isses", L"isse", L"ir", L"is", L"\x00eet", L"it", L"ies", L"ie", L"i" }; search = Collection::newInstance(_search, _search + SIZEOF_ARRAY(_search)); } return deleteFromIfTestVowelBeforeIn(RV, search, false, RV); } - + void FrenchStemmer::step2b() { static Collection suffix; if (!suffix) { - static const wchar_t* _suffix[] = + static const wchar_t* _suffix[] = { - L"eraIent", L"erais", L"erait", L"erai", L"eras", L"erions", L"eriez", - L"erons", L"eront", L"erez", L"\x00e8rent", L"era", L"\x00e9es", L"iez", L"\x00e9e", L"\x00e9s", + L"eraIent", L"erais", L"erait", L"erai", L"eras", L"erions", L"eriez", + L"erons", L"eront", L"erez", L"\x00e8rent", L"era", L"\x00e9es", L"iez", L"\x00e9e", L"\x00e9s", L"er", L"ez", L"\x00e9" }; suffix = Collection::newInstance(_suffix, _suffix + SIZEOF_ARRAY(_suffix)); } deleteFrom(RV, suffix); - + static Collection search; if (!search) { - static const wchar_t* _search[] = + static const wchar_t* _search[] = { - L"assions", L"assiez", L"assent", L"asses", L"asse", L"aIent", L"antes", - L"aIent", L"Aient", L"ante", L"\x00e2mes", L"\x00e2tes", L"ants", L"ant", L"ait", + L"assions", L"assiez", L"assent", L"asses", L"asse", L"aIent", L"antes", + L"aIent", L"Aient", L"ante", L"\x00e2mes", L"\x00e2tes", L"ants", L"ant", L"ait", L"a\x00eet", L"ais", L"Ait", L"A\x00eet", L"Ais", L"\x00e2t", L"as", L"ai", L"Ai", L"a" }; search = Collection::newInstance(_search, _search + SIZEOF_ARRAY(_search)); } deleteButSuffixFrom(RV, search, L"e", true); - + deleteFrom(R2, newCollection(L"ions")); } - + void FrenchStemmer::step3() { if (!stringBuffer.empty()) @@ -190,7 +190,7 @@ namespace Lucene } } } - + void FrenchStemmer::step4() { if (stringBuffer.length() > 1) @@ -213,12 +213,12 @@ namespace Lucene deleteFrom(RV, newCollection(L"e")); deleteFromIfPrecededIn(RV, newCollection(L"\x00eb"), R0, L"gu"); } - + void FrenchStemmer::step5() { if (!R0.empty()) { - if (boost::ends_with(R0, L"enn") || boost::ends_with(R0, L"onn") || + if (boost::ends_with(R0, L"enn") || boost::ends_with(R0, L"onn") || boost::ends_with(R0, L"ett") || boost::ends_with(R0, L"ell") || boost::ends_with(R0, L"eill")) { stringBuffer.resize(stringBuffer.length() - 1); @@ -226,7 +226,7 @@ namespace Lucene } } } - + void FrenchStemmer::step6() { if (!R0.empty()) @@ -261,7 +261,7 @@ namespace Lucene stringBuffer[pos] = L'e'; } } - + bool FrenchStemmer::deleteFromIfPrecededIn(const String& source, Collection search, const String& from, const String& prefix) { bool found = false; @@ -283,7 +283,7 @@ namespace Lucene } return found; } - + bool FrenchStemmer::deleteFromIfTestVowelBeforeIn(const String& source, Collection search, bool vowel, const String& from) { bool found = false; @@ -310,7 +310,7 @@ namespace Lucene } return found; } - + void FrenchStemmer::deleteButSuffixFrom(const String& source, Collection search, const String& prefix, bool without) { if (!source.empty()) @@ -334,7 +334,7 @@ namespace Lucene } } } - + void FrenchStemmer::deleteButSuffixFromElseReplace(const String& source, Collection search, const String& prefix, bool without, const String& from, const String& replace) { if (!source.empty()) @@ -366,7 +366,7 @@ namespace Lucene } } } - + bool FrenchStemmer::replaceFrom(const String& source, Collection search, const String& replace) { bool found = false; @@ -387,7 +387,7 @@ namespace Lucene } return found; } - + void FrenchStemmer::deleteFrom(const String& source, Collection suffix) { if (!source.empty()) @@ -404,7 +404,7 @@ namespace Lucene } } } - + bool FrenchStemmer::isVowel(wchar_t ch) { switch (ch) @@ -432,7 +432,7 @@ namespace Lucene return false; } } - + String FrenchStemmer::retrieveR(const String& buffer) { int32_t len = (int32_t)buffer.length(); @@ -464,7 +464,7 @@ namespace Lucene else return L""; } - + String FrenchStemmer::retrieveRV(const String& buffer) { int32_t len = (int32_t)buffer.length(); @@ -492,10 +492,10 @@ namespace Lucene else return L""; } - + void FrenchStemmer::treatVowels(String& buffer) { - + for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) { wchar_t ch = buffer[c]; @@ -537,7 +537,7 @@ namespace Lucene } } } - + bool FrenchStemmer::isStemmable(const String& term) { bool upper = false; diff --git a/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp b/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp index 46cbfdaa..49105e5c 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,20 +13,20 @@ namespace Lucene { - const wchar_t* DutchAnalyzer::_DUTCH_STOP_WORDS[] = + const wchar_t* DutchAnalyzer::_DUTCH_STOP_WORDS[] = { - L"de", L"en", L"van", L"ik", L"te", L"dat", L"die", L"in", L"een", L"hij", L"het", L"niet", - L"zijn", L"is", L"was", L"op", L"aan", L"met", L"als", L"voor", L"had", L"er", L"maar", - L"om", L"hem", L"dan", L"zou", L"of", L"wat", L"mijn", L"men", L"dit", L"zo", L"door", + L"de", L"en", L"van", L"ik", L"te", L"dat", L"die", L"in", L"een", L"hij", L"het", L"niet", + L"zijn", L"is", L"was", L"op", L"aan", L"met", L"als", L"voor", L"had", L"er", L"maar", + L"om", L"hem", L"dan", L"zou", L"of", L"wat", L"mijn", L"men", L"dit", L"zo", L"door", L"over", L"ze", L"zich", L"bij", L"ook", L"tot", L"je", L"mij", L"uit", L"der", L"daar", - L"haar", L"naar", L"heb", L"hoe", L"heeft", L"hebben", L"deze", L"u", L"want", L"nog", - L"zal", L"me", L"zij", L"nu", L"ge", L"geen", L"omdat", L"iets", L"worden", L"toch", - L"al", L"waren", L"veel", L"meer", L"doen", L"toen", L"moet", L"ben", L"zonder", L"kan", - L"hun", L"dus", L"alles", L"onder", L"ja", L"eens", L"hier", L"wie", L"werd", L"altijd", - L"doch", L"wordt", L"wezen", L"kunnen", L"ons", L"zelf", L"tegen", L"na", L"reeds", L"wil", + L"haar", L"naar", L"heb", L"hoe", L"heeft", L"hebben", L"deze", L"u", L"want", L"nog", + L"zal", L"me", L"zij", L"nu", L"ge", L"geen", L"omdat", L"iets", L"worden", L"toch", + L"al", L"waren", L"veel", L"meer", L"doen", L"toen", L"moet", L"ben", L"zonder", L"kan", + L"hun", L"dus", L"alles", L"onder", L"ja", L"eens", L"hier", L"wie", L"werd", L"altijd", + L"doch", L"wordt", L"wezen", L"kunnen", L"ons", L"zelf", L"tegen", L"na", L"reeds", L"wil", L"kon", L"niets", L"uw", L"iemand", L"geweest", L"andere" }; - + DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion) { this->stoptable = getDefaultStopSet(); @@ -34,25 +34,25 @@ namespace Lucene this->stemdict = MapStringString::newInstance(); this->matchVersion = matchVersion; } - + DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stoptable = stopwords; this->excltable = HashSet::newInstance(); this->matchVersion = matchVersion; } - + DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { this->stoptable = stopwords; this->excltable = exclusions; this->matchVersion = matchVersion; } - + DutchAnalyzer::~DutchAnalyzer() { } - + void DutchAnalyzer::initialize() { stemdict.put(L"fiets", L"fiets"); // otherwise fiet @@ -60,7 +60,7 @@ namespace Lucene stemdict.put(L"ei", L"eier"); stemdict.put(L"kind", L"kinder"); } - + const HashSet DutchAnalyzer::getDefaultStopSet() { static HashSet stoptable; @@ -68,13 +68,13 @@ namespace Lucene stoptable = HashSet::newInstance(_DUTCH_STOP_WORDS, _DUTCH_STOP_WORDS + SIZEOF_ARRAY(_DUTCH_STOP_WORDS)); return stoptable; } - + void DutchAnalyzer::setStemExclusionTable(HashSet exclusions) { excltable = exclusions; setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - + TokenStreamPtr DutchAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(matchVersion, reader); @@ -83,7 +83,7 @@ namespace Lucene result = newLucene(result, excltable); return result; } - + TokenStreamPtr DutchAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { DutchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -100,7 +100,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + DutchAnalyzerSavedStreams::~DutchAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp b/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp index 37230245..76f73d62 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,14 +16,14 @@ namespace Lucene stemmer = newLucene(); termAtt = addAttribute(); } - + DutchStemFilter::DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); this->exclusions = exclusiontable; } - + DutchStemFilter::DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable, MapStringString stemdictionary) : TokenFilter(input) { stemmer = newLucene(); @@ -31,17 +31,17 @@ namespace Lucene this->exclusions = exclusiontable; this->stemmer->setStemDictionary(stemdictionary); } - + DutchStemFilter::~DutchStemFilter() { } - + bool DutchStemFilter::incrementToken() { if (input->incrementToken()) { String term(termAtt->term()); - + // Check the exclusion table. if (!exclusions || !exclusions.contains(term)) { @@ -55,18 +55,18 @@ namespace Lucene else return false; } - + void DutchStemFilter::setStemmer(DutchStemmerPtr stemmer) { if (stemmer) this->stemmer = stemmer; } - + void DutchStemFilter::setExclusionSet(HashSet exclusiontable) { this->exclusions = exclusiontable; } - + void DutchStemFilter::setStemDictionary(MapStringString dict) { if (stemmer) diff --git a/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp b/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp index 191282e7..ad2f8c6f 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,18 +19,18 @@ namespace Lucene R1 = 0; R2 = 0; } - + DutchStemmer::~DutchStemmer() { } - + String DutchStemmer::stem(const String& term) { // Use lowercase for medium stemming. buffer = StringUtils::toLower(term); if (!isStemmable()) return buffer; - + if (stemDict && stemDict.contains(term)) return stemDict.get(term); @@ -65,7 +65,7 @@ namespace Lucene } return false; } - + void DutchStemmer::step1() { if (R1 >= (int32_t)buffer.length()) @@ -82,19 +82,19 @@ namespace Lucene if (enEnding()) return; - + index = (int32_t)buffer.length() - 2; if (boost::ends_with(buffer, L"se") && index >= R1 && isValidSEnding(index - 1)) { buffer.erase(index, 2); return; } - + index = (int32_t)(buffer.length() - 1); if (boost::ends_with(buffer, L"s") && index >= R1 && isValidSEnding(index - 1)) buffer.erase(index, 1); } - + void DutchStemmer::step2() { removedE = false; @@ -108,7 +108,7 @@ namespace Lucene removedE = true; } } - + void DutchStemmer::step3a() { if (R2 >= (int32_t)buffer.length()) @@ -120,12 +120,12 @@ namespace Lucene enEnding(); } } - + void DutchStemmer::step3b() { if (R2 >= (int32_t)buffer.length()) return; - + int32_t index = (int32_t)(buffer.length() - 3); if ((boost::ends_with(buffer, L"end") || boost::ends_with(buffer, L"ing")) && index >= R2) { @@ -170,7 +170,7 @@ namespace Lucene return; } } - + void DutchStemmer::step4() { if (buffer.length() < 4) @@ -179,7 +179,7 @@ namespace Lucene if (end[1] == end[2] && end[3] != L'I' && end[1] != L'i' && isVowel(end[1]) && !isVowel(end[3]) && !isVowel(end[0])) buffer.erase(buffer.length() - 2, 1); } - + bool DutchStemmer::isStemmable() { for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) @@ -189,7 +189,7 @@ namespace Lucene } return true; } - + void DutchStemmer::substitute() { for (int32_t i = 0; i < (int32_t)buffer.length(); ++i) @@ -219,7 +219,7 @@ namespace Lucene } } } - + bool DutchStemmer::isValidSEnding(int32_t index) { wchar_t c = buffer[index]; @@ -227,7 +227,7 @@ namespace Lucene return false; return true; } - + bool DutchStemmer::isValidEnEnding(int32_t index) { wchar_t c = buffer[index]; @@ -240,20 +240,20 @@ namespace Lucene return false; return true; } - + void DutchStemmer::unDouble() { unDouble((int32_t)buffer.length()); } - + void DutchStemmer::unDouble(int32_t endIndex) { String s = buffer.substr(0, endIndex); - if (boost::ends_with(s, L"kk") || boost::ends_with(s, L"tt") || boost::ends_with(s, L"dd") || + if (boost::ends_with(s, L"kk") || boost::ends_with(s, L"tt") || boost::ends_with(s, L"dd") || boost::ends_with(s, L"nn") || boost::ends_with(s, L"mm") || boost::ends_with(s, L"ff")) buffer.resize(endIndex - 1); } - + int32_t DutchStemmer::getRIndex(int32_t start) { if (start == 0) @@ -267,7 +267,7 @@ namespace Lucene } return i + 1; } - + void DutchStemmer::storeYandI() { if (buffer[0] == L'y') @@ -292,13 +292,13 @@ namespace Lucene if (last > 0 && buffer[last] == L'y' && isVowel(buffer[last - 1])) buffer[last] = L'Y'; } - + void DutchStemmer::reStoreYandI() { boost::replace_all(buffer, L"I", L"i"); boost::replace_all(buffer, L"Y", L"y"); } - + bool DutchStemmer::isVowel(wchar_t c) { switch (c) @@ -315,7 +315,7 @@ namespace Lucene return false; } } - + void DutchStemmer::setStemDictionary(MapStringString dict) { stemDict = dict; diff --git a/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp b/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp index e470a592..13caf383 100644 --- a/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp +++ b/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,35 +11,35 @@ namespace Lucene { const wchar_t ReverseStringFilter::NOMARKER = (wchar_t)0xffff; - - /// Example marker character: U+0001 (START OF HEADING) + + /// Example marker character: U+0001 (START OF HEADING) const wchar_t ReverseStringFilter::START_OF_HEADING_MARKER = (wchar_t)0x0001; - + /// Example marker character: U+001F (INFORMATION SEPARATOR ONE) const wchar_t ReverseStringFilter::INFORMATION_SEPARATOR_MARKER = (wchar_t)0x001f; - - /// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) + + /// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) const wchar_t ReverseStringFilter::PUA_EC00_MARKER = (wchar_t)0xec00; - + /// Example marker character: U+200F (RIGHT-TO-LEFT MARK) const wchar_t ReverseStringFilter::RTL_DIRECTION_MARKER = (wchar_t)0x200f; - + ReverseStringFilter::ReverseStringFilter(TokenStreamPtr input) : TokenFilter(input) { this->marker = NOMARKER; termAtt = addAttribute(); } - + ReverseStringFilter::ReverseStringFilter(TokenStreamPtr input, wchar_t marker) : TokenFilter(input) { this->marker = marker; termAtt = addAttribute(); } - + ReverseStringFilter::~ReverseStringFilter() { } - + bool ReverseStringFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp index 4bd04a86..d1cda356 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,70 +15,70 @@ namespace Lucene { /// Default Russian stopwords in UTF-8 format. - const uint8_t RussianAnalyzer::DEFAULT_STOPWORD_FILE[] = + const uint8_t RussianAnalyzer::DEFAULT_STOPWORD_FILE[] = { - 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb7, 0x0a, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, 0xbb, - 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, - 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, - 0xd0, 0xb8, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xbe, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, - 0xd1, 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb2, 0x0a, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbc, 0x0a, 0xd0, - 0xb2, 0xd0, 0xb0, 0xd1, 0x81, 0x0a, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, 0xd0, - 0xb2, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, - 0xb5, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd1, - 0x81, 0xd0, 0xb5, 0xd1, 0x85, 0x0a, 0xd0, 0xb2, 0xd1, 0x8b, 0x0a, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, - 0xb5, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, - 0xd0, 0xb4, 0xd0, 0xbb, 0xd1, 0x8f, 0x0a, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb3, - 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd0, 0xb5, 0xd1, - 0x8e, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, - 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb5, 0xd1, 0x89, 0xd0, 0xb5, 0x0a, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, - 0xd0, 0xb7, 0xd0, 0xb0, 0x0a, 0xd0, 0xb7, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, - 0xd0, 0xb8, 0x0a, 0xd0, 0xb8, 0xd0, 0xb7, 0x0a, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, - 0xb8, 0xd0, 0xbc, 0x0a, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xb0, - 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, - 0xd0, 0xb0, 0x0a, 0xd0, 0xba, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, - 0xbb, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, 0xbe, 0x0a, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, - 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, 0xd0, 0xbc, 0xd1, 0x8b, 0x0a, 0xd0, - 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, - 0xb0, 0xd1, 0x88, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, - 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, - 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xbd, 0xd0, 0xbe, - 0x0a, 0xd0, 0xbd, 0xd1, 0x83, 0x0a, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xb1, 0x0a, 0xd0, 0xbe, - 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0x0a, - 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbe, - 0xd0, 0xbd, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, 0xb5, - 0xd0, 0xbd, 0xd1, 0x8c, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xb4, - 0x0a, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb8, 0x0a, 0xd1, 0x81, 0x0a, 0xd1, 0x81, 0xd0, 0xbe, 0x0a, - 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb6, 0xd0, - 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, 0xd0, - 0xb0, 0xd0, 0xbc, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0x0a, - 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, - 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, - 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, - 0xbc, 0x0a, 0xd1, 0x82, 0xd1, 0x8b, 0x0a, 0xd1, 0x83, 0x0a, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb5, - 0x0a, 0xd1, 0x85, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x8f, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, - 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbc, - 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb1, - 0xd1, 0x8b, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd0, 0xb5, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd1, 0x8f, - 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb0, 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb8, 0x0a, 0xd1, + 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb7, 0x0a, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, 0xbb, + 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, + 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, + 0xd0, 0xb8, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xbe, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, + 0xd1, 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb2, 0x0a, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbc, 0x0a, 0xd0, + 0xb2, 0xd0, 0xb0, 0xd1, 0x81, 0x0a, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, 0xd0, + 0xb2, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, + 0xb5, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd1, + 0x81, 0xd0, 0xb5, 0xd1, 0x85, 0x0a, 0xd0, 0xb2, 0xd1, 0x8b, 0x0a, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, + 0xb5, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, + 0xd0, 0xb4, 0xd0, 0xbb, 0xd1, 0x8f, 0x0a, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb3, + 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd0, 0xb5, 0xd1, + 0x8e, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, + 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb5, 0xd1, 0x89, 0xd0, 0xb5, 0x0a, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, + 0xd0, 0xb7, 0xd0, 0xb0, 0x0a, 0xd0, 0xb7, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, + 0xd0, 0xb8, 0x0a, 0xd0, 0xb8, 0xd0, 0xb7, 0x0a, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, + 0xb8, 0xd0, 0xbc, 0x0a, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xb0, + 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, + 0xd0, 0xb0, 0x0a, 0xd0, 0xba, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, + 0xbb, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, 0xbe, 0x0a, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, + 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, 0xd0, 0xbc, 0xd1, 0x8b, 0x0a, 0xd0, + 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, + 0xb0, 0xd1, 0x88, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, + 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, + 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xbd, 0xd0, 0xbe, + 0x0a, 0xd0, 0xbd, 0xd1, 0x83, 0x0a, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xb1, 0x0a, 0xd0, 0xbe, + 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0x0a, + 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbe, + 0xd0, 0xbd, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, 0xb5, + 0xd0, 0xbd, 0xd1, 0x8c, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xb4, + 0x0a, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb8, 0x0a, 0xd1, 0x81, 0x0a, 0xd1, 0x81, 0xd0, 0xbe, 0x0a, + 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb6, 0xd0, + 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, 0xd0, + 0xb0, 0xd0, 0xbc, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0x0a, + 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, + 0xbc, 0x0a, 0xd1, 0x82, 0xd1, 0x8b, 0x0a, 0xd1, 0x83, 0x0a, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb5, + 0x0a, 0xd1, 0x85, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x8f, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, + 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbc, + 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb1, + 0xd1, 0x8b, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd0, 0xb5, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd1, 0x8f, + 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb0, 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb8, 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x8f, 0x0a }; - + RussianAnalyzer::RussianAnalyzer(LuceneVersion::Version matchVersion) { this->stopSet = getDefaultStopSet(); this->matchVersion = matchVersion; } - + RussianAnalyzer::RussianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { this->stopSet = stopwords; this->matchVersion = matchVersion; } - + RussianAnalyzer::~RussianAnalyzer() { } - + const HashSet RussianAnalyzer::getDefaultStopSet() { static HashSet stopSet; @@ -90,7 +90,7 @@ namespace Lucene } return stopSet; } - + TokenStreamPtr RussianAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(reader); @@ -99,7 +99,7 @@ namespace Lucene result = newLucene(result); return result; } - + TokenStreamPtr RussianAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { RussianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -116,7 +116,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + RussianAnalyzerSavedStreams::~RussianAnalyzerSavedStreams() { } diff --git a/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp index 9a3c7a0f..e551f47f 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,19 +14,19 @@ namespace Lucene RussianLetterTokenizer::RussianLetterTokenizer(ReaderPtr input) : CharTokenizer(input) { } - + RussianLetterTokenizer::RussianLetterTokenizer(AttributeSourcePtr source, ReaderPtr input) : CharTokenizer(source, input) { } - + RussianLetterTokenizer::RussianLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : CharTokenizer(factory, input) { } - + RussianLetterTokenizer::~RussianLetterTokenizer() { } - + bool RussianLetterTokenizer::isTokenChar(wchar_t c) { return (UnicodeUtil::isAlpha(c) || UnicodeUtil::isDigit(c)); diff --git a/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp b/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp index 5015f481..3982ff67 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,11 +15,11 @@ namespace Lucene { termAtt = addAttribute(); } - + RussianLowerCaseFilter::~RussianLowerCaseFilter() { } - + bool RussianLowerCaseFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp b/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp index 9fc8f6d3..407194a8 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene stemmer = newLucene(); termAtt = addAttribute(); } - + RussianStemFilter::~RussianStemFilter() { } - + bool RussianStemFilter::incrementToken() { if (input->incrementToken()) @@ -34,7 +34,7 @@ namespace Lucene else return false; } - + void RussianStemFilter::setStemmer(RussianStemmerPtr stemmer) { if (stemmer) diff --git a/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp index a590b803..ff489fa8 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -32,20 +32,20 @@ namespace Lucene const wchar_t RussianStemmer::AE = L'\x044d'; const wchar_t RussianStemmer::IU = L'\x044e'; const wchar_t RussianStemmer::IA = L'\x044f'; - + const wchar_t RussianStemmer::vowels[] = {A, E, I, O, U, Y, AE, IU, IA}; - + RussianStemmer::RussianStemmer() { RV = 0; R1 = 0; R2 = 0; } - + RussianStemmer::~RussianStemmer() { } - + Collection RussianStemmer::perfectiveGerundEndings1() { static Collection _perfectiveGerundEndings1; @@ -58,7 +58,7 @@ namespace Lucene } return _perfectiveGerundEndings1; } - + Collection RussianStemmer::perfectiveGerund1Predessors() { static Collection _perfectiveGerund1Predessors; @@ -70,7 +70,7 @@ namespace Lucene } return _perfectiveGerund1Predessors; } - + Collection RussianStemmer::perfectiveGerundEndings2() { static Collection _perfectiveGerundEndings2; @@ -86,7 +86,7 @@ namespace Lucene } return _perfectiveGerundEndings2; } - + Collection RussianStemmer::adjectiveEndings() { static Collection _adjectiveEndings; @@ -137,7 +137,7 @@ namespace Lucene } return _participleEndings1; } - + Collection RussianStemmer::participleEndings2() { static Collection _participleEndings2; @@ -150,7 +150,7 @@ namespace Lucene } return _participleEndings2; } - + Collection RussianStemmer::participle1Predessors() { static Collection _participle1Predessors; @@ -162,7 +162,7 @@ namespace Lucene } return _participle1Predessors; } - + Collection RussianStemmer::reflexiveEndings() { static Collection _participle1Predessors; @@ -174,7 +174,7 @@ namespace Lucene } return _participle1Predessors; } - + Collection RussianStemmer::verbEndings1() { static Collection _verbEndings1; @@ -201,7 +201,7 @@ namespace Lucene } return _verbEndings1; } - + Collection RussianStemmer::verbEndings2() { static Collection _verbEndings2; @@ -240,7 +240,7 @@ namespace Lucene } return _verbEndings2; } - + Collection RussianStemmer::verb1Predessors() { static Collection _verb1Predessors; @@ -252,7 +252,7 @@ namespace Lucene } return _verb1Predessors; } - + Collection RussianStemmer::nounEndings() { static Collection _nounEndings; @@ -310,7 +310,7 @@ namespace Lucene } return _superlativeEndings; } - + Collection RussianStemmer::derivationalEndings() { static Collection _derivationalEndings; @@ -322,7 +322,7 @@ namespace Lucene } return _derivationalEndings; } - + Collection RussianStemmer::doubleN() { static Collection _doubleN; @@ -333,22 +333,22 @@ namespace Lucene } return _doubleN; } - + String RussianStemmer::stem(const String& input) { markPositions(input); if (RV == 0) return input; // RV wasn't detected, nothing to stem - + String stemmingZone(input.substr(RV)); - + // stemming goes on in RV // Step 1 if (!perfectiveGerund(stemmingZone)) { reflexive(stemmingZone); - + if (!adjectival(stemmingZone)) { if (!verb(stemmingZone)) @@ -370,24 +370,24 @@ namespace Lucene // return result return input.substr(0, RV) + stemmingZone; } - + String RussianStemmer::stemWord(const String& word) { return newLucene()->stem(word); } - + bool RussianStemmer::adjectival(String& stemmingZone) { // look for adjective ending in a stemming zone if (!findAndRemoveEnding(stemmingZone, adjectiveEndings())) return false; - + if (!findAndRemoveEnding(stemmingZone, participleEndings1(), participle1Predessors())) findAndRemoveEnding(stemmingZone, participleEndings2()); - + return true; } - + bool RussianStemmer::derivational(String& stemmingZone) { int32_t endingLength = findEnding(stemmingZone, derivationalEndings()); @@ -405,7 +405,7 @@ namespace Lucene return false; } } - + int32_t RussianStemmer::findEnding(String& stemmingZone, int32_t startIndex, Collection theEndingClass) { bool match = false; @@ -434,12 +434,12 @@ namespace Lucene } return 0; } - + int32_t RussianStemmer::findEnding(String& stemmingZone, Collection theEndingClass) { return findEnding(stemmingZone, (int32_t)(stemmingZone.length() - 1), theEndingClass); } - + bool RussianStemmer::findAndRemoveEnding(String& stemmingZone, Collection theEndingClass) { int32_t endingLength = findEnding(stemmingZone, theEndingClass); @@ -451,7 +451,7 @@ namespace Lucene return true; // cut the ending found } } - + bool RussianStemmer::findAndRemoveEnding(String& stemmingZone, Collection theEndingClass, Collection thePredessors) { int32_t endingLength = findEnding(stemmingZone, theEndingClass); @@ -469,7 +469,7 @@ namespace Lucene } } } - + void RussianStemmer::markPositions(const String& word) { RV = 0; @@ -499,7 +499,7 @@ namespace Lucene return; // R2 zone is empty R2 = i; } - + bool RussianStemmer::isVowel(wchar_t letter) { for (int32_t i = 0; i < SIZEOF_ARRAY(vowels); ++i) @@ -509,23 +509,23 @@ namespace Lucene } return false; } - + bool RussianStemmer::noun(String& stemmingZone) { return findAndRemoveEnding(stemmingZone, nounEndings()); } - + bool RussianStemmer::perfectiveGerund(String& stemmingZone) { - return findAndRemoveEnding(stemmingZone, perfectiveGerundEndings1(), perfectiveGerund1Predessors()) || + return findAndRemoveEnding(stemmingZone, perfectiveGerundEndings1(), perfectiveGerund1Predessors()) || findAndRemoveEnding(stemmingZone, perfectiveGerundEndings2()); } - + bool RussianStemmer::reflexive(String& stemmingZone) { return findAndRemoveEnding(stemmingZone, reflexiveEndings()); } - + bool RussianStemmer::removeI(String& stemmingZone) { if ((int32_t)stemmingZone.length() > 0 && stemmingZone[stemmingZone.length() - 1] == I) @@ -536,7 +536,7 @@ namespace Lucene else return false; } - + bool RussianStemmer::removeSoft(String& stemmingZone) { if ((int32_t)stemmingZone.length() > 0 && stemmingZone[stemmingZone.length() - 1] == SOFT) @@ -546,12 +546,12 @@ namespace Lucene } return false; } - + bool RussianStemmer::superlative(String& stemmingZone) { return findAndRemoveEnding(stemmingZone, superlativeEndings()); } - + bool RussianStemmer::undoubleN(String& stemmingZone) { if (findEnding(stemmingZone, doubleN()) != 0) @@ -562,10 +562,10 @@ namespace Lucene else return false; } - + bool RussianStemmer::verb(String& stemmingZone) { - return findAndRemoveEnding(stemmingZone, verbEndings1(), verb1Predessors()) || + return findAndRemoveEnding(stemmingZone, verbEndings1(), verb1Predessors()) || findAndRemoveEnding(stemmingZone, verbEndings2()); } } diff --git a/src/contrib/highlighter/DefaultEncoder.cpp b/src/contrib/highlighter/DefaultEncoder.cpp index c49aaadd..bf0ec07c 100644 --- a/src/contrib/highlighter/DefaultEncoder.cpp +++ b/src/contrib/highlighter/DefaultEncoder.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene DefaultEncoder::~DefaultEncoder() { } - + String DefaultEncoder::encodeText(const String& originalText) { return originalText; diff --git a/src/contrib/highlighter/Encoder.cpp b/src/contrib/highlighter/Encoder.cpp index 31e64398..c3db84da 100644 --- a/src/contrib/highlighter/Encoder.cpp +++ b/src/contrib/highlighter/Encoder.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene Encoder::~Encoder() { } - + String Encoder::encodeText(const String& originalText) { BOOST_ASSERT(false); diff --git a/src/contrib/highlighter/Formatter.cpp b/src/contrib/highlighter/Formatter.cpp index 77aea354..b3c60a58 100644 --- a/src/contrib/highlighter/Formatter.cpp +++ b/src/contrib/highlighter/Formatter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene Formatter::~Formatter() { } - + String Formatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) { BOOST_ASSERT(false); diff --git a/src/contrib/highlighter/Fragmenter.cpp b/src/contrib/highlighter/Fragmenter.cpp index c336a638..9c3f9cf4 100644 --- a/src/contrib/highlighter/Fragmenter.cpp +++ b/src/contrib/highlighter/Fragmenter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,13 +12,13 @@ namespace Lucene Fragmenter::~Fragmenter() { } - + void Fragmenter::start(const String& originalText, TokenStreamPtr tokenStream) { BOOST_ASSERT(false); // override } - + bool Fragmenter::isNewFragment() { BOOST_ASSERT(false); diff --git a/src/contrib/highlighter/GradientFormatter.cpp b/src/contrib/highlighter/GradientFormatter.cpp index dcd278e4..b5351536 100644 --- a/src/contrib/highlighter/GradientFormatter.cpp +++ b/src/contrib/highlighter/GradientFormatter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,7 +20,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"minForegroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); if (maxForegroundColor.length() != 7) boost::throw_exception(IllegalArgumentException(L"maxForegroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); - + fgRMin = hexToInt(minForegroundColor.substr(1, 2)); fgGMin = hexToInt(minForegroundColor.substr(3, 2)); fgBMin = hexToInt(minForegroundColor.substr(5, 2)); @@ -29,7 +29,7 @@ namespace Lucene fgGMax = hexToInt(maxForegroundColor.substr(3, 2)); fgBMax = hexToInt(maxForegroundColor.substr(5, 2)); } - + highlightBackground = (!minBackgroundColor.empty() && !maxBackgroundColor.empty()); if (highlightBackground) { @@ -37,7 +37,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"minBackgroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); if (maxBackgroundColor.length() != 7) boost::throw_exception(IllegalArgumentException(L"maxBackgroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); - + bgRMin = hexToInt(minBackgroundColor.substr(1, 2)); bgGMin = hexToInt(minBackgroundColor.substr(3, 2)); bgBMin = hexToInt(minBackgroundColor.substr(5, 2)); @@ -46,14 +46,14 @@ namespace Lucene bgGMax = hexToInt(maxBackgroundColor.substr(3, 2)); bgBMax = hexToInt(maxBackgroundColor.substr(5, 2)); } - + this->maxScore = maxScore; } - + GradientFormatter::~GradientFormatter() { } - + String GradientFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) { if (tokenGroup->getTotalScore() == 0) @@ -70,7 +70,7 @@ namespace Lucene buffer << L">" << originalText << L""; return buffer.str(); } - + String GradientFormatter::getForegroundColorString(double score) { int32_t rVal = getColorVal(fgRMin, fgRMax, score); @@ -80,7 +80,7 @@ namespace Lucene buffer << L"#" << intToHex(rVal) << intToHex(gVal) << intToHex(bVal); return buffer.str(); } - + String GradientFormatter::getBackgroundColorString(double score) { int32_t rVal = getColorVal(bgRMin, bgRMax, score); @@ -90,7 +90,7 @@ namespace Lucene buffer << L"#" << intToHex(rVal) << intToHex(gVal) << intToHex(bVal); return buffer.str(); } - + int32_t GradientFormatter::getColorVal(int32_t colorMin, int32_t colorMax, double score) { if (colorMin == colorMax) @@ -100,7 +100,7 @@ namespace Lucene double colScore = scale * relScorePercent; return std::min(colorMin, colorMax) + (int32_t)colScore; } - + String GradientFormatter::intToHex(int32_t i) { static const wchar_t* hexDigits = L"0123456789abcdef"; @@ -108,7 +108,7 @@ namespace Lucene buffer << hexDigits[(i & 0xf0) >> 4] << hexDigits[i & 0x0f]; return buffer.str(); } - + int32_t GradientFormatter::hexToInt(const String& hex) { int32_t len = (int32_t)hex.length(); diff --git a/src/contrib/highlighter/Highlighter.cpp b/src/contrib/highlighter/Highlighter.cpp index b226e760..f03ad83f 100644 --- a/src/contrib/highlighter/Highlighter.cpp +++ b/src/contrib/highlighter/Highlighter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,7 +24,7 @@ namespace Lucene { const int32_t Highlighter::DEFAULT_MAX_CHARS_TO_ANALYZE = 50 * 1024; - + Highlighter::Highlighter(HighlighterScorerPtr fragmentScorer) { this->formatter = newLucene(); @@ -33,7 +33,7 @@ namespace Lucene this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; this->textFragmenter = newLucene(); } - + Highlighter::Highlighter(FormatterPtr formatter, HighlighterScorerPtr fragmentScorer) { this->formatter = formatter; @@ -42,7 +42,7 @@ namespace Lucene this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; this->textFragmenter = newLucene(); } - + Highlighter::Highlighter(FormatterPtr formatter, EncoderPtr encoder, HighlighterScorerPtr fragmentScorer) { this->formatter = formatter; @@ -51,35 +51,35 @@ namespace Lucene this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; this->textFragmenter = newLucene(); } - + Highlighter::~Highlighter() { } - + String Highlighter::getBestFragment(AnalyzerPtr analyzer, const String& fieldName, const String& text) { TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); return getBestFragment(tokenStream, text); } - + String Highlighter::getBestFragment(TokenStreamPtr tokenStream, const String& text) { Collection results(getBestFragments(tokenStream,text, 1)); return results.empty() ? L"" : results[0]; } - + Collection Highlighter::getBestFragments(AnalyzerPtr analyzer, const String& fieldName, const String& text, int32_t maxNumFragments) { TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); return getBestFragments(tokenStream, text, maxNumFragments); } - + Collection Highlighter::getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments) { maxNumFragments = std::max((int32_t)1, maxNumFragments); //sanity check Collection frag(getBestTextFragments(tokenStream, text, true, maxNumFragments)); - + // Get text Collection fragTexts(Collection::newInstance()); for (int32_t i = 0; i < frag.size(); ++i) @@ -89,7 +89,7 @@ namespace Lucene } return fragTexts; } - + Collection Highlighter::getBestTextFragments(TokenStreamPtr tokenStream, const String& text, bool merge, int32_t maxNumFragments) { Collection docFrags(Collection::newInstance()); @@ -109,7 +109,7 @@ namespace Lucene FragmentQueuePtr fragQueue(newLucene(maxNumFragments)); Collection frag; - + LuceneException finally; try { @@ -124,7 +124,7 @@ namespace Lucene { if (offsetAtt->endOffset() > (int32_t)text.length() || offsetAtt->startOffset() > (int32_t)text.length()) boost::throw_exception(RuntimeException(L"InvalidTokenOffsets: Token " + termAtt->term() + L" exceeds length of provided text sized " + StringUtils::toString(text.length()))); - + if (tokenGroup->numTokens > 0 && tokenGroup->isDistinct()) { // the current token is distinct from previous tokens - markup the cached token group info @@ -138,7 +138,7 @@ namespace Lucene newText->append(markedUpText); lastEndOffset = std::max(endOffset, lastEndOffset); tokenGroup->clear(); - + // check if current token marks the start of a new fragment if (textFragmenter->isNewFragment()) { @@ -150,12 +150,12 @@ namespace Lucene docFrags.add(currentFrag); } } - + tokenGroup->addToken(fragmentScorer->getTokenScore()); } - + currentFrag->setScore(fragmentScorer->getFragmentScore()); - + if (tokenGroup->numTokens > 0) { // flush the accumulated text (same code as in above loop) @@ -169,25 +169,25 @@ namespace Lucene newText->append(markedUpText); lastEndOffset = std::max(lastEndOffset, endOffset); } - + // Test what remains of the original text beyond the point where we stopped analyzing if (lastEndOffset < (int32_t)text.length() && (int32_t)text.length() <= maxDocCharsToAnalyze) { // append it to the last fragment newText->append(encoder->encodeText(text.substr(lastEndOffset))); } - + currentFrag->textEndPos = newText->length(); - + // sort the most relevant sections of the text for (Collection::iterator i = docFrags.begin(); i != docFrags.end(); ++i) fragQueue->addOverflow(*i); - + // return the most relevant fragments frag = Collection::newInstance(fragQueue->size()); for (int32_t i = frag.size() - 1; i >= 0; --i) frag[i] = fragQueue->pop(); - + // merge any contiguous fragments to improve readability if (merge) { @@ -218,7 +218,7 @@ namespace Lucene finally.throwException(); return frag; } - + void Highlighter::mergeContiguousFragments(Collection frag) { if (frag.size() > 1) @@ -232,7 +232,7 @@ namespace Lucene { if (!frag[i]) continue; - // merge any contiguous blocks + // merge any contiguous blocks for (int32_t x = 0; x < frag.size(); ++x) { if (!frag[x]) @@ -260,7 +260,7 @@ namespace Lucene frag2 = frag[x]; frag2Num = x; } - + // merging required if (frag1) { @@ -285,7 +285,7 @@ namespace Lucene while (mergingStillBeingDone); } } - + String Highlighter::getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments, const String& separator) { Collection sections(getBestFragments(tokenStream, text, maxNumFragments)); @@ -298,55 +298,55 @@ namespace Lucene } return result.str(); } - + int32_t Highlighter::getMaxDocCharsToAnalyze() { return maxDocCharsToAnalyze; } - + void Highlighter::setMaxDocCharsToAnalyze(int32_t maxDocCharsToAnalyze) { this->maxDocCharsToAnalyze = maxDocCharsToAnalyze; } - + FragmenterPtr Highlighter::getTextFragmenter() { return textFragmenter; } - + void Highlighter::setTextFragmenter(FragmenterPtr fragmenter) { textFragmenter = fragmenter; } - + HighlighterScorerPtr Highlighter::getFragmentScorer() { return fragmentScorer; } - + void Highlighter::setFragmentScorer(HighlighterScorerPtr scorer) { fragmentScorer = scorer; } - + EncoderPtr Highlighter::getEncoder() { return encoder; } - + void Highlighter::setEncoder(EncoderPtr encoder) { this->encoder = encoder; } - + FragmentQueue::FragmentQueue(int32_t size) : PriorityQueue(size) { } - + FragmentQueue::~FragmentQueue() { } - + bool FragmentQueue::lessThan(const TextFragmentPtr& first, const TextFragmentPtr& second) { if (first->getScore() == second->getScore()) diff --git a/src/contrib/highlighter/HighlighterScorer.cpp b/src/contrib/highlighter/HighlighterScorer.cpp index 489e33fc..b75b744d 100644 --- a/src/contrib/highlighter/HighlighterScorer.cpp +++ b/src/contrib/highlighter/HighlighterScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,19 +12,19 @@ namespace Lucene HighlighterScorer::~HighlighterScorer() { } - + TokenStreamPtr HighlighterScorer::init(TokenStreamPtr tokenStream) { BOOST_ASSERT(false); return TokenStreamPtr(); // override } - + void HighlighterScorer::startFragment(TextFragmentPtr newFragment) { BOOST_ASSERT(false); // override } - + double HighlighterScorer::getTokenScore() { BOOST_ASSERT(false); diff --git a/src/contrib/highlighter/MapWeightedSpanTerm.cpp b/src/contrib/highlighter/MapWeightedSpanTerm.cpp index 5a5596e5..a534b1fa 100644 --- a/src/contrib/highlighter/MapWeightedSpanTerm.cpp +++ b/src/contrib/highlighter/MapWeightedSpanTerm.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,31 +13,31 @@ namespace Lucene { map = MapStringWeightedSpanTerm::newInstance(); } - + MapWeightedSpanTerm::~MapWeightedSpanTerm() { } - + MapStringWeightedSpanTerm::iterator MapWeightedSpanTerm::begin() { return map.begin(); } - + MapStringWeightedSpanTerm::iterator MapWeightedSpanTerm::end() { return map.end(); } - + void MapWeightedSpanTerm::put(const String& key, WeightedSpanTermPtr val) { return map.put(key, val); } - + WeightedSpanTermPtr MapWeightedSpanTerm::get(const String& key) const { return map.get(key); } - + void MapWeightedSpanTerm::clear() { map.clear(); diff --git a/src/contrib/highlighter/NullFragmenter.cpp b/src/contrib/highlighter/NullFragmenter.cpp index 60697883..fb3b779d 100644 --- a/src/contrib/highlighter/NullFragmenter.cpp +++ b/src/contrib/highlighter/NullFragmenter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,11 +12,11 @@ namespace Lucene NullFragmenter::~NullFragmenter() { } - + void NullFragmenter::start(const String& originalText, TokenStreamPtr tokenStream) { } - + bool NullFragmenter::isNewFragment() { return false; diff --git a/src/contrib/highlighter/QueryScorer.cpp b/src/contrib/highlighter/QueryScorer.cpp index 5616e74c..1a2052dd 100644 --- a/src/contrib/highlighter/QueryScorer.cpp +++ b/src/contrib/highlighter/QueryScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,33 +19,33 @@ namespace Lucene { init(query, L"", IndexReaderPtr(), true); } - + QueryScorer::QueryScorer(QueryPtr query, const String& field) { init(query, field, IndexReaderPtr(), true); } - + QueryScorer::QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field) { init(query, field, reader, true); } - + QueryScorer::QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field, const String& defaultField) { this->defaultField = defaultField; init(query, field, reader, true); } - + QueryScorer::QueryScorer(QueryPtr query, const String& field, const String& defaultField) { this->defaultField = defaultField; init(query, field, IndexReaderPtr(), true); } - + QueryScorer::QueryScorer(Collection weightedTerms) { init(QueryPtr(), L"", IndexReaderPtr(), true); - + this->fieldWeightedSpanTerms = newLucene(); for (int32_t i = 0; i < weightedTerms.size(); ++i) { @@ -59,11 +59,11 @@ namespace Lucene } skipInitExtractor = true; } - + QueryScorer::~QueryScorer() { } - + void QueryScorer::init(QueryPtr query, const String& field, IndexReaderPtr reader, bool expandMultiTermQuery) { this->totalScore = 0; @@ -71,23 +71,23 @@ namespace Lucene this->position = -1; this->skipInitExtractor = false; this->wrapToCaching = true; - + this->reader = reader; this->expandMultiTermQuery = expandMultiTermQuery; this->query = query; this->field = field; } - + double QueryScorer::getFragmentScore() { return totalScore; } - + double QueryScorer::getMaxTermWeight() { return maxTermWeight; } - + double QueryScorer::getTokenScore() { position += posIncAtt->getPositionIncrement(); @@ -112,7 +112,7 @@ namespace Lucene return score; } - + TokenStreamPtr QueryScorer::init(TokenStreamPtr tokenStream) { position = -1; @@ -126,12 +126,12 @@ namespace Lucene } return TokenStreamPtr(); } - + WeightedSpanTermPtr QueryScorer::getWeightedSpanTerm(const String& token) { return fieldWeightedSpanTerms->get(token); } - + TokenStreamPtr QueryScorer::initExtractor(TokenStreamPtr tokenStream) { WeightedSpanTermExtractorPtr qse(newLucene(defaultField)); @@ -146,23 +146,23 @@ namespace Lucene return qse->getTokenStream(); return TokenStreamPtr(); } - + void QueryScorer::startFragment(TextFragmentPtr newFragment) { foundTerms = HashSet::newInstance(); totalScore = 0; } - + bool QueryScorer::isExpandMultiTermQuery() { return expandMultiTermQuery; } - + void QueryScorer::setExpandMultiTermQuery(bool expandMultiTermQuery) { this->expandMultiTermQuery = expandMultiTermQuery; } - + void QueryScorer::setWrapIfNotCachingTokenFilter(bool wrap) { this->wrapToCaching = wrap; diff --git a/src/contrib/highlighter/QueryTermExtractor.cpp b/src/contrib/highlighter/QueryTermExtractor.cpp index 9b697270..c1abfadd 100644 --- a/src/contrib/highlighter/QueryTermExtractor.cpp +++ b/src/contrib/highlighter/QueryTermExtractor.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,12 +19,12 @@ namespace Lucene QueryTermExtractor::~QueryTermExtractor() { } - + Collection QueryTermExtractor::getTerms(QueryPtr query) { return getTerms(query, false); } - + Collection QueryTermExtractor::getIdfWeightedTerms(QueryPtr query, IndexReaderPtr reader, const String& fieldName) { Collection terms(getTerms(query, false, fieldName)); @@ -48,21 +48,21 @@ namespace Lucene } return terms; } - + Collection QueryTermExtractor::getTerms(QueryPtr query, bool prohibited, const String& fieldName) { SetWeightedTerm terms(SetWeightedTerm::newInstance()); getTerms(query, terms, prohibited, fieldName); return Collection::newInstance(terms.begin(), terms.end()); } - + Collection QueryTermExtractor::getTerms(QueryPtr query, bool prohibited) { SetWeightedTerm terms(SetWeightedTerm::newInstance()); getTerms(query, terms, prohibited, L""); return Collection::newInstance(terms.begin(), terms.end()); } - + void QueryTermExtractor::getTerms(QueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { try @@ -87,7 +87,7 @@ namespace Lucene // this is non-fatal for our purposes } } - + void QueryTermExtractor::getTermsFromBooleanQuery(BooleanQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { Collection queryClauses(query->getClauses()); @@ -97,7 +97,7 @@ namespace Lucene getTerms(queryClauses[i]->getQuery(), terms, prohibited, fieldName); } } - + void QueryTermExtractor::getTermsFromFilteredQuery(FilteredQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { getTerms(query->getQuery(), terms, prohibited, fieldName); diff --git a/src/contrib/highlighter/QueryTermScorer.cpp b/src/contrib/highlighter/QueryTermScorer.cpp index 264c47ba..adbce4d9 100644 --- a/src/contrib/highlighter/QueryTermScorer.cpp +++ b/src/contrib/highlighter/QueryTermScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,31 +17,31 @@ namespace Lucene { ConstructQueryTermScorer(QueryTermExtractor::getTerms(query)); } - + QueryTermScorer::QueryTermScorer(QueryPtr query, const String& fieldName) { ConstructQueryTermScorer(QueryTermExtractor::getTerms(query, false, fieldName)); } - + QueryTermScorer::QueryTermScorer(QueryPtr query, IndexReaderPtr reader, const String& fieldName) { ConstructQueryTermScorer(QueryTermExtractor::getIdfWeightedTerms(query, reader, fieldName)); } - + QueryTermScorer::QueryTermScorer(Collection weightedTerms) { ConstructQueryTermScorer(weightedTerms); } - + QueryTermScorer::~QueryTermScorer() { } - + void QueryTermScorer::ConstructQueryTermScorer(Collection weightedTerms) { totalScore = 0; maxTermWeight = 0; - + termsToFind = MapStringWeightedTerm::newInstance(); for (int32_t i = 0; i < weightedTerms.size(); ++i) { @@ -54,20 +54,20 @@ namespace Lucene } } } - + TokenStreamPtr QueryTermScorer::init(TokenStreamPtr tokenStream) { termAtt = tokenStream->addAttribute(); return TokenStreamPtr(); } - + void QueryTermScorer::startFragment(TextFragmentPtr newFragment) { uniqueTermsInFragment = HashSet::newInstance(); currentTextFragment = newFragment; totalScore = 0; } - + double QueryTermScorer::getTokenScore() { String termText(termAtt->term()); @@ -85,17 +85,17 @@ namespace Lucene return queryTerm->getWeight(); } - + double QueryTermScorer::getFragmentScore() { return totalScore; } - + void QueryTermScorer::allFragmentsProcessed() { // this class has no special operations to perform at end of processing - } - + } + double QueryTermScorer::getMaxTermWeight() { return maxTermWeight; diff --git a/src/contrib/highlighter/SimpleFragmenter.cpp b/src/contrib/highlighter/SimpleFragmenter.cpp index 42f332df..768a98fa 100644 --- a/src/contrib/highlighter/SimpleFragmenter.cpp +++ b/src/contrib/highlighter/SimpleFragmenter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,29 +13,29 @@ namespace Lucene { const int32_t SimpleFragmenter::DEFAULT_FRAGMENT_SIZE = 100; - + SimpleFragmenter::SimpleFragmenter() { this->currentNumFrags = 0; this->fragmentSize = DEFAULT_FRAGMENT_SIZE; } - + SimpleFragmenter::SimpleFragmenter(int32_t fragmentSize) { this->currentNumFrags = 0; this->fragmentSize = fragmentSize; } - + SimpleFragmenter::~SimpleFragmenter() { } - + void SimpleFragmenter::start(const String& originalText, TokenStreamPtr tokenStream) { offsetAtt = tokenStream->addAttribute(); currentNumFrags = 1; } - + bool SimpleFragmenter::isNewFragment() { bool isNewFrag = (offsetAtt->endOffset() >= (fragmentSize * currentNumFrags)); @@ -43,12 +43,12 @@ namespace Lucene ++currentNumFrags; return isNewFrag; } - + int32_t SimpleFragmenter::getFragmentSize() { return fragmentSize; } - + void SimpleFragmenter::setFragmentSize(int32_t size) { fragmentSize = size; diff --git a/src/contrib/highlighter/SimpleHTMLEncoder.cpp b/src/contrib/highlighter/SimpleHTMLEncoder.cpp index e3ee16f7..fb4dc03e 100644 --- a/src/contrib/highlighter/SimpleHTMLEncoder.cpp +++ b/src/contrib/highlighter/SimpleHTMLEncoder.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,24 +12,24 @@ namespace Lucene SimpleHTMLEncoder::~SimpleHTMLEncoder() { } - + String SimpleHTMLEncoder::encodeText(const String& originalText) { return htmlEncode(originalText); } - + String SimpleHTMLEncoder::htmlEncode(const String& plainText) { if (plainText.empty()) return L""; - + StringStream result; - + for (int32_t index = 0; index < (int32_t)plainText.length(); ++index) { wchar_t ch = plainText[index]; - - switch (ch) + + switch (ch) { case L'\"': result << L"""; @@ -44,14 +44,14 @@ namespace Lucene result << L">"; break; default: - if (ch < 128) + if (ch < 128) result << ch; else result << L"&#" << (int32_t)ch << L";"; break; } } - + return result.str(); } } diff --git a/src/contrib/highlighter/SimpleHTMLFormatter.cpp b/src/contrib/highlighter/SimpleHTMLFormatter.cpp index 811a322b..404c9f58 100644 --- a/src/contrib/highlighter/SimpleHTMLFormatter.cpp +++ b/src/contrib/highlighter/SimpleHTMLFormatter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,23 +12,23 @@ namespace Lucene { const String SimpleHTMLFormatter::DEFAULT_PRE_TAG = L""; const String SimpleHTMLFormatter::DEFAULT_POST_TAG = L""; - + SimpleHTMLFormatter::SimpleHTMLFormatter() { this->preTag = DEFAULT_PRE_TAG; this->postTag = DEFAULT_POST_TAG; } - + SimpleHTMLFormatter::SimpleHTMLFormatter(const String& preTag, const String& postTag) { this->preTag = preTag; this->postTag = postTag; } - + SimpleHTMLFormatter::~SimpleHTMLFormatter() { } - + String SimpleHTMLFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) { if (tokenGroup->getTotalScore() == 0) diff --git a/src/contrib/highlighter/SimpleSpanFragmenter.cpp b/src/contrib/highlighter/SimpleSpanFragmenter.cpp index 6403f66e..8941d4a4 100644 --- a/src/contrib/highlighter/SimpleSpanFragmenter.cpp +++ b/src/contrib/highlighter/SimpleSpanFragmenter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,44 +17,44 @@ namespace Lucene { const int32_t SimpleSpanFragmenter::DEFAULT_FRAGMENT_SIZE = 100; - + SimpleSpanFragmenter::SimpleSpanFragmenter(QueryScorerPtr queryScorer) { this->currentNumFrags = 0; this->position = -1; this->waitForPos = -1; this->textSize = 0; - + this->queryScorer = queryScorer; this->fragmentSize = DEFAULT_FRAGMENT_SIZE; } - + SimpleSpanFragmenter::SimpleSpanFragmenter(QueryScorerPtr queryScorer, int32_t fragmentSize) { this->currentNumFrags = 0; this->position = -1; this->waitForPos = -1; this->textSize = 0; - + this->queryScorer = queryScorer; this->fragmentSize = fragmentSize; } - + SimpleSpanFragmenter::~SimpleSpanFragmenter() { } - + bool SimpleSpanFragmenter::isNewFragment() { position += posIncAtt->getPositionIncrement(); - + if (waitForPos == position) waitForPos = -1; else if (waitForPos != -1) return false; - + WeightedSpanTermPtr wSpanTerm(queryScorer->getWeightedSpanTerm(termAtt->term())); - + if (wSpanTerm) { Collection positionSpans(wSpanTerm->getPositionSpans()); @@ -68,15 +68,15 @@ namespace Lucene } } } - + bool isNewFrag = (offsetAtt->endOffset() >= (fragmentSize * currentNumFrags) && (textSize - offsetAtt->endOffset()) >= MiscUtils::unsignedShift(fragmentSize, 1)); - + if (isNewFrag) ++currentNumFrags; - + return isNewFrag; } - + void SimpleSpanFragmenter::start(const String& originalText, TokenStreamPtr tokenStream) { position = -1; diff --git a/src/contrib/highlighter/SpanGradientFormatter.cpp b/src/contrib/highlighter/SpanGradientFormatter.cpp index d30186b2..122145af 100644 --- a/src/contrib/highlighter/SpanGradientFormatter.cpp +++ b/src/contrib/highlighter/SpanGradientFormatter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -10,15 +10,15 @@ namespace Lucene { - SpanGradientFormatter::SpanGradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor) : + SpanGradientFormatter::SpanGradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor) : GradientFormatter(maxScore, minForegroundColor, maxForegroundColor, minBackgroundColor, maxBackgroundColor) { } - + SpanGradientFormatter::~SpanGradientFormatter() { } - + String SpanGradientFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) { if (tokenGroup->getTotalScore() == 0) diff --git a/src/contrib/highlighter/TextFragment.cpp b/src/contrib/highlighter/TextFragment.cpp index 7002dd49..e5c2ea29 100644 --- a/src/contrib/highlighter/TextFragment.cpp +++ b/src/contrib/highlighter/TextFragment.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,61 +17,61 @@ namespace Lucene this->fragNum = fragNum; this->score = 0; } - + TextFragment::~TextFragment() { } - + void TextFragment::setScore(double score) { this->score = score; } - + double TextFragment::getScore() { return score; } - + void TextFragment::merge(TextFragmentPtr frag2) { textEndPos = frag2->textEndPos; score = std::max(score, frag2->score); } - + bool TextFragment::follows(TextFragmentPtr fragment) { return (textStartPos == fragment->textEndPos); } - + int32_t TextFragment::getFragNum() { return fragNum; } - + String TextFragment::toString() { return markedUpText->toString().substr(textStartPos, textEndPos - textStartPos); } - + StringBuffer::~StringBuffer() { } - + int32_t StringBuffer::length() { return buffer.str().length(); } - + String StringBuffer::toString() { return buffer.str(); } - + void StringBuffer::append(const String& str) { buffer << str; } - + void StringBuffer::clear() { buffer.str(L""); diff --git a/src/contrib/highlighter/TokenGroup.cpp b/src/contrib/highlighter/TokenGroup.cpp index 2d9e1aa9..05ff951e 100644 --- a/src/contrib/highlighter/TokenGroup.cpp +++ b/src/contrib/highlighter/TokenGroup.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,12 +14,12 @@ namespace Lucene { const int32_t TokenGroup::MAX_NUM_TOKENS_PER_GROUP = 50; - + TokenGroup::TokenGroup(TokenStreamPtr tokenStream) { offsetAtt = tokenStream->addAttribute(); termAtt = tokenStream->addAttribute(); - + tokens = Collection::newInstance(MAX_NUM_TOKENS_PER_GROUP); scores = Collection::newInstance(MAX_NUM_TOKENS_PER_GROUP); numTokens = 0; @@ -29,11 +29,11 @@ namespace Lucene matchStartOffset = 0; matchEndOffset = 0; } - + TokenGroup::~TokenGroup() { } - + void TokenGroup::addToken(double score) { if (numTokens < MAX_NUM_TOKENS_PER_GROUP) @@ -74,43 +74,43 @@ namespace Lucene ++numTokens; } } - + bool TokenGroup::isDistinct() { return (offsetAtt->startOffset() >= endOffset); } - + void TokenGroup::clear() { numTokens = 0; tot = 0; } - + TokenPtr TokenGroup::getToken(int32_t index) { return tokens[index]; } - + double TokenGroup::getScore(int32_t index) { return scores[index]; } - + int32_t TokenGroup::getEndOffset() { return endOffset; } - + int32_t TokenGroup::getNumTokens() { return numTokens; } - + int32_t TokenGroup::getStartOffset() { return startOffset; } - + double TokenGroup::getTotalScore() { return tot; diff --git a/src/contrib/highlighter/TokenSources.cpp b/src/contrib/highlighter/TokenSources.cpp index 270984d5..3772bef8 100644 --- a/src/contrib/highlighter/TokenSources.cpp +++ b/src/contrib/highlighter/TokenSources.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,7 +24,7 @@ namespace Lucene TokenSources::~TokenSources() { } - + TokenStreamPtr TokenSources::getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, DocumentPtr doc, AnalyzerPtr analyzer) { TokenStreamPtr ts; @@ -39,7 +39,7 @@ namespace Lucene ts = getTokenStream(doc, field, analyzer); return ts; } - + TokenStreamPtr TokenSources::getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer) { TokenStreamPtr ts; @@ -54,13 +54,13 @@ namespace Lucene ts = getTokenStream(reader, docId, field, analyzer); return ts; } - + TokenStreamPtr TokenSources::getTokenStream(TermPositionVectorPtr tpv) { // assumes the worst and makes no assumptions about token position sequences. return getTokenStream(tpv, false); } - + struct lessTokenOffset { inline bool operator()(const TokenPtr& first, const TokenPtr& second) const @@ -70,17 +70,17 @@ namespace Lucene return (first->startOffset() > second->endOffset()); } }; - + TokenStreamPtr TokenSources::getTokenStream(TermPositionVectorPtr tpv, bool tokenPositionsGuaranteedContiguous) { // code to reconstruct the original sequence of Tokens - Collection terms(tpv->getTerms()); + Collection terms(tpv->getTerms()); Collection freq(tpv->getTermFrequencies()); int32_t totalTokens = 0; - + for (int32_t t = 0; t < freq.size(); ++t) totalTokens += freq[t]; - + Collection tokensInOriginalOrder(Collection::newInstance(totalTokens)); Collection unsortedTokens; for (int32_t t = 0; t < freq.size(); ++t) @@ -129,13 +129,13 @@ namespace Lucene } return newLucene(tokensInOriginalOrder); } - + TokenStreamPtr TokenSources::getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field) { TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); if (!tfv) boost::throw_exception(IllegalArgumentException(field + L" in doc #" + StringUtils::toString(docId) + L"does not have any term position data stored")); - + if (boost::dynamic_pointer_cast(tfv)) { TermPositionVectorPtr tpv(boost::dynamic_pointer_cast(reader->getTermFreqVector(docId, field))); @@ -144,13 +144,13 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(field + L" in doc #" + StringUtils::toString(docId) + L"does not have any term position data stored")); return TokenStreamPtr(); } - + TokenStreamPtr TokenSources::getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer) { DocumentPtr doc(reader->document(docId)); return getTokenStream(doc, field, analyzer); } - + TokenStreamPtr TokenSources::getTokenStream(DocumentPtr doc, const String& field, AnalyzerPtr analyzer) { String contents(doc->get(field)); @@ -158,23 +158,23 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"Field " + field + L" in document is not stored and cannot be analyzed")); return getTokenStream(field, contents, analyzer); } - + TokenStreamPtr TokenSources::getTokenStream(const String& field, const String& contents, AnalyzerPtr analyzer) { return analyzer->tokenStream(field, newLucene(contents)); } - + StoredTokenStream::StoredTokenStream(Collection tokens) { this->tokens = tokens; this->termAtt = addAttribute(); this->offsetAtt = addAttribute(); } - + StoredTokenStream::~StoredTokenStream() { } - + bool StoredTokenStream::incrementToken() { if (currentToken >= tokens.size()) diff --git a/src/contrib/highlighter/WeightedSpanTerm.cpp b/src/contrib/highlighter/WeightedSpanTerm.cpp index cc3995ea..44a5f1be 100644 --- a/src/contrib/highlighter/WeightedSpanTerm.cpp +++ b/src/contrib/highlighter/WeightedSpanTerm.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,14 +14,14 @@ namespace Lucene this->positionSensitive = positionSensitive; this->positionSpans = Collection::newInstance(); } - + WeightedSpanTerm::~WeightedSpanTerm() { } - + bool WeightedSpanTerm::checkPosition(int32_t position) { - // There would probably be a slight speed improvement if PositionSpans where kept in some sort of priority queue - + // There would probably be a slight speed improvement if PositionSpans where kept in some sort of priority queue - // that way this method could bail early without checking each PositionSpan. for (Collection::iterator posSpan = positionSpans.begin(); posSpan != positionSpans.end(); ++posSpan) { @@ -30,33 +30,33 @@ namespace Lucene } return false; } - + void WeightedSpanTerm::addPositionSpans(Collection positionSpans) { this->positionSpans.addAll(positionSpans.begin(), positionSpans.end()); } - + bool WeightedSpanTerm::isPositionSensitive() { return positionSensitive; } - + void WeightedSpanTerm::setPositionSensitive(bool positionSensitive) { this->positionSensitive = positionSensitive; } - + Collection WeightedSpanTerm::getPositionSpans() { return positionSpans; } - + PositionSpan::PositionSpan(int32_t start, int32_t end) { this->start = start; this->end = end; } - + PositionSpan::~PositionSpan() { } diff --git a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp index 025c646c..3d02b6c9 100644 --- a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp +++ b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -40,11 +40,11 @@ namespace Lucene this->wrapToCaching = true; this->readers = MapStringIndexReader::newInstance(); } - + WeightedSpanTermExtractor::~WeightedSpanTermExtractor() { } - + void WeightedSpanTermExtractor::closeReaders() { for (MapStringIndexReader::iterator reader = readers.begin(); reader != readers.end(); ++reader) @@ -58,7 +58,7 @@ namespace Lucene } } } - + void WeightedSpanTermExtractor::extract(QueryPtr query, MapWeightedSpanTermPtr terms) { if (MiscUtils::typeOf(query)) @@ -96,9 +96,9 @@ namespace Lucene if (largestInc > 1) slop += largestInc; } - + bool inorder = (slop == 0); - + SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); sp->setBoost(query->getBoost()); extractWeightedSpanTerms(terms, sp); @@ -145,7 +145,7 @@ namespace Lucene if (positions[i] > maxPosition) maxPosition = positions[i]; } - + Collection< Collection > disjunctLists(Collection< Collection >::newInstance(maxPosition + 1)); int32_t distinctPositions = 0; for (int32_t i = 0; i < termArrays.size(); ++i) @@ -161,7 +161,7 @@ namespace Lucene for (int32_t j = 0; j < termArray.size(); ++j) disjuncts.add(newLucene(termArray[j])); } - + int32_t positionGaps = 0; int32_t position = 0; Collection clauses(Collection::newInstance(distinctPositions)); @@ -173,7 +173,7 @@ namespace Lucene else ++positionGaps; } - + int32_t slop = mpq->getSlop(); bool inorder = (slop == 0); @@ -183,7 +183,7 @@ namespace Lucene } } } - + void WeightedSpanTermExtractor::extractWeightedSpanTerms(MapWeightedSpanTermPtr terms, SpanQueryPtr spanQuery) { HashSet fieldNames(HashSet::newInstance()); @@ -194,10 +194,10 @@ namespace Lucene // To support the use of the default field name if (!defaultField.empty()) fieldNames.add(defaultField); - + MapStringSpanQuery queries(MapStringSpanQuery::newInstance()); SetTerm nonWeightedTerms(SetTerm::newInstance()); - + bool rewriteQuery = mustRewriteQuery(spanQuery); if (rewriteQuery) { @@ -210,9 +210,9 @@ namespace Lucene } else spanQuery->extractTerms(nonWeightedTerms); - + Collection spanPositions(Collection::newInstance()); - + for (HashSet::iterator field = fieldNames.begin(); field != fieldNames.end(); ++field) { IndexReaderPtr reader(getReaderForField(*field)); @@ -221,18 +221,18 @@ namespace Lucene spans = queries.get(*field)->getSpans(reader); else spans = spanQuery->getSpans(reader); - + // collect span positions while (spans->next()) spanPositions.add(newLucene(spans->start(), spans->end() - 1)); } - + if (spanPositions.empty()) { // no spans found return; } - + for (SetTerm::iterator queryTerm = nonWeightedTerms.begin(); queryTerm != nonWeightedTerms.end(); ++queryTerm) { if (fieldNameComparator((*queryTerm)->field())) @@ -253,12 +253,12 @@ namespace Lucene } } } - + void WeightedSpanTermExtractor::extractWeightedTerms(MapWeightedSpanTermPtr terms, QueryPtr query) { SetTerm nonWeightedTerms(SetTerm::newInstance()); query->extractTerms(nonWeightedTerms); - + for (SetTerm::iterator queryTerm = nonWeightedTerms.begin(); queryTerm != nonWeightedTerms.end(); ++queryTerm) { if (fieldNameComparator((*queryTerm)->field())) @@ -268,12 +268,12 @@ namespace Lucene } } } - + bool WeightedSpanTermExtractor::fieldNameComparator(const String& fieldNameToCheck) { return (fieldName.empty() || fieldNameToCheck == fieldName || fieldNameToCheck == defaultField); } - + IndexReaderPtr WeightedSpanTermExtractor::getReaderForField(const String& field) { if (wrapToCaching && !cachedTokenStream && !MiscUtils::typeOf(tokenStream)) @@ -293,22 +293,22 @@ namespace Lucene } return reader; } - + MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream) { return getWeightedSpanTerms(query, tokenStream, L""); } - + MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName) { if (!fieldName.empty()) this->fieldName = fieldName; else this->fieldName.clear(); - + MapWeightedSpanTermPtr terms(newLucene()); this->tokenStream = tokenStream; - + LuceneException finally; try { @@ -322,19 +322,19 @@ namespace Lucene finally.throwException(); return terms; } - + MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTermsWithScores(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName, IndexReaderPtr reader) { if (!fieldName.empty()) this->fieldName = fieldName; else this->fieldName.clear(); - + MapWeightedSpanTermPtr terms(newLucene()); extract(query, terms); - + int32_t totalNumDocs = reader->numDocs(); - + LuceneException finally; try { @@ -357,7 +357,7 @@ namespace Lucene finally.throwException(); return terms; } - + void WeightedSpanTermExtractor::collectSpanQueryFields(SpanQueryPtr spanQuery, HashSet fieldNames) { if (MiscUtils::typeOf(spanQuery)) @@ -381,7 +381,7 @@ namespace Lucene else fieldNames.add(spanQuery->getField()); } - + bool WeightedSpanTermExtractor::mustRewriteQuery(SpanQueryPtr spanQuery) { if (!expandMultiTermQuery) @@ -420,39 +420,39 @@ namespace Lucene else return true; } - + bool WeightedSpanTermExtractor::getExpandMultiTermQuery() { return expandMultiTermQuery; } - + void WeightedSpanTermExtractor::setExpandMultiTermQuery(bool expandMultiTermQuery) { this->expandMultiTermQuery = expandMultiTermQuery; } - + bool WeightedSpanTermExtractor::isCachedTokenStream() { return cachedTokenStream; } - + TokenStreamPtr WeightedSpanTermExtractor::getTokenStream() { return tokenStream; } - + void WeightedSpanTermExtractor::setWrapIfNotCachingTokenFilter(bool wrap) { this->wrapToCaching = wrap; } - + PositionCheckingMap::~PositionCheckingMap() { } - + void PositionCheckingMap::put(const String& key, WeightedSpanTermPtr val) { - MapStringWeightedSpanTerm::iterator prev = map.find(key); + MapStringWeightedSpanTerm::iterator prev = map.find(key); if (prev == map.end()) { map.put(key, val); @@ -463,15 +463,15 @@ namespace Lucene if (!positionSensitive) prev->second->positionSensitive = false; } - + FakeReader::FakeReader() : FilterIndexReader(EMPTY_MEMORY_INDEX_READER()) { } - + FakeReader::~FakeReader() { } - + IndexReaderPtr FakeReader::EMPTY_MEMORY_INDEX_READER() { static IndexReaderPtr _EMPTY_MEMORY_INDEX_READER; @@ -482,7 +482,7 @@ namespace Lucene } return _EMPTY_MEMORY_INDEX_READER; } - + TermEnumPtr FakeReader::terms(TermPtr t) { // only set first fieldname diff --git a/src/contrib/highlighter/WeightedTerm.cpp b/src/contrib/highlighter/WeightedTerm.cpp index 342a10d6..c7c3fb14 100644 --- a/src/contrib/highlighter/WeightedTerm.cpp +++ b/src/contrib/highlighter/WeightedTerm.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,26 +14,26 @@ namespace Lucene this->weight = weight; this->term = term; } - + WeightedTerm::~WeightedTerm() { } - + String WeightedTerm::getTerm() { return term; } - + double WeightedTerm::getWeight() { return weight; } - + void WeightedTerm::setTerm(const String& term) { this->term = term; } - + void WeightedTerm::setWeight(double weight) { this->weight = weight; diff --git a/src/contrib/include/ArabicAnalyzer.h b/src/contrib/include/ArabicAnalyzer.h index 86b17a50..bab47b4e 100644 --- a/src/contrib/include/ArabicAnalyzer.h +++ b/src/contrib/include/ArabicAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// {@link Analyzer} for Arabic. + /// {@link Analyzer} for Arabic. /// /// This analyzer implements light-stemming as specified by: /// Light Stemming for Arabic Information Retrieval @@ -30,52 +30,52 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. ArabicAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. ArabicAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + virtual ~ArabicAnalyzer(); - + LUCENE_CLASS(ArabicAnalyzer); - + public: /// Default Arabic stopwords in UTF-8 format. /// /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html /// The stopword list is BSD-Licensed. static const uint8_t DEFAULT_STOPWORD_FILE[]; - + protected: /// Contains the stopwords used with the StopFilter. HashSet stoptable; - + LuceneVersion::Version matchVersion; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and /// {@link ArabicStemFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and /// {@link ArabicStemFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI ArabicAnalyzerSavedStreams : public LuceneObject { public: virtual ~ArabicAnalyzerSavedStreams(); - + LUCENE_CLASS(ArabicAnalyzerSavedStreams); public: diff --git a/src/contrib/include/ArabicLetterTokenizer.h b/src/contrib/include/ArabicLetterTokenizer.h index 7e78b10b..214937b3 100644 --- a/src/contrib/include/ArabicLetterTokenizer.h +++ b/src/contrib/include/ArabicLetterTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,17 +22,17 @@ namespace Lucene public: /// Construct a new ArabicLetterTokenizer. ArabicLetterTokenizer(ReaderPtr input); - + /// Construct a new ArabicLetterTokenizer using a given {@link AttributeSource}. ArabicLetterTokenizer(AttributeSourcePtr source, ReaderPtr input); - + /// Construct a new ArabicLetterTokenizer using a given {@link AttributeFactory}. ArabicLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~ArabicLetterTokenizer(); - + LUCENE_CLASS(ArabicLetterTokenizer); - + public: /// Allows for Letter category or NonspacingMark category virtual bool isTokenChar(wchar_t c); diff --git a/src/contrib/include/ArabicNormalizationFilter.h b/src/contrib/include/ArabicNormalizationFilter.h index 6417475b..5f63bbec 100644 --- a/src/contrib/include/ArabicNormalizationFilter.h +++ b/src/contrib/include/ArabicNormalizationFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,13 +18,13 @@ namespace Lucene public: ArabicNormalizationFilter(TokenStreamPtr input); virtual ~ArabicNormalizationFilter(); - + LUCENE_CLASS(ArabicNormalizationFilter); - + protected: ArabicNormalizerPtr normalizer; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/ArabicNormalizer.h b/src/contrib/include/ArabicNormalizer.h index 906d11c2..8061abad 100644 --- a/src/contrib/include/ArabicNormalizer.h +++ b/src/contrib/include/ArabicNormalizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -28,23 +28,23 @@ namespace Lucene { public: virtual ~ArabicNormalizer(); - + LUCENE_CLASS(ArabicNormalizer); - + public: static const wchar_t ALEF; static const wchar_t ALEF_MADDA; static const wchar_t ALEF_HAMZA_ABOVE; static const wchar_t ALEF_HAMZA_BELOW; - + static const wchar_t YEH; static const wchar_t DOTLESS_YEH; - + static const wchar_t TEH_MARBUTA; static const wchar_t HEH; - + static const wchar_t TATWEEL; - + static const wchar_t FATHATAN; static const wchar_t DAMMATAN; static const wchar_t KASRATAN; @@ -53,14 +53,14 @@ namespace Lucene static const wchar_t KASRA; static const wchar_t SHADDA; static const wchar_t SUKUN; - + public: /// Normalize an input buffer of Arabic text /// @param s input buffer /// @param len length of input buffer /// @return length of input buffer after normalization int32_t normalize(wchar_t* s, int32_t len); - + /// Delete a character in-place /// @param s Input Buffer /// @param pos Position of character to delete diff --git a/src/contrib/include/ArabicStemFilter.h b/src/contrib/include/ArabicStemFilter.h index 2342d581..c46d7e95 100644 --- a/src/contrib/include/ArabicStemFilter.h +++ b/src/contrib/include/ArabicStemFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,13 +18,13 @@ namespace Lucene public: ArabicStemFilter(TokenStreamPtr input); virtual ~ArabicStemFilter(); - + LUCENE_CLASS(ArabicStemFilter); - + protected: ArabicStemmerPtr stemmer; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/ArabicStemmer.h b/src/contrib/include/ArabicStemmer.h index b7b38d6b..55a61bb5 100644 --- a/src/contrib/include/ArabicStemmer.h +++ b/src/contrib/include/ArabicStemmer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,9 +25,9 @@ namespace Lucene { public: virtual ~ArabicStemmer(); - + LUCENE_CLASS(ArabicStemmer); - + public: static const wchar_t ALEF; static const wchar_t BEH; @@ -40,43 +40,43 @@ namespace Lucene static const wchar_t HEH; static const wchar_t WAW; static const wchar_t YEH; - + public: static const Collection prefixes(); static const Collection suffixes(); - + /// Stem an input buffer of Arabic text. /// @param s input buffer /// @param len length of input buffer /// @return length of input buffer after normalization int32_t stem(wchar_t* s, int32_t len); - + /// Stem a prefix off an Arabic word. /// @param s input buffer /// @param len length of input buffer /// @return new length of input buffer after stemming. int32_t stemPrefix(wchar_t* s, int32_t len); - + /// Stem suffix(es) off an Arabic word. /// @param s input buffer /// @param len length of input buffer /// @return new length of input buffer after stemming int32_t stemSuffix(wchar_t* s, int32_t len); - + /// Returns true if the prefix matches and can be stemmed /// @param s input buffer /// @param len length of input buffer /// @param prefix prefix to check /// @return true if the prefix matches and can be stemmed bool startsWith(wchar_t* s, int32_t len, const String& prefix); - + /// Returns true if the suffix matches and can be stemmed /// @param s input buffer /// @param len length of input buffer /// @param suffix suffix to check /// @return true if the suffix matches and can be stemmed bool endsWith(wchar_t* s, int32_t len, const String& suffix); - + protected: /// Delete n characters in-place /// @param s Input Buffer @@ -85,7 +85,7 @@ namespace Lucene /// @param chars number of characters to delete /// @return length of input buffer after deletion int32_t deleteChars(wchar_t* s, int32_t pos, int32_t len, int32_t chars); - + /// Delete a character in-place /// @param s Input Buffer /// @param pos Position of character to delete diff --git a/src/contrib/include/BrazilianAnalyzer.h b/src/contrib/include/BrazilianAnalyzer.h index c9001387..d8e13080 100644 --- a/src/contrib/include/BrazilianAnalyzer.h +++ b/src/contrib/include/BrazilianAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,9 +12,9 @@ namespace Lucene { - /// {@link Analyzer} for Brazilian Portuguese language. + /// {@link Analyzer} for Brazilian Portuguese language. /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of + /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of /// exclusions (words that will not be stemmed, but indexed). /// /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. @@ -23,55 +23,55 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. BrazilianAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + /// Builds an analyzer with the given stop words and stemming exclusion words. BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - + virtual ~BrazilianAnalyzer(); - + LUCENE_CLASS(BrazilianAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stoptable; - + /// Contains words that should be indexed but not stemmed. HashSet excltable; - + LuceneVersion::Version matchVersion; - + /// List of typical Brazilian Portuguese stopwords. static const wchar_t* _BRAZILIAN_STOP_WORDS[]; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + void setStemExclusionTable(HashSet exclusions); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link BrazilianStemFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link BrazilianLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link BrazilianNormalizationFilter} and + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link BrazilianNormalizationFilter} and /// {@link BrazilianStemFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI BrazilianAnalyzerSavedStreams : public LuceneObject { public: virtual ~BrazilianAnalyzerSavedStreams(); - + LUCENE_CLASS(BrazilianAnalyzerSavedStreams); public: diff --git a/src/contrib/include/BrazilianStemFilter.h b/src/contrib/include/BrazilianStemFilter.h index 7080788d..73b928ff 100644 --- a/src/contrib/include/BrazilianStemFilter.h +++ b/src/contrib/include/BrazilianStemFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,18 +18,18 @@ namespace Lucene public: BrazilianStemFilter(TokenStreamPtr input); BrazilianStemFilter(TokenStreamPtr input, HashSet exclusiontable); - + virtual ~BrazilianStemFilter(); - + LUCENE_CLASS(BrazilianStemFilter); - + protected: /// {@link BrazilianStemmer} in use by this filter. BrazilianStemmerPtr stemmer; - + HashSet exclusions; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/BrazilianStemmer.h b/src/contrib/include/BrazilianStemmer.h index ae37877b..bcb2a1d7 100644 --- a/src/contrib/include/BrazilianStemmer.h +++ b/src/contrib/include/BrazilianStemmer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,16 +17,16 @@ namespace Lucene { public: virtual ~BrazilianStemmer(); - + LUCENE_CLASS(BrazilianStemmer); - + protected: String TERM; String CT; String R1; String R2; String RV; - + public: /// Stems the given term to a unique discriminator. /// @@ -38,24 +38,24 @@ namespace Lucene /// Checks a term if it can be processed correctly. /// @return true if, and only if, the given term consists in letters. bool isStemmable(const String& term); - + /// Checks a term if it can be processed indexed. /// @return true if it can be indexed bool isIndexable(const String& term); - + /// See if string is 'a','e','i','o','u' /// @return true if is vowel bool isVowel(wchar_t value); - + /// Gets R1. /// R1 - is the region after the first non-vowel following a vowel, or is the null region at the end of the /// word if there is no such non-vowel. /// @return null or a string representing R1 String getR1(const String& value); - + /// Gets RV. /// RV - if the second letter is a consonant, RV is the region after the next following vowel, - /// + /// /// OR if the first two letters are vowels, RV is the region after the next consonant, /// /// AND otherwise (consonant-vowel case) RV is the region after the third letter. @@ -63,50 +63,50 @@ namespace Lucene /// BUT RV is the end of the word if this positions cannot be found. /// @return null or a string representing RV String getRV(const String& value); - + /// 1) Turn to lowercase /// 2) Remove accents /// 3) ã -> a ; õ -> o /// 4) ç -> c /// @return null or a string transformed String changeTerm(const String& value); - + /// Check if a string ends with a suffix. /// @return true if the string ends with the specified suffix. bool checkSuffix(const String& value, const String& suffix); - + /// Replace a string suffix by another /// @return the replaced String String replaceSuffix(const String& value, const String& toReplace, const String& changeTo); - + /// Remove a string suffix. /// @return the String without the suffix; String removeSuffix(const String& value, const String& toRemove); - + /// See if a suffix is preceded by a String. /// @return true if the suffix is preceded. bool suffixPreceded(const String& value, const String& suffix, const String& preceded); - + /// Creates CT (changed term) , substituting * 'ã' and 'õ' for 'a~' and 'o~'. void createCT(const String& term); - + /// Standard suffix removal. /// @return false if no ending was removed bool step1(); - + /// Verb suffixes. /// Search for the longest among the following suffixes in RV, and if found, delete. /// @return false if no ending was removed bool step2(); - + /// Delete suffix 'i' if in RV and preceded by 'c' void step3(); - + /// Residual suffix /// If the word ends with one of the suffixes (os a i o á í ó) in RV, delete it. void step4(); - - /// If the word ends with one of (e é ê) in RV,delete it, and if preceded by 'gu' (or 'ci') with + + /// If the word ends with one of (e é ê) in RV,delete it, and if preceded by 'gu' (or 'ci') with /// the 'u' (or 'i') in RV, delete the 'u' (or 'i') /// /// Or if the word ends ç remove the cedilha. diff --git a/src/contrib/include/CJKAnalyzer.h b/src/contrib/include/CJKAnalyzer.h index e1ae37a3..2d0395e9 100644 --- a/src/contrib/include/CJKAnalyzer.h +++ b/src/contrib/include/CJKAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,44 +18,44 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. CJKAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. CJKAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + virtual ~CJKAnalyzer(); - + LUCENE_CLASS(CJKAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stoptable; - + LuceneVersion::Version matchVersion; - + /// List of typical English stopwords. static const wchar_t* _STOP_WORDS[]; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI CJKAnalyzerSavedStreams : public LuceneObject { public: virtual ~CJKAnalyzerSavedStreams(); - + LUCENE_CLASS(CJKAnalyzerSavedStreams); public: diff --git a/src/contrib/include/CJKTokenizer.h b/src/contrib/include/CJKTokenizer.h index 9e4dcc65..d75366e0 100644 --- a/src/contrib/include/CJKTokenizer.h +++ b/src/contrib/include/CJKTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -31,11 +31,11 @@ namespace Lucene CJKTokenizer(ReaderPtr input); CJKTokenizer(AttributeSourcePtr source, ReaderPtr input); CJKTokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~CJKTokenizer(); - + LUCENE_CLASS(CJKTokenizer); - + public: /// Word token type static const int32_t WORD_TYPE; @@ -48,47 +48,47 @@ namespace Lucene /// Names for token types static const wchar_t* TOKEN_TYPE_NAMES[]; - + protected: /// Max word length static const int32_t MAX_WORD_LEN; static const int32_t IO_BUFFER_SIZE; - + enum UnicodeBlock { NONE, BASIC_LATIN, HALFWIDTH_AND_FULLWIDTH_FORMS }; - + protected: /// word offset, used to imply which character(in) is parsed int32_t offset; - + /// the index used only for ioBuffer int32_t bufferIndex; - + /// data length int32_t dataLen; - + /// character buffer, store the characters which are used to compose the returned Token CharArray buffer; - + /// I/O buffer, used to store the content of the input (one of the members of Tokenizer) CharArray ioBuffer; - + /// word type: single=>ASCII double=>non-ASCII word=>default int32_t tokenType; - + /// tag: previous character is a cached double-byte character "C1C2C3C4" /// ----(set the C1 isTokened) C1C2 "C2C3C4" ----(set the C2 isTokened) /// C1C2 C2C3 "C3C4" ----(set the C3 isTokened) "C1C2 C2C3 C3C4" bool preIsTokened; - + TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; TypeAttributePtr typeAtt; - + protected: /// return unicode block for given character (see http://unicode.org/Public/UNIDATA/Blocks.txt) UnicodeBlock unicodeBlock(wchar_t c); - + public: virtual void initialize(); virtual bool incrementToken(); diff --git a/src/contrib/include/ChineseAnalyzer.h b/src/contrib/include/ChineseAnalyzer.h index 4026164f..bf489bea 100644 --- a/src/contrib/include/ChineseAnalyzer.h +++ b/src/contrib/include/ChineseAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,27 +17,27 @@ namespace Lucene { public: virtual ~ChineseAnalyzer(); - + LUCENE_CLASS(ChineseAnalyzer); - + public: /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI ChineseAnalyzerSavedStreams : public LuceneObject { public: virtual ~ChineseAnalyzerSavedStreams(); - + LUCENE_CLASS(ChineseAnalyzerSavedStreams); public: diff --git a/src/contrib/include/ChineseFilter.h b/src/contrib/include/ChineseFilter.h index efcb5fa9..5b691a84 100644 --- a/src/contrib/include/ChineseFilter.h +++ b/src/contrib/include/ChineseFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// A {@link TokenFilter} with a stop word table. + /// A {@link TokenFilter} with a stop word table. ///
      ///
    • Numeric tokens are removed. ///
    • English tokens must be larger than 1 character. @@ -23,17 +23,17 @@ namespace Lucene public: ChineseFilter(TokenStreamPtr input); virtual ~ChineseFilter(); - + LUCENE_CLASS(ChineseFilter); - + public: /// Only English now, Chinese to be added later. static const wchar_t* STOP_WORDS[]; - + protected: HashSet stopTable; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/ChineseTokenizer.h b/src/contrib/include/ChineseTokenizer.h index 5af00cc8..53552e26 100644 --- a/src/contrib/include/ChineseTokenizer.h +++ b/src/contrib/include/ChineseTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,13 +18,13 @@ namespace Lucene /// /// For example, if the Chinese text "C1C2C3C4" is to be indexed: ///
        - ///
      • The tokens returned from ChineseTokenizer are C1, C2, C3, C4. + ///
      • The tokens returned from ChineseTokenizer are C1, C2, C3, C4. ///
      • The tokens returned from the ChineseTokenizer are C1C2, C2C3, C3C4. ///
      /// /// Therefore the index created by ChineseTokenizer is much larger. /// - /// The problem is that when searching for C1, C1C2, C1C3, C4C2, C1C2C3 ... the + /// The problem is that when searching for C1, C1C2, C1C3, C4C2, C1C2C3 ... the /// ChineseTokenizer works, but the ChineseTokenizer will not work. class LPPCONTRIBAPI ChineseTokenizer : public Tokenizer { @@ -32,39 +32,39 @@ namespace Lucene ChineseTokenizer(ReaderPtr input); ChineseTokenizer(AttributeSourcePtr source, ReaderPtr input); ChineseTokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~ChineseTokenizer(); - + LUCENE_CLASS(ChineseTokenizer); - + protected: /// Max word length static const int32_t MAX_WORD_LEN; static const int32_t IO_BUFFER_SIZE; - + protected: /// word offset, used to imply which character(in) is parsed int32_t offset; - + /// the index used only for ioBuffer int32_t bufferIndex; - + /// data length int32_t dataLen; - + /// character buffer, store the characters which are used to compose the returned Token CharArray buffer; - + /// I/O buffer, used to store the content of the input (one of the members of Tokenizer) CharArray ioBuffer; - + TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; - + int32_t length; int32_t start; - + public: virtual void initialize(); virtual bool incrementToken(); diff --git a/src/contrib/include/ContribInc.h b/src/contrib/include/ContribInc.h index e11e3716..777bd0e8 100644 --- a/src/contrib/include/ContribInc.h +++ b/src/contrib/include/ContribInc.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/contrib/include/CzechAnalyzer.h b/src/contrib/include/CzechAnalyzer.h index e4c202c3..cc42cfdf 100644 --- a/src/contrib/include/CzechAnalyzer.h +++ b/src/contrib/include/CzechAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,9 +12,9 @@ namespace Lucene { - /// {@link Analyzer} for Czech language. + /// {@link Analyzer} for Czech language. /// - /// Supports an external list of stopwords (words that will not be indexed at all). + /// Supports an external list of stopwords (words that will not be indexed at all). /// A default set of stopwords is used unless an alternative list is specified. /// /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. @@ -23,46 +23,46 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. CzechAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. CzechAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + virtual ~CzechAnalyzer(); - + LUCENE_CLASS(CzechAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stoptable; - + LuceneVersion::Version matchVersion; - + /// Default Czech stopwords in UTF-8 format. static const uint8_t _CZECH_STOP_WORDS[]; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, /// {@link LowerCaseFilter}, and {@link StopFilter} virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, /// {@link LowerCaseFilter}, and {@link StopFilter} virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI CzechAnalyzerSavedStreams : public LuceneObject { public: virtual ~CzechAnalyzerSavedStreams(); - + LUCENE_CLASS(CzechAnalyzerSavedStreams); public: diff --git a/src/contrib/include/DefaultEncoder.h b/src/contrib/include/DefaultEncoder.h index c23fdf5a..57082ae7 100644 --- a/src/contrib/include/DefaultEncoder.h +++ b/src/contrib/include/DefaultEncoder.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,7 +17,7 @@ namespace Lucene public: virtual ~DefaultEncoder(); LUCENE_CLASS(DefaultEncoder); - + public: virtual String encodeText(const String& originalText); }; diff --git a/src/contrib/include/DutchAnalyzer.h b/src/contrib/include/DutchAnalyzer.h index e2d1a8cf..22e804bc 100644 --- a/src/contrib/include/DutchAnalyzer.h +++ b/src/contrib/include/DutchAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,10 +12,10 @@ namespace Lucene { - /// {@link Analyzer} for Dutch language. + /// {@link Analyzer} for Dutch language. /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of - /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an + /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of + /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an /// alternative list is specified, but the exclusion list is empty by default. /// /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. @@ -24,58 +24,58 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. DutchAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + /// Builds an analyzer with the given stop words and stemming exclusion words. DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - + virtual ~DutchAnalyzer(); - + LUCENE_CLASS(DutchAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stoptable; - + /// Contains words that should be indexed but not stemmed. HashSet excltable; - + MapStringString stemdict; - + LuceneVersion::Version matchVersion; - + /// List of typical Dutch stopwords. static const wchar_t* _DUTCH_STOP_WORDS[]; - + public: virtual void initialize(); - + /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + void setStemExclusionTable(HashSet exclusions); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI DutchAnalyzerSavedStreams : public LuceneObject { public: virtual ~DutchAnalyzerSavedStreams(); - + LUCENE_CLASS(DutchAnalyzerSavedStreams); public: diff --git a/src/contrib/include/DutchStemFilter.h b/src/contrib/include/DutchStemFilter.h index 2bce9a68..02796cec 100644 --- a/src/contrib/include/DutchStemFilter.h +++ b/src/contrib/include/DutchStemFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,48 +12,48 @@ namespace Lucene { - /// A {@link TokenFilter} that stems Dutch words. + /// A {@link TokenFilter} that stems Dutch words. /// - /// It supports a table of words that should not be stemmed at all. The stemmer used can - /// be changed at runtime after the filter object is created (as long as it is a + /// It supports a table of words that should not be stemmed at all. The stemmer used can + /// be changed at runtime after the filter object is created (as long as it is a /// {@link DutchStemmer}). /// - /// NOTE: This stemmer does not implement the Snowball algorithm correctly, specifically - /// doubled consonants. It is recommended that you consider using the "Dutch" stemmer in + /// NOTE: This stemmer does not implement the Snowball algorithm correctly, specifically + /// doubled consonants. It is recommended that you consider using the "Dutch" stemmer in /// the snowball package instead. This stemmer will likely be deprecated in a future release. class LPPCONTRIBAPI DutchStemFilter : public TokenFilter { public: DutchStemFilter(TokenStreamPtr input); - + /// Builds a DutchStemFilter that uses an exclusion table. DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable); - - /// Builds a DutchStemFilter that uses an exclusion table and dictionary of word stem + + /// Builds a DutchStemFilter that uses an exclusion table and dictionary of word stem /// pairs, that overrule the algorithm. DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable, MapStringString stemdictionary); - + virtual ~DutchStemFilter(); - + LUCENE_CLASS(DutchStemFilter); - + protected: /// {@link DutchStemmer} in use by this filter. DutchStemmerPtr stemmer; - + HashSet exclusions; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); - + /// Set a alternative/custom {@link DutchStemmer} for this filter. void setStemmer(DutchStemmerPtr stemmer); - + /// Set an alternative exclusion list for this filter. void setExclusionSet(HashSet exclusiontable); - - /// Set dictionary for stemming, this dictionary overrules the algorithm, so you can + + /// Set dictionary for stemming, this dictionary overrules the algorithm, so you can /// correct for a particular unwanted word-stem pair. void setStemDictionary(MapStringString dict); }; diff --git a/src/contrib/include/DutchStemmer.h b/src/contrib/include/DutchStemmer.h index 1ace4ef7..1adf969d 100644 --- a/src/contrib/include/DutchStemmer.h +++ b/src/contrib/include/DutchStemmer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene { /// A stemmer for Dutch words. /// - /// The algorithm is an implementation of the + /// The algorithm is an implementation of the /// dutch stemming /// algorithm in Martin Porter's snowball project. class LPPCONTRIBAPI DutchStemmer : public LuceneObject @@ -22,70 +22,70 @@ namespace Lucene public: DutchStemmer(); virtual ~DutchStemmer(); - + LUCENE_CLASS(DutchStemmer); - + protected: /// Buffer for the terms while stemming them. String buffer; - + bool removedE; MapStringString stemDict; - + int32_t R1; int32_t R2; - + public: /// Stems the given term to a unique discriminator. /// /// @param term The term that should be stemmed. /// @return Discriminator for term. String stem(const String& term); - + void setStemDictionary(MapStringString dict); protected: bool enEnding(); - + void step1(); - + /// Delete suffix e if in R1 and preceded by a non-vowel, and then undouble the ending. void step2(); - + /// Delete "heid" void step3a(); - - /// A d-suffix, or derivational suffix, enables a new word, often with a different grammatical - /// category, or with a different sense, to be built from another word. Whether a d-suffix can - /// be attached is discovered not from the rules of grammar, but by referring to a dictionary. - /// So in English, ness can be added to certain adjectives to form corresponding nouns - /// (littleness, kindness, foolishness ...) but not to all adjectives (not for example, to big, + + /// A d-suffix, or derivational suffix, enables a new word, often with a different grammatical + /// category, or with a different sense, to be built from another word. Whether a d-suffix can + /// be attached is discovered not from the rules of grammar, but by referring to a dictionary. + /// So in English, ness can be added to certain adjectives to form corresponding nouns + /// (littleness, kindness, foolishness ...) but not to all adjectives (not for example, to big, /// cruel, wise ...) d-suffixes can be used to change meaning, often in rather exotic ways. /// Remove "ing", "end", "ig", "lijk", "baar" and "bar" void step3b(); - - /// Undouble vowel. If the words ends CVD, where C is a non-vowel, D is a non-vowel other than - /// I, and V is double a, e, o or u, remove one of the vowels from V (for example, maan -> man, + + /// Undouble vowel. If the words ends CVD, where C is a non-vowel, D is a non-vowel other than + /// I, and V is double a, e, o or u, remove one of the vowels from V (for example, maan -> man, /// brood -> brod). void step4(); - + /// Checks if a term could be stemmed. bool isStemmable(); - + /// Substitute ä, ë, ï, ö, ü, á , é, í, ó, ú void substitute(); - + bool isValidSEnding(int32_t index); bool isValidEnEnding(int32_t index); - + void unDouble(); void unDouble(int32_t endIndex); - + int32_t getRIndex(int32_t start); void storeYandI(); void reStoreYandI(); - + bool isVowel(wchar_t c); }; } diff --git a/src/contrib/include/ElisionFilter.h b/src/contrib/include/ElisionFilter.h index a1185741..aa084fc6 100644 --- a/src/contrib/include/ElisionFilter.h +++ b/src/contrib/include/ElisionFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,23 +22,23 @@ namespace Lucene public: /// Constructs an elision filter with standard stop words. ElisionFilter(TokenStreamPtr input); - + /// Constructs an elision filter with a Set of stop words ElisionFilter(TokenStreamPtr input, HashSet articles); - + virtual ~ElisionFilter(); - + LUCENE_CLASS(ElisionFilter); - + protected: static const wchar_t apostrophes[]; - + CharArraySetPtr articles; TermAttributePtr termAtt; - + public: void setArticles(HashSet articles); - + virtual bool incrementToken(); }; } diff --git a/src/contrib/include/Encoder.h b/src/contrib/include/Encoder.h index a6d95747..0883f81d 100644 --- a/src/contrib/include/Encoder.h +++ b/src/contrib/include/Encoder.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,7 +18,7 @@ namespace Lucene public: virtual ~Encoder(); LUCENE_INTERFACE(Encoder); - + public: virtual String encodeText(const String& originalText); }; diff --git a/src/contrib/include/Formatter.h b/src/contrib/include/Formatter.h index b93541a4..b5c478c0 100644 --- a/src/contrib/include/Formatter.h +++ b/src/contrib/include/Formatter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,14 +12,14 @@ namespace Lucene { - /// Processes terms found in the original text, typically by applying some form of mark-up to highlight + /// Processes terms found in the original text, typically by applying some form of mark-up to highlight /// terms in HTML search results pages. class LPPCONTRIBAPI Formatter { public: virtual ~Formatter(); LUCENE_INTERFACE(Formatter); - + public: /// @param originalText The section of text being considered for markup /// @param tokenGroup contains one or several overlapping Tokens along with their scores and positions. diff --git a/src/contrib/include/Fragmenter.h b/src/contrib/include/Fragmenter.h index e197e971..c6532cce 100644 --- a/src/contrib/include/Fragmenter.h +++ b/src/contrib/include/Fragmenter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,24 +12,24 @@ namespace Lucene { - /// Implements the policy for breaking text into multiple fragments for consideration by the - /// {@link Highlighter} class. A sophisticated implementation may do this on the basis of + /// Implements the policy for breaking text into multiple fragments for consideration by the + /// {@link Highlighter} class. A sophisticated implementation may do this on the basis of /// detecting end of sentences in the text. class LPPCONTRIBAPI Fragmenter { public: virtual ~Fragmenter(); LUCENE_INTERFACE(Fragmenter); - + public: - /// Initializes the Fragmenter. You can grab references to the Attributes you are + /// Initializes the Fragmenter. You can grab references to the Attributes you are /// interested in from tokenStream and then access the values in {@link #isNewFragment()}. /// @param originalText the original source text. /// @param tokenStream the {@link TokenStream} to be fragmented. virtual void start(const String& originalText, TokenStreamPtr tokenStream); - - /// Test to see if this token from the stream should be held in a new TextFragment. - /// Every time this is called, the TokenStream passed to start(String, TokenStream) + + /// Test to see if this token from the stream should be held in a new TextFragment. + /// Every time this is called, the TokenStream passed to start(String, TokenStream) /// will have been incremented. virtual bool isNewFragment(); }; diff --git a/src/contrib/include/FrenchAnalyzer.h b/src/contrib/include/FrenchAnalyzer.h index df72a790..4c07da27 100644 --- a/src/contrib/include/FrenchAnalyzer.h +++ b/src/contrib/include/FrenchAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,10 +12,10 @@ namespace Lucene { - /// {@link Analyzer} for French language. + /// {@link Analyzer} for French language. /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of - /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an + /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of + /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an /// alternative list is specified, but the exclusion list is empty by default. /// /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. @@ -24,54 +24,54 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. FrenchAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + /// Builds an analyzer with the given stop words and stemming exclusion words. FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - + virtual ~FrenchAnalyzer(); - + LUCENE_CLASS(FrenchAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stoptable; - + /// Contains words that should be indexed but not stemmed. HashSet excltable; - + LuceneVersion::Version matchVersion; - + /// List of typical French stopwords. static const wchar_t* _FRENCH_STOP_WORDS[]; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + void setStemExclusionTable(HashSet exclusions); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter}, and {@link LowerCaseFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter} and {@link LowerCaseFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI FrenchAnalyzerSavedStreams : public LuceneObject { public: virtual ~FrenchAnalyzerSavedStreams(); - + LUCENE_CLASS(FrenchAnalyzerSavedStreams); public: diff --git a/src/contrib/include/FrenchStemFilter.h b/src/contrib/include/FrenchStemFilter.h index e017e28d..7e333ac3 100644 --- a/src/contrib/include/FrenchStemFilter.h +++ b/src/contrib/include/FrenchStemFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,40 +12,40 @@ namespace Lucene { - /// A {@link TokenFilter} that stems French words. + /// A {@link TokenFilter} that stems French words. /// - /// It supports a table of words that should not be stemmed at all. The stemmer used can - /// be changed at runtime after the filter object is created (as long as it is a + /// It supports a table of words that should not be stemmed at all. The stemmer used can + /// be changed at runtime after the filter object is created (as long as it is a /// {@link FrenchStemmer}). /// - /// NOTE: This stemmer does not implement the Snowball algorithm correctly, especially - /// involving case problems. It is recommended that you consider using the "French" stemmer + /// NOTE: This stemmer does not implement the Snowball algorithm correctly, especially + /// involving case problems. It is recommended that you consider using the "French" stemmer /// in the snowball package instead. This stemmer will likely be deprecated in a future release. class LPPCONTRIBAPI FrenchStemFilter : public TokenFilter { public: FrenchStemFilter(TokenStreamPtr input); - + /// Builds a FrenchStemFilter that uses an exclusion table. FrenchStemFilter(TokenStreamPtr input, HashSet exclusiontable); - + virtual ~FrenchStemFilter(); - + LUCENE_CLASS(FrenchStemFilter); - + protected: /// {@link FrenchStemmer} in use by this filter. FrenchStemmerPtr stemmer; - + HashSet exclusions; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); - + /// Set a alternative/custom {@link FrenchStemmer} for this filter. void setStemmer(FrenchStemmerPtr stemmer); - + /// Set an alternative exclusion list for this filter. void setExclusionSet(HashSet exclusiontable); }; diff --git a/src/contrib/include/FrenchStemmer.h b/src/contrib/include/FrenchStemmer.h index 2e1b1417..4a2dc3be 100644 --- a/src/contrib/include/FrenchStemmer.h +++ b/src/contrib/include/FrenchStemmer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,51 +14,51 @@ namespace Lucene { /// A stemmer for French words. /// - /// The algorithm is based on the work of Dr Martin Porter on his snowball project refer to + /// The algorithm is based on the work of Dr Martin Porter on his snowball project refer to /// http://snowball.sourceforge.net/french/stemmer.html (French stemming algorithm) for details. class LPPCONTRIBAPI FrenchStemmer : public LuceneObject { public: FrenchStemmer(); virtual ~FrenchStemmer(); - + LUCENE_CLASS(FrenchStemmer); - + protected: /// Buffer for the terms while stemming them. String stringBuffer; - + /// A temporary buffer, used to reconstruct R2. String tempBuffer; - + /// Region R0 is equal to the whole buffer. String R0; - + /// Region RV /// - /// "If the word begins with two vowels, RV is the region after the third letter, otherwise - /// the region after the first vowel not at the beginning of the word, or the end of the + /// "If the word begins with two vowels, RV is the region after the third letter, otherwise + /// the region after the first vowel not at the beginning of the word, or the end of the /// word if these positions cannot be found." String RV; - + /// Region R1 /// - /// "R1 is the region after the first non-vowel following a vowel or is the null region at + /// "R1 is the region after the first non-vowel following a vowel or is the null region at /// the end of the word if there is no such non-vowel" String R1; - + /// Region R2 /// - /// "R2 is the region after the first non-vowel in R1 following a vowel or is the null region + /// "R2 is the region after the first non-vowel in R1 following a vowel or is the null region /// at the end of the word if there is no such non-vowel" String R2; - + /// Set to true if we need to perform step 2 bool suite; - + /// Set to true if the buffer was modified bool modified; - + public: /// Stems the given term to a unique discriminator. /// @@ -69,39 +69,39 @@ namespace Lucene protected: /// Sets the search region Strings it needs to be done each time the buffer was modified. void setStrings(); - + /// First step of the Porter Algorithm. /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. void step1(); - + /// Second step (A) of the Porter Algorithm. - /// Will be performed if nothing changed from the first step or changed were done in the amment, + /// Will be performed if nothing changed from the first step or changed were done in the amment, /// emment, ments or ment suffixes. /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. /// @return true if something changed in the buffer bool step2a(); - + /// Second step (B) of the Porter Algorithm. /// Will be performed if step 2 A was performed unsuccessfully. /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. void step2b(); - + /// Third step of the Porter Algorithm. /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. void step3(); - + /// Fourth step of the Porter Algorithm. /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. void step4(); - + /// Fifth step of the Porter Algorithm. /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. void step5(); - + /// Sixth step of the Porter Algorithm. /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. void step6(); - + /// Delete a suffix searched in zone "source" if zone "from" contains prefix + search string. /// @param source String - the primary source zone for search. /// @param search String[] - the strings to search for suppression. @@ -109,7 +109,7 @@ namespace Lucene /// @param prefix String - the prefix to add to the search string to test. /// @return true if modified bool deleteFromIfPrecededIn(const String& source, Collection search, const String& from, const String& prefix); - + /// Delete a suffix searched in zone "source" if the preceding letter is (or isn't) a vowel. /// @param source String - the primary source zone for search. /// @param search String[] - the strings to search for suppression. @@ -117,59 +117,59 @@ namespace Lucene /// @param from String - the secondary source zone for search (where vowel could be). /// @return true if modified bool deleteFromIfTestVowelBeforeIn(const String& source, Collection search, bool vowel, const String& from); - + /// Delete a suffix searched in zone "source" if preceded by the prefix. /// @param source String - the primary source zone for search. /// @param search String[] - the strings to search for suppression. /// @param prefix String - the prefix to add to the search string to test. /// @param without boolean - true if it will be deleted even without prefix found. void deleteButSuffixFrom(const String& source, Collection search, const String& prefix, bool without); - - /// Delete a suffix searched in zone "source" if preceded by prefix or replace it with the + + /// Delete a suffix searched in zone "source" if preceded by prefix or replace it with the /// replace string if preceded by the prefix in the zone "from" or delete the suffix if specified. /// @param source String - the primary source zone for search. /// @param search String[] - the strings to search for suppression. /// @param prefix String - the prefix to add to the search string to test. /// @param without boolean - true if it will be deleted even without prefix found. void deleteButSuffixFromElseReplace(const String& source, Collection search, const String& prefix, bool without, const String& from, const String& replace); - + /// Replace a search string with another within the source zone. /// @param source String - the source zone for search. /// @param search String[] - the strings to search for replacement. /// @param replace String - the replacement string. bool replaceFrom(const String& source, Collection search, const String& replace); - + /// Delete a search string within the source zone. /// @param source the source zone for search. /// @param suffix the strings to search for suppression. void deleteFrom(const String& source, Collection suffix); - + /// Test if a char is a French vowel, including accentuated ones. /// @param ch the char to test. /// @return true if the char is a vowel bool isVowel(wchar_t ch); - + /// Retrieve the "R zone" (1 or 2 depending on the buffer) and return the corresponding string. - /// "R is the region after the first non-vowel following a vowel or is the null region at the + /// "R is the region after the first non-vowel following a vowel or is the null region at the /// end of the word if there is no such non-vowel". /// @param buffer the in buffer. /// @return the resulting string. String retrieveR(const String& buffer); - + /// Retrieve the "RV zone" from a buffer an return the corresponding string. - /// "If the word begins with two vowels, RV is the region after the third letter, otherwise the - /// region after the first vowel not at the beginning of the word, or the end of the word if + /// "If the word begins with two vowels, RV is the region after the third letter, otherwise the + /// region after the first vowel not at the beginning of the word, or the end of the word if /// these positions cannot be found." /// @param buffer the in buffer /// @return the resulting string String retrieveRV(const String& buffer); - + /// Turns u and i preceded AND followed by a vowel to UpperCase<. /// Turns y preceded OR followed by a vowel to UpperCase. /// Turns u preceded by q to UpperCase. /// @param buffer the buffer to treat void treatVowels(String& buffer); - + /// Checks a term if it can be processed correctly. /// @return boolean - true if, and only if, the given term consists in letters. bool isStemmable(const String& term); diff --git a/src/contrib/include/GermanAnalyzer.h b/src/contrib/include/GermanAnalyzer.h index 448ccb2d..a460a917 100644 --- a/src/contrib/include/GermanAnalyzer.h +++ b/src/contrib/include/GermanAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,10 +12,10 @@ namespace Lucene { - /// {@link Analyzer} for German language. + /// {@link Analyzer} for German language. /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of - /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an + /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of + /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an /// alternative list is specified, but the exclusion list is empty by default. /// /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. @@ -24,55 +24,55 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. GermanAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + /// Builds an analyzer with the given stop words and stemming exclusion words. GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - + virtual ~GermanAnalyzer(); - + LUCENE_CLASS(GermanAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stopSet; - + /// Contains words that should be indexed but not stemmed. HashSet exclusionSet; - + LuceneVersion::Version matchVersion; - + /// List of typical German stopwords. static const wchar_t* _GERMAN_STOP_WORDS[]; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + void setStemExclusionTable(HashSet exclusions); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link GermanStemFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link GermanLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link GermanNormalizationFilter} and + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link GermanNormalizationFilter} and /// {@link GermanStemFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI GermanAnalyzerSavedStreams : public LuceneObject { public: virtual ~GermanAnalyzerSavedStreams(); - + LUCENE_CLASS(GermanAnalyzerSavedStreams); public: diff --git a/src/contrib/include/GermanStemFilter.h b/src/contrib/include/GermanStemFilter.h index be34a9d7..6241d465 100644 --- a/src/contrib/include/GermanStemFilter.h +++ b/src/contrib/include/GermanStemFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,36 +12,36 @@ namespace Lucene { - /// A {@link TokenFilter} that stems German words. + /// A {@link TokenFilter} that stems German words. /// - /// It supports a table of words that should not be stemmed at all. The stemmer used can - /// be changed at runtime after the filter object is created (as long as it is a + /// It supports a table of words that should not be stemmed at all. The stemmer used can + /// be changed at runtime after the filter object is created (as long as it is a /// {@link GermanStemmer}). class LPPCONTRIBAPI GermanStemFilter : public TokenFilter { public: GermanStemFilter(TokenStreamPtr input); - + /// Builds a GermanStemFilter that uses an exclusion table. GermanStemFilter(TokenStreamPtr input, HashSet exclusionSet); - + virtual ~GermanStemFilter(); - + LUCENE_CLASS(GermanStemFilter); - + protected: /// {@link GermanStemmer} in use by this filter. GermanStemmerPtr stemmer; - + HashSet exclusionSet; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); - + /// Set a alternative/custom {@link GermanStemmer} for this filter. void setStemmer(GermanStemmerPtr stemmer); - + /// Set an alternative exclusion list for this filter. void setExclusionSet(HashSet exclusionSet); }; diff --git a/src/contrib/include/GermanStemmer.h b/src/contrib/include/GermanStemmer.h index 252a68ce..53a4ee83 100644 --- a/src/contrib/include/GermanStemmer.h +++ b/src/contrib/include/GermanStemmer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,16 +21,16 @@ namespace Lucene public: GermanStemmer(); virtual ~GermanStemmer(); - + LUCENE_CLASS(GermanStemmer); - + protected: /// Buffer for the terms while stemming them. String buffer; - + /// Amount of characters that are removed with substitute() while stemming. int32_t substCount; - + public: /// Stems the given term to a unique discriminator. /// @@ -42,29 +42,29 @@ namespace Lucene /// Checks if a term could be stemmed. /// @return true if, and only if, the given term consists in letters. bool isStemmable(); - - /// Suffix stripping (stemming) on the current term. The stripping is reduced to the seven "base" - /// suffixes "e", "s", "n", "t", "em", "er" and * "nd", from which all regular suffixes are build - /// of. The simplification causes some overstemming, and way more irregular stems, but still - /// provides unique. + + /// Suffix stripping (stemming) on the current term. The stripping is reduced to the seven "base" + /// suffixes "e", "s", "n", "t", "em", "er" and * "nd", from which all regular suffixes are build + /// of. The simplification causes some overstemming, and way more irregular stems, but still + /// provides unique. /// Discriminators in the most of those cases. /// The algorithm is context free, except of the length restrictions. void strip(); - + /// Does some optimizations on the term. This optimisations are contextual. void optimize(); - + /// Removes a particle denotion ("ge") from a term. void removeParticleDenotion(); - + /// Do some substitutions for the term to reduce overstemming: /// /// - Substitute Umlauts with their corresponding vowel: äöü -> aou, "ß" is substituted by "ss" /// - Substitute a second char of a pair of equal characters with an asterisk: ?? -> ?* /// - Substitute some common character combinations with a token: sch/ch/ei/ie/ig/st -> $/§/%/&/#/! void substitute(); - - /// Undoes the changes made by substitute(). That are character pairs and character combinations. + + /// Undoes the changes made by substitute(). That are character pairs and character combinations. /// Umlauts will remain as their corresponding vowel, as "ß" remains as "ss". void resubstitute(); }; diff --git a/src/contrib/include/GradientFormatter.h b/src/contrib/include/GradientFormatter.h index be6a23af..d3790089 100644 --- a/src/contrib/include/GradientFormatter.h +++ b/src/contrib/include/GradientFormatter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,41 +17,41 @@ namespace Lucene public: GradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor); virtual ~GradientFormatter(); - + LUCENE_CLASS(GradientFormatter); - + protected: double maxScore; bool highlightForeground; bool highlightBackground; - + public: int32_t fgRMin; int32_t fgGMin; int32_t fgBMin; - + int32_t fgRMax; int32_t fgGMax; int32_t fgBMax; - + int32_t bgRMin; int32_t bgGMin; int32_t bgBMin; - + int32_t bgRMax; int32_t bgGMax; int32_t bgBMax; - + public: virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); - + protected: String getForegroundColorString(double score); String getBackgroundColorString(double score); int32_t getColorVal(int32_t colorMin, int32_t colorMax, double score); static String intToHex(int32_t i); - + /// Converts a hex string into an int. static int32_t hexToInt(const String& hex); }; diff --git a/src/contrib/include/GreekAnalyzer.h b/src/contrib/include/GreekAnalyzer.h index dbc48e61..4f0d300c 100644 --- a/src/contrib/include/GreekAnalyzer.h +++ b/src/contrib/include/GreekAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,9 +12,9 @@ namespace Lucene { - /// {@link Analyzer} for Greek language. + /// {@link Analyzer} for Greek language. /// - /// Supports an external list of stopwords (words that will not be indexed at all). A default set of stopwords + /// Supports an external list of stopwords (words that will not be indexed at all). A default set of stopwords /// is used unless an alternative list is specified. /// /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. @@ -23,46 +23,46 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. GreekAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. GreekAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + virtual ~GreekAnalyzer(); - + LUCENE_CLASS(GreekAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stopSet; - + LuceneVersion::Version matchVersion; - + /// Default Greek stopwords in UTF-8 format. static const uint8_t _GREEK_STOP_WORDS[]; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link GreekLowerCaseFilter} and {@link StopFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link GreekLetterTokenizer} filtered with /// {@link GreekLowerCaseFilter} and {@link StopFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI GreekAnalyzerSavedStreams : public LuceneObject { public: virtual ~GreekAnalyzerSavedStreams(); - + LUCENE_CLASS(GreekAnalyzerSavedStreams); public: diff --git a/src/contrib/include/GreekLowerCaseFilter.h b/src/contrib/include/GreekLowerCaseFilter.h index b59b3284..3409d96c 100644 --- a/src/contrib/include/GreekLowerCaseFilter.h +++ b/src/contrib/include/GreekLowerCaseFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,22 +12,22 @@ namespace Lucene { - /// Normalizes token text to lower case, removes some Greek diacritics, and standardizes - /// final sigma to sigma. + /// Normalizes token text to lower case, removes some Greek diacritics, and standardizes + /// final sigma to sigma. class LPPCONTRIBAPI GreekLowerCaseFilter : public TokenFilter { public: GreekLowerCaseFilter(TokenStreamPtr input); virtual ~GreekLowerCaseFilter(); - + LUCENE_CLASS(GreekLowerCaseFilter); - + protected: TermAttributePtr termAtt; - + public: virtual bool incrementToken(); - + protected: wchar_t lowerCase(wchar_t codepoint); }; diff --git a/src/contrib/include/Highlighter.h b/src/contrib/include/Highlighter.h index 1481c837..cc9780cb 100644 --- a/src/contrib/include/Highlighter.h +++ b/src/contrib/include/Highlighter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// Class used to markup highlighted terms found in the best sections of a text, using configurable + /// Class used to markup highlighted terms found in the best sections of a text, using configurable /// {@link Fragmenter}, {@link Scorer}, {@link Formatter}, {@link Encoder} and tokenizers. class LPPCONTRIBAPI Highlighter : public LuceneObject { @@ -20,23 +20,23 @@ namespace Lucene Highlighter(HighlighterScorerPtr fragmentScorer); Highlighter(FormatterPtr formatter, HighlighterScorerPtr fragmentScorer); Highlighter(FormatterPtr formatter, EncoderPtr encoder, HighlighterScorerPtr fragmentScorer); - + virtual ~Highlighter(); - + LUCENE_CLASS(Highlighter); - + public: static const int32_t DEFAULT_MAX_CHARS_TO_ANALYZE; - + protected: int32_t maxDocCharsToAnalyze; FormatterPtr formatter; EncoderPtr encoder; FragmenterPtr textFragmenter; HighlighterScorerPtr fragmentScorer; - + public: - /// Highlights chosen terms in a text, extracting the most relevant section. This is a convenience + /// Highlights chosen terms in a text, extracting the most relevant section. This is a convenience /// method that calls {@link #getBestFragment(TokenStreamPtr, const String&)} /// /// @param analyzer The analyzer that will be used to split text into chunks @@ -44,20 +44,20 @@ namespace Lucene /// @param fieldName Name of field used to influence analyzer's tokenization policy /// @return highlighted text fragment or null if no terms found String getBestFragment(AnalyzerPtr analyzer, const String& fieldName, const String& text); - - /// Highlights chosen terms in a text, extracting the most relevant section. The document text is - /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the + + /// Highlights chosen terms in a text, extracting the most relevant section. The document text is + /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the /// fragment with the highest score is returned. /// - /// @param tokenStream A stream of tokens identified in the text parameter, including offset - /// information. This is typically produced by an analyzer re-parsing a document's text. Some - /// work may be done on retrieving TokenStreams more efficiently by adding support for storing + /// @param tokenStream A stream of tokens identified in the text parameter, including offset + /// information. This is typically produced by an analyzer re-parsing a document's text. Some + /// work may be done on retrieving TokenStreams more efficiently by adding support for storing /// original text position data in the Lucene index but this support is not currently available. /// @param text Text to highlight terms in /// @return highlighted text fragment or null if no terms found String getBestFragment(TokenStreamPtr tokenStream, const String& text); - - /// Highlights chosen terms in a text, extracting the most relevant sections. This is a convenience + + /// Highlights chosen terms in a text, extracting the most relevant sections. This is a convenience /// method that calls {@link #getBestFragments(TokenStreamPtr, const String&, int32_t)} /// /// @param analyzer The analyzer that will be used to split text into chunks @@ -66,30 +66,30 @@ namespace Lucene /// @param maxNumFragments The maximum number of fragments. /// @return highlighted text fragments (between 0 and maxNumFragments number of fragments) Collection getBestFragments(AnalyzerPtr analyzer, const String& fieldName, const String& text, int32_t maxNumFragments); - - /// Highlights chosen terms in a text, extracting the most relevant sections. The document text is - /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the - /// fragments with the highest scores are returned as an array of strings in order of score (contiguous + + /// Highlights chosen terms in a text, extracting the most relevant sections. The document text is + /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the + /// fragments with the highest scores are returned as an array of strings in order of score (contiguous /// fragments are merged into one in their original order to improve readability) - /// + /// /// @param text Text to highlight terms in /// @param maxNumFragments The maximum number of fragments. /// @return highlighted Text fragments (between 0 and maxNumFragments number of fragments) Collection getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments); - + /// Low level api to get the most relevant (formatted) sections of the document. /// This method has been made public to allow visibility of score information held in TextFragment objects. Collection getBestTextFragments(TokenStreamPtr tokenStream, const String& text, bool merge, int32_t maxNumFragments); - - /// Improves readability of a score-sorted list of TextFragments by merging any fragments that were - /// contiguous in the original text into one larger fragment with the correct order. This will leave - /// a "null" in the array entry for the lesser scored fragment. + + /// Improves readability of a score-sorted list of TextFragments by merging any fragments that were + /// contiguous in the original text into one larger fragment with the correct order. This will leave + /// a "null" in the array entry for the lesser scored fragment. /// /// @param frag An array of document fragments in descending score void mergeContiguousFragments(Collection frag); - - /// Highlights terms in the text , extracting the most relevant sections and concatenating the chosen - /// fragments with a separator (typically "..."). The document text is analyzed in chunks to record + + /// Highlights terms in the text , extracting the most relevant sections and concatenating the chosen + /// fragments with a separator (typically "..."). The document text is analyzed in chunks to record /// hit statistics across the document. After accumulating stats, the fragments with the highest scores /// are returned in order as "separator" delimited strings. /// @@ -98,29 +98,29 @@ namespace Lucene /// @param separator The separator used to intersperse the document fragments (typically "...") /// @return highlighted text String getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments, const String& separator); - + int32_t getMaxDocCharsToAnalyze(); void setMaxDocCharsToAnalyze(int32_t maxDocCharsToAnalyze); FragmenterPtr getTextFragmenter(); void setTextFragmenter(FragmenterPtr fragmenter); - - /// @return Object used to score each text fragment + + /// @return Object used to score each text fragment HighlighterScorerPtr getFragmentScorer(); - + void setFragmentScorer(HighlighterScorerPtr scorer); - + EncoderPtr getEncoder(); void setEncoder(EncoderPtr encoder); }; - + class LPPCONTRIBAPI FragmentQueue : public PriorityQueue { public: FragmentQueue(int32_t size); virtual ~FragmentQueue(); - + LUCENE_CLASS(FragmentQueue); - + protected: virtual bool lessThan(const TextFragmentPtr& first, const TextFragmentPtr& second); }; diff --git a/src/contrib/include/HighlighterScorer.h b/src/contrib/include/HighlighterScorer.h index 574f838c..cd0d3a8f 100644 --- a/src/contrib/include/HighlighterScorer.h +++ b/src/contrib/include/HighlighterScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,31 +19,31 @@ namespace Lucene public: virtual ~HighlighterScorer(); LUCENE_INTERFACE(HighlighterScorer); - + public: - /// Called to init the Scorer with a {@link TokenStream}. You can grab references to the + /// Called to init the Scorer with a {@link TokenStream}. You can grab references to the /// attributes you are interested in here and access them from {@link #getTokenScore()}. /// /// @param tokenStream the {@link TokenStream} that will be scored. /// @return either a {@link TokenStream} that the Highlighter should continue using (eg - /// if you read the tokenSream in this method) or null to continue using the same {@link + /// if you read the tokenSream in this method) or null to continue using the same {@link /// TokenStream} that was passed in. virtual TokenStreamPtr init(TokenStreamPtr tokenStream); - + /// Called when a new fragment is started for consideration. /// /// @param newFragment the fragment that will be scored next virtual void startFragment(TextFragmentPtr newFragment); - - /// Called for each token in the current fragment. The {@link Highlighter} will increment + + /// Called for each token in the current fragment. The {@link Highlighter} will increment /// the {@link TokenStream} passed to init on every call. /// - /// @return a score which is passed to the {@link Highlighter} class to influence the + /// @return a score which is passed to the {@link Highlighter} class to influence the /// mark-up of the text (this return value is NOT used to score the fragment) virtual double getTokenScore(); - - /// Called when the {@link Highlighter} has no more tokens for the current fragment - the - /// Scorer returns the weighting it has derived for the most recent fragment, typically + + /// Called when the {@link Highlighter} has no more tokens for the current fragment - the + /// Scorer returns the weighting it has derived for the most recent fragment, typically /// based on the results of {@link #getTokenScore()}. virtual double getFragmentScore(); }; diff --git a/src/contrib/include/LuceneContrib.h b/src/contrib/include/LuceneContrib.h index dee5d126..f240b24b 100644 --- a/src/contrib/include/LuceneContrib.h +++ b/src/contrib/include/LuceneContrib.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -62,7 +62,7 @@ namespace Lucene DECLARE_SHARED_PTR(SnowballFilter) DECLARE_SHARED_PTR(SnowballAnalyzer) DECLARE_SHARED_PTR(SnowballAnalyzerSavedStreams) - + // highlighter DECLARE_SHARED_PTR(DefaultEncoder) DECLARE_SHARED_PTR(Encoder) @@ -103,13 +103,13 @@ namespace Lucene typedef HashMap< String, SpanQueryPtr > MapStringSpanQuery; typedef HashMap< String, Collection > MapStringIntCollection; typedef HashMap< String, MemoryIndexInfoPtr > MapStringMemoryIndexInfo; - + typedef std::pair< String, Collection > PairStringIntCollection; typedef Collection< PairStringIntCollection > CollectionStringIntCollection; - + typedef std::pair< String, MemoryIndexInfoPtr > PairStringMemoryIndexInfo; typedef Collection< PairStringMemoryIndexInfo > CollectionStringMemoryIndexInfo; - + typedef HashSet< WeightedTermPtr, luceneHash, luceneEquals > SetWeightedTerm; } diff --git a/src/contrib/include/MapWeightedSpanTerm.h b/src/contrib/include/MapWeightedSpanTerm.h index c6aebef0..190283fe 100644 --- a/src/contrib/include/MapWeightedSpanTerm.h +++ b/src/contrib/include/MapWeightedSpanTerm.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,12 +18,12 @@ namespace Lucene public: MapWeightedSpanTerm(); virtual ~MapWeightedSpanTerm(); - + LUCENE_CLASS(MapWeightedSpanTerm); - + protected: MapStringWeightedSpanTerm map; - + public: virtual MapStringWeightedSpanTerm::iterator begin(); virtual MapStringWeightedSpanTerm::iterator end(); diff --git a/src/contrib/include/MemoryIndex.h b/src/contrib/include/MemoryIndex.h index e5ee3633..e8536295 100644 --- a/src/contrib/include/MemoryIndex.h +++ b/src/contrib/include/MemoryIndex.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,41 +16,41 @@ namespace Lucene { - /// High-performance single-document main memory Lucene fulltext search index. + /// High-performance single-document main memory Lucene fulltext search index. /// /// Overview /// - /// This class is a replacement/substitute for a large subset of {@link RAMDirectory} functionality. - /// It is designed to enable maximum efficiency for on-the-fly matchmaking combining structured and - /// fuzzy fulltext search in realtime streaming applications such as Nux XQuery based XML message - /// queues, publish-subscribe systems for Blogs/newsfeeds, text chat, data acquisition and - /// distribution systems, application level routers, firewalls, classifiers, etc. Rather than - /// targeting fulltext search of infrequent queries over huge persistent data archives (historic - /// search), this class targets fulltext search of huge numbers of queries over comparatively small - /// transient realtime data (prospective search). + /// This class is a replacement/substitute for a large subset of {@link RAMDirectory} functionality. + /// It is designed to enable maximum efficiency for on-the-fly matchmaking combining structured and + /// fuzzy fulltext search in realtime streaming applications such as Nux XQuery based XML message + /// queues, publish-subscribe systems for Blogs/newsfeeds, text chat, data acquisition and + /// distribution systems, application level routers, firewalls, classifiers, etc. Rather than + /// targeting fulltext search of infrequent queries over huge persistent data archives (historic + /// search), this class targets fulltext search of huge numbers of queries over comparatively small + /// transient realtime data (prospective search). /// - /// For example as in + /// For example as in ///
           /// double score = search(const String& text, QueryPtr query)
           /// 
      /// - /// Each instance can hold at most one Lucene "document", with a document containing zero or more - /// "fields", each field having a name and a fulltext value. The fulltext value is tokenized - /// (split and transformed) into zero or more index terms (aka words) on addField(), according to - /// the policy implemented by an Analyzer. For example, Lucene analyzers can split on whitespace, - /// normalize to lower case for case insensitivity, ignore common terms with little discriminatory - /// value such as "he", "in", "and" (stop words), reduce the terms to their natural linguistic root - /// form such as "fishing" being reduced to "fish" (stemming), resolve synonyms/inflexions/thesauri + /// Each instance can hold at most one Lucene "document", with a document containing zero or more + /// "fields", each field having a name and a fulltext value. The fulltext value is tokenized + /// (split and transformed) into zero or more index terms (aka words) on addField(), according to + /// the policy implemented by an Analyzer. For example, Lucene analyzers can split on whitespace, + /// normalize to lower case for case insensitivity, ignore common terms with little discriminatory + /// value such as "he", "in", "and" (stop words), reduce the terms to their natural linguistic root + /// form such as "fishing" being reduced to "fish" (stemming), resolve synonyms/inflexions/thesauri /// (upon indexing and/or querying), etc. /// - /// Note that a Lucene query selects on the field names and associated (indexed) tokenized terms, - /// not on the original fulltext(s) - the latter are not stored but rather thrown away immediately + /// Note that a Lucene query selects on the field names and associated (indexed) tokenized terms, + /// not on the original fulltext(s) - the latter are not stored but rather thrown away immediately /// after tokenization. /// /// For some interesting background information on search technology, see Bob Wyman's Prospective Search, + /// href="http://bobwyman.pubsub.com/main/2005/05/mary_hodder_poi.html">Prospective Search, /// Jim Gray's - /// A Call to Arms - Custom subscriptions, and Tim Bray's , and Tim Bray's On Search, the Series. /// /// @@ -75,166 +75,166 @@ namespace Lucene /// /// Performance Notes /// - /// Internally there's a new data structure geared towards efficient indexing and searching, plus + /// Internally there's a new data structure geared towards efficient indexing and searching, plus /// the necessary support code to seamlessly plug into the Lucene framework. /// - /// This class performs very well for very small texts (eg. 10 chars) as well as for large texts - /// (eg. 10 MB) and everything in between. Typically, it is about 10-100 times faster than - /// RAMDirectory. Note that RAMDirectory has particularly large efficiency overheads for small to - /// medium sized texts, both in time and space. Indexing a field with N tokens takes O(N) in the - /// best case, and O(N logN) in the worst case. Memory consumption is probably larger than for + /// This class performs very well for very small texts (eg. 10 chars) as well as for large texts + /// (eg. 10 MB) and everything in between. Typically, it is about 10-100 times faster than + /// RAMDirectory. Note that RAMDirectory has particularly large efficiency overheads for small to + /// medium sized texts, both in time and space. Indexing a field with N tokens takes O(N) in the + /// best case, and O(N logN) in the worst case. Memory consumption is probably larger than for /// RAMDirectory. /// class LPPCONTRIBAPI MemoryIndex : public LuceneObject { public: - /// Constructs an empty instance that can optionally store the start and end character offset - /// of each token term in the text. This can be useful for highlighting of hit locations with - /// the Lucene highlighter package. Private until the highlighter package matures, so that + /// Constructs an empty instance that can optionally store the start and end character offset + /// of each token term in the text. This can be useful for highlighting of hit locations with + /// the Lucene highlighter package. Private until the highlighter package matures, so that /// this can actually be meaningfully integrated. - /// @param storeOffsets Whether or not to store the start and end character offset of each + /// @param storeOffsets Whether or not to store the start and end character offset of each /// token term in the text. MemoryIndex(bool storeOffsets = false); - + virtual ~MemoryIndex(); - + LUCENE_CLASS(MemoryIndex); protected: /// info for each field MapStringMemoryIndexInfo fields; - + /// fields sorted ascending by fieldName; lazily computed on demand CollectionStringMemoryIndexInfo sortedFields; - + /// pos: positions[3 * i], startOffset: positions[3 * i + 1], endOffset: positions[3 * i + 2] int32_t stride; - + static const double docBoost; - + public: - /// Convenience method; Tokenizes the given field text and adds the resulting terms to the - /// index; Equivalent to adding an indexed non-keyword Lucene {@link Field} that is {@link - /// Field::INDEX_ANALYZED tokenized}, {@link Field::STORE_NO not stored}, {@link - /// Field::TERM_VECTOR_WITH_POSITIONS termVectorStored with positions} (or {@link + /// Convenience method; Tokenizes the given field text and adds the resulting terms to the + /// index; Equivalent to adding an indexed non-keyword Lucene {@link Field} that is {@link + /// Field::INDEX_ANALYZED tokenized}, {@link Field::STORE_NO not stored}, {@link + /// Field::TERM_VECTOR_WITH_POSITIONS termVectorStored with positions} (or {@link /// Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS termVectorStored with positions and offsets}) /// @param fieldName A name to be associated with the text /// @param text The text to tokenize and index. /// @param analyzer The analyzer to use for tokenization void addField(const String& fieldName, const String& text, AnalyzerPtr analyzer); - - /// Iterates over the given token stream and adds the resulting terms to the index; - /// Equivalent to adding a tokenized, indexed, termVectorStored, unstored, Lucene {@link - /// Field}. Finally closes the token stream. Note that untokenized keywords can be added - /// with this method via {@link #keywordTokenStream(Collection)}, the Lucene contrib + + /// Iterates over the given token stream and adds the resulting terms to the index; + /// Equivalent to adding a tokenized, indexed, termVectorStored, unstored, Lucene {@link + /// Field}. Finally closes the token stream. Note that untokenized keywords can be added + /// with this method via {@link #keywordTokenStream(Collection)}, the Lucene contrib /// KeywordTokenizer or similar utilities. /// @param fieldName A name to be associated with the text. /// @param stream The token stream to retrieve tokens from. /// @param boost The boost factor for hits for this field. /// @see Field#setBoost(double) void addField(const String& fieldName, TokenStreamPtr stream, double boost = 1.0); - - /// Creates and returns a searcher that can be used to execute arbitrary Lucene queries + + /// Creates and returns a searcher that can be used to execute arbitrary Lucene queries /// and to collect the resulting query results as hits. /// @return a searcher IndexSearcherPtr createSearcher(); - - /// Convenience method that efficiently returns the relevance score by matching this index + + /// Convenience method that efficiently returns the relevance score by matching this index /// against the given Lucene query expression. /// @param query An arbitrary Lucene query to run against this index - /// @return the relevance score of the matchmaking; A number in the range [0.0 .. 1.0], + /// @return the relevance score of the matchmaking; A number in the range [0.0 .. 1.0], /// with 0.0 indicating no match. The higher the number the better the match. double search(QueryPtr query); - + protected: int32_t numPositions(Collection positions); - + /// sorts into ascending order (on demand), reusing memory along the way void sortFields(); - + friend class MemoryIndexReader; friend class MemoryIndexInfo; friend class MemoryIndexTermEnum; friend class MemoryIndexTermPositions; friend class MemoryIndexTermPositionVector; }; - + /// Index data structure for a field; Contains the tokenized term texts and their positions. class LPPCONTRIBAPI MemoryIndexInfo : public LuceneObject { public: MemoryIndexInfo(MapStringIntCollection terms, int32_t numTokens, int32_t numOverlapTokens, double boost); virtual ~MemoryIndexInfo(); - + LUCENE_CLASS(MemoryIndexInfo); - + protected: /// Term strings and their positions for this field MapStringIntCollection terms; - + /// Terms sorted ascending by term text; computed on demand CollectionStringIntCollection sortedTerms; - + /// Number of added tokens for this field int32_t numTokens; - + /// Number of overlapping tokens for this field int32_t numOverlapTokens; - + /// Boost factor for hits for this field double boost; - + /// Term for this field's fieldName, lazily computed on demand TermPtr _template; - + public: - /// Sorts hashed terms into ascending order, reusing memory along the way. Note that + /// Sorts hashed terms into ascending order, reusing memory along the way. Note that /// sorting is lazily delayed until required (often it's not required at all). void sortTerms(); - + /// Note that the frequency can be calculated as numPosition(getPositions(x)) Collection getPositions(const String& term); - + /// Note that the frequency can be calculated as numPosition(getPositions(x)) Collection getPositions(int32_t pos); - + double getBoost(); - + friend class MemoryIndexReader; friend class MemoryIndexTermEnum; friend class MemoryIndexTermPositions; friend class MemoryIndexTermPositionVector; }; - - /// Search support for Lucene framework integration; implements all methods required by the + + /// Search support for Lucene framework integration; implements all methods required by the /// Lucene IndexReader contracts. class LPPCONTRIBAPI MemoryIndexReader : public IndexReader { public: MemoryIndexReader(MemoryIndexPtr memoryIndex); virtual ~MemoryIndexReader(); - + LUCENE_CLASS(MemoryIndexReader); - + public: static TermPtr MATCH_ALL_TERM(); - + protected: MemoryIndexPtr memoryIndex; - SearcherWeakPtr _searcher; // needed to find searcher.getSimilarity() - + SearcherWeakPtr _searcher; // needed to find searcher.getSimilarity() + /// cache norms to avoid repeated expensive calculations ByteArray cachedNorms; String cachedFieldName; SimilarityPtr cachedSimilarity; - + protected: MemoryIndexInfoPtr getInfo(const String& fieldName); MemoryIndexInfoPtr getInfo(int32_t pos); - + SimilarityPtr getSimilarity(); void setSearcher(SearcherPtr searcher); - + public: virtual int32_t docFreq(TermPtr t); virtual TermEnumPtr terms(); @@ -259,70 +259,70 @@ namespace Lucene virtual void doCommit(MapStringString commitUserData); virtual void doClose(); virtual HashSet getFieldNames(FieldOption fieldOption); - + friend class MemoryIndex; friend class MemoryIndexTermEnum; friend class MemoryIndexTermPositions; friend class MemoryIndexTermPositionVector; }; - + class LPPCONTRIBAPI MemoryIndexTermEnum : public TermEnum { public: MemoryIndexTermEnum(MemoryIndexReaderPtr reader, int32_t ix, int32_t jx); virtual ~MemoryIndexTermEnum(); - + LUCENE_CLASS(MemoryIndexTermEnum); - + protected: MemoryIndexReaderWeakPtr _reader; int32_t i; int32_t j; - + public: virtual bool next(); virtual TermPtr term(); virtual int32_t docFreq(); virtual void close(); - + protected: TermPtr createTerm(MemoryIndexInfoPtr info, int32_t pos, const String& text); }; - + class LPPCONTRIBAPI MemoryIndexCollector : public Collector { public: MemoryIndexCollector(Collection scores); virtual ~MemoryIndexCollector(); - + LUCENE_CLASS(MemoryIndexCollector); - + protected: Collection scores; ScorerPtr scorer; - + public: virtual void collect(int32_t doc); virtual void setScorer(ScorerPtr scorer); virtual bool acceptsDocsOutOfOrder(); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); }; - + class LPPCONTRIBAPI MemoryIndexTermPositions : public TermPositions, public LuceneObject { public: MemoryIndexTermPositions(MemoryIndexReaderPtr reader); virtual ~MemoryIndexTermPositions(); - + LUCENE_CLASS(MemoryIndexTermPositions); - + protected: MemoryIndexReaderWeakPtr _reader; bool hasNext; int32_t cursor; Collection current; TermPtr term; - + public: virtual void seek(TermPtr term); virtual void seek(TermEnumPtr termEnum); @@ -332,26 +332,26 @@ namespace Lucene virtual int32_t read(Collection docs, Collection freqs); virtual bool skipTo(int32_t target); virtual void close(); - + virtual int32_t nextPosition(); virtual int32_t getPayloadLength(); virtual ByteArray getPayload(ByteArray data, int32_t offset); virtual bool isPayloadAvailable(); }; - + class MemoryIndexTermPositionVector : public TermPositionVector, public LuceneObject { public: MemoryIndexTermPositionVector(MemoryIndexReaderPtr reader, MemoryIndexInfoPtr info, const String& fieldName); virtual ~MemoryIndexTermPositionVector(); - + LUCENE_CLASS(MemoryIndexTermPositionVector); - + protected: MemoryIndexReaderWeakPtr _reader; CollectionStringIntCollection sortedTerms; String fieldName; - + public: virtual String getField(); virtual int32_t size(); @@ -359,7 +359,7 @@ namespace Lucene virtual Collection getTermFrequencies(); virtual int32_t indexOf(const String& term); virtual Collection indexesOf(Collection terms, int32_t start, int32_t length); - + virtual Collection getTermPositions(int32_t index); virtual Collection getOffsets(int32_t index); }; diff --git a/src/contrib/include/NullFragmenter.h b/src/contrib/include/NullFragmenter.h index 97e3e48f..7dd7d65c 100644 --- a/src/contrib/include/NullFragmenter.h +++ b/src/contrib/include/NullFragmenter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,14 +11,14 @@ namespace Lucene { - /// {@link Fragmenter} implementation which does not fragment the text. This is useful for + /// {@link Fragmenter} implementation which does not fragment the text. This is useful for /// highlighting the entire content of a document or field. class LPPCONTRIBAPI NullFragmenter : public Fragmenter, public LuceneObject { public: virtual ~NullFragmenter(); LUCENE_CLASS(NullFragmenter); - + public: virtual void start(const String& originalText, TokenStreamPtr tokenStream); virtual bool isNewFragment(); diff --git a/src/contrib/include/PersianAnalyzer.h b/src/contrib/include/PersianAnalyzer.h index ea32e174..83e05946 100644 --- a/src/contrib/include/PersianAnalyzer.h +++ b/src/contrib/include/PersianAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,63 +12,63 @@ namespace Lucene { - /// {@link Analyzer} for Persian. + /// {@link Analyzer} for Persian. /// /// This Analyzer uses {@link ArabicLetterTokenizer} which implies tokenizing around - /// zero-width non-joiner in addition to whitespace. Some persian-specific variant - /// forms (such as farsi yeh and keheh) are standardized. "Stemming" is accomplished + /// zero-width non-joiner in addition to whitespace. Some persian-specific variant + /// forms (such as farsi yeh and keheh) are standardized. "Stemming" is accomplished /// via stopwords. class LPPCONTRIBAPI PersianAnalyzer : public Analyzer { public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. PersianAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. PersianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + virtual ~PersianAnalyzer(); - + LUCENE_CLASS(PersianAnalyzer); - + public: /// Default Persian stopwords in UTF-8 format. /// /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html /// The stopword list is BSD-Licensed. static const uint8_t DEFAULT_STOPWORD_FILE[]; - + protected: /// Contains the stopwords used with the StopFilter. HashSet stoptable; - + LuceneVersion::Version matchVersion; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} + /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} /// and Persian Stop words. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} + /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} /// and Persian Stop words. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI PersianAnalyzerSavedStreams : public LuceneObject { public: virtual ~PersianAnalyzerSavedStreams(); - + LUCENE_CLASS(PersianAnalyzerSavedStreams); public: diff --git a/src/contrib/include/PersianNormalizationFilter.h b/src/contrib/include/PersianNormalizationFilter.h index 2c4bd604..3300887b 100644 --- a/src/contrib/include/PersianNormalizationFilter.h +++ b/src/contrib/include/PersianNormalizationFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,13 +18,13 @@ namespace Lucene public: PersianNormalizationFilter(TokenStreamPtr input); virtual ~PersianNormalizationFilter(); - + LUCENE_CLASS(PersianNormalizationFilter); - + protected: PersianNormalizerPtr normalizer; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/PersianNormalizer.h b/src/contrib/include/PersianNormalizer.h index 523af01e..4e1b692b 100644 --- a/src/contrib/include/PersianNormalizer.h +++ b/src/contrib/include/PersianNormalizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,27 +26,27 @@ namespace Lucene { public: virtual ~PersianNormalizer(); - + LUCENE_CLASS(PersianNormalizer); - + public: static const wchar_t YEH; static const wchar_t FARSI_YEH; static const wchar_t YEH_BARREE; - static const wchar_t KEHEH; - static const wchar_t KAF; + static const wchar_t KEHEH; + static const wchar_t KAF; static const wchar_t HAMZA_ABOVE; static const wchar_t HEH_YEH; static const wchar_t HEH_GOAL; static const wchar_t HEH; - + public: /// Normalize an input buffer of Persian text /// @param s input buffer /// @param len length of input buffer /// @return length of input buffer after normalization int32_t normalize(wchar_t* s, int32_t len); - + /// Delete a character in-place /// @param s Input Buffer /// @param pos Position of character to delete diff --git a/src/contrib/include/QueryScorer.h b/src/contrib/include/QueryScorer.h index a5064391..442c0073 100644 --- a/src/contrib/include/QueryScorer.h +++ b/src/contrib/include/QueryScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,42 +12,42 @@ namespace Lucene { - /// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. - /// This class converts appropriate {@link Query}s to {@link SpanQuery}s and attempts to score only + /// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. + /// This class converts appropriate {@link Query}s to {@link SpanQuery}s and attempts to score only /// those terms that participated in generating the 'hit' on the document. class LPPCONTRIBAPI QueryScorer : public HighlighterScorer, public LuceneObject { public: /// @param query Query to use for highlighting QueryScorer(QueryPtr query); - + /// @param query Query to use for highlighting /// @param field Field to highlight - pass empty string to ignore fields QueryScorer(QueryPtr query, const String& field); - + /// @param query Query to use for highlighting /// @param reader {@link IndexReader} to use for quasi tf/idf scoring /// @param field Field to highlight - pass empty string to ignore fields QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field); - + /// @param query Query to use for highlighting /// @param reader {@link IndexReader} to use for quasi tf/idf scoring /// @param field Field to highlight - pass empty string to ignore fields /// @param defaultField QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field, const String& defaultField); - + /// @param query Query to use for highlighting /// @param field Field to highlight - pass empty string to ignore fields /// @param defaultField QueryScorer(QueryPtr query, const String& field, const String& defaultField); - + /// @param weightedTerms an array of pre-created {@link WeightedSpanTerm}s QueryScorer(Collection weightedTerms); - + virtual ~QueryScorer(); - + LUCENE_CLASS(QueryScorer); - + protected: double totalScore; HashSet foundTerms; @@ -63,31 +63,31 @@ namespace Lucene IndexReaderPtr reader; bool skipInitExtractor; bool wrapToCaching; - + protected: void init(QueryPtr query, const String& field, IndexReaderPtr reader, bool expandMultiTermQuery); TokenStreamPtr initExtractor(TokenStreamPtr tokenStream); - + public: virtual double getFragmentScore(); - + /// @return The highest weighted term (useful for passing to GradientFormatter to set top end of coloring scale). virtual double getMaxTermWeight(); - + virtual double getTokenScore(); virtual TokenStreamPtr init(TokenStreamPtr tokenStream); virtual WeightedSpanTermPtr getWeightedSpanTerm(const String& token); virtual void startFragment(TextFragmentPtr newFragment); - + /// @return true if multi-term queries should be expanded virtual bool isExpandMultiTermQuery(); - + /// Controls whether or not multi-term queries are expanded against a {@link MemoryIndex} {@link IndexReader}. /// @param expandMultiTermQuery true if multi-term queries should be expanded virtual void setExpandMultiTermQuery(bool expandMultiTermQuery); - - /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} are wrapped in a {@link - /// CachingTokenFilter} to ensure an efficient reset - if you are already using a different caching {@link + + /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} are wrapped in a {@link + /// CachingTokenFilter} to ensure an efficient reset - if you are already using a different caching {@link /// TokenStream} impl and you don't want it to be wrapped, set this to false. virtual void setWrapIfNotCachingTokenFilter(bool wrap); }; diff --git a/src/contrib/include/QueryTermExtractor.h b/src/contrib/include/QueryTermExtractor.h index 509ded3e..c298ff0a 100644 --- a/src/contrib/include/QueryTermExtractor.h +++ b/src/contrib/include/QueryTermExtractor.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,32 +12,32 @@ namespace Lucene { - /// Utility class used to extract the terms used in a query, plus any weights. This class will not - /// find terms for MultiTermQuery, TermRangeQuery and PrefixQuery classes so the caller must pass a - /// rewritten query (see Query.rewrite) to obtain a list of expanded terms. + /// Utility class used to extract the terms used in a query, plus any weights. This class will not + /// find terms for MultiTermQuery, TermRangeQuery and PrefixQuery classes so the caller must pass a + /// rewritten query (see Query.rewrite) to obtain a list of expanded terms. class LPPCONTRIBAPI QueryTermExtractor : public LuceneObject { public: virtual ~QueryTermExtractor(); LUCENE_CLASS(QueryTermExtractor); - + public: /// Extracts all terms texts of a given Query into an array of WeightedTerms /// /// @param query Query to extract term texts from. /// @return an array of the terms used in a query, plus their weights. static Collection getTerms(QueryPtr query); - + /// Extracts all terms texts of a given Query into an array of WeightedTerms /// /// @param query Query to extract term texts from. - /// @param reader used to compute IDF which can be used to + /// @param reader used to compute IDF which can be used to /// a) score selected fragments better /// b) use graded highlights eg changing intensity of font color /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based. /// @return an array of the terms used in a query, plus their weights. static Collection getIdfWeightedTerms(QueryPtr query, IndexReaderPtr reader, const String& fieldName); - + /// Extracts all terms texts of a given Query into an array of WeightedTerms /// /// @param query Query to extract term texts from. @@ -45,20 +45,20 @@ namespace Lucene /// @param fieldName The fieldName used to filter query terms. /// @return an array of the terms used in a query, plus their weights. static Collection getTerms(QueryPtr query, bool prohibited, const String& fieldName); - + /// Extracts all terms texts of a given Query into an array of WeightedTerms /// /// @param query Query to extract term texts from. /// @param prohibited true to extract "prohibited" terms, too. /// @return an array of the terms used in a query, plus their weights. static Collection getTerms(QueryPtr query, bool prohibited); - + static void getTerms(QueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName); - + protected: /// extractTerms is currently the only query-independent means of introspecting queries but it only reveals /// a list of terms for that query - not the boosts each individual term in that query may or may not have. - /// "Container" queries such as BooleanQuery should be unwrapped to get at the boost info held in each child + /// "Container" queries such as BooleanQuery should be unwrapped to get at the boost info held in each child /// element. static void getTermsFromBooleanQuery(BooleanQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName); static void getTermsFromFilteredQuery(FilteredQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName); diff --git a/src/contrib/include/QueryTermScorer.h b/src/contrib/include/QueryTermScorer.h index 99ee41f9..a56a143a 100644 --- a/src/contrib/include/QueryTermScorer.h +++ b/src/contrib/include/QueryTermScorer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,57 +12,57 @@ namespace Lucene { - /// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. - /// This class uses the {@link QueryTermExtractor} class to process determine the query terms and their + /// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. + /// This class uses the {@link QueryTermExtractor} class to process determine the query terms and their /// boosts to be used. class LPPCONTRIBAPI QueryTermScorer : public HighlighterScorer, public LuceneObject { public: - /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class + /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class /// and the searcher) QueryTermScorer(QueryPtr query); - - /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class + + /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class /// and the searcher) /// @param fieldName the Field name which is used to match Query terms QueryTermScorer(QueryPtr query, const String& fieldName); - - /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class + + /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class /// and the searcher) - /// @param reader used to compute IDF which can be used to - /// a) score selected fragments better + /// @param reader used to compute IDF which can be used to + /// a) score selected fragments better /// b) use graded highlights eg set font color intensity /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based QueryTermScorer(QueryPtr query, IndexReaderPtr reader, const String& fieldName); - + /// @param weightedTerms an array of pre-created {@link WeightedTerm}s QueryTermScorer(Collection weightedTerms); - + virtual ~QueryTermScorer(); - + LUCENE_CLASS(QueryTermScorer); - + public: TextFragmentPtr currentTextFragment; HashSet uniqueTermsInFragment; double totalScore; double maxTermWeight; - + protected: MapStringWeightedTerm termsToFind; TermAttributePtr termAtt; - + protected: void ConstructQueryTermScorer(Collection weightedTerms); - + public: virtual TokenStreamPtr init(TokenStreamPtr tokenStream); virtual void startFragment(TextFragmentPtr newFragment); virtual double getTokenScore(); virtual double getFragmentScore(); virtual void allFragmentsProcessed(); - + /// @return The highest weighted term (useful for passing to GradientFormatter to set top end of coloring scale. virtual double getMaxTermWeight(); }; diff --git a/src/contrib/include/ReverseStringFilter.h b/src/contrib/include/ReverseStringFilter.h index 64adaa24..33de5fed 100644 --- a/src/contrib/include/ReverseStringFilter.h +++ b/src/contrib/include/ReverseStringFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,46 +13,46 @@ namespace Lucene { /// Reverse token string, for example "country" => "yrtnuoc". /// - /// If marker is supplied, then tokens will be also prepended by that character. For example, with a - /// marker of \u0001, "country" => "\u0001yrtnuoc". This is useful when implementing efficient + /// If marker is supplied, then tokens will be also prepended by that character. For example, with a + /// marker of \u0001, "country" => "\u0001yrtnuoc". This is useful when implementing efficient /// leading wildcards search. class LPPCONTRIBAPI ReverseStringFilter : public TokenFilter { public: /// Create a new ReverseStringFilter that reverses all tokens in the supplied {@link TokenStream}. - /// - /// The reversed tokens will not be marked. + /// + /// The reversed tokens will not be marked. ReverseStringFilter(TokenStreamPtr input); - - /// Create a new ReverseStringFilter that reverses and marks all tokens in the supplied {@link + + /// Create a new ReverseStringFilter that reverses and marks all tokens in the supplied {@link /// TokenStream}. /// /// The reversed tokens will be prepended (marked) by the marker character. ReverseStringFilter(TokenStreamPtr input, wchar_t marker); - + virtual ~ReverseStringFilter(); - + LUCENE_CLASS(ReverseStringFilter); - + protected: TermAttributePtr termAtt; wchar_t marker; - + static const wchar_t NOMARKER; - + public: - /// Example marker character: U+0001 (START OF HEADING) + /// Example marker character: U+0001 (START OF HEADING) static const wchar_t START_OF_HEADING_MARKER; - + /// Example marker character: U+001F (INFORMATION SEPARATOR ONE) static const wchar_t INFORMATION_SEPARATOR_MARKER; - - /// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) + + /// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) static const wchar_t PUA_EC00_MARKER; - + /// Example marker character: U+200F (RIGHT-TO-LEFT MARK) static const wchar_t RTL_DIRECTION_MARKER; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/RussianAnalyzer.h b/src/contrib/include/RussianAnalyzer.h index f1b9c24e..d3d82612 100644 --- a/src/contrib/include/RussianAnalyzer.h +++ b/src/contrib/include/RussianAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// {@link Analyzer} for Russian language. + /// {@link Analyzer} for Russian language. /// /// Supports an external list of stopwords (words that will not be indexed at all). /// A default set of stopwords is used unless an alternative list is specified. @@ -21,46 +21,46 @@ namespace Lucene public: /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. RussianAnalyzer(LuceneVersion::Version matchVersion); - + /// Builds an analyzer with the given stop words. RussianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - + virtual ~RussianAnalyzer(); - + LUCENE_CLASS(RussianAnalyzer); - + protected: /// Contains the stopwords used with the {@link StopFilter}. HashSet stopSet; - + LuceneVersion::Version matchVersion; - + /// List of typical Russian stopwords. static const uint8_t DEFAULT_STOPWORD_FILE[]; - + public: /// Returns an unmodifiable instance of the default stop-words set. static const HashSet getDefaultStopSet(); - + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI RussianAnalyzerSavedStreams : public LuceneObject { public: virtual ~RussianAnalyzerSavedStreams(); - + LUCENE_CLASS(RussianAnalyzerSavedStreams); public: diff --git a/src/contrib/include/RussianLetterTokenizer.h b/src/contrib/include/RussianLetterTokenizer.h index 6241a0b3..1ac76e3f 100644 --- a/src/contrib/include/RussianLetterTokenizer.h +++ b/src/contrib/include/RussianLetterTokenizer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,24 +11,24 @@ namespace Lucene { - /// A RussianLetterTokenizer is a {@link Tokenizer} that extends {@link LetterTokenizer} by also - /// allowing the basic Latin digits 0-9. + /// A RussianLetterTokenizer is a {@link Tokenizer} that extends {@link LetterTokenizer} by also + /// allowing the basic Latin digits 0-9. class LPPCONTRIBAPI RussianLetterTokenizer : public CharTokenizer { public: /// Construct a new RussianLetterTokenizer. RussianLetterTokenizer(ReaderPtr input); - + /// Construct a new RussianLetterTokenizer using a given {@link AttributeSource}. RussianLetterTokenizer(AttributeSourcePtr source, ReaderPtr input); - + /// Construct a new RussianLetterTokenizer using a given {@link AttributeFactory}. RussianLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input); - + virtual ~RussianLetterTokenizer(); - + LUCENE_CLASS(RussianLetterTokenizer); - + public: /// Collects only characters which satisfy UnicodeUtil::isAlpha(c). virtual bool isTokenChar(wchar_t c); diff --git a/src/contrib/include/RussianLowerCaseFilter.h b/src/contrib/include/RussianLowerCaseFilter.h index aef8bdfe..06608a29 100644 --- a/src/contrib/include/RussianLowerCaseFilter.h +++ b/src/contrib/include/RussianLowerCaseFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,14 +17,14 @@ namespace Lucene { public: RussianLowerCaseFilter(TokenStreamPtr input); - + virtual ~RussianLowerCaseFilter(); - + LUCENE_CLASS(RussianLowerCaseFilter); - + protected: TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/RussianStemFilter.h b/src/contrib/include/RussianStemFilter.h index f29b909b..b2b4508b 100644 --- a/src/contrib/include/RussianStemFilter.h +++ b/src/contrib/include/RussianStemFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// A {@link TokenFilter} that stems Russian words. + /// A {@link TokenFilter} that stems Russian words. /// /// The implementation was inspired by GermanStemFilter. /// @@ -22,20 +22,20 @@ namespace Lucene { public: RussianStemFilter(TokenStreamPtr input); - + virtual ~RussianStemFilter(); - + LUCENE_CLASS(RussianStemFilter); - + protected: /// {@link RussianStemmer} in use by this filter. RussianStemmerPtr stemmer; - + TermAttributePtr termAtt; - + public: virtual bool incrementToken(); - + /// Set a alternative/custom {@link RussianStemmer} for this filter. void setStemmer(RussianStemmerPtr stemmer); }; diff --git a/src/contrib/include/RussianStemmer.h b/src/contrib/include/RussianStemmer.h index a92f5504..fef8e0ce 100644 --- a/src/contrib/include/RussianStemmer.h +++ b/src/contrib/include/RussianStemmer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,22 +12,22 @@ namespace Lucene { - /// Russian stemming algorithm implementation (see http://snowball.sourceforge.net for + /// Russian stemming algorithm implementation (see http://snowball.sourceforge.net for /// detailed description). class LPPCONTRIBAPI RussianStemmer : public LuceneObject { public: RussianStemmer(); virtual ~RussianStemmer(); - + LUCENE_CLASS(RussianStemmer); - + protected: /// positions of RV, R1 and R2 respectively int32_t RV; int32_t R1; int32_t R2; - + static const wchar_t A; static const wchar_t V; static const wchar_t G; @@ -49,10 +49,10 @@ namespace Lucene static const wchar_t AE; static const wchar_t IU; static const wchar_t IA; - + /// stem definitions static const wchar_t vowels[]; - + Collection perfectiveGerundEndings1(); Collection perfectiveGerund1Predessors(); Collection perfectiveGerundEndings2(); @@ -68,56 +68,56 @@ namespace Lucene Collection superlativeEndings(); Collection derivationalEndings(); Collection doubleN(); - + public: /// Finds the stem for given Russian word. String stem(const String& input); - + /// Static method for stemming. static String stemWord(const String& word); protected: /// Adjectival ending is an adjective ending, optionally preceded by participle ending. bool adjectival(String& stemmingZone); - + /// Derivational endings bool derivational(String& stemmingZone); - + /// Finds ending among given ending class and returns the length of ending found(0, if not found). int32_t findEnding(String& stemmingZone, int32_t startIndex, Collection theEndingClass); int32_t findEnding(String& stemmingZone, Collection theEndingClass); - + /// Finds the ending among the given class of endings and removes it from stemming zone. bool findAndRemoveEnding(String& stemmingZone, Collection theEndingClass); - + /// Finds the ending among the given class of endings, then checks if this ending was /// preceded by any of given predecessors, and if so, removes it from stemming zone. bool findAndRemoveEnding(String& stemmingZone, Collection theEndingClass, Collection thePredessors); - + /// Marks positions of RV, R1 and R2 in a given word. void markPositions(const String& word); - + /// Checks if character is a vowel. bool isVowel(wchar_t letter); - + /// Noun endings. bool noun(String& stemmingZone); - + /// Perfective gerund endings. bool perfectiveGerund(String& stemmingZone); - + /// Reflexive endings. bool reflexive(String& stemmingZone); - + bool removeI(String& stemmingZone); bool removeSoft(String& stemmingZone); - + /// Superlative endings. bool superlative(String& stemmingZone); - + /// Undoubles N. bool undoubleN(String& stemmingZone); - + /// Verb endings. bool verb(String& stemmingZone); }; diff --git a/src/contrib/include/SimpleFragmenter.h b/src/contrib/include/SimpleFragmenter.h index 6b7e4e1d..59b4fabe 100644 --- a/src/contrib/include/SimpleFragmenter.h +++ b/src/contrib/include/SimpleFragmenter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,31 +11,31 @@ namespace Lucene { - /// {@link Fragmenter} implementation which breaks text up into same-size fragments with + /// {@link Fragmenter} implementation which breaks text up into same-size fragments with /// no concerns over spotting sentence boundaries. class LPPCONTRIBAPI SimpleFragmenter : public Fragmenter, public LuceneObject { public: SimpleFragmenter(); SimpleFragmenter(int32_t fragmentSize); - + virtual ~SimpleFragmenter(); - + LUCENE_CLASS(SimpleFragmenter); - + protected: static const int32_t DEFAULT_FRAGMENT_SIZE; int32_t currentNumFrags; int32_t fragmentSize; OffsetAttributePtr offsetAtt; - + public: virtual void start(const String& originalText, TokenStreamPtr tokenStream); virtual bool isNewFragment(); - + /// @return size in number of characters of each fragment int32_t getFragmentSize(); - + /// @param size size in characters of each fragment void setFragmentSize(int32_t size); }; diff --git a/src/contrib/include/SimpleHTMLEncoder.h b/src/contrib/include/SimpleHTMLEncoder.h index 4b0fdc6b..c201a53e 100644 --- a/src/contrib/include/SimpleHTMLEncoder.h +++ b/src/contrib/include/SimpleHTMLEncoder.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,10 +17,10 @@ namespace Lucene public: virtual ~SimpleHTMLEncoder(); LUCENE_CLASS(SimpleHTMLEncoder); - + public: virtual String encodeText(const String& originalText); - + /// Encode string into HTML static String htmlEncode(const String& plainText); }; diff --git a/src/contrib/include/SimpleHTMLFormatter.h b/src/contrib/include/SimpleHTMLFormatter.h index cec23c5a..a342d70e 100644 --- a/src/contrib/include/SimpleHTMLFormatter.h +++ b/src/contrib/include/SimpleHTMLFormatter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,21 +16,21 @@ namespace Lucene { public: /// Default constructor uses HTML: <B> tags to markup terms. - SimpleHTMLFormatter(); - + SimpleHTMLFormatter(); + SimpleHTMLFormatter(const String& preTag, const String& postTag); - + virtual ~SimpleHTMLFormatter(); - + LUCENE_CLASS(SimpleHTMLFormatter); - + protected: static const String DEFAULT_PRE_TAG; static const String DEFAULT_POST_TAG; - + String preTag; String postTag; - + public: virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); }; diff --git a/src/contrib/include/SimpleSpanFragmenter.h b/src/contrib/include/SimpleSpanFragmenter.h index 018db4e4..02ec2ee3 100644 --- a/src/contrib/include/SimpleSpanFragmenter.h +++ b/src/contrib/include/SimpleSpanFragmenter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,25 +11,25 @@ namespace Lucene { - /// {@link Fragmenter} implementation which breaks text up into same-size fragments but + /// {@link Fragmenter} implementation which breaks text up into same-size fragments but /// does not split up {@link Spans}. This is a simple sample class. class LPPCONTRIBAPI SimpleSpanFragmenter : public Fragmenter, public LuceneObject { public: /// @param queryScorer QueryScorer that was used to score hits SimpleSpanFragmenter(QueryScorerPtr queryScorer); - + /// @param queryScorer QueryScorer that was used to score hits /// @param fragmentSize size in bytes of each fragment SimpleSpanFragmenter(QueryScorerPtr queryScorer, int32_t fragmentSize); - + virtual ~SimpleSpanFragmenter(); - + LUCENE_CLASS(SimpleSpanFragmenter); - + protected: static const int32_t DEFAULT_FRAGMENT_SIZE; - + int32_t fragmentSize; int32_t currentNumFrags; int32_t position; @@ -39,7 +39,7 @@ namespace Lucene TermAttributePtr termAtt; PositionIncrementAttributePtr posIncAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool isNewFragment(); virtual void start(const String& originalText, TokenStreamPtr tokenStream); diff --git a/src/contrib/include/SnowballAnalyzer.h b/src/contrib/include/SnowballAnalyzer.h index 2439cc6b..b703178b 100644 --- a/src/contrib/include/SnowballAnalyzer.h +++ b/src/contrib/include/SnowballAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { - /// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter}, {@link StopFilter} + /// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter}, {@link StopFilter} /// and {@link SnowballFilter}. /// /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. @@ -21,36 +21,36 @@ namespace Lucene public: /// Builds the named analyzer with no stop words. SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name); - + /// Builds an analyzer with the given stop words. SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name, HashSet stopwords); - + virtual ~SnowballAnalyzer(); - + LUCENE_CLASS(SnowballAnalyzer); - + protected: /// Contains the stopwords used with the StopFilter. HashSet stopSet; - - String name; + + String name; LuceneVersion::Version matchVersion; - + public: - /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter}, + /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter}, /// a {@link StopFilter} and a {@link SnowballFilter}. virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - - /// Returns a (possibly reused) {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link + + /// Returns a (possibly reused) {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link /// LowerCaseFilter}, a {@link StopFilter} and a {@link SnowballFilter}. virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); }; - + class LPPCONTRIBAPI SnowballAnalyzerSavedStreams : public LuceneObject { public: virtual ~SnowballAnalyzerSavedStreams(); - + LUCENE_CLASS(SnowballAnalyzerSavedStreams); public: diff --git a/src/contrib/include/SnowballFilter.h b/src/contrib/include/SnowballFilter.h index bfaf74a6..064f1394 100644 --- a/src/contrib/include/SnowballFilter.h +++ b/src/contrib/include/SnowballFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,14 +20,14 @@ namespace Lucene public: SnowballFilter(TokenStreamPtr input, const String& name); virtual ~SnowballFilter(); - + LUCENE_CLASS(SnowballFilter); - + protected: struct sb_stemmer* stemmer; UTF8ResultPtr utf8Result; TermAttributePtr termAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/SpanGradientFormatter.h b/src/contrib/include/SpanGradientFormatter.h index 3d93f680..32fdf1fd 100644 --- a/src/contrib/include/SpanGradientFormatter.h +++ b/src/contrib/include/SpanGradientFormatter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,8 +11,8 @@ namespace Lucene { - /// Formats text with different color intensity depending on the score of the term using the - /// span tag. GradientFormatter uses a bgcolor argument to the font tag which doesn't work + /// Formats text with different color intensity depending on the score of the term using the + /// span tag. GradientFormatter uses a bgcolor argument to the font tag which doesn't work /// in Mozilla, thus this class. /// @see GradientFormatter class LPPCONTRIBAPI SpanGradientFormatter : public GradientFormatter @@ -20,9 +20,9 @@ namespace Lucene public: SpanGradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor); virtual ~SpanGradientFormatter(); - + LUCENE_CLASS(SpanGradientFormatter); - + public: virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); }; diff --git a/src/contrib/include/TextFragment.h b/src/contrib/include/TextFragment.h index 9e94990e..875e5a1d 100644 --- a/src/contrib/include/TextFragment.h +++ b/src/contrib/include/TextFragment.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,43 +18,43 @@ namespace Lucene public: TextFragment(StringBufferPtr markedUpText, int32_t textStartPos, int32_t fragNum); virtual ~TextFragment(); - + LUCENE_CLASS(TextFragment); - + public: StringBufferPtr markedUpText; int32_t fragNum; int32_t textStartPos; int32_t textEndPos; double score; - + public: void setScore(double score); double getScore(); - + /// @param frag2 Fragment to be merged into this one void merge(TextFragmentPtr frag2); - + /// @return true if this fragment follows the one passed bool follows(TextFragmentPtr fragment); - + /// @return the fragment sequence number int32_t getFragNum(); - + /// Returns the marked-up text for this text fragment virtual String toString(); }; - + /// Utility class to store a string buffer that contains text fragment class LPPCONTRIBAPI StringBuffer : public LuceneObject { public: virtual ~StringBuffer(); LUCENE_CLASS(StringBuffer); - + protected: StringStream buffer; - + public: virtual String toString(); virtual int32_t length(); diff --git a/src/contrib/include/TokenGroup.h b/src/contrib/include/TokenGroup.h index 2302808d..52d533ad 100644 --- a/src/contrib/include/TokenGroup.h +++ b/src/contrib/include/TokenGroup.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,48 +18,48 @@ namespace Lucene public: TokenGroup(TokenStreamPtr tokenStream); virtual ~TokenGroup(); - + LUCENE_CLASS(TokenGroup); - + protected: static const int32_t MAX_NUM_TOKENS_PER_GROUP; - + OffsetAttributePtr offsetAtt; TermAttributePtr termAtt; - + public: Collection tokens; Collection scores; - + int32_t numTokens; int32_t startOffset; int32_t endOffset; double tot; int32_t matchStartOffset; int32_t matchEndOffset; - + public: void addToken(double score); bool isDistinct(); void clear(); - + /// @param index a value between 0 and numTokens -1 /// @return the "n"th token TokenPtr getToken(int32_t index); - + /// @param index a value between 0 and numTokens -1 /// @return the "n"th score double getScore(int32_t index); - + /// @return the end position in the original text int32_t getEndOffset(); - + /// @return the number of tokens in this group int32_t getNumTokens(); - + /// @return the start position in the original text int32_t getStartOffset(); - + /// @return all tokens' scores summed up double getTotalScore(); }; diff --git a/src/contrib/include/TokenSources.h b/src/contrib/include/TokenSources.h index ca5e019c..9970b85d 100644 --- a/src/contrib/include/TokenSources.h +++ b/src/contrib/include/TokenSources.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,17 +12,17 @@ namespace Lucene { - /// Hides implementation issues associated with obtaining a TokenStream for use with the highlighter - can obtain + /// Hides implementation issues associated with obtaining a TokenStream for use with the highlighter - can obtain /// from TermFreqVectors with offsets and (optionally) positions or from Analyzer class re-parsing the stored content. class LPPCONTRIBAPI TokenSources : public LuceneObject { public: virtual ~TokenSources(); LUCENE_CLASS(TokenSources); - + public: /// A convenience method that tries to first get a TermPositionVector for the specified docId, then, falls back to - /// using the passed in {@link Document} to retrieve the TokenStream. This is useful when you already have the + /// using the passed in {@link Document} to retrieve the TokenStream. This is useful when you already have the /// document, but would prefer to use the vector first. /// @param reader The {@link IndexReader} to use to try and get the vector from. /// @param docId The docId to retrieve. @@ -31,59 +31,59 @@ namespace Lucene /// @param analyzer The analyzer to use for creating the TokenStream if the vector doesn't exist. /// @return The {@link TokenStream} for the {@link Fieldable} on the {@link Document} static TokenStreamPtr getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, DocumentPtr doc, AnalyzerPtr analyzer); - - /// A convenience method that tries a number of approaches to getting a token stream. The cost of finding there - /// are no termVectors in the index is minimal (1000 invocations still registers 0 ms). So this "lazy" (flexible?) + + /// A convenience method that tries a number of approaches to getting a token stream. The cost of finding there + /// are no termVectors in the index is minimal (1000 invocations still registers 0 ms). So this "lazy" (flexible?) /// approach to coding is probably acceptable static TokenStreamPtr getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer); - + static TokenStreamPtr getTokenStream(TermPositionVectorPtr tpv); - + /// Low level api. - /// Returns a token stream or null if no offset info available in index. This can be used to feed the highlighter + /// Returns a token stream or null if no offset info available in index. This can be used to feed the highlighter /// with a pre-parsed token stream. /// /// In my tests the speeds to recreate 1000 token streams using this method are: /// - with TermVector offset only data stored - 420 milliseconds /// - with TermVector offset AND position data stored - 271 milliseconds - /// (nb timings for TermVector with position data are based on a tokenizer with contiguous positions - no overlaps - /// or gaps) The cost of not using TermPositionVector to store pre-parsed content and using an analyzer to re-parse - /// the original content: + /// (nb timings for TermVector with position data are based on a tokenizer with contiguous positions - no overlaps + /// or gaps) The cost of not using TermPositionVector to store pre-parsed content and using an analyzer to re-parse + /// the original content: /// - reanalyzing the original content - 980 milliseconds /// /// The re-analyze timings will typically vary depending on - /// 1) The complexity of the analyzer code (timings above were using a stemmer/lowercaser/stopword combo) - /// 2) The number of other fields (Lucene reads ALL fields off the disk when accessing just one document field - + /// 2) The number of other fields (Lucene reads ALL fields off the disk when accessing just one document field - /// can cost dear!) - /// 3) Use of compression on field storage - could be faster due to compression (less disk IO) or slower (more CPU + /// 3) Use of compression on field storage - could be faster due to compression (less disk IO) or slower (more CPU /// burn) depending on the content. /// /// @param tpv /// @param tokenPositionsGuaranteedContiguous true if the token position numbers have no overlaps or gaps. If looking /// to eek out the last drops of performance, set to true. If in doubt, set to false. static TokenStreamPtr getTokenStream(TermPositionVectorPtr tpv, bool tokenPositionsGuaranteedContiguous); - + static TokenStreamPtr getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field); static TokenStreamPtr getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer); static TokenStreamPtr getTokenStream(DocumentPtr doc, const String& field, AnalyzerPtr analyzer); static TokenStreamPtr getTokenStream(const String& field, const String& contents, AnalyzerPtr analyzer); }; - + /// an object used to iterate across an array of tokens class LPPCONTRIBAPI StoredTokenStream : public TokenStream { public: StoredTokenStream(Collection tokens); virtual ~StoredTokenStream(); - + LUCENE_CLASS(StoredTokenStream); - + public: Collection tokens; int32_t currentToken; TermAttributePtr termAtt; OffsetAttributePtr offsetAtt; - + public: virtual bool incrementToken(); }; diff --git a/src/contrib/include/WeightedSpanTerm.h b/src/contrib/include/WeightedSpanTerm.h index db0f4598..83c89d4b 100644 --- a/src/contrib/include/WeightedSpanTerm.h +++ b/src/contrib/include/WeightedSpanTerm.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,40 +17,40 @@ namespace Lucene public: WeightedSpanTerm(double weight, const String& term, bool positionSensitive = false); virtual ~WeightedSpanTerm(); - + LUCENE_CLASS(WeightedSpanTerm); - + public: bool positionSensitive; - + protected: Collection positionSpans; - + public: /// Checks to see if this term is valid at position. /// @param position To check against valid term positions. /// @return true if this term is a hit at this position. bool checkPosition(int32_t position); - + void addPositionSpans(Collection positionSpans); bool isPositionSensitive(); void setPositionSensitive(bool positionSensitive); Collection getPositionSpans(); }; - + /// Utility class to store a Span class LPPCONTRIBAPI PositionSpan : public LuceneObject { public: PositionSpan(int32_t start, int32_t end); virtual ~PositionSpan(); - + LUCENE_CLASS(PositionSpan); - + public: int32_t start; int32_t end; - }; + }; } #endif diff --git a/src/contrib/include/WeightedSpanTermExtractor.h b/src/contrib/include/WeightedSpanTermExtractor.h index 26b3e934..a41a5700 100644 --- a/src/contrib/include/WeightedSpanTermExtractor.h +++ b/src/contrib/include/WeightedSpanTermExtractor.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,16 +13,16 @@ namespace Lucene { - /// Class used to extract {@link WeightedSpanTerm}s from a {@link Query} based on whether {@link Term}s + /// Class used to extract {@link WeightedSpanTerm}s from a {@link Query} based on whether {@link Term}s /// from the {@link Query} are contained in a supplied {@link TokenStream}. class LPPCONTRIBAPI WeightedSpanTermExtractor : public LuceneObject { public: WeightedSpanTermExtractor(const String& defaultField = L""); virtual ~WeightedSpanTermExtractor(); - + LUCENE_CLASS(WeightedSpanTermExtractor); - + protected: String fieldName; TokenStreamPtr tokenStream; @@ -31,32 +31,32 @@ namespace Lucene bool expandMultiTermQuery; bool cachedTokenStream; bool wrapToCaching; - + protected: void closeReaders(); - + /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied Query. /// /// @param query Query to extract Terms from /// @param terms Map to place created WeightedSpanTerms in void extract(QueryPtr query, MapWeightedSpanTermPtr terms); - + /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied SpanQuery. /// /// @param terms Map to place created WeightedSpanTerms in. /// @param spanQuery SpanQuery to extract Terms from void extractWeightedSpanTerms(MapWeightedSpanTermPtr terms, SpanQueryPtr spanQuery); - + /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied Query. /// @param terms Map to place created WeightedSpanTerms in /// @param query Query to extract Terms from void extractWeightedTerms(MapWeightedSpanTermPtr terms, QueryPtr query); - + /// Necessary to implement matches for queries against defaultField bool fieldNameComparator(const String& fieldNameToCheck); - + IndexReaderPtr getReaderForField(const String& field); - + void collectSpanQueryFields(SpanQueryPtr spanQuery, HashSet fieldNames); bool mustRewriteQuery(SpanQueryPtr spanQuery); @@ -67,7 +67,7 @@ namespace Lucene /// @param tokenStream Of text to be highlighted /// @return Map containing WeightedSpanTerms MapWeightedSpanTermPtr getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream); - + /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. /// /// @param query That caused hit @@ -75,7 +75,7 @@ namespace Lucene /// @param fieldName Restricts Term's used based on field name /// @return Map containing WeightedSpanTerms MapWeightedSpanTermPtr getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName); - + /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. Uses a supplied /// IndexReader to properly weight terms (for gradient highlighting). /// @@ -85,47 +85,47 @@ namespace Lucene /// @param reader To use for scoring /// @return Map containing WeightedSpanTerms MapWeightedSpanTermPtr getWeightedSpanTermsWithScores(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName, IndexReaderPtr reader); - + bool getExpandMultiTermQuery(); void setExpandMultiTermQuery(bool expandMultiTermQuery); - + bool isCachedTokenStream(); TokenStreamPtr getTokenStream(); - - /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} - /// are wrapped in a {@link CachingTokenFilter} to ensure an efficient reset - if you - /// are already using a different caching {@link TokenStream} impl and you don't want + + /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} + /// are wrapped in a {@link CachingTokenFilter} to ensure an efficient reset - if you + /// are already using a different caching {@link TokenStream} impl and you don't want /// it to be wrapped, set this to false. void setWrapIfNotCachingTokenFilter(bool wrap); }; - - /// This class makes sure that if both position sensitive and insensitive versions of the same + + /// This class makes sure that if both position sensitive and insensitive versions of the same /// term are added, the position insensitive one wins. class LPPCONTRIBAPI PositionCheckingMap : public MapWeightedSpanTerm { public: virtual ~PositionCheckingMap(); LUCENE_CLASS(PositionCheckingMap); - + public: virtual void put(const String& key, WeightedSpanTermPtr val); }; - + /// A fake IndexReader class to extract the field from a MultiTermQuery class LPPCONTRIBAPI FakeReader : public FilterIndexReader { public: FakeReader(); virtual ~FakeReader(); - + LUCENE_CLASS(FakeReader); - + public: String field; - + protected: static IndexReaderPtr EMPTY_MEMORY_INDEX_READER(); - + public: virtual TermEnumPtr terms(TermPtr t); }; diff --git a/src/contrib/include/WeightedTerm.h b/src/contrib/include/WeightedTerm.h index 16d0818a..cc380181 100644 --- a/src/contrib/include/WeightedTerm.h +++ b/src/contrib/include/WeightedTerm.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,23 +18,23 @@ namespace Lucene public: WeightedTerm(double weight, const String& term); virtual ~WeightedTerm(); - + LUCENE_CLASS(WeightedTerm); - + public: double weight; // multiplier String term; // stemmed form - + public: /// @return the term value (stemmed) String getTerm(); - + /// @return the weight associated with this term double getWeight(); - + /// @param term the term value (stemmed) void setTerm(const String& term); - + /// @param weight the weight associated with this term void setWeight(double weight); }; diff --git a/src/contrib/memory/MemoryIndex.cpp b/src/contrib/memory/MemoryIndex.cpp index 01c2072d..6a6e4e97 100644 --- a/src/contrib/memory/MemoryIndex.cpp +++ b/src/contrib/memory/MemoryIndex.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,17 +26,17 @@ namespace Lucene { const double MemoryIndex::docBoost = 1.0; - + MemoryIndex::MemoryIndex(bool storeOffsets) { stride = storeOffsets ? 3 : 1; fields = MapStringMemoryIndexInfo::newInstance(); } - + MemoryIndex::~MemoryIndex() { } - + void MemoryIndex::addField(const String& fieldName, const String& text, AnalyzerPtr analyzer) { if (fieldName.empty()) @@ -45,11 +45,11 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"text must not be empty")); if (!analyzer) boost::throw_exception(IllegalArgumentException(L"analyzer must not be null")); - + TokenStreamPtr stream(analyzer->tokenStream(fieldName, newLucene(text))); addField(fieldName, stream); } - + void MemoryIndex::addField(const String& fieldName, TokenStreamPtr stream, double boost) { LuceneException finally; @@ -63,7 +63,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"boost factor must be greater than 0.0")); if (fields.contains(fieldName)) boost::throw_exception(IllegalArgumentException(L"field must not be added more than once")); - + MapStringIntCollection terms(MapStringIntCollection::newInstance()); int32_t numTokens = 0; int32_t numOverlapTokens = 0; @@ -72,7 +72,7 @@ namespace Lucene TermAttributePtr termAtt(stream->addAttribute()); PositionIncrementAttributePtr posIncrAttribute(stream->addAttribute()); OffsetAttributePtr offsetAtt(stream->addAttribute()); - + stream->reset(); while (stream->incrementToken()) { @@ -100,7 +100,7 @@ namespace Lucene } } stream->end(); - + // ensure infos.numTokens > 0 invariant; needed for correct operation of terms() if (numTokens > 0) { @@ -129,7 +129,7 @@ namespace Lucene } finally.throwException(); } - + IndexSearcherPtr MemoryIndex::createSearcher() { MemoryIndexReaderPtr reader(newLucene(shared_from_this())); @@ -137,12 +137,12 @@ namespace Lucene reader->setSearcher(searcher); // to later get hold of searcher.getSimilarity() return searcher; } - + double MemoryIndex::search(QueryPtr query) { if (!query) boost::throw_exception(IllegalArgumentException(L"query must not be null")); - + SearcherPtr searcher(createSearcher()); LuceneException finally; try @@ -164,12 +164,12 @@ namespace Lucene finally.throwException(); return 0; // silence static analyzers } - + int32_t MemoryIndex::numPositions(Collection positions) { return (positions.size() / stride); } - + struct lessField { inline bool operator()(const PairStringMemoryIndexInfo& first, const PairStringMemoryIndexInfo& second) const @@ -177,7 +177,7 @@ namespace Lucene return (first.first < second.first); } }; - + void MemoryIndex::sortFields() { if (!sortedFields) @@ -185,8 +185,8 @@ namespace Lucene sortedFields = CollectionStringMemoryIndexInfo::newInstance(fields.begin(), fields.end()); std::sort(sortedFields.begin(), sortedFields.end(), lessField()); } - } - + } + MemoryIndexInfo::MemoryIndexInfo(MapStringIntCollection terms, int32_t numTokens, int32_t numOverlapTokens, double boost) { this->terms = terms; @@ -194,11 +194,11 @@ namespace Lucene this->numOverlapTokens = numOverlapTokens; this->boost = boost; } - + MemoryIndexInfo::~MemoryIndexInfo() { } - + struct lessTerm { inline bool operator()(const PairStringIntCollection& first, const PairStringIntCollection& second) const @@ -206,7 +206,7 @@ namespace Lucene return (first.first < second.first); } }; - + void MemoryIndexInfo::sortTerms() { if (!sortedTerms) @@ -215,31 +215,31 @@ namespace Lucene std::sort(sortedTerms.begin(), sortedTerms.end(), lessTerm()); } } - + Collection MemoryIndexInfo::getPositions(const String& term) { return terms.get(term); } - + Collection MemoryIndexInfo::getPositions(int32_t pos) { return sortedTerms[pos].second; } - + double MemoryIndexInfo::getBoost() { return boost; } - + MemoryIndexReader::MemoryIndexReader(MemoryIndexPtr memoryIndex) { this->memoryIndex = memoryIndex; } - + MemoryIndexReader::~MemoryIndexReader() { } - + TermPtr MemoryIndexReader::MATCH_ALL_TERM() { static TermPtr _MATCH_ALL_TERM; @@ -250,17 +250,17 @@ namespace Lucene } return _MATCH_ALL_TERM; } - + MemoryIndexInfoPtr MemoryIndexReader::getInfo(const String& fieldName) { return memoryIndex->fields.get(fieldName); } - + MemoryIndexInfoPtr MemoryIndexReader::getInfo(int32_t pos) { return memoryIndex->sortedFields[pos].second; } - + int32_t MemoryIndexReader::docFreq(TermPtr t) { MemoryIndexInfoPtr info(getInfo(t->field())); @@ -269,17 +269,17 @@ namespace Lucene freq = info->getPositions(t->text()) ? 1 : 0; return freq; } - + TermEnumPtr MemoryIndexReader::terms() { return terms(MATCH_ALL_TERM()); } - + TermEnumPtr MemoryIndexReader::terms(TermPtr t) { int32_t i = 0; // index into info.sortedTerms int32_t j = 0; // index into sortedFields - + memoryIndex->sortFields(); if (memoryIndex->sortedFields.size() == 1 && memoryIndex->sortedFields[0].first == t->field()) j = 0; // fast path @@ -289,10 +289,10 @@ namespace Lucene int32_t keyPos = std::distance(memoryIndex->sortedFields.begin(), search); j = (search == memoryIndex->sortedFields.end() || t->field() < search->first) ? -(keyPos + 1) : keyPos; } - + if (j < 0) // not found; choose successor { - j = -j - 1; + j = -j - 1; i = 0; if (j < memoryIndex->sortedFields.size()) getInfo(j)->sortTerms(); @@ -316,20 +316,20 @@ namespace Lucene } } } - + return newLucene(shared_from_this(), i, j); } - + TermPositionsPtr MemoryIndexReader::termPositions() { return newLucene(shared_from_this()); } - + TermDocsPtr MemoryIndexReader::termDocs() { return termPositions(); } - + Collection MemoryIndexReader::getTermFreqVectors(int32_t docNumber) { Collection vectors(Collection::newInstance()); @@ -337,13 +337,13 @@ namespace Lucene vectors.add(getTermFreqVector(docNumber, fieldName->first)); return vectors; } - + void MemoryIndexReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) { for (MapStringMemoryIndexInfo::iterator fieldName = memoryIndex->fields.begin(); fieldName != memoryIndex->fields.end(); ++fieldName) getTermFreqVector(docNumber, fieldName->first, mapper); } - + void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) { MemoryIndexInfoPtr info(getInfo(field)); @@ -365,7 +365,7 @@ namespace Lucene mapper->map(info->sortedTerms[i].first, memoryIndex->numPositions(info->sortedTerms[i].second), offsets, info->sortedTerms[i].second); } } - + TermFreqVectorPtr MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field) { MemoryIndexInfoPtr info(getInfo(field)); @@ -374,7 +374,7 @@ namespace Lucene info->sortTerms(); return newLucene(shared_from_this(), info, field); } - + SimilarityPtr MemoryIndexReader::getSimilarity() { SearcherPtr searcher(_searcher.lock()); @@ -382,12 +382,12 @@ namespace Lucene return searcher->getSimilarity(); return Similarity::getDefault(); } - + void MemoryIndexReader::setSearcher(SearcherPtr searcher) { _searcher = searcher; } - + ByteArray MemoryIndexReader::norms(const String& field) { ByteArray norms(cachedNorms); @@ -411,66 +411,66 @@ namespace Lucene } return norms; } - + void MemoryIndexReader::norms(const String& field, ByteArray norms, int32_t offset) { ByteArray _norms(this->norms(field)); MiscUtils::arrayCopy(_norms.get(), 0, norms.get(), offset, _norms.size()); } - + void MemoryIndexReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { boost::throw_exception(UnsupportedOperationException()); } - + int32_t MemoryIndexReader::numDocs() { return memoryIndex->fields.empty() ? 0 : 1; } - + int32_t MemoryIndexReader::maxDoc() { - return 1; + return 1; } - + DocumentPtr MemoryIndexReader::document(int32_t n) { return newLucene(); // there are no stored fields } - + DocumentPtr MemoryIndexReader::document(int32_t n, FieldSelectorPtr fieldSelector) { return newLucene(); // there are no stored fields } - + bool MemoryIndexReader::isDeleted(int32_t n) { return false; } - + bool MemoryIndexReader::hasDeletions() { return false; } - + void MemoryIndexReader::doDelete(int32_t docNum) { boost::throw_exception(UnsupportedOperationException()); } - + void MemoryIndexReader::doUndeleteAll() { boost::throw_exception(UnsupportedOperationException()); } - + void MemoryIndexReader::doCommit(MapStringString commitUserData) { } - + void MemoryIndexReader::doClose() { } - + HashSet MemoryIndexReader::getFieldNames(FieldOption fieldOption) { static HashSet emptySet; @@ -489,18 +489,18 @@ namespace Lucene fieldSet.add(field->first); return fieldSet; } - + MemoryIndexTermEnum::MemoryIndexTermEnum(MemoryIndexReaderPtr reader, int32_t ix, int32_t jx) { _reader = reader; i = ix; j = jx; } - + MemoryIndexTermEnum::~MemoryIndexTermEnum() { } - + bool MemoryIndexTermEnum::next() { MemoryIndexReaderPtr reader(_reader); @@ -509,7 +509,7 @@ namespace Lucene MemoryIndexInfoPtr info(reader->getInfo(j)); if (++i < info->sortedTerms.size()) return true; - + // move to successor ++j; i = 0; @@ -518,7 +518,7 @@ namespace Lucene reader->getInfo(j)->sortTerms(); return true; } - + TermPtr MemoryIndexTermEnum::term() { MemoryIndexReaderPtr reader(_reader); @@ -529,7 +529,7 @@ namespace Lucene return TermPtr(); return createTerm(info, j, info->sortedTerms[i].first); } - + int32_t MemoryIndexTermEnum::docFreq() { MemoryIndexReaderPtr reader(_reader); @@ -540,11 +540,11 @@ namespace Lucene return 0; return reader->memoryIndex->numPositions(info->getPositions(i)); } - + void MemoryIndexTermEnum::close() { } - + TermPtr MemoryIndexTermEnum::createTerm(MemoryIndexInfoPtr info, int32_t pos, const String& text) { TermPtr _template(info->_template); @@ -557,46 +557,46 @@ namespace Lucene } return _template->createTerm(text); } - + MemoryIndexCollector::MemoryIndexCollector(Collection scores) { this->scores = scores; } - + MemoryIndexCollector::~MemoryIndexCollector() { } - + void MemoryIndexCollector::collect(int32_t doc) { scores[0] = scorer->score(); } - + void MemoryIndexCollector::setScorer(ScorerPtr scorer) { this->scorer = scorer; } - + bool MemoryIndexCollector::acceptsDocsOutOfOrder() { return true; } - + void MemoryIndexCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { } - + MemoryIndexTermPositions::MemoryIndexTermPositions(MemoryIndexReaderPtr reader) { _reader = reader; hasNext = false; cursor = 0; } - + MemoryIndexTermPositions::~MemoryIndexTermPositions() { } - + void MemoryIndexTermPositions::seek(TermPtr term) { this->term = term; @@ -611,31 +611,31 @@ namespace Lucene cursor = 0; } } - + void MemoryIndexTermPositions::seek(TermEnumPtr termEnum) { seek(termEnum->term()); } - + int32_t MemoryIndexTermPositions::doc() { return 0; } - + int32_t MemoryIndexTermPositions::freq() { MemoryIndexReaderPtr reader(_reader); int32_t freq = current ? reader->memoryIndex->numPositions(current) : (term ? 0 : 1); return freq; } - + bool MemoryIndexTermPositions::next() { bool _next = hasNext; hasNext = false; return _next; } - + int32_t MemoryIndexTermPositions::read(Collection docs, Collection freqs) { if (!hasNext) @@ -645,16 +645,16 @@ namespace Lucene freqs[0] = freq(); return 1; } - + bool MemoryIndexTermPositions::skipTo(int32_t target) { return next(); } - + void MemoryIndexTermPositions::close() { } - + int32_t MemoryIndexTermPositions::nextPosition() { // implements TermPositions @@ -663,44 +663,44 @@ namespace Lucene cursor += reader->memoryIndex->stride; return pos; } - + int32_t MemoryIndexTermPositions::getPayloadLength() { boost::throw_exception(UnsupportedOperationException()); } - + ByteArray MemoryIndexTermPositions::getPayload(ByteArray data, int32_t offset) { boost::throw_exception(UnsupportedOperationException()); return ByteArray(); } - + bool MemoryIndexTermPositions::isPayloadAvailable() { return false; // unsupported } - + MemoryIndexTermPositionVector::MemoryIndexTermPositionVector(MemoryIndexReaderPtr reader, MemoryIndexInfoPtr info, const String& fieldName) { this->_reader = reader; this->sortedTerms = info->sortedTerms; this->fieldName = fieldName; } - + MemoryIndexTermPositionVector::~MemoryIndexTermPositionVector() { } - + String MemoryIndexTermPositionVector::getField() { return fieldName; } - + int32_t MemoryIndexTermPositionVector::size() { return sortedTerms.size(); } - + Collection MemoryIndexTermPositionVector::getTerms() { Collection terms(Collection::newInstance(sortedTerms.size())); @@ -708,7 +708,7 @@ namespace Lucene terms[i] = sortedTerms[i].first; return terms; } - + Collection MemoryIndexTermPositionVector::getTermFrequencies() { MemoryIndexReaderPtr reader(_reader); @@ -717,13 +717,13 @@ namespace Lucene freqs[i] = reader->memoryIndex->numPositions(sortedTerms[i].second); return freqs; } - + int32_t MemoryIndexTermPositionVector::indexOf(const String& term) { CollectionStringIntCollection::iterator search = std::lower_bound(sortedTerms.begin(), sortedTerms.end(), std::make_pair(term, Collection()), lessTerm()); return (search == sortedTerms.end() || term < search->first) ? -1 : std::distance(sortedTerms.begin(), search); } - + Collection MemoryIndexTermPositionVector::indexesOf(Collection terms, int32_t start, int32_t length) { Collection indexes(Collection::newInstance(length)); @@ -731,18 +731,18 @@ namespace Lucene indexes[i] = indexOf(terms[start++]); return indexes; } - + Collection MemoryIndexTermPositionVector::getTermPositions(int32_t index) { return sortedTerms[index].second; } - + Collection MemoryIndexTermPositionVector::getOffsets(int32_t index) { MemoryIndexReaderPtr reader(_reader); if (reader->memoryIndex->stride == 1) return Collection(); // no offsets stored - + Collection positions(sortedTerms[index].second); int32_t size = positions.size(); Collection offsets(Collection::newInstance(size / reader->memoryIndex->stride)); diff --git a/src/contrib/msvc/ContribInc.cpp b/src/contrib/msvc/ContribInc.cpp index 4d3fe4b2..df166262 100644 --- a/src/contrib/msvc/ContribInc.cpp +++ b/src/contrib/msvc/ContribInc.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/contrib/msvc/dllmain.cpp b/src/contrib/msvc/dllmain.cpp index 480902b8..4373bf84 100644 --- a/src/contrib/msvc/dllmain.cpp +++ b/src/contrib/msvc/dllmain.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/contrib/snowball/SnowballAnalyzer.cpp b/src/contrib/snowball/SnowballAnalyzer.cpp index 56fdb1ad..a4ee9793 100644 --- a/src/contrib/snowball/SnowballAnalyzer.cpp +++ b/src/contrib/snowball/SnowballAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,18 +19,18 @@ namespace Lucene this->matchVersion = matchVersion; this->name = name; } - + SnowballAnalyzer::SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name, HashSet stopwords) { this->stopSet = stopwords; this->matchVersion = matchVersion; this->name = name; } - + SnowballAnalyzer::~SnowballAnalyzer() { } - + TokenStreamPtr SnowballAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { TokenStreamPtr result = newLucene(matchVersion, reader); @@ -41,7 +41,7 @@ namespace Lucene result = newLucene(result, name); return result; } - + TokenStreamPtr SnowballAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { SnowballAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -60,7 +60,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + SnowballAnalyzerSavedStreams::~SnowballAnalyzerSavedStreams() { } diff --git a/src/contrib/snowball/SnowballFilter.cpp b/src/contrib/snowball/SnowballFilter.cpp index 037b53e5..15252625 100644 --- a/src/contrib/snowball/SnowballFilter.cpp +++ b/src/contrib/snowball/SnowballFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,11 +22,11 @@ namespace Lucene termAtt = addAttribute(); utf8Result = newLucene(); } - + SnowballFilter::~SnowballFilter() { } - + bool SnowballFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/core/analysis/ASCIIFoldingFilter.cpp b/src/core/analysis/ASCIIFoldingFilter.cpp index c4c735c8..382805b6 100644 --- a/src/core/analysis/ASCIIFoldingFilter.cpp +++ b/src/core/analysis/ASCIIFoldingFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,18 +17,18 @@ namespace Lucene outputPos = 0; termAtt = addAttribute(); } - + ASCIIFoldingFilter::~ASCIIFoldingFilter() { } - + bool ASCIIFoldingFilter::incrementToken() { if (input->incrementToken()) { wchar_t* buffer = termAtt->termBufferArray(); int32_t length = termAtt->termLength(); - + // If no characters actually require rewriting then we just return token as-is for (int32_t i = 0; i < length; ++i) { @@ -45,21 +45,21 @@ namespace Lucene else return false; } - + void ASCIIFoldingFilter::foldToASCII(const wchar_t* input, int32_t length) { // Worst-case length required int32_t maxSizeNeeded = 4 * length; if (output.size() < maxSizeNeeded) output.resize(MiscUtils::getNextSize(maxSizeNeeded)); - + outputPos = 0; wchar_t* output = this->output.get(); - + for (int32_t pos = 0; pos < length; ++pos) { wchar_t c = input[pos]; - + // Quick test: if it's not in range then just keep current character if (c < 0x0080) output[outputPos++] = c; @@ -158,7 +158,7 @@ namespace Lucene output[outputPos++] = L'E'; break; case 0xA734: // [LATIN CAPITAL LETTER AO] - output[outputPos++] = L'A'; + output[outputPos++] = L'A'; output[outputPos++] = L'O'; break; case 0xA736: // [LATIN CAPITAL LETTER AU] @@ -232,7 +232,7 @@ namespace Lucene output[outputPos++] = L'b'; break; case 0x249D: // [PARENTHESIZED LATIN SMALL LETTER B] - output[outputPos++] = L'('; + output[outputPos++] = L'('; output[outputPos++] = L'b'; output[outputPos++] = L')'; break; diff --git a/src/core/analysis/Analyzer.cpp b/src/core/analysis/Analyzer.cpp index 8356783e..0e8a88c7 100644 --- a/src/core/analysis/Analyzer.cpp +++ b/src/core/analysis/Analyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,32 +13,32 @@ namespace Lucene Analyzer::~Analyzer() { } - + TokenStreamPtr Analyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { return tokenStream(fieldName, reader); } - + LuceneObjectPtr Analyzer::getPreviousTokenStream() { return tokenStreams.get(); } - + void Analyzer::setPreviousTokenStream(LuceneObjectPtr stream) { tokenStreams.set(stream); } - + int32_t Analyzer::getPositionIncrementGap(const String& fieldName) { return 0; } - + int32_t Analyzer::getOffsetGap(FieldablePtr field) { return field->isTokenized() ? 1 : 0; } - + void Analyzer::close() { tokenStreams.close(); diff --git a/src/core/analysis/BaseCharFilter.cpp b/src/core/analysis/BaseCharFilter.cpp index 31b87226..609b2556 100644 --- a/src/core/analysis/BaseCharFilter.cpp +++ b/src/core/analysis/BaseCharFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,23 +14,23 @@ namespace Lucene { size = 0; } - + BaseCharFilter::~BaseCharFilter() { } - + int32_t BaseCharFilter::correct(int32_t currentOff) { if (!offsets || currentOff < offsets[0]) return currentOff; - + int32_t hi = size - 1; if (currentOff >= offsets[hi]) return currentOff + diffs[hi]; - + int32_t lo = 0; int32_t mid = -1; - + while (hi >= lo) { mid = MiscUtils::unsignedShift(lo + hi, 1); @@ -41,18 +41,18 @@ namespace Lucene else return currentOff + diffs[mid]; } - + if (currentOff < offsets[mid]) return mid == 0 ? currentOff : currentOff + diffs[mid - 1]; else return currentOff + diffs[mid]; } - + int32_t BaseCharFilter::getLastCumulativeDiff() { return !offsets ? 0 : diffs[size - 1]; } - + void BaseCharFilter::addOffCorrectMap(int32_t off, int32_t cumulativeDiff) { if (!offsets) @@ -67,6 +67,6 @@ namespace Lucene } offsets[size] = off; - diffs[size++] = cumulativeDiff; + diffs[size++] = cumulativeDiff; } } diff --git a/src/core/analysis/CachingTokenFilter.cpp b/src/core/analysis/CachingTokenFilter.cpp index c5d42d01..ccfaac01 100644 --- a/src/core/analysis/CachingTokenFilter.cpp +++ b/src/core/analysis/CachingTokenFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,11 +12,11 @@ namespace Lucene CachingTokenFilter::CachingTokenFilter(TokenStreamPtr input) : TokenFilter(input) { } - + CachingTokenFilter::~CachingTokenFilter() { } - + bool CachingTokenFilter::incrementToken() { if (!cache) @@ -26,30 +26,30 @@ namespace Lucene fillCache(); iterator = cache.begin(); } - + if (iterator == cache.end()) { // the cache is exhausted, return false return false; } - + // Since the TokenFilter can be reset, the tokens need to be preserved as immutable. restoreState(*iterator++); return true; } - + void CachingTokenFilter::end() { if (finalState) restoreState(finalState); } - + void CachingTokenFilter::reset() { if (cache) iterator = cache.begin(); } - + void CachingTokenFilter::fillCache() { while (input->incrementToken()) diff --git a/src/core/analysis/CharArraySet.cpp b/src/core/analysis/CharArraySet.cpp index ccb07af1..33c88a44 100644 --- a/src/core/analysis/CharArraySet.cpp +++ b/src/core/analysis/CharArraySet.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene this->ignoreCase = ignoreCase; this->entries = HashSet::newInstance(); } - + CharArraySet::CharArraySet(HashSet entries, bool ignoreCase) { this->ignoreCase = ignoreCase; @@ -26,7 +26,7 @@ namespace Lucene add(*entry); } } - + CharArraySet::CharArraySet(Collection entries, bool ignoreCase) { this->ignoreCase = ignoreCase; @@ -37,46 +37,46 @@ namespace Lucene add(*entry); } } - + CharArraySet::~CharArraySet() { } - + bool CharArraySet::contains(const String& text) { return entries.contains(ignoreCase ? StringUtils::toLower(text) : text); } - + bool CharArraySet::contains(const wchar_t* text, int32_t offset, int32_t length) { return contains(String(text + offset, length)); } - + bool CharArraySet::add(const String& text) { return entries.add(ignoreCase ? StringUtils::toLower(text) : text); } - + bool CharArraySet::add(CharArray text) { return add(String(text.get(), text.size())); } - + int32_t CharArraySet::size() { return entries.size(); } - + bool CharArraySet::isEmpty() { return entries.empty(); } - + HashSet::iterator CharArraySet::begin() { return entries.begin(); } - + HashSet::iterator CharArraySet::end() { return entries.end(); diff --git a/src/core/analysis/CharFilter.cpp b/src/core/analysis/CharFilter.cpp index 8687f127..900316ac 100644 --- a/src/core/analysis/CharFilter.cpp +++ b/src/core/analysis/CharFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,41 +13,41 @@ namespace Lucene { input = in; } - + CharFilter::~CharFilter() { } - + int32_t CharFilter::correct(int32_t currentOff) { return currentOff; } - + int32_t CharFilter::correctOffset(int32_t currentOff) { return input->correctOffset(correct(currentOff)); } - + void CharFilter::close() { input->close(); } - + int32_t CharFilter::read(wchar_t* buffer, int32_t offset, int32_t length) { return input->read(buffer, offset, length); } - + bool CharFilter::markSupported() { return input->markSupported(); } - + void CharFilter::mark(int32_t readAheadLimit) { input->mark(readAheadLimit); } - + void CharFilter::reset() { input->reset(); diff --git a/src/core/analysis/CharReader.cpp b/src/core/analysis/CharReader.cpp index cf1fbded..c304e143 100644 --- a/src/core/analysis/CharReader.cpp +++ b/src/core/analysis/CharReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,43 +13,43 @@ namespace Lucene { input = in; } - + CharReader::~CharReader() { } - + CharStreamPtr CharReader::get(ReaderPtr input) { CharStreamPtr charStream(boost::dynamic_pointer_cast(input)); return charStream ? charStream : newLucene(input); } - + int32_t CharReader::correctOffset(int32_t currentOff) { return currentOff; } - + void CharReader::close() { if (input) input->close(); } - + int32_t CharReader::read(wchar_t* buffer, int32_t offset, int32_t length) { return input->read(buffer, offset, length); } - + bool CharReader::markSupported() { return input->markSupported(); } - + void CharReader::mark(int32_t readAheadLimit) { input->mark(readAheadLimit); } - + void CharReader::reset() { input->reset(); diff --git a/src/core/analysis/CharStream.cpp b/src/core/analysis/CharStream.cpp index 47b1b802..ecaeeec5 100644 --- a/src/core/analysis/CharStream.cpp +++ b/src/core/analysis/CharStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/analysis/CharTokenizer.cpp b/src/core/analysis/CharTokenizer.cpp index d7768134..c3941aef 100644 --- a/src/core/analysis/CharTokenizer.cpp +++ b/src/core/analysis/CharTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,49 +14,49 @@ namespace Lucene { const int32_t CharTokenizer::MAX_WORD_LEN = 255; const int32_t CharTokenizer::IO_BUFFER_SIZE = 4096; - + CharTokenizer::CharTokenizer(ReaderPtr input) : Tokenizer(input) { offset = 0; bufferIndex = 0; dataLen = 0; ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - + offsetAtt = addAttribute(); termAtt = addAttribute(); } - + CharTokenizer::CharTokenizer(AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source, input) { offset = 0; bufferIndex = 0; dataLen = 0; ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - + offsetAtt = addAttribute(); termAtt = addAttribute(); } - + CharTokenizer::CharTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory, input) { offset = 0; bufferIndex = 0; dataLen = 0; ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - + offsetAtt = addAttribute(); termAtt = addAttribute(); } - + CharTokenizer::~CharTokenizer() { } - + wchar_t CharTokenizer::normalize(wchar_t c) { return c; } - + bool CharTokenizer::incrementToken() { clearAttributes(); @@ -79,38 +79,38 @@ namespace Lucene } bufferIndex = 0; } - + wchar_t c = ioBuffer[bufferIndex++]; - + if (isTokenChar(c)) // if it's a token char { if (length == 0) start = offset + bufferIndex - 1; else if (length == buffer.size()) buffer = termAtt->resizeTermBuffer(1 + length); - + buffer[length++] = normalize(c); // buffer it, normalized - + if (length == MAX_WORD_LEN) // buffer overflow! break; } else if (length > 0) // at non-Letter with chars break; // return them } - + termAtt->setTermLength(length); offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); - + return true; } - + void CharTokenizer::end() { // set final offset int32_t finalOffset = correctOffset(offset); offsetAtt->setOffset(finalOffset, finalOffset); } - + void CharTokenizer::reset(ReaderPtr input) { Tokenizer::reset(input); diff --git a/src/core/analysis/ISOLatin1AccentFilter.cpp b/src/core/analysis/ISOLatin1AccentFilter.cpp index 8eea181b..fbdc8f50 100644 --- a/src/core/analysis/ISOLatin1AccentFilter.cpp +++ b/src/core/analysis/ISOLatin1AccentFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,18 +16,18 @@ namespace Lucene outputPos = 0; termAtt = addAttribute(); } - + ISOLatin1AccentFilter::~ISOLatin1AccentFilter() { } - + bool ISOLatin1AccentFilter::incrementToken() { if (input->incrementToken()) { wchar_t* buffer = termAtt->termBufferArray(); int32_t length = termAtt->termLength(); - + // If no characters actually require rewriting then we just return token as-is for (int32_t i = 0; i < length; ++i) { @@ -44,28 +44,28 @@ namespace Lucene else return false; } - + void ISOLatin1AccentFilter::removeAccents(const wchar_t* input, int32_t length) { // Worst-case length required int32_t maxSizeNeeded = 2 * length; - + int32_t size = output.size(); while (size < maxSizeNeeded) size *= 2; - + if (size != output.size()) output.resize(size); - + outputPos = 0; int32_t pos = 0; - + wchar_t* output = this->output.get(); - + for (int32_t i = 0; i < length; ++i, ++pos) { wchar_t c = input[pos]; - + // Quick test: if it's not in range then just keep current character if (c < 0x00C0 || c > 0xFB06) output[outputPos++] = c; diff --git a/src/core/analysis/KeywordAnalyzer.cpp b/src/core/analysis/KeywordAnalyzer.cpp index 61b8d7d9..4c83672a 100644 --- a/src/core/analysis/KeywordAnalyzer.cpp +++ b/src/core/analysis/KeywordAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,12 +13,12 @@ namespace Lucene KeywordAnalyzer::~KeywordAnalyzer() { } - + TokenStreamPtr KeywordAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(reader); } - + TokenStreamPtr KeywordAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); diff --git a/src/core/analysis/KeywordTokenizer.cpp b/src/core/analysis/KeywordTokenizer.cpp index b98189a1..81edc2ef 100644 --- a/src/core/analysis/KeywordTokenizer.cpp +++ b/src/core/analysis/KeywordTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,31 +13,31 @@ namespace Lucene { const int32_t KeywordTokenizer::DEFAULT_BUFFER_SIZE = 256; - + KeywordTokenizer::KeywordTokenizer(ReaderPtr input) : Tokenizer(input) { init(DEFAULT_BUFFER_SIZE); } - + KeywordTokenizer::KeywordTokenizer(ReaderPtr input, int32_t bufferSize) : Tokenizer(input) { init(bufferSize); } - + KeywordTokenizer::KeywordTokenizer(AttributeSourcePtr source, ReaderPtr input, int32_t bufferSize) : Tokenizer(source, input) { init(bufferSize); } - + KeywordTokenizer::KeywordTokenizer(AttributeFactoryPtr factory, ReaderPtr input, int32_t bufferSize) : Tokenizer(factory, input) { init(bufferSize); } - + KeywordTokenizer::~KeywordTokenizer() { } - + void KeywordTokenizer::init(int32_t bufferSize) { this->done = false; @@ -46,7 +46,7 @@ namespace Lucene this->offsetAtt = addAttribute(); this->termAtt->resizeTermBuffer(bufferSize); } - + bool KeywordTokenizer::incrementToken() { if (!done) @@ -71,13 +71,13 @@ namespace Lucene } return false; } - + void KeywordTokenizer::end() { // set final offset offsetAtt->setOffset(finalOffset, finalOffset); } - + void KeywordTokenizer::reset() { Tokenizer::reset(input); diff --git a/src/core/analysis/LengthFilter.cpp b/src/core/analysis/LengthFilter.cpp index 68d71c5b..827f58cc 100644 --- a/src/core/analysis/LengthFilter.cpp +++ b/src/core/analysis/LengthFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene this->max = max; this->termAtt = addAttribute(); } - + LengthFilter::~LengthFilter() { } - + bool LengthFilter::incrementToken() { // return the first non-stop word found diff --git a/src/core/analysis/LetterTokenizer.cpp b/src/core/analysis/LetterTokenizer.cpp index 0bf733f3..c66be70b 100644 --- a/src/core/analysis/LetterTokenizer.cpp +++ b/src/core/analysis/LetterTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,19 +14,19 @@ namespace Lucene LetterTokenizer::LetterTokenizer(ReaderPtr input) : CharTokenizer(input) { } - + LetterTokenizer::LetterTokenizer(AttributeSourcePtr source, ReaderPtr input) : CharTokenizer(source, input) { } - + LetterTokenizer::LetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : CharTokenizer(factory, input) { } - + LetterTokenizer::~LetterTokenizer() { } - + bool LetterTokenizer::isTokenChar(wchar_t c) { return UnicodeUtil::isAlpha(c); diff --git a/src/core/analysis/LowerCaseFilter.cpp b/src/core/analysis/LowerCaseFilter.cpp index c52de0bf..5dca0cbd 100644 --- a/src/core/analysis/LowerCaseFilter.cpp +++ b/src/core/analysis/LowerCaseFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,11 +15,11 @@ namespace Lucene { termAtt = addAttribute(); } - + LowerCaseFilter::~LowerCaseFilter() { } - + bool LowerCaseFilter::incrementToken() { if (input->incrementToken()) diff --git a/src/core/analysis/LowerCaseTokenizer.cpp b/src/core/analysis/LowerCaseTokenizer.cpp index 166cd0e2..efbdfb58 100644 --- a/src/core/analysis/LowerCaseTokenizer.cpp +++ b/src/core/analysis/LowerCaseTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,19 +13,19 @@ namespace Lucene LowerCaseTokenizer::LowerCaseTokenizer(ReaderPtr input) : LetterTokenizer(input) { } - + LowerCaseTokenizer::LowerCaseTokenizer(AttributeSourcePtr source, ReaderPtr input) : LetterTokenizer(source, input) { } - + LowerCaseTokenizer::LowerCaseTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : LetterTokenizer(factory, input) { } - + LowerCaseTokenizer::~LowerCaseTokenizer() { } - + wchar_t LowerCaseTokenizer::normalize(wchar_t c) { return CharFolder::toLower(c); diff --git a/src/core/analysis/MappingCharFilter.cpp b/src/core/analysis/MappingCharFilter.cpp index a6610a8b..a8f018ae 100644 --- a/src/core/analysis/MappingCharFilter.cpp +++ b/src/core/analysis/MappingCharFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,25 +17,25 @@ namespace Lucene this->charPointer = 0; this->nextCharCounter = 0; } - + MappingCharFilter::MappingCharFilter(NormalizeCharMapPtr normMap, ReaderPtr in) : BaseCharFilter(CharReader::get(in)) { this->normMap = normMap; this->charPointer = 0; this->nextCharCounter = 0; } - + MappingCharFilter::~MappingCharFilter() { } - + int32_t MappingCharFilter::read() { while (true) { if (charPointer < (int32_t)replacement.length()) return (int32_t)replacement[charPointer++]; - + int32_t firstChar = nextChar(); if (firstChar == -1) return -1; @@ -58,10 +58,10 @@ namespace Lucene else addOffCorrectMap(nextCharCounter - result->diff - prevCumulativeDiff, prevCumulativeDiff + result->diff); } - + } } - + int32_t MappingCharFilter::nextChar() { ++nextCharCounter; @@ -69,7 +69,7 @@ namespace Lucene return buffer.removeFirst(); return input->read(); } - + void MappingCharFilter::pushChar(int32_t c) { --nextCharCounter; @@ -77,14 +77,14 @@ namespace Lucene buffer = Collection::newInstance(); buffer.add(0, (wchar_t)c); } - + void MappingCharFilter::pushLastChar(int32_t c) { if (!buffer) buffer = Collection::newInstance(); buffer.add((wchar_t)c); } - + NormalizeCharMapPtr MappingCharFilter::match(NormalizeCharMapPtr map) { NormalizeCharMapPtr result; @@ -104,7 +104,7 @@ namespace Lucene result = map; return result; } - + int32_t MappingCharFilter::read(wchar_t* buffer, int32_t offset, int32_t length) { CharArray tmp(CharArray::newInstance(length)); diff --git a/src/core/analysis/NormalizeCharMap.cpp b/src/core/analysis/NormalizeCharMap.cpp index d0353ca5..ea2cd54c 100644 --- a/src/core/analysis/NormalizeCharMap.cpp +++ b/src/core/analysis/NormalizeCharMap.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,11 +13,11 @@ namespace Lucene { diff = 0; } - + NormalizeCharMap::~NormalizeCharMap() { } - + void NormalizeCharMap::add(const String& singleMatch, const String& replacement) { NormalizeCharMapPtr currMap(shared_from_this()); diff --git a/src/core/analysis/NumericTokenStream.cpp b/src/core/analysis/NumericTokenStream.cpp index 7524ca63..6d7f7f2b 100644 --- a/src/core/analysis/NumericTokenStream.cpp +++ b/src/core/analysis/NumericTokenStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,7 +23,7 @@ namespace Lucene this->posIncrAtt = addAttribute(); this->precisionStep = NumericUtils::PRECISION_STEP_DEFAULT; } - + NumericTokenStream::NumericTokenStream(int32_t precisionStep) { this->shift = 0; @@ -35,7 +35,7 @@ namespace Lucene if (precisionStep < 1) boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } - + NumericTokenStream::NumericTokenStream(AttributeSourcePtr source, int32_t precisionStep) : TokenStream(source) { this->shift = 0; @@ -47,7 +47,7 @@ namespace Lucene if (precisionStep < 1) boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } - + NumericTokenStream::NumericTokenStream(AttributeFactoryPtr factory, int32_t precisionStep) : TokenStream(factory) { this->shift = 0; @@ -59,23 +59,23 @@ namespace Lucene if (precisionStep < 1) boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } - + NumericTokenStream::~NumericTokenStream() { } - + const String& NumericTokenStream::TOKEN_TYPE_FULL_PREC() { static String _TOKEN_TYPE_FULL_PREC(L"fullPrecNumeric"); return _TOKEN_TYPE_FULL_PREC; } - + const String& NumericTokenStream::TOKEN_TYPE_LOWER_PREC() { static String _TOKEN_TYPE_LOWER_PREC(L"lowerPrecNumeric"); return _TOKEN_TYPE_LOWER_PREC; } - + NumericTokenStreamPtr NumericTokenStream::setLongValue(int64_t value) { this->value = value; @@ -83,7 +83,7 @@ namespace Lucene shift = 0; return shared_from_this(); } - + NumericTokenStreamPtr NumericTokenStream::setIntValue(int32_t value) { this->value = (int64_t)value; @@ -91,7 +91,7 @@ namespace Lucene shift = 0; return shared_from_this(); } - + NumericTokenStreamPtr NumericTokenStream::setDoubleValue(double value) { this->value = (int64_t)value; @@ -99,21 +99,21 @@ namespace Lucene shift = 0; return shared_from_this(); } - + void NumericTokenStream::reset() { if (valSize == 0) boost::throw_exception(IllegalStateException(L"call setValue() before usage")); shift = 0; } - + bool NumericTokenStream::incrementToken() { if (valSize == 0) boost::throw_exception(IllegalStateException(L"call setValue() before usage")); if (shift >= valSize) return false; - + clearAttributes(); CharArray buffer; switch (valSize) @@ -130,13 +130,13 @@ namespace Lucene // should not happen boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); } - + typeAtt->setType(shift == 0 ? TOKEN_TYPE_FULL_PREC() : TOKEN_TYPE_LOWER_PREC()); posIncrAtt->setPositionIncrement(shift == 0 ? 1 : 0); shift += precisionStep; return true; } - + String NumericTokenStream::toString() { StringStream buffer; diff --git a/src/core/analysis/PerFieldAnalyzerWrapper.cpp b/src/core/analysis/PerFieldAnalyzerWrapper.cpp index bc7859a0..414accd0 100644 --- a/src/core/analysis/PerFieldAnalyzerWrapper.cpp +++ b/src/core/analysis/PerFieldAnalyzerWrapper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene this->defaultAnalyzer = defaultAnalyzer; this->analyzerMap = MapStringAnalyzer::newInstance(); } - + PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(AnalyzerPtr defaultAnalyzer, MapStringAnalyzer fieldAnalyzers) { this->defaultAnalyzer = defaultAnalyzer; @@ -23,16 +23,16 @@ namespace Lucene if (fieldAnalyzers) analyzerMap.putAll(fieldAnalyzers.begin(), fieldAnalyzers.end()); } - + PerFieldAnalyzerWrapper::~PerFieldAnalyzerWrapper() { } - + void PerFieldAnalyzerWrapper::addAnalyzer(const String& fieldName, AnalyzerPtr analyzer) { analyzerMap.put(fieldName, analyzer); } - + TokenStreamPtr PerFieldAnalyzerWrapper::tokenStream(const String& fieldName, ReaderPtr reader) { AnalyzerPtr analyzer(analyzerMap.get(fieldName)); @@ -40,7 +40,7 @@ namespace Lucene analyzer = defaultAnalyzer; return analyzer->tokenStream(fieldName, reader); } - + TokenStreamPtr PerFieldAnalyzerWrapper::reusableTokenStream(const String& fieldName, ReaderPtr reader) { AnalyzerPtr analyzer(analyzerMap.get(fieldName)); @@ -48,7 +48,7 @@ namespace Lucene analyzer = defaultAnalyzer; return analyzer->reusableTokenStream(fieldName, reader); } - + int32_t PerFieldAnalyzerWrapper::getPositionIncrementGap(const String& fieldName) { AnalyzerPtr analyzer(analyzerMap.get(fieldName)); @@ -56,7 +56,7 @@ namespace Lucene analyzer = defaultAnalyzer; return analyzer->getPositionIncrementGap(fieldName); } - + int32_t PerFieldAnalyzerWrapper::getOffsetGap(FieldablePtr field) { AnalyzerPtr analyzer(analyzerMap.get(field->name())); @@ -64,7 +64,7 @@ namespace Lucene analyzer = defaultAnalyzer; return analyzer->getOffsetGap(field); } - + String PerFieldAnalyzerWrapper::toString() { return L"PerFieldAnalyzerWrapper(default=" + defaultAnalyzer->toString() + L")"; diff --git a/src/core/analysis/PorterStemFilter.cpp b/src/core/analysis/PorterStemFilter.cpp index 0d3dc412..17227264 100644 --- a/src/core/analysis/PorterStemFilter.cpp +++ b/src/core/analysis/PorterStemFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,16 +16,16 @@ namespace Lucene stemmer = newLucene(); termAtt = addAttribute(); } - + PorterStemFilter::~PorterStemFilter() { } - + bool PorterStemFilter::incrementToken() { if (!input->incrementToken()) return false; - + if (stemmer->stem(termAtt->termBuffer())) termAtt->setTermBuffer(stemmer->getResultBuffer(), 0, stemmer->getResultLength()); return true; diff --git a/src/core/analysis/PorterStemmer.cpp b/src/core/analysis/PorterStemmer.cpp index 6855f154..4170bddf 100644 --- a/src/core/analysis/PorterStemmer.cpp +++ b/src/core/analysis/PorterStemmer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,16 +17,16 @@ namespace Lucene i = 0; dirty = false; } - + PorterStemmer::~PorterStemmer() { } - + bool PorterStemmer::stem(CharArray word) { return stem(word.get(), word.size() - 1); } - + bool PorterStemmer::stem(wchar_t* b, int32_t k) { this->b = b; @@ -34,11 +34,11 @@ namespace Lucene this->j = 0; this->i = k; dirty = false; - + if (k <= 1) return false; // DEPARTURE - - // With these lines, strings of length 1 or 2 don't go through the stemming process, although no mention + + // With these lines, strings of length 1 or 2 don't go through the stemming process, although no mention // is made of this in the published algorithm. Remove the line to match the published algorithm. step1ab(); step1c(); @@ -46,22 +46,22 @@ namespace Lucene step3(); step4(); step5(); - + if (i != this->k) dirty = true; return dirty; } - + wchar_t* PorterStemmer::getResultBuffer() { return b; } - + int32_t PorterStemmer::getResultLength() { return k + 1; } - + bool PorterStemmer::cons(int32_t i) { switch (b[i]) @@ -78,7 +78,7 @@ namespace Lucene return true; } } - + int32_t PorterStemmer::m() { int32_t n = 0; @@ -115,7 +115,7 @@ namespace Lucene ++i; } } - + bool PorterStemmer::vowelinstem() { for (int32_t i = 0; i <= j; ++i) @@ -125,7 +125,7 @@ namespace Lucene } return false; } - + bool PorterStemmer::doublec(int32_t j) { if (j < 1) @@ -134,7 +134,7 @@ namespace Lucene return false; return cons(j); } - + bool PorterStemmer::cvc(int32_t i) { if (i < 2 || !cons(i) || cons(i - 1) || !cons(i - 2)) @@ -144,7 +144,7 @@ namespace Lucene return false; return true; } - + bool PorterStemmer::ends(const wchar_t* s) { int32_t length = s[0]; @@ -157,7 +157,7 @@ namespace Lucene j = k - length; return true; } - + void PorterStemmer::setto(const wchar_t* s) { int32_t length = s[0]; @@ -165,13 +165,13 @@ namespace Lucene k = j + length; dirty = true; } - + void PorterStemmer::r(const wchar_t* s) { if (m() > 0) setto(s); } - + void PorterStemmer::step1ab() { if (b[k] == L's') @@ -208,7 +208,7 @@ namespace Lucene setto(L"\01" L"e"); } } - + void PorterStemmer::step1c() { if (ends(L"\01" L"y") && vowelinstem()) @@ -217,7 +217,7 @@ namespace Lucene dirty = true; } } - + void PorterStemmer::step2() { if (k == 0) @@ -346,7 +346,7 @@ namespace Lucene } } } - + void PorterStemmer::step3() { switch (b[k]) @@ -396,7 +396,7 @@ namespace Lucene break; } } - + void PorterStemmer::step4() { if (k == 0) @@ -449,7 +449,7 @@ namespace Lucene break; return; case L't': - if (ends(L"\03" L"ate")) + if (ends(L"\03" L"ate")) break; if (ends(L"\03" L"iti")) break; @@ -472,7 +472,7 @@ namespace Lucene if (m() > 1) k = j; } - + void PorterStemmer::step5() { j = k; diff --git a/src/core/analysis/SimpleAnalyzer.cpp b/src/core/analysis/SimpleAnalyzer.cpp index a92cea42..4378aadb 100644 --- a/src/core/analysis/SimpleAnalyzer.cpp +++ b/src/core/analysis/SimpleAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,12 +13,12 @@ namespace Lucene SimpleAnalyzer::~SimpleAnalyzer() { } - + TokenStreamPtr SimpleAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(reader); } - + TokenStreamPtr SimpleAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); diff --git a/src/core/analysis/StopAnalyzer.cpp b/src/core/analysis/StopAnalyzer.cpp index c0bc7da6..401cba74 100644 --- a/src/core/analysis/StopAnalyzer.cpp +++ b/src/core/analysis/StopAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,42 +14,42 @@ namespace Lucene { - const wchar_t* StopAnalyzer::_ENGLISH_STOP_WORDS_SET[] = + const wchar_t* StopAnalyzer::_ENGLISH_STOP_WORDS_SET[] = { L"a", L"an", L"and", L"are", L"as", L"at", L"be", L"but", L"by", - L"for", L"if", L"in", L"into", L"is", L"it", L"no", L"not", L"of", - L"on", L"or", L"such", L"that", L"the", L"their", L"then", L"there", + L"for", L"if", L"in", L"into", L"is", L"it", L"no", L"not", L"of", + L"on", L"or", L"such", L"that", L"the", L"their", L"then", L"there", L"these", L"they", L"this", L"to", L"was", L"will", L"with" }; - + StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion) { stopWords = ENGLISH_STOP_WORDS_SET(); enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); } - + StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords) { this->stopWords = stopWords; enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); } - + StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, const String& stopwordsFile) { stopWords = WordlistLoader::getWordSet(stopwordsFile); enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); } - + StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords) { stopWords = WordlistLoader::getWordSet(stopwords); enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); } - + StopAnalyzer::~StopAnalyzer() { } - + const HashSet StopAnalyzer::ENGLISH_STOP_WORDS_SET() { static HashSet __ENGLISH_STOP_WORDS_SET; @@ -57,12 +57,12 @@ namespace Lucene __ENGLISH_STOP_WORDS_SET = HashSet::newInstance(_ENGLISH_STOP_WORDS_SET, _ENGLISH_STOP_WORDS_SET + SIZEOF_ARRAY(_ENGLISH_STOP_WORDS_SET)); return __ENGLISH_STOP_WORDS_SET; } - + TokenStreamPtr StopAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(enablePositionIncrements, newLucene(reader), stopWords); } - + TokenStreamPtr StopAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { StopAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); @@ -77,7 +77,7 @@ namespace Lucene streams->source->reset(reader); return streams->result; } - + StopAnalyzerSavedStreams::~StopAnalyzerSavedStreams() { } diff --git a/src/core/analysis/StopFilter.cpp b/src/core/analysis/StopFilter.cpp index 362ed7f9..f883ae47 100644 --- a/src/core/analysis/StopFilter.cpp +++ b/src/core/analysis/StopFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,7 +19,7 @@ namespace Lucene termAtt = addAttribute(); posIncrAtt = addAttribute(); } - + StopFilter::StopFilter(bool enablePositionIncrements, TokenStreamPtr input, CharArraySetPtr stopWords, bool ignoreCase) : TokenFilter(input) { this->stopWords = stopWords; @@ -27,16 +27,16 @@ namespace Lucene termAtt = addAttribute(); posIncrAtt = addAttribute(); } - + StopFilter::~StopFilter() { } - + HashSet StopFilter::makeStopSet(Collection stopWords) { return HashSet::newInstance(stopWords.begin(), stopWords.end()); } - + bool StopFilter::incrementToken() { // return the first non-stop word found @@ -54,17 +54,17 @@ namespace Lucene // reached EOS -- return false return false; } - + bool StopFilter::getEnablePositionIncrementsVersionDefault(LuceneVersion::Version matchVersion) { return LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_29); } - + bool StopFilter::getEnablePositionIncrements() { return enablePositionIncrements; } - + void StopFilter::setEnablePositionIncrements(bool enable) { this->enablePositionIncrements = enable; diff --git a/src/core/analysis/TeeSinkTokenFilter.cpp b/src/core/analysis/TeeSinkTokenFilter.cpp index 266863ba..17db6bc5 100644 --- a/src/core/analysis/TeeSinkTokenFilter.cpp +++ b/src/core/analysis/TeeSinkTokenFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene { this->sinks = Collection::newInstance(); } - + TeeSinkTokenFilter::~TeeSinkTokenFilter() { } - + SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream() { static SinkFilterPtr ACCEPT_ALL_FILTER; @@ -29,14 +29,14 @@ namespace Lucene } return newSinkTokenStream(ACCEPT_ALL_FILTER); } - + SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream(SinkFilterPtr filter) { SinkTokenStreamPtr sink(newLucene(this->cloneAttributes(), filter)); this->sinks.add(sink); return sink; } - + void TeeSinkTokenFilter::addSinkTokenStream(SinkTokenStreamPtr sink) { // check that sink has correct factory @@ -48,14 +48,14 @@ namespace Lucene sink->addAttribute((*it)->getClassName(), *it); this->sinks.add(sink); } - + void TeeSinkTokenFilter::consumeAllTokens() { while (incrementToken()) { } } - + bool TeeSinkTokenFilter::incrementToken() { if (input->incrementToken()) @@ -76,10 +76,10 @@ namespace Lucene } return true; } - + return false; } - + void TeeSinkTokenFilter::end() { TokenFilter::end(); @@ -90,25 +90,25 @@ namespace Lucene (*ref)->setFinalState(finalState); } } - + SinkFilter::~SinkFilter() { } - + void SinkFilter::reset() { // nothing to do; can be overridden } - + AcceptAllSinkFilter::~AcceptAllSinkFilter() { } - + bool AcceptAllSinkFilter::accept(AttributeSourcePtr source) { return true; } - + SinkTokenStream::SinkTokenStream(AttributeSourcePtr source, SinkFilterPtr filter) : TokenStream(source) { this->filter = filter; @@ -116,28 +116,28 @@ namespace Lucene this->it = cachedStates.begin(); this->initIterator = false; } - + SinkTokenStream::~SinkTokenStream() { } - + bool SinkTokenStream::accept(AttributeSourcePtr source) { return filter->accept(source); } - + void SinkTokenStream::addState(AttributeSourceStatePtr state) { if (initIterator) boost::throw_exception(IllegalStateException(L"The tee must be consumed before sinks are consumed.")); cachedStates.add(state); } - + void SinkTokenStream::setFinalState(AttributeSourceStatePtr finalState) { this->finalState = finalState; } - + bool SinkTokenStream::incrementToken() { // lazy init the iterator @@ -146,21 +146,21 @@ namespace Lucene it = cachedStates.begin(); initIterator = true; } - + if (it == cachedStates.end()) return false; - + AttributeSourceStatePtr state = *it++; restoreState(state); return true; } - + void SinkTokenStream::end() { if (finalState) restoreState(finalState); } - + void SinkTokenStream::reset() { it = cachedStates.begin(); diff --git a/src/core/analysis/Token.cpp b/src/core/analysis/Token.cpp index 46404ae3..12fb87fb 100644 --- a/src/core/analysis/Token.cpp +++ b/src/core/analysis/Token.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,55 +19,55 @@ namespace Lucene { const int32_t Token::MIN_BUFFER_SIZE = 10; - + Token::Token() { ConstructToken(0, 0, DEFAULT_TYPE(), 0); } - + Token::Token(int32_t start, int32_t end) { ConstructToken(start, end, DEFAULT_TYPE(), 0); } - + Token::Token(int32_t start, int32_t end, const String& type) { ConstructToken(start, end, type, 0); } - + Token::Token(int32_t start, int32_t end, int32_t flags) { ConstructToken(start, end, DEFAULT_TYPE(), flags); } - + Token::Token(const String& text, int32_t start, int32_t end) { ConstructToken(start, end, DEFAULT_TYPE(), 0); setTermBuffer(text); } - + Token::Token(const String& text, int32_t start, int32_t end, const String& type) { ConstructToken(start, end, type, 0); setTermBuffer(text); } - + Token::Token(const String& text, int32_t start, int32_t end, int32_t flags) { ConstructToken(start, end, DEFAULT_TYPE(), flags); setTermBuffer(text); } - + Token::Token(CharArray startTermBuffer, int32_t termBufferOffset, int32_t termBufferLength, int32_t start, int32_t end) { ConstructToken(start, end, DEFAULT_TYPE(), 0); setTermBuffer(startTermBuffer.get(), termBufferOffset, termBufferLength); } - + Token::~Token() { } - + void Token::ConstructToken(int32_t start, int32_t end, const String& type, int32_t flags) { this->_termLength = 0; @@ -77,38 +77,38 @@ namespace Lucene this->flags = flags; this->positionIncrement = 1; } - + const String& Token::DEFAULT_TYPE() { static String _DEFAULT_TYPE(L"word"); return _DEFAULT_TYPE; } - + void Token::setPositionIncrement(int32_t positionIncrement) { if (positionIncrement < 0) boost::throw_exception(IllegalArgumentException(L"Increment must be zero or greater: " + StringUtils::toString(positionIncrement))); this->positionIncrement = positionIncrement; } - + int32_t Token::getPositionIncrement() { return positionIncrement; } - + String Token::term() { initTermBuffer(); return String(_termBuffer.get(), _termLength); } - + void Token::setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length) { growTermBuffer(length); MiscUtils::arrayCopy(buffer, offset, _termBuffer.get(), 0, length); _termLength = length; } - + void Token::setTermBuffer(const String& buffer) { int32_t length = (int32_t)buffer.size(); @@ -116,7 +116,7 @@ namespace Lucene MiscUtils::arrayCopy(buffer.begin(), 0, _termBuffer.get(), 0, length); _termLength = length; } - + void Token::setTermBuffer(const String& buffer, int32_t offset, int32_t length) { BOOST_ASSERT(offset <= (int32_t)buffer.length()); @@ -125,21 +125,21 @@ namespace Lucene MiscUtils::arrayCopy(buffer.begin(), offset, _termBuffer.get(), 0, length); _termLength = length; } - + CharArray Token::termBuffer() { if (!_termBuffer) initTermBuffer(); return _termBuffer; } - + wchar_t* Token::termBufferArray() { if (!_termBuffer) initTermBuffer(); return _termBuffer.get(); } - + CharArray Token::resizeTermBuffer(int32_t newSize) { if (!_termBuffer) @@ -157,12 +157,12 @@ namespace Lucene } return _termBuffer; } - + void Token::growTermBuffer(int32_t newSize) { _termBuffer = resizeTermBuffer(newSize); } - + void Token::initTermBuffer() { if (!_termBuffer) @@ -171,82 +171,82 @@ namespace Lucene _termLength = 0; } } - + int32_t Token::termLength() { if (!_termBuffer) initTermBuffer(); return _termLength; } - + void Token::setTermLength(int32_t length) { initTermBuffer(); if (length > _termBuffer.size()) { - boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + - L" exceeds the size of the termBuffer (" + + boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + + L" exceeds the size of the termBuffer (" + StringUtils::toString(_termBuffer.size()) + L")")); } _termLength = length; } - + int32_t Token::startOffset() { return _startOffset; } - + void Token::setStartOffset(int32_t offset) { this->_startOffset = offset; } - + int32_t Token::endOffset() { return _endOffset; } - + void Token::setEndOffset(int32_t offset) { this->_endOffset = offset; } - + void Token::setOffset(int32_t startOffset, int32_t endOffset) { this->_startOffset = startOffset; this->_endOffset = endOffset; } - + String Token::type() { return _type; } - + void Token::setType(const String& type) { this->_type = type; } - + int32_t Token::getFlags() { return flags; } - + void Token::setFlags(int32_t flags) { this->flags = flags; } - + PayloadPtr Token::getPayload() { return this->payload; } - + void Token::setPayload(PayloadPtr payload) { this->payload = payload; } - + String Token::toString() { StringStream buffer; @@ -263,7 +263,7 @@ namespace Lucene buffer << L")"; return buffer.str(); } - + void Token::clear() { payload.reset(); @@ -275,7 +275,7 @@ namespace Lucene _endOffset = 0; _type = DEFAULT_TYPE(); } - + LuceneObjectPtr Token::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); @@ -286,7 +286,7 @@ namespace Lucene cloneToken->_type = _type; cloneToken->flags = flags; cloneToken->positionIncrement = positionIncrement; - + // Do a deep clone if (_termBuffer) { @@ -295,10 +295,10 @@ namespace Lucene } if (payload) cloneToken->payload = boost::dynamic_pointer_cast(payload->clone()); - + return cloneToken; } - + TokenPtr Token::clone(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) { TokenPtr clone(newLucene(newTermBuffer, newTermOffset, newTermLength, newStartOffset, newEndOffset)); @@ -309,18 +309,18 @@ namespace Lucene clone->payload = boost::dynamic_pointer_cast(payload->clone()); return clone; } - + bool Token::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + TokenPtr otherToken(boost::dynamic_pointer_cast(other)); if (otherToken) { initTermBuffer(); otherToken->initTermBuffer(); - + if (_termLength == otherToken->_termLength && _startOffset == otherToken->_startOffset && _endOffset == otherToken->_endOffset && flags == otherToken->flags && positionIncrement == otherToken->positionIncrement && _type == otherToken->_type && @@ -339,7 +339,7 @@ namespace Lucene else return false; } - + int32_t Token::hashCode() { initTermBuffer(); @@ -353,7 +353,7 @@ namespace Lucene code = code * 31 + MiscUtils::hashCode(_termBuffer.get(), 0, _termLength); return code; } - + void Token::clearNoTermBuffer() { payload.reset(); @@ -363,7 +363,7 @@ namespace Lucene _endOffset = 0; _type = DEFAULT_TYPE(); } - + TokenPtr Token::reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType) { clearNoTermBuffer(); @@ -375,7 +375,7 @@ namespace Lucene _type = newType; return shared_from_this(); } - + TokenPtr Token::reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) { clearNoTermBuffer(); @@ -385,7 +385,7 @@ namespace Lucene _type = DEFAULT_TYPE(); return shared_from_this(); } - + TokenPtr Token::reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset, const String& newType) { clearNoTermBuffer(); @@ -395,7 +395,7 @@ namespace Lucene _type = newType; return shared_from_this(); } - + TokenPtr Token::reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType) { clearNoTermBuffer(); @@ -405,7 +405,7 @@ namespace Lucene _type = newType; return shared_from_this(); } - + TokenPtr Token::reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset) { clearNoTermBuffer(); @@ -415,7 +415,7 @@ namespace Lucene _type = DEFAULT_TYPE(); return shared_from_this(); } - + TokenPtr Token::reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) { clearNoTermBuffer(); @@ -425,7 +425,7 @@ namespace Lucene _type = DEFAULT_TYPE(); return shared_from_this(); } - + void Token::reinit(TokenPtr prototype) { prototype->initTermBuffer(); @@ -437,7 +437,7 @@ namespace Lucene _type = prototype->_type; payload = prototype->payload; } - + void Token::reinit(TokenPtr prototype, const String& newTerm) { setTermBuffer(newTerm); @@ -448,7 +448,7 @@ namespace Lucene _type = prototype->_type; payload = prototype->payload; } - + void Token::reinit(TokenPtr prototype, CharArray newTermBuffer, int32_t offset, int32_t length) { setTermBuffer(newTermBuffer.get(), offset, length); @@ -459,7 +459,7 @@ namespace Lucene _type = prototype->_type; payload = prototype->payload; } - + void Token::copyTo(AttributePtr target) { TokenPtr targetToken(boost::dynamic_pointer_cast(target)); @@ -493,7 +493,7 @@ namespace Lucene targetTypeAttribute->setType(_type); } } - + AttributeFactoryPtr Token::TOKEN_ATTRIBUTE_FACTORY() { static AttributeFactoryPtr _TOKEN_ATTRIBUTE_FACTORY; @@ -504,32 +504,32 @@ namespace Lucene } return _TOKEN_ATTRIBUTE_FACTORY; } - + TokenAttributeFactory::TokenAttributeFactory(AttributeFactoryPtr delegate) { this->delegate = delegate; } - + TokenAttributeFactory::~TokenAttributeFactory() { } - + AttributePtr TokenAttributeFactory::createAttributeInstance(const String& className) { return newLucene(); } - + bool TokenAttributeFactory::equals(LuceneObjectPtr other) { if (AttributeFactory::equals(other)) return true; - + TokenAttributeFactoryPtr otherTokenAttributeFactory(boost::dynamic_pointer_cast(other)); if (otherTokenAttributeFactory) return this->delegate->equals(otherTokenAttributeFactory->delegate); return false; } - + int32_t TokenAttributeFactory::hashCode() { return (delegate->hashCode() ^ 0x0a45aa31); diff --git a/src/core/analysis/TokenFilter.cpp b/src/core/analysis/TokenFilter.cpp index 563931c5..2f9d8f96 100644 --- a/src/core/analysis/TokenFilter.cpp +++ b/src/core/analysis/TokenFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,21 +13,21 @@ namespace Lucene { this->input = input; } - + TokenFilter::~TokenFilter() { } - + void TokenFilter::end() { input->end(); } - + void TokenFilter::close() { input->close(); } - + void TokenFilter::reset() { input->reset(); diff --git a/src/core/analysis/TokenStream.cpp b/src/core/analysis/TokenStream.cpp index 67f8d001..45190b64 100644 --- a/src/core/analysis/TokenStream.cpp +++ b/src/core/analysis/TokenStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,28 +12,28 @@ namespace Lucene TokenStream::TokenStream() { } - + TokenStream::TokenStream(AttributeSourcePtr input) : AttributeSource(input) { } - + TokenStream::TokenStream(AttributeFactoryPtr factory) : AttributeSource(factory) { } - + TokenStream::~TokenStream() { } - + void TokenStream::end() { // do nothing by default } - + void TokenStream::reset() { } - + void TokenStream::close() { } diff --git a/src/core/analysis/Tokenizer.cpp b/src/core/analysis/Tokenizer.cpp index d777a010..a1c12d55 100644 --- a/src/core/analysis/Tokenizer.cpp +++ b/src/core/analysis/Tokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,37 +13,37 @@ namespace Lucene Tokenizer::Tokenizer() { } - + Tokenizer::Tokenizer(ReaderPtr input) { this->input = CharReader::get(input); this->charStream = boost::dynamic_pointer_cast(this->input); } - + Tokenizer::Tokenizer(AttributeFactoryPtr factory) : TokenStream(factory) { } - + Tokenizer::Tokenizer(AttributeFactoryPtr factory, ReaderPtr input) : TokenStream(factory) { this->input = CharReader::get(input); this->charStream = boost::dynamic_pointer_cast(this->input); } - + Tokenizer::Tokenizer(AttributeSourcePtr source) : TokenStream(source) { } - + Tokenizer::Tokenizer(AttributeSourcePtr source, ReaderPtr input) : TokenStream(source) { this->input = CharReader::get(input); this->charStream = boost::dynamic_pointer_cast(this->input); } - + Tokenizer::~Tokenizer() { } - + void Tokenizer::close() { if (input) @@ -52,12 +52,12 @@ namespace Lucene input.reset(); // don't hold onto Reader after close } } - + int32_t Tokenizer::correctOffset(int32_t currentOff) { return charStream ? charStream->correctOffset(currentOff) : currentOff; } - + void Tokenizer::reset(ReaderPtr input) { this->input = input; diff --git a/src/core/analysis/WhitespaceAnalyzer.cpp b/src/core/analysis/WhitespaceAnalyzer.cpp index dc21a04f..be79ccde 100644 --- a/src/core/analysis/WhitespaceAnalyzer.cpp +++ b/src/core/analysis/WhitespaceAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,12 +13,12 @@ namespace Lucene WhitespaceAnalyzer::~WhitespaceAnalyzer() { } - + TokenStreamPtr WhitespaceAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { return newLucene(reader); } - + TokenStreamPtr WhitespaceAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); diff --git a/src/core/analysis/WhitespaceTokenizer.cpp b/src/core/analysis/WhitespaceTokenizer.cpp index 885e3adb..04a36689 100644 --- a/src/core/analysis/WhitespaceTokenizer.cpp +++ b/src/core/analysis/WhitespaceTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,19 +14,19 @@ namespace Lucene WhitespaceTokenizer::WhitespaceTokenizer(ReaderPtr input) : CharTokenizer(input) { } - + WhitespaceTokenizer::WhitespaceTokenizer(AttributeSourcePtr source, ReaderPtr input) : CharTokenizer(source, input) { } - + WhitespaceTokenizer::WhitespaceTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : CharTokenizer(factory, input) { } - + WhitespaceTokenizer::~WhitespaceTokenizer() { } - + bool WhitespaceTokenizer::isTokenChar(wchar_t c) { return !UnicodeUtil::isSpace(c); diff --git a/src/core/analysis/WordlistLoader.cpp b/src/core/analysis/WordlistLoader.cpp index a2530950..6beb49c1 100644 --- a/src/core/analysis/WordlistLoader.cpp +++ b/src/core/analysis/WordlistLoader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene WordlistLoader::~WordlistLoader() { } - + HashSet WordlistLoader::getWordSet(const String& wordfile, const String& comment) { HashSet result(HashSet::newInstance()); @@ -35,7 +35,7 @@ namespace Lucene finally.throwException(); return result; } - + HashSet WordlistLoader::getWordSet(ReaderPtr reader, const String& comment) { HashSet result(HashSet::newInstance()); @@ -64,7 +64,7 @@ namespace Lucene finally.throwException(); return result; } - + MapStringString WordlistLoader::getStemDict(const String& wordstemfile) { MapStringString result(MapStringString::newInstance()); diff --git a/src/core/analysis/standard/StandardAnalyzer.cpp b/src/core/analysis/standard/StandardAnalyzer.cpp index 738a544b..4be8873a 100644 --- a/src/core/analysis/standard/StandardAnalyzer.cpp +++ b/src/core/analysis/standard/StandardAnalyzer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,31 +18,31 @@ namespace Lucene { /// Construct an analyzer with the given stop words. const int32_t StandardAnalyzer::DEFAULT_MAX_TOKEN_LENGTH = 255; - + StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion) { ConstructAnalyser(matchVersion, StopAnalyzer::ENGLISH_STOP_WORDS_SET()); } - + StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords) { ConstructAnalyser(matchVersion, stopWords); } - + StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, const String& stopwords) { ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); } - + StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords) { ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); } - + StandardAnalyzer::~StandardAnalyzer() { } - + void StandardAnalyzer::ConstructAnalyser(LuceneVersion::Version matchVersion, HashSet stopWords) { stopSet = stopWords; @@ -51,7 +51,7 @@ namespace Lucene this->matchVersion = matchVersion; this->maxTokenLength = DEFAULT_MAX_TOKEN_LENGTH; } - + TokenStreamPtr StandardAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) { StandardTokenizerPtr tokenStream(newLucene(matchVersion, reader)); @@ -61,17 +61,17 @@ namespace Lucene result = newLucene(enableStopPositionIncrements, result, stopSet); return result; } - + void StandardAnalyzer::setMaxTokenLength(int32_t length) { maxTokenLength = length; } - + int32_t StandardAnalyzer::getMaxTokenLength() { return maxTokenLength; } - + TokenStreamPtr StandardAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) { StandardAnalyzerSavedStreamsPtr streams = boost::dynamic_pointer_cast(getPreviousTokenStream()); @@ -87,12 +87,12 @@ namespace Lucene else streams->tokenStream->reset(reader); streams->tokenStream->setMaxTokenLength(maxTokenLength); - + streams->tokenStream->setReplaceInvalidAcronym(replaceInvalidAcronym); - + return streams->filteredTokenStream; } - + StandardAnalyzerSavedStreams::~StandardAnalyzerSavedStreams() { } diff --git a/src/core/analysis/standard/StandardFilter.cpp b/src/core/analysis/standard/StandardFilter.cpp index 80b2474a..772c3245 100644 --- a/src/core/analysis/standard/StandardFilter.cpp +++ b/src/core/analysis/standard/StandardFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,11 +17,11 @@ namespace Lucene termAtt = addAttribute(); typeAtt = addAttribute(); } - + StandardFilter::~StandardFilter() { } - + const String& StandardFilter::APOSTROPHE_TYPE() { static String _APOSTROPHE_TYPE; @@ -29,7 +29,7 @@ namespace Lucene _APOSTROPHE_TYPE = StandardTokenizer::TOKEN_TYPES()[StandardTokenizer::APOSTROPHE]; return _APOSTROPHE_TYPE; } - + const String& StandardFilter::ACRONYM_TYPE() { static String _ACRONYM_TYPE; @@ -37,16 +37,16 @@ namespace Lucene _ACRONYM_TYPE = StandardTokenizer::TOKEN_TYPES()[StandardTokenizer::ACRONYM]; return _ACRONYM_TYPE; } - + bool StandardFilter::incrementToken() { if (!input->incrementToken()) return false; - + wchar_t* termBuffer = termAtt->termBufferArray(); int32_t bufferLength = termAtt->termLength(); String type(typeAtt->type()); - + if (type == APOSTROPHE_TYPE() && bufferLength >= 2 && termBuffer[bufferLength - 2] == L'\'' && (termBuffer[bufferLength - 1] == L's' || termBuffer[bufferLength - 1] == L'S')) // remove 's { @@ -64,7 +64,7 @@ namespace Lucene } termAtt->setTermLength(upto); } - + return true; } } diff --git a/src/core/analysis/standard/StandardTokenizer.cpp b/src/core/analysis/standard/StandardTokenizer.cpp index 4b94b40b..dbf37a8e 100644 --- a/src/core/analysis/standard/StandardTokenizer.cpp +++ b/src/core/analysis/standard/StandardTokenizer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,29 +26,29 @@ namespace Lucene /// @deprecated this solves a bug where HOSTs that end with '.' are identified as ACRONYMs. const int32_t StandardTokenizer::ACRONYM_DEP = 8; - + StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, ReaderPtr input) { this->scanner = newLucene(input); init(input, matchVersion); } - + StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source) { this->scanner = newLucene(input); init(input, matchVersion); } - + StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory) { this->scanner = newLucene(input); init(input, matchVersion); } - + StandardTokenizer::~StandardTokenizer() { } - + const Collection StandardTokenizer::TOKEN_TYPES() { static Collection _TOKEN_TYPES; @@ -68,7 +68,7 @@ namespace Lucene } return _TOKEN_TYPES; } - + void StandardTokenizer::init(ReaderPtr input, LuceneVersion::Version matchVersion) { replaceInvalidAcronym = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_24); @@ -79,37 +79,37 @@ namespace Lucene posIncrAtt = addAttribute(); typeAtt = addAttribute(); } - + void StandardTokenizer::setMaxTokenLength(int32_t length) { this->maxTokenLength = length; } - + int32_t StandardTokenizer::getMaxTokenLength() { return maxTokenLength; } - + bool StandardTokenizer::incrementToken() { clearAttributes(); int32_t posIncr = 1; - + while (true) { int32_t tokenType = scanner->getNextToken(); - + if (tokenType == StandardTokenizerImpl::YYEOF) return false; - + if (scanner->yylength() <= maxTokenLength) { posIncrAtt->setPositionIncrement(posIncr); scanner->getText(termAtt); int32_t start = scanner->yychar(); offsetAtt->setOffset(correctOffset(start), correctOffset(start + termAtt->termLength())); - - // This 'if' should be removed in the next release. For now, it converts invalid acronyms to HOST. + + // This 'if' should be removed in the next release. For now, it converts invalid acronyms to HOST. /// When removed, only the 'else' part should remain. if (tokenType == ACRONYM_DEP) { @@ -132,25 +132,25 @@ namespace Lucene } } } - + void StandardTokenizer::end() { // set final offset int32_t finalOffset = correctOffset(scanner->yychar() + scanner->yylength()); offsetAtt->setOffset(finalOffset, finalOffset); } - + void StandardTokenizer::reset(ReaderPtr input) { Tokenizer::reset(input); scanner->reset(input); } - + bool StandardTokenizer::isReplaceInvalidAcronym() { return replaceInvalidAcronym; } - + void StandardTokenizer::setReplaceInvalidAcronym(bool replaceInvalidAcronym) { this->replaceInvalidAcronym = replaceInvalidAcronym; diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index d73a45c6..efe537da 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,7 +21,7 @@ namespace Lucene /// Translates characters to character classes CharArray StandardTokenizerImpl::_ZZ_CMAP; - const wchar_t StandardTokenizerImpl::ZZ_CMAP_PACKED[] = + const wchar_t StandardTokenizerImpl::ZZ_CMAP_PACKED[] = { L"\11\0\1\0\1\15\1\0\1\0\1\14\22\0\1\0\5\0\1\5" L"\1\3\4\0\1\11\1\7\1\4\1\11\12\2\6\0\1\6\32\12" @@ -82,24 +82,24 @@ namespace Lucene L"\7\0\32\12\6\0\32\12\12\0\1\13\72\13\37\12\3\0\6\12" L"\2\0\6\12\2\0\6\12\2\0\3\12\43\0" }; - + const int32_t StandardTokenizerImpl::ZZ_CMAP_LENGTH = 65536; const int32_t StandardTokenizerImpl::ZZ_CMAP_PACKED_LENGTH = 1154; IntArray StandardTokenizerImpl::_ZZ_ACTION; - const wchar_t StandardTokenizerImpl::ZZ_ACTION_PACKED_0[] = + const wchar_t StandardTokenizerImpl::ZZ_ACTION_PACKED_0[] = { L"\1\0\1\1\3\2\1\3\1\1\13\0\1\2\3\4" L"\2\0\1\5\1\0\1\5\3\4\6\5\1\6\1\4" L"\2\7\1\10\1\0\1\10\3\0\2\10\1\11\1\12" L"\1\4" }; - + const int32_t StandardTokenizerImpl::ZZ_ACTION_LENGTH = 51; const int32_t StandardTokenizerImpl::ZZ_ACTION_PACKED_LENGTH = 50; IntArray StandardTokenizerImpl::_ZZ_ROWMAP; - const wchar_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_0[] = + const wchar_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_0[] = { L"\0\0\0\16\0\34\0\52\0\70\0\16\0\106\0\124" L"\0\142\0\160\0\176\0\214\0\232\0\250\0\266\0\304" @@ -109,12 +109,12 @@ namespace Lucene L"\0\u0214\0\u0222\0\u0230\0\u023e\0\u024c\0\u025a\0\124\0\214" L"\0\u0268\0\u0276\0\u0284" }; - + const int32_t StandardTokenizerImpl::ZZ_ROWMAP_LENGTH = 51; const int32_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_LENGTH = 102; IntArray StandardTokenizerImpl::_ZZ_TRANS; - const wchar_t StandardTokenizerImpl::ZZ_TRANS_PACKED_0[] = + const wchar_t StandardTokenizerImpl::ZZ_TRANS_PACKED_0[] = { L"\1\2\1\3\1\4\7\2\1\5\1\6\1\7\1\2" L"\17\0\2\3\1\0\1\10\1\0\1\11\2\12\1\13" @@ -157,15 +157,15 @@ namespace Lucene L"\1\56\2\0\1\62\4\0\2\24\1\0\1\61\1\0" L"\1\11\2\52\1\0\1\24\3\0" }; - + const int32_t StandardTokenizerImpl::ZZ_TRANS_LENGTH = 658; const int32_t StandardTokenizerImpl::ZZ_TRANS_PACKED_LENGTH = 634; - + const int32_t StandardTokenizerImpl::ZZ_UNKNOWN_ERROR = 0; const int32_t StandardTokenizerImpl::ZZ_NO_MATCH = 1; const int32_t StandardTokenizerImpl::ZZ_PUSHBACK_2BIG = 2; - - const wchar_t* StandardTokenizerImpl::ZZ_ERROR_MSG[] = + + const wchar_t* StandardTokenizerImpl::ZZ_ERROR_MSG[] = { L"Unknown internal scanner error", L"Error: could not match input", @@ -173,21 +173,21 @@ namespace Lucene }; IntArray StandardTokenizerImpl::_ZZ_ATTRIBUTE; - const wchar_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_0[] = + const wchar_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_0[] = { L"\1\0\1\11\3\1\1\11\1\1\13\0\4\1\2\0" L"\1\1\1\0\17\1\1\0\1\1\3\0\5\1" }; - + const int32_t StandardTokenizerImpl::ZZ_ATTRIBUTE_LENGTH = 51; const int32_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_LENGTH = 30; - + /// This character denotes the end of file const int32_t StandardTokenizerImpl::YYEOF = -1; - + /// Lexical states const int32_t StandardTokenizerImpl::YYINITIAL = 0; - + StandardTokenizerImpl::StandardTokenizerImpl(ReaderPtr in) { this->zzState = 0; @@ -205,7 +205,7 @@ namespace Lucene this->zzAtEOF = false; this->zzReader = in; } - + StandardTokenizerImpl::~StandardTokenizerImpl() { } @@ -214,7 +214,7 @@ namespace Lucene { _ZZ_CMAP = CharArray::newInstance(ZZ_CMAP_LENGTH); wchar_t* result = _ZZ_CMAP.get(); - + int32_t i = 0; // index in packed string int32_t j = 0; // index in unpacked array while (i < ZZ_CMAP_PACKED_LENGTH) @@ -250,7 +250,7 @@ namespace Lucene while (--count > 0); } } - + const int32_t* StandardTokenizerImpl::ZZ_ACTION() { static boost::once_flag once = BOOST_ONCE_INIT; @@ -294,9 +294,9 @@ namespace Lucene do result[j++] = value; while (--count > 0); - } + } } - + const int32_t* StandardTokenizerImpl::ZZ_TRANS() { static boost::once_flag once = BOOST_ONCE_INIT; @@ -327,12 +327,12 @@ namespace Lucene boost::call_once(once, ZZ_ATTRIBUTE_INIT); return _ZZ_ATTRIBUTE.get(); } - + int32_t StandardTokenizerImpl::yychar() { return _yychar; } - + void StandardTokenizerImpl::reset(ReaderPtr r) { // reset to default buffer size, if buffer has grown @@ -340,24 +340,24 @@ namespace Lucene zzBuffer.resize(ZZ_BUFFERSIZE); yyreset(r); } - + void StandardTokenizerImpl::getText(TokenPtr t) { t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); } - + void StandardTokenizerImpl::getText(TermAttributePtr t) { t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); } - + bool StandardTokenizerImpl::zzRefill() { // first: make room (if you can) if (zzStartRead > 0) { MiscUtils::arrayCopy(zzBuffer.get(), zzStartRead, zzBuffer.get(), 0, zzEndRead - zzStartRead); - + // translate stored positions zzEndRead -= zzStartRead; zzCurrentPos -= zzStartRead; @@ -365,14 +365,14 @@ namespace Lucene zzPushbackPos -= zzStartRead; zzStartRead = 0; } - + // is the buffer big enough? if (zzCurrentPos >= zzBuffer.size()) zzBuffer.resize(zzCurrentPos * 2); - + // finally: fill the buffer with new input int32_t numRead = zzReader->read(zzBuffer.get(), zzEndRead, zzBuffer.size() - zzEndRead); - + if (numRead < 0) return true; else @@ -381,16 +381,16 @@ namespace Lucene return false; } } - + void StandardTokenizerImpl::yyclose() { zzAtEOF = true; // indicate end of file zzEndRead = zzStartRead; // invalidate buffer - + if (zzReader) zzReader->close(); } - + void StandardTokenizerImpl::yyreset(ReaderPtr reader) { zzReader = reader; @@ -406,61 +406,61 @@ namespace Lucene yycolumn = 0; zzLexicalState = YYINITIAL; } - + int32_t StandardTokenizerImpl::yystate() { return zzLexicalState; } - + void StandardTokenizerImpl::yybegin(int32_t newState) { zzLexicalState = newState; } - + String StandardTokenizerImpl::yytext() { return String(zzBuffer.get() + zzStartRead, zzMarkedPos - zzStartRead); } - + wchar_t StandardTokenizerImpl::yycharat(int32_t pos) { return zzBuffer[zzStartRead + pos]; } - + int32_t StandardTokenizerImpl::yylength() { return zzMarkedPos - zzStartRead; } - + void StandardTokenizerImpl::zzScanError(int32_t errorCode) { boost::throw_exception(ParseException(ZZ_ERROR_MSG[errorCode])); } - + void StandardTokenizerImpl::yypushback(int32_t number) { if (number > yylength()) zzScanError(ZZ_PUSHBACK_2BIG); zzMarkedPos -= number; } - + int32_t StandardTokenizerImpl::getNextToken() { int32_t zzInput; int32_t zzAction; - + // cached fields int32_t zzCurrentPosL; int32_t zzMarkedPosL; int32_t zzEndReadL = zzEndRead; wchar_t* zzBufferL = zzBuffer.get(); const wchar_t* zzCMapL = ZZ_CMAP(); - + const int32_t* zzTransL = ZZ_TRANS(); const int32_t* zzRowMapL = ZZ_ROWMAP(); const int32_t* zzAttrL = ZZ_ATTRIBUTE(); const int32_t* zzActionL = ZZ_ACTION(); - + while (true) { zzMarkedPosL = zzMarkedPos; @@ -499,12 +499,12 @@ namespace Lucene else zzInput = zzBufferL[zzCurrentPosL++]; } - + int32_t zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; if (zzNext == -1) break; zzState = zzNext; - + int32_t zzAttributes = zzAttrL[zzState]; if ((zzAttributes & 1) == 1) { @@ -517,7 +517,7 @@ namespace Lucene // store back cached position zzMarkedPos = zzMarkedPosL; - + switch (zzAction < 0 ? zzAction : zzActionL[zzAction]) { case 4: @@ -569,7 +569,7 @@ namespace Lucene zzScanError(ZZ_NO_MATCH); } } - + return YYINITIAL; } } diff --git a/src/core/analysis/tokenattributes/FlagsAttribute.cpp b/src/core/analysis/tokenattributes/FlagsAttribute.cpp index b8e0857f..8cd155e8 100644 --- a/src/core/analysis/tokenattributes/FlagsAttribute.cpp +++ b/src/core/analysis/tokenattributes/FlagsAttribute.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,53 +14,53 @@ namespace Lucene { flags = 0; } - + FlagsAttribute::~FlagsAttribute() { } - + String FlagsAttribute::toString() { return L"flags=" + StringUtils::toString(flags); } - + int32_t FlagsAttribute::getFlags() { return flags; } - + void FlagsAttribute::setFlags(int32_t flags) { this->flags = flags; } - + void FlagsAttribute::clear() { flags = 0; } - + bool FlagsAttribute::equals(LuceneObjectPtr other) { if (Attribute::equals(other)) return true; - + FlagsAttributePtr otherFlagsAttribute(boost::dynamic_pointer_cast(other)); if (otherFlagsAttribute) return (otherFlagsAttribute->flags == flags); - + return false; } - + int32_t FlagsAttribute::hashCode() { return flags; } - + void FlagsAttribute::copyTo(AttributePtr target) { boost::dynamic_pointer_cast(target)->setFlags(flags); } - + LuceneObjectPtr FlagsAttribute::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); diff --git a/src/core/analysis/tokenattributes/OffsetAttribute.cpp b/src/core/analysis/tokenattributes/OffsetAttribute.cpp index 32a7ca45..df55a858 100644 --- a/src/core/analysis/tokenattributes/OffsetAttribute.cpp +++ b/src/core/analysis/tokenattributes/OffsetAttribute.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,63 +15,63 @@ namespace Lucene _startOffset = 0; _endOffset = 0; } - + OffsetAttribute::~OffsetAttribute() { } - + String OffsetAttribute::toString() { return L"startOffset=" + StringUtils::toString(_startOffset) + L";endOffset=" + StringUtils::toString(_endOffset); } - + int32_t OffsetAttribute::startOffset() { return _startOffset; } - + void OffsetAttribute::setOffset(int32_t startOffset, int32_t endOffset) { this->_startOffset = startOffset; this->_endOffset = endOffset; } - + int32_t OffsetAttribute::endOffset() { return _endOffset; } - + void OffsetAttribute::clear() { _startOffset = 0; _endOffset = 0; } - + bool OffsetAttribute::equals(LuceneObjectPtr other) { if (Attribute::equals(other)) return true; - + OffsetAttributePtr otherOffsetAttribute(boost::dynamic_pointer_cast(other)); if (otherOffsetAttribute) return (otherOffsetAttribute->_startOffset == _startOffset && otherOffsetAttribute->_endOffset == _endOffset); - + return false; } - + int32_t OffsetAttribute::hashCode() { int32_t code = _startOffset; code = code * 31 + _endOffset; return code; } - + void OffsetAttribute::copyTo(AttributePtr target) { OffsetAttributePtr targetOffsetAttribute(boost::dynamic_pointer_cast(target)); targetOffsetAttribute->setOffset(_startOffset, _endOffset); } - + LuceneObjectPtr OffsetAttribute::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); diff --git a/src/core/analysis/tokenattributes/PayloadAttribute.cpp b/src/core/analysis/tokenattributes/PayloadAttribute.cpp index 14c87828..3055c993 100644 --- a/src/core/analysis/tokenattributes/PayloadAttribute.cpp +++ b/src/core/analysis/tokenattributes/PayloadAttribute.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,36 +14,36 @@ namespace Lucene PayloadAttribute::PayloadAttribute() { } - + PayloadAttribute::PayloadAttribute(PayloadPtr payload) { this->payload = payload; } - + PayloadAttribute::~PayloadAttribute() { } - + String PayloadAttribute::toString() { return L"payload(length)=" + StringUtils::toString(payload->length()); } - + PayloadPtr PayloadAttribute::getPayload() { return this->payload; } - + void PayloadAttribute::setPayload(PayloadPtr payload) { this->payload = payload; } - + void PayloadAttribute::clear() { payload.reset(); } - + LuceneObjectPtr PayloadAttribute::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); @@ -52,12 +52,12 @@ namespace Lucene cloneAttribute->payload = boost::dynamic_pointer_cast(payload->clone()); return cloneAttribute; } - + bool PayloadAttribute::equals(LuceneObjectPtr other) { if (Attribute::equals(other)) return true; - + PayloadAttributePtr otherAttribute(boost::dynamic_pointer_cast(other)); if (otherAttribute) { @@ -65,15 +65,15 @@ namespace Lucene return true; return otherAttribute->payload->equals(payload); } - + return false; } - + int32_t PayloadAttribute::hashCode() { return payload ? payload->hashCode() : 0; } - + void PayloadAttribute::copyTo(AttributePtr target) { PayloadAttributePtr targetPayloadAttribute(boost::dynamic_pointer_cast(target)); diff --git a/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp b/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp index f8fde549..481e5357 100644 --- a/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp +++ b/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,56 +14,56 @@ namespace Lucene { positionIncrement = 1; } - + PositionIncrementAttribute::~PositionIncrementAttribute() { } - + String PositionIncrementAttribute::toString() { return L"positionIncrement=" + StringUtils::toString(positionIncrement); } - + void PositionIncrementAttribute::setPositionIncrement(int32_t positionIncrement) { if (positionIncrement < 0) boost::throw_exception(IllegalArgumentException(L"Increment must be zero or greater: " + StringUtils::toString(positionIncrement))); this->positionIncrement = positionIncrement; } - + int32_t PositionIncrementAttribute::getPositionIncrement() { return positionIncrement; } - + void PositionIncrementAttribute::clear() { this->positionIncrement = 1; } - + bool PositionIncrementAttribute::equals(LuceneObjectPtr other) { if (Attribute::equals(other)) return true; - + PositionIncrementAttributePtr otherPositionIncrementAttribute(boost::dynamic_pointer_cast(other)); if (otherPositionIncrementAttribute) return positionIncrement == otherPositionIncrementAttribute->positionIncrement; - + return false; } - + int32_t PositionIncrementAttribute::hashCode() { return positionIncrement; } - + void PositionIncrementAttribute::copyTo(AttributePtr target) { PositionIncrementAttributePtr targetPositionIncrementAttribute(boost::dynamic_pointer_cast(target)); targetPositionIncrementAttribute->setPositionIncrement(positionIncrement); } - + LuceneObjectPtr PositionIncrementAttribute::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); diff --git a/src/core/analysis/tokenattributes/TermAttribute.cpp b/src/core/analysis/tokenattributes/TermAttribute.cpp index ccc01162..21ecccc4 100644 --- a/src/core/analysis/tokenattributes/TermAttribute.cpp +++ b/src/core/analysis/tokenattributes/TermAttribute.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,34 +12,34 @@ namespace Lucene { const int32_t TermAttribute::MIN_BUFFER_SIZE = 10; - + TermAttribute::TermAttribute() { _termLength = 0; } - + TermAttribute::~TermAttribute() { } - + String TermAttribute::toString() { return L"term=" + term(); } - + String TermAttribute::term() { initTermBuffer(); return String(_termBuffer.get(), _termLength); } - + void TermAttribute::setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length) { growTermBuffer(length); MiscUtils::arrayCopy(buffer, offset, _termBuffer.get(), 0, length); _termLength = length; } - + void TermAttribute::setTermBuffer(const String& buffer) { int32_t length = (int32_t)buffer.size(); @@ -47,21 +47,21 @@ namespace Lucene MiscUtils::arrayCopy(buffer.begin(), 0, _termBuffer.get(), 0, length); _termLength = length; } - + CharArray TermAttribute::termBuffer() { if (!_termBuffer) initTermBuffer(); return _termBuffer; } - + wchar_t* TermAttribute::termBufferArray() { if (!_termBuffer) initTermBuffer(); return _termBuffer.get(); } - + CharArray TermAttribute::resizeTermBuffer(int32_t newSize) { if (!_termBuffer) @@ -73,7 +73,7 @@ namespace Lucene _termBuffer.resize(MiscUtils::getNextSize(newSize)); return _termBuffer; } - + void TermAttribute::growTermBuffer(int32_t newSize) { if (!_termBuffer) @@ -84,7 +84,7 @@ namespace Lucene else if (_termBuffer.size() < newSize) _termBuffer.resize(MiscUtils::getNextSize(newSize)); } - + void TermAttribute::initTermBuffer() { if (!_termBuffer) @@ -93,25 +93,25 @@ namespace Lucene _termLength = 0; } } - + int32_t TermAttribute::termLength() { return _termLength; } - + void TermAttribute::setTermLength(int32_t length) { if (!_termBuffer) initTermBuffer(); if (length > _termBuffer.size()) { - boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + - L" exceeds the size of the termBuffer (" + + boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + + L" exceeds the size of the termBuffer (" + StringUtils::toString(_termBuffer.size()) + L")")); } _termLength = length; } - + int32_t TermAttribute::hashCode() { initTermBuffer(); @@ -119,12 +119,12 @@ namespace Lucene code = code * 31 + MiscUtils::hashCode(_termBuffer.get(), 0, _termLength); return code; } - + void TermAttribute::clear() { _termLength = 0; } - + LuceneObjectPtr TermAttribute::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); @@ -137,27 +137,27 @@ namespace Lucene } return cloneAttribute; } - + bool TermAttribute::equals(LuceneObjectPtr other) { if (Attribute::equals(other)) return true; - + TermAttributePtr otherTermAttribute(boost::dynamic_pointer_cast(other)); if (otherTermAttribute) { initTermBuffer(); otherTermAttribute->initTermBuffer(); - + if (_termLength != otherTermAttribute->_termLength) return false; - + return (std::memcmp(_termBuffer.get(), otherTermAttribute->_termBuffer.get(), _termLength) == 0); } - + return false; } - + void TermAttribute::copyTo(AttributePtr target) { initTermBuffer(); diff --git a/src/core/analysis/tokenattributes/TypeAttribute.cpp b/src/core/analysis/tokenattributes/TypeAttribute.cpp index 0417b702..527ac68a 100644 --- a/src/core/analysis/tokenattributes/TypeAttribute.cpp +++ b/src/core/analysis/tokenattributes/TypeAttribute.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,64 +14,64 @@ namespace Lucene { _type = DEFAULT_TYPE(); } - + TypeAttribute::TypeAttribute(const String& type) { _type = type; } - + TypeAttribute::~TypeAttribute() { } - + const String& TypeAttribute::DEFAULT_TYPE() { static String _DEFAULT_TYPE(L"word"); return _DEFAULT_TYPE; } - + String TypeAttribute::toString() { return L"type=" + _type; } - + String TypeAttribute::type() { return _type; } - + void TypeAttribute::setType(const String& type) { _type = type; } - + void TypeAttribute::clear() { _type = DEFAULT_TYPE(); } - + bool TypeAttribute::equals(LuceneObjectPtr other) { if (Attribute::equals(other)) return true; - + TypeAttributePtr otherTypeAttribute(boost::dynamic_pointer_cast(other)); if (otherTypeAttribute) return (otherTypeAttribute->_type == _type); - + return false; } - + int32_t TypeAttribute::hashCode() { return StringUtils::hashCode(_type); } - + void TypeAttribute::copyTo(AttributePtr target) { boost::dynamic_pointer_cast(target)->setType(_type); } - + LuceneObjectPtr TypeAttribute::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); diff --git a/src/core/document/AbstractField.cpp b/src/core/document/AbstractField.cpp index 6c54d390..aee3fe24 100644 --- a/src/core/document/AbstractField.cpp +++ b/src/core/document/AbstractField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,16 +23,16 @@ namespace Lucene this->_isIndexed = true; this->_isTokenized = true; this->_isBinary = false; - + this->lazy = false; this->omitTermFreqAndPositions = false; this->boost = 1.0; this->fieldsData = VariantUtils::null(); - + this->binaryLength = 0; this->binaryOffset = 0; } - + AbstractField::AbstractField(const String& name, Field::Store store, Field::Index index, Field::TermVector termVector) { this->_name = name; @@ -41,89 +41,89 @@ namespace Lucene this->_isTokenized = Field::isAnalyzed(index); this->_omitNorms = Field::omitNorms(index); this->_isBinary = false; - + this->lazy = false; this->omitTermFreqAndPositions = false; this->boost = 1.0; this->fieldsData = VariantUtils::null(); - + this->binaryLength = 0; this->binaryOffset = 0; setStoreTermVector(termVector); } - + AbstractField::~AbstractField() { } - + void AbstractField::setBoost(double boost) { this->boost = boost; } - + double AbstractField::getBoost() { return boost; } - + String AbstractField::name() { return _name; } - + void AbstractField::setStoreTermVector(Field::TermVector termVector) { this->storeTermVector = Field::isStored(termVector); this->storePositionWithTermVector = Field::withPositions(termVector); this->storeOffsetWithTermVector = Field::withOffsets(termVector); } - + bool AbstractField::isStored() { return _isStored; } - + bool AbstractField::isIndexed() { return _isIndexed; } - + bool AbstractField::isTokenized() { return _isTokenized; } - + bool AbstractField::isTermVectorStored() { return storeTermVector; } - + bool AbstractField::isStoreOffsetWithTermVector() { return storeOffsetWithTermVector; } - + bool AbstractField::isStorePositionWithTermVector() { return storePositionWithTermVector; } - + bool AbstractField::isBinary() { return _isBinary; } - + ByteArray AbstractField::getBinaryValue() { return getBinaryValue(ByteArray()); } - + ByteArray AbstractField::getBinaryValue(ByteArray result) { return VariantUtils::get(fieldsData); } - + int32_t AbstractField::getBinaryLength() { if (_isBinary) @@ -131,37 +131,37 @@ namespace Lucene ByteArray binary(VariantUtils::get(fieldsData)); return binary ? binary.size() : 0; } - + int32_t AbstractField::getBinaryOffset() { return binaryOffset; } - + bool AbstractField::getOmitNorms() { return _omitNorms; } - + bool AbstractField::getOmitTermFreqAndPositions() { return omitTermFreqAndPositions; } - + void AbstractField::setOmitNorms(bool omitNorms) { this->_omitNorms = omitNorms; } - + void AbstractField::setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) { this->omitTermFreqAndPositions = omitTermFreqAndPositions; } - + bool AbstractField::isLazy() { return lazy; } - + String AbstractField::toString() { StringStream result; @@ -210,14 +210,14 @@ namespace Lucene if (lazy) result << L",lazy"; result << L"<" << _name << L":"; - + if (VariantUtils::typeOf(fieldsData)) result << VariantUtils::get(fieldsData); else if (VariantUtils::typeOf(fieldsData)) result << L"Reader"; else if (VariantUtils::typeOf(fieldsData)) result << L"Binary [size=" << StringUtils::toString(VariantUtils::get(fieldsData).size()) << L"]"; - + result << L">"; return result.str(); } diff --git a/src/core/document/CompressionTools.cpp b/src/core/document/CompressionTools.cpp index ff644995..dd1c02c0 100644 --- a/src/core/document/CompressionTools.cpp +++ b/src/core/document/CompressionTools.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,7 +18,7 @@ namespace Lucene { const int32_t CompressionTools::COMPRESS_BUFFER = 4096; - + String ZLibToMessage(int32_t error) { if (error == boost::iostreams::zlib::okay) @@ -38,7 +38,7 @@ namespace Lucene else return L"unknown"; } - + class BufferArraySink : public boost::iostreams::sink { public: @@ -47,15 +47,15 @@ namespace Lucene this->allocSize = allocSize; this->buffer.resize((int32_t)allocSize); } - + public: ByteArray& buffer; std::streamsize& position; - + private: size_t allocSize; - public: + public: std::streamsize write(const char* s, std::streamsize n) { if (position + n >= (std::streamsize)allocSize) @@ -77,82 +77,82 @@ namespace Lucene ByteArray CompressionTools::compress(uint8_t* value, int32_t offset, int32_t length, int32_t compressionLevel) { // setup the outStream - boost::iostreams::filtering_ostreambuf outStream; + boost::iostreams::filtering_ostreambuf outStream; boost::iostreams::zlib_compressor zcompressor(compressionLevel); outStream.push(zcompressor); - + // and the output buffer ByteArray buffer(ByteArray::newInstance(COMPRESS_BUFFER)); std::streamsize position = 0; - outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); - + outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); + // setup the source stream, and then copy it to the outStream boost::iostreams::stream< boost::iostreams::array_source > source((char*)(value + offset), length); - + try { - boost::iostreams::copy(source, outStream); + boost::iostreams::copy(source, outStream); } catch (boost::iostreams::zlib_error& err) { boost::throw_exception(CompressionException(L"deflate failure: " + ZLibToMessage(err.error()))); } - + buffer.resize((int32_t)position); - + return buffer; } - + ByteArray CompressionTools::compress(uint8_t* value, int32_t offset, int32_t length) { return compress(value, offset, length, boost::iostreams::zlib::best_compression); } - + ByteArray CompressionTools::compress(ByteArray value) { return compress(value.get(), 0, value.size(), boost::iostreams::zlib::best_compression); } - + ByteArray CompressionTools::compressString(const String& value) { return compressString(value, boost::iostreams::zlib::best_compression); } - + ByteArray CompressionTools::compressString(const String& value, int32_t compressionLevel) { UTF8ResultPtr utf8Result(newLucene()); StringUtils::toUTF8(value.c_str(), (int32_t)value.length(), utf8Result); return compress(utf8Result->result.get(), 0, utf8Result->length, compressionLevel); } - + ByteArray CompressionTools::decompress(ByteArray value) { // setup the outStream - boost::iostreams::filtering_ostreambuf outStream; + boost::iostreams::filtering_ostreambuf outStream; outStream.push(boost::iostreams::zlib_decompressor()); - + // and the output buffer ByteArray buffer(ByteArray::newInstance(COMPRESS_BUFFER)); std::streamsize position = 0; - outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); - + outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); + //setup the source stream, and then copy it to the outStream boost::iostreams::stream< boost::iostreams::array_source > source((char*)value.get(), value.size()); - + try { - boost::iostreams::copy(source, outStream); - } + boost::iostreams::copy(source, outStream); + } catch (boost::iostreams::zlib_error& err) { boost::throw_exception(CompressionException(L"deflate failure: " + ZLibToMessage(err.error()))); } - + buffer.resize((int32_t)position); - + return buffer; } - + String CompressionTools::decompressString(ByteArray value) { ByteArray bytes(decompress(value)); diff --git a/src/core/document/DateField.cpp b/src/core/document/DateField.cpp index 545c6717..449845f7 100644 --- a/src/core/document/DateField.cpp +++ b/src/core/document/DateField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene DateField::~DateField() { } - + int32_t DateField::DATE_LEN() { static int32_t _DATE_LEN = 0; @@ -25,7 +25,7 @@ namespace Lucene } return _DATE_LEN; } - + const String& DateField::MIN_DATE_STRING() { static String _MIN_DATE_STRING; @@ -33,7 +33,7 @@ namespace Lucene _MIN_DATE_STRING = timeToString(0); return _MIN_DATE_STRING; } - + const String& DateField::MAX_DATE_STRING() { static String _MAX_DATE_STRING; @@ -44,23 +44,23 @@ namespace Lucene } return _MAX_DATE_STRING; } - + String DateField::dateToString(const boost::posix_time::ptime& date) { return timeToString(MiscUtils::getTimeMillis(date)); } - + String DateField::timeToString(int64_t time) { if (time < 0) boost::throw_exception(RuntimeException(L"time '" + StringUtils::toString(time) + L"' is too early, must be >= 0")); - + String timeString(DATE_LEN(), L'0'); timeString += StringUtils::toString(time, StringUtils::CHARACTER_MAX_RADIX); - + return timeString.substr(timeString.length() - DATE_LEN(), DATE_LEN()); } - + int64_t DateField::stringToTime(const String& s) { return StringUtils::toLong(s, StringUtils::CHARACTER_MAX_RADIX); diff --git a/src/core/document/DateTools.cpp b/src/core/document/DateTools.cpp index 4ad1f4f0..f0234980 100644 --- a/src/core/document/DateTools.cpp +++ b/src/core/document/DateTools.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,16 +14,16 @@ namespace Lucene { DateTools::DateOrder DateTools::dateOrder = DateTools::DATEORDER_LOCALE; - + DateTools::~DateTools() { } - + String DateTools::dateToString(const boost::posix_time::ptime& date, Resolution resolution) { return timeToString(MiscUtils::getTimeMillis(date), resolution); } - + String DateTools::timeToString(int64_t time, Resolution resolution) { std::string timeString(boost::posix_time::to_iso_string(boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1), boost::posix_time::milliseconds(time)))); @@ -50,16 +50,16 @@ namespace Lucene // silence static analyzers break; } - + boost::throw_exception(IllegalArgumentException(L"unknown resolution '" + StringUtils::toString(resolution) + L"'")); return L""; } - + int64_t DateTools::stringToTime(const String& dateString) { return MiscUtils::getTimeMillis(stringToDate(dateString)); } - + boost::posix_time::ptime DateTools::stringToDate(const String& dateString) { uint16_t year = dateString.length() >= 4 ? (uint16_t)wcstol(dateString.substr(0, 4).c_str(), 0, 10) : 1970; @@ -73,9 +73,9 @@ namespace Lucene try { date = boost::posix_time::ptime(boost::gregorian::date(year, month, day), - boost::posix_time::hours(hour) + - boost::posix_time::minutes(minute) + - boost::posix_time::seconds(second) + + boost::posix_time::hours(hour) + + boost::posix_time::minutes(minute) + + boost::posix_time::seconds(second) + boost::posix_time::milliseconds(millisecond)); } catch (...) @@ -84,11 +84,11 @@ namespace Lucene } return date; } - + boost::posix_time::ptime DateTools::round(const boost::posix_time::ptime& date, Resolution resolution) { boost::posix_time::ptime roundDate; - + switch (resolution) { case RESOLUTION_YEAR: @@ -98,16 +98,16 @@ namespace Lucene case RESOLUTION_DAY: return boost::posix_time::ptime(date.date()); case RESOLUTION_HOUR: - return boost::posix_time::ptime(date.date(), + return boost::posix_time::ptime(date.date(), boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours())); case RESOLUTION_MINUTE: - return boost::posix_time::ptime(date.date(), + return boost::posix_time::ptime(date.date(), boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours()) + boost::posix_time::minutes(boost::posix_time::time_duration(date.time_of_day()).minutes())); case RESOLUTION_SECOND: - return boost::posix_time::ptime(date.date(), + return boost::posix_time::ptime(date.date(), boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours()) + - boost::posix_time::minutes(boost::posix_time::time_duration(date.time_of_day()).minutes()) + + boost::posix_time::minutes(boost::posix_time::time_duration(date.time_of_day()).minutes()) + boost::posix_time::seconds(boost::posix_time::time_duration(date.time_of_day()).seconds())); case RESOLUTION_MILLISECOND: return date; @@ -115,38 +115,38 @@ namespace Lucene // silence static analyzers break; } - + return boost::posix_time::ptime(); } - + int64_t DateTools::round(int64_t time, Resolution resolution) { return MiscUtils::getTimeMillis(round(boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1), boost::posix_time::milliseconds(time)), resolution)); } - + void DateTools::setDateOrder(DateTools::DateOrder order) { dateOrder = order; } - + DateTools::DateOrder DateTools::getDateOrder(std::locale locale) { if (dateOrder != DATEORDER_LOCALE) return dateOrder; - + std::locale localeDate(std::locale(locale, new boost::gregorian::date_facet("%x"))); SingleStringStream controlStream; - + controlStream.imbue(localeDate); controlStream << boost::gregorian::date(1974, 10, 20); // Oct 20th 1974 - + SingleString controlDate(controlStream.str()); SingleString::size_type year = controlDate.find("74"); SingleString::size_type month = controlDate.find("10"); if (month == SingleString::npos) month = controlDate.find("O"); // safety SingleString::size_type day = controlDate.find("20"); - + if (year < month) return DATEORDER_YMD; else if (month < day) @@ -154,7 +154,7 @@ namespace Lucene else return DATEORDER_DMY; } - + boost::posix_time::ptime DateTools::parseDate(const String& dateString, std::locale locale) { Collection dateTokens(StringUtils::split(dateString, L",-. /")); @@ -169,9 +169,9 @@ namespace Lucene else paddedDate += *token; } - + Collection dateFormats(Collection::newInstance()); - + switch (getDateOrder(locale)) { case DATEORDER_DMY: @@ -202,10 +202,10 @@ namespace Lucene // silence static analyzers break; } - + boost::date_time::format_date_parser parser(L"", locale); - boost::date_time::special_values_parser svp; - + boost::date_time::special_values_parser svp; + for (Collection::iterator dateFormat = dateFormats.begin(); dateFormat != dateFormats.end(); ++dateFormat) { try @@ -218,7 +218,7 @@ namespace Lucene { } } - + boost::throw_exception(ParseException(L"Invalid date '" + dateString + L"'")); return boost::posix_time::ptime(); } diff --git a/src/core/document/Document.cpp b/src/core/document/Document.cpp index 715ae908..c0a8c063 100644 --- a/src/core/document/Document.cpp +++ b/src/core/document/Document.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,26 +16,26 @@ namespace Lucene fields = Collection::newInstance(); boost = 1.0; } - + Document::~Document() { } - + void Document::setBoost(double boost) { this->boost = boost; } - + double Document::getBoost() { return boost; } - + void Document::add(FieldablePtr field) { fields.add(field); } - + /// Utility functor for comparing fieldable names. /// see {@link Document}. struct equalFieldableName @@ -47,30 +47,30 @@ namespace Lucene } const String& equalName; }; - + void Document::removeField(const String& name) { Collection::iterator field = fields.find_if(equalFieldableName(name)); if (field != fields.end()) fields.remove(field); } - + void Document::removeFields(const String& name) { fields.remove_if(equalFieldableName(name)); } - + FieldPtr Document::getField(const String& name) { return boost::static_pointer_cast(getFieldable(name)); } - + FieldablePtr Document::getFieldable(const String& name) { Collection::iterator field = fields.find_if(equalFieldableName(name)); return field == fields.end() ? FieldablePtr() : *field; } - + String Document::get(const String& name) { for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) @@ -80,12 +80,12 @@ namespace Lucene } return L""; } - + Collection Document::getFields() { return fields; } - + Collection Document::getFields(const String& name) { Collection result(Collection::newInstance()); @@ -96,7 +96,7 @@ namespace Lucene } return result; } - + Collection Document::getFieldables(const String& name) { Collection result(Collection::newInstance()); @@ -107,7 +107,7 @@ namespace Lucene } return result; } - + Collection Document::getValues(const String& name) { Collection result(Collection::newInstance()); @@ -118,7 +118,7 @@ namespace Lucene } return result; } - + Collection Document::getBinaryValues(const String& name) { Collection result(Collection::newInstance()); @@ -129,7 +129,7 @@ namespace Lucene } return result; } - + ByteArray Document::getBinaryValue(const String& name) { for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) @@ -139,7 +139,7 @@ namespace Lucene } return ByteArray(); } - + String Document::toString() { StringStream buffer; diff --git a/src/core/document/Field.cpp b/src/core/document/Field.cpp index a2407d2a..9ed29000 100644 --- a/src/core/document/Field.cpp +++ b/src/core/document/Field.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,42 +16,42 @@ namespace Lucene { ConstructField(name, value, store, index, TERM_VECTOR_NO); } - + Field::Field(const String& name, const String& value, Store store, Index index, TermVector termVector) { ConstructField(name, value, store, index, termVector); } - + Field::Field(const String& name, ReaderPtr reader) { ConstructField(name, reader, TERM_VECTOR_NO); } - + Field::Field(const String& name, ReaderPtr reader, TermVector termVector) { ConstructField(name, reader, termVector); } - + Field::Field(const String& name, TokenStreamPtr tokenStream) { ConstructField(name, tokenStream, TERM_VECTOR_NO); } - + Field::Field(const String& name, TokenStreamPtr tokenStream, TermVector termVector) { ConstructField(name, tokenStream, termVector); } - + Field::Field(const String& name, ByteArray value, Store store) { ConstructField(name, value, 0, value.size(), store); } - + Field::Field(const String& name, ByteArray value, int32_t offset, int32_t length, Store store) { ConstructField(name, value, offset, length, store); } - + void Field::ConstructField(const String& name, const String& value, Store store, Index index, TermVector termVector) { if (name.empty() && value.empty()) @@ -60,21 +60,21 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"it doesn't make sense to have a field that is neither indexed nor stored")); if (index == INDEX_NO && termVector != TERM_VECTOR_NO) boost::throw_exception(IllegalArgumentException(L"cannot store term vector information for a field that is not indexed")); - - this->_name = name; + + this->_name = name; this->fieldsData = value; this->_isStored = isStored(store); this->_isIndexed = isIndexed(index); this->_isTokenized = isAnalyzed(index); this->_omitNorms = omitNorms(index); this->_isBinary = false; - + if (index == INDEX_NO) this->omitTermFreqAndPositions = false; - + setStoreTermVector(termVector); } - + void Field::ConstructField(const String& name, ReaderPtr reader, TermVector termVector) { this->_name = name; @@ -86,7 +86,7 @@ namespace Lucene setStoreTermVector(termVector); } - + void Field::ConstructField(const String& name, TokenStreamPtr tokenStream, TermVector termVector) { this->_name = name; @@ -99,12 +99,12 @@ namespace Lucene setStoreTermVector(termVector); } - + void Field::ConstructField(const String& name, ByteArray value, int32_t offset, int32_t length, Store store) { if (store == STORE_NO) boost::throw_exception(IllegalArgumentException(L"binary values can't be unstored")); - + this->_name = name; this->fieldsData = value; this->_isStored = isStored(store); @@ -115,36 +115,36 @@ namespace Lucene this->_isBinary = true; this->binaryLength = length; this->binaryOffset = offset; - + setStoreTermVector(TERM_VECTOR_NO); } - + Field::~Field() { } - + String Field::stringValue() { return VariantUtils::get(fieldsData); } - + ReaderPtr Field::readerValue() { return VariantUtils::get(fieldsData); } - + TokenStreamPtr Field::tokenStreamValue() { return tokenStream; } - + void Field::setValue(const String& value) { if (_isBinary) boost::throw_exception(IllegalArgumentException(L"cannot set a String value on a binary field")); fieldsData = value; } - + void Field::setValue(ReaderPtr value) { if (_isBinary) @@ -153,7 +153,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"cannot set a Reader value on a stored field")); fieldsData = value; } - + void Field::setValue(ByteArray value) { if (!_isBinary) @@ -162,7 +162,7 @@ namespace Lucene binaryLength = value.size(); binaryOffset = 0; } - + void Field::setValue(ByteArray value, int32_t offset, int32_t length) { if (!_isBinary) @@ -171,208 +171,208 @@ namespace Lucene binaryLength = length; binaryOffset = offset; } - + void Field::setTokenStream(TokenStreamPtr tokenStream) { this->_isIndexed = true; this->_isTokenized = true; this->tokenStream = tokenStream; } - + bool Field::isStored(Store store) { switch (store) { case STORE_YES: return true; - + case STORE_NO: return false; - + default: boost::throw_exception(IllegalArgumentException(L"Invalid field store")); return false; } } - + bool Field::isIndexed(Index index) { switch (index) { case INDEX_NO: return false; - + case INDEX_ANALYZED: return true; - + case INDEX_NOT_ANALYZED: return true; - + case INDEX_NOT_ANALYZED_NO_NORMS: return true; - + case INDEX_ANALYZED_NO_NORMS: return true; - + default: boost::throw_exception(IllegalArgumentException(L"Invalid field index")); return false; } } - + bool Field::isAnalyzed(Index index) { switch (index) { case INDEX_NO: return false; - + case INDEX_ANALYZED: return true; - + case INDEX_NOT_ANALYZED: return false; - + case INDEX_NOT_ANALYZED_NO_NORMS: return false; - + case INDEX_ANALYZED_NO_NORMS: return true; - + default: boost::throw_exception(IllegalArgumentException(L"Invalid field index")); return false; } } - + bool Field::omitNorms(Index index) { switch (index) { case INDEX_NO: return true; - + case INDEX_ANALYZED: return false; - + case INDEX_NOT_ANALYZED: return false; - + case INDEX_NOT_ANALYZED_NO_NORMS: return true; - + case INDEX_ANALYZED_NO_NORMS: return true; - + default: boost::throw_exception(IllegalArgumentException(L"Invalid field index")); return false; } } - + Field::Index Field::toIndex(bool indexed, bool analyzed) { return toIndex(indexed, analyzed, false); } - + Field::Index Field::toIndex(bool indexed, bool analyzed, bool omitNorms) { // If it is not indexed nothing else matters if (!indexed) return INDEX_NO; - + // typical, non-expert if (!omitNorms) return analyzed ? INDEX_ANALYZED : INDEX_NOT_ANALYZED; - + // Expert: Norms omitted return analyzed ? INDEX_ANALYZED_NO_NORMS : INDEX_NOT_ANALYZED_NO_NORMS; } - + bool Field::isStored(TermVector termVector) { switch (termVector) { case TERM_VECTOR_NO: return false; - + case TERM_VECTOR_YES: return true; - + case TERM_VECTOR_WITH_POSITIONS: return true; - + case TERM_VECTOR_WITH_OFFSETS: return true; - + case TERM_VECTOR_WITH_POSITIONS_OFFSETS: return true; - + default: boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); return false; } } - + bool Field::withPositions(TermVector termVector) { switch (termVector) { case TERM_VECTOR_NO: return false; - + case TERM_VECTOR_YES: return false; - + case TERM_VECTOR_WITH_POSITIONS: return true; - + case TERM_VECTOR_WITH_OFFSETS: return false; - + case TERM_VECTOR_WITH_POSITIONS_OFFSETS: return true; - + default: boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); return false; } } - + bool Field::withOffsets(TermVector termVector) { switch (termVector) { case TERM_VECTOR_NO: return false; - + case TERM_VECTOR_YES: return false; - + case TERM_VECTOR_WITH_POSITIONS: return false; - + case TERM_VECTOR_WITH_OFFSETS: return true; - + case TERM_VECTOR_WITH_POSITIONS_OFFSETS: return true; - + default: boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); return false; } } - + Field::TermVector Field::toTermVector(bool stored, bool withOffsets, bool withPositions) { // If it is not stored, nothing else matters. if (!stored) return TERM_VECTOR_NO; - + if (withOffsets) return withPositions ? TERM_VECTOR_WITH_POSITIONS_OFFSETS : TERM_VECTOR_WITH_OFFSETS; - + return withPositions ? TERM_VECTOR_WITH_POSITIONS : TERM_VECTOR_YES; } } diff --git a/src/core/document/FieldSelector.cpp b/src/core/document/FieldSelector.cpp index 669b17cf..a8fbf2b2 100644 --- a/src/core/document/FieldSelector.cpp +++ b/src/core/document/FieldSelector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/document/Fieldable.cpp b/src/core/document/Fieldable.cpp index 559a0584..514d1517 100644 --- a/src/core/document/Fieldable.cpp +++ b/src/core/document/Fieldable.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,127 +14,127 @@ namespace Lucene BOOST_ASSERT(false); // override } - + double Fieldable::getBoost() { BOOST_ASSERT(false); return 0; // override } - + String Fieldable::name() { BOOST_ASSERT(false); return L""; // override } - + String Fieldable::stringValue() { BOOST_ASSERT(false); return L""; // override } - + ReaderPtr Fieldable::readerValue() { BOOST_ASSERT(false); return ReaderPtr(); // override } - + TokenStreamPtr Fieldable::tokenStreamValue() { BOOST_ASSERT(false); return TokenStreamPtr(); // override } - + bool Fieldable::isStored() { BOOST_ASSERT(false); return false; // override } - + bool Fieldable::isIndexed() { BOOST_ASSERT(false); return false; // override } - + bool Fieldable::isTokenized() { BOOST_ASSERT(false); return false; // override } - + bool Fieldable::isTermVectorStored() { BOOST_ASSERT(false); return false; // override } - + bool Fieldable::isStoreOffsetWithTermVector() { BOOST_ASSERT(false); return false; // override } - + bool Fieldable::isStorePositionWithTermVector() { BOOST_ASSERT(false); return false; // override } - + bool Fieldable::isBinary() { BOOST_ASSERT(false); return false; // override } - + bool Fieldable::getOmitNorms() { BOOST_ASSERT(false); return false; // override } - + void Fieldable::setOmitNorms(bool omitNorms) { - BOOST_ASSERT(false); + BOOST_ASSERT(false); // override } - + bool Fieldable::isLazy() { BOOST_ASSERT(false); return false; // override } - + int32_t Fieldable::getBinaryOffset() { BOOST_ASSERT(false); return 0; // override } - + int32_t Fieldable::getBinaryLength() { BOOST_ASSERT(false); return 0; // override } - + ByteArray Fieldable::getBinaryValue() { BOOST_ASSERT(false); return ByteArray(); // override } - + ByteArray Fieldable::getBinaryValue(ByteArray result) { BOOST_ASSERT(false); return ByteArray(); // override } - + bool Fieldable::getOmitTermFreqAndPositions() { BOOST_ASSERT(false); return false; // override } - + void Fieldable::setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) { BOOST_ASSERT(false); diff --git a/src/core/document/LoadFirstFieldSelector.cpp b/src/core/document/LoadFirstFieldSelector.cpp index 5efff051..cfe9686a 100644 --- a/src/core/document/LoadFirstFieldSelector.cpp +++ b/src/core/document/LoadFirstFieldSelector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene LoadFirstFieldSelector::~LoadFirstFieldSelector() { } - + FieldSelector::FieldSelectorResult LoadFirstFieldSelector::accept(const String& fieldName) { return FieldSelector::SELECTOR_LOAD_AND_BREAK; diff --git a/src/core/document/MapFieldSelector.cpp b/src/core/document/MapFieldSelector.cpp index 0341d970..f5e0739e 100644 --- a/src/core/document/MapFieldSelector.cpp +++ b/src/core/document/MapFieldSelector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,18 +13,18 @@ namespace Lucene { this->fieldSelections = fieldSelections; } - + MapFieldSelector::MapFieldSelector(Collection fields) { fieldSelections = MapStringFieldSelectorResult::newInstance(); for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) fieldSelections.put(*field, FieldSelector::SELECTOR_LOAD); } - + MapFieldSelector::~MapFieldSelector() { } - + FieldSelector::FieldSelectorResult MapFieldSelector::accept(const String& fieldName) { MapStringFieldSelectorResult::iterator selection = fieldSelections.find(fieldName); diff --git a/src/core/document/NumberTools.cpp b/src/core/document/NumberTools.cpp index ff1cab40..86a13499 100644 --- a/src/core/document/NumberTools.cpp +++ b/src/core/document/NumberTools.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,11 +13,11 @@ namespace Lucene const int32_t NumberTools::RADIX = 36; const wchar_t NumberTools::NEGATIVE_PREFIX = L'-'; const wchar_t NumberTools::POSITIVE_PREFIX = L'0'; - + NumberTools::~NumberTools() { } - + const String& NumberTools::MIN_STRING_VALUE() { static String _MIN_STRING_VALUE; @@ -28,7 +28,7 @@ namespace Lucene } return _MIN_STRING_VALUE; } - + const String& NumberTools::MAX_STRING_VALUE() { static String _MAX_STRING_VALUE; @@ -39,7 +39,7 @@ namespace Lucene } return _MAX_STRING_VALUE; } - + int32_t NumberTools::STR_SIZE() { static int32_t _STR_SIZE = 0; @@ -47,7 +47,7 @@ namespace Lucene _STR_SIZE = (int32_t)MIN_STRING_VALUE().length(); return _STR_SIZE; } - + String NumberTools::longToString(int64_t l) { if (l == std::numeric_limits::min()) @@ -55,37 +55,37 @@ namespace Lucene // special case, because long is not symmetric around zero return MIN_STRING_VALUE(); } - + String buf; buf.reserve(STR_SIZE()); - + if (l < 0) { buf += NEGATIVE_PREFIX; l = std::numeric_limits::max() + l + 1; } buf += POSITIVE_PREFIX; - + String num(StringUtils::toString(l, RADIX)); - + int32_t padLen = (int32_t)(STR_SIZE() - num.length() - buf.length()); while (padLen-- > 0) buf += L'0'; - + return buf + num; } - + int64_t NumberTools::stringToLong(const String& str) { if ((int32_t)str.length() != STR_SIZE()) boost::throw_exception(NumberFormatException(L"string is the wrong size")); - + if (str == MIN_STRING_VALUE()) return std::numeric_limits::min(); - + wchar_t prefix = str[0]; int64_t l = StringUtils::toLong(str.substr(1), RADIX); - + if (prefix == POSITIVE_PREFIX) { // nop } @@ -93,7 +93,7 @@ namespace Lucene l = l - std::numeric_limits::max() - 1; else boost::throw_exception(NumberFormatException(L"string does not begin with the correct prefix")); - + return l; } } diff --git a/src/core/document/NumericField.cpp b/src/core/document/NumericField.cpp index c9abd20f..b1a839ca 100644 --- a/src/core/document/NumericField.cpp +++ b/src/core/document/NumericField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,79 +13,79 @@ namespace Lucene { - NumericField::NumericField(const String& name) + NumericField::NumericField(const String& name) : AbstractField(name, Field::STORE_NO, Field::INDEX_ANALYZED_NO_NORMS, Field::TERM_VECTOR_NO) { setOmitTermFreqAndPositions(true); tokenStream = newLucene(NumericUtils::PRECISION_STEP_DEFAULT); } - + NumericField::NumericField(const String& name, Field::Store store, bool index) : AbstractField(name, store, index ? Field::INDEX_ANALYZED_NO_NORMS : Field::INDEX_NO, Field::TERM_VECTOR_NO) { setOmitTermFreqAndPositions(true); tokenStream = newLucene(NumericUtils::PRECISION_STEP_DEFAULT); } - + NumericField::NumericField(const String& name, int32_t precisionStep) : AbstractField(name, Field::STORE_NO, Field::INDEX_ANALYZED_NO_NORMS, Field::TERM_VECTOR_NO) { setOmitTermFreqAndPositions(true); tokenStream = newLucene(precisionStep); } - + NumericField::NumericField(const String& name, int32_t precisionStep, Field::Store store, bool index) : AbstractField(name, store, index ? Field::INDEX_ANALYZED_NO_NORMS : Field::INDEX_NO, Field::TERM_VECTOR_NO) { setOmitTermFreqAndPositions(true); tokenStream = newLucene(precisionStep); } - + NumericField::~NumericField() { } - + TokenStreamPtr NumericField::tokenStreamValue() { return isIndexed() ? boost::static_pointer_cast(tokenStream) : TokenStreamPtr(); } - + ByteArray NumericField::getBinaryValue(ByteArray result) { return ByteArray(); } - + ReaderPtr NumericField::readerValue() { return ReaderPtr(); } - + String NumericField::stringValue() { StringStream value; value << fieldsData; return value.str(); } - + int64_t NumericField::getNumericValue() { return StringUtils::toLong(stringValue()); } - + NumericFieldPtr NumericField::setLongValue(int64_t value) { tokenStream->setLongValue(value); fieldsData = value; return shared_from_this(); } - + NumericFieldPtr NumericField::setIntValue(int32_t value) { tokenStream->setIntValue(value); fieldsData = value; return shared_from_this(); } - + NumericFieldPtr NumericField::setDoubleValue(double value) { tokenStream->setDoubleValue(value); diff --git a/src/core/document/SetBasedFieldSelector.cpp b/src/core/document/SetBasedFieldSelector.cpp index 999a23fc..067d2994 100644 --- a/src/core/document/SetBasedFieldSelector.cpp +++ b/src/core/document/SetBasedFieldSelector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene this->fieldsToLoad = fieldsToLoad; this->lazyFieldsToLoad = lazyFieldsToLoad; } - + SetBasedFieldSelector::~SetBasedFieldSelector() { } - + FieldSelector::FieldSelectorResult SetBasedFieldSelector::accept(const String& fieldName) { FieldSelector::FieldSelectorResult result = FieldSelector::SELECTOR_NO_LOAD; diff --git a/src/core/include/LuceneInc.h b/src/core/include/LuceneInc.h index 4f1ee0b7..1fbee3a2 100644 --- a/src/core/include/LuceneInc.h +++ b/src/core/include/LuceneInc.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/include/_BooleanQuery.h b/src/core/include/_BooleanQuery.h index 66db36ea..f0e7f603 100644 --- a/src/core/include/_BooleanQuery.h +++ b/src/core/include/_BooleanQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,16 +17,16 @@ namespace Lucene public: BooleanWeight(BooleanQueryPtr query, SearcherPtr searcher); virtual ~BooleanWeight(); - + LUCENE_CLASS(BooleanWeight); - + protected: BooleanQueryPtr query; - + /// The Similarity implementation. SimilarityPtr similarity; Collection weights; - + public: virtual QueryPtr getQuery(); virtual double getValue(); @@ -36,16 +36,16 @@ namespace Lucene virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); virtual bool scoresDocsOutOfOrder(); }; - + /// Disabled coord Similarity class SimilarityDisableCoord : public SimilarityDelegator { public: SimilarityDisableCoord(SimilarityPtr delegee); virtual ~SimilarityDisableCoord(); - + LUCENE_CLASS(SimilarityDisableCoord); - + public: virtual double coord(int32_t overlap, int32_t maxOverlap); }; diff --git a/src/core/include/_ByteFieldSource.h b/src/core/include/_ByteFieldSource.h index a9c2ec2e..945f988d 100644 --- a/src/core/include/_ByteFieldSource.h +++ b/src/core/include/_ByteFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,13 +16,13 @@ namespace Lucene public: ByteDocValues(ByteFieldSourcePtr source, Collection arr); virtual ~ByteDocValues(); - + LUCENE_CLASS(ByteDocValues); - + protected: ByteFieldSourceWeakPtr _source; Collection arr; - + public: virtual double doubleVal(int32_t doc); virtual int32_t intVal(int32_t doc); diff --git a/src/core/include/_CachingSpanFilter.h b/src/core/include/_CachingSpanFilter.h index d0ca264f..0aafb4e2 100644 --- a/src/core/include/_CachingSpanFilter.h +++ b/src/core/include/_CachingSpanFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,7 +16,7 @@ namespace Lucene public: FilterCacheSpanFilterResult(CachingWrapperFilter::DeletesMode deletesMode); virtual ~FilterCacheSpanFilterResult(); - + LUCENE_CLASS(FilterCacheSpanFilterResult); protected: diff --git a/src/core/include/_CachingWrapperFilter.h b/src/core/include/_CachingWrapperFilter.h index 5ccb1e81..e246f5db 100644 --- a/src/core/include/_CachingWrapperFilter.h +++ b/src/core/include/_CachingWrapperFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,7 +16,7 @@ namespace Lucene public: FilterCache(CachingWrapperFilter::DeletesMode deletesMode); virtual ~FilterCache(); - + LUCENE_CLASS(FilterCache); public: @@ -26,34 +26,34 @@ namespace Lucene public: virtual LuceneObjectPtr get(IndexReaderPtr reader, LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey); virtual void put(LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey, LuceneObjectPtr value); - + protected: virtual LuceneObjectPtr mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value) = 0; }; - + class FilterCacheDocIdSet : public FilterCache { public: FilterCacheDocIdSet(CachingWrapperFilter::DeletesMode deletesMode); virtual ~FilterCacheDocIdSet(); - + LUCENE_CLASS(FilterCacheDocIdSet); protected: virtual LuceneObjectPtr mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value); }; - + class FilteredCacheDocIdSet : public FilteredDocIdSet { public: FilteredCacheDocIdSet(IndexReaderPtr reader, DocIdSetPtr innerSet); virtual ~FilteredCacheDocIdSet(); - + LUCENE_CLASS(FilteredCacheDocIdSet); - + protected: IndexReaderPtr reader; - + protected: virtual bool match(int32_t docid); }; diff --git a/src/core/include/_CheckIndex.h b/src/core/include/_CheckIndex.h index 0f2556a2..a279b7de 100644 --- a/src/core/include/_CheckIndex.h +++ b/src/core/include/_CheckIndex.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,12 +16,12 @@ namespace Lucene public: MySegmentTermDocs(SegmentReaderPtr p); virtual ~MySegmentTermDocs(); - + LUCENE_CLASS(MySegmentTermDocs); - + public: int32_t delCount; - + public: virtual void seek(TermPtr term); virtual void skippingDoc(); diff --git a/src/core/include/_ConcurrentMergeScheduler.h b/src/core/include/_ConcurrentMergeScheduler.h index 315859ff..69568ebf 100644 --- a/src/core/include/_ConcurrentMergeScheduler.h +++ b/src/core/include/_ConcurrentMergeScheduler.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,15 +16,15 @@ namespace Lucene public: MergeThread(ConcurrentMergeSchedulerPtr merger, IndexWriterPtr writer, OneMergePtr startMerge); virtual ~MergeThread(); - + LUCENE_CLASS(MergeThread); - + protected: ConcurrentMergeSchedulerWeakPtr _merger; IndexWriterWeakPtr _writer; OneMergePtr startMerge; OneMergePtr runningMerge; - + public: void setRunningMerge(OneMergePtr merge); OneMergePtr getRunningMerge(); diff --git a/src/core/include/_ConstantScoreQuery.h b/src/core/include/_ConstantScoreQuery.h index 456d3bb1..46c0a9cb 100644 --- a/src/core/include/_ConstantScoreQuery.h +++ b/src/core/include/_ConstantScoreQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,15 +16,15 @@ namespace Lucene public: ConstantWeight(ConstantScoreQueryPtr constantScorer, SearcherPtr searcher); virtual ~ConstantWeight(); - + LUCENE_CLASS(ConstantWeight); - + protected: ConstantScoreQueryPtr constantScorer; SimilarityPtr similarity; double queryNorm; double queryWeight; - + public: virtual QueryPtr getQuery(); virtual double getValue(); @@ -33,20 +33,20 @@ namespace Lucene virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); }; - + class ConstantScorer : public Scorer { public: ConstantScorer(ConstantScoreQueryPtr constantScorer, SimilarityPtr similarity, IndexReaderPtr reader, WeightPtr w); virtual ~ConstantScorer(); - + LUCENE_CLASS(ConstantScorer); - + public: DocIdSetIteratorPtr docIdSetIterator; double theScore; int32_t doc; - + public: virtual int32_t nextDoc(); virtual int32_t docID(); diff --git a/src/core/include/_CustomScoreQuery.h b/src/core/include/_CustomScoreQuery.h index 9f276823..3c7d71e7 100644 --- a/src/core/include/_CustomScoreQuery.h +++ b/src/core/include/_CustomScoreQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,34 +19,34 @@ namespace Lucene public: DefaultCustomScoreProvider(CustomScoreQueryPtr customQuery, IndexReaderPtr reader); virtual ~DefaultCustomScoreProvider(); - + LUCENE_CLASS(DefaultCustomScoreProvider); - + protected: CustomScoreQueryWeakPtr _customQuery; - + public: virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls); virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl); }; - + class CustomWeight : public Weight { public: CustomWeight(CustomScoreQueryPtr query, SearcherPtr searcher); virtual ~CustomWeight(); - + LUCENE_CLASS(CustomWeight); - + public: CustomScoreQueryPtr query; SimilarityPtr similarity; WeightPtr subQueryWeight; Collection valSrcWeights; bool qStrict; - + public: virtual QueryPtr getQuery(); virtual double getValue(); @@ -55,28 +55,28 @@ namespace Lucene virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); virtual bool scoresDocsOutOfOrder(); - + protected: ExplanationPtr doExplain(IndexReaderPtr reader, int32_t doc); }; - + /// A scorer that applies a (callback) function on scores of the subQuery. class CustomScorer : public Scorer { public: CustomScorer(SimilarityPtr similarity, IndexReaderPtr reader, CustomWeightPtr weight, ScorerPtr subQueryScorer, Collection valSrcScorers); virtual ~CustomScorer(); - + LUCENE_CLASS(CustomScorer); - + protected: double qWeight; ScorerPtr subQueryScorer; Collection valSrcScorers; IndexReaderPtr reader; CustomScoreProviderPtr provider; - Collection vScores; // reused in score() to avoid allocating this array for each doc - + Collection vScores; // reused in score() to avoid allocating this array for each doc + public: virtual int32_t nextDoc(); virtual int32_t docID(); diff --git a/src/core/include/_DirectoryReader.h b/src/core/include/_DirectoryReader.h index 20e82732..0d240d4e 100644 --- a/src/core/include/_DirectoryReader.h +++ b/src/core/include/_DirectoryReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,31 +16,31 @@ namespace Lucene public: FindSegmentsOpen(bool readOnly, IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor, SegmentInfosPtr infos, DirectoryPtr directory); virtual ~FindSegmentsOpen(); - + LUCENE_CLASS(FindSegmentsOpen); - + protected: bool readOnly; IndexDeletionPolicyPtr deletionPolicy; int32_t termInfosIndexDivisor; - + public: virtual IndexReaderPtr doBody(const String& segmentFileName); }; - + class FindSegmentsReopen : public FindSegmentsFileT { public: FindSegmentsReopen(DirectoryReaderPtr reader, bool openReadOnly, SegmentInfosPtr infos, DirectoryPtr directory); virtual ~FindSegmentsReopen(); - + LUCENE_CLASS(FindSegmentsReopen); - + protected: DirectoryReaderWeakPtr _reader; bool openReadOnly; - - public: + + public: virtual DirectoryReaderPtr doBody(const String& segmentFileName); }; } diff --git a/src/core/include/_DisjunctionMaxQuery.h b/src/core/include/_DisjunctionMaxQuery.h index 71da9684..dde594fe 100644 --- a/src/core/include/_DisjunctionMaxQuery.h +++ b/src/core/include/_DisjunctionMaxQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,37 +18,37 @@ namespace Lucene /// Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. DisjunctionMaxWeight(DisjunctionMaxQueryPtr query, SearcherPtr searcher); virtual ~DisjunctionMaxWeight(); - + LUCENE_CLASS(DisjunctionMaxWeight); - + protected: DisjunctionMaxQueryPtr query; - + /// The Similarity implementation. SimilarityPtr similarity; - + /// The Weights for our subqueries, in 1-1 correspondence with disjuncts Collection weights; - + public: /// Return our associated DisjunctionMaxQuery virtual QueryPtr getQuery(); - + /// Return our boost virtual double getValue(); - + /// Compute the sub of squared weights of us applied to our subqueries. Used for normalization. virtual double sumOfSquaredWeights(); - + /// Apply the computed normalization factor to our subqueries virtual void normalize(double norm); - + /// Create the scorer used to score our associated DisjunctionMaxQuery virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - + /// Explain the score we computed for doc virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); - }; + }; } #endif diff --git a/src/core/include/_DocIdBitSet.h b/src/core/include/_DocIdBitSet.h index 92afe0c3..9ffff066 100644 --- a/src/core/include/_DocIdBitSet.h +++ b/src/core/include/_DocIdBitSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,13 +16,13 @@ namespace Lucene public: DocIdBitSetIterator(BitSetPtr bitSet); virtual ~DocIdBitSetIterator(); - + LUCENE_CLASS(DocIdBitSetIterator); - + protected: int32_t docId; BitSetPtr bitSet; - + public: virtual int32_t docID(); virtual int32_t nextDoc(); diff --git a/src/core/include/_DocIdSet.h b/src/core/include/_DocIdSet.h index 8afb44e6..3cf2bc98 100644 --- a/src/core/include/_DocIdSet.h +++ b/src/core/include/_DocIdSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,20 +16,20 @@ namespace Lucene public: virtual ~EmptyDocIdSetIterator(); LUCENE_CLASS(EmptyDocIdSetIterator); - + public: virtual int32_t advance(int32_t target); virtual int32_t docID(); virtual int32_t nextDoc(); }; - + /// An empty {@code DocIdSet} instance for easy use, eg. in Filters that hit no documents. class EmptyDocIdSet : public DocIdSet { public: virtual ~EmptyDocIdSet(); LUCENE_CLASS(EmptyDocIdSet); - + public: virtual DocIdSetIteratorPtr iterator(); virtual bool isCacheable(); diff --git a/src/core/include/_FieldCache.h b/src/core/include/_FieldCache.h index 12d8b641..76d38e0d 100644 --- a/src/core/include/_FieldCache.h +++ b/src/core/include/_FieldCache.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,79 +17,79 @@ namespace Lucene public: virtual ~DefaultByteParser(); LUCENE_CLASS(DefaultByteParser); - + public: virtual uint8_t parseByte(const String& string); virtual String toString(); }; - + /// @see FieldCache#DEFAULT_INT_PARSER() class DefaultIntParser : public IntParser { public: virtual ~DefaultIntParser(); LUCENE_CLASS(DefaultIntParser); - + public: virtual int32_t parseInt(const String& string); virtual String toString(); }; - + /// @see FieldCache#NUMERIC_UTILS_INT_PARSER() class NumericUtilsIntParser : public IntParser { public: virtual ~NumericUtilsIntParser(); LUCENE_CLASS(NumericUtilsIntParser); - + public: virtual int32_t parseInt(const String& string); virtual String toString(); }; - + /// @see FieldCache#DEFAULT_LONG_PARSER() class DefaultLongParser : public LongParser { public: virtual ~DefaultLongParser(); LUCENE_CLASS(DefaultLongParser); - + public: virtual int64_t parseLong(const String& string); virtual String toString(); }; - + /// @see FieldCache#NUMERIC_UTILS_LONG_PARSER() class NumericUtilsLongParser : public LongParser { public: virtual ~NumericUtilsLongParser(); LUCENE_CLASS(NumericUtilsLongParser); - + public: virtual int64_t parseLong(const String& string); virtual String toString(); }; - + /// @see FieldCache#DEFAULT_DOUBLE_PARSER() class DefaultDoubleParser : public DoubleParser { public: virtual ~DefaultDoubleParser(); LUCENE_CLASS(DefaultDoubleParser); - + public: virtual double parseDouble(const String& string); virtual String toString(); }; - + /// @see FieldCache#NUMERIC_UTILS_DOUBLE_PARSER() class NumericUtilsDoubleParser : public DoubleParser { public: virtual ~NumericUtilsDoubleParser(); LUCENE_CLASS(NumericUtilsDoubleParser); - + public: virtual double parseDouble(const String& string); virtual String toString(); diff --git a/src/core/include/_FieldCacheRangeFilter.h b/src/core/include/_FieldCacheRangeFilter.h index ba44022c..ddf2a759 100644 --- a/src/core/include/_FieldCacheRangeFilter.h +++ b/src/core/include/_FieldCacheRangeFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,43 +20,43 @@ namespace Lucene public: FieldCacheRangeFilterString(const String& field, ParserPtr parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterString(); - + LUCENE_CLASS(FieldCacheRangeFilterString); - + public: String lowerVal; String upperVal; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); - + virtual String toString(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); }; - + class FieldCacheDocIdSet : public DocIdSet { public: FieldCacheDocIdSet(IndexReaderPtr reader, bool mayUseTermDocs); virtual ~FieldCacheDocIdSet(); - + LUCENE_CLASS(FieldCacheDocIdSet); - + protected: IndexReaderPtr reader; bool mayUseTermDocs; - + public: /// This method checks, if a doc is a hit, should throw ArrayIndexOutOfBounds, when position invalid virtual bool matchDoc(int32_t doc) = 0; - + /// This DocIdSet is cacheable, if it works solely with FieldCache and no TermDocs. virtual bool isCacheable(); - + virtual DocIdSetIteratorPtr iterator(); }; - + template class FieldCacheDocIdSetNumeric : public FieldCacheDocIdSet { @@ -67,16 +67,16 @@ namespace Lucene this->inclusiveLowerPoint = inclusiveLowerPoint; this->inclusiveUpperPoint = inclusiveUpperPoint; } - + virtual ~FieldCacheDocIdSetNumeric() { } - + protected: Collection values; TYPE inclusiveLowerPoint; TYPE inclusiveUpperPoint; - + public: virtual bool matchDoc(int32_t doc) { @@ -84,8 +84,8 @@ namespace Lucene boost::throw_exception(IndexOutOfBoundsException()); return (values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint); } - }; - + }; + template class FieldCacheRangeFilterNumeric : public FieldCacheRangeFilter { @@ -96,36 +96,36 @@ namespace Lucene this->upperVal = upperVal; this->maxVal = maxVal; } - + virtual ~FieldCacheRangeFilterNumeric() { } - + public: TYPE lowerVal; TYPE upperVal; TYPE maxVal; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) { if (!includeLower && lowerVal == maxVal) return DocIdSet::EMPTY_DOCIDSET(); int64_t inclusiveLowerPoint = (int64_t)(includeLower ? lowerVal : (lowerVal + 1)); - + if (!includeUpper && upperVal == 0) return DocIdSet::EMPTY_DOCIDSET(); int64_t inclusiveUpperPoint = (int64_t)(includeUpper ? upperVal : (upperVal - 1)); - + if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet::EMPTY_DOCIDSET(); - + // we only request the usage of termDocs, if the range contains 0 return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); } - + virtual Collection getValues(IndexReaderPtr reader) = 0; - + virtual String toString() { StringStream buffer; @@ -134,7 +134,7 @@ namespace Lucene buffer << (includeLower ? L"]" : L"}"); return buffer.str(); } - + virtual bool equals(LuceneObjectPtr other) { if (Filter::equals(other)) @@ -150,7 +150,7 @@ namespace Lucene return false; return true; } - + int32_t hashCode() { int32_t code = StringUtils::hashCode(field); @@ -162,107 +162,107 @@ namespace Lucene return code; } }; - + class FieldCacheRangeFilterByte : public FieldCacheRangeFilterNumeric { public: FieldCacheRangeFilterByte(const String& field, ParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterByte(); - + LUCENE_CLASS(FieldCacheRangeFilterByte); - + public: virtual Collection getValues(IndexReaderPtr reader); }; - + class FieldCacheRangeFilterInt : public FieldCacheRangeFilterNumeric { public: FieldCacheRangeFilterInt(const String& field, ParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterInt(); - + LUCENE_CLASS(FieldCacheRangeFilterInt); - + public: virtual Collection getValues(IndexReaderPtr reader); }; - + class FieldCacheRangeFilterLong : public FieldCacheRangeFilterNumeric { public: FieldCacheRangeFilterLong(const String& field, ParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterLong(); - + LUCENE_CLASS(FieldCacheRangeFilterLong); - + public: virtual Collection getValues(IndexReaderPtr reader); }; - + class FieldCacheRangeFilterDouble : public FieldCacheRangeFilterNumeric { public: FieldCacheRangeFilterDouble(const String& field, ParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterDouble(); - + LUCENE_CLASS(FieldCacheRangeFilterDouble); - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); virtual Collection getValues(IndexReaderPtr reader); }; - + class FieldCacheDocIdSetString : public FieldCacheDocIdSet { public: FieldCacheDocIdSetString(IndexReaderPtr reader, bool mayUseTermDocs, StringIndexPtr fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint); virtual ~FieldCacheDocIdSetString(); - + LUCENE_CLASS(FieldCacheDocIdSetString); - + protected: StringIndexPtr fcsi; int32_t inclusiveLowerPoint; int32_t inclusiveUpperPoint; - + public: virtual bool matchDoc(int32_t doc); }; - + /// A DocIdSetIterator using TermDocs to iterate valid docIds class FieldDocIdSetIteratorTermDocs : public DocIdSetIterator { public: FieldDocIdSetIteratorTermDocs(FieldCacheDocIdSetPtr cacheDocIdSet, TermDocsPtr termDocs); virtual ~FieldDocIdSetIteratorTermDocs(); - + LUCENE_CLASS(FieldDocIdSetIteratorTermDocs); - + protected: FieldCacheDocIdSetWeakPtr _cacheDocIdSet; TermDocsPtr termDocs; int32_t doc; - + public: virtual int32_t docID(); virtual int32_t nextDoc(); virtual int32_t advance(int32_t target); }; - - /// A DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there + + /// A DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there /// are no deletions are on the index. class FieldDocIdSetIteratorIncrement : public DocIdSetIterator { public: FieldDocIdSetIteratorIncrement(FieldCacheDocIdSetPtr cacheDocIdSet); virtual ~FieldDocIdSetIteratorIncrement(); - + LUCENE_CLASS(FieldDocIdSetIteratorIncrement); - + protected: FieldCacheDocIdSetWeakPtr _cacheDocIdSet; int32_t doc; - + public: virtual int32_t docID(); virtual int32_t nextDoc(); diff --git a/src/core/include/_FieldCacheSanityChecker.h b/src/core/include/_FieldCacheSanityChecker.h index 423b2333..11ee4941 100644 --- a/src/core/include/_FieldCacheSanityChecker.h +++ b/src/core/include/_FieldCacheSanityChecker.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,13 +17,13 @@ namespace Lucene public: ReaderField(LuceneObjectPtr readerKey, const String& fieldName); virtual ~ReaderField(); - + LUCENE_CLASS(ReaderField); - + public: LuceneObjectPtr readerKey; String fieldName; - + public: virtual int32_t hashCode(); virtual bool equals(LuceneObjectPtr other); diff --git a/src/core/include/_FieldCacheTermsFilter.h b/src/core/include/_FieldCacheTermsFilter.h index aff3fffa..808c3e4b 100644 --- a/src/core/include/_FieldCacheTermsFilter.h +++ b/src/core/include/_FieldCacheTermsFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,33 +17,33 @@ namespace Lucene public: FieldCacheTermsFilterDocIdSet(Collection terms, StringIndexPtr fcsi); virtual ~FieldCacheTermsFilterDocIdSet(); - + LUCENE_CLASS(FieldCacheTermsFilterDocIdSet); - + protected: StringIndexPtr fcsi; OpenBitSetPtr openBitSet; - + public: virtual DocIdSetIteratorPtr iterator(); - + /// This DocIdSet implementation is cacheable. virtual bool isCacheable(); }; - + class FieldCacheTermsFilterDocIdSetIterator : public DocIdSetIterator { public: FieldCacheTermsFilterDocIdSetIterator(StringIndexPtr fcsi, OpenBitSetPtr openBitSet); virtual ~FieldCacheTermsFilterDocIdSetIterator(); - + LUCENE_CLASS(FieldCacheTermsFilterDocIdSetIterator); - + protected: StringIndexPtr fcsi; OpenBitSetPtr openBitSet; int32_t doc; - + public: virtual int32_t docID(); virtual int32_t nextDoc(); diff --git a/src/core/include/_FieldValueHitQueue.h b/src/core/include/_FieldValueHitQueue.h index aef20d3f..c104f243 100644 --- a/src/core/include/_FieldValueHitQueue.h +++ b/src/core/include/_FieldValueHitQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,26 +17,26 @@ namespace Lucene public: OneComparatorFieldValueHitQueue(Collection fields, int32_t size); virtual ~OneComparatorFieldValueHitQueue(); - + LUCENE_CLASS(OneComparatorFieldValueHitQueue); - + public: FieldComparatorPtr comparator; int32_t oneReverseMul; - + protected: virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); }; - + /// An implementation of {@link FieldValueHitQueue} which is optimized in case there is more than one comparator. class MultiComparatorsFieldValueHitQueue : public FieldValueHitQueue { public: MultiComparatorsFieldValueHitQueue(Collection fields, int32_t size); virtual ~MultiComparatorsFieldValueHitQueue(); - + LUCENE_CLASS(MultiComparatorsFieldValueHitQueue); - + protected: virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); }; diff --git a/src/core/include/_FilterManager.h b/src/core/include/_FilterManager.h index 2f7d8a34..c981909e 100644 --- a/src/core/include/_FilterManager.h +++ b/src/core/include/_FilterManager.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,36 +17,36 @@ namespace Lucene public: FilterItem(FilterPtr filter); virtual ~FilterItem(); - + LUCENE_CLASS(FilterItem); - + public: FilterPtr filter; int64_t timestamp; }; - + /// Keeps the cache from getting too big. /// - /// The SortedSet sortedFilterItems is used only to sort the items from the cache, so when it's time to clean + /// The SortedSet sortedFilterItems is used only to sort the items from the cache, so when it's time to clean /// up we have the TreeSet sort the FilterItems by timestamp. /// - /// Removes 1.5 * the numbers of items to make the cache smaller. - /// For example: If cache clean size is 10, and the cache is at 15, we would remove (15 - 10) * 1.5 = 7.5 - /// round up to 8. This way we clean the cache a bit more, and avoid having the cache cleaner having to do + /// Removes 1.5 * the numbers of items to make the cache smaller. + /// For example: If cache clean size is 10, and the cache is at 15, we would remove (15 - 10) * 1.5 = 7.5 + /// round up to 8. This way we clean the cache a bit more, and avoid having the cache cleaner having to do /// it frequently. class FilterCleaner : public LuceneThread { public: FilterCleaner(FilterManagerPtr manager); virtual ~FilterCleaner(); - + LUCENE_CLASS(FilterCleaner); - + protected: FilterManagerWeakPtr _manager; bool running; MapLongInt sortedFilterItems; - + public: virtual void run(); }; diff --git a/src/core/include/_FilteredDocIdSet.h b/src/core/include/_FilteredDocIdSet.h index 19fde802..033e30f3 100644 --- a/src/core/include/_FilteredDocIdSet.h +++ b/src/core/include/_FilteredDocIdSet.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,12 +17,12 @@ namespace Lucene public: DefaultFilteredDocIdSetIterator(FilteredDocIdSetPtr filtered, DocIdSetIteratorPtr innerIter); virtual ~DefaultFilteredDocIdSetIterator(); - + LUCENE_CLASS(DefaultFilteredDocIdSetIterator); - + protected: FilteredDocIdSetPtr filtered; - + protected: virtual bool match(int32_t docid); }; diff --git a/src/core/include/_FilteredQuery.h b/src/core/include/_FilteredQuery.h index 726a3751..d74b8ed2 100644 --- a/src/core/include/_FilteredQuery.h +++ b/src/core/include/_FilteredQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,15 +17,15 @@ namespace Lucene public: FilteredQueryWeight(FilteredQueryPtr query, WeightPtr weight, SimilarityPtr similarity); virtual ~FilteredQueryWeight(); - + LUCENE_CLASS(FilteredQueryWeight); - + protected: FilteredQueryPtr query; WeightPtr weight; SimilarityPtr similarity; double value; - + public: virtual double getValue(); virtual double sumOfSquaredWeights(); @@ -33,30 +33,30 @@ namespace Lucene virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); virtual QueryPtr getQuery(); virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - + friend class FilteredQueryWeightScorer; }; - + class FilteredQueryWeightScorer : public Scorer { public: FilteredQueryWeightScorer(FilteredQueryWeightPtr weight, ScorerPtr scorer, DocIdSetIteratorPtr docIdSetIterator, SimilarityPtr similarity); virtual ~FilteredQueryWeightScorer(); - + LUCENE_CLASS(FilteredQueryWeightScorer); - + protected: FilteredQueryWeightPtr weight; ScorerPtr scorer; DocIdSetIteratorPtr docIdSetIterator; int32_t doc; - + public: virtual int32_t nextDoc(); virtual int32_t docID(); virtual int32_t advance(int32_t target); virtual double score(); - + protected: int32_t advanceToCommon(int32_t scorerDoc, int32_t disiDoc); }; diff --git a/src/core/include/_FuzzyQuery.h b/src/core/include/_FuzzyQuery.h index d2705298..a5ecc6fb 100644 --- a/src/core/include/_FuzzyQuery.h +++ b/src/core/include/_FuzzyQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,23 +16,23 @@ namespace Lucene public: virtual ~ScoreTerm(); LUCENE_CLASS(ScoreTerm); - + public: TermPtr term; double score; - + public: int32_t compareTo(ScoreTermPtr other); }; - + class ScoreTermQueue : public PriorityQueue { public: ScoreTermQueue(int32_t size); virtual ~ScoreTermQueue(); - + LUCENE_CLASS(ScoreTermQueue); - + protected: virtual bool lessThan(const ScoreTermPtr& first, const ScoreTermPtr& second); }; diff --git a/src/core/include/_IndexReader.h b/src/core/include/_IndexReader.h index 4f819111..ac243c7a 100644 --- a/src/core/include/_IndexReader.h +++ b/src/core/include/_IndexReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: FindSegmentsModified(SegmentInfosPtr infos, DirectoryPtr directory); virtual ~FindSegmentsModified(); - + LUCENE_CLASS(FindSegmentsModified); - + public: virtual uint64_t doBody(const String& segmentFileName); }; diff --git a/src/core/include/_IndexWriter.h b/src/core/include/_IndexWriter.h index 1070cc3b..93b59477 100644 --- a/src/core/include/_IndexWriter.h +++ b/src/core/include/_IndexWriter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,54 +11,54 @@ namespace Lucene { - /// Holds shared SegmentReader instances. IndexWriter uses SegmentReaders for 1) applying deletes, - /// 2) doing merges, 3) handing out a real-time reader. This pool reuses instances of the SegmentReaders + /// Holds shared SegmentReader instances. IndexWriter uses SegmentReaders for 1) applying deletes, + /// 2) doing merges, 3) handing out a real-time reader. This pool reuses instances of the SegmentReaders /// in all these places if it is in "near real-time mode" (getReader() has been called on this instance). class ReaderPool : public LuceneObject { public: ReaderPool(IndexWriterPtr writer); virtual ~ReaderPool(); - + LUCENE_CLASS(ReaderPool); - + protected: IndexWriterWeakPtr _indexWriter; MapSegmentInfoSegmentReader readerMap; - + public: - /// Forcefully clear changes for the specified segments, and remove from the pool. + /// Forcefully clear changes for the specified segments, and remove from the pool. /// This is called on successful merge. void clear(SegmentInfosPtr infos); - + /// used only by asserts bool infoIsLive(SegmentInfoPtr info); SegmentInfoPtr mapToLive(SegmentInfoPtr info); - + /// Release the segment reader (i.e. decRef it and close if there are no more references. void release(SegmentReaderPtr sr); - + /// Release the segment reader (i.e. decRef it and close if there are no more references. void release(SegmentReaderPtr sr, bool drop); - + /// Remove all our references to readers, and commits any pending changes. void close(); - + /// Commit all segment reader in the pool. void commit(); - - /// Returns a ref to a clone. NOTE: this clone is not enrolled in the pool, so you should + + /// Returns a ref to a clone. NOTE: this clone is not enrolled in the pool, so you should /// simply close() it when you're done (ie, do not call release()). IndexReaderPtr getReadOnlyClone(const SegmentInfoPtr info, bool doOpenStores, int32_t termInfosIndexDivisor); - - /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling + + /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling /// {@link #release(SegmentReader)} SegmentReaderPtr get(SegmentInfoPtr info, bool doOpenStores); - - /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling + + /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling /// {@link #release(SegmentReader)} SegmentReaderPtr get(SegmentInfoPtr info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor); - + /// Returns a ref SegmentReaderPtr getIfExists(SegmentInfoPtr info); }; diff --git a/src/core/include/_IntFieldSource.h b/src/core/include/_IntFieldSource.h index b016a066..b7227da3 100644 --- a/src/core/include/_IntFieldSource.h +++ b/src/core/include/_IntFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,13 +16,13 @@ namespace Lucene public: IntDocValues(IntFieldSourcePtr source, Collection arr); virtual ~IntDocValues(); - + LUCENE_CLASS(IntDocValues); - + protected: IntFieldSourceWeakPtr _source; Collection arr; - + public: virtual double doubleVal(int32_t doc); virtual int32_t intVal(int32_t doc); diff --git a/src/core/include/_MMapDirectory.h b/src/core/include/_MMapDirectory.h index 19de2b8e..9778ea8c 100644 --- a/src/core/include/_MMapDirectory.h +++ b/src/core/include/_MMapDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,41 +17,41 @@ namespace Lucene public: MMapIndexInput(const String& path = L""); virtual ~MMapIndexInput(); - + LUCENE_CLASS(MMapIndexInput); - + protected: int32_t _length; bool isClone; boost::iostreams::mapped_file_source file; int32_t bufferPosition; // next byte to read - + public: /// Reads and returns a single byte. /// @see IndexOutput#writeByte(uint8_t) virtual uint8_t readByte(); - + /// Reads a specified number of bytes into an array at the specified offset. /// @param b the array to read bytes into. /// @param offset the offset in the array to start storing bytes. /// @param length the number of bytes to read. /// @see IndexOutput#writeBytes(const uint8_t*,int) virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - + /// Returns the current position in this file, where the next read will occur. /// @see #seek(int64_t) virtual int64_t getFilePointer(); - + /// Sets current position in this file, where the next read will occur. /// @see #getFilePointer() virtual void seek(int64_t pos); - + /// The number of bytes in the file. virtual int64_t length(); - + /// Closes the stream to further operations. virtual void close(); - + /// Returns a clone of this stream. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); }; diff --git a/src/core/include/_MatchAllDocsQuery.h b/src/core/include/_MatchAllDocsQuery.h index 058e5dc3..1c91e2ad 100644 --- a/src/core/include/_MatchAllDocsQuery.h +++ b/src/core/include/_MatchAllDocsQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,15 +17,15 @@ namespace Lucene public: MatchAllDocsWeight(MatchAllDocsQueryPtr query, SearcherPtr searcher); virtual ~MatchAllDocsWeight(); - + LUCENE_CLASS(MatchAllDocsWeight); - + protected: MatchAllDocsQueryPtr query; SimilarityPtr similarity; double queryWeight; double queryNorm; - + public: virtual String toString(); virtual QueryPtr getQuery(); @@ -35,24 +35,24 @@ namespace Lucene virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); }; - + class MatchAllScorer : public Scorer { public: MatchAllScorer(MatchAllDocsQueryPtr query, IndexReaderPtr reader, SimilarityPtr similarity, WeightPtr weight, ByteArray norms); virtual ~MatchAllScorer(); - + LUCENE_CLASS(MatchAllScorer); - + public: TermDocsPtr termDocs; double _score; ByteArray norms; - + protected: MatchAllDocsQueryPtr query; int32_t doc; - + public: virtual int32_t docID(); virtual int32_t nextDoc(); diff --git a/src/core/include/_MultiPhraseQuery.h b/src/core/include/_MultiPhraseQuery.h index 207eb56b..60748c83 100644 --- a/src/core/include/_MultiPhraseQuery.h +++ b/src/core/include/_MultiPhraseQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: MultiPhraseWeight(MultiPhraseQueryPtr query, SearcherPtr searcher); virtual ~MultiPhraseWeight(); - + LUCENE_CLASS(MultiPhraseWeight); - + protected: MultiPhraseQueryPtr query; SimilarityPtr similarity; @@ -26,7 +26,7 @@ namespace Lucene double idf; double queryNorm; double queryWeight; - + public: virtual QueryPtr getQuery(); virtual double getValue(); diff --git a/src/core/include/_MultiSearcher.h b/src/core/include/_MultiSearcher.h index 5d41ea8e..02d2c4c4 100644 --- a/src/core/include/_MultiSearcher.h +++ b/src/core/include/_MultiSearcher.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,20 +12,20 @@ namespace Lucene { - /// Document Frequency cache acting as a Dummy-Searcher. This class is not a full-fledged Searcher, but + /// Document Frequency cache acting as a Dummy-Searcher. This class is not a full-fledged Searcher, but /// only supports the methods necessary to initialize Weights. class CachedDfSource : public Searcher { public: CachedDfSource(MapTermInt dfMap, int32_t maxDoc, SimilarityPtr similarity); virtual ~CachedDfSource(); - + LUCENE_CLASS(CachedDfSource); - + protected: MapTermInt dfMap; // Map from Terms to corresponding doc freqs int32_t _maxDoc; // document count - + public: virtual int32_t docFreq(TermPtr term); virtual Collection docFreqs(Collection terms); @@ -44,12 +44,12 @@ namespace Lucene class MultiSearcherCallableNoSort : public LuceneObject { public: - MultiSearcherCallableNoSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, FilterPtr filter, int32_t nDocs, + MultiSearcherCallableNoSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, FilterPtr filter, int32_t nDocs, HitQueuePtr hq, int32_t i, Collection starts); virtual ~MultiSearcherCallableNoSort(); - + LUCENE_CLASS(MultiSearcherCallableNoSort); - + protected: SynchronizePtr lock; SearchablePtr searchable; @@ -59,21 +59,21 @@ namespace Lucene int32_t i; HitQueuePtr hq; Collection starts; - + public: TopDocsPtr call(); }; - + /// A subclass for searching a single searchable class MultiSearcherCallableWithSort : public LuceneObject { public: - MultiSearcherCallableWithSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, FilterPtr filter, + MultiSearcherCallableWithSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, FilterPtr filter, int32_t nDocs, FieldDocSortedHitQueuePtr hq, SortPtr sort, int32_t i, Collection starts); virtual ~MultiSearcherCallableWithSort(); - + LUCENE_CLASS(MultiSearcherCallableWithSort); - + protected: SynchronizePtr lock; SearchablePtr searchable; @@ -84,23 +84,23 @@ namespace Lucene FieldDocSortedHitQueuePtr hq; Collection starts; SortPtr sort; - + public: TopFieldDocsPtr call(); }; - + class MultiSearcherCollector : public Collector { public: MultiSearcherCollector(CollectorPtr collector, int32_t start); virtual ~MultiSearcherCollector(); - + LUCENE_CLASS(MultiSearcherCollector); - + protected: CollectorPtr collector; int32_t start; - + public: virtual void setScorer(ScorerPtr scorer); virtual void collect(int32_t doc); diff --git a/src/core/include/_MultiTermQuery.h b/src/core/include/_MultiTermQuery.h index 3f906fb9..5ee5695d 100644 --- a/src/core/include/_MultiTermQuery.h +++ b/src/core/include/_MultiTermQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,37 +16,37 @@ namespace Lucene public: virtual ~ConstantScoreFilterRewrite(); LUCENE_CLASS(ConstantScoreFilterRewrite); - + public: virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query); }; - + class ScoringBooleanQueryRewrite : public RewriteMethod { public: virtual ~ScoringBooleanQueryRewrite(); LUCENE_CLASS(ScoringBooleanQueryRewrite); - + public: virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query); }; - + class ConstantScoreBooleanQueryRewrite : public ScoringBooleanQueryRewrite { public: virtual ~ConstantScoreBooleanQueryRewrite(); LUCENE_CLASS(ConstantScoreBooleanQueryRewrite); - + public: virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query); }; - + class ConstantScoreAutoRewriteDefault : public ConstantScoreAutoRewrite { public: virtual ~ConstantScoreAutoRewriteDefault(); LUCENE_CLASS(ConstantScoreAutoRewriteDefault); - + public: virtual void setTermCountCutoff(int32_t count); virtual void setDocCountPercent(double percent); diff --git a/src/core/include/_MultipleTermPositions.h b/src/core/include/_MultipleTermPositions.h index c5e7f197..b99d9c03 100644 --- a/src/core/include/_MultipleTermPositions.h +++ b/src/core/include/_MultipleTermPositions.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,40 +16,40 @@ namespace Lucene public: TermPositionsQueue(Collection termPositions); virtual ~TermPositionsQueue(); - + LUCENE_CLASS(TermPositionsQueue); - + protected: Collection termPositions; - + public: virtual void initialize(); - + protected: virtual bool lessThan(const TermPositionsPtr& first, const TermPositionsPtr& second); }; - + class IntQueue : public LuceneObject { public: IntQueue(); virtual ~IntQueue(); - + LUCENE_CLASS(IntQueue); - + protected: int32_t arraySize; int32_t index; int32_t lastIndex; Collection array; - + public: void add(int32_t i); int32_t next(); void sort(); void clear(); int32_t size(); - + protected: void growArray(); }; diff --git a/src/core/include/_NativeFSLockFactory.h b/src/core/include/_NativeFSLockFactory.h index ae3f3c81..c0f0904a 100644 --- a/src/core/include/_NativeFSLockFactory.h +++ b/src/core/include/_NativeFSLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,23 +16,23 @@ namespace Lucene public: NativeFSLock(const String& lockDir, const String& lockFileName); virtual ~NativeFSLock(); - + LUCENE_CLASS(NativeFSLock); - + protected: String lockDir; String path; filelockPtr lock; - + static SynchronizePtr LOCK_HELD_LOCK(); static HashSet LOCK_HELD(); - + public: virtual bool obtain(); virtual void release(); virtual bool isLocked(); virtual String toString(); - + protected: bool lockExists(); }; diff --git a/src/core/include/_NearSpansUnordered.h b/src/core/include/_NearSpansUnordered.h index 98329370..16f184a9 100644 --- a/src/core/include/_NearSpansUnordered.h +++ b/src/core/include/_NearSpansUnordered.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,16 +18,16 @@ namespace Lucene public: SpansCell(NearSpansUnorderedPtr unordered, SpansPtr spans, int32_t index); virtual ~SpansCell(); - + LUCENE_CLASS(SpansCell); - + protected: NearSpansUnorderedWeakPtr _unordered; SpansPtr spans; SpansCellPtr _next; int32_t length; int32_t index; - + public: virtual bool next(); virtual bool skipTo(int32_t target); @@ -37,21 +37,21 @@ namespace Lucene virtual Collection getPayload(); virtual bool isPayloadAvailable(); virtual String toString(); - + protected: bool adjust(bool condition); - + friend class NearSpansUnordered; }; - + class CellQueue : public PriorityQueue { public: CellQueue(int32_t size); virtual ~CellQueue(); - + LUCENE_CLASS(CellQueue); - + protected: virtual bool lessThan(const SpansCellPtr& first, const SpansCellPtr& second); }; diff --git a/src/core/include/_NoLockFactory.h b/src/core/include/_NoLockFactory.h index 5de9edf7..b766af6e 100644 --- a/src/core/include/_NoLockFactory.h +++ b/src/core/include/_NoLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,9 +15,9 @@ namespace Lucene { public: virtual ~NoLock(); - + LUCENE_CLASS(NoLock); - + public: virtual bool obtain(); virtual void release(); diff --git a/src/core/include/_NumericRangeQuery.h b/src/core/include/_NumericRangeQuery.h index 57122fa6..158b3477 100644 --- a/src/core/include/_NumericRangeQuery.h +++ b/src/core/include/_NumericRangeQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,72 +14,72 @@ namespace Lucene { /// Subclass of FilteredTermEnum for enumerating all terms that match the sub-ranges for trie range queries. /// - /// Warning: This term enumeration is not guaranteed to be always ordered by {@link Term#compareTo}. The - /// ordering depends on how {@link NumericUtils#splitLongRange} and {@link NumericUtils#splitIntRange} + /// Warning: This term enumeration is not guaranteed to be always ordered by {@link Term#compareTo}. The + /// ordering depends on how {@link NumericUtils#splitLongRange} and {@link NumericUtils#splitIntRange} /// generates the sub-ranges. For {@link MultiTermQuery} ordering is not relevant. class NumericRangeTermEnum : public FilteredTermEnum { public: NumericRangeTermEnum(NumericRangeQueryPtr query, IndexReaderPtr reader); virtual ~NumericRangeTermEnum(); - + LUCENE_CLASS(NumericRangeTermEnum); - + protected: NumericRangeQueryWeakPtr _query; IndexReaderPtr reader; Collection rangeBounds; TermPtr termTemplate; String currentUpperBound; - + public: virtual double difference(); - + /// Increments the enumeration to the next element. True if one exists. virtual bool next(); - + /// Closes the enumeration to further activity, freeing resources. virtual void close(); - + protected: /// This is a dummy, it is not used by this class. virtual bool endEnum(); - + /// This is a dummy, it is not used by this class. virtual void setEnum(TermEnumPtr actualEnum); - + /// Compares if current upper bound is reached, this also updates the term count for statistics. /// In contrast to {@link FilteredTermEnum}, a return value of false ends iterating the current enum /// and forwards to the next sub-range. virtual bool termCompare(TermPtr term); }; - + class NumericLongRangeBuilder : public LongRangeBuilder { public: NumericLongRangeBuilder(Collection rangeBounds); virtual ~NumericLongRangeBuilder(); - + LUCENE_CLASS(NumericLongRangeBuilder); - + protected: Collection rangeBounds; - + public: virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); }; - + class NumericIntRangeBuilder : public IntRangeBuilder { public: NumericIntRangeBuilder(Collection rangeBounds); virtual ~NumericIntRangeBuilder(); - + LUCENE_CLASS(NumericIntRangeBuilder); - + protected: Collection rangeBounds; - + public: virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); }; diff --git a/src/core/include/_OrdFieldSource.h b/src/core/include/_OrdFieldSource.h index 8438054a..1cafad0b 100644 --- a/src/core/include/_OrdFieldSource.h +++ b/src/core/include/_OrdFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,13 +16,13 @@ namespace Lucene public: OrdDocValues(OrdFieldSourcePtr source, Collection arr); virtual ~OrdDocValues(); - + LUCENE_CLASS(OrdDocValues); - + protected: OrdFieldSourceWeakPtr _source; Collection arr; - + public: virtual double doubleVal(int32_t doc); virtual String strVal(int32_t doc); diff --git a/src/core/include/_ParallelReader.h b/src/core/include/_ParallelReader.h index daeb8a57..76b86942 100644 --- a/src/core/include/_ParallelReader.h +++ b/src/core/include/_ParallelReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,30 +19,30 @@ namespace Lucene ParallelTermEnum(ParallelReaderPtr reader); ParallelTermEnum(ParallelReaderPtr reader, TermPtr term); virtual ~ParallelTermEnum(); - + LUCENE_CLASS(ParallelTermEnum); - + protected: ParallelReaderWeakPtr _reader; String field; MapStringIndexReader::iterator fieldIterator; bool setIterator; TermEnumPtr termEnum; - + public: /// Increments the enumeration to the next element. True if one exists. virtual bool next(); - + /// Returns the current Term in the enumeration. virtual TermPtr term(); - + /// Returns the docFreq of the current Term in the enumeration. virtual int32_t docFreq(); - + /// Closes the enumeration to further activity, freeing resources. virtual void close(); }; - + /// Wrap a TermDocs in order to support seek(Term) class ParallelTermDocs : public TermPositions, public LuceneObject { @@ -50,13 +50,13 @@ namespace Lucene ParallelTermDocs(ParallelReaderPtr reader); ParallelTermDocs(ParallelReaderPtr reader, TermPtr term); virtual ~ParallelTermDocs(); - + LUCENE_CLASS(ParallelTermDocs); - + protected: ParallelReaderWeakPtr _reader; TermDocsPtr termDocs; - + public: virtual int32_t doc(); virtual int32_t freq(); @@ -67,16 +67,16 @@ namespace Lucene virtual bool skipTo(int32_t target); virtual void close(); }; - + class ParallelTermPositions : public ParallelTermDocs { public: ParallelTermPositions(ParallelReaderPtr reader); ParallelTermPositions(ParallelReaderPtr reader, TermPtr term); virtual ~ParallelTermPositions(); - + LUCENE_CLASS(ParallelTermPositions); - + public: virtual void seek(TermPtr term); virtual int32_t nextPosition(); diff --git a/src/core/include/_PayloadTermQuery.h b/src/core/include/_PayloadTermQuery.h index 309e9ae5..395850c8 100644 --- a/src/core/include/_PayloadTermQuery.h +++ b/src/core/include/_PayloadTermQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,35 +17,35 @@ namespace Lucene public: PayloadTermWeight(PayloadTermQueryPtr query, SearcherPtr searcher); virtual ~PayloadTermWeight(); - + LUCENE_CLASS(PayloadTermWeight); - + public: virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); }; - + class PayloadTermSpanScorer : public SpanScorer { public: PayloadTermSpanScorer(TermSpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms); virtual ~PayloadTermSpanScorer(); - + LUCENE_CLASS(PayloadTermSpanScorer); - + protected: ByteArray payload; TermPositionsPtr positions; double payloadScore; int32_t payloadsSeen; - + public: virtual double score(); - + protected: virtual bool setFreqCurrentDoc(); - + void processPayload(SimilarityPtr similarity); - + /// Returns the SpanScorer score only. /// /// Should not be overridden without good cause @@ -53,15 +53,15 @@ namespace Lucene /// @return the score for just the Span part without the payload /// @see #score() virtual double getSpanScore(); - + /// The score for the payload /// - /// @return The score, as calculated by {@link PayloadFunction#docScore(int32_t, const String&, + /// @return The score, as calculated by {@link PayloadFunction#docScore(int32_t, const String&, /// int32_t, double)} virtual double getPayloadScore(); - + virtual ExplanationPtr explain(int32_t doc); - }; + }; } #endif diff --git a/src/core/include/_PhraseQuery.h b/src/core/include/_PhraseQuery.h index 1246eaca..34cd9516 100644 --- a/src/core/include/_PhraseQuery.h +++ b/src/core/include/_PhraseQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: PhraseWeight(PhraseQueryPtr query, SearcherPtr searcher); virtual ~PhraseWeight(); - + LUCENE_CLASS(PhraseWeight); - + protected: PhraseQueryPtr query; SimilarityPtr similarity; @@ -27,7 +27,7 @@ namespace Lucene double queryNorm; double queryWeight; IDFExplanationPtr idfExp; - + public: virtual String toString(); virtual QueryPtr getQuery(); diff --git a/src/core/include/_QueryWrapperFilter.h b/src/core/include/_QueryWrapperFilter.h index 145408d1..e78f1209 100644 --- a/src/core/include/_QueryWrapperFilter.h +++ b/src/core/include/_QueryWrapperFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,13 +16,13 @@ namespace Lucene public: QueryWrapperFilterDocIdSet(IndexReaderPtr reader, WeightPtr weight); virtual ~QueryWrapperFilterDocIdSet(); - + LUCENE_CLASS(QueryWrapperFilterDocIdSet); - + protected: IndexReaderPtr reader; WeightPtr weight; - + public: virtual DocIdSetIteratorPtr iterator(); virtual bool isCacheable(); diff --git a/src/core/include/_ReverseOrdFieldSource.h b/src/core/include/_ReverseOrdFieldSource.h index 8eb5f8cd..0528cb8a 100644 --- a/src/core/include/_ReverseOrdFieldSource.h +++ b/src/core/include/_ReverseOrdFieldSource.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,14 +16,14 @@ namespace Lucene public: ReverseOrdDocValues(ReverseOrdFieldSourcePtr source, Collection arr, int32_t end); virtual ~ReverseOrdDocValues(); - + LUCENE_CLASS(ReverseOrdDocValues); - + protected: ReverseOrdFieldSourceWeakPtr _source; Collection arr; int32_t end; - + public: virtual double doubleVal(int32_t doc); virtual int32_t intVal(int32_t doc); diff --git a/src/core/include/_ScorerDocQueue.h b/src/core/include/_ScorerDocQueue.h index 6352fa6e..bc04370c 100644 --- a/src/core/include/_ScorerDocQueue.h +++ b/src/core/include/_ScorerDocQueue.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,13 +17,13 @@ namespace Lucene HeapedScorerDoc(ScorerPtr scorer); HeapedScorerDoc(ScorerPtr scorer, int32_t doc); virtual ~HeapedScorerDoc(); - + LUCENE_CLASS(HeapedScorerDoc); - + public: ScorerPtr scorer; int32_t doc; - + public: void adjust(); }; diff --git a/src/core/include/_SegmentInfos.h b/src/core/include/_SegmentInfos.h index ed2c72ad..9e8db102 100644 --- a/src/core/include/_SegmentInfos.h +++ b/src/core/include/_SegmentInfos.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,54 +17,54 @@ namespace Lucene public: FindSegmentsFile(SegmentInfosPtr infos, DirectoryPtr directory); virtual ~FindSegmentsFile(); - + LUCENE_CLASS(FindSegmentsFile); - + protected: SegmentInfosWeakPtr _segmentInfos; DirectoryPtr directory; - + public: - void doRun(IndexCommitPtr commit = IndexCommitPtr()); + void doRun(IndexCommitPtr commit = IndexCommitPtr()); virtual void runBody(const String& segmentFileName) = 0; }; - + template class FindSegmentsFileT : public FindSegmentsFile { public: FindSegmentsFileT(SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFile(infos, directory) {} virtual ~FindSegmentsFileT() {} - + protected: TYPE result; - + public: virtual TYPE run(IndexCommitPtr commit = IndexCommitPtr()) { doRun(commit); return result; } - + virtual void runBody(const String& segmentFileName) { result = doBody(segmentFileName); } - + virtual TYPE doBody(const String& segmentFileName) = 0; }; - - /// Utility class for executing code that needs to do something with the current segments file. This is necessary with - /// lock-less commits because from the time you locate the current segments file name, until you actually open it, read + + /// Utility class for executing code that needs to do something with the current segments file. This is necessary with + /// lock-less commits because from the time you locate the current segments file name, until you actually open it, read /// its contents, or check modified time, etc., it could have been deleted due to a writer commit finishing. class FindSegmentsRead : public FindSegmentsFileT { public: FindSegmentsRead(SegmentInfosPtr infos, DirectoryPtr directory); virtual ~FindSegmentsRead(); - + LUCENE_CLASS(FindSegmentsRead); - + public: virtual int64_t doBody(const String& segmentFileName); }; diff --git a/src/core/include/_SegmentReader.h b/src/core/include/_SegmentReader.h index c4d9b40b..5712ea62 100644 --- a/src/core/include/_SegmentReader.h +++ b/src/core/include/_SegmentReader.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,17 +17,17 @@ namespace Lucene public: CoreReaders(SegmentReaderPtr origInstance, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, int32_t termsIndexDivisor); virtual ~CoreReaders(); - + LUCENE_CLASS(CoreReaders); - + protected: /// Counts how many other reader share the core objects (freqStream, proxStream, tis, etc.) of this reader; /// when coreRef drops to 0, these core objects may be closed. A given instance of SegmentReader may be /// closed, even those it shares core objects with other SegmentReaders SegmentReaderRefPtr ref; - + SegmentReaderWeakPtr _origInstance; - + public: String segment; FieldInfosPtr fieldInfos; @@ -45,7 +45,7 @@ namespace Lucene TermVectorsReaderPtr termVectorsReaderOrig; CompoundFileReaderPtr cfsReader; CompoundFileReaderPtr storeCFSReader; - + public: TermVectorsReaderPtr getTermVectorsReaderOrig(); FieldsReaderPtr getFieldsReaderOrig(); @@ -53,55 +53,55 @@ namespace Lucene DirectoryPtr getCFSReader(); TermInfosReaderPtr getTermsReader(); bool termsIndexIsLoaded(); - + /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, /// sharing a segment that's still being merged. This method is not fully thread safe, and relies on the /// synchronization in IndexWriter void loadTermsIndex(SegmentInfoPtr si, int32_t termsIndexDivisor); - + void openDocStores(SegmentInfoPtr si); - + void decRef(); - + friend class SegmentReader; }; - + /// Sets the initial value class FieldsReaderLocal : public CloseableThreadLocal { public: FieldsReaderLocal(SegmentReaderPtr reader); - + protected: SegmentReaderWeakPtr _reader; - + protected: virtual FieldsReaderPtr initialValue(); }; - + class SegmentReaderRef : public LuceneObject { public: SegmentReaderRef(); virtual ~SegmentReaderRef(); - + LUCENE_CLASS(SegmentReaderRef); - + protected: int32_t _refCount; - + public: virtual String toString(); int32_t refCount(); int32_t incRef(); int32_t decRef(); - + friend class SegmentReader; }; - - /// Byte[] referencing is used because a new norm object needs to be created for each clone, and the byte - /// array is all that is needed for sharing between cloned readers. The current norm referencing is for - /// sharing between readers whereas the byte[] referencing is for copy on write which is independent of + + /// Byte[] referencing is used because a new norm object needs to be created for each clone, and the byte + /// array is all that is needed for sharing between cloned readers. The current norm referencing is for + /// sharing between readers whereas the byte[] referencing is for copy on write which is independent of /// reader references (i.e. incRef, decRef). class Norm : public LuceneObject { @@ -109,52 +109,52 @@ namespace Lucene Norm(); Norm(SegmentReaderPtr reader, IndexInputPtr in, int32_t number, int64_t normSeek); virtual ~Norm(); - + LUCENE_CLASS(Norm); - + protected: SegmentReaderWeakPtr _reader; int32_t refCount; - + /// If this instance is a clone, the originalNorm references the Norm that has a real open IndexInput NormPtr origNorm; SegmentReaderPtr origReader; - + IndexInputPtr in; int64_t normSeek; - + SegmentReaderRefPtr _bytesRef; ByteArray _bytes; bool dirty; int32_t number; bool rollbackDirty; - + public: void incRef(); void decRef(); - + /// Load bytes but do not cache them if they were not already cached void bytes(uint8_t* bytesOut, int32_t offset, int32_t length); - + /// Load & cache full bytes array. Returns bytes. ByteArray bytes(); - + /// Only for testing SegmentReaderRefPtr bytesRef(); - - /// Called if we intend to change a norm value. We make a private copy of bytes if it's shared + + /// Called if we intend to change a norm value. We make a private copy of bytes if it's shared // with others ByteArray copyOnWrite(); - + /// Returns a copy of this Norm instance that shares IndexInput & bytes with the original one virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - + /// Flush all pending changes to the next generation separate norms file. void reWrite(SegmentInfoPtr si); - + protected: void closeInput(); - + friend class SegmentReader; }; } diff --git a/src/core/include/_Similarity.h b/src/core/include/_Similarity.h index 2ec5cd07..95b43315 100644 --- a/src/core/include/_Similarity.h +++ b/src/core/include/_Similarity.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,17 +16,17 @@ namespace Lucene public: SimilarityIDFExplanation(int32_t df, int32_t max, double idf); SimilarityIDFExplanation(const String& exp, double idf); - + virtual ~SimilarityIDFExplanation(); - + LUCENE_CLASS(SimilarityIDFExplanation); - + protected: String exp; int32_t df; int32_t max; double idf; - + public: virtual String explain(); virtual double getIdf(); diff --git a/src/core/include/_SimpleFSDirectory.h b/src/core/include/_SimpleFSDirectory.h index e56e276d..d2c0d783 100644 --- a/src/core/include/_SimpleFSDirectory.h +++ b/src/core/include/_SimpleFSDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,18 +17,18 @@ namespace Lucene public: InputFile(const String& path); virtual ~InputFile(); - + LUCENE_CLASS(InputFile); - + public: static const int32_t FILE_EOF; static const int32_t FILE_ERROR; - + protected: ifstreamPtr file; int64_t position; int64_t length; - + public: void setPosition(int64_t position); int64_t getPosition(); @@ -37,49 +37,49 @@ namespace Lucene void close(); bool isValid(); }; - + class SimpleFSIndexInput : public BufferedIndexInput { public: SimpleFSIndexInput(); SimpleFSIndexInput(const String& path, int32_t bufferSize, int32_t chunkSize); virtual ~SimpleFSIndexInput(); - + LUCENE_CLASS(SimpleFSIndexInput); - + protected: String path; InputFilePtr file; bool isClone; int32_t chunkSize; - + protected: virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); virtual void seekInternal(int64_t pos); - + public: virtual int64_t length(); virtual void close(); - + /// Method used for testing. bool isValid(); - + /// Returns a clone of this stream. virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); }; - + class OutputFile : public LuceneObject { public: OutputFile(const String& path); virtual ~OutputFile(); - + LUCENE_CLASS(OutputFile); - + protected: ofstreamPtr file; String path; - + public: bool write(const uint8_t* b, int32_t offset, int32_t length); void close(); @@ -89,26 +89,26 @@ namespace Lucene void flush(); bool isValid(); }; - + class SimpleFSIndexOutput : public BufferedIndexOutput { public: SimpleFSIndexOutput(const String& path); virtual ~SimpleFSIndexOutput(); - + LUCENE_CLASS(SimpleFSIndexOutput); - + protected: OutputFilePtr file; bool isOpen; - + public: virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length); virtual void close(); virtual void seek(int64_t pos); virtual int64_t length(); virtual void setLength(int64_t length); - }; + }; } #endif diff --git a/src/core/include/_SimpleFSLockFactory.h b/src/core/include/_SimpleFSLockFactory.h index a0de522b..cedb8907 100644 --- a/src/core/include/_SimpleFSLockFactory.h +++ b/src/core/include/_SimpleFSLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,25 +16,25 @@ namespace Lucene public: SimpleFSLock(const String& lockDir, const String& lockFileName); virtual ~SimpleFSLock(); - + LUCENE_CLASS(SimpleFSLock); - + public: String lockDir; String lockFile; - + public: /// Attempts to obtain exclusive access and immediately return upon success or failure. /// @return true if exclusive access is obtained. virtual bool obtain(); - + /// Releases exclusive access. virtual void release(); - - /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} + + /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} /// before using the resource. virtual bool isLocked(); - + /// Returns derived object name. virtual String toString(); }; diff --git a/src/core/include/_SingleInstanceLockFactory.h b/src/core/include/_SingleInstanceLockFactory.h index b26d5657..ea2d56a8 100644 --- a/src/core/include/_SingleInstanceLockFactory.h +++ b/src/core/include/_SingleInstanceLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,26 +16,26 @@ namespace Lucene public: SingleInstanceLock(HashSet locks, const String& lockName); virtual ~SingleInstanceLock(); - + LUCENE_CLASS(SingleInstanceLock); - + protected: HashSet locks; String lockName; - + public: /// Attempts to obtain exclusive access and immediately return /// upon success or failure. /// @return true if exclusive access is obtained. virtual bool obtain(); - + /// Releases exclusive access. virtual void release(); - + /// Returns true if the resource is currently locked. Note that /// one must still call {@link #obtain()} before using the resource. virtual bool isLocked(); - + /// Returns derived object name. virtual String toString(); }; diff --git a/src/core/include/_SnapshotDeletionPolicy.h b/src/core/include/_SnapshotDeletionPolicy.h index 7b1da72b..cf9389de 100644 --- a/src/core/include/_SnapshotDeletionPolicy.h +++ b/src/core/include/_SnapshotDeletionPolicy.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,41 +16,41 @@ namespace Lucene public: MyCommitPoint(SnapshotDeletionPolicyPtr deletionPolicy, IndexCommitPtr cp); virtual ~MyCommitPoint(); - + LUCENE_CLASS(MyCommitPoint); - + protected: SnapshotDeletionPolicyWeakPtr _deletionPolicy; - + public: IndexCommitPtr cp; - + public: virtual String toString(); - + /// Get the segments file (segments_N) associated with this commit point. virtual String getSegmentsFileName(); - + /// Returns all index files referenced by this commit point. virtual HashSet getFileNames(); - + /// Returns the {@link Directory} for the index. virtual DirectoryPtr getDirectory(); - + /// Delete this commit point. virtual void deleteCommit(); - + virtual bool isDeleted(); - + /// Returns the version for this IndexCommit. virtual int64_t getVersion(); - + /// Returns the generation (the _N in segments_N) for this IndexCommit. virtual int64_t getGeneration(); - + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. virtual MapStringString getUserData(); - + virtual bool isOptimized(); }; } diff --git a/src/core/include/_SortedVIntList.h b/src/core/include/_SortedVIntList.h index 12e39779..5a95845e 100644 --- a/src/core/include/_SortedVIntList.h +++ b/src/core/include/_SortedVIntList.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,20 +16,20 @@ namespace Lucene public: SortedDocIdSetIterator(SortedVIntListPtr list); virtual ~SortedDocIdSetIterator(); - + LUCENE_CLASS(SortedDocIdSetIterator); - + public: SortedVIntListWeakPtr _list; int32_t bytePos; int32_t lastInt; int32_t doc; - + public: virtual int32_t docID(); virtual int32_t nextDoc(); virtual int32_t advance(int32_t target); - + protected: void advance(); }; diff --git a/src/core/include/_SpanFirstQuery.h b/src/core/include/_SpanFirstQuery.h index 3c00980d..2fd8f035 100644 --- a/src/core/include/_SpanFirstQuery.h +++ b/src/core/include/_SpanFirstQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,13 +16,13 @@ namespace Lucene public: FirstSpans(SpanFirstQueryPtr query, SpansPtr spans); virtual ~FirstSpans(); - + LUCENE_CLASS(FirstSpans); - + protected: SpanFirstQueryPtr query; SpansPtr spans; - + public: virtual bool next(); virtual bool skipTo(int32_t target); diff --git a/src/core/include/_SpanNotQuery.h b/src/core/include/_SpanNotQuery.h index 281d11ad..56489451 100644 --- a/src/core/include/_SpanNotQuery.h +++ b/src/core/include/_SpanNotQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,16 +16,16 @@ namespace Lucene public: NotSpans(SpanNotQueryPtr query, SpansPtr includeSpans, SpansPtr excludeSpans); virtual ~NotSpans(); - + LUCENE_CLASS(NotSpans); - + protected: SpanNotQueryPtr query; SpansPtr includeSpans; bool moreInclude; SpansPtr excludeSpans; bool moreExclude; - + public: virtual bool next(); virtual bool skipTo(int32_t target); diff --git a/src/core/include/_SpanOrQuery.h b/src/core/include/_SpanOrQuery.h index 9f569abb..9aad3310 100644 --- a/src/core/include/_SpanOrQuery.h +++ b/src/core/include/_SpanOrQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,26 +17,26 @@ namespace Lucene public: SpanQueue(int32_t size); virtual ~SpanQueue(); - + LUCENE_CLASS(SpanQueue); - + protected: virtual bool lessThan(const SpansPtr& first, const SpansPtr& second); }; - + class OrSpans : public Spans { public: OrSpans(SpanOrQueryPtr query, IndexReaderPtr reader); virtual ~OrSpans(); - + LUCENE_CLASS(OrSpans); - + protected: SpanOrQueryPtr query; IndexReaderPtr reader; SpanQueuePtr queue; - + public: virtual bool next(); virtual bool skipTo(int32_t target); @@ -46,7 +46,7 @@ namespace Lucene virtual Collection getPayload(); virtual bool isPayloadAvailable(); virtual String toString(); - + protected: bool initSpanQueue(int32_t target); SpansPtr top(); diff --git a/src/core/include/_StandardAnalyzer.h b/src/core/include/_StandardAnalyzer.h index e09aac4d..96c8b7b8 100644 --- a/src/core/include/_StandardAnalyzer.h +++ b/src/core/include/_StandardAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene { public: virtual ~StandardAnalyzerSavedStreams(); - + public: StandardTokenizerPtr tokenStream; TokenStreamPtr filteredTokenStream; diff --git a/src/core/include/_StopAnalyzer.h b/src/core/include/_StopAnalyzer.h index 57ac15bb..799a6200 100644 --- a/src/core/include/_StopAnalyzer.h +++ b/src/core/include/_StopAnalyzer.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene { public: virtual ~StopAnalyzerSavedStreams(); - + LUCENE_CLASS(StopAnalyzerSavedStreams); - + public: TokenizerPtr source; TokenStreamPtr result; diff --git a/src/core/include/_TermQuery.h b/src/core/include/_TermQuery.h index 46c5ebde..b5ae14f0 100644 --- a/src/core/include/_TermQuery.h +++ b/src/core/include/_TermQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,9 +16,9 @@ namespace Lucene public: TermWeight(TermQueryPtr query, SearcherPtr searcher); virtual ~TermWeight(); - + LUCENE_CLASS(TermWeight); - + protected: TermQueryPtr query; SimilarityPtr similarity; @@ -27,7 +27,7 @@ namespace Lucene double queryNorm; double queryWeight; IDFExplanationPtr idfExp; - + public: virtual String toString(); virtual QueryPtr getQuery(); diff --git a/src/core/include/_TimeLimitingCollector.h b/src/core/include/_TimeLimitingCollector.h index 4729e7ca..a2879cbc 100644 --- a/src/core/include/_TimeLimitingCollector.h +++ b/src/core/include/_TimeLimitingCollector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,20 +16,20 @@ namespace Lucene public: TimerThread(); virtual ~TimerThread(); - + LUCENE_CLASS(TimerThread); - + protected: int64_t time; bool _stopThread; - + public: virtual void start(); virtual void run(); - + /// Get the timer value in milliseconds. int64_t getMilliseconds(); - + /// Stop timer thread. void stopThread(); }; diff --git a/src/core/include/_TopFieldCollector.h b/src/core/include/_TopFieldCollector.h index 2f362b60..dd3afbba 100644 --- a/src/core/include/_TopFieldCollector.h +++ b/src/core/include/_TopFieldCollector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,115 +17,115 @@ namespace Lucene public: OneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OneComparatorNonScoringCollector(); - + LUCENE_CLASS(OneComparatorNonScoringCollector); - + public: FieldComparatorPtr comparator; int32_t reverseMul; - + public: - virtual void initialize(); + virtual void initialize(); virtual void updateBottom(int32_t doc); virtual void collect(int32_t doc); virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); virtual void setScorer(ScorerPtr scorer); }; - - /// Implements a TopFieldCollector over one SortField criteria, without tracking document scores and maxScore, + + /// Implements a TopFieldCollector over one SortField criteria, without tracking document scores and maxScore, /// and assumes out of orderness in doc Ids collection. class OutOfOrderOneComparatorNonScoringCollector : public OneComparatorNonScoringCollector { public: OutOfOrderOneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderOneComparatorNonScoringCollector(); - + LUCENE_CLASS(OutOfOrderOneComparatorNonScoringCollector); - + public: virtual void collect(int32_t doc); virtual bool acceptsDocsOutOfOrder(); }; - + /// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore. class OneComparatorScoringNoMaxScoreCollector : public OneComparatorNonScoringCollector { public: OneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OneComparatorScoringNoMaxScoreCollector(); - + LUCENE_CLASS(OneComparatorScoringNoMaxScoreCollector); - + public: ScorerPtr scorer; - + public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); virtual void setScorer(ScorerPtr scorer); }; - - /// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore, + + /// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore, /// and assumes out of orderness in doc Ids collection. class OutOfOrderOneComparatorScoringNoMaxScoreCollector : public OneComparatorScoringNoMaxScoreCollector { public: OutOfOrderOneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderOneComparatorScoringNoMaxScoreCollector(); - + LUCENE_CLASS(OutOfOrderOneComparatorScoringNoMaxScoreCollector); - + public: virtual void collect(int32_t doc); virtual bool acceptsDocsOutOfOrder(); }; - + /// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore. class OneComparatorScoringMaxScoreCollector : public OneComparatorNonScoringCollector { public: OneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OneComparatorScoringMaxScoreCollector(); - + LUCENE_CLASS(OneComparatorScoringMaxScoreCollector); - + public: ScorerPtr scorer; - + public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); virtual void setScorer(ScorerPtr scorer); }; - - /// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore, + + /// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore, /// and assumes out of orderness in doc Ids collection. class OutOfOrderOneComparatorScoringMaxScoreCollector : public OneComparatorScoringMaxScoreCollector { public: OutOfOrderOneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderOneComparatorScoringMaxScoreCollector(); - + LUCENE_CLASS(OutOfOrderOneComparatorScoringMaxScoreCollector); - + public: virtual void collect(int32_t doc); virtual bool acceptsDocsOutOfOrder(); }; - + /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. class MultiComparatorNonScoringCollector : public TopFieldCollector { public: MultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~MultiComparatorNonScoringCollector(); - + LUCENE_CLASS(MultiComparatorNonScoringCollector); - + public: Collection comparators; Collection reverseMul; - + public: virtual void initialize(); virtual void updateBottom(int32_t doc); @@ -133,81 +133,81 @@ namespace Lucene virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); virtual void setScorer(ScorerPtr scorer); }; - + /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. class OutOfOrderMultiComparatorNonScoringCollector : public MultiComparatorNonScoringCollector { public: OutOfOrderMultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderMultiComparatorNonScoringCollector(); - + LUCENE_CLASS(OutOfOrderMultiComparatorNonScoringCollector); - + public: virtual void collect(int32_t doc); virtual bool acceptsDocsOutOfOrder(); }; - + /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore. class MultiComparatorScoringMaxScoreCollector : public MultiComparatorNonScoringCollector { public: MultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~MultiComparatorScoringMaxScoreCollector(); - + LUCENE_CLASS(MultiComparatorScoringMaxScoreCollector); - + public: ScorerWeakPtr _scorer; - + public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); virtual void setScorer(ScorerPtr scorer); }; - + /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. class OutOfOrderMultiComparatorScoringMaxScoreCollector : public MultiComparatorScoringMaxScoreCollector { public: OutOfOrderMultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderMultiComparatorScoringMaxScoreCollector(); - + LUCENE_CLASS(OutOfOrderMultiComparatorScoringMaxScoreCollector); - + public: virtual void collect(int32_t doc); virtual bool acceptsDocsOutOfOrder(); }; - + /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore. class MultiComparatorScoringNoMaxScoreCollector : public MultiComparatorNonScoringCollector { public: MultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~MultiComparatorScoringNoMaxScoreCollector(); - + LUCENE_CLASS(MultiComparatorScoringNoMaxScoreCollector); - + public: ScorerWeakPtr _scorer; - + public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); virtual void setScorer(ScorerPtr scorer); }; - - /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore, + + /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore, /// and assumes out of orderness in doc Ids collection. class OutOfOrderMultiComparatorScoringNoMaxScoreCollector : public MultiComparatorScoringNoMaxScoreCollector { public: OutOfOrderMultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderMultiComparatorScoringNoMaxScoreCollector(); - + LUCENE_CLASS(OutOfOrderMultiComparatorScoringNoMaxScoreCollector); - + public: virtual void collect(int32_t doc); virtual void setScorer(ScorerPtr scorer); diff --git a/src/core/include/_TopScoreDocCollector.h b/src/core/include/_TopScoreDocCollector.h index 92fa00e7..fdaf0185 100644 --- a/src/core/include/_TopScoreDocCollector.h +++ b/src/core/include/_TopScoreDocCollector.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,23 +17,23 @@ namespace Lucene public: InOrderTopScoreDocCollector(int32_t numHits); virtual ~InOrderTopScoreDocCollector(); - + LUCENE_CLASS(InOrderTopScoreDocCollector); - + public: virtual void collect(int32_t doc); virtual bool acceptsDocsOutOfOrder(); }; - + /// Assumes docs are scored out of order. class OutOfOrderTopScoreDocCollector : public TopScoreDocCollector { public: OutOfOrderTopScoreDocCollector(int32_t numHits); virtual ~OutOfOrderTopScoreDocCollector(); - + LUCENE_CLASS(OutOfOrderTopScoreDocCollector); - + public: virtual void collect(int32_t doc); virtual bool acceptsDocsOutOfOrder(); diff --git a/src/core/include/_ValueSourceQuery.h b/src/core/include/_ValueSourceQuery.h index bfe4bf97..a39b0026 100644 --- a/src/core/include/_ValueSourceQuery.h +++ b/src/core/include/_ValueSourceQuery.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,15 +17,15 @@ namespace Lucene public: ValueSourceWeight(ValueSourceQueryPtr query, SearcherPtr searcher); virtual ~ValueSourceWeight(); - + LUCENE_CLASS(ValueSourceWeight); - + public: ValueSourceQueryPtr query; SimilarityPtr similarity; double queryNorm; double queryWeight; - + public: virtual QueryPtr getQuery(); virtual double getValue(); @@ -34,25 +34,25 @@ namespace Lucene virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); }; - - /// A scorer that (simply) matches all documents, and scores each document with the value of the value + + /// A scorer that (simply) matches all documents, and scores each document with the value of the value /// source in effect. As an example, if the value source is a (cached) field source, then value of that - /// field in that document will be used. (assuming field is indexed for this doc, with a single token.) + /// field in that document will be used. (assuming field is indexed for this doc, with a single token.) class ValueSourceScorer : public Scorer { public: ValueSourceScorer(SimilarityPtr similarity, IndexReaderPtr reader, ValueSourceWeightPtr weight); virtual ~ValueSourceScorer(); - + LUCENE_CLASS(ValueSourceScorer); - + public: ValueSourceWeightPtr weight; double qWeight; DocValuesPtr vals; TermDocsPtr termDocs; int32_t doc; - + public: virtual int32_t nextDoc(); virtual int32_t docID(); diff --git a/src/core/index/AbstractAllTermDocs.cpp b/src/core/index/AbstractAllTermDocs.cpp index 73057625..ad2370e1 100644 --- a/src/core/index/AbstractAllTermDocs.cpp +++ b/src/core/index/AbstractAllTermDocs.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene this->maxDoc = maxDoc; this->_doc = -1; } - + AbstractAllTermDocs::~AbstractAllTermDocs() { } - + void AbstractAllTermDocs::seek(TermPtr term) { if (!term) @@ -26,27 +26,27 @@ namespace Lucene else boost::throw_exception(UnsupportedOperationException()); } - + void AbstractAllTermDocs::seek(TermEnumPtr termEnum) { boost::throw_exception(UnsupportedOperationException()); } - + int32_t AbstractAllTermDocs::doc() { return _doc; } - + int32_t AbstractAllTermDocs::freq() { return 1; } - + bool AbstractAllTermDocs::next() { return skipTo(_doc + 1); } - + int32_t AbstractAllTermDocs::read(Collection docs, Collection freqs) { int32_t length = docs.size(); @@ -63,7 +63,7 @@ namespace Lucene } return i; } - + bool AbstractAllTermDocs::skipTo(int32_t target) { _doc = target; @@ -75,7 +75,7 @@ namespace Lucene } return false; } - + void AbstractAllTermDocs::close() { } diff --git a/src/core/index/AllTermDocs.cpp b/src/core/index/AllTermDocs.cpp index d29a83ae..b197e398 100644 --- a/src/core/index/AllTermDocs.cpp +++ b/src/core/index/AllTermDocs.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene SyncLock parentLock(parent); this->_deletedDocs = parent->deletedDocs; } - + AllTermDocs::~AllTermDocs() { } - + bool AllTermDocs::isDeleted(int32_t doc) { BitVectorPtr deletedDocs(_deletedDocs.lock()); diff --git a/src/core/index/BufferedDeletes.cpp b/src/core/index/BufferedDeletes.cpp index bd50ae8e..c350d9d0 100644 --- a/src/core/index/BufferedDeletes.cpp +++ b/src/core/index/BufferedDeletes.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,19 +19,19 @@ namespace Lucene numTerms = 0; bytesUsed = 0; } - + BufferedDeletes::~BufferedDeletes() { } - + int32_t BufferedDeletes::size() { - // We use numTerms not terms.size() intentionally, so that deletes by the same term - // multiple times "count", ie if you ask to flush every 1000 deletes then even dup'd + // We use numTerms not terms.size() intentionally, so that deletes by the same term + // multiple times "count", ie if you ask to flush every 1000 deletes then even dup'd // terms are counted towards that 1000 return numTerms + queries.size() + docIDs.size(); } - + void BufferedDeletes::update(BufferedDeletesPtr in) { numTerms += in->numTerms; @@ -41,7 +41,7 @@ namespace Lucene docIDs.addAll(in->docIDs.begin(), in->docIDs.end()); in->clear(); } - + void BufferedDeletes::clear() { terms.clear(); @@ -50,23 +50,23 @@ namespace Lucene numTerms = 0; bytesUsed = 0; } - + void BufferedDeletes::addBytesUsed(int64_t b) { bytesUsed += b; } - + bool BufferedDeletes::any() { return (!terms.empty() || !docIDs.empty() || !queries.empty()); } - + void BufferedDeletes::remap(MergeDocIDRemapperPtr mapper, SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergedDocCount) { SyncLock syncLock(this); - + MapTermNum newDeleteTerms; - + // Remap delete-by-term if (!terms.empty()) { @@ -74,27 +74,27 @@ namespace Lucene for (MapTermNum::iterator entry = terms.begin(); entry != terms.end(); ++entry) newDeleteTerms.put(entry->first, newLucene(mapper->remap(entry->second->getNum()))); } - + // Remap delete-by-docID Collection newDeleteDocIDs; - + if (!docIDs.empty()) { newDeleteDocIDs = Collection::newInstance(); for (Collection::iterator num = docIDs.begin(); num != docIDs.end(); ++num) newDeleteDocIDs.add(mapper->remap(*num)); } - + // Remap delete-by-query MapQueryInt newDeleteQueries; - + if (!queries.empty()) { newDeleteQueries = MapQueryInt::newInstance(); for (MapQueryInt::iterator entry = queries.begin(); entry != queries.end(); ++entry) newDeleteQueries.put(entry->first, mapper->remap(entry->second)); } - + if (newDeleteTerms) terms = newDeleteTerms; if (newDeleteDocIDs) @@ -102,21 +102,21 @@ namespace Lucene if (newDeleteQueries) queries = newDeleteQueries; } - + Num::Num(int32_t num) { this->num = num; } - + int32_t Num::getNum() { return num; } - + void Num::setNum(int32_t num) { - // Only record the new number if it's greater than the current one. This is important - // because if multiple threads are replacing the same doc at nearly the same time, it's + // Only record the new number if it's greater than the current one. This is important + // because if multiple threads are replacing the same doc at nearly the same time, it's // possible that one thread that got a higher docID is scheduled before the other threads. this->num = std::max(this->num, num); } diff --git a/src/core/index/ByteBlockPool.cpp b/src/core/index/ByteBlockPool.cpp index bed7d73e..14fac54d 100644 --- a/src/core/index/ByteBlockPool.cpp +++ b/src/core/index/ByteBlockPool.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,31 +12,31 @@ namespace Lucene { // Size of each slice. These arrays should be at most 16 elements (index is encoded with 4 bits). First array - // is just a compact way to encode X+1 with a max. Second array is the length of each slice, ie first slice is + // is just a compact way to encode X+1 with a max. Second array is the length of each slice, ie first slice is // 5 bytes, next slice is 14 bytes, etc. const int32_t ByteBlockPool::nextLevelArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9}; const int32_t ByteBlockPool::levelSizeArray[] = {5, 14, 20, 30, 40, 40, 80, 80, 120, 200}; - + ByteBlockPool::ByteBlockPool(ByteBlockPoolAllocatorBasePtr allocator, bool trackAllocations) { buffers = Collection::newInstance(10); bufferUpto = -1; byteUpto = DocumentsWriter::BYTE_BLOCK_SIZE; byteOffset = -DocumentsWriter::BYTE_BLOCK_SIZE; - + this->allocator = allocator; this->trackAllocations = trackAllocations; } - + ByteBlockPool::~ByteBlockPool() { } - + int32_t ByteBlockPool::FIRST_LEVEL_SIZE() { return levelSizeArray[0]; } - + void ByteBlockPool::reset() { if (bufferUpto != -1) @@ -47,16 +47,16 @@ namespace Lucene // Fully zero fill buffers that we fully used MiscUtils::arrayFill(buffers[i].get(), 0, buffers[i].size(), 0); } - + // Partial zero fill the final buffer MiscUtils::arrayFill(buffers[bufferUpto].get(), 0, byteUpto, 0); - + if (bufferUpto > 0) { // Recycle all but the first buffer allocator->recycleByteBlocks(buffers, 1, 1 + bufferUpto); } - + // Re-use the first buffer bufferUpto = 0; byteUpto = 0; @@ -64,7 +64,7 @@ namespace Lucene buffer = buffers[0]; } } - + void ByteBlockPool::nextBuffer() { if (1 + bufferUpto == buffers.size()) @@ -72,11 +72,11 @@ namespace Lucene buffers[1 + bufferUpto] = allocator->getByteBlock(trackAllocations); buffer = buffers[1 + bufferUpto]; ++bufferUpto; - + byteUpto = 0; byteOffset += DocumentsWriter::BYTE_BLOCK_SIZE; } - + int32_t ByteBlockPool::newSlice(int32_t size) { if (byteUpto > DocumentsWriter::BYTE_BLOCK_SIZE - size) @@ -86,38 +86,38 @@ namespace Lucene buffer[byteUpto - 1] = 16; return upto; } - + int32_t ByteBlockPool::allocSlice(ByteArray slice, int32_t upto) { int32_t level = slice[upto] & 15; int32_t newLevel = nextLevelArray[level]; int32_t newSize = levelSizeArray[newLevel]; - + // Maybe allocate another block if (byteUpto > DocumentsWriter::BYTE_BLOCK_SIZE - newSize) nextBuffer(); - + int32_t newUpto = byteUpto; int32_t offset = newUpto + byteOffset; byteUpto += newSize; - + // Copy forward the past 3 bytes (which we are about to overwrite with the forwarding address) buffer[newUpto] = slice[upto - 3]; buffer[newUpto + 1] = slice[upto - 2]; buffer[newUpto + 2] = slice[upto - 1]; - + // Write forwarding address at end of last slice slice[upto - 3] = (uint8_t)MiscUtils::unsignedShift(offset, 24); slice[upto - 2] = (uint8_t)MiscUtils::unsignedShift(offset, 16); slice[upto - 1] = (uint8_t)MiscUtils::unsignedShift(offset, 8); slice[upto] = (uint8_t)offset; - + // Write new level buffer[byteUpto - 1] = (uint8_t)(16 | newLevel); - + return (newUpto + 3); } - + ByteBlockPoolAllocatorBase::~ByteBlockPoolAllocatorBase() { } diff --git a/src/core/index/ByteSliceReader.cpp b/src/core/index/ByteSliceReader.cpp index 43bfcc9b..9198df43 100644 --- a/src/core/index/ByteSliceReader.cpp +++ b/src/core/index/ByteSliceReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,28 +21,28 @@ namespace Lucene bufferOffset = 0; endIndex = 0; } - + ByteSliceReader::~ByteSliceReader() { } - + void ByteSliceReader::init(ByteBlockPoolPtr pool, int32_t startIndex, int32_t endIndex) { BOOST_ASSERT(endIndex - startIndex >= 0); BOOST_ASSERT(startIndex >= 0); BOOST_ASSERT(endIndex >= 0); - + this->pool = pool; this->endIndex = endIndex; - + level = 0; bufferUpto = startIndex / DocumentsWriter::BYTE_BLOCK_SIZE; bufferOffset = bufferUpto * DocumentsWriter::BYTE_BLOCK_SIZE; buffer = pool->buffers[bufferUpto]; upto = startIndex & DocumentsWriter::BYTE_BLOCK_MASK; - + int32_t firstSize = ByteBlockPool::levelSizeArray[0]; - + if (startIndex + firstSize >= endIndex) { // There is only this one slice to read @@ -51,13 +51,13 @@ namespace Lucene else limit = upto + firstSize - 4; } - + bool ByteSliceReader::eof() { BOOST_ASSERT(upto + bufferOffset <= endIndex); return (upto + bufferOffset == endIndex); } - + uint8_t ByteSliceReader::readByte() { BOOST_ASSERT(!eof()); @@ -66,7 +66,7 @@ namespace Lucene nextSlice(); return buffer[upto++]; } - + int64_t ByteSliceReader::writeTo(IndexOutputPtr out) { int64_t size = 0; @@ -88,22 +88,22 @@ namespace Lucene } return size; } - + void ByteSliceReader::nextSlice() { // Skip to our next slice - int32_t nextIndex = ((buffer[limit] & 0xff) << 24) + ((buffer[1 + limit] & 0xff) << 16) + + int32_t nextIndex = ((buffer[limit] & 0xff) << 24) + ((buffer[1 + limit] & 0xff) << 16) + ((buffer[2 + limit] & 0xff) << 8) + (buffer[3 + limit] & 0xff); - + level = ByteBlockPool::nextLevelArray[level]; int32_t newSize = ByteBlockPool::levelSizeArray[level]; - + bufferUpto = nextIndex / DocumentsWriter::BYTE_BLOCK_SIZE; bufferOffset = bufferUpto * DocumentsWriter::BYTE_BLOCK_SIZE; - + this->buffer = pool->buffers[bufferUpto]; upto = nextIndex & DocumentsWriter::BYTE_BLOCK_MASK; - + if (nextIndex + newSize >= endIndex) { // We are advancing to the final slice @@ -116,7 +116,7 @@ namespace Lucene limit = upto + newSize - 4; } } - + void ByteSliceReader::readBytes(uint8_t* b, int32_t offset, int32_t length) { while (length > 0) @@ -139,24 +139,24 @@ namespace Lucene } } } - + int64_t ByteSliceReader::getFilePointer() { boost::throw_exception(RuntimeException(L"not implemented")); return 0; } - + int64_t ByteSliceReader::length() { boost::throw_exception(RuntimeException(L"not implemented")); return 0; } - + void ByteSliceReader::seek(int64_t pos) { boost::throw_exception(RuntimeException(L"not implemented")); } - + void ByteSliceReader::close() { boost::throw_exception(RuntimeException(L"not implemented")); diff --git a/src/core/index/ByteSliceWriter.cpp b/src/core/index/ByteSliceWriter.cpp index 8994b31f..0316817a 100644 --- a/src/core/index/ByteSliceWriter.cpp +++ b/src/core/index/ByteSliceWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,11 +17,11 @@ namespace Lucene upto = 0; offset0 = 0; } - + ByteSliceWriter::~ByteSliceWriter() { } - + void ByteSliceWriter::init(int32_t address) { slice = pool->buffers[address >> DocumentsWriter::BYTE_BLOCK_SHIFT]; @@ -30,7 +30,7 @@ namespace Lucene offset0 = address; BOOST_ASSERT(upto < slice.size()); } - + void ByteSliceWriter::writeByte(uint8_t b) { BOOST_ASSERT(slice); @@ -44,7 +44,7 @@ namespace Lucene slice[upto++] = b; BOOST_ASSERT(upto != slice.size()); } - + void ByteSliceWriter::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { int32_t offsetEnd = offset + length; @@ -57,17 +57,17 @@ namespace Lucene slice = pool->buffer; offset0 = pool->byteOffset; } - + slice[upto++] = b[offset++]; BOOST_ASSERT(upto != slice.size()); } } - + int32_t ByteSliceWriter::getAddress() { return upto + (offset0 & DocumentsWriter::BYTE_BLOCK_NOT_MASK); } - + void ByteSliceWriter::writeVInt(int32_t i) { while ((i & ~0x7f) != 0) diff --git a/src/core/index/CharBlockPool.cpp b/src/core/index/CharBlockPool.cpp index a97fc2a6..a4121c1f 100644 --- a/src/core/index/CharBlockPool.cpp +++ b/src/core/index/CharBlockPool.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,11 +19,11 @@ namespace Lucene buffers = Collection::newInstance(10); this->_docWriter = docWriter; } - + CharBlockPool::~CharBlockPool() { } - + void CharBlockPool::reset() { DocumentsWriterPtr(_docWriter)->recycleCharBlocks(buffers, 1 + bufferUpto); @@ -31,7 +31,7 @@ namespace Lucene charUpto = DocumentsWriter::CHAR_BLOCK_SIZE; charOffset = -DocumentsWriter::CHAR_BLOCK_SIZE; } - + void CharBlockPool::nextBuffer() { if (1 + bufferUpto == buffers.size()) @@ -39,7 +39,7 @@ namespace Lucene buffers[1 + bufferUpto] = DocumentsWriterPtr(_docWriter)->getCharBlock(); buffer = buffers[1 + bufferUpto]; ++bufferUpto; - + charUpto = 0; charOffset += DocumentsWriter::CHAR_BLOCK_SIZE; } diff --git a/src/core/index/CheckIndex.cpp b/src/core/index/CheckIndex.cpp index 7f783d85..1d8c8a26 100644 --- a/src/core/index/CheckIndex.cpp +++ b/src/core/index/CheckIndex.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,32 +25,32 @@ namespace Lucene { bool CheckIndex::_assertsOn = false; - + CheckIndex::CheckIndex(DirectoryPtr dir) { this->dir = dir; } - + CheckIndex::~CheckIndex() { } - + void CheckIndex::setInfoStream(InfoStreamPtr out) { infoStream = out; } - + void CheckIndex::msg(const String& msg) { if (infoStream) *infoStream << msg << L"\n"; } - + IndexStatusPtr CheckIndex::checkIndex() { return checkIndex(Collection()); } - + IndexStatusPtr CheckIndex::checkIndex(Collection onlySegments) { SegmentInfosPtr sis(newLucene()); @@ -66,11 +66,11 @@ namespace Lucene result->missingSegments = true; return result; } - + int32_t numSegments = sis->size(); String segmentsFileName(sis->getCurrentSegmentFileName()); IndexInputPtr input; - + try { input = dir->openInput(segmentsFileName); @@ -81,7 +81,7 @@ namespace Lucene result->cantOpenSegments = true; return result; } - + int32_t format = 0; try { @@ -97,10 +97,10 @@ namespace Lucene } if (input) input->close(); - + String sFormat; bool skip = false; - + if (format == SegmentInfos::FORMAT) sFormat = L"FORMAT [Lucene Pre-2.1]"; if (format == SegmentInfos::FORMAT_LOCKLESS) @@ -129,7 +129,7 @@ namespace Lucene else sFormat = StringUtils::toString(format) + L" [Lucene 1.3 or prior]"; } - + result->segmentsFileName = segmentsFileName; result->numSegments = numSegments; result->segmentFormat = sFormat; @@ -137,10 +137,10 @@ namespace Lucene String userDataString; if (!sis->getUserData().empty()) userDataString = L" userData(size)=" + StringUtils::toString(sis->getUserData().size()); - - msg(L"Segments file=" + segmentsFileName + L" numSegments=" + StringUtils::toString(numSegments) + + + msg(L"Segments file=" + segmentsFileName + L" numSegments=" + StringUtils::toString(numSegments) + L" version=" + sFormat + userDataString); - + if (onlySegments) { result->partial = true; @@ -150,7 +150,7 @@ namespace Lucene result->segmentsChecked.addAll(onlySegments.begin(), onlySegments.end()); msg(L":"); } - + if (skip) { msg(L"\nERROR: this index appears to be created by a newer version of Lucene than this tool was compiled on;" \ @@ -158,10 +158,10 @@ namespace Lucene result->toolOutOfDate = true; return result; } - + result->newSegments = boost::dynamic_pointer_cast(sis->clone()); result->newSegments->clear(); - + for (int32_t i = 0; i < numSegments; ++i) { SegmentInfoPtr info(sis->info(i)); @@ -172,11 +172,11 @@ namespace Lucene msg(L" name=" + info->name + L" docCount=" + StringUtils::toString(info->docCount)); segInfoStat->name = info->name; segInfoStat->docCount = info->docCount; - + int32_t toLoseDocCount = info->docCount; - + SegmentReaderPtr reader; - + try { msg(L" compound=" + StringUtils::toString(info->getUseCompoundFile())); @@ -191,7 +191,7 @@ namespace Lucene segInfoStat->diagnostics = diagnostics; if (!diagnostics.empty()) msg(L" diagnostics (size)= " + StringUtils::toString(diagnostics.size())); - + int32_t docStoreOffset = info->getDocStoreOffset(); if (docStoreOffset != -1) { @@ -216,26 +216,26 @@ namespace Lucene } msg(L" test: open reader........."); reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); - + segInfoStat->openReaderPassed = true; - + int32_t numDocs = reader->numDocs(); toLoseDocCount = numDocs; if (reader->hasDeletions()) { if (reader->deletedDocs->count() != info->getDelCount()) { - boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + + boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + L" vs deletedDocs.count()=" + StringUtils::toString(reader->deletedDocs->count()))); } if (reader->deletedDocs->count() > reader->maxDoc()) { - boost::throw_exception(RuntimeException(L"too many deleted docs: maxDoc()=" + StringUtils::toString(reader->maxDoc()) + + boost::throw_exception(RuntimeException(L"too many deleted docs: maxDoc()=" + StringUtils::toString(reader->maxDoc()) + L" vs deletedDocs.count()=" + StringUtils::toString(reader->deletedDocs->count()))); } if (info->docCount - numDocs != info->getDelCount()) { - boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + + boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + L" vs reader=" + StringUtils::toString((info->docCount - numDocs)))); } segInfoStat->numDeleted = info->docCount - numDocs; @@ -245,33 +245,33 @@ namespace Lucene { if (info->getDelCount() != 0) { - boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + + boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + L" vs reader=" + StringUtils::toString(info->docCount - numDocs))); } msg(L"OK"); } if (reader->maxDoc() != info->docCount) { - boost::throw_exception(RuntimeException(L"SegmentReader.maxDoc() " + StringUtils::toString(reader->maxDoc()) + + boost::throw_exception(RuntimeException(L"SegmentReader.maxDoc() " + StringUtils::toString(reader->maxDoc()) + L" != SegmentInfos.docCount " + StringUtils::toString(info->docCount))); } msg(L" test: fields.............."); HashSet fieldNames(reader->getFieldNames(IndexReader::FIELD_OPTION_ALL)); msg(L"OK [" + StringUtils::toString(fieldNames.size()) + L" fields]"); segInfoStat->numFields = fieldNames.size(); - + // Test Field Norms segInfoStat->fieldNormStatus = testFieldNorms(Collection::newInstance(fieldNames.begin(), fieldNames.end()), reader); - + // Test the Term Index segInfoStat->termIndexStatus = testTermIndex(info, reader); - + // Test Stored Fields segInfoStat->storedFieldStatus = testStoredFields(info, reader); - + // Test Term Vectors segInfoStat->termVectorStatus = testTermVectors(info, reader); - + // Rethrow the first exception we encountered. This will cause stats for failed segments to be incremented properly if (!segInfoStat->fieldNormStatus->error.isNull()) boost::throw_exception(RuntimeException(L"Field Norm test failed")); @@ -281,7 +281,7 @@ namespace Lucene boost::throw_exception(RuntimeException(L"Stored Field test failed")); else if (!segInfoStat->termVectorStatus->error.isNull()) boost::throw_exception(RuntimeException(L"Term Vector test failed")); - + msg(L""); } catch (...) @@ -292,19 +292,19 @@ namespace Lucene msg(L""); result->totLoseDocCount += toLoseDocCount; ++result->numBadSegments; - + if (reader) reader->close(); - + continue; } if (reader) reader->close(); - + // Keeper result->newSegments->add(boost::dynamic_pointer_cast(info->clone())); } - + if (result->numBadSegments == 0) { result->clean = true; @@ -312,23 +312,23 @@ namespace Lucene } else { - msg(L"WARNING: " + StringUtils::toString(result->numBadSegments) + - L" broken segments (containing " + StringUtils::toString(result->totLoseDocCount) + + msg(L"WARNING: " + StringUtils::toString(result->numBadSegments) + + L" broken segments (containing " + StringUtils::toString(result->totLoseDocCount) + L" documents) detected"); } - + return result; } - + FieldNormStatusPtr CheckIndex::testFieldNorms(Collection fieldNames, SegmentReaderPtr reader) { FieldNormStatusPtr status(newLucene()); - + try { // Test Field Norms msg(L" test: field norms........."); - + ByteArray b(ByteArray::newInstance(reader->maxDoc())); for (Collection::iterator fieldName = fieldNames.begin(); fieldName != fieldNames.end(); ++fieldName) { @@ -338,7 +338,7 @@ namespace Lucene ++status->totFields; } } - + msg(L"OK [" + StringUtils::toString(status->totFields) + L" fields]"); } catch (LuceneException& e) @@ -346,26 +346,26 @@ namespace Lucene msg(L"ERROR [" + e.getError() + L"]"); status->error = e; } - + return status; } - + TermIndexStatusPtr CheckIndex::testTermIndex(SegmentInfoPtr info, SegmentReaderPtr reader) { TermIndexStatusPtr status(newLucene()); - + try { msg(L" test: terms, freq, prox..."); - + TermEnumPtr termEnum(reader->terms()); TermPositionsPtr termPositions(reader->termPositions()); - + // Used only to count up # deleted docs for this term MySegmentTermDocsPtr myTermDocs(newLucene(reader)); - + int32_t maxDoc = reader->maxDoc(); - + while (termEnum->next()) { ++status->termCount; @@ -382,26 +382,26 @@ namespace Lucene int32_t freq = termPositions->freq(); if (doc <= lastDoc) { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + L" <= lastDoc " + StringUtils::toString(lastDoc))); } if (doc >= maxDoc) { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + L" >= maxDoc " + StringUtils::toString(maxDoc))); } - + lastDoc = doc; if (freq <= 0) { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + L": freq " + StringUtils::toString(freq) + L" is out of bounds")); } - + int32_t lastPos = -1; status->totPos += freq; for (int32_t j = 0; j < freq; ++j) @@ -409,22 +409,22 @@ namespace Lucene int32_t pos = termPositions->nextPosition(); if (pos < -1) { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + L": pos " + StringUtils::toString(pos) + L" is out of bounds")); } if (pos < lastPos) { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + L": pos " + StringUtils::toString(pos) + L" < lastPos " + StringUtils::toString(lastPos))); } lastPos = pos; } } - + // Now count how many deleted docs occurred in this term int32_t delCount; if (reader->hasDeletions()) @@ -437,17 +437,17 @@ namespace Lucene } else delCount = 0; - + if (freq0 + delCount != docFreq) { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L"docFreq=" + StringUtils::toString(docFreq) + + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L"docFreq=" + StringUtils::toString(docFreq) + L" != num docs seen " + StringUtils::toString(freq0) + L" + num docs deleted " + StringUtils::toString(delCount))); } } - - msg(L"OK [" + StringUtils::toString(status->termCount) + L" terms; " + StringUtils::toString(status->totFreq) + + + msg(L"OK [" + StringUtils::toString(status->termCount) + L" terms; " + StringUtils::toString(status->totFreq) + L" terms/docs pairs; " + StringUtils::toString(status->totPos) + L" tokens]"); } catch (LuceneException& e) @@ -455,18 +455,18 @@ namespace Lucene msg(L"ERROR [" + e.getError() + L"]"); status->error = e; } - + return status; } - + StoredFieldStatusPtr CheckIndex::testStoredFields(SegmentInfoPtr info, SegmentReaderPtr reader) { StoredFieldStatusPtr status(newLucene()); - + try { msg(L" test: stored fields......."); - + // Scan stored fields for all documents for (int32_t j = 0; j < info->docCount; ++j) { @@ -477,16 +477,16 @@ namespace Lucene status->totFields += doc->getFields().size(); } } - + // Validate docCount if (status->docCount != reader->numDocs()) { - boost::throw_exception(RuntimeException(L"docCount=" + StringUtils::toString(status->docCount) + - L" but saw " + StringUtils::toString(status->docCount) + + boost::throw_exception(RuntimeException(L"docCount=" + StringUtils::toString(status->docCount) + + L" but saw " + StringUtils::toString(status->docCount) + L" undeleted docs")); } - - msg(L"OK [" + StringUtils::toString(status->totFields) + L" total field count; avg " + + + msg(L"OK [" + StringUtils::toString(status->totFields) + L" total field count; avg " + StringUtils::toString((double)status->totFields / (double)status->docCount) + L" fields per doc]"); } catch (LuceneException& e) @@ -494,18 +494,18 @@ namespace Lucene msg(L"ERROR [" + e.getError() + L"]"); status->error = e; } - + return status; } - + TermVectorStatusPtr CheckIndex::testTermVectors(SegmentInfoPtr info, SegmentReaderPtr reader) { TermVectorStatusPtr status(newLucene()); - + try { msg(L" test: term vectors........"); - + for (int32_t j = 0; j < info->docCount; ++j) { if (!reader->isDeleted(j)) @@ -516,8 +516,8 @@ namespace Lucene status->totVectors += tfv.size(); } } - - msg(L"OK [" + StringUtils::toString(status->totVectors) + L" total vector count; avg " + + + msg(L"OK [" + StringUtils::toString(status->totVectors) + L" total vector count; avg " + StringUtils::toString((double)status->totVectors / (double)status->docCount) + L" term/freq vector fields per doc]"); } catch (LuceneException& e) @@ -525,29 +525,29 @@ namespace Lucene msg(L"ERROR [" + e.getError() + L"]"); status->error = e; } - + return status; } - + void CheckIndex::fixIndex(IndexStatusPtr result) { if (result->partial) boost::throw_exception(IllegalArgumentException(L"can only fix an index that was fully checked (this status checked a subset of segments)")); result->newSegments->commit(result->dir); } - + bool CheckIndex::testAsserts() { _assertsOn = true; return true; } - + bool CheckIndex::assertsOn() { BOOST_ASSERT(testAsserts()); return _assertsOn; } - + int CheckIndex::main(Collection args) { bool doFix = false; @@ -577,7 +577,7 @@ namespace Lucene indexPath = *arg; } } - + if (indexPath.empty()) { std::wcout << L"\nERROR: index path not specified\n"; @@ -603,10 +603,10 @@ namespace Lucene std::wcout << L"corruption, else 0.\n\n"; return 1; } - + if (!assertsOn()) std::wcout << L"\nNOTE: testing will be more thorough if you run with '-ea', so assertions are enabled\n"; - + if (onlySegments.empty()) onlySegments.reset(); else if (doFix) @@ -614,7 +614,7 @@ namespace Lucene std::wcout << L"ERROR: cannot specify both -fix and -segment\n"; return 1; } - + std::wcout << L"\nOpening index @ " << indexPath << L"\n\n"; DirectoryPtr dir; try @@ -626,14 +626,14 @@ namespace Lucene std::wcout << L"ERROR: could not open directory \"" << indexPath << L"\"; exiting\n"; return 1; } - + CheckIndexPtr checker(newLucene(dir)); checker->setInfoStream(newLucene()); - + IndexStatusPtr result(checker->checkIndex(onlySegments)); if (result->missingSegments) return 1; - + if (!result->clean) { if (!doFix) @@ -654,11 +654,11 @@ namespace Lucene std::wcout << L"Wrote new segments file \"" << result->newSegments->getCurrentSegmentFileName() << L"\"\n"; } } - + std::wcout << L"\n"; return ((result && result->clean) ? 0 : 1); } - + IndexStatus::IndexStatus() { clean = false; @@ -673,11 +673,11 @@ namespace Lucene numBadSegments = 0; partial = false; } - + IndexStatus::~IndexStatus() { } - + SegmentInfoStatus::SegmentInfoStatus() { docCount = 0; @@ -692,66 +692,66 @@ namespace Lucene numFields = 0; hasProx = false; } - + SegmentInfoStatus::~SegmentInfoStatus() { } - + FieldNormStatus::FieldNormStatus() { totFields = 0; } - + FieldNormStatus::~FieldNormStatus() { } - + TermIndexStatus::TermIndexStatus() { termCount = 0; totFreq = 0; totPos = 0; } - + TermIndexStatus::~TermIndexStatus() { } - + StoredFieldStatus::StoredFieldStatus() { docCount = 0; totFields = 0; } - + StoredFieldStatus::~StoredFieldStatus() { } - + TermVectorStatus::TermVectorStatus() { docCount = 0; totVectors = 0; } - + TermVectorStatus::~TermVectorStatus() { } - + MySegmentTermDocs::MySegmentTermDocs(SegmentReaderPtr p) : SegmentTermDocs(p) { delCount = 0; } - + MySegmentTermDocs::~MySegmentTermDocs() { } - + void MySegmentTermDocs::seek(TermPtr term) { SegmentTermDocs::seek(term); delCount = 0; } - + void MySegmentTermDocs::skippingDoc() { ++delCount; diff --git a/src/core/index/CompoundFileReader.cpp b/src/core/index/CompoundFileReader.cpp index b2c81219..601f9977 100644 --- a/src/core/index/CompoundFileReader.cpp +++ b/src/core/index/CompoundFileReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,61 +13,61 @@ namespace Lucene { ConstructReader(dir, name, BufferedIndexInput::BUFFER_SIZE); } - + CompoundFileReader::CompoundFileReader(DirectoryPtr dir, const String& name, int32_t readBufferSize) { ConstructReader(dir, name, readBufferSize); } - + CompoundFileReader::~CompoundFileReader() { } - + void CompoundFileReader::ConstructReader(DirectoryPtr dir, const String& name, int32_t readBufferSize) { directory = dir; fileName = name; this->readBufferSize = readBufferSize; this->entries = MapStringFileEntryPtr::newInstance(); - + bool success = false; - + LuceneException finally; try { stream = dir->openInput(name, readBufferSize); - + // read the directory and init files int32_t count = stream->readVInt(); - + FileEntryPtr entry; for (int32_t i = 0; i < count; ++i) { int64_t offset = stream->readLong(); String id(stream->readString()); - + if (entry) { // set length of the previous entry entry->length = offset - entry->offset; } - + entry = newInstance(); entry->offset = offset; entries.put(id, entry); } - + // set the length of the final entry if (entry) entry->length = stream->length() - entry->offset; - + success = true; } catch (LuceneException& e) { finally = e; } - + if (!success && stream) { try @@ -78,51 +78,51 @@ namespace Lucene { } } - + finally.throwException(); } - + DirectoryPtr CompoundFileReader::getDirectory() { return directory; } - + String CompoundFileReader::getName() { return fileName; } - + void CompoundFileReader::close() { SyncLock syncLock(this); if (!stream) boost::throw_exception(IOException(L"Already closed")); - + entries.clear(); stream->close(); stream.reset(); } - + IndexInputPtr CompoundFileReader::openInput(const String& name) { SyncLock syncLock(this); // Default to readBufferSize passed in when we were opened return openInput(name, readBufferSize); } - + IndexInputPtr CompoundFileReader::openInput(const String& name, int32_t bufferSize) { SyncLock syncLock(this); if (!stream) boost::throw_exception(IOException(L"Stream closed")); - + MapStringFileEntryPtr::iterator entry = entries.find(name); if (entry == entries.end()) boost::throw_exception(IOException(L"No sub-file with id " + name + L" found")); - + return newLucene(stream, entry->second->offset, entry->second->length, readBufferSize); } - + HashSet CompoundFileReader::listAll() { HashSet res(HashSet::newInstance()); @@ -130,32 +130,32 @@ namespace Lucene res.add(entry->first); return res; } - + bool CompoundFileReader::fileExists(const String& name) { return entries.contains(name); } - + uint64_t CompoundFileReader::fileModified(const String& name) { return directory->fileModified(fileName); } - + void CompoundFileReader::touchFile(const String& name) { directory->touchFile(fileName); } - + void CompoundFileReader::deleteFile(const String& name) { boost::throw_exception(UnsupportedOperationException()); } - + void CompoundFileReader::renameFile(const String& from, const String& to) { boost::throw_exception(UnsupportedOperationException()); } - + int64_t CompoundFileReader::fileLength(const String& name) { MapStringFileEntryPtr::iterator entry = entries.find(name); @@ -163,43 +163,43 @@ namespace Lucene boost::throw_exception(IOException(L"File " + name + L" does not exist")); return entry->second->length; } - + IndexOutputPtr CompoundFileReader::createOutput(const String& name) { boost::throw_exception(UnsupportedOperationException()); return IndexOutputPtr(); } - + LockPtr CompoundFileReader::makeLock(const String& name) { boost::throw_exception(UnsupportedOperationException()); return LockPtr(); } - + CSIndexInput::CSIndexInput() { fileOffset = 0; _length = 0; } - + CSIndexInput::CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length) : BufferedIndexInput(BufferedIndexInput::BUFFER_SIZE) { this->base = boost::dynamic_pointer_cast(base->clone()); this->fileOffset = fileOffset; this->_length = length; } - + CSIndexInput::CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length, int32_t readBufferSize) : BufferedIndexInput(readBufferSize) { this->base = boost::dynamic_pointer_cast(base->clone()); this->fileOffset = fileOffset; this->_length = length; } - + CSIndexInput::~CSIndexInput() { } - + void CSIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) { int64_t start = getFilePointer(); @@ -208,21 +208,21 @@ namespace Lucene base->seek(fileOffset + start); base->readBytes(b, offset, length, false); } - + void CSIndexInput::seekInternal(int64_t pos) { } - + void CSIndexInput::close() { base->close(); } - + int64_t CSIndexInput::length() { return _length; } - + LuceneObjectPtr CSIndexInput::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); diff --git a/src/core/index/CompoundFileWriter.cpp b/src/core/index/CompoundFileWriter.cpp index 0c15d48d..89da3372 100644 --- a/src/core/index/CompoundFileWriter.cpp +++ b/src/core/index/CompoundFileWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/ConcurrentMergeScheduler.cpp b/src/core/index/ConcurrentMergeScheduler.cpp index fe4933ee..71b75dac 100644 --- a/src/core/index/ConcurrentMergeScheduler.cpp +++ b/src/core/index/ConcurrentMergeScheduler.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene { Collection ConcurrentMergeScheduler::allInstances; bool ConcurrentMergeScheduler::anyExceptions = false; - + ConcurrentMergeScheduler::ConcurrentMergeScheduler() { mergeThreadPriority = -1; @@ -24,62 +24,62 @@ namespace Lucene suppressExceptions = false; closed = false; } - + ConcurrentMergeScheduler::~ConcurrentMergeScheduler() { } - + void ConcurrentMergeScheduler::initialize() { // Only for testing if (allInstances) addMyself(); } - + void ConcurrentMergeScheduler::setMaxThreadCount(int32_t count) { if (count < 1) boost::throw_exception(IllegalArgumentException(L"count should be at least 1")); maxThreadCount = count; } - + int32_t ConcurrentMergeScheduler::getMaxThreadCount() { return maxThreadCount; } - + int32_t ConcurrentMergeScheduler::getMergeThreadPriority() { SyncLock syncLock(this); initMergeThreadPriority(); return mergeThreadPriority; } - + void ConcurrentMergeScheduler::setMergeThreadPriority(int32_t pri) { SyncLock syncLock(this); if (pri > LuceneThread::MAX_PRIORITY || pri < LuceneThread::MIN_PRIORITY) { - boost::throw_exception(IllegalArgumentException(L"priority must be in range " + StringUtils::toString(LuceneThread::MIN_PRIORITY) + + boost::throw_exception(IllegalArgumentException(L"priority must be in range " + StringUtils::toString(LuceneThread::MIN_PRIORITY) + L" .. " + StringUtils::toString(LuceneThread::MAX_PRIORITY) + L" inclusive")); } mergeThreadPriority = pri; - + for (SetMergeThread::iterator merge = mergeThreads.begin(); merge != mergeThreads.end(); ++merge) (*merge)->setThreadPriority(pri); } - + bool ConcurrentMergeScheduler::verbose() { return (!_writer.expired() && IndexWriterPtr(_writer)->verbose()); } - + void ConcurrentMergeScheduler::message(const String& message) { if (verbose() && !_writer.expired()) IndexWriterPtr(_writer)->message(L"CMS: " + message); } - + void ConcurrentMergeScheduler::initMergeThreadPriority() { SyncLock syncLock(this); @@ -89,13 +89,13 @@ namespace Lucene mergeThreadPriority = std::min(LuceneThread::NORM_PRIORITY + 1, LuceneThread::MAX_PRIORITY); } } - + void ConcurrentMergeScheduler::close() { sync(); closed = true; } - + void ConcurrentMergeScheduler::sync() { SyncLock syncLock(this); @@ -106,7 +106,7 @@ namespace Lucene } mergeThreads.clear(); } - + int32_t ConcurrentMergeScheduler::mergeThreadCount() { SyncLock syncLock(this); @@ -118,23 +118,23 @@ namespace Lucene } return count; } - + void ConcurrentMergeScheduler::merge(IndexWriterPtr writer) { BOOST_ASSERT(!writer->holdsLock()); - + this->_writer = writer; - + initMergeThreadPriority(); - + dir = writer->getDirectory(); - + // First, quickly run through the newly proposed merges and add any orthogonal merges (ie a merge not - // involving segments already pending to be merged) to the queue. If we are way behind on merging, + // involving segments already pending to be merged) to the queue. If we are way behind on merging, // many of these newly proposed merges will likely already be registered. message(L"now merge"); message(L" index: " + writer->segString()); - + // Iterate, pulling from the IndexWriter's queue of pending merges, until it's empty while (true) { @@ -144,10 +144,10 @@ namespace Lucene message(L" no more merges pending; now return"); return; } - + // We do this with the primary thread to keep deterministic assignment of segment names writer->mergeInit(merge); - + bool success = false; LuceneException finally; try @@ -159,16 +159,16 @@ namespace Lucene message(L" too many merge threads running; stalling..."); wait(1000); } - + message(L" consider merge " + merge->segString(dir)); - + BOOST_ASSERT(mergeThreadCount() < maxThreadCount); - + // OK to spawn a new merge thread to handle this merge merger = getMergeThread(writer, merge); mergeThreads.add(merger); message(L" launch new thread"); - + merger->start(); success = true; } @@ -181,13 +181,13 @@ namespace Lucene finally.throwException(); } } - + void ConcurrentMergeScheduler::doMerge(OneMergePtr merge) { TestScope testScope(L"ConcurrentMergeScheduler", L"doMerge"); IndexWriterPtr(_writer)->merge(merge); } - + MergeThreadPtr ConcurrentMergeScheduler::getMergeThread(IndexWriterPtr writer, OneMergePtr merge) { SyncLock syncLock(this); @@ -195,16 +195,16 @@ namespace Lucene thread->setThreadPriority(mergeThreadPriority); return thread; } - + void ConcurrentMergeScheduler::handleMergeException(const LuceneException& exc) { - // When an exception is hit during merge, IndexWriter removes any partial files and then - // allows another merge to run. If whatever caused the error is not transient then the + // When an exception is hit during merge, IndexWriter removes any partial files and then + // allows another merge to run. If whatever caused the error is not transient then the // exception will keep happening, so, we sleep here to avoid saturating CPU in such cases LuceneThread::threadSleep(250); // pause 250 msec boost::throw_exception(MergeException()); } - + bool ConcurrentMergeScheduler::anyUnhandledExceptions() { if (!allInstances) @@ -216,13 +216,13 @@ namespace Lucene anyExceptions = false; return v; } - + void ConcurrentMergeScheduler::clearUnhandledExceptions() { SyncLock instancesLock(&allInstances); anyExceptions = false; } - + void ConcurrentMergeScheduler::addMyself() { SyncLock instancesLock(&allInstances); @@ -236,52 +236,52 @@ namespace Lucene // Keep this one for now: it still has threads or may spawn new threads allInstances[upto++] = other; } - + allInstances.remove(allInstances.begin() + upto, allInstances.end()); allInstances.add(shared_from_this()); } } - + void ConcurrentMergeScheduler::setSuppressExceptions() { suppressExceptions = true; } - + void ConcurrentMergeScheduler::clearSuppressExceptions() { suppressExceptions = false; } - + void ConcurrentMergeScheduler::setTestMode() { allInstances = Collection::newInstance(); } - + MergeThread::MergeThread(ConcurrentMergeSchedulerPtr merger, IndexWriterPtr writer, OneMergePtr startMerge) { this->_merger = merger; this->_writer = writer; this->startMerge = startMerge; } - + MergeThread::~MergeThread() { } - + void MergeThread::setRunningMerge(OneMergePtr merge) { ConcurrentMergeSchedulerPtr merger(_merger); SyncLock syncLock(merger); runningMerge = merge; } - + OneMergePtr MergeThread::getRunningMerge() { ConcurrentMergeSchedulerPtr merger(_merger); SyncLock syncLock(merger); return runningMerge; } - + void MergeThread::setThreadPriority(int32_t pri) { try @@ -292,24 +292,24 @@ namespace Lucene { } } - + void MergeThread::run() { // First time through the while loop we do the merge that we were started with OneMergePtr merge(this->startMerge); ConcurrentMergeSchedulerPtr merger(_merger); - + LuceneException finally; try { merger->message(L" merge thread: start"); IndexWriterPtr writer(_writer); - + while (true) { setRunningMerge(merge); merger->doMerge(merge); - + // Subsequent times through the loop we do any new merge that writer says is necessary merge = writer->getNextMerge(); if (merge) @@ -320,7 +320,7 @@ namespace Lucene else break; } - + merger->message(L" merge thread: done"); } catch (MergeAbortedException&) @@ -338,11 +338,11 @@ namespace Lucene else finally = e; } - + { SyncLock syncLock(merger); merger->notifyAll(); - + bool removed = merger->mergeThreads.remove(shared_from_this()); BOOST_ASSERT(removed); } diff --git a/src/core/index/DefaultSkipListReader.cpp b/src/core/index/DefaultSkipListReader.cpp index 805556b5..5e9ab354 100644 --- a/src/core/index/DefaultSkipListReader.cpp +++ b/src/core/index/DefaultSkipListReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,47 +17,47 @@ namespace Lucene lastFreqPointer = 0; lastProxPointer = 0; lastPayloadLength = 0; - + freqPointer = Collection::newInstance(maxSkipLevels); proxPointer = Collection::newInstance(maxSkipLevels); payloadLength = Collection::newInstance(maxSkipLevels); - + MiscUtils::arrayFill(freqPointer.begin(), 0, freqPointer.size(), 0); MiscUtils::arrayFill(proxPointer.begin(), 0, proxPointer.size(), 0); MiscUtils::arrayFill(payloadLength.begin(), 0, payloadLength.size(), 0); } - + DefaultSkipListReader::~DefaultSkipListReader() { } - + void DefaultSkipListReader::init(int64_t skipPointer, int64_t freqBasePointer, int64_t proxBasePointer, int32_t df, bool storesPayloads) { MultiLevelSkipListReader::init(skipPointer, df); this->currentFieldStoresPayloads = storesPayloads; lastFreqPointer = freqBasePointer; lastProxPointer = proxBasePointer; - + MiscUtils::arrayFill(freqPointer.begin(), 0, freqPointer.size(), freqBasePointer); MiscUtils::arrayFill(proxPointer.begin(), 0, proxPointer.size(), proxBasePointer); MiscUtils::arrayFill(payloadLength.begin(), 0, payloadLength.size(), 0); } - + int64_t DefaultSkipListReader::getFreqPointer() { return lastFreqPointer; } - + int64_t DefaultSkipListReader::getProxPointer() { return lastProxPointer; } - + int32_t DefaultSkipListReader::getPayloadLength() { return lastPayloadLength; } - + void DefaultSkipListReader::seekChild(int32_t level) { MultiLevelSkipListReader::seekChild(level); @@ -65,7 +65,7 @@ namespace Lucene proxPointer[level] = lastProxPointer; payloadLength[level] = lastPayloadLength; } - + void DefaultSkipListReader::setLastSkipData(int32_t level) { MultiLevelSkipListReader::setLastSkipData(level); @@ -73,13 +73,13 @@ namespace Lucene lastProxPointer = proxPointer[level]; lastPayloadLength = payloadLength[level]; } - + int32_t DefaultSkipListReader::readSkipData(int32_t level, IndexInputPtr skipStream) { int32_t delta; if (currentFieldStoresPayloads) { - // The current field stores payloads. If the doc delta is odd then we have to read the current + // The current field stores payloads. If the doc delta is odd then we have to read the current // payload length because it differs from the length of the previous payload delta = skipStream->readVInt(); if ((delta & 1) != 0) @@ -88,10 +88,10 @@ namespace Lucene } else delta = skipStream->readVInt(); - + freqPointer[level] += skipStream->readVInt(); proxPointer[level] += skipStream->readVInt(); - + return delta; } } diff --git a/src/core/index/DefaultSkipListWriter.cpp b/src/core/index/DefaultSkipListWriter.cpp index 3963ced3..64d7219c 100644 --- a/src/core/index/DefaultSkipListWriter.cpp +++ b/src/core/index/DefaultSkipListWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,7 +18,7 @@ namespace Lucene curPayloadLength = 0; curFreqPointer = 0; curProxPointer = 0; - + this->freqOutput = freqOutput; this->proxOutput = proxOutput; @@ -27,21 +27,21 @@ namespace Lucene lastSkipFreqPointer = Collection::newInstance(numberOfSkipLevels); lastSkipProxPointer = Collection::newInstance(numberOfSkipLevels); } - + DefaultSkipListWriter::~DefaultSkipListWriter() { } - + void DefaultSkipListWriter::setFreqOutput(IndexOutputPtr freqOutput) { this->freqOutput = freqOutput; } - + void DefaultSkipListWriter::setProxOutput(IndexOutputPtr proxOutput) { this->proxOutput = proxOutput; } - + void DefaultSkipListWriter::setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength) { this->curDoc = doc; @@ -51,7 +51,7 @@ namespace Lucene if (proxOutput) this->curProxPointer = proxOutput->getFilePointer(); } - + void DefaultSkipListWriter::resetSkip() { MultiLevelSkipListWriter::resetSkip(); @@ -61,7 +61,7 @@ namespace Lucene if (proxOutput) MiscUtils::arrayFill(lastSkipProxPointer.begin(), 0, lastSkipProxPointer.size(), proxOutput->getFilePointer()); } - + void DefaultSkipListWriter::writeSkipData(int32_t level, IndexOutputPtr skipBuffer) { // To efficiently store payloads in the posting lists we do not store the length of @@ -72,12 +72,12 @@ namespace Lucene // Case 1: current field does not store payloads // SkipDatum --> DocSkip, FreqSkip, ProxSkip // DocSkip,FreqSkip,ProxSkip --> VInt - // DocSkip records the document number before every SkipInterval th document in TermFreqs. + // DocSkip records the document number before every SkipInterval th document in TermFreqs. // Document numbers are represented as differences from the previous value in the sequence. // Case 2: current field stores payloads // SkipDatum --> DocSkip, PayloadLength?, FreqSkip,ProxSkip // DocSkip,FreqSkip,ProxSkip --> VInt - // PayloadLength --> VInt + // PayloadLength --> VInt // In this case DocSkip/2 is the difference between // the current and the previous value. If DocSkip // is odd, then a PayloadLength encoded as VInt follows, @@ -89,13 +89,13 @@ namespace Lucene int32_t delta = curDoc - lastSkipDoc[level]; if (curPayloadLength == lastSkipPayloadLength[level]) { - // the current payload length equals the length at the previous skip point, so we don't store + // the current payload length equals the length at the previous skip point, so we don't store // the length again skipBuffer->writeVInt(delta * 2); } else { - // the payload length is different from the previous one. We shift the DocSkip, set the lowest + // the payload length is different from the previous one. We shift the DocSkip, set the lowest // bit and store the current payload length as VInt. skipBuffer->writeVInt(delta * 2 + 1); skipBuffer->writeVInt(curPayloadLength); @@ -109,7 +109,7 @@ namespace Lucene } skipBuffer->writeVInt((int32_t)(curFreqPointer - lastSkipFreqPointer[level])); skipBuffer->writeVInt((int32_t)(curProxPointer - lastSkipProxPointer[level])); - + lastSkipDoc[level] = curDoc; lastSkipFreqPointer[level] = curFreqPointer; diff --git a/src/core/index/DirectoryReader.cpp b/src/core/index/DirectoryReader.cpp index 9fddf414..5c32560f 100644 --- a/src/core/index/DirectoryReader.cpp +++ b/src/core/index/DirectoryReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -38,7 +38,7 @@ namespace Lucene synced = HashSet::newInstance(); stale = false; rollbackHasChanges = false; - + this->_directory = directory; this->readOnly = readOnly; this->segmentInfos = sis; @@ -51,11 +51,11 @@ namespace Lucene HashSet files(sis->files(directory, true)); synced.addAll(files.begin(), files.end()); } - + // To reduce the chance of hitting FileNotFound (and having to retry), we open segments in // reverse because IndexWriter merges & deletes the newest segments first. Collection readers(Collection::newInstance(sis->size())); - + for (int32_t i = sis->size() - 1; i >= 0; --i) { bool success = false; @@ -87,10 +87,10 @@ namespace Lucene } finally.throwException(); } - + _initialize(readers); } - + DirectoryReader::DirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor) { normsCache = MapStringByteArray::newInstance(); @@ -100,27 +100,27 @@ namespace Lucene synced = HashSet::newInstance(); stale = false; rollbackHasChanges = false; - + this->_directory = writer->getDirectory(); this->readOnly = true; this->segmentInfos = infos; this->segmentInfosStart = boost::dynamic_pointer_cast(infos->clone()); this->termInfosIndexDivisor = termInfosIndexDivisor; - + if (!readOnly) { // We assume that this segments_N was previously properly sync'd HashSet files(infos->files(_directory, true)); synced.addAll(files.begin(), files.end()); } - + // IndexWriter synchronizes externally before calling us, which ensures infos will not change; so there's // no need to process segments in reverse order int32_t numSegments = infos->size(); Collection readers(Collection::newInstance(numSegments)); DirectoryPtr dir(writer->getDirectory()); int32_t upto = 0; - + for (int32_t i = 0; i < numSegments; ++i) { bool success = false; @@ -154,20 +154,20 @@ namespace Lucene } finally.throwException(); } - + this->_writer = writer; - + if (upto < readers.size()) { // This means some segments were in a foreign Directory readers.resize(upto); } - + _initialize(readers); } - - DirectoryReader::DirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, - Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, + + DirectoryReader::DirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, + Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, bool doClone, int32_t termInfosIndexDivisor) { normsCache = MapStringByteArray::newInstance(); @@ -177,7 +177,7 @@ namespace Lucene synced = HashSet::newInstance(); stale = false; rollbackHasChanges = false; - + this->_directory = directory; this->readOnly = readOnly; this->segmentInfos = infos; @@ -188,10 +188,10 @@ namespace Lucene HashSet files(infos->files(directory, true)); synced.addAll(files.begin(), files.end()); } - + // we put the old SegmentReaders in a map, that allows us to lookup a reader using its segment name MapStringInt segmentReaders(MapStringInt::newInstance()); - + if (oldReaders) { int32_t segReader = 0; @@ -199,12 +199,12 @@ namespace Lucene for (Collection::iterator reader = oldReaders.begin(); reader != oldReaders.end(); ++reader) segmentReaders.put((*reader)->getSegmentName(), segReader++); } - + Collection newReaders(Collection::newInstance(infos->size())); - + // remember which readers are shared between the old and the re-opened DirectoryReader - we have to incRef those readers Collection readerShared(Collection::newInstance(infos->size())); - + for (int32_t i = infos->size() - 1; i >= 0; --i) { // find SegmentReader for this segment @@ -219,7 +219,7 @@ namespace Lucene // there is an old reader for this segment - we'll try to reopen it newReaders[i] = oldReaders[oldReaderIndex->second]; } - + bool success = false; LuceneException finally; try @@ -229,13 +229,13 @@ namespace Lucene { // We should never see a totally new segment during cloning BOOST_ASSERT(!doClone); - + // this is a new reader; in case we hit an exception we can close it safely newReader = SegmentReader::get(readOnly, infos->info(i), termInfosIndexDivisor); } else newReader = newReaders[i]->reopenSegment(infos->info(i), doClone, readOnly); - + if (newReader == newReaders[i]) { // this reader will be shared between the old and the new one, so we must incRef it @@ -281,10 +281,10 @@ namespace Lucene } finally.throwException(); } - + // initialize the readers to calculate maxDoc before we try to reuse the old normsCache _initialize(newReaders); - + // try to copy unchanged norms from the old normsCache to the new one if (oldNormsCache) { @@ -292,34 +292,34 @@ namespace Lucene { if (!hasNorms(entry->first)) continue; - + ByteArray bytes(ByteArray::newInstance(maxDoc())); - + for (int32_t i = 0; i < subReaders.size(); ++i) { MapStringInt::iterator oldReaderIndex = segmentReaders.find(subReaders[i]->getSegmentName()); - - // this SegmentReader was not re-opened, we can copy all of its norms - if (oldReaderIndex != segmentReaders.end() && (oldReaders[oldReaderIndex->second] == subReaders[i] + + // this SegmentReader was not re-opened, we can copy all of its norms + if (oldReaderIndex != segmentReaders.end() && (oldReaders[oldReaderIndex->second] == subReaders[i] || oldReaders[oldReaderIndex->second]->_norms.get(entry->first) == subReaders[i]->_norms.get(entry->first))) { - // we don't have to synchronize here: either this constructor is called from a SegmentReader, in which + // we don't have to synchronize here: either this constructor is called from a SegmentReader, in which // case no old norms cache is present, or it is called from MultiReader.reopen(), which is synchronized MiscUtils::arrayCopy(entry->second.get(), oldStarts[oldReaderIndex->second], bytes.get(), starts[i], starts[i + 1] - starts[i]); } else subReaders[i]->norms(entry->first, bytes, starts[i]); } - + normsCache.put(entry->first, bytes); // update cache } } } - + DirectoryReader::~DirectoryReader() { } - + void DirectoryReader::_initialize(Collection subReaders) { this->subReaders = subReaders; @@ -328,21 +328,21 @@ namespace Lucene { starts[i] = _maxDoc; _maxDoc += subReaders[i]->maxDoc(); // compute maxDocs - + if (subReaders[i]->hasDeletions()) _hasDeletions = true; } starts[subReaders.size()] = _maxDoc; - + if (!readOnly) maxIndexVersion = SegmentInfos::readCurrentVersion(_directory); } - + IndexReaderPtr DirectoryReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor) { return newLucene(readOnly, deletionPolicy, termInfosIndexDivisor, newLucene(), directory)->run(commit); } - + LuceneObjectPtr DirectoryReader::clone(LuceneObjectPtr other) { try @@ -355,17 +355,17 @@ namespace Lucene } return DirectoryReaderPtr(); } - + LuceneObjectPtr DirectoryReader::clone(bool openReadOnly, LuceneObjectPtr other) { SyncLock syncLock(this); DirectoryReaderPtr newReader(doReopen(boost::dynamic_pointer_cast(segmentInfos->clone()), true, openReadOnly)); - + if (shared_from_this() != newReader) newReader->deletionPolicy = deletionPolicy; - + newReader->_writer = _writer; - + // If we're cloning a non-readOnly reader, move the writeLock (if there is one) to the new reader if (!openReadOnly && writeLock) { @@ -377,54 +377,54 @@ namespace Lucene writeLock.reset(); _hasChanges = false; } - + return newReader; } - + IndexReaderPtr DirectoryReader::reopen() { // Preserve current readOnly return doReopen(readOnly, IndexCommitPtr()); } - + IndexReaderPtr DirectoryReader::reopen(bool openReadOnly) { return doReopen(openReadOnly, IndexCommitPtr()); } - + IndexReaderPtr DirectoryReader::reopen(IndexCommitPtr commit) { return doReopen(true, commit); } - + IndexReaderPtr DirectoryReader::doReopenFromWriter(bool openReadOnly, IndexCommitPtr commit) { BOOST_ASSERT(readOnly); - + if (!openReadOnly) boost::throw_exception(IllegalArgumentException(L"a reader obtained from IndexWriter.getReader() can only be reopened with openReadOnly=true (got false)")); - + if (commit) boost::throw_exception(IllegalArgumentException(L"a reader obtained from IndexWriter.getReader() cannot currently accept a commit")); - + return IndexWriterPtr(_writer)->getReader(); } - + IndexReaderPtr DirectoryReader::doReopen(bool openReadOnly, IndexCommitPtr commit) { ensureOpen(); - + BOOST_ASSERT(!commit || openReadOnly); - + IndexWriterPtr writer(_writer.lock()); - + // If we were obtained by writer.getReader(), re-ask the writer to get a new reader. if (writer) return doReopenFromWriter(openReadOnly, commit); else return doReopenNoWriter(openReadOnly, commit); } - + IndexReaderPtr DirectoryReader::doReopenNoWriter(bool openReadOnly, IndexCommitPtr commit) { SyncLock syncLock(this); @@ -438,7 +438,7 @@ namespace Lucene BOOST_ASSERT(writeLock); // so no other writer holds the write lock, which means no changes could have been done to the index BOOST_ASSERT(isCurrent()); - + if (openReadOnly) return boost::dynamic_pointer_cast(clone(openReadOnly)); else @@ -470,10 +470,10 @@ namespace Lucene return shared_from_this(); } } - + return newLucene(shared_from_this(), openReadOnly, newLucene(), _directory)->run(commit); } - + DirectoryReaderPtr DirectoryReader::doReopen(SegmentInfosPtr infos, bool doClone, bool openReadOnly) { SyncLock syncLock(this); @@ -482,51 +482,51 @@ namespace Lucene else return newLucene(_directory, infos, subReaders, starts, normsCache, false, doClone, termInfosIndexDivisor); } - + int64_t DirectoryReader::getVersion() { ensureOpen(); return segmentInfos->getVersion(); } - + Collection DirectoryReader::getTermFreqVectors(int32_t docNumber) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num return subReaders[i]->getTermFreqVectors(docNumber - starts[i]); // dispatch to segment } - + TermFreqVectorPtr DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); } - + void DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); } - + void DirectoryReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num subReaders[i]->getTermFreqVector(docNumber - starts[i], mapper); } - + bool DirectoryReader::isOptimized() { ensureOpen(); return (segmentInfos->size() == 1 && !hasDeletions()); } - + int32_t DirectoryReader::numDocs() { // Don't call ensureOpen() here (it could affect performance) - + // NOTE: multiple threads may wind up init'ing numDocs... but that's harmless if (_numDocs == -1) // check cache { @@ -537,33 +537,33 @@ namespace Lucene } return _numDocs; } - + int32_t DirectoryReader::maxDoc() { // Don't call ensureOpen() here (it could affect performance) return _maxDoc; } - + DocumentPtr DirectoryReader::document(int32_t n, FieldSelectorPtr fieldSelector) { ensureOpen(); int32_t i = readerIndex(n); // find segment num return subReaders[i]->document(n - starts[i], fieldSelector); // dispatch to segment reader } - + bool DirectoryReader::isDeleted(int32_t n) { // Don't call ensureOpen() here (it could affect performance) int32_t i = readerIndex(n); // find segment num return subReaders[i]->isDeleted(n - starts[i]); // dispatch to segment reader } - + bool DirectoryReader::hasDeletions() { // Don't call ensureOpen() here (it could affect performance) return _hasDeletions; } - + void DirectoryReader::doDelete(int32_t docNum) { _numDocs = -1; // invalidate cache @@ -571,7 +571,7 @@ namespace Lucene subReaders[i]->deleteDocument(docNum - starts[i]); // dispatch to segment reader _hasDeletions = true; } - + void DirectoryReader::doUndeleteAll() { for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) @@ -579,19 +579,19 @@ namespace Lucene _hasDeletions = false; _numDocs = -1; // invalidate cache } - + int32_t DirectoryReader::readerIndex(int32_t n) { return readerIndex(n, this->starts, this->subReaders.size()); } - + int32_t DirectoryReader::readerIndex(int32_t n, Collection starts, int32_t numSubReaders) { // Binary search to locate reader Collection::iterator reader = std::upper_bound(starts.begin(), starts.begin() + numSubReaders, n); return (int32_t)(std::distance(starts.begin(), reader) - 1); } - + bool DirectoryReader::hasNorms(const String& field) { ensureOpen(); @@ -602,7 +602,7 @@ namespace Lucene } return false; } - + ByteArray DirectoryReader::norms(const String& field) { SyncLock syncLock(this); @@ -612,14 +612,14 @@ namespace Lucene return bytes; // cache hit if (!hasNorms(field)) return ByteArray(); - + bytes = ByteArray::newInstance(maxDoc()); for (int32_t i = 0; i < subReaders.size(); ++i) subReaders[i]->norms(field, bytes, starts[i]); normsCache.put(field, bytes); // update cache return bytes; } - + void DirectoryReader::norms(const String& field, ByteArray norms, int32_t offset) { SyncLock syncLock(this); @@ -635,7 +635,7 @@ namespace Lucene subReaders[i]->norms(field, norms, offset + starts[i]); } } - + void DirectoryReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { { @@ -645,19 +645,19 @@ namespace Lucene int32_t i = readerIndex(doc); // find segment num subReaders[i]->setNorm(doc - starts[i], field, value); // dispatch } - + TermEnumPtr DirectoryReader::terms() { ensureOpen(); return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, TermPtr()); } - + TermEnumPtr DirectoryReader::terms(TermPtr t) { ensureOpen(); return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, t); } - + int32_t DirectoryReader::docFreq(TermPtr t) { ensureOpen(); @@ -666,42 +666,42 @@ namespace Lucene total += (*reader)->docFreq(t); return total; } - + TermDocsPtr DirectoryReader::termDocs() { ensureOpen(); return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts); } - + TermPositionsPtr DirectoryReader::termPositions() { ensureOpen(); return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts); } - + void DirectoryReader::acquireWriteLock() { if (readOnly) { - // NOTE: we should not reach this code with the core IndexReader classes; + // NOTE: we should not reach this code with the core IndexReader classes; // however, an external subclass of IndexReader could reach this. ReadOnlySegmentReader::noWrite(); } - + if (segmentInfos) { ensureOpen(); if (stale) boost::throw_exception(StaleReaderException(L"IndexReader out of date and no longer valid for delete, undelete, or setNorm operations")); - + if (!writeLock) { LockPtr writeLock(_directory->makeLock(IndexWriter::WRITE_LOCK_NAME)); if (!writeLock->obtain((int32_t)IndexWriter::WRITE_LOCK_TIMEOUT)) // obtain write lock boost::throw_exception(LockObtainFailedException(L"Index locked for write: " + writeLock->toString())); this->writeLock = writeLock; - - // we have to check whether index has changed since this reader was opened. + + // we have to check whether index has changed since this reader was opened. // if so, this reader is no longer valid for deletion if (SegmentInfos::readCurrentVersion(_directory) > maxIndexVersion) { @@ -713,27 +713,27 @@ namespace Lucene } } } - + void DirectoryReader::doCommit(MapStringString commitUserData) { if (_hasChanges) { segmentInfos->setUserData(commitUserData); - + // Default deleter (for backwards compatibility) is KeepOnlyLastCommitDeleter IndexFileDeleterPtr deleter(newLucene(_directory, deletionPolicy ? deletionPolicy : newLucene(), segmentInfos, InfoStreamPtr(), DocumentsWriterPtr(), synced)); segmentInfos->updateGeneration(deleter->getLastSegmentInfos()); - + // Checkpoint the state we are about to change, in case we have to roll back startCommit(); - + bool success = false; LuceneException finally; try { for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) (*reader)->commit(); - + // Sync all files we just wrote HashSet files(segmentInfos->files(_directory, false)); for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) @@ -745,7 +745,7 @@ namespace Lucene synced.add(*fileName); } } - + segmentInfos->commit(_directory); success = true; } @@ -753,7 +753,7 @@ namespace Lucene { finally = e; } - + if (!success) { // Rollback changes that were made to SegmentInfos but failed to get [fully] @@ -761,18 +761,18 @@ namespace Lucene // actually in the index) rollbackCommit(); - // Recompute deletable files & remove them (so partially written .del files, etc, + // Recompute deletable files & remove them (so partially written .del files, etc, // are removed) deleter->refresh(); } finally.throwException(); - + // Have the deleter remove any now unreferenced files due to this commit deleter->checkpoint(segmentInfos, true); deleter->close(); - + maxIndexVersion = segmentInfos->getVersion(); - + if (writeLock) { writeLock->release(); // release write lock @@ -781,27 +781,27 @@ namespace Lucene } _hasChanges = false; } - + void DirectoryReader::startCommit() { rollbackHasChanges = _hasChanges; for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) (*reader)->startCommit(); } - + void DirectoryReader::rollbackCommit() { _hasChanges = rollbackHasChanges; for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) (*reader)->rollbackCommit(); } - + MapStringString DirectoryReader::getCommitUserData() { ensureOpen(); return segmentInfos->getUserData(); } - + bool DirectoryReader::isCurrent() { ensureOpen(); @@ -814,7 +814,7 @@ namespace Lucene else return writer->nrtIsCurrent(segmentInfosStart); } - + void DirectoryReader::doClose() { SyncLock syncLock(this); @@ -833,26 +833,26 @@ namespace Lucene ioe = e; } } - - // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is + + // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is // generally not a good idea): FieldCache::DEFAULT()->purge(shared_from_this()); - + // throw the first exception ioe.throwException(); } - + HashSet DirectoryReader::getFieldNames(FieldOption fieldOption) { ensureOpen(); return getFieldNames(fieldOption, Collection::newInstance(subReaders.begin(), subReaders.end())); } - + HashSet DirectoryReader::getFieldNames(FieldOption fieldOption, Collection subReaders) { // maintain a unique set of field names HashSet fieldSet(HashSet::newInstance()); - + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { HashSet names((*reader)->getFieldNames(fieldOption)); @@ -860,41 +860,41 @@ namespace Lucene } return fieldSet; } - + Collection DirectoryReader::getSequentialSubReaders() { return Collection::newInstance(subReaders.begin(), subReaders.end()); } - + DirectoryPtr DirectoryReader::directory() { // Don't ensureOpen here -- in certain cases, when a cloned/reopened reader needs to commit, it may call // this method on the closed original reader return _directory; } - + int32_t DirectoryReader::getTermInfosIndexDivisor() { return termInfosIndexDivisor; } - + IndexCommitPtr DirectoryReader::getIndexCommit() { return newLucene(segmentInfos, _directory); } - + Collection DirectoryReader::listCommits(DirectoryPtr dir) { HashSet files(dir->listAll()); - + Collection commits(Collection::newInstance()); - + SegmentInfosPtr latest(newLucene()); latest->read(dir); int64_t currentGen = latest->getGeneration(); - + commits.add(newLucene(latest, dir)); - + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { if (boost::starts_with(*fileName, IndexFileNames::SEGMENTS()) && @@ -911,26 +911,26 @@ namespace Lucene { sis.reset(); } - + if (sis) commits.add(newLucene(sis, dir)); } } - + return commits; } - + FindSegmentsOpen::FindSegmentsOpen(bool readOnly, IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor, SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) { this->readOnly = readOnly; this->deletionPolicy = deletionPolicy; this->termInfosIndexDivisor = termInfosIndexDivisor; } - + FindSegmentsOpen::~FindSegmentsOpen() { } - + IndexReaderPtr FindSegmentsOpen::doBody(const String& segmentFileName) { SegmentInfosPtr segmentInfos(_segmentInfos); @@ -940,24 +940,24 @@ namespace Lucene else return newLucene(directory, segmentInfos, deletionPolicy, false, termInfosIndexDivisor); } - + FindSegmentsReopen::FindSegmentsReopen(DirectoryReaderPtr reader, bool openReadOnly, SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) { this->_reader = reader; this->openReadOnly = openReadOnly; } - + FindSegmentsReopen::~FindSegmentsReopen() { } - + DirectoryReaderPtr FindSegmentsReopen::doBody(const String& segmentFileName) { SegmentInfosPtr segmentInfos(_segmentInfos); segmentInfos->read(directory, segmentFileName); return DirectoryReaderPtr(_reader)->doReopen(segmentInfos, false, openReadOnly); } - + MultiTermEnum::MultiTermEnum(IndexReaderPtr topReader, Collection readers, Collection starts, TermPtr t) { _docFreq = 0; @@ -968,12 +968,12 @@ namespace Lucene { IndexReaderPtr reader(readers[i]); TermEnumPtr termEnum; - + if (t) termEnum = reader->terms(t); else termEnum = reader->terms(); - + SegmentMergeInfoPtr smi(newLucene(starts[i], termEnum, reader)); smi->ord = i; if (t.get() != NULL ? termEnum->term().get() != NULL : smi->next()) @@ -981,15 +981,15 @@ namespace Lucene else smi->close(); } - + if (t && !queue->empty()) next(); } - + MultiTermEnum::~MultiTermEnum() { } - + bool MultiTermEnum::next() { for (Collection::iterator smi = matchingSegments.begin(); smi != matchingSegments.end(); ++smi) @@ -1001,21 +1001,21 @@ namespace Lucene else (*smi)->close(); // done with segment } - + int32_t numMatchingSegments = 0; matchingSegments[0].reset(); - + SegmentMergeInfoPtr top(queue->top()); - + if (!top) { _term.reset(); return false; } - + _term = top->term; _docFreq = 0; - + while (top && _term->compareTo(top->term) == 0) { matchingSegments[numMatchingSegments++] = top; @@ -1023,26 +1023,26 @@ namespace Lucene _docFreq += top->termEnum->docFreq(); // increment freq top = queue->top(); } - + matchingSegments[numMatchingSegments].reset(); return true; } - + TermPtr MultiTermEnum::term() { return _term; } - + int32_t MultiTermEnum::docFreq() { return _docFreq; } - + void MultiTermEnum::close() { queue->close(); } - + MultiTermDocs::MultiTermDocs(IndexReaderPtr topReader, Collection r, Collection s) { this->_topReader = topReader; @@ -1052,21 +1052,21 @@ namespace Lucene pointer = 0; readerTermDocs = Collection::newInstance(r.size()); } - + MultiTermDocs::~MultiTermDocs() { } - + int32_t MultiTermDocs::doc() { return base + current->doc(); } - + int32_t MultiTermDocs::freq() { return current->freq(); } - + void MultiTermDocs::seek(TermPtr term) { this->term = term; @@ -1077,7 +1077,7 @@ namespace Lucene this->smi.reset(); this->matchingSegmentPos = 0; } - + void MultiTermDocs::seek(TermEnumPtr termEnum) { seek(termEnum->term()); @@ -1089,7 +1089,7 @@ namespace Lucene tenum.reset(); } } - + bool MultiTermDocs::next() { while (true) @@ -1115,7 +1115,7 @@ namespace Lucene return false; } } - + int32_t MultiTermDocs::read(Collection docs, Collection freqs) { while (true) @@ -1151,7 +1151,7 @@ namespace Lucene } } } - + bool MultiTermDocs::skipTo(int32_t target) { while (true) @@ -1177,7 +1177,7 @@ namespace Lucene return false; } } - + TermDocsPtr MultiTermDocs::termDocs(int32_t i) { TermDocsPtr result(readerTermDocs[i]); @@ -1196,12 +1196,12 @@ namespace Lucene result->seek(term); return result; } - + TermDocsPtr MultiTermDocs::termDocs(IndexReaderPtr reader) { return term ? reader->termDocs() : reader->termDocs(TermPtr()); } - + void MultiTermDocs::close() { for (Collection::iterator termDoc = readerTermDocs.begin(); termDoc != readerTermDocs.end(); ++termDoc) @@ -1210,40 +1210,40 @@ namespace Lucene (*termDoc)->close(); } } - + MultiTermPositions::MultiTermPositions(IndexReaderPtr topReader, Collection r, Collection s) : MultiTermDocs(topReader, r, s) { } - + MultiTermPositions::~MultiTermPositions() { } - + TermDocsPtr MultiTermPositions::termDocs(IndexReaderPtr reader) { return reader->termPositions(); } - + int32_t MultiTermPositions::nextPosition() { return boost::static_pointer_cast(current)->nextPosition(); } - + int32_t MultiTermPositions::getPayloadLength() { return boost::static_pointer_cast(current)->getPayloadLength(); } - + ByteArray MultiTermPositions::getPayload(ByteArray data, int32_t offset) { return boost::static_pointer_cast(current)->getPayload(data, offset); } - + bool MultiTermPositions::isPayloadAvailable() { return boost::static_pointer_cast(current)->isPayloadAvailable(); } - + ReaderCommit::ReaderCommit(SegmentInfosPtr infos, DirectoryPtr dir) { segmentsFileName = infos->getCurrentSegmentFileName(); @@ -1255,56 +1255,56 @@ namespace Lucene generation = infos->getGeneration(); _isOptimized = infos->size() == 1 && !infos->info(0)->hasDeletions(); } - + ReaderCommit::~ReaderCommit() { } - + String ReaderCommit::toString() { return L"DirectoryReader::ReaderCommit(" + segmentsFileName + L")"; } - + bool ReaderCommit::isOptimized() { return _isOptimized; } - + String ReaderCommit::getSegmentsFileName() { return segmentsFileName; } - + HashSet ReaderCommit::getFileNames() { return files; } - + DirectoryPtr ReaderCommit::getDirectory() { return dir; } - + int64_t ReaderCommit::getVersion() { return version; } - + int64_t ReaderCommit::getGeneration() { return generation; } - + bool ReaderCommit::isDeleted() { return false; } - + MapStringString ReaderCommit::getUserData() { return userData; } - + void ReaderCommit::deleteCommit() { boost::throw_exception(UnsupportedOperationException(L"This IndexCommit does not support deletions.")); diff --git a/src/core/index/DocConsumer.cpp b/src/core/index/DocConsumer.cpp index 568fe334..c90a8670 100644 --- a/src/core/index/DocConsumer.cpp +++ b/src/core/index/DocConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/DocConsumerPerThread.cpp b/src/core/index/DocConsumerPerThread.cpp index e13c6709..07dec8ec 100644 --- a/src/core/index/DocConsumerPerThread.cpp +++ b/src/core/index/DocConsumerPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/DocFieldConsumer.cpp b/src/core/index/DocFieldConsumer.cpp index 7203eef2..dcb59af8 100644 --- a/src/core/index/DocFieldConsumer.cpp +++ b/src/core/index/DocFieldConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene DocFieldConsumer::~DocFieldConsumer() { } - + void DocFieldConsumer::setFieldInfos(FieldInfosPtr fieldInfos) { this->fieldInfos = fieldInfos; diff --git a/src/core/index/DocFieldConsumerPerField.cpp b/src/core/index/DocFieldConsumerPerField.cpp index 7a771fa3..f93a1a74 100644 --- a/src/core/index/DocFieldConsumerPerField.cpp +++ b/src/core/index/DocFieldConsumerPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/DocFieldConsumerPerThread.cpp b/src/core/index/DocFieldConsumerPerThread.cpp index b0818e9b..2495f8e2 100644 --- a/src/core/index/DocFieldConsumerPerThread.cpp +++ b/src/core/index/DocFieldConsumerPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/DocFieldConsumers.cpp b/src/core/index/DocFieldConsumers.cpp index c8a39525..f0ffa7e5 100644 --- a/src/core/index/DocFieldConsumers.cpp +++ b/src/core/index/DocFieldConsumers.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,38 +17,38 @@ namespace Lucene freeCount = 0; allocCount = 0; docFreeList = Collection::newInstance(1); - + this->one = one; this->two = two; } - + DocFieldConsumers::~DocFieldConsumers() { } - + void DocFieldConsumers::setFieldInfos(FieldInfosPtr fieldInfos) { DocFieldConsumer::setFieldInfos(fieldInfos); one->setFieldInfos(fieldInfos); two->setFieldInfos(fieldInfos); } - + void DocFieldConsumers::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state) { MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField oneThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField twoThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); - + for (MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { Collection oneFields(Collection::newInstance()); Collection twoFields(Collection::newInstance()); - + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) { oneFields.add(boost::static_pointer_cast(*perField)->one); twoFields.add(boost::static_pointer_cast(*perField)->two); } - + oneThreadsAndFields.put(boost::static_pointer_cast(entry->first)->one, oneFields); twoThreadsAndFields.put(boost::static_pointer_cast(entry->first)->two, oneFields); } @@ -56,7 +56,7 @@ namespace Lucene one->flush(oneThreadsAndFields, state); two->flush(twoThreadsAndFields, state); } - + void DocFieldConsumers::closeDocStore(SegmentWriteStatePtr state) { LuceneException finally; @@ -78,17 +78,17 @@ namespace Lucene } finally.throwException(); } - + bool DocFieldConsumers::freeRAM() { return (one->freeRAM() || two->freeRAM()); } - + DocFieldConsumerPerThreadPtr DocFieldConsumers::addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread) { return newLucene(docFieldProcessorPerThread, shared_from_this(), one->addThread(docFieldProcessorPerThread), two->addThread(docFieldProcessorPerThread)); } - + DocFieldConsumersPerDocPtr DocFieldConsumers::getPerDoc() { SyncLock syncLock(this); @@ -97,7 +97,7 @@ namespace Lucene ++allocCount; if (allocCount > docFreeList.size()) { - // Grow our free list up front to make sure we have enough space to recycle all outstanding + // Grow our free list up front to make sure we have enough space to recycle all outstanding // PerDoc instances BOOST_ASSERT(allocCount == 1 + docFreeList.size()); docFreeList.resize(MiscUtils::getNextSize(allocCount)); @@ -107,28 +107,28 @@ namespace Lucene else return docFreeList[--freeCount]; } - + void DocFieldConsumers::freePerDoc(DocFieldConsumersPerDocPtr perDoc) { SyncLock syncLock(this); BOOST_ASSERT(freeCount < docFreeList.size()); docFreeList[freeCount++] = perDoc; } - + DocFieldConsumersPerDoc::DocFieldConsumersPerDoc(DocFieldConsumersPtr fieldConsumers) { this->_fieldConsumers = fieldConsumers; } - + DocFieldConsumersPerDoc::~DocFieldConsumersPerDoc() { } - + int64_t DocFieldConsumersPerDoc::sizeInBytes() { return one->sizeInBytes() + two->sizeInBytes(); } - + void DocFieldConsumersPerDoc::finish() { LuceneException finally; @@ -151,7 +151,7 @@ namespace Lucene DocFieldConsumersPtr(_fieldConsumers)->freePerDoc(shared_from_this()); finally.throwException(); } - + void DocFieldConsumersPerDoc::abort() { LuceneException finally; diff --git a/src/core/index/DocFieldConsumersPerField.cpp b/src/core/index/DocFieldConsumersPerField.cpp index eebc532b..04b57fda 100644 --- a/src/core/index/DocFieldConsumersPerField.cpp +++ b/src/core/index/DocFieldConsumersPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,17 +15,17 @@ namespace Lucene this->one = one; this->two = two; } - + DocFieldConsumersPerField::~DocFieldConsumersPerField() { } - + void DocFieldConsumersPerField::processFields(Collection fields, int32_t count) { one->processFields(fields, count); two->processFields(fields, count); } - + void DocFieldConsumersPerField::abort() { LuceneException finally; diff --git a/src/core/index/DocFieldConsumersPerThread.cpp b/src/core/index/DocFieldConsumersPerThread.cpp index 408342ef..7504ef00 100644 --- a/src/core/index/DocFieldConsumersPerThread.cpp +++ b/src/core/index/DocFieldConsumersPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,8 +12,8 @@ namespace Lucene { - DocFieldConsumersPerThread::DocFieldConsumersPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, - DocFieldConsumersPtr parent, + DocFieldConsumersPerThread::DocFieldConsumersPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, + DocFieldConsumersPtr parent, DocFieldConsumerPerThreadPtr one, DocFieldConsumerPerThreadPtr two) { this->_parent = parent; @@ -21,17 +21,17 @@ namespace Lucene this->two = two; docState = docFieldProcessorPerThread->docState; } - + DocFieldConsumersPerThread::~DocFieldConsumersPerThread() { } - + void DocFieldConsumersPerThread::startDocument() { one->startDocument(); two->startDocument(); } - + void DocFieldConsumersPerThread::abort() { LuceneException finally; @@ -53,7 +53,7 @@ namespace Lucene } finally.throwException(); } - + DocWriterPtr DocFieldConsumersPerThread::finishDocument() { DocWriterPtr oneDoc(one->finishDocument()); @@ -73,7 +73,7 @@ namespace Lucene return both; } } - + DocFieldConsumerPerFieldPtr DocFieldConsumersPerThread::addField(FieldInfoPtr fi) { return newLucene(shared_from_this(), one->addField(fi), two->addField(fi)); diff --git a/src/core/index/DocFieldProcessor.cpp b/src/core/index/DocFieldProcessor.cpp index 73c6731d..9864f2ab 100644 --- a/src/core/index/DocFieldProcessor.cpp +++ b/src/core/index/DocFieldProcessor.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,22 +25,22 @@ namespace Lucene consumer->setFieldInfos(fieldInfos); fieldsWriter = newLucene(docWriter, fieldInfos); } - + DocFieldProcessor::~DocFieldProcessor() { } - + void DocFieldProcessor::closeDocStore(SegmentWriteStatePtr state) { consumer->closeDocStore(state); fieldsWriter->closeDocStore(state); } - + void DocFieldProcessor::flush(Collection threads, SegmentWriteStatePtr state) { TestScope testScope(L"DocFieldProcessor", L"flush"); MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField childThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); - + for (Collection::iterator thread = threads.begin(); thread != threads.end(); ++thread) { DocFieldProcessorPerThreadPtr perThread(boost::static_pointer_cast(*thread)); @@ -49,25 +49,25 @@ namespace Lucene } fieldsWriter->flush(state); consumer->flush(childThreadsAndFields, state); - + // Important to save after asking consumer to flush so consumer can alter the FieldInfo* if necessary. // eg FreqProxTermsWriter does this with FieldInfo.storePayload. String fileName(state->segmentFileName(IndexFileNames::FIELD_INFOS_EXTENSION())); fieldInfos->write(state->directory, fileName); state->flushedFiles.add(fileName); } - + void DocFieldProcessor::abort() { fieldsWriter->abort(); consumer->abort(); } - + bool DocFieldProcessor::freeRAM() { return consumer->freeRAM(); } - + DocConsumerPerThreadPtr DocFieldProcessor::addThread(DocumentsWriterThreadStatePtr perThread) { return newLucene(perThread, shared_from_this()); diff --git a/src/core/index/DocFieldProcessorPerField.cpp b/src/core/index/DocFieldProcessorPerField.cpp index 702f0ec5..67224d69 100644 --- a/src/core/index/DocFieldProcessorPerField.cpp +++ b/src/core/index/DocFieldProcessorPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,11 +20,11 @@ namespace Lucene this->consumer = perThread->consumer->addField(fieldInfo); this->fieldInfo = fieldInfo; } - + DocFieldProcessorPerField::~DocFieldProcessorPerField() { } - + void DocFieldProcessorPerField::abort() { consumer->abort(); diff --git a/src/core/index/DocFieldProcessorPerThread.cpp b/src/core/index/DocFieldProcessorPerThread.cpp index 745aa791..586bbd19 100644 --- a/src/core/index/DocFieldProcessorPerThread.cpp +++ b/src/core/index/DocFieldProcessorPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -35,27 +35,27 @@ namespace Lucene fieldGen = 0; fieldCount = 0; totalFieldCount = 0; - + this->docState = threadState->docState; this->_docFieldProcessor = docFieldProcessor; this->fieldInfos = docFieldProcessor->fieldInfos; - + docFreeList = Collection::newInstance(1); freeCount = 0; allocCount = 0; } - + DocFieldProcessorPerThread::~DocFieldProcessorPerThread() { } - + void DocFieldProcessorPerThread::initialize() { DocFieldProcessorPtr docFieldProcessor(_docFieldProcessor); consumer = docFieldProcessor->consumer->addThread(shared_from_this()); fieldsWriter = docFieldProcessor->fieldsWriter->addThread(docState); } - + void DocFieldProcessorPerThread::abort() { for (Collection::iterator field = fieldHash.begin(); field != fieldHash.end(); ++field) @@ -71,7 +71,7 @@ namespace Lucene fieldsWriter->abort(); consumer->abort(); } - + Collection DocFieldProcessorPerThread::fields() { Collection fields(Collection::newInstance()); @@ -87,30 +87,30 @@ namespace Lucene BOOST_ASSERT(fields.size() == totalFieldCount); return fields; } - + void DocFieldProcessorPerThread::trimFields(SegmentWriteStatePtr state) { for (Collection::iterator perField = fieldHash.begin(); perField != fieldHash.end(); ++perField) { DocFieldProcessorPerFieldPtr current(*perField); DocFieldProcessorPerFieldPtr lastPerField; - + while (current) { if (current->lastGen == -1) { // This field was not seen since the previous flush, so, free up its resources now - + // Unhash if (!lastPerField) *perField = current->next; else lastPerField->next = current->next; - + DocumentsWriterPtr docWriter(state->_docWriter); if (docWriter->infoStream) *(docWriter->infoStream) << L" purge field=" << current->fieldInfo->name << L"\n"; - + --totalFieldCount; } else @@ -119,19 +119,19 @@ namespace Lucene current->lastGen = -1; lastPerField = current; } - + current = current->next; } } } - + void DocFieldProcessorPerThread::rehash() { int32_t newHashSize = (fieldHash.size() * 2); BOOST_ASSERT(newHashSize > fieldHash.size()); - + Collection newHashArray(Collection::newInstance(newHashSize)); - + // Rehash int32_t newHashMask = newHashSize - 1; for (Collection::iterator fp0 = fieldHash.begin(); fp0 != fieldHash.end(); ++fp0) @@ -146,11 +146,11 @@ namespace Lucene current = nextFP0; } } - + fieldHash = newHashArray; hashMask = newHashMask; } - + struct lessFieldInfoName { inline bool operator()(const DocFieldProcessorPerFieldPtr& first, const DocFieldProcessorPerFieldPtr& second) const @@ -158,49 +158,49 @@ namespace Lucene return (first->fieldInfo->name < second->fieldInfo->name); } }; - + DocWriterPtr DocFieldProcessorPerThread::processDocument() { consumer->startDocument(); fieldsWriter->startDocument(); - + DocumentPtr doc(docState->doc); - + DocFieldProcessorPtr docFieldProcessor(_docFieldProcessor); DocumentsWriterPtr docWriter(docFieldProcessor->_docWriter); bool testPoint = IndexWriterPtr(docWriter->_writer)->testPoint(L"DocumentsWriter.ThreadState.init start"); BOOST_ASSERT(testPoint); - + fieldCount = 0; int32_t thisFieldGen = fieldGen++; - + Collection docFields(doc->getFields()); - + // Absorb any new fields first seen in this document. // Also absorb any changes to fields we had already seen before (eg suddenly turning on norms or // vectors, etc.) for (Collection::iterator field = docFields.begin(); field != docFields.end(); ++field) { String fieldName((*field)->name()); - + // Make sure we have a PerField allocated int32_t hashPos = StringUtils::hashCode(fieldName) & hashMask; - + DocFieldProcessorPerFieldPtr fp(fieldHash[hashPos]); while (fp && fp->fieldInfo->name != fieldName) fp = fp->next; - + if (!fp) { FieldInfoPtr fi(fieldInfos->add(fieldName, (*field)->isIndexed(), (*field)->isTermVectorStored(), (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions())); - + fp = newLucene(shared_from_this(), fi); fp->next = fieldHash[hashPos]; fieldHash[hashPos] = fp; ++totalFieldCount; - + if (totalFieldCount >= fieldHash.size() / 2) rehash(); } @@ -210,45 +210,45 @@ namespace Lucene (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions()); } - + if (thisFieldGen != fp->lastGen) { // First time we're seeing this field for this doc fp->fieldCount = 0; - + if (fieldCount == _fields.size()) _fields.resize(_fields.size() * 2); - + _fields[fieldCount++] = fp; fp->lastGen = thisFieldGen; } - + if (fp->fieldCount == fp->fields.size()) fp->fields.resize(fp->fields.size() * 2); - + fp->fields[fp->fieldCount++] = *field; if ((*field)->isStored()) fieldsWriter->addField(*field, fp->fieldInfo); } - + // If we are writing vectors then we must visit fields in sorted order so they are written in sorted order. std::sort(_fields.begin(), _fields.begin() + fieldCount, lessFieldInfoName()); - + for (int32_t i = 0; i < fieldCount; ++i) _fields[i]->consumer->processFields(_fields[i]->fields, _fields[i]->fieldCount); - + if (!docState->maxTermPrefix.empty() && docState->infoStream) { - *(docState->infoStream) << L"WARNING: document contains at least one immense term (longer than the max length " << + *(docState->infoStream) << L"WARNING: document contains at least one immense term (longer than the max length " << StringUtils::toString(DocumentsWriter::MAX_TERM_LENGTH) << L"), all of which were skipped. " << L"Please correct the analyzer to not produce such terms. The prefix of the first immense " << L"term is: '" << StringUtils::toString(docState->maxTermPrefix) << L"...'\n"; docState->maxTermPrefix.clear(); } - + DocWriterPtr one(fieldsWriter->finishDocument()); DocWriterPtr two(consumer->finishDocument()); - + if (!one) return two; else if (!two) @@ -264,7 +264,7 @@ namespace Lucene return both; } } - + DocFieldProcessorPerThreadPerDocPtr DocFieldProcessorPerThread::getPerDoc() { SyncLock syncLock(this); @@ -273,7 +273,7 @@ namespace Lucene ++allocCount; if (allocCount > docFreeList.size()) { - // Grow our free list up front to make sure we have enough space to recycle all + // Grow our free list up front to make sure we have enough space to recycle all // outstanding PerDoc instances BOOST_ASSERT(allocCount == docFreeList.size() + 1); docFreeList.resize(MiscUtils::getNextSize(allocCount)); @@ -283,28 +283,28 @@ namespace Lucene else return docFreeList[--freeCount]; } - + void DocFieldProcessorPerThread::freePerDoc(DocFieldProcessorPerThreadPerDocPtr perDoc) { SyncLock syncLock(this); BOOST_ASSERT(freeCount < docFreeList.size()); docFreeList[freeCount++] = perDoc; } - + DocFieldProcessorPerThreadPerDoc::DocFieldProcessorPerThreadPerDoc(DocFieldProcessorPerThreadPtr docProcessor) { this->_docProcessor = docProcessor; } - + DocFieldProcessorPerThreadPerDoc::~DocFieldProcessorPerThreadPerDoc() { } - + int64_t DocFieldProcessorPerThreadPerDoc::sizeInBytes() { return one->sizeInBytes() + two->sizeInBytes(); } - + void DocFieldProcessorPerThreadPerDoc::finish() { LuceneException finally; @@ -327,7 +327,7 @@ namespace Lucene DocFieldProcessorPerThreadPtr(_docProcessor)->freePerDoc(shared_from_this()); finally.throwException(); } - + void DocFieldProcessorPerThreadPerDoc::abort() { LuceneException finally; diff --git a/src/core/index/DocInverter.cpp b/src/core/index/DocInverter.cpp index ad54a084..f342e646 100644 --- a/src/core/index/DocInverter.cpp +++ b/src/core/index/DocInverter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,59 +22,59 @@ namespace Lucene this->consumer = consumer; this->endConsumer = endConsumer; } - + DocInverter::~DocInverter() { } - + void DocInverter::setFieldInfos(FieldInfosPtr fieldInfos) { DocFieldConsumer::setFieldInfos(fieldInfos); consumer->setFieldInfos(fieldInfos); endConsumer->setFieldInfos(fieldInfos); } - + void DocInverter::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state) { MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField childThreadsAndFields(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::newInstance()); MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField endChildThreadsAndFields(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField::newInstance()); - + for (MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { Collection childFields(Collection::newInstance()); Collection endChildFields(Collection::newInstance()); - + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) { childFields.add(boost::static_pointer_cast(*perField)->consumer); endChildFields.add(boost::static_pointer_cast(*perField)->endConsumer); } - + childThreadsAndFields.put(boost::static_pointer_cast(entry->first)->consumer, childFields); endChildThreadsAndFields.put(boost::static_pointer_cast(entry->first)->endConsumer, endChildFields); } - + consumer->flush(childThreadsAndFields, state); endConsumer->flush(endChildThreadsAndFields, state); } - + void DocInverter::closeDocStore(SegmentWriteStatePtr state) { consumer->closeDocStore(state); endConsumer->closeDocStore(state); } - + void DocInverter::abort() { consumer->abort(); endConsumer->abort(); } - + bool DocInverter::freeRAM() { return consumer->freeRAM(); } - + DocFieldConsumerPerThreadPtr DocInverter::addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread) { return newLucene(docFieldProcessorPerThread, shared_from_this()); diff --git a/src/core/index/DocInverterPerField.cpp b/src/core/index/DocInverterPerField.cpp index af983722..74ae904e 100644 --- a/src/core/index/DocInverterPerField.cpp +++ b/src/core/index/DocInverterPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -34,43 +34,43 @@ namespace Lucene docState = perThread->docState; fieldState = perThread->fieldState; } - + DocInverterPerField::~DocInverterPerField() { } - + void DocInverterPerField::initialize() { DocInverterPerThreadPtr perThread(_perThread); consumer = perThread->consumer->addField(shared_from_this(), fieldInfo); endConsumer = perThread->endConsumer->addField(shared_from_this(), fieldInfo); } - + void DocInverterPerField::abort() { consumer->abort(); endConsumer->abort(); } - + void DocInverterPerField::processFields(Collection fields, int32_t count) { fieldState->reset(docState->doc->getBoost()); - + int32_t maxFieldLength = docState->maxFieldLength; bool doInvert = consumer->start(fields, count); DocumentsWriterPtr docWriter(docState->_docWriter); DocInverterPerThreadPtr perThread(_perThread); - + for (int32_t i = 0; i < count; ++i) { FieldablePtr field = fields[i]; if (field->isIndexed() && doInvert) { bool anyToken; - + if (fieldState->length > 0) fieldState->position += docState->analyzer->getPositionIncrementGap(fieldInfo->name); - + if (!field->isTokenized()) { // un-tokenized field @@ -104,7 +104,7 @@ namespace Lucene // tokenized field TokenStreamPtr stream; TokenStreamPtr streamValue(field->tokenStreamValue()); - + if (streamValue) stream = streamValue; else @@ -112,7 +112,7 @@ namespace Lucene // the field does not have a TokenStream, so we have to obtain one from the analyzer ReaderPtr reader; // find or make Reader ReaderPtr readerValue(field->readerValue()); - + if (readerValue) reader = readerValue; else @@ -121,30 +121,30 @@ namespace Lucene perThread->stringReader->init(stringValue); reader = perThread->stringReader; } - + // Tokenize field and add to postingTable stream = docState->analyzer->reusableTokenStream(fieldInfo->name, reader); } - + // reset the TokenStream to the first token stream->reset(); - + int32_t startLength = fieldState->length; - + LuceneException finally; try { int32_t offsetEnd = fieldState->offset - 1; - + bool hasMoreTokens = stream->incrementToken(); - + fieldState->attributeSource = stream; - + OffsetAttributePtr offsetAttribute(fieldState->attributeSource->addAttribute()); PositionIncrementAttributePtr posIncrAttribute(fieldState->attributeSource->addAttribute()); - + consumer->start(field); - + while (true) { // If we hit an exception in stream.next below (which is fairly common, eg if analyzer @@ -152,20 +152,20 @@ namespace Lucene // will be marked as deleted, but still consume a docID if (!hasMoreTokens) break; - + int32_t posIncr = posIncrAttribute->getPositionIncrement(); fieldState->position += posIncr; if (fieldState->position > 0) --fieldState->position; - + if (posIncr == 0) ++fieldState->numOverlap; - + bool success = false; try { // If we hit an exception in here, we abort all buffered documents since the last - // flush, on the likelihood that the internal state of the consumer is now corrupt + // flush, on the likelihood that the internal state of the consumer is now corrupt // and should not be flushed to a new segment consumer->add(); success = true; @@ -185,13 +185,13 @@ namespace Lucene *docState->infoStream << L"maxFieldLength " << StringUtils::toString(maxFieldLength) << L" reached for field " << fieldInfo->name << L", ignoring following tokens\n"; break; } - + hasMoreTokens = stream->incrementToken(); } - + // trigger streams to perform end-of-stream operations stream->end(); - + fieldState->offset += offsetAttribute->endOffset(); anyToken = (fieldState->length > startLength); } @@ -202,16 +202,16 @@ namespace Lucene stream->close(); finally.throwException(); } - + if (anyToken) fieldState->offset += docState->analyzer->getOffsetGap(field); fieldState->boost *= field->getBoost(); } - + // don't hang onto the field fields[i].reset(); } - + consumer->finish(); endConsumer->finish(); } diff --git a/src/core/index/DocInverterPerThread.cpp b/src/core/index/DocInverterPerThread.cpp index 2c8dc6cb..6ef9dd76 100644 --- a/src/core/index/DocInverterPerThread.cpp +++ b/src/core/index/DocInverterPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -28,30 +28,30 @@ namespace Lucene this->_docInverter = docInverter; this->docState = docFieldProcessorPerThread->docState; } - + DocInverterPerThread::~DocInverterPerThread() { } - + void DocInverterPerThread::initialize() { DocInverterPtr docInverter(_docInverter); consumer = docInverter->consumer->addThread(shared_from_this()); endConsumer = docInverter->endConsumer->addThread(shared_from_this()); } - + void DocInverterPerThread::startDocument() { consumer->startDocument(); endConsumer->startDocument(); } - + DocWriterPtr DocInverterPerThread::finishDocument() { endConsumer->finishDocument(); return consumer->finishDocument(); } - + void DocInverterPerThread::abort() { LuceneException finally; @@ -73,22 +73,22 @@ namespace Lucene } finally.throwException(); } - + DocFieldConsumerPerFieldPtr DocInverterPerThread::addField(FieldInfoPtr fi) { return newLucene(shared_from_this(), fi); } - + SingleTokenAttributeSource::SingleTokenAttributeSource() { termAttribute = addAttribute(); offsetAttribute = addAttribute(); } - + SingleTokenAttributeSource::~SingleTokenAttributeSource() { } - + void SingleTokenAttributeSource::reinit(const String& stringValue, int32_t startOffset, int32_t endOffset) { termAttribute->setTermBuffer(stringValue); diff --git a/src/core/index/DocumentsWriter.cpp b/src/core/index/DocumentsWriter.cpp index 6d94c951..fdbcfbfa 100644 --- a/src/core/index/DocumentsWriter.cpp +++ b/src/core/index/DocumentsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -44,7 +44,7 @@ namespace Lucene { /// Max # ThreadState instances; if there are more threads than this they share ThreadStates const int32_t DocumentsWriter::MAX_THREAD_STATE = 5; - + /// Coarse estimates used to measure RAM usage of buffered deletes const int32_t DocumentsWriter::OBJECT_HEADER_BYTES = 8; #ifdef LPP_BUILD_64 @@ -59,26 +59,26 @@ namespace Lucene const int32_t DocumentsWriter::CHAR_NUM_BYTE = 2; #endif - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is - /// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since - /// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). + /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object + /// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is + /// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since + /// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). /// BufferedDeletes.num is OBJ_HEADER + INT. - const int32_t DocumentsWriter::BYTES_PER_DEL_TERM = 8 * DocumentsWriter::POINTER_NUM_BYTE + 5 * - DocumentsWriter::OBJECT_HEADER_BYTES + 6 * + const int32_t DocumentsWriter::BYTES_PER_DEL_TERM = 8 * DocumentsWriter::POINTER_NUM_BYTE + 5 * + DocumentsWriter::OBJECT_HEADER_BYTES + 6 * DocumentsWriter::INT_NUM_BYTE; - /// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is + /// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is /// OBJ_HEADER + int - const int32_t DocumentsWriter::BYTES_PER_DEL_DOCID = 2 * DocumentsWriter::POINTER_NUM_BYTE + - DocumentsWriter::OBJECT_HEADER_BYTES + + const int32_t DocumentsWriter::BYTES_PER_DEL_DOCID = 2 * DocumentsWriter::POINTER_NUM_BYTE + + DocumentsWriter::OBJECT_HEADER_BYTES + DocumentsWriter::INT_NUM_BYTE; - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount + /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object + /// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount /// (say 24 bytes). Integer is OBJ_HEADER + INT. - const int32_t DocumentsWriter::BYTES_PER_DEL_QUERY = 5 * DocumentsWriter::POINTER_NUM_BYTE + 2 * - DocumentsWriter::OBJECT_HEADER_BYTES + 2 * + const int32_t DocumentsWriter::BYTES_PER_DEL_QUERY = 5 * DocumentsWriter::POINTER_NUM_BYTE + 2 * + DocumentsWriter::OBJECT_HEADER_BYTES + 2 * DocumentsWriter::INT_NUM_BYTE + 24; /// Initial chunks size of the shared byte[] blocks used to store postings data @@ -100,7 +100,7 @@ namespace Lucene const int32_t DocumentsWriter::INT_BLOCK_MASK = DocumentsWriter::INT_BLOCK_SIZE - 1; const int32_t DocumentsWriter::PER_DOC_BLOCK_SIZE = 1024; - + DocumentsWriter::DocumentsWriter(DirectoryPtr directory, IndexWriterPtr writer, IndexingChainPtr indexingChain) { this->threadStates = Collection::newInstance(); @@ -109,16 +109,16 @@ namespace Lucene this->_closedFiles = HashSet::newInstance(); this->freeIntBlocks = Collection::newInstance(); this->freeCharBlocks = Collection::newInstance(); - + this->directory = directory; this->_writer = writer; this->indexingChain = indexingChain; } - + DocumentsWriter::~DocumentsWriter() { } - + void DocumentsWriter::initialize() { docStoreOffset = 0; @@ -147,20 +147,20 @@ namespace Lucene numBytesUsed = 0; byteBlockAllocator = newLucene(shared_from_this(), BYTE_BLOCK_SIZE); perDocAllocator = newLucene(shared_from_this(), PER_DOC_BLOCK_SIZE); - + IndexWriterPtr writer(_writer); this->similarity = writer->getSimilarity(); flushedDocCount = writer->maxDoc(); - + consumer = indexingChain->getChain(shared_from_this()); docFieldProcessor = boost::dynamic_pointer_cast(consumer); } - + PerDocBufferPtr DocumentsWriter::newPerDocBuffer() { return newLucene(shared_from_this()); } - + IndexingChainPtr DocumentsWriter::getDefaultIndexingChain() { static DefaultIndexingChainPtr defaultIndexingChain; @@ -171,30 +171,30 @@ namespace Lucene } return defaultIndexingChain; } - + void DocumentsWriter::updateFlushedDocCount(int32_t n) { SyncLock syncLock(this); flushedDocCount += n; } - + int32_t DocumentsWriter::getFlushedDocCount() { SyncLock syncLock(this); return flushedDocCount; } - + void DocumentsWriter::setFlushedDocCount(int32_t n) { SyncLock syncLock(this); flushedDocCount = n; } - + bool DocumentsWriter::hasProx() { return docFieldProcessor ? docFieldProcessor->fieldInfos->hasProx() : true; } - + void DocumentsWriter::setInfoStream(InfoStreamPtr infoStream) { SyncLock syncLock(this); @@ -202,7 +202,7 @@ namespace Lucene for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) (*threadState)->docState->infoStream = infoStream; } - + void DocumentsWriter::setMaxFieldLength(int32_t maxFieldLength) { SyncLock syncLock(this); @@ -210,7 +210,7 @@ namespace Lucene for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) (*threadState)->docState->maxFieldLength = maxFieldLength; } - + void DocumentsWriter::setSimilarity(SimilarityPtr similarity) { SyncLock syncLock(this); @@ -218,7 +218,7 @@ namespace Lucene for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) (*threadState)->docState->similarity = similarity; } - + void DocumentsWriter::setRAMBufferSizeMB(double mb) { SyncLock syncLock(this); @@ -237,7 +237,7 @@ namespace Lucene freeLevel = (int64_t)(0.95 * (double)ramBufferSize); } } - + double DocumentsWriter::getRAMBufferSizeMB() { SyncLock syncLock(this); @@ -246,50 +246,50 @@ namespace Lucene else return (double)ramBufferSize / 1024.0 / 1024.0; } - + void DocumentsWriter::setMaxBufferedDocs(int32_t count) { maxBufferedDocs = count; } - + int32_t DocumentsWriter::getMaxBufferedDocs() { return maxBufferedDocs; } - + String DocumentsWriter::getSegment() { return segment; } - + int32_t DocumentsWriter::getNumDocsInRAM() { return numDocsInRAM; } - + String DocumentsWriter::getDocStoreSegment() { SyncLock syncLock(this); return docStoreSegment; } - + int32_t DocumentsWriter::getDocStoreOffset() { return docStoreOffset; } - + String DocumentsWriter::closeDocStore() { TestScope testScope(L"DocumentsWriter", L"closeDocStore"); SyncLock syncLock(this); BOOST_ASSERT(allThreadsIdle()); - + if (infoStream) { - message(L"closeDocStore: " + StringUtils::toString(_openFiles.size()) + L" files to flush to segment " + + message(L"closeDocStore: " + StringUtils::toString(_openFiles.size()) + L" files to flush to segment " + docStoreSegment + L" numDocs=" + StringUtils::toString(numDocsInStore)); } - + bool success = false; LuceneException finally; String s; @@ -297,10 +297,10 @@ namespace Lucene { initFlushState(true); _closedFiles.clear(); - + consumer->closeDocStore(flushState); BOOST_ASSERT(_openFiles.empty()); - + s = docStoreSegment; docStoreSegment.clear(); docStoreOffset = 0; @@ -316,37 +316,37 @@ namespace Lucene finally.throwException(); return s; } - + HashSet DocumentsWriter::abortedFiles() { return _abortedFiles; } - + void DocumentsWriter::message(const String& message) { if (infoStream) *infoStream << L"DW " << message << L"\n"; } - + HashSet DocumentsWriter::openFiles() { SyncLock syncLock(this); return HashSet::newInstance(_openFiles.begin(), _openFiles.end()); } - + HashSet DocumentsWriter::closedFiles() { SyncLock syncLock(this); return HashSet::newInstance(_closedFiles.begin(), _closedFiles.end()); } - + void DocumentsWriter::addOpenFile(const String& name) { SyncLock syncLock(this); BOOST_ASSERT(!_openFiles.contains(name)); _openFiles.add(name); } - + void DocumentsWriter::removeOpenFile(const String& name) { SyncLock syncLock(this); @@ -354,13 +354,13 @@ namespace Lucene _openFiles.remove(name); _closedFiles.add(name); } - + void DocumentsWriter::setAborting() { SyncLock syncLock(this); aborting = true; } - + void DocumentsWriter::abort() { TestScope testScope(L"DocumentsWriter", L"abort"); @@ -370,19 +370,19 @@ namespace Lucene { if (infoStream) message(L"docWriter: now abort"); - + // Forcefully remove waiting ThreadStates from line waitQueue->abort(); - + // Wait for all other threads to finish with DocumentsWriter pauseAllThreads(); - + try { BOOST_ASSERT(waitQueue->numWaiting == 0); - + waitQueue->waitingBytes = 0; - + try { _abortedFiles = openFiles(); @@ -391,11 +391,11 @@ namespace Lucene { _abortedFiles.reset(); } - + deletesInRAM->clear(); deletesFlushed->clear(); _openFiles.clear(); - + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { try @@ -406,7 +406,7 @@ namespace Lucene { } } - + try { consumer->abort(); @@ -414,11 +414,11 @@ namespace Lucene catch (...) { } - + docStoreSegment.clear(); numDocsInStore = 0; docStoreOffset = 0; - + // Reset all postings data doAfterFlush(); } @@ -439,7 +439,7 @@ namespace Lucene message(L"docWriter: done abort"); finally.throwException(); } - + void DocumentsWriter::doAfterFlush() { // All ThreadStates should be idle when we are called @@ -455,7 +455,7 @@ namespace Lucene (*threadState)->doAfterFlush(); numBytesUsed = 0; } - + bool DocumentsWriter::pauseAllThreads() { SyncLock syncLock(this); @@ -464,7 +464,7 @@ namespace Lucene wait(1000); return aborting; } - + void DocumentsWriter::resumeAllThreads() { SyncLock syncLock(this); @@ -473,7 +473,7 @@ namespace Lucene if (pauseThreads == 0) notifyAll(); } - + bool DocumentsWriter::allThreadsIdle() { SyncLock syncLock(this); @@ -484,38 +484,38 @@ namespace Lucene } return true; } - + bool DocumentsWriter::anyChanges() { SyncLock syncLock(this); return (numDocsInRAM != 0 || deletesInRAM->numTerms != 0 || !deletesInRAM->docIDs.empty() || !deletesInRAM->queries.empty()); } - + void DocumentsWriter::initFlushState(bool onlyDocStore) { SyncLock syncLock(this); initSegmentName(onlyDocStore); flushState = newLucene(shared_from_this(), directory, segment, docStoreSegment, numDocsInRAM, numDocsInStore, IndexWriterPtr(_writer)->getTermIndexInterval()); } - + int32_t DocumentsWriter::flush(bool _closeDocStore) { SyncLock syncLock(this); BOOST_ASSERT(allThreadsIdle()); - + BOOST_ASSERT(numDocsInRAM > 0); - + BOOST_ASSERT(nextDocID == numDocsInRAM); BOOST_ASSERT(waitQueue->numWaiting == 0); BOOST_ASSERT(waitQueue->waitingBytes == 0); - + initFlushState(false); - + docStoreOffset = numDocsInStore; - + if (infoStream) message(L"flush postings as segment " + flushState->segmentName + L" numDocs=" + StringUtils::toString(numDocsInRAM)); - + bool success = false; LuceneException finally; @@ -525,33 +525,33 @@ namespace Lucene { BOOST_ASSERT(!flushState->docStoreSegmentName.empty()); BOOST_ASSERT(flushState->docStoreSegmentName == flushState->segmentName); - + closeDocStore(); flushState->numDocsInStore = 0; } - + Collection threads(Collection::newInstance()); for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) threads.add((*threadState)->consumer); consumer->flush(threads, flushState); - + if (infoStream) { SegmentInfoPtr si(newLucene(flushState->segmentName, flushState->numDocs, directory)); int64_t newSegmentSize = si->sizeInBytes(); if (infoStream) { - message(L" oldRAMSize=" + StringUtils::toString(numBytesUsed) + L" newFlushedSize=" + - StringUtils::toString(newSegmentSize) + L" docs/MB=" + + message(L" oldRAMSize=" + StringUtils::toString(numBytesUsed) + L" newFlushedSize=" + + StringUtils::toString(newSegmentSize) + L" docs/MB=" + StringUtils::toString((double)numDocsInRAM / ((double)newSegmentSize / 1024.0 / 1024.0)) + L" new/old=" + StringUtils::toString(100.0 * (double)newSegmentSize / (double)numBytesUsed) + L"%"); } } - + flushedDocCount += flushState->numDocs; - + doAfterFlush(); - + success = true; } catch (LuceneException& e) @@ -561,27 +561,27 @@ namespace Lucene if (!success) abort(); finally.throwException(); - + BOOST_ASSERT(waitQueue->waitingBytes == 0); - + return flushState->numDocs; } - + HashSet DocumentsWriter::getFlushedFiles() { return flushState->flushedFiles; } - + void DocumentsWriter::createCompoundFile(const String& segment) { CompoundFileWriterPtr cfsWriter(newLucene(directory, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION())); for (HashSet::iterator flushedFile = flushState->flushedFiles.begin(); flushedFile != flushState->flushedFiles.end(); ++flushedFile) cfsWriter->addFile(*flushedFile); - + // Perform the merge cfsWriter->close(); } - + bool DocumentsWriter::setFlushPending() { SyncLock syncLock(this); @@ -593,26 +593,26 @@ namespace Lucene return true; } } - + void DocumentsWriter::clearFlushPending() { SyncLock syncLock(this); flushPending = false; } - + void DocumentsWriter::pushDeletes() { SyncLock syncLock(this); deletesFlushed->update(deletesInRAM); } - + void DocumentsWriter::close() { SyncLock syncLock(this); closed = true; notifyAll(); } - + void DocumentsWriter::initSegmentName(bool onlyDocStore) { SyncLock syncLock(this); @@ -627,7 +627,7 @@ namespace Lucene BOOST_ASSERT(numDocsInStore == 0); } } - + DocumentsWriterThreadStatePtr DocumentsWriter::getThreadState(DocumentPtr doc, TermPtr delTerm) { SyncLock syncLock(this); @@ -656,43 +656,43 @@ namespace Lucene } threadBindings.put(LuceneThread::currentId(), state); } - + // Next, wait until my thread state is idle (in case it's shared with other threads) and for threads to // not be paused nor a flush pending waitReady(state); - + // Allocate segment name if this is the first doc since last flush initSegmentName(false); - + state->isIdle = false; - + bool success = false; LuceneException finally; try { state->docState->docID = nextDocID; - + BOOST_ASSERT(IndexWriterPtr(_writer)->testPoint(L"DocumentsWriter.ThreadState.init start")); - + if (delTerm) { addDeleteTerm(delTerm, state->docState->docID); state->doFlushAfter = timeToFlushDeletes(); } - + BOOST_ASSERT(IndexWriterPtr(_writer)->testPoint(L"DocumentsWriter.ThreadState.init after delTerm")); - + ++nextDocID; ++numDocsInRAM; - - // We must at this point commit to flushing to ensure we always get N docs when we flush by doc + + // We must at this point commit to flushing to ensure we always get N docs when we flush by doc // count, even if > 1 thread is adding documents if (!flushPending && maxBufferedDocs != IndexWriter::DISABLE_AUTO_FLUSH && numDocsInRAM >= maxBufferedDocs) { flushPending = true; state->doFlushAfter = true; } - + success = true; } catch (LuceneException& e) @@ -711,29 +711,29 @@ namespace Lucene } } finally.throwException(); - + return state; } - + bool DocumentsWriter::addDocument(DocumentPtr doc, AnalyzerPtr analyzer) { return updateDocument(doc, analyzer, TermPtr()); } - + bool DocumentsWriter::updateDocument(TermPtr t, DocumentPtr doc, AnalyzerPtr analyzer) { return updateDocument(doc, analyzer, t); } - + bool DocumentsWriter::updateDocument(DocumentPtr doc, AnalyzerPtr analyzer, TermPtr delTerm) { // This call is synchronized but fast DocumentsWriterThreadStatePtr state(getThreadState(doc, delTerm)); - + DocStatePtr docState(state->docState); docState->doc = doc; docState->analyzer = analyzer; - + bool success = false; LuceneException finally; try @@ -750,10 +750,10 @@ namespace Lucene } docState->clear(); finally.throwException(); - + // This call is synchronized but fast finishDocument(state, perDoc); - + success = true; } catch (LuceneException& e) @@ -789,10 +789,10 @@ namespace Lucene abort(); return false; } - + state->isIdle = true; notifyAll(); - + // If this thread state had decided to flush, we must clear it so another thread can flush if (state->doFlushAfter) { @@ -800,30 +800,30 @@ namespace Lucene flushPending = false; notifyAll(); } - - // Immediately mark this document as deleted since likely it was partially added. This keeps + + // Immediately mark this document as deleted since likely it was partially added. This keeps // indexing as "all or none" (atomic) when adding a document addDeleteDocID(state->docState->docID); } } finally.throwException(); - + return (state->doFlushAfter || timeToFlushDeletes()); } - + int32_t DocumentsWriter::getNumBufferedDeleteTerms() { SyncLock syncLock(this); return deletesInRAM->numTerms; } - + MapTermNum DocumentsWriter::getBufferedDeleteTerms() { SyncLock syncLock(this); return deletesInRAM->terms; } - + void DocumentsWriter::remapDeletes(SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergeDocCount) { SyncLock syncLock(this); @@ -837,7 +837,7 @@ namespace Lucene deletesFlushed->remap(mapper, infos, docMaps, delCounts, merge, mergeDocCount); flushedDocCount -= mapper->docShift; } - + void DocumentsWriter::waitReady(DocumentsWriterThreadStatePtr state) { SyncLock syncLock(this); @@ -846,7 +846,7 @@ namespace Lucene if (closed) boost::throw_exception(AlreadyClosedException(L"this IndexWriter is closed")); } - + bool DocumentsWriter::bufferDeleteTerms(Collection terms) { SyncLock syncLock(this); @@ -855,7 +855,7 @@ namespace Lucene addDeleteTerm(*term, numDocsInRAM); return timeToFlushDeletes(); } - + bool DocumentsWriter::bufferDeleteTerm(TermPtr term) { SyncLock syncLock(this); @@ -863,7 +863,7 @@ namespace Lucene addDeleteTerm(term, numDocsInRAM); return timeToFlushDeletes(); } - + bool DocumentsWriter::bufferDeleteQueries(Collection queries) { SyncLock syncLock(this); @@ -872,7 +872,7 @@ namespace Lucene addDeleteQuery(*query, numDocsInRAM); return timeToFlushDeletes(); } - + bool DocumentsWriter::bufferDeleteQuery(QueryPtr query) { SyncLock syncLock(this); @@ -880,7 +880,7 @@ namespace Lucene addDeleteQuery(query, numDocsInRAM); return timeToFlushDeletes(); } - + bool DocumentsWriter::deletesFull() { SyncLock syncLock(this); @@ -889,12 +889,12 @@ namespace Lucene (maxBufferedDeleteTerms != IndexWriter::DISABLE_AUTO_FLUSH && ((deletesInRAM->size() + deletesFlushed->size()) >= maxBufferedDeleteTerms))); } - + bool DocumentsWriter::doApplyDeletes() { SyncLock syncLock(this); // Very similar to deletesFull(), except we don't count numBytesAlloc, because we are checking whether - // deletes (alone) are consuming too many resources now and thus should be applied. We apply deletes + // deletes (alone) are consuming too many resources now and thus should be applied. We apply deletes // if RAM usage is > 1/2 of our allowed RAM buffer, to prevent too-frequent flushing of a long tail of // tiny segments when merges (which always apply deletes) are infrequent. return ((ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && @@ -902,13 +902,13 @@ namespace Lucene (maxBufferedDeleteTerms != IndexWriter::DISABLE_AUTO_FLUSH && ((deletesInRAM->size() + deletesFlushed->size()) >= maxBufferedDeleteTerms))); } - + bool DocumentsWriter::timeToFlushDeletes() { SyncLock syncLock(this); return ((bufferIsFull || deletesFull()) && setFlushPending()); } - + bool DocumentsWriter::checkDeleteTerm(TermPtr term) { if (term) @@ -916,29 +916,29 @@ namespace Lucene lastDeleteTerm = term; return true; } - + void DocumentsWriter::setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms) { this->maxBufferedDeleteTerms = maxBufferedDeleteTerms; } - + int32_t DocumentsWriter::getMaxBufferedDeleteTerms() { return maxBufferedDeleteTerms; } - + bool DocumentsWriter::hasDeletes() { SyncLock syncLock(this); return deletesFlushed->any(); } - + bool DocumentsWriter::applyDeletes(SegmentInfosPtr infos) { SyncLock syncLock(this); if (!hasDeletes()) return false; - + if (infoStream) { message(L"apply " + StringUtils::toString(deletesFlushed->numTerms) + L" buffered deleted terms and " + @@ -946,18 +946,18 @@ namespace Lucene StringUtils::toString(deletesFlushed->queries.size()) + L" deleted queries on " + StringUtils::toString(infos->size()) + L" segments."); } - + int32_t infosEnd = infos->size(); - + int32_t docStart = 0; bool any = false; IndexWriterPtr writer(_writer); - + for (int32_t i = 0; i < infosEnd; ++i) { // Make sure we never attempt to apply deletes to segment in external dir BOOST_ASSERT(infos->info(i)->dir == directory); - + SegmentReaderPtr reader(writer->readerPool->get(infos->info(i), false)); LuceneException finally; try @@ -973,20 +973,20 @@ namespace Lucene writer->readerPool->release(reader); finally.throwException(); } - + deletesFlushed->clear(); - + return any; } - + bool DocumentsWriter::applyDeletes(IndexReaderPtr reader, int32_t docIDStart) { SyncLock syncLock(this); int32_t docEnd = docIDStart + reader->maxDoc(); bool any = false; - + BOOST_ASSERT(checkDeleteTerm(TermPtr())); - + // Delete by term TermDocsPtr docs(reader->termDocs()); LuceneException finally; @@ -1014,7 +1014,7 @@ namespace Lucene } docs->close(); finally.throwException(); - + // Delete by docID for (Collection::iterator docID = deletesFlushed->docIDs.begin(); docID != deletesFlushed->docIDs.end(); ++docID) { @@ -1024,7 +1024,7 @@ namespace Lucene any = true; } } - + // Delete by query IndexSearcherPtr searcher(newLucene(reader)); for (MapQueryInt::iterator entry = deletesFlushed->queries.begin(); entry != deletesFlushed->queries.end(); ++entry) @@ -1046,7 +1046,7 @@ namespace Lucene searcher->close(); return any; } - + void DocumentsWriter::addDeleteTerm(TermPtr term, int32_t docCount) { SyncLock syncLock(this); @@ -1057,32 +1057,32 @@ namespace Lucene else num->setNum(docIDUpto); ++deletesInRAM->numTerms; - + deletesInRAM->addBytesUsed(BYTES_PER_DEL_TERM + term->_text.length() * CHAR_NUM_BYTE); } - + void DocumentsWriter::addDeleteDocID(int32_t docID) { SyncLock syncLock(this); deletesInRAM->docIDs.add(flushedDocCount + docID); deletesInRAM->addBytesUsed(BYTES_PER_DEL_DOCID); } - + void DocumentsWriter::addDeleteQuery(QueryPtr query, int32_t docID) { SyncLock syncLock(this); deletesInRAM->queries.put(query, flushedDocCount + docID); deletesInRAM->addBytesUsed(BYTES_PER_DEL_QUERY); } - + bool DocumentsWriter::doBalanceRAM() { SyncLock syncLock(this); return (ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && !bufferIsFull && - (numBytesUsed + deletesInRAM->bytesUsed + deletesFlushed->bytesUsed >= ramBufferSize || + (numBytesUsed + deletesInRAM->bytesUsed + deletesFlushed->bytesUsed >= ramBufferSize || numBytesAlloc >= freeTrigger)); } - + void DocumentsWriter::finishDocument(DocumentsWriterThreadStatePtr perThread, DocWriterPtr docWriter) { if (doBalanceRAM()) @@ -1090,14 +1090,14 @@ namespace Lucene // Must call this without holding synchronized(this) else we'll hit deadlock balanceRAM(); } - + { SyncLock syncLock(this); BOOST_ASSERT(!docWriter || docWriter->docID == perThread->docState->docID); - + if (aborting) { - // We are currently aborting, and another thread is waiting for me to become idle. We + // We are currently aborting, and another thread is waiting for me to become idle. We // just forcefully idle this threadState; it will be fully reset by abort() if (docWriter) { @@ -1109,14 +1109,14 @@ namespace Lucene { } } - + perThread->isIdle = true; notifyAll(); return; } - + bool doPause; - + if (docWriter) doPause = waitQueue->add(docWriter); else @@ -1124,21 +1124,21 @@ namespace Lucene skipDocWriter->docID = perThread->docState->docID; doPause = waitQueue->add(skipDocWriter); } - + if (doPause) waitForWaitQueue(); - + if (bufferIsFull && !flushPending) { flushPending = true; perThread->doFlushAfter = true; } - + perThread->isIdle = true; notifyAll(); } } - + void DocumentsWriter::waitForWaitQueue() { SyncLock syncLock(this); @@ -1148,12 +1148,12 @@ namespace Lucene } while (!waitQueue->doResume()); } - + int64_t DocumentsWriter::getRAMUsed() { return numBytesUsed + deletesInRAM->bytesUsed + deletesFlushed->bytesUsed; } - + IntArray DocumentsWriter::getIntBlock(bool trackAllocations) { SyncLock syncLock(this); @@ -1161,8 +1161,8 @@ namespace Lucene IntArray b; if (size == 0) { - // Always record a block allocated, even if trackAllocations is false. This is necessary because - // this block will be shared between things that don't track allocations (term vectors) and things + // Always record a block allocated, even if trackAllocations is false. This is necessary because + // this block will be shared between things that don't track allocations (term vectors) and things // that do (freq/prox postings). numBytesAlloc += INT_BLOCK_SIZE * INT_NUM_BYTE; b = IntArray::newInstance(INT_BLOCK_SIZE); @@ -1174,20 +1174,20 @@ namespace Lucene BOOST_ASSERT(numBytesUsed <= numBytesAlloc); return b; } - + void DocumentsWriter::bytesAllocated(int64_t numBytes) { SyncLock syncLock(this); numBytesAlloc += numBytes; } - + void DocumentsWriter::bytesUsed(int64_t numBytes) { SyncLock syncLock(this); numBytesUsed += numBytes; BOOST_ASSERT(numBytesUsed <= numBytesAlloc); } - + void DocumentsWriter::recycleIntBlocks(Collection blocks, int32_t start, int32_t end) { SyncLock syncLock(this); @@ -1197,7 +1197,7 @@ namespace Lucene blocks[i].reset(); } } - + CharArray DocumentsWriter::getCharBlock() { SyncLock syncLock(this); @@ -1216,7 +1216,7 @@ namespace Lucene BOOST_ASSERT(numBytesUsed <= numBytesAlloc); return c; } - + void DocumentsWriter::recycleCharBlocks(Collection blocks, int32_t numBlocks) { SyncLock syncLock(this); @@ -1226,19 +1226,19 @@ namespace Lucene blocks[i].reset(); } } - + String DocumentsWriter::toMB(int64_t v) { return StringUtils::toString((double)v / 1024.0 / 1024.0); } - + void DocumentsWriter::balanceRAM() { // We flush when we've used our target usage int64_t flushTrigger = ramBufferSize; - + int64_t deletesRAMUsed = deletesInRAM->bytesUsed + deletesFlushed->bytesUsed; - + if (numBytesAlloc + deletesRAMUsed > freeTrigger) { if (infoStream) @@ -1252,20 +1252,20 @@ namespace Lucene L" perDocFree=" + toMB(perDocAllocator->freeByteBlocks.size() * PER_DOC_BLOCK_SIZE) + L" charBlockFree=" + toMB(freeCharBlocks.size() * CHAR_BLOCK_SIZE * CHAR_NUM_BYTE)); } - + int64_t startBytesAlloc = numBytesAlloc + deletesRAMUsed; - + int32_t iter = 0; - + // We free equally from each pool in 32 KB chunks until we are below our threshold (freeLevel) - + bool any = true; - + while (numBytesAlloc + deletesRAMUsed > freeLevel) { { SyncLock syncLock(this); - if (perDocAllocator->freeByteBlocks.empty() && byteBlockAllocator->freeByteBlocks.empty() && + if (perDocAllocator->freeByteBlocks.empty() && byteBlockAllocator->freeByteBlocks.empty() && freeCharBlocks.empty() && freeIntBlocks.empty() && !any) { // Nothing else to free -- must flush now. @@ -1280,25 +1280,25 @@ namespace Lucene BOOST_ASSERT(numBytesUsed <= numBytesAlloc); break; } - + if ((iter % 5) == 0 && !byteBlockAllocator->freeByteBlocks.empty()) { byteBlockAllocator->freeByteBlocks.removeLast(); numBytesAlloc -= BYTE_BLOCK_SIZE; } - + if ((iter % 5) == 1 && !freeCharBlocks.empty()) { freeCharBlocks.removeLast(); numBytesAlloc -= CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; } - + if ((iter % 5) == 2 && !freeIntBlocks.empty()) { freeIntBlocks.removeLast(); numBytesAlloc -= INT_BLOCK_SIZE * INT_NUM_BYTE; } - + if ((iter % 5) == 3 && !perDocAllocator->freeByteBlocks.empty()) { // Remove upwards of 32 blocks (each block is 1K) @@ -1311,20 +1311,20 @@ namespace Lucene } } } - + if ((iter % 5) == 4 && any) { // Ask consumer to free any recycled state any = consumer->freeRAM(); } - + ++iter; } - + if (infoStream) { - message(L" after free: freedMB=" + StringUtils::toString((double)(startBytesAlloc - numBytesAlloc - deletesRAMUsed) / 1024.0 / 1024.0) + - L" usedMB=" + StringUtils::toString((double)(numBytesUsed + deletesRAMUsed) / 1024.0 / 1024.0) + + message(L" after free: freedMB=" + StringUtils::toString((double)(startBytesAlloc - numBytesAlloc - deletesRAMUsed) / 1024.0 / 1024.0) + + L" usedMB=" + StringUtils::toString((double)(numBytesUsed + deletesRAMUsed) / 1024.0 / 1024.0) + L" allocMB=" + StringUtils::toString((double)numBytesAlloc / 1024.0 / 1024.0)); } } @@ -1346,44 +1346,44 @@ namespace Lucene } } } - + DocState::DocState() { maxFieldLength = 0; docID = 0; } - + DocState::~DocState() { } - + bool DocState::testPoint(const String& name) { return IndexWriterPtr(DocumentsWriterPtr(_docWriter)->_writer)->testPoint(name); } - + void DocState::clear() { // don't hold onto doc nor analyzer, in case it is large doc.reset(); analyzer.reset(); } - + PerDocBuffer::PerDocBuffer(DocumentsWriterPtr docWriter) { _docWriter = docWriter; } - + PerDocBuffer::~PerDocBuffer() { } - + ByteArray PerDocBuffer::newBuffer(int32_t size) { BOOST_ASSERT(size == DocumentsWriter::PER_DOC_BLOCK_SIZE); return DocumentsWriterPtr(_docWriter)->perDocAllocator->getByteBlock(false); } - + void PerDocBuffer::recycle() { SyncLock syncLock(this); @@ -1399,59 +1399,59 @@ namespace Lucene BOOST_ASSERT(numBuffers() == 0); } } - + DocWriter::DocWriter() { docID = 0; } - + DocWriter::~DocWriter() { } - + void DocWriter::setNext(DocWriterPtr next) { this->next = next; } - + IndexingChain::~IndexingChain() { } - + DefaultIndexingChain::~DefaultIndexingChain() { } - + DocConsumerPtr DefaultIndexingChain::getChain(DocumentsWriterPtr documentsWriter) { TermsHashConsumerPtr termVectorsWriter(newLucene(documentsWriter)); TermsHashConsumerPtr freqProxWriter(newLucene()); - + InvertedDocConsumerPtr termsHash(newLucene(documentsWriter, true, freqProxWriter, - newLucene(documentsWriter, false, + newLucene(documentsWriter, false, termVectorsWriter, TermsHashPtr()))); - + DocInverterPtr docInverter(newLucene(termsHash, newLucene())); return newLucene(documentsWriter, docInverter); } - + SkipDocWriter::~SkipDocWriter() { } - + void SkipDocWriter::finish() { } - + void SkipDocWriter::abort() { } - + int64_t SkipDocWriter::sizeInBytes() { return 0; } - + WaitQueue::WaitQueue(DocumentsWriterPtr docWriter) { this->_docWriter = docWriter; @@ -1461,11 +1461,11 @@ namespace Lucene numWaiting = 0; waitingBytes = 0; } - + WaitQueue::~WaitQueue() { } - + void WaitQueue::reset() { SyncLock syncLock(this); @@ -1474,19 +1474,19 @@ namespace Lucene BOOST_ASSERT(waitingBytes == 0); nextWriteDocID = 0; } - + bool WaitQueue::doResume() { SyncLock syncLock(this); return (waitingBytes <= DocumentsWriterPtr(_docWriter)->waitQueueResumeBytes); } - + bool WaitQueue::doPause() { SyncLock syncLock(this); return (waitingBytes > DocumentsWriterPtr(_docWriter)->waitQueuePauseBytes); } - + void WaitQueue::abort() { SyncLock syncLock(this); @@ -1504,7 +1504,7 @@ namespace Lucene BOOST_ASSERT(count == numWaiting); numWaiting = 0; } - + void WaitQueue::writeDocument(DocWriterPtr doc) { DocumentsWriterPtr docWriter(_docWriter); @@ -1530,7 +1530,7 @@ namespace Lucene docWriter->setAborting(); finally.throwException(); } - + bool WaitQueue::add(DocWriterPtr doc) { SyncLock syncLock(this); @@ -1554,8 +1554,8 @@ namespace Lucene } else { - // I finished before documents that were added before me. This can easily happen when I am a small doc - // and the docs before me were large, or just due to luck in the thread scheduling. Just add myself to + // I finished before documents that were added before me. This can easily happen when I am a small doc + // and the docs before me were large, or just due to luck in the thread scheduling. Just add myself to // the queue and when that large doc finishes, it will flush me int32_t gap = doc->docID - nextWriteDocID; if (gap >= waiting.size()) @@ -1567,37 +1567,37 @@ namespace Lucene MiscUtils::arrayCopy(waiting.begin(), 0, newArray.begin(), waiting.size() - nextWriteLoc, nextWriteLoc); nextWriteLoc = 0; waiting = newArray; - gap = doc->docID - nextWriteDocID; + gap = doc->docID - nextWriteDocID; } - + int32_t loc = nextWriteLoc + gap; if (loc >= waiting.size()) loc -= waiting.size(); - + // We should only wrap one time BOOST_ASSERT(loc < waiting.size()); - + // Nobody should be in my spot! BOOST_ASSERT(!waiting[loc]); waiting[loc] = doc; ++numWaiting; waitingBytes += doc->sizeInBytes(); } - + return doPause(); } - + ByteBlockAllocator::ByteBlockAllocator(DocumentsWriterPtr docWriter, int32_t blockSize) { this->blockSize = blockSize; this->freeByteBlocks = Collection::newInstance(); this->_docWriter = docWriter; } - + ByteBlockAllocator::~ByteBlockAllocator() { } - + ByteArray ByteBlockAllocator::getByteBlock(bool trackAllocations) { DocumentsWriterPtr docWriter(_docWriter); @@ -1606,7 +1606,7 @@ namespace Lucene ByteArray b; if (size == 0) { - // Always record a block allocated, even if trackAllocations is false. This is necessary because this block will + // Always record a block allocated, even if trackAllocations is false. This is necessary because this block will // be shared between things that don't track allocations (term vectors) and things that do (freq/prox postings). docWriter->numBytesAlloc += blockSize; b = ByteArray::newInstance(blockSize); @@ -1619,7 +1619,7 @@ namespace Lucene BOOST_ASSERT(docWriter->numBytesUsed <= docWriter->numBytesAlloc); return b; } - + void ByteBlockAllocator::recycleByteBlocks(Collection blocks, int32_t start, int32_t end) { DocumentsWriterPtr docWriter(_docWriter); @@ -1630,7 +1630,7 @@ namespace Lucene blocks[i].reset(); } } - + void ByteBlockAllocator::recycleByteBlocks(Collection blocks) { DocumentsWriterPtr docWriter(_docWriter); diff --git a/src/core/index/DocumentsWriterThreadState.cpp b/src/core/index/DocumentsWriterThreadState.cpp index 731dfbe8..c19aebb5 100644 --- a/src/core/index/DocumentsWriterThreadState.cpp +++ b/src/core/index/DocumentsWriterThreadState.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,11 +15,11 @@ namespace Lucene { this->_docWriter = docWriter; } - + DocumentsWriterThreadState::~DocumentsWriterThreadState() { } - + void DocumentsWriterThreadState::initialize() { isIdle = true; @@ -33,7 +33,7 @@ namespace Lucene docState->_docWriter = docWriter; consumer = docWriter->consumer->addThread(shared_from_this()); } - + void DocumentsWriterThreadState::doAfterFlush() { numThreads = 0; diff --git a/src/core/index/FieldInfo.cpp b/src/core/index/FieldInfo.cpp index e5a406c1..27180a6f 100644 --- a/src/core/index/FieldInfo.cpp +++ b/src/core/index/FieldInfo.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -9,13 +9,13 @@ namespace Lucene { - FieldInfo::FieldInfo(const String& name, bool isIndexed, int32_t number, bool storeTermVector, bool storePositionWithTermVector, + FieldInfo::FieldInfo(const String& name, bool isIndexed, int32_t number, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) { this->name = name; this->isIndexed = isIndexed; this->number = number; - + // for non-indexed fields, leave defaults this->storeTermVector = isIndexed ? storeTermVector : false; this->storeOffsetWithTermVector = isIndexed ? storeOffsetWithTermVector : false; @@ -24,19 +24,19 @@ namespace Lucene this->omitNorms = isIndexed ? omitNorms : true; this->omitTermFreqAndPositions = isIndexed ? omitTermFreqAndPositions : false; } - + FieldInfo::~FieldInfo() { } - + LuceneObjectPtr FieldInfo::clone(LuceneObjectPtr other) { - return newLucene(name, isIndexed, number, storeTermVector, storePositionWithTermVector, + return newLucene(name, isIndexed, number, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); } - - void FieldInfo::update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, + + void FieldInfo::update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) { if (this->isIndexed != isIndexed) diff --git a/src/core/index/FieldInfos.cpp b/src/core/index/FieldInfos.cpp index c58f032d..7122f420 100644 --- a/src/core/index/FieldInfos.cpp +++ b/src/core/index/FieldInfos.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -31,14 +31,14 @@ namespace Lucene const uint8_t FieldInfos::OMIT_NORMS = 0x10; const uint8_t FieldInfos::STORE_PAYLOADS = 0x20; const uint8_t FieldInfos::OMIT_TERM_FREQ_AND_POSITIONS = 0x40; - + FieldInfos::FieldInfos() { format = 0; byNumber = Collection::newInstance(); byName = MapStringFieldInfo::newInstance(); } - + FieldInfos::FieldInfos(DirectoryPtr d, const String& name) { format = 0; @@ -81,11 +81,11 @@ namespace Lucene input->close(); finally.throwException(); } - + FieldInfos::~FieldInfos() { } - + LuceneObjectPtr FieldInfos::clone(LuceneObjectPtr other) { SyncLock syncLock(this); @@ -98,19 +98,19 @@ namespace Lucene } return fis; } - + void FieldInfos::add(DocumentPtr doc) { SyncLock syncLock(this); Collection fields(doc->getFields()); for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { - add((*field)->name(), (*field)->isIndexed(), (*field)->isTermVectorStored(), - (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), + add((*field)->name(), (*field)->isIndexed(), (*field)->isTermVectorStored(), + (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions()); } } - + bool FieldInfos::hasProx() { for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) @@ -120,43 +120,43 @@ namespace Lucene } return false; } - + void FieldInfos::addIndexed(HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector) { SyncLock syncLock(this); for (HashSet::iterator name = names.begin(); name != names.end(); ++name) add(*name, true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector); } - + void FieldInfos::add(HashSet names, bool isIndexed) { SyncLock syncLock(this); for (HashSet::iterator name = names.begin(); name != names.end(); ++name) add(*name, isIndexed); } - + void FieldInfos::add(const String& name, bool isIndexed) { add(name, isIndexed, false, false, false, false); } - + void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector) { add(name, isIndexed, storeTermVector, false, false, false); } - + void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector) { add(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, false); } - + void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms) { add(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, false, false); } - - FieldInfoPtr FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + + FieldInfoPtr FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) { SyncLock syncLock(this); @@ -167,45 +167,45 @@ namespace Lucene fi->update(isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); return fi; } - - FieldInfoPtr FieldInfos::addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + + FieldInfoPtr FieldInfos::addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) { - FieldInfoPtr fi(newLucene(name, isIndexed, byNumber.size(), storeTermVector, - storePositionWithTermVector, storeOffsetWithTermVector, + FieldInfoPtr fi(newLucene(name, isIndexed, byNumber.size(), storeTermVector, + storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions)); byNumber.add(fi); byName.put(name, fi); return fi; } - + int32_t FieldInfos::fieldNumber(const String& fieldName) { FieldInfoPtr fi(fieldInfo(fieldName)); return fi ? fi->number : -1; } - + FieldInfoPtr FieldInfos::fieldInfo(const String& fieldName) { return byName.get(fieldName); } - + String FieldInfos::fieldName(int32_t fieldNumber) { FieldInfoPtr fi(fieldInfo(fieldNumber)); return fi ? fi->name : L""; } - + FieldInfoPtr FieldInfos::fieldInfo(int32_t fieldNumber) { return (fieldNumber >= 0 && fieldNumber < byNumber.size()) ? byNumber[fieldNumber] : FieldInfoPtr(); } - + int32_t FieldInfos::size() { return byNumber.size(); } - + bool FieldInfos::hasVectors() { for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) @@ -215,7 +215,7 @@ namespace Lucene } return false; } - + void FieldInfos::write(DirectoryPtr d, const String& name) { IndexOutputPtr output(d->createOutput(name)); @@ -231,7 +231,7 @@ namespace Lucene output->close(); finally.throwException(); } - + void FieldInfos::write(IndexOutputPtr output) { output->writeVInt(CURRENT_FORMAT); @@ -253,35 +253,35 @@ namespace Lucene bits |= STORE_PAYLOADS; if ((*fi)->omitTermFreqAndPositions) bits |= OMIT_TERM_FREQ_AND_POSITIONS; - + output->writeString((*fi)->name); output->writeByte(bits); } } - + void FieldInfos::read(IndexInputPtr input, const String& fileName) { int32_t firstInt = input->readVInt(); format = firstInt < 0 ? firstInt : FORMAT_PRE; // This is a real format? - + if (format != FORMAT_PRE && format != FORMAT_START) boost::throw_exception(CorruptIndexException(L"unrecognized format " + StringUtils::toString(format) + L" in file \"" + fileName + L"\"")); - + int32_t size = format == FORMAT_PRE ? firstInt : input->readVInt(); // read in the size if required for (int32_t i = 0; i < size; ++i) { String name(input->readString()); uint8_t bits = input->readByte(); - + addInternal(name, (bits & IS_INDEXED) != 0, (bits & STORE_TERMVECTOR) != 0, (bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0, (bits & STORE_OFFSET_WITH_TERMVECTOR) != 0, (bits & OMIT_NORMS) != 0, (bits & STORE_PAYLOADS) != 0, (bits & OMIT_TERM_FREQ_AND_POSITIONS) != 0); } - + if (input->getFilePointer() != input->length()) { - boost::throw_exception(CorruptIndexException(L"did not read all bytes from file \"" + fileName + L"\": read " + - StringUtils::toString(input->getFilePointer()) + L" vs size " + + boost::throw_exception(CorruptIndexException(L"did not read all bytes from file \"" + fileName + L"\": read " + + StringUtils::toString(input->getFilePointer()) + L" vs size " + StringUtils::toString(input->length()))); } } diff --git a/src/core/index/FieldInvertState.cpp b/src/core/index/FieldInvertState.cpp index 539798d5..c98d67ec 100644 --- a/src/core/index/FieldInvertState.cpp +++ b/src/core/index/FieldInvertState.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,11 +17,11 @@ namespace Lucene this->offset = offset; this->boost = boost; } - + FieldInvertState::~FieldInvertState() { } - + void FieldInvertState::reset(double docBoost) { position = 0; @@ -31,32 +31,32 @@ namespace Lucene boost = docBoost; attributeSource.reset(); } - + int32_t FieldInvertState::getPosition() { return position; } - + int32_t FieldInvertState::getLength() { return length; } - + int32_t FieldInvertState::getNumOverlap() { return numOverlap; } - + int32_t FieldInvertState::getOffset() { return offset; } - + double FieldInvertState::getBoost() { return boost; } - + AttributeSourcePtr FieldInvertState::getAttributeSource() { return attributeSource; diff --git a/src/core/index/FieldSortedTermVectorMapper.cpp b/src/core/index/FieldSortedTermVectorMapper.cpp index 0d864a72..ab43124d 100644 --- a/src/core/index/FieldSortedTermVectorMapper.cpp +++ b/src/core/index/FieldSortedTermVectorMapper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,37 +16,37 @@ namespace Lucene this->fieldToTerms = MapStringCollectionTermVectorEntry::newInstance(); this->comparator = comparator; } - + FieldSortedTermVectorMapper::FieldSortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator) : TermVectorMapper(ignoringPositions, ignoringOffsets) { this->fieldToTerms = MapStringCollectionTermVectorEntry::newInstance(); this->comparator = comparator; } - + FieldSortedTermVectorMapper::~FieldSortedTermVectorMapper() { } - + void FieldSortedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { TermVectorEntryPtr entry(newLucene(currentField, term, frequency, offsets, positions)); if (!currentSet.contains_if(luceneEqualTo(entry))) currentSet.insert(std::upper_bound(currentSet.begin(), currentSet.end(), entry, comparator), entry); } - + void FieldSortedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { currentSet = Collection::newInstance(); currentField = field; fieldToTerms.put(field, currentSet); } - + MapStringCollectionTermVectorEntry FieldSortedTermVectorMapper::getFieldToTerms() { return fieldToTerms; } - + TermVectorEntryComparator FieldSortedTermVectorMapper::getComparator() { return comparator; diff --git a/src/core/index/FieldsReader.cpp b/src/core/index/FieldsReader.cpp index 57180db2..9c46db4f 100644 --- a/src/core/index/FieldsReader.cpp +++ b/src/core/index/FieldsReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,8 +22,8 @@ namespace Lucene { - FieldsReader::FieldsReader(FieldInfosPtr fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, - int32_t formatSize, int32_t docStoreOffset, IndexInputPtr cloneableFieldsStream, + FieldsReader::FieldsReader(FieldInfosPtr fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, + int32_t formatSize, int32_t docStoreOffset, IndexInputPtr cloneableFieldsStream, IndexInputPtr cloneableIndexStream) { closed = false; @@ -39,21 +39,21 @@ namespace Lucene fieldsStream = boost::dynamic_pointer_cast(cloneableFieldsStream->clone()); indexStream = boost::dynamic_pointer_cast(cloneableIndexStream->clone()); } - + FieldsReader::FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn) { ConstructReader(d, segment, fn, BufferedIndexInput::BUFFER_SIZE, -1, 0); } - + FieldsReader::FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { ConstructReader(d, segment, fn, readBufferSize, docStoreOffset, size); } - + FieldsReader::~FieldsReader() { } - + void FieldsReader::ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { bool success = false; @@ -68,35 +68,35 @@ namespace Lucene try { fieldInfos = fn; - + cloneableFieldsStream = d->openInput(segment + L"." + IndexFileNames::FIELDS_EXTENSION(), readBufferSize); cloneableIndexStream = d->openInput(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION(), readBufferSize); - + // First version of fdx did not include a format header, but, the first int will always be 0 in that case format = cloneableIndexStream->readInt(); - + if (format > FieldsWriter::FORMAT_CURRENT) { - boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + StringUtils::toString(format) + + boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + StringUtils::toString(format) + L" expected " + StringUtils::toString(FieldsWriter::FORMAT_CURRENT) + L" or lower")); } - + formatSize = format > FieldsWriter::FORMAT ? 4 : 0; - + if (format < FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) cloneableFieldsStream->setModifiedUTF8StringsMode(); - + fieldsStream = boost::dynamic_pointer_cast(cloneableFieldsStream->clone()); - + int64_t indexSize = cloneableIndexStream->length() - formatSize; - + if (docStoreOffset != -1) { // We read only a slice out of this shared fields file this->docStoreOffset = docStoreOffset; this->_size = size; - + // Verify the file is long enough to hold all of our docs BOOST_ASSERT(((int32_t)((double)indexSize / 8.0)) >= _size + this->docStoreOffset); } @@ -105,7 +105,7 @@ namespace Lucene this->docStoreOffset = 0; this->_size = (int32_t)(indexSize >> 3); } - + indexStream = boost::dynamic_pointer_cast(cloneableIndexStream->clone()); numTotalDocs = (int32_t)(indexSize >> 3); success = true; @@ -114,25 +114,25 @@ namespace Lucene { finally = e; } - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. // In this case, we want to explicitly close any subset of things that were opened if (!success) close(); finally.throwException(); } - + LuceneObjectPtr FieldsReader::clone(LuceneObjectPtr other) { ensureOpen(); return newLucene(fieldInfos, numTotalDocs, _size, format, formatSize, docStoreOffset, cloneableFieldsStream, cloneableIndexStream); } - + void FieldsReader::ensureOpen() { if (closed) boost::throw_exception(AlreadyClosedException(L"this FieldsReader is closed")); } - + void FieldsReader::close() { if (!closed) @@ -152,31 +152,31 @@ namespace Lucene closed = true; } } - + int32_t FieldsReader::size() { return _size; } - + void FieldsReader::seekIndex(int32_t docID) { indexStream->seek(formatSize + (docID + docStoreOffset) * 8); } - + bool FieldsReader::canReadRawDocs() { - // Disable reading raw docs in 2.x format, because of the removal of compressed fields in 3.0. - // We don't want rawDocs() to decode field bits to figure out if a field was compressed, hence + // Disable reading raw docs in 2.x format, because of the removal of compressed fields in 3.0. + // We don't want rawDocs() to decode field bits to figure out if a field was compressed, hence // we enforce ordinary (non-raw) stored field merges for <3.0 indexes. return (format >= FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS); } - + DocumentPtr FieldsReader::doc(int32_t n, FieldSelectorPtr fieldSelector) { seekIndex(n); int64_t position = indexStream->readLong(); fieldsStream->seek(position); - + DocumentPtr doc(newLucene()); int32_t numFields = fieldsStream->readVInt(); for (int32_t i = 0; i < numFields; ++i) @@ -184,18 +184,18 @@ namespace Lucene int32_t fieldNumber = fieldsStream->readVInt(); FieldInfoPtr fi = fieldInfos->fieldInfo(fieldNumber); FieldSelector::FieldSelectorResult acceptField = fieldSelector ? fieldSelector->accept(fi->name) : FieldSelector::SELECTOR_LOAD; - + uint8_t bits = fieldsStream->readByte(); BOOST_ASSERT(bits <= FieldsWriter::FIELD_IS_COMPRESSED + FieldsWriter::FIELD_IS_TOKENIZED + FieldsWriter::FIELD_IS_BINARY); - + bool compressed = ((bits & FieldsWriter::FIELD_IS_COMPRESSED) != 0); - + // compressed fields are only allowed in indexes of version <= 2.9 BOOST_ASSERT(compressed ? (format < FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS) : true); - + bool tokenize = ((bits & FieldsWriter::FIELD_IS_TOKENIZED) != 0); bool binary = ((bits & FieldsWriter::FIELD_IS_BINARY) != 0); - + if (acceptField == FieldSelector::SELECTOR_LOAD) addField(doc, fi, binary, compressed, tokenize); else if (acceptField == FieldSelector::SELECTOR_LOAD_AND_BREAK) @@ -218,7 +218,7 @@ namespace Lucene return doc; } - + IndexInputPtr FieldsReader::rawDocs(Collection lengths, int32_t startDocID, int32_t numDocs) { seekIndex(startDocID); @@ -233,17 +233,17 @@ namespace Lucene lengths[count++] = (int32_t)(offset - lastOffset); lastOffset = offset; } - + fieldsStream->seek(startOffset); - + return fieldsStream; } - + void FieldsReader::skipField(bool binary, bool compressed) { skipField(binary, compressed, fieldsStream->readVInt()); } - + void FieldsReader::skipField(bool binary, bool compressed, int32_t toRead) { if (format >= FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES || binary || compressed) @@ -254,7 +254,7 @@ namespace Lucene fieldsStream->skipChars(toRead); } } - + void FieldsReader::addFieldLazy(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize) { if (binary) @@ -269,7 +269,7 @@ namespace Lucene Field::Store store = Field::STORE_YES; Field::Index index = Field::toIndex(fi->isIndexed, tokenize); Field::TermVector termVector = Field::toTermVector(fi->storeTermVector, fi->storeOffsetWithTermVector, fi->storePositionWithTermVector); - + AbstractFieldPtr f; if (compressed) { @@ -294,11 +294,11 @@ namespace Lucene f->setOmitNorms(fi->omitNorms); f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); } - + doc->add(f); } } - + void FieldsReader::addField(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize) { // we have a binary stored field, and it may be compressed @@ -317,12 +317,12 @@ namespace Lucene Field::Store store = Field::STORE_YES; Field::Index index = Field::toIndex(fi->isIndexed, tokenize); Field::TermVector termVector = Field::toTermVector(fi->storeTermVector, fi->storeOffsetWithTermVector, fi->storePositionWithTermVector); - + AbstractFieldPtr f; if (compressed) { int32_t toRead = fieldsStream->readVInt(); - + ByteArray b(ByteArray::newInstance(toRead)); fieldsStream->readBytes(b.get(), 0, b.size()); f = newLucene(fi->name, uncompressString(b), store, index, termVector); @@ -335,11 +335,11 @@ namespace Lucene f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); f->setOmitNorms(fi->omitNorms); } - + doc->add(f); } } - + int32_t FieldsReader::addFieldSize(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed) { int32_t size = fieldsStream->readVInt(); @@ -352,7 +352,7 @@ namespace Lucene doc->add(newLucene(fi->name, sizebytes, Field::STORE_YES)); return size; } - + ByteArray FieldsReader::uncompress(ByteArray b) { try @@ -365,7 +365,7 @@ namespace Lucene } return ByteArray(); } - + String FieldsReader::uncompressString(ByteArray b) { try @@ -378,8 +378,8 @@ namespace Lucene } return L""; } - - LazyField::LazyField(FieldsReaderPtr reader, const String& name, Field::Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : + + LazyField::LazyField(FieldsReaderPtr reader, const String& name, Field::Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : AbstractField(name, store, Field::INDEX_NO, Field::TERM_VECTOR_NO) { this->_reader = reader; @@ -391,7 +391,7 @@ namespace Lucene lazy = true; this->isCompressed = isCompressed; } - + LazyField::LazyField(FieldsReaderPtr reader, const String& name, Field::Store store, Field::Index index, Field::TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : AbstractField(name, store, index, termVector) { @@ -404,11 +404,11 @@ namespace Lucene lazy = true; this->isCompressed = isCompressed; } - + LazyField::~LazyField() { } - + IndexInputPtr LazyField::getFieldStream() { FieldsReaderPtr reader(_reader); @@ -420,19 +420,19 @@ namespace Lucene } return localFieldsStream; } - + ReaderPtr LazyField::readerValue() { FieldsReaderPtr(_reader)->ensureOpen(); return ReaderPtr(); } - + TokenStreamPtr LazyField::tokenStreamValue() { FieldsReaderPtr(_reader)->ensureOpen(); return TokenStreamPtr(); } - + String LazyField::stringValue() { FieldsReaderPtr reader(_reader); @@ -478,51 +478,51 @@ namespace Lucene return VariantUtils::get(fieldsData); } } - + int64_t LazyField::getPointer() { FieldsReaderPtr(_reader)->ensureOpen(); return pointer; } - + void LazyField::setPointer(int64_t pointer) { FieldsReaderPtr(_reader)->ensureOpen(); this->pointer = pointer; } - + int32_t LazyField::getToRead() { FieldsReaderPtr(_reader)->ensureOpen(); return toRead; } - + void LazyField::setToRead(int32_t toRead) { FieldsReaderPtr(_reader)->ensureOpen(); this->toRead = toRead; } - + ByteArray LazyField::getBinaryValue(ByteArray result) { FieldsReaderPtr reader(_reader); reader->ensureOpen(); - + if (_isBinary) { if (VariantUtils::isNull(fieldsData)) { ByteArray b; - + // Allocate new buffer if result is null or too small if (!result || result.size() < toRead) b = ByteArray::newInstance(toRead); else b = result; - + IndexInputPtr localFieldsStream(getFieldStream()); - - // Throw this IOException since IndexReader.document does so anyway, so probably not that big of a + + // Throw this IOException since IndexReader.document does so anyway, so probably not that big of a // change for people since they are already handling this exception when getting the document. try { @@ -537,7 +537,7 @@ namespace Lucene { boost::throw_exception(FieldReaderException(e.getError())); } - + binaryOffset = 0; binaryLength = toRead; } diff --git a/src/core/index/FieldsWriter.cpp b/src/core/index/FieldsWriter.cpp index cb4839ab..36f5008a 100644 --- a/src/core/index/FieldsWriter.cpp +++ b/src/core/index/FieldsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,14 +26,14 @@ namespace Lucene const int32_t FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES = 1; // Changed strings to UTF8 const int32_t FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS = 2; // Lucene 3.0: Removal of compressed fields - // NOTE: if you introduce a new format, make it 1 higher than the current one, and always change this if you + // NOTE: if you introduce a new format, make it 1 higher than the current one, and always change this if you // switch to a new format! const int32_t FieldsWriter::FORMAT_CURRENT = FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS; FieldsWriter::FieldsWriter(DirectoryPtr d, const String& segment, FieldInfosPtr fn) { fieldInfos = fn; - + bool success = false; String fieldsName(segment + L"." + IndexFileNames::FIELDS_EXTENSION()); LuceneException finally; @@ -60,7 +60,7 @@ namespace Lucene } } finally.throwException(); - + success = false; String indexName(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); try @@ -87,10 +87,10 @@ namespace Lucene } } finally.throwException(); - + doClose = true; } - + FieldsWriter::FieldsWriter(IndexOutputPtr fdx, IndexOutputPtr fdt, FieldInfosPtr fn) { fieldInfos = fn; @@ -98,16 +98,16 @@ namespace Lucene indexStream = fdx; doClose = false; } - + FieldsWriter::~FieldsWriter() { } - + void FieldsWriter::setFieldsStream(IndexOutputPtr stream) { this->fieldsStream = stream; } - + void FieldsWriter::flushDocument(int32_t numStoredFields, RAMOutputStreamPtr buffer) { TestScope testScope(L"FieldsWriter", L"flushDocument"); @@ -121,7 +121,7 @@ namespace Lucene indexStream->writeLong(fieldsStream->getFilePointer()); fieldsStream->writeVInt(0); } - + void FieldsWriter::flush() { indexStream->flush(); @@ -161,7 +161,7 @@ namespace Lucene finally.throwException(); } } - + void FieldsWriter::writeField(FieldInfoPtr fi, FieldablePtr field) { fieldsStream->writeVInt(fi->number); @@ -170,22 +170,22 @@ namespace Lucene bits |= FIELD_IS_TOKENIZED; if (field->isBinary()) bits |= FIELD_IS_BINARY; - + fieldsStream->writeByte(bits); - + if (field->isBinary()) { ByteArray data(field->getBinaryValue()); int32_t len = field->getBinaryLength(); int32_t offset = field->getBinaryOffset(); - + fieldsStream->writeVInt(len); fieldsStream->writeBytes(data.get(), offset, len); } else fieldsStream->writeString(field->stringValue()); } - + void FieldsWriter::addRawDocuments(IndexInputPtr stream, Collection lengths, int32_t numDocs) { int64_t position = fieldsStream->getFilePointer(); @@ -198,11 +198,11 @@ namespace Lucene fieldsStream->copyBytes(stream, position - start); BOOST_ASSERT(fieldsStream->getFilePointer() == position); } - + void FieldsWriter::addDocument(DocumentPtr doc) { indexStream->writeLong(fieldsStream->getFilePointer()); - + int32_t storedCount = 0; Collection fields(doc->getFields()); for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) @@ -211,7 +211,7 @@ namespace Lucene ++storedCount; } fieldsStream->writeVInt(storedCount); - + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { if ((*field)->isStored()) diff --git a/src/core/index/FilterIndexReader.cpp b/src/core/index/FilterIndexReader.cpp index c8154bdd..d1521fcc 100644 --- a/src/core/index/FilterIndexReader.cpp +++ b/src/core/index/FilterIndexReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,293 +14,293 @@ namespace Lucene { this->in = in; } - + FilterIndexReader::~FilterIndexReader() { } - + DirectoryPtr FilterIndexReader::directory() { return in->directory(); } - + Collection FilterIndexReader::getTermFreqVectors(int32_t docNumber) { ensureOpen(); return in->getTermFreqVectors(docNumber); } - + TermFreqVectorPtr FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field) { ensureOpen(); return in->getTermFreqVector(docNumber, field); } - + void FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) { ensureOpen(); in->getTermFreqVector(docNumber, field, mapper); } - + void FilterIndexReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) { ensureOpen(); in->getTermFreqVector(docNumber, mapper); } - + int32_t FilterIndexReader::numDocs() { // Don't call ensureOpen() here (it could affect performance) return in->numDocs(); } - + int32_t FilterIndexReader::maxDoc() { // Don't call ensureOpen() here (it could affect performance) return in->maxDoc(); } - + DocumentPtr FilterIndexReader::document(int32_t n, FieldSelectorPtr fieldSelector) { ensureOpen(); return in->document(n, fieldSelector); } - + bool FilterIndexReader::isDeleted(int32_t n) { // Don't call ensureOpen() here (it could affect performance) return in->isDeleted(n); } - + bool FilterIndexReader::hasDeletions() { // Don't call ensureOpen() here (it could affect performance) return in->hasDeletions(); } - + void FilterIndexReader::doUndeleteAll() { in->undeleteAll(); } - + bool FilterIndexReader::hasNorms(const String& field) { ensureOpen(); return in->hasNorms(field); } - + ByteArray FilterIndexReader::norms(const String& field) { ensureOpen(); return in->norms(field); } - + void FilterIndexReader::norms(const String& field, ByteArray norms, int32_t offset) { ensureOpen(); in->norms(field, norms, offset); } - + void FilterIndexReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { in->setNorm(doc, field, value); } - + TermEnumPtr FilterIndexReader::terms() { ensureOpen(); return in->terms(); } - + TermEnumPtr FilterIndexReader::terms(TermPtr t) { ensureOpen(); return in->terms(t); } - + int32_t FilterIndexReader::docFreq(TermPtr t) { ensureOpen(); return in->docFreq(t); } - + TermDocsPtr FilterIndexReader::termDocs() { ensureOpen(); return in->termDocs(); } - + TermDocsPtr FilterIndexReader::termDocs(TermPtr term) { ensureOpen(); return in->termDocs(term); } - + TermPositionsPtr FilterIndexReader::termPositions() { ensureOpen(); return in->termPositions(); } - + void FilterIndexReader::doDelete(int32_t docNum) { in->deleteDocument(docNum); } - + void FilterIndexReader::doCommit(MapStringString commitUserData) { in->commit(commitUserData); } - + void FilterIndexReader::doClose() { in->close(); - - // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is + + // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is // generally not a good idea) FieldCache::DEFAULT()->purge(shared_from_this()); } - + HashSet FilterIndexReader::getFieldNames(FieldOption fieldOption) { ensureOpen(); return in->getFieldNames(fieldOption); } - + int64_t FilterIndexReader::getVersion() { ensureOpen(); return in->getVersion(); } - + bool FilterIndexReader::isCurrent() { ensureOpen(); return in->isCurrent(); } - + bool FilterIndexReader::isOptimized() { ensureOpen(); return in->isOptimized(); } - + Collection FilterIndexReader::getSequentialSubReaders() { return in->getSequentialSubReaders(); } - + LuceneObjectPtr FilterIndexReader::getFieldCacheKey() { return in->getFieldCacheKey(); } - + LuceneObjectPtr FilterIndexReader::getDeletesCacheKey() { return in->getDeletesCacheKey(); } - + FilterTermDocs::FilterTermDocs(TermDocsPtr in) { this->in = in; } - + FilterTermDocs::~FilterTermDocs() { } - + void FilterTermDocs::seek(TermPtr term) { in->seek(term); } - + void FilterTermDocs::seek(TermEnumPtr termEnum) { in->seek(termEnum); } - + int32_t FilterTermDocs::doc() { return in->doc(); } - + int32_t FilterTermDocs::freq() { return in->freq(); } - + bool FilterTermDocs::next() { return in->next(); } - + int32_t FilterTermDocs::read(Collection docs, Collection freqs) { return in->read(docs, freqs); } - + bool FilterTermDocs::skipTo(int32_t target) { return in->skipTo(target); } - + void FilterTermDocs::close() { in->close(); } - + FilterTermPositions::FilterTermPositions(TermPositionsPtr in) : FilterTermDocs(in) { } - + FilterTermPositions::~FilterTermPositions() { } - + int32_t FilterTermPositions::nextPosition() { return boost::static_pointer_cast(in)->nextPosition(); } - + int32_t FilterTermPositions::getPayloadLength() { return boost::static_pointer_cast(in)->getPayloadLength(); } - + ByteArray FilterTermPositions::getPayload(ByteArray data, int32_t offset) { return boost::static_pointer_cast(in)->getPayload(data, offset); } - + bool FilterTermPositions::isPayloadAvailable() { return boost::static_pointer_cast(in)->isPayloadAvailable(); } - + FilterTermEnum::FilterTermEnum(TermEnumPtr in) { this->in = in; } - + FilterTermEnum::~FilterTermEnum() { } - + bool FilterTermEnum::next() { return in->next(); } - + TermPtr FilterTermEnum::term() { return in->term(); } - + int32_t FilterTermEnum::docFreq() { return in->docFreq(); } - + void FilterTermEnum::close() { in->close(); diff --git a/src/core/index/FormatPostingsDocsConsumer.cpp b/src/core/index/FormatPostingsDocsConsumer.cpp index 43dceb2b..ec221611 100644 --- a/src/core/index/FormatPostingsDocsConsumer.cpp +++ b/src/core/index/FormatPostingsDocsConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/FormatPostingsDocsWriter.cpp b/src/core/index/FormatPostingsDocsWriter.cpp index 1e83d1da..b09b689d 100644 --- a/src/core/index/FormatPostingsDocsWriter.cpp +++ b/src/core/index/FormatPostingsDocsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -30,7 +30,7 @@ namespace Lucene this->omitTermFreqAndPositions = false; this->storePayloads = false; this->freqStart = 0; - + FormatPostingsFieldsWriterPtr parentPostings(parent->_parent); this->_parent = parent; this->state = state; @@ -38,24 +38,24 @@ namespace Lucene state->flushedFiles.add(fileName); out = parentPostings->dir->createOutput(fileName); totalNumDocs = parentPostings->totalNumDocs; - + skipInterval = parentPostings->termsOut->skipInterval; skipListWriter = parentPostings->skipListWriter; skipListWriter->setFreqOutput(out); - + termInfo = newLucene(); utf8 = newLucene(); } - + FormatPostingsDocsWriter::~FormatPostingsDocsWriter() { } - + void FormatPostingsDocsWriter::initialize() { posWriter = newLucene(state, shared_from_this()); } - + void FormatPostingsDocsWriter::setField(FieldInfoPtr fieldInfo) { this->fieldInfo = fieldInfo; @@ -63,22 +63,22 @@ namespace Lucene storePayloads = fieldInfo->storePayloads; posWriter->setField(fieldInfo); } - + FormatPostingsPositionsConsumerPtr FormatPostingsDocsWriter::addDoc(int32_t docID, int32_t termDocFreq) { int32_t delta = docID - lastDocID; - + if (docID < 0 || (df > 0 && delta <= 0)) boost::throw_exception(CorruptIndexException(L"docs out of order (" + StringUtils::toString(docID) + L" <= " + StringUtils::toString(lastDocID) + L" )")); - + if ((++df % skipInterval) == 0) { skipListWriter->setSkipData(lastDocID, storePayloads, posWriter->lastPayloadLength); skipListWriter->bufferSkip(df); } - + BOOST_ASSERT(docID < totalNumDocs); - + lastDocID = docID; if (omitTermFreqAndPositions) out->writeVInt(delta); @@ -89,25 +89,25 @@ namespace Lucene out->writeVInt(delta << 1); out->writeVInt(termDocFreq); } - + return posWriter; } - + void FormatPostingsDocsWriter::finish() { int64_t skipPointer = skipListWriter->writeSkip(out); FormatPostingsTermsWriterPtr parent(_parent); termInfo->set(df, parent->freqStart, parent->proxStart, (int32_t)(skipPointer - parent->freqStart)); - + StringUtils::toUTF8(parent->currentTerm.get() + parent->currentTermStart, parent->currentTerm.size(), utf8); - + if (df > 0) parent->termsOut->add(fieldInfo->number, utf8->result, utf8->length, termInfo); - + lastDocID = 0; df = 0; } - + void FormatPostingsDocsWriter::close() { out->close(); diff --git a/src/core/index/FormatPostingsFieldsConsumer.cpp b/src/core/index/FormatPostingsFieldsConsumer.cpp index e5bedd3b..d7373eb1 100644 --- a/src/core/index/FormatPostingsFieldsConsumer.cpp +++ b/src/core/index/FormatPostingsFieldsConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/FormatPostingsFieldsWriter.cpp b/src/core/index/FormatPostingsFieldsWriter.cpp index 701118d0..a6f3bc79 100644 --- a/src/core/index/FormatPostingsFieldsWriter.cpp +++ b/src/core/index/FormatPostingsFieldsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -28,22 +28,22 @@ namespace Lucene state->flushedFiles.add(state->segmentFileName(IndexFileNames::TERMS_EXTENSION())); state->flushedFiles.add(state->segmentFileName(IndexFileNames::TERMS_INDEX_EXTENSION())); } - + FormatPostingsFieldsWriter::~FormatPostingsFieldsWriter() { } - + void FormatPostingsFieldsWriter::initialize() { termsWriter = newLucene(state, shared_from_this()); } - + FormatPostingsTermsConsumerPtr FormatPostingsFieldsWriter::addField(FieldInfoPtr field) { termsWriter->setField(field); return termsWriter; } - + void FormatPostingsFieldsWriter::finish() { termsOut->close(); diff --git a/src/core/index/FormatPostingsPositionsConsumer.cpp b/src/core/index/FormatPostingsPositionsConsumer.cpp index 45b2d343..252f4222 100644 --- a/src/core/index/FormatPostingsPositionsConsumer.cpp +++ b/src/core/index/FormatPostingsPositionsConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/FormatPostingsPositionsWriter.cpp b/src/core/index/FormatPostingsPositionsWriter.cpp index cfa86e5c..40af6d42 100644 --- a/src/core/index/FormatPostingsPositionsWriter.cpp +++ b/src/core/index/FormatPostingsPositionsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,12 +24,12 @@ namespace Lucene lastPosition = 0; storePayloads = false; lastPayloadLength = -1; - + this->_parent = parent; FormatPostingsFieldsWriterPtr parentFieldsWriter(FormatPostingsTermsWriterPtr(parent->_parent)->_parent); - + omitTermFreqAndPositions = parent->omitTermFreqAndPositions; - + if (parentFieldsWriter->fieldInfos->hasProx()) { // At least one field does not omit TF, so create the prox file @@ -43,19 +43,19 @@ namespace Lucene // Every field omits TF so we will write no prox file } } - + FormatPostingsPositionsWriter::~FormatPostingsPositionsWriter() { } - + void FormatPostingsPositionsWriter::addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength) { BOOST_ASSERT(!omitTermFreqAndPositions); BOOST_ASSERT(out); - + int32_t delta = position - lastPosition; lastPosition = position; - + if (storePayloads) { if (payloadLength != lastPayloadLength) @@ -72,19 +72,19 @@ namespace Lucene else out->writeVInt(delta); } - + void FormatPostingsPositionsWriter::setField(FieldInfoPtr fieldInfo) { omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; storePayloads = omitTermFreqAndPositions ? false : fieldInfo->storePayloads; } - + void FormatPostingsPositionsWriter::finish() { lastPosition = 0; lastPayloadLength = -1; } - + void FormatPostingsPositionsWriter::close() { if (out) diff --git a/src/core/index/FormatPostingsTermsConsumer.cpp b/src/core/index/FormatPostingsTermsConsumer.cpp index 0f045efb..a2ad2dfc 100644 --- a/src/core/index/FormatPostingsTermsConsumer.cpp +++ b/src/core/index/FormatPostingsTermsConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene FormatPostingsTermsConsumer::~FormatPostingsTermsConsumer() { } - + FormatPostingsDocsConsumerPtr FormatPostingsTermsConsumer::addTerm(const String& text) { int32_t len = text.length(); diff --git a/src/core/index/FormatPostingsTermsWriter.cpp b/src/core/index/FormatPostingsTermsWriter.cpp index e7902103..8dbe2e41 100644 --- a/src/core/index/FormatPostingsTermsWriter.cpp +++ b/src/core/index/FormatPostingsTermsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,45 +19,45 @@ namespace Lucene currentTermStart = 0; freqStart = 0; proxStart = 0; - + this->_parent = parent; this->state = state; termsOut = parent->termsOut; } - + FormatPostingsTermsWriter::~FormatPostingsTermsWriter() { } - + void FormatPostingsTermsWriter::initialize() { docsWriter = newLucene(state, shared_from_this()); } - + void FormatPostingsTermsWriter::setField(FieldInfoPtr fieldInfo) { this->fieldInfo = fieldInfo; docsWriter->setField(fieldInfo); } - + FormatPostingsDocsConsumerPtr FormatPostingsTermsWriter::addTerm(CharArray text, int32_t start) { currentTerm = text; currentTermStart = start; - + freqStart = docsWriter->out->getFilePointer(); if (docsWriter->posWriter->out) proxStart = docsWriter->posWriter->out->getFilePointer(); - + FormatPostingsFieldsWriterPtr(_parent)->skipListWriter->resetSkip(); - + return docsWriter; } - + void FormatPostingsTermsWriter::finish() { } - + void FormatPostingsTermsWriter::close() { docsWriter->close(); diff --git a/src/core/index/FreqProxFieldMergeState.cpp b/src/core/index/FreqProxFieldMergeState.cpp index 49286f56..429f5246 100644 --- a/src/core/index/FreqProxFieldMergeState.cpp +++ b/src/core/index/FreqProxFieldMergeState.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -28,43 +28,43 @@ namespace Lucene this->postingUpto = -1; this->freq = newLucene(); this->prox = newLucene(); - + this->field = field; this->charPool = TermsHashPerThreadPtr(FreqProxTermsWriterPerThreadPtr(field->_perThread)->_termsHashPerThread)->charPool; - + TermsHashPerFieldPtr termsHashPerField(field->_termsHashPerField); this->numPostings = termsHashPerField->numPostings; this->postings = termsHashPerField->sortPostings(); } - + FreqProxFieldMergeState::~FreqProxFieldMergeState() { } - + bool FreqProxFieldMergeState::nextTerm() { ++postingUpto; if (postingUpto == numPostings) return false; - + p = boost::static_pointer_cast(postings[postingUpto]); docID = 0; - + text = charPool->buffers[p->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]; textOffset = (p->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - + TermsHashPerFieldPtr termsHashPerField(field->_termsHashPerField); termsHashPerField->initReader(freq, p, 0); if (!field->fieldInfo->omitTermFreqAndPositions) termsHashPerField->initReader(prox, p, 1); - + // Should always be true bool result = nextDoc(); BOOST_ASSERT(result); - + return true; } - + bool FreqProxFieldMergeState::nextDoc() { if (freq->eof()) @@ -84,7 +84,7 @@ namespace Lucene return false; } } - + int32_t code = freq->readVInt(); if (field->omitTermFreqAndPositions) docID += code; @@ -96,9 +96,9 @@ namespace Lucene else termFreq = freq->readVInt(); } - + BOOST_ASSERT(docID != p->lastDocID); - + return true; } } diff --git a/src/core/index/FreqProxTermsWriter.cpp b/src/core/index/FreqProxTermsWriter.cpp index 04c94b88..4d24cfe8 100644 --- a/src/core/index/FreqProxTermsWriter.cpp +++ b/src/core/index/FreqProxTermsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -30,19 +30,19 @@ namespace Lucene FreqProxTermsWriter::~FreqProxTermsWriter() { } - + TermsHashConsumerPerThreadPtr FreqProxTermsWriter::addThread(TermsHashPerThreadPtr perThread) { return newLucene(perThread); } - + void FreqProxTermsWriter::createPostings(Collection postings, int32_t start, int32_t count) { int32_t end = start + count; for (int32_t i = start; i < end; ++i) postings[i] = newLucene(); } - + int32_t FreqProxTermsWriter::compareText(const wchar_t* text1, int32_t pos1, const wchar_t* text2, int32_t pos2) { while (true) @@ -62,20 +62,20 @@ namespace Lucene return 0; } } - + void FreqProxTermsWriter::closeDocStore(SegmentWriteStatePtr state) { } - + void FreqProxTermsWriter::abort() { } - + void FreqProxTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state) { // Gather all FieldData's that have postings, across all ThreadStates Collection allFields(Collection::newInstance()); - + for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) @@ -85,14 +85,14 @@ namespace Lucene allFields.add(freqProxPerField); } } - + // Sort by field name std::sort(allFields.begin(), allFields.end(), luceneCompare()); - + int32_t numAllFields = allFields.size(); - + FormatPostingsFieldsConsumerPtr consumer(newLucene(state, fieldInfos)); - + // Current writer chain: // FormatPostingsFieldsConsumer // -> IMPL: FormatPostingsFieldsWriter @@ -102,30 +102,30 @@ namespace Lucene // -> IMPL: FormatPostingsDocWriter // -> FormatPostingsPositionsConsumer // -> IMPL: FormatPostingsPositionsWriter - + int32_t start = 0; while (start < numAllFields) { FieldInfoPtr fieldInfo(allFields[start]->fieldInfo); String fieldName(fieldInfo->name); - + int32_t end = start + 1; while (end < numAllFields && allFields[end]->fieldInfo->name == fieldName) ++end; - + Collection fields(Collection::newInstance(end - start)); for (int32_t i = start; i < end; ++i) { fields[i - start] = allFields[i]; - + // Aggregate the storePayload as seen by the same field across multiple threads if (fields[i - start]->hasPayloads) fieldInfo->storePayloads = true; } - + // If this field has postings then add them to the segment appendPostings(fields, consumer); - + for (int32_t i = 0; i < fields.size(); ++i) { TermsHashPerFieldPtr perField(fields[i]->_termsHashPerField); @@ -134,53 +134,53 @@ namespace Lucene perField->shrinkHash(numPostings); fields[i]->reset(); } - + start = end; } - + for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) TermsHashPerThreadPtr(boost::static_pointer_cast(entry->first)->_termsHashPerThread)->reset(true); - + consumer->finish(); } - + void FreqProxTermsWriter::appendPostings(Collection fields, FormatPostingsFieldsConsumerPtr consumer) { TestScope testScope(L"FreqProxTermsWriter", L"appendPostings"); int32_t numFields = fields.size(); - + Collection mergeStates(Collection::newInstance(numFields)); - + for (int32_t i = 0; i < numFields; ++i) { FreqProxFieldMergeStatePtr fms(newLucene(fields[i])); mergeStates[i] = fms; - + BOOST_ASSERT(fms->field->fieldInfo == fields[0]->fieldInfo); - + // Should always be true bool result = fms->nextTerm(); BOOST_ASSERT(result); } - + FormatPostingsTermsConsumerPtr termsConsumer(consumer->addField(fields[0]->fieldInfo)); - + Collection termStates(Collection::newInstance(numFields)); - + bool currentFieldOmitTermFreqAndPositions = fields[0]->fieldInfo->omitTermFreqAndPositions; - + while (numFields > 0) { // Get the next term to merge termStates[0] = mergeStates[0]; int32_t numToMerge = 1; - + for (int32_t i = 1; i < numFields; ++i) { CharArray text = mergeStates[i]->text; int32_t textOffset = mergeStates[i]->textOffset; int32_t cmp = compareText(text.get(), textOffset, termStates[0]->text.get(), termStates[0]->textOffset); - + if (cmp < 0) { termStates[0] = mergeStates[i]; @@ -189,9 +189,9 @@ namespace Lucene else if (cmp == 0) termStates[numToMerge++] = mergeStates[i]; } - + FormatPostingsDocsConsumerPtr docConsumer(termsConsumer->addTerm(termStates[0]->text, termStates[0]->textOffset)); - + // Now termStates has numToMerge FieldMergeStates which all share the same term. Now we must // interleave the docID streams. while (numToMerge > 0) @@ -202,45 +202,45 @@ namespace Lucene if (termStates[i]->docID < minState->docID) minState = termStates[i]; } - + int32_t termDocFreq = minState->termFreq; - + FormatPostingsPositionsConsumerPtr posConsumer(docConsumer->addDoc(minState->docID, termDocFreq)); - + ByteSliceReaderPtr prox(minState->prox); - + // Carefully copy over the prox + payload info, changing the format to match Lucene's segment format. if (!currentFieldOmitTermFreqAndPositions) { - // omitTermFreqAndPositions == false so we do write positions & payload + // omitTermFreqAndPositions == false so we do write positions & payload int32_t position = 0; for (int32_t j = 0; j < termDocFreq; ++j) { int32_t code = prox->readVInt(); position += (code >> 1); - + int32_t payloadLength; if ((code & 1) != 0) { // This position has a payload payloadLength = prox->readVInt(); - + if (!payloadBuffer) payloadBuffer = ByteArray::newInstance(payloadLength); if (payloadBuffer.size() < payloadLength) payloadBuffer.resize(payloadLength); - + prox->readBytes(payloadBuffer.get(), 0, payloadLength); } else payloadLength = 0; - + posConsumer->addPosition(position, payloadBuffer, 0, payloadLength); } - + posConsumer->finish(); } - + if (!minState->nextDoc()) { // Remove from termStates @@ -252,9 +252,9 @@ namespace Lucene } --numToMerge; BOOST_ASSERT(upto == numToMerge); - + // Advance this state to the next term - + if (!minState->nextTerm()) { // OK, no more terms, so remove from mergeStates as well @@ -269,18 +269,18 @@ namespace Lucene } } } - + docConsumer->finish(); } - + termsConsumer->finish(); } - + int32_t FreqProxTermsWriter::bytesPerPosting() { return RawPostingList::BYTES_SIZE + 4 * DocumentsWriter::INT_NUM_BYTE; } - + FreqProxTermsWriterPostingList::FreqProxTermsWriterPostingList() { docFreq = 0; @@ -288,7 +288,7 @@ namespace Lucene lastDocCode = 0; lastPosition = 0; } - + FreqProxTermsWriterPostingList::~FreqProxTermsWriterPostingList() { } diff --git a/src/core/index/FreqProxTermsWriterPerField.cpp b/src/core/index/FreqProxTermsWriterPerField.cpp index 8f1437a2..b2d29898 100644 --- a/src/core/index/FreqProxTermsWriterPerField.cpp +++ b/src/core/index/FreqProxTermsWriterPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -29,36 +29,36 @@ namespace Lucene fieldState = termsHashPerField->fieldState; omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; } - + FreqProxTermsWriterPerField::~FreqProxTermsWriterPerField() { } - + int32_t FreqProxTermsWriterPerField::getStreamCount() { return fieldInfo->omitTermFreqAndPositions ? 1 : 2; } - + void FreqProxTermsWriterPerField::finish() { } - + void FreqProxTermsWriterPerField::skippingLongTerm() { } - + int32_t FreqProxTermsWriterPerField::compareTo(LuceneObjectPtr other) { return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); } - + void FreqProxTermsWriterPerField::reset() { // Record, up front, whether our in-RAM format will be with or without term freqs omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; payloadAttribute.reset(); } - + bool FreqProxTermsWriterPerField::start(Collection fields, int32_t count) { for (int32_t i = 0; i < count; ++i) @@ -68,7 +68,7 @@ namespace Lucene } return false; } - + void FreqProxTermsWriterPerField::start(FieldablePtr field) { if (fieldState->attributeSource->hasAttribute()) @@ -76,15 +76,15 @@ namespace Lucene else payloadAttribute.reset(); } - + void FreqProxTermsWriterPerField::writeProx(FreqProxTermsWriterPostingListPtr p, int32_t proxCode) { PayloadPtr payload; if (payloadAttribute) payload = payloadAttribute->getPayload(); - + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - + if (payload && payload->length() > 0) { termsHashPerField->writeVInt(1, (proxCode << 1) | 1); @@ -96,7 +96,7 @@ namespace Lucene termsHashPerField->writeVInt(1, proxCode << 1); p->lastPosition = fieldState->position; } - + void FreqProxTermsWriterPerField::newTerm(RawPostingListPtr p) { // First time we're seeing this term since the last flush @@ -112,16 +112,16 @@ namespace Lucene writeProx(newPostingList, fieldState->position); } } - + void FreqProxTermsWriterPerField::addTerm(RawPostingListPtr p) { BOOST_ASSERT(docState->testPoint(L"FreqProxTermsWriterPerField.addTerm start")); - + FreqProxTermsWriterPostingListPtr addPostingList(boost::static_pointer_cast(p)); - + BOOST_ASSERT(omitTermFreqAndPositions || addPostingList->docFreq > 0); TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - + if (omitTermFreqAndPositions) { if (docState->docID != addPostingList->lastDocID) @@ -137,9 +137,9 @@ namespace Lucene if (docState->docID != addPostingList->lastDocID) { BOOST_ASSERT(docState->docID > addPostingList->lastDocID); - // Term not yet seen in the current doc but previously seen in other doc(s) since + // Term not yet seen in the current doc but previously seen in other doc(s) since // the last flush - + // Now that we know doc freq for previous doc, write it & lastDocCode if (addPostingList->docFreq == 1) termsHashPerField->writeVInt(0, addPostingList->lastDocCode | 1); @@ -160,7 +160,7 @@ namespace Lucene } } } - + void FreqProxTermsWriterPerField::abort() { } diff --git a/src/core/index/FreqProxTermsWriterPerThread.cpp b/src/core/index/FreqProxTermsWriterPerThread.cpp index b39012c8..2ada6d8a 100644 --- a/src/core/index/FreqProxTermsWriterPerThread.cpp +++ b/src/core/index/FreqProxTermsWriterPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,25 +16,25 @@ namespace Lucene docState = perThread->docState; _termsHashPerThread = perThread; } - + FreqProxTermsWriterPerThread::~FreqProxTermsWriterPerThread() { } - + TermsHashConsumerPerFieldPtr FreqProxTermsWriterPerThread::addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo) { return newLucene(termsHashPerField, shared_from_this(), fieldInfo); } - + void FreqProxTermsWriterPerThread::startDocument() { } - + DocWriterPtr FreqProxTermsWriterPerThread::finishDocument() { return DocWriterPtr(); } - + void FreqProxTermsWriterPerThread::abort() { } diff --git a/src/core/index/IndexCommit.cpp b/src/core/index/IndexCommit.cpp index 7b9d9c19..1d080145 100644 --- a/src/core/index/IndexCommit.cpp +++ b/src/core/index/IndexCommit.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene IndexCommit::~IndexCommit() { } - + bool IndexCommit::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -23,12 +23,12 @@ namespace Lucene return false; return (otherCommit->getDirectory()->equals(getDirectory()) && otherCommit->getVersion() == getVersion()); } - + int32_t IndexCommit::hashCode() { return (getDirectory()->hashCode() + (int32_t)getVersion()); } - + int64_t IndexCommit::getTimestamp() { return getDirectory()->fileModified(getSegmentsFileName()); diff --git a/src/core/index/IndexDeletionPolicy.cpp b/src/core/index/IndexDeletionPolicy.cpp index 0221e43c..8fae6f4a 100644 --- a/src/core/index/IndexDeletionPolicy.cpp +++ b/src/core/index/IndexDeletionPolicy.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/IndexFileDeleter.cpp b/src/core/index/IndexFileDeleter.cpp index dd1f51dc..32dd7a50 100644 --- a/src/core/index/IndexFileDeleter.cpp +++ b/src/core/index/IndexFileDeleter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,7 +24,7 @@ namespace Lucene { /// Change to true to see details of reference counts when infoStream != null bool IndexFileDeleter::VERBOSE_REF_COUNTS = false; - + IndexFileDeleter::IndexFileDeleter(DirectoryPtr directory, IndexDeletionPolicyPtr policy, SegmentInfosPtr segmentInfos, InfoStreamPtr infoStream, DocumentsWriterPtr docWriter, HashSet synced) { this->lastFiles = Collection< HashSet >::newInstance(); @@ -34,30 +34,30 @@ namespace Lucene this->docWriter = docWriter; this->infoStream = infoStream; this->synced = synced; - + if (infoStream) message(L"init: current segments file is \"" + segmentInfos->getCurrentSegmentFileName()); - + this->policy = policy; this->directory = directory; - + // First pass: walk the files and initialize our ref counts int64_t currentGen = segmentInfos->getGeneration(); IndexFileNameFilterPtr filter(IndexFileNameFilter::getFilter()); - + HashSet files(directory->listAll()); CommitPointPtr currentCommitPoint; - + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { if (filter->accept(L"", *fileName) && *fileName != IndexFileNames::SEGMENTS_GEN()) { // Add this file to refCounts with initial count 0 getRefCount(*fileName); - + if (boost::starts_with(*fileName, IndexFileNames::SEGMENTS())) { - // This is a commit (segments or segments_N), and it's valid (<= the max gen). + // This is a commit (segments or segments_N), and it's valid (<= the max gen). // Load it, then incref all files it refers to if (infoStream) message(L"init: load commit \"" + *fileName + L"\""); @@ -72,7 +72,7 @@ namespace Lucene boost::throw_exception(e); else { - // Most likely we are opening an index that has an aborted "future" commit, + // Most likely we are opening an index that has an aborted "future" commit, // so suppress exc in this case sis.reset(); } @@ -90,19 +90,19 @@ namespace Lucene currentCommitPoint = commitPoint; commits.add(commitPoint); incRef(sis, true); - + if (!lastSegmentInfos || sis->getGeneration() > lastSegmentInfos->getGeneration()) lastSegmentInfos = sis; } } } } - + if (!currentCommitPoint) { // We did not in fact see the segments_N file corresponding to the segmentInfos that was passed - // in. Yet, it must exist, because our caller holds the write lock. This can happen when the - // directory listing was stale (eg when index accessed via NFS client with stale directory listing + // in. Yet, it must exist, because our caller holds the write lock. This can happen when the + // directory listing was stale (eg when index accessed via NFS client with stale directory listing // cache). So we try now to explicitly open this commit point. SegmentInfosPtr sis(newLucene()); try @@ -119,10 +119,10 @@ namespace Lucene commits.add(currentCommitPoint); incRef(sis, true); } - + // We keep commits list in sorted order (oldest to newest) std::sort(commits.begin(), commits.end(), luceneCompare()); - + // Now delete anything with ref count at 0. These are presumably abandoned files eg due to crash of IndexWriter. for (MapStringRefCount::iterator entry = refCounts.begin(); entry != refCounts.end(); ++entry) { @@ -133,27 +133,27 @@ namespace Lucene deleteFile(entry->first); } } - + // Finally, give policy a chance to remove things on startup policy->onInit(commits); - + // Always protect the incoming segmentInfos since sometime it may not be the most recent commit checkpoint(segmentInfos, false); - + startingCommitDeleted = currentCommitPoint->isDeleted(); - + deleteCommits(); } - + IndexFileDeleter::~IndexFileDeleter() { } - + void IndexFileDeleter::setInfoStream(InfoStreamPtr infoStream) { this->infoStream = infoStream; } - + void IndexFileDeleter::message(const String& message) { if (infoStream) @@ -162,12 +162,12 @@ namespace Lucene *infoStream << L"; " << StringUtils::toString(LuceneThread::currentId()) << L"]: " << message << L"\n"; } } - + SegmentInfosPtr IndexFileDeleter::getLastSegmentInfos() { return lastSegmentInfos; } - + void IndexFileDeleter::deleteCommits() { if (!commitsToDelete.empty()) @@ -181,7 +181,7 @@ namespace Lucene decRef(*file); } commitsToDelete.clear(); - + // Now compact commits to remove deleted ones (preserving the sort) int32_t size = commits.size(); int32_t readFrom = 0; @@ -197,7 +197,7 @@ namespace Lucene } ++readFrom; } - + while (size > writeTo) { commits.removeLast(); @@ -205,17 +205,17 @@ namespace Lucene } } } - + void IndexFileDeleter::refresh(const String& segmentName) { HashSet files(directory->listAll()); IndexFileNameFilterPtr filter(IndexFileNameFilter::getFilter()); String segmentPrefix1(segmentName + L"."); String segmentPrefix2(segmentName + L"_"); - + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { - if (filter->accept(L"", *fileName) && + if (filter->accept(L"", *fileName) && (segmentName.empty() || boost::starts_with(*fileName, segmentPrefix1) || boost::starts_with(*fileName, segmentPrefix2)) && !refCounts.contains(*fileName) && *fileName != IndexFileNames::SEGMENTS_GEN()) { @@ -226,12 +226,12 @@ namespace Lucene } } } - + void IndexFileDeleter::refresh() { refresh(L""); } - + void IndexFileDeleter::close() { // DecRef old files from the last checkpoint, if any @@ -240,7 +240,7 @@ namespace Lucene lastFiles.clear(); deletePendingFiles(); } - + void IndexFileDeleter::deletePendingFiles() { if (deletable) @@ -255,26 +255,26 @@ namespace Lucene } } } - + void IndexFileDeleter::checkpoint(SegmentInfosPtr segmentInfos, bool isCommit) { if (infoStream) message(L"now checkpoint \"" + segmentInfos->getCurrentSegmentFileName() + L"\" [" + StringUtils::toString(segmentInfos->size()) + L" segments; isCommit = " + StringUtils::toString(isCommit) + L"]"); - + // Try again now to delete any previously un-deletable files (because they were in use, on Windows) deletePendingFiles(); - + // Incref the files incRef(segmentInfos, isCommit); - + if (isCommit) { // Append to our commits list commits.add(newLucene(commitsToDelete, directory, segmentInfos)); - + // Tell policy so it can remove commits policy->onCommit(commits); - + // Decref files for commits that were deleted by the policy deleteCommits(); } @@ -286,25 +286,25 @@ namespace Lucene docWriterFiles = docWriter->openFiles(); if (docWriterFiles) { - // We must incRef these files before decRef'ing last files to make sure we + // We must incRef these files before decRef'ing last files to make sure we // don't accidentally delete them incRef(docWriterFiles); } } - + // DecRef old files from the last checkpoint, if any for (Collection< HashSet >::iterator file = lastFiles.begin(); file != lastFiles.end(); ++file) decRef(*file); lastFiles.clear(); - + // Save files so we can decr on next checkpoint/commit lastFiles.add(segmentInfos->files(directory, false)); - + if (docWriterFiles) lastFiles.add(docWriterFiles); } } - + void IndexFileDeleter::incRef(SegmentInfosPtr segmentInfos, bool isCommit) { // If this is a commit point, also incRef the segments_N file @@ -312,13 +312,13 @@ namespace Lucene for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) incRef(*fileName); } - + void IndexFileDeleter::incRef(HashSet files) { for (HashSet::iterator file = files.begin(); file != files.end(); ++file) incRef(*file); } - + void IndexFileDeleter::incRef(const String& fileName) { RefCountPtr rc(getRefCount(fileName)); @@ -326,13 +326,13 @@ namespace Lucene message(L" IncRef \"" + fileName + L"\": pre-incr count is " + StringUtils::toString(rc->count)); rc->IncRef(); } - + void IndexFileDeleter::decRef(HashSet files) { for (HashSet::iterator file = files.begin(); file != files.end(); ++file) decRef(*file); } - + void IndexFileDeleter::decRef(const String& fileName) { RefCountPtr rc(getRefCount(fileName)); @@ -343,7 +343,7 @@ namespace Lucene // This file is no longer referenced by any past commit points nor by the in-memory SegmentInfos deleteFile(fileName); refCounts.remove(fileName); - + if (synced) { SyncLock syncLock(&synced); @@ -351,17 +351,17 @@ namespace Lucene } } } - + void IndexFileDeleter::decRef(SegmentInfosPtr segmentInfos) { decRef(segmentInfos->files(directory, false)); } - + bool IndexFileDeleter::exists(const String& fileName) { return refCounts.contains(fileName) ? getRefCount(fileName)->count > 0 : false; } - + RefCountPtr IndexFileDeleter::getRefCount(const String& fileName) { RefCountPtr rc; @@ -375,13 +375,13 @@ namespace Lucene rc = ref->second; return rc; } - + void IndexFileDeleter::deleteFiles(HashSet files) { for (HashSet::iterator file = files.begin(); file != files.end(); ++file) deleteFile(*file); } - + void IndexFileDeleter::deleteNewFiles(HashSet files) { for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) @@ -394,7 +394,7 @@ namespace Lucene } } } - + void IndexFileDeleter::deleteFile(const String& fileName) { try @@ -408,7 +408,7 @@ namespace Lucene if (directory->fileExists(fileName)) // if delete fails { // Some operating systems (eg. Windows) don't permit a file to be deleted while it is opened - // for read (eg. by another process or thread). So we assume that when a delete fails it is + // for read (eg. by another process or thread). So we assume that when a delete fails it is // because the file is open in another process, and queue the file for subsequent deletion. if (infoStream) message(L"IndexFileDeleter: unable to remove file \"" + fileName + L"\": " + e.getError() + L"; Will re-try later."); @@ -418,18 +418,18 @@ namespace Lucene } } } - + RefCount::RefCount(const String& fileName) { initDone = false; count = 0; this->fileName = fileName; } - + RefCount::~RefCount() { } - + int32_t RefCount::IncRef() { if (!initDone) @@ -438,17 +438,17 @@ namespace Lucene BOOST_ASSERT(count > 0); return ++count; } - + int32_t RefCount::DecRef() { BOOST_ASSERT(count > 0); return --count; } - + CommitPoint::CommitPoint(Collection commitsToDelete, DirectoryPtr directory, SegmentInfosPtr segmentInfos) { deleted = false; - + this->directory = directory; this->commitsToDelete = commitsToDelete; userData = segmentInfos->getUserData(); @@ -459,54 +459,54 @@ namespace Lucene this->files = HashSet::newInstance(files.begin(), files.end()); gen = segmentInfos->getGeneration(); _isOptimized = (segmentInfos->size() == 1 && !segmentInfos->info(0)->hasDeletions()); - + BOOST_ASSERT(!segmentInfos->hasExternalSegments(directory)); } - + CommitPoint::~CommitPoint() { } - + String CommitPoint::toString() { return L"IndexFileDeleter::CommitPoint(" + segmentsFileName + L")"; } - + bool CommitPoint::isOptimized() { return _isOptimized; } - + String CommitPoint::getSegmentsFileName() { return segmentsFileName; } - + HashSet CommitPoint::getFileNames() { return files; } - + DirectoryPtr CommitPoint::getDirectory() { return directory; } - + int64_t CommitPoint::getVersion() { return version; } - + int64_t CommitPoint::getGeneration() { return generation; } - + MapStringString CommitPoint::getUserData() { return userData; } - + void CommitPoint::deleteCommit() { if (!deleted) @@ -515,12 +515,12 @@ namespace Lucene commitsToDelete.add(shared_from_this()); } } - + bool CommitPoint::isDeleted() { return deleted; } - + int32_t CommitPoint::compareTo(LuceneObjectPtr other) { CommitPointPtr otherCommit(boost::static_pointer_cast(other)); diff --git a/src/core/index/IndexFileNameFilter.cpp b/src/core/index/IndexFileNameFilter.cpp index 35ae238d..189d1800 100644 --- a/src/core/index/IndexFileNameFilter.cpp +++ b/src/core/index/IndexFileNameFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -37,7 +37,7 @@ namespace Lucene } return false; } - + bool IndexFileNameFilter::isCFSFile(const String& name) { String::size_type i = name.find_last_of(L'.'); @@ -51,7 +51,7 @@ namespace Lucene } return false; } - + IndexFileNameFilterPtr IndexFileNameFilter::getFilter() { static IndexFileNameFilterPtr singleton; diff --git a/src/core/index/IndexFileNames.cpp b/src/core/index/IndexFileNames.cpp index 52ea1534..3dcba767 100644 --- a/src/core/index/IndexFileNames.cpp +++ b/src/core/index/IndexFileNames.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,127 +15,127 @@ namespace Lucene IndexFileNames::~IndexFileNames() { } - + const String& IndexFileNames::SEGMENTS() { static String _SEGMENTS(L"segments"); return _SEGMENTS; } - + const String& IndexFileNames::SEGMENTS_GEN() { static String _SEGMENTS_GEN(L"segments.gen"); return _SEGMENTS_GEN; } - + const String& IndexFileNames::DELETABLE() { static String _DELETABLE(L"deletable"); return _DELETABLE; } - + const String& IndexFileNames::NORMS_EXTENSION() { static String _NORMS_EXTENSION(L"nrm"); return _NORMS_EXTENSION; } - + const String& IndexFileNames::FREQ_EXTENSION() { static String _FREQ_EXTENSION(L"frq"); return _FREQ_EXTENSION; } - + const String& IndexFileNames::PROX_EXTENSION() { static String _PROX_EXTENSION(L"prx"); return _PROX_EXTENSION; } - + const String& IndexFileNames::TERMS_EXTENSION() { static String _TERMS_EXTENSION(L"tis"); return _TERMS_EXTENSION; } - + const String& IndexFileNames::TERMS_INDEX_EXTENSION() { static String _TERMS_INDEX_EXTENSION(L"tii"); return _TERMS_INDEX_EXTENSION; } - + const String& IndexFileNames::FIELDS_INDEX_EXTENSION() { static String _FIELDS_INDEX_EXTENSION(L"fdx"); return _FIELDS_INDEX_EXTENSION; } - + const String& IndexFileNames::FIELDS_EXTENSION() { static String _FIELDS_EXTENSION(L"fdt"); return _FIELDS_EXTENSION; } - + const String& IndexFileNames::VECTORS_FIELDS_EXTENSION() { static String _VECTORS_FIELDS_EXTENSION(L"tvf"); return _VECTORS_FIELDS_EXTENSION; } - + const String& IndexFileNames::VECTORS_DOCUMENTS_EXTENSION() { static String _VECTORS_DOCUMENTS_EXTENSION(L"tvd"); return _VECTORS_DOCUMENTS_EXTENSION; } - + const String& IndexFileNames::VECTORS_INDEX_EXTENSION() { static String _VECTORS_INDEX_EXTENSION(L"tvx"); return _VECTORS_INDEX_EXTENSION; } - + const String& IndexFileNames::COMPOUND_FILE_EXTENSION() { static String _COMPOUND_FILE_EXTENSION(L"cfs"); return _COMPOUND_FILE_EXTENSION; } - + const String& IndexFileNames::COMPOUND_FILE_STORE_EXTENSION() { static String _COMPOUND_FILE_STORE_EXTENSION(L"cfx"); return _COMPOUND_FILE_STORE_EXTENSION; } - + const String& IndexFileNames::DELETES_EXTENSION() { static String _DELETES_EXTENSION(L"del"); return _DELETES_EXTENSION; } - + const String& IndexFileNames::FIELD_INFOS_EXTENSION() { static String _FIELD_INFOS_EXTENSION(L"fnm"); return _FIELD_INFOS_EXTENSION; } - + const String& IndexFileNames::PLAIN_NORMS_EXTENSION() { static String _PLAIN_NORMS_EXTENSION(L"f"); return _PLAIN_NORMS_EXTENSION; } - + const String& IndexFileNames::SEPARATE_NORMS_EXTENSION() { static String _SEPARATE_NORMS_EXTENSION(L"s"); return _SEPARATE_NORMS_EXTENSION; } - + const String& IndexFileNames::GEN_EXTENSION() { static String _GEN_EXTENSION(L"gen"); return _GEN_EXTENSION; } - + const HashSet IndexFileNames::INDEX_EXTENSIONS() { static HashSet _INDEX_EXTENSIONS; @@ -160,7 +160,7 @@ namespace Lucene } return _INDEX_EXTENSIONS; }; - + const HashSet IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE() { static HashSet _INDEX_EXTENSIONS_IN_COMPOUND_FILE; @@ -181,7 +181,7 @@ namespace Lucene } return _INDEX_EXTENSIONS_IN_COMPOUND_FILE; }; - + const HashSet IndexFileNames::STORE_INDEX_EXTENSIONS() { static HashSet _STORE_INDEX_EXTENSIONS; @@ -196,7 +196,7 @@ namespace Lucene } return _STORE_INDEX_EXTENSIONS; }; - + const HashSet IndexFileNames::NON_STORE_INDEX_EXTENSIONS() { static HashSet _NON_STORE_INDEX_EXTENSIONS; @@ -212,7 +212,7 @@ namespace Lucene } return _NON_STORE_INDEX_EXTENSIONS; }; - + const HashSet IndexFileNames::COMPOUND_EXTENSIONS() { static HashSet _COMPOUND_EXTENSIONS; @@ -229,7 +229,7 @@ namespace Lucene } return _COMPOUND_EXTENSIONS; }; - + const HashSet IndexFileNames::VECTOR_EXTENSIONS() { static HashSet _VECTOR_EXTENSIONS; @@ -242,7 +242,7 @@ namespace Lucene } return _VECTOR_EXTENSIONS; }; - + String IndexFileNames::fileNameFromGeneration(const String& base, const String& extension, int64_t gen) { if (gen == SegmentInfo::NO) @@ -252,7 +252,7 @@ namespace Lucene else return base + L"_" + StringUtils::toString(gen, StringUtils::CHARACTER_MAX_RADIX) + extension; } - + bool IndexFileNames::isDocStoreFile(const String& fileName) { if (boost::ends_with(fileName, COMPOUND_FILE_STORE_EXTENSION())) @@ -264,7 +264,7 @@ namespace Lucene } return false; } - + String IndexFileNames::segmentFileName(const String& segmentName, const String& ext) { return segmentName + L"." + ext; diff --git a/src/core/index/IndexReader.cpp b/src/core/index/IndexReader.cpp index 4489441e..b3de1318 100644 --- a/src/core/index/IndexReader.cpp +++ b/src/core/index/IndexReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,24 +21,24 @@ namespace Lucene { const int32_t IndexReader::DEFAULT_TERMS_INDEX_DIVISOR = 1; - + IndexReader::IndexReader() { refCount = 1; closed = false; _hasChanges = false; } - + IndexReader::~IndexReader() { } - + int32_t IndexReader::getRefCount() { SyncLock syncLock(this); return refCount; } - + void IndexReader::incRef() { SyncLock syncLock(this); @@ -46,7 +46,7 @@ namespace Lucene ensureOpen(); ++refCount; } - + void IndexReader::decRef() { SyncLock syncLock(this); @@ -59,67 +59,67 @@ namespace Lucene } --refCount; } - + void IndexReader::ensureOpen() { if (refCount <= 0) boost::throw_exception(AlreadyClosedException(L"this IndexReader is closed")); } - + IndexReaderPtr IndexReader::open(DirectoryPtr directory) { return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), true, DEFAULT_TERMS_INDEX_DIVISOR); } - + IndexReaderPtr IndexReader::open(DirectoryPtr directory, bool readOnly) { return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - + IndexReaderPtr IndexReader::open(IndexCommitPtr commit, bool readOnly) { return open(commit->getDirectory(), IndexDeletionPolicyPtr(), commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - + IndexReaderPtr IndexReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly) { return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - + IndexReaderPtr IndexReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, termInfosIndexDivisor); } - + IndexReaderPtr IndexReader::open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly) { return open(commit->getDirectory(), deletionPolicy, commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - + IndexReaderPtr IndexReader::open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { return open(commit->getDirectory(), deletionPolicy, commit, readOnly, termInfosIndexDivisor); } - + IndexReaderPtr IndexReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor) { return DirectoryReader::open(directory, deletionPolicy, commit, readOnly, termInfosIndexDivisor); } - + IndexReaderPtr IndexReader::reopen() { SyncLock syncLock(this); boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen().")); return IndexReaderPtr(); } - + IndexReaderPtr IndexReader::reopen(bool openReadOnly) { SyncLock syncLock(this); boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen().")); return IndexReaderPtr(); } - + IndexReaderPtr IndexReader::reopen(IndexCommitPtr commit) { SyncLock syncLock(this); @@ -134,7 +134,7 @@ namespace Lucene boost::throw_exception(UnsupportedOperationException(L"This reader does not implement clone().")); return other; } - + LuceneObjectPtr IndexReader::clone(bool openReadOnly, LuceneObjectPtr other) { SyncLock syncLock(this); @@ -142,74 +142,74 @@ namespace Lucene boost::throw_exception(UnsupportedOperationException(L"This reader does not implement clone(bool).")); return other; } - + DirectoryPtr IndexReader::directory() { ensureOpen(); boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); return DirectoryPtr(); } - + int64_t IndexReader::lastModified(DirectoryPtr directory2) { return newLucene(newLucene(), directory2)->run(); } - + int64_t IndexReader::getCurrentVersion(DirectoryPtr directory) { return SegmentInfos::readCurrentVersion(directory); } - + MapStringString IndexReader::getCommitUserData(DirectoryPtr directory) { return SegmentInfos::readCurrentUserData(directory); } - + int64_t IndexReader::getVersion() { boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); return 0; } - + MapStringString IndexReader::getCommitUserData() { boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); return MapStringString(); } - + bool IndexReader::isCurrent() { boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); return false; } - + bool IndexReader::isOptimized() { boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); return false; } - + bool IndexReader::indexExists(DirectoryPtr directory) { return (SegmentInfos::getCurrentSegmentGeneration(directory) != -1); } - + int32_t IndexReader::numDeletedDocs() { return (maxDoc() - numDocs()); } - + DocumentPtr IndexReader::document(int32_t n) { ensureOpen(); return document(n, FieldSelectorPtr()); } - + bool IndexReader::hasChanges() { return _hasChanges; } - + bool IndexReader::hasNorms(const String& field) { // backward compatible implementation. @@ -217,7 +217,7 @@ namespace Lucene ensureOpen(); return norms(field); } - + void IndexReader::setNorm(int32_t doc, const String& field, uint8_t value) { SyncLock syncLock(this); @@ -226,7 +226,7 @@ namespace Lucene _hasChanges = true; doSetNorm(doc, field, value); } - + void IndexReader::setNorm(int32_t doc, const String& field, double value) { ensureOpen(); @@ -240,7 +240,7 @@ namespace Lucene _termDocs->seek(term); return _termDocs; } - + TermPositionsPtr IndexReader::termPositions(TermPtr term) { ensureOpen(); @@ -248,7 +248,7 @@ namespace Lucene _termPositions->seek(term); return _termPositions; } - + void IndexReader::deleteDocument(int32_t docNum) { SyncLock syncLock(this); @@ -257,7 +257,7 @@ namespace Lucene _hasChanges = true; doDelete(docNum); } - + int32_t IndexReader::deleteDocuments(TermPtr term) { ensureOpen(); @@ -282,7 +282,7 @@ namespace Lucene finally.throwException(); return n; } - + void IndexReader::undeleteAll() { SyncLock syncLock(this); @@ -291,32 +291,32 @@ namespace Lucene _hasChanges = true; doUndeleteAll(); } - + void IndexReader::acquireWriteLock() { SyncLock syncLock(this); // NOOP } - + void IndexReader::flush() { SyncLock syncLock(this); ensureOpen(); commit(); } - + void IndexReader::flush(MapStringString commitUserData) { SyncLock syncLock(this); ensureOpen(); commit(commitUserData); } - + void IndexReader::commit() { commit(MapStringString()); } - + void IndexReader::commit(MapStringString commitUserData) { SyncLock syncLock(this); @@ -324,7 +324,7 @@ namespace Lucene doCommit(commitUserData); _hasChanges = false; } - + void IndexReader::close() { SyncLock syncLock(this); @@ -334,18 +334,18 @@ namespace Lucene closed = true; } } - + IndexCommitPtr IndexReader::getIndexCommit() { boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); return IndexCommitPtr(); } - + void IndexReader::main(Collection args) { String filename; bool extract = false; - + for (Collection::iterator arg = args.begin(); arg != args.end(); ++arg) { if (*arg == L"-extract") @@ -353,16 +353,16 @@ namespace Lucene else if (filename.empty()) filename = *arg; } - + if (filename.empty()) { std::wcout << L"Usage: IndexReader [-extract] "; return; } - + DirectoryPtr dir; CompoundFileReaderPtr cfr; - + LuceneException finally; try { @@ -370,25 +370,25 @@ namespace Lucene filename = FileUtils::extractPath(filename); dir = FSDirectory::open(dirname); cfr = newLucene(dir, filename); - + HashSet _files(cfr->listAll()); Collection files(Collection::newInstance(_files.begin(), _files.end())); std::sort(files.begin(), files.end()); // sort the array of filename so that the output is more readable - + for (Collection::iterator file = files.begin(); file != files.end(); ++file) { int64_t len = cfr->fileLength(*file); - + if (extract) { std::wcout << L"extract " << *file << L" with " << len << L" bytes to local directory..."; IndexInputPtr ii(cfr->openInput(*file)); boost::filesystem::ofstream f(*file, std::ios::binary | std::ios::out); - + // read and write with a small buffer, which is more effective than reading byte by byte ByteArray buffer(ByteArray::newInstance(1024)); - + int32_t chunk = buffer.size(); while (len > 0) { @@ -407,56 +407,56 @@ namespace Lucene { finally = e; } - + if (dir) dir->close(); if (cfr) cfr->close(); - + finally.throwException(); } - + Collection IndexReader::listCommits(DirectoryPtr dir) { return DirectoryReader::listCommits(dir); } - + Collection IndexReader::getSequentialSubReaders() { return Collection(); // override } - + LuceneObjectPtr IndexReader::getFieldCacheKey() { return shared_from_this(); } - + LuceneObjectPtr IndexReader::getDeletesCacheKey() { return shared_from_this(); } - + int64_t IndexReader::getUniqueTermCount() { boost::throw_exception(UnsupportedOperationException(L"This reader does not implement getUniqueTermCount()")); return 0; } - + int32_t IndexReader::getTermInfosIndexDivisor() { boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); return 0; } - + FindSegmentsModified::FindSegmentsModified(SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) { result = 0; } - + FindSegmentsModified::~FindSegmentsModified() { } - + uint64_t FindSegmentsModified::doBody(const String& segmentFileName) { return directory->fileModified(segmentFileName); diff --git a/src/core/index/IndexWriter.cpp b/src/core/index/IndexWriter.cpp index a7cc6883..22d59afb 100644 --- a/src/core/index/IndexWriter.cpp +++ b/src/core/index/IndexWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -32,43 +32,43 @@ namespace Lucene { - /// The normal read buffer size defaults to 1024, but increasing this during merging seems to - /// yield performance gains. However we don't want to increase it too much because there are + /// The normal read buffer size defaults to 1024, but increasing this during merging seems to + /// yield performance gains. However we don't want to increase it too much because there are /// quite a few BufferedIndexInputs created during merging. const int32_t IndexWriter::MERGE_READ_BUFFER_SIZE = 4096; - + int32_t IndexWriter::MESSAGE_ID = 0; InfoStreamPtr IndexWriter::defaultInfoStream; - + /// Default value for the write lock timeout (1,000). int64_t IndexWriter::WRITE_LOCK_TIMEOUT = 1000; - + const String IndexWriter::WRITE_LOCK_NAME = L"write.lock"; - + /// Value to denote a flush trigger is disabled. const int32_t IndexWriter::DISABLE_AUTO_FLUSH = -1; - + /// Disabled by default (because IndexWriter flushes by RAM usage by default). const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DOCS = IndexWriter::DISABLE_AUTO_FLUSH; - + /// Default value is 16 MB (which means flush when buffered docs consume 16 MB RAM). const double IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB = 16.0; - + /// Disabled by default (because IndexWriter flushes by RAM usage by default). const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DELETE_TERMS = IndexWriter::DISABLE_AUTO_FLUSH; - + /// Default value is 10000. const int32_t IndexWriter::DEFAULT_MAX_FIELD_LENGTH = 10000; - + /// Default value is 128. const int32_t IndexWriter::DEFAULT_TERM_INDEX_INTERVAL = 128; - + /// Sets the maximum field length to INT_MAX const int32_t IndexWriter::MaxFieldLengthUNLIMITED = INT_MAX; - + /// Sets the maximum field length to {@link #DEFAULT_MAX_FIELD_LENGTH} const int32_t IndexWriter::MaxFieldLengthLIMITED = IndexWriter::DEFAULT_MAX_FIELD_LENGTH; - + IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) { this->directory = d; @@ -76,7 +76,7 @@ namespace Lucene this->create = create; this->maxFieldLength = mfl; } - + IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, int32_t mfl) { this->directory = d; @@ -84,7 +84,7 @@ namespace Lucene this->create = !IndexReader::indexExists(d); this->maxFieldLength = mfl; } - + IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl) { this->directory = d; @@ -93,7 +93,7 @@ namespace Lucene this->create = !IndexReader::indexExists(d); this->maxFieldLength = mfl; } - + IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl) { this->directory = d; @@ -102,7 +102,7 @@ namespace Lucene this->deletionPolicy = deletionPolicy; this->maxFieldLength = mfl; } - + IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexingChainPtr indexingChain, IndexCommitPtr commit) { this->directory = d; @@ -113,7 +113,7 @@ namespace Lucene this->indexingChain = indexingChain; this->indexCommit = commit; } - + IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexCommitPtr commit) { this->directory = d; @@ -123,11 +123,11 @@ namespace Lucene this->maxFieldLength = mfl; this->indexCommit = commit; } - + IndexWriter::~IndexWriter() { } - + void IndexWriter::initialize() { messageID = -1; @@ -171,16 +171,16 @@ namespace Lucene if (create) directory->clearLock(WRITE_LOCK_NAME); // clear the write lock in case it's leftover - + LockPtr writeLock(directory->makeLock(WRITE_LOCK_NAME)); - + if (!writeLock->obtain((int32_t)writeLockTimeout)) // obtain write lock boost::throw_exception(LockObtainFailedException(L"Index locked for write: " + writeLock->toString())); this->writeLock = writeLock; - + bool success = false; LuceneException finally; - + try { if (create) @@ -193,7 +193,7 @@ namespace Lucene segmentInfos->read(directory); segmentInfos->clear(); doCommit = false; - } + } catch (LuceneException&) { // Likely this means it's a fresh directory @@ -206,7 +206,7 @@ namespace Lucene segmentInfos->commit(directory); HashSet files(segmentInfos->files(directory, true)); synced.addAll(files.begin(), files.end()); - } + } else { // Record that we have a change (zero out all segments) pending @@ -216,7 +216,7 @@ namespace Lucene else { segmentInfos->read(directory); - + if (indexCommit) { // Swap out all segments, but, keep metadata in SegmentInfos, like version & generation, to @@ -230,41 +230,41 @@ namespace Lucene if (infoStream) message(L"init: loaded commit \"" + indexCommit->getSegmentsFileName() + L"\""); } - + // We assume that this segments_N was previously properly sync'd HashSet files(segmentInfos->files(directory, true)); synced.addAll(files.begin(), files.end()); } - + setRollbackSegmentInfos(segmentInfos); - + docWriter = newLucene(directory, shared_from_this(), indexingChain); docWriter->setInfoStream(infoStream); docWriter->setMaxFieldLength(maxFieldLength); - + // Default deleter (for backwards compatibility) is KeepOnlyLastCommitDeleter deleter = newLucene(directory, deletionPolicy ? deletionPolicy : newLucene(), segmentInfos, infoStream, docWriter, synced); - + if (deleter->startingCommitDeleted) { // Deletion policy deleted the "head" commit point. We have to mark ourself as changed so that if we // are closed without any further changes we write a new segments_N file. ++changeCount; } - + pushMaxBufferedDocs(); - + if (infoStream) message(L"init: create=" + StringUtils::toString(create)); messageState(); - + success = true; } catch (LuceneException& e) { finally = e; } - + if (!success) { if (infoStream) @@ -279,10 +279,10 @@ namespace Lucene } this->writeLock.reset(); } - + finally.throwException(); } - + int32_t IndexWriter::MAX_TERM_LENGTH() { static int32_t _MAX_TERM_LENGTH = 0; @@ -290,19 +290,19 @@ namespace Lucene _MAX_TERM_LENGTH = DocumentsWriter::MAX_TERM_LENGTH; return _MAX_TERM_LENGTH; } - + IndexReaderPtr IndexWriter::getReader() { return getReader(readerTermsIndexDivisor); } - + IndexReaderPtr IndexWriter::getReader(int32_t termInfosIndexDivisor) { ensureOpen(); - + if (infoStream) message(L"flush at getReader"); - + // Do this up front before flushing so that the readers obtained during this flush are pooled, the first time // this method is called poolReaders = true; @@ -318,7 +318,7 @@ namespace Lucene maybeMerge(); return r; } - + int32_t IndexWriter::numDeletedDocs(SegmentInfoPtr info) { SegmentReaderPtr reader(readerPool->getIfExists(info)); @@ -337,20 +337,20 @@ namespace Lucene finally.throwException(); return deletedDocs; } - + void IndexWriter::acquireWrite() { SyncLock syncLock(this); BOOST_ASSERT(writeThread != LuceneThread::currentId()); while (writeThread != 0 || readCount > 0) doWait(); - + // we could have been closed while we were waiting ensureOpen(); - + writeThread = LuceneThread::currentId(); } - + void IndexWriter::releaseWrite() { SyncLock syncLock(this); @@ -358,7 +358,7 @@ namespace Lucene writeThread = 0; notifyAll(); } - + void IndexWriter::acquireRead() { SyncLock syncLock(this); @@ -367,7 +367,7 @@ namespace Lucene doWait(); ++readCount; } - + void IndexWriter::upgradeReadToWrite() { SyncLock syncLock(this); @@ -379,7 +379,7 @@ namespace Lucene --readCount; --upgradeCount; } - + void IndexWriter::releaseRead() { SyncLock syncLock(this); @@ -387,7 +387,7 @@ namespace Lucene BOOST_ASSERT(readCount >= 0); notifyAll(); } - + bool IndexWriter::isOpen(bool includePendingClose) { SyncLock syncLock(this); @@ -400,12 +400,12 @@ namespace Lucene if (!isOpen(includePendingClose)) boost::throw_exception(AlreadyClosedException(L"This IndexWriter is closed")); } - + void IndexWriter::ensureOpen() { ensureOpen(true); } - + void IndexWriter::message(const String& message) { if (infoStream) @@ -415,7 +415,7 @@ namespace Lucene *infoStream << L"; " << StringUtils::toString(LuceneThread::currentId()) << L"]: " << message << L"\n"; } } - + void IndexWriter::setMessageID(InfoStreamPtr infoStream) { SyncLock syncLock(this); @@ -426,7 +426,7 @@ namespace Lucene } this->infoStream = infoStream; } - + LogMergePolicyPtr IndexWriter::getLogMergePolicy() { LogMergePolicyPtr logMergePolicy(boost::dynamic_pointer_cast(mergePolicy)); @@ -435,18 +435,18 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"This method can only be called when the merge policy is the default LogMergePolicy")); return LogMergePolicyPtr(); } - + bool IndexWriter::getUseCompoundFile() { return getLogMergePolicy()->getUseCompoundFile(); } - + void IndexWriter::setUseCompoundFile(bool value) { getLogMergePolicy()->setUseCompoundFile(value); getLogMergePolicy()->setUseCompoundDocStore(value); } - + void IndexWriter::setSimilarity(SimilarityPtr similarity) { ensureOpen(); @@ -459,13 +459,13 @@ namespace Lucene ensureOpen(); return this->similarity; } - + void IndexWriter::setTermIndexInterval(int32_t interval) { ensureOpen(); this->termIndexInterval = interval; } - + int32_t IndexWriter::getTermIndexInterval() { // We pass false because this method is called by SegmentMerger while we are in the process of closing @@ -483,13 +483,13 @@ namespace Lucene for (int32_t i = 0; i < size; ++i) rollbackSegments.put(rollbackSegmentInfos->info(i), i); } - + void IndexWriter::setMergePolicy(MergePolicyPtr mp) { ensureOpen(); if (!mp) boost::throw_exception(NullPointerException(L"MergePolicy must be non-null")); - + if (mergePolicy != mp) mergePolicy->close(); mergePolicy = mp; @@ -497,13 +497,13 @@ namespace Lucene if (infoStream) message(L"setMergePolicy"); } - + MergePolicyPtr IndexWriter::getMergePolicy() { ensureOpen(); return mergePolicy; } - + void IndexWriter::setMergeScheduler(MergeSchedulerPtr mergeScheduler) { SyncLock syncLock(this); @@ -519,23 +519,23 @@ namespace Lucene if (infoStream) message(L"setMergeScheduler"); } - + MergeSchedulerPtr IndexWriter::getMergeScheduler() { ensureOpen(); return mergeScheduler; } - + void IndexWriter::setMaxMergeDocs(int32_t maxMergeDocs) { getLogMergePolicy()->setMaxMergeDocs(maxMergeDocs); } - + int32_t IndexWriter::getMaxMergeDocs() { return getLogMergePolicy()->getMaxMergeDocs(); } - + void IndexWriter::setMaxFieldLength(int32_t maxFieldLength) { ensureOpen(); @@ -544,13 +544,13 @@ namespace Lucene if (infoStream) message(L"setMaxFieldLength " + StringUtils::toString(maxFieldLength)); } - + int32_t IndexWriter::getMaxFieldLength() { ensureOpen(); return maxFieldLength; } - + void IndexWriter::setReaderTermsIndexDivisor(int32_t divisor) { ensureOpen(); @@ -560,13 +560,13 @@ namespace Lucene if (infoStream) message(L"setReaderTermsIndexDivisor " + StringUtils::toString(readerTermsIndexDivisor)); } - + int32_t IndexWriter::getReaderTermsIndexDivisor() { ensureOpen(); return readerTermsIndexDivisor; } - + void IndexWriter::setMaxBufferedDocs(int32_t maxBufferedDocs) { ensureOpen(); @@ -579,7 +579,7 @@ namespace Lucene if (infoStream) message(L"setMaxBufferedDocs " + StringUtils::toString(maxBufferedDocs)); } - + void IndexWriter::pushMaxBufferedDocs() { if (docWriter->getMaxBufferedDocs() != DISABLE_AUTO_FLUSH) @@ -597,13 +597,13 @@ namespace Lucene } } } - + int32_t IndexWriter::getMaxBufferedDocs() { ensureOpen(); return docWriter->getMaxBufferedDocs(); } - + void IndexWriter::setRAMBufferSizeMB(double mb) { if (mb > 2048.0) @@ -616,12 +616,12 @@ namespace Lucene if (infoStream) message(L"setRAMBufferSizeMB " + StringUtils::toString(mb)); } - + double IndexWriter::getRAMBufferSizeMB() { return docWriter->getRAMBufferSizeMB(); } - + void IndexWriter::setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms) { ensureOpen(); @@ -631,33 +631,33 @@ namespace Lucene if (infoStream) message(L"setMaxBufferedDeleteTerms " + StringUtils::toString(maxBufferedDeleteTerms)); } - + int32_t IndexWriter::getMaxBufferedDeleteTerms() { ensureOpen(); return docWriter->getMaxBufferedDeleteTerms(); } - + void IndexWriter::setMergeFactor(int32_t mergeFactor) { getLogMergePolicy()->setMergeFactor(mergeFactor); } - + int32_t IndexWriter::getMergeFactor() { return getLogMergePolicy()->getMergeFactor(); } - + void IndexWriter::setDefaultInfoStream(InfoStreamPtr infoStream) { IndexWriter::defaultInfoStream = infoStream; } - + InfoStreamPtr IndexWriter::getDefaultInfoStream() { return IndexWriter::defaultInfoStream; } - + void IndexWriter::setInfoStream(InfoStreamPtr infoStream) { ensureOpen(); @@ -666,7 +666,7 @@ namespace Lucene deleter->setInfoStream(infoStream); messageState(); } - + void IndexWriter::messageState() { if (infoStream) @@ -678,45 +678,45 @@ namespace Lucene L" index=" + segString()); } } - + InfoStreamPtr IndexWriter::getInfoStream() { ensureOpen(); return infoStream; } - + bool IndexWriter::verbose() { return infoStream.get() != NULL; } - + void IndexWriter::setWriteLockTimeout(int64_t writeLockTimeout) { ensureOpen(); this->writeLockTimeout = writeLockTimeout; } - + int64_t IndexWriter::getWriteLockTimeout() { ensureOpen(); return writeLockTimeout; } - + void IndexWriter::setDefaultWriteLockTimeout(int64_t writeLockTimeout) { IndexWriter::WRITE_LOCK_TIMEOUT = writeLockTimeout; } - + int64_t IndexWriter::getDefaultWriteLockTimeout() { return IndexWriter::WRITE_LOCK_TIMEOUT; } - + void IndexWriter::close() { close(true); } - + void IndexWriter::close(bool waitForMerges) { // Ensure that only one thread actually gets to do the closing @@ -754,56 +754,56 @@ namespace Lucene return false; } } - + void IndexWriter::closeInternal(bool waitForMerges) { docWriter->pauseAllThreads(); - + LuceneException finally; try { if (infoStream) message(L"now flush at close"); - + docWriter->close(); - + // Only allow a new merge to be triggered if we are going to wait for merges if (!hitOOM) flush(waitForMerges, true, true); - + // Give merge scheduler last chance to run, in case any pending merges are waiting if (waitForMerges) mergeScheduler->merge(shared_from_this()); - + mergePolicy->close(); - + finishMerges(waitForMerges); stopMerges = true; - + mergeScheduler->close(); - + if (infoStream) message(L"now call final commit()"); - + if (!hitOOM) commit(0); - + if (infoStream) message(L"at close: " + segString()); - + { SyncLock syncLock(this); readerPool->close(); docWriter.reset(); deleter->close(); } - + if (writeLock) { writeLock->release(); // release write lock writeLock.reset(); } - + { SyncLock syncLock(this); closed = true; @@ -831,21 +831,21 @@ namespace Lucene } finally.throwException(); } - + bool IndexWriter::flushDocStores() { SyncLock syncLock(this); - + if (infoStream) message(L"flushDocStores segment=" + docWriter->getDocStoreSegment()); - + bool useCompoundDocStore = false; - + if (infoStream) message(L"closeDocStores segment=" + docWriter->getDocStoreSegment()); - + String docStoreSegment; - + bool success = false; LuceneException finally; try @@ -860,30 +860,30 @@ namespace Lucene if (!success && infoStream) message(L"hit exception closing doc store segment"); finally.throwException(); - + if (infoStream) message(L"flushDocStores files=" + StringUtils::toString(docWriter->closedFiles())); - + useCompoundDocStore = mergePolicy->useCompoundDocStore(segmentInfos); HashSet closedFiles(docWriter->closedFiles()); - + if (useCompoundDocStore && !docStoreSegment.empty() && !closedFiles.empty()) { // Now build compound doc store file if (infoStream) message(L"create compound file " + docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); - + success = false; - + int32_t numSegments = segmentInfos->size(); String compoundFileName(docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); - + try { CompoundFileWriterPtr cfsWriter(newLucene(directory, compoundFileName)); for (HashSet::iterator file = closedFiles.begin(); file != closedFiles.end(); ++file) cfsWriter->addFile(*file); - + // Perform the merge cfsWriter->close(); success = true; @@ -892,7 +892,7 @@ namespace Lucene { finally = e; } - + if (!success) { if (infoStream) @@ -901,35 +901,35 @@ namespace Lucene docWriter->abort(); } finally.throwException(); - + for (int32_t i = 0; i < numSegments; ++i) { SegmentInfoPtr si(segmentInfos->info(i)); if (si->getDocStoreOffset() != -1 && si->getDocStoreSegment() == docStoreSegment) si->setDocStoreIsCompoundFile(true); } - + checkpoint(); - + // In case the files we just merged into a CFS were not previously checkpointed deleter->deleteNewFiles(docWriter->closedFiles()); } - + return useCompoundDocStore; } - + DirectoryPtr IndexWriter::getDirectory() { ensureOpen(false); // Pass false because the flush during closing calls getDirectory return directory; } - + AnalyzerPtr IndexWriter::getAnalyzer() { ensureOpen(); return analyzer; } - + int32_t IndexWriter::maxDoc() { SyncLock syncLock(this); @@ -938,7 +938,7 @@ namespace Lucene count += segmentInfos->info(i)->docCount; return count; } - + int32_t IndexWriter::numDocs() { SyncLock syncLock(this); @@ -950,7 +950,7 @@ namespace Lucene } return count; } - + bool IndexWriter::hasDeletions() { SyncLock syncLock(this); @@ -964,12 +964,12 @@ namespace Lucene } return false; } - + void IndexWriter::addDocument(DocumentPtr doc) { addDocument(doc, analyzer); } - + void IndexWriter::addDocument(DocumentPtr doc, AnalyzerPtr analyzer) { ensureOpen(); @@ -1011,7 +1011,7 @@ namespace Lucene boost::throw_exception(handleOOM(oom, L"addDocument")); } } - + void IndexWriter::deleteDocuments(TermPtr term) { ensureOpen(); @@ -1026,7 +1026,7 @@ namespace Lucene boost::throw_exception(handleOOM(oom, L"deleteDocuments(Term)")); } } - + void IndexWriter::deleteDocuments(Collection terms) { ensureOpen(); @@ -1041,7 +1041,7 @@ namespace Lucene boost::throw_exception(handleOOM(oom, L"deleteDocuments(VectorTerm)")); } } - + void IndexWriter::deleteDocuments(QueryPtr query) { ensureOpen(); @@ -1049,7 +1049,7 @@ namespace Lucene if (doFlush) flush(true, false, false); } - + void IndexWriter::deleteDocuments(Collection queries) { ensureOpen(); @@ -1057,13 +1057,13 @@ namespace Lucene if (doFlush) flush(true, false, false); } - + void IndexWriter::updateDocument(TermPtr term, DocumentPtr doc) { ensureOpen(); updateDocument(term, doc, getAnalyzer()); } - + void IndexWriter::updateDocument(TermPtr term, DocumentPtr doc, AnalyzerPtr analyzer) { ensureOpen(); @@ -1085,7 +1085,7 @@ namespace Lucene { if (infoStream) message(L"hit exception updating document"); - + { SyncLock syncLock(this); // If docWriter has some aborted files that were never incref'd, then we clean them up here @@ -1106,102 +1106,102 @@ namespace Lucene boost::throw_exception(handleOOM(oom, L"updateDocument")); } } - + int32_t IndexWriter::getSegmentCount() { SyncLock syncLock(this); return segmentInfos->size(); } - + int32_t IndexWriter::getNumBufferedDocuments() { SyncLock syncLock(this); return docWriter->getNumDocsInRAM(); } - + int32_t IndexWriter::getDocCount(int32_t i) { SyncLock syncLock(this); return (i >= 0 && i < segmentInfos->size()) ? segmentInfos->info(i)->docCount : -1; } - + int32_t IndexWriter::getFlushCount() { SyncLock syncLock(this); return flushCount; } - + int32_t IndexWriter::getFlushDeletesCount() { SyncLock syncLock(this); return flushDeletesCount; } - + String IndexWriter::newSegmentName() { // Cannot synchronize on IndexWriter because that causes deadlock SyncLock segmentLock(segmentInfos); - - // Important to increment changeCount so that the segmentInfos is written on close. - // Otherwise we could close, re-open and re-return the same segment name that was + + // Important to increment changeCount so that the segmentInfos is written on close. + // Otherwise we could close, re-open and re-return the same segment name that was // previously returned which can cause problems at least with ConcurrentMergeScheduler. ++changeCount; return L"_" + StringUtils::toString(segmentInfos->counter++, StringUtils::CHARACTER_MAX_RADIX); } - + void IndexWriter::optimize() { optimize(true); } - + void IndexWriter::optimize(int32_t maxNumSegments) { optimize(maxNumSegments, true); } - + void IndexWriter::optimize(bool doWait) { optimize(1, doWait); } - + void IndexWriter::optimize(int32_t maxNumSegments, bool doWait) { ensureOpen(); - + if (maxNumSegments < 1) boost::throw_exception(IllegalArgumentException(L"maxNumSegments must be >= 1; got " + StringUtils::toString(maxNumSegments))); - + if (infoStream) message(L"optimize: index now " + segString()); - + flush(true, false, true); - + { SyncLock syncLock(this); - + resetMergeExceptions(); segmentsToOptimize.clear(); optimizeMaxNumSegments = maxNumSegments; int32_t numSegments = segmentInfos->size(); for (int32_t i = 0; i < numSegments; ++i) segmentsToOptimize.add(segmentInfos->info(i)); - + // Now mark all pending & running merges as optimize merge for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) { (*merge)->optimize = true; (*merge)->maxNumSegmentsOptimize = maxNumSegments; } - + for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) { (*merge)->optimize = true; (*merge)->maxNumSegmentsOptimize = maxNumSegments; } } - + maybeMerge(maxNumSegments, true); - + if (doWait) { { @@ -1210,7 +1210,7 @@ namespace Lucene { if (hitOOM) boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete optimize")); - + if (!mergeExceptions.empty()) { // Forward any exceptions in background merge threads to the current thread @@ -1224,60 +1224,60 @@ namespace Lucene } } } - + if (optimizeMergesPending()) IndexWriter::doWait(); else break; } } - - // If close is called while we are still running, throw an exception so the calling thread will know the + + // If close is called while we are still running, throw an exception so the calling thread will know the // optimize did not complete ensureOpen(); } - - // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background + + // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background // threads accomplish the optimization } - + bool IndexWriter::optimizeMergesPending() { SyncLock syncLock(this); - + for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) { if ((*merge)->optimize) return true; } - + for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) { if ((*merge)->optimize) return true; } - + return false; } - + void IndexWriter::expungeDeletes(bool doWait) { ensureOpen(); - + if (infoStream) message(L"expungeDeletes: index now " + segString()); - + MergeSpecificationPtr spec; - + { SyncLock syncLock(this); spec = mergePolicy->findMergesToExpungeDeletes(segmentInfos); for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) registerMerge(*merge); } - + mergeScheduler->merge(shared_from_this()); - + if (doWait) { { @@ -1287,7 +1287,7 @@ namespace Lucene { if (hitOOM) boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete expungeDeletes")); - + // Check each merge that MergePolicy asked us to do, to see if any of them are still running and // if any of them have hit an exception. running = false; @@ -1299,57 +1299,57 @@ namespace Lucene if (!err.isNull()) boost::throw_exception(IOException(L"background merge hit exception: " + (*merge)->segString(directory))); } - + // If any of our merges are still running, wait if (running) IndexWriter::doWait(); } } } - - // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background + + // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background // threads accomplish the optimization } - + void IndexWriter::expungeDeletes() { expungeDeletes(true); } - + void IndexWriter::maybeMerge() { maybeMerge(false); } - + void IndexWriter::maybeMerge(bool optimize) { maybeMerge(1, optimize); } - + void IndexWriter::maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize) { updatePendingMerges(maxNumSegmentsOptimize, optimize); mergeScheduler->merge(shared_from_this()); } - + void IndexWriter::updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize) { SyncLock syncLock(this); BOOST_ASSERT(!optimize || maxNumSegmentsOptimize > 0); - + if (stopMerges) return; - + // Do not start new merges if we've hit std::bad_alloc if (hitOOM) return; - + MergeSpecificationPtr spec; - + if (optimize) { spec = mergePolicy->findMergesForOptimize(segmentInfos, maxNumSegmentsOptimize, segmentsToOptimize); - + if (spec) { for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) @@ -1361,14 +1361,14 @@ namespace Lucene } else spec = mergePolicy->findMerges(segmentInfos); - + if (spec) { for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) registerMerge(*merge); } } - + OneMergePtr IndexWriter::getNextMerge() { SyncLock syncLock(this); @@ -1382,7 +1382,7 @@ namespace Lucene return merge; } } - + OneMergePtr IndexWriter::getNextExternalMerge() { SyncLock syncLock(this); @@ -1402,11 +1402,11 @@ namespace Lucene } } } - + // All existing merges do not involve external segments return OneMergePtr(); } - + void IndexWriter::startTransaction(bool haveReadLock) { SyncLock syncLock(this); @@ -1416,148 +1416,148 @@ namespace Lucene { if (infoStream) message(L"now start transaction"); - + BOOST_ASSERT(docWriter->getNumBufferedDeleteTerms() == 0); // calling startTransaction with buffered delete terms not supported BOOST_ASSERT(docWriter->getNumDocsInRAM() == 0); // calling startTransaction with buffered documents not supported - + ensureOpen(); - + // If a transaction is trying to roll back (because addIndexes hit an exception) then wait here until that's done while (stopMerges) doWait(); - + success = true; } catch (LuceneException& e) { finally = e; } - + // Release the write lock if our caller held it, on hitting an exception if (!success && haveReadLock) releaseRead(); finally.throwException(); - + if (haveReadLock) upgradeReadToWrite(); else acquireWrite(); - + success = false; - + try { localRollbackSegmentInfos = boost::dynamic_pointer_cast(segmentInfos->clone()); - + BOOST_ASSERT(!hasExternalSegments()); - + localFlushedDocCount = docWriter->getFlushedDocCount(); - + // We must "protect" our files at this point from deletion in case we need to rollback deleter->incRef(segmentInfos, false); - + success = true; } catch (LuceneException& e) { finally = e; } - + if (!success) finishAddIndexes(); finally.throwException(); } - + void IndexWriter::rollbackTransaction() { SyncLock syncLock(this); - + if (infoStream) message(L"now rollback transaction"); - + if (docWriter) docWriter->setFlushedDocCount(localFlushedDocCount); - - // Must finish merges before rolling back segmentInfos so merges don't hit exceptions on trying to commit + + // Must finish merges before rolling back segmentInfos so merges don't hit exceptions on trying to commit // themselves, don't get files deleted out from under them, etc. finishMerges(false); - - // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next + + // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next // attempt to commit using this instance of IndexWriter will always write to a new generation ("write once"). segmentInfos->clear(); segmentInfos->addAll(localRollbackSegmentInfos); localRollbackSegmentInfos.reset(); - - // This must come after we rollback segmentInfos, so that if a commit() kicks off it does not see the + + // This must come after we rollback segmentInfos, so that if a commit() kicks off it does not see the // segmentInfos with external segments. finishAddIndexes(); - + // Ask deleter to locate unreferenced files we had created & remove them deleter->checkpoint(segmentInfos, false); - + // Remove the incRef we did in startTransaction deleter->decRef(segmentInfos); - - // Also ask deleter to remove any newly created files that were never incref'd; this "garbage" is created + + // Also ask deleter to remove any newly created files that were never incref'd; this "garbage" is created // when a merge kicks off but aborts part way through before it had a chance to incRef the files it had // partially created deleter->refresh(); - + notifyAll(); - + BOOST_ASSERT(!hasExternalSegments()); } - + void IndexWriter::commitTransaction() { SyncLock syncLock(this); - + if (infoStream) message(L"now commit transaction"); - + // Give deleter a chance to remove files now checkpoint(); - + // Remove the incRef we did in startTransaction. deleter->decRef(localRollbackSegmentInfos); - + localRollbackSegmentInfos.reset(); - + BOOST_ASSERT(!hasExternalSegments()); - + finishAddIndexes(); } - + void IndexWriter::rollback() { ensureOpen(); - + // Ensure that only one thread actually gets to do the closing if (shouldClose()) rollbackInternal(); } - + void IndexWriter::rollbackInternal() { bool success = false; - + if (infoStream) message(L"rollback"); - + docWriter->pauseAllThreads(); LuceneException finally; try { finishMerges(false); - - // Must pre-close these two, in case they increment changeCount so that we can then set it to false before + + // Must pre-close these two, in case they increment changeCount so that we can then set it to false before // calling closeInternal mergePolicy->close(); mergeScheduler->close(); { SyncLock syncLock(this); - + if (pendingCommit) { pendingCommit->rollbackCommit(directory); @@ -1566,28 +1566,28 @@ namespace Lucene notifyAll(); } - // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next + // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next // attempt to commit using this instance of IndexWriter will always write to a new generation ("write once"). segmentInfos->clear(); segmentInfos->addAll(rollbackSegmentInfos); - + BOOST_ASSERT(!hasExternalSegments()); - + docWriter->abort(); - + bool test = testPoint(L"rollback before checkpoint"); BOOST_ASSERT(test); - + // Ask deleter to locate unreferenced files & remove them deleter->checkpoint(segmentInfos, false); deleter->refresh(); } - + // Don't bother saving any changes in our segmentInfos readerPool->clear(SegmentInfosPtr()); - + lastCommitChangeCount = changeCount; - + success = true; } catch (std::bad_alloc& oom) @@ -1600,7 +1600,7 @@ namespace Lucene } { SyncLock syncLock(this); - + if (!success) { docWriter->resumeAllThreads(); @@ -1611,10 +1611,10 @@ namespace Lucene } } finally.throwException(); - + closeInternal(false); } - + void IndexWriter::deleteAll() { SyncLock syncLock(this); @@ -1625,24 +1625,24 @@ namespace Lucene { // Abort any running merges finishMerges(false); - + // Remove any buffered docs docWriter->abort(); docWriter->setFlushedDocCount(0); - + // Remove all segments segmentInfos->clear(); - + // Ask deleter to locate unreferenced files & remove them deleter->checkpoint(segmentInfos, false); deleter->refresh(); - + // Don't bother saving any changes in our segmentInfos readerPool->clear(SegmentInfosPtr()); - + // Mark that the index has changed ++changeCount; - + success = true; } catch (std::bad_alloc& oom) @@ -1653,21 +1653,21 @@ namespace Lucene { finally = e; } - + docWriter->resumeAllThreads(); if (!success && infoStream) message(L"hit exception during deleteAll"); - + finally.throwException(); } - + void IndexWriter::finishMerges(bool waitForMerges) { SyncLock syncLock(this); if (!waitForMerges) { stopMerges = true; - + // Abort all pending and running merges for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) { @@ -1677,21 +1677,21 @@ namespace Lucene mergeFinish(*merge); } pendingMerges.clear(); - + for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) { if (infoStream) message(L"now abort running merge " + (*merge)->segString(directory)); (*merge)->abort(); } - - // Ensure any running addIndexes finishes. It's fine if a new one attempts to start because its merges + + // Ensure any running addIndexes finishes. It's fine if a new one attempts to start because its merges // will quickly see the stopMerges == true and abort. acquireRead(); releaseRead(); - - // These merges periodically check whether they have been aborted, and stop if so. We wait here to make - // sure they all stop. It should not take very long because the merge threads periodically check if they + + // These merges periodically check whether they have been aborted, and stop if so. We wait here to make + // sure they all stop. It should not take very long because the merge threads periodically check if they // are aborted. while (!runningMerges.empty()) { @@ -1699,54 +1699,54 @@ namespace Lucene message(L"now wait for " + StringUtils::toString(runningMerges.size()) + L" running merge to abort"); doWait(); } - + stopMerges = false; notifyAll(); - + BOOST_ASSERT(mergingSegments.empty()); - + if (infoStream) message(L"all running merges have aborted"); } else { - // waitForMerges() will ensure any running addIndexes finishes. It's fine if a new one attempts to start - // because from our caller above the call will see that we are in the process of closing, and will throw + // waitForMerges() will ensure any running addIndexes finishes. It's fine if a new one attempts to start + // because from our caller above the call will see that we are in the process of closing, and will throw // an AlreadyClosed exception. IndexWriter::waitForMerges(); } } - + void IndexWriter::waitForMerges() { SyncLock syncLock(this); // Ensure any running addIndexes finishes. acquireRead(); releaseRead(); - + while (!pendingMerges.empty() || !runningMerges.empty()) doWait(); - + // sanity check BOOST_ASSERT(mergingSegments.empty()); } - + void IndexWriter::checkpoint() { SyncLock syncLock(this); ++changeCount; deleter->checkpoint(segmentInfos, false); } - + void IndexWriter::finishAddIndexes() { releaseWrite(); } - + void IndexWriter::blockAddIndexes(bool includePendingClose) { acquireRead(); - + bool success = false; LuceneException finally; try @@ -1759,28 +1759,28 @@ namespace Lucene { finally = e; } - + if (!success) releaseRead(); finally.throwException(); } - + void IndexWriter::resumeAddIndexes() { releaseRead(); } - + void IndexWriter::resetMergeExceptions() { SyncLock syncLock(this); mergeExceptions.clear(); ++mergeGen; } - + void IndexWriter::noDupDirs(Collection dirs) { Collection dups(Collection::newInstance()); - + for (Collection::iterator dir = dirs.begin(); dir != dirs.end(); ++dir) { for (Collection::iterator dup = dups.begin(); dup != dups.end(); ++dup) @@ -1793,35 +1793,35 @@ namespace Lucene dups.add(*dir); } } - + void IndexWriter::addIndexesNoOptimize(Collection dirs) { ensureOpen(); - + noDupDirs(dirs); - + // Do not allow add docs or deletes while we are running docWriter->pauseAllThreads(); - + LuceneException finally; try { if (infoStream) message(L"flush at addIndexesNoOptimize"); flush(true, false, true); - + bool success = false; - + startTransaction(false); - + try { int32_t docCount = 0; - + { SyncLock syncLock(this); ensureOpen(); - + for (Collection::iterator dir = dirs.begin(); dir != dirs.end(); ++dir) { if (directory == *dir) @@ -1829,10 +1829,10 @@ namespace Lucene // cannot add this index: segments may be deleted in merge before added boost::throw_exception(IllegalArgumentException(L"Cannot add this index to itself")); } - + SegmentInfosPtr sis(newLucene()); // read infos from dir sis->read(*dir); - + for (int32_t j = 0; j < sis->size(); ++j) { SegmentInfoPtr info(sis->info(j)); @@ -1842,16 +1842,16 @@ namespace Lucene } } } - + // Notify DocumentsWriter that the flushed count just increased docWriter->updateFlushedDocCount(docCount); - + maybeMerge(); - + ensureOpen(); - - // If after merging there remain segments in the index that are in a different directory, just copy these - // over into our index. This is necessary (before finishing the transaction) to avoid leaving the index + + // If after merging there remain segments in the index that are in a different directory, just copy these + // over into our index. This is necessary (before finishing the transaction) to avoid leaving the index // in an unusable (inconsistent) state. resolveExternalSegments(); @@ -1863,7 +1863,7 @@ namespace Lucene { finally = e; } - + if (success) commitTransaction(); else @@ -1881,29 +1881,29 @@ namespace Lucene docWriter->resumeAllThreads(); finally.throwException(); } - + bool IndexWriter::hasExternalSegments() { return segmentInfos->hasExternalSegments(directory); } - + void IndexWriter::resolveExternalSegments() { bool any = false; bool done = false; - + while (!done) { SegmentInfoPtr info; OneMergePtr merge; - + { SyncLock syncLock(this); if (stopMerges) boost::throw_exception(MergeAbortedException(L"rollback() was called or addIndexes* hit an unhandled exception")); - + int32_t numSegments = segmentInfos->size(); - + done = true; for (int32_t i = 0; i < numSegments; ++i) { @@ -1912,13 +1912,13 @@ namespace Lucene { done = false; OneMergePtr newMerge(newLucene(segmentInfos->range(i, i + 1), boost::dynamic_pointer_cast(mergePolicy) && getUseCompoundFile())); - + // Returns true if no running merge conflicts with this one (and, records this merge as // pending), ie, this segment is not currently being merged if (registerMerge(newMerge)) { merge = newMerge; - + // If this segment is not currently being merged, then advance it to running & run // the merge ourself (below) pendingMerges.remove(merge); @@ -1927,7 +1927,7 @@ namespace Lucene } } } - + if (!done && !merge) { // We are not yet done (external segments still exist in segmentInfos), yet, all such segments @@ -1935,7 +1935,7 @@ namespace Lucene // that involves external segments merge = getNextExternalMerge(); } - + if (!done && !merge) { // We are not yet done, and, all external segments fall under merges that the merge scheduler is @@ -1943,42 +1943,42 @@ namespace Lucene doWait(); } } - + if (merge) { any = true; IndexWriter::merge(merge); } } - + if (any) { // Sometimes, on copying an external segment over, more merges may become necessary mergeScheduler->merge(shared_from_this()); } } - + void IndexWriter::addIndexes(Collection readers) { ensureOpen(); - + // Do not allow add docs or deletes while we are running docWriter->pauseAllThreads(); - - // We must pre-acquire a read lock here (and upgrade to write lock in startTransaction below) so that no - // other addIndexes is allowed to start up after we have flushed & optimized but before we then start our + + // We must pre-acquire a read lock here (and upgrade to write lock in startTransaction below) so that no + // other addIndexes is allowed to start up after we have flushed & optimized but before we then start our // transaction. This is because the merging below requires that only one segment is present in the index acquireRead(); - + LuceneException finally; try { SegmentInfoPtr info; String mergedName; SegmentMergerPtr merger; - + bool success = false; - + try { flush(true, false, true); @@ -1989,40 +1989,40 @@ namespace Lucene { finally = e; } - + // Take care to release the read lock if we hit an exception before starting the transaction if (!success) releaseRead(); finally.throwException(); - + // true means we already have a read lock; if this call hits an exception it will release the write lock startTransaction(true); - + try { mergedName = newSegmentName(); merger = newLucene(shared_from_this(), mergedName, OneMergePtr()); - + SegmentReaderPtr sReader; - + { SyncLock syncLock(this); if (segmentInfos->size() == 1) // add existing index, if any sReader = readerPool->get(segmentInfos->info(0), true, BufferedIndexInput::BUFFER_SIZE, -1); } - + success = false; - + try { if (sReader) merger->add(sReader); - + for (Collection::iterator i = readers.begin(); i != readers.end(); ++i) merger->add(*i); - + int32_t docCount = merger->merge(); // merge 'em - + { SyncLock syncLock(this); segmentInfos->clear(); // pop old infos & add new @@ -2030,17 +2030,17 @@ namespace Lucene setDiagnostics(info, L"addIndexes(Collection)"); segmentInfos->add(info); } - + // Notify DocumentsWriter that the flushed count just increased docWriter->updateFlushedDocCount(docCount); - + success = true; } catch (LuceneException& e) { finally = e; } - + if (sReader) readerPool->release(sReader); } @@ -2048,7 +2048,7 @@ namespace Lucene { finally = e; } - + if (!success) { if (infoStream) @@ -2057,16 +2057,16 @@ namespace Lucene } else commitTransaction(); - + finally.throwException(); - + if (boost::dynamic_pointer_cast(mergePolicy) && getUseCompoundFile()) { HashSet files; - + { SyncLock syncLock(this); - // Must incRef our files so that if another thread is running merge/optimize, it doesn't delete our + // Must incRef our files so that if another thread is running merge/optimize, it doesn't delete our // segment's files before we have a change to finish making the compound file. if (segmentInfos->contains(info)) { @@ -2074,34 +2074,34 @@ namespace Lucene deleter->incRef(files); } } - + if (files) { success = false; - + startTransaction(false); - + try { merger->createCompoundFile(mergedName + L".cfs"); - + { SyncLock syncLock(this); info->setUseCompoundFile(true); } - + success = true; } catch (LuceneException& e) { finally = e; } - + { SyncLock syncLock(this); deleter->decRef(files); } - + if (!success) { if (infoStream) @@ -2125,77 +2125,77 @@ namespace Lucene docWriter->resumeAllThreads(); finally.throwException(); } - + void IndexWriter::doAfterFlush() { // override } - + void IndexWriter::doBeforeFlush() { // override } - + void IndexWriter::prepareCommit() { ensureOpen(); prepareCommit(MapStringString()); } - + void IndexWriter::prepareCommit(MapStringString commitUserData) { if (hitOOM) boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot commit")); - + if (pendingCommit) boost::throw_exception(IllegalStateException(L"prepareCommit was already called with no corresponding call to commit")); if (infoStream) message(L"prepareCommit: flush"); - + flush(true, true, true); - + startCommit(0, commitUserData); } - + void IndexWriter::commit(int64_t sizeInBytes) { SyncLock messageLock(commitLock); startCommit(sizeInBytes, MapStringString()); finishCommit(); } - + void IndexWriter::commit() { commit(MapStringString()); } - + void IndexWriter::commit(MapStringString commitUserData) { ensureOpen(); - + if (infoStream) message(L"commit: start"); - + { SyncLock messageLock(commitLock); - + if (infoStream) message(L"commit: enter lock"); - + if (!pendingCommit) { if (infoStream) message(L"commit: now prepare"); prepareCommit(commitUserData); } - else if (infoStream) + else if (infoStream) message(L"commit: already prepared"); - + finishCommit(); } } - + void IndexWriter::finishCommit() { SyncLock syncLock(this); @@ -2219,19 +2219,19 @@ namespace Lucene { finally = e; } - + deleter->decRef(pendingCommit); pendingCommit.reset(); notifyAll(); finally.throwException(); } - else if (infoStream) + else if (infoStream) message(L"commit: pendingCommit == null; skip"); - + if (infoStream) message(L"commit: done"); } - + void IndexWriter::flush(bool triggerMerge, bool flushDocStores, bool flushDeletes) { // We can be called during close, when closing = true, so we must pass false to ensureOpen @@ -2239,7 +2239,7 @@ namespace Lucene if (doFlush(flushDocStores, flushDeletes) && triggerMerge) maybeMerge(); } - + bool IndexWriter::doFlush(bool flushDocStores, bool flushDeletes) { TestScope testScope(L"IndexWriter", L"doFlush"); @@ -2268,58 +2268,58 @@ namespace Lucene finally.throwException(); return success; } - + bool IndexWriter::doFlushInternal(bool flushDocStores, bool flushDeletes) { SyncLock syncLock(this); if (hitOOM) boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot flush")); - + ensureOpen(false); - + BOOST_ASSERT(testPoint(L"startDoFlush")); - + doBeforeFlush(); - + ++flushCount; - + // If we are flushing because too many deletes accumulated, then we should apply the deletes to free RAM if (docWriter->doApplyDeletes()) flushDeletes = true; - - // Make sure no threads are actively adding a document. Returns true if docWriter is currently aborting, in + + // Make sure no threads are actively adding a document. Returns true if docWriter is currently aborting, in // which case we skip flushing this segment if (infoStream) - message(L"flush: now pause all indexing threads"); + message(L"flush: now pause all indexing threads"); if (docWriter->pauseAllThreads()) { docWriter->resumeAllThreads(); return false; } - + bool flushDocs = false; - + LuceneException finally; try { SegmentInfoPtr newSegment; - + int32_t numDocs = docWriter->getNumDocsInRAM(); - + // Always flush docs if there are any flushDocs = (numDocs > 0); - + String docStoreSegment(docWriter->getDocStoreSegment()); - + BOOST_ASSERT(!docStoreSegment.empty() || numDocs == 0); - + if (docStoreSegment.empty()) flushDocStores = false; - + int32_t docStoreOffset = docWriter->getDocStoreOffset(); - + bool docStoreIsCompoundFile = false; - + if (infoStream) { message(L" flush: segment=" + docWriter->getSegment() + @@ -2332,29 +2332,29 @@ namespace Lucene L" numBufDelTerms=" + StringUtils::toString(docWriter->getNumBufferedDeleteTerms())); message(L" index before flush " + segString()); } - - // Check if the doc stores must be separately flushed because other segments, besides the one we are + + // Check if the doc stores must be separately flushed because other segments, besides the one we are // about to flush, reference it if (flushDocStores && (!flushDocs || docWriter->getSegment() != docWriter->getDocStoreSegment())) { // We must separately flush the doc store if (infoStream) message(L" flush shared docStore segment " + docStoreSegment); - + docStoreIsCompoundFile = IndexWriter::flushDocStores(); flushDocStores = false; } - + String segment(docWriter->getSegment()); - + // If we are flushing docs, segment must not be null BOOST_ASSERT(!segment.empty() || !flushDocs); - + if (flushDocs) { bool success = false; int32_t flushedDocCount; - + try { flushedDocCount = docWriter->flush(flushDocStores); @@ -2366,19 +2366,19 @@ namespace Lucene { finally = e; } - + if (!success) { if (infoStream) message(L"hit exception flushing segment " + segment); deleter->refresh(segment); } - + finally.throwException(); - + if (docStoreOffset == 0 && flushDocStores) { - // This means we are flushing private doc stores with this segment, so it will not be shared + // This means we are flushing private doc stores with this segment, so it will not be shared // with other segments BOOST_ASSERT(!docStoreSegment.empty()); BOOST_ASSERT(docStoreSegment == segment); @@ -2386,20 +2386,20 @@ namespace Lucene docStoreIsCompoundFile = false; docStoreSegment.clear(); } - + // Create new SegmentInfo, but do not add to our segmentInfos until deletes are flushed successfully. newSegment = newLucene(segment, flushedDocCount, directory, false, true, docStoreOffset, docStoreSegment, docStoreIsCompoundFile, docWriter->hasProx()); setDiagnostics(newSegment, L"flush"); } - + docWriter->pushDeletes(); - + if (flushDocs) { segmentInfos->add(newSegment); checkpoint(); } - + if (flushDocs && mergePolicy->useCompoundFile(segmentInfos, newSegment)) { // Now build compound file @@ -2413,26 +2413,26 @@ namespace Lucene { finally = e; } - + if (!success) { if (infoStream) message(L"hit exception creating compound file for newly flushed segment " + segment); deleter->deleteFile(segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); } - + finally.throwException(); - + newSegment->setUseCompoundFile(true); checkpoint(); } - + if (flushDeletes) applyDeletes(); - + if (flushDocs) checkpoint(); - + doAfterFlush(); } catch (std::bad_alloc& oom) @@ -2446,36 +2446,36 @@ namespace Lucene } docWriter->resumeAllThreads(); finally.throwException(); - + return flushDocs; } - + int64_t IndexWriter::ramSizeInBytes() { ensureOpen(); return docWriter->getRAMUsed(); } - + int32_t IndexWriter::numRamDocs() { SyncLock syncLock(this); ensureOpen(); return docWriter->getNumDocsInRAM(); } - + int32_t IndexWriter::ensureContiguousMerge(OneMergePtr merge) { int32_t first = segmentInfos->find(merge->segments->info(0)); if (first == -1) boost::throw_exception(MergeException(L"Could not find segment " + merge->segments->info(0)->name + L" in current index " + segString())); - + int32_t numSegments = segmentInfos->size(); int32_t numSegmentsToMerge = merge->segments->size(); - + for (int32_t i = 0; i < numSegmentsToMerge; ++i) { SegmentInfoPtr info(merge->segments->info(i)); - + if (first + i >= numSegments || !segmentInfos->info(first + i)->equals(info)) { if (!segmentInfos->contains(info)) @@ -2484,24 +2484,24 @@ namespace Lucene boost::throw_exception(MergeException(L"MergePolicy selected non-contiguous segments to merge (" + merge->segString(directory) + L" vs " + segString() + L"), which IndexWriter (currently) cannot handle")); } } - + return first; } - + void IndexWriter::commitMergedDeletes(OneMergePtr merge, SegmentReaderPtr mergeReader) { SyncLock syncLock(this); BOOST_ASSERT(testPoint(L"startCommitMergeDeletes")); - + SegmentInfosPtr sourceSegments(merge->segments); - + if (infoStream) message(L"commitMergeDeletes " + merge->segString(directory)); - + // Carefully merge deletes that occurred after we started merging int32_t docUpto = 0; int32_t delCount = 0; - + for (int32_t i = 0; i < sourceSegments->size(); ++i) { SegmentInfoPtr info(sourceSegments->info(i)); @@ -2510,10 +2510,10 @@ namespace Lucene SegmentReaderPtr currentReader(merge->readers[i]); if (previousReader->hasDeletions()) { - // There were deletes on this segment when the merge started. The merge has collapsed away those deletes, - // but if new deletes were flushed since the merge started, we must now carefully keep any newly flushed + // There were deletes on this segment when the merge started. The merge has collapsed away those deletes, + // but if new deletes were flushed since the merge started, we must now carefully keep any newly flushed // deletes but mapping them to the new docIDs. - + if (currentReader->numDeletedDocs() > previousReader->numDeletedDocs()) { // This means this segment has had new deletes committed since we started the merge, so we must merge them @@ -2554,27 +2554,27 @@ namespace Lucene docUpto += info->docCount; } } - + BOOST_ASSERT(mergeReader->numDeletedDocs() == delCount); - + mergeReader->_hasChanges = (delCount > 0); } - + bool IndexWriter::commitMerge(OneMergePtr merge, SegmentMergerPtr merger, int32_t mergedDocCount, SegmentReaderPtr mergedReader) { SyncLock syncLock(this); BOOST_ASSERT(testPoint(L"startCommitMerge")); - + if (hitOOM) boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete merge")); - + if (infoStream) message(L"commitMerge: " + merge->segString(directory) + L" index=" + segString()); - + BOOST_ASSERT(merge->registerDone); - - // If merge was explicitly aborted, or, if rollback() or rollbackTransaction() had been called since our merge - // started (which results in an unqualified deleter.refresh() call that will remove any index file that current + + // If merge was explicitly aborted, or, if rollback() or rollbackTransaction() had been called since our merge + // started (which results in an unqualified deleter.refresh() call that will remove any index file that current // segments does not reference), we abort this merge if (merge->isAborted()) { @@ -2582,31 +2582,31 @@ namespace Lucene message(L"commitMerge: skipping merge " + merge->segString(directory) + L": it was aborted"); return false; } - + int32_t start = ensureContiguousMerge(merge); - + commitMergedDeletes(merge, mergedReader); docWriter->remapDeletes(segmentInfos, merger->getDocMaps(), merger->getDelCounts(), merge, mergedDocCount); - - // If the doc store we are using has been closed and is in now compound format (but wasn't when we started), + + // If the doc store we are using has been closed and is in now compound format (but wasn't when we started), // then we will switch to the compound format as well setMergeDocStoreIsCompoundFile(merge); - + merge->info->setHasProx(merger->hasProx()); - + segmentInfos->remove(start, start + merge->segments->size()); BOOST_ASSERT(!segmentInfos->contains(merge->info)); segmentInfos->add(start, merge->info); - + closeMergeReaders(merge, false); - + // Must note the change to segmentInfos so any commits in-flight don't lose it checkpoint(); - - // If the merged segments had pending changes, clear them so that they don't bother writing + + // If the merged segments had pending changes, clear them so that they don't bother writing // them to disk, updating SegmentInfo, etc. readerPool->clear(merge->segments); - + if (merge->optimize) { // cascade the optimize @@ -2614,21 +2614,21 @@ namespace Lucene } return true; } - + LuceneException IndexWriter::handleMergeException(const LuceneException& exc, OneMergePtr merge) { if (infoStream) message(L"handleMergeException: merge=" + merge->segString(directory) + L" exc=" + exc.getError()); - + // Set the exception on the merge, so if optimize() is waiting on us it sees the root cause exception merge->setException(exc); addMergeException(merge); - + switch (exc.getType()) { case LuceneException::MergeAborted: // We can ignore this exception (it happens when close(false) or rollback is called), unless the - // merge involves segments from external directories, in which case we must throw it so, for + // merge involves segments from external directories, in which case we must throw it so, for // example, the rollbackTransaction code in addIndexes* is executed. if (merge->isExternal) return exc; @@ -2641,11 +2641,11 @@ namespace Lucene } return LuceneException(); } - + void IndexWriter::merge(OneMergePtr merge) { bool success = false; - + try { LuceneException finally; @@ -2656,7 +2656,7 @@ namespace Lucene mergeInit(merge); if (infoStream) message(L"now merge\n merge=" + merge->segString(directory) + L"\n index=" + segString()); - + mergeMiddle(merge); mergeSuccess(merge); success = true; @@ -2665,21 +2665,21 @@ namespace Lucene { finally = handleMergeException(e, merge); } - + { SyncLock syncLock(this); mergeFinish(merge); - + if (!success) { if (infoStream) message(L"hit exception during merge"); - + if (merge->info && !segmentInfos->contains(merge->info)) deleter->refresh(merge->info->name); } - // This merge (and, generally, any change to the segments) may now enable + // This merge (and, generally, any change to the segments) may now enable // new merges, so we call merge policy & update pending merges. if (success && !merge->isAborted() && !closed && !closing) updatePendingMerges(merge->maxNumSegmentsOptimize, merge->optimize); @@ -2696,25 +2696,25 @@ namespace Lucene boost::throw_exception(handleOOM(oom, L"merge")); } } - + void IndexWriter::mergeSuccess(OneMergePtr merge) { // override } - + bool IndexWriter::registerMerge(OneMergePtr merge) { SyncLock syncLock(this); - + if (merge->registerDone) return true; - + if (stopMerges) { merge->abort(); boost::throw_exception(MergeAbortedException(L"merge is aborted: " + merge->segString(directory))); } - + int32_t count = merge->segments->size(); bool isExternal = false; for (int32_t i = 0; i < count; ++i) @@ -2732,27 +2732,27 @@ namespace Lucene merge->maxNumSegmentsOptimize = optimizeMaxNumSegments; } } - + ensureContiguousMerge(merge); - + pendingMerges.add(merge); - + if (infoStream) message(L"add merge to pendingMerges: " + merge->segString(directory) + L" [total " + StringUtils::toString(pendingMerges.size()) + L" pending]"); - + merge->mergeGen = mergeGen; merge->isExternal = isExternal; - - // OK it does not conflict; now record that this merge is running (while synchronized) + + // OK it does not conflict; now record that this merge is running (while synchronized) // to avoid race condition where two conflicting merges from different threads, start for (int32_t i = 0; i < count; ++i) mergingSegments.add(merge->segments->info(i)); - + // Merge is now registered merge->registerDone = true; return true; } - + void IndexWriter::mergeInit(OneMergePtr merge) { SyncLock syncLock(this); @@ -2767,61 +2767,61 @@ namespace Lucene { finally = e; } - + if (!success) mergeFinish(merge); finally.throwException(); } - + void IndexWriter::_mergeInit(OneMergePtr merge) { SyncLock syncLock(this); bool test = testPoint(L"startMergeInit"); BOOST_ASSERT(test); - + BOOST_ASSERT(merge->registerDone); BOOST_ASSERT(!merge->optimize || merge->maxNumSegmentsOptimize > 0); - + if (hitOOM) boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot merge")); - + if (merge->info) { // mergeInit already done return; } - + if (merge->isAborted()) return; - + applyDeletes(); - + SegmentInfosPtr sourceSegments(merge->segments); int32_t end = sourceSegments->size(); - + // Check whether this merge will allow us to skip merging the doc stores (stored field & vectors). // This is a very substantial optimization (saves tons of IO). DirectoryPtr lastDir(directory); String lastDocStoreSegment; int32_t next = -1; - + bool mergeDocStores = false; bool doFlushDocStore = false; String currentDocStoreSegment(docWriter->getDocStoreSegment()); - + // Test each segment to be merged: check if we need to flush/merge doc stores for (int32_t i = 0; i < end; ++i) { SegmentInfoPtr si(sourceSegments->info(i)); - + // If it has deletions we must merge the doc stores if (si->hasDeletions()) mergeDocStores = true; - + // If it has its own (private) doc stores we must merge the doc stores if (si->getDocStoreOffset() == -1) mergeDocStores = true; - + // If it has a different doc store segment than previous segments, we must merge the doc stores String docStoreSegment(si->getDocStoreSegment()); if (docStoreSegment.empty()) @@ -2830,7 +2830,7 @@ namespace Lucene lastDocStoreSegment = docStoreSegment; else if (lastDocStoreSegment != docStoreSegment) mergeDocStores = true; - + // Segments' docScoreOffsets must be in-order, contiguous. For the default merge policy now // this will always be the case but for an arbitrary merge policy this may not be the case if (next == -1) @@ -2839,7 +2839,7 @@ namespace Lucene mergeDocStores = true; else next = si->getDocStoreOffset() + si->docCount; - + // If the segment comes from a different directory we must merge if (lastDir != si->dir) mergeDocStores = true; @@ -2848,16 +2848,16 @@ namespace Lucene if (si->getDocStoreOffset() != -1 && !currentDocStoreSegment.empty() && si->getDocStoreSegment() == currentDocStoreSegment) doFlushDocStore = true; } - + // if a mergedSegmentWarmer is installed, we must merge the doc stores because we will open a full // SegmentReader on the merged segment if (!mergeDocStores && mergedSegmentWarmer && !currentDocStoreSegment.empty() && !lastDocStoreSegment.empty() && lastDocStoreSegment == currentDocStoreSegment) mergeDocStores = true; - + int32_t docStoreOffset; String docStoreSegment; bool docStoreIsCompoundFile; - + if (mergeDocStores) { docStoreOffset = -1; @@ -2871,37 +2871,37 @@ namespace Lucene docStoreSegment = si->getDocStoreSegment(); docStoreIsCompoundFile = si->getDocStoreIsCompoundFile(); } - + if (mergeDocStores && doFlushDocStore) { - // SegmentMerger intends to merge the doc stores (stored fields, vectors), and at + // SegmentMerger intends to merge the doc stores (stored fields, vectors), and at // least one of the segments to be merged refers to the currently live doc stores. if (infoStream) message(L"now flush at merge"); doFlush(true, false); } - + merge->mergeDocStores = mergeDocStores; - + // Bind a new segment name here so even with ConcurrentMergePolicy we keep deterministic segment names. merge->info = newLucene(newSegmentName(), 0, directory, false, true, docStoreOffset, docStoreSegment, docStoreIsCompoundFile, false); - + MapStringString details(MapStringString::newInstance()); details.put(L"optimize", StringUtils::toString(merge->optimize)); details.put(L"mergeFactor", StringUtils::toString(end)); details.put(L"mergeDocStores", StringUtils::toString(mergeDocStores)); setDiagnostics(merge->info, L"merge", details); - - // Also enroll the merged segment into mergingSegments; this prevents it from getting + + // Also enroll the merged segment into mergingSegments; this prevents it from getting // selected for a merge after our merge is done but while we are building the CFS mergingSegments.add(merge->info); } - + void IndexWriter::setDiagnostics(SegmentInfoPtr info, const String& source) { setDiagnostics(info, source, MapStringString()); } - + void IndexWriter::setDiagnostics(SegmentInfoPtr info, const String& source, MapStringString details) { MapStringString diagnostics(MapStringString::newInstance()); @@ -2912,13 +2912,13 @@ namespace Lucene diagnostics.putAll(details.begin(), details.end()); info->setDiagnostics(diagnostics); } - + void IndexWriter::mergeFinish(OneMergePtr merge) { SyncLock syncLock(this); // Optimize, addIndexes or finishMerges may be waiting on merges to finish. notifyAll(); - + // It's possible we are called twice, eg if there was an exception inside mergeInit if (merge->registerDone) { @@ -2926,18 +2926,18 @@ namespace Lucene int32_t end = sourceSegments->size(); for (int32_t i = 0; i < end; ++i) mergingSegments.remove(sourceSegments->info(i)); - + mergingSegments.remove(merge->info); merge->registerDone = false; } runningMerges.remove(merge); } - + void IndexWriter::setMergeDocStoreIsCompoundFile(OneMergePtr merge) { SyncLock syncLock(this); - + String mergeDocStoreSegment(merge->info->getDocStoreSegment()); if (!mergeDocStoreSegment.empty() && !merge->info->getDocStoreIsCompoundFile()) { @@ -2954,11 +2954,11 @@ namespace Lucene } } } - + void IndexWriter::closeMergeReaders(OneMergePtr merge, bool suppressExceptions) { SyncLock syncLock(this); - + int32_t numSegments = merge->segments->size(); if (suppressExceptions) { @@ -2976,7 +2976,7 @@ namespace Lucene } merge->readers[i].reset(); } - + if (merge->readersClone[i]) { try @@ -3001,7 +3001,7 @@ namespace Lucene readerPool->release(merge->readers[i], true); merge->readers[i].reset(); } - + if (merge->readersClone[i]) { merge->readersClone[i]->close(); @@ -3012,35 +3012,35 @@ namespace Lucene } } } - + int32_t IndexWriter::mergeMiddle(OneMergePtr merge) { merge->checkAborted(directory); - + String mergedName(merge->info->name); int32_t mergedDocCount = 0; - + SegmentInfosPtr sourceSegments(merge->segments); int32_t numSegments = sourceSegments->size(); - + if (infoStream) message(L"merging " + merge->segString(directory)); - + SegmentMergerPtr merger(newLucene(shared_from_this(), mergedName, merge)); - + merge->readers = Collection::newInstance(numSegments); merge->readersClone = Collection::newInstance(numSegments); - + bool mergeDocStores = false; - + String currentDocStoreSegment; { SyncLock syncLock(this); currentDocStoreSegment = docWriter->getDocStoreSegment(); } - + bool currentDSSMerged = false; - + LuceneException finally; // This is try/finally to make sure merger's readers are closed bool success = false; @@ -3050,11 +3050,11 @@ namespace Lucene for (int32_t i = 0; i < numSegments; ++i) { SegmentInfoPtr info(sourceSegments->info(i)); - + // Hold onto the "live" reader; we will use this to commit merged deletes merge->readers[i] = readerPool->get(info, merge->mergeDocStores, MERGE_READ_BUFFER_SIZE, -1); SegmentReaderPtr reader(merge->readers[i]); - + // We clone the segment readers because other deletes may come in while we're merging so we need readers that will not change merge->readersClone[i] = boost::dynamic_pointer_cast(reader->clone(true)); SegmentReaderPtr clone(merge->readersClone[i]); @@ -3068,17 +3068,17 @@ namespace Lucene totDocCount += clone->numDocs(); } - + if (infoStream) message(L"merge: total " + StringUtils::toString(totDocCount) + L" docs"); - + merge->checkAborted(directory); - + // If deletions have arrived and it has now become necessary to merge doc stores, go and open them if (mergeDocStores && !merge->mergeDocStores) { merge->mergeDocStores = true; - + { SyncLock syncLock(this); if (currentDSSMerged) @@ -3088,26 +3088,26 @@ namespace Lucene doFlush(true, false); } } - + for (Collection::iterator reader = merge->readersClone.begin(); reader != merge->readersClone.end(); ++reader) (*reader)->openDocStores(); - + // Clear DSS merge->info->setDocStore(-1, L"", false); } - + // This is where all the work happens merge->info->docCount = merger->merge(merge->mergeDocStores); mergedDocCount = merge->info->docCount; - + BOOST_ASSERT(mergedDocCount == totDocCount); - + if (merge->useCompoundFile) { success = false; - + String compoundFileName(IndexFileNames::segmentFileName(mergedName, IndexFileNames::COMPOUND_FILE_EXTENSION())); - + try { if (infoStream) @@ -3120,7 +3120,7 @@ namespace Lucene SyncLock syncLock(this); if (merge->isAborted()) { - // This can happen if rollback or close(false) is called - fall through to logic + // This can happen if rollback or close(false) is called - fall through to logic // below to remove the partially created CFS } else @@ -3130,7 +3130,7 @@ namespace Lucene { finally = handleMergeException(e, merge); } - + if (!success) { if (infoStream) @@ -3141,17 +3141,17 @@ namespace Lucene deleter->deleteNewFiles(merger->getMergedFiles()); } } - + finally.throwException(); - + success = false; - + { SyncLock syncLock(this); - + // delete new non cfs files directly: they were never registered with IFD deleter->deleteNewFiles(merger->getMergedFiles()); - + if (merge->isAborted()) { if (infoStream) @@ -3160,26 +3160,26 @@ namespace Lucene boost::throw_exception(TemporaryException()); } } - + merge->info->setUseCompoundFile(true); } - + int32_t termsIndexDivisor = -1; bool loadDocStores = false; - // if the merged segment warmer was not installed when this merge was started, causing us + // if the merged segment warmer was not installed when this merge was started, causing us // to not force the docStores to close, we can't warm it now bool canWarm = (merge->info->getDocStoreSegment().empty() || currentDocStoreSegment.empty() || merge->info->getDocStoreSegment() == currentDocStoreSegment); - + if (poolReaders && mergedSegmentWarmer && canWarm) { // Load terms index & doc stores so the segment warmer can run searches, load documents/term vectors termsIndexDivisor = readerTermsIndexDivisor; loadDocStores = true; } - + SegmentReaderPtr mergedReader(readerPool->get(merge->info, loadDocStores, BufferedIndexInput::BUFFER_SIZE, termsIndexDivisor)); - + try { if (poolReaders && mergedSegmentWarmer) @@ -3194,14 +3194,14 @@ namespace Lucene { finally = e; } - + { SyncLock syncLock(this); readerPool->release(mergedReader); } - + finally.throwException(); - + success = true; } catch (LuceneException& e) @@ -3212,16 +3212,16 @@ namespace Lucene // Readers are already closed in commitMerge if we didn't hit an exc if (!success) closeMergeReaders(merge, true); - + // has this merge been aborted? if (finally.getType() == LuceneException::Temporary) return 0; - + finally.throwException(); - + return mergedDocCount; } - + void IndexWriter::addMergeException(OneMergePtr merge) { SyncLock syncLock(this); @@ -3229,7 +3229,7 @@ namespace Lucene if (!mergeExceptions.contains(merge) && mergeGen == merge->mergeGen) mergeExceptions.add(merge); } - + bool IndexWriter::applyDeletes() { TestScope testScope(L"IndexWriter", L"applyDeletes"); @@ -3238,7 +3238,7 @@ namespace Lucene ++flushDeletesCount; bool success = false; bool changed = false; - + LuceneException finally; try { @@ -3249,29 +3249,29 @@ namespace Lucene { finally = e; } - + if (!success && infoStream) message(L"hit exception flushing deletes"); - + finally.throwException(); - + if (changed) checkpoint(); return changed; } - + int32_t IndexWriter::getBufferedDeleteTermsSize() { SyncLock syncLock(this); return docWriter->getBufferedDeleteTerms().size(); } - + int32_t IndexWriter::getNumBufferedDeleteTerms() { SyncLock syncLock(this); return docWriter->getNumBufferedDeleteTerms(); } - + SegmentInfoPtr IndexWriter::newestSegment() { return !segmentInfos->empty() ? segmentInfos->info(segmentInfos->size() - 1) : SegmentInfoPtr(); @@ -3281,7 +3281,7 @@ namespace Lucene { return segString(segmentInfos); } - + String IndexWriter::segString(SegmentInfosPtr infos) { SyncLock syncLock(this); @@ -3298,7 +3298,7 @@ namespace Lucene } return buffer.str(); } - + bool IndexWriter::startSync(const String& fileName, HashSet pending) { SyncLock syncedLock(&synced); @@ -3328,7 +3328,7 @@ namespace Lucene synced.add(fileName); synced.notifyAll(); } - + bool IndexWriter::waitForAllSynced(HashSet syncing) { SyncLock syncedLock(&synced); @@ -3351,8 +3351,8 @@ namespace Lucene void IndexWriter::doWait() { SyncLock syncLock(this); - // NOTE: the callers of this method should in theory be able to do simply wait(), but, as a defense against - // thread timing hazards where notifyAll() fails to be called, we wait for at most 1 second and then return + // NOTE: the callers of this method should in theory be able to do simply wait(), but, as a defense against + // thread timing hazards where notifyAll() fails to be called, we wait for at most 1 second and then return // so caller can check if wait conditions are satisfied wait(1000); } @@ -3360,34 +3360,34 @@ namespace Lucene void IndexWriter::startCommit(int64_t sizeInBytes, MapStringString commitUserData) { BOOST_ASSERT(testPoint(L"startStartCommit")); - + if (hitOOM) boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot commit")); - + try { if (infoStream) message(L"startCommit(): start sizeInBytes=" + StringUtils::toString(sizeInBytes)); - + SegmentInfosPtr toSync; int64_t myChangeCount = 0; LuceneException finally; - + { SyncLock syncLock(this); - - // Wait for any running addIndexes to complete first, then block any from running + + // Wait for any running addIndexes to complete first, then block any from running // until we've copied the segmentInfos we intend to sync blockAddIndexes(false); // On commit the segmentInfos must never reference a segment in another directory BOOST_ASSERT(!hasExternalSegments()); - + try { BOOST_ASSERT(lastCommitChangeCount <= changeCount); myChangeCount = changeCount; - + if (changeCount == lastCommitChangeCount) { if (infoStream) @@ -3395,20 +3395,20 @@ namespace Lucene boost::throw_exception(TemporaryException()); } - // First, we clone & incref the segmentInfos we intend to sync, then, without locking, we sync() each - // file referenced by toSync, in the background. Multiple threads can be doing this at once, if say + // First, we clone & incref the segmentInfos we intend to sync, then, without locking, we sync() each + // file referenced by toSync, in the background. Multiple threads can be doing this at once, if say // a large merge and a small merge finish at the same time - + if (infoStream) message(L"startCommit index=" + segString(segmentInfos) + L" changeCount=" + StringUtils::toString(changeCount)); - + readerPool->commit(); - + // It's possible another flush (that did not close the open do stores) snook in after the flush we - // just did, so we remove any tail segments referencing the open doc store from the SegmentInfos - // we are about to sync (the main SegmentInfos will keep them) + // just did, so we remove any tail segments referencing the open doc store from the SegmentInfos + // we are about to sync (the main SegmentInfos will keep them) toSync = boost::dynamic_pointer_cast(segmentInfos->clone()); - + String dss(docWriter->getDocStoreSegment()); if (!dss.empty()) { @@ -3421,18 +3421,18 @@ namespace Lucene ++changeCount; } } - + if (commitUserData) toSync->setUserData(commitUserData); - + deleter->incRef(toSync, false); - + HashSet files(toSync->files(directory, false)); for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { BOOST_ASSERT(directory->fileExists(*fileName)); - - // If this trips it means we are missing a call to .checkpoint somewhere, because by the + + // If this trips it means we are missing a call to .checkpoint somewhere, because by the // time we are called, deleter should know about every file referenced by the current head // segmentInfos BOOST_ASSERT(deleter->exists(*fileName)); @@ -3443,18 +3443,18 @@ namespace Lucene finally = e; } resumeAddIndexes(); - + // no changes pending? if (finally.getType() == LuceneException::Temporary) return; - + finally.throwException(); } - + BOOST_ASSERT(testPoint(L"midStartCommit")); - + bool setPending = false; - + try { // Loop until all files toSync references are sync'd @@ -3471,7 +3471,7 @@ namespace Lucene { // Because we incRef'd this commit point above, the file had better exist BOOST_ASSERT(directory->fileExists(*fileName)); - + if (infoStream) message(L"now sync " + *fileName); directory->sync(*fileName); @@ -3485,22 +3485,22 @@ namespace Lucene finally.throwException(); } } - - // All files that I require are either synced or being synced by other threads. If they are being - // synced, we must at this point block until they are done. If this returns false, that means an + + // All files that I require are either synced or being synced by other threads. If they are being + // synced, we must at this point block until they are done. If this returns false, that means an // error in another thread resulted in failing to actually sync one of our files, so we repeat if (waitForAllSynced(pending)) break; } - + BOOST_ASSERT(testPoint(L"midStartCommit2")); - + { SyncLock syncLock(this); - - // If someone saved a newer version of segments file since I first started syncing + + // If someone saved a newer version of segments file since I first started syncing // my version, I can safely skip saving myself since I've been superseded - + while (true) { if (myChangeCount <= lastCommitChangeCount) @@ -3514,11 +3514,11 @@ namespace Lucene // My turn to commit if (segmentInfos->getGeneration() > toSync->getGeneration()) toSync->updateGeneration(segmentInfos); - + bool success = false; try { - // Exception here means nothing is prepared (this method unwinds + // Exception here means nothing is prepared (this method unwinds // everything it did on an exception) try { @@ -3528,12 +3528,12 @@ namespace Lucene { finally = e; } - - // Have our master segmentInfos record the generations we just prepared. We do this on + + // Have our master segmentInfos record the generations we just prepared. We do this on // error or success so we don't double-write a segments_N file. segmentInfos->updateGeneration(toSync); finally.throwException(); - + BOOST_ASSERT(!pendingCommit); setPending = true; pendingCommit = toSync; @@ -3544,7 +3544,7 @@ namespace Lucene { finally = e; } - + if (!success && infoStream) message(L"hit exception committing segments file"); finally.throwException(); @@ -3557,7 +3557,7 @@ namespace Lucene } } } - + if (infoStream) message(L"done all syncs"); BOOST_ASSERT(testPoint(L"midStartCommitSuccess")); @@ -3566,7 +3566,7 @@ namespace Lucene { finally = e; } - + { SyncLock syncLock(this); if (!setPending) @@ -3580,12 +3580,12 @@ namespace Lucene } BOOST_ASSERT(testPoint(L"finishStartCommit")); } - + bool IndexWriter::isLocked(DirectoryPtr directory) { return directory->makeLock(WRITE_LOCK_NAME)->isLocked(); } - + void IndexWriter::unlock(DirectoryPtr directory) { directory->makeLock(IndexWriter::WRITE_LOCK_NAME)->release(); @@ -3595,12 +3595,12 @@ namespace Lucene { mergedSegmentWarmer = warmer; } - + IndexReaderWarmerPtr IndexWriter::getMergedSegmentWarmer() { return mergedSegmentWarmer; } - + LuceneException IndexWriter::handleOOM(const std::bad_alloc& oom, const String& location) { if (infoStream) @@ -3608,12 +3608,12 @@ namespace Lucene hitOOM = true; return OutOfMemoryError(); } - + bool IndexWriter::testPoint(const String& name) { return true; } - + bool IndexWriter::nrtIsCurrent(SegmentInfosPtr infos) { SyncLock syncLock(this); @@ -3630,13 +3630,13 @@ namespace Lucene else return !docWriter->anyChanges(); } - + bool IndexWriter::isClosed() { SyncLock syncLock(this); return closed; } - + ReaderPool::ReaderPool(IndexWriterPtr writer) { readerMap = MapSegmentInfoSegmentReader::newInstance(); @@ -3646,7 +3646,7 @@ namespace Lucene ReaderPool::~ReaderPool() { } - + void ReaderPool::clear(SegmentInfosPtr infos) { SyncLock syncLock(this); @@ -3665,7 +3665,7 @@ namespace Lucene } } } - + bool ReaderPool::infoIsLive(SegmentInfoPtr info) { SyncLock syncLock(this); @@ -3675,7 +3675,7 @@ namespace Lucene BOOST_ASSERT(indexWriter->segmentInfos->info(idx) == info); return true; } - + SegmentInfoPtr ReaderPool::mapToLive(SegmentInfoPtr info) { SyncLock syncLock(this); @@ -3685,30 +3685,30 @@ namespace Lucene info = indexWriter->segmentInfos->info(idx); return info; } - + void ReaderPool::release(SegmentReaderPtr sr) { release(sr, false); } - + void ReaderPool::release(SegmentReaderPtr sr, bool drop) { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); - + bool pooled = readerMap.contains(sr->getSegmentInfo()); - + BOOST_ASSERT(!pooled || readerMap.get(sr->getSegmentInfo()) == sr); - + // Drop caller's ref; for an external reader (not pooled), this decRef will close it sr->decRef(); - + if (pooled && (drop || (!indexWriter->poolReaders && sr->getRefCount() == 1))) { // We invoke deleter.checkpoint below, so we must be sync'd on IW if there are changes BOOST_ASSERT(!sr->_hasChanges || holdsLock()); - // Discard (don't save) changes when we are dropping the reader; this is used only on the + // Discard (don't save) changes when we are dropping the reader; this is used only on the // sub-readers after a successful merge. sr->_hasChanges = sr->_hasChanges && !drop; @@ -3722,62 +3722,62 @@ namespace Lucene if (hasChanges) { - // Must checkpoint with deleter, because this segment reader will have created new + // Must checkpoint with deleter, because this segment reader will have created new // _X_N.del file. indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); } } } - + void ReaderPool::close() { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); - + // We invoke deleter.checkpoint below, so we must be sync'd on IW BOOST_ASSERT(holdsLock()); - + for (MapSegmentInfoSegmentReader::iterator iter = readerMap.begin(); iter != readerMap.end(); ++iter) { if (iter->second->_hasChanges) { BOOST_ASSERT(infoIsLive(iter->second->getSegmentInfo())); iter->second->doCommit(MapStringString()); - - // Must checkpoint with deleter, because this segment reader will have created + + // Must checkpoint with deleter, because this segment reader will have created // new _X_N.del file. indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); } - + // NOTE: it is allowed that this decRef does not actually close the SR; this can happen when a // near real-time reader is kept open after the IndexWriter instance is closed iter->second->decRef(); } readerMap.clear(); } - + void ReaderPool::commit() { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); - + // We invoke deleter.checkpoint below, so we must be sync'd on IW BOOST_ASSERT(holdsLock()); - + for (MapSegmentInfoSegmentReader::iterator ent = readerMap.begin(); ent != readerMap.end(); ++ent) { if (ent->second->_hasChanges) { BOOST_ASSERT(infoIsLive(ent->second->getSegmentInfo())); ent->second->doCommit(MapStringString()); - - // Must checkpoint with deleter, because this segment reader will have created + + // Must checkpoint with deleter, because this segment reader will have created // new _X_N.del file. indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); } } } - + IndexReaderPtr ReaderPool::getReadOnlyClone(SegmentInfoPtr info, bool doOpenStores, int32_t termInfosIndexDivisor) { SyncLock syncLock(this); @@ -3796,19 +3796,19 @@ namespace Lucene finally.throwException(); return clone; } - + SegmentReaderPtr ReaderPool::get(SegmentInfoPtr info, bool doOpenStores) { return get(info, doOpenStores, BufferedIndexInput::BUFFER_SIZE, IndexWriterPtr(_indexWriter)->readerTermsIndexDivisor); } - + SegmentReaderPtr ReaderPool::get(SegmentInfoPtr info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor) { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); if (indexWriter->poolReaders) readBufferSize = BufferedIndexInput::BUFFER_SIZE; - + SegmentReaderPtr sr(readerMap.get(info)); if (!sr) { @@ -3832,7 +3832,7 @@ namespace Lucene sr->loadTermsIndex(termsIndexDivisor); } } - + // Return a ref to our caller if (info->dir == indexWriter->directory) { @@ -3841,7 +3841,7 @@ namespace Lucene } return sr; } - + SegmentReaderPtr ReaderPool::getIfExists(SegmentInfoPtr info) { SyncLock syncLock(this); @@ -3850,7 +3850,7 @@ namespace Lucene sr->incRef(); return sr; } - + IndexReaderWarmer::~IndexReaderWarmer() { } diff --git a/src/core/index/IntBlockPool.cpp b/src/core/index/IntBlockPool.cpp index 48d73e4f..45c76fed 100644 --- a/src/core/index/IntBlockPool.cpp +++ b/src/core/index/IntBlockPool.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,11 +19,11 @@ namespace Lucene this->_docWriter = docWriter; this->trackAllocations = trackAllocations; } - + IntBlockPool::~IntBlockPool() { } - + void IntBlockPool::reset() { if (bufferUpto != -1) @@ -33,7 +33,7 @@ namespace Lucene // Recycle all but the first buffer DocumentsWriterPtr(_docWriter)->recycleIntBlocks(buffers, 1, 1 + bufferUpto); } - + // Reuse first buffer bufferUpto = 0; intUpto = 0; @@ -41,7 +41,7 @@ namespace Lucene buffer = buffers[0]; } } - + void IntBlockPool::nextBuffer() { if (bufferUpto + 1 == buffers.size()) @@ -49,7 +49,7 @@ namespace Lucene buffer = DocumentsWriterPtr(_docWriter)->getIntBlock(trackAllocations); buffers[1 + bufferUpto] = buffer; ++bufferUpto; - + intUpto = 0; intOffset += DocumentsWriter::INT_BLOCK_SIZE; } diff --git a/src/core/index/InvertedDocConsumer.cpp b/src/core/index/InvertedDocConsumer.cpp index a8b17de2..6e140359 100644 --- a/src/core/index/InvertedDocConsumer.cpp +++ b/src/core/index/InvertedDocConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene InvertedDocConsumer::~InvertedDocConsumer() { } - + void InvertedDocConsumer::setFieldInfos(FieldInfosPtr fieldInfos) { this->fieldInfos = fieldInfos; diff --git a/src/core/index/InvertedDocConsumerPerField.cpp b/src/core/index/InvertedDocConsumerPerField.cpp index ec7a7082..e3aaea5e 100644 --- a/src/core/index/InvertedDocConsumerPerField.cpp +++ b/src/core/index/InvertedDocConsumerPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/InvertedDocConsumerPerThread.cpp b/src/core/index/InvertedDocConsumerPerThread.cpp index b82c213b..636cda1f 100644 --- a/src/core/index/InvertedDocConsumerPerThread.cpp +++ b/src/core/index/InvertedDocConsumerPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/InvertedDocEndConsumer.cpp b/src/core/index/InvertedDocEndConsumer.cpp index d574aa43..6df08e41 100644 --- a/src/core/index/InvertedDocEndConsumer.cpp +++ b/src/core/index/InvertedDocEndConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/InvertedDocEndConsumerPerField.cpp b/src/core/index/InvertedDocEndConsumerPerField.cpp index 616821a9..dc3f5c3a 100644 --- a/src/core/index/InvertedDocEndConsumerPerField.cpp +++ b/src/core/index/InvertedDocEndConsumerPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/InvertedDocEndConsumerPerThread.cpp b/src/core/index/InvertedDocEndConsumerPerThread.cpp index 349d66b9..b1cabe40 100644 --- a/src/core/index/InvertedDocEndConsumerPerThread.cpp +++ b/src/core/index/InvertedDocEndConsumerPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp b/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp index 0244abcb..19399047 100644 --- a/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp +++ b/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,13 +13,13 @@ namespace Lucene KeepOnlyLastCommitDeletionPolicy::~KeepOnlyLastCommitDeletionPolicy() { } - + void KeepOnlyLastCommitDeletionPolicy::onInit(Collection commits) { // Note that commits.size() should normally be 1 onCommit(commits); } - + void KeepOnlyLastCommitDeletionPolicy::onCommit(Collection commits) { // Note that commits.size() should normally be 2 (if not called by onInit above) diff --git a/src/core/index/LogByteSizeMergePolicy.cpp b/src/core/index/LogByteSizeMergePolicy.cpp index 4bcbfa69..8836e375 100644 --- a/src/core/index/LogByteSizeMergePolicy.cpp +++ b/src/core/index/LogByteSizeMergePolicy.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,40 +12,40 @@ namespace Lucene { /// Default minimum segment size. const double LogByteSizeMergePolicy::DEFAULT_MIN_MERGE_MB = 1.6; - + /// Default maximum segment size. A segment of this size or larger will never be merged. const double LogByteSizeMergePolicy::DEFAULT_MAX_MERGE_MB = DBL_MAX; - + LogByteSizeMergePolicy::LogByteSizeMergePolicy(IndexWriterPtr writer) : LogMergePolicy(writer) { minMergeSize = (int64_t)(DEFAULT_MIN_MERGE_MB * 1024 * 1024); maxMergeSize = DEFAULT_MAX_MERGE_MB == DBL_MAX ? std::numeric_limits::max() : (int64_t)(DEFAULT_MAX_MERGE_MB * 1024 * 1024); } - + LogByteSizeMergePolicy::~LogByteSizeMergePolicy() { } - + int64_t LogByteSizeMergePolicy::size(SegmentInfoPtr info) { return sizeBytes(info); } - + void LogByteSizeMergePolicy::setMaxMergeMB(double mb) { maxMergeSize = (int64_t)(mb * 1024 * 1024); } - + double LogByteSizeMergePolicy::getMaxMergeMB() { return ((double)maxMergeSize) / 1024 / 1024; } - + void LogByteSizeMergePolicy::setMinMergeMB(double mb) { minMergeSize = (int64_t)(mb * 1024 * 1024); } - + double LogByteSizeMergePolicy::getMinMergeMB() { return ((double)minMergeSize) / 1024 / 1024; diff --git a/src/core/index/LogDocMergePolicy.cpp b/src/core/index/LogDocMergePolicy.cpp index 8d70ece2..5fe6a0d5 100644 --- a/src/core/index/LogDocMergePolicy.cpp +++ b/src/core/index/LogDocMergePolicy.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,29 +11,29 @@ namespace Lucene { /// Default minimum segment size. @see setMinMergeDocs const int32_t LogDocMergePolicy::DEFAULT_MIN_MERGE_DOCS = 1000; - + LogDocMergePolicy::LogDocMergePolicy(IndexWriterPtr writer) : LogMergePolicy(writer) { minMergeSize = DEFAULT_MIN_MERGE_DOCS; - + // maxMergeSize is never used by LogDocMergePolicy; set it to LLONG_MAX to disable it maxMergeSize = std::numeric_limits::max(); } - + LogDocMergePolicy::~LogDocMergePolicy() { } - + int64_t LogDocMergePolicy::size(SegmentInfoPtr info) { return sizeDocs(info); } - + void LogDocMergePolicy::setMinMergeDocs(int32_t minMergeDocs) { minMergeSize = minMergeDocs; } - + int32_t LogDocMergePolicy::getMinMergeDocs() { return (int32_t)minMergeSize; diff --git a/src/core/index/LogMergePolicy.cpp b/src/core/index/LogMergePolicy.cpp index de532c84..510efd25 100644 --- a/src/core/index/LogMergePolicy.cpp +++ b/src/core/index/LogMergePolicy.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,16 +15,16 @@ namespace Lucene /// Defines the allowed range of log(size) for each level. A level is computed by taking the max segment /// log size, minus LEVEL_LOG_SPAN, and finding all segments falling within that range. const double LogMergePolicy::LEVEL_LOG_SPAN = 0.75; - + /// Default merge factor, which is how many segments are merged at a time. const int32_t LogMergePolicy::DEFAULT_MERGE_FACTOR = 10; - + /// Default maximum segment size. A segment of this size or larger will never be merged. const int32_t LogMergePolicy::DEFAULT_MAX_MERGE_DOCS = INT_MAX; - + /// Default noCFSRatio. If a merge's size is >= 10% of the index, then we disable compound file for it. const double LogMergePolicy::DEFAULT_NO_CFS_RATIO = 0.1; - + LogMergePolicy::LogMergePolicy(IndexWriterPtr writer) : MergePolicy(writer) { mergeFactor = DEFAULT_MERGE_FACTOR; @@ -36,86 +36,86 @@ namespace Lucene _useCompoundFile = true; _useCompoundDocStore = true; } - + LogMergePolicy::~LogMergePolicy() { } - + double LogMergePolicy::getNoCFSRatio() { return noCFSRatio; } - + void LogMergePolicy::setNoCFSRatio(double noCFSRatio) { if (noCFSRatio < 0.0 || noCFSRatio > 1.0) boost::throw_exception(IllegalArgumentException(L"noCFSRatio must be 0.0 to 1.0 inclusive; got " + StringUtils::toString(noCFSRatio))); this->noCFSRatio = noCFSRatio; } - + bool LogMergePolicy::verbose() { return (!_writer.expired() && IndexWriterPtr(_writer)->verbose()); } - + void LogMergePolicy::message(const String& message) { if (verbose()) IndexWriterPtr(_writer)->message(L"LMP: " + message); } - + int32_t LogMergePolicy::getMergeFactor() { return mergeFactor; } - + void LogMergePolicy::setMergeFactor(int32_t mergeFactor) { if (mergeFactor < 2) boost::throw_exception(IllegalArgumentException(L"mergeFactor cannot be less than 2")); this->mergeFactor = mergeFactor; } - + bool LogMergePolicy::getUseCompoundFile() { return _useCompoundFile; } - + void LogMergePolicy::setUseCompoundFile(bool useCompoundFile) { _useCompoundFile = useCompoundFile; } - + bool LogMergePolicy::useCompoundFile(SegmentInfosPtr segments, SegmentInfoPtr newSegment) { return _useCompoundFile; } - + bool LogMergePolicy::useCompoundDocStore(SegmentInfosPtr segments) { return _useCompoundDocStore; } - + void LogMergePolicy::setUseCompoundDocStore(bool useCompoundDocStore) { _useCompoundDocStore = useCompoundDocStore; } - + bool LogMergePolicy::getUseCompoundDocStore() { return _useCompoundDocStore; } - + void LogMergePolicy::setCalibrateSizeByDeletes(bool calibrateSizeByDeletes) { this->calibrateSizeByDeletes = calibrateSizeByDeletes; } - + bool LogMergePolicy::getCalibrateSizeByDeletes() { return calibrateSizeByDeletes; } - + void LogMergePolicy::close() { } @@ -130,7 +130,7 @@ namespace Lucene else return info->docCount; } - + int64_t LogMergePolicy::sizeBytes(SegmentInfoPtr info) { int64_t byteSize = info->sizeInBytes(); @@ -143,7 +143,7 @@ namespace Lucene else return byteSize; } - + bool LogMergePolicy::isOptimized(SegmentInfosPtr infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize) { int32_t numSegments = infos->size(); @@ -160,23 +160,23 @@ namespace Lucene } return (numToOptimize <= maxNumSegments && (numToOptimize != 1 || isOptimized(optimizeInfo))); } - + bool LogMergePolicy::isOptimized(SegmentInfoPtr info) { IndexWriterPtr writer(_writer); bool hasDeletions = (writer->numDeletedDocs(info) > 0); return (!hasDeletions && !info->hasSeparateNorms() && info->dir == writer->getDirectory() && (info->getUseCompoundFile() == _useCompoundFile || noCFSRatio < 1.0)); } - + MergeSpecificationPtr LogMergePolicy::findMergesForOptimize(SegmentInfosPtr segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) { MergeSpecificationPtr spec; - + BOOST_ASSERT(maxSegmentCount > 0); - + if (!isOptimized(segmentInfos, maxSegmentCount, segmentsToOptimize)) { - // Find the newest (rightmost) segment that needs to be optimized (other segments may have been + // Find the newest (rightmost) segment that needs to be optimized (other segments may have been // flushed since optimize started) int32_t last = segmentInfos->size(); while (last > 0) @@ -187,18 +187,18 @@ namespace Lucene break; } } - + if (last > 0) { spec = newLucene(); - + // First, enroll all "full" merges (size mergeFactor) to potentially be run concurrently while (last - maxSegmentCount + 1 >= mergeFactor) { spec->add(makeOneMerge(segmentInfos, segmentInfos->range(last - mergeFactor, last))); last -= mergeFactor; } - + // Only if there are no full merges pending do we add a final partial (< mergeFactor segments) merge if (spec->merges.empty()) { @@ -213,15 +213,15 @@ namespace Lucene // Take care to pick a partial merge that is least cost, but does not make the index too // lopsided. If we always just picked the partial tail then we could produce a highly // lopsided index over time - + // We must merge this many segments to leave maxNumSegments in the index (from when // optimize was first kicked off) int32_t finalMergeSize = last - maxSegmentCount + 1; - + // Consider all possible starting points int64_t bestSize = 0; int32_t bestStart = 0; - + for (int32_t i = 0; i < last - finalMergeSize + 1; ++i) { int64_t sumSize = 0; @@ -233,7 +233,7 @@ namespace Lucene bestSize = sumSize; } } - + spec->add(makeOneMerge(segmentInfos, segmentInfos->range(bestStart, bestStart + finalMergeSize))); } } @@ -243,16 +243,16 @@ namespace Lucene } else spec.reset(); - + return spec; } - + MergeSpecificationPtr LogMergePolicy::findMergesToExpungeDeletes(SegmentInfosPtr segmentInfos) { int32_t numSegments = segmentInfos->size(); - + message(L"findMergesToExpungeDeletes: " + StringUtils::toString(numSegments) + L" segments"); - + MergeSpecificationPtr spec(newLucene()); int32_t firstSegmentWithDeletions = -1; for (int32_t i = 0; i < numSegments; ++i) @@ -274,50 +274,50 @@ namespace Lucene } else if (firstSegmentWithDeletions != -1) { - // End of a sequence of segments with deletions, so merge those past segments even if + // End of a sequence of segments with deletions, so merge those past segments even if // it's fewer than mergeFactor segments message(L" add merge " + StringUtils::toString(firstSegmentWithDeletions) + L" to " + StringUtils::toString(i - 1) + L" inclusive"); spec->add(makeOneMerge(segmentInfos, segmentInfos->range(firstSegmentWithDeletions, i))); firstSegmentWithDeletions = -1; } } - + if (firstSegmentWithDeletions != -1) { message(L" add merge " + StringUtils::toString(firstSegmentWithDeletions) + L" to " + StringUtils::toString(numSegments - 1) + L" inclusive"); spec->add(makeOneMerge(segmentInfos, segmentInfos->range(firstSegmentWithDeletions, numSegments))); } - + return spec; } - + MergeSpecificationPtr LogMergePolicy::findMerges(SegmentInfosPtr segmentInfos) { int32_t numSegments = segmentInfos->size(); message(L"findMerges: " + StringUtils::toString(numSegments) + L" segments"); - + // Compute levels, which is just log (base mergeFactor) of the size of each segment Collection levels(Collection::newInstance(numSegments)); double norm = std::log((double)mergeFactor); - + for (int32_t i = 0; i < numSegments; ++i) { SegmentInfoPtr info(segmentInfos->info(i)); int64_t _size = size(info); - + // Floor tiny segments _size = std::max(_size, (int64_t)1); levels[i] = std::log((double)_size) / norm; } - + double levelFloor = minMergeSize <= 0 ? 0 : (std::log((double)minMergeSize) / norm); - - // Now, we quantize the log values into levels. The first level is any segment whose log + + // Now, we quantize the log values into levels. The first level is any segment whose log // size is within LEVEL_LOG_SPAN of the max size, or, who has such as segment "to the right". // Then, we find the max of all other segments and use that to define the next level segment, etc. - + MergeSpecificationPtr spec; - + int32_t start = 0; while (start < numSegments) { @@ -325,7 +325,7 @@ namespace Lucene double maxLevel = levels[start]; for (int32_t i = 1 + start; i < numSegments; ++i) maxLevel = std::max(maxLevel, levels[i]); - + // Now search backwards for the rightmost segment that falls into this level double levelBottom; if (maxLevel < levelFloor) @@ -333,12 +333,12 @@ namespace Lucene else { levelBottom = (double)(maxLevel - LEVEL_LOG_SPAN); - + // Force a boundary at the level floor if (levelBottom < levelFloor && maxLevel >= levelFloor) levelBottom = levelFloor; } - + int32_t upto = numSegments - 1; while (upto >= start) { @@ -347,7 +347,7 @@ namespace Lucene --upto; } message(L" level " + StringUtils::toString(levelBottom) + L" to " + StringUtils::toString(maxLevel) + L": " + StringUtils::toString(1 + upto - start) + L" segments"); - + // Finally, record all merges that are viable at this level int32_t end = start + mergeFactor; while (end <= 1 + upto) @@ -362,7 +362,7 @@ namespace Lucene break; } } - + if (!anyTooLarge) { if (!spec) @@ -372,17 +372,17 @@ namespace Lucene } else message(L" " + StringUtils::toString(start) + L" to " + StringUtils::toString(end) + L": contains segment over maxMergeSize or maxMergeDocs; skipping"); - + start = end; end = start + mergeFactor; } - + start = 1 + upto; } - + return spec; } - + OneMergePtr LogMergePolicy::makeOneMerge(SegmentInfosPtr infos, SegmentInfosPtr infosToMerge) { bool doCFS; @@ -410,12 +410,12 @@ namespace Lucene } return newLucene(infosToMerge, doCFS); } - + void LogMergePolicy::setMaxMergeDocs(int32_t maxMergeDocs) { this->maxMergeDocs = maxMergeDocs; } - + int32_t LogMergePolicy::getMaxMergeDocs() { return maxMergeDocs; diff --git a/src/core/index/MergeDocIDRemapper.cpp b/src/core/index/MergeDocIDRemapper.cpp index 41808ebe..cfaf5ba7 100644 --- a/src/core/index/MergeDocIDRemapper.cpp +++ b/src/core/index/MergeDocIDRemapper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,7 +26,7 @@ namespace Lucene minDocID += info->docCount; ++i; } - + int32_t numDocs = 0; for (int32_t j = 0; j < docMaps.size(); ++i, ++j) { @@ -34,10 +34,10 @@ namespace Lucene BOOST_ASSERT(infos->info(i)->equals(merge->segments->info(j))); } this->maxDocID = minDocID + numDocs; - + starts = Collection::newInstance(docMaps.size()); newStarts = Collection::newInstance(docMaps.size()); - + starts[0] = minDocID; newStarts[0] = minDocID; for (i = 1; i < docMaps.size(); ++i) @@ -47,19 +47,19 @@ namespace Lucene newStarts[i] = newStarts[i - 1] + lastDocCount - delCounts[i - 1]; } this->docShift = numDocs - mergedDocCount; - - // There are rare cases when docShift is 0. It happens if you try to delete a docID that's - // out of bounds, because the SegmentReader still allocates deletedDocs and pretends it has + + // There are rare cases when docShift is 0. It happens if you try to delete a docID that's + // out of bounds, because the SegmentReader still allocates deletedDocs and pretends it has // deletions ... so we can't make this assert here: BOOST_ASSERT(docShift > 0); - + // Make sure it all adds up BOOST_ASSERT(docShift == maxDocID - (newStarts[docMaps.size() - 1] + merge->segments->info(docMaps.size() - 1)->docCount - delCounts[docMaps.size() - 1])); } - + MergeDocIDRemapper::~MergeDocIDRemapper() { } - + int32_t MergeDocIDRemapper::remap(int32_t oldDocID) { if (oldDocID < minDocID) @@ -77,7 +77,7 @@ namespace Lucene // Binary search to locate this document & find its new docID Collection::iterator doc = std::upper_bound(starts.begin(), starts.begin() + docMaps.size(), oldDocID); int32_t docMap = std::distance(starts.begin(), doc) - 1; - + if (docMaps[docMap]) return newStarts[docMap] + docMaps[docMap][oldDocID - starts[docMap]]; else diff --git a/src/core/index/MergePolicy.cpp b/src/core/index/MergePolicy.cpp index 023b0985..30f6af48 100644 --- a/src/core/index/MergePolicy.cpp +++ b/src/core/index/MergePolicy.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene { this->_writer = writer; } - + MergePolicy::~MergePolicy() { } - + OneMerge::OneMerge(SegmentInfosPtr segments, bool useCompoundFile) { mergeDocStores = false; @@ -30,48 +30,48 @@ namespace Lucene isExternal = false; maxNumSegmentsOptimize = 0; aborted = false; - + if (segments->empty()) boost::throw_exception(RuntimeException(L"segments must include at least one segment")); this->segments = segments; this->useCompoundFile = useCompoundFile; } - + OneMerge::~OneMerge() { } - + void OneMerge::setException(const LuceneException& error) { SyncLock syncLock(this); this->error = error; } - + LuceneException OneMerge::getException() { SyncLock syncLock(this); return error; } - + void OneMerge::abort() { SyncLock syncLock(this); aborted = true; } - + bool OneMerge::isAborted() { SyncLock syncLock(this); return aborted; } - + void OneMerge::checkAborted(DirectoryPtr dir) { SyncLock syncLock(this); if (aborted) boost::throw_exception(MergeAbortedException(L"merge is aborted: " + segString(dir))); } - + String OneMerge::segString(DirectoryPtr dir) { StringStream buffer; @@ -90,21 +90,21 @@ namespace Lucene buffer << L" [mergeDocStores]"; return buffer.str(); } - + MergeSpecification::MergeSpecification() { merges = Collection::newInstance(); } - + MergeSpecification::~MergeSpecification() { } - + void MergeSpecification::add(OneMergePtr merge) { merges.add(merge); } - + String MergeSpecification::segString(DirectoryPtr dir) { String seg(L"MergeSpec:\n"); diff --git a/src/core/index/MergeScheduler.cpp b/src/core/index/MergeScheduler.cpp index eafa734f..9aaf7f47 100644 --- a/src/core/index/MergeScheduler.cpp +++ b/src/core/index/MergeScheduler.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/MultiLevelSkipListReader.cpp b/src/core/index/MultiLevelSkipListReader.cpp index c38fd603..c579be88 100644 --- a/src/core/index/MultiLevelSkipListReader.cpp +++ b/src/core/index/MultiLevelSkipListReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/MultiLevelSkipListWriter.cpp b/src/core/index/MultiLevelSkipListWriter.cpp index 13b475d9..76518d67 100644 --- a/src/core/index/MultiLevelSkipListWriter.cpp +++ b/src/core/index/MultiLevelSkipListWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,25 +13,25 @@ namespace Lucene MultiLevelSkipListWriter::MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df) { this->skipInterval = skipInterval; - + // calculate the maximum number of skip levels for this document frequency numberOfSkipLevels = df == 0 ? 0 : (int32_t)std::floor(std::log((double)df) / std::log((double)skipInterval)); - + // make sure it does not exceed maxSkipLevels numberOfSkipLevels = std::max(numberOfSkipLevels, maxSkipLevels); } - + MultiLevelSkipListWriter::~MultiLevelSkipListWriter() { } - + void MultiLevelSkipListWriter::init() { skipBuffer = Collection::newInstance(numberOfSkipLevels); for (int32_t i = 0; i < numberOfSkipLevels; ++i) skipBuffer[i] = newLucene(); } - + void MultiLevelSkipListWriter::resetSkip() { // creates new buffers or empties the existing ones @@ -43,40 +43,40 @@ namespace Lucene (*buffer)->reset(); } } - + void MultiLevelSkipListWriter::bufferSkip(int32_t df) { int32_t numLevels = 0; - + // determine max level for (; (df % skipInterval) == 0 && numLevels < numberOfSkipLevels; df /= skipInterval) ++numLevels; - + int64_t childPointer = 0; - + for (int32_t level = 0; level < numLevels; ++level) { writeSkipData(level, skipBuffer[level]); - + int64_t newChildPointer = skipBuffer[level]->getFilePointer(); - + if (level != 0) { // store child pointers for all levels except the lowest skipBuffer[level]->writeVLong(childPointer); } - + // remember the childPointer for the next level childPointer = newChildPointer; } } - + int64_t MultiLevelSkipListWriter::writeSkip(IndexOutputPtr output) { int64_t skipPointer = output->getFilePointer(); if (!skipBuffer || skipBuffer.empty()) return skipPointer; - + for (int32_t level = numberOfSkipLevels - 1; level > 0; --level) { int64_t length = skipBuffer[level]->getFilePointer(); @@ -89,6 +89,6 @@ namespace Lucene skipBuffer[0]->writeTo(output); return skipPointer; } - - + + } diff --git a/src/core/index/MultiReader.cpp b/src/core/index/MultiReader.cpp index 755500a1..6055ea66 100644 --- a/src/core/index/MultiReader.cpp +++ b/src/core/index/MultiReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,7 +26,7 @@ namespace Lucene { starts[i] = _maxDoc; _maxDoc += subReaders[i]->maxDoc(); // compute maxDocs - + if (!closeSubReaders) { subReaders[i]->incRef(); @@ -34,23 +34,23 @@ namespace Lucene } else decrefOnClose[i] = false; - + if (subReaders[i]->hasDeletions()) _hasDeletions = true; } starts[subReaders.size()] = _maxDoc; } - + MultiReader::~MultiReader() { } - + IndexReaderPtr MultiReader::reopen() { SyncLock syncLock(this); return doReopen(false); } - + LuceneObjectPtr MultiReader::clone(LuceneObjectPtr other) { SyncLock syncLock(this); @@ -64,14 +64,14 @@ namespace Lucene } return LuceneObjectPtr(); } - + IndexReaderPtr MultiReader::doReopen(bool doClone) { ensureOpen(); - + bool reopened = false; Collection newSubReaders(Collection::newInstance(subReaders.size())); - + bool success = false; LuceneException finally; try @@ -111,7 +111,7 @@ namespace Lucene } } finally.throwException(); - + if (reopened) { Collection newDecrefOnClose(Collection::newInstance(subReaders.size())); @@ -123,7 +123,7 @@ namespace Lucene newDecrefOnClose[i] = true; } } - + MultiReaderPtr mr(newLucene(newSubReaders)); mr->decrefOnClose = newDecrefOnClose; return mr; @@ -131,44 +131,44 @@ namespace Lucene else return shared_from_this(); } - + Collection MultiReader::getTermFreqVectors(int32_t docNumber) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num return subReaders[i]->getTermFreqVectors(docNumber - starts[i]); // dispatch to segment } - + TermFreqVectorPtr MultiReader::getTermFreqVector(int32_t docNumber, const String& field) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); } - + void MultiReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); } - + void MultiReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num subReaders[i]->getTermFreqVector(docNumber - starts[i], mapper); } - + bool MultiReader::isOptimized() { return false; } - + int32_t MultiReader::numDocs() { // Don't call ensureOpen() here (it could affect performance) - + // NOTE: multiple threads may wind up init'ing numDocs... but that's harmless if (_numDocs == -1) { @@ -180,33 +180,33 @@ namespace Lucene } return _numDocs; } - + int32_t MultiReader::maxDoc() { // Don't call ensureOpen() here (it could affect performance) return _maxDoc; } - + DocumentPtr MultiReader::document(int32_t n, FieldSelectorPtr fieldSelector) { ensureOpen(); int32_t i = readerIndex(n); // find segment num return subReaders[i]->document(n - starts[i], fieldSelector); // dispatch to segment reader } - + bool MultiReader::isDeleted(int32_t n) { // Don't call ensureOpen() here (it could affect performance) int32_t i = readerIndex(n); // find segment num return subReaders[i]->isDeleted(n - starts[i]); // dispatch to segment reader } - + bool MultiReader::hasDeletions() { // Don't call ensureOpen() here (it could affect performance) return _hasDeletions; } - + void MultiReader::doDelete(int32_t docNum) { _numDocs = -1; // invalidate cache @@ -214,7 +214,7 @@ namespace Lucene subReaders[i]->deleteDocument(docNum - starts[i]); // dispatch to segment reader _hasDeletions = true; } - + void MultiReader::doUndeleteAll() { for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) @@ -222,12 +222,12 @@ namespace Lucene _hasDeletions = false; _numDocs = -1; // invalidate cache } - + int32_t MultiReader::readerIndex(int32_t n) { return DirectoryReader::readerIndex(n, this->starts, this->subReaders.size()); } - + bool MultiReader::hasNorms(const String& field) { ensureOpen(); @@ -238,7 +238,7 @@ namespace Lucene } return false; } - + ByteArray MultiReader::norms(const String& field) { SyncLock syncLock(this); @@ -248,14 +248,14 @@ namespace Lucene return bytes; // cache hit if (!hasNorms(field)) return ByteArray(); - + bytes = ByteArray::newInstance(maxDoc()); for (int32_t i = 0; i < subReaders.size(); ++i) subReaders[i]->norms(field, bytes, starts[i]); normsCache.put(field, bytes); // update cache return bytes; } - + void MultiReader::norms(const String& field, ByteArray norms, int32_t offset) { SyncLock syncLock(this); @@ -263,7 +263,7 @@ namespace Lucene ByteArray bytes(normsCache.get(field)); for (int32_t i = 0; i < subReaders.size(); ++i) // read from segments subReaders[i]->norms(field, norms, offset + starts[i]); - + if (!bytes && !hasNorms(field)) MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); else if (bytes) // cache hit @@ -274,7 +274,7 @@ namespace Lucene subReaders[i]->norms(field, norms, offset + starts[i]); } } - + void MultiReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { { @@ -284,19 +284,19 @@ namespace Lucene int32_t i = readerIndex(doc); // find segment num subReaders[i]->setNorm(doc - starts[i], field, value); // dispatch } - + TermEnumPtr MultiReader::terms() { ensureOpen(); return newLucene(shared_from_this(), subReaders, starts, TermPtr()); } - + TermEnumPtr MultiReader::terms(TermPtr t) { ensureOpen(); return newLucene(shared_from_this(), subReaders, starts, t); } - + int32_t MultiReader::docFreq(TermPtr t) { ensureOpen(); @@ -305,25 +305,25 @@ namespace Lucene total += (*reader)->docFreq(t); return total; } - + TermDocsPtr MultiReader::termDocs() { ensureOpen(); return newLucene(shared_from_this(), subReaders, starts); } - + TermPositionsPtr MultiReader::termPositions() { ensureOpen(); return newLucene(shared_from_this(), subReaders, starts); } - + void MultiReader::doCommit(MapStringString commitUserData) { for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) (*reader)->commit(commitUserData); } - + void MultiReader::doClose() { SyncLock syncLock(this); @@ -334,18 +334,18 @@ namespace Lucene else subReaders[i]->close(); } - - // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is + + // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is // generally not a good idea) FieldCache::DEFAULT()->purge(shared_from_this()); } - + HashSet MultiReader::getFieldNames(FieldOption fieldOption) { ensureOpen(); return DirectoryReader::getFieldNames(fieldOption, this->subReaders); } - + bool MultiReader::isCurrent() { for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) @@ -356,13 +356,13 @@ namespace Lucene // all subreaders are up to date return true; } - + int64_t MultiReader::getVersion() { boost::throw_exception(UnsupportedOperationException()); return 0; } - + Collection MultiReader::getSequentialSubReaders() { return subReaders; diff --git a/src/core/index/MultipleTermPositions.cpp b/src/core/index/MultipleTermPositions.cpp index 6da226e6..aceefa80 100644 --- a/src/core/index/MultipleTermPositions.cpp +++ b/src/core/index/MultipleTermPositions.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/NormsWriter.cpp b/src/core/index/NormsWriter.cpp index ecbc5e87..83fb37fc 100644 --- a/src/core/index/NormsWriter.cpp +++ b/src/core/index/NormsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,11 +23,11 @@ namespace Lucene NormsWriter::NormsWriter() { } - + NormsWriter::~NormsWriter() { } - + uint8_t NormsWriter::getDefaultNorm() { static uint8_t defaultNorm = 0; @@ -35,29 +35,29 @@ namespace Lucene defaultNorm = Similarity::encodeNorm(1.0); return defaultNorm; } - + InvertedDocEndConsumerPerThreadPtr NormsWriter::addThread(DocInverterPerThreadPtr docInverterPerThread) { return newLucene(docInverterPerThread, shared_from_this()); } - + void NormsWriter::abort() { } - + void NormsWriter::files(HashSet files) { } - + void NormsWriter::setFieldInfos(FieldInfosPtr fieldInfos) { this->fieldInfos = fieldInfos; } - + void NormsWriter::flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, SegmentWriteStatePtr state) { MapFieldInfoCollectionNormsWriterPerField byField(MapFieldInfoCollectionNormsWriterPerField::newInstance()); - + // Typically, each thread will have encountered the same field. So first we collate by field, ie all // per-thread field instances that correspond to the same FieldInfo for (MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) @@ -84,48 +84,48 @@ namespace Lucene } } } - + String normsFileName(state->segmentName + L"." + IndexFileNames::NORMS_EXTENSION()); state->flushedFiles.add(normsFileName); IndexOutputPtr normsOut(state->directory->createOutput(normsFileName)); - + LuceneException finally; try { normsOut->writeBytes(SegmentMerger::NORMS_HEADER, 0, SegmentMerger::NORMS_HEADER_LENGTH); - + int32_t numField = fieldInfos->size(); - + int32_t normCount = 0; - + for (int32_t fieldNumber = 0; fieldNumber < numField; ++fieldNumber) { FieldInfoPtr fieldInfo(fieldInfos->fieldInfo(fieldNumber)); - + Collection toMerge = byField.get(fieldInfo); int32_t upto = 0; - + if (toMerge) { int32_t numFields = toMerge.size(); - + ++normCount; - + Collection fields(Collection::newInstance(numFields)); Collection uptos(Collection::newInstance(numFields)); - + for (int32_t j = 0; j < numFields; ++j) fields[j] = toMerge[j]; - + int32_t numLeft = numFields; - + while (numLeft > 0) { BOOST_ASSERT(uptos[0] < fields[0]->docIDs.size()); - + int32_t minLoc = 0; int32_t minDocID = fields[0]->docIDs[uptos[0]]; - + for (int32_t j = 1; j < numLeft; ++j) { int32_t docID = fields[j]->docIDs[uptos[j]]; @@ -135,17 +135,17 @@ namespace Lucene minLoc = j; } } - + BOOST_ASSERT(minDocID < state->numDocs); - + // Fill hole for (;upto < minDocID; ++upto) normsOut->writeByte(getDefaultNorm()); - + normsOut->writeByte(fields[minLoc]->norms[uptos[minLoc]]); ++(uptos[minLoc]); ++upto; - + if (uptos[minLoc] == fields[minLoc]->upto) { fields[minLoc]->reset(); @@ -157,7 +157,7 @@ namespace Lucene --numLeft; } } - + // Fill final hole with defaultNorm for (;upto < state->numDocs; ++upto) normsOut->writeByte(getDefaultNorm()); @@ -169,7 +169,7 @@ namespace Lucene for (;upto < state->numDocs; ++upto) normsOut->writeByte(getDefaultNorm()); } - + BOOST_ASSERT(4 + normCount * state->numDocs == normsOut->getFilePointer()); // .nrm file size mismatch? } } @@ -177,12 +177,12 @@ namespace Lucene { finally = e; } - + normsOut->close(); - + finally.throwException(); } - + void NormsWriter::closeDocStore(SegmentWriteStatePtr state) { } diff --git a/src/core/index/NormsWriterPerField.cpp b/src/core/index/NormsWriterPerField.cpp index 951ee866..39b7f9bf 100644 --- a/src/core/index/NormsWriterPerField.cpp +++ b/src/core/index/NormsWriterPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,17 +20,17 @@ namespace Lucene docIDs = Collection::newInstance(1); norms = ByteArray::newInstance(1); upto = 0; - + this->_perThread = perThread; this->fieldInfo = fieldInfo; docState = perThread->docState; fieldState = docInverterPerField->fieldState; } - + NormsWriterPerField::~NormsWriterPerField() { } - + void NormsWriterPerField::reset() { // Shrink back if we are over allocated now @@ -38,17 +38,17 @@ namespace Lucene norms.resize(MiscUtils::getShrinkSize(norms.size(), upto)); upto = 0; } - + void NormsWriterPerField::abort() { upto = 0; } - + int32_t NormsWriterPerField::compareTo(LuceneObjectPtr other) { return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); } - + void NormsWriterPerField::finish() { BOOST_ASSERT(docIDs.size() == norms.size()); diff --git a/src/core/index/NormsWriterPerThread.cpp b/src/core/index/NormsWriterPerThread.cpp index 68f5dc51..ff2a2d1b 100644 --- a/src/core/index/NormsWriterPerThread.cpp +++ b/src/core/index/NormsWriterPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,28 +16,28 @@ namespace Lucene this->_normsWriter = normsWriter; docState = docInverterPerThread->docState; } - + NormsWriterPerThread::~NormsWriterPerThread() { } - + InvertedDocEndConsumerPerFieldPtr NormsWriterPerThread::addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) { return newLucene(docInverterPerField, shared_from_this(), fieldInfo); } - + void NormsWriterPerThread::abort() { } - + void NormsWriterPerThread::startDocument() { } - + void NormsWriterPerThread::finishDocument() { } - + bool NormsWriterPerThread::freeRAM() { return false; diff --git a/src/core/index/ParallelReader.cpp b/src/core/index/ParallelReader.cpp index 671c58b4..4509b1dc 100644 --- a/src/core/index/ParallelReader.cpp +++ b/src/core/index/ParallelReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,20 +25,20 @@ namespace Lucene this->_maxDoc = 0; this->_numDocs = 0; this->_hasDeletions = false; - + this->incRefReaders = !closeSubReaders; } - + ParallelReader::~ParallelReader() { } - + void ParallelReader::add(IndexReaderPtr reader) { ensureOpen(); add(reader, false); } - + void ParallelReader::add(IndexReaderPtr reader, bool ignoreStoredFields) { ensureOpen(); @@ -48,18 +48,18 @@ namespace Lucene this->_numDocs = reader->numDocs(); this->_hasDeletions = reader->hasDeletions(); } - + if (reader->maxDoc() != _maxDoc) // check compatibility { - boost::throw_exception(IllegalArgumentException(L"All readers must have same maxDoc: " + StringUtils::toString(_maxDoc) + + boost::throw_exception(IllegalArgumentException(L"All readers must have same maxDoc: " + StringUtils::toString(_maxDoc) + L" != " + StringUtils::toString(reader->maxDoc()))); } if (reader->numDocs() != _numDocs) { - boost::throw_exception(IllegalArgumentException(L"All readers must have same numDocs: " + StringUtils::toString(_numDocs) + + boost::throw_exception(IllegalArgumentException(L"All readers must have same numDocs: " + StringUtils::toString(_numDocs) + L" != " + StringUtils::toString(reader->numDocs()))); } - + HashSet fields(reader->getFieldNames(IndexReader::FIELD_OPTION_ALL)); readerToFields.put(reader, fields); for (HashSet::iterator field = fields.begin(); field != fields.end(); ++field) // update fieldToReader map @@ -67,17 +67,17 @@ namespace Lucene if (!fieldToReader.contains(*field)) fieldToReader.put(*field, reader); } - + if (!ignoreStoredFields) storedFieldReaders.add(reader); // add to storedFieldReaders readers.add(reader); - + if (incRefReaders) reader->incRef(); - + decrefOnClose.add(incRefReaders); } - + LuceneObjectPtr ParallelReader::clone(LuceneObjectPtr other) { SyncLock syncLock(this); @@ -91,20 +91,20 @@ namespace Lucene } return LuceneObjectPtr(); } - + IndexReaderPtr ParallelReader::reopen() { SyncLock syncLock(this); return doReopen(false); } - + IndexReaderPtr ParallelReader::doReopen(bool doClone) { ensureOpen(); - + bool reopened = false; Collection newReaders(Collection::newInstance()); - + bool success = false; LuceneException finally; try @@ -146,7 +146,7 @@ namespace Lucene } } finally.throwException(); - + if (reopened) { Collection newDecrefOnClose(Collection::newInstance()); @@ -162,7 +162,7 @@ namespace Lucene } else { - // this is a new subreader instance, so on close() we don't decRef but close it + // this is a new subreader instance, so on close() we don't decRef but close it newDecrefOnClose.add(false); } pr->add(newReader, !storedFieldReaders.contains(oldReader)); @@ -177,31 +177,31 @@ namespace Lucene return shared_from_this(); } } - + int32_t ParallelReader::numDocs() { // Don't call ensureOpen() here (it could affect performance) return _numDocs; } - + int32_t ParallelReader::maxDoc() { // Don't call ensureOpen() here (it could affect performance) return _maxDoc; } - + bool ParallelReader::hasDeletions() { // Don't call ensureOpen() here (it could affect performance) return _hasDeletions; } - + bool ParallelReader::isDeleted(int32_t n) { // Don't call ensureOpen() here (it could affect performance) return !readers.empty() ? readers[0]->isDeleted(n) : false; // check first reader } - + void ParallelReader::doDelete(int32_t docNum) { // delete in all readers @@ -209,7 +209,7 @@ namespace Lucene (*reader)->deleteDocument(docNum); _hasDeletions = true; } - + void ParallelReader::doUndeleteAll() { // undeleteAll in all readers @@ -217,12 +217,12 @@ namespace Lucene (*reader)->undeleteAll(); _hasDeletions = false; } - + DocumentPtr ParallelReader::document(int32_t n, FieldSelectorPtr fieldSelector) { ensureOpen(); DocumentPtr result(newLucene()); - + // append fields from storedFieldReaders for (Collection::iterator reader = storedFieldReaders.begin(); reader != storedFieldReaders.end(); ++reader) { @@ -248,13 +248,13 @@ namespace Lucene } return result; } - + Collection ParallelReader::getTermFreqVectors(int32_t docNumber) { ensureOpen(); - + Collection results(Collection::newInstance()); - + // get all vectors for (MapStringIndexReader::iterator entry = fieldToReader.begin(); entry != fieldToReader.end(); ++entry) { @@ -262,17 +262,17 @@ namespace Lucene if (vector) results.add(vector); } - + return results; } - + TermFreqVectorPtr ParallelReader::getTermFreqVector(int32_t docNumber, const String& field) { ensureOpen(); MapStringIndexReader::iterator reader = fieldToReader.find(field); return reader == fieldToReader.end() ? TermFreqVectorPtr() : reader->second->getTermFreqVector(docNumber, field); } - + void ParallelReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) { ensureOpen(); @@ -280,28 +280,28 @@ namespace Lucene if (reader != fieldToReader.end()) reader->second->getTermFreqVector(docNumber, field, mapper); } - + void ParallelReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) { ensureOpen(); for (MapStringIndexReader::iterator entry = fieldToReader.begin(); entry != fieldToReader.end(); ++entry) entry->second->getTermFreqVector(docNumber, entry->first, mapper); } - + bool ParallelReader::hasNorms(const String& field) { ensureOpen(); MapStringIndexReader::iterator reader = fieldToReader.find(field); return reader == fieldToReader.end() ? false : reader->second->hasNorms(field); } - + ByteArray ParallelReader::norms(const String& field) { ensureOpen(); MapStringIndexReader::iterator reader = fieldToReader.find(field); return reader == fieldToReader.end() ? ByteArray() : reader->second->norms(field); } - + void ParallelReader::norms(const String& field, ByteArray norms, int32_t offset) { ensureOpen(); @@ -309,7 +309,7 @@ namespace Lucene if (reader != fieldToReader.end()) reader->second->norms(field, norms, offset); } - + void ParallelReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { ensureOpen(); @@ -317,50 +317,50 @@ namespace Lucene if (reader != fieldToReader.end()) reader->second->doSetNorm(doc, field, value); } - + TermEnumPtr ParallelReader::terms() { ensureOpen(); return newLucene(shared_from_this()); } - + TermEnumPtr ParallelReader::terms(TermPtr t) { ensureOpen(); return newLucene(shared_from_this(), t); } - + int32_t ParallelReader::docFreq(TermPtr t) { ensureOpen(); MapStringIndexReader::iterator reader = fieldToReader.find(t->field()); return reader == fieldToReader.end() ? 0 : reader->second->docFreq(t); } - + TermDocsPtr ParallelReader::termDocs(TermPtr term) { ensureOpen(); return newLucene(shared_from_this(), term); } - + TermDocsPtr ParallelReader::termDocs() { ensureOpen(); return newLucene(shared_from_this()); } - + TermPositionsPtr ParallelReader::termPositions(TermPtr term) { ensureOpen(); return newLucene(shared_from_this(), term); } - + TermPositionsPtr ParallelReader::termPositions() { ensureOpen(); return newLucene(shared_from_this()); } - + bool ParallelReader::isCurrent() { for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) @@ -368,11 +368,11 @@ namespace Lucene if (!(*reader)->isCurrent()) return false; } - + // all subreaders are up to date return true; } - + bool ParallelReader::isOptimized() { for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) @@ -380,28 +380,28 @@ namespace Lucene if (!(*reader)->isOptimized()) return false; } - + // all subindexes are optimized return true; } - + int64_t ParallelReader::getVersion() { boost::throw_exception(UnsupportedOperationException(L"ParallelReader does not support this method.")); return 0; } - + Collection ParallelReader::getSubReaders() { return readers; } - + void ParallelReader::doCommit(MapStringString commitUserData) { for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) (*reader)->commit(commitUserData); } - + void ParallelReader::doClose() { SyncLock syncLock(this); @@ -412,10 +412,10 @@ namespace Lucene else readers[i]->close(); } - + FieldCache::DEFAULT()->purge(shared_from_this()); } - + HashSet ParallelReader::getFieldNames(FieldOption fieldOption) { ensureOpen(); @@ -427,7 +427,7 @@ namespace Lucene } return fieldSet; } - + ParallelTermEnum::ParallelTermEnum(ParallelReaderPtr reader) { this->setIterator = false; @@ -438,7 +438,7 @@ namespace Lucene if (!field.empty()) this->termEnum = reader->fieldToReader[field]->terms(); } - + ParallelTermEnum::ParallelTermEnum(ParallelReaderPtr reader, TermPtr term) { this->setIterator = false; @@ -448,23 +448,23 @@ namespace Lucene if (indexReader != reader->fieldToReader.end()) this->termEnum = indexReader->second->terms(term); } - + ParallelTermEnum::~ParallelTermEnum() { } - + bool ParallelTermEnum::next() { if (!termEnum) return false; - + // another term in this field? if (termEnum->next() && termEnum->term()->field() == field) return true; // yes, keep going - + termEnum->close(); // close old termEnum ParallelReaderPtr reader(_reader); - + // find the next field with terms, if any if (!setIterator) { @@ -472,7 +472,7 @@ namespace Lucene ++fieldIterator; // Skip field to get next one setIterator = false; } - + while (fieldIterator != reader->fieldToReader.end()) { field = fieldIterator->first; @@ -484,31 +484,31 @@ namespace Lucene else termEnum->close(); } - + return false; // no more fields } - + TermPtr ParallelTermEnum::term() { return termEnum ? termEnum->term() : TermPtr(); } - + int32_t ParallelTermEnum::docFreq() { return termEnum ? termEnum->docFreq() : 0; } - + void ParallelTermEnum::close() { if (termEnum) termEnum->close(); } - + ParallelTermDocs::ParallelTermDocs(ParallelReaderPtr reader) { this->_reader = reader; } - + ParallelTermDocs::ParallelTermDocs(ParallelReaderPtr reader, TermPtr term) { this->_reader = reader; @@ -517,92 +517,92 @@ namespace Lucene else seek(term); } - + ParallelTermDocs::~ParallelTermDocs() { } - + int32_t ParallelTermDocs::doc() { return termDocs->doc(); } - + int32_t ParallelTermDocs::freq() { return termDocs->freq(); } - + void ParallelTermDocs::seek(TermPtr term) { ParallelReaderPtr reader(_reader); MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); termDocs = indexReader != reader->fieldToReader.end() ? indexReader->second->termDocs(term) : TermDocsPtr(); } - + void ParallelTermDocs::seek(TermEnumPtr termEnum) { seek(termEnum->term()); } - + bool ParallelTermDocs::next() { return termDocs ? termDocs->next() : false; } - + int32_t ParallelTermDocs::read(Collection docs, Collection freqs) { return termDocs ? termDocs->read(docs, freqs) : 0; } - + bool ParallelTermDocs::skipTo(int32_t target) { return termDocs ? termDocs->skipTo(target) : false; } - + void ParallelTermDocs::close() { if (termDocs) termDocs->close(); } - + ParallelTermPositions::ParallelTermPositions(ParallelReaderPtr reader) : ParallelTermDocs(reader) { } - + ParallelTermPositions::ParallelTermPositions(ParallelReaderPtr reader, TermPtr term) : ParallelTermDocs(reader) { seek(term); } - + ParallelTermPositions::~ParallelTermPositions() { } - + void ParallelTermPositions::seek(TermPtr term) { ParallelReaderPtr reader(_reader); MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); termDocs = indexReader != reader->fieldToReader.end() ? indexReader->second->termPositions(term) : TermDocsPtr(); } - + int32_t ParallelTermPositions::nextPosition() { // It is an error to call this if there is no next position, eg. if termDocs==null return boost::static_pointer_cast(termDocs)->nextPosition(); } - + int32_t ParallelTermPositions::getPayloadLength() { // It is an error to call this if there is no next position, eg. if termDocs==null return boost::static_pointer_cast(termDocs)->getPayloadLength(); } - + ByteArray ParallelTermPositions::getPayload(ByteArray data, int32_t offset) { // It is an error to call this if there is no next position, eg. if termDocs==null return boost::static_pointer_cast(termDocs)->getPayload(data, offset); } - + bool ParallelTermPositions::isPayloadAvailable() { // It is an error to call this if there is no next position, eg. if termDocs==null diff --git a/src/core/index/Payload.cpp b/src/core/index/Payload.cpp index 9c28c51b..628993d6 100644 --- a/src/core/index/Payload.cpp +++ b/src/core/index/Payload.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,14 +15,14 @@ namespace Lucene this->offset = 0; this->_length = 0; } - + Payload::Payload(ByteArray data) { this->data = data; this->offset = 0; this->_length = data.size(); } - + Payload::Payload(ByteArray data, int32_t offset, int32_t length) { if (offset < 0 || offset + length > data.size()) @@ -31,38 +31,38 @@ namespace Lucene this->offset = offset; this->_length = length; } - + Payload::~Payload() { } - + void Payload::setData(ByteArray data) { setData(data, 0, data.size()); } - + void Payload::setData(ByteArray data, int32_t offset, int32_t length) { this->data = data; this->offset = offset; this->_length = length; } - + ByteArray Payload::getData() { return this->data; } - + int32_t Payload::getOffset() { return this->offset; } - + int32_t Payload::length() { return this->_length; } - + uint8_t Payload::byteAt(int32_t index) { if (0 <= index && index < this->_length) @@ -70,21 +70,21 @@ namespace Lucene boost::throw_exception(IndexOutOfBoundsException()); return 0; } - + ByteArray Payload::toByteArray() { ByteArray retArray(ByteArray::newInstance(this->_length)); MiscUtils::arrayCopy(this->data.get(), this->offset, retArray.get(), 0, this->_length); return retArray; } - + void Payload::copyTo(ByteArray target, int32_t targetOffset) { if (this->_length > target.size() + targetOffset) boost::throw_exception(IndexOutOfBoundsException()); MiscUtils::arrayCopy(this->data.get(), this->offset, target.get(), targetOffset, this->_length); } - + LuceneObjectPtr Payload::clone(LuceneObjectPtr other) { // Start with a shallow copy of data @@ -92,7 +92,7 @@ namespace Lucene PayloadPtr clonePayload(boost::dynamic_pointer_cast(clone)); clonePayload->offset = offset; clonePayload->_length = _length; - + // Only copy the part of data that belongs to this Payload if (offset == 0 && _length == data.size()) { @@ -108,12 +108,12 @@ namespace Lucene } return clonePayload; } - + bool Payload::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + PayloadPtr otherPayload(boost::dynamic_pointer_cast(other)); if (otherPayload) { @@ -122,10 +122,10 @@ namespace Lucene else return false; } - + return false; } - + int32_t Payload::hashCode() { return MiscUtils::hashCode(data.get(), offset, offset + _length); diff --git a/src/core/index/PositionBasedTermVectorMapper.cpp b/src/core/index/PositionBasedTermVectorMapper.cpp index 44216b95..d2c4795d 100644 --- a/src/core/index/PositionBasedTermVectorMapper.cpp +++ b/src/core/index/PositionBasedTermVectorMapper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,16 +13,16 @@ namespace Lucene { storeOffsets = false; } - + PositionBasedTermVectorMapper::~PositionBasedTermVectorMapper() { } - + bool PositionBasedTermVectorMapper::isIgnoringPositions() { return false; } - + void PositionBasedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { for (int32_t i = 0; i < positions.size(); ++i) @@ -36,7 +36,7 @@ namespace Lucene pos->addTerm(term, offsets ? offsets[i] : TermVectorOffsetInfoPtr()); } } - + void PositionBasedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { if (storePositions == false) @@ -51,12 +51,12 @@ namespace Lucene this->currentPositions = MapIntTermVectorsPositionInfo::newInstance(); fieldToTerms.put(currentField, currentPositions); } - + MapStringMapIntTermVectorsPositionInfo PositionBasedTermVectorMapper::getFieldToTerms() { return fieldToTerms; } - + TermVectorsPositionInfo::TermVectorsPositionInfo(int32_t position, bool storeOffsets) { this->position = position; @@ -64,28 +64,28 @@ namespace Lucene if (storeOffsets) offsets = Collection::newInstance(); } - + TermVectorsPositionInfo::~TermVectorsPositionInfo() { } - + void TermVectorsPositionInfo::addTerm(const String& term, TermVectorOffsetInfoPtr info) { terms.add(term); if (offsets) offsets.add(info); } - + int32_t TermVectorsPositionInfo::getPosition() { return position; } - + Collection TermVectorsPositionInfo::getTerms() { return terms; } - + Collection TermVectorsPositionInfo::getOffsets() { return offsets; diff --git a/src/core/index/RawPostingList.cpp b/src/core/index/RawPostingList.cpp index 900a8b60..6f5eac3d 100644 --- a/src/core/index/RawPostingList.cpp +++ b/src/core/index/RawPostingList.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,14 +11,14 @@ namespace Lucene { const int32_t RawPostingList::BYTES_SIZE = DocumentsWriter::OBJECT_HEADER_BYTES + 3 * DocumentsWriter::INT_NUM_BYTE; - + RawPostingList::RawPostingList() { textStart = 0; intStart = 0; byteStart = 0; } - + RawPostingList::~RawPostingList() { } diff --git a/src/core/index/ReadOnlyDirectoryReader.cpp b/src/core/index/ReadOnlyDirectoryReader.cpp index e3baedaa..f160bea6 100644 --- a/src/core/index/ReadOnlyDirectoryReader.cpp +++ b/src/core/index/ReadOnlyDirectoryReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -10,29 +10,29 @@ namespace Lucene { - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, - IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor) : + ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, + IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor) : DirectoryReader(directory, sis, deletionPolicy, true, termInfosIndexDivisor) { } - - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, - Collection oldReaders, Collection oldStarts, - MapStringByteArray oldNormsCache, bool doClone, + + ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, + Collection oldReaders, Collection oldStarts, + MapStringByteArray oldNormsCache, bool doClone, int32_t termInfosIndexDivisor) : DirectoryReader(directory, infos, oldReaders, oldStarts, oldNormsCache, true, doClone, termInfosIndexDivisor) { } - + ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor) : DirectoryReader(writer, infos, termInfosIndexDivisor) { } - + ReadOnlyDirectoryReader::~ReadOnlyDirectoryReader() { } - + void ReadOnlyDirectoryReader::acquireWriteLock() { ReadOnlySegmentReader::noWrite(); diff --git a/src/core/index/ReadOnlySegmentReader.cpp b/src/core/index/ReadOnlySegmentReader.cpp index 994a5035..30b4577b 100644 --- a/src/core/index/ReadOnlySegmentReader.cpp +++ b/src/core/index/ReadOnlySegmentReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,17 +13,17 @@ namespace Lucene ReadOnlySegmentReader::~ReadOnlySegmentReader() { } - + void ReadOnlySegmentReader::noWrite() { boost::throw_exception(UnsupportedOperationException(L"This IndexReader cannot make any changes to the index (it was opened with readOnly = true)")); } - + void ReadOnlySegmentReader::acquireWriteLock() { noWrite(); } - + bool ReadOnlySegmentReader::isDeleted(int32_t n) { return (deletedDocs && deletedDocs->get(n)); diff --git a/src/core/index/ReusableStringReader.cpp b/src/core/index/ReusableStringReader.cpp index 50640428..4d848d09 100644 --- a/src/core/index/ReusableStringReader.cpp +++ b/src/core/index/ReusableStringReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,18 +15,18 @@ namespace Lucene upto = 0; left = 0; } - + ReusableStringReader::~ReusableStringReader() { } - + void ReusableStringReader::init(const String& s) { this->s = s; left = s.length(); this->upto = 0; } - + int32_t ReusableStringReader::read(wchar_t* buffer, int32_t offset, int32_t length) { if (left > length) @@ -50,7 +50,7 @@ namespace Lucene return r; } } - + void ReusableStringReader::close() { } diff --git a/src/core/index/SegmentInfo.cpp b/src/core/index/SegmentInfo.cpp index 3a3a5a2b..4e399d3c 100644 --- a/src/core/index/SegmentInfo.cpp +++ b/src/core/index/SegmentInfo.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,8 +23,8 @@ namespace Lucene const int32_t SegmentInfo::NO = -1; // no norms; no deletes; const int32_t SegmentInfo::YES = 1; // have norms; have deletes; const int32_t SegmentInfo::CHECK_DIR = 0; // must check dir to see if there are norms/deletions - const int32_t SegmentInfo::WITHOUT_GEN = 0; // a file name that has no GEN in it. - + const int32_t SegmentInfo::WITHOUT_GEN = 0; // a file name that has no GEN in it. + SegmentInfo::SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir) { _sizeInBytes = -1; @@ -41,7 +41,7 @@ namespace Lucene delCount = 0; hasProx = true; } - + SegmentInfo::SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, bool hasSingleNormFile) { _sizeInBytes = -1; @@ -57,7 +57,7 @@ namespace Lucene delCount = 0; hasProx = true; } - + SegmentInfo::SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, bool hasSingleNormFile, int32_t docStoreOffset, const String& docStoreSegment, bool docStoreIsCompoundFile, bool hasProx) { @@ -75,7 +75,7 @@ namespace Lucene delCount = 0; this->hasProx = hasProx; } - + SegmentInfo::SegmentInfo(DirectoryPtr dir, int32_t format, IndexInputPtr input) { _sizeInBytes = -1; @@ -129,7 +129,7 @@ namespace Lucene hasProx = (input->readByte() == 1); else hasProx = true; - + if (format <= SegmentInfos::FORMAT_DIAGNOSTICS) diagnostics = input->readStringStringMap(); else @@ -148,11 +148,11 @@ namespace Lucene diagnostics = MapStringString::newInstance(); } } - + SegmentInfo::~SegmentInfo() { } - + void SegmentInfo::reset(SegmentInfoPtr src) { clearFiles(); @@ -171,17 +171,17 @@ namespace Lucene hasSingleNormFile = src->hasSingleNormFile; delCount = src->delCount; } - + void SegmentInfo::setDiagnostics(MapStringString diagnostics) { this->diagnostics = diagnostics; } - + MapStringString SegmentInfo::getDiagnostics() { return diagnostics; } - + void SegmentInfo::setNumFields(int32_t numFields) { if (!normGen) @@ -189,9 +189,9 @@ namespace Lucene // normGen is null if we loaded a pre-2.1 segment file, or, if this segments file hasn't had any // norms set against it yet normGen = Collection::newInstance(numFields); - - if (!preLockless) - { // Do nothing: thus leaving normGen[k] == CHECK_DIR (==0), so that later we know + + if (!preLockless) + { // Do nothing: thus leaving normGen[k] == CHECK_DIR (==0), so that later we know } // we have to check filesystem for norm files, because this is prelockless. else { @@ -201,7 +201,7 @@ namespace Lucene } } } - + int64_t SegmentInfo::sizeInBytes() { if (_sizeInBytes == -1) @@ -217,7 +217,7 @@ namespace Lucene } return _sizeInBytes; } - + bool SegmentInfo::hasDeletions() { if (delGen == NO) @@ -227,7 +227,7 @@ namespace Lucene else return dir->fileExists(getDelFileName()); } - + void SegmentInfo::advanceDelGen() { // delGen 0 is reserved for pre-LOCKLESS format @@ -237,13 +237,13 @@ namespace Lucene delGen++; clearFiles(); } - + void SegmentInfo::clearDelGen() { delGen = NO; clearFiles(); } - + LuceneObjectPtr SegmentInfo::clone(LuceneObjectPtr other) { SegmentInfoPtr si(newLucene(name, docCount, dir)); @@ -262,7 +262,7 @@ namespace Lucene si->docStoreIsCompoundFile = docStoreIsCompoundFile; return si; } - + String SegmentInfo::getDelFileName() { if (delGen == NO) @@ -273,10 +273,10 @@ namespace Lucene else { // if delgen is check_dir, it's the pre-lockless-commit file format - return IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::DELETES_EXTENSION(), delGen); + return IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::DELETES_EXTENSION(), delGen); } } - + bool SegmentInfo::hasSeparateNorms(int32_t fieldNumber) { if ((!normGen && preLockless) || (normGen && normGen[fieldNumber] == CHECK_DIR)) @@ -289,7 +289,7 @@ namespace Lucene else return true; } - + bool SegmentInfo::hasSeparateNorms() { if (!normGen) @@ -333,7 +333,7 @@ namespace Lucene } return false; } - + void SegmentInfo::advanceNormGen(int32_t fieldIndex) { if (normGen[fieldIndex] == NO) @@ -342,37 +342,37 @@ namespace Lucene normGen[fieldIndex]++; clearFiles(); } - + String SegmentInfo::getNormFileName(int32_t number) { String prefix; int64_t gen = !normGen ? CHECK_DIR : normGen[number]; - + if (hasSeparateNorms(number)) { // case 1: separate norm prefix = L".s"; return IndexFileNames::fileNameFromGeneration(name, prefix + StringUtils::toString(number), gen); } - + if (hasSingleNormFile) { - // case 2: lockless (or nrm file exists) - single file for all norms + // case 2: lockless (or nrm file exists) - single file for all norms prefix = String(L".") + IndexFileNames::NORMS_EXTENSION(); return IndexFileNames::fileNameFromGeneration(name, prefix, WITHOUT_GEN); } - + // case 3: norm file for each field prefix = L".f"; - return IndexFileNames::fileNameFromGeneration(name, prefix + StringUtils::toString(number), WITHOUT_GEN); + return IndexFileNames::fileNameFromGeneration(name, prefix + StringUtils::toString(number), WITHOUT_GEN); } - + void SegmentInfo::setUseCompoundFile(bool isCompoundFile) { this->isCompoundFile = (uint8_t)(isCompoundFile ? YES : NO); clearFiles(); } - + bool SegmentInfo::getUseCompoundFile() { if (isCompoundFile == (uint8_t)NO) @@ -382,7 +382,7 @@ namespace Lucene else return dir->fileExists(name + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); } - + int32_t SegmentInfo::getDelCount() { if (delCount == -1) @@ -390,47 +390,47 @@ namespace Lucene BOOST_ASSERT(delCount <= docCount); return delCount; } - + void SegmentInfo::setDelCount(int32_t delCount) { this->delCount = delCount; BOOST_ASSERT(delCount <= docCount); } - + int32_t SegmentInfo::getDocStoreOffset() { return docStoreOffset; } - + bool SegmentInfo::getDocStoreIsCompoundFile() { return docStoreIsCompoundFile; } - + void SegmentInfo::setDocStoreIsCompoundFile(bool v) { docStoreIsCompoundFile = v; clearFiles(); } - + String SegmentInfo::getDocStoreSegment() { return docStoreSegment; } - + void SegmentInfo::setDocStoreOffset(int32_t offset) { docStoreOffset = offset; clearFiles(); } - + void SegmentInfo::setDocStore(int32_t offset, const String& segment, bool isCompoundFile) { docStoreOffset = offset; docStoreSegment = segment; docStoreIsCompoundFile = isCompoundFile; } - + void SegmentInfo::write(IndexOutputPtr output) { output->writeString(name); @@ -442,7 +442,7 @@ namespace Lucene output->writeString(docStoreSegment); output->writeByte((uint8_t)(docStoreIsCompoundFile ? 1 : 0)); } - + output->writeByte((uint8_t)(hasSingleNormFile ? 1 : 0)); if (!normGen) output->writeInt(NO); @@ -457,24 +457,24 @@ namespace Lucene output->writeByte((uint8_t)(hasProx ? 1 : 0)); output->writeStringStringMap(diagnostics); } - + void SegmentInfo::setHasProx(bool hasProx) { this->hasProx = hasProx; clearFiles(); } - + bool SegmentInfo::getHasProx() { return hasProx; } - + void SegmentInfo::addIfExists(HashSet files, const String& fileName) { if (dir->fileExists(fileName)) files.add(fileName); } - + HashSet SegmentInfo::files() { if (_files) @@ -482,10 +482,10 @@ namespace Lucene // already cached return _files; } - + _files = HashSet::newInstance(); bool useCompoundFile = getUseCompoundFile(); - + if (useCompoundFile) _files.add(name + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); else @@ -493,7 +493,7 @@ namespace Lucene for (HashSet::iterator ext = IndexFileNames::NON_STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::NON_STORE_INDEX_EXTENSIONS().end(); ++ext) addIfExists(_files, name + L"." + *ext); } - + if (docStoreOffset != -1) { // we are sharing doc stores (stored fields, term vectors) with other segments @@ -512,11 +512,11 @@ namespace Lucene for (HashSet::iterator ext = IndexFileNames::STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::STORE_INDEX_EXTENSIONS().end(); ++ext) addIfExists(_files, name + L"." + *ext); } - + String delFileName(IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::DELETES_EXTENSION(), delGen)); if (!delFileName.empty() && (delGen >= YES || dir->fileExists(delFileName))) _files.add(delFileName); - + // careful logic for norms files if (normGen) { @@ -562,20 +562,20 @@ namespace Lucene HashSet allFiles(dir->listAll()); for (HashSet::iterator fileName = allFiles.begin(); fileName != allFiles.end(); ++fileName) { - if (IndexFileNameFilter::accept(L"", *fileName) && (int32_t)fileName->length() > prefixLength && + if (IndexFileNameFilter::accept(L"", *fileName) && (int32_t)fileName->length() > prefixLength && UnicodeUtil::isDigit((*fileName)[prefixLength]) && boost::starts_with(*fileName, prefix)) _files.add(*fileName); } } return _files; } - + void SegmentInfo::clearFiles() { _files.reset(); _sizeInBytes = -1; } - + String SegmentInfo::segString(DirectoryPtr dir) { String cfs; @@ -587,14 +587,14 @@ namespace Lucene { cfs = L"?"; } - + String docStore; if (docStoreOffset != -1) docStore = L"->" + docStoreSegment; - + return name + L":" + cfs + (this->dir == dir ? L"" : L"x") + StringUtils::toString(docCount) + docStore; } - + bool SegmentInfo::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -604,7 +604,7 @@ namespace Lucene return false; return (otherSegmentInfo->dir == dir && otherSegmentInfo->name == name); } - + int32_t SegmentInfo::hashCode() { return dir->hashCode() + StringUtils::hashCode(name); diff --git a/src/core/index/SegmentInfoCollection.cpp b/src/core/index/SegmentInfoCollection.cpp index b1325706..008e3f96 100644 --- a/src/core/index/SegmentInfoCollection.cpp +++ b/src/core/index/SegmentInfoCollection.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,69 +14,69 @@ namespace Lucene { segmentInfos = Collection::newInstance(); } - + SegmentInfoCollection::~SegmentInfoCollection() { } - + int32_t SegmentInfoCollection::size() { return segmentInfos.size(); } - + bool SegmentInfoCollection::empty() { return segmentInfos.empty(); } - + void SegmentInfoCollection::clear() { segmentInfos.clear(); } - + void SegmentInfoCollection::add(SegmentInfoPtr info) { segmentInfos.add(info); } - + void SegmentInfoCollection::add(int32_t pos, SegmentInfoPtr info) { segmentInfos.add(pos, info); } - + void SegmentInfoCollection::addAll(SegmentInfoCollectionPtr segmentInfos) { this->segmentInfos.addAll(segmentInfos->segmentInfos.begin(), segmentInfos->segmentInfos.end()); } - + bool SegmentInfoCollection::equals(SegmentInfoCollectionPtr other) { if (LuceneObject::equals(other)) return true; return segmentInfos.equals(other->segmentInfos, luceneEquals()); } - + int32_t SegmentInfoCollection::find(SegmentInfoPtr info) { Collection::iterator idx = segmentInfos.find_if(luceneEqualTo(info)); return idx == segmentInfos.end() ? -1 : std::distance(segmentInfos.begin(), idx); } - + bool SegmentInfoCollection::contains(SegmentInfoPtr info) { return segmentInfos.contains_if(luceneEqualTo(info)); } - + void SegmentInfoCollection::remove(int32_t pos) { segmentInfos.remove(segmentInfos.begin() + pos); } - + void SegmentInfoCollection::remove(int32_t start, int32_t end) { segmentInfos.remove(segmentInfos.begin() + start, segmentInfos.begin() + end); } - + LuceneObjectPtr SegmentInfoCollection::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); diff --git a/src/core/index/SegmentInfos.cpp b/src/core/index/SegmentInfos.cpp index 6e0a5178..ae34643d 100644 --- a/src/core/index/SegmentInfos.cpp +++ b/src/core/index/SegmentInfos.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,45 +24,45 @@ namespace Lucene { /// The file format version, a negative number. Works since counter, the old 1st entry, is always >= 0 const int32_t SegmentInfos::FORMAT = -1; - + /// This format adds details used for lockless commits. It differs slightly from the previous format in that file names - /// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, - /// segments_2, etc. This allows us to not use a commit lock. + /// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, + /// segments_2, etc. This allows us to not use a commit lock. const int32_t SegmentInfos::FORMAT_LOCKLESS = -2; - + /// This format adds a "hasSingleNormFile" flag into each segment info. const int32_t SegmentInfos::FORMAT_SINGLE_NORM_FILE = -3; - + /// This format allows multiple segments to share a single vectors and stored fields file. const int32_t SegmentInfos::FORMAT_SHARED_DOC_STORE = -4; - + /// This format adds a checksum at the end of the file to ensure all bytes were successfully written. const int32_t SegmentInfos::FORMAT_CHECKSUM = -5; - + /// This format adds the deletion count for each segment. This way IndexWriter can efficiently report numDocs(). const int32_t SegmentInfos::FORMAT_DEL_COUNT = -6; - + /// This format adds the boolean hasProx to record if any fields in the segment store prox information (ie, have /// omitTermFreqAndPositions == false) const int32_t SegmentInfos::FORMAT_HAS_PROX = -7; - + /// This format adds optional commit userData storage. const int32_t SegmentInfos::FORMAT_USER_DATA = -8; - + /// This format adds optional per-segment string diagnostics storage, and switches userData to Map const int32_t SegmentInfos::FORMAT_DIAGNOSTICS = -9; - + /// This must always point to the most recent file format. const int32_t SegmentInfos::CURRENT_FORMAT = SegmentInfos::FORMAT_DIAGNOSTICS; - + /// Advanced configuration of retry logic in loading segments_N file. int32_t SegmentInfos::defaultGenFileRetryCount = 10; int32_t SegmentInfos::defaultGenFileRetryPauseMsec = 50; int32_t SegmentInfos::defaultGenLookaheadCount = 10; - + MapStringString SegmentInfos::singletonUserData; InfoStreamPtr SegmentInfos::infoStream; - + SegmentInfos::SegmentInfos() { userData = MapStringString::newInstance(); @@ -71,16 +71,16 @@ namespace Lucene counter = 0; version = MiscUtils::currentTimeMillis(); } - + SegmentInfos::~SegmentInfos() { } - + SegmentInfoPtr SegmentInfos::info(int32_t i) { return segmentInfos[i]; } - + int64_t SegmentInfos::getCurrentSegmentGeneration(HashSet files) { if (!files) @@ -93,7 +93,7 @@ namespace Lucene } return max; } - + int64_t SegmentInfos::getCurrentSegmentGeneration(DirectoryPtr directory) { try @@ -105,22 +105,22 @@ namespace Lucene return -1; } } - + String SegmentInfos::getCurrentSegmentFileName(HashSet files) { return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(files)); } - + String SegmentInfos::getCurrentSegmentFileName(DirectoryPtr directory) { return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(directory)); } - + String SegmentInfos::getCurrentSegmentFileName() { return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", lastGeneration); } - + int64_t SegmentInfos::generationFromSegmentsFileName(const String& fileName) { if (fileName == IndexFileNames::SEGMENTS()) @@ -131,28 +131,28 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"FileName '" + fileName + L"' is not a segments file")); return 0; } - + String SegmentInfos::getNextSegmentFileName() { return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation == -1 ? 1 : generation + 1); } - + void SegmentInfos::read(DirectoryPtr directory, const String& segmentFileName) { bool success = false; // clear any previous segments segmentInfos.clear(); - + ChecksumIndexInputPtr input(newLucene(directory->openInput(segmentFileName))); - + generation = generationFromSegmentsFileName(segmentFileName); lastGeneration = generation; LuceneException finally; try { int32_t format = input->readInt(); - + if (format < 0) // file contains explicit format info { if (format < CURRENT_FORMAT) @@ -162,10 +162,10 @@ namespace Lucene } else counter = format; - + for (int32_t i = input->readInt(); i > 0; --i) // read segmentInfos segmentInfos.add(newLucene(directory, format, input)); - + // in old format the version number may be at the end of the file if (format >= 0) { @@ -174,7 +174,7 @@ namespace Lucene else input->readLong(); // read version } - + if (format <= FORMAT_USER_DATA) { if (format <= FORMAT_DIAGNOSTICS) @@ -191,7 +191,7 @@ namespace Lucene } else userData.clear(); - + if (format <= FORMAT_CHECKSUM) { int64_t checksumNow = input->getChecksum(); @@ -199,42 +199,42 @@ namespace Lucene if (checksumNow != checksumThen) boost::throw_exception(CorruptIndexException(L"Checksum mismatch in segments file")); } - + success = true; } catch (LuceneException& e) { finally = e; } - + input->close(); - + // clear any segment infos we had loaded so we have a clean slate on retry if (!success) segmentInfos.clear(); - + finally.throwException(); } - + void SegmentInfos::read(DirectoryPtr directory) { lastGeneration = -1; generation = lastGeneration; newLucene(shared_from_this(), directory)->run(); } - + void SegmentInfos::write(DirectoryPtr directory) { String segmentFileName(getNextSegmentFileName()); - + // always advance the generation on write if (generation == -1) generation = 1; else ++generation; - + ChecksumIndexOutputPtr segnOutput(newLucene(directory->createOutput(segmentFileName))); - + bool success = false; LuceneException finally; try @@ -254,7 +254,7 @@ namespace Lucene { finally = e; } - + if (!success) { // We hit an exception above; try to close the file but suppress any exception @@ -266,7 +266,7 @@ namespace Lucene { // Suppress so we keep throwing the original exception } - + try { // try not to leave a truncated segments_n file in the index @@ -277,10 +277,10 @@ namespace Lucene // Suppress so we keep throwing the original exception } } - + finally.throwException(); } - + LuceneObjectPtr SegmentInfos::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = SegmentInfoCollection::clone(other ? other : newLucene()); @@ -296,94 +296,94 @@ namespace Lucene cloneInfos->userData.putAll(userData.begin(), userData.end()); return cloneInfos; } - + int64_t SegmentInfos::getVersion() { return version; } - + int64_t SegmentInfos::getGeneration() { return generation; } - + int64_t SegmentInfos::getLastGeneration() { return lastGeneration; } - + int64_t SegmentInfos::readCurrentVersion(DirectoryPtr directory) { - // Fully read the segments file: this ensures that it's completely written so that if IndexWriter.prepareCommit has been called + // Fully read the segments file: this ensures that it's completely written so that if IndexWriter.prepareCommit has been called // (but not yet commit), then the reader will still see itself as current. SegmentInfosPtr sis(newLucene()); sis->read(directory); return sis->getVersion(); } - + MapStringString SegmentInfos::readCurrentUserData(DirectoryPtr directory) { SegmentInfosPtr sis(newLucene()); sis->read(directory); return sis->getUserData(); } - + void SegmentInfos::setInfoStream(InfoStreamPtr infoStream) { SegmentInfos::infoStream = infoStream; } - + void SegmentInfos::setDefaultGenFileRetryCount(int32_t count) { defaultGenFileRetryCount = count; } - + int32_t SegmentInfos::getDefaultGenFileRetryCount() { return defaultGenFileRetryCount; } - + void SegmentInfos::setDefaultGenFileRetryPauseMsec(int32_t msec) { defaultGenFileRetryPauseMsec = msec; } - + int32_t SegmentInfos::getDefaultGenFileRetryPauseMsec() { return defaultGenFileRetryPauseMsec; } - + void SegmentInfos::setDefaultGenLookaheadCount(int32_t count) { defaultGenLookaheadCount = count; } - + int32_t SegmentInfos::getDefaultGenLookahedCount() { return defaultGenLookaheadCount; } - + InfoStreamPtr SegmentInfos::getInfoStream() { return infoStream; } - + void SegmentInfos::message(const String& message) { if (infoStream) *infoStream << L"SIS [" << message << L"]\n"; } - + FindSegmentsFile::FindSegmentsFile(SegmentInfosPtr infos, DirectoryPtr directory) { this->_segmentInfos = infos; this->directory = directory; } - + FindSegmentsFile::~FindSegmentsFile() { } - + void FindSegmentsFile::doRun(IndexCommitPtr commit) { if (commit) @@ -393,7 +393,7 @@ namespace Lucene runBody(commit->getSegmentsFileName()); return; } - + String segmentFileName; int64_t lastGen = -1; int64_t gen = 0; @@ -401,18 +401,18 @@ namespace Lucene bool retry = false; LuceneException exc; SegmentInfosPtr segmentInfos(_segmentInfos); - + int32_t method = 0; - + // Loop until we succeed in calling runBody() without hitting an IOException. An IOException most likely // means a commit was in process and has finished, in the time it took us to load the now-old infos files // (and segments files). It's also possible it's a true error (corrupt index). To distinguish these, - // on each retry we must see "forward progress" on which generation we are trying to load. If we don't, + // on each retry we must see "forward progress" on which generation we are trying to load. If we don't, // then the original error is real and we throw it. // We have three methods for determining the current generation. We try the first two in parallel, and // fall back to the third when necessary. - + while (true) { if (method == 0) @@ -443,7 +443,7 @@ namespace Lucene { segmentInfos->message(L"Segments.gen open: IOException " + e.getError()); } - + if (genInput) { LuceneException finally; @@ -477,26 +477,26 @@ namespace Lucene if (fileConsistent) break; } - + LuceneThread::threadSleep(SegmentInfos::defaultGenFileRetryPauseMsec); } - + segmentInfos->message(String(IndexFileNames::SEGMENTS_GEN()) + L" check: genB=" + StringUtils::toString(genB)); // pick the larger of the two gen's gen = std::max(genA, genB); - + // neither approach found a generation if (gen == -1) boost::throw_exception(FileNotFoundException(L"No segments* file found in directory")); } - + // Third method (fallback if first & second methods are not reliable): since both directory cache and // file contents cache seem to be stale, just advance the generation. if (method == 1 || (method == 0 && lastGen == gen && retry)) { method = 1; - + if (genLookaheadCount < SegmentInfos::defaultGenLookaheadCount) { ++gen; @@ -504,12 +504,12 @@ namespace Lucene segmentInfos->message(L"look ahead increment gen to " + StringUtils::toString(gen)); } } - + if (lastGen == gen) { - // This means we're about to try the same segments_N last tried. This is allowed, exactly once, because + // This means we're about to try the same segments_N last tried. This is allowed, exactly once, because // writer could have been in the process of writing segments_N last time. - + if (retry) { // OK, we've tried the same segments_N file twice in a row, so this must be a real error. @@ -523,11 +523,11 @@ namespace Lucene // Segment file has advanced since our last loop, so reset retry retry = false; } - + lastGen = gen; - + segmentFileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen); - + try { runBody(segmentFileName); @@ -539,19 +539,19 @@ namespace Lucene // Save the original root cause if (exc.isNull()) exc = err; - + segmentInfos->message(L"primary Exception on '" + segmentFileName + L"': " + err.getError() + L"'; will retry: retry=" + StringUtils::toString(retry) + L"; gen = " + StringUtils::toString(gen)); - + if (!retry && gen > 1) { - // This is our first time trying this segments file (because retry is false), and, there is possibly a + // This is our first time trying this segments file (because retry is false), and, there is possibly a // segments_(N-1) (because gen > 1). So, check if the segments_(N-1) exists and try it if so. String prevSegmentFileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen - 1)); - + if (directory->fileExists(prevSegmentFileName)) { segmentInfos->message(L"fallback to prior segment file '" + prevSegmentFileName + L"'"); - + try { runBody(prevSegmentFileName); @@ -568,48 +568,48 @@ namespace Lucene } } } - + FindSegmentsRead::FindSegmentsRead(SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) { result = 0; } - + FindSegmentsRead::~FindSegmentsRead() { } - + int64_t FindSegmentsRead::doBody(const String& segmentFileName) { SegmentInfosPtr(_segmentInfos)->read(directory, segmentFileName); return 0; } - + SegmentInfosPtr SegmentInfos::range(int32_t first, int32_t last) { SegmentInfosPtr infos(newLucene()); infos->segmentInfos.addAll(segmentInfos.begin() + first, segmentInfos.begin() + last); return infos; } - + void SegmentInfos::updateGeneration(SegmentInfosPtr other) { lastGeneration = other->lastGeneration; generation = other->generation; version = other->version; } - + void SegmentInfos::rollbackCommit(DirectoryPtr dir) { if (pendingSegnOutput) { - try + try { pendingSegnOutput->close(); } catch (...) { } - + // must carefully compute filename from "generation" since lastgeneration isn't incremented try { @@ -622,7 +622,7 @@ namespace Lucene pendingSegnOutput.reset(); } } - + void SegmentInfos::prepareCommit(DirectoryPtr dir) { TestScope testScope(L"SegmentInfos", L"prepareCommit"); @@ -630,7 +630,7 @@ namespace Lucene boost::throw_exception(IllegalStateException(L"prepareCommit was already called")); write(dir); } - + HashSet SegmentInfos::files(DirectoryPtr dir, bool includeSegmentsFile) { HashSet files(HashSet::newInstance()); @@ -646,12 +646,12 @@ namespace Lucene } return files; } - + void SegmentInfos::finishCommit(DirectoryPtr dir) { if (!pendingSegnOutput) boost::throw_exception(IllegalStateException(L"prepareCommit was not called")); - + bool success = false; LuceneException finally; try @@ -665,19 +665,19 @@ namespace Lucene { finally = e; } - + if (!success) rollbackCommit(dir); finally.throwException(); - + // NOTE: if we crash here, we have left a segments_N file in the directory in a possibly corrupt state (if // some bytes made it to stable storage and others didn't). But, the segments_N file includes checksum - // at the end, which should catch this case. So when a reader tries to read it, it will throw a + // at the end, which should catch this case. So when a reader tries to read it, it will throw a // CorruptIndexException, which should cause the retry logic in SegmentInfos to kick in and load the last // good (previous) segments_N-1 file. - + String fileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation)); - + success = false; try { @@ -687,16 +687,16 @@ namespace Lucene catch (...) { } - + if (!success) dir->deleteFile(fileName); - + lastGeneration = generation; IndexOutputPtr genOutput; try { genOutput = dir->createOutput(IndexFileNames::SEGMENTS_GEN()); - + try { genOutput->writeInt(FORMAT_LOCKLESS); @@ -707,7 +707,7 @@ namespace Lucene { finally = e; } - + genOutput->close(); finally.throwException(); } @@ -715,13 +715,13 @@ namespace Lucene { } } - + void SegmentInfos::commit(DirectoryPtr dir) { prepareCommit(dir); finishCommit(dir); } - + String SegmentInfos::segString(DirectoryPtr directory) { SyncLock syncLock(this); @@ -736,12 +736,12 @@ namespace Lucene } return buffer; } - + MapStringString SegmentInfos::getUserData() { return userData; } - + void SegmentInfos::setUserData(MapStringString data) { if (!data) @@ -749,14 +749,14 @@ namespace Lucene else userData = data; } - + void SegmentInfos::replace(SegmentInfosPtr other) { segmentInfos.clear(); segmentInfos.addAll(other->segmentInfos.begin(), other->segmentInfos.end()); lastGeneration = other->lastGeneration; } - + bool SegmentInfos::hasExternalSegments(DirectoryPtr dir) { for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) diff --git a/src/core/index/SegmentMergeInfo.cpp b/src/core/index/SegmentMergeInfo.cpp index 967e9b5c..9beb4212 100644 --- a/src/core/index/SegmentMergeInfo.cpp +++ b/src/core/index/SegmentMergeInfo.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,19 +21,19 @@ namespace Lucene ord = 0; delCount = 0; } - + SegmentMergeInfo::~SegmentMergeInfo() { } - + Collection SegmentMergeInfo::getDocMap() { if (!docMap) { delCount = 0; IndexReaderPtr reader(_reader); - - // build array which maps document numbers around deletions + + // build array which maps document numbers around deletions if (reader->hasDeletions()) { int32_t maxDoc = reader->maxDoc(); @@ -53,14 +53,14 @@ namespace Lucene } return docMap; } - + TermPositionsPtr SegmentMergeInfo::getPositions() { if (!postings) postings = IndexReaderPtr(_reader)->termPositions(); return postings; } - + bool SegmentMergeInfo::next() { if (termEnum->next()) @@ -74,7 +74,7 @@ namespace Lucene return false; } } - + void SegmentMergeInfo::close() { termEnum->close(); diff --git a/src/core/index/SegmentMergeQueue.cpp b/src/core/index/SegmentMergeQueue.cpp index 6d1933ec..257f8f37 100644 --- a/src/core/index/SegmentMergeQueue.cpp +++ b/src/core/index/SegmentMergeQueue.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,17 +13,17 @@ namespace Lucene SegmentMergeQueue::SegmentMergeQueue(int32_t size) : PriorityQueue(size) { } - + SegmentMergeQueue::~SegmentMergeQueue() { } - + void SegmentMergeQueue::close() { while (top()) pop()->close(); } - + bool SegmentMergeQueue::lessThan(const SegmentMergeInfoPtr& first, const SegmentMergeInfoPtr& second) { int32_t comparison = first->term->compareTo(second->term); diff --git a/src/core/index/SegmentMerger.cpp b/src/core/index/SegmentMerger.cpp index 41f4dc56..bdbdca02 100644 --- a/src/core/index/SegmentMerger.cpp +++ b/src/core/index/SegmentMerger.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -36,11 +36,11 @@ namespace Lucene { /// Maximum number of contiguous documents to bulk-copy when merging stored fields const int32_t SegmentMerger::MAX_RAW_MERGE_DOCS = 4192; - + /// norms header placeholder const uint8_t SegmentMerger::NORMS_HEADER[] = {'N', 'R', 'M', static_cast(-1) }; const int32_t SegmentMerger::NORMS_HEADER_LENGTH = 4; - + SegmentMerger::SegmentMerger(DirectoryPtr dir, const String& name) { readers = Collection::newInstance(); @@ -48,29 +48,29 @@ namespace Lucene mergedDocs = 0; mergeDocStores = false; omitTermFreqAndPositions = false; - + directory = dir; segment = name; checkAbort = newLucene(); } - + SegmentMerger::SegmentMerger(IndexWriterPtr writer, const String& name, OneMergePtr merge) { readers = Collection::newInstance(); mergedDocs = 0; mergeDocStores = false; omitTermFreqAndPositions = false; - + directory = writer->getDirectory(); segment = name; - + if (merge) checkAbort = newLucene(merge, directory); else checkAbort = newLucene(); termIndexInterval = writer->getTermIndexInterval(); } - + SegmentMerger::~SegmentMerger() { } @@ -79,59 +79,59 @@ namespace Lucene { return fieldInfos->hasProx(); } - + void SegmentMerger::add(IndexReaderPtr reader) { readers.add(reader); } - + IndexReaderPtr SegmentMerger::segmentReader(int32_t i) { return readers[i]; } - + int32_t SegmentMerger::merge() { return merge(true); } - + int32_t SegmentMerger::merge(bool mergeDocStores) { this->mergeDocStores = mergeDocStores; - - // NOTE: it's important to add calls to checkAbort.work(...) if you make any changes to this method that will spend a lot of time. + + // NOTE: it's important to add calls to checkAbort.work(...) if you make any changes to this method that will spend a lot of time. // The frequency of this check impacts how long IndexWriter.close(false) takes to actually stop the threads. - + mergedDocs = mergeFields(); mergeTerms(); mergeNorms(); - + if (mergeDocStores && fieldInfos->hasVectors()) mergeVectors(); - + return mergedDocs; } - + void SegmentMerger::closeReaders() { for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) (*reader)->close(); } - + HashSet SegmentMerger::getMergedFiles() { HashSet fileSet(HashSet::newInstance()); - + // Basic files for (HashSet::iterator ext = IndexFileNames::COMPOUND_EXTENSIONS().begin(); ext != IndexFileNames::COMPOUND_EXTENSIONS().end(); ++ext) { if (*ext == IndexFileNames::PROX_EXTENSION() && !hasProx()) continue; - + if (mergeDocStores || (*ext != IndexFileNames::FIELDS_EXTENSION() && *ext != IndexFileNames::FIELDS_INDEX_EXTENSION())) fileSet.add(segment + L"." + *ext); } - + // Fieldable norm files for (int32_t i = 0; i < fieldInfos->size(); ++i) { @@ -142,51 +142,51 @@ namespace Lucene break; } } - + // Vector files if (fieldInfos->hasVectors() && mergeDocStores) { for (HashSet::iterator ext = IndexFileNames::VECTOR_EXTENSIONS().begin(); ext != IndexFileNames::VECTOR_EXTENSIONS().end(); ++ext) fileSet.add(segment + L"." + *ext); } - + return fileSet; } - + HashSet SegmentMerger::createCompoundFile(const String& fileName) { HashSet files(getMergedFiles()); CompoundFileWriterPtr cfsWriter(newLucene(directory, fileName, checkAbort)); - + // Now merge all added files for (HashSet::iterator file = files.begin(); file != files.end(); ++file) cfsWriter->addFile(*file); - + // Perform the merge cfsWriter->close(); - + return files; } - - void SegmentMerger::addIndexed(IndexReaderPtr reader, FieldInfosPtr fInfos, HashSet names, - bool storeTermVectors, bool storePositionWithTermVector, + + void SegmentMerger::addIndexed(IndexReaderPtr reader, FieldInfosPtr fInfos, HashSet names, + bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool storePayloads, bool omitTFAndPositions) { for (HashSet::iterator field = names.begin(); field != names.end(); ++field) { - fInfos->add(*field, true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector, + fInfos->add(*field, true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector, !reader->hasNorms(*field), storePayloads, omitTFAndPositions); } } void SegmentMerger::setMatchingSegmentReaders() { - // If the i'th reader is a SegmentReader and has identical fieldName -> number mapping, then + // If the i'th reader is a SegmentReader and has identical fieldName -> number mapping, then // this array will be non-null at position i int32_t numReaders = readers.size(); matchingSegmentReaders = Collection::newInstance(numReaders); - - // If this reader is a SegmentReader, and all of its field name -> number mappings match the + + // If this reader is a SegmentReader, and all of its field name -> number mappings match the // "merged" FieldInfos, then we can do a bulk copy of the stored fields for (int32_t i = 0; i < numReaders; ++i) { @@ -203,7 +203,7 @@ namespace Lucene matchingSegmentReaders[i] = segmentReader; } } - + // Used for bulk-reading raw bytes for stored fields rawDocLengths = Collection::newInstance(MAX_RAW_MERGE_DOCS); rawDocLengths2 = Collection::newInstance(MAX_RAW_MERGE_DOCS); @@ -213,13 +213,13 @@ namespace Lucene { if (!mergeDocStores) { - // When we are not merging by doc stores, their field name -> number mapping are the same. + // When we are not merging by doc stores, their field name -> number mapping are the same. // So, we start with the fieldInfos of the last segment in this case, to keep that numbering fieldInfos = boost::dynamic_pointer_cast(boost::dynamic_pointer_cast(readers[readers.size() - 1])->core->fieldInfos->clone()); } else fieldInfos = newLucene(); // merge field names - + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(*reader)); @@ -230,8 +230,8 @@ namespace Lucene for (int32_t j = 0; j < numReaderFieldInfos; ++j) { FieldInfoPtr fi(readerFieldInfos->fieldInfo(j)); - fieldInfos->add(fi->name, fi->isIndexed, fi->storeTermVector, fi->storePositionWithTermVector, - fi->storeOffsetWithTermVector, !(*reader)->hasNorms(fi->name), fi->storePayloads, + fieldInfos->add(fi->name, fi->isIndexed, fi->storeTermVector, fi->storePositionWithTermVector, + fi->storeOffsetWithTermVector, !(*reader)->hasNorms(fi->name), fi->storePayloads, fi->omitTermFreqAndPositions); } } @@ -248,16 +248,16 @@ namespace Lucene } } fieldInfos->write(directory, segment + L".fnm"); - + int32_t docCount = 0; - + setMatchingSegmentReaders(); - + if (mergeDocStores) { // merge field values FieldsWriterPtr fieldsWriter(newLucene(directory, segment, fieldInfos)); - + LuceneException finally; try { @@ -284,27 +284,27 @@ namespace Lucene } fieldsWriter->close(); finally.throwException(); - + String fileName(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); int64_t fdxFileLength = directory->fileLength(fileName); - + if (4 + ((int64_t)docCount) * 8 != fdxFileLength) { - boost::throw_exception(RuntimeException(L"mergeFields produced an invalid result: docCount is " + - StringUtils::toString(docCount) + L" but fdx file size is " + - StringUtils::toString(fdxFileLength) + L" file=" + fileName + - L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + + boost::throw_exception(RuntimeException(L"mergeFields produced an invalid result: docCount is " + + StringUtils::toString(docCount) + L" but fdx file size is " + + StringUtils::toString(fdxFileLength) + L" file=" + fileName + + L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + L"; now aborting this merge to prevent index corruption")); } } else { - // If we are skipping the doc stores, that means there are no deletions in any of these segments, + // If we are skipping the doc stores, that means there are no deletions in any of these segments, // so we just sum numDocs() of each segment to get total docCount for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) docCount += (*reader)->numDocs(); } - + return docCount; } @@ -339,7 +339,7 @@ namespace Lucene } } while (numDocs < MAX_RAW_MERGE_DOCS); - + IndexInputPtr stream(matchingFieldsReader->rawDocs(rawDocLengths, start, numDocs)); fieldsWriter->addRawDocuments(stream, rawDocLengths, numDocs); docCount += numDocs; @@ -355,7 +355,7 @@ namespace Lucene // skip deleted docs continue; } - + // NOTE: it's very important to first assign to doc then pass it to termVectorsWriter.addAllDocVectors fieldsWriter->addDocument(reader->document(j)); ++docCount; @@ -364,7 +364,7 @@ namespace Lucene } return docCount; } - + int32_t SegmentMerger::copyFieldsNoDeletions(FieldsWriterPtr fieldsWriter, IndexReaderPtr reader, FieldsReaderPtr matchingFieldsReader) { int32_t docCount = 0; @@ -396,7 +396,7 @@ namespace Lucene void SegmentMerger::mergeVectors() { TermVectorsWriterPtr termVectorsWriter(newLucene(directory, segment, fieldInfos)); - + LuceneException finally; try { @@ -408,7 +408,7 @@ namespace Lucene if (matchingSegmentReader) { TermVectorsReaderPtr vectorsReader(matchingSegmentReader->getTermVectorsReaderOrig()); - + // If the TV* files are an older format then they cannot read raw docs if (vectorsReader && vectorsReader->canReadRawDocs()) matchingVectorsReader = vectorsReader; @@ -425,20 +425,20 @@ namespace Lucene } termVectorsWriter->close(); finally.throwException(); - + String fileName(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); int64_t tvxSize = directory->fileLength(fileName); - + if (4 + ((int64_t)mergedDocs) * 16 != tvxSize) { - boost::throw_exception(RuntimeException(L"mergeVectors produced an invalid result: mergedDocs is " + - StringUtils::toString(mergedDocs) + L" but tvx size is " + - StringUtils::toString(tvxSize) + L" file=" + fileName + - L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + + boost::throw_exception(RuntimeException(L"mergeVectors produced an invalid result: mergedDocs is " + + StringUtils::toString(mergedDocs) + L" but tvx size is " + + StringUtils::toString(tvxSize) + L" file=" + fileName + + L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + L"; now aborting this merge to prevent index corruption")); } } - + void SegmentMerger::copyVectorsWithDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader) { int32_t maxDoc = reader->maxDoc(); @@ -469,7 +469,7 @@ namespace Lucene } } while (numDocs < MAX_RAW_MERGE_DOCS); - + matchingVectorsReader->rawDocs(rawDocLengths, rawDocLengths2, start, numDocs); termVectorsWriter->addRawDocuments(matchingVectorsReader, rawDocLengths, rawDocLengths2, numDocs); checkAbort->work(300 * numDocs); @@ -484,14 +484,14 @@ namespace Lucene // skip deleted docs continue; } - + // NOTE: it's very important to first assign to vectors then pass it to termVectorsWriter.addAllDocVectors termVectorsWriter->addAllDocVectors(reader->getTermFreqVectors(docNum)); checkAbort->work(300); } } } - + void SegmentMerger::copyVectorsNoDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader) { int32_t maxDoc = reader->maxDoc(); @@ -522,7 +522,7 @@ namespace Lucene void SegmentMerger::mergeTerms() { TestScope testScope(L"SegmentMerger", L"mergeTerms"); - + SegmentWriteStatePtr state(newLucene(DocumentsWriterPtr(), directory, segment, L"", mergedDocs, 0, termIndexInterval)); FormatPostingsFieldsConsumerPtr consumer(newLucene(state, fieldInfos)); @@ -542,7 +542,7 @@ namespace Lucene queue->close(); finally.throwException(); } - + void SegmentMerger::mergeTermInfos(FormatPostingsFieldsConsumerPtr consumer) { int32_t base = 0; @@ -564,35 +564,35 @@ namespace Lucene IndexReaderPtr segmentMergeReader(smi->_reader); delCounts[i] = segmentMergeReader->maxDoc() - segmentMergeReader->numDocs(); } - + base += reader->numDocs(); - + BOOST_ASSERT(reader->numDocs() == reader->maxDoc() - smi->delCount); - + if (smi->next()) queue->add(smi); // initialize queue else smi->close(); } - + Collection match(Collection::newInstance(readers.size())); - + String currentField; FormatPostingsTermsConsumerPtr termsConsumer; - + while (!queue->empty()) { int32_t matchSize = 0; // pop matching terms match[matchSize++] = queue->pop(); TermPtr term(match[0]->term); SegmentMergeInfoPtr top(queue->empty() ? SegmentMergeInfoPtr() : queue->top()); - + while (top && term->compareTo(top->term) == 0) { match[matchSize++] = queue->pop(); top = queue->top(); } - + if (currentField != term->_field) { currentField = term->_field; @@ -602,11 +602,11 @@ namespace Lucene termsConsumer = consumer->addField(fieldInfo); omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; } - + int32_t df = appendPostings(termsConsumer, match, matchSize); // add new TermInfo - + checkAbort->work(df / 3.0); - + while (matchSize > 0) { SegmentMergeInfoPtr smi(match[--matchSize]); @@ -617,17 +617,17 @@ namespace Lucene } } } - + Collection< Collection > SegmentMerger::getDocMaps() { return docMaps; } - + Collection SegmentMerger::getDelCounts() { return delCounts; } - + int32_t SegmentMerger::appendPostings(FormatPostingsTermsConsumerPtr termsConsumer, Collection smis, int32_t n) { FormatPostingsDocsConsumerPtr docConsumer(termsConsumer->addTerm(smis[0]->term->_text)); @@ -640,7 +640,7 @@ namespace Lucene int32_t base = smi->base; Collection docMap(smi->getDocMap()); postings->seek(smi->termEnum); - + while (postings->next()) { ++df; @@ -648,10 +648,10 @@ namespace Lucene if (docMap) doc = docMap[doc]; // map around deletions doc += base; // convert to merged space - + int32_t freq = postings->freq(); FormatPostingsPositionsConsumerPtr posConsumer(docConsumer->addDoc(doc, freq)); - + if (!omitTermFreqAndPositions) { for (int32_t j = 0; j < freq; ++j) @@ -673,7 +673,7 @@ namespace Lucene } } docConsumer->finish(); - + return df; } @@ -698,7 +698,7 @@ namespace Lucene for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { int32_t maxDoc = (*reader)->maxDoc(); - + if (!normBuffer) normBuffer = ByteArray::newInstance(maxDoc); if (normBuffer.size() < maxDoc) // the buffer is too small for the current segment @@ -739,11 +739,11 @@ namespace Lucene this->merge = merge; this->_dir = dir; } - + CheckAbort::~CheckAbort() { } - + void CheckAbort::work(double units) { workCount += units; @@ -753,15 +753,15 @@ namespace Lucene workCount = 0; } } - + CheckAbortNull::CheckAbortNull() : CheckAbort(OneMergePtr(), DirectoryPtr()) { } - + CheckAbortNull::~CheckAbortNull() { } - + void CheckAbortNull::work(double units) { // do nothing diff --git a/src/core/index/SegmentReader.cpp b/src/core/index/SegmentReader.cpp index d9d1b795..0e559357 100644 --- a/src/core/index/SegmentReader.cpp +++ b/src/core/index/SegmentReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -41,33 +41,33 @@ namespace Lucene rollbackHasChanges = false; rollbackDeletedDocsDirty = false; rollbackNormsDirty = false; - + readBufferSize = 0; pendingDeleteCount = 0; rollbackPendingDeleteCount = 0; } - + SegmentReader::~SegmentReader() { } - + void SegmentReader::initialize() { fieldsReaderLocal = newLucene(shared_from_this()); } - + SegmentReaderPtr SegmentReader::get(bool readOnly, SegmentInfoPtr si, int32_t termInfosIndexDivisor) { return get(readOnly, si->dir, si, BufferedIndexInput::BUFFER_SIZE, true, termInfosIndexDivisor); } - + SegmentReaderPtr SegmentReader::get(bool readOnly, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor) { SegmentReaderPtr instance(readOnly ? newLucene() : newLucene()); instance->readOnly = readOnly; instance->si = si; instance->readBufferSize = readBufferSize; - + bool success = false; LuceneException finally; try @@ -83,20 +83,20 @@ namespace Lucene { finally = e; } - - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. + + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. // In this case, we want to explicitly close any subset of things that were opened if (!success) - instance->doClose(); + instance->doClose(); finally.throwException(); return instance; } - + void SegmentReader::openDocStores() { core->openDocStores(si); } - + bool SegmentReader::checkDeletedCounts() { int32_t recomputedCount = deletedDocs->getRecomputedCount(); @@ -107,10 +107,10 @@ namespace Lucene // Verify # deletes does not exceed maxDoc for this segment BOOST_ASSERT(si->getDelCount() <= maxDoc()); - + return true; } - + void SegmentReader::loadDeletedDocs() { // NOTE: the bitvector is stored using the regular directory, not cfs @@ -123,19 +123,19 @@ namespace Lucene else BOOST_ASSERT(si->getDelCount() == 0); } - + ByteArray SegmentReader::cloneNormBytes(ByteArray bytes) { ByteArray cloneBytes(ByteArray::newInstance(bytes.size())); MiscUtils::arrayCopy(bytes.get(), 0, cloneBytes.get(), 0, bytes.size()); return cloneBytes; } - + BitVectorPtr SegmentReader::cloneDeletedDocs(BitVectorPtr bv) { return boost::dynamic_pointer_cast(bv->clone()); } - + LuceneObjectPtr SegmentReader::clone(LuceneObjectPtr other) { try @@ -148,23 +148,23 @@ namespace Lucene } return LuceneObjectPtr(); } - + LuceneObjectPtr SegmentReader::clone(bool openReadOnly, LuceneObjectPtr other) { SyncLock syncLock(this); return reopenSegment(si, true, openReadOnly); } - + SegmentReaderPtr SegmentReader::reopenSegment(SegmentInfoPtr si, bool doClone, bool openReadOnly) { SyncLock syncLock(this); - - bool deletionsUpToDate = (this->si->hasDeletions() == si->hasDeletions() && + + bool deletionsUpToDate = (this->si->hasDeletions() == si->hasDeletions() && (!si->hasDeletions() || this->si->getDelFileName() == si->getDelFileName())); bool normsUpToDate = true; int32_t fieldCount = core->fieldInfos->size(); Collection fieldNormsChanged(Collection::newInstance(fieldCount)); - + for (int32_t i = 0; i < fieldCount; ++i) { if (this->si->getNormFileName(i) != si->getNormFileName(i)) @@ -173,18 +173,18 @@ namespace Lucene fieldNormsChanged[i] = true; } } - - // if we're cloning we need to run through the reopenSegment logic also if both old and new readers + + // if we're cloning we need to run through the reopenSegment logic also if both old and new readers // aren't readonly, we clone to avoid sharing modifications if (normsUpToDate && deletionsUpToDate && !doClone && openReadOnly && readOnly) return shared_from_this(); - + // When cloning, the incoming SegmentInfos should not have any changes in it BOOST_ASSERT(!doClone || (normsUpToDate && deletionsUpToDate)); - + // clone reader SegmentReaderPtr clone(openReadOnly ? newLucene() : newLucene()); - + bool success = false; LuceneException finally; try @@ -194,7 +194,7 @@ namespace Lucene clone->readOnly = openReadOnly; clone->si = si; clone->readBufferSize = readBufferSize; - + if (!openReadOnly && _hasChanges) { // My pending changes transfer to the new reader @@ -204,7 +204,7 @@ namespace Lucene clone->_hasChanges = _hasChanges; _hasChanges = false; } - + if (doClone) { if (deletedDocs) @@ -229,9 +229,9 @@ namespace Lucene clone->deletedDocsRef = deletedDocsRef; } } - + clone->_norms = MapStringNorm::newInstance(); - + // Clone norms for (int32_t i = 0; i < fieldNormsChanged.size(); ++i) { @@ -248,10 +248,10 @@ namespace Lucene } } } - + // If we are not cloning, then this will open anew any norms that have changed clone->openNorms(si->getUseCompoundFile() ? core->getCFSReader() : directory(), readBufferSize); - + success = true; } catch (LuceneException& e) @@ -260,14 +260,14 @@ namespace Lucene } if (!success) { - // An exception occurred during reopen, we have to decRef the norms that we incRef'ed already + // An exception occurred during reopen, we have to decRef the norms that we incRef'ed already // and close singleNormsStream and FieldsReader clone->decRef(); } finally.throwException(); return clone; } - + void SegmentReader::doCommit(MapStringString commitUserData) { if (_hasChanges) @@ -289,17 +289,17 @@ namespace Lucene finally.throwException(); } } - + void SegmentReader::commitChanges(MapStringString commitUserData) { if (deletedDocsDirty) // re-write deleted { si->advanceDelGen(); - - // We can write directly to the actual name (vs to a .tmp & renaming it) because the file + + // We can write directly to the actual name (vs to a .tmp & renaming it) because the file // is not live until segments file is written String delFileName(si->getDelFileName()); - + bool success = false; LuceneException finally; try @@ -323,7 +323,7 @@ namespace Lucene } } finally.throwException(); - + si->setDelCount(si->getDelCount() + pendingDeleteCount); pendingDeleteCount = 0; BOOST_ASSERT(deletedDocs->count() == si->getDelCount()); // delete count mismatch during commit? @@ -332,7 +332,7 @@ namespace Lucene { BOOST_ASSERT(pendingDeleteCount == 0); } - + if (normsDirty) // re-write norms { si->setNumFields(core->fieldInfos->size()); @@ -346,12 +346,12 @@ namespace Lucene normsDirty = false; _hasChanges = false; } - + FieldsReaderPtr SegmentReader::getFieldsReader() { return fieldsReaderLocal->get(); } - + void SegmentReader::doClose() { termVectorsLocal.close(); @@ -366,29 +366,29 @@ namespace Lucene if (core) core->decRef(); } - + bool SegmentReader::hasDeletions(SegmentInfoPtr si) { // Don't call ensureOpen() here (it could affect performance) return si->hasDeletions(); } - + bool SegmentReader::hasDeletions() { // Don't call ensureOpen() here (it could affect performance) return deletedDocs.get() != NULL; } - + bool SegmentReader::usesCompoundFile(SegmentInfoPtr si) { return si->getUseCompoundFile(); } - + bool SegmentReader::hasSeparateNorms(SegmentInfoPtr si) { return si->hasSeparateNorms(); } - + void SegmentReader::doDelete(int32_t docNum) { if (!deletedDocs) @@ -396,7 +396,7 @@ namespace Lucene deletedDocs = newLucene(maxDoc()); deletedDocsRef = newLucene(); } - // there is more than 1 SegmentReader with a reference to this deletedDocs BitVector so decRef + // there is more than 1 SegmentReader with a reference to this deletedDocs BitVector so decRef // the current deletedDocsRef, clone the BitVector, create a new deletedDocsRef if (deletedDocsRef->refCount() > 1) { @@ -409,7 +409,7 @@ namespace Lucene if (!deletedDocs->getAndSet(docNum)) ++pendingDeleteCount; } - + void SegmentReader::doUndeleteAll() { deletedDocsDirty = false; @@ -429,41 +429,41 @@ namespace Lucene BOOST_ASSERT(pendingDeleteCount == 0); } } - + HashSet SegmentReader::files() { return si->files(); } - + TermEnumPtr SegmentReader::terms() { ensureOpen(); return core->getTermsReader()->terms(); } - + TermEnumPtr SegmentReader::terms(TermPtr t) { ensureOpen(); return core->getTermsReader()->terms(t); } - + FieldInfosPtr SegmentReader::fieldInfos() { return core->fieldInfos; } - + DocumentPtr SegmentReader::document(int32_t n, FieldSelectorPtr fieldSelector) { ensureOpen(); return getFieldsReader()->doc(n, fieldSelector); } - + bool SegmentReader::isDeleted(int32_t n) { SyncLock syncLock(this); return (deletedDocs && deletedDocs->get(n)); } - + TermDocsPtr SegmentReader::termDocs(TermPtr term) { if (!term) @@ -471,26 +471,26 @@ namespace Lucene else return IndexReader::termDocs(term); } - + TermDocsPtr SegmentReader::termDocs() { ensureOpen(); return newLucene(shared_from_this()); } - + TermPositionsPtr SegmentReader::termPositions() { ensureOpen(); return newLucene(shared_from_this()); } - + int32_t SegmentReader::docFreq(TermPtr t) { ensureOpen(); TermInfoPtr ti(core->getTermsReader()->get(t)); return ti ? ti->docFreq : 0; } - + int32_t SegmentReader::numDocs() { // Don't call ensureOpen() here (it could affect performance) @@ -499,13 +499,13 @@ namespace Lucene n -= deletedDocs->count(); return n; } - + int32_t SegmentReader::maxDoc() { // Don't call ensureOpen() here (it could affect performance) return si->docCount; } - + HashSet SegmentReader::getFieldNames(FieldOption fieldOption) { ensureOpen(); @@ -538,41 +538,41 @@ namespace Lucene } return fieldSet; } - + bool SegmentReader::hasNorms(const String& field) { SyncLock syncLock(this); ensureOpen(); return _norms.contains(field); } - + ByteArray SegmentReader::getNorms(const String& field) { SyncLock syncLock(this); NormPtr norm(_norms.get(field)); return norm ? norm->bytes() : ByteArray(); } - + ByteArray SegmentReader::norms(const String& field) { SyncLock syncLock(this); ensureOpen(); return getNorms(field); } - + void SegmentReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { NormPtr norm(_norms.get(field)); if (!norm) // not an indexed field return; - + normsDirty = true; ByteArray bytes(norm->copyOnWrite()); if (doc < 0 || doc >= bytes.size()) boost::throw_exception(IndexOutOfBoundsException()); bytes[doc] = value; // set the value } - + void SegmentReader::norms(const String& field, ByteArray norms, int32_t offset) { SyncLock syncLock(this); @@ -583,10 +583,10 @@ namespace Lucene MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); return; } - + norm->bytes(norms.get(), offset, maxDoc()); } - + void SegmentReader::openNorms(DirectoryPtr cfsDir, int32_t readBufferSize) { int64_t nextNormSeek = SegmentMerger::NORMS_HEADER_LENGTH; // skip header (header unused for now) @@ -596,7 +596,7 @@ namespace Lucene FieldInfoPtr fi(core->fieldInfos->fieldInfo(i)); if (_norms.contains(fi->name)) { - // in case this SegmentReader is being re-opened, we might be able to reuse some norm + // in case this SegmentReader is being re-opened, we might be able to reuse some norm // instances and skip loading them here continue; } @@ -606,12 +606,12 @@ namespace Lucene String fileName(si->getNormFileName(fi->number)); if (!si->hasSeparateNorms(fi->number)) d = cfsDir; - + // singleNormFile means multiple norms share this file bool singleNormFile = boost::ends_with(fileName, String(L".") + IndexFileNames::NORMS_EXTENSION()); IndexInputPtr normInput; int64_t normSeek; - + if (singleNormFile) { normSeek = nextNormSeek; @@ -622,8 +622,8 @@ namespace Lucene } else singleNormRef->incRef(); - - // All norms in the .nrm file can share a single IndexInput since they are only used in + + // All norms in the .nrm file can share a single IndexInput since they are only used in // a synchronized context. If this were to change in the future, a clone could be done here. normInput = singleNormStream; } @@ -632,23 +632,23 @@ namespace Lucene normSeek = 0; normInput = d->openInput(fileName); } - + _norms.put(fi->name, newLucene(shared_from_this(), normInput, fi->number, normSeek)); nextNormSeek += _maxDoc; // increment also if some norms are separate } } } - + bool SegmentReader::termsIndexLoaded() { return core->termsIndexIsLoaded(); } - + void SegmentReader::loadTermsIndex(int32_t termsIndexDivisor) { core->loadTermsIndex(si, termsIndexDivisor); } - + bool SegmentReader::normsClosed() { if (singleNormStream) @@ -660,12 +660,12 @@ namespace Lucene } return true; } - + bool SegmentReader::normsClosed(const String& field) { return (_norms.get(field)->refCount == 0); } - + TermVectorsReaderPtr SegmentReader::getTermVectorsReader() { TermVectorsReaderPtr tvReader(termVectorsLocal.get()); @@ -689,12 +689,12 @@ namespace Lucene } return tvReader; } - + TermVectorsReaderPtr SegmentReader::getTermVectorsReaderOrig() { return core->getTermVectorsReaderOrig(); } - + TermFreqVectorPtr SegmentReader::getTermFreqVector(int32_t docNumber, const String& field) { // Check if this field is invalid or has no stored term vector @@ -702,65 +702,65 @@ namespace Lucene FieldInfoPtr fi(core->fieldInfos->fieldInfo(field)); if (!fi || !fi->storeTermVector) return TermFreqVectorPtr(); - + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); if (!termVectorsReader) return TermFreqVectorPtr(); - + return termVectorsReader->get(docNumber, field); } - + void SegmentReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) { ensureOpen(); FieldInfoPtr fi(core->fieldInfos->fieldInfo(field)); if (!fi || !fi->storeTermVector) return; - + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); if (!termVectorsReader) return; - + termVectorsReader->get(docNumber, field, mapper); } - + void SegmentReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) { ensureOpen(); - + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); if (!termVectorsReader) return; - + termVectorsReader->get(docNumber, mapper); } - + Collection SegmentReader::getTermFreqVectors(int32_t docNumber) { ensureOpen(); - + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); if (!termVectorsReader) return Collection(); - + return termVectorsReader->get(docNumber); } - + String SegmentReader::getSegmentName() { return core->segment; } - + SegmentInfoPtr SegmentReader::getSegmentInfo() { return si; } - + void SegmentReader::setSegmentInfo(SegmentInfoPtr info) { si = info; } - + void SegmentReader::startCommit() { rollbackSegmentInfo = boost::dynamic_pointer_cast(si->clone()); @@ -771,7 +771,7 @@ namespace Lucene for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) norm->second->rollbackDirty = norm->second->dirty; } - + void SegmentReader::rollbackCommit() { si->reset(rollbackSegmentInfo); @@ -782,40 +782,40 @@ namespace Lucene for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) norm->second->dirty = norm->second->rollbackDirty; } - + DirectoryPtr SegmentReader::directory() { - // Don't ensureOpen here - in certain cases, when a cloned/reopened reader needs to commit, + // Don't ensureOpen here - in certain cases, when a cloned/reopened reader needs to commit, // it may call this method on the closed original reader return core->dir; } - + LuceneObjectPtr SegmentReader::getFieldCacheKey() { return core->freqStream; } - + LuceneObjectPtr SegmentReader::getDeletesCacheKey() { return deletedDocs; } - + int64_t SegmentReader::getUniqueTermCount() { return core->getTermsReader()->size(); } - + SegmentReaderPtr SegmentReader::getOnlySegmentReader(DirectoryPtr dir) { return getOnlySegmentReader(IndexReader::open(dir, false)); } - + SegmentReaderPtr SegmentReader::getOnlySegmentReader(IndexReaderPtr reader) { SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(reader)); if (segmentReader) return segmentReader; - + DirectoryReaderPtr directoryReader(boost::dynamic_pointer_cast(reader)); if (directoryReader) { @@ -824,25 +824,25 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"reader has " + StringUtils::toString(subReaders.size()) + L" segments instead of exactly one")); return boost::dynamic_pointer_cast(subReaders[0]); } - + boost::throw_exception(IllegalArgumentException(L"reader is not a SegmentReader or a single-segment DirectoryReader")); - + return SegmentReaderPtr(); } - + int32_t SegmentReader::getTermInfosIndexDivisor() { return core->termsIndexDivisor; } - + CoreReaders::CoreReaders(SegmentReaderPtr origInstance, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, int32_t termsIndexDivisor) { ref = newLucene(); - + segment = si->name; this->readBufferSize = readBufferSize; this->dir = dir; - + bool success = false; LuceneException finally; try @@ -854,23 +854,23 @@ namespace Lucene dir0 = cfsReader; } cfsDir = dir0; - + fieldInfos = newLucene(cfsDir, segment + L"." + IndexFileNames::FIELD_INFOS_EXTENSION()); - + this->termsIndexDivisor = termsIndexDivisor; TermInfosReaderPtr reader(newLucene(cfsDir, segment, fieldInfos, readBufferSize, termsIndexDivisor)); if (termsIndexDivisor == -1) tisNoIndex = reader; else tis = reader; - - // make sure that all index files have been read or are kept open so that if an index + + // make sure that all index files have been read or are kept open so that if an index // update removes them we'll still have them freqStream = cfsDir->openInput(segment + L"." + IndexFileNames::FREQ_EXTENSION(), readBufferSize); - + if (fieldInfos->hasProx()) proxStream = cfsDir->openInput(segment + L"." + IndexFileNames::PROX_EXTENSION(), readBufferSize); - + success = true; } catch (LuceneException& e) @@ -880,52 +880,52 @@ namespace Lucene if (!success) decRef(); finally.throwException(); - + // Must assign this at the end -- if we hit an exception above core, we don't want to attempt to // purge the FieldCache (will hit NPE because core is not assigned yet). _origInstance = origInstance; } - + CoreReaders::~CoreReaders() { } - + TermVectorsReaderPtr CoreReaders::getTermVectorsReaderOrig() { SyncLock syncLock(this); return termVectorsReaderOrig; } - + FieldsReaderPtr CoreReaders::getFieldsReaderOrig() { SyncLock syncLock(this); return fieldsReaderOrig; } - + void CoreReaders::incRef() { SyncLock syncLock(this); ref->incRef(); } - + DirectoryPtr CoreReaders::getCFSReader() { SyncLock syncLock(this); return cfsReader; } - + TermInfosReaderPtr CoreReaders::getTermsReader() { SyncLock syncLock(this); return tis ? tis : tisNoIndex; } - + bool CoreReaders::termsIndexIsLoaded() { SyncLock syncLock(this); return tis.get() != NULL; } - + void CoreReaders::loadTermsIndex(SegmentInfoPtr si, int32_t termsIndexDivisor) { SyncLock syncLock(this); @@ -934,20 +934,20 @@ namespace Lucene DirectoryPtr dir0; if (si->getUseCompoundFile()) { - // In some cases, we were originally opened when CFS was not used, but then we are asked + // In some cases, we were originally opened when CFS was not used, but then we are asked // to open the terms reader with index, the segment has switched to CFS if (!cfsReader) cfsReader = newLucene(dir, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION(), readBufferSize); - + dir0 = cfsReader; } else dir0 = dir; - + tis = newLucene(dir0, segment, fieldInfos, readBufferSize, termsIndexDivisor); } } - + void CoreReaders::decRef() { SyncLock syncLock(this); @@ -973,19 +973,19 @@ namespace Lucene cfsReader->close(); if (storeCFSReader) storeCFSReader->close(); - + // Force FieldCache to evict our entries at this point SegmentReaderPtr origInstance(_origInstance.lock()); if (origInstance) FieldCache::DEFAULT()->purge(origInstance); } } - + void CoreReaders::openDocStores(SegmentInfoPtr si) { SyncLock syncLock(this); BOOST_ASSERT(si->name == segment); - + if (!fieldsReaderOrig) { DirectoryPtr storeDir; @@ -1018,70 +1018,70 @@ namespace Lucene storeDir = dir; BOOST_ASSERT(storeDir); } - + String storesSegment(si->getDocStoreOffset() != -1 ? si->getDocStoreSegment() : segment); - + fieldsReaderOrig = newLucene(storeDir, storesSegment, fieldInfos, readBufferSize, si->getDocStoreOffset(), si->docCount); - + // Verify two sources of "maxDoc" agree if (si->getDocStoreOffset() == -1 && fieldsReaderOrig->size() != si->docCount) { - boost::throw_exception(CorruptIndexException(L"doc counts differ for segment " + segment + - L": fieldsReader shows " + StringUtils::toString(fieldsReaderOrig->size()) + + boost::throw_exception(CorruptIndexException(L"doc counts differ for segment " + segment + + L": fieldsReader shows " + StringUtils::toString(fieldsReaderOrig->size()) + L" but segmentInfo shows " + StringUtils::toString(si->docCount))); } - + if (fieldInfos->hasVectors()) // open term vector files only as needed termVectorsReaderOrig = newLucene(storeDir, storesSegment, fieldInfos, readBufferSize, si->getDocStoreOffset(), si->docCount); } } - + FieldsReaderLocal::FieldsReaderLocal(SegmentReaderPtr reader) { this->_reader = reader; } - + FieldsReaderPtr FieldsReaderLocal::initialValue() { return boost::dynamic_pointer_cast(SegmentReaderPtr(_reader)->core->getFieldsReaderOrig()->clone()); } - + SegmentReaderRef::SegmentReaderRef() { _refCount = 1; } - + SegmentReaderRef::~SegmentReaderRef() { } - + String SegmentReaderRef::toString() { StringStream buffer; buffer << L"refcount: " << _refCount; return buffer.str(); } - + int32_t SegmentReaderRef::refCount() { SyncLock syncLock(this); return _refCount; } - + int32_t SegmentReaderRef::incRef() { SyncLock syncLock(this); BOOST_ASSERT(_refCount > 0); return ++_refCount; } - + int32_t SegmentReaderRef::decRef() { SyncLock syncLock(this); BOOST_ASSERT(_refCount > 0); return --_refCount; } - + Norm::Norm() { this->refCount = 1; @@ -1090,7 +1090,7 @@ namespace Lucene this->rollbackDirty = false; this->number = 0; } - + Norm::Norm(SegmentReaderPtr reader, IndexInputPtr in, int32_t number, int64_t normSeek) { this->_reader = reader; @@ -1101,18 +1101,18 @@ namespace Lucene this->number = number; this->normSeek = normSeek; } - + Norm::~Norm() { } - + void Norm::incRef() { SyncLock syncLock(this); BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); ++refCount; } - + void Norm::closeInput() { SegmentReaderPtr reader(_reader.lock()); @@ -1132,16 +1132,16 @@ namespace Lucene reader->singleNormStream.reset(); } } - + in.reset(); } } - + void Norm::decRef() { SyncLock syncLock(this); BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - + if (--refCount == 0) { if (origNorm) @@ -1151,10 +1151,10 @@ namespace Lucene } else closeInput(); - + if (origReader) origReader.reset(); - + if (_bytes) { BOOST_ASSERT(_bytesRef); @@ -1168,7 +1168,7 @@ namespace Lucene } } } - + void Norm::bytes(uint8_t* bytesOut, int32_t offset, int32_t length) { SyncLock syncLock(this); @@ -1196,7 +1196,7 @@ namespace Lucene } } } - + ByteArray Norm::bytes() { SyncLock syncLock(this); @@ -1210,7 +1210,7 @@ namespace Lucene _bytes = origNorm->bytes(); _bytesRef = origNorm->_bytesRef; _bytesRef->incRef(); - + // Once we've loaded the bytes we no longer need origNorm origNorm->decRef(); origNorm.reset(); @@ -1221,30 +1221,30 @@ namespace Lucene // We are the origNorm, so load the bytes for real ourself int32_t count = SegmentReaderPtr(_reader)->maxDoc(); _bytes = ByteArray::newInstance(count); - + // Since we are orig, in must not be null BOOST_ASSERT(in); - + // Read from disk. { SyncLock instancesLock(in); in->seek(normSeek); in->readBytes(_bytes.get(), 0, count, false); } - + _bytesRef = newLucene(); closeInput(); } } - + return _bytes; } - + SegmentReaderRefPtr Norm::bytesRef() { return _bytesRef; } - + ByteArray Norm::copyOnWrite() { SyncLock syncLock(this); @@ -1254,7 +1254,7 @@ namespace Lucene BOOST_ASSERT(_bytesRef); if (_bytesRef->refCount() > 1) { - // I cannot be the origNorm for another norm instance if I'm being changed. + // I cannot be the origNorm for another norm instance if I'm being changed. // ie, only the "head Norm" can be changed BOOST_ASSERT(refCount == 1); SegmentReaderRefPtr oldRef(_bytesRef); @@ -1265,11 +1265,11 @@ namespace Lucene dirty = true; return _bytes; } - + LuceneObjectPtr Norm::clone(LuceneObjectPtr other) { SyncLock syncLock(this); - + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); LuceneObjectPtr clone = other ? other : newLucene(); NormPtr cloneNorm(boost::dynamic_pointer_cast(clone)); @@ -1282,14 +1282,14 @@ namespace Lucene cloneNorm->dirty = dirty; cloneNorm->number = number; cloneNorm->rollbackDirty = rollbackDirty; - + cloneNorm->refCount = 1; - + if (_bytes) { BOOST_ASSERT(_bytesRef); BOOST_ASSERT(!origNorm); - + // Clone holds a reference to my bytes cloneNorm->_bytesRef->incRef(); } @@ -1304,17 +1304,17 @@ namespace Lucene } cloneNorm->origNorm->incRef(); } - + // Only the origNorm will actually readBytes from in cloneNorm->in.reset(); - + return cloneNorm; } - + void Norm::reWrite(SegmentInfoPtr si) { BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - + // NOTE: norms are re-written in regular directory, not cfs si->advanceNormGen(this->number); String normFileName(si->getNormFileName(this->number)); diff --git a/src/core/index/SegmentTermDocs.cpp b/src/core/index/SegmentTermDocs.cpp index 937c1166..897d8882 100644 --- a/src/core/index/SegmentTermDocs.cpp +++ b/src/core/index/SegmentTermDocs.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -34,7 +34,7 @@ namespace Lucene this->haveSkipped = false; this->currentFieldStoresPayloads = false; this->currentFieldOmitTermFreqAndPositions = false; - + this->_freqStream = boost::dynamic_pointer_cast(parent->core->freqStream->clone()); { SyncLock parentLock(parent); @@ -43,25 +43,25 @@ namespace Lucene this->skipInterval = parent->core->getTermsReader()->getSkipInterval(); this->maxSkipLevels = parent->core->getTermsReader()->getMaxSkipLevels(); } - + SegmentTermDocs::~SegmentTermDocs() { } - + void SegmentTermDocs::seek(TermPtr term) { TermInfoPtr ti(SegmentReaderPtr(_parent)->core->getTermsReader()->get(term)); seek(ti, term); } - + void SegmentTermDocs::seek(TermEnumPtr termEnum) { TermInfoPtr ti; TermPtr term; - + SegmentTermEnumPtr segmentTermEnum(boost::dynamic_pointer_cast(termEnum)); SegmentReaderPtr parent(_parent); - + // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs if (segmentTermEnum && segmentTermEnum->fieldInfos == parent->core->fieldInfos) // optimized case { @@ -73,10 +73,10 @@ namespace Lucene term = termEnum->term(); ti = parent->core->getTermsReader()->get(term); } - + seek(ti, term); } - + void SegmentTermDocs::seek(TermInfoPtr ti, TermPtr term) { count = 0; @@ -96,28 +96,28 @@ namespace Lucene haveSkipped = false; } } - + void SegmentTermDocs::close() { _freqStream->close(); if (skipListReader) skipListReader->close(); } - + int32_t SegmentTermDocs::doc() { return _doc; } - + int32_t SegmentTermDocs::freq() { return _freq; } - + void SegmentTermDocs::skippingDoc() { } - + bool SegmentTermDocs::next() { while (true) @@ -125,7 +125,7 @@ namespace Lucene if (count == df) return false; int32_t docCode = _freqStream->readVInt(); - + if (currentFieldOmitTermFreqAndPositions) { _doc += docCode; @@ -139,16 +139,16 @@ namespace Lucene else _freq = _freqStream->readVInt(); // else read freq } - + ++count; - + if (!deletedDocs || !deletedDocs->get(_doc)) break; skippingDoc(); } return true; } - + int32_t SegmentTermDocs::read(Collection docs, Collection freqs) { int32_t length = docs.size(); @@ -167,7 +167,7 @@ namespace Lucene else _freq = _freqStream->readVInt(); // else read freq ++count; - + if (!deletedDocs || !deletedDocs->get(_doc)) { docs[i] = _doc; @@ -178,7 +178,7 @@ namespace Lucene return i; } } - + int32_t SegmentTermDocs::readNoTf(Collection docs, Collection freqs, int32_t length) { int32_t i = 0; @@ -187,11 +187,11 @@ namespace Lucene // manually inlined call to next() for speed _doc += _freqStream->readVInt(); ++count; - + if (!deletedDocs || !deletedDocs->get(_doc)) { docs[i] = _doc; - + // Hardware freq to 1 when term freqs were not stored in the index freqs[i] = 1; ++i; @@ -199,24 +199,24 @@ namespace Lucene } return i; } - + void SegmentTermDocs::skipProx(int64_t proxPointer, int32_t payloadLength) { } - + bool SegmentTermDocs::skipTo(int32_t target) { if (df >= skipInterval) // optimized case { if (!skipListReader) skipListReader = newLucene(boost::dynamic_pointer_cast(_freqStream->clone()), maxSkipLevels, skipInterval); // lazily clone - + if (!haveSkipped) // lazily initialize skip stream { skipListReader->init(skipPointer, freqBasePointer, proxBasePointer, df, currentFieldStoresPayloads); haveSkipped = true; } - + int32_t newCount = skipListReader->skipTo(target); if (newCount > count) { @@ -227,7 +227,7 @@ namespace Lucene count = newCount; } } - + // done skipping, now just scan do { @@ -237,12 +237,12 @@ namespace Lucene while (target > _doc); return true; } - + IndexInputPtr SegmentTermDocs::freqStream() { return _freqStream; } - + void SegmentTermDocs::freqStream(IndexInputPtr freqStream) { _freqStream = freqStream; diff --git a/src/core/index/SegmentTermEnum.cpp b/src/core/index/SegmentTermEnum.cpp index c69da940..6c1eafee 100644 --- a/src/core/index/SegmentTermEnum.cpp +++ b/src/core/index/SegmentTermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -28,11 +28,11 @@ namespace Lucene indexInterval = 0; skipInterval = 0; maxSkipLevels = 0; - + isIndex = false; maxSkipLevels = 0; } - + SegmentTermEnum::SegmentTermEnum(IndexInputPtr i, FieldInfosPtr fis, bool isi) { format = 0; @@ -47,19 +47,19 @@ namespace Lucene indexInterval = 0; skipInterval = 0; maxSkipLevels = 0; - + input = i; fieldInfos = fis; isIndex = isi; - maxSkipLevels = 1; // use single-level skip lists for formats > -3 - + maxSkipLevels = 1; // use single-level skip lists for formats > -3 + int32_t firstInt = input->readInt(); if (firstInt >= 0) { // original-format file, without explicit format version number format = 0; size = firstInt; - + // back-compatible settings indexInterval = 128; skipInterval = INT_MAX; // switch off skipTo optimization @@ -68,13 +68,13 @@ namespace Lucene { // we have a format version number format = firstInt; - + // check that it is a format we can understand if (format < TermInfosWriter::FORMAT_CURRENT) boost::throw_exception(CorruptIndexException(L"Unknown format version:" + StringUtils::toString(format) + L" expected " + StringUtils::toString(TermInfosWriter::FORMAT_CURRENT) + L" or higher")); - + size = input->readLong(); // read the size - + if (format == -1) { if (!isIndex) @@ -95,7 +95,7 @@ namespace Lucene maxSkipLevels = input->readInt(); } } - + BOOST_ASSERT(indexInterval > 0); // must not be negative BOOST_ASSERT(skipInterval > 0); // must not be negative } @@ -106,11 +106,11 @@ namespace Lucene prevBuffer->setPreUTF8Strings(); } } - + SegmentTermEnum::~SegmentTermEnum() { } - + LuceneObjectPtr SegmentTermEnum::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -125,17 +125,17 @@ namespace Lucene cloneEnum->indexInterval = indexInterval; cloneEnum->skipInterval = skipInterval; cloneEnum->maxSkipLevels = maxSkipLevels; - + cloneEnum->input = boost::dynamic_pointer_cast(input->clone()); cloneEnum->_termInfo = newLucene(_termInfo); - + cloneEnum->termBuffer = boost::dynamic_pointer_cast(termBuffer->clone()); cloneEnum->prevBuffer = boost::dynamic_pointer_cast(prevBuffer->clone()); cloneEnum->scanBuffer = newLucene(); - + return cloneEnum; } - + void SegmentTermEnum::seek(int64_t pointer, int64_t p, TermPtr t, TermInfoPtr ti) { input->seek(pointer); @@ -144,7 +144,7 @@ namespace Lucene prevBuffer->reset(); _termInfo->set(ti); } - + bool SegmentTermEnum::next() { if (position++ >= size - 1) @@ -153,30 +153,30 @@ namespace Lucene termBuffer->reset(); return false; } - + prevBuffer->set(termBuffer); termBuffer->read(input, fieldInfos); - + _termInfo->docFreq = input->readVInt(); // read doc freq _termInfo->freqPointer += input->readVLong(); // read freq pointer _termInfo->proxPointer += input->readVLong(); // read prox pointer - + if (format == -1) { - // just read skipOffset in order to increment file pointer; value is never used + // just read skipOffset in order to increment file pointer; value is never used // since skipTo is switched off if (!isIndex && _termInfo->docFreq > formatM1SkipInterval) _termInfo->skipOffset = input->readVInt(); } else if (_termInfo->docFreq >= skipInterval) _termInfo->skipOffset = input->readVInt(); - + if (isIndex) indexPointer += input->readVLong(); // read index pointer - + return true; } - + int32_t SegmentTermEnum::scanTo(TermPtr term) { scanBuffer->set(term); @@ -185,42 +185,42 @@ namespace Lucene ++count; return count; } - + TermPtr SegmentTermEnum::term() { return termBuffer->toTerm(); } - + TermPtr SegmentTermEnum::prev() { return prevBuffer->toTerm(); } - + TermInfoPtr SegmentTermEnum::termInfo() { return newLucene(_termInfo); } - + void SegmentTermEnum::termInfo(TermInfoPtr ti) { ti->set(_termInfo); } - + int32_t SegmentTermEnum::docFreq() { return _termInfo->docFreq; } - + int64_t SegmentTermEnum::freqPointer() { return _termInfo->freqPointer; } - + int64_t SegmentTermEnum::proxPointer() { return _termInfo->proxPointer; } - + void SegmentTermEnum::close() { input->close(); diff --git a/src/core/index/SegmentTermPositionVector.cpp b/src/core/index/SegmentTermPositionVector.cpp index 5bb015b6..c874109d 100644 --- a/src/core/index/SegmentTermPositionVector.cpp +++ b/src/core/index/SegmentTermPositionVector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -10,19 +10,19 @@ namespace Lucene { - SegmentTermPositionVector::SegmentTermPositionVector(const String& field, Collection terms, - Collection termFreqs, Collection< Collection > positions, + SegmentTermPositionVector::SegmentTermPositionVector(const String& field, Collection terms, + Collection termFreqs, Collection< Collection > positions, Collection< Collection > offsets) : SegmentTermVector(field, terms, termFreqs) { this->offsets = offsets; this->positions = positions; } - + SegmentTermPositionVector::~SegmentTermPositionVector() { } - + const Collection SegmentTermPositionVector::EMPTY_TERM_POS() { static Collection _EMPTY_TERM_POS; @@ -30,7 +30,7 @@ namespace Lucene _EMPTY_TERM_POS = Collection::newInstance(); return _EMPTY_TERM_POS; } - + Collection SegmentTermPositionVector::getOffsets(int32_t index) { Collection result(TermVectorOffsetInfo::EMPTY_OFFSET_INFO()); @@ -40,7 +40,7 @@ namespace Lucene result = offsets[index]; return result; } - + Collection SegmentTermPositionVector::getTermPositions(int32_t index) { Collection result(EMPTY_TERM_POS()); diff --git a/src/core/index/SegmentTermPositions.cpp b/src/core/index/SegmentTermPositions.cpp index 829cee39..6e8d21de 100644 --- a/src/core/index/SegmentTermPositions.cpp +++ b/src/core/index/SegmentTermPositions.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,11 +23,11 @@ namespace Lucene this->lazySkipPointer = -1; this->lazySkipProxCount = 0; } - + SegmentTermPositions::~SegmentTermPositions() { } - + void SegmentTermPositions::seek(TermInfoPtr ti, TermPtr term) { SegmentTermDocs::seek(ti, term); @@ -38,14 +38,14 @@ namespace Lucene payloadLength = 0; needToLoadPayload = false; } - + void SegmentTermPositions::close() { SegmentTermDocs::close(); if (proxStream) proxStream->close(); } - + int32_t SegmentTermPositions::nextPosition() { if (currentFieldOmitTermFreqAndPositions) @@ -53,14 +53,14 @@ namespace Lucene // This field does not store term freq, positions, payloads return 0; } - + // perform lazy skips if necessary lazySkip(); --proxCount; position += readDeltaPosition(); return position; } - + int32_t SegmentTermPositions::readDeltaPosition() { int32_t delta = proxStream->readVInt(); @@ -75,18 +75,18 @@ namespace Lucene } return delta; } - + void SegmentTermPositions::skippingDoc() { // we remember to skip a document lazily lazySkipProxCount += _freq; } - + bool SegmentTermPositions::next() { // we remember to skip the remaining positions of the current document lazily lazySkipProxCount += proxCount; - + if (SegmentTermDocs::next()) { proxCount = _freq; // note frequency @@ -95,13 +95,13 @@ namespace Lucene } return false; } - + int32_t SegmentTermPositions::read(Collection docs, Collection freqs) { boost::throw_exception(UnsupportedOperationException(L"TermPositions does not support processing multiple documents in one call. Use TermDocs instead.")); return 0; } - + void SegmentTermPositions::skipProx(int64_t proxPointer, int32_t payloadLength) { // we save the pointer, we might have to skip there lazily @@ -111,7 +111,7 @@ namespace Lucene this->payloadLength = payloadLength; needToLoadPayload = false; } - + void SegmentTermPositions::skipPositions(int32_t n) { BOOST_ASSERT(!currentFieldOmitTermFreqAndPositions); @@ -121,14 +121,14 @@ namespace Lucene skipPayload(); } } - + void SegmentTermPositions::skipPayload() { if (needToLoadPayload && payloadLength > 0) proxStream->seek(proxStream->getFilePointer() + payloadLength); needToLoadPayload = false; } - + void SegmentTermPositions::lazySkip() { if (!proxStream) @@ -136,33 +136,33 @@ namespace Lucene // clone lazily proxStream = boost::dynamic_pointer_cast(SegmentReaderPtr(_parent)->core->proxStream->clone()); } - + // we might have to skip the current payload if it was not read yet skipPayload(); - + if (lazySkipPointer != -1) { proxStream->seek(lazySkipPointer); lazySkipPointer = -1; } - + if (lazySkipProxCount != 0) { skipPositions(lazySkipProxCount); lazySkipProxCount = 0; } } - + int32_t SegmentTermPositions::getPayloadLength() { return payloadLength; } - + ByteArray SegmentTermPositions::getPayload(ByteArray data, int32_t offset) { if (!needToLoadPayload) boost::throw_exception(IOException(L"Either no payload exists at this term position or an attempt was made to load it more than once.")); - + // read payloads lazily ByteArray retArray; int32_t retOffset = 0; @@ -181,7 +181,7 @@ namespace Lucene needToLoadPayload = false; return retArray; } - + bool SegmentTermPositions::isPayloadAvailable() { return (needToLoadPayload && payloadLength > 0); diff --git a/src/core/index/SegmentTermVector.cpp b/src/core/index/SegmentTermVector.cpp index 4627cfdf..09046986 100644 --- a/src/core/index/SegmentTermVector.cpp +++ b/src/core/index/SegmentTermVector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,16 +15,16 @@ namespace Lucene this->terms = terms; this->termFreqs = termFreqs; } - + SegmentTermVector::~SegmentTermVector() { } - + String SegmentTermVector::getField() { return field; } - + String SegmentTermVector::toString() { StringStream segTermVector; @@ -41,22 +41,22 @@ namespace Lucene segTermVector << L"}"; return segTermVector.str(); } - + int32_t SegmentTermVector::size() { return terms ? terms.size() : 0; } - + Collection SegmentTermVector::getTerms() { return terms; } - + Collection SegmentTermVector::getTermFrequencies() { return termFreqs; } - + int32_t SegmentTermVector::indexOf(const String& term) { if (!terms) @@ -64,7 +64,7 @@ namespace Lucene Collection::iterator search = std::lower_bound(terms.begin(), terms.end(), term); return (search == terms.end() || term < *search) ? -1 : std::distance(terms.begin(), search); } - + Collection SegmentTermVector::indexesOf(Collection termNumbers, int32_t start, int32_t length) { Collection res(Collection::newInstance(length)); diff --git a/src/core/index/SegmentWriteState.cpp b/src/core/index/SegmentWriteState.cpp index 246f9878..841d792d 100644 --- a/src/core/index/SegmentWriteState.cpp +++ b/src/core/index/SegmentWriteState.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -9,8 +9,8 @@ namespace Lucene { - SegmentWriteState::SegmentWriteState(DocumentsWriterPtr docWriter, DirectoryPtr directory, const String& segmentName, - const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, + SegmentWriteState::SegmentWriteState(DocumentsWriterPtr docWriter, DirectoryPtr directory, const String& segmentName, + const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, int32_t termIndexInterval) { this->_docWriter = docWriter; @@ -22,11 +22,11 @@ namespace Lucene this->termIndexInterval = termIndexInterval; this->flushedFiles = HashSet::newInstance(); } - + SegmentWriteState::~SegmentWriteState() { } - + String SegmentWriteState::segmentFileName(const String& ext) { return segmentName + L"." + ext; diff --git a/src/core/index/SerialMergeScheduler.cpp b/src/core/index/SerialMergeScheduler.cpp index 38b1c458..63223de2 100644 --- a/src/core/index/SerialMergeScheduler.cpp +++ b/src/core/index/SerialMergeScheduler.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene SerialMergeScheduler::~SerialMergeScheduler() { } - + void SerialMergeScheduler::merge(IndexWriterPtr writer) { SyncLock syncLock(this); @@ -25,7 +25,7 @@ namespace Lucene writer->merge(merge); } } - + void SerialMergeScheduler::close() { } diff --git a/src/core/index/SnapshotDeletionPolicy.cpp b/src/core/index/SnapshotDeletionPolicy.cpp index 17c6f509..6ee34c13 100644 --- a/src/core/index/SnapshotDeletionPolicy.cpp +++ b/src/core/index/SnapshotDeletionPolicy.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,25 +14,25 @@ namespace Lucene { this->primary = primary; } - + SnapshotDeletionPolicy::~SnapshotDeletionPolicy() { } - + void SnapshotDeletionPolicy::onInit(Collection commits) { SyncLock syncLock(this); primary->onInit(wrapCommits(commits)); lastCommit = commits[commits.size() - 1]; } - + void SnapshotDeletionPolicy::onCommit(Collection commits) { SyncLock syncLock(this); primary->onCommit(wrapCommits(commits)); lastCommit = commits[commits.size() - 1]; } - + IndexCommitPtr SnapshotDeletionPolicy::snapshot() { SyncLock syncLock(this); @@ -44,7 +44,7 @@ namespace Lucene boost::throw_exception(IllegalStateException(L"snapshot is already set; please call release() first")); return lastCommit; } - + void SnapshotDeletionPolicy::release() { SyncLock syncLock(this); @@ -53,7 +53,7 @@ namespace Lucene else boost::throw_exception(IllegalStateException(L"snapshot was not set; please call snapshot() first")); } - + Collection SnapshotDeletionPolicy::wrapCommits(Collection commits) { Collection myCommits(Collection::newInstance()); @@ -61,37 +61,37 @@ namespace Lucene myCommits.add(newLucene(shared_from_this(), *commit)); return myCommits; } - + MyCommitPoint::MyCommitPoint(SnapshotDeletionPolicyPtr deletionPolicy, IndexCommitPtr cp) { this->_deletionPolicy = deletionPolicy; this->cp = cp; } - + MyCommitPoint::~MyCommitPoint() { } - + String MyCommitPoint::toString() { return L"SnapshotDeletionPolicy.SnapshotCommitPoint(" + cp->toString() + L")"; } - + String MyCommitPoint::getSegmentsFileName() { return cp->getSegmentsFileName(); } - + HashSet MyCommitPoint::getFileNames() { return cp->getFileNames(); } - + DirectoryPtr MyCommitPoint::getDirectory() { return cp->getDirectory(); } - + void MyCommitPoint::deleteCommit() { SnapshotDeletionPolicyPtr deletionPolicy(_deletionPolicy); @@ -100,27 +100,27 @@ namespace Lucene if (deletionPolicy->_snapshot.empty() || deletionPolicy->_snapshot != getSegmentsFileName()) cp->deleteCommit(); } - + bool MyCommitPoint::isDeleted() { return cp->isDeleted(); } - + int64_t MyCommitPoint::getVersion() { return cp->getVersion(); } - + int64_t MyCommitPoint::getGeneration() { return cp->getGeneration(); } - + MapStringString MyCommitPoint::getUserData() { return cp->getUserData(); } - + bool MyCommitPoint::isOptimized() { return cp->isOptimized(); diff --git a/src/core/index/SortedTermVectorMapper.cpp b/src/core/index/SortedTermVectorMapper.cpp index 1871756c..3e291b55 100644 --- a/src/core/index/SortedTermVectorMapper.cpp +++ b/src/core/index/SortedTermVectorMapper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { const wchar_t* SortedTermVectorMapper::ALL = L"_ALL_"; - + SortedTermVectorMapper::SortedTermVectorMapper(TermVectorEntryComparator comparator) : TermVectorMapper(false, false) { this->storeOffsets = false; @@ -20,7 +20,7 @@ namespace Lucene this->currentSet = Collection::newInstance(); this->termToTVE = MapStringTermVectorEntry::newInstance(); } - + SortedTermVectorMapper::SortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator) : TermVectorMapper(ignoringPositions, ignoringPositions) { @@ -30,11 +30,11 @@ namespace Lucene this->currentSet = Collection::newInstance(); this->termToTVE = MapStringTermVectorEntry::newInstance(); } - + SortedTermVectorMapper::~SortedTermVectorMapper() { } - + void SortedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { // We need to combine any previous mentions of the term @@ -43,7 +43,7 @@ namespace Lucene { entry = newLucene(ALL, term, frequency, storeOffsets ? offsets : Collection(), storePositions ? positions : Collection()); termToTVE.put(term, entry); - + if (!currentSet.contains_if(luceneEqualTo(entry))) currentSet.insert(std::upper_bound(currentSet.begin(), currentSet.end(), entry, comparator), entry); } @@ -80,13 +80,13 @@ namespace Lucene } } } - + void SortedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { this->storeOffsets = storeOffsets; this->storePositions = storePositions; } - + Collection SortedTermVectorMapper::getTermVectorEntrySet() { return currentSet; diff --git a/src/core/index/StoredFieldsWriter.cpp b/src/core/index/StoredFieldsWriter.cpp index 78f1ce5d..de57d0d1 100644 --- a/src/core/index/StoredFieldsWriter.cpp +++ b/src/core/index/StoredFieldsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,38 +24,38 @@ namespace Lucene docFreeList = Collection::newInstance(1); freeCount = 0; allocCount = 0; - + this->_docWriter = docWriter; this->fieldInfos = fieldInfos; } - + StoredFieldsWriter::~StoredFieldsWriter() { } - + StoredFieldsWriterPerThreadPtr StoredFieldsWriter::addThread(DocStatePtr docState) { return newLucene(docState, shared_from_this()); } - + void StoredFieldsWriter::flush(SegmentWriteStatePtr state) { SyncLock syncLock(this); if (state->numDocsInStore > 0) { - // It's possible that all documents seen in this segment hit non-aborting exceptions, + // It's possible that all documents seen in this segment hit non-aborting exceptions, // in which case we will not have yet init'd the FieldsWriter initFieldsWriter(); - // Fill fdx file to include any final docs that we skipped because they hit non-aborting + // Fill fdx file to include any final docs that we skipped because they hit non-aborting // exceptions fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); } - + if (fieldsWriter) fieldsWriter->flush(); } - + void StoredFieldsWriter::initFieldsWriter() { if (!fieldsWriter) @@ -71,7 +71,7 @@ namespace Lucene } } } - + void StoredFieldsWriter::closeDocStore(SegmentWriteStatePtr state) { SyncLock syncLock(this); @@ -81,7 +81,7 @@ namespace Lucene initFieldsWriter(); fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); } - + if (fieldsWriter) { fieldsWriter->close(); @@ -94,19 +94,19 @@ namespace Lucene DocumentsWriterPtr docWriter(state->_docWriter); docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_EXTENSION()); docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - + String fileName(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - + if (4 + ((int64_t)state->numDocsInStore) * 8 != state->directory->fileLength(fileName)) { - boost::throw_exception(RuntimeException(L"after flush: fdx size mismatch: " + StringUtils::toString(state->numDocsInStore) + - L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + - L" length in bytes of " + fileName + L" file exists?=" + + boost::throw_exception(RuntimeException(L"after flush: fdx size mismatch: " + StringUtils::toString(state->numDocsInStore) + + L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + + L" length in bytes of " + fileName + L" file exists?=" + StringUtils::toString(state->directory->fileExists(fileName)))); } } } - + StoredFieldsWriterPerDocPtr StoredFieldsWriter::getPerDoc() { SyncLock syncLock(this); @@ -115,7 +115,7 @@ namespace Lucene ++allocCount; if (allocCount > docFreeList.size()) { - // Grow our free list up front to make sure we have enough space to recycle all + // Grow our free list up front to make sure we have enough space to recycle all // outstanding StoredFieldsWriterPerDoc instances BOOST_ASSERT(allocCount == docFreeList.size() + 1); docFreeList.resize(MiscUtils::getNextSize(allocCount)); @@ -125,7 +125,7 @@ namespace Lucene else return docFreeList[--freeCount]; } - + void StoredFieldsWriter::abort() { SyncLock syncLock(this); @@ -142,11 +142,11 @@ namespace Lucene lastDocID = 0; } } - + void StoredFieldsWriter::fill(int32_t docID) { int32_t docStoreOffset = DocumentsWriterPtr(_docWriter)->getDocStoreOffset(); - + // We must "catch up" for all docs before us that had no stored fields int32_t end = docID + docStoreOffset; while (lastDocID < end) @@ -155,16 +155,16 @@ namespace Lucene ++lastDocID; } } - + void StoredFieldsWriter::finishDocument(StoredFieldsWriterPerDocPtr perDoc) { SyncLock syncLock(this); IndexWriterPtr writer(DocumentsWriterPtr(_docWriter)->_writer); BOOST_ASSERT(writer->testPoint(L"StoredFieldsWriter.finishDocument start")); initFieldsWriter(); - + fill(perDoc->docID); - + // Append stored fields to the real FieldsWriter fieldsWriter->flushDocument(perDoc->numStoredFields, perDoc->fdt); ++lastDocID; @@ -172,12 +172,12 @@ namespace Lucene free(perDoc); BOOST_ASSERT(writer->testPoint(L"StoredFieldsWriter.finishDocument end")); } - + bool StoredFieldsWriter::freeRAM() { return false; } - + void StoredFieldsWriter::free(StoredFieldsWriterPerDocPtr perDoc) { SyncLock syncLock(this); @@ -187,7 +187,7 @@ namespace Lucene BOOST_ASSERT(perDoc->fdt->getFilePointer() == 0); docFreeList[freeCount++] = perDoc; } - + StoredFieldsWriterPerDoc::StoredFieldsWriterPerDoc(StoredFieldsWriterPtr fieldsWriter) { this->_fieldsWriter = fieldsWriter; @@ -195,29 +195,29 @@ namespace Lucene fdt = newLucene(buffer); numStoredFields = 0; } - + StoredFieldsWriterPerDoc::~StoredFieldsWriterPerDoc() { } - + void StoredFieldsWriterPerDoc::reset() { fdt->reset(); buffer->recycle(); numStoredFields = 0; } - + void StoredFieldsWriterPerDoc::abort() { reset(); StoredFieldsWriterPtr(_fieldsWriter)->free(shared_from_this()); } - + int64_t StoredFieldsWriterPerDoc::sizeInBytes() { return buffer->getSizeInBytes(); } - + void StoredFieldsWriterPerDoc::finish() { StoredFieldsWriterPtr(_fieldsWriter)->finishDocument(shared_from_this()); diff --git a/src/core/index/StoredFieldsWriterPerThread.cpp b/src/core/index/StoredFieldsWriterPerThread.cpp index 870bacb3..a6ea476c 100644 --- a/src/core/index/StoredFieldsWriterPerThread.cpp +++ b/src/core/index/StoredFieldsWriterPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,22 +18,22 @@ namespace Lucene this->docState = docState; localFieldsWriter = newLucene(IndexOutputPtr(), IndexOutputPtr(), storedFieldsWriter->fieldInfos); } - + StoredFieldsWriterPerThread::~StoredFieldsWriterPerThread() { } - + void StoredFieldsWriterPerThread::startDocument() { if (doc) { - // Only happens if previous document hit non-aborting exception while writing stored fields + // Only happens if previous document hit non-aborting exception while writing stored fields // into localFieldsWriter doc->reset(); doc->docID = docState->docID; } } - + void StoredFieldsWriterPerThread::addField(FieldablePtr field, FieldInfoPtr fieldInfo) { if (!doc) @@ -45,12 +45,12 @@ namespace Lucene BOOST_ASSERT(doc->fdt->length() == 0); BOOST_ASSERT(doc->fdt->getFilePointer() == 0); } - + localFieldsWriter->writeField(fieldInfo, field); BOOST_ASSERT(docState->testPoint(L"StoredFieldsWriterPerThread.processFields.writeField")); ++doc->numStoredFields; } - + DocWriterPtr StoredFieldsWriterPerThread::finishDocument() { // If there were any stored fields in this doc, doc will be non-null; else it's null. @@ -58,7 +58,7 @@ namespace Lucene doc.reset(); return finishDoc; } - + void StoredFieldsWriterPerThread::abort() { if (doc) diff --git a/src/core/index/Term.cpp b/src/core/index/Term.cpp index ae96d75c..0bce0ff6 100644 --- a/src/core/index/Term.cpp +++ b/src/core/index/Term.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,26 +14,26 @@ namespace Lucene Term::Term(const String& fld, const String& txt) : _field(fld), _text(txt) { } - + Term::~Term() { } - + String Term::field() { return _field; } - + String Term::text() { return _text; } - + TermPtr Term::createTerm(const String& text) { return newLucene(_field, text); } - + bool Term::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -47,7 +47,7 @@ namespace Lucene return false; return (_field == otherTerm->_field && _text == otherTerm->_text); } - + int32_t Term::hashCode() { int32_t prime = 31; @@ -56,7 +56,7 @@ namespace Lucene result = prime * result + (_text.empty() ? 0 : StringUtils::hashCode(_text)); return result; } - + int32_t Term::compareTo(LuceneObjectPtr other) { TermPtr otherTerm(boost::static_pointer_cast(other)); @@ -65,13 +65,13 @@ namespace Lucene else return _field.compare(otherTerm->_field); } - + void Term::set(const String& fld, const String& txt) { _field = fld; _text = txt; } - + String Term::toString() { return _field + L":" + _text; diff --git a/src/core/index/TermBuffer.cpp b/src/core/index/TermBuffer.cpp index e1b3dc78..8bf48f67 100644 --- a/src/core/index/TermBuffer.cpp +++ b/src/core/index/TermBuffer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,11 +21,11 @@ namespace Lucene text = newLucene(); bytes = newLucene(); } - + TermBuffer::~TermBuffer() { } - + int32_t TermBuffer::compareTo(LuceneObjectPtr other) { TermBufferPtr otherTermBuffer(boost::static_pointer_cast(other)); @@ -34,7 +34,7 @@ namespace Lucene else return field.compare(otherTermBuffer->field); } - + int32_t TermBuffer::compareChars(wchar_t* chars1, int32_t len1, wchar_t* chars2, int32_t len2) { int32_t end = len1 < len2 ? len1 : len2; @@ -47,12 +47,12 @@ namespace Lucene } return len1 - len2; } - + void TermBuffer::setPreUTF8Strings() { preUTF8Strings = true; } - + void TermBuffer::read(IndexInputPtr input, FieldInfosPtr fieldInfos) { this->term.reset(); // invalidate cache @@ -73,7 +73,7 @@ namespace Lucene } this->field = fieldInfos->fieldName(input->readVInt()); } - + void TermBuffer::set(TermPtr term) { if (!term) @@ -88,7 +88,7 @@ namespace Lucene field = term->field(); this->term = term; } - + void TermBuffer::set(TermBufferPtr other) { text->copyText(other->text); @@ -102,18 +102,18 @@ namespace Lucene text->setLength(0); term.reset(); } - + TermPtr TermBuffer::toTerm() { if (field.empty()) // unset return TermPtr(); - + if (!term) term = newLucene(field, String(text->result.get(), text->length)); - + return term; } - + LuceneObjectPtr TermBuffer::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -121,7 +121,7 @@ namespace Lucene cloneBuffer->field = field; cloneBuffer->term = term; cloneBuffer->preUTF8Strings = preUTF8Strings; - + cloneBuffer->bytes = newLucene(); cloneBuffer->text = newLucene(); cloneBuffer->text->copyText(text); diff --git a/src/core/index/TermDocs.cpp b/src/core/index/TermDocs.cpp index ef8ac077..764d75c3 100644 --- a/src/core/index/TermDocs.cpp +++ b/src/core/index/TermDocs.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,49 +12,49 @@ namespace Lucene TermDocs::TermDocs() { } - + void TermDocs::seek(TermPtr term) { BOOST_ASSERT(false); // override } - + void TermDocs::seek(TermEnumPtr termEnum) { BOOST_ASSERT(false); // override } - + int32_t TermDocs::doc() { BOOST_ASSERT(false); return 0; // override } - + int32_t TermDocs::freq() { BOOST_ASSERT(false); return 0; // override } - + bool TermDocs::next() { BOOST_ASSERT(false); return false; // override } - + int32_t TermDocs::read(Collection docs, Collection freqs) { BOOST_ASSERT(false); return 0; // override } - + bool TermDocs::skipTo(int32_t target) { BOOST_ASSERT(false); return false; // override } - + void TermDocs::close() { BOOST_ASSERT(false); diff --git a/src/core/index/TermEnum.cpp b/src/core/index/TermEnum.cpp index 442874d0..3261c5d1 100644 --- a/src/core/index/TermEnum.cpp +++ b/src/core/index/TermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/TermFreqVector.cpp b/src/core/index/TermFreqVector.cpp index f081f599..0b16651e 100644 --- a/src/core/index/TermFreqVector.cpp +++ b/src/core/index/TermFreqVector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,41 +12,41 @@ namespace Lucene TermFreqVector::TermFreqVector() { } - + TermFreqVector::~TermFreqVector() { } - + String TermFreqVector::getField() { BOOST_ASSERT(false); return L""; // override } - + int32_t TermFreqVector::size() { BOOST_ASSERT(false); return 0; // override } - + Collection TermFreqVector::getTerms() { BOOST_ASSERT(false); return Collection(); // override } - + Collection TermFreqVector::getTermFrequencies() { BOOST_ASSERT(false); return Collection(); // override } - + int32_t TermFreqVector::indexOf(const String& term) { BOOST_ASSERT(false); return 0; // override } - + Collection TermFreqVector::indexesOf(Collection terms, int32_t start, int32_t length) { BOOST_ASSERT(false); diff --git a/src/core/index/TermInfo.cpp b/src/core/index/TermInfo.cpp index bb07db8a..18683ce2 100644 --- a/src/core/index/TermInfo.cpp +++ b/src/core/index/TermInfo.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene { set(ti); } - + TermInfo::TermInfo(int32_t df, int64_t fp, int64_t pp) { docFreq = df; @@ -21,11 +21,11 @@ namespace Lucene proxPointer = pp; skipOffset = 0; } - + TermInfo::~TermInfo() { } - + void TermInfo::set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer, int32_t skipOffset) { this->docFreq = docFreq; @@ -33,7 +33,7 @@ namespace Lucene this->proxPointer = proxPointer; this->skipOffset = skipOffset; } - + void TermInfo::set(TermInfoPtr ti) { docFreq = ti->docFreq; diff --git a/src/core/index/TermInfosReader.cpp b/src/core/index/TermInfosReader.cpp index 7923d1df..46755171 100644 --- a/src/core/index/TermInfosReader.cpp +++ b/src/core/index/TermInfosReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,44 +15,44 @@ namespace Lucene { const int32_t TermInfosReader::DEFAULT_CACHE_SIZE = 1024; - + TermInfosReader::TermInfosReader(DirectoryPtr dir, const String& seg, FieldInfosPtr fis, int32_t readBufferSize, int32_t indexDivisor) { bool success = false; - + if (indexDivisor < 1 && indexDivisor != -1) boost::throw_exception(IllegalArgumentException(L"indexDivisor must be -1 (don't load terms index) or greater than 0: got " + StringUtils::toString(indexDivisor))); - + LuceneException finally; try { directory = dir; segment = seg; fieldInfos = fis; - + origEnum = newLucene(directory->openInput(segment + L"." + IndexFileNames::TERMS_EXTENSION(), readBufferSize), fieldInfos, false); _size = origEnum->size; - + if (indexDivisor != -1) { // Load terms index totalIndexInterval = origEnum->indexInterval * indexDivisor; SegmentTermEnumPtr indexEnum(newLucene(directory->openInput(segment + L"." + IndexFileNames::TERMS_INDEX_EXTENSION(), readBufferSize), fieldInfos, true)); - + try { int32_t indexSize = 1 + ((int32_t)indexEnum->size - 1) / indexDivisor; // otherwise read index - + indexTerms = Collection::newInstance(indexSize); indexInfos = Collection::newInstance(indexSize); indexPointers = Collection::newInstance(indexSize); - + for (int32_t i = 0; indexEnum->next(); ++i) { indexTerms[i] = indexEnum->term(); indexInfos[i] = indexEnum->termInfo(); indexPointers[i] = indexEnum->indexPointer; - + for (int32_t j = 1; j < indexDivisor; ++j) { if (!indexEnum->next()) @@ -77,39 +77,39 @@ namespace Lucene { finally = e; } - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. // In this case, we want to explicitly close any subset of things that were opened. if (!success) close(); finally.throwException(); } - + TermInfosReader::~TermInfosReader() { } - + int32_t TermInfosReader::getMaxSkipLevels() { return origEnum->maxSkipLevels; } - + int32_t TermInfosReader::getSkipInterval() { return origEnum->skipInterval; } - + void TermInfosReader::close() { if (origEnum) origEnum->close(); threadResources.close(); } - + int64_t TermInfosReader::size() { return _size; } - + TermInfosReaderThreadResourcesPtr TermInfosReader::getThreadResources() { TermInfosReaderThreadResourcesPtr resources(threadResources.get()); @@ -117,42 +117,42 @@ namespace Lucene { resources = newLucene(); resources->termEnum = terms(); - + // Cache does not have to be thread-safe, it is only used by one thread at the same time resources->termInfoCache = newInstance(DEFAULT_CACHE_SIZE); threadResources.set(resources); } return resources; } - + int32_t TermInfosReader::getIndexOffset(TermPtr term) { // binary search indexTerms Collection::iterator indexTerm = std::upper_bound(indexTerms.begin(), indexTerms.end(), term, luceneCompare()); return (std::distance(indexTerms.begin(), indexTerm) - 1); } - + void TermInfosReader::seekEnum(SegmentTermEnumPtr enumerator, int32_t indexOffset) { enumerator->seek(indexPointers[indexOffset], ((int64_t)indexOffset * (int64_t)totalIndexInterval) - 1, indexTerms[indexOffset], indexInfos[indexOffset]); } - + TermInfoPtr TermInfosReader::get(TermPtr term) { return get(term, true); } - + TermInfoPtr TermInfosReader::get(TermPtr term, bool useCache) { if (_size == 0) return TermInfoPtr(); - + ensureIndexIsRead(); - + TermInfoPtr ti; TermInfosReaderThreadResourcesPtr resources(getThreadResources()); TermInfoCachePtr cache; - + if (useCache) { cache = resources->termInfoCache; @@ -161,10 +161,10 @@ namespace Lucene if (ti) return ti; } - + // optimize sequential access: first try scanning cached enum without seeking SegmentTermEnumPtr enumerator = resources->termEnum; - + if (enumerator->term() && // term is at or past current ((enumerator->prev() && term->compareTo(enumerator->prev()) > 0) || term->compareTo(enumerator->term()) >= 0)) @@ -180,8 +180,8 @@ namespace Lucene ti = enumerator->termInfo(); if (cache && numScans > 1) { - // we only want to put this TermInfo into the cache if scanEnum skipped more - // than one dictionary entry. This prevents RangeQueries or WildcardQueries to + // we only want to put this TermInfo into the cache if scanEnum skipped more + // than one dictionary entry. This prevents RangeQueries or WildcardQueries to // wipe out the cache when they iterate over a large numbers of terms in order. cache->put(term, ti); } @@ -191,7 +191,7 @@ namespace Lucene return ti; } } - + // random-access: must seek seekEnum(enumerator, getIndexOffset(term)); enumerator->scanTo(term); @@ -205,43 +205,43 @@ namespace Lucene ti.reset(); return ti; } - + void TermInfosReader::ensureIndexIsRead() { if (!indexTerms) boost::throw_exception(IllegalStateException(L"terms index was not loaded when this reader was created")); } - + int64_t TermInfosReader::getPosition(TermPtr term) { if (_size == 0) return -1; - + ensureIndexIsRead(); int32_t indexOffset = getIndexOffset(term); - + SegmentTermEnumPtr enumerator(getThreadResources()->termEnum); seekEnum(enumerator, indexOffset); - + while (term->compareTo(enumerator->term()) > 0 && enumerator->next()) { } - + return term->compareTo(enumerator->term()) == 0 ? enumerator->position : -1; } - + SegmentTermEnumPtr TermInfosReader::terms() { return boost::static_pointer_cast(origEnum->clone()); } - + SegmentTermEnumPtr TermInfosReader::terms(TermPtr term) { // don't use the cache in this call because we want to reposition the enumeration get(term, false); return boost::static_pointer_cast(getThreadResources()->termEnum->clone()); } - + TermInfosReaderThreadResources::~TermInfosReaderThreadResources() { } diff --git a/src/core/index/TermInfosWriter.cpp b/src/core/index/TermInfosWriter.cpp index d332592e..4d72be16 100644 --- a/src/core/index/TermInfosWriter.cpp +++ b/src/core/index/TermInfosWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,28 +19,28 @@ namespace Lucene { /// The file format version, a negative number. const int32_t TermInfosWriter::FORMAT = -3; - + /// Changed strings to true utf8 with length-in-bytes not length-in-chars. const int32_t TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES = -4; - + /// NOTE: always change this if you switch to a new format. const int32_t TermInfosWriter::FORMAT_CURRENT = TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; - + TermInfosWriter::TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval) { initialize(directory, segment, fis, interval, false); otherWriter = newLucene(directory, segment, fis, interval, true); } - + TermInfosWriter::TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isIndex) { initialize(directory, segment, fis, interval, isIndex); } - + TermInfosWriter::~TermInfosWriter() { } - + void TermInfosWriter::initialize() { if (otherWriter) @@ -49,7 +49,7 @@ namespace Lucene otherWriter->_other = shared_from_this(); } } - + void TermInfosWriter::initialize(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isi) { lastTi = newLucene(); @@ -61,7 +61,7 @@ namespace Lucene maxSkipLevels = 10; size = 0; lastIndexPointer = 0; - + indexInterval = interval; fieldInfos = fis; isIndex = isi; @@ -73,20 +73,20 @@ namespace Lucene output->writeInt(maxSkipLevels); // write maxSkipLevels BOOST_ASSERT(initUnicodeResults()); } - + void TermInfosWriter::add(TermPtr term, TermInfoPtr ti) { StringUtils::toUTF8(term->_text.c_str(), term->_text.size(), utf8Result); add(fieldInfos->fieldNumber(term->_field), utf8Result->result, utf8Result->length, ti); } - + bool TermInfosWriter::initUnicodeResults() { unicodeResult1 = newLucene(); unicodeResult2 = newLucene(); return true; } - + int32_t TermInfosWriter::compareToLastTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength) { if (lastFieldNumber != fieldNumber) @@ -97,11 +97,11 @@ namespace Lucene if (cmp != 0 || lastFieldNumber != -1) return cmp; } - + StringUtils::toUnicode(lastTermBytes.get(), lastTermBytesLength, unicodeResult1); StringUtils::toUnicode(termBytes.get(), termBytesLength, unicodeResult2); int32_t len = std::min(unicodeResult1->length, unicodeResult2->length); - + for (int32_t i = 0; i < len; ++i) { wchar_t ch1 = unicodeResult1->result[i]; @@ -111,35 +111,35 @@ namespace Lucene } return (unicodeResult1->length - unicodeResult2->length); } - + void TermInfosWriter::add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, TermInfoPtr ti) { // terms out of order? BOOST_ASSERT(compareToLastTerm(fieldNumber, termBytes, termBytesLength) < 0 || (isIndex && termBytesLength == 0 && lastTermBytesLength == 0)); - + BOOST_ASSERT(ti->freqPointer >= lastTi->freqPointer); // freqPointer out of order? BOOST_ASSERT(ti->proxPointer >= lastTi->proxPointer); // proxPointer out of order? - + TermInfosWriterPtr other(_other); - + if (!isIndex && size % indexInterval == 0) other->add(lastFieldNumber, lastTermBytes, lastTermBytesLength, lastTi); // add an index term - + writeTerm(fieldNumber, termBytes, termBytesLength); // write term output->writeVInt(ti->docFreq); // write doc freq output->writeVLong(ti->freqPointer - lastTi->freqPointer); // write pointers output->writeVLong(ti->proxPointer - lastTi->proxPointer); - + if (ti->docFreq >= skipInterval) output->writeVInt(ti->skipOffset); - + if (isIndex) { output->writeVLong(other->output->getFilePointer() - lastIndexPointer); lastIndexPointer = other->output->getFilePointer(); // write pointer } - + lastFieldNumber = fieldNumber; lastTi->set(ti); ++size; @@ -156,7 +156,7 @@ namespace Lucene break; ++start; } - + int32_t length = termBytesLength - start; output->writeVInt(start); // write shared prefix length output->writeVInt(length); // write delta length @@ -167,7 +167,7 @@ namespace Lucene MiscUtils::arrayCopy(termBytes.get(), start, lastTermBytes.get(), start, length); lastTermBytesLength = termBytesLength; } - + void TermInfosWriter::close() { output->seek(4); // write size after format diff --git a/src/core/index/TermPositionVector.cpp b/src/core/index/TermPositionVector.cpp index 73117e86..6636dd51 100644 --- a/src/core/index/TermPositionVector.cpp +++ b/src/core/index/TermPositionVector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,17 +12,17 @@ namespace Lucene TermPositionVector::TermPositionVector() { } - + TermPositionVector::~TermPositionVector() { } - + Collection TermPositionVector::getTermPositions(int32_t index) { BOOST_ASSERT(false); return Collection(); // override } - + Collection TermPositionVector::getOffsets(int32_t index) { BOOST_ASSERT(false); diff --git a/src/core/index/TermPositions.cpp b/src/core/index/TermPositions.cpp index 172afadc..3703996e 100644 --- a/src/core/index/TermPositions.cpp +++ b/src/core/index/TermPositions.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,29 +12,29 @@ namespace Lucene TermPositions::TermPositions() { } - + TermPositions::~TermPositions() { } - + int32_t TermPositions::nextPosition() { BOOST_ASSERT(false); return 0; // override } - + int32_t TermPositions::getPayloadLength() { BOOST_ASSERT(false); return 0; // override } - + ByteArray TermPositions::getPayload(ByteArray data, int32_t offset) { BOOST_ASSERT(false); return ByteArray(); // override } - + bool TermPositions::isPayloadAvailable() { BOOST_ASSERT(false); diff --git a/src/core/index/TermVectorEntry.cpp b/src/core/index/TermVectorEntry.cpp index ee66ba7e..6a06d675 100644 --- a/src/core/index/TermVectorEntry.cpp +++ b/src/core/index/TermVectorEntry.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -10,7 +10,7 @@ namespace Lucene { - TermVectorEntry::TermVectorEntry(const String& field, const String& term, int32_t frequency, + TermVectorEntry::TermVectorEntry(const String& field, const String& term, int32_t frequency, Collection offsets, Collection positions) { this->field = field; @@ -19,68 +19,68 @@ namespace Lucene this->offsets = offsets; this->positions = positions; } - + TermVectorEntry::~TermVectorEntry() { } - + String TermVectorEntry::getField() { return field; } - + int32_t TermVectorEntry::getFrequency() { return frequency; } - + Collection TermVectorEntry::getOffsets() { return offsets; } - + Collection TermVectorEntry::getPositions() { return positions; } - + String TermVectorEntry::getTerm() { return term; } - + void TermVectorEntry::setFrequency(int32_t frequency) { this->frequency = frequency; } - + void TermVectorEntry::setOffsets(Collection offsets) { this->offsets = offsets; } - + void TermVectorEntry::setPositions(Collection positions) { this->positions = positions; } - + bool TermVectorEntry::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + TermVectorEntryPtr otherTermVectorEntry(boost::dynamic_pointer_cast(other)); if (otherTermVectorEntry) return (term == otherTermVectorEntry->term); - + return false; } - + int32_t TermVectorEntry::hashCode() { return StringUtils::hashCode(term); } - + String TermVectorEntry::toString() { StringStream buffer; diff --git a/src/core/index/TermVectorEntryFreqSortedComparator.cpp b/src/core/index/TermVectorEntryFreqSortedComparator.cpp index e65f2d75..6ae03964 100644 --- a/src/core/index/TermVectorEntryFreqSortedComparator.cpp +++ b/src/core/index/TermVectorEntryFreqSortedComparator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene TermVectorEntryFreqSortedComparator::~TermVectorEntryFreqSortedComparator() { } - + bool TermVectorEntryFreqSortedComparator::compare(const TermVectorEntryPtr& first, const TermVectorEntryPtr& second) { int32_t result = (second->getFrequency() - first->getFrequency()); diff --git a/src/core/index/TermVectorMapper.cpp b/src/core/index/TermVectorMapper.cpp index 084db377..70c7179f 100644 --- a/src/core/index/TermVectorMapper.cpp +++ b/src/core/index/TermVectorMapper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,21 +14,21 @@ namespace Lucene this->ignoringPositions = ignoringPositions; this->ignoringOffsets = ignoringOffsets; } - + TermVectorMapper::~TermVectorMapper() { } - + bool TermVectorMapper::isIgnoringPositions() { return ignoringPositions; } - + bool TermVectorMapper::isIgnoringOffsets() { return ignoringOffsets; } - + void TermVectorMapper::setDocumentNumber(int32_t documentNumber) { // override diff --git a/src/core/index/TermVectorOffsetInfo.cpp b/src/core/index/TermVectorOffsetInfo.cpp index 750a74c9..6c66e801 100644 --- a/src/core/index/TermVectorOffsetInfo.cpp +++ b/src/core/index/TermVectorOffsetInfo.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene this->endOffset = endOffset; this->startOffset = startOffset; } - + TermVectorOffsetInfo::~TermVectorOffsetInfo() { } - + const Collection TermVectorOffsetInfo::EMPTY_OFFSET_INFO() { static Collection _EMPTY_OFFSET_INFO; @@ -26,27 +26,27 @@ namespace Lucene _EMPTY_OFFSET_INFO = Collection::newInstance(); return _EMPTY_OFFSET_INFO; } - + int32_t TermVectorOffsetInfo::getEndOffset() { return endOffset; } - + void TermVectorOffsetInfo::setEndOffset(int32_t endOffset) { this->endOffset = endOffset; } - + int32_t TermVectorOffsetInfo::getStartOffset() { return startOffset; } - + void TermVectorOffsetInfo::setStartOffset(int32_t startOffset) { this->startOffset = startOffset; } - + bool TermVectorOffsetInfo::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -56,7 +56,7 @@ namespace Lucene return false; return (endOffset == otherTermVector->endOffset && startOffset == otherTermVector->startOffset); } - + int32_t TermVectorOffsetInfo::hashCode() { int32_t result = startOffset; diff --git a/src/core/index/TermVectorsReader.cpp b/src/core/index/TermVectorsReader.cpp index 155df37c..448a1ce4 100644 --- a/src/core/index/TermVectorsReader.cpp +++ b/src/core/index/TermVectorsReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,22 +19,22 @@ namespace Lucene { /// NOTE: if you make a new format, it must be larger than the current format const int32_t TermVectorsReader::FORMAT_VERSION = 2; - + /// Changes to speed up bulk merging of term vectors const int32_t TermVectorsReader::FORMAT_VERSION2 = 3; - + /// Changed strings to UTF8 with length-in-bytes not length-in-chars const int32_t TermVectorsReader::FORMAT_UTF8_LENGTH_IN_BYTES = 4; - + /// NOTE: always change this if you switch to a new format const int32_t TermVectorsReader::FORMAT_CURRENT = TermVectorsReader::FORMAT_UTF8_LENGTH_IN_BYTES; - + /// The size in bytes that the FORMAT_VERSION will take up at the beginning of each file const int32_t TermVectorsReader::FORMAT_SIZE = 4; - + const uint8_t TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR = 0x1; const uint8_t TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR = 0x2; - + TermVectorsReader::TermVectorsReader() { this->_size = 0; @@ -42,28 +42,28 @@ namespace Lucene this->docStoreOffset = 0; this->format = 0; } - + TermVectorsReader::TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos) { ConstructReader(d, segment, fieldInfos, BufferedIndexInput::BUFFER_SIZE, -1, 0); } - + TermVectorsReader::TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { ConstructReader(d, segment, fieldInfos, readBufferSize, docStoreOffset, size); } - + TermVectorsReader::~TermVectorsReader() { } - + void TermVectorsReader::ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { this->_size = 0; this->numTotalDocs = 0; this->docStoreOffset = 0; this->format = 0; - + bool success = false; LuceneException finally; try @@ -76,10 +76,10 @@ namespace Lucene int32_t tvdFormat = checkValidFormat(tvd); tvf = d->openInput(segment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION(), readBufferSize); int32_t tvfFormat = checkValidFormat(tvf); - + BOOST_ASSERT(format == tvdFormat); BOOST_ASSERT(format == tvfFormat); - + if (format >= FORMAT_VERSION2) { BOOST_ASSERT((tvx->length() - FORMAT_SIZE) % 16 == 0); @@ -90,7 +90,7 @@ namespace Lucene BOOST_ASSERT((tvx->length() - FORMAT_SIZE) % 8 == 0); numTotalDocs = (int32_t)(tvx->length() >> 3); } - + if (docStoreOffset == -1) { this->docStoreOffset = 0; @@ -111,7 +111,7 @@ namespace Lucene // FieldInfos.hasVectors returns true yet the term vector files don't exist. format = 0; } - + this->fieldInfos = fieldInfos; success = true; } @@ -119,24 +119,24 @@ namespace Lucene { finally = e; } - - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception + + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception // above. In this case, we want to explicitly close any subset of things that were opened. if (!success) close(); finally.throwException(); } - + IndexInputPtr TermVectorsReader::getTvdStream() { return tvd; } - + IndexInputPtr TermVectorsReader::getTvfStream() { return tvf; } - + void TermVectorsReader::seekTvx(int32_t docNum) { if (format < FORMAT_VERSION2) @@ -144,12 +144,12 @@ namespace Lucene else tvx->seek((docNum + docStoreOffset) * 16 + FORMAT_SIZE); } - + bool TermVectorsReader::canReadRawDocs() { return (format >= FORMAT_UTF8_LENGTH_IN_BYTES); } - + void TermVectorsReader::rawDocs(Collection tvdLengths, Collection tvfLengths, int32_t startDocID, int32_t numDocs) { if (!tvx) @@ -158,22 +158,22 @@ namespace Lucene MiscUtils::arrayFill(tvfLengths.begin(), 0, tvfLengths.size(), 0); return; } - + // SegmentMerger calls canReadRawDocs() first and should not call us if that returns false. if (format < FORMAT_VERSION2) boost::throw_exception(IllegalStateException(L"cannot read raw docs with older term vector formats")); - + seekTvx(startDocID); - + int64_t tvdPosition = tvx->readLong(); tvd->seek(tvdPosition); - + int64_t tvfPosition = tvx->readLong(); tvf->seek(tvfPosition); - + int64_t lastTvdPosition = tvdPosition; int64_t lastTvfPosition = tvfPosition; - + int32_t count = 0; while (count < numDocs) { @@ -197,19 +197,19 @@ namespace Lucene lastTvfPosition = tvfPosition; } } - + int32_t TermVectorsReader::checkValidFormat(IndexInputPtr in) { int32_t format = in->readInt(); if (format > FORMAT_CURRENT) { - boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + - StringUtils::toString(format) + L" expected " + + boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + + StringUtils::toString(format) + L" expected " + StringUtils::toString(FORMAT_CURRENT) + L" or less")); } return format; } - + void TermVectorsReader::close() { // make all effort to close up. Keep the first exception and throw it as a new one. @@ -252,27 +252,27 @@ namespace Lucene } keep.throwException(); } - + int32_t TermVectorsReader::size() { return _size; } - + void TermVectorsReader::get(int32_t docNum, const String& field, TermVectorMapperPtr mapper) { if (tvx) { int32_t fieldNumber = fieldInfos->fieldNumber(field); - - // We need to account for the FORMAT_SIZE at when seeking in the tvx. We don't need to do + + // We need to account for the FORMAT_SIZE at when seeking in the tvx. We don't need to do // this in other seeks because we already have the file pointer that was written in another file seekTvx(docNum); int64_t tvdPosition = tvx->readLong(); - + tvd->seek(tvdPosition); int32_t fieldCount = tvd->readVInt(); - - // There are only a few fields per document. We opt for a full scan rather then requiring that they + + // There are only a few fields per document. We opt for a full scan rather then requiring that they // be ordered. We need to read through all of the fields anyway to get to the tvf pointers. int32_t number = 0; int32_t found = -1; @@ -282,11 +282,11 @@ namespace Lucene number = tvd->readVInt(); else number += tvd->readVInt(); - + if (number == fieldNumber) found = i; } - + // This field, although valid in the segment, was not found in this document if (found != -1) { @@ -298,13 +298,13 @@ namespace Lucene position = tvd->readVLong(); for (int32_t i = 1; i <= found; ++i) position += tvd->readVLong(); - + mapper->setDocumentNumber(docNum); readTermVector(field, position, mapper); } } } - + TermFreqVectorPtr TermVectorsReader::get(int32_t docNum, const String& field) { // Check if no term vectors are available for this segment at all @@ -312,12 +312,12 @@ namespace Lucene get(docNum, field, mapper); return mapper->materializeVector(); } - + Collection TermVectorsReader::readFields(int32_t fieldCount) { int32_t number = 0; Collection fields(Collection::newInstance(fieldCount)); - + for (int32_t i = 0; i < fieldCount; ++i) { if (format >= FORMAT_VERSION) @@ -326,10 +326,10 @@ namespace Lucene number += tvd->readVInt(); fields[i] = fieldInfos->fieldName(number); } - + return fields; } - + Collection TermVectorsReader::readTvfPointers(int32_t fieldCount) { // Compute position in the tvf file @@ -338,19 +338,19 @@ namespace Lucene position = tvx->readLong(); else position = tvd->readVLong(); - + Collection tvfPointers(Collection::newInstance(fieldCount)); tvfPointers[0] = position; - + for (int32_t i = 1; i < fieldCount; ++i) { position += tvd->readVLong(); tvfPointers[i] = position; } - + return tvfPointers; } - + Collection TermVectorsReader::get(int32_t docNum) { Collection result; @@ -359,10 +359,10 @@ namespace Lucene // We need to offset by seekTvx(docNum); int64_t tvdPosition = tvx->readLong(); - + tvd->seek(tvdPosition); int32_t fieldCount = tvd->readVInt(); - + // No fields are vectorized for this document if (fieldCount != 0) { @@ -373,7 +373,7 @@ namespace Lucene } return result; } - + void TermVectorsReader::get(int32_t docNumber, TermVectorMapperPtr mapper) { // Check if no term vectors are available for this segment at all @@ -382,10 +382,10 @@ namespace Lucene // We need to offset by seekTvx(docNumber); int64_t tvdPosition = tvx->readLong(); - + tvd->seek(tvdPosition); int32_t fieldCount = tvd->readVInt(); - + // No fields are vectorized for this document if (fieldCount != 0) { @@ -396,7 +396,7 @@ namespace Lucene } } } - + Collection TermVectorsReader::readTermVectors(int32_t docNum, Collection fields, Collection tvfPointers) { Collection res(Collection::newInstance(fields.size())); @@ -409,28 +409,28 @@ namespace Lucene } return res; } - + void TermVectorsReader::readTermVectors(Collection fields, Collection tvfPointers, TermVectorMapperPtr mapper) { for (int32_t i = 0; i < fields.size(); ++i) readTermVector(fields[i], tvfPointers[i], mapper); } - + void TermVectorsReader::readTermVector(const String& field, int64_t tvfPointer, TermVectorMapperPtr mapper) { - // Now read the data from specified position. We don't need to offset by the FORMAT here since + // Now read the data from specified position. We don't need to offset by the FORMAT here since // the pointer already includes the offset tvf->seek(tvfPointer); - + int32_t numTerms = tvf->readVInt(); - + // If no terms - return a constant empty termvector. However, this should never occur! if (numTerms == 0) return; - + bool storePositions; bool storeOffsets; - + if (format >= FORMAT_VERSION) { uint8_t bits = tvf->readByte(); @@ -443,7 +443,7 @@ namespace Lucene storePositions = false; storeOffsets = false; } - + mapper->setExpectations(field, numTerms, storeOffsets, storePositions); int32_t start = 0; int32_t deltaLength = 0; @@ -451,7 +451,7 @@ namespace Lucene ByteArray byteBuffer; CharArray charBuffer; bool preUTF8 = (format < FORMAT_UTF8_LENGTH_IN_BYTES); - + // init the buffers if (preUTF8) { @@ -463,15 +463,15 @@ namespace Lucene charBuffer.reset(); byteBuffer = ByteArray::newInstance(20); } - + for (int32_t i = 0; i < numTerms; ++i) { start = tvf->readVInt(); deltaLength = tvf->readVInt(); totalLength = start + deltaLength; - + String term; - + if (preUTF8) { // Term stored as "java chars" @@ -505,13 +505,13 @@ namespace Lucene } else { - // we need to skip over the positions. Since these are VInts, I don't believe there + // we need to skip over the positions. Since these are VInts, I don't believe there // is anyway to know for sure how far to skip for (int32_t j = 0; j < freq; ++j) tvf->readVInt(); } } - + Collection offsets; if (storeOffsets) { @@ -540,7 +540,7 @@ namespace Lucene mapper->map(term, freq, offsets, positions); } } - + LuceneObjectPtr TermVectorsReader::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -550,7 +550,7 @@ namespace Lucene cloneReader->numTotalDocs = numTotalDocs; cloneReader->docStoreOffset = docStoreOffset; cloneReader->format = format; - + // These are null when a TermVectorsReader was created on a segment that did not have term vectors saved if (tvx && tvd && tvf) { @@ -558,21 +558,21 @@ namespace Lucene cloneReader->tvd = boost::dynamic_pointer_cast(tvd->clone()); cloneReader->tvf = boost::dynamic_pointer_cast(tvf->clone()); } - + return cloneReader; } - + ParallelArrayTermVectorMapper::ParallelArrayTermVectorMapper() { currentPosition = 0; storingOffsets = false; storingPositions = false; } - + ParallelArrayTermVectorMapper::~ParallelArrayTermVectorMapper() { } - + void ParallelArrayTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { this->field = field; @@ -580,13 +580,13 @@ namespace Lucene termFreqs = Collection::newInstance(numTerms); this->storingOffsets = storeOffsets; this->storingPositions = storePositions; - + if (storePositions) this->positions = Collection< Collection >::newInstance(numTerms); if (storeOffsets) this->offsets = Collection< Collection >::newInstance(numTerms); } - + void ParallelArrayTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { terms[currentPosition] = term; @@ -594,10 +594,10 @@ namespace Lucene if (storingOffsets) this->offsets[currentPosition] = offsets; if (storingPositions) - this->positions[currentPosition] = positions; + this->positions[currentPosition] = positions; ++currentPosition; } - + TermFreqVectorPtr ParallelArrayTermVectorMapper::materializeVector() { SegmentTermVectorPtr tv; diff --git a/src/core/index/TermVectorsTermsWriter.cpp b/src/core/index/TermVectorsTermsWriter.cpp index 0f55ef7f..843937fa 100644 --- a/src/core/index/TermVectorsTermsWriter.cpp +++ b/src/core/index/TermVectorsTermsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -29,30 +29,30 @@ namespace Lucene this->_docWriter = docWriter; this->docFreeList = Collection::newInstance(1); } - + TermVectorsTermsWriter::~TermVectorsTermsWriter() { } - + TermsHashConsumerPerThreadPtr TermVectorsTermsWriter::addThread(TermsHashPerThreadPtr perThread) { return newLucene(perThread, shared_from_this()); } - + void TermVectorsTermsWriter::createPostings(Collection postings, int32_t start, int32_t count) { int32_t end = start + count; for (int32_t i = start; i < end; ++i) postings[i] = newLucene(); } - + void TermVectorsTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state) { SyncLock syncLock(this); - + // NOTE: it's possible that all documents seen in this segment hit non-aborting exceptions, in which case we will - // not have yet init'd the TermVectorsWriter. This is actually OK (unlike in the stored fields case) because, - // although IieldInfos.hasVectors() will return true, the TermVectorsReader gracefully handles non-existence of + // not have yet init'd the TermVectorsWriter. This is actually OK (unlike in the stored fields case) because, + // although IieldInfos.hasVectors() will return true, the TermVectorsReader gracefully handles non-existence of // the term vectors files. if (tvx) { @@ -61,12 +61,12 @@ namespace Lucene // In case there are some final documents that we didn't see (because they hit a non-aborting exception) fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); } - + tvx->flush(); tvd->flush(); tvf->flush(); } - + for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { for (Collection::iterator field = entry->second.begin(); field != entry->second.end(); ++field) @@ -75,19 +75,19 @@ namespace Lucene TermsHashPerFieldPtr(perField->_termsHashPerField)->reset(); perField->shrinkHash(); } - + TermVectorsTermsWriterPerThreadPtr perThread(boost::static_pointer_cast(entry->first)); TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(true); } } - + void TermVectorsTermsWriter::closeDocStore(SegmentWriteStatePtr state) { SyncLock syncLock(this); if (tvx) { DocumentsWriterPtr docWriter(_docWriter); - + // At least one doc in this run had term vectors enabled fill(state->numDocsInStore - docWriter->getDocStoreOffset()); tvx->close(); @@ -98,24 +98,24 @@ namespace Lucene String fileName(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); if (4 + ((int64_t)state->numDocsInStore) * 16 != state->directory->fileLength(fileName)) { - boost::throw_exception(RuntimeException(L"after flush: tvx size mismatch: " + StringUtils::toString(state->numDocsInStore) + - L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + - L" length in bytes of " + fileName + L" file exists?=" + + boost::throw_exception(RuntimeException(L"after flush: tvx size mismatch: " + StringUtils::toString(state->numDocsInStore) + + L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + + L" length in bytes of " + fileName + L" file exists?=" + StringUtils::toString(state->directory->fileExists(fileName)))); } - + state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - + docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - + lastDocID = 0; } } - + TermVectorsTermsWriterPerDocPtr TermVectorsTermsWriter::getPerDoc() { SyncLock syncLock(this); @@ -123,7 +123,7 @@ namespace Lucene { if (++allocCount > docFreeList.size()) { - // Grow our free list up front to make sure we have enough space to recycle all outstanding + // Grow our free list up front to make sure we have enough space to recycle all outstanding // PerDoc instances BOOST_ASSERT(allocCount == 1 + docFreeList.size()); docFreeList.resize(MiscUtils::getNextSize(allocCount)); @@ -133,7 +133,7 @@ namespace Lucene else return docFreeList[--freeCount]; } - + void TermVectorsTermsWriter::fill(int32_t docID) { int32_t docStoreOffset = DocumentsWriterPtr(_docWriter)->getDocStoreOffset(); @@ -150,52 +150,52 @@ namespace Lucene } } } - + void TermVectorsTermsWriter::initTermVectorsWriter() { SyncLock syncLock(this); if (!tvx) { DocumentsWriterPtr docWriter(_docWriter); - + String docStoreSegment(docWriter->getDocStoreSegment()); if (docStoreSegment.empty()) return; - + // If we hit an exception while init'ing the term vector output files, we must abort this segment // because those files will be in an unknown state tvx = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); tvd = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); tvf = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); - + tvx->writeInt(TermVectorsReader::FORMAT_CURRENT); tvd->writeInt(TermVectorsReader::FORMAT_CURRENT); tvf->writeInt(TermVectorsReader::FORMAT_CURRENT); - + docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - + lastDocID = 0; } } - + void TermVectorsTermsWriter::finishDocument(TermVectorsTermsWriterPerDocPtr perDoc) { SyncLock syncLock(this); DocumentsWriterPtr docWriter(_docWriter); - + BOOST_ASSERT(IndexWriterPtr(docWriter->_writer)->testPoint(L"TermVectorsTermsWriter.finishDocument start")); - + initTermVectorsWriter(); - + fill(perDoc->docID); - + // Append term vectors to the real outputs tvx->writeLong(tvd->getFilePointer()); tvx->writeLong(tvf->getFilePointer()); tvd->writeVInt(perDoc->numVectorFields); - + if (perDoc->numVectorFields > 0) { for (int32_t i = 0; i < perDoc->numVectorFields; ++i) @@ -211,22 +211,22 @@ namespace Lucene perDoc->perDocTvf->writeTo(tvf); perDoc->numVectorFields = 0; } - + BOOST_ASSERT(lastDocID == perDoc->docID + docWriter->getDocStoreOffset()); - + ++lastDocID; - + perDoc->reset(); free(perDoc); BOOST_ASSERT(IndexWriterPtr(docWriter->_writer)->testPoint(L"TermVectorsTermsWriter.finishDocument end")); } - + bool TermVectorsTermsWriter::freeRAM() { // We don't hold any state beyond one doc, so we don't free persistent RAM here return false; } - + void TermVectorsTermsWriter::abort() { if (tvx) @@ -264,19 +264,19 @@ namespace Lucene } lastDocID = 0; } - + void TermVectorsTermsWriter::free(TermVectorsTermsWriterPerDocPtr doc) { SyncLock syncLock(this); BOOST_ASSERT(freeCount < docFreeList.size()); docFreeList[freeCount++] = doc; } - + int32_t TermVectorsTermsWriter::bytesPerPosting() { return (RawPostingList::BYTES_SIZE + 3 * DocumentsWriter::INT_NUM_BYTE); } - + TermVectorsTermsWriterPerDoc::TermVectorsTermsWriterPerDoc(TermVectorsTermsWriterPtr termsWriter) { this->_termsWriter = termsWriter; @@ -286,24 +286,24 @@ namespace Lucene fieldNumbers = Collection::newInstance(1); fieldPointers = Collection::newInstance(1); } - + TermVectorsTermsWriterPerDoc::~TermVectorsTermsWriterPerDoc() { } - + void TermVectorsTermsWriterPerDoc::reset() { perDocTvf->reset(); buffer->recycle(); numVectorFields = 0; } - + void TermVectorsTermsWriterPerDoc::abort() { reset(); TermVectorsTermsWriterPtr(_termsWriter)->free(shared_from_this()); } - + void TermVectorsTermsWriterPerDoc::addField(int32_t fieldNumber) { if (numVectorFields == fieldNumbers.size()) @@ -315,24 +315,24 @@ namespace Lucene fieldPointers[numVectorFields] = perDocTvf->getFilePointer(); ++numVectorFields; } - + int64_t TermVectorsTermsWriterPerDoc::sizeInBytes() { return buffer->getSizeInBytes(); } - + void TermVectorsTermsWriterPerDoc::finish() { TermVectorsTermsWriterPtr(_termsWriter)->finishDocument(shared_from_this()); } - + TermVectorsTermsWriterPostingList::TermVectorsTermsWriterPostingList() { freq = 0; lastOffset = 0; lastPosition = 0; } - + TermVectorsTermsWriterPostingList::~TermVectorsTermsWriterPostingList() { } diff --git a/src/core/index/TermVectorsTermsWriterPerField.cpp b/src/core/index/TermVectorsTermsWriterPerField.cpp index a0e14871..321b6d1c 100644 --- a/src/core/index/TermVectorsTermsWriterPerField.cpp +++ b/src/core/index/TermVectorsTermsWriterPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -31,7 +31,7 @@ namespace Lucene this->doVectorPositions = false; this->doVectorOffsets = false; this->maxNumPostings = 0; - + this->_termsHashPerField = termsHashPerField; this->_perThread = perThread; this->_termsWriter = perThread->_termsWriter; @@ -39,22 +39,22 @@ namespace Lucene _docState = termsHashPerField->docState; _fieldState = termsHashPerField->fieldState; } - + TermVectorsTermsWriterPerField::~TermVectorsTermsWriterPerField() { } - + int32_t TermVectorsTermsWriterPerField::getStreamCount() { return 2; } - + bool TermVectorsTermsWriterPerField::start(Collection fields, int32_t count) { doVectors = false; doVectorPositions = false; doVectorOffsets = false; - + for (int32_t i = 0; i < count; ++i) { FieldablePtr field(fields[i]); @@ -67,7 +67,7 @@ namespace Lucene doVectorOffsets = true; } } - + if (doVectors) { TermVectorsTermsWriterPerThreadPtr perThread(_perThread); @@ -82,81 +82,81 @@ namespace Lucene } BOOST_ASSERT(perThread->doc->docID == docState->docID); - + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - + if (termsHashPerField->numPostings != 0) { - // Only necessary if previous doc hit a non-aborting exception while writing vectors + // Only necessary if previous doc hit a non-aborting exception while writing vectors // in this field termsHashPerField->reset(); TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(false); } } - + return doVectors; } - + void TermVectorsTermsWriterPerField::abort() { } - + void TermVectorsTermsWriterPerField::finish() { BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.finish start")); - + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); int32_t numPostings = termsHashPerField->numPostings; - + BOOST_ASSERT(numPostings >= 0); - + if (!doVectors || numPostings == 0) return; - + if (numPostings > maxNumPostings) maxNumPostings = numPostings; - + TermVectorsTermsWriterPerThreadPtr perThread(_perThread); IndexOutputPtr tvf(perThread->doc->perDocTvf); - + // This is called once, after inverting all occurrences of a given field in the doc. At this point we flush // our hash into the DocWriter. - + BOOST_ASSERT(fieldInfo->storeTermVector); BOOST_ASSERT(perThread->vectorFieldsInOrder(fieldInfo)); - + perThread->doc->addField(termsHashPerField->fieldInfo->number); - + Collection postings(termsHashPerField->sortPostings()); - + tvf->writeVInt(numPostings); uint8_t bits = 0x0; if (doVectorPositions) bits |= TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR; - if (doVectorOffsets) + if (doVectorOffsets) bits |= TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR; tvf->writeByte(bits); - + int32_t encoderUpto = 0; int32_t lastTermBytesCount = 0; - + ByteSliceReaderPtr reader(perThread->vectorSliceReader); Collection charBuffers(TermsHashPerThreadPtr(perThread->_termsHashPerThread)->charPool->buffers); - + for (int32_t j = 0; j < numPostings; ++j) { TermVectorsTermsWriterPostingListPtr posting(boost::static_pointer_cast(postings[j])); int32_t freq = posting->freq; - + CharArray text2(charBuffers[posting->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]); int32_t start2 = (posting->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - + // We swap between two encoders to save copying last Term's byte array UTF8ResultPtr utf8Result(perThread->utf8Results[encoderUpto]); - + StringUtils::toUTF8(text2.get() + start2, text2.size(), utf8Result); int32_t termBytesCount = utf8Result->length; - + // Compute common prefix between last term and this term int32_t prefix = 0; if (j > 0) @@ -172,40 +172,40 @@ namespace Lucene } encoderUpto = 1 - encoderUpto; lastTermBytesCount = termBytesCount; - + int32_t suffix = termBytesCount - prefix; tvf->writeVInt(prefix); tvf->writeVInt(suffix); tvf->writeBytes(utf8Result->result.get(), prefix, suffix); tvf->writeVInt(freq); - + if (doVectorPositions) { termsHashPerField->initReader(reader, posting, 0); reader->writeTo(tvf); } - + if (doVectorOffsets) { termsHashPerField->initReader(reader, posting, 1); reader->writeTo(tvf); } } - + termsHashPerField->reset(); - + // NOTE: we clear per-field at the thread level, because term vectors fully write themselves on each - // field; this saves RAM (eg if large doc has two large fields with term vectors on) because we + // field; this saves RAM (eg if large doc has two large fields with term vectors on) because we // recycle/reuse all RAM after each field TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(false); } - + void TermVectorsTermsWriterPerField::shrinkHash() { TermsHashPerFieldPtr(_termsHashPerField)->shrinkHash(maxNumPostings); maxNumPostings = 0; } - + void TermVectorsTermsWriterPerField::start(FieldablePtr field) { if (doVectorOffsets) @@ -213,63 +213,63 @@ namespace Lucene else offsetAttribute.reset(); } - + void TermVectorsTermsWriterPerField::newTerm(RawPostingListPtr p0) { BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); - + TermVectorsTermsWriterPostingListPtr p(boost::static_pointer_cast(p0)); - + p->freq = 1; - + FieldInvertStatePtr fieldState(_fieldState); TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - + if (doVectorOffsets) { int32_t startOffset = fieldState->offset + offsetAttribute->startOffset(); int32_t endOffset = fieldState->offset + offsetAttribute->endOffset(); - + termsHashPerField->writeVInt(1, startOffset); termsHashPerField->writeVInt(1, endOffset - startOffset); p->lastOffset = endOffset; } - + if (doVectorPositions) { termsHashPerField->writeVInt(0, fieldState->position); p->lastPosition = fieldState->position; } } - + void TermVectorsTermsWriterPerField::addTerm(RawPostingListPtr p0) { BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); - + TermVectorsTermsWriterPostingListPtr p(boost::static_pointer_cast(p0)); - + ++p->freq; - + FieldInvertStatePtr fieldState(_fieldState); TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - + if (doVectorOffsets) { int32_t startOffset = fieldState->offset + offsetAttribute->startOffset(); int32_t endOffset = fieldState->offset + offsetAttribute->endOffset(); - + termsHashPerField->writeVInt(1, startOffset - p->lastOffset); termsHashPerField->writeVInt(1, endOffset - startOffset); p->lastOffset = endOffset; } - + if (doVectorPositions) { termsHashPerField->writeVInt(0, fieldState->position - p->lastPosition); p->lastPosition = fieldState->position; } } - + void TermVectorsTermsWriterPerField::skippingLongTerm() { } diff --git a/src/core/index/TermVectorsTermsWriterPerThread.cpp b/src/core/index/TermVectorsTermsWriterPerThread.cpp index ac1b6dcd..6acea3db 100644 --- a/src/core/index/TermVectorsTermsWriterPerThread.cpp +++ b/src/core/index/TermVectorsTermsWriterPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,11 +24,11 @@ namespace Lucene this->_termsHashPerThread = termsHashPerThread; _docState = termsHashPerThread->docState; } - + TermVectorsTermsWriterPerThread::~TermVectorsTermsWriterPerThread() { } - + void TermVectorsTermsWriterPerThread::startDocument() { BOOST_ASSERT(clearLastVectorFieldName()); @@ -38,19 +38,19 @@ namespace Lucene doc->docID = DocStatePtr(_docState)->docID; } } - + DocWriterPtr TermVectorsTermsWriterPerThread::finishDocument() { DocWriterPtr returnDoc(doc); doc.reset(); return returnDoc; } - + TermsHashConsumerPerFieldPtr TermVectorsTermsWriterPerThread::addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo) { return newLucene(termsHashPerField, shared_from_this(), fieldInfo); } - + void TermVectorsTermsWriterPerThread::abort() { if (doc) @@ -59,13 +59,13 @@ namespace Lucene doc.reset(); } } - + bool TermVectorsTermsWriterPerThread::clearLastVectorFieldName() { lastVectorFieldName.clear(); return true; } - + bool TermVectorsTermsWriterPerThread::vectorFieldsInOrder(FieldInfoPtr fi) { bool inOrder = lastVectorFieldName.empty() ? true : (lastVectorFieldName < fi->name); diff --git a/src/core/index/TermVectorsWriter.cpp b/src/core/index/TermVectorsWriter.cpp index 6a8dbf91..344bfa16 100644 --- a/src/core/index/TermVectorsWriter.cpp +++ b/src/core/index/TermVectorsWriter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,7 +22,7 @@ namespace Lucene TermVectorsWriter::TermVectorsWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fieldInfos) { utf8Results = newCollection(newInstance(), newInstance()); - + // Open files for TermVector storage tvx = directory->createOutput(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); tvx->writeInt(TermVectorsReader::FORMAT_CURRENT); @@ -33,41 +33,41 @@ namespace Lucene this->fieldInfos = fieldInfos; } - + TermVectorsWriter::~TermVectorsWriter() { } - + void TermVectorsWriter::addAllDocVectors(Collection vectors) { tvx->writeLong(tvd->getFilePointer()); tvx->writeLong(tvf->getFilePointer()); - + if (vectors) { int32_t numFields = vectors.size(); tvd->writeVInt(numFields); - + Collection fieldPointers(Collection::newInstance(numFields)); - + for (int32_t i = 0; i < numFields; ++i) { fieldPointers[i] = tvf->getFilePointer(); - + int32_t fieldNumber = fieldInfos->fieldNumber(vectors[i]->getField()); - + // 1st pass: write field numbers to tvd tvd->writeVInt(fieldNumber); - + int32_t numTerms = vectors[i]->size(); tvf->writeVInt(numTerms); - + TermPositionVectorPtr tpVector(boost::dynamic_pointer_cast(vectors[i])); - + uint8_t bits; bool storePositions; bool storeOffsets; - + if (tpVector) { // May have positions & offsets @@ -82,18 +82,18 @@ namespace Lucene storePositions = false; storeOffsets = false; } - + tvf->writeVInt(bits); Collection terms(vectors[i]->getTerms()); Collection freqs(vectors[i]->getTermFrequencies()); - + int32_t utf8Upto = 0; utf8Results[1]->length = 0; - + for (int32_t j = 0; j < numTerms; ++j) { StringUtils::toUTF8(terms[j].c_str(), terms[j].length(), utf8Results[utf8Upto]); - + int32_t start = MiscUtils::bytesDifference(utf8Results[1 - utf8Upto]->result.get(), utf8Results[1 - utf8Upto]->length, utf8Results[utf8Upto]->result.get(), utf8Results[utf8Upto]->length); int32_t length = utf8Results[utf8Upto]->length - start; @@ -101,17 +101,17 @@ namespace Lucene tvf->writeVInt(length); // write delta length tvf->writeBytes(utf8Results[utf8Upto]->result.get(), start, length); // write delta bytes utf8Upto = 1 - utf8Upto; - + int32_t termFreq = freqs[j]; tvf->writeVInt(termFreq); - + if (storePositions) { Collection positions(tpVector->getTermPositions(j)); if (!positions) boost::throw_exception(IllegalStateException(L"Trying to write positions that are null!")); BOOST_ASSERT(positions.size() == termFreq); - + // use delta encoding for positions int32_t lastPosition = 0; for (int32_t k = 0; k < positions.size(); ++k) @@ -121,14 +121,14 @@ namespace Lucene lastPosition = position; } } - + if (storeOffsets) { Collection offsets(tpVector->getOffsets(j)); if (!offsets) boost::throw_exception(IllegalStateException(L"Trying to write offsets that are null!")); BOOST_ASSERT(offsets.size() == termFreq); - + // use delta encoding for offsets int32_t lastEndOffset = 0; for (int32_t k = 0; k < offsets.size(); ++k) @@ -142,7 +142,7 @@ namespace Lucene } } } - + // 2nd pass: write field pointers to tvd if (numFields > 1) { @@ -158,7 +158,7 @@ namespace Lucene else tvd->writeVInt(0); } - + void TermVectorsWriter::addRawDocuments(TermVectorsReaderPtr reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs) { int64_t tvdPosition = tvd->getFilePointer(); @@ -177,10 +177,10 @@ namespace Lucene BOOST_ASSERT(tvd->getFilePointer() == tvdPosition); BOOST_ASSERT(tvf->getFilePointer() == tvfPosition); } - + void TermVectorsWriter::close() { - // make an effort to close all streams we can but remember and re-throw the first exception + // make an effort to close all streams we can but remember and re-throw the first exception // encountered in this process LuceneException keep; if (tvx) diff --git a/src/core/index/TermsHash.cpp b/src/core/index/TermsHash.cpp index 7cbc629d..7874a88a 100644 --- a/src/core/index/TermsHash.cpp +++ b/src/core/index/TermsHash.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,47 +24,47 @@ namespace Lucene this->postingsAllocCount = 0; this->trackAllocations = false; this->postingsFreeList = Collection::newInstance(1); - + this->_docWriter = docWriter; this->consumer = consumer; this->nextTermsHash = nextTermsHash; this->trackAllocations = trackAllocations; - + bytesPerPosting = consumer->bytesPerPosting() + 4 * DocumentsWriter::POINTER_NUM_BYTE; postingsFreeChunk = (int32_t)((double)DocumentsWriter::BYTE_BLOCK_SIZE / (double)bytesPerPosting); } - + TermsHash::~TermsHash() { } - + InvertedDocConsumerPerThreadPtr TermsHash::addThread(DocInverterPerThreadPtr docInverterPerThread) { return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, TermsHashPerThreadPtr()); } - + TermsHashPerThreadPtr TermsHash::addThread(DocInverterPerThreadPtr docInverterPerThread, TermsHashPerThreadPtr primaryPerThread) { return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, primaryPerThread); } - + void TermsHash::setFieldInfos(FieldInfosPtr fieldInfos) { this->fieldInfos = fieldInfos; consumer->setFieldInfos(fieldInfos); } - + void TermsHash::abort() { consumer->abort(); if (nextTermsHash) nextTermsHash->abort(); } - + void TermsHash::shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state) { BOOST_ASSERT(postingsFreeCount == postingsAllocCount); - + int32_t newSize = 1; if (newSize != postingsFreeList.size()) { @@ -78,7 +78,7 @@ namespace Lucene postingsFreeList.resize(newSize); } } - + void TermsHash::closeDocStore(SegmentWriteStatePtr state) { SyncLock syncLock(this); @@ -86,7 +86,7 @@ namespace Lucene if (nextTermsHash) nextTermsHash->closeDocStore(state); } - + void TermsHash::flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state) { SyncLock syncLock(this); @@ -94,39 +94,39 @@ namespace Lucene MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField nextThreadsAndFields; if (nextTermsHash) nextThreadsAndFields = MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::newInstance(); - + for (MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { Collection childFields(Collection::newInstance()); Collection nextChildFields; if (nextTermsHash) nextChildFields = Collection::newInstance(); - + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) { childFields.add(boost::static_pointer_cast(*perField)->consumer); if (nextTermsHash) nextChildFields.add(boost::static_pointer_cast(*perField)->nextPerField); } - + childThreadsAndFields.put(boost::static_pointer_cast(entry->first)->consumer, childFields); if (nextTermsHash) nextThreadsAndFields.put(boost::static_pointer_cast(entry->first)->nextPerThread, nextChildFields); } - + consumer->flush(childThreadsAndFields, state); - + shrinkFreePostings(threadsAndFields, state); - + if (nextTermsHash) nextTermsHash->flush(nextThreadsAndFields, state); } - + bool TermsHash::freeRAM() { if (!trackAllocations) return false; - + bool any = false; int64_t bytesFreed = 0; { @@ -142,68 +142,68 @@ namespace Lucene any = true; } } - + if (any) DocumentsWriterPtr(_docWriter)->bytesAllocated(bytesFreed); if (nextTermsHash && nextTermsHash->freeRAM()) any = true; - + return any; } - + void TermsHash::recyclePostings(Collection postings, int32_t numPostings) { SyncLock syncLock(this); BOOST_ASSERT(postings.size() >= numPostings); - - // Move all Postings from this ThreadState back to our free list. We pre-allocated this array while we + + // Move all Postings from this ThreadState back to our free list. We pre-allocated this array while we // were creating Postings to make sure it's large enough BOOST_ASSERT(postingsFreeCount + numPostings <= postingsFreeList.size()); MiscUtils::arrayCopy(postings.begin(), 0, postingsFreeList.begin(), postingsFreeCount, numPostings); postingsFreeCount += numPostings; } - + void TermsHash::getPostings(Collection postings) { SyncLock syncLock(this); DocumentsWriterPtr docWriter(_docWriter); IndexWriterPtr writer(docWriter->_writer); - + BOOST_ASSERT(writer->testPoint(L"TermsHash.getPostings start")); - + BOOST_ASSERT(postingsFreeCount <= postingsFreeList.size()); BOOST_ASSERT(postingsFreeCount <= postingsAllocCount); - + int32_t numToCopy = postingsFreeCount < postings.size() ? postingsFreeCount : postings.size(); int32_t start = postingsFreeCount - numToCopy; BOOST_ASSERT(start >= 0); BOOST_ASSERT(start + numToCopy <= postingsFreeList.size()); BOOST_ASSERT(numToCopy <= postings.size()); MiscUtils::arrayCopy(postingsFreeList.begin(), start, postings.begin(), 0, numToCopy); - + // Directly allocate the remainder if any if (numToCopy != postings.size()) { int32_t extra = postings.size() - numToCopy; int32_t newPostingsAllocCount = postingsAllocCount + extra; - + consumer->createPostings(postings, numToCopy, extra); BOOST_ASSERT(writer->testPoint(L"TermsHash.getPostings after create")); postingsAllocCount += extra; - + if (trackAllocations) docWriter->bytesAllocated(extra * bytesPerPosting); - + if (newPostingsAllocCount > postingsFreeList.size()) { // Pre-allocate the postingsFreeList so it's large enough to hold all postings we've given out postingsFreeList = Collection::newInstance(MiscUtils::getNextSize(newPostingsAllocCount)); } } - + postingsFreeCount -= numToCopy; - + if (trackAllocations) docWriter->bytesUsed(postings.size() * bytesPerPosting); } diff --git a/src/core/index/TermsHashConsumer.cpp b/src/core/index/TermsHashConsumer.cpp index 50c508c1..eb8f8308 100644 --- a/src/core/index/TermsHashConsumer.cpp +++ b/src/core/index/TermsHashConsumer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene TermsHashConsumer::~TermsHashConsumer() { } - + void TermsHashConsumer::setFieldInfos(FieldInfosPtr fieldInfos) { this->fieldInfos = fieldInfos; diff --git a/src/core/index/TermsHashConsumerPerField.cpp b/src/core/index/TermsHashConsumerPerField.cpp index 85bdfa0a..9e5df4d9 100644 --- a/src/core/index/TermsHashConsumerPerField.cpp +++ b/src/core/index/TermsHashConsumerPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/TermsHashConsumerPerThread.cpp b/src/core/index/TermsHashConsumerPerThread.cpp index ec8cc28e..295cb16f 100644 --- a/src/core/index/TermsHashConsumerPerThread.cpp +++ b/src/core/index/TermsHashConsumerPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/index/TermsHashPerField.cpp b/src/core/index/TermsHashPerField.cpp index bdf56822..5c8ff05b 100644 --- a/src/core/index/TermsHashPerField.cpp +++ b/src/core/index/TermsHashPerField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -31,11 +31,11 @@ namespace Lucene this->nextPerThread = nextPerThread; this->fieldInfo = fieldInfo; } - + TermsHashPerField::~TermsHashPerField() { } - + void TermsHashPerField::initialize() { this->postingsCompacted = false; @@ -47,7 +47,7 @@ namespace Lucene this->doCall = false; this->doNextCall = false; this->intUptoStart = 0; - + TermsHashPerThreadPtr perThread(_perThread); intPool = perThread->intPool; charPool = perThread->charPool; @@ -61,11 +61,11 @@ namespace Lucene if (nextPerThread) nextPerField = boost::dynamic_pointer_cast(nextPerThread->addField(docInverterPerField, fieldInfo)); } - + void TermsHashPerField::shrinkHash(int32_t targetSize) { BOOST_ASSERT(postingsCompacted || numPostings == 0); - + int32_t newSize = 4; if (newSize != postingsHash.size()) { @@ -76,7 +76,7 @@ namespace Lucene } MiscUtils::arrayFill(postingsHash.begin(), 0, postingsHash.size(), RawPostingListPtr()); } - + void TermsHashPerField::reset() { if (!postingsCompacted) @@ -92,7 +92,7 @@ namespace Lucene if (nextPerField) nextPerField->reset(); } - + void TermsHashPerField::abort() { SyncLock syncLock(this); @@ -100,7 +100,7 @@ namespace Lucene if (nextPerField) nextPerField->abort(); } - + void TermsHashPerField::initReader(ByteSliceReaderPtr reader, RawPostingListPtr p, int32_t stream) { BOOST_ASSERT(stream < streamCount); @@ -108,7 +108,7 @@ namespace Lucene int32_t upto = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); reader->init(bytePool, p->byteStart + stream * ByteBlockPool::FIRST_LEVEL_SIZE(), ints[upto + stream]); } - + void TermsHashPerField::compactPostings() { SyncLock syncLock(this); @@ -125,31 +125,31 @@ namespace Lucene ++upto; } } - + BOOST_ASSERT(upto == numPostings); postingsCompacted = true; } - + struct comparePostings { comparePostings(Collection buffers) { this->buffers = buffers; } - + /// Compares term text for two Posting instance inline bool operator()(const RawPostingListPtr& first, const RawPostingListPtr& second) const { if (first == second) return false; - + wchar_t* text1 = buffers[first->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); int32_t pos1 = (first->textStart & DocumentsWriter::CHAR_BLOCK_MASK); wchar_t* text2 = buffers[second->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); int32_t pos2 = (second->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - + BOOST_ASSERT(text1 != text2 || pos1 != pos2); - + while (true) { wchar_t c1 = text1[pos1++]; @@ -170,17 +170,17 @@ namespace Lucene } } } - + Collection buffers; }; - + Collection TermsHashPerField::sortPostings() { compactPostings(); std::sort(postingsHash.begin(), postingsHash.begin() + numPostings, comparePostings(charPool->buffers)); return postingsHash; } - + bool TermsHashPerField::postingEquals(const wchar_t* tokenText, int32_t tokenTextLen) { wchar_t* text = TermsHashPerThreadPtr(_perThread)->charPool->buffers[p->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); @@ -194,7 +194,7 @@ namespace Lucene } return (text[pos] == UTF8Base::UNICODE_TERMINATOR); } - + void TermsHashPerField::start(FieldablePtr field) { termAtt = fieldState->attributeSource->addAttribute(); @@ -202,7 +202,7 @@ namespace Lucene if (nextPerField) nextPerField->start(field); } - + bool TermsHashPerField::start(Collection fields, int32_t count) { doCall = consumer->start(fields, count); @@ -210,19 +210,19 @@ namespace Lucene doNextCall = nextPerField->start(fields, count); return (doCall || doNextCall); } - + void TermsHashPerField::add(int32_t textStart) { // Secondary entry point (for 2nd and subsequent TermsHash), we hash by textStart int32_t code = textStart; - + int32_t hashPos = (code & postingsHashMask); - + BOOST_ASSERT(!postingsCompacted); - + // Locate RawPostingList in hash p = postingsHash[hashPos]; - + if (p && p->textStart != textStart) { // Conflict: keep searching different locations in the hash table. @@ -235,49 +235,49 @@ namespace Lucene } while (p && p->textStart != textStart); } - + if (!p) { // First time we are seeing this token since we last flushed the hash. TermsHashPerThreadPtr perThread(_perThread); - + // Refill? if (perThread->freePostingsCount == 0) perThread->morePostings(); - + // Pull next free RawPostingList from free list p = perThread->freePostings[--perThread->freePostingsCount]; BOOST_ASSERT(p); - + p->textStart = textStart; - + BOOST_ASSERT(!postingsHash[hashPos]); postingsHash[hashPos] = p; ++numPostings; - + if (numPostings == postingsHashHalfSize) rehashPostings(2 * postingsHashSize); - + // Init stream slices if (numPostingInt + intPool->intUpto > DocumentsWriter::INT_BLOCK_SIZE) intPool->nextBuffer(); - + if (DocumentsWriter::BYTE_BLOCK_SIZE - bytePool->byteUpto < numPostingInt * ByteBlockPool::FIRST_LEVEL_SIZE()) bytePool->nextBuffer(); - + intUptos = intPool->buffer; intUptoStart = intPool->intUpto; intPool->intUpto += streamCount; - + p->intStart = intUptoStart + intPool->intOffset; - + for (int32_t i = 0; i < streamCount; ++i) { int32_t upto = bytePool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); intUptos[intUptoStart + i] = upto + bytePool->byteOffset; } p->byteStart = intUptos[intUptoStart]; - + consumer->newTerm(p); } else @@ -287,23 +287,23 @@ namespace Lucene consumer->addTerm(p); } } - + void TermsHashPerField::add() { BOOST_ASSERT(!postingsCompacted); - + // Get the text of this term. wchar_t* tokenText = termAtt->termBufferArray(); int32_t tokenTextLen = termAtt->termLength(); - + // Compute hashcode and replace any invalid UTF16 sequences int32_t downto = tokenTextLen; int32_t code = 0; - + while (downto > 0) { wchar_t ch = tokenText[--downto]; - + #ifdef LPP_UNICODE_CHAR_SIZE_2 if (ch >= UTF8Base::TRAIL_SURROGATE_MIN && ch <= UTF8Base::TRAIL_SURROGATE_MAX) { @@ -345,15 +345,15 @@ namespace Lucene tokenText[downto] = ch; } #endif - + code = (code * 31) + ch; } - + int32_t hashPos = (code & postingsHashMask); - + // Locate RawPostingList in hash p = postingsHash[hashPos]; - + if (p && !postingEquals(tokenText, tokenTextLen)) { // Conflict: keep searching different locations in the hash table. @@ -366,7 +366,7 @@ namespace Lucene } while (p && !postingEquals(tokenText, tokenTextLen)); } - + if (!p) { // First time we are seeing this token since we last flushed the hash. @@ -378,62 +378,62 @@ namespace Lucene // Just skip this term, to remain as robust as possible during indexing. A TokenFilter // can be inserted into the analyzer chain if other behavior is wanted (pruning the term // to a prefix, throwing an exception, etc). - + if (docState->maxTermPrefix.empty()) docState->maxTermPrefix.append(tokenText, std::min((int32_t)30, tokenTextLen)); - + consumer->skippingLongTerm(); return; } charPool->nextBuffer(); } - + TermsHashPerThreadPtr perThread(_perThread); - + // Refill? if (perThread->freePostingsCount == 0) perThread->morePostings(); - + // Pull next free RawPostingList from free list p = perThread->freePostings[--perThread->freePostingsCount]; BOOST_ASSERT(p); - + wchar_t* text = charPool->buffer.get(); int32_t textUpto = charPool->charUpto; - + p->textStart = textUpto + charPool->charOffset; charPool->charUpto += textLen1; - + MiscUtils::arrayCopy(tokenText, 0, text, textUpto, tokenTextLen); text[textUpto + tokenTextLen] = UTF8Base::UNICODE_TERMINATOR; - + BOOST_ASSERT(!postingsHash[hashPos]); postingsHash[hashPos] = p; ++numPostings; - + if (numPostings == postingsHashHalfSize) rehashPostings(2 * postingsHashSize); - + // Init stream slices if (numPostingInt + intPool->intUpto > DocumentsWriter::INT_BLOCK_SIZE) intPool->nextBuffer(); - + if (DocumentsWriter::BYTE_BLOCK_SIZE - bytePool->byteUpto < numPostingInt * ByteBlockPool::FIRST_LEVEL_SIZE()) bytePool->nextBuffer(); - + intUptos = intPool->buffer; intUptoStart = intPool->intUpto; intPool->intUpto += streamCount; - + p->intStart = intUptoStart + intPool->intOffset; - + for (int32_t i = 0; i < streamCount; ++i) { int32_t upto = bytePool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); intUptos[intUptoStart + i] = upto + bytePool->byteOffset; } p->byteStart = intUptos[intUptoStart]; - + consumer->newTerm(p); } else @@ -442,11 +442,11 @@ namespace Lucene intUptoStart = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); consumer->addTerm(p); } - + if (doNextCall) nextPerField->add(p->textStart); } - + void TermsHashPerField::writeByte(int32_t stream, int8_t b) { int32_t upto = intUptos[intUptoStart + stream]; @@ -463,14 +463,14 @@ namespace Lucene bytes[offset] = b; intUptos[intUptoStart + stream]++; } - + void TermsHashPerField::writeBytes(int32_t stream, const uint8_t* b, int32_t offset, int32_t length) { int32_t end = offset + length; for (int32_t i = offset; i < end; ++i) writeByte(stream, b[i]); } - + void TermsHashPerField::writeVInt(int32_t stream, int32_t i) { BOOST_ASSERT(stream < streamCount); @@ -481,21 +481,21 @@ namespace Lucene } writeByte(stream, (uint8_t)i); } - + void TermsHashPerField::finish() { consumer->finish(); if (nextPerField) nextPerField->finish(); } - + void TermsHashPerField::rehashPostings(int32_t newSize) { int32_t newMask = newSize - 1; - + Collection newHash(Collection::newInstance(newSize)); TermsHashPerThreadPtr perThread(_perThread); - + for (int32_t i = 0; i < postingsHashSize; ++i) { RawPostingListPtr p0(postingsHash[i]); @@ -515,7 +515,7 @@ namespace Lucene } else code = p0->textStart; - + int32_t hashPos = (code & newMask); BOOST_ASSERT(hashPos >= 0); if (newHash[hashPos]) @@ -531,7 +531,7 @@ namespace Lucene newHash[hashPos] = p0; } } - + postingsHashMask = newMask; postingsHash = newHash; postingsHashSize = newSize; diff --git a/src/core/index/TermsHashPerThread.cpp b/src/core/index/TermsHashPerThread.cpp index ff24f28c..e602ea7f 100644 --- a/src/core/index/TermsHashPerThread.cpp +++ b/src/core/index/TermsHashPerThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -27,18 +27,18 @@ namespace Lucene this->nextTermsHash = nextTermsHash; this->_primaryPerThread = primaryPerThread; } - + TermsHashPerThread::~TermsHashPerThread() { } - + void TermsHashPerThread::initialize() { DocInverterPerThreadPtr docInverterPerThread(_docInverterPerThread); TermsHashPtr termsHash(_termsHash); docState = docInverterPerThread->docState; consumer = termsHash->consumer->addThread(shared_from_this()); - + if (nextTermsHash) { // We are primary @@ -50,19 +50,19 @@ namespace Lucene charPool = TermsHashPerThreadPtr(_primaryPerThread)->charPool; primary = false; } - + intPool = newLucene(DocumentsWriterPtr(termsHash->_docWriter), termsHash->trackAllocations); bytePool = newLucene(DocumentsWriterPtr(termsHash->_docWriter)->byteBlockAllocator, termsHash->trackAllocations); - + if (nextTermsHash) nextPerThread = nextTermsHash->addThread(docInverterPerThread, shared_from_this()); } - + InvertedDocConsumerPerFieldPtr TermsHashPerThread::addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) { return newLucene(docInverterPerField, shared_from_this(), nextPerThread, fieldInfo); } - + void TermsHashPerThread::abort() { SyncLock syncLock(this); @@ -71,7 +71,7 @@ namespace Lucene if (nextPerThread) nextPerThread->abort(); } - + void TermsHashPerThread::morePostings() { BOOST_ASSERT(freePostingsCount == 0); @@ -79,7 +79,7 @@ namespace Lucene freePostingsCount = freePostings.size(); BOOST_ASSERT(noNullPostings(freePostings, freePostingsCount, L"consumer=" + consumer->toString())); } - + bool TermsHashPerThread::noNullPostings(Collection postings, int32_t count, const String& details) { for (int32_t i = 0; i < count; ++i) @@ -88,14 +88,14 @@ namespace Lucene } return true; } - + void TermsHashPerThread::startDocument() { consumer->startDocument(); if (nextPerThread) nextPerThread->consumer->startDocument(); } - + DocWriterPtr TermsHashPerThread::finishDocument() { DocWriterPtr doc(consumer->finishDocument()); @@ -113,10 +113,10 @@ namespace Lucene { intPool->reset(); bytePool->reset(); - + if (primary) charPool->reset(); - + if (recyclePostings) { TermsHashPtr(_termsHash)->recyclePostings(freePostings, freePostingsCount); diff --git a/src/core/msvc/LuceneInc.cpp b/src/core/msvc/LuceneInc.cpp index e53579e2..18915650 100644 --- a/src/core/msvc/LuceneInc.cpp +++ b/src/core/msvc/LuceneInc.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/msvc/dllmain.cpp b/src/core/msvc/dllmain.cpp index e3847950..02ab59e1 100644 --- a/src/core/msvc/dllmain.cpp +++ b/src/core/msvc/dllmain.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/queryparser/FastCharStream.cpp b/src/core/queryparser/FastCharStream.cpp index ff26acdd..eb696b36 100644 --- a/src/core/queryparser/FastCharStream.cpp +++ b/src/core/queryparser/FastCharStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,22 +19,22 @@ namespace Lucene tokenStart = 0; bufferStart = 0; } - + FastCharStream::~FastCharStream() { } - + wchar_t FastCharStream::readChar() { if (bufferPosition >= bufferLength) refill(); return buffer[bufferPosition++]; } - + void FastCharStream::refill() { int32_t newPosition = bufferLength - tokenStart; - + if (tokenStart == 0) // token won't fit in buffer { if (!buffer) @@ -44,42 +44,42 @@ namespace Lucene } else // shift token to front MiscUtils::arrayCopy(buffer.get(), tokenStart, buffer.get(), 0, newPosition); - + bufferLength = newPosition; // update state bufferPosition = newPosition; bufferStart += tokenStart; tokenStart = 0; - + int32_t charsRead = input->read(buffer.get(), newPosition, buffer.size() - newPosition); // fill space in buffer if (charsRead == -1) boost::throw_exception(IOException(L"read past eof")); else bufferLength += charsRead; } - + wchar_t FastCharStream::BeginToken() { tokenStart = bufferPosition; return readChar(); } - + void FastCharStream::backup(int32_t amount) { bufferPosition -= amount; } - + String FastCharStream::GetImage() { return String(buffer.get() + tokenStart, bufferPosition - tokenStart); } - + CharArray FastCharStream::GetSuffix(int32_t length) { CharArray value(CharArray::newInstance(length)); MiscUtils::arrayCopy(buffer.get(), bufferPosition - length, value.get(), 0, length); return value; } - + void FastCharStream::Done() { try @@ -91,32 +91,32 @@ namespace Lucene // ignore IO exceptions } } - + int32_t FastCharStream::getColumn() { return bufferStart + bufferPosition; } - + int32_t FastCharStream::getLine() { return 1; } - + int32_t FastCharStream::getEndColumn() { return bufferStart + bufferPosition; } - + int32_t FastCharStream::getEndLine() { return 1; } - + int32_t FastCharStream::getBeginColumn() { return bufferStart + tokenStart; } - + int32_t FastCharStream::getBeginLine() { return 1; diff --git a/src/core/queryparser/MultiFieldQueryParser.cpp b/src/core/queryparser/MultiFieldQueryParser.cpp index 1ddee72b..d9594143 100644 --- a/src/core/queryparser/MultiFieldQueryParser.cpp +++ b/src/core/queryparser/MultiFieldQueryParser.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,16 +19,16 @@ namespace Lucene this->boosts = boosts; this->fields = fields; } - + MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, AnalyzerPtr analyzer) : QueryParser(matchVersion, L"", analyzer) { this->fields = fields; } - + MultiFieldQueryParser::~MultiFieldQueryParser() { } - + QueryPtr MultiFieldQueryParser::getFieldQuery(const String& field, const String& queryText, int32_t slop) { if (field.empty()) @@ -59,12 +59,12 @@ namespace Lucene applySlop(query, slop); return query; } - + QueryPtr MultiFieldQueryParser::getFieldQuery(const String& field, const String& queryText) { return getFieldQuery(field, queryText, 0); } - + void MultiFieldQueryParser::applySlop(QueryPtr query, int32_t slop) { if (MiscUtils::typeOf(query)) @@ -72,7 +72,7 @@ namespace Lucene if (MiscUtils::typeOf(query)) boost::dynamic_pointer_cast(query)->setSlop(slop); } - + QueryPtr MultiFieldQueryParser::getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) { if (field.empty()) @@ -84,7 +84,7 @@ namespace Lucene } return QueryParser::getFuzzyQuery(field, termStr, minSimilarity); } - + QueryPtr MultiFieldQueryParser::getPrefixQuery(const String& field, const String& termStr) { if (field.empty()) @@ -96,7 +96,7 @@ namespace Lucene } return QueryParser::getPrefixQuery(field, termStr); } - + QueryPtr MultiFieldQueryParser::getWildcardQuery(const String& field, const String& termStr) { if (field.empty()) @@ -108,7 +108,7 @@ namespace Lucene } return QueryParser::getWildcardQuery(field, termStr); } - + QueryPtr MultiFieldQueryParser::getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) { if (field.empty()) @@ -120,7 +120,7 @@ namespace Lucene } return QueryParser::getRangeQuery(field, part1, part2, inclusive); } - + QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, AnalyzerPtr analyzer) { if (queries.size() != fields.size()) @@ -135,7 +135,7 @@ namespace Lucene } return booleanQuery; } - + QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, AnalyzerPtr analyzer) { if (fields.size() != flags.size()) @@ -150,7 +150,7 @@ namespace Lucene } return booleanQuery; } - + QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, AnalyzerPtr analyzer) { if (queries.size() != fields.size() || fields.size() != flags.size()) diff --git a/src/core/queryparser/QueryParseError.cpp b/src/core/queryparser/QueryParseError.cpp index ab2ed2b3..2fac15b9 100644 --- a/src/core/queryparser/QueryParseError.cpp +++ b/src/core/queryparser/QueryParseError.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,8 +14,8 @@ namespace Lucene QueryParseError::~QueryParseError() { } - - String QueryParseError::lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, + + String QueryParseError::lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, const String& errorAfter, wchar_t curChar) { StringStream buffer; @@ -27,7 +27,7 @@ namespace Lucene buffer << L" (" << (int32_t)curChar << L"), after : \"" << addEscapes(errorAfter) + L"\""; return buffer.str(); } - + String QueryParseError::parseError(QueryParserTokenPtr currentToken, Collection< Collection > expectedTokenSequences, Collection tokenImage) { @@ -67,7 +67,7 @@ namespace Lucene retval << expected.str(); return retval.str(); } - + String QueryParseError::addEscapes(const String& str) { StringStream buffer; diff --git a/src/core/queryparser/QueryParser.cpp b/src/core/queryparser/QueryParser.cpp index 73cde9cb..baac3799 100644 --- a/src/core/queryparser/QueryParser.cpp +++ b/src/core/queryparser/QueryParser.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ #include "QueryParseError.h" #include "MultiTermQuery.h" #include "TermQuery.h" -#include "TermRangeQuery.h" +#include "TermRangeQuery.h" #include "FuzzyQuery.h" #include "FastCharStream.h" #include "StringReader.h" @@ -47,13 +47,13 @@ namespace Lucene 0x300, 0x300, 0x1c00, 0x1c00, 0x3ed3f00, 0x90000, 0x20000, 0x3ed2000, 0x2690000, 0x100000, 0x100000, 0x20000, 0x30000000, 0x4000000, 0x30000000, 0x20000, 0x0, 0x40000000, 0x0, 0x20000, 0x100000, 0x20000, 0x3ed0000 }; - + const int32_t QueryParser::jj_la1_1[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0 }; - + QueryParser::QueryParser(LuceneVersion::Version matchVersion, const String& field, AnalyzerPtr analyzer) { ConstructParser(newLucene(newLucene(L"")), QueryParserTokenManagerPtr()); @@ -61,21 +61,21 @@ namespace Lucene this->field = field; this->enablePositionIncrements = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_29); } - + QueryParser::QueryParser(QueryParserCharStreamPtr stream) { ConstructParser(stream, QueryParserTokenManagerPtr()); } - + QueryParser::QueryParser(QueryParserTokenManagerPtr tokenMgr) { ConstructParser(QueryParserCharStreamPtr(), tokenMgr); } - + QueryParser::~QueryParser() { } - + void QueryParser::ConstructParser(QueryParserCharStreamPtr stream, QueryParserTokenManagerPtr tokenMgr) { _operator = OR_OPERATOR; @@ -88,7 +88,7 @@ namespace Lucene fuzzyPrefixLength = FuzzyQuery::defaultPrefixLength; locale = std::locale(); dateResolution = DateTools::RESOLUTION_NULL; - + token_source = tokenMgr ? tokenMgr : newLucene(stream); token = newLucene(); _jj_ntk = -1; @@ -107,7 +107,7 @@ namespace Lucene jj_lasttokens = Collection::newInstance(100); jj_endpos = 0; } - + QueryPtr QueryParser::parse(const String& query) { ReInit(newLucene(newLucene(query))); @@ -127,162 +127,162 @@ namespace Lucene } return QueryPtr(); } - + AnalyzerPtr QueryParser::getAnalyzer() { return analyzer; } - + String QueryParser::getField() { return field; } - + double QueryParser::getFuzzyMinSim() { return fuzzyMinSim; } - + void QueryParser::setFuzzyMinSim(double fuzzyMinSim) { this->fuzzyMinSim = fuzzyMinSim; } - + int32_t QueryParser::getFuzzyPrefixLength() { return fuzzyPrefixLength; } - + void QueryParser::setFuzzyPrefixLength(int32_t fuzzyPrefixLength) { this->fuzzyPrefixLength = fuzzyPrefixLength; } - + void QueryParser::setPhraseSlop(int32_t phraseSlop) { this->phraseSlop = phraseSlop; } - + int32_t QueryParser::getPhraseSlop() { return phraseSlop; } - + void QueryParser::setAllowLeadingWildcard(bool allowLeadingWildcard) { this->allowLeadingWildcard = allowLeadingWildcard; } - + bool QueryParser::getAllowLeadingWildcard() { return allowLeadingWildcard; } - + void QueryParser::setEnablePositionIncrements(bool enable) { this->enablePositionIncrements = enable; } - + bool QueryParser::getEnablePositionIncrements() { return enablePositionIncrements; } - + void QueryParser::setDefaultOperator(Operator op) { this->_operator = op; } - + QueryParser::Operator QueryParser::getDefaultOperator() { return _operator; } - + void QueryParser::setLowercaseExpandedTerms(bool lowercaseExpandedTerms) { this->lowercaseExpandedTerms = lowercaseExpandedTerms; } - + bool QueryParser::getLowercaseExpandedTerms() { return lowercaseExpandedTerms; } - + void QueryParser::setMultiTermRewriteMethod(RewriteMethodPtr method) { multiTermRewriteMethod = method; } - + RewriteMethodPtr QueryParser::getMultiTermRewriteMethod() { return multiTermRewriteMethod; } - + void QueryParser::setLocale(std::locale locale) { this->locale = locale; } - + std::locale QueryParser::getLocale() { return locale; } - + void QueryParser::setDateResolution(DateTools::Resolution dateResolution) { this->dateResolution = dateResolution; } - + void QueryParser::setDateResolution(const String& fieldName, DateTools::Resolution dateResolution) { if (fieldName.empty()) boost::throw_exception(IllegalArgumentException(L"Field cannot be empty.")); - + if (!fieldToDateResolution) { // lazily initialize Map fieldToDateResolution = MapStringResolution::newInstance(); } - + fieldToDateResolution.put(fieldName, dateResolution); } - + DateTools::Resolution QueryParser::getDateResolution(const String& fieldName) { if (fieldName.empty()) boost::throw_exception(IllegalArgumentException(L"Field cannot be empty.")); - + if (!fieldToDateResolution) { // no field specific date resolutions set; return default date resolution instead return this->dateResolution; } - + MapStringResolution::iterator resolution = fieldToDateResolution.find(fieldName); if (resolution == fieldToDateResolution.end()) { // no date resolutions set for the given field; return default date resolution instead return this->dateResolution; } - + return resolution->second; } - + void QueryParser::setRangeCollator(CollatorPtr rc) { rangeCollator = rc; } - + CollatorPtr QueryParser::getRangeCollator() { return rangeCollator; } - + void QueryParser::addClause(Collection clauses, int32_t conj, int32_t mods, QueryPtr q) { bool required = false; bool prohibited = false; - + // If this term is introduced by AND, make the preceding term required, unless it's already prohibited if (!clauses.empty() && conj == CONJ_AND) { @@ -290,24 +290,24 @@ namespace Lucene if (!c->isProhibited()) c->setOccur(BooleanClause::MUST); } - + if (!clauses.empty() && _operator == AND_OPERATOR && conj == CONJ_OR) { - // If this term is introduced by OR, make the preceding term optional, unless it's prohibited (that - // means we leave -a OR b but +a OR b-->a OR b) notice if the input is a OR b, first term is parsed + // If this term is introduced by OR, make the preceding term optional, unless it's prohibited (that + // means we leave -a OR b but +a OR b-->a OR b) notice if the input is a OR b, first term is parsed // as required; without this modification a OR b would parsed as +a OR b BooleanClausePtr c(clauses[clauses.size() - 1]); if (!c->isProhibited()) c->setOccur(BooleanClause::SHOULD); } - + // We might have been passed a null query; the term might have been filtered away by the analyzer. if (!q) return; - + if (_operator == OR_OPERATOR) { - // We set REQUIRED if we're introduced by AND or +; PROHIBITED if introduced by NOT or -; make + // We set REQUIRED if we're introduced by AND or +; PROHIBITED if introduced by NOT or -; make // sure not to set both. prohibited = (mods == MOD_NOT); required = (mods == MOD_REQ); @@ -316,8 +316,8 @@ namespace Lucene } else { - // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED if not PROHIBITED and not - // introduced by OR + // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED if not PROHIBITED and not + // introduced by OR prohibited = (mods == MOD_NOT); required = (!prohibited && conj != CONJ_OR); } @@ -330,7 +330,7 @@ namespace Lucene else boost::throw_exception(RuntimeException(L"Clause cannot be both required and prohibited")); } - + QueryPtr QueryParser::getFieldQuery(const String& field, const String& queryText) { TokenStreamPtr source; @@ -343,12 +343,12 @@ namespace Lucene { source = analyzer->tokenStream(field, newLucene(queryText)); } - + CachingTokenFilterPtr buffer(newLucene(source)); TermAttributePtr termAtt; PositionIncrementAttributePtr posIncrAtt; int32_t numTokens = 0; - + bool success = false; try { @@ -366,10 +366,10 @@ namespace Lucene if (buffer->hasAttribute()) posIncrAtt = buffer->getAttribute(); } - + int32_t positionCount = 0; bool severalTokensAtSamePosition = false; - + bool hasMoreTokens = false; if (termAtt) { @@ -396,7 +396,7 @@ namespace Lucene { // rewind the buffer stream buffer->reset(); - + // close original stream - all tokens buffered source->close(); } @@ -404,7 +404,7 @@ namespace Lucene { // ignore } - + if (numTokens == 0) return QueryPtr(); else if (numTokens == 1) @@ -443,7 +443,7 @@ namespace Lucene { // safe to ignore, because we know the number of tokens } - + QueryPtr currentQuery(newTermQuery(newLucene(field, term))); q->add(currentQuery, BooleanClause::SHOULD); } @@ -472,7 +472,7 @@ namespace Lucene { // safe to ignore, because we know the number of tokens } - + if (positionIncrement > 0 && !multiTerms.empty()) { if (enablePositionIncrements) @@ -496,12 +496,12 @@ namespace Lucene PhraseQueryPtr pq(newPhraseQuery()); pq->setSlop(phraseSlop); int32_t position = -1; - + for (int32_t i = 0; i < numTokens; ++i) { String term; int32_t positionIncrement = 1; - + try { bool hasNext = buffer->incrementToken(); @@ -514,7 +514,7 @@ namespace Lucene { // safe to ignore, because we know the number of tokens } - + if (enablePositionIncrements) { position += positionIncrement; @@ -527,7 +527,7 @@ namespace Lucene } } } - + QueryPtr QueryParser::getFieldQuery(const String& field, const String& queryText, int32_t slop) { QueryPtr query(getFieldQuery(field, queryText)); @@ -537,7 +537,7 @@ namespace Lucene boost::dynamic_pointer_cast(query)->setSlop(slop); return query; } - + QueryPtr QueryParser::getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) { String date1(part1); @@ -551,13 +551,13 @@ namespace Lucene { boost::posix_time::ptime d1(DateTools::parseDate(date1, locale)); boost::posix_time::ptime d2; - - // The user can only specify the date, not the time, so make sure the time is set to + + // The user can only specify the date, not the time, so make sure the time is set to // the latest possible time of that date to really include all documents if (inclusive) { d2 = boost::posix_time::ptime(DateTools::parseDate(date2, locale) + - boost::posix_time::hours(23) + + boost::posix_time::hours(23) + boost::posix_time::minutes(59) + boost::posix_time::seconds(59) + boost::posix_time::millisec(999)); @@ -567,7 +567,7 @@ namespace Lucene DateTools::Resolution resolution = getDateResolution(field); if (resolution == DateTools::RESOLUTION_NULL) { - // no default or field specific date resolution has been set, use deprecated + // no default or field specific date resolution has been set, use deprecated // DateField to maintain compatibility with pre-1.9 Lucene versions. date1 = DateField::dateToString(d1); date2 = DateField::dateToString(d2); @@ -583,22 +583,22 @@ namespace Lucene } return newRangeQuery(field, date1, date2, inclusive); } - + BooleanQueryPtr QueryParser::newBooleanQuery(bool disableCoord) { return newLucene(disableCoord); } - + BooleanClausePtr QueryParser::newBooleanClause(QueryPtr q, BooleanClause::Occur occur) { return newLucene(q, occur); } - + QueryPtr QueryParser::newTermQuery(TermPtr term) { return newLucene(term); } - + PhraseQueryPtr QueryParser::newPhraseQuery() { return newLucene(); @@ -608,14 +608,14 @@ namespace Lucene { return newLucene(); } - + QueryPtr QueryParser::newPrefixQuery(TermPtr prefix) { PrefixQueryPtr query(newLucene(prefix)); query->setRewriteMethod(multiTermRewriteMethod); return query; } - + QueryPtr QueryParser::newFuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength) { // FuzzyQuery doesn't yet allow constant score rewrite @@ -628,24 +628,24 @@ namespace Lucene query->setRewriteMethod(multiTermRewriteMethod); return query; } - + QueryPtr QueryParser::newMatchAllDocsQuery() { return newLucene(); } - + QueryPtr QueryParser::newWildcardQuery(TermPtr term) { WildcardQueryPtr query(newLucene(term)); query->setRewriteMethod(multiTermRewriteMethod); return query; } - + QueryPtr QueryParser::getBooleanQuery(Collection clauses) { return getBooleanQuery(clauses, false); } - + QueryPtr QueryParser::getBooleanQuery(Collection clauses, bool disableCoord) { if (clauses.empty()) @@ -655,7 +655,7 @@ namespace Lucene query->add(*clause); return query; } - + QueryPtr QueryParser::getWildcardQuery(const String& field, const String& termStr) { if (field == L"*" && termStr == L"*") @@ -668,7 +668,7 @@ namespace Lucene TermPtr term(newLucene(field, queryTerm)); return newWildcardQuery(term); } - + QueryPtr QueryParser::getPrefixQuery(const String& field, const String& termStr) { if (!allowLeadingWildcard && boost::starts_with(termStr, L"*")) @@ -679,7 +679,7 @@ namespace Lucene TermPtr term(newLucene(field, queryTerm)); return newPrefixQuery(term); } - + QueryPtr QueryParser::getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) { String queryTerm(termStr); @@ -688,26 +688,26 @@ namespace Lucene TermPtr term(newLucene(field, queryTerm)); return newFuzzyQuery(term, minSimilarity, fuzzyPrefixLength); } - + String QueryParser::discardEscapeChar(const String& input) { // Create char array to hold unescaped char sequence CharArray output(CharArray::newInstance(input.length())); - - // The length of the output can be less than the input due to discarded escape chars. + + // The length of the output can be less than the input due to discarded escape chars. // This variable holds the actual length of the output int32_t length = 0; - + // We remember whether the last processed character was an escape character bool lastCharWasEscapeChar = false; - - // The multiplier the current unicode digit must be multiplied with. eg. the first digit must + + // The multiplier the current unicode digit must be multiplied with. eg. the first digit must // be multiplied with 16^3, the second with 16^2 int32_t codePointMultiplier = 0; - + // Used to calculate the codepoint of the escaped unicode character int32_t codePoint = 0; - + for (int32_t i = 0; i < (int32_t)input.length(); ++i) { wchar_t curChar = input[i]; @@ -743,14 +743,14 @@ namespace Lucene output[length++] = curChar; } } - + if (codePointMultiplier > 0) boost::throw_exception(QueryParserError(L"Truncated unicode escape sequence.")); if (lastCharWasEscapeChar) boost::throw_exception(QueryParserError(L"Term can not end with escape character.")); return String(output.get(), length); } - + int32_t QueryParser::hexToInt(wchar_t c) { if (L'0' <= c && c <= L'9') @@ -765,7 +765,7 @@ namespace Lucene return 0; } } - + String QueryParser::escape(const String& s) { StringStream buffer; @@ -773,15 +773,15 @@ namespace Lucene { wchar_t c = s[i]; // These characters are part of the query syntax and must be escaped - if (c == L'\\' || c == L'+' || c == L'-' || c == L'!' || c == L'(' || c == L')' || c == L':' || - c == L'^' || c == L'[' || c == L']' || c == L'\"' || c == L'{' || c == L'}' || c == L'~' || + if (c == L'\\' || c == L'+' || c == L'-' || c == L'!' || c == L'(' || c == L')' || c == L':' || + c == L'^' || c == L'[' || c == L']' || c == L'\"' || c == L'{' || c == L'}' || c == L'~' || c == L'*' || c == L'?' || c == L'|' || c == L'&') buffer << L"\\"; buffer << c; } return buffer.str(); } - + int QueryParser::main(Collection args) { if (args.empty()) @@ -794,7 +794,7 @@ namespace Lucene std::wcout << q->toString(L"field"); return 0; } - + int32_t QueryParser::Conjunction() { int32_t ret = CONJ_NONE; @@ -823,7 +823,7 @@ namespace Lucene } return ret; } - + int32_t QueryParser::Modifiers() { int32_t ret = MOD_NONE; @@ -857,14 +857,14 @@ namespace Lucene } return ret; } - + QueryPtr QueryParser::TopLevelQuery(const String& field) { QueryPtr q(ParseQuery(field)); jj_consume_token(0); return q; } - + QueryPtr QueryParser::ParseQuery(const String& field) { Collection clauses(Collection::newInstance()); @@ -908,7 +908,7 @@ namespace Lucene else return getBooleanQuery(clauses); } - + QueryPtr QueryParser::ParseClause(const String& field) { QueryPtr q; @@ -983,7 +983,7 @@ namespace Lucene } return q; } - + QueryPtr QueryParser::ParseTerm(const String& field) { QueryParserTokenPtr term; @@ -1231,14 +1231,14 @@ namespace Lucene catch (...) { } - + // avoid boosting null queries, such as those caused by stop words if (q) q->setBoost(f); } return q; } - + bool QueryParser::jj_2_1(int32_t xla) { jj_la = xla; @@ -1262,7 +1262,7 @@ namespace Lucene finally.throwException(); return _jj_2_1; } - + bool QueryParser::jj_3R_2() { if (jj_scan_token(TERM)) @@ -1271,7 +1271,7 @@ namespace Lucene return true; return false; } - + bool QueryParser::jj_3_1() { QueryParserTokenPtr xsp(jj_scanpos); @@ -1283,7 +1283,7 @@ namespace Lucene } return false; } - + bool QueryParser::jj_3R_3() { if (jj_scan_token(STAR)) @@ -1292,7 +1292,7 @@ namespace Lucene return true; return false; } - + void QueryParser::ReInit(QueryParserCharStreamPtr stream) { token_source->ReInit(stream); @@ -1304,7 +1304,7 @@ namespace Lucene for (int32_t i = 0; i < jj_2_rtns.size(); ++i) jj_2_rtns[i] = newInstance(); } - + void QueryParser::ReInit(QueryParserTokenManagerPtr tokenMgr) { token_source = tokenMgr; @@ -1316,7 +1316,7 @@ namespace Lucene for (int32_t i = 0; i < jj_2_rtns.size(); ++i) jj_2_rtns[i] = newInstance(); } - + QueryParserTokenPtr QueryParser::jj_consume_token(int32_t kind) { QueryParserTokenPtr oldToken(token); @@ -1352,7 +1352,7 @@ namespace Lucene generateParseException(); return QueryParserTokenPtr(); } - + bool QueryParser::jj_scan_token(int32_t kind) { if (jj_scanpos == jj_lastpos) @@ -1390,7 +1390,7 @@ namespace Lucene boost::throw_exception(LookaheadSuccess()); return false; } - + QueryParserTokenPtr QueryParser::getNextToken() { if (token->next) @@ -1404,7 +1404,7 @@ namespace Lucene ++jj_gen; return token; } - + QueryParserTokenPtr QueryParser::getToken(int32_t index) { QueryParserTokenPtr t(token); @@ -1420,7 +1420,7 @@ namespace Lucene } return t; } - + int32_t QueryParser::jj_ntk() { jj_nt = token->next; @@ -1436,7 +1436,7 @@ namespace Lucene return _jj_ntk; } } - + void QueryParser::jj_add_error_token(int32_t kind, int32_t pos) { if (pos >= 100) @@ -1474,7 +1474,7 @@ namespace Lucene } } } - + void QueryParser::generateParseException() { jj_expentries.clear(); @@ -1514,15 +1514,15 @@ namespace Lucene exptokseq[i] = jj_expentries[i]; boost::throw_exception(QueryParserError(QueryParseError::parseError(token, exptokseq, tokenImage))); } - + void QueryParser::enable_tracing() { } - + void QueryParser::disable_tracing() { } - + void QueryParser::jj_rescan_token() { jj_rescan = true; @@ -1550,7 +1550,7 @@ namespace Lucene } jj_rescan = false; } - + void QueryParser::jj_save(int32_t index, int32_t xla) { JJCallsPtr p(jj_2_rtns[index]); diff --git a/src/core/queryparser/QueryParserCharStream.cpp b/src/core/queryparser/QueryParserCharStream.cpp index ae152ba5..d9c4d390 100644 --- a/src/core/queryparser/QueryParserCharStream.cpp +++ b/src/core/queryparser/QueryParserCharStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,67 +14,67 @@ namespace Lucene BOOST_ASSERT(false); return 0; // override } - + int32_t QueryParserCharStream::getColumn() { BOOST_ASSERT(false); return 0; // override } - + int32_t QueryParserCharStream::getLine() { BOOST_ASSERT(false); return 0; // override } - + int32_t QueryParserCharStream::getEndColumn() { BOOST_ASSERT(false); return 0; // override } - + int32_t QueryParserCharStream::getEndLine() { BOOST_ASSERT(false); return 0; // override } - + int32_t QueryParserCharStream::getBeginColumn() { BOOST_ASSERT(false); return 0; // override } - + int32_t QueryParserCharStream::getBeginLine() { BOOST_ASSERT(false); return 0; // override } - + void QueryParserCharStream::backup(int32_t amount) { BOOST_ASSERT(false); // override } - + wchar_t QueryParserCharStream::BeginToken() { BOOST_ASSERT(false); return 0; // override } - + String QueryParserCharStream::GetImage() { BOOST_ASSERT(false); return L""; // override } - + CharArray QueryParserCharStream::GetSuffix(int32_t length) { BOOST_ASSERT(false); return CharArray(); // override } - + void QueryParserCharStream::Done() { BOOST_ASSERT(false); diff --git a/src/core/queryparser/QueryParserConstants.cpp b/src/core/queryparser/QueryParserConstants.cpp index 838b99a1..48109f29 100644 --- a/src/core/queryparser/QueryParserConstants.cpp +++ b/src/core/queryparser/QueryParserConstants.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -9,7 +9,7 @@ namespace Lucene { - const wchar_t* QueryParserConstants::_tokenImage[] = + const wchar_t* QueryParserConstants::_tokenImage[] = { L"", L"<_NUM_CHAR>", @@ -47,7 +47,7 @@ namespace Lucene L"" }; Collection QueryParserConstants::tokenImage = Collection::newInstance(_tokenImage, _tokenImage + SIZEOF_ARRAY(_tokenImage)); - + QueryParserConstants::QueryParserConstants() { } diff --git a/src/core/queryparser/QueryParserToken.cpp b/src/core/queryparser/QueryParserToken.cpp index f37f6aff..5bfa7290 100644 --- a/src/core/queryparser/QueryParserToken.cpp +++ b/src/core/queryparser/QueryParserToken.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,16 +18,16 @@ namespace Lucene this->endLine = 0; this->endColumn = 0; } - + QueryParserToken::~QueryParserToken() { } - + String QueryParserToken::toString() { return image; } - + QueryParserTokenPtr QueryParserToken::newToken(int32_t ofKind, const String& image) { return newLucene(ofKind, image); diff --git a/src/core/queryparser/QueryParserTokenManager.cpp b/src/core/queryparser/QueryParserTokenManager.cpp index cb64c976..547690a7 100644 --- a/src/core/queryparser/QueryParserTokenManager.cpp +++ b/src/core/queryparser/QueryParserTokenManager.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,31 +20,31 @@ namespace Lucene const int64_t QueryParserTokenManager::jjbitVec4[] = {static_cast(0xfffefffffffffffeLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; const int32_t QueryParserTokenManager::jjnextStates[] = {15, 16, 18, 29, 32, 23, 33, 30, 20, 21, 32, 23, 33, 31, 34, 27, 2, 4, 5, 0, 1}; - + /// Token literal values. - const wchar_t* QueryParserTokenManager::jjstrLiteralImages[] = + const wchar_t* QueryParserTokenManager::jjstrLiteralImages[] = { - L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"\53", L"\55", - L"\50", L"\51", L"\72", L"\52", L"\136", L"", L"", L"", L"", L"", L"\133", + L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"\53", L"\55", + L"\50", L"\51", L"\72", L"\52", L"\136", L"", L"", L"", L"", L"", L"\133", L"\173", L"", L"\124\117", L"\135", L"", L"", L"\124\117", L"\175", L"", L"" }; - + /// Lexer state names. - const wchar_t* QueryParserTokenManager::lexStateNames[] = + const wchar_t* QueryParserTokenManager::lexStateNames[] = { L"Boost", L"RangeEx", L"RangeIn", L"DEFAULT" }; - + /// Lex State array. - const int32_t QueryParserTokenManager::jjnewLexState[] = + const int32_t QueryParserTokenManager::jjnewLexState[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 2, 1, 3, -1, 3, -1, -1, -1, 3, -1, -1 }; - + const int64_t QueryParserTokenManager::jjtoToken[] = {0x3ffffff01LL}; const int64_t QueryParserTokenManager::jjtoSkip[] = {0x80LL}; - + QueryParserTokenManager::QueryParserTokenManager(QueryParserCharStreamPtr stream) { debugStream = newLucene(); @@ -59,7 +59,7 @@ namespace Lucene jjmatchedKind = 0; input_stream = stream; } - + QueryParserTokenManager::QueryParserTokenManager(QueryParserCharStreamPtr stream, int32_t lexState) { debugStream = newLucene(); @@ -75,33 +75,33 @@ namespace Lucene jjmatchedKind = 0; SwitchTo(lexState); } - + QueryParserTokenManager::~QueryParserTokenManager() { } - + void QueryParserTokenManager::setDebugStream(InfoStreamPtr debugStream) { this->debugStream = debugStream; } - + int32_t QueryParserTokenManager::jjStopStringLiteralDfa_3(int32_t pos, int64_t active0) { return -1; } - + int32_t QueryParserTokenManager::jjStartNfa_3(int32_t pos, int64_t active0) { return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1); } - + int32_t QueryParserTokenManager::jjStopAtPos(int32_t pos, int32_t kind) { jjmatchedKind = kind; jjmatchedPos = pos; return pos + 1; } - + int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_3() { switch (curChar) @@ -128,7 +128,7 @@ namespace Lucene return jjMoveNfa_3(0, 0); } } - + int32_t QueryParserTokenManager::jjStartNfaWithStates_3(int32_t pos, int32_t kind, int32_t state) { jjmatchedKind = kind; @@ -143,7 +143,7 @@ namespace Lucene } return jjMoveNfa_3(state, pos + 1); } - + int32_t QueryParserTokenManager::jjMoveNfa_3(int32_t startState, int32_t curPos) { int32_t startsAt = 0; @@ -579,7 +579,7 @@ namespace Lucene } } } - + int32_t QueryParserTokenManager::jjStopStringLiteralDfa_1(int32_t pos, int64_t active0) { switch (pos) @@ -595,12 +595,12 @@ namespace Lucene return -1; } } - + int32_t QueryParserTokenManager::jjStartNfa_1(int32_t pos, int64_t active0) { return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); } - + int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_1() { switch (curChar) @@ -613,7 +613,7 @@ namespace Lucene return jjMoveNfa_1(0, 0); } } - + int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_1(int64_t active0) { try @@ -636,7 +636,7 @@ namespace Lucene } return jjStartNfa_1(0, active0); } - + int32_t QueryParserTokenManager::jjStartNfaWithStates_1(int32_t pos, int32_t kind, int32_t state) { jjmatchedKind = kind; @@ -651,7 +651,7 @@ namespace Lucene } return jjMoveNfa_1(state, pos + 1); } - + int32_t QueryParserTokenManager::jjMoveNfa_1(int32_t startState, int32_t curPos) { int32_t startsAt = 0; @@ -802,12 +802,12 @@ namespace Lucene } } } - + int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_0() { return jjMoveNfa_0(0, 0); } - + int32_t QueryParserTokenManager::jjMoveNfa_0(int32_t startState, int32_t curPos) { int32_t startsAt = 0; @@ -891,7 +891,7 @@ namespace Lucene } } } - + int32_t QueryParserTokenManager::jjStopStringLiteralDfa_2(int32_t pos, int64_t active0) { switch (pos) @@ -907,12 +907,12 @@ namespace Lucene return -1; } } - + int32_t QueryParserTokenManager::jjStartNfa_2(int32_t pos, int64_t active0) { return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); } - + int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_2() { switch (curChar) @@ -925,7 +925,7 @@ namespace Lucene return jjMoveNfa_2(0, 0); } } - + int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_2(int64_t active0) { try @@ -948,7 +948,7 @@ namespace Lucene } return jjStartNfa_2(0, active0); } - + int32_t QueryParserTokenManager::jjStartNfaWithStates_2(int32_t pos, int32_t kind, int32_t state) { jjmatchedKind = kind; @@ -963,7 +963,7 @@ namespace Lucene } return jjMoveNfa_2(state, pos + 1); } - + int32_t QueryParserTokenManager::jjMoveNfa_2(int32_t startState, int32_t curPos) { int32_t startsAt = 0; @@ -1114,7 +1114,7 @@ namespace Lucene } } } - + bool QueryParserTokenManager::jjCanMove_0(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) { switch (hiByte) @@ -1125,7 +1125,7 @@ namespace Lucene return false; } } - + bool QueryParserTokenManager::jjCanMove_1(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) { switch (hiByte) @@ -1138,7 +1138,7 @@ namespace Lucene return false; } } - + bool QueryParserTokenManager::jjCanMove_2(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) { switch (hiByte) @@ -1153,7 +1153,7 @@ namespace Lucene return false; } } - + void QueryParserTokenManager::ReInit(QueryParserCharStreamPtr stream) { jjmatchedPos = 0; @@ -1162,31 +1162,31 @@ namespace Lucene input_stream = stream; ReInitRounds(); } - + void QueryParserTokenManager::ReInitRounds() { jjround = 0x80000001; for (int32_t i = 36; i-- > 0;) jjrounds[i] = 0x80000000; } - + void QueryParserTokenManager::ReInit(QueryParserCharStreamPtr stream, int32_t lexState) { ReInit(stream); SwitchTo(lexState); } - + void QueryParserTokenManager::SwitchTo(int32_t lexState) { if (lexState >= 4 || lexState < 0) { - boost::throw_exception(QueryParserError(L"Error: Ignoring invalid lexical state : " + + boost::throw_exception(QueryParserError(L"Error: Ignoring invalid lexical state : " + StringUtils::toString(lexState) + L". State unchanged.")); } else curLexState = lexState; } - + QueryParserTokenPtr QueryParserTokenManager::jjFillToken() { String im(jjstrLiteralImages[jjmatchedKind]); @@ -1196,20 +1196,20 @@ namespace Lucene int32_t endLine = input_stream->getEndLine(); int32_t endColumn = input_stream->getEndColumn(); QueryParserTokenPtr t(QueryParserToken::newToken(jjmatchedKind, curTokenImage)); - + t->beginLine = beginLine; t->endLine = endLine; t->beginColumn = beginColumn; t->endColumn = endColumn; - + return t; } - + QueryParserTokenPtr QueryParserTokenManager::getNextToken() { QueryParserTokenPtr matchedToken; int32_t curPos = 0; - + while (true) { try @@ -1222,7 +1222,7 @@ namespace Lucene matchedToken = jjFillToken(); return matchedToken; } - + switch (curLexState) { case 0: @@ -1246,7 +1246,7 @@ namespace Lucene curPos = jjMoveStringLiteralDfa0_3(); break; } - + if (jjmatchedKind != 0x7fffffff) { if (jjmatchedPos + 1 < curPos) @@ -1286,17 +1286,17 @@ namespace Lucene else ++error_column; } - + if (!EOFSeen) { input_stream->backup(1); error_after = curPos <= 1 ? L"" : input_stream->GetImage(); } - + boost::throw_exception(QueryParserError(QueryParseError::lexicalError(EOFSeen, curLexState, error_line, error_column, error_after, curChar))); } } - + void QueryParserTokenManager::jjCheckNAdd(int32_t state) { if (jjrounds[state] != jjround) @@ -1305,7 +1305,7 @@ namespace Lucene jjrounds[state] = jjround; } } - + void QueryParserTokenManager::jjAddStates(int32_t start, int32_t end) { do @@ -1314,13 +1314,13 @@ namespace Lucene } while (start++ != end); } - + void QueryParserTokenManager::jjCheckNAddTwoStates(int32_t state1, int32_t state2) { jjCheckNAdd(state1); jjCheckNAdd(state2); } - + void QueryParserTokenManager::jjCheckNAddStates(int32_t start, int32_t end) { do diff --git a/src/core/search/BooleanClause.cpp b/src/core/search/BooleanClause.cpp index ba72dfe1..cbb95eb9 100644 --- a/src/core/search/BooleanClause.cpp +++ b/src/core/search/BooleanClause.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,41 +15,41 @@ namespace Lucene this->query = query; this->occur = occur; } - + BooleanClause::~BooleanClause() { } - + BooleanClause::Occur BooleanClause::getOccur() { return occur; } - + void BooleanClause::setOccur(BooleanClause::Occur occur) { this->occur = occur; } - + QueryPtr BooleanClause::getQuery() { return query; } - + void BooleanClause::setQuery(QueryPtr query) { this->query = query; } - + bool BooleanClause::isProhibited() { return (occur == MUST_NOT); } - + bool BooleanClause::isRequired() { return (occur == MUST); } - + bool BooleanClause::equals(LuceneObjectPtr other) { BooleanClausePtr otherBooleanClause(boost::dynamic_pointer_cast(other)); @@ -57,12 +57,12 @@ namespace Lucene return false; return (this->query->equals(otherBooleanClause->query) && this->occur == otherBooleanClause->occur); } - + int32_t BooleanClause::hashCode() { return query->hashCode() ^ (occur == MUST ? 1 : 0) ^ (occur == MUST_NOT ? 2 : 0); } - + String BooleanClause::toString() { switch (occur) diff --git a/src/core/search/BooleanQuery.cpp b/src/core/search/BooleanQuery.cpp index f0c95011..a86ea88f 100644 --- a/src/core/search/BooleanQuery.cpp +++ b/src/core/search/BooleanQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,35 +16,35 @@ namespace Lucene { int32_t BooleanQuery::maxClauseCount = 1024; - + BooleanQuery::BooleanQuery(bool disableCoord) { this->disableCoord = disableCoord; this->clauses = Collection::newInstance(); this->minNrShouldMatch = 0; } - + BooleanQuery::~BooleanQuery() { } - + int32_t BooleanQuery::getMaxClauseCount() { return maxClauseCount; } - + void BooleanQuery::setMaxClauseCount(int32_t maxClauseCount) { if (maxClauseCount < 1) boost::throw_exception(IllegalArgumentException(L"maxClauseCount must be >= 1")); BooleanQuery::maxClauseCount = maxClauseCount; } - + bool BooleanQuery::isCoordDisabled() { return disableCoord; } - + SimilarityPtr BooleanQuery::getSimilarity(SearcherPtr searcher) { SimilarityPtr result(Query::getSimilarity(searcher)); @@ -52,49 +52,49 @@ namespace Lucene result = newLucene(result); return result; } - + void BooleanQuery::setMinimumNumberShouldMatch(int32_t min) { this->minNrShouldMatch = min; } - + int32_t BooleanQuery::getMinimumNumberShouldMatch() { return minNrShouldMatch; } - + void BooleanQuery::add(QueryPtr query, BooleanClause::Occur occur) { add(newLucene(query, occur)); } - + void BooleanQuery::add(BooleanClausePtr clause) { if (clauses.size() >= maxClauseCount) boost::throw_exception(TooManyClausesException(L"maxClauseCount is set to " + StringUtils::toString(maxClauseCount))); clauses.add(clause); } - + Collection BooleanQuery::getClauses() { return clauses; } - + Collection::iterator BooleanQuery::begin() { return clauses.begin(); } - + Collection::iterator BooleanQuery::end() { return clauses.end(); } - + WeightPtr BooleanQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + QueryPtr BooleanQuery::rewrite(IndexReaderPtr reader) { if (minNrShouldMatch == 0 && clauses.size() == 1) // optimize 1-clause queries @@ -103,18 +103,18 @@ namespace Lucene if (!c->isProhibited()) // just return clause { QueryPtr query(c->getQuery()->rewrite(reader)); // rewrite first - + if (getBoost() != 1.0) // incorporate boost { if (query == c->getQuery()) // if rewrite was no-op query = boost::dynamic_pointer_cast(query->clone()); // then clone before boost query->setBoost(getBoost() * query->getBoost()); } - + return query; } } - + BooleanQueryPtr clone; // recursively rewrite for (int32_t i = 0; i < clauses.size(); ++i) { @@ -127,19 +127,19 @@ namespace Lucene clone->clauses[i] = newLucene(query, c->getOccur()); } } - + if (clone) return clone; // some clauses rewrote else return shared_from_this(); // no clauses rewrote } - + void BooleanQuery::extractTerms(SetTerm terms) { for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) (*clause)->getQuery()->extractTerms(terms); } - + LuceneObjectPtr BooleanQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); @@ -149,7 +149,7 @@ namespace Lucene cloneQuery->clauses = Collection::newInstance(clauses.begin(), clauses.end()); return cloneQuery; } - + String BooleanQuery::toString(const String& field) { String buffer; @@ -161,12 +161,12 @@ namespace Lucene { if (clause != clauses.begin()) buffer += L" "; - + if ((*clause)->isProhibited()) buffer += L"-"; else if ((*clause)->isRequired()) buffer += L"+"; - + QueryPtr subQuery((*clause)->getQuery()); if (subQuery) { @@ -182,39 +182,39 @@ namespace Lucene else buffer += L"null"; } - + if (needParens) buffer += L")"; - + if (getMinimumNumberShouldMatch() > 0) { buffer += L"~"; buffer += StringUtils::toString(getMinimumNumberShouldMatch()); } - + if (getBoost() != 1.0) buffer += boostString(); - + return buffer; } - + bool BooleanQuery::equals(LuceneObjectPtr other) { BooleanQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) return false; - return (getBoost() == otherQuery->getBoost() && - clauses.equals(otherQuery->clauses, luceneEquals()) && + return (getBoost() == otherQuery->getBoost() && + clauses.equals(otherQuery->clauses, luceneEquals()) && getMinimumNumberShouldMatch() == otherQuery->getMinimumNumberShouldMatch() && disableCoord == otherQuery->disableCoord); } - + int32_t BooleanQuery::hashCode() { - return MiscUtils::doubleToIntBits(getBoost()) ^ MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene) + + return MiscUtils::doubleToIntBits(getBoost()) ^ MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene) + getMinimumNumberShouldMatch() + (disableCoord ? 17 : 0); } - + BooleanWeight::BooleanWeight(BooleanQueryPtr query, SearcherPtr searcher) { this->query = query; @@ -223,21 +223,21 @@ namespace Lucene for (Collection::iterator clause = query->clauses.begin(); clause != query->clauses.end(); ++clause) weights.add((*clause)->getQuery()->createWeight(searcher)); } - + BooleanWeight::~BooleanWeight() { } - + QueryPtr BooleanWeight::getQuery() { return query; } - + double BooleanWeight::getValue() { return query->getBoost(); } - + double BooleanWeight::sumOfSquaredWeights() { double sum = 0.0; @@ -251,12 +251,12 @@ namespace Lucene sum += s; } } - + sum *= query->getBoost() * query->getBoost(); // boost each sub-weight - + return sum; } - + void BooleanWeight::normalize(double norm) { norm *= query->getBoost(); // incorporate boost @@ -266,7 +266,7 @@ namespace Lucene (*w)->normalize(norm); } } - + ExplanationPtr BooleanWeight::explain(IndexReaderPtr reader, int32_t doc) { int32_t minShouldMatch = query->getMinimumNumberShouldMatch(); @@ -325,7 +325,7 @@ namespace Lucene sumExpl->setDescription(L"Failure to match minimum number of optional clauses: " + StringUtils::toString(minShouldMatch)); return sumExpl; } - + sumExpl->setMatch(0 < coord); sumExpl->setValue(sum); double coordFactor = similarity->coord(coord, maxCoord); @@ -339,7 +339,7 @@ namespace Lucene return result; } } - + ScorerPtr BooleanWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { Collection required(Collection::newInstance()); @@ -361,11 +361,11 @@ namespace Lucene else optional.add(subScorer); } - + // Check if we can return a BooleanScorer if (!scoreDocsInOrder && topScorer && required.empty() && prohibited.size() < 32) return newLucene(similarity, query->minNrShouldMatch, optional, prohibited); - + if (required.empty() && optional.empty()) { // no required and optional clauses. @@ -373,15 +373,15 @@ namespace Lucene } else if (optional.size() < query->minNrShouldMatch) { - // either >1 req scorer, or there are 0 req scorers and at least 1 optional scorer. Therefore if there + // either >1 req scorer, or there are 0 req scorers and at least 1 optional scorer. Therefore if there // are not enough optional scorers no documents will be matched by the query return ScorerPtr(); } - + // Return a BooleanScorer2 return newLucene(similarity, query->minNrShouldMatch, required, prohibited, optional); } - + bool BooleanWeight::scoresDocsOutOfOrder() { int32_t numProhibited = 0; @@ -392,22 +392,22 @@ namespace Lucene else if ((*c)->isProhibited()) ++numProhibited; } - + if (numProhibited > 32) // cannot use BS return false; - + // scorer() will return an out-of-order scorer if requested. return true; } - + SimilarityDisableCoord::SimilarityDisableCoord(SimilarityPtr delegee) : SimilarityDelegator(delegee) { } - + SimilarityDisableCoord::~SimilarityDisableCoord() { } - + double SimilarityDisableCoord::coord(int32_t overlap, int32_t maxOverlap) { return 1.0; // disable coord diff --git a/src/core/search/BooleanScorer.cpp b/src/core/search/BooleanScorer.cpp index 5e63c864..8992ce90 100644 --- a/src/core/search/BooleanScorer.cpp +++ b/src/core/search/BooleanScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,7 +20,7 @@ namespace Lucene this->minNrShouldMatch = minNrShouldMatch; this->end = 0; this->doc = -1; - + if (optionalScorers && !optionalScorers.empty()) { for (Collection::iterator scorer = optionalScorers.begin(); scorer != optionalScorers.end(); ++scorer) @@ -30,7 +30,7 @@ namespace Lucene scorers = newLucene(*scorer, false, false, bucketTable->newCollector(0), scorers); } } - + if (prohibitedScorers && !prohibitedScorers.empty()) { for (Collection::iterator scorer = prohibitedScorers.begin(); scorer != prohibitedScorers.end(); ++scorer) @@ -42,17 +42,17 @@ namespace Lucene scorers = newLucene(*scorer, false, true, bucketTable->newCollector(mask), scorers); } } - + coordFactors = Collection::newInstance(maxCoord); SimilarityPtr sim(getSimilarity()); for (int32_t i = 0; i < maxCoord; ++i) - coordFactors[i] = sim->coord(i, maxCoord - 1); + coordFactors[i] = sim->coord(i, maxCoord - 1); } - + BooleanScorer::~BooleanScorer() { } - + bool BooleanScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) { bool more = false; @@ -63,7 +63,7 @@ namespace Lucene do { bucketTable->first.reset(); - + while (current) // more queued { // check prohibited & required @@ -77,7 +77,7 @@ namespace Lucene bucketTable->first = tmp; continue; } - + if (current->coord >= minNrShouldMatch) { bs->_score = current->score * coordFactors[current->coord]; @@ -85,21 +85,21 @@ namespace Lucene collector->collect(current->doc); } } - + current = current->_next.lock(); // pop the queue } - + if (bucketTable->first) { current = bucketTable->first; bucketTable->first = current->_next.lock(); return true; } - + // refill the queue more = false; end += BucketTable::SIZE; - + for (SubScorerPtr sub(scorers); sub; sub = sub->next) { int32_t subScorerDocID = sub->scorer->docID(); @@ -112,21 +112,21 @@ namespace Lucene current = bucketTable->first; } while (current || more); - + return false; } - + int32_t BooleanScorer::advance(int32_t target) { boost::throw_exception(UnsupportedOperationException()); return 0; } - + int32_t BooleanScorer::docID() { return doc; } - + int32_t BooleanScorer::nextDoc() { bool more = false; @@ -136,7 +136,7 @@ namespace Lucene { current = bucketTable->first; bucketTable->first = current->_next.lock(); // pop the queue - + // check prohibited & required and minNrShouldMatch if ((current->bits & prohibitedMask) == 0 && (current->bits & requiredMask) == requiredMask && current->coord >= minNrShouldMatch) { @@ -144,11 +144,11 @@ namespace Lucene return doc; } } - + // refill the queue more = false; end += BucketTable::SIZE; - + for (SubScorerPtr sub(scorers); sub; sub = sub->next) { ScorerPtr scorer(sub->scorer); @@ -164,21 +164,21 @@ namespace Lucene } } while (bucketTable->first || more); - + doc = NO_MORE_DOCS; return doc; } - + double BooleanScorer::score() { return current->score * coordFactors[current->coord]; } - + void BooleanScorer::score(CollectorPtr collector) { score(collector, INT_MAX, nextDoc()); } - + String BooleanScorer::toString() { StringStream buffer; @@ -188,17 +188,17 @@ namespace Lucene buffer << L")"; return buffer.str(); } - + BooleanScorerCollector::BooleanScorerCollector(int32_t mask, BucketTablePtr bucketTable) { this->mask = mask; this->_bucketTable = bucketTable; } - + BooleanScorerCollector::~BooleanScorerCollector() { } - + void BooleanScorerCollector::collect(int32_t doc) { BucketTablePtr table(_bucketTable); @@ -209,14 +209,14 @@ namespace Lucene bucket = newLucene(); table->buckets[i] = bucket; } - + if (bucket->doc != doc) // invalid bucket { bucket->doc = doc; // set doc bucket->score = ScorerPtr(_scorer)->score(); // initialize score bucket->bits = mask; // initialize mask bucket->coord = 1; // initialize coord - + bucket->_next = table->first; // push onto valid list table->first = bucket; } @@ -227,52 +227,52 @@ namespace Lucene ++bucket->coord; // increment coord } } - + void BooleanScorerCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { // not needed by this implementation } - + void BooleanScorerCollector::setScorer(ScorerPtr scorer) { this->_scorer = scorer; } - + bool BooleanScorerCollector::acceptsDocsOutOfOrder() { return true; } - + BucketScorer::BucketScorer() : Scorer(SimilarityPtr()) { _score = 0; doc = NO_MORE_DOCS; } - + BucketScorer::~BucketScorer() { } - + int32_t BucketScorer::advance(int32_t target) { return NO_MORE_DOCS; } - + int32_t BucketScorer::docID() { return doc; } - + int32_t BucketScorer::nextDoc() { return NO_MORE_DOCS; } - + double BucketScorer::score() { return _score; } - + Bucket::Bucket() { doc = -1; @@ -280,33 +280,33 @@ namespace Lucene bits = 0; coord = 0; } - + Bucket::~Bucket() { } - + const int32_t BucketTable::SIZE = 1 << 11; const int32_t BucketTable::MASK = BucketTable::SIZE - 1; - + BucketTable::BucketTable() { buckets = Collection::newInstance(SIZE); } - + BucketTable::~BucketTable() { } - + CollectorPtr BucketTable::newCollector(int32_t mask) { return newLucene(mask, shared_from_this()); } - + int32_t BucketTable::size() { return SIZE; } - + SubScorer::SubScorer(ScorerPtr scorer, bool required, bool prohibited, CollectorPtr collector, SubScorerPtr next) { this->scorer = scorer; @@ -315,7 +315,7 @@ namespace Lucene this->collector = collector; this->next = next; } - + SubScorer::~SubScorer() { } diff --git a/src/core/search/BooleanScorer2.cpp b/src/core/search/BooleanScorer2.cpp index fe4ac3a2..c743cb46 100644 --- a/src/core/search/BooleanScorer2.cpp +++ b/src/core/search/BooleanScorer2.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,11 +21,11 @@ namespace Lucene this->optionalScorers = optional; this->doc = -1; } - + BooleanScorer2::~BooleanScorer2() { } - + void BooleanScorer2::initialize() { if (minNrShouldMatch < 0) @@ -34,37 +34,37 @@ namespace Lucene coordinator = newLucene(shared_from_this()); coordinator->maxCoord += optionalScorers.size(); coordinator->maxCoord += requiredScorers.size(); - + coordinator->init(); countingSumScorer = makeCountingSumScorer(); } - + ScorerPtr BooleanScorer2::countingDisjunctionSumScorer(Collection scorers, int32_t minNrShouldMatch) { // each scorer from the list counted as a single matcher return newLucene(shared_from_this(), scorers, minNrShouldMatch); } - + ScorerPtr BooleanScorer2::countingConjunctionSumScorer(Collection requiredScorers) { // each scorer from the list counted as a single matcher return newLucene(shared_from_this(), Similarity::getDefault(), requiredScorers); } - + ScorerPtr BooleanScorer2::dualConjunctionSumScorer(ScorerPtr req1, ScorerPtr req2) { Collection scorers(newCollection(req1, req2)); - + // All scorers match, so Similarity::getDefault() always has 1 as the coordination factor. // Therefore the sum of the scores of two scorers is used as score. return newLucene(Similarity::getDefault(), scorers); } - + ScorerPtr BooleanScorer2::makeCountingSumScorer() { return requiredScorers.empty() ? makeCountingSumScorerNoReq() : makeCountingSumScorerSomeReq(); } - + ScorerPtr BooleanScorer2::makeCountingSumScorerNoReq() { // minNrShouldMatch optional scorers are required, but at least 1 @@ -78,7 +78,7 @@ namespace Lucene requiredCountingSumScorer = countingConjunctionSumScorer(optionalScorers); return addProhibitedScorers(requiredCountingSumScorer); } - + ScorerPtr BooleanScorer2::makeCountingSumScorerSomeReq() { if (optionalScorers.size() == minNrShouldMatch) // all optional scorers also required. @@ -96,19 +96,19 @@ namespace Lucene return newLucene(addProhibitedScorers(requiredCountingSumScorer), optionalScorers.size() == 1 ? newLucene(optionalScorers[0], coordinator) : countingDisjunctionSumScorer(optionalScorers, 1)); } } - + ScorerPtr BooleanScorer2::addProhibitedScorers(ScorerPtr requiredCountingSumScorer) { return prohibitedScorers.empty() ? requiredCountingSumScorer : newLucene(requiredCountingSumScorer, (prohibitedScorers.size() == 1 ? prohibitedScorers[0] : newLucene(prohibitedScorers))); } - + void BooleanScorer2::score(CollectorPtr collector) { collector->setScorer(shared_from_this()); while ((doc = countingSumScorer->nextDoc()) != NO_MORE_DOCS) collector->collect(doc); } - + bool BooleanScorer2::score(CollectorPtr collector, int32_t max, int32_t firstDocID) { doc = firstDocID; @@ -120,7 +120,7 @@ namespace Lucene } return (doc != NO_MORE_DOCS); } - + int32_t BooleanScorer2::docID() { return doc; @@ -131,31 +131,31 @@ namespace Lucene doc = countingSumScorer->nextDoc(); return doc; } - + double BooleanScorer2::score() { coordinator->nrMatchers = 0; double sum = countingSumScorer->score(); return sum * coordinator->coordFactors[coordinator->nrMatchers]; } - + int32_t BooleanScorer2::advance(int32_t target) { doc = countingSumScorer->advance(target); return doc; } - + Coordinator::Coordinator(BooleanScorer2Ptr scorer) { _scorer = scorer; maxCoord = 0; nrMatchers = 0; } - + Coordinator::~Coordinator() { } - + void Coordinator::init() { coordFactors = Collection::newInstance(maxCoord + 1); @@ -163,7 +163,7 @@ namespace Lucene for (int32_t i = 0; i <= maxCoord; ++i) coordFactors[i] = sim->coord(i, maxCoord); } - + SingleMatchScorer::SingleMatchScorer(ScorerPtr scorer, CoordinatorPtr coordinator) : Scorer(scorer->getSimilarity()) { lastScoredDoc = -1; @@ -171,11 +171,11 @@ namespace Lucene this->scorer = scorer; this->coordinator = coordinator; } - + SingleMatchScorer::~SingleMatchScorer() { } - + double SingleMatchScorer::score() { int32_t doc = docID(); @@ -190,33 +190,33 @@ namespace Lucene } return lastDocScore; } - + int32_t SingleMatchScorer::docID() { return scorer->docID(); } - + int32_t SingleMatchScorer::nextDoc() { return scorer->nextDoc(); } - + int32_t SingleMatchScorer::advance(int32_t target) { return scorer->advance(target); } - + CountingDisjunctionSumScorer::CountingDisjunctionSumScorer(BooleanScorer2Ptr scorer, Collection subScorers, int32_t minimumNrMatchers) : DisjunctionSumScorer(subScorers, minimumNrMatchers) { _scorer = scorer; lastScoredDoc = -1; lastDocScore = std::numeric_limits::quiet_NaN(); } - + CountingDisjunctionSumScorer::~CountingDisjunctionSumScorer() { } - + double CountingDisjunctionSumScorer::score() { int32_t doc = docID(); @@ -231,7 +231,7 @@ namespace Lucene } return lastDocScore; } - + CountingConjunctionSumScorer::CountingConjunctionSumScorer(BooleanScorer2Ptr scorer, SimilarityPtr similarity, Collection scorers) : ConjunctionScorer(similarity, scorers) { _scorer = scorer; @@ -239,11 +239,11 @@ namespace Lucene requiredNrMatchers = scorers.size(); lastDocScore = std::numeric_limits::quiet_NaN(); } - + CountingConjunctionSumScorer::~CountingConjunctionSumScorer() { } - + double CountingConjunctionSumScorer::score() { int32_t doc = docID(); @@ -256,7 +256,7 @@ namespace Lucene } BooleanScorer2Ptr(_scorer)->coordinator->nrMatchers += requiredNrMatchers; } - // All scorers match, so Similarity::getDefault() ConjunctionScorer::score() always has 1 as the + // All scorers match, so Similarity::getDefault() ConjunctionScorer::score() always has 1 as the /// coordination factor. Therefore the sum of the scores of the requiredScorers is used as score. return lastDocScore; } diff --git a/src/core/search/CachingSpanFilter.cpp b/src/core/search/CachingSpanFilter.cpp index eb55babb..c1db7111 100644 --- a/src/core/search/CachingSpanFilter.cpp +++ b/src/core/search/CachingSpanFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,72 +21,72 @@ namespace Lucene this->hitCount = 0; this->missCount = 0; } - + CachingSpanFilter::~CachingSpanFilter() { } - + DocIdSetPtr CachingSpanFilter::getDocIdSet(IndexReaderPtr reader) { SpanFilterResultPtr result(getCachedResult(reader)); return result ? result->getDocIdSet() : DocIdSetPtr(); } - + SpanFilterResultPtr CachingSpanFilter::getCachedResult(IndexReaderPtr reader) { LuceneObjectPtr coreKey = reader->getFieldCacheKey(); LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; - + SpanFilterResultPtr result(boost::dynamic_pointer_cast(cache->get(reader, coreKey, delCoreKey))); if (result) { ++hitCount; return result; } - + ++missCount; result = filter->bitSpans(reader); - + cache->put(coreKey, delCoreKey, result); - + return result; } - + SpanFilterResultPtr CachingSpanFilter::bitSpans(IndexReaderPtr reader) { return getCachedResult(reader); } - + String CachingSpanFilter::toString() { return L"CachingSpanFilter(" + filter->toString() + L")"; } - + bool CachingSpanFilter::equals(LuceneObjectPtr other) { if (SpanFilter::equals(other)) return true; - + CachingSpanFilterPtr otherCachingSpanFilter(boost::dynamic_pointer_cast(other)); if (!otherCachingSpanFilter) return false; - + return this->filter->equals(otherCachingSpanFilter->filter); } - + int32_t CachingSpanFilter::hashCode() { return filter->hashCode() ^ 0x1117bf25; } - + FilterCacheSpanFilterResult::FilterCacheSpanFilterResult(CachingWrapperFilter::DeletesMode deletesMode) : FilterCache(deletesMode) { } - + FilterCacheSpanFilterResult::~FilterCacheSpanFilterResult() { } - + LuceneObjectPtr FilterCacheSpanFilterResult::mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value) { boost::throw_exception(IllegalStateException(L"DeletesMode::DYNAMIC is not supported")); diff --git a/src/core/search/CachingWrapperFilter.cpp b/src/core/search/CachingWrapperFilter.cpp index 0e462d83..e88c54dc 100644 --- a/src/core/search/CachingWrapperFilter.cpp +++ b/src/core/search/CachingWrapperFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,11 +19,11 @@ namespace Lucene this->hitCount = 0; this->missCount = 0; } - + CachingWrapperFilter::~CachingWrapperFilter() { } - + DocIdSetPtr CachingWrapperFilter::docIdSetToCache(DocIdSetPtr docIdSet, IndexReaderPtr reader) { if (!docIdSet) @@ -41,68 +41,68 @@ namespace Lucene return !it ? DocIdSet::EMPTY_DOCIDSET() : newLucene(it, reader->maxDoc()); } } - + DocIdSetPtr CachingWrapperFilter::getDocIdSet(IndexReaderPtr reader) { LuceneObjectPtr coreKey = reader->getFieldCacheKey(); LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; - + DocIdSetPtr docIdSet(boost::dynamic_pointer_cast(cache->get(reader, coreKey, delCoreKey))); if (docIdSet) { ++hitCount; return docIdSet; } - + ++missCount; - + // cache miss docIdSet = docIdSetToCache(filter->getDocIdSet(reader), reader); - + if (docIdSet) cache->put(coreKey, delCoreKey, docIdSet); - + return docIdSet; } - + String CachingWrapperFilter::toString() { return L"CachingWrapperFilter(" + filter->toString() + L")"; } - + bool CachingWrapperFilter::equals(LuceneObjectPtr other) { if (Filter::equals(other)) return true; - + CachingWrapperFilterPtr otherCachingWrapperFilter(boost::dynamic_pointer_cast(other)); if (!otherCachingWrapperFilter) return false; - + return this->filter->equals(otherCachingWrapperFilter->filter); } - + int32_t CachingWrapperFilter::hashCode() { return filter->hashCode() ^ 0x1117bf25; } - + FilterCache::FilterCache(CachingWrapperFilter::DeletesMode deletesMode) { this->deletesMode = deletesMode; } - + FilterCache::~FilterCache() { } - + LuceneObjectPtr FilterCache::get(IndexReaderPtr reader, LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey) { SyncLock syncLock(this); - + if (!cache) cache = WeakMapObjectObject::newInstance(); - + LuceneObjectPtr value; if (deletesMode == CachingWrapperFilter::DELETES_IGNORE) { @@ -120,7 +120,7 @@ namespace Lucene // first try for exact match value = cache.get(delCoreKey); - + if (!value) { // now for core match, but dynamically AND NOT deletions @@ -129,14 +129,14 @@ namespace Lucene value = mergeDeletes(reader, value); } } - + return value; } - + void FilterCache::put(LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey, LuceneObjectPtr value) { SyncLock syncLock(this); - + if (deletesMode == CachingWrapperFilter::DELETES_IGNORE) cache.put(coreKey, value); else if (deletesMode == CachingWrapperFilter::DELETES_RECACHE) @@ -147,29 +147,29 @@ namespace Lucene cache.put(delCoreKey, value); } } - + FilterCacheDocIdSet::FilterCacheDocIdSet(CachingWrapperFilter::DeletesMode deletesMode) : FilterCache(deletesMode) - { + { } - + FilterCacheDocIdSet::~FilterCacheDocIdSet() { } - + LuceneObjectPtr FilterCacheDocIdSet::mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value) { return newLucene(reader, boost::dynamic_pointer_cast(value)); } - + FilteredCacheDocIdSet::FilteredCacheDocIdSet(IndexReaderPtr reader, DocIdSetPtr innerSet) : FilteredDocIdSet(innerSet) { this->reader = reader; } - + FilteredCacheDocIdSet::~FilteredCacheDocIdSet() { } - + bool FilteredCacheDocIdSet::match(int32_t docid) { return !reader->isDeleted(docid); diff --git a/src/core/search/Collector.cpp b/src/core/search/Collector.cpp index 056854e3..3a400dbb 100644 --- a/src/core/search/Collector.cpp +++ b/src/core/search/Collector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/search/ComplexExplanation.cpp b/src/core/search/ComplexExplanation.cpp index 31a1f641..45742ff4 100644 --- a/src/core/search/ComplexExplanation.cpp +++ b/src/core/search/ComplexExplanation.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,26 +14,26 @@ namespace Lucene { this->match = match; } - + ComplexExplanation::~ComplexExplanation() { } - + bool ComplexExplanation::getMatch() { return match; } - + void ComplexExplanation::setMatch(bool match) { this->match = match; } - + bool ComplexExplanation::isMatch() { return getMatch(); } - + String ComplexExplanation::getSummary() { return StringUtils::toString(getValue()) + L" = " + (isMatch() ? L"(MATCH) " : L"(NON-MATCH) ") + getDescription(); diff --git a/src/core/search/ConjunctionScorer.cpp b/src/core/search/ConjunctionScorer.cpp index 589ac86b..e6459b73 100644 --- a/src/core/search/ConjunctionScorer.cpp +++ b/src/core/search/ConjunctionScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,29 +23,29 @@ namespace Lucene this->lastDoc = -1; this->scorers = scorers; this->coord = similarity->coord(scorers.size(), scorers.size()); - + for (Collection::iterator scorer = scorers.begin(); scorer != scorers.end(); ++scorer) { if ((*scorer)->nextDoc() == NO_MORE_DOCS) { - // If even one of the sub-scorers does not have any documents, this scorer should not attempt + // If even one of the sub-scorers does not have any documents, this scorer should not attempt // to do any more work. lastDoc = NO_MORE_DOCS; return; } } - + // Sort the array the first time... - // We don't need to sort the array in any future calls because we know it will already start off + // We don't need to sort the array in any future calls because we know it will already start off // sorted (all scorers on same doc). std::sort(scorers.begin(), scorers.end(), lessScorerDocId()); - - // NOTE: doNext() must be called before the re-sorting of the array later on. The reason is this: - // assume there are 5 scorers, whose first docs are 1, 2, 3, 5, 5 respectively. Sorting (above) leaves + + // NOTE: doNext() must be called before the re-sorting of the array later on. The reason is this: + // assume there are 5 scorers, whose first docs are 1, 2, 3, 5, 5 respectively. Sorting (above) leaves // the array as is. Calling doNext() here advances all the first scorers to 5 (or a larger doc ID - // they all agree on). - // However, if we re-sort before doNext() is called, the order will be 5, 3, 2, 1, 5 and then doNext() - // will stop immediately, since the first scorer's docs equals the last one. So the invariant that after + // they all agree on). + // However, if we re-sort before doNext() is called, the order will be 5, 3, 2, 1, 5 and then doNext() + // will stop immediately, since the first scorer's docs equals the last one. So the invariant that after // calling doNext() all scorers are on the same doc ID is broken. if (doNext() == NO_MORE_DOCS) { @@ -53,9 +53,9 @@ namespace Lucene lastDoc = NO_MORE_DOCS; return; } - - // If first-time skip distance is any predictor of scorer sparseness, then we should always try to skip - // first on those scorers. Keep last scorer in it's last place (it will be the first to be skipped on), + + // If first-time skip distance is any predictor of scorer sparseness, then we should always try to skip + // first on those scorers. Keep last scorer in it's last place (it will be the first to be skipped on), // but reverse all of the others so that they will be skipped on in order of original high skip. int32_t end = scorers.size() - 1; int32_t max = end >> 1; @@ -67,11 +67,11 @@ namespace Lucene scorers[idx] = tmp; } } - + ConjunctionScorer::~ConjunctionScorer() { } - + int32_t ConjunctionScorer::doNext() { int32_t first = 0; @@ -84,7 +84,7 @@ namespace Lucene } return doc; } - + int32_t ConjunctionScorer::advance(int32_t target) { if (lastDoc == NO_MORE_DOCS) @@ -94,12 +94,12 @@ namespace Lucene lastDoc = doNext(); return lastDoc; } - + int32_t ConjunctionScorer::docID() { return lastDoc; } - + int32_t ConjunctionScorer::nextDoc() { if (lastDoc == NO_MORE_DOCS) @@ -113,7 +113,7 @@ namespace Lucene lastDoc = doNext(); return lastDoc; } - + double ConjunctionScorer::score() { double sum = 0.0; diff --git a/src/core/search/ConstantScoreQuery.cpp b/src/core/search/ConstantScoreQuery.cpp index 972a579a..00a9485d 100644 --- a/src/core/search/ConstantScoreQuery.cpp +++ b/src/core/search/ConstantScoreQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,54 +19,54 @@ namespace Lucene { this->filter = filter; } - + ConstantScoreQuery::~ConstantScoreQuery() { } - + FilterPtr ConstantScoreQuery::getFilter() { return filter; } - + QueryPtr ConstantScoreQuery::rewrite(IndexReaderPtr reader) { return shared_from_this(); } - + void ConstantScoreQuery::extractTerms(SetTerm terms) { // OK to not add any terms when used for MultiSearcher, but may not be OK for highlighting } - + WeightPtr ConstantScoreQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + String ConstantScoreQuery::toString(const String& field) { return L"ConstantScore(" + filter->toString() + (getBoost() == 1.0 ? L")" : L"^" + StringUtils::toString(getBoost())); } - + bool ConstantScoreQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + ConstantScoreQueryPtr otherConstantScoreQuery(boost::dynamic_pointer_cast(other)); if (!otherConstantScoreQuery) return false; - + return (this->getBoost() == otherConstantScoreQuery->getBoost() && this->filter->equals(otherConstantScoreQuery->filter)); } - + int32_t ConstantScoreQuery::hashCode() { // Simple add is OK since no existing filter hashcode has a float component. return filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); } - + LuceneObjectPtr ConstantScoreQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(filter); @@ -74,7 +74,7 @@ namespace Lucene cloneQuery->filter = filter; return cloneQuery; } - + ConstantWeight::ConstantWeight(ConstantScoreQueryPtr constantScorer, SearcherPtr searcher) { this->constantScorer = constantScorer; @@ -82,45 +82,45 @@ namespace Lucene this->queryNorm = 0; this->queryWeight = 0; } - + ConstantWeight::~ConstantWeight() { } - + QueryPtr ConstantWeight::getQuery() { return constantScorer; } - + double ConstantWeight::getValue() { return queryWeight; } - + double ConstantWeight::sumOfSquaredWeights() { queryWeight = constantScorer->getBoost(); return queryWeight * queryWeight; } - + void ConstantWeight::normalize(double norm) { this->queryNorm = norm; queryWeight *= this->queryNorm; } - + ScorerPtr ConstantWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(constantScorer, similarity, reader, shared_from_this()); } - + ExplanationPtr ConstantWeight::explain(IndexReaderPtr reader, int32_t doc) { ConstantScorerPtr cs(newLucene(constantScorer, similarity, reader, shared_from_this())); bool exists = (cs->docIdSetIterator->advance(doc) == doc); - + ComplexExplanationPtr result(newLucene()); - + if (exists) { result->setDescription(L"ConstantScoreQuery(" + constantScorer->filter->toString() + L"), product of:"); @@ -137,7 +137,7 @@ namespace Lucene } return result; } - + ConstantScorer::ConstantScorer(ConstantScoreQueryPtr constantScorer, SimilarityPtr similarity, IndexReaderPtr reader, WeightPtr w) : Scorer(similarity) { doc = -1; @@ -154,26 +154,26 @@ namespace Lucene docIdSetIterator = iter; } } - + ConstantScorer::~ConstantScorer() { } - + int32_t ConstantScorer::nextDoc() { return docIdSetIterator->nextDoc(); } - + int32_t ConstantScorer::docID() { return docIdSetIterator->docID(); } - + double ConstantScorer::score() { return theScore; } - + int32_t ConstantScorer::advance(int32_t target) { return docIdSetIterator->advance(target); diff --git a/src/core/search/DefaultSimilarity.cpp b/src/core/search/DefaultSimilarity.cpp index 6449f911..9217f007 100644 --- a/src/core/search/DefaultSimilarity.cpp +++ b/src/core/search/DefaultSimilarity.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene { discountOverlaps = false; } - + DefaultSimilarity::~DefaultSimilarity() { } - + double DefaultSimilarity::computeNorm(const String& fieldName, FieldInvertStatePtr state) { int32_t numTerms; @@ -28,42 +28,42 @@ namespace Lucene numTerms = state->getLength(); return (state->getBoost() * lengthNorm(fieldName, numTerms)); } - + double DefaultSimilarity::lengthNorm(const String& fieldName, int32_t numTokens) { return (double)(1.0 / std::sqrt((double)numTokens)); } - + double DefaultSimilarity::queryNorm(double sumOfSquaredWeights) { return (double)(1.0 / std::sqrt(sumOfSquaredWeights)); } - + double DefaultSimilarity::tf(double freq) { return (double)std::sqrt(freq); } - + double DefaultSimilarity::sloppyFreq(int32_t distance) { return (1.0 / (double)(distance + 1)); } - + double DefaultSimilarity::idf(int32_t docFreq, int32_t numDocs) { return (double)(std::log((double)numDocs / (double)(docFreq + 1)) + 1.0); } - + double DefaultSimilarity::coord(int32_t overlap, int32_t maxOverlap) { return (double)overlap / (double)maxOverlap; } - + void DefaultSimilarity::setDiscountOverlaps(bool v) { discountOverlaps = v; } - + bool DefaultSimilarity::getDiscountOverlaps() { return discountOverlaps; diff --git a/src/core/search/DisjunctionMaxQuery.cpp b/src/core/search/DisjunctionMaxQuery.cpp index 67cb42a7..13f90d77 100644 --- a/src/core/search/DisjunctionMaxQuery.cpp +++ b/src/core/search/DisjunctionMaxQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,43 +22,43 @@ namespace Lucene this->tieBreakerMultiplier = tieBreakerMultiplier; this->disjuncts = Collection::newInstance(); } - + DisjunctionMaxQuery::DisjunctionMaxQuery(Collection disjuncts, double tieBreakerMultiplier) { this->tieBreakerMultiplier = tieBreakerMultiplier; this->disjuncts = Collection::newInstance(); add(disjuncts); } - + DisjunctionMaxQuery::~DisjunctionMaxQuery() { } - + void DisjunctionMaxQuery::add(QueryPtr query) { disjuncts.add(query); } - + void DisjunctionMaxQuery::add(Collection disjuncts) { this->disjuncts.addAll(disjuncts.begin(), disjuncts.end()); } - + Collection::iterator DisjunctionMaxQuery::begin() { return disjuncts.begin(); } - + Collection::iterator DisjunctionMaxQuery::end() { return disjuncts.end(); } - + WeightPtr DisjunctionMaxQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + QueryPtr DisjunctionMaxQuery::rewrite(IndexReaderPtr reader) { int32_t numDisjunctions = disjuncts.size(); @@ -88,7 +88,7 @@ namespace Lucene } return clone ? clone : shared_from_this(); } - + LuceneObjectPtr DisjunctionMaxQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); @@ -97,13 +97,13 @@ namespace Lucene cloneQuery->disjuncts = Collection::newInstance(disjuncts.begin(), disjuncts.end()); return cloneQuery; } - + void DisjunctionMaxQuery::extractTerms(SetTerm terms) { for (Collection::iterator query = disjuncts.begin(); query != disjuncts.end(); ++query) (*query)->extractTerms(terms); } - + String DisjunctionMaxQuery::toString(const String& field) { String buffer(L"("); @@ -123,24 +123,24 @@ namespace Lucene buffer += L"^" + StringUtils::toString(getBoost()); return buffer; } - + bool DisjunctionMaxQuery::equals(LuceneObjectPtr other) { if (!Query::equals(other)) return false; - + DisjunctionMaxQueryPtr otherDisjunctionMaxQuery(boost::dynamic_pointer_cast(other)); if (!otherDisjunctionMaxQuery) return false; - + return (tieBreakerMultiplier == otherDisjunctionMaxQuery->tieBreakerMultiplier && disjuncts.equals(otherDisjunctionMaxQuery->disjuncts, luceneEquals())); } - + int32_t DisjunctionMaxQuery::hashCode() { return MiscUtils::doubleToIntBits(getBoost()) + MiscUtils::doubleToIntBits(tieBreakerMultiplier) + MiscUtils::hashCode(disjuncts.begin(), disjuncts.end(), MiscUtils::hashLucene); } - + DisjunctionMaxWeight::DisjunctionMaxWeight(DisjunctionMaxQueryPtr query, SearcherPtr searcher) { this->query = query; @@ -149,21 +149,21 @@ namespace Lucene for (Collection::iterator disjunctQuery = query->disjuncts.begin(); disjunctQuery != query->disjuncts.end(); ++disjunctQuery) this->weights.add((*disjunctQuery)->createWeight(searcher)); } - + DisjunctionMaxWeight::~DisjunctionMaxWeight() { } - + QueryPtr DisjunctionMaxWeight::getQuery() { return query; } - + double DisjunctionMaxWeight::getValue() { return query->getBoost(); } - + double DisjunctionMaxWeight::sumOfSquaredWeights() { double max = 0.0; @@ -177,14 +177,14 @@ namespace Lucene double boost = query->getBoost(); return (((sum - max) * query->tieBreakerMultiplier * query->tieBreakerMultiplier) + max) * boost * boost; } - + void DisjunctionMaxWeight::normalize(double norm) { norm *= query->getBoost(); // Incorporate our boost for (Collection::iterator wt = weights.begin(); wt != weights.end(); ++wt) (*wt)->normalize(norm); } - + ScorerPtr DisjunctionMaxWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { Collection scorers(Collection::newInstance(weights.size())); @@ -200,7 +200,7 @@ namespace Lucene DisjunctionMaxScorerPtr result(newLucene(query->tieBreakerMultiplier, similarity, scorers, idx)); return result; } - + ExplanationPtr DisjunctionMaxWeight::explain(IndexReaderPtr reader, int32_t doc) { if (query->disjuncts.size() == 1) diff --git a/src/core/search/DisjunctionMaxScorer.cpp b/src/core/search/DisjunctionMaxScorer.cpp index 7ba6dacf..e25cf94d 100644 --- a/src/core/search/DisjunctionMaxScorer.cpp +++ b/src/core/search/DisjunctionMaxScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,19 +13,19 @@ namespace Lucene { this->doc = -1; this->tieBreakerMultiplier = tieBreakerMultiplier; - - // The passed subScorers array includes only scorers which have documents (DisjunctionMaxQuery takes care + + // The passed subScorers array includes only scorers which have documents (DisjunctionMaxQuery takes care // of that), and their nextDoc() was already called. this->subScorers = subScorers; this->numScorers = numScorers; - + heapify(); } - + DisjunctionMaxScorer::~DisjunctionMaxScorer() { } - + int32_t DisjunctionMaxScorer::nextDoc() { if (numScorers == 0) @@ -47,16 +47,16 @@ namespace Lucene } } } - + doc = subScorers[0]->docID(); return doc; } - + int32_t DisjunctionMaxScorer::docID() { return doc; } - + double DisjunctionMaxScorer::score() { int32_t doc = subScorers[0]->docID(); @@ -67,7 +67,7 @@ namespace Lucene scoreAll(2, size, doc, sum, max); return max[0] + (sum[0] - max[0]) * tieBreakerMultiplier; } - + void DisjunctionMaxScorer::scoreAll(int32_t root, int32_t size, int32_t doc, Collection sum, Collection max) { if (root < size && subScorers[root]->docID() == doc) @@ -79,7 +79,7 @@ namespace Lucene scoreAll((root << 1) + 2, size, doc, sum, max); } } - + int32_t DisjunctionMaxScorer::advance(int32_t target) { if (numScorers == 0) @@ -104,13 +104,13 @@ namespace Lucene doc = subScorers[0]->docID(); return doc; } - + void DisjunctionMaxScorer::heapify() { for (int32_t i = (numScorers >> 1) - 1; i >= 0; --i) heapAdjust(i); } - + void DisjunctionMaxScorer::heapAdjust(int32_t root) { ScorerPtr scorer(subScorers[root]); @@ -154,7 +154,7 @@ namespace Lucene return; } } - + void DisjunctionMaxScorer::heapRemoveRoot() { if (numScorers == 1) diff --git a/src/core/search/DisjunctionSumScorer.cpp b/src/core/search/DisjunctionSumScorer.cpp index 72d329e1..060d18b4 100644 --- a/src/core/search/DisjunctionSumScorer.cpp +++ b/src/core/search/DisjunctionSumScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,27 +16,27 @@ namespace Lucene this->currentDoc = -1; this->_nrMatchers = -1; this->currentScore = std::numeric_limits::quiet_NaN(); - + this->nrScorers = subScorers.size(); - + if (minimumNrMatchers <= 0) boost::throw_exception(IllegalArgumentException(L"Minimum nr of matchers must be positive")); if (nrScorers <= 1) boost::throw_exception(IllegalArgumentException(L"There must be at least 2 subScorers")); - + this->minimumNrMatchers = minimumNrMatchers; this->subScorers = subScorers; } - + DisjunctionSumScorer::~DisjunctionSumScorer() { } - + void DisjunctionSumScorer::initialize() { initScorerDocQueue(); } - + void DisjunctionSumScorer::initScorerDocQueue() { scorerDocQueue = newLucene(nrScorers); @@ -46,14 +46,14 @@ namespace Lucene scorerDocQueue->insert(*se); } } - + void DisjunctionSumScorer::score(CollectorPtr collector) { collector->setScorer(shared_from_this()); while (nextDoc() != NO_MORE_DOCS) collector->collect(currentDoc); } - + bool DisjunctionSumScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) { // firstDocID is ignored since nextDoc() sets 'currentDoc' @@ -66,14 +66,14 @@ namespace Lucene } return true; } - + int32_t DisjunctionSumScorer::nextDoc() { if (scorerDocQueue->size() < minimumNrMatchers || !advanceAfterCurrent()) currentDoc = NO_MORE_DOCS; return currentDoc; } - + bool DisjunctionSumScorer::advanceAfterCurrent() { do // repeat until minimum nr of matchers @@ -94,7 +94,7 @@ namespace Lucene ++_nrMatchers; } while (true); - + if (_nrMatchers >= minimumNrMatchers) return true; else if (scorerDocQueue->size() < minimumNrMatchers) @@ -102,22 +102,22 @@ namespace Lucene } while (true); } - + double DisjunctionSumScorer::score() { return currentScore; } - + int32_t DisjunctionSumScorer::docID() { return currentDoc; } - + int32_t DisjunctionSumScorer::nrMatchers() { return _nrMatchers; } - + int32_t DisjunctionSumScorer::advance(int32_t target) { if (scorerDocQueue->size() < minimumNrMatchers) diff --git a/src/core/search/DocIdSet.cpp b/src/core/search/DocIdSet.cpp index e1050745..5ea2c6b8 100644 --- a/src/core/search/DocIdSet.cpp +++ b/src/core/search/DocIdSet.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,12 +13,12 @@ namespace Lucene DocIdSet::~DocIdSet() { } - + bool DocIdSet::isCacheable() { return false; } - + DocIdSetPtr DocIdSet::EMPTY_DOCIDSET() { static DocIdSetPtr _EMPTY_DOCIDSET; @@ -29,35 +29,35 @@ namespace Lucene } return _EMPTY_DOCIDSET; } - + EmptyDocIdSetIterator::~EmptyDocIdSetIterator() { } - + int32_t EmptyDocIdSetIterator::advance(int32_t target) { return NO_MORE_DOCS; } - + int32_t EmptyDocIdSetIterator::docID() { return NO_MORE_DOCS; } - + int32_t EmptyDocIdSetIterator::nextDoc() { return NO_MORE_DOCS; } - + EmptyDocIdSet::~EmptyDocIdSet() { } - + DocIdSetIteratorPtr EmptyDocIdSet::iterator() { return newLucene(); } - + bool EmptyDocIdSet::isCacheable() { return true; diff --git a/src/core/search/DocIdSetIterator.cpp b/src/core/search/DocIdSetIterator.cpp index 393fdf55..69702039 100644 --- a/src/core/search/DocIdSetIterator.cpp +++ b/src/core/search/DocIdSetIterator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene /// When returned by {@link #nextDoc()}, {@link #advance(int)} and {@link #docID()} it means there /// docs in the iterator. const int32_t DocIdSetIterator::NO_MORE_DOCS = INT_MAX; - + DocIdSetIterator::~DocIdSetIterator() { } diff --git a/src/core/search/ExactPhraseScorer.cpp b/src/core/search/ExactPhraseScorer.cpp index d5f9431b..020919f9 100644 --- a/src/core/search/ExactPhraseScorer.cpp +++ b/src/core/search/ExactPhraseScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene ExactPhraseScorer::ExactPhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) { } - + ExactPhraseScorer::~ExactPhraseScorer() { } - + double ExactPhraseScorer::phraseFreq() { // sort list with pq @@ -29,8 +29,8 @@ namespace Lucene pq->add(pp); // build pq from list } pqToList(); // rebuild list from pq - - // For counting how many times the exact phrase is found in current document, just count how many + + // For counting how many times the exact phrase is found in current document, just count how many // times all PhrasePosition's have exactly the same position. int32_t freq = 0; do @@ -48,7 +48,7 @@ namespace Lucene ++freq; // all equal: a match } while (last->nextPosition()); - + return freq; } } diff --git a/src/core/search/Explanation.cpp b/src/core/search/Explanation.cpp index d73ed4b4..294f3ba4 100644 --- a/src/core/search/Explanation.cpp +++ b/src/core/search/Explanation.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,60 +15,60 @@ namespace Lucene this->value = value; this->description = description; } - + Explanation::~Explanation() { } - + bool Explanation::isMatch() { return (0.0 < getValue()); } - + double Explanation::getValue() { return value; } - + void Explanation::setValue(double value) { this->value = value; } - + String Explanation::getDescription() { return description; } - + void Explanation::setDescription(const String& description) { this->description = description; } - + String Explanation::getSummary() { return StringUtils::toString(getValue()) + L" = " + getDescription(); } - + Collection Explanation::getDetails() { if (!details) return Collection(); return Collection::newInstance(this->details.begin(), this->details.end()); } - + void Explanation::addDetail(ExplanationPtr detail) { if (!details) details = Collection::newInstance(); details.add(detail); } - + String Explanation::toString() { return toString(0); } - + String Explanation::toString(int32_t depth) { String buffer; @@ -82,7 +82,7 @@ namespace Lucene } return buffer; } - + String Explanation::toHtml() { String buffer(L"
        \n
      • " + getSummary() + L"
        \n"); @@ -94,7 +94,7 @@ namespace Lucene buffer += L"
      • \n
      \n"; return buffer; } - + IDFExplanation::~IDFExplanation() { } diff --git a/src/core/search/FieldCache.cpp b/src/core/search/FieldCache.cpp index c93a9623..4895c54a 100644 --- a/src/core/search/FieldCache.cpp +++ b/src/core/search/FieldCache.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,11 +15,11 @@ namespace Lucene { /// Indicator for StringIndex values in the cache. const int32_t FieldCache::STRING_INDEX = -1; - + FieldCache::~FieldCache() { } - + FieldCachePtr FieldCache::DEFAULT() { static FieldCacheImplPtr _DEFAULT; @@ -30,7 +30,7 @@ namespace Lucene } return _DEFAULT; } - + ByteParserPtr FieldCache::DEFAULT_BYTE_PARSER() { static DefaultByteParserPtr _DEFAULT_BYTE_PARSER; @@ -41,7 +41,7 @@ namespace Lucene } return _DEFAULT_BYTE_PARSER; } - + IntParserPtr FieldCache::DEFAULT_INT_PARSER() { static DefaultIntParserPtr _DEFAULT_INT_PARSER; @@ -52,7 +52,7 @@ namespace Lucene } return _DEFAULT_INT_PARSER; } - + LongParserPtr FieldCache::DEFAULT_LONG_PARSER() { static DefaultLongParserPtr _DEFAULT_LONG_PARSER; @@ -63,7 +63,7 @@ namespace Lucene } return _DEFAULT_LONG_PARSER; } - + DoubleParserPtr FieldCache::DEFAULT_DOUBLE_PARSER() { static DefaultDoubleParserPtr _DEFAULT_DOUBLE_PARSER; @@ -74,7 +74,7 @@ namespace Lucene } return _DEFAULT_DOUBLE_PARSER; } - + IntParserPtr FieldCache::NUMERIC_UTILS_INT_PARSER() { static NumericUtilsIntParserPtr _NUMERIC_UTILS_INT_PARSER; @@ -85,7 +85,7 @@ namespace Lucene } return _NUMERIC_UTILS_INT_PARSER; } - + LongParserPtr FieldCache::NUMERIC_UTILS_LONG_PARSER() { static NumericUtilsLongParserPtr _NUMERIC_UTILS_LONG_PARSER; @@ -96,7 +96,7 @@ namespace Lucene } return _NUMERIC_UTILS_LONG_PARSER; } - + DoubleParserPtr FieldCache::NUMERIC_UTILS_DOUBLE_PARSER() { static NumericUtilsDoubleParserPtr _NUMERIC_UTILS_DOUBLE_PARSER; @@ -107,154 +107,154 @@ namespace Lucene } return _NUMERIC_UTILS_DOUBLE_PARSER; } - + Collection FieldCache::getBytes(IndexReaderPtr reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getInts(IndexReaderPtr reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getLongs(IndexReaderPtr reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getDoubles(IndexReaderPtr reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser) { BOOST_ASSERT(false); return Collection(); // override } - + Collection FieldCache::getStrings(IndexReaderPtr reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - + StringIndexPtr FieldCache::getStringIndex(IndexReaderPtr reader, const String& field) { BOOST_ASSERT(false); return StringIndexPtr(); // override } - + void FieldCache::setInfoStream(InfoStreamPtr stream) { BOOST_ASSERT(false); // override } - + InfoStreamPtr FieldCache::getInfoStream() { BOOST_ASSERT(false); return InfoStreamPtr(); // override } - + CreationPlaceholder::~CreationPlaceholder() { } - + StringIndex::StringIndex(Collection values, Collection lookup) { this->order = values; this->lookup = lookup; } - + StringIndex::~StringIndex() { } - + int32_t StringIndex::binarySearchLookup(const String& key) { Collection::iterator search = std::lower_bound(lookup.begin(), lookup.end(), key); int32_t keyPos = std::distance(lookup.begin(), search); return (search == lookup.end() || key < *search) ? -(keyPos + 1) : keyPos; } - + Parser::~Parser() { } - + ByteParser::~ByteParser() { } - + uint8_t ByteParser::parseByte(const String& string) { return 0; // override } - + DefaultByteParser::~DefaultByteParser() { } - + uint8_t DefaultByteParser::parseByte(const String& string) { return (uint8_t)StringUtils::toInt(string); } - + String DefaultByteParser::toString() { - return FieldCache::_getClassName() + L".DEFAULT_BYTE_PARSER"; + return FieldCache::_getClassName() + L".DEFAULT_BYTE_PARSER"; } - + IntParser::~IntParser() { } - + int32_t IntParser::parseInt(const String& string) { return 0; // override } - + DefaultIntParser::~DefaultIntParser() { } - + int32_t DefaultIntParser::parseInt(const String& string) { return StringUtils::toInt(string); } - + String DefaultIntParser::toString() { - return FieldCache::_getClassName() + L".DEFAULT_INT_PARSER"; + return FieldCache::_getClassName() + L".DEFAULT_INT_PARSER"; } - + NumericUtilsIntParser::~NumericUtilsIntParser() { } - + int32_t NumericUtilsIntParser::parseInt(const String& string) { int32_t shift = string[0] - NumericUtils::SHIFT_START_INT; @@ -262,39 +262,39 @@ namespace Lucene boost::throw_exception(StopFillCacheException()); return NumericUtils::prefixCodedToInt(string); } - + String NumericUtilsIntParser::toString() { - return FieldCache::_getClassName() + L".NUMERIC_UTILS_INT_PARSER"; + return FieldCache::_getClassName() + L".NUMERIC_UTILS_INT_PARSER"; } - + LongParser::~LongParser() { } - + int64_t LongParser::parseLong(const String& string) { return 0; // override } - + DefaultLongParser::~DefaultLongParser() { } - + int64_t DefaultLongParser::parseLong(const String& string) { return StringUtils::toLong(string); } - + String DefaultLongParser::toString() { - return FieldCache::_getClassName() + L".DEFAULT_LONG_PARSER"; + return FieldCache::_getClassName() + L".DEFAULT_LONG_PARSER"; } - + NumericUtilsLongParser::~NumericUtilsLongParser() { } - + int64_t NumericUtilsLongParser::parseLong(const String& string) { int32_t shift = string[0] - NumericUtils::SHIFT_START_LONG; @@ -302,39 +302,39 @@ namespace Lucene boost::throw_exception(StopFillCacheException()); return NumericUtils::prefixCodedToLong(string); } - + String NumericUtilsLongParser::toString() { - return FieldCache::_getClassName() + L".NUMERIC_UTILS_LONG_PARSER"; + return FieldCache::_getClassName() + L".NUMERIC_UTILS_LONG_PARSER"; } - + DoubleParser::~DoubleParser() { } - + double DoubleParser::parseDouble(const String& string) { return 0; // override } - + DefaultDoubleParser::~DefaultDoubleParser() { } - + double DefaultDoubleParser::parseDouble(const String& string) { return StringUtils::toDouble(string); } - + String DefaultDoubleParser::toString() { - return FieldCache::_getClassName() + L".DEFAULT_DOUBLE_PARSER"; + return FieldCache::_getClassName() + L".DEFAULT_DOUBLE_PARSER"; } - + NumericUtilsDoubleParser::~NumericUtilsDoubleParser() { } - + double NumericUtilsDoubleParser::parseDouble(const String& string) { int32_t shift = string[0] - NumericUtils::SHIFT_START_LONG; @@ -342,16 +342,16 @@ namespace Lucene boost::throw_exception(StopFillCacheException()); return NumericUtils::sortableLongToDouble(NumericUtils::prefixCodedToLong(string)); } - + String NumericUtilsDoubleParser::toString() { - return FieldCache::_getClassName() + L".NUMERIC_UTILS_DOUBLE_PARSER"; + return FieldCache::_getClassName() + L".NUMERIC_UTILS_DOUBLE_PARSER"; } - + FieldCacheEntry::~FieldCacheEntry() { } - + String FieldCacheEntry::toString() { StringStream buffer; diff --git a/src/core/search/FieldCacheImpl.cpp b/src/core/search/FieldCacheImpl.cpp index 9e45629f..e8761975 100644 --- a/src/core/search/FieldCacheImpl.cpp +++ b/src/core/search/FieldCacheImpl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,11 +20,11 @@ namespace Lucene FieldCacheImpl::FieldCacheImpl() { } - + FieldCacheImpl::~FieldCacheImpl() { } - + void FieldCacheImpl::initialize() { caches = MapStringCache::newInstance(); @@ -35,18 +35,18 @@ namespace Lucene caches.put(CACHE_STRING, newLucene(shared_from_this())); caches.put(CACHE_STRING_INDEX, newLucene(shared_from_this())); } - + void FieldCacheImpl::purgeAllCaches() { initialize(); } - + void FieldCacheImpl::purge(IndexReaderPtr r) { for (MapStringCache::iterator cache = caches.begin(); cache != caches.end(); ++cache) cache->second->purge(r); } - + Collection FieldCacheImpl::getCacheEntries() { Collection result(Collection::newInstance()); @@ -55,7 +55,7 @@ namespace Lucene for (WeakMapLuceneObjectMapEntryAny::iterator key = cache->second->readerCache.begin(); key != cache->second->readerCache.end(); ++key) { LuceneObjectPtr readerKey(key->first.lock()); - + // we've now materialized a hard ref if (readerKey) { @@ -66,82 +66,82 @@ namespace Lucene } return result; } - + Collection FieldCacheImpl::getBytes(IndexReaderPtr reader, const String& field) { return getBytes(reader, field, ByteParserPtr()); } - + Collection FieldCacheImpl::getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser) { return VariantUtils::get< Collection >(caches.get(CACHE_BYTE)->get(reader, newLucene(field, parser))); } - + Collection FieldCacheImpl::getInts(IndexReaderPtr reader, const String& field) { return getInts(reader, field, IntParserPtr()); } - + Collection FieldCacheImpl::getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser) { return VariantUtils::get< Collection >(caches.get(CACHE_INT)->get(reader, newLucene(field, parser))); } - + Collection FieldCacheImpl::getLongs(IndexReaderPtr reader, const String& field) { return getLongs(reader, field, LongParserPtr()); } - + Collection FieldCacheImpl::getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser) { return VariantUtils::get< Collection >(caches.get(CACHE_LONG)->get(reader, newLucene(field, parser))); } - + Collection FieldCacheImpl::getDoubles(IndexReaderPtr reader, const String& field) { return getDoubles(reader, field, DoubleParserPtr()); } - + Collection FieldCacheImpl::getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser) { return VariantUtils::get< Collection >(caches.get(CACHE_DOUBLE)->get(reader, newLucene(field, parser))); } - + Collection FieldCacheImpl::getStrings(IndexReaderPtr reader, const String& field) { return VariantUtils::get< Collection >(caches.get(CACHE_STRING)->get(reader, newLucene(field, ParserPtr()))); } - + StringIndexPtr FieldCacheImpl::getStringIndex(IndexReaderPtr reader, const String& field) { return VariantUtils::get< StringIndexPtr >(caches.get(CACHE_STRING_INDEX)->get(reader, newLucene(field, ParserPtr()))); } - + void FieldCacheImpl::setInfoStream(InfoStreamPtr stream) { infoStream = stream; } - + InfoStreamPtr FieldCacheImpl::getInfoStream() { return infoStream; } - + Entry::Entry(const String& field, boost::any custom) { this->field = field; this->custom = custom; } - + Entry::~Entry() { } - + bool Entry::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + EntryPtr otherEntry(boost::dynamic_pointer_cast(other)); if (otherEntry) { @@ -150,29 +150,29 @@ namespace Lucene } return false; } - + int32_t Entry::hashCode() { return StringUtils::hashCode(field) ^ VariantUtils::hashCode(custom); } - + Cache::Cache(FieldCachePtr wrapper) { this->_wrapper = wrapper; this->readerCache = WeakMapLuceneObjectMapEntryAny::newInstance(); } - + Cache::~Cache() { } - + void Cache::purge(IndexReaderPtr r) { LuceneObjectPtr readerKey(r->getFieldCacheKey()); SyncLock cacheLock(&readerCache); readerCache.remove(readerKey); } - + boost::any Cache::get(IndexReaderPtr reader, EntryPtr key) { MapEntryAny innerCache; @@ -205,9 +205,9 @@ namespace Lucene SyncLock cacheLock(&readerCache); innerCache.put(key, progress->value); } - + FieldCachePtr wrapper(_wrapper); - + // Only check if key.custom (the parser) is non-null; else, we check twice for a single // call to FieldCache.getXXX if (!VariantUtils::isNull(key->custom) && wrapper) @@ -221,7 +221,7 @@ namespace Lucene } return value; } - + void Cache::printNewInsanity(InfoStreamPtr infoStream, boost::any value) { Collection insanities(FieldCacheSanityChecker::checkSanity(FieldCachePtr(_wrapper))); @@ -239,15 +239,15 @@ namespace Lucene } } } - + ByteCache::ByteCache(FieldCachePtr wrapper) : Cache(wrapper) { } - + ByteCache::~ByteCache() { } - + boost::any ByteCache::createValue(IndexReaderPtr reader, EntryPtr key) { EntryPtr entry(key); @@ -285,15 +285,15 @@ namespace Lucene finally.throwException(); return retArray; } - + IntCache::IntCache(FieldCachePtr wrapper) : Cache(wrapper) { } - + IntCache::~IntCache() { } - + boost::any IntCache::createValue(IndexReaderPtr reader, EntryPtr key) { EntryPtr entry(key); @@ -347,15 +347,15 @@ namespace Lucene retArray = Collection::newInstance(reader->maxDoc()); return retArray; } - + LongCache::LongCache(FieldCachePtr wrapper) : Cache(wrapper) { } - + LongCache::~LongCache() { } - + boost::any LongCache::createValue(IndexReaderPtr reader, EntryPtr key) { EntryPtr entry(key); @@ -409,15 +409,15 @@ namespace Lucene retArray = Collection::newInstance(reader->maxDoc()); return retArray; } - + DoubleCache::DoubleCache(FieldCachePtr wrapper) : Cache(wrapper) { } - + DoubleCache::~DoubleCache() { } - + boost::any DoubleCache::createValue(IndexReaderPtr reader, EntryPtr key) { EntryPtr entry(key); @@ -471,15 +471,15 @@ namespace Lucene retArray = Collection::newInstance(reader->maxDoc()); return retArray; } - + StringCache::StringCache(FieldCachePtr wrapper) : Cache(wrapper) { } - + StringCache::~StringCache() { } - + boost::any StringCache::createValue(IndexReaderPtr reader, EntryPtr key) { EntryPtr entry(key); @@ -511,15 +511,15 @@ namespace Lucene finally.throwException(); return retArray; } - + StringIndexCache::StringIndexCache(FieldCachePtr wrapper) : Cache(wrapper) { } - + StringIndexCache::~StringIndexCache() { } - + boost::any StringIndexCache::createValue(IndexReaderPtr reader, EntryPtr key) { EntryPtr entry(key); @@ -529,12 +529,12 @@ namespace Lucene TermDocsPtr termDocs(reader->termDocs()); TermEnumPtr termEnum(reader->terms(newLucene(field))); int32_t t = 0; // current term number - - // an entry for documents that have no terms in this field should a document with no terms be at - // top or bottom? This puts them at the top - if it is changed, FieldDocSortedHitQueue needs to + + // an entry for documents that have no terms in this field should a document with no terms be at + // top or bottom? This puts them at the top - if it is changed, FieldDocSortedHitQueue needs to // change as well. mterms[t++] = L""; - + LuceneException finally; try { @@ -543,14 +543,14 @@ namespace Lucene TermPtr term(termEnum->term()); if (!term || term->field() != field || t >= mterms.size() ) break; - + // store term text mterms[t] = term->text(); - + termDocs->seek(termEnum); while (termDocs->next()) retArray[termDocs->doc()] = t; - + ++t; } while (termEnum->next()); @@ -562,7 +562,7 @@ namespace Lucene termDocs->close(); termEnum->close(); finally.throwException(); - + if (t == 0) { // if there are no terms, make the term array have a single null entry @@ -573,10 +573,10 @@ namespace Lucene // if there are less terms than documents, trim off the dead array space mterms.resize(t); } - + return newLucene(retArray, mterms); } - + FieldCacheEntryImpl::FieldCacheEntryImpl(LuceneObjectPtr readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value) { this->readerKey = readerKey; @@ -585,31 +585,31 @@ namespace Lucene this->custom = custom; this->value = value; } - + FieldCacheEntryImpl::~FieldCacheEntryImpl() { } - + LuceneObjectPtr FieldCacheEntryImpl::getReaderKey() { return readerKey; } - + String FieldCacheEntryImpl::getFieldName() { return fieldName; } - + int32_t FieldCacheEntryImpl::getCacheType() { return cacheType; } - + boost::any FieldCacheEntryImpl::getCustom() { return custom; } - + boost::any FieldCacheEntryImpl::getValue() { return value; diff --git a/src/core/search/FieldCacheRangeFilter.cpp b/src/core/search/FieldCacheRangeFilter.cpp index 15851211..b5f6da76 100644 --- a/src/core/search/FieldCacheRangeFilter.cpp +++ b/src/core/search/FieldCacheRangeFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,96 +23,96 @@ namespace Lucene this->includeLower = includeLower; this->includeUpper = includeUpper; } - + FieldCacheRangeFilter::~FieldCacheRangeFilter() { } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newStringRange(const String& field, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) { return newLucene(field, ParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) { return newByteRange(field, ByteParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, ByteParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) { return newIntRange(field, IntParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, IntParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) { return newLongRange(field, LongParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, LongParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, double lowerVal, double upperVal, bool includeLower, bool includeUpper) { return newDoubleRange(field, DoubleParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, DoubleParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } - + String FieldCacheRangeFilter::getField() { return field; } - + bool FieldCacheRangeFilter::includesLower() { return includeLower; } - + bool FieldCacheRangeFilter::includesUpper() { return includeUpper; } - + ParserPtr FieldCacheRangeFilter::getParser() { return parser; } - + FieldCacheRangeFilterString::FieldCacheRangeFilterString(const String& field, ParserPtr parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) { this->lowerVal = lowerVal; this->upperVal = upperVal; } - + FieldCacheRangeFilterString::~FieldCacheRangeFilterString() { } - + DocIdSetPtr FieldCacheRangeFilterString::getDocIdSet(IndexReaderPtr reader) { StringIndexPtr fcsi(FieldCache::DEFAULT()->getStringIndex(reader, field)); int32_t lowerPoint = fcsi->binarySearchLookup(lowerVal); int32_t upperPoint = fcsi->binarySearchLookup(upperVal); - + int32_t inclusiveLowerPoint = 0; int32_t inclusiveUpperPoint = 0; - + // Hints: // * binarySearchLookup returns 0, if value was null. // * the value is <0 if no exact hit was found, the returned value is (-(insertion point) - 1) @@ -127,7 +127,7 @@ namespace Lucene inclusiveLowerPoint = lowerPoint + 1; else inclusiveLowerPoint = std::max((int32_t)1, -lowerPoint - 1); - + if (upperPoint == 0) { BOOST_ASSERT(upperVal.empty()); @@ -139,17 +139,17 @@ namespace Lucene inclusiveUpperPoint = upperPoint - 1; else inclusiveUpperPoint = -upperPoint - 2; - + if (inclusiveUpperPoint <= 0 || inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet::EMPTY_DOCIDSET(); - + BOOST_ASSERT(inclusiveLowerPoint > 0 && inclusiveUpperPoint > 0); - - // for this DocIdSet, we never need to use TermDocs, because deleted docs have an order of 0 + + // for this DocIdSet, we never need to use TermDocs, because deleted docs have an order of 0 // (null entry in StringIndex) return newLucene(reader, false, fcsi, inclusiveLowerPoint, inclusiveUpperPoint); } - + String FieldCacheRangeFilterString::toString() { StringStream buffer; @@ -158,7 +158,7 @@ namespace Lucene buffer << (includeLower ? L"]" : L"}"); return buffer.str(); } - + bool FieldCacheRangeFilterString::equals(LuceneObjectPtr other) { if (Filter::equals(other)) @@ -174,7 +174,7 @@ namespace Lucene return false; return true; } - + int32_t FieldCacheRangeFilterString::hashCode() { int32_t code = StringUtils::hashCode(field); @@ -185,101 +185,101 @@ namespace Lucene code ^= (includeLower ? 1549299360 : -365038026) ^ (includeUpper ? 1721088258 : 1948649653); return code; } - + FieldCacheRangeFilterByte::FieldCacheRangeFilterByte(const String& field, ParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, UCHAR_MAX, includeLower, includeUpper) { } - + FieldCacheRangeFilterByte::~FieldCacheRangeFilterByte() { } - + Collection FieldCacheRangeFilterByte::getValues(IndexReaderPtr reader) { return FieldCache::DEFAULT()->getBytes(reader, field, boost::static_pointer_cast(parser)); } - + FieldCacheRangeFilterInt::FieldCacheRangeFilterInt(const String& field, ParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, INT_MAX, includeLower, includeUpper) { } - + FieldCacheRangeFilterInt::~FieldCacheRangeFilterInt() { } - + Collection FieldCacheRangeFilterInt::getValues(IndexReaderPtr reader) { return FieldCache::DEFAULT()->getInts(reader, field, boost::static_pointer_cast(parser)); } - + FieldCacheRangeFilterLong::FieldCacheRangeFilterLong(const String& field, ParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::max(), includeLower, includeUpper) { } - + FieldCacheRangeFilterLong::~FieldCacheRangeFilterLong() { } - + Collection FieldCacheRangeFilterLong::getValues(IndexReaderPtr reader) { return FieldCache::DEFAULT()->getLongs(reader, field, boost::static_pointer_cast(parser)); } - + FieldCacheRangeFilterDouble::FieldCacheRangeFilterDouble(const String& field, ParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::infinity(), includeLower, includeUpper) { } - + FieldCacheRangeFilterDouble::~FieldCacheRangeFilterDouble() { } - + DocIdSetPtr FieldCacheRangeFilterDouble::getDocIdSet(IndexReaderPtr reader) { if (!includeLower && lowerVal > 0.0 && MiscUtils::isInfinite(lowerVal)) return DocIdSet::EMPTY_DOCIDSET(); int64_t lower = NumericUtils::doubleToSortableLong(lowerVal); double inclusiveLowerPoint = NumericUtils::sortableLongToDouble(includeLower ? lower : (lower + 1)); - + if (!includeUpper && upperVal < 0.0 && MiscUtils::isInfinite(upperVal)) return DocIdSet::EMPTY_DOCIDSET(); int64_t upper = NumericUtils::doubleToSortableLong(upperVal); double inclusiveUpperPoint = NumericUtils::sortableLongToDouble(includeUpper ? upper : (upper - 1)); - + if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet::EMPTY_DOCIDSET(); - + // we only request the usage of termDocs, if the range contains 0 return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); } - + Collection FieldCacheRangeFilterDouble::getValues(IndexReaderPtr reader) { return FieldCache::DEFAULT()->getDoubles(reader, field, boost::static_pointer_cast(parser)); } - + FieldCacheDocIdSet::FieldCacheDocIdSet(IndexReaderPtr reader, bool mayUseTermDocs) { this->reader = reader; this->mayUseTermDocs = mayUseTermDocs; } - + FieldCacheDocIdSet::~FieldCacheDocIdSet() { } - + bool FieldCacheDocIdSet::isCacheable() { return !(mayUseTermDocs && reader->hasDeletions()); } - + DocIdSetIteratorPtr FieldCacheDocIdSet::iterator() { - // Synchronization needed because deleted docs BitVector can change after call to hasDeletions until - // TermDocs creation. We only use an iterator with termDocs, when this was requested (eg. range + // Synchronization needed because deleted docs BitVector can change after call to hasDeletions until + // TermDocs creation. We only use an iterator with termDocs, when this was requested (eg. range // contains 0) and the index has deletions TermDocsPtr termDocs; { @@ -293,46 +293,46 @@ namespace Lucene } else { - // a DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there + // a DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there // are no deletions are on the index return newLucene(shared_from_this()); } } - + FieldCacheDocIdSetString::FieldCacheDocIdSetString(IndexReaderPtr reader, bool mayUseTermDocs, StringIndexPtr fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) { this->fcsi = fcsi; this->inclusiveLowerPoint = inclusiveLowerPoint; this->inclusiveUpperPoint = inclusiveUpperPoint; } - + FieldCacheDocIdSetString::~FieldCacheDocIdSetString() { } - + bool FieldCacheDocIdSetString::matchDoc(int32_t doc) { if (doc < 0 || doc >= fcsi->order.size()) boost::throw_exception(IndexOutOfBoundsException()); return (fcsi->order[doc] >= inclusiveLowerPoint && fcsi->order[doc] <= inclusiveUpperPoint); } - + FieldDocIdSetIteratorTermDocs::FieldDocIdSetIteratorTermDocs(FieldCacheDocIdSetPtr cacheDocIdSet, TermDocsPtr termDocs) { this->_cacheDocIdSet = cacheDocIdSet; this->termDocs = termDocs; this->doc = -1; } - + FieldDocIdSetIteratorTermDocs::~FieldDocIdSetIteratorTermDocs() { } - + int32_t FieldDocIdSetIteratorTermDocs::docID() { return doc; } - + int32_t FieldDocIdSetIteratorTermDocs::nextDoc() { FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); @@ -347,7 +347,7 @@ namespace Lucene while (!cacheDocIdSet->matchDoc(doc = termDocs->doc())); return doc; } - + int32_t FieldDocIdSetIteratorTermDocs::advance(int32_t target) { FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); @@ -366,22 +366,22 @@ namespace Lucene } return doc; } - + FieldDocIdSetIteratorIncrement::FieldDocIdSetIteratorIncrement(FieldCacheDocIdSetPtr cacheDocIdSet) { this->_cacheDocIdSet = cacheDocIdSet; this->doc = -1; } - + FieldDocIdSetIteratorIncrement::~FieldDocIdSetIteratorIncrement() { } - + int32_t FieldDocIdSetIteratorIncrement::docID() { return doc; } - + int32_t FieldDocIdSetIteratorIncrement::nextDoc() { FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); @@ -400,7 +400,7 @@ namespace Lucene return doc; } } - + int32_t FieldDocIdSetIteratorIncrement::advance(int32_t target) { FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); diff --git a/src/core/search/FieldCacheTermsFilter.cpp b/src/core/search/FieldCacheTermsFilter.cpp index c9f688a6..e1bcac33 100644 --- a/src/core/search/FieldCacheTermsFilter.cpp +++ b/src/core/search/FieldCacheTermsFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,21 +17,21 @@ namespace Lucene this->field = field; this->terms = terms; } - + FieldCacheTermsFilter::~FieldCacheTermsFilter() { } - + FieldCachePtr FieldCacheTermsFilter::getFieldCache() { return FieldCache::DEFAULT(); } - + DocIdSetPtr FieldCacheTermsFilter::getDocIdSet(IndexReaderPtr reader) { return newLucene(terms, getFieldCache()->getStringIndex(reader, field)); } - + FieldCacheTermsFilterDocIdSet::FieldCacheTermsFilterDocIdSet(Collection terms, StringIndexPtr fcsi) { this->fcsi = fcsi; @@ -43,37 +43,37 @@ namespace Lucene openBitSet->set(termNumber); } } - + FieldCacheTermsFilterDocIdSet::~FieldCacheTermsFilterDocIdSet() { } - + DocIdSetIteratorPtr FieldCacheTermsFilterDocIdSet::iterator() { return newLucene(fcsi, openBitSet); } - + bool FieldCacheTermsFilterDocIdSet::isCacheable() { return true; } - + FieldCacheTermsFilterDocIdSetIterator::FieldCacheTermsFilterDocIdSetIterator(StringIndexPtr fcsi, OpenBitSetPtr openBitSet) { this->fcsi = fcsi; this->openBitSet = openBitSet; this->doc = -1; } - + FieldCacheTermsFilterDocIdSetIterator::~FieldCacheTermsFilterDocIdSetIterator() { } - + int32_t FieldCacheTermsFilterDocIdSetIterator::docID() { return doc; } - + int32_t FieldCacheTermsFilterDocIdSetIterator::nextDoc() { try @@ -92,7 +92,7 @@ namespace Lucene } return doc; } - + int32_t FieldCacheTermsFilterDocIdSetIterator::advance(int32_t target) { try diff --git a/src/core/search/FieldComparator.cpp b/src/core/search/FieldComparator.cpp index dd736bd9..c3864319 100644 --- a/src/core/search/FieldComparator.cpp +++ b/src/core/search/FieldComparator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,178 +15,178 @@ namespace Lucene FieldComparator::~FieldComparator() { } - + void FieldComparator::setScorer(ScorerPtr scorer) { // Empty implementation since most comparators don't need the score. // This can be overridden by those that need it. } - + ByteComparator::ByteComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } - + ByteComparator::~ByteComparator() { } - + void ByteComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getBytes(reader, field, parser); } - + DocComparator::DocComparator(int32_t numHits) : NumericComparator(numHits) { this->docBase = 0; } - + DocComparator::~DocComparator() { } - + int32_t DocComparator::compareBottom(int32_t doc) { // No overflow risk because docIDs are non-negative return (bottom - (docBase + doc)); } - + void DocComparator::copy(int32_t slot, int32_t doc) { values[slot] = docBase + doc; } - + void DocComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { this->docBase = docBase; } - + DoubleComparator::DoubleComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } - + DoubleComparator::~DoubleComparator() { } - + int32_t DoubleComparator::compare(int32_t slot1, int32_t slot2) { double v1 = values[slot1]; double v2 = values[slot2]; return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); } - + int32_t DoubleComparator::compareBottom(int32_t doc) { double v2 = currentReaderValues[doc]; return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); } - + void DoubleComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getDoubles(reader, field, parser); } - + IntComparator::IntComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } - + IntComparator::~IntComparator() { } - + int32_t IntComparator::compare(int32_t slot1, int32_t slot2) { int32_t v1 = values[slot1]; int32_t v2 = values[slot2]; return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); } - + int32_t IntComparator::compareBottom(int32_t doc) { int32_t v2 = currentReaderValues[doc]; return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); } - + void IntComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getInts(reader, field, parser); } - + LongComparator::LongComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } - + LongComparator::~LongComparator() { } - + int32_t LongComparator::compare(int32_t slot1, int32_t slot2) { int64_t v1 = values[slot1]; int64_t v2 = values[slot2]; return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); } - + int32_t LongComparator::compareBottom(int32_t doc) { int64_t v2 = currentReaderValues[doc]; return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); } - + void LongComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getLongs(reader, field, parser); } - + RelevanceComparator::RelevanceComparator(int32_t numHits) : NumericComparator(numHits) { } - + RelevanceComparator::~RelevanceComparator() { } - + int32_t RelevanceComparator::compare(int32_t slot1, int32_t slot2) { double score1 = values[slot1]; double score2 = values[slot2]; return score1 > score2 ? -1 : (score1 < score2 ? 1 : 0); } - + int32_t RelevanceComparator::compareBottom(int32_t doc) { double score = scorer->score(); return bottom > score ? -1 : (bottom < score ? 1 : 0); } - + void RelevanceComparator::copy(int32_t slot, int32_t doc) { values[slot] = scorer->score(); } - + void RelevanceComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { } - + void RelevanceComparator::setScorer(ScorerPtr scorer) { this->scorer = newLucene(scorer); } - + StringComparatorLocale::StringComparatorLocale(int32_t numHits, const String& field, const std::locale& locale) : collator(newLucene(locale)) { this->values = Collection::newInstance(numHits); this->field = field; } - + StringComparatorLocale::~StringComparatorLocale() { } - + int32_t StringComparatorLocale::compare(int32_t slot1, int32_t slot2) { return collator->compare(values[slot1], values[slot2]); @@ -196,27 +196,27 @@ namespace Lucene { return collator->compare(bottom, currentReaderValues[doc]); } - + void StringComparatorLocale::copy(int32_t slot, int32_t doc) { values[slot] = currentReaderValues[doc]; } - + void StringComparatorLocale::setNextReader(IndexReaderPtr reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); } - + void StringComparatorLocale::setBottom(int32_t slot) { bottom = values[slot]; } - + ComparableValue StringComparatorLocale::value(int32_t slot) { return values[slot]; } - + StringOrdValComparator::StringOrdValComparator(int32_t numHits, const String& field, int32_t sortPos, bool reversed) { this->ords = Collection::newInstance(numHits); @@ -229,11 +229,11 @@ namespace Lucene this->bottomSlot = -1; this->bottomOrd = 0; } - + StringOrdValComparator::~StringOrdValComparator() { } - + int32_t StringOrdValComparator::compare(int32_t slot1, int32_t slot2) { if (readerGen[slot1] == readerGen[slot2]) @@ -254,7 +254,7 @@ namespace Lucene return cmp; return bottomValue.compare(lookup[order]); } - + void StringOrdValComparator::convert(int32_t slot) { readerGen[slot] = currentReaderGen; @@ -265,7 +265,7 @@ namespace Lucene ords[slot] = 0; return; } - + if (sortPos == 0 && bottomSlot != -1 && bottomSlot != slot) { // Since we are the primary sort, the entries in the queue are bounded by bottomOrd @@ -280,20 +280,20 @@ namespace Lucene // Full binary search index = binarySearch(lookup, value, 0, lookup.size() - 1); } - + if (index < 0) index = -index - 2; - + ords[slot] = index; } - + int32_t StringOrdValComparator::binarySearch(Collection lookup, const String& key, int32_t low, int32_t high) { Collection::iterator search = std::lower_bound(lookup.begin() + low, lookup.begin() + high, key); int32_t keyPos = std::distance(lookup.begin(), search); return (search == lookup.end() || key < *search) ? -(keyPos + 1) : keyPos; } - + void StringOrdValComparator::copy(int32_t slot, int32_t doc) { int32_t ord = order[doc]; @@ -302,7 +302,7 @@ namespace Lucene values[slot] = lookup[ord]; readerGen[slot] = currentReaderGen; } - + void StringOrdValComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { StringIndexPtr currentReaderValues(FieldCache::DEFAULT()->getStringIndex(reader, field)); @@ -316,7 +316,7 @@ namespace Lucene bottomOrd = ords[bottomSlot]; } } - + void StringOrdValComparator::setBottom(int32_t slot) { bottomSlot = slot; @@ -327,37 +327,37 @@ namespace Lucene BOOST_ASSERT(bottomOrd < lookup.size()); bottomValue = values[slot]; } - + ComparableValue StringOrdValComparator::value(int32_t slot) { return values[slot]; } - + Collection StringOrdValComparator::getValues() { return values; } - + int32_t StringOrdValComparator::getBottomSlot() { return bottomSlot; } - + String StringOrdValComparator::getField() { return field; } - + StringValComparator::StringValComparator(int32_t numHits, const String& field) { this->values = Collection::newInstance(numHits); this->field = field; } - + StringValComparator::~StringValComparator() { } - + int32_t StringValComparator::compare(int32_t slot1, int32_t slot2) { return values[slot1].compare(values[slot2]); @@ -367,22 +367,22 @@ namespace Lucene { return bottom.compare(currentReaderValues[doc]); } - + void StringValComparator::copy(int32_t slot, int32_t doc) { values[slot] = currentReaderValues[doc]; } - + void StringValComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); } - + void StringValComparator::setBottom(int32_t slot) { bottom = values[slot]; } - + ComparableValue StringValComparator::value(int32_t slot) { return values[slot]; diff --git a/src/core/search/FieldComparatorSource.cpp b/src/core/search/FieldComparatorSource.cpp index 35c5edc6..edb76a91 100644 --- a/src/core/search/FieldComparatorSource.cpp +++ b/src/core/search/FieldComparatorSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/search/FieldDoc.cpp b/src/core/search/FieldDoc.cpp index 15acb18e..cc25b5e0 100644 --- a/src/core/search/FieldDoc.cpp +++ b/src/core/search/FieldDoc.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,11 +13,11 @@ namespace Lucene { this->fields = fields; } - + FieldDoc::~FieldDoc() { } - + String FieldDoc::toString() { StringStream buffer; diff --git a/src/core/search/FieldDocSortedHitQueue.cpp b/src/core/search/FieldDocSortedHitQueue.cpp index f1ca6bee..0ccf7a1f 100644 --- a/src/core/search/FieldDocSortedHitQueue.cpp +++ b/src/core/search/FieldDocSortedHitQueue.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,22 +17,22 @@ namespace Lucene FieldDocSortedHitQueue::FieldDocSortedHitQueue(int32_t size) : PriorityQueue(size) { } - + FieldDocSortedHitQueue::~FieldDocSortedHitQueue() { } - + void FieldDocSortedHitQueue::setFields(Collection fields) { this->fields = fields; this->collators = hasCollators(fields); } - + Collection FieldDocSortedHitQueue::getFields() { return fields; } - + Collection FieldDocSortedHitQueue::hasCollators(Collection fields) { if (!fields) @@ -46,7 +46,7 @@ namespace Lucene } return ret; } - + bool FieldDocSortedHitQueue::lessThan(const FieldDocPtr& first, const FieldDocPtr& second) { int32_t n = fields.size(); @@ -69,16 +69,16 @@ namespace Lucene if (type == SortField::SCORE) c = -c; } - + // reverse sort if (fields[i]->getReverse()) c = -c; } - + // avoid random sort order that could lead to duplicates if (c == 0) return (first->doc > second->doc); - + return (c > 0); } } diff --git a/src/core/search/FieldValueHitQueue.cpp b/src/core/search/FieldValueHitQueue.cpp index 4c436407..80830b2f 100644 --- a/src/core/search/FieldValueHitQueue.cpp +++ b/src/core/search/FieldValueHitQueue.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,40 +16,40 @@ namespace Lucene FieldValueHitQueue::FieldValueHitQueue(Collection fields, int32_t size) : HitQueueBase(size) { // When we get here, fields.size() is guaranteed to be > 0, therefore no need to check it again. - - // All these are required by this class's API - need to return arrays. Therefore even in the case + + // All these are required by this class's API - need to return arrays. Therefore even in the case // of a single comparator, create an array anyway. this->fields = fields; int32_t numComparators = fields.size(); comparators = Collection::newInstance(numComparators); reverseMul = Collection::newInstance(numComparators); } - + FieldValueHitQueue::~FieldValueHitQueue() { } - + FieldValueHitQueuePtr FieldValueHitQueue::create(Collection fields, int32_t size) { if (fields.empty()) boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); - + if (fields.size() == 1) return newLucene(fields, size); else return newLucene(fields, size); } - + Collection FieldValueHitQueue::getComparators() { return comparators; } - + Collection FieldValueHitQueue::getReverseMul() { return reverseMul; } - + FieldDocPtr FieldValueHitQueue::fillFields(FieldValueHitQueueEntryPtr entry) { int32_t n = comparators.size(); @@ -58,59 +58,59 @@ namespace Lucene fields[i] = comparators[i]->value(entry->slot); return newLucene(entry->doc, entry->score, fields); } - + Collection FieldValueHitQueue::getFields() { return fields; } - + FieldValueHitQueueEntry::FieldValueHitQueueEntry(int32_t slot, int32_t doc, double score) : ScoreDoc(doc, score) { this->slot = slot; } - + FieldValueHitQueueEntry::~FieldValueHitQueueEntry() { } - + String FieldValueHitQueueEntry::toString() { StringStream buffer; buffer << L"slot:" << slot << L" " << ScoreDoc::toString(); return buffer.str(); } - + OneComparatorFieldValueHitQueue::OneComparatorFieldValueHitQueue(Collection fields, int32_t size) : FieldValueHitQueue(fields, size) { if (fields.empty()) boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); - + SortFieldPtr field(fields[0]); comparator = field->getComparator(size, 0); oneReverseMul = field->reverse ? -1 : 1; - + comparators[0] = comparator; reverseMul[0] = oneReverseMul; } - + OneComparatorFieldValueHitQueue::~OneComparatorFieldValueHitQueue() { } - + bool OneComparatorFieldValueHitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { FieldValueHitQueueEntryPtr firstEntry(boost::static_pointer_cast(first)); FieldValueHitQueueEntryPtr secondEntry(boost::static_pointer_cast(second)); - + BOOST_ASSERT(firstEntry != secondEntry); BOOST_ASSERT(firstEntry->slot != secondEntry->slot); - + int32_t c = oneReverseMul * comparator->compare(firstEntry->slot, secondEntry->slot); - + // avoid random sort order that could lead to duplicates return c != 0 ? (c > 0) : (firstEntry->doc > secondEntry->doc); } - + MultiComparatorsFieldValueHitQueue::MultiComparatorsFieldValueHitQueue(Collection fields, int32_t size) : FieldValueHitQueue(fields, size) { int32_t numComparators = comparators.size(); @@ -121,19 +121,19 @@ namespace Lucene comparators[i] = field->getComparator(size, i); } } - + MultiComparatorsFieldValueHitQueue::~MultiComparatorsFieldValueHitQueue() { } - + bool MultiComparatorsFieldValueHitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { FieldValueHitQueueEntryPtr firstEntry(boost::static_pointer_cast(first)); FieldValueHitQueueEntryPtr secondEntry(boost::static_pointer_cast(second)); - + BOOST_ASSERT(firstEntry != secondEntry); BOOST_ASSERT(firstEntry->slot != secondEntry->slot); - + int32_t numComparators = comparators.size(); for (int32_t i = 0; i < numComparators; ++i) { @@ -141,7 +141,7 @@ namespace Lucene if (c != 0) return (c > 0); // Short circuit } - + // avoid random sort order that could lead to duplicates return (firstEntry->doc > secondEntry->doc); } diff --git a/src/core/search/Filter.cpp b/src/core/search/Filter.cpp index 7ee0bc3a..dd4add26 100644 --- a/src/core/search/Filter.cpp +++ b/src/core/search/Filter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/search/FilterManager.cpp b/src/core/search/FilterManager.cpp index d3c92601..34178420 100644 --- a/src/core/search/FilterManager.cpp +++ b/src/core/search/FilterManager.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,28 +14,28 @@ namespace Lucene { /// The default maximum number of Filters in the cache const int32_t FilterManager::DEFAULT_CACHE_CLEAN_SIZE = 100; - + /// The default frequency of cache cleanup const int64_t FilterManager::DEFAULT_CACHE_SLEEP_TIME = 1000 * 60 * 10; - + FilterManager::FilterManager() { } - + FilterManager::~FilterManager() { } - + void FilterManager::initialize() { cache = MapIntFilterItem::newInstance(); cacheCleanSize = DEFAULT_CACHE_CLEAN_SIZE; // Let the cache get to 100 items cleanSleepTime = DEFAULT_CACHE_SLEEP_TIME; // 10 minutes between cleanings - + filterCleaner = newLucene(shared_from_this()); filterCleaner->start(); } - + FilterManagerPtr FilterManager::getInstance() { static FilterManagerPtr manager; @@ -46,17 +46,17 @@ namespace Lucene } return manager; } - + void FilterManager::setCacheSize(int32_t cacheCleanSize) { this->cacheCleanSize = cacheCleanSize; } - + void FilterManager::setCleanThreadSleepTime(int64_t cleanSleepTime) { this->cleanSleepTime = cleanSleepTime; } - + FilterPtr FilterManager::getFilter(FilterPtr filter) { SyncLock parentLock(&cache); @@ -69,39 +69,39 @@ namespace Lucene cache.put(filter->hashCode(), newLucene(filter)); return filter; } - + FilterItem::FilterItem(FilterPtr filter) { this->filter = filter; this->timestamp = MiscUtils::currentTimeMillis(); } - + FilterItem::~FilterItem() { } - + FilterCleaner::FilterCleaner(FilterManagerPtr manager) { _manager = manager; running = true; } - + FilterCleaner::~FilterCleaner() { } - + void FilterCleaner::run() { while (running) { FilterManagerPtr manager(_manager); - - // sort items from oldest to newest we delete the oldest filters + + // sort items from oldest to newest we delete the oldest filters if (manager->cache.size() > manager->cacheCleanSize) { // empty the temporary set sortedFilterItems.clear(); - + { SyncLock parentLock(&manager->cache); for (MapIntFilterItem::iterator item = manager->cache.begin(); item != manager->cache.end(); ++item) @@ -116,7 +116,7 @@ namespace Lucene // empty the set so we don't tie up the memory sortedFilterItems.clear(); } - + // take a nap LuceneThread::threadSleep(manager->cleanSleepTime); } diff --git a/src/core/search/FilteredDocIdSet.cpp b/src/core/search/FilteredDocIdSet.cpp index 8970e5c9..fc92f753 100644 --- a/src/core/search/FilteredDocIdSet.cpp +++ b/src/core/search/FilteredDocIdSet.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,30 +14,30 @@ namespace Lucene { this->innerSet = innerSet; } - + FilteredDocIdSet::~FilteredDocIdSet() { } - + bool FilteredDocIdSet::isCacheable() { return innerSet->isCacheable(); } - + DocIdSetIteratorPtr FilteredDocIdSet::iterator() { return newLucene(shared_from_this(), innerSet->iterator()); } - + DefaultFilteredDocIdSetIterator::DefaultFilteredDocIdSetIterator(FilteredDocIdSetPtr filtered, DocIdSetIteratorPtr innerIter) : FilteredDocIdSetIterator(innerIter) { this->filtered = filtered; } - + DefaultFilteredDocIdSetIterator::~DefaultFilteredDocIdSetIterator() { } - + bool DefaultFilteredDocIdSetIterator::match(int32_t docid) { return filtered->match(docid); diff --git a/src/core/search/FilteredDocIdSetIterator.cpp b/src/core/search/FilteredDocIdSetIterator.cpp index 86f919fe..9f13a574 100644 --- a/src/core/search/FilteredDocIdSetIterator.cpp +++ b/src/core/search/FilteredDocIdSetIterator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,16 +16,16 @@ namespace Lucene this->innerIter = innerIter; this->doc = -1; } - + FilteredDocIdSetIterator::~FilteredDocIdSetIterator() { } - + int32_t FilteredDocIdSetIterator::docID() { return doc; } - + int32_t FilteredDocIdSetIterator::nextDoc() { while ((doc = innerIter->nextDoc()) != NO_MORE_DOCS) @@ -35,7 +35,7 @@ namespace Lucene } return doc; } - + int32_t FilteredDocIdSetIterator::advance(int32_t target) { doc = innerIter->advance(target); diff --git a/src/core/search/FilteredQuery.cpp b/src/core/search/FilteredQuery.cpp index 53f0970d..764586ec 100644 --- a/src/core/search/FilteredQuery.cpp +++ b/src/core/search/FilteredQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,18 +19,18 @@ namespace Lucene this->query = query; this->filter = filter; } - + FilteredQuery::~FilteredQuery() { } - + WeightPtr FilteredQuery::createWeight(SearcherPtr searcher) { WeightPtr weight(query->createWeight(searcher)); SimilarityPtr similarity(query->getSimilarity(searcher)); return newLucene(shared_from_this(), weight, similarity); } - + QueryPtr FilteredQuery::rewrite(IndexReaderPtr reader) { QueryPtr rewritten(query->rewrite(reader)); @@ -43,29 +43,29 @@ namespace Lucene else return shared_from_this(); } - + QueryPtr FilteredQuery::getQuery() { return query; } - + FilterPtr FilteredQuery::getFilter() { return filter; } - + void FilteredQuery::extractTerms(SetTerm terms) { getQuery()->extractTerms(terms); } - + String FilteredQuery::toString(const String& field) { StringStream buffer; buffer << L"filtered(" << query->toString(field) << L")->" << filter->toString() << boostString(); return buffer.str(); } - + bool FilteredQuery::equals(LuceneObjectPtr other) { FilteredQueryPtr otherFilteredQuery(boost::dynamic_pointer_cast(other)); @@ -73,12 +73,12 @@ namespace Lucene return false; return (Query::equals(other) && query->equals(otherFilteredQuery->query) && filter->equals(otherFilteredQuery->filter)); } - + int32_t FilteredQuery::hashCode() { return query->hashCode() ^ filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); } - + LuceneObjectPtr FilteredQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(query, filter); @@ -87,7 +87,7 @@ namespace Lucene cloneQuery->filter = filter; return cloneQuery; } - + FilteredQueryWeight::FilteredQueryWeight(FilteredQueryPtr query, WeightPtr weight, SimilarityPtr similarity) { this->query = query; @@ -95,27 +95,27 @@ namespace Lucene this->similarity = similarity; value = 0.0; } - + FilteredQueryWeight::~FilteredQueryWeight() { } - + double FilteredQueryWeight::getValue() { return value; } - + double FilteredQueryWeight::sumOfSquaredWeights() { - return weight->sumOfSquaredWeights() * query->getBoost() * query->getBoost(); + return weight->sumOfSquaredWeights() * query->getBoost() * query->getBoost(); } - + void FilteredQueryWeight::normalize(double norm) { weight->normalize(norm); value = weight->getValue() * query->getBoost(); } - + ExplanationPtr FilteredQueryWeight::explain(IndexReaderPtr reader, int32_t doc) { ExplanationPtr inner(weight->explain(reader, doc)); @@ -140,12 +140,12 @@ namespace Lucene return result; } } - + QueryPtr FilteredQueryWeight::getQuery() { return query; } - + ScorerPtr FilteredQueryWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { ScorerPtr scorer(weight->scorer(reader, true, false)); @@ -159,7 +159,7 @@ namespace Lucene return ScorerPtr(); return newLucene(shared_from_this(), scorer, docIdSetIterator, similarity); } - + FilteredQueryWeightScorer::FilteredQueryWeightScorer(FilteredQueryWeightPtr weight, ScorerPtr scorer, DocIdSetIteratorPtr docIdSetIterator, SimilarityPtr similarity) : Scorer(similarity) { this->weight = weight; @@ -167,11 +167,11 @@ namespace Lucene this->docIdSetIterator = docIdSetIterator; doc = -1; } - + FilteredQueryWeightScorer::~FilteredQueryWeightScorer() { } - + int32_t FilteredQueryWeightScorer::advanceToCommon(int32_t scorerDoc, int32_t disiDoc) { while (scorerDoc != disiDoc) @@ -183,7 +183,7 @@ namespace Lucene } return scorerDoc; } - + int32_t FilteredQueryWeightScorer::nextDoc() { int32_t disiDoc = docIdSetIterator->nextDoc(); @@ -191,12 +191,12 @@ namespace Lucene doc = (scorerDoc != NO_MORE_DOCS && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS) ? scorer->docID() : NO_MORE_DOCS; return doc; } - + int32_t FilteredQueryWeightScorer::docID() { return doc; } - + int32_t FilteredQueryWeightScorer::advance(int32_t target) { int32_t disiDoc = docIdSetIterator->advance(target); @@ -204,7 +204,7 @@ namespace Lucene doc = (scorerDoc != NO_MORE_DOCS && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS) ? scorer->docID() : NO_MORE_DOCS; return doc; } - + double FilteredQueryWeightScorer::score() { return weight->query->getBoost() * scorer->score(); diff --git a/src/core/search/FilteredTermEnum.cpp b/src/core/search/FilteredTermEnum.cpp index afe12457..2ce9335b 100644 --- a/src/core/search/FilteredTermEnum.cpp +++ b/src/core/search/FilteredTermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene FilteredTermEnum::~FilteredTermEnum() { } - + void FilteredTermEnum::setEnum(TermEnumPtr actualEnum) { this->actualEnum = actualEnum; @@ -23,7 +23,7 @@ namespace Lucene else next(); } - + int32_t FilteredTermEnum::docFreq() { if (!currentTerm) @@ -31,7 +31,7 @@ namespace Lucene BOOST_ASSERT(actualEnum); return actualEnum->docFreq(); } - + bool FilteredTermEnum::next() { if (!actualEnum) @@ -56,12 +56,12 @@ namespace Lucene currentTerm.reset(); return false; } - + TermPtr FilteredTermEnum::term() { return currentTerm; } - + void FilteredTermEnum::close() { if (actualEnum) diff --git a/src/core/search/FuzzyQuery.cpp b/src/core/search/FuzzyQuery.cpp index 13111f8b..be8a818b 100644 --- a/src/core/search/FuzzyQuery.cpp +++ b/src/core/search/FuzzyQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,80 +17,80 @@ namespace Lucene { const int32_t FuzzyQuery::defaultPrefixLength = 0; - + FuzzyQuery::FuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength) { ConstructQuery(term, minimumSimilarity, prefixLength); } - + FuzzyQuery::FuzzyQuery(TermPtr term, double minimumSimilarity) { ConstructQuery(term, minimumSimilarity, defaultPrefixLength); } - + FuzzyQuery::FuzzyQuery(TermPtr term) { ConstructQuery(term, defaultMinSimilarity(), defaultPrefixLength); } - + FuzzyQuery::~FuzzyQuery() { } - + void FuzzyQuery::ConstructQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength) { this->term = term; - + if (minimumSimilarity >= 1.0) boost::throw_exception(IllegalArgumentException(L"minimumSimilarity >= 1")); else if (minimumSimilarity < 0.0) boost::throw_exception(IllegalArgumentException(L"minimumSimilarity < 0")); if (prefixLength < 0) boost::throw_exception(IllegalArgumentException(L"prefixLength < 0")); - + this->termLongEnough = ((int32_t)term->text().length() > (int32_t)(1.0 / (1.0 - minimumSimilarity))); - + this->minimumSimilarity = minimumSimilarity; this->prefixLength = prefixLength; rewriteMethod = SCORING_BOOLEAN_QUERY_REWRITE(); } - + double FuzzyQuery::defaultMinSimilarity() { const double _defaultMinSimilarity = 0.5; return _defaultMinSimilarity; } - + double FuzzyQuery::getMinSimilarity() { return minimumSimilarity; } - + int32_t FuzzyQuery::getPrefixLength() { return prefixLength; } - + FilteredTermEnumPtr FuzzyQuery::getEnum(IndexReaderPtr reader) { return newLucene(reader, getTerm(), minimumSimilarity, prefixLength); } - + TermPtr FuzzyQuery::getTerm() { return term; } - + void FuzzyQuery::setRewriteMethod(RewriteMethodPtr method) { boost::throw_exception(UnsupportedOperationException(L"FuzzyQuery cannot change rewrite method")); } - + QueryPtr FuzzyQuery::rewrite(IndexReaderPtr reader) { if (!termLongEnough) // can only match if it's exact return newLucene(term); - + int32_t maxSize = BooleanQuery::getMaxClauseCount(); ScoreTermQueuePtr stQueue(newLucene(1024)); FilteredTermEnumPtr enumerator(getEnum(reader)); @@ -122,7 +122,7 @@ namespace Lucene } enumerator->close(); finally.throwException(); - + BooleanQueryPtr query(newLucene(true)); int32_t size = stQueue->size(); for (int32_t i = 0; i < size; ++i) @@ -132,10 +132,10 @@ namespace Lucene tq->setBoost(getBoost() * st->score); // set the boost query->add(tq, BooleanClause::SHOULD); // add to query } - + return query; } - + LuceneObjectPtr FuzzyQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); @@ -146,7 +146,7 @@ namespace Lucene cloneQuery->term = term; return cloneQuery; } - + String FuzzyQuery::toString(const String& field) { StringStream buffer; @@ -155,7 +155,7 @@ namespace Lucene buffer << term->text() << L"~" << minimumSimilarity << boostString(); return buffer.str(); } - + int32_t FuzzyQuery::hashCode() { int32_t prime = 31; @@ -165,7 +165,7 @@ namespace Lucene result = prime * result + (term ? term->hashCode() : 0); return result; } - + bool FuzzyQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -190,11 +190,11 @@ namespace Lucene return false; return true; } - + ScoreTerm::~ScoreTerm() { } - + int32_t ScoreTerm::compareTo(ScoreTermPtr other) { if (this->score == other->score) @@ -202,15 +202,15 @@ namespace Lucene else return this->score < other->score ? -1 : (this->score > other->score ? 1 : 0); } - + ScoreTermQueue::ScoreTermQueue(int32_t size) : PriorityQueue(size) { } - + ScoreTermQueue::~ScoreTermQueue() { } - + bool ScoreTermQueue::lessThan(const ScoreTermPtr& first, const ScoreTermPtr& second) { return (first->compareTo(second) < 0); diff --git a/src/core/search/FuzzyTermEnum.cpp b/src/core/search/FuzzyTermEnum.cpp index 2cc37ea6..80266dc9 100644 --- a/src/core/search/FuzzyTermEnum.cpp +++ b/src/core/search/FuzzyTermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,21 +17,21 @@ namespace Lucene { ConstructTermEnum(reader, term, minSimilarity, prefixLength); } - + FuzzyTermEnum::FuzzyTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity) { ConstructTermEnum(reader, term, minSimilarity, FuzzyQuery::defaultPrefixLength); } - + FuzzyTermEnum::FuzzyTermEnum(IndexReaderPtr reader, TermPtr term) { ConstructTermEnum(reader, term, FuzzyQuery::defaultMinSimilarity(), FuzzyQuery::defaultPrefixLength); } - + FuzzyTermEnum::~FuzzyTermEnum() { } - + void FuzzyTermEnum::ConstructTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity, int32_t prefixLength) { if (minSimilarity >= 1.0) @@ -40,28 +40,28 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"minimumSimilarity cannot be less than 0")); if (prefixLength < 0) boost::throw_exception(IllegalArgumentException(L"prefixLength cannot be less than 0")); - + this->minimumSimilarity = minSimilarity; this->scale_factor = 1.0 / (1.0 - minimumSimilarity); this->searchTerm = term; this->field = searchTerm->field(); this->_endEnum = false; this->_similarity = 0.0; - - // The prefix could be longer than the word. + + // The prefix could be longer than the word. // It's kind of silly though. It means we must match the entire word. int32_t fullSearchTermLength = searchTerm->text().length(); int32_t realPrefixLength = prefixLength > fullSearchTermLength ? fullSearchTermLength : prefixLength; - + this->text = searchTerm->text().substr(realPrefixLength); this->prefix = searchTerm->text().substr(0, realPrefixLength); - + this->p = Collection::newInstance(this->text.length() + 1); this->d = Collection::newInstance(this->text.length() + 1); - + setEnum(reader->terms(newLucene(searchTerm->field(), prefix))); } - + bool FuzzyTermEnum::termCompare(TermPtr term) { if (field == term->field() && boost::starts_with(term->text(), prefix)) @@ -73,17 +73,17 @@ namespace Lucene _endEnum = true; return false; } - + double FuzzyTermEnum::difference() { return (_similarity - minimumSimilarity) * scale_factor; } - + bool FuzzyTermEnum::endEnum() { return _endEnum; } - + double FuzzyTermEnum::similarity(const String& target) { int32_t m = target.length(); @@ -95,29 +95,29 @@ namespace Lucene } if (m == 0) return prefix.empty() ? 0.0 : 1.0 - ((double)n / (double)prefix.length()); - + int32_t maxDistance = calculateMaxDistance(m); - + if (maxDistance < std::abs(m - n)) { - // Just adding the characters of m to n or vice-versa results in too many edits for example "pre" length - // is 3 and "prefixes" length is 8. We can see that given this optimal circumstance, the edit distance - // cannot be less than 5. which is 8-3 or more precisely std::abs(3 - 8). if our maximum edit distance + // Just adding the characters of m to n or vice-versa results in too many edits for example "pre" length + // is 3 and "prefixes" length is 8. We can see that given this optimal circumstance, the edit distance + // cannot be less than 5. which is 8-3 or more precisely std::abs(3 - 8). if our maximum edit distance // is 4, then we can discard this word without looking at it. return 0.0; } - + // init matrix d for (int32_t i = 0; i <= n; ++i) p[i] = i; - + // start computing edit distance for (int32_t j = 1; j <= m; ++j) // iterates through target { int32_t bestPossibleEditDistance = m; wchar_t t_j = target[j - 1]; // jth character of t d[0] = j; - + for (int32_t i = 1; i <= n; ++i) // iterates through text { // minimum of cell to the left+1, to the top+1, diagonally left and up +(0|1) @@ -127,34 +127,34 @@ namespace Lucene d[i] = std::min(std::min(d[i - 1] + 1, p[i] + 1), p[i - 1]); bestPossibleEditDistance = std::min(bestPossibleEditDistance, d[i]); } - - // After calculating row i, the best possible edit distance can be found by found by finding the smallest + + // After calculating row i, the best possible edit distance can be found by found by finding the smallest // value in a given column. If the bestPossibleEditDistance is greater than the max distance, abort. - + if (j > maxDistance && bestPossibleEditDistance > maxDistance) // equal is okay, but not greater { // The closest the target can be to the text is just too far away. // This target is leaving the party early. return 0.0; } - + // copy current distance counts to 'previous row' distance counts: swap p and d std::swap(p, d); } - + // Our last action in the above loop was to switch d and p, so p now actually has the most recent cost counts - - // This will return less than 0.0 when the edit distance is greater than the number of characters in the shorter - // word. But this was the formula that was previously used in FuzzyTermEnum, so it has not been changed (even + + // This will return less than 0.0 when the edit distance is greater than the number of characters in the shorter + // word. But this was the formula that was previously used in FuzzyTermEnum, so it has not been changed (even // though minimumSimilarity must be greater than 0.0) return 1.0 - ((double)p[n] / (double)(prefix.length() + std::min(n, m))); } - + int32_t FuzzyTermEnum::calculateMaxDistance(int32_t m) { return (int32_t)((1.0 - minimumSimilarity) * (double)(std::min((int32_t)text.length(), m) + prefix.length())); } - + void FuzzyTermEnum::close() { p.reset(); diff --git a/src/core/search/HitQueue.cpp b/src/core/search/HitQueue.cpp index 5e255674..91ebb3da 100644 --- a/src/core/search/HitQueue.cpp +++ b/src/core/search/HitQueue.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene { this->prePopulate = prePopulate; } - + HitQueue::~HitQueue() { } - + bool HitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { if (first->score == second->score) @@ -26,10 +26,10 @@ namespace Lucene else return (first->score < second->score); } - + ScoreDocPtr HitQueue::getSentinelObject() { - // Always set the doc Id to MAX_VALUE so that it won't be favored by lessThan. This generally should + // Always set the doc Id to MAX_VALUE so that it won't be favored by lessThan. This generally should // not happen since if score is not NEG_INF, TopScoreDocCollector will always add the object to the queue. return !prePopulate ? ScoreDocPtr() : newLucene(INT_MAX, -std::numeric_limits::infinity()); } diff --git a/src/core/search/HitQueueBase.cpp b/src/core/search/HitQueueBase.cpp index 46181df8..f37f3b9f 100644 --- a/src/core/search/HitQueueBase.cpp +++ b/src/core/search/HitQueueBase.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,75 +14,75 @@ namespace Lucene { queueSize = size; } - + HitQueueBase::~HitQueueBase() { } - + void HitQueueBase::initialize() { queue = newLucene(shared_from_this(), queueSize); } - + ScoreDocPtr HitQueueBase::add(ScoreDocPtr scoreDoc) { return queue->add(scoreDoc); } - + ScoreDocPtr HitQueueBase::addOverflow(ScoreDocPtr scoreDoc) { return queue->addOverflow(scoreDoc); } - + ScoreDocPtr HitQueueBase::top() { return queue->top(); } - + ScoreDocPtr HitQueueBase::pop() { return queue->pop(); } - + ScoreDocPtr HitQueueBase::updateTop() { return queue->updateTop(); } - + int32_t HitQueueBase::size() { return queue->size(); } - + bool HitQueueBase::empty() { return queue->empty(); } - + void HitQueueBase::clear() { queue->clear(); } - + ScoreDocPtr HitQueueBase::getSentinelObject() { return ScoreDocPtr(); } - + PriorityQueueScoreDocs::PriorityQueueScoreDocs(HitQueueBasePtr hitQueue, int32_t size) : PriorityQueue(size) { _hitQueue = hitQueue; } - + PriorityQueueScoreDocs::~PriorityQueueScoreDocs() { } - + bool PriorityQueueScoreDocs::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { return HitQueueBasePtr(_hitQueue)->lessThan(first, second); } - + ScoreDocPtr PriorityQueueScoreDocs::getSentinelObject() { return HitQueueBasePtr(_hitQueue)->getSentinelObject(); diff --git a/src/core/search/IndexSearcher.cpp b/src/core/search/IndexSearcher.cpp index b0a49d37..7f85749e 100644 --- a/src/core/search/IndexSearcher.cpp +++ b/src/core/search/IndexSearcher.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,12 +23,12 @@ namespace Lucene { ConstructSearcher(IndexReader::open(path, readOnly), true); } - + IndexSearcher::IndexSearcher(IndexReaderPtr reader) { ConstructSearcher(reader, false); } - + IndexSearcher::IndexSearcher(IndexReaderPtr reader, Collection subReaders, Collection docStarts) { this->fieldSortDoTrackScores = false; @@ -38,18 +38,18 @@ namespace Lucene this->docStarts = docStarts; closeReader = false; } - + IndexSearcher::~IndexSearcher() { } - + void IndexSearcher::ConstructSearcher(IndexReaderPtr reader, bool closeReader) { this->fieldSortDoTrackScores = false; this->fieldSortDoMaxScore = false; this->reader = reader; this->closeReader = closeReader; - + Collection subReadersList(Collection::newInstance()); gatherSubReaders(subReadersList, reader); subReaders = subReadersList; @@ -61,43 +61,43 @@ namespace Lucene maxDoc += subReaders[i]->maxDoc(); } } - + void IndexSearcher::gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader) { ReaderUtil::gatherSubReaders(allSubReaders, reader); } - + IndexReaderPtr IndexSearcher::getIndexReader() { return reader; } - + void IndexSearcher::close() { if (closeReader) reader->close(); } - + int32_t IndexSearcher::docFreq(TermPtr term) { return reader->docFreq(term); } - + DocumentPtr IndexSearcher::doc(int32_t n) { return reader->document(n); } - + DocumentPtr IndexSearcher::doc(int32_t n, FieldSelectorPtr fieldSelector) { return reader->document(n, fieldSelector); } - + int32_t IndexSearcher::maxDoc() { return reader->maxDoc(); } - + TopDocsPtr IndexSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n) { if (n <= 0) @@ -106,19 +106,19 @@ namespace Lucene search(weight, filter, collector); return collector->topDocs(); } - + TopFieldDocsPtr IndexSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) { return search(weight, filter, n, sort, true); } - + TopFieldDocsPtr IndexSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort, bool fillFields) { TopFieldCollectorPtr collector(TopFieldCollector::create(sort, std::min(n, reader->maxDoc()), fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight->scoresDocsOutOfOrder())); search(weight, filter, collector); return boost::dynamic_pointer_cast(collector->topDocs()); } - + void IndexSearcher::search(WeightPtr weight, FilterPtr filter, CollectorPtr results) { if (!filter) @@ -140,35 +140,35 @@ namespace Lucene } } } - + void IndexSearcher::searchWithFilter(IndexReaderPtr reader, WeightPtr weight, FilterPtr filter, CollectorPtr collector) { BOOST_ASSERT(filter); - + ScorerPtr scorer(weight->scorer(reader, true, false)); if (!scorer) return; - + int32_t docID = scorer->docID(); BOOST_ASSERT(docID == -1 || docID == DocIdSetIterator::NO_MORE_DOCS); - + DocIdSetPtr filterDocIdSet(filter->getDocIdSet(reader)); if (!filterDocIdSet) { // this means the filter does not accept any documents. return; } - + DocIdSetIteratorPtr filterIter(filterDocIdSet->iterator()); if (!filterIter) { // this means the filter does not accept any documents. return; } - + int32_t filterDoc = filterIter->nextDoc(); int32_t scorerDoc = scorer->advance(filterDoc); - + collector->setScorer(scorer); while (true) { @@ -187,7 +187,7 @@ namespace Lucene scorerDoc = scorer->advance(filterDoc); } } - + QueryPtr IndexSearcher::rewrite(QueryPtr original) { QueryPtr query(original); @@ -195,14 +195,14 @@ namespace Lucene query = rewrittenQuery; return query; } - + ExplanationPtr IndexSearcher::explain(WeightPtr weight, int32_t doc) { int32_t n = ReaderUtil::subIndex(doc, docStarts); int32_t deBasedDoc = doc - docStarts[n]; return weight->explain(subReaders[n], deBasedDoc); } - + void IndexSearcher::setDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore) { fieldSortDoTrackScores = doTrackScores; diff --git a/src/core/search/MatchAllDocsQuery.cpp b/src/core/search/MatchAllDocsQuery.cpp index 0b5e7e15..b5395e5e 100644 --- a/src/core/search/MatchAllDocsQuery.cpp +++ b/src/core/search/MatchAllDocsQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,37 +20,37 @@ namespace Lucene { this->normsField = normsField; } - + MatchAllDocsQuery::~MatchAllDocsQuery() { } - + WeightPtr MatchAllDocsQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + void MatchAllDocsQuery::extractTerms(SetTerm terms) { } - + String MatchAllDocsQuery::toString(const String& field) { StringStream buffer; buffer << L"*:*" << boostString(); return buffer.str(); } - + bool MatchAllDocsQuery::equals(LuceneObjectPtr other) { return Query::equals(other); } - + int32_t MatchAllDocsQuery::hashCode() { return MiscUtils::doubleToIntBits(getBoost()) ^ 0x1aa71190; } - + LuceneObjectPtr MatchAllDocsQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -58,7 +58,7 @@ namespace Lucene cloneQuery->normsField = normsField; return cloneQuery; } - + MatchAllDocsWeight::MatchAllDocsWeight(MatchAllDocsQueryPtr query, SearcherPtr searcher) { this->query = query; @@ -66,45 +66,45 @@ namespace Lucene this->queryWeight = 0.0; this->queryNorm = 0.0; } - + MatchAllDocsWeight::~MatchAllDocsWeight() { } - + String MatchAllDocsWeight::toString() { StringStream buffer; buffer << L"weight(" << queryWeight << L", " << queryNorm << L")"; return buffer.str(); } - + QueryPtr MatchAllDocsWeight::getQuery() { return query; } - + double MatchAllDocsWeight::getValue() { return queryWeight; } - + double MatchAllDocsWeight::sumOfSquaredWeights() { queryWeight = getQuery()->getBoost(); return queryWeight * queryWeight; } - + void MatchAllDocsWeight::normalize(double norm) { this->queryNorm = norm; queryWeight *= this->queryNorm; } - + ScorerPtr MatchAllDocsWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(query, reader, similarity, shared_from_this(), !query->normsField.empty() ? reader->norms(query->normsField) : ByteArray()); } - + ExplanationPtr MatchAllDocsWeight::explain(IndexReaderPtr reader, int32_t doc) { // explain query weight @@ -114,7 +114,7 @@ namespace Lucene queryExpl->addDetail(newLucene(queryNorm, L"queryNorm")); return queryExpl; } - + MatchAllScorer::MatchAllScorer(MatchAllDocsQueryPtr query, IndexReaderPtr reader, SimilarityPtr similarity, WeightPtr weight, ByteArray norms) : Scorer(similarity) { this->query = query; @@ -123,27 +123,27 @@ namespace Lucene this->norms = norms; this->doc = -1; } - + MatchAllScorer::~MatchAllScorer() { } - + int32_t MatchAllScorer::docID() { return doc; } - + int32_t MatchAllScorer::nextDoc() { doc = termDocs->next() ? termDocs->doc() : NO_MORE_DOCS; return doc; } - + double MatchAllScorer::score() { return norms ? _score * Similarity::decodeNorm(norms[docID()]) : _score; } - + int32_t MatchAllScorer::advance(int32_t target) { doc = termDocs->skipTo(target) ? termDocs->doc() : NO_MORE_DOCS; diff --git a/src/core/search/MultiPhraseQuery.cpp b/src/core/search/MultiPhraseQuery.cpp index 5a04e786..928901a2 100644 --- a/src/core/search/MultiPhraseQuery.cpp +++ b/src/core/search/MultiPhraseQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -28,26 +28,26 @@ namespace Lucene positions = Collection::newInstance(); slop = 0; } - + MultiPhraseQuery::~MultiPhraseQuery() { } - + void MultiPhraseQuery::setSlop(int32_t s) { slop = s; } - + int32_t MultiPhraseQuery::getSlop() { return slop; } - + void MultiPhraseQuery::add(TermPtr term) { add(newCollection(term)); } - + void MultiPhraseQuery::add(Collection terms) { int32_t position = 0; @@ -55,7 +55,7 @@ namespace Lucene position = positions[positions.size() - 1] + 1; add(terms, position); } - + void MultiPhraseQuery::add(Collection terms, int32_t position) { if (termArrays.empty()) @@ -68,17 +68,17 @@ namespace Lucene termArrays.add(terms); positions.add(position); } - + Collection< Collection > MultiPhraseQuery::getTermArrays() { return termArrays; } - + Collection MultiPhraseQuery::getPositions() { return positions; } - + void MultiPhraseQuery::extractTerms(SetTerm terms) { for (Collection< Collection >::iterator arr = termArrays.begin(); arr != termArrays.end(); ++arr) @@ -87,7 +87,7 @@ namespace Lucene terms.add(*term); } } - + QueryPtr MultiPhraseQuery::rewrite(IndexReaderPtr reader) { if (termArrays.size() == 1) // optimize one-term case @@ -102,12 +102,12 @@ namespace Lucene else return shared_from_this(); } - + WeightPtr MultiPhraseQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + String MultiPhraseQuery::toString(const String& field) { StringStream buffer; @@ -133,34 +133,34 @@ namespace Lucene buffer << (*arr)[0]->text(); } buffer << L"\""; - + if (slop != 0) buffer << L"~" << slop; - + buffer << boostString(); - + return buffer.str(); } - + bool MultiPhraseQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + MultiPhraseQueryPtr otherMultiPhraseQuery(boost::dynamic_pointer_cast(other)); if (!otherMultiPhraseQuery) return false; - + return (getBoost() == otherMultiPhraseQuery->getBoost() && slop == otherMultiPhraseQuery->slop && termArraysEquals(termArrays, otherMultiPhraseQuery->termArrays) && positions.equals(otherMultiPhraseQuery->positions)); } - + int32_t MultiPhraseQuery::hashCode() { return MiscUtils::doubleToIntBits(getBoost()) ^ slop ^ termArraysHashCode() ^ MiscUtils::hashCode(positions.begin(), positions.end(), MiscUtils::hashNumeric) ^ 0x4ac65113; } - + int32_t MultiPhraseQuery::termArraysHashCode() { int32_t hashCode = 1; @@ -168,7 +168,7 @@ namespace Lucene hashCode = 31 * hashCode + MiscUtils::hashCode(arr->begin(), arr->end(), MiscUtils::hashLucene); return hashCode; } - + struct equalTermArrays { inline bool operator()(const Collection& first, const Collection& second) const @@ -178,12 +178,12 @@ namespace Lucene return first.equals(second, luceneEquals()); } }; - + bool MultiPhraseQuery::termArraysEquals(Collection< Collection > first, Collection< Collection > second) { return first.equals(second, equalTermArrays()); } - + LuceneObjectPtr MultiPhraseQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -194,7 +194,7 @@ namespace Lucene cloneQuery->slop = slop; return cloneQuery; } - + MultiPhraseWeight::MultiPhraseWeight(MultiPhraseQueryPtr query, SearcherPtr searcher) { this->query = query; @@ -203,7 +203,7 @@ namespace Lucene this->idf = 0.0; this->queryNorm = 0.0; this->queryWeight = 0.0; - + // compute idf int32_t maxDoc = searcher->maxDoc(); for (Collection< Collection >::iterator arr = query->termArrays.begin(); arr != query->termArrays.end(); ++arr) @@ -212,121 +212,121 @@ namespace Lucene idf += this->similarity->idf(searcher->docFreq(*term), maxDoc); } } - + MultiPhraseWeight::~MultiPhraseWeight() { } - + QueryPtr MultiPhraseWeight::getQuery() { return query; } - + double MultiPhraseWeight::getValue() { return value; } - + double MultiPhraseWeight::sumOfSquaredWeights() { queryWeight = idf * getQuery()->getBoost(); // compute query weight return queryWeight * queryWeight; // square it } - + void MultiPhraseWeight::normalize(double norm) { queryNorm = norm; queryWeight *= queryNorm; // normalize query weight - value = queryWeight * idf; // idf for document + value = queryWeight * idf; // idf for document } - + ScorerPtr MultiPhraseWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { if (query->termArrays.empty()) // optimize zero-term case return ScorerPtr(); - + Collection tps(Collection::newInstance(query->termArrays.size())); for (int32_t i = 0; i < tps.size(); ++i) { Collection terms(query->termArrays[i]); - + TermPositionsPtr p; if (terms.size() > 1) p = newLucene(reader, terms); else p = reader->termPositions(terms[0]); - + if (!p) return ScorerPtr(); - + tps[i] = p; } - + if (query->slop == 0) // optimize exact case return newLucene(shared_from_this(), tps, query->getPositions(), similarity, reader->norms(query->field)); else return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); } - + ExplanationPtr MultiPhraseWeight::explain(IndexReaderPtr reader, int32_t doc) { ComplexExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - + ExplanationPtr idfExpl(newLucene(idf, L"idf(" + query->toString() + L")")); - + // explain query weight ExplanationPtr queryExpl(newLucene()); queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); if (query->getBoost() != 1.0) queryExpl->addDetail(boostExpl); - + queryExpl->addDetail(idfExpl); - + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); queryExpl->addDetail(queryNormExpl); - + queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); result->addDetail(queryExpl); - + // explain field weight ComplexExplanationPtr fieldExpl(newLucene()); fieldExpl->setDescription(L"fieldWeight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - + PhraseScorerPtr phraseScorer(boost::dynamic_pointer_cast(scorer(reader, true, false))); if (!phraseScorer) return newLucene(0.0, L"no matching docs"); - + ExplanationPtr tfExplanation(newLucene()); int32_t d = phraseScorer->advance(doc); double phraseFreq = d == doc ? phraseScorer->currentFreq() : 0.0; tfExplanation->setValue(similarity->tf(phraseFreq)); tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); - + fieldExpl->addDetail(tfExplanation); fieldExpl->addDetail(idfExpl); - + ExplanationPtr fieldNormExpl(newLucene()); ByteArray fieldNorms(reader->norms(query->field)); double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; fieldNormExpl->setValue(fieldNorm); fieldNormExpl->setDescription(L"fieldNorm(field=" + query->field + L", doc=" + StringUtils::toString(doc) + L")"); fieldExpl->addDetail(fieldNormExpl); - + fieldExpl->setMatch(tfExplanation->isMatch()); fieldExpl->setValue(tfExplanation->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); - + result->addDetail(fieldExpl); result->setMatch(fieldExpl->getMatch()); - + // combine them result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - + if (queryExpl->getValue() == 1.0) return fieldExpl; - + return result; } } diff --git a/src/core/search/MultiSearcher.cpp b/src/core/search/MultiSearcher.cpp index 6bf1b48a..8c761007 100644 --- a/src/core/search/MultiSearcher.cpp +++ b/src/core/search/MultiSearcher.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,7 +26,7 @@ namespace Lucene { this->searchables = searchables; this->_maxDoc = 0; - + this->starts = Collection::newInstance(searchables.size() + 1); // build starts array for (int32_t i = 0; i < searchables.size(); ++i) { @@ -35,27 +35,27 @@ namespace Lucene } starts[searchables.size()] = _maxDoc; } - + MultiSearcher::~MultiSearcher() { } - + Collection MultiSearcher::getSearchables() { return searchables; } - + Collection MultiSearcher::getStarts() { return starts; } - + void MultiSearcher::close() { for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) (*searchable)->close(); } - + int32_t MultiSearcher::docFreq(TermPtr term) { int32_t docFreq = 0; @@ -63,75 +63,75 @@ namespace Lucene docFreq += (*searchable)->docFreq(term); return docFreq; } - + DocumentPtr MultiSearcher::doc(int32_t n) { int32_t i = subSearcher(n); // find searcher index return searchables[i]->doc(n - starts[i]); // dispatch to searcher } - + DocumentPtr MultiSearcher::doc(int32_t n, FieldSelectorPtr fieldSelector) { int32_t i = subSearcher(n); // find searcher index return searchables[i]->doc(n - starts[i], fieldSelector); // dispatch to searcher } - + int32_t MultiSearcher::subSearcher(int32_t n) { return ReaderUtil::subIndex(n, starts); } - + int32_t MultiSearcher::subDoc(int32_t n) { return n - starts[subSearcher(n)]; } - + int32_t MultiSearcher::maxDoc() { return _maxDoc; } - + TopDocsPtr MultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n) { HitQueuePtr hq(newLucene(n, false)); int32_t totalHits = 0; - + for (int32_t i = 0; i < searchables.size(); ++i) // search each searcher { TopDocsPtr docs(newLucene(SynchronizePtr(), searchables[i], weight, filter, n, hq, i, starts)->call()); totalHits += docs->totalHits; // update totalHits } - + Collection scoreDocs(Collection::newInstance(hq->size())); for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array scoreDocs[i] = hq->pop(); - + double maxScore = totalHits == 0 ? -std::numeric_limits::infinity() : scoreDocs[0]->score; - + return newLucene(totalHits, scoreDocs, maxScore); } - + TopFieldDocsPtr MultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) { FieldDocSortedHitQueuePtr hq(newLucene(n)); int32_t totalHits = 0; - + double maxScore = -std::numeric_limits::infinity(); - + for (int32_t i = 0; i < searchables.size(); ++i) // search each searcher { TopFieldDocsPtr docs(newLucene(SynchronizePtr(), searchables[i], weight, filter, n, hq, sort, i, starts)->call()); totalHits += docs->totalHits; // update totalHits maxScore = std::max(maxScore, docs->maxScore); } - + Collection scoreDocs(Collection::newInstance(hq->size())); for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array scoreDocs[i] = hq->pop(); - + return newLucene(totalHits, scoreDocs, hq->getFields(), maxScore); } - + void MultiSearcher::search(WeightPtr weight, FilterPtr filter, CollectorPtr results) { for (int32_t i = 0; i < searchables.size(); ++i) @@ -141,7 +141,7 @@ namespace Lucene searchables[i]->search(weight, filter, hc); } } - + QueryPtr MultiSearcher::rewrite(QueryPtr query) { Collection queries(Collection::newInstance(searchables.size())); @@ -149,22 +149,22 @@ namespace Lucene queries[i] = searchables[i]->rewrite(query); return queries[0]->combine(queries); } - + ExplanationPtr MultiSearcher::explain(WeightPtr weight, int32_t doc) { int32_t i = subSearcher(doc); // find searcher index return searchables[i]->explain(weight, doc - starts[i]); // dispatch to searcher } - + WeightPtr MultiSearcher::createWeight(QueryPtr query) { // step 1 QueryPtr rewrittenQuery(rewrite(query)); - + // step 2 SetTerm terms(SetTerm::newInstance()); rewrittenQuery->extractTerms(terms); - + // step3 Collection allTermsArray(Collection::newInstance(terms.begin(), terms.end())); Collection aggregatedDfs(Collection::newInstance(terms.size())); @@ -174,29 +174,29 @@ namespace Lucene for (int32_t j = 0; j < aggregatedDfs.size(); ++j) aggregatedDfs[j] += dfs[j]; } - + MapTermInt dfMap(MapTermInt::newInstance()); for (int32_t i = 0; i < allTermsArray.size(); ++i) dfMap.put(allTermsArray[i], aggregatedDfs[i]); - + // step4 int32_t numDocs = maxDoc(); CachedDfSourcePtr cacheSim(newLucene(dfMap, numDocs, getSimilarity())); - + return rewrittenQuery->weight(cacheSim); } - + CachedDfSource::CachedDfSource(MapTermInt dfMap, int32_t maxDoc, SimilarityPtr similarity) { this->dfMap = dfMap; this->_maxDoc = maxDoc; setSimilarity(similarity); } - + CachedDfSource::~CachedDfSource() { } - + int32_t CachedDfSource::docFreq(TermPtr term) { MapTermInt::iterator df = dfMap.find(term); @@ -204,7 +204,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"df for term " + term->text() + L" not available")); return df->second; } - + Collection CachedDfSource::docFreqs(Collection terms) { Collection result(Collection::newInstance(terms.size())); @@ -212,61 +212,61 @@ namespace Lucene result[i] = docFreq(terms[i]); return result; } - + int32_t CachedDfSource::maxDoc() { return _maxDoc; } - + QueryPtr CachedDfSource::rewrite(QueryPtr query) { // This is a bit of a hack. We know that a query which creates a Weight based on this Dummy-Searcher is // always already rewritten (see preparedWeight()). Therefore we just return the unmodified query here. return query; } - + void CachedDfSource::close() { boost::throw_exception(UnsupportedOperationException()); } - + DocumentPtr CachedDfSource::doc(int32_t n) { boost::throw_exception(UnsupportedOperationException()); return DocumentPtr(); } - + DocumentPtr CachedDfSource::doc(int32_t n, FieldSelectorPtr fieldSelector) { boost::throw_exception(UnsupportedOperationException()); return DocumentPtr(); } - + ExplanationPtr CachedDfSource::explain(WeightPtr weight, int32_t doc) { boost::throw_exception(UnsupportedOperationException()); return ExplanationPtr(); } - + void CachedDfSource::search(WeightPtr weight, FilterPtr filter, CollectorPtr results) { boost::throw_exception(UnsupportedOperationException()); } - + TopDocsPtr CachedDfSource::search(WeightPtr weight, FilterPtr filter, int32_t n) { boost::throw_exception(UnsupportedOperationException()); return TopDocsPtr(); } - + TopFieldDocsPtr CachedDfSource::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) { boost::throw_exception(UnsupportedOperationException()); return TopFieldDocsPtr(); } - - MultiSearcherCallableNoSort::MultiSearcherCallableNoSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, - FilterPtr filter, int32_t nDocs, HitQueuePtr hq, int32_t i, + + MultiSearcherCallableNoSort::MultiSearcherCallableNoSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, + FilterPtr filter, int32_t nDocs, HitQueuePtr hq, int32_t i, Collection starts) { this->lock = lock; @@ -278,11 +278,11 @@ namespace Lucene this->i = i; this->starts = starts; } - + MultiSearcherCallableNoSort::~MultiSearcherCallableNoSort() { } - + TopDocsPtr MultiSearcherCallableNoSort::call() { TopDocsPtr docs(searchable->search(weight, filter, nDocs)); @@ -290,17 +290,17 @@ namespace Lucene for (int32_t j = 0; j < scoreDocs.size(); ++j) // merge scoreDocs into hq { ScoreDocPtr scoreDoc(scoreDocs[j]); - scoreDoc->doc += starts[i]; // convert doc - + scoreDoc->doc += starts[i]; // convert doc + SyncLock syncLock(lock); if (scoreDoc == hq->addOverflow(scoreDoc)) break; } return docs; } - - MultiSearcherCallableWithSort::MultiSearcherCallableWithSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, - FilterPtr filter, int32_t nDocs, FieldDocSortedHitQueuePtr hq, + + MultiSearcherCallableWithSort::MultiSearcherCallableWithSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, + FilterPtr filter, int32_t nDocs, FieldDocSortedHitQueuePtr hq, SortPtr sort, int32_t i, Collection starts) { this->lock = lock; @@ -313,15 +313,15 @@ namespace Lucene this->starts = starts; this->sort = sort; } - + MultiSearcherCallableWithSort::~MultiSearcherCallableWithSort() { } - + TopFieldDocsPtr MultiSearcherCallableWithSort::call() { TopFieldDocsPtr docs(searchable->search(weight, filter, nDocs, sort)); - // If one of the Sort fields is FIELD_DOC, need to fix its values, so that it will break ties by doc Id + // If one of the Sort fields is FIELD_DOC, need to fix its values, so that it will break ties by doc Id // properly. Otherwise, it will compare to 'relative' doc Ids, that belong to two different searchables. for (int32_t j = 0; j < docs->fields.size(); ++j) { @@ -336,51 +336,51 @@ namespace Lucene break; } } - + { SyncLock syncLock(lock); hq->setFields(docs->fields); } - + Collection scoreDocs(docs->scoreDocs); for (int32_t j = 0; j < scoreDocs.size(); ++j) // merge scoreDocs into hq { FieldDocPtr fieldDoc(boost::dynamic_pointer_cast(scoreDocs[j])); - fieldDoc->doc += starts[i]; // convert doc - + fieldDoc->doc += starts[i]; // convert doc + SyncLock syncLock(lock); if (fieldDoc == hq->addOverflow(fieldDoc)) break; } - + return docs; } - + MultiSearcherCollector::MultiSearcherCollector(CollectorPtr collector, int32_t start) { this->collector = collector; this->start = start; } - + MultiSearcherCollector::~MultiSearcherCollector() { } - + void MultiSearcherCollector::setScorer(ScorerPtr scorer) { collector->setScorer(scorer); } - + void MultiSearcherCollector::collect(int32_t doc) { collector->collect(doc); } - + void MultiSearcherCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { collector->setNextReader(reader, start + docBase); } - + bool MultiSearcherCollector::acceptsDocsOutOfOrder() { return collector->acceptsDocsOutOfOrder(); diff --git a/src/core/search/MultiTermQuery.cpp b/src/core/search/MultiTermQuery.cpp index 5f350204..ec85a26c 100644 --- a/src/core/search/MultiTermQuery.cpp +++ b/src/core/search/MultiTermQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,11 +25,11 @@ namespace Lucene numberOfTerms = 0; rewriteMethod = CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(); } - + MultiTermQuery::~MultiTermQuery() { } - + RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE() { static RewriteMethodPtr _CONSTANT_SCORE_FILTER_REWRITE; @@ -40,7 +40,7 @@ namespace Lucene } return _CONSTANT_SCORE_FILTER_REWRITE; } - + RewriteMethodPtr MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE() { static RewriteMethodPtr _SCORING_BOOLEAN_QUERY_REWRITE; @@ -51,7 +51,7 @@ namespace Lucene } return _SCORING_BOOLEAN_QUERY_REWRITE; } - + RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE() { static RewriteMethodPtr _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE; @@ -62,7 +62,7 @@ namespace Lucene } return _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE; } - + RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT() { static RewriteMethodPtr _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT; @@ -73,37 +73,37 @@ namespace Lucene } return _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT; } - + int32_t MultiTermQuery::getTotalNumberOfTerms() { return numberOfTerms; } - + void MultiTermQuery::clearTotalNumberOfTerms() { numberOfTerms = 0; } - + void MultiTermQuery::incTotalNumberOfTerms(int32_t inc) { numberOfTerms += inc; } - + QueryPtr MultiTermQuery::rewrite(IndexReaderPtr reader) { return rewriteMethod->rewrite(reader, shared_from_this()); } - + RewriteMethodPtr MultiTermQuery::getRewriteMethod() { return rewriteMethod; } - + void MultiTermQuery::setRewriteMethod(RewriteMethodPtr method) { rewriteMethod = method; } - + LuceneObjectPtr MultiTermQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = Query::clone(other); @@ -112,7 +112,7 @@ namespace Lucene cloneQuery->numberOfTerms = numberOfTerms; return cloneQuery; } - + int32_t MultiTermQuery::hashCode() { int32_t prime = 31; @@ -122,7 +122,7 @@ namespace Lucene result += rewriteMethod->hashCode(); return result; } - + bool MultiTermQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -140,26 +140,26 @@ namespace Lucene return false; return true; } - + RewriteMethod::~RewriteMethod() { } - + ConstantScoreFilterRewrite::~ConstantScoreFilterRewrite() { } - + QueryPtr ConstantScoreFilterRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) { QueryPtr result(newLucene(newLucene(query))); result->setBoost(query->getBoost()); return result; } - + ScoringBooleanQueryRewrite::~ScoringBooleanQueryRewrite() { } - + QueryPtr ScoringBooleanQueryRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) { FilteredTermEnumPtr enumerator(query->getEnum(reader)); @@ -190,11 +190,11 @@ namespace Lucene query->incTotalNumberOfTerms(count); return result; } - + ConstantScoreBooleanQueryRewrite::~ConstantScoreBooleanQueryRewrite() { } - + QueryPtr ConstantScoreBooleanQueryRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) { // strip the scores off @@ -202,44 +202,44 @@ namespace Lucene result->setBoost(query->getBoost()); return result; } - - // Defaults derived from rough tests with a 20.0 million doc Wikipedia index. With more than 350 terms + + // Defaults derived from rough tests with a 20.0 million doc Wikipedia index. With more than 350 terms // in the query, the filter method is fastest const int32_t ConstantScoreAutoRewrite::DEFAULT_TERM_COUNT_CUTOFF = 350; - + // If the query will hit more than 1 in 1000 of the docs in the index (0.1%), the filter method is fastest const double ConstantScoreAutoRewrite::DEFAULT_DOC_COUNT_PERCENT = 0.1; - + ConstantScoreAutoRewrite::ConstantScoreAutoRewrite() { termCountCutoff = DEFAULT_TERM_COUNT_CUTOFF; docCountPercent = DEFAULT_DOC_COUNT_PERCENT; } - + ConstantScoreAutoRewrite::~ConstantScoreAutoRewrite() { } - + void ConstantScoreAutoRewrite::setTermCountCutoff(int32_t count) { termCountCutoff = count; } - + int32_t ConstantScoreAutoRewrite::getTermCountCutoff() { return termCountCutoff; } - + void ConstantScoreAutoRewrite::setDocCountPercent(double percent) { docCountPercent = percent; } - + double ConstantScoreAutoRewrite::getDocCountPercent() { return docCountPercent; } - + QueryPtr ConstantScoreAutoRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) { // Get the enum and start visiting terms. If we exhaust the enum before hitting either of the @@ -248,7 +248,7 @@ namespace Lucene int32_t docCountCutoff = (int32_t)((docCountPercent / 100.0) * (double)reader->maxDoc()); int32_t termCountLimit = std::min(BooleanQuery::getMaxClauseCount(), termCountCutoff); int32_t docVisitCount = 0; - + FilteredTermEnumPtr enumerator(query->getEnum(reader)); QueryPtr result; LuceneException finally; @@ -264,7 +264,7 @@ namespace Lucene // query/filter will load the TermInfo when it runs, and 2) the terms dict has a cache docVisitCount += reader->docFreq(t); } - + if (pendingTerms.size() >= termCountLimit || docVisitCount >= docCountCutoff) { // Too many terms -- make a filter. @@ -274,7 +274,7 @@ namespace Lucene } else if (!enumerator->next()) { - // Enumeration is done, and we hit a small enough number of terms and docs - + // Enumeration is done, and we hit a small enough number of terms and docs - // just make a BooleanQuery, now BooleanQueryPtr bq(newLucene(true)); for (Collection::iterator term = pendingTerms.begin(); term != pendingTerms.end(); ++ term) @@ -298,13 +298,13 @@ namespace Lucene finally.throwException(); return result; } - + int32_t ConstantScoreAutoRewrite::hashCode() { int32_t prime = 1279; return (int32_t)(prime * termCountCutoff + MiscUtils::doubleToLongBits(docCountPercent)); } - + bool ConstantScoreAutoRewrite::equals(LuceneObjectPtr other) { if (RewriteMethod::equals(other)) @@ -313,29 +313,29 @@ namespace Lucene return false; if (!MiscUtils::equalTypes(shared_from_this(), other)) return false; - + ConstantScoreAutoRewritePtr otherConstantScoreAutoRewrite(boost::dynamic_pointer_cast(other)); if (!otherConstantScoreAutoRewrite) return false; - + if (termCountCutoff != otherConstantScoreAutoRewrite->termCountCutoff) return false; - + if (MiscUtils::doubleToLongBits(docCountPercent) != MiscUtils::doubleToLongBits(otherConstantScoreAutoRewrite->docCountPercent)) return false; - + return true; } - + ConstantScoreAutoRewriteDefault::~ConstantScoreAutoRewriteDefault() { } - + void ConstantScoreAutoRewriteDefault::setTermCountCutoff(int32_t count) { boost::throw_exception(UnsupportedOperationException(L"Please create a private instance")); } - + void ConstantScoreAutoRewriteDefault::setDocCountPercent(double percent) { boost::throw_exception(UnsupportedOperationException(L"Please create a private instance")); diff --git a/src/core/search/MultiTermQueryWrapperFilter.cpp b/src/core/search/MultiTermQueryWrapperFilter.cpp index 261640b3..72f11733 100644 --- a/src/core/search/MultiTermQueryWrapperFilter.cpp +++ b/src/core/search/MultiTermQueryWrapperFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,17 +22,17 @@ namespace Lucene { this->query = query; } - + MultiTermQueryWrapperFilter::~MultiTermQueryWrapperFilter() { } - + String MultiTermQueryWrapperFilter::toString() { // query->toString should be ok for the filter, too, if the query boost is 1.0 return query->toString(); } - + bool MultiTermQueryWrapperFilter::equals(LuceneObjectPtr other) { if (Filter::equals(other)) @@ -46,22 +46,22 @@ namespace Lucene return query->equals(otherMultiTermQueryWrapperFilter->query); return false; } - + int32_t MultiTermQueryWrapperFilter::hashCode() { return query->hashCode(); } - + int32_t MultiTermQueryWrapperFilter::getTotalNumberOfTerms() { return query->getTotalNumberOfTerms(); } - + void MultiTermQueryWrapperFilter::clearTotalNumberOfTerms() { query->clearTotalNumberOfTerms(); } - + DocIdSetPtr MultiTermQueryWrapperFilter::getDocIdSet(IndexReaderPtr reader) { TermEnumPtr enumerator(query->getEnum(reader)); @@ -100,7 +100,7 @@ namespace Lucene } } while (enumerator->next()); - + query->incTotalNumberOfTerms(termCount); } catch (LuceneException& e) diff --git a/src/core/search/NumericRangeFilter.cpp b/src/core/search/NumericRangeFilter.cpp index 7fef003d..267ebd31 100644 --- a/src/core/search/NumericRangeFilter.cpp +++ b/src/core/search/NumericRangeFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,71 +13,71 @@ namespace Lucene NumericRangeFilter::NumericRangeFilter(NumericRangeQueryPtr query) : MultiTermQueryWrapperFilter(query) { } - + NumericRangeFilter::~NumericRangeFilter() { } - + NumericRangeFilterPtr NumericRangeFilter::newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); } - + NumericRangeFilterPtr NumericRangeFilter::newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, min, max, minInclusive, maxInclusive); } - + NumericRangeFilterPtr NumericRangeFilter::newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); } - + NumericRangeFilterPtr NumericRangeFilter::newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, min, max, minInclusive, maxInclusive); } - + NumericRangeFilterPtr NumericRangeFilter::newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); } - + NumericRangeFilterPtr NumericRangeFilter::newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, min, max, minInclusive, maxInclusive); } - + NumericRangeFilterPtr NumericRangeFilter::newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { return newLucene(NumericRangeQuery::newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive)); } - + NumericRangeFilterPtr NumericRangeFilter::newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { return newLucene(NumericRangeQuery::newNumericRange(field, min, max, minInclusive, maxInclusive)); } - + String NumericRangeFilter::getField() { return boost::static_pointer_cast(query)->field; } - + bool NumericRangeFilter::includesMin() { return boost::static_pointer_cast(query)->minInclusive; } - + bool NumericRangeFilter::includesMax() { return boost::static_pointer_cast(query)->maxInclusive; } - + NumericValue NumericRangeFilter::getMin() { return boost::static_pointer_cast(query)->min; } - + NumericValue NumericRangeFilter::getMax() { return boost::static_pointer_cast(query)->min; diff --git a/src/core/search/NumericRangeQuery.cpp b/src/core/search/NumericRangeQuery.cpp index 1326a6c5..35bae0c9 100644 --- a/src/core/search/NumericRangeQuery.cpp +++ b/src/core/search/NumericRangeQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -27,8 +27,8 @@ namespace Lucene this->max = max; this->minInclusive = minInclusive; this->maxInclusive = maxInclusive; - - // For bigger precisionSteps this query likely hits too many terms, so set to CONSTANT_SCORE_FILTER + + // For bigger precisionSteps this query likely hits too many terms, so set to CONSTANT_SCORE_FILTER // right off (especially as the FilteredTermEnum is costly if wasted only for AUTO tests because it // creates new enums from IndexReader for each sub-range) switch (valSize) @@ -43,46 +43,46 @@ namespace Lucene // should never happen boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); } - + // shortcut if upper bound == lower bound if (!VariantUtils::isNull(min) && min == max) setRewriteMethod(CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); } - + NumericRangeQuery::~NumericRangeQuery() { } - + NumericRangeQueryPtr NumericRangeQuery::newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); } - + NumericRangeQueryPtr NumericRangeQuery::newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, min, max, minInclusive, maxInclusive); } - + NumericRangeQueryPtr NumericRangeQuery::newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); } - + NumericRangeQueryPtr NumericRangeQuery::newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, min, max, minInclusive, maxInclusive); } - + NumericRangeQueryPtr NumericRangeQuery::newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); } - + NumericRangeQueryPtr NumericRangeQuery::newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, min, max, minInclusive, maxInclusive); } - + NumericRangeQueryPtr NumericRangeQuery::newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { if (!VariantUtils::equalsType(min, max)) @@ -90,42 +90,42 @@ namespace Lucene int32_t valSize = VariantUtils::typeOf(min) ? 32 : 64; return newLucene(field, precisionStep, valSize, min, max, minInclusive, maxInclusive); } - + NumericRangeQueryPtr NumericRangeQuery::newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { return newNumericRange(field, NumericUtils::PRECISION_STEP_DEFAULT, min, max, minInclusive, maxInclusive); } - + FilteredTermEnumPtr NumericRangeQuery::getEnum(IndexReaderPtr reader) { return newLucene(shared_from_this(), reader); } - + String NumericRangeQuery::getField() { return field; } - + bool NumericRangeQuery::includesMin() { return minInclusive; } - + bool NumericRangeQuery::includesMax() { return maxInclusive; } - + NumericValue NumericRangeQuery::getMin() { return min; } - + NumericValue NumericRangeQuery::getMax() { return min; } - + LuceneObjectPtr NumericRangeQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, precisionStep, valSize, min, max, minInclusive, maxInclusive)); @@ -139,7 +139,7 @@ namespace Lucene cloneQuery->maxInclusive = maxInclusive; return cloneQuery; } - + String NumericRangeQuery::toString(const String& field) { StringStream buffer; @@ -159,26 +159,26 @@ namespace Lucene buffer << boostString(); return buffer.str(); } - + bool NumericRangeQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; if (!MultiTermQuery::equals(other)) return false; - + NumericRangeQueryPtr otherNumericRangeQuery(boost::dynamic_pointer_cast(other)); if (!otherNumericRangeQuery) return false; - - return (field == otherNumericRangeQuery->field && + + return (field == otherNumericRangeQuery->field && min == otherNumericRangeQuery->min && max == otherNumericRangeQuery->max && minInclusive == otherNumericRangeQuery->minInclusive && maxInclusive == otherNumericRangeQuery->maxInclusive && precisionStep == otherNumericRangeQuery->precisionStep); } - + int32_t NumericRangeQuery::hashCode() { int32_t hash = MultiTermQuery::hashCode(); @@ -189,14 +189,14 @@ namespace Lucene hash += VariantUtils::hashCode(max) ^ 0x733fa5fe; return hash + (MiscUtils::hashCode(minInclusive) ^ 0x14fa55fb) + (MiscUtils::hashCode(maxInclusive) ^ 0x733fa5fe); } - + NumericRangeTermEnum::NumericRangeTermEnum(NumericRangeQueryPtr query, IndexReaderPtr reader) { this->_query = query; this->reader = reader; this->rangeBounds = Collection::newInstance(); this->termTemplate = newLucene(query->field); - + switch (query->valSize) { case 64: @@ -213,7 +213,7 @@ namespace Lucene break; ++minBound; } - + // upper int64_t maxBound = std::numeric_limits::max(); if (VariantUtils::typeOf(query->max)) @@ -226,12 +226,12 @@ namespace Lucene break; --maxBound; } - + NumericUtils::splitLongRange(newLucene(rangeBounds), query->precisionStep, minBound, maxBound); - + break; } - + case 32: { // lower @@ -244,7 +244,7 @@ namespace Lucene break; ++minBound; } - + // upper int32_t maxBound = INT_MAX; if (VariantUtils::typeOf(query->max)) @@ -255,49 +255,49 @@ namespace Lucene break; --maxBound; } - + NumericUtils::splitIntRange(newLucene(rangeBounds), query->precisionStep, minBound, maxBound); - + break; } - + default: // should never happen boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); } - + // seek to first term next(); } - + NumericRangeTermEnum::~NumericRangeTermEnum() { } - + double NumericRangeTermEnum::difference() { return 1.0; } - + bool NumericRangeTermEnum::endEnum() { boost::throw_exception(UnsupportedOperationException(L"not implemented")); return false; } - + void NumericRangeTermEnum::setEnum(TermEnumPtr actualEnum) { boost::throw_exception(UnsupportedOperationException(L"not implemented")); } - + bool NumericRangeTermEnum::termCompare(TermPtr term) { return (term->field() == NumericRangeQueryPtr(_query)->field && term->text().compare(currentUpperBound) <= 0); } - + bool NumericRangeTermEnum::next() { - // if a current term exists, the actual enum is initialized: try change to next term, if no + // if a current term exists, the actual enum is initialized: try change to next term, if no // such term exists, fall-through if (currentTerm) { @@ -309,7 +309,7 @@ namespace Lucene return true; } } - + // if all above fails, we go forward to the next enum, if one is available currentTerm.reset(); while (rangeBounds.size() >= 2) @@ -331,43 +331,43 @@ namespace Lucene // clear the current term for next iteration currentTerm.reset(); } - + // no more sub-range enums available BOOST_ASSERT(rangeBounds.empty() && !currentTerm); return false; } - + void NumericRangeTermEnum::close() { rangeBounds.clear(); currentUpperBound.clear(); FilteredTermEnum::close(); } - + NumericLongRangeBuilder::NumericLongRangeBuilder(Collection rangeBounds) { this->rangeBounds = rangeBounds; } - + NumericLongRangeBuilder::~NumericLongRangeBuilder() { } - + void NumericLongRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { rangeBounds.add(minPrefixCoded); rangeBounds.add(maxPrefixCoded); } - + NumericIntRangeBuilder::NumericIntRangeBuilder(Collection rangeBounds) { this->rangeBounds = rangeBounds; } - + NumericIntRangeBuilder::~NumericIntRangeBuilder() { } - + void NumericIntRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { rangeBounds.add(minPrefixCoded); diff --git a/src/core/search/ParallelMultiSearcher.cpp b/src/core/search/ParallelMultiSearcher.cpp index 7c1722a9..61f5d85e 100644 --- a/src/core/search/ParallelMultiSearcher.cpp +++ b/src/core/search/ParallelMultiSearcher.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,11 +20,11 @@ namespace Lucene ParallelMultiSearcher::ParallelMultiSearcher(Collection searchables) : MultiSearcher(searchables) { } - + ParallelMultiSearcher::~ParallelMultiSearcher() { } - + int32_t ParallelMultiSearcher::docFreq(TermPtr term) { ThreadPoolPtr threadPool(ThreadPool::getInstance()); @@ -36,7 +36,7 @@ namespace Lucene docFreq += searchThreads[i]->get(); return docFreq; } - + TopDocsPtr ParallelMultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n) { HitQueuePtr hq(newLucene(n, false)); @@ -49,24 +49,24 @@ namespace Lucene multiSearcher[i] = newLucene(lock, searchables[i], weight, filter, n, hq, i, starts); searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&MultiSearcherCallableNoSort::call), multiSearcher[i]))); } - + int32_t totalHits = 0; double maxScore = -std::numeric_limits::infinity(); - + for (int32_t i = 0; i < searchThreads.size(); ++i) { TopDocsPtr topDocs(searchThreads[i]->get()); totalHits += topDocs->totalHits; maxScore = std::max(maxScore, topDocs->maxScore); } - + Collection scoreDocs(Collection::newInstance(hq->size())); for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array scoreDocs[i] = hq->pop(); - + return newLucene(totalHits, scoreDocs, maxScore); } - + TopFieldDocsPtr ParallelMultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) { if (!sort) @@ -81,21 +81,21 @@ namespace Lucene multiSearcher[i] = newLucene(lock, searchables[i], weight, filter, n, hq, sort, i, starts); searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&MultiSearcherCallableWithSort::call), multiSearcher[i]))); } - + int32_t totalHits = 0; double maxScore = -std::numeric_limits::infinity(); - + for (int32_t i = 0; i < searchThreads.size(); ++i) { TopFieldDocsPtr topDocs(searchThreads[i]->get()); totalHits += topDocs->totalHits; maxScore = std::max(maxScore, topDocs->maxScore); } - + Collection scoreDocs(Collection::newInstance(hq->size())); for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array scoreDocs[i] = hq->pop(); - + return newLucene(totalHits, scoreDocs, hq->getFields(), maxScore); } } diff --git a/src/core/search/PhrasePositions.cpp b/src/core/search/PhrasePositions.cpp index 002976fa..56e72a35 100644 --- a/src/core/search/PhrasePositions.cpp +++ b/src/core/search/PhrasePositions.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,15 +16,15 @@ namespace Lucene position = 0; count = 0; repeats = false; - + tp = t; offset = o; } - + PhrasePositions::~PhrasePositions() { } - + bool PhrasePositions::next() { if (!tp->next()) @@ -37,7 +37,7 @@ namespace Lucene position = 0; return true; } - + bool PhrasePositions::skipTo(int32_t target) { if (!tp->skipTo(target)) @@ -50,13 +50,13 @@ namespace Lucene position = 0; return true; } - + void PhrasePositions::firstPosition() { count = tp->freq(); // read first pos nextPosition(); } - + bool PhrasePositions::nextPosition() { if (count-- > 0) // read subsequent pos's diff --git a/src/core/search/PhraseQuery.cpp b/src/core/search/PhraseQuery.cpp index ba7e49d2..9f163010 100644 --- a/src/core/search/PhraseQuery.cpp +++ b/src/core/search/PhraseQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -27,21 +27,21 @@ namespace Lucene maxPosition = 0; slop = 0; } - + PhraseQuery::~PhraseQuery() { } - + void PhraseQuery::setSlop(int32_t slop) { this->slop = slop; } - + int32_t PhraseQuery::getSlop() { return slop; } - + void PhraseQuery::add(TermPtr term) { int32_t position = 0; @@ -49,30 +49,30 @@ namespace Lucene position = positions[positions.size() - 1] + 1; add(term, position); } - + void PhraseQuery::add(TermPtr term, int32_t position) { if (terms.empty()) field = term->field(); else if (term->field() != field) boost::throw_exception(IllegalArgumentException(L"All phrase terms must be in the same field: " + term->toString())); - + terms.add(term); positions.add(position); if (position > maxPosition) maxPosition = position; } - + Collection PhraseQuery::getTerms() { return terms; } - + Collection PhraseQuery::getPositions() { return positions; } - + WeightPtr PhraseQuery::createWeight(SearcherPtr searcher) { if (terms.size() == 1) // optimize one-term case @@ -83,12 +83,12 @@ namespace Lucene } return newLucene(shared_from_this(), searcher); } - + void PhraseQuery::extractTerms(SetTerm terms) { terms.addAll(this->terms.begin(), this->terms.end()); } - + String PhraseQuery::toString(const String& field) { StringStream buffer; @@ -113,35 +113,35 @@ namespace Lucene buffer << (s.empty() ? L"?" : s); } buffer << L"\""; - + if (slop != 0) buffer << L"~" << slop; - + buffer << boostString(); - + return buffer.str(); } - + bool PhraseQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + PhraseQueryPtr otherPhraseQuery(boost::dynamic_pointer_cast(other)); if (!otherPhraseQuery) return false; - + return (getBoost() == otherPhraseQuery->getBoost() && slop == otherPhraseQuery->slop && terms.equals(otherPhraseQuery->terms, luceneEquals()) && positions.equals(otherPhraseQuery->positions)); } - + int32_t PhraseQuery::hashCode() { - return MiscUtils::doubleToIntBits(getBoost()) ^ slop ^ - MiscUtils::hashCode(terms.begin(), terms.end(), MiscUtils::hashLucene) ^ + return MiscUtils::doubleToIntBits(getBoost()) ^ slop ^ + MiscUtils::hashCode(terms.begin(), terms.end(), MiscUtils::hashLucene) ^ MiscUtils::hashCode(positions.begin(), positions.end(), MiscUtils::hashNumeric); } - + LuceneObjectPtr PhraseQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -153,7 +153,7 @@ namespace Lucene cloneQuery->slop = slop; return cloneQuery; } - + PhraseWeight::PhraseWeight(PhraseQueryPtr query, SearcherPtr searcher) { this->query = query; @@ -162,48 +162,48 @@ namespace Lucene this->idf = 0.0; this->queryNorm = 0.0; this->queryWeight = 0.0; - + this->idfExp = similarity->idfExplain(query->terms, searcher); idf = idfExp->getIdf(); } - + PhraseWeight::~PhraseWeight() { } - + String PhraseWeight::toString() { return L"weight(" + query->toString() + L")"; } - + QueryPtr PhraseWeight::getQuery() { return query; } - + double PhraseWeight::getValue() { return value; } - + double PhraseWeight::sumOfSquaredWeights() { queryWeight = idf * getQuery()->getBoost(); // compute query weight return queryWeight * queryWeight; // square it } - + void PhraseWeight::normalize(double norm) { queryNorm = norm; queryWeight *= queryNorm; // normalize query weight - value = queryWeight * idf; // idf for document + value = queryWeight * idf; // idf for document } - + ScorerPtr PhraseWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { if (query->terms.empty()) // optimize zero-term case return ScorerPtr(); - + Collection tps(Collection::newInstance(query->terms.size())); for (int32_t i = 0; i < tps.size(); ++i) { @@ -212,18 +212,18 @@ namespace Lucene return ScorerPtr(); tps[i] = p; } - + if (query->slop == 0) // optimize exact case return newLucene(shared_from_this(), tps, query->getPositions(), similarity, reader->norms(query->field)); else return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); } - + ExplanationPtr PhraseWeight::explain(IndexReaderPtr reader, int32_t doc) { ExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - + StringStream docFreqsBuffer; StringStream queryBuffer; queryBuffer << L"\""; @@ -235,58 +235,58 @@ namespace Lucene queryBuffer << (*term)->text(); } queryBuffer << L"\""; - + ExplanationPtr idfExpl(newLucene(idf, L"idf(" + query->field + L":" + docFreqsBuffer.str() + L")")); - + // explain query weight ExplanationPtr queryExpl(newLucene()); queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); if (query->getBoost() != 1.0) queryExpl->addDetail(boostExpl); queryExpl->addDetail(idfExpl); - + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); queryExpl->addDetail(queryNormExpl); - + queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); result->addDetail(queryExpl); - + // explain field weight ExplanationPtr fieldExpl(newLucene()); fieldExpl->setDescription(L"fieldWeight(" + query->field + L":" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - + PhraseScorerPtr phraseScorer(boost::dynamic_pointer_cast(scorer(reader, true, false))); if (!phraseScorer) return newLucene(0.0, L"no matching docs"); - + ExplanationPtr tfExplanation(newLucene()); int32_t d = phraseScorer->advance(doc); double phraseFreq = d == doc ? phraseScorer->currentFreq() : 0.0; tfExplanation->setValue(similarity->tf(phraseFreq)); tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); - + fieldExpl->addDetail(tfExplanation); fieldExpl->addDetail(idfExpl); - + ExplanationPtr fieldNormExpl(newLucene()); ByteArray fieldNorms(reader->norms(query->field)); double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; fieldNormExpl->setValue(fieldNorm); fieldNormExpl->setDescription(L"fieldNorm(field=" + query->field + L", doc=" + StringUtils::toString(doc) + L")"); fieldExpl->addDetail(fieldNormExpl); - + fieldExpl->setValue(tfExplanation->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); - + result->addDetail(fieldExpl); - + // combine them result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - + if (queryExpl->getValue() == 1.0) return fieldExpl; - + return result; } } diff --git a/src/core/search/PhraseQueue.cpp b/src/core/search/PhraseQueue.cpp index c74e5e79..c13079a2 100644 --- a/src/core/search/PhraseQueue.cpp +++ b/src/core/search/PhraseQueue.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,19 +13,19 @@ namespace Lucene PhraseQueue::PhraseQueue(int32_t size) : PriorityQueue(size) { } - + PhraseQueue::~PhraseQueue() { } - + bool PhraseQueue::lessThan(const PhrasePositionsPtr& first, const PhrasePositionsPtr& second) { if (first->doc == second->doc) { if (first->position == second->position) { - // same doc and pp.position, so decide by actual term positions. - // rely on: pp.position == tp.position - offset. + // same doc and pp.position, so decide by actual term positions. + // rely on: pp.position == tp.position - offset. return first->offset < second->offset; } else diff --git a/src/core/search/PhraseScorer.cpp b/src/core/search/PhraseScorer.cpp index 78c1f9c6..afbc8638 100644 --- a/src/core/search/PhraseScorer.cpp +++ b/src/core/search/PhraseScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,12 +18,12 @@ namespace Lucene this->firstTime = true; this->more = true; this->freq = 0.0; - + this->norms = norms; this->weight = weight; this->value = weight->getValue(); - - // convert tps to a list of phrase positions. + + // convert tps to a list of phrase positions. // Note: phrase-position differs from term-position in that its position reflects the phrase offset: pp.pos = tp.pos - offset. // This allows to easily identify a matching (exact) phrase when all PhrasePositions have exactly the same position. for (int32_t i = 0; i < tps.size(); ++i) @@ -35,20 +35,20 @@ namespace Lucene first = pp; last = pp; } - + pq = newLucene(tps.size()); // construct empty pq first->doc = -1; } - + PhraseScorer::~PhraseScorer() { } - + int32_t PhraseScorer::docID() { return first->doc; } - + int32_t PhraseScorer::nextDoc() { if (firstTime) @@ -62,7 +62,7 @@ namespace Lucene first->doc = NO_MORE_DOCS; return first->doc; } - + bool PhraseScorer::doNext() { while (more) @@ -72,7 +72,7 @@ namespace Lucene more = first->skipTo(last->doc); // skip first upto last and move it to the end firstToLast(); } - + if (more) { // found a doc with all of the terms @@ -85,13 +85,13 @@ namespace Lucene } return false; // no more matches } - + double PhraseScorer::score() { double raw = getSimilarity()->tf(freq) * value; // raw score return !norms ? raw : raw * Similarity::decodeNorm(norms[first->doc]); // normalize } - + int32_t PhraseScorer::advance(int32_t target) { firstTime = false; @@ -103,12 +103,12 @@ namespace Lucene first->doc = NO_MORE_DOCS; return first->doc; } - + double PhraseScorer::currentFreq() { return freq; } - + void PhraseScorer::init() { for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) @@ -116,7 +116,7 @@ namespace Lucene if (more) sort(); } - + void PhraseScorer::sort() { pq->clear(); @@ -124,7 +124,7 @@ namespace Lucene pq->add(pp); pqToList(); } - + void PhraseScorer::pqToList() { last.reset(); @@ -140,7 +140,7 @@ namespace Lucene pp->_next.reset(); } } - + void PhraseScorer::firstToLast() { last->_next = first; // move first to end of list @@ -148,7 +148,7 @@ namespace Lucene first = first->_next; last->_next.reset(); } - + String PhraseScorer::toString() { return L"scorer(" + weight->toString() + L")"; diff --git a/src/core/search/PositiveScoresOnlyCollector.cpp b/src/core/search/PositiveScoresOnlyCollector.cpp index 0a61e982..d96a6d65 100644 --- a/src/core/search/PositiveScoresOnlyCollector.cpp +++ b/src/core/search/PositiveScoresOnlyCollector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,29 +14,29 @@ namespace Lucene { this->collector = collector; } - + PositiveScoresOnlyCollector::~PositiveScoresOnlyCollector() { } - + void PositiveScoresOnlyCollector::collect(int32_t doc) { if (scorer->score() > 0) collector->collect(doc); } - + void PositiveScoresOnlyCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { collector->setNextReader(reader, docBase); } - + void PositiveScoresOnlyCollector::setScorer(ScorerPtr scorer) { // Set a ScoreCachingWrappingScorer in case the wrapped Collector will call score() also. this->scorer = newLucene(scorer); collector->setScorer(this->scorer); } - + bool PositiveScoresOnlyCollector::acceptsDocsOutOfOrder() { return collector->acceptsDocsOutOfOrder(); diff --git a/src/core/search/PrefixFilter.cpp b/src/core/search/PrefixFilter.cpp index 17f41c97..435f9fda 100644 --- a/src/core/search/PrefixFilter.cpp +++ b/src/core/search/PrefixFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,16 +14,16 @@ namespace Lucene PrefixFilter::PrefixFilter(TermPtr prefix) : MultiTermQueryWrapperFilter(newLucene(prefix)) { } - + PrefixFilter::~PrefixFilter() { } - + TermPtr PrefixFilter::getPrefix() { return boost::static_pointer_cast(query)->getPrefix(); } - + String PrefixFilter::toString() { StringStream buffer; diff --git a/src/core/search/PrefixQuery.cpp b/src/core/search/PrefixQuery.cpp index 226a08f7..ef33a648 100644 --- a/src/core/search/PrefixQuery.cpp +++ b/src/core/search/PrefixQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,21 +16,21 @@ namespace Lucene { this->prefix = prefix; } - + PrefixQuery::~PrefixQuery() { } - + TermPtr PrefixQuery::getPrefix() { return prefix; } - + FilteredTermEnumPtr PrefixQuery::getEnum(IndexReaderPtr reader) { return newLucene(reader, prefix); } - + String PrefixQuery::toString(const String& field) { StringStream buffer; @@ -39,7 +39,7 @@ namespace Lucene buffer << prefix->text() << L"*" << boostString(); return buffer.str(); } - + LuceneObjectPtr PrefixQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(prefix)); @@ -47,7 +47,7 @@ namespace Lucene cloneQuery->prefix = prefix; return cloneQuery; } - + int32_t PrefixQuery::hashCode() { int32_t prime = 31; @@ -55,7 +55,7 @@ namespace Lucene result = prime * result + (prefix ? prefix->hashCode() : 0); return result; } - + bool PrefixQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) diff --git a/src/core/search/PrefixTermEnum.cpp b/src/core/search/PrefixTermEnum.cpp index fbc0458b..ff4e00d9 100644 --- a/src/core/search/PrefixTermEnum.cpp +++ b/src/core/search/PrefixTermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,29 +16,29 @@ namespace Lucene { this->_endEnum = false; this->prefix = prefix; - + setEnum(reader->terms(newLucene(prefix->field(), prefix->text()))); } - + PrefixTermEnum::~PrefixTermEnum() { } - + double PrefixTermEnum::difference() { return 1.0; } - + bool PrefixTermEnum::endEnum() { return _endEnum; } - + TermPtr PrefixTermEnum::getPrefixTerm() { return prefix; } - + bool PrefixTermEnum::termCompare(TermPtr term) { if (term->field() == prefix->field() && boost::starts_with(term->text(), prefix->text())) diff --git a/src/core/search/Query.cpp b/src/core/search/Query.cpp index 0cfc4828..5e52d533 100644 --- a/src/core/search/Query.cpp +++ b/src/core/search/Query.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,37 +17,37 @@ namespace Lucene { boost = 1.0; } - + Query::~Query() { } - + void Query::setBoost(double boost) { this->boost = boost; } - + double Query::getBoost() { return boost; } - + String Query::toString(const String& field) { return L""; // override } - + String Query::toString() { return toString(L""); } - + WeightPtr Query::createWeight(SearcherPtr searcher) { boost::throw_exception(UnsupportedOperationException()); return WeightPtr(); } - + WeightPtr Query::weight(SearcherPtr searcher) { QueryPtr query(searcher->rewrite(shared_from_this())); @@ -59,12 +59,12 @@ namespace Lucene weight->normalize(norm); return weight; } - + QueryPtr Query::rewrite(IndexReaderPtr reader) { return shared_from_this(); } - + QueryPtr Query::combine(Collection queries) { SetQuery uniques(SetQuery::newInstance()); @@ -97,13 +97,13 @@ namespace Lucene result->add(*query, BooleanClause::SHOULD); return result; } - + void Query::extractTerms(SetTerm terms) { // needs to be implemented by query subclasses boost::throw_exception(UnsupportedOperationException()); } - + QueryPtr Query::mergeBooleanQueries(Collection queries) { SetBooleanClause allClauses(SetBooleanClause::newInstance()); @@ -112,19 +112,19 @@ namespace Lucene for (Collection::iterator clause = (*booleanQuery)->begin(); clause != (*booleanQuery)->end(); ++clause) allClauses.add(*clause); } - + bool coordDisabled = queries.empty() ? false : queries[0]->isCoordDisabled(); BooleanQueryPtr result(newLucene(coordDisabled)); for (SetBooleanClause::iterator clause2 = allClauses.begin(); clause2 != allClauses.end(); ++clause2) result->add(*clause2); return result; } - + SimilarityPtr Query::getSimilarity(SearcherPtr searcher) { return searcher->getSimilarity(); } - + LuceneObjectPtr Query::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); @@ -132,7 +132,7 @@ namespace Lucene cloneQuery->boost = boost; return cloneQuery; } - + int32_t Query::hashCode() { int32_t prime = 31; @@ -140,7 +140,7 @@ namespace Lucene result = prime * result + MiscUtils::doubleToIntBits(boost); return result; } - + bool Query::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -154,7 +154,7 @@ namespace Lucene return false; return (boost == otherQuery->boost); } - + String Query::boostString() { double boost = getBoost(); diff --git a/src/core/search/QueryTermVector.cpp b/src/core/search/QueryTermVector.cpp index afa7d3ec..e81d06da 100644 --- a/src/core/search/QueryTermVector.cpp +++ b/src/core/search/QueryTermVector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,7 +19,7 @@ namespace Lucene termFreqs = Collection::newInstance(); processTerms(queryTerms); } - + QueryTermVector::QueryTermVector(const String& queryString, AnalyzerPtr analyzer) { terms = Collection::newInstance(); @@ -33,10 +33,10 @@ namespace Lucene try { bool hasMoreTokens = false; - + stream->reset(); TermAttributePtr termAtt(stream->addAttribute()); - + hasMoreTokens = stream->incrementToken(); while (hasMoreTokens) { @@ -51,18 +51,18 @@ namespace Lucene } } } - + QueryTermVector::~QueryTermVector() { } - + void QueryTermVector::processTerms(Collection queryTerms) { if (queryTerms) { std::sort(queryTerms.begin(), queryTerms.end()); MapStringInt tmpSet(MapStringInt::newInstance()); - + // filter out duplicates Collection tmpList(Collection::newInstance()); Collection tmpFreqs(Collection::newInstance()); @@ -90,7 +90,7 @@ namespace Lucene termFreqs[i++] = *freq; } } - + String QueryTermVector::toString() { StringStream buffer; @@ -104,28 +104,28 @@ namespace Lucene buffer << L"}"; return buffer.str(); } - + int32_t QueryTermVector::size() { return terms.size(); } - + Collection QueryTermVector::getTerms() { return terms; } - + Collection QueryTermVector::getTermFrequencies() { return termFreqs; } - + int32_t QueryTermVector::indexOf(const String& term) { Collection::iterator search = std::lower_bound(terms.begin(), terms.end(), term); return (search == terms.end() || term < *search) ? -1 : std::distance(terms.begin(), search); } - + Collection QueryTermVector::indexesOf(Collection terms, int32_t start, int32_t length) { Collection res(Collection::newInstance(length)); diff --git a/src/core/search/QueryWrapperFilter.cpp b/src/core/search/QueryWrapperFilter.cpp index fb5b7c08..a14e3e49 100644 --- a/src/core/search/QueryWrapperFilter.cpp +++ b/src/core/search/QueryWrapperFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,22 +18,22 @@ namespace Lucene { this->query = query; } - + QueryWrapperFilter::~QueryWrapperFilter() { } - + DocIdSetPtr QueryWrapperFilter::getDocIdSet(IndexReaderPtr reader) { WeightPtr weight(query->weight(newLucene(reader))); return newLucene(reader, weight); } - + String QueryWrapperFilter::toString() { return L"QueryWrapperFilter(" + query->toString() + L")"; } - + bool QueryWrapperFilter::equals(LuceneObjectPtr other) { QueryWrapperFilterPtr otherQueryWrapperFilter(boost::dynamic_pointer_cast(other)); @@ -41,27 +41,27 @@ namespace Lucene return false; return this->query->equals(otherQueryWrapperFilter->query); } - + int32_t QueryWrapperFilter::hashCode() { return query->hashCode() ^ 0x923F64B9; } - + QueryWrapperFilterDocIdSet::QueryWrapperFilterDocIdSet(IndexReaderPtr reader, WeightPtr weight) { this->reader = reader; this->weight = weight; } - + QueryWrapperFilterDocIdSet::~QueryWrapperFilterDocIdSet() { } - + DocIdSetIteratorPtr QueryWrapperFilterDocIdSet::iterator() { return weight->scorer(reader, true, false); } - + bool QueryWrapperFilterDocIdSet::isCacheable() { return false; diff --git a/src/core/search/ReqExclScorer.cpp b/src/core/search/ReqExclScorer.cpp index ee257591..ab9f9fde 100644 --- a/src/core/search/ReqExclScorer.cpp +++ b/src/core/search/ReqExclScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,11 +15,11 @@ namespace Lucene this->exclDisi = exclDisi; this->doc = -1; } - + ReqExclScorer::~ReqExclScorer() { } - + int32_t ReqExclScorer::nextDoc() { if (!reqScorer) @@ -35,7 +35,7 @@ namespace Lucene doc = toNonExcluded(); return doc; } - + int32_t ReqExclScorer::toNonExcluded() { int32_t exclDoc = exclDisi->docID(); @@ -60,17 +60,17 @@ namespace Lucene reqScorer.reset(); // exhausted, nothing left return NO_MORE_DOCS; } - + int32_t ReqExclScorer::docID() { return doc; } - + double ReqExclScorer::score() { return reqScorer->score(); // reqScorer may be null when next() or skipTo() already return false } - + int32_t ReqExclScorer::advance(int32_t target) { if (!reqScorer) diff --git a/src/core/search/ReqOptSumScorer.cpp b/src/core/search/ReqOptSumScorer.cpp index af235b53..5da69480 100644 --- a/src/core/search/ReqOptSumScorer.cpp +++ b/src/core/search/ReqOptSumScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,40 +14,40 @@ namespace Lucene this->reqScorer = reqScorer; this->optScorer = optScorer; } - + ReqOptSumScorer::~ReqOptSumScorer() { } - + int32_t ReqOptSumScorer::nextDoc() { return reqScorer->nextDoc(); } - + int32_t ReqOptSumScorer::advance(int32_t target) { return reqScorer->advance(target); } - + int32_t ReqOptSumScorer::docID() { return reqScorer->docID(); } - + double ReqOptSumScorer::score() { int32_t curDoc = reqScorer->docID(); double reqScore = reqScorer->score(); if (!optScorer) return reqScore; - + int32_t optScorerDoc = optScorer->docID(); if (optScorerDoc < curDoc && (optScorerDoc = optScorer->advance(curDoc)) == NO_MORE_DOCS) { optScorer.reset(); return reqScore; } - + return optScorerDoc == curDoc ? reqScore + optScorer->score() : reqScore; } } diff --git a/src/core/search/ScoreCachingWrappingScorer.cpp b/src/core/search/ScoreCachingWrappingScorer.cpp index 30fa519c..d12ebe73 100644 --- a/src/core/search/ScoreCachingWrappingScorer.cpp +++ b/src/core/search/ScoreCachingWrappingScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,21 +15,21 @@ namespace Lucene this->curScore = 0.0; this->_scorer = scorer; } - + ScoreCachingWrappingScorer::~ScoreCachingWrappingScorer() { } - + bool ScoreCachingWrappingScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) { return ScorerPtr(_scorer)->score(collector, max, firstDocID); } - + SimilarityPtr ScoreCachingWrappingScorer::getSimilarity() { return ScorerPtr(_scorer)->getSimilarity(); } - + double ScoreCachingWrappingScorer::score() { ScorerPtr scorer(_scorer); @@ -41,22 +41,22 @@ namespace Lucene } return curScore; } - + int32_t ScoreCachingWrappingScorer::docID() { return ScorerPtr(_scorer)->docID(); } - + int32_t ScoreCachingWrappingScorer::nextDoc() { return ScorerPtr(_scorer)->nextDoc(); } - + void ScoreCachingWrappingScorer::score(CollectorPtr collector) { ScorerPtr(_scorer)->score(collector); } - + int32_t ScoreCachingWrappingScorer::advance(int32_t target) { return ScorerPtr(_scorer)->advance(target); diff --git a/src/core/search/ScoreDoc.cpp b/src/core/search/ScoreDoc.cpp index 2d1a7d69..c461bd3d 100644 --- a/src/core/search/ScoreDoc.cpp +++ b/src/core/search/ScoreDoc.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene this->doc = doc; this->score = score; } - + ScoreDoc::~ScoreDoc() { } - + String ScoreDoc::toString() { StringStream buffer; diff --git a/src/core/search/Scorer.cpp b/src/core/search/Scorer.cpp index 15f48fd0..0a5ee752 100644 --- a/src/core/search/Scorer.cpp +++ b/src/core/search/Scorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,16 +14,16 @@ namespace Lucene { this->similarity = similarity; } - + Scorer::~Scorer() { } - + SimilarityPtr Scorer::getSimilarity() { return similarity; } - + void Scorer::score(CollectorPtr collector) { collector->setScorer(shared_from_this()); @@ -31,7 +31,7 @@ namespace Lucene while ((doc = nextDoc()) != NO_MORE_DOCS) collector->collect(doc); } - + bool Scorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) { collector->setScorer(shared_from_this()); diff --git a/src/core/search/Searchable.cpp b/src/core/search/Searchable.cpp index 7b636277..331621e2 100644 --- a/src/core/search/Searchable.cpp +++ b/src/core/search/Searchable.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,61 +14,61 @@ namespace Lucene BOOST_ASSERT(false); // override } - + void Searchable::close() { BOOST_ASSERT(false); // override } - + int32_t Searchable::docFreq(TermPtr term) { BOOST_ASSERT(false); return 0; // override } - + Collection Searchable::docFreqs(Collection terms) { BOOST_ASSERT(false); return Collection(); // override } - + int32_t Searchable::maxDoc() { BOOST_ASSERT(false); return 0; // override } - + TopDocsPtr Searchable::search(WeightPtr weight, FilterPtr filter, int32_t n) { BOOST_ASSERT(false); return TopDocsPtr(); // override } - + DocumentPtr Searchable::doc(int32_t n) { BOOST_ASSERT(false); return DocumentPtr(); // override } - + DocumentPtr Searchable::doc(int32_t n, FieldSelectorPtr fieldSelector) { BOOST_ASSERT(false); return DocumentPtr(); // override } - + QueryPtr Searchable::rewrite(QueryPtr query) { BOOST_ASSERT(false); return QueryPtr(); // override } - + ExplanationPtr Searchable::explain(WeightPtr weight, int32_t doc) { BOOST_ASSERT(false); return ExplanationPtr(); // override } - + TopFieldDocsPtr Searchable::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) { BOOST_ASSERT(false); diff --git a/src/core/search/Searcher.cpp b/src/core/search/Searcher.cpp index 684233dd..c5fc4996 100644 --- a/src/core/search/Searcher.cpp +++ b/src/core/search/Searcher.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,56 +16,56 @@ namespace Lucene { similarity = Similarity::getDefault(); } - + Searcher::~Searcher() { } - + TopFieldDocsPtr Searcher::search(QueryPtr query, FilterPtr filter, int32_t n, SortPtr sort) { return search(createWeight(query), filter, n, sort); } - + void Searcher::search(QueryPtr query, CollectorPtr results) { search(createWeight(query), FilterPtr(), results); } - + void Searcher::search(QueryPtr query, FilterPtr filter, CollectorPtr results) { search(createWeight(query), filter, results); } - + TopDocsPtr Searcher::search(QueryPtr query, FilterPtr filter, int32_t n) { return search(createWeight(query), filter, n); } - + TopDocsPtr Searcher::search(QueryPtr query, int32_t n) { return search(query, FilterPtr(), n); } - + ExplanationPtr Searcher::explain(QueryPtr query, int32_t doc) { return explain(createWeight(query), doc); } - + void Searcher::setSimilarity(SimilarityPtr similarity) { this->similarity = similarity; } - + SimilarityPtr Searcher::getSimilarity() { return this->similarity; } - + WeightPtr Searcher::createWeight(QueryPtr query) { return query->weight(shared_from_this()); } - + Collection Searcher::docFreqs(Collection terms) { Collection result(Collection::newInstance(terms.size())); diff --git a/src/core/search/Similarity.cpp b/src/core/search/Similarity.cpp index b53a0a25..4e6f9909 100644 --- a/src/core/search/Similarity.cpp +++ b/src/core/search/Similarity.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,15 +17,15 @@ namespace Lucene { const int32_t Similarity::NO_DOC_ID_PROVIDED = -1; - + Similarity::Similarity() { } - + Similarity::~Similarity() { } - + SimilarityPtr Similarity::getDefault() { static SimilarityPtr defaultImpl; @@ -36,7 +36,7 @@ namespace Lucene } return defaultImpl; } - + const Collection Similarity::NORM_TABLE() { static Collection _NORM_TABLE; @@ -48,32 +48,32 @@ namespace Lucene } return _NORM_TABLE; } - + double Similarity::decodeNorm(uint8_t b) { return NORM_TABLE()[b & 0xff]; // & 0xff maps negative bytes to positive above 127 } - + const Collection Similarity::getNormDecoder() { return NORM_TABLE(); } - + double Similarity::computeNorm(const String& fieldName, FieldInvertStatePtr state) { return (double)(state->getBoost() * lengthNorm(fieldName, state->getLength())); } - + uint8_t Similarity::encodeNorm(double f) { return SmallDouble::doubleToByte(f); } - + double Similarity::tf(int32_t freq) { return tf((double)freq); } - + IDFExplanationPtr Similarity::idfExplain(TermPtr term, SearcherPtr searcher) { int32_t df = searcher->docFreq(term); @@ -81,7 +81,7 @@ namespace Lucene double _idf = idf(df, max); return newLucene(df, max, _idf); } - + IDFExplanationPtr Similarity::idfExplain(Collection terms, SearcherPtr searcher) { int32_t max = searcher->maxDoc(); @@ -95,34 +95,34 @@ namespace Lucene } return newLucene(exp, _idf); } - + double Similarity::scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) { return 1.0; } - + SimilarityIDFExplanation::SimilarityIDFExplanation(int32_t df, int32_t max, double idf) { this->df = df; this->max = max; this->idf = idf; } - + SimilarityIDFExplanation::SimilarityIDFExplanation(const String& exp, double idf) { this->exp = exp; this->idf = idf; } - + SimilarityIDFExplanation::~SimilarityIDFExplanation() { } - + String SimilarityIDFExplanation::explain() { return !exp.empty() ? exp : L"idf(docFreq=" + StringUtils::toString(df) + L", maxDocs=" + StringUtils::toString(max) + L")"; } - + double SimilarityIDFExplanation::getIdf() { return idf; diff --git a/src/core/search/SimilarityDelegator.cpp b/src/core/search/SimilarityDelegator.cpp index 47cfaa23..59f2e0a5 100644 --- a/src/core/search/SimilarityDelegator.cpp +++ b/src/core/search/SimilarityDelegator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,46 +13,46 @@ namespace Lucene { this->delegee = delegee; } - + SimilarityDelegator::~SimilarityDelegator() { } - + double SimilarityDelegator::computeNorm(const String& fieldName, FieldInvertStatePtr state) { return delegee->computeNorm(fieldName, state); } - + double SimilarityDelegator::lengthNorm(const String& fieldName, int32_t numTokens) { return delegee->lengthNorm(fieldName, numTokens); } - + double SimilarityDelegator::queryNorm(double sumOfSquaredWeights) { return delegee->queryNorm(sumOfSquaredWeights); } - + double SimilarityDelegator::tf(double freq) { return delegee->tf(freq); } - + double SimilarityDelegator::sloppyFreq(int32_t distance) { return delegee->sloppyFreq(distance); } - + double SimilarityDelegator::idf(int32_t docFreq, int32_t numDocs) { return delegee->idf(docFreq, numDocs); } - + double SimilarityDelegator::coord(int32_t overlap, int32_t maxOverlap) { return delegee->coord(overlap, maxOverlap); } - + double SimilarityDelegator::scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) { return delegee->scorePayload(docId, fieldName, start, end, payload, offset, length); diff --git a/src/core/search/SingleTermEnum.cpp b/src/core/search/SingleTermEnum.cpp index b81a6e33..d4d5619b 100644 --- a/src/core/search/SingleTermEnum.cpp +++ b/src/core/search/SingleTermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,21 +17,21 @@ namespace Lucene this->singleTerm = singleTerm; setEnum(reader->terms(singleTerm)); } - + SingleTermEnum::~SingleTermEnum() { } - + double SingleTermEnum::difference() { return 1.0; } - + bool SingleTermEnum::endEnum() { return _endEnum; } - + bool SingleTermEnum::termCompare(TermPtr term) { if (term->equals(singleTerm)) diff --git a/src/core/search/SloppyPhraseScorer.cpp b/src/core/search/SloppyPhraseScorer.cpp index 62233e08..ba56a948 100644 --- a/src/core/search/SloppyPhraseScorer.cpp +++ b/src/core/search/SloppyPhraseScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,15 +17,15 @@ namespace Lucene this->slop = slop; this->checkedRepeats = false; } - + SloppyPhraseScorer::~SloppyPhraseScorer() { } - + double SloppyPhraseScorer::phraseFreq() { int32_t end = initPhrasePositions(); - + double freq = 0.0; bool done = (end < 0); while (!done) @@ -33,7 +33,7 @@ namespace Lucene PhrasePositionsPtr pp(pq->pop()); int32_t start = pp->position; int32_t next = pq->top()->position; - + bool tpsDiffer = true; for (int32_t pos = start; pos <= next || !tpsDiffer; pos = pp->position) { @@ -44,25 +44,25 @@ namespace Lucene done = true; // ran out of a term - done break; } - + PhrasePositionsPtr pp2; tpsDiffer = (!pp->repeats || !(pp2 = termPositionsDiffer(pp))); if (pp2 && pp2 != pp) pp = flip(pp, pp2); // flip pp to pp2 } - + int32_t matchLength = end - start; if (matchLength <= slop) freq += getSimilarity()->sloppyFreq(matchLength); // score match - + if (pp->position > end) end = pp->position; pq->add(pp); // restore pq } - + return freq; } - + PhrasePositionsPtr SloppyPhraseScorer::flip(PhrasePositionsPtr pp, PhrasePositionsPtr pp2) { int32_t n = 0; @@ -77,11 +77,11 @@ namespace Lucene pq->add(pp); return pp2; } - + int32_t SloppyPhraseScorer::initPhrasePositions() { int32_t end = 0; - + // no repeats at all (most common case is also the simplest one) if (checkedRepeats && !repeats) { @@ -96,11 +96,11 @@ namespace Lucene } return end; } - + // position the pp's for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) pp->firstPosition(); - + // one time initialization for this scorer if (!checkedRepeats) { @@ -131,7 +131,7 @@ namespace Lucene repeats.add(key->first); } } - + // with repeats must advance some repeating pp's so they all start with differing tp's if (repeats) { @@ -140,12 +140,12 @@ namespace Lucene PhrasePositionsPtr pp2; while (pp2 = termPositionsDiffer(*pp)) { - if (!pp2->nextPosition()) // out of pps that do not differ, advance the pp with higher offset + if (!pp2->nextPosition()) // out of pps that do not differ, advance the pp with higher offset return -1; // ran out of a term - done } } } - + // build queue from list pq->clear(); for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) @@ -154,18 +154,18 @@ namespace Lucene end = pp->position; pq->add(pp); // build pq from list } - + if (repeats) tmpPos = Collection::newInstance(pq->size()); - + return end; } - + PhrasePositionsPtr SloppyPhraseScorer::termPositionsDiffer(PhrasePositionsPtr pp) { - // Efficiency note: a more efficient implementation could keep a map between repeating pp's, so that if - // pp1a, pp1b, pp1c are repeats term1, and pp2a, pp2b are repeats of term2, pp2a would only be checked - // against pp2b but not against pp1a, pp1b, pp1c. However this would complicate code, for a rather rare + // Efficiency note: a more efficient implementation could keep a map between repeating pp's, so that if + // pp1a, pp1b, pp1c are repeats term1, and pp2a, pp2b are repeats of term2, pp2a would only be checked + // against pp2b but not against pp1a, pp1b, pp1c. However this would complicate code, for a rather rare // case, so choice is to compromise here. int32_t tpPos = pp->position + pp->offset; for (Collection::iterator pp2 = repeats.begin(); pp2 != repeats.end(); ++pp2) diff --git a/src/core/search/Sort.cpp b/src/core/search/Sort.cpp index 69f2577d..11cfb7f0 100644 --- a/src/core/search/Sort.cpp +++ b/src/core/search/Sort.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,21 +15,21 @@ namespace Lucene { setSort(SortField::FIELD_SCORE()); } - + Sort::Sort(SortFieldPtr field) { setSort(field); } - + Sort::Sort(Collection fields) { setSort(fields); } - + Sort::~Sort() { } - + SortPtr Sort::RELEVANCE() { static SortPtr _RELEVANCE; @@ -40,7 +40,7 @@ namespace Lucene } return _RELEVANCE; } - + SortPtr Sort::INDEXORDER() { static SortPtr _INDEXORDER; @@ -51,22 +51,22 @@ namespace Lucene } return _INDEXORDER; } - + void Sort::setSort(SortFieldPtr field) { this->fields = newCollection(field); } - + void Sort::setSort(Collection fields) { this->fields = fields; } - + Collection Sort::getSort() { return fields; } - + String Sort::toString() { StringStream buffer; @@ -78,18 +78,18 @@ namespace Lucene } return buffer.str(); } - + bool Sort::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + SortPtr otherSort(boost::dynamic_pointer_cast(other)); if (!otherSort) return false; return fields.equals(otherSort->fields); } - + int32_t Sort::hashCode() { return 0x45aaf665 + MiscUtils::hashCode(fields.begin(), fields.end(), MiscUtils::hashLucene); diff --git a/src/core/search/SortField.cpp b/src/core/search/SortField.cpp index 3ef8ec2d..47e7df1b 100644 --- a/src/core/search/SortField.cpp +++ b/src/core/search/SortField.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -37,7 +37,7 @@ namespace Lucene /// Sort using term values as Shorts. Sort values are Short and lower values are at the front. const int32_t SortField::SHORT = 8; - /// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according + /// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according /// to natural order. const int32_t SortField::CUSTOM = 9; @@ -53,7 +53,7 @@ namespace Lucene initFieldType(field, type); this->reverse = reverse; } - + SortField::SortField(const String& field, ParserPtr parser, bool reverse) { if (boost::dynamic_pointer_cast(parser)) @@ -69,25 +69,25 @@ namespace Lucene this->reverse = reverse; this->parser = parser; } - + SortField::SortField(const String& field, const std::locale& locale, bool reverse) { initFieldType(field, STRING); this->locale = newInstance(locale); this->reverse = reverse; } - + SortField::SortField(const String& field, FieldComparatorSourcePtr comparator, bool reverse) { initFieldType(field, CUSTOM); this->comparatorSource = comparator; this->reverse = reverse; } - + SortField::~SortField() { } - + SortFieldPtr SortField::FIELD_SCORE() { static SortFieldPtr _FIELD_SCORE; @@ -98,7 +98,7 @@ namespace Lucene } return _FIELD_SCORE; } - + SortFieldPtr SortField::FIELD_DOC() { static SortFieldPtr _FIELD_DOC; @@ -109,7 +109,7 @@ namespace Lucene } return _FIELD_DOC; } - + void SortField::initFieldType(const String& field, int32_t type) { this->type = type; @@ -117,37 +117,37 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"Field can only be null when type is SCORE or DOC")); this->field = field; } - + String SortField::getField() { return field; } - + int32_t SortField::getType() { return type; } - + localePtr SortField::getLocale() { return locale; } - + ParserPtr SortField::getParser() { return parser; } - + bool SortField::getReverse() { return reverse; } - + FieldComparatorSourcePtr SortField::getComparatorSource() { return comparatorSource; } - + String SortField::toString() { StringStream buffer; @@ -190,31 +190,31 @@ namespace Lucene buffer << L""; break; } - + if (parser) buffer << L"(" << parser->toString() << L")"; if (reverse) buffer << L"!"; - + return buffer.str(); } - + bool SortField::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + SortFieldPtr otherSortField(boost::dynamic_pointer_cast(other)); if (!otherSortField) return false; - + return (field == otherSortField->field && type == otherSortField->type && - reverse == otherSortField->reverse && + reverse == otherSortField->reverse && ((locale && otherSortField->locale && *locale == *otherSortField->locale) || (!locale && !otherSortField->locale)) && (comparatorSource ? comparatorSource->equals(otherSortField->comparatorSource) : !otherSortField->comparatorSource) && (parser ? parser->equals(otherSortField->parser) : !otherSortField->parser)); } - + int32_t SortField::hashCode() { int32_t hash = type ^ 0x346565dd + (reverse ? 1 : 0) ^ 0xaf5998bb; @@ -227,12 +227,12 @@ namespace Lucene hash += parser->hashCode() ^ 0x3aaf56ff; return hash; } - + FieldComparatorPtr SortField::getComparator(int32_t numHits, int32_t sortPos) { if (locale) return newLucene(numHits, field, *locale); - + switch (type) { case SCORE: diff --git a/src/core/search/SpanFilter.cpp b/src/core/search/SpanFilter.cpp index 72092c3b..61ad52e7 100644 --- a/src/core/search/SpanFilter.cpp +++ b/src/core/search/SpanFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/search/SpanFilterResult.cpp b/src/core/search/SpanFilterResult.cpp index 845d1431..c101b0ee 100644 --- a/src/core/search/SpanFilterResult.cpp +++ b/src/core/search/SpanFilterResult.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,61 +14,61 @@ namespace Lucene this->docIdSet = docIdSet; this->positions = positions; } - + SpanFilterResult::~SpanFilterResult() { } - + Collection SpanFilterResult::getPositions() { return positions; } - + DocIdSetPtr SpanFilterResult::getDocIdSet() { return docIdSet; } - + PositionInfo::PositionInfo(int32_t doc) { this->doc = doc; this->positions = Collection::newInstance(); } - + PositionInfo::~PositionInfo() { } - + void PositionInfo::addPosition(int32_t start, int32_t end) { positions.add(newLucene(start, end)); } - + int32_t PositionInfo::getDoc() { return doc; } - + Collection PositionInfo::getPositions() { return positions; } - + StartEnd::StartEnd(int32_t start, int32_t end) { this->start = start; this->end = end; } - + StartEnd::~StartEnd() { } - + int32_t StartEnd::getEnd() { return end; } - + int32_t StartEnd::getStart() { return start; diff --git a/src/core/search/SpanQueryFilter.cpp b/src/core/search/SpanQueryFilter.cpp index 9a965741..374e7ace 100644 --- a/src/core/search/SpanQueryFilter.cpp +++ b/src/core/search/SpanQueryFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,17 +18,17 @@ namespace Lucene { this->query = query; } - + SpanQueryFilter::~SpanQueryFilter() { } - + DocIdSetPtr SpanQueryFilter::getDocIdSet(IndexReaderPtr reader) { SpanFilterResultPtr result(bitSpans(reader)); return result->getDocIdSet(); } - + SpanFilterResultPtr SpanQueryFilter::bitSpans(IndexReaderPtr reader) { OpenBitSetPtr bits(newLucene(reader->maxDoc())); @@ -50,28 +50,28 @@ namespace Lucene } return newLucene(bits, tmp); } - + SpanQueryPtr SpanQueryFilter::getQuery() { return query; } - + String SpanQueryFilter::toString() { return L"SpanQueryFilter(" + query->toString() + L")"; } - + bool SpanQueryFilter::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + SpanQueryFilterPtr otherSpanQueryFilter(boost::dynamic_pointer_cast(other)); if (!otherSpanQueryFilter) return false; return query->equals(otherSpanQueryFilter->query); } - + int32_t SpanQueryFilter::hashCode() { return query->hashCode() ^ 0x923f64b9; diff --git a/src/core/search/TermQuery.cpp b/src/core/search/TermQuery.cpp index 2c0e1492..bab0d0bc 100644 --- a/src/core/search/TermQuery.cpp +++ b/src/core/search/TermQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,26 +22,26 @@ namespace Lucene { this->term = term; } - + TermQuery::~TermQuery() { } - + TermPtr TermQuery::getTerm() { return term; } - + WeightPtr TermQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + void TermQuery::extractTerms(SetTerm terms) { terms.add(getTerm()); } - + String TermQuery::toString(const String& field) { StringStream buffer; @@ -50,24 +50,24 @@ namespace Lucene buffer << term->text() << boostString(); return buffer.str(); } - + bool TermQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + TermQueryPtr otherTermQuery(boost::dynamic_pointer_cast(other)); if (!otherTermQuery) return false; - + return (getBoost() == otherTermQuery->getBoost() && term->equals(otherTermQuery->term)); } - + int32_t TermQuery::hashCode() { return MiscUtils::doubleToIntBits(getBoost()) ^ term->hashCode(); } - + LuceneObjectPtr TermQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(term); @@ -75,7 +75,7 @@ namespace Lucene cloneQuery->term = term; return cloneQuery; } - + TermWeight::TermWeight(TermQueryPtr query, SearcherPtr searcher) { this->query = query; @@ -84,76 +84,76 @@ namespace Lucene this->idf = 0.0; this->queryNorm = 0.0; this->queryWeight = 0.0; - + this->idfExp = similarity->idfExplain(query->term, searcher); idf = idfExp->getIdf(); } - + TermWeight::~TermWeight() { } - + String TermWeight::toString() { return L"weight(" + query->toString() + L")"; } - + QueryPtr TermWeight::getQuery() { return query; } - + double TermWeight::getValue() { return value; } - + double TermWeight::sumOfSquaredWeights() { queryWeight = idf * getQuery()->getBoost(); // compute query weight return queryWeight * queryWeight; // square it } - + void TermWeight::normalize(double norm) { queryNorm = norm; queryWeight *= queryNorm; // normalize query weight - value = queryWeight * idf; // idf for document + value = queryWeight * idf; // idf for document } - + ScorerPtr TermWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { TermDocsPtr termDocs(reader->termDocs(query->term)); return termDocs ? newLucene(shared_from_this(), termDocs, similarity, reader->norms(query->term->field())) : ScorerPtr(); } - + ExplanationPtr TermWeight::explain(IndexReaderPtr reader, int32_t doc) { ComplexExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - + ExplanationPtr expl(newLucene(idf, idfExp->explain())); - + // explain query weight ExplanationPtr queryExpl(newLucene()); queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); if (query->getBoost() != 1.0) queryExpl->addDetail(boostExpl); queryExpl->addDetail(expl); - + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); queryExpl->addDetail(queryNormExpl); - + queryExpl->setValue(boostExpl->getValue() * expl->getValue() * queryNormExpl->getValue()); result->addDetail(queryExpl); - + // explain field weight String field(query->term->field()); ComplexExplanationPtr fieldExpl(newLucene()); fieldExpl->setDescription(L"fieldWeight(" + query->term->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - + ExplanationPtr tfExplanation(newLucene()); int32_t tf = 0; TermDocsPtr termDocs(reader->termDocs(query->term)); @@ -179,29 +179,29 @@ namespace Lucene tfExplanation->setValue(0.0); tfExplanation->setDescription(L"no matching term"); } - + fieldExpl->addDetail(tfExplanation); fieldExpl->addDetail(expl); - + ExplanationPtr fieldNormExpl(newLucene()); ByteArray fieldNorms(reader->norms(field)); double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; fieldNormExpl->setValue(fieldNorm); fieldNormExpl->setDescription(L"fieldNorm(field=" + field + L", doc=" + StringUtils::toString(doc) + L")"); fieldExpl->addDetail(fieldNormExpl); - + fieldExpl->setMatch(tfExplanation->isMatch()); fieldExpl->setValue(tfExplanation->getValue() * expl->getValue() * fieldNormExpl->getValue()); - + result->addDetail(fieldExpl); result->setMatch(fieldExpl->getMatch()); - + // combine them result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - + if (queryExpl->getValue() == 1.0) return fieldExpl; - + return result; } } diff --git a/src/core/search/TermRangeFilter.cpp b/src/core/search/TermRangeFilter.cpp index 6c5ce852..e1fa9bd5 100644 --- a/src/core/search/TermRangeFilter.cpp +++ b/src/core/search/TermRangeFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,52 +12,52 @@ namespace Lucene { - TermRangeFilter::TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, - bool includeUpper, CollatorPtr collator) : - MultiTermQueryWrapperFilter(newLucene(fieldName, lowerTerm, upperTerm, + TermRangeFilter::TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + bool includeUpper, CollatorPtr collator) : + MultiTermQueryWrapperFilter(newLucene(fieldName, lowerTerm, upperTerm, includeLower, includeUpper, collator)) { } - + TermRangeFilter::~TermRangeFilter() { } - + TermRangeFilterPtr TermRangeFilter::Less(const String& fieldName, StringValue upperTerm) { return newLucene(fieldName, VariantUtils::null(), upperTerm, false, true); } - + TermRangeFilterPtr TermRangeFilter::More(const String& fieldName, StringValue lowerTerm) { return newLucene(fieldName, lowerTerm, VariantUtils::null(), true, false); } - + String TermRangeFilter::getField() { return boost::static_pointer_cast(query)->getField(); } - + String TermRangeFilter::getLowerTerm() { return boost::static_pointer_cast(query)->getLowerTerm(); } - + String TermRangeFilter::getUpperTerm() { return boost::static_pointer_cast(query)->getUpperTerm(); } - + bool TermRangeFilter::includesLower() { return boost::static_pointer_cast(query)->includesLower(); } - + bool TermRangeFilter::includesUpper() { return boost::static_pointer_cast(query)->includesUpper(); } - + CollatorPtr TermRangeFilter::getCollator() { return boost::static_pointer_cast(query)->getCollator(); diff --git a/src/core/search/TermRangeQuery.cpp b/src/core/search/TermRangeQuery.cpp index 4643b9c1..adba80a2 100644 --- a/src/core/search/TermRangeQuery.cpp +++ b/src/core/search/TermRangeQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene { - TermRangeQuery::TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + TermRangeQuery::TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, bool includeUpper, CollatorPtr collator) { this->field = fieldName; @@ -23,46 +23,46 @@ namespace Lucene this->includeUpper = includeUpper; this->collator = collator; } - + TermRangeQuery::~TermRangeQuery() { } - + String TermRangeQuery::getField() { return field; } - + String TermRangeQuery::getLowerTerm() { return VariantUtils::get(lowerTerm); } - + String TermRangeQuery::getUpperTerm() { return VariantUtils::get(upperTerm); } - + bool TermRangeQuery::includesLower() { return includeLower; } - + bool TermRangeQuery::includesUpper() { return includeUpper; } - + CollatorPtr TermRangeQuery::getCollator() { return collator; } - + FilteredTermEnumPtr TermRangeQuery::getEnum(IndexReaderPtr reader) { return newLucene(reader, field, lowerTerm, upperTerm, includeLower, includeUpper, collator); } - + LuceneObjectPtr TermRangeQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, lowerTerm, upperTerm, includeLower, includeUpper, collator)); @@ -75,7 +75,7 @@ namespace Lucene cloneQuery->includeUpper = includeUpper; return cloneQuery; } - + String TermRangeQuery::toString(const String& field) { StringStream buffer; @@ -95,7 +95,7 @@ namespace Lucene buffer << boostString(); return buffer.str(); } - + bool TermRangeQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -136,7 +136,7 @@ namespace Lucene return false; return true; } - + int32_t TermRangeQuery::hashCode() { int32_t prime = 31; diff --git a/src/core/search/TermRangeTermEnum.cpp b/src/core/search/TermRangeTermEnum.cpp index 58d40bbc..ec031082 100644 --- a/src/core/search/TermRangeTermEnum.cpp +++ b/src/core/search/TermRangeTermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene { - TermRangeTermEnum::TermRangeTermEnum(IndexReaderPtr reader, const String& field, StringValue lowerTermText, + TermRangeTermEnum::TermRangeTermEnum(IndexReaderPtr reader, const String& field, StringValue lowerTermText, StringValue upperTermText, bool includeLower, bool includeUpper, CollatorPtr collator) { this->collator = collator; @@ -24,32 +24,32 @@ namespace Lucene this->includeLower = includeLower; this->includeUpper = includeUpper; this->field = field; - + // do a little bit of normalization: open ended range queries should always be inclusive. if (VariantUtils::isNull(this->lowerTermText)) this->includeLower = true; - + if (VariantUtils::isNull(this->upperTermText)) this->includeUpper = true; - + String startTermText(collator ? L"" : VariantUtils::get(this->lowerTermText)); setEnum(reader->terms(newLucene(this->field, startTermText))); } - + TermRangeTermEnum::~TermRangeTermEnum() { } - + double TermRangeTermEnum::difference() { return 1.0; } - + bool TermRangeTermEnum::endEnum() { return _endEnum; } - + bool TermRangeTermEnum::termCompare(TermPtr term) { if (!collator) @@ -88,11 +88,11 @@ namespace Lucene { if (term && term->field() == field) { - if ((VariantUtils::isNull(lowerTermText) || - (includeLower ? collator->compare(term->text(), VariantUtils::get(lowerTermText)) >= 0 : - collator->compare(term->text(), VariantUtils::get(lowerTermText)) > 0)) && + if ((VariantUtils::isNull(lowerTermText) || + (includeLower ? collator->compare(term->text(), VariantUtils::get(lowerTermText)) >= 0 : + collator->compare(term->text(), VariantUtils::get(lowerTermText)) > 0)) && (VariantUtils::isNull(upperTermText) || - (includeUpper ? collator->compare(term->text(), VariantUtils::get(upperTermText)) <= 0 : + (includeUpper ? collator->compare(term->text(), VariantUtils::get(upperTermText)) <= 0 : collator->compare(term->text(), VariantUtils::get(upperTermText)) < 0))) return true; return false; diff --git a/src/core/search/TermScorer.cpp b/src/core/search/TermScorer.cpp index e33cf8f2..0ae61c4f 100644 --- a/src/core/search/TermScorer.cpp +++ b/src/core/search/TermScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene { const int32_t TermScorer::SCORE_CACHE_SIZE = 32; - + TermScorer::TermScorer(WeightPtr weight, TermDocsPtr td, SimilarityPtr similarity, ByteArray norms) : Scorer(similarity) { this->weight = weight; @@ -27,25 +27,25 @@ namespace Lucene this->pointer = 0; this->pointerMax = 0; this->scoreCache = Collection::newInstance(SCORE_CACHE_SIZE); - + for (int32_t i = 0; i < SCORE_CACHE_SIZE; ++i) scoreCache[i] = getSimilarity()->tf(i) * weightValue; } - + TermScorer::~TermScorer() { } - + const Collection TermScorer::SIM_NORM_DECODER() { return Similarity::getNormDecoder(); } - + void TermScorer::score(CollectorPtr collector) { score(collector, INT_MAX, nextDoc()); } - + bool TermScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) { // firstDocID is ignored since nextDoc() sets 'doc' @@ -53,7 +53,7 @@ namespace Lucene while (doc < max) // for docs in window { collector->collect(doc); - + if (++pointer >= pointerMax) { pointerMax = termDocs->read(docs, freqs); // refill buffers @@ -70,12 +70,12 @@ namespace Lucene } return true; } - + int32_t TermScorer::docID() { return doc; } - + int32_t TermScorer::nextDoc() { ++pointer; @@ -94,7 +94,7 @@ namespace Lucene doc = docs[pointer]; return doc; } - + double TermScorer::score() { BOOST_ASSERT(doc != -1); @@ -102,7 +102,7 @@ namespace Lucene double raw = f < SCORE_CACHE_SIZE ? scoreCache[f] : getSimilarity()->tf(f) * weightValue; // compute tf(f) * weight return norms ? raw * SIM_NORM_DECODER()[norms[doc] & 0xff] : raw; // normalize for field } - + int32_t TermScorer::advance(int32_t target) { // first scan in cache @@ -114,7 +114,7 @@ namespace Lucene return doc; } } - + // not found in cache, seek underlying stream bool result = termDocs->skipTo(target); if (result) @@ -129,7 +129,7 @@ namespace Lucene doc = NO_MORE_DOCS; return doc; } - + String TermScorer::toString() { return L"scorer(" + weight->toString() + L")"; diff --git a/src/core/search/TimeLimitingCollector.cpp b/src/core/search/TimeLimitingCollector.cpp index 7a23a1ba..7b2f968d 100644 --- a/src/core/search/TimeLimitingCollector.cpp +++ b/src/core/search/TimeLimitingCollector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,9 +13,9 @@ namespace Lucene { /// Default timer resolution. const int32_t TimeLimitingCollector::DEFAULT_RESOLUTION = 20; - + int64_t TimeLimitingCollector::resolution = TimeLimitingCollector::DEFAULT_RESOLUTION; - + TimeLimitingCollector::TimeLimitingCollector(CollectorPtr collector, int64_t timeAllowed) { this->DEFAULT_GREEDY = false; @@ -25,11 +25,11 @@ namespace Lucene this->timeout = t0 + timeAllowed; this->docBase = 0; } - + TimeLimitingCollector::~TimeLimitingCollector() { } - + TimerThreadPtr TimeLimitingCollector::TIMER_THREAD() { static TimerThreadPtr _TIMER_THREAD; @@ -42,17 +42,17 @@ namespace Lucene _TIMER_THREAD->start(); // start single thread instance return _TIMER_THREAD; } - + int64_t TimeLimitingCollector::getResolution() { return resolution; } - + void TimeLimitingCollector::setResolution(int64_t newResolution) { resolution = std::max(newResolution, (int64_t)5); // 5 milliseconds is about the minimum reasonable time for a wait call. } - + void TimeLimitingCollector::stopTimer() { if (TIMER_THREAD()->isAlive()) @@ -61,17 +61,17 @@ namespace Lucene TIMER_THREAD()->join(); } } - + bool TimeLimitingCollector::isGreedy() { return greedy; } - + void TimeLimitingCollector::setGreedy(bool greedy) { this->greedy = greedy; } - + void TimeLimitingCollector::collect(int32_t doc) { int64_t time = TIMER_THREAD()->getMilliseconds(); @@ -85,39 +85,39 @@ namespace Lucene } collector->collect(doc); } - + void TimeLimitingCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { collector->setNextReader(reader, docBase); this->docBase = docBase; } - + void TimeLimitingCollector::setScorer(ScorerPtr scorer) { collector->setScorer(scorer); } - + bool TimeLimitingCollector::acceptsDocsOutOfOrder() { return collector->acceptsDocsOutOfOrder(); } - + TimerThread::TimerThread() { time = 0; _stopThread = false; } - + TimerThread::~TimerThread() { } - + void TimerThread::start() { _stopThread = false; LuceneThread::start(); } - + void TimerThread::run() { while (!_stopThread) @@ -131,13 +131,13 @@ namespace Lucene LuceneThread::threadSleep(resolution); } } - + int64_t TimerThread::getMilliseconds() { SyncLock syncLock(this); return time; } - + void TimerThread::stopThread() { _stopThread = true; diff --git a/src/core/search/TopDocs.cpp b/src/core/search/TopDocs.cpp index e79d4ae1..83a88a75 100644 --- a/src/core/search/TopDocs.cpp +++ b/src/core/search/TopDocs.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,23 +15,23 @@ namespace Lucene this->scoreDocs = scoreDocs; this->maxScore = std::numeric_limits::quiet_NaN(); } - + TopDocs::TopDocs(int32_t totalHits, Collection scoreDocs, double maxScore) { this->totalHits = totalHits; this->scoreDocs = scoreDocs; this->maxScore = maxScore; } - + TopDocs::~TopDocs() { } - + double TopDocs::getMaxScore() { return maxScore; } - + void TopDocs::setMaxScore(double maxScore) { this->maxScore = maxScore; diff --git a/src/core/search/TopDocsCollector.cpp b/src/core/search/TopDocsCollector.cpp index 9356d02e..2cda42bf 100644 --- a/src/core/search/TopDocsCollector.cpp +++ b/src/core/search/TopDocsCollector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene this->pq = pq; this->totalHits = 0; } - + TopDocsCollector::~TopDocsCollector() { } - + TopDocsPtr TopDocsCollector::EMPTY_TOPDOCS() { static TopDocsPtr _EMPTY_TOPDOCS; @@ -31,62 +31,62 @@ namespace Lucene } return _EMPTY_TOPDOCS; } - + void TopDocsCollector::populateResults(Collection results, int32_t howMany) { for (int32_t i = howMany - 1; i >= 0; --i) results[i] = pq->pop(); } - + TopDocsPtr TopDocsCollector::newTopDocs(Collection results, int32_t start) { return results ? newLucene(totalHits, results) : EMPTY_TOPDOCS(); } - + int32_t TopDocsCollector::getTotalHits() { return totalHits; } - + TopDocsPtr TopDocsCollector::topDocs() { - // In case pq was populated with sentinel values, there might be less results than pq.size(). + // In case pq was populated with sentinel values, there might be less results than pq.size(). // Therefore return all results until either pq.size() or totalHits. return topDocs(0, totalHits < pq->size() ? totalHits : pq->size()); } - + TopDocsPtr TopDocsCollector::topDocs(int32_t start) { - // In case pq was populated with sentinel values, there might be less results than pq.size(). + // In case pq was populated with sentinel values, there might be less results than pq.size(). // Therefore return all results until either pq.size() or totalHits. return topDocs(start, totalHits < pq->size() ? totalHits : pq->size()); } - + TopDocsPtr TopDocsCollector::topDocs(int32_t start, int32_t howMany) { - // In case pq was populated with sentinel values, there might be less results than pq.size(). + // In case pq was populated with sentinel values, there might be less results than pq.size(). // Therefore return all results until either pq.size() or totalHits. int32_t size = totalHits < pq->size() ? totalHits : pq->size(); - - // Don't bother to throw an exception, just return an empty TopDocs in case the parameters are + + // Don't bother to throw an exception, just return an empty TopDocs in case the parameters are // invalid or out of range. if (start < 0 || start >= size || howMany <= 0) return newTopDocs(Collection(), start); - + // We know that start < pq.size, so just fix howMany. howMany = std::min(size - start, howMany); Collection results = Collection::newInstance(howMany); - - // pq's pop() returns the 'least' element in the queue, therefore need to discard the first ones, - // until we reach the requested range. Note that this loop will usually not be executed, since the - // common usage should be that the caller asks for the last howMany results. However it's needed + + // pq's pop() returns the 'least' element in the queue, therefore need to discard the first ones, + // until we reach the requested range. Note that this loop will usually not be executed, since the + // common usage should be that the caller asks for the last howMany results. However it's needed // here for completeness. for (int32_t i = pq->size() - start - howMany; i > 0; --i) pq->pop(); - + // Get the requested results from pq. populateResults(results, howMany); - + return newTopDocs(results, start); } } diff --git a/src/core/search/TopFieldCollector.cpp b/src/core/search/TopFieldCollector.cpp index 6987d9c9..4a341704 100644 --- a/src/core/search/TopFieldCollector.cpp +++ b/src/core/search/TopFieldCollector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,11 +24,11 @@ namespace Lucene this->queueFull = false; this->docBase = 0; } - + TopFieldCollector::~TopFieldCollector() { } - + const Collection TopFieldCollector::EMPTY_SCOREDOCS() { static Collection _EMPTY_SCOREDOCS; @@ -36,12 +36,12 @@ namespace Lucene _EMPTY_SCOREDOCS = Collection::newInstance(); return _EMPTY_SCOREDOCS; } - + TopFieldCollectorPtr TopFieldCollector::create(SortPtr sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder) { if (sort->fields.empty()) boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); - + FieldValueHitQueuePtr queue(FieldValueHitQueue::create(sort->fields, numHits)); if (queue->getComparators().size() == 1) { @@ -64,7 +64,7 @@ namespace Lucene return newLucene(queue, numHits, fillFields); } } - + // multiple comparators if (docsScoredInOrder) { @@ -85,13 +85,13 @@ namespace Lucene return newLucene(queue, numHits, fillFields); } } - + void TopFieldCollector::add(int32_t slot, int32_t doc, double score) { bottom = boost::static_pointer_cast(pq->add(newLucene(slot, docBase + doc, score))); queueFull = (totalHits == numHits); } - + void TopFieldCollector::populateResults(Collection results, int32_t howMany) { if (fillFields) @@ -109,7 +109,7 @@ namespace Lucene } } } - + TopDocsPtr TopFieldCollector::newTopDocs(Collection results, int32_t start) { if (!results) @@ -118,24 +118,24 @@ namespace Lucene // Set maxScore to NaN, in case this is a maxScore tracking collector maxScore = std::numeric_limits::quiet_NaN(); } - + // If this is a maxScoring tracking collector and there were no results return newLucene(totalHits, results, boost::static_pointer_cast(pq)->getFields(), maxScore); } - + bool TopFieldCollector::acceptsDocsOutOfOrder() { return false; } - + OneComparatorNonScoringCollector::OneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) { } - + OneComparatorNonScoringCollector::~OneComparatorNonScoringCollector() { } - + void OneComparatorNonScoringCollector::initialize() { TopFieldCollector::initialize(); @@ -143,14 +143,14 @@ namespace Lucene comparator = queue->getComparators()[0]; reverseMul = queue->getReverseMul()[0]; } - + void OneComparatorNonScoringCollector::updateBottom(int32_t doc) { // bottom.score is already set to NaN in add(). bottom->doc = docBase + doc; bottom = boost::static_pointer_cast(pq->updateTop()); } - + void OneComparatorNonScoringCollector::collect(int32_t doc) { ++totalHits; @@ -158,11 +158,11 @@ namespace Lucene { if ((reverseMul * comparator->compareBottom(doc)) <= 0) { - // since docs are visited in doc Id order, if compare is 0, it means this document is largest + // since docs are visited in doc Id order, if compare is 0, it means this document is largest // than anything else in the queue, and therefore not competitive. return; } - + // This hit is competitive - replace bottom element in queue and adjustTop comparator->copy(bottom->slot, doc); updateBottom(doc); @@ -179,26 +179,26 @@ namespace Lucene comparator->setBottom(bottom->slot); } } - + void OneComparatorNonScoringCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { this->docBase = docBase; comparator->setNextReader(reader, docBase); } - + void OneComparatorNonScoringCollector::setScorer(ScorerPtr scorer) { comparator->setScorer(scorer); } - + OutOfOrderOneComparatorNonScoringCollector::OutOfOrderOneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { } - + OutOfOrderOneComparatorNonScoringCollector::~OutOfOrderOneComparatorNonScoringCollector() { } - + void OutOfOrderOneComparatorNonScoringCollector::collect(int32_t doc) { ++totalHits; @@ -208,7 +208,7 @@ namespace Lucene int32_t cmp = reverseMul * comparator->compareBottom(doc); if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) return; - + // This hit is competitive - replace bottom element in queue and adjustTop comparator->copy(bottom->slot, doc); updateBottom(doc); @@ -225,27 +225,27 @@ namespace Lucene comparator->setBottom(bottom->slot); } } - + bool OutOfOrderOneComparatorNonScoringCollector::acceptsDocsOutOfOrder() { return true; } - + OneComparatorScoringNoMaxScoreCollector::OneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { } - + OneComparatorScoringNoMaxScoreCollector::~OneComparatorScoringNoMaxScoreCollector() { } - + void OneComparatorScoringNoMaxScoreCollector::updateBottom(int32_t doc, double score) { bottom->doc = docBase + doc; bottom->score = score; bottom = boost::static_pointer_cast(pq->updateTop()); } - + void OneComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { ++totalHits; @@ -253,14 +253,14 @@ namespace Lucene { if ((reverseMul * comparator->compareBottom(doc)) <= 0) { - // since docs are visited in doc Id order, if compare is 0, it means this document is largest + // since docs are visited in doc Id order, if compare is 0, it means this document is largest // than anything else in the queue, and therefore not competitive. return; } - + // Compute the score only if the hit is competitive. double score = scorer->score(); - + // This hit is competitive - replace bottom element in queue and adjustTop comparator->copy(bottom->slot, doc); updateBottom(doc, score); @@ -270,7 +270,7 @@ namespace Lucene { // Compute the score only if the hit is competitive. double score = scorer->score(); - + // Startup transient: queue hasn't gathered numHits yet int32_t slot = totalHits - 1; // Copy hit into queue @@ -280,21 +280,21 @@ namespace Lucene comparator->setBottom(bottom->slot); } } - + void OneComparatorScoringNoMaxScoreCollector::setScorer(ScorerPtr scorer) { this->scorer = scorer; comparator->setScorer(scorer); } - + OutOfOrderOneComparatorScoringNoMaxScoreCollector::OutOfOrderOneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) { } - + OutOfOrderOneComparatorScoringNoMaxScoreCollector::~OutOfOrderOneComparatorScoringNoMaxScoreCollector() { } - + void OutOfOrderOneComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { ++totalHits; @@ -304,10 +304,10 @@ namespace Lucene int32_t cmp = reverseMul * comparator->compareBottom(doc); if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) return; - + // Compute the score only if the hit is competitive. double score = scorer->score(); - + // This hit is competitive - replace bottom element in queue and adjustTop comparator->copy(bottom->slot, doc); updateBottom(doc, score); @@ -317,7 +317,7 @@ namespace Lucene { // Compute the score only if the hit is competitive. double score = scorer->score(); - + // Startup transient: queue hasn't gathered numHits yet int32_t slot = totalHits - 1; // Copy hit into queue @@ -327,29 +327,29 @@ namespace Lucene comparator->setBottom(bottom->slot); } } - + bool OutOfOrderOneComparatorScoringNoMaxScoreCollector::acceptsDocsOutOfOrder() { return true; } - + OneComparatorScoringMaxScoreCollector::OneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. this->maxScore = -std::numeric_limits::infinity(); } - + OneComparatorScoringMaxScoreCollector::~OneComparatorScoringMaxScoreCollector() { } - + void OneComparatorScoringMaxScoreCollector::updateBottom(int32_t doc, double score) { bottom->doc = docBase + doc; bottom->score = score; bottom = boost::static_pointer_cast(pq->updateTop()); } - + void OneComparatorScoringMaxScoreCollector::collect(int32_t doc) { double score = scorer->score(); @@ -360,11 +360,11 @@ namespace Lucene { if ((reverseMul * comparator->compareBottom(doc)) <= 0) { - // since docs are visited in doc Id order, if compare is 0, it means this document is largest + // since docs are visited in doc Id order, if compare is 0, it means this document is largest // than anything else in the queue, and therefore not competitive. return; } - + // This hit is competitive - replace bottom element in queue and adjustTop comparator->copy(bottom->slot, doc); updateBottom(doc, score); @@ -381,21 +381,21 @@ namespace Lucene comparator->setBottom(bottom->slot); } } - + void OneComparatorScoringMaxScoreCollector::setScorer(ScorerPtr scorer) { this->scorer = scorer; OneComparatorNonScoringCollector::setScorer(scorer); } - + OutOfOrderOneComparatorScoringMaxScoreCollector::OutOfOrderOneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorScoringMaxScoreCollector(queue, numHits, fillFields) { } - + OutOfOrderOneComparatorScoringMaxScoreCollector::~OutOfOrderOneComparatorScoringMaxScoreCollector() { } - + void OutOfOrderOneComparatorScoringMaxScoreCollector::collect(int32_t doc) { double score = scorer->score(); @@ -408,7 +408,7 @@ namespace Lucene int32_t cmp = reverseMul * comparator->compareBottom(doc); if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) return; - + // This hit is competitive - replace bottom element in queue and adjustTop comparator->copy(bottom->slot, doc); updateBottom(doc, score); @@ -425,20 +425,20 @@ namespace Lucene comparator->setBottom(bottom->slot); } } - + bool OutOfOrderOneComparatorScoringMaxScoreCollector::acceptsDocsOutOfOrder() { return true; } - + MultiComparatorNonScoringCollector::MultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) { } - + MultiComparatorNonScoringCollector::~MultiComparatorNonScoringCollector() { } - + void MultiComparatorNonScoringCollector::initialize() { TopFieldCollector::initialize(); @@ -446,14 +446,14 @@ namespace Lucene comparators = queue->getComparators(); reverseMul = queue->getReverseMul(); } - + void MultiComparatorNonScoringCollector::updateBottom(int32_t doc) { // bottom.score is already set to NaN in add(). bottom->doc = docBase + doc; bottom = boost::static_pointer_cast(pq->updateTop()); } - + void MultiComparatorNonScoringCollector::collect(int32_t doc) { ++totalHits; @@ -475,19 +475,19 @@ namespace Lucene } else if (i == comparators.size() - 1) { - // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are - // visited in doc Id order, which means this doc cannot compete with any other document + // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are + // visited in doc Id order, which means this doc cannot compete with any other document // in the queue. return; } } - + // This hit is competitive - replace bottom element in queue and adjustTop for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(bottom->slot, doc); - + updateBottom(doc); - + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setBottom(bottom->slot); } @@ -506,29 +506,29 @@ namespace Lucene } } } - + void MultiComparatorNonScoringCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { this->docBase = docBase; for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setNextReader(reader, docBase); } - + void MultiComparatorNonScoringCollector::setScorer(ScorerPtr scorer) { // set the scorer on all comparators for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setScorer(scorer); } - + OutOfOrderMultiComparatorNonScoringCollector::OutOfOrderMultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { } - + OutOfOrderMultiComparatorNonScoringCollector::~OutOfOrderMultiComparatorNonScoringCollector() { } - + void OutOfOrderMultiComparatorNonScoringCollector::collect(int32_t doc) { ++totalHits; @@ -559,13 +559,13 @@ namespace Lucene break; } } - + // This hit is competitive - replace bottom element in queue and adjustTop for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(bottom->slot, doc); - + updateBottom(doc); - + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setBottom(bottom->slot); } @@ -584,29 +584,29 @@ namespace Lucene } } } - + bool OutOfOrderMultiComparatorNonScoringCollector::acceptsDocsOutOfOrder() { return true; } - + MultiComparatorScoringMaxScoreCollector::MultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. this->maxScore = -std::numeric_limits::infinity(); } - + MultiComparatorScoringMaxScoreCollector::~MultiComparatorScoringMaxScoreCollector() { } - + void MultiComparatorScoringMaxScoreCollector::updateBottom(int32_t doc, double score) { bottom->doc = docBase + doc; bottom->score = score; bottom = boost::static_pointer_cast(pq->updateTop()); } - + void MultiComparatorScoringMaxScoreCollector::collect(int32_t doc) { double score = ScorerPtr(_scorer)->score(); @@ -631,19 +631,19 @@ namespace Lucene } else if (i == comparators.size() - 1) { - // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are - // visited in doc Id order, which means this doc cannot compete with any other document + // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are + // visited in doc Id order, which means this doc cannot compete with any other document // in the queue. return; } } - + // This hit is competitive - replace bottom element in queue and adjustTop for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(bottom->slot, doc); - + updateBottom(doc, score); - + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setBottom(bottom->slot); } @@ -662,21 +662,21 @@ namespace Lucene } } } - + void MultiComparatorScoringMaxScoreCollector::setScorer(ScorerPtr scorer) { this->_scorer = scorer; MultiComparatorNonScoringCollector::setScorer(scorer); } - + OutOfOrderMultiComparatorScoringMaxScoreCollector::OutOfOrderMultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields) { } - + OutOfOrderMultiComparatorScoringMaxScoreCollector::~OutOfOrderMultiComparatorScoringMaxScoreCollector() { } - + void OutOfOrderMultiComparatorScoringMaxScoreCollector::collect(int32_t doc) { double score = ScorerPtr(_scorer)->score(); @@ -710,13 +710,13 @@ namespace Lucene break; } } - + // This hit is competitive - replace bottom element in queue and adjustTop for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(bottom->slot, doc); - + updateBottom(doc, score); - + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setBottom(bottom->slot); } @@ -735,27 +735,27 @@ namespace Lucene } } } - + bool OutOfOrderMultiComparatorScoringMaxScoreCollector::acceptsDocsOutOfOrder() { return true; } - + MultiComparatorScoringNoMaxScoreCollector::MultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { } - + MultiComparatorScoringNoMaxScoreCollector::~MultiComparatorScoringNoMaxScoreCollector() { } - + void MultiComparatorScoringNoMaxScoreCollector::updateBottom(int32_t doc, double score) { bottom->doc = docBase + doc; bottom->score = score; bottom = boost::static_pointer_cast(pq->updateTop()); } - + void MultiComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { ++totalHits; @@ -777,21 +777,21 @@ namespace Lucene } else if (i == comparators.size() - 1) { - // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are - // visited in doc Id order, which means this doc cannot compete with any other document + // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are + // visited in doc Id order, which means this doc cannot compete with any other document // in the queue. return; } } - + // This hit is competitive - replace bottom element in queue and adjustTop for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(bottom->slot, doc); - + // Compute score only if it is competitive. double score = ScorerPtr(_scorer)->score(); updateBottom(doc, score); - + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setBottom(bottom->slot); } @@ -802,7 +802,7 @@ namespace Lucene // Copy hit into queue for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(slot, doc); - + // Compute score only if it is competitive. double score = ScorerPtr(_scorer)->score(); add(slot, doc, score); @@ -813,21 +813,21 @@ namespace Lucene } } } - + void MultiComparatorScoringNoMaxScoreCollector::setScorer(ScorerPtr scorer) { this->_scorer = scorer; MultiComparatorNonScoringCollector::setScorer(scorer); } - + OutOfOrderMultiComparatorScoringNoMaxScoreCollector::OutOfOrderMultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) { } - + OutOfOrderMultiComparatorScoringNoMaxScoreCollector::~OutOfOrderMultiComparatorScoringNoMaxScoreCollector() { } - + void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { ++totalHits; @@ -858,15 +858,15 @@ namespace Lucene break; } } - + // This hit is competitive - replace bottom element in queue and adjustTop for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(bottom->slot, doc); - + // Compute score only if it is competitive. double score = ScorerPtr(_scorer)->score(); updateBottom(doc, score); - + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setBottom(bottom->slot); } @@ -877,7 +877,7 @@ namespace Lucene // Copy hit into queue for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->copy(slot, doc); - + // Compute score only if it is competitive. double score = ScorerPtr(_scorer)->score(); add(slot, doc, score); @@ -888,13 +888,13 @@ namespace Lucene } } } - + void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::setScorer(ScorerPtr scorer) { this->_scorer = scorer; MultiComparatorScoringNoMaxScoreCollector::setScorer(scorer); } - + bool OutOfOrderMultiComparatorScoringNoMaxScoreCollector::acceptsDocsOutOfOrder() { return true; diff --git a/src/core/search/TopFieldDocs.cpp b/src/core/search/TopFieldDocs.cpp index 5a22e38f..4c3f9b44 100644 --- a/src/core/search/TopFieldDocs.cpp +++ b/src/core/search/TopFieldDocs.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene { this->fields = fields; } - + TopFieldDocs::~TopFieldDocs() { } diff --git a/src/core/search/TopScoreDocCollector.cpp b/src/core/search/TopScoreDocCollector.cpp index e29c6b22..a398c011 100644 --- a/src/core/search/TopScoreDocCollector.cpp +++ b/src/core/search/TopScoreDocCollector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,16 +17,16 @@ namespace Lucene { TopScoreDocCollector::TopScoreDocCollector(int32_t numHits) : TopDocsCollector(newLucene(numHits, true)) { - // HitQueue implements getSentinelObject to return a ScoreDoc, so we know that at this point top() + // HitQueue implements getSentinelObject to return a ScoreDoc, so we know that at this point top() // is already initialized. pqTop = pq->top(); docBase = 0; } - + TopScoreDocCollector::~TopScoreDocCollector() { } - + TopScoreDocCollectorPtr TopScoreDocCollector::create(int32_t numHits, bool docsScoredInOrder) { if (docsScoredInOrder) @@ -34,14 +34,14 @@ namespace Lucene else return newLucene(numHits); } - + TopDocsPtr TopScoreDocCollector::newTopDocs(Collection results, int32_t start) { if (!results) return EMPTY_TOPDOCS(); - - // We need to compute maxScore in order to set it in TopDocs. If start == 0, it means the largest element - // is already in results, use its score as maxScore. Otherwise pop everything else, until the largest + + // We need to compute maxScore in order to set it in TopDocs. If start == 0, it means the largest element + // is already in results, use its score as maxScore. Otherwise pop everything else, until the largest // element is extracted and use its score as maxScore. double maxScore = std::numeric_limits::quiet_NaN(); if (start == 0) @@ -52,32 +52,32 @@ namespace Lucene pq->pop(); maxScore = pq->pop()->score; } - + return newLucene(totalHits, results, maxScore); } - + void TopScoreDocCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) { this->docBase = docBase; } - + void TopScoreDocCollector::setScorer(ScorerPtr scorer) { this->_scorer = scorer; } - + InOrderTopScoreDocCollector::InOrderTopScoreDocCollector(int32_t numHits) : TopScoreDocCollector(numHits) { } - + InOrderTopScoreDocCollector::~InOrderTopScoreDocCollector() { } - + void InOrderTopScoreDocCollector::collect(int32_t doc) { double score = ScorerPtr(_scorer)->score(); - + // This collector cannot handle these scores BOOST_ASSERT(score != -std::numeric_limits::infinity()); BOOST_ASSERT(!MiscUtils::isNaN(score)); @@ -85,8 +85,8 @@ namespace Lucene ++totalHits; if (score <= pqTop->score) { - // Since docs are returned in-order (ie., increasing doc Id), a document with equal score to - // pqTop.score cannot compete since HitQueue favours documents with lower doc Ids. Therefore + // Since docs are returned in-order (ie., increasing doc Id), a document with equal score to + // pqTop.score cannot compete since HitQueue favours documents with lower doc Ids. Therefore // reject those docs too. return; } @@ -94,27 +94,27 @@ namespace Lucene pqTop->score = score; pqTop = pq->updateTop(); } - + bool InOrderTopScoreDocCollector::acceptsDocsOutOfOrder() { return false; } - + OutOfOrderTopScoreDocCollector::OutOfOrderTopScoreDocCollector(int32_t numHits) : TopScoreDocCollector(numHits) { } - + OutOfOrderTopScoreDocCollector::~OutOfOrderTopScoreDocCollector() { } - + void OutOfOrderTopScoreDocCollector::collect(int32_t doc) { double score = ScorerPtr(_scorer)->score(); - + // This collector cannot handle NaN BOOST_ASSERT(!MiscUtils::isNaN(score)); - + ++totalHits; doc += docBase; if (score < pqTop->score || (score == pqTop->score && doc > pqTop->doc)) @@ -123,7 +123,7 @@ namespace Lucene pqTop->score = score; pqTop = pq->updateTop(); } - + bool OutOfOrderTopScoreDocCollector::acceptsDocsOutOfOrder() { return true; diff --git a/src/core/search/Weight.cpp b/src/core/search/Weight.cpp index fdc7aa63..eb05969c 100644 --- a/src/core/search/Weight.cpp +++ b/src/core/search/Weight.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene Weight::~Weight() { } - + bool Weight::scoresDocsOutOfOrder() { return false; diff --git a/src/core/search/WildcardQuery.cpp b/src/core/search/WildcardQuery.cpp index 3bc7dbb6..d2382c4f 100644 --- a/src/core/search/WildcardQuery.cpp +++ b/src/core/search/WildcardQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,15 +20,15 @@ namespace Lucene this->term = term; String text(term->text()); this->termContainsWildcard = boost::contains(text, L"*") || boost::contains(text, L"?"); - this->termIsPrefix = termContainsWildcard && - !boost::contains(text, L"?") && + this->termIsPrefix = termContainsWildcard && + !boost::contains(text, L"?") && text.find_first_of(L"*") == text.length() - 1; } - + WildcardQuery::~WildcardQuery() { } - + FilteredTermEnumPtr WildcardQuery::getEnum(IndexReaderPtr reader) { if (termContainsWildcard) @@ -36,12 +36,12 @@ namespace Lucene else return newLucene(reader, getTerm()); } - + TermPtr WildcardQuery::getTerm() { return term; } - + QueryPtr WildcardQuery::rewrite(IndexReaderPtr reader) { if (termIsPrefix) @@ -54,7 +54,7 @@ namespace Lucene else return MultiTermQuery::rewrite(reader); } - + String WildcardQuery::toString(const String& field) { StringStream buffer; @@ -63,7 +63,7 @@ namespace Lucene buffer << term->text() << boostString(); return buffer.str(); } - + LuceneObjectPtr WildcardQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); @@ -73,7 +73,7 @@ namespace Lucene cloneQuery->term = term; return cloneQuery; } - + int32_t WildcardQuery::hashCode() { int32_t prime = 31; @@ -81,7 +81,7 @@ namespace Lucene result = prime * result + (term ? term->hashCode() : 0); return result; } - + bool WildcardQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) diff --git a/src/core/search/WildcardTermEnum.cpp b/src/core/search/WildcardTermEnum.cpp index 78a7d602..237d9b6e 100644 --- a/src/core/search/WildcardTermEnum.cpp +++ b/src/core/search/WildcardTermEnum.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,14 +14,14 @@ namespace Lucene { const wchar_t WildcardTermEnum::WILDCARD_STRING = L'*'; const wchar_t WildcardTermEnum::WILDCARD_CHAR = L'?'; - + WildcardTermEnum::WildcardTermEnum(IndexReaderPtr reader, TermPtr term) { _endEnum = false; searchTerm = term; field = searchTerm->field(); String searchTermText(searchTerm->text()); - + String::size_type sidx = searchTermText.find(WILDCARD_STRING); String::size_type cidx = searchTermText.find(WILDCARD_CHAR); String::size_type idx = sidx; @@ -30,16 +30,16 @@ namespace Lucene else if (cidx != String::npos) idx = std::min(idx, cidx); pre = idx != String::npos ? searchTerm->text().substr(0, idx) : L""; - + preLen = pre.length(); text = searchTermText.substr(preLen); setEnum(reader->terms(newLucene(searchTerm->field(), pre))); } - + WildcardTermEnum::~WildcardTermEnum() { } - + bool WildcardTermEnum::termCompare(TermPtr term) { if (field == term->field()) @@ -51,17 +51,17 @@ namespace Lucene _endEnum = true; return false; } - + double WildcardTermEnum::difference() { return 1.0; } - + bool WildcardTermEnum::endEnum() { return _endEnum; } - + bool WildcardTermEnum::wildcardEquals(const String& pattern, int32_t patternIdx, const String& string, int32_t stringIdx) { int32_t p = patternIdx; @@ -71,22 +71,22 @@ namespace Lucene bool sEnd = (s >= (int32_t)string.length()); // End of pattern yet? bool pEnd = (p >= (int32_t)pattern.length()); - + // If we're looking at the end of the string if (sEnd) { // Assume the only thing left on the pattern is/are wildcards bool justWildcardsLeft = true; - + // Current wildcard position int32_t wildcardSearchPos = p; - + // While we haven't found the end of the pattern, and haven't encountered any non-wildcard characters while (wildcardSearchPos < (int32_t)pattern.length() && justWildcardsLeft) { // Check the character at the current position wchar_t wildchar = pattern[wildcardSearchPos]; - + // If it's not a wildcard character, then there is more pattern information after this/these wildcards. if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING) justWildcardsLeft = false; @@ -99,20 +99,20 @@ namespace Lucene ++wildcardSearchPos; } } - + // This was a prefix wildcard search, and we've matched, so return true. if (justWildcardsLeft) return true; } - + // If we've gone past the end of the string, or the pattern, return false. if (sEnd || pEnd) break; - + // Match a single character, so continue. if (pattern[p] == WILDCARD_CHAR) continue; - + if (pattern[p] == WILDCARD_STRING) { // Look at the character beyond the '*' characters. diff --git a/src/core/search/function/ByteFieldSource.cpp b/src/core/search/function/ByteFieldSource.cpp index 7a646005..2bd230c5 100644 --- a/src/core/search/function/ByteFieldSource.cpp +++ b/src/core/search/function/ByteFieldSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,22 +17,22 @@ namespace Lucene { this->parser = parser; } - + ByteFieldSource::~ByteFieldSource() { } - + String ByteFieldSource::description() { return L"byte(" + FieldCacheSource::description() + L")"; } - + DocValuesPtr ByteFieldSource::getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) { Collection arr(cache->getBytes(reader, field, parser)); return newLucene(shared_from_this(), arr); } - + bool ByteFieldSource::cachedFieldSourceEquals(FieldCacheSourcePtr other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) @@ -42,41 +42,41 @@ namespace Lucene return false; return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; } - + int32_t ByteFieldSource::cachedFieldSourceHashCode() { return StringUtils::hashCode(parser ? ByteParser::_getClassName() : ByteFieldSource::_getClassName()); } - + ByteDocValues::ByteDocValues(ByteFieldSourcePtr source, Collection arr) { this->_source = source; this->arr = arr; } - + ByteDocValues::~ByteDocValues() { } - + double ByteDocValues::doubleVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); - return (double)arr[doc]; + return (double)arr[doc]; } - + int32_t ByteDocValues::intVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); return (int32_t)arr[doc]; } - + String ByteDocValues::toString(int32_t doc) { return ByteFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); } - + CollectionValue ByteDocValues::getInnerArray() { return arr; diff --git a/src/core/search/function/CustomScoreProvider.cpp b/src/core/search/function/CustomScoreProvider.cpp index c46cb84c..054fda2b 100644 --- a/src/core/search/function/CustomScoreProvider.cpp +++ b/src/core/search/function/CustomScoreProvider.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene { this->reader = reader; } - + CustomScoreProvider::~CustomScoreProvider() { } @@ -30,12 +30,12 @@ namespace Lucene score *= *srcScore; return score; } - + double CustomScoreProvider::customScore(int32_t doc, double subQueryScore, double valSrcScore) { return subQueryScore * valSrcScore; } - + ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) { if (valSrcExpls.size() == 1) @@ -51,7 +51,7 @@ namespace Lucene exp->addDetail(*srcExpl); return exp; } - + ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) { double valSrcScore = 1; diff --git a/src/core/search/function/CustomScoreQuery.cpp b/src/core/search/function/CustomScoreQuery.cpp index 3ccf4a60..7a5ff755 100644 --- a/src/core/search/function/CustomScoreQuery.cpp +++ b/src/core/search/function/CustomScoreQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,7 +18,7 @@ namespace Lucene { ConstructQuery(subQuery, Collection::newInstance()); } - + CustomScoreQuery::CustomScoreQuery(QueryPtr subQuery, ValueSourceQueryPtr valSrcQuery) { Collection valSrcQueries(Collection::newInstance()); @@ -26,16 +26,16 @@ namespace Lucene valSrcQueries.add(valSrcQuery); ConstructQuery(subQuery, valSrcQueries); } - + CustomScoreQuery::CustomScoreQuery(QueryPtr subQuery, Collection valSrcQueries) { ConstructQuery(subQuery, valSrcQueries); } - + CustomScoreQuery::~CustomScoreQuery() { } - + void CustomScoreQuery::ConstructQuery(QueryPtr subQuery, Collection valSrcQueries) { this->strict = false; @@ -44,18 +44,18 @@ namespace Lucene if (!subQuery) boost::throw_exception(IllegalArgumentException(L" must not be null!")); } - + QueryPtr CustomScoreQuery::rewrite(IndexReaderPtr reader) { CustomScoreQueryPtr cloneQuery; - + QueryPtr sq = subQuery->rewrite(reader); if (sq != subQuery) { cloneQuery = boost::static_pointer_cast(clone()); cloneQuery->subQuery = sq; } - + for (int32_t i = 0; i < valSrcQueries.size(); ++i) { ValueSourceQueryPtr v = boost::dynamic_pointer_cast(valSrcQueries[i]->rewrite(reader)); @@ -66,17 +66,17 @@ namespace Lucene cloneQuery->valSrcQueries[i] = v; } } - + return cloneQuery ? cloneQuery : shared_from_this(); } - + void CustomScoreQuery::extractTerms(SetTerm terms) { subQuery->extractTerms(terms); for (Collection::iterator srcQuery = valSrcQueries.begin(); srcQuery != valSrcQueries.end(); ++srcQuery) (*srcQuery)->extractTerms(terms); } - + LuceneObjectPtr CustomScoreQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = Query::clone(other ? other : newLucene(subQuery)); @@ -88,7 +88,7 @@ namespace Lucene cloneQuery->valSrcQueries[i] = boost::dynamic_pointer_cast(valSrcQueries[i]->clone()); return cloneQuery; } - + String CustomScoreQuery::toString(const String& field) { StringStream buffer; @@ -98,7 +98,7 @@ namespace Lucene buffer << L")" << (strict ? L" STRICT" : L"") << boostString(); return buffer.str(); } - + bool CustomScoreQuery::equals(LuceneObjectPtr other) { CustomScoreQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); @@ -108,20 +108,20 @@ namespace Lucene return false; return valSrcQueries.equals(otherQuery->valSrcQueries, luceneEquals()); } - + int32_t CustomScoreQuery::hashCode() { return (StringUtils::hashCode(CustomScoreQuery::_getClassName()) + StringUtils::hashCode(Query::_getClassName()) + MiscUtils::hashCode(valSrcQueries.begin(), valSrcQueries.end(), MiscUtils::hashLucene)) ^ MiscUtils::doubleToIntBits(getBoost()) ^ (strict ? 1234 : 4321); } - + CustomScoreProviderPtr CustomScoreQuery::getCustomScoreProvider(IndexReaderPtr reader) { // when deprecated methods are removed, do not extend class here, just return new default CustomScoreProvider return newLucene(shared_from_this(), reader); } - + double CustomScoreQuery::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) { if (valSrcScores.size() == 1) @@ -133,12 +133,12 @@ namespace Lucene score *= *srcScore; return score; } - + double CustomScoreQuery::customScore(int32_t doc, double subQueryScore, double valSrcScore) { return subQueryScore * valSrcScore; } - + ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) { if (valSrcExpls.size() == 1) @@ -154,7 +154,7 @@ namespace Lucene exp->addDetail(*srcExpl); return exp; } - + ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) { double valSrcScore = 1; @@ -165,56 +165,56 @@ namespace Lucene exp->addDetail(valSrcExpl); return exp; } - + WeightPtr CustomScoreQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + bool CustomScoreQuery::isStrict() { return strict; } - + void CustomScoreQuery::setStrict(bool strict) { this->strict = strict; } - + String CustomScoreQuery::name() { return L"custom"; } - + DefaultCustomScoreProvider::DefaultCustomScoreProvider(CustomScoreQueryPtr customQuery, IndexReaderPtr reader) : CustomScoreProvider(reader) { _customQuery = customQuery; } - + DefaultCustomScoreProvider::~DefaultCustomScoreProvider() { } - + double DefaultCustomScoreProvider::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) { return CustomScoreQueryPtr(_customQuery)->customScore(doc, subQueryScore, valSrcScores); } - + double DefaultCustomScoreProvider::customScore(int32_t doc, double subQueryScore, double valSrcScore) { return CustomScoreQueryPtr(_customQuery)->customScore(doc, subQueryScore, valSrcScore); } - + ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) { return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpls); } - + ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) { return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpl); } - + CustomWeight::CustomWeight(CustomScoreQueryPtr query, SearcherPtr searcher) { this->query = query; @@ -225,21 +225,21 @@ namespace Lucene this->valSrcWeights[i] = query->valSrcQueries[i]->createWeight(searcher); this->qStrict = query->strict; } - + CustomWeight::~CustomWeight() { } - + QueryPtr CustomWeight::getQuery() { return query; } - + double CustomWeight::getValue() { return query->getBoost(); } - + double CustomWeight::sumOfSquaredWeights() { double sum = subQueryWeight->sumOfSquaredWeights(); @@ -253,7 +253,7 @@ namespace Lucene sum *= query->getBoost() * query->getBoost(); // boost each sub-weight return sum; } - + void CustomWeight::normalize(double norm) { norm *= query->getBoost(); // incorporate boost @@ -266,7 +266,7 @@ namespace Lucene valSrcWeights[i]->normalize(norm); } } - + ScorerPtr CustomWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { // Pass true for "scoresDocsInOrder", because we require in-order scoring, even if caller does not, @@ -280,13 +280,13 @@ namespace Lucene valSrcScorers[i] = valSrcWeights[i]->scorer(reader, true, topScorer); return newLucene(similarity, reader, shared_from_this(), subQueryScorer, valSrcScorers); } - + ExplanationPtr CustomWeight::explain(IndexReaderPtr reader, int32_t doc) { ExplanationPtr explain(doExplain(reader, doc)); return explain ? explain : newLucene(0.0, L"no matching docs"); } - + ExplanationPtr CustomWeight::doExplain(IndexReaderPtr reader, int32_t doc) { ExplanationPtr subQueryExpl(subQueryWeight->explain(reader, doc)); @@ -303,12 +303,12 @@ namespace Lucene res->addDetail(newLucene(getValue(), L"queryBoost")); // actually using the q boost as q weight (== weight value) return res; } - + bool CustomWeight::scoresDocsOutOfOrder() { return false; } - + CustomScorer::CustomScorer(SimilarityPtr similarity, IndexReaderPtr reader, CustomWeightPtr weight, ScorerPtr subQueryScorer, Collection valSrcScorers) : Scorer(similarity) { this->qWeight = weight->getValue(); @@ -318,11 +318,11 @@ namespace Lucene this->vScores = Collection::newInstance(valSrcScorers.size()); this->provider = weight->query->getCustomScoreProvider(reader); } - + CustomScorer::~CustomScorer() { } - + int32_t CustomScorer::nextDoc() { int32_t doc = subQueryScorer->nextDoc(); @@ -333,19 +333,19 @@ namespace Lucene } return doc; } - + int32_t CustomScorer::docID() { return subQueryScorer->docID(); } - + double CustomScorer::score() { for (int32_t i = 0; i < valSrcScorers.size(); ++i) vScores[i] = valSrcScorers[i]->score(); return qWeight * provider->customScore(subQueryScorer->docID(), subQueryScorer->score(), vScores); } - + int32_t CustomScorer::advance(int32_t target) { int32_t doc = subQueryScorer->advance(target); diff --git a/src/core/search/function/DocValues.cpp b/src/core/search/function/DocValues.cpp index 94ac8716..1a798450 100644 --- a/src/core/search/function/DocValues.cpp +++ b/src/core/search/function/DocValues.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,37 +20,37 @@ namespace Lucene avgVal = std::numeric_limits::quiet_NaN(); computed = false; } - + DocValues::~DocValues() { } - + int32_t DocValues::intVal(int32_t doc) { return (int32_t)doubleVal(doc); } - + int64_t DocValues::longVal(int32_t doc) { return (int64_t)doubleVal(doc); } - + String DocValues::strVal(int32_t doc) { return StringUtils::toString(doubleVal(doc)); } - + ExplanationPtr DocValues::explain(int32_t doc) { return newLucene(doubleVal(doc), toString(doc)); } - + CollectionValue DocValues::getInnerArray() { boost::throw_exception(UnsupportedOperationException(L"This optional method is for test purposes only")); return VariantUtils::null(); } - + void DocValues::compute() { if (computed) @@ -73,23 +73,23 @@ namespace Lucene maxVal = MiscUtils::isNaN(maxVal) ? val : std::max(maxVal, val); ++n; } - + avgVal = n == 0 ? std::numeric_limits::quiet_NaN() : sum / (double)n; computed = true; } - + double DocValues::getMinValue() { compute(); return minVal; } - + double DocValues::getMaxValue() { compute(); return maxVal; } - + double DocValues::getAverageValue() { compute(); diff --git a/src/core/search/function/DoubleFieldSource.cpp b/src/core/search/function/DoubleFieldSource.cpp index ead5194e..853e6aca 100644 --- a/src/core/search/function/DoubleFieldSource.cpp +++ b/src/core/search/function/DoubleFieldSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,22 +16,22 @@ namespace Lucene { this->parser = parser; } - + DoubleFieldSource::~DoubleFieldSource() { } - + String DoubleFieldSource::description() { return L"double(" + FieldCacheSource::description() + L")"; } - + DocValuesPtr DoubleFieldSource::getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) { Collection arr(cache->getDoubles(reader, field, parser)); return newLucene(shared_from_this(), arr); } - + bool DoubleFieldSource::cachedFieldSourceEquals(FieldCacheSourcePtr other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) @@ -41,34 +41,34 @@ namespace Lucene return false; return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; } - + int32_t DoubleFieldSource::cachedFieldSourceHashCode() { return StringUtils::hashCode(parser ? DoubleParser::_getClassName() : DoubleFieldSource::_getClassName()); } - + DoubleDocValues::DoubleDocValues(DoubleFieldSourcePtr source, Collection arr) { this->_source = source; this->arr = arr; } - + DoubleDocValues::~DoubleDocValues() { } - + double DoubleDocValues::doubleVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); return arr[doc]; } - + String DoubleDocValues::toString(int32_t doc) { return DoubleFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(doubleVal(doc)); } - + CollectionValue DoubleDocValues::getInnerArray() { return arr; diff --git a/src/core/search/function/FieldCacheSource.cpp b/src/core/search/function/FieldCacheSource.cpp index d9122ff2..082d5e91 100644 --- a/src/core/search/function/FieldCacheSource.cpp +++ b/src/core/search/function/FieldCacheSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,21 +15,21 @@ namespace Lucene { this->field = field; } - + FieldCacheSource::~FieldCacheSource() { } - + DocValuesPtr FieldCacheSource::getValues(IndexReaderPtr reader) { return getCachedFieldValues(FieldCache::DEFAULT(), field, reader); } - + String FieldCacheSource::description() { return field; } - + bool FieldCacheSource::equals(LuceneObjectPtr other) { FieldCacheSourcePtr otherSource(boost::dynamic_pointer_cast(other)); @@ -37,7 +37,7 @@ namespace Lucene return false; return field == otherSource->field && cachedFieldSourceEquals(otherSource); } - + int32_t FieldCacheSource::hashCode() { return StringUtils::hashCode(field) + cachedFieldSourceHashCode(); diff --git a/src/core/search/function/FieldScoreQuery.cpp b/src/core/search/function/FieldScoreQuery.cpp index 677a4740..a9c3f6e7 100644 --- a/src/core/search/function/FieldScoreQuery.cpp +++ b/src/core/search/function/FieldScoreQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,11 +15,11 @@ namespace Lucene FieldScoreQuery::FieldScoreQuery(const String& field, Type type) : ValueSourceQuery(getValueSource(field,type)) { } - + FieldScoreQuery::~FieldScoreQuery() { } - + ValueSourcePtr FieldScoreQuery::getValueSource(const String& field, Type type) { switch (type) diff --git a/src/core/search/function/IntFieldSource.cpp b/src/core/search/function/IntFieldSource.cpp index 64f12a11..08581ea6 100644 --- a/src/core/search/function/IntFieldSource.cpp +++ b/src/core/search/function/IntFieldSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,22 +17,22 @@ namespace Lucene { this->parser = parser; } - + IntFieldSource::~IntFieldSource() { } - + String IntFieldSource::description() { return L"int(" + FieldCacheSource::description() + L")"; } - + DocValuesPtr IntFieldSource::getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) { Collection arr(cache->getInts(reader, field, parser)); return newLucene(shared_from_this(), arr); } - + bool IntFieldSource::cachedFieldSourceEquals(FieldCacheSourcePtr other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) @@ -42,41 +42,41 @@ namespace Lucene return false; return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; } - + int32_t IntFieldSource::cachedFieldSourceHashCode() { return StringUtils::hashCode(parser ? IntParser::_getClassName() : IntFieldSource::_getClassName()); } - + IntDocValues::IntDocValues(IntFieldSourcePtr source, Collection arr) { this->_source = source; this->arr = arr; } - + IntDocValues::~IntDocValues() { } - + double IntDocValues::doubleVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); return (double)arr[doc]; } - + int32_t IntDocValues::intVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); return arr[doc]; } - + String IntDocValues::toString(int32_t doc) { return IntFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); } - + CollectionValue IntDocValues::getInnerArray() { return arr; diff --git a/src/core/search/function/OrdFieldSource.cpp b/src/core/search/function/OrdFieldSource.cpp index 5f76a18c..24a30ef1 100644 --- a/src/core/search/function/OrdFieldSource.cpp +++ b/src/core/search/function/OrdFieldSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,22 +17,22 @@ namespace Lucene { this->field = field; } - + OrdFieldSource::~OrdFieldSource() { } - + String OrdFieldSource::description() { return L"ord(" + field + L")"; } - + DocValuesPtr OrdFieldSource::getValues(IndexReaderPtr reader) { Collection arr(FieldCache::DEFAULT()->getStringIndex(reader, field)->order); return newLucene(shared_from_this(), arr); } - + bool OrdFieldSource::equals(LuceneObjectPtr other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) @@ -42,29 +42,29 @@ namespace Lucene return false; return field == otherSource->field; } - + int32_t OrdFieldSource::hashCode() { return StringUtils::hashCode(OrdFieldSource::_getClassName()) + StringUtils::hashCode(field); } - + OrdDocValues::OrdDocValues(OrdFieldSourcePtr source, Collection arr) { this->_source = source; this->arr = arr; } - + OrdDocValues::~OrdDocValues() { } - + double OrdDocValues::doubleVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); return (double)arr[doc]; } - + String OrdDocValues::strVal(int32_t doc) { // the string value of the ordinal, not the string itself @@ -72,12 +72,12 @@ namespace Lucene boost::throw_exception(IndexOutOfBoundsException()); return StringUtils::toString(arr[doc]); } - + String OrdDocValues::toString(int32_t doc) { return OrdFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); } - + CollectionValue OrdDocValues::getInnerArray() { return arr; diff --git a/src/core/search/function/ReverseOrdFieldSource.cpp b/src/core/search/function/ReverseOrdFieldSource.cpp index 0464a9e6..3463f362 100644 --- a/src/core/search/function/ReverseOrdFieldSource.cpp +++ b/src/core/search/function/ReverseOrdFieldSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,16 +17,16 @@ namespace Lucene { this->field = field; } - + ReverseOrdFieldSource::~ReverseOrdFieldSource() { } - + String ReverseOrdFieldSource::description() { return L"rord(" + field + L")"; } - + DocValuesPtr ReverseOrdFieldSource::getValues(IndexReaderPtr reader) { StringIndexPtr sindex(FieldCache::DEFAULT()->getStringIndex(reader, field)); @@ -34,7 +34,7 @@ namespace Lucene int32_t end = sindex->lookup.size(); return newLucene(shared_from_this(), arr, end); } - + bool ReverseOrdFieldSource::equals(LuceneObjectPtr other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) @@ -44,48 +44,48 @@ namespace Lucene return false; return field == otherSource->field; } - + int32_t ReverseOrdFieldSource::hashCode() { return StringUtils::hashCode(ReverseOrdFieldSource::_getClassName()) + StringUtils::hashCode(field); } - + ReverseOrdDocValues::ReverseOrdDocValues(ReverseOrdFieldSourcePtr source, Collection arr, int32_t end) { this->_source = source; this->arr = arr; this->end = end; } - + ReverseOrdDocValues::~ReverseOrdDocValues() { } - + double ReverseOrdDocValues::doubleVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); return (double)(end - arr[doc]); } - + int32_t ReverseOrdDocValues::intVal(int32_t doc) { if (doc < 0 || doc >= arr.size()) boost::throw_exception(IndexOutOfBoundsException()); return (end - arr[doc]); } - + String ReverseOrdDocValues::strVal(int32_t doc) { // the string value of the ordinal, not the string itself return StringUtils::toString(intVal(doc)); } - + String ReverseOrdDocValues::toString(int32_t doc) { return ReverseOrdFieldSourcePtr(_source)->description() + L"=" + strVal(doc); } - + CollectionValue ReverseOrdDocValues::getInnerArray() { return arr; diff --git a/src/core/search/function/ValueSource.cpp b/src/core/search/function/ValueSource.cpp index 2c80cf3f..b38f511f 100644 --- a/src/core/search/function/ValueSource.cpp +++ b/src/core/search/function/ValueSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene ValueSource::~ValueSource() { } - + String ValueSource::toString() { return description(); diff --git a/src/core/search/function/ValueSourceQuery.cpp b/src/core/search/function/ValueSourceQuery.cpp index 5ad06e2c..7e197a8b 100644 --- a/src/core/search/function/ValueSourceQuery.cpp +++ b/src/core/search/function/ValueSourceQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,31 +21,31 @@ namespace Lucene { this->valSrc = valSrc; } - + ValueSourceQuery::~ValueSourceQuery() { } - + QueryPtr ValueSourceQuery::rewrite(IndexReaderPtr reader) { return shared_from_this(); } - + void ValueSourceQuery::extractTerms(SetTerm terms) { // no terms involved here } - + WeightPtr ValueSourceQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + String ValueSourceQuery::toString(const String& field) { return valSrc->toString() + boostString(); } - + bool ValueSourceQuery::equals(LuceneObjectPtr other) { ValueSourceQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); @@ -53,12 +53,12 @@ namespace Lucene return false; return (getBoost() == otherQuery->getBoost() && valSrc->equals(otherQuery->valSrc)); } - + int32_t ValueSourceQuery::hashCode() { return (StringUtils::hashCode(ValueSourceQuery::_getClassName()) + valSrc->hashCode()) ^ MiscUtils::doubleToIntBits(getBoost()); } - + LuceneObjectPtr ValueSourceQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(valSrc); @@ -66,57 +66,57 @@ namespace Lucene cloneQuery->valSrc = valSrc; return cloneQuery; } - + ValueSourceWeight::ValueSourceWeight(ValueSourceQueryPtr query, SearcherPtr searcher) { this->query = query; this->similarity = query->getSimilarity(searcher); } - + ValueSourceWeight::~ValueSourceWeight() { } - + QueryPtr ValueSourceWeight::getQuery() { return query; } - + double ValueSourceWeight::getValue() { return queryWeight; } - + double ValueSourceWeight::sumOfSquaredWeights() { queryWeight = query->getBoost(); return queryWeight * queryWeight; } - + void ValueSourceWeight::normalize(double norm) { queryNorm = norm; queryWeight *= queryNorm; } - + ScorerPtr ValueSourceWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(similarity, reader, shared_from_this()); } - + ExplanationPtr ValueSourceWeight::explain(IndexReaderPtr reader, int32_t doc) { DocValuesPtr vals(query->valSrc->getValues(reader)); double sc = queryWeight * vals->doubleVal(doc); - + ExplanationPtr result(newLucene(true, sc, query->toString() + L", product of:")); - + result->addDetail(vals->explain(doc)); result->addDetail(newLucene(query->getBoost(), L"boost")); result->addDetail(newLucene(queryNorm, L"queryNorm")); return result; } - + ValueSourceScorer::ValueSourceScorer(SimilarityPtr similarity, IndexReaderPtr reader, ValueSourceWeightPtr weight) : Scorer(similarity) { this->weight = weight; @@ -126,28 +126,28 @@ namespace Lucene vals = weight->query->valSrc->getValues(reader); termDocs = reader->termDocs(TermPtr()); } - + ValueSourceScorer::~ValueSourceScorer() { } - + int32_t ValueSourceScorer::nextDoc() { doc = termDocs->next() ? termDocs->doc() : NO_MORE_DOCS; return doc; } - + int32_t ValueSourceScorer::docID() { return doc; } - + int32_t ValueSourceScorer::advance(int32_t target) { doc = termDocs->skipTo(target) ? termDocs->doc() : NO_MORE_DOCS; return doc; } - + double ValueSourceScorer::score() { return qWeight * vals->doubleVal(termDocs->doc()); diff --git a/src/core/search/payloads/AveragePayloadFunction.cpp b/src/core/search/payloads/AveragePayloadFunction.cpp index b98ad9d4..657faf7c 100644 --- a/src/core/search/payloads/AveragePayloadFunction.cpp +++ b/src/core/search/payloads/AveragePayloadFunction.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,18 +14,18 @@ namespace Lucene AveragePayloadFunction::~AveragePayloadFunction() { } - + double AveragePayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { return currentPayloadScore + currentScore; } - + double AveragePayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) { return numPayloadsSeen > 0 ? (payloadScore / (double)numPayloadsSeen) : 1.0; } - + int32_t AveragePayloadFunction::hashCode() { int32_t prime = 31; @@ -33,7 +33,7 @@ namespace Lucene result = prime * result + StringUtils::hashCode(getClassName()); return result; } - + bool AveragePayloadFunction::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) diff --git a/src/core/search/payloads/MaxPayloadFunction.cpp b/src/core/search/payloads/MaxPayloadFunction.cpp index a3bf6648..f8f411ac 100644 --- a/src/core/search/payloads/MaxPayloadFunction.cpp +++ b/src/core/search/payloads/MaxPayloadFunction.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene MaxPayloadFunction::~MaxPayloadFunction() { } - + double MaxPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { @@ -23,12 +23,12 @@ namespace Lucene else return std::max(currentPayloadScore, currentScore); } - + double MaxPayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) { return numPayloadsSeen > 0 ? payloadScore : 1.0; } - + int32_t MaxPayloadFunction::hashCode() { int32_t prime = 31; @@ -36,7 +36,7 @@ namespace Lucene result = prime * result + StringUtils::hashCode(getClassName()); return result; } - + bool MaxPayloadFunction::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) diff --git a/src/core/search/payloads/MinPayloadFunction.cpp b/src/core/search/payloads/MinPayloadFunction.cpp index d6ce41eb..5c695d00 100644 --- a/src/core/search/payloads/MinPayloadFunction.cpp +++ b/src/core/search/payloads/MinPayloadFunction.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,7 +14,7 @@ namespace Lucene MinPayloadFunction::~MinPayloadFunction() { } - + double MinPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { @@ -23,12 +23,12 @@ namespace Lucene else return std::min(currentPayloadScore, currentScore); } - + double MinPayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) { return numPayloadsSeen > 0 ? payloadScore : 1.0; } - + int32_t MinPayloadFunction::hashCode() { int32_t prime = 31; @@ -36,7 +36,7 @@ namespace Lucene result = prime * result + StringUtils::hashCode(getClassName()); return result; } - + bool MinPayloadFunction::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) diff --git a/src/core/search/payloads/PayloadFunction.cpp b/src/core/search/payloads/PayloadFunction.cpp index ea1d07ff..7e458ab8 100644 --- a/src/core/search/payloads/PayloadFunction.cpp +++ b/src/core/search/payloads/PayloadFunction.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/search/payloads/PayloadNearQuery.cpp b/src/core/search/payloads/PayloadNearQuery.cpp index 64467eee..f30d2f1a 100644 --- a/src/core/search/payloads/PayloadNearQuery.cpp +++ b/src/core/search/payloads/PayloadNearQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -21,35 +21,35 @@ namespace Lucene fieldName = clauses[0]->getField(); // all clauses must have same field this->function = newLucene(); } - + PayloadNearQuery::PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, PayloadFunctionPtr function) : SpanNearQuery(clauses, slop, inOrder) { fieldName = clauses[0]->getField(); // all clauses must have same field this->function = function; } - + PayloadNearQuery::~PayloadNearQuery() { } - + WeightPtr PayloadNearQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + LuceneObjectPtr PayloadNearQuery::clone(LuceneObjectPtr other) { int32_t sz = clauses.size(); Collection newClauses(Collection::newInstance(sz)); - + for (int32_t i = 0; i < sz; ++i) newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); - + PayloadNearQueryPtr payloadNearQuery(newLucene(newClauses, slop, inOrder)); payloadNearQuery->setBoost(getBoost()); return payloadNearQuery; } - + String PayloadNearQuery::toString(const String& field) { StringStream buffer; @@ -63,7 +63,7 @@ namespace Lucene buffer << L"], " << slop << L", " << inOrder << L")" << boostString(); return buffer.str(); } - + bool PayloadNearQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -81,12 +81,12 @@ namespace Lucene { if (otherQuery->function) return false; - } + } else if (!function->equals(otherQuery->function)) return false; return true; } - + int32_t PayloadNearQuery::hashCode() { int32_t prime = 31; @@ -95,20 +95,20 @@ namespace Lucene result = prime * result + (!function ? 0 : function->hashCode()); return result; } - + PayloadNearSpanWeight::PayloadNearSpanWeight(SpanQueryPtr query, SearcherPtr searcher) : SpanWeight(query, searcher) { } - + PayloadNearSpanWeight::~PayloadNearSpanWeight() { } - + ScorerPtr PayloadNearSpanWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); } - + PayloadNearSpanScorer::PayloadNearSpanScorer(SpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) { this->spans = spans; @@ -116,11 +116,11 @@ namespace Lucene this->payloadsSeen = 0; this->similarity = getSimilarity(); } - + PayloadNearSpanScorer::~PayloadNearSpanScorer() { } - + void PayloadNearSpanScorer::getPayloads(Collection subSpans) { for (Collection::iterator span = subSpans.begin(); span != subSpans.end(); ++span) @@ -141,21 +141,21 @@ namespace Lucene } } } - + void PayloadNearSpanScorer::processPayloads(Collection payLoads, int32_t start, int32_t end) { PayloadNearSpanWeightPtr spanWeight(boost::static_pointer_cast(weight)); PayloadNearQueryPtr nearQuery(boost::static_pointer_cast(spanWeight->query)); - + for (Collection::iterator payload = payLoads.begin(); payload != payLoads.end(); ++payload) { payloadScore = nearQuery->function->currentScore(doc, nearQuery->fieldName, start, end, payloadsSeen, payloadScore, - similarity->scorePayload(doc, nearQuery->fieldName, spans->start(), + similarity->scorePayload(doc, nearQuery->fieldName, spans->start(), spans->end(), *payload, 0, payload->size())); ++payloadsSeen; } } - + bool PayloadNearSpanScorer::setFreqCurrentDoc() { if (!more) @@ -166,14 +166,14 @@ namespace Lucene getPayloads(spansArr); return SpanScorer::setFreqCurrentDoc(); } - + double PayloadNearSpanScorer::score() { PayloadNearSpanWeightPtr spanWeight(boost::static_pointer_cast(weight)); PayloadNearQueryPtr nearQuery(boost::static_pointer_cast(spanWeight->query)); return SpanScorer::score() * nearQuery->function->docScore(doc, nearQuery->fieldName, payloadsSeen, payloadScore); } - + ExplanationPtr PayloadNearSpanScorer::explain(int32_t doc) { ExplanationPtr result(newLucene()); diff --git a/src/core/search/payloads/PayloadSpanUtil.cpp b/src/core/search/payloads/PayloadSpanUtil.cpp index 510d46a3..f50c6296 100644 --- a/src/core/search/payloads/PayloadSpanUtil.cpp +++ b/src/core/search/payloads/PayloadSpanUtil.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -26,18 +26,18 @@ namespace Lucene { this->reader = reader; } - + PayloadSpanUtil::~PayloadSpanUtil() { } - + Collection PayloadSpanUtil::getPayloadsForQuery(QueryPtr query) { Collection payloads(Collection::newInstance()); queryToSpanQuery(query, payloads); return payloads; } - + void PayloadSpanUtil::queryToSpanQuery(QueryPtr query, Collection payloads) { if (MiscUtils::typeOf(query)) @@ -57,13 +57,13 @@ namespace Lucene Collection clauses(Collection::newInstance(phraseQueryTerms.size())); for (int32_t i = 0; i < phraseQueryTerms.size(); ++i) clauses[i] = newLucene(phraseQueryTerms[i]); - + int32_t slop = phraseQuery->getSlop(); bool inorder = false; - + if (slop == 0) inorder = true; - + SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); sp->setBoost(query->getBoost()); getPayloads(payloads, sp); @@ -104,10 +104,10 @@ namespace Lucene if (positions[i] > maxPosition) maxPosition = positions[i]; } - + Collection< Collection > disjunctLists(Collection< Collection >::newInstance(maxPosition + 1)); int32_t distinctPositions = 0; - + for (int32_t i = 0; i < termArrays.size(); ++i) { Collection termArray(termArrays[i]); @@ -121,7 +121,7 @@ namespace Lucene for (Collection::iterator term = termArray.begin(); term != termArray.end(); ++term) disjuncts.add(newLucene(*term)); } - + int32_t positionGaps = 0; int32_t position = 0; Collection clauses(Collection::newInstance(distinctPositions)); @@ -138,21 +138,21 @@ namespace Lucene else ++positionGaps; } - + int32_t slop = multiphraseQuery->getSlop(); bool inorder = (slop == 0); - + SpanNearQueryPtr sp(newLucene(clauses, slop + positionGaps, inorder)); sp->setBoost(query->getBoost()); getPayloads(payloads, sp); } } } - + void PayloadSpanUtil::getPayloads(Collection payloads, SpanQueryPtr query) { SpansPtr spans(query->getSpans(reader)); - + while (spans->next()) { if (spans->isPayloadAvailable()) diff --git a/src/core/search/payloads/PayloadTermQuery.cpp b/src/core/search/payloads/PayloadTermQuery.cpp index 6ef2beb6..c6eafa5b 100644 --- a/src/core/search/payloads/PayloadTermQuery.cpp +++ b/src/core/search/payloads/PayloadTermQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,16 +23,16 @@ namespace Lucene this->function = function; this->includeSpanScore = includeSpanScore; } - + PayloadTermQuery::~PayloadTermQuery() { } - + WeightPtr PayloadTermQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); } - + LuceneObjectPtr PayloadTermQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term, function, includeSpanScore)); @@ -41,7 +41,7 @@ namespace Lucene termQuery->includeSpanScore = includeSpanScore; return termQuery; } - + bool PayloadTermQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -64,7 +64,7 @@ namespace Lucene return false; return true; } - + int32_t PayloadTermQuery::hashCode() { int32_t prime = 31; @@ -73,20 +73,20 @@ namespace Lucene result = prime * result + (includeSpanScore ? 1231 : 1237); return result; } - + PayloadTermWeight::PayloadTermWeight(PayloadTermQueryPtr query, SearcherPtr searcher) : SpanWeight(query, searcher) { } - + PayloadTermWeight::~PayloadTermWeight() { } - + ScorerPtr PayloadTermWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(boost::dynamic_pointer_cast(query->getSpans(reader)), shared_from_this(), similarity, reader->norms(query->getField())); } - + PayloadTermSpanScorer::PayloadTermSpanScorer(TermSpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) { positions = spans->getPositions(); @@ -94,11 +94,11 @@ namespace Lucene payloadScore = 0.0; payloadsSeen = 0; } - + PayloadTermSpanScorer::~PayloadTermSpanScorer() { } - + bool PayloadTermSpanScorer::setFreqCurrentDoc() { if (!more) @@ -111,26 +111,26 @@ namespace Lucene while (more && doc == spans->doc()) { int32_t matchLength = spans->end() - spans->start(); - + freq += similarity1->sloppyFreq(matchLength); processPayload(similarity1); - + more = spans->next(); // this moves positions to the next match in this document } return more || (freq != 0); } - + void PayloadTermSpanScorer::processPayload(SimilarityPtr similarity) { if (positions->isPayloadAvailable()) { PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); - + payload = positions->getPayload(payload, 0); payloadScore = payloadQuery->function->currentScore(doc, payloadQuery->term->field(), spans->start(), spans->end(), - payloadsSeen, payloadScore, similarity->scorePayload(doc, - payloadQuery->term->field(), spans->start(), spans->end(), + payloadsSeen, payloadScore, similarity->scorePayload(doc, + payloadQuery->term->field(), spans->start(), spans->end(), payload, 0, positions->getPayloadLength())); ++payloadsSeen; } @@ -139,43 +139,43 @@ namespace Lucene // zero out the payload? } } - + double PayloadTermSpanScorer::score() { PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); return payloadQuery->includeSpanScore ? getSpanScore() * getPayloadScore() : getPayloadScore(); } - + double PayloadTermSpanScorer::getSpanScore() { return SpanScorer::score(); } - + double PayloadTermSpanScorer::getPayloadScore() { PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); return payloadQuery->function->docScore(doc, payloadQuery->term->field(), payloadsSeen, payloadScore); } - + ExplanationPtr PayloadTermSpanScorer::explain(int32_t doc) { ComplexExplanationPtr result(newLucene()); ExplanationPtr nonPayloadExpl(SpanScorer::explain(doc)); result->addDetail(nonPayloadExpl); - + ExplanationPtr payloadBoost(newLucene()); result->addDetail(payloadBoost); - + double payloadScore = getPayloadScore(); payloadBoost->setValue(payloadScore); payloadBoost->setDescription(L"scorePayload(...)"); - + result->setValue(nonPayloadExpl->getValue() * payloadScore); result->setDescription(L"btq, product of:"); result->setMatch(nonPayloadExpl->getValue() != 0.0); - + return result; } } diff --git a/src/core/search/spans/FieldMaskingSpanQuery.cpp b/src/core/search/spans/FieldMaskingSpanQuery.cpp index f1b902d1..d51c6d79 100644 --- a/src/core/search/spans/FieldMaskingSpanQuery.cpp +++ b/src/core/search/spans/FieldMaskingSpanQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,61 +16,61 @@ namespace Lucene this->maskedQuery = maskedQuery; this->field = maskedField; } - + FieldMaskingSpanQuery::~FieldMaskingSpanQuery() { } - + String FieldMaskingSpanQuery::getField() { return field; } - + SpanQueryPtr FieldMaskingSpanQuery::getMaskedQuery() { return maskedQuery; } - + // :NOTE: getBoost and setBoost are not proxied to the maskedQuery // ...this is done to be more consistent with things like SpanFirstQuery - + SpansPtr FieldMaskingSpanQuery::getSpans(IndexReaderPtr reader) { return maskedQuery->getSpans(reader); } - + void FieldMaskingSpanQuery::extractTerms(SetTerm terms) { maskedQuery->extractTerms(terms); } - + WeightPtr FieldMaskingSpanQuery::createWeight(SearcherPtr searcher) { return maskedQuery->createWeight(searcher); } - + SimilarityPtr FieldMaskingSpanQuery::getSimilarity(SearcherPtr searcher) { return maskedQuery->getSimilarity(searcher); } - + QueryPtr FieldMaskingSpanQuery::rewrite(IndexReaderPtr reader) { FieldMaskingSpanQueryPtr clone; - + SpanQueryPtr rewritten(boost::dynamic_pointer_cast(maskedQuery->rewrite(reader))); if (rewritten != maskedQuery) { clone = boost::dynamic_pointer_cast(this->clone()); clone->maskedQuery = rewritten; } - + if (clone) return clone; else return shared_from_this(); } - + String FieldMaskingSpanQuery::toString(const String& field) { StringStream buffer; @@ -78,25 +78,25 @@ namespace Lucene buffer << boostString() << L" as " << this->field; return buffer.str(); } - + bool FieldMaskingSpanQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + FieldMaskingSpanQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) return false; - - return (getField() == otherQuery->getField() && getBoost() == otherQuery->getBoost() && + + return (getField() == otherQuery->getField() && getBoost() == otherQuery->getBoost() && getMaskedQuery()->equals(otherQuery->getMaskedQuery())); } - + int32_t FieldMaskingSpanQuery::hashCode() { return getMaskedQuery()->hashCode() ^ StringUtils::hashCode(getField()) ^ MiscUtils::doubleToRawIntBits(getBoost()); } - + LuceneObjectPtr FieldMaskingSpanQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(maskedQuery, field)); diff --git a/src/core/search/spans/NearSpansOrdered.cpp b/src/core/search/spans/NearSpansOrdered.cpp index e53e470c..abfefe90 100644 --- a/src/core/search/spans/NearSpansOrdered.cpp +++ b/src/core/search/spans/NearSpansOrdered.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -33,41 +33,41 @@ namespace Lucene } this->query = spanNearQuery; // kept for toString() only. } - + NearSpansOrdered::~NearSpansOrdered() { } - + int32_t NearSpansOrdered::doc() { return matchDoc; } - + int32_t NearSpansOrdered::start() { return matchStart; } - + int32_t NearSpansOrdered::end() { return matchEnd; } - + Collection NearSpansOrdered::getSubSpans() { return subSpans; } - + Collection NearSpansOrdered::getPayload() { return matchPayload; } - + bool NearSpansOrdered::isPayloadAvailable() { return !matchPayload.empty(); } - + bool NearSpansOrdered::next() { if (firstTime) @@ -87,7 +87,7 @@ namespace Lucene matchPayload.clear(); return advanceAfterOrdered(); } - + bool NearSpansOrdered::skipTo(int32_t target) { if (firstTime) @@ -117,7 +117,7 @@ namespace Lucene matchPayload.clear(); return advanceAfterOrdered(); } - + bool NearSpansOrdered::advanceAfterOrdered() { while (more && (inSameDoc || toSameDoc())) @@ -127,7 +127,7 @@ namespace Lucene } return false; // no more matches } - + struct lessSpanDoc { inline bool operator()(const SpansPtr& first, const SpansPtr& second) const @@ -135,7 +135,7 @@ namespace Lucene return ((first->doc() - second->doc()) < 0); } }; - + bool NearSpansOrdered::toSameDoc() { std::sort(subSpansByDoc.begin(), subSpansByDoc.end(), lessSpanDoc()); @@ -160,7 +160,7 @@ namespace Lucene inSameDoc = true; return true; } - + bool NearSpansOrdered::docSpansOrdered(SpansPtr spans1, SpansPtr spans2) { BOOST_ASSERT(spans1->doc() == spans2->doc()); @@ -169,12 +169,12 @@ namespace Lucene // Do not call docSpansOrdered(int,int,int,int) to avoid invoking .end() return start1 == start2 ? (spans1->end() < spans2->end()) : (start1 < start2); } - + bool NearSpansOrdered::docSpansOrdered(int32_t start1, int32_t end1, int32_t start2, int32_t end2) { return start1 == start2 ? (end1 < end2) : (start1 < start2); } - + bool NearSpansOrdered::stretchToOrder() { matchDoc = subSpans[0]->doc(); @@ -197,7 +197,7 @@ namespace Lucene } return inSameDoc; } - + bool NearSpansOrdered::shrinkToAfterShortestMatch() { SpansPtr subSpan(subSpans[subSpans.size() - 1]); @@ -209,9 +209,9 @@ namespace Lucene Collection payload(subSpan->getPayload()); possibleMatchPayloads.addAll(payload.begin(), payload.end()); } - + Collection possiblePayload; - + int32_t matchSlop = 0; int32_t lastStart = matchStart; int32_t lastEnd = matchEnd; @@ -223,7 +223,7 @@ namespace Lucene Collection payload(prevSpans->getPayload()); possiblePayload = Collection::newInstance(payload.begin(), payload.end()); } - + int32_t prevStart = prevSpans->start(); int32_t prevEnd = prevSpans->end(); while (true) // Advance prevSpans until after (lastStart, lastEnd) @@ -257,29 +257,29 @@ namespace Lucene } } } - + if (collectPayloads && possiblePayload) possibleMatchPayloads.addAll(possiblePayload.begin(), possiblePayload.end()); - + BOOST_ASSERT(prevStart <= matchStart); if (matchStart > prevEnd) // Only non overlapping spans add to slop. matchSlop += (matchStart - prevEnd); - - // Do not break on (matchSlop > allowedSlop) here to make sure that subSpans[0] is + + // Do not break on (matchSlop > allowedSlop) here to make sure that subSpans[0] is // advanced after the match, if any. matchStart = prevStart; lastStart = prevStart; lastEnd = prevEnd; } - + bool match = (matchSlop <= allowedSlop); - + if (collectPayloads && match && !possibleMatchPayloads.empty()) matchPayload.addAll(possibleMatchPayloads.begin(), possibleMatchPayloads.end()); - + return match; // ordered and allowed slop } - + String NearSpansOrdered::toString() { StringStream buffer; diff --git a/src/core/search/spans/NearSpansUnordered.cpp b/src/core/search/spans/NearSpansUnordered.cpp index fd494e55..664d3096 100644 --- a/src/core/search/spans/NearSpansUnordered.cpp +++ b/src/core/search/spans/NearSpansUnordered.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,23 +18,23 @@ namespace Lucene this->query = query; this->reader = reader; } - + NearSpansUnordered::~NearSpansUnordered() { } - + void NearSpansUnordered::initialize() { this->slop = query->getSlop(); this->totalLength = 0; this->more = true; this->firstTime = true; - + Collection clauses(query->getClauses()); queue = newLucene(clauses.size()); subSpans = Collection::newInstance(clauses.size()); ordered = Collection::newInstance(); - + for (int32_t i = 0; i < clauses.size(); ++i) { SpansCellPtr cell(newLucene(shared_from_this(), clauses[i]->getSpans(reader), i)); @@ -42,12 +42,12 @@ namespace Lucene subSpans[i] = cell->spans; } } - + Collection NearSpansUnordered::getSubSpans() { return subSpans; } - + bool NearSpansUnordered::next() { if (firstTime) @@ -63,47 +63,47 @@ namespace Lucene else more = false; } - + while (more) { bool queueStale = false; - + if (min()->doc() != max->doc()) // maintain list { queueToList(); queueStale = true; } - + // skip to doc with all clauses - + while (more && first->doc() < last->doc()) { more = first->skipTo(last->doc()); // skip first upto last firstToLast(); // and move it to the end queueStale = true; } - + if (!more) return false; - + // found doc with all clauses - + if (queueStale) // maintain the queue { listToQueue(); queueStale = false; } - + if (atMatch()) return true; - + more = min()->next(); if (more) queue->updateTop(); // maintain queue } return false; // no more matches } - + bool NearSpansUnordered::skipTo(int32_t target) { if (firstTime) // initialize @@ -127,27 +127,27 @@ namespace Lucene } return (more && (atMatch() || next())); } - + SpansCellPtr NearSpansUnordered::min() { return queue->top(); } - + int32_t NearSpansUnordered::doc() { return min()->doc(); } - + int32_t NearSpansUnordered::start() { return min()->start(); } - + int32_t NearSpansUnordered::end() { return max->end(); } - + Collection NearSpansUnordered::getPayload() { SetByteArray matchPayload(SetByteArray::newInstance()); @@ -161,7 +161,7 @@ namespace Lucene } return Collection::newInstance(matchPayload.begin(), matchPayload.end()); } - + bool NearSpansUnordered::isPayloadAvailable() { SpansCellPtr pointer(min()); @@ -173,7 +173,7 @@ namespace Lucene } return false; } - + String NearSpansUnordered::toString() { StringStream buffer; @@ -189,7 +189,7 @@ namespace Lucene } return buffer.str(); } - + void NearSpansUnordered::initList(bool next) { for (Collection::iterator cell = ordered.begin(); more && cell != ordered.end(); ++cell) @@ -200,7 +200,7 @@ namespace Lucene addToList(*cell); // add to list } } - + void NearSpansUnordered::addToList(SpansCellPtr cell) { if (last) // add next to end of list @@ -210,7 +210,7 @@ namespace Lucene last = cell; cell->_next.reset(); } - + void NearSpansUnordered::firstToLast() { last->_next = first; // move first to end of list @@ -218,7 +218,7 @@ namespace Lucene first = first->_next; last->_next.reset(); } - + void NearSpansUnordered::queueToList() { first.reset(); @@ -226,19 +226,19 @@ namespace Lucene while (queue->top()) addToList(queue->pop()); } - + void NearSpansUnordered::listToQueue() { queue->clear(); // rebuild queue for (SpansCellPtr cell(first); cell; cell = cell->_next) queue->add(cell); // add to queue from list } - + bool NearSpansUnordered::atMatch() { return ((min()->doc() == max->doc()) && ((max->end() - min()->start() - totalLength) <= slop)); } - + SpansCell::SpansCell(NearSpansUnorderedPtr unordered, SpansPtr spans, int32_t index) { this->_unordered = unordered; @@ -246,21 +246,21 @@ namespace Lucene this->index = index; this->length = -1; } - + SpansCell::~SpansCell() { } - + bool SpansCell::next() { return adjust(spans->next()); } - + bool SpansCell::skipTo(int32_t target) { return adjust(spans->skipTo(target)); } - + bool SpansCell::adjust(bool condition) { NearSpansUnorderedPtr unordered(_unordered); @@ -270,53 +270,53 @@ namespace Lucene { length = end() - start(); unordered->totalLength += length; // add new length - + if (!unordered->max || doc() > unordered->max->doc() || (doc() == unordered->max->doc()) && (end() > unordered->max->end())) unordered->max = shared_from_this(); } unordered->more = condition; return condition; } - + int32_t SpansCell::doc() { return spans->doc(); } - + int32_t SpansCell::start() { return spans->start(); } - + int32_t SpansCell::end() { return spans->end(); } - + Collection SpansCell::getPayload() { Collection payload(spans->getPayload()); return Collection::newInstance(payload.begin(), payload.end()); } - + bool SpansCell::isPayloadAvailable() { return spans->isPayloadAvailable(); } - + String SpansCell::toString() { return spans->toString() + L"#" + StringUtils::toString(index); } - + CellQueue::CellQueue(int32_t size) : PriorityQueue(size) { } - + CellQueue::~CellQueue() { } - + bool CellQueue::lessThan(const SpansCellPtr& first, const SpansCellPtr& second) { if (first->doc() == second->doc()) diff --git a/src/core/search/spans/SpanFirstQuery.cpp b/src/core/search/spans/SpanFirstQuery.cpp index 562d3b65..a5482ee6 100644 --- a/src/core/search/spans/SpanFirstQuery.cpp +++ b/src/core/search/spans/SpanFirstQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,33 +17,33 @@ namespace Lucene this->match = match; this->end = end; } - + SpanFirstQuery::~SpanFirstQuery() { } - + SpanQueryPtr SpanFirstQuery::getMatch() { return match; } - + int32_t SpanFirstQuery::getEnd() { return end; } - + String SpanFirstQuery::getField() { return match->getField(); } - + String SpanFirstQuery::toString(const String& field) { StringStream buffer; buffer << L"spanFirst(" << match->toString(field) << L", " << end << L")" << boostString(); return buffer.str(); } - + LuceneObjectPtr SpanFirstQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(boost::dynamic_pointer_cast(match->clone()), end)); @@ -53,17 +53,17 @@ namespace Lucene spanFirstQuery->setBoost(getBoost()); return spanFirstQuery; } - + void SpanFirstQuery::extractTerms(SetTerm terms) { match->extractTerms(terms); } - + SpansPtr SpanFirstQuery::getSpans(IndexReaderPtr reader) { return newLucene(shared_from_this(), match->getSpans(reader)); } - + QueryPtr SpanFirstQuery::rewrite(IndexReaderPtr reader) { SpanFirstQueryPtr clone; @@ -73,25 +73,25 @@ namespace Lucene clone = boost::dynamic_pointer_cast(this->clone()); clone->match = rewritten; } - + if (clone) return clone; // some clauses rewrote else return shared_from_this(); // no clauses rewrote } - + bool SpanFirstQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + SpanFirstQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) return false; - + return (end == otherQuery->end && match->equals(otherQuery->match) && getBoost() == otherQuery->getBoost()); } - + int32_t SpanFirstQuery::hashCode() { int32_t result = match->hashCode(); @@ -99,17 +99,17 @@ namespace Lucene result ^= MiscUtils::doubleToRawIntBits(getBoost()) ^ end; return result; } - + FirstSpans::FirstSpans(SpanFirstQueryPtr query, SpansPtr spans) { this->query = query; this->spans = spans; } - + FirstSpans::~FirstSpans() { } - + bool FirstSpans::next() { while (spans->next()) // scan to next match @@ -119,29 +119,29 @@ namespace Lucene } return false; } - + bool FirstSpans::skipTo(int32_t target) { if (!spans->skipTo(target)) return false; return (spans->end() <= query->end || next()); } - + int32_t FirstSpans::doc() { return spans->doc(); } - + int32_t FirstSpans::start() { return spans->start(); } - + int32_t FirstSpans::end() { return spans->end(); } - + Collection FirstSpans::getPayload() { Collection result; @@ -152,7 +152,7 @@ namespace Lucene } return result; } - + bool FirstSpans::isPayloadAvailable() { return spans->isPayloadAvailable(); diff --git a/src/core/search/spans/SpanNearQuery.cpp b/src/core/search/spans/SpanNearQuery.cpp index 14654a55..687950f2 100644 --- a/src/core/search/spans/SpanNearQuery.cpp +++ b/src/core/search/spans/SpanNearQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -30,37 +30,37 @@ namespace Lucene this->slop = slop; this->inOrder = inOrder; } - + SpanNearQuery::~SpanNearQuery() { } - + Collection SpanNearQuery::getClauses() { return clauses; } - + int32_t SpanNearQuery::getSlop() { return slop; } - + bool SpanNearQuery::isInOrder() { return inOrder; } - + String SpanNearQuery::getField() { return field; } - + void SpanNearQuery::extractTerms(SetTerm terms) { for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) (*clause)->extractTerms(terms); } - + String SpanNearQuery::toString(const String& field) { StringStream buffer; @@ -74,20 +74,20 @@ namespace Lucene buffer << L"], " << slop << L", " << inOrder << L")" << boostString(); return buffer.str(); } - + SpansPtr SpanNearQuery::getSpans(IndexReaderPtr reader) { if (clauses.empty()) // optimize 0-clause case return newLucene(getClauses())->getSpans(reader); - + if (clauses.size() == 1) // optimize 1-clause case return clauses[0]->getSpans(reader); - + return inOrder ? boost::static_pointer_cast(newLucene(shared_from_this(), reader, collectPayloads)) : boost::static_pointer_cast(newLucene(shared_from_this(), reader)); } - + QueryPtr SpanNearQuery::rewrite(IndexReaderPtr reader) { SpanNearQueryPtr clone; @@ -107,43 +107,43 @@ namespace Lucene else return shared_from_this(); // no clauses rewrote } - + LuceneObjectPtr SpanNearQuery::clone(LuceneObjectPtr other) { int32_t sz = clauses.size(); Collection newClauses(Collection::newInstance(sz)); - + for (int32_t i = 0; i < sz; ++i) newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); - + SpanNearQueryPtr spanNearQuery(newLucene(newClauses, slop, inOrder)); spanNearQuery->setBoost(getBoost()); return spanNearQuery; } - + bool SpanNearQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + SpanNearQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) return false; - + if (inOrder != otherQuery->inOrder) return false; if (slop != otherQuery->slop) return false; if (!clauses.equals(otherQuery->clauses, luceneEquals())) return false; - + return (getBoost() == otherQuery->getBoost()); } - + int32_t SpanNearQuery::hashCode() { int32_t result = MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene); - // Mix bits before folding in things like boost, since it could cancel the last element of clauses. + // Mix bits before folding in things like boost, since it could cancel the last element of clauses. // This particular mix also serves to differentiate SpanNearQuery hashcodes from others. result ^= (result << 14) | MiscUtils::unsignedShift(result, 19); // reversible result += MiscUtils::doubleToRawIntBits(getBoost()); diff --git a/src/core/search/spans/SpanNotQuery.cpp b/src/core/search/spans/SpanNotQuery.cpp index 7986b5e6..8ceef89b 100644 --- a/src/core/search/spans/SpanNotQuery.cpp +++ b/src/core/search/spans/SpanNotQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,35 +15,35 @@ namespace Lucene { this->include = include; this->exclude = exclude; - + if (include->getField() != exclude->getField()) boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); } - + SpanNotQuery::~SpanNotQuery() { } - + SpanQueryPtr SpanNotQuery::getInclude() { return include; } - + SpanQueryPtr SpanNotQuery::getExclude() { return exclude; } - + String SpanNotQuery::getField() { return include->getField(); } - + void SpanNotQuery::extractTerms(SetTerm terms) { include->extractTerms(terms); } - + String SpanNotQuery::toString(const String& field) { StringStream buffer; @@ -51,7 +51,7 @@ namespace Lucene buffer << boostString(); return buffer.str(); } - + LuceneObjectPtr SpanNotQuery::clone(LuceneObjectPtr other) { SpanNotQueryPtr spanNotQuery(newLucene(boost::dynamic_pointer_cast(include->clone()), @@ -59,12 +59,12 @@ namespace Lucene spanNotQuery->setBoost(getBoost()); return spanNotQuery; } - + SpansPtr SpanNotQuery::getSpans(IndexReaderPtr reader) { return newLucene(shared_from_this(), include->getSpans(reader), exclude->getSpans(reader)); } - + QueryPtr SpanNotQuery::rewrite(IndexReaderPtr reader) { SpanNotQueryPtr clone; @@ -74,7 +74,7 @@ namespace Lucene clone = boost::dynamic_pointer_cast(this->clone()); clone->include = rewrittenInclude; } - + SpanQueryPtr rewrittenExclude(boost::dynamic_pointer_cast(exclude->rewrite(reader))); if (rewrittenExclude != exclude) { @@ -82,25 +82,25 @@ namespace Lucene clone = boost::dynamic_pointer_cast(this->clone()); clone->exclude = rewrittenExclude; } - + if (clone) return clone; // some clauses rewrote else return shared_from_this(); // no clauses rewrote } - + bool SpanNotQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + SpanNotQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) return false; - + return (include->equals(otherQuery->include) && exclude->equals(otherQuery->exclude) && getBoost() == otherQuery->getBoost()); } - + int32_t SpanNotQuery::hashCode() { int32_t result = include->hashCode(); @@ -110,7 +110,7 @@ namespace Lucene result ^= MiscUtils::doubleToRawIntBits(getBoost()); return result; } - + NotSpans::NotSpans(SpanNotQueryPtr query, SpansPtr includeSpans, SpansPtr excludeSpans) { this->query = query; @@ -119,72 +119,72 @@ namespace Lucene this->excludeSpans = excludeSpans; this->moreExclude = excludeSpans->next(); } - + NotSpans::~NotSpans() { } - + bool NotSpans::next() { if (moreInclude) // move to next include moreInclude = includeSpans->next(); - + while (moreInclude && moreExclude) { if (includeSpans->doc() > excludeSpans->doc()) // skip exclude moreExclude = excludeSpans->skipTo(includeSpans->doc()); - + // while exclude is before while (moreExclude && includeSpans->doc() == excludeSpans->doc() && excludeSpans->end() <= includeSpans->start()) moreExclude = excludeSpans->next(); // increment exclude - + // if no intersection if (!moreExclude || includeSpans->doc() != excludeSpans->doc() || includeSpans->end() <= excludeSpans->start()) break; // we found a match - + moreInclude = includeSpans->next(); // intersected: keep scanning } return moreInclude; } - + bool NotSpans::skipTo(int32_t target) { if (moreInclude) // skip include moreInclude = includeSpans->skipTo(target); - + if (!moreInclude) return false; - + // skip exclude if (moreExclude && includeSpans->doc() > excludeSpans->doc()) moreExclude = excludeSpans->skipTo(includeSpans->doc()); - + // while exclude is before while (moreExclude && includeSpans->doc() == excludeSpans->doc() && excludeSpans->end() <= includeSpans->start()) moreExclude = excludeSpans->next(); // increment exclude - + // if no intersection if (!moreExclude || includeSpans->doc() != excludeSpans->doc() || includeSpans->end() <= excludeSpans->start()) return true; // we found a match - + return next(); // scan to next match } - + int32_t NotSpans::doc() { return includeSpans->doc(); } - + int32_t NotSpans::start() { return includeSpans->start(); } - + int32_t NotSpans::end() { return includeSpans->end(); } - + Collection NotSpans::getPayload() { Collection result; @@ -195,12 +195,12 @@ namespace Lucene } return result; } - + bool NotSpans::isPayloadAvailable() { return includeSpans->isPayloadAvailable(); } - + String NotSpans::toString() { return L"spans(" + query->toString() + L")"; diff --git a/src/core/search/spans/SpanOrQuery.cpp b/src/core/search/spans/SpanOrQuery.cpp index e7a655cc..2601538e 100644 --- a/src/core/search/spans/SpanOrQuery.cpp +++ b/src/core/search/spans/SpanOrQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,40 +25,40 @@ namespace Lucene this->clauses.add(clause); } } - + SpanOrQuery::~SpanOrQuery() { } - + Collection SpanOrQuery::getClauses() { return clauses; } - + String SpanOrQuery::getField() { return field; } - + void SpanOrQuery::extractTerms(SetTerm terms) { for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) (*clause)->extractTerms(terms); } - + LuceneObjectPtr SpanOrQuery::clone(LuceneObjectPtr other) { int32_t sz = clauses.size(); Collection newClauses(Collection::newInstance(sz)); - + for (int32_t i = 0; i < sz; ++i) newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); - + SpanOrQueryPtr spanOrQuery(newLucene(newClauses)); spanOrQuery->setBoost(getBoost()); return spanOrQuery; } - + QueryPtr SpanOrQuery::rewrite(IndexReaderPtr reader) { SpanOrQueryPtr clone; @@ -78,7 +78,7 @@ namespace Lucene else return shared_from_this(); // no clauses rewrote } - + String SpanOrQuery::toString(const String& field) { StringStream buffer; @@ -92,24 +92,24 @@ namespace Lucene buffer << L"])" << boostString(); return buffer.str(); } - + bool SpanOrQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + SpanOrQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) return false; - + if (!clauses.equals(otherQuery->clauses, luceneEquals())) return false; if (!clauses.empty() && field != otherQuery->field) return false; - + return (getBoost() == otherQuery->getBoost()); } - + int32_t SpanOrQuery::hashCode() { int32_t result = MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene); @@ -117,22 +117,22 @@ namespace Lucene result ^= MiscUtils::doubleToRawIntBits(getBoost()); return result; } - + SpansPtr SpanOrQuery::getSpans(IndexReaderPtr reader) { if (clauses.size() == 1) // optimize 1-clause case return clauses[0]->getSpans(reader); return newLucene(shared_from_this(), reader); } - + SpanQueue::SpanQueue(int32_t size) : PriorityQueue(size) { } - + SpanQueue::~SpanQueue() { } - + bool SpanQueue::lessThan(const SpansPtr& first, const SpansPtr& second) { if (first->doc() == second->doc()) @@ -145,17 +145,17 @@ namespace Lucene else return (first->doc() < second->doc()); } - + OrSpans::OrSpans(SpanOrQueryPtr query, IndexReaderPtr reader) { this->query = query; this->reader = reader; } - + OrSpans::~OrSpans() { } - + bool OrSpans::initSpanQueue(int32_t target) { queue = newLucene(query->clauses.size()); @@ -167,35 +167,35 @@ namespace Lucene } return !queue->empty(); } - + bool OrSpans::next() { if (!queue) return initSpanQueue(-1); - + if (queue->empty()) // all done return false; - + if (top()->next()) // move to next { queue->updateTop(); return true; } - + queue->pop(); // exhausted a clause return !queue->empty(); } - + SpansPtr OrSpans::top() { return queue->top(); } - + bool OrSpans::skipTo(int32_t target) { if (!queue) return initSpanQueue(target); - + bool skipCalled = false; while (!queue->empty() && top()->doc() < target) { @@ -205,27 +205,27 @@ namespace Lucene queue->pop(); skipCalled = true; } - + if (skipCalled) return !queue->empty(); return next(); } - + int32_t OrSpans::doc() { return top()->doc(); } - + int32_t OrSpans::start() { return top()->start(); } - + int32_t OrSpans::end() { return top()->end(); } - + Collection OrSpans::getPayload() { Collection result; @@ -237,13 +237,13 @@ namespace Lucene } return result; } - + bool OrSpans::isPayloadAvailable() { SpansPtr theTop(top()); return (theTop && theTop->isPayloadAvailable()); } - + String OrSpans::toString() { StringStream buffer; diff --git a/src/core/search/spans/SpanQuery.cpp b/src/core/search/spans/SpanQuery.cpp index a6e20748..5f386e4f 100644 --- a/src/core/search/spans/SpanQuery.cpp +++ b/src/core/search/spans/SpanQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene SpanQuery::~SpanQuery() { } - + WeightPtr SpanQuery::createWeight(SearcherPtr searcher) { return newLucene(shared_from_this(), searcher); diff --git a/src/core/search/spans/SpanScorer.cpp b/src/core/search/spans/SpanScorer.cpp index e0be498d..1abe535a 100644 --- a/src/core/search/spans/SpanScorer.cpp +++ b/src/core/search/spans/SpanScorer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -32,18 +32,18 @@ namespace Lucene more = false; } } - + SpanScorer::~SpanScorer() { } - + int32_t SpanScorer::nextDoc() { if (!setFreqCurrentDoc()) doc = NO_MORE_DOCS; return doc; } - + int32_t SpanScorer::advance(int32_t target) { if (!more) @@ -57,7 +57,7 @@ namespace Lucene doc = NO_MORE_DOCS; return doc; } - + bool SpanScorer::setFreqCurrentDoc() { if (!more) @@ -73,28 +73,28 @@ namespace Lucene while (more && (doc == spans->doc())); return true; } - + int32_t SpanScorer::docID() { return doc; } - + double SpanScorer::score() { double raw = getSimilarity()->tf(freq) * value; // raw score return norms ? raw * Similarity::decodeNorm(norms[doc]) : raw; // normalize } - + ExplanationPtr SpanScorer::explain(int32_t doc) { ExplanationPtr tfExplanation(newLucene()); - + int32_t expDoc = advance(doc); - + double phraseFreq = expDoc == doc ? freq : 0.0; tfExplanation->setValue(getSimilarity()->tf(phraseFreq)); tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); - + return tfExplanation; } } diff --git a/src/core/search/spans/SpanTermQuery.cpp b/src/core/search/spans/SpanTermQuery.cpp index 47294341..f60e1f2e 100644 --- a/src/core/search/spans/SpanTermQuery.cpp +++ b/src/core/search/spans/SpanTermQuery.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,26 +17,26 @@ namespace Lucene { this->term = term; } - + SpanTermQuery::~SpanTermQuery() { } - + TermPtr SpanTermQuery::getTerm() { return term; } - + String SpanTermQuery::getField() { return term->field(); } - + void SpanTermQuery::extractTerms(SetTerm terms) { terms.add(term); } - + String SpanTermQuery::toString(const String& field) { StringStream buffer; @@ -47,7 +47,7 @@ namespace Lucene buffer << boostString(); return buffer.str(); } - + int32_t SpanTermQuery::hashCode() { int32_t prime = 31; @@ -55,7 +55,7 @@ namespace Lucene result = prime * result + (term ? term->hashCode() : 0); return result; } - + bool SpanTermQuery::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -76,7 +76,7 @@ namespace Lucene return false; return true; } - + LuceneObjectPtr SpanTermQuery::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term)); @@ -84,7 +84,7 @@ namespace Lucene spanFirstQuery->term = term; return spanFirstQuery; } - + SpansPtr SpanTermQuery::getSpans(IndexReaderPtr reader) { return newLucene(reader->termPositions(term), term); diff --git a/src/core/search/spans/SpanWeight.cpp b/src/core/search/spans/SpanWeight.cpp index 44805e28..cd1dcf4c 100644 --- a/src/core/search/spans/SpanWeight.cpp +++ b/src/core/search/spans/SpanWeight.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,99 +19,99 @@ namespace Lucene { this->similarity = query->getSimilarity(searcher); this->query = query; - + terms = SetTerm::newInstance(); query->extractTerms(terms); - + idfExp = similarity->idfExplain(Collection::newInstance(terms.begin(), terms.end()), searcher); idf = idfExp->getIdf(); value = 0.0; queryNorm = 0.0; queryWeight = 0.0; } - + SpanWeight::~SpanWeight() { } - + QueryPtr SpanWeight::getQuery() { return query; } - + double SpanWeight::getValue() { return value; } - + double SpanWeight::sumOfSquaredWeights() { queryWeight = idf * getQuery()->getBoost(); // compute query weight return queryWeight * queryWeight; // square it } - + void SpanWeight::normalize(double norm) { queryNorm = norm; queryWeight *= queryNorm; // normalize query weight value = queryWeight * idf; // idf for document } - + ScorerPtr SpanWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); } - + ExplanationPtr SpanWeight::explain(IndexReaderPtr reader, int32_t doc) { ComplexExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); String field(query->getField()); - + ExplanationPtr idfExpl(newLucene(idf, L"idf(" + field + L":" + idfExp->explain() + L")")); - + // explain query weight ExplanationPtr queryExpl(newLucene()); queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); if (query->getBoost() != 1.0) queryExpl->addDetail(boostExpl); queryExpl->addDetail(idfExpl); - + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); queryExpl->addDetail(queryNormExpl); - + queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); result->addDetail(queryExpl); - + // explain field weight ComplexExplanationPtr fieldExpl(newLucene()); fieldExpl->setDescription(L"fieldWeight(" + field + L":" + query->toString(field) + L" in " + StringUtils::toString(doc) + L"), product of:"); - + ExplanationPtr tfExpl(boost::dynamic_pointer_cast(scorer(reader, true, false))->explain(doc)); fieldExpl->addDetail(tfExpl); fieldExpl->addDetail(idfExpl); - + ExplanationPtr fieldNormExpl(newLucene()); ByteArray fieldNorms(reader->norms(field)); double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; fieldNormExpl->setValue(fieldNorm); fieldNormExpl->setDescription(L"fieldNorm(field=" + field + L", doc=" + StringUtils::toString(doc) + L")"); fieldExpl->addDetail(fieldNormExpl); - + fieldExpl->setMatch(tfExpl->isMatch()); fieldExpl->setValue(tfExpl->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); - + result->addDetail(fieldExpl); result->setMatch(fieldExpl->getMatch()); - + // combine them result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - + if (queryExpl->getValue() == 1.0) return fieldExpl; - + return result; } } diff --git a/src/core/search/spans/Spans.cpp b/src/core/search/spans/Spans.cpp index b0d114b2..6a213fa2 100644 --- a/src/core/search/spans/Spans.cpp +++ b/src/core/search/spans/Spans.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/search/spans/TermSpans.cpp b/src/core/search/spans/TermSpans.cpp index a2988f52..c1ec88f1 100644 --- a/src/core/search/spans/TermSpans.cpp +++ b/src/core/search/spans/TermSpans.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,11 +20,11 @@ namespace Lucene this->count = 0; this->position = 0; } - + TermSpans::~TermSpans() { } - + bool TermSpans::next() { if (count == freq) @@ -42,7 +42,7 @@ namespace Lucene ++count; return true; } - + bool TermSpans::skipTo(int32_t target) { if (!positions->skipTo(target)) @@ -50,44 +50,44 @@ namespace Lucene _doc = INT_MAX; return false; } - + _doc = positions->doc(); freq = positions->freq(); count = 0; - + position = positions->nextPosition(); ++count; - + return true; } - + int32_t TermSpans::doc() { return _doc; } - + int32_t TermSpans::start() { return position; } - + int32_t TermSpans::end() { return position + 1; } - + Collection TermSpans::getPayload() { Collection payload(newCollection(ByteArray::newInstance(positions->getPayloadLength()))); payload[0] = positions->getPayload(payload[0], 0); return payload; } - + bool TermSpans::isPayloadAvailable() { return positions->isPayloadAvailable(); } - + String TermSpans::toString() { StringStream buffer; @@ -100,7 +100,7 @@ namespace Lucene buffer << _doc << L"-" << position; return buffer.str(); } - + TermPositionsPtr TermSpans::getPositions() { return positions; diff --git a/src/core/store/BufferedIndexInput.cpp b/src/core/store/BufferedIndexInput.cpp index 7b6d7e10..5c6a2c63 100644 --- a/src/core/store/BufferedIndexInput.cpp +++ b/src/core/store/BufferedIndexInput.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene { /// Default buffer size. const int32_t BufferedIndexInput::BUFFER_SIZE = 1024; - + BufferedIndexInput::BufferedIndexInput(int32_t bufferSize) { this->bufferSize = bufferSize; @@ -21,18 +21,18 @@ namespace Lucene bufferLength = 0; bufferPosition = 0; } - + BufferedIndexInput::~BufferedIndexInput() { } - + uint8_t BufferedIndexInput::readByte() { if (bufferPosition >= bufferLength) refill(); return buffer[bufferPosition++]; } - + void BufferedIndexInput::setBufferSize(int32_t newSize) { if (newSize != bufferSize) @@ -44,7 +44,7 @@ namespace Lucene ByteArray _newBuffer(ByteArray::newInstance(newSize)); int32_t leftInBuffer = bufferLength - bufferPosition; int32_t numToCopy = leftInBuffer > newSize ? newSize : leftInBuffer; - + MiscUtils::arrayCopy(buffer.get(), bufferPosition, _newBuffer.get(), 0, numToCopy); bufferStart += bufferPosition; bufferPosition = 0; @@ -53,29 +53,29 @@ namespace Lucene } } } - + void BufferedIndexInput::newBuffer(ByteArray newBuffer) { // Subclasses can do something here buffer = newBuffer; } - + int32_t BufferedIndexInput::getBufferSize() { return bufferSize; } - + void BufferedIndexInput::checkBufferSize(int32_t bufferSize) { if (bufferSize <= 0) boost::throw_exception(IllegalArgumentException(L"bufferSize must be greater than 0 (got " + StringUtils::toString(bufferSize) + L")")); } - + void BufferedIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) { readBytes(b, offset, length, true); } - + void BufferedIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer) { if (length <= (bufferLength - bufferPosition)) @@ -96,11 +96,11 @@ namespace Lucene length -= available; bufferPosition += available; } - + // and now, read the remaining 'length' bytes if (useBuffer && length < bufferSize) { - // If the amount left to read is small enough, and we are allowed to use our buffer, + // If the amount left to read is small enough, and we are allowed to use our buffer, // do it in the usual buffered way: fill the buffer and copy from it refill(); if (bufferLength < length) @@ -117,8 +117,8 @@ namespace Lucene } else { - // The amount left to read is larger than the buffer or we've been asked to not use - // our buffer - there's no performance reason not to read it all at once. + // The amount left to read is larger than the buffer or we've been asked to not use + // our buffer - there's no performance reason not to read it all at once. // Note that unlike the previous code of this function, there is no need to do a seek // here, because there's no need to reread what we had in the buffer. int64_t after = bufferStart + bufferPosition + length; @@ -131,7 +131,7 @@ namespace Lucene } } } - + void BufferedIndexInput::refill() { int64_t start = bufferStart + bufferPosition; @@ -141,7 +141,7 @@ namespace Lucene int32_t newLength = (int32_t)(end - start); if (newLength <= 0) boost::throw_exception(IOException(L"Read past EOF")); - + if (!buffer) { newBuffer(ByteArray::newInstance(bufferSize)); // allocate buffer lazily @@ -152,19 +152,19 @@ namespace Lucene bufferStart = start; bufferPosition = 0; } - + void BufferedIndexInput::close() { bufferStart = 0; bufferLength = 0; bufferPosition = 0; } - + int64_t BufferedIndexInput::getFilePointer() { return bufferStart + bufferPosition; } - + void BufferedIndexInput::seek(int64_t pos) { if (pos >= bufferStart && pos < (bufferStart + bufferLength)) @@ -177,7 +177,7 @@ namespace Lucene seekInternal(pos); } } - + LuceneObjectPtr BufferedIndexInput::clone(LuceneObjectPtr other) { BufferedIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(IndexInput::clone(other))); diff --git a/src/core/store/BufferedIndexOutput.cpp b/src/core/store/BufferedIndexOutput.cpp index e4771c7b..2d3a84c5 100644 --- a/src/core/store/BufferedIndexOutput.cpp +++ b/src/core/store/BufferedIndexOutput.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,25 +11,25 @@ namespace Lucene { const int32_t BufferedIndexOutput::BUFFER_SIZE = 16384; - + BufferedIndexOutput::BufferedIndexOutput() { bufferStart = 0; bufferPosition = 0; buffer = ByteArray::newInstance(BUFFER_SIZE); } - + BufferedIndexOutput::~BufferedIndexOutput() { } - + void BufferedIndexOutput::writeByte(uint8_t b) { if (bufferPosition >= BUFFER_SIZE) flush(); buffer[bufferPosition++] = b; } - + void BufferedIndexOutput::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { int32_t bytesLeft = BUFFER_SIZE - bufferPosition; @@ -72,34 +72,34 @@ namespace Lucene } } } - + void BufferedIndexOutput::flush() { flushBuffer(buffer.get(), bufferPosition); bufferStart += bufferPosition; bufferPosition = 0; } - + void BufferedIndexOutput::flushBuffer(const uint8_t* b, int32_t length) { flushBuffer(b, 0, length); } - + void BufferedIndexOutput::flushBuffer(const uint8_t* b, int32_t offset, int32_t length) { // override } - + void BufferedIndexOutput::close() { flush(); } - + int64_t BufferedIndexOutput::getFilePointer() { return bufferStart + bufferPosition; } - + void BufferedIndexOutput::seek(int64_t pos) { flush(); diff --git a/src/core/store/ChecksumIndexInput.cpp b/src/core/store/ChecksumIndexInput.cpp index 3711767a..4e1006b7 100644 --- a/src/core/store/ChecksumIndexInput.cpp +++ b/src/core/store/ChecksumIndexInput.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,49 +13,49 @@ namespace Lucene { this->main = main; } - + ChecksumIndexInput::~ChecksumIndexInput() { } - + uint8_t ChecksumIndexInput::readByte() { uint8_t b = main->readByte(); checksum.process_byte(b); return b; } - + void ChecksumIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) { main->readBytes(b, offset, length); checksum.process_bytes(b + offset, length); } - + int64_t ChecksumIndexInput::getChecksum() { return checksum.checksum(); } - + void ChecksumIndexInput::close() { main->close(); } - + int64_t ChecksumIndexInput::getFilePointer() { return main->getFilePointer(); } - + void ChecksumIndexInput::seek(int64_t pos) { boost::throw_exception(RuntimeException(L"Seek not allowed")); } - + int64_t ChecksumIndexInput::length() { return main->length(); } - + LuceneObjectPtr ChecksumIndexInput::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene(main)); diff --git a/src/core/store/ChecksumIndexOutput.cpp b/src/core/store/ChecksumIndexOutput.cpp index b56a1526..631357bc 100644 --- a/src/core/store/ChecksumIndexOutput.cpp +++ b/src/core/store/ChecksumIndexOutput.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,66 +13,66 @@ namespace Lucene { this->main = main; } - + ChecksumIndexOutput::~ChecksumIndexOutput() { } - + void ChecksumIndexOutput::writeByte(uint8_t b) { checksum.process_byte(b); main->writeByte(b); } - + void ChecksumIndexOutput::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { checksum.process_bytes(b + offset, length); main->writeBytes(b, offset, length); } - + int64_t ChecksumIndexOutput::getChecksum() { return checksum.checksum(); } - + void ChecksumIndexOutput::flush() { main->flush(); } - + void ChecksumIndexOutput::close() { main->close(); } - + int64_t ChecksumIndexOutput::getFilePointer() { return main->getFilePointer(); } - + void ChecksumIndexOutput::seek(int64_t pos) { boost::throw_exception(RuntimeException(L"Seek not allowed")); } - + void ChecksumIndexOutput::prepareCommit() { int64_t checksum = getChecksum(); - + // Intentionally write a mismatched checksum. This is because we want to 1) test, as best we can, that we - // are able to write a long to the file, but 2) not actually "commit" the file yet. This (prepare commit) + // are able to write a long to the file, but 2) not actually "commit" the file yet. This (prepare commit) // is phase 1 of a two-phase commit. int64_t pos = main->getFilePointer(); main->writeLong(checksum - 1); main->flush(); main->seek(pos); } - + void ChecksumIndexOutput::finishCommit() { main->writeLong(getChecksum()); } - + int64_t ChecksumIndexOutput::length() { return main->length(); diff --git a/src/core/store/Directory.cpp b/src/core/store/Directory.cpp index 6730e0af..e331db59 100644 --- a/src/core/store/Directory.cpp +++ b/src/core/store/Directory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,64 +18,64 @@ namespace Lucene { isOpen = true; } - + Directory::~Directory() { } - + void Directory::close() { // override } - + void Directory::sync(const String& name) { } - + IndexInputPtr Directory::openInput(const String& name, int32_t bufferSize) { return openInput(name); } - + LockPtr Directory::makeLock(const String& name) { return lockFactory->makeLock(name); } - + void Directory::clearLock(const String& name) { if (lockFactory) lockFactory->clearLock(name); } - + void Directory::setLockFactory(LockFactoryPtr lockFactory) { BOOST_ASSERT(lockFactory); this->lockFactory = lockFactory; this->lockFactory->setLockPrefix(getLockID()); } - + LockFactoryPtr Directory::getLockFactory() { return lockFactory; } - + String Directory::getLockID() { return toString(); } - + String Directory::toString() { return LuceneObject::toString() + L" lockFactory=" + getLockFactory()->toString(); } - + void Directory::copy(DirectoryPtr src, DirectoryPtr dest, bool closeDirSrc) { HashSet files(src->listAll()); - + ByteArray buf(ByteArray::newInstance(BufferedIndexOutput::BUFFER_SIZE)); - + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { if (!IndexFileNameFilter::accept(L"", *file)) @@ -83,7 +83,7 @@ namespace Lucene IndexOutputPtr os; IndexInputPtr is; - + LuceneException finally; try { @@ -128,7 +128,7 @@ namespace Lucene if (closeDirSrc) src->close(); } - + void Directory::ensureOpen() { if (!isOpen) diff --git a/src/core/store/FSDirectory.cpp b/src/core/store/FSDirectory.cpp index 77b23be6..e1bdeb5f 100644 --- a/src/core/store/FSDirectory.cpp +++ b/src/core/store/FSDirectory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -32,21 +32,21 @@ namespace Lucene { checked = false; chunkSize = DEFAULT_READ_CHUNK_SIZE; - + // new ctors use always NativeFSLockFactory as default if (!lockFactory) lockFactory = newLucene(); directory = path; - + if (FileUtils::fileExists(directory) && !FileUtils::isDirectory(directory)) boost::throw_exception(NoSuchDirectoryException(L"File '" + directory + L"' exists but is not a directory")); - + setLockFactory(lockFactory); - + // for filesystem based LockFactory, delete the lockPrefix if the locks are placed // in index dir. if no index dir is given, set ourselves FSLockFactoryPtr lf(boost::dynamic_pointer_cast(lockFactory)); - + if (lf) { if (lf->getLockDir().empty()) @@ -58,21 +58,21 @@ namespace Lucene lf->setLockPrefix(L""); } } - + FSDirectory::~FSDirectory() { } - + FSDirectoryPtr FSDirectory::open(const String& path) { return open(path, LockFactoryPtr()); } - + FSDirectoryPtr FSDirectory::open(const String& path, LockFactoryPtr lockFactory) { return newLucene(path, lockFactory); } - + void FSDirectory::createDir() { if (!checked) @@ -82,7 +82,7 @@ namespace Lucene checked = true; } } - + void FSDirectory::initOutput(const String& name) { ensureOpen(); @@ -98,64 +98,64 @@ namespace Lucene boost::throw_exception(NoSuchDirectoryException(L"Directory '" + dir + L"' does not exist")); else if (!FileUtils::isDirectory(dir)) boost::throw_exception(NoSuchDirectoryException(L"File '" + dir + L"' exists but is not a directory")); - + HashSet result(HashSet::newInstance()); - + // Exclude subdirs if (!FileUtils::listDirectory(dir, true, result)) boost::throw_exception(IOException(L"Directory '" + dir + L"' exists and is a directory, but cannot be listed")); - + return result; } - + HashSet FSDirectory::listAll() { ensureOpen(); return listAll(directory); } - + bool FSDirectory::fileExists(const String& name) { ensureOpen(); return FileUtils::fileExists(FileUtils::joinPath(directory, name)); } - + uint64_t FSDirectory::fileModified(const String& name) { ensureOpen(); return FileUtils::fileModified(FileUtils::joinPath(directory, name)); } - + uint64_t FSDirectory::fileModified(const String& directory, const String& name) { return FileUtils::fileModified(FileUtils::joinPath(directory, name)); } - + void FSDirectory::touchFile(const String& name) { ensureOpen(); FileUtils::touchFile(FileUtils::joinPath(directory, name)); } - + void FSDirectory::deleteFile(const String& name) { ensureOpen(); if (!FileUtils::removeFile(FileUtils::joinPath(directory, name))) boost::throw_exception(IOException(L"Cannot delete: " + name)); } - + int64_t FSDirectory::fileLength(const String& name) { ensureOpen(); return FileUtils::fileLength(FileUtils::joinPath(directory, name)); } - + void FSDirectory::sync(const String& name) { ensureOpen(); String path(FileUtils::joinPath(directory, name)); bool success = false; - + for (int32_t retryCount = 0; retryCount < 5; ++retryCount) { boost::filesystem::ofstream syncFile; @@ -166,78 +166,78 @@ namespace Lucene catch (...) { } - + if (syncFile.is_open()) { syncFile.close(); success = true; break; } - + LuceneThread::threadSleep(5); // pause 5 msec } if (!success) boost::throw_exception(IOException(L"Sync failure: " + path)); } - + IndexInputPtr FSDirectory::openInput(const String& name) { ensureOpen(); return openInput(name, BufferedIndexInput::BUFFER_SIZE); } - + IndexInputPtr FSDirectory::openInput(const String& name, int32_t bufferSize) { return Directory::openInput(name, bufferSize); } - + String FSDirectory::getLockID() { ensureOpen(); md5_state_t state; md5_byte_t digest[16]; - + md5_init(&state); md5_append(&state, (const md5_byte_t *)StringUtils::toUTF8(directory).c_str(), directory.size()); md5_finish(&state, digest); - + static const wchar_t* hexDigits = L"0123456789abcdef"; - + String lockID(L"lucene-"); for (int32_t i = 0; i < 16; ++i) { lockID += hexDigits[(digest[i] >> 4) & 0x0f]; lockID += hexDigits[digest[i] & 0x0f]; } - + return lockID; } - + void FSDirectory::close() { SyncLock syncLock(this); isOpen = false; } - + String FSDirectory::toString() { return getClassName() + L"@" + directory + L" lockFactory=" + getLockFactory()->toString(); } - + String FSDirectory::getFile() { ensureOpen(); return directory; } - + void FSDirectory::setReadChunkSize(int32_t chunkSize) { #ifndef LPP_BUILD_64 this->chunkSize = chunkSize; #endif } - + int32_t FSDirectory::getReadChunkSize() { return chunkSize; diff --git a/src/core/store/FSLockFactory.cpp b/src/core/store/FSLockFactory.cpp index 6f9e49d1..ab8107c2 100644 --- a/src/core/store/FSLockFactory.cpp +++ b/src/core/store/FSLockFactory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,14 +16,14 @@ namespace Lucene FSLockFactory::~FSLockFactory() { } - + void FSLockFactory::setLockDir(const String& lockDir) { if (!this->lockDir.empty()) boost::throw_exception(IllegalStateException(L"You can set the lock directory for this factory only once.")); this->lockDir = lockDir; } - + String FSLockFactory::getLockDir() { return lockDir; diff --git a/src/core/store/FileSwitchDirectory.cpp b/src/core/store/FileSwitchDirectory.cpp index 54d441eb..f682be5d 100644 --- a/src/core/store/FileSwitchDirectory.cpp +++ b/src/core/store/FileSwitchDirectory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,21 +17,21 @@ namespace Lucene this->doClose = doClose; this->lockFactory = primaryDir->getLockFactory(); } - + FileSwitchDirectory::~FileSwitchDirectory() { } - + DirectoryPtr FileSwitchDirectory::getPrimaryDir() { return primaryDir; } - + DirectoryPtr FileSwitchDirectory::getSecondaryDir() { return secondaryDir; } - + void FileSwitchDirectory::close() { if (doClose) @@ -50,7 +50,7 @@ namespace Lucene finally.throwException(); } } - + HashSet FileSwitchDirectory::listAll() { HashSet primaryFiles(primaryDir->listAll()); @@ -59,53 +59,53 @@ namespace Lucene files.addAll(secondaryFiles.begin(), secondaryFiles.end()); return files; } - + String FileSwitchDirectory::getExtension(const String& name) { String::size_type i = name.find_last_of(L'.'); return i == String::npos ? L"" : name.substr(i + 1); } - + DirectoryPtr FileSwitchDirectory::getDirectory(const String& name) { return primaryExtensions.contains(getExtension(name)) ? primaryDir : secondaryDir; } - + bool FileSwitchDirectory::fileExists(const String& name) { return getDirectory(name)->fileExists(name); } - + uint64_t FileSwitchDirectory::fileModified(const String& name) { return getDirectory(name)->fileModified(name); } - + void FileSwitchDirectory::touchFile(const String& name) { getDirectory(name)->touchFile(name); } - + void FileSwitchDirectory::deleteFile(const String& name) { getDirectory(name)->deleteFile(name); } - + int64_t FileSwitchDirectory::fileLength(const String& name) { return getDirectory(name)->fileLength(name); } - + IndexOutputPtr FileSwitchDirectory::createOutput(const String& name) { return getDirectory(name)->createOutput(name); } - + void FileSwitchDirectory::sync(const String& name) { getDirectory(name)->sync(name); } - + IndexInputPtr FileSwitchDirectory::openInput(const String& name) { return getDirectory(name)->openInput(name); diff --git a/src/core/store/IndexInput.cpp b/src/core/store/IndexInput.cpp index 85580d63..4fee2108 100644 --- a/src/core/store/IndexInput.cpp +++ b/src/core/store/IndexInput.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,17 +16,17 @@ namespace Lucene { preUTF8Strings = false; } - + IndexInput::~IndexInput() { } - + void IndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer) { // default to ignoring useBuffer entirely readBytes(b, offset, length); } - + int32_t IndexInput::readInt() { int32_t i = (readByte() & 0xff) << 24; @@ -35,12 +35,12 @@ namespace Lucene i |= (readByte() & 0xff); return i; } - + int32_t IndexInput::readVInt() { uint8_t b = readByte(); int32_t i = (b & 0x7f); - + for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) { b = readByte(); @@ -48,19 +48,19 @@ namespace Lucene } return i; } - + int64_t IndexInput::readLong() { int64_t i = (int64_t)readInt() << 32; i |= (readInt() & 0xffffffffLL); return i; } - + int64_t IndexInput::readVLong() { uint8_t b = readByte(); int64_t i = (b & 0x7f); - + for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) { b = readByte(); @@ -68,12 +68,12 @@ namespace Lucene } return i; } - + void IndexInput::setModifiedUTF8StringsMode() { preUTF8Strings = true; } - + String IndexInput::readString() { if (preUTF8Strings) @@ -83,14 +83,14 @@ namespace Lucene readBytes(bytes.get(), 0, length); return StringUtils::toUnicode(bytes.get(), length); } - + String IndexInput::readModifiedUTF8String() { int32_t length = readVInt(); CharArray chars(CharArray::newInstance(length)); return String(chars.get(), readChars(chars.get(), 0, length)); } - + int32_t IndexInput::readChars(wchar_t* buffer, int32_t start, int32_t length) { Array chars(Array::newInstance(length)); @@ -113,7 +113,7 @@ namespace Lucene int32_t decodeLength = utf16Decoder->decode(buffer + start, length); return decodeLength == Reader::READER_EOF ? 0 : decodeLength; } - + void IndexInput::skipChars(int32_t length) { for (int32_t i = 0; i < length; ++i) @@ -132,7 +132,7 @@ namespace Lucene } } } - + MapStringString IndexInput::readStringStringMap() { MapStringString map(MapStringString::newInstance()); @@ -145,7 +145,7 @@ namespace Lucene } return map; } - + LuceneObjectPtr IndexInput::clone(LuceneObjectPtr other) { IndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(LuceneObject::clone(other))); diff --git a/src/core/store/IndexOutput.cpp b/src/core/store/IndexOutput.cpp index f7071a08..7cb0052f 100644 --- a/src/core/store/IndexOutput.cpp +++ b/src/core/store/IndexOutput.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,16 +14,16 @@ namespace Lucene { const int32_t IndexOutput::COPY_BUFFER_SIZE = 16384; - + IndexOutput::~IndexOutput() { } - + void IndexOutput::writeBytes(const uint8_t* b, int32_t length) { writeBytes(b, 0, length); } - + void IndexOutput::writeInt(int32_t i) { writeByte((uint8_t)(i >> 24)); @@ -31,7 +31,7 @@ namespace Lucene writeByte((uint8_t)(i >> 8)); writeByte((uint8_t)i); } - + void IndexOutput::writeVInt(int32_t i) { while ((i & ~0x7f) != 0) @@ -41,13 +41,13 @@ namespace Lucene } writeByte((uint8_t)i); } - + void IndexOutput::writeLong(int64_t i) { writeInt((int32_t)(i >> 32)); writeInt((int32_t)i); } - + void IndexOutput::writeVLong(int64_t i) { while ((i & ~0x7f) != 0) @@ -57,7 +57,7 @@ namespace Lucene } writeByte((uint8_t)i); } - + void IndexOutput::writeString(const String& s) { UTF8ResultPtr utf8Result(newLucene()); @@ -65,7 +65,7 @@ namespace Lucene writeVInt(utf8Result->length); writeBytes(utf8Result->result.get(), utf8Result->length); } - + void IndexOutput::writeChars(const String& s, int32_t start, int32_t length) { int32_t end = start + length; @@ -87,7 +87,7 @@ namespace Lucene } } } - + void IndexOutput::copyBytes(IndexInputPtr input, int64_t numBytes) { BOOST_ASSERT(numBytes >= 0); @@ -102,11 +102,11 @@ namespace Lucene left -= toCopy; } } - + void IndexOutput::setLength(int64_t length) { } - + void IndexOutput::writeStringStringMap(MapStringString map) { if (!map) diff --git a/src/core/store/Lock.cpp b/src/core/store/Lock.cpp index 333dfb1a..0b3fd37c 100644 --- a/src/core/store/Lock.cpp +++ b/src/core/store/Lock.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,14 +12,14 @@ namespace Lucene { /// How long {@link #obtain(int64_t)} waits, in milliseconds, in between attempts to acquire the lock. const int32_t Lock::LOCK_OBTAIN_WAIT_FOREVER = -1; - + /// Pass this value to {@link #obtain(int64_t)} to try forever to obtain the lock. const int32_t Lock::LOCK_POLL_INTERVAL = 1000; - + Lock::~Lock() { } - + bool Lock::obtain(int32_t lockWaitTimeout) { bool locked = obtain(); diff --git a/src/core/store/LockFactory.cpp b/src/core/store/LockFactory.cpp index 26e1cede..fdf09314 100644 --- a/src/core/store/LockFactory.cpp +++ b/src/core/store/LockFactory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,12 +12,12 @@ namespace Lucene LockFactory::~LockFactory() { } - + void LockFactory::setLockPrefix(const String& lockPrefix) { this->lockPrefix = lockPrefix; } - + String LockFactory::getLockPrefix() { return lockPrefix; diff --git a/src/core/store/MMapDirectory.cpp b/src/core/store/MMapDirectory.cpp index ac702728..91324e95 100644 --- a/src/core/store/MMapDirectory.cpp +++ b/src/core/store/MMapDirectory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,23 +18,23 @@ namespace Lucene MMapDirectory::MMapDirectory(const String& path, LockFactoryPtr lockFactory) : FSDirectory(path, lockFactory) { } - + MMapDirectory::~MMapDirectory() { } - + IndexInputPtr MMapDirectory::openInput(const String& name, int32_t bufferSize) { ensureOpen(); return newLucene(FileUtils::joinPath(directory, name)); } - + IndexOutputPtr MMapDirectory::createOutput(const String& name) { initOutput(name); return newLucene(FileUtils::joinPath(directory, name)); } - + MMapIndexInput::MMapIndexInput(const String& path) { _length = path.empty() ? 0 : (int32_t)FileUtils::fileLength(path); @@ -52,11 +52,11 @@ namespace Lucene } isClone = false; } - + MMapIndexInput::~MMapIndexInput() { } - + uint8_t MMapIndexInput::readByte() { try @@ -69,7 +69,7 @@ namespace Lucene return 0; } } - + void MMapIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) { try @@ -82,22 +82,22 @@ namespace Lucene boost::throw_exception(IOException(L"Read past EOF")); } } - + int64_t MMapIndexInput::getFilePointer() { return bufferPosition; } - + void MMapIndexInput::seek(int64_t pos) { bufferPosition = (int32_t)pos; } - + int64_t MMapIndexInput::length() { return (int64_t)_length; } - + void MMapIndexInput::close() { if (isClone || !file.is_open()) @@ -106,7 +106,7 @@ namespace Lucene bufferPosition = 0; file.close(); } - + LuceneObjectPtr MMapIndexInput::clone(LuceneObjectPtr other) { if (!file.is_open()) diff --git a/src/core/store/NativeFSLockFactory.cpp b/src/core/store/NativeFSLockFactory.cpp index 3719ba6b..c3c1d0b5 100644 --- a/src/core/store/NativeFSLockFactory.cpp +++ b/src/core/store/NativeFSLockFactory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,22 +19,22 @@ namespace Lucene { setLockDir(lockDirName); } - + NativeFSLockFactory::~NativeFSLockFactory() { } - + LockPtr NativeFSLockFactory::makeLock(const String& lockName) { SyncLock syncLock(this); return newLucene(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName); } - + void NativeFSLockFactory::clearLock(const String& lockName) { // note that this isn't strictly required anymore because the existence of these files does not mean // they are locked, but still do this in case people really want to see the files go away - + if (FileUtils::isDirectory(lockDir)) { String lockPath(FileUtils::joinPath(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName)); @@ -42,13 +42,13 @@ namespace Lucene boost::throw_exception(IOException(L"Failed to delete: " + lockPath)); } } - + NativeFSLock::NativeFSLock(const String& lockDir, const String& lockFileName) { this->lockDir = lockDir; path = FileUtils::joinPath(lockDir, lockFileName); } - + NativeFSLock::~NativeFSLock() { try @@ -59,7 +59,7 @@ namespace Lucene { } } - + SynchronizePtr NativeFSLock::LOCK_HELD_LOCK() { static SynchronizePtr _LOCK_HELD_LOCK; @@ -67,7 +67,7 @@ namespace Lucene _LOCK_HELD_LOCK = newInstance(); return _LOCK_HELD_LOCK; } - + HashSet NativeFSLock::LOCK_HELD() { static HashSet _LOCK_HELD; @@ -75,21 +75,21 @@ namespace Lucene _LOCK_HELD = HashSet::newInstance(); return _LOCK_HELD; } - + bool NativeFSLock::lockExists() { SyncLock syncLock(this); return lock.get() != NULL; } - + bool NativeFSLock::obtain() { SyncLock syncLock(this); - + if (lockExists()) // our instance is already locked return false; - + // ensure that lockdir exists and is a directory if (!FileUtils::fileExists(lockDir)) { @@ -98,9 +98,9 @@ namespace Lucene } else if (!FileUtils::isDirectory(lockDir)) boost::throw_exception(IOException(L"Found regular file where directory expected: " + lockDir)); - + bool markedHeld = false; - + // make sure nobody else in-process has this lock held already and mark it held if not { SyncLock heldLock(LOCK_HELD_LOCK()); @@ -109,18 +109,18 @@ namespace Lucene return false; else { - // this "reserves" the fact that we are the one thread trying to obtain this lock, so we own the + // this "reserves" the fact that we are the one thread trying to obtain this lock, so we own the // only instance of a channel against this file LOCK_HELD().add(path); markedHeld = true; } } - + try { // we can get intermittent "access denied" here, so we treat this as failure to acquire the lock boost::filesystem::ofstream f(path, std::ios::binary | std::ios::out); - + if (f.is_open()) { std::string lockpath; @@ -146,20 +146,20 @@ namespace Lucene { lock.reset(); } - + if (markedHeld && !lockExists()) { SyncLock heldLock(LOCK_HELD_LOCK()); LOCK_HELD().remove(path); } - + return lockExists(); } - + void NativeFSLock::release() { SyncLock syncLock(this); - + if (lockExists()) { try @@ -170,21 +170,21 @@ namespace Lucene catch (...) { } - + { SyncLock heldLock(LOCK_HELD_LOCK()); LOCK_HELD().remove(path); } - - // we don't care anymore if the file cannot be deleted because it's held up by another process + + // we don't care anymore if the file cannot be deleted because it's held up by another process // (eg. AntiVirus). NativeFSLock does not depend on the existence/absence of the lock file FileUtils::removeFile(path); } else { - // if we don't hold the lock, and somebody still called release(), for example as a result of - // calling IndexWriter.unlock(), we should attempt to obtain the lock and release it. If the - // obtain fails, it means the lock cannot be released, and we should throw a proper exception + // if we don't hold the lock, and somebody still called release(), for example as a result of + // calling IndexWriter.unlock(), we should attempt to obtain the lock and release it. If the + // obtain fails, it means the lock cannot be released, and we should throw a proper exception // rather than silently failing/not doing anything. bool obtained = false; LuceneException finally; @@ -203,21 +203,21 @@ namespace Lucene finally.throwException(); } } - + bool NativeFSLock::isLocked() { SyncLock syncLock(this); - + // the test for is islocked is not directly possible with native file locks - + // first a shortcut, if a lock reference in this instance is available if (lockExists()) return true; - + // look if lock file is present; if not, there can definitely be no lock! if (!FileUtils::fileExists(path)) return false; - + // try to obtain and release (if was locked) the lock try { @@ -231,7 +231,7 @@ namespace Lucene return false; } } - + String NativeFSLock::toString() { return getClassName() + L"@" + path; diff --git a/src/core/store/NoLockFactory.cpp b/src/core/store/NoLockFactory.cpp index be20b9f5..24bc2255 100644 --- a/src/core/store/NoLockFactory.cpp +++ b/src/core/store/NoLockFactory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene NoLockFactory::~NoLockFactory() { } - + NoLockFactoryPtr NoLockFactory::getNoLockFactory() { static NoLockFactoryPtr singleton; @@ -24,7 +24,7 @@ namespace Lucene } return singleton; } - + NoLockPtr NoLockFactory::getSingletonLock() { // Single instance returned whenever makeLock is called. @@ -36,34 +36,34 @@ namespace Lucene } return singletonLock; } - + LockPtr NoLockFactory::makeLock(const String& lockName) { return getSingletonLock(); } - + void NoLockFactory::clearLock(const String& lockName) { } - + NoLock::~NoLock() { } - + bool NoLock::obtain() { return true; } - + void NoLock::release() { } - + bool NoLock::isLocked() { return false; } - + String NoLock::toString() { return getClassName(); diff --git a/src/core/store/RAMDirectory.cpp b/src/core/store/RAMDirectory.cpp index 021702d0..dab12d60 100644 --- a/src/core/store/RAMDirectory.cpp +++ b/src/core/store/RAMDirectory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,7 +23,7 @@ namespace Lucene this->closeDir = false; setLockFactory(newLucene()); } - + RAMDirectory::RAMDirectory(DirectoryPtr dir) { this->fileMap = MapStringRAMFile::newInstance(); @@ -33,7 +33,7 @@ namespace Lucene this->closeDir = false; setLockFactory(newLucene()); } - + RAMDirectory::RAMDirectory(DirectoryPtr dir, bool closeDir) { this->fileMap = MapStringRAMFile::newInstance(); @@ -43,17 +43,17 @@ namespace Lucene this->closeDir = closeDir; setLockFactory(newLucene()); } - + RAMDirectory::~RAMDirectory() { } - + void RAMDirectory::initialize() { if (copyDirectory) Directory::copy(DirectoryPtr(_dirSource), shared_from_this(), closeDir); } - + HashSet RAMDirectory::listAll() { SyncLock syncLock(this); @@ -63,14 +63,14 @@ namespace Lucene result.add(fileName->first); return result; } - + bool RAMDirectory::fileExists(const String& name) { ensureOpen(); SyncLock syncLock(this); return fileMap.contains(name); } - + uint64_t RAMDirectory::fileModified(const String& name) { ensureOpen(); @@ -80,7 +80,7 @@ namespace Lucene boost::throw_exception(FileNotFoundException(name)); return ramFile->second->getLastModified(); } - + void RAMDirectory::touchFile(const String& name) { ensureOpen(); @@ -97,7 +97,7 @@ namespace Lucene LuceneThread::threadSleep(1); file->setLastModified(MiscUtils::currentTimeMillis()); } - + int64_t RAMDirectory::fileLength(const String& name) { ensureOpen(); @@ -107,14 +107,14 @@ namespace Lucene boost::throw_exception(FileNotFoundException(name)); return ramFile->second->getLength(); } - + int64_t RAMDirectory::sizeInBytes() { SyncLock syncLock(this); ensureOpen(); return _sizeInBytes; } - + void RAMDirectory::deleteFile(const String& name) { SyncLock syncLock(this); @@ -123,9 +123,9 @@ namespace Lucene if (ramFile == fileMap.end()) boost::throw_exception(FileNotFoundException(name)); _sizeInBytes -= ramFile->second->getSizeInBytes(); - fileMap.remove(name); + fileMap.remove(name); } - + IndexOutputPtr RAMDirectory::createOutput(const String& name) { ensureOpen(); @@ -142,7 +142,7 @@ namespace Lucene } return newLucene(file); } - + IndexInputPtr RAMDirectory::openInput(const String& name) { ensureOpen(); @@ -156,7 +156,7 @@ namespace Lucene } return newLucene(file); } - + void RAMDirectory::close() { isOpen = false; diff --git a/src/core/store/RAMFile.cpp b/src/core/store/RAMFile.cpp index 6c3646d7..e7d861fa 100644 --- a/src/core/store/RAMFile.cpp +++ b/src/core/store/RAMFile.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,7 +18,7 @@ namespace Lucene this->sizeInBytes = 0; this->lastModified = MiscUtils::currentTimeMillis(); } - + RAMFile::RAMFile(RAMDirectoryPtr directory) { this->buffers = Collection::newInstance(); @@ -27,35 +27,35 @@ namespace Lucene this->_directory = directory; this->lastModified = MiscUtils::currentTimeMillis(); } - + RAMFile::~RAMFile() { } - + int64_t RAMFile::getLength() { SyncLock syncLock(this); return length; } - + void RAMFile::setLength(int64_t length) { SyncLock syncLock(this); this->length = length; } - + int64_t RAMFile::getLastModified() { SyncLock syncLock(this); return lastModified; } - + void RAMFile::setLastModified(int64_t lastModified) { SyncLock syncLock(this); this->lastModified = lastModified; } - + ByteArray RAMFile::addBuffer(int32_t size) { ByteArray buffer(newBuffer(size)); @@ -64,7 +64,7 @@ namespace Lucene buffers.add(buffer); sizeInBytes += size; } - + RAMDirectoryPtr directory(_directory.lock()); if (directory) { @@ -73,24 +73,24 @@ namespace Lucene } return buffer; } - + ByteArray RAMFile::getBuffer(int32_t index) { SyncLock syncLock(this); return buffers[index]; } - + int32_t RAMFile::numBuffers() { SyncLock syncLock(this); return buffers.size(); } - + ByteArray RAMFile::newBuffer(int32_t size) { return ByteArray::newInstance(size); } - + int64_t RAMFile::getSizeInBytes() { SyncLock syncLock(this); diff --git a/src/core/store/RAMInputStream.cpp b/src/core/store/RAMInputStream.cpp index a2501bfa..2b8d947b 100644 --- a/src/core/store/RAMInputStream.cpp +++ b/src/core/store/RAMInputStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,46 +14,46 @@ namespace Lucene { const int32_t RAMInputStream::BUFFER_SIZE = RAMOutputStream::BUFFER_SIZE; - + RAMInputStream::RAMInputStream() { _length = 0; - + // make sure that we switch to the first needed buffer lazily currentBufferIndex = -1; bufferPosition = 0; bufferStart = 0; bufferLength = 0; } - + RAMInputStream::RAMInputStream(RAMFilePtr f) { file = f; _length = file->length; if (_length / BUFFER_SIZE >= INT_MAX) boost::throw_exception(IOException(L"Too large RAMFile: " + StringUtils::toString(_length))); - + // make sure that we switch to the first needed buffer lazily currentBufferIndex = -1; bufferPosition = 0; bufferStart = 0; bufferLength = 0; } - + RAMInputStream::~RAMInputStream() { } - + void RAMInputStream::close() { // nothing to do here } - + int64_t RAMInputStream::length() { return _length; } - + uint8_t RAMInputStream::readByte() { if (bufferPosition >= bufferLength) @@ -63,7 +63,7 @@ namespace Lucene } return currentBuffer[bufferPosition++]; } - + void RAMInputStream::readBytes(uint8_t* b, int32_t offset, int32_t length) { while (length > 0) @@ -73,7 +73,7 @@ namespace Lucene ++currentBufferIndex; switchCurrentBuffer(true); } - + int32_t remainInBuffer = bufferLength - bufferPosition; int32_t bytesToCopy = length < remainInBuffer ? length : remainInBuffer; MiscUtils::arrayCopy(currentBuffer.get(), bufferPosition, b, offset, bytesToCopy); @@ -82,7 +82,7 @@ namespace Lucene bufferPosition += bytesToCopy; } } - + void RAMInputStream::switchCurrentBuffer(bool enforceEOF) { if (currentBufferIndex >= file->numBuffers()) @@ -106,12 +106,12 @@ namespace Lucene bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int32_t)buflen; } } - + int64_t RAMInputStream::getFilePointer() { return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; } - + void RAMInputStream::seek(int64_t pos) { if (!currentBuffer || (int32_t)pos < bufferStart || (int32_t)pos >= bufferStart + BUFFER_SIZE) @@ -121,7 +121,7 @@ namespace Lucene } bufferPosition = (int32_t)(pos % BUFFER_SIZE); } - + LuceneObjectPtr RAMInputStream::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene()); diff --git a/src/core/store/RAMOutputStream.cpp b/src/core/store/RAMOutputStream.cpp index bed91d50..b4ee4763 100644 --- a/src/core/store/RAMOutputStream.cpp +++ b/src/core/store/RAMOutputStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,33 +13,33 @@ namespace Lucene { const int32_t RAMOutputStream::BUFFER_SIZE = 1024; - + RAMOutputStream::RAMOutputStream() { file = newLucene(RAMDirectoryPtr()); - + // make sure that we switch to the first needed buffer lazily currentBufferIndex = -1; bufferPosition = 0; bufferStart = 0; bufferLength = 0; } - + RAMOutputStream::RAMOutputStream(RAMFilePtr f) { file = f; - + // make sure that we switch to the first needed buffer lazily currentBufferIndex = -1; bufferPosition = 0; bufferStart = 0; bufferLength = 0; } - + RAMOutputStream::~RAMOutputStream() { } - + void RAMOutputStream::writeTo(IndexOutputPtr out) { flush(); @@ -56,7 +56,7 @@ namespace Lucene pos = nextPos; } } - + void RAMOutputStream::reset() { currentBuffer.reset(); @@ -66,12 +66,12 @@ namespace Lucene bufferLength = 0; file->setLength(0); } - + void RAMOutputStream::close() { flush(); } - + void RAMOutputStream::seek(int64_t pos) { // set the file length in case we seek back and flush() has not been called yet @@ -83,12 +83,12 @@ namespace Lucene } bufferPosition = (int32_t)(pos % BUFFER_SIZE); } - + int64_t RAMOutputStream::length() { return file->length; } - + void RAMOutputStream::writeByte(uint8_t b) { if (bufferPosition == bufferLength) @@ -98,7 +98,7 @@ namespace Lucene } currentBuffer[bufferPosition++] = b; } - + void RAMOutputStream::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { while (length > 0) @@ -109,7 +109,7 @@ namespace Lucene ++currentBufferIndex; switchCurrentBuffer(); } - + int32_t remainInBuffer = currentBuffer.size() - bufferPosition; int32_t bytesToCopy = length < remainInBuffer ? length : remainInBuffer; MiscUtils::arrayCopy(b, offset, currentBuffer.get(), bufferPosition, bytesToCopy); @@ -118,7 +118,7 @@ namespace Lucene bufferPosition += bytesToCopy; } } - + void RAMOutputStream::switchCurrentBuffer() { if (currentBufferIndex == file->numBuffers()) @@ -129,25 +129,25 @@ namespace Lucene bufferStart = (int64_t)BUFFER_SIZE * (int64_t)currentBufferIndex; bufferLength = currentBuffer.size(); } - + void RAMOutputStream::setFileLength() { int64_t pointer = bufferStart + bufferPosition; if (pointer > file->length) file->setLength(pointer); } - + void RAMOutputStream::flush() { file->setLastModified(MiscUtils::currentTimeMillis()); setFileLength(); } - + int64_t RAMOutputStream::getFilePointer() { return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; } - + int64_t RAMOutputStream::sizeInBytes() { return file->numBuffers() * BUFFER_SIZE; diff --git a/src/core/store/SimpleFSDirectory.cpp b/src/core/store/SimpleFSDirectory.cpp index 0aed22ef..7f39ca84 100644 --- a/src/core/store/SimpleFSDirectory.cpp +++ b/src/core/store/SimpleFSDirectory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -18,31 +18,31 @@ namespace Lucene SimpleFSDirectory::SimpleFSDirectory(const String& path, LockFactoryPtr lockFactory) : FSDirectory(path, lockFactory) { } - + SimpleFSDirectory::~SimpleFSDirectory() { } - + IndexOutputPtr SimpleFSDirectory::createOutput(const String& name) { initOutput(name); return newLucene(FileUtils::joinPath(directory, name)); } - + IndexInputPtr SimpleFSDirectory::openInput(const String& name) { return FSDirectory::openInput(name); } - + IndexInputPtr SimpleFSDirectory::openInput(const String& name, int32_t bufferSize) { ensureOpen(); return newLucene(FileUtils::joinPath(directory, name), bufferSize, getReadChunkSize()); } - + const int32_t InputFile::FILE_EOF = FileReader::FILE_EOF; const int32_t InputFile::FILE_ERROR = FileReader::FILE_ERROR; - + InputFile::InputFile(const String& path) { file = newInstance(path, std::ios::binary | std::ios::in); @@ -51,11 +51,11 @@ namespace Lucene position = 0; length = FileUtils::fileLength(path); } - + InputFile::~InputFile() { } - + void InputFile::setPosition(int64_t position) { this->position = position; @@ -63,17 +63,17 @@ namespace Lucene if (!file->good()) boost::throw_exception(IOException()); } - + int64_t InputFile::getPosition() { return position; } - + int64_t InputFile::getLength() { return length; } - + int32_t InputFile::read(uint8_t* b, int32_t offset, int32_t length) { try @@ -90,24 +90,24 @@ namespace Lucene return FILE_ERROR; } } - + void InputFile::close() { if (file->is_open()) file->close(); } - + bool InputFile::isValid() { return (file && file->is_open() && file->good()); } - + SimpleFSIndexInput::SimpleFSIndexInput() { this->chunkSize = 0; this->isClone = false; } - + SimpleFSIndexInput::SimpleFSIndexInput(const String& path, int32_t bufferSize, int32_t chunkSize) : BufferedIndexInput(bufferSize) { this->file = newLucene(path); @@ -115,52 +115,52 @@ namespace Lucene this->chunkSize = chunkSize; this->isClone = false; } - + SimpleFSIndexInput::~SimpleFSIndexInput() { } - + void SimpleFSIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) { SyncLock fileLock(file); - + int64_t position = getFilePointer(); if (position != file->getPosition()) file->setPosition(position); - + int32_t total = 0; - + while (total < length) { int32_t readLength = total + chunkSize > length ? length - total : chunkSize; - + int32_t i = file->read(b, offset + total, readLength); if (i == InputFile::FILE_EOF) boost::throw_exception(IOException(L"Read past EOF")); total += i; } } - + void SimpleFSIndexInput::seekInternal(int64_t pos) { } - + int64_t SimpleFSIndexInput::length() { return file->getLength(); } - + void SimpleFSIndexInput::close() { if (!isClone) file->close(); } - + bool SimpleFSIndexInput::isValid() { return file->isValid(); } - + LuceneObjectPtr SimpleFSIndexInput::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = BufferedIndexInput::clone(other ? other : newLucene()); @@ -171,17 +171,17 @@ namespace Lucene cloneIndexInput->isClone = true; return cloneIndexInput; } - + OutputFile::OutputFile(const String& path) { this->path = path; file = newInstance(path, std::ios::binary | std::ios::out); } - + OutputFile::~OutputFile() { } - + bool OutputFile::write(const uint8_t* b, int32_t offset, int32_t length) { if (!file->is_open()) @@ -196,56 +196,56 @@ namespace Lucene return false; } } - + void OutputFile::close() { file.reset(); } - + void OutputFile::setPosition(int64_t position) { file->seekp((std::streamoff)position); if (!file->good()) boost::throw_exception(IOException()); } - + int64_t OutputFile::getLength() { return FileUtils::fileLength(path); } - + void OutputFile::setLength(int64_t length) { FileUtils::setFileLength(path, length); } - + void OutputFile::flush() { if (file->is_open()) file->flush(); } - + bool OutputFile::isValid() { return (file && file->is_open() && file->good()); } - + SimpleFSIndexOutput::SimpleFSIndexOutput(const String& path) { file = newLucene(path); isOpen = true; } - + SimpleFSIndexOutput::~SimpleFSIndexOutput() { } - + void SimpleFSIndexOutput::flushBuffer(const uint8_t* b, int32_t offset, int32_t length) { file->write(b, offset, length); file->flush(); } - + void SimpleFSIndexOutput::close() { if (isOpen) @@ -255,18 +255,18 @@ namespace Lucene isOpen = false; } } - + void SimpleFSIndexOutput::seek(int64_t pos) { BufferedIndexOutput::seek(pos); file->setPosition(pos); } - + int64_t SimpleFSIndexOutput::length() { return file->getLength(); } - + void SimpleFSIndexOutput::setLength(int64_t length) { file->setLength(length); diff --git a/src/core/store/SimpleFSLockFactory.cpp b/src/core/store/SimpleFSLockFactory.cpp index e1da300a..8060a91d 100644 --- a/src/core/store/SimpleFSLockFactory.cpp +++ b/src/core/store/SimpleFSLockFactory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,21 +16,21 @@ namespace Lucene SimpleFSLockFactory::SimpleFSLockFactory() { } - + SimpleFSLockFactory::SimpleFSLockFactory(const String& lockDir) { setLockDir(lockDir); } - + SimpleFSLockFactory::~SimpleFSLockFactory() { } - + LockPtr SimpleFSLockFactory::makeLock(const String& lockName) { return newLucene(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName); } - + void SimpleFSLockFactory::clearLock(const String& lockName) { if (FileUtils::isDirectory(lockDir)) @@ -40,17 +40,17 @@ namespace Lucene boost::throw_exception(IOException(L"Cannot delete " + lockPath)); } } - + SimpleFSLock::SimpleFSLock(const String& lockDir, const String& lockFileName) { this->lockDir = lockDir; this->lockFile = lockFile; } - + SimpleFSLock::~SimpleFSLock() { } - + bool SimpleFSLock::obtain() { // Ensure that lockDir exists and is a directory @@ -71,19 +71,19 @@ namespace Lucene } return f.is_open(); } - + void SimpleFSLock::release() { String path(FileUtils::joinPath(lockDir, lockFile)); if (FileUtils::fileExists(path) && !FileUtils::removeFile(path)) boost::throw_exception(LockReleaseFailedException(L"failed to delete " + path)); } - + bool SimpleFSLock::isLocked() { return FileUtils::fileExists(FileUtils::joinPath(lockDir, lockFile)); } - + String SimpleFSLock::toString() { return getClassName() + L"@" + FileUtils::joinPath(lockDir, lockFile); diff --git a/src/core/store/SingleInstanceLockFactory.cpp b/src/core/store/SingleInstanceLockFactory.cpp index 739b7ff3..c997edf4 100644 --- a/src/core/store/SingleInstanceLockFactory.cpp +++ b/src/core/store/SingleInstanceLockFactory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,52 +14,52 @@ namespace Lucene { locks = HashSet::newInstance(); } - + SingleInstanceLockFactory::~SingleInstanceLockFactory() { } - + LockPtr SingleInstanceLockFactory::makeLock(const String& lockName) { - // We do not use the LockPrefix at all, because the private HashSet instance + // We do not use the LockPrefix at all, because the private HashSet instance // effectively scopes the locking to this single Directory instance. return newLucene(locks, lockName); } - + void SingleInstanceLockFactory::clearLock(const String& lockName) { SyncLock syncLock(&locks); locks.remove(lockName); } - + SingleInstanceLock::SingleInstanceLock(HashSet locks, const String& lockName) { this->locks = locks; this->lockName = lockName; } - + SingleInstanceLock::~SingleInstanceLock() { } - + bool SingleInstanceLock::obtain() { SyncLock syncLock(&locks); return locks.add(lockName); } - + void SingleInstanceLock::release() { SyncLock syncLock(&locks); locks.remove(lockName); } - + bool SingleInstanceLock::isLocked() { SyncLock syncLock(&locks); return locks.contains(lockName); } - + String SingleInstanceLock::toString() { return lockName; diff --git a/src/core/util/Attribute.cpp b/src/core/util/Attribute.cpp index 5df3b2c7..debf887f 100644 --- a/src/core/util/Attribute.cpp +++ b/src/core/util/Attribute.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,17 +12,17 @@ namespace Lucene Attribute::~Attribute() { } - + int32_t Attribute::hashCode() { return LuceneObject::hashCode(); } - + bool Attribute::equals(LuceneObjectPtr other) { return LuceneObject::equals(other); } - + LuceneObjectPtr Attribute::clone(LuceneObjectPtr other) { return LuceneObject::clone(other); diff --git a/src/core/util/AttributeSource.cpp b/src/core/util/AttributeSource.cpp index 48ea4ffb..2ad09f10 100644 --- a/src/core/util/AttributeSource.cpp +++ b/src/core/util/AttributeSource.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,12 +17,12 @@ namespace Lucene AttributeFactory::~AttributeFactory() { } - + AttributePtr AttributeFactory::createAttributeInstance(const String& className) { return AttributePtr(); // override } - + AttributeFactoryPtr AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY() { static AttributeFactoryPtr _DEFAULT_ATTRIBUTE_FACTORY; @@ -33,13 +33,13 @@ namespace Lucene } return _DEFAULT_ATTRIBUTE_FACTORY; } - + AttributeSource::AttributeSource() { this->attributes = MapStringAttribute::newInstance(); this->factory = AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY(); } - + AttributeSource::AttributeSource(AttributeSourcePtr input) { if (!input) @@ -47,44 +47,44 @@ namespace Lucene this->attributes = input->attributes; this->factory = input->factory; } - + AttributeSource::AttributeSource(AttributeFactoryPtr factory) { this->attributes = MapStringAttribute::newInstance(); this->factory = factory; } - + AttributeSource::~AttributeSource() { } - + AttributeFactoryPtr AttributeSource::getAttributeFactory() { return this->factory; } - + void AttributeSource::addAttribute(const String& className, AttributePtr attrImpl) { // invalidate state to force recomputation in captureState() currentState.reset(); attributes.put(className, attrImpl); } - + bool AttributeSource::hasAttributes() { return !attributes.empty(); } - + AttributePtr AttributeSource::getAttribute(const String& className) { return attributes.get(className); } - + bool AttributeSource::hasAttribute(const String& className) { return attributes.contains(className); } - + void AttributeSource::computeCurrentState() { currentState = newLucene(); @@ -100,7 +100,7 @@ namespace Lucene ++attrImpl; } } - + void AttributeSource::clearAttributes() { if (hasAttributes()) @@ -111,23 +111,23 @@ namespace Lucene attrImpl->second->clear(); } } - + AttributeSourceStatePtr AttributeSource::captureState() { if (!hasAttributes()) return AttributeSourceStatePtr(); - + if (!currentState) computeCurrentState(); - + return boost::dynamic_pointer_cast(currentState->clone()); } - + void AttributeSource::restoreState(AttributeSourceStatePtr state) { if (!state) return; - + do { MapStringAttribute::iterator attrImpl = attributes.find(state->attribute->getClassName()); @@ -138,7 +138,7 @@ namespace Lucene } while (state); } - + int32_t AttributeSource::hashCode() { int32_t code = 0; @@ -146,12 +146,12 @@ namespace Lucene code = code * 31 + attrImpl->second->hashCode(); return code; } - + bool AttributeSource::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) return true; - + AttributeSourcePtr otherAttributeSource = boost::dynamic_pointer_cast(other); if (otherAttributeSource) { @@ -159,18 +159,18 @@ namespace Lucene { if (!otherAttributeSource->hasAttributes()) return false; - + if (attributes.size() != otherAttributeSource->attributes.size()) return false; - + // it is only equal if all attribute impls are the same in the same order if (!currentState) computeCurrentState(); - + AttributeSourceStatePtr thisState(currentState); if (!otherAttributeSource->currentState) otherAttributeSource->computeCurrentState(); - + AttributeSourceStatePtr otherState(otherAttributeSource->currentState); while (thisState && otherState) { @@ -187,7 +187,7 @@ namespace Lucene else return false; } - + String AttributeSource::toString() { StringStream buf; @@ -206,11 +206,11 @@ namespace Lucene buf << ")"; return buf.str(); } - + AttributeSourcePtr AttributeSource::cloneAttributes() { AttributeSourcePtr clone(newLucene(this->factory)); - + if (hasAttributes()) { if (!currentState) @@ -218,10 +218,10 @@ namespace Lucene for (AttributeSourceStatePtr state(currentState); state; state = state->next) clone->attributes.put(state->attribute->getClassName(), boost::dynamic_pointer_cast(state->attribute->clone())); } - + return clone; } - + Collection AttributeSource::getAttributes() { Collection attrImpls(Collection::newInstance()); @@ -234,28 +234,28 @@ namespace Lucene } return attrImpls; } - + DefaultAttributeFactory::~DefaultAttributeFactory() { } - + AttributePtr DefaultAttributeFactory::createAttributeInstance(const String& className) { return AttributePtr(); } - + AttributeSourceState::~AttributeSourceState() { } - + LuceneObjectPtr AttributeSourceState::clone(LuceneObjectPtr other) { AttributeSourceStatePtr clone(newLucene()); clone->attribute = boost::dynamic_pointer_cast(attribute->clone()); - + if (next) clone->next = boost::dynamic_pointer_cast(next->clone()); - + return clone; } } diff --git a/src/core/util/Base64.cpp b/src/core/util/Base64.cpp index d18dc04b..cc399277 100644 --- a/src/core/util/Base64.cpp +++ b/src/core/util/Base64.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,23 +12,23 @@ namespace Lucene { const String Base64::BASE64_CHARS = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - + Base64::~Base64() { } - + String Base64::encode(ByteArray bytes) { return encode(bytes.get(), bytes.size()); } - + String Base64::encode(const uint8_t* bytes, int32_t length) { String result; uint8_t byteArray3[3]; uint8_t byteArray4[4]; int32_t i = 0; - + while (length--) { byteArray3[i++] = *(bytes++); @@ -63,16 +63,16 @@ namespace Lucene } return result; } - + ByteArray Base64::decode(const String& str) { int32_t length = str.length(); uint8_t byteArray4[4]; uint8_t byteArray3[3]; - + int32_t i = 0; int32_t charIndex = 0; - + ByteArray result(ByteArray::newInstance(length / 2)); int32_t resultIndex = 0; @@ -93,7 +93,7 @@ namespace Lucene result.resize((int32_t)((double)result.size() * 1.5)); result[resultIndex++] = byteArray3[i]; } - + i = 0; } } @@ -115,12 +115,12 @@ namespace Lucene result[resultIndex++] = byteArray3[j]; } } - + result.resize(resultIndex); return result; } - + bool Base64::isBase64(wchar_t ch) { return (UnicodeUtil::isAlnum(ch) || ch == L'+' || ch == L'/'); diff --git a/src/core/util/BitSet.cpp b/src/core/util/BitSet.cpp index e0af67f5..53615453 100644 --- a/src/core/util/BitSet.cpp +++ b/src/core/util/BitSet.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,69 +13,69 @@ namespace Lucene BitSet::BitSet(uint32_t size) : bitSet(size) { } - + BitSet::~BitSet() { } - + const uint64_t* BitSet::getBits() { return bitSet.empty() ? NULL : static_cast(&bitSet.m_bits[0]); } - + void BitSet::clear() { bitSet.clear(); } - + void BitSet::clear(uint32_t bitIndex) { if (bitIndex <= bitSet.size()) bitSet.set(bitIndex, false); } - + void BitSet::fastClear(uint32_t bitIndex) { bitSet.set(bitIndex, false); } - + void BitSet::clear(uint32_t fromIndex, uint32_t toIndex) { toIndex = std::min(toIndex, (uint32_t)bitSet.size()); for (bitset_type::size_type i = std::min(fromIndex, (uint32_t)bitSet.size()); i < toIndex; ++i) bitSet.set(i, false); } - + void BitSet::fastClear(uint32_t fromIndex, uint32_t toIndex) { for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) bitSet.set(i, false); } - + void BitSet::set(uint32_t bitIndex) { if (bitIndex >= bitSet.size()) resize(bitIndex + 1); bitSet.set(bitIndex, true); } - + void BitSet::fastSet(uint32_t bitIndex) { bitSet.set(bitIndex, true); } - + void BitSet::set(uint32_t bitIndex, bool value) { if (bitIndex >= bitSet.size()) resize(bitIndex + 1); bitSet.set(bitIndex, value); } - + void BitSet::fastSet(uint32_t bitIndex, bool value) { bitSet.set(bitIndex, value); } - + void BitSet::set(uint32_t fromIndex, uint32_t toIndex) { if (toIndex >= bitSet.size()) @@ -83,13 +83,13 @@ namespace Lucene for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) bitSet.set(i, true); } - + void BitSet::fastSet(uint32_t fromIndex, uint32_t toIndex) { for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) bitSet.set(i, true); } - + void BitSet::set(uint32_t fromIndex, uint32_t toIndex, bool value) { if (toIndex >= bitSet.size()) @@ -97,25 +97,25 @@ namespace Lucene for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) bitSet.set(i, value); } - + void BitSet::fastSet(uint32_t fromIndex, uint32_t toIndex, bool value) { for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) bitSet.set(i, value); } - + void BitSet::flip(uint32_t bitIndex) { if (bitIndex >= bitSet.size()) resize(bitIndex + 1); bitSet.flip(bitIndex); } - + void BitSet::fastFlip(uint32_t bitIndex) { bitSet.flip(bitIndex); } - + void BitSet::flip(uint32_t fromIndex, uint32_t toIndex) { if (toIndex >= bitSet.size()) @@ -123,44 +123,44 @@ namespace Lucene for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) bitSet.flip(i); } - + void BitSet::fastFlip(uint32_t fromIndex, uint32_t toIndex) { for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) bitSet.flip(i); } - + uint32_t BitSet::size() const { return bitSet.num_blocks() * sizeof(bitset_type::block_type) * 8; } - + uint32_t BitSet::numBlocks() const { return bitSet.num_blocks(); } - + bool BitSet::isEmpty() const { return bitSet.none(); } - + bool BitSet::get(uint32_t bitIndex) const { return bitIndex < bitSet.size() ? bitSet.test(bitIndex) : false; } - + bool BitSet::fastGet(uint32_t bitIndex) const { return bitSet.test(bitIndex); } - + int32_t BitSet::nextSetBit(uint32_t fromIndex) const { bitset_type::size_type next = fromIndex == 0 ? bitSet.find_first() : bitSet.find_next(fromIndex - 1); return next == bitset_type::npos ? -1 : next; } - + void BitSet::_and(BitSetPtr set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); @@ -169,7 +169,7 @@ namespace Lucene if (bitSet.num_blocks() > minBlocks) std::fill(bitSet.m_bits.begin() + minBlocks, bitSet.m_bits.end(), bitset_type::block_type(0)); } - + void BitSet::_or(BitSetPtr set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); @@ -180,7 +180,7 @@ namespace Lucene if (bitSet.num_blocks() > minBlocks) std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); } - + void BitSet::_xor(BitSetPtr set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); @@ -191,24 +191,24 @@ namespace Lucene if (bitSet.num_blocks() > minBlocks) std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); } - + void BitSet::andNot(BitSetPtr set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); for (bitset_type::size_type i = 0; i < minBlocks; ++i) bitSet.m_bits[i] &= ~set->bitSet.m_bits[i]; } - + bool BitSet::intersectsBitSet(BitSetPtr set) const { return bitSet.intersects(set->bitSet); } - + uint32_t BitSet::cardinality() { return bitSet.num_blocks() == 0 ? 0 : (uint32_t)BitUtil::pop_array((int64_t*)getBits(), 0, bitSet.num_blocks()); } - + void BitSet::resize(uint32_t size) { bitset_type::size_type old_num_blocks = bitSet.num_blocks(); @@ -220,7 +220,7 @@ namespace Lucene if (extra_bits != 0) bitSet.m_bits.back() &= ~(~static_cast(0) << extra_bits); } - + bool BitSet::equals(LuceneObjectPtr other) { if (LuceneObject::equals(other)) @@ -244,7 +244,7 @@ namespace Lucene } return true; } - + int32_t BitSet::hashCode() { // Start with a zero hash and use a mix that results in zero if the input is zero. @@ -257,11 +257,11 @@ namespace Lucene hash ^= bits[bit]; hash = (hash << 1) | (hash >> 63); // rotate left } - // Fold leftmost bits into right and add a constant to prevent empty sets from + // Fold leftmost bits into right and add a constant to prevent empty sets from // returning 0, which is too common. return (int32_t)((hash >> 32) ^ hash) + 0x98761234; } - + LuceneObjectPtr BitSet::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); diff --git a/src/core/util/BitUtil.cpp b/src/core/util/BitUtil.cpp index 8f79fac9..ebc86555 100644 --- a/src/core/util/BitUtil.cpp +++ b/src/core/util/BitUtil.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,7 @@ namespace Lucene { const uint8_t BitUtil::ntzTable[] = { - 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, @@ -21,11 +21,11 @@ namespace Lucene 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; - + BitUtil::~BitUtil() { } - + int32_t BitUtil::pop(int64_t x) { x = x - (MiscUtils::unsignedShift(x, (int64_t)1) & 0x5555555555555555LL); @@ -36,7 +36,7 @@ namespace Lucene x = x + MiscUtils::unsignedShift(x, (int64_t)32); return (int32_t)x & 0x7f; } - + int64_t BitUtil::pop_array(const int64_t* A, int32_t wordOffset, int32_t numWords) { int32_t n = wordOffset + numWords; @@ -45,76 +45,76 @@ namespace Lucene int64_t ones = 0; int64_t twos = 0; int64_t fours = 0; - + int32_t i = wordOffset; for (; i <= n - 8; i += 8) { int64_t twosA; CSA(twosA, ones, ones, A[i], A[i + 1]); - + int64_t twosB; CSA(twosB, ones, ones, A[i + 2], A[i + 3]); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + CSA(twosA, ones, ones, A[i + 4], A[i + 5]); - + CSA(twosB, ones, ones, A[i + 6], A[i + 7]); - + int64_t foursB; CSA(foursB, twos, twos, twosA, twosB); - + int64_t eights; CSA(eights, fours, fours, foursA, foursB); - + tot8 += pop(eights); } - + // Handle trailing words in a binary-search manner. // Derived from the loop above by setting specific elements to 0. - + if (i <= n - 4) { int64_t twosA; CSA(twosA, ones, ones, A[i], A[i + 1]); - + int64_t twosB; CSA(twosB, ones, ones, A[i + 2], A[i + 3]); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 4; } - + if (i <= n - 2) { int64_t twosA; CSA(twosA, ones, ones, A[i], A[i + 1]); - + int64_t foursA = twos & twosA; twos = twos ^ twosA; - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 2; } - + if (i < n) tot += pop(A[i]); - + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - + return tot; } - + int64_t BitUtil::pop_intersect(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { int32_t n = wordOffset + numWords; @@ -123,73 +123,73 @@ namespace Lucene int64_t ones = 0; int64_t twos = 0; int64_t fours = 0; - + int32_t i = wordOffset; for (; i <= n - 8; i += 8) { int64_t twosA; CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] & B[i + 2]), (A[i + 3] & B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + CSA(twosA, ones, ones, (A[i + 4] & B[i + 4]), (A[i + 5] & B[i + 5])); - + CSA(twosB, ones, ones, (A[i + 6] & B[i + 6]), (A[i + 7] & B[i + 7])); - + int64_t foursB; CSA(foursB, twos, twos, twosA, twosB); - + int64_t eights; CSA(eights, fours, fours, foursA, foursB); - + tot8 += pop(eights); } - + if (i <= n - 4) { int64_t twosA; CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] & B[i + 2]), (A[i + 3] & B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 4; } - + if (i <= n - 2) { int64_t twosA; CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); - + int64_t foursA = twos & twosA; twos = twos ^ twosA; - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 2; } - + if (i < n) tot += pop((A[i] & B[i])); - + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - + return tot; } - + int64_t BitUtil::pop_union(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { int32_t n = wordOffset + numWords; @@ -198,73 +198,73 @@ namespace Lucene int64_t ones = 0; int64_t twos = 0; int64_t fours = 0; - + int32_t i = wordOffset; for (; i <= n - 8; i += 8) { int64_t twosA; CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] | B[i + 2]), (A[i + 3] | B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + CSA(twosA, ones, ones, (A[i + 4] | B[i + 4]), (A[i + 5] | B[i + 5])); - + CSA(twosB, ones, ones, (A[i + 6] | B[i + 6]), (A[i + 7] | B[i + 7])); - + int64_t foursB; CSA(foursB, twos, twos, twosA, twosB); - + int64_t eights; CSA(eights, fours, fours, foursA, foursB); - + tot8 += pop(eights); } - + if (i <= n - 4) { int64_t twosA; CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] | B[i + 2]), (A[i + 3] | B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 4; } - + if (i <= n - 2) { int64_t twosA; CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); - + int64_t foursA = twos & twosA; twos = twos ^ twosA; - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 2; } - + if (i < n) tot += pop((A[i] | B[i])); - + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - + return tot; } - + int64_t BitUtil::pop_andnot(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { int32_t n = wordOffset + numWords; @@ -273,73 +273,73 @@ namespace Lucene int64_t ones = 0; int64_t twos = 0; int64_t fours = 0; - + int32_t i = wordOffset; for (; i <= n - 8; i += 8) { int64_t twosA; CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] & ~B[i + 2]), (A[i + 3] & ~B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + CSA(twosA, ones, ones, (A[i + 4] & ~B[i + 4]), (A[i + 5] & ~B[i + 5])); - + CSA(twosB, ones, ones, (A[i + 6] & ~B[i + 6]), (A[i + 7] & ~B[i + 7])); - + int64_t foursB; CSA(foursB, twos, twos, twosA, twosB); - + int64_t eights; CSA(eights, fours, fours, foursA, foursB); - + tot8 += pop(eights); } - + if (i <= n - 4) { int64_t twosA; CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] & ~B[i + 2]), (A[i + 3] & ~B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 4; } - + if (i <= n - 2) { int64_t twosA; CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); - + int64_t foursA = twos & twosA; twos = twos ^ twosA; - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 2; } - + if (i < n) tot += pop((A[i] & ~B[i])); - + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - + return tot; } - + int64_t BitUtil::pop_xor(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { int32_t n = wordOffset + numWords; @@ -348,70 +348,70 @@ namespace Lucene int64_t ones = 0; int64_t twos = 0; int64_t fours = 0; - + int32_t i = wordOffset; for (; i <= n - 8; i += 8) { int64_t twosA; CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] ^ B[i + 2]), (A[i + 3] ^ B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + CSA(twosA, ones, ones, (A[i + 4] ^ B[i + 4]), (A[i + 5] ^ B[i + 5])); - + CSA(twosB, ones, ones, (A[i + 6] ^ B[i + 6]), (A[i + 7] ^ B[i + 7])); - + int64_t foursB; CSA(foursB, twos, twos, twosA, twosB); - + int64_t eights; CSA(eights, fours, fours, foursA, foursB); - + tot8 += pop(eights); } - + if (i <= n - 4) { int64_t twosA; CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); - + int64_t twosB; CSA(twosB, ones, ones, (A[i + 2] ^ B[i + 2]), (A[i + 3] ^ B[i + 3])); - + int64_t foursA; CSA(foursA, twos, twos, twosA, twosB); - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 4; } - + if (i <= n - 2) { int64_t twosA; CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); - + int64_t foursA = twos & twosA; twos = twos ^ twosA; - + int64_t eights = fours & foursA; fours = fours ^ foursA; - + tot8 += pop(eights); i += 2; } - + if (i < n) tot += pop((A[i] ^ B[i])); - + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - + return tot; } @@ -421,22 +421,22 @@ namespace Lucene h = (a & b) | (u & c); l = u ^ c; } - + int32_t BitUtil::ntz(int64_t val) { - // A full binary search to determine the low byte was slower than a linear search for nextSetBit(). + // A full binary search to determine the low byte was slower than a linear search for nextSetBit(). // This is most likely because the implementation of nextSetBit() shifts bits to the right, increasing // the probability that the first non-zero byte is in the rhs. - - // This implementation does a single binary search at the top level only so that all other bit shifting - // can be done on ints instead of longs to remain friendly to 32 bit architectures. In addition, the + + // This implementation does a single binary search at the top level only so that all other bit shifting + // can be done on ints instead of longs to remain friendly to 32 bit architectures. In addition, the // case of a non-zero first byte is checked for first because it is the most common in dense bit arrays. - + int32_t lower = (int32_t)val; int32_t lowByte = lower & 0xff; if (lowByte != 0) return ntzTable[lowByte]; - + if (lower != 0) { lowByte = MiscUtils::unsignedShift(lower, 8) & 0xff; @@ -467,12 +467,12 @@ namespace Lucene return ntzTable[MiscUtils::unsignedShift(upper, 24)] + 56; } } - + int32_t BitUtil::ntz(int32_t val) { - // This implementation does a single binary search at the top level only. In addition, the case + // This implementation does a single binary search at the top level only. In addition, the case // of a non-zero first byte is checked for first because it is the most common in dense bit arrays. - + int32_t lowByte = val & 0xff; if (lowByte != 0) return ntzTable[lowByte]; @@ -486,7 +486,7 @@ namespace Lucene // no need to check for zero on the last byte either. return ntzTable[MiscUtils::unsignedShift(val, 24)] + 24; } - + int32_t BitUtil::ntz2(int64_t x) { int32_t n = 0; @@ -508,11 +508,11 @@ namespace Lucene } return (ntzTable[y & 0xff]) + n; } - + int32_t BitUtil::ntz3(int64_t x) { int32_t n = 1; - + // do the first step as a long, all others as ints. int32_t y = (int32_t)x; if (y == 0) @@ -542,17 +542,17 @@ namespace Lucene } return n - (y & 1); } - + bool BitUtil::isPowerOfTwo(int32_t v) { return ((v & (v - 1)) == 0); } - + bool BitUtil::isPowerOfTwo(int64_t v) { return ((v & (v - 1)) == 0); } - + int32_t BitUtil::nextHighestPowerOfTwo(int32_t v) { --v; @@ -563,7 +563,7 @@ namespace Lucene v |= v >> 16; return ++v; } - + int64_t BitUtil::nextHighestPowerOfTwo(int64_t v) { --v; diff --git a/src/core/util/BitVector.cpp b/src/core/util/BitVector.cpp index 8487ade3..66456144 100644 --- a/src/core/util/BitVector.cpp +++ b/src/core/util/BitVector.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,7 +25,7 @@ namespace Lucene 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; - + BitVector::BitVector(int32_t n) { _size = n; @@ -33,14 +33,14 @@ namespace Lucene MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); _count = 0; } - + BitVector::BitVector(ByteArray bits, int32_t size) { this->bits = bits; this->_size = size; this->_count = -1; } - + BitVector::BitVector(DirectoryPtr d, const String& name) { IndexInputPtr input(d->openInput(name)); @@ -60,11 +60,11 @@ namespace Lucene input->close(); finally.throwException(); } - + BitVector::~BitVector() { } - + LuceneObjectPtr BitVector::clone(LuceneObjectPtr other) { ByteArray copyBits(ByteArray::newInstance(bits.size())); @@ -73,7 +73,7 @@ namespace Lucene clone->_count = _count; return clone; } - + void BitVector::set(int32_t bit) { if (bit >= _size) @@ -81,7 +81,7 @@ namespace Lucene bits[bit >> 3] |= 1 << (bit & 7); _count = -1; } - + bool BitVector::getAndSet(int32_t bit) { if (bit >= _size) @@ -99,7 +99,7 @@ namespace Lucene return false; } } - + void BitVector::clear(int32_t bit) { if (bit >= _size) @@ -107,18 +107,18 @@ namespace Lucene bits[bit >> 3] &= ~(1 << (bit & 7)); _count = -1; } - + bool BitVector::get(int32_t bit) { BOOST_ASSERT(bit >= 0 && bit < _size); return (bits[bit >> 3] & (1 << (bit & 7))) != 0; } - + int32_t BitVector::size() { return _size; } - + int32_t BitVector::count() { // if the vector has been modified @@ -132,7 +132,7 @@ namespace Lucene } return _count; } - + int32_t BitVector::getRecomputedCount() { int32_t c = 0; @@ -141,7 +141,7 @@ namespace Lucene c += BYTE_COUNTS[bits[i] & 0xff]; // sum bits per byte return c; } - + void BitVector::write(DirectoryPtr d, const String& name) { TestScope testScope(L"BitVector", L"write"); @@ -161,14 +161,14 @@ namespace Lucene output->close(); finally.throwException(); } - + void BitVector::writeBits(IndexOutputPtr output) { output->writeInt(size()); // write size output->writeInt(count()); // write count output->writeBytes(bits.get(), bits.size()); } - + void BitVector::writeDgaps(IndexOutputPtr output) { output->writeInt(-1); // mark using d-gaps @@ -188,15 +188,15 @@ namespace Lucene } } } - + bool BitVector::isSparse() { // note: order of comparisons below set to favor smaller values (no binary range search.) // note: adding 4 because we start with ((int) -1) to indicate d-gaps format. // note: we write the d-gap for the byte number, and the byte (bits[i]) itself, therefore // multiplying count by (8+8) or (8+16) or (8+24) etc.: - // - first 8 for writing bits[i] (1 byte vs. 1 bit), and - // - second part for writing the byte-number d-gap as vint. + // - first 8 for writing bits[i] (1 byte vs. 1 bit), and + // - second part for writing the byte-number d-gap as vint. // note: factor is for read/write of byte-arrays being faster than vints. int32_t factor = 10; if (bits.size() < (1 << 7)) @@ -209,7 +209,7 @@ namespace Lucene return factor * (4 + (8 + 32) * count()) < size(); return factor * (4 + (8 + 40) * count()) < size(); } - + void BitVector::readBits(IndexInputPtr input) { _count = input->readInt(); // read count @@ -217,7 +217,7 @@ namespace Lucene MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); input->readBytes(bits.get(), 0, bits.size()); } - + void BitVector::readDgaps(IndexInputPtr input) { _size = input->readInt(); // (re)read size @@ -233,7 +233,7 @@ namespace Lucene n -= BYTE_COUNTS[bits[last] & 0xff]; } } - + BitVectorPtr BitVector::subset(int32_t start, int32_t end) { if (start < 0 || end > size() || end < start) diff --git a/src/core/util/BufferedReader.cpp b/src/core/util/BufferedReader.cpp index 41379c59..054d1a2d 100644 --- a/src/core/util/BufferedReader.cpp +++ b/src/core/util/BufferedReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,7 +11,7 @@ namespace Lucene { const int32_t BufferedReader::READER_BUFFER = 8192; - + BufferedReader::BufferedReader(ReaderPtr reader, int32_t size) { this->reader = reader; @@ -19,11 +19,11 @@ namespace Lucene this->bufferLength = 0; this->bufferPosition = 0; } - + BufferedReader::~BufferedReader() { } - + int32_t BufferedReader::read() { if (bufferPosition >= bufferLength) @@ -33,7 +33,7 @@ namespace Lucene } return buffer[bufferPosition++]; } - + int32_t BufferedReader::peek() { if (bufferPosition >= bufferLength) @@ -43,18 +43,18 @@ namespace Lucene } return buffer[bufferPosition]; } - + int32_t BufferedReader::read(wchar_t* b, int32_t offset, int32_t length) { if (length == 0) return 0; int32_t remaining = length; - + while (remaining > 0) { int32_t available = bufferLength - bufferPosition; - + if (remaining <= available) { // the buffer contains enough data to satisfy this request @@ -76,10 +76,10 @@ namespace Lucene break; } } - + return length == 0 ? READER_EOF : length; } - + bool BufferedReader::readLine(String& line) { line.clear(); @@ -93,7 +93,7 @@ namespace Lucene read(); return (!line.empty() || ch != (wchar_t)READER_EOF); } - + int32_t BufferedReader::refill() { if (!buffer) @@ -110,12 +110,12 @@ namespace Lucene bufferLength = 0; bufferPosition = 0; } - + bool BufferedReader::markSupported() { return false; } - + void BufferedReader::reset() { reader->reset(); diff --git a/src/core/util/CharFolder.cpp b/src/core/util/CharFolder.cpp index 99db0f34..f0b73e7b 100644 --- a/src/core/util/CharFolder.cpp +++ b/src/core/util/CharFolder.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,24 +19,24 @@ namespace Lucene CharFolder::~CharFolder() { } - + wchar_t CharFolder::toLower(wchar_t ch) { return (ch > CHAR_MIN && ch < CHAR_MAX) ? lowerChars[ch - CHAR_MIN] : UnicodeUtil::toLower(ch); } - + wchar_t CharFolder::toUpper(wchar_t ch) { return (ch > CHAR_MIN && ch < CHAR_MAX) ? upperChars[ch - CHAR_MIN] : UnicodeUtil::toUpper(ch); } - + bool CharFolder::fillLower() { for (int32_t index = CHAR_MIN; index < CHAR_MAX; ++index) lowerChars[index - CHAR_MIN] = UnicodeUtil::toLower((wchar_t)index); return true; } - + bool CharFolder::fillUpper() { for (int32_t index = CHAR_MIN; index < CHAR_MAX; ++index) diff --git a/src/core/util/Collator.cpp b/src/core/util/Collator.cpp index 5f96d774..b46cdd34 100644 --- a/src/core/util/Collator.cpp +++ b/src/core/util/Collator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,11 +13,11 @@ namespace Lucene Collator::Collator(std::locale locale) : collate(std::use_facet< std::collate >(locale)) { } - + Collator::~Collator() { } - + int32_t Collator::compare(const String& first, const String& second) { return collate.compare(first.c_str(), first.c_str() + first.length(), second.c_str(), second.c_str() + second.length()); diff --git a/src/core/util/Constants.cpp b/src/core/util/Constants.cpp index 4c374b77..9be563b3 100644 --- a/src/core/util/Constants.cpp +++ b/src/core/util/Constants.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/util/CycleCheck.cpp b/src/core/util/CycleCheck.cpp index 12a9ac1d..63148e77 100644 --- a/src/core/util/CycleCheck.cpp +++ b/src/core/util/CycleCheck.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/util/DocIdBitSet.cpp b/src/core/util/DocIdBitSet.cpp index 673785ad..9feaaf1a 100644 --- a/src/core/util/DocIdBitSet.cpp +++ b/src/core/util/DocIdBitSet.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,31 +14,31 @@ namespace Lucene DocIdBitSet::DocIdBitSet() { } - + DocIdBitSet::DocIdBitSet(BitSetPtr bitSet) { this->bitSet = bitSet; } - + DocIdBitSet::~DocIdBitSet() { } - + DocIdSetIteratorPtr DocIdBitSet::iterator() { return newLucene(bitSet); } - + bool DocIdBitSet::isCacheable() { return true; } - + BitSetPtr DocIdBitSet::getBitSet() { return bitSet; } - + bool DocIdBitSet::equals(LuceneObjectPtr other) { if (DocIdSet::equals(other)) @@ -46,12 +46,12 @@ namespace Lucene DocIdBitSetPtr otherBitSet(boost::dynamic_pointer_cast(other)); return bitSet->equals(otherBitSet->bitSet); } - + int32_t DocIdBitSet::hashCode() { return bitSet->hashCode(); } - + LuceneObjectPtr DocIdBitSet::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = other ? other : newLucene(); @@ -59,29 +59,29 @@ namespace Lucene cloneBitSet->bitSet = boost::dynamic_pointer_cast(bitSet->clone()); return cloneBitSet; } - + DocIdBitSetIterator::DocIdBitSetIterator(BitSetPtr bitSet) { this->bitSet = bitSet; this->docId = -1; } - + DocIdBitSetIterator::~DocIdBitSetIterator() { } - + int32_t DocIdBitSetIterator::docID() { return docId; } - + int32_t DocIdBitSetIterator::nextDoc() { int32_t doc = bitSet->nextSetBit(docId + 1); docId = doc == -1 ? NO_MORE_DOCS : doc; return docId; } - + int32_t DocIdBitSetIterator::advance(int32_t target) { int32_t doc = bitSet->nextSetBit(target); diff --git a/src/core/util/FieldCacheSanityChecker.cpp b/src/core/util/FieldCacheSanityChecker.cpp index 8090856b..ef6b46d7 100644 --- a/src/core/util/FieldCacheSanityChecker.cpp +++ b/src/core/util/FieldCacheSanityChecker.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,82 +17,82 @@ namespace Lucene FieldCacheSanityChecker::FieldCacheSanityChecker() { } - + FieldCacheSanityChecker::~FieldCacheSanityChecker() { } - + Collection FieldCacheSanityChecker::checkSanity(FieldCachePtr cache) { return checkSanity(cache->getCacheEntries()); } - + Collection FieldCacheSanityChecker::checkSanity(Collection cacheEntries) { FieldCacheSanityCheckerPtr sanityChecker(newLucene()); return sanityChecker->check(cacheEntries); } - + Collection FieldCacheSanityChecker::check(Collection cacheEntries) { if (!cacheEntries || cacheEntries.empty()) return Collection::newInstance(); - + // Maps the (valId) identityhashCode of cache values to sets of CacheEntry instances MapSetIntFieldCacheEntry valIdToItems(MapSetIntFieldCacheEntry::map_type::newInstance()); - + // Maps ReaderField keys to Sets of ValueIds MapSetReaderFieldInt readerFieldToValIds(MapSetReaderFieldInt::map_type::newInstance()); - + // Any keys that we know result in more then one valId SetReaderField valMismatchKeys(SetReaderField::newInstance()); - + // iterate over all the cacheEntries to get the mappings we'll need for (int32_t i = 0; i < cacheEntries.size(); ++i) { FieldCacheEntryPtr item(cacheEntries[i]); boost::any val(item->getValue()); - + if (VariantUtils::typeOf(val)) continue; - + ReaderFieldPtr rf(newLucene(item->getReaderKey(), item->getFieldName())); int32_t valId = VariantUtils::hashCode(val); - + // indirect mapping, so the MapOfSet will dedup identical valIds for us valIdToItems.put(valId, item); if (1 < readerFieldToValIds.put(rf, valId)) valMismatchKeys.add(rf); } - + Collection insanity(Collection::newInstance()); - + Collection mismatch(checkValueMismatch(valIdToItems, readerFieldToValIds, valMismatchKeys)); insanity.addAll(mismatch.begin(), mismatch.end()); - + Collection subreaders(checkSubreaders(valIdToItems, readerFieldToValIds)); insanity.addAll(subreaders.begin(), subreaders.end()); - + return insanity; } - + Collection FieldCacheSanityChecker::checkValueMismatch(MapSetIntFieldCacheEntry valIdToItems, MapSetReaderFieldInt readerFieldToValIds, SetReaderField valMismatchKeys) { Collection insanity(Collection::newInstance()); - + if (!valMismatchKeys.empty()) { // we have multiple values for some ReaderFields - + MapSetReaderFieldInt::map_type rfMap = readerFieldToValIds.getMap(); MapSetIntFieldCacheEntry::map_type valMap = valIdToItems.getMap(); - + for (SetReaderField::iterator rf = valMismatchKeys.begin(); rf != valMismatchKeys.end(); ++rf) { Collection badEntries(Collection::newInstance()); - + MapSetReaderFieldInt::set_type values(rfMap.get(*rf)); for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) { @@ -100,36 +100,36 @@ namespace Lucene for (MapSetIntFieldCacheEntry::set_type::iterator cacheEntry = cacheEntries.begin(); cacheEntry != cacheEntries.end(); ++cacheEntry) badEntries.add(*cacheEntry); } - + insanity.add(newLucene(VALUEMISMATCH, L"Multiple distinct value objects for " + (*rf)->toString(), badEntries)); } } return insanity; } - - Collection FieldCacheSanityChecker::checkSubreaders(MapSetIntFieldCacheEntry valIdToItems, + + Collection FieldCacheSanityChecker::checkSubreaders(MapSetIntFieldCacheEntry valIdToItems, MapSetReaderFieldInt readerFieldToValIds) { Collection insanity(Collection::newInstance()); - + MapReaderFieldSetReaderField badChildren(MapReaderFieldSetReaderField::newInstance()); MapSetReaderFieldReaderField badKids(badChildren); // wrapper MapSetIntFieldCacheEntry::map_type viToItemSets = valIdToItems.getMap(); MapSetReaderFieldInt::map_type rfToValIdSets = readerFieldToValIds.getMap(); - + SetReaderField seen(SetReaderField::newInstance()); - + for (MapSetReaderFieldInt::map_type::iterator rf = rfToValIdSets.begin(); rf != rfToValIdSets.end(); ++rf) { if (seen.contains(rf->first)) continue; - + Collection kids(getAllDecendentReaderKeys(rf->first->readerKey)); for (Collection::iterator kidKey = kids.begin(); kidKey != kids.end(); ++kidKey) { ReaderFieldPtr kid(newLucene(*kidKey, rf->first->fieldName)); - + if (badChildren.contains(kid)) { // we've already process this kid as RF and found other problems track those problems as our own @@ -146,13 +146,13 @@ namespace Lucene } seen.add(rf->first); } - + // every mapping in badKids represents an Insanity for (MapReaderFieldSetReaderField::iterator parent = badChildren.begin(); parent != badChildren.end(); ++parent) { SetReaderField kids = parent->second; Collection badEntries(Collection::newInstance()); - + // put parent entries in first MapSetReaderFieldInt::set_type values(rfToValIdSets.get(parent->first)); for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) @@ -160,7 +160,7 @@ namespace Lucene MapSetIntFieldCacheEntry::set_type cacheEntries(viToItemSets.get(*value)); badEntries.addAll(cacheEntries.begin(), cacheEntries.end()); } - + // now the entries for the descendants for (SetReaderField::iterator kid = kids.begin(); kid != kids.end(); ++kid) { @@ -171,13 +171,13 @@ namespace Lucene badEntries.addAll(cacheEntries.begin(), cacheEntries.end()); } } - + insanity.add(newLucene(SUBREADER, L"Found caches for descendants of " + parent->first->toString(), badEntries)); } - + return insanity; } - + Collection FieldCacheSanityChecker::getAllDecendentReaderKeys(LuceneObjectPtr seed) { Collection all(Collection::newInstance()); // will grow as we iter @@ -192,27 +192,27 @@ namespace Lucene all.add(subs[j]->getFieldCacheKey()); } } - + // need to remove the first, because it was the seed all.remove(all.begin()); return all; } - + ReaderField::ReaderField(LuceneObjectPtr readerKey, const String& fieldName) { this->readerKey = readerKey; this->fieldName = fieldName; } - + ReaderField::~ReaderField() { } - + int32_t ReaderField::hashCode() { return readerKey->hashCode() * StringUtils::hashCode(fieldName); } - + bool ReaderField::equals(LuceneObjectPtr other) { ReaderFieldPtr otherReaderField(boost::dynamic_pointer_cast(other)); @@ -220,12 +220,12 @@ namespace Lucene return false; return (readerKey->equals(otherReaderField->readerKey) && fieldName == otherReaderField->fieldName); } - + String ReaderField::toString() { return readerKey->toString() + L"+" + fieldName; } - + Insanity::Insanity(FieldCacheSanityChecker::InsanityType type, const String& msg, Collection entries) { if (!entries || entries.empty()) @@ -234,26 +234,26 @@ namespace Lucene this->msg = msg; this->entries = entries; } - + Insanity::~Insanity() { } - + FieldCacheSanityChecker::InsanityType Insanity::getType() { return type; } - + String Insanity::getMsg() { return msg; } - + Collection Insanity::getCacheEntries() { return entries; } - + String Insanity::toString() { StringStream buffer; @@ -270,10 +270,10 @@ namespace Lucene break; } buffer << msg << L"\n"; - + for (Collection::iterator ce = entries.begin(); ce != entries.end(); ++ce) buffer << L"\t" << (*ce)->toString() << L"\n"; - + return buffer.str(); } } diff --git a/src/core/util/FileReader.cpp b/src/core/util/FileReader.cpp index 085789ee..6975ad4a 100644 --- a/src/core/util/FileReader.cpp +++ b/src/core/util/FileReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene { const int32_t FileReader::FILE_EOF = Reader::READER_EOF; const int32_t FileReader::FILE_ERROR = -1; - + FileReader::FileReader(const String& fileName) { this->file = newInstance(fileName, std::ios::binary | std::ios::in); @@ -23,17 +23,17 @@ namespace Lucene boost::throw_exception(FileNotFoundException(fileName)); _length = FileUtils::fileLength(fileName); } - + FileReader::~FileReader() { } - + int32_t FileReader::read() { wchar_t buffer; return read(&buffer, 0, 1) == FILE_EOF ? FILE_EOF : buffer; } - + int32_t FileReader::read(wchar_t* buffer, int32_t offset, int32_t length) { try @@ -54,23 +54,23 @@ namespace Lucene return FILE_ERROR; } } - + void FileReader::close() { file->close(); } - + bool FileReader::markSupported() { return false; } - + void FileReader::reset() { file->clear(); file->seekg((std::streamoff)0); } - + int64_t FileReader::length() { return _length; diff --git a/src/core/util/FileUtils.cpp b/src/core/util/FileUtils.cpp index 8d491d0b..ee070619 100644 --- a/src/core/util/FileUtils.cpp +++ b/src/core/util/FileUtils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -35,7 +35,7 @@ namespace Lucene return false; } } - + uint64_t fileModified(const String& path) { try @@ -47,7 +47,7 @@ namespace Lucene return 0; } } - + bool touchFile(const String& path) { try @@ -60,7 +60,7 @@ namespace Lucene return false; } } - + int64_t fileLength(const String& path) { try @@ -97,7 +97,7 @@ namespace Lucene return false; } } - + bool removeFile(const String& path) { try @@ -109,7 +109,7 @@ namespace Lucene return false; } } - + bool copyFile(const String& source, const String& dest) { try @@ -122,7 +122,7 @@ namespace Lucene return false; } } - + bool createDirectory(const String& path) { try @@ -134,7 +134,7 @@ namespace Lucene return false; } } - + bool removeDirectory(const String& path) { try @@ -147,7 +147,7 @@ namespace Lucene return false; } } - + bool isDirectory(const String& path) { try @@ -159,7 +159,7 @@ namespace Lucene return false; } } - + bool listDirectory(const String& path, bool filesOnly, HashSet dirList) { try @@ -176,7 +176,7 @@ namespace Lucene return false; } } - + bool copyDirectory(const String& source, const String& dest) { try @@ -184,12 +184,12 @@ namespace Lucene HashSet dirList(HashSet::newInstance()); if (!listDirectory(source, true, dirList)) return false; - + createDirectory(dest); - + for (HashSet::iterator file = dirList.begin(); file != dirList.end(); ++file) copyFile(joinPath(source, *file), joinPath(dest, *file)); - + return true; } catch (...) @@ -197,7 +197,7 @@ namespace Lucene return false; } } - + String joinPath(const String& path, const String& file) { try @@ -211,7 +211,7 @@ namespace Lucene return path; } } - + String extractPath(const String& path) { try @@ -224,7 +224,7 @@ namespace Lucene return path; } } - + String extractFile(const String& path) { try diff --git a/src/core/util/InfoStream.cpp b/src/core/util/InfoStream.cpp index 04f92d4e..984b32ca 100644 --- a/src/core/util/InfoStream.cpp +++ b/src/core/util/InfoStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,39 +14,39 @@ namespace Lucene InfoStream::InfoStream() { } - + InfoStream::~InfoStream() { } - + InfoStreamFile::InfoStreamFile(const String& path) : file(path) { } - + InfoStreamFile::~InfoStreamFile() { } - + InfoStreamFile& InfoStreamFile::operator<< (const String& t) { file << t; return *this; } - + InfoStreamOut::~InfoStreamOut() { } - + InfoStreamOut& InfoStreamOut::operator<< (const String& t) { std::wcout << t; return *this; } - + InfoStreamNull::~InfoStreamNull() { } - + InfoStreamNull& InfoStreamNull::operator<< (const String& t) { return *this; diff --git a/src/core/util/InputStreamReader.cpp b/src/core/util/InputStreamReader.cpp index f1ed70f6..c2f414a4 100644 --- a/src/core/util/InputStreamReader.cpp +++ b/src/core/util/InputStreamReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,32 +16,32 @@ namespace Lucene this->reader = reader; this->decoder = newLucene(newLucene(reader, 1024)); } - + InputStreamReader::~InputStreamReader() { } - + int32_t InputStreamReader::read() { int32_t buffer; return read((wchar_t*)&buffer, 0, 1) == READER_EOF ? READER_EOF : buffer; } - + int32_t InputStreamReader::read(wchar_t* b, int32_t offset, int32_t length) { return decoder->decode(b + offset, length); } - + void InputStreamReader::close() { reader->close(); } - + bool InputStreamReader::markSupported() { return false; } - + void InputStreamReader::reset() { reader->reset(); diff --git a/src/core/util/LuceneAllocator.cpp b/src/core/util/LuceneAllocator.cpp index 7c2d2bb3..b9588d3e 100644 --- a/src/core/util/LuceneAllocator.cpp +++ b/src/core/util/LuceneAllocator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/util/LuceneException.cpp b/src/core/util/LuceneException.cpp index 7ae4f0f9..7261d022 100644 --- a/src/core/util/LuceneException.cpp +++ b/src/core/util/LuceneException.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,26 +14,26 @@ namespace Lucene this->error = error; this->type = type; } - + LuceneException::~LuceneException() throw() { } - + LuceneException::ExceptionType LuceneException::getType() const { return type; } - + String LuceneException::getError() const { return error; } - + bool LuceneException::isNull() const { return (type == Null); } - + void LuceneException::throwException() { switch (type) diff --git a/src/core/util/LuceneObject.cpp b/src/core/util/LuceneObject.cpp index eb509baf..c9ec00c0 100644 --- a/src/core/util/LuceneObject.cpp +++ b/src/core/util/LuceneObject.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,34 +17,34 @@ namespace Lucene LuceneObject::~LuceneObject() { } - + void LuceneObject::initialize() { // override } - + LuceneObjectPtr LuceneObject::clone(LuceneObjectPtr other) { if (!other) boost::throw_exception(UnsupportedOperationException(L"clone must not be null")); return other; } - + int32_t LuceneObject::hashCode() { return (int32_t)(int64_t)this; } - + bool LuceneObject::equals(LuceneObjectPtr other) { return (other && this == other.get()); } - + int32_t LuceneObject::compareTo(LuceneObjectPtr other) { return (int32_t)(this - other.get()); } - + String LuceneObject::toString() { return StringUtils::toString(hashCode()); diff --git a/src/core/util/LuceneSignal.cpp b/src/core/util/LuceneSignal.cpp index 6dd2c32d..74d0ad26 100644 --- a/src/core/util/LuceneSignal.cpp +++ b/src/core/util/LuceneSignal.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,11 +14,11 @@ namespace Lucene { this->objectLock = objectLock; } - + LuceneSignal::~LuceneSignal() { } - + void LuceneSignal::createSignal(LuceneSignalPtr& signal, SynchronizePtr objectLock) { static boost::mutex lockMutex; @@ -26,7 +26,7 @@ namespace Lucene if (!signal) signal = newInstance(objectLock); } - + void LuceneSignal::wait(int32_t timeout) { int32_t relockCount = objectLock ? objectLock->unlockAll() : 0; @@ -39,7 +39,7 @@ namespace Lucene for (int32_t relock = 0; relock < relockCount; ++relock) objectLock->lock(); } - + void LuceneSignal::notifyAll() { signalCondition.notify_all(); diff --git a/src/core/util/LuceneSync.cpp b/src/core/util/LuceneSync.cpp index 49e0b854..d2065d60 100644 --- a/src/core/util/LuceneSync.cpp +++ b/src/core/util/LuceneSync.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,33 +20,33 @@ namespace Lucene Synchronize::createSync(objectLock); return objectLock; } - + LuceneSignalPtr LuceneSync::getSignal() { LuceneSignal::createSignal(objectSignal, getSync()); return objectSignal; } - + void LuceneSync::lock(int32_t timeout) { getSync()->lock(); } - + void LuceneSync::unlock() { getSync()->unlock(); } - + bool LuceneSync::holdsLock() { return getSync()->holdsLock(); } - + void LuceneSync::wait(int32_t timeout) { getSignal()->wait(timeout); } - + void LuceneSync::notifyAll() { getSignal()->notifyAll(); diff --git a/src/core/util/LuceneThread.cpp b/src/core/util/LuceneThread.cpp index 17066315..977a15a6 100644 --- a/src/core/util/LuceneThread.cpp +++ b/src/core/util/LuceneThread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/util/MiscUtils.cpp b/src/core/util/MiscUtils.cpp index c04cc71b..e5f21e68 100644 --- a/src/core/util/MiscUtils.cpp +++ b/src/core/util/MiscUtils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,23 +23,23 @@ namespace Lucene { return boost::posix_time::time_duration(time - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_milliseconds(); } - + uint64_t MiscUtils::currentTimeMillis() { return getTimeMillis(boost::posix_time::microsec_clock::universal_time()); } - + int32_t MiscUtils::getNextSize(int32_t targetSize) { return (targetSize >> 3) + (targetSize < 9 ? 3 : 6) + targetSize; } - + int32_t MiscUtils::getShrinkSize(int32_t currentSize, int32_t targetSize) { int32_t newSize = getNextSize(targetSize); return (newSize < currentSize / 2) ? newSize : currentSize; } - + int32_t MiscUtils::bytesDifference(uint8_t* bytes1, int32_t len1, uint8_t* bytes2, int32_t len2) { int32_t len = std::min(len1, len2); @@ -50,37 +50,37 @@ namespace Lucene } return len; } - + int32_t MiscUtils::hashCode(const wchar_t* array, int32_t start, int32_t end) { return hashCode(array + start, array + end, hashNumeric); } - + int32_t MiscUtils::hashCode(const uint8_t* array, int32_t start, int32_t end) { return hashCode(array + start, array + end, hashNumeric); } - + int32_t MiscUtils::hashCode(bool value) { return value ? 1231 : 1237; } - + int32_t MiscUtils::doubleToIntBits(double value) { int32_t intValue = 0; float floatValue = (float)value; std::memcpy(&intValue, &floatValue, sizeof(float)); - + if ((intValue & SINGLE_EXPONENT_MASK) == SINGLE_EXPONENT_MASK) { if (intValue & SINGLE_MANTISSA_MASK) return SINGLE_NAN_BITS; } - + return intValue; } - + int32_t MiscUtils::doubleToRawIntBits(double value) { int32_t intValue = 0; @@ -88,35 +88,35 @@ namespace Lucene std::memcpy(&intValue, &floatValue, sizeof(float)); return intValue; } - + double MiscUtils::intBitsToDouble(int32_t bits) { float floatValue = 0; std::memcpy(&floatValue, &bits, sizeof(int32_t)); return (double)floatValue; } - + int64_t MiscUtils::doubleToLongBits(double value) { int64_t longValue = 0; std::memcpy(&longValue, &value, sizeof(double)); - + if ((longValue & DOUBLE_EXPONENT_MASK) == DOUBLE_EXPONENT_MASK) { if (longValue & DOUBLE_MANTISSA_MASK) return DOUBLE_NAN_BITS; } - + return longValue; } - + int64_t MiscUtils::doubleToRawLongBits(double value) { int64_t longValue = 0; std::memcpy(&longValue, &value, sizeof(double)); return longValue; } - + double MiscUtils::longBitsToDouble(int64_t bits) { double doubleValue = 0; @@ -128,22 +128,22 @@ namespace Lucene { return (value == std::numeric_limits::infinity() || value == -std::numeric_limits::infinity()); } - + bool MiscUtils::isNaN(double value) { return (value != value); } - + bool MiscUtils::equalTypes(LuceneObjectPtr first, LuceneObjectPtr second) { return (typeid(*first) == typeid(*second)); } - + int64_t MiscUtils::unsignedShift(int64_t num, int64_t shift) { return (shift & 0x3f) == 0 ? num : (((uint64_t)num >> 1) & 0x7fffffffffffffffLL) >> ((shift & 0x3f) - 1); } - + int32_t MiscUtils::unsignedShift(int32_t num, int32_t shift) { return (shift & 0x1f) == 0 ? num : (((uint32_t)num >> 1) & 0x7fffffff) >> ((shift & 0x1f) - 1); diff --git a/src/core/util/NumericUtils.cpp b/src/core/util/NumericUtils.cpp index 6b6ee5df..7cb5839c 100644 --- a/src/core/util/NumericUtils.cpp +++ b/src/core/util/NumericUtils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,11 +11,11 @@ namespace Lucene { - /// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, + /// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, /// and {@link NumericRangeFilter} as default. const int32_t NumericUtils::PRECISION_STEP_DEFAULT = 4; - /// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + + /// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + /// shift in the first character. const wchar_t NumericUtils::SHIFT_START_LONG = (wchar_t)0x20; @@ -30,11 +30,11 @@ namespace Lucene /// The maximum term length (used for char[] buffer size) for encoding int values. /// @see #intToPrefixCoded(int,int,char[]) const int32_t NumericUtils::BUF_SIZE_INT = 31 / 7 + 2; - + NumericUtils::~NumericUtils() { } - + int32_t NumericUtils::longToPrefixCoded(int64_t val, int32_t shift, CharArray buffer) { if (shift > 63 || shift < 0) @@ -46,26 +46,26 @@ namespace Lucene sortableBits = MiscUtils::unsignedShift(sortableBits, (int64_t)shift); while (nChars >= 1) { - // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is + // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is // right-justified so that lucene can prefix-encode the terms more efficiently. buffer[nChars--] = (wchar_t)(sortableBits & 0x7f); sortableBits = MiscUtils::unsignedShift(sortableBits, (int64_t)7); } return len; } - + String NumericUtils::longToPrefixCoded(int64_t val, int32_t shift) { CharArray buffer(CharArray::newInstance(BUF_SIZE_LONG)); int32_t len = longToPrefixCoded(val, shift, buffer); return String(buffer.get(), len); } - + String NumericUtils::longToPrefixCoded(int64_t val) { return longToPrefixCoded(val, 0); } - + int32_t NumericUtils::intToPrefixCoded(int32_t val, int32_t shift, CharArray buffer) { if (shift > 31 || shift < 0) @@ -77,26 +77,26 @@ namespace Lucene sortableBits = MiscUtils::unsignedShift(sortableBits, shift); while (nChars >= 1) { - // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is + // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is // right-justified so that lucene can prefix-encode the terms more efficiently. buffer[nChars--] = (wchar_t)(sortableBits & 0x7f); sortableBits = MiscUtils::unsignedShift(sortableBits, 7); } return len; } - + String NumericUtils::intToPrefixCoded(int32_t val, int32_t shift) { CharArray buffer(CharArray::newInstance(BUF_SIZE_INT)); int32_t len = intToPrefixCoded(val, shift, buffer); return String(buffer.get(), len); } - + String NumericUtils::intToPrefixCoded(int32_t val) { return intToPrefixCoded(val, 0); } - + int64_t NumericUtils::prefixCodedToLong(const String& prefixCoded) { int32_t shift = prefixCoded[0] - SHIFT_START_LONG; @@ -116,7 +116,7 @@ namespace Lucene } return (sortableBits << shift) ^ 0x8000000000000000LL; } - + int32_t NumericUtils::prefixCodedToInt(const String& prefixCoded) { int32_t shift = prefixCoded[0] - SHIFT_START_INT; @@ -136,7 +136,7 @@ namespace Lucene } return (sortableBits << shift) ^ 0x80000000; } - + int64_t NumericUtils::doubleToSortableLong(double val) { int64_t f = MiscUtils::doubleToRawLongBits(val); @@ -144,34 +144,34 @@ namespace Lucene f ^= 0x7fffffffffffffffLL; return f; } - + String NumericUtils::doubleToPrefixCoded(double val) { return longToPrefixCoded(doubleToSortableLong(val)); } - + double NumericUtils::sortableLongToDouble(int64_t val) { if (val < 0) val ^= 0x7fffffffffffffffLL; return MiscUtils::longBitsToDouble(val); } - + double NumericUtils::prefixCodedToDouble(const String& val) { return sortableLongToDouble(prefixCodedToLong(val)); } - + void NumericUtils::splitLongRange(LongRangeBuilderPtr builder, int32_t precisionStep, int64_t minBound, int64_t maxBound) { splitRange(builder, 64, precisionStep, minBound, maxBound); } - + void NumericUtils::splitIntRange(IntRangeBuilderPtr builder, int32_t precisionStep, int32_t minBound, int32_t maxBound) { splitRange(builder, 32, precisionStep, (int64_t)minBound, (int64_t)maxBound); } - + void NumericUtils::splitRange(LuceneObjectPtr builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound) { if (precisionStep < 1) @@ -189,29 +189,29 @@ namespace Lucene int64_t nextMaxBound = ((hasUpper ? (maxBound - diff) : maxBound) & ~mask); bool lowerWrapped = nextMinBound < minBound; bool upperWrapped = nextMaxBound > maxBound; - + if (shift + precisionStep >= valSize || nextMinBound>nextMaxBound || lowerWrapped || upperWrapped) { // We are in the lowest precision or the next precision is not available. addRange(builder, valSize, minBound, maxBound, shift); break; // exit the split recursion loop } - + if (hasLower) addRange(builder, valSize, minBound, minBound | mask, shift); if (hasUpper) addRange(builder, valSize, maxBound & ~mask, maxBound, shift); - + // recurse to next precision minBound = nextMinBound; maxBound = nextMaxBound; } } - + void NumericUtils::addRange(LuceneObjectPtr builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift) { - // for the max bound set all lower bits (that were shifted away): this is important for testing or other - // usages of the splitted range (eg. to reconstruct the full range). The prefixEncoding will remove the + // for the max bound set all lower bits (that were shifted away): this is important for testing or other + // usages of the splitted range (eg. to reconstruct the full range). The prefixEncoding will remove the // bits anyway, so they do not hurt! maxBound |= ((int64_t)1 << shift) - (int64_t)1; // delegate to correct range builder @@ -227,30 +227,30 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64.")); } } - + LongRangeBuilder::~LongRangeBuilder() { } - + void LongRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { boost::throw_exception(UnsupportedOperationException()); } - + void LongRangeBuilder::addRange(int64_t min, int64_t max, int32_t shift) { addRange(NumericUtils::longToPrefixCoded(min, shift), NumericUtils::longToPrefixCoded(max, shift)); } - + IntRangeBuilder::~IntRangeBuilder() { } - + void IntRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { boost::throw_exception(UnsupportedOperationException()); } - + void IntRangeBuilder::addRange(int32_t min, int32_t max, int32_t shift) { addRange(NumericUtils::intToPrefixCoded(min, shift), NumericUtils::intToPrefixCoded(max, shift)); diff --git a/src/core/util/OpenBitSet.cpp b/src/core/util/OpenBitSet.cpp index 4646716e..70767657 100644 --- a/src/core/util/OpenBitSet.cpp +++ b/src/core/util/OpenBitSet.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/util/OpenBitSetDISI.cpp b/src/core/util/OpenBitSetDISI.cpp index cbda95d9..666e9a50 100644 --- a/src/core/util/OpenBitSetDISI.cpp +++ b/src/core/util/OpenBitSetDISI.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,15 +13,15 @@ namespace Lucene { inPlaceOr(disi); } - + OpenBitSetDISI::OpenBitSetDISI(int32_t maxSize) : OpenBitSet(maxSize) { } - + OpenBitSetDISI::~OpenBitSetDISI() { } - + void OpenBitSetDISI::inPlaceOr(DocIdSetIteratorPtr disi) { int32_t doc; @@ -29,7 +29,7 @@ namespace Lucene while ((doc = disi->nextDoc()) < _size) set(doc); } - + void OpenBitSetDISI::inPlaceAnd(DocIdSetIteratorPtr disi) { int32_t bitSetDoc = nextSetBit((int32_t)0); @@ -42,7 +42,7 @@ namespace Lucene if (bitSetDoc != -1) clear((int64_t)bitSetDoc, size()); } - + void OpenBitSetDISI::inPlaceNot(DocIdSetIteratorPtr disi) { int32_t doc; @@ -50,7 +50,7 @@ namespace Lucene while ((doc = disi->nextDoc()) < _size) clear(doc); } - + void OpenBitSetDISI::inPlaceXor(DocIdSetIteratorPtr disi) { int32_t doc; diff --git a/src/core/util/OpenBitSetIterator.cpp b/src/core/util/OpenBitSetIterator.cpp index 3d43e068..5b805f1e 100644 --- a/src/core/util/OpenBitSetIterator.cpp +++ b/src/core/util/OpenBitSetIterator.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,41 +11,41 @@ namespace Lucene { - /// The General Idea: instead of having an array per byte that has the offsets of the + /// 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 + /// That should be faster than accessing an array for each index, and the total array /// size is kept smaller (256*sizeof(int32_t))=1K const int32_t OpenBitSetIterator::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, + 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, + 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, + 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, static_cast(0x87654321) }; - + OpenBitSetIterator::OpenBitSetIterator(OpenBitSetPtr bitSet) { arr = bitSet->getBits(); @@ -56,7 +56,7 @@ namespace Lucene indexArray = 0; curDocId = -1; } - + OpenBitSetIterator::OpenBitSetIterator(LongArray bits, int32_t numWords) { arr = bits; @@ -67,11 +67,11 @@ namespace Lucene indexArray = 0; curDocId = -1; } - + OpenBitSetIterator::~OpenBitSetIterator() { } - + void OpenBitSetIterator::shift() { if ((int32_t)word == 0) @@ -91,7 +91,7 @@ namespace Lucene } indexArray = bitlist[(int32_t)word & 0xff]; } - + int32_t OpenBitSetIterator::nextDoc() { if (indexArray == 0) @@ -122,7 +122,7 @@ namespace Lucene curDocId = (i << 6) + bitIndex; return curDocId; } - + int32_t OpenBitSetIterator::advance(int32_t target) { indexArray = 0; @@ -158,7 +158,7 @@ namespace Lucene curDocId = (i << 6) + bitIndex; return curDocId; } - + int32_t OpenBitSetIterator::docID() { return curDocId; diff --git a/src/core/util/Random.cpp b/src/core/util/Random.cpp index e6dbe57c..d28bf0ab 100644 --- a/src/core/util/Random.cpp +++ b/src/core/util/Random.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,12 +14,12 @@ namespace Lucene { this->seed = (int64_t)MiscUtils::currentTimeMillis(); } - + Random::Random(int64_t seed) { this->seed = seed; } - + Random::~Random() { } @@ -28,7 +28,7 @@ namespace Lucene { this->seed = (seed ^ 0x5deece66dLL) & (((int64_t)1 << 48) - 1); } - + int32_t Random::nextInt(int32_t limit) { if ((limit & -limit) == limit) @@ -36,17 +36,17 @@ namespace Lucene int32_t bits = 0; int32_t val = 0; - + do { bits = next(31); val = bits % limit; } while (bits - val + (limit - 1) < 0); - + return val; } - + double Random::nextDouble() { return ((double)(((int64_t)next(26) << 27) + next(27)) / (double)((int64_t)1 << 53)); diff --git a/src/core/util/Reader.cpp b/src/core/util/Reader.cpp index 04f38a2d..320a7420 100644 --- a/src/core/util/Reader.cpp +++ b/src/core/util/Reader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -10,7 +10,7 @@ namespace Lucene { const int32_t Reader::READER_EOF = -1; - + Reader::Reader() { } @@ -18,33 +18,33 @@ namespace Lucene Reader::~Reader() { } - + int32_t Reader::read() { wchar_t buffer; return read(&buffer, 0, 1) == READER_EOF ? READER_EOF : buffer; } - + int64_t Reader::skip(int64_t n) { return 0; // override } - + bool Reader::markSupported() { return false; // override } - + void Reader::mark(int32_t readAheadLimit) { // override } - + void Reader::reset() { // override } - + int64_t Reader::length() { return 0; // override diff --git a/src/core/util/ReaderUtil.cpp b/src/core/util/ReaderUtil.cpp index 2e7ef96b..9b27b626 100644 --- a/src/core/util/ReaderUtil.cpp +++ b/src/core/util/ReaderUtil.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene ReaderUtil::~ReaderUtil() { } - + void ReaderUtil::gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader) { Collection subReaders(reader->getSequentialSubReaders()); @@ -28,7 +28,7 @@ namespace Lucene gatherSubReaders(allSubReaders, *subReader); } } - + IndexReaderPtr ReaderUtil::subReader(int32_t doc, IndexReaderPtr reader) { Collection subReaders(Collection::newInstance()); @@ -42,14 +42,14 @@ namespace Lucene } return subReaders[ReaderUtil::subIndex(doc, docStarts)]; } - + IndexReaderPtr ReaderUtil::subReader(IndexReaderPtr reader, int32_t subIndex) { Collection subReaders(Collection::newInstance()); ReaderUtil::gatherSubReaders(subReaders, reader); return subReaders[subIndex]; } - + int32_t ReaderUtil::subIndex(int32_t n, Collection docStarts) { // Binary search to locate reader diff --git a/src/core/util/ScorerDocQueue.cpp b/src/core/util/ScorerDocQueue.cpp index a5e347fd..7c666202 100644 --- a/src/core/util/ScorerDocQueue.cpp +++ b/src/core/util/ScorerDocQueue.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,17 +20,17 @@ namespace Lucene this->maxSize = maxSize; topHSD = heap[1]; // initially null } - + ScorerDocQueue::~ScorerDocQueue() { } - + void ScorerDocQueue::put(ScorerPtr scorer) { heap[++_size] = newLucene(scorer); upHeap(); } - + bool ScorerDocQueue::insert(ScorerPtr scorer) { if (_size < maxSize) @@ -51,32 +51,32 @@ namespace Lucene return false; } } - + ScorerPtr ScorerDocQueue::top() { return topHSD->scorer; } - + int32_t ScorerDocQueue::topDoc() { return topHSD->doc; } - + double ScorerDocQueue::topScore() { return topHSD->scorer->score(); } - + bool ScorerDocQueue::topNextAndAdjustElsePop() { return checkAdjustElsePop(topHSD->scorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); } - + bool ScorerDocQueue::topSkipToAndAdjustElsePop(int32_t target) { return checkAdjustElsePop(topHSD->scorer->advance(target) != DocIdSetIterator::NO_MORE_DOCS); } - + bool ScorerDocQueue::checkAdjustElsePop(bool cond) { if (cond) // see also adjustTop @@ -89,39 +89,39 @@ namespace Lucene downHeap(); return cond; } - + ScorerPtr ScorerDocQueue::pop() { ScorerPtr result(topHSD->scorer); popNoResult(); return result; } - + void ScorerDocQueue::popNoResult() { heap[1] = heap[_size]; // move last to first heap[_size--].reset(); downHeap(); // adjust heap } - + void ScorerDocQueue::adjustTop() { topHSD->adjust(); downHeap(); } - + int32_t ScorerDocQueue::size() { return _size; } - + void ScorerDocQueue::clear() { for (int32_t i = 0; i <= _size; ++i) heap[i].reset(); _size = 0; } - + void ScorerDocQueue::upHeap() { int32_t i = _size; @@ -136,7 +136,7 @@ namespace Lucene heap[i] = node; // install saved node topHSD = heap[1]; } - + void ScorerDocQueue::downHeap() { int32_t i = 1; @@ -157,23 +157,23 @@ namespace Lucene heap[i] = node; // install saved node topHSD = heap[1]; } - + HeapedScorerDoc::HeapedScorerDoc(ScorerPtr scorer) { this->scorer = scorer; this->doc = scorer->docID(); } - + HeapedScorerDoc::HeapedScorerDoc(ScorerPtr scorer, int32_t doc) { this->scorer = scorer; this->doc = doc; } - + HeapedScorerDoc::~HeapedScorerDoc() { } - + void HeapedScorerDoc::adjust() { doc = scorer->docID(); diff --git a/src/core/util/SmallDouble.cpp b/src/core/util/SmallDouble.cpp index 36905718..5f79d8c9 100644 --- a/src/core/util/SmallDouble.cpp +++ b/src/core/util/SmallDouble.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,7 +13,7 @@ namespace Lucene SmallDouble::~SmallDouble() { } - + uint8_t SmallDouble::doubleToByte(double f) { if (f < 0.0) // round negatives up to zero @@ -38,7 +38,7 @@ namespace Lucene return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t } - + double SmallDouble::byteToDouble(uint8_t b) { if (b == 0) // zero is a special case diff --git a/src/core/util/SortedVIntList.cpp b/src/core/util/SortedVIntList.cpp index 1f65da5c..1aabb9bf 100644 --- a/src/core/util/SortedVIntList.cpp +++ b/src/core/util/SortedVIntList.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,14 +14,14 @@ namespace Lucene { - /// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the + /// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the /// index numbers of the set bits will be smaller than that BitSet. const int32_t SortedVIntList::BITS2VINTLIST_SIZE = 8; - + const int32_t SortedVIntList::VB1 = 0x7f; const int32_t SortedVIntList::BIT_SHIFT = 7; const int32_t SortedVIntList::MAX_BYTES_PER_INT = (31 / SortedVIntList::BIT_SHIFT) + 1; - + SortedVIntList::SortedVIntList(Collection sortedInts) { lastInt = 0; @@ -30,7 +30,7 @@ namespace Lucene addInt(sortedInts[i]); bytes.resize(lastBytePos); } - + SortedVIntList::SortedVIntList(Collection sortedInts, int32_t inputSize) { lastInt = 0; @@ -39,7 +39,7 @@ namespace Lucene addInt(sortedInts[i]); bytes.resize(lastBytePos); } - + SortedVIntList::SortedVIntList(BitSetPtr bits) { lastInt = 0; @@ -52,7 +52,7 @@ namespace Lucene } bytes.resize(lastBytePos); } - + SortedVIntList::SortedVIntList(OpenBitSetPtr bits) { lastInt = 0; @@ -65,7 +65,7 @@ namespace Lucene } bytes.resize(lastBytePos); } - + SortedVIntList::SortedVIntList(DocIdSetIteratorPtr docIdSetIterator) { lastInt = 0; @@ -75,30 +75,30 @@ namespace Lucene addInt(doc); bytes.resize(lastBytePos); } - + SortedVIntList::~SortedVIntList() { } - + void SortedVIntList::initBytes() { _size = 0; bytes = ByteArray::newInstance(128); // initial byte size lastBytePos = 0; } - + void SortedVIntList::addInt(int32_t nextInt) { int32_t diff = nextInt - lastInt; if (diff < 0) boost::throw_exception(IllegalArgumentException(L"Input not sorted or first element negative.")); - + if (!bytes || (lastBytePos + MAX_BYTES_PER_INT) > bytes.size()) { // biggest possible int does not fit bytes.resize((bytes.size() * 2) + MAX_BYTES_PER_INT); } - + // See IndexOutput.writeVInt() while ((diff & ~VB1) != 0) // The high bit of the next byte needs to be set. { @@ -109,27 +109,27 @@ namespace Lucene ++_size; lastInt = nextInt; } - + int32_t SortedVIntList::size() { return _size; } - + int32_t SortedVIntList::getByteSize() { return bytes ? bytes.size() : 0; } - + bool SortedVIntList::isCacheable() { return true; } - + DocIdSetIteratorPtr SortedVIntList::iterator() { return newLucene(shared_from_this()); } - + SortedDocIdSetIterator::SortedDocIdSetIterator(SortedVIntListPtr list) { _list = list; @@ -137,15 +137,15 @@ namespace Lucene lastInt = 0; doc = -1; } - + SortedDocIdSetIterator::~SortedDocIdSetIterator() { } - + void SortedDocIdSetIterator::advance() { SortedVIntListPtr list(_list); - + // See IndexInput.readVInt() uint8_t b = list->bytes[bytePos++]; lastInt += b & list->VB1; @@ -155,12 +155,12 @@ namespace Lucene lastInt += (b & list->VB1) << s; } } - + int32_t SortedDocIdSetIterator::docID() { return doc; } - + int32_t SortedDocIdSetIterator::nextDoc() { SortedVIntListPtr list(_list); @@ -173,7 +173,7 @@ namespace Lucene } return doc; } - + int32_t SortedDocIdSetIterator::advance(int32_t target) { SortedVIntListPtr list(_list); diff --git a/src/core/util/StringReader.cpp b/src/core/util/StringReader.cpp index c25be7be..04fcef1f 100644 --- a/src/core/util/StringReader.cpp +++ b/src/core/util/StringReader.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,16 +14,16 @@ namespace Lucene this->str = str; this->position = 0; } - + StringReader::~StringReader() { } - + int32_t StringReader::read() { return position == (int32_t)str.length() ? READER_EOF : (int32_t)str[position++]; } - + int32_t StringReader::read(wchar_t* buffer, int32_t offset, int32_t length) { if (position >= (int32_t)str.length()) @@ -38,17 +38,17 @@ namespace Lucene { str.clear(); } - + bool StringReader::markSupported() { return false; } - + void StringReader::reset() { position = 0; } - + int64_t StringReader::length() { return str.length(); diff --git a/src/core/util/StringUtils.cpp b/src/core/util/StringUtils.cpp index dd931e34..c1abacb3 100644 --- a/src/core/util/StringUtils.cpp +++ b/src/core/util/StringUtils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,10 +17,10 @@ namespace Lucene { /// Maximum length of UTF encoding. const int32_t StringUtils::MAX_ENCODING_UTF8_SIZE = 4; - + /// Default character radix. const int32_t StringUtils::CHARACTER_MAX_RADIX = 36; - + int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, CharArray unicode) { if (length == 0) @@ -29,7 +29,7 @@ namespace Lucene int32_t decodeLength = utf8Decoder.decode(unicode.get(), unicode.size()); return decodeLength == Reader::READER_EOF ? 0 : decodeLength; } - + int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, UnicodeResultPtr unicodeResult) { if (length == 0) @@ -42,7 +42,7 @@ namespace Lucene } return unicodeResult->length; } - + String StringUtils::toUnicode(const uint8_t* utf8, int32_t length) { if (length == 0) @@ -51,12 +51,12 @@ namespace Lucene int32_t result = toUnicode(utf8, length, unicode); return String(unicode.get(), result); } - + String StringUtils::toUnicode(const SingleString& s) { return s.empty() ? L"" : toUnicode((uint8_t*)s.c_str(), s.length()); } - + int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, ByteArray utf8) { if (length == 0) @@ -65,7 +65,7 @@ namespace Lucene int32_t encodeLength = utf8Encoder.encode(utf8.get(), utf8.size()); return encodeLength == Reader::READER_EOF ? 0 : encodeLength; } - + int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, UTF8ResultPtr utf8Result) { if (length == 0) @@ -78,7 +78,7 @@ namespace Lucene } return utf8Result->length; } - + SingleString StringUtils::toUTF8(const wchar_t* unicode, int32_t length) { if (length == 0) @@ -87,48 +87,48 @@ namespace Lucene int32_t result = toUTF8(unicode, length, utf8); return SingleString((char*)utf8.get(), result); } - + SingleString StringUtils::toUTF8(const String& s) { return s.empty() ? "" : toUTF8(s.c_str(), s.size()); } - + void StringUtils::toLower(String& str) { CharFolder::toLower(str.begin(), str.end()); } - + String StringUtils::toLower(const String& str) { String lowerStr(str); toLower(lowerStr); return lowerStr; } - + void StringUtils::toUpper(String& str) { CharFolder::toUpper(str.begin(), str.end()); } - + String StringUtils::toUpper(const String& str) { String upperStr(str); toUpper(upperStr); return upperStr; } - + int32_t StringUtils::compareCase(const String& first, const String& second) { return (toLower(first) == toLower(second)); } - + Collection StringUtils::split(const String& str, const String& delim) { std::vector tokens; boost::split(tokens, str, boost::is_any_of(delim.c_str())); return Collection::newInstance(tokens.begin(), tokens.end()); } - + int32_t StringUtils::toInt(const String& value) { if (value.empty()) @@ -139,7 +139,7 @@ namespace Lucene boost::throw_exception(NumberFormatException()); return (int32_t)std::wcstol(value.c_str(), NULL, 10); } - + int64_t StringUtils::toLong(const String& value) { if (value.empty()) @@ -154,7 +154,7 @@ namespace Lucene return wcstoll(value.c_str(), 0, 10); #endif } - + int64_t StringUtils::toLong(const String& value, int32_t base) { int64_t longValue = 0; @@ -162,7 +162,7 @@ namespace Lucene longValue = UnicodeUtil::isDigit(*ptr) ? (base * longValue) + (*ptr - L'0') : (base * longValue) + (*ptr - L'a' + 10); return longValue; } - + double StringUtils::toDouble(const String& value) { if (value.empty()) @@ -173,7 +173,7 @@ namespace Lucene boost::throw_exception(NumberFormatException()); return std::wcstod(value.c_str(), NULL); } - + int32_t StringUtils::hashCode(const String& value) { int32_t hashCode = 0; @@ -181,24 +181,24 @@ namespace Lucene hashCode = hashCode * 31 + *ptr; return hashCode; } - + String StringUtils::toString(int64_t value, int32_t base) { static const wchar_t* digits = L"0123456789abcdefghijklmnopqrstuvwxyz"; - + int32_t bufferSize = (sizeof(int32_t) << 3) + 1; CharArray baseOutput(CharArray::newInstance(bufferSize)); - + wchar_t* ptr = baseOutput.get() + bufferSize - 1; *ptr = L'\0'; - + do { *--ptr = digits[value % base]; value /= base; } while (ptr > baseOutput.get() && value > 0); - + return String(ptr, (baseOutput.get() + bufferSize - 1) - ptr); } } diff --git a/src/core/util/Synchronize.cpp b/src/core/util/Synchronize.cpp index 5b72e419..38d33f55 100644 --- a/src/core/util/Synchronize.cpp +++ b/src/core/util/Synchronize.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene lockThread = 0; recursionCount = 0; } - + Synchronize::~Synchronize() { } - + void Synchronize::createSync(SynchronizePtr& sync) { static boost::mutex lockMutex; @@ -28,7 +28,7 @@ namespace Lucene if (!sync) sync = newInstance(); } - + void Synchronize::lock(int32_t timeout) { if (timeout > 0) @@ -38,14 +38,14 @@ namespace Lucene lockThread = LuceneThread::currentId(); ++recursionCount; } - + void Synchronize::unlock() { if (--recursionCount == 0) lockThread = 0; - mutexSynchronize.unlock(); + mutexSynchronize.unlock(); } - + int32_t Synchronize::unlockAll() { int32_t count = recursionCount; @@ -53,12 +53,12 @@ namespace Lucene this->unlock(); return count; } - + bool Synchronize::holdsLock() { return (lockThread == LuceneThread::currentId() && recursionCount > 0); } - + SyncLock::SyncLock(SynchronizePtr sync, int32_t timeout) { this->sync = sync; @@ -70,7 +70,7 @@ namespace Lucene if (sync) sync->unlock(); } - + void SyncLock::lock(int32_t timeout) { if (sync) diff --git a/src/core/util/TestPoint.cpp b/src/core/util/TestPoint.cpp index 4e57e74b..c0850b0e 100644 --- a/src/core/util/TestPoint.cpp +++ b/src/core/util/TestPoint.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -11,22 +11,22 @@ namespace Lucene { MapStringInt TestPoint::testMethods = MapStringInt::newInstance(); bool TestPoint::enable = false; - + TestPoint::~TestPoint() { } - + void TestPoint::enableTestPoints() { enable = true; } - + void TestPoint::clear() { SyncLock syncLock(&testMethods); testMethods.clear(); } - + void TestPoint::setTestPoint(const String& object, const String& method, bool point) { if (enable) @@ -36,28 +36,28 @@ namespace Lucene testMethods.put(method, point); } } - + bool TestPoint::getTestPoint(const String& object, const String& method) { SyncLock syncLock(&testMethods); MapStringInt::iterator testMethod = testMethods.find(object + L":" + method); return testMethod == testMethods.end() ? false : (testMethod->second != 0); } - + bool TestPoint::getTestPoint(const String& method) { SyncLock syncLock(&testMethods); MapStringInt::iterator testMethod = testMethods.find(method); return testMethod == testMethods.end() ? false : (testMethod->second != 0); } - + TestScope::TestScope(const String& object, const String& method) { this->object = object; this->method = method; TestPoint::setTestPoint(object, method, true); } - + TestScope::~TestScope() { TestPoint::setTestPoint(object, method, false); diff --git a/src/core/util/ThreadPool.cpp b/src/core/util/ThreadPool.cpp index fb57326b..564620c2 100644 --- a/src/core/util/ThreadPool.cpp +++ b/src/core/util/ThreadPool.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -12,22 +12,22 @@ namespace Lucene Future::~Future() { } - + const int32_t ThreadPool::THREADPOOL_SIZE = 5; - + ThreadPool::ThreadPool() { work.reset(new boost::asio::io_service::work(io_service)); for (int32_t i = 0; i < THREADPOOL_SIZE; ++i) threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &io_service)); } - + ThreadPool::~ThreadPool() { work.reset(); // stop all threads threadGroup.join_all(); // wait for all competition } - + ThreadPoolPtr ThreadPool::getInstance() { static ThreadPoolPtr threadPool; diff --git a/src/core/util/UTF8Stream.cpp b/src/core/util/UTF8Stream.cpp index 35e3ec5c..82983fed 100644 --- a/src/core/util/UTF8Stream.cpp +++ b/src/core/util/UTF8Stream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/util/UnicodeUtils.cpp b/src/core/util/UnicodeUtils.cpp index c6572db2..d66b8f83 100644 --- a/src/core/util/UnicodeUtils.cpp +++ b/src/core/util/UnicodeUtils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,61 +14,61 @@ namespace Lucene UnicodeUtil::~UnicodeUtil() { } - + bool UnicodeUtil::isAlnum(wchar_t c) { return g_unichar_isalnum(c); } - + bool UnicodeUtil::isAlpha(wchar_t c) { return g_unichar_isalpha(c); } - + bool UnicodeUtil::isDigit(wchar_t c) { return g_unichar_isdigit(c); } - + bool UnicodeUtil::isSpace(wchar_t c) { return g_unichar_isspace(c); } - + bool UnicodeUtil::isUpper(wchar_t c) { return g_unichar_isupper(c); } - + bool UnicodeUtil::isLower(wchar_t c) { return g_unichar_islower(c); } - + bool UnicodeUtil::isOther(wchar_t c) { return (g_unichar_type(c) == G_UNICODE_OTHER_LETTER); } - + bool UnicodeUtil::isNonSpacing(wchar_t c) { return (g_unichar_type(c) == G_UNICODE_NON_SPACING_MARK); } - + wchar_t UnicodeUtil::toUpper(wchar_t c) { return (wchar_t)g_unichar_toupper(c); } - + wchar_t UnicodeUtil::toLower(wchar_t c) { return (wchar_t)g_unichar_tolower(c); } - + UTF8Result::~UTF8Result() { } - + UnicodeResult::~UnicodeResult() { } diff --git a/src/core/util/unicode/guniprop.cpp b/src/core/util/unicode/guniprop.cpp index bde7ea4f..fa6287b7 100644 --- a/src/core/util/unicode/guniprop.cpp +++ b/src/core/util/unicode/guniprop.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,7 +24,7 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ - + #include "LuceneInc.h" #include "guniprop.h" @@ -135,17 +135,17 @@ (Result) <<= 6; \ (Result) |= ((Chars)[(Count)] & 0x3f); \ } - + /** * g_utf8_get_char: * @p: a pointer to Unicode character encoded as UTF-8 - * + * * Converts a sequence of bytes encoded as UTF-8 to a Unicode character. * If @p does not point to a valid UTF-8 encoded character, results are * undefined. If you are not sure that the bytes are complete * valid Unicode characters, you should use g_utf8_get_char_validated() * instead. - * + * * Return value: the resulting character **/ gunichar @@ -166,11 +166,11 @@ g_utf8_get_char (const gchar *p) /** * g_unichar_isalnum: * @c: a Unicode character - * + * * Determines whether a character is alphanumeric. * Given some UTF-8 text, obtain a character value * with g_utf8_get_char(). - * + * * Return value: %TRUE if @c is an alphanumeric character **/ gboolean @@ -182,11 +182,11 @@ g_unichar_isalnum (gunichar c) /** * g_unichar_isalpha: * @c: a Unicode character - * + * * Determines whether a character is alphabetic (i.e. a letter). * Given some UTF-8 text, obtain a character value with * g_utf8_get_char(). - * + * * Return value: %TRUE if @c is an alphabetic character **/ gboolean @@ -199,11 +199,11 @@ g_unichar_isalpha (gunichar c) /** * g_unichar_iscntrl: * @c: a Unicode character - * + * * Determines whether a character is a control character. * Given some UTF-8 text, obtain a character value with * g_utf8_get_char(). - * + * * Return value: %TRUE if @c is a control character **/ gboolean @@ -215,11 +215,11 @@ g_unichar_iscntrl (gunichar c) /** * g_unichar_isdigit: * @c: a Unicode character - * + * * Determines whether a character is numeric (i.e. a digit). This * covers ASCII 0-9 and also digits in other languages/scripts. Given * some UTF-8 text, obtain a character value with g_utf8_get_char(). - * + * * Return value: %TRUE if @c is a digit **/ gboolean @@ -232,13 +232,13 @@ g_unichar_isdigit (gunichar c) /** * g_unichar_isgraph: * @c: a Unicode character - * + * * Determines whether a character is printable and not a space * (returns %FALSE for control characters, format characters, and * spaces). g_unichar_isprint() is similar, but returns %TRUE for * spaces. Given some UTF-8 text, obtain a character value with * g_utf8_get_char(). - * + * * Return value: %TRUE if @c is printable unless it's a space **/ gboolean @@ -256,11 +256,11 @@ g_unichar_isgraph (gunichar c) /** * g_unichar_islower: * @c: a Unicode character - * + * * Determines whether a character is a lowercase letter. * Given some UTF-8 text, obtain a character value with * g_utf8_get_char(). - * + * * Return value: %TRUE if @c is a lowercase letter **/ gboolean @@ -273,12 +273,12 @@ g_unichar_islower (gunichar c) /** * g_unichar_isprint: * @c: a Unicode character - * + * * Determines whether a character is printable. * Unlike g_unichar_isgraph(), returns %TRUE for spaces. * Given some UTF-8 text, obtain a character value with * g_utf8_get_char(). - * + * * Return value: %TRUE if @c is printable **/ gboolean @@ -295,11 +295,11 @@ g_unichar_isprint (gunichar c) /** * g_unichar_ispunct: * @c: a Unicode character - * + * * Determines whether a character is punctuation or a symbol. * Given some UTF-8 text, obtain a character value with * g_utf8_get_char(). - * + * * Return value: %TRUE if @c is a punctuation or symbol character **/ gboolean @@ -323,7 +323,7 @@ g_unichar_ispunct (gunichar c) /** * g_unichar_isspace: * @c: a Unicode character - * + * * Determines whether a character is a space, tab, or line separator * (newline, carriage return, etc.). Given some UTF-8 text, obtain a * character value with g_utf8_get_char(). @@ -331,7 +331,7 @@ g_unichar_ispunct (gunichar c) * (Note: don't use this to do word breaking; you have to use * Pango or equivalent to get word breaking right, the algorithm * is fairly complex.) - * + * * Return value: %TRUE if @c is a space character **/ gboolean @@ -346,7 +346,7 @@ g_unichar_isspace (gunichar c) case '\f': return true; break; - + default: { return IS (TYPE(c), @@ -386,9 +386,9 @@ g_unichar_ismark (gunichar c) /** * g_unichar_isupper: * @c: a Unicode character - * + * * Determines if a character is uppercase. - * + * * Return value: %TRUE if @c is an uppercase character **/ gboolean @@ -400,14 +400,14 @@ g_unichar_isupper (gunichar c) /** * g_unichar_istitle: * @c: a Unicode character - * + * * Determines if a character is titlecase. Some characters in * Unicode which are composites, such as the DZ digraph * have three case variants instead of just two. The titlecase * form is used at the beginning of a word where only the * first letter is capitalized. The titlecase form of the DZ * digraph is U+01F2 LATIN CAPITAL LETTTER D WITH SMALL LETTER Z. - * + * * Return value: %TRUE if the character is titlecase **/ gboolean @@ -423,9 +423,9 @@ g_unichar_istitle (gunichar c) /** * g_unichar_isxdigit: * @c: a Unicode character. - * + * * Determines if a character is a hexidecimal digit. - * + * * Return value: %TRUE if the character is a hexadecimal digit **/ gboolean @@ -439,7 +439,7 @@ g_unichar_isxdigit (gunichar c) /** * g_unichar_isdefined: * @c: a Unicode character - * + * * Determines if a given character is assigned in the Unicode * standard. * @@ -457,9 +457,9 @@ g_unichar_isdefined (gunichar c) /** * g_unichar_toupper: * @c: a Unicode character - * + * * Converts a character to uppercase. - * + * * Return value: the result of converting @c to uppercase. * If @c is not an lowercase or titlecase character, * or has no upper case equivalent @c is returned unchanged. @@ -478,7 +478,7 @@ g_unichar_toupper (gunichar c) } /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR, * do not have an uppercase equivalent, in which case val will be - * zero. + * zero. */ return val ? val : c; } @@ -497,9 +497,9 @@ g_unichar_toupper (gunichar c) /** * g_unichar_tolower: * @c: a Unicode character. - * + * * Converts a character to lower case. - * + * * Return value: the result of converting @c to lower case. * If @c is not an upperlower or titlecase character, * or has no lowercase equivalent @c is returned unchanged. @@ -538,9 +538,9 @@ g_unichar_tolower (gunichar c) /** * g_unichar_totitle: * @c: a Unicode character - * + * * Converts a character to the titlecase. - * + * * Return value: the result of converting @c to titlecase. * If @c is not an uppercase or lowercase character, * @c is returned unchanged. @@ -555,7 +555,7 @@ g_unichar_totitle (gunichar c) || title_table[i][2] == c) return title_table[i][0]; } - + if (TYPE (c) == G_UNICODE_LOWERCASE_LETTER) return g_unichar_toupper (c); @@ -605,9 +605,9 @@ g_unichar_xdigit_value (gunichar c) /** * g_unichar_type: * @c: a Unicode character - * + * * Classifies a Unicode character by type. - * + * * Return value: the type of the character. **/ GUnicodeType diff --git a/src/core/util/unicode/guniprop.h b/src/core/util/unicode/guniprop.h index a68d8863..51b5559e 100644 --- a/src/core/util/unicode/guniprop.h +++ b/src/core/util/unicode/guniprop.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -24,7 +24,7 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ - + #include "Lucene.h" typedef uint32_t gunichar; @@ -119,7 +119,7 @@ typedef enum G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE } GUnicodeBreakType; -typedef enum +typedef enum { /* ISO 15924 code */ G_UNICODE_SCRIPT_INVALID_CODE = -1, G_UNICODE_SCRIPT_COMMON = 0, /* Zyyy */ @@ -178,7 +178,7 @@ typedef enum G_UNICODE_SCRIPT_LINEAR_B, /* Linb */ G_UNICODE_SCRIPT_TAI_LE, /* Tale */ G_UNICODE_SCRIPT_UGARITIC, /* Ugar */ - + /* Unicode-4.1 additions */ G_UNICODE_SCRIPT_NEW_TAI_LUE, /* Talu */ G_UNICODE_SCRIPT_BUGINESE, /* Bugi */ diff --git a/src/demo/deletefiles/main.cpp b/src/demo/deletefiles/main.cpp index ddb8083a..ec91791c 100644 --- a/src/demo/deletefiles/main.cpp +++ b/src/demo/deletefiles/main.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/demo/indexfiles/main.cpp b/src/demo/indexfiles/main.cpp index d60da216..3f0b4d37 100644 --- a/src/demo/indexfiles/main.cpp +++ b/src/demo/indexfiles/main.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,20 +20,20 @@ DocumentPtr fileDocument(const String& docFile) { DocumentPtr doc = newLucene(); - // Add the path of the file as a field named "path". Use a field that is indexed (ie. searchable), but + // Add the path of the file as a field named "path". Use a field that is indexed (ie. searchable), but // don't tokenize the field into words. doc->add(newLucene(L"path", docFile, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - - // Add the last modified date of the file a field named "modified". Use a field that is indexed (ie. searchable), + + // Add the last modified date of the file a field named "modified". Use a field that is indexed (ie. searchable), // but don't tokenize the field into words. doc->add(newLucene(L"modified", DateTools::timeToString(FileUtils::fileModified(docFile), DateTools::RESOLUTION_MINUTE), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - // Add the contents of the file to a field named "contents". Specify a Reader, so that the text of the file is - // tokenized and indexed, but not stored. Note that FileReader expects the file to be in the system's default + // Add the contents of the file to a field named "contents". Specify a Reader, so that the text of the file is + // tokenized and indexed, but not stored. Note that FileReader expects the file to be in the system's default // encoding. If that's not the case searching for special characters will fail. doc->add(newLucene(L"contents", newLucene(docFile))); - + return doc; } diff --git a/src/demo/searchfiles/main.cpp b/src/demo/searchfiles/main.cpp index 4b7a1ed3..9254ec12 100644 --- a/src/demo/searchfiles/main.cpp +++ b/src/demo/searchfiles/main.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,8 +15,8 @@ using namespace Lucene; -/// Use the norms from one field for all fields. Norms are read into memory, using a byte of memory -/// per document per searched field. This can cause search of large collections with a large number +/// Use the norms from one field for all fields. Norms are read into memory, using a byte of memory +/// per document per searched field. This can cause search of large collections with a large number /// of fields to run out of memory. If all of the fields contain only a single token, then the norms /// are all identical, then single norm vector may be shared. class OneNormsReader : public FilterIndexReader @@ -41,11 +41,11 @@ class OneNormsReader : public FilterIndexReader } }; -/// This demonstrates a typical paging search scenario, where the search engine presents pages of size n +/// This demonstrates a typical paging search scenario, where the search engine presents pages of size n /// to the user. The user can then go to the next page if interested in the next hits. /// -/// When the query is executed for the first time, then only enough results are collected to fill 5 result -/// pages. If the user wants to page beyond this limit, then the query is executed another time and all +/// When the query is executed for the first time, then only enough results are collected to fill 5 result +/// pages. If the user wants to page beyond this limit, then the query is executed another time and all /// hits are collected. static void doPagingSearch(SearcherPtr searcher, QueryPtr query, int32_t hitsPerPage, bool raw, bool interactive) { @@ -201,10 +201,10 @@ class StreamingHitCollector : public Collector } }; -/// This method uses a custom HitCollector implementation which simply prints out the docId and score of -/// every matching document. +/// This method uses a custom HitCollector implementation which simply prints out the docId and score of +/// every matching document. /// -/// This simulates the streaming search use case, where all hits are supposed to be processed, regardless +/// This simulates the streaming search use case, where all hits are supposed to be processed, regardless /// of their relevance. static void doStreamingSearch(SearcherPtr searcher, QueryPtr query) { diff --git a/src/test/analysis/AnalyzersTest.cpp b/src/test/analysis/AnalyzersTest.cpp index 5513a8e6..705a6611 100644 --- a/src/test/analysis/AnalyzersTest.cpp +++ b/src/test/analysis/AnalyzersTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/BaseTokenStreamFixture.cpp b/src/test/analysis/BaseTokenStreamFixture.cpp index 9fdd2845..fae26b18 100644 --- a/src/test/analysis/BaseTokenStreamFixture.cpp +++ b/src/test/analysis/BaseTokenStreamFixture.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/CachingTokenFilterTest.cpp b/src/test/analysis/CachingTokenFilterTest.cpp index 8447df44..ae295f70 100644 --- a/src/test/analysis/CachingTokenFilterTest.cpp +++ b/src/test/analysis/CachingTokenFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/CharFilterTest.cpp b/src/test/analysis/CharFilterTest.cpp index e55da7a0..c3820152 100644 --- a/src/test/analysis/CharFilterTest.cpp +++ b/src/test/analysis/CharFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/KeywordAnalyzerTest.cpp b/src/test/analysis/KeywordAnalyzerTest.cpp index 0f8044f3..89c7761d 100644 --- a/src/test/analysis/KeywordAnalyzerTest.cpp +++ b/src/test/analysis/KeywordAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/LengthFilterTest.cpp b/src/test/analysis/LengthFilterTest.cpp index 0266953a..8928fc6d 100644 --- a/src/test/analysis/LengthFilterTest.cpp +++ b/src/test/analysis/LengthFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/MappingCharFilterTest.cpp b/src/test/analysis/MappingCharFilterTest.cpp index e9b04ea7..502e4c27 100644 --- a/src/test/analysis/MappingCharFilterTest.cpp +++ b/src/test/analysis/MappingCharFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/NumericTokenStreamTest.cpp b/src/test/analysis/NumericTokenStreamTest.cpp index 6533c238..09d902cb 100644 --- a/src/test/analysis/NumericTokenStreamTest.cpp +++ b/src/test/analysis/NumericTokenStreamTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp b/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp index 48b2fa79..31f21e53 100644 --- a/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp +++ b/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/StopAnalyzerTest.cpp b/src/test/analysis/StopAnalyzerTest.cpp index b0ffb662..13daa9cf 100644 --- a/src/test/analysis/StopAnalyzerTest.cpp +++ b/src/test/analysis/StopAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/StopFilterTest.cpp b/src/test/analysis/StopFilterTest.cpp index ef12b09e..8167a5b6 100644 --- a/src/test/analysis/StopFilterTest.cpp +++ b/src/test/analysis/StopFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/TeeSinkTokenFilterTest.cpp b/src/test/analysis/TeeSinkTokenFilterTest.cpp index 1455158d..8f33d6c0 100644 --- a/src/test/analysis/TeeSinkTokenFilterTest.cpp +++ b/src/test/analysis/TeeSinkTokenFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/TokenTest.cpp b/src/test/analysis/TokenTest.cpp index 58172403..baea4410 100644 --- a/src/test/analysis/TokenTest.cpp +++ b/src/test/analysis/TokenTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/standard/StandardAnalyzerTest.cpp b/src/test/analysis/standard/StandardAnalyzerTest.cpp index ea1c7056..01175ef3 100644 --- a/src/test/analysis/standard/StandardAnalyzerTest.cpp +++ b/src/test/analysis/standard/StandardAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp index 054fc34b..c7732916 100644 --- a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/analysis/tokenattributes/TermAttributeTest.cpp b/src/test/analysis/tokenattributes/TermAttributeTest.cpp index 367a7693..674c1392 100644 --- a/src/test/analysis/tokenattributes/TermAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/TermAttributeTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp index b1b56277..cd0b4b9e 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp index 6ed837e0..85b649c1 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp index 8236af93..00cb0534 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp index 1f576773..af034255 100644 --- a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp index cd857fd3..57030136 100644 --- a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp index 6c8ea1ad..eb9dc991 100644 --- a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp index b20abbe5..b8967727 100644 --- a/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp index 25630270..be9c4245 100644 --- a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp index 2df38994..7354b87d 100644 --- a/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp index 97762529..61bd7ca4 100644 --- a/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp index 1e1ddca7..6d99f33c 100644 --- a/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp index b4b5129b..4ba8a413 100644 --- a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp index 0f6bc81a..011ef483 100644 --- a/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp index af399da1..19510245 100644 --- a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp index a160b80a..9f1e507c 100644 --- a/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp index 2f5a4b14..ab641269 100644 --- a/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp b/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp index 602f5b57..d03cd33a 100644 --- a/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/highlighter/HighlighterTest.cpp b/src/test/contrib/highlighter/HighlighterTest.cpp index 41ef09dd..d2f447d7 100644 --- a/src/test/contrib/highlighter/HighlighterTest.cpp +++ b/src/test/contrib/highlighter/HighlighterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/memory/MemoryIndexTest.cpp b/src/test/contrib/memory/MemoryIndexTest.cpp index a4745178..034c0ee8 100644 --- a/src/test/contrib/memory/MemoryIndexTest.cpp +++ b/src/test/contrib/memory/MemoryIndexTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/contrib/snowball/SnowballTest.cpp b/src/test/contrib/snowball/SnowballTest.cpp index 37cc7e3c..0d5cd263 100644 --- a/src/test/contrib/snowball/SnowballTest.cpp +++ b/src/test/contrib/snowball/SnowballTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/document/BinaryDocumentTest.cpp b/src/test/document/BinaryDocumentTest.cpp index b815cffb..66648dde 100644 --- a/src/test/document/BinaryDocumentTest.cpp +++ b/src/test/document/BinaryDocumentTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/document/DateFieldTest.cpp b/src/test/document/DateFieldTest.cpp index 023ba39e..663d289d 100644 --- a/src/test/document/DateFieldTest.cpp +++ b/src/test/document/DateFieldTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/document/DateToolsTest.cpp b/src/test/document/DateToolsTest.cpp index 8e1e171e..cb6ccdab 100644 --- a/src/test/document/DateToolsTest.cpp +++ b/src/test/document/DateToolsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/document/DocumentTest.cpp b/src/test/document/DocumentTest.cpp index 63b2a4f7..5ece9fda 100644 --- a/src/test/document/DocumentTest.cpp +++ b/src/test/document/DocumentTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/document/NumberToolsTest.cpp b/src/test/document/NumberToolsTest.cpp index 115aa051..901d0f38 100644 --- a/src/test/document/NumberToolsTest.cpp +++ b/src/test/document/NumberToolsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/include/BaseTestRangeFilterFixture.h b/src/test/include/BaseTestRangeFilterFixture.h index 0cf0441b..0e2ae1fb 100644 --- a/src/test/include/BaseTestRangeFilterFixture.h +++ b/src/test/include/BaseTestRangeFilterFixture.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,41 +13,41 @@ namespace Lucene { DECLARE_SHARED_PTR(TestIndex) - + /// Collation interacts badly with hyphens -- collation produces different ordering than Unicode code-point ordering, /// so two indexes are created: - /// one which can't have negative random integers, for testing collated ranges, and the other which can have negative - /// random integers, for all other tests. + /// one which can't have negative random integers, for testing collated ranges, and the other which can have negative + /// random integers, for all other tests. class TestIndex : public LuceneObject { public: TestIndex(int32_t minR, int32_t maxR, bool allowNegativeRandomInts); virtual ~TestIndex(); - + LUCENE_CLASS(TestIndex); - + public: int32_t maxR; int32_t minR; bool allowNegativeRandomInts; RAMDirectoryPtr index; }; - + class BaseTestRangeFilterFixture : public LuceneTestFixture { public: BaseTestRangeFilterFixture(); virtual ~BaseTestRangeFilterFixture(); - + public: TestIndexPtr signedIndex; TestIndexPtr unsignedIndex; - + int32_t minId; int32_t maxId; int32_t intLength; RandomPtr random; - + protected: void build(TestIndexPtr index); String pad(int32_t n); diff --git a/src/test/include/BaseTokenStreamFixture.h b/src/test/include/BaseTokenStreamFixture.h index da5257f7..3d4e6fc4 100644 --- a/src/test/include/BaseTokenStreamFixture.h +++ b/src/test/include/BaseTokenStreamFixture.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,36 +13,36 @@ namespace Lucene { DECLARE_SHARED_PTR(CheckClearAttributesAttribute) - + class CheckClearAttributesAttribute : public Attribute { public: CheckClearAttributesAttribute(); virtual ~CheckClearAttributesAttribute(); - + LUCENE_CLASS(CheckClearAttributesAttribute); - + protected: bool clearCalled; - + public: bool getAndResetClearCalled(); - + virtual void clear(); virtual bool equals(LuceneObjectPtr other); virtual int32_t hashCode(); virtual void copyTo(AttributePtr target); virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); }; - + class BaseTokenStreamFixture : public LuceneTestFixture { public: virtual ~BaseTokenStreamFixture(); - + public: // some helpers to test Analyzers and TokenStreams - + static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements, int32_t finalOffset = -1); static void checkTokenStreamContents(TokenStreamPtr ts, Collection output); @@ -52,7 +52,7 @@ namespace Lucene static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset); static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset); - + static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements); static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output); @@ -60,7 +60,7 @@ namespace Lucene static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements); static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - + static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements); static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output); @@ -68,7 +68,7 @@ namespace Lucene static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements); static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - + static void checkOneTerm(AnalyzerPtr analyzer, const String& input, const String& expected); static void checkOneTermReuse(AnalyzerPtr analyzer, const String& input, const String& expected); }; diff --git a/src/test/include/CheckHits.h b/src/test/include/CheckHits.h index cc5f89e9..8217a764 100644 --- a/src/test/include/CheckHits.h +++ b/src/test/include/CheckHits.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,41 +15,41 @@ namespace Lucene { public: virtual ~CheckHits(); - + public: - /// Some explains methods calculate their values though a slightly different order of operations + /// Some explains methods calculate their values though a slightly different order of operations /// from the actual scoring method - this allows for a small amount of variation static const double EXPLAIN_SCORE_TOLERANCE_DELTA; - - /// Tests that all documents up to maxDoc which are *not* in the expected result set, have an + + /// Tests that all documents up to maxDoc which are *not* in the expected result set, have an /// explanation which indicates no match (ie: Explanation value of 0.0) static void checkNoMatchExplanations(QueryPtr q, const String& defaultFieldName, SearcherPtr searcher, Collection results); - + /// Tests that a query matches the an expected set of documents using a HitCollector. /// - /// Note that when using the HitCollector API, documents will be collected if they "match" + /// Note that when using the HitCollector API, documents will be collected if they "match" /// regardless of what their score is. static void checkHitCollector(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results); - + /// Tests that a query matches the an expected set of documents using Hits. /// - /// Note that when using the Hits API, documents will only be returned if they have a + /// Note that when using the Hits API, documents will only be returned if they have a /// positive normalized score. static void checkHits(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results); - + /// Tests that a Hits has an expected order of documents static void checkDocIds(Collection results, Collection hits); - - /// Tests that two queries have an expected order of documents, and that the two queries have + + /// Tests that two queries have an expected order of documents, and that the two queries have /// the same score values. static void checkHitsQuery(QueryPtr query, Collection hits1, Collection hits2, Collection results); static void checkEqual(QueryPtr query, Collection hits1, Collection hits2); - - /// Asserts that the explanation value for every document matching a query corresponds with the true score. + + /// Asserts that the explanation value for every document matching a query corresponds with the true score. /// Optionally does "deep" testing of the explanation details. static void checkExplanations(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, bool deep = false); - - /// Assert that an explanation has the expected score, and optionally that its sub-details max/sum/factor + + /// Assert that an explanation has the expected score, and optionally that its sub-details max/sum/factor /// match to that score. static void verifyExplanation(const String& q, int32_t doc, double score, bool deep, ExplanationPtr expl); }; diff --git a/src/test/include/DocHelper.h b/src/test/include/DocHelper.h index 38ec73cb..90c2c8e0 100644 --- a/src/test/include/DocHelper.h +++ b/src/test/include/DocHelper.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,70 +16,70 @@ namespace Lucene public: DocHelper(); virtual ~DocHelper(); - + public: static const wchar_t* FIELD_1_TEXT; static const wchar_t* TEXT_FIELD_1_KEY; static FieldPtr textField1; - + static const wchar_t* FIELD_2_TEXT; static const int32_t FIELD_2_FREQS[]; static const wchar_t* TEXT_FIELD_2_KEY; static FieldPtr textField2; - + static const wchar_t* FIELD_3_TEXT; static const wchar_t* TEXT_FIELD_3_KEY; static FieldPtr textField3; - + static const wchar_t* KEYWORD_TEXT; static const wchar_t* KEYWORD_FIELD_KEY; static FieldPtr keyField; - + static const wchar_t* NO_NORMS_TEXT; static const wchar_t* NO_NORMS_KEY; static FieldPtr noNormsField; - + static const wchar_t* NO_TF_TEXT; static const wchar_t* NO_TF_KEY; static FieldPtr noTFField; - + static const wchar_t* UNINDEXED_FIELD_TEXT; static const wchar_t* UNINDEXED_FIELD_KEY; static FieldPtr unIndField; - + static const wchar_t* UNSTORED_1_FIELD_TEXT; static const wchar_t* UNSTORED_FIELD_1_KEY; static FieldPtr unStoredField1; - + static const wchar_t* UNSTORED_2_FIELD_TEXT; static const wchar_t* UNSTORED_FIELD_2_KEY; static FieldPtr unStoredField2; - + static const wchar_t* LAZY_FIELD_BINARY_KEY; static ByteArray LAZY_FIELD_BINARY_BYTES; static FieldPtr lazyFieldBinary; - + static const wchar_t* LAZY_FIELD_KEY; static const wchar_t* LAZY_FIELD_TEXT; static FieldPtr lazyField; - + static const wchar_t* LARGE_LAZY_FIELD_KEY; static String LARGE_LAZY_FIELD_TEXT; static FieldPtr largeLazyField; - + static const uint8_t _FIELD_UTF1_TEXT[]; static const String FIELD_UTF1_TEXT; static const wchar_t* TEXT_FIELD_UTF1_KEY; static FieldPtr textUtfField1; - + static const uint8_t _FIELD_UTF2_TEXT[]; static const String FIELD_UTF2_TEXT; static const int32_t FIELD_UTF2_FREQS[]; static const wchar_t* TEXT_FIELD_UTF2_KEY; static FieldPtr textUtfField2; - + static MapStringString nameValues; - + static Collection fields; static MapStringField all; static MapStringField indexed; @@ -91,19 +91,19 @@ namespace Lucene static MapStringField lazy; static MapStringField noNorms; static MapStringField noTf; - + public: /// Adds the fields above to a document void setupDoc(DocumentPtr doc); - + /// Writes the document to the directory using a segment named "test"; returns the SegmentInfo describing the new segment SegmentInfoPtr writeDoc(DirectoryPtr dir, DocumentPtr doc); - + /// Writes the document to the directory using the analyzer and the similarity score; returns the SegmentInfo describing the new segment SegmentInfoPtr writeDoc(DirectoryPtr dir, AnalyzerPtr analyzer, SimilarityPtr similarity, DocumentPtr doc); - + int32_t numFields(DocumentPtr doc); - + protected: /// One-time setup to initialise static members void setup(); diff --git a/src/test/include/ExplanationsFixture.h b/src/test/include/ExplanationsFixture.h index 6caefeb8..9c4d684d 100644 --- a/src/test/include/ExplanationsFixture.h +++ b/src/test/include/ExplanationsFixture.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,16 +16,16 @@ namespace Lucene public: ExplanationsFixture(); virtual ~ExplanationsFixture(); - + public: static const String KEY; static const String FIELD; - + protected: IndexSearcherPtr searcher; QueryParserPtr qp; Collection docFields; - + public: virtual SpanTermQueryPtr st(const String& s); virtual SpanFirstQueryPtr sf(const String& s, int32_t b); @@ -43,15 +43,15 @@ namespace Lucene virtual QueryPtr reqB(const String& q); virtual QueryPtr reqB(QueryPtr q); virtual Collection ta(Collection s); - + /// Check the expDocNrs first, then check the query (and the explanations) virtual void qtest(const String& queryText, Collection expDocNrs); virtual void qtest(QueryPtr q, Collection expDocNrs); - + /// Tests a query using qtest after wrapping it with both optB and reqB virtual void bqtest(QueryPtr q, Collection expDocNrs); virtual void bqtest(const String& queryText, Collection expDocNrs); - + virtual QueryPtr makeQuery(const String& queryText); }; } diff --git a/src/test/include/FunctionFixture.h b/src/test/include/FunctionFixture.h index 5e218a15..74f222c6 100644 --- a/src/test/include/FunctionFixture.h +++ b/src/test/include/FunctionFixture.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,31 +16,31 @@ namespace Lucene public: FunctionFixture(bool doMultiSegment); virtual ~FunctionFixture(); - + public: static const double TEST_SCORE_TOLERANCE_DELTA; - + public: static const int32_t N_DOCS; - + static const String ID_FIELD; static const String TEXT_FIELD; static const String INT_FIELD; static const String DOUBLE_FIELD; - + bool doMultiSegment; DirectoryPtr dir; AnalyzerPtr anlzr; - + protected: static const Collection DOC_TEXT_LINES(); - + void addDoc(IndexWriterPtr iw, int32_t i); String id2String(int32_t scoreAndID); String textLine(int32_t docNum); - + double expectedFieldScore(const String& docIDFieldVal); - + bool equalCollectionValues(CollectionValue first, CollectionValue second); }; } diff --git a/src/test/include/LuceneGlobalFixture.h b/src/test/include/LuceneGlobalFixture.h index 1c28077d..73a7a40b 100644 --- a/src/test/include/LuceneGlobalFixture.h +++ b/src/test/include/LuceneGlobalFixture.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/include/LuceneTestFixture.h b/src/test/include/LuceneTestFixture.h index cc0e4eb4..a033d03a 100644 --- a/src/test/include/LuceneTestFixture.h +++ b/src/test/include/LuceneTestFixture.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/include/MockFSDirectory.h b/src/test/include/MockFSDirectory.h index 5d744517..ec502484 100644 --- a/src/test/include/MockFSDirectory.h +++ b/src/test/include/MockFSDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,22 +17,22 @@ namespace Lucene public: MockFSDirectory(const String& path); virtual ~MockFSDirectory(); - + LUCENE_CLASS(MockFSDirectory); - + public: Collection allIndexInputs; - + protected: DirectoryPtr dir; RandomPtr rand; - + public: virtual IndexInputPtr openInput(const String& name); virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - + void tweakBufferSizes(); - + virtual IndexOutputPtr createOutput(const String& name); virtual void close(); virtual void deleteFile(const String& name); diff --git a/src/test/include/MockFilter.h b/src/test/include/MockFilter.h index 63709574..d45c0e11 100644 --- a/src/test/include/MockFilter.h +++ b/src/test/include/MockFilter.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,15 +17,15 @@ namespace Lucene public: MockFilter(); virtual ~MockFilter(); - + LUCENE_CLASS(MockFilter); - + protected: bool _wasCalled; - + public: virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); - + void clear(); bool wasCalled(); }; diff --git a/src/test/include/MockIndexInput.h b/src/test/include/MockIndexInput.h index a20051cb..4a4984f2 100644 --- a/src/test/include/MockIndexInput.h +++ b/src/test/include/MockIndexInput.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,18 +17,18 @@ namespace Lucene public: MockIndexInput(ByteArray bytes); virtual ~MockIndexInput(); - + LUCENE_CLASS(MockIndexInput); - + protected: ByteArray buffer; int32_t pointer; int64_t _length; - + public: virtual void close(); virtual int64_t length(); - + protected: virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); virtual void seekInternal(int64_t pos); diff --git a/src/test/include/MockLock.h b/src/test/include/MockLock.h index faa75fb0..c930f081 100644 --- a/src/test/include/MockLock.h +++ b/src/test/include/MockLock.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,12 +17,12 @@ namespace Lucene public: MockLock(); virtual ~MockLock(); - + LUCENE_CLASS(MockLock); - + public: int32_t lockAttempts; - + public: virtual bool obtain(); virtual void release(); diff --git a/src/test/include/MockLockFactory.h b/src/test/include/MockLockFactory.h index 39888480..ec7f9e8d 100644 --- a/src/test/include/MockLockFactory.h +++ b/src/test/include/MockLockFactory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,14 +17,14 @@ namespace Lucene public: MockLockFactory(); virtual ~MockLockFactory(); - + LUCENE_CLASS(MockLockFactory); - + public: bool lockPrefixSet; int32_t makeLockCount; MapStringLock locksCreated; - + public: virtual void setLockPrefix(const String& lockPrefix); virtual LockPtr makeLock(const String& lockName); diff --git a/src/test/include/MockRAMDirectory.h b/src/test/include/MockRAMDirectory.h index c2c3d306..e7c47f37 100644 --- a/src/test/include/MockRAMDirectory.h +++ b/src/test/include/MockRAMDirectory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,111 +19,111 @@ namespace Lucene MockRAMDirectory(); MockRAMDirectory(DirectoryPtr dir); virtual ~MockRAMDirectory(); - + LUCENE_CLASS(MockRAMDirectory); - + public: int64_t maxSize; RandomPtr randomState; - + // Max actual bytes used. This is set by MockRAMOutputStream int64_t maxUsedSize; double randomIOExceptionRate; bool noDeleteOpenFile; bool preventDoubleWrite; bool crashed; - + MapStringInt openFiles; - - // Only tracked if noDeleteOpenFile is true: if an attempt is made to delete an + + // Only tracked if noDeleteOpenFile is true: if an attempt is made to delete an // open file, we enroll it here. HashSet openFilesDeleted; - + Collection failures; - + protected: HashSet unSyncedFiles; HashSet createdFiles; - + public: /// If set to true, we throw an IO exception if the same file is opened by createOutput, ever. void setPreventDoubleWrite(bool value); - + virtual void sync(const String& name); - + /// Simulates a crash of OS or machine by overwriting unsynced files. void crash(); - + void clearCrash(); void setMaxSizeInBytes(int64_t maxSize); int64_t getMaxSizeInBytes(); - + /// Returns the peek actual storage used (bytes) in this directory. int64_t getMaxUsedSizeInBytes(); void resetMaxUsedSizeInBytes(); - + /// Emulate windows whereby deleting an open file is not allowed (raise IO exception) void setNoDeleteOpenFile(bool value); bool getNoDeleteOpenFile(); - + /// If 0.0, no exceptions will be thrown. Else this should be a double 0.0 - 1.0. We will randomly throw an /// IO exception on the first write to an OutputStream based on this probability. void setRandomIOExceptionRate(double rate, int64_t seed); double getRandomIOExceptionRate(); - + void maybeThrowIOException(); - + virtual void deleteFile(const String& name); - + virtual HashSet getOpenDeletedFiles(); - + virtual IndexOutputPtr createOutput(const String& name); virtual IndexInputPtr openInput(const String& name); - + /// Provided for testing purposes. Use sizeInBytes() instead. int64_t getRecomputedSizeInBytes(); - + /// Like getRecomputedSizeInBytes(), but, uses actual file lengths rather than buffer allocations (which are /// quantized up to nearest RAMOutputStream::BUFFER_SIZE (now 1024) bytes. int64_t getRecomputedActualSizeInBytes(); - + virtual void close(); - + /// Add a Failure object to the list of objects to be evaluated at every potential failure point void failOn(MockDirectoryFailurePtr fail); - + /// Iterate through the failures list, giving each object a chance to throw an IO exception. void maybeThrowDeterministicException(); - + protected: void init(); - + void deleteFile(const String& name, bool forced); }; - - /// Objects that represent fail-able conditions. Objects of a derived class are created and registered with the - /// mock directory. After register, each object will be invoked once for each first write of a file, giving the + + /// Objects that represent fail-able conditions. Objects of a derived class are created and registered with the + /// mock directory. After register, each object will be invoked once for each first write of a file, giving the /// object a chance to throw an IO exception. class MockDirectoryFailure : public LuceneObject { public: MockDirectoryFailure(); virtual ~MockDirectoryFailure(); - + LUCENE_CLASS(MockDirectoryFailure); - + public: /// eval is called on the first write of every new file. virtual void eval(MockRAMDirectoryPtr dir); - - /// reset should set the state of the failure to its default (freshly constructed) state. Reset is convenient - /// for tests that want to create one failure object and then reuse it in multiple cases. This, combined with + + /// reset should set the state of the failure to its default (freshly constructed) state. Reset is convenient + /// for tests that want to create one failure object and then reuse it in multiple cases. This, combined with /// the fact that MockDirectoryFailure subclasses are often anonymous classes makes reset difficult to do otherwise. virtual MockDirectoryFailurePtr reset(); - + virtual void setDoFail(); virtual void clearDoFail(); - + protected: bool doFail; }; diff --git a/src/test/include/MockRAMInputStream.h b/src/test/include/MockRAMInputStream.h index 076e83a6..cc00c8fe 100644 --- a/src/test/include/MockRAMInputStream.h +++ b/src/test/include/MockRAMInputStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,21 +16,21 @@ namespace Lucene class MockRAMInputStream : public RAMInputStream { public: - /// Construct an empty output buffer. + /// Construct an empty output buffer. MockRAMInputStream(); MockRAMInputStream(MockRAMDirectoryPtr dir, const String& name, RAMFilePtr f); virtual ~MockRAMInputStream(); - + LUCENE_CLASS(MockRAMInputStream); - + protected: MockRAMDirectoryWeakPtr _dir; String name; bool isClone; - + public: virtual void close(); - + virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); }; } diff --git a/src/test/include/MockRAMOutputStream.h b/src/test/include/MockRAMOutputStream.h index 5ceedc91..365b305b 100644 --- a/src/test/include/MockRAMOutputStream.h +++ b/src/test/include/MockRAMOutputStream.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,17 +20,17 @@ namespace Lucene /// Construct an empty output buffer. MockRAMOutputStream(MockRAMDirectoryPtr dir, RAMFilePtr f, const String& name); virtual ~MockRAMOutputStream(); - + LUCENE_CLASS(MockRAMOutputStream); - + protected: MockRAMDirectoryWeakPtr _dir; bool first; String name; - + public: ByteArray singleByte; - + public: virtual void close(); virtual void flush(); diff --git a/src/test/include/PayloadHelper.h b/src/test/include/PayloadHelper.h index fb7032e1..aa9a7f4e 100644 --- a/src/test/include/PayloadHelper.h +++ b/src/test/include/PayloadHelper.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,7 @@ namespace Lucene { public: virtual ~PayloadHelper(); - + public: static const String NO_PAYLOAD_FIELD; static const String MULTI_FIELD; @@ -25,7 +25,7 @@ namespace Lucene static const ByteArray payloadField(); static const ByteArray payloadMultiField1(); static const ByteArray payloadMultiField2(); - + /// Sets up a RAMDirectory, and adds documents (using intToEnglish()) with two fields: field and multiField /// and analyzes them using the PayloadHelperAnalyzer static IndexSearcherPtr setUp(SimilarityPtr similarity, int32_t numDocs); diff --git a/src/test/include/QueryUtils.h b/src/test/include/QueryUtils.h index 9384125d..1c77c3ab 100644 --- a/src/test/include/QueryUtils.h +++ b/src/test/include/QueryUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,48 +15,48 @@ namespace Lucene { public: virtual ~QueryUtils(); - + public: /// Check the types of things query objects should be able to do. static void check(QueryPtr q); - + /// Check very basic hashCode and equals static void checkHashEquals(QueryPtr q); - + static void checkEqual(QueryPtr q1, QueryPtr q2); static void checkUnequal(QueryPtr q1, QueryPtr q2); - + /// Deep check that explanations of a query 'score' correctly static void checkExplanations(QueryPtr q, SearcherPtr s); - - /// Various query sanity checks on a searcher, some checks are only done + + /// Various query sanity checks on a searcher, some checks are only done /// for types of IndexSearcher. static void check(QueryPtr q1, SearcherPtr s); static void check(QueryPtr q1, SearcherPtr s, bool wrap); - - /// Given an IndexSearcher, returns a new IndexSearcher whose IndexReader is a MultiReader - /// containing the Reader of the original IndexSearcher, as well as several "empty" - /// IndexReaders - some of which will have deleted documents in them. This new IndexSearcher + + /// Given an IndexSearcher, returns a new IndexSearcher whose IndexReader is a MultiReader + /// containing the Reader of the original IndexSearcher, as well as several "empty" + /// IndexReaders - some of which will have deleted documents in them. This new IndexSearcher /// should behave exactly the same as the original IndexSearcher. /// @param s the searcher to wrap. - /// @param edge if negative, s will be the first sub; if 0, s will be in the middle, if + /// @param edge if negative, s will be the first sub; if 0, s will be in the middle, if /// positive s will be the last sub static IndexSearcherPtr wrapUnderlyingReader(IndexSearcherPtr s, int32_t edge); - - /// Given a Searcher, returns a new MultiSearcher wrapping the the original Searcher, as well - /// as several "empty" IndexSearchers - some of which will have deleted documents in them. + + /// Given a Searcher, returns a new MultiSearcher wrapping the the original Searcher, as well + /// as several "empty" IndexSearchers - some of which will have deleted documents in them. /// This new MultiSearcher should behave exactly the same as the original Searcher. /// @param s the Searcher to wrap - /// @param edge if negative, s will be the first sub; if 0, s will be in hte middle, if positive + /// @param edge if negative, s will be the first sub; if 0, s will be in hte middle, if positive /// s will be the last sub static MultiSearcherPtr wrapSearcher(SearcherPtr s, int32_t edge); - + static RAMDirectoryPtr makeEmptyIndex(int32_t numDeletedDocs); - - /// Alternate scorer skipTo(), skipTo(), next(), next(), skipTo(), skipTo(), etc and ensure + + /// Alternate scorer skipTo(), skipTo(), next(), next(), skipTo(), skipTo(), etc and ensure /// a hitcollector receives same docs and scores static void checkSkipTo(QueryPtr q, IndexSearcherPtr s); - + /// Check that first skip on just created scorers always goes to the right doc static void checkFirstSkipTo(QueryPtr q, IndexSearcherPtr s); }; diff --git a/src/test/include/TestInc.h b/src/test/include/TestInc.h index 2a946708..a0056c7a 100644 --- a/src/test/include/TestInc.h +++ b/src/test/include/TestInc.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/include/TestUtils.h b/src/test/include/TestUtils.h index 13e3d1a3..33badb46 100644 --- a/src/test/include/TestUtils.h +++ b/src/test/include/TestUtils.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,29 +13,29 @@ namespace Lucene { /// Initialise unit test files directory void setTestDir(const String& dir); - + /// Return unit test files directory String getTestDir(); - + /// Return temporary directory String getTempDir(); - + /// Return temporary directory (randomly generated) String getTempDir(const String& desc); - + /// Wait for concurrent merge to finish void syncConcurrentMerges(IndexWriterPtr writer); - + /// Wait for concurrent merge to finish void syncConcurrentMerges(MergeSchedulerPtr ms); - + /// Return English representation of given integer String intToEnglish(int32_t i); - + /// Return English representation of given integer (recursive) String _intToEnglish(int32_t i); - - /// This runs the CheckIndex tool on the index in. + + /// This runs the CheckIndex tool on the index in. /// If any issues are hit, a RuntimeException is thrown; else, true is returned. bool checkIndex(DirectoryPtr dir); } diff --git a/src/test/include/test_lucene.h b/src/test/include/test_lucene.h index 63f4cf79..59c57319 100644 --- a/src/test/include/test_lucene.h +++ b/src/test/include/test_lucene.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/AddIndexesNoOptimizeTest.cpp b/src/test/index/AddIndexesNoOptimizeTest.cpp index ba74b6ea..309eb5bb 100644 --- a/src/test/index/AddIndexesNoOptimizeTest.cpp +++ b/src/test/index/AddIndexesNoOptimizeTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/AtomicUpdateTest.cpp b/src/test/index/AtomicUpdateTest.cpp index 0f8f227d..81f18a10 100644 --- a/src/test/index/AtomicUpdateTest.cpp +++ b/src/test/index/AtomicUpdateTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/BackwardsCompatibilityTest.cpp b/src/test/index/BackwardsCompatibilityTest.cpp index 8f5d2a22..8277fa22 100644 --- a/src/test/index/BackwardsCompatibilityTest.cpp +++ b/src/test/index/BackwardsCompatibilityTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/ByteSlicesTest.cpp b/src/test/index/ByteSlicesTest.cpp index 389d0c2c..009f4721 100644 --- a/src/test/index/ByteSlicesTest.cpp +++ b/src/test/index/ByteSlicesTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/CheckIndexTest.cpp b/src/test/index/CheckIndexTest.cpp index baaeb131..11911d48 100644 --- a/src/test/index/CheckIndexTest.cpp +++ b/src/test/index/CheckIndexTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/CompoundFileTest.cpp b/src/test/index/CompoundFileTest.cpp index f58b6100..fc5c7d39 100644 --- a/src/test/index/CompoundFileTest.cpp +++ b/src/test/index/CompoundFileTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/ConcurrentMergeSchedulerTest.cpp b/src/test/index/ConcurrentMergeSchedulerTest.cpp index 46c87166..a9475d2e 100644 --- a/src/test/index/ConcurrentMergeSchedulerTest.cpp +++ b/src/test/index/ConcurrentMergeSchedulerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/CrashTest.cpp b/src/test/index/CrashTest.cpp index 424f2130..714cda01 100644 --- a/src/test/index/CrashTest.cpp +++ b/src/test/index/CrashTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/DeletionPolicyTest.cpp b/src/test/index/DeletionPolicyTest.cpp index ea789b46..768b6eb5 100644 --- a/src/test/index/DeletionPolicyTest.cpp +++ b/src/test/index/DeletionPolicyTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/DirectoryReaderTest.cpp b/src/test/index/DirectoryReaderTest.cpp index 1ffba992..6f3212fa 100644 --- a/src/test/index/DirectoryReaderTest.cpp +++ b/src/test/index/DirectoryReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/DocHelper.cpp b/src/test/index/DocHelper.cpp index 49361472..0328d4b7 100644 --- a/src/test/index/DocHelper.cpp +++ b/src/test/index/DocHelper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -30,56 +30,56 @@ namespace Lucene const wchar_t* DocHelper::FIELD_3_TEXT = L"aaaNoNorms aaaNoNorms bbbNoNorms"; const wchar_t* DocHelper::TEXT_FIELD_3_KEY = L"textField3"; FieldPtr DocHelper::textField3; - + const wchar_t* DocHelper::KEYWORD_TEXT = L"Keyword"; const wchar_t* DocHelper::KEYWORD_FIELD_KEY = L"keyField"; FieldPtr DocHelper::keyField; - + const wchar_t* DocHelper::NO_NORMS_TEXT = L"omitNormsText"; const wchar_t* DocHelper::NO_NORMS_KEY = L"omitNorms"; FieldPtr DocHelper::noNormsField; - + const wchar_t* DocHelper::NO_TF_TEXT = L"analyzed with no tf and positions"; const wchar_t* DocHelper::NO_TF_KEY = L"omitTermFreqAndPositions"; FieldPtr DocHelper::noTFField; - + const wchar_t* DocHelper::UNINDEXED_FIELD_TEXT = L"unindexed field text"; const wchar_t* DocHelper::UNINDEXED_FIELD_KEY = L"unIndField"; FieldPtr DocHelper::unIndField; - + const wchar_t* DocHelper::UNSTORED_1_FIELD_TEXT = L"unstored field text"; const wchar_t* DocHelper::UNSTORED_FIELD_1_KEY = L"unStoredField1"; FieldPtr DocHelper::unStoredField1; - + const wchar_t* DocHelper::UNSTORED_2_FIELD_TEXT = L"unstored field text"; const wchar_t* DocHelper::UNSTORED_FIELD_2_KEY = L"unStoredField2"; FieldPtr DocHelper::unStoredField2; - + const wchar_t* DocHelper::LAZY_FIELD_BINARY_KEY = L"lazyFieldBinary"; ByteArray DocHelper::LAZY_FIELD_BINARY_BYTES; FieldPtr DocHelper::lazyFieldBinary; - + const wchar_t* DocHelper::LAZY_FIELD_KEY = L"lazyField"; const wchar_t* DocHelper::LAZY_FIELD_TEXT = L"These are some field bytes"; FieldPtr DocHelper::lazyField; - + const wchar_t* DocHelper::LARGE_LAZY_FIELD_KEY = L"largeLazyField"; String DocHelper::LARGE_LAZY_FIELD_TEXT; FieldPtr DocHelper::largeLazyField; - + const uint8_t DocHelper::_FIELD_UTF1_TEXT[] = {0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0xe4, 0xb8, 0x80, 0x74, 0x65, 0x78, 0x74}; const String DocHelper::FIELD_UTF1_TEXT = UTF8_TO_STRING(_FIELD_UTF1_TEXT); const wchar_t* DocHelper::TEXT_FIELD_UTF1_KEY = L"textField1Utf8"; FieldPtr DocHelper::textUtfField1; - - const uint8_t DocHelper::_FIELD_UTF2_TEXT[] = {0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, + + const uint8_t DocHelper::_FIELD_UTF2_TEXT[] = {0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0xe4, 0xb8, 0x80, 0x74, 0x77, 0x6f, 0x20, 0x74, 0x65, 0x78, 0x74}; const String DocHelper::FIELD_UTF2_TEXT = UTF8_TO_STRING(_FIELD_UTF2_TEXT); FieldPtr DocHelper::textUtfField2; - + // Fields will be lexicographically sorted. So, the order is: field, text, two const int32_t DocHelper::FIELD_UTF2_FREQS[] = {3, 1, 1}; const wchar_t* DocHelper::TEXT_FIELD_UTF2_KEY = L"textField2Utf8"; @@ -106,11 +106,11 @@ namespace Lucene setupRequired = false; } } - + DocHelper::~DocHelper() { } - + void DocHelper::setup() { textField1 = newLucene(TEXT_FIELD_1_KEY, FIELD_1_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); @@ -124,27 +124,27 @@ namespace Lucene unIndField = newLucene(UNINDEXED_FIELD_KEY, UNINDEXED_FIELD_TEXT, Field::STORE_YES, Field::INDEX_NO); unStoredField1 = newLucene(UNSTORED_FIELD_1_KEY, UNSTORED_1_FIELD_TEXT, Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); unStoredField2 = newLucene(UNSTORED_FIELD_2_KEY, UNSTORED_2_FIELD_TEXT, Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES); - + String binary(L"These are some binary field bytes"); UTF8ResultPtr utf8 = newInstance(); StringUtils::toUTF8(binary.c_str(), binary.length(), utf8); LAZY_FIELD_BINARY_BYTES = ByteArray::newInstance(utf8->length); MiscUtils::arrayCopy(utf8->result.get(), 0, LAZY_FIELD_BINARY_BYTES.get(), 0, utf8->length); - + lazyFieldBinary = newLucene(LAZY_FIELD_BINARY_KEY, LAZY_FIELD_BINARY_BYTES, Field::STORE_YES); lazyField = newLucene(LAZY_FIELD_KEY, LAZY_FIELD_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); - + if (LARGE_LAZY_FIELD_TEXT.empty()) { LARGE_LAZY_FIELD_TEXT.reserve(550000); for (int32_t i = 0; i < 10000; ++i) LARGE_LAZY_FIELD_TEXT += L"Lazily loading lengths of language in lieu of laughing "; } - + largeLazyField = newLucene(LARGE_LAZY_FIELD_KEY, LARGE_LAZY_FIELD_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); textUtfField1 = newLucene(TEXT_FIELD_UTF1_KEY, FIELD_UTF1_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); textUtfField2 = newLucene(TEXT_FIELD_UTF2_KEY, FIELD_UTF2_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); - + nameValues = MapStringString::newInstance(); nameValues.put(TEXT_FIELD_1_KEY, FIELD_1_TEXT); nameValues.put(TEXT_FIELD_2_KEY, FIELD_2_TEXT); @@ -160,7 +160,7 @@ namespace Lucene nameValues.put(LARGE_LAZY_FIELD_KEY, LARGE_LAZY_FIELD_TEXT); nameValues.put(TEXT_FIELD_UTF1_KEY, FIELD_UTF1_TEXT); nameValues.put(TEXT_FIELD_UTF2_KEY, FIELD_UTF2_TEXT); - + fields = Collection::newInstance(); fields.add(textField1); fields.add(textField2); @@ -176,7 +176,7 @@ namespace Lucene fields.add(lazyField); fields.add(lazyFieldBinary); fields.add(largeLazyField); - + all = MapStringField::newInstance(); indexed = MapStringField::newInstance(); stored = MapStringField::newInstance(); @@ -187,7 +187,7 @@ namespace Lucene lazy = MapStringField::newInstance(); noNorms = MapStringField::newInstance(); noTf = MapStringField::newInstance(); - + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { all.put((*field)->name(), *field); @@ -211,18 +211,18 @@ namespace Lucene noTf.put((*field)->name(), *field); } } - + void DocHelper::setupDoc(DocumentPtr doc) { for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) doc->add(*field); } - + SegmentInfoPtr DocHelper::writeDoc(DirectoryPtr dir, DocumentPtr doc) { return writeDoc(dir, newLucene(), Similarity::getDefault(), doc); } - + SegmentInfoPtr DocHelper::writeDoc(DirectoryPtr dir, AnalyzerPtr analyzer, SimilarityPtr similarity, DocumentPtr doc) { IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); @@ -233,7 +233,7 @@ namespace Lucene writer->close(); return info; } - + int32_t DocHelper::numFields(DocumentPtr doc) { return doc->getFields().size(); diff --git a/src/test/index/DocTest.cpp b/src/test/index/DocTest.cpp index 1384ac79..0a69157c 100644 --- a/src/test/index/DocTest.cpp +++ b/src/test/index/DocTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/DocumentWriterTest.cpp b/src/test/index/DocumentWriterTest.cpp index f177ccd8..b5add550 100644 --- a/src/test/index/DocumentWriterTest.cpp +++ b/src/test/index/DocumentWriterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/FieldInfosTest.cpp b/src/test/index/FieldInfosTest.cpp index 43f10c8d..88bb0402 100644 --- a/src/test/index/FieldInfosTest.cpp +++ b/src/test/index/FieldInfosTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/FieldsReaderTest.cpp b/src/test/index/FieldsReaderTest.cpp index 317bca69..30d7915c 100644 --- a/src/test/index/FieldsReaderTest.cpp +++ b/src/test/index/FieldsReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/FilterIndexReaderTest.cpp b/src/test/index/FilterIndexReaderTest.cpp index ef01ce2e..da2fb093 100644 --- a/src/test/index/FilterIndexReaderTest.cpp +++ b/src/test/index/FilterIndexReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexCommitTest.cpp b/src/test/index/IndexCommitTest.cpp index 36c1fa5a..2e547d2b 100644 --- a/src/test/index/IndexCommitTest.cpp +++ b/src/test/index/IndexCommitTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexFileDeleterTest.cpp b/src/test/index/IndexFileDeleterTest.cpp index c89e1628..da61a68e 100644 --- a/src/test/index/IndexFileDeleterTest.cpp +++ b/src/test/index/IndexFileDeleterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexInputTest.cpp b/src/test/index/IndexInputTest.cpp index 893e71d5..47015461 100644 --- a/src/test/index/IndexInputTest.cpp +++ b/src/test/index/IndexInputTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexReaderCloneNormsTest.cpp b/src/test/index/IndexReaderCloneNormsTest.cpp index 8d390e69..e4492df4 100644 --- a/src/test/index/IndexReaderCloneNormsTest.cpp +++ b/src/test/index/IndexReaderCloneNormsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexReaderCloneTest.cpp b/src/test/index/IndexReaderCloneTest.cpp index 9de1d880..62ec8e95 100644 --- a/src/test/index/IndexReaderCloneTest.cpp +++ b/src/test/index/IndexReaderCloneTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexReaderReopenTest.cpp b/src/test/index/IndexReaderReopenTest.cpp index bf5b0d3f..6d5cc2d7 100644 --- a/src/test/index/IndexReaderReopenTest.cpp +++ b/src/test/index/IndexReaderReopenTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexReaderTest.cpp b/src/test/index/IndexReaderTest.cpp index 58c82615..30d6177b 100644 --- a/src/test/index/IndexReaderTest.cpp +++ b/src/test/index/IndexReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexWriterDeleteTest.cpp b/src/test/index/IndexWriterDeleteTest.cpp index 8e02d98d..6a82feef 100644 --- a/src/test/index/IndexWriterDeleteTest.cpp +++ b/src/test/index/IndexWriterDeleteTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexWriterExceptionsTest.cpp b/src/test/index/IndexWriterExceptionsTest.cpp index 2cbb003d..b8d3e96b 100644 --- a/src/test/index/IndexWriterExceptionsTest.cpp +++ b/src/test/index/IndexWriterExceptionsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexWriterLockReleaseTest.cpp b/src/test/index/IndexWriterLockReleaseTest.cpp index 39f6b661..012bd86f 100644 --- a/src/test/index/IndexWriterLockReleaseTest.cpp +++ b/src/test/index/IndexWriterLockReleaseTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexWriterMergePolicyTest.cpp b/src/test/index/IndexWriterMergePolicyTest.cpp index 7e94d507..9326cd5f 100644 --- a/src/test/index/IndexWriterMergePolicyTest.cpp +++ b/src/test/index/IndexWriterMergePolicyTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexWriterMergingTest.cpp b/src/test/index/IndexWriterMergingTest.cpp index 77425383..4442d214 100644 --- a/src/test/index/IndexWriterMergingTest.cpp +++ b/src/test/index/IndexWriterMergingTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexWriterReaderTest.cpp b/src/test/index/IndexWriterReaderTest.cpp index f8ea578e..c1fb761a 100644 --- a/src/test/index/IndexWriterReaderTest.cpp +++ b/src/test/index/IndexWriterReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/IndexWriterTest.cpp b/src/test/index/IndexWriterTest.cpp index 5fdc90e3..7555b5d5 100644 --- a/src/test/index/IndexWriterTest.cpp +++ b/src/test/index/IndexWriterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/LazyBugTest.cpp b/src/test/index/LazyBugTest.cpp index 60cebc31..73f1d55b 100644 --- a/src/test/index/LazyBugTest.cpp +++ b/src/test/index/LazyBugTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/LazyProxSkippingTest.cpp b/src/test/index/LazyProxSkippingTest.cpp index d6055306..9824c1ba 100644 --- a/src/test/index/LazyProxSkippingTest.cpp +++ b/src/test/index/LazyProxSkippingTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/MockIndexInput.cpp b/src/test/index/MockIndexInput.cpp index 4953314e..86de16d0 100644 --- a/src/test/index/MockIndexInput.cpp +++ b/src/test/index/MockIndexInput.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ namespace Lucene _length = bytes.size(); pointer = 0; } - + MockIndexInput::~MockIndexInput() { } - + void MockIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) { int32_t remainder = length; @@ -37,17 +37,17 @@ namespace Lucene } pointer += length; } - + void MockIndexInput::close() { // ignore } - + void MockIndexInput::seekInternal(int64_t pos) { pointer = (int32_t)pos; } - + int64_t MockIndexInput::length() { return _length; diff --git a/src/test/index/MultiLevelSkipListTest.cpp b/src/test/index/MultiLevelSkipListTest.cpp index 69994d17..95acc37f 100644 --- a/src/test/index/MultiLevelSkipListTest.cpp +++ b/src/test/index/MultiLevelSkipListTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/MultiReaderTest.cpp b/src/test/index/MultiReaderTest.cpp index 44f5d2d0..cbf62c70 100644 --- a/src/test/index/MultiReaderTest.cpp +++ b/src/test/index/MultiReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/NRTReaderWithThreadsTest.cpp b/src/test/index/NRTReaderWithThreadsTest.cpp index d91002ed..86b2933e 100644 --- a/src/test/index/NRTReaderWithThreadsTest.cpp +++ b/src/test/index/NRTReaderWithThreadsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/NormsTest.cpp b/src/test/index/NormsTest.cpp index 4a2efd63..8022efea 100644 --- a/src/test/index/NormsTest.cpp +++ b/src/test/index/NormsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/OmitTfTest.cpp b/src/test/index/OmitTfTest.cpp index f5e20757..f77601b6 100644 --- a/src/test/index/OmitTfTest.cpp +++ b/src/test/index/OmitTfTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/ParallelReaderEmptyIndexTest.cpp b/src/test/index/ParallelReaderEmptyIndexTest.cpp index 5b134e64..ad196e3e 100644 --- a/src/test/index/ParallelReaderEmptyIndexTest.cpp +++ b/src/test/index/ParallelReaderEmptyIndexTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/ParallelReaderTest.cpp b/src/test/index/ParallelReaderTest.cpp index f89c33d1..db7a7b90 100644 --- a/src/test/index/ParallelReaderTest.cpp +++ b/src/test/index/ParallelReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/ParallelTermEnumTest.cpp b/src/test/index/ParallelTermEnumTest.cpp index fbfa60e3..e02f52c2 100644 --- a/src/test/index/ParallelTermEnumTest.cpp +++ b/src/test/index/ParallelTermEnumTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/PayloadsTest.cpp b/src/test/index/PayloadsTest.cpp index 75578016..474b2fe0 100644 --- a/src/test/index/PayloadsTest.cpp +++ b/src/test/index/PayloadsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/PositionBasedTermVectorMapperTest.cpp b/src/test/index/PositionBasedTermVectorMapperTest.cpp index 7e55e7bc..4e90c397 100644 --- a/src/test/index/PositionBasedTermVectorMapperTest.cpp +++ b/src/test/index/PositionBasedTermVectorMapperTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/SegmentMergerTest.cpp b/src/test/index/SegmentMergerTest.cpp index 2ee5050a..4cf13390 100644 --- a/src/test/index/SegmentMergerTest.cpp +++ b/src/test/index/SegmentMergerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/SegmentReaderTest.cpp b/src/test/index/SegmentReaderTest.cpp index dbb2ae44..7f30ca49 100644 --- a/src/test/index/SegmentReaderTest.cpp +++ b/src/test/index/SegmentReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/SegmentTermDocsTest.cpp b/src/test/index/SegmentTermDocsTest.cpp index 35512e4f..645ce8e7 100644 --- a/src/test/index/SegmentTermDocsTest.cpp +++ b/src/test/index/SegmentTermDocsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/SegmentTermEnumTest.cpp b/src/test/index/SegmentTermEnumTest.cpp index 391e5a8d..8f0babf5 100644 --- a/src/test/index/SegmentTermEnumTest.cpp +++ b/src/test/index/SegmentTermEnumTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/SnapshotDeletionPolicyTest.cpp b/src/test/index/SnapshotDeletionPolicyTest.cpp index aea64e58..22ada807 100644 --- a/src/test/index/SnapshotDeletionPolicyTest.cpp +++ b/src/test/index/SnapshotDeletionPolicyTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/StressIndexingTest.cpp b/src/test/index/StressIndexingTest.cpp index 074156b3..1a41a16f 100644 --- a/src/test/index/StressIndexingTest.cpp +++ b/src/test/index/StressIndexingTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/TermDocsPerfTest.cpp b/src/test/index/TermDocsPerfTest.cpp index 9f75bac2..ed99523a 100644 --- a/src/test/index/TermDocsPerfTest.cpp +++ b/src/test/index/TermDocsPerfTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/TermTest.cpp b/src/test/index/TermTest.cpp index b0d603ad..8cba2b84 100644 --- a/src/test/index/TermTest.cpp +++ b/src/test/index/TermTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/TermVectorsReaderTest.cpp b/src/test/index/TermVectorsReaderTest.cpp index 6d021800..ac12e213 100644 --- a/src/test/index/TermVectorsReaderTest.cpp +++ b/src/test/index/TermVectorsReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/ThreadedOptimizeTest.cpp b/src/test/index/ThreadedOptimizeTest.cpp index 616361e8..ed413db6 100644 --- a/src/test/index/ThreadedOptimizeTest.cpp +++ b/src/test/index/ThreadedOptimizeTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/TransactionRollbackTest.cpp b/src/test/index/TransactionRollbackTest.cpp index 09b7c88b..b6ee49a8 100644 --- a/src/test/index/TransactionRollbackTest.cpp +++ b/src/test/index/TransactionRollbackTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/TransactionsTest.cpp b/src/test/index/TransactionsTest.cpp index d43e7425..4bfea99d 100644 --- a/src/test/index/TransactionsTest.cpp +++ b/src/test/index/TransactionsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/index/WordlistLoaderTest.cpp b/src/test/index/WordlistLoaderTest.cpp index a634ea4c..44dc1370 100644 --- a/src/test/index/WordlistLoaderTest.cpp +++ b/src/test/index/WordlistLoaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/main/main.cpp b/src/test/main/main.cpp index 032c9e2d..cdf7f56d 100644 --- a/src/test/main/main.cpp +++ b/src/test/main/main.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/msvc/TestInc.cpp b/src/test/msvc/TestInc.cpp index 83637594..51e0e47b 100644 --- a/src/test/msvc/TestInc.cpp +++ b/src/test/msvc/TestInc.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/queryparser/MultiAnalyzerTest.cpp b/src/test/queryparser/MultiAnalyzerTest.cpp index 4ad90ba1..d7d786ae 100644 --- a/src/test/queryparser/MultiAnalyzerTest.cpp +++ b/src/test/queryparser/MultiAnalyzerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/queryparser/MultiFieldQueryParserTest.cpp b/src/test/queryparser/MultiFieldQueryParserTest.cpp index 67220a13..d65b1728 100644 --- a/src/test/queryparser/MultiFieldQueryParserTest.cpp +++ b/src/test/queryparser/MultiFieldQueryParserTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/queryparser/QueryParserTest.cpp b/src/test/queryparser/QueryParserTest.cpp index 5d0c704b..d29f49f5 100644 --- a/src/test/queryparser/QueryParserTest.cpp +++ b/src/test/queryparser/QueryParserTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/BaseTestRangeFilterFixture.cpp b/src/test/search/BaseTestRangeFilterFixture.cpp index 7e528920..15cc3d19 100644 --- a/src/test/search/BaseTestRangeFilterFixture.cpp +++ b/src/test/search/BaseTestRangeFilterFixture.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -22,11 +22,11 @@ namespace Lucene this->allowNegativeRandomInts = allowNegativeRandomInts; this->index = newLucene(); } - + TestIndex::~TestIndex() { } - + BaseTestRangeFilterFixture::BaseTestRangeFilterFixture() { signedIndex = newLucene(INT_MAX, INT_MIN, true); @@ -35,15 +35,15 @@ namespace Lucene maxId = 10000; intLength = StringUtils::toString(INT_MAX).length(); random = newLucene(); - + build(signedIndex); build(unsignedIndex); } - + BaseTestRangeFilterFixture::~BaseTestRangeFilterFixture() { } - + void BaseTestRangeFilterFixture::build(TestIndexPtr index) { IndexWriterPtr writer = newLucene(index->index, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -58,11 +58,11 @@ namespace Lucene doc->add(newLucene(L"body", L"body", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } - + writer->optimize(); writer->close(); } - + String BaseTestRangeFilterFixture::pad(int32_t n) { StringStream buf; @@ -77,6 +77,6 @@ namespace Lucene for (int32_t i = s.length(); i <= intLength; ++i) buf << L"0"; buf << s; - return buf.str(); + return buf.str(); } } diff --git a/src/test/search/BaseTestRangeFilterTest.cpp b/src/test/search/BaseTestRangeFilterTest.cpp index 4ab5137e..ec31673b 100644 --- a/src/test/search/BaseTestRangeFilterTest.cpp +++ b/src/test/search/BaseTestRangeFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/Boolean2Test.cpp b/src/test/search/Boolean2Test.cpp index 7521bbe0..18ef60f0 100644 --- a/src/test/search/Boolean2Test.cpp +++ b/src/test/search/Boolean2Test.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/BooleanMinShouldMatchTest.cpp b/src/test/search/BooleanMinShouldMatchTest.cpp index cb8f15b9..88f49a6b 100644 --- a/src/test/search/BooleanMinShouldMatchTest.cpp +++ b/src/test/search/BooleanMinShouldMatchTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/BooleanOrTest.cpp b/src/test/search/BooleanOrTest.cpp index 34b578ce..fc931548 100644 --- a/src/test/search/BooleanOrTest.cpp +++ b/src/test/search/BooleanOrTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/BooleanPrefixQueryTest.cpp b/src/test/search/BooleanPrefixQueryTest.cpp index 6bb7d268..43a67254 100644 --- a/src/test/search/BooleanPrefixQueryTest.cpp +++ b/src/test/search/BooleanPrefixQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/BooleanQueryTest.cpp b/src/test/search/BooleanQueryTest.cpp index 7814ff0b..2411f91e 100644 --- a/src/test/search/BooleanQueryTest.cpp +++ b/src/test/search/BooleanQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/BooleanScorerTest.cpp b/src/test/search/BooleanScorerTest.cpp index 2453f092..9ac2f8d8 100644 --- a/src/test/search/BooleanScorerTest.cpp +++ b/src/test/search/BooleanScorerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/CachingSpanFilterTest.cpp b/src/test/search/CachingSpanFilterTest.cpp index 5625b4f4..27b903da 100644 --- a/src/test/search/CachingSpanFilterTest.cpp +++ b/src/test/search/CachingSpanFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/CachingWrapperFilterTest.cpp b/src/test/search/CachingWrapperFilterTest.cpp index 18125b50..9b91c01f 100644 --- a/src/test/search/CachingWrapperFilterTest.cpp +++ b/src/test/search/CachingWrapperFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/CheckHits.cpp b/src/test/search/CheckHits.cpp index 923a71b1..49c73863 100644 --- a/src/test/search/CheckHits.cpp +++ b/src/test/search/CheckHits.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp index 16a88703..1b8602ac 100644 --- a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ComplexExplanationsTest.cpp b/src/test/search/ComplexExplanationsTest.cpp index d30af4f1..924ba600 100644 --- a/src/test/search/ComplexExplanationsTest.cpp +++ b/src/test/search/ComplexExplanationsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/CustomSearcherSortTest.cpp b/src/test/search/CustomSearcherSortTest.cpp index fc692ae1..6ef4577a 100644 --- a/src/test/search/CustomSearcherSortTest.cpp +++ b/src/test/search/CustomSearcherSortTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/DateFilterTest.cpp b/src/test/search/DateFilterTest.cpp index bd8a3030..139c066f 100644 --- a/src/test/search/DateFilterTest.cpp +++ b/src/test/search/DateFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/DateSortTest.cpp b/src/test/search/DateSortTest.cpp index bd8c2a54..5346c4e1 100644 --- a/src/test/search/DateSortTest.cpp +++ b/src/test/search/DateSortTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/DisjunctionMaxQueryTest.cpp b/src/test/search/DisjunctionMaxQueryTest.cpp index 734e22fc..a781a754 100644 --- a/src/test/search/DisjunctionMaxQueryTest.cpp +++ b/src/test/search/DisjunctionMaxQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/DocBoostTest.cpp b/src/test/search/DocBoostTest.cpp index 89347dec..af91bfde 100644 --- a/src/test/search/DocBoostTest.cpp +++ b/src/test/search/DocBoostTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/DocIdSetTest.cpp b/src/test/search/DocIdSetTest.cpp index 935eaa6f..0d83e050 100644 --- a/src/test/search/DocIdSetTest.cpp +++ b/src/test/search/DocIdSetTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ElevationComparatorTest.cpp b/src/test/search/ElevationComparatorTest.cpp index 77bb7816..ca57164d 100644 --- a/src/test/search/ElevationComparatorTest.cpp +++ b/src/test/search/ElevationComparatorTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ExplanationsFixture.cpp b/src/test/search/ExplanationsFixture.cpp index 15fe43e9..01a693dd 100644 --- a/src/test/search/ExplanationsFixture.cpp +++ b/src/test/search/ExplanationsFixture.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -27,15 +27,15 @@ namespace Lucene { const String ExplanationsFixture::KEY = L"KEY"; const String ExplanationsFixture::FIELD = L"field"; - + ExplanationsFixture::ExplanationsFixture() { qp = newLucene(LuceneVersion::LUCENE_CURRENT, FIELD, newLucene()); docFields = newCollection(L"w1 w2 w3 w4 w5", L"w1 w3 w2 w3 zz", L"w1 xx w2 yy w3", L"w1 w3 xx w2 yy w3 zz"); - + RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - + for (int32_t i = 0; i < docFields.size(); ++i) { DocumentPtr doc = newLucene(); @@ -46,72 +46,72 @@ namespace Lucene writer->close(); searcher = newLucene(directory, true); } - + ExplanationsFixture::~ExplanationsFixture() { searcher->close(); } - + SpanTermQueryPtr ExplanationsFixture::st(const String& s) { return newLucene(newLucene(FIELD, s)); } - + SpanFirstQueryPtr ExplanationsFixture::sf(const String& s, int32_t b) { return newLucene(st(s), b); } - + SpanNotQueryPtr ExplanationsFixture::snot(SpanQueryPtr i, SpanQueryPtr e) { return newLucene(i, e); } - + SpanOrQueryPtr ExplanationsFixture::sor(const String& s, const String& e) { return sor(st(s), st(e)); } - + SpanOrQueryPtr ExplanationsFixture::sor(SpanQueryPtr s, SpanQueryPtr e) { return newLucene(newCollection(s, e)); } - + SpanOrQueryPtr ExplanationsFixture::sor(const String& s, const String& m, const String& e) { return sor(st(s), st(m), st(e)); } - + SpanOrQueryPtr ExplanationsFixture::sor(SpanQueryPtr s, SpanQueryPtr m, SpanQueryPtr e) { return newLucene(newCollection(s, m, e)); } - + SpanNearQueryPtr ExplanationsFixture::snear(const String& s, const String& e, int32_t slop, bool inOrder) { return snear(st(s), st(e), slop, inOrder); } - + SpanNearQueryPtr ExplanationsFixture::snear(SpanQueryPtr s, SpanQueryPtr e, int32_t slop, bool inOrder) { return newLucene(newCollection(s, e), slop, inOrder); } - + SpanNearQueryPtr ExplanationsFixture::snear(const String& s, const String& m, const String& e, int32_t slop, bool inOrder) { return snear(st(s), st(m), st(e), slop, inOrder); } - + SpanNearQueryPtr ExplanationsFixture::snear(SpanQueryPtr s, SpanQueryPtr m, SpanQueryPtr e, int32_t slop, bool inOrder) { return newLucene(newCollection(s, m, e), slop, inOrder); } - + QueryPtr ExplanationsFixture::optB(const String& q) { return optB(makeQuery(q)); } - + QueryPtr ExplanationsFixture::optB(QueryPtr q) { BooleanQueryPtr bq = newLucene(true); @@ -119,12 +119,12 @@ namespace Lucene bq->add(newLucene(newLucene(L"NEVER", L"MATCH")), BooleanClause::MUST_NOT); return bq; } - + QueryPtr ExplanationsFixture::reqB(const String& q) { return reqB(makeQuery(q)); } - + QueryPtr ExplanationsFixture::reqB(QueryPtr q) { BooleanQueryPtr bq = newLucene(true); @@ -132,7 +132,7 @@ namespace Lucene bq->add(newLucene(newLucene(FIELD, L"w1")), BooleanClause::SHOULD); return bq; } - + Collection ExplanationsFixture::ta(Collection s) { Collection t = Collection::newInstance(s.size()); @@ -140,28 +140,28 @@ namespace Lucene t[i] = newLucene(FIELD, s[i]); return t; } - + void ExplanationsFixture::qtest(const String& queryText, Collection expDocNrs) { qtest(makeQuery(queryText), expDocNrs); } - + void ExplanationsFixture::qtest(QueryPtr q, Collection expDocNrs) { CheckHits::checkHitCollector(q, FIELD, searcher, expDocNrs); } - + void ExplanationsFixture::bqtest(QueryPtr q, Collection expDocNrs) { qtest(reqB(q), expDocNrs); qtest(optB(q), expDocNrs); } - + void ExplanationsFixture::bqtest(const String& queryText, Collection expDocNrs) { bqtest(makeQuery(queryText), expDocNrs); } - + QueryPtr ExplanationsFixture::makeQuery(const String& queryText) { return qp->parse(queryText); diff --git a/src/test/search/FieldCacheRangeFilterTest.cpp b/src/test/search/FieldCacheRangeFilterTest.cpp index ccf14360..38233c36 100644 --- a/src/test/search/FieldCacheRangeFilterTest.cpp +++ b/src/test/search/FieldCacheRangeFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/FieldCacheTermsFilterTest.cpp b/src/test/search/FieldCacheTermsFilterTest.cpp index 32e845bc..af793c98 100644 --- a/src/test/search/FieldCacheTermsFilterTest.cpp +++ b/src/test/search/FieldCacheTermsFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/FieldCacheTest.cpp b/src/test/search/FieldCacheTest.cpp index ae509ab2..2418642c 100644 --- a/src/test/search/FieldCacheTest.cpp +++ b/src/test/search/FieldCacheTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/FilteredQueryTest.cpp b/src/test/search/FilteredQueryTest.cpp index eb1c0067..9bea076c 100644 --- a/src/test/search/FilteredQueryTest.cpp +++ b/src/test/search/FilteredQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/FilteredSearchTest.cpp b/src/test/search/FilteredSearchTest.cpp index a833b9c2..6adbb9b4 100644 --- a/src/test/search/FilteredSearchTest.cpp +++ b/src/test/search/FilteredSearchTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/FuzzyQueryTest.cpp b/src/test/search/FuzzyQueryTest.cpp index c95b607d..d20b3a44 100644 --- a/src/test/search/FuzzyQueryTest.cpp +++ b/src/test/search/FuzzyQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/MatchAllDocsQueryTest.cpp b/src/test/search/MatchAllDocsQueryTest.cpp index c7d1dcb4..9be554b7 100644 --- a/src/test/search/MatchAllDocsQueryTest.cpp +++ b/src/test/search/MatchAllDocsQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/MockFilter.cpp b/src/test/search/MockFilter.cpp index 867aa496..cb662f18 100644 --- a/src/test/search/MockFilter.cpp +++ b/src/test/search/MockFilter.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -15,22 +15,22 @@ namespace Lucene { _wasCalled = false; } - + MockFilter::~MockFilter() { } - + DocIdSetPtr MockFilter::getDocIdSet(IndexReaderPtr reader) { _wasCalled = true; return newLucene(newLucene()); } - + void MockFilter::clear() { _wasCalled = false; } - + bool MockFilter::wasCalled() { return _wasCalled; diff --git a/src/test/search/MultiPhraseQueryTest.cpp b/src/test/search/MultiPhraseQueryTest.cpp index 0b7cfb27..71fd8d4b 100644 --- a/src/test/search/MultiPhraseQueryTest.cpp +++ b/src/test/search/MultiPhraseQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/MultiSearcherRankingTest.cpp b/src/test/search/MultiSearcherRankingTest.cpp index eaac9c60..07e98eb2 100644 --- a/src/test/search/MultiSearcherRankingTest.cpp +++ b/src/test/search/MultiSearcherRankingTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/MultiSearcherTest.cpp b/src/test/search/MultiSearcherTest.cpp index daddf33f..1c757f6c 100644 --- a/src/test/search/MultiSearcherTest.cpp +++ b/src/test/search/MultiSearcherTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/MultiTermConstantScoreTest.cpp b/src/test/search/MultiTermConstantScoreTest.cpp index 3a239168..965e3c64 100644 --- a/src/test/search/MultiTermConstantScoreTest.cpp +++ b/src/test/search/MultiTermConstantScoreTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/MultiThreadTermVectorsTest.cpp b/src/test/search/MultiThreadTermVectorsTest.cpp index b5dcda91..72f5127d 100644 --- a/src/test/search/MultiThreadTermVectorsTest.cpp +++ b/src/test/search/MultiThreadTermVectorsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/MultiValuedNumericRangeQueryTest.cpp b/src/test/search/MultiValuedNumericRangeQueryTest.cpp index 2612c3d4..8d7ac3ee 100644 --- a/src/test/search/MultiValuedNumericRangeQueryTest.cpp +++ b/src/test/search/MultiValuedNumericRangeQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/NotTest.cpp b/src/test/search/NotTest.cpp index c1f81462..56879639 100644 --- a/src/test/search/NotTest.cpp +++ b/src/test/search/NotTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/NumericRangeQuery32Test.cpp b/src/test/search/NumericRangeQuery32Test.cpp index b4fad67c..08a8f372 100644 --- a/src/test/search/NumericRangeQuery32Test.cpp +++ b/src/test/search/NumericRangeQuery32Test.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/NumericRangeQuery64Test.cpp b/src/test/search/NumericRangeQuery64Test.cpp index fdfbb948..8f5623e7 100644 --- a/src/test/search/NumericRangeQuery64Test.cpp +++ b/src/test/search/NumericRangeQuery64Test.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ParallelMultiSearcherTest.cpp b/src/test/search/ParallelMultiSearcherTest.cpp index 0e45c0de..4141da4d 100644 --- a/src/test/search/ParallelMultiSearcherTest.cpp +++ b/src/test/search/ParallelMultiSearcherTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/PhrasePrefixQueryTest.cpp b/src/test/search/PhrasePrefixQueryTest.cpp index 2049e4e1..85195c80 100644 --- a/src/test/search/PhrasePrefixQueryTest.cpp +++ b/src/test/search/PhrasePrefixQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/PhraseQueryTest.cpp b/src/test/search/PhraseQueryTest.cpp index 861926ba..0c268d37 100644 --- a/src/test/search/PhraseQueryTest.cpp +++ b/src/test/search/PhraseQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/PositionIncrementTest.cpp b/src/test/search/PositionIncrementTest.cpp index 9001897d..4e8d7bfe 100644 --- a/src/test/search/PositionIncrementTest.cpp +++ b/src/test/search/PositionIncrementTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/PositiveScoresOnlyCollectorTest.cpp b/src/test/search/PositiveScoresOnlyCollectorTest.cpp index dbb08539..823d1101 100644 --- a/src/test/search/PositiveScoresOnlyCollectorTest.cpp +++ b/src/test/search/PositiveScoresOnlyCollectorTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/PrefixFilterTest.cpp b/src/test/search/PrefixFilterTest.cpp index ffdccbae..1adaeec7 100644 --- a/src/test/search/PrefixFilterTest.cpp +++ b/src/test/search/PrefixFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/PrefixInBooleanQueryTest.cpp b/src/test/search/PrefixInBooleanQueryTest.cpp index 4a52efa1..0781b631 100644 --- a/src/test/search/PrefixInBooleanQueryTest.cpp +++ b/src/test/search/PrefixInBooleanQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/PrefixQueryTest.cpp b/src/test/search/PrefixQueryTest.cpp index e9cdfe91..2c2bff85 100644 --- a/src/test/search/PrefixQueryTest.cpp +++ b/src/test/search/PrefixQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/QueryTermVectorTest.cpp b/src/test/search/QueryTermVectorTest.cpp index 476d5719..76e92b8e 100644 --- a/src/test/search/QueryTermVectorTest.cpp +++ b/src/test/search/QueryTermVectorTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/QueryUtils.cpp b/src/test/search/QueryUtils.cpp index b7e596eb..377f75af 100644 --- a/src/test/search/QueryUtils.cpp +++ b/src/test/search/QueryUtils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/QueryWrapperFilterTest.cpp b/src/test/search/QueryWrapperFilterTest.cpp index 444dfd9b..2d77ed87 100644 --- a/src/test/search/QueryWrapperFilterTest.cpp +++ b/src/test/search/QueryWrapperFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ScoreCachingWrappingScorerTest.cpp b/src/test/search/ScoreCachingWrappingScorerTest.cpp index e4e20e0a..f23c4fe8 100644 --- a/src/test/search/ScoreCachingWrappingScorerTest.cpp +++ b/src/test/search/ScoreCachingWrappingScorerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ScorerPerfTest.cpp b/src/test/search/ScorerPerfTest.cpp index 05a6bd52..618fd2c5 100644 --- a/src/test/search/ScorerPerfTest.cpp +++ b/src/test/search/ScorerPerfTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SearchForDuplicatesTest.cpp b/src/test/search/SearchForDuplicatesTest.cpp index db12d3d4..928b9ad3 100644 --- a/src/test/search/SearchForDuplicatesTest.cpp +++ b/src/test/search/SearchForDuplicatesTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SearchTest.cpp b/src/test/search/SearchTest.cpp index 647e997e..6b8d7a5f 100644 --- a/src/test/search/SearchTest.cpp +++ b/src/test/search/SearchTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SetNormTest.cpp b/src/test/search/SetNormTest.cpp index c75db5a9..215749ce 100644 --- a/src/test/search/SetNormTest.cpp +++ b/src/test/search/SetNormTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SimilarityTest.cpp b/src/test/search/SimilarityTest.cpp index 02f2e8ed..2313a056 100644 --- a/src/test/search/SimilarityTest.cpp +++ b/src/test/search/SimilarityTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp index 3e7b2b7c..87878c58 100644 --- a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SimpleExplanationsTest.cpp b/src/test/search/SimpleExplanationsTest.cpp index fe6c9d2f..9cbd2be6 100644 --- a/src/test/search/SimpleExplanationsTest.cpp +++ b/src/test/search/SimpleExplanationsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SloppyPhraseQueryTest.cpp b/src/test/search/SloppyPhraseQueryTest.cpp index 488bf0a5..98bd6abf 100644 --- a/src/test/search/SloppyPhraseQueryTest.cpp +++ b/src/test/search/SloppyPhraseQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SortTest.cpp b/src/test/search/SortTest.cpp index 2b735f0c..3c891a96 100644 --- a/src/test/search/SortTest.cpp +++ b/src/test/search/SortTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/SpanQueryFilterTest.cpp b/src/test/search/SpanQueryFilterTest.cpp index dda33450..1308464c 100644 --- a/src/test/search/SpanQueryFilterTest.cpp +++ b/src/test/search/SpanQueryFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/TermRangeFilterTest.cpp b/src/test/search/TermRangeFilterTest.cpp index cf525f16..aab7f4d2 100644 --- a/src/test/search/TermRangeFilterTest.cpp +++ b/src/test/search/TermRangeFilterTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/TermRangeQueryTest.cpp b/src/test/search/TermRangeQueryTest.cpp index 5485a2e3..351b4d64 100644 --- a/src/test/search/TermRangeQueryTest.cpp +++ b/src/test/search/TermRangeQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/TermScorerTest.cpp b/src/test/search/TermScorerTest.cpp index 9181c79f..3534a0b2 100644 --- a/src/test/search/TermScorerTest.cpp +++ b/src/test/search/TermScorerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/TermVectorsTest.cpp b/src/test/search/TermVectorsTest.cpp index d0fe9645..d05bed69 100644 --- a/src/test/search/TermVectorsTest.cpp +++ b/src/test/search/TermVectorsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/ThreadSafeTest.cpp b/src/test/search/ThreadSafeTest.cpp index 15f9930e..b427634b 100644 --- a/src/test/search/ThreadSafeTest.cpp +++ b/src/test/search/ThreadSafeTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/TimeLimitingCollectorTest.cpp b/src/test/search/TimeLimitingCollectorTest.cpp index d3dac7e5..273073d1 100644 --- a/src/test/search/TimeLimitingCollectorTest.cpp +++ b/src/test/search/TimeLimitingCollectorTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/TopDocsCollectorTest.cpp b/src/test/search/TopDocsCollectorTest.cpp index 4c5988fc..0454ec4f 100644 --- a/src/test/search/TopDocsCollectorTest.cpp +++ b/src/test/search/TopDocsCollectorTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/TopScoreDocCollectorTest.cpp b/src/test/search/TopScoreDocCollectorTest.cpp index ec8cf61a..3b6b1bc8 100644 --- a/src/test/search/TopScoreDocCollectorTest.cpp +++ b/src/test/search/TopScoreDocCollectorTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/WildcardTest.cpp b/src/test/search/WildcardTest.cpp index 8d427abd..fa9c50df 100644 --- a/src/test/search/WildcardTest.cpp +++ b/src/test/search/WildcardTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/function/CustomScoreQueryTest.cpp b/src/test/search/function/CustomScoreQueryTest.cpp index 2ef7ab51..9bae8c1a 100644 --- a/src/test/search/function/CustomScoreQueryTest.cpp +++ b/src/test/search/function/CustomScoreQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/function/DocValuesTest.cpp b/src/test/search/function/DocValuesTest.cpp index f5aaf3e2..113893f4 100644 --- a/src/test/search/function/DocValuesTest.cpp +++ b/src/test/search/function/DocValuesTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/function/FieldScoreQueryTest.cpp b/src/test/search/function/FieldScoreQueryTest.cpp index 5d10e28c..c36217e0 100644 --- a/src/test/search/function/FieldScoreQueryTest.cpp +++ b/src/test/search/function/FieldScoreQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/function/FunctionFixture.cpp b/src/test/search/function/FunctionFixture.cpp index d68fa627..7d1eb15f 100644 --- a/src/test/search/function/FunctionFixture.cpp +++ b/src/test/search/function/FunctionFixture.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,19 +17,19 @@ namespace Lucene { /// Actual score computation order is slightly different than assumptions this allows for a small amount of variation const double FunctionFixture::TEST_SCORE_TOLERANCE_DELTA = 0.001; - + const int32_t FunctionFixture::N_DOCS = 17; - + const String FunctionFixture::ID_FIELD = L"id"; const String FunctionFixture::TEXT_FIELD = L"text"; const String FunctionFixture::INT_FIELD = L"iii"; const String FunctionFixture::DOUBLE_FIELD = L"fff"; - + FunctionFixture::FunctionFixture(bool doMultiSegment) { this->doMultiSegment = doMultiSegment; - - // prepare a small index with just a few documents. + + // prepare a small index with just a few documents. dir = newLucene(); anlzr = newLucene(LuceneVersion::LUCENE_CURRENT); IndexWriterPtr iw = newLucene(dir, anlzr, IndexWriter::MaxFieldLengthLIMITED); @@ -50,11 +50,11 @@ namespace Lucene } iw->close(); } - + FunctionFixture::~FunctionFixture() { } - + const Collection FunctionFixture::DOC_TEXT_LINES() { static Collection _DOC_TEXT_LINES; @@ -78,7 +78,7 @@ namespace Lucene } return _DOC_TEXT_LINES; } - + void FunctionFixture::addDoc(IndexWriterPtr iw, int32_t i) { DocumentPtr d = newLucene(); @@ -102,27 +102,27 @@ namespace Lucene iw->addDocument(d); } - + String FunctionFixture::id2String(int32_t scoreAndID) { String s = L"000000000" + StringUtils::toString(scoreAndID); // 17 --> ID00017 int32_t n = StringUtils::toString(N_DOCS).length() + 3; - int32_t k = s.length() - n; + int32_t k = s.length() - n; return L"ID" + s.substr(k); } - + String FunctionFixture::textLine(int32_t docNum) { // some text line for regular search return DOC_TEXT_LINES()[docNum % DOC_TEXT_LINES().size()]; } - + double FunctionFixture::expectedFieldScore(const String& docIDFieldVal) { // extract expected doc score from its ID Field: "ID7" --> 7.0 return StringUtils::toDouble(docIDFieldVal.substr(2)); } - + bool FunctionFixture::equalCollectionValues(CollectionValue first, CollectionValue second) { if (!VariantUtils::equalsType(first, second)) diff --git a/src/test/search/function/OrdValuesTest.cpp b/src/test/search/function/OrdValuesTest.cpp index 5b988b1c..0c9ed35e 100644 --- a/src/test/search/function/OrdValuesTest.cpp +++ b/src/test/search/function/OrdValuesTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/payloads/PayloadHelper.cpp b/src/test/search/payloads/PayloadHelper.cpp index a2cb7879..3eeb6fda 100644 --- a/src/test/search/payloads/PayloadHelper.cpp +++ b/src/test/search/payloads/PayloadHelper.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -23,9 +23,9 @@ namespace Lucene const String PayloadHelper::NO_PAYLOAD_FIELD = L"noPayloadField"; const String PayloadHelper::MULTI_FIELD = L"multiField"; const String PayloadHelper::FIELD = L"field"; - + DECLARE_SHARED_PTR(PayloadHelperAnalyzer) - + class PayloadHelperFilter : public TokenFilter { public: @@ -35,11 +35,11 @@ namespace Lucene this->fieldName = fieldName; this->payloadAtt = addAttribute(); } - + virtual ~PayloadHelperFilter() { } - + LUCENE_CLASS(PayloadHelperFilter); public: @@ -74,7 +74,7 @@ namespace Lucene virtual ~PayloadHelperAnalyzer() { } - + LUCENE_CLASS(PayloadHelperAnalyzer); public: @@ -85,11 +85,11 @@ namespace Lucene return result; } }; - + PayloadHelper::~PayloadHelper() { } - + const ByteArray PayloadHelper::payloadField() { static ByteArray _payloadField; @@ -100,7 +100,7 @@ namespace Lucene } return _payloadField; } - + const ByteArray PayloadHelper::payloadMultiField1() { static ByteArray _payloadMultiField1; @@ -111,7 +111,7 @@ namespace Lucene } return _payloadMultiField1; } - + const ByteArray PayloadHelper::payloadMultiField2() { static ByteArray _payloadMultiField2; @@ -122,7 +122,7 @@ namespace Lucene } return _payloadMultiField2; } - + IndexSearcherPtr PayloadHelper::setUp(SimilarityPtr similarity, int32_t numDocs) { RAMDirectoryPtr directory = newLucene(); diff --git a/src/test/search/payloads/PayloadNearQueryTest.cpp b/src/test/search/payloads/PayloadNearQueryTest.cpp index 7af5c032..1f04451a 100644 --- a/src/test/search/payloads/PayloadNearQueryTest.cpp +++ b/src/test/search/payloads/PayloadNearQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/payloads/PayloadTermQueryTest.cpp b/src/test/search/payloads/PayloadTermQueryTest.cpp index d9ef33b2..1cbf409c 100644 --- a/src/test/search/payloads/PayloadTermQueryTest.cpp +++ b/src/test/search/payloads/PayloadTermQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/BasicSpansTest.cpp b/src/test/search/spans/BasicSpansTest.cpp index ac807456..fcd89978 100644 --- a/src/test/search/spans/BasicSpansTest.cpp +++ b/src/test/search/spans/BasicSpansTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp index 1273f149..e1702e2c 100644 --- a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp +++ b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/NearSpansOrderedTest.cpp b/src/test/search/spans/NearSpansOrderedTest.cpp index 6dc9ed3b..45b8f2cb 100644 --- a/src/test/search/spans/NearSpansOrderedTest.cpp +++ b/src/test/search/spans/NearSpansOrderedTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/PayloadSpansTest.cpp b/src/test/search/spans/PayloadSpansTest.cpp index 82f3f015..21af398f 100644 --- a/src/test/search/spans/PayloadSpansTest.cpp +++ b/src/test/search/spans/PayloadSpansTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/SpanExplanationsTest.cpp b/src/test/search/spans/SpanExplanationsTest.cpp index f48137fb..cf714591 100644 --- a/src/test/search/spans/SpanExplanationsTest.cpp +++ b/src/test/search/spans/SpanExplanationsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/SpansAdvanced2Test.cpp b/src/test/search/spans/SpansAdvanced2Test.cpp index e2668257..3aa79eb7 100644 --- a/src/test/search/spans/SpansAdvanced2Test.cpp +++ b/src/test/search/spans/SpansAdvanced2Test.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/SpansAdvancedTest.cpp b/src/test/search/spans/SpansAdvancedTest.cpp index 50e0b907..13641a49 100644 --- a/src/test/search/spans/SpansAdvancedTest.cpp +++ b/src/test/search/spans/SpansAdvancedTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/search/spans/SpansTest.cpp b/src/test/search/spans/SpansTest.cpp index c3913fbd..e51667b6 100644 --- a/src/test/search/spans/SpansTest.cpp +++ b/src/test/search/spans/SpansTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/BufferedIndexInputTest.cpp b/src/test/store/BufferedIndexInputTest.cpp index 5fe0998d..6580a02f 100644 --- a/src/test/store/BufferedIndexInputTest.cpp +++ b/src/test/store/BufferedIndexInputTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/BufferedIndexOutputTest.cpp b/src/test/store/BufferedIndexOutputTest.cpp index 6c091090..05d2f4d5 100644 --- a/src/test/store/BufferedIndexOutputTest.cpp +++ b/src/test/store/BufferedIndexOutputTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/DirectoryTest.cpp b/src/test/store/DirectoryTest.cpp index 8b8542b3..fae7cfce 100644 --- a/src/test/store/DirectoryTest.cpp +++ b/src/test/store/DirectoryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/FileSwitchDirectoryTest.cpp b/src/test/store/FileSwitchDirectoryTest.cpp index 6dc80e39..0739358a 100644 --- a/src/test/store/FileSwitchDirectoryTest.cpp +++ b/src/test/store/FileSwitchDirectoryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/IndexOutputTest.cpp b/src/test/store/IndexOutputTest.cpp index 03136428..238d7e9d 100644 --- a/src/test/store/IndexOutputTest.cpp +++ b/src/test/store/IndexOutputTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/LockFactoryTest.cpp b/src/test/store/LockFactoryTest.cpp index c0b19aaa..0c12881f 100644 --- a/src/test/store/LockFactoryTest.cpp +++ b/src/test/store/LockFactoryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/MMapDirectoryTest.cpp b/src/test/store/MMapDirectoryTest.cpp index d774fa00..05d8f803 100644 --- a/src/test/store/MMapDirectoryTest.cpp +++ b/src/test/store/MMapDirectoryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/store/MockFSDirectory.cpp b/src/test/store/MockFSDirectory.cpp index 5345601c..ccb15638 100644 --- a/src/test/store/MockFSDirectory.cpp +++ b/src/test/store/MockFSDirectory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -20,16 +20,16 @@ namespace Lucene dir = newLucene(path); rand = newLucene(); } - + MockFSDirectory::~MockFSDirectory() { } - + IndexInputPtr MockFSDirectory::openInput(const String& name) { return openInput(name, BufferedIndexInput::BUFFER_SIZE); } - + void MockFSDirectory::tweakBufferSizes() { for (Collection::iterator ii = allIndexInputs.begin(); ii != allIndexInputs.end(); ++ii) @@ -39,7 +39,7 @@ namespace Lucene bii->setBufferSize(bufferSize); } } - + IndexInputPtr MockFSDirectory::openInput(const String& name, int32_t bufferSize) { // Make random changes to buffer size @@ -48,42 +48,42 @@ namespace Lucene allIndexInputs.add(f); return f; } - + IndexOutputPtr MockFSDirectory::createOutput(const String& name) { return dir->createOutput(name); } - + void MockFSDirectory::close() { dir->close(); } - + void MockFSDirectory::deleteFile(const String& name) { dir->deleteFile(name); } - + void MockFSDirectory::touchFile(const String& name) { dir->touchFile(name); } - + uint64_t MockFSDirectory::fileModified(const String& name) { return dir->fileModified(name); } - + bool MockFSDirectory::fileExists(const String& name) { return dir->fileExists(name); } - + HashSet MockFSDirectory::listAll() { return dir->listAll(); } - + int64_t MockFSDirectory::fileLength(const String& name) { return dir->fileLength(name); diff --git a/src/test/store/MockLock.cpp b/src/test/store/MockLock.cpp index 93a1bfdb..541b25cf 100644 --- a/src/test/store/MockLock.cpp +++ b/src/test/store/MockLock.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -13,27 +13,27 @@ namespace Lucene { lockAttempts = 0; } - + MockLock::~MockLock() { } - + bool MockLock::obtain() { ++lockAttempts; return true; } - + void MockLock::release() { // do nothing } - + bool MockLock::isLocked() { return false; } - + String MockLock::toString() { return L"MockLock"; diff --git a/src/test/store/MockLockFactory.cpp b/src/test/store/MockLockFactory.cpp index 756c9e8e..7e405001 100644 --- a/src/test/store/MockLockFactory.cpp +++ b/src/test/store/MockLockFactory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -16,17 +16,17 @@ namespace Lucene lockPrefixSet = false; makeLockCount = 0; } - + MockLockFactory::~MockLockFactory() { } - + void MockLockFactory::setLockPrefix(const String& lockPrefix) { LockFactory::setLockPrefix(lockPrefix); lockPrefixSet = true; } - + LockPtr MockLockFactory::makeLock(const String& lockName) { LockPtr lock(newLucene()); @@ -35,7 +35,7 @@ namespace Lucene ++makeLockCount; return lock; } - + void MockLockFactory::clearLock(const String& lockName) { } diff --git a/src/test/store/MockRAMDirectory.cpp b/src/test/store/MockRAMDirectory.cpp index 03c74468..a063de77 100644 --- a/src/test/store/MockRAMDirectory.cpp +++ b/src/test/store/MockRAMDirectory.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -25,7 +25,7 @@ namespace Lucene crashed = false; init(); } - + MockRAMDirectory::MockRAMDirectory(DirectoryPtr dir) : RAMDirectory(dir) { maxSize = 0; @@ -36,11 +36,11 @@ namespace Lucene crashed = false; init(); } - + MockRAMDirectory::~MockRAMDirectory() { } - + void MockRAMDirectory::init() { SyncLock syncLock(this); @@ -54,12 +54,12 @@ namespace Lucene if (!unSyncedFiles) unSyncedFiles = HashSet::newInstance(); } - + void MockRAMDirectory::setPreventDoubleWrite(bool value) { preventDoubleWrite = value; } - + void MockRAMDirectory::sync(const String& name) { TestScope testScope(L"MockRAMDirectory", L"sync"); @@ -69,7 +69,7 @@ namespace Lucene boost::throw_exception(IOException(L"cannot sync after crash")); unSyncedFiles.remove(name); } - + void MockRAMDirectory::crash() { SyncLock syncLock(this); @@ -99,55 +99,55 @@ namespace Lucene ++count; } } - + void MockRAMDirectory::clearCrash() { SyncLock syncLock(this); crashed = false; } - + void MockRAMDirectory::setMaxSizeInBytes(int64_t maxSize) { this->maxSize = maxSize; } - + int64_t MockRAMDirectory::getMaxSizeInBytes() { return maxSize; } - + int64_t MockRAMDirectory::getMaxUsedSizeInBytes() { return maxUsedSize; } - + void MockRAMDirectory::resetMaxUsedSizeInBytes() { maxUsedSize = getRecomputedActualSizeInBytes(); } - + void MockRAMDirectory::setNoDeleteOpenFile(bool value) { noDeleteOpenFile = value; } - + bool MockRAMDirectory::getNoDeleteOpenFile() { return noDeleteOpenFile; } - + void MockRAMDirectory::setRandomIOExceptionRate(double rate, int64_t seed) { randomIOExceptionRate = rate; // seed so we have deterministic behaviour randomState = newLucene(seed); } - + double MockRAMDirectory::getRandomIOExceptionRate() { return randomIOExceptionRate; } - + void MockRAMDirectory::maybeThrowIOException() { if (randomIOExceptionRate > 0.0) @@ -157,23 +157,23 @@ namespace Lucene boost::throw_exception(IOException(L"a random IO exception")); } } - + void MockRAMDirectory::deleteFile(const String& name) { deleteFile(name, false); } - + void MockRAMDirectory::deleteFile(const String& name, bool forced) { TestScope testScope(L"MockRAMDirectory", L"deleteFile"); SyncLock syncLock(this); maybeThrowDeterministicException(); - + if (crashed && !forced) boost::throw_exception(IOException(L"cannot delete after crash")); - + unSyncedFiles.remove(name); - + if (!forced && noDeleteOpenFile) { if (openFiles.contains(name)) @@ -184,17 +184,17 @@ namespace Lucene else openFilesDeleted.remove(name); } - + RAMDirectory::deleteFile(name); } - + HashSet MockRAMDirectory::getOpenDeletedFiles() { SyncLock syncLock(this); HashSet openFilesDeleted = HashSet::newInstance(this->openFilesDeleted.begin(), this->openFilesDeleted.end()); return openFilesDeleted; } - + IndexOutputPtr MockRAMDirectory::createOutput(const String& name) { SyncLock syncLock(this); @@ -223,10 +223,10 @@ namespace Lucene } fileMap.put(name, file); } - + return newLucene(shared_from_this(), file, name); } - + IndexInputPtr MockRAMDirectory::openInput(const String& name) { SyncLock syncLock(this); @@ -243,7 +243,7 @@ namespace Lucene } return newLucene(shared_from_this(), name, file->second); } - + int64_t MockRAMDirectory::getRecomputedSizeInBytes() { SyncLock syncLock(this); @@ -252,7 +252,7 @@ namespace Lucene size += file->second->getSizeInBytes(); return size; } - + int64_t MockRAMDirectory::getRecomputedActualSizeInBytes() { SyncLock syncLock(this); @@ -261,7 +261,7 @@ namespace Lucene size += file->second->length; return size; } - + void MockRAMDirectory::close() { SyncLock syncLock(this); @@ -276,7 +276,7 @@ namespace Lucene boost::throw_exception(RuntimeException(L"MockRAMDirectory: cannot close: there are still open files")); } } - + void MockRAMDirectory::failOn(MockDirectoryFailurePtr fail) { SyncLock syncLock(this); @@ -284,7 +284,7 @@ namespace Lucene failures = Collection::newInstance(); failures.add(fail); } - + void MockRAMDirectory::maybeThrowDeterministicException() { SyncLock syncLock(this); @@ -294,30 +294,30 @@ namespace Lucene (*failure)->eval(shared_from_this()); } } - + MockDirectoryFailure::MockDirectoryFailure() { doFail = false; } - + MockDirectoryFailure::~MockDirectoryFailure() { } - + void MockDirectoryFailure::eval(MockRAMDirectoryPtr dir) { } - + MockDirectoryFailurePtr MockDirectoryFailure::reset() { return shared_from_this(); } - + void MockDirectoryFailure::setDoFail() { doFail = true; } - + void MockDirectoryFailure::clearDoFail() { doFail = false; diff --git a/src/test/store/MockRAMInputStream.cpp b/src/test/store/MockRAMInputStream.cpp index 9f07445c..10f43fdc 100644 --- a/src/test/store/MockRAMInputStream.cpp +++ b/src/test/store/MockRAMInputStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -14,18 +14,18 @@ namespace Lucene { this->isClone = false; } - + MockRAMInputStream::MockRAMInputStream(MockRAMDirectoryPtr dir, const String& name, RAMFilePtr f) : RAMInputStream(f) { this->isClone = false; this->name = name; this->_dir = dir; } - + MockRAMInputStream::~MockRAMInputStream() { } - + void MockRAMInputStream::close() { RAMInputStream::close(); @@ -47,7 +47,7 @@ namespace Lucene } } } - + LuceneObjectPtr MockRAMInputStream::clone(LuceneObjectPtr other) { LuceneObjectPtr clone = RAMInputStream::clone(other ? other : newLucene()); diff --git a/src/test/store/MockRAMOutputStream.cpp b/src/test/store/MockRAMOutputStream.cpp index 49968a25..cc2784ea 100644 --- a/src/test/store/MockRAMOutputStream.cpp +++ b/src/test/store/MockRAMOutputStream.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -17,44 +17,44 @@ namespace Lucene this->_dir = dir; this->name = name; } - + MockRAMOutputStream::~MockRAMOutputStream() { } - + void MockRAMOutputStream::close() { RAMOutputStream::close(); MockRAMDirectoryPtr dir(_dir); - + // Now compute actual disk usage & track the maxUsedSize in the MockRAMDirectory int64_t size = dir->getRecomputedActualSizeInBytes(); if (size > dir->maxUsedSize) dir->maxUsedSize = size; } - + void MockRAMOutputStream::flush() { MockRAMDirectoryPtr(_dir)->maybeThrowDeterministicException(); RAMOutputStream::flush(); } - + void MockRAMOutputStream::writeByte(uint8_t b) { singleByte[0] = b; writeBytes(singleByte.get(), 0, 1); } - + void MockRAMOutputStream::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { MockRAMDirectoryPtr dir(_dir); int64_t freeSpace = dir->maxSize - dir->sizeInBytes(); int64_t realUsage = 0; - + // If MockRAMDir crashed since we were opened, then don't write anything if (dir->crashed) boost::throw_exception(IOException(L"MockRAMDirectory was crashed; cannot write to " + name)); - + // Enforce disk full if (dir->maxSize != 0 && freeSpace <= length) { @@ -62,7 +62,7 @@ namespace Lucene realUsage = dir->getRecomputedActualSizeInBytes(); freeSpace = dir->maxSize - realUsage; } - + if (dir->maxSize != 0 && freeSpace <= length) { if (freeSpace > 0 && freeSpace < length) @@ -76,9 +76,9 @@ namespace Lucene } else RAMOutputStream::writeBytes(b, offset, length); - + dir->maybeThrowDeterministicException(); - + if (first) { // Maybe throw random exception; only do this on first write to a new file diff --git a/src/test/store/RAMDirectoryTest.cpp b/src/test/store/RAMDirectoryTest.cpp index 64aaff55..8d52bdb2 100644 --- a/src/test/store/RAMDirectoryTest.cpp +++ b/src/test/store/RAMDirectoryTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/AttributeSourceTest.cpp b/src/test/util/AttributeSourceTest.cpp index 63552a0e..40e1ab8f 100644 --- a/src/test/util/AttributeSourceTest.cpp +++ b/src/test/util/AttributeSourceTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/Base64Test.cpp b/src/test/util/Base64Test.cpp index 05a775c0..968850b1 100644 --- a/src/test/util/Base64Test.cpp +++ b/src/test/util/Base64Test.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/BitVectorTest.cpp b/src/test/util/BitVectorTest.cpp index 9d8ddaef..9a7fd688 100644 --- a/src/test/util/BitVectorTest.cpp +++ b/src/test/util/BitVectorTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/BufferedReaderTest.cpp b/src/test/util/BufferedReaderTest.cpp index c6a85461..f70cc56c 100644 --- a/src/test/util/BufferedReaderTest.cpp +++ b/src/test/util/BufferedReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/CloseableThreadLocalTest.cpp b/src/test/util/CloseableThreadLocalTest.cpp index 701e2081..ea07acd7 100644 --- a/src/test/util/CloseableThreadLocalTest.cpp +++ b/src/test/util/CloseableThreadLocalTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/CompressionToolsTest.cpp b/src/test/util/CompressionToolsTest.cpp index 967b7eca..a164f217 100644 --- a/src/test/util/CompressionToolsTest.cpp +++ b/src/test/util/CompressionToolsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/FieldCacheSanityCheckerTest.cpp b/src/test/util/FieldCacheSanityCheckerTest.cpp index 3d5942e9..dc968a66 100644 --- a/src/test/util/FieldCacheSanityCheckerTest.cpp +++ b/src/test/util/FieldCacheSanityCheckerTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/FileReaderTest.cpp b/src/test/util/FileReaderTest.cpp index 400ae76d..cc376418 100644 --- a/src/test/util/FileReaderTest.cpp +++ b/src/test/util/FileReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/FileUtilsTest.cpp b/src/test/util/FileUtilsTest.cpp index 5ca6ffbf..dda0d153 100644 --- a/src/test/util/FileUtilsTest.cpp +++ b/src/test/util/FileUtilsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/InputStreamReaderTest.cpp b/src/test/util/InputStreamReaderTest.cpp index 54587f87..3910757a 100644 --- a/src/test/util/InputStreamReaderTest.cpp +++ b/src/test/util/InputStreamReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/LuceneGlobalFixture.cpp b/src/test/util/LuceneGlobalFixture.cpp index 24ab7c50..d86e7b18 100644 --- a/src/test/util/LuceneGlobalFixture.cpp +++ b/src/test/util/LuceneGlobalFixture.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/LuceneTestFixture.cpp b/src/test/util/LuceneTestFixture.cpp index 3f34a390..e1ce9388 100644 --- a/src/test/util/LuceneTestFixture.cpp +++ b/src/test/util/LuceneTestFixture.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/NumericUtilsTest.cpp b/src/test/util/NumericUtilsTest.cpp index 51f06f5b..dbc7cee2 100644 --- a/src/test/util/NumericUtilsTest.cpp +++ b/src/test/util/NumericUtilsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/OpenBitSetTest.cpp b/src/test/util/OpenBitSetTest.cpp index 021a34fa..1680d926 100644 --- a/src/test/util/OpenBitSetTest.cpp +++ b/src/test/util/OpenBitSetTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/PriorityQueueTest.cpp b/src/test/util/PriorityQueueTest.cpp index 3c637224..14de02be 100644 --- a/src/test/util/PriorityQueueTest.cpp +++ b/src/test/util/PriorityQueueTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/SimpleLRUCacheTest.cpp b/src/test/util/SimpleLRUCacheTest.cpp index ad468d63..5c8c66e9 100644 --- a/src/test/util/SimpleLRUCacheTest.cpp +++ b/src/test/util/SimpleLRUCacheTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/SortedVIntListTest.cpp b/src/test/util/SortedVIntListTest.cpp index e3362de3..aa582f53 100644 --- a/src/test/util/SortedVIntListTest.cpp +++ b/src/test/util/SortedVIntListTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/StringReaderTest.cpp b/src/test/util/StringReaderTest.cpp index eb27bfec..e928f49b 100644 --- a/src/test/util/StringReaderTest.cpp +++ b/src/test/util/StringReaderTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/StringUtilsTest.cpp b/src/test/util/StringUtilsTest.cpp index 3c7c6c8a..a32e911f 100644 --- a/src/test/util/StringUtilsTest.cpp +++ b/src/test/util/StringUtilsTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// diff --git a/src/test/util/TestUtils.cpp b/src/test/util/TestUtils.cpp index 6d3431c1..7f7438f8 100644 --- a/src/test/util/TestUtils.cpp +++ b/src/test/util/TestUtils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// @@ -19,37 +19,37 @@ namespace Lucene { static RandomPtr randomTest = newLucene(); static String testDir; - + void setTestDir(const String& dir) { testDir = dir; } - + String getTestDir() { if (testDir.empty()) boost::throw_exception(RuntimeException(L"test directory not set")); return testDir; } - + String getTempDir() { static String tempDir; - + if (tempDir.empty()) { tempDir = FileUtils::joinPath(getTestDir(), L"temp"); FileUtils::createDirectory(tempDir); } - + return tempDir; } - + String getTempDir(const String& desc) { return FileUtils::joinPath(getTempDir(), desc + L"." + StringUtils::toString(randomTest->nextInt())); } - + void syncConcurrentMerges(IndexWriterPtr writer) { syncConcurrentMerges(writer->getMergeScheduler()); @@ -60,20 +60,20 @@ namespace Lucene if (MiscUtils::typeOf(ms)) boost::dynamic_pointer_cast(ms)->sync(); } - + String intToEnglish(int32_t i) { String english(_intToEnglish(i)); boost::trim(english); return english; } - + String _intToEnglish(int32_t i) { String english; if (i == 0) return L"zero"; - if (i < 0) + if (i < 0) { english += L"minus "; i = -i; @@ -169,7 +169,7 @@ namespace Lucene } return english; } - + bool checkIndex(DirectoryPtr dir) { CheckIndexPtr checker = newLucene(dir); diff --git a/src/test/util/VersionTest.cpp b/src/test/util/VersionTest.cpp index b49a3ce2..3236bd2b 100644 --- a/src/test/util/VersionTest.cpp +++ b/src/test/util/VersionTest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2009-2011 Alan Wright. All rights reserved. +// Copyright (c) 2009-2014 Alan Wright. All rights reserved. // Distributable under the terms of either the Apache License (Version 2.0) // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// From 6a6bb8256dd9fb2668fac00793f090098f5785c0 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Wed, 12 Feb 2014 22:28:52 +0000 Subject: [PATCH 051/157] Make all symbols visible. --- CMakeLists.txt | 6 --- cmake/MacroCheckGccVisibility.cmake | 58 ----------------------------- include/Config.h.cmake | 5 --- 3 files changed, 69 deletions(-) delete mode 100644 cmake/MacroCheckGccVisibility.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 01c64aa7..115bdc2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,12 +92,6 @@ if(NOT MSVC AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") add_definitions(-fPIC) endif() -include(MacroCheckGccVisibility) -MACRO_CHECK_GCC_VISIBILITY(LPP_HAVE_GXXCLASSVISIBILITY) -if(LPP_HAVE_GXXCLASSVISIBILITY) - add_definitions(-DLPP_HAVE_GXXCLASSVISIBILITY) -endif() - if(CYGWIN) add_definitions(-D__LARGE64_FILES) endif() diff --git a/cmake/MacroCheckGccVisibility.cmake b/cmake/MacroCheckGccVisibility.cmake deleted file mode 100644 index 4fb6f8ad..00000000 --- a/cmake/MacroCheckGccVisibility.cmake +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright (c) 2006, Alexander Neundorf -# Copyright (c) 2006, Laurent Montel, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -macro(MACRO_CHECK_GCC_VISIBILITY GccVisibility) - if (CMAKE_COMPILER_IS_GNUCXX) - include(CheckCXXCompilerFlag) - include(MacroEnsureVersion) - # visibility support - check_cxx_compiler_flag(-fvisibility=hidden ${GccVisibility}) - - # get the gcc version - exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info) - - string (REGEX MATCH "[345]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}") - if (NOT _gcc_version) - - # clang reports: clang version 1.1 (trunk 95754) - string (REGEX MATCH "clang version ([123]\\.[0-9])" _gcc_version "${_gcc_version_info}") - if ( _gcc_version ) - string(REGEX REPLACE "clang version (.*)" "\\1.0" _gcc_version "${_gcc_version}" ) - endif ( _gcc_version ) - - # gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the patch level, handle this here: - if (NOT _gcc_version) - string (REGEX REPLACE ".*\\(GCC\\).* ([34]\\.[0-9]) .*" "\\1.0" _gcc_version "${_gcc_version_info}") - endif (NOT _gcc_version) - endif (NOT _gcc_version) - - - - macro_ensure_version("4.1.0" "${_gcc_version}" GCC_IS_NEWER_THAN_4_1) - macro_ensure_version("4.2.0" "${_gcc_version}" GCC_IS_NEWER_THAN_4_2) - - set(_GCC_COMPILED_WITH_BAD_ALLOCATOR FALSE) - if (GCC_IS_NEWER_THAN_4_1) - exec_program(${CMAKE_C_COMPILER} ARGS -v OUTPUT_VARIABLE _gcc_alloc_info) - string(REGEX MATCH "(--enable-libstdcxx-allocator=mt)" _GCC_COMPILED_WITH_BAD_ALLOCATOR "${_gcc_alloc_info}") - endif (GCC_IS_NEWER_THAN_4_1) - - if (${GccVisibility} AND GCC_IS_NEWER_THAN_4_1 AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") - - if (GCC_IS_NEWER_THAN_4_2) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") - endif (GCC_IS_NEWER_THAN_4_2) - else (${GccVisibility} AND GCC_IS_NEWER_THAN_4_1 AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) - set (${GccVisibility} 0) - endif (${GccVisibility} AND GCC_IS_NEWER_THAN_4_1 AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) - - else (CMAKE_COMPILER_IS_GNUCXX) - set(${GccVisibility} FALSE) - endif (CMAKE_COMPILER_IS_GNUCXX) -endmacro(MACRO_CHECK_GCC_VISIBILITY) diff --git a/include/Config.h.cmake b/include/Config.h.cmake index 742021ef..f716a4ed 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -21,14 +21,9 @@ #define LPP_IMPORT __declspec(dllimport) #define LPP_EXPORT __declspec(dllexport) #else -#ifdef LPP_HAVE_GXXCLASSVISIBILITY -#define LPP_IMPORT __attribute__ ((visibility("default"))) -#define LPP_EXPORT __attribute__ ((visibility("default"))) -#else #define LPP_IMPORT #define LPP_EXPORT #endif -#endif // Define LPPAPI for dll builds #ifdef LPP_HAVE_DLL From e7a604affbd1b94036c83e02d97554c1f2c59728 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Tue, 18 Feb 2014 23:48:25 +0100 Subject: [PATCH 052/157] Pass all Ptr (shared_ptr) arguments as const references. - Big improvement in performance. --- include/ASCIIFoldingFilter.h | 2 +- include/AbstractAllTermDocs.h | 4 +- include/AllTermDocs.h | 2 +- include/Analyzer.h | 8 +- include/Attribute.h | 6 +- include/AttributeSource.h | 12 +- include/AveragePayloadFunction.h | 2 +- include/BaseCharFilter.h | 2 +- include/BitSet.h | 14 +-- include/BitVector.h | 14 +-- include/BooleanClause.h | 6 +- include/BooleanQuery.h | 14 +-- include/BooleanScorer.h | 14 +-- include/BooleanScorer2.h | 18 +-- include/BufferedDeletes.h | 4 +- include/BufferedIndexInput.h | 2 +- include/BufferedReader.h | 2 +- include/ByteBlockPool.h | 2 +- include/ByteFieldSource.h | 6 +- include/ByteSliceReader.h | 4 +- include/ByteSliceWriter.h | 2 +- include/CachingSpanFilter.h | 10 +- include/CachingTokenFilter.h | 2 +- include/CachingWrapperFilter.h | 8 +- include/CharBlockPool.h | 2 +- include/CharFilter.h | 2 +- include/CharReader.h | 4 +- include/CharTokenizer.h | 8 +- include/CheckIndex.h | 14 +-- include/ChecksumIndexInput.h | 4 +- include/ChecksumIndexOutput.h | 2 +- include/CloseableThreadLocal.h | 2 +- include/Collector.h | 10 +- include/CompoundFileReader.h | 12 +- include/CompoundFileWriter.h | 4 +- include/ConcurrentMergeScheduler.h | 6 +- include/ConjunctionScorer.h | 2 +- include/ConstantScoreQuery.h | 10 +- include/CustomScoreProvider.h | 6 +- include/CustomScoreQuery.h | 22 ++-- include/DefaultSimilarity.h | 2 +- include/DefaultSkipListReader.h | 4 +- include/DefaultSkipListWriter.h | 8 +- include/Directory.h | 4 +- include/DirectoryReader.h | 50 ++++---- include/DisjunctionMaxQuery.h | 10 +- include/DisjunctionMaxScorer.h | 2 +- include/DisjunctionSumScorer.h | 4 +- include/DocConsumer.h | 6 +- include/DocFieldConsumer.h | 8 +- include/DocFieldConsumerPerThread.h | 2 +- include/DocFieldConsumers.h | 14 +-- include/DocFieldConsumersPerField.h | 2 +- include/DocFieldConsumersPerThread.h | 6 +- include/DocFieldProcessor.h | 8 +- include/DocFieldProcessorPerField.h | 2 +- include/DocFieldProcessorPerThread.h | 8 +- include/DocIdBitSet.h | 6 +- include/DocInverter.h | 10 +- include/DocInverterPerField.h | 2 +- include/DocInverterPerThread.h | 4 +- include/Document.h | 2 +- include/DocumentsWriter.h | 50 ++++---- include/DocumentsWriterThreadState.h | 2 +- include/DoubleFieldSource.h | 8 +- include/ExactPhraseScorer.h | 2 +- include/Explanation.h | 2 +- include/FSDirectory.h | 4 +- include/FastCharStream.h | 2 +- include/Field.h | 16 +-- include/FieldCache.h | 24 ++-- include/FieldCacheImpl.h | 62 +++++----- include/FieldCacheRangeFilter.h | 12 +- include/FieldCacheSanityChecker.h | 4 +- include/FieldCacheSource.h | 8 +- include/FieldCacheTermsFilter.h | 2 +- include/FieldComparator.h | 32 +++--- include/FieldInfo.h | 2 +- include/FieldInfos.h | 12 +- include/FieldMaskingSpanQuery.h | 14 +-- include/FieldValueHitQueue.h | 2 +- include/FieldsReader.h | 24 ++-- include/FieldsWriter.h | 14 +-- include/FileSwitchDirectory.h | 2 +- include/Filter.h | 2 +- include/FilterIndexReader.h | 24 ++-- include/FilterManager.h | 2 +- include/FilteredDocIdSet.h | 2 +- include/FilteredDocIdSetIterator.h | 2 +- include/FilteredQuery.h | 10 +- include/FilteredTermEnum.h | 4 +- include/FlagsAttribute.h | 6 +- include/FormatPostingsDocsWriter.h | 4 +- include/FormatPostingsFieldsConsumer.h | 2 +- include/FormatPostingsFieldsWriter.h | 4 +- include/FormatPostingsPositionsWriter.h | 4 +- include/FormatPostingsTermsWriter.h | 4 +- include/FreqProxFieldMergeState.h | 2 +- include/FreqProxTermsWriter.h | 8 +- include/FreqProxTermsWriterPerField.h | 12 +- include/FreqProxTermsWriterPerThread.h | 4 +- include/FuzzyQuery.h | 18 +-- include/FuzzyTermEnum.h | 10 +- include/HitQueueBase.h | 6 +- include/ISOLatin1AccentFilter.h | 2 +- include/IndexCommit.h | 2 +- include/IndexFileDeleter.h | 14 +-- include/IndexInput.h | 2 +- include/IndexOutput.h | 2 +- include/IndexReader.h | 48 ++++---- include/IndexSearcher.h | 30 ++--- include/IndexWriter.h | 84 +++++++------- include/InputStreamReader.h | 2 +- include/IntBlockPool.h | 2 +- include/IntFieldSource.h | 6 +- include/InvertedDocConsumer.h | 8 +- include/InvertedDocConsumerPerField.h | 2 +- include/InvertedDocConsumerPerThread.h | 2 +- include/InvertedDocEndConsumer.h | 8 +- include/InvertedDocEndConsumerPerThread.h | 2 +- include/KeywordAnalyzer.h | 4 +- include/KeywordTokenizer.h | 8 +- include/LengthFilter.h | 2 +- include/LetterTokenizer.h | 6 +- include/LogByteSizeMergePolicy.h | 4 +- include/LogDocMergePolicy.h | 4 +- include/LogMergePolicy.h | 24 ++-- include/LowerCaseFilter.h | 2 +- include/LowerCaseTokenizer.h | 6 +- include/LuceneObject.h | 6 +- include/LuceneSignal.h | 4 +- include/MMapDirectory.h | 2 +- include/MappingCharFilter.h | 6 +- include/MatchAllDocsQuery.h | 6 +- include/MaxPayloadFunction.h | 2 +- include/MergeDocIDRemapper.h | 2 +- include/MergePolicy.h | 22 ++-- include/MergeScheduler.h | 2 +- include/MinPayloadFunction.h | 2 +- include/MiscUtils.h | 4 +- include/MultiFieldQueryParser.h | 12 +- include/MultiLevelSkipListReader.h | 6 +- include/MultiLevelSkipListWriter.h | 4 +- include/MultiPhraseQuery.h | 10 +- include/MultiReader.h | 12 +- include/MultiSearcher.h | 16 +-- include/MultiTermQuery.h | 16 +-- include/MultiTermQueryWrapperFilter.h | 6 +- include/MultipleTermPositions.h | 6 +- include/NearSpansOrdered.h | 4 +- include/NearSpansUnordered.h | 4 +- include/NormsWriter.h | 8 +- include/NormsWriterPerField.h | 4 +- include/NormsWriterPerThread.h | 4 +- include/NumericRangeFilter.h | 2 +- include/NumericRangeQuery.h | 6 +- include/NumericTokenStream.h | 4 +- include/NumericUtils.h | 8 +- include/OffsetAttribute.h | 6 +- include/OpenBitSet.h | 28 ++--- include/OpenBitSetDISI.h | 10 +- include/OpenBitSetIterator.h | 2 +- include/OrdFieldSource.h | 4 +- include/ParallelMultiSearcher.h | 6 +- include/ParallelReader.h | 20 ++-- include/Payload.h | 4 +- include/PayloadAttribute.h | 10 +- include/PayloadFunction.h | 2 +- include/PayloadNearQuery.h | 14 +-- include/PayloadSpanUtil.h | 8 +- include/PayloadTermQuery.h | 8 +- include/PerFieldAnalyzerWrapper.h | 12 +- include/PhrasePositions.h | 2 +- include/PhraseQuery.h | 10 +- include/PhraseScorer.h | 2 +- include/PorterStemFilter.h | 4 +- include/PositionBasedTermVectorMapper.h | 2 +- include/PositionIncrementAttribute.h | 6 +- include/PositiveScoresOnlyCollector.h | 6 +- include/PrefixFilter.h | 2 +- include/PrefixQuery.h | 8 +- include/PrefixTermEnum.h | 4 +- include/Query.h | 12 +- include/QueryParseError.h | 2 +- include/QueryParser.h | 28 ++--- include/QueryParserTokenManager.h | 10 +- include/QueryTermVector.h | 2 +- include/QueryWrapperFilter.h | 6 +- include/RAMDirectory.h | 4 +- include/RAMFile.h | 2 +- include/RAMInputStream.h | 4 +- include/RAMOutputStream.h | 4 +- include/ReadOnlyDirectoryReader.h | 6 +- include/ReaderUtil.h | 6 +- include/ReqExclScorer.h | 2 +- include/ReqOptSumScorer.h | 2 +- include/ReverseOrdFieldSource.h | 4 +- include/ScoreCachingWrappingScorer.h | 6 +- include/Scorer.h | 6 +- include/ScorerDocQueue.h | 4 +- include/Searchable.h | 14 +-- include/Searcher.h | 30 ++--- include/SegmentInfo.h | 18 +-- include/SegmentInfoCollection.h | 14 +-- include/SegmentInfos.h | 36 +++--- include/SegmentMergeInfo.h | 2 +- include/SegmentMerger.h | 22 ++-- include/SegmentReader.h | 38 +++---- include/SegmentTermDocs.h | 10 +- include/SegmentTermEnum.h | 10 +- include/SegmentTermPositions.h | 4 +- include/SegmentWriteState.h | 2 +- include/SerialMergeScheduler.h | 2 +- include/Similarity.h | 6 +- include/SimilarityDelegator.h | 4 +- include/SimpleAnalyzer.h | 4 +- include/SimpleFSDirectory.h | 2 +- include/SingleTermEnum.h | 4 +- include/SloppyPhraseScorer.h | 6 +- include/SnapshotDeletionPolicy.h | 2 +- include/Sort.h | 6 +- include/SortField.h | 6 +- include/SortedVIntList.h | 6 +- include/SpanFilter.h | 2 +- include/SpanFilterResult.h | 2 +- include/SpanFirstQuery.h | 10 +- include/SpanNearQuery.h | 8 +- include/SpanNotQuery.h | 10 +- include/SpanOrQuery.h | 8 +- include/SpanQuery.h | 4 +- include/SpanQueryFilter.h | 8 +- include/SpanScorer.h | 2 +- include/SpanTermQuery.h | 8 +- include/SpanWeight.h | 6 +- include/StandardAnalyzer.h | 6 +- include/StandardFilter.h | 2 +- include/StandardTokenizer.h | 10 +- include/StandardTokenizerImpl.h | 10 +- include/StopAnalyzer.h | 6 +- include/StopFilter.h | 4 +- include/StoredFieldsWriter.h | 14 +-- include/StoredFieldsWriterPerThread.h | 4 +- include/StringUtils.h | 4 +- include/Synchronize.h | 2 +- include/TeeSinkTokenFilter.h | 18 +-- include/Term.h | 4 +- include/TermAttribute.h | 6 +- include/TermBuffer.h | 10 +- include/TermDocs.h | 4 +- include/TermInfo.h | 4 +- include/TermInfosReader.h | 14 +-- include/TermInfosWriter.h | 10 +- include/TermQuery.h | 8 +- include/TermRangeQuery.h | 6 +- include/TermRangeTermEnum.h | 6 +- include/TermScorer.h | 6 +- include/TermSpans.h | 2 +- include/TermVectorEntry.h | 2 +- include/TermVectorOffsetInfo.h | 2 +- include/TermVectorsReader.h | 18 +-- include/TermVectorsTermsWriter.h | 14 +-- include/TermVectorsTermsWriterPerField.h | 8 +- include/TermVectorsTermsWriterPerThread.h | 6 +- include/TermVectorsWriter.h | 4 +- include/TermsHash.h | 14 +-- include/TermsHashConsumer.h | 8 +- include/TermsHashConsumerPerField.h | 6 +- include/TermsHashConsumerPerThread.h | 2 +- include/TermsHashPerField.h | 6 +- include/TermsHashPerThread.h | 4 +- include/ThreadPool.h | 2 +- include/TimeLimitingCollector.h | 6 +- include/Token.h | 18 +-- include/TokenFilter.h | 2 +- include/TokenStream.h | 4 +- include/Tokenizer.h | 12 +- include/TopDocsCollector.h | 2 +- include/TopFieldCollector.h | 4 +- include/TopScoreDocCollector.h | 4 +- include/TypeAttribute.h | 6 +- include/UTF8Stream.h | 4 +- include/ValueSource.h | 4 +- include/ValueSourceQuery.h | 10 +- include/Weight.h | 4 +- include/WhitespaceAnalyzer.h | 4 +- include/WhitespaceTokenizer.h | 6 +- include/WildcardQuery.h | 10 +- include/WildcardTermEnum.h | 4 +- include/WordlistLoader.h | 2 +- .../common/analysis/ar/ArabicAnalyzer.cpp | 4 +- .../analysis/ar/ArabicLetterTokenizer.cpp | 6 +- .../analysis/ar/ArabicNormalizationFilter.cpp | 2 +- .../common/analysis/ar/ArabicStemFilter.cpp | 2 +- .../common/analysis/br/BrazilianAnalyzer.cpp | 4 +- .../analysis/br/BrazilianStemFilter.cpp | 4 +- .../common/analysis/cjk/CJKAnalyzer.cpp | 4 +- .../common/analysis/cjk/CJKTokenizer.cpp | 8 +- .../common/analysis/cn/ChineseAnalyzer.cpp | 4 +- .../common/analysis/cn/ChineseFilter.cpp | 2 +- .../common/analysis/cn/ChineseTokenizer.cpp | 8 +- .../common/analysis/cz/CzechAnalyzer.cpp | 4 +- .../common/analysis/de/GermanAnalyzer.cpp | 4 +- .../common/analysis/de/GermanStemFilter.cpp | 6 +- .../common/analysis/el/GreekAnalyzer.cpp | 4 +- .../analysis/el/GreekLowerCaseFilter.cpp | 2 +- .../common/analysis/fa/PersianAnalyzer.cpp | 4 +- .../fa/PersianNormalizationFilter.cpp | 2 +- .../common/analysis/fr/ElisionFilter.cpp | 4 +- .../common/analysis/fr/FrenchAnalyzer.cpp | 4 +- .../common/analysis/fr/FrenchStemFilter.cpp | 6 +- .../common/analysis/nl/DutchAnalyzer.cpp | 4 +- .../common/analysis/nl/DutchStemFilter.cpp | 8 +- .../analysis/reverse/ReverseStringFilter.cpp | 4 +- .../common/analysis/ru/RussianAnalyzer.cpp | 4 +- .../analysis/ru/RussianLetterTokenizer.cpp | 6 +- .../analysis/ru/RussianLowerCaseFilter.cpp | 2 +- .../common/analysis/ru/RussianStemFilter.cpp | 4 +- src/contrib/highlighter/Formatter.cpp | 2 +- src/contrib/highlighter/Fragmenter.cpp | 2 +- src/contrib/highlighter/GradientFormatter.cpp | 2 +- src/contrib/highlighter/Highlighter.cpp | 47 ++++---- src/contrib/highlighter/HighlighterScorer.cpp | 4 +- .../highlighter/MapWeightedSpanTerm.cpp | 2 +- src/contrib/highlighter/NullFragmenter.cpp | 2 +- src/contrib/highlighter/QueryScorer.cpp | 18 +-- .../highlighter/QueryTermExtractor.cpp | 14 +-- src/contrib/highlighter/QueryTermScorer.cpp | 10 +- src/contrib/highlighter/SimpleFragmenter.cpp | 2 +- .../highlighter/SimpleHTMLFormatter.cpp | 2 +- .../highlighter/SimpleSpanFragmenter.cpp | 6 +- .../highlighter/SpanGradientFormatter.cpp | 2 +- src/contrib/highlighter/TextFragment.cpp | 6 +- src/contrib/highlighter/TokenGroup.cpp | 2 +- src/contrib/highlighter/TokenSources.cpp | 16 +-- .../highlighter/WeightedSpanTermExtractor.cpp | 61 +++++----- src/contrib/include/ArabicAnalyzer.h | 4 +- src/contrib/include/ArabicLetterTokenizer.h | 6 +- .../include/ArabicNormalizationFilter.h | 2 +- src/contrib/include/ArabicStemFilter.h | 2 +- src/contrib/include/BrazilianAnalyzer.h | 4 +- src/contrib/include/BrazilianStemFilter.h | 4 +- src/contrib/include/CJKAnalyzer.h | 4 +- src/contrib/include/CJKTokenizer.h | 8 +- src/contrib/include/ChineseAnalyzer.h | 4 +- src/contrib/include/ChineseFilter.h | 2 +- src/contrib/include/ChineseTokenizer.h | 8 +- src/contrib/include/CzechAnalyzer.h | 4 +- src/contrib/include/DutchAnalyzer.h | 4 +- src/contrib/include/DutchStemFilter.h | 8 +- src/contrib/include/ElisionFilter.h | 4 +- src/contrib/include/Formatter.h | 2 +- src/contrib/include/Fragmenter.h | 2 +- src/contrib/include/FrenchAnalyzer.h | 4 +- src/contrib/include/FrenchStemFilter.h | 6 +- src/contrib/include/GermanAnalyzer.h | 4 +- src/contrib/include/GermanStemFilter.h | 6 +- src/contrib/include/GradientFormatter.h | 2 +- src/contrib/include/GreekAnalyzer.h | 4 +- src/contrib/include/GreekLowerCaseFilter.h | 2 +- src/contrib/include/Highlighter.h | 24 ++-- src/contrib/include/HighlighterScorer.h | 4 +- src/contrib/include/MapWeightedSpanTerm.h | 2 +- src/contrib/include/MemoryIndex.h | 38 +++---- src/contrib/include/NullFragmenter.h | 2 +- src/contrib/include/PersianAnalyzer.h | 4 +- .../include/PersianNormalizationFilter.h | 2 +- src/contrib/include/QueryScorer.h | 18 +-- src/contrib/include/QueryTermExtractor.h | 14 +-- src/contrib/include/QueryTermScorer.h | 10 +- src/contrib/include/ReverseStringFilter.h | 4 +- src/contrib/include/RussianAnalyzer.h | 4 +- src/contrib/include/RussianLetterTokenizer.h | 6 +- src/contrib/include/RussianLowerCaseFilter.h | 2 +- src/contrib/include/RussianStemFilter.h | 4 +- src/contrib/include/SimpleFragmenter.h | 2 +- src/contrib/include/SimpleHTMLFormatter.h | 2 +- src/contrib/include/SimpleSpanFragmenter.h | 6 +- src/contrib/include/SnowballAnalyzer.h | 4 +- src/contrib/include/SnowballFilter.h | 2 +- src/contrib/include/SpanGradientFormatter.h | 2 +- src/contrib/include/TextFragment.h | 6 +- src/contrib/include/TokenGroup.h | 2 +- src/contrib/include/TokenSources.h | 16 +-- .../include/WeightedSpanTermExtractor.h | 20 ++-- src/contrib/memory/MemoryIndex.cpp | 36 +++--- src/contrib/snowball/SnowballAnalyzer.cpp | 4 +- src/contrib/snowball/SnowballFilter.cpp | 2 +- src/core/analysis/ASCIIFoldingFilter.cpp | 2 +- src/core/analysis/Analyzer.cpp | 6 +- src/core/analysis/BaseCharFilter.cpp | 2 +- src/core/analysis/CachingTokenFilter.cpp | 2 +- src/core/analysis/CharFilter.cpp | 2 +- src/core/analysis/CharReader.cpp | 4 +- src/core/analysis/CharTokenizer.cpp | 8 +- src/core/analysis/ISOLatin1AccentFilter.cpp | 2 +- src/core/analysis/KeywordAnalyzer.cpp | 4 +- src/core/analysis/KeywordTokenizer.cpp | 8 +- src/core/analysis/LengthFilter.cpp | 2 +- src/core/analysis/LetterTokenizer.cpp | 6 +- src/core/analysis/LowerCaseFilter.cpp | 2 +- src/core/analysis/LowerCaseTokenizer.cpp | 6 +- src/core/analysis/MappingCharFilter.cpp | 6 +- src/core/analysis/NumericTokenStream.cpp | 4 +- src/core/analysis/PerFieldAnalyzerWrapper.cpp | 12 +- src/core/analysis/PorterStemFilter.cpp | 2 +- src/core/analysis/SimpleAnalyzer.cpp | 4 +- src/core/analysis/StopAnalyzer.cpp | 6 +- src/core/analysis/StopFilter.cpp | 4 +- src/core/analysis/TeeSinkTokenFilter.cpp | 16 +-- src/core/analysis/Token.cpp | 18 +-- src/core/analysis/TokenFilter.cpp | 2 +- src/core/analysis/TokenStream.cpp | 4 +- src/core/analysis/Tokenizer.cpp | 12 +- src/core/analysis/WhitespaceAnalyzer.cpp | 4 +- src/core/analysis/WhitespaceTokenizer.cpp | 6 +- src/core/analysis/WordlistLoader.cpp | 2 +- .../analysis/standard/StandardAnalyzer.cpp | 6 +- src/core/analysis/standard/StandardFilter.cpp | 2 +- .../analysis/standard/StandardTokenizer.cpp | 10 +- .../standard/StandardTokenizerImpl.cpp | 10 +- .../tokenattributes/FlagsAttribute.cpp | 6 +- .../tokenattributes/OffsetAttribute.cpp | 6 +- .../tokenattributes/PayloadAttribute.cpp | 10 +- .../PositionIncrementAttribute.cpp | 6 +- .../tokenattributes/TermAttribute.cpp | 6 +- .../tokenattributes/TypeAttribute.cpp | 6 +- src/core/document/Document.cpp | 2 +- src/core/document/Field.cpp | 16 +-- src/core/include/_BooleanQuery.h | 8 +- src/core/include/_ByteFieldSource.h | 2 +- src/core/include/_CachingSpanFilter.h | 2 +- src/core/include/_CachingWrapperFilter.h | 10 +- src/core/include/_CheckIndex.h | 4 +- src/core/include/_ConcurrentMergeScheduler.h | 4 +- src/core/include/_ConstantScoreQuery.h | 8 +- src/core/include/_CustomScoreQuery.h | 16 +-- src/core/include/_DirectoryReader.h | 4 +- src/core/include/_DisjunctionMaxQuery.h | 6 +- src/core/include/_DocIdBitSet.h | 2 +- src/core/include/_FieldCacheRangeFilter.h | 42 +++---- src/core/include/_FieldCacheSanityChecker.h | 4 +- src/core/include/_FieldCacheTermsFilter.h | 4 +- src/core/include/_FilterManager.h | 4 +- src/core/include/_FilteredDocIdSet.h | 2 +- src/core/include/_FilteredQuery.h | 8 +- src/core/include/_FuzzyQuery.h | 2 +- src/core/include/_IndexReader.h | 2 +- src/core/include/_IndexWriter.h | 20 ++-- src/core/include/_IntFieldSource.h | 2 +- src/core/include/_MMapDirectory.h | 2 +- src/core/include/_MatchAllDocsQuery.h | 8 +- src/core/include/_MultiPhraseQuery.h | 6 +- src/core/include/_MultiSearcher.h | 30 ++--- src/core/include/_MultiTermQuery.h | 6 +- src/core/include/_NearSpansUnordered.h | 2 +- src/core/include/_NumericRangeQuery.h | 6 +- src/core/include/_OrdFieldSource.h | 2 +- src/core/include/_ParallelReader.h | 18 +-- src/core/include/_PayloadTermQuery.h | 8 +- src/core/include/_PhraseQuery.h | 6 +- src/core/include/_QueryWrapperFilter.h | 2 +- src/core/include/_ReverseOrdFieldSource.h | 2 +- src/core/include/_ScorerDocQueue.h | 4 +- src/core/include/_SegmentInfos.h | 10 +- src/core/include/_SegmentReader.h | 14 +-- src/core/include/_SimpleFSDirectory.h | 2 +- src/core/include/_SnapshotDeletionPolicy.h | 2 +- src/core/include/_SortedVIntList.h | 2 +- src/core/include/_SpanFirstQuery.h | 2 +- src/core/include/_SpanNotQuery.h | 2 +- src/core/include/_SpanOrQuery.h | 2 +- src/core/include/_TermQuery.h | 6 +- src/core/include/_TopFieldCollector.h | 42 +++---- src/core/include/_ValueSourceQuery.h | 8 +- src/core/index/AbstractAllTermDocs.cpp | 4 +- src/core/index/AllTermDocs.cpp | 2 +- src/core/index/BufferedDeletes.cpp | 4 +- src/core/index/ByteBlockPool.cpp | 2 +- src/core/index/ByteSliceReader.cpp | 4 +- src/core/index/ByteSliceWriter.cpp | 2 +- src/core/index/CharBlockPool.cpp | 2 +- src/core/index/CheckIndex.cpp | 18 +-- src/core/index/CompoundFileReader.cpp | 12 +- src/core/index/CompoundFileWriter.cpp | 4 +- src/core/index/ConcurrentMergeScheduler.cpp | 10 +- src/core/index/DefaultSkipListReader.cpp | 4 +- src/core/index/DefaultSkipListWriter.cpp | 8 +- src/core/index/DirectoryReader.cpp | 54 ++++----- src/core/index/DocFieldConsumer.cpp | 2 +- src/core/index/DocFieldConsumers.cpp | 14 +-- src/core/index/DocFieldConsumersPerField.cpp | 2 +- src/core/index/DocFieldConsumersPerThread.cpp | 8 +- src/core/index/DocFieldProcessor.cpp | 8 +- src/core/index/DocFieldProcessorPerField.cpp | 2 +- src/core/index/DocFieldProcessorPerThread.cpp | 8 +- src/core/index/DocInverter.cpp | 10 +- src/core/index/DocInverterPerField.cpp | 2 +- src/core/index/DocInverterPerThread.cpp | 4 +- src/core/index/DocumentsWriter.cpp | 71 ++++++------ src/core/index/DocumentsWriterThreadState.cpp | 2 +- src/core/index/FieldInfo.cpp | 2 +- src/core/index/FieldInfos.cpp | 12 +- src/core/index/FieldsReader.cpp | 26 ++--- src/core/index/FieldsWriter.cpp | 14 +-- src/core/index/FilterIndexReader.cpp | 24 ++-- src/core/index/FormatPostingsDocsWriter.cpp | 4 +- src/core/index/FormatPostingsFieldsWriter.cpp | 4 +- .../index/FormatPostingsPositionsWriter.cpp | 4 +- src/core/index/FormatPostingsTermsWriter.cpp | 4 +- src/core/index/FreqProxFieldMergeState.cpp | 2 +- src/core/index/FreqProxTermsWriter.cpp | 8 +- .../index/FreqProxTermsWriterPerField.cpp | 12 +- .../index/FreqProxTermsWriterPerThread.cpp | 4 +- src/core/index/IndexCommit.cpp | 2 +- src/core/index/IndexFileDeleter.cpp | 14 +-- src/core/index/IndexReader.cpp | 40 +++---- src/core/index/IndexWriter.cpp | 107 +++++++++--------- src/core/index/IntBlockPool.cpp | 2 +- src/core/index/InvertedDocConsumer.cpp | 2 +- src/core/index/LogByteSizeMergePolicy.cpp | 4 +- src/core/index/LogDocMergePolicy.cpp | 4 +- src/core/index/LogMergePolicy.cpp | 22 ++-- src/core/index/MergeDocIDRemapper.cpp | 2 +- src/core/index/MergePolicy.cpp | 12 +- src/core/index/MultiLevelSkipListReader.cpp | 4 +- src/core/index/MultiLevelSkipListWriter.cpp | 2 +- src/core/index/MultiReader.cpp | 12 +- src/core/index/MultipleTermPositions.cpp | 6 +- src/core/index/NormsWriter.cpp | 8 +- src/core/index/NormsWriterPerField.cpp | 4 +- src/core/index/NormsWriterPerThread.cpp | 4 +- src/core/index/ParallelReader.cpp | 38 +++---- src/core/index/Payload.cpp | 4 +- .../index/PositionBasedTermVectorMapper.cpp | 2 +- src/core/index/ReadOnlyDirectoryReader.cpp | 8 +- src/core/index/SegmentInfo.cpp | 18 +-- src/core/index/SegmentInfoCollection.cpp | 14 +-- src/core/index/SegmentInfos.cpp | 42 +++---- src/core/index/SegmentMergeInfo.cpp | 2 +- src/core/index/SegmentMerger.cpp | 22 ++-- src/core/index/SegmentReader.cpp | 52 ++++----- src/core/index/SegmentTermDocs.cpp | 10 +- src/core/index/SegmentTermEnum.cpp | 10 +- src/core/index/SegmentTermPositions.cpp | 4 +- src/core/index/SegmentWriteState.cpp | 2 +- src/core/index/SerialMergeScheduler.cpp | 2 +- src/core/index/SnapshotDeletionPolicy.cpp | 4 +- src/core/index/StoredFieldsWriter.cpp | 14 +-- .../index/StoredFieldsWriterPerThread.cpp | 4 +- src/core/index/Term.cpp | 4 +- src/core/index/TermBuffer.cpp | 10 +- src/core/index/TermDocs.cpp | 4 +- src/core/index/TermInfo.cpp | 4 +- src/core/index/TermInfosReader.cpp | 14 +-- src/core/index/TermInfosWriter.cpp | 10 +- src/core/index/TermVectorEntry.cpp | 2 +- src/core/index/TermVectorOffsetInfo.cpp | 2 +- src/core/index/TermVectorsReader.cpp | 18 +-- src/core/index/TermVectorsTermsWriter.cpp | 14 +-- .../index/TermVectorsTermsWriterPerField.cpp | 8 +- .../index/TermVectorsTermsWriterPerThread.cpp | 6 +- src/core/index/TermVectorsWriter.cpp | 4 +- src/core/index/TermsHash.cpp | 14 +-- src/core/index/TermsHashConsumer.cpp | 2 +- src/core/index/TermsHashPerField.cpp | 6 +- src/core/index/TermsHashPerThread.cpp | 4 +- src/core/queryparser/FastCharStream.cpp | 2 +- .../queryparser/MultiFieldQueryParser.cpp | 12 +- src/core/queryparser/QueryParseError.cpp | 2 +- src/core/queryparser/QueryParser.cpp | 28 ++--- .../queryparser/QueryParserTokenManager.cpp | 10 +- src/core/search/BooleanClause.cpp | 6 +- src/core/search/BooleanQuery.cpp | 22 ++-- src/core/search/BooleanScorer.cpp | 14 +-- src/core/search/BooleanScorer2.cpp | 18 +-- src/core/search/CachingSpanFilter.cpp | 12 +- src/core/search/CachingWrapperFilter.cpp | 16 +-- src/core/search/ConjunctionScorer.cpp | 2 +- src/core/search/ConstantScoreQuery.cpp | 18 +-- src/core/search/DefaultSimilarity.cpp | 2 +- src/core/search/DisjunctionMaxQuery.cpp | 16 +-- src/core/search/DisjunctionMaxScorer.cpp | 2 +- src/core/search/DisjunctionSumScorer.cpp | 4 +- src/core/search/ExactPhraseScorer.cpp | 2 +- src/core/search/Explanation.cpp | 2 +- src/core/search/FieldCache.cpp | 22 ++-- src/core/search/FieldCacheImpl.cpp | 60 +++++----- src/core/search/FieldCacheRangeFilter.cpp | 42 +++---- src/core/search/FieldCacheTermsFilter.cpp | 6 +- src/core/search/FieldComparator.cpp | 30 ++--- src/core/search/FieldValueHitQueue.cpp | 2 +- src/core/search/FilterManager.cpp | 6 +- src/core/search/FilteredDocIdSet.cpp | 4 +- src/core/search/FilteredDocIdSetIterator.cpp | 2 +- src/core/search/FilteredQuery.cpp | 18 +-- src/core/search/FilteredTermEnum.cpp | 2 +- src/core/search/FuzzyQuery.cpp | 20 ++-- src/core/search/FuzzyTermEnum.cpp | 10 +- src/core/search/HitQueueBase.cpp | 6 +- src/core/search/IndexSearcher.cpp | 28 ++--- src/core/search/MatchAllDocsQuery.cpp | 14 +-- src/core/search/MultiPhraseQuery.cpp | 16 +-- src/core/search/MultiSearcher.cpp | 48 ++++---- src/core/search/MultiTermQuery.cpp | 18 +-- .../search/MultiTermQueryWrapperFilter.cpp | 6 +- src/core/search/NumericRangeFilter.cpp | 2 +- src/core/search/NumericRangeQuery.cpp | 12 +- src/core/search/ParallelMultiSearcher.cpp | 6 +- src/core/search/PhrasePositions.cpp | 2 +- src/core/search/PhraseQuery.cpp | 16 +-- src/core/search/PhraseScorer.cpp | 2 +- .../search/PositiveScoresOnlyCollector.cpp | 6 +- src/core/search/PrefixFilter.cpp | 2 +- src/core/search/PrefixQuery.cpp | 8 +- src/core/search/PrefixTermEnum.cpp | 4 +- src/core/search/Query.cpp | 12 +- src/core/search/QueryTermVector.cpp | 2 +- src/core/search/QueryWrapperFilter.cpp | 8 +- src/core/search/ReqExclScorer.cpp | 2 +- src/core/search/ReqOptSumScorer.cpp | 2 +- .../search/ScoreCachingWrappingScorer.cpp | 6 +- src/core/search/Scorer.cpp | 6 +- src/core/search/Searchable.cpp | 14 +-- src/core/search/Searcher.cpp | 16 +-- src/core/search/Similarity.cpp | 6 +- src/core/search/SimilarityDelegator.cpp | 4 +- src/core/search/SingleTermEnum.cpp | 4 +- src/core/search/SloppyPhraseScorer.cpp | 6 +- src/core/search/Sort.cpp | 6 +- src/core/search/SortField.cpp | 6 +- src/core/search/SpanFilterResult.cpp | 2 +- src/core/search/SpanQueryFilter.cpp | 8 +- src/core/search/TermQuery.cpp | 14 +-- src/core/search/TermRangeQuery.cpp | 6 +- src/core/search/TermRangeTermEnum.cpp | 6 +- src/core/search/TermScorer.cpp | 6 +- src/core/search/TimeLimitingCollector.cpp | 6 +- src/core/search/TopDocsCollector.cpp | 2 +- src/core/search/TopFieldCollector.cpp | 46 ++++---- src/core/search/TopScoreDocCollector.cpp | 4 +- src/core/search/WildcardQuery.cpp | 10 +- src/core/search/WildcardTermEnum.cpp | 4 +- src/core/search/function/ByteFieldSource.cpp | 8 +- .../search/function/CustomScoreProvider.cpp | 6 +- src/core/search/function/CustomScoreQuery.cpp | 38 +++---- .../search/function/DoubleFieldSource.cpp | 8 +- src/core/search/function/FieldCacheSource.cpp | 4 +- src/core/search/function/IntFieldSource.cpp | 8 +- src/core/search/function/OrdFieldSource.cpp | 6 +- .../search/function/ReverseOrdFieldSource.cpp | 6 +- src/core/search/function/ValueSourceQuery.cpp | 18 +-- .../payloads/AveragePayloadFunction.cpp | 2 +- .../search/payloads/MaxPayloadFunction.cpp | 4 +- .../search/payloads/MinPayloadFunction.cpp | 4 +- src/core/search/payloads/PayloadNearQuery.cpp | 14 +-- src/core/search/payloads/PayloadSpanUtil.cpp | 8 +- src/core/search/payloads/PayloadTermQuery.cpp | 16 +-- .../search/spans/FieldMaskingSpanQuery.cpp | 14 +-- src/core/search/spans/NearSpansOrdered.cpp | 4 +- src/core/search/spans/NearSpansUnordered.cpp | 6 +- src/core/search/spans/SpanFirstQuery.cpp | 12 +- src/core/search/spans/SpanNearQuery.cpp | 8 +- src/core/search/spans/SpanNotQuery.cpp | 12 +- src/core/search/spans/SpanOrQuery.cpp | 10 +- src/core/search/spans/SpanQuery.cpp | 2 +- src/core/search/spans/SpanScorer.cpp | 2 +- src/core/search/spans/SpanTermQuery.cpp | 8 +- src/core/search/spans/SpanWeight.cpp | 6 +- src/core/search/spans/TermSpans.cpp | 2 +- src/core/store/BufferedIndexInput.cpp | 2 +- src/core/store/ChecksumIndexInput.cpp | 4 +- src/core/store/ChecksumIndexOutput.cpp | 2 +- src/core/store/Directory.cpp | 4 +- src/core/store/FSDirectory.cpp | 14 ++- src/core/store/FileSwitchDirectory.cpp | 2 +- src/core/store/IndexInput.cpp | 2 +- src/core/store/IndexOutput.cpp | 2 +- src/core/store/MMapDirectory.cpp | 4 +- src/core/store/RAMDirectory.cpp | 4 +- src/core/store/RAMFile.cpp | 2 +- src/core/store/RAMInputStream.cpp | 4 +- src/core/store/RAMOutputStream.cpp | 4 +- src/core/store/SimpleFSDirectory.cpp | 4 +- src/core/util/Attribute.cpp | 4 +- src/core/util/AttributeSource.cpp | 23 ++-- src/core/util/BitSet.cpp | 14 +-- src/core/util/BitVector.cpp | 14 +-- src/core/util/BufferedReader.cpp | 2 +- src/core/util/DocIdBitSet.cpp | 8 +- src/core/util/FieldCacheSanityChecker.cpp | 8 +- src/core/util/InputStreamReader.cpp | 2 +- src/core/util/LuceneObject.cpp | 6 +- src/core/util/LuceneSignal.cpp | 4 +- src/core/util/MiscUtils.cpp | 2 +- src/core/util/NumericUtils.cpp | 8 +- src/core/util/OpenBitSet.cpp | 28 ++--- src/core/util/OpenBitSetDISI.cpp | 10 +- src/core/util/OpenBitSetIterator.cpp | 2 +- src/core/util/ReaderUtil.cpp | 6 +- src/core/util/ScorerDocQueue.cpp | 8 +- src/core/util/SortedVIntList.cpp | 8 +- src/core/util/StringUtils.cpp | 4 +- src/core/util/Synchronize.cpp | 2 +- src/core/util/UTF8Stream.cpp | 4 +- src/demo/indexfiles/main.cpp | 2 +- src/demo/searchfiles/main.cpp | 10 +- src/test/analysis/AnalyzersTest.cpp | 4 +- src/test/analysis/BaseTokenStreamFixture.cpp | 50 ++++---- src/test/analysis/CachingTokenFilterTest.cpp | 2 +- src/test/analysis/CharFilterTest.cpp | 4 +- src/test/analysis/StopFilterTest.cpp | 2 +- src/test/analysis/TeeSinkTokenFilterTest.cpp | 8 +- src/test/analysis/TokenTest.cpp | 4 +- .../tokenattributes/SimpleAttributeTest.cpp | 4 +- .../tokenattributes/TermAttributeTest.cpp | 4 +- .../analysis/br/BrazilianStemmerTest.cpp | 2 +- .../common/analysis/cjk/CJKTokenizerTest.cpp | 2 +- .../analysis/cn/ChineseTokenizerTest.cpp | 4 +- .../analysis/de/GermanStemFilterTest.cpp | 2 +- .../common/analysis/fr/ElisionTest.cpp | 2 +- .../common/analysis/nl/DutchStemmerTest.cpp | 2 +- .../contrib/highlighter/HighlighterTest.cpp | 26 ++--- src/test/contrib/memory/MemoryIndexTest.cpp | 2 +- src/test/document/DocumentTest.cpp | 2 +- src/test/include/BaseTestRangeFilterFixture.h | 2 +- src/test/include/BaseTokenStreamFixture.h | 54 ++++----- src/test/include/CheckHits.h | 14 +-- src/test/include/DocHelper.h | 8 +- src/test/include/ExplanationsFixture.h | 18 +-- src/test/include/FunctionFixture.h | 2 +- src/test/include/MockFilter.h | 2 +- src/test/include/MockRAMDirectory.h | 6 +- src/test/include/MockRAMInputStream.h | 4 +- src/test/include/MockRAMOutputStream.h | 2 +- src/test/include/PayloadHelper.h | 2 +- src/test/include/QueryUtils.h | 22 ++-- src/test/include/TestUtils.h | 6 +- src/test/index/AddIndexesNoOptimizeTest.cpp | 12 +- src/test/index/AtomicUpdateTest.cpp | 8 +- src/test/index/BackwardsCompatibilityTest.cpp | 8 +- src/test/index/CompoundFileTest.cpp | 14 +-- .../index/ConcurrentMergeSchedulerTest.cpp | 14 +-- src/test/index/CrashTest.cpp | 4 +- src/test/index/DeletionPolicyTest.cpp | 4 +- src/test/index/DirectoryReaderTest.cpp | 4 +- src/test/index/DocHelper.cpp | 8 +- src/test/index/DocTest.cpp | 6 +- src/test/index/DocumentWriterTest.cpp | 6 +- src/test/index/FieldsReaderTest.cpp | 4 +- src/test/index/FilterIndexReaderTest.cpp | 6 +- src/test/index/IndexCommitTest.cpp | 4 +- src/test/index/IndexFileDeleterTest.cpp | 4 +- src/test/index/IndexReaderCloneNormsTest.cpp | 16 +-- src/test/index/IndexReaderCloneTest.cpp | 14 +-- src/test/index/IndexReaderReopenTest.cpp | 42 +++---- src/test/index/IndexReaderTest.cpp | 10 +- src/test/index/IndexWriterDeleteTest.cpp | 12 +- src/test/index/IndexWriterExceptionsTest.cpp | 4 +- src/test/index/IndexWriterMergePolicyTest.cpp | 4 +- src/test/index/IndexWriterMergingTest.cpp | 4 +- src/test/index/IndexWriterReaderTest.cpp | 18 +-- src/test/index/IndexWriterTest.cpp | 62 +++++----- src/test/index/LazyProxSkippingTest.cpp | 4 +- src/test/index/MultiLevelSkipListTest.cpp | 12 +- src/test/index/MultiReaderTest.cpp | 4 +- src/test/index/NRTReaderWithThreadsTest.cpp | 4 +- src/test/index/NormsTest.cpp | 10 +- src/test/index/OmitTfTest.cpp | 16 +-- src/test/index/ParallelReaderTest.cpp | 2 +- src/test/index/PayloadsTest.cpp | 10 +- src/test/index/SegmentMergerTest.cpp | 2 +- src/test/index/SegmentTermDocsTest.cpp | 2 +- src/test/index/SegmentTermEnumTest.cpp | 4 +- src/test/index/SnapshotDeletionPolicyTest.cpp | 12 +- src/test/index/StressIndexingTest.cpp | 30 ++--- src/test/index/TermDocsPerfTest.cpp | 6 +- src/test/index/TermVectorsReaderTest.cpp | 4 +- src/test/index/ThreadedOptimizeTest.cpp | 4 +- src/test/index/TransactionRollbackTest.cpp | 2 +- src/test/index/TransactionsTest.cpp | 10 +- src/test/queryparser/MultiAnalyzerTest.cpp | 12 +- .../queryparser/MultiFieldQueryParserTest.cpp | 6 +- src/test/queryparser/QueryParserTest.cpp | 40 +++---- .../search/BaseTestRangeFilterFixture.cpp | 2 +- src/test/search/Boolean2Test.cpp | 2 +- src/test/search/BooleanMinShouldMatchTest.cpp | 6 +- src/test/search/BooleanOrTest.cpp | 2 +- src/test/search/BooleanPrefixQueryTest.cpp | 2 +- src/test/search/BooleanScorerTest.cpp | 2 +- src/test/search/CachingSpanFilterTest.cpp | 11 +- src/test/search/CachingWrapperFilterTest.cpp | 19 ++-- src/test/search/CheckHits.cpp | 24 ++-- .../ComplexExplanationsOfNonMatchesTest.cpp | 2 +- src/test/search/CustomSearcherSortTest.cpp | 10 +- src/test/search/DocBoostTest.cpp | 4 +- src/test/search/DocIdSetTest.cpp | 4 +- src/test/search/ElevationComparatorTest.cpp | 4 +- src/test/search/ExplanationsFixture.cpp | 18 +-- src/test/search/FilteredQueryTest.cpp | 8 +- src/test/search/FilteredSearchTest.cpp | 4 +- src/test/search/FuzzyQueryTest.cpp | 2 +- src/test/search/MatchAllDocsQueryTest.cpp | 2 +- src/test/search/MockFilter.cpp | 2 +- src/test/search/MultiPhraseQueryTest.cpp | 4 +- src/test/search/MultiSearcherRankingTest.cpp | 6 +- src/test/search/MultiSearcherTest.cpp | 2 +- .../search/MultiTermConstantScoreTest.cpp | 12 +- .../search/MultiThreadTermVectorsTest.cpp | 4 +- src/test/search/ParallelMultiSearcherTest.cpp | 2 +- src/test/search/PhraseQueryTest.cpp | 2 +- src/test/search/PositionIncrementTest.cpp | 8 +- src/test/search/QueryUtils.cpp | 36 +++--- .../search/ScoreCachingWrappingScorerTest.cpp | 4 +- src/test/search/ScorerPerfTest.cpp | 21 ++-- src/test/search/SearchForDuplicatesTest.cpp | 4 +- src/test/search/SetNormTest.cpp | 4 +- src/test/search/SimilarityTest.cpp | 14 +-- .../SimpleExplanationsOfNonMatchesTest.cpp | 2 +- src/test/search/SloppyPhraseQueryTest.cpp | 2 +- src/test/search/SortTest.cpp | 12 +- src/test/search/SpanQueryFilterTest.cpp | 4 +- src/test/search/TermRangeQueryTest.cpp | 12 +- src/test/search/TermScorerTest.cpp | 4 +- src/test/search/TermVectorsTest.cpp | 2 +- src/test/search/ThreadSafeTest.cpp | 8 +- src/test/search/TimeLimitingCollectorTest.cpp | 10 +- src/test/search/TopDocsCollectorTest.cpp | 4 +- src/test/search/WildcardTest.cpp | 2 +- .../search/function/CustomScoreQueryTest.cpp | 24 ++-- src/test/search/function/FunctionFixture.cpp | 2 +- src/test/search/payloads/PayloadHelper.cpp | 6 +- .../search/payloads/PayloadNearQueryTest.cpp | 6 +- .../search/payloads/PayloadTermQueryTest.cpp | 4 +- src/test/search/spans/BasicSpansTest.cpp | 4 +- .../spans/FieldMaskingSpanQueryTest.cpp | 8 +- .../search/spans/NearSpansOrderedTest.cpp | 2 +- src/test/search/spans/PayloadSpansTest.cpp | 8 +- src/test/search/spans/SpansAdvanced2Test.cpp | 4 +- src/test/search/spans/SpansAdvancedTest.cpp | 4 +- src/test/search/spans/SpansTest.cpp | 14 +-- src/test/store/BufferedIndexInputTest.cpp | 6 +- src/test/store/DirectoryTest.cpp | 2 +- src/test/store/FileSwitchDirectoryTest.cpp | 2 +- src/test/store/LockFactoryTest.cpp | 8 +- src/test/store/MockRAMDirectory.cpp | 6 +- src/test/store/MockRAMInputStream.cpp | 4 +- src/test/store/MockRAMOutputStream.cpp | 2 +- src/test/store/RAMDirectoryTest.cpp | 2 +- src/test/util/BitVectorTest.cpp | 2 +- src/test/util/NumericUtilsTest.cpp | 4 +- src/test/util/OpenBitSetTest.cpp | 10 +- src/test/util/SortedVIntListTest.cpp | 4 +- src/test/util/TestUtils.cpp | 6 +- 853 files changed, 3543 insertions(+), 3531 deletions(-) diff --git a/include/ASCIIFoldingFilter.h b/include/ASCIIFoldingFilter.h index 109449dd..b8087c0d 100644 --- a/include/ASCIIFoldingFilter.h +++ b/include/ASCIIFoldingFilter.h @@ -42,7 +42,7 @@ namespace Lucene class LPPAPI ASCIIFoldingFilter : public TokenFilter { public: - ASCIIFoldingFilter(TokenStreamPtr input); + ASCIIFoldingFilter(const TokenStreamPtr& input); virtual ~ASCIIFoldingFilter(); LUCENE_CLASS(ASCIIFoldingFilter); diff --git a/include/AbstractAllTermDocs.h b/include/AbstractAllTermDocs.h index b1c672ac..b199c4e2 100644 --- a/include/AbstractAllTermDocs.h +++ b/include/AbstractAllTermDocs.h @@ -28,8 +28,8 @@ namespace Lucene int32_t _doc; public: - virtual void seek(TermPtr term); - virtual void seek(TermEnumPtr termEnum); + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); virtual int32_t doc(); virtual int32_t freq(); virtual bool next(); diff --git a/include/AllTermDocs.h b/include/AllTermDocs.h index d34ef9b3..1005a93a 100644 --- a/include/AllTermDocs.h +++ b/include/AllTermDocs.h @@ -14,7 +14,7 @@ namespace Lucene class AllTermDocs : public AbstractAllTermDocs { public: - AllTermDocs(SegmentReaderPtr parent); + AllTermDocs(const SegmentReaderPtr& parent); virtual ~AllTermDocs(); LUCENE_CLASS(AllTermDocs); diff --git a/include/Analyzer.h b/include/Analyzer.h index 909fdf2a..8a07e93d 100644 --- a/include/Analyzer.h +++ b/include/Analyzer.h @@ -28,12 +28,12 @@ namespace Lucene public: /// Creates a TokenStream which tokenizes all the text in the provided Reader. Must be able to handle null /// field name for backward compatibility. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) = 0; + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) = 0; /// Creates a TokenStream that is allowed to be re-used from the previous time that the same thread called /// this method. Callers that do not need to use more than one TokenStream at the same time from this analyzer /// should use this method for better performance. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); /// Invoked before indexing a Fieldable instance if terms have already been added to that field. This allows /// custom analyzers to place an automatic position increment gap between Fieldable instances using the same @@ -51,7 +51,7 @@ namespace Lucene /// /// @param field the field just indexed /// @return offset gap, added to the next token emitted from {@link #tokenStream(String,Reader)} - virtual int32_t getOffsetGap(FieldablePtr field); + virtual int32_t getOffsetGap(const FieldablePtr& field); /// Frees persistent resources used by this Analyzer virtual void close(); @@ -63,7 +63,7 @@ namespace Lucene /// Used by Analyzers that implement reusableTokenStream to save a TokenStream for later re-use by the /// same thread. - virtual void setPreviousTokenStream(LuceneObjectPtr stream); + virtual void setPreviousTokenStream(const LuceneObjectPtr& stream); }; } diff --git a/include/Attribute.h b/include/Attribute.h index 03eb626d..9127335a 100644 --- a/include/Attribute.h +++ b/include/Attribute.h @@ -41,15 +41,15 @@ namespace Lucene /// All values used for computation of {@link #hashCode()} should be checked here for equality. /// /// see also {@link LuceneObject#equals(Object)} - virtual bool equals(LuceneObjectPtr other) = 0; + virtual bool equals(const LuceneObjectPtr& other) = 0; /// Copies the values from this Attribute into the passed-in target attribute. The target implementation /// must support all the Attributes this implementation supports. - virtual void copyTo(AttributePtr target) = 0; + virtual void copyTo(const AttributePtr& target) = 0; /// Shallow clone. Subclasses must override this if they need to clone any members deeply. /// @param base clone reference - null when called initially, then set in top virtual override. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) = 0; + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) = 0; }; } diff --git a/include/AttributeSource.h b/include/AttributeSource.h index 2257053f..bae4dcbe 100644 --- a/include/AttributeSource.h +++ b/include/AttributeSource.h @@ -49,11 +49,11 @@ namespace Lucene AttributeSource(); /// An AttributeSource that uses the same attributes as the supplied one. - AttributeSource(AttributeSourcePtr input); + AttributeSource(const AttributeSourcePtr& input); /// An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} /// instances. - AttributeSource(AttributeFactoryPtr factory); + AttributeSource(const AttributeFactoryPtr& factory); virtual ~AttributeSource(); @@ -86,7 +86,7 @@ namespace Lucene } /// Adds a custom Attribute instance. - void addAttribute(const String& className, AttributePtr attrImpl); + void addAttribute(const String& className, const AttributePtr& attrImpl); /// Returns true if this AttributeSource has any attributes. bool hasAttributes(); @@ -126,13 +126,13 @@ namespace Lucene /// In other words, if for example the targetStream contains an OffsetAttribute, but this state doesn't, then /// the value of the OffsetAttribute remains unchanged. It might be desirable to reset its value to the default, /// in which case the caller should first call {@link TokenStream#clearAttributes()} on the targetStream. - void restoreState(AttributeSourceStatePtr state); + void restoreState(const AttributeSourceStatePtr& state); /// Return hash code for this object. virtual int32_t hashCode(); /// Return whether two objects are equal - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); /// Returns a string representation of the object virtual String toString(); @@ -183,7 +183,7 @@ namespace Lucene AttributeSourceStatePtr next; public: - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); friend class AttributeSource; }; diff --git a/include/AveragePayloadFunction.h b/include/AveragePayloadFunction.h index a5e80705..850ed9c3 100644 --- a/include/AveragePayloadFunction.h +++ b/include/AveragePayloadFunction.h @@ -25,7 +25,7 @@ namespace Lucene double currentScore, double currentPayloadScore); virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); }; } diff --git a/include/BaseCharFilter.h b/include/BaseCharFilter.h index bd50179b..783f970c 100644 --- a/include/BaseCharFilter.h +++ b/include/BaseCharFilter.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI BaseCharFilter : public CharFilter { public: - BaseCharFilter(CharStreamPtr in); + BaseCharFilter(const CharStreamPtr& in); virtual ~BaseCharFilter(); LUCENE_CLASS(BaseCharFilter); diff --git a/include/BitSet.h b/include/BitSet.h index 2e565f5c..cf039a08 100644 --- a/include/BitSet.h +++ b/include/BitSet.h @@ -49,17 +49,17 @@ namespace Lucene bool get(uint32_t bitIndex) const; bool fastGet(uint32_t bitIndex) const; int32_t nextSetBit(uint32_t fromIndex) const; - void _and(BitSetPtr set); - void _or(BitSetPtr set); - void _xor(BitSetPtr set); - void andNot(BitSetPtr set); - bool intersectsBitSet(BitSetPtr set) const; + void _and(const BitSetPtr& set); + void _or(const BitSetPtr& set); + void _xor(const BitSetPtr& set); + void andNot(const BitSetPtr& set); + bool intersectsBitSet(const BitSetPtr& set) const; uint32_t cardinality(); void resize(uint32_t size); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/BitVector.h b/include/BitVector.h index 4e724c4c..ddaa2295 100644 --- a/include/BitVector.h +++ b/include/BitVector.h @@ -22,7 +22,7 @@ namespace Lucene /// Constructs a bit vector from the file name in Directory d, /// as written by the {@link #write} method. - BitVector(DirectoryPtr d, const String& name); + BitVector(const DirectoryPtr& d, const String& name); virtual ~BitVector(); @@ -37,7 +37,7 @@ namespace Lucene public: /// Clone this vector - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Sets the value of bit to one. void set(int32_t bit); @@ -65,7 +65,7 @@ namespace Lucene /// Writes this vector to the file name in Directory d, in a format that can /// be read by the constructor {@link #BitVector(DirectoryPtr, const String&)}. - void write(DirectoryPtr d, const String& name); + void write(const DirectoryPtr& d, const String& name); /// Retrieve a subset of this BitVector. /// @param start starting index, inclusive @@ -75,20 +75,20 @@ namespace Lucene protected: /// Write as a bit set. - void writeBits(IndexOutputPtr output); + void writeBits(const IndexOutputPtr& output); /// Write as a d-gaps list. - void writeDgaps(IndexOutputPtr output); + void writeDgaps(const IndexOutputPtr& output); /// Indicates if the bit vector is sparse and should be saved as a d-gaps list, /// or dense, and should be saved as a bit set. bool isSparse(); /// Read as a bit set. - void readBits(IndexInputPtr input); + void readBits(const IndexInputPtr& input); /// Read as a d-gaps list. - void readDgaps(IndexInputPtr input); + void readDgaps(const IndexInputPtr& input); }; } diff --git a/include/BooleanClause.h b/include/BooleanClause.h index 5a16b7e7..8118f4b8 100644 --- a/include/BooleanClause.h +++ b/include/BooleanClause.h @@ -32,7 +32,7 @@ namespace Lucene }; public: - BooleanClause(QueryPtr query, Occur occur); + BooleanClause(const QueryPtr& query, Occur occur); virtual ~BooleanClause(); LUCENE_CLASS(BooleanClause); @@ -47,12 +47,12 @@ namespace Lucene void setOccur(Occur occur); QueryPtr getQuery(); - void setQuery(QueryPtr query); + void setQuery(const QueryPtr& query); bool isProhibited(); bool isRequired(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); virtual String toString(); }; diff --git a/include/BooleanQuery.h b/include/BooleanQuery.h index 8938a6f0..09d2ca44 100644 --- a/include/BooleanQuery.h +++ b/include/BooleanQuery.h @@ -53,7 +53,7 @@ namespace Lucene bool isCoordDisabled(); /// Implement coord disabling. - virtual SimilarityPtr getSimilarity(SearcherPtr searcher); + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); /// Specifies a minimum number of the optional BooleanClauses which must be satisfied. /// @@ -71,11 +71,11 @@ namespace Lucene /// Adds a clause to a boolean query. /// @see #getMaxClauseCount() - void add(QueryPtr query, BooleanClause::Occur occur); + void add(const QueryPtr& query, BooleanClause::Occur occur); /// Adds a clause to a boolean query. /// @see #getMaxClauseCount() - void add(BooleanClausePtr clause); + void add(const BooleanClausePtr& clause); /// Returns the set of clauses in this query. Collection getClauses(); @@ -84,15 +84,15 @@ namespace Lucene Collection::iterator begin(); Collection::iterator end(); - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); virtual void extractTerms(SetTerm terms); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); friend class BooleanWeight; diff --git a/include/BooleanScorer.h b/include/BooleanScorer.h index 98ac5086..b8ff1397 100644 --- a/include/BooleanScorer.h +++ b/include/BooleanScorer.h @@ -30,7 +30,7 @@ namespace Lucene class BooleanScorer : public Scorer { public: - BooleanScorer(SimilarityPtr similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers); + BooleanScorer(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers); virtual ~BooleanScorer(); LUCENE_CLASS(BooleanScorer); @@ -50,21 +50,21 @@ namespace Lucene protected: // firstDocID is ignored since nextDoc() initializes 'current' - virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); public: virtual int32_t advance(int32_t target); virtual int32_t docID(); virtual int32_t nextDoc(); virtual double score(); - virtual void score(CollectorPtr collector); + virtual void score(const CollectorPtr& collector); virtual String toString(); }; class BooleanScorerCollector : public Collector { public: - BooleanScorerCollector(int32_t mask, BucketTablePtr bucketTable); + BooleanScorerCollector(int32_t mask, const BucketTablePtr& bucketTable); virtual ~BooleanScorerCollector(); LUCENE_CLASS(BooleanScorerCollector); @@ -76,8 +76,8 @@ namespace Lucene public: virtual void collect(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setScorer(ScorerPtr scorer); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); virtual bool acceptsDocsOutOfOrder(); }; @@ -143,7 +143,7 @@ namespace Lucene class SubScorer : public LuceneObject { public: - SubScorer(ScorerPtr scorer, bool required, bool prohibited, CollectorPtr collector, SubScorerPtr next); + SubScorer(const ScorerPtr& scorer, bool required, bool prohibited, const CollectorPtr& collector, const SubScorerPtr& next); virtual ~SubScorer(); LUCENE_CLASS(SubScorer); diff --git a/include/BooleanScorer2.h b/include/BooleanScorer2.h index 24477b4b..9993b21e 100644 --- a/include/BooleanScorer2.h +++ b/include/BooleanScorer2.h @@ -31,7 +31,7 @@ namespace Lucene /// @param required The list of required scorers. /// @param prohibited The list of prohibited scorers. /// @param optional The list of optional scorers. - BooleanScorer2(SimilarityPtr similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional); + BooleanScorer2(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional); virtual ~BooleanScorer2(); @@ -55,9 +55,9 @@ namespace Lucene /// Scores and collects all matching documents. /// @param collector The collector to which all matching documents are passed through. - virtual void score(CollectorPtr collector); + virtual void score(const CollectorPtr& collector); - virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); virtual int32_t docID(); virtual int32_t nextDoc(); virtual double score(); @@ -66,7 +66,7 @@ namespace Lucene protected: ScorerPtr countingDisjunctionSumScorer(Collection scorers, int32_t minNrShouldMatch); ScorerPtr countingConjunctionSumScorer(Collection requiredScorers); - ScorerPtr dualConjunctionSumScorer(ScorerPtr req1, ScorerPtr req2); + ScorerPtr dualConjunctionSumScorer(const ScorerPtr& req1, const ScorerPtr& req2); /// Returns the scorer to be used for match counting and score summing. Uses requiredScorers, optionalScorers /// and prohibitedScorers. @@ -77,7 +77,7 @@ namespace Lucene /// Returns the scorer to be used for match counting and score summing. Uses the given required scorer and /// the prohibitedScorers. /// @param requiredCountingSumScorer A required scorer already built. - ScorerPtr addProhibitedScorers(ScorerPtr requiredCountingSumScorer); + ScorerPtr addProhibitedScorers(const ScorerPtr& requiredCountingSumScorer); friend class CountingDisjunctionSumScorer; friend class CountingConjunctionSumScorer; @@ -86,7 +86,7 @@ namespace Lucene class Coordinator : public LuceneObject { public: - Coordinator(BooleanScorer2Ptr scorer); + Coordinator(const BooleanScorer2Ptr& scorer); virtual ~Coordinator(); LUCENE_CLASS(Coordinator); @@ -107,7 +107,7 @@ namespace Lucene class SingleMatchScorer : public Scorer { public: - SingleMatchScorer(ScorerPtr scorer, CoordinatorPtr coordinator); + SingleMatchScorer(const ScorerPtr& scorer, const CoordinatorPtr& coordinator); virtual ~SingleMatchScorer(); LUCENE_CLASS(SingleMatchScorer); @@ -128,7 +128,7 @@ namespace Lucene class CountingDisjunctionSumScorer : public DisjunctionSumScorer { public: - CountingDisjunctionSumScorer(BooleanScorer2Ptr scorer, Collection subScorers, int32_t minimumNrMatchers); + CountingDisjunctionSumScorer(const BooleanScorer2Ptr& scorer, Collection subScorers, int32_t minimumNrMatchers); virtual ~CountingDisjunctionSumScorer(); LUCENE_CLASS(CountingDisjunctionSumScorer); @@ -149,7 +149,7 @@ namespace Lucene class CountingConjunctionSumScorer : public ConjunctionScorer { public: - CountingConjunctionSumScorer(BooleanScorer2Ptr scorer, SimilarityPtr similarity, Collection scorers); + CountingConjunctionSumScorer(const BooleanScorer2Ptr& scorer, const SimilarityPtr& similarity, Collection scorers); virtual ~CountingConjunctionSumScorer(); LUCENE_CLASS(CountingConjunctionSumScorer); diff --git a/include/BufferedDeletes.h b/include/BufferedDeletes.h index ff75158c..21dba121 100644 --- a/include/BufferedDeletes.h +++ b/include/BufferedDeletes.h @@ -33,11 +33,11 @@ namespace Lucene public: int32_t size(); - void update(BufferedDeletesPtr in); + void update(const BufferedDeletesPtr& in); void clear(); void addBytesUsed(int64_t b); bool any(); - void remap(MergeDocIDRemapperPtr mapper, SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergedDocCount); + void remap(const MergeDocIDRemapperPtr& mapper, const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount); }; /// Number of documents a delete term applies to. diff --git a/include/BufferedIndexInput.h b/include/BufferedIndexInput.h index 125564b3..14ecea4b 100644 --- a/include/BufferedIndexInput.h +++ b/include/BufferedIndexInput.h @@ -76,7 +76,7 @@ namespace Lucene virtual void seek(int64_t pos); /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); protected: virtual void newBuffer(ByteArray newBuffer); diff --git a/include/BufferedReader.h b/include/BufferedReader.h index 04c387d1..9cf22920 100644 --- a/include/BufferedReader.h +++ b/include/BufferedReader.h @@ -17,7 +17,7 @@ namespace Lucene { public: /// Create a buffering character-input stream. - BufferedReader(ReaderPtr reader, int32_t size = READER_BUFFER); + BufferedReader(const ReaderPtr& reader, int32_t size = READER_BUFFER); virtual ~BufferedReader(); LUCENE_CLASS(BufferedReader); diff --git a/include/ByteBlockPool.h b/include/ByteBlockPool.h index c00d0c8c..8a3a981d 100644 --- a/include/ByteBlockPool.h +++ b/include/ByteBlockPool.h @@ -23,7 +23,7 @@ namespace Lucene class ByteBlockPool : public LuceneObject { public: - ByteBlockPool(ByteBlockPoolAllocatorBasePtr allocator, bool trackAllocations); + ByteBlockPool(const ByteBlockPoolAllocatorBasePtr& allocator, bool trackAllocations); virtual ~ByteBlockPool(); LUCENE_CLASS(ByteBlockPool); diff --git a/include/ByteFieldSource.h b/include/ByteFieldSource.h index 7f960f8f..239fd7f7 100644 --- a/include/ByteFieldSource.h +++ b/include/ByteFieldSource.h @@ -25,7 +25,7 @@ namespace Lucene { public: /// Create a cached byte field source with a specific string-to-byte parser. - ByteFieldSource(const String& field, ByteParserPtr parser = ByteParserPtr()); + ByteFieldSource(const String& field, const ByteParserPtr& parser = ByteParserPtr()); virtual ~ByteFieldSource(); LUCENE_CLASS(ByteFieldSource); @@ -35,8 +35,8 @@ namespace Lucene public: virtual String description(); - virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader); - virtual bool cachedFieldSourceEquals(FieldCacheSourcePtr other); + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); virtual int32_t cachedFieldSourceHashCode(); }; } diff --git a/include/ByteSliceReader.h b/include/ByteSliceReader.h index 53cbd457..67edde5e 100644 --- a/include/ByteSliceReader.h +++ b/include/ByteSliceReader.h @@ -32,13 +32,13 @@ namespace Lucene int32_t endIndex; public: - void init(ByteBlockPoolPtr pool, int32_t startIndex, int32_t endIndex); + void init(const ByteBlockPoolPtr& pool, int32_t startIndex, int32_t endIndex); bool eof(); /// Reads and returns a single byte. virtual uint8_t readByte(); - int64_t writeTo(IndexOutputPtr out); + int64_t writeTo(const IndexOutputPtr& out); void nextSlice(); diff --git a/include/ByteSliceWriter.h b/include/ByteSliceWriter.h index 0c93a98b..204e3bd4 100644 --- a/include/ByteSliceWriter.h +++ b/include/ByteSliceWriter.h @@ -16,7 +16,7 @@ namespace Lucene class ByteSliceWriter : public LuceneObject { public: - ByteSliceWriter(ByteBlockPoolPtr pool); + ByteSliceWriter(const ByteBlockPoolPtr& pool); virtual ~ByteSliceWriter(); LUCENE_CLASS(ByteSliceWriter); diff --git a/include/CachingSpanFilter.h b/include/CachingSpanFilter.h index 59f111fb..218c21fe 100644 --- a/include/CachingSpanFilter.h +++ b/include/CachingSpanFilter.h @@ -18,7 +18,7 @@ namespace Lucene { public: /// New deletions always result in a cache miss, by default ({@link CachingWrapperFilter#RECACHE}. - CachingSpanFilter(SpanFilterPtr filter, CachingWrapperFilter::DeletesMode deletesMode = CachingWrapperFilter::DELETES_RECACHE); + CachingSpanFilter(const SpanFilterPtr& filter, CachingWrapperFilter::DeletesMode deletesMode = CachingWrapperFilter::DELETES_RECACHE); virtual ~CachingSpanFilter(); LUCENE_CLASS(CachingSpanFilter); @@ -33,15 +33,15 @@ namespace Lucene int32_t missCount; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); - virtual SpanFilterResultPtr bitSpans(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader); virtual String toString(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); protected: - SpanFilterResultPtr getCachedResult(IndexReaderPtr reader); + SpanFilterResultPtr getCachedResult(const IndexReaderPtr& reader); }; } diff --git a/include/CachingTokenFilter.h b/include/CachingTokenFilter.h index 15c78faa..77cb44db 100644 --- a/include/CachingTokenFilter.h +++ b/include/CachingTokenFilter.h @@ -19,7 +19,7 @@ namespace Lucene class LPPAPI CachingTokenFilter : public TokenFilter { public: - CachingTokenFilter(TokenStreamPtr input); + CachingTokenFilter(const TokenStreamPtr& input); virtual ~CachingTokenFilter(); LUCENE_CLASS(CachingTokenFilter); diff --git a/include/CachingWrapperFilter.h b/include/CachingWrapperFilter.h index 830cf0ee..8183eb34 100644 --- a/include/CachingWrapperFilter.h +++ b/include/CachingWrapperFilter.h @@ -34,7 +34,7 @@ namespace Lucene /// Most of the time this is safe, because the filter will be AND'd with a Query that fully enforces /// deletions. If instead you need this filter to always enforce deletions, pass either {@link /// DeletesMode#RECACHE} or {@link DeletesMode#DYNAMIC}. - CachingWrapperFilter(FilterPtr filter, DeletesMode deletesMode = DELETES_IGNORE); + CachingWrapperFilter(const FilterPtr& filter, DeletesMode deletesMode = DELETES_IGNORE); virtual ~CachingWrapperFilter(); @@ -55,13 +55,13 @@ namespace Lucene /// /// This implementation returns the given {@link DocIdSet}, if {@link DocIdSet#isCacheable} returns /// true, else it copies the {@link DocIdSetIterator} into an {@link OpenBitSetDISI}. - DocIdSetPtr docIdSetToCache(DocIdSetPtr docIdSet, IndexReaderPtr reader); + DocIdSetPtr docIdSetToCache(const DocIdSetPtr& docIdSet, const IndexReaderPtr& reader); public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); virtual String toString(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/CharBlockPool.h b/include/CharBlockPool.h index bb867260..53f69319 100644 --- a/include/CharBlockPool.h +++ b/include/CharBlockPool.h @@ -14,7 +14,7 @@ namespace Lucene class CharBlockPool : public LuceneObject { public: - CharBlockPool(DocumentsWriterPtr docWriter); + CharBlockPool(const DocumentsWriterPtr& docWriter); virtual ~CharBlockPool(); LUCENE_CLASS(CharBlockPool); diff --git a/include/CharFilter.h b/include/CharFilter.h index 9aed7095..5e083307 100644 --- a/include/CharFilter.h +++ b/include/CharFilter.h @@ -17,7 +17,7 @@ namespace Lucene class LPPAPI CharFilter : public CharStream { protected: - CharFilter(CharStreamPtr in); + CharFilter(const CharStreamPtr& in); public: virtual ~CharFilter(); diff --git a/include/CharReader.h b/include/CharReader.h index 4418cb62..887f571c 100644 --- a/include/CharReader.h +++ b/include/CharReader.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI CharReader : public CharStream { public: - CharReader(ReaderPtr in); + CharReader(const ReaderPtr& in); virtual ~CharReader(); LUCENE_CLASS(CharReader); @@ -27,7 +27,7 @@ namespace Lucene public: using CharStream::read; - static CharStreamPtr get(ReaderPtr input); + static CharStreamPtr get(const ReaderPtr& input); virtual int32_t correctOffset(int32_t currentOff); virtual void close(); diff --git a/include/CharTokenizer.h b/include/CharTokenizer.h index 8b946604..35fdbcb1 100644 --- a/include/CharTokenizer.h +++ b/include/CharTokenizer.h @@ -15,9 +15,9 @@ namespace Lucene class LPPAPI CharTokenizer : public Tokenizer { public: - CharTokenizer(ReaderPtr input); - CharTokenizer(AttributeSourcePtr source, ReaderPtr input); - CharTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + CharTokenizer(const ReaderPtr& input); + CharTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + CharTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~CharTokenizer(); LUCENE_CLASS(CharTokenizer); @@ -37,7 +37,7 @@ namespace Lucene public: virtual bool incrementToken(); virtual void end(); - virtual void reset(ReaderPtr input); + virtual void reset(const ReaderPtr& input); protected: /// Returns true if a character should be included in a token. This tokenizer generates as tokens adjacent diff --git a/include/CheckIndex.h b/include/CheckIndex.h index 935dc2ba..9a3e178f 100644 --- a/include/CheckIndex.h +++ b/include/CheckIndex.h @@ -21,7 +21,7 @@ namespace Lucene { public: /// Create a new CheckIndex on the directory. - CheckIndex(DirectoryPtr dir); + CheckIndex(const DirectoryPtr& dir); virtual ~CheckIndex(); LUCENE_CLASS(CheckIndex); @@ -34,7 +34,7 @@ namespace Lucene public: /// Set infoStream where messages should go. If null, no messages are printed - void setInfoStream(InfoStreamPtr out); + void setInfoStream(const InfoStreamPtr& out); /// Returns a {@link IndexStatus} instance detailing the state of the index. /// @@ -61,7 +61,7 @@ namespace Lucene /// segments from the index. BE CAREFUL. /// /// WARNING: Make sure you only call this when the index is not opened by any writer. - void fixIndex(IndexStatusPtr result); + void fixIndex(const IndexStatusPtr& result); static bool testAsserts(); static bool assertsOn(); @@ -93,16 +93,16 @@ namespace Lucene void msg(const String& msg); /// Test field norms. - FieldNormStatusPtr testFieldNorms(Collection fieldNames, SegmentReaderPtr reader); + FieldNormStatusPtr testFieldNorms(Collection fieldNames, const SegmentReaderPtr& reader); /// Test the term index. - TermIndexStatusPtr testTermIndex(SegmentInfoPtr info, SegmentReaderPtr reader); + TermIndexStatusPtr testTermIndex(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); /// Test stored fields for a segment. - StoredFieldStatusPtr testStoredFields(SegmentInfoPtr info, SegmentReaderPtr reader); + StoredFieldStatusPtr testStoredFields(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); /// Test term vectors for a segment. - TermVectorStatusPtr testTermVectors(SegmentInfoPtr info, SegmentReaderPtr reader); + TermVectorStatusPtr testTermVectors(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); }; /// Returned from {@link #checkIndex()} detailing the health and status of the index. diff --git a/include/ChecksumIndexInput.h b/include/ChecksumIndexInput.h index 5739f6b9..20c239d0 100644 --- a/include/ChecksumIndexInput.h +++ b/include/ChecksumIndexInput.h @@ -17,7 +17,7 @@ namespace Lucene class LPPAPI ChecksumIndexInput : public IndexInput { public: - ChecksumIndexInput(IndexInputPtr main); + ChecksumIndexInput(const IndexInputPtr& main); virtual ~ChecksumIndexInput(); LUCENE_CLASS(ChecksumIndexInput); @@ -56,7 +56,7 @@ namespace Lucene virtual int64_t length(); /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/ChecksumIndexOutput.h b/include/ChecksumIndexOutput.h index ef91724d..11c0d545 100644 --- a/include/ChecksumIndexOutput.h +++ b/include/ChecksumIndexOutput.h @@ -17,7 +17,7 @@ namespace Lucene class LPPAPI ChecksumIndexOutput : public IndexOutput { public: - ChecksumIndexOutput(IndexOutputPtr main); + ChecksumIndexOutput(const IndexOutputPtr& main); virtual ~ChecksumIndexOutput(); LUCENE_CLASS(ChecksumIndexOutput); diff --git a/include/CloseableThreadLocal.h b/include/CloseableThreadLocal.h index decf013f..4aa7a942 100644 --- a/include/CloseableThreadLocal.h +++ b/include/CloseableThreadLocal.h @@ -37,7 +37,7 @@ namespace Lucene return initial; } - void set(localDataPtr data) + void set(const localDataPtr& data) { SyncLock syncLock(this); localData.put(LuceneThread::currentId(), data); diff --git a/include/Collector.h b/include/Collector.h index 93ea39c0..de0bd219 100644 --- a/include/Collector.h +++ b/include/Collector.h @@ -51,7 +51,7 @@ namespace Lucene /// class MyCollector : public Collector /// { /// public: - /// MyCollector(BitSetPtr bits) + /// MyCollector(const BitSetPtr& bits) /// { /// this->bits = bits; /// this->docBase = 0; @@ -62,7 +62,7 @@ namespace Lucene /// int32_t docBase; /// /// public: - /// virtual void setScorer(ScorerPtr scorer) + /// virtual void setScorer(const ScorerPtr& scorer) /// { /// // ignore scorer /// } @@ -72,7 +72,7 @@ namespace Lucene /// bits->set(doc + docBase); /// } /// - /// virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + /// virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) /// { /// this->docBase = docBase; /// } @@ -107,7 +107,7 @@ namespace Lucene /// Called before successive calls to {@link #collect(int32_t)}. Implementations that need the score /// of the current document (passed-in to {@link #collect(int32_t)}), should save the passed-in Scorer /// and call scorer.score() when needed. - virtual void setScorer(ScorerPtr scorer) = 0; + virtual void setScorer(const ScorerPtr& scorer) = 0; /// Called once for every document matching a query, with the unbased document number. /// @@ -121,7 +121,7 @@ namespace Lucene /// in {@link #collect(int32_t)}. /// @param reader next IndexReader /// @param docBase - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) = 0; + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) = 0; /// Return true if this collector does not require the matching docIDs to be delivered in int sort /// order (smallest to largest) to {@link #collect}. diff --git a/include/CompoundFileReader.h b/include/CompoundFileReader.h index 7f1037af..447e0519 100644 --- a/include/CompoundFileReader.h +++ b/include/CompoundFileReader.h @@ -18,8 +18,8 @@ namespace Lucene class CompoundFileReader : public Directory { public: - CompoundFileReader(DirectoryPtr dir, const String& name); - CompoundFileReader(DirectoryPtr dir, const String& name, int32_t readBufferSize); + CompoundFileReader(const DirectoryPtr& dir, const String& name); + CompoundFileReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize); virtual ~CompoundFileReader(); LUCENE_CLASS(CompoundFileReader); @@ -45,7 +45,7 @@ namespace Lucene MapStringFileEntryPtr entries; protected: - void ConstructReader(DirectoryPtr dir, const String& name, int32_t readBufferSize); + void ConstructReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize); public: DirectoryPtr getDirectory(); @@ -87,8 +87,8 @@ namespace Lucene { public: CSIndexInput(); - CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length); - CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length, int32_t readBufferSize); + CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length); + CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length, int32_t readBufferSize); virtual ~CSIndexInput(); LUCENE_CLASS(CSIndexInput); @@ -105,7 +105,7 @@ namespace Lucene virtual int64_t length(); /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); protected: /// Implements buffer refill. Reads bytes from the current position in the input. diff --git a/include/CompoundFileWriter.h b/include/CompoundFileWriter.h index ea0d234b..74febe8e 100644 --- a/include/CompoundFileWriter.h +++ b/include/CompoundFileWriter.h @@ -27,7 +27,7 @@ namespace Lucene class CompoundFileWriter : public LuceneObject { public: - CompoundFileWriter(DirectoryPtr dir, const String& name, CheckAbortPtr checkAbort = CheckAbortPtr()); + CompoundFileWriter(const DirectoryPtr& dir, const String& name, const CheckAbortPtr& checkAbort = CheckAbortPtr()); virtual ~CompoundFileWriter(); LUCENE_CLASS(CompoundFileWriter); @@ -71,7 +71,7 @@ namespace Lucene protected: /// Copy the contents of the file with specified extension into the provided output stream. /// Use the provided buffer for moving data to reduce memory allocation. - void copyFile(const FileEntry& source, IndexOutputPtr os, ByteArray buffer); + void copyFile(const FileEntry& source, const IndexOutputPtr& os, ByteArray buffer); }; } diff --git a/include/ConcurrentMergeScheduler.h b/include/ConcurrentMergeScheduler.h index 0a560399..1a43a5ff 100644 --- a/include/ConcurrentMergeScheduler.h +++ b/include/ConcurrentMergeScheduler.h @@ -64,7 +64,7 @@ namespace Lucene virtual void sync(); - virtual void merge(IndexWriterPtr writer); + virtual void merge(const IndexWriterPtr& writer); /// Used for testing static bool anyUnhandledExceptions(); @@ -84,9 +84,9 @@ namespace Lucene virtual int32_t mergeThreadCount(); /// Does the actual merge, by calling {@link IndexWriter#merge} - virtual void doMerge(OneMergePtr merge); + virtual void doMerge(const OneMergePtr& merge); - virtual MergeThreadPtr getMergeThread(IndexWriterPtr writer, OneMergePtr merge); + virtual MergeThreadPtr getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge); /// Called when an exception is hit in a background merge thread virtual void handleMergeException(const LuceneException& exc); diff --git a/include/ConjunctionScorer.h b/include/ConjunctionScorer.h index 6f7ed360..2fc5609a 100644 --- a/include/ConjunctionScorer.h +++ b/include/ConjunctionScorer.h @@ -15,7 +15,7 @@ namespace Lucene class ConjunctionScorer : public Scorer { public: - ConjunctionScorer(SimilarityPtr similarity, Collection scorers); + ConjunctionScorer(const SimilarityPtr& similarity, Collection scorers); virtual ~ConjunctionScorer(); LUCENE_CLASS(ConjunctionScorer); diff --git a/include/ConstantScoreQuery.h b/include/ConstantScoreQuery.h index 22d5074b..72134e5c 100644 --- a/include/ConstantScoreQuery.h +++ b/include/ConstantScoreQuery.h @@ -18,7 +18,7 @@ namespace Lucene class LPPAPI ConstantScoreQuery : public Query { public: - ConstantScoreQuery(FilterPtr filter); + ConstantScoreQuery(const FilterPtr& filter); virtual ~ConstantScoreQuery(); LUCENE_CLASS(ConstantScoreQuery); @@ -32,17 +32,17 @@ namespace Lucene /// Returns the encapsulated filter FilterPtr getFilter(); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); virtual void extractTerms(SetTerm terms); - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); /// Prints a user-readable version of this query. virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); friend class ConstantWeight; friend class ConstantScorer; diff --git a/include/CustomScoreProvider.h b/include/CustomScoreProvider.h index 2a257a86..2ca26202 100644 --- a/include/CustomScoreProvider.h +++ b/include/CustomScoreProvider.h @@ -22,7 +22,7 @@ namespace Lucene { public: /// Creates a new instance of the provider class for the given {@link IndexReader}. - CustomScoreProvider(IndexReaderPtr reader); + CustomScoreProvider(const IndexReaderPtr& reader); virtual ~CustomScoreProvider(); @@ -78,7 +78,7 @@ namespace Lucene /// @param subQueryExpl explanation for the sub-query part. /// @param valSrcExpls explanation for the value source part. /// @return an explanation for the custom score - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, double)}, /// this method should also be overridden to provide the correct explanation for the part of the custom scoring. @@ -86,7 +86,7 @@ namespace Lucene /// @param subQueryExpl explanation for the sub-query part. /// @param valSrcExpl explanation for the value source part. /// @return an explanation for the custom score - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); }; } diff --git a/include/CustomScoreQuery.h b/include/CustomScoreQuery.h index c9e6a09f..e9d0436c 100644 --- a/include/CustomScoreQuery.h +++ b/include/CustomScoreQuery.h @@ -23,21 +23,21 @@ namespace Lucene public: /// Create a CustomScoreQuery over input subQuery. /// @param subQuery the sub query whose scored is being customed. Must not be null. - CustomScoreQuery(QueryPtr subQuery); + CustomScoreQuery(const QueryPtr& subQuery); /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. /// @param subQuery the sub query whose score is being customized. Must not be null. /// @param valSrcQuery a value source query whose scores are used in the custom score computation. For /// most simple/convenient use case this would be a {@link FieldScoreQuery}. This parameter is /// optional - it can be null. - CustomScoreQuery(QueryPtr subQuery, ValueSourceQueryPtr valSrcQuery); + CustomScoreQuery(const QueryPtr& subQuery, const ValueSourceQueryPtr& valSrcQuery); /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. /// @param subQuery the sub query whose score is being customized. Must not be null. /// @param valSrcQueries value source queries whose scores are used in the custom score computation. /// For most simple/convenient use case these would be {@link FieldScoreQueries}. This parameter is /// optional - it can be null or even an empty array. - CustomScoreQuery(QueryPtr subQuery, Collection valSrcQueries); + CustomScoreQuery(const QueryPtr& subQuery, Collection valSrcQueries); virtual ~CustomScoreQuery(); @@ -51,11 +51,11 @@ namespace Lucene public: using Query::toString; - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); virtual void extractTerms(SetTerm terms); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); /// Compute a custom score by the subQuery score and a number of ValueSourceQuery scores. @@ -86,7 +86,7 @@ namespace Lucene /// search (since Lucene 2.9). /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} /// for the given {@link IndexReader}. - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); /// Explain the custom score. /// @@ -96,9 +96,9 @@ namespace Lucene /// search (since Lucene 2.9). /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} /// for the given {@link IndexReader}. - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); /// Checks if this is strict custom scoring. In strict custom scoring, the ValueSource part does not /// participate in weight normalization. This may be useful when one wants full control over how scores @@ -117,12 +117,12 @@ namespace Lucene virtual String name(); protected: - void ConstructQuery(QueryPtr subQuery, Collection valSrcQueries); + void ConstructQuery(const QueryPtr& subQuery, Collection valSrcQueries); /// Returns a {@link CustomScoreProvider} that calculates the custom scores for the given {@link /// IndexReader}. The default implementation returns a default implementation as specified in /// the docs of {@link CustomScoreProvider}. - virtual CustomScoreProviderPtr getCustomScoreProvider(IndexReaderPtr reader); + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader); friend class CustomWeight; friend class CustomScorer; diff --git a/include/DefaultSimilarity.h b/include/DefaultSimilarity.h index ad12ca68..b2c77586 100644 --- a/include/DefaultSimilarity.h +++ b/include/DefaultSimilarity.h @@ -27,7 +27,7 @@ namespace Lucene /// Implemented as state->getBoost() * lengthNorm(numTerms), where numTerms is {@link /// FieldInvertState#getLength()} if {@link #setDiscountOverlaps} is false, else it's {@link /// FieldInvertState#getLength()} - {@link FieldInvertState#getNumOverlap()}. - virtual double computeNorm(const String& fieldName, FieldInvertStatePtr state); + virtual double computeNorm(const String& fieldName, const FieldInvertStatePtr& state); /// Implemented as 1 / sqrt(numTerms). virtual double lengthNorm(const String& fieldName, int32_t numTokens); diff --git a/include/DefaultSkipListReader.h b/include/DefaultSkipListReader.h index c0a29b99..ac2d451c 100644 --- a/include/DefaultSkipListReader.h +++ b/include/DefaultSkipListReader.h @@ -15,7 +15,7 @@ namespace Lucene class DefaultSkipListReader : public MultiLevelSkipListReader { public: - DefaultSkipListReader(IndexInputPtr skipStream, int32_t maxSkipLevels, int32_t skipInterval); + DefaultSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval); virtual ~DefaultSkipListReader(); LUCENE_CLASS(DefaultSkipListReader); @@ -53,7 +53,7 @@ namespace Lucene virtual void setLastSkipData(int32_t level); /// Subclasses must implement the actual skip data encoding in this method. - virtual int32_t readSkipData(int32_t level, IndexInputPtr skipStream); + virtual int32_t readSkipData(int32_t level, const IndexInputPtr& skipStream); }; } diff --git a/include/DefaultSkipListWriter.h b/include/DefaultSkipListWriter.h index 48f443e9..cef4f5d8 100644 --- a/include/DefaultSkipListWriter.h +++ b/include/DefaultSkipListWriter.h @@ -15,7 +15,7 @@ namespace Lucene class DefaultSkipListWriter : public MultiLevelSkipListWriter { public: - DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, IndexOutputPtr freqOutput, IndexOutputPtr proxOutput); + DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, const IndexOutputPtr& freqOutput, const IndexOutputPtr& proxOutput); virtual ~DefaultSkipListWriter(); LUCENE_CLASS(DefaultSkipListWriter); @@ -36,15 +36,15 @@ namespace Lucene int64_t curProxPointer; public: - void setFreqOutput(IndexOutputPtr freqOutput); - void setProxOutput(IndexOutputPtr proxOutput); + void setFreqOutput(const IndexOutputPtr& freqOutput); + void setProxOutput(const IndexOutputPtr& proxOutput); /// Sets the values for the current skip data. void setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength); protected: virtual void resetSkip(); - virtual void writeSkipData(int32_t level, IndexOutputPtr skipBuffer); + virtual void writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer); friend class FormatPostingsTermsWriter; }; diff --git a/include/Directory.h b/include/Directory.h index 81f86ae3..88820704 100644 --- a/include/Directory.h +++ b/include/Directory.h @@ -80,7 +80,7 @@ namespace Lucene /// of LockFactory should only be used for one directory (ie, do not share a single instance across multiple /// Directories). /// @param lockFactory instance of {@link LockFactory}. - void setLockFactory(LockFactoryPtr lockFactory); + void setLockFactory(const LockFactoryPtr& lockFactory); /// Get the LockFactory that this Directory instance is using for its locking implementation. Note that this /// may be null for Directory implementations that provide their own locking implementation. @@ -99,7 +99,7 @@ namespace Lucene /// @param src source directory. /// @param dest destination directory. /// @param closeDirSrc if true, call {@link #close()} method on source directory. - static void copy(DirectoryPtr src, DirectoryPtr dest, bool closeDirSrc); + static void copy(const DirectoryPtr& src, const DirectoryPtr& dest, bool closeDirSrc); protected: /// @throws AlreadyClosed if this Directory is closed. diff --git a/include/DirectoryReader.h b/include/DirectoryReader.h index 524d10e9..c91ff3f8 100644 --- a/include/DirectoryReader.h +++ b/include/DirectoryReader.h @@ -20,13 +20,13 @@ namespace Lucene { public: /// Construct reading the named set of readers. - DirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); + DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); /// Used by near real-time search. - DirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor); + DirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor); /// This constructor is only used for {@link #reopen()} - DirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, + DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, bool doClone, int32_t termInfosIndexDivisor); @@ -62,14 +62,14 @@ namespace Lucene public: void _initialize(Collection subReaders); - static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor); + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual LuceneObjectPtr clone(bool openReadOnly, LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); virtual IndexReaderPtr reopen(); virtual IndexReaderPtr reopen(bool openReadOnly); - virtual IndexReaderPtr reopen(IndexCommitPtr commit); + virtual IndexReaderPtr reopen(const IndexCommitPtr& commit); /// Version number when this IndexReader was opened. virtual int64_t getVersion(); @@ -81,10 +81,10 @@ namespace Lucene virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays of the {@link TermFreqVector}. - virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); /// Map all the term vectors for all fields in a Document - virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented in the IndexReader base class. /// @return true if the index is optimized; false otherwise @@ -97,7 +97,7 @@ namespace Lucene virtual int32_t maxDoc(); /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what {@link Field}s to load and how they should be loaded. - virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n); @@ -121,10 +121,10 @@ namespace Lucene virtual TermEnumPtr terms(); /// Returns an enumeration of all terms starting at a given term. - virtual TermEnumPtr terms(TermPtr t); + virtual TermEnumPtr terms(const TermPtr& t); /// Returns the number of documents containing the term t. - virtual int32_t docFreq(TermPtr t); + virtual int32_t docFreq(const TermPtr& t); /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs(); @@ -163,13 +163,13 @@ namespace Lucene virtual IndexCommitPtr getIndexCommit(); /// Returns all commit points that exist in the Directory. - static Collection listCommits(DirectoryPtr dir); + static Collection listCommits(const DirectoryPtr& dir); protected: - IndexReaderPtr doReopenFromWriter(bool openReadOnly, IndexCommitPtr commit); - IndexReaderPtr doReopen(bool openReadOnly, IndexCommitPtr commit); - IndexReaderPtr doReopenNoWriter(bool openReadOnly, IndexCommitPtr commit); - DirectoryReaderPtr doReopen(SegmentInfosPtr infos, bool doClone, bool openReadOnly); + IndexReaderPtr doReopenFromWriter(bool openReadOnly, const IndexCommitPtr& commit); + IndexReaderPtr doReopen(bool openReadOnly, const IndexCommitPtr& commit); + IndexReaderPtr doReopenNoWriter(bool openReadOnly, const IndexCommitPtr& commit); + DirectoryReaderPtr doReopen(const SegmentInfosPtr& infos, bool doClone, bool openReadOnly); /// Implements deletion of the document numbered docNum. virtual void doDelete(int32_t docNum); @@ -196,7 +196,7 @@ namespace Lucene class MultiTermEnum : public TermEnum { public: - MultiTermEnum(IndexReaderPtr topReader, Collection readers, Collection starts, TermPtr t); + MultiTermEnum(const IndexReaderPtr& topReader, Collection readers, Collection starts, const TermPtr& t); virtual ~MultiTermEnum(); LUCENE_CLASS(MultiTermEnum); @@ -227,7 +227,7 @@ namespace Lucene class MultiTermDocs : public TermPositions, public LuceneObject { public: - MultiTermDocs(IndexReaderPtr topReader, Collection r, Collection s); + MultiTermDocs(const IndexReaderPtr& topReader, Collection r, Collection s); virtual ~MultiTermDocs(); LUCENE_CLASS(MultiTermDocs); @@ -255,10 +255,10 @@ namespace Lucene virtual int32_t freq(); /// Sets this to the data for a term. - virtual void seek(TermPtr term); + virtual void seek(const TermPtr& term); /// Sets this to the data for the current term in a {@link TermEnum}. - virtual void seek(TermEnumPtr termEnum); + virtual void seek(const TermEnumPtr& termEnum); /// Moves to the next pair in the enumeration. virtual bool next(); @@ -275,13 +275,13 @@ namespace Lucene protected: virtual TermDocsPtr termDocs(int32_t i); - virtual TermDocsPtr termDocs(IndexReaderPtr reader); + virtual TermDocsPtr termDocs(const IndexReaderPtr& reader); }; class MultiTermPositions : public MultiTermDocs { public: - MultiTermPositions(IndexReaderPtr topReader, Collection r, Collection s); + MultiTermPositions(const IndexReaderPtr& topReader, Collection r, Collection s); virtual ~MultiTermPositions(); LUCENE_CLASS(MultiTermPositions); @@ -300,13 +300,13 @@ namespace Lucene virtual bool isPayloadAvailable(); protected: - virtual TermDocsPtr termDocs(IndexReaderPtr reader); + virtual TermDocsPtr termDocs(const IndexReaderPtr& reader); }; class ReaderCommit : public IndexCommit { public: - ReaderCommit(SegmentInfosPtr infos, DirectoryPtr dir); + ReaderCommit(const SegmentInfosPtr& infos, const DirectoryPtr& dir); virtual ~ReaderCommit(); LUCENE_CLASS(ReaderCommit); diff --git a/include/DisjunctionMaxQuery.h b/include/DisjunctionMaxQuery.h index 9cbebc14..1b0bc3f4 100644 --- a/include/DisjunctionMaxQuery.h +++ b/include/DisjunctionMaxQuery.h @@ -56,7 +56,7 @@ namespace Lucene /// Add a subquery to this disjunction /// @param query the disjunct added - void add(QueryPtr query); + void add(const QueryPtr& query); /// Add a collection of disjuncts to this disjunction void add(Collection disjuncts); @@ -66,16 +66,16 @@ namespace Lucene Collection::iterator end(); /// Create the Weight used to score us - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); /// Optimize our representation and our subqueries representations /// @param reader the IndexReader we query /// @return an optimized copy of us (which may not be a copy if there is nothing to optimize) - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); /// Create a shallow copy of us - used in rewriting if necessary /// @return a copy of us (but reuse, don't copy, our subqueries) - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Adds all terms occurring in this query to the terms set. virtual void extractTerms(SetTerm terms); @@ -87,7 +87,7 @@ namespace Lucene /// @return true if other is a DisjunctionMaxQuery with the same boost and the same subqueries, in the /// same order, as us - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); diff --git a/include/DisjunctionMaxScorer.h b/include/DisjunctionMaxScorer.h index abd6ecee..ab9aae42 100644 --- a/include/DisjunctionMaxScorer.h +++ b/include/DisjunctionMaxScorer.h @@ -18,7 +18,7 @@ namespace Lucene class DisjunctionMaxScorer : public Scorer { public: - DisjunctionMaxScorer(double tieBreakerMultiplier, SimilarityPtr similarity, Collection subScorers, int32_t numScorers); + DisjunctionMaxScorer(double tieBreakerMultiplier, const SimilarityPtr& similarity, Collection subScorers, int32_t numScorers); virtual ~DisjunctionMaxScorer(); LUCENE_CLASS(DisjunctionMaxScorer); diff --git a/include/DisjunctionSumScorer.h b/include/DisjunctionSumScorer.h index 9b603250..5d2fdde5 100644 --- a/include/DisjunctionSumScorer.h +++ b/include/DisjunctionSumScorer.h @@ -51,7 +51,7 @@ namespace Lucene public: virtual void initialize(); - virtual void score(CollectorPtr collector); + virtual void score(const CollectorPtr& collector); virtual int32_t nextDoc(); /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} @@ -80,7 +80,7 @@ namespace Lucene /// @param collector The collector to which all matching documents are passed through. /// @param max Do not score documents past this. /// @return true if more matching documents may remain. - virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); /// Advance all subscorers after the current document determined by the top of the scorerDocQueue. Repeat /// until at least the minimum number of subscorers match on the same document and all subscorers are after diff --git a/include/DocConsumer.h b/include/DocConsumer.h index 71b4ba2d..66500eb5 100644 --- a/include/DocConsumer.h +++ b/include/DocConsumer.h @@ -19,9 +19,9 @@ namespace Lucene LUCENE_CLASS(DocConsumer); public: - virtual DocConsumerPerThreadPtr addThread(DocumentsWriterThreadStatePtr perThread) = 0; - virtual void flush(Collection threads, SegmentWriteStatePtr state) = 0; - virtual void closeDocStore(SegmentWriteStatePtr state) = 0; + virtual DocConsumerPerThreadPtr addThread(const DocumentsWriterThreadStatePtr& perThread) = 0; + virtual void flush(Collection threads, const SegmentWriteStatePtr& state) = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; virtual void abort() = 0; virtual bool freeRAM() = 0; }; diff --git a/include/DocFieldConsumer.h b/include/DocFieldConsumer.h index 2e2974b9..ed402700 100644 --- a/include/DocFieldConsumer.h +++ b/include/DocFieldConsumer.h @@ -23,22 +23,22 @@ namespace Lucene public: /// Called when DocumentsWriter decides to create a new segment - virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; + virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; /// Called when DocumentsWriter decides to close the doc stores - virtual void closeDocStore(SegmentWriteStatePtr state) = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; /// Called when an aborting exception is hit virtual void abort() = 0; /// Add a new thread - virtual DocFieldConsumerPerThreadPtr addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread) = 0; + virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) = 0; /// Called when DocumentsWriter is using too much RAM. The consumer should free RAM, if possible, returning /// true if any RAM was in fact freed. virtual bool freeRAM() = 0; - virtual void setFieldInfos(FieldInfosPtr fieldInfos); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); }; } diff --git a/include/DocFieldConsumerPerThread.h b/include/DocFieldConsumerPerThread.h index d00b3ebd..9014ebc6 100644 --- a/include/DocFieldConsumerPerThread.h +++ b/include/DocFieldConsumerPerThread.h @@ -21,7 +21,7 @@ namespace Lucene public: virtual void startDocument() = 0; virtual DocWriterPtr finishDocument() = 0; - virtual DocFieldConsumerPerFieldPtr addField(FieldInfoPtr fi) = 0; + virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi) = 0; virtual void abort() = 0; }; } diff --git a/include/DocFieldConsumers.h b/include/DocFieldConsumers.h index ce915e87..46bfb424 100644 --- a/include/DocFieldConsumers.h +++ b/include/DocFieldConsumers.h @@ -16,7 +16,7 @@ namespace Lucene class DocFieldConsumers : public DocFieldConsumer { public: - DocFieldConsumers(DocFieldConsumerPtr one, DocFieldConsumerPtr two); + DocFieldConsumers(const DocFieldConsumerPtr& one, const DocFieldConsumerPtr& two); virtual ~DocFieldConsumers(); LUCENE_CLASS(DocFieldConsumers); @@ -30,28 +30,28 @@ namespace Lucene int32_t allocCount; public: - virtual void setFieldInfos(FieldInfosPtr fieldInfos); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); /// Called when DocumentsWriter decides to create a new segment - virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state); + virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); /// Called when DocumentsWriter decides to close the doc stores - virtual void closeDocStore(SegmentWriteStatePtr state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); /// Called when DocumentsWriter is using too much RAM. virtual bool freeRAM(); /// Add a new thread - virtual DocFieldConsumerPerThreadPtr addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread); + virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread); DocFieldConsumersPerDocPtr getPerDoc(); - void freePerDoc(DocFieldConsumersPerDocPtr perDoc); + void freePerDoc(const DocFieldConsumersPerDocPtr& perDoc); }; class DocFieldConsumersPerDoc : public DocWriter { public: - DocFieldConsumersPerDoc(DocFieldConsumersPtr fieldConsumers); + DocFieldConsumersPerDoc(const DocFieldConsumersPtr& fieldConsumers); virtual ~DocFieldConsumersPerDoc(); LUCENE_CLASS(DocFieldConsumersPerDoc); diff --git a/include/DocFieldConsumersPerField.h b/include/DocFieldConsumersPerField.h index 5bca578b..cbfd73d8 100644 --- a/include/DocFieldConsumersPerField.h +++ b/include/DocFieldConsumersPerField.h @@ -14,7 +14,7 @@ namespace Lucene class DocFieldConsumersPerField : public DocFieldConsumerPerField { public: - DocFieldConsumersPerField(DocFieldConsumersPerThreadPtr perThread, DocFieldConsumerPerFieldPtr one, DocFieldConsumerPerFieldPtr two); + DocFieldConsumersPerField(const DocFieldConsumersPerThreadPtr& perThread, const DocFieldConsumerPerFieldPtr& one, const DocFieldConsumerPerFieldPtr& two); virtual ~DocFieldConsumersPerField(); LUCENE_CLASS(DocFieldConsumersPerField); diff --git a/include/DocFieldConsumersPerThread.h b/include/DocFieldConsumersPerThread.h index b2eb8c85..11820e9a 100644 --- a/include/DocFieldConsumersPerThread.h +++ b/include/DocFieldConsumersPerThread.h @@ -14,8 +14,8 @@ namespace Lucene class DocFieldConsumersPerThread : public DocFieldConsumerPerThread { public: - DocFieldConsumersPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, DocFieldConsumersPtr parent, - DocFieldConsumerPerThreadPtr one, DocFieldConsumerPerThreadPtr two); + DocFieldConsumersPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocFieldConsumersPtr& parent, + const DocFieldConsumerPerThreadPtr& one, const DocFieldConsumerPerThreadPtr& two); virtual ~DocFieldConsumersPerThread(); LUCENE_CLASS(DocFieldConsumersPerThread); @@ -30,7 +30,7 @@ namespace Lucene virtual void startDocument(); virtual void abort(); virtual DocWriterPtr finishDocument(); - virtual DocFieldConsumerPerFieldPtr addField(FieldInfoPtr fi); + virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi); }; } diff --git a/include/DocFieldProcessor.h b/include/DocFieldProcessor.h index 8dcfbf8a..e6c8d8db 100644 --- a/include/DocFieldProcessor.h +++ b/include/DocFieldProcessor.h @@ -17,7 +17,7 @@ namespace Lucene class DocFieldProcessor : public DocConsumer { public: - DocFieldProcessor(DocumentsWriterPtr docWriter, DocFieldConsumerPtr consumer); + DocFieldProcessor(const DocumentsWriterPtr& docWriter, const DocFieldConsumerPtr& consumer); virtual ~DocFieldProcessor(); LUCENE_CLASS(DocFieldProcessor); @@ -29,11 +29,11 @@ namespace Lucene StoredFieldsWriterPtr fieldsWriter; public: - virtual void closeDocStore(SegmentWriteStatePtr state); - virtual void flush(Collection threads, SegmentWriteStatePtr state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); + virtual void flush(Collection threads, const SegmentWriteStatePtr& state); virtual void abort(); virtual bool freeRAM(); - virtual DocConsumerPerThreadPtr addThread(DocumentsWriterThreadStatePtr perThread); + virtual DocConsumerPerThreadPtr addThread(const DocumentsWriterThreadStatePtr& perThread); }; } diff --git a/include/DocFieldProcessorPerField.h b/include/DocFieldProcessorPerField.h index 3ca88838..8274d5f3 100644 --- a/include/DocFieldProcessorPerField.h +++ b/include/DocFieldProcessorPerField.h @@ -15,7 +15,7 @@ namespace Lucene class DocFieldProcessorPerField : public LuceneObject { public: - DocFieldProcessorPerField(DocFieldProcessorPerThreadPtr perThread, FieldInfoPtr fieldInfo); + DocFieldProcessorPerField(const DocFieldProcessorPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); virtual ~DocFieldProcessorPerField(); LUCENE_CLASS(DocFieldProcessorPerField); diff --git a/include/DocFieldProcessorPerThread.h b/include/DocFieldProcessorPerThread.h index 05e57dbd..f581614a 100644 --- a/include/DocFieldProcessorPerThread.h +++ b/include/DocFieldProcessorPerThread.h @@ -19,7 +19,7 @@ namespace Lucene class DocFieldProcessorPerThread : public DocConsumerPerThread { public: - DocFieldProcessorPerThread(DocumentsWriterThreadStatePtr threadState, DocFieldProcessorPtr docFieldProcessor); + DocFieldProcessorPerThread(const DocumentsWriterThreadStatePtr& threadState, const DocFieldProcessorPtr& docFieldProcessor); virtual ~DocFieldProcessorPerThread(); LUCENE_CLASS(DocFieldProcessorPerThread); @@ -50,12 +50,12 @@ namespace Lucene Collection fields(); // If there are fields we've seen but did not see again in the last run, then free them up. - void trimFields(SegmentWriteStatePtr state); + void trimFields(const SegmentWriteStatePtr& state); virtual DocWriterPtr processDocument(); DocFieldProcessorPerThreadPerDocPtr getPerDoc(); - void freePerDoc(DocFieldProcessorPerThreadPerDocPtr perDoc); + void freePerDoc(const DocFieldProcessorPerThreadPerDocPtr& perDoc); protected: void rehash(); @@ -64,7 +64,7 @@ namespace Lucene class DocFieldProcessorPerThreadPerDoc : public DocWriter { public: - DocFieldProcessorPerThreadPerDoc(DocFieldProcessorPerThreadPtr docProcessor); + DocFieldProcessorPerThreadPerDoc(const DocFieldProcessorPerThreadPtr& docProcessor); virtual ~DocFieldProcessorPerThreadPerDoc(); LUCENE_CLASS(DocFieldProcessorPerThreadPerDoc); diff --git a/include/DocIdBitSet.h b/include/DocIdBitSet.h index 1d620b80..30b83224 100644 --- a/include/DocIdBitSet.h +++ b/include/DocIdBitSet.h @@ -16,7 +16,7 @@ namespace Lucene { public: DocIdBitSet(); - DocIdBitSet(BitSetPtr bitSet); + DocIdBitSet(const BitSetPtr& bitSet); virtual ~DocIdBitSet(); @@ -34,9 +34,9 @@ namespace Lucene /// Returns the underlying BitSet. BitSetPtr getBitSet(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/DocInverter.h b/include/DocInverter.h index f9c67ca0..b5e217df 100644 --- a/include/DocInverter.h +++ b/include/DocInverter.h @@ -16,7 +16,7 @@ namespace Lucene class DocInverter : public DocFieldConsumer { public: - DocInverter(InvertedDocConsumerPtr consumer, InvertedDocEndConsumerPtr endConsumer); + DocInverter(const InvertedDocConsumerPtr& consumer, const InvertedDocEndConsumerPtr& endConsumer); virtual ~DocInverter(); LUCENE_CLASS(DocInverter); @@ -26,13 +26,13 @@ namespace Lucene InvertedDocEndConsumerPtr endConsumer; public: - virtual void setFieldInfos(FieldInfosPtr fieldInfos); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); /// Called when DocumentsWriter decides to create a new segment - virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state); + virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); /// Called when DocumentsWriter decides to close the doc stores - virtual void closeDocStore(SegmentWriteStatePtr state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); /// Called when an aborting exception is hit virtual void abort(); @@ -41,7 +41,7 @@ namespace Lucene virtual bool freeRAM(); /// Add a new thread - virtual DocFieldConsumerPerThreadPtr addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread); + virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread); }; } diff --git a/include/DocInverterPerField.h b/include/DocInverterPerField.h index 01c855b2..7c9d9c29 100644 --- a/include/DocInverterPerField.h +++ b/include/DocInverterPerField.h @@ -17,7 +17,7 @@ namespace Lucene class DocInverterPerField : public DocFieldConsumerPerField { public: - DocInverterPerField(DocInverterPerThreadPtr perThread, FieldInfoPtr fieldInfo); + DocInverterPerField(const DocInverterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); virtual ~DocInverterPerField(); LUCENE_CLASS(DocInverterPerField); diff --git a/include/DocInverterPerThread.h b/include/DocInverterPerThread.h index c5adaa9e..c818c1c1 100644 --- a/include/DocInverterPerThread.h +++ b/include/DocInverterPerThread.h @@ -17,7 +17,7 @@ namespace Lucene class DocInverterPerThread : public DocFieldConsumerPerThread { public: - DocInverterPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, DocInverterPtr docInverter); + DocInverterPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocInverterPtr& docInverter); virtual ~DocInverterPerThread(); LUCENE_CLASS(DocInverterPerThread); @@ -39,7 +39,7 @@ namespace Lucene virtual void startDocument(); virtual DocWriterPtr finishDocument(); virtual void abort(); - virtual DocFieldConsumerPerFieldPtr addField(FieldInfoPtr fi); + virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi); }; class SingleTokenAttributeSource : public AttributeSource diff --git a/include/Document.h b/include/Document.h index d61bfbeb..ecb118f0 100644 --- a/include/Document.h +++ b/include/Document.h @@ -64,7 +64,7 @@ namespace Lucene /// Note that add like the removeField(s) methods only makes sense prior to adding a document to an index. /// These methods cannot be used to change the content of an existing index! In order to achieve this, a /// document has to be deleted from an index and a new changed version of that document has to be added. - void add(FieldablePtr field); + void add(const FieldablePtr& field); /// Removes field with the specified name from the document. If multiple fields exist with this name, this /// method removes the first field that has been added. If there is no field with the specified name, the diff --git a/include/DocumentsWriter.h b/include/DocumentsWriter.h index 7d22aa25..b54ed36e 100644 --- a/include/DocumentsWriter.h +++ b/include/DocumentsWriter.h @@ -54,7 +54,7 @@ namespace Lucene class DocumentsWriter : public LuceneObject { public: - DocumentsWriter(DirectoryPtr directory, IndexWriterPtr writer, IndexingChainPtr indexingChain); + DocumentsWriter(const DirectoryPtr& directory, const IndexWriterPtr& writer, const IndexingChainPtr& indexingChain); virtual ~DocumentsWriter(); LUCENE_CLASS(DocumentsWriter); @@ -200,10 +200,10 @@ namespace Lucene bool hasProx(); /// If non-null, various details of indexing are printed here. - void setInfoStream(InfoStreamPtr infoStream); + void setInfoStream(const InfoStreamPtr& infoStream); void setMaxFieldLength(int32_t maxFieldLength); - void setSimilarity(SimilarityPtr similarity); + void setSimilarity(const SimilarityPtr& similarity); /// Set how much RAM we can use before flushing. void setRAMBufferSizeMB(double mb); @@ -276,24 +276,24 @@ namespace Lucene /// Returns a free (idle) ThreadState that may be used for indexing this one document. This call also /// pauses if a flush is pending. If delTerm is non-null then we buffer this deleted term after the /// thread state has been acquired. - DocumentsWriterThreadStatePtr getThreadState(DocumentPtr doc, TermPtr delTerm); + DocumentsWriterThreadStatePtr getThreadState(const DocumentPtr& doc, const TermPtr& delTerm); /// Returns true if the caller (IndexWriter) should now flush. - bool addDocument(DocumentPtr doc, AnalyzerPtr analyzer); + bool addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer); - bool updateDocument(TermPtr t, DocumentPtr doc, AnalyzerPtr analyzer); - bool updateDocument(DocumentPtr doc, AnalyzerPtr analyzer, TermPtr delTerm); + bool updateDocument(const TermPtr& t, const DocumentPtr& doc, const AnalyzerPtr& analyzer); + bool updateDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer, const TermPtr& delTerm); int32_t getNumBufferedDeleteTerms(); // for testing MapTermNum getBufferedDeleteTerms(); // for testing /// Called whenever a merge has completed and the merged segments had deletions - void remapDeletes(SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergeDocCount); + void remapDeletes(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergeDocCount); bool bufferDeleteTerms(Collection terms); - bool bufferDeleteTerm(TermPtr term); + bool bufferDeleteTerm(const TermPtr& term); bool bufferDeleteQueries(Collection queries); - bool bufferDeleteQuery(QueryPtr query); + bool bufferDeleteQuery(const QueryPtr& query); bool deletesFull(); bool doApplyDeletes(); @@ -301,7 +301,7 @@ namespace Lucene int32_t getMaxBufferedDeleteTerms(); bool hasDeletes(); - bool applyDeletes(SegmentInfosPtr infos); + bool applyDeletes(const SegmentInfosPtr& infos); bool doBalanceRAM(); void waitForWaitQueue(); @@ -334,22 +334,22 @@ namespace Lucene bool allThreadsIdle(); - void waitReady(DocumentsWriterThreadStatePtr state); + void waitReady(const DocumentsWriterThreadStatePtr& state); bool timeToFlushDeletes(); // used only by assert - bool checkDeleteTerm(TermPtr term); + bool checkDeleteTerm(const TermPtr& term); - bool applyDeletes(IndexReaderPtr reader, int32_t docIDStart); - void addDeleteTerm(TermPtr term, int32_t docCount); + bool applyDeletes(const IndexReaderPtr& reader, int32_t docIDStart); + void addDeleteTerm(const TermPtr& term, int32_t docCount); /// Buffer a specific docID for deletion. Currently only used when we hit a exception when adding a document void addDeleteDocID(int32_t docID); - void addDeleteQuery(QueryPtr query, int32_t docID); + void addDeleteQuery(const QueryPtr& query, int32_t docID); /// Does the synchronized work to finish/flush the inverted document. - void finishDocument(DocumentsWriterThreadStatePtr perThread, DocWriterPtr docWriter); + void finishDocument(const DocumentsWriterThreadStatePtr& perThread, const DocWriterPtr& docWriter); friend class WaitQueue; }; @@ -383,7 +383,7 @@ namespace Lucene class PerDocBuffer : public RAMFile { public: - PerDocBuffer(DocumentsWriterPtr docWriter); + PerDocBuffer(const DocumentsWriterPtr& docWriter); virtual ~PerDocBuffer(); LUCENE_CLASS(PerDocBuffer); @@ -419,7 +419,7 @@ namespace Lucene virtual void abort() = 0; virtual int64_t sizeInBytes() = 0; - virtual void setNext(DocWriterPtr next); + virtual void setNext(const DocWriterPtr& next); }; /// The IndexingChain must define the {@link #getChain(DocumentsWriter)} method which returns the DocConsumer @@ -432,7 +432,7 @@ namespace Lucene LUCENE_CLASS(IndexingChain); public: - virtual DocConsumerPtr getChain(DocumentsWriterPtr documentsWriter) = 0; + virtual DocConsumerPtr getChain(const DocumentsWriterPtr& documentsWriter) = 0; }; /// This is the current indexing chain: @@ -457,7 +457,7 @@ namespace Lucene LUCENE_CLASS(DefaultIndexingChain); public: - virtual DocConsumerPtr getChain(DocumentsWriterPtr documentsWriter); + virtual DocConsumerPtr getChain(const DocumentsWriterPtr& documentsWriter); }; class SkipDocWriter : public DocWriter @@ -476,7 +476,7 @@ namespace Lucene class WaitQueue : public LuceneObject { public: - WaitQueue(DocumentsWriterPtr docWriter); + WaitQueue(const DocumentsWriterPtr& docWriter); virtual ~WaitQueue(); LUCENE_CLASS(WaitQueue); @@ -496,16 +496,16 @@ namespace Lucene bool doResume(); bool doPause(); void abort(); - bool add(DocWriterPtr doc); + bool add(const DocWriterPtr& doc); protected: - void writeDocument(DocWriterPtr doc); + void writeDocument(const DocWriterPtr& doc); }; class ByteBlockAllocator : public ByteBlockPoolAllocatorBase { public: - ByteBlockAllocator(DocumentsWriterPtr docWriter, int32_t blockSize); + ByteBlockAllocator(const DocumentsWriterPtr& docWriter, int32_t blockSize); virtual ~ByteBlockAllocator(); LUCENE_CLASS(ByteBlockAllocator); diff --git a/include/DocumentsWriterThreadState.h b/include/DocumentsWriterThreadState.h index b8b2b267..e85878fd 100644 --- a/include/DocumentsWriterThreadState.h +++ b/include/DocumentsWriterThreadState.h @@ -17,7 +17,7 @@ namespace Lucene class DocumentsWriterThreadState : public LuceneObject { public: - DocumentsWriterThreadState(DocumentsWriterPtr docWriter); + DocumentsWriterThreadState(const DocumentsWriterPtr& docWriter); virtual ~DocumentsWriterThreadState(); LUCENE_CLASS(DocumentsWriterThreadState); diff --git a/include/DoubleFieldSource.h b/include/DoubleFieldSource.h index 6fa2fbe0..390e7e87 100644 --- a/include/DoubleFieldSource.h +++ b/include/DoubleFieldSource.h @@ -26,7 +26,7 @@ namespace Lucene { public: /// Create a cached double field source with a specific string-to-double parser. - DoubleFieldSource(const String& field, DoubleParserPtr parser = DoubleParserPtr()); + DoubleFieldSource(const String& field, const DoubleParserPtr& parser = DoubleParserPtr()); virtual ~DoubleFieldSource(); LUCENE_CLASS(DoubleFieldSource); @@ -36,15 +36,15 @@ namespace Lucene public: virtual String description(); - virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader); - virtual bool cachedFieldSourceEquals(FieldCacheSourcePtr other); + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); virtual int32_t cachedFieldSourceHashCode(); }; class DoubleDocValues : public DocValues { public: - DoubleDocValues(DoubleFieldSourcePtr source, Collection arr); + DoubleDocValues(const DoubleFieldSourcePtr& source, Collection arr); virtual ~DoubleDocValues(); LUCENE_CLASS(DoubleDocValues); diff --git a/include/ExactPhraseScorer.h b/include/ExactPhraseScorer.h index 3d50d664..68e24e72 100644 --- a/include/ExactPhraseScorer.h +++ b/include/ExactPhraseScorer.h @@ -14,7 +14,7 @@ namespace Lucene class ExactPhraseScorer : public PhraseScorer { public: - ExactPhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, ByteArray norms); + ExactPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms); virtual ~ExactPhraseScorer(); LUCENE_CLASS(ExactPhraseScorer); diff --git a/include/Explanation.h b/include/Explanation.h index b1703f4e..65c26962 100644 --- a/include/Explanation.h +++ b/include/Explanation.h @@ -49,7 +49,7 @@ namespace Lucene virtual Collection getDetails(); /// Adds a sub-node to this explanation node. - virtual void addDetail(ExplanationPtr detail); + virtual void addDetail(const ExplanationPtr& detail); /// Render an explanation as text. virtual String toString(); diff --git a/include/FSDirectory.h b/include/FSDirectory.h index 63dc4269..15971ed4 100644 --- a/include/FSDirectory.h +++ b/include/FSDirectory.h @@ -32,7 +32,7 @@ namespace Lucene /// Create a new FSDirectory for the named location (ctor for subclasses). /// @param path the path of the directory. /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) - FSDirectory(const String& path, LockFactoryPtr lockFactory); + FSDirectory(const String& path, const LockFactoryPtr& lockFactory); public: virtual ~FSDirectory(); @@ -58,7 +58,7 @@ namespace Lucene static FSDirectoryPtr open(const String& path); /// Just like {@link #open(File)}, but allows you to also specify a custom {@link LockFactory}. - static FSDirectoryPtr open(const String& path, LockFactoryPtr lockFactory); + static FSDirectoryPtr open(const String& path, const LockFactoryPtr& lockFactory); /// Lists all files (not subdirectories) in the directory. /// @throws NoSuchDirectoryException if the directory does not exist, or does exist but is not a directory. diff --git a/include/FastCharStream.h b/include/FastCharStream.h index f15448e9..d255cfce 100644 --- a/include/FastCharStream.h +++ b/include/FastCharStream.h @@ -19,7 +19,7 @@ namespace Lucene { public: /// Constructs from a Reader. - FastCharStream(ReaderPtr reader); + FastCharStream(const ReaderPtr& reader); virtual ~FastCharStream(); LUCENE_CLASS(FastCharStream); diff --git a/include/Field.h b/include/Field.h index b6242660..a2fb673a 100644 --- a/include/Field.h +++ b/include/Field.h @@ -38,7 +38,7 @@ namespace Lucene /// /// @param name The name of the field /// @param reader The reader with the content - Field(const String& name, ReaderPtr reader); + Field(const String& name, const ReaderPtr& reader); /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. The /// Reader is read only when the Document is added to the index, ie. you may not close the Reader until @@ -47,7 +47,7 @@ namespace Lucene /// @param name The name of the field /// @param reader The reader with the content /// @param termVector Whether term vector should be stored - Field(const String& name, ReaderPtr reader, TermVector termVector); + Field(const String& name, const ReaderPtr& reader, TermVector termVector); /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. This is useful /// for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, ie. you @@ -55,7 +55,7 @@ namespace Lucene /// /// @param name The name of the field /// @param tokenStream The TokenStream with the content - Field(const String& name, TokenStreamPtr tokenStream); + Field(const String& name, const TokenStreamPtr& tokenStream); /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. This is /// useful for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, @@ -64,7 +64,7 @@ namespace Lucene /// @param name The name of the field /// @param tokenStream The TokenStream with the content /// @param termVector Whether term vector should be stored - Field(const String& name, TokenStreamPtr tokenStream, TermVector termVector); + Field(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector); /// Create a stored field with binary value. Optionally the value may be compressed. /// @@ -132,7 +132,7 @@ namespace Lucene virtual void setValue(const String& value); /// Change the value of this field. - virtual void setValue(ReaderPtr value); + virtual void setValue(const ReaderPtr& value); /// Change the value of this field. virtual void setValue(ByteArray value); @@ -142,12 +142,12 @@ namespace Lucene /// Sets the token stream to be used for indexing and causes isIndexed() and isTokenized() to return /// true. May be combined with stored values from stringValue() or getBinaryValue() - virtual void setTokenStream(TokenStreamPtr tokenStream); + virtual void setTokenStream(const TokenStreamPtr& tokenStream); protected: void ConstructField(const String& name, const String& value, Store store, Index index, TermVector termVector); - void ConstructField(const String& name, ReaderPtr reader, TermVector termVector); - void ConstructField(const String& name, TokenStreamPtr tokenStream, TermVector termVector); + void ConstructField(const String& name, const ReaderPtr& reader, TermVector termVector); + void ConstructField(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector); void ConstructField(const String& name, ByteArray value, int32_t offset, int32_t length, Store store); }; } diff --git a/include/FieldCache.h b/include/FieldCache.h index 9de7e961..12ea2e36 100644 --- a/include/FieldCache.h +++ b/include/FieldCache.h @@ -70,7 +70,7 @@ namespace Lucene /// @param reader Used to get field values. /// @param field Which field contains the single byte values. /// @return The values in the given field for each document. - virtual Collection getBytes(IndexReaderPtr reader, const String& field); + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field); /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as bytes and returns an array of size reader.maxDoc() of the value each document has in @@ -79,7 +79,7 @@ namespace Lucene /// @param field Which field contains the bytes. /// @param parser Computes byte for string values. /// @return The values in the given field for each document. - virtual Collection getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser); + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser); /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as integers and returns an array of size reader.maxDoc() of the value each document has in @@ -87,7 +87,7 @@ namespace Lucene /// @param reader Used to get field values. /// @param field Which field contains the integers. /// @return The values in the given field for each document. - virtual Collection getInts(IndexReaderPtr reader, const String& field); + virtual Collection getInts(const IndexReaderPtr& reader, const String& field); /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as integers and returns an array of size reader.maxDoc() of the value each document has in @@ -96,7 +96,7 @@ namespace Lucene /// @param field Which field contains the integers. /// @param parser Computes integer for string values. /// @return The values in the given field for each document. - virtual Collection getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser); + virtual Collection getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser); /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as longs and returns an array of size reader.maxDoc() of the value each document has in @@ -104,7 +104,7 @@ namespace Lucene /// @param reader Used to get field values. /// @param field Which field contains the longs. /// @return The values in the given field for each document. - virtual Collection getLongs(IndexReaderPtr reader, const String& field); + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field); /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as longs and returns an array of size reader.maxDoc() of the value each document has in @@ -113,7 +113,7 @@ namespace Lucene /// @param field Which field contains the longs. /// @param parser Computes long for string values. /// @return The values in the given field for each document. - virtual Collection getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser); + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser); /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as integers and returns an array of size reader.maxDoc() of the value each document has in @@ -121,7 +121,7 @@ namespace Lucene /// @param reader Used to get field values. /// @param field Which field contains the doubles. /// @return The values in the given field for each document. - virtual Collection getDoubles(IndexReaderPtr reader, const String& field); + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field); /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in /// field as doubles and returns an array of size reader.maxDoc() of the value each document has in @@ -130,7 +130,7 @@ namespace Lucene /// @param field Which field contains the doubles. /// @param parser Computes double for string values. /// @return The values in the given field for each document. - virtual Collection getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser); + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser); /// Checks the internal cache for an appropriate entry, and if none are found, reads the term values in /// field and returns an array of size reader.maxDoc() containing the value each document has in @@ -138,7 +138,7 @@ namespace Lucene /// @param reader Used to get field values. /// @param field Which field contains the strings. /// @return The values in the given field for each document. - virtual Collection getStrings(IndexReaderPtr reader, const String& field); + virtual Collection getStrings(const IndexReaderPtr& reader, const String& field); /// Checks the internal cache for an appropriate entry, and if none are found reads the term values in /// field and returns an array of them in natural order, along with an array telling which element in @@ -146,7 +146,7 @@ namespace Lucene /// @param reader Used to get field values. /// @param field Which field contains the strings. /// @return Array of terms and index into the array for each document. - virtual StringIndexPtr getStringIndex(IndexReaderPtr reader, const String& field); + virtual StringIndexPtr getStringIndex(const IndexReaderPtr& reader, const String& field); /// Generates an array of CacheEntry objects representing all items currently in the FieldCache. virtual Collection getCacheEntries() = 0; @@ -159,11 +159,11 @@ namespace Lucene /// Drops all cache entries associated with this reader. NOTE: this reader must precisely match the reader /// that the cache entry is keyed on. If you pass a top-level reader, it usually will have no effect as /// Lucene now caches at the segment reader level. - virtual void purge(IndexReaderPtr r) = 0; + virtual void purge(const IndexReaderPtr& r) = 0; /// If non-null, FieldCacheImpl will warn whenever entries are created that are not sane according to /// {@link FieldCacheSanityChecker}. - virtual void setInfoStream(InfoStreamPtr stream); + virtual void setInfoStream(const InfoStreamPtr& stream); /// @see #setInfoStream virtual InfoStreamPtr getInfoStream(); diff --git a/include/FieldCacheImpl.h b/include/FieldCacheImpl.h index 5ac8ee80..b58f83b1 100644 --- a/include/FieldCacheImpl.h +++ b/include/FieldCacheImpl.h @@ -27,25 +27,25 @@ namespace Lucene public: virtual void initialize(); virtual void purgeAllCaches(); - virtual void purge(IndexReaderPtr r); + virtual void purge(const IndexReaderPtr& r); virtual Collection getCacheEntries(); - virtual Collection getBytes(IndexReaderPtr reader, const String& field); - virtual Collection getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser); + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field); + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser); - virtual Collection getInts(IndexReaderPtr reader, const String& field); - virtual Collection getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser); + virtual Collection getInts(const IndexReaderPtr& reader, const String& field); + virtual Collection getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser); - virtual Collection getLongs(IndexReaderPtr reader, const String& field); - virtual Collection getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser); + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field); + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser); - virtual Collection getDoubles(IndexReaderPtr reader, const String& field); - virtual Collection getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser); + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field); + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser); - virtual Collection getStrings(IndexReaderPtr reader, const String& field); - virtual StringIndexPtr getStringIndex(IndexReaderPtr reader, const String& field); + virtual Collection getStrings(const IndexReaderPtr& reader, const String& field); + virtual StringIndexPtr getStringIndex(const IndexReaderPtr& reader, const String& field); - virtual void setInfoStream(InfoStreamPtr stream); + virtual void setInfoStream(const InfoStreamPtr& stream); virtual InfoStreamPtr getInfoStream(); }; @@ -64,7 +64,7 @@ namespace Lucene public: /// Two of these are equal if they reference the same field and type. - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); /// Composes a hashcode based on the field and type. virtual int32_t hashCode(); @@ -74,7 +74,7 @@ namespace Lucene class Cache : public LuceneObject { public: - Cache(FieldCachePtr wrapper = FieldCachePtr()); + Cache(const FieldCachePtr& wrapper = FieldCachePtr()); virtual ~Cache(); LUCENE_CLASS(Cache); @@ -84,92 +84,92 @@ namespace Lucene WeakMapLuceneObjectMapEntryAny readerCache; protected: - virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key) = 0; + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key) = 0; public: /// Remove this reader from the cache, if present. - virtual void purge(IndexReaderPtr r); + virtual void purge(const IndexReaderPtr& r); - virtual boost::any get(IndexReaderPtr reader, EntryPtr key); - virtual void printNewInsanity(InfoStreamPtr infoStream, boost::any value); + virtual boost::any get(const IndexReaderPtr& reader, const EntryPtr& key); + virtual void printNewInsanity(const InfoStreamPtr& infoStream, boost::any value); }; class ByteCache : public Cache { public: - ByteCache(FieldCachePtr wrapper = FieldCachePtr()); + ByteCache(const FieldCachePtr& wrapper = FieldCachePtr()); virtual ~ByteCache(); LUCENE_CLASS(ByteCache); protected: - virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); }; class IntCache : public Cache { public: - IntCache(FieldCachePtr wrapper = FieldCachePtr()); + IntCache(const FieldCachePtr& wrapper = FieldCachePtr()); virtual ~IntCache(); LUCENE_CLASS(IntCache); protected: - virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); }; class LongCache : public Cache { public: - LongCache(FieldCachePtr wrapper = FieldCachePtr()); + LongCache(const FieldCachePtr& wrapper = FieldCachePtr()); virtual ~LongCache(); LUCENE_CLASS(LongCache); protected: - virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); }; class DoubleCache : public Cache { public: - DoubleCache(FieldCachePtr wrapper = FieldCachePtr()); + DoubleCache(const FieldCachePtr& wrapper = FieldCachePtr()); virtual ~DoubleCache(); LUCENE_CLASS(DoubleCache); protected: - virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); }; class StringCache : public Cache { public: - StringCache(FieldCachePtr wrapper = FieldCachePtr()); + StringCache(const FieldCachePtr& wrapper = FieldCachePtr()); virtual ~StringCache(); LUCENE_CLASS(StringCache); protected: - virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); }; class StringIndexCache : public Cache { public: - StringIndexCache(FieldCachePtr wrapper = FieldCachePtr()); + StringIndexCache(const FieldCachePtr& wrapper = FieldCachePtr()); virtual ~StringIndexCache(); LUCENE_CLASS(StringIndexCache); protected: - virtual boost::any createValue(IndexReaderPtr reader, EntryPtr key); + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); }; class FieldCacheEntryImpl : public FieldCacheEntry { public: - FieldCacheEntryImpl(LuceneObjectPtr readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value); + FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value); virtual ~FieldCacheEntryImpl(); LUCENE_CLASS(FieldCacheEntryImpl); diff --git a/include/FieldCacheRangeFilter.h b/include/FieldCacheRangeFilter.h index 85702a79..abdf4eee 100644 --- a/include/FieldCacheRangeFilter.h +++ b/include/FieldCacheRangeFilter.h @@ -38,7 +38,7 @@ namespace Lucene class LPPAPI FieldCacheRangeFilter : public Filter { public: - FieldCacheRangeFilter(const String& field, ParserPtr parser, bool includeLower, bool includeUpper); + FieldCacheRangeFilter(const String& field, const ParserPtr& parser, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilter(); LUCENE_CLASS(FieldCacheRangeFilter); @@ -62,7 +62,7 @@ namespace Lucene /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr)}. This /// works with all byte fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. - static FieldCacheRangeFilterPtr newByteRange(const String& field, ByteParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); + static FieldCacheRangeFilterPtr newByteRange(const String& field, const ByteParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String)}. This works with all /// int fields containing exactly one numeric term in the field. The range can be half-open by setting one of the @@ -72,7 +72,7 @@ namespace Lucene /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String, IntParserPtr)}. This /// works with all int fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. - static FieldCacheRangeFilterPtr newIntRange(const String& field, IntParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); + static FieldCacheRangeFilterPtr newIntRange(const String& field, const IntParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String)}. This works with all /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the @@ -82,7 +82,7 @@ namespace Lucene /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr)}. This /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. - static FieldCacheRangeFilterPtr newLongRange(const String& field, LongParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); + static FieldCacheRangeFilterPtr newLongRange(const String& field, const LongParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String)}. This works with all /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the @@ -92,10 +92,10 @@ namespace Lucene /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr)}. This /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by /// setting one of the values to null. - static FieldCacheRangeFilterPtr newDoubleRange(const String& field, DoubleParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); + static FieldCacheRangeFilterPtr newDoubleRange(const String& field, const DoubleParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); virtual String toString() = 0; - virtual bool equals(LuceneObjectPtr other) = 0; + virtual bool equals(const LuceneObjectPtr& other) = 0; virtual int32_t hashCode() = 0; /// Returns the field name for this filter diff --git a/include/FieldCacheSanityChecker.h b/include/FieldCacheSanityChecker.h index 7957b185..97276c7c 100644 --- a/include/FieldCacheSanityChecker.h +++ b/include/FieldCacheSanityChecker.h @@ -61,7 +61,7 @@ namespace Lucene /// Quick and dirty convenience method /// @see #check - static Collection checkSanity(FieldCachePtr cache); + static Collection checkSanity(const FieldCachePtr& cache); /// Quick and dirty convenience method that instantiates an instance with "good defaults" and uses it to /// test the CacheEntrys. @@ -89,7 +89,7 @@ namespace Lucene /// Checks if the seed is an IndexReader, and if so will walk the hierarchy of subReaders building up a /// list of the objects returned by obj.getFieldCacheKey() - Collection getAllDecendentReaderKeys(LuceneObjectPtr seed); + Collection getAllDecendentReaderKeys(const LuceneObjectPtr& seed); }; /// Simple container for a collection of related CacheEntry objects that in conjunction with each other diff --git a/include/FieldCacheSource.h b/include/FieldCacheSource.h index e3d52507..36a18a5b 100644 --- a/include/FieldCacheSource.h +++ b/include/FieldCacheSource.h @@ -38,20 +38,20 @@ namespace Lucene String field; public: - virtual DocValuesPtr getValues(IndexReaderPtr reader); + virtual DocValuesPtr getValues(const IndexReaderPtr& reader); virtual String description(); /// Return cached DocValues for input field and reader. /// @param cache FieldCache so that values of a field are loaded once per reader (RAM allowing) /// @param field Field for which values are required. /// @see ValueSource - virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) = 0; + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) = 0; - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); /// Check if equals to another {@link FieldCacheSource}, already knowing that cache and field are equal. - virtual bool cachedFieldSourceEquals(FieldCacheSourcePtr other) = 0; + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other) = 0; /// Return a hash code of a {@link FieldCacheSource}, without the hash-codes of the field and the cache /// (those are taken care of elsewhere). diff --git a/include/FieldCacheTermsFilter.h b/include/FieldCacheTermsFilter.h index 6e0b6d9f..e61eb549 100644 --- a/include/FieldCacheTermsFilter.h +++ b/include/FieldCacheTermsFilter.h @@ -58,7 +58,7 @@ namespace Lucene public: FieldCachePtr getFieldCache(); - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); }; } diff --git a/include/FieldComparator.h b/include/FieldComparator.h index 8c6b905a..a058104e 100644 --- a/include/FieldComparator.h +++ b/include/FieldComparator.h @@ -79,11 +79,11 @@ namespace Lucene /// /// @param reader current reader /// @param docBase docBase of this reader - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) = 0; + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) = 0; /// Sets the Scorer to use in case a document's score is needed. /// @param scorer Scorer instance that you should use to obtain the current hit's score, if necessary. - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); /// Return the actual value in the slot. /// @param slot the value @@ -143,7 +143,7 @@ namespace Lucene class LPPAPI ByteComparator : public NumericComparator { public: - ByteComparator(int32_t numHits, const String& field, ParserPtr parser); + ByteComparator(int32_t numHits, const String& field, const ParserPtr& parser); virtual ~ByteComparator(); LUCENE_CLASS(ByteComparator); @@ -152,7 +152,7 @@ namespace Lucene ByteParserPtr parser; public: - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); }; /// Sorts by ascending docID @@ -170,14 +170,14 @@ namespace Lucene public: virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); }; /// Parses field's values as double (using {@link FieldCache#getDoubles} and sorts by ascending value class LPPAPI DoubleComparator : public NumericComparator { public: - DoubleComparator(int32_t numHits, const String& field, ParserPtr parser); + DoubleComparator(int32_t numHits, const String& field, const ParserPtr& parser); virtual ~DoubleComparator(); LUCENE_CLASS(DoubleComparator); @@ -188,14 +188,14 @@ namespace Lucene public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); }; /// Parses field's values as int (using {@link FieldCache#getInts} and sorts by ascending value class LPPAPI IntComparator : public NumericComparator { public: - IntComparator(int32_t numHits, const String& field, ParserPtr parser); + IntComparator(int32_t numHits, const String& field, const ParserPtr& parser); virtual ~IntComparator(); LUCENE_CLASS(IntComparator); @@ -206,14 +206,14 @@ namespace Lucene public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); }; /// Parses field's values as long (using {@link FieldCache#getLongs} and sorts by ascending value class LPPAPI LongComparator : public NumericComparator { public: - LongComparator(int32_t numHits, const String& field, ParserPtr parser); + LongComparator(int32_t numHits, const String& field, const ParserPtr& parser); virtual ~LongComparator(); LUCENE_CLASS(LongComparator); @@ -224,7 +224,7 @@ namespace Lucene public: virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); }; /// Sorts by descending relevance. NOTE: if you are sorting only by descending relevance and then secondarily @@ -245,8 +245,8 @@ namespace Lucene virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setScorer(ScorerPtr scorer); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); }; /// Sorts by a field's value using the Collator for a given Locale. @@ -269,7 +269,7 @@ namespace Lucene virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); virtual void setBottom(int32_t slot); virtual ComparableValue value(int32_t slot); }; @@ -307,7 +307,7 @@ namespace Lucene virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); virtual void setBottom(int32_t slot); virtual ComparableValue value(int32_t slot); virtual Collection getValues(); @@ -339,7 +339,7 @@ namespace Lucene virtual int32_t compare(int32_t slot1, int32_t slot2); virtual int32_t compareBottom(int32_t doc); virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); virtual void setBottom(int32_t slot); virtual ComparableValue value(int32_t slot); }; diff --git a/include/FieldInfo.h b/include/FieldInfo.h index deff6480..ba3f491e 100644 --- a/include/FieldInfo.h +++ b/include/FieldInfo.h @@ -36,7 +36,7 @@ namespace Lucene bool storePayloads; // whether this field stores payloads together with term positions public: - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); void update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); diff --git a/include/FieldInfos.h b/include/FieldInfos.h index aa6e8977..458e38de 100644 --- a/include/FieldInfos.h +++ b/include/FieldInfos.h @@ -23,7 +23,7 @@ namespace Lucene /// Construct a FieldInfos object using the directory and the name of the file IndexInput /// @param d The directory to open the IndexInput from /// @param name The name of the file to open the IndexInput from in the Directory - FieldInfos(DirectoryPtr d, const String& name); + FieldInfos(const DirectoryPtr& d, const String& name); virtual ~FieldInfos(); @@ -53,10 +53,10 @@ namespace Lucene public: /// Returns a deep clone of this FieldInfos instance. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Adds field info for a Document. - void add(DocumentPtr doc); + void add(const DocumentPtr& doc); /// Returns true if any fields do not omitTermFreqAndPositions bool hasProx(); @@ -137,14 +137,14 @@ namespace Lucene bool hasVectors(); - void write(DirectoryPtr d, const String& name); - void write(IndexOutputPtr output); + void write(const DirectoryPtr& d, const String& name); + void write(const IndexOutputPtr& output); protected: FieldInfoPtr addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); - void read(IndexInputPtr input, const String& fileName); + void read(const IndexInputPtr& input, const String& fileName); }; } diff --git a/include/FieldMaskingSpanQuery.h b/include/FieldMaskingSpanQuery.h index 09fb1f6b..fc162918 100644 --- a/include/FieldMaskingSpanQuery.h +++ b/include/FieldMaskingSpanQuery.h @@ -52,7 +52,7 @@ namespace Lucene class LPPAPI FieldMaskingSpanQuery : public SpanQuery { public: - FieldMaskingSpanQuery(SpanQueryPtr maskedQuery, const String& maskedField); + FieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField); virtual ~FieldMaskingSpanQuery(); LUCENE_CLASS(FieldMaskingSpanQuery); @@ -66,18 +66,18 @@ namespace Lucene virtual String getField(); SpanQueryPtr getMaskedQuery(); - virtual SpansPtr getSpans(IndexReaderPtr reader); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); virtual void extractTerms(SetTerm terms); - virtual WeightPtr createWeight(SearcherPtr searcher); - virtual SimilarityPtr getSimilarity(SearcherPtr searcher); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual WeightPtr createWeight(const SearcherPtr& searcher); + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); /// Returns a clone of this query. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/FieldValueHitQueue.h b/include/FieldValueHitQueue.h index 4ba1f33a..a38c69b7 100644 --- a/include/FieldValueHitQueue.h +++ b/include/FieldValueHitQueue.h @@ -48,7 +48,7 @@ namespace Lucene /// @param entry The Entry used to create a FieldDoc /// @return The newly created FieldDoc /// @see Searchable#search(WeightPtr, FilterPtr, int32_t, SortPtr) - FieldDocPtr fillFields(FieldValueHitQueueEntryPtr entry); + FieldDocPtr fillFields(const FieldValueHitQueueEntryPtr& entry); /// Returns the SortFields being used by this hit queue. Collection getFields(); diff --git a/include/FieldsReader.h b/include/FieldsReader.h index 94500c0a..15227bc8 100644 --- a/include/FieldsReader.h +++ b/include/FieldsReader.h @@ -17,10 +17,10 @@ namespace Lucene { public: /// Used only by clone - FieldsReader(FieldInfosPtr fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, int32_t formatSize, - int32_t docStoreOffset, IndexInputPtr cloneableFieldsStream, IndexInputPtr cloneableIndexStream); - FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn); - FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); + FieldsReader(const FieldInfosPtr& fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, int32_t formatSize, + int32_t docStoreOffset, const IndexInputPtr& cloneableFieldsStream, const IndexInputPtr& cloneableIndexStream); + FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn); + FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); virtual ~FieldsReader(); @@ -53,7 +53,7 @@ namespace Lucene public: /// Returns a cloned FieldsReader that shares open IndexInputs with the original one. It is the caller's job not to /// close the original FieldsReader until all clones are called (eg, currently SegmentReader manages this logic). - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Closes the underlying {@link IndexInput} streams, including any ones associated with a lazy implementation of a /// Field. This means that the Fields values will not be accessible. @@ -63,14 +63,14 @@ namespace Lucene bool canReadRawDocs(); - DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector); + DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); /// Returns the length in bytes of each raw document in a contiguous range of length numDocs starting with startDocID. /// Returns the IndexInput (the fieldStream), already seeked to the starting point for startDocID. IndexInputPtr rawDocs(Collection lengths, int32_t startDocID, int32_t numDocs); protected: - void ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); + void ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); void ensureOpen(); @@ -81,13 +81,13 @@ namespace Lucene void skipField(bool binary, bool compressed); void skipField(bool binary, bool compressed, int32_t toRead); - void addFieldLazy(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize); - void addField(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize); + void addFieldLazy(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize); + void addField(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize); /// Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes). /// Read just the size - caller must skip the field content to continue reading fields. Return the size in bytes or chars, /// depending on field type. - int32_t addFieldSize(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed); + int32_t addFieldSize(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed); ByteArray uncompress(ByteArray b); String uncompressString(ByteArray b); @@ -98,8 +98,8 @@ namespace Lucene class LazyField : public AbstractField { public: - LazyField(FieldsReaderPtr reader, const String& name, Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); - LazyField(FieldsReaderPtr reader, const String& name, Store store, Index index, TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); + LazyField(const FieldsReaderPtr& reader, const String& name, Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); + LazyField(const FieldsReaderPtr& reader, const String& name, Store store, Index index, TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); virtual ~LazyField(); LUCENE_CLASS(LazyField); diff --git a/include/FieldsWriter.h b/include/FieldsWriter.h index 87bb5f1c..f5884864 100644 --- a/include/FieldsWriter.h +++ b/include/FieldsWriter.h @@ -14,8 +14,8 @@ namespace Lucene class FieldsWriter : public LuceneObject { public: - FieldsWriter(DirectoryPtr d, const String& segment, FieldInfosPtr fn); - FieldsWriter(IndexOutputPtr fdx, IndexOutputPtr fdt, FieldInfosPtr fn); + FieldsWriter(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn); + FieldsWriter(const IndexOutputPtr& fdx, const IndexOutputPtr& fdt, const FieldInfosPtr& fn); virtual ~FieldsWriter(); LUCENE_CLASS(FieldsWriter); @@ -40,22 +40,22 @@ namespace Lucene static const int32_t FORMAT_CURRENT; public: - void setFieldsStream(IndexOutputPtr stream); + void setFieldsStream(const IndexOutputPtr& stream); /// Writes the contents of buffer into the fields stream and adds a new entry for this document into the index /// stream. This assumes the buffer was already written in the correct fields format. - void flushDocument(int32_t numStoredFields, RAMOutputStreamPtr buffer); + void flushDocument(int32_t numStoredFields, const RAMOutputStreamPtr& buffer); void skipDocument(); void flush(); void close(); - void writeField(FieldInfoPtr fi, FieldablePtr field); + void writeField(const FieldInfoPtr& fi, const FieldablePtr& field); /// Bulk write a contiguous series of documents. The lengths array is the length (in bytes) of each raw document. /// The stream IndexInput is the fieldsStream from which we should bulk-copy all bytes. - void addRawDocuments(IndexInputPtr stream, Collection lengths, int32_t numDocs); + void addRawDocuments(const IndexInputPtr& stream, Collection lengths, int32_t numDocs); - void addDocument(DocumentPtr doc); + void addDocument(const DocumentPtr& doc); }; } diff --git a/include/FileSwitchDirectory.h b/include/FileSwitchDirectory.h index f37942d8..da5c7c28 100644 --- a/include/FileSwitchDirectory.h +++ b/include/FileSwitchDirectory.h @@ -21,7 +21,7 @@ namespace Lucene class LPPAPI FileSwitchDirectory : public Directory { public: - FileSwitchDirectory(HashSet primaryExtensions, DirectoryPtr primaryDir, DirectoryPtr secondaryDir, bool doClose); + FileSwitchDirectory(HashSet primaryExtensions, const DirectoryPtr& primaryDir, const DirectoryPtr& secondaryDir, bool doClose); virtual ~FileSwitchDirectory(); LUCENE_CLASS(FileSwitchDirectory); diff --git a/include/Filter.h b/include/Filter.h index 2a25b7c2..f8e1acab 100644 --- a/include/Filter.h +++ b/include/Filter.h @@ -33,7 +33,7 @@ namespace Lucene /// results. NOTE: null can be returned if no documents will be accepted by this Filter. /// /// @see DocIdBitSet - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) = 0; + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) = 0; }; } diff --git a/include/FilterIndexReader.h b/include/FilterIndexReader.h index fd2fd7b8..7a78f6ca 100644 --- a/include/FilterIndexReader.h +++ b/include/FilterIndexReader.h @@ -26,7 +26,7 @@ namespace Lucene /// /// Note that base reader is closed if this FilterIndexReader is closed. /// @param in specified base reader. - FilterIndexReader(IndexReaderPtr in); + FilterIndexReader(const IndexReaderPtr& in); virtual ~FilterIndexReader(); @@ -39,21 +39,21 @@ namespace Lucene virtual DirectoryPtr directory(); virtual Collection getTermFreqVectors(int32_t docNumber); virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); - virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); virtual int32_t numDocs(); virtual int32_t maxDoc(); - virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); virtual bool isDeleted(int32_t n); virtual bool hasDeletions(); virtual bool hasNorms(const String& field); virtual ByteArray norms(const String& field); virtual void norms(const String& field, ByteArray norms, int32_t offset); virtual TermEnumPtr terms(); - virtual TermEnumPtr terms(TermPtr t); - virtual int32_t docFreq(TermPtr t); + virtual TermEnumPtr terms(const TermPtr& t); + virtual int32_t docFreq(const TermPtr& t); virtual TermDocsPtr termDocs(); - virtual TermDocsPtr termDocs(TermPtr term); + virtual TermDocsPtr termDocs(const TermPtr& term); virtual TermPositionsPtr termPositions(); virtual HashSet getFieldNames(FieldOption fieldOption); virtual int64_t getVersion(); @@ -81,7 +81,7 @@ namespace Lucene class LPPAPI FilterTermDocs : public TermPositions, public LuceneObject { public: - FilterTermDocs(TermDocsPtr in); + FilterTermDocs(const TermDocsPtr& in); virtual ~FilterTermDocs(); LUCENE_CLASS(FilterTermDocs); @@ -90,8 +90,8 @@ namespace Lucene TermDocsPtr in; public: - virtual void seek(TermPtr term); - virtual void seek(TermEnumPtr termEnum); + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); virtual int32_t doc(); virtual int32_t freq(); virtual bool next(); @@ -104,7 +104,7 @@ namespace Lucene class LPPAPI FilterTermPositions : public FilterTermDocs { public: - FilterTermPositions(TermPositionsPtr in); + FilterTermPositions(const TermPositionsPtr& in); virtual ~FilterTermPositions(); LUCENE_CLASS(FilterTermPositions); @@ -120,7 +120,7 @@ namespace Lucene class LPPAPI FilterTermEnum : public TermEnum { public: - FilterTermEnum(TermEnumPtr in); + FilterTermEnum(const TermEnumPtr& in); virtual ~FilterTermEnum(); LUCENE_CLASS(FilterTermEnum); diff --git a/include/FilterManager.h b/include/FilterManager.h index 01ff9726..692153f1 100644 --- a/include/FilterManager.h +++ b/include/FilterManager.h @@ -62,7 +62,7 @@ namespace Lucene /// keep a persistent version around and allow the caching filter to do its job. /// @param filter The input filter /// @return The cached version of the filter - FilterPtr getFilter(FilterPtr filter); + FilterPtr getFilter(const FilterPtr& filter); friend class FilterCleaner; }; diff --git a/include/FilteredDocIdSet.h b/include/FilteredDocIdSet.h index 5075e068..8b498bc5 100644 --- a/include/FilteredDocIdSet.h +++ b/include/FilteredDocIdSet.h @@ -24,7 +24,7 @@ namespace Lucene { public: /// @param innerSet Underlying DocIdSet - FilteredDocIdSet(DocIdSetPtr innerSet); + FilteredDocIdSet(const DocIdSetPtr& innerSet); virtual ~FilteredDocIdSet(); LUCENE_CLASS(FilteredDocIdSet); diff --git a/include/FilteredDocIdSetIterator.h b/include/FilteredDocIdSetIterator.h index 9782fe75..64761cb9 100644 --- a/include/FilteredDocIdSetIterator.h +++ b/include/FilteredDocIdSetIterator.h @@ -17,7 +17,7 @@ namespace Lucene { public: /// @param innerIter Underlying DocIdSetIterator. - FilteredDocIdSetIterator(DocIdSetIteratorPtr innerIter); + FilteredDocIdSetIterator(const DocIdSetIteratorPtr& innerIter); virtual ~FilteredDocIdSetIterator(); LUCENE_CLASS(FilteredDocIdSetIterator); diff --git a/include/FilteredQuery.h b/include/FilteredQuery.h index 0d3a4220..32c5af4b 100644 --- a/include/FilteredQuery.h +++ b/include/FilteredQuery.h @@ -24,7 +24,7 @@ namespace Lucene /// Filter::getDocIdSet() will be called every time this query is used in a search. /// @param query Query to be filtered, cannot be null. /// @param filter Filter to apply to query results, cannot be null. - FilteredQuery(QueryPtr query, FilterPtr filter); + FilteredQuery(const QueryPtr& query, const FilterPtr& filter); virtual ~FilteredQuery(); @@ -39,10 +39,10 @@ namespace Lucene /// Returns a Weight that applies the filter to the enclosed query's Weight. /// This is accomplished by overriding the Scorer returned by the Weight. - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); /// Rewrites the wrapped query. - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); QueryPtr getQuery(); FilterPtr getFilter(); @@ -52,9 +52,9 @@ namespace Lucene /// Prints a user-readable version of this query. virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); friend class FilteredQueryWeight; }; diff --git a/include/FilteredTermEnum.h b/include/FilteredTermEnum.h index 9f4f1ae3..c3d7d858 100644 --- a/include/FilteredTermEnum.h +++ b/include/FilteredTermEnum.h @@ -48,14 +48,14 @@ namespace Lucene protected: /// Equality compare on the term - virtual bool termCompare(TermPtr term) = 0; + virtual bool termCompare(const TermPtr& term) = 0; /// Indicates the end of the enumeration has been reached virtual bool endEnum() = 0; /// Use this method to set the actual TermEnum (eg. in ctor), it will be automatically positioned /// on the first matching term. - virtual void setEnum(TermEnumPtr actualEnum); + virtual void setEnum(const TermEnumPtr& actualEnum); }; } diff --git a/include/FlagsAttribute.h b/include/FlagsAttribute.h index 70de4ac2..974b8cf9 100644 --- a/include/FlagsAttribute.h +++ b/include/FlagsAttribute.h @@ -37,10 +37,10 @@ namespace Lucene virtual void clear(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual void copyTo(AttributePtr target); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/FormatPostingsDocsWriter.h b/include/FormatPostingsDocsWriter.h index 0f33c123..9b97d213 100644 --- a/include/FormatPostingsDocsWriter.h +++ b/include/FormatPostingsDocsWriter.h @@ -15,7 +15,7 @@ namespace Lucene class FormatPostingsDocsWriter : public FormatPostingsDocsConsumer { public: - FormatPostingsDocsWriter(SegmentWriteStatePtr state, FormatPostingsTermsWriterPtr parent); + FormatPostingsDocsWriter(const SegmentWriteStatePtr& state, const FormatPostingsTermsWriterPtr& parent); virtual ~FormatPostingsDocsWriter(); LUCENE_CLASS(FormatPostingsDocsWriter); @@ -43,7 +43,7 @@ namespace Lucene public: virtual void initialize(); - void setField(FieldInfoPtr fieldInfo); + void setField(const FieldInfoPtr& fieldInfo); /// Adds a new doc in this term. If this returns null then we just skip consuming positions/payloads. virtual FormatPostingsPositionsConsumerPtr addDoc(int32_t docID, int32_t termDocFreq); diff --git a/include/FormatPostingsFieldsConsumer.h b/include/FormatPostingsFieldsConsumer.h index 6f6cc7e5..51ba9c77 100644 --- a/include/FormatPostingsFieldsConsumer.h +++ b/include/FormatPostingsFieldsConsumer.h @@ -22,7 +22,7 @@ namespace Lucene public: /// Add a new field. - virtual FormatPostingsTermsConsumerPtr addField(FieldInfoPtr field) = 0; + virtual FormatPostingsTermsConsumerPtr addField(const FieldInfoPtr& field) = 0; /// Called when we are done adding everything. virtual void finish() = 0; diff --git a/include/FormatPostingsFieldsWriter.h b/include/FormatPostingsFieldsWriter.h index a4a57ad5..883ca365 100644 --- a/include/FormatPostingsFieldsWriter.h +++ b/include/FormatPostingsFieldsWriter.h @@ -14,7 +14,7 @@ namespace Lucene class FormatPostingsFieldsWriter : public FormatPostingsFieldsConsumer { public: - FormatPostingsFieldsWriter(SegmentWriteStatePtr state, FieldInfosPtr fieldInfos); + FormatPostingsFieldsWriter(const SegmentWriteStatePtr& state, const FieldInfosPtr& fieldInfos); virtual ~FormatPostingsFieldsWriter(); LUCENE_CLASS(FormatPostingsFieldsWriter); @@ -33,7 +33,7 @@ namespace Lucene virtual void initialize(); /// Add a new field. - virtual FormatPostingsTermsConsumerPtr addField(FieldInfoPtr field); + virtual FormatPostingsTermsConsumerPtr addField(const FieldInfoPtr& field); /// Called when we are done adding everything. virtual void finish(); diff --git a/include/FormatPostingsPositionsWriter.h b/include/FormatPostingsPositionsWriter.h index c1410b9b..729e73ba 100644 --- a/include/FormatPostingsPositionsWriter.h +++ b/include/FormatPostingsPositionsWriter.h @@ -14,7 +14,7 @@ namespace Lucene class FormatPostingsPositionsWriter : public FormatPostingsPositionsConsumer { public: - FormatPostingsPositionsWriter(SegmentWriteStatePtr state, FormatPostingsDocsWriterPtr parent); + FormatPostingsPositionsWriter(const SegmentWriteStatePtr& state, const FormatPostingsDocsWriterPtr& parent); virtual ~FormatPostingsPositionsWriter(); LUCENE_CLASS(FormatPostingsPositionsWriter); @@ -33,7 +33,7 @@ namespace Lucene /// Add a new position & payload virtual void addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength); - void setField(FieldInfoPtr fieldInfo); + void setField(const FieldInfoPtr& fieldInfo); /// Called when we are done adding positions & payloads virtual void finish(); diff --git a/include/FormatPostingsTermsWriter.h b/include/FormatPostingsTermsWriter.h index 3df0f5eb..f24e2eab 100644 --- a/include/FormatPostingsTermsWriter.h +++ b/include/FormatPostingsTermsWriter.h @@ -14,7 +14,7 @@ namespace Lucene class FormatPostingsTermsWriter : public FormatPostingsTermsConsumer { public: - FormatPostingsTermsWriter(SegmentWriteStatePtr state, FormatPostingsFieldsWriterPtr parent); + FormatPostingsTermsWriter(const SegmentWriteStatePtr& state, const FormatPostingsFieldsWriterPtr& parent); virtual ~FormatPostingsTermsWriter(); LUCENE_CLASS(FormatPostingsTermsWriter); @@ -35,7 +35,7 @@ namespace Lucene public: virtual void initialize(); - void setField(FieldInfoPtr fieldInfo); + void setField(const FieldInfoPtr& fieldInfo); /// Adds a new term in this field virtual FormatPostingsDocsConsumerPtr addTerm(CharArray text, int32_t start); diff --git a/include/FreqProxFieldMergeState.h b/include/FreqProxFieldMergeState.h index c5ced70d..ed9a8f69 100644 --- a/include/FreqProxFieldMergeState.h +++ b/include/FreqProxFieldMergeState.h @@ -15,7 +15,7 @@ namespace Lucene class FreqProxFieldMergeState : public LuceneObject { public: - FreqProxFieldMergeState(FreqProxTermsWriterPerFieldPtr field); + FreqProxFieldMergeState(const FreqProxTermsWriterPerFieldPtr& field); virtual ~FreqProxFieldMergeState(); LUCENE_CLASS(FreqProxFieldMergeState); diff --git a/include/FreqProxTermsWriter.h b/include/FreqProxTermsWriter.h index 12dcb163..64e70e8e 100644 --- a/include/FreqProxTermsWriter.h +++ b/include/FreqProxTermsWriter.h @@ -23,15 +23,15 @@ namespace Lucene ByteArray payloadBuffer; public: - virtual TermsHashConsumerPerThreadPtr addThread(TermsHashPerThreadPtr perThread); + virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread); virtual void createPostings(Collection postings, int32_t start, int32_t count); - virtual void closeDocStore(SegmentWriteStatePtr state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); virtual void abort(); - virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state); + virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); /// Walk through all unique text tokens (Posting instances) found in this field and serialize them /// into a single RAM segment. - void appendPostings(Collection fields, FormatPostingsFieldsConsumerPtr consumer); + void appendPostings(Collection fields, const FormatPostingsFieldsConsumerPtr& consumer); virtual int32_t bytesPerPosting(); diff --git a/include/FreqProxTermsWriterPerField.h b/include/FreqProxTermsWriterPerField.h index 844eaac8..3ceef1e2 100644 --- a/include/FreqProxTermsWriterPerField.h +++ b/include/FreqProxTermsWriterPerField.h @@ -14,7 +14,7 @@ namespace Lucene class FreqProxTermsWriterPerField : public TermsHashConsumerPerField { public: - FreqProxTermsWriterPerField(TermsHashPerFieldPtr termsHashPerField, FreqProxTermsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo); + FreqProxTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const FreqProxTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); virtual ~FreqProxTermsWriterPerField(); LUCENE_CLASS(FreqProxTermsWriterPerField); @@ -33,13 +33,13 @@ namespace Lucene virtual int32_t getStreamCount(); virtual void finish(); virtual void skippingLongTerm(); - virtual int32_t compareTo(LuceneObjectPtr other); + virtual int32_t compareTo(const LuceneObjectPtr& other); void reset(); virtual bool start(Collection fields, int32_t count); - virtual void start(FieldablePtr field); - void writeProx(FreqProxTermsWriterPostingListPtr p, int32_t proxCode); - virtual void newTerm(RawPostingListPtr p); - virtual void addTerm(RawPostingListPtr p); + virtual void start(const FieldablePtr& field); + void writeProx(const FreqProxTermsWriterPostingListPtr& p, int32_t proxCode); + virtual void newTerm(const RawPostingListPtr& p); + virtual void addTerm(const RawPostingListPtr& p); void abort(); }; } diff --git a/include/FreqProxTermsWriterPerThread.h b/include/FreqProxTermsWriterPerThread.h index 0bb3d119..960b969a 100644 --- a/include/FreqProxTermsWriterPerThread.h +++ b/include/FreqProxTermsWriterPerThread.h @@ -14,7 +14,7 @@ namespace Lucene class FreqProxTermsWriterPerThread : public TermsHashConsumerPerThread { public: - FreqProxTermsWriterPerThread(TermsHashPerThreadPtr perThread); + FreqProxTermsWriterPerThread(const TermsHashPerThreadPtr& perThread); virtual ~FreqProxTermsWriterPerThread(); LUCENE_CLASS(FreqProxTermsWriterPerThread); @@ -24,7 +24,7 @@ namespace Lucene DocStatePtr docState; public: - virtual TermsHashConsumerPerFieldPtr addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo); + virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo); virtual void startDocument(); virtual DocWriterPtr finishDocument(); virtual void abort(); diff --git a/include/FuzzyQuery.h b/include/FuzzyQuery.h index 011701e8..bd3f4b05 100644 --- a/include/FuzzyQuery.h +++ b/include/FuzzyQuery.h @@ -27,9 +27,9 @@ namespace Lucene /// length as the query term is considered similar to the query term if the edit distance between /// both terms is less than length(term) * 0.5 /// @param prefixLength Length of common (non-fuzzy) prefix - FuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength); - FuzzyQuery(TermPtr term, double minimumSimilarity); - FuzzyQuery(TermPtr term); + FuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); + FuzzyQuery(const TermPtr& term, double minimumSimilarity); + FuzzyQuery(const TermPtr& term); virtual ~FuzzyQuery(); @@ -60,18 +60,18 @@ namespace Lucene /// Returns the pattern term. TermPtr getTerm(); - virtual void setRewriteMethod(RewriteMethodPtr method); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual void setRewriteMethod(const RewriteMethodPtr& method); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual String toString(const String& field); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); protected: - void ConstructQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength); + void ConstructQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); - virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); }; } diff --git a/include/FuzzyTermEnum.h b/include/FuzzyTermEnum.h index bf3dcfdf..4a7afe67 100644 --- a/include/FuzzyTermEnum.h +++ b/include/FuzzyTermEnum.h @@ -27,9 +27,9 @@ namespace Lucene /// @param term Pattern term. /// @param minSimilarity Minimum required similarity for terms from the reader. Default value is 0.5. /// @param prefixLength Length of required common prefix. Default value is 0. - FuzzyTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity, int32_t prefixLength); - FuzzyTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity); - FuzzyTermEnum(IndexReaderPtr reader, TermPtr term); + FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength); + FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity); + FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term); virtual ~FuzzyTermEnum(); @@ -57,11 +57,11 @@ namespace Lucene virtual void close(); protected: - void ConstructTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity, int32_t prefixLength); + void ConstructTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength); /// The termCompare method in FuzzyTermEnum uses Levenshtein distance to calculate the distance between /// the given term and the comparing term. - virtual bool termCompare(TermPtr term); + virtual bool termCompare(const TermPtr& term); /// /// Compute Levenshtein distance diff --git a/include/HitQueueBase.h b/include/HitQueueBase.h index 6298fa58..145733da 100644 --- a/include/HitQueueBase.h +++ b/include/HitQueueBase.h @@ -20,8 +20,8 @@ namespace Lucene LUCENE_CLASS(HitQueueBase); public: - virtual ScoreDocPtr add(ScoreDocPtr scoreDoc); - virtual ScoreDocPtr addOverflow(ScoreDocPtr scoreDoc); + virtual ScoreDocPtr add(const ScoreDocPtr& scoreDoc); + virtual ScoreDocPtr addOverflow(const ScoreDocPtr& scoreDoc); virtual ScoreDocPtr top(); virtual ScoreDocPtr pop(); virtual ScoreDocPtr updateTop(); @@ -46,7 +46,7 @@ namespace Lucene class LPPAPI PriorityQueueScoreDocs : public PriorityQueue { public: - PriorityQueueScoreDocs(HitQueueBasePtr hitQueue, int32_t size); + PriorityQueueScoreDocs(const HitQueueBasePtr& hitQueue, int32_t size); virtual ~PriorityQueueScoreDocs(); LUCENE_CLASS(PriorityQueueScoreDocs); diff --git a/include/ISOLatin1AccentFilter.h b/include/ISOLatin1AccentFilter.h index d24d816f..d55dcc36 100644 --- a/include/ISOLatin1AccentFilter.h +++ b/include/ISOLatin1AccentFilter.h @@ -21,7 +21,7 @@ namespace Lucene class LPPAPI ISOLatin1AccentFilter : public TokenFilter { public: - ISOLatin1AccentFilter(TokenStreamPtr input); + ISOLatin1AccentFilter(const TokenStreamPtr& input); virtual ~ISOLatin1AccentFilter(); LUCENE_CLASS(ISOLatin1AccentFilter); diff --git a/include/IndexCommit.h b/include/IndexCommit.h index b03cc2fb..1df1d098 100644 --- a/include/IndexCommit.h +++ b/include/IndexCommit.h @@ -52,7 +52,7 @@ namespace Lucene virtual bool isOptimized() = 0; /// Two IndexCommits are equal if both their Directory and versions are equal. - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); diff --git a/include/IndexFileDeleter.h b/include/IndexFileDeleter.h index 626e6b33..96f2cf99 100644 --- a/include/IndexFileDeleter.h +++ b/include/IndexFileDeleter.h @@ -36,7 +36,7 @@ namespace Lucene public: /// Initialize the deleter: find all previous commits in the Directory, incref the files they reference, call /// the policy to let it delete commits. This will remove any files not referenced by any of the commits. - IndexFileDeleter(DirectoryPtr directory, IndexDeletionPolicyPtr policy, SegmentInfosPtr segmentInfos, InfoStreamPtr infoStream, DocumentsWriterPtr docWriter, HashSet synced); + IndexFileDeleter(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& policy, const SegmentInfosPtr& segmentInfos, const InfoStreamPtr& infoStream, const DocumentsWriterPtr& docWriter, HashSet synced); virtual ~IndexFileDeleter(); LUCENE_CLASS(IndexFileDeleter); @@ -85,7 +85,7 @@ namespace Lucene RefCountPtr getRefCount(const String& fileName); public: - void setInfoStream(InfoStreamPtr infoStream); + void setInfoStream(const InfoStreamPtr& infoStream); SegmentInfosPtr getLastSegmentInfos(); @@ -108,14 +108,14 @@ namespace Lucene /// /// If this is a commit, we also call the policy to give it a chance to remove other commits. If any /// commits are removed, we decref their files as well. - void checkpoint(SegmentInfosPtr segmentInfos, bool isCommit); + void checkpoint(const SegmentInfosPtr& segmentInfos, bool isCommit); - void incRef(SegmentInfosPtr segmentInfos, bool isCommit); + void incRef(const SegmentInfosPtr& segmentInfos, bool isCommit); void incRef(HashSet files); void incRef(const String& fileName); void decRef(HashSet files); void decRef(const String& fileName); - void decRef(SegmentInfosPtr segmentInfos); + void decRef(const SegmentInfosPtr& segmentInfos); bool exists(const String& fileName); @@ -151,7 +151,7 @@ namespace Lucene class CommitPoint : public IndexCommit { public: - CommitPoint(Collection commitsToDelete, DirectoryPtr directory, SegmentInfosPtr segmentInfos); + CommitPoint(Collection commitsToDelete, const DirectoryPtr& directory, const SegmentInfosPtr& segmentInfos); virtual ~CommitPoint(); LUCENE_CLASS(CommitPoint); @@ -197,7 +197,7 @@ namespace Lucene virtual bool isDeleted(); - virtual int32_t compareTo(LuceneObjectPtr other); + virtual int32_t compareTo(const LuceneObjectPtr& other); }; } diff --git a/include/IndexInput.h b/include/IndexInput.h index 964545ba..e25a78c7 100644 --- a/include/IndexInput.h +++ b/include/IndexInput.h @@ -114,7 +114,7 @@ namespace Lucene /// /// Subclasses must ensure that clones may be positioned at different points /// in the input from each other and from the stream they were cloned from. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Read string map as a series of key/value pairs. virtual MapStringString readStringStringMap(); diff --git a/include/IndexOutput.h b/include/IndexOutput.h index edcdfd15..b1e02397 100644 --- a/include/IndexOutput.h +++ b/include/IndexOutput.h @@ -90,7 +90,7 @@ namespace Lucene void writeChars(const String& s, int32_t start, int32_t length); /// Copy numBytes bytes from input to ourself. - void copyBytes(IndexInputPtr input, int64_t numBytes); + void copyBytes(const IndexInputPtr& input, int64_t numBytes); /// Set the file length. By default, this method does nothing (it's optional for a Directory to implement it). /// But, certain Directory implementations (for example @see FSDirectory) can use this to inform the underlying IO diff --git a/include/IndexReader.h b/include/IndexReader.h index 80353db3..f9d1a36a 100644 --- a/include/IndexReader.h +++ b/include/IndexReader.h @@ -98,21 +98,21 @@ namespace Lucene /// Returns a IndexReader reading the index in the given Directory, with readOnly = true. /// @param directory the index directory - static IndexReaderPtr open(DirectoryPtr directory); + static IndexReaderPtr open(const DirectoryPtr& directory); /// Returns an IndexReader reading the index in the given Directory. You should pass readOnly = true, since it /// gives much better concurrent performance, unless you intend to do write operations (delete documents or change /// norms) with the reader. /// @param directory the index directory /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(DirectoryPtr directory, bool readOnly); + static IndexReaderPtr open(const DirectoryPtr& directory, bool readOnly); /// Returns an IndexReader reading the index in the given {@link IndexCommit}. You should pass readOnly = true, /// since it gives much better concurrent performance, unless you intend to do write operations (delete documents /// or change norms) with the reader. /// @param commit the commit point to open /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(IndexCommitPtr commit, bool readOnly); + static IndexReaderPtr open(const IndexCommitPtr& commit, bool readOnly); /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write @@ -121,7 +121,7 @@ namespace Lucene /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform /// deletes or to set norms); see {@link IndexWriter} for details. /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly); + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly); /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write @@ -136,7 +136,7 @@ namespace Lucene /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. The /// default value is 1. Set this to -1 to skip loading the terms index entirely. - static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom /// {@link IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, @@ -146,7 +146,7 @@ namespace Lucene /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform /// deletes or to set norms); see {@link IndexWriter} for details. /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly); + static IndexReaderPtr open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly); /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom {@link /// IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, unless @@ -161,7 +161,7 @@ namespace Lucene /// be set per reader. When set to N, then one in every N * termIndexInterval terms in the index is loaded into /// memory. By setting this to a value > 1 you can reduce memory usage, at the expense of higher latency when loading /// a TermInfo. The default value is 1. Set this to -1 to skip loading the terms index entirely. - static IndexReaderPtr open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); + static IndexReaderPtr open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); /// Refreshes an IndexReader if the index has changed since this instance was (re)opened. /// @@ -205,7 +205,7 @@ namespace Lucene /// Reopen this reader on a specific commit point. This always returns a readOnly reader. If the specified commit /// point matches what this reader is already on, and this reader is already readOnly, then this same instance is /// returned; if it is not already readOnly, a readOnly clone is returned. - virtual IndexReaderPtr reopen(IndexCommitPtr commit); + virtual IndexReaderPtr reopen(const IndexCommitPtr& commit); /// Efficiently clones the IndexReader (sharing most internal state). /// @@ -215,10 +215,10 @@ namespace Lucene /// /// Like {@link #reopen()}, it's safe to make changes to either the original or the cloned reader: all shared mutable /// state obeys "copy on write" semantics to ensure the changes are not seen by other readers. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Clones the IndexReader and optionally changes readOnly. A readOnly reader cannot open a writable reader. - virtual LuceneObjectPtr clone(bool openReadOnly, LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); /// Returns the directory associated with this index. The default implementation returns the directory specified by /// subclasses when delegating to the IndexReader(Directory) constructor, or throws an UnsupportedOperation exception @@ -227,18 +227,18 @@ namespace Lucene /// Returns the time the index in the named directory was last modified. Do not use this to check /// whether the reader is still up-to-date, use {@link #isCurrent()} instead. - static int64_t lastModified(DirectoryPtr directory2); + static int64_t lastModified(const DirectoryPtr& directory2); /// Reads version number from segments files. The version number is initialized with a timestamp /// and then increased by one for each change of the index. /// @param directory where the index resides. /// @return version number. - static int64_t getCurrentVersion(DirectoryPtr directory); + static int64_t getCurrentVersion(const DirectoryPtr& directory); /// Reads commitUserData, previously passed to {@link IndexWriter#commit(MapStringString)}, from /// current index segments file. This will return null if {@link IndexWriter#commit(MapStringString)} /// has never been called for this index. - static MapStringString getCommitUserData(DirectoryPtr directory); + static MapStringString getCommitUserData(const DirectoryPtr& directory); /// Version number when this IndexReader was opened. Not implemented in the IndexReader base class. /// @@ -307,18 +307,18 @@ namespace Lucene /// @param docNumber The number of the document to load the vector for /// @param field The name of the field to load /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. - virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) = 0; + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) = 0; /// Map all the term vectors for all fields in a Document /// @param docNumber The number of the document to load the vector for /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. - virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) = 0; + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) = 0; /// Returns true if an index exists at the specified directory. If the directory does not exist or /// if there is no index in it. /// @param directory the directory to check for an index /// @return true if an index exists; false otherwise - static bool indexExists(DirectoryPtr directory); + static bool indexExists(const DirectoryPtr& directory); /// Returns the number of documents in this index. virtual int32_t numDocs() = 0; @@ -358,7 +358,7 @@ namespace Lucene /// @see FieldSelector /// @see SetBasedFieldSelector /// @see LoadFirstFieldSelector - virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector) = 0; + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n) = 0; @@ -409,17 +409,17 @@ namespace Lucene /// exist, the enumeration is positioned at the first term greater than the supplied term. /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede /// it in the enumeration. - virtual TermEnumPtr terms(TermPtr t) = 0; + virtual TermEnumPtr terms(const TermPtr& t) = 0; /// Returns the number of documents containing the term t. - virtual int32_t docFreq(TermPtr t) = 0; + virtual int32_t docFreq(const TermPtr& t) = 0; /// Returns an enumeration of all the documents which contain term. For each document, the /// document number, the frequency of the term in that document is also provided, for use in /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. /// The enumeration is ordered by document number. Each document number is greater than all /// that precede it in the enumeration. - virtual TermDocsPtr termDocs(TermPtr term); + virtual TermDocsPtr termDocs(const TermPtr& term); /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs() = 0; @@ -431,7 +431,7 @@ namespace Lucene /// This positional information facilitates phrase and proximity searching. /// The enumeration is ordered by document number. Each document number is greater than all /// that precede it in the enumeration. - virtual TermPositionsPtr termPositions(TermPtr term); + virtual TermPositionsPtr termPositions(const TermPtr& term); /// Returns an unpositioned {@link TermPositions} enumerator. virtual TermPositionsPtr termPositions() = 0; @@ -449,7 +449,7 @@ namespace Lucene /// as its text and passes it to this method. See {@link #deleteDocument(int)} for information /// about when this deletion will become effective. /// @return the number of documents deleted - virtual int32_t deleteDocuments(TermPtr term); + virtual int32_t deleteDocuments(const TermPtr& term); /// Undeletes all documents currently marked as deleted in this index. virtual void undeleteAll(); @@ -492,7 +492,7 @@ namespace Lucene /// There must be at least one commit in the Directory, else this method throws an exception. /// Note that if a commit is in progress while this method is running, that commit may or may not /// be returned array. - static Collection listCommits(DirectoryPtr dir); + static Collection listCommits(const DirectoryPtr& dir); /// Returns the sequential sub readers that this reader is logically composed of. For example, /// IndexSearcher uses this API to drive searching by one sub reader at a time. If this reader is @@ -523,7 +523,7 @@ namespace Lucene protected: void ensureOpen(); - static IndexReaderPtr open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor); + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor); /// Implements setNorm in subclass. virtual void doSetNorm(int32_t doc, const String& field, uint8_t value) = 0; diff --git a/include/IndexSearcher.h b/include/IndexSearcher.h index e5731db6..41130118 100644 --- a/include/IndexSearcher.h +++ b/include/IndexSearcher.h @@ -28,13 +28,13 @@ namespace Lucene /// documents or change norms) with the underlying IndexReader. /// @param path Directory where IndexReader will be opened /// @param readOnly If true, the underlying IndexReader will be opened readOnly - IndexSearcher(DirectoryPtr path, bool readOnly = true); + IndexSearcher(const DirectoryPtr& path, bool readOnly = true); /// Creates a searcher searching the provided index. - IndexSearcher(IndexReaderPtr reader); + IndexSearcher(const IndexReaderPtr& reader); /// Directly specify the reader, subReaders and their docID starts. - IndexSearcher(IndexReaderPtr reader, Collection subReaders, Collection docStarts); + IndexSearcher(const IndexReaderPtr& reader, Collection subReaders, Collection docStarts); virtual ~IndexSearcher(); @@ -57,20 +57,20 @@ namespace Lucene IndexReaderPtr getIndexReader(); /// Note that the underlying IndexReader is not closed, if IndexSearcher was constructed with - /// IndexSearcher(IndexReaderPtr reader). If the IndexReader was supplied implicitly by specifying a + /// IndexSearcher(const IndexReaderPtr& reader). If the IndexReader was supplied implicitly by specifying a /// directory, then the IndexReader gets closed. virtual void close(); - virtual int32_t docFreq(TermPtr term); + virtual int32_t docFreq(const TermPtr& term); virtual DocumentPtr doc(int32_t n); - virtual DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); virtual int32_t maxDoc(); using Searcher::search; using Searcher::explain; - virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n); - virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort); + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); /// Just like {@link #search(WeightPtr, FilterPtr, int32_t, SortPtr)}, but you choose whether or not the /// fields in the returned {@link FieldDoc} instances should be set by specifying fillFields. @@ -78,11 +78,11 @@ namespace Lucene /// NOTE: this does not compute scores by default. If you need scores, create a {@link TopFieldCollector} /// instance by calling {@link TopFieldCollector#create} and then pass that to {@link #search(WeightPtr, /// FilterPtr, CollectorPtr)}. - virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort, bool fillFields); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort, bool fillFields); - virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr results); - virtual QueryPtr rewrite(QueryPtr query); - virtual ExplanationPtr explain(WeightPtr weight, int32_t doc); + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); + virtual QueryPtr rewrite(const QueryPtr& query); + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); /// By default, no scores are computed when sorting by field (using {@link #search(QueryPtr, FilterPtr, /// int32_t, SortPtr)}). You can change that, per IndexSearcher instance, by calling this method. Note @@ -93,9 +93,9 @@ namespace Lucene virtual void setDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore); protected: - void ConstructSearcher(IndexReaderPtr reader, bool closeReader); - void gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader); - void searchWithFilter(IndexReaderPtr reader, WeightPtr weight, FilterPtr filter, CollectorPtr collector); + void ConstructSearcher(const IndexReaderPtr& reader, bool closeReader); + void gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader); + void searchWithFilter(const IndexReaderPtr& reader, const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector); }; } diff --git a/include/IndexWriter.h b/include/IndexWriter.h index bdb9df59..787f4919 100644 --- a/include/IndexWriter.h +++ b/include/IndexWriter.h @@ -90,14 +90,14 @@ namespace Lucene class LPPAPI IndexWriter : public LuceneObject { protected: - IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexingChainPtr indexingChain, IndexCommitPtr commit); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexingChainPtr& indexingChain, const IndexCommitPtr& commit); public: - IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl); - IndexWriter(DirectoryPtr d, AnalyzerPtr a, int32_t mfl); - IndexWriter(DirectoryPtr d, AnalyzerPtr a, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl); - IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl); - IndexWriter(DirectoryPtr d, AnalyzerPtr a, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexCommitPtr commit); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexCommitPtr& commit); virtual ~IndexWriter(); LUCENE_CLASS(IndexWriter); @@ -298,7 +298,7 @@ namespace Lucene /// Obtain the number of deleted docs for a pooled reader. If the reader isn't being pooled, /// the segmentInfo's delCount is returned. - virtual int32_t numDeletedDocs(SegmentInfoPtr info); + virtual int32_t numDeletedDocs(const SegmentInfoPtr& info); virtual void acquireWrite(); virtual void releaseWrite(); @@ -331,7 +331,7 @@ namespace Lucene virtual void setUseCompoundFile(bool value); /// Set the Similarity implementation used by this IndexWriter. - virtual void setSimilarity(SimilarityPtr similarity); + virtual void setSimilarity(const SimilarityPtr& similarity); /// Return the Similarity implementation used by this IndexWriter. /// This defaults to the current value of {@link Similarity#getDefault()}. @@ -360,14 +360,14 @@ namespace Lucene virtual int32_t getTermIndexInterval(); /// Set the merge policy used by this writer. - virtual void setMergePolicy(MergePolicyPtr mp); + virtual void setMergePolicy(const MergePolicyPtr& mp); /// Returns the current MergePolicy in use by this writer. /// @see #setMergePolicy virtual MergePolicyPtr getMergePolicy(); /// Set the merge scheduler used by this writer. - virtual void setMergeScheduler(MergeSchedulerPtr mergeScheduler); + virtual void setMergeScheduler(const MergeSchedulerPtr& mergeScheduler); /// Returns the current MergePolicy in use by this writer. /// @see #setMergePolicy @@ -498,7 +498,7 @@ namespace Lucene /// If non-null, this will be the default infoStream used by a newly instantiated IndexWriter. /// @see #setInfoStream - static void setDefaultInfoStream(InfoStreamPtr infoStream); + static void setDefaultInfoStream(const InfoStreamPtr& infoStream); /// Returns the current default infoStream for newly instantiated IndexWriters. /// @see #setDefaultInfoStream @@ -506,7 +506,7 @@ namespace Lucene /// If non-null, information about merges, deletes and a message when maxFieldLength is reached /// will be printed to this. - virtual void setInfoStream(InfoStreamPtr infoStream); + virtual void setInfoStream(const InfoStreamPtr& infoStream); /// Returns the current infoStream in use by this writer. /// @see #setInfoStream @@ -601,7 +601,7 @@ namespace Lucene /// IllegalArgument exception will be thrown. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void addDocument(DocumentPtr doc); + virtual void addDocument(const DocumentPtr& doc); /// Adds a document to this index, using the provided analyzer instead of the value of {@link /// #getAnalyzer()}. If the document contains more than {@link #setMaxFieldLength(int32_t)} terms @@ -611,14 +611,14 @@ namespace Lucene /// exception, and flushing/merging temporary free space requirements. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void addDocument(DocumentPtr doc, AnalyzerPtr analyzer); + virtual void addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer); /// Deletes the document(s) containing term. /// /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// /// @param term the term to identify the documents to be deleted - virtual void deleteDocuments(TermPtr term); + virtual void deleteDocuments(const TermPtr& term); /// Deletes the document(s) containing any of the terms. All deletes are flushed at the same time. /// @@ -632,7 +632,7 @@ namespace Lucene /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. /// /// @param query the query to identify the documents to be deleted - virtual void deleteDocuments(QueryPtr query); + virtual void deleteDocuments(const QueryPtr& query); /// Deletes the document(s) matching any of the provided queries. All deletes are flushed at /// the same time. @@ -650,7 +650,7 @@ namespace Lucene /// /// @param term the term to identify the document(s) to be deleted /// @param doc the document to be added - virtual void updateDocument(TermPtr term, DocumentPtr doc); + virtual void updateDocument(const TermPtr& term, const DocumentPtr& doc); /// Updates a document by first deleting the document(s) containing term and then adding the new /// document. The delete and then add are atomic as seen by a reader on the same index (flush @@ -661,7 +661,7 @@ namespace Lucene /// @param term the term to identify the document(s) to be deleted /// @param doc the document to be added /// @param analyzer the analyzer to use when analyzing the document - virtual void updateDocument(TermPtr term, DocumentPtr doc, AnalyzerPtr analyzer); + virtual void updateDocument(const TermPtr& term, const DocumentPtr& doc, const AnalyzerPtr& analyzer); virtual int32_t getSegmentCount(); virtual int32_t getNumBufferedDocuments(); @@ -891,24 +891,24 @@ namespace Lucene virtual int32_t numRamDocs(); /// Merges the indicated segments, replacing them in the stack with a single segment. - virtual void merge(OneMergePtr merge); + virtual void merge(const OneMergePtr& merge); /// Hook that's called when the specified merge is complete. - virtual void mergeSuccess(OneMergePtr merge); + virtual void mergeSuccess(const OneMergePtr& merge); /// Checks whether this merge involves any segments already participating in a merge. If not, this /// merge is "registered", meaning we record that its segments are now participating in a merge, /// and true is returned. Else (the merge conflicts) false is returned. - virtual bool registerMerge(OneMergePtr merge); + virtual bool registerMerge(const OneMergePtr& merge); /// Does initial setup for a merge, which is fast but holds the synchronized lock on IndexWriter /// instance. - virtual void mergeInit(OneMergePtr merge); + virtual void mergeInit(const OneMergePtr& merge); /// Does finishing for a merge, which is fast but holds the synchronized lock on IndexWriter instance. - virtual void mergeFinish(OneMergePtr merge); + virtual void mergeFinish(const OneMergePtr& merge); - virtual void addMergeException(OneMergePtr merge); + virtual void addMergeException(const OneMergePtr& merge); /// For test purposes. virtual int32_t getBufferedDeleteTermsSize(); @@ -923,15 +923,15 @@ namespace Lucene /// Returns true if the index in the named directory is currently locked. /// @param directory the directory to check for a lock - static bool isLocked(DirectoryPtr directory); + static bool isLocked(const DirectoryPtr& directory); /// Forcibly unlocks the index in the named directory. /// Caution: this should only be used by failure recovery code, when it is known that no other process /// nor thread is in fact currently accessing this index. - static void unlock(DirectoryPtr directory); + static void unlock(const DirectoryPtr& directory); /// Set the merged segment warmer. See {@link IndexReaderWarmer}. - virtual void setMergedSegmentWarmer(IndexReaderWarmerPtr warmer); + virtual void setMergedSegmentWarmer(const IndexReaderWarmerPtr& warmer); /// Returns the current merged segment warmer. See {@link IndexReaderWarmer}. virtual IndexReaderWarmerPtr getMergedSegmentWarmer(); @@ -951,19 +951,19 @@ namespace Lucene /// startMergeInit virtual bool testPoint(const String& name); - virtual bool nrtIsCurrent(SegmentInfosPtr infos); + virtual bool nrtIsCurrent(const SegmentInfosPtr& infos); virtual bool isClosed(); protected: virtual void ensureOpen(bool includePendingClose); virtual void ensureOpen(); - virtual void setMessageID(InfoStreamPtr infoStream); + virtual void setMessageID(const InfoStreamPtr& infoStream); /// Casts current mergePolicy to LogMergePolicy, and throws an exception if the /// mergePolicy is not a LogMergePolicy. virtual LogMergePolicyPtr getLogMergePolicy(); - virtual void setRollbackSegmentInfos(SegmentInfosPtr infos); + virtual void setRollbackSegmentInfos(const SegmentInfosPtr& infos); /// If we are flushing by doc count (not by RAM usage), and using LogDocMergePolicy then push /// maxBufferedDocs down as its minMergeDocs, to keep backwards compatibility. @@ -1046,34 +1046,34 @@ namespace Lucene virtual bool doFlush(bool flushDocStores, bool flushDeletes); virtual bool doFlushInternal(bool flushDocStores, bool flushDeletes); - virtual int32_t ensureContiguousMerge(OneMergePtr merge); + virtual int32_t ensureContiguousMerge(const OneMergePtr& merge); /// Carefully merges deletes for the segments we just merged. This is tricky because, although merging /// will clear all deletes (compacts the documents), new deletes may have been flushed to the segments /// since the merge was started. This method "carries over" such new deletes onto the newly merged /// segment, and saves the resulting deletes file (incrementing the delete generation for merge.info). /// If no deletes were flushed, no new deletes file is saved. - virtual void commitMergedDeletes(OneMergePtr merge, SegmentReaderPtr mergeReader); - virtual bool commitMerge(OneMergePtr merge, SegmentMergerPtr merger, int32_t mergedDocCount, SegmentReaderPtr mergedReader); + virtual void commitMergedDeletes(const OneMergePtr& merge, const SegmentReaderPtr& mergeReader); + virtual bool commitMerge(const OneMergePtr& merge, const SegmentMergerPtr& merger, int32_t mergedDocCount, const SegmentReaderPtr& mergedReader); - virtual LuceneException handleMergeException(const LuceneException& exc, OneMergePtr merge); + virtual LuceneException handleMergeException(const LuceneException& exc, const OneMergePtr& merge); - virtual void _mergeInit(OneMergePtr merge); + virtual void _mergeInit(const OneMergePtr& merge); - virtual void setDiagnostics(SegmentInfoPtr info, const String& source); - virtual void setDiagnostics(SegmentInfoPtr info, const String& source, MapStringString details); + virtual void setDiagnostics(const SegmentInfoPtr& info, const String& source); + virtual void setDiagnostics(const SegmentInfoPtr& info, const String& source, MapStringString details); - virtual void setMergeDocStoreIsCompoundFile(OneMergePtr merge); - virtual void closeMergeReaders(OneMergePtr merge, bool suppressExceptions); + virtual void setMergeDocStoreIsCompoundFile(const OneMergePtr& merge); + virtual void closeMergeReaders(const OneMergePtr& merge, bool suppressExceptions); /// Does the actual (time-consuming) work of the merge, but without holding synchronized lock on /// IndexWriter instance. - virtual int32_t mergeMiddle(OneMergePtr merge); + virtual int32_t mergeMiddle(const OneMergePtr& merge); /// Apply buffered deletes to all segments. virtual bool applyDeletes(); - virtual String segString(SegmentInfosPtr infos); + virtual String segString(const SegmentInfosPtr& infos); virtual bool startSync(const String& fileName, HashSet pending); virtual void finishSync(const String& fileName, bool success); @@ -1106,7 +1106,7 @@ namespace Lucene LUCENE_CLASS(IndexReaderWarmer); public: - virtual void warm(IndexReaderPtr reader) = 0; + virtual void warm(const IndexReaderPtr& reader) = 0; }; } diff --git a/include/InputStreamReader.h b/include/InputStreamReader.h index 561c6827..9a55a88a 100644 --- a/include/InputStreamReader.h +++ b/include/InputStreamReader.h @@ -16,7 +16,7 @@ namespace Lucene { public: /// Create an InputStreamReader that uses the utf8 charset. - InputStreamReader(ReaderPtr reader); + InputStreamReader(const ReaderPtr& reader); virtual ~InputStreamReader(); LUCENE_CLASS(InputStreamReader); diff --git a/include/IntBlockPool.h b/include/IntBlockPool.h index 722138fa..a004216c 100644 --- a/include/IntBlockPool.h +++ b/include/IntBlockPool.h @@ -14,7 +14,7 @@ namespace Lucene class IntBlockPool : public LuceneObject { public: - IntBlockPool(DocumentsWriterPtr docWriter, bool trackAllocations); + IntBlockPool(const DocumentsWriterPtr& docWriter, bool trackAllocations); virtual ~IntBlockPool(); LUCENE_CLASS(IntBlockPool); diff --git a/include/IntFieldSource.h b/include/IntFieldSource.h index 5373339e..bf064201 100644 --- a/include/IntFieldSource.h +++ b/include/IntFieldSource.h @@ -25,7 +25,7 @@ namespace Lucene { public: /// Create a cached int field source with a specific string-to-int parser. - IntFieldSource(const String& field, IntParserPtr parser = IntParserPtr()); + IntFieldSource(const String& field, const IntParserPtr& parser = IntParserPtr()); virtual ~IntFieldSource(); LUCENE_CLASS(IntFieldSource); @@ -35,8 +35,8 @@ namespace Lucene public: virtual String description(); - virtual DocValuesPtr getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader); - virtual bool cachedFieldSourceEquals(FieldCacheSourcePtr other); + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); virtual int32_t cachedFieldSourceHashCode(); }; } diff --git a/include/InvertedDocConsumer.h b/include/InvertedDocConsumer.h index cbc5bf9b..4cb7c713 100644 --- a/include/InvertedDocConsumer.h +++ b/include/InvertedDocConsumer.h @@ -23,21 +23,21 @@ namespace Lucene public: /// Add a new thread - virtual InvertedDocConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread) = 0; + virtual InvertedDocConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread) = 0; /// Abort (called after hitting AbortException) virtual void abort() = 0; /// Flush a new segment - virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; + virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; /// Close doc stores - virtual void closeDocStore(SegmentWriteStatePtr state) = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; /// Attempt to free RAM, returning true if any RAM was freed virtual bool freeRAM() = 0; - virtual void setFieldInfos(FieldInfosPtr fieldInfos); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); }; } diff --git a/include/InvertedDocConsumerPerField.h b/include/InvertedDocConsumerPerField.h index 54cc01ce..d4c93918 100644 --- a/include/InvertedDocConsumerPerField.h +++ b/include/InvertedDocConsumerPerField.h @@ -24,7 +24,7 @@ namespace Lucene virtual bool start(Collection fields, int32_t count) = 0; /// Called before a field instance is being processed - virtual void start(FieldablePtr field) = 0; + virtual void start(const FieldablePtr& field) = 0; /// Called once per inverted token virtual void add() = 0; diff --git a/include/InvertedDocConsumerPerThread.h b/include/InvertedDocConsumerPerThread.h index 35649015..afcc8a4e 100644 --- a/include/InvertedDocConsumerPerThread.h +++ b/include/InvertedDocConsumerPerThread.h @@ -20,7 +20,7 @@ namespace Lucene public: virtual void startDocument() = 0; - virtual InvertedDocConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) = 0; + virtual InvertedDocConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) = 0; virtual DocWriterPtr finishDocument() = 0; virtual void abort() = 0; }; diff --git a/include/InvertedDocEndConsumer.h b/include/InvertedDocEndConsumer.h index 65b92a18..413ee367 100644 --- a/include/InvertedDocEndConsumer.h +++ b/include/InvertedDocEndConsumer.h @@ -19,11 +19,11 @@ namespace Lucene LUCENE_CLASS(InvertedDocEndConsumer); public: - virtual InvertedDocEndConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread) = 0; - virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; - virtual void closeDocStore(SegmentWriteStatePtr state) = 0; + virtual InvertedDocEndConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread) = 0; + virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; virtual void abort() = 0; - virtual void setFieldInfos(FieldInfosPtr fieldInfos) = 0; + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos) = 0; }; } diff --git a/include/InvertedDocEndConsumerPerThread.h b/include/InvertedDocEndConsumerPerThread.h index 6d2af130..986e3622 100644 --- a/include/InvertedDocEndConsumerPerThread.h +++ b/include/InvertedDocEndConsumerPerThread.h @@ -20,7 +20,7 @@ namespace Lucene public: virtual void startDocument() = 0; - virtual InvertedDocEndConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) = 0; + virtual InvertedDocEndConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) = 0; virtual void finishDocument() = 0; virtual void abort() = 0; }; diff --git a/include/KeywordAnalyzer.h b/include/KeywordAnalyzer.h index fa4d5cfe..d8007c29 100644 --- a/include/KeywordAnalyzer.h +++ b/include/KeywordAnalyzer.h @@ -21,8 +21,8 @@ namespace Lucene LUCENE_CLASS(KeywordAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; } diff --git a/include/KeywordTokenizer.h b/include/KeywordTokenizer.h index 639b86cb..c15d731b 100644 --- a/include/KeywordTokenizer.h +++ b/include/KeywordTokenizer.h @@ -15,10 +15,10 @@ namespace Lucene class LPPAPI KeywordTokenizer : public Tokenizer { public: - KeywordTokenizer(ReaderPtr input); - KeywordTokenizer(ReaderPtr input, int32_t bufferSize); - KeywordTokenizer(AttributeSourcePtr source, ReaderPtr input, int32_t bufferSize); - KeywordTokenizer(AttributeFactoryPtr factory, ReaderPtr input, int32_t bufferSize); + KeywordTokenizer(const ReaderPtr& input); + KeywordTokenizer(const ReaderPtr& input, int32_t bufferSize); + KeywordTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input, int32_t bufferSize); + KeywordTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input, int32_t bufferSize); virtual ~KeywordTokenizer(); diff --git a/include/LengthFilter.h b/include/LengthFilter.h index f50405a2..740aa85f 100644 --- a/include/LengthFilter.h +++ b/include/LengthFilter.h @@ -16,7 +16,7 @@ namespace Lucene { public: /// Build a filter that removes words that are too long or too short from the text. - LengthFilter(TokenStreamPtr input, int32_t min, int32_t max); + LengthFilter(const TokenStreamPtr& input, int32_t min, int32_t max); virtual ~LengthFilter(); LUCENE_CLASS(LengthFilter); diff --git a/include/LetterTokenizer.h b/include/LetterTokenizer.h index 88964d77..6db69a54 100644 --- a/include/LetterTokenizer.h +++ b/include/LetterTokenizer.h @@ -20,13 +20,13 @@ namespace Lucene { public: /// Construct a new LetterTokenizer. - LetterTokenizer(ReaderPtr input); + LetterTokenizer(const ReaderPtr& input); /// Construct a new LetterTokenizer using a given {@link AttributeSource}. - LetterTokenizer(AttributeSourcePtr source, ReaderPtr input); + LetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); /// Construct a new LetterTokenizer using a given {@link AttributeFactory}. - LetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + LetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~LetterTokenizer(); diff --git a/include/LogByteSizeMergePolicy.h b/include/LogByteSizeMergePolicy.h index 3304121e..f8b4194e 100644 --- a/include/LogByteSizeMergePolicy.h +++ b/include/LogByteSizeMergePolicy.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI LogByteSizeMergePolicy : public LogMergePolicy { public: - LogByteSizeMergePolicy(IndexWriterPtr writer); + LogByteSizeMergePolicy(const IndexWriterPtr& writer); virtual ~LogByteSizeMergePolicy(); LUCENE_CLASS(LogByteSizeMergePolicy); @@ -30,7 +30,7 @@ namespace Lucene static const double DEFAULT_MAX_MERGE_MB; protected: - virtual int64_t size(SegmentInfoPtr info); + virtual int64_t size(const SegmentInfoPtr& info); public: /// Determines the largest segment (measured by total byte size of the segment's files, in MB) diff --git a/include/LogDocMergePolicy.h b/include/LogDocMergePolicy.h index 156a6d6b..9e44e6fc 100644 --- a/include/LogDocMergePolicy.h +++ b/include/LogDocMergePolicy.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI LogDocMergePolicy : public LogMergePolicy { public: - LogDocMergePolicy(IndexWriterPtr writer); + LogDocMergePolicy(const IndexWriterPtr& writer); virtual ~LogDocMergePolicy(); LUCENE_CLASS(LogDocMergePolicy); @@ -26,7 +26,7 @@ namespace Lucene static const int32_t DEFAULT_MIN_MERGE_DOCS; protected: - virtual int64_t size(SegmentInfoPtr info); + virtual int64_t size(const SegmentInfoPtr& info); public: /// Sets the minimum size for the lowest level segments. Any segments below this size are considered diff --git a/include/LogMergePolicy.h b/include/LogMergePolicy.h index f2126bbc..8ff447c9 100644 --- a/include/LogMergePolicy.h +++ b/include/LogMergePolicy.h @@ -24,7 +24,7 @@ namespace Lucene class LPPAPI LogMergePolicy : public MergePolicy { public: - LogMergePolicy(IndexWriterPtr writer); + LogMergePolicy(const IndexWriterPtr& writer); virtual ~LogMergePolicy(); LUCENE_CLASS(LogMergePolicy); @@ -78,7 +78,7 @@ namespace Lucene void setMergeFactor(int32_t mergeFactor); /// Returns true if a newly flushed (not from merge) segment should use the compound file format. - virtual bool useCompoundFile(SegmentInfosPtr segments, SegmentInfoPtr newSegment); + virtual bool useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment); /// Sets whether compound file format should be used for newly flushed and newly merged segments. void setUseCompoundFile(bool useCompoundFile); @@ -88,7 +88,7 @@ namespace Lucene bool getUseCompoundFile(); /// Returns true if the doc store files should use the compound file format. - virtual bool useCompoundDocStore(SegmentInfosPtr segments); + virtual bool useCompoundDocStore(const SegmentInfosPtr& segments); /// Sets whether compound file format should be used for newly flushed and newly merged doc store /// segment files (term vectors and stored fields). @@ -113,17 +113,17 @@ namespace Lucene /// one segment in the index, where that segment has no deletions pending nor separate norms, and it is in /// compound file format if the current useCompoundFile setting is true. This method returns multiple merges /// (mergeFactor at a time) so the {@link MergeScheduler} in use may make use of concurrency. - virtual MergeSpecificationPtr findMergesForOptimize(SegmentInfosPtr segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize); + virtual MergeSpecificationPtr findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize); /// Finds merges necessary to expunge all deletes from the index. We simply merge adjacent segments that have /// deletes, up to mergeFactor at a time. - virtual MergeSpecificationPtr findMergesToExpungeDeletes(SegmentInfosPtr segmentInfos); + virtual MergeSpecificationPtr findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos); /// Checks if any merges are now necessary and returns a {@link MergePolicy.MergeSpecification} if so. A merge /// is necessary when there are more than {@link #setMergeFactor} segments at a given level. When multiple /// levels have too many segments, this method will return multiple merges, allowing the {@link MergeScheduler} /// to use concurrency. - virtual MergeSpecificationPtr findMerges(SegmentInfosPtr segmentInfos); + virtual MergeSpecificationPtr findMerges(const SegmentInfosPtr& segmentInfos); /// Determines the largest segment (measured by document count) that may be merged with other segments. /// Small values (eg., less than 10,000) are best for interactive indexing, as this limits the length of @@ -143,18 +143,18 @@ namespace Lucene bool verbose(); void message(const String& message); - virtual int64_t size(SegmentInfoPtr info) = 0; + virtual int64_t size(const SegmentInfoPtr& info) = 0; - int64_t sizeDocs(SegmentInfoPtr info); - int64_t sizeBytes(SegmentInfoPtr info); + int64_t sizeDocs(const SegmentInfoPtr& info); + int64_t sizeBytes(const SegmentInfoPtr& info); - bool isOptimized(SegmentInfosPtr infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize); + bool isOptimized(const SegmentInfosPtr& infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize); /// Returns true if this single info is optimized (has no pending norms or deletes, is in the same dir as the /// writer, and matches the current compound file setting - bool isOptimized(SegmentInfoPtr info); + bool isOptimized(const SegmentInfoPtr& info); - OneMergePtr makeOneMerge(SegmentInfosPtr infos, SegmentInfosPtr infosToMerge); + OneMergePtr makeOneMerge(const SegmentInfosPtr& infos, const SegmentInfosPtr& infosToMerge); }; } diff --git a/include/LowerCaseFilter.h b/include/LowerCaseFilter.h index cf8d6228..9aa19ae8 100644 --- a/include/LowerCaseFilter.h +++ b/include/LowerCaseFilter.h @@ -15,7 +15,7 @@ namespace Lucene class LPPAPI LowerCaseFilter : public TokenFilter { public: - LowerCaseFilter(TokenStreamPtr input); + LowerCaseFilter(const TokenStreamPtr& input); virtual ~LowerCaseFilter(); LUCENE_CLASS(LowerCaseFilter); diff --git a/include/LowerCaseTokenizer.h b/include/LowerCaseTokenizer.h index 8d768116..2399d208 100644 --- a/include/LowerCaseTokenizer.h +++ b/include/LowerCaseTokenizer.h @@ -22,13 +22,13 @@ namespace Lucene { public: /// Construct a new LowerCaseTokenizer. - LowerCaseTokenizer(ReaderPtr input); + LowerCaseTokenizer(const ReaderPtr& input); /// Construct a new LowerCaseTokenizer using a given {@link AttributeSource}. - LowerCaseTokenizer(AttributeSourcePtr source, ReaderPtr input); + LowerCaseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); /// Construct a new LowerCaseTokenizer using a given {@link AttributeFactory}. - LowerCaseTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + LowerCaseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~LowerCaseTokenizer(); diff --git a/include/LuceneObject.h b/include/LuceneObject.h index d7ba5c94..44ce17a9 100644 --- a/include/LuceneObject.h +++ b/include/LuceneObject.h @@ -43,16 +43,16 @@ namespace Lucene /// Return clone of this object /// @param other clone reference - null when called initially, then set in top virtual override. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Return hash code for this object. virtual int32_t hashCode(); /// Return whether two objects are equal - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); /// Compare two objects - virtual int32_t compareTo(LuceneObjectPtr other); + virtual int32_t compareTo(const LuceneObjectPtr& other); /// Returns a string representation of the object virtual String toString(); diff --git a/include/LuceneSignal.h b/include/LuceneSignal.h index 093a7d44..bf52590d 100644 --- a/include/LuceneSignal.h +++ b/include/LuceneSignal.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI LuceneSignal { public: - LuceneSignal(SynchronizePtr objectLock = SynchronizePtr()); + LuceneSignal(const SynchronizePtr& objectLock = SynchronizePtr()); virtual ~LuceneSignal(); protected: @@ -26,7 +26,7 @@ namespace Lucene public: /// create a new LuceneSignal instance atomically. - static void createSignal(LuceneSignalPtr& signal, SynchronizePtr objectLock); + static void createSignal(LuceneSignalPtr& signal, const SynchronizePtr& objectLock); /// Wait for signal using an optional timeout. void wait(int32_t timeout = 0); diff --git a/include/MMapDirectory.h b/include/MMapDirectory.h index 0cd77d47..b3e3d5ce 100644 --- a/include/MMapDirectory.h +++ b/include/MMapDirectory.h @@ -25,7 +25,7 @@ namespace Lucene /// Create a new MMapDirectory for the named location. /// @param path the path of the directory. /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) - MMapDirectory(const String& path, LockFactoryPtr lockFactory = LockFactoryPtr()); + MMapDirectory(const String& path, const LockFactoryPtr& lockFactory = LockFactoryPtr()); virtual ~MMapDirectory(); diff --git a/include/MappingCharFilter.h b/include/MappingCharFilter.h index cbadcd9f..8871f559 100644 --- a/include/MappingCharFilter.h +++ b/include/MappingCharFilter.h @@ -17,10 +17,10 @@ namespace Lucene { public: /// Default constructor that takes a {@link CharStream}. - MappingCharFilter(NormalizeCharMapPtr normMap, CharStreamPtr in); + MappingCharFilter(const NormalizeCharMapPtr& normMap, const CharStreamPtr& in); /// Easy-use constructor that takes a {@link Reader}. - MappingCharFilter(NormalizeCharMapPtr normMap, ReaderPtr in); + MappingCharFilter(const NormalizeCharMapPtr& normMap, const ReaderPtr& in); virtual ~MappingCharFilter(); @@ -41,7 +41,7 @@ namespace Lucene int32_t nextChar(); void pushChar(int32_t c); void pushLastChar(int32_t c); - NormalizeCharMapPtr match(NormalizeCharMapPtr map); + NormalizeCharMapPtr match(const NormalizeCharMapPtr& map); }; } diff --git a/include/MatchAllDocsQuery.h b/include/MatchAllDocsQuery.h index 116fd888..8a7ada97 100644 --- a/include/MatchAllDocsQuery.h +++ b/include/MatchAllDocsQuery.h @@ -28,12 +28,12 @@ namespace Lucene public: using Query::toString; - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); friend class MatchAllDocsWeight; }; diff --git a/include/MaxPayloadFunction.h b/include/MaxPayloadFunction.h index e51ae4aa..80580c32 100644 --- a/include/MaxPayloadFunction.h +++ b/include/MaxPayloadFunction.h @@ -25,7 +25,7 @@ namespace Lucene double currentScore, double currentPayloadScore); virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); }; } diff --git a/include/MergeDocIDRemapper.h b/include/MergeDocIDRemapper.h index 6b27d6b2..6c1a2630 100644 --- a/include/MergeDocIDRemapper.h +++ b/include/MergeDocIDRemapper.h @@ -17,7 +17,7 @@ namespace Lucene class MergeDocIDRemapper : public LuceneObject { public: - MergeDocIDRemapper(SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergedDocCount); + MergeDocIDRemapper(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount); virtual ~MergeDocIDRemapper(); LUCENE_CLASS(MergeDocIDRemapper); diff --git a/include/MergePolicy.h b/include/MergePolicy.h index 469f3bae..71b803bc 100644 --- a/include/MergePolicy.h +++ b/include/MergePolicy.h @@ -32,7 +32,7 @@ namespace Lucene class LPPAPI MergePolicy : public LuceneObject { public: - MergePolicy(IndexWriterPtr writer); + MergePolicy(const IndexWriterPtr& writer); virtual ~MergePolicy(); LUCENE_CLASS(MergePolicy); @@ -45,7 +45,7 @@ namespace Lucene /// this whenever there is a change to the segments. This call is always synchronized on the {@link /// IndexWriter} instance so only one thread at a time will call this method. /// @param segmentInfos the total set of segments in the index - virtual MergeSpecificationPtr findMerges(SegmentInfosPtr segmentInfos) = 0; + virtual MergeSpecificationPtr findMerges(const SegmentInfosPtr& segmentInfos) = 0; /// Determine what set of merge operations is necessary in order to optimize the index. {@link /// IndexWriter} calls this when its {@link IndexWriter#optimize()} method is called. This call is @@ -55,20 +55,20 @@ namespace Lucene /// @param maxSegmentCount requested maximum number of segments in the index (currently this is always 1) /// @param segmentsToOptimize contains the specific SegmentInfo instances that must be merged away. /// This may be a subset of all SegmentInfos. - virtual MergeSpecificationPtr findMergesForOptimize(SegmentInfosPtr segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) = 0; + virtual MergeSpecificationPtr findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) = 0; /// Determine what set of merge operations is necessary in order to expunge all deletes from the index. /// @param segmentInfos the total set of segments in the index - virtual MergeSpecificationPtr findMergesToExpungeDeletes(SegmentInfosPtr segmentInfos) = 0; + virtual MergeSpecificationPtr findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos) = 0; /// Release all resources for the policy. virtual void close() = 0; /// Returns true if a newly flushed (not from merge) segment should use the compound file format. - virtual bool useCompoundFile(SegmentInfosPtr segments, SegmentInfoPtr newSegment) = 0; + virtual bool useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment) = 0; /// Returns true if the doc store files should use the compound file format. - virtual bool useCompoundDocStore(SegmentInfosPtr segments) = 0; + virtual bool useCompoundDocStore(const SegmentInfosPtr& segments) = 0; }; /// OneMerge provides the information necessary to perform an individual primitive merge operation, @@ -77,7 +77,7 @@ namespace Lucene class LPPAPI OneMerge : public LuceneObject { public: - OneMerge(SegmentInfosPtr segments, bool useCompoundFile); + OneMerge(const SegmentInfosPtr& segments, bool useCompoundFile); virtual ~OneMerge(); LUCENE_CLASS(OneMerge); @@ -111,9 +111,9 @@ namespace Lucene /// Returns true if this merge was aborted. bool isAborted(); - void checkAborted(DirectoryPtr dir); + void checkAborted(const DirectoryPtr& dir); - String segString(DirectoryPtr dir); + String segString(const DirectoryPtr& dir); }; /// A MergeSpecification instance provides the information necessary to perform multiple merges. @@ -130,8 +130,8 @@ namespace Lucene Collection merges; public: - void add(OneMergePtr merge); - String segString(DirectoryPtr dir); + void add(const OneMergePtr& merge); + String segString(const DirectoryPtr& dir); }; } diff --git a/include/MergeScheduler.h b/include/MergeScheduler.h index 88bf762b..65a20e75 100644 --- a/include/MergeScheduler.h +++ b/include/MergeScheduler.h @@ -22,7 +22,7 @@ namespace Lucene public: /// Run the merges provided by {@link IndexWriter#getNextMerge()}. - virtual void merge(IndexWriterPtr writer) = 0; + virtual void merge(const IndexWriterPtr& writer) = 0; /// Close this MergeScheduler. virtual void close() = 0; diff --git a/include/MinPayloadFunction.h b/include/MinPayloadFunction.h index e5558c19..891eaa73 100644 --- a/include/MinPayloadFunction.h +++ b/include/MinPayloadFunction.h @@ -23,7 +23,7 @@ namespace Lucene double currentScore, double currentPayloadScore); virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); }; } diff --git a/include/MiscUtils.h b/include/MiscUtils.h index 29f2b744..56339a50 100644 --- a/include/MiscUtils.h +++ b/include/MiscUtils.h @@ -123,13 +123,13 @@ namespace Lucene /// Return whether given Lucene object is of a specified type template - static bool typeOf(LuceneObjectPtr object) + static bool typeOf(const LuceneObjectPtr& object) { return boost::dynamic_pointer_cast(object).get() != NULL; } /// Return whether given Lucene objects are of equal type. - static bool equalTypes(LuceneObjectPtr first, LuceneObjectPtr second); + static bool equalTypes(const LuceneObjectPtr& first, const LuceneObjectPtr& second); /// Perform unsigned right-shift (left bits are zero filled) static int64_t unsignedShift(int64_t num, int64_t shift); diff --git a/include/MultiFieldQueryParser.h b/include/MultiFieldQueryParser.h index bcf72c5a..dfa4a3e6 100644 --- a/include/MultiFieldQueryParser.h +++ b/include/MultiFieldQueryParser.h @@ -37,7 +37,7 @@ namespace Lucene /// /// In other words, all the query's terms must appear, but it doesn't matter in what fields they /// appear. - MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, AnalyzerPtr analyzer, MapStringDouble boosts); + MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer, MapStringDouble boosts); /// Creates a MultiFieldQueryParser. It will, when parse(String query) is called, construct a /// query like this (assuming the query consists of two terms and you specify the two fields @@ -53,7 +53,7 @@ namespace Lucene /// /// In other words, all the query's terms must appear, but it doesn't matter in what fields they /// appear. - MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, AnalyzerPtr analyzer); + MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer); virtual ~MultiFieldQueryParser(); @@ -76,7 +76,7 @@ namespace Lucene /// @param queries Queries strings to parse /// @param fields Fields to search on /// @param analyzer Analyzer to use - static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, AnalyzerPtr analyzer); + static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, const AnalyzerPtr& analyzer); /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as /// required, and others as prohibited. @@ -98,7 +98,7 @@ namespace Lucene /// @param fields Fields to search on /// @param flags Flags describing the fields /// @param analyzer Analyzer to use - static QueryPtr parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, AnalyzerPtr analyzer); + static QueryPtr parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, const AnalyzerPtr& analyzer); /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as /// required, and others as prohibited. @@ -121,12 +121,12 @@ namespace Lucene /// @param fields Fields to search on /// @param flags Flags describing the fields /// @param analyzer Analyzer to use - static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, AnalyzerPtr analyzer); + static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, const AnalyzerPtr& analyzer); protected: virtual QueryPtr getFieldQuery(const String& field, const String& queryText, int32_t slop); virtual QueryPtr getFieldQuery(const String& field, const String& queryText); - void applySlop(QueryPtr query, int32_t slop); + void applySlop(const QueryPtr& query, int32_t slop); virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity); virtual QueryPtr getPrefixQuery(const String& field, const String& termStr); diff --git a/include/MultiLevelSkipListReader.h b/include/MultiLevelSkipListReader.h index e1358046..324f8e92 100644 --- a/include/MultiLevelSkipListReader.h +++ b/include/MultiLevelSkipListReader.h @@ -20,7 +20,7 @@ namespace Lucene class MultiLevelSkipListReader : public LuceneObject { public: - MultiLevelSkipListReader(IndexInputPtr skipStream, int32_t maxSkipLevels, int32_t skipInterval); + MultiLevelSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval); virtual ~MultiLevelSkipListReader(); LUCENE_CLASS(MultiLevelSkipListReader); @@ -79,7 +79,7 @@ namespace Lucene /// /// @param level the level skip data shall be read from /// @param skipStream the skip stream to read from - virtual int32_t readSkipData(int32_t level, IndexInputPtr skipStream) = 0; + virtual int32_t readSkipData(int32_t level, const IndexInputPtr& skipStream) = 0; /// Copies the values of the last read skip entry on this level virtual void setLastSkipData(int32_t level); @@ -89,7 +89,7 @@ namespace Lucene class SkipBuffer : public IndexInput { public: - SkipBuffer(IndexInputPtr input, int32_t length); + SkipBuffer(const IndexInputPtr& input, int32_t length); virtual ~SkipBuffer(); LUCENE_CLASS(SkipBuffer); diff --git a/include/MultiLevelSkipListWriter.h b/include/MultiLevelSkipListWriter.h index e8b57bec..4829e1f5 100644 --- a/include/MultiLevelSkipListWriter.h +++ b/include/MultiLevelSkipListWriter.h @@ -60,7 +60,7 @@ namespace Lucene /// Writes the buffered skip lists to the given output. /// @param output the IndexOutput the skip lists shall be written to /// @return the pointer the skip list starts - int64_t writeSkip(IndexOutputPtr output); + int64_t writeSkip(const IndexOutputPtr& output); protected: void init(); @@ -69,7 +69,7 @@ namespace Lucene /// Subclasses must implement the actual skip data encoding in this method. /// @param level the level skip data shall be writing for /// @param skipBuffer the skip buffer to write to - virtual void writeSkipData(int32_t level, IndexOutputPtr skipBuffer) = 0; + virtual void writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer) = 0; }; } diff --git a/include/MultiPhraseQuery.h b/include/MultiPhraseQuery.h index bd8f422f..dbd936f3 100644 --- a/include/MultiPhraseQuery.h +++ b/include/MultiPhraseQuery.h @@ -42,7 +42,7 @@ namespace Lucene /// Add a single term at the next position in the phrase. /// @see PhraseQuery#add(Term) - void add(TermPtr term); + void add(const TermPtr& term); /// Add multiple terms at the next position in the phrase. Any of the terms may match. /// @see PhraseQuery#add(Term) @@ -59,15 +59,15 @@ namespace Lucene Collection getPositions(); virtual void extractTerms(SetTerm terms); - virtual QueryPtr rewrite(IndexReaderPtr reader); - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual WeightPtr createWeight(const SearcherPtr& searcher); /// Prints a user-readable version of this query. virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); protected: int32_t termArraysHashCode(); diff --git a/include/MultiReader.h b/include/MultiReader.h index 6264966e..d3034a43 100644 --- a/include/MultiReader.h +++ b/include/MultiReader.h @@ -52,12 +52,12 @@ namespace Lucene /// /// If subreaders are shared, then the reference count of those readers is increased to ensure that the /// subreaders remain open until the last referring reader is closed. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual Collection getTermFreqVectors(int32_t docNumber); virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); - virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); virtual bool isOptimized(); @@ -69,7 +69,7 @@ namespace Lucene /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine /// what {@link Field}s to load and how they should be loaded. - virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n); @@ -90,10 +90,10 @@ namespace Lucene virtual TermEnumPtr terms(); /// Returns an enumeration of all terms starting at a given term. - virtual TermEnumPtr terms(TermPtr t); + virtual TermEnumPtr terms(const TermPtr& t); /// Returns the number of documents containing the term t. - virtual int32_t docFreq(TermPtr t); + virtual int32_t docFreq(const TermPtr& t); /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs(); diff --git a/include/MultiSearcher.h b/include/MultiSearcher.h index d79a1efd..3bc4aef3 100644 --- a/include/MultiSearcher.h +++ b/include/MultiSearcher.h @@ -38,9 +38,9 @@ namespace Lucene Collection getSearchables(); virtual void close(); - virtual int32_t docFreq(TermPtr term); + virtual int32_t docFreq(const TermPtr& term); virtual DocumentPtr doc(int32_t n); - virtual DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); /// Returns index of the searcher for document n in the array used to construct this searcher. int32_t subSearcher(int32_t n); @@ -49,11 +49,11 @@ namespace Lucene int32_t subDoc(int32_t n); virtual int32_t maxDoc(); - virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n); - virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort); - virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr results); - virtual QueryPtr rewrite(QueryPtr query); - virtual ExplanationPtr explain(WeightPtr weight, int32_t doc); + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); + virtual QueryPtr rewrite(const QueryPtr& query); + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); protected: Collection getStarts(); @@ -71,7 +71,7 @@ namespace Lucene /// Steps 1-4 are done here, 5+6 in the search() methods /// /// @return rewritten queries - virtual WeightPtr createWeight(QueryPtr query); + virtual WeightPtr createWeight(const QueryPtr& query); }; } diff --git a/include/MultiTermQuery.h b/include/MultiTermQuery.h index c43e928b..ec4cc386 100644 --- a/include/MultiTermQuery.h +++ b/include/MultiTermQuery.h @@ -95,22 +95,22 @@ namespace Lucene /// @see #getTotalNumberOfTerms void clearTotalNumberOfTerms(); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); /// @see #setRewriteMethod virtual RewriteMethodPtr getRewriteMethod(); /// Sets the rewrite method to be used when executing the query. You can use one of the four core methods, /// or implement your own subclass of {@link RewriteMethod}. - virtual void setRewriteMethod(RewriteMethodPtr method); + virtual void setRewriteMethod(const RewriteMethodPtr& method); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); protected: /// Construct the enumeration to be used, expanding the pattern term. - virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader) = 0; + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader) = 0; void incTotalNumberOfTerms(int32_t inc); @@ -127,7 +127,7 @@ namespace Lucene LUCENE_CLASS(RewriteMethod); public: - virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) = 0; + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) = 0; }; /// A rewrite method that tries to pick the best constant-score rewrite method based on term and document @@ -170,10 +170,10 @@ namespace Lucene /// @see #setDocCountPercent virtual double getDocCountPercent(); - virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query); + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); }; } diff --git a/include/MultiTermQueryWrapperFilter.h b/include/MultiTermQueryWrapperFilter.h index afc0f361..61e2108a 100644 --- a/include/MultiTermQueryWrapperFilter.h +++ b/include/MultiTermQueryWrapperFilter.h @@ -23,7 +23,7 @@ namespace Lucene { INTERNAL: /// Wrap a {@link MultiTermQuery} as a Filter. - MultiTermQueryWrapperFilter(MultiTermQueryPtr query); + MultiTermQueryWrapperFilter(const MultiTermQueryPtr& query); public: virtual ~MultiTermQueryWrapperFilter(); @@ -35,7 +35,7 @@ namespace Lucene public: virtual String toString(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); /// Return the number of unique terms visited during execution of the filter. If there are many of them, @@ -52,7 +52,7 @@ namespace Lucene void clearTotalNumberOfTerms(); /// Returns a DocIdSet with documents that should be permitted in search results. - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); }; } diff --git a/include/MultipleTermPositions.h b/include/MultipleTermPositions.h index 1dc5a08b..055fb813 100644 --- a/include/MultipleTermPositions.h +++ b/include/MultipleTermPositions.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI MultipleTermPositions : public TermPositions, public LuceneObject { public: - MultipleTermPositions(IndexReaderPtr indexReader, Collection terms); + MultipleTermPositions(const IndexReaderPtr& indexReader, Collection terms); virtual ~MultipleTermPositions(); LUCENE_CLASS(MultipleTermPositions); @@ -36,10 +36,10 @@ namespace Lucene virtual void close(); /// Not implemented. - virtual void seek(TermPtr term); + virtual void seek(const TermPtr& term); /// Not implemented. - virtual void seek(TermEnumPtr termEnum); + virtual void seek(const TermEnumPtr& termEnum); /// Not implemented. virtual int32_t read(Collection docs, Collection freqs); diff --git a/include/NearSpansOrdered.h b/include/NearSpansOrdered.h index d34d8d01..c5c71571 100644 --- a/include/NearSpansOrdered.h +++ b/include/NearSpansOrdered.h @@ -31,7 +31,7 @@ namespace Lucene class LPPAPI NearSpansOrdered : public Spans { public: - NearSpansOrdered(SpanNearQueryPtr spanNearQuery, IndexReaderPtr reader, bool collectPayloads = true); + NearSpansOrdered(const SpanNearQueryPtr& spanNearQuery, const IndexReaderPtr& reader, bool collectPayloads = true); virtual ~NearSpansOrdered(); LUCENE_CLASS(NearSpansOrdered); @@ -71,7 +71,7 @@ namespace Lucene /// Check whether two Spans in the same document are ordered. /// @return true if spans1 starts before spans2 or the spans start at the same position, and /// spans1 ends before spans2. - static bool docSpansOrdered(SpansPtr spans1, SpansPtr spans2); + static bool docSpansOrdered(const SpansPtr& spans1, const SpansPtr& spans2); virtual String toString(); diff --git a/include/NearSpansUnordered.h b/include/NearSpansUnordered.h index 2fa08173..f8472ad7 100644 --- a/include/NearSpansUnordered.h +++ b/include/NearSpansUnordered.h @@ -17,7 +17,7 @@ namespace Lucene class LPPAPI NearSpansUnordered : public Spans { public: - NearSpansUnordered(SpanNearQueryPtr query, IndexReaderPtr reader); + NearSpansUnordered(const SpanNearQueryPtr& query, const IndexReaderPtr& reader); virtual ~NearSpansUnordered(); LUCENE_CLASS(NearSpansUnordered); @@ -58,7 +58,7 @@ namespace Lucene protected: SpansCellPtr min(); void initList(bool next); - void addToList(SpansCellPtr cell); + void addToList(const SpansCellPtr& cell); void firstToLast(); void queueToList(); void listToQueue(); diff --git a/include/NormsWriter.h b/include/NormsWriter.h index 74c9de6d..f7efd4b6 100644 --- a/include/NormsWriter.h +++ b/include/NormsWriter.h @@ -25,17 +25,17 @@ namespace Lucene FieldInfosPtr fieldInfos; public: - virtual InvertedDocEndConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread); + virtual InvertedDocEndConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread); virtual void abort(); // We only write the _X.nrm file at flush virtual void files(HashSet files); - virtual void setFieldInfos(FieldInfosPtr fieldInfos); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); /// Produce _X.nrm if any document had a field with norms not disabled - virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, SegmentWriteStatePtr state); - virtual void closeDocStore(SegmentWriteStatePtr state); + virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); protected: static uint8_t getDefaultNorm(); diff --git a/include/NormsWriterPerField.h b/include/NormsWriterPerField.h index a72ef958..91887f43 100644 --- a/include/NormsWriterPerField.h +++ b/include/NormsWriterPerField.h @@ -16,7 +16,7 @@ namespace Lucene class NormsWriterPerField : public InvertedDocEndConsumerPerField { public: - NormsWriterPerField(DocInverterPerFieldPtr docInverterPerField, NormsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo); + NormsWriterPerField(const DocInverterPerFieldPtr& docInverterPerField, const NormsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); virtual ~NormsWriterPerField(); LUCENE_CLASS(NormsWriterPerField); @@ -38,7 +38,7 @@ namespace Lucene virtual void abort(); /// Compare two objects - virtual int32_t compareTo(LuceneObjectPtr other); + virtual int32_t compareTo(const LuceneObjectPtr& other); virtual void finish(); }; diff --git a/include/NormsWriterPerThread.h b/include/NormsWriterPerThread.h index 1e9d4b53..627a5eeb 100644 --- a/include/NormsWriterPerThread.h +++ b/include/NormsWriterPerThread.h @@ -14,7 +14,7 @@ namespace Lucene class NormsWriterPerThread : public InvertedDocEndConsumerPerThread { public: - NormsWriterPerThread(DocInverterPerThreadPtr docInverterPerThread, NormsWriterPtr normsWriter); + NormsWriterPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const NormsWriterPtr& normsWriter); virtual ~NormsWriterPerThread(); LUCENE_CLASS(NormsWriterPerThread); @@ -24,7 +24,7 @@ namespace Lucene DocStatePtr docState; public: - virtual InvertedDocEndConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo); + virtual InvertedDocEndConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo); virtual void abort(); virtual void startDocument(); virtual void finishDocument(); diff --git a/include/NumericRangeFilter.h b/include/NumericRangeFilter.h index faacfeef..b119391f 100644 --- a/include/NumericRangeFilter.h +++ b/include/NumericRangeFilter.h @@ -24,7 +24,7 @@ namespace Lucene class LPPAPI NumericRangeFilter : public MultiTermQueryWrapperFilter { public: - NumericRangeFilter(NumericRangeQueryPtr query); + NumericRangeFilter(const NumericRangeQueryPtr& query); virtual ~NumericRangeFilter(); LUCENE_CLASS(NumericRangeFilter); diff --git a/include/NumericRangeQuery.h b/include/NumericRangeQuery.h index 914a9c88..62710d33 100644 --- a/include/NumericRangeQuery.h +++ b/include/NumericRangeQuery.h @@ -174,13 +174,13 @@ namespace Lucene /// Returns the upper value of this range query NumericValue getMax(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); protected: - virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); friend class NumericRangeTermEnum; }; diff --git a/include/NumericTokenStream.h b/include/NumericTokenStream.h index 28a5ea7d..c361106f 100644 --- a/include/NumericTokenStream.h +++ b/include/NumericTokenStream.h @@ -64,12 +64,12 @@ namespace Lucene /// Creates a token stream for numeric values with the specified precisionStep using the given {@link /// AttributeSource}. The stream is not yet initialized, before using set a value using the various /// setValue() methods. - NumericTokenStream(AttributeSourcePtr source, int32_t precisionStep); + NumericTokenStream(const AttributeSourcePtr& source, int32_t precisionStep); /// Creates a token stream for numeric values with the specified precisionStep using the given {@link /// AttributeFactory}. The stream is not yet initialized, before using set a value using the various /// setValue() methods. - NumericTokenStream(AttributeFactoryPtr factory, int32_t precisionStep); + NumericTokenStream(const AttributeFactoryPtr& factory, int32_t precisionStep); virtual ~NumericTokenStream(); diff --git a/include/NumericUtils.h b/include/NumericUtils.h index 720cb79f..fb302aca 100644 --- a/include/NumericUtils.h +++ b/include/NumericUtils.h @@ -130,18 +130,18 @@ namespace Lucene /// Splits a int64_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} /// for each call to its {@link LongRangeBuilder#addRange(String,String)} method. /// This method is used by {@link NumericRangeQuery}. - static void splitLongRange(LongRangeBuilderPtr builder, int32_t precisionStep, int64_t minBound, int64_t maxBound); + static void splitLongRange(const LongRangeBuilderPtr& builder, int32_t precisionStep, int64_t minBound, int64_t maxBound); /// Splits an int32_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} /// for each call to its {@link IntRangeBuilder#addRange(String,String)} method. /// This method is used by {@link NumericRangeQuery}. - static void splitIntRange(IntRangeBuilderPtr builder, int32_t precisionStep, int32_t minBound, int32_t maxBound); + static void splitIntRange(const IntRangeBuilderPtr& builder, int32_t precisionStep, int32_t minBound, int32_t maxBound); /// This helper does the splitting for both 32 and 64 bit. - static void splitRange(LuceneObjectPtr builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound); + static void splitRange(const LuceneObjectPtr& builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound); /// Helper that delegates to correct range builder - static void addRange(LuceneObjectPtr builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift); + static void addRange(const LuceneObjectPtr& builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift); }; /// Callback for {@link #splitLongRange}. You need to overwrite only one of the methods. diff --git a/include/OffsetAttribute.h b/include/OffsetAttribute.h index e53c275b..5e038a0e 100644 --- a/include/OffsetAttribute.h +++ b/include/OffsetAttribute.h @@ -43,10 +43,10 @@ namespace Lucene virtual int32_t endOffset(); virtual void clear(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual void copyTo(AttributePtr target); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/OpenBitSet.h b/include/OpenBitSet.h index ba49ed06..7078f31c 100644 --- a/include/OpenBitSet.h +++ b/include/OpenBitSet.h @@ -161,19 +161,19 @@ namespace Lucene /// Returns the popcount or cardinality of the intersection of the two sets. /// Neither set is modified. - static int64_t intersectionCount(OpenBitSetPtr a, OpenBitSetPtr b); + static int64_t intersectionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); /// Returns the popcount or cardinality of the union of the two sets. /// Neither set is modified. - static int64_t unionCount(OpenBitSetPtr a, OpenBitSetPtr b); + static int64_t unionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); /// Returns the popcount or cardinality of "a and not b" or "intersection(a, not(b))". /// Neither set is modified. - static int64_t andNotCount(OpenBitSetPtr a, OpenBitSetPtr b); + static int64_t andNotCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); /// Returns the popcount or cardinality of the exclusive-or of the two sets. /// Neither set is modified. - static int64_t xorCount(OpenBitSetPtr a, OpenBitSetPtr b); + static int64_t xorCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); /// Returns the index of the first set bit starting at the index specified. /// -1 is returned if there are no more set bits. @@ -183,31 +183,31 @@ namespace Lucene /// -1 is returned if there are no more set bits. int64_t nextSetBit(int64_t index); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// this = this AND other - void intersect(OpenBitSetPtr other); + void intersect(const OpenBitSetPtr& other); /// this = this OR other - void _union(OpenBitSetPtr other); + void _union(const OpenBitSetPtr& other); /// Remove all elements set in other. this = this AND_NOT other - void remove(OpenBitSetPtr other); + void remove(const OpenBitSetPtr& other); /// this = this XOR other - void _xor(OpenBitSetPtr other); + void _xor(const OpenBitSetPtr& other); /// see {@link intersect} - void _and(OpenBitSetPtr other); + void _and(const OpenBitSetPtr& other); /// see {@link union} - void _or(OpenBitSetPtr other); + void _or(const OpenBitSetPtr& other); /// see {@link remove} - void andNot(OpenBitSetPtr other); + void andNot(const OpenBitSetPtr& other); /// Returns true if the sets have any elements in common - bool intersects(OpenBitSetPtr other); + bool intersects(const OpenBitSetPtr& other); /// Expand the LongArray with the size given as a number of words (64 bit longs). /// getNumWords() is unchanged by this call. @@ -224,7 +224,7 @@ namespace Lucene static int32_t bits2words(int64_t numBits); /// Returns true if both sets have the same bits set - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); diff --git a/include/OpenBitSetDISI.h b/include/OpenBitSetDISI.h index 3a1428d9..50a351a3 100644 --- a/include/OpenBitSetDISI.h +++ b/include/OpenBitSetDISI.h @@ -17,7 +17,7 @@ namespace Lucene /// Construct an OpenBitSetDISI with its bits set from the doc ids of the given DocIdSetIterator. /// Also give a maximum size one larger than the largest doc id for which a bit may ever be set on /// this OpenBitSetDISI. - OpenBitSetDISI(DocIdSetIteratorPtr disi, int32_t maxSize); + OpenBitSetDISI(const DocIdSetIteratorPtr& disi, int32_t maxSize); /// Construct an OpenBitSetDISI with no bits set, and a given maximum size one larger than the largest /// doc id for which a bit may ever be set on this OpenBitSetDISI. @@ -30,20 +30,20 @@ namespace Lucene public: /// Perform an in-place OR with the doc ids from a given DocIdSetIterator, setting the bit for each /// such doc id. These doc ids should be smaller than the maximum size passed to the constructor. - void inPlaceOr(DocIdSetIteratorPtr disi); + void inPlaceOr(const DocIdSetIteratorPtr& disi); /// Perform an in-place AND with the doc ids from a given DocIdSetIterator, leaving only the bits set /// for which the doc ids are in common. These doc ids should be smaller than the maximum size passed /// to the constructor. - void inPlaceAnd(DocIdSetIteratorPtr disi); + void inPlaceAnd(const DocIdSetIteratorPtr& disi); /// Perform an in-place NOT with the doc ids from a given DocIdSetIterator, clearing all the bits for /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. - void inPlaceNot(DocIdSetIteratorPtr disi); + void inPlaceNot(const DocIdSetIteratorPtr& disi); /// Perform an inplace XOR with the doc ids from a given DocIdSetIterator, flipping all the bits for /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. - void inPlaceXor(DocIdSetIteratorPtr disi); + void inPlaceXor(const DocIdSetIteratorPtr& disi); }; } diff --git a/include/OpenBitSetIterator.h b/include/OpenBitSetIterator.h index 1acbb3b8..be0504db 100644 --- a/include/OpenBitSetIterator.h +++ b/include/OpenBitSetIterator.h @@ -17,7 +17,7 @@ namespace Lucene class LPPAPI OpenBitSetIterator : public DocIdSetIterator { public: - OpenBitSetIterator(OpenBitSetPtr bitSet); + OpenBitSetIterator(const OpenBitSetPtr& bitSet); OpenBitSetIterator(LongArray bits, int32_t numWords); virtual ~OpenBitSetIterator(); diff --git a/include/OrdFieldSource.h b/include/OrdFieldSource.h index 5db257dd..7ff6cd24 100644 --- a/include/OrdFieldSource.h +++ b/include/OrdFieldSource.h @@ -43,8 +43,8 @@ namespace Lucene public: virtual String description(); - virtual DocValuesPtr getValues(IndexReaderPtr reader); - virtual bool equals(LuceneObjectPtr other); + virtual DocValuesPtr getValues(const IndexReaderPtr& reader); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/ParallelMultiSearcher.h b/include/ParallelMultiSearcher.h index d616ec2e..36de1e8e 100644 --- a/include/ParallelMultiSearcher.h +++ b/include/ParallelMultiSearcher.h @@ -27,15 +27,15 @@ namespace Lucene public: /// Executes each {@link Searchable}'s docFreq() in its own thread and waits for each search to /// complete and merge the results back together. - virtual int32_t docFreq(TermPtr term); + virtual int32_t docFreq(const TermPtr& term); /// A search implementation which executes each {@link Searchable} in its own thread and waits /// for each search to complete and merge the results back together. - virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n); + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); /// A search implementation allowing sorting which spans a new thread for each Searchable, waits /// for each search to complete and merges the results back together. - virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); }; } diff --git a/include/ParallelReader.h b/include/ParallelReader.h index 873f9e0a..d3799060 100644 --- a/include/ParallelReader.h +++ b/include/ParallelReader.h @@ -49,13 +49,13 @@ namespace Lucene public: /// Add an IndexReader. - void add(IndexReaderPtr reader); + void add(const IndexReaderPtr& reader); /// Add an IndexReader whose stored fields will not be returned. This can accelerate search when stored /// fields are only needed from a subset of the IndexReaders. - void add(IndexReaderPtr reader, bool ignoreStoredFields); + void add(const IndexReaderPtr& reader, bool ignoreStoredFields); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Tries to reopen the subreaders. /// @@ -84,7 +84,7 @@ namespace Lucene virtual bool isDeleted(int32_t n); /// Get the {@link Document} at the n'th position. - virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); /// Return an array of term frequency vectors for the specified document. virtual Collection getTermFreqVectors(int32_t docNumber); @@ -94,10 +94,10 @@ namespace Lucene /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays /// of the {@link TermFreqVector}. - virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); /// Map all the term vectors for all fields in a Document - virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); /// Returns true if there are norms stored for this field. virtual bool hasNorms(const String& field); @@ -118,23 +118,23 @@ namespace Lucene /// exist, the enumeration is positioned at the first term greater than the supplied term. /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede /// it in the enumeration. - virtual TermEnumPtr terms(TermPtr t); + virtual TermEnumPtr terms(const TermPtr& t); /// Returns the number of documents containing the term t. - virtual int32_t docFreq(TermPtr t); + virtual int32_t docFreq(const TermPtr& t); /// Returns an enumeration of all the documents which contain term. For each document, the /// document number, the frequency of the term in that document is also provided, for use in /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. /// The enumeration is ordered by document number. Each document number is greater than all /// that precede it in the enumeration. - virtual TermDocsPtr termDocs(TermPtr term); + virtual TermDocsPtr termDocs(const TermPtr& term); /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs(); /// Returns an enumeration of all the documents which contain term. - virtual TermPositionsPtr termPositions(TermPtr term); + virtual TermPositionsPtr termPositions(const TermPtr& term); /// Returns an unpositioned {@link TermPositions} enumerator. virtual TermPositionsPtr termPositions(); diff --git a/include/Payload.h b/include/Payload.h index df31ed24..f0bfef1b 100644 --- a/include/Payload.h +++ b/include/Payload.h @@ -78,9 +78,9 @@ namespace Lucene void copyTo(ByteArray target, int32_t targetOffset); /// Clones this payload by creating a copy of the underlying byte array. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/PayloadAttribute.h b/include/PayloadAttribute.h index 7dff4d32..5b235abe 100644 --- a/include/PayloadAttribute.h +++ b/include/PayloadAttribute.h @@ -19,7 +19,7 @@ namespace Lucene PayloadAttribute(); /// Initialize this attribute with the given payload. - PayloadAttribute(PayloadPtr payload); + PayloadAttribute(const PayloadPtr& payload); virtual ~PayloadAttribute(); @@ -35,13 +35,13 @@ namespace Lucene virtual PayloadPtr getPayload(); /// Sets this Token's payload. - virtual void setPayload(PayloadPtr payload); + virtual void setPayload(const PayloadPtr& payload); virtual void clear(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual bool equals(LuceneObjectPtr other); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual void copyTo(AttributePtr target); + virtual void copyTo(const AttributePtr& target); }; } diff --git a/include/PayloadFunction.h b/include/PayloadFunction.h index 26abcb7f..67e16aba 100644 --- a/include/PayloadFunction.h +++ b/include/PayloadFunction.h @@ -51,7 +51,7 @@ namespace Lucene virtual int32_t hashCode() = 0; /// Return whether two objects are equal - virtual bool equals(LuceneObjectPtr other) = 0; + virtual bool equals(const LuceneObjectPtr& other) = 0; }; } diff --git a/include/PayloadNearQuery.h b/include/PayloadNearQuery.h index ed8560bd..75123123 100644 --- a/include/PayloadNearQuery.h +++ b/include/PayloadNearQuery.h @@ -26,7 +26,7 @@ namespace Lucene { public: PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder); - PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, PayloadFunctionPtr function); + PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, const PayloadFunctionPtr& function); virtual ~PayloadNearQuery(); @@ -39,11 +39,11 @@ namespace Lucene public: using SpanNearQuery::toString; - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); friend class PayloadNearSpanWeight; @@ -53,19 +53,19 @@ namespace Lucene class LPPAPI PayloadNearSpanWeight : public SpanWeight { public: - PayloadNearSpanWeight(SpanQueryPtr query, SearcherPtr searcher); + PayloadNearSpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher); virtual ~PayloadNearSpanWeight(); LUCENE_CLASS(PayloadNearSpanWeight); public: - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); }; class LPPAPI PayloadNearSpanScorer : public SpanScorer { public: - PayloadNearSpanScorer(SpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms); + PayloadNearSpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); virtual ~PayloadNearSpanScorer(); LUCENE_CLASS(PayloadNearSpanScorer); diff --git a/include/PayloadSpanUtil.h b/include/PayloadSpanUtil.h index 225c0203..b1609e74 100644 --- a/include/PayloadSpanUtil.h +++ b/include/PayloadSpanUtil.h @@ -17,7 +17,7 @@ namespace Lucene { public: /// @param reader That contains doc with payloads to extract - PayloadSpanUtil(IndexReaderPtr reader); + PayloadSpanUtil(const IndexReaderPtr& reader); virtual ~PayloadSpanUtil(); @@ -29,11 +29,11 @@ namespace Lucene public: /// Query should be rewritten for wild/fuzzy support. /// @return payloads Collection - Collection getPayloadsForQuery(QueryPtr query); + Collection getPayloadsForQuery(const QueryPtr& query); protected: - void queryToSpanQuery(QueryPtr query, Collection payloads); - void getPayloads(Collection payloads, SpanQueryPtr query); + void queryToSpanQuery(const QueryPtr& query, Collection payloads); + void getPayloads(Collection payloads, const SpanQueryPtr& query); }; } diff --git a/include/PayloadTermQuery.h b/include/PayloadTermQuery.h index dcfb7f31..bd7b551b 100644 --- a/include/PayloadTermQuery.h +++ b/include/PayloadTermQuery.h @@ -21,7 +21,7 @@ namespace Lucene class LPPAPI PayloadTermQuery : public SpanTermQuery { public: - PayloadTermQuery(TermPtr term, PayloadFunctionPtr function, bool includeSpanScore = true); + PayloadTermQuery(const TermPtr& term, const PayloadFunctionPtr& function, bool includeSpanScore = true); virtual ~PayloadTermQuery(); LUCENE_CLASS(PayloadTermQuery); @@ -31,10 +31,10 @@ namespace Lucene bool includeSpanScore; public: - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual bool equals(LuceneObjectPtr other); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); friend class PayloadTermWeight; diff --git a/include/PerFieldAnalyzerWrapper.h b/include/PerFieldAnalyzerWrapper.h index 88006bfd..07a8b31d 100644 --- a/include/PerFieldAnalyzerWrapper.h +++ b/include/PerFieldAnalyzerWrapper.h @@ -32,12 +32,12 @@ namespace Lucene /// Constructs with default analyzer. /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the /// one provided here. - PerFieldAnalyzerWrapper(AnalyzerPtr defaultAnalyzer); + PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer); /// Constructs with default analyzer and a map of analyzers to use for specific fields. /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the one provided here. /// @param fieldAnalyzers a Map (String field name to the Analyzer) to be used for those fields - PerFieldAnalyzerWrapper(AnalyzerPtr defaultAnalyzer, MapStringAnalyzer fieldAnalyzers); + PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer, MapStringAnalyzer fieldAnalyzers); virtual ~PerFieldAnalyzerWrapper(); @@ -51,16 +51,16 @@ namespace Lucene /// Defines an analyzer to use for the specified field. /// @param fieldName field name requiring a non-default analyzer /// @param analyzer non-default analyzer to use for field - void addAnalyzer(const String& fieldName, AnalyzerPtr analyzer); + void addAnalyzer(const String& fieldName, const AnalyzerPtr& analyzer); - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); /// Return the positionIncrementGap from the analyzer assigned to fieldName. virtual int32_t getPositionIncrementGap(const String& fieldName); /// Return the offsetGap from the analyzer assigned to field - virtual int32_t getOffsetGap(FieldablePtr field); + virtual int32_t getOffsetGap(const FieldablePtr& field); virtual String toString(); }; diff --git a/include/PhrasePositions.h b/include/PhrasePositions.h index a2201e0d..e1c917be 100644 --- a/include/PhrasePositions.h +++ b/include/PhrasePositions.h @@ -15,7 +15,7 @@ namespace Lucene class PhrasePositions : public LuceneObject { public: - PhrasePositions(TermPositionsPtr t, int32_t o); + PhrasePositions(const TermPositionsPtr& t, int32_t o); virtual ~PhrasePositions(); LUCENE_CLASS(PhrasePositions); diff --git a/include/PhraseQuery.h b/include/PhraseQuery.h index 3d8b4285..e10f875e 100644 --- a/include/PhraseQuery.h +++ b/include/PhraseQuery.h @@ -52,12 +52,12 @@ namespace Lucene /// Adds a term to the end of the query phrase. /// The relative position of the term is the one immediately after the last term added. - void add(TermPtr term); + void add(const TermPtr& term); /// Adds a term to the end of the query phrase. /// The relative position of the term within the phrase is specified explicitly. This allows eg. phrases /// with more than one term at the same position or phrases with gaps (eg. in connection with stopwords). - void add(TermPtr term, int32_t position); + void add(const TermPtr& term, int32_t position); /// Returns the set of terms in this phrase. Collection getTerms(); @@ -65,15 +65,15 @@ namespace Lucene /// Returns the relative positions of terms in this phrase. Collection getPositions(); - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); virtual void extractTerms(SetTerm terms); /// Prints a user-readable version of this query. virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); friend class PhraseWeight; }; diff --git a/include/PhraseScorer.h b/include/PhraseScorer.h index a1fd2090..be5442f1 100644 --- a/include/PhraseScorer.h +++ b/include/PhraseScorer.h @@ -21,7 +21,7 @@ namespace Lucene class PhraseScorer : public Scorer { public: - PhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, ByteArray norms); + PhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms); virtual ~PhraseScorer(); LUCENE_CLASS(PhraseScorer); diff --git a/include/PorterStemFilter.h b/include/PorterStemFilter.h index 90d5b88f..84f151be 100644 --- a/include/PorterStemFilter.h +++ b/include/PorterStemFilter.h @@ -22,7 +22,7 @@ namespace Lucene /// class MyAnalyzer : public Analyzer /// { /// public: - /// virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + /// virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) /// { /// return newLucene(newLucene(reader)); /// } @@ -31,7 +31,7 @@ namespace Lucene class LPPAPI PorterStemFilter : public TokenFilter { public: - PorterStemFilter(TokenStreamPtr input); + PorterStemFilter(const TokenStreamPtr& input); virtual ~PorterStemFilter(); LUCENE_CLASS(PorterStemFilter); diff --git a/include/PositionBasedTermVectorMapper.h b/include/PositionBasedTermVectorMapper.h index 7aa72816..06cb2d29 100644 --- a/include/PositionBasedTermVectorMapper.h +++ b/include/PositionBasedTermVectorMapper.h @@ -61,7 +61,7 @@ namespace Lucene Collection offsets; public: - void addTerm(const String& term, TermVectorOffsetInfoPtr info); + void addTerm(const String& term, const TermVectorOffsetInfoPtr& info); /// @return The position of the term int32_t getPosition(); diff --git a/include/PositionIncrementAttribute.h b/include/PositionIncrementAttribute.h index 3e3b8abd..8d4fa5d8 100644 --- a/include/PositionIncrementAttribute.h +++ b/include/PositionIncrementAttribute.h @@ -52,10 +52,10 @@ namespace Lucene virtual int32_t getPositionIncrement(); virtual void clear(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual void copyTo(AttributePtr target); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/PositiveScoresOnlyCollector.h b/include/PositiveScoresOnlyCollector.h index 2582e0f5..0f493e67 100644 --- a/include/PositiveScoresOnlyCollector.h +++ b/include/PositiveScoresOnlyCollector.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI PositiveScoresOnlyCollector : public Collector { public: - PositiveScoresOnlyCollector(CollectorPtr c); + PositiveScoresOnlyCollector(const CollectorPtr& c); virtual ~PositiveScoresOnlyCollector(); LUCENE_CLASS(PositiveScoresOnlyCollector); @@ -27,8 +27,8 @@ namespace Lucene public: virtual void collect(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setScorer(ScorerPtr scorer); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); virtual bool acceptsDocsOutOfOrder(); }; } diff --git a/include/PrefixFilter.h b/include/PrefixFilter.h index 2ddda2f1..8ab5e4a8 100644 --- a/include/PrefixFilter.h +++ b/include/PrefixFilter.h @@ -15,7 +15,7 @@ namespace Lucene class LPPAPI PrefixFilter : public MultiTermQueryWrapperFilter { public: - PrefixFilter(TermPtr prefix); + PrefixFilter(const TermPtr& prefix); virtual ~PrefixFilter(); LUCENE_CLASS(PrefixFilter); diff --git a/include/PrefixQuery.h b/include/PrefixQuery.h index 27b40bb7..0dc65128 100644 --- a/include/PrefixQuery.h +++ b/include/PrefixQuery.h @@ -19,7 +19,7 @@ namespace Lucene { public: /// Constructs a query for terms starting with prefix. - PrefixQuery(TermPtr prefix); + PrefixQuery(const TermPtr& prefix); virtual ~PrefixQuery(); @@ -37,12 +37,12 @@ namespace Lucene /// Prints a user-readable version of this query. virtual String toString(const String& field); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); protected: - virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); }; } diff --git a/include/PrefixTermEnum.h b/include/PrefixTermEnum.h index b0aa6769..9f4b09cf 100644 --- a/include/PrefixTermEnum.h +++ b/include/PrefixTermEnum.h @@ -18,7 +18,7 @@ namespace Lucene class LPPAPI PrefixTermEnum : public FilteredTermEnum { public: - PrefixTermEnum(IndexReaderPtr reader, TermPtr prefix); + PrefixTermEnum(const IndexReaderPtr& reader, const TermPtr& prefix); virtual ~PrefixTermEnum(); LUCENE_CLASS(PrefixTermEnum); @@ -32,7 +32,7 @@ namespace Lucene protected: virtual bool endEnum(); - virtual bool termCompare(TermPtr term); + virtual bool termCompare(const TermPtr& term); TermPtr getPrefixTerm(); }; diff --git a/include/Query.h b/include/Query.h index 8ec8ce23..5c7200d0 100644 --- a/include/Query.h +++ b/include/Query.h @@ -66,14 +66,14 @@ namespace Lucene /// Constructs an appropriate Weight implementation for this query. /// Only implemented by primitive queries, which re-write to themselves. - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); /// Constructs and initializes a Weight for a top-level query. - virtual WeightPtr weight(SearcherPtr searcher); + virtual WeightPtr weight(const SearcherPtr& searcher); /// Called to re-write queries into primitive queries. For example, a PrefixQuery will be rewritten /// into a BooleanQuery that consists of TermQuerys. - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); /// Called when re-writing queries under MultiSearcher. /// @@ -96,13 +96,13 @@ namespace Lucene /// Returns the Similarity implementation to be used for this query. Subclasses may override this method /// to specify their own Similarity implementation, perhaps one that delegates through that of the Searcher. /// By default the Searcher's Similarity implementation is returned. - virtual SimilarityPtr getSimilarity(SearcherPtr searcher); + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); /// Returns a clone of this query. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); /// Return given boost value as a string. String boostString(); diff --git a/include/QueryParseError.h b/include/QueryParseError.h index d4de3cbf..bc211e1c 100644 --- a/include/QueryParseError.h +++ b/include/QueryParseError.h @@ -39,7 +39,7 @@ namespace Lucene /// of the parse. /// @param tokenImage This is a reference to the "tokenImage" array of the generated parser within /// which the parse error occurred. - static String parseError(QueryParserTokenPtr currentToken, Collection< Collection > expectedTokenSequences, + static String parseError(const QueryParserTokenPtr& currentToken, Collection< Collection > expectedTokenSequences, Collection tokenImage); diff --git a/include/QueryParser.h b/include/QueryParser.h index b976e353..2278bd89 100644 --- a/include/QueryParser.h +++ b/include/QueryParser.h @@ -74,13 +74,13 @@ namespace Lucene /// @param matchVersion Lucene version to match. /// @param field The default field for query terms. /// @param analyzer Used to find terms in the query text. - QueryParser(LuceneVersion::Version matchVersion, const String& field, AnalyzerPtr analyzer); + QueryParser(LuceneVersion::Version matchVersion, const String& field, const AnalyzerPtr& analyzer); /// Constructor with user supplied QueryParserCharStream. - QueryParser(QueryParserCharStreamPtr stream); + QueryParser(const QueryParserCharStreamPtr& stream); /// Constructor with generated Token Manager. - QueryParser(QueryParserTokenManagerPtr tokenMgr); + QueryParser(const QueryParserTokenManagerPtr& tokenMgr); virtual ~QueryParser(); @@ -245,7 +245,7 @@ namespace Lucene /// any "TooManyClauses" exception. However, if your application really needs to use the old- /// fashioned BooleanQuery expansion rewriting and the above points are not relevant then use this /// to change the rewrite method. - void setMultiTermRewriteMethod(RewriteMethodPtr method); + void setMultiTermRewriteMethod(const RewriteMethodPtr& method); /// @see #setMultiTermRewriteMethod RewriteMethodPtr getMultiTermRewriteMethod(); @@ -277,7 +277,7 @@ namespace Lucene /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending /// on the number of index Terms in this Field, the operation could be very slow. /// @param rc The collator to use when constructing RangeQuerys - void setRangeCollator(CollatorPtr rc); + void setRangeCollator(const CollatorPtr& rc); /// @return the collator used to determine index term inclusion in ranges for RangeQuerys. CollatorPtr getRangeCollator(); @@ -298,10 +298,10 @@ namespace Lucene virtual QueryPtr ParseTerm(const String& field); /// Reinitialise. - virtual void ReInit(QueryParserCharStreamPtr stream); + virtual void ReInit(const QueryParserCharStreamPtr& stream); /// Reinitialise. - virtual void ReInit(QueryParserTokenManagerPtr tokenMgr); + virtual void ReInit(const QueryParserTokenManagerPtr& tokenMgr); /// Get the next Token. virtual QueryParserTokenPtr getNextToken(); @@ -320,9 +320,9 @@ namespace Lucene protected: /// Construct query parser with supplied QueryParserCharStream or TokenManager - void ConstructParser(QueryParserCharStreamPtr stream, QueryParserTokenManagerPtr tokenMgr); + void ConstructParser(const QueryParserCharStreamPtr& stream, const QueryParserTokenManagerPtr& tokenMgr); - virtual void addClause(Collection clauses, int32_t conj, int32_t mods, QueryPtr q); + virtual void addClause(Collection clauses, int32_t conj, int32_t mods, const QueryPtr& q); /// Use the analyzer to get all the tokens, and then build a TermQuery, PhraseQuery, or nothing /// based on the term count. @@ -343,12 +343,12 @@ namespace Lucene /// @param q sub query /// @param occur how this clause should occur when matching documents /// @return new BooleanClause instance - BooleanClausePtr newBooleanClause(QueryPtr q, BooleanClause::Occur occur); + BooleanClausePtr newBooleanClause(const QueryPtr& q, BooleanClause::Occur occur); /// Builds a new TermQuery instance /// @param term term /// @return new TermQuery instance - QueryPtr newTermQuery(TermPtr term); + QueryPtr newTermQuery(const TermPtr& term); /// Builds a new PhraseQuery instance /// @return new PhraseQuery instance @@ -361,14 +361,14 @@ namespace Lucene /// Builds a new PrefixQuery instance /// @param prefix Prefix term /// @return new PrefixQuery instance - QueryPtr newPrefixQuery(TermPtr prefix); + QueryPtr newPrefixQuery(const TermPtr& prefix); /// Builds a new FuzzyQuery instance /// @param term Term /// @param minimumSimilarity minimum similarity /// @param prefixLength prefix length /// @return new FuzzyQuery Instance - QueryPtr newFuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength); + QueryPtr newFuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); /// Builds a new TermRangeQuery instance /// @param field Field @@ -385,7 +385,7 @@ namespace Lucene /// Builds a new WildcardQuery instance /// @param t wildcard term /// @return new WildcardQuery instance - QueryPtr newWildcardQuery(TermPtr term); + QueryPtr newWildcardQuery(const TermPtr& term); /// Factory method for generating query, given a set of clauses. By default creates a boolean query /// composed of clauses passed in. diff --git a/include/QueryParserTokenManager.h b/include/QueryParserTokenManager.h index 13943292..726fb419 100644 --- a/include/QueryParserTokenManager.h +++ b/include/QueryParserTokenManager.h @@ -15,8 +15,8 @@ namespace Lucene class LPPAPI QueryParserTokenManager : public QueryParserConstants, public LuceneObject { public: - QueryParserTokenManager(QueryParserCharStreamPtr stream); - QueryParserTokenManager(QueryParserCharStreamPtr stream, int32_t lexState); + QueryParserTokenManager(const QueryParserCharStreamPtr& stream); + QueryParserTokenManager(const QueryParserCharStreamPtr& stream, int32_t lexState); virtual ~QueryParserTokenManager(); @@ -58,13 +58,13 @@ namespace Lucene public: /// Set debug output. - void setDebugStream(InfoStreamPtr debugStream); + void setDebugStream(const InfoStreamPtr& debugStream); /// Reinitialise parser. - void ReInit(QueryParserCharStreamPtr stream); + void ReInit(const QueryParserCharStreamPtr& stream); /// Reinitialise parser. - void ReInit(QueryParserCharStreamPtr stream, int32_t lexState); + void ReInit(const QueryParserCharStreamPtr& stream, int32_t lexState); /// Switch to specified lex state. void SwitchTo(int32_t lexState); diff --git a/include/QueryTermVector.h b/include/QueryTermVector.h index 5b64c123..929de7f1 100644 --- a/include/QueryTermVector.h +++ b/include/QueryTermVector.h @@ -16,7 +16,7 @@ namespace Lucene public: /// @param queryTerms The original list of terms from the query, can contain duplicates QueryTermVector(Collection queryTerms); - QueryTermVector(const String& queryString, AnalyzerPtr analyzer); + QueryTermVector(const String& queryString, const AnalyzerPtr& analyzer); virtual ~QueryTermVector(); diff --git a/include/QueryWrapperFilter.h b/include/QueryWrapperFilter.h index 92b4de9f..8281ecba 100644 --- a/include/QueryWrapperFilter.h +++ b/include/QueryWrapperFilter.h @@ -21,7 +21,7 @@ namespace Lucene { public: /// Constructs a filter which only matches documents matching query. - QueryWrapperFilter(QueryPtr query); + QueryWrapperFilter(const QueryPtr& query); virtual ~QueryWrapperFilter(); @@ -31,9 +31,9 @@ namespace Lucene QueryPtr query; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); virtual String toString(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/RAMDirectory.h b/include/RAMDirectory.h index 0795226e..e9b9dc81 100644 --- a/include/RAMDirectory.h +++ b/include/RAMDirectory.h @@ -29,9 +29,9 @@ namespace Lucene /// original Directory (it is a complete copy). Any subsequent changes to the /// original Directory will not be visible in the RAMDirectory instance. /// @param dir a Directory value - RAMDirectory(DirectoryPtr dir); + RAMDirectory(const DirectoryPtr& dir); - RAMDirectory(DirectoryPtr dir, bool closeDir); + RAMDirectory(const DirectoryPtr& dir, bool closeDir); virtual ~RAMDirectory(); diff --git a/include/RAMFile.h b/include/RAMFile.h index 55e43542..dd14a466 100644 --- a/include/RAMFile.h +++ b/include/RAMFile.h @@ -16,7 +16,7 @@ namespace Lucene { public: RAMFile(); // File used as buffer, in no RAMDirectory - RAMFile(RAMDirectoryPtr directory); + RAMFile(const RAMDirectoryPtr& directory); virtual ~RAMFile(); LUCENE_CLASS(RAMFile); diff --git a/include/RAMInputStream.h b/include/RAMInputStream.h index ea3feb2c..169f0d18 100644 --- a/include/RAMInputStream.h +++ b/include/RAMInputStream.h @@ -16,7 +16,7 @@ namespace Lucene { public: RAMInputStream(); - RAMInputStream(RAMFilePtr f); + RAMInputStream(const RAMFilePtr& f); virtual ~RAMInputStream(); LUCENE_CLASS(RAMInputStream); @@ -60,7 +60,7 @@ namespace Lucene virtual void seek(int64_t pos); /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); protected: void switchCurrentBuffer(bool enforceEOF); diff --git a/include/RAMOutputStream.h b/include/RAMOutputStream.h index 3634dac3..d5479e57 100644 --- a/include/RAMOutputStream.h +++ b/include/RAMOutputStream.h @@ -17,7 +17,7 @@ namespace Lucene public: /// Construct an empty output buffer. RAMOutputStream(); - RAMOutputStream(RAMFilePtr f); + RAMOutputStream(const RAMFilePtr& f); virtual ~RAMOutputStream(); LUCENE_CLASS(RAMOutputStream); @@ -35,7 +35,7 @@ namespace Lucene public: /// Copy the current contents of this buffer to the named output. - void writeTo(IndexOutputPtr out); + void writeTo(const IndexOutputPtr& out); /// Resets this to an empty file. void reset(); diff --git a/include/ReadOnlyDirectoryReader.h b/include/ReadOnlyDirectoryReader.h index 9828bc7f..215635ce 100644 --- a/include/ReadOnlyDirectoryReader.h +++ b/include/ReadOnlyDirectoryReader.h @@ -14,10 +14,10 @@ namespace Lucene class ReadOnlyDirectoryReader : public DirectoryReader { public: - ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor); - ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, + ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor); + ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, Collection oldStarts, MapStringByteArray oldNormsCache, bool doClone, int32_t termInfosIndexDivisor); - ReadOnlyDirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor); + ReadOnlyDirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor); virtual ~ReadOnlyDirectoryReader(); LUCENE_CLASS(ReadOnlyDirectoryReader); diff --git a/include/ReaderUtil.h b/include/ReaderUtil.h index ab2f2dcb..ccd762cf 100644 --- a/include/ReaderUtil.h +++ b/include/ReaderUtil.h @@ -20,21 +20,21 @@ namespace Lucene public: /// Gathers sub-readers from reader into a List. - static void gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader); + static void gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader); /// Returns sub IndexReader that contains the given document id. /// /// @param doc Id of document /// @param reader Parent reader /// @return Sub reader of parent which contains the specified doc id - static IndexReaderPtr subReader(int32_t doc, IndexReaderPtr reader); + static IndexReaderPtr subReader(int32_t doc, const IndexReaderPtr& reader); /// Returns sub-reader subIndex from reader. /// /// @param reader Parent reader /// @param subIndex Index of desired sub reader /// @return The subreader at subIndex - static IndexReaderPtr subReader(IndexReaderPtr reader, int32_t subIndex); + static IndexReaderPtr subReader(const IndexReaderPtr& reader, int32_t subIndex); /// Returns index of the searcher/reader for document n in the array used to construct this /// searcher/reader. diff --git a/include/ReqExclScorer.h b/include/ReqExclScorer.h index fd47a648..7180d5c3 100644 --- a/include/ReqExclScorer.h +++ b/include/ReqExclScorer.h @@ -19,7 +19,7 @@ namespace Lucene /// Construct a ReqExclScorer. /// @param reqScorer The scorer that must match, except where /// @param exclDisi indicates exclusion. - ReqExclScorer(ScorerPtr reqScorer, DocIdSetIteratorPtr exclDisi); + ReqExclScorer(const ScorerPtr& reqScorer, const DocIdSetIteratorPtr& exclDisi); virtual ~ReqExclScorer(); LUCENE_CLASS(ReqExclScorer); diff --git a/include/ReqOptSumScorer.h b/include/ReqOptSumScorer.h index 0c907506..71c59a5b 100644 --- a/include/ReqOptSumScorer.h +++ b/include/ReqOptSumScorer.h @@ -16,7 +16,7 @@ namespace Lucene class ReqOptSumScorer : public Scorer { public: - ReqOptSumScorer(ScorerPtr reqScorer, ScorerPtr optScorer); + ReqOptSumScorer(const ScorerPtr& reqScorer, const ScorerPtr& optScorer); virtual ~ReqOptSumScorer(); LUCENE_CLASS(ReqOptSumScorer); diff --git a/include/ReverseOrdFieldSource.h b/include/ReverseOrdFieldSource.h index 4f215381..bf7bc976 100644 --- a/include/ReverseOrdFieldSource.h +++ b/include/ReverseOrdFieldSource.h @@ -43,8 +43,8 @@ namespace Lucene public: virtual String description(); - virtual DocValuesPtr getValues(IndexReaderPtr reader); - virtual bool equals(LuceneObjectPtr other); + virtual DocValuesPtr getValues(const IndexReaderPtr& reader); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/ScoreCachingWrappingScorer.h b/include/ScoreCachingWrappingScorer.h index 516e185d..403a47db 100644 --- a/include/ScoreCachingWrappingScorer.h +++ b/include/ScoreCachingWrappingScorer.h @@ -23,7 +23,7 @@ namespace Lucene { public: /// Creates a new instance by wrapping the given scorer. - ScoreCachingWrappingScorer(ScorerPtr scorer); + ScoreCachingWrappingScorer(const ScorerPtr& scorer); virtual ~ScoreCachingWrappingScorer(); LUCENE_CLASS(ScoreCachingWrappingScorer); @@ -38,11 +38,11 @@ namespace Lucene virtual double score(); virtual int32_t docID(); virtual int32_t nextDoc(); - virtual void score(CollectorPtr collector); + virtual void score(const CollectorPtr& collector); virtual int32_t advance(int32_t target); protected: - virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); }; } diff --git a/include/Scorer.h b/include/Scorer.h index 063fbb44..0a9dbc74 100644 --- a/include/Scorer.h +++ b/include/Scorer.h @@ -24,7 +24,7 @@ namespace Lucene public: /// Constructs a Scorer. /// @param similarity The Similarity implementation used by this scorer. - Scorer(SimilarityPtr similarity); + Scorer(const SimilarityPtr& similarity); virtual ~Scorer(); LUCENE_CLASS(Scorer); @@ -38,7 +38,7 @@ namespace Lucene /// Scores and collects all matching documents. /// @param collector The collector to which all matching documents are passed. - virtual void score(CollectorPtr collector); + virtual void score(const CollectorPtr& collector); /// Returns the score of the current document matching the query. Initially invalid, until {@link /// #nextDoc()} or {@link #advance(int32_t)} is called the first time, or when called from within @@ -53,7 +53,7 @@ namespace Lucene /// @param max Do not score documents past this. /// @param firstDocID The first document ID (ensures {@link #nextDoc()} is called before this method. /// @return true if more matching documents may remain. - virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); friend class BooleanScorer; friend class ScoreCachingWrappingScorer; diff --git a/include/ScorerDocQueue.h b/include/ScorerDocQueue.h index 9652a0dc..3613d426 100644 --- a/include/ScorerDocQueue.h +++ b/include/ScorerDocQueue.h @@ -30,12 +30,12 @@ namespace Lucene public: /// Adds a Scorer to a ScorerDocQueue in log(size) time. If one tries to add more Scorers than maxSize /// ArrayIndexOutOfBound exception is thrown. - void put(ScorerPtr scorer); + void put(const ScorerPtr& scorer); /// Adds a Scorer to the ScorerDocQueue in log(size) time if either the ScorerDocQueue is not full, or /// not lessThan(scorer, top()). /// @return true if scorer is added, false otherwise. - bool insert(ScorerPtr scorer); + bool insert(const ScorerPtr& scorer); /// Returns the least Scorer of the ScorerDocQueue in constant time. Should not be used when the queue /// is empty. diff --git a/include/Searchable.h b/include/Searchable.h index eb042c26..0b8088ec 100644 --- a/include/Searchable.h +++ b/include/Searchable.h @@ -39,7 +39,7 @@ namespace Lucene /// @param weight To match documents /// @param filter If non-null, used to permit documents to be collected. /// @param collector To receive hits - virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr collector) = 0; + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) = 0; /// Frees resources associated with this Searcher. Be careful not to call this method while you are still /// using objects that reference this Searchable. @@ -47,7 +47,7 @@ namespace Lucene /// Returns the number of documents containing term. /// @see IndexReader#docFreq(TermPtr) - virtual int32_t docFreq(TermPtr term) = 0; + virtual int32_t docFreq(const TermPtr& term) = 0; /// For each term in the terms array, calculates the number of documents containing term. Returns an array /// with these document frequencies. Used to minimize number of remote calls. @@ -60,7 +60,7 @@ namespace Lucene /// Low-level search implementation. Finds the top n hits for query, applying filter if non-null. /// Applications should usually call {@link Searcher#search(QueryPtr, int32_t)} or {@link /// Searcher#search(QueryPtr, FilterPtr, int32_t)} instead. - virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n) = 0; + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) = 0; /// Returns the stored fields of document i. /// @see IndexReader#document(int32_t) @@ -83,10 +83,10 @@ namespace Lucene /// @see FieldSelector /// @see SetBasedFieldSelector /// @see LoadFirstFieldSelector - virtual DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector) = 0; + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; /// Called to re-write queries into primitive queries. - virtual QueryPtr rewrite(QueryPtr query) = 0; + virtual QueryPtr rewrite(const QueryPtr& query) = 0; /// Low-level implementation method. Returns an Explanation that describes how doc scored against weight. /// @@ -95,13 +95,13 @@ namespace Lucene /// the entire index. /// /// Applications should call {@link Searcher#explain(QueryPtr, int32_t)}. - virtual ExplanationPtr explain(WeightPtr weight, int32_t doc) = 0; + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc) = 0; /// Low-level search implementation with arbitrary sorting. Finds the top n hits for query, applying filter /// if non-null, and sorting the hits by the criteria in sort. /// /// Applications should usually call {@link Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr)} instead. - virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) = 0; + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) = 0; }; } diff --git a/include/Searcher.h b/include/Searcher.h index f517e059..4f71a1c0 100644 --- a/include/Searcher.h +++ b/include/Searcher.h @@ -33,7 +33,7 @@ namespace Lucene /// /// NOTE: this does not compute scores by default; use {@link IndexSearcher#setDefaultFieldSortScoring} /// to enable scoring. - virtual TopFieldDocsPtr search(QueryPtr query, FilterPtr filter, int32_t n, SortPtr sort); + virtual TopFieldDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort); /// Lower-level search API. /// @@ -45,7 +45,7 @@ namespace Lucene /// /// Note: The score passed to this method is a raw score. In other words, the score will not necessarily /// be a double whose value is between 0 and 1. - virtual void search(QueryPtr query, CollectorPtr results); + virtual void search(const QueryPtr& query, const CollectorPtr& results); /// Lower-level search API. /// @@ -59,23 +59,23 @@ namespace Lucene /// @param query To match documents /// @param filter If non-null, used to permit documents to be collected. /// @param results To receive hits - virtual void search(QueryPtr query, FilterPtr filter, CollectorPtr results); + virtual void search(const QueryPtr& query, const FilterPtr& filter, const CollectorPtr& results); /// Finds the top n hits for query, applying filter if non-null. - virtual TopDocsPtr search(QueryPtr query, FilterPtr filter, int32_t n); + virtual TopDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n); /// Finds the top n hits for query. - virtual TopDocsPtr search(QueryPtr query, int32_t n); + virtual TopDocsPtr search(const QueryPtr& query, int32_t n); /// Returns an Explanation that describes how doc scored against query. /// /// This is intended to be used in developing Similarity implementations, and for good performance, /// should not be displayed with every hit. Computing an explanation is as expensive as executing the /// query over the entire index. - virtual ExplanationPtr explain(QueryPtr query, int32_t doc); + virtual ExplanationPtr explain(const QueryPtr& query, int32_t doc); /// Set the Similarity implementation used by this Searcher. - virtual void setSimilarity(SimilarityPtr similarity); + virtual void setSimilarity(const SimilarityPtr& similarity); /// Return the Similarity implementation used by this Searcher. /// @@ -84,21 +84,21 @@ namespace Lucene virtual Collection docFreqs(Collection terms); - virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr results) = 0; + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) = 0; virtual void close() = 0; - virtual int32_t docFreq(TermPtr term) = 0; + virtual int32_t docFreq(const TermPtr& term) = 0; virtual int32_t maxDoc() = 0; - virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n) = 0; + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) = 0; virtual DocumentPtr doc(int32_t n) = 0; - virtual DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector) = 0; - virtual QueryPtr rewrite(QueryPtr query) = 0; - virtual ExplanationPtr explain(WeightPtr weight, int32_t doc) = 0; - virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) = 0; + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; + virtual QueryPtr rewrite(const QueryPtr& query) = 0; + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc) = 0; + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) = 0; protected: /// Creates a weight for query. /// @return New weight - virtual WeightPtr createWeight(QueryPtr query); + virtual WeightPtr createWeight(const QueryPtr& query); }; } diff --git a/include/SegmentInfo.h b/include/SegmentInfo.h index 0e1cb459..0e431a1f 100644 --- a/include/SegmentInfo.h +++ b/include/SegmentInfo.h @@ -16,11 +16,11 @@ namespace Lucene class LPPAPI SegmentInfo : public LuceneObject { public: - SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir); + SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir); - SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, bool hasSingleNormFile); + SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile); - SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, + SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile, int32_t docStoreOffset, const String& docStoreSegment, bool docStoreIsCompoundFile, bool hasProx); @@ -28,7 +28,7 @@ namespace Lucene /// @param dir directory to load from. /// @param format format of the segments info file. /// @param input input handle to read segment info from. - SegmentInfo(DirectoryPtr dir, int32_t format, IndexInputPtr input); + SegmentInfo(const DirectoryPtr& dir, int32_t format, const IndexInputPtr& input); virtual ~SegmentInfo(); @@ -95,7 +95,7 @@ namespace Lucene public: /// Copy everything from src SegmentInfo into our instance. - void reset(SegmentInfoPtr src); + void reset(const SegmentInfoPtr& src); void setDiagnostics(MapStringString diagnostics); MapStringString getDiagnostics(); @@ -109,7 +109,7 @@ namespace Lucene void advanceDelGen(); void clearDelGen(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); String getDelFileName(); @@ -145,7 +145,7 @@ namespace Lucene void setDocStore(int32_t offset, const String& segment, bool isCompoundFile); /// Save this segment's info. - void write(IndexOutputPtr output); + void write(const IndexOutputPtr& output); void setHasProx(bool hasProx); bool getHasProx(); @@ -155,10 +155,10 @@ namespace Lucene HashSet files(); /// Used for debugging. - String segString(DirectoryPtr dir); + String segString(const DirectoryPtr& dir); /// We consider another SegmentInfo instance equal if it has the same dir and same name. - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); diff --git a/include/SegmentInfoCollection.h b/include/SegmentInfoCollection.h index 9e7b379e..ae5c509d 100644 --- a/include/SegmentInfoCollection.h +++ b/include/SegmentInfoCollection.h @@ -27,16 +27,16 @@ namespace Lucene int32_t size(); bool empty(); void clear(); - void add(SegmentInfoPtr info); - void add(int32_t pos, SegmentInfoPtr info); - void addAll(SegmentInfoCollectionPtr segmentInfos); - bool equals(SegmentInfoCollectionPtr other); - int32_t find(SegmentInfoPtr info); - bool contains(SegmentInfoPtr info); + void add(const SegmentInfoPtr& info); + void add(int32_t pos, const SegmentInfoPtr& info); + void addAll(const SegmentInfoCollectionPtr& segmentInfos); + bool equals(const SegmentInfoCollectionPtr& other); + int32_t find(const SegmentInfoPtr& info); + bool contains(const SegmentInfoPtr& info); void remove(int32_t pos); void remove(int32_t start, int32_t end); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/SegmentInfos.h b/include/SegmentInfos.h index 49ae6d1d..69d01749 100644 --- a/include/SegmentInfos.h +++ b/include/SegmentInfos.h @@ -86,13 +86,13 @@ namespace Lucene String getNextSegmentFileName(); /// Read a particular segmentFileName. Note that this may throw an IOException if a commit is in process. - void read(DirectoryPtr directory, const String& segmentFileName); + void read(const DirectoryPtr& directory, const String& segmentFileName); /// This version of read uses the retry logic (for lock-less commits) to find the right segments file to load. - void read(DirectoryPtr directory); + void read(const DirectoryPtr& directory); /// Returns a copy of this instance, also copying each SegmentInfo. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Version number when this SegmentInfos was generated. int64_t getVersion(); @@ -104,49 +104,49 @@ namespace Lucene SegmentInfosPtr range(int32_t first, int32_t last); /// Carry over generation numbers from another SegmentInfos. - void updateGeneration(SegmentInfosPtr other); + void updateGeneration(const SegmentInfosPtr& other); - void rollbackCommit(DirectoryPtr dir); + void rollbackCommit(const DirectoryPtr& dir); /// Call this to start a commit. This writes the new segments file, but writes an invalid checksum at the end, so /// that it is not visible to readers. Once this is called you must call. /// {@link #finishCommit} to complete the commit or /// {@link #rollbackCommit} to abort it. - void prepareCommit(DirectoryPtr dir); + void prepareCommit(const DirectoryPtr& dir); /// Returns all file names referenced by SegmentInfo instances matching the provided Directory (ie files associated /// with any "external" segments are skipped). The returned collection is recomputed on each invocation. - HashSet files(DirectoryPtr dir, bool includeSegmentsFile); + HashSet files(const DirectoryPtr& dir, bool includeSegmentsFile); - void finishCommit(DirectoryPtr dir); + void finishCommit(const DirectoryPtr& dir); /// Writes & syncs to the Directory dir, taking care to remove the segments file on exception. - void commit(DirectoryPtr dir); + void commit(const DirectoryPtr& dir); - String segString(DirectoryPtr directory); + String segString(const DirectoryPtr& directory); MapStringString getUserData(); void setUserData(MapStringString data); /// Replaces all segments in this instance, but keeps generation, version, counter so that future commits remain /// write once. - void replace(SegmentInfosPtr other); + void replace(const SegmentInfosPtr& other); - bool hasExternalSegments(DirectoryPtr dir); + bool hasExternalSegments(const DirectoryPtr& dir); static int64_t getCurrentSegmentGeneration(HashSet files); - static int64_t getCurrentSegmentGeneration(DirectoryPtr directory); + static int64_t getCurrentSegmentGeneration(const DirectoryPtr& directory); static String getCurrentSegmentFileName(HashSet files); - static String getCurrentSegmentFileName(DirectoryPtr directory); + static String getCurrentSegmentFileName(const DirectoryPtr& directory); static int64_t generationFromSegmentsFileName(const String& fileName); /// Current version number from segments file. - static int64_t readCurrentVersion(DirectoryPtr directory); + static int64_t readCurrentVersion(const DirectoryPtr& directory); /// Returns userData from latest segments file. - static MapStringString readCurrentUserData(DirectoryPtr directory); + static MapStringString readCurrentUserData(const DirectoryPtr& directory); /// If non-null, information about retries when loading the segments file will be printed to this. - static void setInfoStream(InfoStreamPtr infoStream); + static void setInfoStream(const InfoStreamPtr& infoStream); /// Set how many times to try loading the segments.gen file contents to determine current segment generation. This file /// is only referenced when the primary method (listing the directory) fails. @@ -174,7 +174,7 @@ namespace Lucene static void message(const String& message); protected: - void write(DirectoryPtr directory); + void write(const DirectoryPtr& directory); friend class FindSegmentsFile; }; diff --git a/include/SegmentMergeInfo.h b/include/SegmentMergeInfo.h index 6bade2ab..6514dc8a 100644 --- a/include/SegmentMergeInfo.h +++ b/include/SegmentMergeInfo.h @@ -14,7 +14,7 @@ namespace Lucene class SegmentMergeInfo : public LuceneObject { public: - SegmentMergeInfo(int32_t b, TermEnumPtr te, IndexReaderPtr r); + SegmentMergeInfo(int32_t b, const TermEnumPtr& te, const IndexReaderPtr& r); virtual ~SegmentMergeInfo(); LUCENE_CLASS(SegmentMergeInfo); diff --git a/include/SegmentMerger.h b/include/SegmentMerger.h index 381a7c91..61a71e14 100644 --- a/include/SegmentMerger.h +++ b/include/SegmentMerger.h @@ -20,8 +20,8 @@ namespace Lucene class SegmentMerger : public LuceneObject { public: - SegmentMerger(DirectoryPtr dir, const String& name); - SegmentMerger(IndexWriterPtr writer, const String& name, OneMergePtr merge); + SegmentMerger(const DirectoryPtr& dir, const String& name); + SegmentMerger(const IndexWriterPtr& writer, const String& name, const OneMergePtr& merge); virtual ~SegmentMerger(); LUCENE_CLASS(SegmentMerger); @@ -64,7 +64,7 @@ namespace Lucene bool hasProx(); /// Add an IndexReader to the collection of readers that are to be merged - void add(IndexReaderPtr reader); + void add(const IndexReaderPtr& reader); /// @param i The index of the reader to return /// @return The i'th reader to be merged @@ -92,30 +92,30 @@ namespace Lucene Collection getDelCounts(); protected: - void addIndexed(IndexReaderPtr reader, FieldInfosPtr fInfos, HashSet names, bool storeTermVectors, + void addIndexed(const IndexReaderPtr& reader, const FieldInfosPtr& fInfos, HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool storePayloads, bool omitTFAndPositions); void setMatchingSegmentReaders(); - int32_t copyFieldsWithDeletions(FieldsWriterPtr fieldsWriter, IndexReaderPtr reader, FieldsReaderPtr matchingFieldsReader); - int32_t copyFieldsNoDeletions(FieldsWriterPtr fieldsWriter, IndexReaderPtr reader, FieldsReaderPtr matchingFieldsReader); + int32_t copyFieldsWithDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader); + int32_t copyFieldsNoDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader); /// Merge the TermVectors from each of the segments into the new one. void mergeVectors(); - void copyVectorsWithDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader); - void copyVectorsNoDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader); + void copyVectorsWithDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader); + void copyVectorsNoDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader); void mergeTerms(); - void mergeTermInfos(FormatPostingsFieldsConsumerPtr consumer); + void mergeTermInfos(const FormatPostingsFieldsConsumerPtr& consumer); /// Process postings from multiple segments all positioned on the same term. Writes out merged entries /// into freqOutput and the proxOutput streams. /// @param smis array of segments /// @param n number of cells in the array actually occupied /// @return number of documents across all segments where this term was found - int32_t appendPostings(FormatPostingsTermsConsumerPtr termsConsumer, Collection smis, int32_t n); + int32_t appendPostings(const FormatPostingsTermsConsumerPtr& termsConsumer, Collection smis, int32_t n); void mergeNorms(); }; @@ -123,7 +123,7 @@ namespace Lucene class CheckAbort : public LuceneObject { public: - CheckAbort(OneMergePtr merge, DirectoryPtr dir); + CheckAbort(const OneMergePtr& merge, const DirectoryPtr& dir); virtual ~CheckAbort(); LUCENE_CLASS(CheckAbort); diff --git a/include/SegmentReader.h b/include/SegmentReader.h index 956f2cc2..525e283d 100644 --- a/include/SegmentReader.h +++ b/include/SegmentReader.h @@ -62,22 +62,22 @@ namespace Lucene using IndexReader::document; using IndexReader::termPositions; - static SegmentReaderPtr get(bool readOnly, SegmentInfoPtr si, int32_t termInfosIndexDivisor); - static SegmentReaderPtr get(bool readOnly, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor); + static SegmentReaderPtr get(bool readOnly, const SegmentInfoPtr& si, int32_t termInfosIndexDivisor); + static SegmentReaderPtr get(bool readOnly, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor); void openDocStores(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual LuceneObjectPtr clone(bool openReadOnly, LuceneObjectPtr other = LuceneObjectPtr()); - SegmentReaderPtr reopenSegment(SegmentInfoPtr si, bool doClone, bool openReadOnly); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); + SegmentReaderPtr reopenSegment(const SegmentInfoPtr& si, bool doClone, bool openReadOnly); - static bool hasDeletions(SegmentInfoPtr si); + static bool hasDeletions(const SegmentInfoPtr& si); /// Returns true if any documents have been deleted virtual bool hasDeletions(); - static bool usesCompoundFile(SegmentInfoPtr si); - static bool hasSeparateNorms(SegmentInfoPtr si); + static bool usesCompoundFile(const SegmentInfoPtr& si); + static bool hasSeparateNorms(const SegmentInfoPtr& si); HashSet files(); @@ -85,16 +85,16 @@ namespace Lucene virtual TermEnumPtr terms(); /// Returns an enumeration of all terms starting at a given term. - virtual TermEnumPtr terms(TermPtr t); + virtual TermEnumPtr terms(const TermPtr& t); /// Get the {@link Document} at the n'th position. - virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); /// Returns true if document n has been deleted virtual bool isDeleted(int32_t n); /// Returns an enumeration of all the documents which contain term. - virtual TermDocsPtr termDocs(TermPtr term); + virtual TermDocsPtr termDocs(const TermPtr& term); /// Returns an unpositioned {@link TermDocs} enumerator. virtual TermDocsPtr termDocs(); @@ -103,7 +103,7 @@ namespace Lucene virtual TermPositionsPtr termPositions(); /// Returns the number of documents containing the term t. - virtual int32_t docFreq(TermPtr t); + virtual int32_t docFreq(const TermPtr& t); /// Returns the number of documents in this index. virtual int32_t numDocs(); @@ -139,10 +139,10 @@ namespace Lucene /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays /// of the {@link TermFreqVector}. - virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); /// Map all the term vectors for all fields in a Document - virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); /// Return an array of term frequency vectors for the specified document. The array contains a vector for /// each vectorized field in the document. Each vector vector contains term numbers and frequencies for all @@ -154,7 +154,7 @@ namespace Lucene /// Return the SegmentInfo of the segment this reader is reading. SegmentInfoPtr getSegmentInfo(); - void setSegmentInfo(SegmentInfoPtr info); + void setSegmentInfo(const SegmentInfoPtr& info); void startCommit(); void rollbackCommit(); @@ -170,8 +170,8 @@ namespace Lucene /// Returns the number of unique terms (across all fields) in this reader. virtual int64_t getUniqueTermCount(); - static SegmentReaderPtr getOnlySegmentReader(DirectoryPtr dir); - static SegmentReaderPtr getOnlySegmentReader(IndexReaderPtr reader); + static SegmentReaderPtr getOnlySegmentReader(const DirectoryPtr& dir); + static SegmentReaderPtr getOnlySegmentReader(const IndexReaderPtr& reader); virtual int32_t getTermInfosIndexDivisor(); @@ -187,7 +187,7 @@ namespace Lucene /// Clones the deleteDocs BitVector. May be overridden by subclasses. /// @param bv BitVector to clone /// @return New BitVector - virtual BitVectorPtr cloneDeletedDocs(BitVectorPtr bv); + virtual BitVectorPtr cloneDeletedDocs(const BitVectorPtr& bv); /// Implements commit. virtual void doCommit(MapStringString commitUserData); @@ -210,7 +210,7 @@ namespace Lucene /// Implements setNorm in subclass. virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - void openNorms(DirectoryPtr cfsDir, int32_t readBufferSize); + void openNorms(const DirectoryPtr& cfsDir, int32_t readBufferSize); friend class ReaderPool; friend class IndexWriter; diff --git a/include/SegmentTermDocs.h b/include/SegmentTermDocs.h index 8e45e836..77c068ae 100644 --- a/include/SegmentTermDocs.h +++ b/include/SegmentTermDocs.h @@ -14,7 +14,7 @@ namespace Lucene class SegmentTermDocs : public TermPositions, public LuceneObject { public: - SegmentTermDocs(SegmentReaderPtr parent); + SegmentTermDocs(const SegmentReaderPtr& parent); virtual ~SegmentTermDocs(); LUCENE_CLASS(SegmentTermDocs); @@ -43,12 +43,12 @@ namespace Lucene public: /// Sets this to the data for a term. - virtual void seek(TermPtr term); + virtual void seek(const TermPtr& term); /// Sets this to the data for the current term in a {@link TermEnum}. - virtual void seek(TermEnumPtr termEnum); + virtual void seek(const TermEnumPtr& termEnum); - virtual void seek(TermInfoPtr ti, TermPtr term); + virtual void seek(const TermInfoPtr& ti, const TermPtr& term); virtual void close(); @@ -69,7 +69,7 @@ namespace Lucene /// Used for testing virtual IndexInputPtr freqStream(); - virtual void freqStream(IndexInputPtr freqStream); + virtual void freqStream(const IndexInputPtr& freqStream); protected: virtual void skippingDoc(); diff --git a/include/SegmentTermEnum.h b/include/SegmentTermEnum.h index baaf3517..2dde57c7 100644 --- a/include/SegmentTermEnum.h +++ b/include/SegmentTermEnum.h @@ -15,7 +15,7 @@ namespace Lucene { public: SegmentTermEnum(); - SegmentTermEnum(IndexInputPtr i, FieldInfosPtr fis, bool isi); + SegmentTermEnum(const IndexInputPtr& i, const FieldInfosPtr& fis, bool isi); virtual ~SegmentTermEnum(); LUCENE_CLASS(SegmentTermEnum); @@ -43,15 +43,15 @@ namespace Lucene int32_t maxSkipLevels; public: - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - void seek(int64_t pointer, int64_t p, TermPtr t, TermInfoPtr ti); + void seek(int64_t pointer, int64_t p, const TermPtr& t, const TermInfoPtr& ti); /// Increments the enumeration to the next element. True if one exists. virtual bool next(); /// Optimized scan, without allocating new terms. Return number of invocations to next(). - int32_t scanTo(TermPtr term); + int32_t scanTo(const TermPtr& term); /// Returns the current Term in the enumeration. /// Initially invalid, valid after next() called for the first time. @@ -66,7 +66,7 @@ namespace Lucene /// Sets the argument to the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. - void termInfo(TermInfoPtr ti); + void termInfo(const TermInfoPtr& ti); /// Returns the docFreq of the current Term in the enumeration. /// Initially invalid, valid after next() called for the first time. diff --git a/include/SegmentTermPositions.h b/include/SegmentTermPositions.h index 4af0c99f..e8433881 100644 --- a/include/SegmentTermPositions.h +++ b/include/SegmentTermPositions.h @@ -14,7 +14,7 @@ namespace Lucene class SegmentTermPositions : public SegmentTermDocs { public: - SegmentTermPositions(SegmentReaderPtr parent); + SegmentTermPositions(const SegmentReaderPtr& parent); virtual ~SegmentTermPositions(); LUCENE_CLASS(SegmentTermPositions); @@ -37,7 +37,7 @@ namespace Lucene public: using SegmentTermDocs::seek; - virtual void seek(TermInfoPtr ti, TermPtr term); + virtual void seek(const TermInfoPtr& ti, const TermPtr& term); virtual void close(); /// Returns next position in the current document. diff --git a/include/SegmentWriteState.h b/include/SegmentWriteState.h index b9d6781b..46003a51 100644 --- a/include/SegmentWriteState.h +++ b/include/SegmentWriteState.h @@ -14,7 +14,7 @@ namespace Lucene class SegmentWriteState : public LuceneObject { public: - SegmentWriteState(DocumentsWriterPtr docWriter, DirectoryPtr directory, const String& segmentName, + SegmentWriteState(const DocumentsWriterPtr& docWriter, const DirectoryPtr& directory, const String& segmentName, const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, int32_t termIndexInterval); virtual ~SegmentWriteState(); diff --git a/include/SerialMergeScheduler.h b/include/SerialMergeScheduler.h index 14d04a25..bb0f18a3 100644 --- a/include/SerialMergeScheduler.h +++ b/include/SerialMergeScheduler.h @@ -22,7 +22,7 @@ namespace Lucene public: /// Just do the merges in sequence. We do this "synchronized" so that even if the application is using /// multiple threads, only one merge may run at a time. - virtual void merge(IndexWriterPtr writer); + virtual void merge(const IndexWriterPtr& writer); /// Close this MergeScheduler. virtual void close(); diff --git a/include/Similarity.h b/include/Similarity.h index c50dd4de..20913205 100644 --- a/include/Similarity.h +++ b/include/Similarity.h @@ -465,7 +465,7 @@ namespace Lucene /// @param field Field name /// @param state Current processing state for this field /// @return The calculated float norm - virtual double computeNorm(const String& fieldName, FieldInvertStatePtr state); + virtual double computeNorm(const String& fieldName, const FieldInvertStatePtr& state); /// Computes the normalization value for a field given the total number of terms contained in a field. /// These values, together with field boosts, are stored in an index and multiplied into scores for hits @@ -559,7 +559,7 @@ namespace Lucene /// @param term The term in question /// @param searcher The document collection being searched /// @return An IDFExplain object that includes both an idf score factor and an explanation for the term. - virtual IDFExplanationPtr idfExplain(TermPtr term, SearcherPtr searcher); + virtual IDFExplanationPtr idfExplain(const TermPtr& term, const SearcherPtr& searcher); /// Computes a score factor for a phrase. /// @@ -569,7 +569,7 @@ namespace Lucene /// @param searcher The document collection being searched /// @return An IDFExplain object that includes both an idf score factor for the phrase and an explanation /// for each term. - virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher); + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher); /// Computes a score factor based on a term's document frequency (the number of documents which contain the /// term). This value is multiplied by the {@link #tf(int32_t)} factor for each term in the query and these diff --git a/include/SimilarityDelegator.h b/include/SimilarityDelegator.h index 72b4e5d2..bf57f470 100644 --- a/include/SimilarityDelegator.h +++ b/include/SimilarityDelegator.h @@ -16,7 +16,7 @@ namespace Lucene class LPPAPI SimilarityDelegator : public Similarity { public: - SimilarityDelegator(SimilarityPtr delegee); + SimilarityDelegator(const SimilarityPtr& delegee); virtual ~SimilarityDelegator(); LUCENE_CLASS(SimilarityDelegator); @@ -25,7 +25,7 @@ namespace Lucene SimilarityPtr delegee; public: - virtual double computeNorm(const String& field, FieldInvertStatePtr state); + virtual double computeNorm(const String& field, const FieldInvertStatePtr& state); virtual double lengthNorm(const String& fieldName, int32_t numTokens); virtual double queryNorm(double sumOfSquaredWeights); virtual double tf(double freq); diff --git a/include/SimpleAnalyzer.h b/include/SimpleAnalyzer.h index 14e7db83..ef046d09 100644 --- a/include/SimpleAnalyzer.h +++ b/include/SimpleAnalyzer.h @@ -20,8 +20,8 @@ namespace Lucene LUCENE_CLASS(SimpleAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; } diff --git a/include/SimpleFSDirectory.h b/include/SimpleFSDirectory.h index d81a06c9..1e407e1b 100644 --- a/include/SimpleFSDirectory.h +++ b/include/SimpleFSDirectory.h @@ -18,7 +18,7 @@ namespace Lucene /// Create a new SimpleFSDirectory for the named location and {@link NativeFSLockFactory}. /// @param path the path of the directory. /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) - SimpleFSDirectory(const String& path, LockFactoryPtr lockFactory = LockFactoryPtr()); + SimpleFSDirectory(const String& path, const LockFactoryPtr& lockFactory = LockFactoryPtr()); virtual ~SimpleFSDirectory(); LUCENE_CLASS(SimpleFSDirectory); diff --git a/include/SingleTermEnum.h b/include/SingleTermEnum.h index 055fe583..18fae202 100644 --- a/include/SingleTermEnum.h +++ b/include/SingleTermEnum.h @@ -18,7 +18,7 @@ namespace Lucene class LPPAPI SingleTermEnum : public FilteredTermEnum { public: - SingleTermEnum(IndexReaderPtr reader, TermPtr singleTerm); + SingleTermEnum(const IndexReaderPtr& reader, const TermPtr& singleTerm); virtual ~SingleTermEnum(); LUCENE_CLASS(SingleTermEnum); @@ -32,7 +32,7 @@ namespace Lucene protected: virtual bool endEnum(); - virtual bool termCompare(TermPtr term); + virtual bool termCompare(const TermPtr& term); }; } diff --git a/include/SloppyPhraseScorer.h b/include/SloppyPhraseScorer.h index bdeaa639..e9ea6671 100644 --- a/include/SloppyPhraseScorer.h +++ b/include/SloppyPhraseScorer.h @@ -14,7 +14,7 @@ namespace Lucene class SloppyPhraseScorer : public PhraseScorer { public: - SloppyPhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, int32_t slop, ByteArray norms); + SloppyPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, int32_t slop, ByteArray norms); virtual ~SloppyPhraseScorer(); LUCENE_CLASS(SloppyPhraseScorer); @@ -43,7 +43,7 @@ namespace Lucene protected: /// Flip pp2 and pp in the queue: pop until finding pp2, insert back all but pp2, insert pp back. /// Assumes: pp!=pp2, pp2 in pq, pp not in pq. Called only when there are repeating pps. - PhrasePositionsPtr flip(PhrasePositionsPtr pp, PhrasePositionsPtr pp2); + PhrasePositionsPtr flip(const PhrasePositionsPtr& pp, const PhrasePositionsPtr& pp2); /// Init PhrasePositions in place. /// There is a one time initialization for this scorer: @@ -62,7 +62,7 @@ namespace Lucene /// of the same word would go elsewhere in the matched doc. /// @return null if differ (i.e. valid) otherwise return the higher offset PhrasePositions out of the first /// two PPs found to not differ. - PhrasePositionsPtr termPositionsDiffer(PhrasePositionsPtr pp); + PhrasePositionsPtr termPositionsDiffer(const PhrasePositionsPtr& pp); }; } diff --git a/include/SnapshotDeletionPolicy.h b/include/SnapshotDeletionPolicy.h index b99b1f6d..f7b6f432 100644 --- a/include/SnapshotDeletionPolicy.h +++ b/include/SnapshotDeletionPolicy.h @@ -14,7 +14,7 @@ namespace Lucene class LPPAPI SnapshotDeletionPolicy : public IndexDeletionPolicy { public: - SnapshotDeletionPolicy(IndexDeletionPolicyPtr primary); + SnapshotDeletionPolicy(const IndexDeletionPolicyPtr& primary); virtual ~SnapshotDeletionPolicy(); LUCENE_CLASS(SnapshotDeletionPolicy); diff --git a/include/Sort.h b/include/Sort.h index 55bfa807..0982c902 100644 --- a/include/Sort.h +++ b/include/Sort.h @@ -74,7 +74,7 @@ namespace Lucene Sort(); /// Sorts by the criteria in the given SortField. - Sort(SortFieldPtr field); + Sort(const SortFieldPtr& field); /// Sorts in succession by the criteria in each SortField. Sort(Collection fields); @@ -97,7 +97,7 @@ namespace Lucene static SortPtr INDEXORDER(); /// Sets the sort to the given criteria. - void setSort(SortFieldPtr field); + void setSort(const SortFieldPtr& field); /// Sets the sort to the given criteria in succession. void setSort(Collection fields); @@ -107,7 +107,7 @@ namespace Lucene Collection getSort(); virtual String toString(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/SortField.h b/include/SortField.h index 15c212dc..81502f54 100644 --- a/include/SortField.h +++ b/include/SortField.h @@ -28,7 +28,7 @@ namespace Lucene /// @param parser Instance of a {@link Parser}, which must subclass one of the existing numeric parsers from /// {@link FieldCache}. Sort type is inferred by testing which numeric parser the parser subclasses. /// @param reverse True if natural order should be reversed. - SortField(const String& field, ParserPtr parser, bool reverse = false); + SortField(const String& field, const ParserPtr& parser, bool reverse = false); /// Creates a sort, possibly in reverse, by terms in the given field sorted according to the given locale. /// @param field Name of field to sort by, cannot be null. @@ -40,7 +40,7 @@ namespace Lucene /// @param field Name of field to sort by; cannot be null. /// @param comparator Returns a comparator for sorting hits. /// @param reverse True if natural order should be reversed. - SortField(const String& field, FieldComparatorSourcePtr comparator, bool reverse = false); + SortField(const String& field, const FieldComparatorSourcePtr& comparator, bool reverse = false); virtual ~SortField(); @@ -128,7 +128,7 @@ namespace Lucene /// Returns true if other is equal to this. If a {@link FieldComparatorSource} or {@link Parser} was provided, /// it must properly implement equals (unless a singleton is always used). - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); diff --git a/include/SortedVIntList.h b/include/SortedVIntList.h index 1f8cb8b5..d1357400 100644 --- a/include/SortedVIntList.h +++ b/include/SortedVIntList.h @@ -33,17 +33,17 @@ namespace Lucene /// Create a SortedVIntList from a BitSet. /// @param bits A bit set representing a set of integers. - SortedVIntList(BitSetPtr bits); + SortedVIntList(const BitSetPtr& bits); /// Create a SortedVIntList from an OpenBitSet. /// @param bits A bit set representing a set of integers. - SortedVIntList(OpenBitSetPtr bits); + SortedVIntList(const OpenBitSetPtr& bits); /// Create a SortedVIntList. /// @param docIdSetIterator An iterator providing document numbers as a set of integers. /// This DocIdSetIterator is iterated completely when this constructor is called and it must provide the /// integers in non decreasing order. - SortedVIntList(DocIdSetIteratorPtr docIdSetIterator); + SortedVIntList(const DocIdSetIteratorPtr& docIdSetIterator); virtual ~SortedVIntList(); diff --git a/include/SpanFilter.h b/include/SpanFilter.h index 326c17fe..ba906737 100644 --- a/include/SpanFilter.h +++ b/include/SpanFilter.h @@ -29,7 +29,7 @@ namespace Lucene /// false for those that should not and Spans for where the true docs match. /// @param reader The {@link IndexReader} to load position and DocIdSet information from /// @return A {@link SpanFilterResult} - virtual SpanFilterResultPtr bitSpans(IndexReaderPtr reader) = 0; + virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader) = 0; }; } diff --git a/include/SpanFilterResult.h b/include/SpanFilterResult.h index 9ff5b5de..3934e0c9 100644 --- a/include/SpanFilterResult.h +++ b/include/SpanFilterResult.h @@ -17,7 +17,7 @@ namespace Lucene public: /// @param docIdSet The DocIdSet for the Filter /// @param positions A List of {@link PositionInfo} objects - SpanFilterResult(DocIdSetPtr docIdSet, Collection positions); + SpanFilterResult(const DocIdSetPtr& docIdSet, Collection positions); virtual ~SpanFilterResult(); diff --git a/include/SpanFirstQuery.h b/include/SpanFirstQuery.h index 860a21cd..fba6e765 100644 --- a/include/SpanFirstQuery.h +++ b/include/SpanFirstQuery.h @@ -17,7 +17,7 @@ namespace Lucene { public: /// Construct a SpanFirstQuery matching spans in match whose end position is less than or equal to end. - SpanFirstQuery(SpanQueryPtr match, int32_t end); + SpanFirstQuery(const SpanQueryPtr& match, int32_t end); virtual ~SpanFirstQuery(); LUCENE_CLASS(SpanFirstQuery); @@ -37,12 +37,12 @@ namespace Lucene virtual String getField(); virtual String toString(const String& field); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual void extractTerms(SetTerm terms); - virtual SpansPtr getSpans(IndexReaderPtr reader); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); friend class FirstSpans; diff --git a/include/SpanNearQuery.h b/include/SpanNearQuery.h index 8b5d17c2..75c73c5f 100644 --- a/include/SpanNearQuery.h +++ b/include/SpanNearQuery.h @@ -47,10 +47,10 @@ namespace Lucene virtual String getField(); virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); - virtual SpansPtr getSpans(IndexReaderPtr reader); - virtual QueryPtr rewrite(IndexReaderPtr reader); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual bool equals(LuceneObjectPtr other); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/SpanNotQuery.h b/include/SpanNotQuery.h index d133d87d..53f74d4b 100644 --- a/include/SpanNotQuery.h +++ b/include/SpanNotQuery.h @@ -16,7 +16,7 @@ namespace Lucene { public: /// Construct a SpanNotQuery matching spans from include which have no overlap with spans from exclude. - SpanNotQuery(SpanQueryPtr include, SpanQueryPtr exclude); + SpanNotQuery(const SpanQueryPtr& include, const SpanQueryPtr& exclude); virtual ~SpanNotQuery(); LUCENE_CLASS(SpanNotQuery); @@ -37,11 +37,11 @@ namespace Lucene virtual String getField(); virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual SpansPtr getSpans(IndexReaderPtr reader); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/SpanOrQuery.h b/include/SpanOrQuery.h index 492d207a..b3efaeb7 100644 --- a/include/SpanOrQuery.h +++ b/include/SpanOrQuery.h @@ -33,12 +33,12 @@ namespace Lucene virtual String getField(); virtual void extractTerms(SetTerm terms); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual SpansPtr getSpans(IndexReaderPtr reader); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); friend class OrSpans; }; diff --git a/include/SpanQuery.h b/include/SpanQuery.h index 8ffb8c89..092c9873 100644 --- a/include/SpanQuery.h +++ b/include/SpanQuery.h @@ -20,12 +20,12 @@ namespace Lucene public: /// Returns the matches for this query in an index. Used internally to search for spans. - virtual SpansPtr getSpans(IndexReaderPtr reader) = 0; + virtual SpansPtr getSpans(const IndexReaderPtr& reader) = 0; /// Returns the name of the field matched by this query. virtual String getField() = 0; - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); }; } diff --git a/include/SpanQueryFilter.h b/include/SpanQueryFilter.h index 37e5663e..3a3899bd 100644 --- a/include/SpanQueryFilter.h +++ b/include/SpanQueryFilter.h @@ -22,7 +22,7 @@ namespace Lucene public: /// Constructs a filter which only matches documents matching query. /// @param query The {@link SpanQuery} to use as the basis for the Filter. - SpanQueryFilter(SpanQueryPtr query = SpanQueryPtr()); + SpanQueryFilter(const SpanQueryPtr& query = SpanQueryPtr()); virtual ~SpanQueryFilter(); @@ -32,13 +32,13 @@ namespace Lucene SpanQueryPtr query; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); - virtual SpanFilterResultPtr bitSpans(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader); SpanQueryPtr getQuery(); virtual String toString(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/SpanScorer.h b/include/SpanScorer.h index 7fcc7b3f..8df36d9f 100644 --- a/include/SpanScorer.h +++ b/include/SpanScorer.h @@ -15,7 +15,7 @@ namespace Lucene class LPPAPI SpanScorer : public Scorer { public: - SpanScorer(SpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms); + SpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); virtual ~SpanScorer(); LUCENE_CLASS(SpanScorer); diff --git a/include/SpanTermQuery.h b/include/SpanTermQuery.h index 16f08e66..115a81f3 100644 --- a/include/SpanTermQuery.h +++ b/include/SpanTermQuery.h @@ -16,7 +16,7 @@ namespace Lucene { public: /// Construct a SpanTermQuery matching the named term's spans. - SpanTermQuery(TermPtr term); + SpanTermQuery(const TermPtr& term); virtual ~SpanTermQuery(); LUCENE_CLASS(SpanTermQuery); @@ -34,9 +34,9 @@ namespace Lucene virtual void extractTerms(SetTerm terms); virtual String toString(const String& field); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual SpansPtr getSpans(IndexReaderPtr reader); + virtual bool equals(const LuceneObjectPtr& other); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); }; } diff --git a/include/SpanWeight.h b/include/SpanWeight.h index ae1ee955..35500b30 100644 --- a/include/SpanWeight.h +++ b/include/SpanWeight.h @@ -15,7 +15,7 @@ namespace Lucene class LPPAPI SpanWeight : public Weight { public: - SpanWeight(SpanQueryPtr query, SearcherPtr searcher); + SpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher); virtual ~SpanWeight(); LUCENE_CLASS(SpanWeight); @@ -36,8 +36,8 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); friend class PayloadNearSpanScorer; friend class PayloadTermSpanScorer; diff --git a/include/StandardAnalyzer.h b/include/StandardAnalyzer.h index 4d868ef2..ce202b59 100644 --- a/include/StandardAnalyzer.h +++ b/include/StandardAnalyzer.h @@ -42,7 +42,7 @@ namespace Lucene /// @see WordlistLoader#getWordSet(ReaderPtr, const String&) /// @param matchVersion Lucene version to match. /// @param stopwords Reader to read stop words from. - StandardAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords); + StandardAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords); virtual ~StandardAnalyzer(); @@ -70,7 +70,7 @@ namespace Lucene public: /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter} /// and a {@link StopFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Set maximum allowed token length. If a token is seen that exceeds this length then it is discarded. This setting /// only takes effect the next time tokenStream or reusableTokenStream is called. @@ -79,7 +79,7 @@ namespace Lucene /// @see #setMaxTokenLength int32_t getMaxTokenLength(); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; } diff --git a/include/StandardFilter.h b/include/StandardFilter.h index 551bfe45..7158c39e 100644 --- a/include/StandardFilter.h +++ b/include/StandardFilter.h @@ -16,7 +16,7 @@ namespace Lucene { public: /// Construct filtering input. - StandardFilter(TokenStreamPtr input); + StandardFilter(const TokenStreamPtr& input); virtual ~StandardFilter(); LUCENE_CLASS(StandardFilter); diff --git a/include/StandardTokenizer.h b/include/StandardTokenizer.h index 55630219..c6d9f057 100644 --- a/include/StandardTokenizer.h +++ b/include/StandardTokenizer.h @@ -36,13 +36,13 @@ namespace Lucene public: /// Creates a new instance of the {@link StandardTokenizer}. Attaches the input to the newly created scanner. /// @param input The input reader - StandardTokenizer(LuceneVersion::Version matchVersion, ReaderPtr input); + StandardTokenizer(LuceneVersion::Version matchVersion, const ReaderPtr& input); /// Creates a new StandardTokenizer with a given {@link AttributeSource}. - StandardTokenizer(LuceneVersion::Version matchVersion, AttributeSourcePtr source, ReaderPtr input); + StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeSourcePtr& source, const ReaderPtr& input); /// Creates a new StandardTokenizer with a given {@link AttributeSource.AttributeFactory} - StandardTokenizer(LuceneVersion::Version matchVersion, AttributeFactoryPtr factory, ReaderPtr input); + StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~StandardTokenizer(); @@ -78,7 +78,7 @@ namespace Lucene static const Collection TOKEN_TYPES(); protected: - void init(ReaderPtr input, LuceneVersion::Version matchVersion); + void init(const ReaderPtr& input, LuceneVersion::Version matchVersion); public: /// Set the max allowed token length. Any token longer than this is skipped. @@ -92,7 +92,7 @@ namespace Lucene virtual void end(); - virtual void reset(ReaderPtr input); + virtual void reset(const ReaderPtr& input); /// @return true if StandardTokenizer now returns these tokens as Hosts, otherwise false /// @deprecated Remove in 3.X and make true the only valid value diff --git a/include/StandardTokenizerImpl.h b/include/StandardTokenizerImpl.h index 564d9958..a0e2a853 100644 --- a/include/StandardTokenizerImpl.h +++ b/include/StandardTokenizerImpl.h @@ -16,7 +16,7 @@ namespace Lucene public: /// Creates a new scanner /// @param in the Reader to read input from. - StandardTokenizerImpl(ReaderPtr in); + StandardTokenizerImpl(const ReaderPtr& in); virtual ~StandardTokenizerImpl(); @@ -136,13 +136,13 @@ namespace Lucene int32_t yychar(); /// Resets the Tokenizer to a new Reader. - void reset(ReaderPtr r); + void reset(const ReaderPtr& r); /// Fills Lucene token with the current token text. - void getText(TokenPtr t); + void getText(const TokenPtr& t); /// Fills TermAttribute with the current token text. - void getText(TermAttributePtr t); + void getText(const TermAttributePtr& t); /// Closes the input stream. void yyclose(); @@ -153,7 +153,7 @@ namespace Lucene /// Lexical state is set to ZZ_INITIAL. /// /// @param reader the new input stream. - void yyreset(ReaderPtr reader); + void yyreset(const ReaderPtr& reader); /// Returns the current lexical state. int32_t yystate(); diff --git a/include/StopAnalyzer.h b/include/StopAnalyzer.h index 18c1677e..a8ed37e7 100644 --- a/include/StopAnalyzer.h +++ b/include/StopAnalyzer.h @@ -28,7 +28,7 @@ namespace Lucene StopAnalyzer(LuceneVersion::Version matchVersion, const String& stopwordsFile); /// Builds an analyzer with the stop words from the given reader. - StopAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords); + StopAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords); virtual ~StopAnalyzer(); @@ -44,8 +44,8 @@ namespace Lucene /// An unmodifiable set containing some common English words that are usually not useful for searching. static const HashSet ENGLISH_STOP_WORDS_SET(); - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; } diff --git a/include/StopFilter.h b/include/StopFilter.h index 59320fa0..d6e0f9a9 100644 --- a/include/StopFilter.h +++ b/include/StopFilter.h @@ -26,8 +26,8 @@ namespace Lucene /// @param input Input TokenStream /// @param stopWords A Set of Strings or char[] or any other toString()-able set representing the stopwords /// @param ignoreCase if true, all words are lower cased first - StopFilter(bool enablePositionIncrements, TokenStreamPtr input, HashSet stopWords, bool ignoreCase = false); - StopFilter(bool enablePositionIncrements, TokenStreamPtr input, CharArraySetPtr stopWords, bool ignoreCase = false); + StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, HashSet stopWords, bool ignoreCase = false); + StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, const CharArraySetPtr& stopWords, bool ignoreCase = false); virtual ~StopFilter(); diff --git a/include/StoredFieldsWriter.h b/include/StoredFieldsWriter.h index 9b932147..802ecb7c 100644 --- a/include/StoredFieldsWriter.h +++ b/include/StoredFieldsWriter.h @@ -15,7 +15,7 @@ namespace Lucene class StoredFieldsWriter : public LuceneObject { public: - StoredFieldsWriter(DocumentsWriterPtr docWriter, FieldInfosPtr fieldInfos); + StoredFieldsWriter(const DocumentsWriterPtr& docWriter, const FieldInfosPtr& fieldInfos); virtual ~StoredFieldsWriter(); LUCENE_CLASS(StoredFieldsWriter); @@ -31,18 +31,18 @@ namespace Lucene int32_t allocCount; public: - StoredFieldsWriterPerThreadPtr addThread(DocStatePtr docState); - void flush(SegmentWriteStatePtr state); - void closeDocStore(SegmentWriteStatePtr state); + StoredFieldsWriterPerThreadPtr addThread(const DocStatePtr& docState); + void flush(const SegmentWriteStatePtr& state); + void closeDocStore(const SegmentWriteStatePtr& state); StoredFieldsWriterPerDocPtr getPerDoc(); void abort(); /// Fills in any hole in the docIDs void fill(int32_t docID); - void finishDocument(StoredFieldsWriterPerDocPtr perDoc); + void finishDocument(const StoredFieldsWriterPerDocPtr& perDoc); bool freeRAM(); - void free(StoredFieldsWriterPerDocPtr perDoc); + void free(const StoredFieldsWriterPerDocPtr& perDoc); protected: void initFieldsWriter(); @@ -51,7 +51,7 @@ namespace Lucene class StoredFieldsWriterPerDoc : public DocWriter { public: - StoredFieldsWriterPerDoc(StoredFieldsWriterPtr fieldsWriter); + StoredFieldsWriterPerDoc(const StoredFieldsWriterPtr& fieldsWriter); virtual ~StoredFieldsWriterPerDoc(); LUCENE_CLASS(StoredFieldsWriterPerDoc); diff --git a/include/StoredFieldsWriterPerThread.h b/include/StoredFieldsWriterPerThread.h index 22e72ce8..2266da03 100644 --- a/include/StoredFieldsWriterPerThread.h +++ b/include/StoredFieldsWriterPerThread.h @@ -14,7 +14,7 @@ namespace Lucene class StoredFieldsWriterPerThread : public LuceneObject { public: - StoredFieldsWriterPerThread(DocStatePtr docState, StoredFieldsWriterPtr storedFieldsWriter); + StoredFieldsWriterPerThread(const DocStatePtr& docState, const StoredFieldsWriterPtr& storedFieldsWriter); virtual ~StoredFieldsWriterPerThread(); LUCENE_CLASS(StoredFieldsWriterPerThread); @@ -28,7 +28,7 @@ namespace Lucene public: void startDocument(); - void addField(FieldablePtr field, FieldInfoPtr fieldInfo); + void addField(const FieldablePtr& field, const FieldInfoPtr& fieldInfo); DocWriterPtr finishDocument(); void abort(); }; diff --git a/include/StringUtils.h b/include/StringUtils.h index 72db1b8a..022851d2 100644 --- a/include/StringUtils.h +++ b/include/StringUtils.h @@ -25,7 +25,7 @@ namespace Lucene static int32_t toUnicode(const uint8_t* utf8, int32_t length, CharArray unicode); /// Convert uft8 buffer into unicode. - static int32_t toUnicode(const uint8_t* utf8, int32_t length, UnicodeResultPtr unicodeResult); + static int32_t toUnicode(const uint8_t* utf8, int32_t length, const UnicodeResultPtr& unicodeResult); /// Convert uft8 buffer into unicode. static String toUnicode(const uint8_t* utf8, int32_t length); @@ -37,7 +37,7 @@ namespace Lucene static int32_t toUTF8(const wchar_t* unicode, int32_t length, ByteArray utf8); /// Convert unicode buffer into uft8. - static int32_t toUTF8(const wchar_t* unicode, int32_t length, UTF8ResultPtr utf8Result); + static int32_t toUTF8(const wchar_t* unicode, int32_t length, const UTF8ResultPtr& utf8Result); /// Convert unicode buffer into uft8. static SingleString toUTF8(const wchar_t* unicode, int32_t length); diff --git a/include/Synchronize.h b/include/Synchronize.h index 269fde4b..5afb0eb0 100644 --- a/include/Synchronize.h +++ b/include/Synchronize.h @@ -45,7 +45,7 @@ namespace Lucene class LPPAPI SyncLock { public: - SyncLock(SynchronizePtr sync, int32_t timeout = 0); + SyncLock(const SynchronizePtr& sync, int32_t timeout = 0); template SyncLock(OBJECT object, int32_t timeout = 0) diff --git a/include/TeeSinkTokenFilter.h b/include/TeeSinkTokenFilter.h index 69e8b4e4..cd0e1974 100644 --- a/include/TeeSinkTokenFilter.h +++ b/include/TeeSinkTokenFilter.h @@ -63,7 +63,7 @@ namespace Lucene { public: /// Instantiates a new TeeSinkTokenFilter. - TeeSinkTokenFilter(TokenStreamPtr input); + TeeSinkTokenFilter(const TokenStreamPtr& input); virtual ~TeeSinkTokenFilter(); LUCENE_CLASS(TeeSinkTokenFilter); @@ -78,11 +78,11 @@ namespace Lucene /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream that pass /// the supplied filter. /// @see SinkFilter - SinkTokenStreamPtr newSinkTokenStream(SinkFilterPtr filter); + SinkTokenStreamPtr newSinkTokenStream(const SinkFilterPtr& filter); /// Adds a {@link SinkTokenStream} created by another TeeSinkTokenFilter to this one. The supplied stream will /// also receive all consumed tokens. This method can be used to pass tokens from two different tees to one sink. - void addSinkTokenStream(SinkTokenStreamPtr sink); + void addSinkTokenStream(const SinkTokenStreamPtr& sink); /// TeeSinkTokenFilter passes all tokens to the added sinks when itself is consumed. To be sure, that all tokens /// from the input stream are passed to the sinks, you can call this methods. This instance is exhausted after this, @@ -102,7 +102,7 @@ namespace Lucene public: /// Returns true, if the current state of the passed-in {@link AttributeSource} shall be stored in the sink. - virtual bool accept(AttributeSourcePtr source) = 0; + virtual bool accept(const AttributeSourcePtr& source) = 0; /// Called by {@link SinkTokenStream#reset()}. This method does nothing by default and can optionally be overridden. virtual void reset(); @@ -116,14 +116,14 @@ namespace Lucene LUCENE_CLASS(AcceptAllSinkFilter); public: - virtual bool accept(AttributeSourcePtr source); + virtual bool accept(const AttributeSourcePtr& source); }; /// A filter that decides which {@link AttributeSource} states to store in the sink. class LPPAPI SinkTokenStream : public TokenStream { public: - SinkTokenStream(AttributeSourcePtr source, SinkFilterPtr filter); + SinkTokenStream(const AttributeSourcePtr& source, const SinkFilterPtr& filter); virtual ~SinkTokenStream(); LUCENE_CLASS(SinkTokenStream); @@ -136,9 +136,9 @@ namespace Lucene SinkFilterPtr filter; protected: - bool accept(AttributeSourcePtr source); - void addState(AttributeSourceStatePtr state); - void setFinalState(AttributeSourceStatePtr finalState); + bool accept(const AttributeSourcePtr& source); + void addState(const AttributeSourceStatePtr& state); + void setFinalState(const AttributeSourceStatePtr& finalState); public: virtual bool incrementToken(); diff --git a/include/Term.h b/include/Term.h index 7de42e45..7e55dfae 100644 --- a/include/Term.h +++ b/include/Term.h @@ -44,14 +44,14 @@ namespace Lucene /// @return A new Term TermPtr createTerm(const String& text); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); /// Compares two terms, returning a negative integer if this term belongs before the argument, zero /// if this term is equal to the argument, and a positive integer if this term belongs after the argument. /// /// The ordering of terms is first by field, then by text. - virtual int32_t compareTo(LuceneObjectPtr other); + virtual int32_t compareTo(const LuceneObjectPtr& other); void set(const String& fld, const String& txt); diff --git a/include/TermAttribute.h b/include/TermAttribute.h index b580a37e..90d1693f 100644 --- a/include/TermAttribute.h +++ b/include/TermAttribute.h @@ -75,9 +75,9 @@ namespace Lucene virtual int32_t hashCode(); virtual void clear(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); - virtual bool equals(LuceneObjectPtr other); - virtual void copyTo(AttributePtr target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); + virtual void copyTo(const AttributePtr& target); protected: /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always diff --git a/include/TermBuffer.h b/include/TermBuffer.h index 907b1890..c20c7405 100644 --- a/include/TermBuffer.h +++ b/include/TermBuffer.h @@ -28,20 +28,20 @@ namespace Lucene UTF8ResultPtr bytes; public: - virtual int32_t compareTo(LuceneObjectPtr other); + virtual int32_t compareTo(const LuceneObjectPtr& other); /// Call this if the IndexInput passed to {@link #read} stores terms in the "modified UTF8" format. void setPreUTF8Strings(); - void read(IndexInputPtr input, FieldInfosPtr fieldInfos); + void read(const IndexInputPtr& input, const FieldInfosPtr& fieldInfos); - void set(TermPtr term); - void set(TermBufferPtr other); + void set(const TermPtr& term); + void set(const TermBufferPtr& other); void reset(); TermPtr toTerm(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); protected: int32_t compareChars(wchar_t* chars1, int32_t len1, wchar_t* chars2, int32_t len2); diff --git a/include/TermDocs.h b/include/TermDocs.h index 0de10d44..fa9a9ead 100644 --- a/include/TermDocs.h +++ b/include/TermDocs.h @@ -26,11 +26,11 @@ namespace Lucene public: /// Sets this to the data for a term. The enumeration is reset to the start of the data for this term. - virtual void seek(TermPtr term) = 0; + virtual void seek(const TermPtr& term) = 0; /// Sets this to the data for the current term in a {@link TermEnum}. /// This may be optimized in some implementations. - virtual void seek(TermEnumPtr termEnum) = 0; + virtual void seek(const TermEnumPtr& termEnum) = 0; /// Returns the current document number. This is invalid until {@link #next()} is called for the first time. virtual int32_t doc() = 0; diff --git a/include/TermInfo.h b/include/TermInfo.h index 14f851be..92ea5368 100644 --- a/include/TermInfo.h +++ b/include/TermInfo.h @@ -15,7 +15,7 @@ namespace Lucene class TermInfo : public LuceneObject { public: - TermInfo(TermInfoPtr ti); + TermInfo(const TermInfoPtr& ti); TermInfo(int32_t df = 0, int64_t fp = 0, int64_t pp = 0); virtual ~TermInfo(); @@ -30,7 +30,7 @@ namespace Lucene public: void set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer, int32_t skipOffset); - void set(TermInfoPtr ti); + void set(const TermInfoPtr& ti); }; } diff --git a/include/TermInfosReader.h b/include/TermInfosReader.h index fa4e3b15..25d41aff 100644 --- a/include/TermInfosReader.h +++ b/include/TermInfosReader.h @@ -17,7 +17,7 @@ namespace Lucene class TermInfosReader : public LuceneObject { public: - TermInfosReader(DirectoryPtr dir, const String& seg, FieldInfosPtr fis, int32_t readBufferSize, int32_t indexDivisor); + TermInfosReader(const DirectoryPtr& dir, const String& seg, const FieldInfosPtr& fis, int32_t readBufferSize, int32_t indexDivisor); virtual ~TermInfosReader(); LUCENE_CLASS(TermInfosReader); @@ -47,27 +47,27 @@ namespace Lucene int64_t size(); /// Returns the TermInfo for a Term in the set, or null. - TermInfoPtr get(TermPtr term); + TermInfoPtr get(const TermPtr& term); /// Returns the position of a Term in the set or -1. - int64_t getPosition(TermPtr term); + int64_t getPosition(const TermPtr& term); /// Returns an enumeration of all the Terms and TermInfos in the set. SegmentTermEnumPtr terms(); /// Returns an enumeration of terms starting at or after the named term. - SegmentTermEnumPtr terms(TermPtr term); + SegmentTermEnumPtr terms(const TermPtr& term); protected: TermInfosReaderThreadResourcesPtr getThreadResources(); /// Returns the offset of the greatest index entry which is less than or equal to term. - int32_t getIndexOffset(TermPtr term); + int32_t getIndexOffset(const TermPtr& term); - void seekEnum(SegmentTermEnumPtr enumerator, int32_t indexOffset); + void seekEnum(const SegmentTermEnumPtr& enumerator, int32_t indexOffset); /// Returns the TermInfo for a Term in the set, or null. - TermInfoPtr get(TermPtr term, bool useCache); + TermInfoPtr get(const TermPtr& term, bool useCache); void ensureIndexIsRead(); }; diff --git a/include/TermInfosWriter.h b/include/TermInfosWriter.h index 22c45dfe..8d65f545 100644 --- a/include/TermInfosWriter.h +++ b/include/TermInfosWriter.h @@ -16,8 +16,8 @@ namespace Lucene class TermInfosWriter : public LuceneObject { public: - TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval); - TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isIndex); + TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval); + TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isIndex); virtual ~TermInfosWriter(); LUCENE_CLASS(TermInfosWriter); @@ -70,17 +70,17 @@ namespace Lucene public: virtual void initialize(); - void add(TermPtr term, TermInfoPtr ti); + void add(const TermPtr& term, const TermInfoPtr& ti); /// Adds a new <, TermInfo> pair to the set. Term must be lexicographically /// greater than all previous Terms added. TermInfo pointers must be positive and greater than all previous. - void add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, TermInfoPtr ti); + void add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, const TermInfoPtr& ti); /// Called to complete TermInfos creation. void close(); protected: - void initialize(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isi); + void initialize(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isi); /// Currently used only by assert statements bool initUnicodeResults(); diff --git a/include/TermQuery.h b/include/TermQuery.h index c66a07d9..81838289 100644 --- a/include/TermQuery.h +++ b/include/TermQuery.h @@ -17,7 +17,7 @@ namespace Lucene { public: /// Constructs a query for the term. - TermQuery(TermPtr term); + TermQuery(const TermPtr& term); virtual ~TermQuery(); @@ -32,15 +32,15 @@ namespace Lucene /// Returns the term of this query. TermPtr getTerm(); - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); virtual void extractTerms(SetTerm terms); /// Prints a user-readable version of this query. virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); friend class TermWeight; }; diff --git a/include/TermRangeQuery.h b/include/TermRangeQuery.h index 5c2c7c2e..2e755d11 100644 --- a/include/TermRangeQuery.h +++ b/include/TermRangeQuery.h @@ -76,13 +76,13 @@ namespace Lucene /// Returns the collator used to determine range inclusion, if any. CollatorPtr getCollator(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual String toString(const String& field); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); protected: - virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); }; } diff --git a/include/TermRangeTermEnum.h b/include/TermRangeTermEnum.h index abf0fe9f..ab4a3738 100644 --- a/include/TermRangeTermEnum.h +++ b/include/TermRangeTermEnum.h @@ -32,8 +32,8 @@ namespace Lucene /// @param includeUpper If true, the upperTerm is included in the range. /// @param collator The collator to use to collate index Terms, to determine their membership in the range /// bounded by lowerTerm and upperTerm. - TermRangeTermEnum(IndexReaderPtr reader, const String& field, StringValue lowerTermText, StringValue upperTermText, - bool includeLower, bool includeUpper, CollatorPtr collator); + TermRangeTermEnum(const IndexReaderPtr& reader, const String& field, StringValue lowerTermText, StringValue upperTermText, + bool includeLower, bool includeUpper, const CollatorPtr& collator); virtual ~TermRangeTermEnum(); @@ -53,7 +53,7 @@ namespace Lucene protected: virtual bool endEnum(); - virtual bool termCompare(TermPtr term); + virtual bool termCompare(const TermPtr& term); }; } diff --git a/include/TermScorer.h b/include/TermScorer.h index ec2e75be..53786b39 100644 --- a/include/TermScorer.h +++ b/include/TermScorer.h @@ -20,7 +20,7 @@ namespace Lucene /// @param td An iterator over the documents matching the Term. /// @param similarity The Similarity implementation to be used for score computations. /// @param norms The field norms of the document fields for the Term. - TermScorer(WeightPtr weight, TermDocsPtr td, SimilarityPtr similarity, ByteArray norms); + TermScorer(const WeightPtr& weight, const TermDocsPtr& td, const SimilarityPtr& similarity, ByteArray norms); virtual ~TermScorer(); @@ -42,7 +42,7 @@ namespace Lucene Collection scoreCache; public: - virtual void score(CollectorPtr collector); + virtual void score(const CollectorPtr& collector); virtual int32_t docID(); /// Advances to the next document matching the query. @@ -65,7 +65,7 @@ namespace Lucene protected: static const Collection SIM_NORM_DECODER(); - virtual bool score(CollectorPtr collector, int32_t max, int32_t firstDocID); + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); }; } diff --git a/include/TermSpans.h b/include/TermSpans.h index 34273613..abf044e8 100644 --- a/include/TermSpans.h +++ b/include/TermSpans.h @@ -15,7 +15,7 @@ namespace Lucene class LPPAPI TermSpans : public Spans { public: - TermSpans(TermPositionsPtr positions, TermPtr term); + TermSpans(const TermPositionsPtr& positions, const TermPtr& term); virtual ~TermSpans(); LUCENE_CLASS(TermSpans); diff --git a/include/TermVectorEntry.h b/include/TermVectorEntry.h index 16e2c3d1..5f70c9b0 100644 --- a/include/TermVectorEntry.h +++ b/include/TermVectorEntry.h @@ -40,7 +40,7 @@ namespace Lucene void setOffsets(Collection offsets); void setPositions(Collection positions); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); virtual String toString(); }; diff --git a/include/TermVectorOffsetInfo.h b/include/TermVectorOffsetInfo.h index 478b9c36..64d973d1 100644 --- a/include/TermVectorOffsetInfo.h +++ b/include/TermVectorOffsetInfo.h @@ -40,7 +40,7 @@ namespace Lucene /// Two TermVectorOffsetInfos are equals if both the start and end offsets are the same. /// @return true if both {@link #getStartOffset()} and {@link #getEndOffset()} are the same for both objects. - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; diff --git a/include/TermVectorsReader.h b/include/TermVectorsReader.h index b9a04107..23d722e9 100644 --- a/include/TermVectorsReader.h +++ b/include/TermVectorsReader.h @@ -15,8 +15,8 @@ namespace Lucene { public: TermVectorsReader(); - TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos); - TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, + TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos); + TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); virtual ~TermVectorsReader(); @@ -74,7 +74,7 @@ namespace Lucene /// @return The number of documents in the reader int32_t size(); - void get(int32_t docNum, const String& field, TermVectorMapperPtr mapper); + void get(int32_t docNum, const String& field, const TermVectorMapperPtr& mapper); /// Retrieve the term vector for the given document and field /// @param docNum The document number to retrieve the vector for @@ -89,16 +89,16 @@ namespace Lucene /// @return All term frequency vectors Collection get(int32_t docNum); - void get(int32_t docNumber, TermVectorMapperPtr mapper); + void get(int32_t docNumber, const TermVectorMapperPtr& mapper); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); protected: - void ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); + void ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); void seekTvx(int32_t docNum); - int32_t checkValidFormat(IndexInputPtr in); + int32_t checkValidFormat(const IndexInputPtr& in); /// Reads the String[] fields; you have to pre-seek tvd to the right point Collection readFields(int32_t fieldCount); @@ -107,12 +107,12 @@ namespace Lucene Collection readTvfPointers(int32_t fieldCount); Collection readTermVectors(int32_t docNum, Collection fields, Collection tvfPointers); - void readTermVectors(Collection fields, Collection tvfPointers, TermVectorMapperPtr mapper); + void readTermVectors(Collection fields, Collection tvfPointers, const TermVectorMapperPtr& mapper); /// @param field The field to read in /// @param tvfPointer The pointer within the tvf file where we should start reading /// @param mapper The mapper used to map the TermVector - void readTermVector(const String& field, int64_t tvfPointer, TermVectorMapperPtr mapper); + void readTermVector(const String& field, int64_t tvfPointer, const TermVectorMapperPtr& mapper); }; /// Models the existing parallel array structure diff --git a/include/TermVectorsTermsWriter.h b/include/TermVectorsTermsWriter.h index 3797490a..e9d715e5 100644 --- a/include/TermVectorsTermsWriter.h +++ b/include/TermVectorsTermsWriter.h @@ -16,7 +16,7 @@ namespace Lucene class TermVectorsTermsWriter : public TermsHashConsumer { public: - TermVectorsTermsWriter(DocumentsWriterPtr docWriter); + TermVectorsTermsWriter(const DocumentsWriterPtr& docWriter); virtual ~TermVectorsTermsWriter(); LUCENE_CLASS(TermVectorsTermsWriter); @@ -33,10 +33,10 @@ namespace Lucene int32_t allocCount; public: - virtual TermsHashConsumerPerThreadPtr addThread(TermsHashPerThreadPtr perThread); + virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread); virtual void createPostings(Collection postings, int32_t start, int32_t count); - virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state); - virtual void closeDocStore(SegmentWriteStatePtr state); + virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); TermVectorsTermsWriterPerDocPtr getPerDoc(); @@ -44,9 +44,9 @@ namespace Lucene void fill(int32_t docID); void initTermVectorsWriter(); - void finishDocument(TermVectorsTermsWriterPerDocPtr perDoc); + void finishDocument(const TermVectorsTermsWriterPerDocPtr& perDoc); bool freeRAM(); - void free(TermVectorsTermsWriterPerDocPtr doc); + void free(const TermVectorsTermsWriterPerDocPtr& doc); virtual void abort(); virtual int32_t bytesPerPosting(); @@ -55,7 +55,7 @@ namespace Lucene class TermVectorsTermsWriterPerDoc : public DocWriter { public: - TermVectorsTermsWriterPerDoc(TermVectorsTermsWriterPtr termsWriter = TermVectorsTermsWriterPtr()); + TermVectorsTermsWriterPerDoc(const TermVectorsTermsWriterPtr& termsWriter = TermVectorsTermsWriterPtr()); virtual ~TermVectorsTermsWriterPerDoc(); LUCENE_CLASS(TermVectorsTermsWriterPerDoc); diff --git a/include/TermVectorsTermsWriterPerField.h b/include/TermVectorsTermsWriterPerField.h index 1ac34e3b..b719fd19 100644 --- a/include/TermVectorsTermsWriterPerField.h +++ b/include/TermVectorsTermsWriterPerField.h @@ -14,7 +14,7 @@ namespace Lucene class TermVectorsTermsWriterPerField : public TermsHashConsumerPerField { public: - TermVectorsTermsWriterPerField(TermsHashPerFieldPtr termsHashPerField, TermVectorsTermsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo); + TermVectorsTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const TermVectorsTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); virtual ~TermVectorsTermsWriterPerField(); LUCENE_CLASS(TermVectorsTermsWriterPerField); @@ -45,9 +45,9 @@ namespace Lucene void shrinkHash(); - virtual void start(FieldablePtr field); - virtual void newTerm(RawPostingListPtr p0); - virtual void addTerm(RawPostingListPtr p0); + virtual void start(const FieldablePtr& field); + virtual void newTerm(const RawPostingListPtr& p0); + virtual void addTerm(const RawPostingListPtr& p0); virtual void skippingLongTerm(); }; } diff --git a/include/TermVectorsTermsWriterPerThread.h b/include/TermVectorsTermsWriterPerThread.h index a95def4c..2f6eecef 100644 --- a/include/TermVectorsTermsWriterPerThread.h +++ b/include/TermVectorsTermsWriterPerThread.h @@ -14,7 +14,7 @@ namespace Lucene class TermVectorsTermsWriterPerThread : public TermsHashConsumerPerThread { public: - TermVectorsTermsWriterPerThread(TermsHashPerThreadPtr termsHashPerThread, TermVectorsTermsWriterPtr termsWriter); + TermVectorsTermsWriterPerThread(const TermsHashPerThreadPtr& termsHashPerThread, const TermVectorsTermsWriterPtr& termsWriter); virtual ~TermVectorsTermsWriterPerThread(); LUCENE_CLASS(TermVectorsTermsWriterPerThread); @@ -32,12 +32,12 @@ namespace Lucene public: virtual void startDocument(); virtual DocWriterPtr finishDocument(); - virtual TermsHashConsumerPerFieldPtr addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo); + virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo); virtual void abort(); /// Called only by assert bool clearLastVectorFieldName(); - bool vectorFieldsInOrder(FieldInfoPtr fi); + bool vectorFieldsInOrder(const FieldInfoPtr& fi); }; } diff --git a/include/TermVectorsWriter.h b/include/TermVectorsWriter.h index e6d4bd71..2d03d20c 100644 --- a/include/TermVectorsWriter.h +++ b/include/TermVectorsWriter.h @@ -14,7 +14,7 @@ namespace Lucene class TermVectorsWriter : public LuceneObject { public: - TermVectorsWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fieldInfos); + TermVectorsWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fieldInfos); virtual ~TermVectorsWriter(); LUCENE_CLASS(TermVectorsWriter); @@ -33,7 +33,7 @@ namespace Lucene /// Do a bulk copy of numDocs documents from reader to our streams. This is used to expedite merging, /// if the field numbers are congruent. - void addRawDocuments(TermVectorsReaderPtr reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs); + void addRawDocuments(const TermVectorsReaderPtr& reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs); /// Close all streams. void close(); diff --git a/include/TermsHash.h b/include/TermsHash.h index 8feeb86e..5710d5bc 100644 --- a/include/TermsHash.h +++ b/include/TermsHash.h @@ -18,7 +18,7 @@ namespace Lucene class TermsHash : public InvertedDocConsumer { public: - TermsHash(DocumentsWriterPtr docWriter, bool trackAllocations, TermsHashConsumerPtr consumer, TermsHashPtr nextTermsHash); + TermsHash(const DocumentsWriterPtr& docWriter, bool trackAllocations, const TermsHashConsumerPtr& consumer, const TermsHashPtr& nextTermsHash); virtual ~TermsHash(); LUCENE_CLASS(TermsHash); @@ -38,23 +38,23 @@ namespace Lucene public: /// Add a new thread - virtual InvertedDocConsumerPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread); - virtual TermsHashPerThreadPtr addThread(DocInverterPerThreadPtr docInverterPerThread, TermsHashPerThreadPtr primaryPerThread); + virtual InvertedDocConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread); + virtual TermsHashPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPerThreadPtr& primaryPerThread); - virtual void setFieldInfos(FieldInfosPtr fieldInfos); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); /// Abort (called after hitting AbortException) /// NOTE: do not make this sync'd; it's not necessary (DW ensures all other threads are idle), and it /// leads to deadlock virtual void abort(); - void shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state); + void shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); /// Close doc stores - virtual void closeDocStore(SegmentWriteStatePtr state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); /// Flush a new segment - virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state); + virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); /// Attempt to free RAM, returning true if any RAM was freed virtual bool freeRAM(); diff --git a/include/TermsHashConsumer.h b/include/TermsHashConsumer.h index ef178bb5..8c9b87ff 100644 --- a/include/TermsHashConsumer.h +++ b/include/TermsHashConsumer.h @@ -24,12 +24,12 @@ namespace Lucene public: virtual int32_t bytesPerPosting() = 0; virtual void createPostings(Collection postings, int32_t start, int32_t count) = 0; - virtual TermsHashConsumerPerThreadPtr addThread(TermsHashPerThreadPtr perThread) = 0; - virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state) = 0; + virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread) = 0; + virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; virtual void abort() = 0; - virtual void closeDocStore(SegmentWriteStatePtr state) = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; - virtual void setFieldInfos(FieldInfosPtr fieldInfos); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); }; } diff --git a/include/TermsHashConsumerPerField.h b/include/TermsHashConsumerPerField.h index 2f7405d2..7718bc20 100644 --- a/include/TermsHashConsumerPerField.h +++ b/include/TermsHashConsumerPerField.h @@ -24,9 +24,9 @@ namespace Lucene virtual bool start(Collection fields, int32_t count) = 0; virtual void finish() = 0; virtual void skippingLongTerm() = 0; - virtual void start(FieldablePtr field) = 0; - virtual void newTerm(RawPostingListPtr p) = 0; - virtual void addTerm(RawPostingListPtr p) = 0; + virtual void start(const FieldablePtr& field) = 0; + virtual void newTerm(const RawPostingListPtr& p) = 0; + virtual void addTerm(const RawPostingListPtr& p) = 0; virtual int32_t getStreamCount() = 0; }; } diff --git a/include/TermsHashConsumerPerThread.h b/include/TermsHashConsumerPerThread.h index 575fc4f9..b3a443a3 100644 --- a/include/TermsHashConsumerPerThread.h +++ b/include/TermsHashConsumerPerThread.h @@ -21,7 +21,7 @@ namespace Lucene public: virtual void startDocument() = 0; virtual DocWriterPtr finishDocument() = 0; - virtual TermsHashConsumerPerFieldPtr addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo) = 0; + virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) = 0; virtual void abort() = 0; }; } diff --git a/include/TermsHashPerField.h b/include/TermsHashPerField.h index 5e411343..aac8e073 100644 --- a/include/TermsHashPerField.h +++ b/include/TermsHashPerField.h @@ -14,7 +14,7 @@ namespace Lucene class TermsHashPerField : public InvertedDocConsumerPerField { public: - TermsHashPerField(DocInverterPerFieldPtr docInverterPerField, TermsHashPerThreadPtr perThread, TermsHashPerThreadPtr nextPerThread, FieldInfoPtr fieldInfo); + TermsHashPerField(const DocInverterPerFieldPtr& docInverterPerField, const TermsHashPerThreadPtr& perThread, const TermsHashPerThreadPtr& nextPerThread, const FieldInfoPtr& fieldInfo); virtual ~TermsHashPerField(); LUCENE_CLASS(TermsHashPerField); @@ -62,13 +62,13 @@ namespace Lucene /// Called on hitting an aborting exception virtual void abort(); - void initReader(ByteSliceReaderPtr reader, RawPostingListPtr p, int32_t stream); + void initReader(const ByteSliceReaderPtr& reader, const RawPostingListPtr& p, int32_t stream); /// Collapse the hash table and sort in-place. Collection sortPostings(); /// Called before a field instance is being processed - virtual void start(FieldablePtr field); + virtual void start(const FieldablePtr& field); /// Called once per field, and is given all Fieldable occurrences for this field in the document. virtual bool start(Collection fields, int32_t count); diff --git a/include/TermsHashPerThread.h b/include/TermsHashPerThread.h index ae0d6875..da9dba67 100644 --- a/include/TermsHashPerThread.h +++ b/include/TermsHashPerThread.h @@ -14,7 +14,7 @@ namespace Lucene class TermsHashPerThread : public InvertedDocConsumerPerThread { public: - TermsHashPerThread(DocInverterPerThreadPtr docInverterPerThread, TermsHashPtr termsHash, TermsHashPtr nextTermsHash, TermsHashPerThreadPtr primaryPerThread); + TermsHashPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPtr& termsHash, const TermsHashPtr& nextTermsHash, const TermsHashPerThreadPtr& primaryPerThread); virtual ~TermsHashPerThread(); LUCENE_CLASS(TermsHashPerThread); @@ -39,7 +39,7 @@ namespace Lucene public: virtual void initialize(); - virtual InvertedDocConsumerPerFieldPtr addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo); + virtual InvertedDocConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo); virtual void abort(); /// perField calls this when it needs more postings diff --git a/include/ThreadPool.h b/include/ThreadPool.h index 50454646..c94fc690 100644 --- a/include/ThreadPool.h +++ b/include/ThreadPool.h @@ -75,7 +75,7 @@ namespace Lucene protected: // this will be executed when one of the threads is available template - void execute(FUNC func, FuturePtr future) + void execute(FUNC func, const FuturePtr& future) { future->set(func()); future->notifyAll(); diff --git a/include/TimeLimitingCollector.h b/include/TimeLimitingCollector.h index c417eaf1..9fb236b4 100644 --- a/include/TimeLimitingCollector.h +++ b/include/TimeLimitingCollector.h @@ -20,7 +20,7 @@ namespace Lucene /// Create a TimeLimitedCollector wrapper over another {@link Collector} with a specified timeout. /// @param collector the wrapped {@link Collector} /// @param timeAllowed max time allowed for collecting hits after which TimeExceeded exception is thrown - TimeLimitingCollector(CollectorPtr collector, int64_t timeAllowed); + TimeLimitingCollector(const CollectorPtr& collector, int64_t timeAllowed); virtual ~TimeLimitingCollector(); @@ -82,8 +82,8 @@ namespace Lucene /// passed, in which case it throws an exception. virtual void collect(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setScorer(ScorerPtr scorer); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); virtual bool acceptsDocsOutOfOrder(); protected: diff --git a/include/Token.h b/include/Token.h index 15171d70..85f52b78 100644 --- a/include/Token.h +++ b/include/Token.h @@ -259,20 +259,20 @@ namespace Lucene virtual PayloadPtr getPayload(); /// Sets this Token's payload. - virtual void setPayload(PayloadPtr payload); + virtual void setPayload(const PayloadPtr& payload); virtual String toString(); /// Resets the term text, payload, flags, and positionIncrement, startOffset, endOffset and token type to default. virtual void clear(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Makes a clone, but replaces the term buffer and start/end offset in the process. This is more efficient than /// doing a full clone (and then calling setTermBuffer) because it saves a wasted copy of the old termBuffer. TokenPtr clone(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(char[], int, int)}, {@link #setStartOffset}, @@ -306,15 +306,15 @@ namespace Lucene TokenPtr reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); /// Copy the prototype token's fields into this one. Note: Payloads are shared. - void reinit(TokenPtr prototype); + void reinit(const TokenPtr& prototype); /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. - void reinit(TokenPtr prototype, const String& newTerm); + void reinit(const TokenPtr& prototype, const String& newTerm); /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. - void reinit(TokenPtr prototype, CharArray newTermBuffer, int32_t offset, int32_t length); + void reinit(const TokenPtr& prototype, CharArray newTermBuffer, int32_t offset, int32_t length); - virtual void copyTo(AttributePtr target); + virtual void copyTo(const AttributePtr& target); /// Convenience factory that returns Token as implementation for the basic attributes static AttributeFactoryPtr TOKEN_ATTRIBUTE_FACTORY(); @@ -339,7 +339,7 @@ namespace Lucene class LPPAPI TokenAttributeFactory : public AttributeFactory { public: - TokenAttributeFactory(AttributeFactoryPtr delegate); + TokenAttributeFactory(const AttributeFactoryPtr& delegate); virtual ~TokenAttributeFactory(); LUCENE_CLASS(TokenAttributeFactory); @@ -349,7 +349,7 @@ namespace Lucene public: virtual AttributePtr createAttributeInstance(const String& className); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; } diff --git a/include/TokenFilter.h b/include/TokenFilter.h index 95702e4b..805c52c1 100644 --- a/include/TokenFilter.h +++ b/include/TokenFilter.h @@ -19,7 +19,7 @@ namespace Lucene { protected: /// Construct a token stream filtering the given input. - TokenFilter(TokenStreamPtr input); + TokenFilter(const TokenStreamPtr& input); public: virtual ~TokenFilter(); diff --git a/include/TokenStream.h b/include/TokenStream.h index 4e930d2b..e728dc93 100644 --- a/include/TokenStream.h +++ b/include/TokenStream.h @@ -48,10 +48,10 @@ namespace Lucene TokenStream(); /// A TokenStream that uses the same attributes as the supplied one. - TokenStream(AttributeSourcePtr input); + TokenStream(const AttributeSourcePtr& input); /// A TokenStream using the supplied AttributeFactory for creating new {@link Attribute} instances. - TokenStream(AttributeFactoryPtr factory); + TokenStream(const AttributeFactoryPtr& factory); public: virtual ~TokenStream(); diff --git a/include/Tokenizer.h b/include/Tokenizer.h index ef23fd4b..dfd9e4b8 100644 --- a/include/Tokenizer.h +++ b/include/Tokenizer.h @@ -24,19 +24,19 @@ namespace Lucene Tokenizer(); /// Construct a token stream processing the given input. - Tokenizer(ReaderPtr input); + Tokenizer(const ReaderPtr& input); /// Construct a tokenizer with null input using the given AttributeFactory. - Tokenizer(AttributeFactoryPtr factory); + Tokenizer(const AttributeFactoryPtr& factory); /// Construct a token stream processing the given input using the given AttributeFactory. - Tokenizer(AttributeFactoryPtr factory, ReaderPtr input); + Tokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); /// Construct a token stream processing the given input using the given AttributeSource. - Tokenizer(AttributeSourcePtr source); + Tokenizer(const AttributeSourcePtr& source); /// Construct a token stream processing the given input using the given AttributeSource. - Tokenizer(AttributeSourcePtr source, ReaderPtr input); + Tokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); public: virtual ~Tokenizer(); @@ -63,7 +63,7 @@ namespace Lucene /// Reset the tokenizer to a new reader. Typically, an analyzer (in its reusableTokenStream method) will /// use this to re-use a previously created tokenizer. - virtual void reset(ReaderPtr input); + virtual void reset(const ReaderPtr& input); }; } diff --git a/include/TopDocsCollector.h b/include/TopDocsCollector.h index 9adea4ea..b232d693 100644 --- a/include/TopDocsCollector.h +++ b/include/TopDocsCollector.h @@ -21,7 +21,7 @@ namespace Lucene class LPPAPI TopDocsCollector : public Collector { public: - TopDocsCollector(HitQueueBasePtr pq); + TopDocsCollector(const HitQueueBasePtr& pq); virtual ~TopDocsCollector(); LUCENE_CLASS(TopDocsCollector); diff --git a/include/TopFieldCollector.h b/include/TopFieldCollector.h index 8871c942..19d6737d 100644 --- a/include/TopFieldCollector.h +++ b/include/TopFieldCollector.h @@ -17,7 +17,7 @@ namespace Lucene class LPPAPI TopFieldCollector : public TopDocsCollector { public: - TopFieldCollector(HitQueueBasePtr pq, int32_t numHits, bool fillFields); + TopFieldCollector(const HitQueueBasePtr& pq, int32_t numHits, bool fillFields); virtual ~TopFieldCollector(); LUCENE_CLASS(TopFieldCollector); @@ -53,7 +53,7 @@ namespace Lucene /// @param docsScoredInOrder Specifies whether documents are scored in doc Id order or not by the given /// {@link Scorer} in {@link #setScorer(ScorerPtr)}. /// @return a {@link TopFieldCollector} instance which will sort the results by the sort criteria. - static TopFieldCollectorPtr create(SortPtr sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder); + static TopFieldCollectorPtr create(const SortPtr& sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder); virtual void add(int32_t slot, int32_t doc, double score); diff --git a/include/TopScoreDocCollector.h b/include/TopScoreDocCollector.h index 4fa2e010..236e5278 100644 --- a/include/TopScoreDocCollector.h +++ b/include/TopScoreDocCollector.h @@ -38,8 +38,8 @@ namespace Lucene /// NOTE: The instances returned by this method pre-allocate a full array of length numHits. static TopScoreDocCollectorPtr create(int32_t numHits, bool docsScoredInOrder); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setScorer(ScorerPtr scorer); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); protected: virtual TopDocsPtr newTopDocs(Collection results, int32_t start); diff --git a/include/TypeAttribute.h b/include/TypeAttribute.h index 32f51ad5..75a4a943 100644 --- a/include/TypeAttribute.h +++ b/include/TypeAttribute.h @@ -36,10 +36,10 @@ namespace Lucene void setType(const String& type); virtual void clear(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual void copyTo(AttributePtr target); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/UTF8Stream.h b/include/UTF8Stream.h index 884adf3a..b7cf9349 100644 --- a/include/UTF8Stream.h +++ b/include/UTF8Stream.h @@ -69,7 +69,7 @@ namespace Lucene class UTF8EncoderStream : public UTF8Encoder { public: - UTF8EncoderStream(ReaderPtr reader); + UTF8EncoderStream(const ReaderPtr& reader); virtual ~UTF8EncoderStream(); LUCENE_CLASS(UTF8EncoderStream); @@ -110,7 +110,7 @@ namespace Lucene class UTF8DecoderStream : public UTF8Decoder { public: - UTF8DecoderStream(ReaderPtr reader); + UTF8DecoderStream(const ReaderPtr& reader); virtual ~UTF8DecoderStream(); LUCENE_CLASS(UTF8DecoderStream); diff --git a/include/ValueSource.h b/include/ValueSource.h index 0b4ef465..9c04fd45 100644 --- a/include/ValueSource.h +++ b/include/ValueSource.h @@ -28,7 +28,7 @@ namespace Lucene /// Return the DocValues used by the function query. /// @param reader The IndexReader used to read these values. If any caching is involved, that caching /// would also be IndexReader based. - virtual DocValuesPtr getValues(IndexReaderPtr reader) = 0; + virtual DocValuesPtr getValues(const IndexReaderPtr& reader) = 0; /// Description of field, used in explain() virtual String description() = 0; @@ -36,7 +36,7 @@ namespace Lucene virtual String toString(); /// Needed for possible caching of query results - used by {@link ValueSourceQuery#equals(LuceneObjectPtr)}. - virtual bool equals(LuceneObjectPtr other) = 0; + virtual bool equals(const LuceneObjectPtr& other) = 0; /// Needed for possible caching of query results - used by {@link ValueSourceQuery#hashCode()}. virtual int32_t hashCode() = 0; diff --git a/include/ValueSourceQuery.h b/include/ValueSourceQuery.h index 6d2bda92..966b0f9a 100644 --- a/include/ValueSourceQuery.h +++ b/include/ValueSourceQuery.h @@ -24,7 +24,7 @@ namespace Lucene public: /// Create a value source query /// @param valSrc provides the values defines the function to be used for scoring - ValueSourceQuery(ValueSourcePtr valSrc); + ValueSourceQuery(const ValueSourcePtr& valSrc); virtual ~ValueSourceQuery(); @@ -36,13 +36,13 @@ namespace Lucene public: using Query::toString; - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); virtual void extractTerms(SetTerm terms); - virtual WeightPtr createWeight(SearcherPtr searcher); + virtual WeightPtr createWeight(const SearcherPtr& searcher); virtual String toString(const String& field); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/include/Weight.h b/include/Weight.h index 1aff3f09..29d33a18 100644 --- a/include/Weight.h +++ b/include/Weight.h @@ -38,7 +38,7 @@ namespace Lucene /// @param reader sub-reader containing the give doc /// @param doc /// @return an Explanation for the score - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc) = 0; + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc) = 0; /// The query that this concerns. virtual QueryPtr getQuery() = 0; @@ -66,7 +66,7 @@ namespace Lucene /// @param topScorer If true, {@link Scorer#score(CollectorPtr)} will be called; if false, {@link /// Scorer#nextDoc()} and/or {@link Scorer#advance(int)} will be called. /// @return a {@link Scorer} which scores documents in/out-of order. - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) = 0; + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) = 0; /// The sum of squared weights of contained query clauses. virtual double sumOfSquaredWeights() = 0; diff --git a/include/WhitespaceAnalyzer.h b/include/WhitespaceAnalyzer.h index 53e3b4e0..5a3afd0f 100644 --- a/include/WhitespaceAnalyzer.h +++ b/include/WhitespaceAnalyzer.h @@ -20,8 +20,8 @@ namespace Lucene LUCENE_CLASS(WhitespaceAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; } diff --git a/include/WhitespaceTokenizer.h b/include/WhitespaceTokenizer.h index 105269eb..2368b3c6 100644 --- a/include/WhitespaceTokenizer.h +++ b/include/WhitespaceTokenizer.h @@ -17,13 +17,13 @@ namespace Lucene { public: /// Construct a new WhitespaceTokenizer. - WhitespaceTokenizer(ReaderPtr input); + WhitespaceTokenizer(const ReaderPtr& input); /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource}. - WhitespaceTokenizer(AttributeSourcePtr source, ReaderPtr input); + WhitespaceTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource.AttributeFactory}. - WhitespaceTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + WhitespaceTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~WhitespaceTokenizer(); diff --git a/include/WildcardQuery.h b/include/WildcardQuery.h index e044bd01..dcf87333 100644 --- a/include/WildcardQuery.h +++ b/include/WildcardQuery.h @@ -21,7 +21,7 @@ namespace Lucene class LPPAPI WildcardQuery : public MultiTermQuery { public: - WildcardQuery(TermPtr term); + WildcardQuery(const TermPtr& term); virtual ~WildcardQuery(); LUCENE_CLASS(WildcardQuery); @@ -37,17 +37,17 @@ namespace Lucene /// Returns the pattern term. TermPtr getTerm(); - virtual QueryPtr rewrite(IndexReaderPtr reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); /// Prints a user-readable version of this query. virtual String toString(const String& field); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); protected: - virtual FilteredTermEnumPtr getEnum(IndexReaderPtr reader); + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); }; } diff --git a/include/WildcardTermEnum.h b/include/WildcardTermEnum.h index 3db3b5f5..9c7eaa8c 100644 --- a/include/WildcardTermEnum.h +++ b/include/WildcardTermEnum.h @@ -22,7 +22,7 @@ namespace Lucene /// /// After calling the constructor the enumeration is already pointing to the first valid term if such /// a term exists. - WildcardTermEnum(IndexReaderPtr reader, TermPtr term); + WildcardTermEnum(const IndexReaderPtr& reader, const TermPtr& term); virtual ~WildcardTermEnum(); @@ -46,7 +46,7 @@ namespace Lucene static bool wildcardEquals(const String& pattern, int32_t patternIdx, const String& string, int32_t stringIdx); protected: - virtual bool termCompare(TermPtr term); + virtual bool termCompare(const TermPtr& term); virtual bool endEnum(); }; } diff --git a/include/WordlistLoader.h b/include/WordlistLoader.h index c61527d4..7fc788f4 100644 --- a/include/WordlistLoader.h +++ b/include/WordlistLoader.h @@ -36,7 +36,7 @@ namespace Lucene /// @param reader Reader containing the wordlist /// @param comment The comment string to ignore /// @return A set with the file's words - static HashSet getWordSet(ReaderPtr reader, const String& comment = EmptyString); + static HashSet getWordSet(const ReaderPtr& reader, const String& comment = EmptyString); /// Reads a stem dictionary. Each line contains: ///
      word\tstem
      diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp index 8fffc42b..5bc04484 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp @@ -103,7 +103,7 @@ namespace Lucene return stopSet; } - TokenStreamPtr ArabicAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr ArabicAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result); @@ -114,7 +114,7 @@ namespace Lucene return result; } - TokenStreamPtr ArabicAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr ArabicAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { ArabicAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp index faa0dcb8..e71f203f 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp @@ -11,15 +11,15 @@ namespace Lucene { - ArabicLetterTokenizer::ArabicLetterTokenizer(ReaderPtr input) : LetterTokenizer(input) + ArabicLetterTokenizer::ArabicLetterTokenizer(const ReaderPtr& input) : LetterTokenizer(input) { } - ArabicLetterTokenizer::ArabicLetterTokenizer(AttributeSourcePtr source, ReaderPtr input) : LetterTokenizer(source, input) + ArabicLetterTokenizer::ArabicLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : LetterTokenizer(source, input) { } - ArabicLetterTokenizer::ArabicLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : LetterTokenizer(factory, input) + ArabicLetterTokenizer::ArabicLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : LetterTokenizer(factory, input) { } diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp index 18d8eed8..58012e06 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - ArabicNormalizationFilter::ArabicNormalizationFilter(TokenStreamPtr input) : TokenFilter(input) + ArabicNormalizationFilter::ArabicNormalizationFilter(const TokenStreamPtr& input) : TokenFilter(input) { normalizer = newLucene(); termAtt = addAttribute(); diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp index a4dd4a4a..fb383f97 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - ArabicStemFilter::ArabicStemFilter(TokenStreamPtr input) : TokenFilter(input) + ArabicStemFilter::ArabicStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp index ea1bef11..83715d1b 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp @@ -76,7 +76,7 @@ namespace Lucene setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - TokenStreamPtr BrazilianAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr BrazilianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); @@ -86,7 +86,7 @@ namespace Lucene return result; } - TokenStreamPtr BrazilianAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr BrazilianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { BrazilianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp index 65f26e36..aaea50ea 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp @@ -11,13 +11,13 @@ namespace Lucene { - BrazilianStemFilter::BrazilianStemFilter(TokenStreamPtr input) : TokenFilter(input) + BrazilianStemFilter::BrazilianStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); } - BrazilianStemFilter::BrazilianStemFilter(TokenStreamPtr input, HashSet exclusiontable) : TokenFilter(input) + BrazilianStemFilter::BrazilianStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); diff --git a/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp index 93fe48a0..2c0647f3 100644 --- a/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp @@ -46,12 +46,12 @@ namespace Lucene return stopSet; } - TokenStreamPtr CJKAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr CJKAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), newLucene(reader), stoptable); } - TokenStreamPtr CJKAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr CJKAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { CJKAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp b/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp index 57f428c5..4a4abdf4 100644 --- a/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp @@ -32,15 +32,15 @@ namespace Lucene const int32_t CJKTokenizer::IO_BUFFER_SIZE = 256; - CJKTokenizer::CJKTokenizer(ReaderPtr input) : Tokenizer(input) + CJKTokenizer::CJKTokenizer(const ReaderPtr& input) : Tokenizer(input) { } - CJKTokenizer::CJKTokenizer(AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source, input) + CJKTokenizer::CJKTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) { } - CJKTokenizer::CJKTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory, input) + CJKTokenizer::CJKTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) { } @@ -270,7 +270,7 @@ namespace Lucene tokenType = WORD_TYPE; } - void CJKTokenizer::reset(ReaderPtr input) + void CJKTokenizer::reset(const ReaderPtr& input) { Tokenizer::reset(input); reset(); diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp index 0060a254..ecca602f 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp @@ -15,14 +15,14 @@ namespace Lucene { } - TokenStreamPtr ChineseAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr ChineseAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result); return result; } - TokenStreamPtr ChineseAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr ChineseAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { ChineseAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp index fd9067cd..97fbe0bf 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp @@ -21,7 +21,7 @@ namespace Lucene L"they", L"this", L"to", L"was", L"will", L"with" }; - ChineseFilter::ChineseFilter(TokenStreamPtr input) : TokenFilter(input) + ChineseFilter::ChineseFilter(const TokenStreamPtr& input) : TokenFilter(input) { stopTable = HashSet::newInstance(STOP_WORDS, STOP_WORDS + SIZEOF_ARRAY(STOP_WORDS)); termAtt = addAttribute(); diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp index 86c51dcd..8b35a865 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp @@ -18,15 +18,15 @@ namespace Lucene const int32_t ChineseTokenizer::MAX_WORD_LEN = 255; const int32_t ChineseTokenizer::IO_BUFFER_SIZE = 1024; - ChineseTokenizer::ChineseTokenizer(ReaderPtr input) : Tokenizer(input) + ChineseTokenizer::ChineseTokenizer(const ReaderPtr& input) : Tokenizer(input) { } - ChineseTokenizer::ChineseTokenizer(AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source, input) + ChineseTokenizer::ChineseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) { } - ChineseTokenizer::ChineseTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory, input) + ChineseTokenizer::ChineseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) { } @@ -130,7 +130,7 @@ namespace Lucene dataLen = 0; } - void ChineseTokenizer::reset(ReaderPtr input) + void ChineseTokenizer::reset(const ReaderPtr& input) { Tokenizer::reset(input); reset(); diff --git a/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp index b95afba6..84a5842c 100644 --- a/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp @@ -100,7 +100,7 @@ namespace Lucene return stopSet; } - TokenStreamPtr CzechAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr CzechAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); @@ -109,7 +109,7 @@ namespace Lucene return result; } - TokenStreamPtr CzechAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr CzechAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { CzechAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp b/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp index a5de612f..db166586 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp @@ -62,7 +62,7 @@ namespace Lucene setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - TokenStreamPtr GermanAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr GermanAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); @@ -72,7 +72,7 @@ namespace Lucene return result; } - TokenStreamPtr GermanAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr GermanAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { GermanAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp b/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp index 7b2ff52b..6d5d1210 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp @@ -11,13 +11,13 @@ namespace Lucene { - GermanStemFilter::GermanStemFilter(TokenStreamPtr input) : TokenFilter(input) + GermanStemFilter::GermanStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); } - GermanStemFilter::GermanStemFilter(TokenStreamPtr input, HashSet exclusionSet) : TokenFilter(input) + GermanStemFilter::GermanStemFilter(const TokenStreamPtr& input, HashSet exclusionSet) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); @@ -47,7 +47,7 @@ namespace Lucene return false; } - void GermanStemFilter::setStemmer(GermanStemmerPtr stemmer) + void GermanStemFilter::setStemmer(const GermanStemmerPtr& stemmer) { if (stemmer) this->stemmer = stemmer; diff --git a/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp b/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp index be4ee05b..74b1c04a 100644 --- a/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp @@ -87,7 +87,7 @@ namespace Lucene return stopSet; } - TokenStreamPtr GreekAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr GreekAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); @@ -95,7 +95,7 @@ namespace Lucene return result; } - TokenStreamPtr GreekAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr GreekAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { GreekAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp b/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp index e27a083d..61771c3c 100644 --- a/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - GreekLowerCaseFilter::GreekLowerCaseFilter(TokenStreamPtr input) : TokenFilter(input) + GreekLowerCaseFilter::GreekLowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) { termAtt = addAttribute(); } diff --git a/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp index b73c5f6d..0d26d9ba 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp @@ -219,7 +219,7 @@ namespace Lucene return stopSet; } - TokenStreamPtr PersianAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr PersianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result); @@ -231,7 +231,7 @@ namespace Lucene return result; } - TokenStreamPtr PersianAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr PersianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { PersianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp b/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp index 59971923..c5ef30b1 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - PersianNormalizationFilter::PersianNormalizationFilter(TokenStreamPtr input) : TokenFilter(input) + PersianNormalizationFilter::PersianNormalizationFilter(const TokenStreamPtr& input) : TokenFilter(input) { normalizer = newLucene(); termAtt = addAttribute(); diff --git a/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp b/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp index 36224bc3..b3c33b2b 100644 --- a/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp @@ -13,13 +13,13 @@ namespace Lucene { const wchar_t ElisionFilter::apostrophes[] = {L'\'', L'\x2019'}; - ElisionFilter::ElisionFilter(TokenStreamPtr input) : TokenFilter(input) + ElisionFilter::ElisionFilter(const TokenStreamPtr& input) : TokenFilter(input) { articles = newLucene(newCollection(L"l", L"m", L"t", L"qu", L"n", L"s", L"j"), true); termAtt = addAttribute(); } - ElisionFilter::ElisionFilter(TokenStreamPtr input, HashSet articles) : TokenFilter(input) + ElisionFilter::ElisionFilter(const TokenStreamPtr& input, HashSet articles) : TokenFilter(input) { setArticles(articles); termAtt = addAttribute(); diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp index 1b94e487..3d95f658 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp @@ -78,7 +78,7 @@ namespace Lucene setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - TokenStreamPtr FrenchAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr FrenchAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); @@ -89,7 +89,7 @@ namespace Lucene return result; } - TokenStreamPtr FrenchAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr FrenchAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { FrenchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp index d7062d6d..374fe386 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp @@ -11,13 +11,13 @@ namespace Lucene { - FrenchStemFilter::FrenchStemFilter(TokenStreamPtr input) : TokenFilter(input) + FrenchStemFilter::FrenchStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); } - FrenchStemFilter::FrenchStemFilter(TokenStreamPtr input, HashSet exclusiontable) : TokenFilter(input) + FrenchStemFilter::FrenchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); @@ -47,7 +47,7 @@ namespace Lucene return false; } - void FrenchStemFilter::setStemmer(FrenchStemmerPtr stemmer) + void FrenchStemFilter::setStemmer(const FrenchStemmerPtr& stemmer) { if (stemmer) this->stemmer = stemmer; diff --git a/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp b/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp index 49105e5c..13b3c468 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp @@ -75,7 +75,7 @@ namespace Lucene setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created } - TokenStreamPtr DutchAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr DutchAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); @@ -84,7 +84,7 @@ namespace Lucene return result; } - TokenStreamPtr DutchAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr DutchAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { DutchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp b/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp index 76f73d62..455e9882 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp @@ -11,20 +11,20 @@ namespace Lucene { - DutchStemFilter::DutchStemFilter(TokenStreamPtr input) : TokenFilter(input) + DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); } - DutchStemFilter::DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable) : TokenFilter(input) + DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); this->exclusions = exclusiontable; } - DutchStemFilter::DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable, MapStringString stemdictionary) : TokenFilter(input) + DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable, MapStringString stemdictionary) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); @@ -56,7 +56,7 @@ namespace Lucene return false; } - void DutchStemFilter::setStemmer(DutchStemmerPtr stemmer) + void DutchStemFilter::setStemmer(const DutchStemmerPtr& stemmer) { if (stemmer) this->stemmer = stemmer; diff --git a/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp b/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp index 13caf383..04b3c7f0 100644 --- a/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp +++ b/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp @@ -24,13 +24,13 @@ namespace Lucene /// Example marker character: U+200F (RIGHT-TO-LEFT MARK) const wchar_t ReverseStringFilter::RTL_DIRECTION_MARKER = (wchar_t)0x200f; - ReverseStringFilter::ReverseStringFilter(TokenStreamPtr input) : TokenFilter(input) + ReverseStringFilter::ReverseStringFilter(const TokenStreamPtr& input) : TokenFilter(input) { this->marker = NOMARKER; termAtt = addAttribute(); } - ReverseStringFilter::ReverseStringFilter(TokenStreamPtr input, wchar_t marker) : TokenFilter(input) + ReverseStringFilter::ReverseStringFilter(const TokenStreamPtr& input, wchar_t marker) : TokenFilter(input) { this->marker = marker; termAtt = addAttribute(); diff --git a/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp index d1cda356..3b6a44d5 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp @@ -91,7 +91,7 @@ namespace Lucene return stopSet; } - TokenStreamPtr RussianAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr RussianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result); @@ -100,7 +100,7 @@ namespace Lucene return result; } - TokenStreamPtr RussianAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr RussianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { RussianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp index e551f47f..1359d926 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp @@ -11,15 +11,15 @@ namespace Lucene { - RussianLetterTokenizer::RussianLetterTokenizer(ReaderPtr input) : CharTokenizer(input) + RussianLetterTokenizer::RussianLetterTokenizer(const ReaderPtr& input) : CharTokenizer(input) { } - RussianLetterTokenizer::RussianLetterTokenizer(AttributeSourcePtr source, ReaderPtr input) : CharTokenizer(source, input) + RussianLetterTokenizer::RussianLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) { } - RussianLetterTokenizer::RussianLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : CharTokenizer(factory, input) + RussianLetterTokenizer::RussianLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) { } diff --git a/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp b/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp index 3982ff67..8bbc1842 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - RussianLowerCaseFilter::RussianLowerCaseFilter(TokenStreamPtr input) : TokenFilter(input) + RussianLowerCaseFilter::RussianLowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) { termAtt = addAttribute(); } diff --git a/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp b/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp index 407194a8..ec3cf8af 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - RussianStemFilter::RussianStemFilter(TokenStreamPtr input) : TokenFilter(input) + RussianStemFilter::RussianStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); @@ -35,7 +35,7 @@ namespace Lucene return false; } - void RussianStemFilter::setStemmer(RussianStemmerPtr stemmer) + void RussianStemFilter::setStemmer(const RussianStemmerPtr& stemmer) { if (stemmer) this->stemmer = stemmer; diff --git a/src/contrib/highlighter/Formatter.cpp b/src/contrib/highlighter/Formatter.cpp index b3c60a58..1f832c79 100644 --- a/src/contrib/highlighter/Formatter.cpp +++ b/src/contrib/highlighter/Formatter.cpp @@ -13,7 +13,7 @@ namespace Lucene { } - String Formatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) + String Formatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { BOOST_ASSERT(false); return L""; // override diff --git a/src/contrib/highlighter/Fragmenter.cpp b/src/contrib/highlighter/Fragmenter.cpp index 9c3f9cf4..df74f99b 100644 --- a/src/contrib/highlighter/Fragmenter.cpp +++ b/src/contrib/highlighter/Fragmenter.cpp @@ -13,7 +13,7 @@ namespace Lucene { } - void Fragmenter::start(const String& originalText, TokenStreamPtr tokenStream) + void Fragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { BOOST_ASSERT(false); // override diff --git a/src/contrib/highlighter/GradientFormatter.cpp b/src/contrib/highlighter/GradientFormatter.cpp index b5351536..9a03eb74 100644 --- a/src/contrib/highlighter/GradientFormatter.cpp +++ b/src/contrib/highlighter/GradientFormatter.cpp @@ -54,7 +54,7 @@ namespace Lucene { } - String GradientFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) + String GradientFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { if (tokenGroup->getTotalScore() == 0) return originalText; diff --git a/src/contrib/highlighter/Highlighter.cpp b/src/contrib/highlighter/Highlighter.cpp index f03ad83f..a8ad89d1 100644 --- a/src/contrib/highlighter/Highlighter.cpp +++ b/src/contrib/highlighter/Highlighter.cpp @@ -25,7 +25,7 @@ namespace Lucene { const int32_t Highlighter::DEFAULT_MAX_CHARS_TO_ANALYZE = 50 * 1024; - Highlighter::Highlighter(HighlighterScorerPtr fragmentScorer) + Highlighter::Highlighter(const HighlighterScorerPtr& fragmentScorer) { this->formatter = newLucene(); this->encoder = newLucene(); @@ -34,7 +34,7 @@ namespace Lucene this->textFragmenter = newLucene(); } - Highlighter::Highlighter(FormatterPtr formatter, HighlighterScorerPtr fragmentScorer) + Highlighter::Highlighter(const FormatterPtr& formatter, const HighlighterScorerPtr& fragmentScorer) { this->formatter = formatter; this->encoder = newLucene(); @@ -43,7 +43,7 @@ namespace Lucene this->textFragmenter = newLucene(); } - Highlighter::Highlighter(FormatterPtr formatter, EncoderPtr encoder, HighlighterScorerPtr fragmentScorer) + Highlighter::Highlighter(const FormatterPtr& formatter, const EncoderPtr& encoder, const HighlighterScorerPtr& fragmentScorer) { this->formatter = formatter; this->encoder = encoder; @@ -56,25 +56,25 @@ namespace Lucene { } - String Highlighter::getBestFragment(AnalyzerPtr analyzer, const String& fieldName, const String& text) + String Highlighter::getBestFragment(const AnalyzerPtr& analyzer, const String& fieldName, const String& text) { TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); return getBestFragment(tokenStream, text); } - String Highlighter::getBestFragment(TokenStreamPtr tokenStream, const String& text) + String Highlighter::getBestFragment(const TokenStreamPtr& tokenStream, const String& text) { Collection results(getBestFragments(tokenStream,text, 1)); return results.empty() ? L"" : results[0]; } - Collection Highlighter::getBestFragments(AnalyzerPtr analyzer, const String& fieldName, const String& text, int32_t maxNumFragments) + Collection Highlighter::getBestFragments(const AnalyzerPtr& analyzer, const String& fieldName, const String& text, int32_t maxNumFragments) { TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); return getBestFragments(tokenStream, text, maxNumFragments); } - Collection Highlighter::getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments) + Collection Highlighter::getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments) { maxNumFragments = std::max((int32_t)1, maxNumFragments); //sanity check @@ -90,20 +90,21 @@ namespace Lucene return fragTexts; } - Collection Highlighter::getBestTextFragments(TokenStreamPtr tokenStream, const String& text, bool merge, int32_t maxNumFragments) + Collection Highlighter::getBestTextFragments(const TokenStreamPtr& tokenStream, const String& text, bool merge, int32_t maxNumFragments) { Collection docFrags(Collection::newInstance()); StringBufferPtr newText(newLucene()); - TermAttributePtr termAtt(tokenStream->addAttribute()); - OffsetAttributePtr offsetAtt(tokenStream->addAttribute()); - tokenStream->addAttribute(); - tokenStream->reset(); + TokenStreamPtr _tokenStream(tokenStream); + TermAttributePtr termAtt(_tokenStream->addAttribute()); + OffsetAttributePtr offsetAtt(_tokenStream->addAttribute()); + _tokenStream->addAttribute(); + _tokenStream->reset(); TextFragmentPtr currentFrag(newLucene(newText, newText->length(), docFrags.size())); - TokenStreamPtr newStream(fragmentScorer->init(tokenStream)); + TokenStreamPtr newStream(fragmentScorer->init(_tokenStream)); if (newStream) - tokenStream = newStream; + _tokenStream = newStream; fragmentScorer->startFragment(currentFrag); docFrags.add(currentFrag); @@ -113,14 +114,14 @@ namespace Lucene LuceneException finally; try { - textFragmenter->start(text, tokenStream); - TokenGroupPtr tokenGroup(newLucene(tokenStream)); + textFragmenter->start(text, _tokenStream); + TokenGroupPtr tokenGroup(newLucene(_tokenStream)); String tokenText; int32_t startOffset = 0; int32_t endOffset = 0; int32_t lastEndOffset = 0; - for (bool next = tokenStream->incrementToken(); next && offsetAtt->startOffset() < maxDocCharsToAnalyze; next = tokenStream->incrementToken()) + for (bool next = _tokenStream->incrementToken(); next && offsetAtt->startOffset() < maxDocCharsToAnalyze; next = _tokenStream->incrementToken()) { if (offsetAtt->endOffset() > (int32_t)text.length() || offsetAtt->startOffset() > (int32_t)text.length()) boost::throw_exception(RuntimeException(L"InvalidTokenOffsets: Token " + termAtt->term() + L" exceeds length of provided text sized " + StringUtils::toString(text.length()))); @@ -205,11 +206,11 @@ namespace Lucene { finally = e; } - if (tokenStream) + if (_tokenStream) { try { - tokenStream->close(); + _tokenStream->close(); } catch (...) { @@ -286,7 +287,7 @@ namespace Lucene } } - String Highlighter::getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments, const String& separator) + String Highlighter::getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments, const String& separator) { Collection sections(getBestFragments(tokenStream, text, maxNumFragments)); StringStream result; @@ -314,7 +315,7 @@ namespace Lucene return textFragmenter; } - void Highlighter::setTextFragmenter(FragmenterPtr fragmenter) + void Highlighter::setTextFragmenter(const FragmenterPtr& fragmenter) { textFragmenter = fragmenter; } @@ -324,7 +325,7 @@ namespace Lucene return fragmentScorer; } - void Highlighter::setFragmentScorer(HighlighterScorerPtr scorer) + void Highlighter::setFragmentScorer(const HighlighterScorerPtr& scorer) { fragmentScorer = scorer; } @@ -334,7 +335,7 @@ namespace Lucene return encoder; } - void Highlighter::setEncoder(EncoderPtr encoder) + void Highlighter::setEncoder(const EncoderPtr& encoder) { this->encoder = encoder; } diff --git a/src/contrib/highlighter/HighlighterScorer.cpp b/src/contrib/highlighter/HighlighterScorer.cpp index b75b744d..f041435a 100644 --- a/src/contrib/highlighter/HighlighterScorer.cpp +++ b/src/contrib/highlighter/HighlighterScorer.cpp @@ -13,13 +13,13 @@ namespace Lucene { } - TokenStreamPtr HighlighterScorer::init(TokenStreamPtr tokenStream) + TokenStreamPtr HighlighterScorer::init(const TokenStreamPtr& tokenStream) { BOOST_ASSERT(false); return TokenStreamPtr(); // override } - void HighlighterScorer::startFragment(TextFragmentPtr newFragment) + void HighlighterScorer::startFragment(const TextFragmentPtr& newFragment) { BOOST_ASSERT(false); // override diff --git a/src/contrib/highlighter/MapWeightedSpanTerm.cpp b/src/contrib/highlighter/MapWeightedSpanTerm.cpp index a534b1fa..e87a3f08 100644 --- a/src/contrib/highlighter/MapWeightedSpanTerm.cpp +++ b/src/contrib/highlighter/MapWeightedSpanTerm.cpp @@ -28,7 +28,7 @@ namespace Lucene return map.end(); } - void MapWeightedSpanTerm::put(const String& key, WeightedSpanTermPtr val) + void MapWeightedSpanTerm::put(const String& key, const WeightedSpanTermPtr& val) { return map.put(key, val); } diff --git a/src/contrib/highlighter/NullFragmenter.cpp b/src/contrib/highlighter/NullFragmenter.cpp index fb3b779d..7d0399ce 100644 --- a/src/contrib/highlighter/NullFragmenter.cpp +++ b/src/contrib/highlighter/NullFragmenter.cpp @@ -13,7 +13,7 @@ namespace Lucene { } - void NullFragmenter::start(const String& originalText, TokenStreamPtr tokenStream) + void NullFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { } diff --git a/src/contrib/highlighter/QueryScorer.cpp b/src/contrib/highlighter/QueryScorer.cpp index 1a2052dd..0a46ab7b 100644 --- a/src/contrib/highlighter/QueryScorer.cpp +++ b/src/contrib/highlighter/QueryScorer.cpp @@ -15,28 +15,28 @@ namespace Lucene { - QueryScorer::QueryScorer(QueryPtr query) + QueryScorer::QueryScorer(const QueryPtr& query) { init(query, L"", IndexReaderPtr(), true); } - QueryScorer::QueryScorer(QueryPtr query, const String& field) + QueryScorer::QueryScorer(const QueryPtr& query, const String& field) { init(query, field, IndexReaderPtr(), true); } - QueryScorer::QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field) + QueryScorer::QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field) { init(query, field, reader, true); } - QueryScorer::QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field, const String& defaultField) + QueryScorer::QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field, const String& defaultField) { this->defaultField = defaultField; init(query, field, reader, true); } - QueryScorer::QueryScorer(QueryPtr query, const String& field, const String& defaultField) + QueryScorer::QueryScorer(const QueryPtr& query, const String& field, const String& defaultField) { this->defaultField = defaultField; init(query, field, IndexReaderPtr(), true); @@ -64,7 +64,7 @@ namespace Lucene { } - void QueryScorer::init(QueryPtr query, const String& field, IndexReaderPtr reader, bool expandMultiTermQuery) + void QueryScorer::init(const QueryPtr& query, const String& field, const IndexReaderPtr& reader, bool expandMultiTermQuery) { this->totalScore = 0; this->maxTermWeight = 0; @@ -113,7 +113,7 @@ namespace Lucene return score; } - TokenStreamPtr QueryScorer::init(TokenStreamPtr tokenStream) + TokenStreamPtr QueryScorer::init(const TokenStreamPtr& tokenStream) { position = -1; termAtt = tokenStream->addAttribute(); @@ -132,7 +132,7 @@ namespace Lucene return fieldWeightedSpanTerms->get(token); } - TokenStreamPtr QueryScorer::initExtractor(TokenStreamPtr tokenStream) + TokenStreamPtr QueryScorer::initExtractor(const TokenStreamPtr& tokenStream) { WeightedSpanTermExtractorPtr qse(newLucene(defaultField)); @@ -147,7 +147,7 @@ namespace Lucene return TokenStreamPtr(); } - void QueryScorer::startFragment(TextFragmentPtr newFragment) + void QueryScorer::startFragment(const TextFragmentPtr& newFragment) { foundTerms = HashSet::newInstance(); totalScore = 0; diff --git a/src/contrib/highlighter/QueryTermExtractor.cpp b/src/contrib/highlighter/QueryTermExtractor.cpp index c1abfadd..d6cbf241 100644 --- a/src/contrib/highlighter/QueryTermExtractor.cpp +++ b/src/contrib/highlighter/QueryTermExtractor.cpp @@ -20,12 +20,12 @@ namespace Lucene { } - Collection QueryTermExtractor::getTerms(QueryPtr query) + Collection QueryTermExtractor::getTerms(const QueryPtr& query) { return getTerms(query, false); } - Collection QueryTermExtractor::getIdfWeightedTerms(QueryPtr query, IndexReaderPtr reader, const String& fieldName) + Collection QueryTermExtractor::getIdfWeightedTerms(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName) { Collection terms(getTerms(query, false, fieldName)); int32_t totalNumDocs = reader->numDocs(); @@ -49,21 +49,21 @@ namespace Lucene return terms; } - Collection QueryTermExtractor::getTerms(QueryPtr query, bool prohibited, const String& fieldName) + Collection QueryTermExtractor::getTerms(const QueryPtr& query, bool prohibited, const String& fieldName) { SetWeightedTerm terms(SetWeightedTerm::newInstance()); getTerms(query, terms, prohibited, fieldName); return Collection::newInstance(terms.begin(), terms.end()); } - Collection QueryTermExtractor::getTerms(QueryPtr query, bool prohibited) + Collection QueryTermExtractor::getTerms(const QueryPtr& query, bool prohibited) { SetWeightedTerm terms(SetWeightedTerm::newInstance()); getTerms(query, terms, prohibited, L""); return Collection::newInstance(terms.begin(), terms.end()); } - void QueryTermExtractor::getTerms(QueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName) + void QueryTermExtractor::getTerms(const QueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { try { @@ -88,7 +88,7 @@ namespace Lucene } } - void QueryTermExtractor::getTermsFromBooleanQuery(BooleanQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName) + void QueryTermExtractor::getTermsFromBooleanQuery(const BooleanQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { Collection queryClauses(query->getClauses()); for (int32_t i = 0; i < queryClauses.size(); ++i) @@ -98,7 +98,7 @@ namespace Lucene } } - void QueryTermExtractor::getTermsFromFilteredQuery(FilteredQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName) + void QueryTermExtractor::getTermsFromFilteredQuery(const FilteredQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { getTerms(query->getQuery(), terms, prohibited, fieldName); } diff --git a/src/contrib/highlighter/QueryTermScorer.cpp b/src/contrib/highlighter/QueryTermScorer.cpp index adbce4d9..be4efe0e 100644 --- a/src/contrib/highlighter/QueryTermScorer.cpp +++ b/src/contrib/highlighter/QueryTermScorer.cpp @@ -13,17 +13,17 @@ namespace Lucene { - QueryTermScorer::QueryTermScorer(QueryPtr query) + QueryTermScorer::QueryTermScorer(const QueryPtr& query) { ConstructQueryTermScorer(QueryTermExtractor::getTerms(query)); } - QueryTermScorer::QueryTermScorer(QueryPtr query, const String& fieldName) + QueryTermScorer::QueryTermScorer(const QueryPtr& query, const String& fieldName) { ConstructQueryTermScorer(QueryTermExtractor::getTerms(query, false, fieldName)); } - QueryTermScorer::QueryTermScorer(QueryPtr query, IndexReaderPtr reader, const String& fieldName) + QueryTermScorer::QueryTermScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName) { ConstructQueryTermScorer(QueryTermExtractor::getIdfWeightedTerms(query, reader, fieldName)); } @@ -55,13 +55,13 @@ namespace Lucene } } - TokenStreamPtr QueryTermScorer::init(TokenStreamPtr tokenStream) + TokenStreamPtr QueryTermScorer::init(const TokenStreamPtr& tokenStream) { termAtt = tokenStream->addAttribute(); return TokenStreamPtr(); } - void QueryTermScorer::startFragment(TextFragmentPtr newFragment) + void QueryTermScorer::startFragment(const TextFragmentPtr& newFragment) { uniqueTermsInFragment = HashSet::newInstance(); currentTextFragment = newFragment; diff --git a/src/contrib/highlighter/SimpleFragmenter.cpp b/src/contrib/highlighter/SimpleFragmenter.cpp index 768a98fa..2b8d557d 100644 --- a/src/contrib/highlighter/SimpleFragmenter.cpp +++ b/src/contrib/highlighter/SimpleFragmenter.cpp @@ -30,7 +30,7 @@ namespace Lucene { } - void SimpleFragmenter::start(const String& originalText, TokenStreamPtr tokenStream) + void SimpleFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { offsetAtt = tokenStream->addAttribute(); currentNumFrags = 1; diff --git a/src/contrib/highlighter/SimpleHTMLFormatter.cpp b/src/contrib/highlighter/SimpleHTMLFormatter.cpp index 404c9f58..0247d9ca 100644 --- a/src/contrib/highlighter/SimpleHTMLFormatter.cpp +++ b/src/contrib/highlighter/SimpleHTMLFormatter.cpp @@ -29,7 +29,7 @@ namespace Lucene { } - String SimpleHTMLFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) + String SimpleHTMLFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { if (tokenGroup->getTotalScore() == 0) return originalText; diff --git a/src/contrib/highlighter/SimpleSpanFragmenter.cpp b/src/contrib/highlighter/SimpleSpanFragmenter.cpp index 8941d4a4..819cbcab 100644 --- a/src/contrib/highlighter/SimpleSpanFragmenter.cpp +++ b/src/contrib/highlighter/SimpleSpanFragmenter.cpp @@ -18,7 +18,7 @@ namespace Lucene { const int32_t SimpleSpanFragmenter::DEFAULT_FRAGMENT_SIZE = 100; - SimpleSpanFragmenter::SimpleSpanFragmenter(QueryScorerPtr queryScorer) + SimpleSpanFragmenter::SimpleSpanFragmenter(const QueryScorerPtr& queryScorer) { this->currentNumFrags = 0; this->position = -1; @@ -29,7 +29,7 @@ namespace Lucene this->fragmentSize = DEFAULT_FRAGMENT_SIZE; } - SimpleSpanFragmenter::SimpleSpanFragmenter(QueryScorerPtr queryScorer, int32_t fragmentSize) + SimpleSpanFragmenter::SimpleSpanFragmenter(const QueryScorerPtr& queryScorer, int32_t fragmentSize) { this->currentNumFrags = 0; this->position = -1; @@ -77,7 +77,7 @@ namespace Lucene return isNewFrag; } - void SimpleSpanFragmenter::start(const String& originalText, TokenStreamPtr tokenStream) + void SimpleSpanFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { position = -1; currentNumFrags = 1; diff --git a/src/contrib/highlighter/SpanGradientFormatter.cpp b/src/contrib/highlighter/SpanGradientFormatter.cpp index 122145af..0332ec18 100644 --- a/src/contrib/highlighter/SpanGradientFormatter.cpp +++ b/src/contrib/highlighter/SpanGradientFormatter.cpp @@ -19,7 +19,7 @@ namespace Lucene { } - String SpanGradientFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) + String SpanGradientFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { if (tokenGroup->getTotalScore() == 0) return originalText; diff --git a/src/contrib/highlighter/TextFragment.cpp b/src/contrib/highlighter/TextFragment.cpp index e5c2ea29..71ac9ad8 100644 --- a/src/contrib/highlighter/TextFragment.cpp +++ b/src/contrib/highlighter/TextFragment.cpp @@ -9,7 +9,7 @@ namespace Lucene { - TextFragment::TextFragment(StringBufferPtr markedUpText, int32_t textStartPos, int32_t fragNum) + TextFragment::TextFragment(const StringBufferPtr& markedUpText, int32_t textStartPos, int32_t fragNum) { this->markedUpText = markedUpText; this->textStartPos = textStartPos; @@ -32,13 +32,13 @@ namespace Lucene return score; } - void TextFragment::merge(TextFragmentPtr frag2) + void TextFragment::merge(const TextFragmentPtr& frag2) { textEndPos = frag2->textEndPos; score = std::max(score, frag2->score); } - bool TextFragment::follows(TextFragmentPtr fragment) + bool TextFragment::follows(const TextFragmentPtr& fragment) { return (textStartPos == fragment->textEndPos); } diff --git a/src/contrib/highlighter/TokenGroup.cpp b/src/contrib/highlighter/TokenGroup.cpp index 05ff951e..2883d876 100644 --- a/src/contrib/highlighter/TokenGroup.cpp +++ b/src/contrib/highlighter/TokenGroup.cpp @@ -15,7 +15,7 @@ namespace Lucene { const int32_t TokenGroup::MAX_NUM_TOKENS_PER_GROUP = 50; - TokenGroup::TokenGroup(TokenStreamPtr tokenStream) + TokenGroup::TokenGroup(const TokenStreamPtr& tokenStream) { offsetAtt = tokenStream->addAttribute(); termAtt = tokenStream->addAttribute(); diff --git a/src/contrib/highlighter/TokenSources.cpp b/src/contrib/highlighter/TokenSources.cpp index 3772bef8..8facc957 100644 --- a/src/contrib/highlighter/TokenSources.cpp +++ b/src/contrib/highlighter/TokenSources.cpp @@ -25,7 +25,7 @@ namespace Lucene { } - TokenStreamPtr TokenSources::getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, DocumentPtr doc, AnalyzerPtr analyzer) + TokenStreamPtr TokenSources::getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const DocumentPtr& doc, const AnalyzerPtr& analyzer) { TokenStreamPtr ts; TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); @@ -40,7 +40,7 @@ namespace Lucene return ts; } - TokenStreamPtr TokenSources::getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer) + TokenStreamPtr TokenSources::getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer) { TokenStreamPtr ts; TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); @@ -55,7 +55,7 @@ namespace Lucene return ts; } - TokenStreamPtr TokenSources::getTokenStream(TermPositionVectorPtr tpv) + TokenStreamPtr TokenSources::getTokenStream(const TermPositionVectorPtr& tpv) { // assumes the worst and makes no assumptions about token position sequences. return getTokenStream(tpv, false); @@ -71,7 +71,7 @@ namespace Lucene } }; - TokenStreamPtr TokenSources::getTokenStream(TermPositionVectorPtr tpv, bool tokenPositionsGuaranteedContiguous) + TokenStreamPtr TokenSources::getTokenStream(const TermPositionVectorPtr& tpv, bool tokenPositionsGuaranteedContiguous) { // code to reconstruct the original sequence of Tokens Collection terms(tpv->getTerms()); @@ -130,7 +130,7 @@ namespace Lucene return newLucene(tokensInOriginalOrder); } - TokenStreamPtr TokenSources::getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field) + TokenStreamPtr TokenSources::getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field) { TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); if (!tfv) @@ -145,13 +145,13 @@ namespace Lucene return TokenStreamPtr(); } - TokenStreamPtr TokenSources::getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer) + TokenStreamPtr TokenSources::getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer) { DocumentPtr doc(reader->document(docId)); return getTokenStream(doc, field, analyzer); } - TokenStreamPtr TokenSources::getTokenStream(DocumentPtr doc, const String& field, AnalyzerPtr analyzer) + TokenStreamPtr TokenSources::getTokenStream(const DocumentPtr& doc, const String& field, const AnalyzerPtr& analyzer) { String contents(doc->get(field)); if (contents.empty()) @@ -159,7 +159,7 @@ namespace Lucene return getTokenStream(field, contents, analyzer); } - TokenStreamPtr TokenSources::getTokenStream(const String& field, const String& contents, AnalyzerPtr analyzer) + TokenStreamPtr TokenSources::getTokenStream(const String& field, const String& contents, const AnalyzerPtr& analyzer) { return analyzer->tokenStream(field, newLucene(contents)); } diff --git a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp index 3d02b6c9..a4c82231 100644 --- a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp +++ b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp @@ -59,20 +59,21 @@ namespace Lucene } } - void WeightedSpanTermExtractor::extract(QueryPtr query, MapWeightedSpanTermPtr terms) + void WeightedSpanTermExtractor::extract(const QueryPtr& query, const MapWeightedSpanTermPtr& terms) { - if (MiscUtils::typeOf(query)) + QueryPtr _query(query); + if (MiscUtils::typeOf(_query)) { - Collection queryClauses(boost::dynamic_pointer_cast(query)->getClauses()); + Collection queryClauses(boost::dynamic_pointer_cast(_query)->getClauses()); for (int32_t i = 0; i < queryClauses.size(); ++i) { if (!queryClauses[i]->isProhibited()) extract(queryClauses[i]->getQuery(), terms); } } - else if (MiscUtils::typeOf(query)) + else if (MiscUtils::typeOf(_query)) { - PhraseQueryPtr phraseQuery(boost::dynamic_pointer_cast(query)); + PhraseQueryPtr phraseQuery(boost::dynamic_pointer_cast(_query)); Collection phraseQueryTerms(phraseQuery->getTerms()); Collection clauses(Collection::newInstance(phraseQueryTerms.size())); for (int32_t i = 0; i < phraseQueryTerms.size(); ++i) @@ -100,41 +101,41 @@ namespace Lucene bool inorder = (slop == 0); SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); - sp->setBoost(query->getBoost()); + sp->setBoost(_query->getBoost()); extractWeightedSpanTerms(terms, sp); } - else if (MiscUtils::typeOf(query)) - extractWeightedTerms(terms, query); - else if (MiscUtils::typeOf(query)) - extractWeightedSpanTerms(terms, boost::dynamic_pointer_cast(query)); - else if (MiscUtils::typeOf(query)) - extract(boost::dynamic_pointer_cast(query)->getQuery(), terms); - else if (MiscUtils::typeOf(query)) + else if (MiscUtils::typeOf(_query)) + extractWeightedTerms(terms, _query); + else if (MiscUtils::typeOf(_query)) + extractWeightedSpanTerms(terms, boost::dynamic_pointer_cast(_query)); + else if (MiscUtils::typeOf(_query)) + extract(boost::dynamic_pointer_cast(_query)->getQuery(), terms); + else if (MiscUtils::typeOf(_query)) { - DisjunctionMaxQueryPtr dmq(boost::dynamic_pointer_cast(query)); + DisjunctionMaxQueryPtr dmq(boost::dynamic_pointer_cast(_query)); for (Collection::iterator q = dmq->begin(); q != dmq->end(); ++q) extract(*q, terms); } - else if (MiscUtils::typeOf(query) && expandMultiTermQuery) + else if (MiscUtils::typeOf(_query) && expandMultiTermQuery) { - MultiTermQueryPtr mtq(boost::dynamic_pointer_cast(query)); + MultiTermQueryPtr mtq(boost::dynamic_pointer_cast(_query)); if (mtq->getRewriteMethod() != MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()) { mtq = boost::dynamic_pointer_cast(mtq->clone()); mtq->setRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); - query = mtq; + _query = mtq; } FakeReaderPtr fReader(newLucene()); MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()->rewrite(fReader, mtq); if (!fReader->field.empty()) { IndexReaderPtr ir(getReaderForField(fReader->field)); - extract(query->rewrite(ir), terms); + extract(_query->rewrite(ir), terms); } } - else if (MiscUtils::typeOf(query)) + else if (MiscUtils::typeOf(_query)) { - MultiPhraseQueryPtr mpq(boost::dynamic_pointer_cast(query)); + MultiPhraseQueryPtr mpq(boost::dynamic_pointer_cast(_query)); Collection< Collection > termArrays(mpq->getTermArrays()); Collection positions(mpq->getPositions()); if (!positions.empty()) @@ -178,13 +179,13 @@ namespace Lucene bool inorder = (slop == 0); SpanNearQueryPtr sp(newLucene(clauses, slop + positionGaps, inorder)); - sp->setBoost(query->getBoost()); + sp->setBoost(_query->getBoost()); extractWeightedSpanTerms(terms, sp); } } } - void WeightedSpanTermExtractor::extractWeightedSpanTerms(MapWeightedSpanTermPtr terms, SpanQueryPtr spanQuery) + void WeightedSpanTermExtractor::extractWeightedSpanTerms(const MapWeightedSpanTermPtr& terms, const SpanQueryPtr& spanQuery) { HashSet fieldNames(HashSet::newInstance()); if (fieldName.empty()) @@ -254,7 +255,7 @@ namespace Lucene } } - void WeightedSpanTermExtractor::extractWeightedTerms(MapWeightedSpanTermPtr terms, QueryPtr query) + void WeightedSpanTermExtractor::extractWeightedTerms(const MapWeightedSpanTermPtr& terms, const QueryPtr& query) { SetTerm nonWeightedTerms(SetTerm::newInstance()); query->extractTerms(nonWeightedTerms); @@ -294,12 +295,12 @@ namespace Lucene return reader; } - MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream) + MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream) { return getWeightedSpanTerms(query, tokenStream, L""); } - MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName) + MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName) { if (!fieldName.empty()) this->fieldName = fieldName; @@ -323,7 +324,7 @@ namespace Lucene return terms; } - MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTermsWithScores(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName, IndexReaderPtr reader) + MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTermsWithScores(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName, const IndexReaderPtr& reader) { if (!fieldName.empty()) this->fieldName = fieldName; @@ -358,7 +359,7 @@ namespace Lucene return terms; } - void WeightedSpanTermExtractor::collectSpanQueryFields(SpanQueryPtr spanQuery, HashSet fieldNames) + void WeightedSpanTermExtractor::collectSpanQueryFields(const SpanQueryPtr& spanQuery, HashSet fieldNames) { if (MiscUtils::typeOf(spanQuery)) collectSpanQueryFields(boost::dynamic_pointer_cast(spanQuery)->getMaskedQuery(), fieldNames); @@ -382,7 +383,7 @@ namespace Lucene fieldNames.add(spanQuery->getField()); } - bool WeightedSpanTermExtractor::mustRewriteQuery(SpanQueryPtr spanQuery) + bool WeightedSpanTermExtractor::mustRewriteQuery(const SpanQueryPtr& spanQuery) { if (!expandMultiTermQuery) return false; // Will throw UnsupportedOperationException in case of a SpanRegexQuery. @@ -450,7 +451,7 @@ namespace Lucene { } - void PositionCheckingMap::put(const String& key, WeightedSpanTermPtr val) + void PositionCheckingMap::put(const String& key, const WeightedSpanTermPtr& val) { MapStringWeightedSpanTerm::iterator prev = map.find(key); if (prev == map.end()) @@ -483,7 +484,7 @@ namespace Lucene return _EMPTY_MEMORY_INDEX_READER; } - TermEnumPtr FakeReader::terms(TermPtr t) + TermEnumPtr FakeReader::terms(const TermPtr& t) { // only set first fieldname if (t && field.empty()) diff --git a/src/contrib/include/ArabicAnalyzer.h b/src/contrib/include/ArabicAnalyzer.h index bab47b4e..3d299750 100644 --- a/src/contrib/include/ArabicAnalyzer.h +++ b/src/contrib/include/ArabicAnalyzer.h @@ -60,7 +60,7 @@ namespace Lucene /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and /// {@link ArabicStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. @@ -68,7 +68,7 @@ namespace Lucene /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and /// {@link ArabicStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI ArabicAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/ArabicLetterTokenizer.h b/src/contrib/include/ArabicLetterTokenizer.h index 214937b3..b97831e3 100644 --- a/src/contrib/include/ArabicLetterTokenizer.h +++ b/src/contrib/include/ArabicLetterTokenizer.h @@ -21,13 +21,13 @@ namespace Lucene { public: /// Construct a new ArabicLetterTokenizer. - ArabicLetterTokenizer(ReaderPtr input); + ArabicLetterTokenizer(const ReaderPtr& input); /// Construct a new ArabicLetterTokenizer using a given {@link AttributeSource}. - ArabicLetterTokenizer(AttributeSourcePtr source, ReaderPtr input); + ArabicLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); /// Construct a new ArabicLetterTokenizer using a given {@link AttributeFactory}. - ArabicLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + ArabicLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~ArabicLetterTokenizer(); diff --git a/src/contrib/include/ArabicNormalizationFilter.h b/src/contrib/include/ArabicNormalizationFilter.h index 5f63bbec..4844a20c 100644 --- a/src/contrib/include/ArabicNormalizationFilter.h +++ b/src/contrib/include/ArabicNormalizationFilter.h @@ -16,7 +16,7 @@ namespace Lucene class LPPCONTRIBAPI ArabicNormalizationFilter : public TokenFilter { public: - ArabicNormalizationFilter(TokenStreamPtr input); + ArabicNormalizationFilter(const TokenStreamPtr& input); virtual ~ArabicNormalizationFilter(); LUCENE_CLASS(ArabicNormalizationFilter); diff --git a/src/contrib/include/ArabicStemFilter.h b/src/contrib/include/ArabicStemFilter.h index c46d7e95..de31dc9d 100644 --- a/src/contrib/include/ArabicStemFilter.h +++ b/src/contrib/include/ArabicStemFilter.h @@ -16,7 +16,7 @@ namespace Lucene class LPPCONTRIBAPI ArabicStemFilter : public TokenFilter { public: - ArabicStemFilter(TokenStreamPtr input); + ArabicStemFilter(const TokenStreamPtr& input); virtual ~ArabicStemFilter(); LUCENE_CLASS(ArabicStemFilter); diff --git a/src/contrib/include/BrazilianAnalyzer.h b/src/contrib/include/BrazilianAnalyzer.h index d8e13080..17addfb6 100644 --- a/src/contrib/include/BrazilianAnalyzer.h +++ b/src/contrib/include/BrazilianAnalyzer.h @@ -56,7 +56,7 @@ namespace Lucene /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link BrazilianStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. @@ -64,7 +64,7 @@ namespace Lucene /// @return A {@link TokenStream} built from an {@link BrazilianLetterTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StopFilter}, {@link BrazilianNormalizationFilter} and /// {@link BrazilianStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI BrazilianAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/BrazilianStemFilter.h b/src/contrib/include/BrazilianStemFilter.h index 73b928ff..24d6fe5d 100644 --- a/src/contrib/include/BrazilianStemFilter.h +++ b/src/contrib/include/BrazilianStemFilter.h @@ -16,8 +16,8 @@ namespace Lucene class LPPCONTRIBAPI BrazilianStemFilter : public TokenFilter { public: - BrazilianStemFilter(TokenStreamPtr input); - BrazilianStemFilter(TokenStreamPtr input, HashSet exclusiontable); + BrazilianStemFilter(const TokenStreamPtr& input); + BrazilianStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); virtual ~BrazilianStemFilter(); diff --git a/src/contrib/include/CJKAnalyzer.h b/src/contrib/include/CJKAnalyzer.h index 2d0395e9..81e368f2 100644 --- a/src/contrib/include/CJKAnalyzer.h +++ b/src/contrib/include/CJKAnalyzer.h @@ -42,13 +42,13 @@ namespace Lucene /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI CJKAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/CJKTokenizer.h b/src/contrib/include/CJKTokenizer.h index d75366e0..e7103483 100644 --- a/src/contrib/include/CJKTokenizer.h +++ b/src/contrib/include/CJKTokenizer.h @@ -28,9 +28,9 @@ namespace Lucene class LPPCONTRIBAPI CJKTokenizer : public Tokenizer { public: - CJKTokenizer(ReaderPtr input); - CJKTokenizer(AttributeSourcePtr source, ReaderPtr input); - CJKTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + CJKTokenizer(const ReaderPtr& input); + CJKTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + CJKTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~CJKTokenizer(); @@ -94,7 +94,7 @@ namespace Lucene virtual bool incrementToken(); virtual void end(); virtual void reset(); - virtual void reset(ReaderPtr input); + virtual void reset(const ReaderPtr& input); }; } diff --git a/src/contrib/include/ChineseAnalyzer.h b/src/contrib/include/ChineseAnalyzer.h index bf489bea..0de01e2b 100644 --- a/src/contrib/include/ChineseAnalyzer.h +++ b/src/contrib/include/ChineseAnalyzer.h @@ -24,13 +24,13 @@ namespace Lucene /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI ChineseAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/ChineseFilter.h b/src/contrib/include/ChineseFilter.h index 5b691a84..fd9d2d27 100644 --- a/src/contrib/include/ChineseFilter.h +++ b/src/contrib/include/ChineseFilter.h @@ -21,7 +21,7 @@ namespace Lucene class LPPCONTRIBAPI ChineseFilter : public TokenFilter { public: - ChineseFilter(TokenStreamPtr input); + ChineseFilter(const TokenStreamPtr& input); virtual ~ChineseFilter(); LUCENE_CLASS(ChineseFilter); diff --git a/src/contrib/include/ChineseTokenizer.h b/src/contrib/include/ChineseTokenizer.h index 53552e26..3ff325d9 100644 --- a/src/contrib/include/ChineseTokenizer.h +++ b/src/contrib/include/ChineseTokenizer.h @@ -29,9 +29,9 @@ namespace Lucene class LPPCONTRIBAPI ChineseTokenizer : public Tokenizer { public: - ChineseTokenizer(ReaderPtr input); - ChineseTokenizer(AttributeSourcePtr source, ReaderPtr input); - ChineseTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + ChineseTokenizer(const ReaderPtr& input); + ChineseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + ChineseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~ChineseTokenizer(); @@ -70,7 +70,7 @@ namespace Lucene virtual bool incrementToken(); virtual void end(); virtual void reset(); - virtual void reset(ReaderPtr input); + virtual void reset(const ReaderPtr& input); protected: void push(wchar_t c); diff --git a/src/contrib/include/CzechAnalyzer.h b/src/contrib/include/CzechAnalyzer.h index cc42cfdf..b29689ad 100644 --- a/src/contrib/include/CzechAnalyzer.h +++ b/src/contrib/include/CzechAnalyzer.h @@ -48,14 +48,14 @@ namespace Lucene /// /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, /// {@link LowerCaseFilter}, and {@link StopFilter} - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, /// {@link LowerCaseFilter}, and {@link StopFilter} - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI CzechAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/DutchAnalyzer.h b/src/contrib/include/DutchAnalyzer.h index 22e804bc..5b34ebe2 100644 --- a/src/contrib/include/DutchAnalyzer.h +++ b/src/contrib/include/DutchAnalyzer.h @@ -61,14 +61,14 @@ namespace Lucene /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI DutchAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/DutchStemFilter.h b/src/contrib/include/DutchStemFilter.h index 02796cec..340bd377 100644 --- a/src/contrib/include/DutchStemFilter.h +++ b/src/contrib/include/DutchStemFilter.h @@ -24,14 +24,14 @@ namespace Lucene class LPPCONTRIBAPI DutchStemFilter : public TokenFilter { public: - DutchStemFilter(TokenStreamPtr input); + DutchStemFilter(const TokenStreamPtr& input); /// Builds a DutchStemFilter that uses an exclusion table. - DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable); + DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); /// Builds a DutchStemFilter that uses an exclusion table and dictionary of word stem /// pairs, that overrule the algorithm. - DutchStemFilter(TokenStreamPtr input, HashSet exclusiontable, MapStringString stemdictionary); + DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable, MapStringString stemdictionary); virtual ~DutchStemFilter(); @@ -48,7 +48,7 @@ namespace Lucene virtual bool incrementToken(); /// Set a alternative/custom {@link DutchStemmer} for this filter. - void setStemmer(DutchStemmerPtr stemmer); + void setStemmer(const DutchStemmerPtr& stemmer); /// Set an alternative exclusion list for this filter. void setExclusionSet(HashSet exclusiontable); diff --git a/src/contrib/include/ElisionFilter.h b/src/contrib/include/ElisionFilter.h index aa084fc6..14cd5114 100644 --- a/src/contrib/include/ElisionFilter.h +++ b/src/contrib/include/ElisionFilter.h @@ -21,10 +21,10 @@ namespace Lucene { public: /// Constructs an elision filter with standard stop words. - ElisionFilter(TokenStreamPtr input); + ElisionFilter(const TokenStreamPtr& input); /// Constructs an elision filter with a Set of stop words - ElisionFilter(TokenStreamPtr input, HashSet articles); + ElisionFilter(const TokenStreamPtr& input, HashSet articles); virtual ~ElisionFilter(); diff --git a/src/contrib/include/Formatter.h b/src/contrib/include/Formatter.h index b5c478c0..287cc9d7 100644 --- a/src/contrib/include/Formatter.h +++ b/src/contrib/include/Formatter.h @@ -23,7 +23,7 @@ namespace Lucene public: /// @param originalText The section of text being considered for markup /// @param tokenGroup contains one or several overlapping Tokens along with their scores and positions. - virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); }; } diff --git a/src/contrib/include/Fragmenter.h b/src/contrib/include/Fragmenter.h index c6532cce..0d1601fa 100644 --- a/src/contrib/include/Fragmenter.h +++ b/src/contrib/include/Fragmenter.h @@ -26,7 +26,7 @@ namespace Lucene /// interested in from tokenStream and then access the values in {@link #isNewFragment()}. /// @param originalText the original source text. /// @param tokenStream the {@link TokenStream} to be fragmented. - virtual void start(const String& originalText, TokenStreamPtr tokenStream); + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); /// Test to see if this token from the stream should be held in a new TextFragment. /// Every time this is called, the TokenStream passed to start(String, TokenStream) diff --git a/src/contrib/include/FrenchAnalyzer.h b/src/contrib/include/FrenchAnalyzer.h index 4c07da27..7fd49cb9 100644 --- a/src/contrib/include/FrenchAnalyzer.h +++ b/src/contrib/include/FrenchAnalyzer.h @@ -57,14 +57,14 @@ namespace Lucene /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter}, and {@link LowerCaseFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link StandardTokenizer} filtered with /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter} and {@link LowerCaseFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI FrenchAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/FrenchStemFilter.h b/src/contrib/include/FrenchStemFilter.h index 7e333ac3..e3a4b1a2 100644 --- a/src/contrib/include/FrenchStemFilter.h +++ b/src/contrib/include/FrenchStemFilter.h @@ -24,10 +24,10 @@ namespace Lucene class LPPCONTRIBAPI FrenchStemFilter : public TokenFilter { public: - FrenchStemFilter(TokenStreamPtr input); + FrenchStemFilter(const TokenStreamPtr& input); /// Builds a FrenchStemFilter that uses an exclusion table. - FrenchStemFilter(TokenStreamPtr input, HashSet exclusiontable); + FrenchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); virtual ~FrenchStemFilter(); @@ -44,7 +44,7 @@ namespace Lucene virtual bool incrementToken(); /// Set a alternative/custom {@link FrenchStemmer} for this filter. - void setStemmer(FrenchStemmerPtr stemmer); + void setStemmer(const FrenchStemmerPtr& stemmer); /// Set an alternative exclusion list for this filter. void setExclusionSet(HashSet exclusiontable); diff --git a/src/contrib/include/GermanAnalyzer.h b/src/contrib/include/GermanAnalyzer.h index a460a917..b18ce4e5 100644 --- a/src/contrib/include/GermanAnalyzer.h +++ b/src/contrib/include/GermanAnalyzer.h @@ -57,7 +57,7 @@ namespace Lucene /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link GermanStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. @@ -65,7 +65,7 @@ namespace Lucene /// @return A {@link TokenStream} built from an {@link GermanLetterTokenizer} filtered with /// {@link LowerCaseFilter}, {@link StopFilter}, {@link GermanNormalizationFilter} and /// {@link GermanStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI GermanAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/GermanStemFilter.h b/src/contrib/include/GermanStemFilter.h index 6241d465..7993b404 100644 --- a/src/contrib/include/GermanStemFilter.h +++ b/src/contrib/include/GermanStemFilter.h @@ -20,10 +20,10 @@ namespace Lucene class LPPCONTRIBAPI GermanStemFilter : public TokenFilter { public: - GermanStemFilter(TokenStreamPtr input); + GermanStemFilter(const TokenStreamPtr& input); /// Builds a GermanStemFilter that uses an exclusion table. - GermanStemFilter(TokenStreamPtr input, HashSet exclusionSet); + GermanStemFilter(const TokenStreamPtr& input, HashSet exclusionSet); virtual ~GermanStemFilter(); @@ -40,7 +40,7 @@ namespace Lucene virtual bool incrementToken(); /// Set a alternative/custom {@link GermanStemmer} for this filter. - void setStemmer(GermanStemmerPtr stemmer); + void setStemmer(const GermanStemmerPtr& stemmer); /// Set an alternative exclusion list for this filter. void setExclusionSet(HashSet exclusionSet); diff --git a/src/contrib/include/GradientFormatter.h b/src/contrib/include/GradientFormatter.h index d3790089..28b7085b 100644 --- a/src/contrib/include/GradientFormatter.h +++ b/src/contrib/include/GradientFormatter.h @@ -43,7 +43,7 @@ namespace Lucene int32_t bgBMax; public: - virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); protected: String getForegroundColorString(double score); diff --git a/src/contrib/include/GreekAnalyzer.h b/src/contrib/include/GreekAnalyzer.h index 4f0d300c..13d194a3 100644 --- a/src/contrib/include/GreekAnalyzer.h +++ b/src/contrib/include/GreekAnalyzer.h @@ -48,14 +48,14 @@ namespace Lucene /// /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with /// {@link GreekLowerCaseFilter} and {@link StopFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from an {@link GreekLetterTokenizer} filtered with /// {@link GreekLowerCaseFilter} and {@link StopFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI GreekAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/GreekLowerCaseFilter.h b/src/contrib/include/GreekLowerCaseFilter.h index 3409d96c..fec2b2de 100644 --- a/src/contrib/include/GreekLowerCaseFilter.h +++ b/src/contrib/include/GreekLowerCaseFilter.h @@ -17,7 +17,7 @@ namespace Lucene class LPPCONTRIBAPI GreekLowerCaseFilter : public TokenFilter { public: - GreekLowerCaseFilter(TokenStreamPtr input); + GreekLowerCaseFilter(const TokenStreamPtr& input); virtual ~GreekLowerCaseFilter(); LUCENE_CLASS(GreekLowerCaseFilter); diff --git a/src/contrib/include/Highlighter.h b/src/contrib/include/Highlighter.h index cc9780cb..15fecdf5 100644 --- a/src/contrib/include/Highlighter.h +++ b/src/contrib/include/Highlighter.h @@ -17,9 +17,9 @@ namespace Lucene class LPPCONTRIBAPI Highlighter : public LuceneObject { public: - Highlighter(HighlighterScorerPtr fragmentScorer); - Highlighter(FormatterPtr formatter, HighlighterScorerPtr fragmentScorer); - Highlighter(FormatterPtr formatter, EncoderPtr encoder, HighlighterScorerPtr fragmentScorer); + Highlighter(const HighlighterScorerPtr& fragmentScorer); + Highlighter(const FormatterPtr& formatter, const HighlighterScorerPtr& fragmentScorer); + Highlighter(const FormatterPtr& formatter, const EncoderPtr& encoder, const HighlighterScorerPtr& fragmentScorer); virtual ~Highlighter(); @@ -43,7 +43,7 @@ namespace Lucene /// @param text Text to highlight terms in /// @param fieldName Name of field used to influence analyzer's tokenization policy /// @return highlighted text fragment or null if no terms found - String getBestFragment(AnalyzerPtr analyzer, const String& fieldName, const String& text); + String getBestFragment(const AnalyzerPtr& analyzer, const String& fieldName, const String& text); /// Highlights chosen terms in a text, extracting the most relevant section. The document text is /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the @@ -55,7 +55,7 @@ namespace Lucene /// original text position data in the Lucene index but this support is not currently available. /// @param text Text to highlight terms in /// @return highlighted text fragment or null if no terms found - String getBestFragment(TokenStreamPtr tokenStream, const String& text); + String getBestFragment(const TokenStreamPtr& tokenStream, const String& text); /// Highlights chosen terms in a text, extracting the most relevant sections. This is a convenience /// method that calls {@link #getBestFragments(TokenStreamPtr, const String&, int32_t)} @@ -65,7 +65,7 @@ namespace Lucene /// @param text Text to highlight terms in /// @param maxNumFragments The maximum number of fragments. /// @return highlighted text fragments (between 0 and maxNumFragments number of fragments) - Collection getBestFragments(AnalyzerPtr analyzer, const String& fieldName, const String& text, int32_t maxNumFragments); + Collection getBestFragments(const AnalyzerPtr& analyzer, const String& fieldName, const String& text, int32_t maxNumFragments); /// Highlights chosen terms in a text, extracting the most relevant sections. The document text is /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the @@ -75,11 +75,11 @@ namespace Lucene /// @param text Text to highlight terms in /// @param maxNumFragments The maximum number of fragments. /// @return highlighted Text fragments (between 0 and maxNumFragments number of fragments) - Collection getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments); + Collection getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments); /// Low level api to get the most relevant (formatted) sections of the document. /// This method has been made public to allow visibility of score information held in TextFragment objects. - Collection getBestTextFragments(TokenStreamPtr tokenStream, const String& text, bool merge, int32_t maxNumFragments); + Collection getBestTextFragments(const TokenStreamPtr& tokenStream, const String& text, bool merge, int32_t maxNumFragments); /// Improves readability of a score-sorted list of TextFragments by merging any fragments that were /// contiguous in the original text into one larger fragment with the correct order. This will leave @@ -97,20 +97,20 @@ namespace Lucene /// @param maxNumFragments The maximum number of fragments. /// @param separator The separator used to intersperse the document fragments (typically "...") /// @return highlighted text - String getBestFragments(TokenStreamPtr tokenStream, const String& text, int32_t maxNumFragments, const String& separator); + String getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments, const String& separator); int32_t getMaxDocCharsToAnalyze(); void setMaxDocCharsToAnalyze(int32_t maxDocCharsToAnalyze); FragmenterPtr getTextFragmenter(); - void setTextFragmenter(FragmenterPtr fragmenter); + void setTextFragmenter(const FragmenterPtr& fragmenter); /// @return Object used to score each text fragment HighlighterScorerPtr getFragmentScorer(); - void setFragmentScorer(HighlighterScorerPtr scorer); + void setFragmentScorer(const HighlighterScorerPtr& scorer); EncoderPtr getEncoder(); - void setEncoder(EncoderPtr encoder); + void setEncoder(const EncoderPtr& encoder); }; class LPPCONTRIBAPI FragmentQueue : public PriorityQueue diff --git a/src/contrib/include/HighlighterScorer.h b/src/contrib/include/HighlighterScorer.h index cd0d3a8f..9273ef7e 100644 --- a/src/contrib/include/HighlighterScorer.h +++ b/src/contrib/include/HighlighterScorer.h @@ -28,12 +28,12 @@ namespace Lucene /// @return either a {@link TokenStream} that the Highlighter should continue using (eg /// if you read the tokenSream in this method) or null to continue using the same {@link /// TokenStream} that was passed in. - virtual TokenStreamPtr init(TokenStreamPtr tokenStream); + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); /// Called when a new fragment is started for consideration. /// /// @param newFragment the fragment that will be scored next - virtual void startFragment(TextFragmentPtr newFragment); + virtual void startFragment(const TextFragmentPtr& newFragment); /// Called for each token in the current fragment. The {@link Highlighter} will increment /// the {@link TokenStream} passed to init on every call. diff --git a/src/contrib/include/MapWeightedSpanTerm.h b/src/contrib/include/MapWeightedSpanTerm.h index 190283fe..3f7277a8 100644 --- a/src/contrib/include/MapWeightedSpanTerm.h +++ b/src/contrib/include/MapWeightedSpanTerm.h @@ -27,7 +27,7 @@ namespace Lucene public: virtual MapStringWeightedSpanTerm::iterator begin(); virtual MapStringWeightedSpanTerm::iterator end(); - virtual void put(const String& key, WeightedSpanTermPtr val); + virtual void put(const String& key, const WeightedSpanTermPtr& val); virtual WeightedSpanTermPtr get(const String& key) const; virtual void clear(); }; diff --git a/src/contrib/include/MemoryIndex.h b/src/contrib/include/MemoryIndex.h index e8536295..3423ff40 100644 --- a/src/contrib/include/MemoryIndex.h +++ b/src/contrib/include/MemoryIndex.h @@ -31,7 +31,7 @@ namespace Lucene /// /// For example as in ///
      -    /// double score = search(const String& text, QueryPtr query)
      +    /// double score = search(const String& text, const QueryPtr& query)
           /// 
      /// /// Each instance can hold at most one Lucene "document", with a document containing zero or more @@ -121,7 +121,7 @@ namespace Lucene /// @param fieldName A name to be associated with the text /// @param text The text to tokenize and index. /// @param analyzer The analyzer to use for tokenization - void addField(const String& fieldName, const String& text, AnalyzerPtr analyzer); + void addField(const String& fieldName, const String& text, const AnalyzerPtr& analyzer); /// Iterates over the given token stream and adds the resulting terms to the index; /// Equivalent to adding a tokenized, indexed, termVectorStored, unstored, Lucene {@link @@ -132,7 +132,7 @@ namespace Lucene /// @param stream The token stream to retrieve tokens from. /// @param boost The boost factor for hits for this field. /// @see Field#setBoost(double) - void addField(const String& fieldName, TokenStreamPtr stream, double boost = 1.0); + void addField(const String& fieldName, const TokenStreamPtr& stream, double boost = 1.0); /// Creates and returns a searcher that can be used to execute arbitrary Lucene queries /// and to collect the resulting query results as hits. @@ -144,7 +144,7 @@ namespace Lucene /// @param query An arbitrary Lucene query to run against this index /// @return the relevance score of the matchmaking; A number in the range [0.0 .. 1.0], /// with 0.0 indicating no match. The higher the number the better the match. - double search(QueryPtr query); + double search(const QueryPtr& query); protected: int32_t numPositions(Collection positions); @@ -211,7 +211,7 @@ namespace Lucene class LPPCONTRIBAPI MemoryIndexReader : public IndexReader { public: - MemoryIndexReader(MemoryIndexPtr memoryIndex); + MemoryIndexReader(const MemoryIndexPtr& memoryIndex); virtual ~MemoryIndexReader(); LUCENE_CLASS(MemoryIndexReader); @@ -233,17 +233,17 @@ namespace Lucene MemoryIndexInfoPtr getInfo(int32_t pos); SimilarityPtr getSimilarity(); - void setSearcher(SearcherPtr searcher); + void setSearcher(const SearcherPtr& searcher); public: - virtual int32_t docFreq(TermPtr t); + virtual int32_t docFreq(const TermPtr& t); virtual TermEnumPtr terms(); - virtual TermEnumPtr terms(TermPtr t); + virtual TermEnumPtr terms(const TermPtr& t); virtual TermPositionsPtr termPositions(); virtual TermDocsPtr termDocs(); virtual Collection getTermFreqVectors(int32_t docNumber); - virtual void getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper); - virtual void getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); virtual ByteArray norms(const String& field); virtual void norms(const String& field, ByteArray norms, int32_t offset); @@ -251,7 +251,7 @@ namespace Lucene virtual int32_t numDocs(); virtual int32_t maxDoc(); virtual DocumentPtr document(int32_t n); - virtual DocumentPtr document(int32_t n, FieldSelectorPtr fieldSelector); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); virtual bool isDeleted(int32_t n); virtual bool hasDeletions(); virtual void doDelete(int32_t docNum); @@ -269,7 +269,7 @@ namespace Lucene class LPPCONTRIBAPI MemoryIndexTermEnum : public TermEnum { public: - MemoryIndexTermEnum(MemoryIndexReaderPtr reader, int32_t ix, int32_t jx); + MemoryIndexTermEnum(const MemoryIndexReaderPtr& reader, int32_t ix, int32_t jx); virtual ~MemoryIndexTermEnum(); LUCENE_CLASS(MemoryIndexTermEnum); @@ -286,7 +286,7 @@ namespace Lucene virtual void close(); protected: - TermPtr createTerm(MemoryIndexInfoPtr info, int32_t pos, const String& text); + TermPtr createTerm(const MemoryIndexInfoPtr& info, int32_t pos, const String& text); }; class LPPCONTRIBAPI MemoryIndexCollector : public Collector @@ -303,15 +303,15 @@ namespace Lucene public: virtual void collect(int32_t doc); - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); virtual bool acceptsDocsOutOfOrder(); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); }; class LPPCONTRIBAPI MemoryIndexTermPositions : public TermPositions, public LuceneObject { public: - MemoryIndexTermPositions(MemoryIndexReaderPtr reader); + MemoryIndexTermPositions(const MemoryIndexReaderPtr& reader); virtual ~MemoryIndexTermPositions(); LUCENE_CLASS(MemoryIndexTermPositions); @@ -324,8 +324,8 @@ namespace Lucene TermPtr term; public: - virtual void seek(TermPtr term); - virtual void seek(TermEnumPtr termEnum); + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); virtual int32_t doc(); virtual int32_t freq(); virtual bool next(); @@ -342,7 +342,7 @@ namespace Lucene class MemoryIndexTermPositionVector : public TermPositionVector, public LuceneObject { public: - MemoryIndexTermPositionVector(MemoryIndexReaderPtr reader, MemoryIndexInfoPtr info, const String& fieldName); + MemoryIndexTermPositionVector(const MemoryIndexReaderPtr& reader, const MemoryIndexInfoPtr& info, const String& fieldName); virtual ~MemoryIndexTermPositionVector(); LUCENE_CLASS(MemoryIndexTermPositionVector); diff --git a/src/contrib/include/NullFragmenter.h b/src/contrib/include/NullFragmenter.h index 7dd7d65c..6b73d42d 100644 --- a/src/contrib/include/NullFragmenter.h +++ b/src/contrib/include/NullFragmenter.h @@ -20,7 +20,7 @@ namespace Lucene LUCENE_CLASS(NullFragmenter); public: - virtual void start(const String& originalText, TokenStreamPtr tokenStream); + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); virtual bool isNewFragment(); }; } diff --git a/src/contrib/include/PersianAnalyzer.h b/src/contrib/include/PersianAnalyzer.h index 83e05946..f3632ba8 100644 --- a/src/contrib/include/PersianAnalyzer.h +++ b/src/contrib/include/PersianAnalyzer.h @@ -53,7 +53,7 @@ namespace Lucene /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} /// and Persian Stop words. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. @@ -61,7 +61,7 @@ namespace Lucene /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} /// and Persian Stop words. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI PersianAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/PersianNormalizationFilter.h b/src/contrib/include/PersianNormalizationFilter.h index 3300887b..6b68c908 100644 --- a/src/contrib/include/PersianNormalizationFilter.h +++ b/src/contrib/include/PersianNormalizationFilter.h @@ -16,7 +16,7 @@ namespace Lucene class LPPCONTRIBAPI PersianNormalizationFilter : public TokenFilter { public: - PersianNormalizationFilter(TokenStreamPtr input); + PersianNormalizationFilter(const TokenStreamPtr& input); virtual ~PersianNormalizationFilter(); LUCENE_CLASS(PersianNormalizationFilter); diff --git a/src/contrib/include/QueryScorer.h b/src/contrib/include/QueryScorer.h index 442c0073..cf9f531c 100644 --- a/src/contrib/include/QueryScorer.h +++ b/src/contrib/include/QueryScorer.h @@ -19,27 +19,27 @@ namespace Lucene { public: /// @param query Query to use for highlighting - QueryScorer(QueryPtr query); + QueryScorer(const QueryPtr& query); /// @param query Query to use for highlighting /// @param field Field to highlight - pass empty string to ignore fields - QueryScorer(QueryPtr query, const String& field); + QueryScorer(const QueryPtr& query, const String& field); /// @param query Query to use for highlighting /// @param reader {@link IndexReader} to use for quasi tf/idf scoring /// @param field Field to highlight - pass empty string to ignore fields - QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field); + QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field); /// @param query Query to use for highlighting /// @param reader {@link IndexReader} to use for quasi tf/idf scoring /// @param field Field to highlight - pass empty string to ignore fields /// @param defaultField - QueryScorer(QueryPtr query, IndexReaderPtr reader, const String& field, const String& defaultField); + QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field, const String& defaultField); /// @param query Query to use for highlighting /// @param field Field to highlight - pass empty string to ignore fields /// @param defaultField - QueryScorer(QueryPtr query, const String& field, const String& defaultField); + QueryScorer(const QueryPtr& query, const String& field, const String& defaultField); /// @param weightedTerms an array of pre-created {@link WeightedSpanTerm}s QueryScorer(Collection weightedTerms); @@ -65,8 +65,8 @@ namespace Lucene bool wrapToCaching; protected: - void init(QueryPtr query, const String& field, IndexReaderPtr reader, bool expandMultiTermQuery); - TokenStreamPtr initExtractor(TokenStreamPtr tokenStream); + void init(const QueryPtr& query, const String& field, const IndexReaderPtr& reader, bool expandMultiTermQuery); + TokenStreamPtr initExtractor(const TokenStreamPtr& tokenStream); public: virtual double getFragmentScore(); @@ -75,9 +75,9 @@ namespace Lucene virtual double getMaxTermWeight(); virtual double getTokenScore(); - virtual TokenStreamPtr init(TokenStreamPtr tokenStream); + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); virtual WeightedSpanTermPtr getWeightedSpanTerm(const String& token); - virtual void startFragment(TextFragmentPtr newFragment); + virtual void startFragment(const TextFragmentPtr& newFragment); /// @return true if multi-term queries should be expanded virtual bool isExpandMultiTermQuery(); diff --git a/src/contrib/include/QueryTermExtractor.h b/src/contrib/include/QueryTermExtractor.h index c298ff0a..18b5a3dd 100644 --- a/src/contrib/include/QueryTermExtractor.h +++ b/src/contrib/include/QueryTermExtractor.h @@ -26,7 +26,7 @@ namespace Lucene /// /// @param query Query to extract term texts from. /// @return an array of the terms used in a query, plus their weights. - static Collection getTerms(QueryPtr query); + static Collection getTerms(const QueryPtr& query); /// Extracts all terms texts of a given Query into an array of WeightedTerms /// @@ -36,7 +36,7 @@ namespace Lucene /// b) use graded highlights eg changing intensity of font color /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based. /// @return an array of the terms used in a query, plus their weights. - static Collection getIdfWeightedTerms(QueryPtr query, IndexReaderPtr reader, const String& fieldName); + static Collection getIdfWeightedTerms(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName); /// Extracts all terms texts of a given Query into an array of WeightedTerms /// @@ -44,24 +44,24 @@ namespace Lucene /// @param prohibited true to extract "prohibited" terms, too. /// @param fieldName The fieldName used to filter query terms. /// @return an array of the terms used in a query, plus their weights. - static Collection getTerms(QueryPtr query, bool prohibited, const String& fieldName); + static Collection getTerms(const QueryPtr& query, bool prohibited, const String& fieldName); /// Extracts all terms texts of a given Query into an array of WeightedTerms /// /// @param query Query to extract term texts from. /// @param prohibited true to extract "prohibited" terms, too. /// @return an array of the terms used in a query, plus their weights. - static Collection getTerms(QueryPtr query, bool prohibited); + static Collection getTerms(const QueryPtr& query, bool prohibited); - static void getTerms(QueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName); + static void getTerms(const QueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); protected: /// extractTerms is currently the only query-independent means of introspecting queries but it only reveals /// a list of terms for that query - not the boosts each individual term in that query may or may not have. /// "Container" queries such as BooleanQuery should be unwrapped to get at the boost info held in each child /// element. - static void getTermsFromBooleanQuery(BooleanQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName); - static void getTermsFromFilteredQuery(FilteredQueryPtr query, SetWeightedTerm terms, bool prohibited, const String& fieldName); + static void getTermsFromBooleanQuery(const BooleanQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); + static void getTermsFromFilteredQuery(const FilteredQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); }; } diff --git a/src/contrib/include/QueryTermScorer.h b/src/contrib/include/QueryTermScorer.h index a56a143a..d73d6e27 100644 --- a/src/contrib/include/QueryTermScorer.h +++ b/src/contrib/include/QueryTermScorer.h @@ -20,12 +20,12 @@ namespace Lucene public: /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class /// and the searcher) - QueryTermScorer(QueryPtr query); + QueryTermScorer(const QueryPtr& query); /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class /// and the searcher) /// @param fieldName the Field name which is used to match Query terms - QueryTermScorer(QueryPtr query, const String& fieldName); + QueryTermScorer(const QueryPtr& query, const String& fieldName); /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class /// and the searcher) @@ -33,7 +33,7 @@ namespace Lucene /// a) score selected fragments better /// b) use graded highlights eg set font color intensity /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based - QueryTermScorer(QueryPtr query, IndexReaderPtr reader, const String& fieldName); + QueryTermScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName); /// @param weightedTerms an array of pre-created {@link WeightedTerm}s QueryTermScorer(Collection weightedTerms); @@ -57,8 +57,8 @@ namespace Lucene void ConstructQueryTermScorer(Collection weightedTerms); public: - virtual TokenStreamPtr init(TokenStreamPtr tokenStream); - virtual void startFragment(TextFragmentPtr newFragment); + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); + virtual void startFragment(const TextFragmentPtr& newFragment); virtual double getTokenScore(); virtual double getFragmentScore(); virtual void allFragmentsProcessed(); diff --git a/src/contrib/include/ReverseStringFilter.h b/src/contrib/include/ReverseStringFilter.h index 33de5fed..ba0c6b54 100644 --- a/src/contrib/include/ReverseStringFilter.h +++ b/src/contrib/include/ReverseStringFilter.h @@ -22,13 +22,13 @@ namespace Lucene /// Create a new ReverseStringFilter that reverses all tokens in the supplied {@link TokenStream}. /// /// The reversed tokens will not be marked. - ReverseStringFilter(TokenStreamPtr input); + ReverseStringFilter(const TokenStreamPtr& input); /// Create a new ReverseStringFilter that reverses and marks all tokens in the supplied {@link /// TokenStream}. /// /// The reversed tokens will be prepended (marked) by the marker character. - ReverseStringFilter(TokenStreamPtr input, wchar_t marker); + ReverseStringFilter(const TokenStreamPtr& input, wchar_t marker); virtual ~ReverseStringFilter(); diff --git a/src/contrib/include/RussianAnalyzer.h b/src/contrib/include/RussianAnalyzer.h index d3d82612..413ef2d7 100644 --- a/src/contrib/include/RussianAnalyzer.h +++ b/src/contrib/include/RussianAnalyzer.h @@ -46,14 +46,14 @@ namespace Lucene /// /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the /// provided {@link Reader}. /// /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI RussianAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/RussianLetterTokenizer.h b/src/contrib/include/RussianLetterTokenizer.h index 1ac76e3f..a646c788 100644 --- a/src/contrib/include/RussianLetterTokenizer.h +++ b/src/contrib/include/RussianLetterTokenizer.h @@ -17,13 +17,13 @@ namespace Lucene { public: /// Construct a new RussianLetterTokenizer. - RussianLetterTokenizer(ReaderPtr input); + RussianLetterTokenizer(const ReaderPtr& input); /// Construct a new RussianLetterTokenizer using a given {@link AttributeSource}. - RussianLetterTokenizer(AttributeSourcePtr source, ReaderPtr input); + RussianLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); /// Construct a new RussianLetterTokenizer using a given {@link AttributeFactory}. - RussianLetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input); + RussianLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); virtual ~RussianLetterTokenizer(); diff --git a/src/contrib/include/RussianLowerCaseFilter.h b/src/contrib/include/RussianLowerCaseFilter.h index 06608a29..a7eb56f9 100644 --- a/src/contrib/include/RussianLowerCaseFilter.h +++ b/src/contrib/include/RussianLowerCaseFilter.h @@ -16,7 +16,7 @@ namespace Lucene class LPPCONTRIBAPI RussianLowerCaseFilter : public TokenFilter { public: - RussianLowerCaseFilter(TokenStreamPtr input); + RussianLowerCaseFilter(const TokenStreamPtr& input); virtual ~RussianLowerCaseFilter(); diff --git a/src/contrib/include/RussianStemFilter.h b/src/contrib/include/RussianStemFilter.h index b2b4508b..4a695d97 100644 --- a/src/contrib/include/RussianStemFilter.h +++ b/src/contrib/include/RussianStemFilter.h @@ -21,7 +21,7 @@ namespace Lucene class LPPCONTRIBAPI RussianStemFilter : public TokenFilter { public: - RussianStemFilter(TokenStreamPtr input); + RussianStemFilter(const TokenStreamPtr& input); virtual ~RussianStemFilter(); @@ -37,7 +37,7 @@ namespace Lucene virtual bool incrementToken(); /// Set a alternative/custom {@link RussianStemmer} for this filter. - void setStemmer(RussianStemmerPtr stemmer); + void setStemmer(const RussianStemmerPtr& stemmer); }; } diff --git a/src/contrib/include/SimpleFragmenter.h b/src/contrib/include/SimpleFragmenter.h index 59b4fabe..3e310e2e 100644 --- a/src/contrib/include/SimpleFragmenter.h +++ b/src/contrib/include/SimpleFragmenter.h @@ -30,7 +30,7 @@ namespace Lucene OffsetAttributePtr offsetAtt; public: - virtual void start(const String& originalText, TokenStreamPtr tokenStream); + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); virtual bool isNewFragment(); /// @return size in number of characters of each fragment diff --git a/src/contrib/include/SimpleHTMLFormatter.h b/src/contrib/include/SimpleHTMLFormatter.h index a342d70e..ea7de8d0 100644 --- a/src/contrib/include/SimpleHTMLFormatter.h +++ b/src/contrib/include/SimpleHTMLFormatter.h @@ -32,7 +32,7 @@ namespace Lucene String postTag; public: - virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); }; } diff --git a/src/contrib/include/SimpleSpanFragmenter.h b/src/contrib/include/SimpleSpanFragmenter.h index 02ec2ee3..293b3ebd 100644 --- a/src/contrib/include/SimpleSpanFragmenter.h +++ b/src/contrib/include/SimpleSpanFragmenter.h @@ -17,11 +17,11 @@ namespace Lucene { public: /// @param queryScorer QueryScorer that was used to score hits - SimpleSpanFragmenter(QueryScorerPtr queryScorer); + SimpleSpanFragmenter(const QueryScorerPtr& queryScorer); /// @param queryScorer QueryScorer that was used to score hits /// @param fragmentSize size in bytes of each fragment - SimpleSpanFragmenter(QueryScorerPtr queryScorer, int32_t fragmentSize); + SimpleSpanFragmenter(const QueryScorerPtr& queryScorer, int32_t fragmentSize); virtual ~SimpleSpanFragmenter(); @@ -42,7 +42,7 @@ namespace Lucene public: virtual bool isNewFragment(); - virtual void start(const String& originalText, TokenStreamPtr tokenStream); + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); }; } diff --git a/src/contrib/include/SnowballAnalyzer.h b/src/contrib/include/SnowballAnalyzer.h index b703178b..a680455a 100644 --- a/src/contrib/include/SnowballAnalyzer.h +++ b/src/contrib/include/SnowballAnalyzer.h @@ -39,11 +39,11 @@ namespace Lucene public: /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter}, /// a {@link StopFilter} and a {@link SnowballFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); /// Returns a (possibly reused) {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link /// LowerCaseFilter}, a {@link StopFilter} and a {@link SnowballFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); }; class LPPCONTRIBAPI SnowballAnalyzerSavedStreams : public LuceneObject diff --git a/src/contrib/include/SnowballFilter.h b/src/contrib/include/SnowballFilter.h index 064f1394..8dd56224 100644 --- a/src/contrib/include/SnowballFilter.h +++ b/src/contrib/include/SnowballFilter.h @@ -18,7 +18,7 @@ namespace Lucene class LPPCONTRIBAPI SnowballFilter : public TokenFilter { public: - SnowballFilter(TokenStreamPtr input, const String& name); + SnowballFilter(const TokenStreamPtr& input, const String& name); virtual ~SnowballFilter(); LUCENE_CLASS(SnowballFilter); diff --git a/src/contrib/include/SpanGradientFormatter.h b/src/contrib/include/SpanGradientFormatter.h index 32fdf1fd..dde5f011 100644 --- a/src/contrib/include/SpanGradientFormatter.h +++ b/src/contrib/include/SpanGradientFormatter.h @@ -24,7 +24,7 @@ namespace Lucene LUCENE_CLASS(SpanGradientFormatter); public: - virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); }; } diff --git a/src/contrib/include/TextFragment.h b/src/contrib/include/TextFragment.h index 875e5a1d..e2ffd6dc 100644 --- a/src/contrib/include/TextFragment.h +++ b/src/contrib/include/TextFragment.h @@ -16,7 +16,7 @@ namespace Lucene class LPPCONTRIBAPI TextFragment : public LuceneObject { public: - TextFragment(StringBufferPtr markedUpText, int32_t textStartPos, int32_t fragNum); + TextFragment(const StringBufferPtr& markedUpText, int32_t textStartPos, int32_t fragNum); virtual ~TextFragment(); LUCENE_CLASS(TextFragment); @@ -33,10 +33,10 @@ namespace Lucene double getScore(); /// @param frag2 Fragment to be merged into this one - void merge(TextFragmentPtr frag2); + void merge(const TextFragmentPtr& frag2); /// @return true if this fragment follows the one passed - bool follows(TextFragmentPtr fragment); + bool follows(const TextFragmentPtr& fragment); /// @return the fragment sequence number int32_t getFragNum(); diff --git a/src/contrib/include/TokenGroup.h b/src/contrib/include/TokenGroup.h index 52d533ad..a43ec527 100644 --- a/src/contrib/include/TokenGroup.h +++ b/src/contrib/include/TokenGroup.h @@ -16,7 +16,7 @@ namespace Lucene class LPPCONTRIBAPI TokenGroup : public LuceneObject { public: - TokenGroup(TokenStreamPtr tokenStream); + TokenGroup(const TokenStreamPtr& tokenStream); virtual ~TokenGroup(); LUCENE_CLASS(TokenGroup); diff --git a/src/contrib/include/TokenSources.h b/src/contrib/include/TokenSources.h index 9970b85d..3b7ec06d 100644 --- a/src/contrib/include/TokenSources.h +++ b/src/contrib/include/TokenSources.h @@ -30,14 +30,14 @@ namespace Lucene /// @param doc The document to fall back on. /// @param analyzer The analyzer to use for creating the TokenStream if the vector doesn't exist. /// @return The {@link TokenStream} for the {@link Fieldable} on the {@link Document} - static TokenStreamPtr getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, DocumentPtr doc, AnalyzerPtr analyzer); + static TokenStreamPtr getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const DocumentPtr& doc, const AnalyzerPtr& analyzer); /// A convenience method that tries a number of approaches to getting a token stream. The cost of finding there /// are no termVectors in the index is minimal (1000 invocations still registers 0 ms). So this "lazy" (flexible?) /// approach to coding is probably acceptable - static TokenStreamPtr getAnyTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer); + static TokenStreamPtr getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer); - static TokenStreamPtr getTokenStream(TermPositionVectorPtr tpv); + static TokenStreamPtr getTokenStream(const TermPositionVectorPtr& tpv); /// Low level api. /// Returns a token stream or null if no offset info available in index. This can be used to feed the highlighter @@ -61,12 +61,12 @@ namespace Lucene /// @param tpv /// @param tokenPositionsGuaranteedContiguous true if the token position numbers have no overlaps or gaps. If looking /// to eek out the last drops of performance, set to true. If in doubt, set to false. - static TokenStreamPtr getTokenStream(TermPositionVectorPtr tpv, bool tokenPositionsGuaranteedContiguous); + static TokenStreamPtr getTokenStream(const TermPositionVectorPtr& tpv, bool tokenPositionsGuaranteedContiguous); - static TokenStreamPtr getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field); - static TokenStreamPtr getTokenStream(IndexReaderPtr reader, int32_t docId, const String& field, AnalyzerPtr analyzer); - static TokenStreamPtr getTokenStream(DocumentPtr doc, const String& field, AnalyzerPtr analyzer); - static TokenStreamPtr getTokenStream(const String& field, const String& contents, AnalyzerPtr analyzer); + static TokenStreamPtr getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field); + static TokenStreamPtr getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer); + static TokenStreamPtr getTokenStream(const DocumentPtr& doc, const String& field, const AnalyzerPtr& analyzer); + static TokenStreamPtr getTokenStream(const String& field, const String& contents, const AnalyzerPtr& analyzer); }; /// an object used to iterate across an array of tokens diff --git a/src/contrib/include/WeightedSpanTermExtractor.h b/src/contrib/include/WeightedSpanTermExtractor.h index a41a5700..c46cce2d 100644 --- a/src/contrib/include/WeightedSpanTermExtractor.h +++ b/src/contrib/include/WeightedSpanTermExtractor.h @@ -39,26 +39,26 @@ namespace Lucene /// /// @param query Query to extract Terms from /// @param terms Map to place created WeightedSpanTerms in - void extract(QueryPtr query, MapWeightedSpanTermPtr terms); + void extract(const QueryPtr& query, const MapWeightedSpanTermPtr& terms); /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied SpanQuery. /// /// @param terms Map to place created WeightedSpanTerms in. /// @param spanQuery SpanQuery to extract Terms from - void extractWeightedSpanTerms(MapWeightedSpanTermPtr terms, SpanQueryPtr spanQuery); + void extractWeightedSpanTerms(const MapWeightedSpanTermPtr& terms, const SpanQueryPtr& spanQuery); /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied Query. /// @param terms Map to place created WeightedSpanTerms in /// @param query Query to extract Terms from - void extractWeightedTerms(MapWeightedSpanTermPtr terms, QueryPtr query); + void extractWeightedTerms(const MapWeightedSpanTermPtr& terms, const QueryPtr& query); /// Necessary to implement matches for queries against defaultField bool fieldNameComparator(const String& fieldNameToCheck); IndexReaderPtr getReaderForField(const String& field); - void collectSpanQueryFields(SpanQueryPtr spanQuery, HashSet fieldNames); - bool mustRewriteQuery(SpanQueryPtr spanQuery); + void collectSpanQueryFields(const SpanQueryPtr& spanQuery, HashSet fieldNames); + bool mustRewriteQuery(const SpanQueryPtr& spanQuery); public: /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. @@ -66,7 +66,7 @@ namespace Lucene /// @param query That caused hit /// @param tokenStream Of text to be highlighted /// @return Map containing WeightedSpanTerms - MapWeightedSpanTermPtr getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream); + MapWeightedSpanTermPtr getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream); /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. /// @@ -74,7 +74,7 @@ namespace Lucene /// @param tokenStream Of text to be highlighted /// @param fieldName Restricts Term's used based on field name /// @return Map containing WeightedSpanTerms - MapWeightedSpanTermPtr getWeightedSpanTerms(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName); + MapWeightedSpanTermPtr getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName); /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. Uses a supplied /// IndexReader to properly weight terms (for gradient highlighting). @@ -84,7 +84,7 @@ namespace Lucene /// @param fieldName Restricts Term's used based on field name /// @param reader To use for scoring /// @return Map containing WeightedSpanTerms - MapWeightedSpanTermPtr getWeightedSpanTermsWithScores(QueryPtr query, TokenStreamPtr tokenStream, const String& fieldName, IndexReaderPtr reader); + MapWeightedSpanTermPtr getWeightedSpanTermsWithScores(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName, const IndexReaderPtr& reader); bool getExpandMultiTermQuery(); void setExpandMultiTermQuery(bool expandMultiTermQuery); @@ -108,7 +108,7 @@ namespace Lucene LUCENE_CLASS(PositionCheckingMap); public: - virtual void put(const String& key, WeightedSpanTermPtr val); + virtual void put(const String& key, const WeightedSpanTermPtr& val); }; /// A fake IndexReader class to extract the field from a MultiTermQuery @@ -127,7 +127,7 @@ namespace Lucene static IndexReaderPtr EMPTY_MEMORY_INDEX_READER(); public: - virtual TermEnumPtr terms(TermPtr t); + virtual TermEnumPtr terms(const TermPtr& t); }; } diff --git a/src/contrib/memory/MemoryIndex.cpp b/src/contrib/memory/MemoryIndex.cpp index 6a6e4e97..d8098e17 100644 --- a/src/contrib/memory/MemoryIndex.cpp +++ b/src/contrib/memory/MemoryIndex.cpp @@ -37,7 +37,7 @@ namespace Lucene { } - void MemoryIndex::addField(const String& fieldName, const String& text, AnalyzerPtr analyzer) + void MemoryIndex::addField(const String& fieldName, const String& text, const AnalyzerPtr& analyzer) { if (fieldName.empty()) boost::throw_exception(IllegalArgumentException(L"fieldName must not be empty")); @@ -50,7 +50,7 @@ namespace Lucene addField(fieldName, stream); } - void MemoryIndex::addField(const String& fieldName, TokenStreamPtr stream, double boost) + void MemoryIndex::addField(const String& fieldName, const TokenStreamPtr& stream, double boost) { LuceneException finally; try @@ -138,7 +138,7 @@ namespace Lucene return searcher; } - double MemoryIndex::search(QueryPtr query) + double MemoryIndex::search(const QueryPtr& query) { if (!query) boost::throw_exception(IllegalArgumentException(L"query must not be null")); @@ -231,7 +231,7 @@ namespace Lucene return boost; } - MemoryIndexReader::MemoryIndexReader(MemoryIndexPtr memoryIndex) + MemoryIndexReader::MemoryIndexReader(const MemoryIndexPtr& memoryIndex) { this->memoryIndex = memoryIndex; } @@ -261,7 +261,7 @@ namespace Lucene return memoryIndex->sortedFields[pos].second; } - int32_t MemoryIndexReader::docFreq(TermPtr t) + int32_t MemoryIndexReader::docFreq(const TermPtr& t) { MemoryIndexInfoPtr info(getInfo(t->field())); int32_t freq = 0; @@ -275,7 +275,7 @@ namespace Lucene return terms(MATCH_ALL_TERM()); } - TermEnumPtr MemoryIndexReader::terms(TermPtr t) + TermEnumPtr MemoryIndexReader::terms(const TermPtr& t) { int32_t i = 0; // index into info.sortedTerms int32_t j = 0; // index into sortedFields @@ -338,13 +338,13 @@ namespace Lucene return vectors; } - void MemoryIndexReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) + void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { for (MapStringMemoryIndexInfo::iterator fieldName = memoryIndex->fields.begin(); fieldName != memoryIndex->fields.end(); ++fieldName) getTermFreqVector(docNumber, fieldName->first, mapper); } - void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) + void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { MemoryIndexInfoPtr info(getInfo(field)); if (!info) @@ -383,7 +383,7 @@ namespace Lucene return Similarity::getDefault(); } - void MemoryIndexReader::setSearcher(SearcherPtr searcher) + void MemoryIndexReader::setSearcher(const SearcherPtr& searcher) { _searcher = searcher; } @@ -438,7 +438,7 @@ namespace Lucene return newLucene(); // there are no stored fields } - DocumentPtr MemoryIndexReader::document(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr MemoryIndexReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { return newLucene(); // there are no stored fields } @@ -490,7 +490,7 @@ namespace Lucene return fieldSet; } - MemoryIndexTermEnum::MemoryIndexTermEnum(MemoryIndexReaderPtr reader, int32_t ix, int32_t jx) + MemoryIndexTermEnum::MemoryIndexTermEnum(const MemoryIndexReaderPtr& reader, int32_t ix, int32_t jx) { _reader = reader; i = ix; @@ -545,7 +545,7 @@ namespace Lucene { } - TermPtr MemoryIndexTermEnum::createTerm(MemoryIndexInfoPtr info, int32_t pos, const String& text) + TermPtr MemoryIndexTermEnum::createTerm(const MemoryIndexInfoPtr& info, int32_t pos, const String& text) { TermPtr _template(info->_template); if (!_template) // not yet cached? @@ -572,7 +572,7 @@ namespace Lucene scores[0] = scorer->score(); } - void MemoryIndexCollector::setScorer(ScorerPtr scorer) + void MemoryIndexCollector::setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -582,11 +582,11 @@ namespace Lucene return true; } - void MemoryIndexCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void MemoryIndexCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { } - MemoryIndexTermPositions::MemoryIndexTermPositions(MemoryIndexReaderPtr reader) + MemoryIndexTermPositions::MemoryIndexTermPositions(const MemoryIndexReaderPtr& reader) { _reader = reader; hasNext = false; @@ -597,7 +597,7 @@ namespace Lucene { } - void MemoryIndexTermPositions::seek(TermPtr term) + void MemoryIndexTermPositions::seek(const TermPtr& term) { this->term = term; if (!term) @@ -612,7 +612,7 @@ namespace Lucene } } - void MemoryIndexTermPositions::seek(TermEnumPtr termEnum) + void MemoryIndexTermPositions::seek(const TermEnumPtr& termEnum) { seek(termEnum->term()); } @@ -680,7 +680,7 @@ namespace Lucene return false; // unsupported } - MemoryIndexTermPositionVector::MemoryIndexTermPositionVector(MemoryIndexReaderPtr reader, MemoryIndexInfoPtr info, const String& fieldName) + MemoryIndexTermPositionVector::MemoryIndexTermPositionVector(const MemoryIndexReaderPtr& reader, const MemoryIndexInfoPtr& info, const String& fieldName) { this->_reader = reader; this->sortedTerms = info->sortedTerms; diff --git a/src/contrib/snowball/SnowballAnalyzer.cpp b/src/contrib/snowball/SnowballAnalyzer.cpp index a4ee9793..d93845a0 100644 --- a/src/contrib/snowball/SnowballAnalyzer.cpp +++ b/src/contrib/snowball/SnowballAnalyzer.cpp @@ -31,7 +31,7 @@ namespace Lucene { } - TokenStreamPtr SnowballAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr SnowballAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(matchVersion, reader); result = newLucene(result); @@ -42,7 +42,7 @@ namespace Lucene return result; } - TokenStreamPtr SnowballAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr SnowballAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { SnowballAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/contrib/snowball/SnowballFilter.cpp b/src/contrib/snowball/SnowballFilter.cpp index 15252625..6e0d5deb 100644 --- a/src/contrib/snowball/SnowballFilter.cpp +++ b/src/contrib/snowball/SnowballFilter.cpp @@ -14,7 +14,7 @@ namespace Lucene { - SnowballFilter::SnowballFilter(TokenStreamPtr input, const String& name) : TokenFilter(input) + SnowballFilter::SnowballFilter(const TokenStreamPtr& input, const String& name) : TokenFilter(input) { stemmer = sb_stemmer_new(StringUtils::toUTF8(name).c_str(), "UTF_8"); if (stemmer == NULL) diff --git a/src/core/analysis/ASCIIFoldingFilter.cpp b/src/core/analysis/ASCIIFoldingFilter.cpp index 382805b6..dbd3353e 100644 --- a/src/core/analysis/ASCIIFoldingFilter.cpp +++ b/src/core/analysis/ASCIIFoldingFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - ASCIIFoldingFilter::ASCIIFoldingFilter(TokenStreamPtr input) : TokenFilter(input) + ASCIIFoldingFilter::ASCIIFoldingFilter(const TokenStreamPtr& input) : TokenFilter(input) { output = CharArray::newInstance(512); outputPos = 0; diff --git a/src/core/analysis/Analyzer.cpp b/src/core/analysis/Analyzer.cpp index 0e8a88c7..fd211ebf 100644 --- a/src/core/analysis/Analyzer.cpp +++ b/src/core/analysis/Analyzer.cpp @@ -14,7 +14,7 @@ namespace Lucene { } - TokenStreamPtr Analyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr Analyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { return tokenStream(fieldName, reader); } @@ -24,7 +24,7 @@ namespace Lucene return tokenStreams.get(); } - void Analyzer::setPreviousTokenStream(LuceneObjectPtr stream) + void Analyzer::setPreviousTokenStream(const LuceneObjectPtr& stream) { tokenStreams.set(stream); } @@ -34,7 +34,7 @@ namespace Lucene return 0; } - int32_t Analyzer::getOffsetGap(FieldablePtr field) + int32_t Analyzer::getOffsetGap(const FieldablePtr& field) { return field->isTokenized() ? 1 : 0; } diff --git a/src/core/analysis/BaseCharFilter.cpp b/src/core/analysis/BaseCharFilter.cpp index 609b2556..1eb4c3dd 100644 --- a/src/core/analysis/BaseCharFilter.cpp +++ b/src/core/analysis/BaseCharFilter.cpp @@ -10,7 +10,7 @@ namespace Lucene { - BaseCharFilter::BaseCharFilter(CharStreamPtr in) : CharFilter(in) + BaseCharFilter::BaseCharFilter(const CharStreamPtr& in) : CharFilter(in) { size = 0; } diff --git a/src/core/analysis/CachingTokenFilter.cpp b/src/core/analysis/CachingTokenFilter.cpp index ccfaac01..cb11701f 100644 --- a/src/core/analysis/CachingTokenFilter.cpp +++ b/src/core/analysis/CachingTokenFilter.cpp @@ -9,7 +9,7 @@ namespace Lucene { - CachingTokenFilter::CachingTokenFilter(TokenStreamPtr input) : TokenFilter(input) + CachingTokenFilter::CachingTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) { } diff --git a/src/core/analysis/CharFilter.cpp b/src/core/analysis/CharFilter.cpp index 900316ac..0f1f154c 100644 --- a/src/core/analysis/CharFilter.cpp +++ b/src/core/analysis/CharFilter.cpp @@ -9,7 +9,7 @@ namespace Lucene { - CharFilter::CharFilter(CharStreamPtr in) + CharFilter::CharFilter(const CharStreamPtr& in) { input = in; } diff --git a/src/core/analysis/CharReader.cpp b/src/core/analysis/CharReader.cpp index c304e143..ef166eba 100644 --- a/src/core/analysis/CharReader.cpp +++ b/src/core/analysis/CharReader.cpp @@ -9,7 +9,7 @@ namespace Lucene { - CharReader::CharReader(ReaderPtr in) + CharReader::CharReader(const ReaderPtr& in) { input = in; } @@ -18,7 +18,7 @@ namespace Lucene { } - CharStreamPtr CharReader::get(ReaderPtr input) + CharStreamPtr CharReader::get(const ReaderPtr& input) { CharStreamPtr charStream(boost::dynamic_pointer_cast(input)); return charStream ? charStream : newLucene(input); diff --git a/src/core/analysis/CharTokenizer.cpp b/src/core/analysis/CharTokenizer.cpp index c3941aef..a72a6e6f 100644 --- a/src/core/analysis/CharTokenizer.cpp +++ b/src/core/analysis/CharTokenizer.cpp @@ -15,7 +15,7 @@ namespace Lucene const int32_t CharTokenizer::MAX_WORD_LEN = 255; const int32_t CharTokenizer::IO_BUFFER_SIZE = 4096; - CharTokenizer::CharTokenizer(ReaderPtr input) : Tokenizer(input) + CharTokenizer::CharTokenizer(const ReaderPtr& input) : Tokenizer(input) { offset = 0; bufferIndex = 0; @@ -26,7 +26,7 @@ namespace Lucene termAtt = addAttribute(); } - CharTokenizer::CharTokenizer(AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source, input) + CharTokenizer::CharTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) { offset = 0; bufferIndex = 0; @@ -37,7 +37,7 @@ namespace Lucene termAtt = addAttribute(); } - CharTokenizer::CharTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory, input) + CharTokenizer::CharTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) { offset = 0; bufferIndex = 0; @@ -111,7 +111,7 @@ namespace Lucene offsetAtt->setOffset(finalOffset, finalOffset); } - void CharTokenizer::reset(ReaderPtr input) + void CharTokenizer::reset(const ReaderPtr& input) { Tokenizer::reset(input); bufferIndex = 0; diff --git a/src/core/analysis/ISOLatin1AccentFilter.cpp b/src/core/analysis/ISOLatin1AccentFilter.cpp index fbdc8f50..d22d0244 100644 --- a/src/core/analysis/ISOLatin1AccentFilter.cpp +++ b/src/core/analysis/ISOLatin1AccentFilter.cpp @@ -10,7 +10,7 @@ namespace Lucene { - ISOLatin1AccentFilter::ISOLatin1AccentFilter(TokenStreamPtr input) : TokenFilter(input) + ISOLatin1AccentFilter::ISOLatin1AccentFilter(const TokenStreamPtr& input) : TokenFilter(input) { output = CharArray::newInstance(256); outputPos = 0; diff --git a/src/core/analysis/KeywordAnalyzer.cpp b/src/core/analysis/KeywordAnalyzer.cpp index 4c83672a..1d281746 100644 --- a/src/core/analysis/KeywordAnalyzer.cpp +++ b/src/core/analysis/KeywordAnalyzer.cpp @@ -14,12 +14,12 @@ namespace Lucene { } - TokenStreamPtr KeywordAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr KeywordAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } - TokenStreamPtr KeywordAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr KeywordAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!tokenizer) diff --git a/src/core/analysis/KeywordTokenizer.cpp b/src/core/analysis/KeywordTokenizer.cpp index 81edc2ef..64421a46 100644 --- a/src/core/analysis/KeywordTokenizer.cpp +++ b/src/core/analysis/KeywordTokenizer.cpp @@ -14,22 +14,22 @@ namespace Lucene { const int32_t KeywordTokenizer::DEFAULT_BUFFER_SIZE = 256; - KeywordTokenizer::KeywordTokenizer(ReaderPtr input) : Tokenizer(input) + KeywordTokenizer::KeywordTokenizer(const ReaderPtr& input) : Tokenizer(input) { init(DEFAULT_BUFFER_SIZE); } - KeywordTokenizer::KeywordTokenizer(ReaderPtr input, int32_t bufferSize) : Tokenizer(input) + KeywordTokenizer::KeywordTokenizer(const ReaderPtr& input, int32_t bufferSize) : Tokenizer(input) { init(bufferSize); } - KeywordTokenizer::KeywordTokenizer(AttributeSourcePtr source, ReaderPtr input, int32_t bufferSize) : Tokenizer(source, input) + KeywordTokenizer::KeywordTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input, int32_t bufferSize) : Tokenizer(source, input) { init(bufferSize); } - KeywordTokenizer::KeywordTokenizer(AttributeFactoryPtr factory, ReaderPtr input, int32_t bufferSize) : Tokenizer(factory, input) + KeywordTokenizer::KeywordTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input, int32_t bufferSize) : Tokenizer(factory, input) { init(bufferSize); } diff --git a/src/core/analysis/LengthFilter.cpp b/src/core/analysis/LengthFilter.cpp index 827f58cc..c9283683 100644 --- a/src/core/analysis/LengthFilter.cpp +++ b/src/core/analysis/LengthFilter.cpp @@ -10,7 +10,7 @@ namespace Lucene { - LengthFilter::LengthFilter(TokenStreamPtr input, int32_t min, int32_t max) : TokenFilter(input) + LengthFilter::LengthFilter(const TokenStreamPtr& input, int32_t min, int32_t max) : TokenFilter(input) { this->min = min; this->max = max; diff --git a/src/core/analysis/LetterTokenizer.cpp b/src/core/analysis/LetterTokenizer.cpp index c66be70b..60683057 100644 --- a/src/core/analysis/LetterTokenizer.cpp +++ b/src/core/analysis/LetterTokenizer.cpp @@ -11,15 +11,15 @@ namespace Lucene { - LetterTokenizer::LetterTokenizer(ReaderPtr input) : CharTokenizer(input) + LetterTokenizer::LetterTokenizer(const ReaderPtr& input) : CharTokenizer(input) { } - LetterTokenizer::LetterTokenizer(AttributeSourcePtr source, ReaderPtr input) : CharTokenizer(source, input) + LetterTokenizer::LetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) { } - LetterTokenizer::LetterTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : CharTokenizer(factory, input) + LetterTokenizer::LetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) { } diff --git a/src/core/analysis/LowerCaseFilter.cpp b/src/core/analysis/LowerCaseFilter.cpp index 5dca0cbd..8fdb200c 100644 --- a/src/core/analysis/LowerCaseFilter.cpp +++ b/src/core/analysis/LowerCaseFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - LowerCaseFilter::LowerCaseFilter(TokenStreamPtr input) : TokenFilter(input) + LowerCaseFilter::LowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) { termAtt = addAttribute(); } diff --git a/src/core/analysis/LowerCaseTokenizer.cpp b/src/core/analysis/LowerCaseTokenizer.cpp index efbdfb58..3462efe2 100644 --- a/src/core/analysis/LowerCaseTokenizer.cpp +++ b/src/core/analysis/LowerCaseTokenizer.cpp @@ -10,15 +10,15 @@ namespace Lucene { - LowerCaseTokenizer::LowerCaseTokenizer(ReaderPtr input) : LetterTokenizer(input) + LowerCaseTokenizer::LowerCaseTokenizer(const ReaderPtr& input) : LetterTokenizer(input) { } - LowerCaseTokenizer::LowerCaseTokenizer(AttributeSourcePtr source, ReaderPtr input) : LetterTokenizer(source, input) + LowerCaseTokenizer::LowerCaseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : LetterTokenizer(source, input) { } - LowerCaseTokenizer::LowerCaseTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : LetterTokenizer(factory, input) + LowerCaseTokenizer::LowerCaseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : LetterTokenizer(factory, input) { } diff --git a/src/core/analysis/MappingCharFilter.cpp b/src/core/analysis/MappingCharFilter.cpp index a8f018ae..0834c2d3 100644 --- a/src/core/analysis/MappingCharFilter.cpp +++ b/src/core/analysis/MappingCharFilter.cpp @@ -11,14 +11,14 @@ namespace Lucene { - MappingCharFilter::MappingCharFilter(NormalizeCharMapPtr normMap, CharStreamPtr in) : BaseCharFilter(in) + MappingCharFilter::MappingCharFilter(const NormalizeCharMapPtr& normMap, const CharStreamPtr& in) : BaseCharFilter(in) { this->normMap = normMap; this->charPointer = 0; this->nextCharCounter = 0; } - MappingCharFilter::MappingCharFilter(NormalizeCharMapPtr normMap, ReaderPtr in) : BaseCharFilter(CharReader::get(in)) + MappingCharFilter::MappingCharFilter(const NormalizeCharMapPtr& normMap, const ReaderPtr& in) : BaseCharFilter(CharReader::get(in)) { this->normMap = normMap; this->charPointer = 0; @@ -85,7 +85,7 @@ namespace Lucene buffer.add((wchar_t)c); } - NormalizeCharMapPtr MappingCharFilter::match(NormalizeCharMapPtr map) + NormalizeCharMapPtr MappingCharFilter::match(const NormalizeCharMapPtr& map) { NormalizeCharMapPtr result; if (map->submap) diff --git a/src/core/analysis/NumericTokenStream.cpp b/src/core/analysis/NumericTokenStream.cpp index 6d7f7f2b..f510db38 100644 --- a/src/core/analysis/NumericTokenStream.cpp +++ b/src/core/analysis/NumericTokenStream.cpp @@ -36,7 +36,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } - NumericTokenStream::NumericTokenStream(AttributeSourcePtr source, int32_t precisionStep) : TokenStream(source) + NumericTokenStream::NumericTokenStream(const AttributeSourcePtr& source, int32_t precisionStep) : TokenStream(source) { this->shift = 0; this->valSize = 0; @@ -48,7 +48,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } - NumericTokenStream::NumericTokenStream(AttributeFactoryPtr factory, int32_t precisionStep) : TokenStream(factory) + NumericTokenStream::NumericTokenStream(const AttributeFactoryPtr& factory, int32_t precisionStep) : TokenStream(factory) { this->shift = 0; this->valSize = 0; diff --git a/src/core/analysis/PerFieldAnalyzerWrapper.cpp b/src/core/analysis/PerFieldAnalyzerWrapper.cpp index 414accd0..0d813b8e 100644 --- a/src/core/analysis/PerFieldAnalyzerWrapper.cpp +++ b/src/core/analysis/PerFieldAnalyzerWrapper.cpp @@ -10,13 +10,13 @@ namespace Lucene { - PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(AnalyzerPtr defaultAnalyzer) + PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer) { this->defaultAnalyzer = defaultAnalyzer; this->analyzerMap = MapStringAnalyzer::newInstance(); } - PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(AnalyzerPtr defaultAnalyzer, MapStringAnalyzer fieldAnalyzers) + PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer, MapStringAnalyzer fieldAnalyzers) { this->defaultAnalyzer = defaultAnalyzer; this->analyzerMap = MapStringAnalyzer::newInstance(); @@ -28,12 +28,12 @@ namespace Lucene { } - void PerFieldAnalyzerWrapper::addAnalyzer(const String& fieldName, AnalyzerPtr analyzer) + void PerFieldAnalyzerWrapper::addAnalyzer(const String& fieldName, const AnalyzerPtr& analyzer) { analyzerMap.put(fieldName, analyzer); } - TokenStreamPtr PerFieldAnalyzerWrapper::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr PerFieldAnalyzerWrapper::tokenStream(const String& fieldName, const ReaderPtr& reader) { AnalyzerPtr analyzer(analyzerMap.get(fieldName)); if (!analyzer) @@ -41,7 +41,7 @@ namespace Lucene return analyzer->tokenStream(fieldName, reader); } - TokenStreamPtr PerFieldAnalyzerWrapper::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr PerFieldAnalyzerWrapper::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { AnalyzerPtr analyzer(analyzerMap.get(fieldName)); if (!analyzer) @@ -57,7 +57,7 @@ namespace Lucene return analyzer->getPositionIncrementGap(fieldName); } - int32_t PerFieldAnalyzerWrapper::getOffsetGap(FieldablePtr field) + int32_t PerFieldAnalyzerWrapper::getOffsetGap(const FieldablePtr& field) { AnalyzerPtr analyzer(analyzerMap.get(field->name())); if (!analyzer) diff --git a/src/core/analysis/PorterStemFilter.cpp b/src/core/analysis/PorterStemFilter.cpp index 17227264..8dff5257 100644 --- a/src/core/analysis/PorterStemFilter.cpp +++ b/src/core/analysis/PorterStemFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - PorterStemFilter::PorterStemFilter(TokenStreamPtr input) : TokenFilter(input) + PorterStemFilter::PorterStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { stemmer = newLucene(); termAtt = addAttribute(); diff --git a/src/core/analysis/SimpleAnalyzer.cpp b/src/core/analysis/SimpleAnalyzer.cpp index 4378aadb..99798299 100644 --- a/src/core/analysis/SimpleAnalyzer.cpp +++ b/src/core/analysis/SimpleAnalyzer.cpp @@ -14,12 +14,12 @@ namespace Lucene { } - TokenStreamPtr SimpleAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr SimpleAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } - TokenStreamPtr SimpleAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr SimpleAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!tokenizer) diff --git a/src/core/analysis/StopAnalyzer.cpp b/src/core/analysis/StopAnalyzer.cpp index 401cba74..51dd7024 100644 --- a/src/core/analysis/StopAnalyzer.cpp +++ b/src/core/analysis/StopAnalyzer.cpp @@ -40,7 +40,7 @@ namespace Lucene enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); } - StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords) + StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords) { stopWords = WordlistLoader::getWordSet(stopwords); enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); @@ -58,12 +58,12 @@ namespace Lucene return __ENGLISH_STOP_WORDS_SET; } - TokenStreamPtr StopAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr StopAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(enablePositionIncrements, newLucene(reader), stopWords); } - TokenStreamPtr StopAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr StopAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { StopAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!streams) diff --git a/src/core/analysis/StopFilter.cpp b/src/core/analysis/StopFilter.cpp index f883ae47..6ac29215 100644 --- a/src/core/analysis/StopFilter.cpp +++ b/src/core/analysis/StopFilter.cpp @@ -12,7 +12,7 @@ namespace Lucene { - StopFilter::StopFilter(bool enablePositionIncrements, TokenStreamPtr input, HashSet stopWords, bool ignoreCase) : TokenFilter(input) + StopFilter::StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, HashSet stopWords, bool ignoreCase) : TokenFilter(input) { this->stopWords = newLucene(stopWords, ignoreCase); this->enablePositionIncrements = enablePositionIncrements; @@ -20,7 +20,7 @@ namespace Lucene posIncrAtt = addAttribute(); } - StopFilter::StopFilter(bool enablePositionIncrements, TokenStreamPtr input, CharArraySetPtr stopWords, bool ignoreCase) : TokenFilter(input) + StopFilter::StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, const CharArraySetPtr& stopWords, bool ignoreCase) : TokenFilter(input) { this->stopWords = stopWords; this->enablePositionIncrements = enablePositionIncrements; diff --git a/src/core/analysis/TeeSinkTokenFilter.cpp b/src/core/analysis/TeeSinkTokenFilter.cpp index 17db6bc5..3f36ec79 100644 --- a/src/core/analysis/TeeSinkTokenFilter.cpp +++ b/src/core/analysis/TeeSinkTokenFilter.cpp @@ -10,7 +10,7 @@ namespace Lucene { - TeeSinkTokenFilter::TeeSinkTokenFilter(TokenStreamPtr input) : TokenFilter(input) + TeeSinkTokenFilter::TeeSinkTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) { this->sinks = Collection::newInstance(); } @@ -30,14 +30,14 @@ namespace Lucene return newSinkTokenStream(ACCEPT_ALL_FILTER); } - SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream(SinkFilterPtr filter) + SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream(const SinkFilterPtr& filter) { SinkTokenStreamPtr sink(newLucene(this->cloneAttributes(), filter)); this->sinks.add(sink); return sink; } - void TeeSinkTokenFilter::addSinkTokenStream(SinkTokenStreamPtr sink) + void TeeSinkTokenFilter::addSinkTokenStream(const SinkTokenStreamPtr& sink) { // check that sink has correct factory if (this->getAttributeFactory() != sink->getAttributeFactory()) @@ -104,12 +104,12 @@ namespace Lucene { } - bool AcceptAllSinkFilter::accept(AttributeSourcePtr source) + bool AcceptAllSinkFilter::accept(const AttributeSourcePtr& source) { return true; } - SinkTokenStream::SinkTokenStream(AttributeSourcePtr source, SinkFilterPtr filter) : TokenStream(source) + SinkTokenStream::SinkTokenStream(const AttributeSourcePtr& source, const SinkFilterPtr& filter) : TokenStream(source) { this->filter = filter; this->cachedStates = Collection::newInstance(); @@ -121,19 +121,19 @@ namespace Lucene { } - bool SinkTokenStream::accept(AttributeSourcePtr source) + bool SinkTokenStream::accept(const AttributeSourcePtr& source) { return filter->accept(source); } - void SinkTokenStream::addState(AttributeSourceStatePtr state) + void SinkTokenStream::addState(const AttributeSourceStatePtr& state) { if (initIterator) boost::throw_exception(IllegalStateException(L"The tee must be consumed before sinks are consumed.")); cachedStates.add(state); } - void SinkTokenStream::setFinalState(AttributeSourceStatePtr finalState) + void SinkTokenStream::setFinalState(const AttributeSourceStatePtr& finalState) { this->finalState = finalState; } diff --git a/src/core/analysis/Token.cpp b/src/core/analysis/Token.cpp index 12fb87fb..11791489 100644 --- a/src/core/analysis/Token.cpp +++ b/src/core/analysis/Token.cpp @@ -242,7 +242,7 @@ namespace Lucene return this->payload; } - void Token::setPayload(PayloadPtr payload) + void Token::setPayload(const PayloadPtr& payload) { this->payload = payload; } @@ -276,7 +276,7 @@ namespace Lucene _type = DEFAULT_TYPE(); } - LuceneObjectPtr Token::clone(LuceneObjectPtr other) + LuceneObjectPtr Token::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); TokenPtr cloneToken(boost::dynamic_pointer_cast(clone)); @@ -310,7 +310,7 @@ namespace Lucene return clone; } - bool Token::equals(LuceneObjectPtr other) + bool Token::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -426,7 +426,7 @@ namespace Lucene return shared_from_this(); } - void Token::reinit(TokenPtr prototype) + void Token::reinit(const TokenPtr& prototype) { prototype->initTermBuffer(); setTermBuffer(prototype->_termBuffer.get(), 0, prototype->_termLength); @@ -438,7 +438,7 @@ namespace Lucene payload = prototype->payload; } - void Token::reinit(TokenPtr prototype, const String& newTerm) + void Token::reinit(const TokenPtr& prototype, const String& newTerm) { setTermBuffer(newTerm); positionIncrement = prototype->positionIncrement; @@ -449,7 +449,7 @@ namespace Lucene payload = prototype->payload; } - void Token::reinit(TokenPtr prototype, CharArray newTermBuffer, int32_t offset, int32_t length) + void Token::reinit(const TokenPtr& prototype, CharArray newTermBuffer, int32_t offset, int32_t length) { setTermBuffer(newTermBuffer.get(), offset, length); positionIncrement = prototype->positionIncrement; @@ -460,7 +460,7 @@ namespace Lucene payload = prototype->payload; } - void Token::copyTo(AttributePtr target) + void Token::copyTo(const AttributePtr& target) { TokenPtr targetToken(boost::dynamic_pointer_cast(target)); if (targetToken) @@ -505,7 +505,7 @@ namespace Lucene return _TOKEN_ATTRIBUTE_FACTORY; } - TokenAttributeFactory::TokenAttributeFactory(AttributeFactoryPtr delegate) + TokenAttributeFactory::TokenAttributeFactory(const AttributeFactoryPtr& delegate) { this->delegate = delegate; } @@ -519,7 +519,7 @@ namespace Lucene return newLucene(); } - bool TokenAttributeFactory::equals(LuceneObjectPtr other) + bool TokenAttributeFactory::equals(const LuceneObjectPtr& other) { if (AttributeFactory::equals(other)) return true; diff --git a/src/core/analysis/TokenFilter.cpp b/src/core/analysis/TokenFilter.cpp index 2f9d8f96..28b0fc88 100644 --- a/src/core/analysis/TokenFilter.cpp +++ b/src/core/analysis/TokenFilter.cpp @@ -9,7 +9,7 @@ namespace Lucene { - TokenFilter::TokenFilter(TokenStreamPtr input) : TokenStream(input) + TokenFilter::TokenFilter(const TokenStreamPtr& input) : TokenStream(input) { this->input = input; } diff --git a/src/core/analysis/TokenStream.cpp b/src/core/analysis/TokenStream.cpp index 45190b64..ed304438 100644 --- a/src/core/analysis/TokenStream.cpp +++ b/src/core/analysis/TokenStream.cpp @@ -13,11 +13,11 @@ namespace Lucene { } - TokenStream::TokenStream(AttributeSourcePtr input) : AttributeSource(input) + TokenStream::TokenStream(const AttributeSourcePtr& input) : AttributeSource(input) { } - TokenStream::TokenStream(AttributeFactoryPtr factory) : AttributeSource(factory) + TokenStream::TokenStream(const AttributeFactoryPtr& factory) : AttributeSource(factory) { } diff --git a/src/core/analysis/Tokenizer.cpp b/src/core/analysis/Tokenizer.cpp index a1c12d55..8338eadb 100644 --- a/src/core/analysis/Tokenizer.cpp +++ b/src/core/analysis/Tokenizer.cpp @@ -14,27 +14,27 @@ namespace Lucene { } - Tokenizer::Tokenizer(ReaderPtr input) + Tokenizer::Tokenizer(const ReaderPtr& input) { this->input = CharReader::get(input); this->charStream = boost::dynamic_pointer_cast(this->input); } - Tokenizer::Tokenizer(AttributeFactoryPtr factory) : TokenStream(factory) + Tokenizer::Tokenizer(const AttributeFactoryPtr& factory) : TokenStream(factory) { } - Tokenizer::Tokenizer(AttributeFactoryPtr factory, ReaderPtr input) : TokenStream(factory) + Tokenizer::Tokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : TokenStream(factory) { this->input = CharReader::get(input); this->charStream = boost::dynamic_pointer_cast(this->input); } - Tokenizer::Tokenizer(AttributeSourcePtr source) : TokenStream(source) + Tokenizer::Tokenizer(const AttributeSourcePtr& source) : TokenStream(source) { } - Tokenizer::Tokenizer(AttributeSourcePtr source, ReaderPtr input) : TokenStream(source) + Tokenizer::Tokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : TokenStream(source) { this->input = CharReader::get(input); this->charStream = boost::dynamic_pointer_cast(this->input); @@ -58,7 +58,7 @@ namespace Lucene return charStream ? charStream->correctOffset(currentOff) : currentOff; } - void Tokenizer::reset(ReaderPtr input) + void Tokenizer::reset(const ReaderPtr& input) { this->input = input; } diff --git a/src/core/analysis/WhitespaceAnalyzer.cpp b/src/core/analysis/WhitespaceAnalyzer.cpp index be79ccde..72850a4c 100644 --- a/src/core/analysis/WhitespaceAnalyzer.cpp +++ b/src/core/analysis/WhitespaceAnalyzer.cpp @@ -14,12 +14,12 @@ namespace Lucene { } - TokenStreamPtr WhitespaceAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr WhitespaceAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } - TokenStreamPtr WhitespaceAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr WhitespaceAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); if (!tokenizer) diff --git a/src/core/analysis/WhitespaceTokenizer.cpp b/src/core/analysis/WhitespaceTokenizer.cpp index 04a36689..039a4747 100644 --- a/src/core/analysis/WhitespaceTokenizer.cpp +++ b/src/core/analysis/WhitespaceTokenizer.cpp @@ -11,15 +11,15 @@ namespace Lucene { - WhitespaceTokenizer::WhitespaceTokenizer(ReaderPtr input) : CharTokenizer(input) + WhitespaceTokenizer::WhitespaceTokenizer(const ReaderPtr& input) : CharTokenizer(input) { } - WhitespaceTokenizer::WhitespaceTokenizer(AttributeSourcePtr source, ReaderPtr input) : CharTokenizer(source, input) + WhitespaceTokenizer::WhitespaceTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) { } - WhitespaceTokenizer::WhitespaceTokenizer(AttributeFactoryPtr factory, ReaderPtr input) : CharTokenizer(factory, input) + WhitespaceTokenizer::WhitespaceTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) { } diff --git a/src/core/analysis/WordlistLoader.cpp b/src/core/analysis/WordlistLoader.cpp index 6beb49c1..520c04ea 100644 --- a/src/core/analysis/WordlistLoader.cpp +++ b/src/core/analysis/WordlistLoader.cpp @@ -36,7 +36,7 @@ namespace Lucene return result; } - HashSet WordlistLoader::getWordSet(ReaderPtr reader, const String& comment) + HashSet WordlistLoader::getWordSet(const ReaderPtr& reader, const String& comment) { HashSet result(HashSet::newInstance()); LuceneException finally; diff --git a/src/core/analysis/standard/StandardAnalyzer.cpp b/src/core/analysis/standard/StandardAnalyzer.cpp index 4be8873a..94b13795 100644 --- a/src/core/analysis/standard/StandardAnalyzer.cpp +++ b/src/core/analysis/standard/StandardAnalyzer.cpp @@ -34,7 +34,7 @@ namespace Lucene ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); } - StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, ReaderPtr stopwords) + StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords) { ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); } @@ -52,7 +52,7 @@ namespace Lucene this->maxTokenLength = DEFAULT_MAX_TOKEN_LENGTH; } - TokenStreamPtr StandardAnalyzer::tokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr StandardAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { StandardTokenizerPtr tokenStream(newLucene(matchVersion, reader)); tokenStream->setMaxTokenLength(maxTokenLength); @@ -72,7 +72,7 @@ namespace Lucene return maxTokenLength; } - TokenStreamPtr StandardAnalyzer::reusableTokenStream(const String& fieldName, ReaderPtr reader) + TokenStreamPtr StandardAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { StandardAnalyzerSavedStreamsPtr streams = boost::dynamic_pointer_cast(getPreviousTokenStream()); if (!streams) diff --git a/src/core/analysis/standard/StandardFilter.cpp b/src/core/analysis/standard/StandardFilter.cpp index 772c3245..707dc8c0 100644 --- a/src/core/analysis/standard/StandardFilter.cpp +++ b/src/core/analysis/standard/StandardFilter.cpp @@ -12,7 +12,7 @@ namespace Lucene { - StandardFilter::StandardFilter(TokenStreamPtr input) : TokenFilter(input) + StandardFilter::StandardFilter(const TokenStreamPtr& input) : TokenFilter(input) { termAtt = addAttribute(); typeAtt = addAttribute(); diff --git a/src/core/analysis/standard/StandardTokenizer.cpp b/src/core/analysis/standard/StandardTokenizer.cpp index dbf37a8e..e6c9656b 100644 --- a/src/core/analysis/standard/StandardTokenizer.cpp +++ b/src/core/analysis/standard/StandardTokenizer.cpp @@ -27,19 +27,19 @@ namespace Lucene /// @deprecated this solves a bug where HOSTs that end with '.' are identified as ACRONYMs. const int32_t StandardTokenizer::ACRONYM_DEP = 8; - StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, ReaderPtr input) + StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const ReaderPtr& input) { this->scanner = newLucene(input); init(input, matchVersion); } - StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, AttributeSourcePtr source, ReaderPtr input) : Tokenizer(source) + StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source) { this->scanner = newLucene(input); init(input, matchVersion); } - StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, AttributeFactoryPtr factory, ReaderPtr input) : Tokenizer(factory) + StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory) { this->scanner = newLucene(input); init(input, matchVersion); @@ -69,7 +69,7 @@ namespace Lucene return _TOKEN_TYPES; } - void StandardTokenizer::init(ReaderPtr input, LuceneVersion::Version matchVersion) + void StandardTokenizer::init(const ReaderPtr& input, LuceneVersion::Version matchVersion) { replaceInvalidAcronym = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_24); maxTokenLength = StandardAnalyzer::DEFAULT_MAX_TOKEN_LENGTH; @@ -140,7 +140,7 @@ namespace Lucene offsetAtt->setOffset(finalOffset, finalOffset); } - void StandardTokenizer::reset(ReaderPtr input) + void StandardTokenizer::reset(const ReaderPtr& input) { Tokenizer::reset(input); scanner->reset(input); diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index efe537da..993cfeaf 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -188,7 +188,7 @@ namespace Lucene /// Lexical states const int32_t StandardTokenizerImpl::YYINITIAL = 0; - StandardTokenizerImpl::StandardTokenizerImpl(ReaderPtr in) + StandardTokenizerImpl::StandardTokenizerImpl(const ReaderPtr& in) { this->zzState = 0; this->zzLexicalState = YYINITIAL; @@ -333,7 +333,7 @@ namespace Lucene return _yychar; } - void StandardTokenizerImpl::reset(ReaderPtr r) + void StandardTokenizerImpl::reset(const ReaderPtr& r) { // reset to default buffer size, if buffer has grown if (zzBuffer.size() > ZZ_BUFFERSIZE) @@ -341,12 +341,12 @@ namespace Lucene yyreset(r); } - void StandardTokenizerImpl::getText(TokenPtr t) + void StandardTokenizerImpl::getText(const TokenPtr& t) { t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); } - void StandardTokenizerImpl::getText(TermAttributePtr t) + void StandardTokenizerImpl::getText(const TermAttributePtr& t) { t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); } @@ -391,7 +391,7 @@ namespace Lucene zzReader->close(); } - void StandardTokenizerImpl::yyreset(ReaderPtr reader) + void StandardTokenizerImpl::yyreset(const ReaderPtr& reader) { zzReader = reader; zzAtBOL = true; diff --git a/src/core/analysis/tokenattributes/FlagsAttribute.cpp b/src/core/analysis/tokenattributes/FlagsAttribute.cpp index 8cd155e8..aa86a64f 100644 --- a/src/core/analysis/tokenattributes/FlagsAttribute.cpp +++ b/src/core/analysis/tokenattributes/FlagsAttribute.cpp @@ -39,7 +39,7 @@ namespace Lucene flags = 0; } - bool FlagsAttribute::equals(LuceneObjectPtr other) + bool FlagsAttribute::equals(const LuceneObjectPtr& other) { if (Attribute::equals(other)) return true; @@ -56,12 +56,12 @@ namespace Lucene return flags; } - void FlagsAttribute::copyTo(AttributePtr target) + void FlagsAttribute::copyTo(const AttributePtr& target) { boost::dynamic_pointer_cast(target)->setFlags(flags); } - LuceneObjectPtr FlagsAttribute::clone(LuceneObjectPtr other) + LuceneObjectPtr FlagsAttribute::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); FlagsAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); diff --git a/src/core/analysis/tokenattributes/OffsetAttribute.cpp b/src/core/analysis/tokenattributes/OffsetAttribute.cpp index df55a858..bde260af 100644 --- a/src/core/analysis/tokenattributes/OffsetAttribute.cpp +++ b/src/core/analysis/tokenattributes/OffsetAttribute.cpp @@ -47,7 +47,7 @@ namespace Lucene _endOffset = 0; } - bool OffsetAttribute::equals(LuceneObjectPtr other) + bool OffsetAttribute::equals(const LuceneObjectPtr& other) { if (Attribute::equals(other)) return true; @@ -66,13 +66,13 @@ namespace Lucene return code; } - void OffsetAttribute::copyTo(AttributePtr target) + void OffsetAttribute::copyTo(const AttributePtr& target) { OffsetAttributePtr targetOffsetAttribute(boost::dynamic_pointer_cast(target)); targetOffsetAttribute->setOffset(_startOffset, _endOffset); } - LuceneObjectPtr OffsetAttribute::clone(LuceneObjectPtr other) + LuceneObjectPtr OffsetAttribute::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); OffsetAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); diff --git a/src/core/analysis/tokenattributes/PayloadAttribute.cpp b/src/core/analysis/tokenattributes/PayloadAttribute.cpp index 3055c993..c9ae6d83 100644 --- a/src/core/analysis/tokenattributes/PayloadAttribute.cpp +++ b/src/core/analysis/tokenattributes/PayloadAttribute.cpp @@ -15,7 +15,7 @@ namespace Lucene { } - PayloadAttribute::PayloadAttribute(PayloadPtr payload) + PayloadAttribute::PayloadAttribute(const PayloadPtr& payload) { this->payload = payload; } @@ -34,7 +34,7 @@ namespace Lucene return this->payload; } - void PayloadAttribute::setPayload(PayloadPtr payload) + void PayloadAttribute::setPayload(const PayloadPtr& payload) { this->payload = payload; } @@ -44,7 +44,7 @@ namespace Lucene payload.reset(); } - LuceneObjectPtr PayloadAttribute::clone(LuceneObjectPtr other) + LuceneObjectPtr PayloadAttribute::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); PayloadAttributePtr cloneAttribute(boost::dynamic_pointer_cast(clone)); @@ -53,7 +53,7 @@ namespace Lucene return cloneAttribute; } - bool PayloadAttribute::equals(LuceneObjectPtr other) + bool PayloadAttribute::equals(const LuceneObjectPtr& other) { if (Attribute::equals(other)) return true; @@ -74,7 +74,7 @@ namespace Lucene return payload ? payload->hashCode() : 0; } - void PayloadAttribute::copyTo(AttributePtr target) + void PayloadAttribute::copyTo(const AttributePtr& target) { PayloadAttributePtr targetPayloadAttribute(boost::dynamic_pointer_cast(target)); targetPayloadAttribute->setPayload(payload ? boost::dynamic_pointer_cast(payload->clone()) : PayloadPtr()); diff --git a/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp b/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp index 481e5357..8fc16e34 100644 --- a/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp +++ b/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp @@ -41,7 +41,7 @@ namespace Lucene this->positionIncrement = 1; } - bool PositionIncrementAttribute::equals(LuceneObjectPtr other) + bool PositionIncrementAttribute::equals(const LuceneObjectPtr& other) { if (Attribute::equals(other)) return true; @@ -58,13 +58,13 @@ namespace Lucene return positionIncrement; } - void PositionIncrementAttribute::copyTo(AttributePtr target) + void PositionIncrementAttribute::copyTo(const AttributePtr& target) { PositionIncrementAttributePtr targetPositionIncrementAttribute(boost::dynamic_pointer_cast(target)); targetPositionIncrementAttribute->setPositionIncrement(positionIncrement); } - LuceneObjectPtr PositionIncrementAttribute::clone(LuceneObjectPtr other) + LuceneObjectPtr PositionIncrementAttribute::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); PositionIncrementAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); diff --git a/src/core/analysis/tokenattributes/TermAttribute.cpp b/src/core/analysis/tokenattributes/TermAttribute.cpp index 21ecccc4..aaf2aaa6 100644 --- a/src/core/analysis/tokenattributes/TermAttribute.cpp +++ b/src/core/analysis/tokenattributes/TermAttribute.cpp @@ -125,7 +125,7 @@ namespace Lucene _termLength = 0; } - LuceneObjectPtr TermAttribute::clone(LuceneObjectPtr other) + LuceneObjectPtr TermAttribute::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); TermAttributePtr cloneAttribute(boost::dynamic_pointer_cast(clone)); @@ -138,7 +138,7 @@ namespace Lucene return cloneAttribute; } - bool TermAttribute::equals(LuceneObjectPtr other) + bool TermAttribute::equals(const LuceneObjectPtr& other) { if (Attribute::equals(other)) return true; @@ -158,7 +158,7 @@ namespace Lucene return false; } - void TermAttribute::copyTo(AttributePtr target) + void TermAttribute::copyTo(const AttributePtr& target) { initTermBuffer(); TermAttributePtr targetTermAttribute(boost::dynamic_pointer_cast(target)); diff --git a/src/core/analysis/tokenattributes/TypeAttribute.cpp b/src/core/analysis/tokenattributes/TypeAttribute.cpp index 527ac68a..a2664189 100644 --- a/src/core/analysis/tokenattributes/TypeAttribute.cpp +++ b/src/core/analysis/tokenattributes/TypeAttribute.cpp @@ -50,7 +50,7 @@ namespace Lucene _type = DEFAULT_TYPE(); } - bool TypeAttribute::equals(LuceneObjectPtr other) + bool TypeAttribute::equals(const LuceneObjectPtr& other) { if (Attribute::equals(other)) return true; @@ -67,12 +67,12 @@ namespace Lucene return StringUtils::hashCode(_type); } - void TypeAttribute::copyTo(AttributePtr target) + void TypeAttribute::copyTo(const AttributePtr& target) { boost::dynamic_pointer_cast(target)->setType(_type); } - LuceneObjectPtr TypeAttribute::clone(LuceneObjectPtr other) + LuceneObjectPtr TypeAttribute::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); TypeAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); diff --git a/src/core/document/Document.cpp b/src/core/document/Document.cpp index c0a8c063..5490e4b8 100644 --- a/src/core/document/Document.cpp +++ b/src/core/document/Document.cpp @@ -31,7 +31,7 @@ namespace Lucene return boost; } - void Document::add(FieldablePtr field) + void Document::add(const FieldablePtr& field) { fields.add(field); } diff --git a/src/core/document/Field.cpp b/src/core/document/Field.cpp index 9ed29000..72878191 100644 --- a/src/core/document/Field.cpp +++ b/src/core/document/Field.cpp @@ -22,22 +22,22 @@ namespace Lucene ConstructField(name, value, store, index, termVector); } - Field::Field(const String& name, ReaderPtr reader) + Field::Field(const String& name, const ReaderPtr& reader) { ConstructField(name, reader, TERM_VECTOR_NO); } - Field::Field(const String& name, ReaderPtr reader, TermVector termVector) + Field::Field(const String& name, const ReaderPtr& reader, TermVector termVector) { ConstructField(name, reader, termVector); } - Field::Field(const String& name, TokenStreamPtr tokenStream) + Field::Field(const String& name, const TokenStreamPtr& tokenStream) { ConstructField(name, tokenStream, TERM_VECTOR_NO); } - Field::Field(const String& name, TokenStreamPtr tokenStream, TermVector termVector) + Field::Field(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector) { ConstructField(name, tokenStream, termVector); } @@ -75,7 +75,7 @@ namespace Lucene setStoreTermVector(termVector); } - void Field::ConstructField(const String& name, ReaderPtr reader, TermVector termVector) + void Field::ConstructField(const String& name, const ReaderPtr& reader, TermVector termVector) { this->_name = name; this->fieldsData = reader; @@ -87,7 +87,7 @@ namespace Lucene setStoreTermVector(termVector); } - void Field::ConstructField(const String& name, TokenStreamPtr tokenStream, TermVector termVector) + void Field::ConstructField(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector) { this->_name = name; this->fieldsData = VariantUtils::null(); @@ -145,7 +145,7 @@ namespace Lucene fieldsData = value; } - void Field::setValue(ReaderPtr value) + void Field::setValue(const ReaderPtr& value) { if (_isBinary) boost::throw_exception(IllegalArgumentException(L"cannot set a Reader value on a binary field")); @@ -172,7 +172,7 @@ namespace Lucene binaryOffset = offset; } - void Field::setTokenStream(TokenStreamPtr tokenStream) + void Field::setTokenStream(const TokenStreamPtr& tokenStream) { this->_isIndexed = true; this->_isTokenized = true; diff --git a/src/core/include/_BooleanQuery.h b/src/core/include/_BooleanQuery.h index f0e7f603..ef58d365 100644 --- a/src/core/include/_BooleanQuery.h +++ b/src/core/include/_BooleanQuery.h @@ -15,7 +15,7 @@ namespace Lucene class BooleanWeight : public Weight { public: - BooleanWeight(BooleanQueryPtr query, SearcherPtr searcher); + BooleanWeight(const BooleanQueryPtr& query, const SearcherPtr& searcher); virtual ~BooleanWeight(); LUCENE_CLASS(BooleanWeight); @@ -32,8 +32,8 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); virtual bool scoresDocsOutOfOrder(); }; @@ -41,7 +41,7 @@ namespace Lucene class SimilarityDisableCoord : public SimilarityDelegator { public: - SimilarityDisableCoord(SimilarityPtr delegee); + SimilarityDisableCoord(const SimilarityPtr& delegee); virtual ~SimilarityDisableCoord(); LUCENE_CLASS(SimilarityDisableCoord); diff --git a/src/core/include/_ByteFieldSource.h b/src/core/include/_ByteFieldSource.h index 945f988d..a4cd3e97 100644 --- a/src/core/include/_ByteFieldSource.h +++ b/src/core/include/_ByteFieldSource.h @@ -14,7 +14,7 @@ namespace Lucene class ByteDocValues : public DocValues { public: - ByteDocValues(ByteFieldSourcePtr source, Collection arr); + ByteDocValues(const ByteFieldSourcePtr& source, Collection arr); virtual ~ByteDocValues(); LUCENE_CLASS(ByteDocValues); diff --git a/src/core/include/_CachingSpanFilter.h b/src/core/include/_CachingSpanFilter.h index 0aafb4e2..b7f956cf 100644 --- a/src/core/include/_CachingSpanFilter.h +++ b/src/core/include/_CachingSpanFilter.h @@ -20,7 +20,7 @@ namespace Lucene LUCENE_CLASS(FilterCacheSpanFilterResult); protected: - virtual LuceneObjectPtr mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value); + virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value); }; } diff --git a/src/core/include/_CachingWrapperFilter.h b/src/core/include/_CachingWrapperFilter.h index e246f5db..903b9487 100644 --- a/src/core/include/_CachingWrapperFilter.h +++ b/src/core/include/_CachingWrapperFilter.h @@ -24,11 +24,11 @@ namespace Lucene CachingWrapperFilter::DeletesMode deletesMode; public: - virtual LuceneObjectPtr get(IndexReaderPtr reader, LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey); - virtual void put(LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey, LuceneObjectPtr value); + virtual LuceneObjectPtr get(const IndexReaderPtr& reader, const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey); + virtual void put(const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey, const LuceneObjectPtr& value); protected: - virtual LuceneObjectPtr mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value) = 0; + virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) = 0; }; class FilterCacheDocIdSet : public FilterCache @@ -40,13 +40,13 @@ namespace Lucene LUCENE_CLASS(FilterCacheDocIdSet); protected: - virtual LuceneObjectPtr mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value); + virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value); }; class FilteredCacheDocIdSet : public FilteredDocIdSet { public: - FilteredCacheDocIdSet(IndexReaderPtr reader, DocIdSetPtr innerSet); + FilteredCacheDocIdSet(const IndexReaderPtr& reader, const DocIdSetPtr& innerSet); virtual ~FilteredCacheDocIdSet(); LUCENE_CLASS(FilteredCacheDocIdSet); diff --git a/src/core/include/_CheckIndex.h b/src/core/include/_CheckIndex.h index a279b7de..fd8c870f 100644 --- a/src/core/include/_CheckIndex.h +++ b/src/core/include/_CheckIndex.h @@ -14,7 +14,7 @@ namespace Lucene class MySegmentTermDocs : public SegmentTermDocs { public: - MySegmentTermDocs(SegmentReaderPtr p); + MySegmentTermDocs(const SegmentReaderPtr& p); virtual ~MySegmentTermDocs(); LUCENE_CLASS(MySegmentTermDocs); @@ -23,7 +23,7 @@ namespace Lucene int32_t delCount; public: - virtual void seek(TermPtr term); + virtual void seek(const TermPtr& term); virtual void skippingDoc(); }; } diff --git a/src/core/include/_ConcurrentMergeScheduler.h b/src/core/include/_ConcurrentMergeScheduler.h index 69568ebf..cde81c8d 100644 --- a/src/core/include/_ConcurrentMergeScheduler.h +++ b/src/core/include/_ConcurrentMergeScheduler.h @@ -14,7 +14,7 @@ namespace Lucene class MergeThread : public LuceneThread { public: - MergeThread(ConcurrentMergeSchedulerPtr merger, IndexWriterPtr writer, OneMergePtr startMerge); + MergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge); virtual ~MergeThread(); LUCENE_CLASS(MergeThread); @@ -26,7 +26,7 @@ namespace Lucene OneMergePtr runningMerge; public: - void setRunningMerge(OneMergePtr merge); + void setRunningMerge(const OneMergePtr& merge); OneMergePtr getRunningMerge(); void setThreadPriority(int32_t pri); virtual void run(); diff --git a/src/core/include/_ConstantScoreQuery.h b/src/core/include/_ConstantScoreQuery.h index 46c0a9cb..0e7acc90 100644 --- a/src/core/include/_ConstantScoreQuery.h +++ b/src/core/include/_ConstantScoreQuery.h @@ -14,7 +14,7 @@ namespace Lucene class ConstantWeight : public Weight { public: - ConstantWeight(ConstantScoreQueryPtr constantScorer, SearcherPtr searcher); + ConstantWeight(const ConstantScoreQueryPtr& constantScorer, const SearcherPtr& searcher); virtual ~ConstantWeight(); LUCENE_CLASS(ConstantWeight); @@ -30,14 +30,14 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); }; class ConstantScorer : public Scorer { public: - ConstantScorer(ConstantScoreQueryPtr constantScorer, SimilarityPtr similarity, IndexReaderPtr reader, WeightPtr w); + ConstantScorer(const ConstantScoreQueryPtr& constantScorer, const SimilarityPtr& similarity, const IndexReaderPtr& reader, const WeightPtr& w); virtual ~ConstantScorer(); LUCENE_CLASS(ConstantScorer); diff --git a/src/core/include/_CustomScoreQuery.h b/src/core/include/_CustomScoreQuery.h index 3c7d71e7..00d5fb6b 100644 --- a/src/core/include/_CustomScoreQuery.h +++ b/src/core/include/_CustomScoreQuery.h @@ -17,7 +17,7 @@ namespace Lucene class DefaultCustomScoreProvider : public CustomScoreProvider { public: - DefaultCustomScoreProvider(CustomScoreQueryPtr customQuery, IndexReaderPtr reader); + DefaultCustomScoreProvider(const CustomScoreQueryPtr& customQuery, const IndexReaderPtr& reader); virtual ~DefaultCustomScoreProvider(); LUCENE_CLASS(DefaultCustomScoreProvider); @@ -28,14 +28,14 @@ namespace Lucene public: virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls); - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); }; class CustomWeight : public Weight { public: - CustomWeight(CustomScoreQueryPtr query, SearcherPtr searcher); + CustomWeight(const CustomScoreQueryPtr& query, const SearcherPtr& searcher); virtual ~CustomWeight(); LUCENE_CLASS(CustomWeight); @@ -52,19 +52,19 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); virtual bool scoresDocsOutOfOrder(); protected: - ExplanationPtr doExplain(IndexReaderPtr reader, int32_t doc); + ExplanationPtr doExplain(const IndexReaderPtr& reader, int32_t doc); }; /// A scorer that applies a (callback) function on scores of the subQuery. class CustomScorer : public Scorer { public: - CustomScorer(SimilarityPtr similarity, IndexReaderPtr reader, CustomWeightPtr weight, ScorerPtr subQueryScorer, Collection valSrcScorers); + CustomScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const CustomWeightPtr& weight, const ScorerPtr& subQueryScorer, Collection valSrcScorers); virtual ~CustomScorer(); LUCENE_CLASS(CustomScorer); diff --git a/src/core/include/_DirectoryReader.h b/src/core/include/_DirectoryReader.h index 0d240d4e..b686d32d 100644 --- a/src/core/include/_DirectoryReader.h +++ b/src/core/include/_DirectoryReader.h @@ -14,7 +14,7 @@ namespace Lucene class FindSegmentsOpen : public FindSegmentsFileT { public: - FindSegmentsOpen(bool readOnly, IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor, SegmentInfosPtr infos, DirectoryPtr directory); + FindSegmentsOpen(bool readOnly, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor, const SegmentInfosPtr& infos, const DirectoryPtr& directory); virtual ~FindSegmentsOpen(); LUCENE_CLASS(FindSegmentsOpen); @@ -31,7 +31,7 @@ namespace Lucene class FindSegmentsReopen : public FindSegmentsFileT { public: - FindSegmentsReopen(DirectoryReaderPtr reader, bool openReadOnly, SegmentInfosPtr infos, DirectoryPtr directory); + FindSegmentsReopen(const DirectoryReaderPtr& reader, bool openReadOnly, const SegmentInfosPtr& infos, const DirectoryPtr& directory); virtual ~FindSegmentsReopen(); LUCENE_CLASS(FindSegmentsReopen); diff --git a/src/core/include/_DisjunctionMaxQuery.h b/src/core/include/_DisjunctionMaxQuery.h index dde594fe..ff90f898 100644 --- a/src/core/include/_DisjunctionMaxQuery.h +++ b/src/core/include/_DisjunctionMaxQuery.h @@ -16,7 +16,7 @@ namespace Lucene { public: /// Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. - DisjunctionMaxWeight(DisjunctionMaxQueryPtr query, SearcherPtr searcher); + DisjunctionMaxWeight(const DisjunctionMaxQueryPtr& query, const SearcherPtr& searcher); virtual ~DisjunctionMaxWeight(); LUCENE_CLASS(DisjunctionMaxWeight); @@ -44,10 +44,10 @@ namespace Lucene virtual void normalize(double norm); /// Create the scorer used to score our associated DisjunctionMaxQuery - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); /// Explain the score we computed for doc - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); }; } diff --git a/src/core/include/_DocIdBitSet.h b/src/core/include/_DocIdBitSet.h index 9ffff066..24f3657b 100644 --- a/src/core/include/_DocIdBitSet.h +++ b/src/core/include/_DocIdBitSet.h @@ -14,7 +14,7 @@ namespace Lucene class DocIdBitSetIterator : public DocIdSetIterator { public: - DocIdBitSetIterator(BitSetPtr bitSet); + DocIdBitSetIterator(const BitSetPtr& bitSet); virtual ~DocIdBitSetIterator(); LUCENE_CLASS(DocIdBitSetIterator); diff --git a/src/core/include/_FieldCacheRangeFilter.h b/src/core/include/_FieldCacheRangeFilter.h index ddf2a759..5542b5f8 100644 --- a/src/core/include/_FieldCacheRangeFilter.h +++ b/src/core/include/_FieldCacheRangeFilter.h @@ -18,7 +18,7 @@ namespace Lucene class FieldCacheRangeFilterString : public FieldCacheRangeFilter { public: - FieldCacheRangeFilterString(const String& field, ParserPtr parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); + FieldCacheRangeFilterString(const String& field, const ParserPtr& parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterString(); LUCENE_CLASS(FieldCacheRangeFilterString); @@ -28,17 +28,17 @@ namespace Lucene String upperVal; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); virtual String toString(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); }; class FieldCacheDocIdSet : public DocIdSet { public: - FieldCacheDocIdSet(IndexReaderPtr reader, bool mayUseTermDocs); + FieldCacheDocIdSet(const IndexReaderPtr& reader, bool mayUseTermDocs); virtual ~FieldCacheDocIdSet(); LUCENE_CLASS(FieldCacheDocIdSet); @@ -61,7 +61,7 @@ namespace Lucene class FieldCacheDocIdSetNumeric : public FieldCacheDocIdSet { public: - FieldCacheDocIdSetNumeric(IndexReaderPtr reader, bool mayUseTermDocs, Collection values, TYPE inclusiveLowerPoint, TYPE inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) + FieldCacheDocIdSetNumeric(const IndexReaderPtr& reader, bool mayUseTermDocs, Collection values, TYPE inclusiveLowerPoint, TYPE inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) { this->values = values; this->inclusiveLowerPoint = inclusiveLowerPoint; @@ -90,7 +90,7 @@ namespace Lucene class FieldCacheRangeFilterNumeric : public FieldCacheRangeFilter { public: - FieldCacheRangeFilterNumeric(const String& field, ParserPtr parser, TYPE lowerVal, TYPE upperVal, TYPE maxVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) + FieldCacheRangeFilterNumeric(const String& field, const ParserPtr& parser, TYPE lowerVal, TYPE upperVal, TYPE maxVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) { this->lowerVal = lowerVal; this->upperVal = upperVal; @@ -107,7 +107,7 @@ namespace Lucene TYPE maxVal; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { if (!includeLower && lowerVal == maxVal) return DocIdSet::EMPTY_DOCIDSET(); @@ -124,7 +124,7 @@ namespace Lucene return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); } - virtual Collection getValues(IndexReaderPtr reader) = 0; + virtual Collection getValues(const IndexReaderPtr& reader) = 0; virtual String toString() { @@ -135,7 +135,7 @@ namespace Lucene return buffer.str(); } - virtual bool equals(LuceneObjectPtr other) + virtual bool equals(const LuceneObjectPtr& other) { if (Filter::equals(other)) return true; @@ -166,56 +166,56 @@ namespace Lucene class FieldCacheRangeFilterByte : public FieldCacheRangeFilterNumeric { public: - FieldCacheRangeFilterByte(const String& field, ParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); + FieldCacheRangeFilterByte(const String& field, const ParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterByte(); LUCENE_CLASS(FieldCacheRangeFilterByte); public: - virtual Collection getValues(IndexReaderPtr reader); + virtual Collection getValues(const IndexReaderPtr& reader); }; class FieldCacheRangeFilterInt : public FieldCacheRangeFilterNumeric { public: - FieldCacheRangeFilterInt(const String& field, ParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); + FieldCacheRangeFilterInt(const String& field, const ParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterInt(); LUCENE_CLASS(FieldCacheRangeFilterInt); public: - virtual Collection getValues(IndexReaderPtr reader); + virtual Collection getValues(const IndexReaderPtr& reader); }; class FieldCacheRangeFilterLong : public FieldCacheRangeFilterNumeric { public: - FieldCacheRangeFilterLong(const String& field, ParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); + FieldCacheRangeFilterLong(const String& field, const ParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterLong(); LUCENE_CLASS(FieldCacheRangeFilterLong); public: - virtual Collection getValues(IndexReaderPtr reader); + virtual Collection getValues(const IndexReaderPtr& reader); }; class FieldCacheRangeFilterDouble : public FieldCacheRangeFilterNumeric { public: - FieldCacheRangeFilterDouble(const String& field, ParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); + FieldCacheRangeFilterDouble(const String& field, const ParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); virtual ~FieldCacheRangeFilterDouble(); LUCENE_CLASS(FieldCacheRangeFilterDouble); public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); - virtual Collection getValues(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + virtual Collection getValues(const IndexReaderPtr& reader); }; class FieldCacheDocIdSetString : public FieldCacheDocIdSet { public: - FieldCacheDocIdSetString(IndexReaderPtr reader, bool mayUseTermDocs, StringIndexPtr fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint); + FieldCacheDocIdSetString(const IndexReaderPtr& reader, bool mayUseTermDocs, const StringIndexPtr& fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint); virtual ~FieldCacheDocIdSetString(); LUCENE_CLASS(FieldCacheDocIdSetString); @@ -233,7 +233,7 @@ namespace Lucene class FieldDocIdSetIteratorTermDocs : public DocIdSetIterator { public: - FieldDocIdSetIteratorTermDocs(FieldCacheDocIdSetPtr cacheDocIdSet, TermDocsPtr termDocs); + FieldDocIdSetIteratorTermDocs(const FieldCacheDocIdSetPtr& cacheDocIdSet, const TermDocsPtr& termDocs); virtual ~FieldDocIdSetIteratorTermDocs(); LUCENE_CLASS(FieldDocIdSetIteratorTermDocs); @@ -254,7 +254,7 @@ namespace Lucene class FieldDocIdSetIteratorIncrement : public DocIdSetIterator { public: - FieldDocIdSetIteratorIncrement(FieldCacheDocIdSetPtr cacheDocIdSet); + FieldDocIdSetIteratorIncrement(const FieldCacheDocIdSetPtr& cacheDocIdSet); virtual ~FieldDocIdSetIteratorIncrement(); LUCENE_CLASS(FieldDocIdSetIteratorIncrement); diff --git a/src/core/include/_FieldCacheSanityChecker.h b/src/core/include/_FieldCacheSanityChecker.h index 11ee4941..624c38c0 100644 --- a/src/core/include/_FieldCacheSanityChecker.h +++ b/src/core/include/_FieldCacheSanityChecker.h @@ -15,7 +15,7 @@ namespace Lucene class ReaderField : public LuceneObject { public: - ReaderField(LuceneObjectPtr readerKey, const String& fieldName); + ReaderField(const LuceneObjectPtr& readerKey, const String& fieldName); virtual ~ReaderField(); LUCENE_CLASS(ReaderField); @@ -26,7 +26,7 @@ namespace Lucene public: virtual int32_t hashCode(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual String toString(); }; } diff --git a/src/core/include/_FieldCacheTermsFilter.h b/src/core/include/_FieldCacheTermsFilter.h index 808c3e4b..14310f7e 100644 --- a/src/core/include/_FieldCacheTermsFilter.h +++ b/src/core/include/_FieldCacheTermsFilter.h @@ -15,7 +15,7 @@ namespace Lucene class FieldCacheTermsFilterDocIdSet : public DocIdSet { public: - FieldCacheTermsFilterDocIdSet(Collection terms, StringIndexPtr fcsi); + FieldCacheTermsFilterDocIdSet(Collection terms, const StringIndexPtr& fcsi); virtual ~FieldCacheTermsFilterDocIdSet(); LUCENE_CLASS(FieldCacheTermsFilterDocIdSet); @@ -34,7 +34,7 @@ namespace Lucene class FieldCacheTermsFilterDocIdSetIterator : public DocIdSetIterator { public: - FieldCacheTermsFilterDocIdSetIterator(StringIndexPtr fcsi, OpenBitSetPtr openBitSet); + FieldCacheTermsFilterDocIdSetIterator(const StringIndexPtr& fcsi, const OpenBitSetPtr& openBitSet); virtual ~FieldCacheTermsFilterDocIdSetIterator(); LUCENE_CLASS(FieldCacheTermsFilterDocIdSetIterator); diff --git a/src/core/include/_FilterManager.h b/src/core/include/_FilterManager.h index c981909e..1e1f3d41 100644 --- a/src/core/include/_FilterManager.h +++ b/src/core/include/_FilterManager.h @@ -15,7 +15,7 @@ namespace Lucene class FilterItem : public LuceneObject { public: - FilterItem(FilterPtr filter); + FilterItem(const FilterPtr& filter); virtual ~FilterItem(); LUCENE_CLASS(FilterItem); @@ -37,7 +37,7 @@ namespace Lucene class FilterCleaner : public LuceneThread { public: - FilterCleaner(FilterManagerPtr manager); + FilterCleaner(const FilterManagerPtr& manager); virtual ~FilterCleaner(); LUCENE_CLASS(FilterCleaner); diff --git a/src/core/include/_FilteredDocIdSet.h b/src/core/include/_FilteredDocIdSet.h index 033e30f3..d2f7b0b3 100644 --- a/src/core/include/_FilteredDocIdSet.h +++ b/src/core/include/_FilteredDocIdSet.h @@ -15,7 +15,7 @@ namespace Lucene class DefaultFilteredDocIdSetIterator : public FilteredDocIdSetIterator { public: - DefaultFilteredDocIdSetIterator(FilteredDocIdSetPtr filtered, DocIdSetIteratorPtr innerIter); + DefaultFilteredDocIdSetIterator(const FilteredDocIdSetPtr& filtered, const DocIdSetIteratorPtr& innerIter); virtual ~DefaultFilteredDocIdSetIterator(); LUCENE_CLASS(DefaultFilteredDocIdSetIterator); diff --git a/src/core/include/_FilteredQuery.h b/src/core/include/_FilteredQuery.h index d74b8ed2..83ca70e6 100644 --- a/src/core/include/_FilteredQuery.h +++ b/src/core/include/_FilteredQuery.h @@ -15,7 +15,7 @@ namespace Lucene class FilteredQueryWeight : public Weight { public: - FilteredQueryWeight(FilteredQueryPtr query, WeightPtr weight, SimilarityPtr similarity); + FilteredQueryWeight(const FilteredQueryPtr& query, const WeightPtr& weight, const SimilarityPtr& similarity); virtual ~FilteredQueryWeight(); LUCENE_CLASS(FilteredQueryWeight); @@ -30,9 +30,9 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); virtual QueryPtr getQuery(); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); friend class FilteredQueryWeightScorer; }; @@ -40,7 +40,7 @@ namespace Lucene class FilteredQueryWeightScorer : public Scorer { public: - FilteredQueryWeightScorer(FilteredQueryWeightPtr weight, ScorerPtr scorer, DocIdSetIteratorPtr docIdSetIterator, SimilarityPtr similarity); + FilteredQueryWeightScorer(const FilteredQueryWeightPtr& weight, const ScorerPtr& scorer, const DocIdSetIteratorPtr& docIdSetIterator, const SimilarityPtr& similarity); virtual ~FilteredQueryWeightScorer(); LUCENE_CLASS(FilteredQueryWeightScorer); diff --git a/src/core/include/_FuzzyQuery.h b/src/core/include/_FuzzyQuery.h index a5ecc6fb..db71aa0f 100644 --- a/src/core/include/_FuzzyQuery.h +++ b/src/core/include/_FuzzyQuery.h @@ -22,7 +22,7 @@ namespace Lucene double score; public: - int32_t compareTo(ScoreTermPtr other); + int32_t compareTo(const ScoreTermPtr& other); }; class ScoreTermQueue : public PriorityQueue diff --git a/src/core/include/_IndexReader.h b/src/core/include/_IndexReader.h index ac243c7a..9ead99b5 100644 --- a/src/core/include/_IndexReader.h +++ b/src/core/include/_IndexReader.h @@ -14,7 +14,7 @@ namespace Lucene class FindSegmentsModified : public FindSegmentsFileT { public: - FindSegmentsModified(SegmentInfosPtr infos, DirectoryPtr directory); + FindSegmentsModified(const SegmentInfosPtr& infos, const DirectoryPtr& directory); virtual ~FindSegmentsModified(); LUCENE_CLASS(FindSegmentsModified); diff --git a/src/core/include/_IndexWriter.h b/src/core/include/_IndexWriter.h index 93b59477..d337ec06 100644 --- a/src/core/include/_IndexWriter.h +++ b/src/core/include/_IndexWriter.h @@ -17,7 +17,7 @@ namespace Lucene class ReaderPool : public LuceneObject { public: - ReaderPool(IndexWriterPtr writer); + ReaderPool(const IndexWriterPtr& writer); virtual ~ReaderPool(); LUCENE_CLASS(ReaderPool); @@ -29,17 +29,17 @@ namespace Lucene public: /// Forcefully clear changes for the specified segments, and remove from the pool. /// This is called on successful merge. - void clear(SegmentInfosPtr infos); + void clear(const SegmentInfosPtr& infos); /// used only by asserts - bool infoIsLive(SegmentInfoPtr info); - SegmentInfoPtr mapToLive(SegmentInfoPtr info); + bool infoIsLive(const SegmentInfoPtr& info); + SegmentInfoPtr mapToLive(const SegmentInfoPtr& info); /// Release the segment reader (i.e. decRef it and close if there are no more references. - void release(SegmentReaderPtr sr); + void release(const SegmentReaderPtr& sr); /// Release the segment reader (i.e. decRef it and close if there are no more references. - void release(SegmentReaderPtr sr, bool drop); + void release(const SegmentReaderPtr& sr, bool drop); /// Remove all our references to readers, and commits any pending changes. void close(); @@ -49,18 +49,18 @@ namespace Lucene /// Returns a ref to a clone. NOTE: this clone is not enrolled in the pool, so you should /// simply close() it when you're done (ie, do not call release()). - IndexReaderPtr getReadOnlyClone(const SegmentInfoPtr info, bool doOpenStores, int32_t termInfosIndexDivisor); + IndexReaderPtr getReadOnlyClone(const SegmentInfoPtr& info, bool doOpenStores, int32_t termInfosIndexDivisor); /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling /// {@link #release(SegmentReader)} - SegmentReaderPtr get(SegmentInfoPtr info, bool doOpenStores); + SegmentReaderPtr get(const SegmentInfoPtr& info, bool doOpenStores); /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling /// {@link #release(SegmentReader)} - SegmentReaderPtr get(SegmentInfoPtr info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor); + SegmentReaderPtr get(const SegmentInfoPtr& info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor); /// Returns a ref - SegmentReaderPtr getIfExists(SegmentInfoPtr info); + SegmentReaderPtr getIfExists(const SegmentInfoPtr& info); }; } diff --git a/src/core/include/_IntFieldSource.h b/src/core/include/_IntFieldSource.h index b7227da3..061a7ff0 100644 --- a/src/core/include/_IntFieldSource.h +++ b/src/core/include/_IntFieldSource.h @@ -14,7 +14,7 @@ namespace Lucene class IntDocValues : public DocValues { public: - IntDocValues(IntFieldSourcePtr source, Collection arr); + IntDocValues(const IntFieldSourcePtr& source, Collection arr); virtual ~IntDocValues(); LUCENE_CLASS(IntDocValues); diff --git a/src/core/include/_MMapDirectory.h b/src/core/include/_MMapDirectory.h index 9778ea8c..ccb44242 100644 --- a/src/core/include/_MMapDirectory.h +++ b/src/core/include/_MMapDirectory.h @@ -53,7 +53,7 @@ namespace Lucene virtual void close(); /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/src/core/include/_MatchAllDocsQuery.h b/src/core/include/_MatchAllDocsQuery.h index 1c91e2ad..ce5edccb 100644 --- a/src/core/include/_MatchAllDocsQuery.h +++ b/src/core/include/_MatchAllDocsQuery.h @@ -15,7 +15,7 @@ namespace Lucene class MatchAllDocsWeight : public Weight { public: - MatchAllDocsWeight(MatchAllDocsQueryPtr query, SearcherPtr searcher); + MatchAllDocsWeight(const MatchAllDocsQueryPtr& query, const SearcherPtr& searcher); virtual ~MatchAllDocsWeight(); LUCENE_CLASS(MatchAllDocsWeight); @@ -32,14 +32,14 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); }; class MatchAllScorer : public Scorer { public: - MatchAllScorer(MatchAllDocsQueryPtr query, IndexReaderPtr reader, SimilarityPtr similarity, WeightPtr weight, ByteArray norms); + MatchAllScorer(const MatchAllDocsQueryPtr& query, const IndexReaderPtr& reader, const SimilarityPtr& similarity, const WeightPtr& weight, ByteArray norms); virtual ~MatchAllScorer(); LUCENE_CLASS(MatchAllScorer); diff --git a/src/core/include/_MultiPhraseQuery.h b/src/core/include/_MultiPhraseQuery.h index 60748c83..b211e4a9 100644 --- a/src/core/include/_MultiPhraseQuery.h +++ b/src/core/include/_MultiPhraseQuery.h @@ -14,7 +14,7 @@ namespace Lucene class MultiPhraseWeight : public Weight { public: - MultiPhraseWeight(MultiPhraseQueryPtr query, SearcherPtr searcher); + MultiPhraseWeight(const MultiPhraseQueryPtr& query, const SearcherPtr& searcher); virtual ~MultiPhraseWeight(); LUCENE_CLASS(MultiPhraseWeight); @@ -32,8 +32,8 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); }; } diff --git a/src/core/include/_MultiSearcher.h b/src/core/include/_MultiSearcher.h index 02d2c4c4..0bb85761 100644 --- a/src/core/include/_MultiSearcher.h +++ b/src/core/include/_MultiSearcher.h @@ -17,7 +17,7 @@ namespace Lucene class CachedDfSource : public Searcher { public: - CachedDfSource(MapTermInt dfMap, int32_t maxDoc, SimilarityPtr similarity); + CachedDfSource(MapTermInt dfMap, int32_t maxDoc, const SimilarityPtr& similarity); virtual ~CachedDfSource(); LUCENE_CLASS(CachedDfSource); @@ -27,25 +27,25 @@ namespace Lucene int32_t _maxDoc; // document count public: - virtual int32_t docFreq(TermPtr term); + virtual int32_t docFreq(const TermPtr& term); virtual Collection docFreqs(Collection terms); virtual int32_t maxDoc(); - virtual QueryPtr rewrite(QueryPtr query); + virtual QueryPtr rewrite(const QueryPtr& query); virtual void close(); virtual DocumentPtr doc(int32_t n); - virtual DocumentPtr doc(int32_t n, FieldSelectorPtr fieldSelector); - virtual ExplanationPtr explain(WeightPtr weight, int32_t doc); - virtual void search(WeightPtr weight, FilterPtr filter, CollectorPtr results); - virtual TopDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n); - virtual TopFieldDocsPtr search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort); + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); }; /// A subclass for searching a single searchable class MultiSearcherCallableNoSort : public LuceneObject { public: - MultiSearcherCallableNoSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, FilterPtr filter, int32_t nDocs, - HitQueuePtr hq, int32_t i, Collection starts); + MultiSearcherCallableNoSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, const FilterPtr& filter, int32_t nDocs, + const HitQueuePtr& hq, int32_t i, Collection starts); virtual ~MultiSearcherCallableNoSort(); LUCENE_CLASS(MultiSearcherCallableNoSort); @@ -68,8 +68,8 @@ namespace Lucene class MultiSearcherCallableWithSort : public LuceneObject { public: - MultiSearcherCallableWithSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, FilterPtr filter, - int32_t nDocs, FieldDocSortedHitQueuePtr hq, SortPtr sort, int32_t i, Collection starts); + MultiSearcherCallableWithSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, const FilterPtr& filter, + int32_t nDocs, const FieldDocSortedHitQueuePtr& hq, const SortPtr& sort, int32_t i, Collection starts); virtual ~MultiSearcherCallableWithSort(); LUCENE_CLASS(MultiSearcherCallableWithSort); @@ -92,7 +92,7 @@ namespace Lucene class MultiSearcherCollector : public Collector { public: - MultiSearcherCollector(CollectorPtr collector, int32_t start); + MultiSearcherCollector(const CollectorPtr& collector, int32_t start); virtual ~MultiSearcherCollector(); LUCENE_CLASS(MultiSearcherCollector); @@ -102,9 +102,9 @@ namespace Lucene int32_t start; public: - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); virtual void collect(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); virtual bool acceptsDocsOutOfOrder(); }; } diff --git a/src/core/include/_MultiTermQuery.h b/src/core/include/_MultiTermQuery.h index 5ee5695d..0d3bcb91 100644 --- a/src/core/include/_MultiTermQuery.h +++ b/src/core/include/_MultiTermQuery.h @@ -18,7 +18,7 @@ namespace Lucene LUCENE_CLASS(ConstantScoreFilterRewrite); public: - virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query); + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); }; class ScoringBooleanQueryRewrite : public RewriteMethod @@ -28,7 +28,7 @@ namespace Lucene LUCENE_CLASS(ScoringBooleanQueryRewrite); public: - virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query); + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); }; class ConstantScoreBooleanQueryRewrite : public ScoringBooleanQueryRewrite @@ -38,7 +38,7 @@ namespace Lucene LUCENE_CLASS(ConstantScoreBooleanQueryRewrite); public: - virtual QueryPtr rewrite(IndexReaderPtr reader, MultiTermQueryPtr query); + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); }; class ConstantScoreAutoRewriteDefault : public ConstantScoreAutoRewrite diff --git a/src/core/include/_NearSpansUnordered.h b/src/core/include/_NearSpansUnordered.h index 16f184a9..932f8622 100644 --- a/src/core/include/_NearSpansUnordered.h +++ b/src/core/include/_NearSpansUnordered.h @@ -16,7 +16,7 @@ namespace Lucene class SpansCell : public Spans { public: - SpansCell(NearSpansUnorderedPtr unordered, SpansPtr spans, int32_t index); + SpansCell(const NearSpansUnorderedPtr& unordered, const SpansPtr& spans, int32_t index); virtual ~SpansCell(); LUCENE_CLASS(SpansCell); diff --git a/src/core/include/_NumericRangeQuery.h b/src/core/include/_NumericRangeQuery.h index 158b3477..bc2e2c62 100644 --- a/src/core/include/_NumericRangeQuery.h +++ b/src/core/include/_NumericRangeQuery.h @@ -20,7 +20,7 @@ namespace Lucene class NumericRangeTermEnum : public FilteredTermEnum { public: - NumericRangeTermEnum(NumericRangeQueryPtr query, IndexReaderPtr reader); + NumericRangeTermEnum(const NumericRangeQueryPtr& query, const IndexReaderPtr& reader); virtual ~NumericRangeTermEnum(); LUCENE_CLASS(NumericRangeTermEnum); @@ -46,12 +46,12 @@ namespace Lucene virtual bool endEnum(); /// This is a dummy, it is not used by this class. - virtual void setEnum(TermEnumPtr actualEnum); + virtual void setEnum(const TermEnumPtr& actualEnum); /// Compares if current upper bound is reached, this also updates the term count for statistics. /// In contrast to {@link FilteredTermEnum}, a return value of false ends iterating the current enum /// and forwards to the next sub-range. - virtual bool termCompare(TermPtr term); + virtual bool termCompare(const TermPtr& term); }; class NumericLongRangeBuilder : public LongRangeBuilder diff --git a/src/core/include/_OrdFieldSource.h b/src/core/include/_OrdFieldSource.h index 1cafad0b..77fb6f4b 100644 --- a/src/core/include/_OrdFieldSource.h +++ b/src/core/include/_OrdFieldSource.h @@ -14,7 +14,7 @@ namespace Lucene class LPPAPI OrdDocValues : public DocValues { public: - OrdDocValues(OrdFieldSourcePtr source, Collection arr); + OrdDocValues(const OrdFieldSourcePtr& source, Collection arr); virtual ~OrdDocValues(); LUCENE_CLASS(OrdDocValues); diff --git a/src/core/include/_ParallelReader.h b/src/core/include/_ParallelReader.h index 76b86942..8263d57b 100644 --- a/src/core/include/_ParallelReader.h +++ b/src/core/include/_ParallelReader.h @@ -16,8 +16,8 @@ namespace Lucene class ParallelTermEnum : public TermEnum { public: - ParallelTermEnum(ParallelReaderPtr reader); - ParallelTermEnum(ParallelReaderPtr reader, TermPtr term); + ParallelTermEnum(const ParallelReaderPtr& reader); + ParallelTermEnum(const ParallelReaderPtr& reader, const TermPtr& term); virtual ~ParallelTermEnum(); LUCENE_CLASS(ParallelTermEnum); @@ -47,8 +47,8 @@ namespace Lucene class ParallelTermDocs : public TermPositions, public LuceneObject { public: - ParallelTermDocs(ParallelReaderPtr reader); - ParallelTermDocs(ParallelReaderPtr reader, TermPtr term); + ParallelTermDocs(const ParallelReaderPtr& reader); + ParallelTermDocs(const ParallelReaderPtr& reader, const TermPtr& term); virtual ~ParallelTermDocs(); LUCENE_CLASS(ParallelTermDocs); @@ -60,8 +60,8 @@ namespace Lucene public: virtual int32_t doc(); virtual int32_t freq(); - virtual void seek(TermPtr term); - virtual void seek(TermEnumPtr termEnum); + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); virtual bool next(); virtual int32_t read(Collection docs, Collection freqs); virtual bool skipTo(int32_t target); @@ -71,14 +71,14 @@ namespace Lucene class ParallelTermPositions : public ParallelTermDocs { public: - ParallelTermPositions(ParallelReaderPtr reader); - ParallelTermPositions(ParallelReaderPtr reader, TermPtr term); + ParallelTermPositions(const ParallelReaderPtr& reader); + ParallelTermPositions(const ParallelReaderPtr& reader, const TermPtr& term); virtual ~ParallelTermPositions(); LUCENE_CLASS(ParallelTermPositions); public: - virtual void seek(TermPtr term); + virtual void seek(const TermPtr& term); virtual int32_t nextPosition(); virtual int32_t getPayloadLength(); virtual ByteArray getPayload(ByteArray data, int32_t offset); diff --git a/src/core/include/_PayloadTermQuery.h b/src/core/include/_PayloadTermQuery.h index 395850c8..d441c58c 100644 --- a/src/core/include/_PayloadTermQuery.h +++ b/src/core/include/_PayloadTermQuery.h @@ -15,19 +15,19 @@ namespace Lucene class PayloadTermWeight : public SpanWeight { public: - PayloadTermWeight(PayloadTermQueryPtr query, SearcherPtr searcher); + PayloadTermWeight(const PayloadTermQueryPtr& query, const SearcherPtr& searcher); virtual ~PayloadTermWeight(); LUCENE_CLASS(PayloadTermWeight); public: - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); }; class PayloadTermSpanScorer : public SpanScorer { public: - PayloadTermSpanScorer(TermSpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms); + PayloadTermSpanScorer(const TermSpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); virtual ~PayloadTermSpanScorer(); LUCENE_CLASS(PayloadTermSpanScorer); @@ -44,7 +44,7 @@ namespace Lucene protected: virtual bool setFreqCurrentDoc(); - void processPayload(SimilarityPtr similarity); + void processPayload(const SimilarityPtr& similarity); /// Returns the SpanScorer score only. /// diff --git a/src/core/include/_PhraseQuery.h b/src/core/include/_PhraseQuery.h index 34cd9516..a4b654c8 100644 --- a/src/core/include/_PhraseQuery.h +++ b/src/core/include/_PhraseQuery.h @@ -14,7 +14,7 @@ namespace Lucene class PhraseWeight : public Weight { public: - PhraseWeight(PhraseQueryPtr query, SearcherPtr searcher); + PhraseWeight(const PhraseQueryPtr& query, const SearcherPtr& searcher); virtual ~PhraseWeight(); LUCENE_CLASS(PhraseWeight); @@ -34,8 +34,8 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); }; } diff --git a/src/core/include/_QueryWrapperFilter.h b/src/core/include/_QueryWrapperFilter.h index e78f1209..87d104fe 100644 --- a/src/core/include/_QueryWrapperFilter.h +++ b/src/core/include/_QueryWrapperFilter.h @@ -14,7 +14,7 @@ namespace Lucene class QueryWrapperFilterDocIdSet : public DocIdSet { public: - QueryWrapperFilterDocIdSet(IndexReaderPtr reader, WeightPtr weight); + QueryWrapperFilterDocIdSet(const IndexReaderPtr& reader, const WeightPtr& weight); virtual ~QueryWrapperFilterDocIdSet(); LUCENE_CLASS(QueryWrapperFilterDocIdSet); diff --git a/src/core/include/_ReverseOrdFieldSource.h b/src/core/include/_ReverseOrdFieldSource.h index 0528cb8a..24573066 100644 --- a/src/core/include/_ReverseOrdFieldSource.h +++ b/src/core/include/_ReverseOrdFieldSource.h @@ -14,7 +14,7 @@ namespace Lucene class ReverseOrdDocValues : public DocValues { public: - ReverseOrdDocValues(ReverseOrdFieldSourcePtr source, Collection arr, int32_t end); + ReverseOrdDocValues(const ReverseOrdFieldSourcePtr& source, Collection arr, int32_t end); virtual ~ReverseOrdDocValues(); LUCENE_CLASS(ReverseOrdDocValues); diff --git a/src/core/include/_ScorerDocQueue.h b/src/core/include/_ScorerDocQueue.h index bc04370c..04663372 100644 --- a/src/core/include/_ScorerDocQueue.h +++ b/src/core/include/_ScorerDocQueue.h @@ -14,8 +14,8 @@ namespace Lucene class HeapedScorerDoc : public LuceneObject { public: - HeapedScorerDoc(ScorerPtr scorer); - HeapedScorerDoc(ScorerPtr scorer, int32_t doc); + HeapedScorerDoc(const ScorerPtr& scorer); + HeapedScorerDoc(const ScorerPtr& scorer, int32_t doc); virtual ~HeapedScorerDoc(); LUCENE_CLASS(HeapedScorerDoc); diff --git a/src/core/include/_SegmentInfos.h b/src/core/include/_SegmentInfos.h index 9e8db102..12c78592 100644 --- a/src/core/include/_SegmentInfos.h +++ b/src/core/include/_SegmentInfos.h @@ -15,7 +15,7 @@ namespace Lucene class FindSegmentsFile : public LuceneObject { public: - FindSegmentsFile(SegmentInfosPtr infos, DirectoryPtr directory); + FindSegmentsFile(const SegmentInfosPtr& infos, const DirectoryPtr& directory); virtual ~FindSegmentsFile(); LUCENE_CLASS(FindSegmentsFile); @@ -25,7 +25,7 @@ namespace Lucene DirectoryPtr directory; public: - void doRun(IndexCommitPtr commit = IndexCommitPtr()); + void doRun(const IndexCommitPtr& commit = IndexCommitPtr()); virtual void runBody(const String& segmentFileName) = 0; }; @@ -33,14 +33,14 @@ namespace Lucene class FindSegmentsFileT : public FindSegmentsFile { public: - FindSegmentsFileT(SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFile(infos, directory) {} + FindSegmentsFileT(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFile(infos, directory) {} virtual ~FindSegmentsFileT() {} protected: TYPE result; public: - virtual TYPE run(IndexCommitPtr commit = IndexCommitPtr()) + virtual TYPE run(const IndexCommitPtr& commit = IndexCommitPtr()) { doRun(commit); return result; @@ -60,7 +60,7 @@ namespace Lucene class FindSegmentsRead : public FindSegmentsFileT { public: - FindSegmentsRead(SegmentInfosPtr infos, DirectoryPtr directory); + FindSegmentsRead(const SegmentInfosPtr& infos, const DirectoryPtr& directory); virtual ~FindSegmentsRead(); LUCENE_CLASS(FindSegmentsRead); diff --git a/src/core/include/_SegmentReader.h b/src/core/include/_SegmentReader.h index 5712ea62..fefca9fd 100644 --- a/src/core/include/_SegmentReader.h +++ b/src/core/include/_SegmentReader.h @@ -15,7 +15,7 @@ namespace Lucene class CoreReaders : public LuceneObject { public: - CoreReaders(SegmentReaderPtr origInstance, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, int32_t termsIndexDivisor); + CoreReaders(const SegmentReaderPtr& origInstance, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, int32_t termsIndexDivisor); virtual ~CoreReaders(); LUCENE_CLASS(CoreReaders); @@ -57,9 +57,9 @@ namespace Lucene /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, /// sharing a segment that's still being merged. This method is not fully thread safe, and relies on the /// synchronization in IndexWriter - void loadTermsIndex(SegmentInfoPtr si, int32_t termsIndexDivisor); + void loadTermsIndex(const SegmentInfoPtr& si, int32_t termsIndexDivisor); - void openDocStores(SegmentInfoPtr si); + void openDocStores(const SegmentInfoPtr& si); void decRef(); @@ -70,7 +70,7 @@ namespace Lucene class FieldsReaderLocal : public CloseableThreadLocal { public: - FieldsReaderLocal(SegmentReaderPtr reader); + FieldsReaderLocal(const SegmentReaderPtr& reader); protected: SegmentReaderWeakPtr _reader; @@ -107,7 +107,7 @@ namespace Lucene { public: Norm(); - Norm(SegmentReaderPtr reader, IndexInputPtr in, int32_t number, int64_t normSeek); + Norm(const SegmentReaderPtr& reader, const IndexInputPtr& in, int32_t number, int64_t normSeek); virtual ~Norm(); LUCENE_CLASS(Norm); @@ -147,10 +147,10 @@ namespace Lucene ByteArray copyOnWrite(); /// Returns a copy of this Norm instance that shares IndexInput & bytes with the original one - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); /// Flush all pending changes to the next generation separate norms file. - void reWrite(SegmentInfoPtr si); + void reWrite(const SegmentInfoPtr& si); protected: void closeInput(); diff --git a/src/core/include/_SimpleFSDirectory.h b/src/core/include/_SimpleFSDirectory.h index d2c0d783..6fbf31a5 100644 --- a/src/core/include/_SimpleFSDirectory.h +++ b/src/core/include/_SimpleFSDirectory.h @@ -65,7 +65,7 @@ namespace Lucene bool isValid(); /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; class OutputFile : public LuceneObject diff --git a/src/core/include/_SnapshotDeletionPolicy.h b/src/core/include/_SnapshotDeletionPolicy.h index cf9389de..b53bc5a1 100644 --- a/src/core/include/_SnapshotDeletionPolicy.h +++ b/src/core/include/_SnapshotDeletionPolicy.h @@ -14,7 +14,7 @@ namespace Lucene class MyCommitPoint : public IndexCommit { public: - MyCommitPoint(SnapshotDeletionPolicyPtr deletionPolicy, IndexCommitPtr cp); + MyCommitPoint(const SnapshotDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& cp); virtual ~MyCommitPoint(); LUCENE_CLASS(MyCommitPoint); diff --git a/src/core/include/_SortedVIntList.h b/src/core/include/_SortedVIntList.h index 5a95845e..b641722c 100644 --- a/src/core/include/_SortedVIntList.h +++ b/src/core/include/_SortedVIntList.h @@ -14,7 +14,7 @@ namespace Lucene class SortedDocIdSetIterator : public DocIdSetIterator { public: - SortedDocIdSetIterator(SortedVIntListPtr list); + SortedDocIdSetIterator(const SortedVIntListPtr& list); virtual ~SortedDocIdSetIterator(); LUCENE_CLASS(SortedDocIdSetIterator); diff --git a/src/core/include/_SpanFirstQuery.h b/src/core/include/_SpanFirstQuery.h index 2fd8f035..34b9aae6 100644 --- a/src/core/include/_SpanFirstQuery.h +++ b/src/core/include/_SpanFirstQuery.h @@ -14,7 +14,7 @@ namespace Lucene class FirstSpans : public Spans { public: - FirstSpans(SpanFirstQueryPtr query, SpansPtr spans); + FirstSpans(const SpanFirstQueryPtr& query, const SpansPtr& spans); virtual ~FirstSpans(); LUCENE_CLASS(FirstSpans); diff --git a/src/core/include/_SpanNotQuery.h b/src/core/include/_SpanNotQuery.h index 56489451..95209b7e 100644 --- a/src/core/include/_SpanNotQuery.h +++ b/src/core/include/_SpanNotQuery.h @@ -14,7 +14,7 @@ namespace Lucene class NotSpans : public Spans { public: - NotSpans(SpanNotQueryPtr query, SpansPtr includeSpans, SpansPtr excludeSpans); + NotSpans(const SpanNotQueryPtr& query, const SpansPtr& includeSpans, const SpansPtr& excludeSpans); virtual ~NotSpans(); LUCENE_CLASS(NotSpans); diff --git a/src/core/include/_SpanOrQuery.h b/src/core/include/_SpanOrQuery.h index 9aad3310..6f63875f 100644 --- a/src/core/include/_SpanOrQuery.h +++ b/src/core/include/_SpanOrQuery.h @@ -27,7 +27,7 @@ namespace Lucene class OrSpans : public Spans { public: - OrSpans(SpanOrQueryPtr query, IndexReaderPtr reader); + OrSpans(const SpanOrQueryPtr& query, const IndexReaderPtr& reader); virtual ~OrSpans(); LUCENE_CLASS(OrSpans); diff --git a/src/core/include/_TermQuery.h b/src/core/include/_TermQuery.h index b5ae14f0..d66ce390 100644 --- a/src/core/include/_TermQuery.h +++ b/src/core/include/_TermQuery.h @@ -14,7 +14,7 @@ namespace Lucene class TermWeight : public Weight { public: - TermWeight(TermQueryPtr query, SearcherPtr searcher); + TermWeight(const TermQueryPtr& query, const SearcherPtr& searcher); virtual ~TermWeight(); LUCENE_CLASS(TermWeight); @@ -34,8 +34,8 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); }; } diff --git a/src/core/include/_TopFieldCollector.h b/src/core/include/_TopFieldCollector.h index dd3afbba..fd4d7df1 100644 --- a/src/core/include/_TopFieldCollector.h +++ b/src/core/include/_TopFieldCollector.h @@ -15,7 +15,7 @@ namespace Lucene class OneComparatorNonScoringCollector : public TopFieldCollector { public: - OneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OneComparatorNonScoringCollector(); LUCENE_CLASS(OneComparatorNonScoringCollector); @@ -28,8 +28,8 @@ namespace Lucene virtual void initialize(); virtual void updateBottom(int32_t doc); virtual void collect(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setScorer(ScorerPtr scorer); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); }; /// Implements a TopFieldCollector over one SortField criteria, without tracking document scores and maxScore, @@ -37,7 +37,7 @@ namespace Lucene class OutOfOrderOneComparatorNonScoringCollector : public OneComparatorNonScoringCollector { public: - OutOfOrderOneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OutOfOrderOneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderOneComparatorNonScoringCollector(); LUCENE_CLASS(OutOfOrderOneComparatorNonScoringCollector); @@ -51,7 +51,7 @@ namespace Lucene class OneComparatorScoringNoMaxScoreCollector : public OneComparatorNonScoringCollector { public: - OneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OneComparatorScoringNoMaxScoreCollector(); LUCENE_CLASS(OneComparatorScoringNoMaxScoreCollector); @@ -62,7 +62,7 @@ namespace Lucene public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); }; /// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore, @@ -70,7 +70,7 @@ namespace Lucene class OutOfOrderOneComparatorScoringNoMaxScoreCollector : public OneComparatorScoringNoMaxScoreCollector { public: - OutOfOrderOneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OutOfOrderOneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderOneComparatorScoringNoMaxScoreCollector(); LUCENE_CLASS(OutOfOrderOneComparatorScoringNoMaxScoreCollector); @@ -84,7 +84,7 @@ namespace Lucene class OneComparatorScoringMaxScoreCollector : public OneComparatorNonScoringCollector { public: - OneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OneComparatorScoringMaxScoreCollector(); LUCENE_CLASS(OneComparatorScoringMaxScoreCollector); @@ -95,7 +95,7 @@ namespace Lucene public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); }; /// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore, @@ -103,7 +103,7 @@ namespace Lucene class OutOfOrderOneComparatorScoringMaxScoreCollector : public OneComparatorScoringMaxScoreCollector { public: - OutOfOrderOneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OutOfOrderOneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderOneComparatorScoringMaxScoreCollector(); LUCENE_CLASS(OutOfOrderOneComparatorScoringMaxScoreCollector); @@ -117,7 +117,7 @@ namespace Lucene class MultiComparatorNonScoringCollector : public TopFieldCollector { public: - MultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + MultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~MultiComparatorNonScoringCollector(); LUCENE_CLASS(MultiComparatorNonScoringCollector); @@ -130,15 +130,15 @@ namespace Lucene virtual void initialize(); virtual void updateBottom(int32_t doc); virtual void collect(int32_t doc); - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase); - virtual void setScorer(ScorerPtr scorer); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); }; /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. class OutOfOrderMultiComparatorNonScoringCollector : public MultiComparatorNonScoringCollector { public: - OutOfOrderMultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OutOfOrderMultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderMultiComparatorNonScoringCollector(); LUCENE_CLASS(OutOfOrderMultiComparatorNonScoringCollector); @@ -152,7 +152,7 @@ namespace Lucene class MultiComparatorScoringMaxScoreCollector : public MultiComparatorNonScoringCollector { public: - MultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + MultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~MultiComparatorScoringMaxScoreCollector(); LUCENE_CLASS(MultiComparatorScoringMaxScoreCollector); @@ -163,14 +163,14 @@ namespace Lucene public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); }; /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. class OutOfOrderMultiComparatorScoringMaxScoreCollector : public MultiComparatorScoringMaxScoreCollector { public: - OutOfOrderMultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OutOfOrderMultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderMultiComparatorScoringMaxScoreCollector(); LUCENE_CLASS(OutOfOrderMultiComparatorScoringMaxScoreCollector); @@ -184,7 +184,7 @@ namespace Lucene class MultiComparatorScoringNoMaxScoreCollector : public MultiComparatorNonScoringCollector { public: - MultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + MultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~MultiComparatorScoringNoMaxScoreCollector(); LUCENE_CLASS(MultiComparatorScoringNoMaxScoreCollector); @@ -195,7 +195,7 @@ namespace Lucene public: virtual void updateBottom(int32_t doc, double score); virtual void collect(int32_t doc); - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); }; /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore, @@ -203,14 +203,14 @@ namespace Lucene class OutOfOrderMultiComparatorScoringNoMaxScoreCollector : public MultiComparatorScoringNoMaxScoreCollector { public: - OutOfOrderMultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields); + OutOfOrderMultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); virtual ~OutOfOrderMultiComparatorScoringNoMaxScoreCollector(); LUCENE_CLASS(OutOfOrderMultiComparatorScoringNoMaxScoreCollector); public: virtual void collect(int32_t doc); - virtual void setScorer(ScorerPtr scorer); + virtual void setScorer(const ScorerPtr& scorer); virtual bool acceptsDocsOutOfOrder(); }; } diff --git a/src/core/include/_ValueSourceQuery.h b/src/core/include/_ValueSourceQuery.h index a39b0026..6ea879b6 100644 --- a/src/core/include/_ValueSourceQuery.h +++ b/src/core/include/_ValueSourceQuery.h @@ -15,7 +15,7 @@ namespace Lucene class ValueSourceWeight : public Weight { public: - ValueSourceWeight(ValueSourceQueryPtr query, SearcherPtr searcher); + ValueSourceWeight(const ValueSourceQueryPtr& query, const SearcherPtr& searcher); virtual ~ValueSourceWeight(); LUCENE_CLASS(ValueSourceWeight); @@ -31,8 +31,8 @@ namespace Lucene virtual double getValue(); virtual double sumOfSquaredWeights(); virtual void normalize(double norm); - virtual ScorerPtr scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(IndexReaderPtr reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); }; /// A scorer that (simply) matches all documents, and scores each document with the value of the value @@ -41,7 +41,7 @@ namespace Lucene class ValueSourceScorer : public Scorer { public: - ValueSourceScorer(SimilarityPtr similarity, IndexReaderPtr reader, ValueSourceWeightPtr weight); + ValueSourceScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const ValueSourceWeightPtr& weight); virtual ~ValueSourceScorer(); LUCENE_CLASS(ValueSourceScorer); diff --git a/src/core/index/AbstractAllTermDocs.cpp b/src/core/index/AbstractAllTermDocs.cpp index ad2370e1..222d122d 100644 --- a/src/core/index/AbstractAllTermDocs.cpp +++ b/src/core/index/AbstractAllTermDocs.cpp @@ -19,7 +19,7 @@ namespace Lucene { } - void AbstractAllTermDocs::seek(TermPtr term) + void AbstractAllTermDocs::seek(const TermPtr& term) { if (!term) _doc = -1; @@ -27,7 +27,7 @@ namespace Lucene boost::throw_exception(UnsupportedOperationException()); } - void AbstractAllTermDocs::seek(TermEnumPtr termEnum) + void AbstractAllTermDocs::seek(const TermEnumPtr& termEnum) { boost::throw_exception(UnsupportedOperationException()); } diff --git a/src/core/index/AllTermDocs.cpp b/src/core/index/AllTermDocs.cpp index b197e398..0a27b564 100644 --- a/src/core/index/AllTermDocs.cpp +++ b/src/core/index/AllTermDocs.cpp @@ -11,7 +11,7 @@ namespace Lucene { - AllTermDocs::AllTermDocs(SegmentReaderPtr parent) : AbstractAllTermDocs(parent->maxDoc()) + AllTermDocs::AllTermDocs(const SegmentReaderPtr& parent) : AbstractAllTermDocs(parent->maxDoc()) { SyncLock parentLock(parent); this->_deletedDocs = parent->deletedDocs; diff --git a/src/core/index/BufferedDeletes.cpp b/src/core/index/BufferedDeletes.cpp index c350d9d0..3aa86840 100644 --- a/src/core/index/BufferedDeletes.cpp +++ b/src/core/index/BufferedDeletes.cpp @@ -32,7 +32,7 @@ namespace Lucene return numTerms + queries.size() + docIDs.size(); } - void BufferedDeletes::update(BufferedDeletesPtr in) + void BufferedDeletes::update(const BufferedDeletesPtr& in) { numTerms += in->numTerms; bytesUsed += in->bytesUsed; @@ -61,7 +61,7 @@ namespace Lucene return (!terms.empty() || !docIDs.empty() || !queries.empty()); } - void BufferedDeletes::remap(MergeDocIDRemapperPtr mapper, SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergedDocCount) + void BufferedDeletes::remap(const MergeDocIDRemapperPtr& mapper, const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount) { SyncLock syncLock(this); diff --git a/src/core/index/ByteBlockPool.cpp b/src/core/index/ByteBlockPool.cpp index 14fac54d..bbbf5c8f 100644 --- a/src/core/index/ByteBlockPool.cpp +++ b/src/core/index/ByteBlockPool.cpp @@ -17,7 +17,7 @@ namespace Lucene const int32_t ByteBlockPool::nextLevelArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9}; const int32_t ByteBlockPool::levelSizeArray[] = {5, 14, 20, 30, 40, 40, 80, 80, 120, 200}; - ByteBlockPool::ByteBlockPool(ByteBlockPoolAllocatorBasePtr allocator, bool trackAllocations) + ByteBlockPool::ByteBlockPool(const ByteBlockPoolAllocatorBasePtr& allocator, bool trackAllocations) { buffers = Collection::newInstance(10); bufferUpto = -1; diff --git a/src/core/index/ByteSliceReader.cpp b/src/core/index/ByteSliceReader.cpp index 9198df43..c0dd05a8 100644 --- a/src/core/index/ByteSliceReader.cpp +++ b/src/core/index/ByteSliceReader.cpp @@ -26,7 +26,7 @@ namespace Lucene { } - void ByteSliceReader::init(ByteBlockPoolPtr pool, int32_t startIndex, int32_t endIndex) + void ByteSliceReader::init(const ByteBlockPoolPtr& pool, int32_t startIndex, int32_t endIndex) { BOOST_ASSERT(endIndex - startIndex >= 0); BOOST_ASSERT(startIndex >= 0); @@ -67,7 +67,7 @@ namespace Lucene return buffer[upto++]; } - int64_t ByteSliceReader::writeTo(IndexOutputPtr out) + int64_t ByteSliceReader::writeTo(const IndexOutputPtr& out) { int64_t size = 0; while (true) diff --git a/src/core/index/ByteSliceWriter.cpp b/src/core/index/ByteSliceWriter.cpp index 0316817a..a9cefccd 100644 --- a/src/core/index/ByteSliceWriter.cpp +++ b/src/core/index/ByteSliceWriter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - ByteSliceWriter::ByteSliceWriter(ByteBlockPoolPtr pool) + ByteSliceWriter::ByteSliceWriter(const ByteBlockPoolPtr& pool) { this->pool = pool; upto = 0; diff --git a/src/core/index/CharBlockPool.cpp b/src/core/index/CharBlockPool.cpp index a4121c1f..8f8efdf1 100644 --- a/src/core/index/CharBlockPool.cpp +++ b/src/core/index/CharBlockPool.cpp @@ -10,7 +10,7 @@ namespace Lucene { - CharBlockPool::CharBlockPool(DocumentsWriterPtr docWriter) + CharBlockPool::CharBlockPool(const DocumentsWriterPtr& docWriter) { numBuffer = 0; bufferUpto = -1; diff --git a/src/core/index/CheckIndex.cpp b/src/core/index/CheckIndex.cpp index 1d8c8a26..a6279efa 100644 --- a/src/core/index/CheckIndex.cpp +++ b/src/core/index/CheckIndex.cpp @@ -26,7 +26,7 @@ namespace Lucene { bool CheckIndex::_assertsOn = false; - CheckIndex::CheckIndex(DirectoryPtr dir) + CheckIndex::CheckIndex(const DirectoryPtr& dir) { this->dir = dir; } @@ -35,7 +35,7 @@ namespace Lucene { } - void CheckIndex::setInfoStream(InfoStreamPtr out) + void CheckIndex::setInfoStream(const InfoStreamPtr& out) { infoStream = out; } @@ -320,7 +320,7 @@ namespace Lucene return result; } - FieldNormStatusPtr CheckIndex::testFieldNorms(Collection fieldNames, SegmentReaderPtr reader) + FieldNormStatusPtr CheckIndex::testFieldNorms(Collection fieldNames, const SegmentReaderPtr& reader) { FieldNormStatusPtr status(newLucene()); @@ -350,7 +350,7 @@ namespace Lucene return status; } - TermIndexStatusPtr CheckIndex::testTermIndex(SegmentInfoPtr info, SegmentReaderPtr reader) + TermIndexStatusPtr CheckIndex::testTermIndex(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) { TermIndexStatusPtr status(newLucene()); @@ -459,7 +459,7 @@ namespace Lucene return status; } - StoredFieldStatusPtr CheckIndex::testStoredFields(SegmentInfoPtr info, SegmentReaderPtr reader) + StoredFieldStatusPtr CheckIndex::testStoredFields(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) { StoredFieldStatusPtr status(newLucene()); @@ -498,7 +498,7 @@ namespace Lucene return status; } - TermVectorStatusPtr CheckIndex::testTermVectors(SegmentInfoPtr info, SegmentReaderPtr reader) + TermVectorStatusPtr CheckIndex::testTermVectors(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) { TermVectorStatusPtr status(newLucene()); @@ -529,7 +529,7 @@ namespace Lucene return status; } - void CheckIndex::fixIndex(IndexStatusPtr result) + void CheckIndex::fixIndex(const IndexStatusPtr& result) { if (result->partial) boost::throw_exception(IllegalArgumentException(L"can only fix an index that was fully checked (this status checked a subset of segments)")); @@ -737,7 +737,7 @@ namespace Lucene { } - MySegmentTermDocs::MySegmentTermDocs(SegmentReaderPtr p) : SegmentTermDocs(p) + MySegmentTermDocs::MySegmentTermDocs(const SegmentReaderPtr& p) : SegmentTermDocs(p) { delCount = 0; } @@ -746,7 +746,7 @@ namespace Lucene { } - void MySegmentTermDocs::seek(TermPtr term) + void MySegmentTermDocs::seek(const TermPtr& term) { SegmentTermDocs::seek(term); delCount = 0; diff --git a/src/core/index/CompoundFileReader.cpp b/src/core/index/CompoundFileReader.cpp index 601f9977..bcc2684d 100644 --- a/src/core/index/CompoundFileReader.cpp +++ b/src/core/index/CompoundFileReader.cpp @@ -9,12 +9,12 @@ namespace Lucene { - CompoundFileReader::CompoundFileReader(DirectoryPtr dir, const String& name) + CompoundFileReader::CompoundFileReader(const DirectoryPtr& dir, const String& name) { ConstructReader(dir, name, BufferedIndexInput::BUFFER_SIZE); } - CompoundFileReader::CompoundFileReader(DirectoryPtr dir, const String& name, int32_t readBufferSize) + CompoundFileReader::CompoundFileReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize) { ConstructReader(dir, name, readBufferSize); } @@ -23,7 +23,7 @@ namespace Lucene { } - void CompoundFileReader::ConstructReader(DirectoryPtr dir, const String& name, int32_t readBufferSize) + void CompoundFileReader::ConstructReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize) { directory = dir; fileName = name; @@ -182,14 +182,14 @@ namespace Lucene _length = 0; } - CSIndexInput::CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length) : BufferedIndexInput(BufferedIndexInput::BUFFER_SIZE) + CSIndexInput::CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length) : BufferedIndexInput(BufferedIndexInput::BUFFER_SIZE) { this->base = boost::dynamic_pointer_cast(base->clone()); this->fileOffset = fileOffset; this->_length = length; } - CSIndexInput::CSIndexInput(IndexInputPtr base, int64_t fileOffset, int64_t length, int32_t readBufferSize) : BufferedIndexInput(readBufferSize) + CSIndexInput::CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length, int32_t readBufferSize) : BufferedIndexInput(readBufferSize) { this->base = boost::dynamic_pointer_cast(base->clone()); this->fileOffset = fileOffset; @@ -223,7 +223,7 @@ namespace Lucene return _length; } - LuceneObjectPtr CSIndexInput::clone(LuceneObjectPtr other) + LuceneObjectPtr CSIndexInput::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); CSIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(BufferedIndexInput::clone(clone))); diff --git a/src/core/index/CompoundFileWriter.cpp b/src/core/index/CompoundFileWriter.cpp index 89da3372..ed7c63a9 100644 --- a/src/core/index/CompoundFileWriter.cpp +++ b/src/core/index/CompoundFileWriter.cpp @@ -14,7 +14,7 @@ namespace Lucene { - CompoundFileWriter::CompoundFileWriter(DirectoryPtr dir, const String& name, CheckAbortPtr checkAbort) + CompoundFileWriter::CompoundFileWriter(const DirectoryPtr& dir, const String& name, const CheckAbortPtr& checkAbort) { if (!dir) boost::throw_exception(IllegalArgumentException(L"directory cannot be empty")); @@ -138,7 +138,7 @@ namespace Lucene finally.throwException(); } - void CompoundFileWriter::copyFile(const FileEntry& source, IndexOutputPtr os, ByteArray buffer) + void CompoundFileWriter::copyFile(const FileEntry& source, const IndexOutputPtr& os, ByteArray buffer) { IndexInputPtr is; DirectoryPtr directory(_directory); diff --git a/src/core/index/ConcurrentMergeScheduler.cpp b/src/core/index/ConcurrentMergeScheduler.cpp index 71b75dac..d6db8220 100644 --- a/src/core/index/ConcurrentMergeScheduler.cpp +++ b/src/core/index/ConcurrentMergeScheduler.cpp @@ -119,7 +119,7 @@ namespace Lucene return count; } - void ConcurrentMergeScheduler::merge(IndexWriterPtr writer) + void ConcurrentMergeScheduler::merge(const IndexWriterPtr& writer) { BOOST_ASSERT(!writer->holdsLock()); @@ -182,13 +182,13 @@ namespace Lucene } } - void ConcurrentMergeScheduler::doMerge(OneMergePtr merge) + void ConcurrentMergeScheduler::doMerge(const OneMergePtr& merge) { TestScope testScope(L"ConcurrentMergeScheduler", L"doMerge"); IndexWriterPtr(_writer)->merge(merge); } - MergeThreadPtr ConcurrentMergeScheduler::getMergeThread(IndexWriterPtr writer, OneMergePtr merge) + MergeThreadPtr ConcurrentMergeScheduler::getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge) { SyncLock syncLock(this); MergeThreadPtr thread(newLucene(shared_from_this(), writer, merge)); @@ -257,7 +257,7 @@ namespace Lucene allInstances = Collection::newInstance(); } - MergeThread::MergeThread(ConcurrentMergeSchedulerPtr merger, IndexWriterPtr writer, OneMergePtr startMerge) + MergeThread::MergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge) { this->_merger = merger; this->_writer = writer; @@ -268,7 +268,7 @@ namespace Lucene { } - void MergeThread::setRunningMerge(OneMergePtr merge) + void MergeThread::setRunningMerge(const OneMergePtr& merge) { ConcurrentMergeSchedulerPtr merger(_merger); SyncLock syncLock(merger); diff --git a/src/core/index/DefaultSkipListReader.cpp b/src/core/index/DefaultSkipListReader.cpp index 5e9ab354..f9141864 100644 --- a/src/core/index/DefaultSkipListReader.cpp +++ b/src/core/index/DefaultSkipListReader.cpp @@ -10,7 +10,7 @@ namespace Lucene { - DefaultSkipListReader::DefaultSkipListReader(IndexInputPtr skipStream, int32_t maxSkipLevels, int32_t skipInterval) + DefaultSkipListReader::DefaultSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval) : MultiLevelSkipListReader(skipStream, maxSkipLevels, skipInterval) { currentFieldStoresPayloads = false; @@ -74,7 +74,7 @@ namespace Lucene lastPayloadLength = payloadLength[level]; } - int32_t DefaultSkipListReader::readSkipData(int32_t level, IndexInputPtr skipStream) + int32_t DefaultSkipListReader::readSkipData(int32_t level, const IndexInputPtr& skipStream) { int32_t delta; if (currentFieldStoresPayloads) diff --git a/src/core/index/DefaultSkipListWriter.cpp b/src/core/index/DefaultSkipListWriter.cpp index 64d7219c..e1ee7a68 100644 --- a/src/core/index/DefaultSkipListWriter.cpp +++ b/src/core/index/DefaultSkipListWriter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - DefaultSkipListWriter::DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, IndexOutputPtr freqOutput, IndexOutputPtr proxOutput) : MultiLevelSkipListWriter(skipInterval, numberOfSkipLevels, docCount) + DefaultSkipListWriter::DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, const IndexOutputPtr& freqOutput, const IndexOutputPtr& proxOutput) : MultiLevelSkipListWriter(skipInterval, numberOfSkipLevels, docCount) { curDoc = 0; curStorePayloads = false; @@ -32,12 +32,12 @@ namespace Lucene { } - void DefaultSkipListWriter::setFreqOutput(IndexOutputPtr freqOutput) + void DefaultSkipListWriter::setFreqOutput(const IndexOutputPtr& freqOutput) { this->freqOutput = freqOutput; } - void DefaultSkipListWriter::setProxOutput(IndexOutputPtr proxOutput) + void DefaultSkipListWriter::setProxOutput(const IndexOutputPtr& proxOutput) { this->proxOutput = proxOutput; } @@ -62,7 +62,7 @@ namespace Lucene MiscUtils::arrayFill(lastSkipProxPointer.begin(), 0, lastSkipProxPointer.size(), proxOutput->getFilePointer()); } - void DefaultSkipListWriter::writeSkipData(int32_t level, IndexOutputPtr skipBuffer) + void DefaultSkipListWriter::writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer) { // To efficiently store payloads in the posting lists we do not store the length of // every payload. Instead we omit the length for a payload if the previous payload had diff --git a/src/core/index/DirectoryReader.cpp b/src/core/index/DirectoryReader.cpp index 5c32560f..4ab018ea 100644 --- a/src/core/index/DirectoryReader.cpp +++ b/src/core/index/DirectoryReader.cpp @@ -29,7 +29,7 @@ namespace Lucene { - DirectoryReader::DirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) + DirectoryReader::DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { normsCache = MapStringByteArray::newInstance(); _maxDoc = 0; @@ -91,7 +91,7 @@ namespace Lucene _initialize(readers); } - DirectoryReader::DirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor) + DirectoryReader::DirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor) { normsCache = MapStringByteArray::newInstance(); _maxDoc = 0; @@ -166,7 +166,7 @@ namespace Lucene _initialize(readers); } - DirectoryReader::DirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, Collection oldReaders, + DirectoryReader::DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, bool doClone, int32_t termInfosIndexDivisor) { @@ -338,12 +338,12 @@ namespace Lucene maxIndexVersion = SegmentInfos::readCurrentVersion(_directory); } - IndexReaderPtr DirectoryReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor) + IndexReaderPtr DirectoryReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor) { return newLucene(readOnly, deletionPolicy, termInfosIndexDivisor, newLucene(), directory)->run(commit); } - LuceneObjectPtr DirectoryReader::clone(LuceneObjectPtr other) + LuceneObjectPtr DirectoryReader::clone(const LuceneObjectPtr& other) { try { @@ -356,7 +356,7 @@ namespace Lucene return DirectoryReaderPtr(); } - LuceneObjectPtr DirectoryReader::clone(bool openReadOnly, LuceneObjectPtr other) + LuceneObjectPtr DirectoryReader::clone(bool openReadOnly, const LuceneObjectPtr& other) { SyncLock syncLock(this); DirectoryReaderPtr newReader(doReopen(boost::dynamic_pointer_cast(segmentInfos->clone()), true, openReadOnly)); @@ -392,12 +392,12 @@ namespace Lucene return doReopen(openReadOnly, IndexCommitPtr()); } - IndexReaderPtr DirectoryReader::reopen(IndexCommitPtr commit) + IndexReaderPtr DirectoryReader::reopen(const IndexCommitPtr& commit) { return doReopen(true, commit); } - IndexReaderPtr DirectoryReader::doReopenFromWriter(bool openReadOnly, IndexCommitPtr commit) + IndexReaderPtr DirectoryReader::doReopenFromWriter(bool openReadOnly, const IndexCommitPtr& commit) { BOOST_ASSERT(readOnly); @@ -410,7 +410,7 @@ namespace Lucene return IndexWriterPtr(_writer)->getReader(); } - IndexReaderPtr DirectoryReader::doReopen(bool openReadOnly, IndexCommitPtr commit) + IndexReaderPtr DirectoryReader::doReopen(bool openReadOnly, const IndexCommitPtr& commit) { ensureOpen(); @@ -425,7 +425,7 @@ namespace Lucene return doReopenNoWriter(openReadOnly, commit); } - IndexReaderPtr DirectoryReader::doReopenNoWriter(bool openReadOnly, IndexCommitPtr commit) + IndexReaderPtr DirectoryReader::doReopenNoWriter(bool openReadOnly, const IndexCommitPtr& commit) { SyncLock syncLock(this); if (!commit) @@ -474,7 +474,7 @@ namespace Lucene return newLucene(shared_from_this(), openReadOnly, newLucene(), _directory)->run(commit); } - DirectoryReaderPtr DirectoryReader::doReopen(SegmentInfosPtr infos, bool doClone, bool openReadOnly) + DirectoryReaderPtr DirectoryReader::doReopen(const SegmentInfosPtr& infos, bool doClone, bool openReadOnly) { SyncLock syncLock(this); if (openReadOnly) @@ -503,14 +503,14 @@ namespace Lucene return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); } - void DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) + void DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); } - void DirectoryReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) + void DirectoryReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num @@ -544,7 +544,7 @@ namespace Lucene return _maxDoc; } - DocumentPtr DirectoryReader::document(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr DirectoryReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { ensureOpen(); int32_t i = readerIndex(n); // find segment num @@ -652,13 +652,13 @@ namespace Lucene return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, TermPtr()); } - TermEnumPtr DirectoryReader::terms(TermPtr t) + TermEnumPtr DirectoryReader::terms(const TermPtr& t) { ensureOpen(); return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, t); } - int32_t DirectoryReader::docFreq(TermPtr t) + int32_t DirectoryReader::docFreq(const TermPtr& t) { ensureOpen(); int32_t total = 0; // sum freqs in segments @@ -883,7 +883,7 @@ namespace Lucene return newLucene(segmentInfos, _directory); } - Collection DirectoryReader::listCommits(DirectoryPtr dir) + Collection DirectoryReader::listCommits(const DirectoryPtr& dir) { HashSet files(dir->listAll()); @@ -920,7 +920,7 @@ namespace Lucene return commits; } - FindSegmentsOpen::FindSegmentsOpen(bool readOnly, IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor, SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) + FindSegmentsOpen::FindSegmentsOpen(bool readOnly, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor, const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { this->readOnly = readOnly; this->deletionPolicy = deletionPolicy; @@ -941,7 +941,7 @@ namespace Lucene return newLucene(directory, segmentInfos, deletionPolicy, false, termInfosIndexDivisor); } - FindSegmentsReopen::FindSegmentsReopen(DirectoryReaderPtr reader, bool openReadOnly, SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) + FindSegmentsReopen::FindSegmentsReopen(const DirectoryReaderPtr& reader, bool openReadOnly, const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { this->_reader = reader; this->openReadOnly = openReadOnly; @@ -958,7 +958,7 @@ namespace Lucene return DirectoryReaderPtr(_reader)->doReopen(segmentInfos, false, openReadOnly); } - MultiTermEnum::MultiTermEnum(IndexReaderPtr topReader, Collection readers, Collection starts, TermPtr t) + MultiTermEnum::MultiTermEnum(const IndexReaderPtr& topReader, Collection readers, Collection starts, const TermPtr& t) { _docFreq = 0; this->_topReader = topReader; @@ -1043,7 +1043,7 @@ namespace Lucene queue->close(); } - MultiTermDocs::MultiTermDocs(IndexReaderPtr topReader, Collection r, Collection s) + MultiTermDocs::MultiTermDocs(const IndexReaderPtr& topReader, Collection r, Collection s) { this->_topReader = topReader; readers = r; @@ -1067,7 +1067,7 @@ namespace Lucene return current->freq(); } - void MultiTermDocs::seek(TermPtr term) + void MultiTermDocs::seek(const TermPtr& term) { this->term = term; this->base = 0; @@ -1078,7 +1078,7 @@ namespace Lucene this->matchingSegmentPos = 0; } - void MultiTermDocs::seek(TermEnumPtr termEnum) + void MultiTermDocs::seek(const TermEnumPtr& termEnum) { seek(termEnum->term()); MultiTermEnumPtr multiTermEnum(boost::dynamic_pointer_cast(termEnum)); @@ -1197,7 +1197,7 @@ namespace Lucene return result; } - TermDocsPtr MultiTermDocs::termDocs(IndexReaderPtr reader) + TermDocsPtr MultiTermDocs::termDocs(const IndexReaderPtr& reader) { return term ? reader->termDocs() : reader->termDocs(TermPtr()); } @@ -1211,7 +1211,7 @@ namespace Lucene } } - MultiTermPositions::MultiTermPositions(IndexReaderPtr topReader, Collection r, Collection s) : MultiTermDocs(topReader, r, s) + MultiTermPositions::MultiTermPositions(const IndexReaderPtr& topReader, Collection r, Collection s) : MultiTermDocs(topReader, r, s) { } @@ -1219,7 +1219,7 @@ namespace Lucene { } - TermDocsPtr MultiTermPositions::termDocs(IndexReaderPtr reader) + TermDocsPtr MultiTermPositions::termDocs(const IndexReaderPtr& reader) { return reader->termPositions(); } @@ -1244,7 +1244,7 @@ namespace Lucene return boost::static_pointer_cast(current)->isPayloadAvailable(); } - ReaderCommit::ReaderCommit(SegmentInfosPtr infos, DirectoryPtr dir) + ReaderCommit::ReaderCommit(const SegmentInfosPtr& infos, const DirectoryPtr& dir) { segmentsFileName = infos->getCurrentSegmentFileName(); this->dir = dir; diff --git a/src/core/index/DocFieldConsumer.cpp b/src/core/index/DocFieldConsumer.cpp index dcb59af8..3f25a330 100644 --- a/src/core/index/DocFieldConsumer.cpp +++ b/src/core/index/DocFieldConsumer.cpp @@ -13,7 +13,7 @@ namespace Lucene { } - void DocFieldConsumer::setFieldInfos(FieldInfosPtr fieldInfos) + void DocFieldConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) { this->fieldInfos = fieldInfos; } diff --git a/src/core/index/DocFieldConsumers.cpp b/src/core/index/DocFieldConsumers.cpp index f0ffa7e5..859a88e5 100644 --- a/src/core/index/DocFieldConsumers.cpp +++ b/src/core/index/DocFieldConsumers.cpp @@ -12,7 +12,7 @@ namespace Lucene { - DocFieldConsumers::DocFieldConsumers(DocFieldConsumerPtr one, DocFieldConsumerPtr two) + DocFieldConsumers::DocFieldConsumers(const DocFieldConsumerPtr& one, const DocFieldConsumerPtr& two) { freeCount = 0; allocCount = 0; @@ -26,14 +26,14 @@ namespace Lucene { } - void DocFieldConsumers::setFieldInfos(FieldInfosPtr fieldInfos) + void DocFieldConsumers::setFieldInfos(const FieldInfosPtr& fieldInfos) { DocFieldConsumer::setFieldInfos(fieldInfos); one->setFieldInfos(fieldInfos); two->setFieldInfos(fieldInfos); } - void DocFieldConsumers::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state) + void DocFieldConsumers::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField oneThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField twoThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); @@ -57,7 +57,7 @@ namespace Lucene two->flush(twoThreadsAndFields, state); } - void DocFieldConsumers::closeDocStore(SegmentWriteStatePtr state) + void DocFieldConsumers::closeDocStore(const SegmentWriteStatePtr& state) { LuceneException finally; try @@ -84,7 +84,7 @@ namespace Lucene return (one->freeRAM() || two->freeRAM()); } - DocFieldConsumerPerThreadPtr DocFieldConsumers::addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread) + DocFieldConsumerPerThreadPtr DocFieldConsumers::addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) { return newLucene(docFieldProcessorPerThread, shared_from_this(), one->addThread(docFieldProcessorPerThread), two->addThread(docFieldProcessorPerThread)); } @@ -108,14 +108,14 @@ namespace Lucene return docFreeList[--freeCount]; } - void DocFieldConsumers::freePerDoc(DocFieldConsumersPerDocPtr perDoc) + void DocFieldConsumers::freePerDoc(const DocFieldConsumersPerDocPtr& perDoc) { SyncLock syncLock(this); BOOST_ASSERT(freeCount < docFreeList.size()); docFreeList[freeCount++] = perDoc; } - DocFieldConsumersPerDoc::DocFieldConsumersPerDoc(DocFieldConsumersPtr fieldConsumers) + DocFieldConsumersPerDoc::DocFieldConsumersPerDoc(const DocFieldConsumersPtr& fieldConsumers) { this->_fieldConsumers = fieldConsumers; } diff --git a/src/core/index/DocFieldConsumersPerField.cpp b/src/core/index/DocFieldConsumersPerField.cpp index 04b57fda..5b6de8eb 100644 --- a/src/core/index/DocFieldConsumersPerField.cpp +++ b/src/core/index/DocFieldConsumersPerField.cpp @@ -9,7 +9,7 @@ namespace Lucene { - DocFieldConsumersPerField::DocFieldConsumersPerField(DocFieldConsumersPerThreadPtr perThread, DocFieldConsumerPerFieldPtr one, DocFieldConsumerPerFieldPtr two) + DocFieldConsumersPerField::DocFieldConsumersPerField(const DocFieldConsumersPerThreadPtr& perThread, const DocFieldConsumerPerFieldPtr& one, const DocFieldConsumerPerFieldPtr& two) { this->_perThread = perThread; this->one = one; diff --git a/src/core/index/DocFieldConsumersPerThread.cpp b/src/core/index/DocFieldConsumersPerThread.cpp index 7504ef00..137a332e 100644 --- a/src/core/index/DocFieldConsumersPerThread.cpp +++ b/src/core/index/DocFieldConsumersPerThread.cpp @@ -12,9 +12,9 @@ namespace Lucene { - DocFieldConsumersPerThread::DocFieldConsumersPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, - DocFieldConsumersPtr parent, - DocFieldConsumerPerThreadPtr one, DocFieldConsumerPerThreadPtr two) + DocFieldConsumersPerThread::DocFieldConsumersPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, + const DocFieldConsumersPtr& parent, + const DocFieldConsumerPerThreadPtr& one, const DocFieldConsumerPerThreadPtr& two) { this->_parent = parent; this->one = one; @@ -74,7 +74,7 @@ namespace Lucene } } - DocFieldConsumerPerFieldPtr DocFieldConsumersPerThread::addField(FieldInfoPtr fi) + DocFieldConsumerPerFieldPtr DocFieldConsumersPerThread::addField(const FieldInfoPtr& fi) { return newLucene(shared_from_this(), one->addField(fi), two->addField(fi)); } diff --git a/src/core/index/DocFieldProcessor.cpp b/src/core/index/DocFieldProcessor.cpp index 9864f2ab..4b109671 100644 --- a/src/core/index/DocFieldProcessor.cpp +++ b/src/core/index/DocFieldProcessor.cpp @@ -17,7 +17,7 @@ namespace Lucene { - DocFieldProcessor::DocFieldProcessor(DocumentsWriterPtr docWriter, DocFieldConsumerPtr consumer) + DocFieldProcessor::DocFieldProcessor(const DocumentsWriterPtr& docWriter, const DocFieldConsumerPtr& consumer) { this->fieldInfos = newLucene(); this->_docWriter = docWriter; @@ -30,13 +30,13 @@ namespace Lucene { } - void DocFieldProcessor::closeDocStore(SegmentWriteStatePtr state) + void DocFieldProcessor::closeDocStore(const SegmentWriteStatePtr& state) { consumer->closeDocStore(state); fieldsWriter->closeDocStore(state); } - void DocFieldProcessor::flush(Collection threads, SegmentWriteStatePtr state) + void DocFieldProcessor::flush(Collection threads, const SegmentWriteStatePtr& state) { TestScope testScope(L"DocFieldProcessor", L"flush"); MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField childThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); @@ -68,7 +68,7 @@ namespace Lucene return consumer->freeRAM(); } - DocConsumerPerThreadPtr DocFieldProcessor::addThread(DocumentsWriterThreadStatePtr perThread) + DocConsumerPerThreadPtr DocFieldProcessor::addThread(const DocumentsWriterThreadStatePtr& perThread) { return newLucene(perThread, shared_from_this()); } diff --git a/src/core/index/DocFieldProcessorPerField.cpp b/src/core/index/DocFieldProcessorPerField.cpp index 67224d69..0d95bf8e 100644 --- a/src/core/index/DocFieldProcessorPerField.cpp +++ b/src/core/index/DocFieldProcessorPerField.cpp @@ -12,7 +12,7 @@ namespace Lucene { - DocFieldProcessorPerField::DocFieldProcessorPerField(DocFieldProcessorPerThreadPtr perThread, FieldInfoPtr fieldInfo) + DocFieldProcessorPerField::DocFieldProcessorPerField(const DocFieldProcessorPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { lastGen = -1; fieldCount = 0; diff --git a/src/core/index/DocFieldProcessorPerThread.cpp b/src/core/index/DocFieldProcessorPerThread.cpp index 586bbd19..fec2c53e 100644 --- a/src/core/index/DocFieldProcessorPerThread.cpp +++ b/src/core/index/DocFieldProcessorPerThread.cpp @@ -27,7 +27,7 @@ namespace Lucene { - DocFieldProcessorPerThread::DocFieldProcessorPerThread(DocumentsWriterThreadStatePtr threadState, DocFieldProcessorPtr docFieldProcessor) + DocFieldProcessorPerThread::DocFieldProcessorPerThread(const DocumentsWriterThreadStatePtr& threadState, const DocFieldProcessorPtr& docFieldProcessor) { _fields = Collection::newInstance(1); fieldHash = Collection::newInstance(2); @@ -88,7 +88,7 @@ namespace Lucene return fields; } - void DocFieldProcessorPerThread::trimFields(SegmentWriteStatePtr state) + void DocFieldProcessorPerThread::trimFields(const SegmentWriteStatePtr& state) { for (Collection::iterator perField = fieldHash.begin(); perField != fieldHash.end(); ++perField) { @@ -284,14 +284,14 @@ namespace Lucene return docFreeList[--freeCount]; } - void DocFieldProcessorPerThread::freePerDoc(DocFieldProcessorPerThreadPerDocPtr perDoc) + void DocFieldProcessorPerThread::freePerDoc(const DocFieldProcessorPerThreadPerDocPtr& perDoc) { SyncLock syncLock(this); BOOST_ASSERT(freeCount < docFreeList.size()); docFreeList[freeCount++] = perDoc; } - DocFieldProcessorPerThreadPerDoc::DocFieldProcessorPerThreadPerDoc(DocFieldProcessorPerThreadPtr docProcessor) + DocFieldProcessorPerThreadPerDoc::DocFieldProcessorPerThreadPerDoc(const DocFieldProcessorPerThreadPtr& docProcessor) { this->_docProcessor = docProcessor; } diff --git a/src/core/index/DocInverter.cpp b/src/core/index/DocInverter.cpp index f342e646..4220b230 100644 --- a/src/core/index/DocInverter.cpp +++ b/src/core/index/DocInverter.cpp @@ -17,7 +17,7 @@ namespace Lucene { - DocInverter::DocInverter(InvertedDocConsumerPtr consumer, InvertedDocEndConsumerPtr endConsumer) + DocInverter::DocInverter(const InvertedDocConsumerPtr& consumer, const InvertedDocEndConsumerPtr& endConsumer) { this->consumer = consumer; this->endConsumer = endConsumer; @@ -27,14 +27,14 @@ namespace Lucene { } - void DocInverter::setFieldInfos(FieldInfosPtr fieldInfos) + void DocInverter::setFieldInfos(const FieldInfosPtr& fieldInfos) { DocFieldConsumer::setFieldInfos(fieldInfos); consumer->setFieldInfos(fieldInfos); endConsumer->setFieldInfos(fieldInfos); } - void DocInverter::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, SegmentWriteStatePtr state) + void DocInverter::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField childThreadsAndFields(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::newInstance()); MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField endChildThreadsAndFields(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField::newInstance()); @@ -58,7 +58,7 @@ namespace Lucene endConsumer->flush(endChildThreadsAndFields, state); } - void DocInverter::closeDocStore(SegmentWriteStatePtr state) + void DocInverter::closeDocStore(const SegmentWriteStatePtr& state) { consumer->closeDocStore(state); endConsumer->closeDocStore(state); @@ -75,7 +75,7 @@ namespace Lucene return consumer->freeRAM(); } - DocFieldConsumerPerThreadPtr DocInverter::addThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread) + DocFieldConsumerPerThreadPtr DocInverter::addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) { return newLucene(docFieldProcessorPerThread, shared_from_this()); } diff --git a/src/core/index/DocInverterPerField.cpp b/src/core/index/DocInverterPerField.cpp index 74ae904e..e75f34e6 100644 --- a/src/core/index/DocInverterPerField.cpp +++ b/src/core/index/DocInverterPerField.cpp @@ -27,7 +27,7 @@ namespace Lucene { - DocInverterPerField::DocInverterPerField(DocInverterPerThreadPtr perThread, FieldInfoPtr fieldInfo) + DocInverterPerField::DocInverterPerField(const DocInverterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { this->_perThread = perThread; this->fieldInfo = fieldInfo; diff --git a/src/core/index/DocInverterPerThread.cpp b/src/core/index/DocInverterPerThread.cpp index 6ef9dd76..60df927e 100644 --- a/src/core/index/DocInverterPerThread.cpp +++ b/src/core/index/DocInverterPerThread.cpp @@ -20,7 +20,7 @@ namespace Lucene { - DocInverterPerThread::DocInverterPerThread(DocFieldProcessorPerThreadPtr docFieldProcessorPerThread, DocInverterPtr docInverter) + DocInverterPerThread::DocInverterPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocInverterPtr& docInverter) { this->fieldState = newLucene(); this->stringReader = newLucene(); @@ -74,7 +74,7 @@ namespace Lucene finally.throwException(); } - DocFieldConsumerPerFieldPtr DocInverterPerThread::addField(FieldInfoPtr fi) + DocFieldConsumerPerFieldPtr DocInverterPerThread::addField(const FieldInfoPtr& fi) { return newLucene(shared_from_this(), fi); } diff --git a/src/core/index/DocumentsWriter.cpp b/src/core/index/DocumentsWriter.cpp index fdbcfbfa..a458c6f4 100644 --- a/src/core/index/DocumentsWriter.cpp +++ b/src/core/index/DocumentsWriter.cpp @@ -101,7 +101,7 @@ namespace Lucene const int32_t DocumentsWriter::PER_DOC_BLOCK_SIZE = 1024; - DocumentsWriter::DocumentsWriter(DirectoryPtr directory, IndexWriterPtr writer, IndexingChainPtr indexingChain) + DocumentsWriter::DocumentsWriter(const DirectoryPtr& directory, const IndexWriterPtr& writer, const IndexingChainPtr& indexingChain) { this->threadStates = Collection::newInstance(); this->threadBindings = MapThreadDocumentsWriterThreadState::newInstance(); @@ -195,7 +195,7 @@ namespace Lucene return docFieldProcessor ? docFieldProcessor->fieldInfos->hasProx() : true; } - void DocumentsWriter::setInfoStream(InfoStreamPtr infoStream) + void DocumentsWriter::setInfoStream(const InfoStreamPtr& infoStream) { SyncLock syncLock(this); this->infoStream = infoStream; @@ -211,7 +211,7 @@ namespace Lucene (*threadState)->docState->maxFieldLength = maxFieldLength; } - void DocumentsWriter::setSimilarity(SimilarityPtr similarity) + void DocumentsWriter::setSimilarity(const SimilarityPtr& similarity) { SyncLock syncLock(this); this->similarity = similarity; @@ -628,7 +628,7 @@ namespace Lucene } } - DocumentsWriterThreadStatePtr DocumentsWriter::getThreadState(DocumentPtr doc, TermPtr delTerm) + DocumentsWriterThreadStatePtr DocumentsWriter::getThreadState(const DocumentPtr& doc, const TermPtr& delTerm) { SyncLock syncLock(this); // First, find a thread state. If this thread already has affinity to a specific ThreadState, use that one again. @@ -715,17 +715,17 @@ namespace Lucene return state; } - bool DocumentsWriter::addDocument(DocumentPtr doc, AnalyzerPtr analyzer) + bool DocumentsWriter::addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer) { return updateDocument(doc, analyzer, TermPtr()); } - bool DocumentsWriter::updateDocument(TermPtr t, DocumentPtr doc, AnalyzerPtr analyzer) + bool DocumentsWriter::updateDocument(const TermPtr& t, const DocumentPtr& doc, const AnalyzerPtr& analyzer) { return updateDocument(doc, analyzer, t); } - bool DocumentsWriter::updateDocument(DocumentPtr doc, AnalyzerPtr analyzer, TermPtr delTerm) + bool DocumentsWriter::updateDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer, const TermPtr& delTerm) { // This call is synchronized but fast DocumentsWriterThreadStatePtr state(getThreadState(doc, delTerm)); @@ -824,7 +824,7 @@ namespace Lucene return deletesInRAM->terms; } - void DocumentsWriter::remapDeletes(SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergeDocCount) + void DocumentsWriter::remapDeletes(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergeDocCount) { SyncLock syncLock(this); if (!docMaps) @@ -838,7 +838,7 @@ namespace Lucene flushedDocCount -= mapper->docShift; } - void DocumentsWriter::waitReady(DocumentsWriterThreadStatePtr state) + void DocumentsWriter::waitReady(const DocumentsWriterThreadStatePtr& state) { SyncLock syncLock(this); while (!closed && ((state && !state->isIdle) || pauseThreads != 0 || flushPending || aborting)) @@ -856,7 +856,7 @@ namespace Lucene return timeToFlushDeletes(); } - bool DocumentsWriter::bufferDeleteTerm(TermPtr term) + bool DocumentsWriter::bufferDeleteTerm(const TermPtr& term) { SyncLock syncLock(this); waitReady(DocumentsWriterThreadStatePtr()); @@ -873,7 +873,7 @@ namespace Lucene return timeToFlushDeletes(); } - bool DocumentsWriter::bufferDeleteQuery(QueryPtr query) + bool DocumentsWriter::bufferDeleteQuery(const QueryPtr& query) { SyncLock syncLock(this); waitReady(DocumentsWriterThreadStatePtr()); @@ -909,7 +909,7 @@ namespace Lucene return ((bufferIsFull || deletesFull()) && setFlushPending()); } - bool DocumentsWriter::checkDeleteTerm(TermPtr term) + bool DocumentsWriter::checkDeleteTerm(const TermPtr& term) { if (term) BOOST_ASSERT(!lastDeleteTerm || term->compareTo(lastDeleteTerm) > 0); @@ -933,7 +933,7 @@ namespace Lucene return deletesFlushed->any(); } - bool DocumentsWriter::applyDeletes(SegmentInfosPtr infos) + bool DocumentsWriter::applyDeletes(const SegmentInfosPtr& infos) { SyncLock syncLock(this); if (!hasDeletes()) @@ -979,7 +979,7 @@ namespace Lucene return any; } - bool DocumentsWriter::applyDeletes(IndexReaderPtr reader, int32_t docIDStart) + bool DocumentsWriter::applyDeletes(const IndexReaderPtr& reader, int32_t docIDStart) { SyncLock syncLock(this); int32_t docEnd = docIDStart + reader->maxDoc(); @@ -1047,7 +1047,7 @@ namespace Lucene return any; } - void DocumentsWriter::addDeleteTerm(TermPtr term, int32_t docCount) + void DocumentsWriter::addDeleteTerm(const TermPtr& term, int32_t docCount) { SyncLock syncLock(this); NumPtr num(deletesInRAM->terms.get(term)); @@ -1068,7 +1068,7 @@ namespace Lucene deletesInRAM->addBytesUsed(BYTES_PER_DEL_DOCID); } - void DocumentsWriter::addDeleteQuery(QueryPtr query, int32_t docID) + void DocumentsWriter::addDeleteQuery(const QueryPtr& query, int32_t docID) { SyncLock syncLock(this); deletesInRAM->queries.put(query, flushedDocCount + docID); @@ -1083,7 +1083,7 @@ namespace Lucene numBytesAlloc >= freeTrigger)); } - void DocumentsWriter::finishDocument(DocumentsWriterThreadStatePtr perThread, DocWriterPtr docWriter) + void DocumentsWriter::finishDocument(const DocumentsWriterThreadStatePtr& perThread, const DocWriterPtr& docWriter) { if (doBalanceRAM()) { @@ -1369,7 +1369,7 @@ namespace Lucene analyzer.reset(); } - PerDocBuffer::PerDocBuffer(DocumentsWriterPtr docWriter) + PerDocBuffer::PerDocBuffer(const DocumentsWriterPtr& docWriter) { _docWriter = docWriter; } @@ -1409,7 +1409,7 @@ namespace Lucene { } - void DocWriter::setNext(DocWriterPtr next) + void DocWriter::setNext(const DocWriterPtr& next) { this->next = next; } @@ -1422,7 +1422,7 @@ namespace Lucene { } - DocConsumerPtr DefaultIndexingChain::getChain(DocumentsWriterPtr documentsWriter) + DocConsumerPtr DefaultIndexingChain::getChain(const DocumentsWriterPtr& documentsWriter) { TermsHashConsumerPtr termVectorsWriter(newLucene(documentsWriter)); TermsHashConsumerPtr freqProxWriter(newLucene()); @@ -1452,7 +1452,7 @@ namespace Lucene return 0; } - WaitQueue::WaitQueue(DocumentsWriterPtr docWriter) + WaitQueue::WaitQueue(const DocumentsWriterPtr& docWriter) { this->_docWriter = docWriter; waiting = Collection::newInstance(10); @@ -1505,7 +1505,7 @@ namespace Lucene numWaiting = 0; } - void WaitQueue::writeDocument(DocWriterPtr doc) + void WaitQueue::writeDocument(const DocWriterPtr& doc) { DocumentsWriterPtr docWriter(_docWriter); BOOST_ASSERT(doc == DocumentsWriterPtr(docWriter)->skipDocWriter || nextWriteDocID == doc->docID); @@ -1531,22 +1531,23 @@ namespace Lucene finally.throwException(); } - bool WaitQueue::add(DocWriterPtr doc) + bool WaitQueue::add(const DocWriterPtr& doc) { + DocWriterPtr _doc(doc); SyncLock syncLock(this); - BOOST_ASSERT(doc->docID >= nextWriteDocID); - if (doc->docID == nextWriteDocID) + BOOST_ASSERT(_doc->docID >= nextWriteDocID); + if (_doc->docID == nextWriteDocID) { - writeDocument(doc); + writeDocument(_doc); while (true) { - doc = waiting[nextWriteLoc]; - if (doc) + _doc = waiting[nextWriteLoc]; + if (_doc) { --numWaiting; waiting[nextWriteLoc].reset(); - waitingBytes -= doc->sizeInBytes(); - writeDocument(doc); + waitingBytes -= _doc->sizeInBytes(); + writeDocument(_doc); } else break; @@ -1557,7 +1558,7 @@ namespace Lucene // I finished before documents that were added before me. This can easily happen when I am a small doc // and the docs before me were large, or just due to luck in the thread scheduling. Just add myself to // the queue and when that large doc finishes, it will flush me - int32_t gap = doc->docID - nextWriteDocID; + int32_t gap = _doc->docID - nextWriteDocID; if (gap >= waiting.size()) { // Grow queue @@ -1567,7 +1568,7 @@ namespace Lucene MiscUtils::arrayCopy(waiting.begin(), 0, newArray.begin(), waiting.size() - nextWriteLoc, nextWriteLoc); nextWriteLoc = 0; waiting = newArray; - gap = doc->docID - nextWriteDocID; + gap = _doc->docID - nextWriteDocID; } int32_t loc = nextWriteLoc + gap; @@ -1579,15 +1580,15 @@ namespace Lucene // Nobody should be in my spot! BOOST_ASSERT(!waiting[loc]); - waiting[loc] = doc; + waiting[loc] = _doc; ++numWaiting; - waitingBytes += doc->sizeInBytes(); + waitingBytes += _doc->sizeInBytes(); } return doPause(); } - ByteBlockAllocator::ByteBlockAllocator(DocumentsWriterPtr docWriter, int32_t blockSize) + ByteBlockAllocator::ByteBlockAllocator(const DocumentsWriterPtr& docWriter, int32_t blockSize) { this->blockSize = blockSize; this->freeByteBlocks = Collection::newInstance(); diff --git a/src/core/index/DocumentsWriterThreadState.cpp b/src/core/index/DocumentsWriterThreadState.cpp index c19aebb5..21791cd9 100644 --- a/src/core/index/DocumentsWriterThreadState.cpp +++ b/src/core/index/DocumentsWriterThreadState.cpp @@ -11,7 +11,7 @@ namespace Lucene { - DocumentsWriterThreadState::DocumentsWriterThreadState(DocumentsWriterPtr docWriter) + DocumentsWriterThreadState::DocumentsWriterThreadState(const DocumentsWriterPtr& docWriter) { this->_docWriter = docWriter; } diff --git a/src/core/index/FieldInfo.cpp b/src/core/index/FieldInfo.cpp index 27180a6f..05f31674 100644 --- a/src/core/index/FieldInfo.cpp +++ b/src/core/index/FieldInfo.cpp @@ -29,7 +29,7 @@ namespace Lucene { } - LuceneObjectPtr FieldInfo::clone(LuceneObjectPtr other) + LuceneObjectPtr FieldInfo::clone(const LuceneObjectPtr& other) { return newLucene(name, isIndexed, number, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); diff --git a/src/core/index/FieldInfos.cpp b/src/core/index/FieldInfos.cpp index 7122f420..d2c0733c 100644 --- a/src/core/index/FieldInfos.cpp +++ b/src/core/index/FieldInfos.cpp @@ -39,7 +39,7 @@ namespace Lucene byName = MapStringFieldInfo::newInstance(); } - FieldInfos::FieldInfos(DirectoryPtr d, const String& name) + FieldInfos::FieldInfos(const DirectoryPtr& d, const String& name) { format = 0; byNumber = Collection::newInstance(); @@ -86,7 +86,7 @@ namespace Lucene { } - LuceneObjectPtr FieldInfos::clone(LuceneObjectPtr other) + LuceneObjectPtr FieldInfos::clone(const LuceneObjectPtr& other) { SyncLock syncLock(this); FieldInfosPtr fis(newLucene()); @@ -99,7 +99,7 @@ namespace Lucene return fis; } - void FieldInfos::add(DocumentPtr doc) + void FieldInfos::add(const DocumentPtr& doc) { SyncLock syncLock(this); Collection fields(doc->getFields()); @@ -216,7 +216,7 @@ namespace Lucene return false; } - void FieldInfos::write(DirectoryPtr d, const String& name) + void FieldInfos::write(const DirectoryPtr& d, const String& name) { IndexOutputPtr output(d->createOutput(name)); LuceneException finally; @@ -232,7 +232,7 @@ namespace Lucene finally.throwException(); } - void FieldInfos::write(IndexOutputPtr output) + void FieldInfos::write(const IndexOutputPtr& output) { output->writeVInt(CURRENT_FORMAT); output->writeVInt(size()); @@ -259,7 +259,7 @@ namespace Lucene } } - void FieldInfos::read(IndexInputPtr input, const String& fileName) + void FieldInfos::read(const IndexInputPtr& input, const String& fileName) { int32_t firstInt = input->readVInt(); format = firstInt < 0 ? firstInt : FORMAT_PRE; // This is a real format? diff --git a/src/core/index/FieldsReader.cpp b/src/core/index/FieldsReader.cpp index 9c46db4f..b5ec7b26 100644 --- a/src/core/index/FieldsReader.cpp +++ b/src/core/index/FieldsReader.cpp @@ -22,9 +22,9 @@ namespace Lucene { - FieldsReader::FieldsReader(FieldInfosPtr fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, - int32_t formatSize, int32_t docStoreOffset, IndexInputPtr cloneableFieldsStream, - IndexInputPtr cloneableIndexStream) + FieldsReader::FieldsReader(const FieldInfosPtr& fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, + int32_t formatSize, int32_t docStoreOffset, const IndexInputPtr& cloneableFieldsStream, + const IndexInputPtr& cloneableIndexStream) { closed = false; isOriginal = false; @@ -40,12 +40,12 @@ namespace Lucene indexStream = boost::dynamic_pointer_cast(cloneableIndexStream->clone()); } - FieldsReader::FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn) + FieldsReader::FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn) { ConstructReader(d, segment, fn, BufferedIndexInput::BUFFER_SIZE, -1, 0); } - FieldsReader::FieldsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) + FieldsReader::FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { ConstructReader(d, segment, fn, readBufferSize, docStoreOffset, size); } @@ -54,7 +54,7 @@ namespace Lucene { } - void FieldsReader::ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) + void FieldsReader::ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { bool success = false; isOriginal = true; @@ -121,7 +121,7 @@ namespace Lucene finally.throwException(); } - LuceneObjectPtr FieldsReader::clone(LuceneObjectPtr other) + LuceneObjectPtr FieldsReader::clone(const LuceneObjectPtr& other) { ensureOpen(); return newLucene(fieldInfos, numTotalDocs, _size, format, formatSize, docStoreOffset, cloneableFieldsStream, cloneableIndexStream); @@ -171,7 +171,7 @@ namespace Lucene return (format >= FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS); } - DocumentPtr FieldsReader::doc(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr FieldsReader::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { seekIndex(n); int64_t position = indexStream->readLong(); @@ -255,7 +255,7 @@ namespace Lucene } } - void FieldsReader::addFieldLazy(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize) + void FieldsReader::addFieldLazy(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize) { if (binary) { @@ -299,7 +299,7 @@ namespace Lucene } } - void FieldsReader::addField(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed, bool tokenize) + void FieldsReader::addField(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize) { // we have a binary stored field, and it may be compressed if (binary) @@ -340,7 +340,7 @@ namespace Lucene } } - int32_t FieldsReader::addFieldSize(DocumentPtr doc, FieldInfoPtr fi, bool binary, bool compressed) + int32_t FieldsReader::addFieldSize(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed) { int32_t size = fieldsStream->readVInt(); int32_t bytesize = (binary || compressed) ? size : 2 * size; @@ -379,7 +379,7 @@ namespace Lucene return L""; } - LazyField::LazyField(FieldsReaderPtr reader, const String& name, Field::Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : + LazyField::LazyField(const FieldsReaderPtr& reader, const String& name, Field::Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : AbstractField(name, store, Field::INDEX_NO, Field::TERM_VECTOR_NO) { this->_reader = reader; @@ -392,7 +392,7 @@ namespace Lucene this->isCompressed = isCompressed; } - LazyField::LazyField(FieldsReaderPtr reader, const String& name, Field::Store store, Field::Index index, Field::TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : + LazyField::LazyField(const FieldsReaderPtr& reader, const String& name, Field::Store store, Field::Index index, Field::TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : AbstractField(name, store, index, termVector) { this->_reader = reader; diff --git a/src/core/index/FieldsWriter.cpp b/src/core/index/FieldsWriter.cpp index 36f5008a..cb53dcae 100644 --- a/src/core/index/FieldsWriter.cpp +++ b/src/core/index/FieldsWriter.cpp @@ -30,7 +30,7 @@ namespace Lucene // switch to a new format! const int32_t FieldsWriter::FORMAT_CURRENT = FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS; - FieldsWriter::FieldsWriter(DirectoryPtr d, const String& segment, FieldInfosPtr fn) + FieldsWriter::FieldsWriter(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn) { fieldInfos = fn; @@ -91,7 +91,7 @@ namespace Lucene doClose = true; } - FieldsWriter::FieldsWriter(IndexOutputPtr fdx, IndexOutputPtr fdt, FieldInfosPtr fn) + FieldsWriter::FieldsWriter(const IndexOutputPtr& fdx, const IndexOutputPtr& fdt, const FieldInfosPtr& fn) { fieldInfos = fn; fieldsStream = fdt; @@ -103,12 +103,12 @@ namespace Lucene { } - void FieldsWriter::setFieldsStream(IndexOutputPtr stream) + void FieldsWriter::setFieldsStream(const IndexOutputPtr& stream) { this->fieldsStream = stream; } - void FieldsWriter::flushDocument(int32_t numStoredFields, RAMOutputStreamPtr buffer) + void FieldsWriter::flushDocument(int32_t numStoredFields, const RAMOutputStreamPtr& buffer) { TestScope testScope(L"FieldsWriter", L"flushDocument"); indexStream->writeLong(fieldsStream->getFilePointer()); @@ -162,7 +162,7 @@ namespace Lucene } } - void FieldsWriter::writeField(FieldInfoPtr fi, FieldablePtr field) + void FieldsWriter::writeField(const FieldInfoPtr& fi, const FieldablePtr& field) { fieldsStream->writeVInt(fi->number); uint8_t bits = 0; @@ -186,7 +186,7 @@ namespace Lucene fieldsStream->writeString(field->stringValue()); } - void FieldsWriter::addRawDocuments(IndexInputPtr stream, Collection lengths, int32_t numDocs) + void FieldsWriter::addRawDocuments(const IndexInputPtr& stream, Collection lengths, int32_t numDocs) { int64_t position = fieldsStream->getFilePointer(); int64_t start = position; @@ -199,7 +199,7 @@ namespace Lucene BOOST_ASSERT(fieldsStream->getFilePointer() == position); } - void FieldsWriter::addDocument(DocumentPtr doc) + void FieldsWriter::addDocument(const DocumentPtr& doc) { indexStream->writeLong(fieldsStream->getFilePointer()); diff --git a/src/core/index/FilterIndexReader.cpp b/src/core/index/FilterIndexReader.cpp index d1521fcc..0cce9635 100644 --- a/src/core/index/FilterIndexReader.cpp +++ b/src/core/index/FilterIndexReader.cpp @@ -10,7 +10,7 @@ namespace Lucene { - FilterIndexReader::FilterIndexReader(IndexReaderPtr in) + FilterIndexReader::FilterIndexReader(const IndexReaderPtr& in) { this->in = in; } @@ -36,13 +36,13 @@ namespace Lucene return in->getTermFreqVector(docNumber, field); } - void FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) + void FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { ensureOpen(); in->getTermFreqVector(docNumber, field, mapper); } - void FilterIndexReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) + void FilterIndexReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { ensureOpen(); in->getTermFreqVector(docNumber, mapper); @@ -60,7 +60,7 @@ namespace Lucene return in->maxDoc(); } - DocumentPtr FilterIndexReader::document(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr FilterIndexReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { ensureOpen(); return in->document(n, fieldSelector); @@ -112,13 +112,13 @@ namespace Lucene return in->terms(); } - TermEnumPtr FilterIndexReader::terms(TermPtr t) + TermEnumPtr FilterIndexReader::terms(const TermPtr& t) { ensureOpen(); return in->terms(t); } - int32_t FilterIndexReader::docFreq(TermPtr t) + int32_t FilterIndexReader::docFreq(const TermPtr& t) { ensureOpen(); return in->docFreq(t); @@ -130,7 +130,7 @@ namespace Lucene return in->termDocs(); } - TermDocsPtr FilterIndexReader::termDocs(TermPtr term) + TermDocsPtr FilterIndexReader::termDocs(const TermPtr& term) { ensureOpen(); return in->termDocs(term); @@ -200,7 +200,7 @@ namespace Lucene return in->getDeletesCacheKey(); } - FilterTermDocs::FilterTermDocs(TermDocsPtr in) + FilterTermDocs::FilterTermDocs(const TermDocsPtr& in) { this->in = in; } @@ -209,12 +209,12 @@ namespace Lucene { } - void FilterTermDocs::seek(TermPtr term) + void FilterTermDocs::seek(const TermPtr& term) { in->seek(term); } - void FilterTermDocs::seek(TermEnumPtr termEnum) + void FilterTermDocs::seek(const TermEnumPtr& termEnum) { in->seek(termEnum); } @@ -249,7 +249,7 @@ namespace Lucene in->close(); } - FilterTermPositions::FilterTermPositions(TermPositionsPtr in) : FilterTermDocs(in) + FilterTermPositions::FilterTermPositions(const TermPositionsPtr& in) : FilterTermDocs(in) { } @@ -277,7 +277,7 @@ namespace Lucene return boost::static_pointer_cast(in)->isPayloadAvailable(); } - FilterTermEnum::FilterTermEnum(TermEnumPtr in) + FilterTermEnum::FilterTermEnum(const TermEnumPtr& in) { this->in = in; } diff --git a/src/core/index/FormatPostingsDocsWriter.cpp b/src/core/index/FormatPostingsDocsWriter.cpp index b09b689d..975227cc 100644 --- a/src/core/index/FormatPostingsDocsWriter.cpp +++ b/src/core/index/FormatPostingsDocsWriter.cpp @@ -23,7 +23,7 @@ namespace Lucene { - FormatPostingsDocsWriter::FormatPostingsDocsWriter(SegmentWriteStatePtr state, FormatPostingsTermsWriterPtr parent) + FormatPostingsDocsWriter::FormatPostingsDocsWriter(const SegmentWriteStatePtr& state, const FormatPostingsTermsWriterPtr& parent) { this->lastDocID = 0; this->df = 0; @@ -56,7 +56,7 @@ namespace Lucene posWriter = newLucene(state, shared_from_this()); } - void FormatPostingsDocsWriter::setField(FieldInfoPtr fieldInfo) + void FormatPostingsDocsWriter::setField(const FieldInfoPtr& fieldInfo) { this->fieldInfo = fieldInfo; omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; diff --git a/src/core/index/FormatPostingsFieldsWriter.cpp b/src/core/index/FormatPostingsFieldsWriter.cpp index a6f3bc79..64804ad3 100644 --- a/src/core/index/FormatPostingsFieldsWriter.cpp +++ b/src/core/index/FormatPostingsFieldsWriter.cpp @@ -14,7 +14,7 @@ namespace Lucene { - FormatPostingsFieldsWriter::FormatPostingsFieldsWriter(SegmentWriteStatePtr state, FieldInfosPtr fieldInfos) + FormatPostingsFieldsWriter::FormatPostingsFieldsWriter(const SegmentWriteStatePtr& state, const FieldInfosPtr& fieldInfos) { dir = state->directory; segment = state->segmentName; @@ -38,7 +38,7 @@ namespace Lucene termsWriter = newLucene(state, shared_from_this()); } - FormatPostingsTermsConsumerPtr FormatPostingsFieldsWriter::addField(FieldInfoPtr field) + FormatPostingsTermsConsumerPtr FormatPostingsFieldsWriter::addField(const FieldInfoPtr& field) { termsWriter->setField(field); return termsWriter; diff --git a/src/core/index/FormatPostingsPositionsWriter.cpp b/src/core/index/FormatPostingsPositionsWriter.cpp index 40af6d42..7ccf8fae 100644 --- a/src/core/index/FormatPostingsPositionsWriter.cpp +++ b/src/core/index/FormatPostingsPositionsWriter.cpp @@ -19,7 +19,7 @@ namespace Lucene { - FormatPostingsPositionsWriter::FormatPostingsPositionsWriter(SegmentWriteStatePtr state, FormatPostingsDocsWriterPtr parent) + FormatPostingsPositionsWriter::FormatPostingsPositionsWriter(const SegmentWriteStatePtr& state, const FormatPostingsDocsWriterPtr& parent) { lastPosition = 0; storePayloads = false; @@ -73,7 +73,7 @@ namespace Lucene out->writeVInt(delta); } - void FormatPostingsPositionsWriter::setField(FieldInfoPtr fieldInfo) + void FormatPostingsPositionsWriter::setField(const FieldInfoPtr& fieldInfo) { omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; storePayloads = omitTermFreqAndPositions ? false : fieldInfo->storePayloads; diff --git a/src/core/index/FormatPostingsTermsWriter.cpp b/src/core/index/FormatPostingsTermsWriter.cpp index 8dbe2e41..8e83260b 100644 --- a/src/core/index/FormatPostingsTermsWriter.cpp +++ b/src/core/index/FormatPostingsTermsWriter.cpp @@ -14,7 +14,7 @@ namespace Lucene { - FormatPostingsTermsWriter::FormatPostingsTermsWriter(SegmentWriteStatePtr state, FormatPostingsFieldsWriterPtr parent) + FormatPostingsTermsWriter::FormatPostingsTermsWriter(const SegmentWriteStatePtr& state, const FormatPostingsFieldsWriterPtr& parent) { currentTermStart = 0; freqStart = 0; @@ -34,7 +34,7 @@ namespace Lucene docsWriter = newLucene(state, shared_from_this()); } - void FormatPostingsTermsWriter::setField(FieldInfoPtr fieldInfo) + void FormatPostingsTermsWriter::setField(const FieldInfoPtr& fieldInfo) { this->fieldInfo = fieldInfo; docsWriter->setField(fieldInfo); diff --git a/src/core/index/FreqProxFieldMergeState.cpp b/src/core/index/FreqProxFieldMergeState.cpp index 429f5246..7f6e4ef4 100644 --- a/src/core/index/FreqProxFieldMergeState.cpp +++ b/src/core/index/FreqProxFieldMergeState.cpp @@ -19,7 +19,7 @@ namespace Lucene { - FreqProxFieldMergeState::FreqProxFieldMergeState(FreqProxTermsWriterPerFieldPtr field) + FreqProxFieldMergeState::FreqProxFieldMergeState(const FreqProxTermsWriterPerFieldPtr& field) { this->numPostings = 0; this->textOffset = 0; diff --git a/src/core/index/FreqProxTermsWriter.cpp b/src/core/index/FreqProxTermsWriter.cpp index 4d24cfe8..10fc5f84 100644 --- a/src/core/index/FreqProxTermsWriter.cpp +++ b/src/core/index/FreqProxTermsWriter.cpp @@ -31,7 +31,7 @@ namespace Lucene { } - TermsHashConsumerPerThreadPtr FreqProxTermsWriter::addThread(TermsHashPerThreadPtr perThread) + TermsHashConsumerPerThreadPtr FreqProxTermsWriter::addThread(const TermsHashPerThreadPtr& perThread) { return newLucene(perThread); } @@ -63,7 +63,7 @@ namespace Lucene } } - void FreqProxTermsWriter::closeDocStore(SegmentWriteStatePtr state) + void FreqProxTermsWriter::closeDocStore(const SegmentWriteStatePtr& state) { } @@ -71,7 +71,7 @@ namespace Lucene { } - void FreqProxTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state) + void FreqProxTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { // Gather all FieldData's that have postings, across all ThreadStates Collection allFields(Collection::newInstance()); @@ -144,7 +144,7 @@ namespace Lucene consumer->finish(); } - void FreqProxTermsWriter::appendPostings(Collection fields, FormatPostingsFieldsConsumerPtr consumer) + void FreqProxTermsWriter::appendPostings(Collection fields, const FormatPostingsFieldsConsumerPtr& consumer) { TestScope testScope(L"FreqProxTermsWriter", L"appendPostings"); int32_t numFields = fields.size(); diff --git a/src/core/index/FreqProxTermsWriterPerField.cpp b/src/core/index/FreqProxTermsWriterPerField.cpp index b2d29898..2e630e67 100644 --- a/src/core/index/FreqProxTermsWriterPerField.cpp +++ b/src/core/index/FreqProxTermsWriterPerField.cpp @@ -19,7 +19,7 @@ namespace Lucene { - FreqProxTermsWriterPerField::FreqProxTermsWriterPerField(TermsHashPerFieldPtr termsHashPerField, FreqProxTermsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo) + FreqProxTermsWriterPerField::FreqProxTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const FreqProxTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { this->hasPayloads = false; this->_termsHashPerField = termsHashPerField; @@ -47,7 +47,7 @@ namespace Lucene { } - int32_t FreqProxTermsWriterPerField::compareTo(LuceneObjectPtr other) + int32_t FreqProxTermsWriterPerField::compareTo(const LuceneObjectPtr& other) { return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); } @@ -69,7 +69,7 @@ namespace Lucene return false; } - void FreqProxTermsWriterPerField::start(FieldablePtr field) + void FreqProxTermsWriterPerField::start(const FieldablePtr& field) { if (fieldState->attributeSource->hasAttribute()) payloadAttribute = fieldState->attributeSource->getAttribute(); @@ -77,7 +77,7 @@ namespace Lucene payloadAttribute.reset(); } - void FreqProxTermsWriterPerField::writeProx(FreqProxTermsWriterPostingListPtr p, int32_t proxCode) + void FreqProxTermsWriterPerField::writeProx(const FreqProxTermsWriterPostingListPtr& p, int32_t proxCode) { PayloadPtr payload; if (payloadAttribute) @@ -97,7 +97,7 @@ namespace Lucene p->lastPosition = fieldState->position; } - void FreqProxTermsWriterPerField::newTerm(RawPostingListPtr p) + void FreqProxTermsWriterPerField::newTerm(const RawPostingListPtr& p) { // First time we're seeing this term since the last flush BOOST_ASSERT(docState->testPoint(L"FreqProxTermsWriterPerField.newTerm start")); @@ -113,7 +113,7 @@ namespace Lucene } } - void FreqProxTermsWriterPerField::addTerm(RawPostingListPtr p) + void FreqProxTermsWriterPerField::addTerm(const RawPostingListPtr& p) { BOOST_ASSERT(docState->testPoint(L"FreqProxTermsWriterPerField.addTerm start")); diff --git a/src/core/index/FreqProxTermsWriterPerThread.cpp b/src/core/index/FreqProxTermsWriterPerThread.cpp index 2ada6d8a..4fd7d4cd 100644 --- a/src/core/index/FreqProxTermsWriterPerThread.cpp +++ b/src/core/index/FreqProxTermsWriterPerThread.cpp @@ -11,7 +11,7 @@ namespace Lucene { - FreqProxTermsWriterPerThread::FreqProxTermsWriterPerThread(TermsHashPerThreadPtr perThread) + FreqProxTermsWriterPerThread::FreqProxTermsWriterPerThread(const TermsHashPerThreadPtr& perThread) { docState = perThread->docState; _termsHashPerThread = perThread; @@ -21,7 +21,7 @@ namespace Lucene { } - TermsHashConsumerPerFieldPtr FreqProxTermsWriterPerThread::addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo) + TermsHashConsumerPerFieldPtr FreqProxTermsWriterPerThread::addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) { return newLucene(termsHashPerField, shared_from_this(), fieldInfo); } diff --git a/src/core/index/IndexCommit.cpp b/src/core/index/IndexCommit.cpp index 1d080145..ca2059fe 100644 --- a/src/core/index/IndexCommit.cpp +++ b/src/core/index/IndexCommit.cpp @@ -14,7 +14,7 @@ namespace Lucene { } - bool IndexCommit::equals(LuceneObjectPtr other) + bool IndexCommit::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/index/IndexFileDeleter.cpp b/src/core/index/IndexFileDeleter.cpp index 32dd7a50..e0564512 100644 --- a/src/core/index/IndexFileDeleter.cpp +++ b/src/core/index/IndexFileDeleter.cpp @@ -25,7 +25,7 @@ namespace Lucene /// Change to true to see details of reference counts when infoStream != null bool IndexFileDeleter::VERBOSE_REF_COUNTS = false; - IndexFileDeleter::IndexFileDeleter(DirectoryPtr directory, IndexDeletionPolicyPtr policy, SegmentInfosPtr segmentInfos, InfoStreamPtr infoStream, DocumentsWriterPtr docWriter, HashSet synced) + IndexFileDeleter::IndexFileDeleter(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& policy, const SegmentInfosPtr& segmentInfos, const InfoStreamPtr& infoStream, const DocumentsWriterPtr& docWriter, HashSet synced) { this->lastFiles = Collection< HashSet >::newInstance(); this->commits = Collection::newInstance(); @@ -149,7 +149,7 @@ namespace Lucene { } - void IndexFileDeleter::setInfoStream(InfoStreamPtr infoStream) + void IndexFileDeleter::setInfoStream(const InfoStreamPtr& infoStream) { this->infoStream = infoStream; } @@ -256,7 +256,7 @@ namespace Lucene } } - void IndexFileDeleter::checkpoint(SegmentInfosPtr segmentInfos, bool isCommit) + void IndexFileDeleter::checkpoint(const SegmentInfosPtr& segmentInfos, bool isCommit) { if (infoStream) message(L"now checkpoint \"" + segmentInfos->getCurrentSegmentFileName() + L"\" [" + StringUtils::toString(segmentInfos->size()) + L" segments; isCommit = " + StringUtils::toString(isCommit) + L"]"); @@ -305,7 +305,7 @@ namespace Lucene } } - void IndexFileDeleter::incRef(SegmentInfosPtr segmentInfos, bool isCommit) + void IndexFileDeleter::incRef(const SegmentInfosPtr& segmentInfos, bool isCommit) { // If this is a commit point, also incRef the segments_N file HashSet files(segmentInfos->files(directory, isCommit)); @@ -352,7 +352,7 @@ namespace Lucene } } - void IndexFileDeleter::decRef(SegmentInfosPtr segmentInfos) + void IndexFileDeleter::decRef(const SegmentInfosPtr& segmentInfos) { decRef(segmentInfos->files(directory, false)); } @@ -445,7 +445,7 @@ namespace Lucene return --count; } - CommitPoint::CommitPoint(Collection commitsToDelete, DirectoryPtr directory, SegmentInfosPtr segmentInfos) + CommitPoint::CommitPoint(Collection commitsToDelete, const DirectoryPtr& directory, const SegmentInfosPtr& segmentInfos) { deleted = false; @@ -521,7 +521,7 @@ namespace Lucene return deleted; } - int32_t CommitPoint::compareTo(LuceneObjectPtr other) + int32_t CommitPoint::compareTo(const LuceneObjectPtr& other) { CommitPointPtr otherCommit(boost::static_pointer_cast(other)); if (gen < otherCommit->gen) diff --git a/src/core/index/IndexReader.cpp b/src/core/index/IndexReader.cpp index b3de1318..08561449 100644 --- a/src/core/index/IndexReader.cpp +++ b/src/core/index/IndexReader.cpp @@ -66,42 +66,42 @@ namespace Lucene boost::throw_exception(AlreadyClosedException(L"this IndexReader is closed")); } - IndexReaderPtr IndexReader::open(DirectoryPtr directory) + IndexReaderPtr IndexReader::open(const DirectoryPtr& directory) { return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), true, DEFAULT_TERMS_INDEX_DIVISOR); } - IndexReaderPtr IndexReader::open(DirectoryPtr directory, bool readOnly) + IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, bool readOnly) { return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - IndexReaderPtr IndexReader::open(IndexCommitPtr commit, bool readOnly) + IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, bool readOnly) { return open(commit->getDirectory(), IndexDeletionPolicyPtr(), commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - IndexReaderPtr IndexReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly) + IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly) { return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - IndexReaderPtr IndexReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) + IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, termInfosIndexDivisor); } - IndexReaderPtr IndexReader::open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly) + IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly) { return open(commit->getDirectory(), deletionPolicy, commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); } - IndexReaderPtr IndexReader::open(IndexCommitPtr commit, IndexDeletionPolicyPtr deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) + IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { return open(commit->getDirectory(), deletionPolicy, commit, readOnly, termInfosIndexDivisor); } - IndexReaderPtr IndexReader::open(DirectoryPtr directory, IndexDeletionPolicyPtr deletionPolicy, IndexCommitPtr commit, bool readOnly, int32_t termInfosIndexDivisor) + IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor) { return DirectoryReader::open(directory, deletionPolicy, commit, readOnly, termInfosIndexDivisor); } @@ -120,14 +120,14 @@ namespace Lucene return IndexReaderPtr(); } - IndexReaderPtr IndexReader::reopen(IndexCommitPtr commit) + IndexReaderPtr IndexReader::reopen(const IndexCommitPtr& commit) { SyncLock syncLock(this); boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen(IndexCommit).")); return IndexReaderPtr(); } - LuceneObjectPtr IndexReader::clone(LuceneObjectPtr other) + LuceneObjectPtr IndexReader::clone(const LuceneObjectPtr& other) { SyncLock syncLock(this); if (!other) @@ -135,7 +135,7 @@ namespace Lucene return other; } - LuceneObjectPtr IndexReader::clone(bool openReadOnly, LuceneObjectPtr other) + LuceneObjectPtr IndexReader::clone(bool openReadOnly, const LuceneObjectPtr& other) { SyncLock syncLock(this); if (!other) @@ -150,17 +150,17 @@ namespace Lucene return DirectoryPtr(); } - int64_t IndexReader::lastModified(DirectoryPtr directory2) + int64_t IndexReader::lastModified(const DirectoryPtr& directory2) { return newLucene(newLucene(), directory2)->run(); } - int64_t IndexReader::getCurrentVersion(DirectoryPtr directory) + int64_t IndexReader::getCurrentVersion(const DirectoryPtr& directory) { return SegmentInfos::readCurrentVersion(directory); } - MapStringString IndexReader::getCommitUserData(DirectoryPtr directory) + MapStringString IndexReader::getCommitUserData(const DirectoryPtr& directory) { return SegmentInfos::readCurrentUserData(directory); } @@ -189,7 +189,7 @@ namespace Lucene return false; } - bool IndexReader::indexExists(DirectoryPtr directory) + bool IndexReader::indexExists(const DirectoryPtr& directory) { return (SegmentInfos::getCurrentSegmentGeneration(directory) != -1); } @@ -233,7 +233,7 @@ namespace Lucene setNorm(doc, field, Similarity::encodeNorm(value)); } - TermDocsPtr IndexReader::termDocs(TermPtr term) + TermDocsPtr IndexReader::termDocs(const TermPtr& term) { ensureOpen(); TermDocsPtr _termDocs(termDocs()); @@ -241,7 +241,7 @@ namespace Lucene return _termDocs; } - TermPositionsPtr IndexReader::termPositions(TermPtr term) + TermPositionsPtr IndexReader::termPositions(const TermPtr& term) { ensureOpen(); TermPositionsPtr _termPositions(termPositions()); @@ -258,7 +258,7 @@ namespace Lucene doDelete(docNum); } - int32_t IndexReader::deleteDocuments(TermPtr term) + int32_t IndexReader::deleteDocuments(const TermPtr& term) { ensureOpen(); TermDocsPtr docs(termDocs(term)); @@ -416,7 +416,7 @@ namespace Lucene finally.throwException(); } - Collection IndexReader::listCommits(DirectoryPtr dir) + Collection IndexReader::listCommits(const DirectoryPtr& dir) { return DirectoryReader::listCommits(dir); } @@ -448,7 +448,7 @@ namespace Lucene return 0; } - FindSegmentsModified::FindSegmentsModified(SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) + FindSegmentsModified::FindSegmentsModified(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { result = 0; } diff --git a/src/core/index/IndexWriter.cpp b/src/core/index/IndexWriter.cpp index 22d59afb..3b1aec9e 100644 --- a/src/core/index/IndexWriter.cpp +++ b/src/core/index/IndexWriter.cpp @@ -69,7 +69,7 @@ namespace Lucene /// Sets the maximum field length to {@link #DEFAULT_MAX_FIELD_LENGTH} const int32_t IndexWriter::MaxFieldLengthLIMITED = IndexWriter::DEFAULT_MAX_FIELD_LENGTH; - IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) + IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) { this->directory = d; this->analyzer = a; @@ -77,7 +77,7 @@ namespace Lucene this->maxFieldLength = mfl; } - IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, int32_t mfl) + IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl) { this->directory = d; this->analyzer = a; @@ -85,7 +85,7 @@ namespace Lucene this->maxFieldLength = mfl; } - IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl) + IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl) { this->directory = d; this->analyzer = a; @@ -94,7 +94,7 @@ namespace Lucene this->maxFieldLength = mfl; } - IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl) + IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl) { this->directory = d; this->analyzer = a; @@ -103,7 +103,7 @@ namespace Lucene this->maxFieldLength = mfl; } - IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexingChainPtr indexingChain, IndexCommitPtr commit) + IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexingChainPtr& indexingChain, const IndexCommitPtr& commit) { this->directory = d; this->analyzer = a; @@ -114,7 +114,7 @@ namespace Lucene this->indexCommit = commit; } - IndexWriter::IndexWriter(DirectoryPtr d, AnalyzerPtr a, IndexDeletionPolicyPtr deletionPolicy, int32_t mfl, IndexCommitPtr commit) + IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexCommitPtr& commit) { this->directory = d; this->analyzer = a; @@ -319,7 +319,7 @@ namespace Lucene return r; } - int32_t IndexWriter::numDeletedDocs(SegmentInfoPtr info) + int32_t IndexWriter::numDeletedDocs(const SegmentInfoPtr& info) { SegmentReaderPtr reader(readerPool->getIfExists(info)); int32_t deletedDocs = 0; @@ -416,7 +416,7 @@ namespace Lucene } } - void IndexWriter::setMessageID(InfoStreamPtr infoStream) + void IndexWriter::setMessageID(const InfoStreamPtr& infoStream) { SyncLock syncLock(this); if (infoStream && messageID == -1) @@ -447,7 +447,7 @@ namespace Lucene getLogMergePolicy()->setUseCompoundDocStore(value); } - void IndexWriter::setSimilarity(SimilarityPtr similarity) + void IndexWriter::setSimilarity(const SimilarityPtr& similarity) { ensureOpen(); this->similarity = similarity; @@ -473,7 +473,7 @@ namespace Lucene return termIndexInterval; } - void IndexWriter::setRollbackSegmentInfos(SegmentInfosPtr infos) + void IndexWriter::setRollbackSegmentInfos(const SegmentInfosPtr& infos) { SyncLock syncLock(this); rollbackSegmentInfos = boost::dynamic_pointer_cast(infos->clone()); @@ -484,7 +484,7 @@ namespace Lucene rollbackSegments.put(rollbackSegmentInfos->info(i), i); } - void IndexWriter::setMergePolicy(MergePolicyPtr mp) + void IndexWriter::setMergePolicy(const MergePolicyPtr& mp) { ensureOpen(); if (!mp) @@ -504,7 +504,7 @@ namespace Lucene return mergePolicy; } - void IndexWriter::setMergeScheduler(MergeSchedulerPtr mergeScheduler) + void IndexWriter::setMergeScheduler(const MergeSchedulerPtr& mergeScheduler) { SyncLock syncLock(this); ensureOpen(); @@ -648,7 +648,7 @@ namespace Lucene return getLogMergePolicy()->getMergeFactor(); } - void IndexWriter::setDefaultInfoStream(InfoStreamPtr infoStream) + void IndexWriter::setDefaultInfoStream(const InfoStreamPtr& infoStream) { IndexWriter::defaultInfoStream = infoStream; } @@ -658,7 +658,7 @@ namespace Lucene return IndexWriter::defaultInfoStream; } - void IndexWriter::setInfoStream(InfoStreamPtr infoStream) + void IndexWriter::setInfoStream(const InfoStreamPtr& infoStream) { ensureOpen(); setMessageID(infoStream); @@ -965,12 +965,12 @@ namespace Lucene return false; } - void IndexWriter::addDocument(DocumentPtr doc) + void IndexWriter::addDocument(const DocumentPtr& doc) { addDocument(doc, analyzer); } - void IndexWriter::addDocument(DocumentPtr doc, AnalyzerPtr analyzer) + void IndexWriter::addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer) { ensureOpen(); bool doFlush = false; @@ -1012,7 +1012,7 @@ namespace Lucene } } - void IndexWriter::deleteDocuments(TermPtr term) + void IndexWriter::deleteDocuments(const TermPtr& term) { ensureOpen(); try @@ -1042,7 +1042,7 @@ namespace Lucene } } - void IndexWriter::deleteDocuments(QueryPtr query) + void IndexWriter::deleteDocuments(const QueryPtr& query) { ensureOpen(); bool doFlush = docWriter->bufferDeleteQuery(query); @@ -1058,13 +1058,13 @@ namespace Lucene flush(true, false, false); } - void IndexWriter::updateDocument(TermPtr term, DocumentPtr doc) + void IndexWriter::updateDocument(const TermPtr& term, const DocumentPtr& doc) { ensureOpen(); updateDocument(term, doc, getAnalyzer()); } - void IndexWriter::updateDocument(TermPtr term, DocumentPtr doc, AnalyzerPtr analyzer) + void IndexWriter::updateDocument(const TermPtr& term, const DocumentPtr& doc, const AnalyzerPtr& analyzer) { ensureOpen(); try @@ -2463,7 +2463,7 @@ namespace Lucene return docWriter->getNumDocsInRAM(); } - int32_t IndexWriter::ensureContiguousMerge(OneMergePtr merge) + int32_t IndexWriter::ensureContiguousMerge(const OneMergePtr& merge) { int32_t first = segmentInfos->find(merge->segments->info(0)); if (first == -1) @@ -2488,7 +2488,7 @@ namespace Lucene return first; } - void IndexWriter::commitMergedDeletes(OneMergePtr merge, SegmentReaderPtr mergeReader) + void IndexWriter::commitMergedDeletes(const OneMergePtr& merge, const SegmentReaderPtr& mergeReader) { SyncLock syncLock(this); BOOST_ASSERT(testPoint(L"startCommitMergeDeletes")); @@ -2560,7 +2560,7 @@ namespace Lucene mergeReader->_hasChanges = (delCount > 0); } - bool IndexWriter::commitMerge(OneMergePtr merge, SegmentMergerPtr merger, int32_t mergedDocCount, SegmentReaderPtr mergedReader) + bool IndexWriter::commitMerge(const OneMergePtr& merge, const SegmentMergerPtr& merger, int32_t mergedDocCount, const SegmentReaderPtr& mergedReader) { SyncLock syncLock(this); BOOST_ASSERT(testPoint(L"startCommitMerge")); @@ -2615,7 +2615,7 @@ namespace Lucene return true; } - LuceneException IndexWriter::handleMergeException(const LuceneException& exc, OneMergePtr merge) + LuceneException IndexWriter::handleMergeException(const LuceneException& exc, const OneMergePtr& merge) { if (infoStream) message(L"handleMergeException: merge=" + merge->segString(directory) + L" exc=" + exc.getError()); @@ -2642,7 +2642,7 @@ namespace Lucene return LuceneException(); } - void IndexWriter::merge(OneMergePtr merge) + void IndexWriter::merge(const OneMergePtr& merge) { bool success = false; @@ -2697,12 +2697,12 @@ namespace Lucene } } - void IndexWriter::mergeSuccess(OneMergePtr merge) + void IndexWriter::mergeSuccess(const OneMergePtr& merge) { // override } - bool IndexWriter::registerMerge(OneMergePtr merge) + bool IndexWriter::registerMerge(const OneMergePtr& merge) { SyncLock syncLock(this); @@ -2753,7 +2753,7 @@ namespace Lucene return true; } - void IndexWriter::mergeInit(OneMergePtr merge) + void IndexWriter::mergeInit(const OneMergePtr& merge) { SyncLock syncLock(this); bool success = false; @@ -2773,7 +2773,7 @@ namespace Lucene finally.throwException(); } - void IndexWriter::_mergeInit(OneMergePtr merge) + void IndexWriter::_mergeInit(const OneMergePtr& merge) { SyncLock syncLock(this); bool test = testPoint(L"startMergeInit"); @@ -2897,12 +2897,12 @@ namespace Lucene mergingSegments.add(merge->info); } - void IndexWriter::setDiagnostics(SegmentInfoPtr info, const String& source) + void IndexWriter::setDiagnostics(const SegmentInfoPtr& info, const String& source) { setDiagnostics(info, source, MapStringString()); } - void IndexWriter::setDiagnostics(SegmentInfoPtr info, const String& source, MapStringString details) + void IndexWriter::setDiagnostics(const SegmentInfoPtr& info, const String& source, MapStringString details) { MapStringString diagnostics(MapStringString::newInstance()); diagnostics.put(L"source", source); @@ -2913,7 +2913,7 @@ namespace Lucene info->setDiagnostics(diagnostics); } - void IndexWriter::mergeFinish(OneMergePtr merge) + void IndexWriter::mergeFinish(const OneMergePtr& merge) { SyncLock syncLock(this); // Optimize, addIndexes or finishMerges may be waiting on merges to finish. @@ -2934,7 +2934,7 @@ namespace Lucene runningMerges.remove(merge); } - void IndexWriter::setMergeDocStoreIsCompoundFile(OneMergePtr merge) + void IndexWriter::setMergeDocStoreIsCompoundFile(const OneMergePtr& merge) { SyncLock syncLock(this); @@ -2955,7 +2955,7 @@ namespace Lucene } } - void IndexWriter::closeMergeReaders(OneMergePtr merge, bool suppressExceptions) + void IndexWriter::closeMergeReaders(const OneMergePtr& merge, bool suppressExceptions) { SyncLock syncLock(this); @@ -3013,7 +3013,7 @@ namespace Lucene } } - int32_t IndexWriter::mergeMiddle(OneMergePtr merge) + int32_t IndexWriter::mergeMiddle(const OneMergePtr& merge) { merge->checkAborted(directory); @@ -3222,7 +3222,7 @@ namespace Lucene return mergedDocCount; } - void IndexWriter::addMergeException(OneMergePtr merge) + void IndexWriter::addMergeException(const OneMergePtr& merge) { SyncLock syncLock(this); BOOST_ASSERT(!merge->getException().isNull()); @@ -3282,7 +3282,7 @@ namespace Lucene return segString(segmentInfos); } - String IndexWriter::segString(SegmentInfosPtr infos) + String IndexWriter::segString(const SegmentInfosPtr& infos) { SyncLock syncLock(this); StringStream buffer; @@ -3581,17 +3581,17 @@ namespace Lucene BOOST_ASSERT(testPoint(L"finishStartCommit")); } - bool IndexWriter::isLocked(DirectoryPtr directory) + bool IndexWriter::isLocked(const DirectoryPtr& directory) { return directory->makeLock(WRITE_LOCK_NAME)->isLocked(); } - void IndexWriter::unlock(DirectoryPtr directory) + void IndexWriter::unlock(const DirectoryPtr& directory) { directory->makeLock(IndexWriter::WRITE_LOCK_NAME)->release(); } - void IndexWriter::setMergedSegmentWarmer(IndexReaderWarmerPtr warmer) + void IndexWriter::setMergedSegmentWarmer(const IndexReaderWarmerPtr& warmer) { mergedSegmentWarmer = warmer; } @@ -3614,7 +3614,7 @@ namespace Lucene return true; } - bool IndexWriter::nrtIsCurrent(SegmentInfosPtr infos) + bool IndexWriter::nrtIsCurrent(const SegmentInfosPtr& infos) { SyncLock syncLock(this); if (!infos->equals(segmentInfos)) @@ -3637,7 +3637,7 @@ namespace Lucene return closed; } - ReaderPool::ReaderPool(IndexWriterPtr writer) + ReaderPool::ReaderPool(const IndexWriterPtr& writer) { readerMap = MapSegmentInfoSegmentReader::newInstance(); _indexWriter = writer; @@ -3647,7 +3647,7 @@ namespace Lucene { } - void ReaderPool::clear(SegmentInfosPtr infos) + void ReaderPool::clear(const SegmentInfosPtr& infos) { SyncLock syncLock(this); if (!infos) @@ -3666,7 +3666,7 @@ namespace Lucene } } - bool ReaderPool::infoIsLive(SegmentInfoPtr info) + bool ReaderPool::infoIsLive(const SegmentInfoPtr& info) { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); @@ -3676,22 +3676,23 @@ namespace Lucene return true; } - SegmentInfoPtr ReaderPool::mapToLive(SegmentInfoPtr info) + SegmentInfoPtr ReaderPool::mapToLive(const SegmentInfoPtr& info) { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); int32_t idx = indexWriter->segmentInfos->find(info); + SegmentInfoPtr _info(info); if (idx != -1) - info = indexWriter->segmentInfos->info(idx); - return info; + _info = indexWriter->segmentInfos->info(idx); + return _info; } - void ReaderPool::release(SegmentReaderPtr sr) + void ReaderPool::release(const SegmentReaderPtr& sr) { release(sr, false); } - void ReaderPool::release(SegmentReaderPtr sr, bool drop) + void ReaderPool::release(const SegmentReaderPtr& sr, bool drop) { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); @@ -3778,7 +3779,7 @@ namespace Lucene } } - IndexReaderPtr ReaderPool::getReadOnlyClone(SegmentInfoPtr info, bool doOpenStores, int32_t termInfosIndexDivisor) + IndexReaderPtr ReaderPool::getReadOnlyClone(const SegmentInfoPtr& info, bool doOpenStores, int32_t termInfosIndexDivisor) { SyncLock syncLock(this); SegmentReaderPtr sr(get(info, doOpenStores, BufferedIndexInput::BUFFER_SIZE, termInfosIndexDivisor)); @@ -3797,12 +3798,12 @@ namespace Lucene return clone; } - SegmentReaderPtr ReaderPool::get(SegmentInfoPtr info, bool doOpenStores) + SegmentReaderPtr ReaderPool::get(const SegmentInfoPtr& info, bool doOpenStores) { return get(info, doOpenStores, BufferedIndexInput::BUFFER_SIZE, IndexWriterPtr(_indexWriter)->readerTermsIndexDivisor); } - SegmentReaderPtr ReaderPool::get(SegmentInfoPtr info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor) + SegmentReaderPtr ReaderPool::get(const SegmentInfoPtr& info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor) { SyncLock syncLock(this); IndexWriterPtr indexWriter(_indexWriter); @@ -3842,7 +3843,7 @@ namespace Lucene return sr; } - SegmentReaderPtr ReaderPool::getIfExists(SegmentInfoPtr info) + SegmentReaderPtr ReaderPool::getIfExists(const SegmentInfoPtr& info) { SyncLock syncLock(this); SegmentReaderPtr sr(readerMap.get(info)); diff --git a/src/core/index/IntBlockPool.cpp b/src/core/index/IntBlockPool.cpp index 45c76fed..c43e17d3 100644 --- a/src/core/index/IntBlockPool.cpp +++ b/src/core/index/IntBlockPool.cpp @@ -10,7 +10,7 @@ namespace Lucene { - IntBlockPool::IntBlockPool(DocumentsWriterPtr docWriter, bool trackAllocations) + IntBlockPool::IntBlockPool(const DocumentsWriterPtr& docWriter, bool trackAllocations) { this->buffers = Collection::newInstance(10); this->bufferUpto = -1; diff --git a/src/core/index/InvertedDocConsumer.cpp b/src/core/index/InvertedDocConsumer.cpp index 6e140359..9ab0b33d 100644 --- a/src/core/index/InvertedDocConsumer.cpp +++ b/src/core/index/InvertedDocConsumer.cpp @@ -13,7 +13,7 @@ namespace Lucene { } - void InvertedDocConsumer::setFieldInfos(FieldInfosPtr fieldInfos) + void InvertedDocConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) { this->fieldInfos = fieldInfos; } diff --git a/src/core/index/LogByteSizeMergePolicy.cpp b/src/core/index/LogByteSizeMergePolicy.cpp index 8836e375..75aa4e47 100644 --- a/src/core/index/LogByteSizeMergePolicy.cpp +++ b/src/core/index/LogByteSizeMergePolicy.cpp @@ -16,7 +16,7 @@ namespace Lucene /// Default maximum segment size. A segment of this size or larger will never be merged. const double LogByteSizeMergePolicy::DEFAULT_MAX_MERGE_MB = DBL_MAX; - LogByteSizeMergePolicy::LogByteSizeMergePolicy(IndexWriterPtr writer) : LogMergePolicy(writer) + LogByteSizeMergePolicy::LogByteSizeMergePolicy(const IndexWriterPtr& writer) : LogMergePolicy(writer) { minMergeSize = (int64_t)(DEFAULT_MIN_MERGE_MB * 1024 * 1024); maxMergeSize = DEFAULT_MAX_MERGE_MB == DBL_MAX ? std::numeric_limits::max() : (int64_t)(DEFAULT_MAX_MERGE_MB * 1024 * 1024); @@ -26,7 +26,7 @@ namespace Lucene { } - int64_t LogByteSizeMergePolicy::size(SegmentInfoPtr info) + int64_t LogByteSizeMergePolicy::size(const SegmentInfoPtr& info) { return sizeBytes(info); } diff --git a/src/core/index/LogDocMergePolicy.cpp b/src/core/index/LogDocMergePolicy.cpp index 5fe6a0d5..375d789f 100644 --- a/src/core/index/LogDocMergePolicy.cpp +++ b/src/core/index/LogDocMergePolicy.cpp @@ -12,7 +12,7 @@ namespace Lucene /// Default minimum segment size. @see setMinMergeDocs const int32_t LogDocMergePolicy::DEFAULT_MIN_MERGE_DOCS = 1000; - LogDocMergePolicy::LogDocMergePolicy(IndexWriterPtr writer) : LogMergePolicy(writer) + LogDocMergePolicy::LogDocMergePolicy(const IndexWriterPtr& writer) : LogMergePolicy(writer) { minMergeSize = DEFAULT_MIN_MERGE_DOCS; @@ -24,7 +24,7 @@ namespace Lucene { } - int64_t LogDocMergePolicy::size(SegmentInfoPtr info) + int64_t LogDocMergePolicy::size(const SegmentInfoPtr& info) { return sizeDocs(info); } diff --git a/src/core/index/LogMergePolicy.cpp b/src/core/index/LogMergePolicy.cpp index 510efd25..7e14782a 100644 --- a/src/core/index/LogMergePolicy.cpp +++ b/src/core/index/LogMergePolicy.cpp @@ -25,7 +25,7 @@ namespace Lucene /// Default noCFSRatio. If a merge's size is >= 10% of the index, then we disable compound file for it. const double LogMergePolicy::DEFAULT_NO_CFS_RATIO = 0.1; - LogMergePolicy::LogMergePolicy(IndexWriterPtr writer) : MergePolicy(writer) + LogMergePolicy::LogMergePolicy(const IndexWriterPtr& writer) : MergePolicy(writer) { mergeFactor = DEFAULT_MERGE_FACTOR; noCFSRatio = DEFAULT_NO_CFS_RATIO; @@ -86,12 +86,12 @@ namespace Lucene _useCompoundFile = useCompoundFile; } - bool LogMergePolicy::useCompoundFile(SegmentInfosPtr segments, SegmentInfoPtr newSegment) + bool LogMergePolicy::useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment) { return _useCompoundFile; } - bool LogMergePolicy::useCompoundDocStore(SegmentInfosPtr segments) + bool LogMergePolicy::useCompoundDocStore(const SegmentInfosPtr& segments) { return _useCompoundDocStore; } @@ -120,7 +120,7 @@ namespace Lucene { } - int64_t LogMergePolicy::sizeDocs(SegmentInfoPtr info) + int64_t LogMergePolicy::sizeDocs(const SegmentInfoPtr& info) { if (calibrateSizeByDeletes) { @@ -131,7 +131,7 @@ namespace Lucene return info->docCount; } - int64_t LogMergePolicy::sizeBytes(SegmentInfoPtr info) + int64_t LogMergePolicy::sizeBytes(const SegmentInfoPtr& info) { int64_t byteSize = info->sizeInBytes(); if (calibrateSizeByDeletes) @@ -144,7 +144,7 @@ namespace Lucene return byteSize; } - bool LogMergePolicy::isOptimized(SegmentInfosPtr infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize) + bool LogMergePolicy::isOptimized(const SegmentInfosPtr& infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize) { int32_t numSegments = infos->size(); int32_t numToOptimize = 0; @@ -161,14 +161,14 @@ namespace Lucene return (numToOptimize <= maxNumSegments && (numToOptimize != 1 || isOptimized(optimizeInfo))); } - bool LogMergePolicy::isOptimized(SegmentInfoPtr info) + bool LogMergePolicy::isOptimized(const SegmentInfoPtr& info) { IndexWriterPtr writer(_writer); bool hasDeletions = (writer->numDeletedDocs(info) > 0); return (!hasDeletions && !info->hasSeparateNorms() && info->dir == writer->getDirectory() && (info->getUseCompoundFile() == _useCompoundFile || noCFSRatio < 1.0)); } - MergeSpecificationPtr LogMergePolicy::findMergesForOptimize(SegmentInfosPtr segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) + MergeSpecificationPtr LogMergePolicy::findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) { MergeSpecificationPtr spec; @@ -247,7 +247,7 @@ namespace Lucene return spec; } - MergeSpecificationPtr LogMergePolicy::findMergesToExpungeDeletes(SegmentInfosPtr segmentInfos) + MergeSpecificationPtr LogMergePolicy::findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos) { int32_t numSegments = segmentInfos->size(); @@ -291,7 +291,7 @@ namespace Lucene return spec; } - MergeSpecificationPtr LogMergePolicy::findMerges(SegmentInfosPtr segmentInfos) + MergeSpecificationPtr LogMergePolicy::findMerges(const SegmentInfosPtr& segmentInfos) { int32_t numSegments = segmentInfos->size(); message(L"findMerges: " + StringUtils::toString(numSegments) + L" segments"); @@ -383,7 +383,7 @@ namespace Lucene return spec; } - OneMergePtr LogMergePolicy::makeOneMerge(SegmentInfosPtr infos, SegmentInfosPtr infosToMerge) + OneMergePtr LogMergePolicy::makeOneMerge(const SegmentInfosPtr& infos, const SegmentInfosPtr& infosToMerge) { bool doCFS; if (!_useCompoundFile) diff --git a/src/core/index/MergeDocIDRemapper.cpp b/src/core/index/MergeDocIDRemapper.cpp index cfaf5ba7..7f197f56 100644 --- a/src/core/index/MergeDocIDRemapper.cpp +++ b/src/core/index/MergeDocIDRemapper.cpp @@ -12,7 +12,7 @@ namespace Lucene { - MergeDocIDRemapper::MergeDocIDRemapper(SegmentInfosPtr infos, Collection< Collection > docMaps, Collection delCounts, OneMergePtr merge, int32_t mergedDocCount) + MergeDocIDRemapper::MergeDocIDRemapper(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount) { this->docMaps = docMaps; SegmentInfoPtr firstSegment(merge->segments->info(0)); diff --git a/src/core/index/MergePolicy.cpp b/src/core/index/MergePolicy.cpp index 30f6af48..6d807041 100644 --- a/src/core/index/MergePolicy.cpp +++ b/src/core/index/MergePolicy.cpp @@ -12,7 +12,7 @@ namespace Lucene { - MergePolicy::MergePolicy(IndexWriterPtr writer) + MergePolicy::MergePolicy(const IndexWriterPtr& writer) { this->_writer = writer; } @@ -21,7 +21,7 @@ namespace Lucene { } - OneMerge::OneMerge(SegmentInfosPtr segments, bool useCompoundFile) + OneMerge::OneMerge(const SegmentInfosPtr& segments, bool useCompoundFile) { mergeDocStores = false; optimize = false; @@ -65,14 +65,14 @@ namespace Lucene return aborted; } - void OneMerge::checkAborted(DirectoryPtr dir) + void OneMerge::checkAborted(const DirectoryPtr& dir) { SyncLock syncLock(this); if (aborted) boost::throw_exception(MergeAbortedException(L"merge is aborted: " + segString(dir))); } - String OneMerge::segString(DirectoryPtr dir) + String OneMerge::segString(const DirectoryPtr& dir) { StringStream buffer; int32_t numSegments = segments->size(); @@ -100,12 +100,12 @@ namespace Lucene { } - void MergeSpecification::add(OneMergePtr merge) + void MergeSpecification::add(const OneMergePtr& merge) { merges.add(merge); } - String MergeSpecification::segString(DirectoryPtr dir) + String MergeSpecification::segString(const DirectoryPtr& dir) { String seg(L"MergeSpec:\n"); int32_t i = 1; diff --git a/src/core/index/MultiLevelSkipListReader.cpp b/src/core/index/MultiLevelSkipListReader.cpp index c579be88..89869f4d 100644 --- a/src/core/index/MultiLevelSkipListReader.cpp +++ b/src/core/index/MultiLevelSkipListReader.cpp @@ -11,7 +11,7 @@ namespace Lucene { - MultiLevelSkipListReader::MultiLevelSkipListReader(IndexInputPtr skipStream, int32_t maxSkipLevels, int32_t skipInterval) + MultiLevelSkipListReader::MultiLevelSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval) { this->numberOfLevelsToBuffer = 1; this->numberOfSkipLevels = 0; @@ -190,7 +190,7 @@ namespace Lucene lastChildPointer = childPointer[level]; } - SkipBuffer::SkipBuffer(IndexInputPtr input, int32_t length) + SkipBuffer::SkipBuffer(const IndexInputPtr& input, int32_t length) { pos = 0; data = ByteArray::newInstance(length); diff --git a/src/core/index/MultiLevelSkipListWriter.cpp b/src/core/index/MultiLevelSkipListWriter.cpp index 76518d67..63dc5839 100644 --- a/src/core/index/MultiLevelSkipListWriter.cpp +++ b/src/core/index/MultiLevelSkipListWriter.cpp @@ -71,7 +71,7 @@ namespace Lucene } } - int64_t MultiLevelSkipListWriter::writeSkip(IndexOutputPtr output) + int64_t MultiLevelSkipListWriter::writeSkip(const IndexOutputPtr& output) { int64_t skipPointer = output->getFilePointer(); if (!skipBuffer || skipBuffer.empty()) diff --git a/src/core/index/MultiReader.cpp b/src/core/index/MultiReader.cpp index 6055ea66..55860cc4 100644 --- a/src/core/index/MultiReader.cpp +++ b/src/core/index/MultiReader.cpp @@ -51,7 +51,7 @@ namespace Lucene return doReopen(false); } - LuceneObjectPtr MultiReader::clone(LuceneObjectPtr other) + LuceneObjectPtr MultiReader::clone(const LuceneObjectPtr& other) { SyncLock syncLock(this); try @@ -146,14 +146,14 @@ namespace Lucene return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); } - void MultiReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) + void MultiReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); } - void MultiReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) + void MultiReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { ensureOpen(); int32_t i = readerIndex(docNumber); // find segment num @@ -187,7 +187,7 @@ namespace Lucene return _maxDoc; } - DocumentPtr MultiReader::document(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr MultiReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { ensureOpen(); int32_t i = readerIndex(n); // find segment num @@ -291,13 +291,13 @@ namespace Lucene return newLucene(shared_from_this(), subReaders, starts, TermPtr()); } - TermEnumPtr MultiReader::terms(TermPtr t) + TermEnumPtr MultiReader::terms(const TermPtr& t) { ensureOpen(); return newLucene(shared_from_this(), subReaders, starts, t); } - int32_t MultiReader::docFreq(TermPtr t) + int32_t MultiReader::docFreq(const TermPtr& t) { ensureOpen(); int32_t total = 0; // sum freqs in segments diff --git a/src/core/index/MultipleTermPositions.cpp b/src/core/index/MultipleTermPositions.cpp index aceefa80..e89d9157 100644 --- a/src/core/index/MultipleTermPositions.cpp +++ b/src/core/index/MultipleTermPositions.cpp @@ -12,7 +12,7 @@ namespace Lucene { - MultipleTermPositions::MultipleTermPositions(IndexReaderPtr indexReader, Collection terms) + MultipleTermPositions::MultipleTermPositions(const IndexReaderPtr& indexReader, Collection terms) { Collection termPositions(Collection::newInstance()); @@ -97,12 +97,12 @@ namespace Lucene termPositionsQueue->pop()->close(); } - void MultipleTermPositions::seek(TermPtr term) + void MultipleTermPositions::seek(const TermPtr& term) { boost::throw_exception(UnsupportedOperationException()); } - void MultipleTermPositions::seek(TermEnumPtr termEnum) + void MultipleTermPositions::seek(const TermEnumPtr& termEnum) { boost::throw_exception(UnsupportedOperationException()); } diff --git a/src/core/index/NormsWriter.cpp b/src/core/index/NormsWriter.cpp index 83fb37fc..c7ef422a 100644 --- a/src/core/index/NormsWriter.cpp +++ b/src/core/index/NormsWriter.cpp @@ -36,7 +36,7 @@ namespace Lucene return defaultNorm; } - InvertedDocEndConsumerPerThreadPtr NormsWriter::addThread(DocInverterPerThreadPtr docInverterPerThread) + InvertedDocEndConsumerPerThreadPtr NormsWriter::addThread(const DocInverterPerThreadPtr& docInverterPerThread) { return newLucene(docInverterPerThread, shared_from_this()); } @@ -49,12 +49,12 @@ namespace Lucene { } - void NormsWriter::setFieldInfos(FieldInfosPtr fieldInfos) + void NormsWriter::setFieldInfos(const FieldInfosPtr& fieldInfos) { this->fieldInfos = fieldInfos; } - void NormsWriter::flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, SegmentWriteStatePtr state) + void NormsWriter::flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { MapFieldInfoCollectionNormsWriterPerField byField(MapFieldInfoCollectionNormsWriterPerField::newInstance()); @@ -183,7 +183,7 @@ namespace Lucene finally.throwException(); } - void NormsWriter::closeDocStore(SegmentWriteStatePtr state) + void NormsWriter::closeDocStore(const SegmentWriteStatePtr& state) { } } diff --git a/src/core/index/NormsWriterPerField.cpp b/src/core/index/NormsWriterPerField.cpp index 39b7f9bf..488ae856 100644 --- a/src/core/index/NormsWriterPerField.cpp +++ b/src/core/index/NormsWriterPerField.cpp @@ -15,7 +15,7 @@ namespace Lucene { - NormsWriterPerField::NormsWriterPerField(DocInverterPerFieldPtr docInverterPerField, NormsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo) + NormsWriterPerField::NormsWriterPerField(const DocInverterPerFieldPtr& docInverterPerField, const NormsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { docIDs = Collection::newInstance(1); norms = ByteArray::newInstance(1); @@ -44,7 +44,7 @@ namespace Lucene upto = 0; } - int32_t NormsWriterPerField::compareTo(LuceneObjectPtr other) + int32_t NormsWriterPerField::compareTo(const LuceneObjectPtr& other) { return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); } diff --git a/src/core/index/NormsWriterPerThread.cpp b/src/core/index/NormsWriterPerThread.cpp index ff2a2d1b..0dcdb03c 100644 --- a/src/core/index/NormsWriterPerThread.cpp +++ b/src/core/index/NormsWriterPerThread.cpp @@ -11,7 +11,7 @@ namespace Lucene { - NormsWriterPerThread::NormsWriterPerThread(DocInverterPerThreadPtr docInverterPerThread, NormsWriterPtr normsWriter) + NormsWriterPerThread::NormsWriterPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const NormsWriterPtr& normsWriter) { this->_normsWriter = normsWriter; docState = docInverterPerThread->docState; @@ -21,7 +21,7 @@ namespace Lucene { } - InvertedDocEndConsumerPerFieldPtr NormsWriterPerThread::addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) + InvertedDocEndConsumerPerFieldPtr NormsWriterPerThread::addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) { return newLucene(docInverterPerField, shared_from_this(), fieldInfo); } diff --git a/src/core/index/ParallelReader.cpp b/src/core/index/ParallelReader.cpp index 4509b1dc..eabca996 100644 --- a/src/core/index/ParallelReader.cpp +++ b/src/core/index/ParallelReader.cpp @@ -33,13 +33,13 @@ namespace Lucene { } - void ParallelReader::add(IndexReaderPtr reader) + void ParallelReader::add(const IndexReaderPtr& reader) { ensureOpen(); add(reader, false); } - void ParallelReader::add(IndexReaderPtr reader, bool ignoreStoredFields) + void ParallelReader::add(const IndexReaderPtr& reader, bool ignoreStoredFields) { ensureOpen(); if (readers.empty()) @@ -78,7 +78,7 @@ namespace Lucene decrefOnClose.add(incRefReaders); } - LuceneObjectPtr ParallelReader::clone(LuceneObjectPtr other) + LuceneObjectPtr ParallelReader::clone(const LuceneObjectPtr& other) { SyncLock syncLock(this); try @@ -218,7 +218,7 @@ namespace Lucene _hasDeletions = false; } - DocumentPtr ParallelReader::document(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr ParallelReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { ensureOpen(); DocumentPtr result(newLucene()); @@ -273,7 +273,7 @@ namespace Lucene return reader == fieldToReader.end() ? TermFreqVectorPtr() : reader->second->getTermFreqVector(docNumber, field); } - void ParallelReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) + void ParallelReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { ensureOpen(); MapStringIndexReader::iterator reader = fieldToReader.find(field); @@ -281,7 +281,7 @@ namespace Lucene reader->second->getTermFreqVector(docNumber, field, mapper); } - void ParallelReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) + void ParallelReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { ensureOpen(); for (MapStringIndexReader::iterator entry = fieldToReader.begin(); entry != fieldToReader.end(); ++entry) @@ -324,20 +324,20 @@ namespace Lucene return newLucene(shared_from_this()); } - TermEnumPtr ParallelReader::terms(TermPtr t) + TermEnumPtr ParallelReader::terms(const TermPtr& t) { ensureOpen(); return newLucene(shared_from_this(), t); } - int32_t ParallelReader::docFreq(TermPtr t) + int32_t ParallelReader::docFreq(const TermPtr& t) { ensureOpen(); MapStringIndexReader::iterator reader = fieldToReader.find(t->field()); return reader == fieldToReader.end() ? 0 : reader->second->docFreq(t); } - TermDocsPtr ParallelReader::termDocs(TermPtr term) + TermDocsPtr ParallelReader::termDocs(const TermPtr& term) { ensureOpen(); return newLucene(shared_from_this(), term); @@ -349,7 +349,7 @@ namespace Lucene return newLucene(shared_from_this()); } - TermPositionsPtr ParallelReader::termPositions(TermPtr term) + TermPositionsPtr ParallelReader::termPositions(const TermPtr& term) { ensureOpen(); return newLucene(shared_from_this(), term); @@ -428,7 +428,7 @@ namespace Lucene return fieldSet; } - ParallelTermEnum::ParallelTermEnum(ParallelReaderPtr reader) + ParallelTermEnum::ParallelTermEnum(const ParallelReaderPtr& reader) { this->setIterator = false; this->_reader = reader; @@ -439,7 +439,7 @@ namespace Lucene this->termEnum = reader->fieldToReader[field]->terms(); } - ParallelTermEnum::ParallelTermEnum(ParallelReaderPtr reader, TermPtr term) + ParallelTermEnum::ParallelTermEnum(const ParallelReaderPtr& reader, const TermPtr& term) { this->setIterator = false; this->_reader = reader; @@ -504,12 +504,12 @@ namespace Lucene termEnum->close(); } - ParallelTermDocs::ParallelTermDocs(ParallelReaderPtr reader) + ParallelTermDocs::ParallelTermDocs(const ParallelReaderPtr& reader) { this->_reader = reader; } - ParallelTermDocs::ParallelTermDocs(ParallelReaderPtr reader, TermPtr term) + ParallelTermDocs::ParallelTermDocs(const ParallelReaderPtr& reader, const TermPtr& term) { this->_reader = reader; if (!term) @@ -532,14 +532,14 @@ namespace Lucene return termDocs->freq(); } - void ParallelTermDocs::seek(TermPtr term) + void ParallelTermDocs::seek(const TermPtr& term) { ParallelReaderPtr reader(_reader); MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); termDocs = indexReader != reader->fieldToReader.end() ? indexReader->second->termDocs(term) : TermDocsPtr(); } - void ParallelTermDocs::seek(TermEnumPtr termEnum) + void ParallelTermDocs::seek(const TermEnumPtr& termEnum) { seek(termEnum->term()); } @@ -565,11 +565,11 @@ namespace Lucene termDocs->close(); } - ParallelTermPositions::ParallelTermPositions(ParallelReaderPtr reader) : ParallelTermDocs(reader) + ParallelTermPositions::ParallelTermPositions(const ParallelReaderPtr& reader) : ParallelTermDocs(reader) { } - ParallelTermPositions::ParallelTermPositions(ParallelReaderPtr reader, TermPtr term) : ParallelTermDocs(reader) + ParallelTermPositions::ParallelTermPositions(const ParallelReaderPtr& reader, const TermPtr& term) : ParallelTermDocs(reader) { seek(term); } @@ -578,7 +578,7 @@ namespace Lucene { } - void ParallelTermPositions::seek(TermPtr term) + void ParallelTermPositions::seek(const TermPtr& term) { ParallelReaderPtr reader(_reader); MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); diff --git a/src/core/index/Payload.cpp b/src/core/index/Payload.cpp index 628993d6..379bc663 100644 --- a/src/core/index/Payload.cpp +++ b/src/core/index/Payload.cpp @@ -85,7 +85,7 @@ namespace Lucene MiscUtils::arrayCopy(this->data.get(), this->offset, target.get(), targetOffset, this->_length); } - LuceneObjectPtr Payload::clone(LuceneObjectPtr other) + LuceneObjectPtr Payload::clone(const LuceneObjectPtr& other) { // Start with a shallow copy of data LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); @@ -109,7 +109,7 @@ namespace Lucene return clonePayload; } - bool Payload::equals(LuceneObjectPtr other) + bool Payload::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/index/PositionBasedTermVectorMapper.cpp b/src/core/index/PositionBasedTermVectorMapper.cpp index d2c4795d..cff9665a 100644 --- a/src/core/index/PositionBasedTermVectorMapper.cpp +++ b/src/core/index/PositionBasedTermVectorMapper.cpp @@ -69,7 +69,7 @@ namespace Lucene { } - void TermVectorsPositionInfo::addTerm(const String& term, TermVectorOffsetInfoPtr info) + void TermVectorsPositionInfo::addTerm(const String& term, const TermVectorOffsetInfoPtr& info) { terms.add(term); if (offsets) diff --git a/src/core/index/ReadOnlyDirectoryReader.cpp b/src/core/index/ReadOnlyDirectoryReader.cpp index f160bea6..2fd2d2c0 100644 --- a/src/core/index/ReadOnlyDirectoryReader.cpp +++ b/src/core/index/ReadOnlyDirectoryReader.cpp @@ -10,13 +10,13 @@ namespace Lucene { - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr sis, - IndexDeletionPolicyPtr deletionPolicy, int32_t termInfosIndexDivisor) : + ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, + const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor) : DirectoryReader(directory, sis, deletionPolicy, true, termInfosIndexDivisor) { } - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(DirectoryPtr directory, SegmentInfosPtr infos, + ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, Collection oldStarts, MapStringByteArray oldNormsCache, bool doClone, int32_t termInfosIndexDivisor) : @@ -24,7 +24,7 @@ namespace Lucene { } - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(IndexWriterPtr writer, SegmentInfosPtr infos, int32_t termInfosIndexDivisor) : + ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor) : DirectoryReader(writer, infos, termInfosIndexDivisor) { } diff --git a/src/core/index/SegmentInfo.cpp b/src/core/index/SegmentInfo.cpp index 4e399d3c..038b7d22 100644 --- a/src/core/index/SegmentInfo.cpp +++ b/src/core/index/SegmentInfo.cpp @@ -25,7 +25,7 @@ namespace Lucene const int32_t SegmentInfo::CHECK_DIR = 0; // must check dir to see if there are norms/deletions const int32_t SegmentInfo::WITHOUT_GEN = 0; // a file name that has no GEN in it. - SegmentInfo::SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir) + SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir) { _sizeInBytes = -1; this->name = name; @@ -42,7 +42,7 @@ namespace Lucene hasProx = true; } - SegmentInfo::SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, bool hasSingleNormFile) + SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile) { _sizeInBytes = -1; this->name = name; @@ -58,7 +58,7 @@ namespace Lucene hasProx = true; } - SegmentInfo::SegmentInfo(const String& name, int32_t docCount, DirectoryPtr dir, bool isCompoundFile, bool hasSingleNormFile, + SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile, int32_t docStoreOffset, const String& docStoreSegment, bool docStoreIsCompoundFile, bool hasProx) { _sizeInBytes = -1; @@ -76,7 +76,7 @@ namespace Lucene this->hasProx = hasProx; } - SegmentInfo::SegmentInfo(DirectoryPtr dir, int32_t format, IndexInputPtr input) + SegmentInfo::SegmentInfo(const DirectoryPtr& dir, int32_t format, const IndexInputPtr& input) { _sizeInBytes = -1; this->dir = dir; @@ -153,7 +153,7 @@ namespace Lucene { } - void SegmentInfo::reset(SegmentInfoPtr src) + void SegmentInfo::reset(const SegmentInfoPtr& src) { clearFiles(); name = src->name; @@ -244,7 +244,7 @@ namespace Lucene clearFiles(); } - LuceneObjectPtr SegmentInfo::clone(LuceneObjectPtr other) + LuceneObjectPtr SegmentInfo::clone(const LuceneObjectPtr& other) { SegmentInfoPtr si(newLucene(name, docCount, dir)); si->isCompoundFile = isCompoundFile; @@ -431,7 +431,7 @@ namespace Lucene docStoreIsCompoundFile = isCompoundFile; } - void SegmentInfo::write(IndexOutputPtr output) + void SegmentInfo::write(const IndexOutputPtr& output) { output->writeString(name); output->writeInt(docCount); @@ -576,7 +576,7 @@ namespace Lucene _sizeInBytes = -1; } - String SegmentInfo::segString(DirectoryPtr dir) + String SegmentInfo::segString(const DirectoryPtr& dir) { String cfs; try @@ -595,7 +595,7 @@ namespace Lucene return name + L":" + cfs + (this->dir == dir ? L"" : L"x") + StringUtils::toString(docCount) + docStore; } - bool SegmentInfo::equals(LuceneObjectPtr other) + bool SegmentInfo::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/index/SegmentInfoCollection.cpp b/src/core/index/SegmentInfoCollection.cpp index 008e3f96..98298f81 100644 --- a/src/core/index/SegmentInfoCollection.cpp +++ b/src/core/index/SegmentInfoCollection.cpp @@ -34,35 +34,35 @@ namespace Lucene segmentInfos.clear(); } - void SegmentInfoCollection::add(SegmentInfoPtr info) + void SegmentInfoCollection::add(const SegmentInfoPtr& info) { segmentInfos.add(info); } - void SegmentInfoCollection::add(int32_t pos, SegmentInfoPtr info) + void SegmentInfoCollection::add(int32_t pos, const SegmentInfoPtr& info) { segmentInfos.add(pos, info); } - void SegmentInfoCollection::addAll(SegmentInfoCollectionPtr segmentInfos) + void SegmentInfoCollection::addAll(const SegmentInfoCollectionPtr& segmentInfos) { this->segmentInfos.addAll(segmentInfos->segmentInfos.begin(), segmentInfos->segmentInfos.end()); } - bool SegmentInfoCollection::equals(SegmentInfoCollectionPtr other) + bool SegmentInfoCollection::equals(const SegmentInfoCollectionPtr& other) { if (LuceneObject::equals(other)) return true; return segmentInfos.equals(other->segmentInfos, luceneEquals()); } - int32_t SegmentInfoCollection::find(SegmentInfoPtr info) + int32_t SegmentInfoCollection::find(const SegmentInfoPtr& info) { Collection::iterator idx = segmentInfos.find_if(luceneEqualTo(info)); return idx == segmentInfos.end() ? -1 : std::distance(segmentInfos.begin(), idx); } - bool SegmentInfoCollection::contains(SegmentInfoPtr info) + bool SegmentInfoCollection::contains(const SegmentInfoPtr& info) { return segmentInfos.contains_if(luceneEqualTo(info)); } @@ -77,7 +77,7 @@ namespace Lucene segmentInfos.remove(segmentInfos.begin() + start, segmentInfos.begin() + end); } - LuceneObjectPtr SegmentInfoCollection::clone(LuceneObjectPtr other) + LuceneObjectPtr SegmentInfoCollection::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); SegmentInfoCollectionPtr cloneInfos(boost::dynamic_pointer_cast(clone)); diff --git a/src/core/index/SegmentInfos.cpp b/src/core/index/SegmentInfos.cpp index ae34643d..48ce4564 100644 --- a/src/core/index/SegmentInfos.cpp +++ b/src/core/index/SegmentInfos.cpp @@ -94,7 +94,7 @@ namespace Lucene return max; } - int64_t SegmentInfos::getCurrentSegmentGeneration(DirectoryPtr directory) + int64_t SegmentInfos::getCurrentSegmentGeneration(const DirectoryPtr& directory) { try { @@ -111,7 +111,7 @@ namespace Lucene return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(files)); } - String SegmentInfos::getCurrentSegmentFileName(DirectoryPtr directory) + String SegmentInfos::getCurrentSegmentFileName(const DirectoryPtr& directory) { return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(directory)); } @@ -137,7 +137,7 @@ namespace Lucene return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation == -1 ? 1 : generation + 1); } - void SegmentInfos::read(DirectoryPtr directory, const String& segmentFileName) + void SegmentInfos::read(const DirectoryPtr& directory, const String& segmentFileName) { bool success = false; @@ -216,14 +216,14 @@ namespace Lucene finally.throwException(); } - void SegmentInfos::read(DirectoryPtr directory) + void SegmentInfos::read(const DirectoryPtr& directory) { lastGeneration = -1; generation = lastGeneration; newLucene(shared_from_this(), directory)->run(); } - void SegmentInfos::write(DirectoryPtr directory) + void SegmentInfos::write(const DirectoryPtr& directory) { String segmentFileName(getNextSegmentFileName()); @@ -281,7 +281,7 @@ namespace Lucene finally.throwException(); } - LuceneObjectPtr SegmentInfos::clone(LuceneObjectPtr other) + LuceneObjectPtr SegmentInfos::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = SegmentInfoCollection::clone(other ? other : newLucene()); SegmentInfosPtr cloneInfos(boost::dynamic_pointer_cast(clone)); @@ -312,7 +312,7 @@ namespace Lucene return lastGeneration; } - int64_t SegmentInfos::readCurrentVersion(DirectoryPtr directory) + int64_t SegmentInfos::readCurrentVersion(const DirectoryPtr& directory) { // Fully read the segments file: this ensures that it's completely written so that if IndexWriter.prepareCommit has been called // (but not yet commit), then the reader will still see itself as current. @@ -321,14 +321,14 @@ namespace Lucene return sis->getVersion(); } - MapStringString SegmentInfos::readCurrentUserData(DirectoryPtr directory) + MapStringString SegmentInfos::readCurrentUserData(const DirectoryPtr& directory) { SegmentInfosPtr sis(newLucene()); sis->read(directory); return sis->getUserData(); } - void SegmentInfos::setInfoStream(InfoStreamPtr infoStream) + void SegmentInfos::setInfoStream(const InfoStreamPtr& infoStream) { SegmentInfos::infoStream = infoStream; } @@ -374,7 +374,7 @@ namespace Lucene *infoStream << L"SIS [" << message << L"]\n"; } - FindSegmentsFile::FindSegmentsFile(SegmentInfosPtr infos, DirectoryPtr directory) + FindSegmentsFile::FindSegmentsFile(const SegmentInfosPtr& infos, const DirectoryPtr& directory) { this->_segmentInfos = infos; this->directory = directory; @@ -384,7 +384,7 @@ namespace Lucene { } - void FindSegmentsFile::doRun(IndexCommitPtr commit) + void FindSegmentsFile::doRun(const IndexCommitPtr& commit) { if (commit) { @@ -569,7 +569,7 @@ namespace Lucene } } - FindSegmentsRead::FindSegmentsRead(SegmentInfosPtr infos, DirectoryPtr directory) : FindSegmentsFileT(infos, directory) + FindSegmentsRead::FindSegmentsRead(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { result = 0; } @@ -591,14 +591,14 @@ namespace Lucene return infos; } - void SegmentInfos::updateGeneration(SegmentInfosPtr other) + void SegmentInfos::updateGeneration(const SegmentInfosPtr& other) { lastGeneration = other->lastGeneration; generation = other->generation; version = other->version; } - void SegmentInfos::rollbackCommit(DirectoryPtr dir) + void SegmentInfos::rollbackCommit(const DirectoryPtr& dir) { if (pendingSegnOutput) { @@ -623,7 +623,7 @@ namespace Lucene } } - void SegmentInfos::prepareCommit(DirectoryPtr dir) + void SegmentInfos::prepareCommit(const DirectoryPtr& dir) { TestScope testScope(L"SegmentInfos", L"prepareCommit"); if (pendingSegnOutput) @@ -631,7 +631,7 @@ namespace Lucene write(dir); } - HashSet SegmentInfos::files(DirectoryPtr dir, bool includeSegmentsFile) + HashSet SegmentInfos::files(const DirectoryPtr& dir, bool includeSegmentsFile) { HashSet files(HashSet::newInstance()); if (includeSegmentsFile) @@ -647,7 +647,7 @@ namespace Lucene return files; } - void SegmentInfos::finishCommit(DirectoryPtr dir) + void SegmentInfos::finishCommit(const DirectoryPtr& dir) { if (!pendingSegnOutput) boost::throw_exception(IllegalStateException(L"prepareCommit was not called")); @@ -716,13 +716,13 @@ namespace Lucene } } - void SegmentInfos::commit(DirectoryPtr dir) + void SegmentInfos::commit(const DirectoryPtr& dir) { prepareCommit(dir); finishCommit(dir); } - String SegmentInfos::segString(DirectoryPtr directory) + String SegmentInfos::segString(const DirectoryPtr& directory) { SyncLock syncLock(this); String buffer; @@ -750,14 +750,14 @@ namespace Lucene userData = data; } - void SegmentInfos::replace(SegmentInfosPtr other) + void SegmentInfos::replace(const SegmentInfosPtr& other) { segmentInfos.clear(); segmentInfos.addAll(other->segmentInfos.begin(), other->segmentInfos.end()); lastGeneration = other->lastGeneration; } - bool SegmentInfos::hasExternalSegments(DirectoryPtr dir) + bool SegmentInfos::hasExternalSegments(const DirectoryPtr& dir) { for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) { diff --git a/src/core/index/SegmentMergeInfo.cpp b/src/core/index/SegmentMergeInfo.cpp index 9beb4212..aeafe13a 100644 --- a/src/core/index/SegmentMergeInfo.cpp +++ b/src/core/index/SegmentMergeInfo.cpp @@ -12,7 +12,7 @@ namespace Lucene { - SegmentMergeInfo::SegmentMergeInfo(int32_t b, TermEnumPtr te, IndexReaderPtr r) + SegmentMergeInfo::SegmentMergeInfo(int32_t b, const TermEnumPtr& te, const IndexReaderPtr& r) { base = b; _reader = r; diff --git a/src/core/index/SegmentMerger.cpp b/src/core/index/SegmentMerger.cpp index bdbdca02..d6984cd3 100644 --- a/src/core/index/SegmentMerger.cpp +++ b/src/core/index/SegmentMerger.cpp @@ -41,7 +41,7 @@ namespace Lucene const uint8_t SegmentMerger::NORMS_HEADER[] = {'N', 'R', 'M', static_cast(-1) }; const int32_t SegmentMerger::NORMS_HEADER_LENGTH = 4; - SegmentMerger::SegmentMerger(DirectoryPtr dir, const String& name) + SegmentMerger::SegmentMerger(const DirectoryPtr& dir, const String& name) { readers = Collection::newInstance(); termIndexInterval = IndexWriter::DEFAULT_TERM_INDEX_INTERVAL; @@ -54,7 +54,7 @@ namespace Lucene checkAbort = newLucene(); } - SegmentMerger::SegmentMerger(IndexWriterPtr writer, const String& name, OneMergePtr merge) + SegmentMerger::SegmentMerger(const IndexWriterPtr& writer, const String& name, const OneMergePtr& merge) { readers = Collection::newInstance(); mergedDocs = 0; @@ -80,7 +80,7 @@ namespace Lucene return fieldInfos->hasProx(); } - void SegmentMerger::add(IndexReaderPtr reader) + void SegmentMerger::add(const IndexReaderPtr& reader) { readers.add(reader); } @@ -168,7 +168,7 @@ namespace Lucene return files; } - void SegmentMerger::addIndexed(IndexReaderPtr reader, FieldInfosPtr fInfos, HashSet names, + void SegmentMerger::addIndexed(const IndexReaderPtr& reader, const FieldInfosPtr& fInfos, HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool storePayloads, bool omitTFAndPositions) { @@ -308,7 +308,7 @@ namespace Lucene return docCount; } - int32_t SegmentMerger::copyFieldsWithDeletions(FieldsWriterPtr fieldsWriter, IndexReaderPtr reader, FieldsReaderPtr matchingFieldsReader) + int32_t SegmentMerger::copyFieldsWithDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader) { int32_t docCount = 0; int32_t maxDoc = reader->maxDoc(); @@ -365,7 +365,7 @@ namespace Lucene return docCount; } - int32_t SegmentMerger::copyFieldsNoDeletions(FieldsWriterPtr fieldsWriter, IndexReaderPtr reader, FieldsReaderPtr matchingFieldsReader) + int32_t SegmentMerger::copyFieldsNoDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader) { int32_t docCount = 0; int32_t maxDoc = reader->maxDoc(); @@ -439,7 +439,7 @@ namespace Lucene } } - void SegmentMerger::copyVectorsWithDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader) + void SegmentMerger::copyVectorsWithDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader) { int32_t maxDoc = reader->maxDoc(); if (matchingVectorsReader) @@ -492,7 +492,7 @@ namespace Lucene } } - void SegmentMerger::copyVectorsNoDeletions(TermVectorsWriterPtr termVectorsWriter, TermVectorsReaderPtr matchingVectorsReader, IndexReaderPtr reader) + void SegmentMerger::copyVectorsNoDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader) { int32_t maxDoc = reader->maxDoc(); if (matchingVectorsReader) @@ -543,7 +543,7 @@ namespace Lucene finally.throwException(); } - void SegmentMerger::mergeTermInfos(FormatPostingsFieldsConsumerPtr consumer) + void SegmentMerger::mergeTermInfos(const FormatPostingsFieldsConsumerPtr& consumer) { int32_t base = 0; int32_t readerCount = readers.size(); @@ -628,7 +628,7 @@ namespace Lucene return delCounts; } - int32_t SegmentMerger::appendPostings(FormatPostingsTermsConsumerPtr termsConsumer, Collection smis, int32_t n) + int32_t SegmentMerger::appendPostings(const FormatPostingsTermsConsumerPtr& termsConsumer, Collection smis, int32_t n) { FormatPostingsDocsConsumerPtr docConsumer(termsConsumer->addTerm(smis[0]->term->_text)); int32_t df = 0; @@ -733,7 +733,7 @@ namespace Lucene finally.throwException(); } - CheckAbort::CheckAbort(OneMergePtr merge, DirectoryPtr dir) + CheckAbort::CheckAbort(const OneMergePtr& merge, const DirectoryPtr& dir) { workCount = 0; this->merge = merge; diff --git a/src/core/index/SegmentReader.cpp b/src/core/index/SegmentReader.cpp index 0e559357..ed080daf 100644 --- a/src/core/index/SegmentReader.cpp +++ b/src/core/index/SegmentReader.cpp @@ -56,12 +56,12 @@ namespace Lucene fieldsReaderLocal = newLucene(shared_from_this()); } - SegmentReaderPtr SegmentReader::get(bool readOnly, SegmentInfoPtr si, int32_t termInfosIndexDivisor) + SegmentReaderPtr SegmentReader::get(bool readOnly, const SegmentInfoPtr& si, int32_t termInfosIndexDivisor) { return get(readOnly, si->dir, si, BufferedIndexInput::BUFFER_SIZE, true, termInfosIndexDivisor); } - SegmentReaderPtr SegmentReader::get(bool readOnly, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor) + SegmentReaderPtr SegmentReader::get(bool readOnly, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor) { SegmentReaderPtr instance(readOnly ? newLucene() : newLucene()); instance->readOnly = readOnly; @@ -131,12 +131,12 @@ namespace Lucene return cloneBytes; } - BitVectorPtr SegmentReader::cloneDeletedDocs(BitVectorPtr bv) + BitVectorPtr SegmentReader::cloneDeletedDocs(const BitVectorPtr& bv) { return boost::dynamic_pointer_cast(bv->clone()); } - LuceneObjectPtr SegmentReader::clone(LuceneObjectPtr other) + LuceneObjectPtr SegmentReader::clone(const LuceneObjectPtr& other) { try { @@ -149,13 +149,13 @@ namespace Lucene return LuceneObjectPtr(); } - LuceneObjectPtr SegmentReader::clone(bool openReadOnly, LuceneObjectPtr other) + LuceneObjectPtr SegmentReader::clone(bool openReadOnly, const LuceneObjectPtr& other) { SyncLock syncLock(this); return reopenSegment(si, true, openReadOnly); } - SegmentReaderPtr SegmentReader::reopenSegment(SegmentInfoPtr si, bool doClone, bool openReadOnly) + SegmentReaderPtr SegmentReader::reopenSegment(const SegmentInfoPtr& si, bool doClone, bool openReadOnly) { SyncLock syncLock(this); @@ -367,7 +367,7 @@ namespace Lucene core->decRef(); } - bool SegmentReader::hasDeletions(SegmentInfoPtr si) + bool SegmentReader::hasDeletions(const SegmentInfoPtr& si) { // Don't call ensureOpen() here (it could affect performance) return si->hasDeletions(); @@ -379,12 +379,12 @@ namespace Lucene return deletedDocs.get() != NULL; } - bool SegmentReader::usesCompoundFile(SegmentInfoPtr si) + bool SegmentReader::usesCompoundFile(const SegmentInfoPtr& si) { return si->getUseCompoundFile(); } - bool SegmentReader::hasSeparateNorms(SegmentInfoPtr si) + bool SegmentReader::hasSeparateNorms(const SegmentInfoPtr& si) { return si->hasSeparateNorms(); } @@ -441,7 +441,7 @@ namespace Lucene return core->getTermsReader()->terms(); } - TermEnumPtr SegmentReader::terms(TermPtr t) + TermEnumPtr SegmentReader::terms(const TermPtr& t) { ensureOpen(); return core->getTermsReader()->terms(t); @@ -452,7 +452,7 @@ namespace Lucene return core->fieldInfos; } - DocumentPtr SegmentReader::document(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr SegmentReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { ensureOpen(); return getFieldsReader()->doc(n, fieldSelector); @@ -464,7 +464,7 @@ namespace Lucene return (deletedDocs && deletedDocs->get(n)); } - TermDocsPtr SegmentReader::termDocs(TermPtr term) + TermDocsPtr SegmentReader::termDocs(const TermPtr& term) { if (!term) return newLucene(shared_from_this()); @@ -484,7 +484,7 @@ namespace Lucene return newLucene(shared_from_this()); } - int32_t SegmentReader::docFreq(TermPtr t) + int32_t SegmentReader::docFreq(const TermPtr& t) { ensureOpen(); TermInfoPtr ti(core->getTermsReader()->get(t)); @@ -587,7 +587,7 @@ namespace Lucene norm->bytes(norms.get(), offset, maxDoc()); } - void SegmentReader::openNorms(DirectoryPtr cfsDir, int32_t readBufferSize) + void SegmentReader::openNorms(const DirectoryPtr& cfsDir, int32_t readBufferSize) { int64_t nextNormSeek = SegmentMerger::NORMS_HEADER_LENGTH; // skip header (header unused for now) int32_t _maxDoc = maxDoc(); @@ -710,7 +710,7 @@ namespace Lucene return termVectorsReader->get(docNumber, field); } - void SegmentReader::getTermFreqVector(int32_t docNumber, const String& field, TermVectorMapperPtr mapper) + void SegmentReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { ensureOpen(); FieldInfoPtr fi(core->fieldInfos->fieldInfo(field)); @@ -724,7 +724,7 @@ namespace Lucene termVectorsReader->get(docNumber, field, mapper); } - void SegmentReader::getTermFreqVector(int32_t docNumber, TermVectorMapperPtr mapper) + void SegmentReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { ensureOpen(); @@ -756,7 +756,7 @@ namespace Lucene return si; } - void SegmentReader::setSegmentInfo(SegmentInfoPtr info) + void SegmentReader::setSegmentInfo(const SegmentInfoPtr& info) { si = info; } @@ -805,12 +805,12 @@ namespace Lucene return core->getTermsReader()->size(); } - SegmentReaderPtr SegmentReader::getOnlySegmentReader(DirectoryPtr dir) + SegmentReaderPtr SegmentReader::getOnlySegmentReader(const DirectoryPtr& dir) { return getOnlySegmentReader(IndexReader::open(dir, false)); } - SegmentReaderPtr SegmentReader::getOnlySegmentReader(IndexReaderPtr reader) + SegmentReaderPtr SegmentReader::getOnlySegmentReader(const IndexReaderPtr& reader) { SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(reader)); if (segmentReader) @@ -835,7 +835,7 @@ namespace Lucene return core->termsIndexDivisor; } - CoreReaders::CoreReaders(SegmentReaderPtr origInstance, DirectoryPtr dir, SegmentInfoPtr si, int32_t readBufferSize, int32_t termsIndexDivisor) + CoreReaders::CoreReaders(const SegmentReaderPtr& origInstance, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, int32_t termsIndexDivisor) { ref = newLucene(); @@ -926,7 +926,7 @@ namespace Lucene return tis.get() != NULL; } - void CoreReaders::loadTermsIndex(SegmentInfoPtr si, int32_t termsIndexDivisor) + void CoreReaders::loadTermsIndex(const SegmentInfoPtr& si, int32_t termsIndexDivisor) { SyncLock syncLock(this); if (!tis) @@ -981,7 +981,7 @@ namespace Lucene } } - void CoreReaders::openDocStores(SegmentInfoPtr si) + void CoreReaders::openDocStores(const SegmentInfoPtr& si) { SyncLock syncLock(this); BOOST_ASSERT(si->name == segment); @@ -1036,7 +1036,7 @@ namespace Lucene } } - FieldsReaderLocal::FieldsReaderLocal(SegmentReaderPtr reader) + FieldsReaderLocal::FieldsReaderLocal(const SegmentReaderPtr& reader) { this->_reader = reader; } @@ -1091,7 +1091,7 @@ namespace Lucene this->number = 0; } - Norm::Norm(SegmentReaderPtr reader, IndexInputPtr in, int32_t number, int64_t normSeek) + Norm::Norm(const SegmentReaderPtr& reader, const IndexInputPtr& in, int32_t number, int64_t normSeek) { this->_reader = reader; this->refCount = 1; @@ -1266,7 +1266,7 @@ namespace Lucene return _bytes; } - LuceneObjectPtr Norm::clone(LuceneObjectPtr other) + LuceneObjectPtr Norm::clone(const LuceneObjectPtr& other) { SyncLock syncLock(this); @@ -1311,7 +1311,7 @@ namespace Lucene return cloneNorm; } - void Norm::reWrite(SegmentInfoPtr si) + void Norm::reWrite(const SegmentInfoPtr& si) { BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); diff --git a/src/core/index/SegmentTermDocs.cpp b/src/core/index/SegmentTermDocs.cpp index 897d8882..6e60c3f1 100644 --- a/src/core/index/SegmentTermDocs.cpp +++ b/src/core/index/SegmentTermDocs.cpp @@ -21,7 +21,7 @@ namespace Lucene { - SegmentTermDocs::SegmentTermDocs(SegmentReaderPtr parent) + SegmentTermDocs::SegmentTermDocs(const SegmentReaderPtr& parent) { this->_parent = parent; this->count = 0; @@ -48,13 +48,13 @@ namespace Lucene { } - void SegmentTermDocs::seek(TermPtr term) + void SegmentTermDocs::seek(const TermPtr& term) { TermInfoPtr ti(SegmentReaderPtr(_parent)->core->getTermsReader()->get(term)); seek(ti, term); } - void SegmentTermDocs::seek(TermEnumPtr termEnum) + void SegmentTermDocs::seek(const TermEnumPtr& termEnum) { TermInfoPtr ti; TermPtr term; @@ -77,7 +77,7 @@ namespace Lucene seek(ti, term); } - void SegmentTermDocs::seek(TermInfoPtr ti, TermPtr term) + void SegmentTermDocs::seek(const TermInfoPtr& ti, const TermPtr& term) { count = 0; FieldInfoPtr fi(SegmentReaderPtr(_parent)->core->fieldInfos->fieldInfo(term->_field)); @@ -243,7 +243,7 @@ namespace Lucene return _freqStream; } - void SegmentTermDocs::freqStream(IndexInputPtr freqStream) + void SegmentTermDocs::freqStream(const IndexInputPtr& freqStream) { _freqStream = freqStream; } diff --git a/src/core/index/SegmentTermEnum.cpp b/src/core/index/SegmentTermEnum.cpp index 6c1eafee..8adae7e7 100644 --- a/src/core/index/SegmentTermEnum.cpp +++ b/src/core/index/SegmentTermEnum.cpp @@ -33,7 +33,7 @@ namespace Lucene maxSkipLevels = 0; } - SegmentTermEnum::SegmentTermEnum(IndexInputPtr i, FieldInfosPtr fis, bool isi) + SegmentTermEnum::SegmentTermEnum(const IndexInputPtr& i, const FieldInfosPtr& fis, bool isi) { format = 0; termBuffer = newLucene(); @@ -111,7 +111,7 @@ namespace Lucene { } - LuceneObjectPtr SegmentTermEnum::clone(LuceneObjectPtr other) + LuceneObjectPtr SegmentTermEnum::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); SegmentTermEnumPtr cloneEnum(boost::dynamic_pointer_cast(TermEnum::clone(clone))); @@ -136,7 +136,7 @@ namespace Lucene return cloneEnum; } - void SegmentTermEnum::seek(int64_t pointer, int64_t p, TermPtr t, TermInfoPtr ti) + void SegmentTermEnum::seek(int64_t pointer, int64_t p, const TermPtr& t, const TermInfoPtr& ti) { input->seek(pointer); position = p; @@ -177,7 +177,7 @@ namespace Lucene return true; } - int32_t SegmentTermEnum::scanTo(TermPtr term) + int32_t SegmentTermEnum::scanTo(const TermPtr& term) { scanBuffer->set(term); int32_t count = 0; @@ -201,7 +201,7 @@ namespace Lucene return newLucene(_termInfo); } - void SegmentTermEnum::termInfo(TermInfoPtr ti) + void SegmentTermEnum::termInfo(const TermInfoPtr& ti) { ti->set(_termInfo); } diff --git a/src/core/index/SegmentTermPositions.cpp b/src/core/index/SegmentTermPositions.cpp index 6e8d21de..5f2f6e9b 100644 --- a/src/core/index/SegmentTermPositions.cpp +++ b/src/core/index/SegmentTermPositions.cpp @@ -14,7 +14,7 @@ namespace Lucene { - SegmentTermPositions::SegmentTermPositions(SegmentReaderPtr parent) : SegmentTermDocs(parent) + SegmentTermPositions::SegmentTermPositions(const SegmentReaderPtr& parent) : SegmentTermDocs(parent) { this->proxCount = 0; this->position = 0; @@ -28,7 +28,7 @@ namespace Lucene { } - void SegmentTermPositions::seek(TermInfoPtr ti, TermPtr term) + void SegmentTermPositions::seek(const TermInfoPtr& ti, const TermPtr& term) { SegmentTermDocs::seek(ti, term); if (ti) diff --git a/src/core/index/SegmentWriteState.cpp b/src/core/index/SegmentWriteState.cpp index 841d792d..4158e12c 100644 --- a/src/core/index/SegmentWriteState.cpp +++ b/src/core/index/SegmentWriteState.cpp @@ -9,7 +9,7 @@ namespace Lucene { - SegmentWriteState::SegmentWriteState(DocumentsWriterPtr docWriter, DirectoryPtr directory, const String& segmentName, + SegmentWriteState::SegmentWriteState(const DocumentsWriterPtr& docWriter, const DirectoryPtr& directory, const String& segmentName, const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, int32_t termIndexInterval) { diff --git a/src/core/index/SerialMergeScheduler.cpp b/src/core/index/SerialMergeScheduler.cpp index 63223de2..758b0c8b 100644 --- a/src/core/index/SerialMergeScheduler.cpp +++ b/src/core/index/SerialMergeScheduler.cpp @@ -14,7 +14,7 @@ namespace Lucene { } - void SerialMergeScheduler::merge(IndexWriterPtr writer) + void SerialMergeScheduler::merge(const IndexWriterPtr& writer) { SyncLock syncLock(this); while (true) diff --git a/src/core/index/SnapshotDeletionPolicy.cpp b/src/core/index/SnapshotDeletionPolicy.cpp index 6ee34c13..e1e8d5c2 100644 --- a/src/core/index/SnapshotDeletionPolicy.cpp +++ b/src/core/index/SnapshotDeletionPolicy.cpp @@ -10,7 +10,7 @@ namespace Lucene { - SnapshotDeletionPolicy::SnapshotDeletionPolicy(IndexDeletionPolicyPtr primary) + SnapshotDeletionPolicy::SnapshotDeletionPolicy(const IndexDeletionPolicyPtr& primary) { this->primary = primary; } @@ -62,7 +62,7 @@ namespace Lucene return myCommits; } - MyCommitPoint::MyCommitPoint(SnapshotDeletionPolicyPtr deletionPolicy, IndexCommitPtr cp) + MyCommitPoint::MyCommitPoint(const SnapshotDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& cp) { this->_deletionPolicy = deletionPolicy; this->cp = cp; diff --git a/src/core/index/StoredFieldsWriter.cpp b/src/core/index/StoredFieldsWriter.cpp index de57d0d1..b1e8eb9d 100644 --- a/src/core/index/StoredFieldsWriter.cpp +++ b/src/core/index/StoredFieldsWriter.cpp @@ -18,7 +18,7 @@ namespace Lucene { - StoredFieldsWriter::StoredFieldsWriter(DocumentsWriterPtr docWriter, FieldInfosPtr fieldInfos) + StoredFieldsWriter::StoredFieldsWriter(const DocumentsWriterPtr& docWriter, const FieldInfosPtr& fieldInfos) { lastDocID = 0; docFreeList = Collection::newInstance(1); @@ -33,12 +33,12 @@ namespace Lucene { } - StoredFieldsWriterPerThreadPtr StoredFieldsWriter::addThread(DocStatePtr docState) + StoredFieldsWriterPerThreadPtr StoredFieldsWriter::addThread(const DocStatePtr& docState) { return newLucene(docState, shared_from_this()); } - void StoredFieldsWriter::flush(SegmentWriteStatePtr state) + void StoredFieldsWriter::flush(const SegmentWriteStatePtr& state) { SyncLock syncLock(this); if (state->numDocsInStore > 0) @@ -72,7 +72,7 @@ namespace Lucene } } - void StoredFieldsWriter::closeDocStore(SegmentWriteStatePtr state) + void StoredFieldsWriter::closeDocStore(const SegmentWriteStatePtr& state) { SyncLock syncLock(this); int32_t inc = state->numDocsInStore - lastDocID; @@ -156,7 +156,7 @@ namespace Lucene } } - void StoredFieldsWriter::finishDocument(StoredFieldsWriterPerDocPtr perDoc) + void StoredFieldsWriter::finishDocument(const StoredFieldsWriterPerDocPtr& perDoc) { SyncLock syncLock(this); IndexWriterPtr writer(DocumentsWriterPtr(_docWriter)->_writer); @@ -178,7 +178,7 @@ namespace Lucene return false; } - void StoredFieldsWriter::free(StoredFieldsWriterPerDocPtr perDoc) + void StoredFieldsWriter::free(const StoredFieldsWriterPerDocPtr& perDoc) { SyncLock syncLock(this); BOOST_ASSERT(freeCount < docFreeList.size()); @@ -188,7 +188,7 @@ namespace Lucene docFreeList[freeCount++] = perDoc; } - StoredFieldsWriterPerDoc::StoredFieldsWriterPerDoc(StoredFieldsWriterPtr fieldsWriter) + StoredFieldsWriterPerDoc::StoredFieldsWriterPerDoc(const StoredFieldsWriterPtr& fieldsWriter) { this->_fieldsWriter = fieldsWriter; buffer = DocumentsWriterPtr(fieldsWriter->_docWriter)->newPerDocBuffer(); diff --git a/src/core/index/StoredFieldsWriterPerThread.cpp b/src/core/index/StoredFieldsWriterPerThread.cpp index a6ea476c..e051f668 100644 --- a/src/core/index/StoredFieldsWriterPerThread.cpp +++ b/src/core/index/StoredFieldsWriterPerThread.cpp @@ -12,7 +12,7 @@ namespace Lucene { - StoredFieldsWriterPerThread::StoredFieldsWriterPerThread(DocStatePtr docState, StoredFieldsWriterPtr storedFieldsWriter) + StoredFieldsWriterPerThread::StoredFieldsWriterPerThread(const DocStatePtr& docState, const StoredFieldsWriterPtr& storedFieldsWriter) { this->_storedFieldsWriter = storedFieldsWriter; this->docState = docState; @@ -34,7 +34,7 @@ namespace Lucene } } - void StoredFieldsWriterPerThread::addField(FieldablePtr field, FieldInfoPtr fieldInfo) + void StoredFieldsWriterPerThread::addField(const FieldablePtr& field, const FieldInfoPtr& fieldInfo) { if (!doc) { diff --git a/src/core/index/Term.cpp b/src/core/index/Term.cpp index 0bce0ff6..6ac2f113 100644 --- a/src/core/index/Term.cpp +++ b/src/core/index/Term.cpp @@ -34,7 +34,7 @@ namespace Lucene return newLucene(_field, text); } - bool Term::equals(LuceneObjectPtr other) + bool Term::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -57,7 +57,7 @@ namespace Lucene return result; } - int32_t Term::compareTo(LuceneObjectPtr other) + int32_t Term::compareTo(const LuceneObjectPtr& other) { TermPtr otherTerm(boost::static_pointer_cast(other)); if (_field == otherTerm->_field) diff --git a/src/core/index/TermBuffer.cpp b/src/core/index/TermBuffer.cpp index 8bf48f67..41f27398 100644 --- a/src/core/index/TermBuffer.cpp +++ b/src/core/index/TermBuffer.cpp @@ -26,7 +26,7 @@ namespace Lucene { } - int32_t TermBuffer::compareTo(LuceneObjectPtr other) + int32_t TermBuffer::compareTo(const LuceneObjectPtr& other) { TermBufferPtr otherTermBuffer(boost::static_pointer_cast(other)); if (field == otherTermBuffer->field) @@ -53,7 +53,7 @@ namespace Lucene preUTF8Strings = true; } - void TermBuffer::read(IndexInputPtr input, FieldInfosPtr fieldInfos) + void TermBuffer::read(const IndexInputPtr& input, const FieldInfosPtr& fieldInfos) { this->term.reset(); // invalidate cache int32_t start = input->readVInt(); @@ -74,7 +74,7 @@ namespace Lucene this->field = fieldInfos->fieldName(input->readVInt()); } - void TermBuffer::set(TermPtr term) + void TermBuffer::set(const TermPtr& term) { if (!term) { @@ -89,7 +89,7 @@ namespace Lucene this->term = term; } - void TermBuffer::set(TermBufferPtr other) + void TermBuffer::set(const TermBufferPtr& other) { text->copyText(other->text); field = other->field; @@ -114,7 +114,7 @@ namespace Lucene return term; } - LuceneObjectPtr TermBuffer::clone(LuceneObjectPtr other) + LuceneObjectPtr TermBuffer::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); TermBufferPtr cloneBuffer(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); diff --git a/src/core/index/TermDocs.cpp b/src/core/index/TermDocs.cpp index 764d75c3..1a6b6097 100644 --- a/src/core/index/TermDocs.cpp +++ b/src/core/index/TermDocs.cpp @@ -13,13 +13,13 @@ namespace Lucene { } - void TermDocs::seek(TermPtr term) + void TermDocs::seek(const TermPtr& term) { BOOST_ASSERT(false); // override } - void TermDocs::seek(TermEnumPtr termEnum) + void TermDocs::seek(const TermEnumPtr& termEnum) { BOOST_ASSERT(false); // override diff --git a/src/core/index/TermInfo.cpp b/src/core/index/TermInfo.cpp index 18683ce2..af6f7dc0 100644 --- a/src/core/index/TermInfo.cpp +++ b/src/core/index/TermInfo.cpp @@ -9,7 +9,7 @@ namespace Lucene { - TermInfo::TermInfo(TermInfoPtr ti) + TermInfo::TermInfo(const TermInfoPtr& ti) { set(ti); } @@ -34,7 +34,7 @@ namespace Lucene this->skipOffset = skipOffset; } - void TermInfo::set(TermInfoPtr ti) + void TermInfo::set(const TermInfoPtr& ti) { docFreq = ti->docFreq; freqPointer = ti->freqPointer; diff --git a/src/core/index/TermInfosReader.cpp b/src/core/index/TermInfosReader.cpp index 46755171..d32b40ec 100644 --- a/src/core/index/TermInfosReader.cpp +++ b/src/core/index/TermInfosReader.cpp @@ -16,7 +16,7 @@ namespace Lucene { const int32_t TermInfosReader::DEFAULT_CACHE_SIZE = 1024; - TermInfosReader::TermInfosReader(DirectoryPtr dir, const String& seg, FieldInfosPtr fis, int32_t readBufferSize, int32_t indexDivisor) + TermInfosReader::TermInfosReader(const DirectoryPtr& dir, const String& seg, const FieldInfosPtr& fis, int32_t readBufferSize, int32_t indexDivisor) { bool success = false; @@ -125,24 +125,24 @@ namespace Lucene return resources; } - int32_t TermInfosReader::getIndexOffset(TermPtr term) + int32_t TermInfosReader::getIndexOffset(const TermPtr& term) { // binary search indexTerms Collection::iterator indexTerm = std::upper_bound(indexTerms.begin(), indexTerms.end(), term, luceneCompare()); return (std::distance(indexTerms.begin(), indexTerm) - 1); } - void TermInfosReader::seekEnum(SegmentTermEnumPtr enumerator, int32_t indexOffset) + void TermInfosReader::seekEnum(const SegmentTermEnumPtr& enumerator, int32_t indexOffset) { enumerator->seek(indexPointers[indexOffset], ((int64_t)indexOffset * (int64_t)totalIndexInterval) - 1, indexTerms[indexOffset], indexInfos[indexOffset]); } - TermInfoPtr TermInfosReader::get(TermPtr term) + TermInfoPtr TermInfosReader::get(const TermPtr& term) { return get(term, true); } - TermInfoPtr TermInfosReader::get(TermPtr term, bool useCache) + TermInfoPtr TermInfosReader::get(const TermPtr& term, bool useCache) { if (_size == 0) return TermInfoPtr(); @@ -212,7 +212,7 @@ namespace Lucene boost::throw_exception(IllegalStateException(L"terms index was not loaded when this reader was created")); } - int64_t TermInfosReader::getPosition(TermPtr term) + int64_t TermInfosReader::getPosition(const TermPtr& term) { if (_size == 0) return -1; @@ -235,7 +235,7 @@ namespace Lucene return boost::static_pointer_cast(origEnum->clone()); } - SegmentTermEnumPtr TermInfosReader::terms(TermPtr term) + SegmentTermEnumPtr TermInfosReader::terms(const TermPtr& term) { // don't use the cache in this call because we want to reposition the enumeration get(term, false); diff --git a/src/core/index/TermInfosWriter.cpp b/src/core/index/TermInfosWriter.cpp index 4d72be16..33e04551 100644 --- a/src/core/index/TermInfosWriter.cpp +++ b/src/core/index/TermInfosWriter.cpp @@ -26,13 +26,13 @@ namespace Lucene /// NOTE: always change this if you switch to a new format. const int32_t TermInfosWriter::FORMAT_CURRENT = TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; - TermInfosWriter::TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval) + TermInfosWriter::TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval) { initialize(directory, segment, fis, interval, false); otherWriter = newLucene(directory, segment, fis, interval, true); } - TermInfosWriter::TermInfosWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isIndex) + TermInfosWriter::TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isIndex) { initialize(directory, segment, fis, interval, isIndex); } @@ -50,7 +50,7 @@ namespace Lucene } } - void TermInfosWriter::initialize(DirectoryPtr directory, const String& segment, FieldInfosPtr fis, int32_t interval, bool isi) + void TermInfosWriter::initialize(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isi) { lastTi = newLucene(); utf8Result = newLucene(); @@ -74,7 +74,7 @@ namespace Lucene BOOST_ASSERT(initUnicodeResults()); } - void TermInfosWriter::add(TermPtr term, TermInfoPtr ti) + void TermInfosWriter::add(const TermPtr& term, const TermInfoPtr& ti) { StringUtils::toUTF8(term->_text.c_str(), term->_text.size(), utf8Result); add(fieldInfos->fieldNumber(term->_field), utf8Result->result, utf8Result->length, ti); @@ -112,7 +112,7 @@ namespace Lucene return (unicodeResult1->length - unicodeResult2->length); } - void TermInfosWriter::add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, TermInfoPtr ti) + void TermInfosWriter::add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, const TermInfoPtr& ti) { // terms out of order? BOOST_ASSERT(compareToLastTerm(fieldNumber, termBytes, termBytesLength) < 0 || (isIndex && termBytesLength == 0 && lastTermBytesLength == 0)); diff --git a/src/core/index/TermVectorEntry.cpp b/src/core/index/TermVectorEntry.cpp index 6a06d675..8f6a7829 100644 --- a/src/core/index/TermVectorEntry.cpp +++ b/src/core/index/TermVectorEntry.cpp @@ -64,7 +64,7 @@ namespace Lucene this->positions = positions; } - bool TermVectorEntry::equals(LuceneObjectPtr other) + bool TermVectorEntry::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/index/TermVectorOffsetInfo.cpp b/src/core/index/TermVectorOffsetInfo.cpp index 6c66e801..36979a41 100644 --- a/src/core/index/TermVectorOffsetInfo.cpp +++ b/src/core/index/TermVectorOffsetInfo.cpp @@ -47,7 +47,7 @@ namespace Lucene this->startOffset = startOffset; } - bool TermVectorOffsetInfo::equals(LuceneObjectPtr other) + bool TermVectorOffsetInfo::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/index/TermVectorsReader.cpp b/src/core/index/TermVectorsReader.cpp index 448a1ce4..48d74861 100644 --- a/src/core/index/TermVectorsReader.cpp +++ b/src/core/index/TermVectorsReader.cpp @@ -43,12 +43,12 @@ namespace Lucene this->format = 0; } - TermVectorsReader::TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos) + TermVectorsReader::TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos) { ConstructReader(d, segment, fieldInfos, BufferedIndexInput::BUFFER_SIZE, -1, 0); } - TermVectorsReader::TermVectorsReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) + TermVectorsReader::TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { ConstructReader(d, segment, fieldInfos, readBufferSize, docStoreOffset, size); } @@ -57,7 +57,7 @@ namespace Lucene { } - void TermVectorsReader::ConstructReader(DirectoryPtr d, const String& segment, FieldInfosPtr fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) + void TermVectorsReader::ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { this->_size = 0; this->numTotalDocs = 0; @@ -198,7 +198,7 @@ namespace Lucene } } - int32_t TermVectorsReader::checkValidFormat(IndexInputPtr in) + int32_t TermVectorsReader::checkValidFormat(const IndexInputPtr& in) { int32_t format = in->readInt(); if (format > FORMAT_CURRENT) @@ -258,7 +258,7 @@ namespace Lucene return _size; } - void TermVectorsReader::get(int32_t docNum, const String& field, TermVectorMapperPtr mapper) + void TermVectorsReader::get(int32_t docNum, const String& field, const TermVectorMapperPtr& mapper) { if (tvx) { @@ -374,7 +374,7 @@ namespace Lucene return result; } - void TermVectorsReader::get(int32_t docNumber, TermVectorMapperPtr mapper) + void TermVectorsReader::get(int32_t docNumber, const TermVectorMapperPtr& mapper) { // Check if no term vectors are available for this segment at all if (tvx) @@ -410,13 +410,13 @@ namespace Lucene return res; } - void TermVectorsReader::readTermVectors(Collection fields, Collection tvfPointers, TermVectorMapperPtr mapper) + void TermVectorsReader::readTermVectors(Collection fields, Collection tvfPointers, const TermVectorMapperPtr& mapper) { for (int32_t i = 0; i < fields.size(); ++i) readTermVector(fields[i], tvfPointers[i], mapper); } - void TermVectorsReader::readTermVector(const String& field, int64_t tvfPointer, TermVectorMapperPtr mapper) + void TermVectorsReader::readTermVector(const String& field, int64_t tvfPointer, const TermVectorMapperPtr& mapper) { // Now read the data from specified position. We don't need to offset by the FORMAT here since // the pointer already includes the offset @@ -541,7 +541,7 @@ namespace Lucene } } - LuceneObjectPtr TermVectorsReader::clone(LuceneObjectPtr other) + LuceneObjectPtr TermVectorsReader::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); TermVectorsReaderPtr cloneReader(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); diff --git a/src/core/index/TermVectorsTermsWriter.cpp b/src/core/index/TermVectorsTermsWriter.cpp index 843937fa..eff282e7 100644 --- a/src/core/index/TermVectorsTermsWriter.cpp +++ b/src/core/index/TermVectorsTermsWriter.cpp @@ -21,7 +21,7 @@ namespace Lucene { - TermVectorsTermsWriter::TermVectorsTermsWriter(DocumentsWriterPtr docWriter) + TermVectorsTermsWriter::TermVectorsTermsWriter(const DocumentsWriterPtr& docWriter) { this->freeCount = 0; this->lastDocID = 0; @@ -34,7 +34,7 @@ namespace Lucene { } - TermsHashConsumerPerThreadPtr TermVectorsTermsWriter::addThread(TermsHashPerThreadPtr perThread) + TermsHashConsumerPerThreadPtr TermVectorsTermsWriter::addThread(const TermsHashPerThreadPtr& perThread) { return newLucene(perThread, shared_from_this()); } @@ -46,7 +46,7 @@ namespace Lucene postings[i] = newLucene(); } - void TermVectorsTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, SegmentWriteStatePtr state) + void TermVectorsTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { SyncLock syncLock(this); @@ -81,7 +81,7 @@ namespace Lucene } } - void TermVectorsTermsWriter::closeDocStore(SegmentWriteStatePtr state) + void TermVectorsTermsWriter::closeDocStore(const SegmentWriteStatePtr& state) { SyncLock syncLock(this); if (tvx) @@ -180,7 +180,7 @@ namespace Lucene } } - void TermVectorsTermsWriter::finishDocument(TermVectorsTermsWriterPerDocPtr perDoc) + void TermVectorsTermsWriter::finishDocument(const TermVectorsTermsWriterPerDocPtr& perDoc) { SyncLock syncLock(this); DocumentsWriterPtr docWriter(_docWriter); @@ -265,7 +265,7 @@ namespace Lucene lastDocID = 0; } - void TermVectorsTermsWriter::free(TermVectorsTermsWriterPerDocPtr doc) + void TermVectorsTermsWriter::free(const TermVectorsTermsWriterPerDocPtr& doc) { SyncLock syncLock(this); BOOST_ASSERT(freeCount < docFreeList.size()); @@ -277,7 +277,7 @@ namespace Lucene return (RawPostingList::BYTES_SIZE + 3 * DocumentsWriter::INT_NUM_BYTE); } - TermVectorsTermsWriterPerDoc::TermVectorsTermsWriterPerDoc(TermVectorsTermsWriterPtr termsWriter) + TermVectorsTermsWriterPerDoc::TermVectorsTermsWriterPerDoc(const TermVectorsTermsWriterPtr& termsWriter) { this->_termsWriter = termsWriter; buffer = DocumentsWriterPtr(termsWriter->_docWriter)->newPerDocBuffer(); diff --git a/src/core/index/TermVectorsTermsWriterPerField.cpp b/src/core/index/TermVectorsTermsWriterPerField.cpp index 321b6d1c..97af0e29 100644 --- a/src/core/index/TermVectorsTermsWriterPerField.cpp +++ b/src/core/index/TermVectorsTermsWriterPerField.cpp @@ -25,7 +25,7 @@ namespace Lucene { - TermVectorsTermsWriterPerField::TermVectorsTermsWriterPerField(TermsHashPerFieldPtr termsHashPerField, TermVectorsTermsWriterPerThreadPtr perThread, FieldInfoPtr fieldInfo) + TermVectorsTermsWriterPerField::TermVectorsTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const TermVectorsTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { this->doVectors = false; this->doVectorPositions = false; @@ -206,7 +206,7 @@ namespace Lucene maxNumPostings = 0; } - void TermVectorsTermsWriterPerField::start(FieldablePtr field) + void TermVectorsTermsWriterPerField::start(const FieldablePtr& field) { if (doVectorOffsets) offsetAttribute = FieldInvertStatePtr(_fieldState)->attributeSource->addAttribute(); @@ -214,7 +214,7 @@ namespace Lucene offsetAttribute.reset(); } - void TermVectorsTermsWriterPerField::newTerm(RawPostingListPtr p0) + void TermVectorsTermsWriterPerField::newTerm(const RawPostingListPtr& p0) { BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); @@ -242,7 +242,7 @@ namespace Lucene } } - void TermVectorsTermsWriterPerField::addTerm(RawPostingListPtr p0) + void TermVectorsTermsWriterPerField::addTerm(const RawPostingListPtr& p0) { BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); diff --git a/src/core/index/TermVectorsTermsWriterPerThread.cpp b/src/core/index/TermVectorsTermsWriterPerThread.cpp index 6acea3db..d07a0096 100644 --- a/src/core/index/TermVectorsTermsWriterPerThread.cpp +++ b/src/core/index/TermVectorsTermsWriterPerThread.cpp @@ -16,7 +16,7 @@ namespace Lucene { - TermVectorsTermsWriterPerThread::TermVectorsTermsWriterPerThread(TermsHashPerThreadPtr termsHashPerThread, TermVectorsTermsWriterPtr termsWriter) + TermVectorsTermsWriterPerThread::TermVectorsTermsWriterPerThread(const TermsHashPerThreadPtr& termsHashPerThread, const TermVectorsTermsWriterPtr& termsWriter) { utf8Results = newCollection(newInstance(), newInstance()); this->vectorSliceReader = newLucene(); @@ -46,7 +46,7 @@ namespace Lucene return returnDoc; } - TermsHashConsumerPerFieldPtr TermVectorsTermsWriterPerThread::addField(TermsHashPerFieldPtr termsHashPerField, FieldInfoPtr fieldInfo) + TermsHashConsumerPerFieldPtr TermVectorsTermsWriterPerThread::addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) { return newLucene(termsHashPerField, shared_from_this(), fieldInfo); } @@ -66,7 +66,7 @@ namespace Lucene return true; } - bool TermVectorsTermsWriterPerThread::vectorFieldsInOrder(FieldInfoPtr fi) + bool TermVectorsTermsWriterPerThread::vectorFieldsInOrder(const FieldInfoPtr& fi) { bool inOrder = lastVectorFieldName.empty() ? true : (lastVectorFieldName < fi->name); lastVectorFieldName = fi->name; diff --git a/src/core/index/TermVectorsWriter.cpp b/src/core/index/TermVectorsWriter.cpp index 344bfa16..309677ec 100644 --- a/src/core/index/TermVectorsWriter.cpp +++ b/src/core/index/TermVectorsWriter.cpp @@ -19,7 +19,7 @@ namespace Lucene { - TermVectorsWriter::TermVectorsWriter(DirectoryPtr directory, const String& segment, FieldInfosPtr fieldInfos) + TermVectorsWriter::TermVectorsWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fieldInfos) { utf8Results = newCollection(newInstance(), newInstance()); @@ -159,7 +159,7 @@ namespace Lucene tvd->writeVInt(0); } - void TermVectorsWriter::addRawDocuments(TermVectorsReaderPtr reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs) + void TermVectorsWriter::addRawDocuments(const TermVectorsReaderPtr& reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs) { int64_t tvdPosition = tvd->getFilePointer(); int64_t tvfPosition = tvf->getFilePointer(); diff --git a/src/core/index/TermsHash.cpp b/src/core/index/TermsHash.cpp index 7874a88a..ccd441c1 100644 --- a/src/core/index/TermsHash.cpp +++ b/src/core/index/TermsHash.cpp @@ -18,7 +18,7 @@ namespace Lucene { - TermsHash::TermsHash(DocumentsWriterPtr docWriter, bool trackAllocations, TermsHashConsumerPtr consumer, TermsHashPtr nextTermsHash) + TermsHash::TermsHash(const DocumentsWriterPtr& docWriter, bool trackAllocations, const TermsHashConsumerPtr& consumer, const TermsHashPtr& nextTermsHash) { this->postingsFreeCount = 0; this->postingsAllocCount = 0; @@ -38,17 +38,17 @@ namespace Lucene { } - InvertedDocConsumerPerThreadPtr TermsHash::addThread(DocInverterPerThreadPtr docInverterPerThread) + InvertedDocConsumerPerThreadPtr TermsHash::addThread(const DocInverterPerThreadPtr& docInverterPerThread) { return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, TermsHashPerThreadPtr()); } - TermsHashPerThreadPtr TermsHash::addThread(DocInverterPerThreadPtr docInverterPerThread, TermsHashPerThreadPtr primaryPerThread) + TermsHashPerThreadPtr TermsHash::addThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPerThreadPtr& primaryPerThread) { return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, primaryPerThread); } - void TermsHash::setFieldInfos(FieldInfosPtr fieldInfos) + void TermsHash::setFieldInfos(const FieldInfosPtr& fieldInfos) { this->fieldInfos = fieldInfos; consumer->setFieldInfos(fieldInfos); @@ -61,7 +61,7 @@ namespace Lucene nextTermsHash->abort(); } - void TermsHash::shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state) + void TermsHash::shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { BOOST_ASSERT(postingsFreeCount == postingsAllocCount); @@ -79,7 +79,7 @@ namespace Lucene } } - void TermsHash::closeDocStore(SegmentWriteStatePtr state) + void TermsHash::closeDocStore(const SegmentWriteStatePtr& state) { SyncLock syncLock(this); consumer->closeDocStore(state); @@ -87,7 +87,7 @@ namespace Lucene nextTermsHash->closeDocStore(state); } - void TermsHash::flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, SegmentWriteStatePtr state) + void TermsHash::flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { SyncLock syncLock(this); MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField childThreadsAndFields(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::newInstance()); diff --git a/src/core/index/TermsHashConsumer.cpp b/src/core/index/TermsHashConsumer.cpp index eb8f8308..49ba2fb1 100644 --- a/src/core/index/TermsHashConsumer.cpp +++ b/src/core/index/TermsHashConsumer.cpp @@ -13,7 +13,7 @@ namespace Lucene { } - void TermsHashConsumer::setFieldInfos(FieldInfosPtr fieldInfos) + void TermsHashConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) { this->fieldInfos = fieldInfos; } diff --git a/src/core/index/TermsHashPerField.cpp b/src/core/index/TermsHashPerField.cpp index 5c8ff05b..02212110 100644 --- a/src/core/index/TermsHashPerField.cpp +++ b/src/core/index/TermsHashPerField.cpp @@ -24,7 +24,7 @@ namespace Lucene { - TermsHashPerField::TermsHashPerField(DocInverterPerFieldPtr docInverterPerField, TermsHashPerThreadPtr perThread, TermsHashPerThreadPtr nextPerThread, FieldInfoPtr fieldInfo) + TermsHashPerField::TermsHashPerField(const DocInverterPerFieldPtr& docInverterPerField, const TermsHashPerThreadPtr& perThread, const TermsHashPerThreadPtr& nextPerThread, const FieldInfoPtr& fieldInfo) { this->_docInverterPerField = docInverterPerField; this->_perThread = perThread; @@ -101,7 +101,7 @@ namespace Lucene nextPerField->abort(); } - void TermsHashPerField::initReader(ByteSliceReaderPtr reader, RawPostingListPtr p, int32_t stream) + void TermsHashPerField::initReader(const ByteSliceReaderPtr& reader, const RawPostingListPtr& p, int32_t stream) { BOOST_ASSERT(stream < streamCount); IntArray ints(intPool->buffers[p->intStart >> DocumentsWriter::INT_BLOCK_SHIFT]); @@ -195,7 +195,7 @@ namespace Lucene return (text[pos] == UTF8Base::UNICODE_TERMINATOR); } - void TermsHashPerField::start(FieldablePtr field) + void TermsHashPerField::start(const FieldablePtr& field) { termAtt = fieldState->attributeSource->addAttribute(); consumer->start(field); diff --git a/src/core/index/TermsHashPerThread.cpp b/src/core/index/TermsHashPerThread.cpp index e602ea7f..22539b81 100644 --- a/src/core/index/TermsHashPerThread.cpp +++ b/src/core/index/TermsHashPerThread.cpp @@ -17,7 +17,7 @@ namespace Lucene { - TermsHashPerThread::TermsHashPerThread(DocInverterPerThreadPtr docInverterPerThread, TermsHashPtr termsHash, TermsHashPtr nextTermsHash, TermsHashPerThreadPtr primaryPerThread) + TermsHashPerThread::TermsHashPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPtr& termsHash, const TermsHashPtr& nextTermsHash, const TermsHashPerThreadPtr& primaryPerThread) { this->freePostings = Collection::newInstance(256); this->freePostingsCount = 0; @@ -58,7 +58,7 @@ namespace Lucene nextPerThread = nextTermsHash->addThread(docInverterPerThread, shared_from_this()); } - InvertedDocConsumerPerFieldPtr TermsHashPerThread::addField(DocInverterPerFieldPtr docInverterPerField, FieldInfoPtr fieldInfo) + InvertedDocConsumerPerFieldPtr TermsHashPerThread::addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) { return newLucene(docInverterPerField, shared_from_this(), nextPerThread, fieldInfo); } diff --git a/src/core/queryparser/FastCharStream.cpp b/src/core/queryparser/FastCharStream.cpp index eb696b36..77a8f7da 100644 --- a/src/core/queryparser/FastCharStream.cpp +++ b/src/core/queryparser/FastCharStream.cpp @@ -11,7 +11,7 @@ namespace Lucene { - FastCharStream::FastCharStream(ReaderPtr reader) + FastCharStream::FastCharStream(const ReaderPtr& reader) { input = reader; bufferLength = 0; diff --git a/src/core/queryparser/MultiFieldQueryParser.cpp b/src/core/queryparser/MultiFieldQueryParser.cpp index d9594143..e3353d31 100644 --- a/src/core/queryparser/MultiFieldQueryParser.cpp +++ b/src/core/queryparser/MultiFieldQueryParser.cpp @@ -14,13 +14,13 @@ namespace Lucene { - MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, AnalyzerPtr analyzer, MapStringDouble boosts) : QueryParser(matchVersion, L"", analyzer) + MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer, MapStringDouble boosts) : QueryParser(matchVersion, L"", analyzer) { this->boosts = boosts; this->fields = fields; } - MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, AnalyzerPtr analyzer) : QueryParser(matchVersion, L"", analyzer) + MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer) : QueryParser(matchVersion, L"", analyzer) { this->fields = fields; } @@ -65,7 +65,7 @@ namespace Lucene return getFieldQuery(field, queryText, 0); } - void MultiFieldQueryParser::applySlop(QueryPtr query, int32_t slop) + void MultiFieldQueryParser::applySlop(const QueryPtr& query, int32_t slop) { if (MiscUtils::typeOf(query)) boost::dynamic_pointer_cast(query)->setSlop(slop); @@ -121,7 +121,7 @@ namespace Lucene return QueryParser::getRangeQuery(field, part1, part2, inclusive); } - QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, AnalyzerPtr analyzer) + QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, const AnalyzerPtr& analyzer) { if (queries.size() != fields.size()) boost::throw_exception(IllegalArgumentException(L"queries.size() != fields.size()")); @@ -136,7 +136,7 @@ namespace Lucene return booleanQuery; } - QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, AnalyzerPtr analyzer) + QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, const AnalyzerPtr& analyzer) { if (fields.size() != flags.size()) boost::throw_exception(IllegalArgumentException(L"fields.size() != flags.size()")); @@ -151,7 +151,7 @@ namespace Lucene return booleanQuery; } - QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, AnalyzerPtr analyzer) + QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, const AnalyzerPtr& analyzer) { if (queries.size() != fields.size() || fields.size() != flags.size()) boost::throw_exception(IllegalArgumentException(L"queries, fields, and flags array have have different length")); diff --git a/src/core/queryparser/QueryParseError.cpp b/src/core/queryparser/QueryParseError.cpp index 2fac15b9..5ea10c4b 100644 --- a/src/core/queryparser/QueryParseError.cpp +++ b/src/core/queryparser/QueryParseError.cpp @@ -28,7 +28,7 @@ namespace Lucene return buffer.str(); } - String QueryParseError::parseError(QueryParserTokenPtr currentToken, Collection< Collection > expectedTokenSequences, + String QueryParseError::parseError(const QueryParserTokenPtr& currentToken, Collection< Collection > expectedTokenSequences, Collection tokenImage) { StringStream expected; diff --git a/src/core/queryparser/QueryParser.cpp b/src/core/queryparser/QueryParser.cpp index baac3799..bc3cf838 100644 --- a/src/core/queryparser/QueryParser.cpp +++ b/src/core/queryparser/QueryParser.cpp @@ -54,7 +54,7 @@ namespace Lucene 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0 }; - QueryParser::QueryParser(LuceneVersion::Version matchVersion, const String& field, AnalyzerPtr analyzer) + QueryParser::QueryParser(LuceneVersion::Version matchVersion, const String& field, const AnalyzerPtr& analyzer) { ConstructParser(newLucene(newLucene(L"")), QueryParserTokenManagerPtr()); this->analyzer = analyzer; @@ -62,12 +62,12 @@ namespace Lucene this->enablePositionIncrements = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_29); } - QueryParser::QueryParser(QueryParserCharStreamPtr stream) + QueryParser::QueryParser(const QueryParserCharStreamPtr& stream) { ConstructParser(stream, QueryParserTokenManagerPtr()); } - QueryParser::QueryParser(QueryParserTokenManagerPtr tokenMgr) + QueryParser::QueryParser(const QueryParserTokenManagerPtr& tokenMgr) { ConstructParser(QueryParserCharStreamPtr(), tokenMgr); } @@ -76,7 +76,7 @@ namespace Lucene { } - void QueryParser::ConstructParser(QueryParserCharStreamPtr stream, QueryParserTokenManagerPtr tokenMgr) + void QueryParser::ConstructParser(const QueryParserCharStreamPtr& stream, const QueryParserTokenManagerPtr& tokenMgr) { _operator = OR_OPERATOR; lowercaseExpandedTerms = true; @@ -208,7 +208,7 @@ namespace Lucene return lowercaseExpandedTerms; } - void QueryParser::setMultiTermRewriteMethod(RewriteMethodPtr method) + void QueryParser::setMultiTermRewriteMethod(const RewriteMethodPtr& method) { multiTermRewriteMethod = method; } @@ -268,7 +268,7 @@ namespace Lucene return resolution->second; } - void QueryParser::setRangeCollator(CollatorPtr rc) + void QueryParser::setRangeCollator(const CollatorPtr& rc) { rangeCollator = rc; } @@ -278,7 +278,7 @@ namespace Lucene return rangeCollator; } - void QueryParser::addClause(Collection clauses, int32_t conj, int32_t mods, QueryPtr q) + void QueryParser::addClause(Collection clauses, int32_t conj, int32_t mods, const QueryPtr& q) { bool required = false; bool prohibited = false; @@ -589,12 +589,12 @@ namespace Lucene return newLucene(disableCoord); } - BooleanClausePtr QueryParser::newBooleanClause(QueryPtr q, BooleanClause::Occur occur) + BooleanClausePtr QueryParser::newBooleanClause(const QueryPtr& q, BooleanClause::Occur occur) { return newLucene(q, occur); } - QueryPtr QueryParser::newTermQuery(TermPtr term) + QueryPtr QueryParser::newTermQuery(const TermPtr& term) { return newLucene(term); } @@ -609,14 +609,14 @@ namespace Lucene return newLucene(); } - QueryPtr QueryParser::newPrefixQuery(TermPtr prefix) + QueryPtr QueryParser::newPrefixQuery(const TermPtr& prefix) { PrefixQueryPtr query(newLucene(prefix)); query->setRewriteMethod(multiTermRewriteMethod); return query; } - QueryPtr QueryParser::newFuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength) + QueryPtr QueryParser::newFuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) { // FuzzyQuery doesn't yet allow constant score rewrite return newLucene(term, minimumSimilarity, prefixLength); @@ -634,7 +634,7 @@ namespace Lucene return newLucene(); } - QueryPtr QueryParser::newWildcardQuery(TermPtr term) + QueryPtr QueryParser::newWildcardQuery(const TermPtr& term) { WildcardQueryPtr query(newLucene(term)); query->setRewriteMethod(multiTermRewriteMethod); @@ -1293,7 +1293,7 @@ namespace Lucene return false; } - void QueryParser::ReInit(QueryParserCharStreamPtr stream) + void QueryParser::ReInit(const QueryParserCharStreamPtr& stream) { token_source->ReInit(stream); token = newLucene(); @@ -1305,7 +1305,7 @@ namespace Lucene jj_2_rtns[i] = newInstance(); } - void QueryParser::ReInit(QueryParserTokenManagerPtr tokenMgr) + void QueryParser::ReInit(const QueryParserTokenManagerPtr& tokenMgr) { token_source = tokenMgr; token = newLucene(); diff --git a/src/core/queryparser/QueryParserTokenManager.cpp b/src/core/queryparser/QueryParserTokenManager.cpp index 547690a7..894cfd27 100644 --- a/src/core/queryparser/QueryParserTokenManager.cpp +++ b/src/core/queryparser/QueryParserTokenManager.cpp @@ -45,7 +45,7 @@ namespace Lucene const int64_t QueryParserTokenManager::jjtoToken[] = {0x3ffffff01LL}; const int64_t QueryParserTokenManager::jjtoSkip[] = {0x80LL}; - QueryParserTokenManager::QueryParserTokenManager(QueryParserCharStreamPtr stream) + QueryParserTokenManager::QueryParserTokenManager(const QueryParserCharStreamPtr& stream) { debugStream = newLucene(); jjrounds = IntArray::newInstance(36); @@ -60,7 +60,7 @@ namespace Lucene input_stream = stream; } - QueryParserTokenManager::QueryParserTokenManager(QueryParserCharStreamPtr stream, int32_t lexState) + QueryParserTokenManager::QueryParserTokenManager(const QueryParserCharStreamPtr& stream, int32_t lexState) { debugStream = newLucene(); jjrounds = IntArray::newInstance(36); @@ -80,7 +80,7 @@ namespace Lucene { } - void QueryParserTokenManager::setDebugStream(InfoStreamPtr debugStream) + void QueryParserTokenManager::setDebugStream(const InfoStreamPtr& debugStream) { this->debugStream = debugStream; } @@ -1154,7 +1154,7 @@ namespace Lucene } } - void QueryParserTokenManager::ReInit(QueryParserCharStreamPtr stream) + void QueryParserTokenManager::ReInit(const QueryParserCharStreamPtr& stream) { jjmatchedPos = 0; jjnewStateCnt = 0; @@ -1170,7 +1170,7 @@ namespace Lucene jjrounds[i] = 0x80000000; } - void QueryParserTokenManager::ReInit(QueryParserCharStreamPtr stream, int32_t lexState) + void QueryParserTokenManager::ReInit(const QueryParserCharStreamPtr& stream, int32_t lexState) { ReInit(stream); SwitchTo(lexState); diff --git a/src/core/search/BooleanClause.cpp b/src/core/search/BooleanClause.cpp index cbb95eb9..2f4a4703 100644 --- a/src/core/search/BooleanClause.cpp +++ b/src/core/search/BooleanClause.cpp @@ -10,7 +10,7 @@ namespace Lucene { - BooleanClause::BooleanClause(QueryPtr query, Occur occur) + BooleanClause::BooleanClause(const QueryPtr& query, Occur occur) { this->query = query; this->occur = occur; @@ -35,7 +35,7 @@ namespace Lucene return query; } - void BooleanClause::setQuery(QueryPtr query) + void BooleanClause::setQuery(const QueryPtr& query) { this->query = query; } @@ -50,7 +50,7 @@ namespace Lucene return (occur == MUST); } - bool BooleanClause::equals(LuceneObjectPtr other) + bool BooleanClause::equals(const LuceneObjectPtr& other) { BooleanClausePtr otherBooleanClause(boost::dynamic_pointer_cast(other)); if (!otherBooleanClause) diff --git a/src/core/search/BooleanQuery.cpp b/src/core/search/BooleanQuery.cpp index a86ea88f..6a59e9e9 100644 --- a/src/core/search/BooleanQuery.cpp +++ b/src/core/search/BooleanQuery.cpp @@ -45,7 +45,7 @@ namespace Lucene return disableCoord; } - SimilarityPtr BooleanQuery::getSimilarity(SearcherPtr searcher) + SimilarityPtr BooleanQuery::getSimilarity(const SearcherPtr& searcher) { SimilarityPtr result(Query::getSimilarity(searcher)); if (disableCoord) // disable coord as requested @@ -63,12 +63,12 @@ namespace Lucene return minNrShouldMatch; } - void BooleanQuery::add(QueryPtr query, BooleanClause::Occur occur) + void BooleanQuery::add(const QueryPtr& query, BooleanClause::Occur occur) { add(newLucene(query, occur)); } - void BooleanQuery::add(BooleanClausePtr clause) + void BooleanQuery::add(const BooleanClausePtr& clause) { if (clauses.size() >= maxClauseCount) boost::throw_exception(TooManyClausesException(L"maxClauseCount is set to " + StringUtils::toString(maxClauseCount))); @@ -90,12 +90,12 @@ namespace Lucene return clauses.end(); } - WeightPtr BooleanQuery::createWeight(SearcherPtr searcher) + WeightPtr BooleanQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } - QueryPtr BooleanQuery::rewrite(IndexReaderPtr reader) + QueryPtr BooleanQuery::rewrite(const IndexReaderPtr& reader) { if (minNrShouldMatch == 0 && clauses.size() == 1) // optimize 1-clause queries { @@ -140,7 +140,7 @@ namespace Lucene (*clause)->getQuery()->extractTerms(terms); } - LuceneObjectPtr BooleanQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr BooleanQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); BooleanQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -198,7 +198,7 @@ namespace Lucene return buffer; } - bool BooleanQuery::equals(LuceneObjectPtr other) + bool BooleanQuery::equals(const LuceneObjectPtr& other) { BooleanQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) @@ -215,7 +215,7 @@ namespace Lucene getMinimumNumberShouldMatch() + (disableCoord ? 17 : 0); } - BooleanWeight::BooleanWeight(BooleanQueryPtr query, SearcherPtr searcher) + BooleanWeight::BooleanWeight(const BooleanQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = query->getSimilarity(searcher); @@ -267,7 +267,7 @@ namespace Lucene } } - ExplanationPtr BooleanWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr BooleanWeight::explain(const IndexReaderPtr& reader, int32_t doc) { int32_t minShouldMatch = query->getMinimumNumberShouldMatch(); ComplexExplanationPtr sumExpl(newLucene()); @@ -340,7 +340,7 @@ namespace Lucene } } - ScorerPtr BooleanWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr BooleanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { Collection required(Collection::newInstance()); Collection prohibited(Collection::newInstance()); @@ -400,7 +400,7 @@ namespace Lucene return true; } - SimilarityDisableCoord::SimilarityDisableCoord(SimilarityPtr delegee) : SimilarityDelegator(delegee) + SimilarityDisableCoord::SimilarityDisableCoord(const SimilarityPtr& delegee) : SimilarityDelegator(delegee) { } diff --git a/src/core/search/BooleanScorer.cpp b/src/core/search/BooleanScorer.cpp index 8992ce90..f545c241 100644 --- a/src/core/search/BooleanScorer.cpp +++ b/src/core/search/BooleanScorer.cpp @@ -10,7 +10,7 @@ namespace Lucene { - BooleanScorer::BooleanScorer(SimilarityPtr similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers) : Scorer(similarity) + BooleanScorer::BooleanScorer(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers) : Scorer(similarity) { this->bucketTable = newLucene(); this->maxCoord = 1; @@ -53,7 +53,7 @@ namespace Lucene { } - bool BooleanScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) + bool BooleanScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { bool more = false; BucketPtr tmp; @@ -174,7 +174,7 @@ namespace Lucene return current->score * coordFactors[current->coord]; } - void BooleanScorer::score(CollectorPtr collector) + void BooleanScorer::score(const CollectorPtr& collector) { score(collector, INT_MAX, nextDoc()); } @@ -189,7 +189,7 @@ namespace Lucene return buffer.str(); } - BooleanScorerCollector::BooleanScorerCollector(int32_t mask, BucketTablePtr bucketTable) + BooleanScorerCollector::BooleanScorerCollector(int32_t mask, const BucketTablePtr& bucketTable) { this->mask = mask; this->_bucketTable = bucketTable; @@ -228,12 +228,12 @@ namespace Lucene } } - void BooleanScorerCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void BooleanScorerCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { // not needed by this implementation } - void BooleanScorerCollector::setScorer(ScorerPtr scorer) + void BooleanScorerCollector::setScorer(const ScorerPtr& scorer) { this->_scorer = scorer; } @@ -307,7 +307,7 @@ namespace Lucene return SIZE; } - SubScorer::SubScorer(ScorerPtr scorer, bool required, bool prohibited, CollectorPtr collector, SubScorerPtr next) + SubScorer::SubScorer(const ScorerPtr& scorer, bool required, bool prohibited, const CollectorPtr& collector, const SubScorerPtr& next) { this->scorer = scorer; this->required = required; diff --git a/src/core/search/BooleanScorer2.cpp b/src/core/search/BooleanScorer2.cpp index c743cb46..79589654 100644 --- a/src/core/search/BooleanScorer2.cpp +++ b/src/core/search/BooleanScorer2.cpp @@ -13,7 +13,7 @@ namespace Lucene { - BooleanScorer2::BooleanScorer2(SimilarityPtr similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional) : Scorer(similarity) + BooleanScorer2::BooleanScorer2(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional) : Scorer(similarity) { this->minNrShouldMatch = minNrShouldMatch; this->requiredScorers = required; @@ -51,7 +51,7 @@ namespace Lucene return newLucene(shared_from_this(), Similarity::getDefault(), requiredScorers); } - ScorerPtr BooleanScorer2::dualConjunctionSumScorer(ScorerPtr req1, ScorerPtr req2) + ScorerPtr BooleanScorer2::dualConjunctionSumScorer(const ScorerPtr& req1, const ScorerPtr& req2) { Collection scorers(newCollection(req1, req2)); @@ -97,19 +97,19 @@ namespace Lucene } } - ScorerPtr BooleanScorer2::addProhibitedScorers(ScorerPtr requiredCountingSumScorer) + ScorerPtr BooleanScorer2::addProhibitedScorers(const ScorerPtr& requiredCountingSumScorer) { return prohibitedScorers.empty() ? requiredCountingSumScorer : newLucene(requiredCountingSumScorer, (prohibitedScorers.size() == 1 ? prohibitedScorers[0] : newLucene(prohibitedScorers))); } - void BooleanScorer2::score(CollectorPtr collector) + void BooleanScorer2::score(const CollectorPtr& collector) { collector->setScorer(shared_from_this()); while ((doc = countingSumScorer->nextDoc()) != NO_MORE_DOCS) collector->collect(doc); } - bool BooleanScorer2::score(CollectorPtr collector, int32_t max, int32_t firstDocID) + bool BooleanScorer2::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { doc = firstDocID; collector->setScorer(shared_from_this()); @@ -145,7 +145,7 @@ namespace Lucene return doc; } - Coordinator::Coordinator(BooleanScorer2Ptr scorer) + Coordinator::Coordinator(const BooleanScorer2Ptr& scorer) { _scorer = scorer; maxCoord = 0; @@ -164,7 +164,7 @@ namespace Lucene coordFactors[i] = sim->coord(i, maxCoord); } - SingleMatchScorer::SingleMatchScorer(ScorerPtr scorer, CoordinatorPtr coordinator) : Scorer(scorer->getSimilarity()) + SingleMatchScorer::SingleMatchScorer(const ScorerPtr& scorer, const CoordinatorPtr& coordinator) : Scorer(scorer->getSimilarity()) { lastScoredDoc = -1; lastDocScore = std::numeric_limits::quiet_NaN(); @@ -206,7 +206,7 @@ namespace Lucene return scorer->advance(target); } - CountingDisjunctionSumScorer::CountingDisjunctionSumScorer(BooleanScorer2Ptr scorer, Collection subScorers, int32_t minimumNrMatchers) : DisjunctionSumScorer(subScorers, minimumNrMatchers) + CountingDisjunctionSumScorer::CountingDisjunctionSumScorer(const BooleanScorer2Ptr& scorer, Collection subScorers, int32_t minimumNrMatchers) : DisjunctionSumScorer(subScorers, minimumNrMatchers) { _scorer = scorer; lastScoredDoc = -1; @@ -232,7 +232,7 @@ namespace Lucene return lastDocScore; } - CountingConjunctionSumScorer::CountingConjunctionSumScorer(BooleanScorer2Ptr scorer, SimilarityPtr similarity, Collection scorers) : ConjunctionScorer(similarity, scorers) + CountingConjunctionSumScorer::CountingConjunctionSumScorer(const BooleanScorer2Ptr& scorer, const SimilarityPtr& similarity, Collection scorers) : ConjunctionScorer(similarity, scorers) { _scorer = scorer; lastScoredDoc = -1; diff --git a/src/core/search/CachingSpanFilter.cpp b/src/core/search/CachingSpanFilter.cpp index c1db7111..912aef81 100644 --- a/src/core/search/CachingSpanFilter.cpp +++ b/src/core/search/CachingSpanFilter.cpp @@ -12,7 +12,7 @@ namespace Lucene { - CachingSpanFilter::CachingSpanFilter(SpanFilterPtr filter, CachingWrapperFilter::DeletesMode deletesMode) + CachingSpanFilter::CachingSpanFilter(const SpanFilterPtr& filter, CachingWrapperFilter::DeletesMode deletesMode) { this->filter = filter; if (deletesMode == CachingWrapperFilter::DELETES_DYNAMIC) @@ -26,13 +26,13 @@ namespace Lucene { } - DocIdSetPtr CachingSpanFilter::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr CachingSpanFilter::getDocIdSet(const IndexReaderPtr& reader) { SpanFilterResultPtr result(getCachedResult(reader)); return result ? result->getDocIdSet() : DocIdSetPtr(); } - SpanFilterResultPtr CachingSpanFilter::getCachedResult(IndexReaderPtr reader) + SpanFilterResultPtr CachingSpanFilter::getCachedResult(const IndexReaderPtr& reader) { LuceneObjectPtr coreKey = reader->getFieldCacheKey(); LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; @@ -52,7 +52,7 @@ namespace Lucene return result; } - SpanFilterResultPtr CachingSpanFilter::bitSpans(IndexReaderPtr reader) + SpanFilterResultPtr CachingSpanFilter::bitSpans(const IndexReaderPtr& reader) { return getCachedResult(reader); } @@ -62,7 +62,7 @@ namespace Lucene return L"CachingSpanFilter(" + filter->toString() + L")"; } - bool CachingSpanFilter::equals(LuceneObjectPtr other) + bool CachingSpanFilter::equals(const LuceneObjectPtr& other) { if (SpanFilter::equals(other)) return true; @@ -87,7 +87,7 @@ namespace Lucene { } - LuceneObjectPtr FilterCacheSpanFilterResult::mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value) + LuceneObjectPtr FilterCacheSpanFilterResult::mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) { boost::throw_exception(IllegalStateException(L"DeletesMode::DYNAMIC is not supported")); return LuceneObjectPtr(); diff --git a/src/core/search/CachingWrapperFilter.cpp b/src/core/search/CachingWrapperFilter.cpp index e88c54dc..7ac05bfa 100644 --- a/src/core/search/CachingWrapperFilter.cpp +++ b/src/core/search/CachingWrapperFilter.cpp @@ -12,7 +12,7 @@ namespace Lucene { - CachingWrapperFilter::CachingWrapperFilter(FilterPtr filter, DeletesMode deletesMode) + CachingWrapperFilter::CachingWrapperFilter(const FilterPtr& filter, DeletesMode deletesMode) { this->filter = filter; this->cache = newLucene(deletesMode); @@ -24,7 +24,7 @@ namespace Lucene { } - DocIdSetPtr CachingWrapperFilter::docIdSetToCache(DocIdSetPtr docIdSet, IndexReaderPtr reader) + DocIdSetPtr CachingWrapperFilter::docIdSetToCache(const DocIdSetPtr& docIdSet, const IndexReaderPtr& reader) { if (!docIdSet) { @@ -42,7 +42,7 @@ namespace Lucene } } - DocIdSetPtr CachingWrapperFilter::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr CachingWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) { LuceneObjectPtr coreKey = reader->getFieldCacheKey(); LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; @@ -70,7 +70,7 @@ namespace Lucene return L"CachingWrapperFilter(" + filter->toString() + L")"; } - bool CachingWrapperFilter::equals(LuceneObjectPtr other) + bool CachingWrapperFilter::equals(const LuceneObjectPtr& other) { if (Filter::equals(other)) return true; @@ -96,7 +96,7 @@ namespace Lucene { } - LuceneObjectPtr FilterCache::get(IndexReaderPtr reader, LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey) + LuceneObjectPtr FilterCache::get(const IndexReaderPtr& reader, const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey) { SyncLock syncLock(this); @@ -133,7 +133,7 @@ namespace Lucene return value; } - void FilterCache::put(LuceneObjectPtr coreKey, LuceneObjectPtr delCoreKey, LuceneObjectPtr value) + void FilterCache::put(const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey, const LuceneObjectPtr& value) { SyncLock syncLock(this); @@ -156,12 +156,12 @@ namespace Lucene { } - LuceneObjectPtr FilterCacheDocIdSet::mergeDeletes(IndexReaderPtr reader, LuceneObjectPtr value) + LuceneObjectPtr FilterCacheDocIdSet::mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) { return newLucene(reader, boost::dynamic_pointer_cast(value)); } - FilteredCacheDocIdSet::FilteredCacheDocIdSet(IndexReaderPtr reader, DocIdSetPtr innerSet) : FilteredDocIdSet(innerSet) + FilteredCacheDocIdSet::FilteredCacheDocIdSet(const IndexReaderPtr& reader, const DocIdSetPtr& innerSet) : FilteredDocIdSet(innerSet) { this->reader = reader; } diff --git a/src/core/search/ConjunctionScorer.cpp b/src/core/search/ConjunctionScorer.cpp index e6459b73..dd33d3bb 100644 --- a/src/core/search/ConjunctionScorer.cpp +++ b/src/core/search/ConjunctionScorer.cpp @@ -18,7 +18,7 @@ namespace Lucene } }; - ConjunctionScorer::ConjunctionScorer(SimilarityPtr similarity, Collection scorers) : Scorer(similarity) + ConjunctionScorer::ConjunctionScorer(const SimilarityPtr& similarity, Collection scorers) : Scorer(similarity) { this->lastDoc = -1; this->scorers = scorers; diff --git a/src/core/search/ConstantScoreQuery.cpp b/src/core/search/ConstantScoreQuery.cpp index 00a9485d..0a4429df 100644 --- a/src/core/search/ConstantScoreQuery.cpp +++ b/src/core/search/ConstantScoreQuery.cpp @@ -15,7 +15,7 @@ namespace Lucene { - ConstantScoreQuery::ConstantScoreQuery(FilterPtr filter) + ConstantScoreQuery::ConstantScoreQuery(const FilterPtr& filter) { this->filter = filter; } @@ -29,7 +29,7 @@ namespace Lucene return filter; } - QueryPtr ConstantScoreQuery::rewrite(IndexReaderPtr reader) + QueryPtr ConstantScoreQuery::rewrite(const IndexReaderPtr& reader) { return shared_from_this(); } @@ -39,7 +39,7 @@ namespace Lucene // OK to not add any terms when used for MultiSearcher, but may not be OK for highlighting } - WeightPtr ConstantScoreQuery::createWeight(SearcherPtr searcher) + WeightPtr ConstantScoreQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } @@ -49,7 +49,7 @@ namespace Lucene return L"ConstantScore(" + filter->toString() + (getBoost() == 1.0 ? L")" : L"^" + StringUtils::toString(getBoost())); } - bool ConstantScoreQuery::equals(LuceneObjectPtr other) + bool ConstantScoreQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -67,7 +67,7 @@ namespace Lucene return filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); } - LuceneObjectPtr ConstantScoreQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr ConstantScoreQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(filter); ConstantScoreQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); @@ -75,7 +75,7 @@ namespace Lucene return cloneQuery; } - ConstantWeight::ConstantWeight(ConstantScoreQueryPtr constantScorer, SearcherPtr searcher) + ConstantWeight::ConstantWeight(const ConstantScoreQueryPtr& constantScorer, const SearcherPtr& searcher) { this->constantScorer = constantScorer; this->similarity = constantScorer->getSimilarity(searcher); @@ -109,12 +109,12 @@ namespace Lucene queryWeight *= this->queryNorm; } - ScorerPtr ConstantWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr ConstantWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(constantScorer, similarity, reader, shared_from_this()); } - ExplanationPtr ConstantWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr ConstantWeight::explain(const IndexReaderPtr& reader, int32_t doc) { ConstantScorerPtr cs(newLucene(constantScorer, similarity, reader, shared_from_this())); bool exists = (cs->docIdSetIterator->advance(doc) == doc); @@ -138,7 +138,7 @@ namespace Lucene return result; } - ConstantScorer::ConstantScorer(ConstantScoreQueryPtr constantScorer, SimilarityPtr similarity, IndexReaderPtr reader, WeightPtr w) : Scorer(similarity) + ConstantScorer::ConstantScorer(const ConstantScoreQueryPtr& constantScorer, const SimilarityPtr& similarity, const IndexReaderPtr& reader, const WeightPtr& w) : Scorer(similarity) { doc = -1; theScore = w->getValue(); diff --git a/src/core/search/DefaultSimilarity.cpp b/src/core/search/DefaultSimilarity.cpp index 9217f007..e55a75ca 100644 --- a/src/core/search/DefaultSimilarity.cpp +++ b/src/core/search/DefaultSimilarity.cpp @@ -19,7 +19,7 @@ namespace Lucene { } - double DefaultSimilarity::computeNorm(const String& fieldName, FieldInvertStatePtr state) + double DefaultSimilarity::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) { int32_t numTerms; if (discountOverlaps) diff --git a/src/core/search/DisjunctionMaxQuery.cpp b/src/core/search/DisjunctionMaxQuery.cpp index 13f90d77..ce778508 100644 --- a/src/core/search/DisjunctionMaxQuery.cpp +++ b/src/core/search/DisjunctionMaxQuery.cpp @@ -34,7 +34,7 @@ namespace Lucene { } - void DisjunctionMaxQuery::add(QueryPtr query) + void DisjunctionMaxQuery::add(const QueryPtr& query) { disjuncts.add(query); } @@ -54,12 +54,12 @@ namespace Lucene return disjuncts.end(); } - WeightPtr DisjunctionMaxQuery::createWeight(SearcherPtr searcher) + WeightPtr DisjunctionMaxQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } - QueryPtr DisjunctionMaxQuery::rewrite(IndexReaderPtr reader) + QueryPtr DisjunctionMaxQuery::rewrite(const IndexReaderPtr& reader) { int32_t numDisjunctions = disjuncts.size(); if (numDisjunctions == 1) @@ -89,7 +89,7 @@ namespace Lucene return clone ? clone : shared_from_this(); } - LuceneObjectPtr DisjunctionMaxQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr DisjunctionMaxQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); DisjunctionMaxQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -124,7 +124,7 @@ namespace Lucene return buffer; } - bool DisjunctionMaxQuery::equals(LuceneObjectPtr other) + bool DisjunctionMaxQuery::equals(const LuceneObjectPtr& other) { if (!Query::equals(other)) return false; @@ -141,7 +141,7 @@ namespace Lucene return MiscUtils::doubleToIntBits(getBoost()) + MiscUtils::doubleToIntBits(tieBreakerMultiplier) + MiscUtils::hashCode(disjuncts.begin(), disjuncts.end(), MiscUtils::hashLucene); } - DisjunctionMaxWeight::DisjunctionMaxWeight(DisjunctionMaxQueryPtr query, SearcherPtr searcher) + DisjunctionMaxWeight::DisjunctionMaxWeight(const DisjunctionMaxQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = searcher->getSimilarity(); @@ -185,7 +185,7 @@ namespace Lucene (*wt)->normalize(norm); } - ScorerPtr DisjunctionMaxWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr DisjunctionMaxWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { Collection scorers(Collection::newInstance(weights.size())); int32_t idx = 0; @@ -201,7 +201,7 @@ namespace Lucene return result; } - ExplanationPtr DisjunctionMaxWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr DisjunctionMaxWeight::explain(const IndexReaderPtr& reader, int32_t doc) { if (query->disjuncts.size() == 1) return weights[0]->explain(reader, doc); diff --git a/src/core/search/DisjunctionMaxScorer.cpp b/src/core/search/DisjunctionMaxScorer.cpp index e25cf94d..b2f2200d 100644 --- a/src/core/search/DisjunctionMaxScorer.cpp +++ b/src/core/search/DisjunctionMaxScorer.cpp @@ -9,7 +9,7 @@ namespace Lucene { - DisjunctionMaxScorer::DisjunctionMaxScorer(double tieBreakerMultiplier, SimilarityPtr similarity, Collection subScorers, int32_t numScorers) : Scorer(similarity) + DisjunctionMaxScorer::DisjunctionMaxScorer(double tieBreakerMultiplier, const SimilarityPtr& similarity, Collection subScorers, int32_t numScorers) : Scorer(similarity) { this->doc = -1; this->tieBreakerMultiplier = tieBreakerMultiplier; diff --git a/src/core/search/DisjunctionSumScorer.cpp b/src/core/search/DisjunctionSumScorer.cpp index 060d18b4..0147c611 100644 --- a/src/core/search/DisjunctionSumScorer.cpp +++ b/src/core/search/DisjunctionSumScorer.cpp @@ -47,14 +47,14 @@ namespace Lucene } } - void DisjunctionSumScorer::score(CollectorPtr collector) + void DisjunctionSumScorer::score(const CollectorPtr& collector) { collector->setScorer(shared_from_this()); while (nextDoc() != NO_MORE_DOCS) collector->collect(currentDoc); } - bool DisjunctionSumScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) + bool DisjunctionSumScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { // firstDocID is ignored since nextDoc() sets 'currentDoc' collector->setScorer(shared_from_this()); diff --git a/src/core/search/ExactPhraseScorer.cpp b/src/core/search/ExactPhraseScorer.cpp index 020919f9..f1f56255 100644 --- a/src/core/search/ExactPhraseScorer.cpp +++ b/src/core/search/ExactPhraseScorer.cpp @@ -11,7 +11,7 @@ namespace Lucene { - ExactPhraseScorer::ExactPhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) + ExactPhraseScorer::ExactPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) { } diff --git a/src/core/search/Explanation.cpp b/src/core/search/Explanation.cpp index 294f3ba4..f59cd816 100644 --- a/src/core/search/Explanation.cpp +++ b/src/core/search/Explanation.cpp @@ -57,7 +57,7 @@ namespace Lucene return Collection::newInstance(this->details.begin(), this->details.end()); } - void Explanation::addDetail(ExplanationPtr detail) + void Explanation::addDetail(const ExplanationPtr& detail) { if (!details) details = Collection::newInstance(); diff --git a/src/core/search/FieldCache.cpp b/src/core/search/FieldCache.cpp index 4895c54a..d5f7e59e 100644 --- a/src/core/search/FieldCache.cpp +++ b/src/core/search/FieldCache.cpp @@ -108,67 +108,67 @@ namespace Lucene return _NUMERIC_UTILS_DOUBLE_PARSER; } - Collection FieldCache::getBytes(IndexReaderPtr reader, const String& field) + Collection FieldCache::getBytes(const IndexReaderPtr& reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser) + Collection FieldCache::getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getInts(IndexReaderPtr reader, const String& field) + Collection FieldCache::getInts(const IndexReaderPtr& reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser) + Collection FieldCache::getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getLongs(IndexReaderPtr reader, const String& field) + Collection FieldCache::getLongs(const IndexReaderPtr& reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser) + Collection FieldCache::getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getDoubles(IndexReaderPtr reader, const String& field) + Collection FieldCache::getDoubles(const IndexReaderPtr& reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser) + Collection FieldCache::getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser) { BOOST_ASSERT(false); return Collection(); // override } - Collection FieldCache::getStrings(IndexReaderPtr reader, const String& field) + Collection FieldCache::getStrings(const IndexReaderPtr& reader, const String& field) { BOOST_ASSERT(false); return Collection(); // override } - StringIndexPtr FieldCache::getStringIndex(IndexReaderPtr reader, const String& field) + StringIndexPtr FieldCache::getStringIndex(const IndexReaderPtr& reader, const String& field) { BOOST_ASSERT(false); return StringIndexPtr(); // override } - void FieldCache::setInfoStream(InfoStreamPtr stream) + void FieldCache::setInfoStream(const InfoStreamPtr& stream) { BOOST_ASSERT(false); // override diff --git a/src/core/search/FieldCacheImpl.cpp b/src/core/search/FieldCacheImpl.cpp index e8761975..19d06554 100644 --- a/src/core/search/FieldCacheImpl.cpp +++ b/src/core/search/FieldCacheImpl.cpp @@ -41,7 +41,7 @@ namespace Lucene initialize(); } - void FieldCacheImpl::purge(IndexReaderPtr r) + void FieldCacheImpl::purge(const IndexReaderPtr& r) { for (MapStringCache::iterator cache = caches.begin(); cache != caches.end(); ++cache) cache->second->purge(r); @@ -67,57 +67,57 @@ namespace Lucene return result; } - Collection FieldCacheImpl::getBytes(IndexReaderPtr reader, const String& field) + Collection FieldCacheImpl::getBytes(const IndexReaderPtr& reader, const String& field) { return getBytes(reader, field, ByteParserPtr()); } - Collection FieldCacheImpl::getBytes(IndexReaderPtr reader, const String& field, ByteParserPtr parser) + Collection FieldCacheImpl::getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser) { return VariantUtils::get< Collection >(caches.get(CACHE_BYTE)->get(reader, newLucene(field, parser))); } - Collection FieldCacheImpl::getInts(IndexReaderPtr reader, const String& field) + Collection FieldCacheImpl::getInts(const IndexReaderPtr& reader, const String& field) { return getInts(reader, field, IntParserPtr()); } - Collection FieldCacheImpl::getInts(IndexReaderPtr reader, const String& field, IntParserPtr parser) + Collection FieldCacheImpl::getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser) { return VariantUtils::get< Collection >(caches.get(CACHE_INT)->get(reader, newLucene(field, parser))); } - Collection FieldCacheImpl::getLongs(IndexReaderPtr reader, const String& field) + Collection FieldCacheImpl::getLongs(const IndexReaderPtr& reader, const String& field) { return getLongs(reader, field, LongParserPtr()); } - Collection FieldCacheImpl::getLongs(IndexReaderPtr reader, const String& field, LongParserPtr parser) + Collection FieldCacheImpl::getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser) { return VariantUtils::get< Collection >(caches.get(CACHE_LONG)->get(reader, newLucene(field, parser))); } - Collection FieldCacheImpl::getDoubles(IndexReaderPtr reader, const String& field) + Collection FieldCacheImpl::getDoubles(const IndexReaderPtr& reader, const String& field) { return getDoubles(reader, field, DoubleParserPtr()); } - Collection FieldCacheImpl::getDoubles(IndexReaderPtr reader, const String& field, DoubleParserPtr parser) + Collection FieldCacheImpl::getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser) { return VariantUtils::get< Collection >(caches.get(CACHE_DOUBLE)->get(reader, newLucene(field, parser))); } - Collection FieldCacheImpl::getStrings(IndexReaderPtr reader, const String& field) + Collection FieldCacheImpl::getStrings(const IndexReaderPtr& reader, const String& field) { return VariantUtils::get< Collection >(caches.get(CACHE_STRING)->get(reader, newLucene(field, ParserPtr()))); } - StringIndexPtr FieldCacheImpl::getStringIndex(IndexReaderPtr reader, const String& field) + StringIndexPtr FieldCacheImpl::getStringIndex(const IndexReaderPtr& reader, const String& field) { return VariantUtils::get< StringIndexPtr >(caches.get(CACHE_STRING_INDEX)->get(reader, newLucene(field, ParserPtr()))); } - void FieldCacheImpl::setInfoStream(InfoStreamPtr stream) + void FieldCacheImpl::setInfoStream(const InfoStreamPtr& stream) { infoStream = stream; } @@ -137,7 +137,7 @@ namespace Lucene { } - bool Entry::equals(LuceneObjectPtr other) + bool Entry::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -156,7 +156,7 @@ namespace Lucene return StringUtils::hashCode(field) ^ VariantUtils::hashCode(custom); } - Cache::Cache(FieldCachePtr wrapper) + Cache::Cache(const FieldCachePtr& wrapper) { this->_wrapper = wrapper; this->readerCache = WeakMapLuceneObjectMapEntryAny::newInstance(); @@ -166,14 +166,14 @@ namespace Lucene { } - void Cache::purge(IndexReaderPtr r) + void Cache::purge(const IndexReaderPtr& r) { LuceneObjectPtr readerKey(r->getFieldCacheKey()); SyncLock cacheLock(&readerCache); readerCache.remove(readerKey); } - boost::any Cache::get(IndexReaderPtr reader, EntryPtr key) + boost::any Cache::get(const IndexReaderPtr& reader, const EntryPtr& key) { MapEntryAny innerCache; boost::any value; @@ -222,7 +222,7 @@ namespace Lucene return value; } - void Cache::printNewInsanity(InfoStreamPtr infoStream, boost::any value) + void Cache::printNewInsanity(const InfoStreamPtr& infoStream, boost::any value) { Collection insanities(FieldCacheSanityChecker::checkSanity(FieldCachePtr(_wrapper))); for (Collection::iterator insanity = insanities.begin(); insanity != insanities.end(); ++insanity) @@ -240,7 +240,7 @@ namespace Lucene } } - ByteCache::ByteCache(FieldCachePtr wrapper) : Cache(wrapper) + ByteCache::ByteCache(const FieldCachePtr& wrapper) : Cache(wrapper) { } @@ -248,7 +248,7 @@ namespace Lucene { } - boost::any ByteCache::createValue(IndexReaderPtr reader, EntryPtr key) + boost::any ByteCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { EntryPtr entry(key); String field(entry->field); @@ -286,7 +286,7 @@ namespace Lucene return retArray; } - IntCache::IntCache(FieldCachePtr wrapper) : Cache(wrapper) + IntCache::IntCache(const FieldCachePtr& wrapper) : Cache(wrapper) { } @@ -294,7 +294,7 @@ namespace Lucene { } - boost::any IntCache::createValue(IndexReaderPtr reader, EntryPtr key) + boost::any IntCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { EntryPtr entry(key); String field(entry->field); @@ -348,7 +348,7 @@ namespace Lucene return retArray; } - LongCache::LongCache(FieldCachePtr wrapper) : Cache(wrapper) + LongCache::LongCache(const FieldCachePtr& wrapper) : Cache(wrapper) { } @@ -356,7 +356,7 @@ namespace Lucene { } - boost::any LongCache::createValue(IndexReaderPtr reader, EntryPtr key) + boost::any LongCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { EntryPtr entry(key); String field(entry->field); @@ -410,7 +410,7 @@ namespace Lucene return retArray; } - DoubleCache::DoubleCache(FieldCachePtr wrapper) : Cache(wrapper) + DoubleCache::DoubleCache(const FieldCachePtr& wrapper) : Cache(wrapper) { } @@ -418,7 +418,7 @@ namespace Lucene { } - boost::any DoubleCache::createValue(IndexReaderPtr reader, EntryPtr key) + boost::any DoubleCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { EntryPtr entry(key); String field(entry->field); @@ -472,7 +472,7 @@ namespace Lucene return retArray; } - StringCache::StringCache(FieldCachePtr wrapper) : Cache(wrapper) + StringCache::StringCache(const FieldCachePtr& wrapper) : Cache(wrapper) { } @@ -480,7 +480,7 @@ namespace Lucene { } - boost::any StringCache::createValue(IndexReaderPtr reader, EntryPtr key) + boost::any StringCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { EntryPtr entry(key); String field(entry->field); @@ -512,7 +512,7 @@ namespace Lucene return retArray; } - StringIndexCache::StringIndexCache(FieldCachePtr wrapper) : Cache(wrapper) + StringIndexCache::StringIndexCache(const FieldCachePtr& wrapper) : Cache(wrapper) { } @@ -520,7 +520,7 @@ namespace Lucene { } - boost::any StringIndexCache::createValue(IndexReaderPtr reader, EntryPtr key) + boost::any StringIndexCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { EntryPtr entry(key); String field(entry->field); @@ -577,7 +577,7 @@ namespace Lucene return newLucene(retArray, mterms); } - FieldCacheEntryImpl::FieldCacheEntryImpl(LuceneObjectPtr readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value) + FieldCacheEntryImpl::FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value) { this->readerKey = readerKey; this->fieldName = fieldName; diff --git a/src/core/search/FieldCacheRangeFilter.cpp b/src/core/search/FieldCacheRangeFilter.cpp index b5f6da76..7b318c17 100644 --- a/src/core/search/FieldCacheRangeFilter.cpp +++ b/src/core/search/FieldCacheRangeFilter.cpp @@ -16,7 +16,7 @@ namespace Lucene { - FieldCacheRangeFilter::FieldCacheRangeFilter(const String& field, ParserPtr parser, bool includeLower, bool includeUpper) + FieldCacheRangeFilter::FieldCacheRangeFilter(const String& field, const ParserPtr& parser, bool includeLower, bool includeUpper) { this->field = field; this->parser = parser; @@ -38,7 +38,7 @@ namespace Lucene return newByteRange(field, ByteParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, ByteParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, const ByteParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } @@ -48,7 +48,7 @@ namespace Lucene return newIntRange(field, IntParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, IntParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, const IntParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } @@ -58,7 +58,7 @@ namespace Lucene return newLongRange(field, LongParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, LongParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, const LongParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } @@ -68,7 +68,7 @@ namespace Lucene return newDoubleRange(field, DoubleParserPtr(), lowerVal, upperVal, includeLower, includeUpper); } - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, DoubleParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, const DoubleParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) { return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); } @@ -93,7 +93,7 @@ namespace Lucene return parser; } - FieldCacheRangeFilterString::FieldCacheRangeFilterString(const String& field, ParserPtr parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterString::FieldCacheRangeFilterString(const String& field, const ParserPtr& parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) { this->lowerVal = lowerVal; @@ -104,7 +104,7 @@ namespace Lucene { } - DocIdSetPtr FieldCacheRangeFilterString::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr FieldCacheRangeFilterString::getDocIdSet(const IndexReaderPtr& reader) { StringIndexPtr fcsi(FieldCache::DEFAULT()->getStringIndex(reader, field)); int32_t lowerPoint = fcsi->binarySearchLookup(lowerVal); @@ -159,7 +159,7 @@ namespace Lucene return buffer.str(); } - bool FieldCacheRangeFilterString::equals(LuceneObjectPtr other) + bool FieldCacheRangeFilterString::equals(const LuceneObjectPtr& other) { if (Filter::equals(other)) return true; @@ -186,7 +186,7 @@ namespace Lucene return code; } - FieldCacheRangeFilterByte::FieldCacheRangeFilterByte(const String& field, ParserPtr parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterByte::FieldCacheRangeFilterByte(const String& field, const ParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, UCHAR_MAX, includeLower, includeUpper) { } @@ -195,12 +195,12 @@ namespace Lucene { } - Collection FieldCacheRangeFilterByte::getValues(IndexReaderPtr reader) + Collection FieldCacheRangeFilterByte::getValues(const IndexReaderPtr& reader) { return FieldCache::DEFAULT()->getBytes(reader, field, boost::static_pointer_cast(parser)); } - FieldCacheRangeFilterInt::FieldCacheRangeFilterInt(const String& field, ParserPtr parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterInt::FieldCacheRangeFilterInt(const String& field, const ParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, INT_MAX, includeLower, includeUpper) { } @@ -209,12 +209,12 @@ namespace Lucene { } - Collection FieldCacheRangeFilterInt::getValues(IndexReaderPtr reader) + Collection FieldCacheRangeFilterInt::getValues(const IndexReaderPtr& reader) { return FieldCache::DEFAULT()->getInts(reader, field, boost::static_pointer_cast(parser)); } - FieldCacheRangeFilterLong::FieldCacheRangeFilterLong(const String& field, ParserPtr parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterLong::FieldCacheRangeFilterLong(const String& field, const ParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::max(), includeLower, includeUpper) { } @@ -223,12 +223,12 @@ namespace Lucene { } - Collection FieldCacheRangeFilterLong::getValues(IndexReaderPtr reader) + Collection FieldCacheRangeFilterLong::getValues(const IndexReaderPtr& reader) { return FieldCache::DEFAULT()->getLongs(reader, field, boost::static_pointer_cast(parser)); } - FieldCacheRangeFilterDouble::FieldCacheRangeFilterDouble(const String& field, ParserPtr parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) + FieldCacheRangeFilterDouble::FieldCacheRangeFilterDouble(const String& field, const ParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::infinity(), includeLower, includeUpper) { } @@ -237,7 +237,7 @@ namespace Lucene { } - DocIdSetPtr FieldCacheRangeFilterDouble::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr FieldCacheRangeFilterDouble::getDocIdSet(const IndexReaderPtr& reader) { if (!includeLower && lowerVal > 0.0 && MiscUtils::isInfinite(lowerVal)) return DocIdSet::EMPTY_DOCIDSET(); @@ -256,12 +256,12 @@ namespace Lucene return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); } - Collection FieldCacheRangeFilterDouble::getValues(IndexReaderPtr reader) + Collection FieldCacheRangeFilterDouble::getValues(const IndexReaderPtr& reader) { return FieldCache::DEFAULT()->getDoubles(reader, field, boost::static_pointer_cast(parser)); } - FieldCacheDocIdSet::FieldCacheDocIdSet(IndexReaderPtr reader, bool mayUseTermDocs) + FieldCacheDocIdSet::FieldCacheDocIdSet(const IndexReaderPtr& reader, bool mayUseTermDocs) { this->reader = reader; this->mayUseTermDocs = mayUseTermDocs; @@ -299,7 +299,7 @@ namespace Lucene } } - FieldCacheDocIdSetString::FieldCacheDocIdSetString(IndexReaderPtr reader, bool mayUseTermDocs, StringIndexPtr fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) + FieldCacheDocIdSetString::FieldCacheDocIdSetString(const IndexReaderPtr& reader, bool mayUseTermDocs, const StringIndexPtr& fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) { this->fcsi = fcsi; this->inclusiveLowerPoint = inclusiveLowerPoint; @@ -317,7 +317,7 @@ namespace Lucene return (fcsi->order[doc] >= inclusiveLowerPoint && fcsi->order[doc] <= inclusiveUpperPoint); } - FieldDocIdSetIteratorTermDocs::FieldDocIdSetIteratorTermDocs(FieldCacheDocIdSetPtr cacheDocIdSet, TermDocsPtr termDocs) + FieldDocIdSetIteratorTermDocs::FieldDocIdSetIteratorTermDocs(const FieldCacheDocIdSetPtr& cacheDocIdSet, const TermDocsPtr& termDocs) { this->_cacheDocIdSet = cacheDocIdSet; this->termDocs = termDocs; @@ -367,7 +367,7 @@ namespace Lucene return doc; } - FieldDocIdSetIteratorIncrement::FieldDocIdSetIteratorIncrement(FieldCacheDocIdSetPtr cacheDocIdSet) + FieldDocIdSetIteratorIncrement::FieldDocIdSetIteratorIncrement(const FieldCacheDocIdSetPtr& cacheDocIdSet) { this->_cacheDocIdSet = cacheDocIdSet; this->doc = -1; diff --git a/src/core/search/FieldCacheTermsFilter.cpp b/src/core/search/FieldCacheTermsFilter.cpp index e1bcac33..38229077 100644 --- a/src/core/search/FieldCacheTermsFilter.cpp +++ b/src/core/search/FieldCacheTermsFilter.cpp @@ -27,12 +27,12 @@ namespace Lucene return FieldCache::DEFAULT(); } - DocIdSetPtr FieldCacheTermsFilter::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr FieldCacheTermsFilter::getDocIdSet(const IndexReaderPtr& reader) { return newLucene(terms, getFieldCache()->getStringIndex(reader, field)); } - FieldCacheTermsFilterDocIdSet::FieldCacheTermsFilterDocIdSet(Collection terms, StringIndexPtr fcsi) + FieldCacheTermsFilterDocIdSet::FieldCacheTermsFilterDocIdSet(Collection terms, const StringIndexPtr& fcsi) { this->fcsi = fcsi; openBitSet = newLucene(this->fcsi->lookup.size()); @@ -58,7 +58,7 @@ namespace Lucene return true; } - FieldCacheTermsFilterDocIdSetIterator::FieldCacheTermsFilterDocIdSetIterator(StringIndexPtr fcsi, OpenBitSetPtr openBitSet) + FieldCacheTermsFilterDocIdSetIterator::FieldCacheTermsFilterDocIdSetIterator(const StringIndexPtr& fcsi, const OpenBitSetPtr& openBitSet) { this->fcsi = fcsi; this->openBitSet = openBitSet; diff --git a/src/core/search/FieldComparator.cpp b/src/core/search/FieldComparator.cpp index c3864319..070042ef 100644 --- a/src/core/search/FieldComparator.cpp +++ b/src/core/search/FieldComparator.cpp @@ -16,13 +16,13 @@ namespace Lucene { } - void FieldComparator::setScorer(ScorerPtr scorer) + void FieldComparator::setScorer(const ScorerPtr& scorer) { // Empty implementation since most comparators don't need the score. // This can be overridden by those that need it. } - ByteComparator::ByteComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) + ByteComparator::ByteComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } @@ -31,7 +31,7 @@ namespace Lucene { } - void ByteComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void ByteComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getBytes(reader, field, parser); } @@ -56,12 +56,12 @@ namespace Lucene values[slot] = docBase + doc; } - void DocComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void DocComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } - DoubleComparator::DoubleComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) + DoubleComparator::DoubleComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } @@ -83,12 +83,12 @@ namespace Lucene return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); } - void DoubleComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void DoubleComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getDoubles(reader, field, parser); } - IntComparator::IntComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) + IntComparator::IntComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } @@ -110,12 +110,12 @@ namespace Lucene return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); } - void IntComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void IntComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getInts(reader, field, parser); } - LongComparator::LongComparator(int32_t numHits, const String& field, ParserPtr parser) : NumericComparator(numHits, field) + LongComparator::LongComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { this->parser = boost::static_pointer_cast(parser); } @@ -137,7 +137,7 @@ namespace Lucene return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); } - void LongComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void LongComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getLongs(reader, field, parser); } @@ -168,11 +168,11 @@ namespace Lucene values[slot] = scorer->score(); } - void RelevanceComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void RelevanceComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { } - void RelevanceComparator::setScorer(ScorerPtr scorer) + void RelevanceComparator::setScorer(const ScorerPtr& scorer) { this->scorer = newLucene(scorer); } @@ -202,7 +202,7 @@ namespace Lucene values[slot] = currentReaderValues[doc]; } - void StringComparatorLocale::setNextReader(IndexReaderPtr reader, int32_t docBase) + void StringComparatorLocale::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); } @@ -303,7 +303,7 @@ namespace Lucene readerGen[slot] = currentReaderGen; } - void StringOrdValComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void StringOrdValComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { StringIndexPtr currentReaderValues(FieldCache::DEFAULT()->getStringIndex(reader, field)); ++currentReaderGen; @@ -373,7 +373,7 @@ namespace Lucene values[slot] = currentReaderValues[doc]; } - void StringValComparator::setNextReader(IndexReaderPtr reader, int32_t docBase) + void StringValComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); } diff --git a/src/core/search/FieldValueHitQueue.cpp b/src/core/search/FieldValueHitQueue.cpp index 80830b2f..ee23a280 100644 --- a/src/core/search/FieldValueHitQueue.cpp +++ b/src/core/search/FieldValueHitQueue.cpp @@ -50,7 +50,7 @@ namespace Lucene return reverseMul; } - FieldDocPtr FieldValueHitQueue::fillFields(FieldValueHitQueueEntryPtr entry) + FieldDocPtr FieldValueHitQueue::fillFields(const FieldValueHitQueueEntryPtr& entry) { int32_t n = comparators.size(); Collection fields(Collection::newInstance(n)); diff --git a/src/core/search/FilterManager.cpp b/src/core/search/FilterManager.cpp index 34178420..04e95526 100644 --- a/src/core/search/FilterManager.cpp +++ b/src/core/search/FilterManager.cpp @@ -57,7 +57,7 @@ namespace Lucene this->cleanSleepTime = cleanSleepTime; } - FilterPtr FilterManager::getFilter(FilterPtr filter) + FilterPtr FilterManager::getFilter(const FilterPtr& filter) { SyncLock parentLock(&cache); FilterItemPtr fi(cache.get(filter->hashCode())); @@ -70,7 +70,7 @@ namespace Lucene return filter; } - FilterItem::FilterItem(FilterPtr filter) + FilterItem::FilterItem(const FilterPtr& filter) { this->filter = filter; this->timestamp = MiscUtils::currentTimeMillis(); @@ -80,7 +80,7 @@ namespace Lucene { } - FilterCleaner::FilterCleaner(FilterManagerPtr manager) + FilterCleaner::FilterCleaner(const FilterManagerPtr& manager) { _manager = manager; running = true; diff --git a/src/core/search/FilteredDocIdSet.cpp b/src/core/search/FilteredDocIdSet.cpp index fc92f753..a3a9d930 100644 --- a/src/core/search/FilteredDocIdSet.cpp +++ b/src/core/search/FilteredDocIdSet.cpp @@ -10,7 +10,7 @@ namespace Lucene { - FilteredDocIdSet::FilteredDocIdSet(DocIdSetPtr innerSet) + FilteredDocIdSet::FilteredDocIdSet(const DocIdSetPtr& innerSet) { this->innerSet = innerSet; } @@ -29,7 +29,7 @@ namespace Lucene return newLucene(shared_from_this(), innerSet->iterator()); } - DefaultFilteredDocIdSetIterator::DefaultFilteredDocIdSetIterator(FilteredDocIdSetPtr filtered, DocIdSetIteratorPtr innerIter) : FilteredDocIdSetIterator(innerIter) + DefaultFilteredDocIdSetIterator::DefaultFilteredDocIdSetIterator(const FilteredDocIdSetPtr& filtered, const DocIdSetIteratorPtr& innerIter) : FilteredDocIdSetIterator(innerIter) { this->filtered = filtered; } diff --git a/src/core/search/FilteredDocIdSetIterator.cpp b/src/core/search/FilteredDocIdSetIterator.cpp index 9f13a574..f4c6921b 100644 --- a/src/core/search/FilteredDocIdSetIterator.cpp +++ b/src/core/search/FilteredDocIdSetIterator.cpp @@ -9,7 +9,7 @@ namespace Lucene { - FilteredDocIdSetIterator::FilteredDocIdSetIterator(DocIdSetIteratorPtr innerIter) + FilteredDocIdSetIterator::FilteredDocIdSetIterator(const DocIdSetIteratorPtr& innerIter) { if (!innerIter) boost::throw_exception(IllegalArgumentException(L"null iterator")); diff --git a/src/core/search/FilteredQuery.cpp b/src/core/search/FilteredQuery.cpp index 764586ec..cca924bd 100644 --- a/src/core/search/FilteredQuery.cpp +++ b/src/core/search/FilteredQuery.cpp @@ -14,7 +14,7 @@ namespace Lucene { - FilteredQuery::FilteredQuery(QueryPtr query, FilterPtr filter) + FilteredQuery::FilteredQuery(const QueryPtr& query, const FilterPtr& filter) { this->query = query; this->filter = filter; @@ -24,14 +24,14 @@ namespace Lucene { } - WeightPtr FilteredQuery::createWeight(SearcherPtr searcher) + WeightPtr FilteredQuery::createWeight(const SearcherPtr& searcher) { WeightPtr weight(query->createWeight(searcher)); SimilarityPtr similarity(query->getSimilarity(searcher)); return newLucene(shared_from_this(), weight, similarity); } - QueryPtr FilteredQuery::rewrite(IndexReaderPtr reader) + QueryPtr FilteredQuery::rewrite(const IndexReaderPtr& reader) { QueryPtr rewritten(query->rewrite(reader)); if (rewritten != query) @@ -66,7 +66,7 @@ namespace Lucene return buffer.str(); } - bool FilteredQuery::equals(LuceneObjectPtr other) + bool FilteredQuery::equals(const LuceneObjectPtr& other) { FilteredQueryPtr otherFilteredQuery(boost::dynamic_pointer_cast(other)); if (!otherFilteredQuery) @@ -79,7 +79,7 @@ namespace Lucene return query->hashCode() ^ filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); } - LuceneObjectPtr FilteredQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr FilteredQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(query, filter); FilteredQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); @@ -88,7 +88,7 @@ namespace Lucene return cloneQuery; } - FilteredQueryWeight::FilteredQueryWeight(FilteredQueryPtr query, WeightPtr weight, SimilarityPtr similarity) + FilteredQueryWeight::FilteredQueryWeight(const FilteredQueryPtr& query, const WeightPtr& weight, const SimilarityPtr& similarity) { this->query = query; this->weight = weight; @@ -116,7 +116,7 @@ namespace Lucene value = weight->getValue() * query->getBoost(); } - ExplanationPtr FilteredQueryWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr FilteredQueryWeight::explain(const IndexReaderPtr& reader, int32_t doc) { ExplanationPtr inner(weight->explain(reader, doc)); if (query->getBoost() !=1) @@ -146,7 +146,7 @@ namespace Lucene return query; } - ScorerPtr FilteredQueryWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr FilteredQueryWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { ScorerPtr scorer(weight->scorer(reader, true, false)); if (!scorer) @@ -160,7 +160,7 @@ namespace Lucene return newLucene(shared_from_this(), scorer, docIdSetIterator, similarity); } - FilteredQueryWeightScorer::FilteredQueryWeightScorer(FilteredQueryWeightPtr weight, ScorerPtr scorer, DocIdSetIteratorPtr docIdSetIterator, SimilarityPtr similarity) : Scorer(similarity) + FilteredQueryWeightScorer::FilteredQueryWeightScorer(const FilteredQueryWeightPtr& weight, const ScorerPtr& scorer, const DocIdSetIteratorPtr& docIdSetIterator, const SimilarityPtr& similarity) : Scorer(similarity) { this->weight = weight; this->scorer = scorer; diff --git a/src/core/search/FilteredTermEnum.cpp b/src/core/search/FilteredTermEnum.cpp index 2ce9335b..fb0d28c6 100644 --- a/src/core/search/FilteredTermEnum.cpp +++ b/src/core/search/FilteredTermEnum.cpp @@ -13,7 +13,7 @@ namespace Lucene { } - void FilteredTermEnum::setEnum(TermEnumPtr actualEnum) + void FilteredTermEnum::setEnum(const TermEnumPtr& actualEnum) { this->actualEnum = actualEnum; // Find the first term that matches diff --git a/src/core/search/FuzzyQuery.cpp b/src/core/search/FuzzyQuery.cpp index be8a818b..f39417d0 100644 --- a/src/core/search/FuzzyQuery.cpp +++ b/src/core/search/FuzzyQuery.cpp @@ -18,17 +18,17 @@ namespace Lucene { const int32_t FuzzyQuery::defaultPrefixLength = 0; - FuzzyQuery::FuzzyQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength) + FuzzyQuery::FuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) { ConstructQuery(term, minimumSimilarity, prefixLength); } - FuzzyQuery::FuzzyQuery(TermPtr term, double minimumSimilarity) + FuzzyQuery::FuzzyQuery(const TermPtr& term, double minimumSimilarity) { ConstructQuery(term, minimumSimilarity, defaultPrefixLength); } - FuzzyQuery::FuzzyQuery(TermPtr term) + FuzzyQuery::FuzzyQuery(const TermPtr& term) { ConstructQuery(term, defaultMinSimilarity(), defaultPrefixLength); } @@ -37,7 +37,7 @@ namespace Lucene { } - void FuzzyQuery::ConstructQuery(TermPtr term, double minimumSimilarity, int32_t prefixLength) + void FuzzyQuery::ConstructQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) { this->term = term; @@ -71,7 +71,7 @@ namespace Lucene return prefixLength; } - FilteredTermEnumPtr FuzzyQuery::getEnum(IndexReaderPtr reader) + FilteredTermEnumPtr FuzzyQuery::getEnum(const IndexReaderPtr& reader) { return newLucene(reader, getTerm(), minimumSimilarity, prefixLength); } @@ -81,12 +81,12 @@ namespace Lucene return term; } - void FuzzyQuery::setRewriteMethod(RewriteMethodPtr method) + void FuzzyQuery::setRewriteMethod(const RewriteMethodPtr& method) { boost::throw_exception(UnsupportedOperationException(L"FuzzyQuery cannot change rewrite method")); } - QueryPtr FuzzyQuery::rewrite(IndexReaderPtr reader) + QueryPtr FuzzyQuery::rewrite(const IndexReaderPtr& reader) { if (!termLongEnough) // can only match if it's exact return newLucene(term); @@ -136,7 +136,7 @@ namespace Lucene return query; } - LuceneObjectPtr FuzzyQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr FuzzyQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); FuzzyQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -166,7 +166,7 @@ namespace Lucene return result; } - bool FuzzyQuery::equals(LuceneObjectPtr other) + bool FuzzyQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -195,7 +195,7 @@ namespace Lucene { } - int32_t ScoreTerm::compareTo(ScoreTermPtr other) + int32_t ScoreTerm::compareTo(const ScoreTermPtr& other) { if (this->score == other->score) return other->term->compareTo(this->term); diff --git a/src/core/search/FuzzyTermEnum.cpp b/src/core/search/FuzzyTermEnum.cpp index 80266dc9..ead9e7fd 100644 --- a/src/core/search/FuzzyTermEnum.cpp +++ b/src/core/search/FuzzyTermEnum.cpp @@ -13,17 +13,17 @@ namespace Lucene { - FuzzyTermEnum::FuzzyTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity, int32_t prefixLength) + FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength) { ConstructTermEnum(reader, term, minSimilarity, prefixLength); } - FuzzyTermEnum::FuzzyTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity) + FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity) { ConstructTermEnum(reader, term, minSimilarity, FuzzyQuery::defaultPrefixLength); } - FuzzyTermEnum::FuzzyTermEnum(IndexReaderPtr reader, TermPtr term) + FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term) { ConstructTermEnum(reader, term, FuzzyQuery::defaultMinSimilarity(), FuzzyQuery::defaultPrefixLength); } @@ -32,7 +32,7 @@ namespace Lucene { } - void FuzzyTermEnum::ConstructTermEnum(IndexReaderPtr reader, TermPtr term, double minSimilarity, int32_t prefixLength) + void FuzzyTermEnum::ConstructTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength) { if (minSimilarity >= 1.0) boost::throw_exception(IllegalArgumentException(L"minimumSimilarity cannot be greater than or equal to 1")); @@ -62,7 +62,7 @@ namespace Lucene setEnum(reader->terms(newLucene(searchTerm->field(), prefix))); } - bool FuzzyTermEnum::termCompare(TermPtr term) + bool FuzzyTermEnum::termCompare(const TermPtr& term) { if (field == term->field() && boost::starts_with(term->text(), prefix)) { diff --git a/src/core/search/HitQueueBase.cpp b/src/core/search/HitQueueBase.cpp index f37f3b9f..351aa1f0 100644 --- a/src/core/search/HitQueueBase.cpp +++ b/src/core/search/HitQueueBase.cpp @@ -24,12 +24,12 @@ namespace Lucene queue = newLucene(shared_from_this(), queueSize); } - ScoreDocPtr HitQueueBase::add(ScoreDocPtr scoreDoc) + ScoreDocPtr HitQueueBase::add(const ScoreDocPtr& scoreDoc) { return queue->add(scoreDoc); } - ScoreDocPtr HitQueueBase::addOverflow(ScoreDocPtr scoreDoc) + ScoreDocPtr HitQueueBase::addOverflow(const ScoreDocPtr& scoreDoc) { return queue->addOverflow(scoreDoc); } @@ -69,7 +69,7 @@ namespace Lucene return ScoreDocPtr(); } - PriorityQueueScoreDocs::PriorityQueueScoreDocs(HitQueueBasePtr hitQueue, int32_t size) : PriorityQueue(size) + PriorityQueueScoreDocs::PriorityQueueScoreDocs(const HitQueueBasePtr& hitQueue, int32_t size) : PriorityQueue(size) { _hitQueue = hitQueue; } diff --git a/src/core/search/IndexSearcher.cpp b/src/core/search/IndexSearcher.cpp index 7f85749e..f2d32f18 100644 --- a/src/core/search/IndexSearcher.cpp +++ b/src/core/search/IndexSearcher.cpp @@ -19,17 +19,17 @@ namespace Lucene { - IndexSearcher::IndexSearcher(DirectoryPtr path, bool readOnly) + IndexSearcher::IndexSearcher(const DirectoryPtr& path, bool readOnly) { ConstructSearcher(IndexReader::open(path, readOnly), true); } - IndexSearcher::IndexSearcher(IndexReaderPtr reader) + IndexSearcher::IndexSearcher(const IndexReaderPtr& reader) { ConstructSearcher(reader, false); } - IndexSearcher::IndexSearcher(IndexReaderPtr reader, Collection subReaders, Collection docStarts) + IndexSearcher::IndexSearcher(const IndexReaderPtr& reader, Collection subReaders, Collection docStarts) { this->fieldSortDoTrackScores = false; this->fieldSortDoMaxScore = false; @@ -43,7 +43,7 @@ namespace Lucene { } - void IndexSearcher::ConstructSearcher(IndexReaderPtr reader, bool closeReader) + void IndexSearcher::ConstructSearcher(const IndexReaderPtr& reader, bool closeReader) { this->fieldSortDoTrackScores = false; this->fieldSortDoMaxScore = false; @@ -62,7 +62,7 @@ namespace Lucene } } - void IndexSearcher::gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader) + void IndexSearcher::gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader) { ReaderUtil::gatherSubReaders(allSubReaders, reader); } @@ -78,7 +78,7 @@ namespace Lucene reader->close(); } - int32_t IndexSearcher::docFreq(TermPtr term) + int32_t IndexSearcher::docFreq(const TermPtr& term) { return reader->docFreq(term); } @@ -88,7 +88,7 @@ namespace Lucene return reader->document(n); } - DocumentPtr IndexSearcher::doc(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr IndexSearcher::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { return reader->document(n, fieldSelector); } @@ -98,7 +98,7 @@ namespace Lucene return reader->maxDoc(); } - TopDocsPtr IndexSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n) + TopDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { if (n <= 0) boost::throw_exception(IllegalArgumentException(L"n must be > 0")); @@ -107,19 +107,19 @@ namespace Lucene return collector->topDocs(); } - TopFieldDocsPtr IndexSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) + TopFieldDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { return search(weight, filter, n, sort, true); } - TopFieldDocsPtr IndexSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort, bool fillFields) + TopFieldDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort, bool fillFields) { TopFieldCollectorPtr collector(TopFieldCollector::create(sort, std::min(n, reader->maxDoc()), fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight->scoresDocsOutOfOrder())); search(weight, filter, collector); return boost::dynamic_pointer_cast(collector->topDocs()); } - void IndexSearcher::search(WeightPtr weight, FilterPtr filter, CollectorPtr results) + void IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) { if (!filter) { @@ -141,7 +141,7 @@ namespace Lucene } } - void IndexSearcher::searchWithFilter(IndexReaderPtr reader, WeightPtr weight, FilterPtr filter, CollectorPtr collector) + void IndexSearcher::searchWithFilter(const IndexReaderPtr& reader, const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) { BOOST_ASSERT(filter); @@ -188,7 +188,7 @@ namespace Lucene } } - QueryPtr IndexSearcher::rewrite(QueryPtr original) + QueryPtr IndexSearcher::rewrite(const QueryPtr& original) { QueryPtr query(original); for (QueryPtr rewrittenQuery(query->rewrite(reader)); rewrittenQuery != query; rewrittenQuery = query->rewrite(reader)) @@ -196,7 +196,7 @@ namespace Lucene return query; } - ExplanationPtr IndexSearcher::explain(WeightPtr weight, int32_t doc) + ExplanationPtr IndexSearcher::explain(const WeightPtr& weight, int32_t doc) { int32_t n = ReaderUtil::subIndex(doc, docStarts); int32_t deBasedDoc = doc - docStarts[n]; diff --git a/src/core/search/MatchAllDocsQuery.cpp b/src/core/search/MatchAllDocsQuery.cpp index b5395e5e..3233ad8f 100644 --- a/src/core/search/MatchAllDocsQuery.cpp +++ b/src/core/search/MatchAllDocsQuery.cpp @@ -25,7 +25,7 @@ namespace Lucene { } - WeightPtr MatchAllDocsQuery::createWeight(SearcherPtr searcher) + WeightPtr MatchAllDocsQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } @@ -41,7 +41,7 @@ namespace Lucene return buffer.str(); } - bool MatchAllDocsQuery::equals(LuceneObjectPtr other) + bool MatchAllDocsQuery::equals(const LuceneObjectPtr& other) { return Query::equals(other); } @@ -51,7 +51,7 @@ namespace Lucene return MiscUtils::doubleToIntBits(getBoost()) ^ 0x1aa71190; } - LuceneObjectPtr MatchAllDocsQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr MatchAllDocsQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); MatchAllDocsQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); @@ -59,7 +59,7 @@ namespace Lucene return cloneQuery; } - MatchAllDocsWeight::MatchAllDocsWeight(MatchAllDocsQueryPtr query, SearcherPtr searcher) + MatchAllDocsWeight::MatchAllDocsWeight(const MatchAllDocsQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = searcher->getSimilarity(); @@ -100,12 +100,12 @@ namespace Lucene queryWeight *= this->queryNorm; } - ScorerPtr MatchAllDocsWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr MatchAllDocsWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(query, reader, similarity, shared_from_this(), !query->normsField.empty() ? reader->norms(query->normsField) : ByteArray()); } - ExplanationPtr MatchAllDocsWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr MatchAllDocsWeight::explain(const IndexReaderPtr& reader, int32_t doc) { // explain query weight ExplanationPtr queryExpl(newLucene(true, getValue(), L"MatchAllDocsQuery, product of:")); @@ -115,7 +115,7 @@ namespace Lucene return queryExpl; } - MatchAllScorer::MatchAllScorer(MatchAllDocsQueryPtr query, IndexReaderPtr reader, SimilarityPtr similarity, WeightPtr weight, ByteArray norms) : Scorer(similarity) + MatchAllScorer::MatchAllScorer(const MatchAllDocsQueryPtr& query, const IndexReaderPtr& reader, const SimilarityPtr& similarity, const WeightPtr& weight, ByteArray norms) : Scorer(similarity) { this->query = query; this->termDocs = reader->termDocs(TermPtr()); diff --git a/src/core/search/MultiPhraseQuery.cpp b/src/core/search/MultiPhraseQuery.cpp index 928901a2..04c938ff 100644 --- a/src/core/search/MultiPhraseQuery.cpp +++ b/src/core/search/MultiPhraseQuery.cpp @@ -43,7 +43,7 @@ namespace Lucene return slop; } - void MultiPhraseQuery::add(TermPtr term) + void MultiPhraseQuery::add(const TermPtr& term) { add(newCollection(term)); } @@ -88,7 +88,7 @@ namespace Lucene } } - QueryPtr MultiPhraseQuery::rewrite(IndexReaderPtr reader) + QueryPtr MultiPhraseQuery::rewrite(const IndexReaderPtr& reader) { if (termArrays.size() == 1) // optimize one-term case { @@ -103,7 +103,7 @@ namespace Lucene return shared_from_this(); } - WeightPtr MultiPhraseQuery::createWeight(SearcherPtr searcher) + WeightPtr MultiPhraseQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } @@ -142,7 +142,7 @@ namespace Lucene return buffer.str(); } - bool MultiPhraseQuery::equals(LuceneObjectPtr other) + bool MultiPhraseQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -184,7 +184,7 @@ namespace Lucene return first.equals(second, equalTermArrays()); } - LuceneObjectPtr MultiPhraseQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr MultiPhraseQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); MultiPhraseQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); @@ -195,7 +195,7 @@ namespace Lucene return cloneQuery; } - MultiPhraseWeight::MultiPhraseWeight(MultiPhraseQueryPtr query, SearcherPtr searcher) + MultiPhraseWeight::MultiPhraseWeight(const MultiPhraseQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = query->getSimilarity(searcher); @@ -240,7 +240,7 @@ namespace Lucene value = queryWeight * idf; // idf for document } - ScorerPtr MultiPhraseWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr MultiPhraseWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { if (query->termArrays.empty()) // optimize zero-term case return ScorerPtr(); @@ -268,7 +268,7 @@ namespace Lucene return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); } - ExplanationPtr MultiPhraseWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr MultiPhraseWeight::explain(const IndexReaderPtr& reader, int32_t doc) { ComplexExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); diff --git a/src/core/search/MultiSearcher.cpp b/src/core/search/MultiSearcher.cpp index 8c761007..4825c51a 100644 --- a/src/core/search/MultiSearcher.cpp +++ b/src/core/search/MultiSearcher.cpp @@ -56,7 +56,7 @@ namespace Lucene (*searchable)->close(); } - int32_t MultiSearcher::docFreq(TermPtr term) + int32_t MultiSearcher::docFreq(const TermPtr& term) { int32_t docFreq = 0; for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) @@ -70,7 +70,7 @@ namespace Lucene return searchables[i]->doc(n - starts[i]); // dispatch to searcher } - DocumentPtr MultiSearcher::doc(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr MultiSearcher::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { int32_t i = subSearcher(n); // find searcher index return searchables[i]->doc(n - starts[i], fieldSelector); // dispatch to searcher @@ -91,7 +91,7 @@ namespace Lucene return _maxDoc; } - TopDocsPtr MultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n) + TopDocsPtr MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { HitQueuePtr hq(newLucene(n, false)); int32_t totalHits = 0; @@ -111,7 +111,7 @@ namespace Lucene return newLucene(totalHits, scoreDocs, maxScore); } - TopFieldDocsPtr MultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) + TopFieldDocsPtr MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { FieldDocSortedHitQueuePtr hq(newLucene(n)); int32_t totalHits = 0; @@ -132,7 +132,7 @@ namespace Lucene return newLucene(totalHits, scoreDocs, hq->getFields(), maxScore); } - void MultiSearcher::search(WeightPtr weight, FilterPtr filter, CollectorPtr results) + void MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) { for (int32_t i = 0; i < searchables.size(); ++i) { @@ -142,7 +142,7 @@ namespace Lucene } } - QueryPtr MultiSearcher::rewrite(QueryPtr query) + QueryPtr MultiSearcher::rewrite(const QueryPtr& query) { Collection queries(Collection::newInstance(searchables.size())); for (int32_t i = 0; i < searchables.size(); ++i) @@ -150,13 +150,13 @@ namespace Lucene return queries[0]->combine(queries); } - ExplanationPtr MultiSearcher::explain(WeightPtr weight, int32_t doc) + ExplanationPtr MultiSearcher::explain(const WeightPtr& weight, int32_t doc) { int32_t i = subSearcher(doc); // find searcher index return searchables[i]->explain(weight, doc - starts[i]); // dispatch to searcher } - WeightPtr MultiSearcher::createWeight(QueryPtr query) + WeightPtr MultiSearcher::createWeight(const QueryPtr& query) { // step 1 QueryPtr rewrittenQuery(rewrite(query)); @@ -186,7 +186,7 @@ namespace Lucene return rewrittenQuery->weight(cacheSim); } - CachedDfSource::CachedDfSource(MapTermInt dfMap, int32_t maxDoc, SimilarityPtr similarity) + CachedDfSource::CachedDfSource(MapTermInt dfMap, int32_t maxDoc, const SimilarityPtr& similarity) { this->dfMap = dfMap; this->_maxDoc = maxDoc; @@ -197,7 +197,7 @@ namespace Lucene { } - int32_t CachedDfSource::docFreq(TermPtr term) + int32_t CachedDfSource::docFreq(const TermPtr& term) { MapTermInt::iterator df = dfMap.find(term); if (df == dfMap.end()) @@ -218,7 +218,7 @@ namespace Lucene return _maxDoc; } - QueryPtr CachedDfSource::rewrite(QueryPtr query) + QueryPtr CachedDfSource::rewrite(const QueryPtr& query) { // This is a bit of a hack. We know that a query which creates a Weight based on this Dummy-Searcher is // always already rewritten (see preparedWeight()). Therefore we just return the unmodified query here. @@ -236,37 +236,37 @@ namespace Lucene return DocumentPtr(); } - DocumentPtr CachedDfSource::doc(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr CachedDfSource::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { boost::throw_exception(UnsupportedOperationException()); return DocumentPtr(); } - ExplanationPtr CachedDfSource::explain(WeightPtr weight, int32_t doc) + ExplanationPtr CachedDfSource::explain(const WeightPtr& weight, int32_t doc) { boost::throw_exception(UnsupportedOperationException()); return ExplanationPtr(); } - void CachedDfSource::search(WeightPtr weight, FilterPtr filter, CollectorPtr results) + void CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) { boost::throw_exception(UnsupportedOperationException()); } - TopDocsPtr CachedDfSource::search(WeightPtr weight, FilterPtr filter, int32_t n) + TopDocsPtr CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { boost::throw_exception(UnsupportedOperationException()); return TopDocsPtr(); } - TopFieldDocsPtr CachedDfSource::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) + TopFieldDocsPtr CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { boost::throw_exception(UnsupportedOperationException()); return TopFieldDocsPtr(); } - MultiSearcherCallableNoSort::MultiSearcherCallableNoSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, - FilterPtr filter, int32_t nDocs, HitQueuePtr hq, int32_t i, + MultiSearcherCallableNoSort::MultiSearcherCallableNoSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, + const FilterPtr& filter, int32_t nDocs, const HitQueuePtr& hq, int32_t i, Collection starts) { this->lock = lock; @@ -299,9 +299,9 @@ namespace Lucene return docs; } - MultiSearcherCallableWithSort::MultiSearcherCallableWithSort(SynchronizePtr lock, SearchablePtr searchable, WeightPtr weight, - FilterPtr filter, int32_t nDocs, FieldDocSortedHitQueuePtr hq, - SortPtr sort, int32_t i, Collection starts) + MultiSearcherCallableWithSort::MultiSearcherCallableWithSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, + const FilterPtr& filter, int32_t nDocs, const FieldDocSortedHitQueuePtr& hq, + const SortPtr& sort, int32_t i, Collection starts) { this->lock = lock; this->searchable = searchable; @@ -356,7 +356,7 @@ namespace Lucene return docs; } - MultiSearcherCollector::MultiSearcherCollector(CollectorPtr collector, int32_t start) + MultiSearcherCollector::MultiSearcherCollector(const CollectorPtr& collector, int32_t start) { this->collector = collector; this->start = start; @@ -366,7 +366,7 @@ namespace Lucene { } - void MultiSearcherCollector::setScorer(ScorerPtr scorer) + void MultiSearcherCollector::setScorer(const ScorerPtr& scorer) { collector->setScorer(scorer); } @@ -376,7 +376,7 @@ namespace Lucene collector->collect(doc); } - void MultiSearcherCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void MultiSearcherCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { collector->setNextReader(reader, start + docBase); } diff --git a/src/core/search/MultiTermQuery.cpp b/src/core/search/MultiTermQuery.cpp index ec85a26c..f821222e 100644 --- a/src/core/search/MultiTermQuery.cpp +++ b/src/core/search/MultiTermQuery.cpp @@ -89,7 +89,7 @@ namespace Lucene numberOfTerms += inc; } - QueryPtr MultiTermQuery::rewrite(IndexReaderPtr reader) + QueryPtr MultiTermQuery::rewrite(const IndexReaderPtr& reader) { return rewriteMethod->rewrite(reader, shared_from_this()); } @@ -99,12 +99,12 @@ namespace Lucene return rewriteMethod; } - void MultiTermQuery::setRewriteMethod(RewriteMethodPtr method) + void MultiTermQuery::setRewriteMethod(const RewriteMethodPtr& method) { rewriteMethod = method; } - LuceneObjectPtr MultiTermQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr MultiTermQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = Query::clone(other); MultiTermQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -123,7 +123,7 @@ namespace Lucene return result; } - bool MultiTermQuery::equals(LuceneObjectPtr other) + bool MultiTermQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -149,7 +149,7 @@ namespace Lucene { } - QueryPtr ConstantScoreFilterRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) + QueryPtr ConstantScoreFilterRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { QueryPtr result(newLucene(newLucene(query))); result->setBoost(query->getBoost()); @@ -160,7 +160,7 @@ namespace Lucene { } - QueryPtr ScoringBooleanQueryRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) + QueryPtr ScoringBooleanQueryRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { FilteredTermEnumPtr enumerator(query->getEnum(reader)); BooleanQueryPtr result(newLucene(true)); @@ -195,7 +195,7 @@ namespace Lucene { } - QueryPtr ConstantScoreBooleanQueryRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) + QueryPtr ConstantScoreBooleanQueryRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { // strip the scores off QueryPtr result(newLucene(newLucene(ScoringBooleanQueryRewrite::rewrite(reader, query)))); @@ -240,7 +240,7 @@ namespace Lucene return docCountPercent; } - QueryPtr ConstantScoreAutoRewrite::rewrite(IndexReaderPtr reader, MultiTermQueryPtr query) + QueryPtr ConstantScoreAutoRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { // Get the enum and start visiting terms. If we exhaust the enum before hitting either of the // cutoffs, we use ConstantBooleanQueryRewrite; else ConstantFilterRewrite @@ -305,7 +305,7 @@ namespace Lucene return (int32_t)(prime * termCountCutoff + MiscUtils::doubleToLongBits(docCountPercent)); } - bool ConstantScoreAutoRewrite::equals(LuceneObjectPtr other) + bool ConstantScoreAutoRewrite::equals(const LuceneObjectPtr& other) { if (RewriteMethod::equals(other)) return true; diff --git a/src/core/search/MultiTermQueryWrapperFilter.cpp b/src/core/search/MultiTermQueryWrapperFilter.cpp index 72f11733..f23747a4 100644 --- a/src/core/search/MultiTermQueryWrapperFilter.cpp +++ b/src/core/search/MultiTermQueryWrapperFilter.cpp @@ -18,7 +18,7 @@ namespace Lucene { - MultiTermQueryWrapperFilter::MultiTermQueryWrapperFilter(MultiTermQueryPtr query) + MultiTermQueryWrapperFilter::MultiTermQueryWrapperFilter(const MultiTermQueryPtr& query) { this->query = query; } @@ -33,7 +33,7 @@ namespace Lucene return query->toString(); } - bool MultiTermQueryWrapperFilter::equals(LuceneObjectPtr other) + bool MultiTermQueryWrapperFilter::equals(const LuceneObjectPtr& other) { if (Filter::equals(other)) return true; @@ -62,7 +62,7 @@ namespace Lucene query->clearTotalNumberOfTerms(); } - DocIdSetPtr MultiTermQueryWrapperFilter::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr MultiTermQueryWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) { TermEnumPtr enumerator(query->getEnum(reader)); OpenBitSetPtr bitSet; diff --git a/src/core/search/NumericRangeFilter.cpp b/src/core/search/NumericRangeFilter.cpp index 267ebd31..b00333ca 100644 --- a/src/core/search/NumericRangeFilter.cpp +++ b/src/core/search/NumericRangeFilter.cpp @@ -10,7 +10,7 @@ namespace Lucene { - NumericRangeFilter::NumericRangeFilter(NumericRangeQueryPtr query) : MultiTermQueryWrapperFilter(query) + NumericRangeFilter::NumericRangeFilter(const NumericRangeQueryPtr& query) : MultiTermQueryWrapperFilter(query) { } diff --git a/src/core/search/NumericRangeQuery.cpp b/src/core/search/NumericRangeQuery.cpp index 35bae0c9..ac55d27f 100644 --- a/src/core/search/NumericRangeQuery.cpp +++ b/src/core/search/NumericRangeQuery.cpp @@ -96,7 +96,7 @@ namespace Lucene return newNumericRange(field, NumericUtils::PRECISION_STEP_DEFAULT, min, max, minInclusive, maxInclusive); } - FilteredTermEnumPtr NumericRangeQuery::getEnum(IndexReaderPtr reader) + FilteredTermEnumPtr NumericRangeQuery::getEnum(const IndexReaderPtr& reader) { return newLucene(shared_from_this(), reader); } @@ -126,7 +126,7 @@ namespace Lucene return min; } - LuceneObjectPtr NumericRangeQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr NumericRangeQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, precisionStep, valSize, min, max, minInclusive, maxInclusive)); NumericRangeQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -160,7 +160,7 @@ namespace Lucene return buffer.str(); } - bool NumericRangeQuery::equals(LuceneObjectPtr other) + bool NumericRangeQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -190,7 +190,7 @@ namespace Lucene return hash + (MiscUtils::hashCode(minInclusive) ^ 0x14fa55fb) + (MiscUtils::hashCode(maxInclusive) ^ 0x733fa5fe); } - NumericRangeTermEnum::NumericRangeTermEnum(NumericRangeQueryPtr query, IndexReaderPtr reader) + NumericRangeTermEnum::NumericRangeTermEnum(const NumericRangeQueryPtr& query, const IndexReaderPtr& reader) { this->_query = query; this->reader = reader; @@ -285,12 +285,12 @@ namespace Lucene return false; } - void NumericRangeTermEnum::setEnum(TermEnumPtr actualEnum) + void NumericRangeTermEnum::setEnum(const TermEnumPtr& actualEnum) { boost::throw_exception(UnsupportedOperationException(L"not implemented")); } - bool NumericRangeTermEnum::termCompare(TermPtr term) + bool NumericRangeTermEnum::termCompare(const TermPtr& term) { return (term->field() == NumericRangeQueryPtr(_query)->field && term->text().compare(currentUpperBound) <= 0); } diff --git a/src/core/search/ParallelMultiSearcher.cpp b/src/core/search/ParallelMultiSearcher.cpp index 61f5d85e..c22e3231 100644 --- a/src/core/search/ParallelMultiSearcher.cpp +++ b/src/core/search/ParallelMultiSearcher.cpp @@ -25,7 +25,7 @@ namespace Lucene { } - int32_t ParallelMultiSearcher::docFreq(TermPtr term) + int32_t ParallelMultiSearcher::docFreq(const TermPtr& term) { ThreadPoolPtr threadPool(ThreadPool::getInstance()); Collection searchThreads(Collection::newInstance(searchables.size())); @@ -37,7 +37,7 @@ namespace Lucene return docFreq; } - TopDocsPtr ParallelMultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n) + TopDocsPtr ParallelMultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { HitQueuePtr hq(newLucene(n, false)); SynchronizePtr lock(newInstance()); @@ -67,7 +67,7 @@ namespace Lucene return newLucene(totalHits, scoreDocs, maxScore); } - TopFieldDocsPtr ParallelMultiSearcher::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) + TopFieldDocsPtr ParallelMultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { if (!sort) boost::throw_exception(NullPointerException(L"sort must not be null")); diff --git a/src/core/search/PhrasePositions.cpp b/src/core/search/PhrasePositions.cpp index 56e72a35..c0eeb66f 100644 --- a/src/core/search/PhrasePositions.cpp +++ b/src/core/search/PhrasePositions.cpp @@ -10,7 +10,7 @@ namespace Lucene { - PhrasePositions::PhrasePositions(TermPositionsPtr t, int32_t o) + PhrasePositions::PhrasePositions(const TermPositionsPtr& t, int32_t o) { doc = 0; position = 0; diff --git a/src/core/search/PhraseQuery.cpp b/src/core/search/PhraseQuery.cpp index 9f163010..bad96735 100644 --- a/src/core/search/PhraseQuery.cpp +++ b/src/core/search/PhraseQuery.cpp @@ -42,7 +42,7 @@ namespace Lucene return slop; } - void PhraseQuery::add(TermPtr term) + void PhraseQuery::add(const TermPtr& term) { int32_t position = 0; if (!positions.empty()) @@ -50,7 +50,7 @@ namespace Lucene add(term, position); } - void PhraseQuery::add(TermPtr term, int32_t position) + void PhraseQuery::add(const TermPtr& term, int32_t position) { if (terms.empty()) field = term->field(); @@ -73,7 +73,7 @@ namespace Lucene return positions; } - WeightPtr PhraseQuery::createWeight(SearcherPtr searcher) + WeightPtr PhraseQuery::createWeight(const SearcherPtr& searcher) { if (terms.size() == 1) // optimize one-term case { @@ -122,7 +122,7 @@ namespace Lucene return buffer.str(); } - bool PhraseQuery::equals(LuceneObjectPtr other) + bool PhraseQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -142,7 +142,7 @@ namespace Lucene MiscUtils::hashCode(positions.begin(), positions.end(), MiscUtils::hashNumeric); } - LuceneObjectPtr PhraseQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr PhraseQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); PhraseQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); @@ -154,7 +154,7 @@ namespace Lucene return cloneQuery; } - PhraseWeight::PhraseWeight(PhraseQueryPtr query, SearcherPtr searcher) + PhraseWeight::PhraseWeight(const PhraseQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = query->getSimilarity(searcher); @@ -199,7 +199,7 @@ namespace Lucene value = queryWeight * idf; // idf for document } - ScorerPtr PhraseWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr PhraseWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { if (query->terms.empty()) // optimize zero-term case return ScorerPtr(); @@ -219,7 +219,7 @@ namespace Lucene return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); } - ExplanationPtr PhraseWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr PhraseWeight::explain(const IndexReaderPtr& reader, int32_t doc) { ExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); diff --git a/src/core/search/PhraseScorer.cpp b/src/core/search/PhraseScorer.cpp index afbc8638..750e9182 100644 --- a/src/core/search/PhraseScorer.cpp +++ b/src/core/search/PhraseScorer.cpp @@ -13,7 +13,7 @@ namespace Lucene { - PhraseScorer::PhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, ByteArray norms) : Scorer(similarity) + PhraseScorer::PhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) { this->firstTime = true; this->more = true; diff --git a/src/core/search/PositiveScoresOnlyCollector.cpp b/src/core/search/PositiveScoresOnlyCollector.cpp index d96a6d65..cfbaca4d 100644 --- a/src/core/search/PositiveScoresOnlyCollector.cpp +++ b/src/core/search/PositiveScoresOnlyCollector.cpp @@ -10,7 +10,7 @@ namespace Lucene { - PositiveScoresOnlyCollector::PositiveScoresOnlyCollector(CollectorPtr collector) + PositiveScoresOnlyCollector::PositiveScoresOnlyCollector(const CollectorPtr& collector) { this->collector = collector; } @@ -25,12 +25,12 @@ namespace Lucene collector->collect(doc); } - void PositiveScoresOnlyCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void PositiveScoresOnlyCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { collector->setNextReader(reader, docBase); } - void PositiveScoresOnlyCollector::setScorer(ScorerPtr scorer) + void PositiveScoresOnlyCollector::setScorer(const ScorerPtr& scorer) { // Set a ScoreCachingWrappingScorer in case the wrapped Collector will call score() also. this->scorer = newLucene(scorer); diff --git a/src/core/search/PrefixFilter.cpp b/src/core/search/PrefixFilter.cpp index 435f9fda..dff66b4b 100644 --- a/src/core/search/PrefixFilter.cpp +++ b/src/core/search/PrefixFilter.cpp @@ -11,7 +11,7 @@ namespace Lucene { - PrefixFilter::PrefixFilter(TermPtr prefix) : MultiTermQueryWrapperFilter(newLucene(prefix)) + PrefixFilter::PrefixFilter(const TermPtr& prefix) : MultiTermQueryWrapperFilter(newLucene(prefix)) { } diff --git a/src/core/search/PrefixQuery.cpp b/src/core/search/PrefixQuery.cpp index ef33a648..a4dad417 100644 --- a/src/core/search/PrefixQuery.cpp +++ b/src/core/search/PrefixQuery.cpp @@ -12,7 +12,7 @@ namespace Lucene { - PrefixQuery::PrefixQuery(TermPtr prefix) + PrefixQuery::PrefixQuery(const TermPtr& prefix) { this->prefix = prefix; } @@ -26,7 +26,7 @@ namespace Lucene return prefix; } - FilteredTermEnumPtr PrefixQuery::getEnum(IndexReaderPtr reader) + FilteredTermEnumPtr PrefixQuery::getEnum(const IndexReaderPtr& reader) { return newLucene(reader, prefix); } @@ -40,7 +40,7 @@ namespace Lucene return buffer.str(); } - LuceneObjectPtr PrefixQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr PrefixQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(prefix)); PrefixQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -56,7 +56,7 @@ namespace Lucene return result; } - bool PrefixQuery::equals(LuceneObjectPtr other) + bool PrefixQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/PrefixTermEnum.cpp b/src/core/search/PrefixTermEnum.cpp index ff4e00d9..9665ea05 100644 --- a/src/core/search/PrefixTermEnum.cpp +++ b/src/core/search/PrefixTermEnum.cpp @@ -12,7 +12,7 @@ namespace Lucene { - PrefixTermEnum::PrefixTermEnum(IndexReaderPtr reader, TermPtr prefix) + PrefixTermEnum::PrefixTermEnum(const IndexReaderPtr& reader, const TermPtr& prefix) { this->_endEnum = false; this->prefix = prefix; @@ -39,7 +39,7 @@ namespace Lucene return prefix; } - bool PrefixTermEnum::termCompare(TermPtr term) + bool PrefixTermEnum::termCompare(const TermPtr& term) { if (term->field() == prefix->field() && boost::starts_with(term->text(), prefix->text())) return true; diff --git a/src/core/search/Query.cpp b/src/core/search/Query.cpp index 5e52d533..04fb7ea1 100644 --- a/src/core/search/Query.cpp +++ b/src/core/search/Query.cpp @@ -42,13 +42,13 @@ namespace Lucene return toString(L""); } - WeightPtr Query::createWeight(SearcherPtr searcher) + WeightPtr Query::createWeight(const SearcherPtr& searcher) { boost::throw_exception(UnsupportedOperationException()); return WeightPtr(); } - WeightPtr Query::weight(SearcherPtr searcher) + WeightPtr Query::weight(const SearcherPtr& searcher) { QueryPtr query(searcher->rewrite(shared_from_this())); WeightPtr weight(query->createWeight(searcher)); @@ -60,7 +60,7 @@ namespace Lucene return weight; } - QueryPtr Query::rewrite(IndexReaderPtr reader) + QueryPtr Query::rewrite(const IndexReaderPtr& reader) { return shared_from_this(); } @@ -120,12 +120,12 @@ namespace Lucene return result; } - SimilarityPtr Query::getSimilarity(SearcherPtr searcher) + SimilarityPtr Query::getSimilarity(const SearcherPtr& searcher) { return searcher->getSimilarity(); } - LuceneObjectPtr Query::clone(LuceneObjectPtr other) + LuceneObjectPtr Query::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); QueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -141,7 +141,7 @@ namespace Lucene return result; } - bool Query::equals(LuceneObjectPtr other) + bool Query::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/QueryTermVector.cpp b/src/core/search/QueryTermVector.cpp index e81d06da..fb69f59c 100644 --- a/src/core/search/QueryTermVector.cpp +++ b/src/core/search/QueryTermVector.cpp @@ -20,7 +20,7 @@ namespace Lucene processTerms(queryTerms); } - QueryTermVector::QueryTermVector(const String& queryString, AnalyzerPtr analyzer) + QueryTermVector::QueryTermVector(const String& queryString, const AnalyzerPtr& analyzer) { terms = Collection::newInstance(); termFreqs = Collection::newInstance(); diff --git a/src/core/search/QueryWrapperFilter.cpp b/src/core/search/QueryWrapperFilter.cpp index a14e3e49..9ed68565 100644 --- a/src/core/search/QueryWrapperFilter.cpp +++ b/src/core/search/QueryWrapperFilter.cpp @@ -14,7 +14,7 @@ namespace Lucene { - QueryWrapperFilter::QueryWrapperFilter(QueryPtr query) + QueryWrapperFilter::QueryWrapperFilter(const QueryPtr& query) { this->query = query; } @@ -23,7 +23,7 @@ namespace Lucene { } - DocIdSetPtr QueryWrapperFilter::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr QueryWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) { WeightPtr weight(query->weight(newLucene(reader))); return newLucene(reader, weight); @@ -34,7 +34,7 @@ namespace Lucene return L"QueryWrapperFilter(" + query->toString() + L")"; } - bool QueryWrapperFilter::equals(LuceneObjectPtr other) + bool QueryWrapperFilter::equals(const LuceneObjectPtr& other) { QueryWrapperFilterPtr otherQueryWrapperFilter(boost::dynamic_pointer_cast(other)); if (!otherQueryWrapperFilter) @@ -47,7 +47,7 @@ namespace Lucene return query->hashCode() ^ 0x923F64B9; } - QueryWrapperFilterDocIdSet::QueryWrapperFilterDocIdSet(IndexReaderPtr reader, WeightPtr weight) + QueryWrapperFilterDocIdSet::QueryWrapperFilterDocIdSet(const IndexReaderPtr& reader, const WeightPtr& weight) { this->reader = reader; this->weight = weight; diff --git a/src/core/search/ReqExclScorer.cpp b/src/core/search/ReqExclScorer.cpp index ab9f9fde..48696f91 100644 --- a/src/core/search/ReqExclScorer.cpp +++ b/src/core/search/ReqExclScorer.cpp @@ -9,7 +9,7 @@ namespace Lucene { - ReqExclScorer::ReqExclScorer(ScorerPtr reqScorer, DocIdSetIteratorPtr exclDisi) : Scorer(SimilarityPtr()) // No similarity used. + ReqExclScorer::ReqExclScorer(const ScorerPtr& reqScorer, const DocIdSetIteratorPtr& exclDisi) : Scorer(SimilarityPtr()) // No similarity used. { this->reqScorer = reqScorer; this->exclDisi = exclDisi; diff --git a/src/core/search/ReqOptSumScorer.cpp b/src/core/search/ReqOptSumScorer.cpp index 5da69480..b51b1bca 100644 --- a/src/core/search/ReqOptSumScorer.cpp +++ b/src/core/search/ReqOptSumScorer.cpp @@ -9,7 +9,7 @@ namespace Lucene { - ReqOptSumScorer::ReqOptSumScorer(ScorerPtr reqScorer, ScorerPtr optScorer) : Scorer(SimilarityPtr()) // No similarity used. + ReqOptSumScorer::ReqOptSumScorer(const ScorerPtr& reqScorer, const ScorerPtr& optScorer) : Scorer(SimilarityPtr()) // No similarity used. { this->reqScorer = reqScorer; this->optScorer = optScorer; diff --git a/src/core/search/ScoreCachingWrappingScorer.cpp b/src/core/search/ScoreCachingWrappingScorer.cpp index d12ebe73..34b726c5 100644 --- a/src/core/search/ScoreCachingWrappingScorer.cpp +++ b/src/core/search/ScoreCachingWrappingScorer.cpp @@ -9,7 +9,7 @@ namespace Lucene { - ScoreCachingWrappingScorer::ScoreCachingWrappingScorer(ScorerPtr scorer) : Scorer(scorer->getSimilarity()) + ScoreCachingWrappingScorer::ScoreCachingWrappingScorer(const ScorerPtr& scorer) : Scorer(scorer->getSimilarity()) { this->curDoc = -1; this->curScore = 0.0; @@ -20,7 +20,7 @@ namespace Lucene { } - bool ScoreCachingWrappingScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) + bool ScoreCachingWrappingScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { return ScorerPtr(_scorer)->score(collector, max, firstDocID); } @@ -52,7 +52,7 @@ namespace Lucene return ScorerPtr(_scorer)->nextDoc(); } - void ScoreCachingWrappingScorer::score(CollectorPtr collector) + void ScoreCachingWrappingScorer::score(const CollectorPtr& collector) { ScorerPtr(_scorer)->score(collector); } diff --git a/src/core/search/Scorer.cpp b/src/core/search/Scorer.cpp index 0a5ee752..b2780a8e 100644 --- a/src/core/search/Scorer.cpp +++ b/src/core/search/Scorer.cpp @@ -10,7 +10,7 @@ namespace Lucene { - Scorer::Scorer(SimilarityPtr similarity) + Scorer::Scorer(const SimilarityPtr& similarity) { this->similarity = similarity; } @@ -24,7 +24,7 @@ namespace Lucene return similarity; } - void Scorer::score(CollectorPtr collector) + void Scorer::score(const CollectorPtr& collector) { collector->setScorer(shared_from_this()); int32_t doc; @@ -32,7 +32,7 @@ namespace Lucene collector->collect(doc); } - bool Scorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) + bool Scorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { collector->setScorer(shared_from_this()); int32_t doc = firstDocID; diff --git a/src/core/search/Searchable.cpp b/src/core/search/Searchable.cpp index 331621e2..f6fffc0e 100644 --- a/src/core/search/Searchable.cpp +++ b/src/core/search/Searchable.cpp @@ -9,7 +9,7 @@ namespace Lucene { - void Searchable::search(WeightPtr weight, FilterPtr filter, CollectorPtr collector) + void Searchable::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) { BOOST_ASSERT(false); // override @@ -21,7 +21,7 @@ namespace Lucene // override } - int32_t Searchable::docFreq(TermPtr term) + int32_t Searchable::docFreq(const TermPtr& term) { BOOST_ASSERT(false); return 0; // override @@ -39,7 +39,7 @@ namespace Lucene return 0; // override } - TopDocsPtr Searchable::search(WeightPtr weight, FilterPtr filter, int32_t n) + TopDocsPtr Searchable::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { BOOST_ASSERT(false); return TopDocsPtr(); // override @@ -51,25 +51,25 @@ namespace Lucene return DocumentPtr(); // override } - DocumentPtr Searchable::doc(int32_t n, FieldSelectorPtr fieldSelector) + DocumentPtr Searchable::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { BOOST_ASSERT(false); return DocumentPtr(); // override } - QueryPtr Searchable::rewrite(QueryPtr query) + QueryPtr Searchable::rewrite(const QueryPtr& query) { BOOST_ASSERT(false); return QueryPtr(); // override } - ExplanationPtr Searchable::explain(WeightPtr weight, int32_t doc) + ExplanationPtr Searchable::explain(const WeightPtr& weight, int32_t doc) { BOOST_ASSERT(false); return ExplanationPtr(); // override } - TopFieldDocsPtr Searchable::search(WeightPtr weight, FilterPtr filter, int32_t n, SortPtr sort) + TopFieldDocsPtr Searchable::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { BOOST_ASSERT(false); return TopFieldDocsPtr(); // override diff --git a/src/core/search/Searcher.cpp b/src/core/search/Searcher.cpp index c5fc4996..3d84b806 100644 --- a/src/core/search/Searcher.cpp +++ b/src/core/search/Searcher.cpp @@ -21,37 +21,37 @@ namespace Lucene { } - TopFieldDocsPtr Searcher::search(QueryPtr query, FilterPtr filter, int32_t n, SortPtr sort) + TopFieldDocsPtr Searcher::search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort) { return search(createWeight(query), filter, n, sort); } - void Searcher::search(QueryPtr query, CollectorPtr results) + void Searcher::search(const QueryPtr& query, const CollectorPtr& results) { search(createWeight(query), FilterPtr(), results); } - void Searcher::search(QueryPtr query, FilterPtr filter, CollectorPtr results) + void Searcher::search(const QueryPtr& query, const FilterPtr& filter, const CollectorPtr& results) { search(createWeight(query), filter, results); } - TopDocsPtr Searcher::search(QueryPtr query, FilterPtr filter, int32_t n) + TopDocsPtr Searcher::search(const QueryPtr& query, const FilterPtr& filter, int32_t n) { return search(createWeight(query), filter, n); } - TopDocsPtr Searcher::search(QueryPtr query, int32_t n) + TopDocsPtr Searcher::search(const QueryPtr& query, int32_t n) { return search(query, FilterPtr(), n); } - ExplanationPtr Searcher::explain(QueryPtr query, int32_t doc) + ExplanationPtr Searcher::explain(const QueryPtr& query, int32_t doc) { return explain(createWeight(query), doc); } - void Searcher::setSimilarity(SimilarityPtr similarity) + void Searcher::setSimilarity(const SimilarityPtr& similarity) { this->similarity = similarity; } @@ -61,7 +61,7 @@ namespace Lucene return this->similarity; } - WeightPtr Searcher::createWeight(QueryPtr query) + WeightPtr Searcher::createWeight(const QueryPtr& query) { return query->weight(shared_from_this()); } diff --git a/src/core/search/Similarity.cpp b/src/core/search/Similarity.cpp index 4e6f9909..96d1fde1 100644 --- a/src/core/search/Similarity.cpp +++ b/src/core/search/Similarity.cpp @@ -59,7 +59,7 @@ namespace Lucene return NORM_TABLE(); } - double Similarity::computeNorm(const String& fieldName, FieldInvertStatePtr state) + double Similarity::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) { return (double)(state->getBoost() * lengthNorm(fieldName, state->getLength())); } @@ -74,7 +74,7 @@ namespace Lucene return tf((double)freq); } - IDFExplanationPtr Similarity::idfExplain(TermPtr term, SearcherPtr searcher) + IDFExplanationPtr Similarity::idfExplain(const TermPtr& term, const SearcherPtr& searcher) { int32_t df = searcher->docFreq(term); int32_t max = searcher->maxDoc(); @@ -82,7 +82,7 @@ namespace Lucene return newLucene(df, max, _idf); } - IDFExplanationPtr Similarity::idfExplain(Collection terms, SearcherPtr searcher) + IDFExplanationPtr Similarity::idfExplain(Collection terms, const SearcherPtr& searcher) { int32_t max = searcher->maxDoc(); double _idf = 0.0; diff --git a/src/core/search/SimilarityDelegator.cpp b/src/core/search/SimilarityDelegator.cpp index 59f2e0a5..4ee52be2 100644 --- a/src/core/search/SimilarityDelegator.cpp +++ b/src/core/search/SimilarityDelegator.cpp @@ -9,7 +9,7 @@ namespace Lucene { - SimilarityDelegator::SimilarityDelegator(SimilarityPtr delegee) + SimilarityDelegator::SimilarityDelegator(const SimilarityPtr& delegee) { this->delegee = delegee; } @@ -18,7 +18,7 @@ namespace Lucene { } - double SimilarityDelegator::computeNorm(const String& fieldName, FieldInvertStatePtr state) + double SimilarityDelegator::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) { return delegee->computeNorm(fieldName, state); } diff --git a/src/core/search/SingleTermEnum.cpp b/src/core/search/SingleTermEnum.cpp index d4d5619b..20754260 100644 --- a/src/core/search/SingleTermEnum.cpp +++ b/src/core/search/SingleTermEnum.cpp @@ -11,7 +11,7 @@ namespace Lucene { - SingleTermEnum::SingleTermEnum(IndexReaderPtr reader, TermPtr singleTerm) + SingleTermEnum::SingleTermEnum(const IndexReaderPtr& reader, const TermPtr& singleTerm) { this->_endEnum = false; this->singleTerm = singleTerm; @@ -32,7 +32,7 @@ namespace Lucene return _endEnum; } - bool SingleTermEnum::termCompare(TermPtr term) + bool SingleTermEnum::termCompare(const TermPtr& term) { if (term->equals(singleTerm)) return true; diff --git a/src/core/search/SloppyPhraseScorer.cpp b/src/core/search/SloppyPhraseScorer.cpp index ba56a948..4435ab8f 100644 --- a/src/core/search/SloppyPhraseScorer.cpp +++ b/src/core/search/SloppyPhraseScorer.cpp @@ -12,7 +12,7 @@ namespace Lucene { - SloppyPhraseScorer::SloppyPhraseScorer(WeightPtr weight, Collection tps, Collection offsets, SimilarityPtr similarity, int32_t slop, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) + SloppyPhraseScorer::SloppyPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, int32_t slop, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) { this->slop = slop; this->checkedRepeats = false; @@ -63,7 +63,7 @@ namespace Lucene return freq; } - PhrasePositionsPtr SloppyPhraseScorer::flip(PhrasePositionsPtr pp, PhrasePositionsPtr pp2) + PhrasePositionsPtr SloppyPhraseScorer::flip(const PhrasePositionsPtr& pp, const PhrasePositionsPtr& pp2) { int32_t n = 0; PhrasePositionsPtr pp3; @@ -161,7 +161,7 @@ namespace Lucene return end; } - PhrasePositionsPtr SloppyPhraseScorer::termPositionsDiffer(PhrasePositionsPtr pp) + PhrasePositionsPtr SloppyPhraseScorer::termPositionsDiffer(const PhrasePositionsPtr& pp) { // Efficiency note: a more efficient implementation could keep a map between repeating pp's, so that if // pp1a, pp1b, pp1c are repeats term1, and pp2a, pp2b are repeats of term2, pp2a would only be checked diff --git a/src/core/search/Sort.cpp b/src/core/search/Sort.cpp index 11cfb7f0..0fe4dab3 100644 --- a/src/core/search/Sort.cpp +++ b/src/core/search/Sort.cpp @@ -16,7 +16,7 @@ namespace Lucene setSort(SortField::FIELD_SCORE()); } - Sort::Sort(SortFieldPtr field) + Sort::Sort(const SortFieldPtr& field) { setSort(field); } @@ -52,7 +52,7 @@ namespace Lucene return _INDEXORDER; } - void Sort::setSort(SortFieldPtr field) + void Sort::setSort(const SortFieldPtr& field) { this->fields = newCollection(field); } @@ -79,7 +79,7 @@ namespace Lucene return buffer.str(); } - bool Sort::equals(LuceneObjectPtr other) + bool Sort::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/SortField.cpp b/src/core/search/SortField.cpp index 47e7df1b..c20052e6 100644 --- a/src/core/search/SortField.cpp +++ b/src/core/search/SortField.cpp @@ -54,7 +54,7 @@ namespace Lucene this->reverse = reverse; } - SortField::SortField(const String& field, ParserPtr parser, bool reverse) + SortField::SortField(const String& field, const ParserPtr& parser, bool reverse) { if (boost::dynamic_pointer_cast(parser)) initFieldType(field, INT); @@ -77,7 +77,7 @@ namespace Lucene this->reverse = reverse; } - SortField::SortField(const String& field, FieldComparatorSourcePtr comparator, bool reverse) + SortField::SortField(const String& field, const FieldComparatorSourcePtr& comparator, bool reverse) { initFieldType(field, CUSTOM); this->comparatorSource = comparator; @@ -199,7 +199,7 @@ namespace Lucene return buffer.str(); } - bool SortField::equals(LuceneObjectPtr other) + bool SortField::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/SpanFilterResult.cpp b/src/core/search/SpanFilterResult.cpp index c101b0ee..253e7a5c 100644 --- a/src/core/search/SpanFilterResult.cpp +++ b/src/core/search/SpanFilterResult.cpp @@ -9,7 +9,7 @@ namespace Lucene { - SpanFilterResult::SpanFilterResult(DocIdSetPtr docIdSet, Collection positions) + SpanFilterResult::SpanFilterResult(const DocIdSetPtr& docIdSet, Collection positions) { this->docIdSet = docIdSet; this->positions = positions; diff --git a/src/core/search/SpanQueryFilter.cpp b/src/core/search/SpanQueryFilter.cpp index 374e7ace..392e00cb 100644 --- a/src/core/search/SpanQueryFilter.cpp +++ b/src/core/search/SpanQueryFilter.cpp @@ -14,7 +14,7 @@ namespace Lucene { - SpanQueryFilter::SpanQueryFilter(SpanQueryPtr query) + SpanQueryFilter::SpanQueryFilter(const SpanQueryPtr& query) { this->query = query; } @@ -23,13 +23,13 @@ namespace Lucene { } - DocIdSetPtr SpanQueryFilter::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr SpanQueryFilter::getDocIdSet(const IndexReaderPtr& reader) { SpanFilterResultPtr result(bitSpans(reader)); return result->getDocIdSet(); } - SpanFilterResultPtr SpanQueryFilter::bitSpans(IndexReaderPtr reader) + SpanFilterResultPtr SpanQueryFilter::bitSpans(const IndexReaderPtr& reader) { OpenBitSetPtr bits(newLucene(reader->maxDoc())); SpansPtr spans(query->getSpans(reader)); @@ -61,7 +61,7 @@ namespace Lucene return L"SpanQueryFilter(" + query->toString() + L")"; } - bool SpanQueryFilter::equals(LuceneObjectPtr other) + bool SpanQueryFilter::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/TermQuery.cpp b/src/core/search/TermQuery.cpp index bab0d0bc..ad6a022d 100644 --- a/src/core/search/TermQuery.cpp +++ b/src/core/search/TermQuery.cpp @@ -18,7 +18,7 @@ namespace Lucene { - TermQuery::TermQuery(TermPtr term) + TermQuery::TermQuery(const TermPtr& term) { this->term = term; } @@ -32,7 +32,7 @@ namespace Lucene return term; } - WeightPtr TermQuery::createWeight(SearcherPtr searcher) + WeightPtr TermQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } @@ -51,7 +51,7 @@ namespace Lucene return buffer.str(); } - bool TermQuery::equals(LuceneObjectPtr other) + bool TermQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -68,7 +68,7 @@ namespace Lucene return MiscUtils::doubleToIntBits(getBoost()) ^ term->hashCode(); } - LuceneObjectPtr TermQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr TermQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(term); TermQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); @@ -76,7 +76,7 @@ namespace Lucene return cloneQuery; } - TermWeight::TermWeight(TermQueryPtr query, SearcherPtr searcher) + TermWeight::TermWeight(const TermQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = query->getSimilarity(searcher); @@ -121,13 +121,13 @@ namespace Lucene value = queryWeight * idf; // idf for document } - ScorerPtr TermWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr TermWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { TermDocsPtr termDocs(reader->termDocs(query->term)); return termDocs ? newLucene(shared_from_this(), termDocs, similarity, reader->norms(query->term->field())) : ScorerPtr(); } - ExplanationPtr TermWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr TermWeight::explain(const IndexReaderPtr& reader, int32_t doc) { ComplexExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); diff --git a/src/core/search/TermRangeQuery.cpp b/src/core/search/TermRangeQuery.cpp index adba80a2..f262bd89 100644 --- a/src/core/search/TermRangeQuery.cpp +++ b/src/core/search/TermRangeQuery.cpp @@ -58,12 +58,12 @@ namespace Lucene return collator; } - FilteredTermEnumPtr TermRangeQuery::getEnum(IndexReaderPtr reader) + FilteredTermEnumPtr TermRangeQuery::getEnum(const IndexReaderPtr& reader) { return newLucene(reader, field, lowerTerm, upperTerm, includeLower, includeUpper, collator); } - LuceneObjectPtr TermRangeQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr TermRangeQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, lowerTerm, upperTerm, includeLower, includeUpper, collator)); TermRangeQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -96,7 +96,7 @@ namespace Lucene return buffer.str(); } - bool TermRangeQuery::equals(LuceneObjectPtr other) + bool TermRangeQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/TermRangeTermEnum.cpp b/src/core/search/TermRangeTermEnum.cpp index ec031082..465c30fd 100644 --- a/src/core/search/TermRangeTermEnum.cpp +++ b/src/core/search/TermRangeTermEnum.cpp @@ -14,8 +14,8 @@ namespace Lucene { - TermRangeTermEnum::TermRangeTermEnum(IndexReaderPtr reader, const String& field, StringValue lowerTermText, - StringValue upperTermText, bool includeLower, bool includeUpper, CollatorPtr collator) + TermRangeTermEnum::TermRangeTermEnum(const IndexReaderPtr& reader, const String& field, StringValue lowerTermText, + StringValue upperTermText, bool includeLower, bool includeUpper, const CollatorPtr& collator) { this->collator = collator; this->_endEnum = false; @@ -50,7 +50,7 @@ namespace Lucene return _endEnum; } - bool TermRangeTermEnum::termCompare(TermPtr term) + bool TermRangeTermEnum::termCompare(const TermPtr& term) { if (!collator) { diff --git a/src/core/search/TermScorer.cpp b/src/core/search/TermScorer.cpp index 0ae61c4f..03856e1a 100644 --- a/src/core/search/TermScorer.cpp +++ b/src/core/search/TermScorer.cpp @@ -15,7 +15,7 @@ namespace Lucene { const int32_t TermScorer::SCORE_CACHE_SIZE = 32; - TermScorer::TermScorer(WeightPtr weight, TermDocsPtr td, SimilarityPtr similarity, ByteArray norms) : Scorer(similarity) + TermScorer::TermScorer(const WeightPtr& weight, const TermDocsPtr& td, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) { this->weight = weight; this->termDocs = td; @@ -41,12 +41,12 @@ namespace Lucene return Similarity::getNormDecoder(); } - void TermScorer::score(CollectorPtr collector) + void TermScorer::score(const CollectorPtr& collector) { score(collector, INT_MAX, nextDoc()); } - bool TermScorer::score(CollectorPtr collector, int32_t max, int32_t firstDocID) + bool TermScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { // firstDocID is ignored since nextDoc() sets 'doc' collector->setScorer(shared_from_this()); diff --git a/src/core/search/TimeLimitingCollector.cpp b/src/core/search/TimeLimitingCollector.cpp index 7b2f968d..02259255 100644 --- a/src/core/search/TimeLimitingCollector.cpp +++ b/src/core/search/TimeLimitingCollector.cpp @@ -16,7 +16,7 @@ namespace Lucene int64_t TimeLimitingCollector::resolution = TimeLimitingCollector::DEFAULT_RESOLUTION; - TimeLimitingCollector::TimeLimitingCollector(CollectorPtr collector, int64_t timeAllowed) + TimeLimitingCollector::TimeLimitingCollector(const CollectorPtr& collector, int64_t timeAllowed) { this->DEFAULT_GREEDY = false; this->greedy = DEFAULT_GREEDY; @@ -86,13 +86,13 @@ namespace Lucene collector->collect(doc); } - void TimeLimitingCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void TimeLimitingCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { collector->setNextReader(reader, docBase); this->docBase = docBase; } - void TimeLimitingCollector::setScorer(ScorerPtr scorer) + void TimeLimitingCollector::setScorer(const ScorerPtr& scorer) { collector->setScorer(scorer); } diff --git a/src/core/search/TopDocsCollector.cpp b/src/core/search/TopDocsCollector.cpp index 2cda42bf..e519323a 100644 --- a/src/core/search/TopDocsCollector.cpp +++ b/src/core/search/TopDocsCollector.cpp @@ -11,7 +11,7 @@ namespace Lucene { - TopDocsCollector::TopDocsCollector(HitQueueBasePtr pq) + TopDocsCollector::TopDocsCollector(const HitQueueBasePtr& pq) { this->pq = pq; this->totalHits = 0; diff --git a/src/core/search/TopFieldCollector.cpp b/src/core/search/TopFieldCollector.cpp index 4a341704..a1b09330 100644 --- a/src/core/search/TopFieldCollector.cpp +++ b/src/core/search/TopFieldCollector.cpp @@ -16,7 +16,7 @@ namespace Lucene { - TopFieldCollector::TopFieldCollector(HitQueueBasePtr pq, int32_t numHits, bool fillFields) : TopDocsCollector(pq) + TopFieldCollector::TopFieldCollector(const HitQueueBasePtr& pq, int32_t numHits, bool fillFields) : TopDocsCollector(pq) { this->numHits = numHits; this->fillFields = fillFields; @@ -37,7 +37,7 @@ namespace Lucene return _EMPTY_SCOREDOCS; } - TopFieldCollectorPtr TopFieldCollector::create(SortPtr sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder) + TopFieldCollectorPtr TopFieldCollector::create(const SortPtr& sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder) { if (sort->fields.empty()) boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); @@ -128,7 +128,7 @@ namespace Lucene return false; } - OneComparatorNonScoringCollector::OneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) + OneComparatorNonScoringCollector::OneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) { } @@ -180,18 +180,18 @@ namespace Lucene } } - void OneComparatorNonScoringCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void OneComparatorNonScoringCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; comparator->setNextReader(reader, docBase); } - void OneComparatorNonScoringCollector::setScorer(ScorerPtr scorer) + void OneComparatorNonScoringCollector::setScorer(const ScorerPtr& scorer) { comparator->setScorer(scorer); } - OutOfOrderOneComparatorNonScoringCollector::OutOfOrderOneComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) + OutOfOrderOneComparatorNonScoringCollector::OutOfOrderOneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { } @@ -231,7 +231,7 @@ namespace Lucene return true; } - OneComparatorScoringNoMaxScoreCollector::OneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) + OneComparatorScoringNoMaxScoreCollector::OneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { } @@ -281,13 +281,13 @@ namespace Lucene } } - void OneComparatorScoringNoMaxScoreCollector::setScorer(ScorerPtr scorer) + void OneComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) { this->scorer = scorer; comparator->setScorer(scorer); } - OutOfOrderOneComparatorScoringNoMaxScoreCollector::OutOfOrderOneComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) + OutOfOrderOneComparatorScoringNoMaxScoreCollector::OutOfOrderOneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) { } @@ -333,7 +333,7 @@ namespace Lucene return true; } - OneComparatorScoringMaxScoreCollector::OneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) + OneComparatorScoringMaxScoreCollector::OneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. this->maxScore = -std::numeric_limits::infinity(); @@ -382,13 +382,13 @@ namespace Lucene } } - void OneComparatorScoringMaxScoreCollector::setScorer(ScorerPtr scorer) + void OneComparatorScoringMaxScoreCollector::setScorer(const ScorerPtr& scorer) { this->scorer = scorer; OneComparatorNonScoringCollector::setScorer(scorer); } - OutOfOrderOneComparatorScoringMaxScoreCollector::OutOfOrderOneComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : OneComparatorScoringMaxScoreCollector(queue, numHits, fillFields) + OutOfOrderOneComparatorScoringMaxScoreCollector::OutOfOrderOneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorScoringMaxScoreCollector(queue, numHits, fillFields) { } @@ -431,7 +431,7 @@ namespace Lucene return true; } - MultiComparatorNonScoringCollector::MultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) + MultiComparatorNonScoringCollector::MultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) { } @@ -507,21 +507,21 @@ namespace Lucene } } - void MultiComparatorNonScoringCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void MultiComparatorNonScoringCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setNextReader(reader, docBase); } - void MultiComparatorNonScoringCollector::setScorer(ScorerPtr scorer) + void MultiComparatorNonScoringCollector::setScorer(const ScorerPtr& scorer) { // set the scorer on all comparators for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) (*cmp)->setScorer(scorer); } - OutOfOrderMultiComparatorNonScoringCollector::OutOfOrderMultiComparatorNonScoringCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) + OutOfOrderMultiComparatorNonScoringCollector::OutOfOrderMultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { } @@ -590,7 +590,7 @@ namespace Lucene return true; } - MultiComparatorScoringMaxScoreCollector::MultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) + MultiComparatorScoringMaxScoreCollector::MultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. this->maxScore = -std::numeric_limits::infinity(); @@ -663,13 +663,13 @@ namespace Lucene } } - void MultiComparatorScoringMaxScoreCollector::setScorer(ScorerPtr scorer) + void MultiComparatorScoringMaxScoreCollector::setScorer(const ScorerPtr& scorer) { this->_scorer = scorer; MultiComparatorNonScoringCollector::setScorer(scorer); } - OutOfOrderMultiComparatorScoringMaxScoreCollector::OutOfOrderMultiComparatorScoringMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields) + OutOfOrderMultiComparatorScoringMaxScoreCollector::OutOfOrderMultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields) { } @@ -741,7 +741,7 @@ namespace Lucene return true; } - MultiComparatorScoringNoMaxScoreCollector::MultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) + MultiComparatorScoringNoMaxScoreCollector::MultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { } @@ -814,13 +814,13 @@ namespace Lucene } } - void MultiComparatorScoringNoMaxScoreCollector::setScorer(ScorerPtr scorer) + void MultiComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) { this->_scorer = scorer; MultiComparatorNonScoringCollector::setScorer(scorer); } - OutOfOrderMultiComparatorScoringNoMaxScoreCollector::OutOfOrderMultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueuePtr queue, int32_t numHits, bool fillFields) : MultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) + OutOfOrderMultiComparatorScoringNoMaxScoreCollector::OutOfOrderMultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) { } @@ -889,7 +889,7 @@ namespace Lucene } } - void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::setScorer(ScorerPtr scorer) + void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) { this->_scorer = scorer; MultiComparatorScoringNoMaxScoreCollector::setScorer(scorer); diff --git a/src/core/search/TopScoreDocCollector.cpp b/src/core/search/TopScoreDocCollector.cpp index a398c011..3a04f76f 100644 --- a/src/core/search/TopScoreDocCollector.cpp +++ b/src/core/search/TopScoreDocCollector.cpp @@ -56,12 +56,12 @@ namespace Lucene return newLucene(totalHits, results, maxScore); } - void TopScoreDocCollector::setNextReader(IndexReaderPtr reader, int32_t docBase) + void TopScoreDocCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } - void TopScoreDocCollector::setScorer(ScorerPtr scorer) + void TopScoreDocCollector::setScorer(const ScorerPtr& scorer) { this->_scorer = scorer; } diff --git a/src/core/search/WildcardQuery.cpp b/src/core/search/WildcardQuery.cpp index d2382c4f..5832b691 100644 --- a/src/core/search/WildcardQuery.cpp +++ b/src/core/search/WildcardQuery.cpp @@ -15,7 +15,7 @@ namespace Lucene { - WildcardQuery::WildcardQuery(TermPtr term) + WildcardQuery::WildcardQuery(const TermPtr& term) { this->term = term; String text(term->text()); @@ -29,7 +29,7 @@ namespace Lucene { } - FilteredTermEnumPtr WildcardQuery::getEnum(IndexReaderPtr reader) + FilteredTermEnumPtr WildcardQuery::getEnum(const IndexReaderPtr& reader) { if (termContainsWildcard) return newLucene(reader, getTerm()); @@ -42,7 +42,7 @@ namespace Lucene return term; } - QueryPtr WildcardQuery::rewrite(IndexReaderPtr reader) + QueryPtr WildcardQuery::rewrite(const IndexReaderPtr& reader) { if (termIsPrefix) { @@ -64,7 +64,7 @@ namespace Lucene return buffer.str(); } - LuceneObjectPtr WildcardQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr WildcardQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); WildcardQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -82,7 +82,7 @@ namespace Lucene return result; } - bool WildcardQuery::equals(LuceneObjectPtr other) + bool WildcardQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/WildcardTermEnum.cpp b/src/core/search/WildcardTermEnum.cpp index 237d9b6e..c34b5672 100644 --- a/src/core/search/WildcardTermEnum.cpp +++ b/src/core/search/WildcardTermEnum.cpp @@ -15,7 +15,7 @@ namespace Lucene const wchar_t WildcardTermEnum::WILDCARD_STRING = L'*'; const wchar_t WildcardTermEnum::WILDCARD_CHAR = L'?'; - WildcardTermEnum::WildcardTermEnum(IndexReaderPtr reader, TermPtr term) + WildcardTermEnum::WildcardTermEnum(const IndexReaderPtr& reader, const TermPtr& term) { _endEnum = false; searchTerm = term; @@ -40,7 +40,7 @@ namespace Lucene { } - bool WildcardTermEnum::termCompare(TermPtr term) + bool WildcardTermEnum::termCompare(const TermPtr& term) { if (field == term->field()) { diff --git a/src/core/search/function/ByteFieldSource.cpp b/src/core/search/function/ByteFieldSource.cpp index 2bd230c5..9c313488 100644 --- a/src/core/search/function/ByteFieldSource.cpp +++ b/src/core/search/function/ByteFieldSource.cpp @@ -13,7 +13,7 @@ namespace Lucene { - ByteFieldSource::ByteFieldSource(const String& field, ByteParserPtr parser) : FieldCacheSource(field) + ByteFieldSource::ByteFieldSource(const String& field, const ByteParserPtr& parser) : FieldCacheSource(field) { this->parser = parser; } @@ -27,13 +27,13 @@ namespace Lucene return L"byte(" + FieldCacheSource::description() + L")"; } - DocValuesPtr ByteFieldSource::getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) + DocValuesPtr ByteFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) { Collection arr(cache->getBytes(reader, field, parser)); return newLucene(shared_from_this(), arr); } - bool ByteFieldSource::cachedFieldSourceEquals(FieldCacheSourcePtr other) + bool ByteFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) return false; @@ -48,7 +48,7 @@ namespace Lucene return StringUtils::hashCode(parser ? ByteParser::_getClassName() : ByteFieldSource::_getClassName()); } - ByteDocValues::ByteDocValues(ByteFieldSourcePtr source, Collection arr) + ByteDocValues::ByteDocValues(const ByteFieldSourcePtr& source, Collection arr) { this->_source = source; this->arr = arr; diff --git a/src/core/search/function/CustomScoreProvider.cpp b/src/core/search/function/CustomScoreProvider.cpp index 054fda2b..d3f6b2c2 100644 --- a/src/core/search/function/CustomScoreProvider.cpp +++ b/src/core/search/function/CustomScoreProvider.cpp @@ -10,7 +10,7 @@ namespace Lucene { - CustomScoreProvider::CustomScoreProvider(IndexReaderPtr reader) + CustomScoreProvider::CustomScoreProvider(const IndexReaderPtr& reader) { this->reader = reader; } @@ -36,7 +36,7 @@ namespace Lucene return subQueryScore * valSrcScore; } - ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) + ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { if (valSrcExpls.size() == 1) return customExplain(doc, subQueryExpl, valSrcExpls[0]); @@ -52,7 +52,7 @@ namespace Lucene return exp; } - ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) + ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { double valSrcScore = 1; if (valSrcExpl) diff --git a/src/core/search/function/CustomScoreQuery.cpp b/src/core/search/function/CustomScoreQuery.cpp index 7a5ff755..ed9ff94f 100644 --- a/src/core/search/function/CustomScoreQuery.cpp +++ b/src/core/search/function/CustomScoreQuery.cpp @@ -14,12 +14,12 @@ namespace Lucene { - CustomScoreQuery::CustomScoreQuery(QueryPtr subQuery) + CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery) { ConstructQuery(subQuery, Collection::newInstance()); } - CustomScoreQuery::CustomScoreQuery(QueryPtr subQuery, ValueSourceQueryPtr valSrcQuery) + CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery, const ValueSourceQueryPtr& valSrcQuery) { Collection valSrcQueries(Collection::newInstance()); if (valSrcQuery) @@ -27,7 +27,7 @@ namespace Lucene ConstructQuery(subQuery, valSrcQueries); } - CustomScoreQuery::CustomScoreQuery(QueryPtr subQuery, Collection valSrcQueries) + CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery, Collection valSrcQueries) { ConstructQuery(subQuery, valSrcQueries); } @@ -36,7 +36,7 @@ namespace Lucene { } - void CustomScoreQuery::ConstructQuery(QueryPtr subQuery, Collection valSrcQueries) + void CustomScoreQuery::ConstructQuery(const QueryPtr& subQuery, Collection valSrcQueries) { this->strict = false; this->subQuery = subQuery; @@ -45,7 +45,7 @@ namespace Lucene boost::throw_exception(IllegalArgumentException(L" must not be null!")); } - QueryPtr CustomScoreQuery::rewrite(IndexReaderPtr reader) + QueryPtr CustomScoreQuery::rewrite(const IndexReaderPtr& reader) { CustomScoreQueryPtr cloneQuery; @@ -77,7 +77,7 @@ namespace Lucene (*srcQuery)->extractTerms(terms); } - LuceneObjectPtr CustomScoreQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr CustomScoreQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = Query::clone(other ? other : newLucene(subQuery)); CustomScoreQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); @@ -99,7 +99,7 @@ namespace Lucene return buffer.str(); } - bool CustomScoreQuery::equals(LuceneObjectPtr other) + bool CustomScoreQuery::equals(const LuceneObjectPtr& other) { CustomScoreQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) @@ -116,7 +116,7 @@ namespace Lucene MiscUtils::doubleToIntBits(getBoost()) ^ (strict ? 1234 : 4321); } - CustomScoreProviderPtr CustomScoreQuery::getCustomScoreProvider(IndexReaderPtr reader) + CustomScoreProviderPtr CustomScoreQuery::getCustomScoreProvider(const IndexReaderPtr& reader) { // when deprecated methods are removed, do not extend class here, just return new default CustomScoreProvider return newLucene(shared_from_this(), reader); @@ -139,7 +139,7 @@ namespace Lucene return subQueryScore * valSrcScore; } - ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) + ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { if (valSrcExpls.size() == 1) return customExplain(doc, subQueryExpl, valSrcExpls[0]); @@ -155,7 +155,7 @@ namespace Lucene return exp; } - ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) + ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { double valSrcScore = 1; if (valSrcExpl) @@ -166,7 +166,7 @@ namespace Lucene return exp; } - WeightPtr CustomScoreQuery::createWeight(SearcherPtr searcher) + WeightPtr CustomScoreQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } @@ -186,7 +186,7 @@ namespace Lucene return L"custom"; } - DefaultCustomScoreProvider::DefaultCustomScoreProvider(CustomScoreQueryPtr customQuery, IndexReaderPtr reader) : CustomScoreProvider(reader) + DefaultCustomScoreProvider::DefaultCustomScoreProvider(const CustomScoreQueryPtr& customQuery, const IndexReaderPtr& reader) : CustomScoreProvider(reader) { _customQuery = customQuery; } @@ -205,17 +205,17 @@ namespace Lucene return CustomScoreQueryPtr(_customQuery)->customScore(doc, subQueryScore, valSrcScore); } - ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) + ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpls); } - ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) + ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpl); } - CustomWeight::CustomWeight(CustomScoreQueryPtr query, SearcherPtr searcher) + CustomWeight::CustomWeight(const CustomScoreQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = query->getSimilarity(searcher); @@ -267,7 +267,7 @@ namespace Lucene } } - ScorerPtr CustomWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr CustomWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { // Pass true for "scoresDocsInOrder", because we require in-order scoring, even if caller does not, // since we call advance on the valSrcScorers. Pass false for "topScorer" because we will not invoke @@ -281,13 +281,13 @@ namespace Lucene return newLucene(similarity, reader, shared_from_this(), subQueryScorer, valSrcScorers); } - ExplanationPtr CustomWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr CustomWeight::explain(const IndexReaderPtr& reader, int32_t doc) { ExplanationPtr explain(doExplain(reader, doc)); return explain ? explain : newLucene(0.0, L"no matching docs"); } - ExplanationPtr CustomWeight::doExplain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr CustomWeight::doExplain(const IndexReaderPtr& reader, int32_t doc) { ExplanationPtr subQueryExpl(subQueryWeight->explain(reader, doc)); if (!subQueryExpl->isMatch()) @@ -309,7 +309,7 @@ namespace Lucene return false; } - CustomScorer::CustomScorer(SimilarityPtr similarity, IndexReaderPtr reader, CustomWeightPtr weight, ScorerPtr subQueryScorer, Collection valSrcScorers) : Scorer(similarity) + CustomScorer::CustomScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const CustomWeightPtr& weight, const ScorerPtr& subQueryScorer, Collection valSrcScorers) : Scorer(similarity) { this->qWeight = weight->getValue(); this->subQueryScorer = subQueryScorer; diff --git a/src/core/search/function/DoubleFieldSource.cpp b/src/core/search/function/DoubleFieldSource.cpp index 853e6aca..94311c02 100644 --- a/src/core/search/function/DoubleFieldSource.cpp +++ b/src/core/search/function/DoubleFieldSource.cpp @@ -12,7 +12,7 @@ namespace Lucene { - DoubleFieldSource::DoubleFieldSource(const String& field, DoubleParserPtr parser) : FieldCacheSource(field) + DoubleFieldSource::DoubleFieldSource(const String& field, const DoubleParserPtr& parser) : FieldCacheSource(field) { this->parser = parser; } @@ -26,13 +26,13 @@ namespace Lucene return L"double(" + FieldCacheSource::description() + L")"; } - DocValuesPtr DoubleFieldSource::getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) + DocValuesPtr DoubleFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) { Collection arr(cache->getDoubles(reader, field, parser)); return newLucene(shared_from_this(), arr); } - bool DoubleFieldSource::cachedFieldSourceEquals(FieldCacheSourcePtr other) + bool DoubleFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) return false; @@ -47,7 +47,7 @@ namespace Lucene return StringUtils::hashCode(parser ? DoubleParser::_getClassName() : DoubleFieldSource::_getClassName()); } - DoubleDocValues::DoubleDocValues(DoubleFieldSourcePtr source, Collection arr) + DoubleDocValues::DoubleDocValues(const DoubleFieldSourcePtr& source, Collection arr) { this->_source = source; this->arr = arr; diff --git a/src/core/search/function/FieldCacheSource.cpp b/src/core/search/function/FieldCacheSource.cpp index 082d5e91..962f4e79 100644 --- a/src/core/search/function/FieldCacheSource.cpp +++ b/src/core/search/function/FieldCacheSource.cpp @@ -20,7 +20,7 @@ namespace Lucene { } - DocValuesPtr FieldCacheSource::getValues(IndexReaderPtr reader) + DocValuesPtr FieldCacheSource::getValues(const IndexReaderPtr& reader) { return getCachedFieldValues(FieldCache::DEFAULT(), field, reader); } @@ -30,7 +30,7 @@ namespace Lucene return field; } - bool FieldCacheSource::equals(LuceneObjectPtr other) + bool FieldCacheSource::equals(const LuceneObjectPtr& other) { FieldCacheSourcePtr otherSource(boost::dynamic_pointer_cast(other)); if (!otherSource) diff --git a/src/core/search/function/IntFieldSource.cpp b/src/core/search/function/IntFieldSource.cpp index 08581ea6..f6a3ebe0 100644 --- a/src/core/search/function/IntFieldSource.cpp +++ b/src/core/search/function/IntFieldSource.cpp @@ -13,7 +13,7 @@ namespace Lucene { - IntFieldSource::IntFieldSource(const String& field, IntParserPtr parser) : FieldCacheSource(field) + IntFieldSource::IntFieldSource(const String& field, const IntParserPtr& parser) : FieldCacheSource(field) { this->parser = parser; } @@ -27,13 +27,13 @@ namespace Lucene return L"int(" + FieldCacheSource::description() + L")"; } - DocValuesPtr IntFieldSource::getCachedFieldValues(FieldCachePtr cache, const String& field, IndexReaderPtr reader) + DocValuesPtr IntFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) { Collection arr(cache->getInts(reader, field, parser)); return newLucene(shared_from_this(), arr); } - bool IntFieldSource::cachedFieldSourceEquals(FieldCacheSourcePtr other) + bool IntFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) return false; @@ -48,7 +48,7 @@ namespace Lucene return StringUtils::hashCode(parser ? IntParser::_getClassName() : IntFieldSource::_getClassName()); } - IntDocValues::IntDocValues(IntFieldSourcePtr source, Collection arr) + IntDocValues::IntDocValues(const IntFieldSourcePtr& source, Collection arr) { this->_source = source; this->arr = arr; diff --git a/src/core/search/function/OrdFieldSource.cpp b/src/core/search/function/OrdFieldSource.cpp index 24a30ef1..011049bd 100644 --- a/src/core/search/function/OrdFieldSource.cpp +++ b/src/core/search/function/OrdFieldSource.cpp @@ -27,13 +27,13 @@ namespace Lucene return L"ord(" + field + L")"; } - DocValuesPtr OrdFieldSource::getValues(IndexReaderPtr reader) + DocValuesPtr OrdFieldSource::getValues(const IndexReaderPtr& reader) { Collection arr(FieldCache::DEFAULT()->getStringIndex(reader, field)->order); return newLucene(shared_from_this(), arr); } - bool OrdFieldSource::equals(LuceneObjectPtr other) + bool OrdFieldSource::equals(const LuceneObjectPtr& other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) return false; @@ -48,7 +48,7 @@ namespace Lucene return StringUtils::hashCode(OrdFieldSource::_getClassName()) + StringUtils::hashCode(field); } - OrdDocValues::OrdDocValues(OrdFieldSourcePtr source, Collection arr) + OrdDocValues::OrdDocValues(const OrdFieldSourcePtr& source, Collection arr) { this->_source = source; this->arr = arr; diff --git a/src/core/search/function/ReverseOrdFieldSource.cpp b/src/core/search/function/ReverseOrdFieldSource.cpp index 3463f362..50c08dfb 100644 --- a/src/core/search/function/ReverseOrdFieldSource.cpp +++ b/src/core/search/function/ReverseOrdFieldSource.cpp @@ -27,7 +27,7 @@ namespace Lucene return L"rord(" + field + L")"; } - DocValuesPtr ReverseOrdFieldSource::getValues(IndexReaderPtr reader) + DocValuesPtr ReverseOrdFieldSource::getValues(const IndexReaderPtr& reader) { StringIndexPtr sindex(FieldCache::DEFAULT()->getStringIndex(reader, field)); Collection arr(sindex->order); @@ -35,7 +35,7 @@ namespace Lucene return newLucene(shared_from_this(), arr, end); } - bool ReverseOrdFieldSource::equals(LuceneObjectPtr other) + bool ReverseOrdFieldSource::equals(const LuceneObjectPtr& other) { if (!MiscUtils::equalTypes(shared_from_this(), other)) return false; @@ -50,7 +50,7 @@ namespace Lucene return StringUtils::hashCode(ReverseOrdFieldSource::_getClassName()) + StringUtils::hashCode(field); } - ReverseOrdDocValues::ReverseOrdDocValues(ReverseOrdFieldSourcePtr source, Collection arr, int32_t end) + ReverseOrdDocValues::ReverseOrdDocValues(const ReverseOrdFieldSourcePtr& source, Collection arr, int32_t end) { this->_source = source; this->arr = arr; diff --git a/src/core/search/function/ValueSourceQuery.cpp b/src/core/search/function/ValueSourceQuery.cpp index 7e197a8b..d86cbe09 100644 --- a/src/core/search/function/ValueSourceQuery.cpp +++ b/src/core/search/function/ValueSourceQuery.cpp @@ -17,7 +17,7 @@ namespace Lucene { - ValueSourceQuery::ValueSourceQuery(ValueSourcePtr valSrc) + ValueSourceQuery::ValueSourceQuery(const ValueSourcePtr& valSrc) { this->valSrc = valSrc; } @@ -26,7 +26,7 @@ namespace Lucene { } - QueryPtr ValueSourceQuery::rewrite(IndexReaderPtr reader) + QueryPtr ValueSourceQuery::rewrite(const IndexReaderPtr& reader) { return shared_from_this(); } @@ -36,7 +36,7 @@ namespace Lucene // no terms involved here } - WeightPtr ValueSourceQuery::createWeight(SearcherPtr searcher) + WeightPtr ValueSourceQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } @@ -46,7 +46,7 @@ namespace Lucene return valSrc->toString() + boostString(); } - bool ValueSourceQuery::equals(LuceneObjectPtr other) + bool ValueSourceQuery::equals(const LuceneObjectPtr& other) { ValueSourceQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); if (!otherQuery) @@ -59,7 +59,7 @@ namespace Lucene return (StringUtils::hashCode(ValueSourceQuery::_getClassName()) + valSrc->hashCode()) ^ MiscUtils::doubleToIntBits(getBoost()); } - LuceneObjectPtr ValueSourceQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr ValueSourceQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(valSrc); ValueSourceQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); @@ -67,7 +67,7 @@ namespace Lucene return cloneQuery; } - ValueSourceWeight::ValueSourceWeight(ValueSourceQueryPtr query, SearcherPtr searcher) + ValueSourceWeight::ValueSourceWeight(const ValueSourceQueryPtr& query, const SearcherPtr& searcher) { this->query = query; this->similarity = query->getSimilarity(searcher); @@ -99,12 +99,12 @@ namespace Lucene queryWeight *= queryNorm; } - ScorerPtr ValueSourceWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr ValueSourceWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(similarity, reader, shared_from_this()); } - ExplanationPtr ValueSourceWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr ValueSourceWeight::explain(const IndexReaderPtr& reader, int32_t doc) { DocValuesPtr vals(query->valSrc->getValues(reader)); double sc = queryWeight * vals->doubleVal(doc); @@ -117,7 +117,7 @@ namespace Lucene return result; } - ValueSourceScorer::ValueSourceScorer(SimilarityPtr similarity, IndexReaderPtr reader, ValueSourceWeightPtr weight) : Scorer(similarity) + ValueSourceScorer::ValueSourceScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const ValueSourceWeightPtr& weight) : Scorer(similarity) { this->weight = weight; this->qWeight = weight->getValue(); diff --git a/src/core/search/payloads/AveragePayloadFunction.cpp b/src/core/search/payloads/AveragePayloadFunction.cpp index 657faf7c..537051d7 100644 --- a/src/core/search/payloads/AveragePayloadFunction.cpp +++ b/src/core/search/payloads/AveragePayloadFunction.cpp @@ -34,7 +34,7 @@ namespace Lucene return result; } - bool AveragePayloadFunction::equals(LuceneObjectPtr other) + bool AveragePayloadFunction::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/payloads/MaxPayloadFunction.cpp b/src/core/search/payloads/MaxPayloadFunction.cpp index f8f411ac..0062f7f8 100644 --- a/src/core/search/payloads/MaxPayloadFunction.cpp +++ b/src/core/search/payloads/MaxPayloadFunction.cpp @@ -16,7 +16,7 @@ namespace Lucene } double MaxPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, - int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) + int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { if (numPayloadsSeen == 0) return currentPayloadScore; @@ -37,7 +37,7 @@ namespace Lucene return result; } - bool MaxPayloadFunction::equals(LuceneObjectPtr other) + bool MaxPayloadFunction::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/payloads/MinPayloadFunction.cpp b/src/core/search/payloads/MinPayloadFunction.cpp index 5c695d00..a2d61dd3 100644 --- a/src/core/search/payloads/MinPayloadFunction.cpp +++ b/src/core/search/payloads/MinPayloadFunction.cpp @@ -16,7 +16,7 @@ namespace Lucene } double MinPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, - int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) + int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { if (numPayloadsSeen == 0) return currentPayloadScore; @@ -37,7 +37,7 @@ namespace Lucene return result; } - bool MinPayloadFunction::equals(LuceneObjectPtr other) + bool MinPayloadFunction::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/payloads/PayloadNearQuery.cpp b/src/core/search/payloads/PayloadNearQuery.cpp index f30d2f1a..378b1f3e 100644 --- a/src/core/search/payloads/PayloadNearQuery.cpp +++ b/src/core/search/payloads/PayloadNearQuery.cpp @@ -22,7 +22,7 @@ namespace Lucene this->function = newLucene(); } - PayloadNearQuery::PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, PayloadFunctionPtr function) : SpanNearQuery(clauses, slop, inOrder) + PayloadNearQuery::PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, const PayloadFunctionPtr& function) : SpanNearQuery(clauses, slop, inOrder) { fieldName = clauses[0]->getField(); // all clauses must have same field this->function = function; @@ -32,12 +32,12 @@ namespace Lucene { } - WeightPtr PayloadNearQuery::createWeight(SearcherPtr searcher) + WeightPtr PayloadNearQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } - LuceneObjectPtr PayloadNearQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr PayloadNearQuery::clone(const LuceneObjectPtr& other) { int32_t sz = clauses.size(); Collection newClauses(Collection::newInstance(sz)); @@ -64,7 +64,7 @@ namespace Lucene return buffer.str(); } - bool PayloadNearQuery::equals(LuceneObjectPtr other) + bool PayloadNearQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -96,7 +96,7 @@ namespace Lucene return result; } - PayloadNearSpanWeight::PayloadNearSpanWeight(SpanQueryPtr query, SearcherPtr searcher) : SpanWeight(query, searcher) + PayloadNearSpanWeight::PayloadNearSpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher) : SpanWeight(query, searcher) { } @@ -104,12 +104,12 @@ namespace Lucene { } - ScorerPtr PayloadNearSpanWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr PayloadNearSpanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); } - PayloadNearSpanScorer::PayloadNearSpanScorer(SpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) + PayloadNearSpanScorer::PayloadNearSpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) { this->spans = spans; this->payloadScore = 0.0; diff --git a/src/core/search/payloads/PayloadSpanUtil.cpp b/src/core/search/payloads/PayloadSpanUtil.cpp index f50c6296..28b4f63f 100644 --- a/src/core/search/payloads/PayloadSpanUtil.cpp +++ b/src/core/search/payloads/PayloadSpanUtil.cpp @@ -22,7 +22,7 @@ namespace Lucene { - PayloadSpanUtil::PayloadSpanUtil(IndexReaderPtr reader) + PayloadSpanUtil::PayloadSpanUtil(const IndexReaderPtr& reader) { this->reader = reader; } @@ -31,14 +31,14 @@ namespace Lucene { } - Collection PayloadSpanUtil::getPayloadsForQuery(QueryPtr query) + Collection PayloadSpanUtil::getPayloadsForQuery(const QueryPtr& query) { Collection payloads(Collection::newInstance()); queryToSpanQuery(query, payloads); return payloads; } - void PayloadSpanUtil::queryToSpanQuery(QueryPtr query, Collection payloads) + void PayloadSpanUtil::queryToSpanQuery(const QueryPtr& query, Collection payloads) { if (MiscUtils::typeOf(query)) { @@ -149,7 +149,7 @@ namespace Lucene } } - void PayloadSpanUtil::getPayloads(Collection payloads, SpanQueryPtr query) + void PayloadSpanUtil::getPayloads(Collection payloads, const SpanQueryPtr& query) { SpansPtr spans(query->getSpans(reader)); diff --git a/src/core/search/payloads/PayloadTermQuery.cpp b/src/core/search/payloads/PayloadTermQuery.cpp index c6eafa5b..7638dc76 100644 --- a/src/core/search/payloads/PayloadTermQuery.cpp +++ b/src/core/search/payloads/PayloadTermQuery.cpp @@ -18,7 +18,7 @@ namespace Lucene { - PayloadTermQuery::PayloadTermQuery(TermPtr term, PayloadFunctionPtr function, bool includeSpanScore) : SpanTermQuery(term) + PayloadTermQuery::PayloadTermQuery(const TermPtr& term, const PayloadFunctionPtr& function, bool includeSpanScore) : SpanTermQuery(term) { this->function = function; this->includeSpanScore = includeSpanScore; @@ -28,12 +28,12 @@ namespace Lucene { } - WeightPtr PayloadTermQuery::createWeight(SearcherPtr searcher) + WeightPtr PayloadTermQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } - LuceneObjectPtr PayloadTermQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr PayloadTermQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term, function, includeSpanScore)); PayloadTermQueryPtr termQuery(boost::dynamic_pointer_cast(clone)); @@ -42,7 +42,7 @@ namespace Lucene return termQuery; } - bool PayloadTermQuery::equals(LuceneObjectPtr other) + bool PayloadTermQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -74,7 +74,7 @@ namespace Lucene return result; } - PayloadTermWeight::PayloadTermWeight(PayloadTermQueryPtr query, SearcherPtr searcher) : SpanWeight(query, searcher) + PayloadTermWeight::PayloadTermWeight(const PayloadTermQueryPtr& query, const SearcherPtr& searcher) : SpanWeight(query, searcher) { } @@ -82,12 +82,12 @@ namespace Lucene { } - ScorerPtr PayloadTermWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr PayloadTermWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(boost::dynamic_pointer_cast(query->getSpans(reader)), shared_from_this(), similarity, reader->norms(query->getField())); } - PayloadTermSpanScorer::PayloadTermSpanScorer(TermSpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) + PayloadTermSpanScorer::PayloadTermSpanScorer(const TermSpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) { positions = spans->getPositions(); payload = ByteArray::newInstance(256); @@ -120,7 +120,7 @@ namespace Lucene return more || (freq != 0); } - void PayloadTermSpanScorer::processPayload(SimilarityPtr similarity) + void PayloadTermSpanScorer::processPayload(const SimilarityPtr& similarity) { if (positions->isPayloadAvailable()) { diff --git a/src/core/search/spans/FieldMaskingSpanQuery.cpp b/src/core/search/spans/FieldMaskingSpanQuery.cpp index d51c6d79..42a5b6b9 100644 --- a/src/core/search/spans/FieldMaskingSpanQuery.cpp +++ b/src/core/search/spans/FieldMaskingSpanQuery.cpp @@ -11,7 +11,7 @@ namespace Lucene { - FieldMaskingSpanQuery::FieldMaskingSpanQuery(SpanQueryPtr maskedQuery, const String& maskedField) + FieldMaskingSpanQuery::FieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField) { this->maskedQuery = maskedQuery; this->field = maskedField; @@ -34,7 +34,7 @@ namespace Lucene // :NOTE: getBoost and setBoost are not proxied to the maskedQuery // ...this is done to be more consistent with things like SpanFirstQuery - SpansPtr FieldMaskingSpanQuery::getSpans(IndexReaderPtr reader) + SpansPtr FieldMaskingSpanQuery::getSpans(const IndexReaderPtr& reader) { return maskedQuery->getSpans(reader); } @@ -44,17 +44,17 @@ namespace Lucene maskedQuery->extractTerms(terms); } - WeightPtr FieldMaskingSpanQuery::createWeight(SearcherPtr searcher) + WeightPtr FieldMaskingSpanQuery::createWeight(const SearcherPtr& searcher) { return maskedQuery->createWeight(searcher); } - SimilarityPtr FieldMaskingSpanQuery::getSimilarity(SearcherPtr searcher) + SimilarityPtr FieldMaskingSpanQuery::getSimilarity(const SearcherPtr& searcher) { return maskedQuery->getSimilarity(searcher); } - QueryPtr FieldMaskingSpanQuery::rewrite(IndexReaderPtr reader) + QueryPtr FieldMaskingSpanQuery::rewrite(const IndexReaderPtr& reader) { FieldMaskingSpanQueryPtr clone; @@ -79,7 +79,7 @@ namespace Lucene return buffer.str(); } - bool FieldMaskingSpanQuery::equals(LuceneObjectPtr other) + bool FieldMaskingSpanQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -97,7 +97,7 @@ namespace Lucene return getMaskedQuery()->hashCode() ^ StringUtils::hashCode(getField()) ^ MiscUtils::doubleToRawIntBits(getBoost()); } - LuceneObjectPtr FieldMaskingSpanQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr FieldMaskingSpanQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(maskedQuery, field)); FieldMaskingSpanQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); diff --git a/src/core/search/spans/NearSpansOrdered.cpp b/src/core/search/spans/NearSpansOrdered.cpp index abfefe90..945ccfd1 100644 --- a/src/core/search/spans/NearSpansOrdered.cpp +++ b/src/core/search/spans/NearSpansOrdered.cpp @@ -10,7 +10,7 @@ namespace Lucene { - NearSpansOrdered::NearSpansOrdered(SpanNearQueryPtr spanNearQuery, IndexReaderPtr reader, bool collectPayloads) + NearSpansOrdered::NearSpansOrdered(const SpanNearQueryPtr& spanNearQuery, const IndexReaderPtr& reader, bool collectPayloads) { if (spanNearQuery->getClauses().size() < 2) boost::throw_exception(IllegalArgumentException(L"Less than 2 clauses: " + spanNearQuery->toString())); @@ -161,7 +161,7 @@ namespace Lucene return true; } - bool NearSpansOrdered::docSpansOrdered(SpansPtr spans1, SpansPtr spans2) + bool NearSpansOrdered::docSpansOrdered(const SpansPtr& spans1, const SpansPtr& spans2) { BOOST_ASSERT(spans1->doc() == spans2->doc()); int32_t start1 = spans1->start(); diff --git a/src/core/search/spans/NearSpansUnordered.cpp b/src/core/search/spans/NearSpansUnordered.cpp index 664d3096..27cb074d 100644 --- a/src/core/search/spans/NearSpansUnordered.cpp +++ b/src/core/search/spans/NearSpansUnordered.cpp @@ -13,7 +13,7 @@ namespace Lucene { - NearSpansUnordered::NearSpansUnordered(SpanNearQueryPtr query, IndexReaderPtr reader) + NearSpansUnordered::NearSpansUnordered(const SpanNearQueryPtr& query, const IndexReaderPtr& reader) { this->query = query; this->reader = reader; @@ -201,7 +201,7 @@ namespace Lucene } } - void NearSpansUnordered::addToList(SpansCellPtr cell) + void NearSpansUnordered::addToList(const SpansCellPtr& cell) { if (last) // add next to end of list last->_next = cell; @@ -239,7 +239,7 @@ namespace Lucene return ((min()->doc() == max->doc()) && ((max->end() - min()->start() - totalLength) <= slop)); } - SpansCell::SpansCell(NearSpansUnorderedPtr unordered, SpansPtr spans, int32_t index) + SpansCell::SpansCell(const NearSpansUnorderedPtr& unordered, const SpansPtr& spans, int32_t index) { this->_unordered = unordered; this->spans = spans; diff --git a/src/core/search/spans/SpanFirstQuery.cpp b/src/core/search/spans/SpanFirstQuery.cpp index a5482ee6..0f84c35a 100644 --- a/src/core/search/spans/SpanFirstQuery.cpp +++ b/src/core/search/spans/SpanFirstQuery.cpp @@ -12,7 +12,7 @@ namespace Lucene { - SpanFirstQuery::SpanFirstQuery(SpanQueryPtr match, int32_t end) + SpanFirstQuery::SpanFirstQuery(const SpanQueryPtr& match, int32_t end) { this->match = match; this->end = end; @@ -44,7 +44,7 @@ namespace Lucene return buffer.str(); } - LuceneObjectPtr SpanFirstQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr SpanFirstQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(boost::dynamic_pointer_cast(match->clone()), end)); SpanFirstQueryPtr spanFirstQuery(boost::dynamic_pointer_cast(clone)); @@ -59,12 +59,12 @@ namespace Lucene match->extractTerms(terms); } - SpansPtr SpanFirstQuery::getSpans(IndexReaderPtr reader) + SpansPtr SpanFirstQuery::getSpans(const IndexReaderPtr& reader) { return newLucene(shared_from_this(), match->getSpans(reader)); } - QueryPtr SpanFirstQuery::rewrite(IndexReaderPtr reader) + QueryPtr SpanFirstQuery::rewrite(const IndexReaderPtr& reader) { SpanFirstQueryPtr clone; SpanQueryPtr rewritten(boost::dynamic_pointer_cast(match->rewrite(reader))); @@ -80,7 +80,7 @@ namespace Lucene return shared_from_this(); // no clauses rewrote } - bool SpanFirstQuery::equals(LuceneObjectPtr other) + bool SpanFirstQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -100,7 +100,7 @@ namespace Lucene return result; } - FirstSpans::FirstSpans(SpanFirstQueryPtr query, SpansPtr spans) + FirstSpans::FirstSpans(const SpanFirstQueryPtr& query, const SpansPtr& spans) { this->query = query; this->spans = spans; diff --git a/src/core/search/spans/SpanNearQuery.cpp b/src/core/search/spans/SpanNearQuery.cpp index 687950f2..ccbe6662 100644 --- a/src/core/search/spans/SpanNearQuery.cpp +++ b/src/core/search/spans/SpanNearQuery.cpp @@ -75,7 +75,7 @@ namespace Lucene return buffer.str(); } - SpansPtr SpanNearQuery::getSpans(IndexReaderPtr reader) + SpansPtr SpanNearQuery::getSpans(const IndexReaderPtr& reader) { if (clauses.empty()) // optimize 0-clause case return newLucene(getClauses())->getSpans(reader); @@ -88,7 +88,7 @@ namespace Lucene : boost::static_pointer_cast(newLucene(shared_from_this(), reader)); } - QueryPtr SpanNearQuery::rewrite(IndexReaderPtr reader) + QueryPtr SpanNearQuery::rewrite(const IndexReaderPtr& reader) { SpanNearQueryPtr clone; for (int32_t i = 0; i < clauses.size(); ++i) @@ -108,7 +108,7 @@ namespace Lucene return shared_from_this(); // no clauses rewrote } - LuceneObjectPtr SpanNearQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr SpanNearQuery::clone(const LuceneObjectPtr& other) { int32_t sz = clauses.size(); Collection newClauses(Collection::newInstance(sz)); @@ -121,7 +121,7 @@ namespace Lucene return spanNearQuery; } - bool SpanNearQuery::equals(LuceneObjectPtr other) + bool SpanNearQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/search/spans/SpanNotQuery.cpp b/src/core/search/spans/SpanNotQuery.cpp index 8ceef89b..81984ea1 100644 --- a/src/core/search/spans/SpanNotQuery.cpp +++ b/src/core/search/spans/SpanNotQuery.cpp @@ -11,7 +11,7 @@ namespace Lucene { - SpanNotQuery::SpanNotQuery(SpanQueryPtr include, SpanQueryPtr exclude) + SpanNotQuery::SpanNotQuery(const SpanQueryPtr& include, const SpanQueryPtr& exclude) { this->include = include; this->exclude = exclude; @@ -52,7 +52,7 @@ namespace Lucene return buffer.str(); } - LuceneObjectPtr SpanNotQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr SpanNotQuery::clone(const LuceneObjectPtr& other) { SpanNotQueryPtr spanNotQuery(newLucene(boost::dynamic_pointer_cast(include->clone()), boost::dynamic_pointer_cast(exclude->clone()))); @@ -60,12 +60,12 @@ namespace Lucene return spanNotQuery; } - SpansPtr SpanNotQuery::getSpans(IndexReaderPtr reader) + SpansPtr SpanNotQuery::getSpans(const IndexReaderPtr& reader) { return newLucene(shared_from_this(), include->getSpans(reader), exclude->getSpans(reader)); } - QueryPtr SpanNotQuery::rewrite(IndexReaderPtr reader) + QueryPtr SpanNotQuery::rewrite(const IndexReaderPtr& reader) { SpanNotQueryPtr clone; SpanQueryPtr rewrittenInclude(boost::dynamic_pointer_cast(include->rewrite(reader))); @@ -89,7 +89,7 @@ namespace Lucene return shared_from_this(); // no clauses rewrote } - bool SpanNotQuery::equals(LuceneObjectPtr other) + bool SpanNotQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -111,7 +111,7 @@ namespace Lucene return result; } - NotSpans::NotSpans(SpanNotQueryPtr query, SpansPtr includeSpans, SpansPtr excludeSpans) + NotSpans::NotSpans(const SpanNotQueryPtr& query, const SpansPtr& includeSpans, const SpansPtr& excludeSpans) { this->query = query; this->includeSpans = includeSpans; diff --git a/src/core/search/spans/SpanOrQuery.cpp b/src/core/search/spans/SpanOrQuery.cpp index 2601538e..4e2c102c 100644 --- a/src/core/search/spans/SpanOrQuery.cpp +++ b/src/core/search/spans/SpanOrQuery.cpp @@ -46,7 +46,7 @@ namespace Lucene (*clause)->extractTerms(terms); } - LuceneObjectPtr SpanOrQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr SpanOrQuery::clone(const LuceneObjectPtr& other) { int32_t sz = clauses.size(); Collection newClauses(Collection::newInstance(sz)); @@ -59,7 +59,7 @@ namespace Lucene return spanOrQuery; } - QueryPtr SpanOrQuery::rewrite(IndexReaderPtr reader) + QueryPtr SpanOrQuery::rewrite(const IndexReaderPtr& reader) { SpanOrQueryPtr clone; for (int32_t i = 0; i < clauses.size(); ++i) @@ -93,7 +93,7 @@ namespace Lucene return buffer.str(); } - bool SpanOrQuery::equals(LuceneObjectPtr other) + bool SpanOrQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -118,7 +118,7 @@ namespace Lucene return result; } - SpansPtr SpanOrQuery::getSpans(IndexReaderPtr reader) + SpansPtr SpanOrQuery::getSpans(const IndexReaderPtr& reader) { if (clauses.size() == 1) // optimize 1-clause case return clauses[0]->getSpans(reader); @@ -146,7 +146,7 @@ namespace Lucene return (first->doc() < second->doc()); } - OrSpans::OrSpans(SpanOrQueryPtr query, IndexReaderPtr reader) + OrSpans::OrSpans(const SpanOrQueryPtr& query, const IndexReaderPtr& reader) { this->query = query; this->reader = reader; diff --git a/src/core/search/spans/SpanQuery.cpp b/src/core/search/spans/SpanQuery.cpp index 5f386e4f..eaa80cd3 100644 --- a/src/core/search/spans/SpanQuery.cpp +++ b/src/core/search/spans/SpanQuery.cpp @@ -14,7 +14,7 @@ namespace Lucene { } - WeightPtr SpanQuery::createWeight(SearcherPtr searcher) + WeightPtr SpanQuery::createWeight(const SearcherPtr& searcher) { return newLucene(shared_from_this(), searcher); } diff --git a/src/core/search/spans/SpanScorer.cpp b/src/core/search/spans/SpanScorer.cpp index 1abe535a..42a27351 100644 --- a/src/core/search/spans/SpanScorer.cpp +++ b/src/core/search/spans/SpanScorer.cpp @@ -14,7 +14,7 @@ namespace Lucene { - SpanScorer::SpanScorer(SpansPtr spans, WeightPtr weight, SimilarityPtr similarity, ByteArray norms) : Scorer(similarity) + SpanScorer::SpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) { this->spans = spans; this->norms = norms; diff --git a/src/core/search/spans/SpanTermQuery.cpp b/src/core/search/spans/SpanTermQuery.cpp index f60e1f2e..9664b312 100644 --- a/src/core/search/spans/SpanTermQuery.cpp +++ b/src/core/search/spans/SpanTermQuery.cpp @@ -13,7 +13,7 @@ namespace Lucene { - SpanTermQuery::SpanTermQuery(TermPtr term) + SpanTermQuery::SpanTermQuery(const TermPtr& term) { this->term = term; } @@ -56,7 +56,7 @@ namespace Lucene return result; } - bool SpanTermQuery::equals(LuceneObjectPtr other) + bool SpanTermQuery::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -77,7 +77,7 @@ namespace Lucene return true; } - LuceneObjectPtr SpanTermQuery::clone(LuceneObjectPtr other) + LuceneObjectPtr SpanTermQuery::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term)); SpanTermQueryPtr spanFirstQuery(boost::dynamic_pointer_cast(clone)); @@ -85,7 +85,7 @@ namespace Lucene return spanFirstQuery; } - SpansPtr SpanTermQuery::getSpans(IndexReaderPtr reader) + SpansPtr SpanTermQuery::getSpans(const IndexReaderPtr& reader) { return newLucene(reader->termPositions(term), term); } diff --git a/src/core/search/spans/SpanWeight.cpp b/src/core/search/spans/SpanWeight.cpp index cd1dcf4c..f60f801a 100644 --- a/src/core/search/spans/SpanWeight.cpp +++ b/src/core/search/spans/SpanWeight.cpp @@ -15,7 +15,7 @@ namespace Lucene { - SpanWeight::SpanWeight(SpanQueryPtr query, SearcherPtr searcher) + SpanWeight::SpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher) { this->similarity = query->getSimilarity(searcher); this->query = query; @@ -57,12 +57,12 @@ namespace Lucene value = queryWeight * idf; // idf for document } - ScorerPtr SpanWeight::scorer(IndexReaderPtr reader, bool scoreDocsInOrder, bool topScorer) + ScorerPtr SpanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); } - ExplanationPtr SpanWeight::explain(IndexReaderPtr reader, int32_t doc) + ExplanationPtr SpanWeight::explain(const IndexReaderPtr& reader, int32_t doc) { ComplexExplanationPtr result(newLucene()); result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); diff --git a/src/core/search/spans/TermSpans.cpp b/src/core/search/spans/TermSpans.cpp index c1ec88f1..86340fb4 100644 --- a/src/core/search/spans/TermSpans.cpp +++ b/src/core/search/spans/TermSpans.cpp @@ -11,7 +11,7 @@ namespace Lucene { - TermSpans::TermSpans(TermPositionsPtr positions, TermPtr term) + TermSpans::TermSpans(const TermPositionsPtr& positions, const TermPtr& term) { this->positions = positions; this->term = term; diff --git a/src/core/store/BufferedIndexInput.cpp b/src/core/store/BufferedIndexInput.cpp index 5c6a2c63..33292eaf 100644 --- a/src/core/store/BufferedIndexInput.cpp +++ b/src/core/store/BufferedIndexInput.cpp @@ -178,7 +178,7 @@ namespace Lucene } } - LuceneObjectPtr BufferedIndexInput::clone(LuceneObjectPtr other) + LuceneObjectPtr BufferedIndexInput::clone(const LuceneObjectPtr& other) { BufferedIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(IndexInput::clone(other))); cloneIndexInput->bufferSize = bufferSize; diff --git a/src/core/store/ChecksumIndexInput.cpp b/src/core/store/ChecksumIndexInput.cpp index 4e1006b7..96f696e4 100644 --- a/src/core/store/ChecksumIndexInput.cpp +++ b/src/core/store/ChecksumIndexInput.cpp @@ -9,7 +9,7 @@ namespace Lucene { - ChecksumIndexInput::ChecksumIndexInput(IndexInputPtr main) + ChecksumIndexInput::ChecksumIndexInput(const IndexInputPtr& main) { this->main = main; } @@ -56,7 +56,7 @@ namespace Lucene return main->length(); } - LuceneObjectPtr ChecksumIndexInput::clone(LuceneObjectPtr other) + LuceneObjectPtr ChecksumIndexInput::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene(main)); ChecksumIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); diff --git a/src/core/store/ChecksumIndexOutput.cpp b/src/core/store/ChecksumIndexOutput.cpp index 631357bc..87d0d38c 100644 --- a/src/core/store/ChecksumIndexOutput.cpp +++ b/src/core/store/ChecksumIndexOutput.cpp @@ -9,7 +9,7 @@ namespace Lucene { - ChecksumIndexOutput::ChecksumIndexOutput(IndexOutputPtr main) + ChecksumIndexOutput::ChecksumIndexOutput(const IndexOutputPtr& main) { this->main = main; } diff --git a/src/core/store/Directory.cpp b/src/core/store/Directory.cpp index e331db59..bf93af23 100644 --- a/src/core/store/Directory.cpp +++ b/src/core/store/Directory.cpp @@ -48,7 +48,7 @@ namespace Lucene lockFactory->clearLock(name); } - void Directory::setLockFactory(LockFactoryPtr lockFactory) + void Directory::setLockFactory(const LockFactoryPtr& lockFactory) { BOOST_ASSERT(lockFactory); this->lockFactory = lockFactory; @@ -70,7 +70,7 @@ namespace Lucene return LuceneObject::toString() + L" lockFactory=" + getLockFactory()->toString(); } - void Directory::copy(DirectoryPtr src, DirectoryPtr dest, bool closeDirSrc) + void Directory::copy(const DirectoryPtr& src, const DirectoryPtr& dest, bool closeDirSrc) { HashSet files(src->listAll()); diff --git a/src/core/store/FSDirectory.cpp b/src/core/store/FSDirectory.cpp index e1bdeb5f..81d5e089 100644 --- a/src/core/store/FSDirectory.cpp +++ b/src/core/store/FSDirectory.cpp @@ -28,24 +28,26 @@ namespace Lucene const int32_t FSDirectory::DEFAULT_READ_CHUNK_SIZE = 100 * 1024 * 1024; // 100mb #endif - FSDirectory::FSDirectory(const String& path, LockFactoryPtr lockFactory) + FSDirectory::FSDirectory(const String& path, const LockFactoryPtr& lockFactory) { checked = false; chunkSize = DEFAULT_READ_CHUNK_SIZE; + LockFactoryPtr _lockFactory(lockFactory); + // new ctors use always NativeFSLockFactory as default - if (!lockFactory) - lockFactory = newLucene(); + if (!_lockFactory) + _lockFactory = newLucene(); directory = path; if (FileUtils::fileExists(directory) && !FileUtils::isDirectory(directory)) boost::throw_exception(NoSuchDirectoryException(L"File '" + directory + L"' exists but is not a directory")); - setLockFactory(lockFactory); + setLockFactory(_lockFactory); // for filesystem based LockFactory, delete the lockPrefix if the locks are placed // in index dir. if no index dir is given, set ourselves - FSLockFactoryPtr lf(boost::dynamic_pointer_cast(lockFactory)); + FSLockFactoryPtr lf(boost::dynamic_pointer_cast(_lockFactory)); if (lf) { @@ -68,7 +70,7 @@ namespace Lucene return open(path, LockFactoryPtr()); } - FSDirectoryPtr FSDirectory::open(const String& path, LockFactoryPtr lockFactory) + FSDirectoryPtr FSDirectory::open(const String& path, const LockFactoryPtr& lockFactory) { return newLucene(path, lockFactory); } diff --git a/src/core/store/FileSwitchDirectory.cpp b/src/core/store/FileSwitchDirectory.cpp index f682be5d..2378c2f6 100644 --- a/src/core/store/FileSwitchDirectory.cpp +++ b/src/core/store/FileSwitchDirectory.cpp @@ -9,7 +9,7 @@ namespace Lucene { - FileSwitchDirectory::FileSwitchDirectory(HashSet primaryExtensions, DirectoryPtr primaryDir, DirectoryPtr secondaryDir, bool doClose) + FileSwitchDirectory::FileSwitchDirectory(HashSet primaryExtensions, const DirectoryPtr& primaryDir, const DirectoryPtr& secondaryDir, bool doClose) { this->primaryExtensions = primaryExtensions; this->primaryDir = primaryDir; diff --git a/src/core/store/IndexInput.cpp b/src/core/store/IndexInput.cpp index 4fee2108..592eb02a 100644 --- a/src/core/store/IndexInput.cpp +++ b/src/core/store/IndexInput.cpp @@ -146,7 +146,7 @@ namespace Lucene return map; } - LuceneObjectPtr IndexInput::clone(LuceneObjectPtr other) + LuceneObjectPtr IndexInput::clone(const LuceneObjectPtr& other) { IndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(LuceneObject::clone(other))); cloneIndexInput->preUTF8Strings = preUTF8Strings; diff --git a/src/core/store/IndexOutput.cpp b/src/core/store/IndexOutput.cpp index 7cb0052f..90859ed3 100644 --- a/src/core/store/IndexOutput.cpp +++ b/src/core/store/IndexOutput.cpp @@ -88,7 +88,7 @@ namespace Lucene } } - void IndexOutput::copyBytes(IndexInputPtr input, int64_t numBytes) + void IndexOutput::copyBytes(const IndexInputPtr& input, int64_t numBytes) { BOOST_ASSERT(numBytes >= 0); int64_t left = numBytes; diff --git a/src/core/store/MMapDirectory.cpp b/src/core/store/MMapDirectory.cpp index 91324e95..b8a15812 100644 --- a/src/core/store/MMapDirectory.cpp +++ b/src/core/store/MMapDirectory.cpp @@ -15,7 +15,7 @@ namespace Lucene { - MMapDirectory::MMapDirectory(const String& path, LockFactoryPtr lockFactory) : FSDirectory(path, lockFactory) + MMapDirectory::MMapDirectory(const String& path, const LockFactoryPtr& lockFactory) : FSDirectory(path, lockFactory) { } @@ -107,7 +107,7 @@ namespace Lucene file.close(); } - LuceneObjectPtr MMapIndexInput::clone(LuceneObjectPtr other) + LuceneObjectPtr MMapIndexInput::clone(const LuceneObjectPtr& other) { if (!file.is_open()) boost::throw_exception(AlreadyClosedException(L"MMapIndexInput already closed")); diff --git a/src/core/store/RAMDirectory.cpp b/src/core/store/RAMDirectory.cpp index dab12d60..3973010c 100644 --- a/src/core/store/RAMDirectory.cpp +++ b/src/core/store/RAMDirectory.cpp @@ -24,7 +24,7 @@ namespace Lucene setLockFactory(newLucene()); } - RAMDirectory::RAMDirectory(DirectoryPtr dir) + RAMDirectory::RAMDirectory(const DirectoryPtr& dir) { this->fileMap = MapStringRAMFile::newInstance(); this->_sizeInBytes = 0; @@ -34,7 +34,7 @@ namespace Lucene setLockFactory(newLucene()); } - RAMDirectory::RAMDirectory(DirectoryPtr dir, bool closeDir) + RAMDirectory::RAMDirectory(const DirectoryPtr& dir, bool closeDir) { this->fileMap = MapStringRAMFile::newInstance(); this->_sizeInBytes = 0; diff --git a/src/core/store/RAMFile.cpp b/src/core/store/RAMFile.cpp index e7d861fa..54c599f6 100644 --- a/src/core/store/RAMFile.cpp +++ b/src/core/store/RAMFile.cpp @@ -19,7 +19,7 @@ namespace Lucene this->lastModified = MiscUtils::currentTimeMillis(); } - RAMFile::RAMFile(RAMDirectoryPtr directory) + RAMFile::RAMFile(const RAMDirectoryPtr& directory) { this->buffers = Collection::newInstance(); this->length = 0; diff --git a/src/core/store/RAMInputStream.cpp b/src/core/store/RAMInputStream.cpp index 2b8d947b..7514bc62 100644 --- a/src/core/store/RAMInputStream.cpp +++ b/src/core/store/RAMInputStream.cpp @@ -26,7 +26,7 @@ namespace Lucene bufferLength = 0; } - RAMInputStream::RAMInputStream(RAMFilePtr f) + RAMInputStream::RAMInputStream(const RAMFilePtr& f) { file = f; _length = file->length; @@ -122,7 +122,7 @@ namespace Lucene bufferPosition = (int32_t)(pos % BUFFER_SIZE); } - LuceneObjectPtr RAMInputStream::clone(LuceneObjectPtr other) + LuceneObjectPtr RAMInputStream::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene()); RAMInputStreamPtr cloneInputStream(boost::dynamic_pointer_cast(clone)); diff --git a/src/core/store/RAMOutputStream.cpp b/src/core/store/RAMOutputStream.cpp index b4ee4763..5bca4a23 100644 --- a/src/core/store/RAMOutputStream.cpp +++ b/src/core/store/RAMOutputStream.cpp @@ -25,7 +25,7 @@ namespace Lucene bufferLength = 0; } - RAMOutputStream::RAMOutputStream(RAMFilePtr f) + RAMOutputStream::RAMOutputStream(const RAMFilePtr& f) { file = f; @@ -40,7 +40,7 @@ namespace Lucene { } - void RAMOutputStream::writeTo(IndexOutputPtr out) + void RAMOutputStream::writeTo(const IndexOutputPtr& out) { flush(); int64_t end = file->length; diff --git a/src/core/store/SimpleFSDirectory.cpp b/src/core/store/SimpleFSDirectory.cpp index 7f39ca84..b975a306 100644 --- a/src/core/store/SimpleFSDirectory.cpp +++ b/src/core/store/SimpleFSDirectory.cpp @@ -15,7 +15,7 @@ namespace Lucene { - SimpleFSDirectory::SimpleFSDirectory(const String& path, LockFactoryPtr lockFactory) : FSDirectory(path, lockFactory) + SimpleFSDirectory::SimpleFSDirectory(const String& path, const LockFactoryPtr& lockFactory) : FSDirectory(path, lockFactory) { } @@ -161,7 +161,7 @@ namespace Lucene return file->isValid(); } - LuceneObjectPtr SimpleFSIndexInput::clone(LuceneObjectPtr other) + LuceneObjectPtr SimpleFSIndexInput::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = BufferedIndexInput::clone(other ? other : newLucene()); SimpleFSIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); diff --git a/src/core/util/Attribute.cpp b/src/core/util/Attribute.cpp index debf887f..87402103 100644 --- a/src/core/util/Attribute.cpp +++ b/src/core/util/Attribute.cpp @@ -18,12 +18,12 @@ namespace Lucene return LuceneObject::hashCode(); } - bool Attribute::equals(LuceneObjectPtr other) + bool Attribute::equals(const LuceneObjectPtr& other) { return LuceneObject::equals(other); } - LuceneObjectPtr Attribute::clone(LuceneObjectPtr other) + LuceneObjectPtr Attribute::clone(const LuceneObjectPtr& other) { return LuceneObject::clone(other); } diff --git a/src/core/util/AttributeSource.cpp b/src/core/util/AttributeSource.cpp index 2ad09f10..6dd86955 100644 --- a/src/core/util/AttributeSource.cpp +++ b/src/core/util/AttributeSource.cpp @@ -40,7 +40,7 @@ namespace Lucene this->factory = AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY(); } - AttributeSource::AttributeSource(AttributeSourcePtr input) + AttributeSource::AttributeSource(const AttributeSourcePtr& input) { if (!input) boost::throw_exception(IllegalArgumentException(L"input AttributeSource must not be null")); @@ -48,7 +48,7 @@ namespace Lucene this->factory = input->factory; } - AttributeSource::AttributeSource(AttributeFactoryPtr factory) + AttributeSource::AttributeSource(const AttributeFactoryPtr& factory) { this->attributes = MapStringAttribute::newInstance(); this->factory = factory; @@ -63,7 +63,7 @@ namespace Lucene return this->factory; } - void AttributeSource::addAttribute(const String& className, AttributePtr attrImpl) + void AttributeSource::addAttribute(const String& className, const AttributePtr& attrImpl) { // invalidate state to force recomputation in captureState() currentState.reset(); @@ -123,20 +123,21 @@ namespace Lucene return boost::dynamic_pointer_cast(currentState->clone()); } - void AttributeSource::restoreState(AttributeSourceStatePtr state) + void AttributeSource::restoreState(const AttributeSourceStatePtr& state) { - if (!state) + AttributeSourceStatePtr _state(state); + if (!_state) return; do { - MapStringAttribute::iterator attrImpl = attributes.find(state->attribute->getClassName()); + MapStringAttribute::iterator attrImpl = attributes.find(_state->attribute->getClassName()); if (attrImpl == attributes.end()) boost::throw_exception(IllegalArgumentException(L"State contains an AttributeImpl that is not in this AttributeSource")); - state->attribute->copyTo(attrImpl->second); - state = state->next; + _state->attribute->copyTo(attrImpl->second); + _state = _state->next; } - while (state); + while (_state); } int32_t AttributeSource::hashCode() @@ -147,7 +148,7 @@ namespace Lucene return code; } - bool AttributeSource::equals(LuceneObjectPtr other) + bool AttributeSource::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -248,7 +249,7 @@ namespace Lucene { } - LuceneObjectPtr AttributeSourceState::clone(LuceneObjectPtr other) + LuceneObjectPtr AttributeSourceState::clone(const LuceneObjectPtr& other) { AttributeSourceStatePtr clone(newLucene()); clone->attribute = boost::dynamic_pointer_cast(attribute->clone()); diff --git a/src/core/util/BitSet.cpp b/src/core/util/BitSet.cpp index 53615453..a1142af9 100644 --- a/src/core/util/BitSet.cpp +++ b/src/core/util/BitSet.cpp @@ -161,7 +161,7 @@ namespace Lucene return next == bitset_type::npos ? -1 : next; } - void BitSet::_and(BitSetPtr set) + void BitSet::_and(const BitSetPtr& set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); for (bitset_type::size_type i = 0; i < minBlocks; ++i) @@ -170,7 +170,7 @@ namespace Lucene std::fill(bitSet.m_bits.begin() + minBlocks, bitSet.m_bits.end(), bitset_type::block_type(0)); } - void BitSet::_or(BitSetPtr set) + void BitSet::_or(const BitSetPtr& set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); if (set->bitSet.size() > bitSet.size()) @@ -181,7 +181,7 @@ namespace Lucene std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); } - void BitSet::_xor(BitSetPtr set) + void BitSet::_xor(const BitSetPtr& set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); if (set->bitSet.size() > bitSet.size()) @@ -192,14 +192,14 @@ namespace Lucene std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); } - void BitSet::andNot(BitSetPtr set) + void BitSet::andNot(const BitSetPtr& set) { bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); for (bitset_type::size_type i = 0; i < minBlocks; ++i) bitSet.m_bits[i] &= ~set->bitSet.m_bits[i]; } - bool BitSet::intersectsBitSet(BitSetPtr set) const + bool BitSet::intersectsBitSet(const BitSetPtr& set) const { return bitSet.intersects(set->bitSet); } @@ -221,7 +221,7 @@ namespace Lucene bitSet.m_bits.back() &= ~(~static_cast(0) << extra_bits); } - bool BitSet::equals(LuceneObjectPtr other) + bool BitSet::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; @@ -262,7 +262,7 @@ namespace Lucene return (int32_t)((hash >> 32) ^ hash) + 0x98761234; } - LuceneObjectPtr BitSet::clone(LuceneObjectPtr other) + LuceneObjectPtr BitSet::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); BitSetPtr cloneBitSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); diff --git a/src/core/util/BitVector.cpp b/src/core/util/BitVector.cpp index 66456144..683a4524 100644 --- a/src/core/util/BitVector.cpp +++ b/src/core/util/BitVector.cpp @@ -41,7 +41,7 @@ namespace Lucene this->_count = -1; } - BitVector::BitVector(DirectoryPtr d, const String& name) + BitVector::BitVector(const DirectoryPtr& d, const String& name) { IndexInputPtr input(d->openInput(name)); LuceneException finally; @@ -65,7 +65,7 @@ namespace Lucene { } - LuceneObjectPtr BitVector::clone(LuceneObjectPtr other) + LuceneObjectPtr BitVector::clone(const LuceneObjectPtr& other) { ByteArray copyBits(ByteArray::newInstance(bits.size())); MiscUtils::arrayCopy(bits.get(), 0, copyBits.get(), 0, bits.size()); @@ -142,7 +142,7 @@ namespace Lucene return c; } - void BitVector::write(DirectoryPtr d, const String& name) + void BitVector::write(const DirectoryPtr& d, const String& name) { TestScope testScope(L"BitVector", L"write"); IndexOutputPtr output(d->createOutput(name)); @@ -162,14 +162,14 @@ namespace Lucene finally.throwException(); } - void BitVector::writeBits(IndexOutputPtr output) + void BitVector::writeBits(const IndexOutputPtr& output) { output->writeInt(size()); // write size output->writeInt(count()); // write count output->writeBytes(bits.get(), bits.size()); } - void BitVector::writeDgaps(IndexOutputPtr output) + void BitVector::writeDgaps(const IndexOutputPtr& output) { output->writeInt(-1); // mark using d-gaps output->writeInt(size()); // write size @@ -210,7 +210,7 @@ namespace Lucene return factor * (4 + (8 + 40) * count()) < size(); } - void BitVector::readBits(IndexInputPtr input) + void BitVector::readBits(const IndexInputPtr& input) { _count = input->readInt(); // read count bits = ByteArray::newInstance((_size >> 3) + 1); // allocate bits @@ -218,7 +218,7 @@ namespace Lucene input->readBytes(bits.get(), 0, bits.size()); } - void BitVector::readDgaps(IndexInputPtr input) + void BitVector::readDgaps(const IndexInputPtr& input) { _size = input->readInt(); // (re)read size _count = input->readInt(); // read count diff --git a/src/core/util/BufferedReader.cpp b/src/core/util/BufferedReader.cpp index 054d1a2d..368954af 100644 --- a/src/core/util/BufferedReader.cpp +++ b/src/core/util/BufferedReader.cpp @@ -12,7 +12,7 @@ namespace Lucene { const int32_t BufferedReader::READER_BUFFER = 8192; - BufferedReader::BufferedReader(ReaderPtr reader, int32_t size) + BufferedReader::BufferedReader(const ReaderPtr& reader, int32_t size) { this->reader = reader; this->bufferSize = size; diff --git a/src/core/util/DocIdBitSet.cpp b/src/core/util/DocIdBitSet.cpp index 9feaaf1a..63a0c005 100644 --- a/src/core/util/DocIdBitSet.cpp +++ b/src/core/util/DocIdBitSet.cpp @@ -15,7 +15,7 @@ namespace Lucene { } - DocIdBitSet::DocIdBitSet(BitSetPtr bitSet) + DocIdBitSet::DocIdBitSet(const BitSetPtr& bitSet) { this->bitSet = bitSet; } @@ -39,7 +39,7 @@ namespace Lucene return bitSet; } - bool DocIdBitSet::equals(LuceneObjectPtr other) + bool DocIdBitSet::equals(const LuceneObjectPtr& other) { if (DocIdSet::equals(other)) return true; @@ -52,7 +52,7 @@ namespace Lucene return bitSet->hashCode(); } - LuceneObjectPtr DocIdBitSet::clone(LuceneObjectPtr other) + LuceneObjectPtr DocIdBitSet::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); DocIdBitSetPtr cloneBitSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); @@ -60,7 +60,7 @@ namespace Lucene return cloneBitSet; } - DocIdBitSetIterator::DocIdBitSetIterator(BitSetPtr bitSet) + DocIdBitSetIterator::DocIdBitSetIterator(const BitSetPtr& bitSet) { this->bitSet = bitSet; this->docId = -1; diff --git a/src/core/util/FieldCacheSanityChecker.cpp b/src/core/util/FieldCacheSanityChecker.cpp index ef6b46d7..2b0408f9 100644 --- a/src/core/util/FieldCacheSanityChecker.cpp +++ b/src/core/util/FieldCacheSanityChecker.cpp @@ -22,7 +22,7 @@ namespace Lucene { } - Collection FieldCacheSanityChecker::checkSanity(FieldCachePtr cache) + Collection FieldCacheSanityChecker::checkSanity(const FieldCachePtr& cache) { return checkSanity(cache->getCacheEntries()); } @@ -178,7 +178,7 @@ namespace Lucene return insanity; } - Collection FieldCacheSanityChecker::getAllDecendentReaderKeys(LuceneObjectPtr seed) + Collection FieldCacheSanityChecker::getAllDecendentReaderKeys(const LuceneObjectPtr& seed) { Collection all(Collection::newInstance()); // will grow as we iter all.add(seed); @@ -198,7 +198,7 @@ namespace Lucene return all; } - ReaderField::ReaderField(LuceneObjectPtr readerKey, const String& fieldName) + ReaderField::ReaderField(const LuceneObjectPtr& readerKey, const String& fieldName) { this->readerKey = readerKey; this->fieldName = fieldName; @@ -213,7 +213,7 @@ namespace Lucene return readerKey->hashCode() * StringUtils::hashCode(fieldName); } - bool ReaderField::equals(LuceneObjectPtr other) + bool ReaderField::equals(const LuceneObjectPtr& other) { ReaderFieldPtr otherReaderField(boost::dynamic_pointer_cast(other)); if (!otherReaderField) diff --git a/src/core/util/InputStreamReader.cpp b/src/core/util/InputStreamReader.cpp index c2f414a4..d257da04 100644 --- a/src/core/util/InputStreamReader.cpp +++ b/src/core/util/InputStreamReader.cpp @@ -11,7 +11,7 @@ namespace Lucene { - InputStreamReader::InputStreamReader(ReaderPtr reader) + InputStreamReader::InputStreamReader(const ReaderPtr& reader) { this->reader = reader; this->decoder = newLucene(newLucene(reader, 1024)); diff --git a/src/core/util/LuceneObject.cpp b/src/core/util/LuceneObject.cpp index c9ec00c0..bf83b42c 100644 --- a/src/core/util/LuceneObject.cpp +++ b/src/core/util/LuceneObject.cpp @@ -23,7 +23,7 @@ namespace Lucene // override } - LuceneObjectPtr LuceneObject::clone(LuceneObjectPtr other) + LuceneObjectPtr LuceneObject::clone(const LuceneObjectPtr& other) { if (!other) boost::throw_exception(UnsupportedOperationException(L"clone must not be null")); @@ -35,12 +35,12 @@ namespace Lucene return (int32_t)(int64_t)this; } - bool LuceneObject::equals(LuceneObjectPtr other) + bool LuceneObject::equals(const LuceneObjectPtr& other) { return (other && this == other.get()); } - int32_t LuceneObject::compareTo(LuceneObjectPtr other) + int32_t LuceneObject::compareTo(const LuceneObjectPtr& other) { return (int32_t)(this - other.get()); } diff --git a/src/core/util/LuceneSignal.cpp b/src/core/util/LuceneSignal.cpp index 74d0ad26..31a9fa32 100644 --- a/src/core/util/LuceneSignal.cpp +++ b/src/core/util/LuceneSignal.cpp @@ -10,7 +10,7 @@ namespace Lucene { - LuceneSignal::LuceneSignal(SynchronizePtr objectLock) + LuceneSignal::LuceneSignal(const SynchronizePtr& objectLock) { this->objectLock = objectLock; } @@ -19,7 +19,7 @@ namespace Lucene { } - void LuceneSignal::createSignal(LuceneSignalPtr& signal, SynchronizePtr objectLock) + void LuceneSignal::createSignal(LuceneSignalPtr& signal, const SynchronizePtr& objectLock) { static boost::mutex lockMutex; boost::mutex::scoped_lock syncLock(lockMutex); diff --git a/src/core/util/MiscUtils.cpp b/src/core/util/MiscUtils.cpp index e5f21e68..68c19fe1 100644 --- a/src/core/util/MiscUtils.cpp +++ b/src/core/util/MiscUtils.cpp @@ -134,7 +134,7 @@ namespace Lucene return (value != value); } - bool MiscUtils::equalTypes(LuceneObjectPtr first, LuceneObjectPtr second) + bool MiscUtils::equalTypes(const LuceneObjectPtr& first, const LuceneObjectPtr& second) { return (typeid(*first) == typeid(*second)); } diff --git a/src/core/util/NumericUtils.cpp b/src/core/util/NumericUtils.cpp index 7cb5839c..4165390f 100644 --- a/src/core/util/NumericUtils.cpp +++ b/src/core/util/NumericUtils.cpp @@ -162,17 +162,17 @@ namespace Lucene return sortableLongToDouble(prefixCodedToLong(val)); } - void NumericUtils::splitLongRange(LongRangeBuilderPtr builder, int32_t precisionStep, int64_t minBound, int64_t maxBound) + void NumericUtils::splitLongRange(const LongRangeBuilderPtr& builder, int32_t precisionStep, int64_t minBound, int64_t maxBound) { splitRange(builder, 64, precisionStep, minBound, maxBound); } - void NumericUtils::splitIntRange(IntRangeBuilderPtr builder, int32_t precisionStep, int32_t minBound, int32_t maxBound) + void NumericUtils::splitIntRange(const IntRangeBuilderPtr& builder, int32_t precisionStep, int32_t minBound, int32_t maxBound) { splitRange(builder, 32, precisionStep, (int64_t)minBound, (int64_t)maxBound); } - void NumericUtils::splitRange(LuceneObjectPtr builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound) + void NumericUtils::splitRange(const LuceneObjectPtr& builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound) { if (precisionStep < 1) boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); @@ -208,7 +208,7 @@ namespace Lucene } } - void NumericUtils::addRange(LuceneObjectPtr builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift) + void NumericUtils::addRange(const LuceneObjectPtr& builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift) { // for the max bound set all lower bits (that were shifted away): this is important for testing or other // usages of the splitted range (eg. to reconstruct the full range). The prefixEncoding will remove the diff --git a/src/core/util/OpenBitSet.cpp b/src/core/util/OpenBitSet.cpp index 70767657..869f33ab 100644 --- a/src/core/util/OpenBitSet.cpp +++ b/src/core/util/OpenBitSet.cpp @@ -364,12 +364,12 @@ namespace Lucene return BitUtil::pop_array(bits.get(), 0, wlen); } - int64_t OpenBitSet::intersectionCount(OpenBitSetPtr a, OpenBitSetPtr b) + int64_t OpenBitSet::intersectionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { return BitUtil::pop_intersect(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); } - int64_t OpenBitSet::unionCount(OpenBitSetPtr a, OpenBitSetPtr b) + int64_t OpenBitSet::unionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { int64_t tot = BitUtil::pop_union(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); if (a->wlen < b->wlen) @@ -379,7 +379,7 @@ namespace Lucene return tot; } - int64_t OpenBitSet::andNotCount(OpenBitSetPtr a, OpenBitSetPtr b) + int64_t OpenBitSet::andNotCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { int64_t tot = BitUtil::pop_andnot(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); if (a->wlen > b->wlen) @@ -387,7 +387,7 @@ namespace Lucene return tot; } - int64_t OpenBitSet::xorCount(OpenBitSetPtr a, OpenBitSetPtr b) + int64_t OpenBitSet::xorCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { int64_t tot = BitUtil::pop_xor(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); if (a->wlen < b->wlen) @@ -439,7 +439,7 @@ namespace Lucene return -1; } - LuceneObjectPtr OpenBitSet::clone(LuceneObjectPtr other) + LuceneObjectPtr OpenBitSet::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); OpenBitSetPtr cloneSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); @@ -449,7 +449,7 @@ namespace Lucene return cloneSet; } - void OpenBitSet::intersect(OpenBitSetPtr other) + void OpenBitSet::intersect(const OpenBitSetPtr& other) { int32_t newLen= std::min(this->wlen, other->wlen); LongArray thisArr = this->bits; @@ -466,7 +466,7 @@ namespace Lucene this->wlen = newLen; } - void OpenBitSet::_union(OpenBitSetPtr other) + void OpenBitSet::_union(const OpenBitSetPtr& other) { int32_t newLen = std::max(wlen, other->wlen); ensureCapacityWords(newLen); @@ -481,7 +481,7 @@ namespace Lucene this->wlen = newLen; } - void OpenBitSet::remove(OpenBitSetPtr other) + void OpenBitSet::remove(const OpenBitSetPtr& other) { int32_t idx = std::min(wlen, other->wlen); LongArray thisArr = this->bits; @@ -490,7 +490,7 @@ namespace Lucene thisArr[idx] &= ~otherArr[idx]; } - void OpenBitSet::_xor(OpenBitSetPtr other) + void OpenBitSet::_xor(const OpenBitSetPtr& other) { int32_t newLen = std::max(wlen, other->wlen); ensureCapacityWords(newLen); @@ -505,22 +505,22 @@ namespace Lucene this->wlen = newLen; } - void OpenBitSet::_and(OpenBitSetPtr other) + void OpenBitSet::_and(const OpenBitSetPtr& other) { intersect(other); } - void OpenBitSet::_or(OpenBitSetPtr other) + void OpenBitSet::_or(const OpenBitSetPtr& other) { _union(other); } - void OpenBitSet::andNot(OpenBitSetPtr other) + void OpenBitSet::andNot(const OpenBitSetPtr& other) { remove(other); } - bool OpenBitSet::intersects(OpenBitSetPtr other) + bool OpenBitSet::intersects(const OpenBitSetPtr& other) { int32_t pos = std::min(this->wlen, other->wlen); LongArray thisArr = this->bits; @@ -561,7 +561,7 @@ namespace Lucene return (int32_t)(MiscUtils::unsignedShift(numBits - 1, (int64_t)6) + 1); } - bool OpenBitSet::equals(LuceneObjectPtr other) + bool OpenBitSet::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) return true; diff --git a/src/core/util/OpenBitSetDISI.cpp b/src/core/util/OpenBitSetDISI.cpp index 666e9a50..0688c0be 100644 --- a/src/core/util/OpenBitSetDISI.cpp +++ b/src/core/util/OpenBitSetDISI.cpp @@ -9,7 +9,7 @@ namespace Lucene { - OpenBitSetDISI::OpenBitSetDISI(DocIdSetIteratorPtr disi, int32_t maxSize) : OpenBitSet(maxSize) + OpenBitSetDISI::OpenBitSetDISI(const DocIdSetIteratorPtr& disi, int32_t maxSize) : OpenBitSet(maxSize) { inPlaceOr(disi); } @@ -22,7 +22,7 @@ namespace Lucene { } - void OpenBitSetDISI::inPlaceOr(DocIdSetIteratorPtr disi) + void OpenBitSetDISI::inPlaceOr(const DocIdSetIteratorPtr& disi) { int32_t doc; int32_t _size = size(); @@ -30,7 +30,7 @@ namespace Lucene set(doc); } - void OpenBitSetDISI::inPlaceAnd(DocIdSetIteratorPtr disi) + void OpenBitSetDISI::inPlaceAnd(const DocIdSetIteratorPtr& disi) { int32_t bitSetDoc = nextSetBit((int32_t)0); int32_t disiDoc; @@ -43,7 +43,7 @@ namespace Lucene clear((int64_t)bitSetDoc, size()); } - void OpenBitSetDISI::inPlaceNot(DocIdSetIteratorPtr disi) + void OpenBitSetDISI::inPlaceNot(const DocIdSetIteratorPtr& disi) { int32_t doc; int32_t _size = size(); @@ -51,7 +51,7 @@ namespace Lucene clear(doc); } - void OpenBitSetDISI::inPlaceXor(DocIdSetIteratorPtr disi) + void OpenBitSetDISI::inPlaceXor(const DocIdSetIteratorPtr& disi) { int32_t doc; int32_t _size = size(); diff --git a/src/core/util/OpenBitSetIterator.cpp b/src/core/util/OpenBitSetIterator.cpp index 5b805f1e..3a4e3d40 100644 --- a/src/core/util/OpenBitSetIterator.cpp +++ b/src/core/util/OpenBitSetIterator.cpp @@ -46,7 +46,7 @@ namespace Lucene 0x876541, 0x876542, 0x8765421, 0x876543, 0x8765431, 0x8765432, static_cast(0x87654321) }; - OpenBitSetIterator::OpenBitSetIterator(OpenBitSetPtr bitSet) + OpenBitSetIterator::OpenBitSetIterator(const OpenBitSetPtr& bitSet) { arr = bitSet->getBits(); words = bitSet->getNumWords(); diff --git a/src/core/util/ReaderUtil.cpp b/src/core/util/ReaderUtil.cpp index 9b27b626..fc84d52b 100644 --- a/src/core/util/ReaderUtil.cpp +++ b/src/core/util/ReaderUtil.cpp @@ -14,7 +14,7 @@ namespace Lucene { } - void ReaderUtil::gatherSubReaders(Collection allSubReaders, IndexReaderPtr reader) + void ReaderUtil::gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader) { Collection subReaders(reader->getSequentialSubReaders()); if (!subReaders) @@ -29,7 +29,7 @@ namespace Lucene } } - IndexReaderPtr ReaderUtil::subReader(int32_t doc, IndexReaderPtr reader) + IndexReaderPtr ReaderUtil::subReader(int32_t doc, const IndexReaderPtr& reader) { Collection subReaders(Collection::newInstance()); ReaderUtil::gatherSubReaders(subReaders, reader); @@ -43,7 +43,7 @@ namespace Lucene return subReaders[ReaderUtil::subIndex(doc, docStarts)]; } - IndexReaderPtr ReaderUtil::subReader(IndexReaderPtr reader, int32_t subIndex) + IndexReaderPtr ReaderUtil::subReader(const IndexReaderPtr& reader, int32_t subIndex) { Collection subReaders(Collection::newInstance()); ReaderUtil::gatherSubReaders(subReaders, reader); diff --git a/src/core/util/ScorerDocQueue.cpp b/src/core/util/ScorerDocQueue.cpp index 7c666202..8aabd9ee 100644 --- a/src/core/util/ScorerDocQueue.cpp +++ b/src/core/util/ScorerDocQueue.cpp @@ -25,13 +25,13 @@ namespace Lucene { } - void ScorerDocQueue::put(ScorerPtr scorer) + void ScorerDocQueue::put(const ScorerPtr& scorer) { heap[++_size] = newLucene(scorer); upHeap(); } - bool ScorerDocQueue::insert(ScorerPtr scorer) + bool ScorerDocQueue::insert(const ScorerPtr& scorer) { if (_size < maxSize) { @@ -158,13 +158,13 @@ namespace Lucene topHSD = heap[1]; } - HeapedScorerDoc::HeapedScorerDoc(ScorerPtr scorer) + HeapedScorerDoc::HeapedScorerDoc(const ScorerPtr& scorer) { this->scorer = scorer; this->doc = scorer->docID(); } - HeapedScorerDoc::HeapedScorerDoc(ScorerPtr scorer, int32_t doc) + HeapedScorerDoc::HeapedScorerDoc(const ScorerPtr& scorer, int32_t doc) { this->scorer = scorer; this->doc = doc; diff --git a/src/core/util/SortedVIntList.cpp b/src/core/util/SortedVIntList.cpp index 1aabb9bf..0bd7259d 100644 --- a/src/core/util/SortedVIntList.cpp +++ b/src/core/util/SortedVIntList.cpp @@ -40,7 +40,7 @@ namespace Lucene bytes.resize(lastBytePos); } - SortedVIntList::SortedVIntList(BitSetPtr bits) + SortedVIntList::SortedVIntList(const BitSetPtr& bits) { lastInt = 0; initBytes(); @@ -53,7 +53,7 @@ namespace Lucene bytes.resize(lastBytePos); } - SortedVIntList::SortedVIntList(OpenBitSetPtr bits) + SortedVIntList::SortedVIntList(const OpenBitSetPtr& bits) { lastInt = 0; initBytes(); @@ -66,7 +66,7 @@ namespace Lucene bytes.resize(lastBytePos); } - SortedVIntList::SortedVIntList(DocIdSetIteratorPtr docIdSetIterator) + SortedVIntList::SortedVIntList(const DocIdSetIteratorPtr& docIdSetIterator) { lastInt = 0; initBytes(); @@ -130,7 +130,7 @@ namespace Lucene return newLucene(shared_from_this()); } - SortedDocIdSetIterator::SortedDocIdSetIterator(SortedVIntListPtr list) + SortedDocIdSetIterator::SortedDocIdSetIterator(const SortedVIntListPtr& list) { _list = list; bytePos = 0; diff --git a/src/core/util/StringUtils.cpp b/src/core/util/StringUtils.cpp index c1abacb3..bc950f19 100644 --- a/src/core/util/StringUtils.cpp +++ b/src/core/util/StringUtils.cpp @@ -30,7 +30,7 @@ namespace Lucene return decodeLength == Reader::READER_EOF ? 0 : decodeLength; } - int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, UnicodeResultPtr unicodeResult) + int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, const UnicodeResultPtr& unicodeResult) { if (length == 0) unicodeResult->length = 0; @@ -66,7 +66,7 @@ namespace Lucene return encodeLength == Reader::READER_EOF ? 0 : encodeLength; } - int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, UTF8ResultPtr utf8Result) + int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, const UTF8ResultPtr& utf8Result) { if (length == 0) utf8Result->length = 0; diff --git a/src/core/util/Synchronize.cpp b/src/core/util/Synchronize.cpp index 38d33f55..50b54fcf 100644 --- a/src/core/util/Synchronize.cpp +++ b/src/core/util/Synchronize.cpp @@ -59,7 +59,7 @@ namespace Lucene return (lockThread == LuceneThread::currentId() && recursionCount > 0); } - SyncLock::SyncLock(SynchronizePtr sync, int32_t timeout) + SyncLock::SyncLock(const SynchronizePtr& sync, int32_t timeout) { this->sync = sync; lock(timeout); diff --git a/src/core/util/UTF8Stream.cpp b/src/core/util/UTF8Stream.cpp index 82983fed..ecc4c748 100644 --- a/src/core/util/UTF8Stream.cpp +++ b/src/core/util/UTF8Stream.cpp @@ -185,7 +185,7 @@ namespace Lucene #endif } - UTF8EncoderStream::UTF8EncoderStream(ReaderPtr reader) : UTF8Encoder(NULL, NULL) + UTF8EncoderStream::UTF8EncoderStream(const ReaderPtr& reader) : UTF8Encoder(NULL, NULL) { this->reader = reader; } @@ -334,7 +334,7 @@ namespace Lucene #endif } - UTF8DecoderStream::UTF8DecoderStream(ReaderPtr reader) : UTF8Decoder(NULL, NULL) + UTF8DecoderStream::UTF8DecoderStream(const ReaderPtr& reader) : UTF8Decoder(NULL, NULL) { this->reader = reader; } diff --git a/src/demo/indexfiles/main.cpp b/src/demo/indexfiles/main.cpp index 3f0b4d37..80b72f7e 100644 --- a/src/demo/indexfiles/main.cpp +++ b/src/demo/indexfiles/main.cpp @@ -37,7 +37,7 @@ DocumentPtr fileDocument(const String& docFile) return doc; } -void indexDocs(IndexWriterPtr writer, const String& sourceDir) +void indexDocs(const IndexWriterPtr& writer, const String& sourceDir) { HashSet dirList(HashSet::newInstance()); if (!FileUtils::listDirectory(sourceDir, false, dirList)) diff --git a/src/demo/searchfiles/main.cpp b/src/demo/searchfiles/main.cpp index 9254ec12..9c8aba40 100644 --- a/src/demo/searchfiles/main.cpp +++ b/src/demo/searchfiles/main.cpp @@ -22,7 +22,7 @@ using namespace Lucene; class OneNormsReader : public FilterIndexReader { public: - OneNormsReader(IndexReaderPtr in, const String& field) : FilterIndexReader(in) + OneNormsReader(const IndexReaderPtr& in, const String& field) : FilterIndexReader(in) { this->field = field; } @@ -47,7 +47,7 @@ class OneNormsReader : public FilterIndexReader /// When the query is executed for the first time, then only enough results are collected to fill 5 result /// pages. If the user wants to page beyond this limit, then the query is executed another time and all /// hits are collected. -static void doPagingSearch(SearcherPtr searcher, QueryPtr query, int32_t hitsPerPage, bool raw, bool interactive) +static void doPagingSearch(const SearcherPtr& searcher, const QueryPtr& query, int32_t hitsPerPage, bool raw, bool interactive) { // Collect enough docs to show 5 pages TopScoreDocCollectorPtr collector = TopScoreDocCollector::create(5 * hitsPerPage, false); @@ -190,12 +190,12 @@ class StreamingHitCollector : public Collector return true; } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -206,7 +206,7 @@ class StreamingHitCollector : public Collector /// /// This simulates the streaming search use case, where all hits are supposed to be processed, regardless /// of their relevance. -static void doStreamingSearch(SearcherPtr searcher, QueryPtr query) +static void doStreamingSearch(const SearcherPtr& searcher, const QueryPtr& query) { searcher->search(query, newLucene()); } diff --git a/src/test/analysis/AnalyzersTest.cpp b/src/test/analysis/AnalyzersTest.cpp index 705a6611..bdc6d210 100644 --- a/src/test/analysis/AnalyzersTest.cpp +++ b/src/test/analysis/AnalyzersTest.cpp @@ -19,7 +19,7 @@ using namespace Lucene; typedef BaseTokenStreamFixture AnalyzersTest; -static void verifyPayload(TokenStreamPtr ts) +static void verifyPayload(const TokenStreamPtr& ts) { PayloadAttributePtr payloadAtt = ts->getAttribute(); for (uint8_t b = 1; ; ++b) @@ -71,7 +71,7 @@ namespace TestPayloadCopy class PayloadSetter : public TokenFilter { public: - PayloadSetter(TokenStreamPtr input) : TokenFilter(input) + PayloadSetter(const TokenStreamPtr& input) : TokenFilter(input) { payloadAtt = addAttribute(); data = ByteArray::newInstance(1); diff --git a/src/test/analysis/BaseTokenStreamFixture.cpp b/src/test/analysis/BaseTokenStreamFixture.cpp index fae26b18..e7121976 100644 --- a/src/test/analysis/BaseTokenStreamFixture.cpp +++ b/src/test/analysis/BaseTokenStreamFixture.cpp @@ -37,7 +37,7 @@ namespace Lucene clearCalled = true; } - bool CheckClearAttributesAttribute::equals(LuceneObjectPtr other) + bool CheckClearAttributesAttribute::equals(const LuceneObjectPtr& other) { if (Attribute::equals(other)) return true; @@ -54,13 +54,13 @@ namespace Lucene return 76137213 ^ (clearCalled ? 1231 : 1237); } - void CheckClearAttributesAttribute::copyTo(AttributePtr target) + void CheckClearAttributesAttribute::copyTo(const AttributePtr& target) { CheckClearAttributesAttributePtr clearAttribute(boost::dynamic_pointer_cast(target)); clearAttribute->clear(); } - LuceneObjectPtr CheckClearAttributesAttribute::clone(LuceneObjectPtr other) + LuceneObjectPtr CheckClearAttributesAttribute::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = other ? other : newLucene(); CheckClearAttributesAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); @@ -72,7 +72,7 @@ namespace Lucene { } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements, int32_t finalOffset) { EXPECT_TRUE(output); @@ -136,109 +136,109 @@ namespace Lucene ts->close(); } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output) + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output) { checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), Collection(), -1); } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection types) + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection types) { checkTokenStreamContents(ts, output, Collection(), Collection(), types, Collection(), -1); } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection posIncrements) + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection posIncrements) { checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), posIncrements, -1); } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets) + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), -1); } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset) + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), finalOffset); } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, -1); } - void BaseTokenStreamFixture::checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset) + void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset) { checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, finalOffset); } - void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, + void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements) { checkTokenStreamContents(analyzer->tokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); } - void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output) + void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output) { checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); } - void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection types) + void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types) { checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), types, Collection()); } - void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements) + void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements) { checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); } - void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) + void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) { checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); } - void BaseTokenStreamFixture::checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) + void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); } - void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, + void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements) { checkTokenStreamContents(analyzer->reusableTokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); } - void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output) + void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output) { checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); } - void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection types) + void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types) { checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), types, Collection()); } - void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements) + void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements) { checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); } - void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) + void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) { checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); } - void BaseTokenStreamFixture::checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) + void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); } - void BaseTokenStreamFixture::checkOneTerm(AnalyzerPtr analyzer, const String& input, const String& expected) + void BaseTokenStreamFixture::checkOneTerm(const AnalyzerPtr& analyzer, const String& input, const String& expected) { checkAnalyzesTo(analyzer, input, newCollection(expected)); } - void BaseTokenStreamFixture::checkOneTermReuse(AnalyzerPtr analyzer, const String& input, const String& expected) + void BaseTokenStreamFixture::checkOneTermReuse(const AnalyzerPtr& analyzer, const String& input, const String& expected) { checkAnalyzesToReuse(analyzer, input, newCollection(expected)); } diff --git a/src/test/analysis/CachingTokenFilterTest.cpp b/src/test/analysis/CachingTokenFilterTest.cpp index ae295f70..d7f8bc65 100644 --- a/src/test/analysis/CachingTokenFilterTest.cpp +++ b/src/test/analysis/CachingTokenFilterTest.cpp @@ -25,7 +25,7 @@ typedef BaseTokenStreamFixture CachingTokenFilterTest; static Collection tokens = newCollection(L"term1", L"term2", L"term3", L"term2"); -static void checkTokens(TokenStreamPtr stream) +static void checkTokens(const TokenStreamPtr& stream) { int32_t count = 0; diff --git a/src/test/analysis/CharFilterTest.cpp b/src/test/analysis/CharFilterTest.cpp index c3820152..fb7488e4 100644 --- a/src/test/analysis/CharFilterTest.cpp +++ b/src/test/analysis/CharFilterTest.cpp @@ -17,7 +17,7 @@ typedef LuceneTestFixture CharFilterTest; class CharFilter1 : public CharFilter { public: - CharFilter1(CharStreamPtr in) : CharFilter(in) + CharFilter1(const CharStreamPtr& in) : CharFilter(in) { } @@ -35,7 +35,7 @@ class CharFilter1 : public CharFilter class CharFilter2 : public CharFilter { public: - CharFilter2(CharStreamPtr in) : CharFilter(in) + CharFilter2(const CharStreamPtr& in) : CharFilter(in) { } diff --git a/src/test/analysis/StopFilterTest.cpp b/src/test/analysis/StopFilterTest.cpp index 8167a5b6..c669a1e0 100644 --- a/src/test/analysis/StopFilterTest.cpp +++ b/src/test/analysis/StopFilterTest.cpp @@ -18,7 +18,7 @@ using namespace Lucene; typedef BaseTokenStreamFixture StopFilterTest; -static void doTestStopPositons(StopFilterPtr stpf, bool enableIcrements) +static void doTestStopPositons(const StopFilterPtr& stpf, bool enableIcrements) { stpf->setEnablePositionIncrements(enableIcrements); TermAttributePtr termAtt = stpf->getAttribute(); diff --git a/src/test/analysis/TeeSinkTokenFilterTest.cpp b/src/test/analysis/TeeSinkTokenFilterTest.cpp index 8f33d6c0..ca27e297 100644 --- a/src/test/analysis/TeeSinkTokenFilterTest.cpp +++ b/src/test/analysis/TeeSinkTokenFilterTest.cpp @@ -30,7 +30,7 @@ class TheSinkFilter : public SinkFilter } public: - virtual bool accept(AttributeSourcePtr source) + virtual bool accept(const AttributeSourcePtr& source) { TermAttributePtr termAtt = source->getAttribute(); return boost::iequals(termAtt->term(), L"The"); @@ -45,7 +45,7 @@ class DogSinkFilter : public SinkFilter } public: - virtual bool accept(AttributeSourcePtr source) + virtual bool accept(const AttributeSourcePtr& source) { TermAttributePtr termAtt = source->getAttribute(); return boost::iequals(termAtt->term(), L"Dogs"); @@ -133,7 +133,7 @@ namespace TestPerformance class ModuloTokenFilter : public TokenFilter { public: - ModuloTokenFilter(TokenStreamPtr input, int32_t mc) : TokenFilter(input) + ModuloTokenFilter(const TokenStreamPtr& input, int32_t mc) : TokenFilter(input) { modCount = mc; count = 0; @@ -177,7 +177,7 @@ namespace TestPerformance int32_t count; public: - virtual bool accept(AttributeSourcePtr source) + virtual bool accept(const AttributeSourcePtr& source) { bool b = (source && count % modCount == 0); ++count; diff --git a/src/test/analysis/TokenTest.cpp b/src/test/analysis/TokenTest.cpp index baea4410..e2495a24 100644 --- a/src/test/analysis/TokenTest.cpp +++ b/src/test/analysis/TokenTest.cpp @@ -13,7 +13,7 @@ using namespace Lucene; typedef LuceneTestFixture TokenTest; -static AttributePtr checkCloneIsEqual(AttributePtr att) +static AttributePtr checkCloneIsEqual(const AttributePtr& att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); EXPECT_TRUE(att->equals(clone)); @@ -22,7 +22,7 @@ static AttributePtr checkCloneIsEqual(AttributePtr att) } template -static AttributePtr checkCopyIsEqual(AttributePtr att) +static AttributePtr checkCopyIsEqual(const AttributePtr& att) { AttributePtr copy = newLucene(); att->copyTo(copy); diff --git a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp index c7732916..d303c5c7 100644 --- a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp @@ -18,7 +18,7 @@ using namespace Lucene; typedef LuceneTestFixture SimpleAttributeTest; -static AttributePtr checkCloneIsEqual(AttributePtr att) +static AttributePtr checkCloneIsEqual(const AttributePtr& att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); EXPECT_TRUE(att->equals(clone)); @@ -27,7 +27,7 @@ static AttributePtr checkCloneIsEqual(AttributePtr att) } template -static AttributePtr checkCopyIsEqual(AttributePtr att) +static AttributePtr checkCopyIsEqual(const AttributePtr& att) { AttributePtr copy = newLucene(); att->copyTo(copy); diff --git a/src/test/analysis/tokenattributes/TermAttributeTest.cpp b/src/test/analysis/tokenattributes/TermAttributeTest.cpp index 674c1392..40d4b999 100644 --- a/src/test/analysis/tokenattributes/TermAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/TermAttributeTest.cpp @@ -13,7 +13,7 @@ using namespace Lucene; typedef LuceneTestFixture TermAttributeTest; -static AttributePtr checkCloneIsEqual(AttributePtr att) +static AttributePtr checkCloneIsEqual(const AttributePtr& att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); EXPECT_TRUE(att->equals(clone)); @@ -22,7 +22,7 @@ static AttributePtr checkCloneIsEqual(AttributePtr att) } template -static AttributePtr checkCopyIsEqual(AttributePtr att) +static AttributePtr checkCopyIsEqual(const AttributePtr& att) { AttributePtr copy = newLucene(); att->copyTo(copy); diff --git a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp index af034255..ec33363d 100644 --- a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp @@ -23,7 +23,7 @@ class BrazilianStemmerTest : public BaseTokenStreamFixture checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - void checkReuse(AnalyzerPtr a, const String& input, const String& expected) + void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } diff --git a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp index 57030136..4ffa29f3 100644 --- a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp @@ -52,7 +52,7 @@ class CJKTokenizerTest : public BaseTokenStreamFixture checkAnalyzesTo(analyzer, str, terms, startOffsets, endOffsets, types, Collection()); } - void checkCJKTokenReusable(AnalyzerPtr analyzer, const String& str, Collection out_tokens) + void checkCJKTokenReusable(const AnalyzerPtr& analyzer, const String& str, Collection out_tokens) { Collection terms = Collection::newInstance(out_tokens.size()); Collection startOffsets = Collection::newInstance(out_tokens.size()); diff --git a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp index eb9dc991..df1e6884 100644 --- a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp @@ -25,7 +25,7 @@ class JustChineseTokenizerAnalyzer : public Analyzer } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } @@ -41,7 +41,7 @@ class JustChineseFilterAnalyzer : public Analyzer } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } diff --git a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp index be9c4245..c867ba33 100644 --- a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp @@ -24,7 +24,7 @@ class GermanStemFilterTest : public BaseTokenStreamFixture checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - void checkReuse(AnalyzerPtr a, const String& input, const String& expected) + void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } diff --git a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp index 4ba8a413..2fc6e9a5 100644 --- a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp @@ -21,7 +21,7 @@ class ElisionTest : public BaseTokenStreamFixture } public: - Collection addTerms(TokenFilterPtr filter) + Collection addTerms(const TokenFilterPtr& filter) { Collection terms = Collection::newInstance(); TermAttributePtr termAtt = filter->getAttribute(); diff --git a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp index 19510245..e2e0aecf 100644 --- a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp @@ -24,7 +24,7 @@ class DutchStemmerTest : public BaseTokenStreamFixture checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - void checkReuse(AnalyzerPtr a, const String& input, const String& expected) + void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } diff --git a/src/test/contrib/highlighter/HighlighterTest.cpp b/src/test/contrib/highlighter/HighlighterTest.cpp index d2f447d7..c717a1c7 100644 --- a/src/test/contrib/highlighter/HighlighterTest.cpp +++ b/src/test/contrib/highlighter/HighlighterTest.cpp @@ -71,7 +71,7 @@ namespace HighlighterTestNS HighlighterTest* fixture; public: - virtual String highlightTerm(const String& originalText, TokenGroupPtr tokenGroup); + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); }; } @@ -150,7 +150,7 @@ class HighlighterTest : public BaseTokenStreamFixture static const String NUMERIC_FIELD_NAME; public: - void addDoc(IndexWriterPtr writer, const String& text) + void addDoc(const IndexWriterPtr& writer, const String& text) { DocumentPtr doc = newLucene(); FieldPtr field = newLucene(FIELD_NAME, text, Field::STORE_YES, Field::INDEX_ANALYZED); @@ -158,7 +158,7 @@ class HighlighterTest : public BaseTokenStreamFixture writer->addDocument(doc); } - String highlightField(QueryPtr query, const String& fieldName, const String& text) + String highlightField(const QueryPtr& query, const String& fieldName, const String& text) { TokenStreamPtr tokenStream = newLucene(TEST_VERSION)->tokenStream(fieldName, newLucene(text)); // Assuming "", "" used to highlight @@ -180,7 +180,7 @@ class HighlighterTest : public BaseTokenStreamFixture doSearching(query); } - void doSearching(QueryPtr unReWrittenQuery) + void doSearching(const QueryPtr& unReWrittenQuery) { searcher = newLucene(ramDir, true); // for any multi-term queries to work (prefix, wildcard, range,fuzzy etc) you must use a rewritten query @@ -272,7 +272,7 @@ namespace HighlighterTestNS { } - String TestFormatter::highlightTerm(const String& originalText, TokenGroupPtr tokenGroup) + String TestFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { if (tokenGroup->getTotalScore() <= 0) return originalText; @@ -309,12 +309,12 @@ namespace HighlighterTestNS FragmenterPtr frag; public: - virtual HighlighterPtr getHighlighter(QueryPtr query, const String& fieldName, TokenStreamPtr stream, FormatterPtr formatter) + virtual HighlighterPtr getHighlighter(const QueryPtr& query, const String& fieldName, const TokenStreamPtr& stream, const FormatterPtr& formatter) { return getHighlighter(query, fieldName, stream, formatter, true); } - virtual HighlighterPtr getHighlighter(QueryPtr query, const String& fieldName, TokenStreamPtr stream, FormatterPtr formatter, bool expanMultiTerm) + virtual HighlighterPtr getHighlighter(const QueryPtr& query, const String& fieldName, const TokenStreamPtr& stream, const FormatterPtr& formatter, bool expanMultiTerm) { HighlighterScorerPtr scorer; if (mode == QUERY) @@ -331,7 +331,7 @@ namespace HighlighterTestNS return newLucene(formatter, scorer); } - virtual HighlighterPtr getHighlighter(Collection weightedTerms, FormatterPtr formatter) + virtual HighlighterPtr getHighlighter(Collection weightedTerms, const FormatterPtr& formatter) { if (mode == QUERY) { @@ -347,7 +347,7 @@ namespace HighlighterTestNS return HighlighterPtr(); } - virtual void doStandardHighlights(AnalyzerPtr analyzer, IndexSearcherPtr searcher, TopDocsPtr hits, QueryPtr query, FormatterPtr formatter, Collection expected, bool expandMT = false) + virtual void doStandardHighlights(const AnalyzerPtr& analyzer, const IndexSearcherPtr& searcher, const TopDocsPtr& hits, const QueryPtr& query, const FormatterPtr& formatter, Collection expected, bool expandMT = false) { Collection results = Collection::newInstance(); @@ -1594,7 +1594,7 @@ namespace TestOverlapAnalyzer class SynonymTokenizer : public TokenStream { public: - SynonymTokenizer(TokenStreamPtr realStream, MapStringString synonyms) + SynonymTokenizer(const TokenStreamPtr& realStream, MapStringString synonyms) { this->realStream = realStream; this->synonyms = synonyms; @@ -1685,7 +1685,7 @@ namespace TestOverlapAnalyzer MapStringString synonyms; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { LowerCaseTokenizerPtr stream = newLucene(reader); stream->addAttribute(); @@ -2053,7 +2053,7 @@ namespace TestEncoding } public: - virtual void startFragment(TextFragmentPtr newFragment) + virtual void startFragment(const TextFragmentPtr& newFragment) { } @@ -2067,7 +2067,7 @@ namespace TestEncoding return 1.0; } - virtual TokenStreamPtr init(TokenStreamPtr tokenStream) + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream) { return TokenStreamPtr(); } diff --git a/src/test/contrib/memory/MemoryIndexTest.cpp b/src/test/contrib/memory/MemoryIndexTest.cpp index 034c0ee8..d2c4b229 100644 --- a/src/test/contrib/memory/MemoryIndexTest.cpp +++ b/src/test/contrib/memory/MemoryIndexTest.cpp @@ -134,7 +134,7 @@ class MemoryIndexTest : public BaseTokenStreamFixture checkAllQueries(memory, ramdir, analyzer); } - void checkAllQueries(MemoryIndexPtr memory, RAMDirectoryPtr ramdir, AnalyzerPtr analyzer) + void checkAllQueries(const MemoryIndexPtr& memory, const RAMDirectoryPtr& ramdir, const AnalyzerPtr& analyzer) { IndexSearcherPtr ram = newLucene(ramdir); IndexSearcherPtr mem = memory->createSearcher(); diff --git a/src/test/document/DocumentTest.cpp b/src/test/document/DocumentTest.cpp index 5ece9fda..b31b1d19 100644 --- a/src/test/document/DocumentTest.cpp +++ b/src/test/document/DocumentTest.cpp @@ -38,7 +38,7 @@ static DocumentPtr makeDocumentWithFields() return doc; } -static void checkDocument(DocumentPtr doc, bool fromIndex) +static void checkDocument(const DocumentPtr& doc, bool fromIndex) { Collection keywordFieldValues = doc->getValues(L"keyword"); Collection textFieldValues = doc->getValues(L"text"); diff --git a/src/test/include/BaseTestRangeFilterFixture.h b/src/test/include/BaseTestRangeFilterFixture.h index 0e2ae1fb..fc0d0367 100644 --- a/src/test/include/BaseTestRangeFilterFixture.h +++ b/src/test/include/BaseTestRangeFilterFixture.h @@ -49,7 +49,7 @@ namespace Lucene RandomPtr random; protected: - void build(TestIndexPtr index); + void build(const TestIndexPtr& index); String pad(int32_t n); }; } diff --git a/src/test/include/BaseTokenStreamFixture.h b/src/test/include/BaseTokenStreamFixture.h index 3d4e6fc4..ed4e0836 100644 --- a/src/test/include/BaseTokenStreamFixture.h +++ b/src/test/include/BaseTokenStreamFixture.h @@ -29,10 +29,10 @@ namespace Lucene bool getAndResetClearCalled(); virtual void clear(); - virtual bool equals(LuceneObjectPtr other); + virtual bool equals(const LuceneObjectPtr& other); virtual int32_t hashCode(); - virtual void copyTo(AttributePtr target); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; class BaseTokenStreamFixture : public LuceneTestFixture @@ -43,34 +43,34 @@ namespace Lucene public: // some helpers to test Analyzers and TokenStreams - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements, int32_t finalOffset = -1); - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output); - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection types); - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection posIncrements); - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets); - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset); - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - static void checkTokenStreamContents(TokenStreamPtr ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset); - - static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection types); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection posIncrements); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset); + + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements); - static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output); - static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection types); - static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements); - static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); - static void checkAnalyzesTo(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection types, Collection posIncrements); - static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output); - static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection types); - static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection posIncrements); - static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); - static void checkAnalyzesToReuse(AnalyzerPtr analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - - static void checkOneTerm(AnalyzerPtr analyzer, const String& input, const String& expected); - static void checkOneTermReuse(AnalyzerPtr analyzer, const String& input, const String& expected); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); + + static void checkOneTerm(const AnalyzerPtr& analyzer, const String& input, const String& expected); + static void checkOneTermReuse(const AnalyzerPtr& analyzer, const String& input, const String& expected); }; } diff --git a/src/test/include/CheckHits.h b/src/test/include/CheckHits.h index 8217a764..ec9e2924 100644 --- a/src/test/include/CheckHits.h +++ b/src/test/include/CheckHits.h @@ -23,35 +23,35 @@ namespace Lucene /// Tests that all documents up to maxDoc which are *not* in the expected result set, have an /// explanation which indicates no match (ie: Explanation value of 0.0) - static void checkNoMatchExplanations(QueryPtr q, const String& defaultFieldName, SearcherPtr searcher, Collection results); + static void checkNoMatchExplanations(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); /// Tests that a query matches the an expected set of documents using a HitCollector. /// /// Note that when using the HitCollector API, documents will be collected if they "match" /// regardless of what their score is. - static void checkHitCollector(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results); + static void checkHitCollector(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); /// Tests that a query matches the an expected set of documents using Hits. /// /// Note that when using the Hits API, documents will only be returned if they have a /// positive normalized score. - static void checkHits(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results); + static void checkHits(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); /// Tests that a Hits has an expected order of documents static void checkDocIds(Collection results, Collection hits); /// Tests that two queries have an expected order of documents, and that the two queries have /// the same score values. - static void checkHitsQuery(QueryPtr query, Collection hits1, Collection hits2, Collection results); - static void checkEqual(QueryPtr query, Collection hits1, Collection hits2); + static void checkHitsQuery(const QueryPtr& query, Collection hits1, Collection hits2, Collection results); + static void checkEqual(const QueryPtr& query, Collection hits1, Collection hits2); /// Asserts that the explanation value for every document matching a query corresponds with the true score. /// Optionally does "deep" testing of the explanation details. - static void checkExplanations(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, bool deep = false); + static void checkExplanations(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, bool deep = false); /// Assert that an explanation has the expected score, and optionally that its sub-details max/sum/factor /// match to that score. - static void verifyExplanation(const String& q, int32_t doc, double score, bool deep, ExplanationPtr expl); + static void verifyExplanation(const String& q, int32_t doc, double score, bool deep, const ExplanationPtr& expl); }; } diff --git a/src/test/include/DocHelper.h b/src/test/include/DocHelper.h index 90c2c8e0..fb95f063 100644 --- a/src/test/include/DocHelper.h +++ b/src/test/include/DocHelper.h @@ -94,15 +94,15 @@ namespace Lucene public: /// Adds the fields above to a document - void setupDoc(DocumentPtr doc); + void setupDoc(const DocumentPtr& doc); /// Writes the document to the directory using a segment named "test"; returns the SegmentInfo describing the new segment - SegmentInfoPtr writeDoc(DirectoryPtr dir, DocumentPtr doc); + SegmentInfoPtr writeDoc(const DirectoryPtr& dir, const DocumentPtr& doc); /// Writes the document to the directory using the analyzer and the similarity score; returns the SegmentInfo describing the new segment - SegmentInfoPtr writeDoc(DirectoryPtr dir, AnalyzerPtr analyzer, SimilarityPtr similarity, DocumentPtr doc); + SegmentInfoPtr writeDoc(const DirectoryPtr& dir, const AnalyzerPtr& analyzer, const SimilarityPtr& similarity, const DocumentPtr& doc); - int32_t numFields(DocumentPtr doc); + int32_t numFields(const DocumentPtr& doc); protected: /// One-time setup to initialise static members diff --git a/src/test/include/ExplanationsFixture.h b/src/test/include/ExplanationsFixture.h index 9c4d684d..1ffb336b 100644 --- a/src/test/include/ExplanationsFixture.h +++ b/src/test/include/ExplanationsFixture.h @@ -29,27 +29,27 @@ namespace Lucene public: virtual SpanTermQueryPtr st(const String& s); virtual SpanFirstQueryPtr sf(const String& s, int32_t b); - virtual SpanNotQueryPtr snot(SpanQueryPtr i, SpanQueryPtr e); + virtual SpanNotQueryPtr snot(const SpanQueryPtr& i, const SpanQueryPtr& e); virtual SpanOrQueryPtr sor(const String& s, const String& e); - virtual SpanOrQueryPtr sor(SpanQueryPtr s, SpanQueryPtr e); + virtual SpanOrQueryPtr sor(const SpanQueryPtr& s, const SpanQueryPtr& e); virtual SpanOrQueryPtr sor(const String& s, const String& m, const String& e); - virtual SpanOrQueryPtr sor(SpanQueryPtr s, SpanQueryPtr m, SpanQueryPtr e); + virtual SpanOrQueryPtr sor(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e); virtual SpanNearQueryPtr snear(const String& s, const String& e, int32_t slop, bool inOrder); - virtual SpanNearQueryPtr snear(SpanQueryPtr s, SpanQueryPtr e, int32_t slop, bool inOrder); + virtual SpanNearQueryPtr snear(const SpanQueryPtr& s, const SpanQueryPtr& e, int32_t slop, bool inOrder); virtual SpanNearQueryPtr snear(const String& s, const String& m, const String& e, int32_t slop, bool inOrder); - virtual SpanNearQueryPtr snear(SpanQueryPtr s, SpanQueryPtr m, SpanQueryPtr e, int32_t slop, bool inOrder); + virtual SpanNearQueryPtr snear(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e, int32_t slop, bool inOrder); virtual QueryPtr optB(const String& q); - virtual QueryPtr optB(QueryPtr q); + virtual QueryPtr optB(const QueryPtr& q); virtual QueryPtr reqB(const String& q); - virtual QueryPtr reqB(QueryPtr q); + virtual QueryPtr reqB(const QueryPtr& q); virtual Collection ta(Collection s); /// Check the expDocNrs first, then check the query (and the explanations) virtual void qtest(const String& queryText, Collection expDocNrs); - virtual void qtest(QueryPtr q, Collection expDocNrs); + virtual void qtest(const QueryPtr& q, Collection expDocNrs); /// Tests a query using qtest after wrapping it with both optB and reqB - virtual void bqtest(QueryPtr q, Collection expDocNrs); + virtual void bqtest(const QueryPtr& q, Collection expDocNrs); virtual void bqtest(const String& queryText, Collection expDocNrs); virtual QueryPtr makeQuery(const String& queryText); diff --git a/src/test/include/FunctionFixture.h b/src/test/include/FunctionFixture.h index 74f222c6..0acfe623 100644 --- a/src/test/include/FunctionFixture.h +++ b/src/test/include/FunctionFixture.h @@ -35,7 +35,7 @@ namespace Lucene protected: static const Collection DOC_TEXT_LINES(); - void addDoc(IndexWriterPtr iw, int32_t i); + void addDoc(const IndexWriterPtr& iw, int32_t i); String id2String(int32_t scoreAndID); String textLine(int32_t docNum); diff --git a/src/test/include/MockFilter.h b/src/test/include/MockFilter.h index d45c0e11..eb06e03f 100644 --- a/src/test/include/MockFilter.h +++ b/src/test/include/MockFilter.h @@ -24,7 +24,7 @@ namespace Lucene bool _wasCalled; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader); + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); void clear(); bool wasCalled(); diff --git a/src/test/include/MockRAMDirectory.h b/src/test/include/MockRAMDirectory.h index e7c47f37..c16eba1d 100644 --- a/src/test/include/MockRAMDirectory.h +++ b/src/test/include/MockRAMDirectory.h @@ -17,7 +17,7 @@ namespace Lucene { public: MockRAMDirectory(); - MockRAMDirectory(DirectoryPtr dir); + MockRAMDirectory(const DirectoryPtr& dir); virtual ~MockRAMDirectory(); LUCENE_CLASS(MockRAMDirectory); @@ -90,7 +90,7 @@ namespace Lucene virtual void close(); /// Add a Failure object to the list of objects to be evaluated at every potential failure point - void failOn(MockDirectoryFailurePtr fail); + void failOn(const MockDirectoryFailurePtr& fail); /// Iterate through the failures list, giving each object a chance to throw an IO exception. void maybeThrowDeterministicException(); @@ -114,7 +114,7 @@ namespace Lucene public: /// eval is called on the first write of every new file. - virtual void eval(MockRAMDirectoryPtr dir); + virtual void eval(const MockRAMDirectoryPtr& dir); /// reset should set the state of the failure to its default (freshly constructed) state. Reset is convenient /// for tests that want to create one failure object and then reuse it in multiple cases. This, combined with diff --git a/src/test/include/MockRAMInputStream.h b/src/test/include/MockRAMInputStream.h index cc00c8fe..742d2ab7 100644 --- a/src/test/include/MockRAMInputStream.h +++ b/src/test/include/MockRAMInputStream.h @@ -18,7 +18,7 @@ namespace Lucene public: /// Construct an empty output buffer. MockRAMInputStream(); - MockRAMInputStream(MockRAMDirectoryPtr dir, const String& name, RAMFilePtr f); + MockRAMInputStream(const MockRAMDirectoryPtr& dir, const String& name, const RAMFilePtr& f); virtual ~MockRAMInputStream(); LUCENE_CLASS(MockRAMInputStream); @@ -31,7 +31,7 @@ namespace Lucene public: virtual void close(); - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); }; } diff --git a/src/test/include/MockRAMOutputStream.h b/src/test/include/MockRAMOutputStream.h index 365b305b..78933aee 100644 --- a/src/test/include/MockRAMOutputStream.h +++ b/src/test/include/MockRAMOutputStream.h @@ -18,7 +18,7 @@ namespace Lucene { public: /// Construct an empty output buffer. - MockRAMOutputStream(MockRAMDirectoryPtr dir, RAMFilePtr f, const String& name); + MockRAMOutputStream(const MockRAMDirectoryPtr& dir, const RAMFilePtr& f, const String& name); virtual ~MockRAMOutputStream(); LUCENE_CLASS(MockRAMOutputStream); diff --git a/src/test/include/PayloadHelper.h b/src/test/include/PayloadHelper.h index aa9a7f4e..f0638a41 100644 --- a/src/test/include/PayloadHelper.h +++ b/src/test/include/PayloadHelper.h @@ -28,7 +28,7 @@ namespace Lucene /// Sets up a RAMDirectory, and adds documents (using intToEnglish()) with two fields: field and multiField /// and analyzes them using the PayloadHelperAnalyzer - static IndexSearcherPtr setUp(SimilarityPtr similarity, int32_t numDocs); + static IndexSearcherPtr setUp(const SimilarityPtr& similarity, int32_t numDocs); }; } diff --git a/src/test/include/QueryUtils.h b/src/test/include/QueryUtils.h index 1c77c3ab..6869918e 100644 --- a/src/test/include/QueryUtils.h +++ b/src/test/include/QueryUtils.h @@ -18,21 +18,21 @@ namespace Lucene public: /// Check the types of things query objects should be able to do. - static void check(QueryPtr q); + static void check(const QueryPtr& q); /// Check very basic hashCode and equals - static void checkHashEquals(QueryPtr q); + static void checkHashEquals(const QueryPtr& q); - static void checkEqual(QueryPtr q1, QueryPtr q2); - static void checkUnequal(QueryPtr q1, QueryPtr q2); + static void checkEqual(const QueryPtr& q1, const QueryPtr& q2); + static void checkUnequal(const QueryPtr& q1, const QueryPtr& q2); /// Deep check that explanations of a query 'score' correctly - static void checkExplanations(QueryPtr q, SearcherPtr s); + static void checkExplanations(const QueryPtr& q, const SearcherPtr& s); /// Various query sanity checks on a searcher, some checks are only done /// for types of IndexSearcher. - static void check(QueryPtr q1, SearcherPtr s); - static void check(QueryPtr q1, SearcherPtr s, bool wrap); + static void check(const QueryPtr& q1, const SearcherPtr& s); + static void check(const QueryPtr& q1, const SearcherPtr& s, bool wrap); /// Given an IndexSearcher, returns a new IndexSearcher whose IndexReader is a MultiReader /// containing the Reader of the original IndexSearcher, as well as several "empty" @@ -41,7 +41,7 @@ namespace Lucene /// @param s the searcher to wrap. /// @param edge if negative, s will be the first sub; if 0, s will be in the middle, if /// positive s will be the last sub - static IndexSearcherPtr wrapUnderlyingReader(IndexSearcherPtr s, int32_t edge); + static IndexSearcherPtr wrapUnderlyingReader(const IndexSearcherPtr& s, int32_t edge); /// Given a Searcher, returns a new MultiSearcher wrapping the the original Searcher, as well /// as several "empty" IndexSearchers - some of which will have deleted documents in them. @@ -49,16 +49,16 @@ namespace Lucene /// @param s the Searcher to wrap /// @param edge if negative, s will be the first sub; if 0, s will be in hte middle, if positive /// s will be the last sub - static MultiSearcherPtr wrapSearcher(SearcherPtr s, int32_t edge); + static MultiSearcherPtr wrapSearcher(const SearcherPtr& s, int32_t edge); static RAMDirectoryPtr makeEmptyIndex(int32_t numDeletedDocs); /// Alternate scorer skipTo(), skipTo(), next(), next(), skipTo(), skipTo(), etc and ensure /// a hitcollector receives same docs and scores - static void checkSkipTo(QueryPtr q, IndexSearcherPtr s); + static void checkSkipTo(const QueryPtr& q, const IndexSearcherPtr& s); /// Check that first skip on just created scorers always goes to the right doc - static void checkFirstSkipTo(QueryPtr q, IndexSearcherPtr s); + static void checkFirstSkipTo(const QueryPtr& q, const IndexSearcherPtr& s); }; } diff --git a/src/test/include/TestUtils.h b/src/test/include/TestUtils.h index 33badb46..3d4dddf9 100644 --- a/src/test/include/TestUtils.h +++ b/src/test/include/TestUtils.h @@ -24,10 +24,10 @@ namespace Lucene String getTempDir(const String& desc); /// Wait for concurrent merge to finish - void syncConcurrentMerges(IndexWriterPtr writer); + void syncConcurrentMerges(const IndexWriterPtr& writer); /// Wait for concurrent merge to finish - void syncConcurrentMerges(MergeSchedulerPtr ms); + void syncConcurrentMerges(const MergeSchedulerPtr& ms); /// Return English representation of given integer String intToEnglish(int32_t i); @@ -37,7 +37,7 @@ namespace Lucene /// This runs the CheckIndex tool on the index in. /// If any issues are hit, a RuntimeException is thrown; else, true is returned. - bool checkIndex(DirectoryPtr dir); + bool checkIndex(const DirectoryPtr& dir); } #endif diff --git a/src/test/index/AddIndexesNoOptimizeTest.cpp b/src/test/index/AddIndexesNoOptimizeTest.cpp index 309eb5bb..50fe6e6b 100644 --- a/src/test/index/AddIndexesNoOptimizeTest.cpp +++ b/src/test/index/AddIndexesNoOptimizeTest.cpp @@ -24,14 +24,14 @@ using namespace Lucene; typedef LuceneTestFixture AddIndexesNoOptimizeTest; -static IndexWriterPtr newWriter(DirectoryPtr dir, bool create) +static IndexWriterPtr newWriter(const DirectoryPtr& dir, bool create) { IndexWriterPtr writer = newLucene(dir, newLucene(), create, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMergePolicy(newLucene(writer)); return writer; } -static void addDocs(IndexWriterPtr writer, int32_t numDocs) +static void addDocs(const IndexWriterPtr& writer, int32_t numDocs) { for (int32_t i = 0; i < numDocs; ++i) { @@ -41,7 +41,7 @@ static void addDocs(IndexWriterPtr writer, int32_t numDocs) } } -static void addDocs2(IndexWriterPtr writer, int32_t numDocs) +static void addDocs2(const IndexWriterPtr& writer, int32_t numDocs) { for (int32_t i = 0; i < numDocs; ++i) { @@ -51,7 +51,7 @@ static void addDocs2(IndexWriterPtr writer, int32_t numDocs) } } -static void verifyNumDocs(DirectoryPtr dir, int32_t numDocs) +static void verifyNumDocs(const DirectoryPtr& dir, int32_t numDocs) { IndexReaderPtr reader = IndexReader::open(dir, true); EXPECT_EQ(reader->maxDoc(), numDocs); @@ -59,7 +59,7 @@ static void verifyNumDocs(DirectoryPtr dir, int32_t numDocs) reader->close(); } -static void verifyTermDocs(DirectoryPtr dir, TermPtr term, int32_t numDocs) +static void verifyTermDocs(const DirectoryPtr& dir, const TermPtr& term, int32_t numDocs) { IndexReaderPtr reader = IndexReader::open(dir, true); TermDocsPtr termDocs = reader->termDocs(term); @@ -70,7 +70,7 @@ static void verifyTermDocs(DirectoryPtr dir, TermPtr term, int32_t numDocs) reader->close(); } -static void setUpDirs(DirectoryPtr dir, DirectoryPtr aux) +static void setUpDirs(const DirectoryPtr& dir, const DirectoryPtr& aux) { IndexWriterPtr writer; diff --git a/src/test/index/AtomicUpdateTest.cpp b/src/test/index/AtomicUpdateTest.cpp index 81f18a10..0a4200d0 100644 --- a/src/test/index/AtomicUpdateTest.cpp +++ b/src/test/index/AtomicUpdateTest.cpp @@ -27,7 +27,7 @@ typedef LuceneTestFixture AtomicUpdateTest; class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr dir, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) + MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) { random = newLucene(); } @@ -97,7 +97,7 @@ const int32_t AtomicTimedThread::RUN_TIME_SEC = 3; class AtomicIndexerThread : public AtomicTimedThread { public: - AtomicIndexerThread(IndexWriterPtr writer) + AtomicIndexerThread(const IndexWriterPtr& writer) { this->writer = writer; } @@ -128,7 +128,7 @@ class AtomicIndexerThread : public AtomicTimedThread class AtomicSearcherThread : public AtomicTimedThread { public: - AtomicSearcherThread(DirectoryPtr directory) + AtomicSearcherThread(const DirectoryPtr& directory) { this->directory = directory; } @@ -153,7 +153,7 @@ class AtomicSearcherThread : public AtomicTimedThread }; // Run one indexer and 2 searchers against single index as stress test. -static void runTest(DirectoryPtr directory) +static void runTest(const DirectoryPtr& directory) { Collection threads(Collection::newInstance(4)); AnalyzerPtr analyzer = newLucene(); diff --git a/src/test/index/BackwardsCompatibilityTest.cpp b/src/test/index/BackwardsCompatibilityTest.cpp index 8277fa22..dfeff8ee 100644 --- a/src/test/index/BackwardsCompatibilityTest.cpp +++ b/src/test/index/BackwardsCompatibilityTest.cpp @@ -45,7 +45,7 @@ static void rmDir(const String& dirName) FileUtils::removeDirectory(FileUtils::joinPath(getTempDir(), dirName)); } -static void addDoc(IndexWriterPtr writer, int32_t id) +static void addDoc(const IndexWriterPtr& writer, int32_t id) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -68,7 +68,7 @@ static void addDoc(IndexWriterPtr writer, int32_t id) writer->addDocument(doc); } -static void addNoProxDoc(IndexWriterPtr writer) +static void addNoProxDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"content3", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED); @@ -159,7 +159,7 @@ namespace CheckCompressedFields }; } -void checkCompressedFields29(DirectoryPtr dir, bool shouldStillBeCompressed) +void checkCompressedFields29(const DirectoryPtr& dir, bool shouldStillBeCompressed) { int32_t count = 0; static String TEXT_TO_COMPRESS = L"this is a compressed field and should appear in 3.0 as an uncompressed field after merge"; @@ -238,7 +238,7 @@ void checkCompressedFields29(DirectoryPtr dir, bool shouldStillBeCompressed) finally.throwException(); } -static void testHits(Collection hits, int32_t expectedCount, IndexReaderPtr reader) +static void testHits(Collection hits, int32_t expectedCount, const IndexReaderPtr& reader) { int32_t hitCount = hits.size(); EXPECT_EQ(expectedCount, hitCount); diff --git a/src/test/index/CompoundFileTest.cpp b/src/test/index/CompoundFileTest.cpp index fc5c7d39..fc383f9b 100644 --- a/src/test/index/CompoundFileTest.cpp +++ b/src/test/index/CompoundFileTest.cpp @@ -43,7 +43,7 @@ class CompoundFileTest : public LuceneTestFixture public: /// Creates a file of the specified size with random data. - void createRandomFile(DirectoryPtr dir, const String& name, int32_t size) + void createRandomFile(const DirectoryPtr& dir, const String& name, int32_t size) { IndexOutputPtr os = dir->createOutput(name); RandomPtr r = newLucene(); @@ -52,7 +52,7 @@ class CompoundFileTest : public LuceneTestFixture os->close(); } - void createSequenceFile(DirectoryPtr dir, const String& name, uint8_t start, int32_t size) + void createSequenceFile(const DirectoryPtr& dir, const String& name, uint8_t start, int32_t size) { IndexOutputPtr os = dir->createOutput(name); for (int32_t i = 0; i < size; ++i) @@ -63,7 +63,7 @@ class CompoundFileTest : public LuceneTestFixture os->close(); } - void checkSameStreams(IndexInputPtr expected, IndexInputPtr test) + void checkSameStreams(const IndexInputPtr& expected, const IndexInputPtr& test) { EXPECT_TRUE(expected); EXPECT_TRUE(test); @@ -84,7 +84,7 @@ class CompoundFileTest : public LuceneTestFixture } } - void checkSameStreams(IndexInputPtr expected, IndexInputPtr actual, int64_t seekTo) + void checkSameStreams(const IndexInputPtr& expected, const IndexInputPtr& actual, int64_t seekTo) { if (seekTo >= 0 && seekTo < (int64_t)expected->length()) { @@ -94,7 +94,7 @@ class CompoundFileTest : public LuceneTestFixture } } - void checkSameSeekBehavior(IndexInputPtr expected, IndexInputPtr actual) + void checkSameSeekBehavior(const IndexInputPtr& expected, const IndexInputPtr& actual) { // seek to 0 int64_t point = 0; @@ -143,7 +143,7 @@ class CompoundFileTest : public LuceneTestFixture cw->close(); } - bool isCSIndexInputOpen(IndexInputPtr is) + bool isCSIndexInputOpen(const IndexInputPtr& is) { if (MiscUtils::typeOf(is)) { @@ -154,7 +154,7 @@ class CompoundFileTest : public LuceneTestFixture return false; } - bool isSimpleFSIndexInputOpen(IndexInputPtr is) + bool isSimpleFSIndexInputOpen(const IndexInputPtr& is) { if (MiscUtils::typeOf(is)) { diff --git a/src/test/index/ConcurrentMergeSchedulerTest.cpp b/src/test/index/ConcurrentMergeSchedulerTest.cpp index a9475d2e..fa726b58 100644 --- a/src/test/index/ConcurrentMergeSchedulerTest.cpp +++ b/src/test/index/ConcurrentMergeSchedulerTest.cpp @@ -31,7 +31,7 @@ static bool mergeCalled = false; static bool mergeThreadCreated = false; static bool excCalled = false; -static void checkNoUnreferencedFiles(DirectoryPtr dir) +static void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); @@ -83,7 +83,7 @@ namespace TestFlushException this->doFail = false; } - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (this->doFail && mainThread == LuceneThread::currentId() && TestPoint::getTestPoint(L"doFlush")) { @@ -98,7 +98,7 @@ namespace TestFlushException class TestableIndexWriter : public IndexWriter { public: - TestableIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { } @@ -308,7 +308,7 @@ namespace TestSubclassConcurrentMergeScheduler } public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (TestPoint::getTestPoint(L"doMerge")) boost::throw_exception(IOException(L"now failing during merge")); @@ -318,7 +318,7 @@ namespace TestSubclassConcurrentMergeScheduler class MyMergeThread : public MergeThread { public: - MyMergeThread(ConcurrentMergeSchedulerPtr merger, IndexWriterPtr writer, OneMergePtr startMerge) : MergeThread(merger, writer, startMerge) + MyMergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge) : MergeThread(merger, writer, startMerge) { mergeThreadCreated = true; } @@ -338,7 +338,7 @@ namespace TestSubclassConcurrentMergeScheduler LUCENE_CLASS(MyMergeScheduler); protected: - virtual MergeThreadPtr getMergeThread(IndexWriterPtr writer, OneMergePtr merge) + virtual MergeThreadPtr getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge) { MergeThreadPtr thread = newLucene(shared_from_this(), writer, merge); thread->setThreadPriority(getMergeThreadPriority()); @@ -350,7 +350,7 @@ namespace TestSubclassConcurrentMergeScheduler excCalled = true; } - virtual void doMerge(OneMergePtr merge) + virtual void doMerge(const OneMergePtr& merge) { mergeCalled = true; ConcurrentMergeScheduler::doMerge(merge); diff --git a/src/test/index/CrashTest.cpp b/src/test/index/CrashTest.cpp index 714cda01..0ad262de 100644 --- a/src/test/index/CrashTest.cpp +++ b/src/test/index/CrashTest.cpp @@ -20,7 +20,7 @@ using namespace Lucene; typedef LuceneTestFixture CrashTest; -static IndexWriterPtr initIndex(MockRAMDirectoryPtr dir) +static IndexWriterPtr initIndex(const MockRAMDirectoryPtr& dir) { dir->setLockFactory(NoLockFactory::getNoLockFactory()); @@ -43,7 +43,7 @@ static IndexWriterPtr initIndex() return initIndex(newLucene()); } -static void crash(IndexWriterPtr writer) +static void crash(const IndexWriterPtr& writer) { MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); ConcurrentMergeSchedulerPtr cms = boost::dynamic_pointer_cast(writer->getMergeScheduler()); diff --git a/src/test/index/DeletionPolicyTest.cpp b/src/test/index/DeletionPolicyTest.cpp index 768b6eb5..4f4d1674 100644 --- a/src/test/index/DeletionPolicyTest.cpp +++ b/src/test/index/DeletionPolicyTest.cpp @@ -53,7 +53,7 @@ static void verifyCommitOrder(Collection commits) } } -static void addDoc(IndexWriterPtr writer) +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -212,7 +212,7 @@ class KeepLastNDeletionPolicy : public IndexDeletionPolicy class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy { public: - ExpirationTimeDeletionPolicy(DirectoryPtr dir, double seconds) + ExpirationTimeDeletionPolicy(const DirectoryPtr& dir, double seconds) { this->dir = dir; this->expirationTimeSeconds = seconds; diff --git a/src/test/index/DirectoryReaderTest.cpp b/src/test/index/DirectoryReaderTest.cpp index 6f3212fa..0bb6653a 100644 --- a/src/test/index/DirectoryReaderTest.cpp +++ b/src/test/index/DirectoryReaderTest.cpp @@ -122,7 +122,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper return reader; } - void checkNorms(IndexReaderPtr reader) + void checkNorms(const IndexReaderPtr& reader) { for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) { @@ -145,7 +145,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper } } - void addDoc(RAMDirectoryPtr ramDir1, const String& s, bool create) + void addDoc(const RAMDirectoryPtr& ramDir1, const String& s, bool create) { IndexWriterPtr iw = newLucene(ramDir1, newLucene(LuceneVersion::LUCENE_CURRENT), create, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); diff --git a/src/test/index/DocHelper.cpp b/src/test/index/DocHelper.cpp index 0328d4b7..d37ad77c 100644 --- a/src/test/index/DocHelper.cpp +++ b/src/test/index/DocHelper.cpp @@ -212,18 +212,18 @@ namespace Lucene } } - void DocHelper::setupDoc(DocumentPtr doc) + void DocHelper::setupDoc(const DocumentPtr& doc) { for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) doc->add(*field); } - SegmentInfoPtr DocHelper::writeDoc(DirectoryPtr dir, DocumentPtr doc) + SegmentInfoPtr DocHelper::writeDoc(const DirectoryPtr& dir, const DocumentPtr& doc) { return writeDoc(dir, newLucene(), Similarity::getDefault(), doc); } - SegmentInfoPtr DocHelper::writeDoc(DirectoryPtr dir, AnalyzerPtr analyzer, SimilarityPtr similarity, DocumentPtr doc) + SegmentInfoPtr DocHelper::writeDoc(const DirectoryPtr& dir, const AnalyzerPtr& analyzer, const SimilarityPtr& similarity, const DocumentPtr& doc) { IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); writer->setSimilarity(similarity); @@ -234,7 +234,7 @@ namespace Lucene return info; } - int32_t DocHelper::numFields(DocumentPtr doc) + int32_t DocHelper::numFields(const DocumentPtr& doc) { return doc->getFields().size(); } diff --git a/src/test/index/DocTest.cpp b/src/test/index/DocTest.cpp index 0a69157c..dfb33cb3 100644 --- a/src/test/index/DocTest.cpp +++ b/src/test/index/DocTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; typedef LuceneTestFixture DocTest; -static SegmentInfoPtr indexDoc(IndexWriterPtr writer, const String& fileName) +static SegmentInfoPtr indexDoc(const IndexWriterPtr& writer, const String& fileName) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"contents", newLucene(FileUtils::joinPath(getTestDir(), fileName)))); @@ -34,7 +34,7 @@ static SegmentInfoPtr indexDoc(IndexWriterPtr writer, const String& fileName) return writer->newestSegment(); } -static void printSegment(StringStream& out, SegmentInfoPtr si) +static void printSegment(StringStream& out, const SegmentInfoPtr& si) { SegmentReaderPtr reader = SegmentReader::get(true, si, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); @@ -72,7 +72,7 @@ static void printSegment(StringStream& out, SegmentInfoPtr si) reader->close(); } -static SegmentInfoPtr merge(SegmentInfoPtr si1, SegmentInfoPtr si2, const String& merged, bool useCompoundFile) +static SegmentInfoPtr merge(const SegmentInfoPtr& si1, const SegmentInfoPtr& si2, const String& merged, bool useCompoundFile) { SegmentReaderPtr r1 = SegmentReader::get(true, si1, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); SegmentReaderPtr r2 = SegmentReader::get(true, si2, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); diff --git a/src/test/index/DocumentWriterTest.cpp b/src/test/index/DocumentWriterTest.cpp index b5add550..90c03315 100644 --- a/src/test/index/DocumentWriterTest.cpp +++ b/src/test/index/DocumentWriterTest.cpp @@ -106,7 +106,7 @@ namespace TestPositionIncrementGap LUCENE_CLASS(TestableAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } @@ -151,7 +151,7 @@ namespace TestTokenReuse class TestableTokenFilter : public TokenFilter { public: - TestableTokenFilter(ReaderPtr reader) : TokenFilter(newLucene(reader)) + TestableTokenFilter(const ReaderPtr& reader) : TokenFilter(newLucene(reader)) { first = true; termAtt = addAttribute(); @@ -217,7 +217,7 @@ namespace TestTokenReuse LUCENE_CLASS(TestableAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } diff --git a/src/test/index/FieldsReaderTest.cpp b/src/test/index/FieldsReaderTest.cpp index 30d7915c..24f46869 100644 --- a/src/test/index/FieldsReaderTest.cpp +++ b/src/test/index/FieldsReaderTest.cpp @@ -61,7 +61,7 @@ DECLARE_SHARED_PTR(FaultyIndexInput) class FaultyIndexInput : public BufferedIndexInput { public: - FaultyIndexInput(IndexInputPtr delegate) + FaultyIndexInput(const IndexInputPtr& delegate) { this->delegate = delegate; count = 0; @@ -100,7 +100,7 @@ class FaultyIndexInput : public BufferedIndexInput delegate->close(); } - virtual LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(delegate->clone())); } diff --git a/src/test/index/FilterIndexReaderTest.cpp b/src/test/index/FilterIndexReaderTest.cpp index da2fb093..78c6e663 100644 --- a/src/test/index/FilterIndexReaderTest.cpp +++ b/src/test/index/FilterIndexReaderTest.cpp @@ -27,7 +27,7 @@ DECLARE_SHARED_PTR(TestTermPositions) class TestTermEnum : public FilterTermEnum { public: - TestTermEnum(TermEnumPtr termEnum) : FilterTermEnum(termEnum) + TestTermEnum(const TermEnumPtr& termEnum) : FilterTermEnum(termEnum) { } @@ -53,7 +53,7 @@ class TestTermEnum : public FilterTermEnum class TestTermPositions : public FilterTermPositions { public: - TestTermPositions(TermPositionsPtr in) : FilterTermPositions(in) + TestTermPositions(const TermPositionsPtr& in) : FilterTermPositions(in) { } @@ -78,7 +78,7 @@ class TestTermPositions : public FilterTermPositions class TestReader : public FilterIndexReader { public: - TestReader(IndexReaderPtr reader) : FilterIndexReader(reader) + TestReader(const IndexReaderPtr& reader) : FilterIndexReader(reader) { } diff --git a/src/test/index/IndexCommitTest.cpp b/src/test/index/IndexCommitTest.cpp index 2e547d2b..b38049b7 100644 --- a/src/test/index/IndexCommitTest.cpp +++ b/src/test/index/IndexCommitTest.cpp @@ -18,7 +18,7 @@ namespace TestEqualsHashCode class TestIndexCommit1 : public IndexCommit { public: - TestIndexCommit1(DirectoryPtr dir) + TestIndexCommit1(const DirectoryPtr& dir) { this->dir = dir; } @@ -84,7 +84,7 @@ namespace TestEqualsHashCode class TestIndexCommit2 : public TestIndexCommit1 { public: - TestIndexCommit2(DirectoryPtr dir) : TestIndexCommit1(dir) + TestIndexCommit2(const DirectoryPtr& dir) : TestIndexCommit1(dir) { } diff --git a/src/test/index/IndexFileDeleterTest.cpp b/src/test/index/IndexFileDeleterTest.cpp index da61a68e..e2596454 100644 --- a/src/test/index/IndexFileDeleterTest.cpp +++ b/src/test/index/IndexFileDeleterTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; typedef LuceneTestFixture IndexFileDeleterTest; -static void addDoc(IndexWriterPtr writer, int32_t id) +static void addDoc(const IndexWriterPtr& writer, int32_t id) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -33,7 +33,7 @@ static void addDoc(IndexWriterPtr writer, int32_t id) writer->addDocument(doc); } -static void copyFile(DirectoryPtr dir, const String& src, const String& dest) +static void copyFile(const DirectoryPtr& dir, const String& src, const String& dest) { IndexInputPtr in = dir->openInput(src); IndexOutputPtr out = dir->createOutput(dest); diff --git a/src/test/index/IndexReaderCloneNormsTest.cpp b/src/test/index/IndexReaderCloneNormsTest.cpp index e4492df4..2a15996e 100644 --- a/src/test/index/IndexReaderCloneNormsTest.cpp +++ b/src/test/index/IndexReaderCloneNormsTest.cpp @@ -64,7 +64,7 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture double normDelta; public: - void createIndex(DirectoryPtr dir) + void createIndex(const DirectoryPtr& dir) { IndexWriterPtr iw = newLucene(dir, anlzr, true, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); @@ -74,7 +74,7 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture iw->close(); } - void createIndex(DirectoryPtr dir, bool multiSegment) + void createIndex(const DirectoryPtr& dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -116,7 +116,7 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture } /// try cloning and reopening the norms - void doTestNorms(DirectoryPtr dir) + void doTestNorms(const DirectoryPtr& dir) { addDocs(dir, 12, true); IndexReaderPtr ir = IndexReader::open(dir, false); @@ -135,13 +135,13 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture irc3->close(); } - void modifyNormsForF1(DirectoryPtr dir) + void modifyNormsForF1(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); modifyNormsForF1(ir); } - void modifyNormsForF1(IndexReaderPtr ir) + void modifyNormsForF1(const IndexReaderPtr& ir) { int32_t n = ir->maxDoc(); for (int32_t i = 0; i < n; i += 3) // modify for every third doc @@ -156,7 +156,7 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture } } - void addDocs(DirectoryPtr dir, int32_t ndocs, bool compound) + void addDocs(const DirectoryPtr& dir, int32_t ndocs, bool compound) { IndexWriterPtr iw = newLucene(dir, anlzr, false, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); @@ -203,14 +203,14 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture return norm; } - void verifyIndex(DirectoryPtr dir) + void verifyIndex(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); verifyIndex(ir); ir->close(); } - void verifyIndex(IndexReaderPtr ir) + void verifyIndex(const IndexReaderPtr& ir) { for (int32_t i = 0; i < NUM_FIELDS; ++i) { diff --git a/src/test/index/IndexReaderCloneTest.cpp b/src/test/index/IndexReaderCloneTest.cpp index 62ec8e95..2b7c71e5 100644 --- a/src/test/index/IndexReaderCloneTest.cpp +++ b/src/test/index/IndexReaderCloneTest.cpp @@ -45,7 +45,7 @@ static DocumentPtr createDocument(int32_t n, int32_t numFields) return doc; } -static void createIndex(DirectoryPtr dir, bool multiSegment) +static void createIndex(const DirectoryPtr& dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -72,12 +72,12 @@ static void createIndex(DirectoryPtr dir, bool multiSegment) r->close(); } -static bool isReadOnly(IndexReaderPtr r) +static bool isReadOnly(const IndexReaderPtr& r) { return (MiscUtils::typeOf(r) || MiscUtils::typeOf(r)); } -static bool deleteWorked(int32_t doc, IndexReaderPtr r) +static bool deleteWorked(int32_t doc, const IndexReaderPtr& r) { bool exception = false; try @@ -98,7 +98,7 @@ static bool deleteWorked(int32_t doc, IndexReaderPtr r) /// 4. Verify the norms are not the same on each reader /// 5. Verify the doc deleted is only in the cloned reader /// 6. Try to delete a document in the original reader, an exception should be thrown -static void performDefaultTests(IndexReaderPtr r1) +static void performDefaultTests(const IndexReaderPtr& r1) { double norm1 = Similarity::decodeNorm(r1->norms(L"field1")[4]); @@ -123,7 +123,7 @@ static void performDefaultTests(IndexReaderPtr r1) pr1Clone->close(); } -static void modifyIndex(int32_t i, DirectoryPtr dir) +static void modifyIndex(int32_t i, const DirectoryPtr& dir) { switch (i) { @@ -179,12 +179,12 @@ static void modifyIndex(int32_t i, DirectoryPtr dir) } } -static void checkDelDocsRefCountEquals(int32_t refCount, SegmentReaderPtr reader) +static void checkDelDocsRefCountEquals(int32_t refCount, const SegmentReaderPtr& reader) { EXPECT_EQ(refCount, reader->deletedDocsRef->refCount()); } -static void checkDocDeleted(SegmentReaderPtr reader, SegmentReaderPtr reader2, int32_t doc) +static void checkDocDeleted(const SegmentReaderPtr& reader, const SegmentReaderPtr& reader2, int32_t doc) { EXPECT_EQ(reader->isDeleted(doc), reader2->isDeleted(doc)); } diff --git a/src/test/index/IndexReaderReopenTest.cpp b/src/test/index/IndexReaderReopenTest.cpp index 6d5cc2d7..5e9af7cf 100644 --- a/src/test/index/IndexReaderReopenTest.cpp +++ b/src/test/index/IndexReaderReopenTest.cpp @@ -63,7 +63,7 @@ namespace TestReopen class ReaderCouple { public: - ReaderCouple(IndexReaderPtr r1, IndexReaderPtr r2) + ReaderCouple(const IndexReaderPtr& r1, const IndexReaderPtr& r2) { newReader = r1; refreshedReader = r2; @@ -107,7 +107,7 @@ namespace TestReopen class ReaderThread : public LuceneThread { public: - ReaderThread(ReaderThreadTaskPtr task) + ReaderThread(const ReaderThreadTaskPtr& task) { this->task = task; } @@ -155,7 +155,7 @@ static DocumentPtr createDocument(int32_t n, int32_t numFields) return doc; } -static void createIndex(DirectoryPtr dir, bool multiSegment) +static void createIndex(const DirectoryPtr& dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -182,7 +182,7 @@ static void createIndex(DirectoryPtr dir, bool multiSegment) r->close(); } -static void _modifyIndex(int32_t i, DirectoryPtr dir) +static void _modifyIndex(int32_t i, const DirectoryPtr& dir) { switch (i) { @@ -238,7 +238,7 @@ static void _modifyIndex(int32_t i, DirectoryPtr dir) } } -static void checkIndexEquals(IndexReaderPtr index1, IndexReaderPtr index2) +static void checkIndexEquals(const IndexReaderPtr& index1, const IndexReaderPtr& index2) { EXPECT_EQ(index1->numDocs(), index2->numDocs()); EXPECT_EQ(index1->maxDoc(), index2->maxDoc()); @@ -316,7 +316,7 @@ static void checkIndexEquals(IndexReaderPtr index1, IndexReaderPtr index2) } } -static void checkReaderClosed(IndexReaderPtr reader, bool checkSubReaders, bool checkNormsClosed) +static void checkReaderClosed(const IndexReaderPtr& reader, bool checkSubReaders, bool checkNormsClosed) { EXPECT_EQ(0, reader->getRefCount()); @@ -348,7 +348,7 @@ static void checkReaderClosed(IndexReaderPtr reader, bool checkSubReaders, bool } } -static TestReopen::ReaderCouplePtr refreshReader(IndexReaderPtr reader, TestReopen::TestableReopenPtr test, int32_t modify, bool hasChanges) +static TestReopen::ReaderCouplePtr refreshReader(const IndexReaderPtr& reader, const TestReopen::TestableReopenPtr& test, int32_t modify, bool hasChanges) { static SynchronizePtr createReaderMutex = newInstance(); SyncLock readersLock(createReaderMutex); @@ -390,12 +390,12 @@ static TestReopen::ReaderCouplePtr refreshReader(IndexReaderPtr reader, TestReop return newInstance(r, refreshed); } -static TestReopen::ReaderCouplePtr refreshReader(IndexReaderPtr reader, bool hasChanges) +static TestReopen::ReaderCouplePtr refreshReader(const IndexReaderPtr& reader, bool hasChanges) { return refreshReader(reader, TestReopen::TestableReopenPtr(), -1, hasChanges); } -static void performDefaultTests(TestReopen::TestableReopenPtr test) +static void performDefaultTests(const TestReopen::TestableReopenPtr& test) { IndexReaderPtr index1 = test->openReader(); IndexReaderPtr index2 = test->openReader(); @@ -440,7 +440,7 @@ static void performDefaultTests(TestReopen::TestableReopenPtr test) checkReaderClosed(index2, true, true); } -static void performTestsWithExceptionInReopen(TestReopen::TestableReopenPtr test) +static void performTestsWithExceptionInReopen(const TestReopen::TestableReopenPtr& test) { IndexReaderPtr index1 = test->openReader(); IndexReaderPtr index2 = test->openReader(); @@ -463,7 +463,7 @@ static void performTestsWithExceptionInReopen(TestReopen::TestableReopenPtr test index2->close(); } -static void checkRefCountEquals(int32_t refCount, IndexReaderPtr reader) +static void checkRefCountEquals(int32_t refCount, const IndexReaderPtr& reader) { EXPECT_EQ(refCount, reader->getRefCount()); } @@ -473,7 +473,7 @@ namespace TestReopen class BasicReopen : public TestableReopen { public: - BasicReopen(DirectoryPtr dir) + BasicReopen(const DirectoryPtr& dir) { this->dir = dir; } @@ -516,7 +516,7 @@ namespace TestParallelReaderReopen class FirstReopen : public TestReopen::TestableReopen { public: - FirstReopen(DirectoryPtr dir1, DirectoryPtr dir2) + FirstReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2) { this->dir1 = dir1; this->dir2 = dir2; @@ -549,7 +549,7 @@ namespace TestParallelReaderReopen class SecondReopen : public TestReopen::TestableReopen { public: - SecondReopen(DirectoryPtr dir3, DirectoryPtr dir4) + SecondReopen(const DirectoryPtr& dir3, const DirectoryPtr& dir4) { this->dir3 = dir3; this->dir4 = dir4; @@ -605,7 +605,7 @@ TEST_F(IndexReaderReopenTest, testParallelReaderReopen) dir4->close(); } -static void doTestReopenWithCommit(DirectoryPtr dir, bool withReopen) +static void doTestReopenWithCommit(const DirectoryPtr& dir, bool withReopen) { IndexWriterPtr iwriter = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); iwriter->setMergeScheduler(newLucene()); @@ -694,7 +694,7 @@ namespace TestMultiReaderReopen class FirstReopen : public TestReopen::TestableReopen { public: - FirstReopen(DirectoryPtr dir1, DirectoryPtr dir2) + FirstReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2) { this->dir1 = dir1; this->dir2 = dir2; @@ -721,7 +721,7 @@ namespace TestMultiReaderReopen class SecondReopen : public TestReopen::TestableReopen { public: - SecondReopen(DirectoryPtr dir3, DirectoryPtr dir4) + SecondReopen(const DirectoryPtr& dir3, const DirectoryPtr& dir4) { this->dir3 = dir3; this->dir4 = dir4; @@ -778,7 +778,7 @@ namespace TestMixedReaders class MixedReopen : public TestReopen::TestableReopen { public: - MixedReopen(DirectoryPtr dir1, DirectoryPtr dir2, DirectoryPtr dir3, DirectoryPtr dir4, DirectoryPtr dir5) + MixedReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2, const DirectoryPtr& dir3, const DirectoryPtr& dir4, const DirectoryPtr& dir5) { this->dir1 = dir1; this->dir2 = dir2; @@ -1175,7 +1175,7 @@ namespace TestReopen class ThreadReopen : public TestableReopen { public: - ThreadReopen(DirectoryPtr dir, int32_t n) + ThreadReopen(const DirectoryPtr& dir, int32_t n) { this->dir = dir; this->n = n; @@ -1217,7 +1217,7 @@ namespace TestReopen class FirstThreadTask : public ReaderThreadTask { public: - FirstThreadTask(IndexReaderPtr r, TestableReopenPtr test, int32_t index, HashSet readersToClose, Collection readers) + FirstThreadTask(const IndexReaderPtr& r, const TestableReopenPtr& test, int32_t index, HashSet readersToClose, Collection readers) { this->r = r; this->test = test; @@ -1288,7 +1288,7 @@ namespace TestReopen class SecondThreadTask : public ReaderThreadTask { public: - SecondThreadTask(IndexReaderPtr r, TestableReopenPtr test, int32_t index, HashSet readersToClose, Collection readers) + SecondThreadTask(const IndexReaderPtr& r, const TestableReopenPtr& test, int32_t index, HashSet readersToClose, Collection readers) { this->r = r; this->test = test; diff --git a/src/test/index/IndexReaderTest.cpp b/src/test/index/IndexReaderTest.cpp index 30d6177b..9bd9367a 100644 --- a/src/test/index/IndexReaderTest.cpp +++ b/src/test/index/IndexReaderTest.cpp @@ -41,7 +41,7 @@ using namespace Lucene; typedef LuceneTestFixture IndexReaderTest; -static void addDocumentWithFields(IndexWriterPtr writer) +static void addDocumentWithFields(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"keyword", L"test1", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -51,7 +51,7 @@ static void addDocumentWithFields(IndexWriterPtr writer) writer->addDocument(doc); } -static void addDocumentWithDifferentFields(IndexWriterPtr writer) +static void addDocumentWithDifferentFields(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"keyword2", L"test1", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -61,7 +61,7 @@ static void addDocumentWithDifferentFields(IndexWriterPtr writer) writer->addDocument(doc); } -static void addDocumentWithTermVectorFields(IndexWriterPtr writer) +static void addDocumentWithTermVectorFields(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"tvnot", L"tvnot", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO)); @@ -72,14 +72,14 @@ static void addDocumentWithTermVectorFields(IndexWriterPtr writer) writer->addDocument(doc); } -static void addDoc(IndexWriterPtr writer, const String& value) +static void addDoc(const IndexWriterPtr& writer, const String& value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", value, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void checkTermDocsCount(IndexReaderPtr reader, TermPtr term, int32_t expected) +static void checkTermDocsCount(const IndexReaderPtr& reader, const TermPtr& term, int32_t expected) { TermDocsPtr tdocs; diff --git a/src/test/index/IndexWriterDeleteTest.cpp b/src/test/index/IndexWriterDeleteTest.cpp index 6a82feef..a09de871 100644 --- a/src/test/index/IndexWriterDeleteTest.cpp +++ b/src/test/index/IndexWriterDeleteTest.cpp @@ -52,7 +52,7 @@ class FailOnlyOnDeleteFlush : public MockDirectoryFailure return shared_from_this(); } - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (sawMaybe && !failed) { @@ -95,7 +95,7 @@ class FailOnlyOnAdd : public MockDirectoryFailure return shared_from_this(); } - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (!failed) { @@ -105,7 +105,7 @@ class FailOnlyOnAdd : public MockDirectoryFailure } }; -static int32_t getHitCount(DirectoryPtr dir, TermPtr term) +static int32_t getHitCount(const DirectoryPtr& dir, const TermPtr& term) { IndexSearcherPtr searcher = newLucene(dir, true); int32_t hitCount = searcher->search(newLucene(term), FilterPtr(), 1000)->totalHits; @@ -113,7 +113,7 @@ static int32_t getHitCount(DirectoryPtr dir, TermPtr term) return hitCount; } -static void addDoc(IndexWriterPtr modifier, int32_t id, int32_t value) +static void addDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -122,7 +122,7 @@ static void addDoc(IndexWriterPtr modifier, int32_t id, int32_t value) modifier->addDocument(doc); } -static void updateDoc(IndexWriterPtr modifier, int32_t id, int32_t value) +static void updateDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -131,7 +131,7 @@ static void updateDoc(IndexWriterPtr modifier, int32_t id, int32_t value) modifier->updateDocument(newLucene(L"id", StringUtils::toString(id)), doc); } -static void checkNoUnreferencedFiles(DirectoryPtr dir) +static void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); diff --git a/src/test/index/IndexWriterExceptionsTest.cpp b/src/test/index/IndexWriterExceptionsTest.cpp index b8d3e96b..4b7fe0be 100644 --- a/src/test/index/IndexWriterExceptionsTest.cpp +++ b/src/test/index/IndexWriterExceptionsTest.cpp @@ -56,7 +56,7 @@ DECLARE_SHARED_PTR(ExceptionsIndexerThread) class ExceptionsIndexerThread : public LuceneThread { public: - ExceptionsIndexerThread(IndexWriterPtr writer, IndexWriterExceptionsTest* fixture) + ExceptionsIndexerThread(const IndexWriterPtr& writer, IndexWriterExceptionsTest* fixture) { this->writer = writer; this->fixture = fixture; @@ -142,7 +142,7 @@ class ExceptionsIndexerThread : public LuceneThread class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr dir, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) + MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) { this->r = newLucene(17); } diff --git a/src/test/index/IndexWriterMergePolicyTest.cpp b/src/test/index/IndexWriterMergePolicyTest.cpp index 9326cd5f..c1d056fa 100644 --- a/src/test/index/IndexWriterMergePolicyTest.cpp +++ b/src/test/index/IndexWriterMergePolicyTest.cpp @@ -21,14 +21,14 @@ using namespace Lucene; typedef LuceneTestFixture IndexWriterMergePolicyTest; -static void addDoc(IndexWriterPtr writer) +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void checkInvariants(IndexWriterPtr writer) +static void checkInvariants(const IndexWriterPtr& writer) { writer->waitForMerges(); int32_t maxBufferedDocs = writer->getMaxBufferedDocs(); diff --git a/src/test/index/IndexWriterMergingTest.cpp b/src/test/index/IndexWriterMergingTest.cpp index 4442d214..e7efaaf4 100644 --- a/src/test/index/IndexWriterMergingTest.cpp +++ b/src/test/index/IndexWriterMergingTest.cpp @@ -18,7 +18,7 @@ using namespace Lucene; typedef LuceneTestFixture IndexWriterMergingTest; -static bool verifyIndex(DirectoryPtr directory, int32_t startAt) +static bool verifyIndex(const DirectoryPtr& directory, int32_t startAt) { bool fail = false; IndexReaderPtr reader = IndexReader::open(directory, true); @@ -34,7 +34,7 @@ static bool verifyIndex(DirectoryPtr directory, int32_t startAt) return fail; } -static void fillIndex(DirectoryPtr dir, int32_t start, int32_t numDocs) +static void fillIndex(const DirectoryPtr& dir, int32_t start, int32_t numDocs) { IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMergeFactor(2); diff --git a/src/test/index/IndexWriterReaderTest.cpp b/src/test/index/IndexWriterReaderTest.cpp index c1fb761a..89d4ab7b 100644 --- a/src/test/index/IndexWriterReaderTest.cpp +++ b/src/test/index/IndexWriterReaderTest.cpp @@ -46,7 +46,7 @@ static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t nu return doc; } -static void createIndexNoClose(bool multiSegment, const String& indexName, IndexWriterPtr w) +static void createIndexNoClose(bool multiSegment, const String& indexName, const IndexWriterPtr& w) { for (int32_t i = 0; i < 100; ++i) w->addDocument(createDocument(i, indexName, 4)); @@ -54,7 +54,7 @@ static void createIndexNoClose(bool multiSegment, const String& indexName, Index w->optimize(); } -static int32_t count(TermPtr t, IndexReaderPtr r) +static int32_t count(const TermPtr& t, const IndexReaderPtr& r) { int32_t count = 0; TermDocsPtr td = r->termDocs(t); @@ -70,7 +70,7 @@ static int32_t count(TermPtr t, IndexReaderPtr r) class TestableIndexWriter : public IndexWriter { public: - TestableIndexWriter(DirectoryPtr d, AnalyzerPtr a, int32_t mfl) : IndexWriter(d, a, mfl) + TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl) : IndexWriter(d, a, mfl) { } @@ -124,7 +124,7 @@ class HeavyAtomicInt : public LuceneObject class AddDirectoriesThread : public LuceneThread { public: - AddDirectoriesThread(AddDirectoriesThreadsPtr addDirectories, int32_t numIter) + AddDirectoriesThread(const AddDirectoriesThreadsPtr& addDirectories, int32_t numIter) { this->_addDirectories = addDirectories; this->numIter = numIter; @@ -147,7 +147,7 @@ class AddDirectoriesThread : public LuceneThread class AddDirectoriesThreads : public LuceneObject { public: - AddDirectoriesThreads(int32_t numDirs, IndexWriterPtr mainWriter) + AddDirectoriesThreads(int32_t numDirs, const IndexWriterPtr& mainWriter) { this->numDirs = numDirs; this->mainWriter = mainWriter; @@ -567,7 +567,7 @@ namespace TestMergeWarmer int32_t warmCount; public: - virtual void warm(IndexReaderPtr reader) + virtual void warm(const IndexReaderPtr& reader) { ++warmCount; } @@ -678,7 +678,7 @@ namespace TestDuringAddIndexes class AddIndexesThread : public LuceneThread { public: - AddIndexesThread(int64_t endTime, IndexWriterPtr writer, Collection dirs) + AddIndexesThread(int64_t endTime, const IndexWriterPtr& writer, Collection dirs) { this->endTime = endTime; this->writer = writer; @@ -774,7 +774,7 @@ namespace TestDuringAddDelete class AddDeleteThread : public LuceneThread { public: - AddDeleteThread(int64_t endTime, IndexWriterPtr writer) + AddDeleteThread(int64_t endTime, const IndexWriterPtr& writer) { this->endTime = endTime; this->writer = writer; @@ -939,7 +939,7 @@ namespace TestSegmentWarmer LUCENE_CLASS(SegmentWarmer); public: - virtual void warm(IndexReaderPtr reader) + virtual void warm(const IndexReaderPtr& reader) { IndexSearcherPtr s = newLucene(reader); TopDocsPtr hits = s->search(newLucene(newLucene(L"foo", L"bar")), 10); diff --git a/src/test/index/IndexWriterTest.cpp b/src/test/index/IndexWriterTest.cpp index 7555b5d5..8779a0dd 100644 --- a/src/test/index/IndexWriterTest.cpp +++ b/src/test/index/IndexWriterTest.cpp @@ -59,14 +59,14 @@ using namespace Lucene; typedef LuceneTestFixture IndexWriterTest; -static void addDoc(IndexWriterPtr writer) +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void addDocWithIndex(IndexWriterPtr writer, int32_t index) +static void addDocWithIndex(const IndexWriterPtr& writer, int32_t index) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa " + StringUtils::toString(index), Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -74,7 +74,7 @@ static void addDocWithIndex(IndexWriterPtr writer, int32_t index) writer->addDocument(doc); } -static void checkNoUnreferencedFiles(DirectoryPtr dir) +static void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); @@ -115,7 +115,7 @@ class FailOnlyOnFlush : public MockDirectoryFailure int32_t count; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (this->doFail) { @@ -146,7 +146,7 @@ class FailOnlyOnAbortOrFlush : public MockDirectoryFailure bool onlyOnce; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (doFail) { @@ -177,7 +177,7 @@ class FailOnlyInCloseDocStore : public MockDirectoryFailure bool onlyOnce; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (doFail) { @@ -208,7 +208,7 @@ class FailOnlyInWriteSegment : public MockDirectoryFailure bool onlyOnce; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (doFail) { @@ -239,7 +239,7 @@ class FailOnlyInSync : public MockDirectoryFailure bool didFail; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (doFail) { @@ -270,7 +270,7 @@ class FailOnlyInCommit : public MockDirectoryFailure bool fail2; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { bool isCommit = TestPoint::getTestPoint(L"SegmentInfos", L"prepareCommit"); bool isDelete = TestPoint::getTestPoint(L"MockRAMDirectory", L"deleteFile"); @@ -294,7 +294,7 @@ class FailOnlyInCommit : public MockDirectoryFailure class CrashingFilter : public TokenFilter { public: - CrashingFilter(const String& fieldName, TokenStreamPtr input) : TokenFilter(input) + CrashingFilter(const String& fieldName, const TokenStreamPtr& input) : TokenFilter(input) { this->count = 0; this->fieldName = fieldName; @@ -330,7 +330,7 @@ DECLARE_SHARED_PTR(IndexerThread) class IndexerThread : public LuceneThread { public: - IndexerThread(IndexWriterPtr writer, bool noErrors) + IndexerThread(const IndexWriterPtr& writer, bool noErrors) { this->writer = writer; this->noErrors = noErrors; @@ -431,7 +431,7 @@ const int32_t RunAddIndexesThreads::NUM_THREADS = 5; class RunAddThread : public LuceneThread { public: - RunAddThread(RunAddIndexesThreadsPtr runAdd, int32_t numIter, int32_t numCopy, DirectoryPtr dir) + RunAddThread(const RunAddIndexesThreadsPtr& runAdd, int32_t numIter, int32_t numCopy, const DirectoryPtr& dir) { this->_runAdd = runAdd; this->numIter = numIter; @@ -1855,7 +1855,7 @@ namespace TestFlushWithNoMerging class TestableIndexWriter : public IndexWriter { public: - TestableIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { } @@ -2030,7 +2030,7 @@ namespace TestMaxThreadPriority LUCENE_CLASS(MyMergeScheduler); public: - virtual void merge(IndexWriterPtr writer) + virtual void merge(const IndexWriterPtr& writer) { while (true) { @@ -2071,7 +2071,7 @@ namespace TestExceptionFromTokenStream class ExceptionTokenFilter : public TokenFilter { public: - ExceptionTokenFilter(TokenStreamPtr input) : TokenFilter(input) + ExceptionTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) { count = 0; } @@ -2104,7 +2104,7 @@ namespace TestExceptionFromTokenStream LUCENE_CLASS(ExceptionAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, reader)); } @@ -2201,7 +2201,7 @@ namespace TestDocumentsWriterExceptions LUCENE_CLASS(CrashAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(fieldName, newLucene(reader)); } @@ -2303,7 +2303,7 @@ namespace TestDocumentsWriterExceptionThreads LUCENE_CLASS(CrashAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(fieldName, newLucene(reader)); } @@ -2312,7 +2312,7 @@ namespace TestDocumentsWriterExceptionThreads class ExceptionThread : public LuceneThread { public: - ExceptionThread(IndexWriterPtr writer, int32_t numIter, int32_t finalI) + ExceptionThread(const IndexWriterPtr& writer, int32_t numIter, int32_t finalI) { this->writer = writer; this->numIter = numIter; @@ -2504,7 +2504,7 @@ namespace TestNoWaitClose class NoWaitThread : public LuceneThread { public: - NoWaitThread(IndexWriterPtr finalWriter, DocumentPtr doc) + NoWaitThread(const IndexWriterPtr& finalWriter, const DocumentPtr& doc) { this->finalWriter = finalWriter; this->doc = doc; @@ -2760,7 +2760,7 @@ TEST_F(IndexWriterTest, testImmediateDiskFullWithThreads) } } -static void _testSingleThreadFailure(MockDirectoryFailurePtr failure) +static void _testSingleThreadFailure(const MockDirectoryFailurePtr& failure) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -2788,7 +2788,7 @@ static void _testSingleThreadFailure(MockDirectoryFailurePtr failure) writer->close(false); } -static void _testMultipleThreadsFailure(MockDirectoryFailurePtr failure) +static void _testMultipleThreadsFailure(const MockDirectoryFailurePtr& failure) { int32_t NUM_THREADS = 3; @@ -3347,7 +3347,7 @@ namespace TestExceptionDocumentsWriterInit class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { doFail = false; } @@ -3399,7 +3399,7 @@ namespace TestExceptionJustBeforeFlush class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { doFail = false; } @@ -3432,7 +3432,7 @@ namespace TestExceptionJustBeforeFlush LUCENE_CLASS(CrashAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(fieldName, newLucene(reader)); } @@ -3473,7 +3473,7 @@ namespace TestExceptionOnMergeInit class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { doFail = false; failed = false; @@ -3536,7 +3536,7 @@ namespace TestDoBeforeAfterFlush class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { afterWasCalled = false; beforeWasCalled = false; @@ -4080,7 +4080,7 @@ namespace TestRollbackExceptionHang class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { doFail = false; } @@ -4233,7 +4233,7 @@ namespace TestOutOfMemoryErrorCausesCloseToFail class MemoryIndexWriter : public IndexWriter { public: - MemoryIndexWriter(DirectoryPtr d, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) + MemoryIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { thrown = false; } @@ -4705,7 +4705,7 @@ namespace TestCommitThreadSafety class CommitThread : public LuceneThread { public: - CommitThread(int32_t finalI, IndexWriterPtr writer, DirectoryPtr dir, int64_t endTime) + CommitThread(int32_t finalI, const IndexWriterPtr& writer, const DirectoryPtr& dir, int64_t endTime) { this->finalI = finalI; this->writer = writer; @@ -4800,7 +4800,7 @@ namespace TestCorruptionAfterDiskFullDuringMerge bool didFail2; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (!doFail) return; diff --git a/src/test/index/LazyProxSkippingTest.cpp b/src/test/index/LazyProxSkippingTest.cpp index 9824c1ba..294fc7dc 100644 --- a/src/test/index/LazyProxSkippingTest.cpp +++ b/src/test/index/LazyProxSkippingTest.cpp @@ -31,7 +31,7 @@ DECLARE_SHARED_PTR(SeeksCountingStream) class SeeksCountingStream : public IndexInput { public: - SeeksCountingStream(IndexInputPtr input) + SeeksCountingStream(const IndexInputPtr& input) { this->input = input; } @@ -73,7 +73,7 @@ class SeeksCountingStream : public IndexInput return input->length(); } - LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) + LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(input->clone())); } diff --git a/src/test/index/MultiLevelSkipListTest.cpp b/src/test/index/MultiLevelSkipListTest.cpp index 95acc37f..3dd216f5 100644 --- a/src/test/index/MultiLevelSkipListTest.cpp +++ b/src/test/index/MultiLevelSkipListTest.cpp @@ -33,7 +33,7 @@ typedef LuceneTestFixture MultiLevelSkipListTest; class MultiLevelSkipListPayloadFilter : public TokenFilter { public: - MultiLevelSkipListPayloadFilter(TokenStreamPtr input) : TokenFilter(input) + MultiLevelSkipListPayloadFilter(const TokenStreamPtr& input) : TokenFilter(input) { payloadAtt = addAttribute(); } @@ -49,7 +49,7 @@ class MultiLevelSkipListPayloadFilter : public TokenFilter PayloadAttributePtr payloadAtt; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } @@ -79,7 +79,7 @@ class MultiLevelSkipListPayloadAnalyzer : public Analyzer LUCENE_CLASS(MultiLevelSkipListPayloadAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } @@ -90,7 +90,7 @@ static int32_t counter = 0; class CountingStream : public IndexInput { public: - CountingStream(IndexInputPtr input) + CountingStream(const IndexInputPtr& input) { this->input = input; } @@ -137,13 +137,13 @@ class CountingStream : public IndexInput return input->length(); } - LuceneObjectPtr clone(LuceneObjectPtr other = LuceneObjectPtr()) + LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(input->clone())); } }; -static void checkSkipTo(TermPositionsPtr tp, int32_t target, int32_t maxCounter) +static void checkSkipTo(const TermPositionsPtr& tp, int32_t target, int32_t maxCounter) { tp->skipTo(target); if (maxCounter < counter) diff --git a/src/test/index/MultiReaderTest.cpp b/src/test/index/MultiReaderTest.cpp index cbf62c70..860508ab 100644 --- a/src/test/index/MultiReaderTest.cpp +++ b/src/test/index/MultiReaderTest.cpp @@ -132,7 +132,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper return reader; } - void checkNorms(IndexReaderPtr reader) + void checkNorms(const IndexReaderPtr& reader) { for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) { @@ -155,7 +155,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper } } - void addDoc(RAMDirectoryPtr ramDir1, const String& s, bool create) + void addDoc(const RAMDirectoryPtr& ramDir1, const String& s, bool create) { IndexWriterPtr iw = newLucene(ramDir1, newLucene(LuceneVersion::LUCENE_CURRENT), create, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); diff --git a/src/test/index/NRTReaderWithThreadsTest.cpp b/src/test/index/NRTReaderWithThreadsTest.cpp index 86b2933e..c550bbe5 100644 --- a/src/test/index/NRTReaderWithThreadsTest.cpp +++ b/src/test/index/NRTReaderWithThreadsTest.cpp @@ -40,7 +40,7 @@ static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t nu return doc; } -static int32_t count(TermPtr t, IndexReaderPtr r) +static int32_t count(const TermPtr& t, const IndexReaderPtr& r) { int32_t count = 0; TermDocsPtr td = r->termDocs(t); @@ -93,7 +93,7 @@ class HeavyAtomicInt : public LuceneObject class RunThread : public LuceneThread { public: - RunThread(int32_t type, IndexWriterPtr writer, HeavyAtomicIntPtr seq) + RunThread(int32_t type, const IndexWriterPtr& writer, const HeavyAtomicIntPtr& seq) { this->_run = true; this->delCount = 0; diff --git a/src/test/index/NormsTest.cpp b/src/test/index/NormsTest.cpp index 8022efea..c9614420 100644 --- a/src/test/index/NormsTest.cpp +++ b/src/test/index/NormsTest.cpp @@ -98,7 +98,7 @@ class NormsTest : public LuceneTestFixture return d; } - void verifyIndex(DirectoryPtr dir) + void verifyIndex(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); for (int32_t i = 0; i < NUM_FIELDS; ++i) @@ -116,7 +116,7 @@ class NormsTest : public LuceneTestFixture } } - void addDocs(DirectoryPtr dir, int32_t ndocs, bool compound) + void addDocs(const DirectoryPtr& dir, int32_t ndocs, bool compound) { IndexWriterPtr iw = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); @@ -128,7 +128,7 @@ class NormsTest : public LuceneTestFixture iw->close(); } - void modifyNormsForF1(DirectoryPtr dir) + void modifyNormsForF1(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); int32_t n = ir->maxDoc(); @@ -145,7 +145,7 @@ class NormsTest : public LuceneTestFixture ir->close(); } - void doTestNorms(DirectoryPtr dir) + void doTestNorms(const DirectoryPtr& dir) { for (int32_t i = 0; i < 5; ++i) { @@ -160,7 +160,7 @@ class NormsTest : public LuceneTestFixture } } - void createIndex(DirectoryPtr dir) + void createIndex(const DirectoryPtr& dir) { IndexWriterPtr iw = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); diff --git a/src/test/index/OmitTfTest.cpp b/src/test/index/OmitTfTest.cpp index f77601b6..d8fddcbb 100644 --- a/src/test/index/OmitTfTest.cpp +++ b/src/test/index/OmitTfTest.cpp @@ -92,7 +92,7 @@ class SimpleSimilarity : public Similarity return 1.0; } - virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher) + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) { return newLucene(); } @@ -122,7 +122,7 @@ class CountingHitCollector : public Collector int32_t docBase; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { } @@ -132,7 +132,7 @@ class CountingHitCollector : public Collector sum += doc + docBase; // use it to avoid any possibility of being optimized away } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } @@ -143,7 +143,7 @@ class CountingHitCollector : public Collector } }; -static void checkNoPrx(DirectoryPtr dir) +static void checkNoPrx(const DirectoryPtr& dir) { HashSet files = dir->listAll(); for (HashSet::iterator file = files.begin(); file != files.end(); ++file) @@ -331,7 +331,7 @@ namespace TestBasic ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -349,7 +349,7 @@ namespace TestBasic ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -367,7 +367,7 @@ namespace TestBasic ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -386,7 +386,7 @@ namespace TestBasic ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } diff --git a/src/test/index/ParallelReaderTest.cpp b/src/test/index/ParallelReaderTest.cpp index db7a7b90..3733aba8 100644 --- a/src/test/index/ParallelReaderTest.cpp +++ b/src/test/index/ParallelReaderTest.cpp @@ -107,7 +107,7 @@ class ParallelReaderTest : public LuceneTestFixture return dir2; } - void queryTest(QueryPtr query) + void queryTest(const QueryPtr& query) { Collection parallelHits = parallel->search(query, FilterPtr(), 1000)->scoreDocs; Collection singleHits = single->search(query, FilterPtr(), 1000)->scoreDocs; diff --git a/src/test/index/PayloadsTest.cpp b/src/test/index/PayloadsTest.cpp index 474b2fe0..1e1a0aef 100644 --- a/src/test/index/PayloadsTest.cpp +++ b/src/test/index/PayloadsTest.cpp @@ -67,7 +67,7 @@ class PayloadData : public LuceneObject class PayloadFilter : public TokenFilter { public: - PayloadFilter(TokenStreamPtr in, ByteArray data, int32_t offset, int32_t length) : TokenFilter(in) + PayloadFilter(const TokenStreamPtr& in, ByteArray data, int32_t offset, int32_t length) : TokenFilter(in) { this->payload = newLucene(); this->data = data; @@ -139,7 +139,7 @@ class PayloadAnalyzer : public Analyzer fieldToData.put(field, payload); } - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { PayloadDataPtr payload = fieldToData.get(fieldName); TokenStreamPtr ts = newLucene(reader); @@ -295,7 +295,7 @@ TEST_F(PayloadsTest, testPayloadFieldBit) /// Builds an index with payloads in the given Directory and performs different /// tests to verify the payload encoding -static void encodingTest(DirectoryPtr dir) +static void encodingTest(const DirectoryPtr& dir) { PayloadAnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -520,7 +520,7 @@ namespace TestThreadSafety class PoolingPayloadTokenStream : public TokenStream { public: - PoolingPayloadTokenStream(ByteArrayPoolPtr pool) + PoolingPayloadTokenStream(const ByteArrayPoolPtr& pool) { this->pool = pool; payload = pool->get(); @@ -567,7 +567,7 @@ namespace TestThreadSafety class IngesterThread : public LuceneThread { public: - IngesterThread(int32_t numDocs, ByteArrayPoolPtr pool, IndexWriterPtr writer) + IngesterThread(int32_t numDocs, const ByteArrayPoolPtr& pool, const IndexWriterPtr& writer) { this->numDocs = numDocs; this->pool = pool; diff --git a/src/test/index/SegmentMergerTest.cpp b/src/test/index/SegmentMergerTest.cpp index 4cf13390..07b9c0dc 100644 --- a/src/test/index/SegmentMergerTest.cpp +++ b/src/test/index/SegmentMergerTest.cpp @@ -63,7 +63,7 @@ class SegmentMergerTest : public LuceneTestFixture, public DocHelper SegmentReaderPtr reader2; public: - void checkNorms(IndexReaderPtr reader) + void checkNorms(const IndexReaderPtr& reader) { // test omit norms for (int32_t i = 0; i < DocHelper::fields.size(); ++i) diff --git a/src/test/index/SegmentTermDocsTest.cpp b/src/test/index/SegmentTermDocsTest.cpp index 645ce8e7..38f66ad2 100644 --- a/src/test/index/SegmentTermDocsTest.cpp +++ b/src/test/index/SegmentTermDocsTest.cpp @@ -212,7 +212,7 @@ class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper dir->close(); } - void addDoc(IndexWriterPtr writer, const String& value) + void addDoc(const IndexWriterPtr& writer, const String& value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", value, Field::STORE_NO, Field::INDEX_ANALYZED)); diff --git a/src/test/index/SegmentTermEnumTest.cpp b/src/test/index/SegmentTermEnumTest.cpp index 8f0babf5..e112d300 100644 --- a/src/test/index/SegmentTermEnumTest.cpp +++ b/src/test/index/SegmentTermEnumTest.cpp @@ -22,14 +22,14 @@ using namespace Lucene; typedef LuceneTestFixture SegmentTermEnumTest; -static void addDoc(IndexWriterPtr writer, const String& value) +static void addDoc(const IndexWriterPtr& writer, const String& value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", value, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void verifyDocFreq(DirectoryPtr dir) +static void verifyDocFreq(const DirectoryPtr& dir) { IndexReaderPtr reader = IndexReader::open(dir, true); diff --git a/src/test/index/SnapshotDeletionPolicyTest.cpp b/src/test/index/SnapshotDeletionPolicyTest.cpp index 22ada807..50ff5fa6 100644 --- a/src/test/index/SnapshotDeletionPolicyTest.cpp +++ b/src/test/index/SnapshotDeletionPolicyTest.cpp @@ -26,7 +26,7 @@ using namespace Lucene; class SnapshotThread : public LuceneThread { public: - SnapshotThread(int64_t stopTime, IndexWriterPtr writer) + SnapshotThread(int64_t stopTime, const IndexWriterPtr& writer) { this->stopTime = stopTime; this->writer = writer; @@ -85,7 +85,7 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture ByteArray buffer; public: - void runTest(DirectoryPtr dir) + void runTest(const DirectoryPtr& dir) { // Run for ~1 seconds int64_t stopTime = MiscUtils::currentTimeMillis() + 1000; @@ -124,7 +124,7 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture /// Example showing how to use the SnapshotDeletionPolicy to take a backup. This method does not /// really do a backup; instead, it reads every byte of every file just to test that the files /// indeed exist and are readable even while the index is changing. - void backupIndex(DirectoryPtr dir, SnapshotDeletionPolicyPtr dp) + void backupIndex(const DirectoryPtr& dir, const SnapshotDeletionPolicyPtr& dp) { // To backup an index we first take a snapshot LuceneException finally; @@ -143,7 +143,7 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture finally.throwException(); } - void copyFiles(DirectoryPtr dir, IndexCommitPtr cp) + void copyFiles(const DirectoryPtr& dir, const IndexCommitPtr& cp) { // While we hold the snapshot, and nomatter how long we take to do the backup, the IndexWriter will // never delete the files in the snapshot @@ -157,7 +157,7 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture } } - void readFile(DirectoryPtr dir, const String& name) + void readFile(const DirectoryPtr& dir, const String& name) { IndexInputPtr input = dir->openInput(name); @@ -185,7 +185,7 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture finally.throwException(); } - void checkNoUnreferencedFiles(DirectoryPtr dir) + void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); diff --git a/src/test/index/StressIndexingTest.cpp b/src/test/index/StressIndexingTest.cpp index 1a41a16f..c110b78b 100644 --- a/src/test/index/StressIndexingTest.cpp +++ b/src/test/index/StressIndexingTest.cpp @@ -53,7 +53,7 @@ class DocsAndWriter : public LuceneObject class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(DirectoryPtr dir, AnalyzerPtr a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) + MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) { rand = newLucene(); } @@ -298,13 +298,13 @@ class IndexingThread : public LuceneThread } }; -static void verifyEquals(IndexReaderPtr r1, DirectoryPtr dir2, const String& idField); -static void verifyEquals(DirectoryPtr dir1, DirectoryPtr dir2, const String& idField); -static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idField); -static void verifyEquals(DocumentPtr d1, DocumentPtr d2); +static void verifyEquals(const IndexReaderPtr& r1, const DirectoryPtr& dir2, const String& idField); +static void verifyEquals(const DirectoryPtr& dir1, const DirectoryPtr& dir2, const String& idField); +static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, const String& idField); +static void verifyEquals(const DocumentPtr& d1, const DocumentPtr& d2); static void verifyEquals(Collection d1, Collection d2); -static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iterations, int32_t range, DirectoryPtr dir) +static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iterations, int32_t range, const DirectoryPtr& dir) { HashMap docs = HashMap::newInstance(); IndexWriterPtr w = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -345,7 +345,7 @@ static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iteratio return dw; } -static HashMap indexRandom(int32_t numThreads, int32_t iterations, int32_t range, DirectoryPtr dir) +static HashMap indexRandom(int32_t numThreads, int32_t iterations, int32_t range, const DirectoryPtr& dir) { HashMap docs = HashMap::newInstance(); @@ -390,7 +390,7 @@ static HashMap indexRandom(int32_t numThreads, int32_t iter return docs; } -static void indexSerial(HashMap docs, DirectoryPtr dir) +static void indexSerial(HashMap docs, const DirectoryPtr& dir) { IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -412,14 +412,14 @@ static void indexSerial(HashMap docs, DirectoryPtr dir) w->close(); } -static void verifyEquals(IndexReaderPtr r1, DirectoryPtr dir2, const String& idField) +static void verifyEquals(const IndexReaderPtr& r1, const DirectoryPtr& dir2, const String& idField) { IndexReaderPtr r2 = IndexReader::open(dir2, true); verifyEquals(r1, r2, idField); r2->close(); } -static void verifyEquals(DirectoryPtr dir1, DirectoryPtr dir2, const String& idField) +static void verifyEquals(const DirectoryPtr& dir1, const DirectoryPtr& dir2, const String& idField) { IndexReaderPtr r1 = IndexReader::open(dir1, true); IndexReaderPtr r2 = IndexReader::open(dir2, true); @@ -428,7 +428,7 @@ static void verifyEquals(DirectoryPtr dir1, DirectoryPtr dir2, const String& idF r2->close(); } -static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idField) +static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, const String& idField) { EXPECT_EQ(r1->numDocs(), r2->numDocs()); bool hasDeletes = !(r1->maxDoc() == r2->maxDoc() && r1->numDocs() == r1->maxDoc()); @@ -554,7 +554,7 @@ static void verifyEquals(IndexReaderPtr r1, IndexReaderPtr r2, const String& idF } } -static void verifyEquals(DocumentPtr d1, DocumentPtr d2) +static void verifyEquals(const DocumentPtr& d1, const DocumentPtr& d2) { Collection ff1 = d1->getFields(); Collection ff2 = d2->getFields(); @@ -683,7 +683,7 @@ namespace RunStressTest class StressIndexerThread : public StressTimedThread { public: - StressIndexerThread(IndexWriterPtr writer) + StressIndexerThread(const IndexWriterPtr& writer) { this->writer = writer; this->nextID = 0; @@ -724,7 +724,7 @@ namespace RunStressTest class StressSearcherThread : public StressTimedThread { public: - StressSearcherThread(DirectoryPtr directory) + StressSearcherThread(const DirectoryPtr& directory) { this->directory = directory; } @@ -748,7 +748,7 @@ namespace RunStressTest } /// Run one indexer and 2 searchers against single index as stress test. -static void runStressTest(DirectoryPtr directory, MergeSchedulerPtr mergeScheduler) +static void runStressTest(const DirectoryPtr& directory, const MergeSchedulerPtr& mergeScheduler) { AnalyzerPtr analyzer = newLucene(); IndexWriterPtr modifier = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); diff --git a/src/test/index/TermDocsPerfTest.cpp b/src/test/index/TermDocsPerfTest.cpp index ed99523a..70149ad9 100644 --- a/src/test/index/TermDocsPerfTest.cpp +++ b/src/test/index/TermDocsPerfTest.cpp @@ -65,7 +65,7 @@ class RepeatingTokenStream : public TokenStream class TermDocsPerfTestAnalyzer : public Analyzer { public: - TermDocsPerfTestAnalyzer(RepeatingTokenStreamPtr ts, RandomPtr random, int32_t maxTF, double percentDocs) + TermDocsPerfTestAnalyzer(const RepeatingTokenStreamPtr& ts, const RandomPtr& random, int32_t maxTF, double percentDocs) { this->ts = ts; this->random = random; @@ -86,7 +86,7 @@ class TermDocsPerfTestAnalyzer : public Analyzer double percentDocs; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { if (random->nextDouble() < percentDocs) ts->num = random->nextInt(maxTF) + 1; @@ -96,7 +96,7 @@ class TermDocsPerfTestAnalyzer : public Analyzer } }; -static void addDocs(DirectoryPtr dir, int32_t numDocs, const String& field, const String& val, int32_t maxTF, double percentDocs) +static void addDocs(const DirectoryPtr& dir, int32_t numDocs, const String& field, const String& val, int32_t maxTF, double percentDocs) { RepeatingTokenStreamPtr ts = newLucene(val); RandomPtr random = newLucene(); diff --git a/src/test/index/TermVectorsReaderTest.cpp b/src/test/index/TermVectorsReaderTest.cpp index ac12e213..dfe12975 100644 --- a/src/test/index/TermVectorsReaderTest.cpp +++ b/src/test/index/TermVectorsReaderTest.cpp @@ -58,7 +58,7 @@ class TestToken : public LuceneObject int32_t endOffset; public: - int32_t compareTo(TestTokenPtr other) + int32_t compareTo(const TestTokenPtr& other) { return (pos - other->pos); } @@ -131,7 +131,7 @@ class MyAnalyzer : public Analyzer Collection tokens; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(tokens); } diff --git a/src/test/index/ThreadedOptimizeTest.cpp b/src/test/index/ThreadedOptimizeTest.cpp index ed413db6..4a02a17b 100644 --- a/src/test/index/ThreadedOptimizeTest.cpp +++ b/src/test/index/ThreadedOptimizeTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; class OptimizeThread : public LuceneThread { public: - OptimizeThread(int32_t numIter, int32_t iterFinal, int32_t iFinal, IndexWriterPtr writer, IndexWriterPtr writerFinal) + OptimizeThread(int32_t numIter, int32_t iterFinal, int32_t iFinal, const IndexWriterPtr& writer, const IndexWriterPtr& writerFinal) { this->numIter = numIter; this->iterFinal = iterFinal; @@ -94,7 +94,7 @@ class ThreadedOptimizeTest : public LuceneTestFixture AnalyzerPtr analyzer; public: - void runTest(DirectoryPtr directory, MergeSchedulerPtr merger) + void runTest(const DirectoryPtr& directory, const MergeSchedulerPtr& merger) { IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); diff --git a/src/test/index/TransactionRollbackTest.cpp b/src/test/index/TransactionRollbackTest.cpp index b6ee49a8..079cf368 100644 --- a/src/test/index/TransactionRollbackTest.cpp +++ b/src/test/index/TransactionRollbackTest.cpp @@ -167,7 +167,7 @@ class TransactionRollbackTest : public LuceneTestFixture w->close(); } - void checkExpecteds(BitSetPtr expecteds) + void checkExpecteds(const BitSetPtr& expecteds) { IndexReaderPtr r = IndexReader::open(dir, true); diff --git a/src/test/index/TransactionsTest.cpp b/src/test/index/TransactionsTest.cpp index 4bfea99d..946415f0 100644 --- a/src/test/index/TransactionsTest.cpp +++ b/src/test/index/TransactionsTest.cpp @@ -68,7 +68,7 @@ const int32_t TransactionsTimedThread::RUN_TIME_SEC = 6; class TransactionsIndexerThread : public TransactionsTimedThread { public: - TransactionsIndexerThread(SynchronizePtr lock, DirectoryPtr dir1, DirectoryPtr dir2) + TransactionsIndexerThread(const SynchronizePtr& lock, const DirectoryPtr& dir1, const DirectoryPtr& dir2) { this->lock = lock; this->dir1 = dir1; @@ -151,7 +151,7 @@ class TransactionsIndexerThread : public TransactionsTimedThread writer2->close(); } - void update(IndexWriterPtr writer) + void update(const IndexWriterPtr& writer) { // Add 10 docs for (int32_t j = 0; j < 10; ++j) @@ -175,7 +175,7 @@ class TransactionsIndexerThread : public TransactionsTimedThread class TransactionsSearcherThread : public TransactionsTimedThread { public: - TransactionsSearcherThread(SynchronizePtr lock, DirectoryPtr dir1, DirectoryPtr dir2) + TransactionsSearcherThread(const SynchronizePtr& lock, const DirectoryPtr& dir1, const DirectoryPtr& dir2) { this->lock = lock; this->dir1 = dir1; @@ -228,14 +228,14 @@ class RandomFailure : public MockDirectoryFailure RandomPtr random; public: - virtual void eval(MockRAMDirectoryPtr dir) + virtual void eval(const MockRAMDirectoryPtr& dir) { if (doFail && random->nextInt() % 10 <= 3) boost::throw_exception(IOException(L"now failing randomly but on purpose")); } }; -static void initIndex(DirectoryPtr dir) +static void initIndex(const DirectoryPtr& dir) { IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); RandomPtr random = newLucene(); diff --git a/src/test/queryparser/MultiAnalyzerTest.cpp b/src/test/queryparser/MultiAnalyzerTest.cpp index d7d786ae..3e99cae5 100644 --- a/src/test/queryparser/MultiAnalyzerTest.cpp +++ b/src/test/queryparser/MultiAnalyzerTest.cpp @@ -34,7 +34,7 @@ DECLARE_SHARED_PTR(TestPosIncrementFilter) class MultiAnalyzerTestFilter : public TokenFilter { public: - MultiAnalyzerTestFilter(TokenStreamPtr in) : TokenFilter(in) + MultiAnalyzerTestFilter(const TokenStreamPtr& in) : TokenFilter(in) { prevStartOffset = 0; prevEndOffset = 0; @@ -107,7 +107,7 @@ class MultiAnalyzer : public Analyzer LUCENE_CLASS(MultiAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(LuceneVersion::LUCENE_CURRENT, reader); result = newLucene(result); @@ -120,7 +120,7 @@ class MultiAnalyzer : public Analyzer class DumbQueryWrapper : public Query { public: - DumbQueryWrapper(QueryPtr q) + DumbQueryWrapper(const QueryPtr& q) { this->q = q; } @@ -145,7 +145,7 @@ class DumbQueryWrapper : public Query class DumbQueryParser : public QueryParser { public: - DumbQueryParser(const String& f, AnalyzerPtr a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) + DumbQueryParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { } @@ -165,7 +165,7 @@ class DumbQueryParser : public QueryParser class TestPosIncrementFilter : public TokenFilter { public: - TestPosIncrementFilter(TokenStreamPtr in) : TokenFilter(in) + TestPosIncrementFilter(const TokenStreamPtr& in) : TokenFilter(in) { termAtt = addAttribute(); posIncrAtt = addAttribute(); @@ -217,7 +217,7 @@ class PosIncrementAnalyzer : public Analyzer LUCENE_CLASS(PosIncrementAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(LuceneVersion::LUCENE_CURRENT, reader); result = newLucene(result); diff --git a/src/test/queryparser/MultiFieldQueryParserTest.cpp b/src/test/queryparser/MultiFieldQueryParserTest.cpp index d65b1728..32bd2a06 100644 --- a/src/test/queryparser/MultiFieldQueryParserTest.cpp +++ b/src/test/queryparser/MultiFieldQueryParserTest.cpp @@ -33,7 +33,7 @@ DECLARE_SHARED_PTR(MultiFieldQueryParserTestFilter) class MultiFieldQueryParserTestFilter : public TokenFilter { public: - MultiFieldQueryParserTestFilter(TokenStreamPtr in) : TokenFilter(in) + MultiFieldQueryParserTestFilter(const TokenStreamPtr& in) : TokenFilter(in) { termAtt = addAttribute(); offsetAtt = addAttribute(); @@ -97,7 +97,7 @@ class MultiFieldQueryParserTestAnalyzer : public Analyzer public: // Filters LowerCaseTokenizer with StopFilter. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } @@ -138,7 +138,7 @@ class AnalyzerReturningNull : public Analyzer StandardAnalyzerPtr standardAnalyzer; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { if (fieldName == L"f1") return newLucene(); diff --git a/src/test/queryparser/QueryParserTest.cpp b/src/test/queryparser/QueryParserTest.cpp index d29f49f5..f86be710 100644 --- a/src/test/queryparser/QueryParserTest.cpp +++ b/src/test/queryparser/QueryParserTest.cpp @@ -51,7 +51,7 @@ DECLARE_SHARED_PTR(TestParser) class QueryParserTestFilter : public TokenFilter { public: - QueryParserTestFilter(TokenStreamPtr in) : TokenFilter(in) + QueryParserTestFilter(const TokenStreamPtr& in) : TokenFilter(in) { termAtt = addAttribute(); offsetAtt = addAttribute(); @@ -116,7 +116,7 @@ class QueryParserTestAnalyzer : public Analyzer public: // Filters LowerCaseTokenizer with StopFilter. - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } @@ -125,7 +125,7 @@ class QueryParserTestAnalyzer : public Analyzer class TestParser : public QueryParser { public: - TestParser(const String& f, AnalyzerPtr a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) + TestParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { } @@ -166,21 +166,22 @@ class QueryParserTest : public LuceneTestFixture protected: int32_t originalMaxClauses; - QueryParserPtr getParser(AnalyzerPtr a) + QueryParserPtr getParser(const AnalyzerPtr& a) { - if (!a) - a = newLucene(); - QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", a); + AnalyzerPtr _a(a); + if (!_a) + _a = newLucene(); + QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", _a); qp->setDefaultOperator(QueryParser::OR_OPERATOR); return qp; } - QueryPtr getQuery(const String& query, AnalyzerPtr a) + QueryPtr getQuery(const String& query, const AnalyzerPtr& a) { return getParser(a)->parse(query); } - void checkQueryEquals(const String& query, AnalyzerPtr a, const String& result) + void checkQueryEquals(const String& query, const AnalyzerPtr& a, const String& result) { QueryPtr q = getQuery(query, a); String s = q->toString(L"field"); @@ -188,7 +189,7 @@ class QueryParserTest : public LuceneTestFixture FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - void checkQueryEquals(QueryParserPtr qp, const String& field, const String& query, const String& result) + void checkQueryEquals(const QueryParserPtr& qp, const String& field, const String& query, const String& result) { QueryPtr q = qp->parse(query); String s = q->toString(field); @@ -228,7 +229,7 @@ class QueryParserTest : public LuceneTestFixture FAIL() << "WildcardQuery \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - void checkEscapedQueryEquals(const String& query, AnalyzerPtr a, const String& result) + void checkEscapedQueryEquals(const String& query, const AnalyzerPtr& a, const String& result) { class TestableQueryParser : public QueryParser { @@ -241,16 +242,17 @@ class QueryParserTest : public LuceneTestFixture FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(escapedQuery) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - QueryPtr getQueryDOA(const String& query, AnalyzerPtr a) + QueryPtr getQueryDOA(const String& query, const AnalyzerPtr& a) { - if (!a) - a = newLucene(); - QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", a); + AnalyzerPtr _a(a); + if (!_a) + _a = newLucene(); + QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", _a); qp->setDefaultOperator(QueryParser::AND_OPERATOR); return qp->parse(query); } - void checkQueryEqualsDOA(const String& query, AnalyzerPtr a, const String& result) + void checkQueryEqualsDOA(const String& query, const AnalyzerPtr& a, const String& result) { QueryPtr q = getQueryDOA(query, a); String s = q->toString(L"field"); @@ -258,7 +260,7 @@ class QueryParserTest : public LuceneTestFixture FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; } - void addDateDoc(const String& content, boost::posix_time::ptime date, IndexWriterPtr iw) + void addDateDoc(const String& content, boost::posix_time::ptime date, const IndexWriterPtr& iw) { DocumentPtr d = newLucene(); d->add(newLucene(L"f", content, Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -266,7 +268,7 @@ class QueryParserTest : public LuceneTestFixture iw->addDocument(d); } - void checkHits(int32_t expected, const String& query, IndexSearcherPtr is) + void checkHits(int32_t expected, const String& query, const IndexSearcherPtr& is) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"date", newLucene()); qp->setLocale(std::locale()); @@ -796,7 +798,7 @@ namespace TestStarParsing class StarParser : public QueryParser { public: - StarParser(const String& f, AnalyzerPtr a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) + StarParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { type = Collection::newInstance(1); } diff --git a/src/test/search/BaseTestRangeFilterFixture.cpp b/src/test/search/BaseTestRangeFilterFixture.cpp index 15cc3d19..d9ea2904 100644 --- a/src/test/search/BaseTestRangeFilterFixture.cpp +++ b/src/test/search/BaseTestRangeFilterFixture.cpp @@ -44,7 +44,7 @@ namespace Lucene { } - void BaseTestRangeFilterFixture::build(TestIndexPtr index) + void BaseTestRangeFilterFixture::build(const TestIndexPtr& index) { IndexWriterPtr writer = newLucene(index->index, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); for (int32_t d = minId; d <= maxId; ++d) diff --git a/src/test/search/Boolean2Test.cpp b/src/test/search/Boolean2Test.cpp index 18ef60f0..bc00c101 100644 --- a/src/test/search/Boolean2Test.cpp +++ b/src/test/search/Boolean2Test.cpp @@ -127,7 +127,7 @@ class Boolean2Test : public LuceneTestFixture } /// Random rnd is passed in so that the exact same random query may be created more than once. - BooleanQueryPtr randBoolQuery(RandomPtr rnd, bool allowMust, int32_t level, const String& field, Collection vals) + BooleanQueryPtr randBoolQuery(const RandomPtr& rnd, bool allowMust, int32_t level, const String& field, Collection vals) { BooleanQueryPtr current = newLucene(rnd->nextInt() < 0); for (int32_t i = 0; i < rnd->nextInt(vals.size()) + 1; ++i) diff --git a/src/test/search/BooleanMinShouldMatchTest.cpp b/src/test/search/BooleanMinShouldMatchTest.cpp index 88f49a6b..96eb3a01 100644 --- a/src/test/search/BooleanMinShouldMatchTest.cpp +++ b/src/test/search/BooleanMinShouldMatchTest.cpp @@ -70,7 +70,7 @@ class BooleanMinShouldMatchTest : public LuceneTestFixture IndexSearcherPtr s; public: - void verifyNrHits(QueryPtr q, int32_t expected) + void verifyNrHits(const QueryPtr& q, int32_t expected) { Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(expected, h.size()); @@ -78,7 +78,7 @@ class BooleanMinShouldMatchTest : public LuceneTestFixture } /// Random rnd is passed in so that the exact same random query may be created more than once. - BooleanQueryPtr randBoolQuery(RandomPtr rnd, bool allowMust, int32_t level, const String& field, Collection vals) + BooleanQueryPtr randBoolQuery(const RandomPtr& rnd, bool allowMust, int32_t level, const String& field, Collection vals) { BooleanQueryPtr current = newLucene(rnd->nextInt() < 0); for (int32_t i = 0; i < rnd->nextInt(vals.size()) + 1; ++i) @@ -111,7 +111,7 @@ class BooleanMinShouldMatchTest : public LuceneTestFixture return current; } - void minNrCB(RandomPtr rnd, BooleanQueryPtr q) + void minNrCB(const RandomPtr& rnd, const BooleanQueryPtr& q) { Collection c = q->getClauses(); int32_t opt = 0; diff --git a/src/test/search/BooleanOrTest.cpp b/src/test/search/BooleanOrTest.cpp index fc931548..773252e6 100644 --- a/src/test/search/BooleanOrTest.cpp +++ b/src/test/search/BooleanOrTest.cpp @@ -58,7 +58,7 @@ class BooleanOrTest : public LuceneTestFixture IndexSearcherPtr searcher; public: - int32_t search(QueryPtr q) + int32_t search(const QueryPtr& q) { QueryUtils::check(q, searcher); return searcher->search(q, FilterPtr(), 1000)->totalHits; diff --git a/src/test/search/BooleanPrefixQueryTest.cpp b/src/test/search/BooleanPrefixQueryTest.cpp index 43a67254..3ab106ed 100644 --- a/src/test/search/BooleanPrefixQueryTest.cpp +++ b/src/test/search/BooleanPrefixQueryTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; typedef LuceneTestFixture BooleanPrefixQueryTest; -static int32_t getCount(IndexReaderPtr r, QueryPtr q) +static int32_t getCount(const IndexReaderPtr& r, const QueryPtr& q) { if (MiscUtils::typeOf(q)) return boost::dynamic_pointer_cast(q)->getClauses().size(); diff --git a/src/test/search/BooleanScorerTest.cpp b/src/test/search/BooleanScorerTest.cpp index 9ac2f8d8..a3eb9a97 100644 --- a/src/test/search/BooleanScorerTest.cpp +++ b/src/test/search/BooleanScorerTest.cpp @@ -58,7 +58,7 @@ namespace TestEmptyBucketWithMoreDocs class EmptyScorer : public Scorer { public: - EmptyScorer(SimilarityPtr similarity) : Scorer(similarity) + EmptyScorer(const SimilarityPtr& similarity) : Scorer(similarity) { doc = -1; } diff --git a/src/test/search/CachingSpanFilterTest.cpp b/src/test/search/CachingSpanFilterTest.cpp index 27b903da..0c6a6106 100644 --- a/src/test/search/CachingSpanFilterTest.cpp +++ b/src/test/search/CachingSpanFilterTest.cpp @@ -29,13 +29,14 @@ using namespace Lucene; typedef LuceneTestFixture CachingSpanFilterTest; -static IndexReaderPtr refreshReader(IndexReaderPtr reader) +static IndexReaderPtr refreshReader(const IndexReaderPtr& reader) { - IndexReaderPtr oldReader = reader; - reader = reader->reopen(); - if (reader != oldReader) + IndexReaderPtr _reader(reader); + IndexReaderPtr oldReader = _reader; + _reader = _reader->reopen(); + if (_reader != oldReader) oldReader->close(); - return reader; + return _reader; } TEST_F(CachingSpanFilterTest, testEnforceDeletions) diff --git a/src/test/search/CachingWrapperFilterTest.cpp b/src/test/search/CachingWrapperFilterTest.cpp index 9b91c01f..6716e46f 100644 --- a/src/test/search/CachingWrapperFilterTest.cpp +++ b/src/test/search/CachingWrapperFilterTest.cpp @@ -34,7 +34,7 @@ using namespace Lucene; typedef LuceneTestFixture CachingWrapperFilterTest; -static void checkDocIdSetCacheable(IndexReaderPtr reader, FilterPtr filter, bool shouldCacheable) +static void checkDocIdSetCacheable(const IndexReaderPtr& reader, const FilterPtr& filter, bool shouldCacheable) { CachingWrapperFilterPtr cacher = newLucene(filter); DocIdSetPtr originalSet = filter->getDocIdSet(reader); @@ -47,13 +47,14 @@ static void checkDocIdSetCacheable(IndexReaderPtr reader, FilterPtr filter, bool EXPECT_TRUE(MiscUtils::typeOf(cachedSet)); } -static IndexReaderPtr refreshReader(IndexReaderPtr reader) +static IndexReaderPtr refreshReader(const IndexReaderPtr& reader) { - IndexReaderPtr oldReader = reader; - reader = reader->reopen(); - if (reader != oldReader) + IndexReaderPtr _reader(reader); + IndexReaderPtr oldReader = _reader; + _reader = _reader->reopen(); + if (_reader != oldReader) oldReader->close(); - return reader; + return _reader; } TEST_F(CachingWrapperFilterTest, testCachingWorks) @@ -92,7 +93,7 @@ namespace TestNullDocIdSet } public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { return DocIdSetPtr(); } @@ -139,7 +140,7 @@ namespace TestNullDocIdSetIterator } public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { return newLucene(); } @@ -172,7 +173,7 @@ namespace TestIsCacheable } public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { return newLucene(); } diff --git a/src/test/search/CheckHits.cpp b/src/test/search/CheckHits.cpp index 49c73863..72e53d1e 100644 --- a/src/test/search/CheckHits.cpp +++ b/src/test/search/CheckHits.cpp @@ -45,7 +45,7 @@ namespace Lucene int32_t base; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { } @@ -54,7 +54,7 @@ namespace Lucene bag.add(doc + base); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } @@ -71,7 +71,7 @@ namespace Lucene class ExplanationAsserter : public Collector { public: - ExplanationAsserter(QueryPtr q, const String& defaultFieldName, SearcherPtr s, bool deep = false) + ExplanationAsserter(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& s, bool deep = false) { this->q=q; this->s=s; @@ -95,7 +95,7 @@ namespace Lucene int32_t base; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -109,7 +109,7 @@ namespace Lucene CheckHits::verifyExplanation(d, doc, scorer->score(), deep, exp); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } @@ -124,7 +124,7 @@ namespace Lucene { } - void CheckHits::checkNoMatchExplanations(QueryPtr q, const String& defaultFieldName, SearcherPtr searcher, Collection results) + void CheckHits::checkNoMatchExplanations(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) { String d = q->toString(defaultFieldName); Set ignore = Set::newInstance(); @@ -143,7 +143,7 @@ namespace Lucene } } - void CheckHits::checkHitCollector(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results) + void CheckHits::checkHitCollector(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) { QueryUtils::check(query, searcher); Set correct = Set::newInstance(); @@ -174,7 +174,7 @@ namespace Lucene } } - void CheckHits::checkHits(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, Collection results) + void CheckHits::checkHits(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) { if (!MiscUtils::typeOf(searcher)) QueryUtils::check(query, searcher); @@ -200,14 +200,14 @@ namespace Lucene EXPECT_EQ(results[i], hits[i]->doc); } - void CheckHits::checkHitsQuery(QueryPtr query, Collection hits1, Collection hits2, Collection results) + void CheckHits::checkHitsQuery(const QueryPtr& query, Collection hits1, Collection hits2, Collection results) { checkDocIds(results, hits1); checkDocIds(results, hits2); checkEqual(query, hits1, hits2); } - void CheckHits::checkEqual(QueryPtr query, Collection hits1, Collection hits2) + void CheckHits::checkEqual(const QueryPtr& query, Collection hits1, Collection hits2) { double scoreTolerance = 1.0e-6; EXPECT_EQ(hits1.size(), hits2.size()); @@ -218,12 +218,12 @@ namespace Lucene } } - void CheckHits::checkExplanations(QueryPtr query, const String& defaultFieldName, SearcherPtr searcher, bool deep) + void CheckHits::checkExplanations(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, bool deep) { searcher->search(query, newLucene(query, defaultFieldName, searcher, deep)); } - void CheckHits::verifyExplanation(const String& q, int32_t doc, double score, bool deep, ExplanationPtr expl) + void CheckHits::verifyExplanation(const String& q, int32_t doc, double score, bool deep, const ExplanationPtr& expl) { double value = expl->getValue(); EXPECT_NEAR(score, value, EXPLAIN_SCORE_TOLERANCE_DELTA); diff --git a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp index 1b8602ac..d9132a8a 100644 --- a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp @@ -88,7 +88,7 @@ class ComplexExplanationsOfNonMatchesTest : public ExplanationsFixture using ExplanationsFixture::qtest; /// ignore matches and focus on non-matches - virtual void qtest(QueryPtr q, Collection expDocNrs) + virtual void qtest(const QueryPtr& q, Collection expDocNrs) { CheckHits::checkNoMatchExplanations(q, FIELD, searcher, expDocNrs); } diff --git a/src/test/search/CustomSearcherSortTest.cpp b/src/test/search/CustomSearcherSortTest.cpp index 6ef4577a..1f7038c8 100644 --- a/src/test/search/CustomSearcherSortTest.cpp +++ b/src/test/search/CustomSearcherSortTest.cpp @@ -31,12 +31,12 @@ using namespace Lucene; class CustomSearcher : public IndexSearcher { public: - CustomSearcher(DirectoryPtr directory, int32_t switcher) : IndexSearcher(directory, true) + CustomSearcher(const DirectoryPtr& directory, int32_t switcher) : IndexSearcher(directory, true) { this->switcher = switcher; } - CustomSearcher(IndexReaderPtr r, int32_t switcher) : IndexSearcher(r) + CustomSearcher(const IndexReaderPtr& r, int32_t switcher) : IndexSearcher(r) { this->switcher = switcher; } @@ -49,7 +49,7 @@ class CustomSearcher : public IndexSearcher int32_t switcher; public: - virtual TopFieldDocsPtr search(QueryPtr query, FilterPtr filter, int32_t n, SortPtr sort) + virtual TopFieldDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort) { BooleanQueryPtr bq = newLucene(); bq->add(query, BooleanClause::MUST); @@ -57,7 +57,7 @@ class CustomSearcher : public IndexSearcher return IndexSearcher::search(bq, filter, n, sort); } - virtual TopDocsPtr search(QueryPtr query, FilterPtr filter, int32_t n) + virtual TopDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n) { BooleanQueryPtr bq = newLucene(); bq->add(query, BooleanClause::MUST); @@ -116,7 +116,7 @@ class CustomSearcherSortTest : public LuceneTestFixture } /// make sure the documents returned by the search match the expected list - void matchHits(SearcherPtr searcher, SortPtr sort) + void matchHits(const SearcherPtr& searcher, const SortPtr& sort) { // make a query without sorting first Collection hitsByRank = searcher->search(query, FilterPtr(), 1000)->scoreDocs; diff --git a/src/test/search/DocBoostTest.cpp b/src/test/search/DocBoostTest.cpp index af91bfde..6833dc04 100644 --- a/src/test/search/DocBoostTest.cpp +++ b/src/test/search/DocBoostTest.cpp @@ -42,7 +42,7 @@ namespace TestDocBoost ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -52,7 +52,7 @@ namespace TestDocBoost scores[doc + base] = scorer->score(); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } diff --git a/src/test/search/DocIdSetTest.cpp b/src/test/search/DocIdSetTest.cpp index 0d83e050..10766ee4 100644 --- a/src/test/search/DocIdSetTest.cpp +++ b/src/test/search/DocIdSetTest.cpp @@ -79,7 +79,7 @@ namespace TestFilteredDocIdSet class TestFilteredDocIdSet : public FilteredDocIdSet { public: - TestFilteredDocIdSet(DocIdSetPtr innerSet) : FilteredDocIdSet(innerSet) + TestFilteredDocIdSet(const DocIdSetPtr& innerSet) : FilteredDocIdSet(innerSet) { } @@ -124,7 +124,7 @@ namespace TestNullDocIdSet } public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { return DocIdSetPtr(); } diff --git a/src/test/search/ElevationComparatorTest.cpp b/src/test/search/ElevationComparatorTest.cpp index ca57164d..04894356 100644 --- a/src/test/search/ElevationComparatorTest.cpp +++ b/src/test/search/ElevationComparatorTest.cpp @@ -71,7 +71,7 @@ class ElevationFieldComparator : public FieldComparator values[slot] = docVal(doc); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { idIndex = FieldCache::DEFAULT()->getStringIndex(reader, fieldname); } @@ -135,7 +135,7 @@ class ElevationComparatorTest : public LuceneTestFixture return doc; } - void runTest(IndexSearcherPtr searcher, bool reversed) + void runTest(const IndexSearcherPtr& searcher, bool reversed) { BooleanQueryPtr newq = newLucene(false); TermQueryPtr query = newLucene(newLucene(L"title", L"ipod")); diff --git a/src/test/search/ExplanationsFixture.cpp b/src/test/search/ExplanationsFixture.cpp index 01a693dd..64b98450 100644 --- a/src/test/search/ExplanationsFixture.cpp +++ b/src/test/search/ExplanationsFixture.cpp @@ -62,7 +62,7 @@ namespace Lucene return newLucene(st(s), b); } - SpanNotQueryPtr ExplanationsFixture::snot(SpanQueryPtr i, SpanQueryPtr e) + SpanNotQueryPtr ExplanationsFixture::snot(const SpanQueryPtr& i, const SpanQueryPtr& e) { return newLucene(i, e); } @@ -72,7 +72,7 @@ namespace Lucene return sor(st(s), st(e)); } - SpanOrQueryPtr ExplanationsFixture::sor(SpanQueryPtr s, SpanQueryPtr e) + SpanOrQueryPtr ExplanationsFixture::sor(const SpanQueryPtr& s, const SpanQueryPtr& e) { return newLucene(newCollection(s, e)); } @@ -82,7 +82,7 @@ namespace Lucene return sor(st(s), st(m), st(e)); } - SpanOrQueryPtr ExplanationsFixture::sor(SpanQueryPtr s, SpanQueryPtr m, SpanQueryPtr e) + SpanOrQueryPtr ExplanationsFixture::sor(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e) { return newLucene(newCollection(s, m, e)); } @@ -92,7 +92,7 @@ namespace Lucene return snear(st(s), st(e), slop, inOrder); } - SpanNearQueryPtr ExplanationsFixture::snear(SpanQueryPtr s, SpanQueryPtr e, int32_t slop, bool inOrder) + SpanNearQueryPtr ExplanationsFixture::snear(const SpanQueryPtr& s, const SpanQueryPtr& e, int32_t slop, bool inOrder) { return newLucene(newCollection(s, e), slop, inOrder); } @@ -102,7 +102,7 @@ namespace Lucene return snear(st(s), st(m), st(e), slop, inOrder); } - SpanNearQueryPtr ExplanationsFixture::snear(SpanQueryPtr s, SpanQueryPtr m, SpanQueryPtr e, int32_t slop, bool inOrder) + SpanNearQueryPtr ExplanationsFixture::snear(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e, int32_t slop, bool inOrder) { return newLucene(newCollection(s, m, e), slop, inOrder); } @@ -112,7 +112,7 @@ namespace Lucene return optB(makeQuery(q)); } - QueryPtr ExplanationsFixture::optB(QueryPtr q) + QueryPtr ExplanationsFixture::optB(const QueryPtr& q) { BooleanQueryPtr bq = newLucene(true); bq->add(q, BooleanClause::SHOULD); @@ -125,7 +125,7 @@ namespace Lucene return reqB(makeQuery(q)); } - QueryPtr ExplanationsFixture::reqB(QueryPtr q) + QueryPtr ExplanationsFixture::reqB(const QueryPtr& q) { BooleanQueryPtr bq = newLucene(true); bq->add(q, BooleanClause::MUST); @@ -146,12 +146,12 @@ namespace Lucene qtest(makeQuery(queryText), expDocNrs); } - void ExplanationsFixture::qtest(QueryPtr q, Collection expDocNrs) + void ExplanationsFixture::qtest(const QueryPtr& q, Collection expDocNrs) { CheckHits::checkHitCollector(q, FIELD, searcher, expDocNrs); } - void ExplanationsFixture::bqtest(QueryPtr q, Collection expDocNrs) + void ExplanationsFixture::bqtest(const QueryPtr& q, Collection expDocNrs) { qtest(reqB(q), expDocNrs); qtest(optB(q), expDocNrs); diff --git a/src/test/search/FilteredQueryTest.cpp b/src/test/search/FilteredQueryTest.cpp index 9bea076c..a72108f1 100644 --- a/src/test/search/FilteredQueryTest.cpp +++ b/src/test/search/FilteredQueryTest.cpp @@ -39,7 +39,7 @@ class StaticFilterA : public Filter } public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { BitSetPtr bitset = newLucene(5); bitset->set((uint32_t)0, (uint32_t)5); @@ -55,7 +55,7 @@ class StaticFilterB : public Filter } public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { BitSetPtr bitset = newLucene(5); bitset->set(1); @@ -80,7 +80,7 @@ class SingleDocTestFilter : public Filter int32_t doc; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { BitSetPtr bits = newLucene(reader->maxDoc()); bits->set(doc); @@ -147,7 +147,7 @@ class FilteredQueryTest : public LuceneTestFixture return newLucene(); } - void checkScoreEquals(QueryPtr q1, QueryPtr q2) + void checkScoreEquals(const QueryPtr& q1, const QueryPtr& q2) { Collection hits1 = searcher->search(q1, FilterPtr(), 1000)->scoreDocs; Collection hits2 = searcher->search (q2, FilterPtr(), 1000)->scoreDocs; diff --git a/src/test/search/FilteredSearchTest.cpp b/src/test/search/FilteredSearchTest.cpp index 6adbb9b4..abd6a6d6 100644 --- a/src/test/search/FilteredSearchTest.cpp +++ b/src/test/search/FilteredSearchTest.cpp @@ -45,7 +45,7 @@ class SimpleDocIdSetFilter : public Filter int32_t index; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { OpenBitSetPtr set = newLucene(); int32_t limit = docBase + reader->maxDoc(); @@ -69,7 +69,7 @@ class SimpleDocIdSetFilter : public Filter static const String FIELD = L"category"; -static void searchFiltered(IndexWriterPtr writer, DirectoryPtr directory, FilterPtr filter, bool optimize) +static void searchFiltered(const IndexWriterPtr& writer, const DirectoryPtr& directory, const FilterPtr& filter, bool optimize) { for (int32_t i = 0; i < 60; ++i) { diff --git a/src/test/search/FuzzyQueryTest.cpp b/src/test/search/FuzzyQueryTest.cpp index d20b3a44..4e03c165 100644 --- a/src/test/search/FuzzyQueryTest.cpp +++ b/src/test/search/FuzzyQueryTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; typedef LuceneTestFixture FuzzyQueryTest; -static void addDoc(const String& text, IndexWriterPtr writer) +static void addDoc(const String& text, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", text, Field::STORE_YES, Field::INDEX_ANALYZED)); diff --git a/src/test/search/MatchAllDocsQueryTest.cpp b/src/test/search/MatchAllDocsQueryTest.cpp index 9be554b7..a47257ac 100644 --- a/src/test/search/MatchAllDocsQueryTest.cpp +++ b/src/test/search/MatchAllDocsQueryTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; typedef LuceneTestFixture MatchAllDocsQueryTest; -static void addDoc(const String& text, IndexWriterPtr iw, double boost) +static void addDoc(const String& text, const IndexWriterPtr& iw, double boost) { DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"key", text, Field::STORE_YES, Field::INDEX_ANALYZED); diff --git a/src/test/search/MockFilter.cpp b/src/test/search/MockFilter.cpp index cb662f18..269843fe 100644 --- a/src/test/search/MockFilter.cpp +++ b/src/test/search/MockFilter.cpp @@ -20,7 +20,7 @@ namespace Lucene { } - DocIdSetPtr MockFilter::getDocIdSet(IndexReaderPtr reader) + DocIdSetPtr MockFilter::getDocIdSet(const IndexReaderPtr& reader) { _wasCalled = true; return newLucene(newLucene()); diff --git a/src/test/search/MultiPhraseQueryTest.cpp b/src/test/search/MultiPhraseQueryTest.cpp index 71fd8d4b..28999b5b 100644 --- a/src/test/search/MultiPhraseQueryTest.cpp +++ b/src/test/search/MultiPhraseQueryTest.cpp @@ -27,14 +27,14 @@ using namespace Lucene; typedef LuceneTestFixture MultiPhraseQueryTest; -static void add(const String& s, IndexWriterPtr writer) +static void add(const String& s, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"body", s, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void add(const String& s, const String& type, IndexWriterPtr writer) +static void add(const String& s, const String& type, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"body", s, Field::STORE_YES, Field::INDEX_ANALYZED)); diff --git a/src/test/search/MultiSearcherRankingTest.cpp b/src/test/search/MultiSearcherRankingTest.cpp index 07e98eb2..1c0db4d3 100644 --- a/src/test/search/MultiSearcherRankingTest.cpp +++ b/src/test/search/MultiSearcherRankingTest.cpp @@ -57,7 +57,7 @@ class MultiSearcherRankingTest : public LuceneTestFixture SearcherPtr singleSearcher; public: - void addCollection1(IndexWriterPtr iw) + void addCollection1(const IndexWriterPtr& iw) { add(L"one blah three", iw); add(L"one foo three multiOne", iw); @@ -67,7 +67,7 @@ class MultiSearcherRankingTest : public LuceneTestFixture add(L"blueberry pizza", iw); } - void addCollection2(IndexWriterPtr iw) + void addCollection2(const IndexWriterPtr& iw) { add(L"two blah three", iw); add(L"two foo xxx multiTwo", iw); @@ -78,7 +78,7 @@ class MultiSearcherRankingTest : public LuceneTestFixture add(L"piccadilly circus", iw); } - void add(const String& value, IndexWriterPtr iw) + void add(const String& value, const IndexWriterPtr& iw) { DocumentPtr d = newLucene(); d->add(newLucene(FIELD_NAME, value, Field::STORE_YES, Field::INDEX_ANALYZED)); diff --git a/src/test/search/MultiSearcherTest.cpp b/src/test/search/MultiSearcherTest.cpp index 1c757f6c..dccf8ceb 100644 --- a/src/test/search/MultiSearcherTest.cpp +++ b/src/test/search/MultiSearcherTest.cpp @@ -45,7 +45,7 @@ static DocumentPtr createDocument(const String& contents1, const String& content return document; } -static void initIndex(DirectoryPtr directory, int32_t numDocs, bool create, const String& contents2) +static void initIndex(const DirectoryPtr& directory, int32_t numDocs, bool create, const String& contents2) { IndexWriterPtr indexWriter = newLucene(directory, newLucene(), create, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < numDocs; ++i) diff --git a/src/test/search/MultiTermConstantScoreTest.cpp b/src/test/search/MultiTermConstantScoreTest.cpp index 965e3c64..19deca5f 100644 --- a/src/test/search/MultiTermConstantScoreTest.cpp +++ b/src/test/search/MultiTermConstantScoreTest.cpp @@ -78,28 +78,28 @@ class MultiTermConstantScoreTest : public BaseTestRangeFilterFixture return query; } - QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, RewriteMethodPtr method) + QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, const RewriteMethodPtr& method) { TermRangeQueryPtr query = newLucene(f, l, h, il, ih); query->setRewriteMethod(method); return query; } - QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, CollatorPtr c) + QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, const CollatorPtr& c) { TermRangeQueryPtr query = newLucene(f, l, h, il, ih, c); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - QueryPtr cspq(TermPtr prefix) + QueryPtr cspq(const TermPtr& prefix) { PrefixQueryPtr query = newLucene(prefix); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - QueryPtr cswcq(TermPtr wild) + QueryPtr cswcq(const TermPtr& wild) { WildcardQueryPtr query = newLucene(wild); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); @@ -170,7 +170,7 @@ namespace TestBoost ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -180,7 +180,7 @@ namespace TestBoost EXPECT_EQ(1.0, scorer->score()); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } diff --git a/src/test/search/MultiThreadTermVectorsTest.cpp b/src/test/search/MultiThreadTermVectorsTest.cpp index 72f5127d..bcc1bb13 100644 --- a/src/test/search/MultiThreadTermVectorsTest.cpp +++ b/src/test/search/MultiThreadTermVectorsTest.cpp @@ -24,7 +24,7 @@ DECLARE_SHARED_PTR(MultiThreadTermVectorsReader) class MultiThreadTermVectorsReader : public LuceneThread { public: - MultiThreadTermVectorsReader(IndexReaderPtr reader) + MultiThreadTermVectorsReader(const IndexReaderPtr& reader) { this->reader = reader; timeElapsed = 0; @@ -128,7 +128,7 @@ class MultiThreadTermVectorsTest : public LuceneTestFixture int32_t numThreads; public: - void testTermPositionVectors(IndexReaderPtr reader, int32_t threadCount) + void testTermPositionVectors(const IndexReaderPtr& reader, int32_t threadCount) { Collection mtr = Collection::newInstance(threadCount); for (int32_t i = 0; i < threadCount; ++i) diff --git a/src/test/search/ParallelMultiSearcherTest.cpp b/src/test/search/ParallelMultiSearcherTest.cpp index 4141da4d..c497c483 100644 --- a/src/test/search/ParallelMultiSearcherTest.cpp +++ b/src/test/search/ParallelMultiSearcherTest.cpp @@ -45,7 +45,7 @@ static DocumentPtr createDocument(const String& contents1, const String& content return document; } -static void initIndex(DirectoryPtr directory, int32_t numDocs, bool create, const String& contents2) +static void initIndex(const DirectoryPtr& directory, int32_t numDocs, bool create, const String& contents2) { IndexWriterPtr indexWriter = newLucene(directory, newLucene(), create, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < numDocs; ++i) diff --git a/src/test/search/PhraseQueryTest.cpp b/src/test/search/PhraseQueryTest.cpp index 0c268d37..d3974233 100644 --- a/src/test/search/PhraseQueryTest.cpp +++ b/src/test/search/PhraseQueryTest.cpp @@ -34,7 +34,7 @@ class PhraseQueryAnalyzer : public Analyzer } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } diff --git a/src/test/search/PositionIncrementTest.cpp b/src/test/search/PositionIncrementTest.cpp index 4e8d7bfe..21356b0a 100644 --- a/src/test/search/PositionIncrementTest.cpp +++ b/src/test/search/PositionIncrementTest.cpp @@ -92,7 +92,7 @@ namespace TestSetPosition } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(); } @@ -116,7 +116,7 @@ namespace TestSetPosition WhitespaceAnalyzerPtr a; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr ts = a->tokenStream(fieldName, reader); return newLucene(enablePositionIncrements, ts, newLucene(newCollection(L"stop"), true)); @@ -261,7 +261,7 @@ namespace TestPayloadsPos0 class TestPayloadFilter : public TokenFilter { public: - TestPayloadFilter(TokenStreamPtr input, const String& fieldName) : TokenFilter(input) + TestPayloadFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->fieldName = fieldName; this->pos = 0; @@ -312,7 +312,7 @@ namespace TestPayloadsPos0 } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); return newLucene(result, fieldName); diff --git a/src/test/search/QueryUtils.cpp b/src/test/search/QueryUtils.cpp index 377f75af..5d2b0162 100644 --- a/src/test/search/QueryUtils.cpp +++ b/src/test/search/QueryUtils.cpp @@ -29,7 +29,7 @@ namespace Lucene { } - void QueryUtils::check(QueryPtr q) + void QueryUtils::check(const QueryPtr& q) { checkHashEquals(q); } @@ -47,7 +47,7 @@ namespace Lucene return L"My Whacky Query"; } - virtual bool equals(LuceneObjectPtr other) + virtual bool equals(const LuceneObjectPtr& other) { if (!MiscUtils::typeOf(other)) return false; @@ -55,7 +55,7 @@ namespace Lucene } }; - void QueryUtils::checkHashEquals(QueryPtr q) + void QueryUtils::checkHashEquals(const QueryPtr& q) { QueryPtr q2 = boost::dynamic_pointer_cast(q->clone()); checkEqual(q, q2); @@ -70,13 +70,13 @@ namespace Lucene checkUnequal(q, whacky); } - void QueryUtils::checkEqual(QueryPtr q1, QueryPtr q2) + void QueryUtils::checkEqual(const QueryPtr& q1, const QueryPtr& q2) { EXPECT_TRUE(q1->equals(q2)); EXPECT_EQ(q1->hashCode(), q2->hashCode()); } - void QueryUtils::checkUnequal(QueryPtr q1, QueryPtr q2) + void QueryUtils::checkUnequal(const QueryPtr& q1, const QueryPtr& q2) { EXPECT_TRUE(!q1->equals(q2)); EXPECT_TRUE(!q2->equals(q1)); @@ -86,17 +86,17 @@ namespace Lucene EXPECT_NE(q1->hashCode(), q2->hashCode()); } - void QueryUtils::checkExplanations(QueryPtr q, SearcherPtr s) + void QueryUtils::checkExplanations(const QueryPtr& q, const SearcherPtr& s) { CheckHits::checkExplanations(q, L"", s, true); } - void QueryUtils::check(QueryPtr q1, SearcherPtr s) + void QueryUtils::check(const QueryPtr& q1, const SearcherPtr& s) { check(q1, s, true); } - void QueryUtils::check(QueryPtr q1, SearcherPtr s, bool wrap) + void QueryUtils::check(const QueryPtr& q1, const SearcherPtr& s, bool wrap) { check(q1); if (s) @@ -126,7 +126,7 @@ namespace Lucene } } - IndexSearcherPtr QueryUtils::wrapUnderlyingReader(IndexSearcherPtr s, int32_t edge) + IndexSearcherPtr QueryUtils::wrapUnderlyingReader(const IndexSearcherPtr& s, int32_t edge) { IndexReaderPtr r = s->getIndexReader(); @@ -152,7 +152,7 @@ namespace Lucene return out; } - MultiSearcherPtr QueryUtils::wrapSearcher(SearcherPtr s, int32_t edge) + MultiSearcherPtr QueryUtils::wrapSearcher(const SearcherPtr& s, int32_t edge) { // we can't put deleted docs before the nested reader, because it will through off the docIds Collection searchers = newCollection( @@ -202,7 +202,7 @@ namespace Lucene class SkipCollector : public Collector { public: - SkipCollector(QueryPtr q, IndexSearcherPtr s, Collection lastDoc, Collection order, Collection opidx, Collection lastReader) + SkipCollector(const QueryPtr& q, const IndexSearcherPtr& s, Collection lastDoc, Collection order, Collection opidx, Collection lastReader) { this->q = q; this->s = s; @@ -229,7 +229,7 @@ namespace Lucene Collection lastReader; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->sc = scorer; } @@ -281,7 +281,7 @@ namespace Lucene } } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS if (lastReader[0]) @@ -307,7 +307,7 @@ namespace Lucene }; } - void QueryUtils::checkSkipTo(QueryPtr q, IndexSearcherPtr s) + void QueryUtils::checkSkipTo(const QueryPtr& q, const IndexSearcherPtr& s) { if (q->weight(s)->scoresDocsOutOfOrder()) return; // in this case order of skipTo() might differ from that of next(). @@ -354,7 +354,7 @@ namespace Lucene class SkipCollector : public Collector { public: - SkipCollector(QueryPtr q, IndexSearcherPtr s, Collection lastDoc, Collection lastReader) + SkipCollector(const QueryPtr& q, const IndexSearcherPtr& s, Collection lastDoc, Collection lastReader) { this->q = q; this->s = s; @@ -376,7 +376,7 @@ namespace Lucene IndexReaderPtr reader; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -398,7 +398,7 @@ namespace Lucene lastDoc[0] = doc; } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS if (lastReader[0]) @@ -425,7 +425,7 @@ namespace Lucene }; } - void QueryUtils::checkFirstSkipTo(QueryPtr q, IndexSearcherPtr s) + void QueryUtils::checkFirstSkipTo(const QueryPtr& q, const IndexSearcherPtr& s) { Collection lastDoc = newCollection(-1); Collection lastReader = Collection::newInstance(1); diff --git a/src/test/search/ScoreCachingWrappingScorerTest.cpp b/src/test/search/ScoreCachingWrappingScorerTest.cpp index f23c4fe8..e724723b 100644 --- a/src/test/search/ScoreCachingWrappingScorerTest.cpp +++ b/src/test/search/ScoreCachingWrappingScorerTest.cpp @@ -97,11 +97,11 @@ namespace TestGetScores ++idx; } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { } - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = newLucene(scorer); } diff --git a/src/test/search/ScorerPerfTest.cpp b/src/test/search/ScorerPerfTest.cpp index 618fd2c5..273c7df6 100644 --- a/src/test/search/ScorerPerfTest.cpp +++ b/src/test/search/ScorerPerfTest.cpp @@ -44,7 +44,7 @@ class CountingHitCollector : public Collector int32_t docBase; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { } @@ -64,7 +64,7 @@ class CountingHitCollector : public Collector return sum; } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } @@ -78,7 +78,7 @@ class CountingHitCollector : public Collector class MatchingHitCollector : public CountingHitCollector { public: - MatchingHitCollector(BitSetPtr answer) + MatchingHitCollector(const BitSetPtr& answer) { this->answer = answer; this->pos = -1; @@ -105,7 +105,7 @@ class MatchingHitCollector : public CountingHitCollector class AddClauseFilter : public Filter { public: - AddClauseFilter(BitSetPtr rnd) + AddClauseFilter(const BitSetPtr& rnd) { this->rnd = rnd; } @@ -118,7 +118,7 @@ class AddClauseFilter : public Filter BitSetPtr rnd; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { return newLucene(rnd); } @@ -212,16 +212,17 @@ class ScorerPerfTest : public LuceneTestFixture } } - BitSetPtr addClause(BooleanQueryPtr bq, BitSetPtr result) + BitSetPtr addClause(const BooleanQueryPtr& bq, const BitSetPtr& result) { BitSetPtr rnd = sets[r->nextInt(sets.size())]; QueryPtr q = newLucene(newLucene(rnd)); bq->add(q, BooleanClause::MUST); - if (!result) - result = boost::dynamic_pointer_cast(rnd->clone()); + BitSetPtr _result(result); + if (!_result) + _result = boost::dynamic_pointer_cast(rnd->clone()); else - result->_and(rnd); - return result; + _result->_and(rnd); + return _result; } }; diff --git a/src/test/search/SearchForDuplicatesTest.cpp b/src/test/search/SearchForDuplicatesTest.cpp index 928b9ad3..961ba63c 100644 --- a/src/test/search/SearchForDuplicatesTest.cpp +++ b/src/test/search/SearchForDuplicatesTest.cpp @@ -27,7 +27,7 @@ static const String HIGH_PRIORITY = L"high"; static const String MED_PRIORITY = L"medium"; static const String LOW_PRIORITY = L"low"; -static void printHits(StringStream& out, Collection hits, SearcherPtr searcher) +static void printHits(StringStream& out, Collection hits, const SearcherPtr& searcher) { out << hits.size() << L" total results\n"; for (int32_t i = 0; i < hits.size(); ++i) @@ -40,7 +40,7 @@ static void printHits(StringStream& out, Collection hits, SearcherP } } -static void checkHits(Collection hits, int32_t expectedCount, SearcherPtr searcher) +static void checkHits(Collection hits, int32_t expectedCount, const SearcherPtr& searcher) { EXPECT_EQ(expectedCount, hits.size()); for (int32_t i = 0; i < hits.size(); ++i) diff --git a/src/test/search/SetNormTest.cpp b/src/test/search/SetNormTest.cpp index 215749ce..e4c8014c 100644 --- a/src/test/search/SetNormTest.cpp +++ b/src/test/search/SetNormTest.cpp @@ -43,7 +43,7 @@ namespace TestSetNorm Collection scores; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -53,7 +53,7 @@ namespace TestSetNorm scores[doc + base] = scorer->score(); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } diff --git a/src/test/search/SimilarityTest.cpp b/src/test/search/SimilarityTest.cpp index 2313a056..40823ca3 100644 --- a/src/test/search/SimilarityTest.cpp +++ b/src/test/search/SimilarityTest.cpp @@ -84,7 +84,7 @@ namespace TestSimilarity return 1.0; } - virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher) + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) { return newLucene(); } @@ -101,7 +101,7 @@ namespace TestSimilarity ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -111,7 +111,7 @@ namespace TestSimilarity EXPECT_EQ(1.0, scorer->score()); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { } @@ -138,7 +138,7 @@ namespace TestSimilarity ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -148,7 +148,7 @@ namespace TestSimilarity EXPECT_EQ((double)doc + (double)base + 1.0, scorer->score()); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } @@ -176,7 +176,7 @@ namespace TestSimilarity ScorerPtr scorer; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -186,7 +186,7 @@ namespace TestSimilarity EXPECT_EQ(expectedScore, scorer->score()); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { } diff --git a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp index 87878c58..b59f6725 100644 --- a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp @@ -73,7 +73,7 @@ class SimpleExplanationsOfNonMatchesTest : public ExplanationsFixture using ExplanationsFixture::qtest; /// ignore matches and focus on non-matches - virtual void qtest(QueryPtr q, Collection expDocNrs) + virtual void qtest(const QueryPtr& q, Collection expDocNrs) { CheckHits::checkNoMatchExplanations(q, FIELD, searcher, expDocNrs); } diff --git a/src/test/search/SloppyPhraseQueryTest.cpp b/src/test/search/SloppyPhraseQueryTest.cpp index 98bd6abf..855dcd0a 100644 --- a/src/test/search/SloppyPhraseQueryTest.cpp +++ b/src/test/search/SloppyPhraseQueryTest.cpp @@ -78,7 +78,7 @@ class SloppyPhraseQueryTest : public LuceneTestFixture return query; } - double checkPhraseQuery(DocumentPtr doc, PhraseQueryPtr query, int32_t slop, int32_t expectedNumResults) + double checkPhraseQuery(const DocumentPtr& doc, const PhraseQueryPtr& query, int32_t slop, int32_t expectedNumResults) { query->setSlop(slop); diff --git a/src/test/search/SortTest.cpp b/src/test/search/SortTest.cpp index 3c891a96..fa2176cf 100644 --- a/src/test/search/SortTest.cpp +++ b/src/test/search/SortTest.cpp @@ -159,7 +159,7 @@ class SortTest : public LuceneTestFixture return s; } - MapStringDouble getScores(Collection hits, SearcherPtr searcher) + MapStringDouble getScores(Collection hits, const SearcherPtr& searcher) { MapStringDouble scoreMap = MapStringDouble::newInstance(); int32_t n = hits.size(); @@ -187,7 +187,7 @@ class SortTest : public LuceneTestFixture } /// make sure the documents returned by the search match the expected list - void checkMatches(SearcherPtr searcher, QueryPtr query, SortPtr sort, const String& expectedResult) + void checkMatches(const SearcherPtr& searcher, const QueryPtr& query, const SortPtr& sort, const String& expectedResult) { TopDocsPtr hits = searcher->search(query, FilterPtr(), expectedResult.length(), sort); Collection result = hits->scoreDocs; @@ -262,7 +262,7 @@ class SortTest : public LuceneTestFixture } /// runs a variety of sorts useful for multisearchers - void runMultiSorts(SearcherPtr multi, bool isFull) + void runMultiSorts(const SearcherPtr& multi, bool isFull) { sort->setSort(SortField::FIELD_DOC()); String expected = isFull ? L"ABCDEFGHIJ" : L"ACEGIBDFHJ"; @@ -588,7 +588,7 @@ namespace TestNewCustomFieldParserSort bottomValue = slotValues[slot]; } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { docValues = FieldCache::DEFAULT()->getInts(reader, L"parser", newLucene()); } @@ -828,7 +828,7 @@ namespace TestTopDocsScores class TopDocsFilter : public Filter { public: - TopDocsFilter(TopDocsPtr docs) + TopDocsFilter(const TopDocsPtr& docs) { this->docs = docs; } @@ -841,7 +841,7 @@ namespace TestTopDocsScores TopDocsPtr docs; public: - virtual DocIdSetPtr getDocIdSet(IndexReaderPtr reader) + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { BitSetPtr bs = newLucene(reader->maxDoc()); bs->set((uint32_t)0, (uint32_t)reader->maxDoc()); diff --git a/src/test/search/SpanQueryFilterTest.cpp b/src/test/search/SpanQueryFilterTest.cpp index 1308464c..5e7d9719 100644 --- a/src/test/search/SpanQueryFilterTest.cpp +++ b/src/test/search/SpanQueryFilterTest.cpp @@ -24,7 +24,7 @@ using namespace Lucene; typedef LuceneTestFixture SpanQueryFilterTest; -static int32_t getDocIdSetSize(DocIdSetPtr docIdSet) +static int32_t getDocIdSetSize(const DocIdSetPtr& docIdSet) { int32_t size = 0; DocIdSetIteratorPtr it = docIdSet->iterator(); @@ -33,7 +33,7 @@ static int32_t getDocIdSetSize(DocIdSetPtr docIdSet) return size; } -static void checkContainsDocId(DocIdSetPtr docIdSet, int32_t docId) +static void checkContainsDocId(const DocIdSetPtr& docIdSet, int32_t docId) { DocIdSetIteratorPtr it = docIdSet->iterator(); EXPECT_NE(it->advance(docId), DocIdSetIterator::NO_MORE_DOCS); diff --git a/src/test/search/TermRangeQueryTest.cpp b/src/test/search/TermRangeQueryTest.cpp index 351b4d64..7ad3f7b6 100644 --- a/src/test/search/TermRangeQueryTest.cpp +++ b/src/test/search/TermRangeQueryTest.cpp @@ -26,7 +26,7 @@ using namespace Lucene; class SingleCharTokenizer : public Tokenizer { public: - SingleCharTokenizer(ReaderPtr r) : Tokenizer(r) + SingleCharTokenizer(const ReaderPtr& r) : Tokenizer(r) { termAtt = addAttribute(); buffer = CharArray::newInstance(1); @@ -63,7 +63,7 @@ class SingleCharTokenizer : public Tokenizer } } - virtual void reset(ReaderPtr input) + virtual void reset(const ReaderPtr& input) { Tokenizer::reset(input); done = false; @@ -78,7 +78,7 @@ class SingleCharAnalyzer : public Analyzer } public: - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { TokenizerPtr tokenizer = boost::dynamic_pointer_cast(getPreviousTokenStream()); if (!tokenizer) @@ -91,7 +91,7 @@ class SingleCharAnalyzer : public Analyzer return tokenizer; } - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } @@ -120,7 +120,7 @@ class TermRangeQueryTest : public LuceneTestFixture initializeIndex(values, newLucene()); } - void initializeIndex(Collection values, AnalyzerPtr analyzer) + void initializeIndex(Collection values, const AnalyzerPtr& analyzer) { IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); for (int32_t i = 0; i < values.size(); ++i) @@ -135,7 +135,7 @@ class TermRangeQueryTest : public LuceneTestFixture writer->close(); } - void insertDoc(IndexWriterPtr writer, const String& content) + void insertDoc(const IndexWriterPtr& writer, const String& content) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", L"id" + StringUtils::toString(docCount), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); diff --git a/src/test/search/TermScorerTest.cpp b/src/test/search/TermScorerTest.cpp index 3534a0b2..3a926c73 100644 --- a/src/test/search/TermScorerTest.cpp +++ b/src/test/search/TermScorerTest.cpp @@ -103,7 +103,7 @@ namespace TestTermScorer Collection docs; public: - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } @@ -117,7 +117,7 @@ namespace TestTermScorer EXPECT_TRUE(doc == 0 || doc == 5); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } diff --git a/src/test/search/TermVectorsTest.cpp b/src/test/search/TermVectorsTest.cpp index d05bed69..53d09bc4 100644 --- a/src/test/search/TermVectorsTest.cpp +++ b/src/test/search/TermVectorsTest.cpp @@ -68,7 +68,7 @@ class TermVectorsTest : public LuceneTestFixture DirectoryPtr directory; public: - void setupDoc(DocumentPtr doc, const String& text) + void setupDoc(const DocumentPtr& doc, const String& text) { doc->add(newLucene(L"field2", text, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); doc->add(newLucene(L"field", text, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); diff --git a/src/test/search/ThreadSafeTest.cpp b/src/test/search/ThreadSafeTest.cpp index b427634b..06d1aca0 100644 --- a/src/test/search/ThreadSafeTest.cpp +++ b/src/test/search/ThreadSafeTest.cpp @@ -22,7 +22,7 @@ using namespace Lucene; class TestFieldSelector : public FieldSelector { public: - TestFieldSelector(RandomPtr rand) + TestFieldSelector(const RandomPtr& rand) { this->rand = rand; } @@ -52,7 +52,7 @@ class TestFieldSelector : public FieldSelector class TestThread : public LuceneThread { public: - TestThread(int32_t iter, RandomPtr rand, IndexReaderPtr reader) + TestThread(int32_t iter, const RandomPtr& rand, const IndexReaderPtr& reader) { this->iter = iter; this->rand = rand; @@ -92,7 +92,7 @@ class TestThread : public LuceneThread validateField(fields[i]); } - void validateField(FieldablePtr f) + void validateField(const FieldablePtr& f) { String val = f->stringValue(); if (!boost::starts_with(val, L"^") || !boost::ends_with(val, L"$")) @@ -121,7 +121,7 @@ class ThreadSafeTest : public LuceneTestFixture Collection words; public: - void buildDir(DirectoryPtr dir, int32_t numDocs, int32_t maxFields, int32_t maxFieldLen) + void buildDir(const DirectoryPtr& dir, int32_t numDocs, int32_t maxFields, int32_t maxFieldLen) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); diff --git a/src/test/search/TimeLimitingCollectorTest.cpp b/src/test/search/TimeLimitingCollectorTest.cpp index 273073d1..b0fe6d5b 100644 --- a/src/test/search/TimeLimitingCollectorTest.cpp +++ b/src/test/search/TimeLimitingCollectorTest.cpp @@ -61,7 +61,7 @@ class MyHitCollector : public Collector return lastDocCollected; } - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { // scorer is not needed } @@ -77,7 +77,7 @@ class MyHitCollector : public Collector lastDocCollected = docId; } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } @@ -171,7 +171,7 @@ class TimeLimitingCollectorTest : public LuceneTestFixture QueryPtr query; public: - void add(const String& value, IndexWriterPtr writer) + void add(const String& value, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD_NAME, value, Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -301,14 +301,14 @@ class TimeLimitingCollectorTest : public LuceneTestFixture return StringUtils::toString(maxTime(multiThreaded)) + L" = " + buf.str(); } - CollectorPtr createTimedCollector(MyHitCollectorPtr hc, int64_t timeAllowed, bool greedy) + CollectorPtr createTimedCollector(const MyHitCollectorPtr& hc, int64_t timeAllowed, bool greedy) { TimeLimitingCollectorPtr res = newLucene(hc, timeAllowed); res->setGreedy(greedy); // set to true to make sure at least one doc is collected. return res; } - void search(CollectorPtr collector) + void search(const CollectorPtr& collector) { searcher->search(query, collector); } diff --git a/src/test/search/TopDocsCollectorTest.cpp b/src/test/search/TopDocsCollectorTest.cpp index 0454ec4f..498e49c3 100644 --- a/src/test/search/TopDocsCollectorTest.cpp +++ b/src/test/search/TopDocsCollectorTest.cpp @@ -62,12 +62,12 @@ class MyTopsDocCollector : public TopDocsCollector pq->addOverflow(newLucene(doc + base, scores[idx++])); } - virtual void setNextReader(IndexReaderPtr reader, int32_t docBase) + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } - virtual void setScorer(ScorerPtr scorer) + virtual void setScorer(const ScorerPtr& scorer) { // Don't do anything. Assign scores in random } diff --git a/src/test/search/WildcardTest.cpp b/src/test/search/WildcardTest.cpp index fa9c50df..7388776c 100644 --- a/src/test/search/WildcardTest.cpp +++ b/src/test/search/WildcardTest.cpp @@ -45,7 +45,7 @@ static RAMDirectoryPtr getIndexStore(const String& field, Collection con return indexStore; } -static void checkMatches(IndexSearcherPtr searcher, QueryPtr q, int32_t expectedMatches) +static void checkMatches(const IndexSearcherPtr& searcher, const QueryPtr& q, int32_t expectedMatches) { Collection result = searcher->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(expectedMatches, result.size()); diff --git a/src/test/search/function/CustomScoreQueryTest.cpp b/src/test/search/function/CustomScoreQueryTest.cpp index 9bae8c1a..8cf4e060 100644 --- a/src/test/search/function/CustomScoreQueryTest.cpp +++ b/src/test/search/function/CustomScoreQueryTest.cpp @@ -25,7 +25,7 @@ using namespace Lucene; class CustomAddScoreProvider : public CustomScoreProvider { public: - CustomAddScoreProvider(IndexReaderPtr reader) : CustomScoreProvider(reader) + CustomAddScoreProvider(const IndexReaderPtr& reader) : CustomScoreProvider(reader) { } @@ -39,7 +39,7 @@ class CustomAddScoreProvider : public CustomScoreProvider return subQueryScore + valSrcScore; } - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, ExplanationPtr valSrcExpl) + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { double valSrcScore = valSrcExpl ? valSrcExpl->getValue() : 0.0; ExplanationPtr exp = newLucene(valSrcScore + subQueryExpl->getValue(), L"custom score: sum of:"); @@ -53,7 +53,7 @@ class CustomAddScoreProvider : public CustomScoreProvider class CustomAddQuery : public CustomScoreQuery { public: - CustomAddQuery(QueryPtr q, ValueSourceQueryPtr qValSrc) : CustomScoreQuery(q, qValSrc) + CustomAddQuery(const QueryPtr& q, const ValueSourceQueryPtr& qValSrc) : CustomScoreQuery(q, qValSrc) { } @@ -68,7 +68,7 @@ class CustomAddQuery : public CustomScoreQuery } protected: - virtual CustomScoreProviderPtr getCustomScoreProvider(IndexReaderPtr reader) + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) { return newLucene(reader); } @@ -77,7 +77,7 @@ class CustomAddQuery : public CustomScoreQuery class CustomMulAddScoreProvider : public CustomScoreProvider { public: - CustomMulAddScoreProvider(IndexReaderPtr reader) : CustomScoreProvider(reader) + CustomMulAddScoreProvider(const IndexReaderPtr& reader) : CustomScoreProvider(reader) { } @@ -96,7 +96,7 @@ class CustomMulAddScoreProvider : public CustomScoreProvider return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know there are two } - virtual ExplanationPtr customExplain(int32_t doc, ExplanationPtr subQueryExpl, Collection valSrcExpls) + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { if (valSrcExpls.empty()) return subQueryExpl; @@ -118,7 +118,7 @@ class CustomMulAddScoreProvider : public CustomScoreProvider class CustomMulAddQuery : public CustomScoreQuery { public: - CustomMulAddQuery(QueryPtr q, ValueSourceQueryPtr qValSrc1, ValueSourceQueryPtr qValSrc2) : CustomScoreQuery(q, newCollection(qValSrc1, qValSrc2)) + CustomMulAddQuery(const QueryPtr& q, const ValueSourceQueryPtr& qValSrc1, const ValueSourceQueryPtr& qValSrc2) : CustomScoreQuery(q, newCollection(qValSrc1, qValSrc2)) { } @@ -133,7 +133,7 @@ class CustomMulAddQuery : public CustomScoreQuery } protected: - virtual CustomScoreProviderPtr getCustomScoreProvider(IndexReaderPtr reader) + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) { return newLucene(reader); } @@ -142,7 +142,7 @@ class CustomMulAddQuery : public CustomScoreQuery class CustomExternalScoreProvider : public CustomScoreProvider { public: - CustomExternalScoreProvider(IndexReaderPtr reader, Collection values) : CustomScoreProvider(reader) + CustomExternalScoreProvider(const IndexReaderPtr& reader, Collection values) : CustomScoreProvider(reader) { this->values = values; } @@ -165,7 +165,7 @@ class CustomExternalScoreProvider : public CustomScoreProvider class CustomExternalQuery : public CustomScoreQuery { public: - CustomExternalQuery(QueryPtr q) : CustomScoreQuery(q) + CustomExternalQuery(const QueryPtr& q) : CustomScoreQuery(q) { } @@ -174,7 +174,7 @@ class CustomExternalQuery : public CustomScoreQuery } protected: - virtual CustomScoreProviderPtr getCustomScoreProvider(IndexReaderPtr reader) + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) { Collection values = FieldCache::DEFAULT()->getInts(reader, FunctionFixture::INT_FIELD); return newLucene(reader, values); @@ -194,7 +194,7 @@ class CustomScoreQueryTest : public FunctionFixture public: /// since custom scoring modifies the order of docs, map results by doc ids so that we can later compare/verify them - MapIntDouble topDocsToMap(TopDocsPtr td) + MapIntDouble topDocsToMap(const TopDocsPtr& td) { MapIntDouble h = MapIntDouble::newInstance(); for (int32_t i = 0; i < td->totalHits; ++i) diff --git a/src/test/search/function/FunctionFixture.cpp b/src/test/search/function/FunctionFixture.cpp index 7d1eb15f..d60fd34d 100644 --- a/src/test/search/function/FunctionFixture.cpp +++ b/src/test/search/function/FunctionFixture.cpp @@ -79,7 +79,7 @@ namespace Lucene return _DOC_TEXT_LINES; } - void FunctionFixture::addDoc(IndexWriterPtr iw, int32_t i) + void FunctionFixture::addDoc(const IndexWriterPtr& iw, int32_t i) { DocumentPtr d = newLucene(); int32_t scoreAndID = i + 1; diff --git a/src/test/search/payloads/PayloadHelper.cpp b/src/test/search/payloads/PayloadHelper.cpp index 3eeb6fda..a5ee28ab 100644 --- a/src/test/search/payloads/PayloadHelper.cpp +++ b/src/test/search/payloads/PayloadHelper.cpp @@ -29,7 +29,7 @@ namespace Lucene class PayloadHelperFilter : public TokenFilter { public: - PayloadHelperFilter(TokenStreamPtr input, const String& fieldName) : TokenFilter(input) + PayloadHelperFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->numSeen = 0; this->fieldName = fieldName; @@ -78,7 +78,7 @@ namespace Lucene LUCENE_CLASS(PayloadHelperAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result, fieldName); @@ -123,7 +123,7 @@ namespace Lucene return _payloadMultiField2; } - IndexSearcherPtr PayloadHelper::setUp(SimilarityPtr similarity, int32_t numDocs) + IndexSearcherPtr PayloadHelper::setUp(const SimilarityPtr& similarity, int32_t numDocs) { RAMDirectoryPtr directory = newLucene(); PayloadHelperAnalyzerPtr analyzer = newLucene(); diff --git a/src/test/search/payloads/PayloadNearQueryTest.cpp b/src/test/search/payloads/PayloadNearQueryTest.cpp index 1f04451a..117c6bb2 100644 --- a/src/test/search/payloads/PayloadNearQueryTest.cpp +++ b/src/test/search/payloads/PayloadNearQueryTest.cpp @@ -91,7 +91,7 @@ class BoostingNearSimilarity : public DefaultSimilarity return 1.0; } - virtual IDFExplanationPtr idfExplain(Collection terms, SearcherPtr searcher) + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) { return newLucene(); } @@ -100,7 +100,7 @@ class BoostingNearSimilarity : public DefaultSimilarity class PayloadNearFilter : public TokenFilter { public: - PayloadNearFilter(ByteArray payload2, ByteArray payload4, TokenStreamPtr input, const String& fieldName) : TokenFilter(input) + PayloadNearFilter(ByteArray payload2, ByteArray payload4, const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->payload2 = payload2; this->payload4 = payload4; @@ -159,7 +159,7 @@ class PayloadNearAnalyzer : public Analyzer ByteArray payload4; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(payload2, payload4, result, fieldName); diff --git a/src/test/search/payloads/PayloadTermQueryTest.cpp b/src/test/search/payloads/PayloadTermQueryTest.cpp index 1cbf409c..3af8cc92 100644 --- a/src/test/search/payloads/PayloadTermQueryTest.cpp +++ b/src/test/search/payloads/PayloadTermQueryTest.cpp @@ -101,7 +101,7 @@ class FullSimilarity : public DefaultSimilarity class PayloadTermFilter : public TokenFilter { public: - PayloadTermFilter(ByteArray payloadField, ByteArray payloadMultiField1, ByteArray payloadMultiField2, TokenStreamPtr input, const String& fieldName) : TokenFilter(input) + PayloadTermFilter(ByteArray payloadField, ByteArray payloadMultiField1, ByteArray payloadMultiField2, const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->payloadField = payloadField; this->payloadMultiField1 = payloadMultiField1; @@ -170,7 +170,7 @@ class PayloadTermAnalyzer : public Analyzer ByteArray payloadMultiField2; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(payloadField, payloadMultiField1, payloadMultiField2, result, fieldName); diff --git a/src/test/search/spans/BasicSpansTest.cpp b/src/test/search/spans/BasicSpansTest.cpp index fcd89978..e005f750 100644 --- a/src/test/search/spans/BasicSpansTest.cpp +++ b/src/test/search/spans/BasicSpansTest.cpp @@ -62,12 +62,12 @@ class BasicSpansTest : public LuceneTestFixture IndexSearcherPtr searcher; public: - void checkHits(QueryPtr query, Collection results) + void checkHits(const QueryPtr& query, Collection results) { CheckHits::checkHits(query, L"field", searcher, results); } - bool skipTo(SpansPtr s, int32_t target) + bool skipTo(const SpansPtr& s, int32_t target) { do { diff --git a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp index e1702e2c..1bc9c542 100644 --- a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp +++ b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp @@ -110,12 +110,12 @@ class FieldMaskingSpanQueryTest : public LuceneTestFixture return newLucene(name, value, Field::STORE_NO, Field::INDEX_ANALYZED); } - void check(SpanQueryPtr q, Collection docs) + void check(const SpanQueryPtr& q, Collection docs) { CheckHits::checkHitCollector(q, L"", searcher, docs); } - String str(SpansPtr span) + String str(const SpansPtr& span) { return str(span->doc(), span->start(), span->end()); } @@ -144,7 +144,7 @@ namespace TestRewrite class TestableFieldMaskingSpanQuery : public FieldMaskingSpanQuery { public: - TestableFieldMaskingSpanQuery(SpanQueryPtr maskedQuery, const String& maskedField) : FieldMaskingSpanQuery(maskedQuery, maskedField) + TestableFieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField) : FieldMaskingSpanQuery(maskedQuery, maskedField) { } @@ -153,7 +153,7 @@ namespace TestRewrite } public: - virtual QueryPtr rewrite(IndexReaderPtr reader) + virtual QueryPtr rewrite(const IndexReaderPtr& reader) { return newLucene(newCollection( newLucene(newLucene(L"first", L"sally")), diff --git a/src/test/search/spans/NearSpansOrderedTest.cpp b/src/test/search/spans/NearSpansOrderedTest.cpp index 45b8f2cb..89b68cc3 100644 --- a/src/test/search/spans/NearSpansOrderedTest.cpp +++ b/src/test/search/spans/NearSpansOrderedTest.cpp @@ -71,7 +71,7 @@ class NearSpansOrderedTest : public LuceneTestFixture return makeQuery(L"w1", L"w2", L"w3", 1, true); } - String str(SpansPtr span) + String str(const SpansPtr& span) { return str(span->doc(), span->start(), span->end()); } diff --git a/src/test/search/spans/PayloadSpansTest.cpp b/src/test/search/spans/PayloadSpansTest.cpp index 21af398f..3c02ff3e 100644 --- a/src/test/search/spans/PayloadSpansTest.cpp +++ b/src/test/search/spans/PayloadSpansTest.cpp @@ -39,7 +39,7 @@ DECLARE_SHARED_PTR(PayloadSpansAnalyzer) class PayloadSpansFilter : public TokenFilter { public: - PayloadSpansFilter(TokenStreamPtr input, const String& fieldName) : TokenFilter(input) + PayloadSpansFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->fieldName = fieldName; this->pos = 0; @@ -107,7 +107,7 @@ class PayloadSpansAnalyzer : public Analyzer LUCENE_CLASS(PayloadSpansAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, ReaderPtr reader) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result, fieldName); @@ -135,7 +135,7 @@ class PayloadSpansTest : public LuceneTestFixture IndexReaderPtr indexReader; public: - void checkSpans(SpansPtr spans, int32_t expectedNumSpans, int32_t expectedNumPayloads, int32_t expectedPayloadLength, int32_t expectedFirstByte) + void checkSpans(const SpansPtr& spans, int32_t expectedNumSpans, int32_t expectedNumPayloads, int32_t expectedPayloadLength, int32_t expectedFirstByte) { EXPECT_TRUE(spans); int32_t seen = 0; @@ -162,7 +162,7 @@ class PayloadSpansTest : public LuceneTestFixture EXPECT_EQ(seen, expectedNumSpans); } - void checkSpans(SpansPtr spans, int32_t numSpans, Collection numPayloads) + void checkSpans(const SpansPtr& spans, int32_t numSpans, Collection numPayloads) { int32_t cnt = 0; while (spans->next()) diff --git a/src/test/search/spans/SpansAdvanced2Test.cpp b/src/test/search/spans/SpansAdvanced2Test.cpp index 3aa79eb7..e9889542 100644 --- a/src/test/search/spans/SpansAdvanced2Test.cpp +++ b/src/test/search/spans/SpansAdvanced2Test.cpp @@ -62,7 +62,7 @@ class SpansAdvanced2Test : public LuceneTestFixture IndexSearcherPtr searcher; IndexSearcherPtr searcher2; - void addDocument(IndexWriterPtr writer, const String& id, const String& text) + void addDocument(const IndexWriterPtr& writer, const String& id, const String& text) { DocumentPtr document = newLucene(); document->add(newLucene(FIELD_ID, id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -70,7 +70,7 @@ class SpansAdvanced2Test : public LuceneTestFixture writer->addDocument(document); } - void checkHits(SearcherPtr s, QueryPtr query, const String& description, Collection expectedIds, Collection expectedScores) + void checkHits(const SearcherPtr& s, const QueryPtr& query, const String& description, Collection expectedIds, Collection expectedScores) { QueryUtils::check(query, s); diff --git a/src/test/search/spans/SpansAdvancedTest.cpp b/src/test/search/spans/SpansAdvancedTest.cpp index 13641a49..089a0810 100644 --- a/src/test/search/spans/SpansAdvancedTest.cpp +++ b/src/test/search/spans/SpansAdvancedTest.cpp @@ -52,7 +52,7 @@ class SpansAdvancedTest : public LuceneTestFixture DirectoryPtr directory; IndexSearcherPtr searcher; - void addDocument(IndexWriterPtr writer, const String& id, const String& text) + void addDocument(const IndexWriterPtr& writer, const String& id, const String& text) { DocumentPtr document = newLucene(); document->add(newLucene(FIELD_ID, id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -60,7 +60,7 @@ class SpansAdvancedTest : public LuceneTestFixture writer->addDocument(document); } - void checkHits(SearcherPtr s, QueryPtr query, const String& description, Collection expectedIds, Collection expectedScores) + void checkHits(const SearcherPtr& s, const QueryPtr& query, const String& description, Collection expectedIds, Collection expectedScores) { QueryUtils::check(query, s); diff --git a/src/test/search/spans/SpansTest.cpp b/src/test/search/spans/SpansTest.cpp index e51667b6..dfc257b1 100644 --- a/src/test/search/spans/SpansTest.cpp +++ b/src/test/search/spans/SpansTest.cpp @@ -78,12 +78,12 @@ class SpansTest : public LuceneTestFixture return newLucene(newLucene(field, text)); } - void checkHits(QueryPtr query, Collection results) + void checkHits(const QueryPtr& query, Collection results) { CheckHits::checkHits(query, field, searcher, results); } - void orderedSlopTest3SQ(SpanQueryPtr q1, SpanQueryPtr q2, SpanQueryPtr q3, int32_t slop, Collection expectedDocs) + void orderedSlopTest3SQ(const SpanQueryPtr& q1, const SpanQueryPtr& q2, const SpanQueryPtr& q3, int32_t slop, Collection expectedDocs) { bool ordered = true; SpanNearQueryPtr snq = newLucene(newCollection(q1, q2, q3), slop, ordered); @@ -113,7 +113,7 @@ class SpansTest : public LuceneTestFixture return newLucene(sqa)->getSpans(searcher->getIndexReader()); } - void checkNextSpans(SpansPtr spans, int32_t doc, int32_t start, int32_t end) + void checkNextSpans(const SpansPtr& spans, int32_t doc, int32_t start, int32_t end) { EXPECT_TRUE(spans->next()); EXPECT_EQ(doc, spans->doc()); @@ -121,7 +121,7 @@ class SpansTest : public LuceneTestFixture EXPECT_EQ(end, spans->end()); } - void addDoc(IndexWriterPtr writer, const String& id, const String& text) + void addDoc(const IndexWriterPtr& writer, const String& id, const String& text) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -129,7 +129,7 @@ class SpansTest : public LuceneTestFixture writer->addDocument(doc); } - int32_t hitCount(SearcherPtr searcher, const String& word) + int32_t hitCount(const SearcherPtr& searcher, const String& word) { return searcher->search(newLucene(newLucene(L"text", word)), 10)->totalHits; } @@ -418,7 +418,7 @@ namespace TestSpanScorerZeroSloppyFreq class SloppyFreqSpanNearQuery : public SpanNearQuery { public: - SloppyFreqSpanNearQuery(SimilarityPtr sim, Collection clauses, int32_t slop, bool inOrder) : SpanNearQuery(clauses, slop, inOrder) + SloppyFreqSpanNearQuery(const SimilarityPtr& sim, Collection clauses, int32_t slop, bool inOrder) : SpanNearQuery(clauses, slop, inOrder) { this->sim = sim; } @@ -431,7 +431,7 @@ namespace TestSpanScorerZeroSloppyFreq SimilarityPtr sim; public: - virtual SimilarityPtr getSimilarity(SearcherPtr searcher) + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher) { return sim; } diff --git a/src/test/store/BufferedIndexInputTest.cpp b/src/test/store/BufferedIndexInputTest.cpp index 6580a02f..c7715d5f 100644 --- a/src/test/store/BufferedIndexInputTest.cpp +++ b/src/test/store/BufferedIndexInputTest.cpp @@ -362,7 +362,7 @@ TEST_F(BufferedIndexInputTest, testReadByte) EXPECT_EQ(input->readByte(), byten(i)); } -void checkReadBytes(IndexInputPtr input, int32_t size, int32_t pos) +void checkReadBytes(const IndexInputPtr& input, int32_t size, int32_t pos) { // Just to see that "offset" is treated properly in readBytes(), we add an arbitrary offset at // the beginning of the array @@ -381,7 +381,7 @@ void checkReadBytes(IndexInputPtr input, int32_t size, int32_t pos) EXPECT_EQ(byten(pos + i), buffer[offset + i]); } -void runReadBytes(IndexInputPtr input, int32_t bufferSize) +void runReadBytes(const IndexInputPtr& input, int32_t bufferSize) { int32_t pos = 0; RandomPtr random = newLucene(); @@ -425,7 +425,7 @@ void runReadBytes(IndexInputPtr input, int32_t bufferSize) } } -void runReadBytesAndClose(IndexInputPtr input, int32_t bufferSize) +void runReadBytesAndClose(const IndexInputPtr& input, int32_t bufferSize) { LuceneException finally; try diff --git a/src/test/store/DirectoryTest.cpp b/src/test/store/DirectoryTest.cpp index fae7cfce..0da450b5 100644 --- a/src/test/store/DirectoryTest.cpp +++ b/src/test/store/DirectoryTest.cpp @@ -157,7 +157,7 @@ TEST_F(DirectoryTest, testDontCreate) FileUtils::removeDirectory(path); } -void checkDirectoryFilter(DirectoryPtr dir) +void checkDirectoryFilter(const DirectoryPtr& dir) { String name(L"file"); dir->createOutput(name)->close(); diff --git a/src/test/store/FileSwitchDirectoryTest.cpp b/src/test/store/FileSwitchDirectoryTest.cpp index 0739358a..57575987 100644 --- a/src/test/store/FileSwitchDirectoryTest.cpp +++ b/src/test/store/FileSwitchDirectoryTest.cpp @@ -32,7 +32,7 @@ static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t nu return doc; } -static void createIndexNoClose(bool multiSegment, const String& indexName, IndexWriterPtr writer) +static void createIndexNoClose(bool multiSegment, const String& indexName, const IndexWriterPtr& writer) { for (int32_t i = 0; i < 100; ++i) writer->addDocument(createDocument(i, indexName, 4)); diff --git a/src/test/store/LockFactoryTest.cpp b/src/test/store/LockFactoryTest.cpp index 0c12881f..95191015 100644 --- a/src/test/store/LockFactoryTest.cpp +++ b/src/test/store/LockFactoryTest.cpp @@ -32,7 +32,7 @@ using namespace Lucene; typedef LuceneTestFixture LockFactoryTest; -static void addDoc(IndexWriterPtr writer) +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc(newLucene()); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -131,7 +131,7 @@ namespace LockFactoryTestNS class WriterThread : public LuceneThread { public: - WriterThread(int32_t numIteration, DirectoryPtr dir) + WriterThread(int32_t numIteration, const DirectoryPtr& dir) { this->numIteration = numIteration; this->dir = dir; @@ -211,7 +211,7 @@ namespace LockFactoryTestNS class LockFactorySearcherThread : public LuceneThread { public: - LockFactorySearcherThread(int32_t numIteration, DirectoryPtr dir) + LockFactorySearcherThread(int32_t numIteration, const DirectoryPtr& dir) { this->numIteration = numIteration; this->dir = dir; @@ -278,7 +278,7 @@ namespace LockFactoryTestNS }; } -static void _testStressLocks(LockFactoryPtr lockFactory, const String& indexDir) +static void _testStressLocks(const LockFactoryPtr& lockFactory, const String& indexDir) { FSDirectoryPtr fs1 = FSDirectory::open(indexDir, lockFactory); diff --git a/src/test/store/MockRAMDirectory.cpp b/src/test/store/MockRAMDirectory.cpp index a063de77..0de025a6 100644 --- a/src/test/store/MockRAMDirectory.cpp +++ b/src/test/store/MockRAMDirectory.cpp @@ -26,7 +26,7 @@ namespace Lucene init(); } - MockRAMDirectory::MockRAMDirectory(DirectoryPtr dir) : RAMDirectory(dir) + MockRAMDirectory::MockRAMDirectory(const DirectoryPtr& dir) : RAMDirectory(dir) { maxSize = 0; maxUsedSize = 0; @@ -277,7 +277,7 @@ namespace Lucene } } - void MockRAMDirectory::failOn(MockDirectoryFailurePtr fail) + void MockRAMDirectory::failOn(const MockDirectoryFailurePtr& fail) { SyncLock syncLock(this); if (!failures) @@ -304,7 +304,7 @@ namespace Lucene { } - void MockDirectoryFailure::eval(MockRAMDirectoryPtr dir) + void MockDirectoryFailure::eval(const MockRAMDirectoryPtr& dir) { } diff --git a/src/test/store/MockRAMInputStream.cpp b/src/test/store/MockRAMInputStream.cpp index 10f43fdc..87a4bc62 100644 --- a/src/test/store/MockRAMInputStream.cpp +++ b/src/test/store/MockRAMInputStream.cpp @@ -15,7 +15,7 @@ namespace Lucene this->isClone = false; } - MockRAMInputStream::MockRAMInputStream(MockRAMDirectoryPtr dir, const String& name, RAMFilePtr f) : RAMInputStream(f) + MockRAMInputStream::MockRAMInputStream(const MockRAMDirectoryPtr& dir, const String& name, const RAMFilePtr& f) : RAMInputStream(f) { this->isClone = false; this->name = name; @@ -48,7 +48,7 @@ namespace Lucene } } - LuceneObjectPtr MockRAMInputStream::clone(LuceneObjectPtr other) + LuceneObjectPtr MockRAMInputStream::clone(const LuceneObjectPtr& other) { LuceneObjectPtr clone = RAMInputStream::clone(other ? other : newLucene()); MockRAMInputStreamPtr cloneInputStream(boost::dynamic_pointer_cast(clone)); diff --git a/src/test/store/MockRAMOutputStream.cpp b/src/test/store/MockRAMOutputStream.cpp index cc2784ea..46501db9 100644 --- a/src/test/store/MockRAMOutputStream.cpp +++ b/src/test/store/MockRAMOutputStream.cpp @@ -10,7 +10,7 @@ namespace Lucene { - MockRAMOutputStream::MockRAMOutputStream(MockRAMDirectoryPtr dir, RAMFilePtr f, const String& name) : RAMOutputStream(f) + MockRAMOutputStream::MockRAMOutputStream(const MockRAMDirectoryPtr& dir, const RAMFilePtr& f, const String& name) : RAMOutputStream(f) { this->first = true; this->singleByte = ByteArray::newInstance(1); diff --git a/src/test/store/RAMDirectoryTest.cpp b/src/test/store/RAMDirectoryTest.cpp index 8d52bdb2..f43e3a37 100644 --- a/src/test/store/RAMDirectoryTest.cpp +++ b/src/test/store/RAMDirectoryTest.cpp @@ -63,7 +63,7 @@ class RAMDirectoryTest : public LuceneTestFixture class TestRAMDirectoryThread : public LuceneThread { public: - TestRAMDirectoryThread(IndexWriterPtr writer, int32_t num) + TestRAMDirectoryThread(const IndexWriterPtr& writer, int32_t num) { this->writer = writer; this->num = num; diff --git a/src/test/util/BitVectorTest.cpp b/src/test/util/BitVectorTest.cpp index 9a7fd688..0355ec84 100644 --- a/src/test/util/BitVectorTest.cpp +++ b/src/test/util/BitVectorTest.cpp @@ -15,7 +15,7 @@ typedef LuceneTestFixture BitVectorTest; static const int32_t subsetPattern[] = {1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1}; -static bool compareBitVectors(BitVectorPtr bv, BitVectorPtr compare) +static bool compareBitVectors(const BitVectorPtr& bv, const BitVectorPtr& compare) { for (int32_t i = 0; i < bv->size(); ++i) { diff --git a/src/test/util/NumericUtilsTest.cpp b/src/test/util/NumericUtilsTest.cpp index dbc7cee2..5d7cb9c9 100644 --- a/src/test/util/NumericUtilsTest.cpp +++ b/src/test/util/NumericUtilsTest.cpp @@ -378,7 +378,7 @@ TEST_F(NumericUtilsTest, testLongExtremeValues) ); } -static int64_t randomLong(RandomPtr random) +static int64_t randomLong(const RandomPtr& random) { int64_t val; switch (random->nextInt(4)) @@ -410,7 +410,7 @@ static int64_t randomLong(RandomPtr random) return val; } -static void executeOneRandomSplit(RandomPtr random) +static void executeOneRandomSplit(const RandomPtr& random) { int64_t lower = randomLong(random); int64_t len = (int64_t)random->nextInt(16384 * 1024); // not too large bitsets, else OOME! diff --git a/src/test/util/OpenBitSetTest.cpp b/src/test/util/OpenBitSetTest.cpp index 1680d926..4568254e 100644 --- a/src/test/util/OpenBitSetTest.cpp +++ b/src/test/util/OpenBitSetTest.cpp @@ -19,14 +19,14 @@ typedef LuceneTestFixture OpenBitSetTest; static RandomPtr randBitSet = newLucene(123); -static void doGet(BitSetPtr a, OpenBitSetPtr b) +static void doGet(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t max = a->size(); for (int32_t i = 0; i < max; ++i) EXPECT_EQ(a->get(i), b->get(i)); } -static void doNextSetBit(BitSetPtr a, OpenBitSetPtr b) +static void doNextSetBit(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t aa = -1; int32_t bb = -1; @@ -39,7 +39,7 @@ static void doNextSetBit(BitSetPtr a, OpenBitSetPtr b) while (aa >= 0); } -static void doIterate1(BitSetPtr a, OpenBitSetPtr b) +static void doIterate1(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t aa = -1; int32_t bb = -1; @@ -53,7 +53,7 @@ static void doIterate1(BitSetPtr a, OpenBitSetPtr b) while (aa >= 0); } -static void doIterate2(BitSetPtr a, OpenBitSetPtr b) +static void doIterate2(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t aa = -1; int32_t bb = -1; @@ -67,7 +67,7 @@ static void doIterate2(BitSetPtr a, OpenBitSetPtr b) while (aa >= 0); } -static void doIterate(BitSetPtr a, OpenBitSetPtr b, int32_t mode) +static void doIterate(const BitSetPtr& a, const OpenBitSetPtr& b, int32_t mode) { if (mode == 1) doIterate1(a, b); diff --git a/src/test/util/SortedVIntListTest.cpp b/src/test/util/SortedVIntListTest.cpp index aa582f53..b8ded48b 100644 --- a/src/test/util/SortedVIntListTest.cpp +++ b/src/test/util/SortedVIntListTest.cpp @@ -46,7 +46,7 @@ static int32_t vIntListByteSize(Collection ints) return byteSize; } -static void tstIterator(SortedVIntListPtr vintList, Collection ints) +static void tstIterator(const SortedVIntListPtr& vintList, Collection ints) { for (int32_t i = 0; i < ints.size(); ++i) { @@ -62,7 +62,7 @@ static void tstIterator(SortedVIntListPtr vintList, Collection ints) EXPECT_EQ(m->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); } -static void tstVIntList(SortedVIntListPtr vintList, Collection ints, int32_t expectedByteSize) +static void tstVIntList(const SortedVIntListPtr& vintList, Collection ints, int32_t expectedByteSize) { EXPECT_EQ(ints.size(), vintList->size()); EXPECT_EQ(expectedByteSize, vintList->getByteSize()); diff --git a/src/test/util/TestUtils.cpp b/src/test/util/TestUtils.cpp index 7f7438f8..0261b947 100644 --- a/src/test/util/TestUtils.cpp +++ b/src/test/util/TestUtils.cpp @@ -50,12 +50,12 @@ namespace Lucene return FileUtils::joinPath(getTempDir(), desc + L"." + StringUtils::toString(randomTest->nextInt())); } - void syncConcurrentMerges(IndexWriterPtr writer) + void syncConcurrentMerges(const IndexWriterPtr& writer) { syncConcurrentMerges(writer->getMergeScheduler()); } - void syncConcurrentMerges(MergeSchedulerPtr ms) + void syncConcurrentMerges(const MergeSchedulerPtr& ms) { if (MiscUtils::typeOf(ms)) boost::dynamic_pointer_cast(ms)->sync(); @@ -170,7 +170,7 @@ namespace Lucene return english; } - bool checkIndex(DirectoryPtr dir) + bool checkIndex(const DirectoryPtr& dir) { CheckIndexPtr checker = newLucene(dir); IndexStatusPtr indexStatus = checker->checkIndex(); From 034a03f11fcbcbf534f8fa1daaf1a530a94df8eb Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 20 Feb 2014 01:38:56 +0100 Subject: [PATCH 053/157] Pass boost::any arguments as const references. --- include/FieldCacheImpl.h | 6 +++--- include/VariantUtils.h | 4 ++-- src/core/search/FieldCacheImpl.cpp | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/FieldCacheImpl.h b/include/FieldCacheImpl.h index b58f83b1..cfbeb7bf 100644 --- a/include/FieldCacheImpl.h +++ b/include/FieldCacheImpl.h @@ -53,7 +53,7 @@ namespace Lucene { public: /// Creates one of these objects for a custom comparator/parser. - Entry(const String& field, boost::any custom); + Entry(const String& field, const boost::any& custom); virtual ~Entry(); LUCENE_CLASS(Entry); @@ -91,7 +91,7 @@ namespace Lucene virtual void purge(const IndexReaderPtr& r); virtual boost::any get(const IndexReaderPtr& reader, const EntryPtr& key); - virtual void printNewInsanity(const InfoStreamPtr& infoStream, boost::any value); + virtual void printNewInsanity(const InfoStreamPtr& infoStream, const boost::any& value); }; class ByteCache : public Cache @@ -169,7 +169,7 @@ namespace Lucene class FieldCacheEntryImpl : public FieldCacheEntry { public: - FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value); + FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, const boost::any& custom, const boost::any& value); virtual ~FieldCacheEntryImpl(); LUCENE_CLASS(FieldCacheEntryImpl); diff --git a/include/VariantUtils.h b/include/VariantUtils.h index 4d610a5a..bc5398b3 100644 --- a/include/VariantUtils.h +++ b/include/VariantUtils.h @@ -17,7 +17,7 @@ namespace Lucene { public: template - static TYPE get(boost::any var) + static TYPE get(const boost::any& var) { return var.type() == typeid(TYPE) ? boost::any_cast(var) : TYPE(); } @@ -39,7 +39,7 @@ namespace Lucene return VariantNull(); } - static bool isNull(boost::any var) + static bool isNull(const boost::any& var) { return var.empty(); } diff --git a/src/core/search/FieldCacheImpl.cpp b/src/core/search/FieldCacheImpl.cpp index 19d06554..74477b0c 100644 --- a/src/core/search/FieldCacheImpl.cpp +++ b/src/core/search/FieldCacheImpl.cpp @@ -127,7 +127,7 @@ namespace Lucene return infoStream; } - Entry::Entry(const String& field, boost::any custom) + Entry::Entry(const String& field, const boost::any& custom) { this->field = field; this->custom = custom; @@ -222,7 +222,7 @@ namespace Lucene return value; } - void Cache::printNewInsanity(const InfoStreamPtr& infoStream, boost::any value) + void Cache::printNewInsanity(const InfoStreamPtr& infoStream, const boost::any& value) { Collection insanities(FieldCacheSanityChecker::checkSanity(FieldCachePtr(_wrapper))); for (Collection::iterator insanity = insanities.begin(); insanity != insanities.end(); ++insanity) @@ -577,7 +577,7 @@ namespace Lucene return newLucene(retArray, mterms); } - FieldCacheEntryImpl::FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, boost::any custom, boost::any value) + FieldCacheEntryImpl::FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, const boost::any& custom, const boost::any& value) { this->readerKey = readerKey; this->fieldName = fieldName; From 6be7218d138c49359fcc3c9ba81bc1b0a11ac03f Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 20 Feb 2014 02:10:59 +0100 Subject: [PATCH 054/157] Improved pre-compiled header support. --- CMakeLists.txt | 12 +- README.rst | 18 +- cmake/PCHSupport.cmake | 263 --- cmake/Toolchain-llvm.cmake | 1 - cmake/cotire.cmake | 3351 ++++++++++++++++++++++++++++++++++++ src/contrib/CMakeLists.txt | 4 +- src/core/CMakeLists.txt | 9 +- src/test/CMakeLists.txt | 2 + 8 files changed, 3367 insertions(+), 293 deletions(-) delete mode 100644 cmake/PCHSupport.cmake create mode 100644 cmake/cotire.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 115bdc2f..3a15d7cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ project(lucene++) -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.6) set(lucene++_VERSION_MAJOR 3) set(lucene++_VERSION_MINOR 0) @@ -15,6 +15,11 @@ set(lucene++_VERSION # include specific modules set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +#################################### +# pre-compiled headers support +#################################### +include(cotire) + # if setup using the Toolchain-llvm.cmake file, then use llvm... if(ENABLE_LLVM) include(Toolchain-llvm) @@ -96,11 +101,6 @@ if(CYGWIN) add_definitions(-D__LARGE64_FILES) endif() -#################################### -# pre-compiled headers -#################################### -include(PCHSupport) - ################################# # generate Config.h ################################# diff --git a/README.rst b/README.rst index f0e18967..be73647e 100644 --- a/README.rst +++ b/README.rst @@ -10,8 +10,8 @@ Components ---------------- - liblucene++ library -- liblucene_contrib library -- lucene_tester (unit tester) +- liblucene++-contrib library +- lucene++-tester (unit tester) - deletefiles (demo) - indexfiles (demo) - searchfiles (demo) @@ -44,10 +44,6 @@ To build the library the following commands should be issued:: $ make $ make install -To build the demo programs, execute the following after having first built the library:: - - $ make indexfiles searchfiles deletefiles - Build Instructions for Windows systems -------------------------------------- @@ -68,14 +64,6 @@ You'll need Boost installed. - boost::iostreams -Building Performance --------------------- - -Use of ccache will speed up build times a lot. I found it easiest to add the ``/usr/lib/ccache`` directory to the beginning of your paths. This works for most common compilers:: - - PATH=/usr/lib/ccache:$PATH - - To run unit test suite ---------------------- @@ -90,6 +78,6 @@ Acknowledgements ---------------- - Ben van Klinken and contributors to the CLucene project for inspiring this project. - - md5 Copyright (C) 1999, 2000, 2002 Aladdin Enterprises - `Unicode character properties (guniprop) `_ Copyright (C) 1999 Tom Tromey, Copyright (C) 2000 Red Hat, Inc. +- `Cotire (compile time reducer) `_ by Sascha Kratky. diff --git a/cmake/PCHSupport.cmake b/cmake/PCHSupport.cmake deleted file mode 100644 index af3b3dac..00000000 --- a/cmake/PCHSupport.cmake +++ /dev/null @@ -1,263 +0,0 @@ -# - Try to find precompiled headers support for GCC 3.4 and 4.x -# Once done this will define: -# -# Variable: -# PCHSupport_FOUND -# PCHSupport_ENABLED -# -# Macro: -# ADD_PRECOMPILED_HEADER _targetName _input _dowarn -# ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use _dowarn -# -# Since this macro overides COMPILER_FLAGS on a target, you must use the following -# variables instead. -# set PCH_ADDITIONAL_COMPILER_FLAGS to add extra COMPILER_FLAGS to targets -# set PCH_ADDITIONAL_COMPILER_FLAGS_${targetName} to add extra COMPILER_FLAGS to a specific target -# - -IF(CMAKE_COMPILER_IS_GNUCXX) - - EXEC_PROGRAM( - ${CMAKE_CXX_COMPILER} - ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion - OUTPUT_VARIABLE gcc_compiler_version) - #MESSAGE("GCC Version: ${gcc_compiler_version}") - IF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") - SET(PCHSupport_FOUND TRUE) - ELSE(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") - IF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") - SET(PCHSupport_FOUND TRUE) - ENDIF(gcc_compiler_version MATCHES "3\\.4\\.[0-9]") - ENDIF(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]") - - SET(_PCH_include_prefix "-I") - -ELSE(CMAKE_COMPILER_IS_GNUCXX) - IF( (WIN32 OR WIN64) ) - #SET(PCHSupport_FOUND TRUE) # for experimental msvc support - #SET(_PCH_include_prefix "/I") - SET(PCHSupport_FOUND FALSE) - ELSE( (WIN32 OR WIN64) ) - SET(PCHSupport_FOUND FALSE) - ENDIF( (WIN32 OR WIN64) ) -ENDIF(CMAKE_COMPILER_IS_GNUCXX) - -IF ( DEFINED PCHSupport_ENABLED AND NOT PCHSupport_ENABLED ) - SET(PCHSupport_FOUND FALSE) -ENDIF ( DEFINED PCHSupport_ENABLED AND NOT PCHSupport_ENABLED) - -MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags) - - - STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name) - SET(${_out_compile_flags} ${${_flags_var_name}} ) - - IF(CMAKE_COMPILER_IS_GNUCXX) - - GET_TARGET_PROPERTY(_targetType ${_PCH_current_target} TYPE) - IF(${_targetType} STREQUAL SHARED_LIBRARY) - LIST(APPEND ${_out_compile_flags} "${${_out_compile_flags}} -fPIC") - ENDIF(${_targetType} STREQUAL SHARED_LIBRARY) - - ELSE(CMAKE_COMPILER_IS_GNUCXX) - ## TODO ... ? or does it work out of the box - ENDIF(CMAKE_COMPILER_IS_GNUCXX) - - GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES ) - FOREACH(item ${DIRINC}) - LIST(APPEND ${_out_compile_flags} "${_PCH_include_prefix}${item}") - ENDFOREACH(item) - - GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS) - #MESSAGE("_directory_flags ${_directory_flags}" ) - LIST(APPEND ${_out_compile_flags} ${_directory_flags}) - LIST(APPEND ${_out_compile_flags} ${CMAKE_CXX_FLAGS} ) - - SEPARATE_ARGUMENTS(${_out_compile_flags}) - -ENDMACRO(_PCH_GET_COMPILE_FLAGS) - - -MACRO(_PCH_WRITE_PCHDEP_CXX _targetName _include_file _dephelp) - - SET(${_dephelp} ${CMAKE_CURRENT_BINARY_DIR}/${_targetName}_pch_dephelp.cxx) - FILE(WRITE ${${_dephelp}} -"#include \"${_include_file}\" -int testfunction() -{ - return 0; -} -" - ) - -ENDMACRO(_PCH_WRITE_PCHDEP_CXX ) - -MACRO(_PCH_GET_COMPILE_COMMAND out_command _input _output) - - FILE(TO_NATIVE_PATH ${_input} _native_input) - FILE(TO_NATIVE_PATH ${_output} _native_output) - - - IF(CMAKE_COMPILER_IS_GNUCXX) - IF(CMAKE_CXX_COMPILER_ARG1) - # remove leading space in compiler argument - STRING(REGEX REPLACE "^ +" "" pchsupport_compiler_cxx_arg1 ${CMAKE_CXX_COMPILER_ARG1}) - - SET(${out_command} - ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input} - ) - ELSE(CMAKE_CXX_COMPILER_ARG1) - SET(${out_command} - ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input} - ) - ENDIF(CMAKE_CXX_COMPILER_ARG1) - ELSE(CMAKE_COMPILER_IS_GNUCXX) - - SET(_dummy_str "#include <${_input}>") - FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pch_dummy.cpp ${_dummy_str}) - - SET(${out_command} - ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} /c /Fp${_native_output} /Yc${_native_input} pch_dummy.cpp - ) - #/out:${_output} - - ENDIF(CMAKE_COMPILER_IS_GNUCXX) - -ENDMACRO(_PCH_GET_COMPILE_COMMAND ) - - - - -MACRO(_PCH_GET_TARGET_COMPILE_FLAGS _targetName _cflags _header_name _pch_path _dowarn ) - - FILE(TO_NATIVE_PATH ${_pch_path} _native_pch_path) - #message(${_native_pch_path}) - - IF(CMAKE_COMPILER_IS_GNUCXX) - # for use with distcc and gcc >4.0.1 if preprocessed files are accessible - # on all remote machines set - # PCH_ADDITIONAL_COMPILER_FLAGS to -fpch-preprocess - # if you want warnings for invalid header files (which is very inconvenient - # if you have different versions of the headers for different build types - # you may set _pch_dowarn - IF (_dowarn) - SET(${_cflags} "${PCH_ADDITIONAL_COMPILER_FLAGS} ${PCH_ADDITIONAL_COMPILER_FLAGS_${_targetName}} -include ${CMAKE_CURRENT_BINARY_DIR}/${_header_name} -Winvalid-pch " ) - ELSE (_dowarn) - SET(${_cflags} "${PCH_ADDITIONAL_COMPILER_FLAGS} ${PCH_ADDITIONAL_COMPILER_FLAGS_${_targetName}} -include ${CMAKE_CURRENT_BINARY_DIR}/${_header_name} " ) - ENDIF (_dowarn) - ELSE(CMAKE_COMPILER_IS_GNUCXX) - - set(${_cflags} "/Fp${_native_pch_path} /Yu${_header_name}" ) - - ENDIF(CMAKE_COMPILER_IS_GNUCXX) - -ENDMACRO(_PCH_GET_TARGET_COMPILE_FLAGS ) - -MACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input _output) - GET_FILENAME_COMPONENT(_name ${_input} NAME) - GET_FILENAME_COMPONENT(_path ${_input} PATH) - SET(_output "${CMAKE_CURRENT_BINARY_DIR}/${_name}.gch/${_targetName}_${CMAKE_BUILD_TYPE}.h++") -ENDMACRO(GET_PRECOMPILED_HEADER_OUTPUT _targetName _input) - - -MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use ) - if ( PCHSupport_FOUND ) - # to do: test whether compiler flags match between target _targetName - # and _pch_output_to_use - GET_FILENAME_COMPONENT(_name ${_input} NAME) - - IF( "${ARGN}" STREQUAL "0") - SET(_dowarn 0) - ELSE( "${ARGN}" STREQUAL "0") - SET(_dowarn 1) - ENDIF("${ARGN}" STREQUAL "0") - - - _PCH_GET_TARGET_COMPILE_FLAGS(${_targetName} _target_cflags ${_name} ${_pch_output_to_use} ${_dowarn}) - #MESSAGE("Add flags ${_target_cflags} to ${_targetName} " ) - - SET_TARGET_PROPERTIES(${_targetName} - PROPERTIES - COMPILE_FLAGS ${_target_cflags} - ) - - ADD_CUSTOM_TARGET(pch_Generate_${_targetName} - DEPENDS ${_pch_output_to_use} - ) - - ADD_DEPENDENCIES(${_targetName} pch_Generate_${_targetName} ) - else ( PCHSupport_FOUND ) - SET_TARGET_PROPERTIES(${_targetName} - PROPERTIES - COMPILE_FLAGS ${PCH_ADDITIONAL_COMPILER_FLAGS} ${PCH_ADDITIONAL_COMPILER_FLAGS_${_targetName}} - ) - endif ( PCHSupport_FOUND ) -ENDMACRO(ADD_PRECOMPILED_HEADER_TO_TARGET) - - -MACRO(ADD_PRECOMPILED_HEADER _targetName _input) - if ( PCHSupport_FOUND ) - SET(_PCH_current_target ${_targetName}) - - IF(NOT CMAKE_BUILD_TYPE) - MESSAGE(FATAL_ERROR - "This is the ADD_PRECOMPILED_HEADER macro. " - "You must set CMAKE_BUILD_TYPE!" - ) - ENDIF(NOT CMAKE_BUILD_TYPE) - - IF( "${ARGN}" STREQUAL "0") - SET(_dowarn 0) - ELSE( "${ARGN}" STREQUAL "0") - SET(_dowarn 1) - ENDIF("${ARGN}" STREQUAL "0") - - - GET_FILENAME_COMPONENT(_name ${_input} NAME) - GET_FILENAME_COMPONENT(_path ${_input} PATH) - GET_PRECOMPILED_HEADER_OUTPUT( ${_targetName} ${_input} _output) - GET_FILENAME_COMPONENT(_outdir ${_output} PATH ) - - GET_TARGET_PROPERTY(_targetType ${_PCH_current_target} TYPE) - _PCH_WRITE_PCHDEP_CXX(${_targetName} ${_input} _pch_dephelp_cxx) - - #MESSAGE(${_pch_dephelp_cxx}) - IF(${_targetType} STREQUAL SHARED_LIBRARY) - ADD_LIBRARY(${_targetName}_pch_dephelp SHARED ${_pch_dephelp_cxx} ) - ELSE(${_targetType} STREQUAL SHARED_LIBRARY) - ADD_LIBRARY(${_targetName}_pch_dephelp STATIC ${_pch_dephelp_cxx}) - ENDIF(${_targetType} STREQUAL SHARED_LIBRARY) - - FILE(MAKE_DIRECTORY ${_outdir}) - - - _PCH_GET_COMPILE_FLAGS(_compile_FLAGS) - - SET(_compile_FLAGS ${_compile_FLAGS} ${PCH_ADDITIONAL_COMPILER_FLAGS} ${PCH_ADDITIONAL_COMPILER_FLAGS_${_targetName}}) - - #MESSAGE("_compile_FLAGS: ${_compile_FLAGS}") - #message("COMMAND ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input}") - SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${_name} PROPERTIES GENERATED 1) - ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name} - COMMAND ${CMAKE_COMMAND} -E copy ${_input} ${CMAKE_CURRENT_BINARY_DIR}/${_name} # ensure same directory! Required by gcc - DEPENDS ${_input} - ) - - #message("_command ${_input} ${_output}") - _PCH_GET_COMPILE_COMMAND(_command ${CMAKE_CURRENT_BINARY_DIR}/${_name} ${_output} ) - - #message(${_input} ) - #message("_output ${_output}") - - ADD_CUSTOM_COMMAND( - OUTPUT ${_output} - COMMAND ${_command} - DEPENDS ${_input} ${CMAKE_CURRENT_BINARY_DIR}/${_name} ${_targetName}_pch_dephelp - ) - - - ADD_PRECOMPILED_HEADER_TO_TARGET(${_targetName} ${_input} ${_output} ${_dowarn}) - endif ( PCHSupport_FOUND ) -ENDMACRO(ADD_PRECOMPILED_HEADER) - diff --git a/cmake/Toolchain-llvm.cmake b/cmake/Toolchain-llvm.cmake index 6d2c66f1..d98db8a1 100644 --- a/cmake/Toolchain-llvm.cmake +++ b/cmake/Toolchain-llvm.cmake @@ -7,7 +7,6 @@ SET(CMAKE_CXX_COMPILER clang++) SET(ENABLE_LLVM CACHE BOOL TRUE) SET(ENABLE_LLVM_BC CACHE BOOL FALSE) -SET(PCHSupport_ENABLED FALSE) IF ( ENABLE_LLVM_BC ) #TODO: make this work... diff --git a/cmake/cotire.cmake b/cmake/cotire.cmake new file mode 100644 index 00000000..1661cbb3 --- /dev/null +++ b/cmake/cotire.cmake @@ -0,0 +1,3351 @@ +# - cotire (compile time reducer) +# +# See the cotire manual for usage hints. +# +#============================================================================= +# Copyright 2012-2014 Sascha Kratky +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +#============================================================================= + +if(__COTIRE_INCLUDED) + return() +endif() +set(__COTIRE_INCLUDED TRUE) + +# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode +# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(PUSH) +endif() +# we need the CMake variables CMAKE_SCRIPT_MODE_FILE and CMAKE_ARGV available since 2.8.5 +# we need APPEND_STRING option for set_property available since 2.8.6 +cmake_minimum_required(VERSION 2.8.6) +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(POP) +endif() + +set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") +set (COTIRE_CMAKE_MODULE_VERSION "1.5.2") + +include(CMakeParseArguments) +include(ProcessorCount) + +function (cotire_determine_compiler_version _language _versionPrefix) + if (NOT ${_versionPrefix}_VERSION) + # use CMake's predefined compiler version variable (available since CMake 2.8.8) + if (DEFINED CMAKE_${_language}_COMPILER_VERSION) + set (${_versionPrefix}_VERSION "${CMAKE_${_language}_COMPILER_VERSION}") + elseif (WIN32) + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) + execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} + ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10) + string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}") + else() + # assume GCC like command line interface + string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) + execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion" + OUTPUT_VARIABLE ${_versionPrefix}_VERSION + RESULT_VARIABLE _result + OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10) + if (_result) + set (${_versionPrefix}_VERSION "") + endif() + endif() + if (${_versionPrefix}_VERSION) + set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" CACHE INTERNAL "${_language} compiler version") + endif() + set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" PARENT_SCOPE) + if (COTIRE_DEBUG) + message (STATUS "${CMAKE_${_language}_COMPILER} version ${${_versionPrefix}_VERSION}") + endif() + endif() +endfunction() + +function (cotire_get_source_file_extension _sourceFile _extVar) + # get_filename_component returns extension from first occurrence of . in file name + # this function computes the extension from last occurrence of . in file name + string (FIND "${_sourceFile}" "." _index REVERSE) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt) + else() + set (_sourceExt "") + endif() + set (${_extVar} "${_sourceExt}" PARENT_SCOPE) +endfunction() + +macro (cotire_check_is_path_relative_to _path _isRelativeVar) + set (${_isRelativeVar} FALSE) + if (IS_ABSOLUTE "${_path}") + foreach (_dir ${ARGN}) + file (RELATIVE_PATH _relPath "${_dir}" "${_path}") + if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")) + set (${_isRelativeVar} TRUE) + break() + endif() + endforeach() + endif() +endmacro() + +function (cotire_filter_language_source_files _language _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) + set (_sourceFiles "") + set (_excludedSourceFiles "") + set (_cotiredSourceFiles "") + if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") + else() + set (_languageExtensions "") + endif() + if (CMAKE_${_language}_IGNORE_EXTENSIONS) + set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}") + else() + set (_ignoreExtensions "") + endif() + if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS) + set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}") + else() + set (_excludeExtensions "") + endif() + if (COTIRE_DEBUG) + message (STATUS "${_language} source file extensions: ${_languageExtensions}") + message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") + message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") + endif() + foreach (_sourceFile ${ARGN}) + get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) + get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) + get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) + get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) + set (_sourceIsFiltered FALSE) + if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) + cotire_get_source_file_extension("${_sourceFile}" _sourceExt) + if (_sourceExt) + list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex) + if (_ignoreIndex LESS 0) + list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex) + if (_excludeIndex GREATER -1) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) + if (_sourceIndex GREATER -1) + set (_sourceIsFiltered TRUE) + elseif ("${_sourceLanguage}" STREQUAL "${_language}") + # add to excluded sources, if file is not ignored and has correct language without having the correct extension + list (APPEND _excludedSourceFiles "${_sourceFile}") + endif() + endif() + endif() + endif() + endif() + if (COTIRE_DEBUG) + message (STATUS "${_sourceFile} filtered=${_sourceIsFiltered} language=${_sourceLanguage} header=${_sourceIsHeaderOnly}") + endif() + if (_sourceIsFiltered) + get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) + get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) + get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) + if (COTIRE_DEBUG) + message (STATUS "${_sourceFile} excluded=${_sourceIsExcluded} cotired=${_sourceIsCotired} compileFlags=${_sourceCompileFlags}") + endif() + if (_sourceIsCotired) + list (APPEND _cotiredSourceFiles "${_sourceFile}") + elseif (_sourceIsExcluded OR _sourceCompileFlags) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _sourceFiles "${_sourceFile}") + endif() + endif() + endforeach() + if (COTIRE_DEBUG) + message (STATUS "All: ${ARGN}") + message (STATUS "${_language}: ${_sourceFiles}") + message (STATUS "Excluded: ${_excludedSourceFiles}") + message (STATUS "Cotired: ${_cotiredSourceFiles}") + endif() + set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) + set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) + set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (NOT _propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_file_property_values _valuesVar _property) + set (_values "") + foreach (_sourceFile ${ARGN}) + get_source_file_property(_propertyValue "${_sourceFile}" ${_property}) + if (_propertyValue) + list (APPEND _values "${_propertyValue}") + endif() + endforeach() + set (${_valuesVar} ${_values} PARENT_SCOPE) +endfunction() + +function (cotire_resolve_config_properites _configurations _propertiesVar) + set (_properties "") + foreach (_property ${ARGN}) + if ("${_property}" MATCHES "") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + string (REPLACE "" "${_upperConfig}" _configProperty "${_property}") + list (APPEND _properties ${_configProperty}) + endforeach() + else() + list (APPEND _properties ${_property}) + endif() + endforeach() + set (${_propertiesVar} ${_properties} PARENT_SCOPE) +endfunction() + +function (cotire_copy_set_properites _configurations _type _source _target) + cotire_resolve_config_properites("${_configurations}" _properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property}) + set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}") + endif() + endforeach() +endfunction() + +function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + set (_flagPrefix "[/-]") + else() + set (_flagPrefix "--?") + endif() + set (_optionFlag "") + set (_matchedOptions "") + set (_unmatchedOptions "") + foreach (_compileFlag ${ARGN}) + if (_compileFlag) + if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}") + # option with separate argument + list (APPEND _matchedOptions "${_compileFlag}") + set (_optionFlag "") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$") + # remember option + set (_optionFlag "${CMAKE_MATCH_2}") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$") + # option with joined argument + list (APPEND _matchedOptions "${CMAKE_MATCH_3}") + set (_optionFlag "") + else() + # flush remembered option + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + set (_optionFlag "") + endif() + # add to unfiltered options + list (APPEND _unmatchedOptions "${_compileFlag}") + endif() + endif() + endforeach() + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + endif() + if (COTIRE_DEBUG) + message (STATUS "Filter ${_flagFilter}") + if (_matchedOptions) + message (STATUS "Matched ${_matchedOptions}") + endif() + if (_unmatchedOptions) + message (STATUS "Unmatched ${_unmatchedOptions}") + endif() + endif() + set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) + set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_flags _config _language _directory _target _flagsVar) + string (TOUPPER "${_config}" _upperConfig) + # collect options from CMake language variables + set (_compileFlags "") + if (CMAKE_${_language}_FLAGS) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}") + endif() + if (CMAKE_${_language}_FLAGS_${_upperConfig}) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") + endif() + if (_target) + # add option from CMake target type variable + get_target_property(_targetType ${_target} TYPE) + if (POLICY CMP0018) + # handle POSITION_INDEPENDENT_CODE property introduced with CMake 2.8.9 if policy CMP0018 is turned on + cmake_policy(GET CMP0018 _PIC_Policy) + else() + # default to old behavior + set (_PIC_Policy "OLD") + endif() + if (COTIRE_DEBUG) + message(STATUS "CMP0018=${_PIC_Policy}") + endif() + if (_PIC_Policy STREQUAL "NEW") + # NEW behavior: honor the POSITION_INDEPENDENT_CODE target property + get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) + if (_targetPIC) + if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") + elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") + endif() + endif() + else() + # OLD behavior or policy not set: use the value of CMAKE_SHARED_LIBRARY__FLAGS + if (_targetType STREQUAL "MODULE_LIBRARY") + # flags variable for module library uses different name SHARED_MODULE + # (e.g., CMAKE_SHARED_MODULE_C_FLAGS) + set (_targetType SHARED_MODULE) + endif() + if (CMAKE_${_targetType}_${_language}_FLAGS) + set (_compileFlags "${_compileFlags} ${CMAKE_${_targetType}_${_language}_FLAGS}") + endif() + endif() + endif() + if (_directory) + # add_definitions may have been used to add flags to the compiler command + get_directory_property(_dirDefinitions DIRECTORY "${_directory}" DEFINITIONS) + if (_dirDefinitions) + set (_compileFlags "${_compileFlags} ${_dirDefinitions}") + endif() + endif() + if (_target) + # add target compile options + get_target_property(_targetflags ${_target} COMPILE_FLAGS) + if (_targetflags) + set (_compileFlags "${_compileFlags} ${_targetflags}") + endif() + get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) + if (_targetOptions) + set (_compileFlags "${_compileFlags} ${_targetOptions}") + endif() + endif() + if (UNIX) + separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") + elseif(WIN32) + separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}") + else() + separate_arguments(_compileFlags) + endif() + # platform specific flags + if (APPLE) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) + if (NOT _architectures) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES) + endif() + foreach (_arch ${_architectures}) + list (APPEND _compileFlags "-arch" "${_arch}") + endforeach() + if (CMAKE_OSX_SYSROOT) + if (CMAKE_${_language}_SYSROOT_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") + else() + list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}") + endif() + endif() + if (CMAKE_OSX_DEPLOYMENT_TARGET) + if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") + else() + list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endif() + endif() + endif() + if (COTIRE_DEBUG AND _compileFlags) + message (STATUS "Target ${_target} compile flags ${_compileFlags}") + endif() + set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar) + set (_includeDirs "") + # default include dirs + if (CMAKE_INCLUDE_CURRENT_DIR) + list (APPEND _includeDirs "${_targetBinaryDir}") + list (APPEND _includeDirs "${_targetSourceDir}") + endif() + # parse additional include directories from target compile flags + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "I" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _includeDirs ${_dirs}) + endif() + # target include directories + get_directory_property(_dirs DIRECTORY "${_targetSourceDir}" INCLUDE_DIRECTORIES) + if (_target) + get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + list (REMOVE_DUPLICATES _dirs) + endif() + endif() + list (LENGTH _includeDirs _projectInsertIndex) + foreach (_dir ${_dirs}) + if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE) + cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") + if (_isRelative) + list (LENGTH _includeDirs _len) + if (_len EQUAL _projectInsertIndex) + list (APPEND _includeDirs "${_dir}") + else() + list (INSERT _includeDirs _projectInsertIndex "${_dir}") + endif() + math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1") + else() + list (APPEND _includeDirs "${_dir}") + endif() + else() + list (APPEND _includeDirs "${_dir}") + endif() + endforeach() + list (REMOVE_DUPLICATES _includeDirs) + if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) + list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) + endif() + if (COTIRE_DEBUG AND _includeDirs) + message (STATUS "Target ${_target} include dirs ${_includeDirs}") + endif() + set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) +endfunction() + +macro (cotire_make_C_identifier _identifierVar _str) + if (CMAKE_VERSION VERSION_LESS "2.8.12") + # mimic CMake SystemTools::MakeCindentifier behavior + if ("${_str}" MATCHES "^[0-9].+$") + set (_str "_${str}") + endif() + string (REGEX REPLACE "[^a-zA-Z0-9]" "_" ${_identifierVar} "${_str}") + else() + string (MAKE_C_IDENTIFIER "${_identifierVar}" "${_str}") + endif() +endmacro() + +function (cotire_get_target_export_symbol _target _exportSymbolVar) + set (_exportSymbol "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_enableExports ${_target} ENABLE_EXPORTS) + if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR + (_targetType STREQUAL "EXECUTABLE" AND _enableExports)) + get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL) + if (NOT _exportSymbol) + set (_exportSymbol "${_target}_EXPORTS") + endif() + cotire_make_C_identifier(_exportSymbol "${_exportSymbol}") + endif() + set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_definitions _config _language _directory _target _definitionsVar) + string (TOUPPER "${_config}" _upperConfig) + set (_configDefinitions "") + # CMAKE_INTDIR for multi-configuration build systems + if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"") + endif() + # target export define symbol + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + list (APPEND _configDefinitions "${_defineSymbol}") + endif() + # directory compile definitions + get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # target compile definitions + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # parse additional compile definitions from target compile flags + # and don't look at directory compile definitions, which we already handled + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + list (REMOVE_DUPLICATES _configDefinitions) + if (COTIRE_DEBUG AND _configDefinitions) + message (STATUS "Target ${_target} compile definitions ${_configDefinitions}") + endif() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compiler_flags _config _language _directory _target _compilerFlagsVar) + # parse target compile flags omitting compile definitions and include directives + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_directory}" "${_target}" _targetFlags) + set (_compilerFlags "") + cotire_filter_compile_flags("${_language}" "[ID]" _ignore _compilerFlags ${_targetFlags}) + if (COTIRE_DEBUG AND _compilerFlags) + message (STATUS "Target ${_target} compiler flags ${_compilerFlags}") + endif() + set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) +endfunction() + +function (cotire_add_sys_root_paths _pathsVar) + if (APPLE) + if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT) + foreach (_path IN LISTS ${_pathsVar}) + if (IS_ABSOLUTE "${_path}") + get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE) + if (EXISTS "${_path}") + list (APPEND ${_pathsVar} "${_path}") + endif() + endif() + endforeach() + endif() + endif() + set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) + if (COTIRE_DEBUG) + message (STATUS "${_pathsVar}=${${_pathsVar}}") + endif() +endfunction() + +function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) + set (_extraProperties ${ARGN}) + set (_result "") + if (_extraProperties) + list (FIND _extraProperties "${_sourceFile}" _index) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + list (LENGTH _extraProperties _len) + math (EXPR _len "${_len} - 1") + foreach (_index RANGE ${_index} ${_len}) + list (GET _extraProperties ${_index} _value) + if (_value MATCHES "${_pattern}") + list (APPEND _result "${_value}") + else() + break() + endif() + endforeach() + endif() + endif() + set (${_resultVar} ${_result} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar) + set (_compileDefinitions "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + string (TOUPPER "${_config}" _upperConfig) + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + if (COTIRE_DEBUG AND _compileDefinitions) + message (STATUS "Source ${_sourceFile} compile definitions ${_compileDefinitions}") + endif() + set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_compile_definitions _config _language _definitionsVar) + set (_configDefinitions "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions) + if (_sourceDefinitions) + list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-") + endif() + endforeach() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) + set (_sourceUndefs "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + get_source_file_property(_undefs "${_sourceFile}" ${_property}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + if (COTIRE_DEBUG AND _sourceUndefs) + message (STATUS "Source ${_sourceFile} ${_property} undefs ${_sourceUndefs}") + endif() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_undefs _property _sourceUndefsVar) + set (_sourceUndefs "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs) + if (_undefs) + list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-") + endif() + endforeach() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +macro (cotire_set_cmd_to_prologue _cmdVar) + set (${_cmdVar} "${CMAKE_COMMAND}") + if (COTIRE_DEBUG) + list (APPEND ${_cmdVar} "--warn-uninitialized") + endif() + list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$") + if (COTIRE_VERBOSE) + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") + elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)") + endif() +endmacro() + +function (cotire_init_compile_cmd _cmdVar _language _compilerExe _compilerArg1) + if (NOT _compilerExe) + set (_compilerExe "${CMAKE_${_language}_COMPILER}") + endif() + if (NOT _compilerArg1) + set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) + endif() + string (STRIP "${_compilerArg1}" _compilerArg1) + set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) +endfunction() + +macro (cotire_add_definitions_to_cmd _cmdVar _language) + foreach (_definition ${ARGN}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + list (APPEND ${_cmdVar} "/D${_definition}") + else() + list (APPEND ${_cmdVar} "-D${_definition}") + endif() + endforeach() +endmacro() + +macro (cotire_add_includes_to_cmd _cmdVar _language) + foreach (_include ${ARGN}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + file (TO_NATIVE_PATH "${_include}" _include) + list (APPEND ${_cmdVar} "/I${_include}") + else() + list (APPEND ${_cmdVar} "-I${_include}") + endif() + endforeach() +endmacro() + +macro (cotire_add_frameworks_to_cmd _cmdVar _language) + if (APPLE) + set (_frameWorkDirs "") + foreach (_include ${ARGN}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameWorkDir "${_include}" PATH) + list (APPEND _frameWorkDirs "${_frameWorkDir}") + endif() + endforeach() + if (_frameWorkDirs) + list (REMOVE_DUPLICATES _frameWorkDirs) + foreach (_frameWorkDir ${_frameWorkDirs}) + list (APPEND ${_cmdVar} "-F${_frameWorkDir}") + endforeach() + endif() + endif() +endmacro() + +macro (cotire_add_compile_flags_to_cmd _cmdVar) + foreach (_flag ${ARGN}) + list (APPEND ${_cmdVar} "${_flag}") + endforeach() +endmacro() + +function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + set (_triggerFile "") + foreach (_dependencyFile ${ARGN}) + if (EXISTS "${_dependencyFile}" AND "${_dependencyFile}" IS_NEWER_THAN "${_file}") + set (_triggerFile "${_dependencyFile}") + break() + endif() + endforeach() + get_filename_component(_fileName "${_file}" NAME) + if (EXISTS "${_file}") + if (_triggerFile) + if (COTIRE_VERBOSE) + message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") + endif() + else() + if (COTIRE_VERBOSE) + message (STATUS "${_fileName} is up-to-date.") + endif() + set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) + endif() + else() + if (COTIRE_VERBOSE) + message (STATUS "${_fileName} does not exist yet.") + endif() + endif() +endfunction() + +macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) + set (${_relPathVar} "") + foreach (_includeDir ${_includeDirs}) + if (IS_DIRECTORY "${_includeDir}") + file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}") + if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.") + string (LENGTH "${${_relPathVar}}" _closestLen) + string (LENGTH "${_relPath}" _relLen) + if (_closestLen EQUAL 0 OR _relLen LESS _closestLen) + set (${_relPathVar} "${_relPath}") + endif() + endif() + elseif ("${_includeDir}" STREQUAL "${_headerFile}") + # if path matches exactly, return short non-empty string + set (${_relPathVar} "1") + break() + endif() + endforeach() +endmacro() + +macro (cotire_check_header_file_location _headerFile _insideIncudeDirs _outsideIncudeDirs _headerIsInside) + # check header path against ignored and honored include directories + cotire_find_closest_relative_path("${_headerFile}" "${_insideIncudeDirs}" _insideRelPath) + if (_insideRelPath) + # header is inside, but could be become outside if there is a shorter outside match + cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncudeDirs}" _outsideRelPath) + if (_outsideRelPath) + string (LENGTH "${_insideRelPath}" _insideRelPathLen) + string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) + if (_outsideRelPathLen LESS _insideRelPathLen) + set (${_headerIsInside} FALSE) + else() + set (${_headerIsInside} TRUE) + endif() + else() + set (${_headerIsInside} TRUE) + endif() + else() + # header is outside + set (${_headerIsInside} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) + if (NOT EXISTS "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif (IS_DIRECTORY "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$") + # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path + # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation + # with the error message "error: no include path in which to search for header.h" + set (${_headerIsIgnoredVar} TRUE) + else() + set (${_headerIsIgnoredVar} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar) + # check header file extension + cotire_get_source_file_extension("${_headerFile}" _headerFileExt) + set (${_headerIsIgnoredVar} FALSE) + if (_headerFileExt) + list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index) + if (_index GREATER -1) + set (${_headerIsIgnoredVar} TRUE) + endif() + endif() +endmacro() + +macro (cotire_parse_line _line _headerFileVar _headerDepthVar) + if (MSVC) + # cl.exe /showIncludes output looks different depending on the language pack used, e.g.: + # English: "Note: including file: C:\directory\file" + # German: "Hinweis: Einlesen der Datei: C:\directory\file" + # We use a very general regular expression, relying on the presence of the : characters + if (_line MATCHES ":( +)([^:]+:[^:]+)$") + # Visual Studio compiler output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + else() + if (_line MATCHES "^(\\.+) (.*)$") + # GCC like output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + if (IS_ABSOLUTE "${CMAKE_MATCH_2}") + set (${_headerFileVar} "${CMAKE_MATCH_2}") + else() + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH) + endif() + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + endif() +endmacro() + +function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honoredIncudeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) + if (WIN32) + # prevent CMake macro invocation errors due to backslash characters in Windows paths + string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") + endif() + # canonize slashes + string (REPLACE "//" "/" _scanOutput "${_scanOutput}") + # prevent semicolon from being interpreted as a line separator + string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}") + # then separate lines + string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}") + list (LENGTH _scanOutput _len) + # remove duplicate lines to speed up parsing + list (REMOVE_DUPLICATES _scanOutput) + list (LENGTH _scanOutput _uniqueLen) + if (COTIRE_VERBOSE) + message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") + if (_ignoredExtensions) + message (STATUS "Ignored extensions: ${_ignoredExtensions}") + endif() + if (_ignoredIncudeDirs) + message (STATUS "Ignored paths: ${_ignoredIncudeDirs}") + endif() + if (_honoredIncudeDirs) + message (STATUS "Included paths: ${_honoredIncudeDirs}") + endif() + endif() + set (_sourceFiles ${ARGN}) + set (_selectedIncludes "") + set (_unparsedLines "") + # stack keeps track of inside/outside project status of processed header files + set (_headerIsInsideStack "") + foreach (_line IN LISTS _scanOutput) + if (_line) + cotire_parse_line("${_line}" _headerFile _headerDepth) + if (_headerFile) + cotire_check_header_file_location("${_headerFile}" "${_ignoredIncudeDirs}" "${_honoredIncudeDirs}" _headerIsInside) + if (COTIRE_DEBUG) + message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") + endif() + # update stack + list (LENGTH _headerIsInsideStack _stackLen) + if (_headerDepth GREATER _stackLen) + math (EXPR _stackLen "${_stackLen} + 1") + foreach (_index RANGE ${_stackLen} ${_headerDepth}) + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endforeach() + else() + foreach (_index RANGE ${_headerDepth} ${_stackLen}) + list (REMOVE_AT _headerIsInsideStack -1) + endforeach() + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerIsInsideStack}") + endif() + # header is a candidate if it is outside project + if (NOT _headerIsInside) + # get parent header file's inside/outside status + if (_headerDepth GREATER 1) + math (EXPR _index "${_headerDepth} - 2") + list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside) + else() + set (_parentHeaderIsInside TRUE) + endif() + # select header file if parent header file is inside project + # (e.g., a project header file that includes a standard header file) + if (_parentHeaderIsInside) + cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored) + if (NOT _headerIsIgnored) + cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored) + if (NOT _headerIsIgnored) + list (APPEND _selectedIncludes "${_headerFile}") + else() + # fix header's inside status on stack, it is ignored by extension now + list (REMOVE_AT _headerIsInsideStack -1) + list (APPEND _headerIsInsideStack TRUE) + endif() + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}") + endif() + endif() + endif() + else() + if (MSVC) + # for cl.exe do not keep unparsed lines which solely consist of a source file name + string (FIND "${_sourceFiles}" "${_line}" _index) + if (_index LESS 0) + list (APPEND _unparsedLines "${_line}") + endif() + else() + list (APPEND _unparsedLines "${_line}") + endif() + endif() + endif() + endforeach() + list (REMOVE_DUPLICATES _selectedIncludes) + set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE) + set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE) +endfunction() + +function (cotire_scan_includes _includesVar) + set(_options "") + set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION LANGUAGE UNPARSED_LINES) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + set (_cmd "${_option_COMPILER_EXECUTABLE}" ${_option_COMPILER_ARG1}) + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) + # only consider existing source files for scanning + set (_existingSourceFiles "") + foreach (_sourceFile ${_sourceFiles}) + if (EXISTS "${_sourceFile}") + list (APPEND _existingSourceFiles "${_sourceFile}") + endif() + endforeach() + if (NOT _existingSourceFiles) + set (${_includesVar} "" PARENT_SCOPE) + return() + endif() + list (APPEND _cmd ${_existingSourceFiles}) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + if (COTIRE_DEBUG) + message (STATUS "clearing VS_UNICODE_OUTPUT") + endif() + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output) + if (_result) + message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") + endif() + cotire_parse_includes( + "${_option_LANGUAGE}" "${_output}" + "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}" + "${_option_IGNORE_EXTENSIONS}" + _includes _unparsedLines + ${_sourceFiles}) + set (${_includesVar} ${_includes} PARENT_SCOPE) + if (_option_UNPARSED_LINES) + set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_append_undefs _contentsVar) + set (_undefs ${ARGN}) + if (_undefs) + list (REMOVE_DUPLICATES _undefs) + foreach (_definition ${_undefs}) + list (APPEND ${_contentsVar} "#undef ${_definition}") + endforeach() + endif() +endmacro() + +macro (cotire_comment_str _language _commentText _commentVar) + if ("${_language}" STREQUAL "CMAKE") + set (${_commentVar} "# ${_commentText}") + else() + set (${_commentVar} "/* ${_commentText} */") + endif() +endmacro() + +function (cotire_write_file _language _file _contents _force) + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1) + cotire_comment_str("${_language}" "${_file}" _header2) + set (_contents "${_header1}\n${_header2}\n${_contents}") + if (COTIRE_DEBUG) + message (STATUS "${_contents}") + endif() + if (_force OR NOT EXISTS "${_file}") + file (WRITE "${_file}" "${_contents}") + else() + file (READ "${_file}" _oldContents) + if (NOT "${_oldContents}" STREQUAL "${_contents}") + file (WRITE "${_file}" "${_contents}") + else() + if (COTIRE_DEBUG) + message (STATUS "${_file} unchanged") + endif() + endif() + endif() +endfunction() + +function (cotire_generate_unity_source _unityFile) + set(_options "") + set(_oneValueArgs LANGUAGE) + set(_multiValueArgs + DEPENDS SOURCES_COMPILE_DEFINITIONS + PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (_option_DEPENDS) + cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS}) + if (_unityFileIsUpToDate) + return() + endif() + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_PRE_UNDEFS) + set (_option_PRE_UNDEFS "") + endif() + if (NOT _option_SOURCES_PRE_UNDEFS) + set (_option_SOURCES_PRE_UNDEFS "") + endif() + if (NOT _option_POST_UNDEFS) + set (_option_POST_UNDEFS "") + endif() + if (NOT _option_SOURCES_POST_UNDEFS) + set (_option_SOURCES_POST_UNDEFS "") + endif() + set (_contents "") + if (_option_PROLOGUE) + list (APPEND _contents ${_option_PROLOGUE}) + endif() + if (_option_LANGUAGE AND _sourceFiles) + if ("${_option_LANGUAGE}" STREQUAL "CXX") + list (APPEND _contents "#ifdef __cplusplus") + elseif ("${_option_LANGUAGE}" STREQUAL "C") + list (APPEND _contents "#ifndef __cplusplus") + endif() + endif() + set (_compileUndefinitions "") + foreach (_sourceFile ${_sourceFiles}) + cotire_get_source_compile_definitions( + "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions + ${_option_SOURCES_COMPILE_DEFINITIONS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS}) + if (_option_PRE_UNDEFS) + list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS}) + endif() + if (_sourcePreUndefs) + list (APPEND _compileUndefinitions ${_sourcePreUndefs}) + endif() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_sourcePostUndefs) + list (APPEND _compileUndefinitions ${_sourcePostUndefs}) + endif() + if (_option_POST_UNDEFS) + list (APPEND _compileUndefinitions ${_option_POST_UNDEFS}) + endif() + foreach (_definition ${_compileDefinitions}) + if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$") + list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}") + list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}") + else() + list (APPEND _contents "#define ${_definition}") + list (INSERT _compileUndefinitions 0 "${_definition}") + endif() + endforeach() + get_filename_component(_sourceFile "${_sourceFile}" ABSOLUTE) + if (WIN32) + file (TO_NATIVE_PATH "${_sourceFile}" _sourceFile) + endif() + list (APPEND _contents "#include \"${_sourceFile}\"") + endforeach() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_option_LANGUAGE AND _sourceFiles) + list (APPEND _contents "#endif") + endif() + if (_option_EPILOGUE) + list (APPEND _contents ${_option_EPILOGUE}) + endif() + list (APPEND _contents "") + string (REPLACE ";" "\n" _contents "${_contents}") + if (COTIRE_VERBOSE) + message ("${_contents}") + endif() + cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE) +endfunction() + +function (cotire_generate_prefix_header _prefixFile) + set(_options "") + set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION) + set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS + INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (_option_DEPENDS) + cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) + if (_prefixFileIsUpToDate) + return() + endif() + endif() + set (_epilogue "") + if (_option_COMPILER_ID MATCHES "Intel") + # Intel compiler requires hdrstop pragma to stop generating PCH file + set (_epilogue "#pragma hdrstop") + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + cotire_scan_includes(_selectedHeaders ${_sourceFiles} + LANGUAGE "${_option_LANGUAGE}" + COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" + COMPILER_ID "${_option_COMPILER_ID}" + COMPILER_VERSION "${_option_COMPILER_VERSION}" + COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} + COMPILE_FLAGS ${_option_COMPILE_FLAGS} + INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} + IGNORE_PATH ${_option_IGNORE_PATH} + INCLUDE_PATH ${_option_INCLUDE_PATH} + IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} + UNPARSED_LINES _unparsedLines) + cotire_generate_unity_source("${_prefixFile}" EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) + set (_unparsedLinesFile "${_prefixFile}.log") + if (_unparsedLines) + if (COTIRE_VERBOSE OR NOT _selectedHeaders) + list (LENGTH _unparsedLines _skippedLineCount) + file (RELATIVE_PATH _unparsedLinesFileRelPath "${CMAKE_BINARY_DIR}" "${_unparsedLinesFile}") + message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFileRelPath}") + endif() + string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") + endif() + file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}") +endfunction() + +function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + # cl.exe options used + # /nologo suppresses display of sign-on banner + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /EP preprocess to stdout without #line directives + # /showIncludes list include files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /showIncludes") + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fdirectives-only do not expand macros, requires GCC >= 4.3 + if (_flags) + # append to list + list (APPEND _flags -H -E) + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + list (APPEND _flags "-fdirectives-only") + endif() + else() + # return as a flag string + set (_flags "-H -E") + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + set (_flags "${_flags} -fdirectives-only") + endif() + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -H print the name of each header file used + # -E invoke preprocessor + if (_flags) + # append to list + list (APPEND _flags -H -E) + else() + # return as a flag string + set (_flags "-H -E") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + # Windows Intel options used + # /nologo do not display compiler version information + # /QH display the include file order + # /EP preprocess to stdout, omitting #line directives + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /QH") + endif() + else() + # Linux / Mac OS X Intel options used + # -H print the name of each header file used + # -EP preprocess to stdout, omitting #line directives + # -Kc++ process all source or unrecognized file types as C++ source files + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags -H -EP) + else() + # return as a flag string + if ("${_language}" STREQUAL "CXX") + set (_flags "-Kc++ ") + endif() + set (_flags "${_flags}-H -EP") + endif() + endif() + else() + message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # cl.exe options used + # /Yc creates a precompiled header file + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /Zs syntax check only + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + else() + # return as a flag string + set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + endif() + elseif (_compilerID MATCHES "GNU|Clang") + # GCC / Clang options used + # -x specify the source language + # -c compile but do not link + # -o place output in file + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + else() + # return as a flag string + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # Windows Intel options used + # /nologo do not display compiler version information + # /Yc create a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + # /Zs syntax check only + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-create name of the precompiled header (PCH) to create + # -Kc++ process all source or unrecognized file types as C++ source files + # -fsyntax-only check only for correct syntax + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + get_filename_component(_pchDir "${_pchFile}" PATH) + get_filename_component(_pchName "${_pchFile}" NAME) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "-Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + endif() + else() + message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # cl.exe options used + # /Yu uses a precompiled header file during build + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -include process include file as the first line of the primary source file + # -Winvalid-pch warns if precompiled header is found but cannot be used + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}" "-Winvalid-pch") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -Winvalid-pch") + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -include process include file as the first line of the primary source file + # -Qunused-arguments don't emit warning for unused driver arguments + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # Windows Intel options used + # /Yu use a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-use name of the precompiled header (PCH) to use + # -include process include file as the first line of the primary source file + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + get_filename_component(_pchDir "${_pchFile}" PATH) + get_filename_component(_pchName "${_pchFile}" NAME) + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "-Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\"") + endif() + endif() + endif() + else() + message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) + set(_options "") + set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION LANGUAGE) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_pch_compilation_flags( + "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + if (COTIRE_DEBUG) + message (STATUS "clearing VS_UNICODE_OUTPUT") + endif() + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result) + if (_result) + message (FATAL_ERROR "Error ${_result} precompiling ${_prefixFile}.") + endif() +endfunction() + +function (cotire_check_precompiled_header_support _language _targetSourceDir _target _msgVar) + set (_unsupportedCompiler + "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # supported since Visual Studio C++ 6.0 + # and CMake does not support an earlier version + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC PCH support requires version >= 3.4 + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND + "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") + set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # all Clang versions have PCH support + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel PCH support requires version >= 8.0.0 + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND + "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") + set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + else() + set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) + endif() + if (APPLE) + # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) + if (CMAKE_CONFIGURATION_TYPES) + set (_configs ${CMAKE_CONFIGURATION_TYPES}) + elseif (CMAKE_BUILD_TYPE) + set (_configs ${CMAKE_BUILD_TYPE}) + else() + set (_configs "None") + endif() + foreach (_config ${_configs}) + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) + list (LENGTH _architectures _numberOfArchitectures) + if (_numberOfArchitectures GREATER 1) + string (REPLACE ";" ", " _architectureStr "${_architectures}") + set (${_msgVar} + "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})." + PARENT_SCOPE) + break() + endif() + endforeach() + endif() +endfunction() + +macro (cotire_get_intermediate_dir _cotireDir) + get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) +endmacro() + +macro (cotire_setup_file_extension_variables) + set (_unityFileExt_C ".c") + set (_unityFileExt_CXX ".cxx") + set (_prefixFileExt_C ".h") + set (_prefixFileExt_CXX ".hxx") +endmacro() + +function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}") + cotire_get_intermediate_dir(_baseDir) + set (_unityFile "${_baseDir}/${_unityFileName}") + set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) + if (COTIRE_DEBUG) + message(STATUS "${_unityFile}") + endif() +endfunction() + +function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + cotire_get_intermediate_dir(_baseDir) + set (_startIndex 0) + set (_index 0) + set (_unityFiles "") + set (_sourceFiles ${ARGN}) + foreach (_sourceFile ${_sourceFiles}) + get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE) + math (EXPR _unityFileCount "${_index} - ${_startIndex}") + if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes)) + if (_index GREATER 0) + # start new unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (_startIndex ${_index}) + endif() + math (EXPR _index "${_index} + 1") + endforeach() + list (LENGTH _sourceFiles _numberOfSources) + if (_startIndex EQUAL 0) + # there is only a single unity file + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles) + elseif (_startIndex LESS _numberOfSources) + # end with final unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) + if (COTIRE_DEBUG) + message(STATUS "${_unityFiles}") + endif() +endfunction() + +function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_prefixFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}") + string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}") + set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) + cotire_setup_file_extension_variables() + if (NOT _language) + set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}") + elseif (DEFINED _prefixFileExt_${_language}) + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}") + else() + set (_prefixFileBaseName "") + set (_prefixFileName "") + endif() + set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE) + set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_path _language _target _prefixFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_prefixFileVar} "" PARENT_SCOPE) + if (_prefixFileName) + if (NOT _language) + set (_language "C") + endif() + if (MSVC OR CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel") + cotire_get_intermediate_dir(_baseDir) + set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function (cotire_make_pch_file_path _language _targetSourceDir _target _pchFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_pchFileVar} "" PARENT_SCOPE) + if (_prefixFileBaseName AND _prefixFileName) + cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _msg) + if (NOT _msg) + if (XCODE) + # For Xcode, we completely hand off the compilation of the prefix header to the IDE + return() + endif() + cotire_get_intermediate_dir(_baseDir) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # MSVC uses the extension .pch added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GCC / Clang look for a precompiled header corresponding to the prefix header with the extension .gch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel uses the extension .pchi added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + +function (cotire_select_unity_source_files _unityFile _sourcesVar) + set (_sourceFiles ${ARGN}) + if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)") + set (_startIndex ${CMAKE_MATCH_1}) + set (_endIndex ${CMAKE_MATCH_2}) + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _startIndex LESS _numberOfSources) + math (EXPR _startIndex "${_numberOfSources} - 1") + endif() + if (NOT _endIndex LESS _numberOfSources) + math (EXPR _endIndex "${_numberOfSources} - 1") + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${_endIndex}) + list (GET _sourceFiles ${_index} _file) + list (APPEND _files "${_file}") + endforeach() + else() + set (_files ${_sourceFiles}) + endif() + set (${_sourcesVar} ${_files} PARENT_SCOPE) +endfunction() + +function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target's generated source files + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN}) + if (_generatedSources) + # but omit all generated source files that have the COTIRE_EXCLUDED property set to true + cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) + if (_excludedGeneratedSources) + list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources}) + endif() + # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly + cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources}) + if (_excludedNonDependencySources) + list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources}) + endif() + if (_generatedSources) + list (APPEND _dependencySources ${_generatedSources}) + endif() + endif() + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} unity source depends on ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) + # depend on target source files marked with custom COTIRE_DEPENDENCY property + set (_dependencySources "") + cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN}) + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} prefix header DEPENDS ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar) + set (COTIRE_TARGET_SOURCES ${ARGN}) + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") + cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${COTIRE_TARGET_SOURCES}) + cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${COTIRE_TARGET_SOURCES}) + # set up variables to be configured + set (COTIRE_TARGET_LANGUAGE "${_language}") + cotire_determine_compiler_version("${COTIRE_TARGET_LANGUAGE}" COTIRE_${_language}_COMPILER) + get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) + get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH) + get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) + get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) + get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES}) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES}) + set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + cotire_get_target_include_directories( + "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}) + cotire_get_target_compile_definitions( + "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) + cotire_get_target_compiler_flags( + "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) + cotire_get_source_files_compile_definitions( + "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${COTIRE_TARGET_SOURCES}) + endforeach() + get_cmake_property(_vars VARIABLES) + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") + # remove COTIRE_VERBOSE which is passed as a CMake define on command line + list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) + set (_contents "") + foreach (_var IN LISTS _matchVars ITEMS + MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES + CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 + CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + if (DEFINED ${_var}) + string (REPLACE "\"" "\\\"" _value "${${_var}}") + set (_contents "${_contents}set (${_var} \"${_value}\")\n") + endif() + endforeach() + cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) + set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) +endfunction() + +function (cotire_setup_pch_file_compilation _language _target _targetSourceDir _targetScript _prefixFile _pchFile) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we attach the precompiled header compilation to the first source file + # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion + if (_sourceFiles) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + list (GET _sourceFiles 0 _hostFile) + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_pch_compilation_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) + set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") + # make first source file depend on prefix header + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") + # mark first source file as cotired to prevent it from being used in another cotired target + set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + # for makefile based generator, we add a custom command to precompile the prefix header + if (_targetScript) + cotire_set_cmd_to_prologue(_cmds) + list (GET _sourceFiles 0 _hostFile) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") + file (RELATIVE_PATH _pchFileRelPath "${CMAKE_BINARY_DIR}" "${_pchFile}") + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") + endif() + set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) + add_custom_command(OUTPUT "${_pchFile}" + COMMAND ${_cmds} + DEPENDS "${_prefixFile}" + IMPLICIT_DEPENDS ${_language} "${_prefixFile}" + WORKING_DIRECTORY "${_targetSourceDir}" + COMMENT "Building ${_language} precompiled header ${_pchFileRelPath}" VERBATIM) + endif() + endif() +endfunction() + +function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we include the precompiled header in all but the first source file + # the first source file does the precompiled header compilation, see cotire_setup_pch_file_compilation + list (LENGTH _sourceFiles _numberOfSourceFiles) + if (_numberOfSourceFiles GREATER 1) + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + list (REMOVE_AT _sourceFiles 0) + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # make source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + if (NOT _wholeTarget) + # for makefile based generator, we force the inclusion of the prefix header for a subset + # of the source files, if this is a multi-language target or has excluded files + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + endif() + # make source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() +endfunction() + +function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) + set (_sourceFiles ${ARGN}) + # force the inclusion of the prefix header for the given source files + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + # make source files depend on prefix header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") +endfunction() + +function (cotire_get_first_set_property_value _propertyValueVar _type _object) + set (_properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE) + return() + endif() + endforeach() + set (${_propertyValueVar} "" PARENT_SCOPE) +endfunction() + +function (cotire_setup_combine_command _language _sourceDir _targetScript _joinedFile _cmdsVar) + set (_files ${ARGN}) + set (_filesPaths "") + foreach (_file ${_files}) + if (IS_ABSOLUTE "${_file}") + set (_filePath "${_file}") + else() + get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE) + endif() + file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}") + if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.") + list (APPEND _filesPaths "${_fileRelPath}") + else() + list (APPEND _filesPaths "${_filePath}") + endif() + endforeach() + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") + if (_targetScript) + list (APPEND _prefixCmd "${_targetScript}") + endif() + list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths}) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") + endif() + set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) + file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") + get_filename_component(_joinedFileName "${_joinedFileRelPath}" NAME_WE) + if (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}") + elseif (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}") + else() + set (_comment "Generating ${_joinedFileRelPath}") + endif() + add_custom_command( + OUTPUT "${_joinedFile}" + COMMAND ${_prefixCmd} + DEPENDS ${_files} + COMMENT "${_comment}" + WORKING_DIRECTORY "${_sourceDir}" VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _wholeTarget) + if (XCODE) + # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers + # if necessary, we also generate a single prefix header which includes all language specific prefix headers + set (_prefixFiles "") + foreach (_language ${_languages}) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + list (APPEND _prefixFiles "${_prefixFile}") + endif() + endforeach() + set (_cmds ${ARGN}) + list (LENGTH _prefixFiles _numberOfPrefixFiles) + if (_numberOfPrefixFiles GREATER 1) + cotire_make_prefix_file_path("" ${_target} _prefixHeader) + cotire_setup_combine_command("" "${_targetSourceDir}" "" "${_prefixHeader}" _cmds ${_prefixFiles}) + else() + set (_prefixHeader "${_prefixFiles}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") + endif() + add_custom_command(TARGET "${_target}" + PRE_BUILD ${_cmds} + WORKING_DIRECTORY "${_targetSourceDir}" + COMMENT "Updating target ${_target} prefix headers" VERBATIM) + # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") + elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + # for makefile based generator, we force inclusion of the prefix header for all target source files + # if this is a single-language target without any excluded files + if (_wholeTarget) + set (_language "${_languages}") + # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level + # see cotire_setup_pch_file_inclusion + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property(TARGET ${_target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + endif() + endif() + endif() +endfunction() + +function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _unityFiles _cmdsVar) + set (_dependencySources "") + cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) + foreach (_unityFile ${_unityFiles}) + file (RELATIVE_PATH _unityFileRelPath "${CMAKE_BINARY_DIR}" "${_unityFile}") + set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) + # set up compiled unity source dependencies + # this ensures that missing source files are generated before the unity file is compiled + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") + endif() + if (_dependencySources) + set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_dependencySources}) + endif() + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel + set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") + endif() + cotire_set_cmd_to_prologue(_unityCmd) + list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetScript}" "${_unityFile}") + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_targetScript}") + endif() + add_custom_command( + OUTPUT "${_unityFile}" + COMMAND ${_unityCmd} + DEPENDS "${_targetScript}" + COMMENT "Generating ${_language} unity source ${_unityFileRelPath}" + WORKING_DIRECTORY "${_targetSourceDir}" VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) + endforeach() + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles GREATER 1) + # create a joint unity file from all unity file segments + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_single_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar) + set (_sourceFiles ${ARGN}) + set (_dependencySources "") + cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" "${_unityFile}") + set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_targetScript} ${_unityFile} ${_dependencySources}") + endif() + file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") + add_custom_command( + OUTPUT "${_prefixFile}" "${_prefixFile}.log" + COMMAND ${_prefixCmd} + DEPENDS "${_targetScript}" "${_unityFile}" ${_dependencySources} + COMMENT "Generating ${_language} prefix header ${_prefixFileRelPath}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_multi_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles GREATER 1) + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) + cotire_setup_single_prefix_generation_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" + "${_prefixFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles}) + else() + cotire_setup_single_prefix_generation_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" + "${_prefixFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_init_cotire_target_properties _target) + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}") + cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}") + if (NOT _isRelative) + set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}") + endif() + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) + if (NOT _isSet) + if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}") + else() + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "") + endif() + endif() +endfunction() + +function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + string (REPLACE ";" " " _languagesStr "${_languages}") + math (EXPR _numberOfExcludedFiles "${ARGC} - 4") + if (_numberOfExcludedFiles EQUAL 0) + set (_excludedStr "") + elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4) + string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}") + else() + set (_excludedStr "excluding ${_numberOfExcludedFiles} files") + endif() + set (_targetMsg "") + if (NOT _languages) + set (_targetMsg "Target ${_target} cannot be cotired.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH AND NOT _targetAddSCU) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.") + endif() + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetAddSCU) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") + endif() + else() + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired.") + endif() + endif() + set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) +endfunction() + +function (cotire_choose_target_languages _targetSourceDir _target _targetLanguagesVar) + set (_languages ${ARGN}) + set (_allSourceFiles "") + set (_allExcludedSourceFiles "") + set (_allCotiredSourceFiles "") + set (_targetLanguages "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + set (_disableMsg "") + foreach (_language ${_languages}) + get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) + get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) + if (_prefixHeader OR _unityBuildFile) + message (STATUS "Target ${_target} has already been cotired.") + set (${_targetLanguagesVar} "" PARENT_SCOPE) + return() + endif() + if (_targetUsePCH AND "${_language}" STREQUAL "C" OR "${_language}" STREQUAL "CXX") + cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _disableMsg) + if (_disableMsg) + set (_targetUsePCH FALSE) + endif() + endif() + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _excludedSources OR _cotiredSources) + list (APPEND _targetLanguages ${_language}) + endif() + if (_sourceFiles) + list (APPEND _allSourceFiles ${_sourceFiles}) + endif() + if (_excludedSources) + list (APPEND _allExcludedSourceFiles ${_excludedSources}) + endif() + if (_cotiredSources) + list (APPEND _allCotiredSourceFiles ${_cotiredSources}) + endif() + endforeach() + set (_targetMsgLevel STATUS) + if (NOT _targetLanguages) + string (REPLACE ";" " or " _languagesStr "${_languages}") + set (_disableMsg "No ${_languagesStr} source files.") + set (_targetUsePCH FALSE) + set (_targetAddSCU FALSE) + endif() + if (_targetUsePCH) + list (LENGTH _allSourceFiles _numberOfSources) + if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_disableMsg "Too few applicable sources.") + set (_targetUsePCH FALSE) + elseif (_allCotiredSourceFiles) + cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) + list (REMOVE_DUPLICATES _cotireTargets) + string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") + set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.") + set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},") + set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") + set (_targetMsgLevel SEND_ERROR) + set (_targetUsePCH FALSE) + elseif (XCODE AND _allExcludedSourceFiles) + # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target + set (_disableMsg "Exclusion of source files not supported for generator Xcode.") + set (_targetUsePCH FALSE) + elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY") + # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target + set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.") + set (_targetUsePCH FALSE) + endif() + endif() + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) + cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) + if (_targetMsg) + if (NOT DEFINED COTIREMSG_${_target}) + set (COTIREMSG_${_target} "") + endif() + if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR + NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}") + # cache message to avoid redundant messages on re-configure + set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.") + message (${_targetMsgLevel} "${_targetMsg}") + endif() + endif() + set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) +endfunction() + +function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) + set (_sourceFiles ${ARGN}) + get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") + set (_numberOfThreads "${CMAKE_MATCH_2}") + if (NOT _numberOfThreads) + # use all available cores + ProcessorCount(_numberOfThreads) + endif() + list (LENGTH _sourceFiles _numberOfSources) + math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") + # a unity source segment must not contain less than COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES files + if (_maxIncludes LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_maxIncludes ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + endif() + elseif (NOT _maxIncludes MATCHES "[0-9]+") + set (_maxIncludes 0) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_target} unity source max includes = ${_maxIncludes}") + endif() + set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) +endfunction() + +function (cotire_process_target_language _language _configurations _targetSourceDir _targetBinaryDir _target _wholeTargetVar _cmdsVar) + set (${_cmdsVar} "" PARENT_SCOPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (NOT _sourceFiles AND NOT _cotiredSources) + return() + endif() + set (_wholeTarget ${${_wholeTargetVar}}) + set (_cmds "") + # check for user provided unity source file list + get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) + if (NOT _unitySourceFiles) + set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) + endif() + cotire_generate_target_script( + ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript ${_unitySourceFiles}) + cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) + cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) + if (NOT _unityFiles) + return() + endif() + cotire_setup_unity_generation_commands( + ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) + if (_prefixFile) + # check for user provided prefix header files + get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + if (_prefixHeaderFiles) + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + else() + cotire_setup_multi_prefix_generation_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + endif() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + if (_targetUsePCH) + cotire_make_pch_file_path(${_language} "${_targetSourceDir}" ${_target} _pchFile) + if (_pchFile) + cotire_setup_pch_file_compilation( + ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + if (_excludedSources) + set (_wholeTarget FALSE) + endif() + cotire_setup_pch_file_inclusion( + ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + endif() + elseif (_prefixHeaderFiles) + # user provided prefix header must be included + cotire_setup_prefix_file_inclusion( + ${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) + endif() + endif() + # mark target as cotired for language + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}") + if (_prefixFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}") + if (_targetUsePCH AND _pchFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") + endif() + endif() + set (${_wholeTargetVar} ${_wholeTarget} PARENT_SCOPE) + set (${_cmdsVar} ${_cmds} PARENT_SCOPE) +endfunction() + +function (cotire_setup_clean_target _target) + set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}") + if (NOT TARGET "${_cleanTargetName}") + cotire_set_cmd_to_prologue(_cmds) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") + add_custom_target(${_cleanTargetName} COMMAND ${_cmds} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up target ${_target} cotire generated files" VERBATIM) + cotire_init_target("${_cleanTargetName}") + endif() +endfunction() + +function (cotire_setup_pch_target _languages _configurations _target) + if ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + # for makefile based generators, we add a custom target to trigger the generation of the cotire related files + set (_dependsFiles "") + foreach (_language ${_languages}) + set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # Visual Studio and Intel only create precompiled header as a side effect + list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) + endif() + cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) + if (_dependsFile) + list (APPEND _dependsFiles "${_dependsFile}") + endif() + endforeach() + if (_dependsFiles) + set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}") + add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles}) + cotire_init_target("${_pchTargetName}") + cotire_add_to_pch_all_target(${_pchTargetName}) + endif() + else() + # for other generators, we add the "clean all" target to clean up the precompiled header + cotire_setup_clean_all_target() + endif() +endfunction() + +function (cotire_setup_unity_build_target _languages _configurations _targetSourceDir _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (NOT _unityTargetName) + set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") + endif() + # determine unity target sub type + get_target_property(_targetType ${_target} TYPE) + if ("${_targetType}" STREQUAL "EXECUTABLE") + set (_unityTargetSubType "") + elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (_unityTargetSubType "${CMAKE_MATCH_1}") + else() + message (WARNING "Unknown target type ${_targetType}.") + return() + endif() + # determine unity target sources + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_unityTargetSources ${_targetSourceFiles}) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + # remove source files that are included in the unity source + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _cotiredSources) + list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) + endif() + # if cotire is applied to a target which has not been added in the current source dir, + # non-existing files cannot be referenced from the unity build target (this is a CMake restriction) + if (NOT "${_targetSourceDir}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + set (_nonExistingFiles "") + foreach (_file ${_unityTargetSources}) + if (NOT EXISTS "${_file}") + list (APPEND _nonExistingFiles "${_file}") + endif() + endforeach() + if (_nonExistingFiles) + if (COTIRE_VERBOSE) + message (STATUS "removing non-existing ${_nonExistingFiles} from ${_unityTargetName}") + endif() + list (REMOVE_ITEM _unityTargetSources ${_nonExistingFiles}) + endif() + endif() + # add unity source files instead + list (APPEND _unityTargetSources ${_unityFiles}) + endif() + endforeach() + if (COTIRE_DEBUG) + message (STATUS "add ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") + endif() + # generate unity target + if ("${_targetType}" STREQUAL "EXECUTABLE") + add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + else() + add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + endif() + set (_outputDirProperties + ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_ + LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_ + RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_) + # copy output location properties + if (COTIRE_UNITY_OUTPUT_DIRECTORY) + set (_setDefaultOutputDir TRUE) + if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + else() + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + cotire_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties}) + foreach (_property ${_properties}) + get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) + if (_outputDir) + get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}") + set (_setDefaultOutputDir FALSE) + endif() + endforeach() + if (_setDefaultOutputDir) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + endif() + endif() + if (_setDefaultOutputDir) + set_target_properties(${_unityTargetName} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}" + LIBRARY_OUTPUT_DIRECTORY "${_outputDir}" + RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") + endif() + else() + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + endif() + # copy output name + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_ + LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_ + OUTPUT_NAME OUTPUT_NAME_ + RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_ + PREFIX _POSTFIX SUFFIX) + # copy compile stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPILE_DEFINITIONS COMPILE_DEFINITIONS_ + COMPILE_FLAGS COMPILE_OPTIONS + Fortran_FORMAT Fortran_MODULE_DIRECTORY + INCLUDE_DIRECTORIES + INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_ + POSITION_INDEPENDENT_CODE + C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN) + # copy interface stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_STRING + INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_OPTIONS INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_LINK_LIBRARIES INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + # copy link stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH + LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED + LINK_FLAGS LINK_FLAGS_ + LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_ + LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_ + LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC + STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_ + NO_SONAME SOVERSION VERSION) + # copy Qt stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + AUTOMOC AUTOMOC_MOC_OPTIONS) + # copy cmake stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) + # copy Apple platform specific stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUNDLE BUNDLE_EXTENSION FRAMEWORK INSTALL_NAME_DIR MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST + MACOSX_RPATH OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE) + # copy Windows platform specific stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + GNUtoMS + PDB_NAME PDB_NAME_ PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_ + VS_DOTNET_REFERENCES VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE VS_KEYWORD + VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER + VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES WIN32_EXECUTABLE) + # use output name from original target + get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) + if (NOT _targetOutputName) + set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}") + endif() + # use export symbol from original target + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}") + if ("${_targetType}" STREQUAL "EXECUTABLE") + set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) + endif() + endif() + cotire_init_target(${_unityTargetName}) + cotire_add_to_unity_all_target(${_unityTargetName}) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") +endfunction(cotire_setup_unity_build_target) + +function (cotire_target _target) + set(_options "") + set(_oneValueArgs SOURCE_DIR BINARY_DIR) + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_SOURCE_DIR) + set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + if (NOT _option_BINARY_DIR) + set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + if (NOT _option_LANGUAGES) + get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + endif() + if (NOT _option_CONFIGURATIONS) + if (CMAKE_CONFIGURATION_TYPES) + set (_option_CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES}) + elseif (CMAKE_BUILD_TYPE) + set (_option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}") + else() + set (_option_CONFIGURATIONS "None") + endif() + endif() + # trivial checks + get_target_property(_imported ${_target} IMPORTED) + if (_imported) + message (WARNING "Imported target ${_target} cannot be cotired.") + return() + endif() + # resolve alias + get_target_property(_aliasName ${_target} ALIASED_TARGET) + if (_aliasName) + if (COTIRE_DEBUG) + message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.") + endif() + set (_target ${_aliasName}) + endif() + # check if target needs to be cotired for build type + # when using configuration types, the test is performed at build time + cotire_init_cotire_target_properties(${_target}) + if (NOT CMAKE_CONFIGURATION_TYPES) + if (CMAKE_BUILD_TYPE) + list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index) + else() + list (FIND _option_CONFIGURATIONS "None" _index) + endif() + if (_index EQUAL -1) + if (COTIRE_DEBUG) + message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})") + endif() + return() + endif() + endif() + # choose languages that apply to the target + cotire_choose_target_languages("${_option_SOURCE_DIR}" "${_target}" _targetLanguages ${_option_LANGUAGES}) + if (NOT _targetLanguages) + return() + endif() + list (LENGTH _targetLanguages _numberOfLanguages) + if (_numberOfLanguages GREATER 1) + set (_wholeTarget FALSE) + else() + set (_wholeTarget TRUE) + endif() + set (_cmds "") + foreach (_language ${_targetLanguages}) + cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" + "${_option_SOURCE_DIR}" "${_option_BINARY_DIR}" ${_target} _wholeTarget _cmd) + if (_cmd) + list (APPEND _cmds ${_cmd}) + endif() + endforeach() + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + if (_targetAddSCU) + cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" "${_option_SOURCE_DIR}" ${_target}) + endif() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + if (_targetUsePCH) + cotire_setup_target_pch_usage("${_targetLanguages}" "${_option_SOURCE_DIR}" ${_target} ${_wholeTarget} ${_cmds}) + cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + endif() + get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) + if (_targetAddCleanTarget) + cotire_setup_clean_target(${_target}) + endif() +endfunction(cotire_target) + +function(cotire_target_link_libraries _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_unityTargetName}") + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") + endif() + if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") + if (CMAKE_VERSION VERSION_LESS "2.8.11") + message (WARNING "Unity target link strategy ${_linkLibrariesStrategy} requires CMake 2.8.11 or later. Defaulting to NONE for ${_target}.") + return() + endif() + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + if (_linkLibraries) + if (COTIRE_DEBUG) + message (STATUS "target ${_target} link libraries: ${_linkLibraries}") + endif() + set (_unityTargetLibraries "") + foreach (_library ${_linkLibraries}) + if (TARGET "${_library}" AND "${_linkLibrariesStrategy}" MATCHES "COPY_UNITY") + get_target_property(_libraryUnityTargetName ${_library} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_libraryUnityTargetName}") + list (APPEND _unityTargetLibraries "${_libraryUnityTargetName}") + else() + list (APPEND _unityTargetLibraries "${_library}") + endif() + else() + list (APPEND _unityTargetLibraries "${_library}") + endif() + endforeach() + set_property(TARGET ${_unityTargetName} APPEND PROPERTY LINK_LIBRARIES ${_unityTargetLibraries}) + if (COTIRE_DEBUG) + message (STATUS "set unity target ${_unityTargetName} link libraries: ${_unityTargetLibraries}") + endif() + endif() + endif() + endif() +endfunction(cotire_target_link_libraries) + +function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) + if (_targetName) + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*") + else() + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*") + endif() + # filter files in intermediate directory + set (_filesToRemove "") + foreach (_file ${_cotireFiles}) + get_filename_component(_dir "${_file}" PATH) + get_filename_component(_dirName "${_dir}" NAME) + if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") + list (APPEND _filesToRemove "${_file}") + endif() + endforeach() + if (_filesToRemove) + if (COTIRE_VERBOSE) + message (STATUS "removing ${_filesToRemove}") + endif() + file (REMOVE ${_filesToRemove}) + endif() +endfunction() + +function (cotire_init_target _targetName) + if (COTIRE_TARGETS_FOLDER) + set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") + endif() + if (MSVC_IDE) + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endfunction() + +function (cotire_add_to_pch_all_target _pchTargetName) + set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_pchTargetName}) +endfunction() + +function (cotire_add_to_unity_all_target _unityTargetName) + set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_unityTargetName}) +endfunction() + +function (cotire_setup_clean_all_target) + set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") + add_custom_target(${_targetName} COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Cleaning up all cotire generated files" VERBATIM) + cotire_init_target("${_targetName}") + endif() +endfunction() + +function (cotire) + set(_options "") + set(_oneValueArgs SOURCE_DIR BINARY_DIR) + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_targets ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_SOURCE_DIR) + set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + if (NOT _option_BINARY_DIR) + set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS} + SOURCE_DIR "${_option_SOURCE_DIR}" BINARY_DIR "${_option_BINARY_DIR}") + else() + message (WARNING "${_target} is not a target.") + endif() + endforeach() + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target_link_libraries(${_target}) + endif() + endforeach() +endfunction() + +if (CMAKE_SCRIPT_MODE_FILE) + + # cotire is being run in script mode + # locate -P on command args + set (COTIRE_ARGC -1) + foreach (_index RANGE ${CMAKE_ARGC}) + if (COTIRE_ARGC GREATER -1) + set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}") + math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1") + elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P") + set (COTIRE_ARGC 0) + endif() + endforeach() + + # include target script if available + if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$") + # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES) + include("${COTIRE_ARGV2}") + endif() + + if (COTIRE_DEBUG) + message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") + endif() + + if (WIN32) + # for MSVC, compiler IDs may not always be set correctly + if (MSVC) + set (CMAKE_C_COMPILER_ID "MSVC") + set (CMAKE_CXX_COMPILER_ID "MSVC") + endif() + endif() + + if (NOT COTIRE_BUILD_TYPE) + set (COTIRE_BUILD_TYPE "None") + endif() + string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) + set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) + set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) + # check if target has been cotired for actual build type COTIRE_BUILD_TYPE + list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index) + if (_index GREATER -1) + set (_sources ${COTIRE_TARGET_SOURCES}) + set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}}) + else() + if (COTIRE_DEBUG) + message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})") + endif() + set (_sources "") + set (_sourcesDefinitions "") + endif() + set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS}) + set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS}) + set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS}) + set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS}) + + if ("${COTIRE_ARGV1}" STREQUAL "unity") + + cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) + cotire_generate_unity_source( + "${COTIRE_ARGV3}" ${_sources} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV2}" + SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} + PRE_UNDEFS ${_targetPreUndefs} + POST_UNDEFS ${_targetPostUndefs} + SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} + SOURCES_POST_UNDEFS ${_sourcesPostUndefs}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") + + set (_files "") + foreach (_index RANGE 4 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_generate_prefix_header( + "${COTIRE_ARGV3}" ${_files} + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS} + IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" + INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} + IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" + INCLUDE_DIRECTORIES ${_includeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") + + set (_files "") + foreach (_index RANGE 5 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_precompile_prefix_header( + "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + INCLUDE_DIRECTORIES ${_includeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "combine") + + if (COTIRE_TARGET_LANGUAGE) + set (_startIndex 3) + else() + set (_startIndex 2) + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + if (COTIRE_TARGET_LANGUAGE) + cotire_generate_unity_source(${_files} LANGUAGE "${COTIRE_TARGET_LANGUAGE}") + else() + cotire_generate_unity_source(${_files}) + endif() + + elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") + + cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") + + else() + message (FATAL_ERROR "Unknown cotire command \"${COTIRE_ARGV1}\".") + endif() + +else() + + # cotire is being run in include mode + # set up all variable and property definitions + + unset (COTIRE_C_COMPILER_VERSION CACHE) + unset (COTIRE_CXX_COMPILER_VERSION CACHE) + + if (NOT DEFINED COTIRE_DEBUG_INIT) + if (DEFINED COTIRE_DEBUG) + set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) + else() + set (COTIRE_DEBUG_INIT FALSE) + endif() + endif() + option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT}) + + if (NOT DEFINED COTIRE_VERBOSE_INIT) + if (DEFINED COTIRE_VERBOSE) + set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE}) + else() + set (COTIRE_VERBOSE_INIT FALSE) + endif() + endif() + option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT}) + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING + "Ignore headers with the listed file extensions from the generated prefix header.") + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING + "Ignore headers from these directories when generating the prefix header.") + + set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING + "Ignore sources with the listed file extensions from the generated unity source.") + + set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING + "Minimum number of sources in target required to enable use of precompiled header.") + + if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) + if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}) + elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio") + # enable parallelization for generators that run multiple jobs by default + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j") + else() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0") + endif() + endif() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING + "Maximum number of source files to include in a single unity source file.") + + if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX) + set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix") + endif() + if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX) + set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity") + endif() + if (NOT COTIRE_INTDIR) + set (COTIRE_INTDIR "cotire") + endif() + if (NOT COTIRE_PCH_ALL_TARGET_NAME) + set (COTIRE_PCH_ALL_TARGET_NAME "all_pch") + endif() + if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME) + set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity") + endif() + if (NOT COTIRE_CLEAN_ALL_TARGET_NAME) + set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire") + endif() + if (NOT COTIRE_CLEAN_TARGET_SUFFIX) + set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire") + endif() + if (NOT COTIRE_PCH_TARGET_SUFFIX) + set (COTIRE_PCH_TARGET_SUFFIX "_pch") + endif() + if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) + set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") + endif() + if (NOT DEFINED COTIRE_TARGETS_FOLDER) + set (COTIRE_TARGETS_FOLDER "cotire") + endif() + if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY) + if ("${CMAKE_GENERATOR}" MATCHES "Ninja") + # generated Ninja build files do not work if the unity target produces the same output file as the cotired target + set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity") + else() + set (COTIRE_UNITY_OUTPUT_DIRECTORY "") + endif() + endif() + + # define cotire cache variables + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of include directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "If not defined, defaults to empty list." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS" + BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a header file extension matches one in the list, it will be excluded from the generated prefix header." + "Includes with an extension in CMAKE__SOURCE_FILE_EXTENSIONS are always ignored." + "If not defined, defaults to inc;inl;ipp." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS" + BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a source file extension matches one in the list, it will be excluded from the generated unity source file." + "Source files with an extension in CMAKE__IGNORE_EXTENSIONS are always excluded." + "If not defined, defaults to m;mm." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES" + BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header." + FULL_DOCS + "The variable can be set to an integer > 0." + "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." + "If not defined, defaults to 3." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer >= 0." + "If 0, cotire will only create a single unity source file." + "If a target contains more than that number of source files, cotire will create multiple unity source files for it." + "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores." + "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs." + "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise." + ) + + # define cotire directory properties + + define_property( + DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" + BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header." + FULL_DOCS + "See target property COTIRE_ENABLE_PRECOMPILED_HEADER." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD" + BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_UNITY_BUILD." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_CLEAN" + BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_CLEAN." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" + BRIEF_DOCS "Define strategy for setting up the unity target's link libraries." + FULL_DOCS + "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT." + ) + + # define cotire target properties + + define_property( + TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED + BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header." + FULL_DOCS + "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header." + "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target." + "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header." + "The target name will be set to this target's name with the suffix _pch appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED + BRIEF_DOCS "Add a new target that performs a unity build for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources." + "Most of the relevant target properties will be copied from this target to the new unity build target." + "Target dependencies and linked libraries have to be manually set up for the new unity build target." + "The unity target name will be set to this target's name with the suffix _unity appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED + BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)." + "The clean target name will be set to this target's name with the suffix _clean_cotire appended." + "Inherited from directory." + "Defaults to FALSE." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "Inherited from directory." + "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header." + "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH," + "the option which yields the closer relative path match wins." + "Inherited from directory." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer > 0." + "If a target contains more than that number of source files, cotire will create multiple unity build files for it." + "If not set, cotire will only create a single unity source file." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE_INIT" + BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will only add the given file(s) to the generated unity source file." + "If not set, cotire will add all the target source files to the generated unity source file." + "The property can be set to a user provided unity source file." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER_INIT" + BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will add the given header file(s) to the generated prefix header file." + "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file." + "The property can be set to a user provided prefix header file (e.g., stdafx.h)." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED + BRIEF_DOCS "Define strategy for setting up unity target's link libraries." + FULL_DOCS + "If this property is empty, the generated unity target's link libraries have to be set up manually." + "If this property is set to COPY, the unity target's link libraries will be copied from this target." + "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE" + BRIEF_DOCS "Read-only property. The generated unity source file(s)." + FULL_DOCS + "cotire sets this property to the path of the generated single computation unit source file for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER" + BRIEF_DOCS "Read-only property. The generated prefix header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language prefix header for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PRECOMPILED_HEADER" + BRIEF_DOCS "Read-only property. The generated precompiled header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language precompiled header binary for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME" + BRIEF_DOCS "The name of the generated unity build target corresponding to this target." + FULL_DOCS + "This property can be set to the desired name of the unity target that will be created by cotire." + "If not set, the unity target name will be set to this target's name with the suffix _unity appended." + "After this target has been processed by cotire, the property is set to the actual name of the generated unity target." + "Defaults to empty string." + ) + + # define cotire source properties + + define_property( + SOURCE PROPERTY "COTIRE_EXCLUDED" + BRIEF_DOCS "Do not modify source file's build command." + FULL_DOCS + "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header." + "The source file will also be excluded from the generated unity source file." + "Source files that have their COMPILE_FLAGS property set will be excluded by default." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_DEPENDENCY" + BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file." + FULL_DOCS + "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file." + "If the file is modified, cotire will re-generate the prefix header source upon build." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE" + BRIEF_DOCS "Start a new unity source file which includes this source file as the first one." + FULL_DOCS + "If this property is set to TRUE, cotire will complete the current unity file and start a new one." + "The new unity source file will include this source file as the first one." + "This property essentially works as a separator for unity source files." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_TARGET" + BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target." + FULL_DOCS + "cotire sets this property to the name of target, that the source file's build command has been altered for." + "Defaults to empty string." + ) + + message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") + +endif() diff --git a/src/contrib/CMakeLists.txt b/src/contrib/CMakeLists.txt index 19ff862b..41501c50 100644 --- a/src/contrib/CMakeLists.txt +++ b/src/contrib/CMakeLists.txt @@ -34,8 +34,6 @@ install(FILES ${contrib_headers} COMPONENT development-contrib ) -set(PCH_ADDITIONAL_COMPILER_FLAGS_lucene++-contrib -DLPP_HAVE_DLL) - add_library(lucene++-contrib SHARED ${contrib_sources} ${contrib_headers} @@ -52,6 +50,8 @@ target_link_libraries(lucene++-contrib lucene++ ) +cotire(lucene++-contrib) + install(TARGETS lucene++-contrib DESTINATION ${LIB_DESTINATION} COMPONENT runtime diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index be374090..17ed352a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -29,17 +29,14 @@ add_library(lucene++ SHARED ${lucene_sources} ) -set(PCH_ADDITIONAL_COMPILER_FLAGS_lucene++ -DLPP_HAVE_DLL) - -add_precompiled_header(lucene++ - ${lucene++-lib_SOURCE_DIR}/include/LuceneInc.h -) - target_link_libraries(lucene++ ${CMAKE_THREAD_LIBS_INIT} ${lucene_boost_libs} ) +set_target_properties(lucene++ PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "include/LuceneInc.h") +cotire(lucene++) + set_target_properties(lucene++ PROPERTIES VERSION ${lucene++_VERSION} SOVERSION ${lucene++_SOVERSION} diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 4b36179f..9400d37c 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -48,3 +48,5 @@ target_link_libraries(lucene++-tester gtest ${lucene_boost_libs} ) + +cotire(lucene++-tester) From 131f11ae22b975933f37f5c289b6754676359653 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 20 Feb 2014 02:36:23 +0100 Subject: [PATCH 055/157] Fix compiler warnings. --- src/core/analysis/PorterStemmer.cpp | 2 +- src/core/queryparser/QueryParserTokenManager.cpp | 16 ++++++++++++---- src/core/search/SloppyPhraseScorer.cpp | 2 +- src/core/search/spans/NearSpansUnordered.cpp | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/core/analysis/PorterStemmer.cpp b/src/core/analysis/PorterStemmer.cpp index 4170bddf..855b47f6 100644 --- a/src/core/analysis/PorterStemmer.cpp +++ b/src/core/analysis/PorterStemmer.cpp @@ -479,7 +479,7 @@ namespace Lucene if (b[k] == L'e') { int32_t a = m(); - if (a > 1 || a == 1 && !cvc(k - 1)) + if (a > 1 || (a == 1 && !cvc(k - 1))) --k; } if (b[k] == L'l' && doublec(k) && m() > 1) diff --git a/src/core/queryparser/QueryParserTokenManager.cpp b/src/core/queryparser/QueryParserTokenManager.cpp index 894cfd27..9c278763 100644 --- a/src/core/queryparser/QueryParserTokenManager.cpp +++ b/src/core/queryparser/QueryParserTokenManager.cpp @@ -567,7 +567,9 @@ namespace Lucene kind = 0x7fffffff; } ++curPos; - if ((i = jjnewStateCnt) == (startsAt = 36 - (jjnewStateCnt = startsAt))) + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 36 - jjnewStateCnt)) return curPos; try { @@ -790,7 +792,9 @@ namespace Lucene kind = 0x7fffffff; } ++curPos; - if ((i = jjnewStateCnt) == (startsAt = 7 - (jjnewStateCnt = startsAt))) + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 7 - jjnewStateCnt)) return curPos; try { @@ -879,7 +883,9 @@ namespace Lucene kind = 0x7fffffff; } ++curPos; - if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt))) + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 3 - jjnewStateCnt)) return curPos; try { @@ -1102,7 +1108,9 @@ namespace Lucene kind = 0x7fffffff; } ++curPos; - if ((i = jjnewStateCnt) == (startsAt = 7 - (jjnewStateCnt = startsAt))) + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 7 - jjnewStateCnt)) return curPos; try { diff --git a/src/core/search/SloppyPhraseScorer.cpp b/src/core/search/SloppyPhraseScorer.cpp index 4435ab8f..d21a48ab 100644 --- a/src/core/search/SloppyPhraseScorer.cpp +++ b/src/core/search/SloppyPhraseScorer.cpp @@ -138,7 +138,7 @@ namespace Lucene for (Collection::iterator pp = repeats.begin(); pp != repeats.end(); ++pp) { PhrasePositionsPtr pp2; - while (pp2 = termPositionsDiffer(*pp)) + while ((pp2 = termPositionsDiffer(*pp))) { if (!pp2->nextPosition()) // out of pps that do not differ, advance the pp with higher offset return -1; // ran out of a term - done diff --git a/src/core/search/spans/NearSpansUnordered.cpp b/src/core/search/spans/NearSpansUnordered.cpp index 27cb074d..1aa5a506 100644 --- a/src/core/search/spans/NearSpansUnordered.cpp +++ b/src/core/search/spans/NearSpansUnordered.cpp @@ -271,7 +271,7 @@ namespace Lucene length = end() - start(); unordered->totalLength += length; // add new length - if (!unordered->max || doc() > unordered->max->doc() || (doc() == unordered->max->doc()) && (end() > unordered->max->end())) + if (!unordered->max || doc() > unordered->max->doc() || ((doc() == unordered->max->doc()) && (end() > unordered->max->end()))) unordered->max = shared_from_this(); } unordered->more = condition; From 3bc5c686fa403a0f71a1aec391d55f3be1b967a8 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 20 Feb 2014 12:04:43 +0100 Subject: [PATCH 056/157] Reformatted code to a saner format. - Added braces, even for single lines. - Reduce indention inside namespaces. - I'm allowed to change my mind, right? --- .gitignore | 1 + include/ASCIIFoldingFilter.h | 96 +- include/AbstractAllTermDocs.h | 58 +- include/AbstractField.h | 415 +- include/AllTermDocs.h | 32 +- include/Analyzer.h | 96 +- include/Array.h | 218 +- include/Attribute.h | 82 +- include/AttributeSource.h | 304 +- include/AveragePayloadFunction.h | 34 +- include/Base64.h | 38 +- include/BaseCharFilter.h | 48 +- include/BitSet.h | 94 +- include/BitUtil.h | 90 +- include/BitVector.h | 120 +- include/BooleanClause.h | 91 +- include/BooleanQuery.h | 172 +- include/BooleanScorer.h | 285 +- include/BooleanScorer2.h | 300 +- include/BufferedDeletes.h | 85 +- include/BufferedIndexInput.h | 182 +- include/BufferedIndexOutput.h | 122 +- include/BufferedReader.h | 98 +- include/ByteBlockPool.h | 109 +- include/ByteFieldSource.h | 60 +- include/ByteSliceReader.h | 96 +- include/ByteSliceWriter.h | 62 +- include/CachingSpanFilter.h | 66 +- include/CachingTokenFilter.h | 56 +- include/CachingWrapperFilter.h | 92 +- include/CharArraySet.h | 62 +- include/CharBlockPool.h | 52 +- include/CharFilter.h | 64 +- include/CharFolder.h | 66 +- include/CharReader.h | 54 +- include/CharStream.h | 36 +- include/CharTokenizer.h | 80 +- include/CheckIndex.h | 500 +- include/ChecksumIndexInput.h | 96 +- include/ChecksumIndexOutput.h | 110 +- include/CloseableThreadLocal.h | 81 +- include/Collator.h | 36 +- include/Collection.h | 458 +- include/Collector.h | 240 +- include/ComplexExplanation.h | 66 +- include/CompoundFileReader.h | 209 +- include/CompoundFileWriter.h | 125 +- include/CompressionTools.h | 52 +- include/ConcurrentMergeScheduler.h | 122 +- include/ConjunctionScorer.h | 50 +- include/ConstantScoreQuery.h | 54 +- include/Constants.h | 142 +- include/CustomScoreProvider.h | 144 +- include/CustomScoreQuery.h | 236 +- include/CycleCheck.h | 72 +- include/DateField.h | 84 +- include/DateTools.h | 188 +- include/DefaultSimilarity.h | 70 +- include/DefaultSkipListReader.h | 92 +- include/DefaultSkipListWriter.h | 78 +- include/Directory.h | 192 +- include/DirectoryReader.h | 480 +- include/DisjunctionMaxQuery.h | 168 +- include/DisjunctionMaxScorer.h | 96 +- include/DisjunctionSumScorer.h | 162 +- include/DocConsumer.h | 32 +- include/DocConsumerPerThread.h | 34 +- include/DocFieldConsumer.h | 46 +- include/DocFieldConsumerPerField.h | 24 +- include/DocFieldConsumerPerThread.h | 30 +- include/DocFieldConsumers.h | 87 +- include/DocFieldConsumersPerField.h | 42 +- include/DocFieldConsumersPerThread.h | 46 +- include/DocFieldProcessor.h | 52 +- include/DocFieldProcessorPerField.h | 48 +- include/DocFieldProcessorPerThread.h | 141 +- include/DocIdBitSet.h | 44 +- include/DocIdSet.h | 48 +- include/DocIdSetIterator.h | 112 +- include/DocInverter.h | 52 +- include/DocInverterPerField.h | 60 +- include/DocInverterPerThread.h | 93 +- include/DocValues.h | 166 +- include/Document.h | 252 +- include/DocumentsWriter.h | 894 +- include/DocumentsWriterThreadState.h | 50 +- include/DoubleFieldSource.h | 95 +- include/ExactPhraseScorer.h | 26 +- include/Explanation.h | 117 +- include/FSDirectory.h | 232 +- include/FSLockFactory.h | 54 +- include/FastCharStream.h | 86 +- include/Field.h | 282 +- include/FieldCache.h | 517 +- include/FieldCacheImpl.h | 325 +- include/FieldCacheRangeFilter.h | 200 +- include/FieldCacheSanityChecker.h | 214 +- include/FieldCacheSource.h | 96 +- include/FieldCacheTermsFilter.h | 94 +- include/FieldComparator.h | 645 +- include/FieldComparatorSource.h | 28 +- include/FieldDoc.h | 54 +- include/FieldDocSortedHitQueue.h | 76 +- include/FieldInfo.h | 64 +- include/FieldInfos.h | 274 +- include/FieldInvertState.h | 96 +- include/FieldMaskingSpanQuery.h | 128 +- include/FieldScoreQuery.h | 109 +- include/FieldSelector.h | 117 +- include/FieldSortedTermVectorMapper.h | 72 +- include/FieldValueHitQueue.h | 115 +- include/Fieldable.h | 272 +- include/FieldsReader.h | 187 +- include/FieldsWriter.h | 96 +- include/FileReader.h | 80 +- include/FileSwitchDirectory.h | 142 +- include/FileUtils.h | 77 +- include/Filter.h | 50 +- include/FilterIndexReader.h | 243 +- include/FilterManager.h | 114 +- include/FilteredDocIdSet.h | 80 +- include/FilteredDocIdSetIterator.h | 58 +- include/FilteredQuery.h | 98 +- include/FilteredTermEnum.h | 96 +- include/FlagsAttribute.h | 66 +- include/FormatPostingsDocsConsumer.h | 32 +- include/FormatPostingsDocsWriter.h | 88 +- include/FormatPostingsFieldsConsumer.h | 36 +- include/FormatPostingsFieldsWriter.h | 58 +- include/FormatPostingsPositionsConsumer.h | 32 +- include/FormatPostingsPositionsWriter.h | 46 +- include/FormatPostingsTermsConsumer.h | 40 +- include/FormatPostingsTermsWriter.h | 54 +- include/FreqProxFieldMergeState.h | 68 +- include/FreqProxTermsWriter.h | 85 +- include/FreqProxTermsWriterPerField.h | 66 +- include/FreqProxTermsWriterPerThread.h | 40 +- include/FuzzyQuery.h | 128 +- include/FuzzyTermEnum.h | 202 +- include/HashMap.h | 321 +- include/HashSet.h | 217 +- include/HitQueue.h | 40 +- include/HitQueueBase.h | 97 +- include/ISOLatin1AccentFilter.h | 56 +- include/IndexCommit.h | 102 +- include/IndexDeletionPolicy.h | 106 +- include/IndexFileDeleter.h | 328 +- include/IndexFileNameFilter.h | 34 +- include/IndexFileNames.h | 148 +- include/IndexInput.h | 220 +- include/IndexOutput.h | 188 +- include/IndexReader.h | 1075 +- include/IndexSearcher.h | 172 +- include/IndexWriter.h | 2139 +- include/InfoStream.h | 103 +- include/InputStreamReader.h | 64 +- include/IntBlockPool.h | 42 +- include/IntFieldSource.h | 60 +- include/InvertedDocConsumer.h | 44 +- include/InvertedDocConsumerPerField.h | 40 +- include/InvertedDocConsumerPerThread.h | 30 +- include/InvertedDocEndConsumer.h | 32 +- include/InvertedDocEndConsumerPerField.h | 26 +- include/InvertedDocEndConsumerPerThread.h | 30 +- include/KeepOnlyLastCommitDeletionPolicy.h | 36 +- include/KeywordAnalyzer.h | 30 +- include/KeywordTokenizer.h | 62 +- include/LengthFilter.h | 46 +- include/LetterTokenizer.h | 54 +- include/LoadFirstFieldSelector.h | 28 +- include/Lock.h | 72 +- include/LockFactory.h | 80 +- include/LogByteSizeMergePolicy.h | 94 +- include/LogDocMergePolicy.h | 60 +- include/LogMergePolicy.h | 284 +- include/LowerCaseFilter.h | 34 +- include/LowerCaseTokenizer.h | 58 +- include/Lucene.h | 306 +- include/LuceneAllocator.h | 16 +- include/LuceneException.h | 162 +- include/LuceneFactory.h | 343 +- include/LuceneObject.h | 64 +- include/LuceneSignal.h | 49 +- include/LuceneSync.h | 52 +- include/LuceneThread.h | 144 +- include/LuceneTypes.h | 1076 +- include/MMapDirectory.h | 62 +- include/Map.h | 249 +- include/MapFieldSelector.h | 58 +- include/MapOfSets.h | 104 +- include/MappingCharFilter.h | 68 +- include/MatchAllDocsQuery.h | 56 +- include/MaxPayloadFunction.h | 34 +- include/MergeDocIDRemapper.h | 48 +- include/MergePolicy.h | 246 +- include/MergeScheduler.h | 36 +- include/MinPayloadFunction.h | 30 +- include/MiscUtils.h | 213 +- include/MultiFieldQueryParser.h | 246 +- include/MultiLevelSkipListReader.h | 165 +- include/MultiLevelSkipListWriter.h | 108 +- include/MultiPhraseQuery.h | 132 +- include/MultiReader.h | 238 +- include/MultiSearcher.h | 124 +- include/MultiTermQuery.h | 322 +- include/MultiTermQueryWrapperFilter.h | 88 +- include/MultipleTermPositions.h | 82 +- include/NativeFSLockFactory.h | 66 +- include/NearSpansOrdered.h | 170 +- include/NearSpansUnordered.h | 114 +- include/NoLockFactory.h | 52 +- include/NormalizeCharMap.h | 48 +- include/NormsWriter.h | 48 +- include/NormsWriterPerField.h | 66 +- include/NormsWriterPerThread.h | 44 +- include/NumberTools.h | 90 +- include/NumericField.h | 238 +- include/NumericRangeFilter.h | 138 +- include/NumericRangeQuery.h | 346 +- include/NumericTokenStream.h | 212 +- include/NumericUtils.h | 330 +- include/OffsetAttribute.h | 78 +- include/OpenBitSet.h | 326 +- include/OpenBitSetDISI.h | 72 +- include/OpenBitSetIterator.h | 76 +- include/OrdFieldSource.h | 76 +- include/ParallelMultiSearcher.h | 56 +- include/ParallelReader.h | 266 +- include/Payload.h | 148 +- include/PayloadAttribute.h | 52 +- include/PayloadFunction.h | 86 +- include/PayloadNearQuery.h | 168 +- include/PayloadSpanUtil.h | 52 +- include/PayloadTermQuery.h | 62 +- include/PerFieldAnalyzerWrapper.h | 92 +- include/PhrasePositions.h | 52 +- include/PhraseQuery.h | 134 +- include/PhraseQueue.h | 26 +- include/PhraseScorer.h | 114 +- include/PorterStemFilter.h | 68 +- include/PorterStemmer.h | 216 +- include/PositionBasedTermVectorMapper.h | 99 +- include/PositionIncrementAttribute.h | 96 +- include/PositiveScoresOnlyCollector.h | 44 +- include/PrefixFilter.h | 32 +- include/PrefixQuery.h | 54 +- include/PrefixTermEnum.h | 54 +- include/PriorityQueue.h | 376 +- include/Query.h | 190 +- include/QueryParseError.h | 78 +- include/QueryParser.h | 880 +- include/QueryParserCharStream.h | 138 +- include/QueryParserConstants.h | 118 +- include/QueryParserToken.h | 112 +- include/QueryParserTokenManager.h | 194 +- include/QueryTermVector.h | 58 +- include/QueryWrapperFilter.h | 54 +- include/RAMDirectory.h | 144 +- include/RAMFile.h | 66 +- include/RAMInputStream.h | 112 +- include/RAMOutputStream.h | 128 +- include/Random.h | 44 +- include/RawPostingList.h | 44 +- include/ReadOnlyDirectoryReader.h | 36 +- include/ReadOnlySegmentReader.h | 24 +- include/Reader.h | 64 +- include/ReaderUtil.h | 62 +- include/ReqExclScorer.h | 88 +- include/ReqOptSumScorer.h | 54 +- include/ReusableStringReader.h | 56 +- include/ReverseOrdFieldSource.h | 76 +- include/ScoreCachingWrappingScorer.h | 70 +- include/ScoreDoc.h | 46 +- include/Scorer.h | 96 +- include/ScorerDocQueue.h | 126 +- include/Searchable.h | 182 +- include/Searcher.h | 180 +- include/SegmentInfo.h | 234 +- include/SegmentInfoCollection.h | 58 +- include/SegmentInfos.h | 242 +- include/SegmentMergeInfo.h | 56 +- include/SegmentMergeQueue.h | 32 +- include/SegmentMerger.h | 258 +- include/SegmentReader.h | 296 +- include/SegmentTermDocs.h | 102 +- include/SegmentTermEnum.h | 112 +- include/SegmentTermPositionVector.h | 56 +- include/SegmentTermPositions.h | 98 +- include/SegmentTermVector.h | 56 +- include/SegmentWriteState.h | 50 +- include/SerialMergeScheduler.h | 36 +- include/Set.h | 256 +- include/SetBasedFieldSelector.h | 56 +- include/Similarity.h | 1164 +- include/SimilarityDelegator.h | 50 +- include/SimpleAnalyzer.h | 28 +- include/SimpleFSDirectory.h | 48 +- include/SimpleFSLockFactory.h | 54 +- include/SimpleLRUCache.h | 124 +- include/SingleInstanceLockFactory.h | 60 +- include/SingleTermEnum.h | 50 +- include/SloppyPhraseScorer.h | 98 +- include/SmallDouble.h | 38 +- include/SnapshotDeletionPolicy.h | 78 +- include/Sort.h | 202 +- include/SortField.h | 250 +- include/SortedTermVectorMapper.h | 88 +- include/SortedVIntList.h | 148 +- include/SpanFilter.h | 42 +- include/SpanFilterResult.h | 128 +- include/SpanFirstQuery.h | 74 +- include/SpanNearQuery.h | 88 +- include/SpanNotQuery.h | 70 +- include/SpanOrQuery.h | 66 +- include/SpanQuery.h | 36 +- include/SpanQueryFilter.h | 64 +- include/SpanScorer.h | 72 +- include/SpanTermQuery.h | 58 +- include/SpanWeight.h | 66 +- include/Spans.h | 114 +- include/StandardAnalyzer.h | 144 +- include/StandardFilter.h | 54 +- include/StandardTokenizer.h | 186 +- include/StandardTokenizerImpl.h | 306 +- include/StopAnalyzer.h | 58 +- include/StopFilter.h | 90 +- include/StoredFieldsWriter.h | 121 +- include/StoredFieldsWriterPerThread.h | 46 +- include/StringReader.h | 54 +- include/StringUtils.h | 118 +- include/Synchronize.h | 102 +- include/TeeSinkTokenFilter.h | 271 +- include/Term.h | 94 +- include/TermAttribute.h | 156 +- include/TermBuffer.h | 54 +- include/TermDocs.h | 90 +- include/TermEnum.h | 50 +- include/TermFreqVector.h | 86 +- include/TermInfo.h | 46 +- include/TermInfosReader.h | 109 +- include/TermInfosWriter.h | 162 +- include/TermPositionVector.h | 48 +- include/TermPositions.h | 82 +- include/TermQuery.h | 52 +- include/TermRangeFilter.h | 108 +- include/TermRangeQuery.h | 146 +- include/TermRangeTermEnum.h | 90 +- include/TermScorer.h | 116 +- include/TermSpans.h | 62 +- include/TermVectorEntry.h | 70 +- include/TermVectorEntryFreqSortedComparator.h | 26 +- include/TermVectorMapper.h | 102 +- include/TermVectorOffsetInfo.h | 70 +- include/TermVectorsReader.h | 203 +- include/TermVectorsTermsWriter.h | 160 +- include/TermVectorsTermsWriterPerField.h | 82 +- include/TermVectorsTermsWriterPerThread.h | 60 +- include/TermVectorsWriter.h | 58 +- include/TermsHash.h | 108 +- include/TermsHashConsumer.h | 44 +- include/TermsHashConsumerPerField.h | 40 +- include/TermsHashConsumerPerThread.h | 30 +- include/TermsHashPerField.h | 128 +- include/TermsHashPerThread.h | 90 +- include/TestPoint.h | 59 +- include/ThreadPool.h | 128 +- include/TimeLimitingCollector.h | 166 +- include/Token.h | 637 +- include/TokenFilter.h | 64 +- include/TokenStream.h | 158 +- include/Tokenizer.h | 112 +- include/TopDocs.h | 54 +- include/TopDocsCollector.h | 134 +- include/TopFieldCollector.h | 116 +- include/TopFieldDocs.h | 40 +- include/TopScoreDocCollector.h | 68 +- include/TypeAttribute.h | 64 +- include/UTF8Stream.h | 245 +- include/UnicodeUtils.h | 161 +- include/ValueSource.h | 64 +- include/ValueSourceQuery.h | 70 +- include/VariantUtils.h | 150 +- include/Weight.h | 126 +- include/WhitespaceAnalyzer.h | 28 +- include/WhitespaceTokenizer.h | 48 +- include/WildcardQuery.h | 80 +- include/WildcardTermEnum.h | 78 +- include/WordlistLoader.h | 70 +- .../common/analysis/ar/ArabicAnalyzer.cpp | 217 +- .../analysis/ar/ArabicLetterTokenizer.cpp | 40 +- .../analysis/ar/ArabicNormalizationFilter.cpp | 37 +- .../common/analysis/ar/ArabicNormalizer.cpp | 115 +- .../common/analysis/ar/ArabicStemFilter.cpp | 37 +- .../common/analysis/ar/ArabicStemmer.cpp | 199 +- .../common/analysis/br/BrazilianAnalyzer.cpp | 159 +- .../analysis/br/BrazilianStemFilter.cpp | 58 +- .../common/analysis/br/BrazilianStemmer.cpp | 1938 +- .../common/analysis/cjk/CJKAnalyzer.cpp | 95 +- .../common/analysis/cjk/CJKTokenizer.cpp | 378 +- .../common/analysis/cn/ChineseAnalyzer.cpp | 50 +- .../common/analysis/cn/ChineseFilter.cpp | 69 +- .../common/analysis/cn/ChineseTokenizer.cpp | 182 +- .../common/analysis/cz/CzechAnalyzer.cpp | 207 +- .../common/analysis/de/GermanAnalyzer.cpp | 131 +- .../common/analysis/de/GermanStemFilter.cpp | 73 +- .../common/analysis/de/GermanStemmer.cpp | 307 +- .../common/analysis/el/GreekAnalyzer.cpp | 179 +- .../analysis/el/GreekLowerCaseFilter.cpp | 142 +- .../common/analysis/fa/PersianAnalyzer.cpp | 453 +- .../fa/PersianNormalizationFilter.cpp | 37 +- .../common/analysis/fa/PersianNormalizer.cpp | 83 +- .../common/analysis/fr/ElisionFilter.cpp | 81 +- .../common/analysis/fr/FrenchAnalyzer.cpp | 165 +- .../common/analysis/fr/FrenchStemFilter.cpp | 73 +- .../common/analysis/fr/FrenchStemmer.cpp | 811 +- .../common/analysis/nl/DutchAnalyzer.cpp | 152 +- .../common/analysis/nl/DutchStemFilter.cpp | 94 +- .../common/analysis/nl/DutchStemmer.cpp | 517 +- .../analysis/reverse/ReverseStringFilter.cpp | 77 +- .../common/analysis/ru/RussianAnalyzer.cpp | 189 +- .../analysis/ru/RussianLetterTokenizer.cpp | 40 +- .../analysis/ru/RussianLowerCaseFilter.cpp | 38 +- .../common/analysis/ru/RussianStemFilter.cpp | 48 +- .../common/analysis/ru/RussianStemmer.cpp | 944 +- src/contrib/highlighter/DefaultEncoder.cpp | 17 +- src/contrib/highlighter/Encoder.cpp | 19 +- src/contrib/highlighter/Formatter.cpp | 19 +- src/contrib/highlighter/Fragmenter.cpp | 28 +- src/contrib/highlighter/GradientFormatter.cpp | 199 +- src/contrib/highlighter/Highlighter.cpp | 524 +- src/contrib/highlighter/HighlighterScorer.cpp | 54 +- .../highlighter/MapWeightedSpanTerm.cpp | 64 +- src/contrib/highlighter/NullFragmenter.cpp | 22 +- src/contrib/highlighter/QueryScorer.cpp | 236 +- .../highlighter/QueryTermExtractor.cpp | 130 +- src/contrib/highlighter/QueryTermScorer.cpp | 133 +- src/contrib/highlighter/SimpleFragmenter.cpp | 67 +- src/contrib/highlighter/SimpleHTMLEncoder.cpp | 80 +- .../highlighter/SimpleHTMLFormatter.cpp | 48 +- .../highlighter/SimpleSpanFragmenter.cpp | 111 +- .../highlighter/SpanGradientFormatter.cpp | 50 +- src/contrib/highlighter/TextFragment.cpp | 126 +- src/contrib/highlighter/TokenGroup.cpp | 162 +- src/contrib/highlighter/TokenSources.cpp | 263 +- src/contrib/highlighter/WeightedSpanTerm.cpp | 78 +- .../highlighter/WeightedSpanTermExtractor.cpp | 714 +- src/contrib/highlighter/WeightedTerm.cpp | 57 +- src/contrib/include/ArabicAnalyzer.h | 137 +- src/contrib/include/ArabicLetterTokenizer.h | 54 +- .../include/ArabicNormalizationFilter.h | 36 +- src/contrib/include/ArabicNormalizer.h | 100 +- src/contrib/include/ArabicStemFilter.h | 36 +- src/contrib/include/ArabicStemmer.h | 166 +- src/contrib/include/BrazilianAnalyzer.h | 105 +- src/contrib/include/BrazilianStemFilter.h | 36 +- src/contrib/include/BrazilianStemmer.h | 204 +- src/contrib/include/CJKAnalyzer.h | 103 +- src/contrib/include/CJKTokenizer.h | 174 +- src/contrib/include/ChineseAnalyzer.h | 67 +- src/contrib/include/ChineseFilter.h | 54 +- src/contrib/include/ChineseTokenizer.h | 134 +- src/contrib/include/CzechAnalyzer.h | 113 +- src/contrib/include/DefaultEncoder.h | 22 +- src/contrib/include/DutchAnalyzer.h | 109 +- src/contrib/include/DutchStemFilter.h | 94 +- src/contrib/include/DutchStemmer.h | 118 +- src/contrib/include/ElisionFilter.h | 48 +- src/contrib/include/Encoder.h | 22 +- src/contrib/include/Formatter.h | 28 +- src/contrib/include/Fragmenter.h | 46 +- src/contrib/include/FrenchAnalyzer.h | 105 +- src/contrib/include/FrenchStemFilter.h | 78 +- src/contrib/include/FrenchStemmer.h | 326 +- src/contrib/include/GermanAnalyzer.h | 107 +- src/contrib/include/GermanStemFilter.h | 54 +- src/contrib/include/GermanStemmer.h | 114 +- src/contrib/include/GradientFormatter.h | 92 +- src/contrib/include/GreekAnalyzer.h | 113 +- src/contrib/include/GreekLowerCaseFilter.h | 42 +- src/contrib/include/Highlighter.h | 227 +- src/contrib/include/HighlighterScorer.h | 74 +- src/contrib/include/LuceneContrib.h | 192 +- src/contrib/include/MapWeightedSpanTerm.h | 42 +- src/contrib/include/MemoryIndex.h | 692 +- src/contrib/include/NullFragmenter.h | 26 +- src/contrib/include/PersianAnalyzer.h | 127 +- .../include/PersianNormalizationFilter.h | 36 +- src/contrib/include/PersianNormalizer.h | 88 +- src/contrib/include/QueryScorer.h | 162 +- src/contrib/include/QueryTermExtractor.h | 94 +- src/contrib/include/QueryTermScorer.h | 112 +- src/contrib/include/ReverseStringFilter.h | 72 +- src/contrib/include/RussianAnalyzer.h | 111 +- src/contrib/include/RussianLetterTokenizer.h | 48 +- src/contrib/include/RussianLowerCaseFilter.h | 28 +- src/contrib/include/RussianStemFilter.h | 58 +- src/contrib/include/RussianStemmer.h | 222 +- src/contrib/include/SimpleFragmenter.h | 60 +- src/contrib/include/SimpleHTMLEncoder.h | 30 +- src/contrib/include/SimpleHTMLFormatter.h | 38 +- src/contrib/include/SimpleSpanFragmenter.h | 70 +- src/contrib/include/SnowballAnalyzer.h | 93 +- src/contrib/include/SnowballFilter.h | 38 +- src/contrib/include/SpanGradientFormatter.h | 34 +- src/contrib/include/TextFragment.h | 101 +- src/contrib/include/TokenGroup.h | 106 +- src/contrib/include/TokenSources.h | 135 +- src/contrib/include/WeightedSpanTerm.h | 83 +- .../include/WeightedSpanTermExtractor.h | 234 +- src/contrib/include/WeightedTerm.h | 56 +- src/contrib/memory/MemoryIndex.cpp | 1147 +- src/contrib/msvc/dllmain.cpp | 16 +- src/contrib/snowball/SnowballAnalyzer.cpp | 84 +- src/contrib/snowball/SnowballFilter.cpp | 49 +- .../libstemmer_c/include/libstemmer.h | 12 +- .../libstemmer_c/libstemmer/modules.h | 270 +- .../libstemmer_c/libstemmer/modules_utf8.h | 162 +- .../snowball/libstemmer_c/runtime/api.h | 20 +- .../snowball/libstemmer_c/runtime/header.h | 60 +- .../src_c/stem_ISO_8859_1_danish.h | 6 +- .../src_c/stem_ISO_8859_1_dutch.h | 6 +- .../src_c/stem_ISO_8859_1_english.h | 6 +- .../src_c/stem_ISO_8859_1_finnish.h | 6 +- .../src_c/stem_ISO_8859_1_french.h | 6 +- .../src_c/stem_ISO_8859_1_german.h | 6 +- .../src_c/stem_ISO_8859_1_hungarian.h | 6 +- .../src_c/stem_ISO_8859_1_italian.h | 6 +- .../src_c/stem_ISO_8859_1_norwegian.h | 6 +- .../src_c/stem_ISO_8859_1_porter.h | 6 +- .../src_c/stem_ISO_8859_1_portuguese.h | 6 +- .../src_c/stem_ISO_8859_1_spanish.h | 6 +- .../src_c/stem_ISO_8859_1_swedish.h | 6 +- .../src_c/stem_ISO_8859_2_romanian.h | 6 +- .../libstemmer_c/src_c/stem_KOI8_R_russian.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_danish.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_dutch.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_english.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_finnish.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_french.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_german.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_hungarian.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_italian.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_norwegian.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_porter.h | 6 +- .../src_c/stem_UTF_8_portuguese.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_romanian.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_russian.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_spanish.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_swedish.h | 6 +- .../libstemmer_c/src_c/stem_UTF_8_turkish.h | 6 +- src/core/analysis/ASCIIFoldingFilter.cpp | 3908 ++- src/core/analysis/Analyzer.cpp | 64 +- src/core/analysis/BaseCharFilter.cpp | 92 +- src/core/analysis/CachingTokenFilter.cpp | 78 +- src/core/analysis/CharArraySet.cpp | 105 +- src/core/analysis/CharFilter.cpp | 82 +- src/core/analysis/CharReader.cpp | 69 +- src/core/analysis/CharStream.cpp | 10 +- src/core/analysis/CharTokenizer.cpp | 170 +- src/core/analysis/ISOLatin1AccentFilter.cpp | 403 +- src/core/analysis/KeywordAnalyzer.cpp | 37 +- src/core/analysis/KeywordTokenizer.cpp | 114 +- src/core/analysis/LengthFilter.cpp | 42 +- src/core/analysis/LetterTokenizer.cpp | 40 +- src/core/analysis/LowerCaseFilter.cpp | 33 +- src/core/analysis/LowerCaseTokenizer.cpp | 40 +- src/core/analysis/MappingCharFilter.cpp | 186 +- src/core/analysis/NormalizeCharMap.cpp | 52 +- src/core/analysis/NumericTokenStream.cpp | 219 +- src/core/analysis/PerFieldAnalyzerWrapper.cpp | 93 +- src/core/analysis/PorterStemFilter.cpp | 34 +- src/core/analysis/PorterStemmer.cpp | 833 +- src/core/analysis/SimpleAnalyzer.cpp | 37 +- src/core/analysis/StopAnalyzer.cpp | 107 +- src/core/analysis/StopFilter.cpp | 90 +- src/core/analysis/TeeSinkTokenFilter.cpp | 228 +- src/core/analysis/Token.cpp | 815 +- src/core/analysis/TokenFilter.cpp | 46 +- src/core/analysis/TokenStream.cpp | 54 +- src/core/analysis/Tokenizer.cpp | 78 +- src/core/analysis/WhitespaceAnalyzer.cpp | 37 +- src/core/analysis/WhitespaceTokenizer.cpp | 40 +- src/core/analysis/WordlistLoader.cpp | 139 +- .../analysis/standard/StandardAnalyzer.cpp | 131 +- src/core/analysis/standard/StandardFilter.cpp | 88 +- .../analysis/standard/StandardTokenizer.cpp | 232 +- .../standard/StandardTokenizerImpl.cpp | 972 +- .../tokenattributes/FlagsAttribute.cpp | 89 +- .../tokenattributes/OffsetAttribute.cpp | 110 +- .../tokenattributes/PayloadAttribute.cpp | 102 +- .../PositionIncrementAttribute.cpp | 94 +- .../tokenattributes/TermAttribute.cpp | 230 +- .../tokenattributes/TypeAttribute.cpp | 105 +- src/core/document/AbstractField.cpp | 337 +- src/core/document/CompressionTools.cpp | 223 +- src/core/document/DateField.cpp | 82 +- src/core/document/DateTools.cpp | 357 +- src/core/document/Document.cpp | 207 +- src/core/document/Field.cpp | 541 +- src/core/document/FieldSelector.cpp | 15 +- src/core/document/Fieldable.cpp | 245 +- src/core/document/LoadFirstFieldSelector.cpp | 17 +- src/core/document/MapFieldSelector.cpp | 36 +- src/core/document/NumberTools.cpp | 133 +- src/core/document/NumericField.cpp | 150 +- src/core/document/SetBasedFieldSelector.cpp | 36 +- src/core/include/_BooleanQuery.h | 79 +- src/core/include/_ByteFieldSource.h | 40 +- src/core/include/_CachingSpanFilter.h | 26 +- src/core/include/_CachingWrapperFilter.h | 94 +- src/core/include/_CheckIndex.h | 34 +- src/core/include/_ConcurrentMergeScheduler.h | 44 +- src/core/include/_ConstantScoreQuery.h | 87 +- src/core/include/_CustomScoreQuery.h | 142 +- src/core/include/_DirectoryReader.h | 67 +- src/core/include/_DisjunctionMaxQuery.h | 60 +- src/core/include/_DocIdBitSet.h | 38 +- src/core/include/_DocIdSet.h | 49 +- src/core/include/_FieldCache.h | 164 +- src/core/include/_FieldCacheRangeFilter.h | 468 +- src/core/include/_FieldCacheSanityChecker.h | 40 +- src/core/include/_FieldCacheTermsFilter.h | 77 +- src/core/include/_FieldValueHitQueue.h | 61 +- src/core/include/_FilterManager.h | 81 +- src/core/include/_FilteredDocIdSet.h | 34 +- src/core/include/_FilteredQuery.h | 81 +- src/core/include/_FuzzyQuery.h | 53 +- src/core/include/_IndexReader.h | 26 +- src/core/include/_IndexWriter.h | 106 +- src/core/include/_IntFieldSource.h | 40 +- src/core/include/_MMapDirectory.h | 90 +- src/core/include/_MatchAllDocsQuery.h | 95 +- src/core/include/_MultiPhraseQuery.h | 52 +- src/core/include/_MultiSearcher.h | 191 +- src/core/include/_MultiTermQuery.h | 81 +- src/core/include/_MultipleTermPositions.h | 87 +- src/core/include/_NativeFSLockFactory.h | 54 +- src/core/include/_NearSpansUnordered.h | 89 +- src/core/include/_NoLockFactory.h | 30 +- src/core/include/_NumericRangeQuery.h | 144 +- src/core/include/_OrdFieldSource.h | 40 +- src/core/include/_ParallelReader.h | 144 +- src/core/include/_PayloadTermQuery.h | 103 +- src/core/include/_PhraseQuery.h | 56 +- src/core/include/_QueryWrapperFilter.h | 36 +- src/core/include/_ReverseOrdFieldSource.h | 44 +- src/core/include/_ScorerDocQueue.h | 36 +- src/core/include/_SegmentInfos.h | 114 +- src/core/include/_SegmentReader.h | 283 +- src/core/include/_Similarity.h | 44 +- src/core/include/_SimpleFSDirectory.h | 195 +- src/core/include/_SimpleFSLockFactory.h | 58 +- src/core/include/_SingleInstanceLockFactory.h | 60 +- src/core/include/_SnapshotDeletionPolicy.h | 62 +- src/core/include/_SortedVIntList.h | 48 +- src/core/include/_SpanFirstQuery.h | 46 +- src/core/include/_SpanNotQuery.h | 54 +- src/core/include/_SpanOrQuery.h | 81 +- src/core/include/_StandardAnalyzer.h | 20 +- src/core/include/_StopAnalyzer.h | 28 +- src/core/include/_TermQuery.h | 56 +- src/core/include/_TimeLimitingCollector.h | 48 +- src/core/include/_TopFieldCollector.h | 397 +- src/core/include/_TopScoreDocCollector.h | 57 +- src/core/include/_ValueSourceQuery.h | 95 +- src/core/index/AbstractAllTermDocs.cpp | 104 +- src/core/index/AllTermDocs.cpp | 28 +- src/core/index/BufferedDeletes.cpp | 175 +- src/core/index/ByteBlockPool.cpp | 181 +- src/core/index/ByteSliceReader.cpp | 228 +- src/core/index/ByteSliceWriter.cpp | 96 +- src/core/index/CharBlockPool.cpp | 58 +- src/core/index/CheckIndex.cpp | 1178 +- src/core/index/CompoundFileReader.cpp | 336 +- src/core/index/CompoundFileWriter.cpp | 285 +- src/core/index/ConcurrentMergeScheduler.cpp | 505 +- src/core/index/DefaultSkipListReader.cpp | 140 +- src/core/index/DefaultSkipListWriter.cpp | 176 +- src/core/index/DirectoryReader.cpp | 1938 +- src/core/index/DocConsumer.cpp | 10 +- src/core/index/DocConsumerPerThread.cpp | 10 +- src/core/index/DocFieldConsumer.cpp | 17 +- src/core/index/DocFieldConsumerPerField.cpp | 10 +- src/core/index/DocFieldConsumerPerThread.cpp | 10 +- src/core/index/DocFieldConsumers.cpp | 245 +- src/core/index/DocFieldConsumersPerField.cpp | 63 +- src/core/index/DocFieldConsumersPerThread.cpp | 110 +- src/core/index/DocFieldProcessor.cpp | 89 +- src/core/index/DocFieldProcessorPerField.cpp | 32 +- src/core/index/DocFieldProcessorPerThread.cpp | 494 +- src/core/index/DocInverter.cpp | 93 +- src/core/index/DocInverterPerField.cpp | 310 +- src/core/index/DocInverterPerThread.cpp | 117 +- src/core/index/DocumentsWriter.cpp | 2477 +- src/core/index/DocumentsWriterThreadState.cpp | 51 +- src/core/index/FieldInfo.cpp | 93 +- src/core/index/FieldInfos.cpp | 427 +- src/core/index/FieldInvertState.cpp | 84 +- .../index/FieldSortedTermVectorMapper.cpp | 67 +- src/core/index/FieldsReader.cpp | 840 +- src/core/index/FieldsWriter.cpp | 322 +- src/core/index/FilterIndexReader.cpp | 540 +- src/core/index/FormatPostingsDocsConsumer.cpp | 10 +- src/core/index/FormatPostingsDocsWriter.cpp | 152 +- .../index/FormatPostingsFieldsConsumer.cpp | 10 +- src/core/index/FormatPostingsFieldsWriter.cpp | 70 +- .../index/FormatPostingsPositionsConsumer.cpp | 10 +- .../index/FormatPostingsPositionsWriter.cpp | 110 +- .../index/FormatPostingsTermsConsumer.cpp | 31 +- src/core/index/FormatPostingsTermsWriter.cpp | 75 +- src/core/index/FreqProxFieldMergeState.cpp | 134 +- src/core/index/FreqProxTermsWriter.cpp | 399 +- .../index/FreqProxTermsWriterPerField.cpp | 222 +- .../index/FreqProxTermsWriterPerThread.cpp | 53 +- src/core/index/IndexCommit.cpp | 41 +- src/core/index/IndexDeletionPolicy.cpp | 15 +- src/core/index/IndexFileDeleter.cpp | 772 +- src/core/index/IndexFileNameFilter.cpp | 81 +- src/core/index/IndexFileNames.cpp | 431 +- src/core/index/IndexReader.cpp | 679 +- src/core/index/IndexWriter.cpp | 5674 ++-- src/core/index/IntBlockPool.cpp | 74 +- src/core/index/InvertedDocConsumer.cpp | 17 +- .../index/InvertedDocConsumerPerField.cpp | 10 +- .../index/InvertedDocConsumerPerThread.cpp | 10 +- src/core/index/InvertedDocEndConsumer.cpp | 10 +- .../index/InvertedDocEndConsumerPerField.cpp | 10 +- .../index/InvertedDocEndConsumerPerThread.cpp | 10 +- .../KeepOnlyLastCommitDeletionPolicy.cpp | 31 +- src/core/index/LogByteSizeMergePolicy.cpp | 78 +- src/core/index/LogDocMergePolicy.cpp | 58 +- src/core/index/LogMergePolicy.cpp | 633 +- src/core/index/MergeDocIDRemapper.cpp | 118 +- src/core/index/MergePolicy.cpp | 163 +- src/core/index/MergeScheduler.cpp | 10 +- src/core/index/MultiLevelSkipListReader.cpp | 341 +- src/core/index/MultiLevelSkipListWriter.cpp | 117 +- src/core/index/MultiReader.cpp | 547 +- src/core/index/MultipleTermPositions.cpp | 272 +- src/core/index/NormsWriter.cpp | 241 +- src/core/index/NormsWriterPerField.cpp | 83 +- src/core/index/NormsWriterPerThread.cpp | 60 +- src/core/index/ParallelReader.cpp | 906 +- src/core/index/Payload.cpp | 185 +- .../index/PositionBasedTermVectorMapper.cpp | 123 +- src/core/index/RawPostingList.cpp | 23 +- src/core/index/ReadOnlyDirectoryReader.cpp | 54 +- src/core/index/ReadOnlySegmentReader.cpp | 31 +- src/core/index/ReusableStringReader.cpp | 73 +- src/core/index/SegmentInfo.cpp | 932 +- src/core/index/SegmentInfoCollection.cpp | 113 +- src/core/index/SegmentInfos.cpp | 1140 +- src/core/index/SegmentMergeInfo.cpp | 106 +- src/core/index/SegmentMergeQueue.cpp | 32 +- src/core/index/SegmentMerger.cpp | 1130 +- src/core/index/SegmentReader.cpp | 2036 +- src/core/index/SegmentTermDocs.cpp | 346 +- src/core/index/SegmentTermEnum.cpp | 351 +- src/core/index/SegmentTermPositionVector.cpp | 71 +- src/core/index/SegmentTermPositions.cpp | 272 +- src/core/index/SegmentTermVector.cpp | 97 +- src/core/index/SegmentWriteState.cpp | 42 +- src/core/index/SerialMergeScheduler.cpp | 32 +- src/core/index/SnapshotDeletionPolicy.cpp | 177 +- src/core/index/SortedTermVectorMapper.cpp | 131 +- src/core/index/StoredFieldsWriter.cpp | 315 +- .../index/StoredFieldsWriterPerThread.cpp | 86 +- src/core/index/Term.cpp | 108 +- src/core/index/TermBuffer.cpp | 179 +- src/core/index/TermDocs.cpp | 98 +- src/core/index/TermEnum.cpp | 10 +- src/core/index/TermFreqVector.cpp | 83 +- src/core/index/TermInfo.cpp | 64 +- src/core/index/TermInfosReader.cpp | 359 +- src/core/index/TermInfosWriter.cpp | 252 +- src/core/index/TermPositionVector.cpp | 33 +- src/core/index/TermPositions.cpp | 61 +- src/core/index/TermVectorEntry.cpp | 122 +- .../TermVectorEntryFreqSortedComparator.cpp | 39 +- src/core/index/TermVectorMapper.cpp | 48 +- src/core/index/TermVectorOffsetInfo.cpp | 85 +- src/core/index/TermVectorsReader.cpp | 930 +- src/core/index/TermVectorsTermsWriter.cpp | 489 +- .../index/TermVectorsTermsWriterPerField.cpp | 372 +- .../index/TermVectorsTermsWriterPerThread.cpp | 89 +- src/core/index/TermVectorsWriter.cpp | 322 +- src/core/index/TermsHash.cpp | 311 +- src/core/index/TermsHashConsumer.cpp | 17 +- src/core/index/TermsHashConsumerPerField.cpp | 10 +- src/core/index/TermsHashConsumerPerThread.cpp | 10 +- src/core/index/TermsHashPerField.cpp | 775 +- src/core/index/TermsHashPerThread.cpp | 169 +- src/core/msvc/dllmain.cpp | 16 +- src/core/queryparser/FastCharStream.cpp | 169 +- .../queryparser/MultiFieldQueryParser.cpp | 233 +- src/core/queryparser/QueryParseError.cpp | 187 +- src/core/queryparser/QueryParser.cpp | 2526 +- .../queryparser/QueryParserCharStream.cpp | 113 +- src/core/queryparser/QueryParserConstants.cpp | 90 +- src/core/queryparser/QueryParserToken.cpp | 41 +- .../queryparser/QueryParserTokenManager.cpp | 2388 +- src/core/search/BooleanClause.cpp | 100 +- src/core/search/BooleanQuery.cpp | 615 +- src/core/search/BooleanScorer.cpp | 471 +- src/core/search/BooleanScorer2.cpp | 375 +- src/core/search/CachingSpanFilter.cpp | 118 +- src/core/search/CachingWrapperFilter.cpp | 236 +- src/core/search/Collector.cpp | 10 +- src/core/search/ComplexExplanation.cpp | 55 +- src/core/search/ConjunctionScorer.cpp | 172 +- src/core/search/ConstantScoreQuery.cpp | 242 +- src/core/search/DefaultSimilarity.cpp | 89 +- src/core/search/DisjunctionMaxQuery.cpp | 324 +- src/core/search/DisjunctionMaxScorer.cpp | 250 +- src/core/search/DisjunctionSumScorer.cpp | 208 +- src/core/search/DocIdSet.cpp | 78 +- src/core/search/DocIdSetIterator.cpp | 16 +- src/core/search/ExactPhraseScorer.cpp | 65 +- src/core/search/Explanation.cpp | 132 +- src/core/search/FieldCache.cpp | 497 +- src/core/search/FieldCacheImpl.cpp | 926 +- src/core/search/FieldCacheRangeFilter.cpp | 596 +- src/core/search/FieldCacheTermsFilter.cpp | 144 +- src/core/search/FieldComparator.cpp | 555 +- src/core/search/FieldComparatorSource.cpp | 10 +- src/core/search/FieldDoc.cpp | 38 +- src/core/search/FieldDocSortedHitQueue.cpp | 108 +- src/core/search/FieldValueHitQueue.cpp | 196 +- src/core/search/Filter.cpp | 10 +- src/core/search/FilterManager.cpp | 163 +- src/core/search/FilteredDocIdSet.cpp | 62 +- src/core/search/FilteredDocIdSetIterator.cpp | 69 +- src/core/search/FilteredQuery.cpp | 309 +- src/core/search/FilteredTermEnum.cpp | 99 +- src/core/search/FuzzyQuery.cpp | 327 +- src/core/search/FuzzyTermEnum.cpp | 243 +- src/core/search/HitQueue.cpp | 40 +- src/core/search/HitQueueBase.cpp | 143 +- src/core/search/IndexSearcher.cpp | 289 +- src/core/search/MatchAllDocsQuery.cpp | 203 +- src/core/search/MultiPhraseQuery.cpp | 466 +- src/core/search/MultiSearcher.cpp | 546 +- src/core/search/MultiTermQuery.cpp | 500 +- .../search/MultiTermQueryWrapperFilter.cpp | 160 +- src/core/search/NumericRangeFilter.cpp | 134 +- src/core/search/NumericRangeQuery.cpp | 584 +- src/core/search/ParallelMultiSearcher.cpp | 145 +- src/core/search/PhrasePositions.cpp | 92 +- src/core/search/PhraseQuery.cpp | 419 +- src/core/search/PhraseQueue.cpp | 40 +- src/core/search/PhraseScorer.cpp | 228 +- .../search/PositiveScoresOnlyCollector.cpp | 50 +- src/core/search/PrefixFilter.cpp | 33 +- src/core/search/PrefixQuery.cpp | 108 +- src/core/search/PrefixTermEnum.cpp | 56 +- src/core/search/Query.cpp | 250 +- src/core/search/QueryTermVector.cpp | 184 +- src/core/search/QueryWrapperFilter.cpp | 80 +- src/core/search/ReqExclScorer.cpp | 133 +- src/core/search/ReqOptSumScorer.cpp | 67 +- .../search/ScoreCachingWrappingScorer.cpp | 81 +- src/core/search/ScoreDoc.cpp | 30 +- src/core/search/Scorer.cpp | 54 +- src/core/search/Searchable.cpp | 104 +- src/core/search/Searcher.cpp | 92 +- src/core/search/Similarity.cpp | 166 +- src/core/search/SimilarityDelegator.cpp | 91 +- src/core/search/SingleTermEnum.cpp | 47 +- src/core/search/SloppyPhraseScorer.cpp | 267 +- src/core/search/Sort.cpp | 125 +- src/core/search/SortField.cpp | 417 +- src/core/search/SpanFilter.cpp | 10 +- src/core/search/SpanFilterResult.cpp | 120 +- src/core/search/SpanQueryFilter.cpp | 99 +- src/core/search/TermQuery.cpp | 295 +- src/core/search/TermRangeFilter.cpp | 77 +- src/core/search/TermRangeQuery.cpp | 234 +- src/core/search/TermRangeTermEnum.cpp | 130 +- src/core/search/TermScorer.cpp | 188 +- src/core/search/TimeLimitingCollector.cpp | 199 +- src/core/search/TopDocs.cpp | 54 +- src/core/search/TopDocsCollector.cpp | 124 +- src/core/search/TopFieldCollector.cpp | 1336 +- src/core/search/TopFieldDocs.cpp | 17 +- src/core/search/TopScoreDocCollector.cpp | 177 +- src/core/search/Weight.cpp | 17 +- src/core/search/WildcardQuery.cpp | 147 +- src/core/search/WildcardTermEnum.cpp | 205 +- src/core/search/function/ByteFieldSource.cpp | 105 +- .../search/function/CustomScoreProvider.cpp | 95 +- src/core/search/function/CustomScoreQuery.cpp | 534 +- src/core/search/function/DocValues.cpp | 131 +- .../search/function/DoubleFieldSource.cpp | 95 +- src/core/search/function/FieldCacheSource.cpp | 50 +- src/core/search/function/FieldScoreQuery.cpp | 41 +- src/core/search/function/IntFieldSource.cpp | 105 +- src/core/search/function/OrdFieldSource.cpp | 107 +- .../search/function/ReverseOrdFieldSource.cpp | 120 +- src/core/search/function/ValueSource.cpp | 17 +- src/core/search/function/ValueSourceQuery.cpp | 203 +- .../payloads/AveragePayloadFunction.cpp | 57 +- .../search/payloads/MaxPayloadFunction.cpp | 62 +- .../search/payloads/MinPayloadFunction.cpp | 62 +- src/core/search/payloads/PayloadFunction.cpp | 15 +- src/core/search/payloads/PayloadNearQuery.cpp | 273 +- src/core/search/payloads/PayloadSpanUtil.cpp | 222 +- src/core/search/payloads/PayloadTermQuery.cpp | 254 +- .../search/spans/FieldMaskingSpanQuery.cpp | 146 +- src/core/search/spans/NearSpansOrdered.cpp | 436 +- src/core/search/spans/NearSpansUnordered.cpp | 465 +- src/core/search/spans/SpanFirstQuery.cpp | 218 +- src/core/search/spans/SpanNearQuery.cpp | 219 +- src/core/search/spans/SpanNotQuery.cpp | 287 +- src/core/search/spans/SpanOrQuery.cpp | 376 +- src/core/search/spans/SpanQuery.cpp | 17 +- src/core/search/spans/SpanScorer.cpp | 131 +- src/core/search/spans/SpanTermQuery.cpp | 126 +- src/core/search/spans/SpanWeight.cpp | 155 +- src/core/search/spans/Spans.cpp | 10 +- src/core/search/spans/TermSpans.cpp | 142 +- src/core/store/BufferedIndexInput.cpp | 285 +- src/core/store/BufferedIndexOutput.cpp | 149 +- src/core/store/ChecksumIndexInput.cpp | 87 +- src/core/store/ChecksumIndexOutput.cpp | 129 +- src/core/store/Directory.cpp | 189 +- src/core/store/FSDirectory.cpp | 343 +- src/core/store/FSLockFactory.cpp | 32 +- src/core/store/FileSwitchDirectory.cpp | 153 +- src/core/store/IndexInput.cpp | 218 +- src/core/store/IndexOutput.cpp | 166 +- src/core/store/Lock.cpp | 41 +- src/core/store/LockFactory.cpp | 24 +- src/core/store/MMapDirectory.cpp | 156 +- src/core/store/NativeFSLockFactory.cpp | 323 +- src/core/store/NoLockFactory.cpp | 87 +- src/core/store/RAMDirectory.cpp | 227 +- src/core/store/RAMFile.cpp | 132 +- src/core/store/RAMInputStream.cpp | 187 +- src/core/store/RAMOutputStream.cpp | 218 +- src/core/store/SimpleFSDirectory.cpp | 373 +- src/core/store/SimpleFSLockFactory.cpp | 112 +- src/core/store/SingleInstanceLockFactory.cpp | 85 +- src/core/util/Attribute.cpp | 31 +- src/core/util/AttributeSource.cpp | 376 +- src/core/util/Base64.cpp | 175 +- src/core/util/BitSet.cpp | 400 +- src/core/util/BitUtil.cpp | 854 +- src/core/util/BitVector.cpp | 397 +- src/core/util/BufferedReader.cpp | 179 +- src/core/util/CharFolder.cpp | 54 +- src/core/util/Collator.cpp | 22 +- src/core/util/Constants.cpp | 74 +- src/core/util/CycleCheck.cpp | 91 +- src/core/util/DocIdBitSet.cpp | 118 +- src/core/util/FieldCacheSanityChecker.cpp | 389 +- src/core/util/FileReader.cpp | 98 +- src/core/util/FileUtils.cpp | 335 +- src/core/util/InfoStream.cpp | 76 +- src/core/util/InputStreamReader.cpp | 68 +- src/core/util/LuceneAllocator.cpp | 65 +- src/core/util/LuceneException.cpp | 162 +- src/core/util/LuceneObject.cpp | 60 +- src/core/util/LuceneSignal.cpp | 56 +- src/core/util/LuceneSync.cpp | 77 +- src/core/util/LuceneThread.cpp | 175 +- src/core/util/MiscUtils.cpp | 210 +- src/core/util/NumericUtils.cpp | 407 +- src/core/util/OpenBitSet.cpp | 929 +- src/core/util/OpenBitSetDISI.cpp | 79 +- src/core/util/OpenBitSetIterator.cpp | 254 +- src/core/util/Random.cpp | 71 +- src/core/util/Reader.cpp | 77 +- src/core/util/ReaderUtil.cpp | 75 +- src/core/util/ScorerDocQueue.cpp | 256 +- src/core/util/SmallDouble.cpp | 69 +- src/core/util/SortedVIntList.cpp | 269 +- src/core/util/StringReader.cpp | 70 +- src/core/util/StringUtils.cpp | 302 +- src/core/util/Synchronize.cpp | 101 +- src/core/util/TestPoint.cpp | 82 +- src/core/util/ThreadPool.cpp | 47 +- src/core/util/UTF8Stream.cpp | 659 +- src/core/util/UnicodeUtils.cpp | 114 +- src/core/util/md5/md5.h | 24 +- src/core/util/unicode/gunichartables.h | 26128 ++++++++-------- src/core/util/unicode/guniprop.cpp | 480 +- src/core/util/unicode/guniprop.h | 310 +- src/demo/deletefiles/main.cpp | 13 +- src/demo/indexfiles/main.cpp | 46 +- src/demo/searchfiles/main.cpp | 195 +- src/test/analysis/AnalyzersTest.cpp | 83 +- src/test/analysis/BaseTokenStreamFixture.cpp | 344 +- src/test/analysis/CachingTokenFilterTest.cpp | 69 +- src/test/analysis/CharFilterTest.cpp | 36 +- src/test/analysis/KeywordAnalyzerTest.cpp | 18 +- src/test/analysis/LengthFilterTest.cpp | 3 +- src/test/analysis/MappingCharFilterTest.cpp | 45 +- src/test/analysis/NumericTokenStreamTest.cpp | 29 +- .../analysis/PerFieldAnalzyerWrapperTest.cpp | 3 +- src/test/analysis/StopAnalyzerTest.cpp | 30 +- src/test/analysis/StopFilterTest.cpp | 29 +- src/test/analysis/TeeSinkTokenFilterTest.cpp | 167 +- src/test/analysis/TokenTest.cpp | 39 +- .../standard/StandardAnalyzerTest.cpp | 71 +- .../tokenattributes/SimpleAttributeTest.cpp | 44 +- .../tokenattributes/TermAttributeTest.cpp | 36 +- .../common/analysis/ar/ArabicAnalyzerTest.cpp | 42 +- .../ar/ArabicNormalizationFilterTest.cpp | 51 +- .../analysis/ar/ArabicStemFilterTest.cpp | 72 +- .../analysis/br/BrazilianStemmerTest.cpp | 27 +- .../common/analysis/cjk/CJKTokenizerTest.cpp | 277 +- .../analysis/cn/ChineseTokenizerTest.cpp | 75 +- .../common/analysis/cz/CzechAnalyzerTest.cpp | 12 +- .../analysis/de/GermanStemFilterTest.cpp | 21 +- .../common/analysis/el/GreekAnalyzerTest.cpp | 108 +- .../analysis/fa/PersianAnalyzerTest.cpp | 351 +- .../fa/PersianNormalizationFilterTest.cpp | 27 +- .../common/analysis/fr/ElisionTest.cpp | 15 +- .../common/analysis/fr/FrenchAnalyzerTest.cpp | 9 +- .../common/analysis/nl/DutchStemmerTest.cpp | 21 +- .../reverse/ReverseStringFilterTest.cpp | 6 +- .../analysis/ru/RussianAnalyzerTest.cpp | 48 +- .../common/analysis/ru/RussianStemTest.cpp | 21 +- .../contrib/highlighter/HighlighterTest.cpp | 2459 +- src/test/contrib/memory/MemoryIndexTest.cpp | 98 +- src/test/contrib/snowball/SnowballTest.cpp | 9 +- src/test/document/BinaryDocumentTest.cpp | 13 +- src/test/document/DateFieldTest.cpp | 15 +- src/test/document/DateToolsTest.cpp | 44 +- src/test/document/DocumentTest.cpp | 73 +- src/test/document/NumberToolsTest.cpp | 29 +- src/test/include/BaseTestRangeFilterFixture.h | 84 +- src/test/include/BaseTokenStreamFixture.h | 124 +- src/test/include/CheckHits.h | 88 +- src/test/include/DocHelper.h | 198 +- src/test/include/ExplanationsFixture.h | 91 +- src/test/include/FunctionFixture.h | 53 +- src/test/include/LuceneGlobalFixture.h | 20 +- src/test/include/LuceneTestFixture.h | 20 +- src/test/include/MockFSDirectory.h | 64 +- src/test/include/MockFilter.h | 30 +- src/test/include/MockIndexInput.h | 46 +- src/test/include/MockLock.h | 38 +- src/test/include/MockLockFactory.h | 40 +- src/test/include/MockRAMDirectory.h | 171 +- src/test/include/MockRAMInputStream.h | 46 +- src/test/include/MockRAMOutputStream.h | 54 +- src/test/include/PayloadHelper.h | 42 +- src/test/include/QueryUtils.h | 102 +- src/test/include/TestUtils.h | 42 +- src/test/include/test_lucene.h | 56 +- src/test/index/AddIndexesNoOptimizeTest.cpp | 97 +- src/test/index/AtomicUpdateTest.cpp | 82 +- src/test/index/BackwardsCompatibilityTest.cpp | 193 +- src/test/index/ByteSlicesTest.cpp | 73 +- src/test/index/CheckIndexTest.cpp | 6 +- src/test/index/CompoundFileTest.cpp | 158 +- .../index/ConcurrentMergeSchedulerTest.cpp | 256 +- src/test/index/CrashTest.cpp | 33 +- src/test/index/DeletionPolicyTest.cpp | 262 +- src/test/index/DirectoryReaderTest.cpp | 67 +- src/test/index/DocHelper.cpp | 424 +- src/test/index/DocTest.cpp | 37 +- src/test/index/DocumentWriterTest.cpp | 269 +- src/test/index/FieldInfosTest.cpp | 9 +- src/test/index/FieldsReaderTest.cpp | 180 +- src/test/index/FilterIndexReaderTest.cpp | 63 +- src/test/index/IndexCommitTest.cpp | 157 +- src/test/index/IndexFileDeleterTest.cpp | 45 +- src/test/index/IndexInputTest.cpp | 77 +- src/test/index/IndexReaderCloneNormsTest.cpp | 108 +- src/test/index/IndexReaderCloneTest.cpp | 223 +- src/test/index/IndexReaderReopenTest.cpp | 1271 +- src/test/index/IndexReaderTest.cpp | 448 +- src/test/index/IndexWriterDeleteTest.cpp | 243 +- src/test/index/IndexWriterExceptionsTest.cpp | 108 +- src/test/index/IndexWriterLockReleaseTest.cpp | 17 +- src/test/index/IndexWriterMergePolicyTest.cpp | 80 +- src/test/index/IndexWriterMergingTest.cpp | 18 +- src/test/index/IndexWriterReaderTest.cpp | 461 +- src/test/index/IndexWriterTest.cpp | 2699 +- src/test/index/LazyBugTest.cpp | 85 +- src/test/index/LazyProxSkippingTest.cpp | 89 +- src/test/index/MockIndexInput.cpp | 70 +- src/test/index/MultiLevelSkipListTest.cpp | 72 +- src/test/index/MultiReaderTest.cpp | 67 +- src/test/index/NRTReaderWithThreadsTest.cpp | 74 +- src/test/index/NormsTest.cpp | 69 +- src/test/index/OmitTfTest.cpp | 238 +- .../index/ParallelReaderEmptyIndexTest.cpp | 6 +- src/test/index/ParallelReaderTest.cpp | 58 +- src/test/index/ParallelTermEnumTest.cpp | 12 +- src/test/index/PayloadsTest.cpp | 380 +- .../PositionBasedTermVectorMapperTest.cpp | 27 +- src/test/index/SegmentMergerTest.cpp | 30 +- src/test/index/SegmentReaderTest.cpp | 57 +- src/test/index/SegmentTermDocsTest.cpp | 45 +- src/test/index/SegmentTermEnumTest.cpp | 15 +- src/test/index/SnapshotDeletionPolicyTest.cpp | 104 +- src/test/index/StressIndexingTest.cpp | 529 +- src/test/index/TermDocsPerfTest.cpp | 47 +- src/test/index/TermTest.cpp | 3 +- src/test/index/TermVectorsReaderTest.cpp | 189 +- src/test/index/ThreadedOptimizeTest.cpp | 61 +- src/test/index/TransactionRollbackTest.cpp | 99 +- src/test/index/TransactionsTest.cpp | 109 +- src/test/index/WordlistLoaderTest.cpp | 9 +- src/test/main/main.cpp | 24 +- src/test/queryparser/MultiAnalyzerTest.cpp | 110 +- .../queryparser/MultiFieldQueryParserTest.cpp | 122 +- src/test/queryparser/QueryParserTest.cpp | 313 +- .../search/BaseTestRangeFilterFixture.cpp | 108 +- src/test/search/BaseTestRangeFilterTest.cpp | 6 +- src/test/search/Boolean2Test.cpp | 118 +- src/test/search/BooleanMinShouldMatchTest.cpp | 131 +- src/test/search/BooleanOrTest.cpp | 27 +- src/test/search/BooleanPrefixQueryTest.cpp | 21 +- src/test/search/BooleanQueryTest.cpp | 16 +- src/test/search/BooleanScorerTest.cpp | 83 +- src/test/search/CachingSpanFilterTest.cpp | 9 +- src/test/search/CachingWrapperFilterTest.cpp | 138 +- src/test/search/CheckHits.cpp | 430 +- .../ComplexExplanationsOfNonMatchesTest.cpp | 105 +- src/test/search/ComplexExplanationsTest.cpp | 102 +- src/test/search/CustomSearcherSortTest.cpp | 69 +- src/test/search/DateFilterTest.cpp | 14 +- src/test/search/DateSortTest.cpp | 18 +- src/test/search/DisjunctionMaxQueryTest.cpp | 80 +- src/test/search/DocBoostTest.cpp | 82 +- src/test/search/DocIdSetTest.cpp | 139 +- src/test/search/ElevationComparatorTest.cpp | 82 +- src/test/search/ExplanationsFixture.cpp | 216 +- src/test/search/FieldCacheRangeFilterTest.cpp | 21 +- src/test/search/FieldCacheTermsFilterTest.cpp | 6 +- src/test/search/FieldCacheTest.cpp | 27 +- src/test/search/FilteredQueryTest.cpp | 63 +- src/test/search/FilteredSearchTest.cpp | 33 +- src/test/search/FuzzyQueryTest.cpp | 35 +- src/test/search/MatchAllDocsQueryTest.cpp | 9 +- src/test/search/MockFilter.cpp | 48 +- src/test/search/MultiPhraseQueryTest.cpp | 43 +- src/test/search/MultiSearcherRankingTest.cpp | 45 +- src/test/search/MultiSearcherTest.cpp | 112 +- .../search/MultiTermConstantScoreTest.cpp | 144 +- .../search/MultiThreadTermVectorsTest.cpp | 74 +- .../MultiValuedNumericRangeQueryTest.cpp | 24 +- src/test/search/NotTest.cpp | 3 +- src/test/search/NumericRangeQuery32Test.cpp | 195 +- src/test/search/NumericRangeQuery64Test.cpp | 209 +- src/test/search/ParallelMultiSearcherTest.cpp | 112 +- src/test/search/PhrasePrefixQueryTest.cpp | 12 +- src/test/search/PhraseQueryTest.cpp | 66 +- src/test/search/PositionIncrementTest.cpp | 268 +- .../PositiveScoresOnlyCollectorTest.cpp | 79 +- src/test/search/PrefixFilterTest.cpp | 16 +- src/test/search/PrefixInBooleanQueryTest.cpp | 27 +- src/test/search/PrefixQueryTest.cpp | 14 +- src/test/search/QueryTermVectorTest.cpp | 9 +- src/test/search/QueryUtils.cpp | 669 +- src/test/search/QueryWrapperFilterTest.cpp | 3 +- .../search/ScoreCachingWrappingScorerTest.cpp | 169 +- src/test/search/ScorerPerfTest.cpp | 110 +- src/test/search/SearchForDuplicatesTest.cpp | 27 +- src/test/search/SearchTest.cpp | 45 +- src/test/search/SetNormTest.cpp | 82 +- src/test/search/SimilarityTest.cpp | 311 +- .../SimpleExplanationsOfNonMatchesTest.cpp | 192 +- src/test/search/SimpleExplanationsTest.cpp | 189 +- src/test/search/SloppyPhraseQueryTest.cpp | 54 +- src/test/search/SortTest.cpp | 517 +- src/test/search/SpanQueryFilterTest.cpp | 18 +- src/test/search/TermRangeFilterTest.cpp | 18 +- src/test/search/TermRangeQueryTest.cpp | 91 +- src/test/search/TermScorerTest.cpp | 105 +- src/test/search/TermVectorsTest.cpp | 120 +- src/test/search/ThreadSafeTest.cpp | 97 +- src/test/search/TimeLimitingCollectorTest.cpp | 202 +- src/test/search/TopDocsCollectorTest.cpp | 77 +- src/test/search/TopScoreDocCollectorTest.cpp | 12 +- src/test/search/WildcardTest.cpp | 73 +- .../search/function/CustomScoreQueryTest.cpp | 138 +- src/test/search/function/DocValuesTest.cpp | 27 +- .../search/function/FieldScoreQueryTest.cpp | 87 +- src/test/search/function/FunctionFixture.cpp | 207 +- src/test/search/function/OrdValuesTest.cpp | 127 +- src/test/search/payloads/PayloadHelper.cpp | 198 +- .../search/payloads/PayloadNearQueryTest.cpp | 122 +- .../search/payloads/PayloadTermQueryTest.cpp | 136 +- src/test/search/spans/BasicSpansTest.cpp | 111 +- .../spans/FieldMaskingSpanQueryTest.cpp | 186 +- .../search/spans/NearSpansOrderedTest.cpp | 62 +- src/test/search/spans/PayloadSpansTest.cpp | 223 +- .../search/spans/SpanExplanationsTest.cpp | 90 +- src/test/search/spans/SpansAdvanced2Test.cpp | 33 +- src/test/search/spans/SpansAdvancedTest.cpp | 24 +- src/test/search/spans/SpansTest.cpp | 189 +- src/test/store/BufferedIndexInputTest.cpp | 204 +- src/test/store/BufferedIndexOutputTest.cpp | 96 +- src/test/store/DirectoryTest.cpp | 126 +- src/test/store/FileSwitchDirectoryTest.cpp | 27 +- src/test/store/IndexOutputTest.cpp | 142 +- src/test/store/LockFactoryTest.cpp | 298 +- src/test/store/MMapDirectoryTest.cpp | 18 +- src/test/store/MockFSDirectory.cpp | 115 +- src/test/store/MockLock.cpp | 57 +- src/test/store/MockLockFactory.cpp | 58 +- src/test/store/MockRAMDirectory.cpp | 479 +- src/test/store/MockRAMInputStream.cpp | 77 +- src/test/store/MockRAMOutputStream.cpp | 122 +- src/test/store/RAMDirectoryTest.cpp | 91 +- src/test/util/AttributeSourceTest.cpp | 19 +- src/test/util/Base64Test.cpp | 12 +- src/test/util/BitVectorTest.cpp | 94 +- src/test/util/BufferedReaderTest.cpp | 30 +- src/test/util/CloseableThreadLocalTest.cpp | 18 +- src/test/util/CompressionToolsTest.cpp | 3 +- src/test/util/FieldCacheSanityCheckerTest.cpp | 26 +- src/test/util/FileReaderTest.cpp | 9 +- src/test/util/FileUtilsTest.cpp | 81 +- src/test/util/InputStreamReaderTest.cpp | 27 +- src/test/util/LuceneGlobalFixture.cpp | 25 +- src/test/util/LuceneTestFixture.cpp | 30 +- src/test/util/NumericUtilsTest.cpp | 390 +- src/test/util/OpenBitSetTest.cpp | 74 +- src/test/util/PriorityQueueTest.cpp | 39 +- src/test/util/SimpleLRUCacheTest.cpp | 45 +- src/test/util/SortedVIntListTest.cpp | 133 +- src/test/util/StringReaderTest.cpp | 12 +- src/test/util/StringUtilsTest.cpp | 63 +- src/test/util/TestUtils.cpp | 310 +- src/test/util/VersionTest.cpp | 6 +- 1231 files changed, 106214 insertions(+), 117745 deletions(-) diff --git a/.gitignore b/.gitignore index a9865f41..4c59cff6 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ *.manifest *.user *.bak +*.orig *.lock* *.waf* .DS_Store diff --git a/include/ASCIIFoldingFilter.h b/include/ASCIIFoldingFilter.h index b8087c0d..68597772 100644 --- a/include/ASCIIFoldingFilter.h +++ b/include/ASCIIFoldingFilter.h @@ -9,58 +9,58 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// This class converts alphabetic, numeric, and symbolic Unicode characters which are not in the first 127 ASCII - /// characters (the "Basic Latin" Unicode block) into their ASCII equivalents, if one exists. - /// - /// Characters from the following Unicode blocks are converted; however, only those characters with reasonable ASCII - /// alternatives are converted: - /// - /// C1 Controls and Latin-1 Supplement: http://www.unicode.org/charts/PDF/U0080.pdf - /// Latin Extended-A: http://www.unicode.org/charts/PDF/U0100.pdf - /// Latin Extended-B: http://www.unicode.org/charts/PDF/U0180.pdf - /// Latin Extended Additional: http://www.unicode.org/charts/PDF/U1E00.pdf - /// Latin Extended-C: http://www.unicode.org/charts/PDF/U2C60.pdf - /// Latin Extended-D: http://www.unicode.org/charts/PDF/UA720.pdf - /// IPA Extensions: http://www.unicode.org/charts/PDF/U0250.pdf - /// Phonetic Extensions: http://www.unicode.org/charts/PDF/U1D00.pdf - /// Phonetic Extensions Supplement: http://www.unicode.org/charts/PDF/U1D80.pdf - /// General Punctuation: http://www.unicode.org/charts/PDF/U2000.pdf - /// Superscripts and Subscripts: http://www.unicode.org/charts/PDF/U2070.pdf - /// Enclosed Alphanumerics: http://www.unicode.org/charts/PDF/U2460.pdf - /// Dingbats: http://www.unicode.org/charts/PDF/U2700.pdf - /// Supplemental Punctuation: http://www.unicode.org/charts/PDF/U2E00.pdf - /// Alphabetic Presentation Forms: http://www.unicode.org/charts/PDF/UFB00.pdf - /// Halfwidth and Fullwidth Forms: http://www.unicode.org/charts/PDF/UFF00.pdf - /// - /// See: http://en.wikipedia.org/wiki/Latin_characters_in_Unicode - /// - /// The set of character conversions supported by this class is a superset of those supported by Lucene's {@link - /// ISOLatin1AccentFilter} which strips accents from Latin1 characters. For example, 'à' will be replaced by 'a'. - /// - class LPPAPI ASCIIFoldingFilter : public TokenFilter - { - public: - ASCIIFoldingFilter(const TokenStreamPtr& input); - virtual ~ASCIIFoldingFilter(); +namespace Lucene { - LUCENE_CLASS(ASCIIFoldingFilter); +/// This class converts alphabetic, numeric, and symbolic Unicode characters which are not in the first 127 ASCII +/// characters (the "Basic Latin" Unicode block) into their ASCII equivalents, if one exists. +/// +/// Characters from the following Unicode blocks are converted; however, only those characters with reasonable ASCII +/// alternatives are converted: +/// +/// C1 Controls and Latin-1 Supplement: http://www.unicode.org/charts/PDF/U0080.pdf +/// Latin Extended-A: http://www.unicode.org/charts/PDF/U0100.pdf +/// Latin Extended-B: http://www.unicode.org/charts/PDF/U0180.pdf +/// Latin Extended Additional: http://www.unicode.org/charts/PDF/U1E00.pdf +/// Latin Extended-C: http://www.unicode.org/charts/PDF/U2C60.pdf +/// Latin Extended-D: http://www.unicode.org/charts/PDF/UA720.pdf +/// IPA Extensions: http://www.unicode.org/charts/PDF/U0250.pdf +/// Phonetic Extensions: http://www.unicode.org/charts/PDF/U1D00.pdf +/// Phonetic Extensions Supplement: http://www.unicode.org/charts/PDF/U1D80.pdf +/// General Punctuation: http://www.unicode.org/charts/PDF/U2000.pdf +/// Superscripts and Subscripts: http://www.unicode.org/charts/PDF/U2070.pdf +/// Enclosed Alphanumerics: http://www.unicode.org/charts/PDF/U2460.pdf +/// Dingbats: http://www.unicode.org/charts/PDF/U2700.pdf +/// Supplemental Punctuation: http://www.unicode.org/charts/PDF/U2E00.pdf +/// Alphabetic Presentation Forms: http://www.unicode.org/charts/PDF/UFB00.pdf +/// Halfwidth and Fullwidth Forms: http://www.unicode.org/charts/PDF/UFF00.pdf +/// +/// See: http://en.wikipedia.org/wiki/Latin_characters_in_Unicode +/// +/// The set of character conversions supported by this class is a superset of those supported by Lucene's {@link +/// ISOLatin1AccentFilter} which strips accents from Latin1 characters. For example, 'à' will be replaced by 'a'. +/// +class LPPAPI ASCIIFoldingFilter : public TokenFilter { +public: + ASCIIFoldingFilter(const TokenStreamPtr& input); + virtual ~ASCIIFoldingFilter(); - protected: - CharArray output; - int32_t outputPos; - TermAttributePtr termAtt; + LUCENE_CLASS(ASCIIFoldingFilter); - public: - virtual bool incrementToken(); +protected: + CharArray output; + int32_t outputPos; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); + + /// Converts characters above ASCII to their ASCII equivalents. For example, accents are removed from + /// accented characters. + /// @param input The string to fold + /// @param length The number of characters in the input string + void foldToASCII(const wchar_t* input, int32_t length); +}; - /// Converts characters above ASCII to their ASCII equivalents. For example, accents are removed from - /// accented characters. - /// @param input The string to fold - /// @param length The number of characters in the input string - void foldToASCII(const wchar_t* input, int32_t length); - }; } #endif diff --git a/include/AbstractAllTermDocs.h b/include/AbstractAllTermDocs.h index b199c4e2..f6100403 100644 --- a/include/AbstractAllTermDocs.h +++ b/include/AbstractAllTermDocs.h @@ -9,35 +9,35 @@ #include "TermDocs.h" -namespace Lucene -{ - /// Base class for enumerating all but deleted docs. - /// - /// NOTE: this class is meant only to be used internally by Lucene; it's only public so it - /// can be shared across packages. - class LPPAPI AbstractAllTermDocs : public TermDocs, public LuceneObject - { - public: - AbstractAllTermDocs(int32_t maxDoc); - virtual ~AbstractAllTermDocs(); - - LUCENE_CLASS(AbstractAllTermDocs); - - protected: - int32_t maxDoc; - int32_t _doc; - - public: - virtual void seek(const TermPtr& term); - virtual void seek(const TermEnumPtr& termEnum); - virtual int32_t doc(); - virtual int32_t freq(); - virtual bool next(); - virtual int32_t read(Collection docs, Collection freqs); - virtual bool skipTo(int32_t target); - virtual void close(); - virtual bool isDeleted(int32_t doc) = 0; - }; +namespace Lucene { + +/// Base class for enumerating all but deleted docs. +/// +/// NOTE: this class is meant only to be used internally by Lucene; it's only public so it +/// can be shared across packages. +class LPPAPI AbstractAllTermDocs : public TermDocs, public LuceneObject { +public: + AbstractAllTermDocs(int32_t maxDoc); + virtual ~AbstractAllTermDocs(); + + LUCENE_CLASS(AbstractAllTermDocs); + +protected: + int32_t maxDoc; + int32_t _doc; + +public: + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); + virtual int32_t doc(); + virtual int32_t freq(); + virtual bool next(); + virtual int32_t read(Collection docs, Collection freqs); + virtual bool skipTo(int32_t target); + virtual void close(); + virtual bool isDeleted(int32_t doc) = 0; +}; + } #endif diff --git a/include/AbstractField.h b/include/AbstractField.h index 35097596..b719c630 100644 --- a/include/AbstractField.h +++ b/include/AbstractField.h @@ -9,216 +9,213 @@ #include "Fieldable.h" -namespace Lucene -{ - class LPPAPI AbstractField : public Fieldable, public LuceneObject - { - public: - /// Specifies whether and how a field should be stored. - enum Store - { - /// Store the original field value in the index. This is useful for short texts like a document's title - /// which should be displayed with the results. The value is stored in its original form, ie. no analyzer - /// is used before it is stored. - STORE_YES, - - /// Do not store the field value in the index. - STORE_NO - }; - - /// Specifies whether and how a field should be indexed. - enum Index - { - /// Do not index the field value. This field can thus not be searched, but one can still access its - /// contents provided it is {@link Field.Store stored}. - INDEX_NO, - - /// Index the tokens produced by running the field's value through an Analyzer. This is useful for - /// common text. - INDEX_ANALYZED, - - /// Index the field's value without using an Analyzer, so it can be searched. As no analyzer is used - /// the value will be stored as a single term. This is useful for unique Ids like product numbers. - INDEX_NOT_ANALYZED, - - /// Index the field's value without an Analyzer, and also disable the storing of norms. Note that you - /// can also separately enable/disable norms by calling {@link Field#setOmitNorms}. No norms means - /// that index-time field and document boosting and field length normalization are disabled. The benefit - /// is less memory usage as norms take up one byte of RAM per indexed field for every document in the - /// index, during searching. Note that once you index a given field with norms enabled, disabling norms - /// will have no effect. In other words, for this to have the above described effect on a field, all - /// instances of that field must be indexed with NOT_ANALYZED_NO_NORMS from the beginning. - INDEX_NOT_ANALYZED_NO_NORMS, - - /// Index the tokens produced by running the field's value through an Analyzer, and also separately - /// disable the storing of norms. See {@link #NOT_ANALYZED_NO_NORMS} for what norms are and why you - /// may want to disable them. - INDEX_ANALYZED_NO_NORMS - }; - - /// Specifies whether and how a field should have term vectors. - enum TermVector - { - /// Do not store term vectors. - TERM_VECTOR_NO, - - /// Store the term vectors of each document. A term vector is a list of the document's terms and their - /// number of occurrences in that document. - TERM_VECTOR_YES, - - /// Store the term vector + token position information - /// @see #YES - TERM_VECTOR_WITH_POSITIONS, - - /// Store the term vector + token offset information - /// @see #YES - TERM_VECTOR_WITH_OFFSETS, - - /// Store the term vector + token position and offset information - /// @see #YES - /// @see #WITH_POSITIONS - /// @see #WITH_OFFSETS - TERM_VECTOR_WITH_POSITIONS_OFFSETS - }; - - public: - virtual ~AbstractField(); - - LUCENE_CLASS(AbstractField); - - protected: - AbstractField(); - AbstractField(const String& name, Store store, Index index, TermVector termVector); - - String _name; - bool storeTermVector; - bool storeOffsetWithTermVector; - bool storePositionWithTermVector; - bool _omitNorms; - bool _isStored; - bool _isIndexed; - bool _isTokenized; - bool _isBinary; - bool lazy; - bool omitTermFreqAndPositions; - double boost; - - // the data object for all different kind of field values - FieldsData fieldsData; - - // pre-analyzed tokenStream for indexed fields - TokenStreamPtr tokenStream; - - // length/offset for all primitive types - int32_t binaryLength; - int32_t binaryOffset; - - public: - /// Sets the boost factor hits on this field. This value will be multiplied into the score of all - /// hits on this this field of this document. - /// - /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. - /// If a document has multiple fields with the same name, all such values are multiplied together. - /// This product is then used to compute the norm factor for the field. By default, in the {@link - /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the - /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} - /// before it is stored in the index. One should attempt to ensure that this product does not overflow - /// the range of that encoding. - /// - /// @see Document#setBoost(double) - /// @see Similarity#computeNorm(String, FieldInvertState) - /// @see Similarity#encodeNorm(double) - virtual void setBoost(double boost); - - /// Returns the boost factor for hits for this field. - /// - /// The default value is 1.0. - /// - /// Note: this value is not stored directly with the document in the index. Documents returned from - /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value - /// present as when this field was indexed. - virtual double getBoost(); - - /// Returns the name of the field as an interned string. For example "date", "title", "body", ... - virtual String name(); - - /// True if the value of the field is to be stored in the index for return with search hits. It is an - /// error for this to be true if a field is Reader-valued. - virtual bool isStored(); - - /// True if the value of the field is to be indexed, so that it may be searched on. - virtual bool isIndexed(); - - /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields - /// are indexed as a single word and may not be Reader-valued. - virtual bool isTokenized(); - - /// True if the term or terms used to index this field are stored as a term vector, available from - /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the - /// original content of the field, only to terms used to index it. If the original content must be - /// preserved, use the stored attribute instead. - virtual bool isTermVectorStored(); - - /// True if terms are stored as term vector together with their offsets (start and end position in - /// source text). - virtual bool isStoreOffsetWithTermVector(); - - /// True if terms are stored as term vector together with their token positions. - virtual bool isStorePositionWithTermVector(); - - /// True if the value of the field is stored as binary. - virtual bool isBinary(); - - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} - /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. - /// @return reference to the Field value as byte[]. - virtual ByteArray getBinaryValue(); - - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} - /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. - /// @return reference to the Field value as byte[]. - virtual ByteArray getBinaryValue(ByteArray result); - - /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is - /// undefined. - /// @return length of byte[] segment that represents this Field value. - virtual int32_t getBinaryLength(); - - /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is - /// undefined. - /// @return index of the first character in byte[] segment that represents this Field value. - virtual int32_t getBinaryOffset(); - - /// True if norms are omitted for this indexed field. - virtual bool getOmitNorms(); - - /// @see #setOmitTermFreqAndPositions - virtual bool getOmitTermFreqAndPositions(); - - /// If set, omit normalization factors associated with this indexed field. - /// This effectively disables indexing boosts and length normalization for this field. - virtual void setOmitNorms(bool omitNorms); - - /// If set, omit term freq, positions and payloads from postings for this field. - /// - /// NOTE: While this option reduces storage space required in the index, it also means any query requiring - /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail - /// to find results. - virtual void setOmitTermFreqAndPositions(bool omitTermFreqAndPositions); - - /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field - /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} - /// is only valid as long as the {@link IndexReader} that retrieved the {@link Document} is still open. - /// - /// @return true if this field can be loaded lazily - virtual bool isLazy(); - - /// Prints a Field for human consumption. - virtual String toString(); - - protected: - void setStoreTermVector(TermVector termVector); +namespace Lucene { + +class LPPAPI AbstractField : public Fieldable, public LuceneObject { +public: + /// Specifies whether and how a field should be stored. + enum Store { + /// Store the original field value in the index. This is useful for short texts like a document's title + /// which should be displayed with the results. The value is stored in its original form, ie. no analyzer + /// is used before it is stored. + STORE_YES, + + /// Do not store the field value in the index. + STORE_NO }; + + /// Specifies whether and how a field should be indexed. + enum Index { + /// Do not index the field value. This field can thus not be searched, but one can still access its + /// contents provided it is {@link Field.Store stored}. + INDEX_NO, + + /// Index the tokens produced by running the field's value through an Analyzer. This is useful for + /// common text. + INDEX_ANALYZED, + + /// Index the field's value without using an Analyzer, so it can be searched. As no analyzer is used + /// the value will be stored as a single term. This is useful for unique Ids like product numbers. + INDEX_NOT_ANALYZED, + + /// Index the field's value without an Analyzer, and also disable the storing of norms. Note that you + /// can also separately enable/disable norms by calling {@link Field#setOmitNorms}. No norms means + /// that index-time field and document boosting and field length normalization are disabled. The benefit + /// is less memory usage as norms take up one byte of RAM per indexed field for every document in the + /// index, during searching. Note that once you index a given field with norms enabled, disabling norms + /// will have no effect. In other words, for this to have the above described effect on a field, all + /// instances of that field must be indexed with NOT_ANALYZED_NO_NORMS from the beginning. + INDEX_NOT_ANALYZED_NO_NORMS, + + /// Index the tokens produced by running the field's value through an Analyzer, and also separately + /// disable the storing of norms. See {@link #NOT_ANALYZED_NO_NORMS} for what norms are and why you + /// may want to disable them. + INDEX_ANALYZED_NO_NORMS + }; + + /// Specifies whether and how a field should have term vectors. + enum TermVector { + /// Do not store term vectors. + TERM_VECTOR_NO, + + /// Store the term vectors of each document. A term vector is a list of the document's terms and their + /// number of occurrences in that document. + TERM_VECTOR_YES, + + /// Store the term vector + token position information + /// @see #YES + TERM_VECTOR_WITH_POSITIONS, + + /// Store the term vector + token offset information + /// @see #YES + TERM_VECTOR_WITH_OFFSETS, + + /// Store the term vector + token position and offset information + /// @see #YES + /// @see #WITH_POSITIONS + /// @see #WITH_OFFSETS + TERM_VECTOR_WITH_POSITIONS_OFFSETS + }; + +public: + virtual ~AbstractField(); + + LUCENE_CLASS(AbstractField); + +protected: + AbstractField(); + AbstractField(const String& name, Store store, Index index, TermVector termVector); + + String _name; + bool storeTermVector; + bool storeOffsetWithTermVector; + bool storePositionWithTermVector; + bool _omitNorms; + bool _isStored; + bool _isIndexed; + bool _isTokenized; + bool _isBinary; + bool lazy; + bool omitTermFreqAndPositions; + double boost; + + // the data object for all different kind of field values + FieldsData fieldsData; + + // pre-analyzed tokenStream for indexed fields + TokenStreamPtr tokenStream; + + // length/offset for all primitive types + int32_t binaryLength; + int32_t binaryOffset; + +public: + /// Sets the boost factor hits on this field. This value will be multiplied into the score of all + /// hits on this this field of this document. + /// + /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. + /// If a document has multiple fields with the same name, all such values are multiplied together. + /// This product is then used to compute the norm factor for the field. By default, in the {@link + /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the + /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} + /// before it is stored in the index. One should attempt to ensure that this product does not overflow + /// the range of that encoding. + /// + /// @see Document#setBoost(double) + /// @see Similarity#computeNorm(String, FieldInvertState) + /// @see Similarity#encodeNorm(double) + virtual void setBoost(double boost); + + /// Returns the boost factor for hits for this field. + /// + /// The default value is 1.0. + /// + /// Note: this value is not stored directly with the document in the index. Documents returned from + /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value + /// present as when this field was indexed. + virtual double getBoost(); + + /// Returns the name of the field as an interned string. For example "date", "title", "body", ... + virtual String name(); + + /// True if the value of the field is to be stored in the index for return with search hits. It is an + /// error for this to be true if a field is Reader-valued. + virtual bool isStored(); + + /// True if the value of the field is to be indexed, so that it may be searched on. + virtual bool isIndexed(); + + /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields + /// are indexed as a single word and may not be Reader-valued. + virtual bool isTokenized(); + + /// True if the term or terms used to index this field are stored as a term vector, available from + /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the + /// original content of the field, only to terms used to index it. If the original content must be + /// preserved, use the stored attribute instead. + virtual bool isTermVectorStored(); + + /// True if terms are stored as term vector together with their offsets (start and end position in + /// source text). + virtual bool isStoreOffsetWithTermVector(); + + /// True if terms are stored as term vector together with their token positions. + virtual bool isStorePositionWithTermVector(); + + /// True if the value of the field is stored as binary. + virtual bool isBinary(); + + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. + /// @return reference to the Field value as byte[]. + virtual ByteArray getBinaryValue(); + + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. + /// @return reference to the Field value as byte[]. + virtual ByteArray getBinaryValue(ByteArray result); + + /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is + /// undefined. + /// @return length of byte[] segment that represents this Field value. + virtual int32_t getBinaryLength(); + + /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is + /// undefined. + /// @return index of the first character in byte[] segment that represents this Field value. + virtual int32_t getBinaryOffset(); + + /// True if norms are omitted for this indexed field. + virtual bool getOmitNorms(); + + /// @see #setOmitTermFreqAndPositions + virtual bool getOmitTermFreqAndPositions(); + + /// If set, omit normalization factors associated with this indexed field. + /// This effectively disables indexing boosts and length normalization for this field. + virtual void setOmitNorms(bool omitNorms); + + /// If set, omit term freq, positions and payloads from postings for this field. + /// + /// NOTE: While this option reduces storage space required in the index, it also means any query requiring + /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail + /// to find results. + virtual void setOmitTermFreqAndPositions(bool omitTermFreqAndPositions); + + /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field + /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} + /// is only valid as long as the {@link IndexReader} that retrieved the {@link Document} is still open. + /// + /// @return true if this field can be loaded lazily + virtual bool isLazy(); + + /// Prints a Field for human consumption. + virtual String toString(); + +protected: + void setStoreTermVector(TermVector termVector); +}; + } #endif diff --git a/include/AllTermDocs.h b/include/AllTermDocs.h index 1005a93a..d3f46efe 100644 --- a/include/AllTermDocs.h +++ b/include/AllTermDocs.h @@ -9,22 +9,22 @@ #include "AbstractAllTermDocs.h" -namespace Lucene -{ - class AllTermDocs : public AbstractAllTermDocs - { - public: - AllTermDocs(const SegmentReaderPtr& parent); - virtual ~AllTermDocs(); - - LUCENE_CLASS(AllTermDocs); - - protected: - BitVectorWeakPtr _deletedDocs; - - public: - virtual bool isDeleted(int32_t doc); - }; +namespace Lucene { + +class AllTermDocs : public AbstractAllTermDocs { +public: + AllTermDocs(const SegmentReaderPtr& parent); + virtual ~AllTermDocs(); + + LUCENE_CLASS(AllTermDocs); + +protected: + BitVectorWeakPtr _deletedDocs; + +public: + virtual bool isDeleted(int32_t doc); +}; + } #endif diff --git a/include/Analyzer.h b/include/Analyzer.h index 8a07e93d..42860834 100644 --- a/include/Analyzer.h +++ b/include/Analyzer.h @@ -9,62 +9,62 @@ #include "CloseableThreadLocal.h" -namespace Lucene -{ - /// An Analyzer builds TokenStreams, which analyze text. It thus represents a policy for extracting index terms - /// from text. - /// - /// Typical implementations first build a Tokenizer, which breaks the stream of characters from the Reader into - /// raw Tokens. One or more TokenFilters may then be applied to the output of the Tokenizer. - class LPPAPI Analyzer : public LuceneObject - { - public: - virtual ~Analyzer(); - LUCENE_CLASS(Analyzer); +namespace Lucene { + +/// An Analyzer builds TokenStreams, which analyze text. It thus represents a policy for extracting index terms +/// from text. +/// +/// Typical implementations first build a Tokenizer, which breaks the stream of characters from the Reader into +/// raw Tokens. One or more TokenFilters may then be applied to the output of the Tokenizer. +class LPPAPI Analyzer : public LuceneObject { +public: + virtual ~Analyzer(); + LUCENE_CLASS(Analyzer); - protected: - CloseableThreadLocal tokenStreams; +protected: + CloseableThreadLocal tokenStreams; - public: - /// Creates a TokenStream which tokenizes all the text in the provided Reader. Must be able to handle null - /// field name for backward compatibility. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) = 0; +public: + /// Creates a TokenStream which tokenizes all the text in the provided Reader. Must be able to handle null + /// field name for backward compatibility. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) = 0; - /// Creates a TokenStream that is allowed to be re-used from the previous time that the same thread called - /// this method. Callers that do not need to use more than one TokenStream at the same time from this analyzer - /// should use this method for better performance. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); + /// Creates a TokenStream that is allowed to be re-used from the previous time that the same thread called + /// this method. Callers that do not need to use more than one TokenStream at the same time from this analyzer + /// should use this method for better performance. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - /// Invoked before indexing a Fieldable instance if terms have already been added to that field. This allows - /// custom analyzers to place an automatic position increment gap between Fieldable instances using the same - /// field name. The default value position increment gap is 0. With a 0 position increment gap and the typical - /// default token position increment of 1, all terms in a field, including across Fieldable instances, are in - /// successive positions, allowing exact PhraseQuery matches, for instance, across Fieldable instance boundaries. - /// - /// @param fieldName Fieldable name being indexed. - /// @return position increment gap, added to the next token emitted from {@link #tokenStream(String,Reader)} - virtual int32_t getPositionIncrementGap(const String& fieldName); + /// Invoked before indexing a Fieldable instance if terms have already been added to that field. This allows + /// custom analyzers to place an automatic position increment gap between Fieldable instances using the same + /// field name. The default value position increment gap is 0. With a 0 position increment gap and the typical + /// default token position increment of 1, all terms in a field, including across Fieldable instances, are in + /// successive positions, allowing exact PhraseQuery matches, for instance, across Fieldable instance boundaries. + /// + /// @param fieldName Fieldable name being indexed. + /// @return position increment gap, added to the next token emitted from {@link #tokenStream(String,Reader)} + virtual int32_t getPositionIncrementGap(const String& fieldName); + + /// Just like {@link #getPositionIncrementGap}, except for Token offsets instead. By default this returns 1 for + /// tokenized fields and, as if the fields were joined with an extra space character, and 0 for un-tokenized + /// fields. This method is only called if the field produced at least one token for indexing. + /// + /// @param field the field just indexed + /// @return offset gap, added to the next token emitted from {@link #tokenStream(String,Reader)} + virtual int32_t getOffsetGap(const FieldablePtr& field); - /// Just like {@link #getPositionIncrementGap}, except for Token offsets instead. By default this returns 1 for - /// tokenized fields and, as if the fields were joined with an extra space character, and 0 for un-tokenized - /// fields. This method is only called if the field produced at least one token for indexing. - /// - /// @param field the field just indexed - /// @return offset gap, added to the next token emitted from {@link #tokenStream(String,Reader)} - virtual int32_t getOffsetGap(const FieldablePtr& field); + /// Frees persistent resources used by this Analyzer + virtual void close(); - /// Frees persistent resources used by this Analyzer - virtual void close(); +protected: + /// Used by Analyzers that implement reusableTokenStream to retrieve previously saved TokenStreams for re-use + /// by the same thread. + virtual LuceneObjectPtr getPreviousTokenStream(); - protected: - /// Used by Analyzers that implement reusableTokenStream to retrieve previously saved TokenStreams for re-use - /// by the same thread. - virtual LuceneObjectPtr getPreviousTokenStream(); + /// Used by Analyzers that implement reusableTokenStream to save a TokenStream for later re-use by the + /// same thread. + virtual void setPreviousTokenStream(const LuceneObjectPtr& stream); +}; - /// Used by Analyzers that implement reusableTokenStream to save a TokenStream for later re-use by the - /// same thread. - virtual void setPreviousTokenStream(const LuceneObjectPtr& stream); - }; } #endif diff --git a/include/Array.h b/include/Array.h index 5bf83d2e..ada8fec1 100644 --- a/include/Array.h +++ b/include/Array.h @@ -10,145 +10,127 @@ #include #include "Lucene.h" -namespace Lucene -{ - template - class ArrayData - { - public: - ArrayData(int32_t size) - { - data = NULL; - resize(size); - } +namespace Lucene { + +template +class ArrayData { +public: + ArrayData(int32_t size) { + data = NULL; + resize(size); + } - ~ArrayData() - { - resize(0); - } + ~ArrayData() { + resize(0); + } - public: - TYPE* data; - int32_t size; - - public: - void resize(int32_t size) - { - if (size == 0) - { - FreeMemory(data); - data = NULL; - } - else if (data == NULL) - data = (TYPE*)AllocMemory(size * sizeof(TYPE)); - else - data = (TYPE*)ReallocMemory(data, size * sizeof(TYPE)); - this->size = size; - } - }; - - /// Utility template class to handle sharable arrays of simple data types - template - class Array - { - public: - typedef Array this_type; - typedef ArrayData array_type; - - Array() - { - array = NULL; - } +public: + TYPE* data; + int32_t size; - protected: - boost::shared_ptr container; - array_type* array; - - public: - static this_type newInstance(int32_t size) - { - this_type instance; - instance.container = Lucene::newInstance(size); - instance.array = instance.container.get(); - return instance; +public: + void resize(int32_t size) { + if (size == 0) { + FreeMemory(data); + data = NULL; + } else if (data == NULL) { + data = (TYPE*)AllocMemory(size * sizeof(TYPE)); + } else { + data = (TYPE*)ReallocMemory(data, size * sizeof(TYPE)); } + this->size = size; + } +}; - void reset() - { - resize(0); - } +/// Utility template class to handle sharable arrays of simple data types +template +class Array { +public: + typedef Array this_type; + typedef ArrayData array_type; - void resize(int32_t size) - { - if (size == 0) - container.reset(); - else if (!container) - container = Lucene::newInstance(size); - else - container->resize(size); - array = container.get(); - } + Array() { + array = NULL; + } - TYPE* get() const - { - return array->data; - } +protected: + boost::shared_ptr container; + array_type* array; - int32_t size() const - { - return array->size; - } +public: + static this_type newInstance(int32_t size) { + this_type instance; + instance.container = Lucene::newInstance(size); + instance.array = instance.container.get(); + return instance; + } - bool equals(const this_type& other) const - { - if (array->size != other.array->size) - return false; - return (std::memcmp(array->data, other.array->data, array->size) == 0); - } + void reset() { + resize(0); + } - int32_t hashCode() const - { - return (int32_t)(int64_t)array; + void resize(int32_t size) { + if (size == 0) { + container.reset(); + } else if (!container) { + container = Lucene::newInstance(size); + } else { + container->resize(size); } + array = container.get(); + } - TYPE& operator[] (int32_t i) const - { - BOOST_ASSERT(i >= 0 && i < array->size); - return array->data[i]; - } + TYPE* get() const { + return array->data; + } - operator bool () const - { - return container.get() != NULL; - } + int32_t size() const { + return array->size; + } - bool operator! () const - { - return !container; + bool equals(const this_type& other) const { + if (array->size != other.array->size) { + return false; } + return (std::memcmp(array->data, other.array->data, array->size) == 0); + } - bool operator== (const Array& other) - { - return (container == other.container); - } + int32_t hashCode() const { + return (int32_t)(int64_t)array; + } - bool operator!= (const Array& other) - { - return (container != other.container); - } - }; + TYPE& operator[] (int32_t i) const { + BOOST_ASSERT(i >= 0 && i < array->size); + return array->data[i]; + } - template - inline std::size_t hash_value(const Array& value) - { - return (std::size_t)value.hashCode(); + operator bool () const { + return container.get() != NULL; } - template - inline bool operator== (const Array& value1, const Array& value2) - { - return (value1.hashCode() == value2.hashCode()); + bool operator! () const { + return !container; } + + bool operator== (const Array& other) { + return (container == other.container); + } + + bool operator!= (const Array& other) { + return (container != other.container); + } +}; + +template +inline std::size_t hash_value(const Array& value) { + return (std::size_t)value.hashCode(); +} + +template +inline bool operator== (const Array& value1, const Array& value2) { + return (value1.hashCode() == value2.hashCode()); +} + } #endif diff --git a/include/Attribute.h b/include/Attribute.h index 9127335a..4c75ce10 100644 --- a/include/Attribute.h +++ b/include/Attribute.h @@ -9,48 +9,48 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Base class for Attributes that can be added to a {@link AttributeSource}. +namespace Lucene { + +/// Base class for Attributes that can be added to a {@link AttributeSource}. +/// +/// Attributes are used to add data in a dynamic, yet type-safe way to a source of usually streamed objects, +/// eg. a {@link TokenStream}. +class LPPAPI Attribute : public LuceneObject { +public: + virtual ~Attribute(); + LUCENE_CLASS(Attribute); + +public: + /// Clears the values in this Attribute and resets it to its default value. If this implementation + /// implements more than one Attribute interface it clears all. + virtual void clear() = 0; + + /// Subclasses must implement this method and should compute a hashCode similar to this: /// - /// Attributes are used to add data in a dynamic, yet type-safe way to a source of usually streamed objects, - /// eg. a {@link TokenStream}. - class LPPAPI Attribute : public LuceneObject - { - public: - virtual ~Attribute(); - LUCENE_CLASS(Attribute); - - public: - /// Clears the values in this Attribute and resets it to its default value. If this implementation - /// implements more than one Attribute interface it clears all. - virtual void clear() = 0; - - /// Subclasses must implement this method and should compute a hashCode similar to this: - /// - /// int32_t hashCode() - /// { - /// int32_t code = startOffset; - /// code = code * 31 + endOffset; - /// return code; - /// } - /// - /// see also {@link #equals(Object)} - virtual int32_t hashCode() = 0; - - /// All values used for computation of {@link #hashCode()} should be checked here for equality. - /// - /// see also {@link LuceneObject#equals(Object)} - virtual bool equals(const LuceneObjectPtr& other) = 0; - - /// Copies the values from this Attribute into the passed-in target attribute. The target implementation - /// must support all the Attributes this implementation supports. - virtual void copyTo(const AttributePtr& target) = 0; - - /// Shallow clone. Subclasses must override this if they need to clone any members deeply. - /// @param base clone reference - null when called initially, then set in top virtual override. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) = 0; - }; + /// int32_t hashCode() + /// { + /// int32_t code = startOffset; + /// code = code * 31 + endOffset; + /// return code; + /// } + /// + /// see also {@link #equals(Object)} + virtual int32_t hashCode() = 0; + + /// All values used for computation of {@link #hashCode()} should be checked here for equality. + /// + /// see also {@link LuceneObject#equals(Object)} + virtual bool equals(const LuceneObjectPtr& other) = 0; + + /// Copies the values from this Attribute into the passed-in target attribute. The target implementation + /// must support all the Attributes this implementation supports. + virtual void copyTo(const AttributePtr& target) = 0; + + /// Shallow clone. Subclasses must override this if they need to clone any members deeply. + /// @param base clone reference - null when called initially, then set in top virtual override. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) = 0; +}; + } #endif diff --git a/include/AttributeSource.h b/include/AttributeSource.h index bae4dcbe..6b63649d 100644 --- a/include/AttributeSource.h +++ b/include/AttributeSource.h @@ -9,184 +9,178 @@ #include "LuceneObject.h" -namespace Lucene -{ - class LPPAPI AttributeFactory : public LuceneObject - { - protected: - AttributeFactory(); - - public: - virtual ~AttributeFactory(); - - LUCENE_CLASS(AttributeFactory); - - public: - /// returns an {@link Attribute}. - virtual AttributePtr createAttributeInstance(const String& className); - - template - AttributePtr createInstance(const String& className) - { - AttributePtr attrImpl = createAttributeInstance(className); - return attrImpl ? attrImpl : newLucene(); - } - - /// This is the default factory that creates {@link Attribute}s using the class name of the supplied - /// {@link Attribute} interface class by appending Impl to it. - static AttributeFactoryPtr DEFAULT_ATTRIBUTE_FACTORY(); - }; - - /// An AttributeSource contains a list of different {@link Attribute}s, and methods to add and get them. - /// There can only be a single instance of an attribute in the same AttributeSource instance. This is ensured - /// by passing in the actual type of the Attribute (Class) to the {@link #addAttribute(Class)}, - /// which then checks if an instance of that type is already present. If yes, it returns the instance, otherwise - /// it creates a new instance and returns it. - class LPPAPI AttributeSource : public LuceneObject - { - public: - /// An AttributeSource using the default attribute factory {@link DefaultAttributeFactory}. - AttributeSource(); - - /// An AttributeSource that uses the same attributes as the supplied one. - AttributeSource(const AttributeSourcePtr& input); - - /// An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} - /// instances. - AttributeSource(const AttributeFactoryPtr& factory); - - virtual ~AttributeSource(); - - LUCENE_CLASS(AttributeSource); - - protected: - AttributeFactoryPtr factory; - MapStringAttribute attributes; - AttributeSourceStatePtr currentState; - - public: - /// returns the used AttributeFactory. - AttributeFactoryPtr getAttributeFactory(); - - /// This method first checks if an instance of that class is already in this AttributeSource and returns it. - /// Otherwise a new instance is created, added to this AttributeSource and returned. - template - boost::shared_ptr addAttribute() - { - String className(ATTR::_getClassName()); - boost::shared_ptr attrImpl(boost::dynamic_pointer_cast(getAttribute(className))); - if (!attrImpl) - { - attrImpl = boost::dynamic_pointer_cast(factory->createInstance(className)); - if (!attrImpl) - boost::throw_exception(IllegalArgumentException(L"Could not instantiate implementing class for " + className)); - addAttribute(className, attrImpl); +namespace Lucene { + +class LPPAPI AttributeFactory : public LuceneObject { +protected: + AttributeFactory(); + +public: + virtual ~AttributeFactory(); + + LUCENE_CLASS(AttributeFactory); + +public: + /// returns an {@link Attribute}. + virtual AttributePtr createAttributeInstance(const String& className); + + template + AttributePtr createInstance(const String& className) { + AttributePtr attrImpl = createAttributeInstance(className); + return attrImpl ? attrImpl : newLucene(); + } + + /// This is the default factory that creates {@link Attribute}s using the class name of the supplied + /// {@link Attribute} interface class by appending Impl to it. + static AttributeFactoryPtr DEFAULT_ATTRIBUTE_FACTORY(); +}; + +/// An AttributeSource contains a list of different {@link Attribute}s, and methods to add and get them. +/// There can only be a single instance of an attribute in the same AttributeSource instance. This is ensured +/// by passing in the actual type of the Attribute (Class) to the {@link #addAttribute(Class)}, +/// which then checks if an instance of that type is already present. If yes, it returns the instance, otherwise +/// it creates a new instance and returns it. +class LPPAPI AttributeSource : public LuceneObject { +public: + /// An AttributeSource using the default attribute factory {@link DefaultAttributeFactory}. + AttributeSource(); + + /// An AttributeSource that uses the same attributes as the supplied one. + AttributeSource(const AttributeSourcePtr& input); + + /// An AttributeSource using the supplied {@link AttributeFactory} for creating new {@link Attribute} + /// instances. + AttributeSource(const AttributeFactoryPtr& factory); + + virtual ~AttributeSource(); + + LUCENE_CLASS(AttributeSource); + +protected: + AttributeFactoryPtr factory; + MapStringAttribute attributes; + AttributeSourceStatePtr currentState; + +public: + /// returns the used AttributeFactory. + AttributeFactoryPtr getAttributeFactory(); + + /// This method first checks if an instance of that class is already in this AttributeSource and returns it. + /// Otherwise a new instance is created, added to this AttributeSource and returned. + template + boost::shared_ptr addAttribute() { + String className(ATTR::_getClassName()); + boost::shared_ptr attrImpl(boost::dynamic_pointer_cast(getAttribute(className))); + if (!attrImpl) { + attrImpl = boost::dynamic_pointer_cast(factory->createInstance(className)); + if (!attrImpl) { + boost::throw_exception(IllegalArgumentException(L"Could not instantiate implementing class for " + className)); } - return attrImpl; + addAttribute(className, attrImpl); } - - /// Adds a custom Attribute instance. - void addAttribute(const String& className, const AttributePtr& attrImpl); - - /// Returns true if this AttributeSource has any attributes. - bool hasAttributes(); - - /// Returns true, if this AttributeSource contains the passed-in Attribute. - template - bool hasAttribute() - { - return getAttribute(ATTR::_getClassName()).get() != NULL; + return attrImpl; + } + + /// Adds a custom Attribute instance. + void addAttribute(const String& className, const AttributePtr& attrImpl); + + /// Returns true if this AttributeSource has any attributes. + bool hasAttributes(); + + /// Returns true, if this AttributeSource contains the passed-in Attribute. + template + bool hasAttribute() { + return getAttribute(ATTR::_getClassName()).get() != NULL; + } + + /// Returns the instance of the passed in Attribute contained in this AttributeSource. + template + boost::shared_ptr getAttribute() { + String className(ATTR::_getClassName()); + boost::shared_ptr attr(boost::dynamic_pointer_cast(getAttribute(className))); + if (!attr) { + boost::throw_exception(IllegalArgumentException(L"This AttributeSource does not have the attribute '" + className + L"'.")); } + return attr; + } - /// Returns the instance of the passed in Attribute contained in this AttributeSource. - template - boost::shared_ptr getAttribute() - { - String className(ATTR::_getClassName()); - boost::shared_ptr attr(boost::dynamic_pointer_cast(getAttribute(className))); - if (!attr) - boost::throw_exception(IllegalArgumentException(L"This AttributeSource does not have the attribute '" + className + L"'.")); - return attr; - } + /// Resets all Attributes in this AttributeSource by calling {@link AttributeImpl#clear()} on each Attribute + /// implementation. + void clearAttributes(); - /// Resets all Attributes in this AttributeSource by calling {@link AttributeImpl#clear()} on each Attribute - /// implementation. - void clearAttributes(); + /// Captures the state of all Attributes. The return value can be passed to {@link #restoreState} to restore + /// the state of this or another AttributeSource. + AttributeSourceStatePtr captureState(); - /// Captures the state of all Attributes. The return value can be passed to {@link #restoreState} to restore - /// the state of this or another AttributeSource. - AttributeSourceStatePtr captureState(); + /// Restores this state by copying the values of all attribute implementations that this state contains into + /// the attributes implementations of the targetStream. The targetStream must contain a corresponding instance + /// for each argument contained in this state (eg. it is not possible to restore the state of an AttributeSource + /// containing a TermAttribute into a AttributeSource using a Token instance as implementation). + /// + /// Note that this method does not affect attributes of the targetStream that are not contained in this state. + /// In other words, if for example the targetStream contains an OffsetAttribute, but this state doesn't, then + /// the value of the OffsetAttribute remains unchanged. It might be desirable to reset its value to the default, + /// in which case the caller should first call {@link TokenStream#clearAttributes()} on the targetStream. + void restoreState(const AttributeSourceStatePtr& state); - /// Restores this state by copying the values of all attribute implementations that this state contains into - /// the attributes implementations of the targetStream. The targetStream must contain a corresponding instance - /// for each argument contained in this state (eg. it is not possible to restore the state of an AttributeSource - /// containing a TermAttribute into a AttributeSource using a Token instance as implementation). - /// - /// Note that this method does not affect attributes of the targetStream that are not contained in this state. - /// In other words, if for example the targetStream contains an OffsetAttribute, but this state doesn't, then - /// the value of the OffsetAttribute remains unchanged. It might be desirable to reset its value to the default, - /// in which case the caller should first call {@link TokenStream#clearAttributes()} on the targetStream. - void restoreState(const AttributeSourceStatePtr& state); + /// Return hash code for this object. + virtual int32_t hashCode(); - /// Return hash code for this object. - virtual int32_t hashCode(); + /// Return whether two objects are equal + virtual bool equals(const LuceneObjectPtr& other); - /// Return whether two objects are equal - virtual bool equals(const LuceneObjectPtr& other); + /// Returns a string representation of the object + virtual String toString(); - /// Returns a string representation of the object - virtual String toString(); + /// Performs a clone of all {@link AttributeImpl} instances returned in a new AttributeSource instance. This + /// method can be used to eg. create another TokenStream with exactly the same attributes (using {@link + /// #AttributeSource(AttributeSource)}) + AttributeSourcePtr cloneAttributes(); - /// Performs a clone of all {@link AttributeImpl} instances returned in a new AttributeSource instance. This - /// method can be used to eg. create another TokenStream with exactly the same attributes (using {@link - /// #AttributeSource(AttributeSource)}) - AttributeSourcePtr cloneAttributes(); + /// Return a vector of attributes based on currentState. + Collection getAttributes(); - /// Return a vector of attributes based on currentState. - Collection getAttributes(); +protected: + /// The caller must pass in a className value. + /// This method checks if an instance of that class is already in this AttributeSource and returns it. + AttributePtr getAttribute(const String& className); - protected: - /// The caller must pass in a className value. - /// This method checks if an instance of that class is already in this AttributeSource and returns it. - AttributePtr getAttribute(const String& className); + /// Returns true, if this AttributeSource contains the passed-in Attribute. + bool hasAttribute(const String& className); - /// Returns true, if this AttributeSource contains the passed-in Attribute. - bool hasAttribute(const String& className); + void computeCurrentState(); +}; - void computeCurrentState(); - }; +class LPPAPI DefaultAttributeFactory : public AttributeFactory { +public: + virtual ~DefaultAttributeFactory(); - class LPPAPI DefaultAttributeFactory : public AttributeFactory - { - public: - virtual ~DefaultAttributeFactory(); + LUCENE_CLASS(DefaultAttributeFactory); - LUCENE_CLASS(DefaultAttributeFactory); +public: + /// returns an {@link Attribute}. + virtual AttributePtr createAttributeInstance(const String& className); +}; - public: - /// returns an {@link Attribute}. - virtual AttributePtr createAttributeInstance(const String& className); - }; +/// This class holds the state of an AttributeSource. +/// @see #captureState +/// @see #restoreState +class LPPAPI AttributeSourceState : public LuceneObject { +public: + virtual ~AttributeSourceState(); - /// This class holds the state of an AttributeSource. - /// @see #captureState - /// @see #restoreState - class LPPAPI AttributeSourceState : public LuceneObject - { - public: - virtual ~AttributeSourceState(); + LUCENE_CLASS(AttributeSourceState); - LUCENE_CLASS(AttributeSourceState); +protected: + AttributePtr attribute; + AttributeSourceStatePtr next; - protected: - AttributePtr attribute; - AttributeSourceStatePtr next; +public: + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - public: - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + friend class AttributeSource; +}; - friend class AttributeSource; - }; } #endif diff --git a/include/AveragePayloadFunction.h b/include/AveragePayloadFunction.h index 850ed9c3..f7b3c3d2 100644 --- a/include/AveragePayloadFunction.h +++ b/include/AveragePayloadFunction.h @@ -9,24 +9,24 @@ #include "PayloadFunction.h" -namespace Lucene -{ - /// Calculate the final score as the average score of all payloads seen. - /// - /// Is thread safe and completely reusable. - class LPPAPI AveragePayloadFunction : public PayloadFunction - { - public: - virtual ~AveragePayloadFunction(); - LUCENE_CLASS(AveragePayloadFunction); +namespace Lucene { + +/// Calculate the final score as the average score of all payloads seen. +/// +/// Is thread safe and completely reusable. +class LPPAPI AveragePayloadFunction : public PayloadFunction { +public: + virtual ~AveragePayloadFunction(); + LUCENE_CLASS(AveragePayloadFunction); + +public: + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + double currentScore, double currentPayloadScore); + virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); +}; - public: - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, - double currentScore, double currentPayloadScore); - virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - }; } #endif diff --git a/include/Base64.h b/include/Base64.h index 36a8e5a0..68db9e50 100644 --- a/include/Base64.h +++ b/include/Base64.h @@ -9,25 +9,25 @@ #include "LuceneObject.h" -namespace Lucene -{ - class Base64 : public LuceneObject - { - public: - virtual ~Base64(); - LUCENE_CLASS(Base64); - - protected: - static const String BASE64_CHARS; - - public: - static String encode(ByteArray bytes); - static String encode(const uint8_t* bytes, int32_t length); - static ByteArray decode(const String& str); - - protected: - static bool isBase64(wchar_t ch); - }; +namespace Lucene { + +class Base64 : public LuceneObject { +public: + virtual ~Base64(); + LUCENE_CLASS(Base64); + +protected: + static const String BASE64_CHARS; + +public: + static String encode(ByteArray bytes); + static String encode(const uint8_t* bytes, int32_t length); + static ByteArray decode(const String& str); + +protected: + static bool isBase64(wchar_t ch); +}; + } #endif diff --git a/include/BaseCharFilter.h b/include/BaseCharFilter.h index 783f970c..5f66e940 100644 --- a/include/BaseCharFilter.h +++ b/include/BaseCharFilter.h @@ -9,30 +9,30 @@ #include "CharFilter.h" -namespace Lucene -{ - /// Base utility class for implementing a {@link CharFilter}. You subclass this, and then record mappings by - /// calling {@link #addOffCorrectMap}, and then invoke the correct method to correct an offset. - class LPPAPI BaseCharFilter : public CharFilter - { - public: - BaseCharFilter(const CharStreamPtr& in); - virtual ~BaseCharFilter(); - - LUCENE_CLASS(BaseCharFilter); - - protected: - IntArray offsets; - IntArray diffs; - int32_t size; - - protected: - /// Retrieve the corrected offset. - virtual int32_t correct(int32_t currentOff); - - int32_t getLastCumulativeDiff(); - void addOffCorrectMap(int32_t off, int32_t cumulativeDiff); - }; +namespace Lucene { + +/// Base utility class for implementing a {@link CharFilter}. You subclass this, and then record mappings by +/// calling {@link #addOffCorrectMap}, and then invoke the correct method to correct an offset. +class LPPAPI BaseCharFilter : public CharFilter { +public: + BaseCharFilter(const CharStreamPtr& in); + virtual ~BaseCharFilter(); + + LUCENE_CLASS(BaseCharFilter); + +protected: + IntArray offsets; + IntArray diffs; + int32_t size; + +protected: + /// Retrieve the corrected offset. + virtual int32_t correct(int32_t currentOff); + + int32_t getLastCumulativeDiff(); + void addOffCorrectMap(int32_t off, int32_t cumulativeDiff); +}; + } #endif diff --git a/include/BitSet.h b/include/BitSet.h index cf039a08..e06e6c7b 100644 --- a/include/BitSet.h +++ b/include/BitSet.h @@ -10,57 +10,57 @@ #include #include "LuceneObject.h" -namespace Lucene -{ - class LPPAPI BitSet : public LuceneObject - { - public: - BitSet(uint32_t size = 0); - virtual ~BitSet(); +namespace Lucene { - LUCENE_CLASS(BitSet); +class LPPAPI BitSet : public LuceneObject { +public: + BitSet(uint32_t size = 0); + virtual ~BitSet(); - protected: - typedef boost::dynamic_bitset bitset_type; - bitset_type bitSet; + LUCENE_CLASS(BitSet); - public: - const uint64_t* getBits(); - void clear(); - void clear(uint32_t bitIndex); - void fastClear(uint32_t bitIndex); - void clear(uint32_t fromIndex, uint32_t toIndex); - void fastClear(uint32_t fromIndex, uint32_t toIndex); - void set(uint32_t bitIndex); - void fastSet(uint32_t bitIndex); - void set(uint32_t bitIndex, bool value); - void fastSet(uint32_t bitIndex, bool value); - void set(uint32_t fromIndex, uint32_t toIndex); - void fastSet(uint32_t fromIndex, uint32_t toIndex); - void set(uint32_t fromIndex, uint32_t toIndex, bool value); - void fastSet(uint32_t fromIndex, uint32_t toIndex, bool value); - void flip(uint32_t bitIndex); - void fastFlip(uint32_t bitIndex); - void flip(uint32_t fromIndex, uint32_t toIndex); - void fastFlip(uint32_t fromIndex, uint32_t toIndex); - uint32_t size() const; - uint32_t numBlocks() const; - bool isEmpty() const; - bool get(uint32_t bitIndex) const; - bool fastGet(uint32_t bitIndex) const; - int32_t nextSetBit(uint32_t fromIndex) const; - void _and(const BitSetPtr& set); - void _or(const BitSetPtr& set); - void _xor(const BitSetPtr& set); - void andNot(const BitSetPtr& set); - bool intersectsBitSet(const BitSetPtr& set) const; - uint32_t cardinality(); - void resize(uint32_t size); +protected: + typedef boost::dynamic_bitset bitset_type; + bitset_type bitSet; + +public: + const uint64_t* getBits(); + void clear(); + void clear(uint32_t bitIndex); + void fastClear(uint32_t bitIndex); + void clear(uint32_t fromIndex, uint32_t toIndex); + void fastClear(uint32_t fromIndex, uint32_t toIndex); + void set(uint32_t bitIndex); + void fastSet(uint32_t bitIndex); + void set(uint32_t bitIndex, bool value); + void fastSet(uint32_t bitIndex, bool value); + void set(uint32_t fromIndex, uint32_t toIndex); + void fastSet(uint32_t fromIndex, uint32_t toIndex); + void set(uint32_t fromIndex, uint32_t toIndex, bool value); + void fastSet(uint32_t fromIndex, uint32_t toIndex, bool value); + void flip(uint32_t bitIndex); + void fastFlip(uint32_t bitIndex); + void flip(uint32_t fromIndex, uint32_t toIndex); + void fastFlip(uint32_t fromIndex, uint32_t toIndex); + uint32_t size() const; + uint32_t numBlocks() const; + bool isEmpty() const; + bool get(uint32_t bitIndex) const; + bool fastGet(uint32_t bitIndex) const; + int32_t nextSetBit(uint32_t fromIndex) const; + void _and(const BitSetPtr& set); + void _or(const BitSetPtr& set); + void _xor(const BitSetPtr& set); + void andNot(const BitSetPtr& set); + bool intersectsBitSet(const BitSetPtr& set) const; + uint32_t cardinality(); + void resize(uint32_t size); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; } #endif diff --git a/include/BitUtil.h b/include/BitUtil.h index 69a5149d..5bb91531 100644 --- a/include/BitUtil.h +++ b/include/BitUtil.h @@ -9,67 +9,67 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A variety of high efficiency bit twiddling routines. - class LPPAPI BitUtil : public LuceneObject - { - public: - virtual ~BitUtil(); - LUCENE_CLASS(BitUtil); +namespace Lucene { - public: - /// Table of number of trailing zeros in a byte - static const uint8_t ntzTable[]; +/// A variety of high efficiency bit twiddling routines. +class LPPAPI BitUtil : public LuceneObject { +public: + virtual ~BitUtil(); + LUCENE_CLASS(BitUtil); - public: - /// Returns the number of bits set in the long - static int32_t pop(int64_t x); +public: + /// Table of number of trailing zeros in a byte + static const uint8_t ntzTable[]; - /// Returns the number of set bits in an array of longs. - static int64_t pop_array(const int64_t* A, int32_t wordOffset, int32_t numWords); +public: + /// Returns the number of bits set in the long + static int32_t pop(int64_t x); - /// Returns the popcount or cardinality of the two sets after an intersection. Neither array is modified. - static int64_t pop_intersect(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); + /// Returns the number of set bits in an array of longs. + static int64_t pop_array(const int64_t* A, int32_t wordOffset, int32_t numWords); - /// Returns the popcount or cardinality of the union of two sets. Neither array is modified. - static int64_t pop_union(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); + /// Returns the popcount or cardinality of the two sets after an intersection. Neither array is modified. + static int64_t pop_intersect(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - /// Returns the popcount or cardinality of A & ~B. Neither array is modified. - static int64_t pop_andnot(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); + /// Returns the popcount or cardinality of the union of two sets. Neither array is modified. + static int64_t pop_union(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - /// Returns the popcount or cardinality of A ^ B. Neither array is modified. - static int64_t pop_xor(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); + /// Returns the popcount or cardinality of A & ~B. Neither array is modified. + static int64_t pop_andnot(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - /// Returns number of trailing zeros in a 64 bit long value. - static int32_t ntz(int64_t val); + /// Returns the popcount or cardinality of A ^ B. Neither array is modified. + static int64_t pop_xor(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords); - /// Returns number of trailing zeros in a 32 bit int value. - static int32_t ntz(int32_t val); + /// Returns number of trailing zeros in a 64 bit long value. + static int32_t ntz(int64_t val); - /// Returns 0 based index of first set bit (only works for x!=0) - /// This is an alternate implementation of ntz() - static int32_t ntz2(int64_t x); + /// Returns number of trailing zeros in a 32 bit int value. + static int32_t ntz(int32_t val); - /// Returns 0 based index of first set bit. - /// This is an alternate implementation of ntz() - static int32_t ntz3(int64_t x); + /// Returns 0 based index of first set bit (only works for x!=0) + /// This is an alternate implementation of ntz() + static int32_t ntz2(int64_t x); - /// Returns true if v is a power of two or zero. - static bool isPowerOfTwo(int32_t v); + /// Returns 0 based index of first set bit. + /// This is an alternate implementation of ntz() + static int32_t ntz3(int64_t x); - /// Returns true if v is a power of two or zero. - static bool isPowerOfTwo(int64_t v); + /// Returns true if v is a power of two or zero. + static bool isPowerOfTwo(int32_t v); - /// Returns the next highest power of two, or the current value if it's already a power of two or zero. - static int32_t nextHighestPowerOfTwo(int32_t v); + /// Returns true if v is a power of two or zero. + static bool isPowerOfTwo(int64_t v); - /// Returns the next highest power of two, or the current value if it's already a power of two or zero. - static int64_t nextHighestPowerOfTwo(int64_t v); + /// Returns the next highest power of two, or the current value if it's already a power of two or zero. + static int32_t nextHighestPowerOfTwo(int32_t v); + + /// Returns the next highest power of two, or the current value if it's already a power of two or zero. + static int64_t nextHighestPowerOfTwo(int64_t v); + +protected: + inline static void CSA(int64_t& h, int64_t& l, int64_t a, int64_t b, int64_t c); +}; - protected: - inline static void CSA(int64_t& h, int64_t& l, int64_t a, int64_t b, int64_t c); - }; } #endif diff --git a/include/BitVector.h b/include/BitVector.h index ddaa2295..694bb74b 100644 --- a/include/BitVector.h +++ b/include/BitVector.h @@ -9,87 +9,87 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Optimized implementation of a vector of bits. - class LPPAPI BitVector : public LuceneObject - { - public: - /// Constructs a vector capable of holding n bits. - BitVector(int32_t n = 0); +namespace Lucene { - BitVector(ByteArray bits, int32_t size); +/// Optimized implementation of a vector of bits. +class LPPAPI BitVector : public LuceneObject { +public: + /// Constructs a vector capable of holding n bits. + BitVector(int32_t n = 0); - /// Constructs a bit vector from the file name in Directory d, - /// as written by the {@link #write} method. - BitVector(const DirectoryPtr& d, const String& name); + BitVector(ByteArray bits, int32_t size); - virtual ~BitVector(); + /// Constructs a bit vector from the file name in Directory d, + /// as written by the {@link #write} method. + BitVector(const DirectoryPtr& d, const String& name); - LUCENE_CLASS(BitVector); + virtual ~BitVector(); - protected: - ByteArray bits; - int32_t _size; - int32_t _count; + LUCENE_CLASS(BitVector); - static const uint8_t BYTE_COUNTS[]; // table of bits/byte +protected: + ByteArray bits; + int32_t _size; + int32_t _count; - public: - /// Clone this vector - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + static const uint8_t BYTE_COUNTS[]; // table of bits/byte - /// Sets the value of bit to one. - void set(int32_t bit); +public: + /// Clone this vector + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - /// Sets the value of bit to true, and returns true if bit was already set. - bool getAndSet(int32_t bit); + /// Sets the value of bit to one. + void set(int32_t bit); - /// Sets the value of bit to zero. - void clear(int32_t bit); + /// Sets the value of bit to true, and returns true if bit was already set. + bool getAndSet(int32_t bit); - /// Returns true if bit is one and false if it is zero. - bool get(int32_t bit); + /// Sets the value of bit to zero. + void clear(int32_t bit); - /// Returns the number of bits in this vector. This is also one greater than - /// the number of the largest valid bit number. - int32_t size(); + /// Returns true if bit is one and false if it is zero. + bool get(int32_t bit); - /// Returns the total number of one bits in this vector. This is efficiently - /// computed and cached, so that, if the vector is not changed, no recomputation - /// is done for repeated calls. - int32_t count(); + /// Returns the number of bits in this vector. This is also one greater than + /// the number of the largest valid bit number. + int32_t size(); - /// For testing - int32_t getRecomputedCount(); + /// Returns the total number of one bits in this vector. This is efficiently + /// computed and cached, so that, if the vector is not changed, no recomputation + /// is done for repeated calls. + int32_t count(); - /// Writes this vector to the file name in Directory d, in a format that can - /// be read by the constructor {@link #BitVector(DirectoryPtr, const String&)}. - void write(const DirectoryPtr& d, const String& name); + /// For testing + int32_t getRecomputedCount(); - /// Retrieve a subset of this BitVector. - /// @param start starting index, inclusive - /// @param end ending index, exclusive - /// @return subset - BitVectorPtr subset(int32_t start, int32_t end); + /// Writes this vector to the file name in Directory d, in a format that can + /// be read by the constructor {@link #BitVector(DirectoryPtr, const String&)}. + void write(const DirectoryPtr& d, const String& name); - protected: - /// Write as a bit set. - void writeBits(const IndexOutputPtr& output); + /// Retrieve a subset of this BitVector. + /// @param start starting index, inclusive + /// @param end ending index, exclusive + /// @return subset + BitVectorPtr subset(int32_t start, int32_t end); - /// Write as a d-gaps list. - void writeDgaps(const IndexOutputPtr& output); +protected: + /// Write as a bit set. + void writeBits(const IndexOutputPtr& output); - /// Indicates if the bit vector is sparse and should be saved as a d-gaps list, - /// or dense, and should be saved as a bit set. - bool isSparse(); + /// Write as a d-gaps list. + void writeDgaps(const IndexOutputPtr& output); - /// Read as a bit set. - void readBits(const IndexInputPtr& input); + /// Indicates if the bit vector is sparse and should be saved as a d-gaps list, + /// or dense, and should be saved as a bit set. + bool isSparse(); + + /// Read as a bit set. + void readBits(const IndexInputPtr& input); + + /// Read as a d-gaps list. + void readDgaps(const IndexInputPtr& input); +}; - /// Read as a d-gaps list. - void readDgaps(const IndexInputPtr& input); - }; } #endif diff --git a/include/BooleanClause.h b/include/BooleanClause.h index 8118f4b8..70aed799 100644 --- a/include/BooleanClause.h +++ b/include/BooleanClause.h @@ -9,53 +9,52 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A clause in a BooleanQuery. - class LPPAPI BooleanClause : public LuceneObject - { - public: - /// Specifies how clauses are to occur in matching documents. - enum Occur - { - /// Use this operator for clauses that must appear in the matching documents. - MUST, - - /// Use this operator for clauses that should appear in the matching documents. For a BooleanQuery - /// with no MUST clauses one or more SHOULD clauses must match a document for the BooleanQuery to match. - /// @see BooleanQuery#setMinimumNumberShouldMatch - SHOULD, - - /// Use this operator for clauses that must not appear in the matching documents. Note that it is not - /// possible to search for queries that only consist of a MUST_NOT clause. - MUST_NOT - }; - - public: - BooleanClause(const QueryPtr& query, Occur occur); - virtual ~BooleanClause(); - - LUCENE_CLASS(BooleanClause); - - protected: - /// The query whose matching documents are combined by the boolean query. - QueryPtr query; - Occur occur; - - public: - Occur getOccur(); - void setOccur(Occur occur); - - QueryPtr getQuery(); - void setQuery(const QueryPtr& query); - - bool isProhibited(); - bool isRequired(); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual String toString(); +namespace Lucene { + +/// A clause in a BooleanQuery. +class LPPAPI BooleanClause : public LuceneObject { +public: + /// Specifies how clauses are to occur in matching documents. + enum Occur { + /// Use this operator for clauses that must appear in the matching documents. + MUST, + + /// Use this operator for clauses that should appear in the matching documents. For a BooleanQuery + /// with no MUST clauses one or more SHOULD clauses must match a document for the BooleanQuery to match. + /// @see BooleanQuery#setMinimumNumberShouldMatch + SHOULD, + + /// Use this operator for clauses that must not appear in the matching documents. Note that it is not + /// possible to search for queries that only consist of a MUST_NOT clause. + MUST_NOT }; + +public: + BooleanClause(const QueryPtr& query, Occur occur); + virtual ~BooleanClause(); + + LUCENE_CLASS(BooleanClause); + +protected: + /// The query whose matching documents are combined by the boolean query. + QueryPtr query; + Occur occur; + +public: + Occur getOccur(); + void setOccur(Occur occur); + + QueryPtr getQuery(); + void setQuery(const QueryPtr& query); + + bool isProhibited(); + bool isRequired(); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual String toString(); +}; + } #endif diff --git a/include/BooleanQuery.h b/include/BooleanQuery.h index 09d2ca44..29f1634e 100644 --- a/include/BooleanQuery.h +++ b/include/BooleanQuery.h @@ -11,92 +11,92 @@ #include "BooleanClause.h" #include "Weight.h" -namespace Lucene -{ - /// A Query that matches documents matching boolean combinations of other queries, eg. {@link TermQuery}s, - /// {@link PhraseQuery}s or other BooleanQuerys. - class LPPAPI BooleanQuery : public Query - { - public: - /// Constructs an empty boolean query. - /// - /// {@link Similarity#coord(int32_t, int32_t)} may be disabled in scoring, as appropriate. For example, - /// this score factor does not make sense for most automatically generated queries, like {@link WildcardQuery} - /// and {@link FuzzyQuery}. - /// - /// @param disableCoord disables {@link Similarity#coord(int32_t, int32_t)} in scoring. - BooleanQuery(bool disableCoord = false); - virtual ~BooleanQuery(); - - LUCENE_CLASS(BooleanQuery); - - protected: - static int32_t maxClauseCount; - - Collection clauses; - bool disableCoord; - int32_t minNrShouldMatch; - - public: - using Query::toString; - - /// Return the maximum number of clauses permitted, 1024 by default. Attempts to add more than the permitted - /// number of clauses cause TooManyClauses to be thrown. - /// @see #setMaxClauseCount(int32_t) - static int32_t getMaxClauseCount(); - - /// Set the maximum number of clauses permitted per BooleanQuery. Default value is 1024. - static void setMaxClauseCount(int32_t maxClauseCount); - - /// Returns true if {@link Similarity#coord(int32_t, int32_t)} is disabled in scoring for this query instance. - /// @see #BooleanQuery(bool) - bool isCoordDisabled(); - - /// Implement coord disabling. - virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); - - /// Specifies a minimum number of the optional BooleanClauses which must be satisfied. - /// - /// By default no optional clauses are necessary for a match (unless there are no required clauses). If this - /// method is used, then the specified number of clauses is required. - /// - /// Use of this method is totally independent of specifying that any specific clauses are required (or prohibited). - /// This number will only be compared against the number of matching optional clauses. - /// - /// @param min the number of optional clauses that must match - void setMinimumNumberShouldMatch(int32_t min); - - /// Gets the minimum number of the optional BooleanClauses which must be satisfied. - int32_t getMinimumNumberShouldMatch(); - - /// Adds a clause to a boolean query. - /// @see #getMaxClauseCount() - void add(const QueryPtr& query, BooleanClause::Occur occur); - - /// Adds a clause to a boolean query. - /// @see #getMaxClauseCount() - void add(const BooleanClausePtr& clause); - - /// Returns the set of clauses in this query. - Collection getClauses(); - - /// Returns an iterator on the clauses in this query. - Collection::iterator begin(); - Collection::iterator end(); - - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - virtual void extractTerms(SetTerm terms); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - friend class BooleanWeight; - }; +namespace Lucene { + +/// A Query that matches documents matching boolean combinations of other queries, eg. {@link TermQuery}s, +/// {@link PhraseQuery}s or other BooleanQuerys. +class LPPAPI BooleanQuery : public Query { +public: + /// Constructs an empty boolean query. + /// + /// {@link Similarity#coord(int32_t, int32_t)} may be disabled in scoring, as appropriate. For example, + /// this score factor does not make sense for most automatically generated queries, like {@link WildcardQuery} + /// and {@link FuzzyQuery}. + /// + /// @param disableCoord disables {@link Similarity#coord(int32_t, int32_t)} in scoring. + BooleanQuery(bool disableCoord = false); + virtual ~BooleanQuery(); + + LUCENE_CLASS(BooleanQuery); + +protected: + static int32_t maxClauseCount; + + Collection clauses; + bool disableCoord; + int32_t minNrShouldMatch; + +public: + using Query::toString; + + /// Return the maximum number of clauses permitted, 1024 by default. Attempts to add more than the permitted + /// number of clauses cause TooManyClauses to be thrown. + /// @see #setMaxClauseCount(int32_t) + static int32_t getMaxClauseCount(); + + /// Set the maximum number of clauses permitted per BooleanQuery. Default value is 1024. + static void setMaxClauseCount(int32_t maxClauseCount); + + /// Returns true if {@link Similarity#coord(int32_t, int32_t)} is disabled in scoring for this query instance. + /// @see #BooleanQuery(bool) + bool isCoordDisabled(); + + /// Implement coord disabling. + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); + + /// Specifies a minimum number of the optional BooleanClauses which must be satisfied. + /// + /// By default no optional clauses are necessary for a match (unless there are no required clauses). If this + /// method is used, then the specified number of clauses is required. + /// + /// Use of this method is totally independent of specifying that any specific clauses are required (or prohibited). + /// This number will only be compared against the number of matching optional clauses. + /// + /// @param min the number of optional clauses that must match + void setMinimumNumberShouldMatch(int32_t min); + + /// Gets the minimum number of the optional BooleanClauses which must be satisfied. + int32_t getMinimumNumberShouldMatch(); + + /// Adds a clause to a boolean query. + /// @see #getMaxClauseCount() + void add(const QueryPtr& query, BooleanClause::Occur occur); + + /// Adds a clause to a boolean query. + /// @see #getMaxClauseCount() + void add(const BooleanClausePtr& clause); + + /// Returns the set of clauses in this query. + Collection getClauses(); + + /// Returns an iterator on the clauses in this query. + Collection::iterator begin(); + Collection::iterator end(); + + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + virtual void extractTerms(SetTerm terms); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + friend class BooleanWeight; +}; + } #endif diff --git a/include/BooleanScorer.h b/include/BooleanScorer.h index b8ff1397..fa02a9d8 100644 --- a/include/BooleanScorer.h +++ b/include/BooleanScorer.h @@ -10,151 +10,146 @@ #include "Scorer.h" #include "Collector.h" -namespace Lucene -{ - /// BooleanScorer uses a ~16k array to score windows of docs. So it scores docs 0-16k first, then docs 16-32k, - /// etc. For each window it iterates through all query terms and accumulates a score in table[doc%16k]. It also - /// stores in the table a bitmask representing which terms contributed to the score. Non-zero scores are chained - /// in a linked list. At the end of scoring each window it then iterates through the linked list and, if the - /// bitmask matches the boolean constraints, collects a hit. For boolean queries with lots of frequent terms this - /// can be much faster, since it does not need to update a priority queue for each posting, instead performing - /// constant-time operations per posting. The only downside is that it results in hits being delivered out-of-order - /// within the window, which means it cannot be nested within other scorers. But it works well as a top-level scorer. - /// - /// The new BooleanScorer2 implementation instead works by merging priority queues of postings, albeit with some - /// clever tricks. For example, a pure conjunction (all terms required) does not require a priority queue. Instead it - /// sorts the posting streams at the start, then repeatedly skips the first to to the last. If the first ever equals - /// the last, then there's a hit. When some terms are required and some terms are optional, the conjunction can - /// be evaluated first, then the optional terms can all skip to the match and be added to the score. Thus the - /// conjunction can reduce the number of priority queue updates for the optional terms. - class BooleanScorer : public Scorer - { - public: - BooleanScorer(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers); - virtual ~BooleanScorer(); - - LUCENE_CLASS(BooleanScorer); - - protected: - SubScorerPtr scorers; - BucketTablePtr bucketTable; - int32_t maxCoord; - Collection coordFactors; - int32_t requiredMask; - int32_t prohibitedMask; - int32_t nextMask; - int32_t minNrShouldMatch; - int32_t end; - BucketPtr current; - int32_t doc; - - protected: - // firstDocID is ignored since nextDoc() initializes 'current' - virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); - - public: - virtual int32_t advance(int32_t target); - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual double score(); - virtual void score(const CollectorPtr& collector); - virtual String toString(); - }; - - class BooleanScorerCollector : public Collector - { - public: - BooleanScorerCollector(int32_t mask, const BucketTablePtr& bucketTable); - virtual ~BooleanScorerCollector(); - - LUCENE_CLASS(BooleanScorerCollector); - - protected: - BucketTableWeakPtr _bucketTable; - int32_t mask; - ScorerWeakPtr _scorer; - - public: - virtual void collect(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setScorer(const ScorerPtr& scorer); - virtual bool acceptsDocsOutOfOrder(); - }; - - // An internal class which is used in score(Collector, int32_t) for setting the current score. This is required - // since Collector exposes a setScorer method and implementations that need the score will call scorer->score(). - // Therefore the only methods that are implemented are score() and doc(). - class BucketScorer : public Scorer - { - public: - BucketScorer(); - virtual ~BucketScorer(); - - LUCENE_CLASS(BucketScorer); - - public: - double _score; - int32_t doc; - - public: - virtual int32_t advance(int32_t target); - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual double score(); - }; - - class Bucket : public LuceneObject - { - public: - Bucket(); - virtual ~Bucket(); - - LUCENE_CLASS(Bucket); - - public: - int32_t doc; // tells if bucket is valid - double score; // incremental score - int32_t bits; // used for bool constraints - int32_t coord; // count of terms in score - BucketWeakPtr _next; // next valid bucket - }; - - /// A simple hash table of document scores within a range. - class BucketTable : public LuceneObject - { - public: - BucketTable(); - virtual ~BucketTable(); - - LUCENE_CLASS(BucketTable); - - public: - static const int32_t SIZE; - static const int32_t MASK; - - Collection buckets; - BucketPtr first; // head of valid list - - public: - CollectorPtr newCollector(int32_t mask); - int32_t size(); - }; - - class SubScorer : public LuceneObject - { - public: - SubScorer(const ScorerPtr& scorer, bool required, bool prohibited, const CollectorPtr& collector, const SubScorerPtr& next); - virtual ~SubScorer(); - - LUCENE_CLASS(SubScorer); - - public: - ScorerPtr scorer; - bool required; - bool prohibited; - CollectorPtr collector; - SubScorerPtr next; - }; +namespace Lucene { + +/// BooleanScorer uses a ~16k array to score windows of docs. So it scores docs 0-16k first, then docs 16-32k, +/// etc. For each window it iterates through all query terms and accumulates a score in table[doc%16k]. It also +/// stores in the table a bitmask representing which terms contributed to the score. Non-zero scores are chained +/// in a linked list. At the end of scoring each window it then iterates through the linked list and, if the +/// bitmask matches the boolean constraints, collects a hit. For boolean queries with lots of frequent terms this +/// can be much faster, since it does not need to update a priority queue for each posting, instead performing +/// constant-time operations per posting. The only downside is that it results in hits being delivered out-of-order +/// within the window, which means it cannot be nested within other scorers. But it works well as a top-level scorer. +/// +/// The new BooleanScorer2 implementation instead works by merging priority queues of postings, albeit with some +/// clever tricks. For example, a pure conjunction (all terms required) does not require a priority queue. Instead it +/// sorts the posting streams at the start, then repeatedly skips the first to to the last. If the first ever equals +/// the last, then there's a hit. When some terms are required and some terms are optional, the conjunction can +/// be evaluated first, then the optional terms can all skip to the match and be added to the score. Thus the +/// conjunction can reduce the number of priority queue updates for the optional terms. +class BooleanScorer : public Scorer { +public: + BooleanScorer(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers); + virtual ~BooleanScorer(); + + LUCENE_CLASS(BooleanScorer); + +protected: + SubScorerPtr scorers; + BucketTablePtr bucketTable; + int32_t maxCoord; + Collection coordFactors; + int32_t requiredMask; + int32_t prohibitedMask; + int32_t nextMask; + int32_t minNrShouldMatch; + int32_t end; + BucketPtr current; + int32_t doc; + +protected: + // firstDocID is ignored since nextDoc() initializes 'current' + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); + +public: + virtual int32_t advance(int32_t target); + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual double score(); + virtual void score(const CollectorPtr& collector); + virtual String toString(); +}; + +class BooleanScorerCollector : public Collector { +public: + BooleanScorerCollector(int32_t mask, const BucketTablePtr& bucketTable); + virtual ~BooleanScorerCollector(); + + LUCENE_CLASS(BooleanScorerCollector); + +protected: + BucketTableWeakPtr _bucketTable; + int32_t mask; + ScorerWeakPtr _scorer; + +public: + virtual void collect(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); + virtual bool acceptsDocsOutOfOrder(); +}; + +// An internal class which is used in score(Collector, int32_t) for setting the current score. This is required +// since Collector exposes a setScorer method and implementations that need the score will call scorer->score(). +// Therefore the only methods that are implemented are score() and doc(). +class BucketScorer : public Scorer { +public: + BucketScorer(); + virtual ~BucketScorer(); + + LUCENE_CLASS(BucketScorer); + +public: + double _score; + int32_t doc; + +public: + virtual int32_t advance(int32_t target); + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual double score(); +}; + +class Bucket : public LuceneObject { +public: + Bucket(); + virtual ~Bucket(); + + LUCENE_CLASS(Bucket); + +public: + int32_t doc; // tells if bucket is valid + double score; // incremental score + int32_t bits; // used for bool constraints + int32_t coord; // count of terms in score + BucketWeakPtr _next; // next valid bucket +}; + +/// A simple hash table of document scores within a range. +class BucketTable : public LuceneObject { +public: + BucketTable(); + virtual ~BucketTable(); + + LUCENE_CLASS(BucketTable); + +public: + static const int32_t SIZE; + static const int32_t MASK; + + Collection buckets; + BucketPtr first; // head of valid list + +public: + CollectorPtr newCollector(int32_t mask); + int32_t size(); +}; + +class SubScorer : public LuceneObject { +public: + SubScorer(const ScorerPtr& scorer, bool required, bool prohibited, const CollectorPtr& collector, const SubScorerPtr& next); + virtual ~SubScorer(); + + LUCENE_CLASS(SubScorer); + +public: + ScorerPtr scorer; + bool required; + bool prohibited; + CollectorPtr collector; + SubScorerPtr next; +}; + } #endif diff --git a/include/BooleanScorer2.h b/include/BooleanScorer2.h index 9993b21e..b4f4bbc1 100644 --- a/include/BooleanScorer2.h +++ b/include/BooleanScorer2.h @@ -10,161 +10,157 @@ #include "DisjunctionSumScorer.h" #include "ConjunctionScorer.h" -namespace Lucene -{ - /// See the description in BooleanScorer, comparing BooleanScorer & BooleanScorer2 +namespace Lucene { + +/// See the description in BooleanScorer, comparing BooleanScorer & BooleanScorer2 +/// +/// An alternative to BooleanScorer that also allows a minimum number of optional scorers that should match. +/// Implements skipTo(), and has no limitations on the numbers of added scorers. +/// Uses ConjunctionScorer, DisjunctionScorer, ReqOptScorer and ReqExclScorer. +class BooleanScorer2 : public Scorer { +public: + /// Creates a {@link Scorer} with the given similarity and lists of required, prohibited and optional + /// scorers. In no required scorers are added, at least one of the optional scorers will have to match + /// during the search. /// - /// An alternative to BooleanScorer that also allows a minimum number of optional scorers that should match. - /// Implements skipTo(), and has no limitations on the numbers of added scorers. - /// Uses ConjunctionScorer, DisjunctionScorer, ReqOptScorer and ReqExclScorer. - class BooleanScorer2 : public Scorer - { - public: - /// Creates a {@link Scorer} with the given similarity and lists of required, prohibited and optional - /// scorers. In no required scorers are added, at least one of the optional scorers will have to match - /// during the search. - /// - /// @param similarity The similarity to be used. - /// @param minNrShouldMatch The minimum number of optional added scorers that should match during the search. - /// In case no required scorers are added, at least one of the optional scorers will have to match during - /// the search. - /// @param required The list of required scorers. - /// @param prohibited The list of prohibited scorers. - /// @param optional The list of optional scorers. - BooleanScorer2(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional); - - virtual ~BooleanScorer2(); - - LUCENE_CLASS(BooleanScorer2); - - protected: - Collection requiredScorers; - Collection optionalScorers; - Collection prohibitedScorers; - - CoordinatorPtr coordinator; - - /// The scorer to which all scoring will be delegated, except for computing and using the coordination factor. - ScorerPtr countingSumScorer; - - int32_t minNrShouldMatch; - int32_t doc; - - public: - virtual void initialize(); - - /// Scores and collects all matching documents. - /// @param collector The collector to which all matching documents are passed through. - virtual void score(const CollectorPtr& collector); - - virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual double score(); - virtual int32_t advance(int32_t target); - - protected: - ScorerPtr countingDisjunctionSumScorer(Collection scorers, int32_t minNrShouldMatch); - ScorerPtr countingConjunctionSumScorer(Collection requiredScorers); - ScorerPtr dualConjunctionSumScorer(const ScorerPtr& req1, const ScorerPtr& req2); - - /// Returns the scorer to be used for match counting and score summing. Uses requiredScorers, optionalScorers - /// and prohibitedScorers. - ScorerPtr makeCountingSumScorer(); - ScorerPtr makeCountingSumScorerNoReq(); - ScorerPtr makeCountingSumScorerSomeReq(); - - /// Returns the scorer to be used for match counting and score summing. Uses the given required scorer and - /// the prohibitedScorers. - /// @param requiredCountingSumScorer A required scorer already built. - ScorerPtr addProhibitedScorers(const ScorerPtr& requiredCountingSumScorer); - - friend class CountingDisjunctionSumScorer; - friend class CountingConjunctionSumScorer; - }; - - class Coordinator : public LuceneObject - { - public: - Coordinator(const BooleanScorer2Ptr& scorer); - virtual ~Coordinator(); - - LUCENE_CLASS(Coordinator); - - public: - BooleanScorer2WeakPtr _scorer; - Collection coordFactors; - int32_t maxCoord; // to be increased for each non prohibited scorer - int32_t nrMatchers; // to be increased by score() of match counting scorers. - - public: - void init(); // use after all scorers have been added. - - friend class BooleanScorer2; - }; - - /// Count a scorer as a single match. - class SingleMatchScorer : public Scorer - { - public: - SingleMatchScorer(const ScorerPtr& scorer, const CoordinatorPtr& coordinator); - virtual ~SingleMatchScorer(); - - LUCENE_CLASS(SingleMatchScorer); - - protected: - ScorerPtr scorer; - CoordinatorPtr coordinator; - int32_t lastScoredDoc; - double lastDocScore; - - public: - virtual double score(); - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - }; - - class CountingDisjunctionSumScorer : public DisjunctionSumScorer - { - public: - CountingDisjunctionSumScorer(const BooleanScorer2Ptr& scorer, Collection subScorers, int32_t minimumNrMatchers); - virtual ~CountingDisjunctionSumScorer(); + /// @param similarity The similarity to be used. + /// @param minNrShouldMatch The minimum number of optional added scorers that should match during the search. + /// In case no required scorers are added, at least one of the optional scorers will have to match during + /// the search. + /// @param required The list of required scorers. + /// @param prohibited The list of prohibited scorers. + /// @param optional The list of optional scorers. + BooleanScorer2(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional); + + virtual ~BooleanScorer2(); + + LUCENE_CLASS(BooleanScorer2); + +protected: + Collection requiredScorers; + Collection optionalScorers; + Collection prohibitedScorers; + + CoordinatorPtr coordinator; + + /// The scorer to which all scoring will be delegated, except for computing and using the coordination factor. + ScorerPtr countingSumScorer; + + int32_t minNrShouldMatch; + int32_t doc; - LUCENE_CLASS(CountingDisjunctionSumScorer); +public: + virtual void initialize(); + + /// Scores and collects all matching documents. + /// @param collector The collector to which all matching documents are passed through. + virtual void score(const CollectorPtr& collector); + + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual double score(); + virtual int32_t advance(int32_t target); + +protected: + ScorerPtr countingDisjunctionSumScorer(Collection scorers, int32_t minNrShouldMatch); + ScorerPtr countingConjunctionSumScorer(Collection requiredScorers); + ScorerPtr dualConjunctionSumScorer(const ScorerPtr& req1, const ScorerPtr& req2); + + /// Returns the scorer to be used for match counting and score summing. Uses requiredScorers, optionalScorers + /// and prohibitedScorers. + ScorerPtr makeCountingSumScorer(); + ScorerPtr makeCountingSumScorerNoReq(); + ScorerPtr makeCountingSumScorerSomeReq(); + + /// Returns the scorer to be used for match counting and score summing. Uses the given required scorer and + /// the prohibitedScorers. + /// @param requiredCountingSumScorer A required scorer already built. + ScorerPtr addProhibitedScorers(const ScorerPtr& requiredCountingSumScorer); + + friend class CountingDisjunctionSumScorer; + friend class CountingConjunctionSumScorer; +}; + +class Coordinator : public LuceneObject { +public: + Coordinator(const BooleanScorer2Ptr& scorer); + virtual ~Coordinator(); + + LUCENE_CLASS(Coordinator); + +public: + BooleanScorer2WeakPtr _scorer; + Collection coordFactors; + int32_t maxCoord; // to be increased for each non prohibited scorer + int32_t nrMatchers; // to be increased by score() of match counting scorers. + +public: + void init(); // use after all scorers have been added. + + friend class BooleanScorer2; +}; + +/// Count a scorer as a single match. +class SingleMatchScorer : public Scorer { +public: + SingleMatchScorer(const ScorerPtr& scorer, const CoordinatorPtr& coordinator); + virtual ~SingleMatchScorer(); + + LUCENE_CLASS(SingleMatchScorer); + +protected: + ScorerPtr scorer; + CoordinatorPtr coordinator; + int32_t lastScoredDoc; + double lastDocScore; + +public: + virtual double score(); + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); +}; + +class CountingDisjunctionSumScorer : public DisjunctionSumScorer { +public: + CountingDisjunctionSumScorer(const BooleanScorer2Ptr& scorer, Collection subScorers, int32_t minimumNrMatchers); + virtual ~CountingDisjunctionSumScorer(); + + LUCENE_CLASS(CountingDisjunctionSumScorer); + +protected: + BooleanScorer2WeakPtr _scorer; + int32_t lastScoredDoc; + + // Save the score of lastScoredDoc, so that we don't compute it more than once in score(). + double lastDocScore; + +public: + virtual double score(); + + friend class BooleanScorer2; +}; + +class CountingConjunctionSumScorer : public ConjunctionScorer { +public: + CountingConjunctionSumScorer(const BooleanScorer2Ptr& scorer, const SimilarityPtr& similarity, Collection scorers); + virtual ~CountingConjunctionSumScorer(); + + LUCENE_CLASS(CountingConjunctionSumScorer); + +protected: + BooleanScorer2WeakPtr _scorer; + int32_t lastScoredDoc; + int32_t requiredNrMatchers; + + // Save the score of lastScoredDoc, so that we don't compute it more than once in score(). + double lastDocScore; + +public: + virtual double score(); +}; - protected: - BooleanScorer2WeakPtr _scorer; - int32_t lastScoredDoc; - - // Save the score of lastScoredDoc, so that we don't compute it more than once in score(). - double lastDocScore; - - public: - virtual double score(); - - friend class BooleanScorer2; - }; - - class CountingConjunctionSumScorer : public ConjunctionScorer - { - public: - CountingConjunctionSumScorer(const BooleanScorer2Ptr& scorer, const SimilarityPtr& similarity, Collection scorers); - virtual ~CountingConjunctionSumScorer(); - - LUCENE_CLASS(CountingConjunctionSumScorer); - - protected: - BooleanScorer2WeakPtr _scorer; - int32_t lastScoredDoc; - int32_t requiredNrMatchers; - - // Save the score of lastScoredDoc, so that we don't compute it more than once in score(). - double lastDocScore; - - public: - virtual double score(); - }; } #endif diff --git a/include/BufferedDeletes.h b/include/BufferedDeletes.h index 21dba121..b54c811b 100644 --- a/include/BufferedDeletes.h +++ b/include/BufferedDeletes.h @@ -10,49 +10,48 @@ #include "Term.h" #include "Query.h" -namespace Lucene -{ - /// Holds buffered deletes, by docID, term or query. We hold two instances of this class: one for - /// the deletes prior to the last flush, the other for deletes after the last flush. This is so if - /// we need to abort (discard all buffered docs) we can also discard the buffered deletes yet keep - /// the deletes done during previously flushed segments. - class BufferedDeletes : public LuceneObject - { - public: - BufferedDeletes(bool doTermSort); - virtual ~BufferedDeletes(); - - LUCENE_CLASS(BufferedDeletes); - - public: - int32_t numTerms; - MapTermNum terms; - MapQueryInt queries; - Collection docIDs; - int64_t bytesUsed; - - public: - int32_t size(); - void update(const BufferedDeletesPtr& in); - void clear(); - void addBytesUsed(int64_t b); - bool any(); - void remap(const MergeDocIDRemapperPtr& mapper, const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount); - }; - - /// Number of documents a delete term applies to. - class Num : public LuceneObject - { - public: - Num(int32_t num); - - protected: - int32_t num; - - public: - int32_t getNum(); - void setNum(int32_t num); - }; +namespace Lucene { + +/// Holds buffered deletes, by docID, term or query. We hold two instances of this class: one for +/// the deletes prior to the last flush, the other for deletes after the last flush. This is so if +/// we need to abort (discard all buffered docs) we can also discard the buffered deletes yet keep +/// the deletes done during previously flushed segments. +class BufferedDeletes : public LuceneObject { +public: + BufferedDeletes(bool doTermSort); + virtual ~BufferedDeletes(); + + LUCENE_CLASS(BufferedDeletes); + +public: + int32_t numTerms; + MapTermNum terms; + MapQueryInt queries; + Collection docIDs; + int64_t bytesUsed; + +public: + int32_t size(); + void update(const BufferedDeletesPtr& in); + void clear(); + void addBytesUsed(int64_t b); + bool any(); + void remap(const MergeDocIDRemapperPtr& mapper, const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount); +}; + +/// Number of documents a delete term applies to. +class Num : public LuceneObject { +public: + Num(int32_t num); + +protected: + int32_t num; + +public: + int32_t getNum(); + void setNum(int32_t num); +}; + } #endif diff --git a/include/BufferedIndexInput.h b/include/BufferedIndexInput.h index 14ecea4b..e71b514f 100644 --- a/include/BufferedIndexInput.h +++ b/include/BufferedIndexInput.h @@ -9,97 +9,97 @@ #include "IndexInput.h" -namespace Lucene -{ - /// Base implementation class for buffered {@link IndexInput}. - class LPPAPI BufferedIndexInput : public IndexInput - { - public: - /// Construct BufferedIndexInput with a specific bufferSize. - BufferedIndexInput(int32_t bufferSize = BUFFER_SIZE); - virtual ~BufferedIndexInput(); - - LUCENE_CLASS(BufferedIndexInput); - - public: - /// Default buffer size. - static const int32_t BUFFER_SIZE; - - protected: - int32_t bufferSize; - int64_t bufferStart; // position in file of buffer - int32_t bufferLength; // end of valid bytes - int32_t bufferPosition; // next byte to read - ByteArray buffer; - - public: - /// Reads and returns a single byte. - /// @see IndexOutput#writeByte(uint8_t) - virtual uint8_t readByte(); - - /// Change the buffer size used by this IndexInput. - void setBufferSize(int32_t newSize); - - /// Returns buffer size. - /// @see #setBufferSize - int32_t getBufferSize(); - - /// Reads a specified number of bytes into an array at the specified offset. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - /// @see IndexOutput#writeBytes(const uint8_t*,int) - /// @see #readInternal(uint8_t*, int32_t, int32_t) - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - - /// Reads a specified number of bytes into an array at the specified offset with control over whether the - /// read should be buffered (callers who have their own buffer should pass in "false" for useBuffer). - /// Currently only {@link BufferedIndexInput} respects this parameter. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - /// @param useBuffer set to false if the caller will handle buffering. - /// @see IndexOutput#writeBytes(const uint8_t*,int) - /// @see #readInternal(uint8_t*, int32_t, int32_t) - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer); - - /// Closes the stream to further operations. - virtual void close(); - - /// Returns the current position in this file, where the next read will occur. - /// @see #seek(int64_t) - virtual int64_t getFilePointer(); - - /// Sets current position in this file, where the next read will occur. - /// @see #getFilePointer() - /// @see #seekInternal(int64_t) - virtual void seek(int64_t pos); - - /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - protected: - virtual void newBuffer(ByteArray newBuffer); - - void checkBufferSize(int32_t bufferSize); - - /// Refill buffer in preparation for reading. - /// @see #readInternal(uint8_t*, int32_t, int32_t) - /// @see #seekInternal(int64_t) - virtual void refill(); - - /// Implements buffer refill. Reads bytes from the current position in the input. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) = 0; - - /// Implements seek. Sets current position in this file, where the next {@link - /// #readInternal(uint8_t*, int32_t, int32_t)} will occur. - /// @param pos position to set next write. - /// @see #readInternal(uint8_t*, int32_t, int32_t) - virtual void seekInternal(int64_t pos) = 0; - }; +namespace Lucene { + +/// Base implementation class for buffered {@link IndexInput}. +class LPPAPI BufferedIndexInput : public IndexInput { +public: + /// Construct BufferedIndexInput with a specific bufferSize. + BufferedIndexInput(int32_t bufferSize = BUFFER_SIZE); + virtual ~BufferedIndexInput(); + + LUCENE_CLASS(BufferedIndexInput); + +public: + /// Default buffer size. + static const int32_t BUFFER_SIZE; + +protected: + int32_t bufferSize; + int64_t bufferStart; // position in file of buffer + int32_t bufferLength; // end of valid bytes + int32_t bufferPosition; // next byte to read + ByteArray buffer; + +public: + /// Reads and returns a single byte. + /// @see IndexOutput#writeByte(uint8_t) + virtual uint8_t readByte(); + + /// Change the buffer size used by this IndexInput. + void setBufferSize(int32_t newSize); + + /// Returns buffer size. + /// @see #setBufferSize + int32_t getBufferSize(); + + /// Reads a specified number of bytes into an array at the specified offset. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + /// @see IndexOutput#writeBytes(const uint8_t*,int) + /// @see #readInternal(uint8_t*, int32_t, int32_t) + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); + + /// Reads a specified number of bytes into an array at the specified offset with control over whether the + /// read should be buffered (callers who have their own buffer should pass in "false" for useBuffer). + /// Currently only {@link BufferedIndexInput} respects this parameter. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + /// @param useBuffer set to false if the caller will handle buffering. + /// @see IndexOutput#writeBytes(const uint8_t*,int) + /// @see #readInternal(uint8_t*, int32_t, int32_t) + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer); + + /// Closes the stream to further operations. + virtual void close(); + + /// Returns the current position in this file, where the next read will occur. + /// @see #seek(int64_t) + virtual int64_t getFilePointer(); + + /// Sets current position in this file, where the next read will occur. + /// @see #getFilePointer() + /// @see #seekInternal(int64_t) + virtual void seek(int64_t pos); + + /// Returns a clone of this stream. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + +protected: + virtual void newBuffer(ByteArray newBuffer); + + void checkBufferSize(int32_t bufferSize); + + /// Refill buffer in preparation for reading. + /// @see #readInternal(uint8_t*, int32_t, int32_t) + /// @see #seekInternal(int64_t) + virtual void refill(); + + /// Implements buffer refill. Reads bytes from the current position in the input. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) = 0; + + /// Implements seek. Sets current position in this file, where the next {@link + /// #readInternal(uint8_t*, int32_t, int32_t)} will occur. + /// @param pos position to set next write. + /// @see #readInternal(uint8_t*, int32_t, int32_t) + virtual void seekInternal(int64_t pos) = 0; +}; + } #endif diff --git a/include/BufferedIndexOutput.h b/include/BufferedIndexOutput.h index 8e0d6820..0a506217 100644 --- a/include/BufferedIndexOutput.h +++ b/include/BufferedIndexOutput.h @@ -9,67 +9,67 @@ #include "IndexOutput.h" -namespace Lucene -{ - /// Base implementation class for buffered {@link IndexOutput}. - class LPPAPI BufferedIndexOutput : public IndexOutput - { - public: - BufferedIndexOutput(); - virtual ~BufferedIndexOutput(); - - LUCENE_CLASS(BufferedIndexOutput); - - public: - static const int32_t BUFFER_SIZE; - - protected: - int64_t bufferStart; // position in file of buffer - int32_t bufferPosition; // position in buffer - ByteArray buffer; - - public: - /// Writes a single byte. - /// @see IndexInput#readByte() - virtual void writeByte(uint8_t b); - - /// Writes an array of bytes. - /// @param b the bytes to write. - /// @param length the number of bytes to write. - /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) - virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - - /// Forces any buffered output to be written. - virtual void flush(); - - /// Implements buffer write. Writes bytes at the current - /// position in the output. - /// @param b the bytes to write. - /// @param offset the offset in the byte array. - /// @param length the number of bytes to write. - virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length); - - /// Closes this stream to further operations. - virtual void close(); - - /// Returns the current position in this file, where the next write will occur. - /// @see #seek(long) - virtual int64_t getFilePointer(); - - /// Sets current position in this file, where the next write will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos); - - /// The number of bytes in the file. - virtual int64_t length() = 0; - - protected: - /// Implements buffer write. Writes bytes at the current - /// position in the output. - /// @param b the bytes to write. - /// @param length the number of bytes to write. - void flushBuffer(const uint8_t* b, int32_t length); - }; +namespace Lucene { + +/// Base implementation class for buffered {@link IndexOutput}. +class LPPAPI BufferedIndexOutput : public IndexOutput { +public: + BufferedIndexOutput(); + virtual ~BufferedIndexOutput(); + + LUCENE_CLASS(BufferedIndexOutput); + +public: + static const int32_t BUFFER_SIZE; + +protected: + int64_t bufferStart; // position in file of buffer + int32_t bufferPosition; // position in buffer + ByteArray buffer; + +public: + /// Writes a single byte. + /// @see IndexInput#readByte() + virtual void writeByte(uint8_t b); + + /// Writes an array of bytes. + /// @param b the bytes to write. + /// @param length the number of bytes to write. + /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) + virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); + + /// Forces any buffered output to be written. + virtual void flush(); + + /// Implements buffer write. Writes bytes at the current + /// position in the output. + /// @param b the bytes to write. + /// @param offset the offset in the byte array. + /// @param length the number of bytes to write. + virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length); + + /// Closes this stream to further operations. + virtual void close(); + + /// Returns the current position in this file, where the next write will occur. + /// @see #seek(long) + virtual int64_t getFilePointer(); + + /// Sets current position in this file, where the next write will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos); + + /// The number of bytes in the file. + virtual int64_t length() = 0; + +protected: + /// Implements buffer write. Writes bytes at the current + /// position in the output. + /// @param b the bytes to write. + /// @param length the number of bytes to write. + void flushBuffer(const uint8_t* b, int32_t length); +}; + } #endif diff --git a/include/BufferedReader.h b/include/BufferedReader.h index 9cf22920..8bbf3f4b 100644 --- a/include/BufferedReader.h +++ b/include/BufferedReader.h @@ -9,55 +9,55 @@ #include "Reader.h" -namespace Lucene -{ - /// Read text from a character-input stream, buffering characters so as to provide - /// for the efficient reading of characters, arrays, and lines. - class LPPAPI BufferedReader : public Reader - { - public: - /// Create a buffering character-input stream. - BufferedReader(const ReaderPtr& reader, int32_t size = READER_BUFFER); - virtual ~BufferedReader(); - - LUCENE_CLASS(BufferedReader); - - protected: - ReaderPtr reader; - int32_t bufferSize; - int32_t bufferLength; // end of valid bytes - int32_t bufferPosition; // next byte to read - CharArray buffer; - - public: - static const int32_t READER_BUFFER; - - public: - /// Read a single character. - virtual int32_t read(); - - /// Read characters into a portion of an array. - virtual int32_t read(wchar_t* b, int32_t offset, int32_t length); - - /// Read a line of text. - virtual bool readLine(String& line); - - /// Close the stream. - virtual void close(); - - /// Tell whether this stream supports the mark() operation - virtual bool markSupported(); - - /// Reset the stream. - virtual void reset(); - - protected: - /// Refill buffer in preparation for reading. - int32_t refill(); - - /// Read a single character without moving position. - int32_t peek(); - }; +namespace Lucene { + +/// Read text from a character-input stream, buffering characters so as to provide +/// for the efficient reading of characters, arrays, and lines. +class LPPAPI BufferedReader : public Reader { +public: + /// Create a buffering character-input stream. + BufferedReader(const ReaderPtr& reader, int32_t size = READER_BUFFER); + virtual ~BufferedReader(); + + LUCENE_CLASS(BufferedReader); + +protected: + ReaderPtr reader; + int32_t bufferSize; + int32_t bufferLength; // end of valid bytes + int32_t bufferPosition; // next byte to read + CharArray buffer; + +public: + static const int32_t READER_BUFFER; + +public: + /// Read a single character. + virtual int32_t read(); + + /// Read characters into a portion of an array. + virtual int32_t read(wchar_t* b, int32_t offset, int32_t length); + + /// Read a line of text. + virtual bool readLine(String& line); + + /// Close the stream. + virtual void close(); + + /// Tell whether this stream supports the mark() operation + virtual bool markSupported(); + + /// Reset the stream. + virtual void reset(); + +protected: + /// Refill buffer in preparation for reading. + int32_t refill(); + + /// Read a single character without moving position. + int32_t peek(); +}; + } #endif diff --git a/include/ByteBlockPool.h b/include/ByteBlockPool.h index 8a3a981d..7b084f2e 100644 --- a/include/ByteBlockPool.h +++ b/include/ByteBlockPool.h @@ -9,61 +9,60 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Class that Posting and PostingVector use to write byte streams into shared fixed-size byte[] arrays. - /// The idea is to allocate slices of increasing lengths. For example, the first slice is 5 bytes, the - /// next slice is 14, etc. We start by writing our bytes into the first 5 bytes. When we hit the end of - /// the slice, we allocate the next slice and then write the address of the new slice into the last 4 - /// bytes of the previous slice (the "forwarding address"). - /// - /// Each slice is filled with 0's initially, and we mark the end with a non-zero byte. This way the methods - /// that are writing into the slice don't need to record its length and instead allocate a new slice once - /// they hit a non-zero byte. - class ByteBlockPool : public LuceneObject - { - public: - ByteBlockPool(const ByteBlockPoolAllocatorBasePtr& allocator, bool trackAllocations); - virtual ~ByteBlockPool(); - - LUCENE_CLASS(ByteBlockPool); - - public: - Collection buffers; - int32_t bufferUpto; // Which buffer we are up to - int32_t byteUpto; // Where we are in head buffer - - ByteArray buffer; - int32_t byteOffset; - - static const int32_t nextLevelArray[]; - static const int32_t levelSizeArray[]; - - protected: - bool trackAllocations; - ByteBlockPoolAllocatorBasePtr allocator; - - public: - static int32_t FIRST_LEVEL_SIZE(); - - void reset(); - void nextBuffer(); - int32_t newSlice(int32_t size); - int32_t allocSlice(ByteArray slice, int32_t upto); - }; - - class ByteBlockPoolAllocatorBase : public LuceneObject - { - public: - virtual ~ByteBlockPoolAllocatorBase(); - - LUCENE_CLASS(ByteBlockPoolAllocatorBase); - - public: - virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end) = 0; - virtual void recycleByteBlocks(Collection blocks) = 0; - virtual ByteArray getByteBlock(bool trackAllocations) = 0; - }; +namespace Lucene { + +/// Class that Posting and PostingVector use to write byte streams into shared fixed-size byte[] arrays. +/// The idea is to allocate slices of increasing lengths. For example, the first slice is 5 bytes, the +/// next slice is 14, etc. We start by writing our bytes into the first 5 bytes. When we hit the end of +/// the slice, we allocate the next slice and then write the address of the new slice into the last 4 +/// bytes of the previous slice (the "forwarding address"). +/// +/// Each slice is filled with 0's initially, and we mark the end with a non-zero byte. This way the methods +/// that are writing into the slice don't need to record its length and instead allocate a new slice once +/// they hit a non-zero byte. +class ByteBlockPool : public LuceneObject { +public: + ByteBlockPool(const ByteBlockPoolAllocatorBasePtr& allocator, bool trackAllocations); + virtual ~ByteBlockPool(); + + LUCENE_CLASS(ByteBlockPool); + +public: + Collection buffers; + int32_t bufferUpto; // Which buffer we are up to + int32_t byteUpto; // Where we are in head buffer + + ByteArray buffer; + int32_t byteOffset; + + static const int32_t nextLevelArray[]; + static const int32_t levelSizeArray[]; + +protected: + bool trackAllocations; + ByteBlockPoolAllocatorBasePtr allocator; + +public: + static int32_t FIRST_LEVEL_SIZE(); + + void reset(); + void nextBuffer(); + int32_t newSlice(int32_t size); + int32_t allocSlice(ByteArray slice, int32_t upto); +}; + +class ByteBlockPoolAllocatorBase : public LuceneObject { +public: + virtual ~ByteBlockPoolAllocatorBase(); + + LUCENE_CLASS(ByteBlockPoolAllocatorBase); + +public: + virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end) = 0; + virtual void recycleByteBlocks(Collection blocks) = 0; + virtual ByteArray getByteBlock(bool trackAllocations) = 0; +}; + } #endif diff --git a/include/ByteFieldSource.h b/include/ByteFieldSource.h index 239fd7f7..111c0e0b 100644 --- a/include/ByteFieldSource.h +++ b/include/ByteFieldSource.h @@ -9,36 +9,36 @@ #include "FieldCacheSource.h" -namespace Lucene -{ - /// Obtains byte field values from the {@link FieldCache} using getBytes() and makes those values available - /// as other numeric types, casting as needed. - /// - /// @see FieldCacheSource for requirements on the field. - /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite - /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU - /// per lookup but will not consume double the FieldCache RAM. - class LPPAPI ByteFieldSource : public FieldCacheSource - { - public: - /// Create a cached byte field source with a specific string-to-byte parser. - ByteFieldSource(const String& field, const ByteParserPtr& parser = ByteParserPtr()); - virtual ~ByteFieldSource(); - - LUCENE_CLASS(ByteFieldSource); - - protected: - ByteParserPtr parser; - - public: - virtual String description(); - virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); - virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); - virtual int32_t cachedFieldSourceHashCode(); - }; +namespace Lucene { + +/// Obtains byte field values from the {@link FieldCache} using getBytes() and makes those values available +/// as other numeric types, casting as needed. +/// +/// @see FieldCacheSource for requirements on the field. +/// +/// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite +/// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's +/// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, +/// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU +/// per lookup but will not consume double the FieldCache RAM. +class LPPAPI ByteFieldSource : public FieldCacheSource { +public: + /// Create a cached byte field source with a specific string-to-byte parser. + ByteFieldSource(const String& field, const ByteParserPtr& parser = ByteParserPtr()); + virtual ~ByteFieldSource(); + + LUCENE_CLASS(ByteFieldSource); + +protected: + ByteParserPtr parser; + +public: + virtual String description(); + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); + virtual int32_t cachedFieldSourceHashCode(); +}; + } #endif diff --git a/include/ByteSliceReader.h b/include/ByteSliceReader.h index 67edde5e..0a9234cf 100644 --- a/include/ByteSliceReader.h +++ b/include/ByteSliceReader.h @@ -9,54 +9,54 @@ #include "IndexInput.h" -namespace Lucene -{ - /// IndexInput that knows how to read the byte slices written by Posting and PostingVector. We read the bytes in each slice - /// until we hit the end of that slice at which point we read the forwarding address of the next slice and then jump to it. - class ByteSliceReader : public IndexInput - { - public: - ByteSliceReader(); - virtual ~ByteSliceReader(); - - LUCENE_CLASS(ByteSliceReader); - - public: - ByteBlockPoolPtr pool; - int32_t bufferUpto; - ByteArray buffer; - int32_t upto; - int32_t limit; - int32_t level; - int32_t bufferOffset; - int32_t endIndex; - - public: - void init(const ByteBlockPoolPtr& pool, int32_t startIndex, int32_t endIndex); - bool eof(); - - /// Reads and returns a single byte. - virtual uint8_t readByte(); - - int64_t writeTo(const IndexOutputPtr& out); - - void nextSlice(); - - /// Reads a specified number of bytes into an array at the specified offset. - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - - /// Not implemented - virtual int64_t getFilePointer(); - - /// Not implemented - virtual int64_t length(); - - /// Not implemented - virtual void seek(int64_t pos); - - /// Not implemented - virtual void close(); - }; +namespace Lucene { + +/// IndexInput that knows how to read the byte slices written by Posting and PostingVector. We read the bytes in each slice +/// until we hit the end of that slice at which point we read the forwarding address of the next slice and then jump to it. +class ByteSliceReader : public IndexInput { +public: + ByteSliceReader(); + virtual ~ByteSliceReader(); + + LUCENE_CLASS(ByteSliceReader); + +public: + ByteBlockPoolPtr pool; + int32_t bufferUpto; + ByteArray buffer; + int32_t upto; + int32_t limit; + int32_t level; + int32_t bufferOffset; + int32_t endIndex; + +public: + void init(const ByteBlockPoolPtr& pool, int32_t startIndex, int32_t endIndex); + bool eof(); + + /// Reads and returns a single byte. + virtual uint8_t readByte(); + + int64_t writeTo(const IndexOutputPtr& out); + + void nextSlice(); + + /// Reads a specified number of bytes into an array at the specified offset. + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); + + /// Not implemented + virtual int64_t getFilePointer(); + + /// Not implemented + virtual int64_t length(); + + /// Not implemented + virtual void seek(int64_t pos); + + /// Not implemented + virtual void close(); +}; + } #endif diff --git a/include/ByteSliceWriter.h b/include/ByteSliceWriter.h index 204e3bd4..f4c16e7f 100644 --- a/include/ByteSliceWriter.h +++ b/include/ByteSliceWriter.h @@ -9,37 +9,37 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Class to write byte streams into slices of shared byte[]. This is used by DocumentsWriter to hold - /// the posting list for many terms in RAM. - class ByteSliceWriter : public LuceneObject - { - public: - ByteSliceWriter(const ByteBlockPoolPtr& pool); - virtual ~ByteSliceWriter(); - - LUCENE_CLASS(ByteSliceWriter); - - protected: - ByteArray slice; - int32_t upto; - ByteBlockPoolPtr pool; - - public: - int32_t offset0; - - public: - /// Set up the writer to write at address. - void init(int32_t address); - - /// Write byte into byte slice stream - void writeByte(uint8_t b); - - void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - int32_t getAddress(); - void writeVInt(int32_t i); - }; +namespace Lucene { + +/// Class to write byte streams into slices of shared byte[]. This is used by DocumentsWriter to hold +/// the posting list for many terms in RAM. +class ByteSliceWriter : public LuceneObject { +public: + ByteSliceWriter(const ByteBlockPoolPtr& pool); + virtual ~ByteSliceWriter(); + + LUCENE_CLASS(ByteSliceWriter); + +protected: + ByteArray slice; + int32_t upto; + ByteBlockPoolPtr pool; + +public: + int32_t offset0; + +public: + /// Set up the writer to write at address. + void init(int32_t address); + + /// Write byte into byte slice stream + void writeByte(uint8_t b); + + void writeBytes(const uint8_t* b, int32_t offset, int32_t length); + int32_t getAddress(); + void writeVInt(int32_t i); +}; + } #endif diff --git a/include/CachingSpanFilter.h b/include/CachingSpanFilter.h index 218c21fe..ec7b0ad5 100644 --- a/include/CachingSpanFilter.h +++ b/include/CachingSpanFilter.h @@ -10,39 +10,39 @@ #include "SpanFilter.h" #include "CachingWrapperFilter.h" -namespace Lucene -{ - /// Wraps another SpanFilter's result and caches it. The purpose is to allow filters to simply filter, - /// and then wrap with this class to add caching. - class LPPAPI CachingSpanFilter : public SpanFilter - { - public: - /// New deletions always result in a cache miss, by default ({@link CachingWrapperFilter#RECACHE}. - CachingSpanFilter(const SpanFilterPtr& filter, CachingWrapperFilter::DeletesMode deletesMode = CachingWrapperFilter::DELETES_RECACHE); - virtual ~CachingSpanFilter(); - - LUCENE_CLASS(CachingSpanFilter); - - protected: - SpanFilterPtr filter; - FilterCachePtr cache; - - public: - // for testing - int32_t hitCount; - int32_t missCount; - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); - virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader); - - virtual String toString(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - protected: - SpanFilterResultPtr getCachedResult(const IndexReaderPtr& reader); - }; +namespace Lucene { + +/// Wraps another SpanFilter's result and caches it. The purpose is to allow filters to simply filter, +/// and then wrap with this class to add caching. +class LPPAPI CachingSpanFilter : public SpanFilter { +public: + /// New deletions always result in a cache miss, by default ({@link CachingWrapperFilter#RECACHE}. + CachingSpanFilter(const SpanFilterPtr& filter, CachingWrapperFilter::DeletesMode deletesMode = CachingWrapperFilter::DELETES_RECACHE); + virtual ~CachingSpanFilter(); + + LUCENE_CLASS(CachingSpanFilter); + +protected: + SpanFilterPtr filter; + FilterCachePtr cache; + +public: + // for testing + int32_t hitCount; + int32_t missCount; + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader); + + virtual String toString(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + +protected: + SpanFilterResultPtr getCachedResult(const IndexReaderPtr& reader); +}; + } #endif diff --git a/include/CachingTokenFilter.h b/include/CachingTokenFilter.h index 77cb44db..ab836be8 100644 --- a/include/CachingTokenFilter.h +++ b/include/CachingTokenFilter.h @@ -9,34 +9,34 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// This class can be used if the token attributes of a TokenStream are intended to be consumed more than once. - /// It caches all token attribute states locally in a List. - /// - /// CachingTokenFilter implements the optional method {@link TokenStream#reset()}, which repositions the stream - /// to the first Token. - class LPPAPI CachingTokenFilter : public TokenFilter - { - public: - CachingTokenFilter(const TokenStreamPtr& input); - virtual ~CachingTokenFilter(); - - LUCENE_CLASS(CachingTokenFilter); - - protected: - Collection cache; - Collection::iterator iterator; - AttributeSourceStatePtr finalState; - - public: - virtual bool incrementToken(); - virtual void end(); - virtual void reset(); - - protected: - void fillCache(); - }; +namespace Lucene { + +/// This class can be used if the token attributes of a TokenStream are intended to be consumed more than once. +/// It caches all token attribute states locally in a List. +/// +/// CachingTokenFilter implements the optional method {@link TokenStream#reset()}, which repositions the stream +/// to the first Token. +class LPPAPI CachingTokenFilter : public TokenFilter { +public: + CachingTokenFilter(const TokenStreamPtr& input); + virtual ~CachingTokenFilter(); + + LUCENE_CLASS(CachingTokenFilter); + +protected: + Collection cache; + Collection::iterator iterator; + AttributeSourceStatePtr finalState; + +public: + virtual bool incrementToken(); + virtual void end(); + virtual void reset(); + +protected: + void fillCache(); +}; + } #endif diff --git a/include/CachingWrapperFilter.h b/include/CachingWrapperFilter.h index 8183eb34..915925e6 100644 --- a/include/CachingWrapperFilter.h +++ b/include/CachingWrapperFilter.h @@ -9,61 +9,61 @@ #include "Filter.h" -namespace Lucene -{ - /// Wraps another filter's result and caches it. The purpose is to allow filters to simply filter, and - /// then wrap with this class to add caching. - class LPPAPI CachingWrapperFilter : public Filter - { - public: - /// Specifies how new deletions against a reopened reader should be handled. - /// - /// The default is IGNORE, which means the cache entry will be re-used for a given segment, even when - /// that segment has been reopened due to changes in deletions. This is a big performance gain, - /// especially with near-real-timer readers, since you don't hit a cache miss on every reopened reader - /// for prior segments. - /// - /// However, in some cases this can cause invalid query results, allowing deleted documents to be - /// returned. This only happens if the main query does not rule out deleted documents on its own, - /// such as a toplevel ConstantScoreQuery. To fix this, use RECACHE to re-create the cached filter - /// (at a higher per-reopen cost, but at faster subsequent search performance), or use DYNAMIC to - /// dynamically intersect deleted docs (fast reopen time but some hit to search performance). - enum DeletesMode { DELETES_IGNORE, DELETES_RECACHE, DELETES_DYNAMIC }; +namespace Lucene { - /// New deletes are ignored by default, which gives higher cache hit rate on reopened readers. - /// Most of the time this is safe, because the filter will be AND'd with a Query that fully enforces - /// deletions. If instead you need this filter to always enforce deletions, pass either {@link - /// DeletesMode#RECACHE} or {@link DeletesMode#DYNAMIC}. - CachingWrapperFilter(const FilterPtr& filter, DeletesMode deletesMode = DELETES_IGNORE); +/// Wraps another filter's result and caches it. The purpose is to allow filters to simply filter, and +/// then wrap with this class to add caching. +class LPPAPI CachingWrapperFilter : public Filter { +public: + /// Specifies how new deletions against a reopened reader should be handled. + /// + /// The default is IGNORE, which means the cache entry will be re-used for a given segment, even when + /// that segment has been reopened due to changes in deletions. This is a big performance gain, + /// especially with near-real-timer readers, since you don't hit a cache miss on every reopened reader + /// for prior segments. + /// + /// However, in some cases this can cause invalid query results, allowing deleted documents to be + /// returned. This only happens if the main query does not rule out deleted documents on its own, + /// such as a toplevel ConstantScoreQuery. To fix this, use RECACHE to re-create the cached filter + /// (at a higher per-reopen cost, but at faster subsequent search performance), or use DYNAMIC to + /// dynamically intersect deleted docs (fast reopen time but some hit to search performance). + enum DeletesMode { DELETES_IGNORE, DELETES_RECACHE, DELETES_DYNAMIC }; - virtual ~CachingWrapperFilter(); + /// New deletes are ignored by default, which gives higher cache hit rate on reopened readers. + /// Most of the time this is safe, because the filter will be AND'd with a Query that fully enforces + /// deletions. If instead you need this filter to always enforce deletions, pass either {@link + /// DeletesMode#RECACHE} or {@link DeletesMode#DYNAMIC}. + CachingWrapperFilter(const FilterPtr& filter, DeletesMode deletesMode = DELETES_IGNORE); - LUCENE_CLASS(CachingWrapperFilter); + virtual ~CachingWrapperFilter(); - INTERNAL: - FilterPtr filter; + LUCENE_CLASS(CachingWrapperFilter); - // for testing - int32_t hitCount; - int32_t missCount; +INTERNAL: + FilterPtr filter; - protected: - /// A Filter cache - FilterCachePtr cache; + // for testing + int32_t hitCount; + int32_t missCount; - /// Provide the DocIdSet to be cached, using the DocIdSet provided by the wrapped Filter. - /// - /// This implementation returns the given {@link DocIdSet}, if {@link DocIdSet#isCacheable} returns - /// true, else it copies the {@link DocIdSetIterator} into an {@link OpenBitSetDISI}. - DocIdSetPtr docIdSetToCache(const DocIdSetPtr& docIdSet, const IndexReaderPtr& reader); +protected: + /// A Filter cache + FilterCachePtr cache; - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + /// Provide the DocIdSet to be cached, using the DocIdSet provided by the wrapped Filter. + /// + /// This implementation returns the given {@link DocIdSet}, if {@link DocIdSet#isCacheable} returns + /// true, else it copies the {@link DocIdSetIterator} into an {@link OpenBitSetDISI}. + DocIdSetPtr docIdSetToCache(const DocIdSetPtr& docIdSet, const IndexReaderPtr& reader); + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + + virtual String toString(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; - virtual String toString(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; } #endif diff --git a/include/CharArraySet.h b/include/CharArraySet.h index 909a5d80..3f911606 100644 --- a/include/CharArraySet.h +++ b/include/CharArraySet.h @@ -9,48 +9,48 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A simple class that stores Strings as char[]'s in a hash table. Note that this is not a general purpose class. - /// For example, it cannot remove items from the set, nor does it resize its hash table to be smaller, etc. It is - /// designed to be quick to test if a char[] is in the set without the necessity of converting it to a String first. - class LPPAPI CharArraySet : public LuceneObject - { - public: - CharArraySet(bool ignoreCase); +namespace Lucene { - /// Create set from a set of strings. - CharArraySet(HashSet entries, bool ignoreCase); +/// A simple class that stores Strings as char[]'s in a hash table. Note that this is not a general purpose class. +/// For example, it cannot remove items from the set, nor does it resize its hash table to be smaller, etc. It is +/// designed to be quick to test if a char[] is in the set without the necessity of converting it to a String first. +class LPPAPI CharArraySet : public LuceneObject { +public: + CharArraySet(bool ignoreCase); - /// Create set from a collection of strings. - CharArraySet(Collection entries, bool ignoreCase); + /// Create set from a set of strings. + CharArraySet(HashSet entries, bool ignoreCase); - virtual ~CharArraySet(); + /// Create set from a collection of strings. + CharArraySet(Collection entries, bool ignoreCase); - LUCENE_CLASS(CharArraySet); + virtual ~CharArraySet(); - protected: - HashSet entries; - bool ignoreCase; + LUCENE_CLASS(CharArraySet); - public: - virtual bool contains(const String& text); +protected: + HashSet entries; + bool ignoreCase; - /// True if the length chars of text starting at offset are in the set - virtual bool contains(const wchar_t* text, int32_t offset, int32_t length); +public: + virtual bool contains(const String& text); - /// Add this String into the set - virtual bool add(const String& text); + /// True if the length chars of text starting at offset are in the set + virtual bool contains(const wchar_t* text, int32_t offset, int32_t length); - /// Add this char[] into the set. - virtual bool add(CharArray text); + /// Add this String into the set + virtual bool add(const String& text); - virtual int32_t size(); - virtual bool isEmpty(); + /// Add this char[] into the set. + virtual bool add(CharArray text); + + virtual int32_t size(); + virtual bool isEmpty(); + + HashSet::iterator begin(); + HashSet::iterator end(); +}; - HashSet::iterator begin(); - HashSet::iterator end(); - }; } #endif diff --git a/include/CharBlockPool.h b/include/CharBlockPool.h index 53f69319..a676b280 100644 --- a/include/CharBlockPool.h +++ b/include/CharBlockPool.h @@ -9,32 +9,32 @@ #include "LuceneObject.h" -namespace Lucene -{ - class CharBlockPool : public LuceneObject - { - public: - CharBlockPool(const DocumentsWriterPtr& docWriter); - virtual ~CharBlockPool(); - - LUCENE_CLASS(CharBlockPool); - - public: - Collection buffers; - int32_t numBuffer; - int32_t bufferUpto; // Which buffer we are up to - int32_t charUpto; // Where we are in head buffer - - CharArray buffer; // Current head buffer - int32_t charOffset; // Current head offset - - protected: - DocumentsWriterWeakPtr _docWriter; - - public: - void reset(); - void nextBuffer(); - }; +namespace Lucene { + +class CharBlockPool : public LuceneObject { +public: + CharBlockPool(const DocumentsWriterPtr& docWriter); + virtual ~CharBlockPool(); + + LUCENE_CLASS(CharBlockPool); + +public: + Collection buffers; + int32_t numBuffer; + int32_t bufferUpto; // Which buffer we are up to + int32_t charUpto; // Where we are in head buffer + + CharArray buffer; // Current head buffer + int32_t charOffset; // Current head offset + +protected: + DocumentsWriterWeakPtr _docWriter; + +public: + void reset(); + void nextBuffer(); +}; + } #endif diff --git a/include/CharFilter.h b/include/CharFilter.h index 5e083307..8589d9f9 100644 --- a/include/CharFilter.h +++ b/include/CharFilter.h @@ -9,38 +9,38 @@ #include "CharStream.h" -namespace Lucene -{ - /// Subclasses of CharFilter can be chained to filter CharStream. They can be used as {@link Reader} with - /// additional offset correction. {@link Tokenizer}s will automatically use {@link #correctOffset} if a - /// CharFilter/CharStream subclass is used. - class LPPAPI CharFilter : public CharStream - { - protected: - CharFilter(const CharStreamPtr& in); - public: - virtual ~CharFilter(); - - LUCENE_CLASS(CharFilter); - - protected: - CharStreamPtr input; - - protected: - /// Subclass may want to override to correct the current offset. - /// @param currentOff current offset - /// @return corrected offset - virtual int32_t correct(int32_t currentOff); - - /// Chains the corrected offset through the input CharFilter. - virtual int32_t correctOffset(int32_t currentOff); - - virtual void close(); - virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - virtual bool markSupported(); - virtual void mark(int32_t readAheadLimit); - virtual void reset(); - }; +namespace Lucene { + +/// Subclasses of CharFilter can be chained to filter CharStream. They can be used as {@link Reader} with +/// additional offset correction. {@link Tokenizer}s will automatically use {@link #correctOffset} if a +/// CharFilter/CharStream subclass is used. +class LPPAPI CharFilter : public CharStream { +protected: + CharFilter(const CharStreamPtr& in); +public: + virtual ~CharFilter(); + + LUCENE_CLASS(CharFilter); + +protected: + CharStreamPtr input; + +protected: + /// Subclass may want to override to correct the current offset. + /// @param currentOff current offset + /// @return corrected offset + virtual int32_t correct(int32_t currentOff); + + /// Chains the corrected offset through the input CharFilter. + virtual int32_t correctOffset(int32_t currentOff); + + virtual void close(); + virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); + virtual bool markSupported(); + virtual void mark(int32_t readAheadLimit); + virtual void reset(); +}; + } #endif diff --git a/include/CharFolder.h b/include/CharFolder.h index cf1b1e2e..fda66bef 100644 --- a/include/CharFolder.h +++ b/include/CharFolder.h @@ -9,43 +9,43 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Utility class for folding character case. - class LPPAPI CharFolder : public LuceneObject - { - public: - virtual ~CharFolder(); - LUCENE_CLASS(CharFolder); - - protected: - static bool lowerCache; - static bool upperCache; - static wchar_t lowerChars[CHAR_MAX - CHAR_MIN + 1]; - static wchar_t upperChars[CHAR_MAX - CHAR_MIN + 1]; - - public: - static wchar_t toLower(wchar_t ch); - static wchar_t toUpper(wchar_t ch); - - template - static void toLower(ITER first, ITER last) - { - for (; first != last; ++first) - *first = toLower(*first); +namespace Lucene { + +/// Utility class for folding character case. +class LPPAPI CharFolder : public LuceneObject { +public: + virtual ~CharFolder(); + LUCENE_CLASS(CharFolder); + +protected: + static bool lowerCache; + static bool upperCache; + static wchar_t lowerChars[CHAR_MAX - CHAR_MIN + 1]; + static wchar_t upperChars[CHAR_MAX - CHAR_MIN + 1]; + +public: + static wchar_t toLower(wchar_t ch); + static wchar_t toUpper(wchar_t ch); + + template + static void toLower(ITER first, ITER last) { + for (; first != last; ++first) { + *first = toLower(*first); } + } - template - static void toUpper(ITER first, ITER last) - { - for (; first != last; ++first) - *first = toUpper(*first); + template + static void toUpper(ITER first, ITER last) { + for (; first != last; ++first) { + *first = toUpper(*first); } + } + +protected: + static bool fillLower(); + static bool fillUpper(); +}; - protected: - static bool fillLower(); - static bool fillUpper(); - }; } #endif diff --git a/include/CharReader.h b/include/CharReader.h index 887f571c..0223d56d 100644 --- a/include/CharReader.h +++ b/include/CharReader.h @@ -9,33 +9,33 @@ #include "CharStream.h" -namespace Lucene -{ - /// CharReader is a Reader wrapper. It reads chars from Reader and outputs {@link CharStream}, defining an - /// identify function {@link #correctOffset} method that simply returns the provided offset. - class LPPAPI CharReader : public CharStream - { - public: - CharReader(const ReaderPtr& in); - virtual ~CharReader(); - - LUCENE_CLASS(CharReader); - - protected: - ReaderPtr input; - - public: - using CharStream::read; - - static CharStreamPtr get(const ReaderPtr& input); - - virtual int32_t correctOffset(int32_t currentOff); - virtual void close(); - virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - virtual bool markSupported(); - virtual void mark(int32_t readAheadLimit); - virtual void reset(); - }; +namespace Lucene { + +/// CharReader is a Reader wrapper. It reads chars from Reader and outputs {@link CharStream}, defining an +/// identify function {@link #correctOffset} method that simply returns the provided offset. +class LPPAPI CharReader : public CharStream { +public: + CharReader(const ReaderPtr& in); + virtual ~CharReader(); + + LUCENE_CLASS(CharReader); + +protected: + ReaderPtr input; + +public: + using CharStream::read; + + static CharStreamPtr get(const ReaderPtr& input); + + virtual int32_t correctOffset(int32_t currentOff); + virtual void close(); + virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); + virtual bool markSupported(); + virtual void mark(int32_t readAheadLimit); + virtual void reset(); +}; + } #endif diff --git a/include/CharStream.h b/include/CharStream.h index c99ed2da..5c5d07f3 100644 --- a/include/CharStream.h +++ b/include/CharStream.h @@ -9,25 +9,25 @@ #include "Reader.h" -namespace Lucene -{ - /// CharStream adds {@link #correctOffset} functionality over {@link Reader}. All Tokenizers accept a CharStream - /// instead of {@link Reader} as input, which enables arbitrary character based filtering before tokenization. - /// The {@link #correctOffset} method fixed offsets to account for removal or insertion of characters, so that the - /// offsets reported in the tokens match the character offsets of the original Reader. - class LPPAPI CharStream : public Reader - { - public: - virtual ~CharStream(); - LUCENE_CLASS(CharStream); +namespace Lucene { + +/// CharStream adds {@link #correctOffset} functionality over {@link Reader}. All Tokenizers accept a CharStream +/// instead of {@link Reader} as input, which enables arbitrary character based filtering before tokenization. +/// The {@link #correctOffset} method fixed offsets to account for removal or insertion of characters, so that the +/// offsets reported in the tokens match the character offsets of the original Reader. +class LPPAPI CharStream : public Reader { +public: + virtual ~CharStream(); + LUCENE_CLASS(CharStream); + +public: + /// Called by CharFilter(s) and Tokenizer to correct token offset. + /// + /// @param currentOff offset as seen in the output + /// @return corrected offset based on the input + virtual int32_t correctOffset(int32_t currentOff) = 0; +}; - public: - /// Called by CharFilter(s) and Tokenizer to correct token offset. - /// - /// @param currentOff offset as seen in the output - /// @return corrected offset based on the input - virtual int32_t correctOffset(int32_t currentOff) = 0; - }; } #endif diff --git a/include/CharTokenizer.h b/include/CharTokenizer.h index 35fdbcb1..a1c5acda 100644 --- a/include/CharTokenizer.h +++ b/include/CharTokenizer.h @@ -9,46 +9,46 @@ #include "Tokenizer.h" -namespace Lucene -{ - /// An abstract base class for simple, character-oriented tokenizers. - class LPPAPI CharTokenizer : public Tokenizer - { - public: - CharTokenizer(const ReaderPtr& input); - CharTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - CharTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - virtual ~CharTokenizer(); - - LUCENE_CLASS(CharTokenizer); - - protected: - int32_t offset; - int32_t bufferIndex; - int32_t dataLen; - - static const int32_t MAX_WORD_LEN; - static const int32_t IO_BUFFER_SIZE; - - CharArray ioBuffer; - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; - - public: - virtual bool incrementToken(); - virtual void end(); - virtual void reset(const ReaderPtr& input); - - protected: - /// Returns true if a character should be included in a token. This tokenizer generates as tokens adjacent - /// sequences of characters which satisfy this predicate. Characters for which this is false are used to - /// define token boundaries and are not included in tokens. - virtual bool isTokenChar(wchar_t c) = 0; - - /// Called on each token character to normalize it before it is added to the token. The default implementation - /// does nothing. Subclasses may use this to, eg., lowercase tokens. - virtual wchar_t normalize(wchar_t c); - }; +namespace Lucene { + +/// An abstract base class for simple, character-oriented tokenizers. +class LPPAPI CharTokenizer : public Tokenizer { +public: + CharTokenizer(const ReaderPtr& input); + CharTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + CharTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + virtual ~CharTokenizer(); + + LUCENE_CLASS(CharTokenizer); + +protected: + int32_t offset; + int32_t bufferIndex; + int32_t dataLen; + + static const int32_t MAX_WORD_LEN; + static const int32_t IO_BUFFER_SIZE; + + CharArray ioBuffer; + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + +public: + virtual bool incrementToken(); + virtual void end(); + virtual void reset(const ReaderPtr& input); + +protected: + /// Returns true if a character should be included in a token. This tokenizer generates as tokens adjacent + /// sequences of characters which satisfy this predicate. Characters for which this is false are used to + /// define token boundaries and are not included in tokens. + virtual bool isTokenChar(wchar_t c) = 0; + + /// Called on each token character to normalize it before it is added to the token. The default implementation + /// does nothing. Subclasses may use this to, eg., lowercase tokens. + virtual wchar_t normalize(wchar_t c); +}; + } #endif diff --git a/include/CheckIndex.h b/include/CheckIndex.h index 9a3e178f..6e22292e 100644 --- a/include/CheckIndex.h +++ b/include/CheckIndex.h @@ -9,312 +9,306 @@ #include "SegmentTermDocs.h" -namespace Lucene -{ - /// Basic tool and API to check the health of an index and write a new segments file that removes reference to - /// problematic segments. +namespace Lucene { + +/// Basic tool and API to check the health of an index and write a new segments file that removes reference to +/// problematic segments. +/// +/// As this tool checks every byte in the index, on a large index it can take quite a long time to run. +/// +/// WARNING: Please make a complete backup of your index before using this to fix your index! +class LPPAPI CheckIndex : public LuceneObject { +public: + /// Create a new CheckIndex on the directory. + CheckIndex(const DirectoryPtr& dir); + virtual ~CheckIndex(); + + LUCENE_CLASS(CheckIndex); + +protected: + InfoStreamPtr infoStream; + DirectoryPtr dir; + + static bool _assertsOn; + +public: + /// Set infoStream where messages should go. If null, no messages are printed + void setInfoStream(const InfoStreamPtr& out); + + /// Returns a {@link IndexStatus} instance detailing the state of the index. + /// + /// As this method checks every byte in the index, on a large index it can take quite a long time to run. + /// + /// WARNING: make sure you only call this when the index is not opened by any writer. + IndexStatusPtr checkIndex(); + + /// Returns a {@link IndexStatus} instance detailing the state of the index. + /// + /// @param onlySegments list of specific segment names to check + /// + /// As this method checks every byte in the specified segments, on a large index it can take quite a long + /// time to run. + /// + /// WARNING: make sure you only call this when the index is not opened by any writer. + IndexStatusPtr checkIndex(Collection onlySegments); + + /// Repairs the index using previously returned result from {@link #checkIndex}. Note that this does not + /// remove any of the unreferenced files after it's done; you must separately open an {@link IndexWriter}, + /// which deletes unreferenced files when it's created. + /// + /// WARNING: this writes a new segments file into the index, effectively removing all documents in broken + /// segments from the index. BE CAREFUL. + /// + /// WARNING: Make sure you only call this when the index is not opened by any writer. + void fixIndex(const IndexStatusPtr& result); + + static bool testAsserts(); + static bool assertsOn(); + + /// Command-line interface to check and fix an index. + /// + /// Run it like this: + /// CheckIndex pathToIndex [-fix] [-segment X] [-segment Y] /// - /// As this tool checks every byte in the index, on a large index it can take quite a long time to run. + /// -fix: actually write a new segments_N file, removing any problematic segments /// - /// WARNING: Please make a complete backup of your index before using this to fix your index! - class LPPAPI CheckIndex : public LuceneObject - { - public: - /// Create a new CheckIndex on the directory. - CheckIndex(const DirectoryPtr& dir); - virtual ~CheckIndex(); - - LUCENE_CLASS(CheckIndex); - - protected: - InfoStreamPtr infoStream; - DirectoryPtr dir; - - static bool _assertsOn; - - public: - /// Set infoStream where messages should go. If null, no messages are printed - void setInfoStream(const InfoStreamPtr& out); - - /// Returns a {@link IndexStatus} instance detailing the state of the index. - /// - /// As this method checks every byte in the index, on a large index it can take quite a long time to run. - /// - /// WARNING: make sure you only call this when the index is not opened by any writer. - IndexStatusPtr checkIndex(); - - /// Returns a {@link IndexStatus} instance detailing the state of the index. - /// - /// @param onlySegments list of specific segment names to check - /// - /// As this method checks every byte in the specified segments, on a large index it can take quite a long - /// time to run. - /// - /// WARNING: make sure you only call this when the index is not opened by any writer. - IndexStatusPtr checkIndex(Collection onlySegments); - - /// Repairs the index using previously returned result from {@link #checkIndex}. Note that this does not - /// remove any of the unreferenced files after it's done; you must separately open an {@link IndexWriter}, - /// which deletes unreferenced files when it's created. - /// - /// WARNING: this writes a new segments file into the index, effectively removing all documents in broken - /// segments from the index. BE CAREFUL. - /// - /// WARNING: Make sure you only call this when the index is not opened by any writer. - void fixIndex(const IndexStatusPtr& result); - - static bool testAsserts(); - static bool assertsOn(); - - /// Command-line interface to check and fix an index. - /// - /// Run it like this: - /// CheckIndex pathToIndex [-fix] [-segment X] [-segment Y] - /// - /// -fix: actually write a new segments_N file, removing any problematic segments - /// - /// -segment X: only check the specified segment(s). This can be specified multiple times, - /// to check more than one segment, eg -segment _2 -segment _a. - /// You can't use this with the -fix option. - /// - /// WARNING: -fix should only be used on an emergency basis as it will cause documents (perhaps many) - /// to be permanently removed from the index. Always make a backup copy of your index before running - /// this! Do not run this tool on an index that is actively being written to. You have been warned! - /// - /// Run without -fix, this tool will open the index, report version information and report any exceptions - /// it hits and what action it would take if -fix were specified. With -fix, this tool will remove any - /// segments that have issues and write a new segments_N file. This means all documents contained in the - /// affected segments will be removed. - /// - /// This tool exits with exit code 1 if the index cannot be opened or has any corruption, else 0. - static int main(Collection args); - - protected: - void msg(const String& msg); - - /// Test field norms. - FieldNormStatusPtr testFieldNorms(Collection fieldNames, const SegmentReaderPtr& reader); - - /// Test the term index. - TermIndexStatusPtr testTermIndex(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); - - /// Test stored fields for a segment. - StoredFieldStatusPtr testStoredFields(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); - - /// Test term vectors for a segment. - TermVectorStatusPtr testTermVectors(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); - }; - - /// Returned from {@link #checkIndex()} detailing the health and status of the index. - class LPPAPI IndexStatus : public LuceneObject - { - public: - IndexStatus(); - virtual ~IndexStatus(); - - LUCENE_CLASS(IndexStatus); - - public: - /// True if no problems were found with the index. - bool clean; - - /// True if we were unable to locate and load the segments_N file. - bool missingSegments; - - /// True if we were unable to open the segments_N file. - bool cantOpenSegments; + /// -segment X: only check the specified segment(s). This can be specified multiple times, + /// to check more than one segment, eg -segment _2 -segment _a. + /// You can't use this with the -fix option. + /// + /// WARNING: -fix should only be used on an emergency basis as it will cause documents (perhaps many) + /// to be permanently removed from the index. Always make a backup copy of your index before running + /// this! Do not run this tool on an index that is actively being written to. You have been warned! + /// + /// Run without -fix, this tool will open the index, report version information and report any exceptions + /// it hits and what action it would take if -fix were specified. With -fix, this tool will remove any + /// segments that have issues and write a new segments_N file. This means all documents contained in the + /// affected segments will be removed. + /// + /// This tool exits with exit code 1 if the index cannot be opened or has any corruption, else 0. + static int main(Collection args); + +protected: + void msg(const String& msg); + + /// Test field norms. + FieldNormStatusPtr testFieldNorms(Collection fieldNames, const SegmentReaderPtr& reader); + + /// Test the term index. + TermIndexStatusPtr testTermIndex(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); + + /// Test stored fields for a segment. + StoredFieldStatusPtr testStoredFields(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); + + /// Test term vectors for a segment. + TermVectorStatusPtr testTermVectors(const SegmentInfoPtr& info, const SegmentReaderPtr& reader); +}; + +/// Returned from {@link #checkIndex()} detailing the health and status of the index. +class LPPAPI IndexStatus : public LuceneObject { +public: + IndexStatus(); + virtual ~IndexStatus(); + + LUCENE_CLASS(IndexStatus); + +public: + /// True if no problems were found with the index. + bool clean; + + /// True if we were unable to locate and load the segments_N file. + bool missingSegments; + + /// True if we were unable to open the segments_N file. + bool cantOpenSegments; + + /// True if we were unable to read the version number from segments_N file. + bool missingSegmentVersion; + + /// Name of latest segments_N file in the index. + String segmentsFileName; + + /// Number of segments in the index. + int32_t numSegments; + + /// String description of the version of the index. + String segmentFormat; - /// True if we were unable to read the version number from segments_N file. - bool missingSegmentVersion; - - /// Name of latest segments_N file in the index. - String segmentsFileName; + /// Empty unless you passed specific segments list to check as optional 3rd argument. + /// @see CheckIndex#checkIndex(List) + Collection segmentsChecked; - /// Number of segments in the index. - int32_t numSegments; - - /// String description of the version of the index. - String segmentFormat; + /// True if the index was created with a newer version of Lucene than the CheckIndex tool. + bool toolOutOfDate; - /// Empty unless you passed specific segments list to check as optional 3rd argument. - /// @see CheckIndex#checkIndex(List) - Collection segmentsChecked; - - /// True if the index was created with a newer version of Lucene than the CheckIndex tool. - bool toolOutOfDate; + /// List of {@link SegmentInfoStatus} instances, detailing status of each segment. + Collection segmentInfos; - /// List of {@link SegmentInfoStatus} instances, detailing status of each segment. - Collection segmentInfos; + /// Directory index is in. + DirectoryPtr dir; - /// Directory index is in. - DirectoryPtr dir; + /// SegmentInfos instance containing only segments that had no problems (this is used with the + /// {@link CheckIndex#fixIndex} method to repair the index. + SegmentInfosPtr newSegments; - /// SegmentInfos instance containing only segments that had no problems (this is used with the - /// {@link CheckIndex#fixIndex} method to repair the index. - SegmentInfosPtr newSegments; + /// How many documents will be lost to bad segments. + int32_t totLoseDocCount; - /// How many documents will be lost to bad segments. - int32_t totLoseDocCount; + /// How many bad segments were found. + int32_t numBadSegments; - /// How many bad segments were found. - int32_t numBadSegments; + /// True if we checked only specific segments ({@link #checkIndex(List)}) was called with non-null argument). + bool partial; - /// True if we checked only specific segments ({@link #checkIndex(List)}) was called with non-null argument). - bool partial; + /// Holds the userData of the last commit in the index + MapStringString userData; +}; - /// Holds the userData of the last commit in the index - MapStringString userData; - }; +/// Holds the status of each segment in the index. See {@link #segmentInfos}. +class LPPAPI SegmentInfoStatus : public LuceneObject { +public: + SegmentInfoStatus(); + virtual ~SegmentInfoStatus(); - /// Holds the status of each segment in the index. See {@link #segmentInfos}. - class LPPAPI SegmentInfoStatus : public LuceneObject - { - public: - SegmentInfoStatus(); - virtual ~SegmentInfoStatus(); + LUCENE_CLASS(SegmentInfoStatus); - LUCENE_CLASS(SegmentInfoStatus); +public: + /// Name of the segment. + String name; - public: - /// Name of the segment. - String name; + /// Document count (does not take deletions into account). + int32_t docCount; - /// Document count (does not take deletions into account). - int32_t docCount; + /// True if segment is compound file format. + bool compound; - /// True if segment is compound file format. - bool compound; + /// Number of files referenced by this segment. + int32_t numFiles; - /// Number of files referenced by this segment. - int32_t numFiles; + /// Net size (MB) of the files referenced by this segment. + double sizeMB; - /// Net size (MB) of the files referenced by this segment. - double sizeMB; + /// Doc store offset, if this segment shares the doc store files (stored fields and term vectors) with + /// other segments. This is -1 if it does not share. + int32_t docStoreOffset; - /// Doc store offset, if this segment shares the doc store files (stored fields and term vectors) with - /// other segments. This is -1 if it does not share. - int32_t docStoreOffset; + /// String of the shared doc store segment, or null if this segment does not share the doc store files. + String docStoreSegment; - /// String of the shared doc store segment, or null if this segment does not share the doc store files. - String docStoreSegment; + /// True if the shared doc store files are compound file format. + bool docStoreCompoundFile; - /// True if the shared doc store files are compound file format. - bool docStoreCompoundFile; + /// True if this segment has pending deletions. + bool hasDeletions; - /// True if this segment has pending deletions. - bool hasDeletions; + /// Name of the current deletions file name. + String deletionsFileName; - /// Name of the current deletions file name. - String deletionsFileName; + /// Number of deleted documents. + int32_t numDeleted; - /// Number of deleted documents. - int32_t numDeleted; + /// True if we were able to open a SegmentReader on this segment. + bool openReaderPassed; - /// True if we were able to open a SegmentReader on this segment. - bool openReaderPassed; + /// Number of fields in this segment. + int32_t numFields; - /// Number of fields in this segment. - int32_t numFields; + /// True if at least one of the fields in this segment does not omitTermFreqAndPositions. + /// @see AbstractField#setOmitTermFreqAndPositions + bool hasProx; - /// True if at least one of the fields in this segment does not omitTermFreqAndPositions. - /// @see AbstractField#setOmitTermFreqAndPositions - bool hasProx; + /// Map that includes certain debugging details that IndexWriter records into each segment it creates + MapStringString diagnostics; - /// Map that includes certain debugging details that IndexWriter records into each segment it creates - MapStringString diagnostics; + /// Status for testing of field norms (null if field norms could not be tested). + FieldNormStatusPtr fieldNormStatus; - /// Status for testing of field norms (null if field norms could not be tested). - FieldNormStatusPtr fieldNormStatus; + /// Status for testing of indexed terms (null if indexed terms could not be tested). + TermIndexStatusPtr termIndexStatus; - /// Status for testing of indexed terms (null if indexed terms could not be tested). - TermIndexStatusPtr termIndexStatus; + /// Status for testing of stored fields (null if stored fields could not be tested). + StoredFieldStatusPtr storedFieldStatus; - /// Status for testing of stored fields (null if stored fields could not be tested). - StoredFieldStatusPtr storedFieldStatus; + /// Status for testing of term vectors (null if term vectors could not be tested). + TermVectorStatusPtr termVectorStatus; +}; - /// Status for testing of term vectors (null if term vectors could not be tested). - TermVectorStatusPtr termVectorStatus; - }; +/// Status from testing field norms. +class LPPAPI FieldNormStatus : public LuceneObject { +public: + FieldNormStatus(); + virtual ~FieldNormStatus(); - /// Status from testing field norms. - class LPPAPI FieldNormStatus : public LuceneObject - { - public: - FieldNormStatus(); - virtual ~FieldNormStatus(); + LUCENE_CLASS(FieldNormStatus); - LUCENE_CLASS(FieldNormStatus); +public: + /// Number of fields successfully tested + int64_t totFields; - public: - /// Number of fields successfully tested - int64_t totFields; + /// Exception thrown during term index test (null on success) + LuceneException error; +}; - /// Exception thrown during term index test (null on success) - LuceneException error; - }; +/// Status from testing term index. +class LPPAPI TermIndexStatus : public LuceneObject { +public: + TermIndexStatus(); + virtual ~TermIndexStatus(); - /// Status from testing term index. - class LPPAPI TermIndexStatus : public LuceneObject - { - public: - TermIndexStatus(); - virtual ~TermIndexStatus(); + LUCENE_CLASS(TermIndexStatus); - LUCENE_CLASS(TermIndexStatus); +public: + /// Total term count + int64_t termCount; - public: - /// Total term count - int64_t termCount; + /// Total frequency across all terms. + int64_t totFreq; - /// Total frequency across all terms. - int64_t totFreq; + /// Total number of positions. + int64_t totPos; - /// Total number of positions. - int64_t totPos; + /// Exception thrown during term index test (null on success) + LuceneException error; +}; - /// Exception thrown during term index test (null on success) - LuceneException error; - }; +/// Status from testing stored fields. +class LPPAPI StoredFieldStatus : public LuceneObject { +public: + StoredFieldStatus(); + virtual ~StoredFieldStatus(); - /// Status from testing stored fields. - class LPPAPI StoredFieldStatus : public LuceneObject - { - public: - StoredFieldStatus(); - virtual ~StoredFieldStatus(); + LUCENE_CLASS(StoredFieldStatus); - LUCENE_CLASS(StoredFieldStatus); +public: + /// Number of documents tested. + int32_t docCount; - public: - /// Number of documents tested. - int32_t docCount; + /// Total number of stored fields tested. + int64_t totFields; - /// Total number of stored fields tested. - int64_t totFields; + /// Exception thrown during stored fields test (null on success) + LuceneException error; +}; - /// Exception thrown during stored fields test (null on success) - LuceneException error; - }; +/// Status from testing stored fields. +class LPPAPI TermVectorStatus : public LuceneObject { +public: + TermVectorStatus(); + virtual ~TermVectorStatus(); - /// Status from testing stored fields. - class LPPAPI TermVectorStatus : public LuceneObject - { - public: - TermVectorStatus(); - virtual ~TermVectorStatus(); + LUCENE_CLASS(TermVectorStatus); - LUCENE_CLASS(TermVectorStatus); +public: + /// Number of documents tested. + int32_t docCount; - public: - /// Number of documents tested. - int32_t docCount; + /// Total number of term vectors tested. + int64_t totVectors; - /// Total number of term vectors tested. - int64_t totVectors; + /// Exception thrown during term vector test (null on success) + LuceneException error; +}; - /// Exception thrown during term vector test (null on success) - LuceneException error; - }; } #endif diff --git a/include/ChecksumIndexInput.h b/include/ChecksumIndexInput.h index 20c239d0..597fbbea 100644 --- a/include/ChecksumIndexInput.h +++ b/include/ChecksumIndexInput.h @@ -10,54 +10,54 @@ #include #include "IndexInput.h" -namespace Lucene -{ - /// Writes bytes through to a primary IndexInput, computing checksum as it goes. - /// Note that you cannot use seek(). - class LPPAPI ChecksumIndexInput : public IndexInput - { - public: - ChecksumIndexInput(const IndexInputPtr& main); - virtual ~ChecksumIndexInput(); - - LUCENE_CLASS(ChecksumIndexInput); - - protected: - IndexInputPtr main; - boost::crc_32_type checksum; - - public: - /// Reads and returns a single byte. - /// @see IndexOutput#writeByte(uint8_t) - virtual uint8_t readByte(); - - /// Reads a specified number of bytes into an array at the specified offset. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - /// @see IndexOutput#writeBytes(const uint8_t*,int) - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - - /// Return calculated checksum. - int64_t getChecksum(); - - /// Closes the stream to further operations. - virtual void close(); - - /// Returns the current position in this file, where the next read will occur. - /// @see #seek(int64_t) - virtual int64_t getFilePointer(); - - /// Sets current position in this file, where the next read will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos); - - /// The number of bytes in the file. - virtual int64_t length(); - - /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// Writes bytes through to a primary IndexInput, computing checksum as it goes. +/// Note that you cannot use seek(). +class LPPAPI ChecksumIndexInput : public IndexInput { +public: + ChecksumIndexInput(const IndexInputPtr& main); + virtual ~ChecksumIndexInput(); + + LUCENE_CLASS(ChecksumIndexInput); + +protected: + IndexInputPtr main; + boost::crc_32_type checksum; + +public: + /// Reads and returns a single byte. + /// @see IndexOutput#writeByte(uint8_t) + virtual uint8_t readByte(); + + /// Reads a specified number of bytes into an array at the specified offset. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + /// @see IndexOutput#writeBytes(const uint8_t*,int) + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); + + /// Return calculated checksum. + int64_t getChecksum(); + + /// Closes the stream to further operations. + virtual void close(); + + /// Returns the current position in this file, where the next read will occur. + /// @see #seek(int64_t) + virtual int64_t getFilePointer(); + + /// Sets current position in this file, where the next read will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos); + + /// The number of bytes in the file. + virtual int64_t length(); + + /// Returns a clone of this stream. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/include/ChecksumIndexOutput.h b/include/ChecksumIndexOutput.h index 11c0d545..67124c67 100644 --- a/include/ChecksumIndexOutput.h +++ b/include/ChecksumIndexOutput.h @@ -10,61 +10,61 @@ #include #include "IndexOutput.h" -namespace Lucene -{ - /// Writes bytes through to a primary IndexOutput, computing - /// checksum. Note that you cannot use seek(). - class LPPAPI ChecksumIndexOutput : public IndexOutput - { - public: - ChecksumIndexOutput(const IndexOutputPtr& main); - virtual ~ChecksumIndexOutput(); - - LUCENE_CLASS(ChecksumIndexOutput); - - protected: - IndexOutputPtr main; - boost::crc_32_type checksum; - - public: - /// Writes a single byte. - /// @see IndexInput#readByte() - virtual void writeByte(uint8_t b); - - /// Writes an array of bytes. - /// @param b the bytes to write. - /// @param length the number of bytes to write. - /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) - virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - - /// Return calculated checksum. - int64_t getChecksum(); - - /// Forces any buffered output to be written. - virtual void flush(); - - /// Closes the stream to further operations. - virtual void close(); - - /// Returns the current position in this file, where the next write will occur. - /// @see #seek(int64_t) - virtual int64_t getFilePointer(); - - /// Sets current position in this file, where the next write will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos); - - /// Starts but does not complete the commit of this file (= writing of - /// the final checksum at the end). After this is called must call - /// {@link #finishCommit} and the {@link #close} to complete the commit. - void prepareCommit(); - - /// See {@link #prepareCommit} - void finishCommit(); - - /// The number of bytes in the file. - virtual int64_t length(); - }; +namespace Lucene { + +/// Writes bytes through to a primary IndexOutput, computing +/// checksum. Note that you cannot use seek(). +class LPPAPI ChecksumIndexOutput : public IndexOutput { +public: + ChecksumIndexOutput(const IndexOutputPtr& main); + virtual ~ChecksumIndexOutput(); + + LUCENE_CLASS(ChecksumIndexOutput); + +protected: + IndexOutputPtr main; + boost::crc_32_type checksum; + +public: + /// Writes a single byte. + /// @see IndexInput#readByte() + virtual void writeByte(uint8_t b); + + /// Writes an array of bytes. + /// @param b the bytes to write. + /// @param length the number of bytes to write. + /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) + virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); + + /// Return calculated checksum. + int64_t getChecksum(); + + /// Forces any buffered output to be written. + virtual void flush(); + + /// Closes the stream to further operations. + virtual void close(); + + /// Returns the current position in this file, where the next write will occur. + /// @see #seek(int64_t) + virtual int64_t getFilePointer(); + + /// Sets current position in this file, where the next write will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos); + + /// Starts but does not complete the commit of this file (= writing of + /// the final checksum at the end). After this is called must call + /// {@link #finishCommit} and the {@link #close} to complete the commit. + void prepareCommit(); + + /// See {@link #prepareCommit} + void finishCommit(); + + /// The number of bytes in the file. + virtual int64_t length(); +}; + } #endif diff --git a/include/CloseableThreadLocal.h b/include/CloseableThreadLocal.h index 4aa7a942..2f27aa25 100644 --- a/include/CloseableThreadLocal.h +++ b/include/CloseableThreadLocal.h @@ -9,54 +9,51 @@ #include "LuceneThread.h" -namespace Lucene -{ - /// General purpose thread-local map. - template - class CloseableThreadLocal : public LuceneObject - { - public: - typedef boost::shared_ptr localDataPtr; - typedef Map MapLocalData; - - CloseableThreadLocal() - { - localData = MapLocalData::newInstance(); +namespace Lucene { + +/// General purpose thread-local map. +template +class CloseableThreadLocal : public LuceneObject { +public: + typedef boost::shared_ptr localDataPtr; + typedef Map MapLocalData; + + CloseableThreadLocal() { + localData = MapLocalData::newInstance(); + } + +public: + localDataPtr get() { + SyncLock syncLock(this); + typename MapLocalData::iterator local = localData.find(LuceneThread::currentId()); + if (local != localData.end()) { + return local->second; } - - public: - localDataPtr get() - { - SyncLock syncLock(this); - typename MapLocalData::iterator local = localData.find(LuceneThread::currentId()); - if (local != localData.end()) - return local->second; - localDataPtr initial(initialValue()); - if (initial) - localData.put(LuceneThread::currentId(), initial); - return initial; + localDataPtr initial(initialValue()); + if (initial) { + localData.put(LuceneThread::currentId(), initial); } + return initial; + } - void set(const localDataPtr& data) - { - SyncLock syncLock(this); - localData.put(LuceneThread::currentId(), data); - } + void set(const localDataPtr& data) { + SyncLock syncLock(this); + localData.put(LuceneThread::currentId(), data); + } - void close() - { - SyncLock syncLock(this); - localData.remove(LuceneThread::currentId()); - } + void close() { + SyncLock syncLock(this); + localData.remove(LuceneThread::currentId()); + } - protected: - MapLocalData localData; +protected: + MapLocalData localData; + + virtual localDataPtr initialValue() { + return localDataPtr(); // override + } +}; - virtual localDataPtr initialValue() - { - return localDataPtr(); // override - } - }; } #endif diff --git a/include/Collator.h b/include/Collator.h index 4d173eb7..3343e23b 100644 --- a/include/Collator.h +++ b/include/Collator.h @@ -9,24 +9,24 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Convenience class for storing collate objects. - class LPPAPI Collator : public LuceneObject - { - public: - /// Creates a new Collator, given the file to read from. - Collator(std::locale locale); - virtual ~Collator(); - - LUCENE_CLASS(Collator); - - protected: - const std::collate& collate; - - public: - int32_t compare(const String& first, const String& second); - }; +namespace Lucene { + +/// Convenience class for storing collate objects. +class LPPAPI Collator : public LuceneObject { +public: + /// Creates a new Collator, given the file to read from. + Collator(std::locale locale); + virtual ~Collator(); + + LUCENE_CLASS(Collator); + +protected: + const std::collate& collate; + +public: + int32_t compare(const String& first, const String& second); +}; + } #endif diff --git a/include/Collection.h b/include/Collection.h index 9a52118b..2721503d 100644 --- a/include/Collection.h +++ b/include/Collection.h @@ -10,305 +10,261 @@ #include #include "LuceneSync.h" -namespace Lucene -{ - /// Utility template class to handle collections that can be safely copied and shared - template - class Collection : public LuceneSync - { - public: - typedef Collection this_type; - typedef boost::shared_ptr shared_ptr; - typedef std::vector collection_type; - typedef typename collection_type::iterator iterator; - typedef typename collection_type::const_iterator const_iterator; - typedef TYPE value_type; - - virtual ~Collection() - { - } - - protected: - boost::shared_ptr container; - - public: - static this_type newInstance(int32_t size = 0) - { - this_type instance; - instance.container = Lucene::newInstance(size); - return instance; - } - - template - static this_type newInstance(ITER first, ITER last) - { - this_type instance; - instance.container = Lucene::newInstance(first, last); - return instance; - } - - void reset() - { - resize(0); - } - - void resize(int32_t size) - { - if (size == 0) - container.reset(); - else - container->resize(size); - } - - int32_t size() const - { - return (int32_t)container->size(); - } - - bool empty() const - { - return container->empty(); - } - - void clear() - { - container->clear(); - } +namespace Lucene { + +/// Utility template class to handle collections that can be safely copied and shared +template +class Collection : public LuceneSync { +public: + typedef Collection this_type; + typedef boost::shared_ptr shared_ptr; + typedef std::vector collection_type; + typedef typename collection_type::iterator iterator; + typedef typename collection_type::const_iterator const_iterator; + typedef TYPE value_type; + + virtual ~Collection() { + } - iterator begin() - { - return container->begin(); - } +protected: + boost::shared_ptr container; - iterator end() - { - return container->end(); - } +public: + static this_type newInstance(int32_t size = 0) { + this_type instance; + instance.container = Lucene::newInstance(size); + return instance; + } - const_iterator begin() const - { - return container->begin(); - } + template + static this_type newInstance(ITER first, ITER last) { + this_type instance; + instance.container = Lucene::newInstance(first, last); + return instance; + } - const_iterator end() const - { - return container->end(); - } + void reset() { + resize(0); + } - void add(const TYPE& type) - { - container->push_back(type); + void resize(int32_t size) { + if (size == 0) { + container.reset(); + } else { + container->resize(size); } + } - void add(int32_t pos, const TYPE& type) - { - container->insert(container->begin() + pos, type); - } + int32_t size() const { + return (int32_t)container->size(); + } - template - void addAll(ITER first, ITER last) - { - container->insert(container->end(), first, last); - } + bool empty() const { + return container->empty(); + } - template - void insert(ITER pos, const TYPE& type) - { - container->insert(pos, type); - } + void clear() { + container->clear(); + } - template - ITER remove(ITER pos) - { - return container->erase(pos); - } + iterator begin() { + return container->begin(); + } - template - ITER remove(ITER first, ITER last) - { - return container->erase(first, last); - } + iterator end() { + return container->end(); + } - void remove(const TYPE& type) - { - container->erase(std::remove(container->begin(), container->end(), type), container->end()); - } + const_iterator begin() const { + return container->begin(); + } - template - void remove_if(PRED comp) - { - container->erase(std::remove_if(container->begin(), container->end(), comp), container->end()); - } + const_iterator end() const { + return container->end(); + } - TYPE removeFirst() - { - TYPE front = container->front(); - container->erase(container->begin()); - return front; - } + void add(const TYPE& type) { + container->push_back(type); + } - TYPE removeLast() - { - TYPE back = container->back(); - container->pop_back(); - return back; - } + void add(int32_t pos, const TYPE& type) { + container->insert(container->begin() + pos, type); + } - iterator find(const TYPE& type) - { - return std::find(container->begin(), container->end(), type); - } + template + void addAll(ITER first, ITER last) { + container->insert(container->end(), first, last); + } - template - iterator find_if(PRED comp) - { - return std::find_if(container->begin(), container->end(), comp); - } + template + void insert(ITER pos, const TYPE& type) { + container->insert(pos, type); + } - bool contains(const TYPE& type) const - { - return (std::find(container->begin(), container->end(), type) != container->end()); - } + template + ITER remove(ITER pos) { + return container->erase(pos); + } - template - bool contains_if(PRED comp) const - { - return (std::find_if(container->begin(), container->end(), comp) != container->end()); - } + template + ITER remove(ITER first, ITER last) { + return container->erase(first, last); + } - bool equals(const this_type& other) const - { - return equals(other, std::equal_to()); - } + void remove(const TYPE& type) { + container->erase(std::remove(container->begin(), container->end(), type), container->end()); + } - template - bool equals(const this_type& other, PRED comp) const - { - if (container->size() != other.container->size()) - return false; - return std::equal(container->begin(), container->end(), other.container->begin(), comp); - } + template + void remove_if(PRED comp) { + container->erase(std::remove_if(container->begin(), container->end(), comp), container->end()); + } - int32_t hashCode() - { - return (int32_t)(int64_t)container.get(); - } + TYPE removeFirst() { + TYPE front = container->front(); + container->erase(container->begin()); + return front; + } - void swap(this_type& other) - { - container.swap(other->container); - } + TYPE removeLast() { + TYPE back = container->back(); + container->pop_back(); + return back; + } - TYPE& operator[] (int32_t pos) - { - return (*container)[pos]; - } + iterator find(const TYPE& type) { + return std::find(container->begin(), container->end(), type); + } - const TYPE& operator[] (int32_t pos) const - { - return (*container)[pos]; - } + template + iterator find_if(PRED comp) { + return std::find_if(container->begin(), container->end(), comp); + } - operator bool() const - { - return container.get() != NULL; - } + bool contains(const TYPE& type) const { + return (std::find(container->begin(), container->end(), type) != container->end()); + } - bool operator! () const - { - return !container; - } + template + bool contains_if(PRED comp) const { + return (std::find_if(container->begin(), container->end(), comp) != container->end()); + } - bool operator== (const this_type& other) - { - return (container == other.container); - } + bool equals(const this_type& other) const { + return equals(other, std::equal_to()); + } - bool operator!= (const this_type& other) - { - return (container != other.container); + template + bool equals(const this_type& other, PRED comp) const { + if (container->size() != other.container->size()) { + return false; } - }; - - template - Collection newCollection(const TYPE& a1) - { - Collection result = Collection::newInstance(); - result.add(a1); - return result; + return std::equal(container->begin(), container->end(), other.container->begin(), comp); } - template - Collection newCollection(const TYPE& a1, const TYPE& a2) - { - Collection result = newCollection(a1); - result.add(a2); - return result; + int32_t hashCode() { + return (int32_t)(int64_t)container.get(); } - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3) - { - Collection result = newCollection(a1, a2); - result.add(a3); - return result; + void swap(this_type& other) { + container.swap(other->container); } - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4) - { - Collection result = newCollection(a1, a2, a3); - result.add(a4); - return result; + TYPE& operator[] (int32_t pos) { + return (*container)[pos]; } - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5) - { - Collection result = newCollection(a1, a2, a3, a4); - result.add(a5); - return result; + const TYPE& operator[] (int32_t pos) const { + return (*container)[pos]; } - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6) - { - Collection result = newCollection(a1, a2, a3, a4, a5); - result.add(a6); - return result; + operator bool() const { + return container.get() != NULL; } - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7) - { - Collection result = newCollection(a1, a2, a3, a4, a5, a6); - result.add(a7); - return result; + bool operator! () const { + return !container; } - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8) - { - Collection result = newCollection(a1, a2, a3, a4, a5, a6, a7); - result.add(a8); - return result; + bool operator== (const this_type& other) { + return (container == other.container); } - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8, const TYPE& a9) - { - Collection result = newCollection(a1, a2, a3, a4, a5, a6, a7, a8); - result.add(a9); - return result; + bool operator!= (const this_type& other) { + return (container != other.container); } +}; + +template +Collection newCollection(const TYPE& a1) { + Collection result = Collection::newInstance(); + result.add(a1); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2) { + Collection result = newCollection(a1); + result.add(a2); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3) { + Collection result = newCollection(a1, a2); + result.add(a3); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4) { + Collection result = newCollection(a1, a2, a3); + result.add(a4); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5) { + Collection result = newCollection(a1, a2, a3, a4); + result.add(a5); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6) { + Collection result = newCollection(a1, a2, a3, a4, a5); + result.add(a6); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7) { + Collection result = newCollection(a1, a2, a3, a4, a5, a6); + result.add(a7); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8) { + Collection result = newCollection(a1, a2, a3, a4, a5, a6, a7); + result.add(a8); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8, const TYPE& a9) { + Collection result = newCollection(a1, a2, a3, a4, a5, a6, a7, a8); + result.add(a9); + return result; +} + +template +Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8, const TYPE& a9, const TYPE& a10) { + Collection result = newCollection(a1, a2, a3, a4, a5, a6, a7, a8, a9); + result.add(a10); + return result; +} - template - Collection newCollection(const TYPE& a1, const TYPE& a2, const TYPE& a3, const TYPE& a4, const TYPE& a5, const TYPE& a6, const TYPE& a7, const TYPE& a8, const TYPE& a9, const TYPE& a10) - { - Collection result = newCollection(a1, a2, a3, a4, a5, a6, a7, a8, a9); - result.add(a10); - return result; - } } #endif diff --git a/include/Collector.h b/include/Collector.h index de0bd219..fc9d9719 100644 --- a/include/Collector.h +++ b/include/Collector.h @@ -9,130 +9,130 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Collectors are primarily meant to be used to gather raw results from a search, and implement sorting - /// or custom result filtering, collation, etc. - /// - /// Lucene's core collectors are derived from Collector. Likely your application can use one of these - /// classes, or subclass {@link TopDocsCollector}, instead of implementing Collector directly: - /// - ///
        - ///
      • {@link TopDocsCollector} is an abstract base class that assumes you will retrieve the top N docs, - /// according to some criteria, after collection is done. - /// - ///
      • {@link TopScoreDocCollector} is a concrete subclass {@link TopDocsCollector} and sorts according - /// to score + docID. This is used internally by the {@link IndexSearcher} search methods that do not take - /// an explicit {@link Sort}. It is likely the most frequently used collector. - /// - ///
      • {@link TopFieldCollector} subclasses {@link TopDocsCollector} and sorts according to a specified - /// {@link Sort} object (sort by field). This is used internally by the {@link IndexSearcher} search methods - /// that take an explicit {@link Sort}. - /// - ///
      • {@link TimeLimitingCollector}, which wraps any other Collector and aborts the search if it's taken too - /// much time. - /// - ///
      • {@link PositiveScoresOnlyCollector} wraps any other Collector and prevents collection of hits whose - /// score is <= 0.0 - /// - ///
      - /// - /// Collector decouples the score from the collected doc: the score computation is skipped entirely if it's not - /// needed. Collectors that do need the score should implement the {@link #setScorer} method, to hold onto the - /// passed {@link Scorer} instance, and call {@link Scorer#score()} within the collect method to compute the - /// current hit's score. If your collector may request the score for a single hit multiple times, you should use - /// {@link ScoreCachingWrappingScorer}. - /// - /// NOTE: The doc that is passed to the collect method is relative to the current reader. If your collector needs - /// to resolve this to the docID space of the Multi*Reader, you must re-base it by recording the docBase from the - /// most recent setNextReader call. Here's a simple example showing how to collect docIDs into a BitSet: - /// - ///
      -    /// class MyCollector : public Collector
      -    /// {
      -    /// public:
      -    ///     MyCollector(const BitSetPtr& bits)
      -    ///     {
      -    ///         this->bits = bits;
      -    ///         this->docBase = 0;
      -    ///     }
      -    ///
      -    /// protected:
      -    ///     BitSetPtr bits;
      -    ///     int32_t docBase;
      -    ///
      -    /// public:
      -    ///     virtual void setScorer(const ScorerPtr& scorer)
      -    ///     {
      -    ///         // ignore scorer
      -    ///     }
      -    ///
      -    ///     virtual void collect(int32_t doc)
      -    ///     {
      -    ///         bits->set(doc + docBase);
      -    ///     }
      -    ///
      -    ///     virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase)
      -    ///     {
      -    ///         this->docBase = docBase;
      -    ///     }
      -    ///
      -    ///     virtual bool acceptsDocsOutOfOrder()
      -    ///     {
      -    ///         return true; // accept docs out of order (for a BitSet it doesn't matter)
      -    ///     }
      -    /// };
      -    ///
      -    /// ...
      -    ///
      -    /// SearcherPtr searcher = newLucene(indexReader);
      -    /// BitSetPtr bits = newLucene(indexReader->maxDoc());
      -    /// searcher->search(query, newLucene(bits));
      -    ///
      -    /// 
      - /// Not all collectors will need to rebase the docID. For example, a collector that simply counts the - /// total number of hits would skip it. - /// - /// NOTE: Prior to 2.9, Lucene silently filtered out hits with score <= 0. As of 2.9, the core Collectors - /// no longer do that. It's very unusual to have such hits (a negative query boost, or function query - /// returning negative custom scores, could cause it to happen). If you need that behavior, use {@link - /// PositiveScoresOnlyCollector}. - class LPPAPI Collector : public LuceneObject - { - public: - virtual ~Collector(); - LUCENE_CLASS(Collector); +namespace Lucene { + +/// Collectors are primarily meant to be used to gather raw results from a search, and implement sorting +/// or custom result filtering, collation, etc. +/// +/// Lucene's core collectors are derived from Collector. Likely your application can use one of these +/// classes, or subclass {@link TopDocsCollector}, instead of implementing Collector directly: +/// +///
        +///
      • {@link TopDocsCollector} is an abstract base class that assumes you will retrieve the top N docs, +/// according to some criteria, after collection is done. +/// +///
      • {@link TopScoreDocCollector} is a concrete subclass {@link TopDocsCollector} and sorts according +/// to score + docID. This is used internally by the {@link IndexSearcher} search methods that do not take +/// an explicit {@link Sort}. It is likely the most frequently used collector. +/// +///
      • {@link TopFieldCollector} subclasses {@link TopDocsCollector} and sorts according to a specified +/// {@link Sort} object (sort by field). This is used internally by the {@link IndexSearcher} search methods +/// that take an explicit {@link Sort}. +/// +///
      • {@link TimeLimitingCollector}, which wraps any other Collector and aborts the search if it's taken too +/// much time. +/// +///
      • {@link PositiveScoresOnlyCollector} wraps any other Collector and prevents collection of hits whose +/// score is <= 0.0 +/// +///
      +/// +/// Collector decouples the score from the collected doc: the score computation is skipped entirely if it's not +/// needed. Collectors that do need the score should implement the {@link #setScorer} method, to hold onto the +/// passed {@link Scorer} instance, and call {@link Scorer#score()} within the collect method to compute the +/// current hit's score. If your collector may request the score for a single hit multiple times, you should use +/// {@link ScoreCachingWrappingScorer}. +/// +/// NOTE: The doc that is passed to the collect method is relative to the current reader. If your collector needs +/// to resolve this to the docID space of the Multi*Reader, you must re-base it by recording the docBase from the +/// most recent setNextReader call. Here's a simple example showing how to collect docIDs into a BitSet: +/// +///
      +/// class MyCollector : public Collector
      +/// {
      +/// public:
      +///     MyCollector(const BitSetPtr& bits)
      +///     {
      +///         this->bits = bits;
      +///         this->docBase = 0;
      +///     }
      +///
      +/// protected:
      +///     BitSetPtr bits;
      +///     int32_t docBase;
      +///
      +/// public:
      +///     virtual void setScorer(const ScorerPtr& scorer)
      +///     {
      +///         // ignore scorer
      +///     }
      +///
      +///     virtual void collect(int32_t doc)
      +///     {
      +///         bits->set(doc + docBase);
      +///     }
      +///
      +///     virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase)
      +///     {
      +///         this->docBase = docBase;
      +///     }
      +///
      +///     virtual bool acceptsDocsOutOfOrder()
      +///     {
      +///         return true; // accept docs out of order (for a BitSet it doesn't matter)
      +///     }
      +/// };
      +///
      +/// ...
      +///
      +/// SearcherPtr searcher = newLucene(indexReader);
      +/// BitSetPtr bits = newLucene(indexReader->maxDoc());
      +/// searcher->search(query, newLucene(bits));
      +///
      +/// 
      +/// Not all collectors will need to rebase the docID. For example, a collector that simply counts the +/// total number of hits would skip it. +/// +/// NOTE: Prior to 2.9, Lucene silently filtered out hits with score <= 0. As of 2.9, the core Collectors +/// no longer do that. It's very unusual to have such hits (a negative query boost, or function query +/// returning negative custom scores, could cause it to happen). If you need that behavior, use {@link +/// PositiveScoresOnlyCollector}. +class LPPAPI Collector : public LuceneObject { +public: + virtual ~Collector(); + LUCENE_CLASS(Collector); + +public: + /// Called before successive calls to {@link #collect(int32_t)}. Implementations that need the score + /// of the current document (passed-in to {@link #collect(int32_t)}), should save the passed-in Scorer + /// and call scorer.score() when needed. + virtual void setScorer(const ScorerPtr& scorer) = 0; - public: - /// Called before successive calls to {@link #collect(int32_t)}. Implementations that need the score - /// of the current document (passed-in to {@link #collect(int32_t)}), should save the passed-in Scorer - /// and call scorer.score() when needed. - virtual void setScorer(const ScorerPtr& scorer) = 0; + /// Called once for every document matching a query, with the unbased document number. + /// + /// Note: This is called in an inner search loop. For good search performance, implementations of this + /// method should not call {@link Searcher#doc(int32_t)} or {@link IndexReader#document(int32_t)} on + /// every hit. Doing so can slow searches by an order of magnitude or more. + virtual void collect(int32_t doc) = 0; - /// Called once for every document matching a query, with the unbased document number. - /// - /// Note: This is called in an inner search loop. For good search performance, implementations of this - /// method should not call {@link Searcher#doc(int32_t)} or {@link IndexReader#document(int32_t)} on - /// every hit. Doing so can slow searches by an order of magnitude or more. - virtual void collect(int32_t doc) = 0; + /// Called before collecting from each IndexReader. All doc ids in {@link #collect(int32_t)} will + /// correspond to reader. Add docBase to the current IndexReaders internal document id to re-base ids + /// in {@link #collect(int32_t)}. + /// @param reader next IndexReader + /// @param docBase + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) = 0; - /// Called before collecting from each IndexReader. All doc ids in {@link #collect(int32_t)} will - /// correspond to reader. Add docBase to the current IndexReaders internal document id to re-base ids - /// in {@link #collect(int32_t)}. - /// @param reader next IndexReader - /// @param docBase - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) = 0; + /// Return true if this collector does not require the matching docIDs to be delivered in int sort + /// order (smallest to largest) to {@link #collect}. + /// + /// Most Lucene Query implementations will visit matching docIDs in order. However, some queries + /// (currently limited to certain cases of {@link BooleanQuery}) can achieve faster searching if the + /// Collector allows them to deliver the docIDs out of order. + /// + /// Many collectors don't mind getting docIDs out of order, so it's important to return true here. + virtual bool acceptsDocsOutOfOrder() = 0; +}; - /// Return true if this collector does not require the matching docIDs to be delivered in int sort - /// order (smallest to largest) to {@link #collect}. - /// - /// Most Lucene Query implementations will visit matching docIDs in order. However, some queries - /// (currently limited to certain cases of {@link BooleanQuery}) can achieve faster searching if the - /// Collector allows them to deliver the docIDs out of order. - /// - /// Many collectors don't mind getting docIDs out of order, so it's important to return true here. - virtual bool acceptsDocsOutOfOrder() = 0; - }; } #endif diff --git a/include/ComplexExplanation.h b/include/ComplexExplanation.h index 8df9b5e4..2b8d8bec 100644 --- a/include/ComplexExplanation.h +++ b/include/ComplexExplanation.h @@ -9,39 +9,39 @@ #include "Explanation.h" -namespace Lucene -{ - /// Describes the score computation for document and query, and can distinguish a match independent - /// of a positive value. - class LPPAPI ComplexExplanation : public Explanation - { - public: - ComplexExplanation(bool match = false, double value = 0, const String& description = EmptyString); - virtual ~ComplexExplanation(); - - LUCENE_CLASS(ComplexExplanation); - - protected: - bool match; - - public: - /// The match status of this explanation node. - bool getMatch(); - - /// Sets the match status assigned to this explanation node. - void setMatch(bool match); - - /// Indicates whether or not this Explanation models a good match. - /// - /// If the match status is explicitly set this method uses it; otherwise it defers to the - /// superclass. - /// - /// @see #getMatch - virtual bool isMatch(); - - protected: - virtual String getSummary(); - }; +namespace Lucene { + +/// Describes the score computation for document and query, and can distinguish a match independent +/// of a positive value. +class LPPAPI ComplexExplanation : public Explanation { +public: + ComplexExplanation(bool match = false, double value = 0, const String& description = EmptyString); + virtual ~ComplexExplanation(); + + LUCENE_CLASS(ComplexExplanation); + +protected: + bool match; + +public: + /// The match status of this explanation node. + bool getMatch(); + + /// Sets the match status assigned to this explanation node. + void setMatch(bool match); + + /// Indicates whether or not this Explanation models a good match. + /// + /// If the match status is explicitly set this method uses it; otherwise it defers to the + /// superclass. + /// + /// @see #getMatch + virtual bool isMatch(); + +protected: + virtual String getSummary(); +}; + } #endif diff --git a/include/CompoundFileReader.h b/include/CompoundFileReader.h index 447e0519..e82d7904 100644 --- a/include/CompoundFileReader.h +++ b/include/CompoundFileReader.h @@ -10,114 +10,111 @@ #include "Directory.h" #include "BufferedIndexInput.h" -namespace Lucene -{ - /// Class for accessing a compound stream. - /// This class implements a directory, but is limited to only read operations. - /// Directory methods that would normally modify data throw an exception. - class CompoundFileReader : public Directory - { - public: - CompoundFileReader(const DirectoryPtr& dir, const String& name); - CompoundFileReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize); - virtual ~CompoundFileReader(); - - LUCENE_CLASS(CompoundFileReader); - - protected: - struct FileEntry - { - FileEntry(int64_t offset = 0, int64_t length = 0) - { - this->offset = offset; - this->length = length; - } - int64_t offset; - int64_t length; - }; - typedef boost::shared_ptr FileEntryPtr; - typedef HashMap MapStringFileEntryPtr; - - DirectoryPtr directory; - String fileName; - int32_t readBufferSize; - IndexInputPtr stream; - MapStringFileEntryPtr entries; - - protected: - void ConstructReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize); - - public: - DirectoryPtr getDirectory(); - String getName(); - virtual void close(); - virtual IndexInputPtr openInput(const String& name); - virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - - /// Returns an array of strings, one for each file in the directory. - virtual HashSet listAll(); - - /// Returns true if a file with the given name exists. - virtual bool fileExists(const String& name); - - /// Returns the time the compound file was last modified. - virtual uint64_t fileModified(const String& name); - - /// Set the modified time of the compound file to now. - virtual void touchFile(const String& name); - - /// Not implemented - virtual void deleteFile(const String& name); - - /// Not implemented - virtual void renameFile(const String& from, const String& to); - - /// Returns the length of a file in the directory. - virtual int64_t fileLength(const String& name); - - /// Not implemented - virtual IndexOutputPtr createOutput(const String& name); - - /// Not implemented - virtual LockPtr makeLock(const String& name); +namespace Lucene { + +/// Class for accessing a compound stream. +/// This class implements a directory, but is limited to only read operations. +/// Directory methods that would normally modify data throw an exception. +class CompoundFileReader : public Directory { +public: + CompoundFileReader(const DirectoryPtr& dir, const String& name); + CompoundFileReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize); + virtual ~CompoundFileReader(); + + LUCENE_CLASS(CompoundFileReader); + +protected: + struct FileEntry { + FileEntry(int64_t offset = 0, int64_t length = 0) { + this->offset = offset; + this->length = length; + } + int64_t offset; + int64_t length; }; + typedef boost::shared_ptr FileEntryPtr; + typedef HashMap MapStringFileEntryPtr; + + DirectoryPtr directory; + String fileName; + int32_t readBufferSize; + IndexInputPtr stream; + MapStringFileEntryPtr entries; + +protected: + void ConstructReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize); + +public: + DirectoryPtr getDirectory(); + String getName(); + virtual void close(); + virtual IndexInputPtr openInput(const String& name); + virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); + + /// Returns an array of strings, one for each file in the directory. + virtual HashSet listAll(); + + /// Returns true if a file with the given name exists. + virtual bool fileExists(const String& name); + + /// Returns the time the compound file was last modified. + virtual uint64_t fileModified(const String& name); + + /// Set the modified time of the compound file to now. + virtual void touchFile(const String& name); + + /// Not implemented + virtual void deleteFile(const String& name); + + /// Not implemented + virtual void renameFile(const String& from, const String& to); + + /// Returns the length of a file in the directory. + virtual int64_t fileLength(const String& name); + + /// Not implemented + virtual IndexOutputPtr createOutput(const String& name); + + /// Not implemented + virtual LockPtr makeLock(const String& name); +}; + +/// Implementation of an IndexInput that reads from a portion of the compound file. +class CSIndexInput : public BufferedIndexInput { +public: + CSIndexInput(); + CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length); + CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length, int32_t readBufferSize); + virtual ~CSIndexInput(); + + LUCENE_CLASS(CSIndexInput); + +public: + IndexInputPtr base; + int64_t fileOffset; + int64_t _length; + +public: + /// Closes the stream to further operations. + virtual void close(); + + virtual int64_t length(); + + /// Returns a clone of this stream. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + +protected: + /// Implements buffer refill. Reads bytes from the current position in the input. + /// @param b the array to read bytes into + /// @param offset the offset in the array to start storing bytes + /// @param len the number of bytes to read + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); + + /// Implements seek. Sets current position in this file, where the next {@link + /// #readInternal(byte[],int,int)} will occur. + virtual void seekInternal(int64_t pos); +}; - /// Implementation of an IndexInput that reads from a portion of the compound file. - class CSIndexInput : public BufferedIndexInput - { - public: - CSIndexInput(); - CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length); - CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length, int32_t readBufferSize); - virtual ~CSIndexInput(); - - LUCENE_CLASS(CSIndexInput); - - public: - IndexInputPtr base; - int64_t fileOffset; - int64_t _length; - - public: - /// Closes the stream to further operations. - virtual void close(); - - virtual int64_t length(); - - /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - protected: - /// Implements buffer refill. Reads bytes from the current position in the input. - /// @param b the array to read bytes into - /// @param offset the offset in the array to start storing bytes - /// @param len the number of bytes to read - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); - - /// Implements seek. Sets current position in this file, where the next {@link - /// #readInternal(byte[],int,int)} will occur. - virtual void seekInternal(int64_t pos); - }; } #endif diff --git a/include/CompoundFileWriter.h b/include/CompoundFileWriter.h index 74febe8e..e2d3f26f 100644 --- a/include/CompoundFileWriter.h +++ b/include/CompoundFileWriter.h @@ -9,70 +9,69 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Combines multiple files into a single compound file. - /// The file format: - /// VInt fileCount - /// {Directory} - /// fileCount entries with the following structure: - /// int64_t dataOffset - /// String fileName - /// {File Data} - /// fileCount entries with the raw data of the corresponding file - /// - /// The fileCount integer indicates how many files are contained in this compound file. The {directory} - /// that follows has that many entries. Each directory entry contains a long pointer to the start of - /// this file's data section, and a string with that file's name. - class CompoundFileWriter : public LuceneObject - { - public: - CompoundFileWriter(const DirectoryPtr& dir, const String& name, const CheckAbortPtr& checkAbort = CheckAbortPtr()); - virtual ~CompoundFileWriter(); - - LUCENE_CLASS(CompoundFileWriter); - - protected: - struct FileEntry - { - /// source file - String file; - - /// temporary holder for the start of directory entry for this file - int64_t directoryOffset; - - /// temporary holder for the start of this file's data section - int64_t dataOffset; - }; - - DirectoryWeakPtr _directory; - String fileName; - HashSet ids; - Collection entries; - bool merged; - CheckAbortPtr checkAbort; - - public: - /// Returns the directory of the compound file. - DirectoryPtr getDirectory(); - - /// Returns the name of the compound file. - String getName(); - - /// Add a source stream. file is the string by which the sub-stream will be known in the - /// compound stream. - void addFile(const String& file); - - /// Merge files with the extensions added up to now. All files with these extensions are - /// combined sequentially into the compound stream. After successful merge, the source - /// are deleted.files - void close(); - - protected: - /// Copy the contents of the file with specified extension into the provided output stream. - /// Use the provided buffer for moving data to reduce memory allocation. - void copyFile(const FileEntry& source, const IndexOutputPtr& os, ByteArray buffer); +namespace Lucene { + +/// Combines multiple files into a single compound file. +/// The file format: +/// VInt fileCount +/// {Directory} +/// fileCount entries with the following structure: +/// int64_t dataOffset +/// String fileName +/// {File Data} +/// fileCount entries with the raw data of the corresponding file +/// +/// The fileCount integer indicates how many files are contained in this compound file. The {directory} +/// that follows has that many entries. Each directory entry contains a long pointer to the start of +/// this file's data section, and a string with that file's name. +class CompoundFileWriter : public LuceneObject { +public: + CompoundFileWriter(const DirectoryPtr& dir, const String& name, const CheckAbortPtr& checkAbort = CheckAbortPtr()); + virtual ~CompoundFileWriter(); + + LUCENE_CLASS(CompoundFileWriter); + +protected: + struct FileEntry { + /// source file + String file; + + /// temporary holder for the start of directory entry for this file + int64_t directoryOffset; + + /// temporary holder for the start of this file's data section + int64_t dataOffset; }; + + DirectoryWeakPtr _directory; + String fileName; + HashSet ids; + Collection entries; + bool merged; + CheckAbortPtr checkAbort; + +public: + /// Returns the directory of the compound file. + DirectoryPtr getDirectory(); + + /// Returns the name of the compound file. + String getName(); + + /// Add a source stream. file is the string by which the sub-stream will be known in the + /// compound stream. + void addFile(const String& file); + + /// Merge files with the extensions added up to now. All files with these extensions are + /// combined sequentially into the compound stream. After successful merge, the source + /// are deleted.files + void close(); + +protected: + /// Copy the contents of the file with specified extension into the provided output stream. + /// Use the provided buffer for moving data to reduce memory allocation. + void copyFile(const FileEntry& source, const IndexOutputPtr& os, ByteArray buffer); +}; + } #endif diff --git a/include/CompressionTools.h b/include/CompressionTools.h index 0457258c..4566c1f1 100644 --- a/include/CompressionTools.h +++ b/include/CompressionTools.h @@ -9,41 +9,41 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Simple utility class providing static methods to compress and decompress binary data for stored fields. - class LPPAPI CompressionTools : public LuceneObject - { - public: - virtual ~CompressionTools(); +namespace Lucene { - LUCENE_CLASS(CompressionTools); +/// Simple utility class providing static methods to compress and decompress binary data for stored fields. +class LPPAPI CompressionTools : public LuceneObject { +public: + virtual ~CompressionTools(); - public: - /// Compresses the specified byte range using the specified compressionLevel - static ByteArray compress(uint8_t* value, int32_t offset, int32_t length, int32_t compressionLevel); + LUCENE_CLASS(CompressionTools); - /// Compresses the specified byte range, with default BEST_COMPRESSION level - static ByteArray compress(uint8_t* value, int32_t offset, int32_t length); +public: + /// Compresses the specified byte range using the specified compressionLevel + static ByteArray compress(uint8_t* value, int32_t offset, int32_t length, int32_t compressionLevel); - /// Compresses all bytes in the array, with default BEST_COMPRESSION level - static ByteArray compress(ByteArray value); + /// Compresses the specified byte range, with default BEST_COMPRESSION level + static ByteArray compress(uint8_t* value, int32_t offset, int32_t length); - /// Compresses the String value, with default BEST_COMPRESSION level - static ByteArray compressString(const String& value); + /// Compresses all bytes in the array, with default BEST_COMPRESSION level + static ByteArray compress(ByteArray value); - /// Compresses the String value using the specified compressionLevel - static ByteArray compressString(const String& value, int32_t compressionLevel); + /// Compresses the String value, with default BEST_COMPRESSION level + static ByteArray compressString(const String& value); - /// Decompress the byte array previously returned by compress - static ByteArray decompress(ByteArray value); + /// Compresses the String value using the specified compressionLevel + static ByteArray compressString(const String& value, int32_t compressionLevel); - /// Decompress the byte array previously returned by compressString back into a String - static String decompressString(ByteArray value); + /// Decompress the byte array previously returned by compress + static ByteArray decompress(ByteArray value); + + /// Decompress the byte array previously returned by compressString back into a String + static String decompressString(ByteArray value); + +protected: + static const int32_t COMPRESS_BUFFER; +}; - protected: - static const int32_t COMPRESS_BUFFER; - }; } #endif diff --git a/include/ConcurrentMergeScheduler.h b/include/ConcurrentMergeScheduler.h index 1a43a5ff..22b33ed6 100644 --- a/include/ConcurrentMergeScheduler.h +++ b/include/ConcurrentMergeScheduler.h @@ -9,92 +9,92 @@ #include "MergeScheduler.h" -namespace Lucene -{ - /// A {@link MergeScheduler} that runs each merge using a separate thread, up until a - /// maximum number of threads ({@link #setMaxThreadCount}) at which when a merge is needed, - /// the thread(s) that are updating the index will pause until one or more merges completes. - /// This is a simple way to use concurrency in the indexing process without having to create - /// and manage application level threads. - class LPPAPI ConcurrentMergeScheduler : public MergeScheduler - { - public: - ConcurrentMergeScheduler(); - virtual ~ConcurrentMergeScheduler(); +namespace Lucene { - LUCENE_CLASS(ConcurrentMergeScheduler); +/// A {@link MergeScheduler} that runs each merge using a separate thread, up until a +/// maximum number of threads ({@link #setMaxThreadCount}) at which when a merge is needed, +/// the thread(s) that are updating the index will pause until one or more merges completes. +/// This is a simple way to use concurrency in the indexing process without having to create +/// and manage application level threads. +class LPPAPI ConcurrentMergeScheduler : public MergeScheduler { +public: + ConcurrentMergeScheduler(); + virtual ~ConcurrentMergeScheduler(); - protected: - int32_t mergeThreadPriority; + LUCENE_CLASS(ConcurrentMergeScheduler); - SetMergeThread mergeThreads; +protected: + int32_t mergeThreadPriority; - /// Max number of threads allowed to be merging at once - int32_t maxThreadCount; + SetMergeThread mergeThreads; - DirectoryPtr dir; + /// Max number of threads allowed to be merging at once + int32_t maxThreadCount; - bool closed; - IndexWriterWeakPtr _writer; + DirectoryPtr dir; - static Collection allInstances; + bool closed; + IndexWriterWeakPtr _writer; - bool suppressExceptions; - static bool anyExceptions; + static Collection allInstances; - public: - virtual void initialize(); + bool suppressExceptions; + static bool anyExceptions; - /// Sets the max # simultaneous threads that may be running. If a merge is necessary yet - /// we already have this many threads running, the incoming thread (that is calling - /// add/updateDocument) will block until a merge thread has completed. - virtual void setMaxThreadCount(int32_t count); +public: + virtual void initialize(); - /// Get the max # simultaneous threads that may be running. @see #setMaxThreadCount. - virtual int32_t getMaxThreadCount(); + /// Sets the max # simultaneous threads that may be running. If a merge is necessary yet + /// we already have this many threads running, the incoming thread (that is calling + /// add/updateDocument) will block until a merge thread has completed. + virtual void setMaxThreadCount(int32_t count); - /// Return the priority that merge threads run at. By default the priority is 1 plus the - /// priority of (ie, slightly higher priority than) the first thread that calls merge. - virtual int32_t getMergeThreadPriority(); + /// Get the max # simultaneous threads that may be running. @see #setMaxThreadCount. + virtual int32_t getMaxThreadCount(); - /// Set the priority that merge threads run at. - virtual void setMergeThreadPriority(int32_t pri); + /// Return the priority that merge threads run at. By default the priority is 1 plus the + /// priority of (ie, slightly higher priority than) the first thread that calls merge. + virtual int32_t getMergeThreadPriority(); - virtual void close(); + /// Set the priority that merge threads run at. + virtual void setMergeThreadPriority(int32_t pri); - virtual void sync(); + virtual void close(); - virtual void merge(const IndexWriterPtr& writer); + virtual void sync(); - /// Used for testing - static bool anyUnhandledExceptions(); - static void clearUnhandledExceptions(); + virtual void merge(const IndexWriterPtr& writer); - /// Used for testing - void setSuppressExceptions(); - void clearSuppressExceptions(); + /// Used for testing + static bool anyUnhandledExceptions(); + static void clearUnhandledExceptions(); - /// Used for testing - static void setTestMode(); + /// Used for testing + void setSuppressExceptions(); + void clearSuppressExceptions(); - protected: - virtual bool verbose(); - virtual void message(const String& message); - virtual void initMergeThreadPriority(); - virtual int32_t mergeThreadCount(); + /// Used for testing + static void setTestMode(); - /// Does the actual merge, by calling {@link IndexWriter#merge} - virtual void doMerge(const OneMergePtr& merge); +protected: + virtual bool verbose(); + virtual void message(const String& message); + virtual void initMergeThreadPriority(); + virtual int32_t mergeThreadCount(); - virtual MergeThreadPtr getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge); + /// Does the actual merge, by calling {@link IndexWriter#merge} + virtual void doMerge(const OneMergePtr& merge); - /// Called when an exception is hit in a background merge thread - virtual void handleMergeException(const LuceneException& exc); + virtual MergeThreadPtr getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge); - virtual void addMyself(); + /// Called when an exception is hit in a background merge thread + virtual void handleMergeException(const LuceneException& exc); + + virtual void addMyself(); + + friend class MergeThread; +}; - friend class MergeThread; - }; } #endif diff --git a/include/ConjunctionScorer.h b/include/ConjunctionScorer.h index 2fc5609a..d902d00e 100644 --- a/include/ConjunctionScorer.h +++ b/include/ConjunctionScorer.h @@ -9,31 +9,31 @@ #include "Scorer.h" -namespace Lucene -{ - /// Scorer for conjunctions, sets of queries, all of which are required. - class ConjunctionScorer : public Scorer - { - public: - ConjunctionScorer(const SimilarityPtr& similarity, Collection scorers); - virtual ~ConjunctionScorer(); - - LUCENE_CLASS(ConjunctionScorer); - - protected: - Collection scorers; - double coord; - int32_t lastDoc; - - public: - virtual int32_t advance(int32_t target); - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual double score(); - - protected: - int32_t doNext(); - }; +namespace Lucene { + +/// Scorer for conjunctions, sets of queries, all of which are required. +class ConjunctionScorer : public Scorer { +public: + ConjunctionScorer(const SimilarityPtr& similarity, Collection scorers); + virtual ~ConjunctionScorer(); + + LUCENE_CLASS(ConjunctionScorer); + +protected: + Collection scorers; + double coord; + int32_t lastDoc; + +public: + virtual int32_t advance(int32_t target); + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual double score(); + +protected: + int32_t doNext(); +}; + } #endif diff --git a/include/ConstantScoreQuery.h b/include/ConstantScoreQuery.h index 72134e5c..8a637b63 100644 --- a/include/ConstantScoreQuery.h +++ b/include/ConstantScoreQuery.h @@ -11,42 +11,42 @@ #include "Weight.h" #include "Scorer.h" -namespace Lucene -{ - /// A query that wraps a filter and simply returns a constant score equal to the query boost for every - /// document in the filter. - class LPPAPI ConstantScoreQuery : public Query - { - public: - ConstantScoreQuery(const FilterPtr& filter); - virtual ~ConstantScoreQuery(); +namespace Lucene { - LUCENE_CLASS(ConstantScoreQuery); +/// A query that wraps a filter and simply returns a constant score equal to the query boost for every +/// document in the filter. +class LPPAPI ConstantScoreQuery : public Query { +public: + ConstantScoreQuery(const FilterPtr& filter); + virtual ~ConstantScoreQuery(); - protected: - FilterPtr filter; + LUCENE_CLASS(ConstantScoreQuery); - public: - using Query::toString; +protected: + FilterPtr filter; - /// Returns the encapsulated filter - FilterPtr getFilter(); +public: + using Query::toString; - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual void extractTerms(SetTerm terms); + /// Returns the encapsulated filter + FilterPtr getFilter(); - virtual WeightPtr createWeight(const SearcherPtr& searcher); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual void extractTerms(SetTerm terms); - /// Prints a user-readable version of this query. - virtual String toString(const String& field); + virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + /// Prints a user-readable version of this query. + virtual String toString(const String& field); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + friend class ConstantWeight; + friend class ConstantScorer; +}; - friend class ConstantWeight; - friend class ConstantScorer; - }; } #endif diff --git a/include/Constants.h b/include/Constants.h index 915736dd..225af5c5 100644 --- a/include/Constants.h +++ b/include/Constants.h @@ -9,80 +9,78 @@ #include "Lucene.h" -namespace Lucene -{ - /// Some useful Lucene constants. - class LPPAPI Constants - { - private: - Constants(); - - public: - virtual ~Constants(); - - public: - static String OS_NAME; - static String LUCENE_MAIN_VERSION; - static String LUCENE_VERSION; +namespace Lucene { + +/// Some useful Lucene constants. +class LPPAPI Constants { +private: + Constants(); + +public: + virtual ~Constants(); + +public: + static String OS_NAME; + static String LUCENE_MAIN_VERSION; + static String LUCENE_VERSION; +}; + +/// Use by certain classes to match version compatibility across releases of Lucene. +/// +/// WARNING: When changing the version parameter that you supply to components in Lucene, do not simply +/// change the version at search-time, but instead also adjust your indexing code to match, and re-index. +class LPPAPI LuceneVersion { +private: + LuceneVersion(); + +public: + virtual ~LuceneVersion(); + +public: + enum Version { + /// Match settings and bugs in Lucene's 2.0 release. + LUCENE_20 = 0, + + /// Match settings and bugs in Lucene's 2.1 release. + LUCENE_21, + + /// Match settings and bugs in Lucene's 2.2 release. + LUCENE_22, + + /// Match settings and bugs in Lucene's 2.3 release. + LUCENE_23, + + /// Match settings and bugs in Lucene's 2.4 release. + LUCENE_24, + + /// Match settings and bugs in Lucene's 2.9 release. + LUCENE_29, + + /// Match settings and bugs in Lucene's 3.0 release. + /// + /// Use this to get the latest & greatest settings, bug fixes, etc, for Lucene. + LUCENE_30, + + /// Add new constants for later versions **here** to respect order! + + /// Warning: If you use this setting, and then upgrade to a newer release of Lucene, + /// sizable changes may happen. If backwards compatibility is important then you + /// should instead explicitly specify an actual version. + /// + /// If you use this constant then you may need to re-index all of your documents + /// when upgrading Lucene, as the way text is indexed may have changed. Additionally, + /// you may need to re-test your entire application to ensure it behaves as + /// expected, as some defaults may have changed and may break functionality in your + /// application. + /// + /// Deprecated: Use an actual version instead. + LUCENE_CURRENT }; - /// Use by certain classes to match version compatibility across releases of Lucene. - /// - /// WARNING: When changing the version parameter that you supply to components in Lucene, do not simply - /// change the version at search-time, but instead also adjust your indexing code to match, and re-index. - class LPPAPI LuceneVersion - { - private: - LuceneVersion(); - - public: - virtual ~LuceneVersion(); - - public: - enum Version - { - /// Match settings and bugs in Lucene's 2.0 release. - LUCENE_20 = 0, - - /// Match settings and bugs in Lucene's 2.1 release. - LUCENE_21, - - /// Match settings and bugs in Lucene's 2.2 release. - LUCENE_22, - - /// Match settings and bugs in Lucene's 2.3 release. - LUCENE_23, - - /// Match settings and bugs in Lucene's 2.4 release. - LUCENE_24, - - /// Match settings and bugs in Lucene's 2.9 release. - LUCENE_29, - - /// Match settings and bugs in Lucene's 3.0 release. - /// - /// Use this to get the latest & greatest settings, bug fixes, etc, for Lucene. - LUCENE_30, - - /// Add new constants for later versions **here** to respect order! - - /// Warning: If you use this setting, and then upgrade to a newer release of Lucene, - /// sizable changes may happen. If backwards compatibility is important then you - /// should instead explicitly specify an actual version. - /// - /// If you use this constant then you may need to re-index all of your documents - /// when upgrading Lucene, as the way text is indexed may have changed. Additionally, - /// you may need to re-test your entire application to ensure it behaves as - /// expected, as some defaults may have changed and may break functionality in your - /// application. - /// - /// Deprecated: Use an actual version instead. - LUCENE_CURRENT - }; - - public: - static bool onOrAfter(LuceneVersion::Version first, LuceneVersion::Version second); - }; +public: + static bool onOrAfter(LuceneVersion::Version first, LuceneVersion::Version second); +}; + } #endif diff --git a/include/CustomScoreProvider.h b/include/CustomScoreProvider.h index 2ca26202..22d27cba 100644 --- a/include/CustomScoreProvider.h +++ b/include/CustomScoreProvider.h @@ -9,85 +9,85 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// An instance of this subclass should be returned by {@link CustomScoreQuery#getCustomScoreProvider}, - /// if you want to modify the custom score calculation of a {@link CustomScoreQuery}. - /// - /// Since Lucene 2.9, queries operate on each segment of an Index separately, so overriding the similar - /// (now deprecated) methods in {@link CustomScoreQuery} is no longer suitable, as the supplied doc ID - /// is per-segment and without knowledge of the IndexReader you cannot access the document or {@link - /// FieldCache}. - class LPPAPI CustomScoreProvider : public LuceneObject - { - public: - /// Creates a new instance of the provider class for the given {@link IndexReader}. - CustomScoreProvider(const IndexReaderPtr& reader); +namespace Lucene { + +/// An instance of this subclass should be returned by {@link CustomScoreQuery#getCustomScoreProvider}, +/// if you want to modify the custom score calculation of a {@link CustomScoreQuery}. +/// +/// Since Lucene 2.9, queries operate on each segment of an Index separately, so overriding the similar +/// (now deprecated) methods in {@link CustomScoreQuery} is no longer suitable, as the supplied doc ID +/// is per-segment and without knowledge of the IndexReader you cannot access the document or {@link +/// FieldCache}. +class LPPAPI CustomScoreProvider : public LuceneObject { +public: + /// Creates a new instance of the provider class for the given {@link IndexReader}. + CustomScoreProvider(const IndexReaderPtr& reader); + + virtual ~CustomScoreProvider(); - virtual ~CustomScoreProvider(); + LUCENE_CLASS(CustomScoreProvider); - LUCENE_CLASS(CustomScoreProvider); +protected: + IndexReaderPtr reader; - protected: - IndexReaderPtr reader; +public: + /// Compute a custom score by the subQuery score and a number of ValueSourceQuery scores. + /// + /// Subclasses can override this method to modify the custom score. + /// + /// If your custom scoring is different than the default herein you should override at least one of + /// the two customScore() methods. If the number of ValueSourceQueries is always < 2 it is + /// sufficient to override the other {@link #customScore(int32_t, double, double) customScore()} + /// method, which is simpler. + /// + /// The default computation herein is a multiplication of given scores: + ///
      +    /// ModifiedScore = valSrcScore * valSrcScores[0] * valSrcScores[1] * ...
      +    /// 
      + /// + /// @param doc id of scored doc. + /// @param subQueryScore score of that doc by the subQuery. + /// @param valSrcScores scores of that doc by the ValueSourceQuery. + /// @return custom score. + virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); - public: - /// Compute a custom score by the subQuery score and a number of ValueSourceQuery scores. - /// - /// Subclasses can override this method to modify the custom score. - /// - /// If your custom scoring is different than the default herein you should override at least one of - /// the two customScore() methods. If the number of ValueSourceQueries is always < 2 it is - /// sufficient to override the other {@link #customScore(int32_t, double, double) customScore()} - /// method, which is simpler. - /// - /// The default computation herein is a multiplication of given scores: - ///
      -        /// ModifiedScore = valSrcScore * valSrcScores[0] * valSrcScores[1] * ...
      -        /// 
      - /// - /// @param doc id of scored doc. - /// @param subQueryScore score of that doc by the subQuery. - /// @param valSrcScores scores of that doc by the ValueSourceQuery. - /// @return custom score. - virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); + /// Compute a custom score by the subQuery score and the ValueSourceQuery score. + /// + /// Subclasses can override this method to modify the custom score. + /// + /// If your custom scoring is different than the default herein you should override at least one of the + /// two customScore() methods. If the number of ValueSourceQueries is always < 2 it is sufficient to + /// override this customScore() method, which is simpler. + /// + /// The default computation herein is a multiplication of the two scores: + ///
      +    /// ModifiedScore = subQueryScore * valSrcScore
      +    /// 
      + /// + /// @param doc id of scored doc. + /// @param subQueryScore score of that doc by the subQuery. + /// @param valSrcScore score of that doc by the ValueSourceQuery. + /// @return custom score. + virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); - /// Compute a custom score by the subQuery score and the ValueSourceQuery score. - /// - /// Subclasses can override this method to modify the custom score. - /// - /// If your custom scoring is different than the default herein you should override at least one of the - /// two customScore() methods. If the number of ValueSourceQueries is always < 2 it is sufficient to - /// override this customScore() method, which is simpler. - /// - /// The default computation herein is a multiplication of the two scores: - ///
      -        /// ModifiedScore = subQueryScore * valSrcScore
      -        /// 
      - /// - /// @param doc id of scored doc. - /// @param subQueryScore score of that doc by the subQuery. - /// @param valSrcScore score of that doc by the ValueSourceQuery. - /// @return custom score. - virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); + /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, Collection)}, + /// this method should also be overridden to provide the correct explanation for the part of the custom scoring. + /// + /// @param doc doc being explained. + /// @param subQueryExpl explanation for the sub-query part. + /// @param valSrcExpls explanation for the value source part. + /// @return an explanation for the custom score + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); - /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, Collection)}, - /// this method should also be overridden to provide the correct explanation for the part of the custom scoring. - /// - /// @param doc doc being explained. - /// @param subQueryExpl explanation for the sub-query part. - /// @param valSrcExpls explanation for the value source part. - /// @return an explanation for the custom score - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); + /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, double)}, + /// this method should also be overridden to provide the correct explanation for the part of the custom scoring. + /// @param doc doc being explained. + /// @param subQueryExpl explanation for the sub-query part. + /// @param valSrcExpl explanation for the value source part. + /// @return an explanation for the custom score + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); +}; - /// Explain the custom score. Whenever overriding {@link #customScore(int32_t, double, double)}, - /// this method should also be overridden to provide the correct explanation for the part of the custom scoring. - /// @param doc doc being explained. - /// @param subQueryExpl explanation for the sub-query part. - /// @param valSrcExpl explanation for the value source part. - /// @return an explanation for the custom score - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); - }; } #endif diff --git a/include/CustomScoreQuery.h b/include/CustomScoreQuery.h index e9d0436c..fcda80e9 100644 --- a/include/CustomScoreQuery.h +++ b/include/CustomScoreQuery.h @@ -9,124 +9,124 @@ #include "Query.h" -namespace Lucene -{ - /// Query that sets document score as a programmatic function of several (sub) scores: - ///
        - ///
      1. the score of its subQuery (any query) - ///
      2. (optional) the score of its ValueSourceQuery (or queries). For most simple/convenient use cases - /// this query is likely to be a {@link FieldScoreQuery} - ///
      - /// Subclasses can modify the computation by overriding {@link #getCustomScoreProvider}. - class LPPAPI CustomScoreQuery : public Query - { - public: - /// Create a CustomScoreQuery over input subQuery. - /// @param subQuery the sub query whose scored is being customed. Must not be null. - CustomScoreQuery(const QueryPtr& subQuery); - - /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. - /// @param subQuery the sub query whose score is being customized. Must not be null. - /// @param valSrcQuery a value source query whose scores are used in the custom score computation. For - /// most simple/convenient use case this would be a {@link FieldScoreQuery}. This parameter is - /// optional - it can be null. - CustomScoreQuery(const QueryPtr& subQuery, const ValueSourceQueryPtr& valSrcQuery); - - /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. - /// @param subQuery the sub query whose score is being customized. Must not be null. - /// @param valSrcQueries value source queries whose scores are used in the custom score computation. - /// For most simple/convenient use case these would be {@link FieldScoreQueries}. This parameter is - /// optional - it can be null or even an empty array. - CustomScoreQuery(const QueryPtr& subQuery, Collection valSrcQueries); - - virtual ~CustomScoreQuery(); - - LUCENE_CLASS(CustomScoreQuery); - - protected: - QueryPtr subQuery; - Collection valSrcQueries; // never null (empty array if there are no valSrcQueries). - bool strict; // if true, valueSource part of query does not take part in weights normalization. - - public: - using Query::toString; - - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual void extractTerms(SetTerm terms); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - /// Compute a custom score by the subQuery score and a number of ValueSourceQuery scores. - /// - /// Deprecated: Will be removed in Lucene 3.1. - /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment - /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} - /// for the given {@link IndexReader}. - virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); - - /// Compute a custom score by the subQuery score and the ValueSourceQuery score. - /// - /// Deprecated: Will be removed in Lucene 3.1. - /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment - /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} - /// for the given {@link IndexReader}. - virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); - - /// Explain the custom score. - /// - /// Deprecated: Will be removed in Lucene 3.1. - /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment - /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} - /// for the given {@link IndexReader}. - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); - - /// Explain the custom score. - /// - /// Deprecated Will be removed in Lucene 3.1. - /// - /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment - /// search (since Lucene 2.9). - /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} - /// for the given {@link IndexReader}. - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); - - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - /// Checks if this is strict custom scoring. In strict custom scoring, the ValueSource part does not - /// participate in weight normalization. This may be useful when one wants full control over how scores - /// are modified, and does not care about normalizing by the ValueSource part. One particular case where - /// this is useful if for testing this query. - /// - /// Note: only has effect when the ValueSource part is not null. - virtual bool isStrict(); - - /// Set the strict mode of this query. - /// @param strict The strict mode to set. - /// @see #isStrict() - virtual void setStrict(bool strict); - - /// A short name of this query, used in {@link #toString(String)}. - virtual String name(); - - protected: - void ConstructQuery(const QueryPtr& subQuery, Collection valSrcQueries); - - /// Returns a {@link CustomScoreProvider} that calculates the custom scores for the given {@link - /// IndexReader}. The default implementation returns a default implementation as specified in - /// the docs of {@link CustomScoreProvider}. - virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader); - - friend class CustomWeight; - friend class CustomScorer; - }; +namespace Lucene { + +/// Query that sets document score as a programmatic function of several (sub) scores: +///
        +///
      1. the score of its subQuery (any query) +///
      2. (optional) the score of its ValueSourceQuery (or queries). For most simple/convenient use cases +/// this query is likely to be a {@link FieldScoreQuery} +///
      +/// Subclasses can modify the computation by overriding {@link #getCustomScoreProvider}. +class LPPAPI CustomScoreQuery : public Query { +public: + /// Create a CustomScoreQuery over input subQuery. + /// @param subQuery the sub query whose scored is being customed. Must not be null. + CustomScoreQuery(const QueryPtr& subQuery); + + /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. + /// @param subQuery the sub query whose score is being customized. Must not be null. + /// @param valSrcQuery a value source query whose scores are used in the custom score computation. For + /// most simple/convenient use case this would be a {@link FieldScoreQuery}. This parameter is + /// optional - it can be null. + CustomScoreQuery(const QueryPtr& subQuery, const ValueSourceQueryPtr& valSrcQuery); + + /// Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}. + /// @param subQuery the sub query whose score is being customized. Must not be null. + /// @param valSrcQueries value source queries whose scores are used in the custom score computation. + /// For most simple/convenient use case these would be {@link FieldScoreQueries}. This parameter is + /// optional - it can be null or even an empty array. + CustomScoreQuery(const QueryPtr& subQuery, Collection valSrcQueries); + + virtual ~CustomScoreQuery(); + + LUCENE_CLASS(CustomScoreQuery); + +protected: + QueryPtr subQuery; + Collection valSrcQueries; // never null (empty array if there are no valSrcQueries). + bool strict; // if true, valueSource part of query does not take part in weights normalization. + +public: + using Query::toString; + + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual void extractTerms(SetTerm terms); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + /// Compute a custom score by the subQuery score and a number of ValueSourceQuery scores. + /// + /// Deprecated: Will be removed in Lucene 3.1. + /// + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// search (since Lucene 2.9). + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// for the given {@link IndexReader}. + virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); + + /// Compute a custom score by the subQuery score and the ValueSourceQuery score. + /// + /// Deprecated: Will be removed in Lucene 3.1. + /// + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// search (since Lucene 2.9). + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// for the given {@link IndexReader}. + virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); + + /// Explain the custom score. + /// + /// Deprecated: Will be removed in Lucene 3.1. + /// + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// search (since Lucene 2.9). + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// for the given {@link IndexReader}. + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); + + /// Explain the custom score. + /// + /// Deprecated Will be removed in Lucene 3.1. + /// + /// The doc is relative to the current reader, which is unknown to CustomScoreQuery when using per-segment + /// search (since Lucene 2.9). + /// Please override {@link #getCustomScoreProvider} and return a subclass of {@link CustomScoreProvider} + /// for the given {@link IndexReader}. + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); + + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + /// Checks if this is strict custom scoring. In strict custom scoring, the ValueSource part does not + /// participate in weight normalization. This may be useful when one wants full control over how scores + /// are modified, and does not care about normalizing by the ValueSource part. One particular case where + /// this is useful if for testing this query. + /// + /// Note: only has effect when the ValueSource part is not null. + virtual bool isStrict(); + + /// Set the strict mode of this query. + /// @param strict The strict mode to set. + /// @see #isStrict() + virtual void setStrict(bool strict); + + /// A short name of this query, used in {@link #toString(String)}. + virtual String name(); + +protected: + void ConstructQuery(const QueryPtr& subQuery, Collection valSrcQueries); + + /// Returns a {@link CustomScoreProvider} that calculates the custom scores for the given {@link + /// IndexReader}. The default implementation returns a default implementation as specified in + /// the docs of {@link CustomScoreProvider}. + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader); + + friend class CustomWeight; + friend class CustomScorer; +}; + } #endif diff --git a/include/CycleCheck.h b/include/CycleCheck.h index 14052415..240eb568 100644 --- a/include/CycleCheck.h +++ b/include/CycleCheck.h @@ -9,46 +9,42 @@ #include "Lucene.h" -namespace Lucene -{ - /// Debug utility to track shared_ptr utilization. - class LPPAPI CycleCheck - { - public: - virtual ~CycleCheck(); - - protected: - static MapStringInt cycleMap; - static Set staticRefs; - - protected: - void addRef(const String& className, int32_t ref); - static void addStatic(LuceneObjectPtr* staticRef); - - public: - template - static void addStatic(TYPE& staticRef) - { - addStatic(reinterpret_cast(&staticRef)); - } - - static void dumpRefs(); - }; +namespace Lucene { +/// Debug utility to track shared_ptr utilization. +class LPPAPI CycleCheck { +public: + virtual ~CycleCheck(); + +protected: + static MapStringInt cycleMap; + static Set staticRefs; + +protected: + void addRef(const String& className, int32_t ref); + static void addStatic(LuceneObjectPtr* staticRef); + +public: template - class CycleCheckT : public CycleCheck - { - public: - CycleCheckT() - { - addRef(TYPE::_getClassName(), 1); - } - - virtual ~CycleCheckT() - { - addRef(TYPE::_getClassName(), -1); - } - }; + static void addStatic(TYPE& staticRef) { + addStatic(reinterpret_cast(&staticRef)); + } + + static void dumpRefs(); +}; + +template +class CycleCheckT : public CycleCheck { +public: + CycleCheckT() { + addRef(TYPE::_getClassName(), 1); + } + + virtual ~CycleCheckT() { + addRef(TYPE::_getClassName(), -1); + } +}; + } #endif diff --git a/include/DateField.h b/include/DateField.h index 5262b3cc..ee9c4d89 100644 --- a/include/DateField.h +++ b/include/DateField.h @@ -9,48 +9,48 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Provides support for converting dates to strings and vice-versa. The strings are structured so that - /// lexicographic sorting orders by date, which makes them suitable for use as field values and search terms. - /// - /// Note that this class saves dates with millisecond granularity, which is bad for {@link TermRangeQuery} and - /// {@link PrefixQuery}, as those queries are expanded to a BooleanQuery with a potentially large number of terms - /// when searching. Thus you might want to use {@link DateTools} instead. - /// - /// Note: dates before 1970 cannot be used, and therefore cannot be indexed when using this class. See {@link - /// DateTools} for an alternative without such a limitation. - /// - /// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) - /// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix - /// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric - /// value with {@link NumericField} and use {@link NumericRangeQuery} to query it. - /// - /// @deprecated If you build a new index, use {@link DateTools} or {@link NumericField} instead. This class is - /// included for use with existing indices and will be removed in a future release (possibly Lucene 4.0). - class LPPAPI DateField : public LuceneObject - { - public: - virtual ~DateField(); - - LUCENE_CLASS(DateField); - - protected: - static int32_t DATE_LEN(); - - public: - static const String& MIN_DATE_STRING(); - static const String& MAX_DATE_STRING(); - - /// Converts a Date to a string suitable for indexing. - static String dateToString(const boost::posix_time::ptime& date); - - /// Converts a millisecond time to a string suitable for indexing. - static String timeToString(int64_t time); - - /// Converts a string-encoded date into a millisecond time. - static int64_t stringToTime(const String& s); - }; +namespace Lucene { + +/// Provides support for converting dates to strings and vice-versa. The strings are structured so that +/// lexicographic sorting orders by date, which makes them suitable for use as field values and search terms. +/// +/// Note that this class saves dates with millisecond granularity, which is bad for {@link TermRangeQuery} and +/// {@link PrefixQuery}, as those queries are expanded to a BooleanQuery with a potentially large number of terms +/// when searching. Thus you might want to use {@link DateTools} instead. +/// +/// Note: dates before 1970 cannot be used, and therefore cannot be indexed when using this class. See {@link +/// DateTools} for an alternative without such a limitation. +/// +/// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) +/// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix +/// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric +/// value with {@link NumericField} and use {@link NumericRangeQuery} to query it. +/// +/// @deprecated If you build a new index, use {@link DateTools} or {@link NumericField} instead. This class is +/// included for use with existing indices and will be removed in a future release (possibly Lucene 4.0). +class LPPAPI DateField : public LuceneObject { +public: + virtual ~DateField(); + + LUCENE_CLASS(DateField); + +protected: + static int32_t DATE_LEN(); + +public: + static const String& MIN_DATE_STRING(); + static const String& MAX_DATE_STRING(); + + /// Converts a Date to a string suitable for indexing. + static String dateToString(const boost::posix_time::ptime& date); + + /// Converts a millisecond time to a string suitable for indexing. + static String timeToString(int64_t time); + + /// Converts a string-encoded date into a millisecond time. + static int64_t stringToTime(const String& s); +}; + } #endif diff --git a/include/DateTools.h b/include/DateTools.h index aab645b4..0a4126fb 100644 --- a/include/DateTools.h +++ b/include/DateTools.h @@ -9,102 +9,100 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Provides support for converting dates to strings and vice-versa. The strings are structured so that - /// lexicographic sorting orders them by date, which makes them suitable for use as field values and search - /// terms. - /// - /// This class also helps you to limit the resolution of your dates. Do not save dates with a finer resolution - /// than you really need, as then RangeQuery and PrefixQuery will require more memory and become slower. - /// - /// Compared to {@link DateField} the strings generated by the methods in this class take slightly more space, - /// unless your selected resolution is set to Resolution.DAY or lower. - /// - /// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) - /// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix - /// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric - /// value with {@link NumericField} and use {@link NumericRangeQuery} to query it. - class LPPAPI DateTools : public LuceneObject - { - public: - virtual ~DateTools(); - - LUCENE_CLASS(DateTools); - - public: - enum Resolution - { - RESOLUTION_NULL, - RESOLUTION_YEAR, - RESOLUTION_MONTH, - RESOLUTION_DAY, - RESOLUTION_HOUR, - RESOLUTION_MINUTE, - RESOLUTION_SECOND, - RESOLUTION_MILLISECOND - }; - - enum DateOrder - { - DATEORDER_LOCALE, - DATEORDER_YMD, - DATEORDER_DMY, - DATEORDER_MDY - }; - - protected: - static DateOrder dateOrder; - - public: - /// Converts a Date to a string suitable for indexing. - /// @param date the date to be converted - /// @param resolution the desired resolution - /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone - static String dateToString(const boost::posix_time::ptime& date, Resolution resolution); - - /// Converts a millisecond time to a string suitable for indexing. - /// @param time the date expressed as milliseconds since January 1, 1970, 00:00:00 GMT - /// @param resolution the desired resolution - /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone - static String timeToString(int64_t time, Resolution resolution); - - /// Converts a string produced by timeToString or dateToString back to a time, represented as the number of - /// milliseconds since January 1, 1970, 00:00:00 GMT. - /// @param dateString the date string to be converted - /// @return the number of milliseconds since January 1, 1970, 00:00:00 GMT - static int64_t stringToTime(const String& dateString); - - /// Converts a string produced by timeToString or dateToString back to a time, represented as a ptime object. - /// @param dateString the date string to be converted - /// @return the parsed time as a ptime object - static boost::posix_time::ptime stringToDate(const String& dateString); - - /// Limit a date's resolution. For example, the date 2004-09-21 13:50:11 will be changed to 2004-09-01 00:00:00 - /// when using Resolution.MONTH. - /// @param resolution The desired resolution of the date to be returned - /// @return the date with all values more precise than resolution set to 0 or 1 - static boost::posix_time::ptime round(const boost::posix_time::ptime& date, Resolution resolution); - - /// Limit a date's resolution. For example, the date 1095767411000 (which represents 2004-09-21 13:50:11) will - /// be changed to 1093989600000 (2004-09-01 00:00:00) when using Resolution.MONTH. - /// @param resolution The desired resolution of the date to be returned - /// @return the date with all values more precise than resolution set to 0 or 1, expressed as milliseconds - /// since January 1, 1970, 00:00:00 GMT - static int64_t round(int64_t time, Resolution resolution); - - /// Allow overriding of date ordering. - static void setDateOrder(DateTools::DateOrder order); - - /// Return date ordering based on given locale (or overridden in {@link #setDateOrder(DateTools::DateOrder)}). - static DateTools::DateOrder getDateOrder(std::locale locale = std::locale()); - - /// Parse a given date using locale date format - /// @param dateString the date string to be converted - /// @param locale the locale to use for parsing - /// @return the parsed time as a ptime object - static boost::posix_time::ptime parseDate(const String& dateString, std::locale locale = std::locale()); +namespace Lucene { + +/// Provides support for converting dates to strings and vice-versa. The strings are structured so that +/// lexicographic sorting orders them by date, which makes them suitable for use as field values and search +/// terms. +/// +/// This class also helps you to limit the resolution of your dates. Do not save dates with a finer resolution +/// than you really need, as then RangeQuery and PrefixQuery will require more memory and become slower. +/// +/// Compared to {@link DateField} the strings generated by the methods in this class take slightly more space, +/// unless your selected resolution is set to Resolution.DAY or lower. +/// +/// Another approach is {@link NumericUtils}, which provides a sortable binary representation (prefix encoded) +/// of numeric values, which date/time are. For indexing a {@link Date} or {@link Calendar}, just get the unix +/// timestamp as long using {@link Date#getTime} or {@link Calendar#getTimeInMillis} and index this as a numeric +/// value with {@link NumericField} and use {@link NumericRangeQuery} to query it. +class LPPAPI DateTools : public LuceneObject { +public: + virtual ~DateTools(); + + LUCENE_CLASS(DateTools); + +public: + enum Resolution { + RESOLUTION_NULL, + RESOLUTION_YEAR, + RESOLUTION_MONTH, + RESOLUTION_DAY, + RESOLUTION_HOUR, + RESOLUTION_MINUTE, + RESOLUTION_SECOND, + RESOLUTION_MILLISECOND }; + + enum DateOrder { + DATEORDER_LOCALE, + DATEORDER_YMD, + DATEORDER_DMY, + DATEORDER_MDY + }; + +protected: + static DateOrder dateOrder; + +public: + /// Converts a Date to a string suitable for indexing. + /// @param date the date to be converted + /// @param resolution the desired resolution + /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone + static String dateToString(const boost::posix_time::ptime& date, Resolution resolution); + + /// Converts a millisecond time to a string suitable for indexing. + /// @param time the date expressed as milliseconds since January 1, 1970, 00:00:00 GMT + /// @param resolution the desired resolution + /// @return a string in format yyyyMMddHHmmssSSS or shorter, depending on resolution; using GMT as timezone + static String timeToString(int64_t time, Resolution resolution); + + /// Converts a string produced by timeToString or dateToString back to a time, represented as the number of + /// milliseconds since January 1, 1970, 00:00:00 GMT. + /// @param dateString the date string to be converted + /// @return the number of milliseconds since January 1, 1970, 00:00:00 GMT + static int64_t stringToTime(const String& dateString); + + /// Converts a string produced by timeToString or dateToString back to a time, represented as a ptime object. + /// @param dateString the date string to be converted + /// @return the parsed time as a ptime object + static boost::posix_time::ptime stringToDate(const String& dateString); + + /// Limit a date's resolution. For example, the date 2004-09-21 13:50:11 will be changed to 2004-09-01 00:00:00 + /// when using Resolution.MONTH. + /// @param resolution The desired resolution of the date to be returned + /// @return the date with all values more precise than resolution set to 0 or 1 + static boost::posix_time::ptime round(const boost::posix_time::ptime& date, Resolution resolution); + + /// Limit a date's resolution. For example, the date 1095767411000 (which represents 2004-09-21 13:50:11) will + /// be changed to 1093989600000 (2004-09-01 00:00:00) when using Resolution.MONTH. + /// @param resolution The desired resolution of the date to be returned + /// @return the date with all values more precise than resolution set to 0 or 1, expressed as milliseconds + /// since January 1, 1970, 00:00:00 GMT + static int64_t round(int64_t time, Resolution resolution); + + /// Allow overriding of date ordering. + static void setDateOrder(DateTools::DateOrder order); + + /// Return date ordering based on given locale (or overridden in {@link #setDateOrder(DateTools::DateOrder)}). + static DateTools::DateOrder getDateOrder(std::locale locale = std::locale()); + + /// Parse a given date using locale date format + /// @param dateString the date string to be converted + /// @param locale the locale to use for parsing + /// @return the parsed time as a ptime object + static boost::posix_time::ptime parseDate(const String& dateString, std::locale locale = std::locale()); +}; + } #endif diff --git a/include/DefaultSimilarity.h b/include/DefaultSimilarity.h index b2c77586..78f18696 100644 --- a/include/DefaultSimilarity.h +++ b/include/DefaultSimilarity.h @@ -9,52 +9,52 @@ #include "Similarity.h" -namespace Lucene -{ - /// Default scoring implementation. - class LPPAPI DefaultSimilarity : public Similarity - { - public: - DefaultSimilarity(); - virtual ~DefaultSimilarity(); +namespace Lucene { - LUCENE_CLASS(DefaultSimilarity); +/// Default scoring implementation. +class LPPAPI DefaultSimilarity : public Similarity { +public: + DefaultSimilarity(); + virtual ~DefaultSimilarity(); - protected: - bool discountOverlaps; // Default false + LUCENE_CLASS(DefaultSimilarity); - public: - /// Implemented as state->getBoost() * lengthNorm(numTerms), where numTerms is {@link - /// FieldInvertState#getLength()} if {@link #setDiscountOverlaps} is false, else it's {@link - /// FieldInvertState#getLength()} - {@link FieldInvertState#getNumOverlap()}. - virtual double computeNorm(const String& fieldName, const FieldInvertStatePtr& state); +protected: + bool discountOverlaps; // Default false - /// Implemented as 1 / sqrt(numTerms). - virtual double lengthNorm(const String& fieldName, int32_t numTokens); +public: + /// Implemented as state->getBoost() * lengthNorm(numTerms), where numTerms is {@link + /// FieldInvertState#getLength()} if {@link #setDiscountOverlaps} is false, else it's {@link + /// FieldInvertState#getLength()} - {@link FieldInvertState#getNumOverlap()}. + virtual double computeNorm(const String& fieldName, const FieldInvertStatePtr& state); - /// Implemented as 1 / sqrt(sumOfSquaredWeights). - virtual double queryNorm(double sumOfSquaredWeights); + /// Implemented as 1 / sqrt(numTerms). + virtual double lengthNorm(const String& fieldName, int32_t numTokens); - /// Implemented as sqrt(freq). - virtual double tf(double freq); + /// Implemented as 1 / sqrt(sumOfSquaredWeights). + virtual double queryNorm(double sumOfSquaredWeights); - /// Implemented as 1 / (distance + 1). - virtual double sloppyFreq(int32_t distance); + /// Implemented as sqrt(freq). + virtual double tf(double freq); - /// Implemented as log(numDocs / (docFreq + 1)) + 1. - virtual double idf(int32_t docFreq, int32_t numDocs); + /// Implemented as 1 / (distance + 1). + virtual double sloppyFreq(int32_t distance); - /// Implemented as overlap / maxOverlap. - virtual double coord(int32_t overlap, int32_t maxOverlap); + /// Implemented as log(numDocs / (docFreq + 1)) + 1. + virtual double idf(int32_t docFreq, int32_t numDocs); - /// Determines whether overlap tokens (Tokens with 0 position increment) are ignored when computing - /// norm. By default this is false, meaning overlap tokens are counted just like non-overlap tokens. - /// @see #computeNorm - void setDiscountOverlaps(bool v); + /// Implemented as overlap / maxOverlap. + virtual double coord(int32_t overlap, int32_t maxOverlap); + + /// Determines whether overlap tokens (Tokens with 0 position increment) are ignored when computing + /// norm. By default this is false, meaning overlap tokens are counted just like non-overlap tokens. + /// @see #computeNorm + void setDiscountOverlaps(bool v); + + /// @see #setDiscountOverlaps + bool getDiscountOverlaps(); +}; - /// @see #setDiscountOverlaps - bool getDiscountOverlaps(); - }; } #endif diff --git a/include/DefaultSkipListReader.h b/include/DefaultSkipListReader.h index ac2d451c..073fd8fc 100644 --- a/include/DefaultSkipListReader.h +++ b/include/DefaultSkipListReader.h @@ -9,52 +9,52 @@ #include "MultiLevelSkipListReader.h" -namespace Lucene -{ - /// Implements the skip list reader for the default posting list format that stores positions and payloads. - class DefaultSkipListReader : public MultiLevelSkipListReader - { - public: - DefaultSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval); - virtual ~DefaultSkipListReader(); - - LUCENE_CLASS(DefaultSkipListReader); - - protected: - bool currentFieldStoresPayloads; - Collection freqPointer; - Collection proxPointer; - Collection payloadLength; - - int64_t lastFreqPointer; - int64_t lastProxPointer; - int32_t lastPayloadLength; - - public: - void init(int64_t skipPointer, int64_t freqBasePointer, int64_t proxBasePointer, int32_t df, bool storesPayloads); - - /// Returns the freq pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} - /// has skipped. - int64_t getFreqPointer(); - - /// Returns the prox pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} - /// has skipped. - int64_t getProxPointer(); - - /// Returns the payload length of the payload stored just before the doc to which the last call of {@link - /// MultiLevelSkipListReader#skipTo(int)} has skipped. - int32_t getPayloadLength(); - - protected: - /// Seeks the skip entry on the given level - virtual void seekChild(int32_t level); - - /// Copies the values of the last read skip entry on this level - virtual void setLastSkipData(int32_t level); - - /// Subclasses must implement the actual skip data encoding in this method. - virtual int32_t readSkipData(int32_t level, const IndexInputPtr& skipStream); - }; +namespace Lucene { + +/// Implements the skip list reader for the default posting list format that stores positions and payloads. +class DefaultSkipListReader : public MultiLevelSkipListReader { +public: + DefaultSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval); + virtual ~DefaultSkipListReader(); + + LUCENE_CLASS(DefaultSkipListReader); + +protected: + bool currentFieldStoresPayloads; + Collection freqPointer; + Collection proxPointer; + Collection payloadLength; + + int64_t lastFreqPointer; + int64_t lastProxPointer; + int32_t lastPayloadLength; + +public: + void init(int64_t skipPointer, int64_t freqBasePointer, int64_t proxBasePointer, int32_t df, bool storesPayloads); + + /// Returns the freq pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} + /// has skipped. + int64_t getFreqPointer(); + + /// Returns the prox pointer of the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} + /// has skipped. + int64_t getProxPointer(); + + /// Returns the payload length of the payload stored just before the doc to which the last call of {@link + /// MultiLevelSkipListReader#skipTo(int)} has skipped. + int32_t getPayloadLength(); + +protected: + /// Seeks the skip entry on the given level + virtual void seekChild(int32_t level); + + /// Copies the values of the last read skip entry on this level + virtual void setLastSkipData(int32_t level); + + /// Subclasses must implement the actual skip data encoding in this method. + virtual int32_t readSkipData(int32_t level, const IndexInputPtr& skipStream); +}; + } #endif diff --git a/include/DefaultSkipListWriter.h b/include/DefaultSkipListWriter.h index cef4f5d8..ae467a3b 100644 --- a/include/DefaultSkipListWriter.h +++ b/include/DefaultSkipListWriter.h @@ -9,45 +9,45 @@ #include "MultiLevelSkipListWriter.h" -namespace Lucene -{ - /// Implements the skip list writer for the default posting list format that stores positions and payloads. - class DefaultSkipListWriter : public MultiLevelSkipListWriter - { - public: - DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, const IndexOutputPtr& freqOutput, const IndexOutputPtr& proxOutput); - virtual ~DefaultSkipListWriter(); - - LUCENE_CLASS(DefaultSkipListWriter); - - protected: - Collection lastSkipDoc; - Collection lastSkipPayloadLength; - Collection lastSkipFreqPointer; - Collection lastSkipProxPointer; - - IndexOutputPtr freqOutput; - IndexOutputPtr proxOutput; - - int32_t curDoc; - bool curStorePayloads; - int32_t curPayloadLength; - int64_t curFreqPointer; - int64_t curProxPointer; - - public: - void setFreqOutput(const IndexOutputPtr& freqOutput); - void setProxOutput(const IndexOutputPtr& proxOutput); - - /// Sets the values for the current skip data. - void setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength); - - protected: - virtual void resetSkip(); - virtual void writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer); - - friend class FormatPostingsTermsWriter; - }; +namespace Lucene { + +/// Implements the skip list writer for the default posting list format that stores positions and payloads. +class DefaultSkipListWriter : public MultiLevelSkipListWriter { +public: + DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, const IndexOutputPtr& freqOutput, const IndexOutputPtr& proxOutput); + virtual ~DefaultSkipListWriter(); + + LUCENE_CLASS(DefaultSkipListWriter); + +protected: + Collection lastSkipDoc; + Collection lastSkipPayloadLength; + Collection lastSkipFreqPointer; + Collection lastSkipProxPointer; + + IndexOutputPtr freqOutput; + IndexOutputPtr proxOutput; + + int32_t curDoc; + bool curStorePayloads; + int32_t curPayloadLength; + int64_t curFreqPointer; + int64_t curProxPointer; + +public: + void setFreqOutput(const IndexOutputPtr& freqOutput); + void setProxOutput(const IndexOutputPtr& proxOutput); + + /// Sets the values for the current skip data. + void setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength); + +protected: + virtual void resetSkip(); + virtual void writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer); + + friend class FormatPostingsTermsWriter; +}; + } #endif diff --git a/include/Directory.h b/include/Directory.h index 88820704..826159ab 100644 --- a/include/Directory.h +++ b/include/Directory.h @@ -9,102 +9,102 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A Directory is a flat list of files. Files may be written once, when they are created. Once a file - /// is created it may only be opened for read, or deleted. Random access is permitted both when reading - /// and writing. Directory locking is implemented by an instance of {@link LockFactory}, and can be changed - /// for each Directory instance using {@link #setLockFactory}. - class LPPAPI Directory : public LuceneObject - { - public: - Directory(); - virtual ~Directory(); - - LUCENE_CLASS(Directory); - - protected: - bool isOpen; - - /// Holds the LockFactory instance (implements locking for this Directory instance). - LockFactoryPtr lockFactory; - - public: - /// Returns an array of strings, one for each file in the directory. - virtual HashSet listAll() = 0; - - /// Returns true if a file with the given name exists. - virtual bool fileExists(const String& name) = 0; - - /// Returns the time the named file was last modified. - virtual uint64_t fileModified(const String& name) = 0; - - /// Set the modified time of an existing file to now. - virtual void touchFile(const String& name) = 0; - - /// Removes an existing file in the directory. - virtual void deleteFile(const String& name) = 0; - - /// Returns the length of a file in the directory. - virtual int64_t fileLength(const String& name) = 0; - - /// Creates a new, empty file in the directory with the given name. - /// Returns a stream writing this file. - virtual IndexOutputPtr createOutput(const String& name) = 0; - - /// Returns a stream reading an existing file. - virtual IndexInputPtr openInput(const String& name) = 0; - - /// Closes the store. - virtual void close() = 0; - - /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit - /// changes to the index, to prevent a machine/OS crash from corrupting the index. - virtual void sync(const String& name); - - /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory - /// implementation may ignore the buffer size. Currently the only Directory implementations that respect - /// this parameter are {@link FSDirectory} and {@link CompoundFileReader}. - virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - - /// Construct a {@link Lock}. - /// @param name the name of the lock file. - virtual LockPtr makeLock(const String& name); - - /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you - /// are certain this lock is no longer in use. - /// @param name name of the lock to be cleared. - void clearLock(const String& name); - - /// Set the LockFactory that this Directory instance should use for its locking implementation. Each * instance - /// of LockFactory should only be used for one directory (ie, do not share a single instance across multiple - /// Directories). - /// @param lockFactory instance of {@link LockFactory}. - void setLockFactory(const LockFactoryPtr& lockFactory); - - /// Get the LockFactory that this Directory instance is using for its locking implementation. Note that this - /// may be null for Directory implementations that provide their own locking implementation. - LockFactoryPtr getLockFactory(); - - /// Return a string identifier that uniquely differentiates this Directory instance from other Directory - /// instances. This ID should be the same if two Directory instances are considered "the same index". - /// This is how locking "scopes" to the right index. - virtual String getLockID(); - - virtual String toString(); - - /// Copy contents of a directory src to a directory dest. If a file in src already exists in dest then the one - /// in dest will be blindly overwritten. NOTE: the source directory cannot change while this method is running. - /// Otherwise the results are undefined. - /// @param src source directory. - /// @param dest destination directory. - /// @param closeDirSrc if true, call {@link #close()} method on source directory. - static void copy(const DirectoryPtr& src, const DirectoryPtr& dest, bool closeDirSrc); - - protected: - /// @throws AlreadyClosed if this Directory is closed. - void ensureOpen(); - }; +namespace Lucene { + +/// A Directory is a flat list of files. Files may be written once, when they are created. Once a file +/// is created it may only be opened for read, or deleted. Random access is permitted both when reading +/// and writing. Directory locking is implemented by an instance of {@link LockFactory}, and can be changed +/// for each Directory instance using {@link #setLockFactory}. +class LPPAPI Directory : public LuceneObject { +public: + Directory(); + virtual ~Directory(); + + LUCENE_CLASS(Directory); + +protected: + bool isOpen; + + /// Holds the LockFactory instance (implements locking for this Directory instance). + LockFactoryPtr lockFactory; + +public: + /// Returns an array of strings, one for each file in the directory. + virtual HashSet listAll() = 0; + + /// Returns true if a file with the given name exists. + virtual bool fileExists(const String& name) = 0; + + /// Returns the time the named file was last modified. + virtual uint64_t fileModified(const String& name) = 0; + + /// Set the modified time of an existing file to now. + virtual void touchFile(const String& name) = 0; + + /// Removes an existing file in the directory. + virtual void deleteFile(const String& name) = 0; + + /// Returns the length of a file in the directory. + virtual int64_t fileLength(const String& name) = 0; + + /// Creates a new, empty file in the directory with the given name. + /// Returns a stream writing this file. + virtual IndexOutputPtr createOutput(const String& name) = 0; + + /// Returns a stream reading an existing file. + virtual IndexInputPtr openInput(const String& name) = 0; + + /// Closes the store. + virtual void close() = 0; + + /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit + /// changes to the index, to prevent a machine/OS crash from corrupting the index. + virtual void sync(const String& name); + + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory + /// implementation may ignore the buffer size. Currently the only Directory implementations that respect + /// this parameter are {@link FSDirectory} and {@link CompoundFileReader}. + virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); + + /// Construct a {@link Lock}. + /// @param name the name of the lock file. + virtual LockPtr makeLock(const String& name); + + /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you + /// are certain this lock is no longer in use. + /// @param name name of the lock to be cleared. + void clearLock(const String& name); + + /// Set the LockFactory that this Directory instance should use for its locking implementation. Each * instance + /// of LockFactory should only be used for one directory (ie, do not share a single instance across multiple + /// Directories). + /// @param lockFactory instance of {@link LockFactory}. + void setLockFactory(const LockFactoryPtr& lockFactory); + + /// Get the LockFactory that this Directory instance is using for its locking implementation. Note that this + /// may be null for Directory implementations that provide their own locking implementation. + LockFactoryPtr getLockFactory(); + + /// Return a string identifier that uniquely differentiates this Directory instance from other Directory + /// instances. This ID should be the same if two Directory instances are considered "the same index". + /// This is how locking "scopes" to the right index. + virtual String getLockID(); + + virtual String toString(); + + /// Copy contents of a directory src to a directory dest. If a file in src already exists in dest then the one + /// in dest will be blindly overwritten. NOTE: the source directory cannot change while this method is running. + /// Otherwise the results are undefined. + /// @param src source directory. + /// @param dest destination directory. + /// @param closeDirSrc if true, call {@link #close()} method on source directory. + static void copy(const DirectoryPtr& src, const DirectoryPtr& dest, bool closeDirSrc); + +protected: + /// @throws AlreadyClosed if this Directory is closed. + void ensureOpen(); +}; + } #endif diff --git a/include/DirectoryReader.h b/include/DirectoryReader.h index c91ff3f8..0fa417d9 100644 --- a/include/DirectoryReader.h +++ b/include/DirectoryReader.h @@ -13,341 +13,337 @@ #include "IndexCommit.h" #include "SegmentMergeQueue.h" -namespace Lucene -{ - /// An IndexReader which reads indexes with multiple segments. - class DirectoryReader : public IndexReader - { - public: - /// Construct reading the named set of readers. - DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); +namespace Lucene { - /// Used by near real-time search. - DirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor); +/// An IndexReader which reads indexes with multiple segments. +class DirectoryReader : public IndexReader { +public: + /// Construct reading the named set of readers. + DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); - /// This constructor is only used for {@link #reopen()} - DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, - Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, - bool doClone, int32_t termInfosIndexDivisor); + /// Used by near real-time search. + DirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor); - virtual ~DirectoryReader(); + /// This constructor is only used for {@link #reopen()} + DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, + Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, + bool doClone, int32_t termInfosIndexDivisor); - LUCENE_CLASS(DirectoryReader); + virtual ~DirectoryReader(); - protected: - DirectoryPtr _directory; - bool readOnly; - IndexWriterWeakPtr _writer; - IndexDeletionPolicyPtr deletionPolicy; - HashSet synced; - LockPtr writeLock; - SegmentInfosPtr segmentInfos; - SegmentInfosPtr segmentInfosStart; - bool stale; - int32_t termInfosIndexDivisor; + LUCENE_CLASS(DirectoryReader); - bool rollbackHasChanges; +protected: + DirectoryPtr _directory; + bool readOnly; + IndexWriterWeakPtr _writer; + IndexDeletionPolicyPtr deletionPolicy; + HashSet synced; + LockPtr writeLock; + SegmentInfosPtr segmentInfos; + SegmentInfosPtr segmentInfosStart; + bool stale; + int32_t termInfosIndexDivisor; - Collection subReaders; - Collection starts; // 1st docno for each segment - MapStringByteArray normsCache; - int32_t _maxDoc; - int32_t _numDocs; - bool _hasDeletions; + bool rollbackHasChanges; - // Max version in index as of when we opened; this can be > our current segmentInfos version - // in case we were opened on a past IndexCommit - int64_t maxIndexVersion; + Collection subReaders; + Collection starts; // 1st docno for each segment + MapStringByteArray normsCache; + int32_t _maxDoc; + int32_t _numDocs; + bool _hasDeletions; - public: - void _initialize(Collection subReaders); + // Max version in index as of when we opened; this can be > our current segmentInfos version + // in case we were opened on a past IndexCommit + int64_t maxIndexVersion; - static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor); +public: + void _initialize(Collection subReaders); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor); - virtual IndexReaderPtr reopen(); - virtual IndexReaderPtr reopen(bool openReadOnly); - virtual IndexReaderPtr reopen(const IndexCommitPtr& commit); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); - /// Version number when this IndexReader was opened. - virtual int64_t getVersion(); + virtual IndexReaderPtr reopen(); + virtual IndexReaderPtr reopen(bool openReadOnly); + virtual IndexReaderPtr reopen(const IndexCommitPtr& commit); - /// Return an array of term frequency vectors for the specified document. - virtual Collection getTermFreqVectors(int32_t docNumber); + /// Version number when this IndexReader was opened. + virtual int64_t getVersion(); - /// Return a term frequency vector for the specified document and field. - virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); + /// Return an array of term frequency vectors for the specified document. + virtual Collection getTermFreqVectors(int32_t docNumber); - /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays of the {@link TermFreqVector}. - virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + /// Return a term frequency vector for the specified document and field. + virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - /// Map all the term vectors for all fields in a Document - virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays of the {@link TermFreqVector}. + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); - /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented in the IndexReader base class. - /// @return true if the index is optimized; false otherwise - virtual bool isOptimized(); + /// Map all the term vectors for all fields in a Document + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); - /// Returns the number of documents in this index. - virtual int32_t numDocs(); + /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented in the IndexReader base class. + /// @return true if the index is optimized; false otherwise + virtual bool isOptimized(); - /// Returns one greater than the largest possible document number. - virtual int32_t maxDoc(); + /// Returns the number of documents in this index. + virtual int32_t numDocs(); - /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what {@link Field}s to load and how they should be loaded. - virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); + /// Returns one greater than the largest possible document number. + virtual int32_t maxDoc(); - /// Returns true if document n has been deleted - virtual bool isDeleted(int32_t n); + /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what {@link Field}s to load and how they should be loaded. + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); - /// Returns true if any documents have been deleted - virtual bool hasDeletions(); + /// Returns true if document n has been deleted + virtual bool isDeleted(int32_t n); - /// Find reader for doc n - static int32_t readerIndex(int32_t n, Collection starts, int32_t numSubReaders); + /// Returns true if any documents have been deleted + virtual bool hasDeletions(); - /// Returns true if there are norms stored for this field. - virtual bool hasNorms(const String& field); + /// Find reader for doc n + static int32_t readerIndex(int32_t n, Collection starts, int32_t numSubReaders); - /// Returns the byte-encoded normalization factor for the named field of every document. - virtual ByteArray norms(const String& field); + /// Returns true if there are norms stored for this field. + virtual bool hasNorms(const String& field); - /// Reads the byte-encoded normalization factor for the named field of every document. - virtual void norms(const String& field, ByteArray norms, int32_t offset); + /// Returns the byte-encoded normalization factor for the named field of every document. + virtual ByteArray norms(const String& field); - /// Returns an enumeration of all the terms in the index. - virtual TermEnumPtr terms(); + /// Reads the byte-encoded normalization factor for the named field of every document. + virtual void norms(const String& field, ByteArray norms, int32_t offset); - /// Returns an enumeration of all terms starting at a given term. - virtual TermEnumPtr terms(const TermPtr& t); + /// Returns an enumeration of all the terms in the index. + virtual TermEnumPtr terms(); - /// Returns the number of documents containing the term t. - virtual int32_t docFreq(const TermPtr& t); + /// Returns an enumeration of all terms starting at a given term. + virtual TermEnumPtr terms(const TermPtr& t); - /// Returns an unpositioned {@link TermDocs} enumerator. - virtual TermDocsPtr termDocs(); + /// Returns the number of documents containing the term t. + virtual int32_t docFreq(const TermPtr& t); - /// Returns an unpositioned {@link TermPositions} enumerator. - virtual TermPositionsPtr termPositions(); + /// Returns an unpositioned {@link TermDocs} enumerator. + virtual TermDocsPtr termDocs(); - /// Tries to acquire the WriteLock on this directory. this method is only valid if this - /// IndexReader is directory owner. - virtual void acquireWriteLock(); + /// Returns an unpositioned {@link TermPositions} enumerator. + virtual TermPositionsPtr termPositions(); - void startCommit(); - void rollbackCommit(); + /// Tries to acquire the WriteLock on this directory. this method is only valid if this + /// IndexReader is directory owner. + virtual void acquireWriteLock(); - /// Retrieve the String userData optionally passed to IndexWriter#commit. - virtual MapStringString getCommitUserData(); + void startCommit(); + void rollbackCommit(); - /// Check whether any new changes have occurred to the index since this reader was opened. - virtual bool isCurrent(); + /// Retrieve the String userData optionally passed to IndexWriter#commit. + virtual MapStringString getCommitUserData(); - /// Get a list of unique field names that exist in this index and have the specified field - /// option information. - virtual HashSet getFieldNames(FieldOption fieldOption); + /// Check whether any new changes have occurred to the index since this reader was opened. + virtual bool isCurrent(); - static HashSet getFieldNames(FieldOption fieldOption, Collection subReaders); + /// Get a list of unique field names that exist in this index and have the specified field + /// option information. + virtual HashSet getFieldNames(FieldOption fieldOption); - /// Returns the sequential sub readers that this reader is logically composed of. - virtual Collection getSequentialSubReaders(); + static HashSet getFieldNames(FieldOption fieldOption, Collection subReaders); - /// Returns the directory this index resides in. - virtual DirectoryPtr directory(); + /// Returns the sequential sub readers that this reader is logically composed of. + virtual Collection getSequentialSubReaders(); - virtual int32_t getTermInfosIndexDivisor(); + /// Returns the directory this index resides in. + virtual DirectoryPtr directory(); - /// Return the IndexCommit that this reader has opened. - virtual IndexCommitPtr getIndexCommit(); + virtual int32_t getTermInfosIndexDivisor(); - /// Returns all commit points that exist in the Directory. - static Collection listCommits(const DirectoryPtr& dir); + /// Return the IndexCommit that this reader has opened. + virtual IndexCommitPtr getIndexCommit(); - protected: - IndexReaderPtr doReopenFromWriter(bool openReadOnly, const IndexCommitPtr& commit); - IndexReaderPtr doReopen(bool openReadOnly, const IndexCommitPtr& commit); - IndexReaderPtr doReopenNoWriter(bool openReadOnly, const IndexCommitPtr& commit); - DirectoryReaderPtr doReopen(const SegmentInfosPtr& infos, bool doClone, bool openReadOnly); + /// Returns all commit points that exist in the Directory. + static Collection listCommits(const DirectoryPtr& dir); - /// Implements deletion of the document numbered docNum. - virtual void doDelete(int32_t docNum); +protected: + IndexReaderPtr doReopenFromWriter(bool openReadOnly, const IndexCommitPtr& commit); + IndexReaderPtr doReopen(bool openReadOnly, const IndexCommitPtr& commit); + IndexReaderPtr doReopenNoWriter(bool openReadOnly, const IndexCommitPtr& commit); + DirectoryReaderPtr doReopen(const SegmentInfosPtr& infos, bool doClone, bool openReadOnly); - /// Implements actual undeleteAll() in subclass. - virtual void doUndeleteAll(); + /// Implements deletion of the document numbered docNum. + virtual void doDelete(int32_t docNum); - int32_t readerIndex(int32_t n); + /// Implements actual undeleteAll() in subclass. + virtual void doUndeleteAll(); - /// Implements setNorm in subclass. - virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + int32_t readerIndex(int32_t n); - /// Commit changes resulting from delete, undeleteAll, or setNorm operations - /// - /// If an exception is hit, then either no changes or all changes will have been committed to the index (transactional semantics). - virtual void doCommit(MapStringString commitUserData); + /// Implements setNorm in subclass. + virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - /// Implements close. - virtual void doClose(); + /// Commit changes resulting from delete, undeleteAll, or setNorm operations + /// + /// If an exception is hit, then either no changes or all changes will have been committed to the index (transactional semantics). + virtual void doCommit(MapStringString commitUserData); - friend class FindSegmentsReopen; - }; + /// Implements close. + virtual void doClose(); - class MultiTermEnum : public TermEnum - { - public: - MultiTermEnum(const IndexReaderPtr& topReader, Collection readers, Collection starts, const TermPtr& t); - virtual ~MultiTermEnum(); + friend class FindSegmentsReopen; +}; - LUCENE_CLASS(MultiTermEnum); +class MultiTermEnum : public TermEnum { +public: + MultiTermEnum(const IndexReaderPtr& topReader, Collection readers, Collection starts, const TermPtr& t); + virtual ~MultiTermEnum(); - protected: - SegmentMergeQueuePtr queue; - TermPtr _term; - int32_t _docFreq; + LUCENE_CLASS(MultiTermEnum); - public: - IndexReaderWeakPtr _topReader; - Collection matchingSegments; // null terminated array of matching segments +protected: + SegmentMergeQueuePtr queue; + TermPtr _term; + int32_t _docFreq; - public: - /// Increments the enumeration to the next element. True if one exists. - virtual bool next(); +public: + IndexReaderWeakPtr _topReader; + Collection matchingSegments; // null terminated array of matching segments - /// Returns the current Term in the enumeration. - virtual TermPtr term(); +public: + /// Increments the enumeration to the next element. True if one exists. + virtual bool next(); - /// Returns the docFreq of the current Term in the enumeration. - virtual int32_t docFreq(); + /// Returns the current Term in the enumeration. + virtual TermPtr term(); - /// Closes the enumeration to further activity, freeing resources. - virtual void close(); - }; + /// Returns the docFreq of the current Term in the enumeration. + virtual int32_t docFreq(); - class MultiTermDocs : public TermPositions, public LuceneObject - { - public: - MultiTermDocs(const IndexReaderPtr& topReader, Collection r, Collection s); - virtual ~MultiTermDocs(); + /// Closes the enumeration to further activity, freeing resources. + virtual void close(); +}; - LUCENE_CLASS(MultiTermDocs); +class MultiTermDocs : public TermPositions, public LuceneObject { +public: + MultiTermDocs(const IndexReaderPtr& topReader, Collection r, Collection s); + virtual ~MultiTermDocs(); - protected: - IndexReaderWeakPtr _topReader; // used for matching TermEnum to TermDocs - Collection readers; - Collection starts; - TermPtr term; + LUCENE_CLASS(MultiTermDocs); - int32_t base; - int32_t pointer; +protected: + IndexReaderWeakPtr _topReader; // used for matching TermEnum to TermDocs + Collection readers; + Collection starts; + TermPtr term; - Collection readerTermDocs; - TermDocsPtr current; - MultiTermEnumPtr tenum; // the term enum used for seeking - int32_t matchingSegmentPos; // position into the matching segments from tenum - SegmentMergeInfoPtr smi; // current segment mere info + int32_t base; + int32_t pointer; - public: - /// Returns the current document number. - virtual int32_t doc(); + Collection readerTermDocs; + TermDocsPtr current; + MultiTermEnumPtr tenum; // the term enum used for seeking + int32_t matchingSegmentPos; // position into the matching segments from tenum + SegmentMergeInfoPtr smi; // current segment mere info - /// Returns the frequency of the term within the current document. - virtual int32_t freq(); +public: + /// Returns the current document number. + virtual int32_t doc(); - /// Sets this to the data for a term. - virtual void seek(const TermPtr& term); + /// Returns the frequency of the term within the current document. + virtual int32_t freq(); - /// Sets this to the data for the current term in a {@link TermEnum}. - virtual void seek(const TermEnumPtr& termEnum); + /// Sets this to the data for a term. + virtual void seek(const TermPtr& term); - /// Moves to the next pair in the enumeration. - virtual bool next(); + /// Sets this to the data for the current term in a {@link TermEnum}. + virtual void seek(const TermEnumPtr& termEnum); - /// Attempts to read multiple entries from the enumeration, up to length of docs. - /// Optimized implementation. - virtual int32_t read(Collection docs, Collection freqs); + /// Moves to the next pair in the enumeration. + virtual bool next(); - /// Skips entries to the first beyond the current whose document number is greater than or equal to target. - virtual bool skipTo(int32_t target); + /// Attempts to read multiple entries from the enumeration, up to length of docs. + /// Optimized implementation. + virtual int32_t read(Collection docs, Collection freqs); - /// Frees associated resources. - virtual void close(); + /// Skips entries to the first beyond the current whose document number is greater than or equal to target. + virtual bool skipTo(int32_t target); - protected: - virtual TermDocsPtr termDocs(int32_t i); - virtual TermDocsPtr termDocs(const IndexReaderPtr& reader); - }; + /// Frees associated resources. + virtual void close(); - class MultiTermPositions : public MultiTermDocs - { - public: - MultiTermPositions(const IndexReaderPtr& topReader, Collection r, Collection s); - virtual ~MultiTermPositions(); +protected: + virtual TermDocsPtr termDocs(int32_t i); + virtual TermDocsPtr termDocs(const IndexReaderPtr& reader); +}; - LUCENE_CLASS(MultiTermPositions); +class MultiTermPositions : public MultiTermDocs { +public: + MultiTermPositions(const IndexReaderPtr& topReader, Collection r, Collection s); + virtual ~MultiTermPositions(); - public: - /// Returns next position in the current document. - virtual int32_t nextPosition(); + LUCENE_CLASS(MultiTermPositions); - /// Returns the length of the payload at the current term position. - virtual int32_t getPayloadLength(); +public: + /// Returns next position in the current document. + virtual int32_t nextPosition(); - /// Returns the payload data at the current term position. - virtual ByteArray getPayload(ByteArray data, int32_t offset); + /// Returns the length of the payload at the current term position. + virtual int32_t getPayloadLength(); - /// Checks if a payload can be loaded at this position. - virtual bool isPayloadAvailable(); + /// Returns the payload data at the current term position. + virtual ByteArray getPayload(ByteArray data, int32_t offset); - protected: - virtual TermDocsPtr termDocs(const IndexReaderPtr& reader); - }; + /// Checks if a payload can be loaded at this position. + virtual bool isPayloadAvailable(); - class ReaderCommit : public IndexCommit - { - public: - ReaderCommit(const SegmentInfosPtr& infos, const DirectoryPtr& dir); - virtual ~ReaderCommit(); +protected: + virtual TermDocsPtr termDocs(const IndexReaderPtr& reader); +}; - LUCENE_CLASS(ReaderCommit); +class ReaderCommit : public IndexCommit { +public: + ReaderCommit(const SegmentInfosPtr& infos, const DirectoryPtr& dir); + virtual ~ReaderCommit(); - protected: - String segmentsFileName; - HashSet files; - DirectoryPtr dir; - int64_t generation; - int64_t version; - bool _isOptimized; - MapStringString userData; + LUCENE_CLASS(ReaderCommit); - public: - virtual String toString(); +protected: + String segmentsFileName; + HashSet files; + DirectoryPtr dir; + int64_t generation; + int64_t version; + bool _isOptimized; + MapStringString userData; - /// Returns true if this commit is an optimized index. - virtual bool isOptimized(); +public: + virtual String toString(); - /// Two IndexCommits are equal if both their Directory and versions are equal. - virtual String getSegmentsFileName(); + /// Returns true if this commit is an optimized index. + virtual bool isOptimized(); - /// Returns all index files referenced by this commit point. - virtual HashSet getFileNames(); + /// Two IndexCommits are equal if both their Directory and versions are equal. + virtual String getSegmentsFileName(); - /// Returns the {@link Directory} for the index. - virtual DirectoryPtr getDirectory(); + /// Returns all index files referenced by this commit point. + virtual HashSet getFileNames(); - /// Returns the version for this IndexCommit. - virtual int64_t getVersion(); + /// Returns the {@link Directory} for the index. + virtual DirectoryPtr getDirectory(); - /// Returns the generation (the _N in segments_N) for this IndexCommit. - virtual int64_t getGeneration(); + /// Returns the version for this IndexCommit. + virtual int64_t getVersion(); - virtual bool isDeleted(); + /// Returns the generation (the _N in segments_N) for this IndexCommit. + virtual int64_t getGeneration(); - /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. - virtual MapStringString getUserData(); + virtual bool isDeleted(); + + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. + virtual MapStringString getUserData(); + + virtual void deleteCommit(); +}; - virtual void deleteCommit(); - }; } #endif diff --git a/include/DisjunctionMaxQuery.h b/include/DisjunctionMaxQuery.h index 1b0bc3f4..9ed7791a 100644 --- a/include/DisjunctionMaxQuery.h +++ b/include/DisjunctionMaxQuery.h @@ -9,90 +9,90 @@ #include "Query.h" -namespace Lucene -{ - /// A query that generates the union of documents produced by its subqueries, and that scores each - /// document with the maximum score for that document as produced by any subquery, plus a tie breaking - /// increment for any additional matching subqueries. This is useful when searching for a word in - /// multiple fields with different boost factors (so that the fields cannot be combined equivalently - /// into a single search field). We want the primary score to be the one associated with the highest - /// boost, not the sum of the field scores (as BooleanQuery would give). If the query is "albino - /// elephant" this ensures that "albino" matching one field and "elephant" matching another gets a - /// higher score than "albino" matching both fields. To get this result, use both BooleanQuery and - /// DisjunctionMaxQuery: for each term a DisjunctionMaxQuery searches for it in each field, while the - /// set of these DisjunctionMaxQuery's is combined into a BooleanQuery. The tie breaker capability - /// allows results that include the same term in multiple fields to be judged better than results that - /// include this term in only the best of those multiple fields, without confusing this with the better - /// case of two different terms in the multiple fields. - class LPPAPI DisjunctionMaxQuery : public Query - { - public: - /// Creates a new empty DisjunctionMaxQuery. Use add() to add the subqueries. - /// @param tieBreakerMultiplier the score of each non-maximum disjunct for a document is multiplied - /// by this weight and added into the final score. If non-zero, the value should be small, on the - /// order of 0.1, which says that 10 occurrences of word in a lower-scored field that is also in a - /// higher scored field is just as good as a unique word in the lower scored field (ie., one that is - /// not in any higher scored field. - DisjunctionMaxQuery(double tieBreakerMultiplier = 0.0); - - /// Creates a new DisjunctionMaxQuery - /// @param disjuncts A Collection of all the disjuncts to add - /// @param tieBreakerMultiplier The weight to give to each matching non-maximum disjunct - DisjunctionMaxQuery(Collection disjuncts, double tieBreakerMultiplier); - - virtual ~DisjunctionMaxQuery(); - - LUCENE_CLASS(DisjunctionMaxQuery); - - protected: - /// The subqueries - Collection disjuncts; - - /// Multiple of the non-max disjunct scores added into our final score. Non-zero values support tie-breaking. - double tieBreakerMultiplier; - - public: - using Query::toString; - - /// Add a subquery to this disjunction - /// @param query the disjunct added - void add(const QueryPtr& query); - - /// Add a collection of disjuncts to this disjunction - void add(Collection disjuncts); - - /// An iterator over the disjuncts - Collection::iterator begin(); - Collection::iterator end(); - - /// Create the Weight used to score us - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - /// Optimize our representation and our subqueries representations - /// @param reader the IndexReader we query - /// @return an optimized copy of us (which may not be a copy if there is nothing to optimize) - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - /// Create a shallow copy of us - used in rewriting if necessary - /// @return a copy of us (but reuse, don't copy, our subqueries) - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - /// Adds all terms occurring in this query to the terms set. - virtual void extractTerms(SetTerm terms); - - /// Pretty print us. - /// @param field the field to which we are applied - /// @return a string that shows what we do, of the form "(disjunct1 | disjunct2 | ... | disjunctn)^boost" - virtual String toString(const String& field); - - /// @return true if other is a DisjunctionMaxQuery with the same boost and the same subqueries, in the - /// same order, as us - virtual bool equals(const LuceneObjectPtr& other); - - virtual int32_t hashCode(); - - friend class DisjunctionMaxWeight; - }; +namespace Lucene { + +/// A query that generates the union of documents produced by its subqueries, and that scores each +/// document with the maximum score for that document as produced by any subquery, plus a tie breaking +/// increment for any additional matching subqueries. This is useful when searching for a word in +/// multiple fields with different boost factors (so that the fields cannot be combined equivalently +/// into a single search field). We want the primary score to be the one associated with the highest +/// boost, not the sum of the field scores (as BooleanQuery would give). If the query is "albino +/// elephant" this ensures that "albino" matching one field and "elephant" matching another gets a +/// higher score than "albino" matching both fields. To get this result, use both BooleanQuery and +/// DisjunctionMaxQuery: for each term a DisjunctionMaxQuery searches for it in each field, while the +/// set of these DisjunctionMaxQuery's is combined into a BooleanQuery. The tie breaker capability +/// allows results that include the same term in multiple fields to be judged better than results that +/// include this term in only the best of those multiple fields, without confusing this with the better +/// case of two different terms in the multiple fields. +class LPPAPI DisjunctionMaxQuery : public Query { +public: + /// Creates a new empty DisjunctionMaxQuery. Use add() to add the subqueries. + /// @param tieBreakerMultiplier the score of each non-maximum disjunct for a document is multiplied + /// by this weight and added into the final score. If non-zero, the value should be small, on the + /// order of 0.1, which says that 10 occurrences of word in a lower-scored field that is also in a + /// higher scored field is just as good as a unique word in the lower scored field (ie., one that is + /// not in any higher scored field. + DisjunctionMaxQuery(double tieBreakerMultiplier = 0.0); + + /// Creates a new DisjunctionMaxQuery + /// @param disjuncts A Collection of all the disjuncts to add + /// @param tieBreakerMultiplier The weight to give to each matching non-maximum disjunct + DisjunctionMaxQuery(Collection disjuncts, double tieBreakerMultiplier); + + virtual ~DisjunctionMaxQuery(); + + LUCENE_CLASS(DisjunctionMaxQuery); + +protected: + /// The subqueries + Collection disjuncts; + + /// Multiple of the non-max disjunct scores added into our final score. Non-zero values support tie-breaking. + double tieBreakerMultiplier; + +public: + using Query::toString; + + /// Add a subquery to this disjunction + /// @param query the disjunct added + void add(const QueryPtr& query); + + /// Add a collection of disjuncts to this disjunction + void add(Collection disjuncts); + + /// An iterator over the disjuncts + Collection::iterator begin(); + Collection::iterator end(); + + /// Create the Weight used to score us + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + /// Optimize our representation and our subqueries representations + /// @param reader the IndexReader we query + /// @return an optimized copy of us (which may not be a copy if there is nothing to optimize) + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + /// Create a shallow copy of us - used in rewriting if necessary + /// @return a copy of us (but reuse, don't copy, our subqueries) + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Adds all terms occurring in this query to the terms set. + virtual void extractTerms(SetTerm terms); + + /// Pretty print us. + /// @param field the field to which we are applied + /// @return a string that shows what we do, of the form "(disjunct1 | disjunct2 | ... | disjunctn)^boost" + virtual String toString(const String& field); + + /// @return true if other is a DisjunctionMaxQuery with the same boost and the same subqueries, in the + /// same order, as us + virtual bool equals(const LuceneObjectPtr& other); + + virtual int32_t hashCode(); + + friend class DisjunctionMaxWeight; +}; + } #endif diff --git a/include/DisjunctionMaxScorer.h b/include/DisjunctionMaxScorer.h index ab9aae42..2f32f7f4 100644 --- a/include/DisjunctionMaxScorer.h +++ b/include/DisjunctionMaxScorer.h @@ -9,54 +9,54 @@ #include "Scorer.h" -namespace Lucene -{ - /// The Scorer for DisjunctionMaxQuery. The union of all documents generated by the the subquery scorers - /// is generated in document number order. The score for each document is the maximum of the scores computed - /// by the subquery scorers that generate that document, plus tieBreakerMultiplier times the sum of the scores - /// for the other subqueries that generate the document. - class DisjunctionMaxScorer : public Scorer - { - public: - DisjunctionMaxScorer(double tieBreakerMultiplier, const SimilarityPtr& similarity, Collection subScorers, int32_t numScorers); - virtual ~DisjunctionMaxScorer(); - - LUCENE_CLASS(DisjunctionMaxScorer); - - protected: - /// The scorers for subqueries that have remaining docs, kept as a min heap by number of next doc. - Collection subScorers; - int32_t numScorers; - - /// Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. - double tieBreakerMultiplier; - - int32_t doc; - - public: - virtual int32_t nextDoc(); - virtual int32_t docID(); - - /// Determine the current document score. Initially invalid, until {@link #next()} is called the first time. - /// @return the score of the current generated document - virtual double score(); - - virtual int32_t advance(int32_t target); - - protected: - /// Recursively iterate all subScorers that generated last doc computing sum and max - void scoreAll(int32_t root, int32_t size, int32_t doc, Collection sum, Collection max); - - /// Organize subScorers into a min heap with scorers generating the earliest document on top. - void heapify(); - - /// The subtree of subScorers at root is a min heap except possibly for its root element. Bubble the root - /// down as required to make the subtree a heap. - void heapAdjust(int32_t root); - - /// Remove the root Scorer from subScorers and re-establish it as a heap - void heapRemoveRoot(); - }; +namespace Lucene { + +/// The Scorer for DisjunctionMaxQuery. The union of all documents generated by the the subquery scorers +/// is generated in document number order. The score for each document is the maximum of the scores computed +/// by the subquery scorers that generate that document, plus tieBreakerMultiplier times the sum of the scores +/// for the other subqueries that generate the document. +class DisjunctionMaxScorer : public Scorer { +public: + DisjunctionMaxScorer(double tieBreakerMultiplier, const SimilarityPtr& similarity, Collection subScorers, int32_t numScorers); + virtual ~DisjunctionMaxScorer(); + + LUCENE_CLASS(DisjunctionMaxScorer); + +protected: + /// The scorers for subqueries that have remaining docs, kept as a min heap by number of next doc. + Collection subScorers; + int32_t numScorers; + + /// Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. + double tieBreakerMultiplier; + + int32_t doc; + +public: + virtual int32_t nextDoc(); + virtual int32_t docID(); + + /// Determine the current document score. Initially invalid, until {@link #next()} is called the first time. + /// @return the score of the current generated document + virtual double score(); + + virtual int32_t advance(int32_t target); + +protected: + /// Recursively iterate all subScorers that generated last doc computing sum and max + void scoreAll(int32_t root, int32_t size, int32_t doc, Collection sum, Collection max); + + /// Organize subScorers into a min heap with scorers generating the earliest document on top. + void heapify(); + + /// The subtree of subScorers at root is a min heap except possibly for its root element. Bubble the root + /// down as required to make the subtree a heap. + void heapAdjust(int32_t root); + + /// Remove the root Scorer from subScorers and re-establish it as a heap + void heapRemoveRoot(); +}; + } #endif diff --git a/include/DisjunctionSumScorer.h b/include/DisjunctionSumScorer.h index 5d2fdde5..d481423a 100644 --- a/include/DisjunctionSumScorer.h +++ b/include/DisjunctionSumScorer.h @@ -9,87 +9,87 @@ #include "Scorer.h" -namespace Lucene -{ - /// A Scorer for OR like queries, counterpart of ConjunctionScorer. This Scorer implements {@link - /// Scorer#skipTo(int32_t)} and uses skipTo() on the given Scorers. - class DisjunctionSumScorer : public Scorer - { - public: - DisjunctionSumScorer(Collection subScorers, int32_t minimumNrMatchers = 1); - virtual ~DisjunctionSumScorer(); - - LUCENE_CLASS(DisjunctionSumScorer); - - protected: - /// The number of subscorers. - int32_t nrScorers; - - /// The subscorers. - Collection subScorers; - - /// The minimum number of scorers that should match. - int32_t minimumNrMatchers; - - /// The scorerDocQueue contains all subscorers ordered by their current doc(), with the minimum at - /// the top. The scorerDocQueue is initialized the first time next() or skipTo() is called. An exhausted - /// scorer is immediately removed from the scorerDocQueue. If less than the minimumNrMatchers scorers - /// remain in the scorerDocQueue next() and skipTo() return false. - /// - /// After each to call to next() or skipTo() currentSumScore is the total score of the current matching doc, - /// nrMatchers is the number of matching scorers, and all scorers are after the matching doc, or are exhausted. - ScorerDocQueuePtr scorerDocQueue; - - /// The document number of the current match. - int32_t currentDoc; - - /// The number of subscorers that provide the current match. - int32_t _nrMatchers; - - double currentScore; - - public: - virtual void initialize(); - - virtual void score(const CollectorPtr& collector); - virtual int32_t nextDoc(); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} - /// is called the first time. - virtual double score(); - - virtual int32_t docID(); - - /// Returns the number of subscorers matching the current document. Initially invalid, until {@link #next()} - /// is called the first time. - int32_t nrMatchers(); - - /// Advances to the first match beyond the current whose document number is greater than or equal to a given - /// target. The implementation uses the skipTo() method on the subscorers. - /// - /// @param target The target document number. - /// @return the document whose number is greater than or equal to the given target, or -1 if none exist. - virtual int32_t advance(int32_t target); - - protected: - /// Called the first time next() or skipTo() is called to initialize scorerDocQueue. - void initScorerDocQueue(); - - /// Collects matching documents in a range. Hook for optimization. Note that {@link #next()} must be - /// called once before this method is called for the first time. - /// @param collector The collector to which all matching documents are passed through. - /// @param max Do not score documents past this. - /// @return true if more matching documents may remain. - virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); - - /// Advance all subscorers after the current document determined by the top of the scorerDocQueue. Repeat - /// until at least the minimum number of subscorers match on the same document and all subscorers are after - /// that document or are exhausted. On entry the scorerDocQueue has at least minimumNrMatchers available. - /// At least the scorer with the minimum document number will be advanced. - /// @return true if there is a match. In case there is a match, currentDoc, currentSumScore and nrMatchers - /// describe the match. - bool advanceAfterCurrent(); - }; +namespace Lucene { + +/// A Scorer for OR like queries, counterpart of ConjunctionScorer. This Scorer implements {@link +/// Scorer#skipTo(int32_t)} and uses skipTo() on the given Scorers. +class DisjunctionSumScorer : public Scorer { +public: + DisjunctionSumScorer(Collection subScorers, int32_t minimumNrMatchers = 1); + virtual ~DisjunctionSumScorer(); + + LUCENE_CLASS(DisjunctionSumScorer); + +protected: + /// The number of subscorers. + int32_t nrScorers; + + /// The subscorers. + Collection subScorers; + + /// The minimum number of scorers that should match. + int32_t minimumNrMatchers; + + /// The scorerDocQueue contains all subscorers ordered by their current doc(), with the minimum at + /// the top. The scorerDocQueue is initialized the first time next() or skipTo() is called. An exhausted + /// scorer is immediately removed from the scorerDocQueue. If less than the minimumNrMatchers scorers + /// remain in the scorerDocQueue next() and skipTo() return false. + /// + /// After each to call to next() or skipTo() currentSumScore is the total score of the current matching doc, + /// nrMatchers is the number of matching scorers, and all scorers are after the matching doc, or are exhausted. + ScorerDocQueuePtr scorerDocQueue; + + /// The document number of the current match. + int32_t currentDoc; + + /// The number of subscorers that provide the current match. + int32_t _nrMatchers; + + double currentScore; + +public: + virtual void initialize(); + + virtual void score(const CollectorPtr& collector); + virtual int32_t nextDoc(); + + /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} + /// is called the first time. + virtual double score(); + + virtual int32_t docID(); + + /// Returns the number of subscorers matching the current document. Initially invalid, until {@link #next()} + /// is called the first time. + int32_t nrMatchers(); + + /// Advances to the first match beyond the current whose document number is greater than or equal to a given + /// target. The implementation uses the skipTo() method on the subscorers. + /// + /// @param target The target document number. + /// @return the document whose number is greater than or equal to the given target, or -1 if none exist. + virtual int32_t advance(int32_t target); + +protected: + /// Called the first time next() or skipTo() is called to initialize scorerDocQueue. + void initScorerDocQueue(); + + /// Collects matching documents in a range. Hook for optimization. Note that {@link #next()} must be + /// called once before this method is called for the first time. + /// @param collector The collector to which all matching documents are passed through. + /// @param max Do not score documents past this. + /// @return true if more matching documents may remain. + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); + + /// Advance all subscorers after the current document determined by the top of the scorerDocQueue. Repeat + /// until at least the minimum number of subscorers match on the same document and all subscorers are after + /// that document or are exhausted. On entry the scorerDocQueue has at least minimumNrMatchers available. + /// At least the scorer with the minimum document number will be advanced. + /// @return true if there is a match. In case there is a match, currentDoc, currentSumScore and nrMatchers + /// describe the match. + bool advanceAfterCurrent(); +}; + } #endif diff --git a/include/DocConsumer.h b/include/DocConsumer.h index 66500eb5..5b92f1f9 100644 --- a/include/DocConsumer.h +++ b/include/DocConsumer.h @@ -9,22 +9,22 @@ #include "LuceneObject.h" -namespace Lucene -{ - class DocConsumer : public LuceneObject - { - public: - virtual ~DocConsumer(); - - LUCENE_CLASS(DocConsumer); - - public: - virtual DocConsumerPerThreadPtr addThread(const DocumentsWriterThreadStatePtr& perThread) = 0; - virtual void flush(Collection threads, const SegmentWriteStatePtr& state) = 0; - virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; - virtual void abort() = 0; - virtual bool freeRAM() = 0; - }; +namespace Lucene { + +class DocConsumer : public LuceneObject { +public: + virtual ~DocConsumer(); + + LUCENE_CLASS(DocConsumer); + +public: + virtual DocConsumerPerThreadPtr addThread(const DocumentsWriterThreadStatePtr& perThread) = 0; + virtual void flush(Collection threads, const SegmentWriteStatePtr& state) = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; + virtual void abort() = 0; + virtual bool freeRAM() = 0; +}; + } #endif diff --git a/include/DocConsumerPerThread.h b/include/DocConsumerPerThread.h index aba9275a..15b32659 100644 --- a/include/DocConsumerPerThread.h +++ b/include/DocConsumerPerThread.h @@ -9,23 +9,23 @@ #include "LuceneObject.h" -namespace Lucene -{ - class DocConsumerPerThread : public LuceneObject - { - public: - virtual ~DocConsumerPerThread(); - - LUCENE_CLASS(DocConsumerPerThread); - - public: - /// Process the document. If there is something for this document to be done in docID order, - /// you should encapsulate that as a DocWriter and return it. - /// DocumentsWriter then calls finish() on this object when it's its turn. - virtual DocWriterPtr processDocument() = 0; - - virtual void abort() = 0; - }; +namespace Lucene { + +class DocConsumerPerThread : public LuceneObject { +public: + virtual ~DocConsumerPerThread(); + + LUCENE_CLASS(DocConsumerPerThread); + +public: + /// Process the document. If there is something for this document to be done in docID order, + /// you should encapsulate that as a DocWriter and return it. + /// DocumentsWriter then calls finish() on this object when it's its turn. + virtual DocWriterPtr processDocument() = 0; + + virtual void abort() = 0; +}; + } #endif diff --git a/include/DocFieldConsumer.h b/include/DocFieldConsumer.h index ed402700..d8d2f443 100644 --- a/include/DocFieldConsumer.h +++ b/include/DocFieldConsumer.h @@ -9,37 +9,37 @@ #include "LuceneObject.h" -namespace Lucene -{ - class DocFieldConsumer : public LuceneObject - { - public: - virtual ~DocFieldConsumer(); +namespace Lucene { - LUCENE_CLASS(DocFieldConsumer); +class DocFieldConsumer : public LuceneObject { +public: + virtual ~DocFieldConsumer(); - protected: - FieldInfosPtr fieldInfos; + LUCENE_CLASS(DocFieldConsumer); - public: - /// Called when DocumentsWriter decides to create a new segment - virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; +protected: + FieldInfosPtr fieldInfos; - /// Called when DocumentsWriter decides to close the doc stores - virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; +public: + /// Called when DocumentsWriter decides to create a new segment + virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; - /// Called when an aborting exception is hit - virtual void abort() = 0; + /// Called when DocumentsWriter decides to close the doc stores + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; - /// Add a new thread - virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) = 0; + /// Called when an aborting exception is hit + virtual void abort() = 0; - /// Called when DocumentsWriter is using too much RAM. The consumer should free RAM, if possible, returning - /// true if any RAM was in fact freed. - virtual bool freeRAM() = 0; + /// Add a new thread + virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) = 0; + + /// Called when DocumentsWriter is using too much RAM. The consumer should free RAM, if possible, returning + /// true if any RAM was in fact freed. + virtual bool freeRAM() = 0; + + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); +}; - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); - }; } #endif diff --git a/include/DocFieldConsumerPerField.h b/include/DocFieldConsumerPerField.h index 46d15194..75b5f0ef 100644 --- a/include/DocFieldConsumerPerField.h +++ b/include/DocFieldConsumerPerField.h @@ -9,21 +9,21 @@ #include "LuceneObject.h" -namespace Lucene -{ - class DocFieldConsumerPerField : public LuceneObject - { - public: - virtual ~DocFieldConsumerPerField(); +namespace Lucene { - LUCENE_CLASS(DocFieldConsumerPerField); +class DocFieldConsumerPerField : public LuceneObject { +public: + virtual ~DocFieldConsumerPerField(); - public: - /// Processes all occurrences of a single field - virtual void processFields(Collection fields, int32_t count) = 0; + LUCENE_CLASS(DocFieldConsumerPerField); + +public: + /// Processes all occurrences of a single field + virtual void processFields(Collection fields, int32_t count) = 0; + + virtual void abort() = 0; +}; - virtual void abort() = 0; - }; } #endif diff --git a/include/DocFieldConsumerPerThread.h b/include/DocFieldConsumerPerThread.h index 9014ebc6..9c88e7ce 100644 --- a/include/DocFieldConsumerPerThread.h +++ b/include/DocFieldConsumerPerThread.h @@ -9,21 +9,21 @@ #include "LuceneObject.h" -namespace Lucene -{ - class DocFieldConsumerPerThread : public LuceneObject - { - public: - virtual ~DocFieldConsumerPerThread(); - - LUCENE_CLASS(DocFieldConsumerPerThread); - - public: - virtual void startDocument() = 0; - virtual DocWriterPtr finishDocument() = 0; - virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi) = 0; - virtual void abort() = 0; - }; +namespace Lucene { + +class DocFieldConsumerPerThread : public LuceneObject { +public: + virtual ~DocFieldConsumerPerThread(); + + LUCENE_CLASS(DocFieldConsumerPerThread); + +public: + virtual void startDocument() = 0; + virtual DocWriterPtr finishDocument() = 0; + virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi) = 0; + virtual void abort() = 0; +}; + } #endif diff --git a/include/DocFieldConsumers.h b/include/DocFieldConsumers.h index 46bfb424..35c4a813 100644 --- a/include/DocFieldConsumers.h +++ b/include/DocFieldConsumers.h @@ -10,64 +10,63 @@ #include "DocFieldConsumer.h" #include "DocumentsWriter.h" -namespace Lucene -{ - /// This is just a "splitter" class: it lets you wrap two DocFieldConsumer instances as a single consumer. - class DocFieldConsumers : public DocFieldConsumer - { - public: - DocFieldConsumers(const DocFieldConsumerPtr& one, const DocFieldConsumerPtr& two); - virtual ~DocFieldConsumers(); +namespace Lucene { - LUCENE_CLASS(DocFieldConsumers); +/// This is just a "splitter" class: it lets you wrap two DocFieldConsumer instances as a single consumer. +class DocFieldConsumers : public DocFieldConsumer { +public: + DocFieldConsumers(const DocFieldConsumerPtr& one, const DocFieldConsumerPtr& two); + virtual ~DocFieldConsumers(); - public: - DocFieldConsumerPtr one; - DocFieldConsumerPtr two; + LUCENE_CLASS(DocFieldConsumers); - Collection docFreeList; - int32_t freeCount; - int32_t allocCount; +public: + DocFieldConsumerPtr one; + DocFieldConsumerPtr two; - public: - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); + Collection docFreeList; + int32_t freeCount; + int32_t allocCount; - /// Called when DocumentsWriter decides to create a new segment - virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); +public: + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); - /// Called when DocumentsWriter decides to close the doc stores - virtual void closeDocStore(const SegmentWriteStatePtr& state); + /// Called when DocumentsWriter decides to create a new segment + virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); - /// Called when DocumentsWriter is using too much RAM. - virtual bool freeRAM(); + /// Called when DocumentsWriter decides to close the doc stores + virtual void closeDocStore(const SegmentWriteStatePtr& state); - /// Add a new thread - virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread); + /// Called when DocumentsWriter is using too much RAM. + virtual bool freeRAM(); - DocFieldConsumersPerDocPtr getPerDoc(); - void freePerDoc(const DocFieldConsumersPerDocPtr& perDoc); - }; + /// Add a new thread + virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread); - class DocFieldConsumersPerDoc : public DocWriter - { - public: - DocFieldConsumersPerDoc(const DocFieldConsumersPtr& fieldConsumers); - virtual ~DocFieldConsumersPerDoc(); + DocFieldConsumersPerDocPtr getPerDoc(); + void freePerDoc(const DocFieldConsumersPerDocPtr& perDoc); +}; - LUCENE_CLASS(DocFieldConsumersPerDoc); +class DocFieldConsumersPerDoc : public DocWriter { +public: + DocFieldConsumersPerDoc(const DocFieldConsumersPtr& fieldConsumers); + virtual ~DocFieldConsumersPerDoc(); - protected: - DocFieldConsumersWeakPtr _fieldConsumers; + LUCENE_CLASS(DocFieldConsumersPerDoc); - public: - DocWriterPtr one; - DocWriterPtr two; +protected: + DocFieldConsumersWeakPtr _fieldConsumers; + +public: + DocWriterPtr one; + DocWriterPtr two; + +public: + virtual int64_t sizeInBytes(); + virtual void finish(); + virtual void abort(); +}; - public: - virtual int64_t sizeInBytes(); - virtual void finish(); - virtual void abort(); - }; } #endif diff --git a/include/DocFieldConsumersPerField.h b/include/DocFieldConsumersPerField.h index cbfd73d8..ee301b64 100644 --- a/include/DocFieldConsumersPerField.h +++ b/include/DocFieldConsumersPerField.h @@ -9,27 +9,27 @@ #include "DocFieldConsumerPerField.h" -namespace Lucene -{ - class DocFieldConsumersPerField : public DocFieldConsumerPerField - { - public: - DocFieldConsumersPerField(const DocFieldConsumersPerThreadPtr& perThread, const DocFieldConsumerPerFieldPtr& one, const DocFieldConsumerPerFieldPtr& two); - virtual ~DocFieldConsumersPerField(); - - LUCENE_CLASS(DocFieldConsumersPerField); - - public: - DocFieldConsumerPerFieldPtr one; - DocFieldConsumerPerFieldPtr two; - DocFieldConsumersPerThreadWeakPtr _perThread; - - public: - /// Processes all occurrences of a single field - virtual void processFields(Collection fields, int32_t count); - - virtual void abort(); - }; +namespace Lucene { + +class DocFieldConsumersPerField : public DocFieldConsumerPerField { +public: + DocFieldConsumersPerField(const DocFieldConsumersPerThreadPtr& perThread, const DocFieldConsumerPerFieldPtr& one, const DocFieldConsumerPerFieldPtr& two); + virtual ~DocFieldConsumersPerField(); + + LUCENE_CLASS(DocFieldConsumersPerField); + +public: + DocFieldConsumerPerFieldPtr one; + DocFieldConsumerPerFieldPtr two; + DocFieldConsumersPerThreadWeakPtr _perThread; + +public: + /// Processes all occurrences of a single field + virtual void processFields(Collection fields, int32_t count); + + virtual void abort(); +}; + } #endif diff --git a/include/DocFieldConsumersPerThread.h b/include/DocFieldConsumersPerThread.h index 11820e9a..e46dc341 100644 --- a/include/DocFieldConsumersPerThread.h +++ b/include/DocFieldConsumersPerThread.h @@ -9,29 +9,29 @@ #include "DocFieldConsumerPerThread.h" -namespace Lucene -{ - class DocFieldConsumersPerThread : public DocFieldConsumerPerThread - { - public: - DocFieldConsumersPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocFieldConsumersPtr& parent, - const DocFieldConsumerPerThreadPtr& one, const DocFieldConsumerPerThreadPtr& two); - virtual ~DocFieldConsumersPerThread(); - - LUCENE_CLASS(DocFieldConsumersPerThread); - - public: - DocFieldConsumerPerThreadPtr one; - DocFieldConsumerPerThreadPtr two; - DocFieldConsumersWeakPtr _parent; - DocStatePtr docState; - - public: - virtual void startDocument(); - virtual void abort(); - virtual DocWriterPtr finishDocument(); - virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi); - }; +namespace Lucene { + +class DocFieldConsumersPerThread : public DocFieldConsumerPerThread { +public: + DocFieldConsumersPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocFieldConsumersPtr& parent, + const DocFieldConsumerPerThreadPtr& one, const DocFieldConsumerPerThreadPtr& two); + virtual ~DocFieldConsumersPerThread(); + + LUCENE_CLASS(DocFieldConsumersPerThread); + +public: + DocFieldConsumerPerThreadPtr one; + DocFieldConsumerPerThreadPtr two; + DocFieldConsumersWeakPtr _parent; + DocStatePtr docState; + +public: + virtual void startDocument(); + virtual void abort(); + virtual DocWriterPtr finishDocument(); + virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi); +}; + } #endif diff --git a/include/DocFieldProcessor.h b/include/DocFieldProcessor.h index e6c8d8db..3cada74b 100644 --- a/include/DocFieldProcessor.h +++ b/include/DocFieldProcessor.h @@ -9,32 +9,32 @@ #include "DocConsumer.h" -namespace Lucene -{ - /// This is a DocConsumer that gathers all fields under the same name, and calls per-field consumers to process - /// field by field. This class doesn't doesn't do any "real" work of its own: it just forwards the fields to a - /// DocFieldConsumer. - class DocFieldProcessor : public DocConsumer - { - public: - DocFieldProcessor(const DocumentsWriterPtr& docWriter, const DocFieldConsumerPtr& consumer); - virtual ~DocFieldProcessor(); - - LUCENE_CLASS(DocFieldProcessor); - - public: - DocumentsWriterWeakPtr _docWriter; - FieldInfosPtr fieldInfos; - DocFieldConsumerPtr consumer; - StoredFieldsWriterPtr fieldsWriter; - - public: - virtual void closeDocStore(const SegmentWriteStatePtr& state); - virtual void flush(Collection threads, const SegmentWriteStatePtr& state); - virtual void abort(); - virtual bool freeRAM(); - virtual DocConsumerPerThreadPtr addThread(const DocumentsWriterThreadStatePtr& perThread); - }; +namespace Lucene { + +/// This is a DocConsumer that gathers all fields under the same name, and calls per-field consumers to process +/// field by field. This class doesn't doesn't do any "real" work of its own: it just forwards the fields to a +/// DocFieldConsumer. +class DocFieldProcessor : public DocConsumer { +public: + DocFieldProcessor(const DocumentsWriterPtr& docWriter, const DocFieldConsumerPtr& consumer); + virtual ~DocFieldProcessor(); + + LUCENE_CLASS(DocFieldProcessor); + +public: + DocumentsWriterWeakPtr _docWriter; + FieldInfosPtr fieldInfos; + DocFieldConsumerPtr consumer; + StoredFieldsWriterPtr fieldsWriter; + +public: + virtual void closeDocStore(const SegmentWriteStatePtr& state); + virtual void flush(Collection threads, const SegmentWriteStatePtr& state); + virtual void abort(); + virtual bool freeRAM(); + virtual DocConsumerPerThreadPtr addThread(const DocumentsWriterThreadStatePtr& perThread); +}; + } #endif diff --git a/include/DocFieldProcessorPerField.h b/include/DocFieldProcessorPerField.h index 8274d5f3..963c8c5c 100644 --- a/include/DocFieldProcessorPerField.h +++ b/include/DocFieldProcessorPerField.h @@ -9,30 +9,30 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Holds all per thread, per field state. - class DocFieldProcessorPerField : public LuceneObject - { - public: - DocFieldProcessorPerField(const DocFieldProcessorPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); - virtual ~DocFieldProcessorPerField(); - - LUCENE_CLASS(DocFieldProcessorPerField); - - public: - DocFieldConsumerPerFieldPtr consumer; - FieldInfoPtr fieldInfo; - - DocFieldProcessorPerFieldPtr next; - int32_t lastGen; - - int32_t fieldCount; - Collection fields; - - public: - virtual void abort(); - }; +namespace Lucene { + +/// Holds all per thread, per field state. +class DocFieldProcessorPerField : public LuceneObject { +public: + DocFieldProcessorPerField(const DocFieldProcessorPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); + virtual ~DocFieldProcessorPerField(); + + LUCENE_CLASS(DocFieldProcessorPerField); + +public: + DocFieldConsumerPerFieldPtr consumer; + FieldInfoPtr fieldInfo; + + DocFieldProcessorPerFieldPtr next; + int32_t lastGen; + + int32_t fieldCount; + Collection fields; + +public: + virtual void abort(); +}; + } #endif diff --git a/include/DocFieldProcessorPerThread.h b/include/DocFieldProcessorPerThread.h index f581614a..ccfb7a89 100644 --- a/include/DocFieldProcessorPerThread.h +++ b/include/DocFieldProcessorPerThread.h @@ -10,77 +10,76 @@ #include "DocConsumerPerThread.h" #include "DocumentsWriter.h" -namespace Lucene -{ - /// Gathers all Fieldables for a document under the same name, updates FieldInfos, and calls per-field - /// consumers to process field by field. - /// - /// Currently, only a single thread visits the fields, sequentially, for processing. - class DocFieldProcessorPerThread : public DocConsumerPerThread - { - public: - DocFieldProcessorPerThread(const DocumentsWriterThreadStatePtr& threadState, const DocFieldProcessorPtr& docFieldProcessor); - virtual ~DocFieldProcessorPerThread(); - - LUCENE_CLASS(DocFieldProcessorPerThread); - - public: - double docBoost; - int32_t fieldGen; - DocFieldProcessorWeakPtr _docFieldProcessor; - FieldInfosPtr fieldInfos; - DocFieldConsumerPerThreadPtr consumer; - Collection _fields; // Holds all fields seen in current doc - int32_t fieldCount; - - Collection fieldHash; // Hash table for all fields ever seen - int32_t hashMask; - int32_t totalFieldCount; - - StoredFieldsWriterPerThreadPtr fieldsWriter; - DocStatePtr docState; - - Collection docFreeList; - int32_t freeCount; - int32_t allocCount; - - public: - virtual void initialize(); - virtual void abort(); - Collection fields(); - - // If there are fields we've seen but did not see again in the last run, then free them up. - void trimFields(const SegmentWriteStatePtr& state); - - virtual DocWriterPtr processDocument(); - - DocFieldProcessorPerThreadPerDocPtr getPerDoc(); - void freePerDoc(const DocFieldProcessorPerThreadPerDocPtr& perDoc); - - protected: - void rehash(); - }; - - class DocFieldProcessorPerThreadPerDoc : public DocWriter - { - public: - DocFieldProcessorPerThreadPerDoc(const DocFieldProcessorPerThreadPtr& docProcessor); - virtual ~DocFieldProcessorPerThreadPerDoc(); - - LUCENE_CLASS(DocFieldProcessorPerThreadPerDoc); - - public: - DocWriterPtr one; - DocWriterPtr two; - - protected: - DocFieldProcessorPerThreadWeakPtr _docProcessor; - - public: - virtual int64_t sizeInBytes(); - virtual void finish(); - virtual void abort(); - }; +namespace Lucene { + +/// Gathers all Fieldables for a document under the same name, updates FieldInfos, and calls per-field +/// consumers to process field by field. +/// +/// Currently, only a single thread visits the fields, sequentially, for processing. +class DocFieldProcessorPerThread : public DocConsumerPerThread { +public: + DocFieldProcessorPerThread(const DocumentsWriterThreadStatePtr& threadState, const DocFieldProcessorPtr& docFieldProcessor); + virtual ~DocFieldProcessorPerThread(); + + LUCENE_CLASS(DocFieldProcessorPerThread); + +public: + double docBoost; + int32_t fieldGen; + DocFieldProcessorWeakPtr _docFieldProcessor; + FieldInfosPtr fieldInfos; + DocFieldConsumerPerThreadPtr consumer; + Collection _fields; // Holds all fields seen in current doc + int32_t fieldCount; + + Collection fieldHash; // Hash table for all fields ever seen + int32_t hashMask; + int32_t totalFieldCount; + + StoredFieldsWriterPerThreadPtr fieldsWriter; + DocStatePtr docState; + + Collection docFreeList; + int32_t freeCount; + int32_t allocCount; + +public: + virtual void initialize(); + virtual void abort(); + Collection fields(); + + // If there are fields we've seen but did not see again in the last run, then free them up. + void trimFields(const SegmentWriteStatePtr& state); + + virtual DocWriterPtr processDocument(); + + DocFieldProcessorPerThreadPerDocPtr getPerDoc(); + void freePerDoc(const DocFieldProcessorPerThreadPerDocPtr& perDoc); + +protected: + void rehash(); +}; + +class DocFieldProcessorPerThreadPerDoc : public DocWriter { +public: + DocFieldProcessorPerThreadPerDoc(const DocFieldProcessorPerThreadPtr& docProcessor); + virtual ~DocFieldProcessorPerThreadPerDoc(); + + LUCENE_CLASS(DocFieldProcessorPerThreadPerDoc); + +public: + DocWriterPtr one; + DocWriterPtr two; + +protected: + DocFieldProcessorPerThreadWeakPtr _docProcessor; + +public: + virtual int64_t sizeInBytes(); + virtual void finish(); + virtual void abort(); +}; + } #endif diff --git a/include/DocIdBitSet.h b/include/DocIdBitSet.h index 30b83224..5262de10 100644 --- a/include/DocIdBitSet.h +++ b/include/DocIdBitSet.h @@ -9,35 +9,35 @@ #include "DocIdSet.h" -namespace Lucene -{ - /// Simple DocIdSet and DocIdSetIterator backed by a BitSet - class LPPAPI DocIdBitSet : public DocIdSet - { - public: - DocIdBitSet(); - DocIdBitSet(const BitSetPtr& bitSet); +namespace Lucene { - virtual ~DocIdBitSet(); +/// Simple DocIdSet and DocIdSetIterator backed by a BitSet +class LPPAPI DocIdBitSet : public DocIdSet { +public: + DocIdBitSet(); + DocIdBitSet(const BitSetPtr& bitSet); - LUCENE_CLASS(DocIdBitSet); + virtual ~DocIdBitSet(); - protected: - BitSetPtr bitSet; + LUCENE_CLASS(DocIdBitSet); - public: - virtual DocIdSetIteratorPtr iterator(); +protected: + BitSetPtr bitSet; - /// This DocIdSet implementation is cacheable. - virtual bool isCacheable(); +public: + virtual DocIdSetIteratorPtr iterator(); - /// Returns the underlying BitSet. - BitSetPtr getBitSet(); + /// This DocIdSet implementation is cacheable. + virtual bool isCacheable(); + + /// Returns the underlying BitSet. + BitSetPtr getBitSet(); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; } #endif diff --git a/include/DocIdSet.h b/include/DocIdSet.h index f4fe9e64..470f9c61 100644 --- a/include/DocIdSet.h +++ b/include/DocIdSet.h @@ -9,30 +9,30 @@ #include "DocIdSetIterator.h" -namespace Lucene -{ - /// A DocIdSet contains a set of doc ids. Implementing classes must only implement {@link #iterator} to - /// provide access to the set. - class LPPAPI DocIdSet : public LuceneObject - { - public: - virtual ~DocIdSet(); - LUCENE_CLASS(DocIdSet); - - public: - /// Provides a {@link DocIdSetIterator} to access the set. This implementation can return null or - /// {@link #EmptyDocIdSet}.iterator() if there are no docs that match. - virtual DocIdSetIteratorPtr iterator() = 0; - - /// This method is a hint for {@link CachingWrapperFilter}, if this DocIdSet should be cached without - /// copying it into a BitSet. The default is to return false. If you have an own DocIdSet implementation - /// that does its iteration very effective and fast without doing disk I/O, override this method and - /// return true. - virtual bool isCacheable(); - - /// An empty {@code DocIdSet} instance for easy use, eg. in Filters that hit no documents. - static DocIdSetPtr EMPTY_DOCIDSET(); - }; +namespace Lucene { + +/// A DocIdSet contains a set of doc ids. Implementing classes must only implement {@link #iterator} to +/// provide access to the set. +class LPPAPI DocIdSet : public LuceneObject { +public: + virtual ~DocIdSet(); + LUCENE_CLASS(DocIdSet); + +public: + /// Provides a {@link DocIdSetIterator} to access the set. This implementation can return null or + /// {@link #EmptyDocIdSet}.iterator() if there are no docs that match. + virtual DocIdSetIteratorPtr iterator() = 0; + + /// This method is a hint for {@link CachingWrapperFilter}, if this DocIdSet should be cached without + /// copying it into a BitSet. The default is to return false. If you have an own DocIdSet implementation + /// that does its iteration very effective and fast without doing disk I/O, override this method and + /// return true. + virtual bool isCacheable(); + + /// An empty {@code DocIdSet} instance for easy use, eg. in Filters that hit no documents. + static DocIdSetPtr EMPTY_DOCIDSET(); +}; + } #endif diff --git a/include/DocIdSetIterator.h b/include/DocIdSetIterator.h index 4835aafa..9db8e706 100644 --- a/include/DocIdSetIterator.h +++ b/include/DocIdSetIterator.h @@ -9,67 +9,67 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This abstract class defines methods to iterate over a set of non-decreasing doc ids. Note that this class - /// assumes it iterates on doc Ids, and therefore {@link #NO_MORE_DOCS} is set to {@value #NO_MORE_DOCS} in order to - /// be used as a sentinel object. Implementations of this class are expected to consider INT_MAX as an invalid value. - class LPPAPI DocIdSetIterator : public LuceneObject - { - public: - virtual ~DocIdSetIterator(); +namespace Lucene { - LUCENE_CLASS(DocIdSetIterator); +/// This abstract class defines methods to iterate over a set of non-decreasing doc ids. Note that this class +/// assumes it iterates on doc Ids, and therefore {@link #NO_MORE_DOCS} is set to {@value #NO_MORE_DOCS} in order to +/// be used as a sentinel object. Implementations of this class are expected to consider INT_MAX as an invalid value. +class LPPAPI DocIdSetIterator : public LuceneObject { +public: + virtual ~DocIdSetIterator(); - public: - /// When returned by {@link #nextDoc()}, {@link #advance(int)} and {@link #docID()} it means there are no more - /// docs in the iterator. - static const int32_t NO_MORE_DOCS; + LUCENE_CLASS(DocIdSetIterator); - public: - /// Returns the following: - ///
        - ///
      • -1 or {@link #NO_MORE_DOCS} if {@link #nextDoc()} or {@link #advance(int)} were not called yet. - ///
      • {@link #NO_MORE_DOCS} if the iterator has exhausted. - ///
      • Otherwise it should return the doc ID it is currently on. - ///
      - virtual int32_t docID() = 0; +public: + /// When returned by {@link #nextDoc()}, {@link #advance(int)} and {@link #docID()} it means there are no more + /// docs in the iterator. + static const int32_t NO_MORE_DOCS; - /// Advances to the next document in the set and returns the doc it is currently on, or {@link #NO_MORE_DOCS} - /// if there are no more docs in the set. - /// - /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted - /// behaviour. - virtual int32_t nextDoc() = 0; +public: + /// Returns the following: + ///
        + ///
      • -1 or {@link #NO_MORE_DOCS} if {@link #nextDoc()} or {@link #advance(int)} were not called yet. + ///
      • {@link #NO_MORE_DOCS} if the iterator has exhausted. + ///
      • Otherwise it should return the doc ID it is currently on. + ///
      + virtual int32_t docID() = 0; + + /// Advances to the next document in the set and returns the doc it is currently on, or {@link #NO_MORE_DOCS} + /// if there are no more docs in the set. + /// + /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted + /// behaviour. + virtual int32_t nextDoc() = 0; + + /// Advances to the first beyond the current whose document number is greater than or equal to target. Returns + /// the current document number or {@link #NO_MORE_DOCS} if there are no more docs in the set. + /// + /// Behaves as if written: + /// + ///
      +    /// int32_t advance(int32_t target)
      +    /// {
      +    ///     int32_t doc;
      +    ///     while ((doc = nextDoc()) < target)
      +    ///     { }
      +    ///     return doc;
      +    /// }
      +    /// 
      + /// + /// Some implementations are considerably more efficient than that. + /// + /// NOTE: certain implementations may return a different value (each time) if called several times in a row + /// with the same target. + /// + /// NOTE: this method may be called with {@value #NO_MORE_DOCS} for efficiency by some Scorers. If your + /// implementation cannot efficiently determine that it should exhaust, it is recommended that you check for + /// that value in each call to this method. + /// + /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted + /// behaviour. + virtual int32_t advance(int32_t target) = 0; +}; - /// Advances to the first beyond the current whose document number is greater than or equal to target. Returns - /// the current document number or {@link #NO_MORE_DOCS} if there are no more docs in the set. - /// - /// Behaves as if written: - /// - ///
      -        /// int32_t advance(int32_t target)
      -        /// {
      -        ///     int32_t doc;
      -        ///     while ((doc = nextDoc()) < target)
      -        ///     { }
      -        ///     return doc;
      -        /// }
      -        /// 
      - /// - /// Some implementations are considerably more efficient than that. - /// - /// NOTE: certain implementations may return a different value (each time) if called several times in a row - /// with the same target. - /// - /// NOTE: this method may be called with {@value #NO_MORE_DOCS} for efficiency by some Scorers. If your - /// implementation cannot efficiently determine that it should exhaust, it is recommended that you check for - /// that value in each call to this method. - /// - /// NOTE: after the iterator has exhausted you should not call this method, as it may result in unpredicted - /// behaviour. - virtual int32_t advance(int32_t target) = 0; - }; } #endif diff --git a/include/DocInverter.h b/include/DocInverter.h index b5e217df..a0e30ed5 100644 --- a/include/DocInverter.h +++ b/include/DocInverter.h @@ -9,40 +9,40 @@ #include "DocFieldConsumer.h" -namespace Lucene -{ - /// This is a DocFieldConsumer that inverts each field, separately, from a Document, and accepts a - /// InvertedTermsConsumer to process those terms. - class DocInverter : public DocFieldConsumer - { - public: - DocInverter(const InvertedDocConsumerPtr& consumer, const InvertedDocEndConsumerPtr& endConsumer); - virtual ~DocInverter(); +namespace Lucene { - LUCENE_CLASS(DocInverter); +/// This is a DocFieldConsumer that inverts each field, separately, from a Document, and accepts a +/// InvertedTermsConsumer to process those terms. +class DocInverter : public DocFieldConsumer { +public: + DocInverter(const InvertedDocConsumerPtr& consumer, const InvertedDocEndConsumerPtr& endConsumer); + virtual ~DocInverter(); - public: - InvertedDocConsumerPtr consumer; - InvertedDocEndConsumerPtr endConsumer; + LUCENE_CLASS(DocInverter); - public: - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); +public: + InvertedDocConsumerPtr consumer; + InvertedDocEndConsumerPtr endConsumer; - /// Called when DocumentsWriter decides to create a new segment - virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); +public: + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); - /// Called when DocumentsWriter decides to close the doc stores - virtual void closeDocStore(const SegmentWriteStatePtr& state); + /// Called when DocumentsWriter decides to create a new segment + virtual void flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); - /// Called when an aborting exception is hit - virtual void abort(); + /// Called when DocumentsWriter decides to close the doc stores + virtual void closeDocStore(const SegmentWriteStatePtr& state); - /// Called when DocumentsWriter is using too much RAM. - virtual bool freeRAM(); + /// Called when an aborting exception is hit + virtual void abort(); + + /// Called when DocumentsWriter is using too much RAM. + virtual bool freeRAM(); + + /// Add a new thread + virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread); +}; - /// Add a new thread - virtual DocFieldConsumerPerThreadPtr addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread); - }; } #endif diff --git a/include/DocInverterPerField.h b/include/DocInverterPerField.h index 7c9d9c29..183f3f3f 100644 --- a/include/DocInverterPerField.h +++ b/include/DocInverterPerField.h @@ -9,36 +9,36 @@ #include "DocFieldConsumerPerField.h" -namespace Lucene -{ - /// Holds state for inverting all occurrences of a single field in the document. This class doesn't do - /// anything itself; instead, it forwards the tokens produced by analysis to its own consumer - /// (InvertedDocConsumerPerField). It also interacts with an endConsumer (InvertedDocEndConsumerPerField). - class DocInverterPerField : public DocFieldConsumerPerField - { - public: - DocInverterPerField(const DocInverterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); - virtual ~DocInverterPerField(); - - LUCENE_CLASS(DocInverterPerField); - - protected: - DocInverterPerThreadWeakPtr _perThread; - FieldInfoPtr fieldInfo; - - public: - InvertedDocConsumerPerFieldPtr consumer; - InvertedDocEndConsumerPerFieldPtr endConsumer; - DocStatePtr docState; - FieldInvertStatePtr fieldState; - - public: - virtual void initialize(); - virtual void abort(); - - /// Processes all occurrences of a single field - virtual void processFields(Collection fields, int32_t count); - }; +namespace Lucene { + +/// Holds state for inverting all occurrences of a single field in the document. This class doesn't do +/// anything itself; instead, it forwards the tokens produced by analysis to its own consumer +/// (InvertedDocConsumerPerField). It also interacts with an endConsumer (InvertedDocEndConsumerPerField). +class DocInverterPerField : public DocFieldConsumerPerField { +public: + DocInverterPerField(const DocInverterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); + virtual ~DocInverterPerField(); + + LUCENE_CLASS(DocInverterPerField); + +protected: + DocInverterPerThreadWeakPtr _perThread; + FieldInfoPtr fieldInfo; + +public: + InvertedDocConsumerPerFieldPtr consumer; + InvertedDocEndConsumerPerFieldPtr endConsumer; + DocStatePtr docState; + FieldInvertStatePtr fieldState; + +public: + virtual void initialize(); + virtual void abort(); + + /// Processes all occurrences of a single field + virtual void processFields(Collection fields, int32_t count); +}; + } #endif diff --git a/include/DocInverterPerThread.h b/include/DocInverterPerThread.h index c818c1c1..8343dc1b 100644 --- a/include/DocInverterPerThread.h +++ b/include/DocInverterPerThread.h @@ -10,53 +10,52 @@ #include "DocFieldConsumerPerThread.h" #include "AttributeSource.h" -namespace Lucene -{ - /// This is a DocFieldConsumer that inverts each field, separately, from a Document, and accepts a - /// InvertedTermsConsumer to process those terms. - class DocInverterPerThread : public DocFieldConsumerPerThread - { - public: - DocInverterPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocInverterPtr& docInverter); - virtual ~DocInverterPerThread(); - - LUCENE_CLASS(DocInverterPerThread); - - public: - DocInverterWeakPtr _docInverter; - InvertedDocConsumerPerThreadPtr consumer; - InvertedDocEndConsumerPerThreadPtr endConsumer; - SingleTokenAttributeSourcePtr singleToken; - - DocStatePtr docState; - FieldInvertStatePtr fieldState; - - /// Used to read a string value for a field - ReusableStringReaderPtr stringReader; - - public: - virtual void initialize(); - virtual void startDocument(); - virtual DocWriterPtr finishDocument(); - virtual void abort(); - virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi); - }; - - class SingleTokenAttributeSource : public AttributeSource - { - public: - SingleTokenAttributeSource(); - virtual ~SingleTokenAttributeSource(); - - LUCENE_CLASS(SingleTokenAttributeSource); - - public: - TermAttributePtr termAttribute; - OffsetAttributePtr offsetAttribute; - - public: - void reinit(const String& stringValue, int32_t startOffset, int32_t endOffset); - }; +namespace Lucene { + +/// This is a DocFieldConsumer that inverts each field, separately, from a Document, and accepts a +/// InvertedTermsConsumer to process those terms. +class DocInverterPerThread : public DocFieldConsumerPerThread { +public: + DocInverterPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocInverterPtr& docInverter); + virtual ~DocInverterPerThread(); + + LUCENE_CLASS(DocInverterPerThread); + +public: + DocInverterWeakPtr _docInverter; + InvertedDocConsumerPerThreadPtr consumer; + InvertedDocEndConsumerPerThreadPtr endConsumer; + SingleTokenAttributeSourcePtr singleToken; + + DocStatePtr docState; + FieldInvertStatePtr fieldState; + + /// Used to read a string value for a field + ReusableStringReaderPtr stringReader; + +public: + virtual void initialize(); + virtual void startDocument(); + virtual DocWriterPtr finishDocument(); + virtual void abort(); + virtual DocFieldConsumerPerFieldPtr addField(const FieldInfoPtr& fi); +}; + +class SingleTokenAttributeSource : public AttributeSource { +public: + SingleTokenAttributeSource(); + virtual ~SingleTokenAttributeSource(); + + LUCENE_CLASS(SingleTokenAttributeSource); + +public: + TermAttributePtr termAttribute; + OffsetAttributePtr offsetAttribute; + +public: + void reinit(const String& stringValue, int32_t startOffset, int32_t endOffset); +}; + } #endif diff --git a/include/DocValues.h b/include/DocValues.h index 5f5d87a6..3b1037e8 100644 --- a/include/DocValues.h +++ b/include/DocValues.h @@ -9,90 +9,90 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Represents field values as different types. Normally created via a {@link ValueSuorce} for a - /// particular field and reader. +namespace Lucene { + +/// Represents field values as different types. Normally created via a {@link ValueSuorce} for a +/// particular field and reader. +/// +/// DocValues is distinct from ValueSource because there needs to be an object created at query +/// evaluation time that is not referenced by the query itself because: +/// - Query objects should be MT safe +/// - For caching, Query objects are often used as keys... you don't want the Query carrying around +/// big objects +class LPPAPI DocValues : public LuceneObject { +public: + DocValues(); + virtual ~DocValues(); + + LUCENE_CLASS(DocValues); + +protected: + double minVal; + double maxVal; + double avgVal; + bool computed; + +public: + using LuceneObject::toString; + + /// Return doc value as a double. + /// Mandatory: every DocValues implementation must implement at least this method. + /// @param doc document whose double value is requested. + virtual double doubleVal(int32_t doc) = 0; + + /// Return doc value as an int. + /// Optional: DocValues implementation can (but don't have to) override this method. + /// @param doc document whose int value is requested. + virtual int32_t intVal(int32_t doc); + + /// Return doc value as a long. + /// Optional: DocValues implementation can (but don't have to) override this method. + /// @param doc document whose long value is requested. + virtual int64_t longVal(int32_t doc); + + /// Return doc value as a string. + /// Optional: DocValues implementation can (but don't have to) override this method. + /// @param doc document whose string value is requested. + virtual String strVal(int32_t doc); + + /// Return a string representation of a doc value, as required for Explanations. + virtual String toString(int32_t doc) = 0; + + /// Explain the scoring value for the input doc. + virtual ExplanationPtr explain(int32_t doc); + + /// For test purposes only, return the inner array of values, or null if not applicable. /// - /// DocValues is distinct from ValueSource because there needs to be an object created at query - /// evaluation time that is not referenced by the query itself because: - /// - Query objects should be MT safe - /// - For caching, Query objects are often used as keys... you don't want the Query carrying around - /// big objects - class LPPAPI DocValues : public LuceneObject - { - public: - DocValues(); - virtual ~DocValues(); - - LUCENE_CLASS(DocValues); - - protected: - double minVal; - double maxVal; - double avgVal; - bool computed; - - public: - using LuceneObject::toString; - - /// Return doc value as a double. - /// Mandatory: every DocValues implementation must implement at least this method. - /// @param doc document whose double value is requested. - virtual double doubleVal(int32_t doc) = 0; - - /// Return doc value as an int. - /// Optional: DocValues implementation can (but don't have to) override this method. - /// @param doc document whose int value is requested. - virtual int32_t intVal(int32_t doc); - - /// Return doc value as a long. - /// Optional: DocValues implementation can (but don't have to) override this method. - /// @param doc document whose long value is requested. - virtual int64_t longVal(int32_t doc); - - /// Return doc value as a string. - /// Optional: DocValues implementation can (but don't have to) override this method. - /// @param doc document whose string value is requested. - virtual String strVal(int32_t doc); - - /// Return a string representation of a doc value, as required for Explanations. - virtual String toString(int32_t doc) = 0; - - /// Explain the scoring value for the input doc. - virtual ExplanationPtr explain(int32_t doc); - - /// For test purposes only, return the inner array of values, or null if not applicable. - /// - /// Allows tests to verify that loaded values are: - ///
        - ///
      1. indeed cached/reused. - ///
      2. stored in the expected size/type (byte/short/int/float). - ///
      - /// - /// Note: implementations of DocValues must override this method for these test elements to be tested, - /// Otherwise the test would not fail, just print a warning. - virtual CollectionValue getInnerArray(); - - /// Returns the minimum of all values or NaN if this DocValues instance does not contain any value. - /// This operation is optional - /// @return the minimum of all values or NaN if this DocValues instance does not contain any value. - virtual double getMinValue(); - - /// Returns the maximum of all values or NaN if this DocValues instance does not contain any value. - /// This operation is optional - /// @return the maximum of all values or NaN if this DocValues instance does not contain any value. - virtual double getMaxValue(); - - /// Returns the average of all values or NaN if this DocValues instance does not contain any value. - /// This operation is optional - /// @return the average of all values or NaN if this DocValues instance does not contain any value. - virtual double getAverageValue(); - - protected: - /// Compute optional values - void compute(); - }; + /// Allows tests to verify that loaded values are: + ///
        + ///
      1. indeed cached/reused. + ///
      2. stored in the expected size/type (byte/short/int/float). + ///
      + /// + /// Note: implementations of DocValues must override this method for these test elements to be tested, + /// Otherwise the test would not fail, just print a warning. + virtual CollectionValue getInnerArray(); + + /// Returns the minimum of all values or NaN if this DocValues instance does not contain any value. + /// This operation is optional + /// @return the minimum of all values or NaN if this DocValues instance does not contain any value. + virtual double getMinValue(); + + /// Returns the maximum of all values or NaN if this DocValues instance does not contain any value. + /// This operation is optional + /// @return the maximum of all values or NaN if this DocValues instance does not contain any value. + virtual double getMaxValue(); + + /// Returns the average of all values or NaN if this DocValues instance does not contain any value. + /// This operation is optional + /// @return the average of all values or NaN if this DocValues instance does not contain any value. + virtual double getAverageValue(); + +protected: + /// Compute optional values + void compute(); +}; + } #endif diff --git a/include/Document.h b/include/Document.h index ecb118f0..5e0422f1 100644 --- a/include/Document.h +++ b/include/Document.h @@ -9,134 +9,134 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Documents are the unit of indexing and search. +namespace Lucene { + +/// Documents are the unit of indexing and search. +/// +/// A Document is a set of fields. Each field has a name and a textual value. A field may be {@link +/// Fieldable#isStored() stored} with the document, in which case it is returned with search hits on the +/// document. Thus each document should typically contain one or more stored fields which uniquely +/// identify it. +/// +/// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents +/// retrieved from the index, eg. with {@link ScoreDoc#doc}, {@link Searcher#doc(int)} or {@link +/// IndexReader#document(int)}. +class LPPAPI Document : public LuceneObject { +public: + /// Constructs a new document with no fields. + Document(); + + virtual ~Document(); + + LUCENE_CLASS(Document); + +protected: + Collection fields; + double boost; + +public: + /// Sets a boost factor for hits on any field of this document. This value will be multiplied into the + /// score of all hits on this document. /// - /// A Document is a set of fields. Each field has a name and a textual value. A field may be {@link - /// Fieldable#isStored() stored} with the document, in which case it is returned with search hits on the - /// document. Thus each document should typically contain one or more stored fields which uniquely - /// identify it. + /// The default value is 1.0. /// - /// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents - /// retrieved from the index, eg. with {@link ScoreDoc#doc}, {@link Searcher#doc(int)} or {@link - /// IndexReader#document(int)}. - class LPPAPI Document : public LuceneObject - { - public: - /// Constructs a new document with no fields. - Document(); - - virtual ~Document(); - - LUCENE_CLASS(Document); - - protected: - Collection fields; - double boost; - - public: - /// Sets a boost factor for hits on any field of this document. This value will be multiplied into the - /// score of all hits on this document. - /// - /// The default value is 1.0. - /// - /// Values are multiplied into the value of {@link Fieldable#getBoost()} of each field in this document. - /// Thus, this method in effect sets a default boost for the fields of this document. - /// - /// @see Fieldable#setBoost(double) - void setBoost(double boost); - - /// Returns, at indexing time, the boost factor as set by {@link #setBoost(double)}. - /// - /// Note that once a document is indexed this value is no longer available from the index. At search time, - /// for retrieved documents, this method always returns 1. This however does not mean that the boost value - /// set at indexing time was ignored - it was just combined with other indexing time factors and stored - /// elsewhere, for better indexing and search performance. (For more information see the "norm(t,d)" part - /// of the scoring formula in {@link Similarity}.) - /// - /// @see #setBoost(double) - double getBoost(); - - /// Adds a field to a document. Several fields may be added with the same name. In this case, if the fields - /// are indexed, their text is treated as though appended for the purposes of search. - /// - /// Note that add like the removeField(s) methods only makes sense prior to adding a document to an index. - /// These methods cannot be used to change the content of an existing index! In order to achieve this, a - /// document has to be deleted from an index and a new changed version of that document has to be added. - void add(const FieldablePtr& field); - - /// Removes field with the specified name from the document. If multiple fields exist with this name, this - /// method removes the first field that has been added. If there is no field with the specified name, the - /// document remains unchanged. - /// - /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to - /// an index. These methods cannot be used to change the content of an existing index! In order to achieve - /// this, a document has to be deleted from an index and a new changed version of that document has to be added. - void removeField(const String& name); - - /// Removes all fields with the given name from the document. If there is no field with the specified name, - /// the document remains unchanged. - /// - /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to an - /// index. These methods cannot be used to change the content of an existing index! In order to achieve this, - /// a document has to be deleted from an index and a new changed version of that document has to be added. - void removeFields(const String& name); - - /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with - /// this name, this method returns the first value added. - /// Do not use this method with lazy loaded fields. - FieldPtr getField(const String& name); - - /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with - /// this name, this method returns the first value added. - FieldablePtr getFieldable(const String& name); - - /// Returns the string value of the field with the given name if any exist in this document, or null. If multiple - /// fields exist with this name, this method returns the first value added. If only binary fields with this name - /// exist, returns null. - String get(const String& name); - - /// Returns a List of all the fields in a document. - /// - /// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents - /// retrieved from the index, eg. {@link Searcher#doc(int)} or {@link IndexReader#document(int)}. - Collection getFields(); - - /// Returns an array of {@link Field}s with the given name. Do not use with lazy loaded fields. This method - /// returns an empty array when there are no matching fields. It never returns null. - /// @param name the name of the field - /// @return a Field[] array - Collection getFields(const String& name); - - /// Returns an array of {@link Fieldable}s with the given name. - /// This method returns an empty array when there are no matching fields. It never returns null. - /// @param name the name of the field - /// @return a Fieldable[] array - Collection getFieldables(const String& name); - - /// Returns an array of values of the field specified as the method parameter. - /// This method returns an empty array when there are no matching fields. It never returns null. - /// @param name the name of the field - /// @return a String[] of field values - Collection getValues(const String& name); - - /// Returns an array of byte arrays for of the fields that have the name specified as the method parameter. - /// This method returns an empty array when there are no matching fields. It never returns null. - /// @param name the name of the field - /// @return a byte[][] of binary field values - Collection getBinaryValues(const String& name); - - /// Returns an array of bytes for the first (or only) field that has the name specified as the method parameter. - /// This method will return null if no binary fields with the specified name are available. There may be - /// non-binary fields with the same name. - /// @param name the name of the field. - /// @return a byte[] containing the binary field value or null - ByteArray getBinaryValue(const String& name); - - /// Returns a string representation of the object - virtual String toString(); - }; + /// Values are multiplied into the value of {@link Fieldable#getBoost()} of each field in this document. + /// Thus, this method in effect sets a default boost for the fields of this document. + /// + /// @see Fieldable#setBoost(double) + void setBoost(double boost); + + /// Returns, at indexing time, the boost factor as set by {@link #setBoost(double)}. + /// + /// Note that once a document is indexed this value is no longer available from the index. At search time, + /// for retrieved documents, this method always returns 1. This however does not mean that the boost value + /// set at indexing time was ignored - it was just combined with other indexing time factors and stored + /// elsewhere, for better indexing and search performance. (For more information see the "norm(t,d)" part + /// of the scoring formula in {@link Similarity}.) + /// + /// @see #setBoost(double) + double getBoost(); + + /// Adds a field to a document. Several fields may be added with the same name. In this case, if the fields + /// are indexed, their text is treated as though appended for the purposes of search. + /// + /// Note that add like the removeField(s) methods only makes sense prior to adding a document to an index. + /// These methods cannot be used to change the content of an existing index! In order to achieve this, a + /// document has to be deleted from an index and a new changed version of that document has to be added. + void add(const FieldablePtr& field); + + /// Removes field with the specified name from the document. If multiple fields exist with this name, this + /// method removes the first field that has been added. If there is no field with the specified name, the + /// document remains unchanged. + /// + /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to + /// an index. These methods cannot be used to change the content of an existing index! In order to achieve + /// this, a document has to be deleted from an index and a new changed version of that document has to be added. + void removeField(const String& name); + + /// Removes all fields with the given name from the document. If there is no field with the specified name, + /// the document remains unchanged. + /// + /// Note that the removeField(s) methods like the add method only make sense prior to adding a document to an + /// index. These methods cannot be used to change the content of an existing index! In order to achieve this, + /// a document has to be deleted from an index and a new changed version of that document has to be added. + void removeFields(const String& name); + + /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with + /// this name, this method returns the first value added. + /// Do not use this method with lazy loaded fields. + FieldPtr getField(const String& name); + + /// Returns a field with the given name if any exist in this document, or null. If multiple fields exists with + /// this name, this method returns the first value added. + FieldablePtr getFieldable(const String& name); + + /// Returns the string value of the field with the given name if any exist in this document, or null. If multiple + /// fields exist with this name, this method returns the first value added. If only binary fields with this name + /// exist, returns null. + String get(const String& name); + + /// Returns a List of all the fields in a document. + /// + /// Note that fields which are not {@link Fieldable#isStored() stored} are not available in documents + /// retrieved from the index, eg. {@link Searcher#doc(int)} or {@link IndexReader#document(int)}. + Collection getFields(); + + /// Returns an array of {@link Field}s with the given name. Do not use with lazy loaded fields. This method + /// returns an empty array when there are no matching fields. It never returns null. + /// @param name the name of the field + /// @return a Field[] array + Collection getFields(const String& name); + + /// Returns an array of {@link Fieldable}s with the given name. + /// This method returns an empty array when there are no matching fields. It never returns null. + /// @param name the name of the field + /// @return a Fieldable[] array + Collection getFieldables(const String& name); + + /// Returns an array of values of the field specified as the method parameter. + /// This method returns an empty array when there are no matching fields. It never returns null. + /// @param name the name of the field + /// @return a String[] of field values + Collection getValues(const String& name); + + /// Returns an array of byte arrays for of the fields that have the name specified as the method parameter. + /// This method returns an empty array when there are no matching fields. It never returns null. + /// @param name the name of the field + /// @return a byte[][] of binary field values + Collection getBinaryValues(const String& name); + + /// Returns an array of bytes for the first (or only) field that has the name specified as the method parameter. + /// This method will return null if no binary fields with the specified name are available. There may be + /// non-binary fields with the same name. + /// @param name the name of the field. + /// @return a byte[] containing the binary field value or null + ByteArray getBinaryValue(const String& name); + + /// Returns a string representation of the object + virtual String toString(); +}; + } #endif diff --git a/include/DocumentsWriter.h b/include/DocumentsWriter.h index b54ed36e..a3d8905f 100644 --- a/include/DocumentsWriter.h +++ b/include/DocumentsWriter.h @@ -10,521 +10,513 @@ #include "ByteBlockPool.h" #include "RAMFile.h" -namespace Lucene -{ - /// This class accepts multiple added documents and directly writes a single segment file. It does this more - /// efficiently than creating a single segment per document (with DocumentWriter) and doing standard merges on - /// those segments. - /// - /// Each added document is passed to the {@link DocConsumer}, which in turn processes the document and interacts - /// with other consumers in the indexing chain. Certain consumers, like {@link StoredFieldsWriter} and {@link - /// TermVectorsTermsWriter}, digest a document and immediately write bytes to the "doc store" files (ie, - /// they do not consume RAM per document, except while they are processing the document). - /// - /// Other consumers, eg {@link FreqProxTermsWriter} and {@link NormsWriter}, buffer bytes in RAM and flush only - /// when a new segment is produced. - /// - /// Once we have used our allowed RAM buffer, or the number of added docs is large enough (in the case we are - /// flushing by doc count instead of RAM usage), we create a real segment and flush it to the Directory. - /// - /// Threads: - /// Multiple threads are allowed into addDocument at once. There is an initial synchronized call to - /// getThreadState which allocates a ThreadState for this thread. The same thread will get the same ThreadState - /// over time (thread affinity) so that if there are consistent patterns (for example each thread is indexing a - /// different content source) then we make better use of RAM. Then processDocument is called on that ThreadState - /// without synchronization (most of the "heavy lifting" is in this call). Finally the synchronized - /// "finishDocument" is called to flush changes to the directory. - /// - /// When flush is called by IndexWriter we forcefully idle all threads and flush only once they are all idle. - /// This means you can call flush with a given thread even while other threads are actively adding/deleting - /// documents. - /// - /// Exceptions: - /// Because this class directly updates in-memory posting lists, and flushes stored fields and term vectors - /// directly to files in the directory, there are certain limited times when an exception can corrupt this state. - /// For example, a disk full while flushing stored fields leaves this file in a corrupt state. Or, an - /// std::bad_alloc exception while appending to the in-memory posting lists can corrupt that posting list. - /// We call such exceptions "aborting exceptions". In these cases we must call abort() to discard all docs added - /// since the last flush. - /// - /// All other exceptions ("non-aborting exceptions") can still partially update the index structures. These - /// updates are consistent, but, they represent only a part of the document seen up until the exception was hit. - /// When this happens, we immediately mark the document as deleted so that the document is always atomically - /// ("all or none") added to the index. - class DocumentsWriter : public LuceneObject - { - public: - DocumentsWriter(const DirectoryPtr& directory, const IndexWriterPtr& writer, const IndexingChainPtr& indexingChain); - virtual ~DocumentsWriter(); - - LUCENE_CLASS(DocumentsWriter); - - protected: - String docStoreSegment; // Current doc-store segment we are writing - int32_t docStoreOffset; // Current starting doc-store offset of current segment - - int32_t nextDocID; // Next docID to be added - int32_t numDocsInRAM; // # docs buffered in RAM - - /// Max # ThreadState instances; if there are more threads than this they share ThreadStates - static const int32_t MAX_THREAD_STATE; - Collection threadStates; - MapThreadDocumentsWriterThreadState threadBindings; - - int32_t pauseThreads; // Non-zero when we need all threads to pause (eg to flush) - bool aborting; // True if an abort is pending - - DocFieldProcessorPtr docFieldProcessor; - - /// Deletes done after the last flush; these are discarded on abort - BufferedDeletesPtr deletesInRAM; - - /// Deletes done before the last flush; these are still kept on abort - BufferedDeletesPtr deletesFlushed; - - /// The max number of delete terms that can be buffered before they must be flushed to disk. - int32_t maxBufferedDeleteTerms; - - /// How much RAM we can use before flushing. This is 0 if we are flushing by doc count instead. - int64_t ramBufferSize; - int64_t waitQueuePauseBytes; - int64_t waitQueueResumeBytes; - - /// If we've allocated 5% over our RAM budget, we then free down to 95% - int64_t freeTrigger; - int64_t freeLevel; +namespace Lucene { + +/// This class accepts multiple added documents and directly writes a single segment file. It does this more +/// efficiently than creating a single segment per document (with DocumentWriter) and doing standard merges on +/// those segments. +/// +/// Each added document is passed to the {@link DocConsumer}, which in turn processes the document and interacts +/// with other consumers in the indexing chain. Certain consumers, like {@link StoredFieldsWriter} and {@link +/// TermVectorsTermsWriter}, digest a document and immediately write bytes to the "doc store" files (ie, +/// they do not consume RAM per document, except while they are processing the document). +/// +/// Other consumers, eg {@link FreqProxTermsWriter} and {@link NormsWriter}, buffer bytes in RAM and flush only +/// when a new segment is produced. +/// +/// Once we have used our allowed RAM buffer, or the number of added docs is large enough (in the case we are +/// flushing by doc count instead of RAM usage), we create a real segment and flush it to the Directory. +/// +/// Threads: +/// Multiple threads are allowed into addDocument at once. There is an initial synchronized call to +/// getThreadState which allocates a ThreadState for this thread. The same thread will get the same ThreadState +/// over time (thread affinity) so that if there are consistent patterns (for example each thread is indexing a +/// different content source) then we make better use of RAM. Then processDocument is called on that ThreadState +/// without synchronization (most of the "heavy lifting" is in this call). Finally the synchronized +/// "finishDocument" is called to flush changes to the directory. +/// +/// When flush is called by IndexWriter we forcefully idle all threads and flush only once they are all idle. +/// This means you can call flush with a given thread even while other threads are actively adding/deleting +/// documents. +/// +/// Exceptions: +/// Because this class directly updates in-memory posting lists, and flushes stored fields and term vectors +/// directly to files in the directory, there are certain limited times when an exception can corrupt this state. +/// For example, a disk full while flushing stored fields leaves this file in a corrupt state. Or, an +/// std::bad_alloc exception while appending to the in-memory posting lists can corrupt that posting list. +/// We call such exceptions "aborting exceptions". In these cases we must call abort() to discard all docs added +/// since the last flush. +/// +/// All other exceptions ("non-aborting exceptions") can still partially update the index structures. These +/// updates are consistent, but, they represent only a part of the document seen up until the exception was hit. +/// When this happens, we immediately mark the document as deleted so that the document is always atomically +/// ("all or none") added to the index. +class DocumentsWriter : public LuceneObject { +public: + DocumentsWriter(const DirectoryPtr& directory, const IndexWriterPtr& writer, const IndexingChainPtr& indexingChain); + virtual ~DocumentsWriter(); + + LUCENE_CLASS(DocumentsWriter); + +protected: + String docStoreSegment; // Current doc-store segment we are writing + int32_t docStoreOffset; // Current starting doc-store offset of current segment + + int32_t nextDocID; // Next docID to be added + int32_t numDocsInRAM; // # docs buffered in RAM + + /// Max # ThreadState instances; if there are more threads than this they share ThreadStates + static const int32_t MAX_THREAD_STATE; + Collection threadStates; + MapThreadDocumentsWriterThreadState threadBindings; + + int32_t pauseThreads; // Non-zero when we need all threads to pause (eg to flush) + bool aborting; // True if an abort is pending + + DocFieldProcessorPtr docFieldProcessor; + + /// Deletes done after the last flush; these are discarded on abort + BufferedDeletesPtr deletesInRAM; + + /// Deletes done before the last flush; these are still kept on abort + BufferedDeletesPtr deletesFlushed; + + /// The max number of delete terms that can be buffered before they must be flushed to disk. + int32_t maxBufferedDeleteTerms; + + /// How much RAM we can use before flushing. This is 0 if we are flushing by doc count instead. + int64_t ramBufferSize; + int64_t waitQueuePauseBytes; + int64_t waitQueueResumeBytes; + + /// If we've allocated 5% over our RAM budget, we then free down to 95% + int64_t freeTrigger; + int64_t freeLevel; + + /// Flush @ this number of docs. If ramBufferSize is non-zero we will flush by RAM usage instead. + int32_t maxBufferedDocs; + + /// How many docs already flushed to index + int32_t flushedDocCount; + + bool closed; + + /// List of files that were written before last abort() + HashSet _abortedFiles; + SegmentWriteStatePtr flushState; + + Collection freeIntBlocks; + Collection freeCharBlocks; + +public: + /// Coarse estimates used to measure RAM usage of buffered deletes + static const int32_t OBJECT_HEADER_BYTES; + static const int32_t POINTER_NUM_BYTE; + static const int32_t INT_NUM_BYTE; + static const int32_t CHAR_NUM_BYTE; + + /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object + /// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is + /// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since + /// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). + /// BufferedDeletes.num is OBJ_HEADER + INT. + static const int32_t BYTES_PER_DEL_TERM; + + /// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is + /// OBJ_HEADER + int + static const int32_t BYTES_PER_DEL_DOCID; + + /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object + /// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount + /// (say 24 bytes). Integer is OBJ_HEADER + INT. + static const int32_t BYTES_PER_DEL_QUERY; - /// Flush @ this number of docs. If ramBufferSize is non-zero we will flush by RAM usage instead. - int32_t maxBufferedDocs; + /// Initial chunks size of the shared byte[] blocks used to store postings data + static const int32_t BYTE_BLOCK_SHIFT; + static const int32_t BYTE_BLOCK_SIZE; + static const int32_t BYTE_BLOCK_MASK; + static const int32_t BYTE_BLOCK_NOT_MASK; - /// How many docs already flushed to index - int32_t flushedDocCount; + /// Initial chunk size of the shared char[] blocks used to store term text + static const int32_t CHAR_BLOCK_SHIFT; + static const int32_t CHAR_BLOCK_SIZE; + static const int32_t CHAR_BLOCK_MASK; - bool closed; + static const int32_t MAX_TERM_LENGTH; - /// List of files that were written before last abort() - HashSet _abortedFiles; - SegmentWriteStatePtr flushState; + /// Initial chunks size of the shared int[] blocks used to store postings data + static const int32_t INT_BLOCK_SHIFT; + static const int32_t INT_BLOCK_SIZE; + static const int32_t INT_BLOCK_MASK; - Collection freeIntBlocks; - Collection freeCharBlocks; + static const int32_t PER_DOC_BLOCK_SIZE; - public: - /// Coarse estimates used to measure RAM usage of buffered deletes - static const int32_t OBJECT_HEADER_BYTES; - static const int32_t POINTER_NUM_BYTE; - static const int32_t INT_NUM_BYTE; - static const int32_t CHAR_NUM_BYTE; +INTERNAL: + IndexWriterWeakPtr _writer; + DirectoryPtr directory; + IndexingChainPtr indexingChain; + String segment; // Current segment we are working on - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is - /// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since - /// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). - /// BufferedDeletes.num is OBJ_HEADER + INT. - static const int32_t BYTES_PER_DEL_TERM; + int32_t numDocsInStore; // # docs written to doc stores - /// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is - /// OBJ_HEADER + int - static const int32_t BYTES_PER_DEL_DOCID; + bool flushPending; // True when a thread has decided to flush + bool bufferIsFull; // True when it's time to write segment - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount - /// (say 24 bytes). Integer is OBJ_HEADER + INT. - static const int32_t BYTES_PER_DEL_QUERY; + InfoStreamPtr infoStream; + int32_t maxFieldLength; + SimilarityPtr similarity; - /// Initial chunks size of the shared byte[] blocks used to store postings data - static const int32_t BYTE_BLOCK_SHIFT; - static const int32_t BYTE_BLOCK_SIZE; - static const int32_t BYTE_BLOCK_MASK; - static const int32_t BYTE_BLOCK_NOT_MASK; + DocConsumerPtr consumer; - /// Initial chunk size of the shared char[] blocks used to store term text - static const int32_t CHAR_BLOCK_SHIFT; - static const int32_t CHAR_BLOCK_SIZE; - static const int32_t CHAR_BLOCK_MASK; + HashSet _openFiles; + HashSet _closedFiles; - static const int32_t MAX_TERM_LENGTH; + WaitQueuePtr waitQueue; + SkipDocWriterPtr skipDocWriter; - /// Initial chunks size of the shared int[] blocks used to store postings data - static const int32_t INT_BLOCK_SHIFT; - static const int32_t INT_BLOCK_SIZE; - static const int32_t INT_BLOCK_MASK; + ByteBlockAllocatorPtr byteBlockAllocator; + ByteBlockAllocatorPtr perDocAllocator; - static const int32_t PER_DOC_BLOCK_SIZE; + int64_t numBytesAlloc; + int64_t numBytesUsed; - INTERNAL: - IndexWriterWeakPtr _writer; - DirectoryPtr directory; - IndexingChainPtr indexingChain; - String segment; // Current segment we are working on + // used only by assert + TermPtr lastDeleteTerm; - int32_t numDocsInStore; // # docs written to doc stores +public: + virtual void initialize(); - bool flushPending; // True when a thread has decided to flush - bool bufferIsFull; // True when it's time to write segment + /// Create and return a new DocWriterBuffer. + PerDocBufferPtr newPerDocBuffer(); - InfoStreamPtr infoStream; - int32_t maxFieldLength; - SimilarityPtr similarity; + static IndexingChainPtr getDefaultIndexingChain(); - DocConsumerPtr consumer; + void updateFlushedDocCount(int32_t n); + int32_t getFlushedDocCount(); + void setFlushedDocCount(int32_t n); - HashSet _openFiles; - HashSet _closedFiles; + /// Returns true if any of the fields in the current buffered docs have omitTermFreqAndPositions==false + bool hasProx(); - WaitQueuePtr waitQueue; - SkipDocWriterPtr skipDocWriter; + /// If non-null, various details of indexing are printed here. + void setInfoStream(const InfoStreamPtr& infoStream); - ByteBlockAllocatorPtr byteBlockAllocator; - ByteBlockAllocatorPtr perDocAllocator; + void setMaxFieldLength(int32_t maxFieldLength); + void setSimilarity(const SimilarityPtr& similarity); - int64_t numBytesAlloc; - int64_t numBytesUsed; + /// Set how much RAM we can use before flushing. + void setRAMBufferSizeMB(double mb); + double getRAMBufferSizeMB(); - // used only by assert - TermPtr lastDeleteTerm; + /// Set max buffered docs, which means we will flush by doc count instead of by RAM usage. + void setMaxBufferedDocs(int32_t count); + int32_t getMaxBufferedDocs(); - public: - virtual void initialize(); + /// Get current segment name we are writing. + String getSegment(); - /// Create and return a new DocWriterBuffer. - PerDocBufferPtr newPerDocBuffer(); + /// Returns how many docs are currently buffered in RAM. + int32_t getNumDocsInRAM(); - static IndexingChainPtr getDefaultIndexingChain(); + /// Returns the current doc store segment we are writing to. + String getDocStoreSegment(); - void updateFlushedDocCount(int32_t n); - int32_t getFlushedDocCount(); - void setFlushedDocCount(int32_t n); + /// Returns the doc offset into the shared doc store for the current buffered docs. + int32_t getDocStoreOffset(); - /// Returns true if any of the fields in the current buffered docs have omitTermFreqAndPositions==false - bool hasProx(); + /// Closes the current open doc stores an returns the doc store segment name. This returns null if there + /// are no buffered documents. + String closeDocStore(); - /// If non-null, various details of indexing are printed here. - void setInfoStream(const InfoStreamPtr& infoStream); + HashSet abortedFiles(); - void setMaxFieldLength(int32_t maxFieldLength); - void setSimilarity(const SimilarityPtr& similarity); + void message(const String& message); - /// Set how much RAM we can use before flushing. - void setRAMBufferSizeMB(double mb); - double getRAMBufferSizeMB(); + /// Returns Collection of files in use by this instance, including any flushed segments. + HashSet openFiles(); + HashSet closedFiles(); - /// Set max buffered docs, which means we will flush by doc count instead of by RAM usage. - void setMaxBufferedDocs(int32_t count); - int32_t getMaxBufferedDocs(); + void addOpenFile(const String& name); + void removeOpenFile(const String& name); - /// Get current segment name we are writing. - String getSegment(); + void setAborting(); - /// Returns how many docs are currently buffered in RAM. - int32_t getNumDocsInRAM(); + /// Called if we hit an exception at a bad time (when updating the index files) and must discard all + /// currently buffered docs. This resets our state, discarding any docs added since last flush. + void abort(); - /// Returns the current doc store segment we are writing to. - String getDocStoreSegment(); + /// Returns true if an abort is in progress + bool pauseAllThreads(); + void resumeAllThreads(); - /// Returns the doc offset into the shared doc store for the current buffered docs. - int32_t getDocStoreOffset(); + bool anyChanges(); - /// Closes the current open doc stores an returns the doc store segment name. This returns null if there - /// are no buffered documents. - String closeDocStore(); + void initFlushState(bool onlyDocStore); - HashSet abortedFiles(); + /// Flush all pending docs to a new segment + int32_t flush(bool _closeDocStore); - void message(const String& message); + HashSet getFlushedFiles(); - /// Returns Collection of files in use by this instance, including any flushed segments. - HashSet openFiles(); - HashSet closedFiles(); + /// Build compound file for the segment we just flushed + void createCompoundFile(const String& segment); - void addOpenFile(const String& name); - void removeOpenFile(const String& name); + /// Set flushPending if it is not already set and returns whether it was set. This is used by IndexWriter + /// to trigger a single flush even when multiple threads are trying to do so. + bool setFlushPending(); + void clearFlushPending(); - void setAborting(); + void pushDeletes(); - /// Called if we hit an exception at a bad time (when updating the index files) and must discard all - /// currently buffered docs. This resets our state, discarding any docs added since last flush. - void abort(); + void close(); - /// Returns true if an abort is in progress - bool pauseAllThreads(); - void resumeAllThreads(); + void initSegmentName(bool onlyDocStore); - bool anyChanges(); + /// Returns a free (idle) ThreadState that may be used for indexing this one document. This call also + /// pauses if a flush is pending. If delTerm is non-null then we buffer this deleted term after the + /// thread state has been acquired. + DocumentsWriterThreadStatePtr getThreadState(const DocumentPtr& doc, const TermPtr& delTerm); - void initFlushState(bool onlyDocStore); + /// Returns true if the caller (IndexWriter) should now flush. + bool addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer); - /// Flush all pending docs to a new segment - int32_t flush(bool _closeDocStore); + bool updateDocument(const TermPtr& t, const DocumentPtr& doc, const AnalyzerPtr& analyzer); + bool updateDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer, const TermPtr& delTerm); - HashSet getFlushedFiles(); + int32_t getNumBufferedDeleteTerms(); // for testing + MapTermNum getBufferedDeleteTerms(); // for testing - /// Build compound file for the segment we just flushed - void createCompoundFile(const String& segment); + /// Called whenever a merge has completed and the merged segments had deletions + void remapDeletes(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergeDocCount); - /// Set flushPending if it is not already set and returns whether it was set. This is used by IndexWriter - /// to trigger a single flush even when multiple threads are trying to do so. - bool setFlushPending(); - void clearFlushPending(); + bool bufferDeleteTerms(Collection terms); + bool bufferDeleteTerm(const TermPtr& term); + bool bufferDeleteQueries(Collection queries); + bool bufferDeleteQuery(const QueryPtr& query); + bool deletesFull(); + bool doApplyDeletes(); - void pushDeletes(); + void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); + int32_t getMaxBufferedDeleteTerms(); - void close(); + bool hasDeletes(); + bool applyDeletes(const SegmentInfosPtr& infos); + bool doBalanceRAM(); - void initSegmentName(bool onlyDocStore); + void waitForWaitQueue(); - /// Returns a free (idle) ThreadState that may be used for indexing this one document. This call also - /// pauses if a flush is pending. If delTerm is non-null then we buffer this deleted term after the - /// thread state has been acquired. - DocumentsWriterThreadStatePtr getThreadState(const DocumentPtr& doc, const TermPtr& delTerm); + int64_t getRAMUsed(); - /// Returns true if the caller (IndexWriter) should now flush. - bool addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer); + IntArray getIntBlock(bool trackAllocations); + void bytesAllocated(int64_t numBytes); + void bytesUsed(int64_t numBytes); + void recycleIntBlocks(Collection blocks, int32_t start, int32_t end); - bool updateDocument(const TermPtr& t, const DocumentPtr& doc, const AnalyzerPtr& analyzer); - bool updateDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer, const TermPtr& delTerm); + CharArray getCharBlock(); + void recycleCharBlocks(Collection blocks, int32_t numBlocks); - int32_t getNumBufferedDeleteTerms(); // for testing - MapTermNum getBufferedDeleteTerms(); // for testing + String toMB(int64_t v); - /// Called whenever a merge has completed and the merged segments had deletions - void remapDeletes(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergeDocCount); - - bool bufferDeleteTerms(Collection terms); - bool bufferDeleteTerm(const TermPtr& term); - bool bufferDeleteQueries(Collection queries); - bool bufferDeleteQuery(const QueryPtr& query); - bool deletesFull(); - bool doApplyDeletes(); - - void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); - int32_t getMaxBufferedDeleteTerms(); - - bool hasDeletes(); - bool applyDeletes(const SegmentInfosPtr& infos); - bool doBalanceRAM(); - - void waitForWaitQueue(); - - int64_t getRAMUsed(); - - IntArray getIntBlock(bool trackAllocations); - void bytesAllocated(int64_t numBytes); - void bytesUsed(int64_t numBytes); - void recycleIntBlocks(Collection blocks, int32_t start, int32_t end); - - CharArray getCharBlock(); - void recycleCharBlocks(Collection blocks, int32_t numBlocks); - - String toMB(int64_t v); - - /// We have four pools of RAM: Postings, byte blocks (holds freq/prox posting data), char blocks (holds - /// characters in the term) and per-doc buffers (stored fields/term vectors). Different docs require - /// varying amount of storage from these four classes. - /// - /// For example, docs with many unique single-occurrence short terms will use up the Postings - /// RAM and hardly any of the other two. Whereas docs with very large terms will use alot of char blocks - /// RAM and relatively less of the other two. This method just frees allocations from the pools once we - /// are over-budget, which balances the pools to match the current docs. - void balanceRAM(); - - protected: - /// Reset after a flush - void doAfterFlush(); - - bool allThreadsIdle(); - - void waitReady(const DocumentsWriterThreadStatePtr& state); - - bool timeToFlushDeletes(); - - // used only by assert - bool checkDeleteTerm(const TermPtr& term); + /// We have four pools of RAM: Postings, byte blocks (holds freq/prox posting data), char blocks (holds + /// characters in the term) and per-doc buffers (stored fields/term vectors). Different docs require + /// varying amount of storage from these four classes. + /// + /// For example, docs with many unique single-occurrence short terms will use up the Postings + /// RAM and hardly any of the other two. Whereas docs with very large terms will use alot of char blocks + /// RAM and relatively less of the other two. This method just frees allocations from the pools once we + /// are over-budget, which balances the pools to match the current docs. + void balanceRAM(); - bool applyDeletes(const IndexReaderPtr& reader, int32_t docIDStart); - void addDeleteTerm(const TermPtr& term, int32_t docCount); +protected: + /// Reset after a flush + void doAfterFlush(); - /// Buffer a specific docID for deletion. Currently only used when we hit a exception when adding a document - void addDeleteDocID(int32_t docID); - void addDeleteQuery(const QueryPtr& query, int32_t docID); + bool allThreadsIdle(); - /// Does the synchronized work to finish/flush the inverted document. - void finishDocument(const DocumentsWriterThreadStatePtr& perThread, const DocWriterPtr& docWriter); + void waitReady(const DocumentsWriterThreadStatePtr& state); - friend class WaitQueue; - }; + bool timeToFlushDeletes(); + + // used only by assert + bool checkDeleteTerm(const TermPtr& term); + + bool applyDeletes(const IndexReaderPtr& reader, int32_t docIDStart); + void addDeleteTerm(const TermPtr& term, int32_t docCount); + + /// Buffer a specific docID for deletion. Currently only used when we hit a exception when adding a document + void addDeleteDocID(int32_t docID); + void addDeleteQuery(const QueryPtr& query, int32_t docID); + + /// Does the synchronized work to finish/flush the inverted document. + void finishDocument(const DocumentsWriterThreadStatePtr& perThread, const DocWriterPtr& docWriter); + + friend class WaitQueue; +}; + +class DocState : public LuceneObject { +public: + DocState(); + virtual ~DocState(); + + LUCENE_CLASS(DocState); + +public: + DocumentsWriterWeakPtr _docWriter; + AnalyzerPtr analyzer; + int32_t maxFieldLength; + InfoStreamPtr infoStream; + SimilarityPtr similarity; + int32_t docID; + DocumentPtr doc; + String maxTermPrefix; + +public: + /// Only called by asserts + virtual bool testPoint(const String& name); + + void clear(); +}; + +/// RAMFile buffer for DocWriters. +class PerDocBuffer : public RAMFile { +public: + PerDocBuffer(const DocumentsWriterPtr& docWriter); + virtual ~PerDocBuffer(); + + LUCENE_CLASS(PerDocBuffer); + +protected: + DocumentsWriterWeakPtr _docWriter; + +public: + /// Recycle the bytes used. + void recycle(); + +protected: + /// Allocate bytes used from shared pool. + virtual ByteArray newBuffer(int32_t size); +}; + +/// Consumer returns this on each doc. This holds any state that must be flushed synchronized +/// "in docID order". We gather these and flush them in order. +class DocWriter : public LuceneObject { +public: + DocWriter(); + virtual ~DocWriter(); + + LUCENE_CLASS(DocWriter); + +public: + DocWriterPtr next; + int32_t docID; + +public: + virtual void finish() = 0; + virtual void abort() = 0; + virtual int64_t sizeInBytes() = 0; + + virtual void setNext(const DocWriterPtr& next); +}; + +/// The IndexingChain must define the {@link #getChain(DocumentsWriter)} method which returns the DocConsumer +/// that the DocumentsWriter calls to process the documents. +class IndexingChain : public LuceneObject { +public: + virtual ~IndexingChain(); + + LUCENE_CLASS(IndexingChain); + +public: + virtual DocConsumerPtr getChain(const DocumentsWriterPtr& documentsWriter) = 0; +}; + +/// This is the current indexing chain: +/// DocConsumer / DocConsumerPerThread +/// --> code: DocFieldProcessor / DocFieldProcessorPerThread +/// --> DocFieldConsumer / DocFieldConsumerPerThread / DocFieldConsumerPerField +/// --> code: DocFieldConsumers / DocFieldConsumersPerThread / DocFieldConsumersPerField +/// --> code: DocInverter / DocInverterPerThread / DocInverterPerField +/// --> InvertedDocConsumer / InvertedDocConsumerPerThread / InvertedDocConsumerPerField +/// --> code: TermsHash / TermsHashPerThread / TermsHashPerField +/// --> TermsHashConsumer / TermsHashConsumerPerThread / TermsHashConsumerPerField +/// --> code: FreqProxTermsWriter / FreqProxTermsWriterPerThread / FreqProxTermsWriterPerField +/// --> code: TermVectorsTermsWriter / TermVectorsTermsWriterPerThread / TermVectorsTermsWriterPerField +/// --> InvertedDocEndConsumer / InvertedDocConsumerPerThread / InvertedDocConsumerPerField +/// --> code: NormsWriter / NormsWriterPerThread / NormsWriterPerField +/// --> code: StoredFieldsWriter / StoredFieldsWriterPerThread / StoredFieldsWriterPerField +class DefaultIndexingChain : public IndexingChain { +public: + virtual ~DefaultIndexingChain(); + + LUCENE_CLASS(DefaultIndexingChain); + +public: + virtual DocConsumerPtr getChain(const DocumentsWriterPtr& documentsWriter); +}; + +class SkipDocWriter : public DocWriter { +public: + virtual ~SkipDocWriter(); + + LUCENE_CLASS(SkipDocWriter); + +public: + virtual void finish(); + virtual void abort(); + virtual int64_t sizeInBytes(); +}; + +class WaitQueue : public LuceneObject { +public: + WaitQueue(const DocumentsWriterPtr& docWriter); + virtual ~WaitQueue(); + + LUCENE_CLASS(WaitQueue); + +protected: + DocumentsWriterWeakPtr _docWriter; + +public: + Collection waiting; + int32_t nextWriteDocID; + int32_t nextWriteLoc; + int32_t numWaiting; + int64_t waitingBytes; + +public: + void reset(); + bool doResume(); + bool doPause(); + void abort(); + bool add(const DocWriterPtr& doc); + +protected: + void writeDocument(const DocWriterPtr& doc); +}; + +class ByteBlockAllocator : public ByteBlockPoolAllocatorBase { +public: + ByteBlockAllocator(const DocumentsWriterPtr& docWriter, int32_t blockSize); + virtual ~ByteBlockAllocator(); + + LUCENE_CLASS(ByteBlockAllocator); + +protected: + DocumentsWriterWeakPtr _docWriter; + +public: + int32_t blockSize; + Collection freeByteBlocks; + +public: + /// Allocate another byte[] from the shared pool + virtual ByteArray getByteBlock(bool trackAllocations); + + /// Return byte[]'s to the pool + virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end); + virtual void recycleByteBlocks(Collection blocks); +}; - class DocState : public LuceneObject - { - public: - DocState(); - virtual ~DocState(); - - LUCENE_CLASS(DocState); - - public: - DocumentsWriterWeakPtr _docWriter; - AnalyzerPtr analyzer; - int32_t maxFieldLength; - InfoStreamPtr infoStream; - SimilarityPtr similarity; - int32_t docID; - DocumentPtr doc; - String maxTermPrefix; - - public: - /// Only called by asserts - virtual bool testPoint(const String& name); - - void clear(); - }; - - /// RAMFile buffer for DocWriters. - class PerDocBuffer : public RAMFile - { - public: - PerDocBuffer(const DocumentsWriterPtr& docWriter); - virtual ~PerDocBuffer(); - - LUCENE_CLASS(PerDocBuffer); - - protected: - DocumentsWriterWeakPtr _docWriter; - - public: - /// Recycle the bytes used. - void recycle(); - - protected: - /// Allocate bytes used from shared pool. - virtual ByteArray newBuffer(int32_t size); - }; - - /// Consumer returns this on each doc. This holds any state that must be flushed synchronized - /// "in docID order". We gather these and flush them in order. - class DocWriter : public LuceneObject - { - public: - DocWriter(); - virtual ~DocWriter(); - - LUCENE_CLASS(DocWriter); - - public: - DocWriterPtr next; - int32_t docID; - - public: - virtual void finish() = 0; - virtual void abort() = 0; - virtual int64_t sizeInBytes() = 0; - - virtual void setNext(const DocWriterPtr& next); - }; - - /// The IndexingChain must define the {@link #getChain(DocumentsWriter)} method which returns the DocConsumer - /// that the DocumentsWriter calls to process the documents. - class IndexingChain : public LuceneObject - { - public: - virtual ~IndexingChain(); - - LUCENE_CLASS(IndexingChain); - - public: - virtual DocConsumerPtr getChain(const DocumentsWriterPtr& documentsWriter) = 0; - }; - - /// This is the current indexing chain: - /// DocConsumer / DocConsumerPerThread - /// --> code: DocFieldProcessor / DocFieldProcessorPerThread - /// --> DocFieldConsumer / DocFieldConsumerPerThread / DocFieldConsumerPerField - /// --> code: DocFieldConsumers / DocFieldConsumersPerThread / DocFieldConsumersPerField - /// --> code: DocInverter / DocInverterPerThread / DocInverterPerField - /// --> InvertedDocConsumer / InvertedDocConsumerPerThread / InvertedDocConsumerPerField - /// --> code: TermsHash / TermsHashPerThread / TermsHashPerField - /// --> TermsHashConsumer / TermsHashConsumerPerThread / TermsHashConsumerPerField - /// --> code: FreqProxTermsWriter / FreqProxTermsWriterPerThread / FreqProxTermsWriterPerField - /// --> code: TermVectorsTermsWriter / TermVectorsTermsWriterPerThread / TermVectorsTermsWriterPerField - /// --> InvertedDocEndConsumer / InvertedDocConsumerPerThread / InvertedDocConsumerPerField - /// --> code: NormsWriter / NormsWriterPerThread / NormsWriterPerField - /// --> code: StoredFieldsWriter / StoredFieldsWriterPerThread / StoredFieldsWriterPerField - class DefaultIndexingChain : public IndexingChain - { - public: - virtual ~DefaultIndexingChain(); - - LUCENE_CLASS(DefaultIndexingChain); - - public: - virtual DocConsumerPtr getChain(const DocumentsWriterPtr& documentsWriter); - }; - - class SkipDocWriter : public DocWriter - { - public: - virtual ~SkipDocWriter(); - - LUCENE_CLASS(SkipDocWriter); - - public: - virtual void finish(); - virtual void abort(); - virtual int64_t sizeInBytes(); - }; - - class WaitQueue : public LuceneObject - { - public: - WaitQueue(const DocumentsWriterPtr& docWriter); - virtual ~WaitQueue(); - - LUCENE_CLASS(WaitQueue); - - protected: - DocumentsWriterWeakPtr _docWriter; - - public: - Collection waiting; - int32_t nextWriteDocID; - int32_t nextWriteLoc; - int32_t numWaiting; - int64_t waitingBytes; - - public: - void reset(); - bool doResume(); - bool doPause(); - void abort(); - bool add(const DocWriterPtr& doc); - - protected: - void writeDocument(const DocWriterPtr& doc); - }; - - class ByteBlockAllocator : public ByteBlockPoolAllocatorBase - { - public: - ByteBlockAllocator(const DocumentsWriterPtr& docWriter, int32_t blockSize); - virtual ~ByteBlockAllocator(); - - LUCENE_CLASS(ByteBlockAllocator); - - protected: - DocumentsWriterWeakPtr _docWriter; - - public: - int32_t blockSize; - Collection freeByteBlocks; - - public: - /// Allocate another byte[] from the shared pool - virtual ByteArray getByteBlock(bool trackAllocations); - - /// Return byte[]'s to the pool - virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end); - virtual void recycleByteBlocks(Collection blocks); - }; } #endif diff --git a/include/DocumentsWriterThreadState.h b/include/DocumentsWriterThreadState.h index e85878fd..c0d86d33 100644 --- a/include/DocumentsWriterThreadState.h +++ b/include/DocumentsWriterThreadState.h @@ -9,31 +9,31 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Used by DocumentsWriter to maintain per-thread state. - /// We keep a separate Posting hash and other state for each thread and then merge postings - /// hashes from all threads when writing the segment. - class DocumentsWriterThreadState : public LuceneObject - { - public: - DocumentsWriterThreadState(const DocumentsWriterPtr& docWriter); - virtual ~DocumentsWriterThreadState(); - - LUCENE_CLASS(DocumentsWriterThreadState); - - public: - bool isIdle; // false if this is currently in use by a thread - int32_t numThreads; // Number of threads that share this instance - bool doFlushAfter; // true if we should flush after processing current doc - DocConsumerPerThreadPtr consumer; - DocStatePtr docState; - DocumentsWriterWeakPtr _docWriter; - - public: - virtual void initialize(); - void doAfterFlush(); - }; +namespace Lucene { + +/// Used by DocumentsWriter to maintain per-thread state. +/// We keep a separate Posting hash and other state for each thread and then merge postings +/// hashes from all threads when writing the segment. +class DocumentsWriterThreadState : public LuceneObject { +public: + DocumentsWriterThreadState(const DocumentsWriterPtr& docWriter); + virtual ~DocumentsWriterThreadState(); + + LUCENE_CLASS(DocumentsWriterThreadState); + +public: + bool isIdle; // false if this is currently in use by a thread + int32_t numThreads; // Number of threads that share this instance + bool doFlushAfter; // true if we should flush after processing current doc + DocConsumerPerThreadPtr consumer; + DocStatePtr docState; + DocumentsWriterWeakPtr _docWriter; + +public: + virtual void initialize(); + void doAfterFlush(); +}; + } #endif diff --git a/include/DoubleFieldSource.h b/include/DoubleFieldSource.h index 390e7e87..8934c979 100644 --- a/include/DoubleFieldSource.h +++ b/include/DoubleFieldSource.h @@ -10,54 +10,53 @@ #include "FieldCacheSource.h" #include "DocValues.h" -namespace Lucene -{ - /// Obtains double field values from the {@link FieldCache} using getDoubles() and makes those values available - /// as other numeric types, casting as needed. - /// - /// @see FieldCacheSource for requirements on the field. - /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite - /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU - /// per lookup but will not consume double the FieldCache RAM. - class DoubleFieldSource : public FieldCacheSource - { - public: - /// Create a cached double field source with a specific string-to-double parser. - DoubleFieldSource(const String& field, const DoubleParserPtr& parser = DoubleParserPtr()); - virtual ~DoubleFieldSource(); - - LUCENE_CLASS(DoubleFieldSource); - - protected: - DoubleParserPtr parser; - - public: - virtual String description(); - virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); - virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); - virtual int32_t cachedFieldSourceHashCode(); - }; - - class DoubleDocValues : public DocValues - { - public: - DoubleDocValues(const DoubleFieldSourcePtr& source, Collection arr); - virtual ~DoubleDocValues(); - - LUCENE_CLASS(DoubleDocValues); - - protected: - DoubleFieldSourceWeakPtr _source; - Collection arr; - - public: - virtual double doubleVal(int32_t doc); - virtual String toString(int32_t doc); - virtual CollectionValue getInnerArray(); - }; +namespace Lucene { + +/// Obtains double field values from the {@link FieldCache} using getDoubles() and makes those values available +/// as other numeric types, casting as needed. +/// +/// @see FieldCacheSource for requirements on the field. +/// +/// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite +/// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's +/// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, +/// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU +/// per lookup but will not consume double the FieldCache RAM. +class DoubleFieldSource : public FieldCacheSource { +public: + /// Create a cached double field source with a specific string-to-double parser. + DoubleFieldSource(const String& field, const DoubleParserPtr& parser = DoubleParserPtr()); + virtual ~DoubleFieldSource(); + + LUCENE_CLASS(DoubleFieldSource); + +protected: + DoubleParserPtr parser; + +public: + virtual String description(); + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); + virtual int32_t cachedFieldSourceHashCode(); +}; + +class DoubleDocValues : public DocValues { +public: + DoubleDocValues(const DoubleFieldSourcePtr& source, Collection arr); + virtual ~DoubleDocValues(); + + LUCENE_CLASS(DoubleDocValues); + +protected: + DoubleFieldSourceWeakPtr _source; + Collection arr; + +public: + virtual double doubleVal(int32_t doc); + virtual String toString(int32_t doc); + virtual CollectionValue getInnerArray(); +}; + } #endif diff --git a/include/ExactPhraseScorer.h b/include/ExactPhraseScorer.h index 68e24e72..c70ac192 100644 --- a/include/ExactPhraseScorer.h +++ b/include/ExactPhraseScorer.h @@ -9,19 +9,19 @@ #include "PhraseScorer.h" -namespace Lucene -{ - class ExactPhraseScorer : public PhraseScorer - { - public: - ExactPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms); - virtual ~ExactPhraseScorer(); - - LUCENE_CLASS(ExactPhraseScorer); - - protected: - virtual double phraseFreq(); - }; +namespace Lucene { + +class ExactPhraseScorer : public PhraseScorer { +public: + ExactPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms); + virtual ~ExactPhraseScorer(); + + LUCENE_CLASS(ExactPhraseScorer); + +protected: + virtual double phraseFreq(); +}; + } #endif diff --git a/include/Explanation.h b/include/Explanation.h index 65c26962..289868d1 100644 --- a/include/Explanation.h +++ b/include/Explanation.h @@ -9,79 +9,78 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Describes the score computation for document and query. - class LPPAPI Explanation : public LuceneObject - { - public: - Explanation(double value = 0, const String& description = EmptyString); - virtual ~Explanation(); +namespace Lucene { - LUCENE_CLASS(Explanation); +/// Describes the score computation for document and query. +class LPPAPI Explanation : public LuceneObject { +public: + Explanation(double value = 0, const String& description = EmptyString); + virtual ~Explanation(); - protected: - double value; // the value of this node - String description; // what it represents - Collection details; // sub-explanations + LUCENE_CLASS(Explanation); - public: - /// Indicates whether or not this Explanation models a good match. - /// - /// By default, an Explanation represents a "match" if the value is positive. - /// - /// @see #getValue - virtual bool isMatch(); +protected: + double value; // the value of this node + String description; // what it represents + Collection details; // sub-explanations - /// The value assigned to this explanation node. - virtual double getValue(); +public: + /// Indicates whether or not this Explanation models a good match. + /// + /// By default, an Explanation represents a "match" if the value is positive. + /// + /// @see #getValue + virtual bool isMatch(); - /// Sets the value assigned to this explanation node. - virtual void setValue(double value); + /// The value assigned to this explanation node. + virtual double getValue(); - /// A description of this explanation node. - virtual String getDescription(); + /// Sets the value assigned to this explanation node. + virtual void setValue(double value); - /// Sets the description of this explanation node. - virtual void setDescription(const String& description); + /// A description of this explanation node. + virtual String getDescription(); - /// The sub-nodes of this explanation node. - virtual Collection getDetails(); + /// Sets the description of this explanation node. + virtual void setDescription(const String& description); - /// Adds a sub-node to this explanation node. - virtual void addDetail(const ExplanationPtr& detail); + /// The sub-nodes of this explanation node. + virtual Collection getDetails(); - /// Render an explanation as text. - virtual String toString(); + /// Adds a sub-node to this explanation node. + virtual void addDetail(const ExplanationPtr& detail); - /// Render an explanation as HTML. - virtual String toHtml(); + /// Render an explanation as text. + virtual String toString(); - protected: - /// A short one line summary which should contain all high level information about this Explanation, - /// without the "Details" - virtual String getSummary(); + /// Render an explanation as HTML. + virtual String toHtml(); - virtual String toString(int32_t depth); - }; +protected: + /// A short one line summary which should contain all high level information about this Explanation, + /// without the "Details" + virtual String getSummary(); + + virtual String toString(int32_t depth); +}; + +/// Small Util class used to pass both an idf factor as well as an explanation for that factor. +/// +/// This class will likely be held on a {@link Weight}, so be aware before storing any large fields. +class LPPAPI IDFExplanation : public LuceneObject { +public: + virtual ~IDFExplanation(); + LUCENE_CLASS(IDFExplanation); + +public: + /// @return the idf factor + virtual double getIdf() = 0; + + /// This should be calculated lazily if possible. + /// @return the explanation for the idf factor. + virtual String explain() = 0; +}; - /// Small Util class used to pass both an idf factor as well as an explanation for that factor. - /// - /// This class will likely be held on a {@link Weight}, so be aware before storing any large fields. - class LPPAPI IDFExplanation : public LuceneObject - { - public: - virtual ~IDFExplanation(); - LUCENE_CLASS(IDFExplanation); - - public: - /// @return the idf factor - virtual double getIdf() = 0; - - /// This should be calculated lazily if possible. - /// @return the explanation for the idf factor. - virtual String explain() = 0; - }; } #endif diff --git a/include/FSDirectory.h b/include/FSDirectory.h index 15971ed4..31bed0e0 100644 --- a/include/FSDirectory.h +++ b/include/FSDirectory.h @@ -9,125 +9,125 @@ #include "Directory.h" -namespace Lucene -{ - /// Base class for Directory implementations that store index files in the file system. There are currently three - /// core subclasses: - /// - /// {@link SimpleFSDirectory} is a straightforward implementation using std::ofstream and std::ifstream. - /// - /// {@link MMapDirectory} uses memory-mapped IO when reading. This is a good choice if you have plenty of virtual - /// memory relative to your index size, eg if you are running on a 64 bit operating system, oryour index sizes are - /// small enough to fit into the virtual memory space. - /// - /// For users who have no reason to prefer a specific implementation, it's best to simply use {@link #open}. For - /// all others, you should instantiate the desired implementation directly. - /// - /// The locking implementation is by default {@link NativeFSLockFactory}, but can be changed by passing in a custom - /// {@link LockFactory} instance. - /// @see Directory - class LPPAPI FSDirectory : public Directory - { - protected: - /// Create a new FSDirectory for the named location (ctor for subclasses). - /// @param path the path of the directory. - /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) - FSDirectory(const String& path, const LockFactoryPtr& lockFactory); - - public: - virtual ~FSDirectory(); - - LUCENE_CLASS(FSDirectory); - - public: - /// Default read chunk size. This is a conditional default based on operating system. - /// @see #setReadChunkSize - static const int32_t DEFAULT_READ_CHUNK_SIZE; - - protected: - bool checked; - - /// The underlying filesystem directory. - String directory; - - /// @see #DEFAULT_READ_CHUNK_SIZE - int32_t chunkSize; - - public: - /// Creates an FSDirectory instance. - static FSDirectoryPtr open(const String& path); - - /// Just like {@link #open(File)}, but allows you to also specify a custom {@link LockFactory}. - static FSDirectoryPtr open(const String& path, const LockFactoryPtr& lockFactory); - - /// Lists all files (not subdirectories) in the directory. - /// @throws NoSuchDirectoryException if the directory does not exist, or does exist but is not a directory. - static HashSet listAll(const String& dir); - - /// Returns the time the named file was last modified. - static uint64_t fileModified(const String& directory, const String& name); - - /// Create file system directory. - void createDir(); - - /// Return file system directory. - String getFile(); - - /// Sets the maximum number of bytes read at once from the underlying file during {@link IndexInput#readBytes}. - /// The default value is {@link #DEFAULT_READ_CHUNK_SIZE}. Changes to this value will not impact any already-opened - /// {@link IndexInput}s. You should call this before attempting to open an index on the directory. This value should - /// be as large as possible to reduce any possible performance impact. - void setReadChunkSize(int32_t chunkSize); - - /// The maximum number of bytes to read at once from the underlying file during {@link IndexInput#readBytes}. - /// @see #setReadChunkSize - int32_t getReadChunkSize(); - - /// Lists all files (not subdirectories) in the directory. - /// @see #listAll(const String&) - virtual HashSet listAll(); - - /// Returns true if a file with the given name exists. - virtual bool fileExists(const String& name); - - /// Returns the time the named file was last modified. - virtual uint64_t fileModified(const String& name); - - /// Set the modified time of an existing file to now. - virtual void touchFile(const String& name); - - /// Removes an existing file in the directory. - virtual void deleteFile(const String& name); - - /// Returns the length in bytes of a file in the directory. - virtual int64_t fileLength(const String& name); - - /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit changes to - /// the index, to prevent a machine/OS crash from corrupting the index. - virtual void sync(const String& name); - - /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory - /// implementation may ignore the buffer size. - virtual IndexInputPtr openInput(const String& name); - - /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory - /// implementation may ignore the buffer size. Currently the only Directory implementations that respect this parameter - /// are {@link FSDirectory} and {@link CompoundFileReader}. - virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - - /// Return a string identifier that uniquely differentiates this Directory instance from other Directory instances. - virtual String getLockID(); +namespace Lucene { + +/// Base class for Directory implementations that store index files in the file system. There are currently three +/// core subclasses: +/// +/// {@link SimpleFSDirectory} is a straightforward implementation using std::ofstream and std::ifstream. +/// +/// {@link MMapDirectory} uses memory-mapped IO when reading. This is a good choice if you have plenty of virtual +/// memory relative to your index size, eg if you are running on a 64 bit operating system, oryour index sizes are +/// small enough to fit into the virtual memory space. +/// +/// For users who have no reason to prefer a specific implementation, it's best to simply use {@link #open}. For +/// all others, you should instantiate the desired implementation directly. +/// +/// The locking implementation is by default {@link NativeFSLockFactory}, but can be changed by passing in a custom +/// {@link LockFactory} instance. +/// @see Directory +class LPPAPI FSDirectory : public Directory { +protected: + /// Create a new FSDirectory for the named location (ctor for subclasses). + /// @param path the path of the directory. + /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) + FSDirectory(const String& path, const LockFactoryPtr& lockFactory); - /// Closes the store to future operations. - virtual void close(); +public: + virtual ~FSDirectory(); - /// For debug output. - virtual String toString(); + LUCENE_CLASS(FSDirectory); + +public: + /// Default read chunk size. This is a conditional default based on operating system. + /// @see #setReadChunkSize + static const int32_t DEFAULT_READ_CHUNK_SIZE; + +protected: + bool checked; + + /// The underlying filesystem directory. + String directory; + + /// @see #DEFAULT_READ_CHUNK_SIZE + int32_t chunkSize; + +public: + /// Creates an FSDirectory instance. + static FSDirectoryPtr open(const String& path); + + /// Just like {@link #open(File)}, but allows you to also specify a custom {@link LockFactory}. + static FSDirectoryPtr open(const String& path, const LockFactoryPtr& lockFactory); + + /// Lists all files (not subdirectories) in the directory. + /// @throws NoSuchDirectoryException if the directory does not exist, or does exist but is not a directory. + static HashSet listAll(const String& dir); + + /// Returns the time the named file was last modified. + static uint64_t fileModified(const String& directory, const String& name); + + /// Create file system directory. + void createDir(); + + /// Return file system directory. + String getFile(); + + /// Sets the maximum number of bytes read at once from the underlying file during {@link IndexInput#readBytes}. + /// The default value is {@link #DEFAULT_READ_CHUNK_SIZE}. Changes to this value will not impact any already-opened + /// {@link IndexInput}s. You should call this before attempting to open an index on the directory. This value should + /// be as large as possible to reduce any possible performance impact. + void setReadChunkSize(int32_t chunkSize); + + /// The maximum number of bytes to read at once from the underlying file during {@link IndexInput#readBytes}. + /// @see #setReadChunkSize + int32_t getReadChunkSize(); + + /// Lists all files (not subdirectories) in the directory. + /// @see #listAll(const String&) + virtual HashSet listAll(); + + /// Returns true if a file with the given name exists. + virtual bool fileExists(const String& name); + + /// Returns the time the named file was last modified. + virtual uint64_t fileModified(const String& name); + + /// Set the modified time of an existing file to now. + virtual void touchFile(const String& name); + + /// Removes an existing file in the directory. + virtual void deleteFile(const String& name); + + /// Returns the length in bytes of a file in the directory. + virtual int64_t fileLength(const String& name); + + /// Ensure that any writes to this file are moved to stable storage. Lucene uses this to properly commit changes to + /// the index, to prevent a machine/OS crash from corrupting the index. + virtual void sync(const String& name); + + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory + /// implementation may ignore the buffer size. + virtual IndexInputPtr openInput(const String& name); + + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory + /// implementation may ignore the buffer size. Currently the only Directory implementations that respect this parameter + /// are {@link FSDirectory} and {@link CompoundFileReader}. + virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); + + /// Return a string identifier that uniquely differentiates this Directory instance from other Directory instances. + virtual String getLockID(); + + /// Closes the store to future operations. + virtual void close(); + + /// For debug output. + virtual String toString(); + +protected: + /// Initializes the directory to create a new file with the given name. This method should be used in {@link #createOutput}. + void initOutput(const String& name); +}; - protected: - /// Initializes the directory to create a new file with the given name. This method should be used in {@link #createOutput}. - void initOutput(const String& name); - }; } #endif diff --git a/include/FSLockFactory.h b/include/FSLockFactory.h index 162cead8..99ee04e6 100644 --- a/include/FSLockFactory.h +++ b/include/FSLockFactory.h @@ -9,33 +9,33 @@ #include "LockFactory.h" -namespace Lucene -{ - /// Base class for file system based locking implementation. - class LPPAPI FSLockFactory : public LockFactory - { - protected: - FSLockFactory(); - - public: - virtual ~FSLockFactory(); - - LUCENE_CLASS(FSLockFactory); - - protected: - /// Directory for the lock files. - String lockDir; - - public: - /// Set the lock directory. This method can be only called once to - /// initialize the lock directory. It is used by {@link FSDirectory} - /// to set the lock directory to itself. Subclasses can also use - /// this method to set the directory in the constructor. - void setLockDir(const String& lockDir); - - /// Retrieve the lock directory. - String getLockDir(); - }; +namespace Lucene { + +/// Base class for file system based locking implementation. +class LPPAPI FSLockFactory : public LockFactory { +protected: + FSLockFactory(); + +public: + virtual ~FSLockFactory(); + + LUCENE_CLASS(FSLockFactory); + +protected: + /// Directory for the lock files. + String lockDir; + +public: + /// Set the lock directory. This method can be only called once to + /// initialize the lock directory. It is used by {@link FSDirectory} + /// to set the lock directory to itself. Subclasses can also use + /// this method to set the directory in the constructor. + void setLockDir(const String& lockDir); + + /// Retrieve the lock directory. + String getLockDir(); +}; + } #endif diff --git a/include/FastCharStream.h b/include/FastCharStream.h index d255cfce..01bbec3b 100644 --- a/include/FastCharStream.h +++ b/include/FastCharStream.h @@ -9,49 +9,49 @@ #include "QueryParserCharStream.h" -namespace Lucene -{ - /// An efficient implementation of QueryParserCharStream interface. - /// - /// Note that this does not do line-number counting, but instead keeps track of the character position of - /// the token in the input, as required by Lucene's {@link Token} API. - class LPPAPI FastCharStream : public QueryParserCharStream, public LuceneObject - { - public: - /// Constructs from a Reader. - FastCharStream(const ReaderPtr& reader); - virtual ~FastCharStream(); - - LUCENE_CLASS(FastCharStream); - - public: - CharArray buffer; - - int32_t bufferLength; // end of valid chars - int32_t bufferPosition; // next char to read - - int32_t tokenStart; // offset in buffer - int32_t bufferStart; // position in file of buffer - - ReaderPtr input; // source of chars - - public: - virtual wchar_t readChar(); - virtual wchar_t BeginToken(); - virtual void backup(int32_t amount); - virtual String GetImage(); - virtual CharArray GetSuffix(int32_t length); - virtual void Done(); - virtual int32_t getColumn(); - virtual int32_t getLine(); - virtual int32_t getEndColumn(); - virtual int32_t getEndLine(); - virtual int32_t getBeginColumn(); - virtual int32_t getBeginLine(); - - protected: - void refill(); - }; +namespace Lucene { + +/// An efficient implementation of QueryParserCharStream interface. +/// +/// Note that this does not do line-number counting, but instead keeps track of the character position of +/// the token in the input, as required by Lucene's {@link Token} API. +class LPPAPI FastCharStream : public QueryParserCharStream, public LuceneObject { +public: + /// Constructs from a Reader. + FastCharStream(const ReaderPtr& reader); + virtual ~FastCharStream(); + + LUCENE_CLASS(FastCharStream); + +public: + CharArray buffer; + + int32_t bufferLength; // end of valid chars + int32_t bufferPosition; // next char to read + + int32_t tokenStart; // offset in buffer + int32_t bufferStart; // position in file of buffer + + ReaderPtr input; // source of chars + +public: + virtual wchar_t readChar(); + virtual wchar_t BeginToken(); + virtual void backup(int32_t amount); + virtual String GetImage(); + virtual CharArray GetSuffix(int32_t length); + virtual void Done(); + virtual int32_t getColumn(); + virtual int32_t getLine(); + virtual int32_t getEndColumn(); + virtual int32_t getEndLine(); + virtual int32_t getBeginColumn(); + virtual int32_t getBeginLine(); + +protected: + void refill(); +}; + } #endif diff --git a/include/Field.h b/include/Field.h index a2fb673a..1429240a 100644 --- a/include/Field.h +++ b/include/Field.h @@ -9,147 +9,147 @@ #include "AbstractField.h" -namespace Lucene -{ - class LPPAPI Field : public AbstractField - { - public: - /// Create a field by specifying its name, value and how it will be saved in the index. Term vectors - /// will not be stored in the index. - /// - /// @param name The name of the field - /// @param value The string to process - /// @param store Whether value should be stored in the index - /// @param index Whether the field should be indexed, and if so, if it should be tokenized before indexing - Field(const String& name, const String& value, Store store, Index index); - - /// Create a field by specifying its name, value and how it will be saved in the index. - /// - /// @param name The name of the field - /// @param value The string to process - /// @param store Whether value should be stored in the index - /// @param index Whether the field should be indexed, and if so, if it should be tokenized before indexing - /// @param termVector Whether term vector should be stored - Field(const String& name, const String& value, Store store, Index index, TermVector termVector); - - /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. The Reader is - /// read only when the Document is added to the index, ie. you may not close the Reader until {@link - /// IndexWriter#addDocument(Document)} has been called. - /// - /// @param name The name of the field - /// @param reader The reader with the content - Field(const String& name, const ReaderPtr& reader); - - /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. The - /// Reader is read only when the Document is added to the index, ie. you may not close the Reader until - /// {@link IndexWriter#addDocument(Document)} has been called. - /// - /// @param name The name of the field - /// @param reader The reader with the content - /// @param termVector Whether term vector should be stored - Field(const String& name, const ReaderPtr& reader, TermVector termVector); - - /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. This is useful - /// for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, ie. you - /// may not close the TokenStream until {@link IndexWriter#addDocument(Document)} has been called. - /// - /// @param name The name of the field - /// @param tokenStream The TokenStream with the content - Field(const String& name, const TokenStreamPtr& tokenStream); - - /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. This is - /// useful for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, - /// ie. you may not close the TokenStream until {@link IndexWriter#addDocument(Document)} has been called. - /// - /// @param name The name of the field - /// @param tokenStream The TokenStream with the content - /// @param termVector Whether term vector should be stored - Field(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector); - - /// Create a stored field with binary value. Optionally the value may be compressed. - /// - /// @param name The name of the field - /// @param value The binary value - /// @param store How value should be stored (compressed or not) - Field(const String& name, ByteArray value, Store store); - - /// Create a stored field with binary value. Optionally the value may be compressed. - /// - /// @param name The name of the field - /// @param value The binary value - /// @param offset Starting offset in value where this Field's bytes are - /// @param length Number of bytes to use for this Field, starting at offset - /// @param store How value should be stored (compressed or not) - Field(const String& name, ByteArray value, int32_t offset, int32_t length, Store store); - - virtual ~Field(); - - LUCENE_CLASS(Field); - - public: - using AbstractField::isStored; - using AbstractField::isIndexed; - - /// Specifies whether and how a field should be stored. - static bool isStored(Store store); - - /// Specifies whether and how a field should be indexed. - static bool isIndexed(Index index); - static bool isAnalyzed(Index index); - static bool omitNorms(Index index); - - /// Get the best representation of the index given the flags. - static Field::Index toIndex(bool indexed, bool analyzed); - - /// Get the best representation of the index given the flags. - static Field::Index toIndex(bool indexed, bool analyzed, bool omitNorms); - - /// Specifies whether and how a field should have term vectors. - static bool isStored(TermVector termVector); - static bool withPositions(TermVector termVector); - static bool withOffsets(TermVector termVector); - - /// Get the best representation of the index given the flags. - static Field::TermVector toTermVector(bool stored, bool withOffsets, bool withPositions); - - /// The value of the field as a String, or null. If null, the Reader value or binary value is used. - /// Exactly one of stringValue(), readerValue(), and getBinaryValue() must be set. - virtual String stringValue(); - - /// The value of the field as a Reader, or null. If null, the String value or binary value is used. - /// Exactly one of stringValue(), readerValue(), and getBinaryValue() must be set. - virtual ReaderPtr readerValue(); - - /// The value of the field as a TokesStream, or null. If null, the Reader value or String value is - /// analyzed to produce the indexed tokens. - virtual TokenStreamPtr tokenStreamValue(); - - /// Change the value of this field. This can be used during indexing to re-use a single Field instance - /// to improve indexing speed. Typically a single {@link Document} instance is re-used as well. This - /// helps most on small documents. - /// - /// Each Field instance should only be used once within a single {@link Document} instance. - virtual void setValue(const String& value); - - /// Change the value of this field. - virtual void setValue(const ReaderPtr& value); - - /// Change the value of this field. - virtual void setValue(ByteArray value); - - /// Change the value of this field. - virtual void setValue(ByteArray value, int32_t offset, int32_t length); - - /// Sets the token stream to be used for indexing and causes isIndexed() and isTokenized() to return - /// true. May be combined with stored values from stringValue() or getBinaryValue() - virtual void setTokenStream(const TokenStreamPtr& tokenStream); - - protected: - void ConstructField(const String& name, const String& value, Store store, Index index, TermVector termVector); - void ConstructField(const String& name, const ReaderPtr& reader, TermVector termVector); - void ConstructField(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector); - void ConstructField(const String& name, ByteArray value, int32_t offset, int32_t length, Store store); - }; +namespace Lucene { + +class LPPAPI Field : public AbstractField { +public: + /// Create a field by specifying its name, value and how it will be saved in the index. Term vectors + /// will not be stored in the index. + /// + /// @param name The name of the field + /// @param value The string to process + /// @param store Whether value should be stored in the index + /// @param index Whether the field should be indexed, and if so, if it should be tokenized before indexing + Field(const String& name, const String& value, Store store, Index index); + + /// Create a field by specifying its name, value and how it will be saved in the index. + /// + /// @param name The name of the field + /// @param value The string to process + /// @param store Whether value should be stored in the index + /// @param index Whether the field should be indexed, and if so, if it should be tokenized before indexing + /// @param termVector Whether term vector should be stored + Field(const String& name, const String& value, Store store, Index index, TermVector termVector); + + /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. The Reader is + /// read only when the Document is added to the index, ie. you may not close the Reader until {@link + /// IndexWriter#addDocument(Document)} has been called. + /// + /// @param name The name of the field + /// @param reader The reader with the content + Field(const String& name, const ReaderPtr& reader); + + /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. The + /// Reader is read only when the Document is added to the index, ie. you may not close the Reader until + /// {@link IndexWriter#addDocument(Document)} has been called. + /// + /// @param name The name of the field + /// @param reader The reader with the content + /// @param termVector Whether term vector should be stored + Field(const String& name, const ReaderPtr& reader, TermVector termVector); + + /// Create a tokenized and indexed field that is not stored. Term vectors will not be stored. This is useful + /// for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, ie. you + /// may not close the TokenStream until {@link IndexWriter#addDocument(Document)} has been called. + /// + /// @param name The name of the field + /// @param tokenStream The TokenStream with the content + Field(const String& name, const TokenStreamPtr& tokenStream); + + /// Create a tokenized and indexed field that is not stored, optionally with storing term vectors. This is + /// useful for pre-analyzed fields. The TokenStream is read only when the Document is added to the index, + /// ie. you may not close the TokenStream until {@link IndexWriter#addDocument(Document)} has been called. + /// + /// @param name The name of the field + /// @param tokenStream The TokenStream with the content + /// @param termVector Whether term vector should be stored + Field(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector); + + /// Create a stored field with binary value. Optionally the value may be compressed. + /// + /// @param name The name of the field + /// @param value The binary value + /// @param store How value should be stored (compressed or not) + Field(const String& name, ByteArray value, Store store); + + /// Create a stored field with binary value. Optionally the value may be compressed. + /// + /// @param name The name of the field + /// @param value The binary value + /// @param offset Starting offset in value where this Field's bytes are + /// @param length Number of bytes to use for this Field, starting at offset + /// @param store How value should be stored (compressed or not) + Field(const String& name, ByteArray value, int32_t offset, int32_t length, Store store); + + virtual ~Field(); + + LUCENE_CLASS(Field); + +public: + using AbstractField::isStored; + using AbstractField::isIndexed; + + /// Specifies whether and how a field should be stored. + static bool isStored(Store store); + + /// Specifies whether and how a field should be indexed. + static bool isIndexed(Index index); + static bool isAnalyzed(Index index); + static bool omitNorms(Index index); + + /// Get the best representation of the index given the flags. + static Field::Index toIndex(bool indexed, bool analyzed); + + /// Get the best representation of the index given the flags. + static Field::Index toIndex(bool indexed, bool analyzed, bool omitNorms); + + /// Specifies whether and how a field should have term vectors. + static bool isStored(TermVector termVector); + static bool withPositions(TermVector termVector); + static bool withOffsets(TermVector termVector); + + /// Get the best representation of the index given the flags. + static Field::TermVector toTermVector(bool stored, bool withOffsets, bool withPositions); + + /// The value of the field as a String, or null. If null, the Reader value or binary value is used. + /// Exactly one of stringValue(), readerValue(), and getBinaryValue() must be set. + virtual String stringValue(); + + /// The value of the field as a Reader, or null. If null, the String value or binary value is used. + /// Exactly one of stringValue(), readerValue(), and getBinaryValue() must be set. + virtual ReaderPtr readerValue(); + + /// The value of the field as a TokesStream, or null. If null, the Reader value or String value is + /// analyzed to produce the indexed tokens. + virtual TokenStreamPtr tokenStreamValue(); + + /// Change the value of this field. This can be used during indexing to re-use a single Field instance + /// to improve indexing speed. Typically a single {@link Document} instance is re-used as well. This + /// helps most on small documents. + /// + /// Each Field instance should only be used once within a single {@link Document} instance. + virtual void setValue(const String& value); + + /// Change the value of this field. + virtual void setValue(const ReaderPtr& value); + + /// Change the value of this field. + virtual void setValue(ByteArray value); + + /// Change the value of this field. + virtual void setValue(ByteArray value, int32_t offset, int32_t length); + + /// Sets the token stream to be used for indexing and causes isIndexed() and isTokenized() to return + /// true. May be combined with stored values from stringValue() or getBinaryValue() + virtual void setTokenStream(const TokenStreamPtr& tokenStream); + +protected: + void ConstructField(const String& name, const String& value, Store store, Index index, TermVector termVector); + void ConstructField(const String& name, const ReaderPtr& reader, TermVector termVector); + void ConstructField(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector); + void ConstructField(const String& name, ByteArray value, int32_t offset, int32_t length, Store store); +}; + } #endif diff --git a/include/FieldCache.h b/include/FieldCache.h index 12ea2e36..d00073b6 100644 --- a/include/FieldCache.h +++ b/include/FieldCache.h @@ -10,272 +10,263 @@ #include #include "LuceneObject.h" -namespace Lucene -{ - /// Maintains caches of term values. - /// @see FieldCacheSanityChecker - class LPPAPI FieldCache - { - public: - virtual ~FieldCache(); - LUCENE_INTERFACE(FieldCache); - - public: - /// Specifies whether and how a field should be stored. - enum CacheType - { - CACHE_BYTE = 1, - CACHE_INT, - CACHE_LONG, - CACHE_DOUBLE, - CACHE_STRING, - CACHE_STRING_INDEX - }; - - /// Indicator for StringIndex values in the cache. - /// NOTE: the value assigned to this constant must not be the same as any of those in SortField - static const int32_t STRING_INDEX; - - public: - /// The cache used internally by sorting and range query classes. - static FieldCachePtr DEFAULT(); - - /// The default parser for byte values, which are encoded by StringUtils::toInt - static ByteParserPtr DEFAULT_BYTE_PARSER(); - - /// The default parser for int values, which are encoded by StringUtils::toInt - static IntParserPtr DEFAULT_INT_PARSER(); - - /// The default parser for int values, which are encoded by StringUtils::toLong - static LongParserPtr DEFAULT_LONG_PARSER(); - - /// The default parser for double values, which are encoded by StringUtils::toDouble - static DoubleParserPtr DEFAULT_DOUBLE_PARSER(); - - /// A parser instance for int values encoded by {@link NumericUtils#prefixCodedToInt(String)}, - /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. - static IntParserPtr NUMERIC_UTILS_INT_PARSER(); - - /// A parser instance for long values encoded by {@link NumericUtils#prefixCodedToLong(String)}, - /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. - static LongParserPtr NUMERIC_UTILS_LONG_PARSER(); - - /// A parser instance for double values encoded by {@link NumericUtils}, - /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. - static DoubleParserPtr NUMERIC_UTILS_DOUBLE_PARSER(); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as a single byte and returns an array of size reader.maxDoc() of the value each document - /// has in the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the single byte values. - /// @return The values in the given field for each document. - virtual Collection getBytes(const IndexReaderPtr& reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as bytes and returns an array of size reader.maxDoc() of the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the bytes. - /// @param parser Computes byte for string values. - /// @return The values in the given field for each document. - virtual Collection getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as integers and returns an array of size reader.maxDoc() of the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the integers. - /// @return The values in the given field for each document. - virtual Collection getInts(const IndexReaderPtr& reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as integers and returns an array of size reader.maxDoc() of the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the integers. - /// @param parser Computes integer for string values. - /// @return The values in the given field for each document. - virtual Collection getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as longs and returns an array of size reader.maxDoc() of the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the longs. - /// @return The values in the given field for each document. - virtual Collection getLongs(const IndexReaderPtr& reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as longs and returns an array of size reader.maxDoc() of the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the longs. - /// @param parser Computes long for string values. - /// @return The values in the given field for each document. - virtual Collection getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as integers and returns an array of size reader.maxDoc() of the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the doubles. - /// @return The values in the given field for each document. - virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in - /// field as doubles and returns an array of size reader.maxDoc() of the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the doubles. - /// @param parser Computes double for string values. - /// @return The values in the given field for each document. - virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser); - - /// Checks the internal cache for an appropriate entry, and if none are found, reads the term values in - /// field and returns an array of size reader.maxDoc() containing the value each document has in - /// the given field. - /// @param reader Used to get field values. - /// @param field Which field contains the strings. - /// @return The values in the given field for each document. - virtual Collection getStrings(const IndexReaderPtr& reader, const String& field); - - /// Checks the internal cache for an appropriate entry, and if none are found reads the term values in - /// field and returns an array of them in natural order, along with an array telling which element in - /// the term array each document uses. - /// @param reader Used to get field values. - /// @param field Which field contains the strings. - /// @return Array of terms and index into the array for each document. - virtual StringIndexPtr getStringIndex(const IndexReaderPtr& reader, const String& field); - - /// Generates an array of CacheEntry objects representing all items currently in the FieldCache. - virtual Collection getCacheEntries() = 0; - - /// Instructs the FieldCache to forcibly expunge all entries from the underlying caches. This is intended - /// only to be used for test methods as a way to ensure a known base state of the Cache. It should not be - /// relied on for "Cache maintenance" in general application code. - virtual void purgeAllCaches() = 0; - - /// Drops all cache entries associated with this reader. NOTE: this reader must precisely match the reader - /// that the cache entry is keyed on. If you pass a top-level reader, it usually will have no effect as - /// Lucene now caches at the segment reader level. - virtual void purge(const IndexReaderPtr& r) = 0; - - /// If non-null, FieldCacheImpl will warn whenever entries are created that are not sane according to - /// {@link FieldCacheSanityChecker}. - virtual void setInfoStream(const InfoStreamPtr& stream); - - /// @see #setInfoStream - virtual InfoStreamPtr getInfoStream(); +namespace Lucene { + +/// Maintains caches of term values. +/// @see FieldCacheSanityChecker +class LPPAPI FieldCache { +public: + virtual ~FieldCache(); + LUCENE_INTERFACE(FieldCache); + +public: + /// Specifies whether and how a field should be stored. + enum CacheType { + CACHE_BYTE = 1, + CACHE_INT, + CACHE_LONG, + CACHE_DOUBLE, + CACHE_STRING, + CACHE_STRING_INDEX }; - class LPPAPI CreationPlaceholder : public LuceneObject - { - public: - virtual ~CreationPlaceholder(); - LUCENE_CLASS(CreationPlaceholder); + /// Indicator for StringIndex values in the cache. + /// NOTE: the value assigned to this constant must not be the same as any of those in SortField + static const int32_t STRING_INDEX; + +public: + /// The cache used internally by sorting and range query classes. + static FieldCachePtr DEFAULT(); + + /// The default parser for byte values, which are encoded by StringUtils::toInt + static ByteParserPtr DEFAULT_BYTE_PARSER(); + + /// The default parser for int values, which are encoded by StringUtils::toInt + static IntParserPtr DEFAULT_INT_PARSER(); + + /// The default parser for int values, which are encoded by StringUtils::toLong + static LongParserPtr DEFAULT_LONG_PARSER(); + + /// The default parser for double values, which are encoded by StringUtils::toDouble + static DoubleParserPtr DEFAULT_DOUBLE_PARSER(); + + /// A parser instance for int values encoded by {@link NumericUtils#prefixCodedToInt(String)}, + /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. + static IntParserPtr NUMERIC_UTILS_INT_PARSER(); + + /// A parser instance for long values encoded by {@link NumericUtils#prefixCodedToLong(String)}, + /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. + static LongParserPtr NUMERIC_UTILS_LONG_PARSER(); + + /// A parser instance for double values encoded by {@link NumericUtils}, + /// eg. when indexed via {@link NumericField}/{@link NumericTokenStream}. + static DoubleParserPtr NUMERIC_UTILS_DOUBLE_PARSER(); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as a single byte and returns an array of size reader.maxDoc() of the value each document + /// has in the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the single byte values. + /// @return The values in the given field for each document. + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as bytes and returns an array of size reader.maxDoc() of the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the bytes. + /// @param parser Computes byte for string values. + /// @return The values in the given field for each document. + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as integers and returns an array of size reader.maxDoc() of the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the integers. + /// @return The values in the given field for each document. + virtual Collection getInts(const IndexReaderPtr& reader, const String& field); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as integers and returns an array of size reader.maxDoc() of the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the integers. + /// @param parser Computes integer for string values. + /// @return The values in the given field for each document. + virtual Collection getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as longs and returns an array of size reader.maxDoc() of the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the longs. + /// @return The values in the given field for each document. + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as longs and returns an array of size reader.maxDoc() of the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the longs. + /// @param parser Computes long for string values. + /// @return The values in the given field for each document. + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as integers and returns an array of size reader.maxDoc() of the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the doubles. + /// @return The values in the given field for each document. + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the terms in + /// field as doubles and returns an array of size reader.maxDoc() of the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the doubles. + /// @param parser Computes double for string values. + /// @return The values in the given field for each document. + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser); + + /// Checks the internal cache for an appropriate entry, and if none are found, reads the term values in + /// field and returns an array of size reader.maxDoc() containing the value each document has in + /// the given field. + /// @param reader Used to get field values. + /// @param field Which field contains the strings. + /// @return The values in the given field for each document. + virtual Collection getStrings(const IndexReaderPtr& reader, const String& field); + + /// Checks the internal cache for an appropriate entry, and if none are found reads the term values in + /// field and returns an array of them in natural order, along with an array telling which element in + /// the term array each document uses. + /// @param reader Used to get field values. + /// @param field Which field contains the strings. + /// @return Array of terms and index into the array for each document. + virtual StringIndexPtr getStringIndex(const IndexReaderPtr& reader, const String& field); + + /// Generates an array of CacheEntry objects representing all items currently in the FieldCache. + virtual Collection getCacheEntries() = 0; + + /// Instructs the FieldCache to forcibly expunge all entries from the underlying caches. This is intended + /// only to be used for test methods as a way to ensure a known base state of the Cache. It should not be + /// relied on for "Cache maintenance" in general application code. + virtual void purgeAllCaches() = 0; + + /// Drops all cache entries associated with this reader. NOTE: this reader must precisely match the reader + /// that the cache entry is keyed on. If you pass a top-level reader, it usually will have no effect as + /// Lucene now caches at the segment reader level. + virtual void purge(const IndexReaderPtr& r) = 0; + + /// If non-null, FieldCacheImpl will warn whenever entries are created that are not sane according to + /// {@link FieldCacheSanityChecker}. + virtual void setInfoStream(const InfoStreamPtr& stream); + + /// @see #setInfoStream + virtual InfoStreamPtr getInfoStream(); +}; + +class LPPAPI CreationPlaceholder : public LuceneObject { +public: + virtual ~CreationPlaceholder(); + LUCENE_CLASS(CreationPlaceholder); + +public: + boost::any value; +}; + +/// Stores term text values and document ordering data. +class LPPAPI StringIndex : public LuceneObject { +public: + StringIndex(Collection values, Collection lookup); + virtual ~StringIndex(); + + LUCENE_CLASS(StringIndex); + +public: + /// All the term values, in natural order. + Collection lookup; + + /// For each document, an index into the lookup array. + Collection order; + +public: + int32_t binarySearchLookup(const String& key); +}; + +/// Marker interface as super-interface to all parsers. It is used to specify a custom parser to {@link +/// SortField#SortField(String, Parser)}. +class LPPAPI Parser : public LuceneObject { +public: + virtual ~Parser(); + LUCENE_CLASS(Parser); +}; + +/// Interface to parse bytes from document fields. +/// @see FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr) +class LPPAPI ByteParser : public Parser { +public: + virtual ~ByteParser(); + LUCENE_CLASS(ByteParser); + +public: + /// Return a single Byte representation of this field's value. + virtual uint8_t parseByte(const String& string); +}; + +/// Interface to parse ints from document fields. +/// @see FieldCache#getInts(IndexReaderPtr, String, IntParserPtr) +class LPPAPI IntParser : public Parser { +public: + virtual ~IntParser(); + LUCENE_CLASS(IntParser); + +public: + /// Return a integer representation of this field's value. + virtual int32_t parseInt(const String& string); +}; + +/// Interface to parse longs from document fields. +/// @see FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr) +class LPPAPI LongParser : public Parser { +public: + virtual ~LongParser(); + LUCENE_CLASS(LongParser); + +public: + /// Return a long representation of this field's value. + virtual int64_t parseLong(const String& string); +}; + +/// Interface to parse doubles from document fields. +/// @see FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr) +class LPPAPI DoubleParser : public Parser { +public: + virtual ~DoubleParser(); + LUCENE_CLASS(DoubleParser); + +public: + /// Return a double representation of this field's value. + virtual double parseDouble(const String& string); +}; + +/// A unique Identifier/Description for each item in the FieldCache. Can be useful for logging/debugging. +class LPPAPI FieldCacheEntry : public LuceneObject { +public: + virtual ~FieldCacheEntry(); + LUCENE_CLASS(FieldCacheEntry); + +public: + virtual LuceneObjectPtr getReaderKey() = 0; + virtual String getFieldName() = 0; + virtual int32_t getCacheType() = 0; + virtual boost::any getCustom() = 0; + virtual boost::any getValue() = 0; + + virtual String toString(); +}; - public: - boost::any value; - }; - - /// Stores term text values and document ordering data. - class LPPAPI StringIndex : public LuceneObject - { - public: - StringIndex(Collection values, Collection lookup); - virtual ~StringIndex(); - - LUCENE_CLASS(StringIndex); - - public: - /// All the term values, in natural order. - Collection lookup; - - /// For each document, an index into the lookup array. - Collection order; - - public: - int32_t binarySearchLookup(const String& key); - }; - - /// Marker interface as super-interface to all parsers. It is used to specify a custom parser to {@link - /// SortField#SortField(String, Parser)}. - class LPPAPI Parser : public LuceneObject - { - public: - virtual ~Parser(); - LUCENE_CLASS(Parser); - }; - - /// Interface to parse bytes from document fields. - /// @see FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr) - class LPPAPI ByteParser : public Parser - { - public: - virtual ~ByteParser(); - LUCENE_CLASS(ByteParser); - - public: - /// Return a single Byte representation of this field's value. - virtual uint8_t parseByte(const String& string); - }; - - /// Interface to parse ints from document fields. - /// @see FieldCache#getInts(IndexReaderPtr, String, IntParserPtr) - class LPPAPI IntParser : public Parser - { - public: - virtual ~IntParser(); - LUCENE_CLASS(IntParser); - - public: - /// Return a integer representation of this field's value. - virtual int32_t parseInt(const String& string); - }; - - /// Interface to parse longs from document fields. - /// @see FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr) - class LPPAPI LongParser : public Parser - { - public: - virtual ~LongParser(); - LUCENE_CLASS(LongParser); - - public: - /// Return a long representation of this field's value. - virtual int64_t parseLong(const String& string); - }; - - /// Interface to parse doubles from document fields. - /// @see FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr) - class LPPAPI DoubleParser : public Parser - { - public: - virtual ~DoubleParser(); - LUCENE_CLASS(DoubleParser); - - public: - /// Return a double representation of this field's value. - virtual double parseDouble(const String& string); - }; - - /// A unique Identifier/Description for each item in the FieldCache. Can be useful for logging/debugging. - class LPPAPI FieldCacheEntry : public LuceneObject - { - public: - virtual ~FieldCacheEntry(); - LUCENE_CLASS(FieldCacheEntry); - - public: - virtual LuceneObjectPtr getReaderKey() = 0; - virtual String getFieldName() = 0; - virtual int32_t getCacheType() = 0; - virtual boost::any getCustom() = 0; - virtual boost::any getValue() = 0; - - virtual String toString(); - }; } #endif diff --git a/include/FieldCacheImpl.h b/include/FieldCacheImpl.h index cfbeb7bf..c58eed09 100644 --- a/include/FieldCacheImpl.h +++ b/include/FieldCacheImpl.h @@ -9,185 +9,176 @@ #include "FieldCache.h" -namespace Lucene -{ - /// The default cache implementation, storing all values in memory. A WeakHashMap is used for storage. - class FieldCacheImpl : public FieldCache, public LuceneObject - { - public: - FieldCacheImpl(); - virtual ~FieldCacheImpl(); +namespace Lucene { - LUCENE_CLASS(FieldCacheImpl); +/// The default cache implementation, storing all values in memory. A WeakHashMap is used for storage. +class FieldCacheImpl : public FieldCache, public LuceneObject { +public: + FieldCacheImpl(); + virtual ~FieldCacheImpl(); - protected: - MapStringCache caches; - InfoStreamPtr infoStream; + LUCENE_CLASS(FieldCacheImpl); - public: - virtual void initialize(); - virtual void purgeAllCaches(); - virtual void purge(const IndexReaderPtr& r); - virtual Collection getCacheEntries(); +protected: + MapStringCache caches; + InfoStreamPtr infoStream; - virtual Collection getBytes(const IndexReaderPtr& reader, const String& field); - virtual Collection getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser); - - virtual Collection getInts(const IndexReaderPtr& reader, const String& field); - virtual Collection getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser); +public: + virtual void initialize(); + virtual void purgeAllCaches(); + virtual void purge(const IndexReaderPtr& r); + virtual Collection getCacheEntries(); - virtual Collection getLongs(const IndexReaderPtr& reader, const String& field); - virtual Collection getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser); + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field); + virtual Collection getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser); - virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field); - virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser); + virtual Collection getInts(const IndexReaderPtr& reader, const String& field); + virtual Collection getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser); - virtual Collection getStrings(const IndexReaderPtr& reader, const String& field); - virtual StringIndexPtr getStringIndex(const IndexReaderPtr& reader, const String& field); - - virtual void setInfoStream(const InfoStreamPtr& stream); - virtual InfoStreamPtr getInfoStream(); - }; - - class Entry : public LuceneObject - { - public: - /// Creates one of these objects for a custom comparator/parser. - Entry(const String& field, const boost::any& custom); - virtual ~Entry(); + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field); + virtual Collection getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser); - LUCENE_CLASS(Entry); - - public: - String field; // which Fieldable - boost::any custom; // which custom comparator or parser + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field); + virtual Collection getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser); - public: - /// Two of these are equal if they reference the same field and type. - virtual bool equals(const LuceneObjectPtr& other); + virtual Collection getStrings(const IndexReaderPtr& reader, const String& field); + virtual StringIndexPtr getStringIndex(const IndexReaderPtr& reader, const String& field); - /// Composes a hashcode based on the field and type. - virtual int32_t hashCode(); - }; - - /// Internal cache. - class Cache : public LuceneObject - { - public: - Cache(const FieldCachePtr& wrapper = FieldCachePtr()); - virtual ~Cache(); - - LUCENE_CLASS(Cache); - - public: - FieldCacheWeakPtr _wrapper; - WeakMapLuceneObjectMapEntryAny readerCache; - - protected: - virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key) = 0; - - public: - /// Remove this reader from the cache, if present. - virtual void purge(const IndexReaderPtr& r); - - virtual boost::any get(const IndexReaderPtr& reader, const EntryPtr& key); - virtual void printNewInsanity(const InfoStreamPtr& infoStream, const boost::any& value); - }; - - class ByteCache : public Cache - { - public: - ByteCache(const FieldCachePtr& wrapper = FieldCachePtr()); - virtual ~ByteCache(); - - LUCENE_CLASS(ByteCache); - - protected: - virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); - }; - - class IntCache : public Cache - { - public: - IntCache(const FieldCachePtr& wrapper = FieldCachePtr()); - virtual ~IntCache(); - - LUCENE_CLASS(IntCache); - - protected: - virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); - }; + virtual void setInfoStream(const InfoStreamPtr& stream); + virtual InfoStreamPtr getInfoStream(); +}; - class LongCache : public Cache - { - public: - LongCache(const FieldCachePtr& wrapper = FieldCachePtr()); - virtual ~LongCache(); - - LUCENE_CLASS(LongCache); - - protected: - virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); - }; +class Entry : public LuceneObject { +public: + /// Creates one of these objects for a custom comparator/parser. + Entry(const String& field, const boost::any& custom); + virtual ~Entry(); + + LUCENE_CLASS(Entry); + +public: + String field; // which Fieldable + boost::any custom; // which custom comparator or parser + +public: + /// Two of these are equal if they reference the same field and type. + virtual bool equals(const LuceneObjectPtr& other); + + /// Composes a hashcode based on the field and type. + virtual int32_t hashCode(); +}; + +/// Internal cache. +class Cache : public LuceneObject { +public: + Cache(const FieldCachePtr& wrapper = FieldCachePtr()); + virtual ~Cache(); + + LUCENE_CLASS(Cache); + +public: + FieldCacheWeakPtr _wrapper; + WeakMapLuceneObjectMapEntryAny readerCache; + +protected: + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key) = 0; + +public: + /// Remove this reader from the cache, if present. + virtual void purge(const IndexReaderPtr& r); + + virtual boost::any get(const IndexReaderPtr& reader, const EntryPtr& key); + virtual void printNewInsanity(const InfoStreamPtr& infoStream, const boost::any& value); +}; + +class ByteCache : public Cache { +public: + ByteCache(const FieldCachePtr& wrapper = FieldCachePtr()); + virtual ~ByteCache(); + + LUCENE_CLASS(ByteCache); + +protected: + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); +}; + +class IntCache : public Cache { +public: + IntCache(const FieldCachePtr& wrapper = FieldCachePtr()); + virtual ~IntCache(); + + LUCENE_CLASS(IntCache); + +protected: + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); +}; + +class LongCache : public Cache { +public: + LongCache(const FieldCachePtr& wrapper = FieldCachePtr()); + virtual ~LongCache(); + + LUCENE_CLASS(LongCache); + +protected: + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); +}; + +class DoubleCache : public Cache { +public: + DoubleCache(const FieldCachePtr& wrapper = FieldCachePtr()); + virtual ~DoubleCache(); + + LUCENE_CLASS(DoubleCache); + +protected: + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); +}; + +class StringCache : public Cache { +public: + StringCache(const FieldCachePtr& wrapper = FieldCachePtr()); + virtual ~StringCache(); + + LUCENE_CLASS(StringCache); + +protected: + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); +}; + +class StringIndexCache : public Cache { +public: + StringIndexCache(const FieldCachePtr& wrapper = FieldCachePtr()); + virtual ~StringIndexCache(); + + LUCENE_CLASS(StringIndexCache); + +protected: + virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); +}; + +class FieldCacheEntryImpl : public FieldCacheEntry { +public: + FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, const boost::any& custom, const boost::any& value); + virtual ~FieldCacheEntryImpl(); + + LUCENE_CLASS(FieldCacheEntryImpl); + +protected: + LuceneObjectPtr readerKey; + String fieldName; + int32_t cacheType; + boost::any custom; + boost::any value; + +public: + virtual LuceneObjectPtr getReaderKey(); + virtual String getFieldName(); + virtual int32_t getCacheType(); + virtual boost::any getCustom(); + virtual boost::any getValue(); +}; - class DoubleCache : public Cache - { - public: - DoubleCache(const FieldCachePtr& wrapper = FieldCachePtr()); - virtual ~DoubleCache(); - - LUCENE_CLASS(DoubleCache); - - protected: - virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); - }; - - class StringCache : public Cache - { - public: - StringCache(const FieldCachePtr& wrapper = FieldCachePtr()); - virtual ~StringCache(); - - LUCENE_CLASS(StringCache); - - protected: - virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); - }; - - class StringIndexCache : public Cache - { - public: - StringIndexCache(const FieldCachePtr& wrapper = FieldCachePtr()); - virtual ~StringIndexCache(); - - LUCENE_CLASS(StringIndexCache); - - protected: - virtual boost::any createValue(const IndexReaderPtr& reader, const EntryPtr& key); - }; - - class FieldCacheEntryImpl : public FieldCacheEntry - { - public: - FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, const boost::any& custom, const boost::any& value); - virtual ~FieldCacheEntryImpl(); - - LUCENE_CLASS(FieldCacheEntryImpl); - - protected: - LuceneObjectPtr readerKey; - String fieldName; - int32_t cacheType; - boost::any custom; - boost::any value; - - public: - virtual LuceneObjectPtr getReaderKey(); - virtual String getFieldName(); - virtual int32_t getCacheType(); - virtual boost::any getCustom(); - virtual boost::any getValue(); - }; } #endif diff --git a/include/FieldCacheRangeFilter.h b/include/FieldCacheRangeFilter.h index abdf4eee..87be89af 100644 --- a/include/FieldCacheRangeFilter.h +++ b/include/FieldCacheRangeFilter.h @@ -10,106 +10,106 @@ #include "Filter.h" #include "FieldCache.h" -namespace Lucene -{ - /// A range filter built on top of a cached single term field (in {@link FieldCache}). - /// - /// FieldCacheRangeFilter builds a single cache for the field the first time it is used. Each subsequent - /// FieldCacheRangeFilter on the same field then reuses this cache, even if the range itself changes. - /// - /// This means that FieldCacheRangeFilter is much faster (sometimes more than 100x as fast) as building a - /// {@link TermRangeFilter}, if using a {@link #newStringRange}. However, if the range never changes it is - /// slower (around 2x as slow) than building a CachingWrapperFilter on top of a single {@link TermRangeFilter}. - /// - /// For numeric data types, this filter may be significantly faster than {@link NumericRangeFilter}. - /// Furthermore, it does not need the numeric values encoded by {@link NumericField}. But it has the problem - /// that it only works with exact one value/document (see below). - /// - /// As with all {@link FieldCache} based functionality, FieldCacheRangeFilter is only valid for fields which - /// exact one term for each document (except for {@link #newStringRange} where 0 terms are also allowed). Due - /// to a restriction of {@link FieldCache}, for numeric ranges all terms that do not have a numeric value, 0 - /// is assumed. - /// - /// Thus it works on dates, prices and other single value fields but will not work on regular text fields. It - /// is preferable to use a NOT_ANALYZED field to ensure that there is only a single term. - /// - /// Do not instantiate this template directly, use one of the static factory methods available, that create a - /// correct instance for different data types supported by {@link FieldCache}. - class LPPAPI FieldCacheRangeFilter : public Filter - { - public: - FieldCacheRangeFilter(const String& field, const ParserPtr& parser, bool includeLower, bool includeUpper); - virtual ~FieldCacheRangeFilter(); - - LUCENE_CLASS(FieldCacheRangeFilter); - - INTERNAL: - String field; - ParserPtr parser; - bool includeLower; - bool includeUpper; - - public: - /// Creates a string range filter using {@link FieldCache#getStringIndex}. This works with all fields containing - /// zero or one term in the field. The range can be half-open by setting one of the values to null. - static FieldCacheRangeFilterPtr newStringRange(const String& field, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String)}. This works with all - /// byte fields containing exactly one numeric term in the field. The range can be half-open by setting one of the - /// values to null. - static FieldCacheRangeFilterPtr newByteRange(const String& field, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr)}. This - /// works with all byte fields containing exactly one numeric term in the field. The range can be half-open by - /// setting one of the values to null. - static FieldCacheRangeFilterPtr newByteRange(const String& field, const ByteParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String)}. This works with all - /// int fields containing exactly one numeric term in the field. The range can be half-open by setting one of the - /// values to null. - static FieldCacheRangeFilterPtr newIntRange(const String& field, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String, IntParserPtr)}. This - /// works with all int fields containing exactly one numeric term in the field. The range can be half-open by - /// setting one of the values to null. - static FieldCacheRangeFilterPtr newIntRange(const String& field, const IntParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String)}. This works with all - /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the - /// values to null. - static FieldCacheRangeFilterPtr newLongRange(const String& field, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr)}. This - /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by - /// setting one of the values to null. - static FieldCacheRangeFilterPtr newLongRange(const String& field, const LongParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String)}. This works with all - /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the - /// values to null. - static FieldCacheRangeFilterPtr newDoubleRange(const String& field, double lowerVal, double upperVal, bool includeLower, bool includeUpper); - - /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr)}. This - /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by - /// setting one of the values to null. - static FieldCacheRangeFilterPtr newDoubleRange(const String& field, const DoubleParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); - - virtual String toString() = 0; - virtual bool equals(const LuceneObjectPtr& other) = 0; - virtual int32_t hashCode() = 0; - - /// Returns the field name for this filter - virtual String getField(); - - /// Returns true if the lower endpoint is inclusive - virtual bool includesLower(); - - /// Returns true if the upper endpoint is inclusive - virtual bool includesUpper(); - - /// Returns the current numeric parser - virtual ParserPtr getParser(); - }; +namespace Lucene { + +/// A range filter built on top of a cached single term field (in {@link FieldCache}). +/// +/// FieldCacheRangeFilter builds a single cache for the field the first time it is used. Each subsequent +/// FieldCacheRangeFilter on the same field then reuses this cache, even if the range itself changes. +/// +/// This means that FieldCacheRangeFilter is much faster (sometimes more than 100x as fast) as building a +/// {@link TermRangeFilter}, if using a {@link #newStringRange}. However, if the range never changes it is +/// slower (around 2x as slow) than building a CachingWrapperFilter on top of a single {@link TermRangeFilter}. +/// +/// For numeric data types, this filter may be significantly faster than {@link NumericRangeFilter}. +/// Furthermore, it does not need the numeric values encoded by {@link NumericField}. But it has the problem +/// that it only works with exact one value/document (see below). +/// +/// As with all {@link FieldCache} based functionality, FieldCacheRangeFilter is only valid for fields which +/// exact one term for each document (except for {@link #newStringRange} where 0 terms are also allowed). Due +/// to a restriction of {@link FieldCache}, for numeric ranges all terms that do not have a numeric value, 0 +/// is assumed. +/// +/// Thus it works on dates, prices and other single value fields but will not work on regular text fields. It +/// is preferable to use a NOT_ANALYZED field to ensure that there is only a single term. +/// +/// Do not instantiate this template directly, use one of the static factory methods available, that create a +/// correct instance for different data types supported by {@link FieldCache}. +class LPPAPI FieldCacheRangeFilter : public Filter { +public: + FieldCacheRangeFilter(const String& field, const ParserPtr& parser, bool includeLower, bool includeUpper); + virtual ~FieldCacheRangeFilter(); + + LUCENE_CLASS(FieldCacheRangeFilter); + +INTERNAL: + String field; + ParserPtr parser; + bool includeLower; + bool includeUpper; + +public: + /// Creates a string range filter using {@link FieldCache#getStringIndex}. This works with all fields containing + /// zero or one term in the field. The range can be half-open by setting one of the values to null. + static FieldCacheRangeFilterPtr newStringRange(const String& field, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String)}. This works with all + /// byte fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// values to null. + static FieldCacheRangeFilterPtr newByteRange(const String& field, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getBytes(IndexReaderPtr, String, ByteParserPtr)}. This + /// works with all byte fields containing exactly one numeric term in the field. The range can be half-open by + /// setting one of the values to null. + static FieldCacheRangeFilterPtr newByteRange(const String& field, const ByteParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String)}. This works with all + /// int fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// values to null. + static FieldCacheRangeFilterPtr newIntRange(const String& field, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getInts(IndexReaderPtr, String, IntParserPtr)}. This + /// works with all int fields containing exactly one numeric term in the field. The range can be half-open by + /// setting one of the values to null. + static FieldCacheRangeFilterPtr newIntRange(const String& field, const IntParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String)}. This works with all + /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// values to null. + static FieldCacheRangeFilterPtr newLongRange(const String& field, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getLongs(IndexReaderPtr, String, LongParserPtr)}. This + /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by + /// setting one of the values to null. + static FieldCacheRangeFilterPtr newLongRange(const String& field, const LongParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String)}. This works with all + /// long fields containing exactly one numeric term in the field. The range can be half-open by setting one of the + /// values to null. + static FieldCacheRangeFilterPtr newDoubleRange(const String& field, double lowerVal, double upperVal, bool includeLower, bool includeUpper); + + /// Creates a numeric range filter using {@link FieldCache#getDoubles(IndexReaderPtr, String, DoubleParserPtr)}. This + /// works with all long fields containing exactly one numeric term in the field. The range can be half-open by + /// setting one of the values to null. + static FieldCacheRangeFilterPtr newDoubleRange(const String& field, const DoubleParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); + + virtual String toString() = 0; + virtual bool equals(const LuceneObjectPtr& other) = 0; + virtual int32_t hashCode() = 0; + + /// Returns the field name for this filter + virtual String getField(); + + /// Returns true if the lower endpoint is inclusive + virtual bool includesLower(); + + /// Returns true if the upper endpoint is inclusive + virtual bool includesUpper(); + + /// Returns the current numeric parser + virtual ParserPtr getParser(); +}; + } #endif diff --git a/include/FieldCacheSanityChecker.h b/include/FieldCacheSanityChecker.h index 97276c7c..dc2c2eea 100644 --- a/include/FieldCacheSanityChecker.h +++ b/include/FieldCacheSanityChecker.h @@ -10,117 +10,115 @@ #include "LuceneObject.h" #include "MapOfSets.h" -namespace Lucene -{ - /// Provides methods for sanity checking that entries in the FieldCache are not wasteful or inconsistent. - /// - /// Lucene 2.9 Introduced numerous enhancements into how the FieldCache is used by the low levels of Lucene - /// searching (for Sorting and ValueSourceQueries) to improve both the speed for Sorting, as well as reopening - /// of IndexReaders. But these changes have shifted the usage of FieldCache from "top level" IndexReaders - /// (frequently a MultiReader or DirectoryReader) down to the leaf level SegmentReaders. As a result, - /// existing applications that directly access the FieldCache may find RAM usage increase significantly when - /// upgrading to 2.9 or later. This class provides an API for these applications (or their Unit tests) to - /// check at run time if the FieldCache contains "insane" usages of the FieldCache. - /// - /// @see FieldCache - /// @see FieldCacheSanityChecker.Insanity - /// @see FieldCacheSanityChecker.InsanityType - class LPPAPI FieldCacheSanityChecker : public LuceneObject - { - public: - FieldCacheSanityChecker(); - virtual ~FieldCacheSanityChecker(); - - LUCENE_CLASS(FieldCacheSanityChecker); - - public: - typedef MapOfSets< int32_t, boost::hash, std::equal_to, FieldCacheEntryPtr, luceneHash, luceneEquals > MapSetIntFieldCacheEntry; - typedef MapOfSets< ReaderFieldPtr, luceneHash, luceneEquals, int32_t, boost::hash, std::equal_to > MapSetReaderFieldInt; - typedef MapOfSets< ReaderFieldPtr, luceneHash, luceneEquals, ReaderFieldPtr, luceneHash, luceneEquals > MapSetReaderFieldReaderField; - - /// An Enumeration of the different types of "insane" behaviour that may be detected in a FieldCache. - enum InsanityType - { - /// Indicates an overlap in cache usage on a given field in sub/super readers. - SUBREADER, - - /// Indicates entries have the same reader+fieldname but different cached values. This can happen - /// if different datatypes, or parsers are used -- and while it's not necessarily a bug it's - /// typically an indication of a possible problem. - /// - /// NOTE: Only the reader, fieldname, and cached value are actually tested -- if two cache entries - /// have different parsers or datatypes but the cached values are the same Object (== not just equal()) - /// this method does not consider that a red flag. This allows for subtle variations in the way a - /// Parser is specified (null vs DEFAULT_LONG_PARSER, etc...) - VALUEMISMATCH, - - /// Indicates an expected bit of "insanity". This may be useful for clients that wish to preserve/log - /// information about insane usage but indicate that it was expected. - EXPECTED - }; - - /// Quick and dirty convenience method - /// @see #check - static Collection checkSanity(const FieldCachePtr& cache); - - /// Quick and dirty convenience method that instantiates an instance with "good defaults" and uses it to - /// test the CacheEntrys. - /// @see #check - static Collection checkSanity(Collection cacheEntries); - - /// Tests a CacheEntry[] for indication of "insane" cache usage. - /// NOTE: FieldCache CreationPlaceholder objects are ignored. - Collection check(Collection cacheEntries); - - protected: - /// Internal helper method used by check that iterates over valMismatchKeys and generates a Collection of - /// Insanity instances accordingly. The MapOfSets are used to populate the Insanity objects. - /// @see InsanityType#VALUEMISMATCH - Collection checkValueMismatch(MapSetIntFieldCacheEntry valIdToItems, - MapSetReaderFieldInt readerFieldToValIds, - SetReaderField valMismatchKeys); - - /// Internal helper method used by check that iterates over the keys of readerFieldToValIds and generates a - /// Collection of Insanity instances whenever two (or more) ReaderField instances are found that have an - /// ancestry relationships. - /// @see InsanityType#SUBREADER - Collection checkSubreaders(MapSetIntFieldCacheEntry valIdToItems, - MapSetReaderFieldInt readerFieldToValIds); - - /// Checks if the seed is an IndexReader, and if so will walk the hierarchy of subReaders building up a - /// list of the objects returned by obj.getFieldCacheKey() - Collection getAllDecendentReaderKeys(const LuceneObjectPtr& seed); +namespace Lucene { + +/// Provides methods for sanity checking that entries in the FieldCache are not wasteful or inconsistent. +/// +/// Lucene 2.9 Introduced numerous enhancements into how the FieldCache is used by the low levels of Lucene +/// searching (for Sorting and ValueSourceQueries) to improve both the speed for Sorting, as well as reopening +/// of IndexReaders. But these changes have shifted the usage of FieldCache from "top level" IndexReaders +/// (frequently a MultiReader or DirectoryReader) down to the leaf level SegmentReaders. As a result, +/// existing applications that directly access the FieldCache may find RAM usage increase significantly when +/// upgrading to 2.9 or later. This class provides an API for these applications (or their Unit tests) to +/// check at run time if the FieldCache contains "insane" usages of the FieldCache. +/// +/// @see FieldCache +/// @see FieldCacheSanityChecker.Insanity +/// @see FieldCacheSanityChecker.InsanityType +class LPPAPI FieldCacheSanityChecker : public LuceneObject { +public: + FieldCacheSanityChecker(); + virtual ~FieldCacheSanityChecker(); + + LUCENE_CLASS(FieldCacheSanityChecker); + +public: + typedef MapOfSets< int32_t, boost::hash, std::equal_to, FieldCacheEntryPtr, luceneHash, luceneEquals > MapSetIntFieldCacheEntry; + typedef MapOfSets< ReaderFieldPtr, luceneHash, luceneEquals, int32_t, boost::hash, std::equal_to > MapSetReaderFieldInt; + typedef MapOfSets< ReaderFieldPtr, luceneHash, luceneEquals, ReaderFieldPtr, luceneHash, luceneEquals > MapSetReaderFieldReaderField; + + /// An Enumeration of the different types of "insane" behaviour that may be detected in a FieldCache. + enum InsanityType { + /// Indicates an overlap in cache usage on a given field in sub/super readers. + SUBREADER, + + /// Indicates entries have the same reader+fieldname but different cached values. This can happen + /// if different datatypes, or parsers are used -- and while it's not necessarily a bug it's + /// typically an indication of a possible problem. + /// + /// NOTE: Only the reader, fieldname, and cached value are actually tested -- if two cache entries + /// have different parsers or datatypes but the cached values are the same Object (== not just equal()) + /// this method does not consider that a red flag. This allows for subtle variations in the way a + /// Parser is specified (null vs DEFAULT_LONG_PARSER, etc...) + VALUEMISMATCH, + + /// Indicates an expected bit of "insanity". This may be useful for clients that wish to preserve/log + /// information about insane usage but indicate that it was expected. + EXPECTED }; - /// Simple container for a collection of related CacheEntry objects that in conjunction with each other - /// represent some "insane" usage of the FieldCache. - class LPPAPI Insanity : public LuceneObject - { - public: - Insanity(FieldCacheSanityChecker::InsanityType type, const String& msg, Collection entries); - virtual ~Insanity(); + /// Quick and dirty convenience method + /// @see #check + static Collection checkSanity(const FieldCachePtr& cache); + + /// Quick and dirty convenience method that instantiates an instance with "good defaults" and uses it to + /// test the CacheEntrys. + /// @see #check + static Collection checkSanity(Collection cacheEntries); + + /// Tests a CacheEntry[] for indication of "insane" cache usage. + /// NOTE: FieldCache CreationPlaceholder objects are ignored. + Collection check(Collection cacheEntries); + +protected: + /// Internal helper method used by check that iterates over valMismatchKeys and generates a Collection of + /// Insanity instances accordingly. The MapOfSets are used to populate the Insanity objects. + /// @see InsanityType#VALUEMISMATCH + Collection checkValueMismatch(MapSetIntFieldCacheEntry valIdToItems, + MapSetReaderFieldInt readerFieldToValIds, + SetReaderField valMismatchKeys); + + /// Internal helper method used by check that iterates over the keys of readerFieldToValIds and generates a + /// Collection of Insanity instances whenever two (or more) ReaderField instances are found that have an + /// ancestry relationships. + /// @see InsanityType#SUBREADER + Collection checkSubreaders(MapSetIntFieldCacheEntry valIdToItems, + MapSetReaderFieldInt readerFieldToValIds); + + /// Checks if the seed is an IndexReader, and if so will walk the hierarchy of subReaders building up a + /// list of the objects returned by obj.getFieldCacheKey() + Collection getAllDecendentReaderKeys(const LuceneObjectPtr& seed); +}; + +/// Simple container for a collection of related CacheEntry objects that in conjunction with each other +/// represent some "insane" usage of the FieldCache. +class LPPAPI Insanity : public LuceneObject { +public: + Insanity(FieldCacheSanityChecker::InsanityType type, const String& msg, Collection entries); + virtual ~Insanity(); + + LUCENE_CLASS(Insanity); + +protected: + FieldCacheSanityChecker::InsanityType type; + String msg; + Collection entries; + +public: + /// Type of insane behavior this object represents + FieldCacheSanityChecker::InsanityType getType(); + + /// Description of the insane behaviour + String getMsg(); + + /// CacheEntry objects which suggest a problem + Collection getCacheEntries(); + + /// Multi-Line representation of this Insanity object, starting with the Type and Msg, followed by each + /// CacheEntry.toString() on it's own line prefaced by a tab character + virtual String toString(); +}; - LUCENE_CLASS(Insanity); - - protected: - FieldCacheSanityChecker::InsanityType type; - String msg; - Collection entries; - - public: - /// Type of insane behavior this object represents - FieldCacheSanityChecker::InsanityType getType(); - - /// Description of the insane behaviour - String getMsg(); - - /// CacheEntry objects which suggest a problem - Collection getCacheEntries(); - - /// Multi-Line representation of this Insanity object, starting with the Type and Msg, followed by each - /// CacheEntry.toString() on it's own line prefaced by a tab character - virtual String toString(); - }; } #endif diff --git a/include/FieldCacheSource.h b/include/FieldCacheSource.h index 36a18a5b..18806420 100644 --- a/include/FieldCacheSource.h +++ b/include/FieldCacheSource.h @@ -9,54 +9,54 @@ #include "ValueSource.h" -namespace Lucene -{ - /// A base class for ValueSource implementations that retrieve values for a single field from the - /// {@link FieldCache}. - /// - /// Fields used herein must be indexed (doesn't matter if these fields are stored or not). - /// - /// It is assumed that each such indexed field is untokenized, or at least has a single token in a document. - /// For documents with multiple tokens of the same field, behavior is undefined (It is likely that current - /// code would use the value of one of these tokens, but this is not guaranteed). - /// - /// Document with no tokens in this field are assigned the Zero value. - /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite - /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. - class LPPAPI FieldCacheSource : public ValueSource - { - public: - /// Create a cached field source for the input field. - FieldCacheSource(const String& field); - virtual ~FieldCacheSource(); - - LUCENE_CLASS(FieldCacheSource); - - protected: - String field; - - public: - virtual DocValuesPtr getValues(const IndexReaderPtr& reader); - virtual String description(); - - /// Return cached DocValues for input field and reader. - /// @param cache FieldCache so that values of a field are loaded once per reader (RAM allowing) - /// @param field Field for which values are required. - /// @see ValueSource - virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) = 0; - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - /// Check if equals to another {@link FieldCacheSource}, already knowing that cache and field are equal. - virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other) = 0; - - /// Return a hash code of a {@link FieldCacheSource}, without the hash-codes of the field and the cache - /// (those are taken care of elsewhere). - virtual int32_t cachedFieldSourceHashCode() = 0; - }; +namespace Lucene { + +/// A base class for ValueSource implementations that retrieve values for a single field from the +/// {@link FieldCache}. +/// +/// Fields used herein must be indexed (doesn't matter if these fields are stored or not). +/// +/// It is assumed that each such indexed field is untokenized, or at least has a single token in a document. +/// For documents with multiple tokens of the same field, behavior is undefined (It is likely that current +/// code would use the value of one of these tokens, but this is not guaranteed). +/// +/// Document with no tokens in this field are assigned the Zero value. +/// +/// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite +/// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's +/// best to switch your application to pass only atomic (single segment) readers to this API. +class LPPAPI FieldCacheSource : public ValueSource { +public: + /// Create a cached field source for the input field. + FieldCacheSource(const String& field); + virtual ~FieldCacheSource(); + + LUCENE_CLASS(FieldCacheSource); + +protected: + String field; + +public: + virtual DocValuesPtr getValues(const IndexReaderPtr& reader); + virtual String description(); + + /// Return cached DocValues for input field and reader. + /// @param cache FieldCache so that values of a field are loaded once per reader (RAM allowing) + /// @param field Field for which values are required. + /// @see ValueSource + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) = 0; + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + /// Check if equals to another {@link FieldCacheSource}, already knowing that cache and field are equal. + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other) = 0; + + /// Return a hash code of a {@link FieldCacheSource}, without the hash-codes of the field and the cache + /// (those are taken care of elsewhere). + virtual int32_t cachedFieldSourceHashCode() = 0; +}; + } #endif diff --git a/include/FieldCacheTermsFilter.h b/include/FieldCacheTermsFilter.h index e61eb549..9b51cea2 100644 --- a/include/FieldCacheTermsFilter.h +++ b/include/FieldCacheTermsFilter.h @@ -9,57 +9,57 @@ #include "Filter.h" -namespace Lucene -{ - /// A {@link Filter} that only accepts documents whose single term value in the specified field is contained - /// in the provided set of allowed terms. - /// - /// This is the same functionality as TermsFilter (from contrib/queries), except this filter requires that the - /// field contains only a single term for all documents. Because of drastically different implementations, - /// they also have different performance characteristics, as described below. - /// - /// The first invocation of this filter on a given field will be slower, since a {@link StringIndex} must be - /// created. Subsequent invocations using the same field will re-use this cache. However, as with all - /// functionality based on {@link FieldCache}, persistent RAM is consumed to hold the cache, and is not freed - /// until the {@link IndexReader} is closed. In contrast, TermsFilter has no persistent RAM consumption. - /// - /// With each search, this filter translates the specified set of Terms into a private {@link OpenBitSet} keyed - /// by term number per unique {@link IndexReader} (normally one reader per segment). Then, during matching, - /// the term number for each docID is retrieved from the cache and then checked for inclusion using the {@link - /// OpenBitSet}. Since all testing is done using RAM resident data structures, performance should be very fast, - /// most likely fast enough to not require further caching of the DocIdSet for each possible combination of - /// terms. However, because docIDs are simply scanned linearly, an index with a great many small documents may - /// find this linear scan too costly. - /// - /// In contrast, TermsFilter builds up an {@link OpenBitSet}, keyed by docID, every time it's created, by - /// enumerating through all matching docs using {@link TermDocs} to seek and scan through each term's docID list. - /// While there is no linear scan of all docIDs, besides the allocation of the underlying array in the {@link - /// OpenBitSet}, this approach requires a number of "disk seeks" in proportion to the number of terms, which can - /// be exceptionally costly when there are cache misses in the OS's IO cache. - /// - /// Generally, this filter will be slower on the first invocation for a given field, but subsequent invocations, - /// even if you change the allowed set of Terms, should be faster than TermsFilter, especially as the number of - /// Terms being matched increases. If you are matching only a very small number of terms, and those terms in - /// turn match a very small number of documents, TermsFilter may perform faster. - /// - /// Which filter is best is very application dependent. - class LPPAPI FieldCacheTermsFilter : public Filter - { - public: - FieldCacheTermsFilter(const String& field, Collection terms); - virtual ~FieldCacheTermsFilter(); +namespace Lucene { - LUCENE_CLASS(FieldCacheTermsFilter); +/// A {@link Filter} that only accepts documents whose single term value in the specified field is contained +/// in the provided set of allowed terms. +/// +/// This is the same functionality as TermsFilter (from contrib/queries), except this filter requires that the +/// field contains only a single term for all documents. Because of drastically different implementations, +/// they also have different performance characteristics, as described below. +/// +/// The first invocation of this filter on a given field will be slower, since a {@link StringIndex} must be +/// created. Subsequent invocations using the same field will re-use this cache. However, as with all +/// functionality based on {@link FieldCache}, persistent RAM is consumed to hold the cache, and is not freed +/// until the {@link IndexReader} is closed. In contrast, TermsFilter has no persistent RAM consumption. +/// +/// With each search, this filter translates the specified set of Terms into a private {@link OpenBitSet} keyed +/// by term number per unique {@link IndexReader} (normally one reader per segment). Then, during matching, +/// the term number for each docID is retrieved from the cache and then checked for inclusion using the {@link +/// OpenBitSet}. Since all testing is done using RAM resident data structures, performance should be very fast, +/// most likely fast enough to not require further caching of the DocIdSet for each possible combination of +/// terms. However, because docIDs are simply scanned linearly, an index with a great many small documents may +/// find this linear scan too costly. +/// +/// In contrast, TermsFilter builds up an {@link OpenBitSet}, keyed by docID, every time it's created, by +/// enumerating through all matching docs using {@link TermDocs} to seek and scan through each term's docID list. +/// While there is no linear scan of all docIDs, besides the allocation of the underlying array in the {@link +/// OpenBitSet}, this approach requires a number of "disk seeks" in proportion to the number of terms, which can +/// be exceptionally costly when there are cache misses in the OS's IO cache. +/// +/// Generally, this filter will be slower on the first invocation for a given field, but subsequent invocations, +/// even if you change the allowed set of Terms, should be faster than TermsFilter, especially as the number of +/// Terms being matched increases. If you are matching only a very small number of terms, and those terms in +/// turn match a very small number of documents, TermsFilter may perform faster. +/// +/// Which filter is best is very application dependent. +class LPPAPI FieldCacheTermsFilter : public Filter { +public: + FieldCacheTermsFilter(const String& field, Collection terms); + virtual ~FieldCacheTermsFilter(); - protected: - String field; - Collection terms; + LUCENE_CLASS(FieldCacheTermsFilter); - public: - FieldCachePtr getFieldCache(); +protected: + String field; + Collection terms; + +public: + FieldCachePtr getFieldCache(); + + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); +}; - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); - }; } #endif diff --git a/include/FieldComparator.h b/include/FieldComparator.h index a058104e..a276eb38 100644 --- a/include/FieldComparator.h +++ b/include/FieldComparator.h @@ -9,340 +9,323 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A FieldComparator compares hits so as to determine their sort order when collecting the top results with - /// {@link TopFieldCollector}. The concrete public FieldComparator classes here correspond to the SortField types. +namespace Lucene { + +/// A FieldComparator compares hits so as to determine their sort order when collecting the top results with +/// {@link TopFieldCollector}. The concrete public FieldComparator classes here correspond to the SortField types. +/// +/// This API is designed to achieve high performance sorting, by exposing a tight interaction with {@link +/// FieldValueHitQueue} as it visits hits. Whenever a hit is competitive, it's enrolled into a virtual slot, +/// which is an int ranging from 0 to numHits-1. The {@link FieldComparator} is made aware of segment transitions +/// during searching in case any internal state it's tracking needs to be recomputed during these transitions. +/// +/// A comparator must define these functions: +///
        +///
      • {@link #compare} Compare a hit at 'slot a' with hit 'slot b'. +/// +///
      • {@link #setBottom} This method is called by {@link FieldValueHitQueue} to notify the FieldComparator of +/// the current weakest ("bottom") slot. Note that this slot may not hold the weakest value according to your +/// comparator, in cases where your comparator is not the primary one (ie, is only used to break ties from the +/// comparators before it). +/// +///
      • {@link #compareBottom} Compare a new hit (docID) against the "weakest" (bottom) entry in the queue. +/// +///
      • {@link #copy} Installs a new hit into the priority queue. The {@link FieldValueHitQueue} calls this +/// method when a new hit is competitive. +/// +///
      • {@link #setNextReader} Invoked when the search is switching to the next segment. You may need to update +/// internal state of the comparator, for example retrieving new values from the {@link FieldCache}. +/// +///
      • {@link #value} Return the sort value stored in the specified slot. This is only called at the end of +/// the search, in order to populate {@link FieldDoc#fields} when returning the top results. +///
      +class LPPAPI FieldComparator : public LuceneObject { +public: + virtual ~FieldComparator(); + LUCENE_CLASS(FieldComparator); + +public: + /// Compare hit at slot1 with hit at slot2. + /// @param slot1 first slot to compare + /// @param slot2 second slot to compare + /// @return any N < 0 if slot2's value is sorted after slot1, any N > 0 if the slot2's value is sorted + /// before slot1 and 0 if they are equal + virtual int32_t compare(int32_t slot1, int32_t slot2) = 0; + + /// Set the bottom slot, ie the "weakest" (sorted last) entry in the queue. When {@link #compareBottom} + /// is called, you should compare against this slot. This will always be called before {@link #compareBottom}. + /// @param slot the currently weakest (sorted last) slot in the queue + virtual void setBottom(int32_t slot) = 0; + + /// Compare the bottom of the queue with doc. This will only invoked after setBottom has been called. + /// This should return the same result as {@link #compare(int,int)}} as if bottom were slot1 and the new + /// document were slot 2. /// - /// This API is designed to achieve high performance sorting, by exposing a tight interaction with {@link - /// FieldValueHitQueue} as it visits hits. Whenever a hit is competitive, it's enrolled into a virtual slot, - /// which is an int ranging from 0 to numHits-1. The {@link FieldComparator} is made aware of segment transitions - /// during searching in case any internal state it's tracking needs to be recomputed during these transitions. + /// For a search that hits many results, this method will be the hotspot (invoked by far the most frequently). /// - /// A comparator must define these functions: - ///
        - ///
      • {@link #compare} Compare a hit at 'slot a' with hit 'slot b'. + /// @param doc that was hit + /// @return any N < 0 if the doc's value is sorted after the bottom entry (not competitive), any N > 0 if + /// the doc's value is sorted before the bottom entry and 0 if they are equal. + virtual int32_t compareBottom(int32_t doc) = 0; + + /// This method is called when a new hit is competitive. You should copy any state associated with this + /// document that will be required for future comparisons, into the specified slot. + /// @param slot which slot to copy the hit to + /// @param doc docID relative to current reader + virtual void copy(int32_t slot, int32_t doc) = 0; + + /// Set a new Reader. All doc correspond to the current Reader. /// - ///
      • {@link #setBottom} This method is called by {@link FieldValueHitQueue} to notify the FieldComparator of - /// the current weakest ("bottom") slot. Note that this slot may not hold the weakest value according to your - /// comparator, in cases where your comparator is not the primary one (ie, is only used to break ties from the - /// comparators before it). - /// - ///
      • {@link #compareBottom} Compare a new hit (docID) against the "weakest" (bottom) entry in the queue. - /// - ///
      • {@link #copy} Installs a new hit into the priority queue. The {@link FieldValueHitQueue} calls this - /// method when a new hit is competitive. - /// - ///
      • {@link #setNextReader} Invoked when the search is switching to the next segment. You may need to update - /// internal state of the comparator, for example retrieving new values from the {@link FieldCache}. - /// - ///
      • {@link #value} Return the sort value stored in the specified slot. This is only called at the end of - /// the search, in order to populate {@link FieldDoc#fields} when returning the top results. - ///
      - class LPPAPI FieldComparator : public LuceneObject - { - public: - virtual ~FieldComparator(); - LUCENE_CLASS(FieldComparator); - - public: - /// Compare hit at slot1 with hit at slot2. - /// @param slot1 first slot to compare - /// @param slot2 second slot to compare - /// @return any N < 0 if slot2's value is sorted after slot1, any N > 0 if the slot2's value is sorted - /// before slot1 and 0 if they are equal - virtual int32_t compare(int32_t slot1, int32_t slot2) = 0; - - /// Set the bottom slot, ie the "weakest" (sorted last) entry in the queue. When {@link #compareBottom} - /// is called, you should compare against this slot. This will always be called before {@link #compareBottom}. - /// @param slot the currently weakest (sorted last) slot in the queue - virtual void setBottom(int32_t slot) = 0; - - /// Compare the bottom of the queue with doc. This will only invoked after setBottom has been called. - /// This should return the same result as {@link #compare(int,int)}} as if bottom were slot1 and the new - /// document were slot 2. - /// - /// For a search that hits many results, this method will be the hotspot (invoked by far the most frequently). - /// - /// @param doc that was hit - /// @return any N < 0 if the doc's value is sorted after the bottom entry (not competitive), any N > 0 if - /// the doc's value is sorted before the bottom entry and 0 if they are equal. - virtual int32_t compareBottom(int32_t doc) = 0; - - /// This method is called when a new hit is competitive. You should copy any state associated with this - /// document that will be required for future comparisons, into the specified slot. - /// @param slot which slot to copy the hit to - /// @param doc docID relative to current reader - virtual void copy(int32_t slot, int32_t doc) = 0; - - /// Set a new Reader. All doc correspond to the current Reader. - /// - /// @param reader current reader - /// @param docBase docBase of this reader - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) = 0; - - /// Sets the Scorer to use in case a document's score is needed. - /// @param scorer Scorer instance that you should use to obtain the current hit's score, if necessary. - virtual void setScorer(const ScorerPtr& scorer); - - /// Return the actual value in the slot. - /// @param slot the value - /// @return value in this slot upgraded to ComparableValue - virtual ComparableValue value(int32_t slot) = 0; - }; - - template - class NumericComparator : public FieldComparator - { - public: - NumericComparator(int32_t numHits, const String& field = EmptyString) - { - this->values = Collection::newInstance(numHits); - this->field = field; - this->bottom = 0; - } - - virtual ~NumericComparator() - { - } - - protected: - Collection values; - Collection currentReaderValues; - String field; - TYPE bottom; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2) - { - return (int32_t)(values[slot1] - values[slot2]); - } - - virtual int32_t compareBottom(int32_t doc) - { - return (int32_t)(bottom - currentReaderValues[doc]); - } - - virtual void copy(int32_t slot, int32_t doc) - { - values[slot] = currentReaderValues[doc]; - } - - virtual void setBottom(int32_t slot) - { - bottom = values[slot]; - } - - virtual ComparableValue value(int32_t slot) - { - return ComparableValue(values[slot]); - } - }; - - /// Parses field's values as byte (using {@link FieldCache#getBytes} and sorts by ascending value. - class LPPAPI ByteComparator : public NumericComparator - { - public: - ByteComparator(int32_t numHits, const String& field, const ParserPtr& parser); - virtual ~ByteComparator(); - - LUCENE_CLASS(ByteComparator); - - protected: - ByteParserPtr parser; - - public: - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - }; - - /// Sorts by ascending docID - class LPPAPI DocComparator : public NumericComparator - { - public: - DocComparator(int32_t numHits); - virtual ~DocComparator(); - - LUCENE_CLASS(DocComparator); - - protected: - int32_t docBase; - - public: - virtual int32_t compareBottom(int32_t doc); - virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - }; - - /// Parses field's values as double (using {@link FieldCache#getDoubles} and sorts by ascending value - class LPPAPI DoubleComparator : public NumericComparator - { - public: - DoubleComparator(int32_t numHits, const String& field, const ParserPtr& parser); - virtual ~DoubleComparator(); - - LUCENE_CLASS(DoubleComparator); - - protected: - DoubleParserPtr parser; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2); - virtual int32_t compareBottom(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - }; - - /// Parses field's values as int (using {@link FieldCache#getInts} and sorts by ascending value - class LPPAPI IntComparator : public NumericComparator - { - public: - IntComparator(int32_t numHits, const String& field, const ParserPtr& parser); - virtual ~IntComparator(); - - LUCENE_CLASS(IntComparator); - - protected: - IntParserPtr parser; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2); - virtual int32_t compareBottom(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - }; - - /// Parses field's values as long (using {@link FieldCache#getLongs} and sorts by ascending value - class LPPAPI LongComparator : public NumericComparator - { - public: - LongComparator(int32_t numHits, const String& field, const ParserPtr& parser); - virtual ~LongComparator(); - - LUCENE_CLASS(LongComparator); - - protected: - LongParserPtr parser; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2); - virtual int32_t compareBottom(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - }; - - /// Sorts by descending relevance. NOTE: if you are sorting only by descending relevance and then secondarily - /// by ascending docID, performance is faster using {@link TopScoreDocCollector} directly (which {@link - /// IndexSearcher#search} uses when no {@link Sort} is specified). - class LPPAPI RelevanceComparator : public NumericComparator - { - public: - RelevanceComparator(int32_t numHits); - virtual ~RelevanceComparator(); - - LUCENE_CLASS(RelevanceComparator); - - protected: - ScorerPtr scorer; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2); - virtual int32_t compareBottom(int32_t doc); - virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setScorer(const ScorerPtr& scorer); - }; - - /// Sorts by a field's value using the Collator for a given Locale. - class LPPAPI StringComparatorLocale : public FieldComparator - { - public: - StringComparatorLocale(int32_t numHits, const String& field, const std::locale& locale); - virtual ~StringComparatorLocale(); - - LUCENE_CLASS(StringComparatorLocale); - - protected: - Collection values; - Collection currentReaderValues; - String field; - CollatorPtr collator; - String bottom; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2); - virtual int32_t compareBottom(int32_t doc); - virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setBottom(int32_t slot); - virtual ComparableValue value(int32_t slot); - }; - - /// Sorts by field's natural String sort order, using ordinals. This is functionally equivalent to {@link - /// StringValComparator}, but it first resolves the string to their relative ordinal positions (using the - /// index returned by {@link FieldCache#getStringIndex}), and does most comparisons using the ordinals. - /// For medium to large results, this comparator will be much faster than {@link StringValComparator}. For - /// very small result sets it may be slower. - class LPPAPI StringOrdValComparator : public FieldComparator - { - public: - StringOrdValComparator(int32_t numHits, const String& field, int32_t sortPos, bool reversed); - virtual ~StringOrdValComparator(); - - LUCENE_CLASS(StringOrdValComparator); - - protected: - Collection ords; - Collection values; - Collection readerGen; - - int32_t currentReaderGen; - Collection lookup; - Collection order; - String field; - - int32_t bottomSlot; - int32_t bottomOrd; - String bottomValue; - bool reversed; - int32_t sortPos; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2); - virtual int32_t compareBottom(int32_t doc); - virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setBottom(int32_t slot); - virtual ComparableValue value(int32_t slot); - virtual Collection getValues(); - virtual int32_t getBottomSlot(); - virtual String getField(); - - protected: - void convert(int32_t slot); - int32_t binarySearch(Collection lookup, const String& key, int32_t low, int32_t high); - }; - - /// Sorts by field's natural String sort order. All comparisons are done using String.compare, which is - /// slow for medium to large result sets but possibly very fast for very small results sets. - class LPPAPI StringValComparator : public FieldComparator - { - public: - StringValComparator(int32_t numHits, const String& field); - virtual ~StringValComparator(); - - LUCENE_CLASS(StringOrdValComparator); - - protected: - Collection values; - Collection currentReaderValues; - String field; - String bottom; - - public: - virtual int32_t compare(int32_t slot1, int32_t slot2); - virtual int32_t compareBottom(int32_t doc); - virtual void copy(int32_t slot, int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setBottom(int32_t slot); - virtual ComparableValue value(int32_t slot); - }; + /// @param reader current reader + /// @param docBase docBase of this reader + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) = 0; + + /// Sets the Scorer to use in case a document's score is needed. + /// @param scorer Scorer instance that you should use to obtain the current hit's score, if necessary. + virtual void setScorer(const ScorerPtr& scorer); + + /// Return the actual value in the slot. + /// @param slot the value + /// @return value in this slot upgraded to ComparableValue + virtual ComparableValue value(int32_t slot) = 0; +}; + +template +class NumericComparator : public FieldComparator { +public: + NumericComparator(int32_t numHits, const String& field = EmptyString) { + this->values = Collection::newInstance(numHits); + this->field = field; + this->bottom = 0; + } + + virtual ~NumericComparator() { + } + +protected: + Collection values; + Collection currentReaderValues; + String field; + TYPE bottom; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2) { + return (int32_t)(values[slot1] - values[slot2]); + } + + virtual int32_t compareBottom(int32_t doc) { + return (int32_t)(bottom - currentReaderValues[doc]); + } + + virtual void copy(int32_t slot, int32_t doc) { + values[slot] = currentReaderValues[doc]; + } + + virtual void setBottom(int32_t slot) { + bottom = values[slot]; + } + + virtual ComparableValue value(int32_t slot) { + return ComparableValue(values[slot]); + } +}; + +/// Parses field's values as byte (using {@link FieldCache#getBytes} and sorts by ascending value. +class LPPAPI ByteComparator : public NumericComparator { +public: + ByteComparator(int32_t numHits, const String& field, const ParserPtr& parser); + virtual ~ByteComparator(); + + LUCENE_CLASS(ByteComparator); + +protected: + ByteParserPtr parser; + +public: + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); +}; + +/// Sorts by ascending docID +class LPPAPI DocComparator : public NumericComparator { +public: + DocComparator(int32_t numHits); + virtual ~DocComparator(); + + LUCENE_CLASS(DocComparator); + +protected: + int32_t docBase; + +public: + virtual int32_t compareBottom(int32_t doc); + virtual void copy(int32_t slot, int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); +}; + +/// Parses field's values as double (using {@link FieldCache#getDoubles} and sorts by ascending value +class LPPAPI DoubleComparator : public NumericComparator { +public: + DoubleComparator(int32_t numHits, const String& field, const ParserPtr& parser); + virtual ~DoubleComparator(); + + LUCENE_CLASS(DoubleComparator); + +protected: + DoubleParserPtr parser; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2); + virtual int32_t compareBottom(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); +}; + +/// Parses field's values as int (using {@link FieldCache#getInts} and sorts by ascending value +class LPPAPI IntComparator : public NumericComparator { +public: + IntComparator(int32_t numHits, const String& field, const ParserPtr& parser); + virtual ~IntComparator(); + + LUCENE_CLASS(IntComparator); + +protected: + IntParserPtr parser; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2); + virtual int32_t compareBottom(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); +}; + +/// Parses field's values as long (using {@link FieldCache#getLongs} and sorts by ascending value +class LPPAPI LongComparator : public NumericComparator { +public: + LongComparator(int32_t numHits, const String& field, const ParserPtr& parser); + virtual ~LongComparator(); + + LUCENE_CLASS(LongComparator); + +protected: + LongParserPtr parser; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2); + virtual int32_t compareBottom(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); +}; + +/// Sorts by descending relevance. NOTE: if you are sorting only by descending relevance and then secondarily +/// by ascending docID, performance is faster using {@link TopScoreDocCollector} directly (which {@link +/// IndexSearcher#search} uses when no {@link Sort} is specified). +class LPPAPI RelevanceComparator : public NumericComparator { +public: + RelevanceComparator(int32_t numHits); + virtual ~RelevanceComparator(); + + LUCENE_CLASS(RelevanceComparator); + +protected: + ScorerPtr scorer; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2); + virtual int32_t compareBottom(int32_t doc); + virtual void copy(int32_t slot, int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); +}; + +/// Sorts by a field's value using the Collator for a given Locale. +class LPPAPI StringComparatorLocale : public FieldComparator { +public: + StringComparatorLocale(int32_t numHits, const String& field, const std::locale& locale); + virtual ~StringComparatorLocale(); + + LUCENE_CLASS(StringComparatorLocale); + +protected: + Collection values; + Collection currentReaderValues; + String field; + CollatorPtr collator; + String bottom; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2); + virtual int32_t compareBottom(int32_t doc); + virtual void copy(int32_t slot, int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setBottom(int32_t slot); + virtual ComparableValue value(int32_t slot); +}; + +/// Sorts by field's natural String sort order, using ordinals. This is functionally equivalent to {@link +/// StringValComparator}, but it first resolves the string to their relative ordinal positions (using the +/// index returned by {@link FieldCache#getStringIndex}), and does most comparisons using the ordinals. +/// For medium to large results, this comparator will be much faster than {@link StringValComparator}. For +/// very small result sets it may be slower. +class LPPAPI StringOrdValComparator : public FieldComparator { +public: + StringOrdValComparator(int32_t numHits, const String& field, int32_t sortPos, bool reversed); + virtual ~StringOrdValComparator(); + + LUCENE_CLASS(StringOrdValComparator); + +protected: + Collection ords; + Collection values; + Collection readerGen; + + int32_t currentReaderGen; + Collection lookup; + Collection order; + String field; + + int32_t bottomSlot; + int32_t bottomOrd; + String bottomValue; + bool reversed; + int32_t sortPos; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2); + virtual int32_t compareBottom(int32_t doc); + virtual void copy(int32_t slot, int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setBottom(int32_t slot); + virtual ComparableValue value(int32_t slot); + virtual Collection getValues(); + virtual int32_t getBottomSlot(); + virtual String getField(); + +protected: + void convert(int32_t slot); + int32_t binarySearch(Collection lookup, const String& key, int32_t low, int32_t high); +}; + +/// Sorts by field's natural String sort order. All comparisons are done using String.compare, which is +/// slow for medium to large result sets but possibly very fast for very small results sets. +class LPPAPI StringValComparator : public FieldComparator { +public: + StringValComparator(int32_t numHits, const String& field); + virtual ~StringValComparator(); + + LUCENE_CLASS(StringOrdValComparator); + +protected: + Collection values; + Collection currentReaderValues; + String field; + String bottom; + +public: + virtual int32_t compare(int32_t slot1, int32_t slot2); + virtual int32_t compareBottom(int32_t doc); + virtual void copy(int32_t slot, int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setBottom(int32_t slot); + virtual ComparableValue value(int32_t slot); +}; + } #endif diff --git a/include/FieldComparatorSource.h b/include/FieldComparatorSource.h index 59a7a193..f8074d7b 100644 --- a/include/FieldComparatorSource.h +++ b/include/FieldComparatorSource.h @@ -9,21 +9,21 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Provides a {@link FieldComparator} for custom field sorting. - class LPPAPI FieldComparatorSource : public LuceneObject - { - public: - virtual ~FieldComparatorSource(); - LUCENE_CLASS(FieldComparatorSource); +namespace Lucene { + +/// Provides a {@link FieldComparator} for custom field sorting. +class LPPAPI FieldComparatorSource : public LuceneObject { +public: + virtual ~FieldComparatorSource(); + LUCENE_CLASS(FieldComparatorSource); + +public: + /// Creates a comparator for the field in the given index. + /// @param fieldname Name of the field to create comparator for. + /// @return FieldComparator. + virtual FieldComparatorPtr newComparator(const String& fieldname, int32_t numHits, int32_t sortPos, bool reversed) = 0; +}; - public: - /// Creates a comparator for the field in the given index. - /// @param fieldname Name of the field to create comparator for. - /// @return FieldComparator. - virtual FieldComparatorPtr newComparator(const String& fieldname, int32_t numHits, int32_t sortPos, bool reversed) = 0; - }; } #endif diff --git a/include/FieldDoc.h b/include/FieldDoc.h index 9add14af..0438894f 100644 --- a/include/FieldDoc.h +++ b/include/FieldDoc.h @@ -9,33 +9,33 @@ #include "ScoreDoc.h" -namespace Lucene -{ - /// A ScoreDoc which also contains information about how to sort the referenced document. In addition to the - /// document number and score, this object contains an array of values for the document from the field(s) used - /// to sort. For example, if the sort criteria was to sort by fields "a", "b" then "c", the fields object array - /// will have three elements, corresponding respectively to the term values for the document in fields "a", "b" - /// and "c". The class of each element in the array will be either Integer, Double or String depending on the - /// type of values in the terms of each field. - class LPPAPI FieldDoc : public ScoreDoc - { - public: - FieldDoc(int32_t doc, double score, Collection fields = Collection()); - virtual ~FieldDoc(); - - LUCENE_CLASS(FieldDoc); - - public: - /// The values which are used to sort the referenced document. The order of these will match the original - /// sort criteria given by a Sort object. Each Object will be either an Integer, Double or String, depending - /// on the type of values in the terms of the original field. - /// @see Sort - /// @see Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr) - Collection fields; - - public: - virtual String toString(); - }; +namespace Lucene { + +/// A ScoreDoc which also contains information about how to sort the referenced document. In addition to the +/// document number and score, this object contains an array of values for the document from the field(s) used +/// to sort. For example, if the sort criteria was to sort by fields "a", "b" then "c", the fields object array +/// will have three elements, corresponding respectively to the term values for the document in fields "a", "b" +/// and "c". The class of each element in the array will be either Integer, Double or String depending on the +/// type of values in the terms of each field. +class LPPAPI FieldDoc : public ScoreDoc { +public: + FieldDoc(int32_t doc, double score, Collection fields = Collection()); + virtual ~FieldDoc(); + + LUCENE_CLASS(FieldDoc); + +public: + /// The values which are used to sort the referenced document. The order of these will match the original + /// sort criteria given by a Sort object. Each Object will be either an Integer, Double or String, depending + /// on the type of values in the terms of the original field. + /// @see Sort + /// @see Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr) + Collection fields; + +public: + virtual String toString(); +}; + } #endif diff --git a/include/FieldDocSortedHitQueue.h b/include/FieldDocSortedHitQueue.h index 4a73b3b8..114d923e 100644 --- a/include/FieldDocSortedHitQueue.h +++ b/include/FieldDocSortedHitQueue.h @@ -9,44 +9,44 @@ #include "PriorityQueue.h" -namespace Lucene -{ - /// Collects sorted results from Searchable's and collates them. - /// The elements put into this queue must be of type FieldDoc. - class FieldDocSortedHitQueue : public PriorityQueue - { - public: - FieldDocSortedHitQueue(int32_t size); - virtual ~FieldDocSortedHitQueue(); - - LUCENE_CLASS(FieldDocSortedHitQueue); - - public: - Collection fields; - - // used in the case where the fields are sorted by locale based strings - Collection collators; - - public: - /// Allows redefinition of sort fields if they are null. This is to handle the case using - /// ParallelMultiSearcher where the original list contains AUTO and we don't know the actual sort - /// type until the values come back. The fields can only be set once. This method should be - /// synchronized external like all other PQ methods. - void setFields(Collection fields); - - /// Returns the fields being used to sort. - Collection getFields(); - - protected: - /// Returns an array of collators, possibly null. The collators correspond to any SortFields which - /// were given a specific locale. - /// @param fields Array of sort fields. - /// @return Array, possibly null. - Collection hasCollators(Collection fields); - - /// Returns whether first is less relevant than second. - virtual bool lessThan(const FieldDocPtr& first, const FieldDocPtr& second); - }; +namespace Lucene { + +/// Collects sorted results from Searchable's and collates them. +/// The elements put into this queue must be of type FieldDoc. +class FieldDocSortedHitQueue : public PriorityQueue { +public: + FieldDocSortedHitQueue(int32_t size); + virtual ~FieldDocSortedHitQueue(); + + LUCENE_CLASS(FieldDocSortedHitQueue); + +public: + Collection fields; + + // used in the case where the fields are sorted by locale based strings + Collection collators; + +public: + /// Allows redefinition of sort fields if they are null. This is to handle the case using + /// ParallelMultiSearcher where the original list contains AUTO and we don't know the actual sort + /// type until the values come back. The fields can only be set once. This method should be + /// synchronized external like all other PQ methods. + void setFields(Collection fields); + + /// Returns the fields being used to sort. + Collection getFields(); + +protected: + /// Returns an array of collators, possibly null. The collators correspond to any SortFields which + /// were given a specific locale. + /// @param fields Array of sort fields. + /// @return Array, possibly null. + Collection hasCollators(Collection fields); + + /// Returns whether first is less relevant than second. + virtual bool lessThan(const FieldDocPtr& first, const FieldDocPtr& second); +}; + } #endif diff --git a/include/FieldInfo.h b/include/FieldInfo.h index ba3f491e..6cffbedd 100644 --- a/include/FieldInfo.h +++ b/include/FieldInfo.h @@ -9,38 +9,38 @@ #include "LuceneObject.h" -namespace Lucene -{ - class FieldInfo : public LuceneObject - { - public: - FieldInfo(const String& na, bool tk, int32_t nu, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); - virtual ~FieldInfo(); - - LUCENE_CLASS(FieldInfo); - - public: - String name; - bool isIndexed; - int32_t number; - - // true if term vector for this field should be stored - bool storeTermVector; - bool storeOffsetWithTermVector; - bool storePositionWithTermVector; - - bool omitNorms; // omit norms associated with indexed fields - bool omitTermFreqAndPositions; - - bool storePayloads; // whether this field stores payloads together with term positions - - public: - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - void update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, - bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); - }; +namespace Lucene { + +class FieldInfo : public LuceneObject { +public: + FieldInfo(const String& na, bool tk, int32_t nu, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); + virtual ~FieldInfo(); + + LUCENE_CLASS(FieldInfo); + +public: + String name; + bool isIndexed; + int32_t number; + + // true if term vector for this field should be stored + bool storeTermVector; + bool storeOffsetWithTermVector; + bool storePositionWithTermVector; + + bool omitNorms; // omit norms associated with indexed fields + bool omitTermFreqAndPositions; + + bool storePayloads; // whether this field stores payloads together with term positions + +public: + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + void update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector, + bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); +}; + } #endif diff --git a/include/FieldInfos.h b/include/FieldInfos.h index 458e38de..61dcfda0 100644 --- a/include/FieldInfos.h +++ b/include/FieldInfos.h @@ -9,143 +9,143 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Access to the Fieldable Info file that describes document fields and whether or not they are indexed. - /// Each segment has a separate Fieldable Info file. Objects of this class are thread-safe for multiple - /// readers, but only one thread can be adding documents at a time, with no other reader or writer threads - /// accessing this object. - class FieldInfos : public LuceneObject - { - public: - FieldInfos(); - - /// Construct a FieldInfos object using the directory and the name of the file IndexInput - /// @param d The directory to open the IndexInput from - /// @param name The name of the file to open the IndexInput from in the Directory - FieldInfos(const DirectoryPtr& d, const String& name); - - virtual ~FieldInfos(); - - LUCENE_CLASS(FieldInfos); - - public: - // Used internally (ie not written to *.fnm files) for pre-2.9 files - static const int32_t FORMAT_PRE; - - // First used in 2.9; prior to 2.9 there was no format header - static const int32_t FORMAT_START; - - static const int32_t CURRENT_FORMAT; - - static const uint8_t IS_INDEXED; - static const uint8_t STORE_TERMVECTOR; - static const uint8_t STORE_POSITIONS_WITH_TERMVECTOR; - static const uint8_t STORE_OFFSET_WITH_TERMVECTOR; - static const uint8_t OMIT_NORMS; - static const uint8_t STORE_PAYLOADS; - static const uint8_t OMIT_TERM_FREQ_AND_POSITIONS; - - protected: - Collection byNumber; - MapStringFieldInfo byName; - int32_t format; - - public: - /// Returns a deep clone of this FieldInfos instance. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - /// Adds field info for a Document. - void add(const DocumentPtr& doc); - - /// Returns true if any fields do not omitTermFreqAndPositions - bool hasProx(); - - /// Add fields that are indexed. Whether they have termvectors has to be specified. - /// @param names The names of the fields - /// @param storeTermVectors Whether the fields store term vectors or not - /// @param storePositionWithTermVector true if positions should be stored. - /// @param storeOffsetWithTermVector true if offsets should be stored - void addIndexed(HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector); - - /// Assumes the fields are not storing term vectors. - /// @param names The names of the fields - /// @param isIndexed Whether the fields are indexed or not - /// @see #add(const String&, bool) - void add(HashSet names, bool isIndexed); - - /// Calls 5 parameter add with false for all TermVector parameters. - /// @param name The name of the Fieldable - /// @param isIndexed true if the field is indexed - /// @see #add(const String&, bool, bool, bool, bool) - void add(const String& name, bool isIndexed); - - /// Calls 5 parameter add with false for term vector positions and offsets. - /// @param name The name of the field - /// @param isIndexed true if the field is indexed - /// @param storeTermVector true if the term vector should be stored - void add(const String& name, bool isIndexed, bool storeTermVector); - - /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag - /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes - /// for the TermVector parameters. - /// @param name The name of the field - /// @param isIndexed true if the field is indexed - /// @param storeTermVector true if the term vector should be stored - /// @param storePositionWithTermVector true if the term vector with positions should be stored - /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored - void add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector); - - /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag - /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes - /// for the TermVector parameters. - /// @param name The name of the field - /// @param isIndexed true if the field is indexed - /// @param storeTermVector true if the term vector should be stored - /// @param storePositionWithTermVector true if the term vector with positions should be stored - /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored - /// @param omitNorms true if the norms for the indexed field should be omitted - void add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms); - - /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed - /// flag is the same as was given previously for this field. If not - marks it as being indexed. - /// Same goes for the TermVector parameters. - /// @param name The name of the field - /// @param isIndexed true if the field is indexed - /// @param storeTermVector true if the term vector should be stored - /// @param storePositionWithTermVector true if the term vector with positions should be stored - /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored - /// @param omitNorms true if the norms for the indexed field should be omitted - /// @param storePayloads true if payloads should be stored for this field - /// @param omitTermFreqAndPositions true if term freqs should be omitted for this field - FieldInfoPtr add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); - - int32_t fieldNumber(const String& fieldName); - FieldInfoPtr fieldInfo(const String& fieldName); - - /// Return the fieldName identified by its number. - /// @return the fieldName or an empty string when the field with the given number doesn't exist. - String fieldName(int32_t fieldNumber); - - /// Return the fieldinfo object referenced by the fieldNumber. - /// @return the FieldInfo object or null when the given fieldNumber doesn't exist. - FieldInfoPtr fieldInfo(int32_t fieldNumber); - - int32_t size(); - - bool hasVectors(); - - void write(const DirectoryPtr& d, const String& name); - void write(const IndexOutputPtr& output); - - protected: - FieldInfoPtr addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); - - void read(const IndexInputPtr& input, const String& fileName); - }; +namespace Lucene { + +/// Access to the Fieldable Info file that describes document fields and whether or not they are indexed. +/// Each segment has a separate Fieldable Info file. Objects of this class are thread-safe for multiple +/// readers, but only one thread can be adding documents at a time, with no other reader or writer threads +/// accessing this object. +class FieldInfos : public LuceneObject { +public: + FieldInfos(); + + /// Construct a FieldInfos object using the directory and the name of the file IndexInput + /// @param d The directory to open the IndexInput from + /// @param name The name of the file to open the IndexInput from in the Directory + FieldInfos(const DirectoryPtr& d, const String& name); + + virtual ~FieldInfos(); + + LUCENE_CLASS(FieldInfos); + +public: + // Used internally (ie not written to *.fnm files) for pre-2.9 files + static const int32_t FORMAT_PRE; + + // First used in 2.9; prior to 2.9 there was no format header + static const int32_t FORMAT_START; + + static const int32_t CURRENT_FORMAT; + + static const uint8_t IS_INDEXED; + static const uint8_t STORE_TERMVECTOR; + static const uint8_t STORE_POSITIONS_WITH_TERMVECTOR; + static const uint8_t STORE_OFFSET_WITH_TERMVECTOR; + static const uint8_t OMIT_NORMS; + static const uint8_t STORE_PAYLOADS; + static const uint8_t OMIT_TERM_FREQ_AND_POSITIONS; + +protected: + Collection byNumber; + MapStringFieldInfo byName; + int32_t format; + +public: + /// Returns a deep clone of this FieldInfos instance. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Adds field info for a Document. + void add(const DocumentPtr& doc); + + /// Returns true if any fields do not omitTermFreqAndPositions + bool hasProx(); + + /// Add fields that are indexed. Whether they have termvectors has to be specified. + /// @param names The names of the fields + /// @param storeTermVectors Whether the fields store term vectors or not + /// @param storePositionWithTermVector true if positions should be stored. + /// @param storeOffsetWithTermVector true if offsets should be stored + void addIndexed(HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector); + + /// Assumes the fields are not storing term vectors. + /// @param names The names of the fields + /// @param isIndexed Whether the fields are indexed or not + /// @see #add(const String&, bool) + void add(HashSet names, bool isIndexed); + + /// Calls 5 parameter add with false for all TermVector parameters. + /// @param name The name of the Fieldable + /// @param isIndexed true if the field is indexed + /// @see #add(const String&, bool, bool, bool, bool) + void add(const String& name, bool isIndexed); + + /// Calls 5 parameter add with false for term vector positions and offsets. + /// @param name The name of the field + /// @param isIndexed true if the field is indexed + /// @param storeTermVector true if the term vector should be stored + void add(const String& name, bool isIndexed, bool storeTermVector); + + /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag + /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes + /// for the TermVector parameters. + /// @param name The name of the field + /// @param isIndexed true if the field is indexed + /// @param storeTermVector true if the term vector should be stored + /// @param storePositionWithTermVector true if the term vector with positions should be stored + /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored + void add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector); + + /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed flag + /// is the same as was given previously for this field. If not - marks it as being indexed. Same goes + /// for the TermVector parameters. + /// @param name The name of the field + /// @param isIndexed true if the field is indexed + /// @param storeTermVector true if the term vector should be stored + /// @param storePositionWithTermVector true if the term vector with positions should be stored + /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored + /// @param omitNorms true if the norms for the indexed field should be omitted + void add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms); + + /// If the field is not yet known, adds it. If it is known, checks to make sure that the isIndexed + /// flag is the same as was given previously for this field. If not - marks it as being indexed. + /// Same goes for the TermVector parameters. + /// @param name The name of the field + /// @param isIndexed true if the field is indexed + /// @param storeTermVector true if the term vector should be stored + /// @param storePositionWithTermVector true if the term vector with positions should be stored + /// @param storeOffsetWithTermVector true if the term vector with offsets should be stored + /// @param omitNorms true if the norms for the indexed field should be omitted + /// @param storePayloads true if payloads should be stored for this field + /// @param omitTermFreqAndPositions true if term freqs should be omitted for this field + FieldInfoPtr add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); + + int32_t fieldNumber(const String& fieldName); + FieldInfoPtr fieldInfo(const String& fieldName); + + /// Return the fieldName identified by its number. + /// @return the fieldName or an empty string when the field with the given number doesn't exist. + String fieldName(int32_t fieldNumber); + + /// Return the fieldinfo object referenced by the fieldNumber. + /// @return the FieldInfo object or null when the given fieldNumber doesn't exist. + FieldInfoPtr fieldInfo(int32_t fieldNumber); + + int32_t size(); + + bool hasVectors(); + + void write(const DirectoryPtr& d, const String& name); + void write(const IndexOutputPtr& output); + +protected: + FieldInfoPtr addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions); + + void read(const IndexInputPtr& input, const String& fileName); +}; + } #endif diff --git a/include/FieldInvertState.h b/include/FieldInvertState.h index 53cd0b01..18818e4d 100644 --- a/include/FieldInvertState.h +++ b/include/FieldInvertState.h @@ -9,54 +9,54 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This class tracks the number and position / offset parameters of terms being added to the index. - /// The information collected in this class is also used to calculate the normalization factor for a field. - class LPPAPI FieldInvertState : public LuceneObject - { - public: - FieldInvertState(int32_t position = 0, int32_t length = 0, int32_t numOverlap = 0, int32_t offset = 0, double boost = 0); - virtual ~FieldInvertState(); - - LUCENE_CLASS(FieldInvertState); - - INTERNAL: - int32_t position; - int32_t length; - int32_t numOverlap; - int32_t offset; - double boost; - AttributeSourcePtr attributeSource; - - public: - /// Re-initialize the state, using this boost value. - /// @param docBoost boost value to use. - void reset(double docBoost); - - /// Get the last processed term position. - /// @return the position - int32_t getPosition(); - - /// Get total number of terms in this field. - /// @return the length - int32_t getLength(); - - /// Get the number of terms with positionIncrement == 0. - /// @return the numOverlap - int32_t getNumOverlap(); - - /// Get end offset of the last processed term. - /// @return the offset - int32_t getOffset(); - - /// Get boost value. This is the cumulative product of document boost and field boost for all field - /// instances sharing the same field name. - /// @return the boost - double getBoost(); - - AttributeSourcePtr getAttributeSource(); - }; +namespace Lucene { + +/// This class tracks the number and position / offset parameters of terms being added to the index. +/// The information collected in this class is also used to calculate the normalization factor for a field. +class LPPAPI FieldInvertState : public LuceneObject { +public: + FieldInvertState(int32_t position = 0, int32_t length = 0, int32_t numOverlap = 0, int32_t offset = 0, double boost = 0); + virtual ~FieldInvertState(); + + LUCENE_CLASS(FieldInvertState); + +INTERNAL: + int32_t position; + int32_t length; + int32_t numOverlap; + int32_t offset; + double boost; + AttributeSourcePtr attributeSource; + +public: + /// Re-initialize the state, using this boost value. + /// @param docBoost boost value to use. + void reset(double docBoost); + + /// Get the last processed term position. + /// @return the position + int32_t getPosition(); + + /// Get total number of terms in this field. + /// @return the length + int32_t getLength(); + + /// Get the number of terms with positionIncrement == 0. + /// @return the numOverlap + int32_t getNumOverlap(); + + /// Get end offset of the last processed term. + /// @return the offset + int32_t getOffset(); + + /// Get boost value. This is the cumulative product of document boost and field boost for all field + /// instances sharing the same field name. + /// @return the boost + double getBoost(); + + AttributeSourcePtr getAttributeSource(); +}; + } #endif diff --git a/include/FieldMaskingSpanQuery.h b/include/FieldMaskingSpanQuery.h index fc162918..27dedf89 100644 --- a/include/FieldMaskingSpanQuery.h +++ b/include/FieldMaskingSpanQuery.h @@ -9,76 +9,76 @@ #include "SpanQuery.h" -namespace Lucene -{ - /// Wrapper to allow {@link SpanQuery} objects participate in composite single-field SpanQueries by - /// 'lying' about their search field. That is, the masked SpanQuery will function as normal, but - /// {@link SpanQuery#getField()} simply hands back the value supplied in this class's constructor. - /// - /// This can be used to support Queries like {@link SpanNearQuery} or {@link SpanOrQuery} across - /// different fields, which is not ordinarily permitted. - /// - /// This can be useful for denormalized relational data: for example, when indexing a document with - /// conceptually many 'children': - /// - ///
      -    /// teacherid: 1
      -    /// studentfirstname: james
      -    /// studentsurname: jones
      -    ///
      -    /// teacherid: 2
      -    /// studenfirstname: james
      -    /// studentsurname: smith
      -    /// studentfirstname: sally
      -    /// studentsurname: jones
      -    /// 
      - /// - /// A SpanNearQuery with a slop of 0 can be applied across two {@link SpanTermQuery} objects as follows: - /// - ///
      -    /// SpanQueryPtr q1 = newLucene(newLucene(L"studentfirstname", L"james"));
      -    /// SpanQueryPtr q2 = newLucene(newLucene(L"studentsurname", L"jones"));
      -    /// SpanQueryPtr q2m = newLucene(q2, L"studentfirstname");
      -    ///
      -    /// Collection span = newCollection(q1, q1);
      -    ///
      -    /// QueryPtr q = newLucene(span, -1, false);
      -    /// 
      - /// to search for 'studentfirstname:james studentsurname:jones' and find teacherid 1 without matching - /// teacherid 2 (which has a 'james' in position 0 and 'jones' in position 1). - /// - /// Note: as {@link #getField()} returns the masked field, scoring will be done using the norms of the - /// field name supplied. This may lead to unexpected scoring behaviour. - class LPPAPI FieldMaskingSpanQuery : public SpanQuery - { - public: - FieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField); - virtual ~FieldMaskingSpanQuery(); +namespace Lucene { - LUCENE_CLASS(FieldMaskingSpanQuery); +/// Wrapper to allow {@link SpanQuery} objects participate in composite single-field SpanQueries by +/// 'lying' about their search field. That is, the masked SpanQuery will function as normal, but +/// {@link SpanQuery#getField()} simply hands back the value supplied in this class's constructor. +/// +/// This can be used to support Queries like {@link SpanNearQuery} or {@link SpanOrQuery} across +/// different fields, which is not ordinarily permitted. +/// +/// This can be useful for denormalized relational data: for example, when indexing a document with +/// conceptually many 'children': +/// +///
      +/// teacherid: 1
      +/// studentfirstname: james
      +/// studentsurname: jones
      +///
      +/// teacherid: 2
      +/// studenfirstname: james
      +/// studentsurname: smith
      +/// studentfirstname: sally
      +/// studentsurname: jones
      +/// 
      +/// +/// A SpanNearQuery with a slop of 0 can be applied across two {@link SpanTermQuery} objects as follows: +/// +///
      +/// SpanQueryPtr q1 = newLucene(newLucene(L"studentfirstname", L"james"));
      +/// SpanQueryPtr q2 = newLucene(newLucene(L"studentsurname", L"jones"));
      +/// SpanQueryPtr q2m = newLucene(q2, L"studentfirstname");
      +///
      +/// Collection span = newCollection(q1, q1);
      +///
      +/// QueryPtr q = newLucene(span, -1, false);
      +/// 
      +/// to search for 'studentfirstname:james studentsurname:jones' and find teacherid 1 without matching +/// teacherid 2 (which has a 'james' in position 0 and 'jones' in position 1). +/// +/// Note: as {@link #getField()} returns the masked field, scoring will be done using the norms of the +/// field name supplied. This may lead to unexpected scoring behaviour. +class LPPAPI FieldMaskingSpanQuery : public SpanQuery { +public: + FieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField); + virtual ~FieldMaskingSpanQuery(); - protected: - SpanQueryPtr maskedQuery; - String field; + LUCENE_CLASS(FieldMaskingSpanQuery); - public: - using SpanQuery::toString; +protected: + SpanQueryPtr maskedQuery; + String field; - virtual String getField(); - SpanQueryPtr getMaskedQuery(); - virtual SpansPtr getSpans(const IndexReaderPtr& reader); - virtual void extractTerms(SetTerm terms); - virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); - virtual QueryPtr rewrite(const IndexReaderPtr& reader); +public: + using SpanQuery::toString; - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); + virtual String getField(); + SpanQueryPtr getMaskedQuery(); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + virtual void extractTerms(SetTerm terms); + virtual WeightPtr createWeight(const SearcherPtr& searcher); + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + /// Returns a clone of this query. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; - /// Returns a clone of this query. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; } #endif diff --git a/include/FieldScoreQuery.h b/include/FieldScoreQuery.h index ae6fe785..a961fe50 100644 --- a/include/FieldScoreQuery.h +++ b/include/FieldScoreQuery.h @@ -9,67 +9,66 @@ #include "ValueSourceQuery.h" -namespace Lucene -{ - /// A query that scores each document as the value of the numeric input field. - /// - /// The query matches all documents, and scores each document according to the numeric value of that field. - /// - /// It is assumed, and expected, that: - ///
        - ///
      • The field used here is indexed, and has exactly one token in every scored document. - ///
      • Best if this field is un_tokenized. - ///
      • That token is parseable to the selected type. - ///
      - /// - /// Combining this query in a FunctionQuery allows much freedom in affecting document scores. Note, that - /// with this freedom comes responsibility: it is more than likely that the default Lucene scoring is superior - /// in quality to scoring modified as explained here. However, in some cases, and certainly for research - /// experiments, this capability may turn useful. - /// - /// When constructing this query, select the appropriate type. That type should match the data stored in the - /// field. So in fact the "right" type should be selected before indexing. Type selection has effect on the - /// RAM usage: - ///
        - ///
      • Byte consumes 1 * maxDocs bytes. - ///
      • Int consumes 4 * maxDocs bytes. - ///
      • Double consumes 8 * maxDocs bytes. - ///
      - /// - /// Caching: Values for the numeric field are loaded once and cached in memory for further use with the same - /// IndexReader. To take advantage of this, it is extremely important to reuse index-readers or index- - /// searchers, otherwise, for instance if for each query a new index reader is opened, large penalties would - /// be paid for loading the field values into memory over and over again. - class LPPAPI FieldScoreQuery : public ValueSourceQuery - { - public: - /// Type of score field, indicating how field values are interpreted/parsed. - enum Type - { - /// Field values are interpreted as numeric byte values. - BYTE, +namespace Lucene { - /// Field values are interpreted as numeric integer values. - INT, +/// A query that scores each document as the value of the numeric input field. +/// +/// The query matches all documents, and scores each document according to the numeric value of that field. +/// +/// It is assumed, and expected, that: +///
        +///
      • The field used here is indexed, and has exactly one token in every scored document. +///
      • Best if this field is un_tokenized. +///
      • That token is parseable to the selected type. +///
      +/// +/// Combining this query in a FunctionQuery allows much freedom in affecting document scores. Note, that +/// with this freedom comes responsibility: it is more than likely that the default Lucene scoring is superior +/// in quality to scoring modified as explained here. However, in some cases, and certainly for research +/// experiments, this capability may turn useful. +/// +/// When constructing this query, select the appropriate type. That type should match the data stored in the +/// field. So in fact the "right" type should be selected before indexing. Type selection has effect on the +/// RAM usage: +///
        +///
      • Byte consumes 1 * maxDocs bytes. +///
      • Int consumes 4 * maxDocs bytes. +///
      • Double consumes 8 * maxDocs bytes. +///
      +/// +/// Caching: Values for the numeric field are loaded once and cached in memory for further use with the same +/// IndexReader. To take advantage of this, it is extremely important to reuse index-readers or index- +/// searchers, otherwise, for instance if for each query a new index reader is opened, large penalties would +/// be paid for loading the field values into memory over and over again. +class LPPAPI FieldScoreQuery : public ValueSourceQuery { +public: + /// Type of score field, indicating how field values are interpreted/parsed. + enum Type { + /// Field values are interpreted as numeric byte values. + BYTE, - /// Field values are interpreted as numeric double values. - DOUBLE - }; + /// Field values are interpreted as numeric integer values. + INT, - /// Create a FieldScoreQuery - a query that scores each document as the value of the numeric input field. - /// The type param tells how to parse the field string values into a numeric score value. - /// @param field the numeric field to be used. - /// @param type the type of the field. - FieldScoreQuery(const String& field, Type type); + /// Field values are interpreted as numeric double values. + DOUBLE + }; - virtual ~FieldScoreQuery(); + /// Create a FieldScoreQuery - a query that scores each document as the value of the numeric input field. + /// The type param tells how to parse the field string values into a numeric score value. + /// @param field the numeric field to be used. + /// @param type the type of the field. + FieldScoreQuery(const String& field, Type type); - LUCENE_CLASS(FieldScoreQuery); + virtual ~FieldScoreQuery(); + + LUCENE_CLASS(FieldScoreQuery); + +public: + /// Create the appropriate (cached) field value source. + static ValueSourcePtr getValueSource(const String& field, Type type); +}; - public: - /// Create the appropriate (cached) field value source. - static ValueSourcePtr getValueSource(const String& field, Type type); - }; } #endif diff --git a/include/FieldSelector.h b/include/FieldSelector.h index fc56e567..e35d0c13 100644 --- a/include/FieldSelector.h +++ b/include/FieldSelector.h @@ -9,66 +9,65 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// The FieldSelector allows one to make decisions about what Fields get loaded on a {@link Document} by - /// {@link IndexReader#document(int32_t, FieldSelector)} - class LPPAPI FieldSelector : public LuceneObject - { - protected: - FieldSelector(); - - public: - virtual ~FieldSelector(); - - LUCENE_CLASS(FieldSelector); - - public: - /// Provides information about what should be done with this Field - enum FieldSelectorResult - { - /// Null value - SELECTOR_NULL, - - /// Load this {@link Field} every time the {@link Document} is loaded, reading in the data as it is - /// encountered. {@link Document#getField(String)} and {@link Document#getFieldable(String)} should - /// not return null. - /// {@link Document#add(Fieldable)} should be called by the Reader. - SELECTOR_LOAD, - - /// Lazily load this {@link Field}. This means the {@link Field} is valid, but it may not actually - /// contain its data until invoked. {@link Document#getField(String)} SHOULD NOT BE USED. {@link - /// Document#getFieldable(String)} is safe to use and should return a valid instance of a {@link - /// Fieldable}. - /// {@link Document#add(Fieldable)} should be called by the Reader. - SELECTOR_LAZY_LOAD, - - /// Do not load the {@link Field}. {@link Document#getField(String)} and {@link - /// Document#getFieldable(String)} should return null. {@link Document#add(Fieldable)} is not called. - /// {@link Document#add(Fieldable)} should not be called by the Reader. - SELECTOR_NO_LOAD, - - /// Load this field as in the {@link #LOAD} case, but immediately return from {@link Field} loading - /// for the {@link Document}. Thus, the Document may not have its complete set of Fields. {@link - /// Document#getField(String)} and {@link Document#getFieldable(String)} should both be valid for - /// this {@link Field} - /// {@link Document#add(Fieldable)} should be called by the Reader. - SELECTOR_LOAD_AND_BREAK, - - /// Load the size of this {@link Field} rather than its value. Size is measured as number of bytes - /// required to store the field == bytes for a binary or any compressed value, and 2*chars for a String - /// value. The size is stored as a binary value, represented as an int in a byte[], with the higher - /// order byte first in [0] - SELECTOR_SIZE, - - /// Like {@link #SIZE} but immediately break from the field loading loop, i.e., stop loading further - /// fields, after the size is loaded - SELECTOR_SIZE_AND_BREAK - }; - - public: - virtual FieldSelectorResult accept(const String& fieldName) = 0; +namespace Lucene { + +/// The FieldSelector allows one to make decisions about what Fields get loaded on a {@link Document} by +/// {@link IndexReader#document(int32_t, FieldSelector)} +class LPPAPI FieldSelector : public LuceneObject { +protected: + FieldSelector(); + +public: + virtual ~FieldSelector(); + + LUCENE_CLASS(FieldSelector); + +public: + /// Provides information about what should be done with this Field + enum FieldSelectorResult { + /// Null value + SELECTOR_NULL, + + /// Load this {@link Field} every time the {@link Document} is loaded, reading in the data as it is + /// encountered. {@link Document#getField(String)} and {@link Document#getFieldable(String)} should + /// not return null. + /// {@link Document#add(Fieldable)} should be called by the Reader. + SELECTOR_LOAD, + + /// Lazily load this {@link Field}. This means the {@link Field} is valid, but it may not actually + /// contain its data until invoked. {@link Document#getField(String)} SHOULD NOT BE USED. {@link + /// Document#getFieldable(String)} is safe to use and should return a valid instance of a {@link + /// Fieldable}. + /// {@link Document#add(Fieldable)} should be called by the Reader. + SELECTOR_LAZY_LOAD, + + /// Do not load the {@link Field}. {@link Document#getField(String)} and {@link + /// Document#getFieldable(String)} should return null. {@link Document#add(Fieldable)} is not called. + /// {@link Document#add(Fieldable)} should not be called by the Reader. + SELECTOR_NO_LOAD, + + /// Load this field as in the {@link #LOAD} case, but immediately return from {@link Field} loading + /// for the {@link Document}. Thus, the Document may not have its complete set of Fields. {@link + /// Document#getField(String)} and {@link Document#getFieldable(String)} should both be valid for + /// this {@link Field} + /// {@link Document#add(Fieldable)} should be called by the Reader. + SELECTOR_LOAD_AND_BREAK, + + /// Load the size of this {@link Field} rather than its value. Size is measured as number of bytes + /// required to store the field == bytes for a binary or any compressed value, and 2*chars for a String + /// value. The size is stored as a binary value, represented as an int in a byte[], with the higher + /// order byte first in [0] + SELECTOR_SIZE, + + /// Like {@link #SIZE} but immediately break from the field loading loop, i.e., stop loading further + /// fields, after the size is loaded + SELECTOR_SIZE_AND_BREAK }; + +public: + virtual FieldSelectorResult accept(const String& fieldName) = 0; +}; + } #endif diff --git a/include/FieldSortedTermVectorMapper.h b/include/FieldSortedTermVectorMapper.h index ef1f79ff..49e5c4fe 100644 --- a/include/FieldSortedTermVectorMapper.h +++ b/include/FieldSortedTermVectorMapper.h @@ -10,42 +10,42 @@ #include #include "TermVectorMapper.h" -namespace Lucene -{ - /// For each Field, store a sorted collection of {@link TermVectorEntry}s - /// This is not thread-safe. - class LPPAPI FieldSortedTermVectorMapper : public TermVectorMapper - { - public: - /// @param comparator A Comparator for sorting {@link TermVectorEntry}s - FieldSortedTermVectorMapper(TermVectorEntryComparator comparator); - - FieldSortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator); - - virtual ~FieldSortedTermVectorMapper(); - - LUCENE_CLASS(FieldSortedTermVectorMapper); - - protected: - MapStringCollectionTermVectorEntry fieldToTerms; - Collection currentSet; - String currentField; - TermVectorEntryComparator comparator; - - public: - /// Map the Term Vector information into your own structure - virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); - - /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. - virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); - - /// Get the mapping between fields and terms, sorted by the comparator - /// @return A map between field names and {@link java.util.SortedSet}s per field. SortedSet entries are - /// {@link TermVectorEntry} - MapStringCollectionTermVectorEntry getFieldToTerms(); - - TermVectorEntryComparator getComparator(); - }; +namespace Lucene { + +/// For each Field, store a sorted collection of {@link TermVectorEntry}s +/// This is not thread-safe. +class LPPAPI FieldSortedTermVectorMapper : public TermVectorMapper { +public: + /// @param comparator A Comparator for sorting {@link TermVectorEntry}s + FieldSortedTermVectorMapper(TermVectorEntryComparator comparator); + + FieldSortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator); + + virtual ~FieldSortedTermVectorMapper(); + + LUCENE_CLASS(FieldSortedTermVectorMapper); + +protected: + MapStringCollectionTermVectorEntry fieldToTerms; + Collection currentSet; + String currentField; + TermVectorEntryComparator comparator; + +public: + /// Map the Term Vector information into your own structure + virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); + + /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. + virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); + + /// Get the mapping between fields and terms, sorted by the comparator + /// @return A map between field names and {@link java.util.SortedSet}s per field. SortedSet entries are + /// {@link TermVectorEntry} + MapStringCollectionTermVectorEntry getFieldToTerms(); + + TermVectorEntryComparator getComparator(); +}; + } #endif diff --git a/include/FieldValueHitQueue.h b/include/FieldValueHitQueue.h index a38c69b7..7b4fab70 100644 --- a/include/FieldValueHitQueue.h +++ b/include/FieldValueHitQueue.h @@ -10,64 +10,63 @@ #include "HitQueueBase.h" #include "ScoreDoc.h" -namespace Lucene -{ - /// A hit queue for sorting by hits by terms in more than one field. Uses FieldCache::DEFAULT for maintaining - /// internal term lookup tables. - /// @see Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr) - /// @see FieldCache - class LPPAPI FieldValueHitQueue : public HitQueueBase - { - protected: - FieldValueHitQueue(Collection fields, int32_t size); - - public: - virtual ~FieldValueHitQueue(); - - LUCENE_CLASS(FieldValueHitQueue); - - protected: - /// Stores the sort criteria being used. - Collection fields; - Collection comparators; - Collection reverseMul; - - public: - /// Creates a hit queue sorted by the given list of fields. - /// @param fields SortField array we are sorting by in priority order (highest priority first); cannot - /// be null or empty. - /// @param size The number of hits to retain. Must be greater than zero. - static FieldValueHitQueuePtr create(Collection fields, int32_t size); - - Collection getComparators(); - Collection getReverseMul(); - - /// Given a queue Entry, creates a corresponding FieldDoc that contains the values used to sort the given - /// document. These values are not the raw values out of the index, but the internal representation of - /// them. This is so the given search hit can be collated by a MultiSearcher with other search hits. - /// @param entry The Entry used to create a FieldDoc - /// @return The newly created FieldDoc - /// @see Searchable#search(WeightPtr, FilterPtr, int32_t, SortPtr) - FieldDocPtr fillFields(const FieldValueHitQueueEntryPtr& entry); - - /// Returns the SortFields being used by this hit queue. - Collection getFields(); - }; - - class LPPAPI FieldValueHitQueueEntry : public ScoreDoc - { - public: - FieldValueHitQueueEntry(int32_t slot, int32_t doc, double score); - virtual ~FieldValueHitQueueEntry(); - - LUCENE_CLASS(FieldValueHitQueueEntry); - - public: - int32_t slot; - - public: - virtual String toString(); - }; +namespace Lucene { + +/// A hit queue for sorting by hits by terms in more than one field. Uses FieldCache::DEFAULT for maintaining +/// internal term lookup tables. +/// @see Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr) +/// @see FieldCache +class LPPAPI FieldValueHitQueue : public HitQueueBase { +protected: + FieldValueHitQueue(Collection fields, int32_t size); + +public: + virtual ~FieldValueHitQueue(); + + LUCENE_CLASS(FieldValueHitQueue); + +protected: + /// Stores the sort criteria being used. + Collection fields; + Collection comparators; + Collection reverseMul; + +public: + /// Creates a hit queue sorted by the given list of fields. + /// @param fields SortField array we are sorting by in priority order (highest priority first); cannot + /// be null or empty. + /// @param size The number of hits to retain. Must be greater than zero. + static FieldValueHitQueuePtr create(Collection fields, int32_t size); + + Collection getComparators(); + Collection getReverseMul(); + + /// Given a queue Entry, creates a corresponding FieldDoc that contains the values used to sort the given + /// document. These values are not the raw values out of the index, but the internal representation of + /// them. This is so the given search hit can be collated by a MultiSearcher with other search hits. + /// @param entry The Entry used to create a FieldDoc + /// @return The newly created FieldDoc + /// @see Searchable#search(WeightPtr, FilterPtr, int32_t, SortPtr) + FieldDocPtr fillFields(const FieldValueHitQueueEntryPtr& entry); + + /// Returns the SortFields being used by this hit queue. + Collection getFields(); +}; + +class LPPAPI FieldValueHitQueueEntry : public ScoreDoc { +public: + FieldValueHitQueueEntry(int32_t slot, int32_t doc, double score); + virtual ~FieldValueHitQueueEntry(); + + LUCENE_CLASS(FieldValueHitQueueEntry); + +public: + int32_t slot; + +public: + virtual String toString(); +}; + } #endif diff --git a/include/Fieldable.h b/include/Fieldable.h index bdb7f2a0..4846f009 100644 --- a/include/Fieldable.h +++ b/include/Fieldable.h @@ -9,143 +9,143 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Synonymous with {@link Field}. +namespace Lucene { + +/// Synonymous with {@link Field}. +/// +/// WARNING: This interface may change within minor versions, despite Lucene's backward compatibility +/// requirements. This means new methods may be added from version to version. This change only +/// affects the Fieldable API; other backwards compatibility promises remain intact. For example, Lucene +/// can still read and write indices created within the same major version. +class LPPAPI Fieldable { +public: + LUCENE_INTERFACE(Fieldable); + +public: + /// Sets the boost factor hits on this field. This value will be multiplied into the score of all + /// hits on this this field of this document. /// - /// WARNING: This interface may change within minor versions, despite Lucene's backward compatibility - /// requirements. This means new methods may be added from version to version. This change only - /// affects the Fieldable API; other backwards compatibility promises remain intact. For example, Lucene - /// can still read and write indices created within the same major version. - class LPPAPI Fieldable - { - public: - LUCENE_INTERFACE(Fieldable); - - public: - /// Sets the boost factor hits on this field. This value will be multiplied into the score of all - /// hits on this this field of this document. - /// - /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. - /// If a document has multiple fields with the same name, all such values are multiplied together. - /// This product is then used to compute the norm factor for the field. By default, in the {@link - /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the - /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} - /// before it is stored in the index. One should attempt to ensure that this product does not overflow - /// the range of that encoding. - /// - /// @see Document#setBoost(double) - /// @see Similarity#computeNorm(String, FieldInvertState) - /// @see Similarity#encodeNorm(double) - virtual void setBoost(double boost) = 0; - - /// Returns the boost factor for hits for this field. - /// - /// The default value is 1.0. - /// - /// Note: this value is not stored directly with the document in the index. Documents returned from - /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value - /// present as when this field was indexed. - virtual double getBoost() = 0; - - /// Returns the name of the field as an interned string. For example "date", "title", "body", ... - virtual String name() = 0; - - /// The value of the field as a String, or empty. - /// - /// For indexing, if isStored()==true, the stringValue() will be used as the stored field value - /// unless isBinary()==true, in which case getBinaryValue() will be used. - /// - /// If isIndexed()==true and isTokenized()==false, this String value will be indexed as a single token. - /// If isIndexed()==true and isTokenized()==true, then tokenStreamValue() will be used to generate - /// indexed tokens if not null, else readerValue() will be used to generate indexed tokens if not null, - /// else stringValue() will be used to generate tokens. - virtual String stringValue() = 0; - - /// The value of the field as a Reader, which can be used at index time to generate indexed tokens. - /// @see #stringValue() - virtual ReaderPtr readerValue() = 0; - - /// The TokenStream for this field to be used when indexing, or null. - /// @see #stringValue() - virtual TokenStreamPtr tokenStreamValue() = 0; - - /// True if the value of the field is to be stored in the index for return with search hits. - virtual bool isStored() = 0; - - /// True if the value of the field is to be indexed, so that it may be searched on. - virtual bool isIndexed() = 0; - - /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields - /// are indexed as a single word and may not be Reader-valued. - virtual bool isTokenized() = 0; - - /// True if the term or terms used to index this field are stored as a term vector, available from - /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the - /// original content of the field, only to terms used to index it. If the original content must be - /// preserved, use the stored attribute instead. - virtual bool isTermVectorStored() = 0; - - /// True if terms are stored as term vector together with their offsets (start and end position in - /// source text). - virtual bool isStoreOffsetWithTermVector() = 0; - - /// True if terms are stored as term vector together with their token positions. - virtual bool isStorePositionWithTermVector() = 0; - - /// True if the value of the field is stored as binary. - virtual bool isBinary() = 0; - - /// True if norms are omitted for this indexed field. - virtual bool getOmitNorms() = 0; - - /// If set, omit normalization factors associated with this indexed field. - /// This effectively disables indexing boosts and length normalization for this field. - virtual void setOmitNorms(bool omitNorms) = 0; - - /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field - /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} - /// is only valid as long as the {@link IndexReader} that retrieved the {@link Document} is still open. - /// - /// @return true if this field can be loaded lazily - virtual bool isLazy() = 0; - - /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is - /// undefined. - /// @return index of the first character in byte[] segment that represents this Field value. - virtual int32_t getBinaryOffset() = 0; - - /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is - /// undefined. - /// @return length of byte[] segment that represents this Field value. - virtual int32_t getBinaryLength() = 0; - - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} - /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. - /// @return reference to the Field value as byte[]. - virtual ByteArray getBinaryValue() = 0; - - /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} - /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. - /// - /// About reuse: if you pass in the result byte[] and it is used, likely the underlying implementation will - /// hold onto this byte[] and return it in future calls to {@link #getBinaryValue()}. So if you subsequently - /// re-use the same byte[] elsewhere it will alter this Fieldable's value. - /// @param result User defined buffer that will be used if possible. If this is null or not large enough, - /// a new buffer is allocated - /// @return reference to the Field value as byte[]. - virtual ByteArray getBinaryValue(ByteArray result) = 0; - - /// @see #setOmitTermFreqAndPositions - virtual bool getOmitTermFreqAndPositions() = 0; - - /// If set, omit term freq, positions and payloads from postings for this field. - /// - /// NOTE: While this option reduces storage space required in the index, it also means any query requiring - /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail - /// to find results. - virtual void setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) = 0; - }; + /// The boost is multiplied by {@link Document#getBoost()} of the document containing this field. + /// If a document has multiple fields with the same name, all such values are multiplied together. + /// This product is then used to compute the norm factor for the field. By default, in the {@link + /// Similarity#computeNorm(String, FieldInvertState)} method, the boost value is multiplied by the + /// {@link Similarity#lengthNorm(String,int)} and then rounded by {@link Similarity#encodeNorm(double)} + /// before it is stored in the index. One should attempt to ensure that this product does not overflow + /// the range of that encoding. + /// + /// @see Document#setBoost(double) + /// @see Similarity#computeNorm(String, FieldInvertState) + /// @see Similarity#encodeNorm(double) + virtual void setBoost(double boost) = 0; + + /// Returns the boost factor for hits for this field. + /// + /// The default value is 1.0. + /// + /// Note: this value is not stored directly with the document in the index. Documents returned from + /// {@link IndexReader#document(int)} and {@link Searcher#doc(int)} may thus not have the same value + /// present as when this field was indexed. + virtual double getBoost() = 0; + + /// Returns the name of the field as an interned string. For example "date", "title", "body", ... + virtual String name() = 0; + + /// The value of the field as a String, or empty. + /// + /// For indexing, if isStored()==true, the stringValue() will be used as the stored field value + /// unless isBinary()==true, in which case getBinaryValue() will be used. + /// + /// If isIndexed()==true and isTokenized()==false, this String value will be indexed as a single token. + /// If isIndexed()==true and isTokenized()==true, then tokenStreamValue() will be used to generate + /// indexed tokens if not null, else readerValue() will be used to generate indexed tokens if not null, + /// else stringValue() will be used to generate tokens. + virtual String stringValue() = 0; + + /// The value of the field as a Reader, which can be used at index time to generate indexed tokens. + /// @see #stringValue() + virtual ReaderPtr readerValue() = 0; + + /// The TokenStream for this field to be used when indexing, or null. + /// @see #stringValue() + virtual TokenStreamPtr tokenStreamValue() = 0; + + /// True if the value of the field is to be stored in the index for return with search hits. + virtual bool isStored() = 0; + + /// True if the value of the field is to be indexed, so that it may be searched on. + virtual bool isIndexed() = 0; + + /// True if the value of the field should be tokenized as text prior to indexing. Un-tokenized fields + /// are indexed as a single word and may not be Reader-valued. + virtual bool isTokenized() = 0; + + /// True if the term or terms used to index this field are stored as a term vector, available from + /// {@link IndexReader#getTermFreqVector(int,String)}. These methods do not provide access to the + /// original content of the field, only to terms used to index it. If the original content must be + /// preserved, use the stored attribute instead. + virtual bool isTermVectorStored() = 0; + + /// True if terms are stored as term vector together with their offsets (start and end position in + /// source text). + virtual bool isStoreOffsetWithTermVector() = 0; + + /// True if terms are stored as term vector together with their token positions. + virtual bool isStorePositionWithTermVector() = 0; + + /// True if the value of the field is stored as binary. + virtual bool isBinary() = 0; + + /// True if norms are omitted for this indexed field. + virtual bool getOmitNorms() = 0; + + /// If set, omit normalization factors associated with this indexed field. + /// This effectively disables indexing boosts and length normalization for this field. + virtual void setOmitNorms(bool omitNorms) = 0; + + /// Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field + /// is lazily loaded, retrieving it's values via {@link #stringValue()} or {@link #getBinaryValue()} + /// is only valid as long as the {@link IndexReader} that retrieved the {@link Document} is still open. + /// + /// @return true if this field can be loaded lazily + virtual bool isLazy() = 0; + + /// Returns offset into byte[] segment that is used as value, if Field is not binary returned value is + /// undefined. + /// @return index of the first character in byte[] segment that represents this Field value. + virtual int32_t getBinaryOffset() = 0; + + /// Returns length of byte[] segment that is used as value, if Field is not binary returned value is + /// undefined. + /// @return length of byte[] segment that represents this Field value. + virtual int32_t getBinaryLength() = 0; + + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. + /// @return reference to the Field value as byte[]. + virtual ByteArray getBinaryValue() = 0; + + /// Return the raw byte[] for the binary field. Note that you must also call {@link #getBinaryLength} + /// and {@link #getBinaryOffset} to know which range of bytes in this returned array belong to the field. + /// + /// About reuse: if you pass in the result byte[] and it is used, likely the underlying implementation will + /// hold onto this byte[] and return it in future calls to {@link #getBinaryValue()}. So if you subsequently + /// re-use the same byte[] elsewhere it will alter this Fieldable's value. + /// @param result User defined buffer that will be used if possible. If this is null or not large enough, + /// a new buffer is allocated + /// @return reference to the Field value as byte[]. + virtual ByteArray getBinaryValue(ByteArray result) = 0; + + /// @see #setOmitTermFreqAndPositions + virtual bool getOmitTermFreqAndPositions() = 0; + + /// If set, omit term freq, positions and payloads from postings for this field. + /// + /// NOTE: While this option reduces storage space required in the index, it also means any query requiring + /// positional information, such as {@link PhraseQuery} or {@link SpanQuery} subclasses will silently fail + /// to find results. + virtual void setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) = 0; +}; + } #endif diff --git a/include/FieldsReader.h b/include/FieldsReader.h index 15227bc8..3d4d4ed1 100644 --- a/include/FieldsReader.h +++ b/include/FieldsReader.h @@ -10,132 +10,131 @@ #include "AbstractField.h" #include "CloseableThreadLocal.h" -namespace Lucene -{ - /// Class responsible for access to stored document fields. It uses .fdt and .fdx; files. - class FieldsReader : public LuceneObject - { - public: - /// Used only by clone - FieldsReader(const FieldInfosPtr& fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, int32_t formatSize, - int32_t docStoreOffset, const IndexInputPtr& cloneableFieldsStream, const IndexInputPtr& cloneableIndexStream); - FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn); - FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); +namespace Lucene { - virtual ~FieldsReader(); +/// Class responsible for access to stored document fields. It uses .fdt and .fdx; files. +class FieldsReader : public LuceneObject { +public: + /// Used only by clone + FieldsReader(const FieldInfosPtr& fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, int32_t formatSize, + int32_t docStoreOffset, const IndexInputPtr& cloneableFieldsStream, const IndexInputPtr& cloneableIndexStream); + FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn); + FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); - LUCENE_CLASS(FieldsReader); + virtual ~FieldsReader(); - protected: - FieldInfosPtr fieldInfos; + LUCENE_CLASS(FieldsReader); - // The main fieldStream, used only for cloning. - IndexInputPtr cloneableFieldsStream; +protected: + FieldInfosPtr fieldInfos; - // This is a clone of cloneableFieldsStream used for reading documents. It should not be cloned outside of a - // synchronized context. - IndexInputPtr fieldsStream; + // The main fieldStream, used only for cloning. + IndexInputPtr cloneableFieldsStream; - IndexInputPtr cloneableIndexStream; - IndexInputPtr indexStream; - int32_t numTotalDocs; - int32_t _size; - bool closed; - int32_t format; - int32_t formatSize; + // This is a clone of cloneableFieldsStream used for reading documents. It should not be cloned outside of a + // synchronized context. + IndexInputPtr fieldsStream; - // The docID offset where our docs begin in the index file. This will be 0 if we have our own private file. - int32_t docStoreOffset; + IndexInputPtr cloneableIndexStream; + IndexInputPtr indexStream; + int32_t numTotalDocs; + int32_t _size; + bool closed; + int32_t format; + int32_t formatSize; - CloseableThreadLocal fieldsStreamTL; - bool isOriginal; + // The docID offset where our docs begin in the index file. This will be 0 if we have our own private file. + int32_t docStoreOffset; - public: - /// Returns a cloned FieldsReader that shares open IndexInputs with the original one. It is the caller's job not to - /// close the original FieldsReader until all clones are called (eg, currently SegmentReader manages this logic). - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + CloseableThreadLocal fieldsStreamTL; + bool isOriginal; - /// Closes the underlying {@link IndexInput} streams, including any ones associated with a lazy implementation of a - /// Field. This means that the Fields values will not be accessible. - void close(); +public: + /// Returns a cloned FieldsReader that shares open IndexInputs with the original one. It is the caller's job not to + /// close the original FieldsReader until all clones are called (eg, currently SegmentReader manages this logic). + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - int32_t size(); + /// Closes the underlying {@link IndexInput} streams, including any ones associated with a lazy implementation of a + /// Field. This means that the Fields values will not be accessible. + void close(); - bool canReadRawDocs(); + int32_t size(); - DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); + bool canReadRawDocs(); - /// Returns the length in bytes of each raw document in a contiguous range of length numDocs starting with startDocID. - /// Returns the IndexInput (the fieldStream), already seeked to the starting point for startDocID. - IndexInputPtr rawDocs(Collection lengths, int32_t startDocID, int32_t numDocs); + DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); - protected: - void ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); + /// Returns the length in bytes of each raw document in a contiguous range of length numDocs starting with startDocID. + /// Returns the IndexInput (the fieldStream), already seeked to the starting point for startDocID. + IndexInputPtr rawDocs(Collection lengths, int32_t startDocID, int32_t numDocs); - void ensureOpen(); +protected: + void ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); - void seekIndex(int32_t docID); + void ensureOpen(); - /// Skip the field. We still have to read some of the information about the field, but can skip past the actual content. - /// This will have the most payoff on large fields. - void skipField(bool binary, bool compressed); - void skipField(bool binary, bool compressed, int32_t toRead); + void seekIndex(int32_t docID); - void addFieldLazy(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize); - void addField(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize); + /// Skip the field. We still have to read some of the information about the field, but can skip past the actual content. + /// This will have the most payoff on large fields. + void skipField(bool binary, bool compressed); + void skipField(bool binary, bool compressed, int32_t toRead); - /// Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes). - /// Read just the size - caller must skip the field content to continue reading fields. Return the size in bytes or chars, - /// depending on field type. - int32_t addFieldSize(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed); + void addFieldLazy(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize); + void addField(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize); - ByteArray uncompress(ByteArray b); - String uncompressString(ByteArray b); + /// Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes). + /// Read just the size - caller must skip the field content to continue reading fields. Return the size in bytes or chars, + /// depending on field type. + int32_t addFieldSize(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed); - friend class LazyField; - }; + ByteArray uncompress(ByteArray b); + String uncompressString(ByteArray b); - class LazyField : public AbstractField - { - public: - LazyField(const FieldsReaderPtr& reader, const String& name, Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); - LazyField(const FieldsReaderPtr& reader, const String& name, Store store, Index index, TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); - virtual ~LazyField(); + friend class LazyField; +}; - LUCENE_CLASS(LazyField); +class LazyField : public AbstractField { +public: + LazyField(const FieldsReaderPtr& reader, const String& name, Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); + LazyField(const FieldsReaderPtr& reader, const String& name, Store store, Index index, TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed); + virtual ~LazyField(); - protected: - FieldsReaderWeakPtr _reader; - int32_t toRead; - int64_t pointer; + LUCENE_CLASS(LazyField); - /// @deprecated Only kept for backward-compatibility with <3.0 indexes. - bool isCompressed; +protected: + FieldsReaderWeakPtr _reader; + int32_t toRead; + int64_t pointer; - public: - /// The value of the field as a Reader, or null. If null, the String value, binary value, or TokenStream value is used. - /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. - ReaderPtr readerValue(); + /// @deprecated Only kept for backward-compatibility with <3.0 indexes. + bool isCompressed; - /// The value of the field as a TokenStream, or null. If null, the Reader value, String value, or binary value is used. - /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. - TokenStreamPtr tokenStreamValue(); +public: + /// The value of the field as a Reader, or null. If null, the String value, binary value, or TokenStream value is used. + /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. + ReaderPtr readerValue(); - /// The value of the field as a String, or null. If null, the Reader value, binary value, or TokenStream value is used. - /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. - String stringValue(); + /// The value of the field as a TokenStream, or null. If null, the Reader value, String value, or binary value is used. + /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. + TokenStreamPtr tokenStreamValue(); - int64_t getPointer(); - void setPointer(int64_t pointer); - int32_t getToRead(); - void setToRead(int32_t toRead); + /// The value of the field as a String, or null. If null, the Reader value, binary value, or TokenStream value is used. + /// Exactly one of stringValue(), readerValue(), getBinaryValue(), and tokenStreamValue() must be set. + String stringValue(); - /// Return the raw byte[] for the binary field. - virtual ByteArray getBinaryValue(ByteArray result); + int64_t getPointer(); + void setPointer(int64_t pointer); + int32_t getToRead(); + void setToRead(int32_t toRead); + + /// Return the raw byte[] for the binary field. + virtual ByteArray getBinaryValue(ByteArray result); + +protected: + IndexInputPtr getFieldStream(); +}; - protected: - IndexInputPtr getFieldStream(); - }; } #endif diff --git a/include/FieldsWriter.h b/include/FieldsWriter.h index f5884864..70cac199 100644 --- a/include/FieldsWriter.h +++ b/include/FieldsWriter.h @@ -9,54 +9,54 @@ #include "LuceneObject.h" -namespace Lucene -{ - class FieldsWriter : public LuceneObject - { - public: - FieldsWriter(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn); - FieldsWriter(const IndexOutputPtr& fdx, const IndexOutputPtr& fdt, const FieldInfosPtr& fn); - virtual ~FieldsWriter(); - - LUCENE_CLASS(FieldsWriter); - - protected: - FieldInfosPtr fieldInfos; - IndexOutputPtr fieldsStream; - IndexOutputPtr indexStream; - bool doClose; - - public: - static const uint8_t FIELD_IS_TOKENIZED; - static const uint8_t FIELD_IS_BINARY; - static const uint8_t FIELD_IS_COMPRESSED; - - static const int32_t FORMAT; // Original format - static const int32_t FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; // Changed strings to UTF8 - static const int32_t FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS; // Lucene 3.0: Removal of compressed fields - - // NOTE: if you introduce a new format, make it 1 higher than the current one, and always change this - // if you switch to a new format! - static const int32_t FORMAT_CURRENT; - - public: - void setFieldsStream(const IndexOutputPtr& stream); - - /// Writes the contents of buffer into the fields stream and adds a new entry for this document into the index - /// stream. This assumes the buffer was already written in the correct fields format. - void flushDocument(int32_t numStoredFields, const RAMOutputStreamPtr& buffer); - - void skipDocument(); - void flush(); - void close(); - void writeField(const FieldInfoPtr& fi, const FieldablePtr& field); - - /// Bulk write a contiguous series of documents. The lengths array is the length (in bytes) of each raw document. - /// The stream IndexInput is the fieldsStream from which we should bulk-copy all bytes. - void addRawDocuments(const IndexInputPtr& stream, Collection lengths, int32_t numDocs); - - void addDocument(const DocumentPtr& doc); - }; +namespace Lucene { + +class FieldsWriter : public LuceneObject { +public: + FieldsWriter(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn); + FieldsWriter(const IndexOutputPtr& fdx, const IndexOutputPtr& fdt, const FieldInfosPtr& fn); + virtual ~FieldsWriter(); + + LUCENE_CLASS(FieldsWriter); + +protected: + FieldInfosPtr fieldInfos; + IndexOutputPtr fieldsStream; + IndexOutputPtr indexStream; + bool doClose; + +public: + static const uint8_t FIELD_IS_TOKENIZED; + static const uint8_t FIELD_IS_BINARY; + static const uint8_t FIELD_IS_COMPRESSED; + + static const int32_t FORMAT; // Original format + static const int32_t FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; // Changed strings to UTF8 + static const int32_t FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS; // Lucene 3.0: Removal of compressed fields + + // NOTE: if you introduce a new format, make it 1 higher than the current one, and always change this + // if you switch to a new format! + static const int32_t FORMAT_CURRENT; + +public: + void setFieldsStream(const IndexOutputPtr& stream); + + /// Writes the contents of buffer into the fields stream and adds a new entry for this document into the index + /// stream. This assumes the buffer was already written in the correct fields format. + void flushDocument(int32_t numStoredFields, const RAMOutputStreamPtr& buffer); + + void skipDocument(); + void flush(); + void close(); + void writeField(const FieldInfoPtr& fi, const FieldablePtr& field); + + /// Bulk write a contiguous series of documents. The lengths array is the length (in bytes) of each raw document. + /// The stream IndexInput is the fieldsStream from which we should bulk-copy all bytes. + void addRawDocuments(const IndexInputPtr& stream, Collection lengths, int32_t numDocs); + + void addDocument(const DocumentPtr& doc); +}; + } #endif diff --git a/include/FileReader.h b/include/FileReader.h index ecdf3ac5..5b26dcdc 100644 --- a/include/FileReader.h +++ b/include/FileReader.h @@ -9,46 +9,46 @@ #include "Reader.h" -namespace Lucene -{ - /// Convenience class for reading character files. - class LPPAPI FileReader : public Reader - { - public: - /// Creates a new FileReader, given the file name to read from. - FileReader(const String& fileName); - virtual ~FileReader(); - - LUCENE_CLASS(FileReader); - - protected: - ifstreamPtr file; - int64_t _length; - ByteArray fileBuffer; - - public: - static const int32_t FILE_EOF; - static const int32_t FILE_ERROR; - - public: - /// Read a single character. - virtual int32_t read(); - - /// Read characters into a portion of an array. - virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - - /// Close the stream. - virtual void close(); - - /// Tell whether this stream supports the mark() operation - virtual bool markSupported(); - - /// Reset the stream. - virtual void reset(); - - /// The number of bytes in the file. - virtual int64_t length(); - }; +namespace Lucene { + +/// Convenience class for reading character files. +class LPPAPI FileReader : public Reader { +public: + /// Creates a new FileReader, given the file name to read from. + FileReader(const String& fileName); + virtual ~FileReader(); + + LUCENE_CLASS(FileReader); + +protected: + ifstreamPtr file; + int64_t _length; + ByteArray fileBuffer; + +public: + static const int32_t FILE_EOF; + static const int32_t FILE_ERROR; + +public: + /// Read a single character. + virtual int32_t read(); + + /// Read characters into a portion of an array. + virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); + + /// Close the stream. + virtual void close(); + + /// Tell whether this stream supports the mark() operation + virtual bool markSupported(); + + /// Reset the stream. + virtual void reset(); + + /// The number of bytes in the file. + virtual int64_t length(); +}; + } #endif diff --git a/include/FileSwitchDirectory.h b/include/FileSwitchDirectory.h index da5c7c28..7cad4291 100644 --- a/include/FileSwitchDirectory.h +++ b/include/FileSwitchDirectory.h @@ -9,77 +9,77 @@ #include "Directory.h" -namespace Lucene -{ - /// A Directory instance that switches files between two other - /// Directory instances. - /// - /// Files with the specified extensions are placed in the primary - /// directory; others are placed in the secondary directory. The - /// provided Set must not change once passed to this class, and - /// must allow multiple threads to call contains at once. - class LPPAPI FileSwitchDirectory : public Directory - { - public: - FileSwitchDirectory(HashSet primaryExtensions, const DirectoryPtr& primaryDir, const DirectoryPtr& secondaryDir, bool doClose); - virtual ~FileSwitchDirectory(); - - LUCENE_CLASS(FileSwitchDirectory); - - protected: - HashSet primaryExtensions; - DirectoryPtr primaryDir; - DirectoryPtr secondaryDir; - bool doClose; - - public: - /// Return the primary directory. - DirectoryPtr getPrimaryDir(); - - /// Return the secondary directory. - DirectoryPtr getSecondaryDir(); - - /// Closes the store. - virtual void close(); - - /// Returns an array of strings, one for each file in the directory. - virtual HashSet listAll(); - - /// Utility method to return a file's extension. - static String getExtension(const String& name); - - /// Returns true if a file with the given name exists. - virtual bool fileExists(const String& name); - - /// Returns the time the named file was last modified. - virtual uint64_t fileModified(const String& name); - - /// Set the modified time of an existing file to now. - virtual void touchFile(const String& name); - - /// Removes an existing file in the directory. - virtual void deleteFile(const String& name); - - /// Returns the length of a file in the directory. - virtual int64_t fileLength(const String& name); - - /// Creates a new, empty file in the directory with the given name. - /// Returns a stream writing this file. - virtual IndexOutputPtr createOutput(const String& name); - - /// Ensure that any writes to this file are moved to stable storage. - /// Lucene uses this to properly commit changes to the index, to - /// prevent a machine/OS crash from corrupting the index. - virtual void sync(const String& name); - - /// Returns a stream reading an existing file, with the specified - /// read buffer size. The particular Directory implementation may - /// ignore the buffer size. - virtual IndexInputPtr openInput(const String& name); - - protected: - DirectoryPtr getDirectory(const String& name); - }; +namespace Lucene { + +/// A Directory instance that switches files between two other +/// Directory instances. +/// +/// Files with the specified extensions are placed in the primary +/// directory; others are placed in the secondary directory. The +/// provided Set must not change once passed to this class, and +/// must allow multiple threads to call contains at once. +class LPPAPI FileSwitchDirectory : public Directory { +public: + FileSwitchDirectory(HashSet primaryExtensions, const DirectoryPtr& primaryDir, const DirectoryPtr& secondaryDir, bool doClose); + virtual ~FileSwitchDirectory(); + + LUCENE_CLASS(FileSwitchDirectory); + +protected: + HashSet primaryExtensions; + DirectoryPtr primaryDir; + DirectoryPtr secondaryDir; + bool doClose; + +public: + /// Return the primary directory. + DirectoryPtr getPrimaryDir(); + + /// Return the secondary directory. + DirectoryPtr getSecondaryDir(); + + /// Closes the store. + virtual void close(); + + /// Returns an array of strings, one for each file in the directory. + virtual HashSet listAll(); + + /// Utility method to return a file's extension. + static String getExtension(const String& name); + + /// Returns true if a file with the given name exists. + virtual bool fileExists(const String& name); + + /// Returns the time the named file was last modified. + virtual uint64_t fileModified(const String& name); + + /// Set the modified time of an existing file to now. + virtual void touchFile(const String& name); + + /// Removes an existing file in the directory. + virtual void deleteFile(const String& name); + + /// Returns the length of a file in the directory. + virtual int64_t fileLength(const String& name); + + /// Creates a new, empty file in the directory with the given name. + /// Returns a stream writing this file. + virtual IndexOutputPtr createOutput(const String& name); + + /// Ensure that any writes to this file are moved to stable storage. + /// Lucene uses this to properly commit changes to the index, to + /// prevent a machine/OS crash from corrupting the index. + virtual void sync(const String& name); + + /// Returns a stream reading an existing file, with the specified + /// read buffer size. The particular Directory implementation may + /// ignore the buffer size. + virtual IndexInputPtr openInput(const String& name); + +protected: + DirectoryPtr getDirectory(const String& name); +}; + } #endif diff --git a/include/FileUtils.h b/include/FileUtils.h index 27b9f070..da3021a4 100644 --- a/include/FileUtils.h +++ b/include/FileUtils.h @@ -9,58 +9,59 @@ #include "Lucene.h" -namespace Lucene -{ - namespace FileUtils - { - /// Return true if given file or directory exists. - LPPAPI bool fileExists(const String& path); +namespace Lucene { - /// Return file last modified date and time. - LPPAPI uint64_t fileModified(const String& path); +namespace FileUtils { - /// Set file last modified date and time to now. - LPPAPI bool touchFile(const String& path); +/// Return true if given file or directory exists. +LPPAPI bool fileExists(const String& path); - /// Return file length in bytes. - LPPAPI int64_t fileLength(const String& path); +/// Return file last modified date and time. +LPPAPI uint64_t fileModified(const String& path); - /// Set new file length, truncating or expanding as required. - LPPAPI bool setFileLength(const String& path, int64_t length); +/// Set file last modified date and time to now. +LPPAPI bool touchFile(const String& path); - /// Delete file from file system. - LPPAPI bool removeFile(const String& path); +/// Return file length in bytes. +LPPAPI int64_t fileLength(const String& path); - /// Copy a file to/from file system. - LPPAPI bool copyFile(const String& source, const String& dest); +/// Set new file length, truncating or expanding as required. +LPPAPI bool setFileLength(const String& path, int64_t length); - /// Create new directory under given location. - LPPAPI bool createDirectory(const String& path); +/// Delete file from file system. +LPPAPI bool removeFile(const String& path); - /// Delete directory from file system. - LPPAPI bool removeDirectory(const String& path); +/// Copy a file to/from file system. +LPPAPI bool copyFile(const String& source, const String& dest); - /// Return true if given path points to a directory. - LPPAPI bool isDirectory(const String& path); +/// Create new directory under given location. +LPPAPI bool createDirectory(const String& path); - /// Return list of files (and/or directories) under given directory. - /// @param path path to list directory. - /// @param filesOnly if true the exclude sub-directories. - /// @param dirList list of files to return. - LPPAPI bool listDirectory(const String& path, bool filesOnly, HashSet dirList); +/// Delete directory from file system. +LPPAPI bool removeDirectory(const String& path); - /// Copy a directory to/from file system. - LPPAPI bool copyDirectory(const String& source, const String& dest); +/// Return true if given path points to a directory. +LPPAPI bool isDirectory(const String& path); - /// Return complete path after joining given directory and file name. - LPPAPI String joinPath(const String& path, const String& file); +/// Return list of files (and/or directories) under given directory. +/// @param path path to list directory. +/// @param filesOnly if true the exclude sub-directories. +/// @param dirList list of files to return. +LPPAPI bool listDirectory(const String& path, bool filesOnly, HashSet dirList); - /// Extract parent path from given path. - LPPAPI String extractPath(const String& path); +/// Copy a directory to/from file system. +LPPAPI bool copyDirectory(const String& source, const String& dest); + +/// Return complete path after joining given directory and file name. +LPPAPI String joinPath(const String& path, const String& file); + +/// Extract parent path from given path. +LPPAPI String extractPath(const String& path); + +/// Extract file name from given path. +LPPAPI String extractFile(const String& path); +} - /// Extract file name from given path. - LPPAPI String extractFile(const String& path); - } } #endif diff --git a/include/Filter.h b/include/Filter.h index f8e1acab..e4a5af47 100644 --- a/include/Filter.h +++ b/include/Filter.h @@ -9,32 +9,32 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Abstract base class for restricting which documents may be returned during searching. - class LPPAPI Filter : public LuceneObject - { - public: - virtual ~Filter(); - LUCENE_CLASS(Filter); +namespace Lucene { + +/// Abstract base class for restricting which documents may be returned during searching. +class LPPAPI Filter : public LuceneObject { +public: + virtual ~Filter(); + LUCENE_CLASS(Filter); + +public: + /// Creates a {@link DocIdSet} enumerating the documents that should be permitted in search results. + /// + /// Note: null can be returned if no documents are accepted by this Filter. + /// + /// Note: This method will be called once per segment in the index during searching. The returned + /// {@link DocIdSet} must refer to document IDs for that segment, not for the top-level reader. + /// + /// @param reader a {@link IndexReader} instance opened on the index currently searched on. Note, + /// it is likely that the provided reader does not represent the whole underlying index ie. if the + /// index has more than one segment the given reader only represents a single segment. + /// @return a DocIdSet that provides the documents which should be permitted or prohibited in search + /// results. NOTE: null can be returned if no documents will be accepted by this Filter. + /// + /// @see DocIdBitSet + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) = 0; +}; - public: - /// Creates a {@link DocIdSet} enumerating the documents that should be permitted in search results. - /// - /// Note: null can be returned if no documents are accepted by this Filter. - /// - /// Note: This method will be called once per segment in the index during searching. The returned - /// {@link DocIdSet} must refer to document IDs for that segment, not for the top-level reader. - /// - /// @param reader a {@link IndexReader} instance opened on the index currently searched on. Note, - /// it is likely that the provided reader does not represent the whole underlying index ie. if the - /// index has more than one segment the given reader only represents a single segment. - /// @return a DocIdSet that provides the documents which should be permitted or prohibited in search - /// results. NOTE: null can be returned if no documents will be accepted by this Filter. - /// - /// @see DocIdBitSet - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) = 0; - }; } #endif diff --git a/include/FilterIndexReader.h b/include/FilterIndexReader.h index 7a78f6ca..ebf58528 100644 --- a/include/FilterIndexReader.h +++ b/include/FilterIndexReader.h @@ -11,129 +11,126 @@ #include "TermPositions.h" #include "TermEnum.h" -namespace Lucene -{ - /// A FilterIndexReader contains another IndexReader, which it uses as its basic source of data, possibly - /// transforming the data along the way or providing additional functionality. The class FilterIndexReader - /// itself simply implements all abstract methods of IndexReader with versions that pass all requests to - /// the contained index reader. Subclasses of FilterIndexReader may further override some of these methods - /// and may also provide additional methods and fields. - class LPPAPI FilterIndexReader : public IndexReader - { - public: - /// Construct a FilterIndexReader based on the specified base reader. Directory locking for delete, - /// undeleteAll, and setNorm operations is left to the base reader. - /// - /// Note that base reader is closed if this FilterIndexReader is closed. - /// @param in specified base reader. - FilterIndexReader(const IndexReaderPtr& in); - - virtual ~FilterIndexReader(); - - LUCENE_CLASS(FilterIndexReader); - - protected: - IndexReaderPtr in; - - public: - virtual DirectoryPtr directory(); - virtual Collection getTermFreqVectors(int32_t docNumber); - virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); - virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); - virtual int32_t numDocs(); - virtual int32_t maxDoc(); - virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); - virtual bool isDeleted(int32_t n); - virtual bool hasDeletions(); - virtual bool hasNorms(const String& field); - virtual ByteArray norms(const String& field); - virtual void norms(const String& field, ByteArray norms, int32_t offset); - virtual TermEnumPtr terms(); - virtual TermEnumPtr terms(const TermPtr& t); - virtual int32_t docFreq(const TermPtr& t); - virtual TermDocsPtr termDocs(); - virtual TermDocsPtr termDocs(const TermPtr& term); - virtual TermPositionsPtr termPositions(); - virtual HashSet getFieldNames(FieldOption fieldOption); - virtual int64_t getVersion(); - virtual bool isCurrent(); - virtual bool isOptimized(); - virtual Collection getSequentialSubReaders(); - - /// If the subclass of FilteredIndexReader modifies the contents of the FieldCache, you must - /// override this method to provide a different key - virtual LuceneObjectPtr getFieldCacheKey(); - - /// If the subclass of FilteredIndexReader modifies the deleted docs, you must override this - /// method to provide a different key - virtual LuceneObjectPtr getDeletesCacheKey(); - - protected: - virtual void doUndeleteAll(); - virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - virtual void doDelete(int32_t docNum); - virtual void doCommit(MapStringString commitUserData); - virtual void doClose(); - }; - - /// Base class for filtering {@link TermDocs} implementations. - class LPPAPI FilterTermDocs : public TermPositions, public LuceneObject - { - public: - FilterTermDocs(const TermDocsPtr& in); - virtual ~FilterTermDocs(); - - LUCENE_CLASS(FilterTermDocs); - - protected: - TermDocsPtr in; - - public: - virtual void seek(const TermPtr& term); - virtual void seek(const TermEnumPtr& termEnum); - virtual int32_t doc(); - virtual int32_t freq(); - virtual bool next(); - virtual int32_t read(Collection docs, Collection freqs); - virtual bool skipTo(int32_t target); - virtual void close(); - }; - - /// Base class for filtering {@link TermPositions} implementations. - class LPPAPI FilterTermPositions : public FilterTermDocs - { - public: - FilterTermPositions(const TermPositionsPtr& in); - virtual ~FilterTermPositions(); - - LUCENE_CLASS(FilterTermPositions); - - public: - virtual int32_t nextPosition(); - virtual int32_t getPayloadLength(); - virtual ByteArray getPayload(ByteArray data, int32_t offset); - virtual bool isPayloadAvailable(); - }; - - /// Base class for filtering {@link TermEnum} implementations. - class LPPAPI FilterTermEnum : public TermEnum - { - public: - FilterTermEnum(const TermEnumPtr& in); - virtual ~FilterTermEnum(); - - LUCENE_CLASS(FilterTermEnum); - - protected: - TermEnumPtr in; - - public: - virtual bool next(); - virtual TermPtr term(); - virtual int32_t docFreq(); - virtual void close(); - }; +namespace Lucene { + +/// A FilterIndexReader contains another IndexReader, which it uses as its basic source of data, possibly +/// transforming the data along the way or providing additional functionality. The class FilterIndexReader +/// itself simply implements all abstract methods of IndexReader with versions that pass all requests to +/// the contained index reader. Subclasses of FilterIndexReader may further override some of these methods +/// and may also provide additional methods and fields. +class LPPAPI FilterIndexReader : public IndexReader { +public: + /// Construct a FilterIndexReader based on the specified base reader. Directory locking for delete, + /// undeleteAll, and setNorm operations is left to the base reader. + /// + /// Note that base reader is closed if this FilterIndexReader is closed. + /// @param in specified base reader. + FilterIndexReader(const IndexReaderPtr& in); + + virtual ~FilterIndexReader(); + + LUCENE_CLASS(FilterIndexReader); + +protected: + IndexReaderPtr in; + +public: + virtual DirectoryPtr directory(); + virtual Collection getTermFreqVectors(int32_t docNumber); + virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); + virtual int32_t numDocs(); + virtual int32_t maxDoc(); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); + virtual bool isDeleted(int32_t n); + virtual bool hasDeletions(); + virtual bool hasNorms(const String& field); + virtual ByteArray norms(const String& field); + virtual void norms(const String& field, ByteArray norms, int32_t offset); + virtual TermEnumPtr terms(); + virtual TermEnumPtr terms(const TermPtr& t); + virtual int32_t docFreq(const TermPtr& t); + virtual TermDocsPtr termDocs(); + virtual TermDocsPtr termDocs(const TermPtr& term); + virtual TermPositionsPtr termPositions(); + virtual HashSet getFieldNames(FieldOption fieldOption); + virtual int64_t getVersion(); + virtual bool isCurrent(); + virtual bool isOptimized(); + virtual Collection getSequentialSubReaders(); + + /// If the subclass of FilteredIndexReader modifies the contents of the FieldCache, you must + /// override this method to provide a different key + virtual LuceneObjectPtr getFieldCacheKey(); + + /// If the subclass of FilteredIndexReader modifies the deleted docs, you must override this + /// method to provide a different key + virtual LuceneObjectPtr getDeletesCacheKey(); + +protected: + virtual void doUndeleteAll(); + virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + virtual void doDelete(int32_t docNum); + virtual void doCommit(MapStringString commitUserData); + virtual void doClose(); +}; + +/// Base class for filtering {@link TermDocs} implementations. +class LPPAPI FilterTermDocs : public TermPositions, public LuceneObject { +public: + FilterTermDocs(const TermDocsPtr& in); + virtual ~FilterTermDocs(); + + LUCENE_CLASS(FilterTermDocs); + +protected: + TermDocsPtr in; + +public: + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); + virtual int32_t doc(); + virtual int32_t freq(); + virtual bool next(); + virtual int32_t read(Collection docs, Collection freqs); + virtual bool skipTo(int32_t target); + virtual void close(); +}; + +/// Base class for filtering {@link TermPositions} implementations. +class LPPAPI FilterTermPositions : public FilterTermDocs { +public: + FilterTermPositions(const TermPositionsPtr& in); + virtual ~FilterTermPositions(); + + LUCENE_CLASS(FilterTermPositions); + +public: + virtual int32_t nextPosition(); + virtual int32_t getPayloadLength(); + virtual ByteArray getPayload(ByteArray data, int32_t offset); + virtual bool isPayloadAvailable(); +}; + +/// Base class for filtering {@link TermEnum} implementations. +class LPPAPI FilterTermEnum : public TermEnum { +public: + FilterTermEnum(const TermEnumPtr& in); + virtual ~FilterTermEnum(); + + LUCENE_CLASS(FilterTermEnum); + +protected: + TermEnumPtr in; + +public: + virtual bool next(); + virtual TermPtr term(); + virtual int32_t docFreq(); + virtual void close(); +}; + } #endif diff --git a/include/FilterManager.h b/include/FilterManager.h index 692153f1..4c10988a 100644 --- a/include/FilterManager.h +++ b/include/FilterManager.h @@ -9,63 +9,63 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Filter caching singleton. It can be used to save filters locally for reuse. Also could be used as a - /// persistent storage for any filter as long as the filter provides a proper hashCode(), as that is used - /// as the key in the cache. - /// - /// The cache is periodically cleaned up from a separate thread to ensure the cache doesn't exceed the - /// maximum size. - class LPPAPI FilterManager : public LuceneObject - { - public: - /// Sets up the FilterManager singleton. - FilterManager(); - virtual ~FilterManager(); - - LUCENE_CLASS(FilterManager); - - protected: - /// The default maximum number of Filters in the cache - static const int32_t DEFAULT_CACHE_CLEAN_SIZE; - - /// The default frequency of cache cleanup - static const int64_t DEFAULT_CACHE_SLEEP_TIME; - - /// The cache itself - MapIntFilterItem cache; - - /// Maximum allowed cache size - int32_t cacheCleanSize; - - /// Cache cleaning frequency - int64_t cleanSleepTime; - - /// Cache cleaner that runs in a separate thread - FilterCleanerPtr filterCleaner; - - public: - virtual void initialize(); - - static FilterManagerPtr getInstance(); - - /// Sets the max size that cache should reach before it is cleaned up - /// @param cacheCleanSize maximum allowed cache size - void setCacheSize(int32_t cacheCleanSize); - - /// Sets the cache cleaning frequency in milliseconds. - /// @param cleanSleepTime cleaning frequency in milliseconds - void setCleanThreadSleepTime(int64_t cleanSleepTime); - - /// Returns the cached version of the filter. Allows the caller to pass up a small filter but this will - /// keep a persistent version around and allow the caching filter to do its job. - /// @param filter The input filter - /// @return The cached version of the filter - FilterPtr getFilter(const FilterPtr& filter); - - friend class FilterCleaner; - }; +namespace Lucene { + +/// Filter caching singleton. It can be used to save filters locally for reuse. Also could be used as a +/// persistent storage for any filter as long as the filter provides a proper hashCode(), as that is used +/// as the key in the cache. +/// +/// The cache is periodically cleaned up from a separate thread to ensure the cache doesn't exceed the +/// maximum size. +class LPPAPI FilterManager : public LuceneObject { +public: + /// Sets up the FilterManager singleton. + FilterManager(); + virtual ~FilterManager(); + + LUCENE_CLASS(FilterManager); + +protected: + /// The default maximum number of Filters in the cache + static const int32_t DEFAULT_CACHE_CLEAN_SIZE; + + /// The default frequency of cache cleanup + static const int64_t DEFAULT_CACHE_SLEEP_TIME; + + /// The cache itself + MapIntFilterItem cache; + + /// Maximum allowed cache size + int32_t cacheCleanSize; + + /// Cache cleaning frequency + int64_t cleanSleepTime; + + /// Cache cleaner that runs in a separate thread + FilterCleanerPtr filterCleaner; + +public: + virtual void initialize(); + + static FilterManagerPtr getInstance(); + + /// Sets the max size that cache should reach before it is cleaned up + /// @param cacheCleanSize maximum allowed cache size + void setCacheSize(int32_t cacheCleanSize); + + /// Sets the cache cleaning frequency in milliseconds. + /// @param cleanSleepTime cleaning frequency in milliseconds + void setCleanThreadSleepTime(int64_t cleanSleepTime); + + /// Returns the cached version of the filter. Allows the caller to pass up a small filter but this will + /// keep a persistent version around and allow the caching filter to do its job. + /// @param filter The input filter + /// @return The cached version of the filter + FilterPtr getFilter(const FilterPtr& filter); + + friend class FilterCleaner; +}; + } #endif diff --git a/include/FilteredDocIdSet.h b/include/FilteredDocIdSet.h index 8b498bc5..70c8e615 100644 --- a/include/FilteredDocIdSet.h +++ b/include/FilteredDocIdSet.h @@ -9,46 +9,46 @@ #include "DocIdSet.h" -namespace Lucene -{ - /// Abstract decorator class for a DocIdSet implementation that provides on-demand filtering/validation - /// mechanism on a given DocIdSet. - /// - /// Technically, this same functionality could be achieved with ChainedFilter (under contrib/misc), however - /// the benefit of this class is it never materializes the full bitset for the filter. Instead, the {@link - /// #match} method is invoked on-demand, per docID visited during searching. If you know few docIDs will - /// be visited, and the logic behind {@link #match} is relatively costly, this may be a better way to filter - /// than ChainedFilter. - /// @see DocIdSet - class LPPAPI FilteredDocIdSet : public DocIdSet - { - public: - /// @param innerSet Underlying DocIdSet - FilteredDocIdSet(const DocIdSetPtr& innerSet); - virtual ~FilteredDocIdSet(); - - LUCENE_CLASS(FilteredDocIdSet); - - protected: - DocIdSetPtr innerSet; - - public: - /// This DocIdSet implementation is cacheable if the inner set is cacheable. - virtual bool isCacheable(); - - /// Implementation of the contract to build a DocIdSetIterator. - /// @see DocIdSetIterator - /// @see FilteredDocIdSetIterator - virtual DocIdSetIteratorPtr iterator(); - - protected: - /// Validation method to determine whether a docid should be in the result set. - /// @param docid docid to be tested - /// @return true if input docid should be in the result set, false otherwise. - virtual bool match(int32_t docid) = 0; - - friend class DefaultFilteredDocIdSetIterator; - }; +namespace Lucene { + +/// Abstract decorator class for a DocIdSet implementation that provides on-demand filtering/validation +/// mechanism on a given DocIdSet. +/// +/// Technically, this same functionality could be achieved with ChainedFilter (under contrib/misc), however +/// the benefit of this class is it never materializes the full bitset for the filter. Instead, the {@link +/// #match} method is invoked on-demand, per docID visited during searching. If you know few docIDs will +/// be visited, and the logic behind {@link #match} is relatively costly, this may be a better way to filter +/// than ChainedFilter. +/// @see DocIdSet +class LPPAPI FilteredDocIdSet : public DocIdSet { +public: + /// @param innerSet Underlying DocIdSet + FilteredDocIdSet(const DocIdSetPtr& innerSet); + virtual ~FilteredDocIdSet(); + + LUCENE_CLASS(FilteredDocIdSet); + +protected: + DocIdSetPtr innerSet; + +public: + /// This DocIdSet implementation is cacheable if the inner set is cacheable. + virtual bool isCacheable(); + + /// Implementation of the contract to build a DocIdSetIterator. + /// @see DocIdSetIterator + /// @see FilteredDocIdSetIterator + virtual DocIdSetIteratorPtr iterator(); + +protected: + /// Validation method to determine whether a docid should be in the result set. + /// @param docid docid to be tested + /// @return true if input docid should be in the result set, false otherwise. + virtual bool match(int32_t docid) = 0; + + friend class DefaultFilteredDocIdSetIterator; +}; + } #endif diff --git a/include/FilteredDocIdSetIterator.h b/include/FilteredDocIdSetIterator.h index 64761cb9..43165e45 100644 --- a/include/FilteredDocIdSetIterator.h +++ b/include/FilteredDocIdSetIterator.h @@ -9,35 +9,35 @@ #include "DocIdSetIterator.h" -namespace Lucene -{ - /// Abstract decorator class of a DocIdSetIterator implementation that provides on-demand filter/validation - /// mechanism on an underlying DocIdSetIterator. See {@link FilteredDocIdSet}. - class LPPAPI FilteredDocIdSetIterator : public DocIdSetIterator - { - public: - /// @param innerIter Underlying DocIdSetIterator. - FilteredDocIdSetIterator(const DocIdSetIteratorPtr& innerIter); - virtual ~FilteredDocIdSetIterator(); - - LUCENE_CLASS(FilteredDocIdSetIterator); - - protected: - DocIdSetIteratorPtr innerIter; - int32_t doc; - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - - protected: - /// Validation method to determine whether a docid should be in the result set. - /// @param doc docid to be tested - /// @return true if input docid should be in the result set, false otherwise. - /// @see #FilteredDocIdSetIterator(DocIdSetIterator). - virtual bool match(int32_t docid) = 0; - }; +namespace Lucene { + +/// Abstract decorator class of a DocIdSetIterator implementation that provides on-demand filter/validation +/// mechanism on an underlying DocIdSetIterator. See {@link FilteredDocIdSet}. +class LPPAPI FilteredDocIdSetIterator : public DocIdSetIterator { +public: + /// @param innerIter Underlying DocIdSetIterator. + FilteredDocIdSetIterator(const DocIdSetIteratorPtr& innerIter); + virtual ~FilteredDocIdSetIterator(); + + LUCENE_CLASS(FilteredDocIdSetIterator); + +protected: + DocIdSetIteratorPtr innerIter; + int32_t doc; + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); + +protected: + /// Validation method to determine whether a docid should be in the result set. + /// @param doc docid to be tested + /// @return true if input docid should be in the result set, false otherwise. + /// @see #FilteredDocIdSetIterator(DocIdSetIterator). + virtual bool match(int32_t docid) = 0; +}; + } #endif diff --git a/include/FilteredQuery.h b/include/FilteredQuery.h index 32c5af4b..ed33e059 100644 --- a/include/FilteredQuery.h +++ b/include/FilteredQuery.h @@ -9,55 +9,55 @@ #include "Query.h" -namespace Lucene -{ - /// A query that applies a filter to the results of another query. - /// - /// Note: the bits are retrieved from the filter each time this query is used in a search - use a - /// CachingWrapperFilter to avoid regenerating the bits every time. - /// - /// @see CachingWrapperFilter - class LPPAPI FilteredQuery : public Query - { - public: - /// Constructs a new query which applies a filter to the results of the original query. - /// Filter::getDocIdSet() will be called every time this query is used in a search. - /// @param query Query to be filtered, cannot be null. - /// @param filter Filter to apply to query results, cannot be null. - FilteredQuery(const QueryPtr& query, const FilterPtr& filter); - - virtual ~FilteredQuery(); - - LUCENE_CLASS(FilteredQuery); - - private: - QueryPtr query; - FilterPtr filter; - - public: - using Query::toString; - - /// Returns a Weight that applies the filter to the enclosed query's Weight. - /// This is accomplished by overriding the Scorer returned by the Weight. - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - /// Rewrites the wrapped query. - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - QueryPtr getQuery(); - FilterPtr getFilter(); - - virtual void extractTerms(SetTerm terms); - - /// Prints a user-readable version of this query. - virtual String toString(const String& field); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - friend class FilteredQueryWeight; - }; +namespace Lucene { + +/// A query that applies a filter to the results of another query. +/// +/// Note: the bits are retrieved from the filter each time this query is used in a search - use a +/// CachingWrapperFilter to avoid regenerating the bits every time. +/// +/// @see CachingWrapperFilter +class LPPAPI FilteredQuery : public Query { +public: + /// Constructs a new query which applies a filter to the results of the original query. + /// Filter::getDocIdSet() will be called every time this query is used in a search. + /// @param query Query to be filtered, cannot be null. + /// @param filter Filter to apply to query results, cannot be null. + FilteredQuery(const QueryPtr& query, const FilterPtr& filter); + + virtual ~FilteredQuery(); + + LUCENE_CLASS(FilteredQuery); + +private: + QueryPtr query; + FilterPtr filter; + +public: + using Query::toString; + + /// Returns a Weight that applies the filter to the enclosed query's Weight. + /// This is accomplished by overriding the Scorer returned by the Weight. + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + /// Rewrites the wrapped query. + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + QueryPtr getQuery(); + FilterPtr getFilter(); + + virtual void extractTerms(SetTerm terms); + + /// Prints a user-readable version of this query. + virtual String toString(const String& field); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + friend class FilteredQueryWeight; +}; + } #endif diff --git a/include/FilteredTermEnum.h b/include/FilteredTermEnum.h index c3d7d858..0da4f2ce 100644 --- a/include/FilteredTermEnum.h +++ b/include/FilteredTermEnum.h @@ -9,54 +9,54 @@ #include "TermEnum.h" -namespace Lucene -{ - /// Abstract class for enumerating a subset of all terms. - /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than - /// all that precede it. - class LPPAPI FilteredTermEnum : public TermEnum - { - public: - virtual ~FilteredTermEnum(); - LUCENE_CLASS(FilteredTermEnum); - - protected: - /// The current term - TermPtr currentTerm; - - /// The delegate enum - to set this member use {@link #setEnum} - TermEnumPtr actualEnum; - - public: - /// Equality measure on the term - virtual double difference() = 0; - - /// Returns the docFreq of the current Term in the enumeration. - /// Returns -1 if no Term matches or all terms have been enumerated. - virtual int32_t docFreq(); - - /// Increments the enumeration to the next element. True if one exists. - virtual bool next(); - - /// Returns the current Term in the enumeration. - /// Returns null if no Term matches or all terms have been enumerated. - virtual TermPtr term(); - - /// Closes the enumeration to further activity, freeing resources. - virtual void close(); - - protected: - /// Equality compare on the term - virtual bool termCompare(const TermPtr& term) = 0; - - /// Indicates the end of the enumeration has been reached - virtual bool endEnum() = 0; - - /// Use this method to set the actual TermEnum (eg. in ctor), it will be automatically positioned - /// on the first matching term. - virtual void setEnum(const TermEnumPtr& actualEnum); - }; +namespace Lucene { + +/// Abstract class for enumerating a subset of all terms. +/// +/// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than +/// all that precede it. +class LPPAPI FilteredTermEnum : public TermEnum { +public: + virtual ~FilteredTermEnum(); + LUCENE_CLASS(FilteredTermEnum); + +protected: + /// The current term + TermPtr currentTerm; + + /// The delegate enum - to set this member use {@link #setEnum} + TermEnumPtr actualEnum; + +public: + /// Equality measure on the term + virtual double difference() = 0; + + /// Returns the docFreq of the current Term in the enumeration. + /// Returns -1 if no Term matches or all terms have been enumerated. + virtual int32_t docFreq(); + + /// Increments the enumeration to the next element. True if one exists. + virtual bool next(); + + /// Returns the current Term in the enumeration. + /// Returns null if no Term matches or all terms have been enumerated. + virtual TermPtr term(); + + /// Closes the enumeration to further activity, freeing resources. + virtual void close(); + +protected: + /// Equality compare on the term + virtual bool termCompare(const TermPtr& term) = 0; + + /// Indicates the end of the enumeration has been reached + virtual bool endEnum() = 0; + + /// Use this method to set the actual TermEnum (eg. in ctor), it will be automatically positioned + /// on the first matching term. + virtual void setEnum(const TermEnumPtr& actualEnum); +}; + } #endif diff --git a/include/FlagsAttribute.h b/include/FlagsAttribute.h index 974b8cf9..572cadf5 100644 --- a/include/FlagsAttribute.h +++ b/include/FlagsAttribute.h @@ -9,39 +9,39 @@ #include "Attribute.h" -namespace Lucene -{ - /// This attribute can be used to pass different flags down the tokenizer chain, eg from one TokenFilter - /// to another one. - class LPPAPI FlagsAttribute : public Attribute - { - public: - FlagsAttribute(); - virtual ~FlagsAttribute(); - - LUCENE_CLASS(FlagsAttribute); - - protected: - int32_t flags; - - public: - virtual String toString(); - - /// Get the bitset for any bits that have been set. This is completely distinct from {@link - /// TypeAttribute#type()}, although they do share similar purposes. The flags can be used to encode - /// information about the token for use by other {@link TokenFilter}s. - virtual int32_t getFlags(); - - /// @see #getFlags() - virtual void setFlags(int32_t flags); - - virtual void clear(); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual void copyTo(const AttributePtr& target); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// This attribute can be used to pass different flags down the tokenizer chain, eg from one TokenFilter +/// to another one. +class LPPAPI FlagsAttribute : public Attribute { +public: + FlagsAttribute(); + virtual ~FlagsAttribute(); + + LUCENE_CLASS(FlagsAttribute); + +protected: + int32_t flags; + +public: + virtual String toString(); + + /// Get the bitset for any bits that have been set. This is completely distinct from {@link + /// TypeAttribute#type()}, although they do share similar purposes. The flags can be used to encode + /// information about the token for use by other {@link TokenFilter}s. + virtual int32_t getFlags(); + + /// @see #getFlags() + virtual void setFlags(int32_t flags); + + virtual void clear(); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/include/FormatPostingsDocsConsumer.h b/include/FormatPostingsDocsConsumer.h index 44ffb1c8..59d4d06a 100644 --- a/include/FormatPostingsDocsConsumer.h +++ b/include/FormatPostingsDocsConsumer.h @@ -9,22 +9,22 @@ #include "LuceneObject.h" -namespace Lucene -{ - class FormatPostingsDocsConsumer : public LuceneObject - { - public: - virtual ~FormatPostingsDocsConsumer(); - - LUCENE_CLASS(FormatPostingsDocsConsumer); - - public: - /// Adds a new doc in this term. If this returns null then we just skip consuming positions/payloads. - virtual FormatPostingsPositionsConsumerPtr addDoc(int32_t docID, int32_t termDocFreq) = 0; - - /// Called when we are done adding docs to this term - virtual void finish() = 0; - }; +namespace Lucene { + +class FormatPostingsDocsConsumer : public LuceneObject { +public: + virtual ~FormatPostingsDocsConsumer(); + + LUCENE_CLASS(FormatPostingsDocsConsumer); + +public: + /// Adds a new doc in this term. If this returns null then we just skip consuming positions/payloads. + virtual FormatPostingsPositionsConsumerPtr addDoc(int32_t docID, int32_t termDocFreq) = 0; + + /// Called when we are done adding docs to this term + virtual void finish() = 0; +}; + } #endif diff --git a/include/FormatPostingsDocsWriter.h b/include/FormatPostingsDocsWriter.h index 9b97d213..771396a3 100644 --- a/include/FormatPostingsDocsWriter.h +++ b/include/FormatPostingsDocsWriter.h @@ -9,50 +9,50 @@ #include "FormatPostingsDocsConsumer.h" -namespace Lucene -{ - /// Consumes doc & freq, writing them using the current index file format - class FormatPostingsDocsWriter : public FormatPostingsDocsConsumer - { - public: - FormatPostingsDocsWriter(const SegmentWriteStatePtr& state, const FormatPostingsTermsWriterPtr& parent); - virtual ~FormatPostingsDocsWriter(); - - LUCENE_CLASS(FormatPostingsDocsWriter); - - public: - IndexOutputPtr out; - FormatPostingsTermsWriterWeakPtr _parent; - SegmentWriteStatePtr state; - FormatPostingsPositionsWriterPtr posWriter; - DefaultSkipListWriterPtr skipListWriter; - int32_t skipInterval; - int32_t totalNumDocs; - - bool omitTermFreqAndPositions; - bool storePayloads; - int64_t freqStart; - FieldInfoPtr fieldInfo; - - int32_t lastDocID; - int32_t df; - - TermInfoPtr termInfo; // minimize consing - UTF8ResultPtr utf8; - - public: - virtual void initialize(); - - void setField(const FieldInfoPtr& fieldInfo); - - /// Adds a new doc in this term. If this returns null then we just skip consuming positions/payloads. - virtual FormatPostingsPositionsConsumerPtr addDoc(int32_t docID, int32_t termDocFreq); - - /// Called when we are done adding docs to this term - virtual void finish(); - - void close(); - }; +namespace Lucene { + +/// Consumes doc & freq, writing them using the current index file format +class FormatPostingsDocsWriter : public FormatPostingsDocsConsumer { +public: + FormatPostingsDocsWriter(const SegmentWriteStatePtr& state, const FormatPostingsTermsWriterPtr& parent); + virtual ~FormatPostingsDocsWriter(); + + LUCENE_CLASS(FormatPostingsDocsWriter); + +public: + IndexOutputPtr out; + FormatPostingsTermsWriterWeakPtr _parent; + SegmentWriteStatePtr state; + FormatPostingsPositionsWriterPtr posWriter; + DefaultSkipListWriterPtr skipListWriter; + int32_t skipInterval; + int32_t totalNumDocs; + + bool omitTermFreqAndPositions; + bool storePayloads; + int64_t freqStart; + FieldInfoPtr fieldInfo; + + int32_t lastDocID; + int32_t df; + + TermInfoPtr termInfo; // minimize consing + UTF8ResultPtr utf8; + +public: + virtual void initialize(); + + void setField(const FieldInfoPtr& fieldInfo); + + /// Adds a new doc in this term. If this returns null then we just skip consuming positions/payloads. + virtual FormatPostingsPositionsConsumerPtr addDoc(int32_t docID, int32_t termDocFreq); + + /// Called when we are done adding docs to this term + virtual void finish(); + + void close(); +}; + } #endif diff --git a/include/FormatPostingsFieldsConsumer.h b/include/FormatPostingsFieldsConsumer.h index 51ba9c77..7cb0bdfd 100644 --- a/include/FormatPostingsFieldsConsumer.h +++ b/include/FormatPostingsFieldsConsumer.h @@ -9,24 +9,24 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Abstract API that consumes terms, doc, freq, prox and payloads postings. Concrete implementations of this - /// actually do "something" with the postings (write it into the index in a specific format). - class FormatPostingsFieldsConsumer : public LuceneObject - { - public: - virtual ~FormatPostingsFieldsConsumer(); - - LUCENE_CLASS(FormatPostingsFieldsConsumer); - - public: - /// Add a new field. - virtual FormatPostingsTermsConsumerPtr addField(const FieldInfoPtr& field) = 0; - - /// Called when we are done adding everything. - virtual void finish() = 0; - }; +namespace Lucene { + +/// Abstract API that consumes terms, doc, freq, prox and payloads postings. Concrete implementations of this +/// actually do "something" with the postings (write it into the index in a specific format). +class FormatPostingsFieldsConsumer : public LuceneObject { +public: + virtual ~FormatPostingsFieldsConsumer(); + + LUCENE_CLASS(FormatPostingsFieldsConsumer); + +public: + /// Add a new field. + virtual FormatPostingsTermsConsumerPtr addField(const FieldInfoPtr& field) = 0; + + /// Called when we are done adding everything. + virtual void finish() = 0; +}; + } #endif diff --git a/include/FormatPostingsFieldsWriter.h b/include/FormatPostingsFieldsWriter.h index 883ca365..6222cfad 100644 --- a/include/FormatPostingsFieldsWriter.h +++ b/include/FormatPostingsFieldsWriter.h @@ -9,35 +9,35 @@ #include "FormatPostingsFieldsConsumer.h" -namespace Lucene -{ - class FormatPostingsFieldsWriter : public FormatPostingsFieldsConsumer - { - public: - FormatPostingsFieldsWriter(const SegmentWriteStatePtr& state, const FieldInfosPtr& fieldInfos); - virtual ~FormatPostingsFieldsWriter(); - - LUCENE_CLASS(FormatPostingsFieldsWriter); - - public: - DirectoryPtr dir; - String segment; - TermInfosWriterPtr termsOut; - SegmentWriteStatePtr state; - FieldInfosPtr fieldInfos; - FormatPostingsTermsWriterPtr termsWriter; - DefaultSkipListWriterPtr skipListWriter; - int32_t totalNumDocs; - - public: - virtual void initialize(); - - /// Add a new field. - virtual FormatPostingsTermsConsumerPtr addField(const FieldInfoPtr& field); - - /// Called when we are done adding everything. - virtual void finish(); - }; +namespace Lucene { + +class FormatPostingsFieldsWriter : public FormatPostingsFieldsConsumer { +public: + FormatPostingsFieldsWriter(const SegmentWriteStatePtr& state, const FieldInfosPtr& fieldInfos); + virtual ~FormatPostingsFieldsWriter(); + + LUCENE_CLASS(FormatPostingsFieldsWriter); + +public: + DirectoryPtr dir; + String segment; + TermInfosWriterPtr termsOut; + SegmentWriteStatePtr state; + FieldInfosPtr fieldInfos; + FormatPostingsTermsWriterPtr termsWriter; + DefaultSkipListWriterPtr skipListWriter; + int32_t totalNumDocs; + +public: + virtual void initialize(); + + /// Add a new field. + virtual FormatPostingsTermsConsumerPtr addField(const FieldInfoPtr& field); + + /// Called when we are done adding everything. + virtual void finish(); +}; + } #endif diff --git a/include/FormatPostingsPositionsConsumer.h b/include/FormatPostingsPositionsConsumer.h index a047b975..685c73df 100644 --- a/include/FormatPostingsPositionsConsumer.h +++ b/include/FormatPostingsPositionsConsumer.h @@ -9,22 +9,22 @@ #include "LuceneObject.h" -namespace Lucene -{ - class FormatPostingsPositionsConsumer : public LuceneObject - { - public: - virtual ~FormatPostingsPositionsConsumer(); - - LUCENE_CLASS(FormatPostingsPositionsConsumer); - - public: - /// Add a new position & payload. If payloadLength > 0 you must read those bytes from the IndexInput. - virtual void addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength) = 0; - - /// Called when we are done adding positions & payloads. - virtual void finish() = 0; - }; +namespace Lucene { + +class FormatPostingsPositionsConsumer : public LuceneObject { +public: + virtual ~FormatPostingsPositionsConsumer(); + + LUCENE_CLASS(FormatPostingsPositionsConsumer); + +public: + /// Add a new position & payload. If payloadLength > 0 you must read those bytes from the IndexInput. + virtual void addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength) = 0; + + /// Called when we are done adding positions & payloads. + virtual void finish() = 0; +}; + } #endif diff --git a/include/FormatPostingsPositionsWriter.h b/include/FormatPostingsPositionsWriter.h index 729e73ba..cfcca4c9 100644 --- a/include/FormatPostingsPositionsWriter.h +++ b/include/FormatPostingsPositionsWriter.h @@ -9,37 +9,37 @@ #include "FormatPostingsPositionsConsumer.h" -namespace Lucene -{ - class FormatPostingsPositionsWriter : public FormatPostingsPositionsConsumer - { - public: - FormatPostingsPositionsWriter(const SegmentWriteStatePtr& state, const FormatPostingsDocsWriterPtr& parent); - virtual ~FormatPostingsPositionsWriter(); +namespace Lucene { - LUCENE_CLASS(FormatPostingsPositionsWriter); +class FormatPostingsPositionsWriter : public FormatPostingsPositionsConsumer { +public: + FormatPostingsPositionsWriter(const SegmentWriteStatePtr& state, const FormatPostingsDocsWriterPtr& parent); + virtual ~FormatPostingsPositionsWriter(); - public: - FormatPostingsDocsWriterWeakPtr _parent; - IndexOutputPtr out; + LUCENE_CLASS(FormatPostingsPositionsWriter); - bool omitTermFreqAndPositions; - bool storePayloads; - int32_t lastPayloadLength; +public: + FormatPostingsDocsWriterWeakPtr _parent; + IndexOutputPtr out; - int32_t lastPosition; + bool omitTermFreqAndPositions; + bool storePayloads; + int32_t lastPayloadLength; - public: - /// Add a new position & payload - virtual void addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength); + int32_t lastPosition; - void setField(const FieldInfoPtr& fieldInfo); +public: + /// Add a new position & payload + virtual void addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength); - /// Called when we are done adding positions & payloads - virtual void finish(); + void setField(const FieldInfoPtr& fieldInfo); + + /// Called when we are done adding positions & payloads + virtual void finish(); + + void close(); +}; - void close(); - }; } #endif diff --git a/include/FormatPostingsTermsConsumer.h b/include/FormatPostingsTermsConsumer.h index 3d2245b4..d3b4a743 100644 --- a/include/FormatPostingsTermsConsumer.h +++ b/include/FormatPostingsTermsConsumer.h @@ -9,26 +9,26 @@ #include "LuceneObject.h" -namespace Lucene -{ - class FormatPostingsTermsConsumer : public LuceneObject - { - public: - virtual ~FormatPostingsTermsConsumer(); - - LUCENE_CLASS(FormatPostingsTermsConsumer); - - public: - CharArray termBuffer; - - public: - /// Adds a new term in this field - virtual FormatPostingsDocsConsumerPtr addTerm(CharArray text, int32_t start) = 0; - virtual FormatPostingsDocsConsumerPtr addTerm(const String& text); - - /// Called when we are done adding terms to this field - virtual void finish() = 0; - }; +namespace Lucene { + +class FormatPostingsTermsConsumer : public LuceneObject { +public: + virtual ~FormatPostingsTermsConsumer(); + + LUCENE_CLASS(FormatPostingsTermsConsumer); + +public: + CharArray termBuffer; + +public: + /// Adds a new term in this field + virtual FormatPostingsDocsConsumerPtr addTerm(CharArray text, int32_t start) = 0; + virtual FormatPostingsDocsConsumerPtr addTerm(const String& text); + + /// Called when we are done adding terms to this field + virtual void finish() = 0; +}; + } #endif diff --git a/include/FormatPostingsTermsWriter.h b/include/FormatPostingsTermsWriter.h index f24e2eab..06b0fa47 100644 --- a/include/FormatPostingsTermsWriter.h +++ b/include/FormatPostingsTermsWriter.h @@ -9,42 +9,42 @@ #include "FormatPostingsTermsConsumer.h" -namespace Lucene -{ - class FormatPostingsTermsWriter : public FormatPostingsTermsConsumer - { - public: - FormatPostingsTermsWriter(const SegmentWriteStatePtr& state, const FormatPostingsFieldsWriterPtr& parent); - virtual ~FormatPostingsTermsWriter(); +namespace Lucene { - LUCENE_CLASS(FormatPostingsTermsWriter); +class FormatPostingsTermsWriter : public FormatPostingsTermsConsumer { +public: + FormatPostingsTermsWriter(const SegmentWriteStatePtr& state, const FormatPostingsFieldsWriterPtr& parent); + virtual ~FormatPostingsTermsWriter(); - public: - FormatPostingsFieldsWriterWeakPtr _parent; - SegmentWriteStatePtr state; - FormatPostingsDocsWriterPtr docsWriter; - TermInfosWriterPtr termsOut; - FieldInfoPtr fieldInfo; + LUCENE_CLASS(FormatPostingsTermsWriter); - CharArray currentTerm; - int32_t currentTermStart; +public: + FormatPostingsFieldsWriterWeakPtr _parent; + SegmentWriteStatePtr state; + FormatPostingsDocsWriterPtr docsWriter; + TermInfosWriterPtr termsOut; + FieldInfoPtr fieldInfo; - int64_t freqStart; - int64_t proxStart; + CharArray currentTerm; + int32_t currentTermStart; - public: - virtual void initialize(); + int64_t freqStart; + int64_t proxStart; - void setField(const FieldInfoPtr& fieldInfo); +public: + virtual void initialize(); - /// Adds a new term in this field - virtual FormatPostingsDocsConsumerPtr addTerm(CharArray text, int32_t start); + void setField(const FieldInfoPtr& fieldInfo); - /// Called when we are done adding terms to this field - virtual void finish(); + /// Adds a new term in this field + virtual FormatPostingsDocsConsumerPtr addTerm(CharArray text, int32_t start); + + /// Called when we are done adding terms to this field + virtual void finish(); + + void close(); +}; - void close(); - }; } #endif diff --git a/include/FreqProxFieldMergeState.h b/include/FreqProxFieldMergeState.h index ed9a8f69..fb61ff12 100644 --- a/include/FreqProxFieldMergeState.h +++ b/include/FreqProxFieldMergeState.h @@ -9,40 +9,40 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Used by DocumentsWriter to merge the postings from multiple ThreadStates when creating a segment - class FreqProxFieldMergeState : public LuceneObject - { - public: - FreqProxFieldMergeState(const FreqProxTermsWriterPerFieldPtr& field); - virtual ~FreqProxFieldMergeState(); - - LUCENE_CLASS(FreqProxFieldMergeState); - - public: - FreqProxTermsWriterPerFieldPtr field; - int32_t numPostings; - CharBlockPoolPtr charPool; - Collection postings; - - FreqProxTermsWriterPostingListPtr p; - CharArray text; - int32_t textOffset; - - ByteSliceReaderPtr freq; - ByteSliceReaderPtr prox; - - int32_t docID; - int32_t termFreq; - - protected: - int32_t postingUpto; - - public: - bool nextTerm(); - bool nextDoc(); - }; +namespace Lucene { + +/// Used by DocumentsWriter to merge the postings from multiple ThreadStates when creating a segment +class FreqProxFieldMergeState : public LuceneObject { +public: + FreqProxFieldMergeState(const FreqProxTermsWriterPerFieldPtr& field); + virtual ~FreqProxFieldMergeState(); + + LUCENE_CLASS(FreqProxFieldMergeState); + +public: + FreqProxTermsWriterPerFieldPtr field; + int32_t numPostings; + CharBlockPoolPtr charPool; + Collection postings; + + FreqProxTermsWriterPostingListPtr p; + CharArray text; + int32_t textOffset; + + ByteSliceReaderPtr freq; + ByteSliceReaderPtr prox; + + int32_t docID; + int32_t termFreq; + +protected: + int32_t postingUpto; + +public: + bool nextTerm(); + bool nextDoc(); +}; + } #endif diff --git a/include/FreqProxTermsWriter.h b/include/FreqProxTermsWriter.h index 64e70e8e..c037db4d 100644 --- a/include/FreqProxTermsWriter.h +++ b/include/FreqProxTermsWriter.h @@ -10,49 +10,48 @@ #include "TermsHashConsumer.h" #include "RawPostingList.h" -namespace Lucene -{ - class FreqProxTermsWriter : public TermsHashConsumer - { - public: - virtual ~FreqProxTermsWriter(); - - LUCENE_CLASS(FreqProxTermsWriter); - - protected: - ByteArray payloadBuffer; - - public: - virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread); - virtual void createPostings(Collection postings, int32_t start, int32_t count); - virtual void closeDocStore(const SegmentWriteStatePtr& state); - virtual void abort(); - virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); - - /// Walk through all unique text tokens (Posting instances) found in this field and serialize them - /// into a single RAM segment. - void appendPostings(Collection fields, const FormatPostingsFieldsConsumerPtr& consumer); - - virtual int32_t bytesPerPosting(); - - protected: - static int32_t compareText(const wchar_t* text1, int32_t pos1, const wchar_t* text2, int32_t pos2); - }; - - class FreqProxTermsWriterPostingList : public RawPostingList - { - public: - FreqProxTermsWriterPostingList(); - virtual ~FreqProxTermsWriterPostingList(); - - LUCENE_CLASS(FreqProxTermsWriterPostingList); - - public: - int32_t docFreq; // # times this term occurs in the current doc - int32_t lastDocID; // Last docID where this term occurred - int32_t lastDocCode; // Code for prior doc - int32_t lastPosition; // Last position where this term occurred - }; +namespace Lucene { + +class FreqProxTermsWriter : public TermsHashConsumer { +public: + virtual ~FreqProxTermsWriter(); + + LUCENE_CLASS(FreqProxTermsWriter); + +protected: + ByteArray payloadBuffer; + +public: + virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread); + virtual void createPostings(Collection postings, int32_t start, int32_t count); + virtual void closeDocStore(const SegmentWriteStatePtr& state); + virtual void abort(); + virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); + + /// Walk through all unique text tokens (Posting instances) found in this field and serialize them + /// into a single RAM segment. + void appendPostings(Collection fields, const FormatPostingsFieldsConsumerPtr& consumer); + + virtual int32_t bytesPerPosting(); + +protected: + static int32_t compareText(const wchar_t* text1, int32_t pos1, const wchar_t* text2, int32_t pos2); +}; + +class FreqProxTermsWriterPostingList : public RawPostingList { +public: + FreqProxTermsWriterPostingList(); + virtual ~FreqProxTermsWriterPostingList(); + + LUCENE_CLASS(FreqProxTermsWriterPostingList); + +public: + int32_t docFreq; // # times this term occurs in the current doc + int32_t lastDocID; // Last docID where this term occurred + int32_t lastDocCode; // Code for prior doc + int32_t lastPosition; // Last position where this term occurred +}; + } #endif diff --git a/include/FreqProxTermsWriterPerField.h b/include/FreqProxTermsWriterPerField.h index 3ceef1e2..c2152cd2 100644 --- a/include/FreqProxTermsWriterPerField.h +++ b/include/FreqProxTermsWriterPerField.h @@ -9,39 +9,39 @@ #include "TermsHashConsumerPerField.h" -namespace Lucene -{ - class FreqProxTermsWriterPerField : public TermsHashConsumerPerField - { - public: - FreqProxTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const FreqProxTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); - virtual ~FreqProxTermsWriterPerField(); - - LUCENE_CLASS(FreqProxTermsWriterPerField); - - public: - FreqProxTermsWriterPerThreadWeakPtr _perThread; - TermsHashPerFieldWeakPtr _termsHashPerField; - FieldInfoPtr fieldInfo; - DocStatePtr docState; - FieldInvertStatePtr fieldState; - bool omitTermFreqAndPositions; - PayloadAttributePtr payloadAttribute; - bool hasPayloads; - - public: - virtual int32_t getStreamCount(); - virtual void finish(); - virtual void skippingLongTerm(); - virtual int32_t compareTo(const LuceneObjectPtr& other); - void reset(); - virtual bool start(Collection fields, int32_t count); - virtual void start(const FieldablePtr& field); - void writeProx(const FreqProxTermsWriterPostingListPtr& p, int32_t proxCode); - virtual void newTerm(const RawPostingListPtr& p); - virtual void addTerm(const RawPostingListPtr& p); - void abort(); - }; +namespace Lucene { + +class FreqProxTermsWriterPerField : public TermsHashConsumerPerField { +public: + FreqProxTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const FreqProxTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); + virtual ~FreqProxTermsWriterPerField(); + + LUCENE_CLASS(FreqProxTermsWriterPerField); + +public: + FreqProxTermsWriterPerThreadWeakPtr _perThread; + TermsHashPerFieldWeakPtr _termsHashPerField; + FieldInfoPtr fieldInfo; + DocStatePtr docState; + FieldInvertStatePtr fieldState; + bool omitTermFreqAndPositions; + PayloadAttributePtr payloadAttribute; + bool hasPayloads; + +public: + virtual int32_t getStreamCount(); + virtual void finish(); + virtual void skippingLongTerm(); + virtual int32_t compareTo(const LuceneObjectPtr& other); + void reset(); + virtual bool start(Collection fields, int32_t count); + virtual void start(const FieldablePtr& field); + void writeProx(const FreqProxTermsWriterPostingListPtr& p, int32_t proxCode); + virtual void newTerm(const RawPostingListPtr& p); + virtual void addTerm(const RawPostingListPtr& p); + void abort(); +}; + } #endif diff --git a/include/FreqProxTermsWriterPerThread.h b/include/FreqProxTermsWriterPerThread.h index 960b969a..f9e4c6ac 100644 --- a/include/FreqProxTermsWriterPerThread.h +++ b/include/FreqProxTermsWriterPerThread.h @@ -9,26 +9,26 @@ #include "TermsHashConsumerPerThread.h" -namespace Lucene -{ - class FreqProxTermsWriterPerThread : public TermsHashConsumerPerThread - { - public: - FreqProxTermsWriterPerThread(const TermsHashPerThreadPtr& perThread); - virtual ~FreqProxTermsWriterPerThread(); - - LUCENE_CLASS(FreqProxTermsWriterPerThread); - - public: - TermsHashPerThreadWeakPtr _termsHashPerThread; - DocStatePtr docState; - - public: - virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo); - virtual void startDocument(); - virtual DocWriterPtr finishDocument(); - virtual void abort(); - }; +namespace Lucene { + +class FreqProxTermsWriterPerThread : public TermsHashConsumerPerThread { +public: + FreqProxTermsWriterPerThread(const TermsHashPerThreadPtr& perThread); + virtual ~FreqProxTermsWriterPerThread(); + + LUCENE_CLASS(FreqProxTermsWriterPerThread); + +public: + TermsHashPerThreadWeakPtr _termsHashPerThread; + DocStatePtr docState; + +public: + virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo); + virtual void startDocument(); + virtual DocWriterPtr finishDocument(); + virtual void abort(); +}; + } #endif diff --git a/include/FuzzyQuery.h b/include/FuzzyQuery.h index bd3f4b05..281616ea 100644 --- a/include/FuzzyQuery.h +++ b/include/FuzzyQuery.h @@ -9,70 +9,70 @@ #include "MultiTermQuery.h" -namespace Lucene -{ - /// Implements the fuzzy search query. The similarity measurement is based on the Levenshtein (edit - /// distance) algorithm. - /// - /// Warning: this query is not very scalable with its default prefix length of 0 - in this case, *every* - /// term will be enumerated and cause an edit score calculation. - class LPPAPI FuzzyQuery : public MultiTermQuery - { - public: - /// Create a new FuzzyQuery that will match terms with a similarity of at least minimumSimilarity - /// to term. If a prefixLength > 0 is specified, a common prefix of that length is also required. - /// @param term The term to search for - /// @param minimumSimilarity A value between 0 and 1 to set the required similarity between the query - /// term and the matching terms. For example, for a minimumSimilarity of 0.5 a term of the same - /// length as the query term is considered similar to the query term if the edit distance between - /// both terms is less than length(term) * 0.5 - /// @param prefixLength Length of common (non-fuzzy) prefix - FuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); - FuzzyQuery(const TermPtr& term, double minimumSimilarity); - FuzzyQuery(const TermPtr& term); - - virtual ~FuzzyQuery(); - - LUCENE_CLASS(FuzzyQuery); - - protected: - double minimumSimilarity; - int32_t prefixLength; - bool termLongEnough; - - TermPtr term; - - public: - static double defaultMinSimilarity(); - static const int32_t defaultPrefixLength; - - public: - using MultiTermQuery::toString; - - /// Returns the minimum similarity that is required for this query to match. - /// @return float value between 0.0 and 1.0 - double getMinSimilarity(); - - /// Returns the non-fuzzy prefix length. This is the number of characters at the start of a term that - /// must be identical (not fuzzy) to the query term if the query is to match that term. - int32_t getPrefixLength(); - - /// Returns the pattern term. - TermPtr getTerm(); - - virtual void setRewriteMethod(const RewriteMethodPtr& method); - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual String toString(const String& field); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - - protected: - void ConstructQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); - - virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); - }; +namespace Lucene { + +/// Implements the fuzzy search query. The similarity measurement is based on the Levenshtein (edit +/// distance) algorithm. +/// +/// Warning: this query is not very scalable with its default prefix length of 0 - in this case, *every* +/// term will be enumerated and cause an edit score calculation. +class LPPAPI FuzzyQuery : public MultiTermQuery { +public: + /// Create a new FuzzyQuery that will match terms with a similarity of at least minimumSimilarity + /// to term. If a prefixLength > 0 is specified, a common prefix of that length is also required. + /// @param term The term to search for + /// @param minimumSimilarity A value between 0 and 1 to set the required similarity between the query + /// term and the matching terms. For example, for a minimumSimilarity of 0.5 a term of the same + /// length as the query term is considered similar to the query term if the edit distance between + /// both terms is less than length(term) * 0.5 + /// @param prefixLength Length of common (non-fuzzy) prefix + FuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); + FuzzyQuery(const TermPtr& term, double minimumSimilarity); + FuzzyQuery(const TermPtr& term); + + virtual ~FuzzyQuery(); + + LUCENE_CLASS(FuzzyQuery); + +protected: + double minimumSimilarity; + int32_t prefixLength; + bool termLongEnough; + + TermPtr term; + +public: + static double defaultMinSimilarity(); + static const int32_t defaultPrefixLength; + +public: + using MultiTermQuery::toString; + + /// Returns the minimum similarity that is required for this query to match. + /// @return float value between 0.0 and 1.0 + double getMinSimilarity(); + + /// Returns the non-fuzzy prefix length. This is the number of characters at the start of a term that + /// must be identical (not fuzzy) to the query term if the query is to match that term. + int32_t getPrefixLength(); + + /// Returns the pattern term. + TermPtr getTerm(); + + virtual void setRewriteMethod(const RewriteMethodPtr& method); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual String toString(const String& field); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + +protected: + void ConstructQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); + + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); +}; + } #endif diff --git a/include/FuzzyTermEnum.h b/include/FuzzyTermEnum.h index 4a7afe67..de391f05 100644 --- a/include/FuzzyTermEnum.h +++ b/include/FuzzyTermEnum.h @@ -9,108 +9,108 @@ #include "FilteredTermEnum.h" -namespace Lucene -{ - /// Subclass of FilteredTermEnum for enumerating all terms that are similar to the specified filter term. +namespace Lucene { + +/// Subclass of FilteredTermEnum for enumerating all terms that are similar to the specified filter term. +/// +/// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater +/// than all that precede it. +class LPPAPI FuzzyTermEnum : public FilteredTermEnum { +public: + /// Constructor for enumeration of all terms from specified reader which share a prefix of length + /// prefixLength with term and which have a fuzzy similarity > minSimilarity. + /// + /// After calling the constructor the enumeration is already pointing to the first valid term if + /// such a term exists. + /// @param reader Delivers terms. + /// @param term Pattern term. + /// @param minSimilarity Minimum required similarity for terms from the reader. Default value is 0.5. + /// @param prefixLength Length of required common prefix. Default value is 0. + FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength); + FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity); + FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term); + + virtual ~FuzzyTermEnum(); + + LUCENE_CLASS(FuzzyTermEnum); + +protected: + /// Allows us save time required to create a new array every time similarity is called. + Collection p; + Collection d; + + double _similarity; + bool _endEnum; + + TermPtr searchTerm; + String field; + String text; + String prefix; + + double minimumSimilarity; + double scale_factor; + +public: + virtual double difference(); + virtual bool endEnum(); + virtual void close(); + +protected: + void ConstructTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength); + + /// The termCompare method in FuzzyTermEnum uses Levenshtein distance to calculate the distance between + /// the given term and the comparing term. + virtual bool termCompare(const TermPtr& term); + + /// + /// Compute Levenshtein distance + /// + /// Similarity returns a number that is 1.0f or less (including negative numbers) based on how similar the + /// Term is compared to a target term. It returns exactly 0.0 when + ///
      +    /// editDistance > maximumEditDistance
      +    /// 
      + /// + /// Otherwise it returns: + ///
      +    /// 1 - (editDistance / length)
      +    /// 
      + /// where length is the length of the shortest term (text or target) including a prefix that are identical + /// and editDistance is the Levenshtein distance for the two words. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater - /// than all that precede it. - class LPPAPI FuzzyTermEnum : public FilteredTermEnum - { - public: - /// Constructor for enumeration of all terms from specified reader which share a prefix of length - /// prefixLength with term and which have a fuzzy similarity > minSimilarity. - /// - /// After calling the constructor the enumeration is already pointing to the first valid term if - /// such a term exists. - /// @param reader Delivers terms. - /// @param term Pattern term. - /// @param minSimilarity Minimum required similarity for terms from the reader. Default value is 0.5. - /// @param prefixLength Length of required common prefix. Default value is 0. - FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength); - FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity); - FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term); - - virtual ~FuzzyTermEnum(); - - LUCENE_CLASS(FuzzyTermEnum); - - protected: - /// Allows us save time required to create a new array every time similarity is called. - Collection p; - Collection d; - - double _similarity; - bool _endEnum; - - TermPtr searchTerm; - String field; - String text; - String prefix; - - double minimumSimilarity; - double scale_factor; - - public: - virtual double difference(); - virtual bool endEnum(); - virtual void close(); - - protected: - void ConstructTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength); - - /// The termCompare method in FuzzyTermEnum uses Levenshtein distance to calculate the distance between - /// the given term and the comparing term. - virtual bool termCompare(const TermPtr& term); - - /// - /// Compute Levenshtein distance - /// - /// Similarity returns a number that is 1.0f or less (including negative numbers) based on how similar the - /// Term is compared to a target term. It returns exactly 0.0 when - ///
      -        /// editDistance > maximumEditDistance
      -        /// 
      - /// - /// Otherwise it returns: - ///
      -        /// 1 - (editDistance / length)
      -        /// 
      - /// where length is the length of the shortest term (text or target) including a prefix that are identical - /// and editDistance is the Levenshtein distance for the two words. - /// - /// Embedded within this algorithm is a fail-fast Levenshtein distance algorithm. The fail-fast algorithm - /// differs from the standard Levenshtein distance algorithm in that it is aborted if it is discovered that - /// the minimum distance between the words is greater than some threshold. - /// - /// To calculate the maximum distance threshold we use the following formula: - ///
      -        /// (1 - minimumSimilarity) * length
      -        /// 
      - /// where length is the shortest term including any prefix that is not part of the similarity comparison. - /// This formula was derived by solving for what maximum value of distance returns false for the following - /// statements: - ///
      -        /// similarity = 1 - ((double)distance / (double)(prefixLength + std::min(textlen, targetlen)));
      -        /// return (similarity > minimumSimilarity);
      -        /// 
      - /// where distance is the Levenshtein distance for the two words. - /// - /// Levenshtein distance (also known as edit distance) is a measure of similarity between two strings where - /// the distance is measured as the number of character deletions, insertions or substitutions required to - /// transform one string to the other string. - /// - /// @param target The target word or phrase. - /// @return the similarity, 0.0 or less indicates that it matches less than the required threshold and 1.0 - /// indicates that the text and target are identical. - double similarity(const String& target); - - /// The max Distance is the maximum Levenshtein distance for the text compared to some other value that - /// results in score that is better than the minimum similarity. - /// @param m The length of the "other value" - /// @return The maximum Levenshtein distance that we care about - int32_t calculateMaxDistance(int32_t m); - }; + /// Embedded within this algorithm is a fail-fast Levenshtein distance algorithm. The fail-fast algorithm + /// differs from the standard Levenshtein distance algorithm in that it is aborted if it is discovered that + /// the minimum distance between the words is greater than some threshold. + /// + /// To calculate the maximum distance threshold we use the following formula: + ///
      +    /// (1 - minimumSimilarity) * length
      +    /// 
      + /// where length is the shortest term including any prefix that is not part of the similarity comparison. + /// This formula was derived by solving for what maximum value of distance returns false for the following + /// statements: + ///
      +    /// similarity = 1 - ((double)distance / (double)(prefixLength + std::min(textlen, targetlen)));
      +    /// return (similarity > minimumSimilarity);
      +    /// 
      + /// where distance is the Levenshtein distance for the two words. + /// + /// Levenshtein distance (also known as edit distance) is a measure of similarity between two strings where + /// the distance is measured as the number of character deletions, insertions or substitutions required to + /// transform one string to the other string. + /// + /// @param target The target word or phrase. + /// @return the similarity, 0.0 or less indicates that it matches less than the required threshold and 1.0 + /// indicates that the text and target are identical. + double similarity(const String& target); + + /// The max Distance is the maximum Levenshtein distance for the text compared to some other value that + /// results in score that is better than the minimum similarity. + /// @param m The length of the "other value" + /// @return The maximum Levenshtein distance that we care about + int32_t calculateMaxDistance(int32_t m); +}; + } #endif diff --git a/include/HashMap.h b/include/HashMap.h index 4b355ef6..ff2efa1c 100644 --- a/include/HashMap.h +++ b/include/HashMap.h @@ -10,182 +10,159 @@ #include #include "LuceneSync.h" -namespace Lucene -{ - /// Utility template class to handle hash maps that can be safely copied and shared - template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > - class HashMap : public LuceneSync - { - public: - typedef HashMap this_type; - typedef std::pair key_value; - typedef boost::unordered_map map_type; - typedef typename map_type::iterator iterator; - typedef typename map_type::const_iterator const_iterator; - typedef KEY key_type; - typedef VALUE value_type; - - virtual ~HashMap() - { - } - - protected: - boost::shared_ptr mapContainer; - - public: - static this_type newInstance() - { - this_type instance; - instance.mapContainer = Lucene::newInstance(); - return instance; - } - - void reset() - { - mapContainer.reset(); - } - - int32_t size() const - { - return (int32_t)mapContainer->size(); - } - - bool empty() const - { - return mapContainer->empty(); - } - - void clear() - { - mapContainer->clear(); - } - - iterator begin() - { - return mapContainer->begin(); - } - - iterator end() - { - return mapContainer->end(); - } - - const_iterator begin() const - { - return mapContainer->begin(); - } - - const_iterator end() const - { - return mapContainer->end(); - } - - operator bool() const - { - return mapContainer.get() != NULL; - } - - bool operator! () const - { - return !mapContainer; - } - - map_type& operator= (const map_type& other) - { - mapContainer = other.mapContainer; - return *this; - } - - void put(const KEY& key, const VALUE& value) - { - (*mapContainer)[key] = value; - } - - template - void putAll(ITER first, ITER last) - { - for (iterator current = first; current != last; ++current) - (*mapContainer)[current->first] = current->second; - } - - template - void remove(ITER pos) - { - mapContainer->erase(pos); - } - - template - ITER remove(ITER first, ITER last) - { - return mapContainer->erase(first, last); - } - - bool remove(const KEY& key) - { - return (mapContainer->erase(key) > 0); - } - - iterator find(const KEY& key) - { - return mapContainer->find(key); - } - - VALUE get(const KEY& key) const - { - iterator findValue = mapContainer->find(key); - return findValue == mapContainer->end() ? VALUE() : findValue->second; - } - - bool contains(const KEY& key) const - { - return (mapContainer->find(key) != mapContainer->end()); - } - - VALUE& operator[] (const KEY& key) - { - return (*mapContainer)[key]; - } - }; - - /// Utility template class to handle weak keyed maps - template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > - class WeakHashMap : public HashMap - { - public: - typedef WeakHashMap this_type; - typedef std::pair key_value; - typedef typename boost::unordered_map map_type; - typedef typename map_type::iterator iterator; - - static this_type newInstance() - { - this_type instance; - instance.mapContainer = Lucene::newInstance(); - return instance; - } - - void removeWeak() - { - if (!this->mapContainer || this->mapContainer->empty()) - return; - map_type clearCopy; - for (iterator key = this->mapContainer->begin(); key != this->mapContainer->end(); ++key) - { - if (!key->first.expired()) - clearCopy.insert(*key); +namespace Lucene { + +/// Utility template class to handle hash maps that can be safely copied and shared +template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > +class HashMap : public LuceneSync { +public: + typedef HashMap this_type; + typedef std::pair key_value; + typedef boost::unordered_map map_type; + typedef typename map_type::iterator iterator; + typedef typename map_type::const_iterator const_iterator; + typedef KEY key_type; + typedef VALUE value_type; + + virtual ~HashMap() { + } + +protected: + boost::shared_ptr mapContainer; + +public: + static this_type newInstance() { + this_type instance; + instance.mapContainer = Lucene::newInstance(); + return instance; + } + + void reset() { + mapContainer.reset(); + } + + int32_t size() const { + return (int32_t)mapContainer->size(); + } + + bool empty() const { + return mapContainer->empty(); + } + + void clear() { + mapContainer->clear(); + } + + iterator begin() { + return mapContainer->begin(); + } + + iterator end() { + return mapContainer->end(); + } + + const_iterator begin() const { + return mapContainer->begin(); + } + + const_iterator end() const { + return mapContainer->end(); + } + + operator bool() const { + return mapContainer.get() != NULL; + } + + bool operator! () const { + return !mapContainer; + } + + map_type& operator= (const map_type& other) { + mapContainer = other.mapContainer; + return *this; + } + + void put(const KEY& key, const VALUE& value) { + (*mapContainer)[key] = value; + } + + template + void putAll(ITER first, ITER last) { + for (iterator current = first; current != last; ++current) { + (*mapContainer)[current->first] = current->second; + } + } + + template + void remove(ITER pos) { + mapContainer->erase(pos); + } + + template + ITER remove(ITER first, ITER last) { + return mapContainer->erase(first, last); + } + + bool remove(const KEY& key) { + return (mapContainer->erase(key) > 0); + } + + iterator find(const KEY& key) { + return mapContainer->find(key); + } + + VALUE get(const KEY& key) const { + iterator findValue = mapContainer->find(key); + return findValue == mapContainer->end() ? VALUE() : findValue->second; + } + + bool contains(const KEY& key) const { + return (mapContainer->find(key) != mapContainer->end()); + } + + VALUE& operator[] (const KEY& key) { + return (*mapContainer)[key]; + } +}; + +/// Utility template class to handle weak keyed maps +template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > +class WeakHashMap : public HashMap { +public: + typedef WeakHashMap this_type; + typedef std::pair key_value; + typedef typename boost::unordered_map map_type; + typedef typename map_type::iterator iterator; + + static this_type newInstance() { + this_type instance; + instance.mapContainer = Lucene::newInstance(); + return instance; + } + + void removeWeak() { + if (!this->mapContainer || this->mapContainer->empty()) { + return; + } + map_type clearCopy; + for (iterator key = this->mapContainer->begin(); key != this->mapContainer->end(); ++key) { + if (!key->first.expired()) { + clearCopy.insert(*key); } - this->mapContainer->swap(clearCopy); } + this->mapContainer->swap(clearCopy); + } - VALUE get(const KEY& key) - { - iterator findValue = this->mapContainer->find(key); - if (findValue != this->mapContainer->end()) - return findValue->second; - removeWeak(); - return VALUE(); + VALUE get(const KEY& key) { + iterator findValue = this->mapContainer->find(key); + if (findValue != this->mapContainer->end()) { + return findValue->second; } - }; + removeWeak(); + return VALUE(); + } +}; + } #endif diff --git a/include/HashSet.h b/include/HashSet.h index be2068cd..f6036fd7 100644 --- a/include/HashSet.h +++ b/include/HashSet.h @@ -10,124 +10,105 @@ #include #include "LuceneSync.h" -namespace Lucene -{ - /// Utility template class to handle hash set collections that can be safely copied and shared - template < class TYPE, class HASH = boost::hash, class EQUAL = std::equal_to > - class HashSet : public LuceneSync - { - public: - typedef HashSet this_type; - typedef boost::unordered_set set_type; - typedef typename set_type::iterator iterator; - typedef typename set_type::const_iterator const_iterator; - typedef TYPE value_type; - - virtual ~HashSet() - { - } - - protected: - boost::shared_ptr setContainer; - - public: - static this_type newInstance() - { - this_type instance; - instance.setContainer = Lucene::newInstance(); - return instance; - } - - template - static this_type newInstance(ITER first, ITER last) - { - this_type instance; - instance.setContainer = Lucene::newInstance(first, last); - return instance; - } - - void reset() - { - setContainer.reset(); - } - - int32_t size() const - { - return (int32_t)setContainer->size(); - } - - bool empty() const - { - return setContainer->empty(); - } - - void clear() - { - setContainer->clear(); - } - - iterator begin() - { - return setContainer->begin(); - } - - iterator end() - { - return setContainer->end(); - } - - const_iterator begin() const - { - return setContainer->begin(); - } - - const_iterator end() const - { - return setContainer->end(); - } - - operator bool() const - { - return setContainer.get() != NULL; - } - - bool operator! () const - { - return !setContainer; - } - - set_type& operator= (const set_type& other) - { - setContainer = other.setContainer; - return *this; - } - - bool add(const TYPE& type) - { - return setContainer->insert(type).second; - } - - template - void addAll(ITER first, ITER last) - { - setContainer->insert(first, last); - } - - bool remove(const TYPE& type) - { - return (setContainer->erase(type) > 0); - } - - iterator find(const TYPE& type) - { - return setContainer->find(type); - } - - bool contains(const TYPE& type) const - { - return (setContainer->find(type) != setContainer->end()); - } - }; +namespace Lucene { + +/// Utility template class to handle hash set collections that can be safely copied and shared +template < class TYPE, class HASH = boost::hash, class EQUAL = std::equal_to > +class HashSet : public LuceneSync { +public: + typedef HashSet this_type; + typedef boost::unordered_set set_type; + typedef typename set_type::iterator iterator; + typedef typename set_type::const_iterator const_iterator; + typedef TYPE value_type; + + virtual ~HashSet() { + } + +protected: + boost::shared_ptr setContainer; + +public: + static this_type newInstance() { + this_type instance; + instance.setContainer = Lucene::newInstance(); + return instance; + } + + template + static this_type newInstance(ITER first, ITER last) { + this_type instance; + instance.setContainer = Lucene::newInstance(first, last); + return instance; + } + + void reset() { + setContainer.reset(); + } + + int32_t size() const { + return (int32_t)setContainer->size(); + } + + bool empty() const { + return setContainer->empty(); + } + + void clear() { + setContainer->clear(); + } + + iterator begin() { + return setContainer->begin(); + } + + iterator end() { + return setContainer->end(); + } + + const_iterator begin() const { + return setContainer->begin(); + } + + const_iterator end() const { + return setContainer->end(); + } + + operator bool() const { + return setContainer.get() != NULL; + } + + bool operator! () const { + return !setContainer; + } + + set_type& operator= (const set_type& other) { + setContainer = other.setContainer; + return *this; + } + + bool add(const TYPE& type) { + return setContainer->insert(type).second; + } + + template + void addAll(ITER first, ITER last) { + setContainer->insert(first, last); + } + + bool remove(const TYPE& type) { + return (setContainer->erase(type) > 0); + } + + iterator find(const TYPE& type) { + return setContainer->find(type); + } + + bool contains(const TYPE& type) const { + return (setContainer->find(type) != setContainer->end()); + } +}; + } #endif diff --git a/include/HitQueue.h b/include/HitQueue.h index 38d0691a..a9f10681 100644 --- a/include/HitQueue.h +++ b/include/HitQueue.h @@ -9,26 +9,26 @@ #include "HitQueueBase.h" -namespace Lucene -{ - class HitQueue : public HitQueueBase - { - public: - /// Creates a new instance with size elements. - HitQueue(int32_t size, bool prePopulate); - virtual ~HitQueue(); - - LUCENE_CLASS(HitQueue); - - protected: - bool prePopulate; - - protected: - virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); - - /// Returns null if prePopulate is false. - virtual ScoreDocPtr getSentinelObject(); - }; +namespace Lucene { + +class HitQueue : public HitQueueBase { +public: + /// Creates a new instance with size elements. + HitQueue(int32_t size, bool prePopulate); + virtual ~HitQueue(); + + LUCENE_CLASS(HitQueue); + +protected: + bool prePopulate; + +protected: + virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); + + /// Returns null if prePopulate is false. + virtual ScoreDocPtr getSentinelObject(); +}; + } #endif diff --git a/include/HitQueueBase.h b/include/HitQueueBase.h index 145733da..dea149a3 100644 --- a/include/HitQueueBase.h +++ b/include/HitQueueBase.h @@ -9,55 +9,54 @@ #include "PriorityQueue.h" -namespace Lucene -{ - class LPPAPI HitQueueBase : public LuceneObject - { - public: - HitQueueBase(int32_t size); - virtual ~HitQueueBase(); - - LUCENE_CLASS(HitQueueBase); - - public: - virtual ScoreDocPtr add(const ScoreDocPtr& scoreDoc); - virtual ScoreDocPtr addOverflow(const ScoreDocPtr& scoreDoc); - virtual ScoreDocPtr top(); - virtual ScoreDocPtr pop(); - virtual ScoreDocPtr updateTop(); - virtual int32_t size(); - virtual bool empty(); - virtual void clear(); - - protected: - PriorityQueueScoreDocsPtr queue; - int32_t queueSize; - - public: - virtual void initialize(); - - protected: - virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) = 0; - virtual ScoreDocPtr getSentinelObject(); - - friend class PriorityQueueScoreDocs; - }; - - class LPPAPI PriorityQueueScoreDocs : public PriorityQueue - { - public: - PriorityQueueScoreDocs(const HitQueueBasePtr& hitQueue, int32_t size); - virtual ~PriorityQueueScoreDocs(); - - LUCENE_CLASS(PriorityQueueScoreDocs); - - protected: - HitQueueBaseWeakPtr _hitQueue; - - protected: - virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); - virtual ScoreDocPtr getSentinelObject(); - }; +namespace Lucene { + +class LPPAPI HitQueueBase : public LuceneObject { +public: + HitQueueBase(int32_t size); + virtual ~HitQueueBase(); + + LUCENE_CLASS(HitQueueBase); + +public: + virtual ScoreDocPtr add(const ScoreDocPtr& scoreDoc); + virtual ScoreDocPtr addOverflow(const ScoreDocPtr& scoreDoc); + virtual ScoreDocPtr top(); + virtual ScoreDocPtr pop(); + virtual ScoreDocPtr updateTop(); + virtual int32_t size(); + virtual bool empty(); + virtual void clear(); + +protected: + PriorityQueueScoreDocsPtr queue; + int32_t queueSize; + +public: + virtual void initialize(); + +protected: + virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) = 0; + virtual ScoreDocPtr getSentinelObject(); + + friend class PriorityQueueScoreDocs; +}; + +class LPPAPI PriorityQueueScoreDocs : public PriorityQueue { +public: + PriorityQueueScoreDocs(const HitQueueBasePtr& hitQueue, int32_t size); + virtual ~PriorityQueueScoreDocs(); + + LUCENE_CLASS(PriorityQueueScoreDocs); + +protected: + HitQueueBaseWeakPtr _hitQueue; + +protected: + virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); + virtual ScoreDocPtr getSentinelObject(); +}; + } #endif diff --git a/include/ISOLatin1AccentFilter.h b/include/ISOLatin1AccentFilter.h index d55dcc36..1c6a7562 100644 --- a/include/ISOLatin1AccentFilter.h +++ b/include/ISOLatin1AccentFilter.h @@ -9,34 +9,34 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// A filter that replaces accented characters in the ISO Latin 1 character set (ISO-8859-1) by their unaccented - /// equivalent. The case will not be altered. - /// - /// For instance, 'à' will be replaced by 'a'. - /// - /// @deprecated If you build a new index, use {@link ASCIIFoldingFilter} which covers a superset of Latin 1. - /// This class is included for use with existing indexes and will be removed in a future release (possibly Lucene 4.0). - class LPPAPI ISOLatin1AccentFilter : public TokenFilter - { - public: - ISOLatin1AccentFilter(const TokenStreamPtr& input); - virtual ~ISOLatin1AccentFilter(); - - LUCENE_CLASS(ISOLatin1AccentFilter); - - protected: - CharArray output; - int32_t outputPos; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - - /// To replace accented characters in a String by unaccented equivalents. - void removeAccents(const wchar_t* input, int32_t length); - }; +namespace Lucene { + +/// A filter that replaces accented characters in the ISO Latin 1 character set (ISO-8859-1) by their unaccented +/// equivalent. The case will not be altered. +/// +/// For instance, 'à' will be replaced by 'a'. +/// +/// @deprecated If you build a new index, use {@link ASCIIFoldingFilter} which covers a superset of Latin 1. +/// This class is included for use with existing indexes and will be removed in a future release (possibly Lucene 4.0). +class LPPAPI ISOLatin1AccentFilter : public TokenFilter { +public: + ISOLatin1AccentFilter(const TokenStreamPtr& input); + virtual ~ISOLatin1AccentFilter(); + + LUCENE_CLASS(ISOLatin1AccentFilter); + +protected: + CharArray output; + int32_t outputPos; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); + + /// To replace accented characters in a String by unaccented equivalents. + void removeAccents(const wchar_t* input, int32_t length); +}; + } #endif diff --git a/include/IndexCommit.h b/include/IndexCommit.h index 1df1d098..cc14322a 100644 --- a/include/IndexCommit.h +++ b/include/IndexCommit.h @@ -9,68 +9,68 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Represents a single commit into an index as seen by the {@link IndexDeletionPolicy} or {@link IndexReader}. +namespace Lucene { + +/// Represents a single commit into an index as seen by the {@link IndexDeletionPolicy} or {@link IndexReader}. +/// +/// Changes to the content of an index are made visible only after the writer who made that change commits by +/// writing a new segments file (segments_N). This point in time, when the action of writing of a new segments +/// file to the directory is completed, is an index commit. +/// +/// Each index commit point has a unique segments file associated with it. The segments file associated with a +/// later index commit point would have a larger N. +class LPPAPI IndexCommit : public LuceneObject { +public: + virtual ~IndexCommit(); + + LUCENE_CLASS(IndexCommit); + +public: + /// Get the segments file (segments_N) associated with this commit point. + virtual String getSegmentsFileName() = 0; + + /// Returns all index files referenced by this commit point. + virtual HashSet getFileNames() = 0; + + /// Returns the {@link Directory} for the index. + virtual DirectoryPtr getDirectory() = 0; + + /// Delete this commit point. This only applies when using the commit point in the context of IndexWriter's + /// IndexDeletionPolicy. /// - /// Changes to the content of an index are made visible only after the writer who made that change commits by - /// writing a new segments file (segments_N). This point in time, when the action of writing of a new segments - /// file to the directory is completed, is an index commit. + /// Upon calling this, the writer is notified that this commit point should be deleted. /// - /// Each index commit point has a unique segments file associated with it. The segments file associated with a - /// later index commit point would have a larger N. - class LPPAPI IndexCommit : public LuceneObject - { - public: - virtual ~IndexCommit(); + /// Decision that a commit-point should be deleted is taken by the {@link IndexDeletionPolicy} in effect + /// and therefore this should only be called by its {@link IndexDeletionPolicy#onInit onInit()} or + /// {@link IndexDeletionPolicy#onCommit onCommit()} methods. + virtual void deleteCommit() = 0; - LUCENE_CLASS(IndexCommit); + virtual bool isDeleted() = 0; - public: - /// Get the segments file (segments_N) associated with this commit point. - virtual String getSegmentsFileName() = 0; + /// Returns true if this commit is an optimized index. + virtual bool isOptimized() = 0; - /// Returns all index files referenced by this commit point. - virtual HashSet getFileNames() = 0; + /// Two IndexCommits are equal if both their Directory and versions are equal. + virtual bool equals(const LuceneObjectPtr& other); - /// Returns the {@link Directory} for the index. - virtual DirectoryPtr getDirectory() = 0; + virtual int32_t hashCode(); - /// Delete this commit point. This only applies when using the commit point in the context of IndexWriter's - /// IndexDeletionPolicy. - /// - /// Upon calling this, the writer is notified that this commit point should be deleted. - /// - /// Decision that a commit-point should be deleted is taken by the {@link IndexDeletionPolicy} in effect - /// and therefore this should only be called by its {@link IndexDeletionPolicy#onInit onInit()} or - /// {@link IndexDeletionPolicy#onCommit onCommit()} methods. - virtual void deleteCommit() = 0; + /// Returns the version for this IndexCommit. This is the same value that {@link IndexReader#getVersion} + /// would return if it were opened on this commit. + virtual int64_t getVersion() = 0; - virtual bool isDeleted() = 0; + /// Returns the generation (the _N in segments_N) for this IndexCommit. + virtual int64_t getGeneration() = 0; - /// Returns true if this commit is an optimized index. - virtual bool isOptimized() = 0; + /// Convenience method that returns the last modified time of the segments_N file corresponding to this + /// index commit, equivalent to getDirectory()->fileModified(getSegmentsFileName()). + virtual int64_t getTimestamp(); - /// Two IndexCommits are equal if both their Directory and versions are equal. - virtual bool equals(const LuceneObjectPtr& other); + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. Map is + /// String -> String. + virtual MapStringString getUserData() = 0; +}; - virtual int32_t hashCode(); - - /// Returns the version for this IndexCommit. This is the same value that {@link IndexReader#getVersion} - /// would return if it were opened on this commit. - virtual int64_t getVersion() = 0; - - /// Returns the generation (the _N in segments_N) for this IndexCommit. - virtual int64_t getGeneration() = 0; - - /// Convenience method that returns the last modified time of the segments_N file corresponding to this - /// index commit, equivalent to getDirectory()->fileModified(getSegmentsFileName()). - virtual int64_t getTimestamp(); - - /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. Map is - /// String -> String. - virtual MapStringString getUserData() = 0; - }; } #endif diff --git a/include/IndexDeletionPolicy.h b/include/IndexDeletionPolicy.h index 4bc480f0..14d2a4f0 100644 --- a/include/IndexDeletionPolicy.h +++ b/include/IndexDeletionPolicy.h @@ -9,63 +9,63 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Policy for deletion of stale {@link IndexCommit index commits}. - /// Implement this interface, and pass - /// it to one of the {@link IndexWriter} or {@link IndexReader} constructors, to customize when older - /// {@link IndexCommit point-in-time commits} are deleted from the index directory. The default deletion - /// policy is {@link KeepOnlyLastCommitDeletionPolicy}, which always removes old commits as soon as a new - /// commit is done (this matches the behavior before 2.2). - /// - /// One expected use case for this (and the reason why it was first created) is to work around problems - /// with an index directory accessed via filesystems like NFS because NFS does not provide the "delete on - /// last close" semantics that Lucene's "point in time" search normally relies on. By implementing a - /// custom deletion policy, such as "a commit is only removed once it has been stale for more than X - /// minutes", you can give your readers time to refresh to the new commit before {@link IndexWriter} - /// removes the old commits. Note that doing so will increase the storage requirements of the index. - class LPPAPI IndexDeletionPolicy : public LuceneObject - { - protected: - IndexDeletionPolicy(); +namespace Lucene { + +/// Policy for deletion of stale {@link IndexCommit index commits}. +/// Implement this interface, and pass +/// it to one of the {@link IndexWriter} or {@link IndexReader} constructors, to customize when older +/// {@link IndexCommit point-in-time commits} are deleted from the index directory. The default deletion +/// policy is {@link KeepOnlyLastCommitDeletionPolicy}, which always removes old commits as soon as a new +/// commit is done (this matches the behavior before 2.2). +/// +/// One expected use case for this (and the reason why it was first created) is to work around problems +/// with an index directory accessed via filesystems like NFS because NFS does not provide the "delete on +/// last close" semantics that Lucene's "point in time" search normally relies on. By implementing a +/// custom deletion policy, such as "a commit is only removed once it has been stale for more than X +/// minutes", you can give your readers time to refresh to the new commit before {@link IndexWriter} +/// removes the old commits. Note that doing so will increase the storage requirements of the index. +class LPPAPI IndexDeletionPolicy : public LuceneObject { +protected: + IndexDeletionPolicy(); + +public: + virtual ~IndexDeletionPolicy(); - public: - virtual ~IndexDeletionPolicy(); + LUCENE_CLASS(IndexDeletionPolicy); - LUCENE_CLASS(IndexDeletionPolicy); +public: + /// This is called once when a writer is first instantiated to give the policy a chance to remove old + /// commit points. + /// + /// The writer locates all index commits present in the index directory and calls this method. The + /// policy may choose to delete some of the commit points, doing so by calling method {@link + /// IndexCommit#delete delete()} of {@link IndexCommit}. + /// + /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to + /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the + /// index content while doing that. + /// + /// @param commits List of current {@link IndexCommit point-in-time commits}, sorted by age (the 0th + /// one is the oldest commit). + virtual void onInit(Collection commits) = 0; - public: - /// This is called once when a writer is first instantiated to give the policy a chance to remove old - /// commit points. - /// - /// The writer locates all index commits present in the index directory and calls this method. The - /// policy may choose to delete some of the commit points, doing so by calling method {@link - /// IndexCommit#delete delete()} of {@link IndexCommit}. - /// - /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to - /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the - /// index content while doing that. - /// - /// @param commits List of current {@link IndexCommit point-in-time commits}, sorted by age (the 0th - /// one is the oldest commit). - virtual void onInit(Collection commits) = 0; + /// This is called each time the writer completed a commit. This gives the policy a chance to remove + /// old commit points with each commit. + /// + /// The policy may now choose to delete old commit points by calling method {@link + /// IndexCommit#delete delete()} of {@link IndexCommit}. + /// + /// This method is only called when {@link IndexWriter#commit} or {@link IndexWriter#close} is called, + /// or possibly not at all if the {@link IndexWriter#rollback} is called. + /// + /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to + /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the + /// index content while doing that. + /// + /// @param commits List of {@link IndexCommit}, sorted by age (the 0th one is the oldest commit). + virtual void onCommit(Collection commits) = 0; +}; - /// This is called each time the writer completed a commit. This gives the policy a chance to remove - /// old commit points with each commit. - /// - /// The policy may now choose to delete old commit points by calling method {@link - /// IndexCommit#delete delete()} of {@link IndexCommit}. - /// - /// This method is only called when {@link IndexWriter#commit} or {@link IndexWriter#close} is called, - /// or possibly not at all if the {@link IndexWriter#rollback} is called. - /// - /// Note: the last CommitPoint is the most recent one, ie. the "front index state". Be careful not to - /// delete it, unless you know for sure what you are doing, and unless you can afford to lose the - /// index content while doing that. - /// - /// @param commits List of {@link IndexCommit}, sorted by age (the 0th one is the oldest commit). - virtual void onCommit(Collection commits) = 0; - }; } #endif diff --git a/include/IndexFileDeleter.h b/include/IndexFileDeleter.h index 96f2cf99..c774b0dc 100644 --- a/include/IndexFileDeleter.h +++ b/include/IndexFileDeleter.h @@ -9,196 +9,194 @@ #include "IndexCommit.h" -namespace Lucene -{ - /// This class keeps track of each SegmentInfos instance that is still "live", either because it corresponds to a - /// segments_N file in the Directory (a "commit", ie. a committed SegmentInfos) or because it's an in-memory - /// SegmentInfos that a writer is actively updating but has not yet committed. This class uses simple reference - /// counting to map the live SegmentInfos instances to individual files in the Directory. +namespace Lucene { + +/// This class keeps track of each SegmentInfos instance that is still "live", either because it corresponds to a +/// segments_N file in the Directory (a "commit", ie. a committed SegmentInfos) or because it's an in-memory +/// SegmentInfos that a writer is actively updating but has not yet committed. This class uses simple reference +/// counting to map the live SegmentInfos instances to individual files in the Directory. +/// +/// The same directory file may be referenced by more than one IndexCommit, i.e. more than one SegmentInfos. +/// Therefore we count how many commits reference each file. When all the commits referencing a certain file have +/// been deleted, the refcount for that file becomes zero, and the file is deleted. +/// +/// A separate deletion policy interface (IndexDeletionPolicy) is consulted on creation (onInit) and once per +/// commit (onCommit), to decide when a commit should be removed. +/// +/// It is the business of the IndexDeletionPolicy to choose when to delete commit points. The actual mechanics of +/// file deletion, retrying, etc, derived from the deletion of commit points is the business of the IndexFileDeleter. +/// +/// The current default deletion policy is {@link KeepOnlyLastCommitDeletionPolicy}, which removes all prior commits +/// when a new commit has completed. This matches the behavior before 2.2. +/// +/// Note that you must hold the write.lock before instantiating this class. It opens segments_N file(s) directly +/// with no retry logic. +class IndexFileDeleter : public LuceneObject { +public: + /// Initialize the deleter: find all previous commits in the Directory, incref the files they reference, call + /// the policy to let it delete commits. This will remove any files not referenced by any of the commits. + IndexFileDeleter(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& policy, const SegmentInfosPtr& segmentInfos, const InfoStreamPtr& infoStream, const DocumentsWriterPtr& docWriter, HashSet synced); + virtual ~IndexFileDeleter(); + + LUCENE_CLASS(IndexFileDeleter); + +protected: + /// Files that we tried to delete but failed (likely because they are open and we are running on Windows), + /// so we will retry them again later + HashSet deletable; + + /// Reference count for all files in the index. Counts how many existing commits reference a file. + MapStringRefCount refCounts; + + /// Holds all commits (segments_N) currently in the index. This will have just 1 commit if you are using the + /// default delete policy (KeepOnlyLastCommitDeletionPolicy). Other policies may leave commit points live for + /// longer in which case this list would be longer than 1 + Collection commits; + + /// Holds files we had incref'd from the previous non-commit checkpoint + Collection< HashSet > lastFiles; + + /// Commits that the IndexDeletionPolicy have decided to delete + Collection commitsToDelete; + + InfoStreamPtr infoStream; + DirectoryPtr directory; + IndexDeletionPolicyPtr policy; + DocumentsWriterPtr docWriter; + + SegmentInfosPtr lastSegmentInfos; + HashSet synced; + + /// Change to true to see details of reference counts when infoStream != null + static bool VERBOSE_REF_COUNTS; + +public: + bool startingCommitDeleted; + +protected: + void message(const String& message); + + /// Remove the CommitPoints in the commitsToDelete List by DecRef'ing all files from each SegmentInfos. + void deleteCommits(); + + void deletePendingFiles(); + + RefCountPtr getRefCount(const String& fileName); + +public: + void setInfoStream(const InfoStreamPtr& infoStream); + + SegmentInfosPtr getLastSegmentInfos(); + + /// Writer calls this when it has hit an error and had to roll back, to tell us that there may now be + /// unreferenced files in the filesystem. So we re-list the filesystem and delete such files. If + /// segmentName is non-null, we will only delete files corresponding to that segment. + void refresh(const String& segmentName); + void refresh(); + + void close(); + + /// For definition of "check point" see IndexWriter comments: "Clarification: Check Points (and commits)". + /// Writer calls this when it has made a "consistent change" to the index, meaning new files are written to + /// the index and the in-memory SegmentInfos have been modified to point to those files. /// - /// The same directory file may be referenced by more than one IndexCommit, i.e. more than one SegmentInfos. - /// Therefore we count how many commits reference each file. When all the commits referencing a certain file have - /// been deleted, the refcount for that file becomes zero, and the file is deleted. + /// This may or may not be a commit (segments_N may or may not have been written). /// - /// A separate deletion policy interface (IndexDeletionPolicy) is consulted on creation (onInit) and once per - /// commit (onCommit), to decide when a commit should be removed. + /// We simply incref the files referenced by the new SegmentInfos and decref the files we had previously + /// seen (if any). /// - /// It is the business of the IndexDeletionPolicy to choose when to delete commit points. The actual mechanics of - /// file deletion, retrying, etc, derived from the deletion of commit points is the business of the IndexFileDeleter. - /// - /// The current default deletion policy is {@link KeepOnlyLastCommitDeletionPolicy}, which removes all prior commits - /// when a new commit has completed. This matches the behavior before 2.2. - /// - /// Note that you must hold the write.lock before instantiating this class. It opens segments_N file(s) directly - /// with no retry logic. - class IndexFileDeleter : public LuceneObject - { - public: - /// Initialize the deleter: find all previous commits in the Directory, incref the files they reference, call - /// the policy to let it delete commits. This will remove any files not referenced by any of the commits. - IndexFileDeleter(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& policy, const SegmentInfosPtr& segmentInfos, const InfoStreamPtr& infoStream, const DocumentsWriterPtr& docWriter, HashSet synced); - virtual ~IndexFileDeleter(); + /// If this is a commit, we also call the policy to give it a chance to remove other commits. If any + /// commits are removed, we decref their files as well. + void checkpoint(const SegmentInfosPtr& segmentInfos, bool isCommit); + + void incRef(const SegmentInfosPtr& segmentInfos, bool isCommit); + void incRef(HashSet files); + void incRef(const String& fileName); + void decRef(HashSet files); + void decRef(const String& fileName); + void decRef(const SegmentInfosPtr& segmentInfos); + + bool exists(const String& fileName); - LUCENE_CLASS(IndexFileDeleter); + void deleteFiles(HashSet files); - protected: - /// Files that we tried to delete but failed (likely because they are open and we are running on Windows), - /// so we will retry them again later - HashSet deletable; + /// Deletes the specified files, but only if they are new (have not yet been incref'd). + void deleteNewFiles(HashSet files); - /// Reference count for all files in the index. Counts how many existing commits reference a file. - MapStringRefCount refCounts; - - /// Holds all commits (segments_N) currently in the index. This will have just 1 commit if you are using the - /// default delete policy (KeepOnlyLastCommitDeletionPolicy). Other policies may leave commit points live for - /// longer in which case this list would be longer than 1 - Collection commits; - - /// Holds files we had incref'd from the previous non-commit checkpoint - Collection< HashSet > lastFiles; - - /// Commits that the IndexDeletionPolicy have decided to delete - Collection commitsToDelete; - - InfoStreamPtr infoStream; - DirectoryPtr directory; - IndexDeletionPolicyPtr policy; - DocumentsWriterPtr docWriter; - - SegmentInfosPtr lastSegmentInfos; - HashSet synced; - - /// Change to true to see details of reference counts when infoStream != null - static bool VERBOSE_REF_COUNTS; - - public: - bool startingCommitDeleted; - - protected: - void message(const String& message); - - /// Remove the CommitPoints in the commitsToDelete List by DecRef'ing all files from each SegmentInfos. - void deleteCommits(); - - void deletePendingFiles(); - - RefCountPtr getRefCount(const String& fileName); - - public: - void setInfoStream(const InfoStreamPtr& infoStream); - - SegmentInfosPtr getLastSegmentInfos(); - - /// Writer calls this when it has hit an error and had to roll back, to tell us that there may now be - /// unreferenced files in the filesystem. So we re-list the filesystem and delete such files. If - /// segmentName is non-null, we will only delete files corresponding to that segment. - void refresh(const String& segmentName); - void refresh(); + void deleteFile(const String& fileName); +}; - void close(); +/// Tracks the reference count for a single index file +class RefCount : public LuceneObject { +public: + RefCount(const String& fileName); + virtual ~RefCount(); - /// For definition of "check point" see IndexWriter comments: "Clarification: Check Points (and commits)". - /// Writer calls this when it has made a "consistent change" to the index, meaning new files are written to - /// the index and the in-memory SegmentInfos have been modified to point to those files. - /// - /// This may or may not be a commit (segments_N may or may not have been written). - /// - /// We simply incref the files referenced by the new SegmentInfos and decref the files we had previously - /// seen (if any). - /// - /// If this is a commit, we also call the policy to give it a chance to remove other commits. If any - /// commits are removed, we decref their files as well. - void checkpoint(const SegmentInfosPtr& segmentInfos, bool isCommit); + LUCENE_CLASS(RefCount); - void incRef(const SegmentInfosPtr& segmentInfos, bool isCommit); - void incRef(HashSet files); - void incRef(const String& fileName); - void decRef(HashSet files); - void decRef(const String& fileName); - void decRef(const SegmentInfosPtr& segmentInfos); +public: + String fileName; // fileName used only for better assert error messages + bool initDone; + int32_t count; - bool exists(const String& fileName); +public: + int32_t IncRef(); + int32_t DecRef(); +}; - void deleteFiles(HashSet files); +/// Holds details for each commit point. This class is also passed to the deletion policy. Note: this class +/// has a natural ordering that is inconsistent with equals. +class CommitPoint : public IndexCommit { +public: + CommitPoint(Collection commitsToDelete, const DirectoryPtr& directory, const SegmentInfosPtr& segmentInfos); + virtual ~CommitPoint(); - /// Deletes the specified files, but only if they are new (have not yet been incref'd). - void deleteNewFiles(HashSet files); + LUCENE_CLASS(CommitPoint); - void deleteFile(const String& fileName); - }; +public: + int64_t gen; + HashSet files; + String segmentsFileName; + bool deleted; + DirectoryPtr directory; + Collection commitsToDelete; + int64_t version; + int64_t generation; + bool _isOptimized; + MapStringString userData; - /// Tracks the reference count for a single index file - class RefCount : public LuceneObject - { - public: - RefCount(const String& fileName); - virtual ~RefCount(); +public: + virtual String toString(); - LUCENE_CLASS(RefCount); + /// Returns true if this commit is an optimized index. + virtual bool isOptimized(); - public: - String fileName; // fileName used only for better assert error messages - bool initDone; - int32_t count; + /// Get the segments file (segments_N) associated with this commit point. + virtual String getSegmentsFileName(); - public: - int32_t IncRef(); - int32_t DecRef(); - }; + /// Returns all index files referenced by this commit point. + virtual HashSet getFileNames(); - /// Holds details for each commit point. This class is also passed to the deletion policy. Note: this class - /// has a natural ordering that is inconsistent with equals. - class CommitPoint : public IndexCommit - { - public: - CommitPoint(Collection commitsToDelete, const DirectoryPtr& directory, const SegmentInfosPtr& segmentInfos); - virtual ~CommitPoint(); + /// Returns the {@link Directory} for the index. + virtual DirectoryPtr getDirectory(); - LUCENE_CLASS(CommitPoint); + /// Returns the version for this IndexCommit. + virtual int64_t getVersion(); - public: - int64_t gen; - HashSet files; - String segmentsFileName; - bool deleted; - DirectoryPtr directory; - Collection commitsToDelete; - int64_t version; - int64_t generation; - bool _isOptimized; - MapStringString userData; + /// Returns the generation (the _N in segments_N) for this IndexCommit. + virtual int64_t getGeneration(); - public: - virtual String toString(); + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. + virtual MapStringString getUserData(); - /// Returns true if this commit is an optimized index. - virtual bool isOptimized(); + /// Called only be the deletion policy, to remove this commit point from the index. + virtual void deleteCommit(); - /// Get the segments file (segments_N) associated with this commit point. - virtual String getSegmentsFileName(); + virtual bool isDeleted(); - /// Returns all index files referenced by this commit point. - virtual HashSet getFileNames(); + virtual int32_t compareTo(const LuceneObjectPtr& other); +}; - /// Returns the {@link Directory} for the index. - virtual DirectoryPtr getDirectory(); - - /// Returns the version for this IndexCommit. - virtual int64_t getVersion(); - - /// Returns the generation (the _N in segments_N) for this IndexCommit. - virtual int64_t getGeneration(); - - /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. - virtual MapStringString getUserData(); - - /// Called only be the deletion policy, to remove this commit point from the index. - virtual void deleteCommit(); - - virtual bool isDeleted(); - - virtual int32_t compareTo(const LuceneObjectPtr& other); - }; } #endif diff --git a/include/IndexFileNameFilter.h b/include/IndexFileNameFilter.h index 1ba2c399..d101ad3c 100644 --- a/include/IndexFileNameFilter.h +++ b/include/IndexFileNameFilter.h @@ -9,23 +9,23 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Filename filter that accept filenames and extensions only created by Lucene. - class LPPAPI IndexFileNameFilter : public LuceneObject - { - public: - /// Returns true if this is a file known to be a Lucene index file. - static bool accept(const String& directory, const String& name); - - /// Returns true if this is a file that would be contained in a CFS file. - /// This function should only be called on files that pass the - /// {@link #accept} (ie, are already known to be a Lucene index file). - static bool isCFSFile(const String& name); - - /// Return singleton IndexFileNameFilter - static IndexFileNameFilterPtr getFilter(); - }; +namespace Lucene { + +/// Filename filter that accept filenames and extensions only created by Lucene. +class LPPAPI IndexFileNameFilter : public LuceneObject { +public: + /// Returns true if this is a file known to be a Lucene index file. + static bool accept(const String& directory, const String& name); + + /// Returns true if this is a file that would be contained in a CFS file. + /// This function should only be called on files that pass the + /// {@link #accept} (ie, are already known to be a Lucene index file). + static bool isCFSFile(const String& name); + + /// Return singleton IndexFileNameFilter + static IndexFileNameFilterPtr getFilter(); +}; + } #endif diff --git a/include/IndexFileNames.h b/include/IndexFileNames.h index 6495d14c..d157d78e 100644 --- a/include/IndexFileNames.h +++ b/include/IndexFileNames.h @@ -9,108 +9,108 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Constants representing filenames and extensions used by Lucene. - class IndexFileNames : public LuceneObject - { - public: - virtual ~IndexFileNames(); - LUCENE_CLASS(IndexFileNames); +namespace Lucene { - public: - /// Name of the index segment file. - static const String& SEGMENTS(); +/// Constants representing filenames and extensions used by Lucene. +class IndexFileNames : public LuceneObject { +public: + virtual ~IndexFileNames(); + LUCENE_CLASS(IndexFileNames); - /// Name of the generation reference file name. - static const String& SEGMENTS_GEN(); +public: + /// Name of the index segment file. + static const String& SEGMENTS(); - /// Name of the index deletable file (only used in pre-lockless indices). - static const String& DELETABLE(); + /// Name of the generation reference file name. + static const String& SEGMENTS_GEN(); - /// Extension of norms file. - static const String& NORMS_EXTENSION(); + /// Name of the index deletable file (only used in pre-lockless indices). + static const String& DELETABLE(); - /// Extension of freq postings file. - static const String& FREQ_EXTENSION(); + /// Extension of norms file. + static const String& NORMS_EXTENSION(); - /// Extension of prox postings file. - static const String& PROX_EXTENSION(); + /// Extension of freq postings file. + static const String& FREQ_EXTENSION(); - /// Extension of terms file. - static const String& TERMS_EXTENSION(); + /// Extension of prox postings file. + static const String& PROX_EXTENSION(); - /// Extension of terms index file. - static const String& TERMS_INDEX_EXTENSION(); + /// Extension of terms file. + static const String& TERMS_EXTENSION(); - /// Extension of stored fields index file. - static const String& FIELDS_INDEX_EXTENSION(); + /// Extension of terms index file. + static const String& TERMS_INDEX_EXTENSION(); - /// Extension of stored fields file. - static const String& FIELDS_EXTENSION(); + /// Extension of stored fields index file. + static const String& FIELDS_INDEX_EXTENSION(); - /// Extension of vectors fields file. - static const String& VECTORS_FIELDS_EXTENSION(); + /// Extension of stored fields file. + static const String& FIELDS_EXTENSION(); - /// Extension of vectors documents file. - static const String& VECTORS_DOCUMENTS_EXTENSION(); + /// Extension of vectors fields file. + static const String& VECTORS_FIELDS_EXTENSION(); - /// Extension of vectors index file. - static const String& VECTORS_INDEX_EXTENSION(); + /// Extension of vectors documents file. + static const String& VECTORS_DOCUMENTS_EXTENSION(); - /// Extension of compound file. - static const String& COMPOUND_FILE_EXTENSION(); + /// Extension of vectors index file. + static const String& VECTORS_INDEX_EXTENSION(); - /// Extension of compound file for doc store files. - static const String& COMPOUND_FILE_STORE_EXTENSION(); + /// Extension of compound file. + static const String& COMPOUND_FILE_EXTENSION(); - /// Extension of deletes. - static const String& DELETES_EXTENSION(); + /// Extension of compound file for doc store files. + static const String& COMPOUND_FILE_STORE_EXTENSION(); - /// Extension of field infos. - static const String& FIELD_INFOS_EXTENSION(); + /// Extension of deletes. + static const String& DELETES_EXTENSION(); - /// Extension of plain norms. - static const String& PLAIN_NORMS_EXTENSION(); + /// Extension of field infos. + static const String& FIELD_INFOS_EXTENSION(); - /// Extension of separate norms. - static const String& SEPARATE_NORMS_EXTENSION(); + /// Extension of plain norms. + static const String& PLAIN_NORMS_EXTENSION(); - /// Extension of gen file. - static const String& GEN_EXTENSION(); + /// Extension of separate norms. + static const String& SEPARATE_NORMS_EXTENSION(); - /// This array contains all filename extensions used by Lucene's index - /// files, with two exceptions, namely the extension made up from - /// ".f" + number and from ".s" + number. Also note that Lucene's - /// "segments_N" files do not have any filename extension. - static const HashSet INDEX_EXTENSIONS(); + /// Extension of gen file. + static const String& GEN_EXTENSION(); - /// File extensions that are added to a compound file (same as - /// {@link #INDEX_EXTENSIONS}, minus "del", "gen", "cfs"). - static const HashSet INDEX_EXTENSIONS_IN_COMPOUND_FILE(); + /// This array contains all filename extensions used by Lucene's index + /// files, with two exceptions, namely the extension made up from + /// ".f" + number and from ".s" + number. Also note that Lucene's + /// "segments_N" files do not have any filename extension. + static const HashSet INDEX_EXTENSIONS(); - static const HashSet STORE_INDEX_EXTENSIONS(); - static const HashSet NON_STORE_INDEX_EXTENSIONS(); + /// File extensions that are added to a compound file (same as + /// {@link #INDEX_EXTENSIONS}, minus "del", "gen", "cfs"). + static const HashSet INDEX_EXTENSIONS_IN_COMPOUND_FILE(); - /// File extensions of old-style index files. - static const HashSet COMPOUND_EXTENSIONS(); + static const HashSet STORE_INDEX_EXTENSIONS(); + static const HashSet NON_STORE_INDEX_EXTENSIONS(); - /// File extensions for term vector support. - static const HashSet VECTOR_EXTENSIONS(); + /// File extensions of old-style index files. + static const HashSet COMPOUND_EXTENSIONS(); - /// Computes the full file name from base, extension and generation. - /// If the generation is {@link SegmentInfo#NO}, the file name is null. - /// If it's {@link SegmentInfo#WITHOUT_GEN} the file name is base+extension. - /// If it's > 0, the file name is base_generation+extension. - static String fileNameFromGeneration(const String& base, const String& extension, int64_t gen); + /// File extensions for term vector support. + static const HashSet VECTOR_EXTENSIONS(); - /// Returns true if the provided filename is one of the doc store files - /// (ends with an extension in STORE_INDEX_EXTENSIONS). - static bool isDocStoreFile(const String& fileName); + /// Computes the full file name from base, extension and generation. + /// If the generation is {@link SegmentInfo#NO}, the file name is null. + /// If it's {@link SegmentInfo#WITHOUT_GEN} the file name is base+extension. + /// If it's > 0, the file name is base_generation+extension. + static String fileNameFromGeneration(const String& base, const String& extension, int64_t gen); + + /// Returns true if the provided filename is one of the doc store files + /// (ends with an extension in STORE_INDEX_EXTENSIONS). + static bool isDocStoreFile(const String& fileName); + + /// Return segment file name. + static String segmentFileName(const String& segmentName, const String& ext); +}; - /// Return segment file name. - static String segmentFileName(const String& segmentName, const String& ext); - }; } #endif diff --git a/include/IndexInput.h b/include/IndexInput.h index e25a78c7..198ab51a 100644 --- a/include/IndexInput.h +++ b/include/IndexInput.h @@ -9,116 +9,116 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Abstract base class for input from a file in a {@link Directory}. - /// A random-access input stream. Used for all Lucene index input operations. - /// @see Directory - class LPPAPI IndexInput : public LuceneObject - { - public: - IndexInput(); - virtual ~IndexInput(); - - LUCENE_CLASS(IndexInput); - - protected: - bool preUTF8Strings; // true if we are reading old (modified UTF8) string format - - public: - /// Reads and returns a single byte. - /// @see IndexOutput#writeByte(uint8_t) - virtual uint8_t readByte() = 0; - - /// Reads a specified number of bytes into an array at the specified offset. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - /// @see IndexOutput#writeBytes(const uint8_t*, int) - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) = 0; - - /// Reads a specified number of bytes into an array at the specified offset - /// with control over whether the read should be buffered (callers who have - /// their own buffer should pass in "false" for useBuffer). Currently only - /// {@link BufferedIndexInput} respects this parameter. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - /// @param useBuffer set to false if the caller will handle buffering. - /// @see IndexOutput#writeBytes(const uint8_t*,int) - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer); - - /// Reads four bytes and returns an int. - /// @see IndexOutput#writeInt(int32_t) - virtual int32_t readInt(); - - /// Reads an int stored in variable-length format. Reads between one and five - /// bytes. Smaller values take fewer bytes. Negative numbers are not supported. - /// @see IndexOutput#writeVInt(int32_t) - virtual int32_t readVInt(); - - /// Reads eight bytes and returns a int64. - /// @see IndexOutput#writeLong(int64_t) - virtual int64_t readLong(); - - /// Reads a int64 stored in variable-length format. Reads between one and nine - /// bytes. Smaller values take fewer bytes. Negative numbers are not supported. - virtual int64_t readVLong(); - - /// Call this if readString should read characters stored in the old modified - /// UTF8 format. This is used for indices written pre-2.4. - virtual void setModifiedUTF8StringsMode(); - - /// Reads a string. - /// @see IndexOutput#writeString(const String&) - virtual String readString(); - - /// Reads a modified UTF8 format string. - virtual String readModifiedUTF8String(); - - /// Reads Lucene's old "modified UTF-8" encoded characters into an array. - /// @param buffer the array to read characters into. - /// @param start the offset in the array to start storing characters. - /// @param length the number of characters to read. - /// @see IndexOutput#writeChars(const String& s, int32_t, int32_t) - virtual int32_t readChars(wchar_t* buffer, int32_t start, int32_t length); - - /// Similar to {@link #readChars(wchar_t*, int32_t, int32_t)} but does not - /// do any conversion operations on the bytes it is reading in. It still - /// has to invoke {@link #readByte()} just as {@link #readChars(wchar_t*, int32_t, int32_t)} - /// does, but it does not need a buffer to store anything and it does not have - /// to do any of the bitwise operations, since we don't actually care what is - /// in the byte except to determine how many more bytes to read. - /// @param length The number of chars to read. - /// @deprecated this method operates on old "modified utf8" encoded strings. - virtual void skipChars(int32_t length); - - /// Closes the stream to further operations. - virtual void close() = 0; - - /// Returns the current position in this file, where the next read will occur. - /// @see #seek(int64_t) - virtual int64_t getFilePointer() = 0; - - /// Sets current position in this file, where the next read will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos) = 0; - - /// The number of bytes in the file. - virtual int64_t length() = 0; - - /// Returns a clone of this stream. - /// - /// Clones of a stream access the same data, and are positioned at the same - /// point as the stream they were cloned from. - /// - /// Subclasses must ensure that clones may be positioned at different points - /// in the input from each other and from the stream they were cloned from. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - /// Read string map as a series of key/value pairs. - virtual MapStringString readStringStringMap(); - }; +namespace Lucene { + +/// Abstract base class for input from a file in a {@link Directory}. +/// A random-access input stream. Used for all Lucene index input operations. +/// @see Directory +class LPPAPI IndexInput : public LuceneObject { +public: + IndexInput(); + virtual ~IndexInput(); + + LUCENE_CLASS(IndexInput); + +protected: + bool preUTF8Strings; // true if we are reading old (modified UTF8) string format + +public: + /// Reads and returns a single byte. + /// @see IndexOutput#writeByte(uint8_t) + virtual uint8_t readByte() = 0; + + /// Reads a specified number of bytes into an array at the specified offset. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + /// @see IndexOutput#writeBytes(const uint8_t*, int) + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) = 0; + + /// Reads a specified number of bytes into an array at the specified offset + /// with control over whether the read should be buffered (callers who have + /// their own buffer should pass in "false" for useBuffer). Currently only + /// {@link BufferedIndexInput} respects this parameter. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + /// @param useBuffer set to false if the caller will handle buffering. + /// @see IndexOutput#writeBytes(const uint8_t*,int) + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer); + + /// Reads four bytes and returns an int. + /// @see IndexOutput#writeInt(int32_t) + virtual int32_t readInt(); + + /// Reads an int stored in variable-length format. Reads between one and five + /// bytes. Smaller values take fewer bytes. Negative numbers are not supported. + /// @see IndexOutput#writeVInt(int32_t) + virtual int32_t readVInt(); + + /// Reads eight bytes and returns a int64. + /// @see IndexOutput#writeLong(int64_t) + virtual int64_t readLong(); + + /// Reads a int64 stored in variable-length format. Reads between one and nine + /// bytes. Smaller values take fewer bytes. Negative numbers are not supported. + virtual int64_t readVLong(); + + /// Call this if readString should read characters stored in the old modified + /// UTF8 format. This is used for indices written pre-2.4. + virtual void setModifiedUTF8StringsMode(); + + /// Reads a string. + /// @see IndexOutput#writeString(const String&) + virtual String readString(); + + /// Reads a modified UTF8 format string. + virtual String readModifiedUTF8String(); + + /// Reads Lucene's old "modified UTF-8" encoded characters into an array. + /// @param buffer the array to read characters into. + /// @param start the offset in the array to start storing characters. + /// @param length the number of characters to read. + /// @see IndexOutput#writeChars(const String& s, int32_t, int32_t) + virtual int32_t readChars(wchar_t* buffer, int32_t start, int32_t length); + + /// Similar to {@link #readChars(wchar_t*, int32_t, int32_t)} but does not + /// do any conversion operations on the bytes it is reading in. It still + /// has to invoke {@link #readByte()} just as {@link #readChars(wchar_t*, int32_t, int32_t)} + /// does, but it does not need a buffer to store anything and it does not have + /// to do any of the bitwise operations, since we don't actually care what is + /// in the byte except to determine how many more bytes to read. + /// @param length The number of chars to read. + /// @deprecated this method operates on old "modified utf8" encoded strings. + virtual void skipChars(int32_t length); + + /// Closes the stream to further operations. + virtual void close() = 0; + + /// Returns the current position in this file, where the next read will occur. + /// @see #seek(int64_t) + virtual int64_t getFilePointer() = 0; + + /// Sets current position in this file, where the next read will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos) = 0; + + /// The number of bytes in the file. + virtual int64_t length() = 0; + + /// Returns a clone of this stream. + /// + /// Clones of a stream access the same data, and are positioned at the same + /// point as the stream they were cloned from. + /// + /// Subclasses must ensure that clones may be positioned at different points + /// in the input from each other and from the stream they were cloned from. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Read string map as a series of key/value pairs. + virtual MapStringString readStringStringMap(); +}; + } #endif diff --git a/include/IndexOutput.h b/include/IndexOutput.h index b1e02397..03073a9f 100644 --- a/include/IndexOutput.h +++ b/include/IndexOutput.h @@ -9,100 +9,100 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Abstract base class for output to a file in a Directory. A random-access output stream. Used for all - /// Lucene index output operations. - /// @see Directory - /// @see IndexInput - class LPPAPI IndexOutput : public LuceneObject - { - public: - virtual ~IndexOutput(); - - LUCENE_CLASS(IndexOutput); - - protected: - static const int32_t COPY_BUFFER_SIZE; - ByteArray copyBuffer; - - public: - /// Writes a single byte. - /// @see IndexInput#readByte() - virtual void writeByte(uint8_t b) = 0; - - /// Writes an array of bytes. - /// @param b the bytes to write. - /// @param length the number of bytes to write. - /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) - virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length) = 0; - - /// Forces any buffered output to be written. - virtual void flush() = 0; - - /// Closes this stream to further operations. - virtual void close() = 0; - - /// Returns the current position in this file, where the next write will occur. - virtual int64_t getFilePointer() = 0; - - /// Sets current position in this file, where the next write will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos) = 0; - - /// The number of bytes in the file. - virtual int64_t length() = 0; - - public: - /// Writes an array of bytes. - /// @param b the bytes to write. - /// @param length the number of bytes to write. - /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) - void writeBytes(const uint8_t* b, int32_t length); - - /// Writes an int as four bytes. - /// @see IndexInput#readInt() - void writeInt(int32_t i); - - /// Writes an int in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. - /// Negative numbers are not supported. - /// @see IndexInput#readVInt() - void writeVInt(int32_t i); - - /// Writes a int64 as eight bytes. - /// @see IndexInput#readLong() - void writeLong(int64_t i); - - /// Writes an int64 in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. - /// Negative numbers are not supported. - /// @see IndexInput#readVLong() - void writeVLong(int64_t i); - - /// Writes a string. - /// @see IndexInput#readString() - void writeString(const String& s); - - /// Writes a sub sequence of characters from s as the old format (modified UTF-8 encoded bytes). - /// @param s the source of the characters. - /// @param start the first character in the sequence. - /// @param length the number of characters in the sequence. - /// @deprecated -- please use {@link #writeString} - void writeChars(const String& s, int32_t start, int32_t length); - - /// Copy numBytes bytes from input to ourself. - void copyBytes(const IndexInputPtr& input, int64_t numBytes); - - /// Set the file length. By default, this method does nothing (it's optional for a Directory to implement it). - /// But, certain Directory implementations (for example @see FSDirectory) can use this to inform the underlying IO - /// system to pre-allocate the file to the specified size. If the length is longer than the current file length, - /// the bytes added to the file are undefined. Otherwise the file is truncated. - /// @param length file length. - void setLength(int64_t length); - - /// Write string map as a series of key/value pairs. - /// @param map map of string-string key-values. - void writeStringStringMap(MapStringString map); - }; +namespace Lucene { + +/// Abstract base class for output to a file in a Directory. A random-access output stream. Used for all +/// Lucene index output operations. +/// @see Directory +/// @see IndexInput +class LPPAPI IndexOutput : public LuceneObject { +public: + virtual ~IndexOutput(); + + LUCENE_CLASS(IndexOutput); + +protected: + static const int32_t COPY_BUFFER_SIZE; + ByteArray copyBuffer; + +public: + /// Writes a single byte. + /// @see IndexInput#readByte() + virtual void writeByte(uint8_t b) = 0; + + /// Writes an array of bytes. + /// @param b the bytes to write. + /// @param length the number of bytes to write. + /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) + virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length) = 0; + + /// Forces any buffered output to be written. + virtual void flush() = 0; + + /// Closes this stream to further operations. + virtual void close() = 0; + + /// Returns the current position in this file, where the next write will occur. + virtual int64_t getFilePointer() = 0; + + /// Sets current position in this file, where the next write will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos) = 0; + + /// The number of bytes in the file. + virtual int64_t length() = 0; + +public: + /// Writes an array of bytes. + /// @param b the bytes to write. + /// @param length the number of bytes to write. + /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) + void writeBytes(const uint8_t* b, int32_t length); + + /// Writes an int as four bytes. + /// @see IndexInput#readInt() + void writeInt(int32_t i); + + /// Writes an int in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. + /// Negative numbers are not supported. + /// @see IndexInput#readVInt() + void writeVInt(int32_t i); + + /// Writes a int64 as eight bytes. + /// @see IndexInput#readLong() + void writeLong(int64_t i); + + /// Writes an int64 in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes. + /// Negative numbers are not supported. + /// @see IndexInput#readVLong() + void writeVLong(int64_t i); + + /// Writes a string. + /// @see IndexInput#readString() + void writeString(const String& s); + + /// Writes a sub sequence of characters from s as the old format (modified UTF-8 encoded bytes). + /// @param s the source of the characters. + /// @param start the first character in the sequence. + /// @param length the number of characters in the sequence. + /// @deprecated -- please use {@link #writeString} + void writeChars(const String& s, int32_t start, int32_t length); + + /// Copy numBytes bytes from input to ourself. + void copyBytes(const IndexInputPtr& input, int64_t numBytes); + + /// Set the file length. By default, this method does nothing (it's optional for a Directory to implement it). + /// But, certain Directory implementations (for example @see FSDirectory) can use this to inform the underlying IO + /// system to pre-allocate the file to the specified size. If the length is longer than the current file length, + /// the bytes added to the file are undefined. Otherwise the file is truncated. + /// @param length file length. + void setLength(int64_t length); + + /// Write string map as a series of key/value pairs. + /// @param map map of string-string key-values. + void writeStringStringMap(MapStringString map); +}; + } #endif diff --git a/include/IndexReader.h b/include/IndexReader.h index f9d1a36a..4a4aad54 100644 --- a/include/IndexReader.h +++ b/include/IndexReader.h @@ -9,550 +9,549 @@ #include "SegmentInfos.h" -namespace Lucene -{ - /// IndexReader is an abstract class, providing an interface for accessing an index. Search of an index is done - /// entirely through this abstract interface, so that any subclass which implements it is searchable. +namespace Lucene { + +/// IndexReader is an abstract class, providing an interface for accessing an index. Search of an index is done +/// entirely through this abstract interface, so that any subclass which implements it is searchable. +/// +/// Concrete subclasses of IndexReader are usually constructed with a call to one of the static open methods, +/// eg. {@link #open(DirectoryPtr, bool)}. +/// +/// For efficiency, in this API documents are often referred to via document numbers, non-negative integers which +/// each name a unique document in the index. These document numbers are ephemeral -they may change as documents +/// are added to and deleted from an index. Clients should thus not rely on a given document having the same number +/// between sessions. +/// +/// An IndexReader can be opened on a directory for which an IndexWriter is opened already, but it cannot be used +/// to delete documents from the index then. +/// +/// NOTE: for backwards API compatibility, several methods are not listed as abstract, but have no useful implementations +/// in this base class and instead always throw UnsupportedOperation exception. Subclasses are strongly encouraged to +/// override these methods, but in many cases may not need to. +/// +/// NOTE: as of 2.4, it's possible to open a read-only IndexReader using the static open methods that accept the bool +/// readOnly parameter. Such a reader has better concurrency as it's not necessary to synchronize on the isDeleted +/// method. You must specify false if you want to make changes with the resulting IndexReader. +/// +/// NOTE: {@link IndexReader} instances are completely thread safe, meaning multiple threads can call any of its methods, +/// concurrently. If your application requires external synchronization, you should not synchronize on the IndexReader +/// instance; use your own (non-Lucene) objects instead. +class LPPAPI IndexReader : public LuceneObject { +public: + IndexReader(); + virtual ~IndexReader(); + + LUCENE_CLASS(IndexReader); + +public: + /// Constants describing field properties, for example used for {@link IndexReader#getFieldNames(FieldOption)}. + enum FieldOption { + /// All fields + FIELD_OPTION_ALL, + /// All indexed fields + FIELD_OPTION_INDEXED, + /// All fields that store payloads + FIELD_OPTION_STORES_PAYLOADS, + /// All fields that omit tf + FIELD_OPTION_OMIT_TERM_FREQ_AND_POSITIONS, + /// All fields which are not indexed + FIELD_OPTION_UNINDEXED, + /// All fields which are indexed with termvectors enabled + FIELD_OPTION_INDEXED_WITH_TERMVECTOR, + /// All fields which are indexed but don't have termvectors enabled + FIELD_OPTION_INDEXED_NO_TERMVECTOR, + /// All fields with termvectors enabled. Please note that only standard termvector fields are returned + FIELD_OPTION_TERMVECTOR, + /// All fields with termvectors with position values enabled + FIELD_OPTION_TERMVECTOR_WITH_POSITION, + /// All fields with termvectors with offset values enabled + FIELD_OPTION_TERMVECTOR_WITH_OFFSET, + /// All fields with termvectors with offset values and position values enabled + FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET + }; + + static const int32_t DEFAULT_TERMS_INDEX_DIVISOR; + +protected: + bool closed; + bool _hasChanges; + int32_t refCount; + +public: + /// Returns the current refCount for this reader + int32_t getRefCount(); + + /// Increments the refCount of this IndexReader instance. RefCounts are used to determine when a reader can be + /// closed safely, i.e. as soon as there are no more references. Be sure to always call a corresponding {@link + /// #decRef}, in a finally clause; otherwise the reader may never be closed. Note that {@link #close} simply + /// calls decRef(), which means that the IndexReader will not really be closed until {@link #decRef} has been + /// called for all outstanding references. + /// @see #decRef + void incRef(); + + /// Decreases the refCount of this IndexReader instance. If the refCount drops to 0, then pending changes + /// (if any) are committed to the index and this reader is closed. + /// @see #incRef + void decRef(); + + /// Returns a IndexReader reading the index in the given Directory, with readOnly = true. + /// @param directory the index directory + static IndexReaderPtr open(const DirectoryPtr& directory); + + /// Returns an IndexReader reading the index in the given Directory. You should pass readOnly = true, since it + /// gives much better concurrent performance, unless you intend to do write operations (delete documents or change + /// norms) with the reader. + /// @param directory the index directory + /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader + static IndexReaderPtr open(const DirectoryPtr& directory, bool readOnly); + + /// Returns an IndexReader reading the index in the given {@link IndexCommit}. You should pass readOnly = true, + /// since it gives much better concurrent performance, unless you intend to do write operations (delete documents + /// or change norms) with the reader. + /// @param commit the commit point to open + /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader + static IndexReaderPtr open(const IndexCommitPtr& commit, bool readOnly); + + /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. + /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write + /// operations (delete documents or change norms) with the reader. + /// @param directory the index directory + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform + /// deletes or to set norms); see {@link IndexWriter} for details. + /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly); + + /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. + /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write + /// operations (delete documents or change norms) with the reader. + /// @param directory the index directory + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform + /// deletes or to set norms); see {@link IndexWriter} for details. + /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader + /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the + /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at + /// indexing time while this setting can be set per reader. When set to N, then one in every + /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 + /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. The + /// default value is 1. Set this to -1 to skip loading the terms index entirely. + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); + + /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom + /// {@link IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, + /// unless you intend to do write operations (delete documents or change norms) with the reader. + /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to list all + /// commits in a directory + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform + /// deletes or to set norms); see {@link IndexWriter} for details. + /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader + static IndexReaderPtr open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly); + + /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom {@link + /// IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, unless + /// you intend to do write operations (delete documents or change norms) with the reader. + /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to + /// list all commits in a directory + /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform deletes + /// or to set norms); see {@link IndexWriter} for details. + /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader + /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the same effect as + /// {@link IndexWriter#setTermIndexInterval} except that setting must be done at indexing time while this setting can + /// be set per reader. When set to N, then one in every N * termIndexInterval terms in the index is loaded into + /// memory. By setting this to a value > 1 you can reduce memory usage, at the expense of higher latency when loading + /// a TermInfo. The default value is 1. Set this to -1 to skip loading the terms index entirely. + static IndexReaderPtr open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); + + /// Refreshes an IndexReader if the index has changed since this instance was (re)opened. /// - /// Concrete subclasses of IndexReader are usually constructed with a call to one of the static open methods, - /// eg. {@link #open(DirectoryPtr, bool)}. + /// Opening an IndexReader is an expensive operation. This method can be used to refresh an existing IndexReader to + /// reduce these costs. This method tries to only load segments that have changed or were created after the + /// IndexReader was (re)opened. /// - /// For efficiency, in this API documents are often referred to via document numbers, non-negative integers which - /// each name a unique document in the index. These document numbers are ephemeral -they may change as documents - /// are added to and deleted from an index. Clients should thus not rely on a given document having the same number - /// between sessions. + /// If the index has not changed since this instance was (re)opened, then this call is a NOOP and returns this + /// instance. Otherwise, a new instance is returned. The old instance is not closed and remains usable. /// - /// An IndexReader can be opened on a directory for which an IndexWriter is opened already, but it cannot be used - /// to delete documents from the index then. + /// If the reader is reopened, even though they share resources internally, it's safe to make changes (deletions, + /// norms) with the new reader. All shared mutable state obeys "copy on write" semantics to ensure the changes are + /// not seen by other readers. /// - /// NOTE: for backwards API compatibility, several methods are not listed as abstract, but have no useful implementations - /// in this base class and instead always throw UnsupportedOperation exception. Subclasses are strongly encouraged to - /// override these methods, but in many cases may not need to. + /// You can determine whether a reader was actually reopened by comparing the old instance with the + /// instance returned by this method: /// - /// NOTE: as of 2.4, it's possible to open a read-only IndexReader using the static open methods that accept the bool - /// readOnly parameter. Such a reader has better concurrency as it's not necessary to synchronize on the isDeleted - /// method. You must specify false if you want to make changes with the resulting IndexReader. + ///
      +    /// IndexReaderPtr reader = ...
      +    /// ...
      +    /// IndexReaderPtr newReader = r.reopen();
      +    /// if (newReader != reader)
      +    /// {
      +    ///     ... // reader was reopened
      +    ///     reader->close();
      +    /// }
      +    /// reader = newReader;
      +    /// ...
      +    /// 
      /// - /// NOTE: {@link IndexReader} instances are completely thread safe, meaning multiple threads can call any of its methods, - /// concurrently. If your application requires external synchronization, you should not synchronize on the IndexReader - /// instance; use your own (non-Lucene) objects instead. - class LPPAPI IndexReader : public LuceneObject - { - public: - IndexReader(); - virtual ~IndexReader(); - - LUCENE_CLASS(IndexReader); - - public: - /// Constants describing field properties, for example used for {@link IndexReader#getFieldNames(FieldOption)}. - enum FieldOption - { - /// All fields - FIELD_OPTION_ALL, - /// All indexed fields - FIELD_OPTION_INDEXED, - /// All fields that store payloads - FIELD_OPTION_STORES_PAYLOADS, - /// All fields that omit tf - FIELD_OPTION_OMIT_TERM_FREQ_AND_POSITIONS, - /// All fields which are not indexed - FIELD_OPTION_UNINDEXED, - /// All fields which are indexed with termvectors enabled - FIELD_OPTION_INDEXED_WITH_TERMVECTOR, - /// All fields which are indexed but don't have termvectors enabled - FIELD_OPTION_INDEXED_NO_TERMVECTOR, - /// All fields with termvectors enabled. Please note that only standard termvector fields are returned - FIELD_OPTION_TERMVECTOR, - /// All fields with termvectors with position values enabled - FIELD_OPTION_TERMVECTOR_WITH_POSITION, - /// All fields with termvectors with offset values enabled - FIELD_OPTION_TERMVECTOR_WITH_OFFSET, - /// All fields with termvectors with offset values and position values enabled - FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET - }; - - static const int32_t DEFAULT_TERMS_INDEX_DIVISOR; - - protected: - bool closed; - bool _hasChanges; - int32_t refCount; - - public: - /// Returns the current refCount for this reader - int32_t getRefCount(); - - /// Increments the refCount of this IndexReader instance. RefCounts are used to determine when a reader can be - /// closed safely, i.e. as soon as there are no more references. Be sure to always call a corresponding {@link - /// #decRef}, in a finally clause; otherwise the reader may never be closed. Note that {@link #close} simply - /// calls decRef(), which means that the IndexReader will not really be closed until {@link #decRef} has been - /// called for all outstanding references. - /// @see #decRef - void incRef(); - - /// Decreases the refCount of this IndexReader instance. If the refCount drops to 0, then pending changes - /// (if any) are committed to the index and this reader is closed. - /// @see #incRef - void decRef(); - - /// Returns a IndexReader reading the index in the given Directory, with readOnly = true. - /// @param directory the index directory - static IndexReaderPtr open(const DirectoryPtr& directory); - - /// Returns an IndexReader reading the index in the given Directory. You should pass readOnly = true, since it - /// gives much better concurrent performance, unless you intend to do write operations (delete documents or change - /// norms) with the reader. - /// @param directory the index directory - /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(const DirectoryPtr& directory, bool readOnly); - - /// Returns an IndexReader reading the index in the given {@link IndexCommit}. You should pass readOnly = true, - /// since it gives much better concurrent performance, unless you intend to do write operations (delete documents - /// or change norms) with the reader. - /// @param commit the commit point to open - /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(const IndexCommitPtr& commit, bool readOnly); - - /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. - /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write - /// operations (delete documents or change norms) with the reader. - /// @param directory the index directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform - /// deletes or to set norms); see {@link IndexWriter} for details. - /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly); - - /// Returns an IndexReader reading the index in the given Directory, with a custom {@link IndexDeletionPolicy}. - /// You should pass readOnly=true, since it gives much better concurrent performance, unless you intend to do write - /// operations (delete documents or change norms) with the reader. - /// @param directory the index directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform - /// deletes or to set norms); see {@link IndexWriter} for details. - /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the - /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at - /// indexing time while this setting can be set per reader. When set to N, then one in every - /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 - /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. The - /// default value is 1. Set this to -1 to skip loading the terms index entirely. - static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); - - /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom - /// {@link IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, - /// unless you intend to do write operations (delete documents or change norms) with the reader. - /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to list all - /// commits in a directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform - /// deletes or to set norms); see {@link IndexWriter} for details. - /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - static IndexReaderPtr open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly); - - /// Returns an IndexReader reading the index in the given Directory, using a specific commit and with a custom {@link - /// IndexDeletionPolicy}. You should pass readOnly=true, since it gives much better concurrent performance, unless - /// you intend to do write operations (delete documents or change norms) with the reader. - /// @param commit the specific {@link IndexCommit} to open; see {@link IndexReader#listCommits} to - /// list all commits in a directory - /// @param deletionPolicy a custom deletion policy (only used if you use this reader to perform deletes - /// or to set norms); see {@link IndexWriter} for details. - /// @param readOnly true if no changes (deletions, norms) will be made with this IndexReader - /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the same effect as - /// {@link IndexWriter#setTermIndexInterval} except that setting must be done at indexing time while this setting can - /// be set per reader. When set to N, then one in every N * termIndexInterval terms in the index is loaded into - /// memory. By setting this to a value > 1 you can reduce memory usage, at the expense of higher latency when loading - /// a TermInfo. The default value is 1. Set this to -1 to skip loading the terms index entirely. - static IndexReaderPtr open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); - - /// Refreshes an IndexReader if the index has changed since this instance was (re)opened. - /// - /// Opening an IndexReader is an expensive operation. This method can be used to refresh an existing IndexReader to - /// reduce these costs. This method tries to only load segments that have changed or were created after the - /// IndexReader was (re)opened. - /// - /// If the index has not changed since this instance was (re)opened, then this call is a NOOP and returns this - /// instance. Otherwise, a new instance is returned. The old instance is not closed and remains usable. - /// - /// If the reader is reopened, even though they share resources internally, it's safe to make changes (deletions, - /// norms) with the new reader. All shared mutable state obeys "copy on write" semantics to ensure the changes are - /// not seen by other readers. - /// - /// You can determine whether a reader was actually reopened by comparing the old instance with the - /// instance returned by this method: - /// - ///
      -        /// IndexReaderPtr reader = ...
      -        /// ...
      -        /// IndexReaderPtr newReader = r.reopen();
      -        /// if (newReader != reader)
      -        /// {
      -        ///     ... // reader was reopened
      -        ///     reader->close();
      -        /// }
      -        /// reader = newReader;
      -        /// ...
      -        /// 
      - /// - /// Be sure to synchronize that code so that other threads, if present, can never use reader after it has been - /// closed and before it's switched to newReader. If this reader is a near real-time reader (obtained from - /// {@link IndexWriter#getReader()}, reopen() will simply call writer.getReader() again for you, though this - /// may change in the future. - virtual IndexReaderPtr reopen(); - - /// Just like {@link #reopen()}, except you can change the readOnly of the original reader. If the index is - /// unchanged but readOnly is different then a new reader will be returned. - virtual IndexReaderPtr reopen(bool openReadOnly); - - /// Reopen this reader on a specific commit point. This always returns a readOnly reader. If the specified commit - /// point matches what this reader is already on, and this reader is already readOnly, then this same instance is - /// returned; if it is not already readOnly, a readOnly clone is returned. - virtual IndexReaderPtr reopen(const IndexCommitPtr& commit); - - /// Efficiently clones the IndexReader (sharing most internal state). - /// - /// On cloning a reader with pending changes (deletions, norms), the original reader transfers its write lock to the - /// cloned reader. This means only the cloned reader may make further changes to the index, and commit the changes - /// to the index on close, but the old reader still reflects all changes made up until it was cloned. - /// - /// Like {@link #reopen()}, it's safe to make changes to either the original or the cloned reader: all shared mutable - /// state obeys "copy on write" semantics to ensure the changes are not seen by other readers. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - /// Clones the IndexReader and optionally changes readOnly. A readOnly reader cannot open a writable reader. - virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); - - /// Returns the directory associated with this index. The default implementation returns the directory specified by - /// subclasses when delegating to the IndexReader(Directory) constructor, or throws an UnsupportedOperation exception - /// if one was not specified. - virtual DirectoryPtr directory(); - - /// Returns the time the index in the named directory was last modified. Do not use this to check - /// whether the reader is still up-to-date, use {@link #isCurrent()} instead. - static int64_t lastModified(const DirectoryPtr& directory2); - - /// Reads version number from segments files. The version number is initialized with a timestamp - /// and then increased by one for each change of the index. - /// @param directory where the index resides. - /// @return version number. - static int64_t getCurrentVersion(const DirectoryPtr& directory); - - /// Reads commitUserData, previously passed to {@link IndexWriter#commit(MapStringString)}, from - /// current index segments file. This will return null if {@link IndexWriter#commit(MapStringString)} - /// has never been called for this index. - static MapStringString getCommitUserData(const DirectoryPtr& directory); - - /// Version number when this IndexReader was opened. Not implemented in the IndexReader base class. - /// - /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link - /// #reopen} on a reader based on a Directory), then this method returns the version recorded in the - /// commit that the reader opened. This version is advanced every time {@link IndexWriter#commit} - /// is called. - /// - /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link - /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this - /// method returns the version of the last commit done by the writer. Note that even as further - /// changes are made with the writer, the version will not changed until a commit is completed. - /// Thus, you should not rely on this method to determine when a near real-time reader should be - /// opened. Use {@link #isCurrent} instead. - virtual int64_t getVersion(); - - /// Retrieve the String userData optionally passed to IndexWriter#commit. This will return null if - /// {@link IndexWriter#commit(MapStringString)} has never been called for this index. - virtual MapStringString getCommitUserData(); - - /// Check whether any new changes have occurred to the index since this reader was opened. - /// - /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link - /// #reopen} on a reader based on a Directory), then this method checks if any further commits (see - /// {@link IndexWriter#commit} have occurred in that directory). - /// - /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link - /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this - /// method checks if either a new commit has occurred, or any new uncommitted changes have taken - /// place via the writer. Note that even if the writer has only performed merging, this method - /// will still return false. - /// - /// In any event, if this returns false, you should call {@link #reopen} to get a new reader that - /// sees the changes. - virtual bool isCurrent(); - - /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented - /// in the IndexReader base class. - /// @return true if the index is optimized; false otherwise - virtual bool isOptimized(); - - /// Return an array of term frequency vectors for the specified document. The array contains a - /// vector for each vectorized field in the document. Each vector contains terms and frequencies - /// for all terms in a given vectorized field. If no such fields existed, the method returns null. - /// The term vectors that are returned may either be of type {@link TermFreqVector} or of type - /// {@link TermPositionVector} if positions or offsets have been stored. - /// - /// @param docNumber document for which term frequency vectors are returned - /// @return array of term frequency vectors. May be null if no term vectors have been stored for the - /// specified document. - virtual Collection getTermFreqVectors(int32_t docNumber) = 0; - - /// Return a term frequency vector for the specified document and field. The returned vector contains - /// terms and frequencies for the terms in the specified field of this document, if the field had the - /// storeTermVector flag set. If termvectors had been stored with positions or offsets, a - /// {@link TermPositionVector} is returned. - /// - /// @param docNumber document for which the term frequency vector is returned. - /// @param field field for which the term frequency vector is returned. - /// @return term frequency vector May be null if field does not exist in the specified document or - /// term vector was not stored. - virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field) = 0; - - /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays - /// of the {@link TermFreqVector}. - /// @param docNumber The number of the document to load the vector for - /// @param field The name of the field to load - /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. - virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) = 0; - - /// Map all the term vectors for all fields in a Document - /// @param docNumber The number of the document to load the vector for - /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. - virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) = 0; - - /// Returns true if an index exists at the specified directory. If the directory does not exist or - /// if there is no index in it. - /// @param directory the directory to check for an index - /// @return true if an index exists; false otherwise - static bool indexExists(const DirectoryPtr& directory); - - /// Returns the number of documents in this index. - virtual int32_t numDocs() = 0; - - /// Returns one greater than the largest possible document number. This may be used to, eg., determine - /// how big to allocate an array which will have an element for every document number in an index. - virtual int32_t maxDoc() = 0; - - /// Returns the number of deleted documents. - int32_t numDeletedDocs(); - - /// Returns the stored fields of the n'th Document in this index. - /// - /// NOTE: for performance reasons, this method does not check if the requested document is deleted, and - /// therefore asking for a deleted document may yield unspecified results. Usually this is not required, - /// however you can call {@link #isDeleted(int)} with the requested document ID to verify the document - /// is not deleted. - virtual DocumentPtr document(int32_t n); - - /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine - /// what {@link Field}s to load and how they should be loaded. - /// NOTE: If this Reader (more specifically, the underlying FieldsReader) is closed before the lazy - /// {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} - /// to be available after closing you must explicitly load it or fetch the Document again with a new - /// loader. - /// - /// NOTE: for performance reasons, this method does not check if the requested document is deleted, - /// and therefore asking for a deleted document may yield unspecified results. Usually this is not - /// required, however you can call {@link #isDeleted(int32_t)} with the requested document ID to verify - /// the document is not deleted. - /// - /// @param n Get the document at the n'th position - /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on - /// the Document. May be null, in which case all Fields will be loaded. - /// @return The stored fields of the {@link Document} at the n'th position - /// @see Fieldable - /// @see FieldSelector - /// @see SetBasedFieldSelector - /// @see LoadFirstFieldSelector - virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; - - /// Returns true if document n has been deleted - virtual bool isDeleted(int32_t n) = 0; - - /// Returns true if any documents have been deleted - virtual bool hasDeletions() = 0; - - /// Used for testing - virtual bool hasChanges(); - - /// Returns true if there are norms stored for this field. - virtual bool hasNorms(const String& field); - - /// Returns the byte-encoded normalization factor for the named field of every document. This is used - /// by the search code to score documents. - /// @see Field#setBoost(double) - virtual ByteArray norms(const String& field) = 0; - - /// Reads the byte-encoded normalization factor for the named field of every document. This is used - /// by the search code to score documents. - /// @see Field#setBoost(double) - virtual void norms(const String& field, ByteArray norms, int32_t offset) = 0; - - /// Resets the normalization factor for the named field of the named document. The norm represents - /// the product of the field's {@link Fieldable#setBoost(double) boost} and its {@link - /// Similarity#lengthNorm(String, int) length normalization}. Thus, to preserve the length normalization - /// values when resetting this, one should base the new value upon the old. - /// - /// NOTE: If this field does not store norms, then this method call will silently do nothing. - /// - /// @see #norms(String) - /// @see Similarity#decodeNorm(byte) - virtual void setNorm(int32_t doc, const String& field, uint8_t value); - - /// Resets the normalization factor for the named field of the named document. - /// - /// @see #norms(String) - /// @see Similarity#decodeNorm(byte) - virtual void setNorm(int32_t doc, const String& field, double value); - - /// Returns an enumeration of all the terms in the index. The enumeration is ordered by - /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. - /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting - /// enumeration before calling other methods such as {@link TermEnum#term()}. - virtual TermEnumPtr terms() = 0; - - /// Returns an enumeration of all terms starting at a given term. If the given term does not - /// exist, the enumeration is positioned at the first term greater than the supplied term. - /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede - /// it in the enumeration. - virtual TermEnumPtr terms(const TermPtr& t) = 0; - - /// Returns the number of documents containing the term t. - virtual int32_t docFreq(const TermPtr& t) = 0; - - /// Returns an enumeration of all the documents which contain term. For each document, the - /// document number, the frequency of the term in that document is also provided, for use in - /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. - /// The enumeration is ordered by document number. Each document number is greater than all - /// that precede it in the enumeration. - virtual TermDocsPtr termDocs(const TermPtr& term); - - /// Returns an unpositioned {@link TermDocs} enumerator. - virtual TermDocsPtr termDocs() = 0; - - /// Returns an enumeration of all the documents which contain term. For each document, in - /// addition to the document number and frequency of the term in that document, a list of all - /// of the ordinal positions of the term in the document is available. Thus, this method - /// positions of the term in the document is available. - /// This positional information facilitates phrase and proximity searching. - /// The enumeration is ordered by document number. Each document number is greater than all - /// that precede it in the enumeration. - virtual TermPositionsPtr termPositions(const TermPtr& term); - - /// Returns an unpositioned {@link TermPositions} enumerator. - virtual TermPositionsPtr termPositions() = 0; - - /// Deletes the document numbered docNum. Once a document is deleted it will not appear in - /// TermDocs or TermPostitions enumerations. Attempts to read its field with the {@link - /// #document} method will result in an error. The presence of this document may still be - /// reflected in the {@link #docFreq} statistic, though this will be corrected eventually as - /// the index is further modified. - virtual void deleteDocument(int32_t docNum); - - /// Deletes all documents that have a given term indexed. This is useful if one uses a - /// document field to hold a unique ID string for the document. Then to delete such a - /// document, one merely constructs a term with the appropriate field and the unique ID string - /// as its text and passes it to this method. See {@link #deleteDocument(int)} for information - /// about when this deletion will become effective. - /// @return the number of documents deleted - virtual int32_t deleteDocuments(const TermPtr& term); - - /// Undeletes all documents currently marked as deleted in this index. - virtual void undeleteAll(); - - void flush(); - - /// @param commitUserData Opaque Map (String -> String) that's recorded into the segments file - /// in the index, and retrievable by {@link IndexReader#getCommitUserData}. - void flush(MapStringString commitUserData); - - /// Commit changes resulting from delete, undeleteAll, or setNorm operations. - /// If an exception is hit, then either no changes or all changes will have been committed to - /// the index (transactional semantics). - void commit(MapStringString commitUserData); - - /// Closes files associated with this index. Also saves any new deletions to disk. - /// No other methods should be called after this has been called. - void close(); - - /// Get a list of unique field names that exist in this index and have the specified field option information. - /// @param fieldOption specifies which field option should be available for the returned fields - /// @return Collection of Strings indicating the names of the fields. - virtual HashSet getFieldNames(FieldOption fieldOption) = 0; - - /// Return the IndexCommit that this reader has opened. This method is only implemented by those - /// readers that correspond to a Directory with its own segments_N file. - virtual IndexCommitPtr getIndexCommit(); - - /// Prints the filename and size of each file within a given compound file. Add the -extract flag - /// to extract files to the current working directory. In order to make the extracted version of - /// the index work, you have to copy the segments file from the compound index into the directory - /// where the extracted files are stored. - /// @param args Usage: IndexReader [-extract] - static void main(Collection args); - - /// Returns all commit points that exist in the Directory. Normally, because the default is {@link - /// KeepOnlyLastCommitDeletionPolicy}, there would be only one commit point. But if you're using a - /// custom {@link IndexDeletionPolicy} then there could be many commits. Once you have a given - /// commit, you can open a reader on it by calling {@link IndexReader#open(IndexCommit,bool)}. - /// There must be at least one commit in the Directory, else this method throws an exception. - /// Note that if a commit is in progress while this method is running, that commit may or may not - /// be returned array. - static Collection listCommits(const DirectoryPtr& dir); - - /// Returns the sequential sub readers that this reader is logically composed of. For example, - /// IndexSearcher uses this API to drive searching by one sub reader at a time. If this reader is - /// not composed of sequential child readers, it should return null. If this method returns an empty - /// array, that means this reader is a null reader (for example a MultiReader that has no sub readers). - /// - /// NOTE: You should not try using sub-readers returned by this method to make any changes (setNorm, - /// deleteDocument, etc.). While this might succeed for one composite reader (like MultiReader), it - /// will most likely lead to index corruption for other readers (like DirectoryReader obtained - /// through {@link #open}. Use the parent reader directly. - virtual Collection getSequentialSubReaders(); - - virtual LuceneObjectPtr getFieldCacheKey(); - - /// This returns null if the reader has no deletions. - virtual LuceneObjectPtr getDeletesCacheKey(); - - /// Returns the number of unique terms (across all fields) in this reader. - /// - /// This method returns int64_t, even though internally Lucene cannot handle more than 2^31 unique - /// terms, for a possible future when this limitation is removed. - virtual int64_t getUniqueTermCount(); - - /// For IndexReader implementations that use TermInfosReader to read terms, this returns the current - /// indexDivisor as specified when the reader was opened. - virtual int32_t getTermInfosIndexDivisor(); - - protected: - void ensureOpen(); - - static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor); - - /// Implements setNorm in subclass. - virtual void doSetNorm(int32_t doc, const String& field, uint8_t value) = 0; - - /// Implements deletion of the document numbered docNum. - /// Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}. - virtual void doDelete(int32_t docNum) = 0; - - /// Implements actual undeleteAll() in subclass. - virtual void doUndeleteAll() = 0; - - /// Does nothing by default. Subclasses that require a write lock for index modifications must - /// implement this method. - virtual void acquireWriteLock(); - - /// Commit changes resulting from delete, undeleteAll, or setNorm operations. - /// If an exception is hit, then either no changes or all changes will have been committed to - /// the index (transactional semantics). - void commit(); - - /// Implements commit. - virtual void doCommit(MapStringString commitUserData) = 0; - - /// Implements close. - virtual void doClose() = 0; - - friend class DirectoryReader; - friend class ParallelReader; - }; + /// Be sure to synchronize that code so that other threads, if present, can never use reader after it has been + /// closed and before it's switched to newReader. If this reader is a near real-time reader (obtained from + /// {@link IndexWriter#getReader()}, reopen() will simply call writer.getReader() again for you, though this + /// may change in the future. + virtual IndexReaderPtr reopen(); + + /// Just like {@link #reopen()}, except you can change the readOnly of the original reader. If the index is + /// unchanged but readOnly is different then a new reader will be returned. + virtual IndexReaderPtr reopen(bool openReadOnly); + + /// Reopen this reader on a specific commit point. This always returns a readOnly reader. If the specified commit + /// point matches what this reader is already on, and this reader is already readOnly, then this same instance is + /// returned; if it is not already readOnly, a readOnly clone is returned. + virtual IndexReaderPtr reopen(const IndexCommitPtr& commit); + + /// Efficiently clones the IndexReader (sharing most internal state). + /// + /// On cloning a reader with pending changes (deletions, norms), the original reader transfers its write lock to the + /// cloned reader. This means only the cloned reader may make further changes to the index, and commit the changes + /// to the index on close, but the old reader still reflects all changes made up until it was cloned. + /// + /// Like {@link #reopen()}, it's safe to make changes to either the original or the cloned reader: all shared mutable + /// state obeys "copy on write" semantics to ensure the changes are not seen by other readers. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Clones the IndexReader and optionally changes readOnly. A readOnly reader cannot open a writable reader. + virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Returns the directory associated with this index. The default implementation returns the directory specified by + /// subclasses when delegating to the IndexReader(Directory) constructor, or throws an UnsupportedOperation exception + /// if one was not specified. + virtual DirectoryPtr directory(); + + /// Returns the time the index in the named directory was last modified. Do not use this to check + /// whether the reader is still up-to-date, use {@link #isCurrent()} instead. + static int64_t lastModified(const DirectoryPtr& directory2); + + /// Reads version number from segments files. The version number is initialized with a timestamp + /// and then increased by one for each change of the index. + /// @param directory where the index resides. + /// @return version number. + static int64_t getCurrentVersion(const DirectoryPtr& directory); + + /// Reads commitUserData, previously passed to {@link IndexWriter#commit(MapStringString)}, from + /// current index segments file. This will return null if {@link IndexWriter#commit(MapStringString)} + /// has never been called for this index. + static MapStringString getCommitUserData(const DirectoryPtr& directory); + + /// Version number when this IndexReader was opened. Not implemented in the IndexReader base class. + /// + /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link + /// #reopen} on a reader based on a Directory), then this method returns the version recorded in the + /// commit that the reader opened. This version is advanced every time {@link IndexWriter#commit} + /// is called. + /// + /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link + /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this + /// method returns the version of the last commit done by the writer. Note that even as further + /// changes are made with the writer, the version will not changed until a commit is completed. + /// Thus, you should not rely on this method to determine when a near real-time reader should be + /// opened. Use {@link #isCurrent} instead. + virtual int64_t getVersion(); + + /// Retrieve the String userData optionally passed to IndexWriter#commit. This will return null if + /// {@link IndexWriter#commit(MapStringString)} has never been called for this index. + virtual MapStringString getCommitUserData(); + + /// Check whether any new changes have occurred to the index since this reader was opened. + /// + /// If this reader is based on a Directory (ie, was created by calling {@link #open}, or {@link + /// #reopen} on a reader based on a Directory), then this method checks if any further commits (see + /// {@link IndexWriter#commit} have occurred in that directory). + /// + /// If instead this reader is a near real-time reader (ie, obtained by a call to {@link + /// IndexWriter#getReader}, or by calling {@link #reopen} on a near real-time reader), then this + /// method checks if either a new commit has occurred, or any new uncommitted changes have taken + /// place via the writer. Note that even if the writer has only performed merging, this method + /// will still return false. + /// + /// In any event, if this returns false, you should call {@link #reopen} to get a new reader that + /// sees the changes. + virtual bool isCurrent(); + + /// Checks is the index is optimized (if it has a single segment and no deletions). Not implemented + /// in the IndexReader base class. + /// @return true if the index is optimized; false otherwise + virtual bool isOptimized(); + + /// Return an array of term frequency vectors for the specified document. The array contains a + /// vector for each vectorized field in the document. Each vector contains terms and frequencies + /// for all terms in a given vectorized field. If no such fields existed, the method returns null. + /// The term vectors that are returned may either be of type {@link TermFreqVector} or of type + /// {@link TermPositionVector} if positions or offsets have been stored. + /// + /// @param docNumber document for which term frequency vectors are returned + /// @return array of term frequency vectors. May be null if no term vectors have been stored for the + /// specified document. + virtual Collection getTermFreqVectors(int32_t docNumber) = 0; + + /// Return a term frequency vector for the specified document and field. The returned vector contains + /// terms and frequencies for the terms in the specified field of this document, if the field had the + /// storeTermVector flag set. If termvectors had been stored with positions or offsets, a + /// {@link TermPositionVector} is returned. + /// + /// @param docNumber document for which the term frequency vector is returned. + /// @param field field for which the term frequency vector is returned. + /// @return term frequency vector May be null if field does not exist in the specified document or + /// term vector was not stored. + virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field) = 0; + + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays + /// of the {@link TermFreqVector}. + /// @param docNumber The number of the document to load the vector for + /// @param field The name of the field to load + /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) = 0; + + /// Map all the term vectors for all fields in a Document + /// @param docNumber The number of the document to load the vector for + /// @param mapper The {@link TermVectorMapper} to process the vector. Must not be null. + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) = 0; + + /// Returns true if an index exists at the specified directory. If the directory does not exist or + /// if there is no index in it. + /// @param directory the directory to check for an index + /// @return true if an index exists; false otherwise + static bool indexExists(const DirectoryPtr& directory); + + /// Returns the number of documents in this index. + virtual int32_t numDocs() = 0; + + /// Returns one greater than the largest possible document number. This may be used to, eg., determine + /// how big to allocate an array which will have an element for every document number in an index. + virtual int32_t maxDoc() = 0; + + /// Returns the number of deleted documents. + int32_t numDeletedDocs(); + + /// Returns the stored fields of the n'th Document in this index. + /// + /// NOTE: for performance reasons, this method does not check if the requested document is deleted, and + /// therefore asking for a deleted document may yield unspecified results. Usually this is not required, + /// however you can call {@link #isDeleted(int)} with the requested document ID to verify the document + /// is not deleted. + virtual DocumentPtr document(int32_t n); + + /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine + /// what {@link Field}s to load and how they should be loaded. + /// NOTE: If this Reader (more specifically, the underlying FieldsReader) is closed before the lazy + /// {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} + /// to be available after closing you must explicitly load it or fetch the Document again with a new + /// loader. + /// + /// NOTE: for performance reasons, this method does not check if the requested document is deleted, + /// and therefore asking for a deleted document may yield unspecified results. Usually this is not + /// required, however you can call {@link #isDeleted(int32_t)} with the requested document ID to verify + /// the document is not deleted. + /// + /// @param n Get the document at the n'th position + /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on + /// the Document. May be null, in which case all Fields will be loaded. + /// @return The stored fields of the {@link Document} at the n'th position + /// @see Fieldable + /// @see FieldSelector + /// @see SetBasedFieldSelector + /// @see LoadFirstFieldSelector + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; + + /// Returns true if document n has been deleted + virtual bool isDeleted(int32_t n) = 0; + + /// Returns true if any documents have been deleted + virtual bool hasDeletions() = 0; + + /// Used for testing + virtual bool hasChanges(); + + /// Returns true if there are norms stored for this field. + virtual bool hasNorms(const String& field); + + /// Returns the byte-encoded normalization factor for the named field of every document. This is used + /// by the search code to score documents. + /// @see Field#setBoost(double) + virtual ByteArray norms(const String& field) = 0; + + /// Reads the byte-encoded normalization factor for the named field of every document. This is used + /// by the search code to score documents. + /// @see Field#setBoost(double) + virtual void norms(const String& field, ByteArray norms, int32_t offset) = 0; + + /// Resets the normalization factor for the named field of the named document. The norm represents + /// the product of the field's {@link Fieldable#setBoost(double) boost} and its {@link + /// Similarity#lengthNorm(String, int) length normalization}. Thus, to preserve the length normalization + /// values when resetting this, one should base the new value upon the old. + /// + /// NOTE: If this field does not store norms, then this method call will silently do nothing. + /// + /// @see #norms(String) + /// @see Similarity#decodeNorm(byte) + virtual void setNorm(int32_t doc, const String& field, uint8_t value); + + /// Resets the normalization factor for the named field of the named document. + /// + /// @see #norms(String) + /// @see Similarity#decodeNorm(byte) + virtual void setNorm(int32_t doc, const String& field, double value); + + /// Returns an enumeration of all the terms in the index. The enumeration is ordered by + /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. + /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting + /// enumeration before calling other methods such as {@link TermEnum#term()}. + virtual TermEnumPtr terms() = 0; + + /// Returns an enumeration of all terms starting at a given term. If the given term does not + /// exist, the enumeration is positioned at the first term greater than the supplied term. + /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede + /// it in the enumeration. + virtual TermEnumPtr terms(const TermPtr& t) = 0; + + /// Returns the number of documents containing the term t. + virtual int32_t docFreq(const TermPtr& t) = 0; + + /// Returns an enumeration of all the documents which contain term. For each document, the + /// document number, the frequency of the term in that document is also provided, for use in + /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. + /// The enumeration is ordered by document number. Each document number is greater than all + /// that precede it in the enumeration. + virtual TermDocsPtr termDocs(const TermPtr& term); + + /// Returns an unpositioned {@link TermDocs} enumerator. + virtual TermDocsPtr termDocs() = 0; + + /// Returns an enumeration of all the documents which contain term. For each document, in + /// addition to the document number and frequency of the term in that document, a list of all + /// of the ordinal positions of the term in the document is available. Thus, this method + /// positions of the term in the document is available. + /// This positional information facilitates phrase and proximity searching. + /// The enumeration is ordered by document number. Each document number is greater than all + /// that precede it in the enumeration. + virtual TermPositionsPtr termPositions(const TermPtr& term); + + /// Returns an unpositioned {@link TermPositions} enumerator. + virtual TermPositionsPtr termPositions() = 0; + + /// Deletes the document numbered docNum. Once a document is deleted it will not appear in + /// TermDocs or TermPostitions enumerations. Attempts to read its field with the {@link + /// #document} method will result in an error. The presence of this document may still be + /// reflected in the {@link #docFreq} statistic, though this will be corrected eventually as + /// the index is further modified. + virtual void deleteDocument(int32_t docNum); + + /// Deletes all documents that have a given term indexed. This is useful if one uses a + /// document field to hold a unique ID string for the document. Then to delete such a + /// document, one merely constructs a term with the appropriate field and the unique ID string + /// as its text and passes it to this method. See {@link #deleteDocument(int)} for information + /// about when this deletion will become effective. + /// @return the number of documents deleted + virtual int32_t deleteDocuments(const TermPtr& term); + + /// Undeletes all documents currently marked as deleted in this index. + virtual void undeleteAll(); + + void flush(); + + /// @param commitUserData Opaque Map (String -> String) that's recorded into the segments file + /// in the index, and retrievable by {@link IndexReader#getCommitUserData}. + void flush(MapStringString commitUserData); + + /// Commit changes resulting from delete, undeleteAll, or setNorm operations. + /// If an exception is hit, then either no changes or all changes will have been committed to + /// the index (transactional semantics). + void commit(MapStringString commitUserData); + + /// Closes files associated with this index. Also saves any new deletions to disk. + /// No other methods should be called after this has been called. + void close(); + + /// Get a list of unique field names that exist in this index and have the specified field option information. + /// @param fieldOption specifies which field option should be available for the returned fields + /// @return Collection of Strings indicating the names of the fields. + virtual HashSet getFieldNames(FieldOption fieldOption) = 0; + + /// Return the IndexCommit that this reader has opened. This method is only implemented by those + /// readers that correspond to a Directory with its own segments_N file. + virtual IndexCommitPtr getIndexCommit(); + + /// Prints the filename and size of each file within a given compound file. Add the -extract flag + /// to extract files to the current working directory. In order to make the extracted version of + /// the index work, you have to copy the segments file from the compound index into the directory + /// where the extracted files are stored. + /// @param args Usage: IndexReader [-extract] + static void main(Collection args); + + /// Returns all commit points that exist in the Directory. Normally, because the default is {@link + /// KeepOnlyLastCommitDeletionPolicy}, there would be only one commit point. But if you're using a + /// custom {@link IndexDeletionPolicy} then there could be many commits. Once you have a given + /// commit, you can open a reader on it by calling {@link IndexReader#open(IndexCommit,bool)}. + /// There must be at least one commit in the Directory, else this method throws an exception. + /// Note that if a commit is in progress while this method is running, that commit may or may not + /// be returned array. + static Collection listCommits(const DirectoryPtr& dir); + + /// Returns the sequential sub readers that this reader is logically composed of. For example, + /// IndexSearcher uses this API to drive searching by one sub reader at a time. If this reader is + /// not composed of sequential child readers, it should return null. If this method returns an empty + /// array, that means this reader is a null reader (for example a MultiReader that has no sub readers). + /// + /// NOTE: You should not try using sub-readers returned by this method to make any changes (setNorm, + /// deleteDocument, etc.). While this might succeed for one composite reader (like MultiReader), it + /// will most likely lead to index corruption for other readers (like DirectoryReader obtained + /// through {@link #open}. Use the parent reader directly. + virtual Collection getSequentialSubReaders(); + + virtual LuceneObjectPtr getFieldCacheKey(); + + /// This returns null if the reader has no deletions. + virtual LuceneObjectPtr getDeletesCacheKey(); + + /// Returns the number of unique terms (across all fields) in this reader. + /// + /// This method returns int64_t, even though internally Lucene cannot handle more than 2^31 unique + /// terms, for a possible future when this limitation is removed. + virtual int64_t getUniqueTermCount(); + + /// For IndexReader implementations that use TermInfosReader to read terms, this returns the current + /// indexDivisor as specified when the reader was opened. + virtual int32_t getTermInfosIndexDivisor(); + +protected: + void ensureOpen(); + + static IndexReaderPtr open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor); + + /// Implements setNorm in subclass. + virtual void doSetNorm(int32_t doc, const String& field, uint8_t value) = 0; + + /// Implements deletion of the document numbered docNum. + /// Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}. + virtual void doDelete(int32_t docNum) = 0; + + /// Implements actual undeleteAll() in subclass. + virtual void doUndeleteAll() = 0; + + /// Does nothing by default. Subclasses that require a write lock for index modifications must + /// implement this method. + virtual void acquireWriteLock(); + + /// Commit changes resulting from delete, undeleteAll, or setNorm operations. + /// If an exception is hit, then either no changes or all changes will have been committed to + /// the index (transactional semantics). + void commit(); + + /// Implements commit. + virtual void doCommit(MapStringString commitUserData) = 0; + + /// Implements close. + virtual void doClose() = 0; + + friend class DirectoryReader; + friend class ParallelReader; +}; + } #endif diff --git a/include/IndexSearcher.h b/include/IndexSearcher.h index 41130118..7f620137 100644 --- a/include/IndexSearcher.h +++ b/include/IndexSearcher.h @@ -9,94 +9,94 @@ #include "Searcher.h" -namespace Lucene -{ - /// Implements search over a single IndexReader. +namespace Lucene { + +/// Implements search over a single IndexReader. +/// +/// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link +/// #search(QueryPtr, FilterPtr, int32_t)} methods. For performance reasons it is recommended to open only +/// one IndexSearcher and use it for all of your searches. +/// +/// NOTE: {@link IndexSearcher} instances are completely thread safe, meaning multiple threads can call any +/// of its methods, concurrently. If your application requires external synchronization, you should not +/// synchronize on the IndexSearcher instance; use your own (non-Lucene) objects instead. +class LPPAPI IndexSearcher : public Searcher { +public: + /// Creates a searcher searching the index in the named directory. You should pass readOnly = true, + /// since it gives much better concurrent performance, unless you intend to do write operations (delete + /// documents or change norms) with the underlying IndexReader. + /// @param path Directory where IndexReader will be opened + /// @param readOnly If true, the underlying IndexReader will be opened readOnly + IndexSearcher(const DirectoryPtr& path, bool readOnly = true); + + /// Creates a searcher searching the provided index. + IndexSearcher(const IndexReaderPtr& reader); + + /// Directly specify the reader, subReaders and their docID starts. + IndexSearcher(const IndexReaderPtr& reader, Collection subReaders, Collection docStarts); + + virtual ~IndexSearcher(); + + LUCENE_CLASS(IndexSearcher); + +public: + IndexReaderPtr reader; + +protected: + bool closeReader; + + Collection subReaders; + Collection docStarts; + + bool fieldSortDoTrackScores; + bool fieldSortDoMaxScore; + +public: + /// Return the {@link IndexReader} this searches. + IndexReaderPtr getIndexReader(); + + /// Note that the underlying IndexReader is not closed, if IndexSearcher was constructed with + /// IndexSearcher(const IndexReaderPtr& reader). If the IndexReader was supplied implicitly by specifying a + /// directory, then the IndexReader gets closed. + virtual void close(); + + virtual int32_t docFreq(const TermPtr& term); + virtual DocumentPtr doc(int32_t n); + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); + virtual int32_t maxDoc(); + + using Searcher::search; + using Searcher::explain; + + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); + + /// Just like {@link #search(WeightPtr, FilterPtr, int32_t, SortPtr)}, but you choose whether or not the + /// fields in the returned {@link FieldDoc} instances should be set by specifying fillFields. /// - /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link - /// #search(QueryPtr, FilterPtr, int32_t)} methods. For performance reasons it is recommended to open only - /// one IndexSearcher and use it for all of your searches. + /// NOTE: this does not compute scores by default. If you need scores, create a {@link TopFieldCollector} + /// instance by calling {@link TopFieldCollector#create} and then pass that to {@link #search(WeightPtr, + /// FilterPtr, CollectorPtr)}. + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort, bool fillFields); + + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); + virtual QueryPtr rewrite(const QueryPtr& query); + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); + + /// By default, no scores are computed when sorting by field (using {@link #search(QueryPtr, FilterPtr, + /// int32_t, SortPtr)}). You can change that, per IndexSearcher instance, by calling this method. Note + /// that this will incur a CPU cost. /// - /// NOTE: {@link IndexSearcher} instances are completely thread safe, meaning multiple threads can call any - /// of its methods, concurrently. If your application requires external synchronization, you should not - /// synchronize on the IndexSearcher instance; use your own (non-Lucene) objects instead. - class LPPAPI IndexSearcher : public Searcher - { - public: - /// Creates a searcher searching the index in the named directory. You should pass readOnly = true, - /// since it gives much better concurrent performance, unless you intend to do write operations (delete - /// documents or change norms) with the underlying IndexReader. - /// @param path Directory where IndexReader will be opened - /// @param readOnly If true, the underlying IndexReader will be opened readOnly - IndexSearcher(const DirectoryPtr& path, bool readOnly = true); - - /// Creates a searcher searching the provided index. - IndexSearcher(const IndexReaderPtr& reader); - - /// Directly specify the reader, subReaders and their docID starts. - IndexSearcher(const IndexReaderPtr& reader, Collection subReaders, Collection docStarts); - - virtual ~IndexSearcher(); - - LUCENE_CLASS(IndexSearcher); - - public: - IndexReaderPtr reader; - - protected: - bool closeReader; - - Collection subReaders; - Collection docStarts; - - bool fieldSortDoTrackScores; - bool fieldSortDoMaxScore; - - public: - /// Return the {@link IndexReader} this searches. - IndexReaderPtr getIndexReader(); - - /// Note that the underlying IndexReader is not closed, if IndexSearcher was constructed with - /// IndexSearcher(const IndexReaderPtr& reader). If the IndexReader was supplied implicitly by specifying a - /// directory, then the IndexReader gets closed. - virtual void close(); - - virtual int32_t docFreq(const TermPtr& term); - virtual DocumentPtr doc(int32_t n); - virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); - virtual int32_t maxDoc(); - - using Searcher::search; - using Searcher::explain; - - virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); - virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); - - /// Just like {@link #search(WeightPtr, FilterPtr, int32_t, SortPtr)}, but you choose whether or not the - /// fields in the returned {@link FieldDoc} instances should be set by specifying fillFields. - /// - /// NOTE: this does not compute scores by default. If you need scores, create a {@link TopFieldCollector} - /// instance by calling {@link TopFieldCollector#create} and then pass that to {@link #search(WeightPtr, - /// FilterPtr, CollectorPtr)}. - virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort, bool fillFields); - - virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); - virtual QueryPtr rewrite(const QueryPtr& query); - virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); - - /// By default, no scores are computed when sorting by field (using {@link #search(QueryPtr, FilterPtr, - /// int32_t, SortPtr)}). You can change that, per IndexSearcher instance, by calling this method. Note - /// that this will incur a CPU cost. - /// - /// @param doTrackScores If true, then scores are returned for every matching document in {@link TopFieldDocs}. - /// @param doMaxScore If true, then the max score for all matching docs is computed. - virtual void setDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore); - - protected: - void ConstructSearcher(const IndexReaderPtr& reader, bool closeReader); - void gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader); - void searchWithFilter(const IndexReaderPtr& reader, const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector); - }; + /// @param doTrackScores If true, then scores are returned for every matching document in {@link TopFieldDocs}. + /// @param doMaxScore If true, then the max score for all matching docs is computed. + virtual void setDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore); + +protected: + void ConstructSearcher(const IndexReaderPtr& reader, bool closeReader); + void gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader); + void searchWithFilter(const IndexReaderPtr& reader, const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector); +}; + } #endif diff --git a/include/IndexWriter.h b/include/IndexWriter.h index 787f4919..5ace8092 100644 --- a/include/IndexWriter.h +++ b/include/IndexWriter.h @@ -9,1105 +9,1104 @@ #include "MergePolicy.h" -namespace Lucene -{ - /// An IndexWriter creates and maintains an index. - /// - /// The create argument to the {@link #IndexWriter(DirectoryPtr, AnalyzerPtr, bool, int32_t) constructor} - /// determines whether a new index is created, or whether an existing index is opened. Note that you can - /// open an index with create=true even while readers are using the index. The old readers will continue - /// to search the "point in time" snapshot they had opened, and won't see the newly created index until - /// they re-open. There are also {@link #IndexWriter(DirectoryPtr, AnalyzerPtr, int32_t) constructors} - /// with no create argument which will create a new index if there is not already an index at the provided - /// path and otherwise open the existing index. - /// - /// In either case, documents are added with {@link #addDocument(DocumentPtr) addDocument} and removed - /// with {@link #deleteDocuments(TermPtr)} or {@link #deleteDocuments(QueryPtr)}. A document can be updated - /// with {@link #updateDocument(TermPtr, DocumentPtr) updateDocument} (which just deletes and then adds - /// the entire document). When finished adding, deleting and updating documents, {@link #close() close} - /// should be called. - /// - /// These changes are buffered in memory and periodically flushed to the {@link Directory} (during the - /// above method calls). A flush is triggered when there are enough buffered deletes (see - /// {@link #setMaxBufferedDeleteTerms}) or enough added documents since the last flush, whichever is - /// sooner. For the added documents, flushing is triggered either by RAM usage of the documents (see - /// {@link #setRAMBufferSizeMB}) or the number of added documents. The default is to flush when RAM usage - /// hits 16 MB. For best indexing speed you should flush by RAM usage with a large RAM buffer. Note that - /// flushing just moves the internal buffered state in IndexWriter into the index, but these changes are - /// not visible to IndexReader until either {@link #commit()} or {@link #close} is called. A flush may - /// also trigger one or more segment merges which by default run with a background thread so as not to - /// block the addDocument calls (see mergePolicy below for changing the {@link MergeScheduler}). - /// - /// If an index will not have more documents added for a while and optimal search performance is desired, - /// then either the full {@link #optimize() optimize} method or partial {@link #optimize(int32_t)} method - /// should be called before the index is closed. - /// - /// Opening an IndexWriter creates a lock file for the directory in use. Trying to open another IndexWriter - /// on the same directory will lead to a LockObtainFailed exception. The LockObtainFailed exception is also - /// thrown if an IndexReader on the same directory is used to delete documents from the index. - /// - /// IndexWriter allows an optional {@link IndexDeletionPolicy} implementation to be specified. You can use - /// this to control when prior commits are deleted from the index. The default policy is {@link - /// KeepOnlyLastCommitDeletionPolicy} which removes all prior commits as soon as a new commit is done (this - /// matches behavior before 2.2). Creating your own policy can allow you to explicitly keep previous - /// "point in time" commits alive in the index for some time, to allow readers to refresh to the new commit - /// without having the old commit deleted out from under them. This is necessary on file systems like NFS - /// that do not support "delete on last close" semantics, which Lucene's "point in time" search normally - /// relies on. - /// - /// IndexWriter allows you to separately change the {@link MergePolicy} and the {@link MergeScheduler}. - /// The {@link MergePolicy} is invoked whenever there are changes to the segments in the index. Its role - /// is to select which merges to do, if any, and return a {@link MergePolicy.MergeSpecification} describing - /// the merges. It also selects merges to do for optimize(). (The default is {@link LogByteSizeMergePolicy}. - /// Then, the {@link MergeScheduler} is invoked with the requested merges and it decides when and how to run - /// the merges. The default is {@link ConcurrentMergeScheduler}. - /// - /// NOTE: if you hit an std::bad_alloc then IndexWriter will quietly record this fact and block all future - /// segment commits. This is a defensive measure in case any internal state (buffered documents and - /// deletions) were corrupted. Any subsequent calls to {@link #commit()} will throw an IllegalState - /// exception. The only course of action is to call {@link #close()}, which internally will call {@link - /// #rollback()}, to undo any changes to the index since the last commit. You can also just call {@link - /// #rollback()} directly. - /// - /// NOTE: {@link IndexWriter} instances are completely thread safe, meaning multiple threads can call any of - /// its methods, concurrently. If your application requires external synchronization, you should not - /// synchronize on the IndexWriter instance as this may cause deadlock; use your own (non-Lucene) objects - /// instead. - /// - /// Clarification: Check Points (and commits) - /// IndexWriter writes new index files to the directory without writing a new segments_N file which - /// references these new files. It also means that the state of the in memory SegmentInfos object is different - /// than the most recent segments_N file written to the directory. - /// - /// Each time the SegmentInfos is changed, and matches the (possibly modified) directory files, we have a new - /// "check point". If the modified/new SegmentInfos is written to disk - as a new (generation of) segments_N - /// file - this check point is also an IndexCommit. - /// - /// A new checkpoint always replaces the previous checkpoint and becomes the new "front" of the index. This - /// allows the IndexFileDeleter to delete files that are referenced only by stale checkpoints (files that were - /// created since the last commit, but are no longer referenced by the "front" of the index). For this, - /// IndexFileDeleter keeps track of the last non commit checkpoint. - class LPPAPI IndexWriter : public LuceneObject - { - protected: - IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexingChainPtr& indexingChain, const IndexCommitPtr& commit); - - public: - IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl); - IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl); - IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl); - IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl); - IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexCommitPtr& commit); - virtual ~IndexWriter(); - - LUCENE_CLASS(IndexWriter); - - protected: - int64_t writeLockTimeout; - - /// The normal read buffer size defaults to 1024, but increasing this during merging seems to - /// yield performance gains. However we don't want to increase it too much because there are - /// quite a few BufferedIndexInputs created during merging. - static const int32_t MERGE_READ_BUFFER_SIZE; - - SynchronizePtr messageIDLock; - static int32_t MESSAGE_ID; - int32_t messageID; - bool hitOOM; - - DirectoryPtr directory; // where this index resides - AnalyzerPtr analyzer; // how to analyze text - - bool create; - IndexDeletionPolicyPtr deletionPolicy; - IndexingChainPtr indexingChain; - IndexCommitPtr indexCommit; - - SimilarityPtr similarity; // how to normalize - - int64_t changeCount; // increments every time a change is completed - int64_t lastCommitChangeCount; // last changeCount that was committed - - SegmentInfosPtr rollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails - MapSegmentInfoInt rollbackSegments; - - SegmentInfosPtr localRollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails - int32_t localFlushedDocCount; - - SegmentInfosPtr segmentInfos; // the segments - - DocumentsWriterPtr docWriter; - IndexFileDeleterPtr deleter; - - SetSegmentInfo segmentsToOptimize; // used by optimize to note those needing optimization - int32_t optimizeMaxNumSegments; - - LockPtr writeLock; - - int32_t termIndexInterval; - - bool closed; - bool closing; - - SetSegmentInfo mergingSegments; - MergePolicyPtr mergePolicy; - MergeSchedulerPtr mergeScheduler; - Collection pendingMerges; - SetOneMerge runningMerges; - Collection mergeExceptions; - int64_t mergeGen; - bool stopMerges; - - int32_t flushCount; - int32_t flushDeletesCount; - - /// Used to only allow one addIndexes to proceed at once - int32_t readCount; // count of how many threads are holding read lock - int64_t writeThread; // non-null if any thread holds write lock - int32_t upgradeCount; - - int32_t readerTermsIndexDivisor; - - // This is a "write once" variable (like the organic dye on a DVD-R that may or may not - // be heated by a laser and then cooled to permanently record the event): it's false, - // until getReader() is called for the first time, at which point it's switched to true - // and never changes back to false. Once this is true, we hold open and reuse SegmentReader - // instances internally for applying deletes, doing merges, and reopening near real-time readers. - bool poolReaders; - - /// The maximum number of terms that will be indexed for a single field in a document. This - /// limits the amount of memory required for indexing, so that collections with very large files - /// will not crash the indexing process by running out of memory. - /// Note that this effectively truncates large documents, excluding from the index terms that - /// occur further in the document. If you know your source documents are large, be sure to set - /// this value high enough to accommodate the expected size. If you set it to INT_MAX, then the - /// only limit is your memory, but you should anticipate an std::bad_alloc. By default, no more - /// than 10,000 terms will be indexed for a field. - /// - /// @see #setMaxFieldLength(int32_t) - int32_t maxFieldLength; - - InfoStreamPtr infoStream; - static InfoStreamPtr defaultInfoStream; - - HashSet synced; // files that have been sync'd already - HashSet syncing; // files that are now being sync'd - - IndexReaderWarmerPtr mergedSegmentWarmer; - - /// Used only by commit; lock order is commitLock -> IW - SynchronizePtr commitLock; - - INTERNAL: - SegmentInfosPtr pendingCommit; // set when a commit is pending (after prepareCommit() & before commit()) - int64_t pendingCommitChangeCount; - - ReaderPoolPtr readerPool; - - public: - /// Default value for the write lock timeout (1,000). - /// @see #setDefaultWriteLockTimeout - static int64_t WRITE_LOCK_TIMEOUT; - - static const String WRITE_LOCK_NAME; - - /// Value to denote a flush trigger is disabled. - static const int32_t DISABLE_AUTO_FLUSH; - - /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using - /// {@link #setMaxBufferedDocs(int32_t)}. - static const int32_t DEFAULT_MAX_BUFFERED_DOCS; - - /// Default value is 16 MB (which means flush when buffered docs consume 16 MB RAM). - /// Change using {@link #setRAMBufferSizeMB}. - static const double DEFAULT_RAM_BUFFER_SIZE_MB; - - /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using - /// {@link #setMaxBufferedDeleteTerms(int32_t)}. - static const int32_t DEFAULT_MAX_BUFFERED_DELETE_TERMS; - - /// Default value is 10,000. Change using {@link #setMaxFieldLength(int32_t)}. - static const int32_t DEFAULT_MAX_FIELD_LENGTH; - - /// Default value is 128. Change using {@link #setTermIndexInterval(int32_t)}. - static const int32_t DEFAULT_TERM_INDEX_INTERVAL; - - /// Absolute hard maximum length for a term. If a term arrives from the analyzer longer than - /// this length, it is skipped and a message is printed to infoStream, if set (see {@link - /// #setInfoStream}). - static int32_t MAX_TERM_LENGTH(); - - /// Sets the maximum field length to INT_MAX - static const int32_t MaxFieldLengthUNLIMITED; - - /// Sets the maximum field length to {@link #DEFAULT_MAX_FIELD_LENGTH} - static const int32_t MaxFieldLengthLIMITED; - - public: - virtual void initialize(); - - /// Returns a read-only reader, covering all committed as well as un-committed changes to the - /// index. This provides "near real-time" searching, in that changes made during an IndexWriter - /// session can be quickly made available for searching without closing the writer nor calling - /// {@link #commit}. - /// - /// Note that this is functionally equivalent to calling {#commit} and then using {@link - /// IndexReader#open} to open a new reader. But the turnaround time of this method should be - /// faster since it avoids the potentially costly {@link #commit}. - /// - /// You must close the {@link IndexReader} returned by this method once you are done using it. - /// - /// It's near real-time because there is no hard guarantee on how quickly you can get a new - /// reader after making changes with IndexWriter. You'll have to experiment in your situation - /// to determine if it's fast enough. As this is a new and experimental feature, please report - /// back on your findings so we can learn, improve and iterate. - /// - /// The resulting reader supports {@link IndexReader#reopen}, but that call will simply forward - /// back to this method (though this may change in the future). - /// - /// The very first time this method is called, this writer instance will make every effort to - /// pool the readers that it opens for doing merges, applying deletes, etc. This means additional - /// resources (RAM, file descriptors, CPU time) will be consumed. - /// - /// For lower latency on reopening a reader, you should call {@link #setMergedSegmentWarmer} to - /// pre-warm a newly merged segment before it's committed to the index. This is important for - /// minimizing index-to-search delay after a large merge. - /// - /// If an addIndexes* call is running in another thread, then this reader will only search those - /// segments from the foreign index that have been successfully copied over, so far. - /// - /// NOTE: Once the writer is closed, any outstanding readers may continue to be used. However, - /// if you attempt to reopen any of those readers, you'll hit an AlreadyClosed exception. - /// - /// NOTE: This API is experimental and might change in incompatible ways in the next release. - /// - /// @return IndexReader that covers entire index plus all changes made so far by this IndexWriter - /// instance - virtual IndexReaderPtr getReader(); - - /// Like {@link #getReader}, except you can specify which termInfosIndexDivisor should be used for - /// any newly opened readers. - /// - /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the - /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at - /// indexing time while this setting can be set per reader. When set to N, then one in every - /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 - /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. - /// The default value is 1. Set this to -1 to skip loading the terms index entirely. - virtual IndexReaderPtr getReader(int32_t termInfosIndexDivisor); - - /// Obtain the number of deleted docs for a pooled reader. If the reader isn't being pooled, - /// the segmentInfo's delCount is returned. - virtual int32_t numDeletedDocs(const SegmentInfoPtr& info); - - virtual void acquireWrite(); - virtual void releaseWrite(); - virtual void acquireRead(); - - /// Allows one readLock to upgrade to a writeLock even if there are other readLocks as long - /// as all other readLocks are also blocked in this method - virtual void upgradeReadToWrite(); - - virtual void releaseRead(); - virtual bool isOpen(bool includePendingClose); - virtual void message(const String& message); - - /// Get the current setting of whether newly flushed segments will use the compound file format. - /// Note that this just returns the value previously set with setUseCompoundFile(bool), or the - /// default value (true). You cannot use this to query the status of previously flushed segments. - /// - /// Note that this method is a convenience method: it just calls mergePolicy.getUseCompoundFile - /// as long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument - /// exception is thrown. - /// @see #setUseCompoundFile(bool) - virtual bool getUseCompoundFile(); - - /// Setting to turn on usage of a compound file. When on, multiple files for each segment are - /// merged into a single file when a new segment is flushed. - /// - /// Note that this method is a convenience method: it just calls mergePolicy.setUseCompoundFile - /// as long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument - /// exception is thrown. - virtual void setUseCompoundFile(bool value); - - /// Set the Similarity implementation used by this IndexWriter. - virtual void setSimilarity(const SimilarityPtr& similarity); - - /// Return the Similarity implementation used by this IndexWriter. - /// This defaults to the current value of {@link Similarity#getDefault()}. - virtual SimilarityPtr getSimilarity(); - - /// Set the interval between indexed terms. Large values cause less memory to be used by - /// IndexReader, but slow random-access to terms. Small values cause more memory to be used by - /// an IndexReader, and speed random-access to terms. - /// - /// This parameter determines the amount of computation required per query term, regardless of - /// the number of documents that contain that term. In particular, it is the maximum number of - /// other terms that must be scanned before a term is located and its frequency and position - /// information may be processed. In a large index with user-entered query terms, query - /// processing time is likely to be dominated not by term lookup but rather by the processing of - /// frequency and positional data. In a small index or when many uncommon query terms are - /// generated (eg., by wildcard queries) term lookup may become a dominant cost. - /// - /// In particular, numUniqueTerms/interval terms are read into memory by an IndexReader, and on - /// average, interval/2 terms must be scanned for each random term access. - /// - /// @see #DEFAULT_TERM_INDEX_INTERVAL - virtual void setTermIndexInterval(int32_t interval); - - /// Return the interval between indexed terms. - /// @see #setTermIndexInterval(int32_t) - virtual int32_t getTermIndexInterval(); - - /// Set the merge policy used by this writer. - virtual void setMergePolicy(const MergePolicyPtr& mp); - - /// Returns the current MergePolicy in use by this writer. - /// @see #setMergePolicy - virtual MergePolicyPtr getMergePolicy(); - - /// Set the merge scheduler used by this writer. - virtual void setMergeScheduler(const MergeSchedulerPtr& mergeScheduler); - - /// Returns the current MergePolicy in use by this writer. - /// @see #setMergePolicy - virtual MergeSchedulerPtr getMergeScheduler(); - - /// Determines the largest segment (measured by document count) that may be merged with other - /// segments. Small values (eg., less than 10,000) are best for interactive indexing, as this - /// limits the length of pauses while indexing to a few seconds. Larger values are best for - /// batched indexing and speedier searches. - /// - /// The default value is INT_MAX. - /// - /// Note that this method is a convenience method: it just calls mergePolicy.setMaxMergeDocs as - /// long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument - /// exception is thrown. - /// - /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit - /// by net size (in MB) of the segment, using {@link LogByteSizeMergePolicy#setMaxMergeMB}. - virtual void setMaxMergeDocs(int32_t maxMergeDocs); - - /// Returns the largest segment (measured by document count) that may be merged with other - /// segments. - /// - /// Note that this method is a convenience method: it just calls mergePolicy.getMaxMergeDocs as - /// long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument - /// exception is thrown. - /// - /// @see #setMaxMergeDocs - virtual int32_t getMaxMergeDocs(); - - /// The maximum number of terms that will be indexed for a single field in a document. This - /// limits the amount of memory required for indexing, so that collections with very large files - /// will not crash the indexing process by running out of memory. This setting refers to the - /// number of running terms, not to the number of different terms. - /// Note: this silently truncates large documents, excluding from the index all terms that occur - /// further in the document. If you know your source documents are large, be sure to set this - /// value high enough to accommodate the expected size. If you set it to INT_MAX, then the only - /// limit is your memory, but you should anticipate an std::bad_alloc. - /// By default, no more than {@link #DEFAULT_MAX_FIELD_LENGTH} terms will be indexed for a field. - virtual void setMaxFieldLength(int32_t maxFieldLength); - - /// Returns the maximum number of terms that will be indexed for a single field in a document. - /// @see #setMaxFieldLength - virtual int32_t getMaxFieldLength(); - - /// Sets the termsIndexDivisor passed to any readers that IndexWriter opens, for example when - /// applying deletes or creating a near-real-time reader in {@link IndexWriter#getReader}. - /// Default value is {@link IndexReader#DEFAULT_TERMS_INDEX_DIVISOR}. - virtual void setReaderTermsIndexDivisor(int32_t divisor); - - /// @see #setReaderTermsIndexDivisor() - virtual int32_t getReaderTermsIndexDivisor(); - - /// Determines the minimal number of documents required before the buffered in-memory documents - /// are flushed as a new Segment. Large values generally gives faster indexing. - /// - /// When this is set, the writer will flush every maxBufferedDocs added documents. Pass in - /// {@link #DISABLE_AUTO_FLUSH} to prevent triggering a flush due to number of buffered - /// documents. Note that if flushing by RAM usage is also enabled, then the flush will be - /// triggered by whichever comes first. - /// - /// Disabled by default (writer flushes by RAM usage). - /// - /// @see #setRAMBufferSizeMB - virtual void setMaxBufferedDocs(int32_t maxBufferedDocs); - - /// Returns the number of buffered added documents that will trigger a flush if enabled. - /// @see #setMaxBufferedDocs - virtual int32_t getMaxBufferedDocs(); - - /// Determines the amount of RAM that may be used for buffering added documents and deletions - /// before they are flushed to the Directory. Generally for faster indexing performance it's - /// best to flush by RAM usage instead of document count and use as large a RAM buffer as you can. - /// - /// When this is set, the writer will flush whenever buffered documents and deletions use this - /// much RAM. Pass in {@link #DISABLE_AUTO_FLUSH} to prevent triggering a flush due to RAM usage. - /// Note that if flushing by document count is also enabled, then the flush will be triggered by - /// whichever comes first. - /// - /// Note: the account of RAM usage for pending deletions is only approximate. Specifically, if - /// you delete by Query, Lucene currently has no way to measure the RAM usage if individual - /// Queries so the accounting will under-estimate and you should compensate by either calling - /// commit() periodically yourself, or by using {@link #setMaxBufferedDeleteTerms} to flush by - /// count instead of RAM usage (each buffered delete Query counts as one). - /// - /// Note: because IndexWriter uses int32_t when managing its internal storage, the absolute - /// maximum value for this setting is somewhat less than 2048 MB. The precise limit depends on - /// various factors, such as how large your documents are, how many fields have norms, etc., so - /// it's best to set this value comfortably under 2048. - /// - /// The default value is {@link #DEFAULT_RAM_BUFFER_SIZE_MB}. - virtual void setRAMBufferSizeMB(double mb); - - /// Returns the value set by {@link #setRAMBufferSizeMB} if enabled. - virtual double getRAMBufferSizeMB(); - - /// Determines the minimal number of delete terms required before the buffered in-memory delete - /// terms are applied and flushed. If there are documents buffered in memory at the time, they - /// are merged and a new segment is created. - /// - /// Disabled by default (writer flushes by RAM usage). - /// @see #setRAMBufferSizeMB - virtual void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); - - /// Returns the number of buffered deleted terms that will trigger a flush if enabled. - /// @see #setMaxBufferedDeleteTerms - virtual int32_t getMaxBufferedDeleteTerms(); - - /// Determines how often segment indices are merged by addDocument(). With smaller values, less - /// RAM is used while indexing, and searches on unoptimized indices are faster, but indexing - /// speed is slower. With larger values, more RAM is used during indexing, and while searches - /// on unoptimized indices are slower, indexing is faster. Thus larger values (> 10) are best - /// for batch index creation, and smaller values (< 10) for indices that are interactively maintained. - /// - /// Note that this method is a convenience method: it just calls mergePolicy.setMergeFactor as long - /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception - /// is thrown. This must never be less than 2. The default value is 10. - virtual void setMergeFactor(int32_t mergeFactor); - - /// Returns the number of segments that are merged at once and also controls the total number of - /// segments allowed to accumulate in the index. - /// - /// Note that this method is a convenience method: it just calls mergePolicy.getMergeFactor as long - /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception - /// is thrown. - /// @see #setMergeFactor - virtual int32_t getMergeFactor(); - - /// If non-null, this will be the default infoStream used by a newly instantiated IndexWriter. - /// @see #setInfoStream - static void setDefaultInfoStream(const InfoStreamPtr& infoStream); - - /// Returns the current default infoStream for newly instantiated IndexWriters. - /// @see #setDefaultInfoStream - static InfoStreamPtr getDefaultInfoStream(); - - /// If non-null, information about merges, deletes and a message when maxFieldLength is reached - /// will be printed to this. - virtual void setInfoStream(const InfoStreamPtr& infoStream); - - /// Returns the current infoStream in use by this writer. - /// @see #setInfoStream - virtual InfoStreamPtr getInfoStream(); - - /// Returns true if verbosing is enabled (i.e., infoStream != null). - virtual bool verbose(); - - /// Sets the maximum time to wait for a write lock (in milliseconds) for this instance of - /// IndexWriter. @see #setDefaultWriteLockTimeout to change the default value for all instances - /// of IndexWriter. - virtual void setWriteLockTimeout(int64_t writeLockTimeout); - - /// Returns allowed timeout when acquiring the write lock. - /// @see #setWriteLockTimeout - virtual int64_t getWriteLockTimeout(); - - /// Sets the default (for any instance of IndexWriter) maximum time to wait for a write lock - /// (in milliseconds). - static void setDefaultWriteLockTimeout(int64_t writeLockTimeout); - - /// Returns default write lock timeout for newly instantiated IndexWriters. - /// @see #setDefaultWriteLockTimeout - static int64_t getDefaultWriteLockTimeout(); - - /// Commits all changes to an index and closes all associated files. Note that this may be - /// a costly operation, so try to re-use a single writer instead of closing and opening a - /// new one. See {@link #commit()} for caveats about write caching done by some IO devices. - /// - /// If an Exception is hit during close, eg due to disk full or some other reason, then both - /// the on-disk index and the internal state of the IndexWriter instance will be consistent. - /// However, the close will not be complete even though part of it (flushing buffered documents) - /// may have succeeded, so the write lock will still be held. - /// - /// If you can correct the underlying cause (eg free up some disk space) then you can call - /// close() again. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer, again. - virtual void close(); - - /// Closes the index with or without waiting for currently running merges to finish. This is - /// only meaningful when using a MergeScheduler that runs merges in background threads. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer, again. - /// - /// NOTE: it is dangerous to always call close(false), especially when IndexWriter is not open - /// for very long, because this can result in "merge starvation" whereby long merges will never - /// have a chance to finish. This will cause too many segments in your index over time. - /// - /// @param waitForMerges if true, this call will block until all merges complete; else, it will - /// ask all running merges to abort, wait until those merges have finished (which should be at - /// most a few seconds), and then return. - virtual void close(bool waitForMerges); - - /// Returns the Directory used by this index. - virtual DirectoryPtr getDirectory(); - - /// Returns the analyzer used by this index. - virtual AnalyzerPtr getAnalyzer(); - - /// Returns total number of docs in this index, including docs not yet flushed (still in the - /// RAM buffer), not counting deletions. - /// @see #numDocs - virtual int32_t maxDoc(); - - /// Returns total number of docs in this index, including docs not yet flushed (still in the - /// RAM buffer), and including deletions. - /// NOTE: buffered deletions are not counted. If you really need these to be counted you should - /// call {@link #commit()} first. - virtual int32_t numDocs(); - - virtual bool hasDeletions(); - - /// Adds a document to this index. If the document contains more than {@link - /// #setMaxFieldLength(int32_t)} terms for a given field, the remainder are discarded. - /// - /// Note that if an Exception is hit (for example disk full) then the index will be consistent, - /// but this document may not have been added. Furthermore, it's possible the index will have - /// one segment in non-compound format even when using compound files (when a merge has partially - /// succeeded). - /// - /// This method periodically flushes pending documents to the Directory, and also periodically - /// triggers segment merges in the index according to the {@link MergePolicy} in use. - /// - /// Merges temporarily consume space in the directory. The amount of space required is up to 1X - /// the size of all segments being merged, when no size of all segments being merged, when no - /// 2X the size of all segments being merged when readers/searchers are open against the index - /// (see {@link #optimize()} for details). The sequence of primitive merge operations performed - /// is governed by the merge policy. - /// - /// Note that each term in the document can be no longer than 16383 characters, otherwise an - /// IllegalArgument exception will be thrown. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void addDocument(const DocumentPtr& doc); - - /// Adds a document to this index, using the provided analyzer instead of the value of {@link - /// #getAnalyzer()}. If the document contains more than {@link #setMaxFieldLength(int32_t)} terms - /// for a given field, the remainder are discarded. - /// - /// See {@link #addDocument(DocumentPtr)} for details on index and IndexWriter state after an - /// exception, and flushing/merging temporary free space requirements. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer); - - /// Deletes the document(s) containing term. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param term the term to identify the documents to be deleted - virtual void deleteDocuments(const TermPtr& term); - - /// Deletes the document(s) containing any of the terms. All deletes are flushed at the same time. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param terms array of terms to identify the documents to be deleted - virtual void deleteDocuments(Collection terms); - - /// Deletes the document(s) matching the provided query. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param query the query to identify the documents to be deleted - virtual void deleteDocuments(const QueryPtr& query); - - /// Deletes the document(s) matching any of the provided queries. All deletes are flushed at - /// the same time. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param queries array of queries to identify the documents to be deleted - virtual void deleteDocuments(Collection queries); - - /// Updates a document by first deleting the document(s) containing term and then adding the new - /// document. The delete and then add are atomic as seen by a reader on the same index (flush - /// may happen only after the add). - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param term the term to identify the document(s) to be deleted - /// @param doc the document to be added - virtual void updateDocument(const TermPtr& term, const DocumentPtr& doc); - - /// Updates a document by first deleting the document(s) containing term and then adding the new - /// document. The delete and then add are atomic as seen by a reader on the same index (flush - /// may happen only after the add). - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param term the term to identify the document(s) to be deleted - /// @param doc the document to be added - /// @param analyzer the analyzer to use when analyzing the document - virtual void updateDocument(const TermPtr& term, const DocumentPtr& doc, const AnalyzerPtr& analyzer); - - virtual int32_t getSegmentCount(); - virtual int32_t getNumBufferedDocuments(); - virtual int32_t getDocCount(int32_t i); - virtual int32_t getFlushCount(); - virtual int32_t getFlushDeletesCount(); - - virtual String newSegmentName(); - - /// Requests an "optimize" operation on an index, priming the index for the fastest available - /// search. Traditionally this has meant merging all segments into a single segment as is done in - /// the default merge policy, but individual merge policies may implement optimize in different ways. - /// - /// It is recommended that this method be called upon completion of indexing. In environments with - /// frequent updates, optimize is best done during low volume times, if at all. - /// - /// Note that optimize requires 2X the index size free space in your Directory (3X if you're using - /// compound file format). For example, if your index size is 10 MB then you need 20 MB free for - /// optimize to complete (30 MB if you're using compound file format). - /// - /// If some but not all readers re-open while an optimize is underway, this will cause > 2X temporary - /// space to be consumed as those new readers will then hold open the partially optimized segments at - /// that time. It is best not to re-open readers while optimize is running. - /// - /// The actual temporary usage could be much less than these figures (it depends on many factors). - /// - /// In general, once the optimize completes, the total size of the index will be less than the size - /// of the starting index. It could be quite a bit smaller (if there were many pending deletes) or - /// just slightly smaller. - /// - /// If an Exception is hit during optimize(), for example due to disk full, the index will not be - /// corrupt and no documents will have been lost. However, it may have been partially optimized - /// (some segments were merged but not all), and it's possible that one of the segments in the index - /// will be in non-compound format even when using compound file format. This will occur when the - /// exception is hit during conversion of the segment into compound format. - /// - /// This call will optimize those segments present in the index when the call started. If other - /// threads are still adding documents and flushing segments, those newly created segments will not - /// be optimized unless you call optimize again. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @see LogMergePolicy#findMergesForOptimize - virtual void optimize(); - - /// Optimize the index down to <= maxNumSegments. If maxNumSegments==1 then this is the same as - /// {@link #optimize()}. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param maxNumSegments maximum number of segments left in the index after optimization finishes - virtual void optimize(int32_t maxNumSegments); - - /// Just like {@link #optimize()}, except you can specify whether the call should block until the - /// optimize completes. This is only meaningful with a {@link MergeScheduler} that is able to run - /// merges in background threads. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void optimize(bool doWait); - - /// Just like {@link #optimize(int32_t)}, except you can specify whether the call should block - /// until the optimize completes. This is only meaningful with a {@link MergeScheduler} that is - /// able to run merges in background threads. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void optimize(int32_t maxNumSegments, bool doWait); - - /// Just like {@link #expungeDeletes()}, except you can specify whether the call should block - /// until the operation completes. This is only meaningful with a {@link MergeScheduler} that - /// is able to run merges in background threads. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void expungeDeletes(bool doWait); - - /// Expunges all deletes from the index. When an index has many document deletions (or updates - /// to existing documents), it's best to either call optimize or expungeDeletes to remove all - /// unused data in the index associated with the deleted documents. To see how many deletions - /// you have pending in your index, call {@link IndexReader#numDeletedDocs}. This saves disk - /// space and memory usage while searching. expungeDeletes should be somewhat faster than - /// optimize since it does not insist on reducing the index to a single segment (though, this - /// depends on the {@link MergePolicy}; see {@link MergePolicy#findMergesToExpungeDeletes}.). - /// Note that this call does not first commit any buffered documents, so you must do so yourself - /// if necessary. See also {@link #expungeDeletes(bool)} - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void expungeDeletes(); - - /// Asks the mergePolicy whether any merges are necessary now and if so, runs the requested - /// merges and then iterate (test again if merges are needed) until no more merges are returned - /// by the mergePolicy. - /// - /// Explicit calls to maybeMerge() are usually not necessary. The most common case is when merge - /// policy parameters have changed. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void maybeMerge(); - - /// The {@link MergeScheduler} calls this method to retrieve the next merge requested by the - /// MergePolicy. - virtual OneMergePtr getNextMerge(); - - /// Close the IndexWriter without committing any changes that have occurred since the last commit - /// (or since it was opened, if commit hasn't been called). This removes any temporary files that - /// had been created, after which the state of the index will be the same as it was when commit() - /// was last called or when this writer was first opened. This also clears a previous call to - /// {@link #prepareCommit}. - virtual void rollback(); - - /// Delete all documents in the index. - /// - /// This method will drop all buffered documents and will remove all segments from the index. This - /// change will not be visible until a {@link #commit()} has been called. This method can be rolled - /// back using {@link #rollback()}. - /// - /// NOTE: this method is much faster than using {@link #deleteDocuments()}. - /// - /// NOTE: this method will forcefully abort all merges in progress. If other threads are running - /// {@link #optimize()} or any of the addIndexes methods, they will receive {@link - /// MergePolicy.MergeAbortedException} - virtual void deleteAll(); - - /// Wait for any currently outstanding merges to finish. - /// - /// It is guaranteed that any merges started prior to calling this method will have completed once - /// this method completes. - virtual void waitForMerges(); - - /// Merges all segments from an array of indexes into this index. - /// - /// This may be used to parallelize batch indexing. A large document collection can be broken into - /// sub-collections. Each sub-collection can be indexed in parallel, on a different thread, process - /// or machine. The complete index can then be created by merging sub-collection indexes with this - /// method. - /// - /// NOTE: the index in each Directory must not be changed (opened by a writer) while this method is - /// running. This method does not acquire a write lock in each input Directory, so it is up to the - /// caller to enforce this. - /// - /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will - /// be paused until this method completes. - /// - /// This method is transactional in how exceptions are handled: it does not commit a new segments_N - /// file until all indexes are added. This means if an exception occurs (for example disk full), - /// then either no indexes will have been added or they all will have been. - /// - /// Note that this requires temporary free space in the Directory up to 2X the sum of all input - /// indexes (including the starting index). If readers/searchers are open against the starting index, - /// then temporary free space required will be higher by the size of the starting index (see - /// {@link #optimize()} for details). - /// - /// Once this completes, the final size of the index will be less than the sum of all input index - /// sizes (including the starting index). It could be quite a bit smaller (if there were many pending - /// deletes) or just slightly smaller. - /// - /// This requires this index not be among those to be added. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void addIndexesNoOptimize(Collection dirs); - - /// Merges the provided indexes into this index. - /// After this completes, the index is optimized. The provided IndexReaders are not closed. - /// - /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will - /// be paused until this method completes. - /// - /// See {@link #addIndexesNoOptimize} for details on transactional semantics, temporary free space - /// required in the Directory, and non-CFS segments on an exception. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void addIndexes(Collection readers); - - /// Prepare for commit. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// @see #prepareCommit(MapStringString) - virtual void prepareCommit(); - - /// Prepare for commit, specifying commitUserData Map (String -> String). This does the first phase - /// of 2-phase commit. This method does all steps necessary to commit changes since this writer was - /// opened: flushes pending added and deleted docs, syncs the index files, writes most of next - /// segments_N file. After calling this you must call either {@link #commit()} to finish the commit, - /// or {@link #rollback()} to revert the commit and undo all changes done since the writer was opened. - /// - /// You can also just call {@link #commit(Map)} directly without prepareCommit first in which case - /// that method will internally call prepareCommit. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @param commitUserData Opaque Map (String->String) that's recorded into the segments file in the - /// index, and retrievable by {@link IndexReader#getCommitUserData}. Note that when IndexWriter - /// commits itself during {@link #close}, the commitUserData is unchanged (just carried over from the - /// prior commit). If this is null then the previous commitUserData is kept. Also, the commitUserData - // will only "stick" if there are actually changes in the index to commit. - virtual void prepareCommit(MapStringString commitUserData); - - /// Commits all pending changes (added & deleted documents, optimizations, segment merges, added - /// indexes, etc.) to the index, and syncs all referenced index files, such that a reader will see the - /// changes and the index updates will survive an OS or machine crash or power loss. Note that this - /// does not wait for any running background merges to finish. This may be a costly operation, so you - /// should test the cost in your application and do it only when really necessary. - /// - /// Note that this operation calls Directory.sync on the index files. That call should not return until - /// the file contents & metadata are on stable storage. For FSDirectory, this calls the OS's fsync. - /// But, beware: some hardware devices may in fact cache writes even during fsync, and return before the - /// bits are actually on stable storage, to give the appearance of faster performance. If you have such - /// a device, and it does not have a battery backup (for example) then on power loss it may still lose - /// data. Lucene cannot guarantee consistency on such devices. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - /// - /// @see #prepareCommit - /// @see #commit(MapStringString) - virtual void commit(); - - /// Commits all changes to the index, specifying a commitUserData Map (String -> String). This just - /// calls {@link #prepareCommit(MapStringString)} (if you didn't already call it) and then - /// {@link #finishCommit}. - /// - /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. - virtual void commit(MapStringString commitUserData); - - /// Return the total size of all index files currently cached in memory. Useful for size management - /// with flushRamDocs() - virtual int64_t ramSizeInBytes(); - - /// Return the number of documents currently buffered in RAM. - virtual int32_t numRamDocs(); - - /// Merges the indicated segments, replacing them in the stack with a single segment. - virtual void merge(const OneMergePtr& merge); - - /// Hook that's called when the specified merge is complete. - virtual void mergeSuccess(const OneMergePtr& merge); - - /// Checks whether this merge involves any segments already participating in a merge. If not, this - /// merge is "registered", meaning we record that its segments are now participating in a merge, - /// and true is returned. Else (the merge conflicts) false is returned. - virtual bool registerMerge(const OneMergePtr& merge); - - /// Does initial setup for a merge, which is fast but holds the synchronized lock on IndexWriter - /// instance. - virtual void mergeInit(const OneMergePtr& merge); - - /// Does finishing for a merge, which is fast but holds the synchronized lock on IndexWriter instance. - virtual void mergeFinish(const OneMergePtr& merge); - - virtual void addMergeException(const OneMergePtr& merge); - - /// For test purposes. - virtual int32_t getBufferedDeleteTermsSize(); - - /// For test purposes. - virtual int32_t getNumBufferedDeleteTerms(); - - /// Utility routines for tests - virtual SegmentInfoPtr newestSegment(); - - virtual String segString(); - - /// Returns true if the index in the named directory is currently locked. - /// @param directory the directory to check for a lock - static bool isLocked(const DirectoryPtr& directory); - - /// Forcibly unlocks the index in the named directory. - /// Caution: this should only be used by failure recovery code, when it is known that no other process - /// nor thread is in fact currently accessing this index. - static void unlock(const DirectoryPtr& directory); - - /// Set the merged segment warmer. See {@link IndexReaderWarmer}. - virtual void setMergedSegmentWarmer(const IndexReaderWarmerPtr& warmer); - - /// Returns the current merged segment warmer. See {@link IndexReaderWarmer}. - virtual IndexReaderWarmerPtr getMergedSegmentWarmer(); - - /// Used only by assert for testing. Current points: - /// startDoFlush - /// startCommitMerge - /// startStartCommit - /// midStartCommit - /// midStartCommit2 - /// midStartCommitSuccess - /// finishStartCommit - /// startCommitMergeDeletes - /// startMergeInit - /// startApplyDeletes - /// startMergeInit - /// startMergeInit - virtual bool testPoint(const String& name); - - virtual bool nrtIsCurrent(const SegmentInfosPtr& infos); - virtual bool isClosed(); - - protected: - virtual void ensureOpen(bool includePendingClose); - virtual void ensureOpen(); - virtual void setMessageID(const InfoStreamPtr& infoStream); - - /// Casts current mergePolicy to LogMergePolicy, and throws an exception if the - /// mergePolicy is not a LogMergePolicy. - virtual LogMergePolicyPtr getLogMergePolicy(); - - virtual void setRollbackSegmentInfos(const SegmentInfosPtr& infos); - - /// If we are flushing by doc count (not by RAM usage), and using LogDocMergePolicy then push - /// maxBufferedDocs down as its minMergeDocs, to keep backwards compatibility. - virtual void pushMaxBufferedDocs(); - - virtual void messageState(); - - /// Returns true if this thread should attempt to close, or false if IndexWriter is now closed; - /// else, waits until another thread finishes closing - virtual bool shouldClose(); - virtual void closeInternal(bool waitForMerges); +namespace Lucene { + +/// An IndexWriter creates and maintains an index. +/// +/// The create argument to the {@link #IndexWriter(DirectoryPtr, AnalyzerPtr, bool, int32_t) constructor} +/// determines whether a new index is created, or whether an existing index is opened. Note that you can +/// open an index with create=true even while readers are using the index. The old readers will continue +/// to search the "point in time" snapshot they had opened, and won't see the newly created index until +/// they re-open. There are also {@link #IndexWriter(DirectoryPtr, AnalyzerPtr, int32_t) constructors} +/// with no create argument which will create a new index if there is not already an index at the provided +/// path and otherwise open the existing index. +/// +/// In either case, documents are added with {@link #addDocument(DocumentPtr) addDocument} and removed +/// with {@link #deleteDocuments(TermPtr)} or {@link #deleteDocuments(QueryPtr)}. A document can be updated +/// with {@link #updateDocument(TermPtr, DocumentPtr) updateDocument} (which just deletes and then adds +/// the entire document). When finished adding, deleting and updating documents, {@link #close() close} +/// should be called. +/// +/// These changes are buffered in memory and periodically flushed to the {@link Directory} (during the +/// above method calls). A flush is triggered when there are enough buffered deletes (see +/// {@link #setMaxBufferedDeleteTerms}) or enough added documents since the last flush, whichever is +/// sooner. For the added documents, flushing is triggered either by RAM usage of the documents (see +/// {@link #setRAMBufferSizeMB}) or the number of added documents. The default is to flush when RAM usage +/// hits 16 MB. For best indexing speed you should flush by RAM usage with a large RAM buffer. Note that +/// flushing just moves the internal buffered state in IndexWriter into the index, but these changes are +/// not visible to IndexReader until either {@link #commit()} or {@link #close} is called. A flush may +/// also trigger one or more segment merges which by default run with a background thread so as not to +/// block the addDocument calls (see mergePolicy below for changing the {@link MergeScheduler}). +/// +/// If an index will not have more documents added for a while and optimal search performance is desired, +/// then either the full {@link #optimize() optimize} method or partial {@link #optimize(int32_t)} method +/// should be called before the index is closed. +/// +/// Opening an IndexWriter creates a lock file for the directory in use. Trying to open another IndexWriter +/// on the same directory will lead to a LockObtainFailed exception. The LockObtainFailed exception is also +/// thrown if an IndexReader on the same directory is used to delete documents from the index. +/// +/// IndexWriter allows an optional {@link IndexDeletionPolicy} implementation to be specified. You can use +/// this to control when prior commits are deleted from the index. The default policy is {@link +/// KeepOnlyLastCommitDeletionPolicy} which removes all prior commits as soon as a new commit is done (this +/// matches behavior before 2.2). Creating your own policy can allow you to explicitly keep previous +/// "point in time" commits alive in the index for some time, to allow readers to refresh to the new commit +/// without having the old commit deleted out from under them. This is necessary on file systems like NFS +/// that do not support "delete on last close" semantics, which Lucene's "point in time" search normally +/// relies on. +/// +/// IndexWriter allows you to separately change the {@link MergePolicy} and the {@link MergeScheduler}. +/// The {@link MergePolicy} is invoked whenever there are changes to the segments in the index. Its role +/// is to select which merges to do, if any, and return a {@link MergePolicy.MergeSpecification} describing +/// the merges. It also selects merges to do for optimize(). (The default is {@link LogByteSizeMergePolicy}. +/// Then, the {@link MergeScheduler} is invoked with the requested merges and it decides when and how to run +/// the merges. The default is {@link ConcurrentMergeScheduler}. +/// +/// NOTE: if you hit an std::bad_alloc then IndexWriter will quietly record this fact and block all future +/// segment commits. This is a defensive measure in case any internal state (buffered documents and +/// deletions) were corrupted. Any subsequent calls to {@link #commit()} will throw an IllegalState +/// exception. The only course of action is to call {@link #close()}, which internally will call {@link +/// #rollback()}, to undo any changes to the index since the last commit. You can also just call {@link +/// #rollback()} directly. +/// +/// NOTE: {@link IndexWriter} instances are completely thread safe, meaning multiple threads can call any of +/// its methods, concurrently. If your application requires external synchronization, you should not +/// synchronize on the IndexWriter instance as this may cause deadlock; use your own (non-Lucene) objects +/// instead. +/// +/// Clarification: Check Points (and commits) +/// IndexWriter writes new index files to the directory without writing a new segments_N file which +/// references these new files. It also means that the state of the in memory SegmentInfos object is different +/// than the most recent segments_N file written to the directory. +/// +/// Each time the SegmentInfos is changed, and matches the (possibly modified) directory files, we have a new +/// "check point". If the modified/new SegmentInfos is written to disk - as a new (generation of) segments_N +/// file - this check point is also an IndexCommit. +/// +/// A new checkpoint always replaces the previous checkpoint and becomes the new "front" of the index. This +/// allows the IndexFileDeleter to delete files that are referenced only by stale checkpoints (files that were +/// created since the last commit, but are no longer referenced by the "front" of the index). For this, +/// IndexFileDeleter keeps track of the last non commit checkpoint. +class LPPAPI IndexWriter : public LuceneObject { +protected: + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexingChainPtr& indexingChain, const IndexCommitPtr& commit); + +public: + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl); + IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexCommitPtr& commit); + virtual ~IndexWriter(); + + LUCENE_CLASS(IndexWriter); + +protected: + int64_t writeLockTimeout; + + /// The normal read buffer size defaults to 1024, but increasing this during merging seems to + /// yield performance gains. However we don't want to increase it too much because there are + /// quite a few BufferedIndexInputs created during merging. + static const int32_t MERGE_READ_BUFFER_SIZE; + + SynchronizePtr messageIDLock; + static int32_t MESSAGE_ID; + int32_t messageID; + bool hitOOM; + + DirectoryPtr directory; // where this index resides + AnalyzerPtr analyzer; // how to analyze text + + bool create; + IndexDeletionPolicyPtr deletionPolicy; + IndexingChainPtr indexingChain; + IndexCommitPtr indexCommit; + + SimilarityPtr similarity; // how to normalize + + int64_t changeCount; // increments every time a change is completed + int64_t lastCommitChangeCount; // last changeCount that was committed + + SegmentInfosPtr rollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails + MapSegmentInfoInt rollbackSegments; + + SegmentInfosPtr localRollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails + int32_t localFlushedDocCount; + + SegmentInfosPtr segmentInfos; // the segments + + DocumentsWriterPtr docWriter; + IndexFileDeleterPtr deleter; + + SetSegmentInfo segmentsToOptimize; // used by optimize to note those needing optimization + int32_t optimizeMaxNumSegments; + + LockPtr writeLock; + + int32_t termIndexInterval; + + bool closed; + bool closing; + + SetSegmentInfo mergingSegments; + MergePolicyPtr mergePolicy; + MergeSchedulerPtr mergeScheduler; + Collection pendingMerges; + SetOneMerge runningMerges; + Collection mergeExceptions; + int64_t mergeGen; + bool stopMerges; + + int32_t flushCount; + int32_t flushDeletesCount; + + /// Used to only allow one addIndexes to proceed at once + int32_t readCount; // count of how many threads are holding read lock + int64_t writeThread; // non-null if any thread holds write lock + int32_t upgradeCount; + + int32_t readerTermsIndexDivisor; + + // This is a "write once" variable (like the organic dye on a DVD-R that may or may not + // be heated by a laser and then cooled to permanently record the event): it's false, + // until getReader() is called for the first time, at which point it's switched to true + // and never changes back to false. Once this is true, we hold open and reuse SegmentReader + // instances internally for applying deletes, doing merges, and reopening near real-time readers. + bool poolReaders; + + /// The maximum number of terms that will be indexed for a single field in a document. This + /// limits the amount of memory required for indexing, so that collections with very large files + /// will not crash the indexing process by running out of memory. + /// Note that this effectively truncates large documents, excluding from the index terms that + /// occur further in the document. If you know your source documents are large, be sure to set + /// this value high enough to accommodate the expected size. If you set it to INT_MAX, then the + /// only limit is your memory, but you should anticipate an std::bad_alloc. By default, no more + /// than 10,000 terms will be indexed for a field. + /// + /// @see #setMaxFieldLength(int32_t) + int32_t maxFieldLength; + + InfoStreamPtr infoStream; + static InfoStreamPtr defaultInfoStream; + + HashSet synced; // files that have been sync'd already + HashSet syncing; // files that are now being sync'd + + IndexReaderWarmerPtr mergedSegmentWarmer; + + /// Used only by commit; lock order is commitLock -> IW + SynchronizePtr commitLock; + +INTERNAL: + SegmentInfosPtr pendingCommit; // set when a commit is pending (after prepareCommit() & before commit()) + int64_t pendingCommitChangeCount; + + ReaderPoolPtr readerPool; + +public: + /// Default value for the write lock timeout (1,000). + /// @see #setDefaultWriteLockTimeout + static int64_t WRITE_LOCK_TIMEOUT; + + static const String WRITE_LOCK_NAME; + + /// Value to denote a flush trigger is disabled. + static const int32_t DISABLE_AUTO_FLUSH; + + /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using + /// {@link #setMaxBufferedDocs(int32_t)}. + static const int32_t DEFAULT_MAX_BUFFERED_DOCS; + + /// Default value is 16 MB (which means flush when buffered docs consume 16 MB RAM). + /// Change using {@link #setRAMBufferSizeMB}. + static const double DEFAULT_RAM_BUFFER_SIZE_MB; - /// Tells the docWriter to close its currently open shared doc stores (stored fields & vectors - /// files). Return value specifies whether new doc store files are compound or not. - virtual bool flushDocStores(); + /// Disabled by default (because IndexWriter flushes by RAM usage by default). Change using + /// {@link #setMaxBufferedDeleteTerms(int32_t)}. + static const int32_t DEFAULT_MAX_BUFFERED_DELETE_TERMS; - /// Returns true if any merges in pendingMerges or runningMerges are optimization merges. - virtual bool optimizeMergesPending(); + /// Default value is 10,000. Change using {@link #setMaxFieldLength(int32_t)}. + static const int32_t DEFAULT_MAX_FIELD_LENGTH; - virtual void maybeMerge(bool optimize); - virtual void maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize); - virtual void updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize); + /// Default value is 128. Change using {@link #setTermIndexInterval(int32_t)}. + static const int32_t DEFAULT_TERM_INDEX_INTERVAL; - /// Like {@link #getNextMerge()} except only returns a merge if it's external. - virtual OneMergePtr getNextExternalMerge(); + /// Absolute hard maximum length for a term. If a term arrives from the analyzer longer than + /// this length, it is skipped and a message is printed to infoStream, if set (see {@link + /// #setInfoStream}). + static int32_t MAX_TERM_LENGTH(); - /// Begin a transaction. During a transaction, any segment merges that happen (or ram segments - /// flushed) will not write a new segments file and will not remove any files that were present - /// at the start of the transaction. You must make a matched call to commitTransaction() or - /// rollbackTransaction() to finish the transaction. - /// - /// Note that buffered documents and delete terms are not handled within the transactions, so - /// they must be flushed before the transaction is started. - virtual void startTransaction(bool haveReadLock); + /// Sets the maximum field length to INT_MAX + static const int32_t MaxFieldLengthUNLIMITED; - /// Rolls back the transaction and restores state to where we were at the start. - virtual void rollbackTransaction(); + /// Sets the maximum field length to {@link #DEFAULT_MAX_FIELD_LENGTH} + static const int32_t MaxFieldLengthLIMITED; - /// Commits the transaction. This will write the new segments file and remove and pending - /// deletions we have accumulated during the transaction. - virtual void commitTransaction(); - virtual void rollbackInternal(); +public: + virtual void initialize(); - virtual void finishMerges(bool waitForMerges); + /// Returns a read-only reader, covering all committed as well as un-committed changes to the + /// index. This provides "near real-time" searching, in that changes made during an IndexWriter + /// session can be quickly made available for searching without closing the writer nor calling + /// {@link #commit}. + /// + /// Note that this is functionally equivalent to calling {#commit} and then using {@link + /// IndexReader#open} to open a new reader. But the turnaround time of this method should be + /// faster since it avoids the potentially costly {@link #commit}. + /// + /// You must close the {@link IndexReader} returned by this method once you are done using it. + /// + /// It's near real-time because there is no hard guarantee on how quickly you can get a new + /// reader after making changes with IndexWriter. You'll have to experiment in your situation + /// to determine if it's fast enough. As this is a new and experimental feature, please report + /// back on your findings so we can learn, improve and iterate. + /// + /// The resulting reader supports {@link IndexReader#reopen}, but that call will simply forward + /// back to this method (though this may change in the future). + /// + /// The very first time this method is called, this writer instance will make every effort to + /// pool the readers that it opens for doing merges, applying deletes, etc. This means additional + /// resources (RAM, file descriptors, CPU time) will be consumed. + /// + /// For lower latency on reopening a reader, you should call {@link #setMergedSegmentWarmer} to + /// pre-warm a newly merged segment before it's committed to the index. This is important for + /// minimizing index-to-search delay after a large merge. + /// + /// If an addIndexes* call is running in another thread, then this reader will only search those + /// segments from the foreign index that have been successfully copied over, so far. + /// + /// NOTE: Once the writer is closed, any outstanding readers may continue to be used. However, + /// if you attempt to reopen any of those readers, you'll hit an AlreadyClosed exception. + /// + /// NOTE: This API is experimental and might change in incompatible ways in the next release. + /// + /// @return IndexReader that covers entire index plus all changes made so far by this IndexWriter + /// instance + virtual IndexReaderPtr getReader(); - /// Called whenever the SegmentInfos has been updated and the index files referenced exist - /// (correctly) in the index directory. - virtual void checkpoint(); + /// Like {@link #getReader}, except you can specify which termInfosIndexDivisor should be used for + /// any newly opened readers. + /// + /// @param termInfosIndexDivisor Subsamples which indexed terms are loaded into RAM. This has the + /// same effect as {@link IndexWriter#setTermIndexInterval} except that setting must be done at + /// indexing time while this setting can be set per reader. When set to N, then one in every + /// N*termIndexInterval terms in the index is loaded into memory. By setting this to a value > 1 + /// you can reduce memory usage, at the expense of higher latency when loading a TermInfo. + /// The default value is 1. Set this to -1 to skip loading the terms index entirely. + virtual IndexReaderPtr getReader(int32_t termInfosIndexDivisor); + + /// Obtain the number of deleted docs for a pooled reader. If the reader isn't being pooled, + /// the segmentInfo's delCount is returned. + virtual int32_t numDeletedDocs(const SegmentInfoPtr& info); + + virtual void acquireWrite(); + virtual void releaseWrite(); + virtual void acquireRead(); + + /// Allows one readLock to upgrade to a writeLock even if there are other readLocks as long + /// as all other readLocks are also blocked in this method + virtual void upgradeReadToWrite(); + + virtual void releaseRead(); + virtual bool isOpen(bool includePendingClose); + virtual void message(const String& message); + + /// Get the current setting of whether newly flushed segments will use the compound file format. + /// Note that this just returns the value previously set with setUseCompoundFile(bool), or the + /// default value (true). You cannot use this to query the status of previously flushed segments. + /// + /// Note that this method is a convenience method: it just calls mergePolicy.getUseCompoundFile + /// as long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument + /// exception is thrown. + /// @see #setUseCompoundFile(bool) + virtual bool getUseCompoundFile(); + + /// Setting to turn on usage of a compound file. When on, multiple files for each segment are + /// merged into a single file when a new segment is flushed. + /// + /// Note that this method is a convenience method: it just calls mergePolicy.setUseCompoundFile + /// as long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument + /// exception is thrown. + virtual void setUseCompoundFile(bool value); - virtual void finishAddIndexes(); - virtual void blockAddIndexes(bool includePendingClose); - virtual void resumeAddIndexes(); - virtual void resetMergeExceptions(); - virtual void noDupDirs(Collection dirs); + /// Set the Similarity implementation used by this IndexWriter. + virtual void setSimilarity(const SimilarityPtr& similarity); - virtual bool hasExternalSegments(); - - /// If any of our segments are using a directory != ours then we have to either copy them over one - /// by one, merge them (if merge policy has chosen to) or wait until currently running merges (in - /// the background) complete. We don't return until the SegmentInfos has no more external segments. - /// Currently this is only used by addIndexesNoOptimize(). - virtual void resolveExternalSegments(); - - /// A hook for extending classes to execute operations after pending added and deleted documents have - /// been flushed to the Directory but before the change is committed (new segments_N file written). - virtual void doAfterFlush(); - - /// A hook for extending classes to execute operations before pending added and deleted documents are - /// flushed to the Directory. - virtual void doBeforeFlush(); - - virtual void commit(int64_t sizeInBytes); - virtual void finishCommit(); - - /// Flush all in-memory buffered updates (adds and deletes) to the Directory. - /// @param triggerMerge if true, we may merge segments (if deletes or docs were flushed) if necessary - /// @param flushDocStores if false we are allowed to keep doc stores open to share with the next segment - /// @param flushDeletes whether pending deletes should also be flushed - virtual void flush(bool triggerMerge, bool flushDocStores, bool flushDeletes); - virtual bool doFlush(bool flushDocStores, bool flushDeletes); - virtual bool doFlushInternal(bool flushDocStores, bool flushDeletes); + /// Return the Similarity implementation used by this IndexWriter. + /// This defaults to the current value of {@link Similarity#getDefault()}. + virtual SimilarityPtr getSimilarity(); - virtual int32_t ensureContiguousMerge(const OneMergePtr& merge); + /// Set the interval between indexed terms. Large values cause less memory to be used by + /// IndexReader, but slow random-access to terms. Small values cause more memory to be used by + /// an IndexReader, and speed random-access to terms. + /// + /// This parameter determines the amount of computation required per query term, regardless of + /// the number of documents that contain that term. In particular, it is the maximum number of + /// other terms that must be scanned before a term is located and its frequency and position + /// information may be processed. In a large index with user-entered query terms, query + /// processing time is likely to be dominated not by term lookup but rather by the processing of + /// frequency and positional data. In a small index or when many uncommon query terms are + /// generated (eg., by wildcard queries) term lookup may become a dominant cost. + /// + /// In particular, numUniqueTerms/interval terms are read into memory by an IndexReader, and on + /// average, interval/2 terms must be scanned for each random term access. + /// + /// @see #DEFAULT_TERM_INDEX_INTERVAL + virtual void setTermIndexInterval(int32_t interval); - /// Carefully merges deletes for the segments we just merged. This is tricky because, although merging - /// will clear all deletes (compacts the documents), new deletes may have been flushed to the segments - /// since the merge was started. This method "carries over" such new deletes onto the newly merged - /// segment, and saves the resulting deletes file (incrementing the delete generation for merge.info). - /// If no deletes were flushed, no new deletes file is saved. - virtual void commitMergedDeletes(const OneMergePtr& merge, const SegmentReaderPtr& mergeReader); - virtual bool commitMerge(const OneMergePtr& merge, const SegmentMergerPtr& merger, int32_t mergedDocCount, const SegmentReaderPtr& mergedReader); + /// Return the interval between indexed terms. + /// @see #setTermIndexInterval(int32_t) + virtual int32_t getTermIndexInterval(); - virtual LuceneException handleMergeException(const LuceneException& exc, const OneMergePtr& merge); + /// Set the merge policy used by this writer. + virtual void setMergePolicy(const MergePolicyPtr& mp); - virtual void _mergeInit(const OneMergePtr& merge); + /// Returns the current MergePolicy in use by this writer. + /// @see #setMergePolicy + virtual MergePolicyPtr getMergePolicy(); - virtual void setDiagnostics(const SegmentInfoPtr& info, const String& source); - virtual void setDiagnostics(const SegmentInfoPtr& info, const String& source, MapStringString details); + /// Set the merge scheduler used by this writer. + virtual void setMergeScheduler(const MergeSchedulerPtr& mergeScheduler); - virtual void setMergeDocStoreIsCompoundFile(const OneMergePtr& merge); - virtual void closeMergeReaders(const OneMergePtr& merge, bool suppressExceptions); + /// Returns the current MergePolicy in use by this writer. + /// @see #setMergePolicy + virtual MergeSchedulerPtr getMergeScheduler(); - /// Does the actual (time-consuming) work of the merge, but without holding synchronized lock on - /// IndexWriter instance. - virtual int32_t mergeMiddle(const OneMergePtr& merge); + /// Determines the largest segment (measured by document count) that may be merged with other + /// segments. Small values (eg., less than 10,000) are best for interactive indexing, as this + /// limits the length of pauses while indexing to a few seconds. Larger values are best for + /// batched indexing and speedier searches. + /// + /// The default value is INT_MAX. + /// + /// Note that this method is a convenience method: it just calls mergePolicy.setMaxMergeDocs as + /// long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument + /// exception is thrown. + /// + /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit + /// by net size (in MB) of the segment, using {@link LogByteSizeMergePolicy#setMaxMergeMB}. + virtual void setMaxMergeDocs(int32_t maxMergeDocs); - /// Apply buffered deletes to all segments. - virtual bool applyDeletes(); + /// Returns the largest segment (measured by document count) that may be merged with other + /// segments. + /// + /// Note that this method is a convenience method: it just calls mergePolicy.getMaxMergeDocs as + /// long as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument + /// exception is thrown. + /// + /// @see #setMaxMergeDocs + virtual int32_t getMaxMergeDocs(); + + /// The maximum number of terms that will be indexed for a single field in a document. This + /// limits the amount of memory required for indexing, so that collections with very large files + /// will not crash the indexing process by running out of memory. This setting refers to the + /// number of running terms, not to the number of different terms. + /// Note: this silently truncates large documents, excluding from the index all terms that occur + /// further in the document. If you know your source documents are large, be sure to set this + /// value high enough to accommodate the expected size. If you set it to INT_MAX, then the only + /// limit is your memory, but you should anticipate an std::bad_alloc. + /// By default, no more than {@link #DEFAULT_MAX_FIELD_LENGTH} terms will be indexed for a field. + virtual void setMaxFieldLength(int32_t maxFieldLength); + + /// Returns the maximum number of terms that will be indexed for a single field in a document. + /// @see #setMaxFieldLength + virtual int32_t getMaxFieldLength(); + + /// Sets the termsIndexDivisor passed to any readers that IndexWriter opens, for example when + /// applying deletes or creating a near-real-time reader in {@link IndexWriter#getReader}. + /// Default value is {@link IndexReader#DEFAULT_TERMS_INDEX_DIVISOR}. + virtual void setReaderTermsIndexDivisor(int32_t divisor); + + /// @see #setReaderTermsIndexDivisor() + virtual int32_t getReaderTermsIndexDivisor(); + + /// Determines the minimal number of documents required before the buffered in-memory documents + /// are flushed as a new Segment. Large values generally gives faster indexing. + /// + /// When this is set, the writer will flush every maxBufferedDocs added documents. Pass in + /// {@link #DISABLE_AUTO_FLUSH} to prevent triggering a flush due to number of buffered + /// documents. Note that if flushing by RAM usage is also enabled, then the flush will be + /// triggered by whichever comes first. + /// + /// Disabled by default (writer flushes by RAM usage). + /// + /// @see #setRAMBufferSizeMB + virtual void setMaxBufferedDocs(int32_t maxBufferedDocs); - virtual String segString(const SegmentInfosPtr& infos); + /// Returns the number of buffered added documents that will trigger a flush if enabled. + /// @see #setMaxBufferedDocs + virtual int32_t getMaxBufferedDocs(); - virtual bool startSync(const String& fileName, HashSet pending); - virtual void finishSync(const String& fileName, bool success); + /// Determines the amount of RAM that may be used for buffering added documents and deletions + /// before they are flushed to the Directory. Generally for faster indexing performance it's + /// best to flush by RAM usage instead of document count and use as large a RAM buffer as you can. + /// + /// When this is set, the writer will flush whenever buffered documents and deletions use this + /// much RAM. Pass in {@link #DISABLE_AUTO_FLUSH} to prevent triggering a flush due to RAM usage. + /// Note that if flushing by document count is also enabled, then the flush will be triggered by + /// whichever comes first. + /// + /// Note: the account of RAM usage for pending deletions is only approximate. Specifically, if + /// you delete by Query, Lucene currently has no way to measure the RAM usage if individual + /// Queries so the accounting will under-estimate and you should compensate by either calling + /// commit() periodically yourself, or by using {@link #setMaxBufferedDeleteTerms} to flush by + /// count instead of RAM usage (each buffered delete Query counts as one). + /// + /// Note: because IndexWriter uses int32_t when managing its internal storage, the absolute + /// maximum value for this setting is somewhat less than 2048 MB. The precise limit depends on + /// various factors, such as how large your documents are, how many fields have norms, etc., so + /// it's best to set this value comfortably under 2048. + /// + /// The default value is {@link #DEFAULT_RAM_BUFFER_SIZE_MB}. + virtual void setRAMBufferSizeMB(double mb); - /// Blocks until all files in syncing are sync'd - bool waitForAllSynced(HashSet syncing); - void doWait(); + /// Returns the value set by {@link #setRAMBufferSizeMB} if enabled. + virtual double getRAMBufferSizeMB(); - /// Walk through all files referenced by the current segmentInfos and ask the Directory to sync each - /// file, if it wasn't already. If that succeeds, then we prepare a new segments_N file but do not - /// fully commit it. - virtual void startCommit(int64_t sizeInBytes, MapStringString commitUserData); + /// Determines the minimal number of delete terms required before the buffered in-memory delete + /// terms are applied and flushed. If there are documents buffered in memory at the time, they + /// are merged and a new segment is created. + /// + /// Disabled by default (writer flushes by RAM usage). + /// @see #setRAMBufferSizeMB + virtual void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); + + /// Returns the number of buffered deleted terms that will trigger a flush if enabled. + /// @see #setMaxBufferedDeleteTerms + virtual int32_t getMaxBufferedDeleteTerms(); + + /// Determines how often segment indices are merged by addDocument(). With smaller values, less + /// RAM is used while indexing, and searches on unoptimized indices are faster, but indexing + /// speed is slower. With larger values, more RAM is used during indexing, and while searches + /// on unoptimized indices are slower, indexing is faster. Thus larger values (> 10) are best + /// for batch index creation, and smaller values (< 10) for indices that are interactively maintained. + /// + /// Note that this method is a convenience method: it just calls mergePolicy.setMergeFactor as long + /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception + /// is thrown. This must never be less than 2. The default value is 10. + virtual void setMergeFactor(int32_t mergeFactor); - virtual LuceneException handleOOM(const std::bad_alloc& oom, const String& location); + /// Returns the number of segments that are merged at once and also controls the total number of + /// segments allowed to accumulate in the index. + /// + /// Note that this method is a convenience method: it just calls mergePolicy.getMergeFactor as long + /// as mergePolicy is an instance of {@link LogMergePolicy}. Otherwise an IllegalArgument exception + /// is thrown. + /// @see #setMergeFactor + virtual int32_t getMergeFactor(); + + /// If non-null, this will be the default infoStream used by a newly instantiated IndexWriter. + /// @see #setInfoStream + static void setDefaultInfoStream(const InfoStreamPtr& infoStream); + + /// Returns the current default infoStream for newly instantiated IndexWriters. + /// @see #setDefaultInfoStream + static InfoStreamPtr getDefaultInfoStream(); + + /// If non-null, information about merges, deletes and a message when maxFieldLength is reached + /// will be printed to this. + virtual void setInfoStream(const InfoStreamPtr& infoStream); + + /// Returns the current infoStream in use by this writer. + /// @see #setInfoStream + virtual InfoStreamPtr getInfoStream(); + + /// Returns true if verbosing is enabled (i.e., infoStream != null). + virtual bool verbose(); + + /// Sets the maximum time to wait for a write lock (in milliseconds) for this instance of + /// IndexWriter. @see #setDefaultWriteLockTimeout to change the default value for all instances + /// of IndexWriter. + virtual void setWriteLockTimeout(int64_t writeLockTimeout); + + /// Returns allowed timeout when acquiring the write lock. + /// @see #setWriteLockTimeout + virtual int64_t getWriteLockTimeout(); + + /// Sets the default (for any instance of IndexWriter) maximum time to wait for a write lock + /// (in milliseconds). + static void setDefaultWriteLockTimeout(int64_t writeLockTimeout); + + /// Returns default write lock timeout for newly instantiated IndexWriters. + /// @see #setDefaultWriteLockTimeout + static int64_t getDefaultWriteLockTimeout(); + + /// Commits all changes to an index and closes all associated files. Note that this may be + /// a costly operation, so try to re-use a single writer instead of closing and opening a + /// new one. See {@link #commit()} for caveats about write caching done by some IO devices. + /// + /// If an Exception is hit during close, eg due to disk full or some other reason, then both + /// the on-disk index and the internal state of the IndexWriter instance will be consistent. + /// However, the close will not be complete even though part of it (flushing buffered documents) + /// may have succeeded, so the write lock will still be held. + /// + /// If you can correct the underlying cause (eg free up some disk space) then you can call + /// close() again. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer, again. + virtual void close(); - friend class ReaderPool; - }; + /// Closes the index with or without waiting for currently running merges to finish. This is + /// only meaningful when using a MergeScheduler that runs merges in background threads. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer, again. + /// + /// NOTE: it is dangerous to always call close(false), especially when IndexWriter is not open + /// for very long, because this can result in "merge starvation" whereby long merges will never + /// have a chance to finish. This will cause too many segments in your index over time. + /// + /// @param waitForMerges if true, this call will block until all merges complete; else, it will + /// ask all running merges to abort, wait until those merges have finished (which should be at + /// most a few seconds), and then return. + virtual void close(bool waitForMerges); + + /// Returns the Directory used by this index. + virtual DirectoryPtr getDirectory(); + + /// Returns the analyzer used by this index. + virtual AnalyzerPtr getAnalyzer(); + + /// Returns total number of docs in this index, including docs not yet flushed (still in the + /// RAM buffer), not counting deletions. + /// @see #numDocs + virtual int32_t maxDoc(); + + /// Returns total number of docs in this index, including docs not yet flushed (still in the + /// RAM buffer), and including deletions. + /// NOTE: buffered deletions are not counted. If you really need these to be counted you should + /// call {@link #commit()} first. + virtual int32_t numDocs(); + + virtual bool hasDeletions(); + + /// Adds a document to this index. If the document contains more than {@link + /// #setMaxFieldLength(int32_t)} terms for a given field, the remainder are discarded. + /// + /// Note that if an Exception is hit (for example disk full) then the index will be consistent, + /// but this document may not have been added. Furthermore, it's possible the index will have + /// one segment in non-compound format even when using compound files (when a merge has partially + /// succeeded). + /// + /// This method periodically flushes pending documents to the Directory, and also periodically + /// triggers segment merges in the index according to the {@link MergePolicy} in use. + /// + /// Merges temporarily consume space in the directory. The amount of space required is up to 1X + /// the size of all segments being merged, when no size of all segments being merged, when no + /// 2X the size of all segments being merged when readers/searchers are open against the index + /// (see {@link #optimize()} for details). The sequence of primitive merge operations performed + /// is governed by the merge policy. + /// + /// Note that each term in the document can be no longer than 16383 characters, otherwise an + /// IllegalArgument exception will be thrown. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void addDocument(const DocumentPtr& doc); + + /// Adds a document to this index, using the provided analyzer instead of the value of {@link + /// #getAnalyzer()}. If the document contains more than {@link #setMaxFieldLength(int32_t)} terms + /// for a given field, the remainder are discarded. + /// + /// See {@link #addDocument(DocumentPtr)} for details on index and IndexWriter state after an + /// exception, and flushing/merging temporary free space requirements. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer); + + /// Deletes the document(s) containing term. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param term the term to identify the documents to be deleted + virtual void deleteDocuments(const TermPtr& term); + + /// Deletes the document(s) containing any of the terms. All deletes are flushed at the same time. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param terms array of terms to identify the documents to be deleted + virtual void deleteDocuments(Collection terms); + + /// Deletes the document(s) matching the provided query. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param query the query to identify the documents to be deleted + virtual void deleteDocuments(const QueryPtr& query); + + /// Deletes the document(s) matching any of the provided queries. All deletes are flushed at + /// the same time. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param queries array of queries to identify the documents to be deleted + virtual void deleteDocuments(Collection queries); + + /// Updates a document by first deleting the document(s) containing term and then adding the new + /// document. The delete and then add are atomic as seen by a reader on the same index (flush + /// may happen only after the add). + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param term the term to identify the document(s) to be deleted + /// @param doc the document to be added + virtual void updateDocument(const TermPtr& term, const DocumentPtr& doc); + + /// Updates a document by first deleting the document(s) containing term and then adding the new + /// document. The delete and then add are atomic as seen by a reader on the same index (flush + /// may happen only after the add). + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param term the term to identify the document(s) to be deleted + /// @param doc the document to be added + /// @param analyzer the analyzer to use when analyzing the document + virtual void updateDocument(const TermPtr& term, const DocumentPtr& doc, const AnalyzerPtr& analyzer); + + virtual int32_t getSegmentCount(); + virtual int32_t getNumBufferedDocuments(); + virtual int32_t getDocCount(int32_t i); + virtual int32_t getFlushCount(); + virtual int32_t getFlushDeletesCount(); + + virtual String newSegmentName(); + + /// Requests an "optimize" operation on an index, priming the index for the fastest available + /// search. Traditionally this has meant merging all segments into a single segment as is done in + /// the default merge policy, but individual merge policies may implement optimize in different ways. + /// + /// It is recommended that this method be called upon completion of indexing. In environments with + /// frequent updates, optimize is best done during low volume times, if at all. + /// + /// Note that optimize requires 2X the index size free space in your Directory (3X if you're using + /// compound file format). For example, if your index size is 10 MB then you need 20 MB free for + /// optimize to complete (30 MB if you're using compound file format). + /// + /// If some but not all readers re-open while an optimize is underway, this will cause > 2X temporary + /// space to be consumed as those new readers will then hold open the partially optimized segments at + /// that time. It is best not to re-open readers while optimize is running. + /// + /// The actual temporary usage could be much less than these figures (it depends on many factors). + /// + /// In general, once the optimize completes, the total size of the index will be less than the size + /// of the starting index. It could be quite a bit smaller (if there were many pending deletes) or + /// just slightly smaller. + /// + /// If an Exception is hit during optimize(), for example due to disk full, the index will not be + /// corrupt and no documents will have been lost. However, it may have been partially optimized + /// (some segments were merged but not all), and it's possible that one of the segments in the index + /// will be in non-compound format even when using compound file format. This will occur when the + /// exception is hit during conversion of the segment into compound format. + /// + /// This call will optimize those segments present in the index when the call started. If other + /// threads are still adding documents and flushing segments, those newly created segments will not + /// be optimized unless you call optimize again. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @see LogMergePolicy#findMergesForOptimize + virtual void optimize(); + + /// Optimize the index down to <= maxNumSegments. If maxNumSegments==1 then this is the same as + /// {@link #optimize()}. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param maxNumSegments maximum number of segments left in the index after optimization finishes + virtual void optimize(int32_t maxNumSegments); + + /// Just like {@link #optimize()}, except you can specify whether the call should block until the + /// optimize completes. This is only meaningful with a {@link MergeScheduler} that is able to run + /// merges in background threads. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void optimize(bool doWait); - /// If {@link #getReader} has been called (ie, this writer is in near real-time mode), then after - /// a merge completes, this class can be invoked to warm the reader on the newly merged segment, - /// before the merge commits. This is not required for near real-time search, but will reduce - /// search latency on opening a new near real-time reader after a merge completes. + /// Just like {@link #optimize(int32_t)}, except you can specify whether the call should block + /// until the optimize completes. This is only meaningful with a {@link MergeScheduler} that is + /// able to run merges in background threads. /// - /// NOTE: warm is called before any deletes have been carried over to the merged segment. - class LPPAPI IndexReaderWarmer : public LuceneObject - { - public: - virtual ~IndexReaderWarmer(); + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void optimize(int32_t maxNumSegments, bool doWait); + + /// Just like {@link #expungeDeletes()}, except you can specify whether the call should block + /// until the operation completes. This is only meaningful with a {@link MergeScheduler} that + /// is able to run merges in background threads. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void expungeDeletes(bool doWait); + + /// Expunges all deletes from the index. When an index has many document deletions (or updates + /// to existing documents), it's best to either call optimize or expungeDeletes to remove all + /// unused data in the index associated with the deleted documents. To see how many deletions + /// you have pending in your index, call {@link IndexReader#numDeletedDocs}. This saves disk + /// space and memory usage while searching. expungeDeletes should be somewhat faster than + /// optimize since it does not insist on reducing the index to a single segment (though, this + /// depends on the {@link MergePolicy}; see {@link MergePolicy#findMergesToExpungeDeletes}.). + /// Note that this call does not first commit any buffered documents, so you must do so yourself + /// if necessary. See also {@link #expungeDeletes(bool)} + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void expungeDeletes(); + + /// Asks the mergePolicy whether any merges are necessary now and if so, runs the requested + /// merges and then iterate (test again if merges are needed) until no more merges are returned + /// by the mergePolicy. + /// + /// Explicit calls to maybeMerge() are usually not necessary. The most common case is when merge + /// policy parameters have changed. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void maybeMerge(); + + /// The {@link MergeScheduler} calls this method to retrieve the next merge requested by the + /// MergePolicy. + virtual OneMergePtr getNextMerge(); + + /// Close the IndexWriter without committing any changes that have occurred since the last commit + /// (or since it was opened, if commit hasn't been called). This removes any temporary files that + /// had been created, after which the state of the index will be the same as it was when commit() + /// was last called or when this writer was first opened. This also clears a previous call to + /// {@link #prepareCommit}. + virtual void rollback(); + + /// Delete all documents in the index. + /// + /// This method will drop all buffered documents and will remove all segments from the index. This + /// change will not be visible until a {@link #commit()} has been called. This method can be rolled + /// back using {@link #rollback()}. + /// + /// NOTE: this method is much faster than using {@link #deleteDocuments()}. + /// + /// NOTE: this method will forcefully abort all merges in progress. If other threads are running + /// {@link #optimize()} or any of the addIndexes methods, they will receive {@link + /// MergePolicy.MergeAbortedException} + virtual void deleteAll(); + + /// Wait for any currently outstanding merges to finish. + /// + /// It is guaranteed that any merges started prior to calling this method will have completed once + /// this method completes. + virtual void waitForMerges(); + + /// Merges all segments from an array of indexes into this index. + /// + /// This may be used to parallelize batch indexing. A large document collection can be broken into + /// sub-collections. Each sub-collection can be indexed in parallel, on a different thread, process + /// or machine. The complete index can then be created by merging sub-collection indexes with this + /// method. + /// + /// NOTE: the index in each Directory must not be changed (opened by a writer) while this method is + /// running. This method does not acquire a write lock in each input Directory, so it is up to the + /// caller to enforce this. + /// + /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will + /// be paused until this method completes. + /// + /// This method is transactional in how exceptions are handled: it does not commit a new segments_N + /// file until all indexes are added. This means if an exception occurs (for example disk full), + /// then either no indexes will have been added or they all will have been. + /// + /// Note that this requires temporary free space in the Directory up to 2X the sum of all input + /// indexes (including the starting index). If readers/searchers are open against the starting index, + /// then temporary free space required will be higher by the size of the starting index (see + /// {@link #optimize()} for details). + /// + /// Once this completes, the final size of the index will be less than the sum of all input index + /// sizes (including the starting index). It could be quite a bit smaller (if there were many pending + /// deletes) or just slightly smaller. + /// + /// This requires this index not be among those to be added. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void addIndexesNoOptimize(Collection dirs); + + /// Merges the provided indexes into this index. + /// After this completes, the index is optimized. The provided IndexReaders are not closed. + /// + /// NOTE: while this is running, any attempts to add or delete documents (with another thread) will + /// be paused until this method completes. + /// + /// See {@link #addIndexesNoOptimize} for details on transactional semantics, temporary free space + /// required in the Directory, and non-CFS segments on an exception. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void addIndexes(Collection readers); + + /// Prepare for commit. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// @see #prepareCommit(MapStringString) + virtual void prepareCommit(); + + /// Prepare for commit, specifying commitUserData Map (String -> String). This does the first phase + /// of 2-phase commit. This method does all steps necessary to commit changes since this writer was + /// opened: flushes pending added and deleted docs, syncs the index files, writes most of next + /// segments_N file. After calling this you must call either {@link #commit()} to finish the commit, + /// or {@link #rollback()} to revert the commit and undo all changes done since the writer was opened. + /// + /// You can also just call {@link #commit(Map)} directly without prepareCommit first in which case + /// that method will internally call prepareCommit. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @param commitUserData Opaque Map (String->String) that's recorded into the segments file in the + /// index, and retrievable by {@link IndexReader#getCommitUserData}. Note that when IndexWriter + /// commits itself during {@link #close}, the commitUserData is unchanged (just carried over from the + /// prior commit). If this is null then the previous commitUserData is kept. Also, the commitUserData + // will only "stick" if there are actually changes in the index to commit. + virtual void prepareCommit(MapStringString commitUserData); + + /// Commits all pending changes (added & deleted documents, optimizations, segment merges, added + /// indexes, etc.) to the index, and syncs all referenced index files, such that a reader will see the + /// changes and the index updates will survive an OS or machine crash or power loss. Note that this + /// does not wait for any running background merges to finish. This may be a costly operation, so you + /// should test the cost in your application and do it only when really necessary. + /// + /// Note that this operation calls Directory.sync on the index files. That call should not return until + /// the file contents & metadata are on stable storage. For FSDirectory, this calls the OS's fsync. + /// But, beware: some hardware devices may in fact cache writes even during fsync, and return before the + /// bits are actually on stable storage, to give the appearance of faster performance. If you have such + /// a device, and it does not have a battery backup (for example) then on power loss it may still lose + /// data. Lucene cannot guarantee consistency on such devices. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + /// + /// @see #prepareCommit + /// @see #commit(MapStringString) + virtual void commit(); + + /// Commits all changes to the index, specifying a commitUserData Map (String -> String). This just + /// calls {@link #prepareCommit(MapStringString)} (if you didn't already call it) and then + /// {@link #finishCommit}. + /// + /// NOTE: if this method hits an std::bad_alloc you should immediately close the writer. + virtual void commit(MapStringString commitUserData); + + /// Return the total size of all index files currently cached in memory. Useful for size management + /// with flushRamDocs() + virtual int64_t ramSizeInBytes(); + + /// Return the number of documents currently buffered in RAM. + virtual int32_t numRamDocs(); + + /// Merges the indicated segments, replacing them in the stack with a single segment. + virtual void merge(const OneMergePtr& merge); + + /// Hook that's called when the specified merge is complete. + virtual void mergeSuccess(const OneMergePtr& merge); + + /// Checks whether this merge involves any segments already participating in a merge. If not, this + /// merge is "registered", meaning we record that its segments are now participating in a merge, + /// and true is returned. Else (the merge conflicts) false is returned. + virtual bool registerMerge(const OneMergePtr& merge); + + /// Does initial setup for a merge, which is fast but holds the synchronized lock on IndexWriter + /// instance. + virtual void mergeInit(const OneMergePtr& merge); + + /// Does finishing for a merge, which is fast but holds the synchronized lock on IndexWriter instance. + virtual void mergeFinish(const OneMergePtr& merge); + + virtual void addMergeException(const OneMergePtr& merge); + + /// For test purposes. + virtual int32_t getBufferedDeleteTermsSize(); + + /// For test purposes. + virtual int32_t getNumBufferedDeleteTerms(); + + /// Utility routines for tests + virtual SegmentInfoPtr newestSegment(); + + virtual String segString(); + + /// Returns true if the index in the named directory is currently locked. + /// @param directory the directory to check for a lock + static bool isLocked(const DirectoryPtr& directory); + + /// Forcibly unlocks the index in the named directory. + /// Caution: this should only be used by failure recovery code, when it is known that no other process + /// nor thread is in fact currently accessing this index. + static void unlock(const DirectoryPtr& directory); + + /// Set the merged segment warmer. See {@link IndexReaderWarmer}. + virtual void setMergedSegmentWarmer(const IndexReaderWarmerPtr& warmer); + + /// Returns the current merged segment warmer. See {@link IndexReaderWarmer}. + virtual IndexReaderWarmerPtr getMergedSegmentWarmer(); + + /// Used only by assert for testing. Current points: + /// startDoFlush + /// startCommitMerge + /// startStartCommit + /// midStartCommit + /// midStartCommit2 + /// midStartCommitSuccess + /// finishStartCommit + /// startCommitMergeDeletes + /// startMergeInit + /// startApplyDeletes + /// startMergeInit + /// startMergeInit + virtual bool testPoint(const String& name); + + virtual bool nrtIsCurrent(const SegmentInfosPtr& infos); + virtual bool isClosed(); + +protected: + virtual void ensureOpen(bool includePendingClose); + virtual void ensureOpen(); + virtual void setMessageID(const InfoStreamPtr& infoStream); + + /// Casts current mergePolicy to LogMergePolicy, and throws an exception if the + /// mergePolicy is not a LogMergePolicy. + virtual LogMergePolicyPtr getLogMergePolicy(); + + virtual void setRollbackSegmentInfos(const SegmentInfosPtr& infos); + + /// If we are flushing by doc count (not by RAM usage), and using LogDocMergePolicy then push + /// maxBufferedDocs down as its minMergeDocs, to keep backwards compatibility. + virtual void pushMaxBufferedDocs(); + + virtual void messageState(); + + /// Returns true if this thread should attempt to close, or false if IndexWriter is now closed; + /// else, waits until another thread finishes closing + virtual bool shouldClose(); + virtual void closeInternal(bool waitForMerges); + + /// Tells the docWriter to close its currently open shared doc stores (stored fields & vectors + /// files). Return value specifies whether new doc store files are compound or not. + virtual bool flushDocStores(); + + /// Returns true if any merges in pendingMerges or runningMerges are optimization merges. + virtual bool optimizeMergesPending(); + + virtual void maybeMerge(bool optimize); + virtual void maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize); + virtual void updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize); + + /// Like {@link #getNextMerge()} except only returns a merge if it's external. + virtual OneMergePtr getNextExternalMerge(); + + /// Begin a transaction. During a transaction, any segment merges that happen (or ram segments + /// flushed) will not write a new segments file and will not remove any files that were present + /// at the start of the transaction. You must make a matched call to commitTransaction() or + /// rollbackTransaction() to finish the transaction. + /// + /// Note that buffered documents and delete terms are not handled within the transactions, so + /// they must be flushed before the transaction is started. + virtual void startTransaction(bool haveReadLock); + + /// Rolls back the transaction and restores state to where we were at the start. + virtual void rollbackTransaction(); + + /// Commits the transaction. This will write the new segments file and remove and pending + /// deletions we have accumulated during the transaction. + virtual void commitTransaction(); + virtual void rollbackInternal(); + + virtual void finishMerges(bool waitForMerges); + + /// Called whenever the SegmentInfos has been updated and the index files referenced exist + /// (correctly) in the index directory. + virtual void checkpoint(); + + virtual void finishAddIndexes(); + virtual void blockAddIndexes(bool includePendingClose); + virtual void resumeAddIndexes(); + virtual void resetMergeExceptions(); + virtual void noDupDirs(Collection dirs); + + virtual bool hasExternalSegments(); + + /// If any of our segments are using a directory != ours then we have to either copy them over one + /// by one, merge them (if merge policy has chosen to) or wait until currently running merges (in + /// the background) complete. We don't return until the SegmentInfos has no more external segments. + /// Currently this is only used by addIndexesNoOptimize(). + virtual void resolveExternalSegments(); + + /// A hook for extending classes to execute operations after pending added and deleted documents have + /// been flushed to the Directory but before the change is committed (new segments_N file written). + virtual void doAfterFlush(); + + /// A hook for extending classes to execute operations before pending added and deleted documents are + /// flushed to the Directory. + virtual void doBeforeFlush(); + + virtual void commit(int64_t sizeInBytes); + virtual void finishCommit(); + + /// Flush all in-memory buffered updates (adds and deletes) to the Directory. + /// @param triggerMerge if true, we may merge segments (if deletes or docs were flushed) if necessary + /// @param flushDocStores if false we are allowed to keep doc stores open to share with the next segment + /// @param flushDeletes whether pending deletes should also be flushed + virtual void flush(bool triggerMerge, bool flushDocStores, bool flushDeletes); + virtual bool doFlush(bool flushDocStores, bool flushDeletes); + virtual bool doFlushInternal(bool flushDocStores, bool flushDeletes); + + virtual int32_t ensureContiguousMerge(const OneMergePtr& merge); + + /// Carefully merges deletes for the segments we just merged. This is tricky because, although merging + /// will clear all deletes (compacts the documents), new deletes may have been flushed to the segments + /// since the merge was started. This method "carries over" such new deletes onto the newly merged + /// segment, and saves the resulting deletes file (incrementing the delete generation for merge.info). + /// If no deletes were flushed, no new deletes file is saved. + virtual void commitMergedDeletes(const OneMergePtr& merge, const SegmentReaderPtr& mergeReader); + virtual bool commitMerge(const OneMergePtr& merge, const SegmentMergerPtr& merger, int32_t mergedDocCount, const SegmentReaderPtr& mergedReader); + + virtual LuceneException handleMergeException(const LuceneException& exc, const OneMergePtr& merge); + + virtual void _mergeInit(const OneMergePtr& merge); + + virtual void setDiagnostics(const SegmentInfoPtr& info, const String& source); + virtual void setDiagnostics(const SegmentInfoPtr& info, const String& source, MapStringString details); + + virtual void setMergeDocStoreIsCompoundFile(const OneMergePtr& merge); + virtual void closeMergeReaders(const OneMergePtr& merge, bool suppressExceptions); + + /// Does the actual (time-consuming) work of the merge, but without holding synchronized lock on + /// IndexWriter instance. + virtual int32_t mergeMiddle(const OneMergePtr& merge); + + /// Apply buffered deletes to all segments. + virtual bool applyDeletes(); + + virtual String segString(const SegmentInfosPtr& infos); + + virtual bool startSync(const String& fileName, HashSet pending); + virtual void finishSync(const String& fileName, bool success); + + /// Blocks until all files in syncing are sync'd + bool waitForAllSynced(HashSet syncing); + void doWait(); + + /// Walk through all files referenced by the current segmentInfos and ask the Directory to sync each + /// file, if it wasn't already. If that succeeds, then we prepare a new segments_N file but do not + /// fully commit it. + virtual void startCommit(int64_t sizeInBytes, MapStringString commitUserData); + + virtual LuceneException handleOOM(const std::bad_alloc& oom, const String& location); + + friend class ReaderPool; +}; + +/// If {@link #getReader} has been called (ie, this writer is in near real-time mode), then after +/// a merge completes, this class can be invoked to warm the reader on the newly merged segment, +/// before the merge commits. This is not required for near real-time search, but will reduce +/// search latency on opening a new near real-time reader after a merge completes. +/// +/// NOTE: warm is called before any deletes have been carried over to the merged segment. +class LPPAPI IndexReaderWarmer : public LuceneObject { +public: + virtual ~IndexReaderWarmer(); + + LUCENE_CLASS(IndexReaderWarmer); - LUCENE_CLASS(IndexReaderWarmer); +public: + virtual void warm(const IndexReaderPtr& reader) = 0; +}; - public: - virtual void warm(const IndexReaderPtr& reader) = 0; - }; } #endif diff --git a/include/InfoStream.h b/include/InfoStream.h index a15020b6..2c649762 100644 --- a/include/InfoStream.h +++ b/include/InfoStream.h @@ -10,59 +10,56 @@ #include "LuceneObject.h" #include -namespace Lucene -{ - /// Utility class to support streaming info messages. - class LPPAPI InfoStream : public LuceneObject - { - protected: - InfoStream(); - - public: - virtual ~InfoStream(); - LUCENE_CLASS(InfoStream); - - public: - virtual InfoStream& operator<< (const String& t) = 0; - }; - - /// Stream override to write messages to a file. - class LPPAPI InfoStreamFile : public InfoStream - { - public: - InfoStreamFile(const String& path); - virtual ~InfoStreamFile(); - - LUCENE_CLASS(InfoStreamFile); - - protected: - boost::filesystem::wofstream file; - - public: - virtual InfoStreamFile& operator<< (const String& t); - }; - - /// Stream override to write messages to a std::cout. - class LPPAPI InfoStreamOut : public InfoStream - { - public: - virtual ~InfoStreamOut(); - LUCENE_CLASS(InfoStreamOut); - - public: - virtual InfoStreamOut& operator<< (const String& t); - }; - - /// Null stream override to eat messages. - class LPPAPI InfoStreamNull : public InfoStream - { - public: - virtual ~InfoStreamNull(); - LUCENE_CLASS(InfoStreamNull); - - public: - virtual InfoStreamNull& operator<< (const String& t); - }; +namespace Lucene { + +/// Utility class to support streaming info messages. +class LPPAPI InfoStream : public LuceneObject { +protected: + InfoStream(); + +public: + virtual ~InfoStream(); + LUCENE_CLASS(InfoStream); + +public: + virtual InfoStream& operator<< (const String& t) = 0; +}; + +/// Stream override to write messages to a file. +class LPPAPI InfoStreamFile : public InfoStream { +public: + InfoStreamFile(const String& path); + virtual ~InfoStreamFile(); + + LUCENE_CLASS(InfoStreamFile); + +protected: + boost::filesystem::wofstream file; + +public: + virtual InfoStreamFile& operator<< (const String& t); +}; + +/// Stream override to write messages to a std::cout. +class LPPAPI InfoStreamOut : public InfoStream { +public: + virtual ~InfoStreamOut(); + LUCENE_CLASS(InfoStreamOut); + +public: + virtual InfoStreamOut& operator<< (const String& t); +}; + +/// Null stream override to eat messages. +class LPPAPI InfoStreamNull : public InfoStream { +public: + virtual ~InfoStreamNull(); + LUCENE_CLASS(InfoStreamNull); + +public: + virtual InfoStreamNull& operator<< (const String& t); +}; + } #endif diff --git a/include/InputStreamReader.h b/include/InputStreamReader.h index 9a55a88a..1dd7730f 100644 --- a/include/InputStreamReader.h +++ b/include/InputStreamReader.h @@ -9,38 +9,38 @@ #include "Reader.h" -namespace Lucene -{ - /// An InputStreamReader is a bridge from byte streams to character streams. - class InputStreamReader : public Reader - { - public: - /// Create an InputStreamReader that uses the utf8 charset. - InputStreamReader(const ReaderPtr& reader); - virtual ~InputStreamReader(); - - LUCENE_CLASS(InputStreamReader); - - protected: - ReaderPtr reader; - UTF8DecoderStreamPtr decoder; - - public: - /// Read a single character. - virtual int32_t read(); - - /// Read characters into a portion of an array. - virtual int32_t read(wchar_t* b, int32_t offset, int32_t length); - - /// Close the stream. - virtual void close(); - - /// Tell whether this stream supports the mark() operation - virtual bool markSupported(); - - /// Reset the stream. - virtual void reset(); - }; +namespace Lucene { + +/// An InputStreamReader is a bridge from byte streams to character streams. +class InputStreamReader : public Reader { +public: + /// Create an InputStreamReader that uses the utf8 charset. + InputStreamReader(const ReaderPtr& reader); + virtual ~InputStreamReader(); + + LUCENE_CLASS(InputStreamReader); + +protected: + ReaderPtr reader; + UTF8DecoderStreamPtr decoder; + +public: + /// Read a single character. + virtual int32_t read(); + + /// Read characters into a portion of an array. + virtual int32_t read(wchar_t* b, int32_t offset, int32_t length); + + /// Close the stream. + virtual void close(); + + /// Tell whether this stream supports the mark() operation + virtual bool markSupported(); + + /// Reset the stream. + virtual void reset(); +}; + } #endif diff --git a/include/IntBlockPool.h b/include/IntBlockPool.h index a004216c..e96f1a19 100644 --- a/include/IntBlockPool.h +++ b/include/IntBlockPool.h @@ -9,33 +9,33 @@ #include "LuceneObject.h" -namespace Lucene -{ - class IntBlockPool : public LuceneObject - { - public: - IntBlockPool(const DocumentsWriterPtr& docWriter, bool trackAllocations); - virtual ~IntBlockPool(); +namespace Lucene { - LUCENE_CLASS(IntBlockPool); +class IntBlockPool : public LuceneObject { +public: + IntBlockPool(const DocumentsWriterPtr& docWriter, bool trackAllocations); + virtual ~IntBlockPool(); - public: - Collection buffers; + LUCENE_CLASS(IntBlockPool); - int32_t bufferUpto; // Which buffer we are upto - int32_t intUpto; // Where we are in head buffer +public: + Collection buffers; - IntArray buffer; // Current head buffer - int32_t intOffset; // Current head offset - bool trackAllocations; + int32_t bufferUpto; // Which buffer we are upto + int32_t intUpto; // Where we are in head buffer - protected: - DocumentsWriterWeakPtr _docWriter; + IntArray buffer; // Current head buffer + int32_t intOffset; // Current head offset + bool trackAllocations; + +protected: + DocumentsWriterWeakPtr _docWriter; + +public: + void reset(); + void nextBuffer(); +}; - public: - void reset(); - void nextBuffer(); - }; } #endif diff --git a/include/IntFieldSource.h b/include/IntFieldSource.h index bf064201..c2473bf4 100644 --- a/include/IntFieldSource.h +++ b/include/IntFieldSource.h @@ -9,36 +9,36 @@ #include "FieldCacheSource.h" -namespace Lucene -{ - /// Obtains int field values from the {@link FieldCache} using getInts() and makes those values available - /// as other numeric types, casting as needed. - /// - /// @see FieldCacheSource for requirements on the field. - /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite - /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU - /// per lookup but will not consume double the FieldCache RAM. - class LPPAPI IntFieldSource : public FieldCacheSource - { - public: - /// Create a cached int field source with a specific string-to-int parser. - IntFieldSource(const String& field, const IntParserPtr& parser = IntParserPtr()); - virtual ~IntFieldSource(); - - LUCENE_CLASS(IntFieldSource); - - protected: - IntParserPtr parser; - - public: - virtual String description(); - virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); - virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); - virtual int32_t cachedFieldSourceHashCode(); - }; +namespace Lucene { + +/// Obtains int field values from the {@link FieldCache} using getInts() and makes those values available +/// as other numeric types, casting as needed. +/// +/// @see FieldCacheSource for requirements on the field. +/// +/// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite +/// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's +/// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, +/// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU +/// per lookup but will not consume double the FieldCache RAM. +class LPPAPI IntFieldSource : public FieldCacheSource { +public: + /// Create a cached int field source with a specific string-to-int parser. + IntFieldSource(const String& field, const IntParserPtr& parser = IntParserPtr()); + virtual ~IntFieldSource(); + + LUCENE_CLASS(IntFieldSource); + +protected: + IntParserPtr parser; + +public: + virtual String description(); + virtual DocValuesPtr getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader); + virtual bool cachedFieldSourceEquals(const FieldCacheSourcePtr& other); + virtual int32_t cachedFieldSourceHashCode(); +}; + } #endif diff --git a/include/InvertedDocConsumer.h b/include/InvertedDocConsumer.h index 4cb7c713..3ef78cb6 100644 --- a/include/InvertedDocConsumer.h +++ b/include/InvertedDocConsumer.h @@ -9,36 +9,36 @@ #include "LuceneObject.h" -namespace Lucene -{ - class InvertedDocConsumer : public LuceneObject - { - public: - virtual ~InvertedDocConsumer(); +namespace Lucene { - LUCENE_CLASS(InvertedDocConsumer); +class InvertedDocConsumer : public LuceneObject { +public: + virtual ~InvertedDocConsumer(); - public: - FieldInfosPtr fieldInfos; + LUCENE_CLASS(InvertedDocConsumer); - public: - /// Add a new thread - virtual InvertedDocConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread) = 0; +public: + FieldInfosPtr fieldInfos; - /// Abort (called after hitting AbortException) - virtual void abort() = 0; +public: + /// Add a new thread + virtual InvertedDocConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread) = 0; - /// Flush a new segment - virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; + /// Abort (called after hitting AbortException) + virtual void abort() = 0; - /// Close doc stores - virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; + /// Flush a new segment + virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; - /// Attempt to free RAM, returning true if any RAM was freed - virtual bool freeRAM() = 0; + /// Close doc stores + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; + + /// Attempt to free RAM, returning true if any RAM was freed + virtual bool freeRAM() = 0; + + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); +}; - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); - }; } #endif diff --git a/include/InvertedDocConsumerPerField.h b/include/InvertedDocConsumerPerField.h index d4c93918..d5591a5b 100644 --- a/include/InvertedDocConsumerPerField.h +++ b/include/InvertedDocConsumerPerField.h @@ -9,32 +9,32 @@ #include "LuceneObject.h" -namespace Lucene -{ - class InvertedDocConsumerPerField : public LuceneObject - { - public: - virtual ~InvertedDocConsumerPerField(); +namespace Lucene { - LUCENE_CLASS(InvertedDocConsumerPerField); +class InvertedDocConsumerPerField : public LuceneObject { +public: + virtual ~InvertedDocConsumerPerField(); - public: - /// Called once per field, and is given all Fieldable occurrences for this field in the document. - /// Return true if you wish to see inverted tokens for these fields - virtual bool start(Collection fields, int32_t count) = 0; + LUCENE_CLASS(InvertedDocConsumerPerField); - /// Called before a field instance is being processed - virtual void start(const FieldablePtr& field) = 0; +public: + /// Called once per field, and is given all Fieldable occurrences for this field in the document. + /// Return true if you wish to see inverted tokens for these fields + virtual bool start(Collection fields, int32_t count) = 0; - /// Called once per inverted token - virtual void add() = 0; + /// Called before a field instance is being processed + virtual void start(const FieldablePtr& field) = 0; - /// Called once per field per document, after all Fieldable occurrences are inverted - virtual void finish() = 0; + /// Called once per inverted token + virtual void add() = 0; + + /// Called once per field per document, after all Fieldable occurrences are inverted + virtual void finish() = 0; + + /// Called on hitting an aborting exception + virtual void abort() = 0; +}; - /// Called on hitting an aborting exception - virtual void abort() = 0; - }; } #endif diff --git a/include/InvertedDocConsumerPerThread.h b/include/InvertedDocConsumerPerThread.h index afcc8a4e..e66fab7e 100644 --- a/include/InvertedDocConsumerPerThread.h +++ b/include/InvertedDocConsumerPerThread.h @@ -9,21 +9,21 @@ #include "LuceneObject.h" -namespace Lucene -{ - class InvertedDocConsumerPerThread : public LuceneObject - { - public: - virtual ~InvertedDocConsumerPerThread(); - - LUCENE_CLASS(InvertedDocConsumerPerThread); - - public: - virtual void startDocument() = 0; - virtual InvertedDocConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) = 0; - virtual DocWriterPtr finishDocument() = 0; - virtual void abort() = 0; - }; +namespace Lucene { + +class InvertedDocConsumerPerThread : public LuceneObject { +public: + virtual ~InvertedDocConsumerPerThread(); + + LUCENE_CLASS(InvertedDocConsumerPerThread); + +public: + virtual void startDocument() = 0; + virtual InvertedDocConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) = 0; + virtual DocWriterPtr finishDocument() = 0; + virtual void abort() = 0; +}; + } #endif diff --git a/include/InvertedDocEndConsumer.h b/include/InvertedDocEndConsumer.h index 413ee367..86a8a834 100644 --- a/include/InvertedDocEndConsumer.h +++ b/include/InvertedDocEndConsumer.h @@ -9,22 +9,22 @@ #include "LuceneObject.h" -namespace Lucene -{ - class InvertedDocEndConsumer : public LuceneObject - { - public: - virtual ~InvertedDocEndConsumer(); - - LUCENE_CLASS(InvertedDocEndConsumer); - - public: - virtual InvertedDocEndConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread) = 0; - virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; - virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; - virtual void abort() = 0; - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos) = 0; - }; +namespace Lucene { + +class InvertedDocEndConsumer : public LuceneObject { +public: + virtual ~InvertedDocEndConsumer(); + + LUCENE_CLASS(InvertedDocEndConsumer); + +public: + virtual InvertedDocEndConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread) = 0; + virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; + virtual void abort() = 0; + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos) = 0; +}; + } #endif diff --git a/include/InvertedDocEndConsumerPerField.h b/include/InvertedDocEndConsumerPerField.h index dc437336..51194c00 100644 --- a/include/InvertedDocEndConsumerPerField.h +++ b/include/InvertedDocEndConsumerPerField.h @@ -9,19 +9,19 @@ #include "LuceneObject.h" -namespace Lucene -{ - class InvertedDocEndConsumerPerField : public LuceneObject - { - public: - virtual ~InvertedDocEndConsumerPerField(); - - LUCENE_CLASS(InvertedDocEndConsumerPerField); - - public: - virtual void finish() = 0; - virtual void abort() = 0; - }; +namespace Lucene { + +class InvertedDocEndConsumerPerField : public LuceneObject { +public: + virtual ~InvertedDocEndConsumerPerField(); + + LUCENE_CLASS(InvertedDocEndConsumerPerField); + +public: + virtual void finish() = 0; + virtual void abort() = 0; +}; + } #endif diff --git a/include/InvertedDocEndConsumerPerThread.h b/include/InvertedDocEndConsumerPerThread.h index 986e3622..9a070d34 100644 --- a/include/InvertedDocEndConsumerPerThread.h +++ b/include/InvertedDocEndConsumerPerThread.h @@ -9,21 +9,21 @@ #include "LuceneObject.h" -namespace Lucene -{ - class InvertedDocEndConsumerPerThread : public LuceneObject - { - public: - virtual ~InvertedDocEndConsumerPerThread(); - - LUCENE_CLASS(InvertedDocEndConsumerPerThread); - - public: - virtual void startDocument() = 0; - virtual InvertedDocEndConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) = 0; - virtual void finishDocument() = 0; - virtual void abort() = 0; - }; +namespace Lucene { + +class InvertedDocEndConsumerPerThread : public LuceneObject { +public: + virtual ~InvertedDocEndConsumerPerThread(); + + LUCENE_CLASS(InvertedDocEndConsumerPerThread); + +public: + virtual void startDocument() = 0; + virtual InvertedDocEndConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) = 0; + virtual void finishDocument() = 0; + virtual void abort() = 0; +}; + } #endif diff --git a/include/KeepOnlyLastCommitDeletionPolicy.h b/include/KeepOnlyLastCommitDeletionPolicy.h index e015666e..ceb25104 100644 --- a/include/KeepOnlyLastCommitDeletionPolicy.h +++ b/include/KeepOnlyLastCommitDeletionPolicy.h @@ -9,24 +9,24 @@ #include "IndexDeletionPolicy.h" -namespace Lucene -{ - /// This {@link IndexDeletionPolicy} implementation that keeps only the most recent commit and immediately - /// removes all prior commits after a new commit is done. This is the default deletion policy. - class LPPAPI KeepOnlyLastCommitDeletionPolicy : public IndexDeletionPolicy - { - public: - virtual ~KeepOnlyLastCommitDeletionPolicy(); - - LUCENE_CLASS(KeepOnlyLastCommitDeletionPolicy); - - public: - /// Deletes all commits except the most recent one. - virtual void onInit(Collection commits); - - /// Deletes all commits except the most recent one. - virtual void onCommit(Collection commits); - }; +namespace Lucene { + +/// This {@link IndexDeletionPolicy} implementation that keeps only the most recent commit and immediately +/// removes all prior commits after a new commit is done. This is the default deletion policy. +class LPPAPI KeepOnlyLastCommitDeletionPolicy : public IndexDeletionPolicy { +public: + virtual ~KeepOnlyLastCommitDeletionPolicy(); + + LUCENE_CLASS(KeepOnlyLastCommitDeletionPolicy); + +public: + /// Deletes all commits except the most recent one. + virtual void onInit(Collection commits); + + /// Deletes all commits except the most recent one. + virtual void onCommit(Collection commits); +}; + } #endif diff --git a/include/KeywordAnalyzer.h b/include/KeywordAnalyzer.h index d8007c29..d57351d4 100644 --- a/include/KeywordAnalyzer.h +++ b/include/KeywordAnalyzer.h @@ -9,21 +9,21 @@ #include "Analyzer.h" -namespace Lucene -{ - /// Tokenizes the entire stream as a single token. This is useful for data like zip codes, ids, and some - /// product names. - class LPPAPI KeywordAnalyzer : public Analyzer - { - public: - virtual ~KeywordAnalyzer(); - - LUCENE_CLASS(KeywordAnalyzer); - - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +namespace Lucene { + +/// Tokenizes the entire stream as a single token. This is useful for data like zip codes, ids, and some +/// product names. +class LPPAPI KeywordAnalyzer : public Analyzer { +public: + virtual ~KeywordAnalyzer(); + + LUCENE_CLASS(KeywordAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + } #endif diff --git a/include/KeywordTokenizer.h b/include/KeywordTokenizer.h index c15d731b..e93bbc4e 100644 --- a/include/KeywordTokenizer.h +++ b/include/KeywordTokenizer.h @@ -9,37 +9,37 @@ #include "Tokenizer.h" -namespace Lucene -{ - /// Emits the entire input as a single token. - class LPPAPI KeywordTokenizer : public Tokenizer - { - public: - KeywordTokenizer(const ReaderPtr& input); - KeywordTokenizer(const ReaderPtr& input, int32_t bufferSize); - KeywordTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input, int32_t bufferSize); - KeywordTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input, int32_t bufferSize); - - virtual ~KeywordTokenizer(); - - LUCENE_CLASS(KeywordTokenizer); - - protected: - static const int32_t DEFAULT_BUFFER_SIZE; - - bool done; - int32_t finalOffset; - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; - - protected: - void init(int32_t bufferSize); - - public: - virtual bool incrementToken(); - virtual void end(); - virtual void reset(); - }; +namespace Lucene { + +/// Emits the entire input as a single token. +class LPPAPI KeywordTokenizer : public Tokenizer { +public: + KeywordTokenizer(const ReaderPtr& input); + KeywordTokenizer(const ReaderPtr& input, int32_t bufferSize); + KeywordTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input, int32_t bufferSize); + KeywordTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input, int32_t bufferSize); + + virtual ~KeywordTokenizer(); + + LUCENE_CLASS(KeywordTokenizer); + +protected: + static const int32_t DEFAULT_BUFFER_SIZE; + + bool done; + int32_t finalOffset; + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + +protected: + void init(int32_t bufferSize); + +public: + virtual bool incrementToken(); + virtual void end(); + virtual void reset(); +}; + } #endif diff --git a/include/LengthFilter.h b/include/LengthFilter.h index 740aa85f..63f8e9d4 100644 --- a/include/LengthFilter.h +++ b/include/LengthFilter.h @@ -9,29 +9,29 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// Removes words that are too long or too short from the stream. - class LPPAPI LengthFilter : public TokenFilter - { - public: - /// Build a filter that removes words that are too long or too short from the text. - LengthFilter(const TokenStreamPtr& input, int32_t min, int32_t max); - virtual ~LengthFilter(); - - LUCENE_CLASS(LengthFilter); - - public: - int32_t min; - int32_t max; - - protected: - TermAttributePtr termAtt; - - public: - /// Returns the next input Token whose term() is the right len - virtual bool incrementToken(); - }; +namespace Lucene { + +/// Removes words that are too long or too short from the stream. +class LPPAPI LengthFilter : public TokenFilter { +public: + /// Build a filter that removes words that are too long or too short from the text. + LengthFilter(const TokenStreamPtr& input, int32_t min, int32_t max); + virtual ~LengthFilter(); + + LUCENE_CLASS(LengthFilter); + +public: + int32_t min; + int32_t max; + +protected: + TermAttributePtr termAtt; + +public: + /// Returns the next input Token whose term() is the right len + virtual bool incrementToken(); +}; + } #endif diff --git a/include/LetterTokenizer.h b/include/LetterTokenizer.h index 6db69a54..eddb040f 100644 --- a/include/LetterTokenizer.h +++ b/include/LetterTokenizer.h @@ -9,33 +9,33 @@ #include "CharTokenizer.h" -namespace Lucene -{ - /// A LetterTokenizer is a tokenizer that divides text at non-letters. That's to say, it defines tokens as maximal - /// strings of adjacent letters, as defined UnicodeUtil::isAlpha(c) predicate. - /// - /// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, where - /// words are not separated by spaces. - class LPPAPI LetterTokenizer : public CharTokenizer - { - public: - /// Construct a new LetterTokenizer. - LetterTokenizer(const ReaderPtr& input); - - /// Construct a new LetterTokenizer using a given {@link AttributeSource}. - LetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - - /// Construct a new LetterTokenizer using a given {@link AttributeFactory}. - LetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~LetterTokenizer(); - - LUCENE_CLASS(LetterTokenizer); - - public: - /// Collects only characters which satisfy UnicodeUtil::isAlpha(c). - virtual bool isTokenChar(wchar_t c); - }; +namespace Lucene { + +/// A LetterTokenizer is a tokenizer that divides text at non-letters. That's to say, it defines tokens as maximal +/// strings of adjacent letters, as defined UnicodeUtil::isAlpha(c) predicate. +/// +/// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, where +/// words are not separated by spaces. +class LPPAPI LetterTokenizer : public CharTokenizer { +public: + /// Construct a new LetterTokenizer. + LetterTokenizer(const ReaderPtr& input); + + /// Construct a new LetterTokenizer using a given {@link AttributeSource}. + LetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + + /// Construct a new LetterTokenizer using a given {@link AttributeFactory}. + LetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~LetterTokenizer(); + + LUCENE_CLASS(LetterTokenizer); + +public: + /// Collects only characters which satisfy UnicodeUtil::isAlpha(c). + virtual bool isTokenChar(wchar_t c); +}; + } #endif diff --git a/include/LoadFirstFieldSelector.h b/include/LoadFirstFieldSelector.h index 45572aae..ba02dd5b 100644 --- a/include/LoadFirstFieldSelector.h +++ b/include/LoadFirstFieldSelector.h @@ -9,20 +9,20 @@ #include "FieldSelector.h" -namespace Lucene -{ - /// Load the First field and break. - /// See {@link FieldSelectorResult#LOAD_AND_BREAK} - class LPPAPI LoadFirstFieldSelector : public FieldSelector - { - public: - virtual ~LoadFirstFieldSelector(); - - LUCENE_CLASS(LoadFirstFieldSelector); - - public: - virtual FieldSelectorResult accept(const String& fieldName); - }; +namespace Lucene { + +/// Load the First field and break. +/// See {@link FieldSelectorResult#LOAD_AND_BREAK} +class LPPAPI LoadFirstFieldSelector : public FieldSelector { +public: + virtual ~LoadFirstFieldSelector(); + + LUCENE_CLASS(LoadFirstFieldSelector); + +public: + virtual FieldSelectorResult accept(const String& fieldName); +}; + } #endif diff --git a/include/Lock.h b/include/Lock.h index 29840e61..f27a11ca 100644 --- a/include/Lock.h +++ b/include/Lock.h @@ -9,42 +9,42 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// An interprocess mutex lock. - /// @see Directory#makeLock(const String&) - class LPPAPI Lock : public LuceneObject - { - public: - virtual ~Lock(); - LUCENE_CLASS(Lock); - - public: - /// How long {@link #obtain(int64_t)} waits, in milliseconds, in between attempts to acquire the lock. - static const int32_t LOCK_OBTAIN_WAIT_FOREVER; - - /// Pass this value to {@link #obtain(int64_t)} to try forever to obtain the lock. - static const int32_t LOCK_POLL_INTERVAL; - - public: - /// Attempts to obtain exclusive access and immediately return upon success or failure. - /// @return true if exclusive access is obtained. - virtual bool obtain() = 0; - - /// Releases exclusive access. - virtual void release() = 0; - - /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} - /// before using the resource. - virtual bool isLocked() = 0; - - /// Attempts to obtain an exclusive lock within amount of time given. Polls once per {@link #LOCK_POLL_INTERVAL} - /// (currently 1000) milliseconds until lockWaitTimeout is passed. - /// @param lockWaitTimeout length of time to wait in milliseconds or {@link #LOCK_OBTAIN_WAIT_FOREVER} - /// to retry forever. - /// @return true if lock was obtained. - bool obtain(int32_t lockWaitTimeout); - }; +namespace Lucene { + +/// An interprocess mutex lock. +/// @see Directory#makeLock(const String&) +class LPPAPI Lock : public LuceneObject { +public: + virtual ~Lock(); + LUCENE_CLASS(Lock); + +public: + /// How long {@link #obtain(int64_t)} waits, in milliseconds, in between attempts to acquire the lock. + static const int32_t LOCK_OBTAIN_WAIT_FOREVER; + + /// Pass this value to {@link #obtain(int64_t)} to try forever to obtain the lock. + static const int32_t LOCK_POLL_INTERVAL; + +public: + /// Attempts to obtain exclusive access and immediately return upon success or failure. + /// @return true if exclusive access is obtained. + virtual bool obtain() = 0; + + /// Releases exclusive access. + virtual void release() = 0; + + /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} + /// before using the resource. + virtual bool isLocked() = 0; + + /// Attempts to obtain an exclusive lock within amount of time given. Polls once per {@link #LOCK_POLL_INTERVAL} + /// (currently 1000) milliseconds until lockWaitTimeout is passed. + /// @param lockWaitTimeout length of time to wait in milliseconds or {@link #LOCK_OBTAIN_WAIT_FOREVER} + /// to retry forever. + /// @return true if lock was obtained. + bool obtain(int32_t lockWaitTimeout); +}; + } #endif diff --git a/include/LockFactory.h b/include/LockFactory.h index 56ce224b..b921e5a6 100644 --- a/include/LockFactory.h +++ b/include/LockFactory.h @@ -9,46 +9,46 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Base class for Locking implementation. {@link Directory} uses - /// instances of this class to implement locking. - /// Note that there are some useful tools to verify that - /// your LockFactory is working correctly: {@link - /// VerifyingLockFactory}, {@link LockStressTest}, {@link - /// LockVerifyServer}. - /// @see LockVerifyServer - /// @see LockStressTest - /// @see VerifyingLockFactory - class LPPAPI LockFactory : public LuceneObject - { - public: - virtual ~LockFactory(); - - LUCENE_CLASS(LockFactory); - - protected: - String lockPrefix; - - public: - /// Set the prefix in use for all locks created in this LockFactory. This is normally called once, when a - /// Directory gets this LockFactory instance. However, you can also call this (after this instance is - /// assigned to a Directory) to override the prefix in use. This is helpful if you're running Lucene on - /// machines that have different mount points for the same shared directory. - virtual void setLockPrefix(const String& lockPrefix); - - /// Get the prefix in use for all locks created in this LockFactory. - virtual String getLockPrefix(); - - /// Return a new Lock instance identified by lockName. - /// @param lockName name of the lock to be created. - virtual LockPtr makeLock(const String& lockName) = 0; - - /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you - /// are certain this lock is no longer in use. - /// @param lockName name of the lock to be cleared. - virtual void clearLock(const String& lockName) = 0; - }; +namespace Lucene { + +/// Base class for Locking implementation. {@link Directory} uses +/// instances of this class to implement locking. +/// Note that there are some useful tools to verify that +/// your LockFactory is working correctly: {@link +/// VerifyingLockFactory}, {@link LockStressTest}, {@link +/// LockVerifyServer}. +/// @see LockVerifyServer +/// @see LockStressTest +/// @see VerifyingLockFactory +class LPPAPI LockFactory : public LuceneObject { +public: + virtual ~LockFactory(); + + LUCENE_CLASS(LockFactory); + +protected: + String lockPrefix; + +public: + /// Set the prefix in use for all locks created in this LockFactory. This is normally called once, when a + /// Directory gets this LockFactory instance. However, you can also call this (after this instance is + /// assigned to a Directory) to override the prefix in use. This is helpful if you're running Lucene on + /// machines that have different mount points for the same shared directory. + virtual void setLockPrefix(const String& lockPrefix); + + /// Get the prefix in use for all locks created in this LockFactory. + virtual String getLockPrefix(); + + /// Return a new Lock instance identified by lockName. + /// @param lockName name of the lock to be created. + virtual LockPtr makeLock(const String& lockName) = 0; + + /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you + /// are certain this lock is no longer in use. + /// @param lockName name of the lock to be cleared. + virtual void clearLock(const String& lockName) = 0; +}; + } #endif diff --git a/include/LogByteSizeMergePolicy.h b/include/LogByteSizeMergePolicy.h index f8b4194e..83fff274 100644 --- a/include/LogByteSizeMergePolicy.h +++ b/include/LogByteSizeMergePolicy.h @@ -9,53 +9,53 @@ #include "LogMergePolicy.h" -namespace Lucene -{ - /// This is a {@link LogMergePolicy} that measures size of a segment as the total byte size of the - /// segment's files. - class LPPAPI LogByteSizeMergePolicy : public LogMergePolicy - { - public: - LogByteSizeMergePolicy(const IndexWriterPtr& writer); - virtual ~LogByteSizeMergePolicy(); - - LUCENE_CLASS(LogByteSizeMergePolicy); - - public: - /// Default minimum segment size. @see setMinMergeMB. - static const double DEFAULT_MIN_MERGE_MB; - - /// Default maximum segment size. A segment of this size or larger will never be merged. - /// @see setMaxMergeMB - static const double DEFAULT_MAX_MERGE_MB; - - protected: - virtual int64_t size(const SegmentInfoPtr& info); - - public: - /// Determines the largest segment (measured by total byte size of the segment's files, in MB) - /// that may be merged with other segments. Small values (eg., less than 50 MB) are best for - /// interactive indexing, as this limits the length of pauses while indexing to a few seconds. - /// Larger values are best for batched indexing and speedier searches. - /// - /// Note that {@link #setMaxMergeDocs} is also used to check whether a segment is too large for - /// merging (it's either or). - void setMaxMergeMB(double mb); - - /// Returns the largest segment (measured by total byte size of the segment's files, in MB) that - /// may be merged with other segments. @see #setMaxMergeMB - double getMaxMergeMB(); - - /// Sets the minimum size for the lowest level segments. Any segments below this size are - /// considered to be on the same level (even if they vary drastically in size) and will be merged - /// whenever there are mergeFactor of them. This effectively truncates the "long tail" of small - /// segments that would otherwise be created into a single level. If you set this too large, it - /// could greatly increase the merging cost during indexing (if you flush many small segments). - void setMinMergeMB(double mb); - - /// Get the minimum size for a segment to remain un-merged. @see #setMinMergeMB - double getMinMergeMB(); - }; +namespace Lucene { + +/// This is a {@link LogMergePolicy} that measures size of a segment as the total byte size of the +/// segment's files. +class LPPAPI LogByteSizeMergePolicy : public LogMergePolicy { +public: + LogByteSizeMergePolicy(const IndexWriterPtr& writer); + virtual ~LogByteSizeMergePolicy(); + + LUCENE_CLASS(LogByteSizeMergePolicy); + +public: + /// Default minimum segment size. @see setMinMergeMB. + static const double DEFAULT_MIN_MERGE_MB; + + /// Default maximum segment size. A segment of this size or larger will never be merged. + /// @see setMaxMergeMB + static const double DEFAULT_MAX_MERGE_MB; + +protected: + virtual int64_t size(const SegmentInfoPtr& info); + +public: + /// Determines the largest segment (measured by total byte size of the segment's files, in MB) + /// that may be merged with other segments. Small values (eg., less than 50 MB) are best for + /// interactive indexing, as this limits the length of pauses while indexing to a few seconds. + /// Larger values are best for batched indexing and speedier searches. + /// + /// Note that {@link #setMaxMergeDocs} is also used to check whether a segment is too large for + /// merging (it's either or). + void setMaxMergeMB(double mb); + + /// Returns the largest segment (measured by total byte size of the segment's files, in MB) that + /// may be merged with other segments. @see #setMaxMergeMB + double getMaxMergeMB(); + + /// Sets the minimum size for the lowest level segments. Any segments below this size are + /// considered to be on the same level (even if they vary drastically in size) and will be merged + /// whenever there are mergeFactor of them. This effectively truncates the "long tail" of small + /// segments that would otherwise be created into a single level. If you set this too large, it + /// could greatly increase the merging cost during indexing (if you flush many small segments). + void setMinMergeMB(double mb); + + /// Get the minimum size for a segment to remain un-merged. @see #setMinMergeMB + double getMinMergeMB(); +}; + } #endif diff --git a/include/LogDocMergePolicy.h b/include/LogDocMergePolicy.h index 9e44e6fc..4d26df83 100644 --- a/include/LogDocMergePolicy.h +++ b/include/LogDocMergePolicy.h @@ -9,36 +9,36 @@ #include "LogMergePolicy.h" -namespace Lucene -{ - /// This is a {@link LogMergePolicy} that measures size of a segment as the number of documents - /// (not taking deletions into account). - class LPPAPI LogDocMergePolicy : public LogMergePolicy - { - public: - LogDocMergePolicy(const IndexWriterPtr& writer); - virtual ~LogDocMergePolicy(); - - LUCENE_CLASS(LogDocMergePolicy); - - public: - /// Default minimum segment size. @see setMinMergeDocs - static const int32_t DEFAULT_MIN_MERGE_DOCS; - - protected: - virtual int64_t size(const SegmentInfoPtr& info); - - public: - /// Sets the minimum size for the lowest level segments. Any segments below this size are considered - /// to be on the same level (even if they vary drastically in size) and will be merged whenever there - /// are mergeFactor of them. This effectively truncates the "long tail" of small segments that would - /// otherwise be created into a single level. If you set this too large, it could greatly increase the - /// merging cost during indexing (if you flush many small segments). - void setMinMergeDocs(int32_t minMergeDocs); - - /// Get the minimum size for a segment to remain un-merged. @see #setMinMergeDocs - int32_t getMinMergeDocs(); - }; +namespace Lucene { + +/// This is a {@link LogMergePolicy} that measures size of a segment as the number of documents +/// (not taking deletions into account). +class LPPAPI LogDocMergePolicy : public LogMergePolicy { +public: + LogDocMergePolicy(const IndexWriterPtr& writer); + virtual ~LogDocMergePolicy(); + + LUCENE_CLASS(LogDocMergePolicy); + +public: + /// Default minimum segment size. @see setMinMergeDocs + static const int32_t DEFAULT_MIN_MERGE_DOCS; + +protected: + virtual int64_t size(const SegmentInfoPtr& info); + +public: + /// Sets the minimum size for the lowest level segments. Any segments below this size are considered + /// to be on the same level (even if they vary drastically in size) and will be merged whenever there + /// are mergeFactor of them. This effectively truncates the "long tail" of small segments that would + /// otherwise be created into a single level. If you set this too large, it could greatly increase the + /// merging cost during indexing (if you flush many small segments). + void setMinMergeDocs(int32_t minMergeDocs); + + /// Get the minimum size for a segment to remain un-merged. @see #setMinMergeDocs + int32_t getMinMergeDocs(); +}; + } #endif diff --git a/include/LogMergePolicy.h b/include/LogMergePolicy.h index 8ff447c9..c4100487 100644 --- a/include/LogMergePolicy.h +++ b/include/LogMergePolicy.h @@ -9,153 +9,153 @@ #include "MergePolicy.h" -namespace Lucene -{ - /// This class implements a {@link MergePolicy} that tries to merge segments into levels of exponentially - /// increasing size, where each level has fewer segments than the value of the merge factor. Whenever extra - /// segments (beyond the merge factor upper bound) are encountered, all segments within the level are merged. - /// You can get or set the merge factor using {@link #getMergeFactor()} and {@link #setMergeFactor(int)} - /// respectively. +namespace Lucene { + +/// This class implements a {@link MergePolicy} that tries to merge segments into levels of exponentially +/// increasing size, where each level has fewer segments than the value of the merge factor. Whenever extra +/// segments (beyond the merge factor upper bound) are encountered, all segments within the level are merged. +/// You can get or set the merge factor using {@link #getMergeFactor()} and {@link #setMergeFactor(int)} +/// respectively. +/// +/// This class is abstract and requires a subclass to define the {@link #size} method which specifies how a +/// segment's size is determined. {@link LogDocMergePolicy} is one subclass that measures size by document +/// count in the segment. {@link LogByteSizeMergePolicy} is another subclass that measures size as the total +/// byte size of the file(s) for the segment. +class LPPAPI LogMergePolicy : public MergePolicy { +public: + LogMergePolicy(const IndexWriterPtr& writer); + virtual ~LogMergePolicy(); + + LUCENE_CLASS(LogMergePolicy); + +protected: + int32_t mergeFactor; + + double noCFSRatio; + + bool calibrateSizeByDeletes; + bool _useCompoundFile; + bool _useCompoundDocStore; + +public: + /// Defines the allowed range of log(size) for each level. A level is computed by taking the max segment + /// log size, minus LEVEL_LOG_SPAN, and finding all segments falling within that range. + static const double LEVEL_LOG_SPAN; + + /// Default merge factor, which is how many segments are merged at a time. + static const int32_t DEFAULT_MERGE_FACTOR; + + /// Default maximum segment size. A segment of this size or larger will never be merged. + /// @see setMaxMergeDocs + static const int32_t DEFAULT_MAX_MERGE_DOCS; + + /// Default noCFSRatio. If a merge's size is >= 10% of the index, then we disable compound file for it. + /// @see #setNoCFSRatio + static const double DEFAULT_NO_CFS_RATIO; + + int64_t minMergeSize; + int64_t maxMergeSize; + int32_t maxMergeDocs; + +public: + /// @see #setNoCFSRatio + double getNoCFSRatio(); + + /// If a merged segment will be more than this percentage of the total size of the index, leave the segment as + /// non-compound file even if compound file is enabled. Set to 1.0 to always use CFS regardless of merge size. + void setNoCFSRatio(double noCFSRatio); + + /// Returns the number of segments that are merged at once and also controls the total number of segments + /// allowed to accumulate in the index. + int32_t getMergeFactor(); + + /// Determines how often segment indices are merged by addDocument(). With smaller values, less RAM is + /// used while indexing, and searches on unoptimized indices are faster, but indexing speed is slower. + /// With larger values, more RAM is used during indexing, and while searches on unoptimized indices are + /// slower, indexing is faster. Thus larger values (> 10) are best for batch index creation, and smaller + /// values (< 10) for indices that are interactively maintained. + void setMergeFactor(int32_t mergeFactor); + + /// Returns true if a newly flushed (not from merge) segment should use the compound file format. + virtual bool useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment); + + /// Sets whether compound file format should be used for newly flushed and newly merged segments. + void setUseCompoundFile(bool useCompoundFile); + + /// Returns true if newly flushed and newly merge segments are written in compound file format. + /// @see #setUseCompoundFile + bool getUseCompoundFile(); + + /// Returns true if the doc store files should use the compound file format. + virtual bool useCompoundDocStore(const SegmentInfosPtr& segments); + + /// Sets whether compound file format should be used for newly flushed and newly merged doc store + /// segment files (term vectors and stored fields). + void setUseCompoundDocStore(bool useCompoundDocStore); + + /// Returns true if newly flushed and newly merge doc store segment files (term vectors and stored fields) + /// are written in compound file format. @see #setUseCompoundDocStore + bool getUseCompoundDocStore(); + + /// Sets whether the segment size should be calibrated by the number of deletes when choosing segments + /// for merge. + void setCalibrateSizeByDeletes(bool calibrateSizeByDeletes); + + /// Returns true if the segment size should be calibrated by the number of deletes when choosing segments + /// for merge. + bool getCalibrateSizeByDeletes(); + + /// Release all resources for the policy. + virtual void close(); + + /// Returns the merges necessary to optimize the index. This merge policy defines "optimized" to mean only + /// one segment in the index, where that segment has no deletions pending nor separate norms, and it is in + /// compound file format if the current useCompoundFile setting is true. This method returns multiple merges + /// (mergeFactor at a time) so the {@link MergeScheduler} in use may make use of concurrency. + virtual MergeSpecificationPtr findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize); + + /// Finds merges necessary to expunge all deletes from the index. We simply merge adjacent segments that have + /// deletes, up to mergeFactor at a time. + virtual MergeSpecificationPtr findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos); + + /// Checks if any merges are now necessary and returns a {@link MergePolicy.MergeSpecification} if so. A merge + /// is necessary when there are more than {@link #setMergeFactor} segments at a given level. When multiple + /// levels have too many segments, this method will return multiple merges, allowing the {@link MergeScheduler} + /// to use concurrency. + virtual MergeSpecificationPtr findMerges(const SegmentInfosPtr& segmentInfos); + + /// Determines the largest segment (measured by document count) that may be merged with other segments. + /// Small values (eg., less than 10,000) are best for interactive indexing, as this limits the length of + /// pauses while indexing to a few seconds. Larger values are best for batched indexing and speedier searches. + /// + /// The default value is INT_MAX. /// - /// This class is abstract and requires a subclass to define the {@link #size} method which specifies how a - /// segment's size is determined. {@link LogDocMergePolicy} is one subclass that measures size by document - /// count in the segment. {@link LogByteSizeMergePolicy} is another subclass that measures size as the total - /// byte size of the file(s) for the segment. - class LPPAPI LogMergePolicy : public MergePolicy - { - public: - LogMergePolicy(const IndexWriterPtr& writer); - virtual ~LogMergePolicy(); - - LUCENE_CLASS(LogMergePolicy); - - protected: - int32_t mergeFactor; - - double noCFSRatio; - - bool calibrateSizeByDeletes; - bool _useCompoundFile; - bool _useCompoundDocStore; - - public: - /// Defines the allowed range of log(size) for each level. A level is computed by taking the max segment - /// log size, minus LEVEL_LOG_SPAN, and finding all segments falling within that range. - static const double LEVEL_LOG_SPAN; - - /// Default merge factor, which is how many segments are merged at a time. - static const int32_t DEFAULT_MERGE_FACTOR; - - /// Default maximum segment size. A segment of this size or larger will never be merged. - /// @see setMaxMergeDocs - static const int32_t DEFAULT_MAX_MERGE_DOCS; - - /// Default noCFSRatio. If a merge's size is >= 10% of the index, then we disable compound file for it. - /// @see #setNoCFSRatio - static const double DEFAULT_NO_CFS_RATIO; - - int64_t minMergeSize; - int64_t maxMergeSize; - int32_t maxMergeDocs; - - public: - /// @see #setNoCFSRatio - double getNoCFSRatio(); - - /// If a merged segment will be more than this percentage of the total size of the index, leave the segment as - /// non-compound file even if compound file is enabled. Set to 1.0 to always use CFS regardless of merge size. - void setNoCFSRatio(double noCFSRatio); - - /// Returns the number of segments that are merged at once and also controls the total number of segments - /// allowed to accumulate in the index. - int32_t getMergeFactor(); - - /// Determines how often segment indices are merged by addDocument(). With smaller values, less RAM is - /// used while indexing, and searches on unoptimized indices are faster, but indexing speed is slower. - /// With larger values, more RAM is used during indexing, and while searches on unoptimized indices are - /// slower, indexing is faster. Thus larger values (> 10) are best for batch index creation, and smaller - /// values (< 10) for indices that are interactively maintained. - void setMergeFactor(int32_t mergeFactor); - - /// Returns true if a newly flushed (not from merge) segment should use the compound file format. - virtual bool useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment); - - /// Sets whether compound file format should be used for newly flushed and newly merged segments. - void setUseCompoundFile(bool useCompoundFile); - - /// Returns true if newly flushed and newly merge segments are written in compound file format. - /// @see #setUseCompoundFile - bool getUseCompoundFile(); - - /// Returns true if the doc store files should use the compound file format. - virtual bool useCompoundDocStore(const SegmentInfosPtr& segments); - - /// Sets whether compound file format should be used for newly flushed and newly merged doc store - /// segment files (term vectors and stored fields). - void setUseCompoundDocStore(bool useCompoundDocStore); - - /// Returns true if newly flushed and newly merge doc store segment files (term vectors and stored fields) - /// are written in compound file format. @see #setUseCompoundDocStore - bool getUseCompoundDocStore(); - - /// Sets whether the segment size should be calibrated by the number of deletes when choosing segments - /// for merge. - void setCalibrateSizeByDeletes(bool calibrateSizeByDeletes); - - /// Returns true if the segment size should be calibrated by the number of deletes when choosing segments - /// for merge. - bool getCalibrateSizeByDeletes(); - - /// Release all resources for the policy. - virtual void close(); - - /// Returns the merges necessary to optimize the index. This merge policy defines "optimized" to mean only - /// one segment in the index, where that segment has no deletions pending nor separate norms, and it is in - /// compound file format if the current useCompoundFile setting is true. This method returns multiple merges - /// (mergeFactor at a time) so the {@link MergeScheduler} in use may make use of concurrency. - virtual MergeSpecificationPtr findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize); - - /// Finds merges necessary to expunge all deletes from the index. We simply merge adjacent segments that have - /// deletes, up to mergeFactor at a time. - virtual MergeSpecificationPtr findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos); - - /// Checks if any merges are now necessary and returns a {@link MergePolicy.MergeSpecification} if so. A merge - /// is necessary when there are more than {@link #setMergeFactor} segments at a given level. When multiple - /// levels have too many segments, this method will return multiple merges, allowing the {@link MergeScheduler} - /// to use concurrency. - virtual MergeSpecificationPtr findMerges(const SegmentInfosPtr& segmentInfos); + /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit by net size + /// (in MB) of the segment, using {@link LogByteSizeMergePolicy#setMaxMergeMB}. + void setMaxMergeDocs(int32_t maxMergeDocs); + + /// Returns the largest segment (measured by document count) that may be merged with other segments. + /// @see #setMaxMergeDocs + int32_t getMaxMergeDocs(); + +protected: + bool verbose(); + void message(const String& message); + + virtual int64_t size(const SegmentInfoPtr& info) = 0; + + int64_t sizeDocs(const SegmentInfoPtr& info); + int64_t sizeBytes(const SegmentInfoPtr& info); - /// Determines the largest segment (measured by document count) that may be merged with other segments. - /// Small values (eg., less than 10,000) are best for interactive indexing, as this limits the length of - /// pauses while indexing to a few seconds. Larger values are best for batched indexing and speedier searches. - /// - /// The default value is INT_MAX. - /// - /// The default merge policy ({@link LogByteSizeMergePolicy}) also allows you to set this limit by net size - /// (in MB) of the segment, using {@link LogByteSizeMergePolicy#setMaxMergeMB}. - void setMaxMergeDocs(int32_t maxMergeDocs); - - /// Returns the largest segment (measured by document count) that may be merged with other segments. - /// @see #setMaxMergeDocs - int32_t getMaxMergeDocs(); - - protected: - bool verbose(); - void message(const String& message); + bool isOptimized(const SegmentInfosPtr& infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize); - virtual int64_t size(const SegmentInfoPtr& info) = 0; - - int64_t sizeDocs(const SegmentInfoPtr& info); - int64_t sizeBytes(const SegmentInfoPtr& info); - - bool isOptimized(const SegmentInfosPtr& infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize); + /// Returns true if this single info is optimized (has no pending norms or deletes, is in the same dir as the + /// writer, and matches the current compound file setting + bool isOptimized(const SegmentInfoPtr& info); - /// Returns true if this single info is optimized (has no pending norms or deletes, is in the same dir as the - /// writer, and matches the current compound file setting - bool isOptimized(const SegmentInfoPtr& info); + OneMergePtr makeOneMerge(const SegmentInfosPtr& infos, const SegmentInfosPtr& infosToMerge); +}; - OneMergePtr makeOneMerge(const SegmentInfosPtr& infos, const SegmentInfosPtr& infosToMerge); - }; } #endif diff --git a/include/LowerCaseFilter.h b/include/LowerCaseFilter.h index 9aa19ae8..8679436f 100644 --- a/include/LowerCaseFilter.h +++ b/include/LowerCaseFilter.h @@ -9,23 +9,23 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// Normalizes token text to lower case. - class LPPAPI LowerCaseFilter : public TokenFilter - { - public: - LowerCaseFilter(const TokenStreamPtr& input); - virtual ~LowerCaseFilter(); - - LUCENE_CLASS(LowerCaseFilter); - - protected: - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - }; +namespace Lucene { + +/// Normalizes token text to lower case. +class LPPAPI LowerCaseFilter : public TokenFilter { +public: + LowerCaseFilter(const TokenStreamPtr& input); + virtual ~LowerCaseFilter(); + + LUCENE_CLASS(LowerCaseFilter); + +protected: + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; + } #endif diff --git a/include/LowerCaseTokenizer.h b/include/LowerCaseTokenizer.h index 2399d208..769e10cd 100644 --- a/include/LowerCaseTokenizer.h +++ b/include/LowerCaseTokenizer.h @@ -9,35 +9,35 @@ #include "LetterTokenizer.h" -namespace Lucene -{ - /// LowerCaseTokenizer performs the function of LetterTokenizer and LowerCaseFilter together. It divides text at - /// non-letters and converts them to lower case. While it is functionally equivalent to the combination of - /// LetterTokenizer and LowerCaseFilter, there is a performance advantage to doing the two tasks at once, hence - /// this (redundant) implementation. - /// - /// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, - /// where words are not separated by spaces. - class LPPAPI LowerCaseTokenizer : public LetterTokenizer - { - public: - /// Construct a new LowerCaseTokenizer. - LowerCaseTokenizer(const ReaderPtr& input); - - /// Construct a new LowerCaseTokenizer using a given {@link AttributeSource}. - LowerCaseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - - /// Construct a new LowerCaseTokenizer using a given {@link AttributeFactory}. - LowerCaseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~LowerCaseTokenizer(); - - LUCENE_CLASS(LowerCaseTokenizer); - - public: - /// Converts char to lower case CharFolder::toLower. - virtual wchar_t normalize(wchar_t c); - }; +namespace Lucene { + +/// LowerCaseTokenizer performs the function of LetterTokenizer and LowerCaseFilter together. It divides text at +/// non-letters and converts them to lower case. While it is functionally equivalent to the combination of +/// LetterTokenizer and LowerCaseFilter, there is a performance advantage to doing the two tasks at once, hence +/// this (redundant) implementation. +/// +/// Note: this does a decent job for most European languages, but does a terrible job for some Asian languages, +/// where words are not separated by spaces. +class LPPAPI LowerCaseTokenizer : public LetterTokenizer { +public: + /// Construct a new LowerCaseTokenizer. + LowerCaseTokenizer(const ReaderPtr& input); + + /// Construct a new LowerCaseTokenizer using a given {@link AttributeSource}. + LowerCaseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + + /// Construct a new LowerCaseTokenizer using a given {@link AttributeFactory}. + LowerCaseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~LowerCaseTokenizer(); + + LUCENE_CLASS(LowerCaseTokenizer); + +public: + /// Converts char to lower case CharFolder::toLower. + virtual wchar_t normalize(wchar_t c); +}; + } #endif diff --git a/include/Lucene.h b/include/Lucene.h index 149a975f..c377f154 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -38,37 +38,38 @@ using boost::uint64_t; #include "LuceneTypes.h" #include "LuceneAllocator.h" -namespace boost -{ - struct blank; - class thread; - class any; - template < typename Signature > class function; - namespace interprocess - { - class file_lock; - } - namespace posix_time - { - class ptime; - } +namespace boost { + +struct blank; +class thread; +class any; +template < typename Signature > class function; +namespace interprocess { + +class file_lock; +} +namespace posix_time { + +class ptime; } -namespace Lucene -{ - typedef std::basic_string< char, std::char_traits > SingleString; - typedef std::basic_ostringstream< char, std::char_traits > SingleStringStream; - typedef std::basic_string< wchar_t, std::char_traits > String; - typedef std::basic_ostringstream< wchar_t, std::char_traits > StringStream; +} + +namespace Lucene { + +typedef std::basic_string< char, std::char_traits > SingleString; +typedef std::basic_ostringstream< char, std::char_traits > SingleStringStream; +typedef std::basic_string< wchar_t, std::char_traits > String; +typedef std::basic_ostringstream< wchar_t, std::char_traits > StringStream; - const std::basic_string< wchar_t, std::char_traits > EmptyString; +const std::basic_string< wchar_t, std::char_traits > EmptyString; - typedef boost::shared_ptr filelockPtr; - typedef boost::shared_ptr threadPtr; +typedef boost::shared_ptr filelockPtr; +typedef boost::shared_ptr threadPtr; - typedef boost::shared_ptr ofstreamPtr; - typedef boost::shared_ptr ifstreamPtr; - typedef boost::shared_ptr localePtr; +typedef boost::shared_ptr ofstreamPtr; +typedef boost::shared_ptr ifstreamPtr; +typedef boost::shared_ptr localePtr; } #include "LuceneFactory.h" @@ -81,140 +82,131 @@ namespace Lucene #include "HashSet.h" #include "Constants.h" -namespace Lucene -{ - typedef Array ByteArray; - typedef Array IntArray; - typedef Array LongArray; - typedef Array CharArray; - typedef Array DoubleArray; - - template - struct luceneEquals - { - inline bool operator()(const TYPE& first, const TYPE& second) const - { - return first ? first->equals(second) : (!first && !second); - } - }; - - template - struct luceneEqualTo - { - luceneEqualTo(const TYPE& type) : equalType(type) {} - inline bool operator()(const TYPE& other) const - { - return equalType->equals(other); - } - const TYPE& equalType; - }; - - template - struct luceneWeakEquals - { - inline bool operator()(const TYPE& first, const TYPE& second) const - { - if (first.expired() || second.expired()) - return (first.expired() && second.expired()); - return first.lock()->equals(second.lock()); - } - }; - - template - struct luceneHash : std::unary_function - { - std::size_t operator()(const TYPE& type) const - { - return type ? type->hashCode() : 0; +namespace Lucene { + +typedef Array ByteArray; +typedef Array IntArray; +typedef Array LongArray; +typedef Array CharArray; +typedef Array DoubleArray; + +template +struct luceneEquals { + inline bool operator()(const TYPE& first, const TYPE& second) const { + return first ? first->equals(second) : (!first && !second); + } +}; + +template +struct luceneEqualTo { + luceneEqualTo(const TYPE& type) : equalType(type) {} + inline bool operator()(const TYPE& other) const { + return equalType->equals(other); + } + const TYPE& equalType; +}; + +template +struct luceneWeakEquals { + inline bool operator()(const TYPE& first, const TYPE& second) const { + if (first.expired() || second.expired()) { + return (first.expired() && second.expired()); } - }; - - template - struct luceneWeakHash : std::unary_function - { - std::size_t operator()(const TYPE& type) const - { - return type.expired() ? 0 : type.lock()->hashCode(); + return first.lock()->equals(second.lock()); + } +}; + +template +struct luceneHash : std::unary_function { + std::size_t operator()(const TYPE& type) const { + return type ? type->hashCode() : 0; + } +}; + +template +struct luceneWeakHash : std::unary_function { + std::size_t operator()(const TYPE& type) const { + return type.expired() ? 0 : type.lock()->hashCode(); + } +}; + +template +struct luceneCompare { + inline bool operator()(const TYPE& first, const TYPE& second) const { + if (!second) { + return false; } - }; - - template - struct luceneCompare - { - inline bool operator()(const TYPE& first, const TYPE& second) const - { - if (!second) - return false; - if (!first) - return true; - return (first->compareTo(second) < 0); + if (!first) { + return true; } - }; - - typedef boost::blank VariantNull; - typedef boost::variant FieldsData; - typedef boost::variant ComparableValue; - typedef boost::variant NumericValue; - typedef boost::variant StringValue; - typedef boost::variant, Collection, Collection, VariantNull> CollectionValue; - - typedef HashSet< SegmentInfoPtr, luceneHash, luceneEquals > SetSegmentInfo; - typedef HashSet< MergeThreadPtr, luceneHash, luceneEquals > SetMergeThread; - typedef HashSet< OneMergePtr, luceneHash, luceneEquals > SetOneMerge; - typedef HashSet< QueryPtr, luceneHash, luceneEquals > SetQuery; - typedef HashSet< TermPtr, luceneHash, luceneEquals > SetTerm; - typedef HashSet< BooleanClausePtr, luceneHash, luceneEquals > SetBooleanClause; - typedef HashSet< ReaderFieldPtr, luceneHash, luceneEquals > SetReaderField; - typedef HashSet SetByteArray; - - typedef HashMap< String, String > MapStringString; - typedef HashMap< wchar_t, NormalizeCharMapPtr > MapCharNormalizeCharMap; - typedef HashMap< String, AnalyzerPtr > MapStringAnalyzer; - typedef HashMap< String, ByteArray > MapStringByteArray; - typedef HashMap< String, int32_t > MapStringInt; - typedef HashMap< String, FieldInfoPtr > MapStringFieldInfo; - typedef HashMap< String, Collection > MapStringCollectionTermVectorEntry; - typedef HashMap< String, RefCountPtr > MapStringRefCount; - typedef HashMap< int32_t, TermVectorsPositionInfoPtr > MapIntTermVectorsPositionInfo; - typedef HashMap< String, MapIntTermVectorsPositionInfo > MapStringMapIntTermVectorsPositionInfo; - typedef HashMap< String, NormPtr > MapStringNorm; - typedef HashMap< String, TermVectorEntryPtr > MapStringTermVectorEntry; - typedef HashMap< String, RAMFilePtr > MapStringRAMFile; - typedef HashMap< int32_t, ByteArray > MapIntByteArray; - typedef HashMap< int32_t, FilterItemPtr > MapIntFilterItem; - typedef HashMap< int32_t, double > MapIntDouble; - typedef HashMap< int64_t, int32_t > MapLongInt; - typedef HashMap< String, double > MapStringDouble; - typedef HashMap< int32_t, CachePtr > MapStringCache; - typedef HashMap< String, LockPtr > MapStringLock; - - typedef HashMap< SegmentInfoPtr, SegmentReaderPtr, luceneHash, luceneEquals > MapSegmentInfoSegmentReader; - typedef HashMap< SegmentInfoPtr, int32_t, luceneHash, luceneEquals > MapSegmentInfoInt; - typedef HashMap< DocFieldConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField; - typedef HashMap< InvertedDocConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField; - typedef HashMap< InvertedDocEndConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField; - typedef HashMap< TermsHashConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField; - typedef HashMap< FieldInfoPtr, Collection, luceneHash, luceneEquals > MapFieldInfoCollectionNormsWriterPerField; - typedef HashMap< IndexReaderPtr, HashSet, luceneHash, luceneEquals > MapIndexReaderSetString; - typedef HashMap< TermPtr, int32_t, luceneHash, luceneEquals > MapTermInt; - typedef HashMap< QueryPtr, int32_t, luceneHash, luceneEquals > MapQueryInt; - typedef HashMap< EntryPtr, boost::any, luceneHash, luceneEquals > MapEntryAny; - typedef HashMap< PhrasePositionsPtr, LuceneObjectPtr, luceneHash, luceneEquals > MapPhrasePositionsLuceneObject; - typedef HashMap< ReaderFieldPtr, SetReaderField, luceneHash, luceneEquals > MapReaderFieldSetReaderField; - - typedef WeakHashMap< LuceneObjectWeakPtr, LuceneObjectPtr, luceneWeakHash, luceneWeakEquals > WeakMapObjectObject; - typedef WeakHashMap< LuceneObjectWeakPtr, MapEntryAny, luceneWeakHash, luceneWeakEquals > WeakMapLuceneObjectMapEntryAny; - - typedef Map< String, AttributePtr > MapStringAttribute; - typedef Map< int64_t, DocumentsWriterThreadStatePtr > MapThreadDocumentsWriterThreadState; - typedef Map< String, IndexReaderPtr > MapStringIndexReader; - typedef Map< TermPtr, NumPtr, luceneCompare > MapTermNum; - - typedef boost::function TermVectorEntryComparator; - - template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > class SimpleLRUCache; - typedef SimpleLRUCache< TermPtr, TermInfoPtr, luceneHash, luceneEquals > TermInfoCache; - typedef boost::shared_ptr TermInfoCachePtr; + return (first->compareTo(second) < 0); + } +}; + +typedef boost::blank VariantNull; +typedef boost::variant FieldsData; +typedef boost::variant ComparableValue; +typedef boost::variant NumericValue; +typedef boost::variant StringValue; +typedef boost::variant, Collection, Collection, VariantNull> CollectionValue; + +typedef HashSet< SegmentInfoPtr, luceneHash, luceneEquals > SetSegmentInfo; +typedef HashSet< MergeThreadPtr, luceneHash, luceneEquals > SetMergeThread; +typedef HashSet< OneMergePtr, luceneHash, luceneEquals > SetOneMerge; +typedef HashSet< QueryPtr, luceneHash, luceneEquals > SetQuery; +typedef HashSet< TermPtr, luceneHash, luceneEquals > SetTerm; +typedef HashSet< BooleanClausePtr, luceneHash, luceneEquals > SetBooleanClause; +typedef HashSet< ReaderFieldPtr, luceneHash, luceneEquals > SetReaderField; +typedef HashSet SetByteArray; + +typedef HashMap< String, String > MapStringString; +typedef HashMap< wchar_t, NormalizeCharMapPtr > MapCharNormalizeCharMap; +typedef HashMap< String, AnalyzerPtr > MapStringAnalyzer; +typedef HashMap< String, ByteArray > MapStringByteArray; +typedef HashMap< String, int32_t > MapStringInt; +typedef HashMap< String, FieldInfoPtr > MapStringFieldInfo; +typedef HashMap< String, Collection > MapStringCollectionTermVectorEntry; +typedef HashMap< String, RefCountPtr > MapStringRefCount; +typedef HashMap< int32_t, TermVectorsPositionInfoPtr > MapIntTermVectorsPositionInfo; +typedef HashMap< String, MapIntTermVectorsPositionInfo > MapStringMapIntTermVectorsPositionInfo; +typedef HashMap< String, NormPtr > MapStringNorm; +typedef HashMap< String, TermVectorEntryPtr > MapStringTermVectorEntry; +typedef HashMap< String, RAMFilePtr > MapStringRAMFile; +typedef HashMap< int32_t, ByteArray > MapIntByteArray; +typedef HashMap< int32_t, FilterItemPtr > MapIntFilterItem; +typedef HashMap< int32_t, double > MapIntDouble; +typedef HashMap< int64_t, int32_t > MapLongInt; +typedef HashMap< String, double > MapStringDouble; +typedef HashMap< int32_t, CachePtr > MapStringCache; +typedef HashMap< String, LockPtr > MapStringLock; + +typedef HashMap< SegmentInfoPtr, SegmentReaderPtr, luceneHash, luceneEquals > MapSegmentInfoSegmentReader; +typedef HashMap< SegmentInfoPtr, int32_t, luceneHash, luceneEquals > MapSegmentInfoInt; +typedef HashMap< DocFieldConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField; +typedef HashMap< InvertedDocConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField; +typedef HashMap< InvertedDocEndConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField; +typedef HashMap< TermsHashConsumerPerThreadPtr, Collection, luceneHash, luceneEquals > MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField; +typedef HashMap< FieldInfoPtr, Collection, luceneHash, luceneEquals > MapFieldInfoCollectionNormsWriterPerField; +typedef HashMap< IndexReaderPtr, HashSet, luceneHash, luceneEquals > MapIndexReaderSetString; +typedef HashMap< TermPtr, int32_t, luceneHash, luceneEquals > MapTermInt; +typedef HashMap< QueryPtr, int32_t, luceneHash, luceneEquals > MapQueryInt; +typedef HashMap< EntryPtr, boost::any, luceneHash, luceneEquals > MapEntryAny; +typedef HashMap< PhrasePositionsPtr, LuceneObjectPtr, luceneHash, luceneEquals > MapPhrasePositionsLuceneObject; +typedef HashMap< ReaderFieldPtr, SetReaderField, luceneHash, luceneEquals > MapReaderFieldSetReaderField; + +typedef WeakHashMap< LuceneObjectWeakPtr, LuceneObjectPtr, luceneWeakHash, luceneWeakEquals > WeakMapObjectObject; +typedef WeakHashMap< LuceneObjectWeakPtr, MapEntryAny, luceneWeakHash, luceneWeakEquals > WeakMapLuceneObjectMapEntryAny; + +typedef Map< String, AttributePtr > MapStringAttribute; +typedef Map< int64_t, DocumentsWriterThreadStatePtr > MapThreadDocumentsWriterThreadState; +typedef Map< String, IndexReaderPtr > MapStringIndexReader; +typedef Map< TermPtr, NumPtr, luceneCompare > MapTermNum; + +typedef boost::function TermVectorEntryComparator; + +template < class KEY, class VALUE, class HASH = boost::hash, class EQUAL = std::equal_to > class SimpleLRUCache; +typedef SimpleLRUCache< TermPtr, TermInfoPtr, luceneHash, luceneEquals > TermInfoCache; +typedef boost::shared_ptr TermInfoCachePtr; } #include "Synchronize.h" diff --git a/include/LuceneAllocator.h b/include/LuceneAllocator.h index c78ac7d6..b1436e12 100644 --- a/include/LuceneAllocator.h +++ b/include/LuceneAllocator.h @@ -9,16 +9,16 @@ #include "Config.h" -namespace Lucene -{ - /// Allocate block of memory. - LPPAPI void* AllocMemory(size_t size); +namespace Lucene { - /// Reallocate a given block of memory. - LPPAPI void* ReallocMemory(void* memory, size_t size); +/// Allocate block of memory. +LPPAPI void* AllocMemory(size_t size); - /// Release a given block of memory. - LPPAPI void FreeMemory(void* memory); +/// Reallocate a given block of memory. +LPPAPI void* ReallocMemory(void* memory, size_t size); + +/// Release a given block of memory. +LPPAPI void FreeMemory(void* memory); } #endif diff --git a/include/LuceneException.h b/include/LuceneException.h index 00a55f23..91d09b07 100644 --- a/include/LuceneException.h +++ b/include/LuceneException.h @@ -9,94 +9,90 @@ #include "Lucene.h" -namespace Lucene -{ - /// Lucene exception container. - class LPPAPI LuceneException : public std::exception - { - public: - enum ExceptionType - { - Null, - AlreadyClosed, - Compression, - CorruptIndex, - FieldReader, - FileNotFound, - IllegalArgument, - IllegalState, - IndexOutOfBounds, - IO, - LockObtainFailed, - LockReleaseFailed, - Lookahead, - MergeAborted, - Merge, - NoSuchDirectory, - NullPointer, - NumberFormat, - OutOfMemory, - Parse, - QueryParser, - Runtime, - StaleReader, - StopFillCache, - Temporary, - TimeExceeded, - TooManyClauses, - UnsupportedOperation - }; +namespace Lucene { - LuceneException(const String& error = EmptyString, LuceneException::ExceptionType type = Null) throw(); - ~LuceneException() throw(); +/// Lucene exception container. +class LPPAPI LuceneException : public std::exception { +public: + enum ExceptionType { + Null, + AlreadyClosed, + Compression, + CorruptIndex, + FieldReader, + FileNotFound, + IllegalArgument, + IllegalState, + IndexOutOfBounds, + IO, + LockObtainFailed, + LockReleaseFailed, + Lookahead, + MergeAborted, + Merge, + NoSuchDirectory, + NullPointer, + NumberFormat, + OutOfMemory, + Parse, + QueryParser, + Runtime, + StaleReader, + StopFillCache, + Temporary, + TimeExceeded, + TooManyClauses, + UnsupportedOperation + }; - protected: - ExceptionType type; - String error; + LuceneException(const String& error = EmptyString, LuceneException::ExceptionType type = Null) throw(); + ~LuceneException() throw(); - public: - ExceptionType getType() const; - String getError() const; - bool isNull() const; - void throwException(); - }; +protected: + ExceptionType type; + String error; - template - class ExceptionTemplate : public ParentException - { - public: - ExceptionTemplate(const String& error = EmptyString, LuceneException::ExceptionType type = Type) : ParentException(error, type) - { - } - }; +public: + ExceptionType getType() const; + String getError() const; + bool isNull() const; + void throwException(); +}; + +template +class ExceptionTemplate : public ParentException { +public: + ExceptionTemplate(const String& error = EmptyString, LuceneException::ExceptionType type = Type) : ParentException(error, type) { + } +}; - typedef ExceptionTemplate RuntimeException; - typedef ExceptionTemplate OutOfMemoryError; - typedef ExceptionTemplate TemporaryException; - typedef ExceptionTemplate IllegalStateException; - typedef ExceptionTemplate IllegalArgumentException; - typedef ExceptionTemplate IndexOutOfBoundsException; - typedef ExceptionTemplate NullPointerException; - typedef ExceptionTemplate FieldReaderException; - typedef ExceptionTemplate MergeException; - typedef ExceptionTemplate StopFillCacheException; - typedef ExceptionTemplate TimeExceededException; - typedef ExceptionTemplate TooManyClausesException; - typedef ExceptionTemplate UnsupportedOperationException; - typedef ExceptionTemplate NumberFormatException; - typedef ExceptionTemplate AlreadyClosedException; - typedef ExceptionTemplate IOException; - typedef ExceptionTemplate CorruptIndexException; - typedef ExceptionTemplate FileNotFoundException; - typedef ExceptionTemplate LockObtainFailedException; - typedef ExceptionTemplate LockReleaseFailedException; - typedef ExceptionTemplate MergeAbortedException; - typedef ExceptionTemplate StaleReaderException; - typedef ExceptionTemplate NoSuchDirectoryException; - typedef ExceptionTemplate LookaheadSuccess; - typedef ExceptionTemplate ParseException; - typedef ExceptionTemplate QueryParserError; - typedef ExceptionTemplate CompressionException; +typedef ExceptionTemplate RuntimeException; +typedef ExceptionTemplate OutOfMemoryError; +typedef ExceptionTemplate TemporaryException; +typedef ExceptionTemplate IllegalStateException; +typedef ExceptionTemplate IllegalArgumentException; +typedef ExceptionTemplate IndexOutOfBoundsException; +typedef ExceptionTemplate NullPointerException; +typedef ExceptionTemplate FieldReaderException; +typedef ExceptionTemplate MergeException; +typedef ExceptionTemplate StopFillCacheException; +typedef ExceptionTemplate TimeExceededException; +typedef ExceptionTemplate TooManyClausesException; +typedef ExceptionTemplate UnsupportedOperationException; +typedef ExceptionTemplate NumberFormatException; +typedef ExceptionTemplate AlreadyClosedException; +typedef ExceptionTemplate IOException; +typedef ExceptionTemplate CorruptIndexException; +typedef ExceptionTemplate FileNotFoundException; +typedef ExceptionTemplate LockObtainFailedException; +typedef ExceptionTemplate LockReleaseFailedException; +typedef ExceptionTemplate MergeAbortedException; +typedef ExceptionTemplate StaleReaderException; +typedef ExceptionTemplate NoSuchDirectoryException; +typedef ExceptionTemplate LookaheadSuccess; +typedef ExceptionTemplate ParseException; +typedef ExceptionTemplate QueryParserError; +typedef ExceptionTemplate CompressionException; } #endif diff --git a/include/LuceneFactory.h b/include/LuceneFactory.h index 993ebe9f..b6a56264 100644 --- a/include/LuceneFactory.h +++ b/include/LuceneFactory.h @@ -10,187 +10,168 @@ #include #include -namespace Lucene -{ - template - boost::shared_ptr newInstance() - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T); - #else - return boost::make_shared(); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1)); - #else - return boost::make_shared(a1); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2)); - #else - return boost::make_shared(a1, a2); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2, a3)); - #else - return boost::make_shared(a1, a2, a3); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2, a3, a4)); - #else - return boost::make_shared(a1, a2, a3, a4); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2, a3, a4, a5)); - #else - return boost::make_shared(a1, a2, a3, a4, a5); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6)); - #else - return boost::make_shared(a1, a2, a3, a4, a5, a6); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7)); - #else - return boost::make_shared(a1, a2, a3, a4, a5, a6, a7); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8)); - #else - return boost::make_shared(a1, a2, a3, a4, a5, a6, a7, a8); - #endif - } - - template - boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) - { - #if BOOST_VERSION <= 103800 - return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9)); - #else - return boost::make_shared(a1, a2, a3, a4, a5, a6, a7, a8, a9); - #endif - } - - template - boost::shared_ptr newLucene() - { - boost::shared_ptr instance(newInstance()); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1) - { - boost::shared_ptr instance(newInstance(a1)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2) - { - boost::shared_ptr instance(newInstance(a1, a2)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3) - { - boost::shared_ptr instance(newInstance(a1, a2, a3)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) - { - boost::shared_ptr instance(newInstance(a1, a2, a3, a4)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) - { - boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) - { - boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) - { - boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6, a7)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) - { - boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6, a7, a8)); - instance->initialize(); - return instance; - } - - template - boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) - { - boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6, a7, a8, a9)); - instance->initialize(); - return instance; - } +namespace Lucene { + +template +boost::shared_ptr newInstance() { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T); +#else + return boost::make_shared(); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1)); +#else + return boost::make_shared(a1); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2)); +#else + return boost::make_shared(a1, a2); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2, a3)); +#else + return boost::make_shared(a1, a2, a3); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2, a3, a4)); +#else + return boost::make_shared(a1, a2, a3, a4); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2, a3, a4, a5)); +#else + return boost::make_shared(a1, a2, a3, a4, a5); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6)); +#else + return boost::make_shared(a1, a2, a3, a4, a5, a6); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7)); +#else + return boost::make_shared(a1, a2, a3, a4, a5, a6, a7); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8)); +#else + return boost::make_shared(a1, a2, a3, a4, a5, a6, a7, a8); +#endif +} + +template +boost::shared_ptr newInstance(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) { +#if BOOST_VERSION <= 103800 + return boost::shared_ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +#else + return boost::make_shared(a1, a2, a3, a4, a5, a6, a7, a8, a9); +#endif +} + +template +boost::shared_ptr newLucene() { + boost::shared_ptr instance(newInstance()); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1) { + boost::shared_ptr instance(newInstance(a1)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2) { + boost::shared_ptr instance(newInstance(a1, a2)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3) { + boost::shared_ptr instance(newInstance(a1, a2, a3)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) { + boost::shared_ptr instance(newInstance(a1, a2, a3, a4)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) { + boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) { + boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) { + boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6, a7)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) { + boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6, a7, a8)); + instance->initialize(); + return instance; +} + +template +boost::shared_ptr newLucene(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) { + boost::shared_ptr instance(newInstance(a1, a2, a3, a4, a5, a6, a7, a8, a9)); + instance->initialize(); + return instance; +} + } #endif diff --git a/include/LuceneObject.h b/include/LuceneObject.h index 44ce17a9..54363dbd 100644 --- a/include/LuceneObject.h +++ b/include/LuceneObject.h @@ -25,38 +25,38 @@ LUCENE_INTERFACE(Name); \ boost::shared_ptr shared_from_this() { return boost::static_pointer_cast(LuceneObject::shared_from_this()); } \ -namespace Lucene -{ - /// Base class for all Lucene classes - class LPPAPI LuceneObject : public LuceneSync, public boost::enable_shared_from_this - { - public: - virtual ~LuceneObject(); - - protected: - LuceneObject(); - - public: - /// Called directly after instantiation to create objects that depend on this object being - /// fully constructed. - virtual void initialize(); - - /// Return clone of this object - /// @param other clone reference - null when called initially, then set in top virtual override. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - /// Return hash code for this object. - virtual int32_t hashCode(); - - /// Return whether two objects are equal - virtual bool equals(const LuceneObjectPtr& other); - - /// Compare two objects - virtual int32_t compareTo(const LuceneObjectPtr& other); - - /// Returns a string representation of the object - virtual String toString(); - }; +namespace Lucene { + +/// Base class for all Lucene classes +class LPPAPI LuceneObject : public LuceneSync, public boost::enable_shared_from_this { +public: + virtual ~LuceneObject(); + +protected: + LuceneObject(); + +public: + /// Called directly after instantiation to create objects that depend on this object being + /// fully constructed. + virtual void initialize(); + + /// Return clone of this object + /// @param other clone reference - null when called initially, then set in top virtual override. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Return hash code for this object. + virtual int32_t hashCode(); + + /// Return whether two objects are equal + virtual bool equals(const LuceneObjectPtr& other); + + /// Compare two objects + virtual int32_t compareTo(const LuceneObjectPtr& other); + + /// Returns a string representation of the object + virtual String toString(); +}; + } #endif diff --git a/include/LuceneSignal.h b/include/LuceneSignal.h index bf52590d..c809a6be 100644 --- a/include/LuceneSignal.h +++ b/include/LuceneSignal.h @@ -10,31 +10,30 @@ #include #include "Lucene.h" -namespace Lucene -{ - /// Utility class to support signaling notifications. - class LPPAPI LuceneSignal - { - public: - LuceneSignal(const SynchronizePtr& objectLock = SynchronizePtr()); - virtual ~LuceneSignal(); - - protected: - boost::mutex waitMutex; - boost::condition signalCondition; - SynchronizePtr objectLock; - - public: - /// create a new LuceneSignal instance atomically. - static void createSignal(LuceneSignalPtr& signal, const SynchronizePtr& objectLock); - - /// Wait for signal using an optional timeout. - void wait(int32_t timeout = 0); - - /// Notify all threads waiting for signal. - void notifyAll(); - }; -} +namespace Lucene { + +/// Utility class to support signaling notifications. +class LPPAPI LuceneSignal { +public: + LuceneSignal(const SynchronizePtr& objectLock = SynchronizePtr()); + virtual ~LuceneSignal(); + +protected: + boost::mutex waitMutex; + boost::condition signalCondition; + SynchronizePtr objectLock; + +public: + /// create a new LuceneSignal instance atomically. + static void createSignal(LuceneSignalPtr& signal, const SynchronizePtr& objectLock); + /// Wait for signal using an optional timeout. + void wait(int32_t timeout = 0); + + /// Notify all threads waiting for signal. + void notifyAll(); +}; + +} #endif diff --git a/include/LuceneSync.h b/include/LuceneSync.h index 4bb2e12e..4325e8d9 100644 --- a/include/LuceneSync.h +++ b/include/LuceneSync.h @@ -9,40 +9,40 @@ #include "Lucene.h" -namespace Lucene -{ - /// Base class for all Lucene synchronised classes - class LPPAPI LuceneSync - { - public: - virtual ~LuceneSync(); +namespace Lucene { - protected: - SynchronizePtr objectLock; - LuceneSignalPtr objectSignal; +/// Base class for all Lucene synchronised classes +class LPPAPI LuceneSync { +public: + virtual ~LuceneSync(); - public: - /// Return this object synchronize lock. - virtual SynchronizePtr getSync(); +protected: + SynchronizePtr objectLock; + LuceneSignalPtr objectSignal; - /// Return this object signal. - virtual LuceneSignalPtr getSignal(); +public: + /// Return this object synchronize lock. + virtual SynchronizePtr getSync(); - /// Lock this object using an optional timeout. - virtual void lock(int32_t timeout = 0); + /// Return this object signal. + virtual LuceneSignalPtr getSignal(); - /// Unlock this object. - virtual void unlock(); + /// Lock this object using an optional timeout. + virtual void lock(int32_t timeout = 0); - /// Returns true if this object is currently locked by current thread. - virtual bool holdsLock(); + /// Unlock this object. + virtual void unlock(); - /// Wait for signal using an optional timeout. - virtual void wait(int32_t timeout = 0); + /// Returns true if this object is currently locked by current thread. + virtual bool holdsLock(); + + /// Wait for signal using an optional timeout. + virtual void wait(int32_t timeout = 0); + + /// Notify all threads waiting for signal. + virtual void notifyAll(); +}; - /// Notify all threads waiting for signal. - virtual void notifyAll(); - }; } #endif diff --git a/include/LuceneThread.h b/include/LuceneThread.h index b7e92364..8f99bc93 100644 --- a/include/LuceneThread.h +++ b/include/LuceneThread.h @@ -9,78 +9,78 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Lucene thread container. - /// - /// It seems there are major issues with using boost::thread::id under Windows. - /// After many hours of debugging and trying various strategies, I was unable to fix an - /// occasional crash whereby boost::thread::thread_data was being deleted prematurely. - /// - /// This problem is most visible when running the AtomicUpdateTest test suite. - /// - /// Therefore, I now uniquely identify threads by their native id. - class LPPAPI LuceneThread : public LuceneObject - { - public: - LuceneThread(); - virtual ~LuceneThread(); - - LUCENE_CLASS(LuceneThread); - - public: - static const int32_t MAX_PRIORITY; - static const int32_t NORM_PRIORITY; - static const int32_t MIN_PRIORITY; - - protected: - threadPtr thread; - - /// Flag to indicate running thread. - /// @see #isAlive - bool running; - - public: - /// start thread see {@link #run}. - virtual void start(); - - /// return whether thread is current running. - virtual bool isAlive(); - - /// set running thread priority. - virtual void setPriority(int32_t priority); - - /// return running thread priority. - virtual int32_t getPriority(); - - /// wait for thread to finish using an optional timeout. - virtual bool join(int32_t timeout = 0); - - /// causes the currently executing thread object to temporarily pause and allow other threads to execute. - virtual void yield(); - - /// override to provide the body of the thread. - virtual void run() = 0; - - /// Return representation of current execution thread. - static int64_t currentId(); - - /// Suspends current execution thread for a given time. - static void threadSleep(int32_t time); - - /// Yield current execution thread. - static void threadYield(); - - protected: - /// set thread running state. - void setRunning(bool running); - - /// return thread running state. - bool isRunning(); - - /// function that controls the lifetime of the running thread. - static void runThread(LuceneThread* thread); - }; +namespace Lucene { + +/// Lucene thread container. +/// +/// It seems there are major issues with using boost::thread::id under Windows. +/// After many hours of debugging and trying various strategies, I was unable to fix an +/// occasional crash whereby boost::thread::thread_data was being deleted prematurely. +/// +/// This problem is most visible when running the AtomicUpdateTest test suite. +/// +/// Therefore, I now uniquely identify threads by their native id. +class LPPAPI LuceneThread : public LuceneObject { +public: + LuceneThread(); + virtual ~LuceneThread(); + + LUCENE_CLASS(LuceneThread); + +public: + static const int32_t MAX_PRIORITY; + static const int32_t NORM_PRIORITY; + static const int32_t MIN_PRIORITY; + +protected: + threadPtr thread; + + /// Flag to indicate running thread. + /// @see #isAlive + bool running; + +public: + /// start thread see {@link #run}. + virtual void start(); + + /// return whether thread is current running. + virtual bool isAlive(); + + /// set running thread priority. + virtual void setPriority(int32_t priority); + + /// return running thread priority. + virtual int32_t getPriority(); + + /// wait for thread to finish using an optional timeout. + virtual bool join(int32_t timeout = 0); + + /// causes the currently executing thread object to temporarily pause and allow other threads to execute. + virtual void yield(); + + /// override to provide the body of the thread. + virtual void run() = 0; + + /// Return representation of current execution thread. + static int64_t currentId(); + + /// Suspends current execution thread for a given time. + static void threadSleep(int32_t time); + + /// Yield current execution thread. + static void threadYield(); + +protected: + /// set thread running state. + void setRunning(bool running); + + /// return thread running state. + bool isRunning(); + + /// function that controls the lifetime of the running thread. + static void runThread(LuceneThread* thread); +}; + } #endif diff --git a/include/LuceneTypes.h b/include/LuceneTypes.h index 75a9563b..2a1f03e0 100644 --- a/include/LuceneTypes.h +++ b/include/LuceneTypes.h @@ -14,550 +14,550 @@ typedef boost::shared_ptr Type##Ptr; \ typedef boost::weak_ptr Type##WeakPtr; -namespace Lucene -{ - // analysis - DECLARE_SHARED_PTR(Analyzer) - DECLARE_SHARED_PTR(ASCIIFoldingFilter) - DECLARE_SHARED_PTR(BaseCharFilter) - DECLARE_SHARED_PTR(CachingTokenFilter) - DECLARE_SHARED_PTR(CharArraySet) - DECLARE_SHARED_PTR(CharFilter) - DECLARE_SHARED_PTR(CharReader) - DECLARE_SHARED_PTR(CharStream) - DECLARE_SHARED_PTR(CharTokenizer) - DECLARE_SHARED_PTR(FlagsAttribute) - DECLARE_SHARED_PTR(ISOLatin1AccentFilter) - DECLARE_SHARED_PTR(KeywordAnalyzer) - DECLARE_SHARED_PTR(KeywordTokenizer) - DECLARE_SHARED_PTR(LengthFilter) - DECLARE_SHARED_PTR(LetterTokenizer) - DECLARE_SHARED_PTR(LowerCaseFilter) - DECLARE_SHARED_PTR(LowerCaseTokenizer) - DECLARE_SHARED_PTR(MappingCharFilter) - DECLARE_SHARED_PTR(NormalizeCharMap) - DECLARE_SHARED_PTR(NumericTokenStream) - DECLARE_SHARED_PTR(OffsetAttribute) - DECLARE_SHARED_PTR(PayloadAttribute) - DECLARE_SHARED_PTR(PerFieldAnalyzerWrapper) - DECLARE_SHARED_PTR(PorterStemFilter) - DECLARE_SHARED_PTR(PorterStemmer) - DECLARE_SHARED_PTR(PositionIncrementAttribute) - DECLARE_SHARED_PTR(SimpleAnalyzer) - DECLARE_SHARED_PTR(SinkFilter) - DECLARE_SHARED_PTR(SinkTokenStream) - DECLARE_SHARED_PTR(StandardAnalyzer) - DECLARE_SHARED_PTR(StandardAnalyzerSavedStreams) - DECLARE_SHARED_PTR(StandardFilter) - DECLARE_SHARED_PTR(StandardTokenizer) - DECLARE_SHARED_PTR(StandardTokenizerImpl) - DECLARE_SHARED_PTR(StopAnalyzer) - DECLARE_SHARED_PTR(StopAnalyzerSavedStreams) - DECLARE_SHARED_PTR(StopFilter) - DECLARE_SHARED_PTR(TeeSinkTokenFilter) - DECLARE_SHARED_PTR(TermAttribute) - DECLARE_SHARED_PTR(Token) - DECLARE_SHARED_PTR(TokenAttributeFactory) - DECLARE_SHARED_PTR(TokenFilter) - DECLARE_SHARED_PTR(Tokenizer) - DECLARE_SHARED_PTR(TokenStream) - DECLARE_SHARED_PTR(TypeAttribute) - DECLARE_SHARED_PTR(WhitespaceAnalyzer) - DECLARE_SHARED_PTR(WhitespaceTokenizer) - DECLARE_SHARED_PTR(WordlistLoader) +namespace Lucene { - // document - DECLARE_SHARED_PTR(AbstractField) - DECLARE_SHARED_PTR(CompressionTools) - DECLARE_SHARED_PTR(DateField) - DECLARE_SHARED_PTR(DateTools) - DECLARE_SHARED_PTR(Document) - DECLARE_SHARED_PTR(Field) - DECLARE_SHARED_PTR(Fieldable) - DECLARE_SHARED_PTR(FieldSelector) - DECLARE_SHARED_PTR(LoadFirstFieldSelector) - DECLARE_SHARED_PTR(MapFieldSelector) - DECLARE_SHARED_PTR(NumberTools) - DECLARE_SHARED_PTR(NumericField) - DECLARE_SHARED_PTR(SetBasedFieldSelector) +// analysis +DECLARE_SHARED_PTR(Analyzer) +DECLARE_SHARED_PTR(ASCIIFoldingFilter) +DECLARE_SHARED_PTR(BaseCharFilter) +DECLARE_SHARED_PTR(CachingTokenFilter) +DECLARE_SHARED_PTR(CharArraySet) +DECLARE_SHARED_PTR(CharFilter) +DECLARE_SHARED_PTR(CharReader) +DECLARE_SHARED_PTR(CharStream) +DECLARE_SHARED_PTR(CharTokenizer) +DECLARE_SHARED_PTR(FlagsAttribute) +DECLARE_SHARED_PTR(ISOLatin1AccentFilter) +DECLARE_SHARED_PTR(KeywordAnalyzer) +DECLARE_SHARED_PTR(KeywordTokenizer) +DECLARE_SHARED_PTR(LengthFilter) +DECLARE_SHARED_PTR(LetterTokenizer) +DECLARE_SHARED_PTR(LowerCaseFilter) +DECLARE_SHARED_PTR(LowerCaseTokenizer) +DECLARE_SHARED_PTR(MappingCharFilter) +DECLARE_SHARED_PTR(NormalizeCharMap) +DECLARE_SHARED_PTR(NumericTokenStream) +DECLARE_SHARED_PTR(OffsetAttribute) +DECLARE_SHARED_PTR(PayloadAttribute) +DECLARE_SHARED_PTR(PerFieldAnalyzerWrapper) +DECLARE_SHARED_PTR(PorterStemFilter) +DECLARE_SHARED_PTR(PorterStemmer) +DECLARE_SHARED_PTR(PositionIncrementAttribute) +DECLARE_SHARED_PTR(SimpleAnalyzer) +DECLARE_SHARED_PTR(SinkFilter) +DECLARE_SHARED_PTR(SinkTokenStream) +DECLARE_SHARED_PTR(StandardAnalyzer) +DECLARE_SHARED_PTR(StandardAnalyzerSavedStreams) +DECLARE_SHARED_PTR(StandardFilter) +DECLARE_SHARED_PTR(StandardTokenizer) +DECLARE_SHARED_PTR(StandardTokenizerImpl) +DECLARE_SHARED_PTR(StopAnalyzer) +DECLARE_SHARED_PTR(StopAnalyzerSavedStreams) +DECLARE_SHARED_PTR(StopFilter) +DECLARE_SHARED_PTR(TeeSinkTokenFilter) +DECLARE_SHARED_PTR(TermAttribute) +DECLARE_SHARED_PTR(Token) +DECLARE_SHARED_PTR(TokenAttributeFactory) +DECLARE_SHARED_PTR(TokenFilter) +DECLARE_SHARED_PTR(Tokenizer) +DECLARE_SHARED_PTR(TokenStream) +DECLARE_SHARED_PTR(TypeAttribute) +DECLARE_SHARED_PTR(WhitespaceAnalyzer) +DECLARE_SHARED_PTR(WhitespaceTokenizer) +DECLARE_SHARED_PTR(WordlistLoader) - // index - DECLARE_SHARED_PTR(AbstractAllTermDocs) - DECLARE_SHARED_PTR(AllTermDocs) - DECLARE_SHARED_PTR(BufferedDeletes) - DECLARE_SHARED_PTR(ByteBlockAllocator) - DECLARE_SHARED_PTR(ByteBlockPool) - DECLARE_SHARED_PTR(ByteBlockPoolAllocatorBase) - DECLARE_SHARED_PTR(ByteSliceReader) - DECLARE_SHARED_PTR(ByteSliceWriter) - DECLARE_SHARED_PTR(CharBlockPool) - DECLARE_SHARED_PTR(CheckAbort) - DECLARE_SHARED_PTR(CheckIndex) - DECLARE_SHARED_PTR(CommitPoint) - DECLARE_SHARED_PTR(CompoundFileReader) - DECLARE_SHARED_PTR(CompoundFileWriter) - DECLARE_SHARED_PTR(ConcurrentMergeScheduler) - DECLARE_SHARED_PTR(CoreReaders) - DECLARE_SHARED_PTR(CSIndexInput) - DECLARE_SHARED_PTR(DefaultIndexingChain) - DECLARE_SHARED_PTR(DefaultSkipListReader) - DECLARE_SHARED_PTR(DefaultSkipListWriter) - DECLARE_SHARED_PTR(DirectoryReader) - DECLARE_SHARED_PTR(DocConsumer) - DECLARE_SHARED_PTR(DocConsumerPerThread) - DECLARE_SHARED_PTR(DocFieldConsumer) - DECLARE_SHARED_PTR(DocFieldConsumerPerField) - DECLARE_SHARED_PTR(DocFieldConsumerPerThread) - DECLARE_SHARED_PTR(DocFieldConsumers) - DECLARE_SHARED_PTR(DocFieldConsumersPerDoc) - DECLARE_SHARED_PTR(DocFieldConsumersPerField) - DECLARE_SHARED_PTR(DocFieldConsumersPerThread) - DECLARE_SHARED_PTR(DocFieldProcessor) - DECLARE_SHARED_PTR(DocFieldProcessorPerField) - DECLARE_SHARED_PTR(DocFieldProcessorPerThread) - DECLARE_SHARED_PTR(DocFieldProcessorPerThreadPerDoc) - DECLARE_SHARED_PTR(DocInverter) - DECLARE_SHARED_PTR(DocInverterPerField) - DECLARE_SHARED_PTR(DocInverterPerThread) - DECLARE_SHARED_PTR(DocState) - DECLARE_SHARED_PTR(DocumentsWriter) - DECLARE_SHARED_PTR(DocumentsWriterThreadState) - DECLARE_SHARED_PTR(DocWriter) - DECLARE_SHARED_PTR(FieldInfo) - DECLARE_SHARED_PTR(FieldInfos) - DECLARE_SHARED_PTR(FieldInvertState) - DECLARE_SHARED_PTR(FieldNormStatus) - DECLARE_SHARED_PTR(FieldSortedTermVectorMapper) - DECLARE_SHARED_PTR(FieldsReader) - DECLARE_SHARED_PTR(FieldsReaderLocal) - DECLARE_SHARED_PTR(FieldsWriter) - DECLARE_SHARED_PTR(FilterIndexReader) - DECLARE_SHARED_PTR(FindSegmentsModified) - DECLARE_SHARED_PTR(FindSegmentsOpen) - DECLARE_SHARED_PTR(FindSegmentsRead) - DECLARE_SHARED_PTR(FindSegmentsReopen) - DECLARE_SHARED_PTR(FormatPostingsDocsConsumer) - DECLARE_SHARED_PTR(FormatPostingsDocsWriter) - DECLARE_SHARED_PTR(FormatPostingsFieldsConsumer) - DECLARE_SHARED_PTR(FormatPostingsFieldsWriter) - DECLARE_SHARED_PTR(FormatPostingsPositionsConsumer) - DECLARE_SHARED_PTR(FormatPostingsPositionsWriter) - DECLARE_SHARED_PTR(FormatPostingsTermsConsumer) - DECLARE_SHARED_PTR(FormatPostingsTermsWriter) - DECLARE_SHARED_PTR(FreqProxFieldMergeState) - DECLARE_SHARED_PTR(FreqProxTermsWriter) - DECLARE_SHARED_PTR(FreqProxTermsWriterPerField) - DECLARE_SHARED_PTR(FreqProxTermsWriterPerThread) - DECLARE_SHARED_PTR(FreqProxTermsWriterPostingList) - DECLARE_SHARED_PTR(IndexCommit) - DECLARE_SHARED_PTR(IndexDeletionPolicy) - DECLARE_SHARED_PTR(IndexFileDeleter) - DECLARE_SHARED_PTR(IndexFileNameFilter) - DECLARE_SHARED_PTR(IndexingChain) - DECLARE_SHARED_PTR(IndexReader) - DECLARE_SHARED_PTR(IndexReaderWarmer) - DECLARE_SHARED_PTR(IndexStatus) - DECLARE_SHARED_PTR(IndexWriter) - DECLARE_SHARED_PTR(IntBlockPool) - DECLARE_SHARED_PTR(IntQueue) - DECLARE_SHARED_PTR(InvertedDocConsumer) - DECLARE_SHARED_PTR(InvertedDocConsumerPerField) - DECLARE_SHARED_PTR(InvertedDocConsumerPerThread) - DECLARE_SHARED_PTR(InvertedDocEndConsumer) - DECLARE_SHARED_PTR(InvertedDocEndConsumerPerField) - DECLARE_SHARED_PTR(InvertedDocEndConsumerPerThread) - DECLARE_SHARED_PTR(KeepOnlyLastCommitDeletionPolicy) - DECLARE_SHARED_PTR(LogByteSizeMergePolicy) - DECLARE_SHARED_PTR(LogDocMergePolicy) - DECLARE_SHARED_PTR(LogMergePolicy) - DECLARE_SHARED_PTR(MergeDocIDRemapper) - DECLARE_SHARED_PTR(MergePolicy) - DECLARE_SHARED_PTR(MergeScheduler) - DECLARE_SHARED_PTR(MergeSpecification) - DECLARE_SHARED_PTR(MergeThread) - DECLARE_SHARED_PTR(MultiLevelSkipListReader) - DECLARE_SHARED_PTR(MultiLevelSkipListWriter) - DECLARE_SHARED_PTR(MultipleTermPositions) - DECLARE_SHARED_PTR(MultiReader) - DECLARE_SHARED_PTR(MultiTermDocs) - DECLARE_SHARED_PTR(MultiTermEnum) - DECLARE_SHARED_PTR(MultiTermPositions) - DECLARE_SHARED_PTR(MyCommitPoint) - DECLARE_SHARED_PTR(MySegmentTermDocs) - DECLARE_SHARED_PTR(Norm) - DECLARE_SHARED_PTR(NormsWriter) - DECLARE_SHARED_PTR(NormsWriterPerField) - DECLARE_SHARED_PTR(NormsWriterPerThread) - DECLARE_SHARED_PTR(Num) - DECLARE_SHARED_PTR(OneMerge) - DECLARE_SHARED_PTR(ParallelArrayTermVectorMapper) - DECLARE_SHARED_PTR(ParallelReader) - DECLARE_SHARED_PTR(ParallelTermEnum) - DECLARE_SHARED_PTR(ParallelTermDocs) - DECLARE_SHARED_PTR(ParallelTermPositions) - DECLARE_SHARED_PTR(Payload) - DECLARE_SHARED_PTR(PerDocBuffer) - DECLARE_SHARED_PTR(PositionBasedTermVectorMapper) - DECLARE_SHARED_PTR(RawPostingList) - DECLARE_SHARED_PTR(ReaderCommit) - DECLARE_SHARED_PTR(ReaderPool) - DECLARE_SHARED_PTR(ReadOnlyDirectoryReader) - DECLARE_SHARED_PTR(ReadOnlySegmentReader) - DECLARE_SHARED_PTR(RefCount) - DECLARE_SHARED_PTR(ReusableStringReader) - DECLARE_SHARED_PTR(SegmentInfo) - DECLARE_SHARED_PTR(SegmentInfoCollection) - DECLARE_SHARED_PTR(SegmentInfos) - DECLARE_SHARED_PTR(SegmentInfoStatus) - DECLARE_SHARED_PTR(SegmentMergeInfo) - DECLARE_SHARED_PTR(SegmentMergeQueue) - DECLARE_SHARED_PTR(SegmentMerger) - DECLARE_SHARED_PTR(SegmentReader) - DECLARE_SHARED_PTR(SegmentReaderRef) - DECLARE_SHARED_PTR(SegmentTermDocs) - DECLARE_SHARED_PTR(SegmentTermEnum) - DECLARE_SHARED_PTR(SegmentTermPositions) - DECLARE_SHARED_PTR(SegmentTermPositionVector) - DECLARE_SHARED_PTR(SegmentTermVector) - DECLARE_SHARED_PTR(SegmentWriteState) - DECLARE_SHARED_PTR(SerialMergeScheduler) - DECLARE_SHARED_PTR(SingleTokenAttributeSource) - DECLARE_SHARED_PTR(SkipBuffer) - DECLARE_SHARED_PTR(SkipDocWriter) - DECLARE_SHARED_PTR(SnapshotDeletionPolicy) - DECLARE_SHARED_PTR(SortedTermVectorMapper) - DECLARE_SHARED_PTR(StoredFieldStatus) - DECLARE_SHARED_PTR(StoredFieldsWriter) - DECLARE_SHARED_PTR(StoredFieldsWriterPerDoc) - DECLARE_SHARED_PTR(StoredFieldsWriterPerThread) - DECLARE_SHARED_PTR(Term) - DECLARE_SHARED_PTR(TermBuffer) - DECLARE_SHARED_PTR(TermEnum) - DECLARE_SHARED_PTR(TermDocs) - DECLARE_SHARED_PTR(TermFreqVector) - DECLARE_SHARED_PTR(TermIndexStatus) - DECLARE_SHARED_PTR(TermInfo) - DECLARE_SHARED_PTR(TermInfosReader) - DECLARE_SHARED_PTR(TermInfosReaderThreadResources) - DECLARE_SHARED_PTR(TermInfosWriter) - DECLARE_SHARED_PTR(TermPositions) - DECLARE_SHARED_PTR(TermPositionsQueue) - DECLARE_SHARED_PTR(TermPositionVector) - DECLARE_SHARED_PTR(TermsHash) - DECLARE_SHARED_PTR(TermsHashConsumer) - DECLARE_SHARED_PTR(TermsHashConsumerPerField) - DECLARE_SHARED_PTR(TermsHashConsumerPerThread) - DECLARE_SHARED_PTR(TermsHashPerField) - DECLARE_SHARED_PTR(TermsHashPerThread) - DECLARE_SHARED_PTR(TermVectorEntry) - DECLARE_SHARED_PTR(TermVectorEntryFreqSortedComparator) - DECLARE_SHARED_PTR(TermVectorMapper) - DECLARE_SHARED_PTR(TermVectorOffsetInfo) - DECLARE_SHARED_PTR(TermVectorsReader) - DECLARE_SHARED_PTR(TermVectorStatus) - DECLARE_SHARED_PTR(TermVectorsTermsWriter) - DECLARE_SHARED_PTR(TermVectorsTermsWriterPerDoc) - DECLARE_SHARED_PTR(TermVectorsTermsWriterPerField) - DECLARE_SHARED_PTR(TermVectorsTermsWriterPerThread) - DECLARE_SHARED_PTR(TermVectorsTermsWriterPostingList) - DECLARE_SHARED_PTR(TermVectorsWriter) - DECLARE_SHARED_PTR(TermVectorsPositionInfo) - DECLARE_SHARED_PTR(WaitQueue) +// document +DECLARE_SHARED_PTR(AbstractField) +DECLARE_SHARED_PTR(CompressionTools) +DECLARE_SHARED_PTR(DateField) +DECLARE_SHARED_PTR(DateTools) +DECLARE_SHARED_PTR(Document) +DECLARE_SHARED_PTR(Field) +DECLARE_SHARED_PTR(Fieldable) +DECLARE_SHARED_PTR(FieldSelector) +DECLARE_SHARED_PTR(LoadFirstFieldSelector) +DECLARE_SHARED_PTR(MapFieldSelector) +DECLARE_SHARED_PTR(NumberTools) +DECLARE_SHARED_PTR(NumericField) +DECLARE_SHARED_PTR(SetBasedFieldSelector) - // query parser - DECLARE_SHARED_PTR(FastCharStream) - DECLARE_SHARED_PTR(MultiFieldQueryParser) - DECLARE_SHARED_PTR(QueryParser) - DECLARE_SHARED_PTR(QueryParserCharStream) - DECLARE_SHARED_PTR(QueryParserConstants) - DECLARE_SHARED_PTR(QueryParserToken) - DECLARE_SHARED_PTR(QueryParserTokenManager) +// index +DECLARE_SHARED_PTR(AbstractAllTermDocs) +DECLARE_SHARED_PTR(AllTermDocs) +DECLARE_SHARED_PTR(BufferedDeletes) +DECLARE_SHARED_PTR(ByteBlockAllocator) +DECLARE_SHARED_PTR(ByteBlockPool) +DECLARE_SHARED_PTR(ByteBlockPoolAllocatorBase) +DECLARE_SHARED_PTR(ByteSliceReader) +DECLARE_SHARED_PTR(ByteSliceWriter) +DECLARE_SHARED_PTR(CharBlockPool) +DECLARE_SHARED_PTR(CheckAbort) +DECLARE_SHARED_PTR(CheckIndex) +DECLARE_SHARED_PTR(CommitPoint) +DECLARE_SHARED_PTR(CompoundFileReader) +DECLARE_SHARED_PTR(CompoundFileWriter) +DECLARE_SHARED_PTR(ConcurrentMergeScheduler) +DECLARE_SHARED_PTR(CoreReaders) +DECLARE_SHARED_PTR(CSIndexInput) +DECLARE_SHARED_PTR(DefaultIndexingChain) +DECLARE_SHARED_PTR(DefaultSkipListReader) +DECLARE_SHARED_PTR(DefaultSkipListWriter) +DECLARE_SHARED_PTR(DirectoryReader) +DECLARE_SHARED_PTR(DocConsumer) +DECLARE_SHARED_PTR(DocConsumerPerThread) +DECLARE_SHARED_PTR(DocFieldConsumer) +DECLARE_SHARED_PTR(DocFieldConsumerPerField) +DECLARE_SHARED_PTR(DocFieldConsumerPerThread) +DECLARE_SHARED_PTR(DocFieldConsumers) +DECLARE_SHARED_PTR(DocFieldConsumersPerDoc) +DECLARE_SHARED_PTR(DocFieldConsumersPerField) +DECLARE_SHARED_PTR(DocFieldConsumersPerThread) +DECLARE_SHARED_PTR(DocFieldProcessor) +DECLARE_SHARED_PTR(DocFieldProcessorPerField) +DECLARE_SHARED_PTR(DocFieldProcessorPerThread) +DECLARE_SHARED_PTR(DocFieldProcessorPerThreadPerDoc) +DECLARE_SHARED_PTR(DocInverter) +DECLARE_SHARED_PTR(DocInverterPerField) +DECLARE_SHARED_PTR(DocInverterPerThread) +DECLARE_SHARED_PTR(DocState) +DECLARE_SHARED_PTR(DocumentsWriter) +DECLARE_SHARED_PTR(DocumentsWriterThreadState) +DECLARE_SHARED_PTR(DocWriter) +DECLARE_SHARED_PTR(FieldInfo) +DECLARE_SHARED_PTR(FieldInfos) +DECLARE_SHARED_PTR(FieldInvertState) +DECLARE_SHARED_PTR(FieldNormStatus) +DECLARE_SHARED_PTR(FieldSortedTermVectorMapper) +DECLARE_SHARED_PTR(FieldsReader) +DECLARE_SHARED_PTR(FieldsReaderLocal) +DECLARE_SHARED_PTR(FieldsWriter) +DECLARE_SHARED_PTR(FilterIndexReader) +DECLARE_SHARED_PTR(FindSegmentsModified) +DECLARE_SHARED_PTR(FindSegmentsOpen) +DECLARE_SHARED_PTR(FindSegmentsRead) +DECLARE_SHARED_PTR(FindSegmentsReopen) +DECLARE_SHARED_PTR(FormatPostingsDocsConsumer) +DECLARE_SHARED_PTR(FormatPostingsDocsWriter) +DECLARE_SHARED_PTR(FormatPostingsFieldsConsumer) +DECLARE_SHARED_PTR(FormatPostingsFieldsWriter) +DECLARE_SHARED_PTR(FormatPostingsPositionsConsumer) +DECLARE_SHARED_PTR(FormatPostingsPositionsWriter) +DECLARE_SHARED_PTR(FormatPostingsTermsConsumer) +DECLARE_SHARED_PTR(FormatPostingsTermsWriter) +DECLARE_SHARED_PTR(FreqProxFieldMergeState) +DECLARE_SHARED_PTR(FreqProxTermsWriter) +DECLARE_SHARED_PTR(FreqProxTermsWriterPerField) +DECLARE_SHARED_PTR(FreqProxTermsWriterPerThread) +DECLARE_SHARED_PTR(FreqProxTermsWriterPostingList) +DECLARE_SHARED_PTR(IndexCommit) +DECLARE_SHARED_PTR(IndexDeletionPolicy) +DECLARE_SHARED_PTR(IndexFileDeleter) +DECLARE_SHARED_PTR(IndexFileNameFilter) +DECLARE_SHARED_PTR(IndexingChain) +DECLARE_SHARED_PTR(IndexReader) +DECLARE_SHARED_PTR(IndexReaderWarmer) +DECLARE_SHARED_PTR(IndexStatus) +DECLARE_SHARED_PTR(IndexWriter) +DECLARE_SHARED_PTR(IntBlockPool) +DECLARE_SHARED_PTR(IntQueue) +DECLARE_SHARED_PTR(InvertedDocConsumer) +DECLARE_SHARED_PTR(InvertedDocConsumerPerField) +DECLARE_SHARED_PTR(InvertedDocConsumerPerThread) +DECLARE_SHARED_PTR(InvertedDocEndConsumer) +DECLARE_SHARED_PTR(InvertedDocEndConsumerPerField) +DECLARE_SHARED_PTR(InvertedDocEndConsumerPerThread) +DECLARE_SHARED_PTR(KeepOnlyLastCommitDeletionPolicy) +DECLARE_SHARED_PTR(LogByteSizeMergePolicy) +DECLARE_SHARED_PTR(LogDocMergePolicy) +DECLARE_SHARED_PTR(LogMergePolicy) +DECLARE_SHARED_PTR(MergeDocIDRemapper) +DECLARE_SHARED_PTR(MergePolicy) +DECLARE_SHARED_PTR(MergeScheduler) +DECLARE_SHARED_PTR(MergeSpecification) +DECLARE_SHARED_PTR(MergeThread) +DECLARE_SHARED_PTR(MultiLevelSkipListReader) +DECLARE_SHARED_PTR(MultiLevelSkipListWriter) +DECLARE_SHARED_PTR(MultipleTermPositions) +DECLARE_SHARED_PTR(MultiReader) +DECLARE_SHARED_PTR(MultiTermDocs) +DECLARE_SHARED_PTR(MultiTermEnum) +DECLARE_SHARED_PTR(MultiTermPositions) +DECLARE_SHARED_PTR(MyCommitPoint) +DECLARE_SHARED_PTR(MySegmentTermDocs) +DECLARE_SHARED_PTR(Norm) +DECLARE_SHARED_PTR(NormsWriter) +DECLARE_SHARED_PTR(NormsWriterPerField) +DECLARE_SHARED_PTR(NormsWriterPerThread) +DECLARE_SHARED_PTR(Num) +DECLARE_SHARED_PTR(OneMerge) +DECLARE_SHARED_PTR(ParallelArrayTermVectorMapper) +DECLARE_SHARED_PTR(ParallelReader) +DECLARE_SHARED_PTR(ParallelTermEnum) +DECLARE_SHARED_PTR(ParallelTermDocs) +DECLARE_SHARED_PTR(ParallelTermPositions) +DECLARE_SHARED_PTR(Payload) +DECLARE_SHARED_PTR(PerDocBuffer) +DECLARE_SHARED_PTR(PositionBasedTermVectorMapper) +DECLARE_SHARED_PTR(RawPostingList) +DECLARE_SHARED_PTR(ReaderCommit) +DECLARE_SHARED_PTR(ReaderPool) +DECLARE_SHARED_PTR(ReadOnlyDirectoryReader) +DECLARE_SHARED_PTR(ReadOnlySegmentReader) +DECLARE_SHARED_PTR(RefCount) +DECLARE_SHARED_PTR(ReusableStringReader) +DECLARE_SHARED_PTR(SegmentInfo) +DECLARE_SHARED_PTR(SegmentInfoCollection) +DECLARE_SHARED_PTR(SegmentInfos) +DECLARE_SHARED_PTR(SegmentInfoStatus) +DECLARE_SHARED_PTR(SegmentMergeInfo) +DECLARE_SHARED_PTR(SegmentMergeQueue) +DECLARE_SHARED_PTR(SegmentMerger) +DECLARE_SHARED_PTR(SegmentReader) +DECLARE_SHARED_PTR(SegmentReaderRef) +DECLARE_SHARED_PTR(SegmentTermDocs) +DECLARE_SHARED_PTR(SegmentTermEnum) +DECLARE_SHARED_PTR(SegmentTermPositions) +DECLARE_SHARED_PTR(SegmentTermPositionVector) +DECLARE_SHARED_PTR(SegmentTermVector) +DECLARE_SHARED_PTR(SegmentWriteState) +DECLARE_SHARED_PTR(SerialMergeScheduler) +DECLARE_SHARED_PTR(SingleTokenAttributeSource) +DECLARE_SHARED_PTR(SkipBuffer) +DECLARE_SHARED_PTR(SkipDocWriter) +DECLARE_SHARED_PTR(SnapshotDeletionPolicy) +DECLARE_SHARED_PTR(SortedTermVectorMapper) +DECLARE_SHARED_PTR(StoredFieldStatus) +DECLARE_SHARED_PTR(StoredFieldsWriter) +DECLARE_SHARED_PTR(StoredFieldsWriterPerDoc) +DECLARE_SHARED_PTR(StoredFieldsWriterPerThread) +DECLARE_SHARED_PTR(Term) +DECLARE_SHARED_PTR(TermBuffer) +DECLARE_SHARED_PTR(TermEnum) +DECLARE_SHARED_PTR(TermDocs) +DECLARE_SHARED_PTR(TermFreqVector) +DECLARE_SHARED_PTR(TermIndexStatus) +DECLARE_SHARED_PTR(TermInfo) +DECLARE_SHARED_PTR(TermInfosReader) +DECLARE_SHARED_PTR(TermInfosReaderThreadResources) +DECLARE_SHARED_PTR(TermInfosWriter) +DECLARE_SHARED_PTR(TermPositions) +DECLARE_SHARED_PTR(TermPositionsQueue) +DECLARE_SHARED_PTR(TermPositionVector) +DECLARE_SHARED_PTR(TermsHash) +DECLARE_SHARED_PTR(TermsHashConsumer) +DECLARE_SHARED_PTR(TermsHashConsumerPerField) +DECLARE_SHARED_PTR(TermsHashConsumerPerThread) +DECLARE_SHARED_PTR(TermsHashPerField) +DECLARE_SHARED_PTR(TermsHashPerThread) +DECLARE_SHARED_PTR(TermVectorEntry) +DECLARE_SHARED_PTR(TermVectorEntryFreqSortedComparator) +DECLARE_SHARED_PTR(TermVectorMapper) +DECLARE_SHARED_PTR(TermVectorOffsetInfo) +DECLARE_SHARED_PTR(TermVectorsReader) +DECLARE_SHARED_PTR(TermVectorStatus) +DECLARE_SHARED_PTR(TermVectorsTermsWriter) +DECLARE_SHARED_PTR(TermVectorsTermsWriterPerDoc) +DECLARE_SHARED_PTR(TermVectorsTermsWriterPerField) +DECLARE_SHARED_PTR(TermVectorsTermsWriterPerThread) +DECLARE_SHARED_PTR(TermVectorsTermsWriterPostingList) +DECLARE_SHARED_PTR(TermVectorsWriter) +DECLARE_SHARED_PTR(TermVectorsPositionInfo) +DECLARE_SHARED_PTR(WaitQueue) - // search - DECLARE_SHARED_PTR(AveragePayloadFunction) - DECLARE_SHARED_PTR(BooleanClause) - DECLARE_SHARED_PTR(BooleanQuery) - DECLARE_SHARED_PTR(BooleanScorer) - DECLARE_SHARED_PTR(BooleanScorerCollector) - DECLARE_SHARED_PTR(BooleanScorer2) - DECLARE_SHARED_PTR(BooleanWeight) - DECLARE_SHARED_PTR(Bucket) - DECLARE_SHARED_PTR(BucketScorer) - DECLARE_SHARED_PTR(BucketTable) - DECLARE_SHARED_PTR(ByteCache) - DECLARE_SHARED_PTR(ByteFieldSource) - DECLARE_SHARED_PTR(ByteParser) - DECLARE_SHARED_PTR(Cache) - DECLARE_SHARED_PTR(CachedDfSource) - DECLARE_SHARED_PTR(CachingSpanFilter) - DECLARE_SHARED_PTR(CachingWrapperFilter) - DECLARE_SHARED_PTR(CellQueue) - DECLARE_SHARED_PTR(Collector) - DECLARE_SHARED_PTR(ComplexExplanation) - DECLARE_SHARED_PTR(ConjunctionScorer) - DECLARE_SHARED_PTR(ConstantScoreAutoRewrite) - DECLARE_SHARED_PTR(ConstantScoreAutoRewriteDefault) - DECLARE_SHARED_PTR(ConstantScoreBooleanQueryRewrite) - DECLARE_SHARED_PTR(ConstantScoreFilterRewrite) - DECLARE_SHARED_PTR(ConstantScoreQuery) - DECLARE_SHARED_PTR(ConstantScorer) - DECLARE_SHARED_PTR(ConstantWeight) - DECLARE_SHARED_PTR(Coordinator) - DECLARE_SHARED_PTR(CountingConjunctionSumScorer) - DECLARE_SHARED_PTR(CountingDisjunctionSumScorer) - DECLARE_SHARED_PTR(CreationPlaceholder) - DECLARE_SHARED_PTR(CustomScoreProvider) - DECLARE_SHARED_PTR(CustomScoreQuery) - DECLARE_SHARED_PTR(CustomWeight) - DECLARE_SHARED_PTR(CustomScorer) - DECLARE_SHARED_PTR(DefaultByteParser) - DECLARE_SHARED_PTR(DefaultCustomScoreProvider) - DECLARE_SHARED_PTR(DefaultDoubleParser) - DECLARE_SHARED_PTR(DefaultIntParser) - DECLARE_SHARED_PTR(DefaultLongParser) - DECLARE_SHARED_PTR(DefaultSimilarity) - DECLARE_SHARED_PTR(DisjunctionMaxQuery) - DECLARE_SHARED_PTR(DisjunctionMaxScorer) - DECLARE_SHARED_PTR(DisjunctionMaxWeight) - DECLARE_SHARED_PTR(DisjunctionSumScorer) - DECLARE_SHARED_PTR(DocIdSet) - DECLARE_SHARED_PTR(DocIdSetIterator) - DECLARE_SHARED_PTR(DocValues) - DECLARE_SHARED_PTR(DoubleCache) - DECLARE_SHARED_PTR(DoubleFieldSource) - DECLARE_SHARED_PTR(DoubleParser) - DECLARE_SHARED_PTR(EmptyDocIdSet) - DECLARE_SHARED_PTR(EmptyDocIdSetIterator) - DECLARE_SHARED_PTR(Entry) - DECLARE_SHARED_PTR(ExactPhraseScorer) - DECLARE_SHARED_PTR(Explanation) - DECLARE_SHARED_PTR(FieldCache) - DECLARE_SHARED_PTR(FieldCacheDocIdSet) - DECLARE_SHARED_PTR(FieldCacheEntry) - DECLARE_SHARED_PTR(FieldCacheEntryImpl) - DECLARE_SHARED_PTR(FieldCacheImpl) - DECLARE_SHARED_PTR(FieldCacheRangeFilter) - DECLARE_SHARED_PTR(FieldCacheRangeFilterByte) - DECLARE_SHARED_PTR(FieldCacheRangeFilterDouble) - DECLARE_SHARED_PTR(FieldCacheRangeFilterInt) - DECLARE_SHARED_PTR(FieldCacheRangeFilterLong) - DECLARE_SHARED_PTR(FieldCacheRangeFilterString) - DECLARE_SHARED_PTR(FieldCacheSource) - DECLARE_SHARED_PTR(FieldCacheTermsFilter) - DECLARE_SHARED_PTR(FieldCacheTermsFilterDocIdSet) - DECLARE_SHARED_PTR(FieldComparator) - DECLARE_SHARED_PTR(FieldComparatorSource) - DECLARE_SHARED_PTR(FieldDoc) - DECLARE_SHARED_PTR(FieldDocIdSetIteratorIncrement) - DECLARE_SHARED_PTR(FieldDocIdSetIteratorTermDocs) - DECLARE_SHARED_PTR(FieldDocSortedHitQueue) - DECLARE_SHARED_PTR(FieldMaskingSpanQuery) - DECLARE_SHARED_PTR(FieldScoreQuery) - DECLARE_SHARED_PTR(FieldValueHitQueue) - DECLARE_SHARED_PTR(FieldValueHitQueueEntry) - DECLARE_SHARED_PTR(Filter) - DECLARE_SHARED_PTR(FilterCache) - DECLARE_SHARED_PTR(FilterCleaner) - DECLARE_SHARED_PTR(FilteredDocIdSet) - DECLARE_SHARED_PTR(FilteredDocIdSetIterator) - DECLARE_SHARED_PTR(FilteredQuery) - DECLARE_SHARED_PTR(FilteredQueryWeight) - DECLARE_SHARED_PTR(FilteredTermEnum) - DECLARE_SHARED_PTR(FilterItem) - DECLARE_SHARED_PTR(FilterManager) - DECLARE_SHARED_PTR(FuzzyQuery) - DECLARE_SHARED_PTR(FuzzyTermEnum) - DECLARE_SHARED_PTR(HitQueue) - DECLARE_SHARED_PTR(HitQueueBase) - DECLARE_SHARED_PTR(IDFExplanation) - DECLARE_SHARED_PTR(IndexSearcher) - DECLARE_SHARED_PTR(IntCache) - DECLARE_SHARED_PTR(IntFieldSource) - DECLARE_SHARED_PTR(IntParser) - DECLARE_SHARED_PTR(LongCache) - DECLARE_SHARED_PTR(LongParser) - DECLARE_SHARED_PTR(MatchAllDocsQuery) - DECLARE_SHARED_PTR(MatchAllDocsWeight) - DECLARE_SHARED_PTR(MatchAllScorer) - DECLARE_SHARED_PTR(MaxPayloadFunction) - DECLARE_SHARED_PTR(MinPayloadFunction) - DECLARE_SHARED_PTR(MultiComparatorsFieldValueHitQueue) - DECLARE_SHARED_PTR(MultiPhraseQuery) - DECLARE_SHARED_PTR(MultiSearcher) - DECLARE_SHARED_PTR(MultiSearcherCallableNoSort) - DECLARE_SHARED_PTR(MultiSearcherCallableWithSort) - DECLARE_SHARED_PTR(MultiTermQuery) - DECLARE_SHARED_PTR(MultiTermQueryWrapperFilter) - DECLARE_SHARED_PTR(NearSpansOrdered) - DECLARE_SHARED_PTR(NearSpansUnordered) - DECLARE_SHARED_PTR(NumericRangeFilter) - DECLARE_SHARED_PTR(NumericRangeQuery) - DECLARE_SHARED_PTR(NumericUtilsDoubleParser) - DECLARE_SHARED_PTR(NumericUtilsIntParser) - DECLARE_SHARED_PTR(NumericUtilsLongParser) - DECLARE_SHARED_PTR(OneComparatorFieldValueHitQueue) - DECLARE_SHARED_PTR(OrdFieldSource) - DECLARE_SHARED_PTR(ParallelMultiSearcher) - DECLARE_SHARED_PTR(Parser) - DECLARE_SHARED_PTR(PayloadFunction) - DECLARE_SHARED_PTR(PayloadNearQuery) - DECLARE_SHARED_PTR(PayloadNearSpanScorer) - DECLARE_SHARED_PTR(PayloadNearSpanWeight) - DECLARE_SHARED_PTR(PayloadSpanUtil) - DECLARE_SHARED_PTR(PayloadTermQuery) - DECLARE_SHARED_PTR(PayloadTermSpanScorer) - DECLARE_SHARED_PTR(PayloadTermWeight) - DECLARE_SHARED_PTR(PhrasePositions) - DECLARE_SHARED_PTR(PhraseQuery) - DECLARE_SHARED_PTR(PhraseQueue) - DECLARE_SHARED_PTR(PhraseScorer) - DECLARE_SHARED_PTR(PositionInfo) - DECLARE_SHARED_PTR(PositiveScoresOnlyCollector) - DECLARE_SHARED_PTR(PrefixFilter) - DECLARE_SHARED_PTR(PrefixQuery) - DECLARE_SHARED_PTR(PrefixTermEnum) - DECLARE_SHARED_PTR(PriorityQueueScoreDocs) - DECLARE_SHARED_PTR(Query) - DECLARE_SHARED_PTR(QueryTermVector) - DECLARE_SHARED_PTR(QueryWrapperFilter) - DECLARE_SHARED_PTR(ReqExclScorer) - DECLARE_SHARED_PTR(ReqOptSumScorer) - DECLARE_SHARED_PTR(RewriteMethod) - DECLARE_SHARED_PTR(ReverseOrdFieldSource) - DECLARE_SHARED_PTR(ScoreCachingWrappingScorer) - DECLARE_SHARED_PTR(ScoreDoc) - DECLARE_SHARED_PTR(Scorer) - DECLARE_SHARED_PTR(ScoreTerm) - DECLARE_SHARED_PTR(ScoreTermQueue) - DECLARE_SHARED_PTR(ScoringBooleanQueryRewrite) - DECLARE_SHARED_PTR(Searchable) - DECLARE_SHARED_PTR(Searcher) - DECLARE_SHARED_PTR(Similarity) - DECLARE_SHARED_PTR(SimilarityDisableCoord) - DECLARE_SHARED_PTR(SimilarityDelegator) - DECLARE_SHARED_PTR(SimilarityIDFExplanation) - DECLARE_SHARED_PTR(SingleMatchScorer) - DECLARE_SHARED_PTR(SingleTermEnum) - DECLARE_SHARED_PTR(SloppyPhraseScorer) - DECLARE_SHARED_PTR(Sort) - DECLARE_SHARED_PTR(SortField) - DECLARE_SHARED_PTR(SpanFilter) - DECLARE_SHARED_PTR(SpanFilterResult) - DECLARE_SHARED_PTR(SpanFirstQuery) - DECLARE_SHARED_PTR(SpanNearQuery) - DECLARE_SHARED_PTR(SpanNotQuery) - DECLARE_SHARED_PTR(SpanOrQuery) - DECLARE_SHARED_PTR(SpanQuery) - DECLARE_SHARED_PTR(SpanQueryFilter) - DECLARE_SHARED_PTR(SpanQueue) - DECLARE_SHARED_PTR(Spans) - DECLARE_SHARED_PTR(SpansCell) - DECLARE_SHARED_PTR(SpanScorer) - DECLARE_SHARED_PTR(SpanTermQuery) - DECLARE_SHARED_PTR(SpanWeight) - DECLARE_SHARED_PTR(StartEnd) - DECLARE_SHARED_PTR(StringCache) - DECLARE_SHARED_PTR(StringIndex) - DECLARE_SHARED_PTR(StringIndexCache) - DECLARE_SHARED_PTR(SubScorer) - DECLARE_SHARED_PTR(TermQuery) - DECLARE_SHARED_PTR(TermRangeFilter) - DECLARE_SHARED_PTR(TermRangeQuery) - DECLARE_SHARED_PTR(TermRangeTermEnum) - DECLARE_SHARED_PTR(TermScorer) - DECLARE_SHARED_PTR(TermSpans) - DECLARE_SHARED_PTR(TimeLimitingCollector) - DECLARE_SHARED_PTR(TimerThread) - DECLARE_SHARED_PTR(TopDocs) - DECLARE_SHARED_PTR(TopDocsCollector) - DECLARE_SHARED_PTR(TopFieldCollector) - DECLARE_SHARED_PTR(TopFieldDocs) - DECLARE_SHARED_PTR(TopScoreDocCollector) - DECLARE_SHARED_PTR(ValueSource) - DECLARE_SHARED_PTR(ValueSourceQuery) - DECLARE_SHARED_PTR(ValueSourceScorer) - DECLARE_SHARED_PTR(ValueSourceWeight) - DECLARE_SHARED_PTR(Weight) - DECLARE_SHARED_PTR(WildcardQuery) - DECLARE_SHARED_PTR(WildcardTermEnum) +// query parser +DECLARE_SHARED_PTR(FastCharStream) +DECLARE_SHARED_PTR(MultiFieldQueryParser) +DECLARE_SHARED_PTR(QueryParser) +DECLARE_SHARED_PTR(QueryParserCharStream) +DECLARE_SHARED_PTR(QueryParserConstants) +DECLARE_SHARED_PTR(QueryParserToken) +DECLARE_SHARED_PTR(QueryParserTokenManager) - // store - DECLARE_SHARED_PTR(BufferedIndexInput) - DECLARE_SHARED_PTR(BufferedIndexOutput) - DECLARE_SHARED_PTR(ChecksumIndexInput) - DECLARE_SHARED_PTR(ChecksumIndexOutput) - DECLARE_SHARED_PTR(Directory) - DECLARE_SHARED_PTR(FileSwitchDirectory) - DECLARE_SHARED_PTR(FSDirectory) - DECLARE_SHARED_PTR(FSLockFactory) - DECLARE_SHARED_PTR(IndexInput) - DECLARE_SHARED_PTR(IndexOutput) - DECLARE_SHARED_PTR(InputFile) - DECLARE_SHARED_PTR(Lock) - DECLARE_SHARED_PTR(LockFactory) - DECLARE_SHARED_PTR(MMapDirectory) - DECLARE_SHARED_PTR(MMapIndexInput) - DECLARE_SHARED_PTR(NativeFSLock) - DECLARE_SHARED_PTR(NativeFSLockFactory) - DECLARE_SHARED_PTR(NoLock) - DECLARE_SHARED_PTR(NoLockFactory) - DECLARE_SHARED_PTR(OutputFile) - DECLARE_SHARED_PTR(RAMDirectory) - DECLARE_SHARED_PTR(RAMFile) - DECLARE_SHARED_PTR(RAMInputStream) - DECLARE_SHARED_PTR(RAMOutputStream) - DECLARE_SHARED_PTR(SimpleFSDirectory) - DECLARE_SHARED_PTR(SimpleFSIndexInput) - DECLARE_SHARED_PTR(SimpleFSIndexOutput) - DECLARE_SHARED_PTR(SimpleFSLock) - DECLARE_SHARED_PTR(SimpleFSLockFactory) - DECLARE_SHARED_PTR(SingleInstanceLock) - DECLARE_SHARED_PTR(SingleInstanceLockFactory) +// search +DECLARE_SHARED_PTR(AveragePayloadFunction) +DECLARE_SHARED_PTR(BooleanClause) +DECLARE_SHARED_PTR(BooleanQuery) +DECLARE_SHARED_PTR(BooleanScorer) +DECLARE_SHARED_PTR(BooleanScorerCollector) +DECLARE_SHARED_PTR(BooleanScorer2) +DECLARE_SHARED_PTR(BooleanWeight) +DECLARE_SHARED_PTR(Bucket) +DECLARE_SHARED_PTR(BucketScorer) +DECLARE_SHARED_PTR(BucketTable) +DECLARE_SHARED_PTR(ByteCache) +DECLARE_SHARED_PTR(ByteFieldSource) +DECLARE_SHARED_PTR(ByteParser) +DECLARE_SHARED_PTR(Cache) +DECLARE_SHARED_PTR(CachedDfSource) +DECLARE_SHARED_PTR(CachingSpanFilter) +DECLARE_SHARED_PTR(CachingWrapperFilter) +DECLARE_SHARED_PTR(CellQueue) +DECLARE_SHARED_PTR(Collector) +DECLARE_SHARED_PTR(ComplexExplanation) +DECLARE_SHARED_PTR(ConjunctionScorer) +DECLARE_SHARED_PTR(ConstantScoreAutoRewrite) +DECLARE_SHARED_PTR(ConstantScoreAutoRewriteDefault) +DECLARE_SHARED_PTR(ConstantScoreBooleanQueryRewrite) +DECLARE_SHARED_PTR(ConstantScoreFilterRewrite) +DECLARE_SHARED_PTR(ConstantScoreQuery) +DECLARE_SHARED_PTR(ConstantScorer) +DECLARE_SHARED_PTR(ConstantWeight) +DECLARE_SHARED_PTR(Coordinator) +DECLARE_SHARED_PTR(CountingConjunctionSumScorer) +DECLARE_SHARED_PTR(CountingDisjunctionSumScorer) +DECLARE_SHARED_PTR(CreationPlaceholder) +DECLARE_SHARED_PTR(CustomScoreProvider) +DECLARE_SHARED_PTR(CustomScoreQuery) +DECLARE_SHARED_PTR(CustomWeight) +DECLARE_SHARED_PTR(CustomScorer) +DECLARE_SHARED_PTR(DefaultByteParser) +DECLARE_SHARED_PTR(DefaultCustomScoreProvider) +DECLARE_SHARED_PTR(DefaultDoubleParser) +DECLARE_SHARED_PTR(DefaultIntParser) +DECLARE_SHARED_PTR(DefaultLongParser) +DECLARE_SHARED_PTR(DefaultSimilarity) +DECLARE_SHARED_PTR(DisjunctionMaxQuery) +DECLARE_SHARED_PTR(DisjunctionMaxScorer) +DECLARE_SHARED_PTR(DisjunctionMaxWeight) +DECLARE_SHARED_PTR(DisjunctionSumScorer) +DECLARE_SHARED_PTR(DocIdSet) +DECLARE_SHARED_PTR(DocIdSetIterator) +DECLARE_SHARED_PTR(DocValues) +DECLARE_SHARED_PTR(DoubleCache) +DECLARE_SHARED_PTR(DoubleFieldSource) +DECLARE_SHARED_PTR(DoubleParser) +DECLARE_SHARED_PTR(EmptyDocIdSet) +DECLARE_SHARED_PTR(EmptyDocIdSetIterator) +DECLARE_SHARED_PTR(Entry) +DECLARE_SHARED_PTR(ExactPhraseScorer) +DECLARE_SHARED_PTR(Explanation) +DECLARE_SHARED_PTR(FieldCache) +DECLARE_SHARED_PTR(FieldCacheDocIdSet) +DECLARE_SHARED_PTR(FieldCacheEntry) +DECLARE_SHARED_PTR(FieldCacheEntryImpl) +DECLARE_SHARED_PTR(FieldCacheImpl) +DECLARE_SHARED_PTR(FieldCacheRangeFilter) +DECLARE_SHARED_PTR(FieldCacheRangeFilterByte) +DECLARE_SHARED_PTR(FieldCacheRangeFilterDouble) +DECLARE_SHARED_PTR(FieldCacheRangeFilterInt) +DECLARE_SHARED_PTR(FieldCacheRangeFilterLong) +DECLARE_SHARED_PTR(FieldCacheRangeFilterString) +DECLARE_SHARED_PTR(FieldCacheSource) +DECLARE_SHARED_PTR(FieldCacheTermsFilter) +DECLARE_SHARED_PTR(FieldCacheTermsFilterDocIdSet) +DECLARE_SHARED_PTR(FieldComparator) +DECLARE_SHARED_PTR(FieldComparatorSource) +DECLARE_SHARED_PTR(FieldDoc) +DECLARE_SHARED_PTR(FieldDocIdSetIteratorIncrement) +DECLARE_SHARED_PTR(FieldDocIdSetIteratorTermDocs) +DECLARE_SHARED_PTR(FieldDocSortedHitQueue) +DECLARE_SHARED_PTR(FieldMaskingSpanQuery) +DECLARE_SHARED_PTR(FieldScoreQuery) +DECLARE_SHARED_PTR(FieldValueHitQueue) +DECLARE_SHARED_PTR(FieldValueHitQueueEntry) +DECLARE_SHARED_PTR(Filter) +DECLARE_SHARED_PTR(FilterCache) +DECLARE_SHARED_PTR(FilterCleaner) +DECLARE_SHARED_PTR(FilteredDocIdSet) +DECLARE_SHARED_PTR(FilteredDocIdSetIterator) +DECLARE_SHARED_PTR(FilteredQuery) +DECLARE_SHARED_PTR(FilteredQueryWeight) +DECLARE_SHARED_PTR(FilteredTermEnum) +DECLARE_SHARED_PTR(FilterItem) +DECLARE_SHARED_PTR(FilterManager) +DECLARE_SHARED_PTR(FuzzyQuery) +DECLARE_SHARED_PTR(FuzzyTermEnum) +DECLARE_SHARED_PTR(HitQueue) +DECLARE_SHARED_PTR(HitQueueBase) +DECLARE_SHARED_PTR(IDFExplanation) +DECLARE_SHARED_PTR(IndexSearcher) +DECLARE_SHARED_PTR(IntCache) +DECLARE_SHARED_PTR(IntFieldSource) +DECLARE_SHARED_PTR(IntParser) +DECLARE_SHARED_PTR(LongCache) +DECLARE_SHARED_PTR(LongParser) +DECLARE_SHARED_PTR(MatchAllDocsQuery) +DECLARE_SHARED_PTR(MatchAllDocsWeight) +DECLARE_SHARED_PTR(MatchAllScorer) +DECLARE_SHARED_PTR(MaxPayloadFunction) +DECLARE_SHARED_PTR(MinPayloadFunction) +DECLARE_SHARED_PTR(MultiComparatorsFieldValueHitQueue) +DECLARE_SHARED_PTR(MultiPhraseQuery) +DECLARE_SHARED_PTR(MultiSearcher) +DECLARE_SHARED_PTR(MultiSearcherCallableNoSort) +DECLARE_SHARED_PTR(MultiSearcherCallableWithSort) +DECLARE_SHARED_PTR(MultiTermQuery) +DECLARE_SHARED_PTR(MultiTermQueryWrapperFilter) +DECLARE_SHARED_PTR(NearSpansOrdered) +DECLARE_SHARED_PTR(NearSpansUnordered) +DECLARE_SHARED_PTR(NumericRangeFilter) +DECLARE_SHARED_PTR(NumericRangeQuery) +DECLARE_SHARED_PTR(NumericUtilsDoubleParser) +DECLARE_SHARED_PTR(NumericUtilsIntParser) +DECLARE_SHARED_PTR(NumericUtilsLongParser) +DECLARE_SHARED_PTR(OneComparatorFieldValueHitQueue) +DECLARE_SHARED_PTR(OrdFieldSource) +DECLARE_SHARED_PTR(ParallelMultiSearcher) +DECLARE_SHARED_PTR(Parser) +DECLARE_SHARED_PTR(PayloadFunction) +DECLARE_SHARED_PTR(PayloadNearQuery) +DECLARE_SHARED_PTR(PayloadNearSpanScorer) +DECLARE_SHARED_PTR(PayloadNearSpanWeight) +DECLARE_SHARED_PTR(PayloadSpanUtil) +DECLARE_SHARED_PTR(PayloadTermQuery) +DECLARE_SHARED_PTR(PayloadTermSpanScorer) +DECLARE_SHARED_PTR(PayloadTermWeight) +DECLARE_SHARED_PTR(PhrasePositions) +DECLARE_SHARED_PTR(PhraseQuery) +DECLARE_SHARED_PTR(PhraseQueue) +DECLARE_SHARED_PTR(PhraseScorer) +DECLARE_SHARED_PTR(PositionInfo) +DECLARE_SHARED_PTR(PositiveScoresOnlyCollector) +DECLARE_SHARED_PTR(PrefixFilter) +DECLARE_SHARED_PTR(PrefixQuery) +DECLARE_SHARED_PTR(PrefixTermEnum) +DECLARE_SHARED_PTR(PriorityQueueScoreDocs) +DECLARE_SHARED_PTR(Query) +DECLARE_SHARED_PTR(QueryTermVector) +DECLARE_SHARED_PTR(QueryWrapperFilter) +DECLARE_SHARED_PTR(ReqExclScorer) +DECLARE_SHARED_PTR(ReqOptSumScorer) +DECLARE_SHARED_PTR(RewriteMethod) +DECLARE_SHARED_PTR(ReverseOrdFieldSource) +DECLARE_SHARED_PTR(ScoreCachingWrappingScorer) +DECLARE_SHARED_PTR(ScoreDoc) +DECLARE_SHARED_PTR(Scorer) +DECLARE_SHARED_PTR(ScoreTerm) +DECLARE_SHARED_PTR(ScoreTermQueue) +DECLARE_SHARED_PTR(ScoringBooleanQueryRewrite) +DECLARE_SHARED_PTR(Searchable) +DECLARE_SHARED_PTR(Searcher) +DECLARE_SHARED_PTR(Similarity) +DECLARE_SHARED_PTR(SimilarityDisableCoord) +DECLARE_SHARED_PTR(SimilarityDelegator) +DECLARE_SHARED_PTR(SimilarityIDFExplanation) +DECLARE_SHARED_PTR(SingleMatchScorer) +DECLARE_SHARED_PTR(SingleTermEnum) +DECLARE_SHARED_PTR(SloppyPhraseScorer) +DECLARE_SHARED_PTR(Sort) +DECLARE_SHARED_PTR(SortField) +DECLARE_SHARED_PTR(SpanFilter) +DECLARE_SHARED_PTR(SpanFilterResult) +DECLARE_SHARED_PTR(SpanFirstQuery) +DECLARE_SHARED_PTR(SpanNearQuery) +DECLARE_SHARED_PTR(SpanNotQuery) +DECLARE_SHARED_PTR(SpanOrQuery) +DECLARE_SHARED_PTR(SpanQuery) +DECLARE_SHARED_PTR(SpanQueryFilter) +DECLARE_SHARED_PTR(SpanQueue) +DECLARE_SHARED_PTR(Spans) +DECLARE_SHARED_PTR(SpansCell) +DECLARE_SHARED_PTR(SpanScorer) +DECLARE_SHARED_PTR(SpanTermQuery) +DECLARE_SHARED_PTR(SpanWeight) +DECLARE_SHARED_PTR(StartEnd) +DECLARE_SHARED_PTR(StringCache) +DECLARE_SHARED_PTR(StringIndex) +DECLARE_SHARED_PTR(StringIndexCache) +DECLARE_SHARED_PTR(SubScorer) +DECLARE_SHARED_PTR(TermQuery) +DECLARE_SHARED_PTR(TermRangeFilter) +DECLARE_SHARED_PTR(TermRangeQuery) +DECLARE_SHARED_PTR(TermRangeTermEnum) +DECLARE_SHARED_PTR(TermScorer) +DECLARE_SHARED_PTR(TermSpans) +DECLARE_SHARED_PTR(TimeLimitingCollector) +DECLARE_SHARED_PTR(TimerThread) +DECLARE_SHARED_PTR(TopDocs) +DECLARE_SHARED_PTR(TopDocsCollector) +DECLARE_SHARED_PTR(TopFieldCollector) +DECLARE_SHARED_PTR(TopFieldDocs) +DECLARE_SHARED_PTR(TopScoreDocCollector) +DECLARE_SHARED_PTR(ValueSource) +DECLARE_SHARED_PTR(ValueSourceQuery) +DECLARE_SHARED_PTR(ValueSourceScorer) +DECLARE_SHARED_PTR(ValueSourceWeight) +DECLARE_SHARED_PTR(Weight) +DECLARE_SHARED_PTR(WildcardQuery) +DECLARE_SHARED_PTR(WildcardTermEnum) - // util - DECLARE_SHARED_PTR(Attribute) - DECLARE_SHARED_PTR(AttributeFactory) - DECLARE_SHARED_PTR(AttributeSource) - DECLARE_SHARED_PTR(AttributeSourceState) - DECLARE_SHARED_PTR(BitSet) - DECLARE_SHARED_PTR(BitVector) - DECLARE_SHARED_PTR(BufferedReader) - DECLARE_SHARED_PTR(Collator) - DECLARE_SHARED_PTR(DefaultAttributeFactory) - DECLARE_SHARED_PTR(DocIdBitSet) - DECLARE_SHARED_PTR(FieldCacheSanityChecker) - DECLARE_SHARED_PTR(FileReader) - DECLARE_SHARED_PTR(Future) - DECLARE_SHARED_PTR(HeapedScorerDoc) - DECLARE_SHARED_PTR(InfoStream) - DECLARE_SHARED_PTR(InfoStreamFile) - DECLARE_SHARED_PTR(InfoStreamOut) - DECLARE_SHARED_PTR(InputStreamReader) - DECLARE_SHARED_PTR(Insanity) - DECLARE_SHARED_PTR(IntRangeBuilder) - DECLARE_SHARED_PTR(LongRangeBuilder) - DECLARE_SHARED_PTR(LuceneObject) - DECLARE_SHARED_PTR(LuceneSignal) - DECLARE_SHARED_PTR(LuceneThread) - DECLARE_SHARED_PTR(NumericUtils) - DECLARE_SHARED_PTR(OpenBitSet) - DECLARE_SHARED_PTR(OpenBitSetDISI) - DECLARE_SHARED_PTR(OpenBitSetIterator) - DECLARE_SHARED_PTR(Random) - DECLARE_SHARED_PTR(Reader) - DECLARE_SHARED_PTR(ReaderField) - DECLARE_SHARED_PTR(ScorerDocQueue) - DECLARE_SHARED_PTR(SortedVIntList) - DECLARE_SHARED_PTR(StringReader) - DECLARE_SHARED_PTR(Synchronize) - DECLARE_SHARED_PTR(ThreadPool) - DECLARE_SHARED_PTR(UnicodeResult) - DECLARE_SHARED_PTR(UTF8Decoder) - DECLARE_SHARED_PTR(UTF8DecoderStream) - DECLARE_SHARED_PTR(UTF8Encoder) - DECLARE_SHARED_PTR(UTF8EncoderStream) - DECLARE_SHARED_PTR(UTF8Result) - DECLARE_SHARED_PTR(UTF16Decoder) +// store +DECLARE_SHARED_PTR(BufferedIndexInput) +DECLARE_SHARED_PTR(BufferedIndexOutput) +DECLARE_SHARED_PTR(ChecksumIndexInput) +DECLARE_SHARED_PTR(ChecksumIndexOutput) +DECLARE_SHARED_PTR(Directory) +DECLARE_SHARED_PTR(FileSwitchDirectory) +DECLARE_SHARED_PTR(FSDirectory) +DECLARE_SHARED_PTR(FSLockFactory) +DECLARE_SHARED_PTR(IndexInput) +DECLARE_SHARED_PTR(IndexOutput) +DECLARE_SHARED_PTR(InputFile) +DECLARE_SHARED_PTR(Lock) +DECLARE_SHARED_PTR(LockFactory) +DECLARE_SHARED_PTR(MMapDirectory) +DECLARE_SHARED_PTR(MMapIndexInput) +DECLARE_SHARED_PTR(NativeFSLock) +DECLARE_SHARED_PTR(NativeFSLockFactory) +DECLARE_SHARED_PTR(NoLock) +DECLARE_SHARED_PTR(NoLockFactory) +DECLARE_SHARED_PTR(OutputFile) +DECLARE_SHARED_PTR(RAMDirectory) +DECLARE_SHARED_PTR(RAMFile) +DECLARE_SHARED_PTR(RAMInputStream) +DECLARE_SHARED_PTR(RAMOutputStream) +DECLARE_SHARED_PTR(SimpleFSDirectory) +DECLARE_SHARED_PTR(SimpleFSIndexInput) +DECLARE_SHARED_PTR(SimpleFSIndexOutput) +DECLARE_SHARED_PTR(SimpleFSLock) +DECLARE_SHARED_PTR(SimpleFSLockFactory) +DECLARE_SHARED_PTR(SingleInstanceLock) +DECLARE_SHARED_PTR(SingleInstanceLockFactory) + +// util +DECLARE_SHARED_PTR(Attribute) +DECLARE_SHARED_PTR(AttributeFactory) +DECLARE_SHARED_PTR(AttributeSource) +DECLARE_SHARED_PTR(AttributeSourceState) +DECLARE_SHARED_PTR(BitSet) +DECLARE_SHARED_PTR(BitVector) +DECLARE_SHARED_PTR(BufferedReader) +DECLARE_SHARED_PTR(Collator) +DECLARE_SHARED_PTR(DefaultAttributeFactory) +DECLARE_SHARED_PTR(DocIdBitSet) +DECLARE_SHARED_PTR(FieldCacheSanityChecker) +DECLARE_SHARED_PTR(FileReader) +DECLARE_SHARED_PTR(Future) +DECLARE_SHARED_PTR(HeapedScorerDoc) +DECLARE_SHARED_PTR(InfoStream) +DECLARE_SHARED_PTR(InfoStreamFile) +DECLARE_SHARED_PTR(InfoStreamOut) +DECLARE_SHARED_PTR(InputStreamReader) +DECLARE_SHARED_PTR(Insanity) +DECLARE_SHARED_PTR(IntRangeBuilder) +DECLARE_SHARED_PTR(LongRangeBuilder) +DECLARE_SHARED_PTR(LuceneObject) +DECLARE_SHARED_PTR(LuceneSignal) +DECLARE_SHARED_PTR(LuceneThread) +DECLARE_SHARED_PTR(NumericUtils) +DECLARE_SHARED_PTR(OpenBitSet) +DECLARE_SHARED_PTR(OpenBitSetDISI) +DECLARE_SHARED_PTR(OpenBitSetIterator) +DECLARE_SHARED_PTR(Random) +DECLARE_SHARED_PTR(Reader) +DECLARE_SHARED_PTR(ReaderField) +DECLARE_SHARED_PTR(ScorerDocQueue) +DECLARE_SHARED_PTR(SortedVIntList) +DECLARE_SHARED_PTR(StringReader) +DECLARE_SHARED_PTR(Synchronize) +DECLARE_SHARED_PTR(ThreadPool) +DECLARE_SHARED_PTR(UnicodeResult) +DECLARE_SHARED_PTR(UTF8Decoder) +DECLARE_SHARED_PTR(UTF8DecoderStream) +DECLARE_SHARED_PTR(UTF8Encoder) +DECLARE_SHARED_PTR(UTF8EncoderStream) +DECLARE_SHARED_PTR(UTF8Result) +DECLARE_SHARED_PTR(UTF16Decoder) } #endif diff --git a/include/MMapDirectory.h b/include/MMapDirectory.h index b3e3d5ce..3a3400e4 100644 --- a/include/MMapDirectory.h +++ b/include/MMapDirectory.h @@ -9,37 +9,37 @@ #include "FSDirectory.h" -namespace Lucene -{ - /// File-based {@link Directory} implementation that uses mmap for reading, and {@link SimpleFSIndexOutput} for writing. - /// - /// NOTE: memory mapping uses up a portion of the virtual memory address space in your process equal to the size of the - /// file being mapped. Before using this class, be sure your have plenty of virtual address space. - /// - /// NOTE: Accessing this class either directly or indirectly from a thread while it's interrupted can close the - /// underlying channel immediately if at the same time the thread is blocked on IO. The channel will remain closed and - /// subsequent access to {@link MMapDirectory} will throw an exception. - class LPPAPI MMapDirectory : public FSDirectory - { - public: - /// Create a new MMapDirectory for the named location. - /// @param path the path of the directory. - /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) - MMapDirectory(const String& path, const LockFactoryPtr& lockFactory = LockFactoryPtr()); - - virtual ~MMapDirectory(); - - LUCENE_CLASS(MMapDirectory); - - public: - using FSDirectory::openInput; - - /// Creates an IndexInput for the file with the given name. - virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - - /// Creates an IndexOutput for the file with the given name. - virtual IndexOutputPtr createOutput(const String& name); - }; +namespace Lucene { + +/// File-based {@link Directory} implementation that uses mmap for reading, and {@link SimpleFSIndexOutput} for writing. +/// +/// NOTE: memory mapping uses up a portion of the virtual memory address space in your process equal to the size of the +/// file being mapped. Before using this class, be sure your have plenty of virtual address space. +/// +/// NOTE: Accessing this class either directly or indirectly from a thread while it's interrupted can close the +/// underlying channel immediately if at the same time the thread is blocked on IO. The channel will remain closed and +/// subsequent access to {@link MMapDirectory} will throw an exception. +class LPPAPI MMapDirectory : public FSDirectory { +public: + /// Create a new MMapDirectory for the named location. + /// @param path the path of the directory. + /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) + MMapDirectory(const String& path, const LockFactoryPtr& lockFactory = LockFactoryPtr()); + + virtual ~MMapDirectory(); + + LUCENE_CLASS(MMapDirectory); + +public: + using FSDirectory::openInput; + + /// Creates an IndexInput for the file with the given name. + virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); + + /// Creates an IndexOutput for the file with the given name. + virtual IndexOutputPtr createOutput(const String& name); +}; + } #endif diff --git a/include/Map.h b/include/Map.h index 31a24cac..a86b0c86 100644 --- a/include/Map.h +++ b/include/Map.h @@ -10,142 +10,121 @@ #include #include "LuceneSync.h" -namespace Lucene -{ - /// Utility template class to handle maps that can be safely copied and shared - template < class KEY, class VALUE, class LESS = std::less > - class Map : public LuceneSync - { - public: - typedef Map this_type; - typedef std::pair key_value; - typedef std::map map_type; - typedef typename map_type::iterator iterator; - typedef typename map_type::const_iterator const_iterator; - typedef KEY key_type; - typedef VALUE value_type; - - virtual ~Map() - { - } - - protected: - boost::shared_ptr mapContainer; - - public: - static this_type newInstance() - { - this_type instance; - instance.mapContainer = Lucene::newInstance(); - return instance; - } - - void reset() - { - mapContainer.reset(); - } - - int32_t size() const - { - return (int32_t)mapContainer->size(); - } - - bool empty() const - { - return mapContainer->empty(); - } - - void clear() - { - mapContainer->clear(); - } - - iterator begin() - { - return mapContainer->begin(); - } - - iterator end() - { - return mapContainer->end(); - } - - const_iterator begin() const - { - return mapContainer->begin(); - } - - const_iterator end() const - { - return mapContainer->end(); - } - - operator bool() const - { - return mapContainer.get() != NULL; - } +namespace Lucene { + +/// Utility template class to handle maps that can be safely copied and shared +template < class KEY, class VALUE, class LESS = std::less > +class Map : public LuceneSync { +public: + typedef Map this_type; + typedef std::pair key_value; + typedef std::map map_type; + typedef typename map_type::iterator iterator; + typedef typename map_type::const_iterator const_iterator; + typedef KEY key_type; + typedef VALUE value_type; + + virtual ~Map() { + } + +protected: + boost::shared_ptr mapContainer; + +public: + static this_type newInstance() { + this_type instance; + instance.mapContainer = Lucene::newInstance(); + return instance; + } + + void reset() { + mapContainer.reset(); + } + + int32_t size() const { + return (int32_t)mapContainer->size(); + } + + bool empty() const { + return mapContainer->empty(); + } + + void clear() { + mapContainer->clear(); + } + + iterator begin() { + return mapContainer->begin(); + } + + iterator end() { + return mapContainer->end(); + } + + const_iterator begin() const { + return mapContainer->begin(); + } + + const_iterator end() const { + return mapContainer->end(); + } + + operator bool() const { + return mapContainer.get() != NULL; + } + + bool operator! () const { + return !mapContainer; + } + + map_type& operator= (const map_type& other) { + mapContainer = other.mapContainer; + return *this; + } + + void put(const KEY& key, const VALUE& value) { + (*mapContainer)[key] = value; + } + + template + void putAll(ITER first, ITER last) { + for (iterator current = first; current != last; ++current) { + (*mapContainer)[current->first] = current->second; + } + } + + template + void remove(ITER pos) { + mapContainer->erase(pos); + } + + template + ITER remove(ITER first, ITER last) { + return mapContainer->erase(first, last); + } + + bool remove(const KEY& key) { + return (mapContainer->erase(key) > 0); + } + + iterator find(const KEY& key) { + return mapContainer->find(key); + } + + VALUE get(const KEY& key) const { + iterator findValue = mapContainer->find(key); + return findValue == mapContainer->end() ? VALUE() : findValue->second; + } + + bool contains(const KEY& key) const { + return (mapContainer->find(key) != mapContainer->end()); + } + + VALUE& operator[] (const KEY& key) { + return (*mapContainer)[key]; + } +}; - bool operator! () const - { - return !mapContainer; - } - - map_type& operator= (const map_type& other) - { - mapContainer = other.mapContainer; - return *this; - } - - void put(const KEY& key, const VALUE& value) - { - (*mapContainer)[key] = value; - } - - template - void putAll(ITER first, ITER last) - { - for (iterator current = first; current != last; ++current) - (*mapContainer)[current->first] = current->second; - } - - template - void remove(ITER pos) - { - mapContainer->erase(pos); - } - - template - ITER remove(ITER first, ITER last) - { - return mapContainer->erase(first, last); - } - - bool remove(const KEY& key) - { - return (mapContainer->erase(key) > 0); - } - - iterator find(const KEY& key) - { - return mapContainer->find(key); - } - - VALUE get(const KEY& key) const - { - iterator findValue = mapContainer->find(key); - return findValue == mapContainer->end() ? VALUE() : findValue->second; - } - - bool contains(const KEY& key) const - { - return (mapContainer->find(key) != mapContainer->end()); - } - - VALUE& operator[] (const KEY& key) - { - return (*mapContainer)[key]; - } - }; } #endif diff --git a/include/MapFieldSelector.h b/include/MapFieldSelector.h index 4d8fc1d2..2db2d41a 100644 --- a/include/MapFieldSelector.h +++ b/include/MapFieldSelector.h @@ -9,35 +9,35 @@ #include "FieldSelector.h" -namespace Lucene -{ - typedef HashMap MapStringFieldSelectorResult; - - /// A {@link FieldSelector} based on a Map of field names to {@link FieldSelectorResult}s - class LPPAPI MapFieldSelector : public FieldSelector - { - public: - /// Create a MapFieldSelector - /// @param fieldSelections maps from field names (String) to {@link FieldSelectorResult}s - MapFieldSelector(MapStringFieldSelectorResult fieldSelections); - - /// Create a MapFieldSelector - /// @param fields fields to LOAD. List of Strings. All other fields are NO_LOAD. - MapFieldSelector(Collection fields); - - virtual ~MapFieldSelector(); - - LUCENE_CLASS(MapFieldSelector); - - public: - MapStringFieldSelectorResult fieldSelections; - - public: - /// Load field according to its associated value in fieldSelections - /// @param field a field name - /// @return the fieldSelections value that field maps to or NO_LOAD if none. - virtual FieldSelectorResult accept(const String& fieldName); - }; +namespace Lucene { + +typedef HashMap MapStringFieldSelectorResult; + +/// A {@link FieldSelector} based on a Map of field names to {@link FieldSelectorResult}s +class LPPAPI MapFieldSelector : public FieldSelector { +public: + /// Create a MapFieldSelector + /// @param fieldSelections maps from field names (String) to {@link FieldSelectorResult}s + MapFieldSelector(MapStringFieldSelectorResult fieldSelections); + + /// Create a MapFieldSelector + /// @param fields fields to LOAD. List of Strings. All other fields are NO_LOAD. + MapFieldSelector(Collection fields); + + virtual ~MapFieldSelector(); + + LUCENE_CLASS(MapFieldSelector); + +public: + MapStringFieldSelectorResult fieldSelections; + +public: + /// Load field according to its associated value in fieldSelections + /// @param field a field name + /// @return the fieldSelections value that field maps to or NO_LOAD if none. + virtual FieldSelectorResult accept(const String& fieldName); +}; + } #endif diff --git a/include/MapOfSets.h b/include/MapOfSets.h index 622855a3..d3a7d81d 100644 --- a/include/MapOfSets.h +++ b/include/MapOfSets.h @@ -9,70 +9,60 @@ #include "Lucene.h" -namespace Lucene -{ - /// Helper class for keeping Lists of Objects associated with keys. - template - class MapOfSets - { - public: - typedef HashSet set_type; - typedef HashMap map_type; +namespace Lucene { - MapOfSets(map_type m) - { - theMap = m; - } +/// Helper class for keeping Lists of Objects associated with keys. +template +class MapOfSets { +public: + typedef HashSet set_type; + typedef HashMap map_type; - protected: - map_type theMap; + MapOfSets(map_type m) { + theMap = m; + } - public: - /// @return direct access to the map backing this object. - map_type getMap() - { - return theMap; - } +protected: + map_type theMap; - /// Adds val to the HashSet associated with key in the HashMap. If key is not already in the map, - /// a new HashSet will first be created. - /// @return the size of the HashSet associated with key once val is added to it. - int32_t put(MAPKEY key, SETVALUE val) - { - typename map_type::iterator entry = theMap.find(key); - if (entry != theMap.end()) - { - entry->second.add(val); - return entry->second.size(); - } - else - { - set_type theSet(set_type::newInstance()); - theSet.add(val); - theMap.put(key, theSet); - return 1; - } +public: + /// @return direct access to the map backing this object. + map_type getMap() { + return theMap; + } + + /// Adds val to the HashSet associated with key in the HashMap. If key is not already in the map, + /// a new HashSet will first be created. + /// @return the size of the HashSet associated with key once val is added to it. + int32_t put(MAPKEY key, SETVALUE val) { + typename map_type::iterator entry = theMap.find(key); + if (entry != theMap.end()) { + entry->second.add(val); + return entry->second.size(); + } else { + set_type theSet(set_type::newInstance()); + theSet.add(val); + theMap.put(key, theSet); + return 1; } + } - /// Adds multiple vals to the HashSet associated with key in the HashMap. If key is not already in - /// the map, a new HashSet will first be created. - /// @return the size of the HashSet associated with key once val is added to it. - int32_t putAll(MAPKEY key, set_type vals) - { - typename map_type::iterator entry = theMap.find(key); - if (entry != theMap.end()) - { - entry->second.addAll(vals.begin(), vals.end()); - return entry->second.size(); - } - else - { - set_type theSet(set_type::newInstance(vals.begin(), vals.end())); - theMap.put(key, theSet); - return theSet.size(); - } + /// Adds multiple vals to the HashSet associated with key in the HashMap. If key is not already in + /// the map, a new HashSet will first be created. + /// @return the size of the HashSet associated with key once val is added to it. + int32_t putAll(MAPKEY key, set_type vals) { + typename map_type::iterator entry = theMap.find(key); + if (entry != theMap.end()) { + entry->second.addAll(vals.begin(), vals.end()); + return entry->second.size(); + } else { + set_type theSet(set_type::newInstance(vals.begin(), vals.end())); + theMap.put(key, theSet); + return theSet.size(); } - }; + } +}; + } #endif diff --git a/include/MappingCharFilter.h b/include/MappingCharFilter.h index 8871f559..26f530a2 100644 --- a/include/MappingCharFilter.h +++ b/include/MappingCharFilter.h @@ -9,40 +9,40 @@ #include "BaseCharFilter.h" -namespace Lucene -{ - /// Simplistic {@link CharFilter} that applies the mappings contained in a {@link NormalizeCharMap} to the character - /// stream, and correcting the resulting changes to the offsets. - class LPPAPI MappingCharFilter : public BaseCharFilter - { - public: - /// Default constructor that takes a {@link CharStream}. - MappingCharFilter(const NormalizeCharMapPtr& normMap, const CharStreamPtr& in); - - /// Easy-use constructor that takes a {@link Reader}. - MappingCharFilter(const NormalizeCharMapPtr& normMap, const ReaderPtr& in); - - virtual ~MappingCharFilter(); - - LUCENE_CLASS(MappingCharFilter); - - protected: - NormalizeCharMapPtr normMap; - Collection buffer; - String replacement; - int32_t charPointer; - int32_t nextCharCounter; - - public: - virtual int32_t read(); - virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - - protected: - int32_t nextChar(); - void pushChar(int32_t c); - void pushLastChar(int32_t c); - NormalizeCharMapPtr match(const NormalizeCharMapPtr& map); - }; +namespace Lucene { + +/// Simplistic {@link CharFilter} that applies the mappings contained in a {@link NormalizeCharMap} to the character +/// stream, and correcting the resulting changes to the offsets. +class LPPAPI MappingCharFilter : public BaseCharFilter { +public: + /// Default constructor that takes a {@link CharStream}. + MappingCharFilter(const NormalizeCharMapPtr& normMap, const CharStreamPtr& in); + + /// Easy-use constructor that takes a {@link Reader}. + MappingCharFilter(const NormalizeCharMapPtr& normMap, const ReaderPtr& in); + + virtual ~MappingCharFilter(); + + LUCENE_CLASS(MappingCharFilter); + +protected: + NormalizeCharMapPtr normMap; + Collection buffer; + String replacement; + int32_t charPointer; + int32_t nextCharCounter; + +public: + virtual int32_t read(); + virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); + +protected: + int32_t nextChar(); + void pushChar(int32_t c); + void pushLastChar(int32_t c); + NormalizeCharMapPtr match(const NormalizeCharMapPtr& map); +}; + } #endif diff --git a/include/MatchAllDocsQuery.h b/include/MatchAllDocsQuery.h index 8a7ada97..1985fb4f 100644 --- a/include/MatchAllDocsQuery.h +++ b/include/MatchAllDocsQuery.h @@ -9,34 +9,34 @@ #include "Query.h" -namespace Lucene -{ - /// A query that matches all documents. - class LPPAPI MatchAllDocsQuery : public Query - { - public: - /// @param normsField Field used for normalization factor (document boost). Null if nothing. - MatchAllDocsQuery(const String& normsField = EmptyString); - - virtual ~MatchAllDocsQuery(); - - LUCENE_CLASS(MatchAllDocsQuery); - - protected: - String normsField; - - public: - using Query::toString; - - virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual void extractTerms(SetTerm terms); - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - friend class MatchAllDocsWeight; - }; +namespace Lucene { + +/// A query that matches all documents. +class LPPAPI MatchAllDocsQuery : public Query { +public: + /// @param normsField Field used for normalization factor (document boost). Null if nothing. + MatchAllDocsQuery(const String& normsField = EmptyString); + + virtual ~MatchAllDocsQuery(); + + LUCENE_CLASS(MatchAllDocsQuery); + +protected: + String normsField; + +public: + using Query::toString; + + virtual WeightPtr createWeight(const SearcherPtr& searcher); + virtual void extractTerms(SetTerm terms); + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + friend class MatchAllDocsWeight; +}; + } #endif diff --git a/include/MaxPayloadFunction.h b/include/MaxPayloadFunction.h index 80580c32..cd95085b 100644 --- a/include/MaxPayloadFunction.h +++ b/include/MaxPayloadFunction.h @@ -9,24 +9,24 @@ #include "PayloadFunction.h" -namespace Lucene -{ - /// Returns the maximum payload score seen, else 1 if there are no payloads on the doc. - /// - /// Is thread safe and completely reusable. - class LPPAPI MaxPayloadFunction : public PayloadFunction - { - public: - virtual ~MaxPayloadFunction(); - LUCENE_CLASS(MaxPayloadFunction); +namespace Lucene { + +/// Returns the maximum payload score seen, else 1 if there are no payloads on the doc. +/// +/// Is thread safe and completely reusable. +class LPPAPI MaxPayloadFunction : public PayloadFunction { +public: + virtual ~MaxPayloadFunction(); + LUCENE_CLASS(MaxPayloadFunction); + +public: + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + double currentScore, double currentPayloadScore); + virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); +}; - public: - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, - double currentScore, double currentPayloadScore); - virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - }; } #endif diff --git a/include/MergeDocIDRemapper.h b/include/MergeDocIDRemapper.h index 6c1a2630..4c48ee33 100644 --- a/include/MergeDocIDRemapper.h +++ b/include/MergeDocIDRemapper.h @@ -9,30 +9,30 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Remaps docIDs after a merge has completed, where the merged segments had at least one deletion. - /// This is used to renumber the buffered deletes in IndexWriter when a merge of segments with deletions - /// commits. - class MergeDocIDRemapper : public LuceneObject - { - public: - MergeDocIDRemapper(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount); - virtual ~MergeDocIDRemapper(); - - LUCENE_CLASS(MergeDocIDRemapper); - - public: - Collection starts; // used for binary search of mapped docID - Collection newStarts; // starts, minus the deletes - Collection< Collection > docMaps; // maps docIDs in the merged set - int32_t minDocID; // minimum docID that needs renumbering - int32_t maxDocID; // 1+ the max docID that needs renumbering - int32_t docShift; // total # deleted docs that were compacted by this merge - - public: - int32_t remap(int32_t oldDocID); - }; +namespace Lucene { + +/// Remaps docIDs after a merge has completed, where the merged segments had at least one deletion. +/// This is used to renumber the buffered deletes in IndexWriter when a merge of segments with deletions +/// commits. +class MergeDocIDRemapper : public LuceneObject { +public: + MergeDocIDRemapper(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount); + virtual ~MergeDocIDRemapper(); + + LUCENE_CLASS(MergeDocIDRemapper); + +public: + Collection starts; // used for binary search of mapped docID + Collection newStarts; // starts, minus the deletes + Collection< Collection > docMaps; // maps docIDs in the merged set + int32_t minDocID; // minimum docID that needs renumbering + int32_t maxDocID; // 1+ the max docID that needs renumbering + int32_t docShift; // total # deleted docs that were compacted by this merge + +public: + int32_t remap(int32_t oldDocID); +}; + } #endif diff --git a/include/MergePolicy.h b/include/MergePolicy.h index 71b803bc..e06da3e1 100644 --- a/include/MergePolicy.h +++ b/include/MergePolicy.h @@ -9,130 +9,128 @@ #include "SegmentInfos.h" -namespace Lucene -{ - /// A MergePolicy determines the sequence of primitive merge operations to be used for overall merge - /// and optimize operations. - /// - /// Whenever the segments in an index have been altered by {@link IndexWriter}, either the addition of - /// a newly flushed segment, addition of many segments from addIndexes* calls, or a previous merge that - /// may now need to cascade, {@link IndexWriter} invokes {@link #findMerges} to give the MergePolicy a - /// chance to pick merges that are now required. This method returns a {@link MergeSpecification} - /// instance describing the set of merges that should be done, or null if no merges are necessary. - /// When IndexWriter.optimize is called, it calls {@link #findMergesForOptimize} and the MergePolicy - /// should then return the necessary merges. - /// - /// Note that the policy can return more than one merge at a time. In this case, if the writer is using - /// {@link SerialMergeScheduler}, the merges will be run sequentially but if it is using {@link - /// ConcurrentMergeScheduler} they will be run concurrently. - /// - /// The default MergePolicy is {@link LogByteSizeMergePolicy}. - /// - /// NOTE: This API is new and still experimental (subject to change suddenly in the next release) - class LPPAPI MergePolicy : public LuceneObject - { - public: - MergePolicy(const IndexWriterPtr& writer); - virtual ~MergePolicy(); - - LUCENE_CLASS(MergePolicy); - - protected: - IndexWriterWeakPtr _writer; - - public: - /// Determine what set of merge operations are now necessary on the index. {@link IndexWriter} calls - /// this whenever there is a change to the segments. This call is always synchronized on the {@link - /// IndexWriter} instance so only one thread at a time will call this method. - /// @param segmentInfos the total set of segments in the index - virtual MergeSpecificationPtr findMerges(const SegmentInfosPtr& segmentInfos) = 0; - - /// Determine what set of merge operations is necessary in order to optimize the index. {@link - /// IndexWriter} calls this when its {@link IndexWriter#optimize()} method is called. This call is - /// always synchronized on the {@link IndexWriter} instance so only one thread at a time will call - /// this method. - /// @param segmentInfos the total set of segments in the index - /// @param maxSegmentCount requested maximum number of segments in the index (currently this is always 1) - /// @param segmentsToOptimize contains the specific SegmentInfo instances that must be merged away. - /// This may be a subset of all SegmentInfos. - virtual MergeSpecificationPtr findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) = 0; - - /// Determine what set of merge operations is necessary in order to expunge all deletes from the index. - /// @param segmentInfos the total set of segments in the index - virtual MergeSpecificationPtr findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos) = 0; - - /// Release all resources for the policy. - virtual void close() = 0; - - /// Returns true if a newly flushed (not from merge) segment should use the compound file format. - virtual bool useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment) = 0; - - /// Returns true if the doc store files should use the compound file format. - virtual bool useCompoundDocStore(const SegmentInfosPtr& segments) = 0; - }; - - /// OneMerge provides the information necessary to perform an individual primitive merge operation, - /// resulting in a single new segment. The merge spec includes the subset of segments to be merged - /// as well as whether the new segment should use the compound file format. - class LPPAPI OneMerge : public LuceneObject - { - public: - OneMerge(const SegmentInfosPtr& segments, bool useCompoundFile); - virtual ~OneMerge(); - - LUCENE_CLASS(OneMerge); - - public: - SegmentInfoPtr info; // used by IndexWriter - bool mergeDocStores; // used by IndexWriter - bool optimize; // used by IndexWriter - bool registerDone; // used by IndexWriter - int64_t mergeGen; // used by IndexWriter - bool isExternal; // used by IndexWriter - int32_t maxNumSegmentsOptimize; // used by IndexWriter - Collection readers; // used by IndexWriter - Collection readersClone; // used by IndexWriter - - SegmentInfosPtr segments; - bool useCompoundFile; - bool aborted; - LuceneException error; - - public: - /// Record that an exception occurred while executing this merge - void setException(const LuceneException& error); - - /// Retrieve previous exception set by {@link #setException}. - LuceneException getException(); - - /// Mark this merge as aborted. If this is called before the merge is committed then the merge will not be committed. - void abort(); - - /// Returns true if this merge was aborted. - bool isAborted(); - - void checkAborted(const DirectoryPtr& dir); - - String segString(const DirectoryPtr& dir); - }; - - /// A MergeSpecification instance provides the information necessary to perform multiple merges. - /// It simply contains a list of {@link OneMerge} instances. - class LPPAPI MergeSpecification : public LuceneObject - { - public: - MergeSpecification(); - virtual ~MergeSpecification(); - - LUCENE_CLASS(MergeSpecification); - - public: - Collection merges; - - public: - void add(const OneMergePtr& merge); - String segString(const DirectoryPtr& dir); - }; +namespace Lucene { + +/// A MergePolicy determines the sequence of primitive merge operations to be used for overall merge +/// and optimize operations. +/// +/// Whenever the segments in an index have been altered by {@link IndexWriter}, either the addition of +/// a newly flushed segment, addition of many segments from addIndexes* calls, or a previous merge that +/// may now need to cascade, {@link IndexWriter} invokes {@link #findMerges} to give the MergePolicy a +/// chance to pick merges that are now required. This method returns a {@link MergeSpecification} +/// instance describing the set of merges that should be done, or null if no merges are necessary. +/// When IndexWriter.optimize is called, it calls {@link #findMergesForOptimize} and the MergePolicy +/// should then return the necessary merges. +/// +/// Note that the policy can return more than one merge at a time. In this case, if the writer is using +/// {@link SerialMergeScheduler}, the merges will be run sequentially but if it is using {@link +/// ConcurrentMergeScheduler} they will be run concurrently. +/// +/// The default MergePolicy is {@link LogByteSizeMergePolicy}. +/// +/// NOTE: This API is new and still experimental (subject to change suddenly in the next release) +class LPPAPI MergePolicy : public LuceneObject { +public: + MergePolicy(const IndexWriterPtr& writer); + virtual ~MergePolicy(); + + LUCENE_CLASS(MergePolicy); + +protected: + IndexWriterWeakPtr _writer; + +public: + /// Determine what set of merge operations are now necessary on the index. {@link IndexWriter} calls + /// this whenever there is a change to the segments. This call is always synchronized on the {@link + /// IndexWriter} instance so only one thread at a time will call this method. + /// @param segmentInfos the total set of segments in the index + virtual MergeSpecificationPtr findMerges(const SegmentInfosPtr& segmentInfos) = 0; + + /// Determine what set of merge operations is necessary in order to optimize the index. {@link + /// IndexWriter} calls this when its {@link IndexWriter#optimize()} method is called. This call is + /// always synchronized on the {@link IndexWriter} instance so only one thread at a time will call + /// this method. + /// @param segmentInfos the total set of segments in the index + /// @param maxSegmentCount requested maximum number of segments in the index (currently this is always 1) + /// @param segmentsToOptimize contains the specific SegmentInfo instances that must be merged away. + /// This may be a subset of all SegmentInfos. + virtual MergeSpecificationPtr findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) = 0; + + /// Determine what set of merge operations is necessary in order to expunge all deletes from the index. + /// @param segmentInfos the total set of segments in the index + virtual MergeSpecificationPtr findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos) = 0; + + /// Release all resources for the policy. + virtual void close() = 0; + + /// Returns true if a newly flushed (not from merge) segment should use the compound file format. + virtual bool useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment) = 0; + + /// Returns true if the doc store files should use the compound file format. + virtual bool useCompoundDocStore(const SegmentInfosPtr& segments) = 0; +}; + +/// OneMerge provides the information necessary to perform an individual primitive merge operation, +/// resulting in a single new segment. The merge spec includes the subset of segments to be merged +/// as well as whether the new segment should use the compound file format. +class LPPAPI OneMerge : public LuceneObject { +public: + OneMerge(const SegmentInfosPtr& segments, bool useCompoundFile); + virtual ~OneMerge(); + + LUCENE_CLASS(OneMerge); + +public: + SegmentInfoPtr info; // used by IndexWriter + bool mergeDocStores; // used by IndexWriter + bool optimize; // used by IndexWriter + bool registerDone; // used by IndexWriter + int64_t mergeGen; // used by IndexWriter + bool isExternal; // used by IndexWriter + int32_t maxNumSegmentsOptimize; // used by IndexWriter + Collection readers; // used by IndexWriter + Collection readersClone; // used by IndexWriter + + SegmentInfosPtr segments; + bool useCompoundFile; + bool aborted; + LuceneException error; + +public: + /// Record that an exception occurred while executing this merge + void setException(const LuceneException& error); + + /// Retrieve previous exception set by {@link #setException}. + LuceneException getException(); + + /// Mark this merge as aborted. If this is called before the merge is committed then the merge will not be committed. + void abort(); + + /// Returns true if this merge was aborted. + bool isAborted(); + + void checkAborted(const DirectoryPtr& dir); + + String segString(const DirectoryPtr& dir); +}; + +/// A MergeSpecification instance provides the information necessary to perform multiple merges. +/// It simply contains a list of {@link OneMerge} instances. +class LPPAPI MergeSpecification : public LuceneObject { +public: + MergeSpecification(); + virtual ~MergeSpecification(); + + LUCENE_CLASS(MergeSpecification); + +public: + Collection merges; + +public: + void add(const OneMergePtr& merge); + String segString(const DirectoryPtr& dir); +}; + } #endif diff --git a/include/MergeScheduler.h b/include/MergeScheduler.h index 65a20e75..7034ab0e 100644 --- a/include/MergeScheduler.h +++ b/include/MergeScheduler.h @@ -9,24 +9,24 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// {@link IndexWriter} uses an instance implementing this interface to execute the merges - /// selected by a {@link MergePolicy}. The default MergeScheduler is {@link ConcurrentMergeScheduler}. - class LPPAPI MergeScheduler : public LuceneObject - { - public: - virtual ~MergeScheduler(); - - LUCENE_CLASS(MergeScheduler); - - public: - /// Run the merges provided by {@link IndexWriter#getNextMerge()}. - virtual void merge(const IndexWriterPtr& writer) = 0; - - /// Close this MergeScheduler. - virtual void close() = 0; - }; +namespace Lucene { + +/// {@link IndexWriter} uses an instance implementing this interface to execute the merges +/// selected by a {@link MergePolicy}. The default MergeScheduler is {@link ConcurrentMergeScheduler}. +class LPPAPI MergeScheduler : public LuceneObject { +public: + virtual ~MergeScheduler(); + + LUCENE_CLASS(MergeScheduler); + +public: + /// Run the merges provided by {@link IndexWriter#getNextMerge()}. + virtual void merge(const IndexWriterPtr& writer) = 0; + + /// Close this MergeScheduler. + virtual void close() = 0; +}; + } #endif diff --git a/include/MinPayloadFunction.h b/include/MinPayloadFunction.h index 891eaa73..831d9191 100644 --- a/include/MinPayloadFunction.h +++ b/include/MinPayloadFunction.h @@ -9,22 +9,22 @@ #include "PayloadFunction.h" -namespace Lucene -{ - /// Calculates the minimum payload seen - class LPPAPI MinPayloadFunction : public PayloadFunction - { - public: - virtual ~MinPayloadFunction(); - LUCENE_CLASS(MinPayloadFunction); +namespace Lucene { + +/// Calculates the minimum payload seen +class LPPAPI MinPayloadFunction : public PayloadFunction { +public: + virtual ~MinPayloadFunction(); + LUCENE_CLASS(MinPayloadFunction); + +public: + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + double currentScore, double currentPayloadScore); + virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); +}; - public: - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, - double currentScore, double currentPayloadScore); - virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - }; } #endif diff --git a/include/MiscUtils.h b/include/MiscUtils.h index 56339a50..06286bd5 100644 --- a/include/MiscUtils.h +++ b/include/MiscUtils.h @@ -9,134 +9,129 @@ #include "Lucene.h" -namespace Lucene -{ - class LPPAPI MiscUtils - { - protected: - static const uint32_t SINGLE_EXPONENT_MASK; - static const uint32_t SINGLE_MANTISSA_MASK; - static const uint32_t SINGLE_NAN_BITS; - - static const uint64_t DOUBLE_SIGN_MASK; - static const uint64_t DOUBLE_EXPONENT_MASK; - static const uint64_t DOUBLE_MANTISSA_MASK; - static const uint64_t DOUBLE_NAN_BITS; - - public: - /// Return given time in milliseconds. - static uint64_t getTimeMillis(boost::posix_time::ptime time); - - /// Returns the current time in milliseconds. - static uint64_t currentTimeMillis(); - - /// 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(). - /// The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... - static int32_t getNextSize(int32_t targetSize); - - /// Only reallocate if we are "substantially" smaller. This saves us from "running hot" (constantly - /// making a bit bigger then a bit smaller, over and over) - static int32_t getShrinkSize(int32_t currentSize, int32_t targetSize); - - /// Compares two byte[] arrays, element by element, and returns the number of elements common to - /// both arrays. - /// @param bytes1 The first byte[] to compare - /// @param bytes2 The second byte[] to compare - /// @return The number of common elements. - static int32_t bytesDifference(uint8_t* bytes1, int32_t len1, uint8_t* bytes2, int32_t len2); - - template - static int32_t hashLucene(TYPE type) - { - return type->hashCode(); +namespace Lucene { + +class LPPAPI MiscUtils { +protected: + static const uint32_t SINGLE_EXPONENT_MASK; + static const uint32_t SINGLE_MANTISSA_MASK; + static const uint32_t SINGLE_NAN_BITS; + + static const uint64_t DOUBLE_SIGN_MASK; + static const uint64_t DOUBLE_EXPONENT_MASK; + static const uint64_t DOUBLE_MANTISSA_MASK; + static const uint64_t DOUBLE_NAN_BITS; + +public: + /// Return given time in milliseconds. + static uint64_t getTimeMillis(boost::posix_time::ptime time); + + /// Returns the current time in milliseconds. + static uint64_t currentTimeMillis(); + + /// 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(). + /// The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... + static int32_t getNextSize(int32_t targetSize); + + /// Only reallocate if we are "substantially" smaller. This saves us from "running hot" (constantly + /// making a bit bigger then a bit smaller, over and over) + static int32_t getShrinkSize(int32_t currentSize, int32_t targetSize); + + /// Compares two byte[] arrays, element by element, and returns the number of elements common to + /// both arrays. + /// @param bytes1 The first byte[] to compare + /// @param bytes2 The second byte[] to compare + /// @return The number of common elements. + static int32_t bytesDifference(uint8_t* bytes1, int32_t len1, uint8_t* bytes2, int32_t len2); + + template + static int32_t hashLucene(TYPE type) { + return type->hashCode(); + } + + template + static int32_t hashNumeric(TYPE type) { + return type; + } + + template + static int32_t hashCode(ITER first, ITER last, PRED pred) { + int32_t code = 0; + for (ITER hash = first; hash != last; ++hash) { + code = code * 31 + pred(*hash); } + return code; + } - template - static int32_t hashNumeric(TYPE type) - { - return type; - } - - template - static int32_t hashCode(ITER first, ITER last, PRED pred) - { - int32_t code = 0; - for (ITER hash = first; hash != last; ++hash) - code = code * 31 + pred(*hash); - return code; - } + /// Returns hash of chars in range start (inclusive) to end (inclusive) + static int32_t hashCode(const wchar_t* array, int32_t start, int32_t end); - /// Returns hash of chars in range start (inclusive) to end (inclusive) - static int32_t hashCode(const wchar_t* array, int32_t start, int32_t end); + /// Returns hash of bytes in range start (inclusive) to end (inclusive) + static int32_t hashCode(const uint8_t* array, int32_t start, int32_t end); - /// Returns hash of bytes in range start (inclusive) to end (inclusive) - static int32_t hashCode(const uint8_t* array, int32_t start, int32_t end); + /// Returns hash code of given boolean + static int32_t hashCode(bool value); - /// Returns hash code of given boolean - static int32_t hashCode(bool value); + /// Copy elements from on buffer to another + template + static void arrayCopy(SOURCE source, int32_t sourceOffset, DEST dest, int32_t destOffset, int32_t length) { + std::copy(source + sourceOffset, source + sourceOffset + length, dest + destOffset); + } - /// Copy elements from on buffer to another - template - static void arrayCopy(SOURCE source, int32_t sourceOffset, DEST dest, int32_t destOffset, int32_t length) - { - std::copy(source + sourceOffset, source + sourceOffset + length, dest + destOffset); - } + /// Fill buffer with given element + template + static void arrayFill(DEST dest, int32_t destFrom, int32_t destTo, FILL value) { + std::fill(dest + destFrom, dest + destTo, value); + } - /// Fill buffer with given element - template - static void arrayFill(DEST dest, int32_t destFrom, int32_t destTo, FILL value) - { - std::fill(dest + destFrom, dest + destTo, value); - } + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "single format" bit layout. + static int32_t doubleToIntBits(double value); - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "single format" bit layout. - static int32_t doubleToIntBits(double value); + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "single format" bit layout, preserving Not-a-Number (NaN) values. + static int32_t doubleToRawIntBits(double value); - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "single format" bit layout, preserving Not-a-Number (NaN) values. - static int32_t doubleToRawIntBits(double value); + /// Returns the float value corresponding to a given bit representation. The argument is considered to be a + /// representation of a floating-point value according to the IEEE 754 floating-point "single format" bit layout. + static double intBitsToDouble(int32_t bits); - /// Returns the float value corresponding to a given bit representation. The argument is considered to be a - /// representation of a floating-point value according to the IEEE 754 floating-point "single format" bit layout. - static double intBitsToDouble(int32_t bits); + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "double format" bit layout. + static int64_t doubleToLongBits(double value); - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "double format" bit layout. - static int64_t doubleToLongBits(double value); + /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point + /// "double format" bit layout, preserving Not-a-Number (NaN) values. + static int64_t doubleToRawLongBits(double value); - /// Returns a representation of the specified floating-point value according to the IEEE 754 floating-point - /// "double format" bit layout, preserving Not-a-Number (NaN) values. - static int64_t doubleToRawLongBits(double value); + /// Returns the double value corresponding to a given bit representation. The argument is considered to be a + /// representation of a floating-point value according to the IEEE 754 floating-point "double format" bit layout. + static double longBitsToDouble(int64_t bits); - /// Returns the double value corresponding to a given bit representation. The argument is considered to be a - /// representation of a floating-point value according to the IEEE 754 floating-point "double format" bit layout. - static double longBitsToDouble(int64_t bits); + /// Returns true if the specified number is infinitely large in magnitude, false otherwise. + static bool isInfinite(double value); - /// Returns true if the specified number is infinitely large in magnitude, false otherwise. - static bool isInfinite(double value); + /// Returns true if this Double value is a Not-a-Number (NaN), false otherwise. + static bool isNaN(double value); - /// Returns true if this Double value is a Not-a-Number (NaN), false otherwise. - static bool isNaN(double value); + /// Return whether given Lucene object is of a specified type + template + static bool typeOf(const LuceneObjectPtr& object) { + return boost::dynamic_pointer_cast(object).get() != NULL; + } - /// Return whether given Lucene object is of a specified type - template - static bool typeOf(const LuceneObjectPtr& object) - { - return boost::dynamic_pointer_cast(object).get() != NULL; - } + /// Return whether given Lucene objects are of equal type. + static bool equalTypes(const LuceneObjectPtr& first, const LuceneObjectPtr& second); - /// Return whether given Lucene objects are of equal type. - static bool equalTypes(const LuceneObjectPtr& first, const LuceneObjectPtr& second); + /// Perform unsigned right-shift (left bits are zero filled) + static int64_t unsignedShift(int64_t num, int64_t shift); - /// Perform unsigned right-shift (left bits are zero filled) - static int64_t unsignedShift(int64_t num, int64_t shift); + /// Perform unsigned right-shift (left bits are zero filled) + static int32_t unsignedShift(int32_t num, int32_t shift); +}; - /// Perform unsigned right-shift (left bits are zero filled) - static int32_t unsignedShift(int32_t num, int32_t shift); - }; } #endif diff --git a/include/MultiFieldQueryParser.h b/include/MultiFieldQueryParser.h index dfa4a3e6..9c4c4aae 100644 --- a/include/MultiFieldQueryParser.h +++ b/include/MultiFieldQueryParser.h @@ -10,129 +10,129 @@ #include "QueryParser.h" #include "BooleanClause.h" -namespace Lucene -{ - /// A QueryParser which constructs queries to search multiple fields. - class LPPAPI MultiFieldQueryParser : public QueryParser - { - public: - /// Creates a MultiFieldQueryParser. Allows passing of a map with term to Boost, and the boost to - /// apply to each term. - /// - /// It will, when parse(String query) is called, construct a query like this (assuming the query - /// consists of two terms and you specify the two fields title and body): - ///
      -        /// (title:term1 body:term1) (title:term2 body:term2)
      -        /// 
      - /// - /// When setDefaultOperator(AND_OPERATOR) is set, the result will be: - ///
      -        /// +(title:term1 body:term1) +(title:term2 body:term2)
      -        /// 
      - /// - /// When you pass a boost (title=>5 body=>10) you can get: - ///
      -        /// +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
      -        /// 
      - /// - /// In other words, all the query's terms must appear, but it doesn't matter in what fields they - /// appear. - MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer, MapStringDouble boosts); - - /// Creates a MultiFieldQueryParser. It will, when parse(String query) is called, construct a - /// query like this (assuming the query consists of two terms and you specify the two fields - /// title and body): - ///
      -        /// (title:term1 body:term1) (title:term2 body:term2)
      -        /// 
      - /// - /// When setDefaultOperator(AND_OPERATOR) is set, the result will be: - ///
      -        /// +(title:term1 body:term1) +(title:term2 body:term2)
      -        /// 
      - /// - /// In other words, all the query's terms must appear, but it doesn't matter in what fields they - /// appear. - MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer); - - virtual ~MultiFieldQueryParser(); - - LUCENE_CLASS(MultiFieldQueryParser); - - protected: - Collection fields; - MapStringDouble boosts; - - public: - using QueryParser::parse; - - /// Parses a query which searches on the fields specified. - /// - /// If x fields are specified, this effectively constructs: - ///
      -        /// (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
      -        /// 
      - /// @param matchVersion Lucene version to match; this is passed through to QueryParser. - /// @param queries Queries strings to parse - /// @param fields Fields to search on - /// @param analyzer Analyzer to use - static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, const AnalyzerPtr& analyzer); - - /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as - /// required, and others as prohibited. - /// - ///
      -        /// Usage:
      -        /// Collection fields = newCollection(L"filename", L"contents", L"description");
      -        /// Collection flags = newCollection(BooleanClause::SHOULD, BooleanClause::MUST, BooleanClause::MUST_NOT);
      -        /// MultiFieldQueryParser::parse(L"query", fields, flags, analyzer);
      -        /// 
      - /// - /// The code above would construct a query: - ///
      -        /// (filename:query) +(contents:query) -(description:query)
      -        /// 
      - /// - /// @param matchVersion Lucene version to match; this is passed through to QueryParser. - /// @param query Query string to parse - /// @param fields Fields to search on - /// @param flags Flags describing the fields - /// @param analyzer Analyzer to use - static QueryPtr parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, const AnalyzerPtr& analyzer); - - /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as - /// required, and others as prohibited. - /// - ///
      -        /// Usage:
      -        /// Collection query = newCollection(L"query1", L"query2", L"query3");
      -        /// Collection fields = newCollection(L"filename", L"contents", L"description");
      -        /// Collection flags = newCollection(BooleanClause::SHOULD, BooleanClause::MUST, BooleanClause::MUST_NOT);
      -        /// MultiFieldQueryParser::parse(query, fields, flags, analyzer);
      -        /// 
      - /// - /// The code above would construct a query: - ///
      -        /// (filename:query1) +(contents:query2) -(description:query3)
      -        /// 
      - /// - /// @param matchVersion Lucene version to match; this is passed through to QueryParser. - /// @param queries Queries string to parse - /// @param fields Fields to search on - /// @param flags Flags describing the fields - /// @param analyzer Analyzer to use - static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, const AnalyzerPtr& analyzer); - - protected: - virtual QueryPtr getFieldQuery(const String& field, const String& queryText, int32_t slop); - virtual QueryPtr getFieldQuery(const String& field, const String& queryText); - void applySlop(const QueryPtr& query, int32_t slop); - - virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity); - virtual QueryPtr getPrefixQuery(const String& field, const String& termStr); - virtual QueryPtr getWildcardQuery(const String& field, const String& termStr); - virtual QueryPtr getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); - }; +namespace Lucene { + +/// A QueryParser which constructs queries to search multiple fields. +class LPPAPI MultiFieldQueryParser : public QueryParser { +public: + /// Creates a MultiFieldQueryParser. Allows passing of a map with term to Boost, and the boost to + /// apply to each term. + /// + /// It will, when parse(String query) is called, construct a query like this (assuming the query + /// consists of two terms and you specify the two fields title and body): + ///
      +    /// (title:term1 body:term1) (title:term2 body:term2)
      +    /// 
      + /// + /// When setDefaultOperator(AND_OPERATOR) is set, the result will be: + ///
      +    /// +(title:term1 body:term1) +(title:term2 body:term2)
      +    /// 
      + /// + /// When you pass a boost (title=>5 body=>10) you can get: + ///
      +    /// +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
      +    /// 
      + /// + /// In other words, all the query's terms must appear, but it doesn't matter in what fields they + /// appear. + MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer, MapStringDouble boosts); + + /// Creates a MultiFieldQueryParser. It will, when parse(String query) is called, construct a + /// query like this (assuming the query consists of two terms and you specify the two fields + /// title and body): + ///
      +    /// (title:term1 body:term1) (title:term2 body:term2)
      +    /// 
      + /// + /// When setDefaultOperator(AND_OPERATOR) is set, the result will be: + ///
      +    /// +(title:term1 body:term1) +(title:term2 body:term2)
      +    /// 
      + /// + /// In other words, all the query's terms must appear, but it doesn't matter in what fields they + /// appear. + MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer); + + virtual ~MultiFieldQueryParser(); + + LUCENE_CLASS(MultiFieldQueryParser); + +protected: + Collection fields; + MapStringDouble boosts; + +public: + using QueryParser::parse; + + /// Parses a query which searches on the fields specified. + /// + /// If x fields are specified, this effectively constructs: + ///
      +    /// (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
      +    /// 
      + /// @param matchVersion Lucene version to match; this is passed through to QueryParser. + /// @param queries Queries strings to parse + /// @param fields Fields to search on + /// @param analyzer Analyzer to use + static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, const AnalyzerPtr& analyzer); + + /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as + /// required, and others as prohibited. + /// + ///
      +    /// Usage:
      +    /// Collection fields = newCollection(L"filename", L"contents", L"description");
      +    /// Collection flags = newCollection(BooleanClause::SHOULD, BooleanClause::MUST, BooleanClause::MUST_NOT);
      +    /// MultiFieldQueryParser::parse(L"query", fields, flags, analyzer);
      +    /// 
      + /// + /// The code above would construct a query: + ///
      +    /// (filename:query) +(contents:query) -(description:query)
      +    /// 
      + /// + /// @param matchVersion Lucene version to match; this is passed through to QueryParser. + /// @param query Query string to parse + /// @param fields Fields to search on + /// @param flags Flags describing the fields + /// @param analyzer Analyzer to use + static QueryPtr parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, const AnalyzerPtr& analyzer); + + /// Parses a query, searching on the fields specified. Use this if you need to specify certain fields as + /// required, and others as prohibited. + /// + ///
      +    /// Usage:
      +    /// Collection query = newCollection(L"query1", L"query2", L"query3");
      +    /// Collection fields = newCollection(L"filename", L"contents", L"description");
      +    /// Collection flags = newCollection(BooleanClause::SHOULD, BooleanClause::MUST, BooleanClause::MUST_NOT);
      +    /// MultiFieldQueryParser::parse(query, fields, flags, analyzer);
      +    /// 
      + /// + /// The code above would construct a query: + ///
      +    /// (filename:query1) +(contents:query2) -(description:query3)
      +    /// 
      + /// + /// @param matchVersion Lucene version to match; this is passed through to QueryParser. + /// @param queries Queries string to parse + /// @param fields Fields to search on + /// @param flags Flags describing the fields + /// @param analyzer Analyzer to use + static QueryPtr parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, const AnalyzerPtr& analyzer); + +protected: + virtual QueryPtr getFieldQuery(const String& field, const String& queryText, int32_t slop); + virtual QueryPtr getFieldQuery(const String& field, const String& queryText); + void applySlop(const QueryPtr& query, int32_t slop); + + virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity); + virtual QueryPtr getPrefixQuery(const String& field, const String& termStr); + virtual QueryPtr getWildcardQuery(const String& field, const String& termStr); + virtual QueryPtr getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); +}; + } #endif diff --git a/include/MultiLevelSkipListReader.h b/include/MultiLevelSkipListReader.h index 324f8e92..ab8246b0 100644 --- a/include/MultiLevelSkipListReader.h +++ b/include/MultiLevelSkipListReader.h @@ -9,115 +9,114 @@ #include "IndexInput.h" -namespace Lucene -{ - /// This abstract class reads skip lists with multiple levels. - /// - /// See {@link MultiLevelSkipListWriter} for the information about the encoding of the multi level skip lists. - /// - /// Subclasses must implement the abstract method {@link #readSkipData(int, IndexInput)} which defines the - /// actual format of the skip data. - class MultiLevelSkipListReader : public LuceneObject - { - public: - MultiLevelSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval); - virtual ~MultiLevelSkipListReader(); +namespace Lucene { + +/// This abstract class reads skip lists with multiple levels. +/// +/// See {@link MultiLevelSkipListWriter} for the information about the encoding of the multi level skip lists. +/// +/// Subclasses must implement the abstract method {@link #readSkipData(int, IndexInput)} which defines the +/// actual format of the skip data. +class MultiLevelSkipListReader : public LuceneObject { +public: + MultiLevelSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval); + virtual ~MultiLevelSkipListReader(); - LUCENE_CLASS(MultiLevelSkipListReader); + LUCENE_CLASS(MultiLevelSkipListReader); - protected: - /// the maximum number of skip levels possible for this index - int32_t maxNumberOfSkipLevels; +protected: + /// the maximum number of skip levels possible for this index + int32_t maxNumberOfSkipLevels; - /// number of levels in this skip list - int32_t numberOfSkipLevels; + /// number of levels in this skip list + int32_t numberOfSkipLevels; - /// Defines the number of top skip levels to buffer in memory. Reducing this number results in less - /// memory usage, but possibly slower performance due to more random I/Os. Please notice that the space - /// each level occupies is limited by the skipInterval. The top level can not contain more than - /// skipLevel entries, the second top level can not contain more than skipLevel^2 entries and so forth. - int32_t numberOfLevelsToBuffer; + /// Defines the number of top skip levels to buffer in memory. Reducing this number results in less + /// memory usage, but possibly slower performance due to more random I/Os. Please notice that the space + /// each level occupies is limited by the skipInterval. The top level can not contain more than + /// skipLevel entries, the second top level can not contain more than skipLevel^2 entries and so forth. + int32_t numberOfLevelsToBuffer; - int32_t docCount; - bool haveSkipped; + int32_t docCount; + bool haveSkipped; - Collection skipStream; // skipStream for each level - Collection skipPointer; // the start pointer of each skip level - Collection skipInterval; // skipInterval of each level - Collection numSkipped; // number of docs skipped per level + Collection skipStream; // skipStream for each level + Collection skipPointer; // the start pointer of each skip level + Collection skipInterval; // skipInterval of each level + Collection numSkipped; // number of docs skipped per level - Collection skipDoc; // doc id of current skip entry per level - int32_t lastDoc; // doc id of last read skip entry with docId <= target - Collection childPointer; // child pointer of current skip entry per level - int64_t lastChildPointer; // childPointer of last read skip entry with docId <= target + Collection skipDoc; // doc id of current skip entry per level + int32_t lastDoc; // doc id of last read skip entry with docId <= target + Collection childPointer; // child pointer of current skip entry per level + int64_t lastChildPointer; // childPointer of last read skip entry with docId <= target - bool inputIsBuffered; + bool inputIsBuffered; - public: - /// Returns the id of the doc to which the last call of {@link #skipTo(int)} has skipped. - virtual int32_t getDoc(); +public: + /// Returns the id of the doc to which the last call of {@link #skipTo(int)} has skipped. + virtual int32_t getDoc(); - /// Skips entries to the first beyond the current whose document number is greater than or equal to - /// target. Returns the current doc count. - virtual int32_t skipTo(int32_t target); + /// Skips entries to the first beyond the current whose document number is greater than or equal to + /// target. Returns the current doc count. + virtual int32_t skipTo(int32_t target); - virtual void close(); + virtual void close(); - /// Initializes the reader. - virtual void init(int64_t skipPointer, int32_t df); + /// Initializes the reader. + virtual void init(int64_t skipPointer, int32_t df); - protected: - virtual bool loadNextSkip(int32_t level); +protected: + virtual bool loadNextSkip(int32_t level); - /// Seeks the skip entry on the given level - virtual void seekChild(int32_t level); + /// Seeks the skip entry on the given level + virtual void seekChild(int32_t level); - /// Loads the skip levels - virtual void loadSkipLevels(); + /// Loads the skip levels + virtual void loadSkipLevels(); + + /// Subclasses must implement the actual skip data encoding in this method. + /// + /// @param level the level skip data shall be read from + /// @param skipStream the skip stream to read from + virtual int32_t readSkipData(int32_t level, const IndexInputPtr& skipStream) = 0; - /// Subclasses must implement the actual skip data encoding in this method. - /// - /// @param level the level skip data shall be read from - /// @param skipStream the skip stream to read from - virtual int32_t readSkipData(int32_t level, const IndexInputPtr& skipStream) = 0; + /// Copies the values of the last read skip entry on this level + virtual void setLastSkipData(int32_t level); +}; - /// Copies the values of the last read skip entry on this level - virtual void setLastSkipData(int32_t level); - }; +/// Used to buffer the top skip levels +class SkipBuffer : public IndexInput { +public: + SkipBuffer(const IndexInputPtr& input, int32_t length); + virtual ~SkipBuffer(); - /// Used to buffer the top skip levels - class SkipBuffer : public IndexInput - { - public: - SkipBuffer(const IndexInputPtr& input, int32_t length); - virtual ~SkipBuffer(); + LUCENE_CLASS(SkipBuffer); - LUCENE_CLASS(SkipBuffer); +protected: + ByteArray data; + int64_t pointer; + int32_t pos; - protected: - ByteArray data; - int64_t pointer; - int32_t pos; +public: + /// Closes the stream to further operations. + virtual void close(); - public: - /// Closes the stream to further operations. - virtual void close(); + /// Returns the current position in this file, where the next read will occur. + virtual int64_t getFilePointer(); - /// Returns the current position in this file, where the next read will occur. - virtual int64_t getFilePointer(); + /// The number of bytes in the file. + virtual int64_t length(); - /// The number of bytes in the file. - virtual int64_t length(); + /// Reads and returns a single byte. + virtual uint8_t readByte(); - /// Reads and returns a single byte. - virtual uint8_t readByte(); + /// Reads a specified number of bytes into an array at the specified offset. + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - /// Reads a specified number of bytes into an array at the specified offset. - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); + /// Sets current position in this file, where the next read will occur. + virtual void seek(int64_t pos); +}; - /// Sets current position in this file, where the next read will occur. - virtual void seek(int64_t pos); - }; } #endif diff --git a/include/MultiLevelSkipListWriter.h b/include/MultiLevelSkipListWriter.h index 4829e1f5..f7529452 100644 --- a/include/MultiLevelSkipListWriter.h +++ b/include/MultiLevelSkipListWriter.h @@ -9,68 +9,68 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This abstract class writes skip lists with multiple levels. - /// - /// Example for skipInterval = 3: - /// - /// c (skip level 2) - /// c c c (skip level 1) - /// x x x x x x x x x x (skip level 0) - /// d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d (posting list) - /// 3 6 9 12 15 18 21 24 27 30 (df) - /// - /// d - document - /// x - skip data - /// c - skip data with child pointer - /// - /// Skip level i contains every skipInterval-th entry from skip level i-1. - /// Therefore the number of entries on level i is: floor(df / ((skipInterval ^ (i + 1))). - /// - /// Each skip entry on a level i>0 contains a pointer to the corresponding skip entry in list i-1. - /// This guarantees a logarithmic amount of skips to find the target document. - /// - /// While this class takes care of writing the different skip levels, subclasses must define the - /// actual format of the skip data. - class MultiLevelSkipListWriter : public LuceneObject - { - public: - MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df); - virtual ~MultiLevelSkipListWriter(); +namespace Lucene { - LUCENE_CLASS(MultiLevelSkipListWriter); +/// This abstract class writes skip lists with multiple levels. +/// +/// Example for skipInterval = 3: +/// +/// c (skip level 2) +/// c c c (skip level 1) +/// x x x x x x x x x x (skip level 0) +/// d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d (posting list) +/// 3 6 9 12 15 18 21 24 27 30 (df) +/// +/// d - document +/// x - skip data +/// c - skip data with child pointer +/// +/// Skip level i contains every skipInterval-th entry from skip level i-1. +/// Therefore the number of entries on level i is: floor(df / ((skipInterval ^ (i + 1))). +/// +/// Each skip entry on a level i>0 contains a pointer to the corresponding skip entry in list i-1. +/// This guarantees a logarithmic amount of skips to find the target document. +/// +/// While this class takes care of writing the different skip levels, subclasses must define the +/// actual format of the skip data. +class MultiLevelSkipListWriter : public LuceneObject { +public: + MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df); + virtual ~MultiLevelSkipListWriter(); - protected: - /// number of levels in this skip list - int32_t numberOfSkipLevels; + LUCENE_CLASS(MultiLevelSkipListWriter); - /// the skip interval in the list with level = 0 - int32_t skipInterval; +protected: + /// number of levels in this skip list + int32_t numberOfSkipLevels; - /// for every skip level a different buffer is used - Collection skipBuffer; + /// the skip interval in the list with level = 0 + int32_t skipInterval; - public: - /// Writes the current skip data to the buffers. The current document frequency determines - /// the max level is skip data is to be written to. - /// @param df the current document frequency - void bufferSkip(int32_t df); + /// for every skip level a different buffer is used + Collection skipBuffer; - /// Writes the buffered skip lists to the given output. - /// @param output the IndexOutput the skip lists shall be written to - /// @return the pointer the skip list starts - int64_t writeSkip(const IndexOutputPtr& output); +public: + /// Writes the current skip data to the buffers. The current document frequency determines + /// the max level is skip data is to be written to. + /// @param df the current document frequency + void bufferSkip(int32_t df); - protected: - void init(); - virtual void resetSkip(); + /// Writes the buffered skip lists to the given output. + /// @param output the IndexOutput the skip lists shall be written to + /// @return the pointer the skip list starts + int64_t writeSkip(const IndexOutputPtr& output); + +protected: + void init(); + virtual void resetSkip(); + + /// Subclasses must implement the actual skip data encoding in this method. + /// @param level the level skip data shall be writing for + /// @param skipBuffer the skip buffer to write to + virtual void writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer) = 0; +}; - /// Subclasses must implement the actual skip data encoding in this method. - /// @param level the level skip data shall be writing for - /// @param skipBuffer the skip buffer to write to - virtual void writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer) = 0; - }; } #endif diff --git a/include/MultiPhraseQuery.h b/include/MultiPhraseQuery.h index dbd936f3..020982ba 100644 --- a/include/MultiPhraseQuery.h +++ b/include/MultiPhraseQuery.h @@ -9,72 +9,72 @@ #include "Query.h" -namespace Lucene -{ - /// MultiPhraseQuery is a generalized version of PhraseQuery, with an added method {@link #add(Term[])}. - /// To use this class, to search for the phrase "Microsoft app*" first use add(Term) on the term "Microsoft", - /// then find all terms that have "app" as prefix using IndexReader.terms(Term), and use - /// MultiPhraseQuery.add(Term[] terms) to add them to the query. - class LPPAPI MultiPhraseQuery : public Query - { - public: - MultiPhraseQuery(); - virtual ~MultiPhraseQuery(); - - LUCENE_CLASS(MultiPhraseQuery); - - protected: - String field; - Collection< Collection > termArrays; - Collection positions; - int32_t slop; - - public: - using Query::toString; - - /// Sets the phrase slop for this query. - /// @see PhraseQuery#setSlop(int32_t) - void setSlop(int32_t s); - - /// Gets the phrase slop for this query. - /// @see PhraseQuery#getSlop() - int32_t getSlop(); - - /// Add a single term at the next position in the phrase. - /// @see PhraseQuery#add(Term) - void add(const TermPtr& term); - - /// Add multiple terms at the next position in the phrase. Any of the terms may match. - /// @see PhraseQuery#add(Term) - void add(Collection terms); - - /// Allows to specify the relative position of terms within the phrase. - /// @see PhraseQuery#add(Term, int) - void add(Collection terms, int32_t position); - - /// Returns a List of the terms in the multiphrase. Do not modify the List or its contents. - Collection< Collection > getTermArrays(); - - /// Returns the relative positions of terms in this phrase. - Collection getPositions(); - - virtual void extractTerms(SetTerm terms); - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - /// Prints a user-readable version of this query. - virtual String toString(const String& field); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - protected: - int32_t termArraysHashCode(); - bool termArraysEquals(Collection< Collection > first, Collection< Collection > second); - - friend class MultiPhraseWeight; - }; +namespace Lucene { + +/// MultiPhraseQuery is a generalized version of PhraseQuery, with an added method {@link #add(Term[])}. +/// To use this class, to search for the phrase "Microsoft app*" first use add(Term) on the term "Microsoft", +/// then find all terms that have "app" as prefix using IndexReader.terms(Term), and use +/// MultiPhraseQuery.add(Term[] terms) to add them to the query. +class LPPAPI MultiPhraseQuery : public Query { +public: + MultiPhraseQuery(); + virtual ~MultiPhraseQuery(); + + LUCENE_CLASS(MultiPhraseQuery); + +protected: + String field; + Collection< Collection > termArrays; + Collection positions; + int32_t slop; + +public: + using Query::toString; + + /// Sets the phrase slop for this query. + /// @see PhraseQuery#setSlop(int32_t) + void setSlop(int32_t s); + + /// Gets the phrase slop for this query. + /// @see PhraseQuery#getSlop() + int32_t getSlop(); + + /// Add a single term at the next position in the phrase. + /// @see PhraseQuery#add(Term) + void add(const TermPtr& term); + + /// Add multiple terms at the next position in the phrase. Any of the terms may match. + /// @see PhraseQuery#add(Term) + void add(Collection terms); + + /// Allows to specify the relative position of terms within the phrase. + /// @see PhraseQuery#add(Term, int) + void add(Collection terms, int32_t position); + + /// Returns a List of the terms in the multiphrase. Do not modify the List or its contents. + Collection< Collection > getTermArrays(); + + /// Returns the relative positions of terms in this phrase. + Collection getPositions(); + + virtual void extractTerms(SetTerm terms); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + /// Prints a user-readable version of this query. + virtual String toString(const String& field); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + +protected: + int32_t termArraysHashCode(); + bool termArraysEquals(Collection< Collection > first, Collection< Collection > second); + + friend class MultiPhraseWeight; +}; + } #endif diff --git a/include/MultiReader.h b/include/MultiReader.h index d3034a43..11854d69 100644 --- a/include/MultiReader.h +++ b/include/MultiReader.h @@ -9,134 +9,134 @@ #include "IndexReader.h" -namespace Lucene -{ - /// An IndexReader which reads multiple indexes, appending their content. - class LPPAPI MultiReader : public IndexReader - { - public: - /// Construct a MultiReader aggregating the named set of (sub)readers. Directory locking for delete, - /// undeleteAll, and setNorm operations is left to the subreaders. - /// @param closeSubReaders indicates whether the subreaders should be closed when this MultiReader is closed - /// @param subReaders set of (sub)readers - MultiReader(Collection subReaders, bool closeSubReaders = true); - - virtual ~MultiReader(); - - LUCENE_CLASS(MultiReader); - - protected: - Collection subReaders; - Collection starts; // 1st docno for each segment - Collection decrefOnClose; // remember which subreaders to decRef on close - MapStringByteArray normsCache; - int32_t _maxDoc; - int32_t _numDocs; - bool _hasDeletions; +namespace Lucene { - public: - /// Tries to reopen the subreaders. - /// - /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader), - /// then a new MultiReader instance is returned, otherwise this instance is returned. - /// - /// A re-opened instance might share one or more subreaders with the old instance. Index modification - /// operations result in undefined behavior when performed before the old instance is closed. (see {@link - /// IndexReader#reopen()}). - /// - /// If subreaders are shared, then the reference count of those readers is increased to ensure that the - /// subreaders remain open until the last referring reader is closed. - virtual IndexReaderPtr reopen(); - - /// Clones the subreaders. (see {@link IndexReader#clone()}). - /// - /// If subreaders are shared, then the reference count of those readers is increased to ensure that the - /// subreaders remain open until the last referring reader is closed. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - virtual Collection getTermFreqVectors(int32_t docNumber); - virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); - virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); - - virtual bool isOptimized(); - - /// Returns the number of documents in this index. - virtual int32_t numDocs(); - - /// Returns one greater than the largest possible document number. - virtual int32_t maxDoc(); - - /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine - /// what {@link Field}s to load and how they should be loaded. - virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); - - /// Returns true if document n has been deleted - virtual bool isDeleted(int32_t n); - - /// Returns true if any documents have been deleted - virtual bool hasDeletions(); - - /// Returns true if there are norms stored for this field. - virtual bool hasNorms(const String& field); - - /// Returns the byte-encoded normalization factor for the named field of every document. - virtual ByteArray norms(const String& field); - - /// Reads the byte-encoded normalization factor for the named field of every document. - virtual void norms(const String& field, ByteArray norms, int32_t offset); - - /// Returns an enumeration of all the terms in the index. - virtual TermEnumPtr terms(); - - /// Returns an enumeration of all terms starting at a given term. - virtual TermEnumPtr terms(const TermPtr& t); - - /// Returns the number of documents containing the term t. - virtual int32_t docFreq(const TermPtr& t); - - /// Returns an unpositioned {@link TermDocs} enumerator. - virtual TermDocsPtr termDocs(); - - /// Returns an unpositioned {@link TermPositions} enumerator. - virtual TermPositionsPtr termPositions(); - - /// Get a list of unique field names that exist in this index and have the specified field option - /// information. - virtual HashSet getFieldNames(FieldOption fieldOption); - - /// Checks recursively if all subreaders are up to date. - virtual bool isCurrent(); - - /// Not implemented. - virtual int64_t getVersion(); +/// An IndexReader which reads multiple indexes, appending their content. +class LPPAPI MultiReader : public IndexReader { +public: + /// Construct a MultiReader aggregating the named set of (sub)readers. Directory locking for delete, + /// undeleteAll, and setNorm operations is left to the subreaders. + /// @param closeSubReaders indicates whether the subreaders should be closed when this MultiReader is closed + /// @param subReaders set of (sub)readers + MultiReader(Collection subReaders, bool closeSubReaders = true); - /// Returns the sequential sub readers that this reader is logically composed of. - virtual Collection getSequentialSubReaders(); + virtual ~MultiReader(); - protected: - /// If clone is true then we clone each of the subreaders - /// @param doClone - /// @return New IndexReader, or same one (this) if reopen/clone is not necessary - IndexReaderPtr doReopen(bool doClone); + LUCENE_CLASS(MultiReader); - /// Implements deletion of the document numbered docNum. - virtual void doDelete(int32_t docNum); +protected: + Collection subReaders; + Collection starts; // 1st docno for each segment + Collection decrefOnClose; // remember which subreaders to decRef on close + MapStringByteArray normsCache; + int32_t _maxDoc; + int32_t _numDocs; + bool _hasDeletions; - /// Implements actual undeleteAll() in subclass. - virtual void doUndeleteAll(); +public: + /// Tries to reopen the subreaders. + /// + /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader), + /// then a new MultiReader instance is returned, otherwise this instance is returned. + /// + /// A re-opened instance might share one or more subreaders with the old instance. Index modification + /// operations result in undefined behavior when performed before the old instance is closed. (see {@link + /// IndexReader#reopen()}). + /// + /// If subreaders are shared, then the reference count of those readers is increased to ensure that the + /// subreaders remain open until the last referring reader is closed. + virtual IndexReaderPtr reopen(); - /// Find reader for doc n - int32_t readerIndex(int32_t n); + /// Clones the subreaders. (see {@link IndexReader#clone()}). + /// + /// If subreaders are shared, then the reference count of those readers is increased to ensure that the + /// subreaders remain open until the last referring reader is closed. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - /// Implements setNorm in subclass. - virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + virtual Collection getTermFreqVectors(int32_t docNumber); + virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); - virtual void doCommit(MapStringString commitUserData); + virtual bool isOptimized(); + + /// Returns the number of documents in this index. + virtual int32_t numDocs(); + + /// Returns one greater than the largest possible document number. + virtual int32_t maxDoc(); + + /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine + /// what {@link Field}s to load and how they should be loaded. + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); + + /// Returns true if document n has been deleted + virtual bool isDeleted(int32_t n); + + /// Returns true if any documents have been deleted + virtual bool hasDeletions(); + + /// Returns true if there are norms stored for this field. + virtual bool hasNorms(const String& field); + + /// Returns the byte-encoded normalization factor for the named field of every document. + virtual ByteArray norms(const String& field); + + /// Reads the byte-encoded normalization factor for the named field of every document. + virtual void norms(const String& field, ByteArray norms, int32_t offset); + + /// Returns an enumeration of all the terms in the index. + virtual TermEnumPtr terms(); + + /// Returns an enumeration of all terms starting at a given term. + virtual TermEnumPtr terms(const TermPtr& t); + + /// Returns the number of documents containing the term t. + virtual int32_t docFreq(const TermPtr& t); + + /// Returns an unpositioned {@link TermDocs} enumerator. + virtual TermDocsPtr termDocs(); + + /// Returns an unpositioned {@link TermPositions} enumerator. + virtual TermPositionsPtr termPositions(); + + /// Get a list of unique field names that exist in this index and have the specified field option + /// information. + virtual HashSet getFieldNames(FieldOption fieldOption); + + /// Checks recursively if all subreaders are up to date. + virtual bool isCurrent(); + + /// Not implemented. + virtual int64_t getVersion(); + + /// Returns the sequential sub readers that this reader is logically composed of. + virtual Collection getSequentialSubReaders(); + +protected: + /// If clone is true then we clone each of the subreaders + /// @param doClone + /// @return New IndexReader, or same one (this) if reopen/clone is not necessary + IndexReaderPtr doReopen(bool doClone); + + /// Implements deletion of the document numbered docNum. + virtual void doDelete(int32_t docNum); + + /// Implements actual undeleteAll() in subclass. + virtual void doUndeleteAll(); + + /// Find reader for doc n + int32_t readerIndex(int32_t n); + + /// Implements setNorm in subclass. + virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + + virtual void doCommit(MapStringString commitUserData); + + /// Implements close. + virtual void doClose(); +}; - /// Implements close. - virtual void doClose(); - }; } #endif diff --git a/include/MultiSearcher.h b/include/MultiSearcher.h index 3bc4aef3..c0f87a74 100644 --- a/include/MultiSearcher.h +++ b/include/MultiSearcher.h @@ -10,69 +10,69 @@ #include "Searcher.h" #include "Collector.h" -namespace Lucene -{ - /// Implements search over a set of Searchables. +namespace Lucene { + +/// Implements search over a set of Searchables. +/// +/// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link +/// #search(QueryPtr, FilterPtr, int32_t)} methods. +class LPPAPI MultiSearcher : public Searcher { +public: + /// Creates a searcher which searches searchers. + MultiSearcher(Collection searchables); + + virtual ~MultiSearcher(); + + LUCENE_CLASS(MultiSearcher); + +protected: + Collection searchables; + Collection starts; + int32_t _maxDoc; + +public: + using Searcher::search; + + /// Return the array of {@link Searchable}s this searches. + Collection getSearchables(); + + virtual void close(); + virtual int32_t docFreq(const TermPtr& term); + virtual DocumentPtr doc(int32_t n); + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); + + /// Returns index of the searcher for document n in the array used to construct this searcher. + int32_t subSearcher(int32_t n); + + /// Returns the document number of document n within its sub-index. + int32_t subDoc(int32_t n); + + virtual int32_t maxDoc(); + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); + virtual QueryPtr rewrite(const QueryPtr& query); + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); + +protected: + Collection getStarts(); + + /// Create weight in multiple index scenario. /// - /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or {@link - /// #search(QueryPtr, FilterPtr, int32_t)} methods. - class LPPAPI MultiSearcher : public Searcher - { - public: - /// Creates a searcher which searches searchers. - MultiSearcher(Collection searchables); - - virtual ~MultiSearcher(); - - LUCENE_CLASS(MultiSearcher); - - protected: - Collection searchables; - Collection starts; - int32_t _maxDoc; - - public: - using Searcher::search; - - /// Return the array of {@link Searchable}s this searches. - Collection getSearchables(); - - virtual void close(); - virtual int32_t docFreq(const TermPtr& term); - virtual DocumentPtr doc(int32_t n); - virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); - - /// Returns index of the searcher for document n in the array used to construct this searcher. - int32_t subSearcher(int32_t n); - - /// Returns the document number of document n within its sub-index. - int32_t subDoc(int32_t n); - - virtual int32_t maxDoc(); - virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); - virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); - virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); - virtual QueryPtr rewrite(const QueryPtr& query); - virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); - - protected: - Collection getStarts(); - - /// Create weight in multiple index scenario. - /// - /// Distributed query processing is done in the following steps: - /// 1. rewrite query. - /// 2. extract necessary terms. - /// 3. collect dfs for these terms from the Searchables. - /// 4. create query weight using aggregate dfs. - /// 5. distribute that weight to Searchables. - /// 6. merge results. - /// - /// Steps 1-4 are done here, 5+6 in the search() methods - /// - /// @return rewritten queries - virtual WeightPtr createWeight(const QueryPtr& query); - }; + /// Distributed query processing is done in the following steps: + /// 1. rewrite query. + /// 2. extract necessary terms. + /// 3. collect dfs for these terms from the Searchables. + /// 4. create query weight using aggregate dfs. + /// 5. distribute that weight to Searchables. + /// 6. merge results. + /// + /// Steps 1-4 are done here, 5+6 in the search() methods + /// + /// @return rewritten queries + virtual WeightPtr createWeight(const QueryPtr& query); +}; + } #endif diff --git a/include/MultiTermQuery.h b/include/MultiTermQuery.h index ec4cc386..15036b80 100644 --- a/include/MultiTermQuery.h +++ b/include/MultiTermQuery.h @@ -9,172 +9,170 @@ #include "Query.h" -namespace Lucene -{ - /// An abstract {@link Query} that matches documents containing a subset of terms provided by a {@link - /// FilteredTermEnum} enumeration. +namespace Lucene { + +/// An abstract {@link Query} that matches documents containing a subset of terms provided by a {@link +/// FilteredTermEnum} enumeration. +/// +/// This query cannot be used directly; you must subclass it and define {@link #getEnum} to provide a +/// {@link FilteredTermEnum} that iterates through the terms to be matched. +/// +/// NOTE: if {@link #setRewriteMethod} is either {@link #CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE} or {@link +/// #SCORING_BOOLEAN_QUERY_REWRITE}, you may encounter a {@link BooleanQuery.TooManyClauses} exception +/// during searching, which happens when the number of terms to be searched exceeds {@link +/// BooleanQuery#getMaxClauseCount()}. Setting {@link #setRewriteMethod} to {@link +/// #CONSTANT_SCORE_FILTER_REWRITE} prevents this. +/// +/// The recommended rewrite method is {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT}: it doesn't spend CPU +/// computing unhelpful scores, and it tries to pick the most performant rewrite method given the query. +/// +/// Note that {@link QueryParser} produces MultiTermQueries using {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} +/// by default. +class LPPAPI MultiTermQuery : public Query { +public: + MultiTermQuery(); + virtual ~MultiTermQuery(); + + LUCENE_CLASS(MultiTermQuery); + +protected: + RewriteMethodPtr rewriteMethod; + int32_t numberOfTerms; + +public: + /// A rewrite method that first creates a private Filter, by visiting each term in sequence and marking + /// all docs for that term. Matching documents are assigned a constant score equal to the query's boost. /// - /// This query cannot be used directly; you must subclass it and define {@link #getEnum} to provide a - /// {@link FilteredTermEnum} that iterates through the terms to be matched. + /// This method is faster than the BooleanQuery rewrite methods when the number of matched terms or matched + /// documents is non-trivial. Also, it will never hit an errant TooManyClauses exception. /// - /// NOTE: if {@link #setRewriteMethod} is either {@link #CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE} or {@link - /// #SCORING_BOOLEAN_QUERY_REWRITE}, you may encounter a {@link BooleanQuery.TooManyClauses} exception - /// during searching, which happens when the number of terms to be searched exceeds {@link - /// BooleanQuery#getMaxClauseCount()}. Setting {@link #setRewriteMethod} to {@link - /// #CONSTANT_SCORE_FILTER_REWRITE} prevents this. + /// @see #setRewriteMethod + static RewriteMethodPtr CONSTANT_SCORE_FILTER_REWRITE(); + + /// A rewrite method that first translates each term into {@link BooleanClause.Occur#SHOULD} clause in a + /// BooleanQuery, and keeps the scores as computed by the query. Note that typically such scores are + /// meaningless to the user, and require non-trivial CPU to compute, so it's almost always better to use + /// {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} instead. + /// + /// NOTE: This rewrite method will hit {@link BooleanQuery.TooManyClauses} if the number of terms exceeds + /// {@link BooleanQuery#getMaxClauseCount}. + /// + /// @see #setRewriteMethod + static RewriteMethodPtr SCORING_BOOLEAN_QUERY_REWRITE(); + + /// Like {@link #SCORING_BOOLEAN_QUERY_REWRITE} except scores are not computed. Instead, each matching + /// document receives a constant score equal to the query's boost. /// - /// The recommended rewrite method is {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT}: it doesn't spend CPU - /// computing unhelpful scores, and it tries to pick the most performant rewrite method given the query. + /// NOTE: This rewrite method will hit TooManyClauses if the number of terms exceeds {@link + /// BooleanQuery#getMaxClauseCount}. /// - /// Note that {@link QueryParser} produces MultiTermQueries using {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} - /// by default. - class LPPAPI MultiTermQuery : public Query - { - public: - MultiTermQuery(); - virtual ~MultiTermQuery(); - - LUCENE_CLASS(MultiTermQuery); - - protected: - RewriteMethodPtr rewriteMethod; - int32_t numberOfTerms; - - public: - /// A rewrite method that first creates a private Filter, by visiting each term in sequence and marking - /// all docs for that term. Matching documents are assigned a constant score equal to the query's boost. - /// - /// This method is faster than the BooleanQuery rewrite methods when the number of matched terms or matched - /// documents is non-trivial. Also, it will never hit an errant TooManyClauses exception. - /// - /// @see #setRewriteMethod - static RewriteMethodPtr CONSTANT_SCORE_FILTER_REWRITE(); - - /// A rewrite method that first translates each term into {@link BooleanClause.Occur#SHOULD} clause in a - /// BooleanQuery, and keeps the scores as computed by the query. Note that typically such scores are - /// meaningless to the user, and require non-trivial CPU to compute, so it's almost always better to use - /// {@link #CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} instead. - /// - /// NOTE: This rewrite method will hit {@link BooleanQuery.TooManyClauses} if the number of terms exceeds - /// {@link BooleanQuery#getMaxClauseCount}. - /// - /// @see #setRewriteMethod - static RewriteMethodPtr SCORING_BOOLEAN_QUERY_REWRITE(); - - /// Like {@link #SCORING_BOOLEAN_QUERY_REWRITE} except scores are not computed. Instead, each matching - /// document receives a constant score equal to the query's boost. - /// - /// NOTE: This rewrite method will hit TooManyClauses if the number of terms exceeds {@link - /// BooleanQuery#getMaxClauseCount}. - /// - /// @see #setRewriteMethod - static RewriteMethodPtr CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(); - - /// Read-only default instance of {@link ConstantScoreAutoRewrite}, with {@link - /// ConstantScoreAutoRewrite#setTermCountCutoff} set to {@link ConstantScoreAutoRewrite#DEFAULT_TERM_COUNT_CUTOFF} - /// and {@link ConstantScoreAutoRewrite#setDocCountPercent} set to {@link - /// ConstantScoreAutoRewrite#DEFAULT_DOC_COUNT_PERCENT}. Note that you cannot alter the configuration of - /// this instance; you'll need to create a private instance instead. - static RewriteMethodPtr CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(); - - /// Return the number of unique terms visited during execution of the query. If there are many of them, - /// you may consider using another query type or optimize your total term count in index. - /// - /// This method is not thread safe, be sure to only call it when no query is running! If you re-use the - /// same query instance for another search, be sure to first reset the term counter with {@link - /// #clearTotalNumberOfTerms}. - /// - /// On optimized indexes / no MultiReaders, you get the correct number of unique terms for the whole index. - /// Use this number to compare different queries. For non-optimized indexes this number can also be achieved - /// in non-constant-score mode. In constant-score mode you get the total number of terms seeked for all - /// segments / sub-readers. - /// @see #clearTotalNumberOfTerms - int32_t getTotalNumberOfTerms(); - - /// Resets the counting of unique terms. Do this before executing the query/filter. - /// @see #getTotalNumberOfTerms - void clearTotalNumberOfTerms(); - - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - /// @see #setRewriteMethod - virtual RewriteMethodPtr getRewriteMethod(); - - /// Sets the rewrite method to be used when executing the query. You can use one of the four core methods, - /// or implement your own subclass of {@link RewriteMethod}. - virtual void setRewriteMethod(const RewriteMethodPtr& method); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - - protected: - /// Construct the enumeration to be used, expanding the pattern term. - virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader) = 0; - - void incTotalNumberOfTerms(int32_t inc); - - friend class MultiTermQueryWrapperFilter; - friend class ScoringBooleanQueryRewrite; - friend class ConstantScoreAutoRewrite; - }; - - /// Abstract class that defines how the query is rewritten. - class LPPAPI RewriteMethod : public LuceneObject - { - public: - virtual ~RewriteMethod(); - LUCENE_CLASS(RewriteMethod); - - public: - virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) = 0; - }; - - /// A rewrite method that tries to pick the best constant-score rewrite method based on term and document - /// counts from the query. If both the number of terms and documents is small enough, then {@link - /// #CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE} is used. Otherwise, {@link #CONSTANT_SCORE_FILTER_REWRITE} is - /// used. - class LPPAPI ConstantScoreAutoRewrite : public RewriteMethod - { - public: - ConstantScoreAutoRewrite(); - virtual ~ConstantScoreAutoRewrite(); - - LUCENE_CLASS(ConstantScoreAutoRewrite); - - public: - // Defaults derived from rough tests with a 20.0 million doc Wikipedia index. With more than 350 terms - // in the query, the filter method is fastest - static const int32_t DEFAULT_TERM_COUNT_CUTOFF; - - // If the query will hit more than 1 in 1000 of the docs in the index (0.1%), the filter method is fastest - static const double DEFAULT_DOC_COUNT_PERCENT; - - protected: - int32_t termCountCutoff; - double docCountPercent; - - public: - /// If the number of terms in this query is equal to or larger than this setting then {@link - /// #CONSTANT_SCORE_FILTER_REWRITE} is used. - virtual void setTermCountCutoff(int32_t count); - - /// @see #setTermCountCutoff - virtual int32_t getTermCountCutoff(); - - /// If the number of documents to be visited in the postings exceeds this specified percentage of the - /// maxDoc() for the index, then {@link #CONSTANT_SCORE_FILTER_REWRITE} is used. - /// @param percent 0.0 to 100.0 - virtual void setDocCountPercent(double percent); - - /// @see #setDocCountPercent - virtual double getDocCountPercent(); - - virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); - - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - }; + /// @see #setRewriteMethod + static RewriteMethodPtr CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(); + + /// Read-only default instance of {@link ConstantScoreAutoRewrite}, with {@link + /// ConstantScoreAutoRewrite#setTermCountCutoff} set to {@link ConstantScoreAutoRewrite#DEFAULT_TERM_COUNT_CUTOFF} + /// and {@link ConstantScoreAutoRewrite#setDocCountPercent} set to {@link + /// ConstantScoreAutoRewrite#DEFAULT_DOC_COUNT_PERCENT}. Note that you cannot alter the configuration of + /// this instance; you'll need to create a private instance instead. + static RewriteMethodPtr CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(); + + /// Return the number of unique terms visited during execution of the query. If there are many of them, + /// you may consider using another query type or optimize your total term count in index. + /// + /// This method is not thread safe, be sure to only call it when no query is running! If you re-use the + /// same query instance for another search, be sure to first reset the term counter with {@link + /// #clearTotalNumberOfTerms}. + /// + /// On optimized indexes / no MultiReaders, you get the correct number of unique terms for the whole index. + /// Use this number to compare different queries. For non-optimized indexes this number can also be achieved + /// in non-constant-score mode. In constant-score mode you get the total number of terms seeked for all + /// segments / sub-readers. + /// @see #clearTotalNumberOfTerms + int32_t getTotalNumberOfTerms(); + + /// Resets the counting of unique terms. Do this before executing the query/filter. + /// @see #getTotalNumberOfTerms + void clearTotalNumberOfTerms(); + + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + /// @see #setRewriteMethod + virtual RewriteMethodPtr getRewriteMethod(); + + /// Sets the rewrite method to be used when executing the query. You can use one of the four core methods, + /// or implement your own subclass of {@link RewriteMethod}. + virtual void setRewriteMethod(const RewriteMethodPtr& method); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + +protected: + /// Construct the enumeration to be used, expanding the pattern term. + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader) = 0; + + void incTotalNumberOfTerms(int32_t inc); + + friend class MultiTermQueryWrapperFilter; + friend class ScoringBooleanQueryRewrite; + friend class ConstantScoreAutoRewrite; +}; + +/// Abstract class that defines how the query is rewritten. +class LPPAPI RewriteMethod : public LuceneObject { +public: + virtual ~RewriteMethod(); + LUCENE_CLASS(RewriteMethod); + +public: + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) = 0; +}; + +/// A rewrite method that tries to pick the best constant-score rewrite method based on term and document +/// counts from the query. If both the number of terms and documents is small enough, then {@link +/// #CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE} is used. Otherwise, {@link #CONSTANT_SCORE_FILTER_REWRITE} is +/// used. +class LPPAPI ConstantScoreAutoRewrite : public RewriteMethod { +public: + ConstantScoreAutoRewrite(); + virtual ~ConstantScoreAutoRewrite(); + + LUCENE_CLASS(ConstantScoreAutoRewrite); + +public: + // Defaults derived from rough tests with a 20.0 million doc Wikipedia index. With more than 350 terms + // in the query, the filter method is fastest + static const int32_t DEFAULT_TERM_COUNT_CUTOFF; + + // If the query will hit more than 1 in 1000 of the docs in the index (0.1%), the filter method is fastest + static const double DEFAULT_DOC_COUNT_PERCENT; + +protected: + int32_t termCountCutoff; + double docCountPercent; + +public: + /// If the number of terms in this query is equal to or larger than this setting then {@link + /// #CONSTANT_SCORE_FILTER_REWRITE} is used. + virtual void setTermCountCutoff(int32_t count); + + /// @see #setTermCountCutoff + virtual int32_t getTermCountCutoff(); + + /// If the number of documents to be visited in the postings exceeds this specified percentage of the + /// maxDoc() for the index, then {@link #CONSTANT_SCORE_FILTER_REWRITE} is used. + /// @param percent 0.0 to 100.0 + virtual void setDocCountPercent(double percent); + + /// @see #setDocCountPercent + virtual double getDocCountPercent(); + + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); + + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); +}; + } #endif diff --git a/include/MultiTermQueryWrapperFilter.h b/include/MultiTermQueryWrapperFilter.h index 61e2108a..62f6ca6d 100644 --- a/include/MultiTermQueryWrapperFilter.h +++ b/include/MultiTermQueryWrapperFilter.h @@ -9,51 +9,51 @@ #include "Filter.h" -namespace Lucene -{ - /// A wrapper for {@link MultiTermQuery}, that exposes its functionality as a {@link Filter}. +namespace Lucene { + +/// A wrapper for {@link MultiTermQuery}, that exposes its functionality as a {@link Filter}. +/// +/// MultiTermQueryWrapperFilter is not designed to be used by itself. Normally you subclass it to +/// provide a Filter counterpart for a {@link MultiTermQuery} subclass. +/// +/// For example, {@link TermRangeFilter} and {@link PrefixFilter} extend MultiTermQueryWrapperFilter. +/// This class also provides the functionality behind {@link MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE}; +/// this is why it is not abstract. +class LPPAPI MultiTermQueryWrapperFilter : public Filter { +INTERNAL: + /// Wrap a {@link MultiTermQuery} as a Filter. + MultiTermQueryWrapperFilter(const MultiTermQueryPtr& query); + +public: + virtual ~MultiTermQueryWrapperFilter(); + + LUCENE_CLASS(MultiTermQueryWrapperFilter); + +protected: + MultiTermQueryPtr query; + +public: + virtual String toString(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + /// Return the number of unique terms visited during execution of the filter. If there are many of them, + /// you may consider using another filter type or optimize your total term count in index. /// - /// MultiTermQueryWrapperFilter is not designed to be used by itself. Normally you subclass it to - /// provide a Filter counterpart for a {@link MultiTermQuery} subclass. - /// - /// For example, {@link TermRangeFilter} and {@link PrefixFilter} extend MultiTermQueryWrapperFilter. - /// This class also provides the functionality behind {@link MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE}; - /// this is why it is not abstract. - class LPPAPI MultiTermQueryWrapperFilter : public Filter - { - INTERNAL: - /// Wrap a {@link MultiTermQuery} as a Filter. - MultiTermQueryWrapperFilter(const MultiTermQueryPtr& query); - - public: - virtual ~MultiTermQueryWrapperFilter(); - - LUCENE_CLASS(MultiTermQueryWrapperFilter); - - protected: - MultiTermQueryPtr query; - - public: - virtual String toString(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - /// Return the number of unique terms visited during execution of the filter. If there are many of them, - /// you may consider using another filter type or optimize your total term count in index. - /// - /// This method is not thread safe, be sure to only call it when no filter is running! If you re-use the - /// same filter instance for another search, be sure to first reset the term counter with {@link - /// #clearTotalNumberOfTerms}. - /// @see #clearTotalNumberOfTerms - int32_t getTotalNumberOfTerms(); - - /// Resets the counting of unique terms. Do this before executing the filter. - /// @see #getTotalNumberOfTerms - void clearTotalNumberOfTerms(); - - /// Returns a DocIdSet with documents that should be permitted in search results. - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); - }; + /// This method is not thread safe, be sure to only call it when no filter is running! If you re-use the + /// same filter instance for another search, be sure to first reset the term counter with {@link + /// #clearTotalNumberOfTerms}. + /// @see #clearTotalNumberOfTerms + int32_t getTotalNumberOfTerms(); + + /// Resets the counting of unique terms. Do this before executing the filter. + /// @see #getTotalNumberOfTerms + void clearTotalNumberOfTerms(); + + /// Returns a DocIdSet with documents that should be permitted in search results. + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); +}; + } #endif diff --git a/include/MultipleTermPositions.h b/include/MultipleTermPositions.h index 055fb813..8e3e9360 100644 --- a/include/MultipleTermPositions.h +++ b/include/MultipleTermPositions.h @@ -9,47 +9,47 @@ #include "TermPositions.h" -namespace Lucene -{ - /// Allows you to iterate over the {@link TermPositions} for multiple {@link Term}s as a single - /// {@link TermPositions}. - class LPPAPI MultipleTermPositions : public TermPositions, public LuceneObject - { - public: - MultipleTermPositions(const IndexReaderPtr& indexReader, Collection terms); - virtual ~MultipleTermPositions(); - - LUCENE_CLASS(MultipleTermPositions); - - protected: - int32_t _doc; - int32_t _freq; - TermPositionsQueuePtr termPositionsQueue; - IntQueuePtr posList; - - public: - virtual bool next(); - virtual int32_t nextPosition(); - virtual bool skipTo(int32_t target); - virtual int32_t doc(); - virtual int32_t freq(); - virtual void close(); - - /// Not implemented. - virtual void seek(const TermPtr& term); - - /// Not implemented. - virtual void seek(const TermEnumPtr& termEnum); - - /// Not implemented. - virtual int32_t read(Collection docs, Collection freqs); - - /// Not implemented. - virtual ByteArray getPayload(ByteArray data, int32_t offset); - - /// @return false - virtual bool isPayloadAvailable(); - }; +namespace Lucene { + +/// Allows you to iterate over the {@link TermPositions} for multiple {@link Term}s as a single +/// {@link TermPositions}. +class LPPAPI MultipleTermPositions : public TermPositions, public LuceneObject { +public: + MultipleTermPositions(const IndexReaderPtr& indexReader, Collection terms); + virtual ~MultipleTermPositions(); + + LUCENE_CLASS(MultipleTermPositions); + +protected: + int32_t _doc; + int32_t _freq; + TermPositionsQueuePtr termPositionsQueue; + IntQueuePtr posList; + +public: + virtual bool next(); + virtual int32_t nextPosition(); + virtual bool skipTo(int32_t target); + virtual int32_t doc(); + virtual int32_t freq(); + virtual void close(); + + /// Not implemented. + virtual void seek(const TermPtr& term); + + /// Not implemented. + virtual void seek(const TermEnumPtr& termEnum); + + /// Not implemented. + virtual int32_t read(Collection docs, Collection freqs); + + /// Not implemented. + virtual ByteArray getPayload(ByteArray data, int32_t offset); + + /// @return false + virtual bool isPayloadAvailable(); +}; + } #endif diff --git a/include/NativeFSLockFactory.h b/include/NativeFSLockFactory.h index 8fa8f324..273f15ab 100644 --- a/include/NativeFSLockFactory.h +++ b/include/NativeFSLockFactory.h @@ -9,39 +9,39 @@ #include "FSLockFactory.h" -namespace Lucene -{ - /// Implements {@link LockFactory} using native file lock. - /// @see LockFactory - class LPPAPI NativeFSLockFactory : public FSLockFactory - { - public: - /// Create a NativeFSLockFactory instance, storing lock files into - /// the specified lockDirName. - /// @param lockDirName where lock files are created. - NativeFSLockFactory(const String& lockDirName = EmptyString); - virtual ~NativeFSLockFactory(); - - LUCENE_CLASS(NativeFSLockFactory); - - public: - /// Return a new Lock instance identified by lockName. - /// @param lockName name of the lock to be created. - virtual LockPtr makeLock(const String& lockName); - - /// Attempt to clear (forcefully unlock and remove) the - /// specified lock. Only call this at a time when you are - /// certain this lock is no longer in use. - /// @param lockName name of the lock to be cleared. - virtual void clearLock(const String& lockName); - - protected: - /// Simple test to verify locking system is "working". On NFS, if - /// it's mis-configured, you can hit long (35 second) timeouts which - /// cause Lock.obtain to take far too long (it assumes the obtain() - /// call takes zero time). - void acquireTestLock(); - }; +namespace Lucene { + +/// Implements {@link LockFactory} using native file lock. +/// @see LockFactory +class LPPAPI NativeFSLockFactory : public FSLockFactory { +public: + /// Create a NativeFSLockFactory instance, storing lock files into + /// the specified lockDirName. + /// @param lockDirName where lock files are created. + NativeFSLockFactory(const String& lockDirName = EmptyString); + virtual ~NativeFSLockFactory(); + + LUCENE_CLASS(NativeFSLockFactory); + +public: + /// Return a new Lock instance identified by lockName. + /// @param lockName name of the lock to be created. + virtual LockPtr makeLock(const String& lockName); + + /// Attempt to clear (forcefully unlock and remove) the + /// specified lock. Only call this at a time when you are + /// certain this lock is no longer in use. + /// @param lockName name of the lock to be cleared. + virtual void clearLock(const String& lockName); + +protected: + /// Simple test to verify locking system is "working". On NFS, if + /// it's mis-configured, you can hit long (35 second) timeouts which + /// cause Lock.obtain to take far too long (it assumes the obtain() + /// call takes zero time). + void acquireTestLock(); +}; + } #endif diff --git a/include/NearSpansOrdered.h b/include/NearSpansOrdered.h index c5c71571..4ee965f3 100644 --- a/include/NearSpansOrdered.h +++ b/include/NearSpansOrdered.h @@ -9,91 +9,91 @@ #include "Spans.h" -namespace Lucene -{ - /// A Spans that is formed from the ordered subspans of a SpanNearQuery where the subspans do not overlap - /// and have a maximum slop between them. - /// - /// The formed spans only contains minimum slop matches. The matching slop is computed from the distance(s) - /// between the non overlapping matching Spans. - /// - /// Successive matches are always formed from the successive Spans of the SpanNearQuery. - /// - /// The formed spans may contain overlaps when the slop is at least 1. For example, when querying using - ///
      t1 t2 t3
      - /// with slop at least 1, the fragment: - ///
      t1 t2 t1 t3 t2 t3
      - /// matches twice: - ///
      t1 t2 .. t3      
      - ///
            t1 .. t2 t3
      - /// - /// Note: Only public for subclassing. Most implementations should not need this class - class LPPAPI NearSpansOrdered : public Spans - { - public: - NearSpansOrdered(const SpanNearQueryPtr& spanNearQuery, const IndexReaderPtr& reader, bool collectPayloads = true); - virtual ~NearSpansOrdered(); - - LUCENE_CLASS(NearSpansOrdered); - - protected: - int32_t allowedSlop; - bool firstTime; - bool more; - - /// The spans in the same order as the SpanNearQuery - Collection subSpans; - - /// Indicates that all subSpans have same doc() - bool inSameDoc; - - int32_t matchDoc; - int32_t matchStart; - int32_t matchEnd; - Collection matchPayload; - - Collection subSpansByDoc; - SpanNearQueryPtr query; - bool collectPayloads; - - public: - virtual int32_t doc(); - virtual int32_t start(); - virtual int32_t end(); - - Collection getSubSpans(); - - virtual Collection getPayload(); - virtual bool isPayloadAvailable(); - virtual bool next(); - virtual bool skipTo(int32_t target); - - /// Check whether two Spans in the same document are ordered. - /// @return true if spans1 starts before spans2 or the spans start at the same position, and - /// spans1 ends before spans2. - static bool docSpansOrdered(const SpansPtr& spans1, const SpansPtr& spans2); - - virtual String toString(); - - protected: - /// Advances the subSpans to just after an ordered match with a minimum slop that is smaller than the - /// slop allowed by the SpanNearQuery. - /// @return true if there is such a match. - bool advanceAfterOrdered(); - - /// Advance the subSpans to the same document. - bool toSameDoc(); - - // Like {@link #docSpansOrdered(SpansPtr, SpansPtr)}, but use the spans starts and ends as parameters. - static bool docSpansOrdered(int32_t start1, int32_t end1, int32_t start2, int32_t end2); - - /// Order the subSpans within the same document by advancing all later spans after the previous one. - bool stretchToOrder(); - - /// The subSpans are ordered in the same doc, so there is a possible match. Compute the slop while - /// making the match as short as possible by advancing all subSpans except the last one in reverse order. - bool shrinkToAfterShortestMatch(); - }; +namespace Lucene { + +/// A Spans that is formed from the ordered subspans of a SpanNearQuery where the subspans do not overlap +/// and have a maximum slop between them. +/// +/// The formed spans only contains minimum slop matches. The matching slop is computed from the distance(s) +/// between the non overlapping matching Spans. +/// +/// Successive matches are always formed from the successive Spans of the SpanNearQuery. +/// +/// The formed spans may contain overlaps when the slop is at least 1. For example, when querying using +///
      t1 t2 t3
      +/// with slop at least 1, the fragment: +///
      t1 t2 t1 t3 t2 t3
      +/// matches twice: +///
      t1 t2 .. t3      
      +///
            t1 .. t2 t3
      +/// +/// Note: Only public for subclassing. Most implementations should not need this class +class LPPAPI NearSpansOrdered : public Spans { +public: + NearSpansOrdered(const SpanNearQueryPtr& spanNearQuery, const IndexReaderPtr& reader, bool collectPayloads = true); + virtual ~NearSpansOrdered(); + + LUCENE_CLASS(NearSpansOrdered); + +protected: + int32_t allowedSlop; + bool firstTime; + bool more; + + /// The spans in the same order as the SpanNearQuery + Collection subSpans; + + /// Indicates that all subSpans have same doc() + bool inSameDoc; + + int32_t matchDoc; + int32_t matchStart; + int32_t matchEnd; + Collection matchPayload; + + Collection subSpansByDoc; + SpanNearQueryPtr query; + bool collectPayloads; + +public: + virtual int32_t doc(); + virtual int32_t start(); + virtual int32_t end(); + + Collection getSubSpans(); + + virtual Collection getPayload(); + virtual bool isPayloadAvailable(); + virtual bool next(); + virtual bool skipTo(int32_t target); + + /// Check whether two Spans in the same document are ordered. + /// @return true if spans1 starts before spans2 or the spans start at the same position, and + /// spans1 ends before spans2. + static bool docSpansOrdered(const SpansPtr& spans1, const SpansPtr& spans2); + + virtual String toString(); + +protected: + /// Advances the subSpans to just after an ordered match with a minimum slop that is smaller than the + /// slop allowed by the SpanNearQuery. + /// @return true if there is such a match. + bool advanceAfterOrdered(); + + /// Advance the subSpans to the same document. + bool toSameDoc(); + + // Like {@link #docSpansOrdered(SpansPtr, SpansPtr)}, but use the spans starts and ends as parameters. + static bool docSpansOrdered(int32_t start1, int32_t end1, int32_t start2, int32_t end2); + + /// Order the subSpans within the same document by advancing all later spans after the previous one. + bool stretchToOrder(); + + /// The subSpans are ordered in the same doc, so there is a possible match. Compute the slop while + /// making the match as short as possible by advancing all subSpans except the last one in reverse order. + bool shrinkToAfterShortestMatch(); +}; + } #endif diff --git a/include/NearSpansUnordered.h b/include/NearSpansUnordered.h index f8472ad7..a27d43e3 100644 --- a/include/NearSpansUnordered.h +++ b/include/NearSpansUnordered.h @@ -9,63 +9,63 @@ #include "Spans.h" -namespace Lucene -{ - /// Similar to {@link NearSpansOrdered}, but for the unordered case. - /// - /// Only public for subclassing. Most implementations should not need this class - class LPPAPI NearSpansUnordered : public Spans - { - public: - NearSpansUnordered(const SpanNearQueryPtr& query, const IndexReaderPtr& reader); - virtual ~NearSpansUnordered(); - - LUCENE_CLASS(NearSpansUnordered); - - protected: - SpanNearQueryPtr query; - IndexReaderPtr reader; - - Collection ordered; // spans in query order - Collection subSpans; - int32_t slop; // from query - - SpansCellPtr first; // linked list of spans - SpansCellPtr last; // sorted by doc only - - int32_t totalLength; // sum of current lengths - - CellQueuePtr queue; // sorted queue of spans - SpansCellPtr max; // max element in queue - - bool more; // true if not done - bool firstTime; // true before first next() - - public: - virtual void initialize(); - - Collection getSubSpans(); - - virtual bool next(); - virtual bool skipTo(int32_t target); - virtual int32_t doc(); - virtual int32_t start(); - virtual int32_t end(); - virtual Collection getPayload(); - virtual bool isPayloadAvailable(); - virtual String toString(); - - protected: - SpansCellPtr min(); - void initList(bool next); - void addToList(const SpansCellPtr& cell); - void firstToLast(); - void queueToList(); - void listToQueue(); - bool atMatch(); - - friend class SpansCell; - }; +namespace Lucene { + +/// Similar to {@link NearSpansOrdered}, but for the unordered case. +/// +/// Only public for subclassing. Most implementations should not need this class +class LPPAPI NearSpansUnordered : public Spans { +public: + NearSpansUnordered(const SpanNearQueryPtr& query, const IndexReaderPtr& reader); + virtual ~NearSpansUnordered(); + + LUCENE_CLASS(NearSpansUnordered); + +protected: + SpanNearQueryPtr query; + IndexReaderPtr reader; + + Collection ordered; // spans in query order + Collection subSpans; + int32_t slop; // from query + + SpansCellPtr first; // linked list of spans + SpansCellPtr last; // sorted by doc only + + int32_t totalLength; // sum of current lengths + + CellQueuePtr queue; // sorted queue of spans + SpansCellPtr max; // max element in queue + + bool more; // true if not done + bool firstTime; // true before first next() + +public: + virtual void initialize(); + + Collection getSubSpans(); + + virtual bool next(); + virtual bool skipTo(int32_t target); + virtual int32_t doc(); + virtual int32_t start(); + virtual int32_t end(); + virtual Collection getPayload(); + virtual bool isPayloadAvailable(); + virtual String toString(); + +protected: + SpansCellPtr min(); + void initList(bool next); + void addToList(const SpansCellPtr& cell); + void firstToLast(); + void queueToList(); + void listToQueue(); + bool atMatch(); + + friend class SpansCell; +}; + } #endif diff --git a/include/NoLockFactory.h b/include/NoLockFactory.h index f12626d8..39195ff7 100644 --- a/include/NoLockFactory.h +++ b/include/NoLockFactory.h @@ -9,32 +9,32 @@ #include "LockFactory.h" -namespace Lucene -{ - /// Use this {@link LockFactory} to disable locking entirely. Only one instance of this lock is created. - /// You should call {@link #getNoLockFactory()} to get the instance. - /// - /// @see LockFactory - class LPPAPI NoLockFactory : public LockFactory - { - public: - virtual ~NoLockFactory(); - - LUCENE_CLASS(NoLockFactory); - - private: - static NoLockPtr getSingletonLock(); - - public: - static NoLockFactoryPtr getNoLockFactory(); - - /// Return a new Lock instance identified by lockName. - virtual LockPtr makeLock(const String& lockName); - - /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you - /// are certain this lock is no longer in use. - virtual void clearLock(const String& lockName); - }; +namespace Lucene { + +/// Use this {@link LockFactory} to disable locking entirely. Only one instance of this lock is created. +/// You should call {@link #getNoLockFactory()} to get the instance. +/// +/// @see LockFactory +class LPPAPI NoLockFactory : public LockFactory { +public: + virtual ~NoLockFactory(); + + LUCENE_CLASS(NoLockFactory); + +private: + static NoLockPtr getSingletonLock(); + +public: + static NoLockFactoryPtr getNoLockFactory(); + + /// Return a new Lock instance identified by lockName. + virtual LockPtr makeLock(const String& lockName); + + /// Attempt to clear (forcefully unlock and remove) the specified lock. Only call this at a time when you + /// are certain this lock is no longer in use. + virtual void clearLock(const String& lockName); +}; + } #endif diff --git a/include/NormalizeCharMap.h b/include/NormalizeCharMap.h index bd0fb1a3..470456da 100644 --- a/include/NormalizeCharMap.h +++ b/include/NormalizeCharMap.h @@ -9,30 +9,30 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Holds a map of String input to String output, to be used with {@link MappingCharFilter}. - class LPPAPI NormalizeCharMap : public LuceneObject - { - public: - NormalizeCharMap(); - virtual ~NormalizeCharMap(); - - LUCENE_CLASS(NormalizeCharMap); - - public: - MapCharNormalizeCharMap submap; - String normStr; - int32_t diff; - - public: - /// Records a replacement to be applied to the inputs stream. Whenever singleMatch occurs in the input, it - /// will be replaced with replacement. - /// - /// @param singleMatch input String to be replaced - /// @param replacement output String - void add(const String& singleMatch, const String& replacement); - }; +namespace Lucene { + +/// Holds a map of String input to String output, to be used with {@link MappingCharFilter}. +class LPPAPI NormalizeCharMap : public LuceneObject { +public: + NormalizeCharMap(); + virtual ~NormalizeCharMap(); + + LUCENE_CLASS(NormalizeCharMap); + +public: + MapCharNormalizeCharMap submap; + String normStr; + int32_t diff; + +public: + /// Records a replacement to be applied to the inputs stream. Whenever singleMatch occurs in the input, it + /// will be replaced with replacement. + /// + /// @param singleMatch input String to be replaced + /// @param replacement output String + void add(const String& singleMatch, const String& replacement); +}; + } #endif diff --git a/include/NormsWriter.h b/include/NormsWriter.h index f7efd4b6..836774d6 100644 --- a/include/NormsWriter.h +++ b/include/NormsWriter.h @@ -9,37 +9,37 @@ #include "InvertedDocEndConsumer.h" -namespace Lucene -{ - /// Writes norms. Each thread X field accumulates the norms for the doc/fields it saw, then the flush method - /// below merges all of these together into a single _X.nrm file. - class NormsWriter : public InvertedDocEndConsumer - { - public: - NormsWriter(); - virtual ~NormsWriter(); +namespace Lucene { - LUCENE_CLASS(NormsWriter); +/// Writes norms. Each thread X field accumulates the norms for the doc/fields it saw, then the flush method +/// below merges all of these together into a single _X.nrm file. +class NormsWriter : public InvertedDocEndConsumer { +public: + NormsWriter(); + virtual ~NormsWriter(); - protected: - FieldInfosPtr fieldInfos; + LUCENE_CLASS(NormsWriter); - public: - virtual InvertedDocEndConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread); - virtual void abort(); +protected: + FieldInfosPtr fieldInfos; - // We only write the _X.nrm file at flush - virtual void files(HashSet files); +public: + virtual InvertedDocEndConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread); + virtual void abort(); - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); + // We only write the _X.nrm file at flush + virtual void files(HashSet files); - /// Produce _X.nrm if any document had a field with norms not disabled - virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); - virtual void closeDocStore(const SegmentWriteStatePtr& state); + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); + + /// Produce _X.nrm if any document had a field with norms not disabled + virtual void flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); + +protected: + static uint8_t getDefaultNorm(); +}; - protected: - static uint8_t getDefaultNorm(); - }; } #endif diff --git a/include/NormsWriterPerField.h b/include/NormsWriterPerField.h index 91887f43..1560c0f2 100644 --- a/include/NormsWriterPerField.h +++ b/include/NormsWriterPerField.h @@ -9,39 +9,39 @@ #include "InvertedDocEndConsumerPerField.h" -namespace Lucene -{ - /// Taps into DocInverter, as an InvertedDocEndConsumer, which is called at the end of inverting each field. - /// We just look at the length for the field (docState.length) and record the norm. - class NormsWriterPerField : public InvertedDocEndConsumerPerField - { - public: - NormsWriterPerField(const DocInverterPerFieldPtr& docInverterPerField, const NormsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); - virtual ~NormsWriterPerField(); - - LUCENE_CLASS(NormsWriterPerField); - - public: - NormsWriterPerThreadWeakPtr _perThread; - FieldInfoPtr fieldInfo; - DocStatePtr docState; - - // Holds all docID/norm pairs we've seen - Collection docIDs; - ByteArray norms; - int32_t upto; - - FieldInvertStatePtr fieldState; - - public: - void reset(); - virtual void abort(); - - /// Compare two objects - virtual int32_t compareTo(const LuceneObjectPtr& other); - - virtual void finish(); - }; +namespace Lucene { + +/// Taps into DocInverter, as an InvertedDocEndConsumer, which is called at the end of inverting each field. +/// We just look at the length for the field (docState.length) and record the norm. +class NormsWriterPerField : public InvertedDocEndConsumerPerField { +public: + NormsWriterPerField(const DocInverterPerFieldPtr& docInverterPerField, const NormsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); + virtual ~NormsWriterPerField(); + + LUCENE_CLASS(NormsWriterPerField); + +public: + NormsWriterPerThreadWeakPtr _perThread; + FieldInfoPtr fieldInfo; + DocStatePtr docState; + + // Holds all docID/norm pairs we've seen + Collection docIDs; + ByteArray norms; + int32_t upto; + + FieldInvertStatePtr fieldState; + +public: + void reset(); + virtual void abort(); + + /// Compare two objects + virtual int32_t compareTo(const LuceneObjectPtr& other); + + virtual void finish(); +}; + } #endif diff --git a/include/NormsWriterPerThread.h b/include/NormsWriterPerThread.h index 627a5eeb..e020bd3a 100644 --- a/include/NormsWriterPerThread.h +++ b/include/NormsWriterPerThread.h @@ -9,28 +9,28 @@ #include "InvertedDocEndConsumerPerThread.h" -namespace Lucene -{ - class NormsWriterPerThread : public InvertedDocEndConsumerPerThread - { - public: - NormsWriterPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const NormsWriterPtr& normsWriter); - virtual ~NormsWriterPerThread(); - - LUCENE_CLASS(NormsWriterPerThread); - - public: - NormsWriterWeakPtr _normsWriter; - DocStatePtr docState; - - public: - virtual InvertedDocEndConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo); - virtual void abort(); - virtual void startDocument(); - virtual void finishDocument(); - - bool freeRAM(); - }; +namespace Lucene { + +class NormsWriterPerThread : public InvertedDocEndConsumerPerThread { +public: + NormsWriterPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const NormsWriterPtr& normsWriter); + virtual ~NormsWriterPerThread(); + + LUCENE_CLASS(NormsWriterPerThread); + +public: + NormsWriterWeakPtr _normsWriter; + DocStatePtr docState; + +public: + virtual InvertedDocEndConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo); + virtual void abort(); + virtual void startDocument(); + virtual void finishDocument(); + + bool freeRAM(); +}; + } #endif diff --git a/include/NumberTools.h b/include/NumberTools.h index 684a2dab..fc47365e 100644 --- a/include/NumberTools.h +++ b/include/NumberTools.h @@ -9,51 +9,51 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Provides support for converting longs to Strings, and back again. The strings are structured so that - /// lexicographic sorting order is preserved. - /// - /// That is, if l1 is less than l2 for any two longs l1 and l2, then NumberTools.longToString(l1) is - /// lexicographically less than NumberTools.longToString(l2). (Similarly for "greater than" and "equals".) - /// - /// This class handles all long values (unlike {@link DateField}). - /// - /// @deprecated For new indexes use {@link NumericUtils} instead, which provides a sortable binary representation - /// (prefix encoded) of numeric values. - /// To index and efficiently query numeric values use {@link NumericField} and {@link NumericRangeQuery}. This - /// class is included for use with existing indices and will be removed in a future release (possibly Lucene 4.0). - class LPPAPI NumberTools : public LuceneObject - { - public: - virtual ~NumberTools(); - - LUCENE_CLASS(NumberTools); - - protected: - static const int32_t RADIX; - - static const wchar_t NEGATIVE_PREFIX; - - // NB: NEGATIVE_PREFIX must be < POSITIVE_PREFIX - static const wchar_t POSITIVE_PREFIX; - - public: - /// Equivalent to longToString(LLONG_MIN) - static const String& MIN_STRING_VALUE(); - - /// Equivalent to longToString(LLONG_MAX) - static const String& MAX_STRING_VALUE(); - - /// The length of (all) strings returned by {@link #longToString} - static int32_t STR_SIZE(); - - /// Converts a long to a String suitable for indexing. - static String longToString(int64_t l); - - /// Converts a String that was returned by {@link #longToString} back to a long. - static int64_t stringToLong(const String& str); - }; +namespace Lucene { + +/// Provides support for converting longs to Strings, and back again. The strings are structured so that +/// lexicographic sorting order is preserved. +/// +/// That is, if l1 is less than l2 for any two longs l1 and l2, then NumberTools.longToString(l1) is +/// lexicographically less than NumberTools.longToString(l2). (Similarly for "greater than" and "equals".) +/// +/// This class handles all long values (unlike {@link DateField}). +/// +/// @deprecated For new indexes use {@link NumericUtils} instead, which provides a sortable binary representation +/// (prefix encoded) of numeric values. +/// To index and efficiently query numeric values use {@link NumericField} and {@link NumericRangeQuery}. This +/// class is included for use with existing indices and will be removed in a future release (possibly Lucene 4.0). +class LPPAPI NumberTools : public LuceneObject { +public: + virtual ~NumberTools(); + + LUCENE_CLASS(NumberTools); + +protected: + static const int32_t RADIX; + + static const wchar_t NEGATIVE_PREFIX; + + // NB: NEGATIVE_PREFIX must be < POSITIVE_PREFIX + static const wchar_t POSITIVE_PREFIX; + +public: + /// Equivalent to longToString(LLONG_MIN) + static const String& MIN_STRING_VALUE(); + + /// Equivalent to longToString(LLONG_MAX) + static const String& MAX_STRING_VALUE(); + + /// The length of (all) strings returned by {@link #longToString} + static int32_t STR_SIZE(); + + /// Converts a long to a String suitable for indexing. + static String longToString(int64_t l); + + /// Converts a String that was returned by {@link #longToString} back to a long. + static int64_t stringToLong(const String& str); +}; + } #endif diff --git a/include/NumericField.h b/include/NumericField.h index e8fe1901..e8ecd538 100644 --- a/include/NumericField.h +++ b/include/NumericField.h @@ -9,125 +9,125 @@ #include "Field.h" -namespace Lucene -{ - /// This class provides a {@link Field} that enables indexing of numeric values for efficient range filtering and - /// sorting. The native types int32_t, int64_t and double are directly supported. However, any value that can be - /// converted into these native types can also be indexed. For example, date/time values represented by a {@link - /// Date} can be translated into a int64_t value. If you don't need millisecond precision, you can quantize the - /// value, either by dividing the result or using the separate getters (for year, month, etc.) to construct an int32_t - /// or int64_t value. - /// - /// To perform range querying or filtering against a NumericField, use {@link NumericRangeQuery} or {@link - /// NumericRangeFilter}. To sort according to a NumericField, use the normal numeric sort types, eg {@link - /// SortField#INT}. NumericField values can also be loaded directly from {@link FieldCache}. - /// - /// By default, a NumericField's value is not stored but is indexed for range filtering and sorting. You can use the - /// {@link #NumericField(String,Field.Store,boolean)} constructor if you need to change these defaults. - /// - /// You may add the same field name as a NumericField to the same document more than once. Range querying and - /// filtering will be the logical OR of all values; so a range query will hit all documents that have at least one - /// value in the range. However sort behavior is not defined. If you need to sort, you should separately index a - /// single-valued NumericField. - /// - /// A NumericField will consume somewhat more disk space in the index than an ordinary single-valued field. However, - /// for a typical index that includes substantial textual content per document, this increase will likely be in the - /// noise. - /// - /// Within Lucene, each numeric value is indexed as a trie structure, where each term is logically assigned to larger - /// and larger pre-defined brackets (which are simply lower-precision representations of the value). The step size - /// between each successive bracket is called the precisionStep, measured in bits. Smaller precisionStep values - /// result in larger number of brackets, which consumes more disk space in the index but may result in faster range - /// search performance. The default value 4 was selected for a reasonable trade off of disk space consumption versus - /// performance. You can use the expert constructor {@link #NumericField(String,int,Field.Store,boolean)} if you'd - /// like to change the value. Note that you must also specify a congruent value when creating {@link NumericRangeQuery} - /// or {@link NumericRangeFilter}. For low cardinality fields larger precision steps are good. If the cardinality - /// is < 100, it is fair to use {@link INT_MAX}, which produces one term per value. - /// - /// For more information on the internals of numeric trie indexing, including the precisionStep configuration, see - /// {@link NumericRangeQuery}. The format of indexed values is described in {@link NumericUtils}. - /// - /// If you only need to sort by numeric value, and never run range querying/filtering, you can index using a - /// precisionStep of {@link MAX_INT}. This will minimize disk space consumed. - /// - /// More advanced users can instead use {@link NumericTokenStream} directly, when indexing numbers. This class is a - /// wrapper around this token stream type for easier, more intuitive usage. - /// - /// NOTE: This class is only used during indexing. When retrieving the stored field value from a {@link Document} - /// instance after search, you will get a conventional {@link Fieldable} instance where the numeric values are - /// returned as strings (according to toString(value) of the used data type). - class LPPAPI NumericField : public AbstractField - { - public: - /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} - /// (4). The instance is not yet initialized with a numeric value, before indexing a document containing this field, - /// set a value using the various set???Value() methods. - /// This constructor creates an indexed, but not stored field. - /// @param name the field name - NumericField(const String& name); - - /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} - /// (4). The instance is not yet initialized with a numeric value, before indexing a document containing this field, - /// set a value using the various set???Value() methods. - /// This constructor creates an indexed, but not stored field. - /// @param name the field name - /// @param store if the field should be stored in plain text form (according to toString(value) of the used - /// data type) - /// @param index if the field should be indexed using {@link NumericTokenStream} - NumericField(const String& name, Field::Store store, bool index); - - /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with - /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() - /// methods. This constructor creates an indexed, but not stored field. - /// @param name the field name - /// @param precisionStep the used precision step - NumericField(const String& name, int32_t precisionStep); - - /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with - /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() - /// methods. This constructor creates an indexed, but not stored field. - /// @param name the field name - /// @param precisionStep the used precision step - /// @param store if the field should be stored in plain text form (according to toString(value) of the used - /// data type) - /// @param index if the field should be indexed using {@link NumericTokenStream} - NumericField(const String& name, int32_t precisionStep, Field::Store store, bool index); - - virtual ~NumericField(); - - LUCENE_CLASS(NumericField); - - protected: - NumericTokenStreamPtr tokenStream; - - public: - /// Returns a {@link NumericTokenStream} for indexing the numeric value. - virtual TokenStreamPtr tokenStreamValue(); - - /// Returns always null for numeric fields - virtual ByteArray getBinaryValue(ByteArray result); - - /// Returns always null for numeric fields - virtual ReaderPtr readerValue(); - - /// Returns the numeric value as a string (how it is stored, when {@link Field.Store#YES} is chosen). - virtual String stringValue(); - - /// Returns the current numeric value. - virtual int64_t getNumericValue(); - - /// Initializes the field with the supplied long value. - /// @param value the numeric value - virtual NumericFieldPtr setLongValue(int64_t value); - - /// Initializes the field with the supplied int value. - /// @param value the numeric value - virtual NumericFieldPtr setIntValue(int32_t value); - - /// Initializes the field with the supplied double value. - /// @param value the numeric value - virtual NumericFieldPtr setDoubleValue(double value); - }; +namespace Lucene { + +/// This class provides a {@link Field} that enables indexing of numeric values for efficient range filtering and +/// sorting. The native types int32_t, int64_t and double are directly supported. However, any value that can be +/// converted into these native types can also be indexed. For example, date/time values represented by a {@link +/// Date} can be translated into a int64_t value. If you don't need millisecond precision, you can quantize the +/// value, either by dividing the result or using the separate getters (for year, month, etc.) to construct an int32_t +/// or int64_t value. +/// +/// To perform range querying or filtering against a NumericField, use {@link NumericRangeQuery} or {@link +/// NumericRangeFilter}. To sort according to a NumericField, use the normal numeric sort types, eg {@link +/// SortField#INT}. NumericField values can also be loaded directly from {@link FieldCache}. +/// +/// By default, a NumericField's value is not stored but is indexed for range filtering and sorting. You can use the +/// {@link #NumericField(String,Field.Store,boolean)} constructor if you need to change these defaults. +/// +/// You may add the same field name as a NumericField to the same document more than once. Range querying and +/// filtering will be the logical OR of all values; so a range query will hit all documents that have at least one +/// value in the range. However sort behavior is not defined. If you need to sort, you should separately index a +/// single-valued NumericField. +/// +/// A NumericField will consume somewhat more disk space in the index than an ordinary single-valued field. However, +/// for a typical index that includes substantial textual content per document, this increase will likely be in the +/// noise. +/// +/// Within Lucene, each numeric value is indexed as a trie structure, where each term is logically assigned to larger +/// and larger pre-defined brackets (which are simply lower-precision representations of the value). The step size +/// between each successive bracket is called the precisionStep, measured in bits. Smaller precisionStep values +/// result in larger number of brackets, which consumes more disk space in the index but may result in faster range +/// search performance. The default value 4 was selected for a reasonable trade off of disk space consumption versus +/// performance. You can use the expert constructor {@link #NumericField(String,int,Field.Store,boolean)} if you'd +/// like to change the value. Note that you must also specify a congruent value when creating {@link NumericRangeQuery} +/// or {@link NumericRangeFilter}. For low cardinality fields larger precision steps are good. If the cardinality +/// is < 100, it is fair to use {@link INT_MAX}, which produces one term per value. +/// +/// For more information on the internals of numeric trie indexing, including the precisionStep configuration, see +/// {@link NumericRangeQuery}. The format of indexed values is described in {@link NumericUtils}. +/// +/// If you only need to sort by numeric value, and never run range querying/filtering, you can index using a +/// precisionStep of {@link MAX_INT}. This will minimize disk space consumed. +/// +/// More advanced users can instead use {@link NumericTokenStream} directly, when indexing numbers. This class is a +/// wrapper around this token stream type for easier, more intuitive usage. +/// +/// NOTE: This class is only used during indexing. When retrieving the stored field value from a {@link Document} +/// instance after search, you will get a conventional {@link Fieldable} instance where the numeric values are +/// returned as strings (according to toString(value) of the used data type). +class LPPAPI NumericField : public AbstractField { +public: + /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} + /// (4). The instance is not yet initialized with a numeric value, before indexing a document containing this field, + /// set a value using the various set???Value() methods. + /// This constructor creates an indexed, but not stored field. + /// @param name the field name + NumericField(const String& name); + + /// Creates a field for numeric values using the default precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} + /// (4). The instance is not yet initialized with a numeric value, before indexing a document containing this field, + /// set a value using the various set???Value() methods. + /// This constructor creates an indexed, but not stored field. + /// @param name the field name + /// @param store if the field should be stored in plain text form (according to toString(value) of the used + /// data type) + /// @param index if the field should be indexed using {@link NumericTokenStream} + NumericField(const String& name, Field::Store store, bool index); + + /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with + /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() + /// methods. This constructor creates an indexed, but not stored field. + /// @param name the field name + /// @param precisionStep the used precision step + NumericField(const String& name, int32_t precisionStep); + + /// Creates a field for numeric values with the specified precisionStep. The instance is not yet initialized with + /// a numeric value, before indexing a document containing this field, set a value using the various set???Value() + /// methods. This constructor creates an indexed, but not stored field. + /// @param name the field name + /// @param precisionStep the used precision step + /// @param store if the field should be stored in plain text form (according to toString(value) of the used + /// data type) + /// @param index if the field should be indexed using {@link NumericTokenStream} + NumericField(const String& name, int32_t precisionStep, Field::Store store, bool index); + + virtual ~NumericField(); + + LUCENE_CLASS(NumericField); + +protected: + NumericTokenStreamPtr tokenStream; + +public: + /// Returns a {@link NumericTokenStream} for indexing the numeric value. + virtual TokenStreamPtr tokenStreamValue(); + + /// Returns always null for numeric fields + virtual ByteArray getBinaryValue(ByteArray result); + + /// Returns always null for numeric fields + virtual ReaderPtr readerValue(); + + /// Returns the numeric value as a string (how it is stored, when {@link Field.Store#YES} is chosen). + virtual String stringValue(); + + /// Returns the current numeric value. + virtual int64_t getNumericValue(); + + /// Initializes the field with the supplied long value. + /// @param value the numeric value + virtual NumericFieldPtr setLongValue(int64_t value); + + /// Initializes the field with the supplied int value. + /// @param value the numeric value + virtual NumericFieldPtr setIntValue(int32_t value); + + /// Initializes the field with the supplied double value. + /// @param value the numeric value + virtual NumericFieldPtr setDoubleValue(double value); +}; + } #endif diff --git a/include/NumericRangeFilter.h b/include/NumericRangeFilter.h index b119391f..22291f4f 100644 --- a/include/NumericRangeFilter.h +++ b/include/NumericRangeFilter.h @@ -9,75 +9,75 @@ #include "MultiTermQueryWrapperFilter.h" -namespace Lucene -{ - /// A {@link Filter} that only accepts numeric values within a specified range. To use this, you must first - /// index the numeric values using {@link NumericField} ({@link NumericTokenStream}). - /// - /// You create a new NumericRangeFilter with the static factory methods, eg: - ///
      -    /// FilterPtr f = NumericRangeFilter::newDoubleRange(L"weight", 0.3, 0.10, true, true);
      -    /// 
      - /// accepts all documents whose double valued "weight" field ranges from 0.3 to 0.10, inclusive. - /// - /// See {@link NumericRangeQuery} for details on how Lucene indexes and searches numeric valued fields. - class LPPAPI NumericRangeFilter : public MultiTermQueryWrapperFilter - { - public: - NumericRangeFilter(const NumericRangeQueryPtr& query); - virtual ~NumericRangeFilter(); - - LUCENE_CLASS(NumericRangeFilter); - - public: - /// Factory that creates a NumericRangeFilter, that filters a long range using the given precisionStep. - static NumericRangeFilterPtr newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep - /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). - static NumericRangeFilterPtr newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int range using the given precisionStep. - static NumericRangeFilterPtr newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep - /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). - static NumericRangeFilterPtr newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a double range using the given precisionStep. - static NumericRangeFilterPtr newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep - /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). - static NumericRangeFilterPtr newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int, long or double range using the given - /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min - /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents - /// excluding the bounds, with inclusive on the boundaries are hits, too. - static NumericRangeFilterPtr newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int, long or double range range using the default - /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which are in - /// fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting inclusive to false - /// it will match all documents excluding the bounds, with inclusive on the boundaries are hits, too. - static NumericRangeFilterPtr newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - - /// Returns the field name for this filter - String getField(); - - /// Returns true if the lower endpoint is inclusive - bool includesMin(); - - /// Returns true if the upper endpoint is inclusive - bool includesMax(); - - /// Returns the lower value of this range filter - NumericValue getMin(); - - /// Returns the upper value of this range filter - NumericValue getMax(); - }; +namespace Lucene { + +/// A {@link Filter} that only accepts numeric values within a specified range. To use this, you must first +/// index the numeric values using {@link NumericField} ({@link NumericTokenStream}). +/// +/// You create a new NumericRangeFilter with the static factory methods, eg: +///
      +/// FilterPtr f = NumericRangeFilter::newDoubleRange(L"weight", 0.3, 0.10, true, true);
      +/// 
      +/// accepts all documents whose double valued "weight" field ranges from 0.3 to 0.10, inclusive. +/// +/// See {@link NumericRangeQuery} for details on how Lucene indexes and searches numeric valued fields. +class LPPAPI NumericRangeFilter : public MultiTermQueryWrapperFilter { +public: + NumericRangeFilter(const NumericRangeQueryPtr& query); + virtual ~NumericRangeFilter(); + + LUCENE_CLASS(NumericRangeFilter); + +public: + /// Factory that creates a NumericRangeFilter, that filters a long range using the given precisionStep. + static NumericRangeFilterPtr newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep + /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + static NumericRangeFilterPtr newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a int range using the given precisionStep. + static NumericRangeFilterPtr newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep + /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + static NumericRangeFilterPtr newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a double range using the given precisionStep. + static NumericRangeFilterPtr newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep + /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + static NumericRangeFilterPtr newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a int, long or double range using the given + /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min + /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents + /// excluding the bounds, with inclusive on the boundaries are hits, too. + static NumericRangeFilterPtr newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a int, long or double range range using the default + /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which are in + /// fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting inclusive to false + /// it will match all documents excluding the bounds, with inclusive on the boundaries are hits, too. + static NumericRangeFilterPtr newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); + + /// Returns the field name for this filter + String getField(); + + /// Returns true if the lower endpoint is inclusive + bool includesMin(); + + /// Returns true if the upper endpoint is inclusive + bool includesMax(); + + /// Returns the lower value of this range filter + NumericValue getMin(); + + /// Returns the upper value of this range filter + NumericValue getMax(); +}; + } #endif diff --git a/include/NumericRangeQuery.h b/include/NumericRangeQuery.h index 62710d33..e4c7814b 100644 --- a/include/NumericRangeQuery.h +++ b/include/NumericRangeQuery.h @@ -11,179 +11,179 @@ #include "FilteredTermEnum.h" #include "NumericUtils.h" -namespace Lucene -{ - /// A {@link Query} that matches numeric values within a specified range. To use this, you must first - /// index the numeric values using {@link NumericField} (expert: {@link NumericTokenStream}). If your - /// terms are instead textual, you should use {@link TermRangeQuery}. {@link NumericRangeFilter} is the - /// filter equivalent of this query. - /// - /// You create a new NumericRangeQuery with the static factory methods, eg: - ///
      -    /// QueryPtr q = NumericRangeQuery::newDoubleRange("weight", 0.3, 0.10, true, true);
      -    /// 
      - /// matches all documents whose double valued "weight" field ranges from 0.3 to 0.10, inclusive. - /// - /// The performance of NumericRangeQuery is much better than the corresponding {@link TermRangeQuery} - /// because the number of terms that must be searched is usually far fewer, thanks to trie indexing, - /// described below. - /// - /// You can optionally specify a precisionStep when creating this query. This is necessary if you've - /// changed this configuration from its default (4) during indexing. Lower values consume more disk - /// space but speed up searching. Suitable values are between 1 and 8. A good starting point to test - /// is 4, which is the default value for all Numeric* classes. See below for details. - /// - /// This query defaults to {@linkplain MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} for 32 bit - /// integer ranges with precisionStep <=8 and 64 bit (long/double) ranges with precisionStep <=6. - /// Otherwise it uses {@linkplain MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE} as the number of terms - /// is likely to be high. With precision steps of <=4, this query can be run with one of the BooleanQuery - /// rewrite methods without changing BooleanQuery's default max clause count. - /// - /// How it works - /// - /// See the publication about panFMP, where this - /// algorithm was described (referred to as TrieRangeQuery): - ///
      Schindler, U, Diepenbroek, M, 2008. - /// Generic XML-based Framework for Metadata Portals. - /// Computers & Geosciences 34 (12), 1947-1955. - /// doi:10.1016/j.cageo.2008.02.023
      - /// - /// A quote from this paper: Because Apache Lucene is a full-text search engine and not a conventional - /// database, it cannot handle numerical ranges (eg., field value is inside user defined bounds, even - /// dates are numerical values). We have developed an extension to Apache Lucene that stores the - /// numerical values in a special string-encoded format with variable precision (all numerical values like - /// doubles, longs, and ints are converted to lexicographic sortable string representations and stored - /// with different precisions (for a more detailed description of how the values are stored, see {@link - /// NumericUtils}). A range is then divided recursively into multiple intervals for searching: - /// The center of the range is searched only with the lowest possible precision in the trie, while the - /// boundaries are matched more exactly. This reduces the number of terms dramatically. - /// - /// For the variant that stores long values in 8 different precisions (each reduced by 8 bits) that uses a - /// lowest precision of 1 byte, the index contains only a maximum of 256 distinct values in the lowest - /// precision. Overall, a range could consist of a theoretical maximum of 7*255*2 + 255 = 3825 distinct - /// terms (when there is a term for every distinct value of an 8-byte-number in the index and the range - /// covers almost all of them; a maximum of 255 distinct values is used because it would always be possible - /// to reduce the full 256 values to one term with degraded precision). In practice, we have seen up to - /// 300 terms in most cases (index with 500,000 metadata records and a uniform value distribution). - /// - /// Precision Step: - /// You can choose any precisionStep when encoding values. Lower step values mean more precisions and so - /// more terms in index (and index gets larger). On the other hand, the maximum number of terms to match - /// reduces, which optimized query speed. The formula to calculate the maximum term count is: - ///
      -    /// n = [ (bitsPerValue/precisionStep - 1) * (2 ^ precisionStep - 1 ) * 2 ] + (2 ^ precisionStep - 1 )
      -    /// 
      - /// - /// (this formula is only correct, when bitsPerValue/precisionStep is an integer; in other cases, the value - /// must be rounded up and the last summand must contain the modulo of the division as precision step). - /// For longs stored using a precision step of 4, n = 15*15*2 + 15 = 465, and for a precision step of 2, - /// n = 31*3*2 + 3 = 189. But the faster search speed is reduced by more seeking in the term enum of the - /// index. Because of this, the ideal precisionStep value can only be found out by testing. Important: You - /// can index with a lower precision step value and test search speed using a multiple of the original step - /// value. - /// - /// Good values for precisionStep are depending on usage and data type: - ///
        - ///
      • The default for all data types is 4, which is used, when no precisionStep is given. - ///
      • Ideal value in most cases for 64 bit data types (long, double) is 6 or 8. - ///
      • Ideal value in most cases for 32 bit data types (int) is 4. - ///
      • For low cardinality fields larger precision steps are good. If the cardinality is < 100, it is - /// fair to use {@link Integer#MAX_VALUE} (see below). - ///
      • Steps >=64 for long/double and >=32 for int/float produces one token per value in the index and - /// querying is as slow as a conventional {@link TermRangeQuery}. But it can be used to produce fields, - /// that are solely used for sorting (in this case simply use {@link Integer#MAX_VALUE} as precisionStep). - /// Using {@link NumericField NumericFields} for sorting is ideal, because building the field cache is much - /// faster than with text-only numbers. These fields have one term per value and therefore also work with - /// term enumeration for building distinct lists (eg. facets / preselected values to search for). - /// Sorting is also possible with range query optimized fields using one of the above precisionSteps. - ///
      - /// - /// Comparisons of the different types of RangeQueries on an index with about 500,000 docs showed that - /// {@link TermRangeQuery} in boolean rewrite mode (with raised {@link BooleanQuery} clause count) took - /// about 30-40 secs to complete, {@link TermRangeQuery} in constant score filter rewrite mode took 5 secs - /// and executing this class took <100ms to complete (on an Opteron64 machine, 8 bit precision step). This - /// query type was developed for a geographic portal, where the performance for eg. bounding boxes or exact - /// date/time stamps is important. - class LPPAPI NumericRangeQuery : public MultiTermQuery - { - public: - NumericRangeQuery(const String& field, int32_t precisionStep, int32_t valSize, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - virtual ~NumericRangeQuery(); - - LUCENE_CLASS(NumericRangeQuery); - - INTERNAL: - String field; - int32_t precisionStep; - int32_t valSize; - NumericValue min; - NumericValue max; - bool minInclusive; - bool maxInclusive; - - public: - using MultiTermQuery::toString; - - /// Factory that creates a NumericRangeFilter, that filters a long range using the given precisionStep. - static NumericRangeQueryPtr newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep - /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). - static NumericRangeQueryPtr newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int range using the given precisionStep. - static NumericRangeQueryPtr newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep - /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). - static NumericRangeQueryPtr newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a double range using the given precisionStep. - static NumericRangeQueryPtr newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep - /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). - static NumericRangeQueryPtr newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the given - /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min - /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents - /// excluding the bounds, with inclusive on the boundaries are hits, too. - static NumericRangeQueryPtr newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - - /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the default - /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which - /// are in fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting - /// inclusive to false it will match all documents excluding the bounds, with inclusive on the boundaries - /// are hits, too. - static NumericRangeQueryPtr newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); - - /// Returns the field name for this query - String getField(); - - /// Returns true if the lower endpoint is inclusive - bool includesMin(); - - /// Returns true if the upper endpoint is inclusive - bool includesMax(); - - /// Returns the lower value of this range query - NumericValue getMin(); - - /// Returns the upper value of this range query - NumericValue getMax(); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - protected: - virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); - - friend class NumericRangeTermEnum; - }; +namespace Lucene { + +/// A {@link Query} that matches numeric values within a specified range. To use this, you must first +/// index the numeric values using {@link NumericField} (expert: {@link NumericTokenStream}). If your +/// terms are instead textual, you should use {@link TermRangeQuery}. {@link NumericRangeFilter} is the +/// filter equivalent of this query. +/// +/// You create a new NumericRangeQuery with the static factory methods, eg: +///
      +/// QueryPtr q = NumericRangeQuery::newDoubleRange("weight", 0.3, 0.10, true, true);
      +/// 
      +/// matches all documents whose double valued "weight" field ranges from 0.3 to 0.10, inclusive. +/// +/// The performance of NumericRangeQuery is much better than the corresponding {@link TermRangeQuery} +/// because the number of terms that must be searched is usually far fewer, thanks to trie indexing, +/// described below. +/// +/// You can optionally specify a precisionStep when creating this query. This is necessary if you've +/// changed this configuration from its default (4) during indexing. Lower values consume more disk +/// space but speed up searching. Suitable values are between 1 and 8. A good starting point to test +/// is 4, which is the default value for all Numeric* classes. See below for details. +/// +/// This query defaults to {@linkplain MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} for 32 bit +/// integer ranges with precisionStep <=8 and 64 bit (long/double) ranges with precisionStep <=6. +/// Otherwise it uses {@linkplain MultiTermQuery#CONSTANT_SCORE_FILTER_REWRITE} as the number of terms +/// is likely to be high. With precision steps of <=4, this query can be run with one of the BooleanQuery +/// rewrite methods without changing BooleanQuery's default max clause count. +/// +/// How it works +/// +/// See the publication about panFMP, where this +/// algorithm was described (referred to as TrieRangeQuery): +///
      Schindler, U, Diepenbroek, M, 2008. +/// Generic XML-based Framework for Metadata Portals. +/// Computers & Geosciences 34 (12), 1947-1955. +/// doi:10.1016/j.cageo.2008.02.023
      +/// +/// A quote from this paper: Because Apache Lucene is a full-text search engine and not a conventional +/// database, it cannot handle numerical ranges (eg., field value is inside user defined bounds, even +/// dates are numerical values). We have developed an extension to Apache Lucene that stores the +/// numerical values in a special string-encoded format with variable precision (all numerical values like +/// doubles, longs, and ints are converted to lexicographic sortable string representations and stored +/// with different precisions (for a more detailed description of how the values are stored, see {@link +/// NumericUtils}). A range is then divided recursively into multiple intervals for searching: +/// The center of the range is searched only with the lowest possible precision in the trie, while the +/// boundaries are matched more exactly. This reduces the number of terms dramatically. +/// +/// For the variant that stores long values in 8 different precisions (each reduced by 8 bits) that uses a +/// lowest precision of 1 byte, the index contains only a maximum of 256 distinct values in the lowest +/// precision. Overall, a range could consist of a theoretical maximum of 7*255*2 + 255 = 3825 distinct +/// terms (when there is a term for every distinct value of an 8-byte-number in the index and the range +/// covers almost all of them; a maximum of 255 distinct values is used because it would always be possible +/// to reduce the full 256 values to one term with degraded precision). In practice, we have seen up to +/// 300 terms in most cases (index with 500,000 metadata records and a uniform value distribution). +/// +/// Precision Step: +/// You can choose any precisionStep when encoding values. Lower step values mean more precisions and so +/// more terms in index (and index gets larger). On the other hand, the maximum number of terms to match +/// reduces, which optimized query speed. The formula to calculate the maximum term count is: +///
      +/// n = [ (bitsPerValue/precisionStep - 1) * (2 ^ precisionStep - 1 ) * 2 ] + (2 ^ precisionStep - 1 )
      +/// 
      +/// +/// (this formula is only correct, when bitsPerValue/precisionStep is an integer; in other cases, the value +/// must be rounded up and the last summand must contain the modulo of the division as precision step). +/// For longs stored using a precision step of 4, n = 15*15*2 + 15 = 465, and for a precision step of 2, +/// n = 31*3*2 + 3 = 189. But the faster search speed is reduced by more seeking in the term enum of the +/// index. Because of this, the ideal precisionStep value can only be found out by testing. Important: You +/// can index with a lower precision step value and test search speed using a multiple of the original step +/// value. +/// +/// Good values for precisionStep are depending on usage and data type: +///
        +///
      • The default for all data types is 4, which is used, when no precisionStep is given. +///
      • Ideal value in most cases for 64 bit data types (long, double) is 6 or 8. +///
      • Ideal value in most cases for 32 bit data types (int) is 4. +///
      • For low cardinality fields larger precision steps are good. If the cardinality is < 100, it is +/// fair to use {@link Integer#MAX_VALUE} (see below). +///
      • Steps >=64 for long/double and >=32 for int/float produces one token per value in the index and +/// querying is as slow as a conventional {@link TermRangeQuery}. But it can be used to produce fields, +/// that are solely used for sorting (in this case simply use {@link Integer#MAX_VALUE} as precisionStep). +/// Using {@link NumericField NumericFields} for sorting is ideal, because building the field cache is much +/// faster than with text-only numbers. These fields have one term per value and therefore also work with +/// term enumeration for building distinct lists (eg. facets / preselected values to search for). +/// Sorting is also possible with range query optimized fields using one of the above precisionSteps. +///
      +/// +/// Comparisons of the different types of RangeQueries on an index with about 500,000 docs showed that +/// {@link TermRangeQuery} in boolean rewrite mode (with raised {@link BooleanQuery} clause count) took +/// about 30-40 secs to complete, {@link TermRangeQuery} in constant score filter rewrite mode took 5 secs +/// and executing this class took <100ms to complete (on an Opteron64 machine, 8 bit precision step). This +/// query type was developed for a geographic portal, where the performance for eg. bounding boxes or exact +/// date/time stamps is important. +class LPPAPI NumericRangeQuery : public MultiTermQuery { +public: + NumericRangeQuery(const String& field, int32_t precisionStep, int32_t valSize, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); + virtual ~NumericRangeQuery(); + + LUCENE_CLASS(NumericRangeQuery); + +INTERNAL: + String field; + int32_t precisionStep; + int32_t valSize; + NumericValue min; + NumericValue max; + bool minInclusive; + bool maxInclusive; + +public: + using MultiTermQuery::toString; + + /// Factory that creates a NumericRangeFilter, that filters a long range using the given precisionStep. + static NumericRangeQueryPtr newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a long range using the default precisionStep + /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + static NumericRangeQueryPtr newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a int range using the given precisionStep. + static NumericRangeQueryPtr newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a int range using the default precisionStep + /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + static NumericRangeQueryPtr newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a double range using the given precisionStep. + static NumericRangeQueryPtr newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeFilter, that filters a double range using the default precisionStep + /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). + static NumericRangeQueryPtr newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the given + /// precisionStep. You can have half-open ranges (which are in fact <= or >= queries) by setting the min + /// or max value to VariantUtils::null(). By setting inclusive to false it will match all documents + /// excluding the bounds, with inclusive on the boundaries are hits, too. + static NumericRangeQueryPtr newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); + + /// Factory that creates a NumericRangeQuery, that queries a int, long or double range using the default + /// precisionStep {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). You can have half-open ranges (which + /// are in fact <= or >= queries) by setting the min or max value to VariantUtils::null(). By setting + /// inclusive to false it will match all documents excluding the bounds, with inclusive on the boundaries + /// are hits, too. + static NumericRangeQueryPtr newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive); + + /// Returns the field name for this query + String getField(); + + /// Returns true if the lower endpoint is inclusive + bool includesMin(); + + /// Returns true if the upper endpoint is inclusive + bool includesMax(); + + /// Returns the lower value of this range query + NumericValue getMin(); + + /// Returns the upper value of this range query + NumericValue getMax(); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + +protected: + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); + + friend class NumericRangeTermEnum; +}; + } #endif diff --git a/include/NumericTokenStream.h b/include/NumericTokenStream.h index c361106f..3d8970b1 100644 --- a/include/NumericTokenStream.h +++ b/include/NumericTokenStream.h @@ -9,112 +9,112 @@ #include "TokenStream.h" -namespace Lucene -{ - /// This class provides a {@link TokenStream} for indexing numeric values that can be used by {@link NumericRangeQuery} - /// or {@link NumericRangeFilter}. - /// - /// Note that for simple usage, {@link NumericField} is recommended. {@link NumericField} disables norms and term freqs, - /// as they are not usually needed during searching. If you need to change these settings, you should use this class. - /// - /// See {@link NumericField} for capabilities of fields indexed numerically. - /// - /// Here's an example usage, for an int field: - /// - /// FieldPtr field = newLucene(name, newLucene(precisionStep)->setIntValue(value)); - /// field->setOmitNorms(true); - /// field->setOmitTermFreqAndPositions(true); - /// document->add(field); - /// - /// For optimal performance, re-use the TokenStream and Field instance for more than one document: - /// - /// NumericTokenStreamPtr stream = newLucene(precisionStep); - /// FieldPtr field = newLucene(name, stream); - /// field->setOmitNorms(true); - /// field->setOmitTermFreqAndPositions(true); - /// DocumentPtr document = newLucene(); - /// document->add(field); - /// - /// for (all documents) - /// { - /// stream->setIntValue(value); - /// writer->addDocument(document); - /// } - /// - /// This stream is not intended to be used in analyzers; it's more for iterating the different precisions during - /// indexing a specific numeric value. - /// - /// NOTE: as token streams are only consumed once the document is added to the index, if you index more than one - /// numeric field, use a separate NumericTokenStream * instance for each. - /// - /// See {@link NumericRangeQuery} for more details on the precisionStep - /// parameter as well as how numeric fields work under the hood. - class LPPAPI NumericTokenStream : public TokenStream - { - public: - /// Creates a token stream for numeric values using the default precisionStep {@link - /// NumericUtils#PRECISION_STEP_DEFAULT} (4). The stream is not yet initialized, before using set a - /// value using the various setValue() methods. - NumericTokenStream(); - - /// Creates a token stream for numeric values with the specified precisionStep. The stream is not yet - /// initialized, before using set a value using the various setValue() methods. - NumericTokenStream(int32_t precisionStep); - - /// Creates a token stream for numeric values with the specified precisionStep using the given {@link - /// AttributeSource}. The stream is not yet initialized, before using set a value using the various - /// setValue() methods. - NumericTokenStream(const AttributeSourcePtr& source, int32_t precisionStep); - - /// Creates a token stream for numeric values with the specified precisionStep using the given {@link - /// AttributeFactory}. The stream is not yet initialized, before using set a value using the various - /// setValue() methods. - NumericTokenStream(const AttributeFactoryPtr& factory, int32_t precisionStep); - - virtual ~NumericTokenStream(); - - LUCENE_CLASS(NumericTokenStream); - - protected: - TermAttributePtr termAtt; - TypeAttributePtr typeAtt; - PositionIncrementAttributePtr posIncrAtt; - - int32_t shift; - int32_t valSize; // valSize == 0 means not initialized - int32_t precisionStep; - - int64_t value; - - public: - /// The full precision token gets this token type assigned. - static const String& TOKEN_TYPE_FULL_PREC(); - - /// The lower precision tokens gets this token type assigned. - static const String& TOKEN_TYPE_LOWER_PREC(); - - /// Initializes the token stream with the supplied long value. - /// @param value the value, for which this TokenStream should enumerate tokens. - /// @return this instance, because of this you can use it the following way: - /// newLucene(name, newLucene(precisionStep)->setLongValue(value)) - NumericTokenStreamPtr setLongValue(int64_t value); - - /// Initializes the token stream with the supplied int value. - /// @param value the value, for which this TokenStream should enumerate tokens. - /// @return this instance, because of this you can use it the following way: - /// newLucene(name, newLucene(precisionStep)->setIntValue(value)) - NumericTokenStreamPtr setIntValue(int32_t value); - - /// Initializes the token stream with the supplied double value. - /// @param value the value, for which this TokenStream should enumerate tokens. - /// @return this instance, because of this you can use it the following way: - /// newLucene(name, newLucene(precisionStep)->setDoubleValue(value)) - NumericTokenStreamPtr setDoubleValue(double value); - - virtual void reset(); - virtual bool incrementToken(); - virtual String toString(); - }; +namespace Lucene { + +/// This class provides a {@link TokenStream} for indexing numeric values that can be used by {@link NumericRangeQuery} +/// or {@link NumericRangeFilter}. +/// +/// Note that for simple usage, {@link NumericField} is recommended. {@link NumericField} disables norms and term freqs, +/// as they are not usually needed during searching. If you need to change these settings, you should use this class. +/// +/// See {@link NumericField} for capabilities of fields indexed numerically. +/// +/// Here's an example usage, for an int field: +/// +/// FieldPtr field = newLucene(name, newLucene(precisionStep)->setIntValue(value)); +/// field->setOmitNorms(true); +/// field->setOmitTermFreqAndPositions(true); +/// document->add(field); +/// +/// For optimal performance, re-use the TokenStream and Field instance for more than one document: +/// +/// NumericTokenStreamPtr stream = newLucene(precisionStep); +/// FieldPtr field = newLucene(name, stream); +/// field->setOmitNorms(true); +/// field->setOmitTermFreqAndPositions(true); +/// DocumentPtr document = newLucene(); +/// document->add(field); +/// +/// for (all documents) +/// { +/// stream->setIntValue(value); +/// writer->addDocument(document); +/// } +/// +/// This stream is not intended to be used in analyzers; it's more for iterating the different precisions during +/// indexing a specific numeric value. +/// +/// NOTE: as token streams are only consumed once the document is added to the index, if you index more than one +/// numeric field, use a separate NumericTokenStream * instance for each. +/// +/// See {@link NumericRangeQuery} for more details on the precisionStep +/// parameter as well as how numeric fields work under the hood. +class LPPAPI NumericTokenStream : public TokenStream { +public: + /// Creates a token stream for numeric values using the default precisionStep {@link + /// NumericUtils#PRECISION_STEP_DEFAULT} (4). The stream is not yet initialized, before using set a + /// value using the various setValue() methods. + NumericTokenStream(); + + /// Creates a token stream for numeric values with the specified precisionStep. The stream is not yet + /// initialized, before using set a value using the various setValue() methods. + NumericTokenStream(int32_t precisionStep); + + /// Creates a token stream for numeric values with the specified precisionStep using the given {@link + /// AttributeSource}. The stream is not yet initialized, before using set a value using the various + /// setValue() methods. + NumericTokenStream(const AttributeSourcePtr& source, int32_t precisionStep); + + /// Creates a token stream for numeric values with the specified precisionStep using the given {@link + /// AttributeFactory}. The stream is not yet initialized, before using set a value using the various + /// setValue() methods. + NumericTokenStream(const AttributeFactoryPtr& factory, int32_t precisionStep); + + virtual ~NumericTokenStream(); + + LUCENE_CLASS(NumericTokenStream); + +protected: + TermAttributePtr termAtt; + TypeAttributePtr typeAtt; + PositionIncrementAttributePtr posIncrAtt; + + int32_t shift; + int32_t valSize; // valSize == 0 means not initialized + int32_t precisionStep; + + int64_t value; + +public: + /// The full precision token gets this token type assigned. + static const String& TOKEN_TYPE_FULL_PREC(); + + /// The lower precision tokens gets this token type assigned. + static const String& TOKEN_TYPE_LOWER_PREC(); + + /// Initializes the token stream with the supplied long value. + /// @param value the value, for which this TokenStream should enumerate tokens. + /// @return this instance, because of this you can use it the following way: + /// newLucene(name, newLucene(precisionStep)->setLongValue(value)) + NumericTokenStreamPtr setLongValue(int64_t value); + + /// Initializes the token stream with the supplied int value. + /// @param value the value, for which this TokenStream should enumerate tokens. + /// @return this instance, because of this you can use it the following way: + /// newLucene(name, newLucene(precisionStep)->setIntValue(value)) + NumericTokenStreamPtr setIntValue(int32_t value); + + /// Initializes the token stream with the supplied double value. + /// @param value the value, for which this TokenStream should enumerate tokens. + /// @return this instance, because of this you can use it the following way: + /// newLucene(name, newLucene(precisionStep)->setDoubleValue(value)) + NumericTokenStreamPtr setDoubleValue(double value); + + virtual void reset(); + virtual bool incrementToken(); + virtual String toString(); +}; + } #endif diff --git a/include/NumericUtils.h b/include/NumericUtils.h index fb302aca..28603586 100644 --- a/include/NumericUtils.h +++ b/include/NumericUtils.h @@ -9,172 +9,170 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This is a helper class to generate prefix-encoded representations for numerical values and supplies converters - /// to represent double values as sortable integers/longs. - /// - /// To quickly execute range queries in Apache Lucene, a range is divided recursively into multiple intervals for - /// searching: The center of the range is searched only with the lowest possible precision in the trie, while the - /// boundaries are matched more exactly. This reduces the number of terms dramatically. - /// - /// This class generates terms to achieve this: First the numerical integer values need to be converted to strings. - /// For that integer values (32 bit or 64 bit) are made unsigned and the bits are converted to ASCII chars with each - /// 7 bit. The resulting string is sortable like the original integer value. Each value is also prefixed (in the - /// first char) by the shift value (number of bits removed) used during encoding. - /// - /// To also index floating point numbers, this class supplies two methods to convert them to integer values by - /// changing their bit layout: {@link #doubleToSortableLong}, {@link #doubleToSortableInt}. You will have no precision - /// loss by converting floating point numbers to integers and back (only that the integer form is not usable). Other - /// data types like dates can easily converted to longs or ints (eg. date to long). - /// - /// For easy usage, the trie algorithm is implemented for indexing inside {@link NumericTokenStream} that can index - /// int, long, and double. For querying, {@link NumericRangeQuery} and {@link NumericRangeFilter} implement the query - /// part for the same data types. - /// - /// This class can also be used, to generate lexicographically sortable (according {@link std::string#compare}) - /// representations of numeric data types for other usages (eg. sorting). - class LPPAPI NumericUtils : public LuceneObject - { - public: - virtual ~NumericUtils(); - - LUCENE_CLASS(NumericUtils); - - public: - /// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, - /// and {@link NumericRangeFilter} as default. - static const int32_t PRECISION_STEP_DEFAULT; - - /// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + - /// shift in the first character. - static const wchar_t SHIFT_START_LONG; - - /// The maximum term length (used for char[] buffer size) for encoding long values. - /// @see #longToPrefixCoded(long,int,char[]) - static const int32_t BUF_SIZE_LONG; - - /// Integers are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_INT + - /// shift in the first character. - static const wchar_t SHIFT_START_INT; - - /// The maximum term length (used for char[] buffer size) for encoding int values. - /// @see #intToPrefixCoded(int,int,char[]) - static const int32_t BUF_SIZE_INT; - - public: - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by - /// {@link NumericTokenStream}. - /// @param val the numeric value - /// @param shift how many bits to strip from the right - /// @param buffer that will contain the encoded chars, must be at least of {@link #BUF_SIZE_LONG} length - /// @return number of chars written to buffer - static int32_t longToPrefixCoded(int64_t val, int32_t shift, CharArray buffer); - - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by - /// {@link LongRangeBuilder}. - /// @param val the numeric value - /// @param shift how many bits to strip from the right - static String longToPrefixCoded(int64_t val, int32_t shift); - - /// This is a convenience method, that returns prefix coded bits of a long without reducing the precision. - /// It can be used to store the full precision value as a stored field in index. - /// To decode, use {@link #prefixCodedToLong}. - static String longToPrefixCoded(int64_t val); - - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link - /// NumericTokenStream}. - /// @param val the numeric value - /// @param shift how many bits to strip from the right - /// @param buffer that will contain the encoded chars, must be at least of {@link #BUF_SIZE_INT} length - /// @return number of chars written to buffer - static int32_t intToPrefixCoded(int32_t val, int32_t shift, CharArray buffer); - - /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link - /// IntRangeBuilder}. - /// @param val the numeric value - /// @param shift how many bits to strip from the right - static String intToPrefixCoded(int32_t val, int32_t shift); - - /// This is a convenience method, that returns prefix coded bits of an int without reducing the precision. - /// It can be used to store the full precision value as a stored field in index. - /// To decode, use {@link #prefixCodedToInt}. - static String intToPrefixCoded(int32_t val); - - /// Returns a long from prefixCoded characters. Rightmost bits will be zero for lower precision codes. - /// This method can be used to decode eg. a stored field. - /// @see #longToPrefixCoded(int64_t) - static int64_t prefixCodedToLong(const String& prefixCoded); - - /// Returns an int from prefixCoded characters. Rightmost bits will be zero for lower precision codes. - /// This method can be used to decode eg. a stored field. - /// @see #intToPrefixCoded(int32_t) - static int32_t prefixCodedToInt(const String& prefixCoded); - - /// Converts a double value to a sortable signed long. The value is converted by getting their IEEE 754 - /// floating-point "double format" bit layout and then some bits are swapped, to be able to compare the - /// result as int64_t. By this the precision is not reduced, but the value can easily used as a int64_t. - /// @see #sortableLongToDouble - static int64_t doubleToSortableLong(double val); - - /// Convenience method: this just returns: longToPrefixCoded(doubleToSortableLong(val)) - static String doubleToPrefixCoded(double val); - - /// Converts a sortable long back to a double. - /// @see #doubleToSortableLong - static double sortableLongToDouble(int64_t val); - - /// Convenience method: this just returns: sortableLongToDouble(prefixCodedToLong(val)) - static double prefixCodedToDouble(const String& val); - - /// Splits a int64_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} - /// for each call to its {@link LongRangeBuilder#addRange(String,String)} method. - /// This method is used by {@link NumericRangeQuery}. - static void splitLongRange(const LongRangeBuilderPtr& builder, int32_t precisionStep, int64_t minBound, int64_t maxBound); - - /// Splits an int32_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} - /// for each call to its {@link IntRangeBuilder#addRange(String,String)} method. - /// This method is used by {@link NumericRangeQuery}. - static void splitIntRange(const IntRangeBuilderPtr& builder, int32_t precisionStep, int32_t minBound, int32_t maxBound); - - /// This helper does the splitting for both 32 and 64 bit. - static void splitRange(const LuceneObjectPtr& builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound); - - /// Helper that delegates to correct range builder - static void addRange(const LuceneObjectPtr& builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift); - }; - - /// Callback for {@link #splitLongRange}. You need to overwrite only one of the methods. - /// NOTE: This is a very low-level interface, the method signatures may change in later versions. - class LPPAPI LongRangeBuilder : public LuceneObject - { - public: - virtual ~LongRangeBuilder(); - - public: - /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build - /// classical (inclusive) range queries from them. - virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); - - /// Overwrite this method, if you like to receive the raw long range bounds. You can use this for eg. debugging - /// purposes (print out range bounds). - virtual void addRange(int64_t min, int64_t max, int32_t shift); - }; - - class LPPAPI IntRangeBuilder : public LuceneObject - { - public: - virtual ~IntRangeBuilder(); - - public: - /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build - /// classical range (inclusive) queries from them. - virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); - - /// Overwrite this method, if you like to receive the raw int range bounds. You can use this for eg. debugging - /// purposes (print out range bounds). - virtual void addRange(int32_t min, int32_t max, int32_t shift); - }; +namespace Lucene { + +/// This is a helper class to generate prefix-encoded representations for numerical values and supplies converters +/// to represent double values as sortable integers/longs. +/// +/// To quickly execute range queries in Apache Lucene, a range is divided recursively into multiple intervals for +/// searching: The center of the range is searched only with the lowest possible precision in the trie, while the +/// boundaries are matched more exactly. This reduces the number of terms dramatically. +/// +/// This class generates terms to achieve this: First the numerical integer values need to be converted to strings. +/// For that integer values (32 bit or 64 bit) are made unsigned and the bits are converted to ASCII chars with each +/// 7 bit. The resulting string is sortable like the original integer value. Each value is also prefixed (in the +/// first char) by the shift value (number of bits removed) used during encoding. +/// +/// To also index floating point numbers, this class supplies two methods to convert them to integer values by +/// changing their bit layout: {@link #doubleToSortableLong}, {@link #doubleToSortableInt}. You will have no precision +/// loss by converting floating point numbers to integers and back (only that the integer form is not usable). Other +/// data types like dates can easily converted to longs or ints (eg. date to long). +/// +/// For easy usage, the trie algorithm is implemented for indexing inside {@link NumericTokenStream} that can index +/// int, long, and double. For querying, {@link NumericRangeQuery} and {@link NumericRangeFilter} implement the query +/// part for the same data types. +/// +/// This class can also be used, to generate lexicographically sortable (according {@link std::string#compare}) +/// representations of numeric data types for other usages (eg. sorting). +class LPPAPI NumericUtils : public LuceneObject { +public: + virtual ~NumericUtils(); + + LUCENE_CLASS(NumericUtils); + +public: + /// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, + /// and {@link NumericRangeFilter} as default. + static const int32_t PRECISION_STEP_DEFAULT; + + /// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + + /// shift in the first character. + static const wchar_t SHIFT_START_LONG; + + /// The maximum term length (used for char[] buffer size) for encoding long values. + /// @see #longToPrefixCoded(long,int,char[]) + static const int32_t BUF_SIZE_LONG; + + /// Integers are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_INT + + /// shift in the first character. + static const wchar_t SHIFT_START_INT; + + /// The maximum term length (used for char[] buffer size) for encoding int values. + /// @see #intToPrefixCoded(int,int,char[]) + static const int32_t BUF_SIZE_INT; + +public: + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by + /// {@link NumericTokenStream}. + /// @param val the numeric value + /// @param shift how many bits to strip from the right + /// @param buffer that will contain the encoded chars, must be at least of {@link #BUF_SIZE_LONG} length + /// @return number of chars written to buffer + static int32_t longToPrefixCoded(int64_t val, int32_t shift, CharArray buffer); + + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by + /// {@link LongRangeBuilder}. + /// @param val the numeric value + /// @param shift how many bits to strip from the right + static String longToPrefixCoded(int64_t val, int32_t shift); + + /// This is a convenience method, that returns prefix coded bits of a long without reducing the precision. + /// It can be used to store the full precision value as a stored field in index. + /// To decode, use {@link #prefixCodedToLong}. + static String longToPrefixCoded(int64_t val); + + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link + /// NumericTokenStream}. + /// @param val the numeric value + /// @param shift how many bits to strip from the right + /// @param buffer that will contain the encoded chars, must be at least of {@link #BUF_SIZE_INT} length + /// @return number of chars written to buffer + static int32_t intToPrefixCoded(int32_t val, int32_t shift, CharArray buffer); + + /// Returns prefix coded bits after reducing the precision by shift bits. This is method is used by {@link + /// IntRangeBuilder}. + /// @param val the numeric value + /// @param shift how many bits to strip from the right + static String intToPrefixCoded(int32_t val, int32_t shift); + + /// This is a convenience method, that returns prefix coded bits of an int without reducing the precision. + /// It can be used to store the full precision value as a stored field in index. + /// To decode, use {@link #prefixCodedToInt}. + static String intToPrefixCoded(int32_t val); + + /// Returns a long from prefixCoded characters. Rightmost bits will be zero for lower precision codes. + /// This method can be used to decode eg. a stored field. + /// @see #longToPrefixCoded(int64_t) + static int64_t prefixCodedToLong(const String& prefixCoded); + + /// Returns an int from prefixCoded characters. Rightmost bits will be zero for lower precision codes. + /// This method can be used to decode eg. a stored field. + /// @see #intToPrefixCoded(int32_t) + static int32_t prefixCodedToInt(const String& prefixCoded); + + /// Converts a double value to a sortable signed long. The value is converted by getting their IEEE 754 + /// floating-point "double format" bit layout and then some bits are swapped, to be able to compare the + /// result as int64_t. By this the precision is not reduced, but the value can easily used as a int64_t. + /// @see #sortableLongToDouble + static int64_t doubleToSortableLong(double val); + + /// Convenience method: this just returns: longToPrefixCoded(doubleToSortableLong(val)) + static String doubleToPrefixCoded(double val); + + /// Converts a sortable long back to a double. + /// @see #doubleToSortableLong + static double sortableLongToDouble(int64_t val); + + /// Convenience method: this just returns: sortableLongToDouble(prefixCodedToLong(val)) + static double prefixCodedToDouble(const String& val); + + /// Splits a int64_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} + /// for each call to its {@link LongRangeBuilder#addRange(String,String)} method. + /// This method is used by {@link NumericRangeQuery}. + static void splitLongRange(const LongRangeBuilderPtr& builder, int32_t precisionStep, int64_t minBound, int64_t maxBound); + + /// Splits an int32_t range recursively. You may implement a builder that adds clauses to a {@link BooleanQuery} + /// for each call to its {@link IntRangeBuilder#addRange(String,String)} method. + /// This method is used by {@link NumericRangeQuery}. + static void splitIntRange(const IntRangeBuilderPtr& builder, int32_t precisionStep, int32_t minBound, int32_t maxBound); + + /// This helper does the splitting for both 32 and 64 bit. + static void splitRange(const LuceneObjectPtr& builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound); + + /// Helper that delegates to correct range builder + static void addRange(const LuceneObjectPtr& builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift); +}; + +/// Callback for {@link #splitLongRange}. You need to overwrite only one of the methods. +/// NOTE: This is a very low-level interface, the method signatures may change in later versions. +class LPPAPI LongRangeBuilder : public LuceneObject { +public: + virtual ~LongRangeBuilder(); + +public: + /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build + /// classical (inclusive) range queries from them. + virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); + + /// Overwrite this method, if you like to receive the raw long range bounds. You can use this for eg. debugging + /// purposes (print out range bounds). + virtual void addRange(int64_t min, int64_t max, int32_t shift); +}; + +class LPPAPI IntRangeBuilder : public LuceneObject { +public: + virtual ~IntRangeBuilder(); + +public: + /// Overwrite this method, if you like to receive the already prefix encoded range bounds. You can directly build + /// classical range (inclusive) queries from them. + virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); + + /// Overwrite this method, if you like to receive the raw int range bounds. You can use this for eg. debugging + /// purposes (print out range bounds). + virtual void addRange(int32_t min, int32_t max, int32_t shift); +}; + } #endif diff --git a/include/OffsetAttribute.h b/include/OffsetAttribute.h index 5e038a0e..63ffb4b3 100644 --- a/include/OffsetAttribute.h +++ b/include/OffsetAttribute.h @@ -9,45 +9,45 @@ #include "Attribute.h" -namespace Lucene -{ - /// The start and end character offset of a Token. - class LPPAPI OffsetAttribute : public Attribute - { - public: - OffsetAttribute(); - virtual ~OffsetAttribute(); - - LUCENE_CLASS(OffsetAttribute); - - protected: - int32_t _startOffset; - int32_t _endOffset; - - public: - virtual String toString(); - - /// Returns this Token's starting offset, the position of the first character corresponding to this token - /// in the source text. - /// - /// Note that the difference between endOffset() and startOffset() may not be equal to termText.length(), - /// as the term text may have been altered by a stemmer or some other filter. - virtual int32_t startOffset(); - - /// Set the starting and ending offset. - /// @see #startOffset() and #endOffset() - virtual void setOffset(int32_t startOffset, int32_t endOffset); - - /// Returns this Token's ending offset, one greater than the position of the last character corresponding - /// to this token in the source text. The length of the token in the source text is (endOffset - startOffset). - virtual int32_t endOffset(); - - virtual void clear(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual void copyTo(const AttributePtr& target); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// The start and end character offset of a Token. +class LPPAPI OffsetAttribute : public Attribute { +public: + OffsetAttribute(); + virtual ~OffsetAttribute(); + + LUCENE_CLASS(OffsetAttribute); + +protected: + int32_t _startOffset; + int32_t _endOffset; + +public: + virtual String toString(); + + /// Returns this Token's starting offset, the position of the first character corresponding to this token + /// in the source text. + /// + /// Note that the difference between endOffset() and startOffset() may not be equal to termText.length(), + /// as the term text may have been altered by a stemmer or some other filter. + virtual int32_t startOffset(); + + /// Set the starting and ending offset. + /// @see #startOffset() and #endOffset() + virtual void setOffset(int32_t startOffset, int32_t endOffset); + + /// Returns this Token's ending offset, one greater than the position of the last character corresponding + /// to this token in the source text. The length of the token in the source text is (endOffset - startOffset). + virtual int32_t endOffset(); + + virtual void clear(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/include/OpenBitSet.h b/include/OpenBitSet.h index 7078f31c..b1dc6960 100644 --- a/include/OpenBitSet.h +++ b/include/OpenBitSet.h @@ -9,228 +9,228 @@ #include "DocIdSet.h" -namespace Lucene -{ - /// An "open" BitSet implementation that allows direct access to the array of words storing the bits. +namespace Lucene { + +/// An "open" BitSet implementation that allows direct access to the array of words storing the bits. +/// +/// The goals of OpenBitSet are the fastest implementation possible, and maximum code reuse. Extra +/// safety and encapsulation may always be built on top, but if that's built in, the cost can never +/// be removed (and hence people re-implement their own version in order to get better performance). +class LPPAPI OpenBitSet : public DocIdSet { +public: + /// Constructs an OpenBitSet large enough to hold numBits. + OpenBitSet(int64_t numBits = 64); + + /// Constructs an OpenBitSet from an existing LongArray. /// - /// The goals of OpenBitSet are the fastest implementation possible, and maximum code reuse. Extra - /// safety and encapsulation may always be built on top, but if that's built in, the cost can never - /// be removed (and hence people re-implement their own version in order to get better performance). - class LPPAPI OpenBitSet : public DocIdSet - { - public: - /// Constructs an OpenBitSet large enough to hold numBits. - OpenBitSet(int64_t numBits = 64); + /// 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. + OpenBitSet(LongArray bits, int32_t numWords); - /// Constructs an OpenBitSet from an existing LongArray. - /// - /// 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. - OpenBitSet(LongArray bits, int32_t numWords); + virtual ~OpenBitSet(); - virtual ~OpenBitSet(); + LUCENE_CLASS(OpenBitSet); - LUCENE_CLASS(OpenBitSet); +protected: + LongArray bits; + int32_t wlen; // number of words (elements) used in the array - protected: - LongArray bits; - int32_t wlen; // number of words (elements) used in the array +public: + virtual DocIdSetIteratorPtr iterator(); - public: - virtual DocIdSetIteratorPtr iterator(); + /// This DocIdSet implementation is cacheable. + virtual bool isCacheable(); - /// This DocIdSet implementation is cacheable. - virtual bool isCacheable(); + /// Returns the current capacity in bits (1 greater than the index of the last bit) + int64_t capacity(); - /// Returns the current capacity in bits (1 greater than the index of the last bit) - int64_t capacity(); + /// Returns the current capacity of this set. Included for compatibility. This is *not* + /// equal to {@link #cardinality} + int64_t size(); - /// Returns the current capacity of this set. Included for compatibility. This is *not* - /// equal to {@link #cardinality} - int64_t size(); + /// Returns true if there are no set bits + bool isEmpty(); - /// Returns true if there are no set bits - bool isEmpty(); + /// Returns the long[] storing the bits + LongArray getBits(); - /// Returns the long[] storing the bits - LongArray getBits(); + /// Sets a new long[] to use as the bit storage + void setBits(LongArray bits); - /// Sets a new long[] to use as the bit storage - void setBits(LongArray bits); + /// Gets the number of longs in the array that are in use + int32_t getNumWords(); - /// Gets the number of longs in the array that are in use - int32_t getNumWords(); + /// Sets the number of longs in the array that are in use + void setNumWords(int32_t numWords); - /// Sets the number of longs in the array that are in use - void setNumWords(int32_t numWords); + /// Returns true or false for the specified bit index. + bool get(int32_t index); - /// Returns true or false for the specified bit index. - bool get(int32_t index); + /// Returns true or false for the specified bit index. + /// The index should be less than the OpenBitSet size + bool fastGet(int32_t index); - /// Returns true or false for the specified bit index. - /// The index should be less than the OpenBitSet size - bool fastGet(int32_t index); + /// Returns true or false for the specified bit index + bool get(int64_t index); - /// Returns true or false for the specified bit index - bool get(int64_t index); + /// Returns true or false for the specified bit index. + /// The index should be less than the OpenBitSet size. + bool fastGet(int64_t index); - /// Returns true or false for the specified bit index. - /// The index should be less than the OpenBitSet size. - bool fastGet(int64_t index); + /// Returns 1 if the bit is set, 0 if not. + /// The index should be less than the OpenBitSet size + int32_t getBit(int32_t index); - /// Returns 1 if the bit is set, 0 if not. - /// The index should be less than the OpenBitSet size - int32_t getBit(int32_t index); + /// Sets a bit, expanding the set size if necessary + void set(int64_t index); - /// Sets a bit, expanding the set size if necessary - void set(int64_t index); + /// Sets the bit at the specified index. + /// The index should be less than the OpenBitSet size. + void fastSet(int32_t index); - /// Sets the bit at the specified index. - /// The index should be less than the OpenBitSet size. - void fastSet(int32_t index); + /// Sets the bit at the specified index. + /// The index should be less than the OpenBitSet size. + void fastSet(int64_t index); - /// Sets the bit at the specified index. - /// The index should be less than the OpenBitSet size. - void fastSet(int64_t index); + /// Sets a range of bits, expanding the set size if necessary + /// @param startIndex lower index + /// @param endIndex one-past the last bit to set + void set(int64_t startIndex, int64_t endIndex); - /// Sets a range of bits, expanding the set size if necessary - /// @param startIndex lower index - /// @param endIndex one-past the last bit to set - void set(int64_t startIndex, int64_t endIndex); + /// Clears a bit. + /// The index should be less than the OpenBitSet size. + void fastClear(int32_t index); - /// Clears a bit. - /// The index should be less than the OpenBitSet size. - void fastClear(int32_t index); + /// Clears a bit. + /// The index should be less than the OpenBitSet size. + void fastClear(int64_t index); - /// Clears a bit. - /// The index should be less than the OpenBitSet size. - void fastClear(int64_t index); + /// Clears a bit, allowing access beyond the current set size without changing the size. + void clear(int64_t index); - /// Clears a bit, allowing access beyond the current set size without changing the size. - void clear(int64_t index); + /// 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 + void clear(int32_t startIndex, int32_t endIndex); - /// 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 - void clear(int32_t startIndex, int32_t endIndex); + /// 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 + void clear(int64_t startIndex, int64_t endIndex); - /// 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 - void clear(int64_t startIndex, int64_t endIndex); + /// Sets a bit and returns the previous value. + /// The index should be less than the OpenBitSet size. + bool getAndSet(int32_t index); - /// Sets a bit and returns the previous value. - /// The index should be less than the OpenBitSet size. - bool getAndSet(int32_t index); + /// Sets a bit and returns the previous value. + /// The index should be less than the OpenBitSet size. + bool getAndSet(int64_t index); - /// Sets a bit and returns the previous value. - /// The index should be less than the OpenBitSet size. - bool getAndSet(int64_t index); + /// Flips a bit. + /// The index should be less than the OpenBitSet size. + void fastFlip(int32_t index); - /// Flips a bit. - /// The index should be less than the OpenBitSet size. - void fastFlip(int32_t index); + /// Flips a bit. + /// The index should be less than the OpenBitSet size. + void fastFlip(int64_t index); - /// Flips a bit. - /// The index should be less than the OpenBitSet size. - void fastFlip(int64_t index); + /// Flips a bit, expanding the set size if necessary + void flip(int64_t index); - /// Flips a bit, expanding the set size if necessary - void flip(int64_t index); + /// Flips a bit and returns the resulting bit value. + /// The index should be less than the OpenBitSet size. + bool flipAndGet(int32_t index); - /// Flips a bit and returns the resulting bit value. - /// The index should be less than the OpenBitSet size. - bool flipAndGet(int32_t index); + /// Flips a bit and returns the resulting bit value. + /// The index should be less than the OpenBitSet size. + bool flipAndGet(int64_t index); - /// Flips a bit and returns the resulting bit value. - /// The index should be less than the OpenBitSet size. - bool flipAndGet(int64_t index); + /// Flips a range of bits, expanding the set size if necessary + /// @param startIndex lower index + /// @param endIndex one-past the last bit to flip + void flip(int64_t startIndex, int64_t endIndex); - /// Flips a range of bits, expanding the set size if necessary - /// @param startIndex lower index - /// @param endIndex one-past the last bit to flip - void flip(int64_t startIndex, int64_t endIndex); + /// @return the number of set bits + int64_t cardinality(); - /// @return the number of set bits - int64_t cardinality(); + /// Returns the popcount or cardinality of the intersection of the two sets. + /// Neither set is modified. + static int64_t intersectionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); - /// Returns the popcount or cardinality of the intersection of the two sets. - /// Neither set is modified. - static int64_t intersectionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); + /// Returns the popcount or cardinality of the union of the two sets. + /// Neither set is modified. + static int64_t unionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); - /// Returns the popcount or cardinality of the union of the two sets. - /// Neither set is modified. - static int64_t unionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); + /// Returns the popcount or cardinality of "a and not b" or "intersection(a, not(b))". + /// Neither set is modified. + static int64_t andNotCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); - /// Returns the popcount or cardinality of "a and not b" or "intersection(a, not(b))". - /// Neither set is modified. - static int64_t andNotCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); + /// Returns the popcount or cardinality of the exclusive-or of the two sets. + /// Neither set is modified. + static int64_t xorCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); - /// Returns the popcount or cardinality of the exclusive-or of the two sets. - /// Neither set is modified. - static int64_t xorCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b); + /// Returns the index of the first set bit starting at the index specified. + /// -1 is returned if there are no more set bits. + int32_t nextSetBit(int32_t index); - /// Returns the index of the first set bit starting at the index specified. - /// -1 is returned if there are no more set bits. - int32_t nextSetBit(int32_t index); + /// Returns the index of the first set bit starting at the index specified. + /// -1 is returned if there are no more set bits. + int64_t nextSetBit(int64_t index); - /// Returns the index of the first set bit starting at the index specified. - /// -1 is returned if there are no more set bits. - int64_t nextSetBit(int64_t index); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + /// this = this AND other + void intersect(const OpenBitSetPtr& other); - /// this = this AND other - void intersect(const OpenBitSetPtr& other); + /// this = this OR other + void _union(const OpenBitSetPtr& other); - /// this = this OR other - void _union(const OpenBitSetPtr& other); + /// Remove all elements set in other. this = this AND_NOT other + void remove(const OpenBitSetPtr& other); - /// Remove all elements set in other. this = this AND_NOT other - void remove(const OpenBitSetPtr& other); + /// this = this XOR other + void _xor(const OpenBitSetPtr& other); - /// this = this XOR other - void _xor(const OpenBitSetPtr& other); + /// see {@link intersect} + void _and(const OpenBitSetPtr& other); - /// see {@link intersect} - void _and(const OpenBitSetPtr& other); + /// see {@link union} + void _or(const OpenBitSetPtr& other); - /// see {@link union} - void _or(const OpenBitSetPtr& other); + /// see {@link remove} + void andNot(const OpenBitSetPtr& other); - /// see {@link remove} - void andNot(const OpenBitSetPtr& other); + /// Returns true if the sets have any elements in common + bool intersects(const OpenBitSetPtr& other); - /// Returns true if the sets have any elements in common - bool intersects(const OpenBitSetPtr& other); + /// Expand the LongArray with the size given as a number of words (64 bit longs). + /// getNumWords() is unchanged by this call. + void ensureCapacityWords(int32_t numWords); - /// Expand the LongArray with the size given as a number of words (64 bit longs). - /// getNumWords() is unchanged by this call. - void ensureCapacityWords(int32_t numWords); + /// Ensure that the LongArray is big enough to hold numBits, expanding it if necessary. + /// getNumWords() is unchanged by this call. + void ensureCapacity(int64_t numBits); - /// Ensure that the LongArray is big enough to hold numBits, expanding it if necessary. - /// getNumWords() is unchanged by this call. - void ensureCapacity(int64_t numBits); + /// Lowers numWords, the number of words in use, by checking for trailing zero words. + void trimTrailingZeros(); - /// Lowers numWords, the number of words in use, by checking for trailing zero words. - void trimTrailingZeros(); + /// Returns the number of 64 bit words it would take to hold numBits. + static int32_t bits2words(int64_t numBits); - /// Returns the number of 64 bit words it would take to hold numBits. - static int32_t bits2words(int64_t numBits); + /// Returns true if both sets have the same bits set + virtual bool equals(const LuceneObjectPtr& other); - /// Returns true if both sets have the same bits set - virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); - virtual int32_t hashCode(); +protected: + int32_t expandingWordNum(int64_t index); +}; - protected: - int32_t expandingWordNum(int64_t index); - }; } #endif diff --git a/include/OpenBitSetDISI.h b/include/OpenBitSetDISI.h index 50a351a3..b086931e 100644 --- a/include/OpenBitSetDISI.h +++ b/include/OpenBitSetDISI.h @@ -9,42 +9,42 @@ #include "OpenBitSet.h" -namespace Lucene -{ - class LPPAPI OpenBitSetDISI : public OpenBitSet - { - public: - /// Construct an OpenBitSetDISI with its bits set from the doc ids of the given DocIdSetIterator. - /// Also give a maximum size one larger than the largest doc id for which a bit may ever be set on - /// this OpenBitSetDISI. - OpenBitSetDISI(const DocIdSetIteratorPtr& disi, int32_t maxSize); - - /// Construct an OpenBitSetDISI with no bits set, and a given maximum size one larger than the largest - /// doc id for which a bit may ever be set on this OpenBitSetDISI. - OpenBitSetDISI(int32_t maxSize); - - virtual ~OpenBitSetDISI(); - - LUCENE_CLASS(OpenBitSetDISI); - - public: - /// Perform an in-place OR with the doc ids from a given DocIdSetIterator, setting the bit for each - /// such doc id. These doc ids should be smaller than the maximum size passed to the constructor. - void inPlaceOr(const DocIdSetIteratorPtr& disi); - - /// Perform an in-place AND with the doc ids from a given DocIdSetIterator, leaving only the bits set - /// for which the doc ids are in common. These doc ids should be smaller than the maximum size passed - /// to the constructor. - void inPlaceAnd(const DocIdSetIteratorPtr& disi); - - /// Perform an in-place NOT with the doc ids from a given DocIdSetIterator, clearing all the bits for - /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. - void inPlaceNot(const DocIdSetIteratorPtr& disi); - - /// Perform an inplace XOR with the doc ids from a given DocIdSetIterator, flipping all the bits for - /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. - void inPlaceXor(const DocIdSetIteratorPtr& disi); - }; +namespace Lucene { + +class LPPAPI OpenBitSetDISI : public OpenBitSet { +public: + /// Construct an OpenBitSetDISI with its bits set from the doc ids of the given DocIdSetIterator. + /// Also give a maximum size one larger than the largest doc id for which a bit may ever be set on + /// this OpenBitSetDISI. + OpenBitSetDISI(const DocIdSetIteratorPtr& disi, int32_t maxSize); + + /// Construct an OpenBitSetDISI with no bits set, and a given maximum size one larger than the largest + /// doc id for which a bit may ever be set on this OpenBitSetDISI. + OpenBitSetDISI(int32_t maxSize); + + virtual ~OpenBitSetDISI(); + + LUCENE_CLASS(OpenBitSetDISI); + +public: + /// Perform an in-place OR with the doc ids from a given DocIdSetIterator, setting the bit for each + /// such doc id. These doc ids should be smaller than the maximum size passed to the constructor. + void inPlaceOr(const DocIdSetIteratorPtr& disi); + + /// Perform an in-place AND with the doc ids from a given DocIdSetIterator, leaving only the bits set + /// for which the doc ids are in common. These doc ids should be smaller than the maximum size passed + /// to the constructor. + void inPlaceAnd(const DocIdSetIteratorPtr& disi); + + /// Perform an in-place NOT with the doc ids from a given DocIdSetIterator, clearing all the bits for + /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. + void inPlaceNot(const DocIdSetIteratorPtr& disi); + + /// Perform an inplace XOR with the doc ids from a given DocIdSetIterator, flipping all the bits for + /// each such doc id. These doc ids should be smaller than the maximum size passed to the constructor. + void inPlaceXor(const DocIdSetIteratorPtr& disi); +}; + } #endif diff --git a/include/OpenBitSetIterator.h b/include/OpenBitSetIterator.h index be0504db..15c7b112 100644 --- a/include/OpenBitSetIterator.h +++ b/include/OpenBitSetIterator.h @@ -9,44 +9,44 @@ #include "DocIdSetIterator.h" -namespace Lucene -{ - /// An iterator to iterate over set bits in an OpenBitSet. - /// This is faster than nextSetBit() for iterating over the complete set of bits, - /// especially when the density of the bits set is high. - class LPPAPI OpenBitSetIterator : public DocIdSetIterator - { - public: - OpenBitSetIterator(const OpenBitSetPtr& bitSet); - OpenBitSetIterator(LongArray bits, int32_t numWords); - virtual ~OpenBitSetIterator(); - - LUCENE_CLASS(OpenBitSetIterator); - - protected: - LongArray arr; - int32_t words; - int32_t i; - int64_t word; - int32_t wordShift; - int32_t indexArray; - int32_t curDocId; - - /// 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(int32_t))=1K - static const int32_t bitlist[]; - - public: - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - virtual int32_t docID(); - - protected: - /// 64 bit shifts - void shift(); - }; +namespace Lucene { + +/// An iterator to iterate over set bits in an OpenBitSet. +/// This is faster than nextSetBit() for iterating over the complete set of bits, +/// especially when the density of the bits set is high. +class LPPAPI OpenBitSetIterator : public DocIdSetIterator { +public: + OpenBitSetIterator(const OpenBitSetPtr& bitSet); + OpenBitSetIterator(LongArray bits, int32_t numWords); + virtual ~OpenBitSetIterator(); + + LUCENE_CLASS(OpenBitSetIterator); + +protected: + LongArray arr; + int32_t words; + int32_t i; + int64_t word; + int32_t wordShift; + int32_t indexArray; + int32_t curDocId; + + /// 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(int32_t))=1K + static const int32_t bitlist[]; + +public: + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); + virtual int32_t docID(); + +protected: + /// 64 bit shifts + void shift(); +}; + } #endif diff --git a/include/OrdFieldSource.h b/include/OrdFieldSource.h index 7ff6cd24..2fc43b4d 100644 --- a/include/OrdFieldSource.h +++ b/include/OrdFieldSource.h @@ -9,44 +9,44 @@ #include "ValueSource.h" -namespace Lucene -{ - /// Obtains the ordinal of the field value from the default Lucene {@link FieldCache} using getStringIndex(). - /// - /// The native lucene index order is used to assign an ordinal value for each field value. - /// - /// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1. - /// Example: - /// If there were only three field values: "apple","banana","pear" then ord("apple")=1, ord("banana")=2, - /// ord("pear")=3 - /// - /// WARNING: ord() depends on the position in an index and can thus change when other documents are inserted - /// or deleted, or if a MultiSearcher is used. - /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite - /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, - /// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU - /// per lookup but will not consume double the FieldCache RAM. - class LPPAPI OrdFieldSource : public ValueSource - { - public: - /// Constructor for a certain field. - ///@param field field whose values order is used. - OrdFieldSource(const String& field); - virtual ~OrdFieldSource(); - - LUCENE_CLASS(OrdFieldSource); - - protected: - String field; - - public: - virtual String description(); - virtual DocValuesPtr getValues(const IndexReaderPtr& reader); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// Obtains the ordinal of the field value from the default Lucene {@link FieldCache} using getStringIndex(). +/// +/// The native lucene index order is used to assign an ordinal value for each field value. +/// +/// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1. +/// Example: +/// If there were only three field values: "apple","banana","pear" then ord("apple")=1, ord("banana")=2, +/// ord("pear")=3 +/// +/// WARNING: ord() depends on the position in an index and can thus change when other documents are inserted +/// or deleted, or if a MultiSearcher is used. +/// +/// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite +/// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's +/// best to switch your application to pass only atomic (single segment) readers to this API. Alternatively, +/// for a short-term fix, you could wrap your ValueSource using {@link MultiValueSource}, which costs more CPU +/// per lookup but will not consume double the FieldCache RAM. +class LPPAPI OrdFieldSource : public ValueSource { +public: + /// Constructor for a certain field. + ///@param field field whose values order is used. + OrdFieldSource(const String& field); + virtual ~OrdFieldSource(); + + LUCENE_CLASS(OrdFieldSource); + +protected: + String field; + +public: + virtual String description(); + virtual DocValuesPtr getValues(const IndexReaderPtr& reader); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/ParallelMultiSearcher.h b/include/ParallelMultiSearcher.h index 36de1e8e..a22bb0a6 100644 --- a/include/ParallelMultiSearcher.h +++ b/include/ParallelMultiSearcher.h @@ -9,34 +9,34 @@ #include "MultiSearcher.h" -namespace Lucene -{ - /// Implements parallel search over a set of Searchables. - /// - /// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or - /// {@link #search(QueryPtr, FilterPtr, int32_t)} methods. - class LPPAPI ParallelMultiSearcher : public MultiSearcher - { - public: - /// Creates a {@link Searchable} which searches searchables. - ParallelMultiSearcher(Collection searchables); - virtual ~ParallelMultiSearcher(); - - LUCENE_CLASS(ParallelMultiSearcher); - - public: - /// Executes each {@link Searchable}'s docFreq() in its own thread and waits for each search to - /// complete and merge the results back together. - virtual int32_t docFreq(const TermPtr& term); - - /// A search implementation which executes each {@link Searchable} in its own thread and waits - /// for each search to complete and merge the results back together. - virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); - - /// A search implementation allowing sorting which spans a new thread for each Searchable, waits - /// for each search to complete and merges the results back together. - virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); - }; +namespace Lucene { + +/// Implements parallel search over a set of Searchables. +/// +/// Applications usually need only call the inherited {@link #search(QueryPtr, int32_t)} or +/// {@link #search(QueryPtr, FilterPtr, int32_t)} methods. +class LPPAPI ParallelMultiSearcher : public MultiSearcher { +public: + /// Creates a {@link Searchable} which searches searchables. + ParallelMultiSearcher(Collection searchables); + virtual ~ParallelMultiSearcher(); + + LUCENE_CLASS(ParallelMultiSearcher); + +public: + /// Executes each {@link Searchable}'s docFreq() in its own thread and waits for each search to + /// complete and merge the results back together. + virtual int32_t docFreq(const TermPtr& term); + + /// A search implementation which executes each {@link Searchable} in its own thread and waits + /// for each search to complete and merge the results back together. + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); + + /// A search implementation allowing sorting which spans a new thread for each Searchable, waits + /// for each search to complete and merges the results back together. + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); +}; + } #endif diff --git a/include/ParallelReader.h b/include/ParallelReader.h index d3799060..d01b8b54 100644 --- a/include/ParallelReader.h +++ b/include/ParallelReader.h @@ -9,173 +9,173 @@ #include "IndexReader.h" -namespace Lucene -{ - /// An IndexReader which reads multiple, parallel indexes. Each index added must have the same number of - /// documents, but typically each contains different fields. Each document contains the union of the fields - /// of all documents with the same document number. When searching, matches for a query term are from the - /// first index added that has the field. +namespace Lucene { + +/// An IndexReader which reads multiple, parallel indexes. Each index added must have the same number of +/// documents, but typically each contains different fields. Each document contains the union of the fields +/// of all documents with the same document number. When searching, matches for a query term are from the +/// first index added that has the field. +/// +/// This is useful, eg., with collections that have large fields which change rarely and small fields that +/// change more frequently. The smaller fields may be re-indexed in a new index and both indexes may be +/// searched together. +/// +/// Warning: It is up to you to make sure all indexes are created and modified the same way. For example, +/// if you add documents to one index, you need to add the same documents in the same order to the other +/// indexes. Failure to do so will result in undefined behavior +class LPPAPI ParallelReader : public IndexReader { +public: + /// Construct a ParallelReader. + /// @param closeSubReaders indicates whether the subreaders should be closed when this ParallelReader + /// is closed + ParallelReader(bool closeSubReaders = true); + + virtual ~ParallelReader(); + + LUCENE_CLASS(ParallelReader); + +protected: + Collection readers; + Collection decrefOnClose; // remember which subreaders to decRef on close + bool incRefReaders; + MapStringIndexReader fieldToReader; + MapIndexReaderSetString readerToFields; + Collection storedFieldReaders; + + int32_t _maxDoc; + int32_t _numDocs; + bool _hasDeletions; + +public: + /// Add an IndexReader. + void add(const IndexReaderPtr& reader); + + /// Add an IndexReader whose stored fields will not be returned. This can accelerate search when stored + /// fields are only needed from a subset of the IndexReaders. + void add(const IndexReaderPtr& reader, bool ignoreStoredFields); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Tries to reopen the subreaders. /// - /// This is useful, eg., with collections that have large fields which change rarely and small fields that - /// change more frequently. The smaller fields may be re-indexed in a new index and both indexes may be - /// searched together. + /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader), + /// then a new ParallelReader instance is returned, otherwise this instance is returned. /// - /// Warning: It is up to you to make sure all indexes are created and modified the same way. For example, - /// if you add documents to one index, you need to add the same documents in the same order to the other - /// indexes. Failure to do so will result in undefined behavior - class LPPAPI ParallelReader : public IndexReader - { - public: - /// Construct a ParallelReader. - /// @param closeSubReaders indicates whether the subreaders should be closed when this ParallelReader - /// is closed - ParallelReader(bool closeSubReaders = true); - - virtual ~ParallelReader(); - - LUCENE_CLASS(ParallelReader); - - protected: - Collection readers; - Collection decrefOnClose; // remember which subreaders to decRef on close - bool incRefReaders; - MapStringIndexReader fieldToReader; - MapIndexReaderSetString readerToFields; - Collection storedFieldReaders; - - int32_t _maxDoc; - int32_t _numDocs; - bool _hasDeletions; - - public: - /// Add an IndexReader. - void add(const IndexReaderPtr& reader); - - /// Add an IndexReader whose stored fields will not be returned. This can accelerate search when stored - /// fields are only needed from a subset of the IndexReaders. - void add(const IndexReaderPtr& reader, bool ignoreStoredFields); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + /// A re-opened instance might share one or more subreaders with the old instance. Index modification + /// operations result in undefined behavior when performed before the old instance is closed. + /// (see {@link IndexReader#reopen()}). + /// + /// If subreaders are shared, then the reference count of those readers is increased to ensure that the + /// subreaders remain open until the last referring reader is closed. + virtual IndexReaderPtr reopen(); - /// Tries to reopen the subreaders. - /// - /// If one or more subreaders could be re-opened (ie. subReader.reopen() returned a new instance != subReader), - /// then a new ParallelReader instance is returned, otherwise this instance is returned. - /// - /// A re-opened instance might share one or more subreaders with the old instance. Index modification - /// operations result in undefined behavior when performed before the old instance is closed. - /// (see {@link IndexReader#reopen()}). - /// - /// If subreaders are shared, then the reference count of those readers is increased to ensure that the - /// subreaders remain open until the last referring reader is closed. - virtual IndexReaderPtr reopen(); + /// Returns the number of documents in this index. + virtual int32_t numDocs(); - /// Returns the number of documents in this index. - virtual int32_t numDocs(); + /// Returns one greater than the largest possible document number. This may be used to, eg., determine + /// how big to allocate an array which will have an element for every document number in an index. + virtual int32_t maxDoc(); - /// Returns one greater than the largest possible document number. This may be used to, eg., determine - /// how big to allocate an array which will have an element for every document number in an index. - virtual int32_t maxDoc(); + /// Returns true if any documents have been deleted + virtual bool hasDeletions(); - /// Returns true if any documents have been deleted - virtual bool hasDeletions(); + /// Returns true if document n has been deleted + virtual bool isDeleted(int32_t n); - /// Returns true if document n has been deleted - virtual bool isDeleted(int32_t n); + /// Get the {@link Document} at the n'th position. + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); - /// Get the {@link Document} at the n'th position. - virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); + /// Return an array of term frequency vectors for the specified document. + virtual Collection getTermFreqVectors(int32_t docNumber); - /// Return an array of term frequency vectors for the specified document. - virtual Collection getTermFreqVectors(int32_t docNumber); + /// Return a term frequency vector for the specified document and field. + virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - /// Return a term frequency vector for the specified document and field. - virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays + /// of the {@link TermFreqVector}. + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); - /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays - /// of the {@link TermFreqVector}. - virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + /// Map all the term vectors for all fields in a Document + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); - /// Map all the term vectors for all fields in a Document - virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); + /// Returns true if there are norms stored for this field. + virtual bool hasNorms(const String& field); - /// Returns true if there are norms stored for this field. - virtual bool hasNorms(const String& field); + /// Returns the byte-encoded normalization factor for the named field of every document. + virtual ByteArray norms(const String& field); - /// Returns the byte-encoded normalization factor for the named field of every document. - virtual ByteArray norms(const String& field); + /// Reads the byte-encoded normalization factor for the named field of every document. + virtual void norms(const String& field, ByteArray norms, int32_t offset); - /// Reads the byte-encoded normalization factor for the named field of every document. - virtual void norms(const String& field, ByteArray norms, int32_t offset); + /// Returns an enumeration of all the terms in the index. The enumeration is ordered by + /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. + /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting + /// enumeration before calling other methods such as {@link TermEnum#term()}. + virtual TermEnumPtr terms(); - /// Returns an enumeration of all the terms in the index. The enumeration is ordered by - /// Term::compareTo(). Each term is greater than all that precede it in the enumeration. - /// Note that after calling terms(), {@link TermEnum#next()} must be called on the resulting - /// enumeration before calling other methods such as {@link TermEnum#term()}. - virtual TermEnumPtr terms(); + /// Returns an enumeration of all terms starting at a given term. If the given term does not + /// exist, the enumeration is positioned at the first term greater than the supplied term. + /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede + /// it in the enumeration. + virtual TermEnumPtr terms(const TermPtr& t); - /// Returns an enumeration of all terms starting at a given term. If the given term does not - /// exist, the enumeration is positioned at the first term greater than the supplied term. - /// The enumeration is ordered by Term::compareTo(). Each term is greater than all that precede - /// it in the enumeration. - virtual TermEnumPtr terms(const TermPtr& t); + /// Returns the number of documents containing the term t. + virtual int32_t docFreq(const TermPtr& t); - /// Returns the number of documents containing the term t. - virtual int32_t docFreq(const TermPtr& t); + /// Returns an enumeration of all the documents which contain term. For each document, the + /// document number, the frequency of the term in that document is also provided, for use in + /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. + /// The enumeration is ordered by document number. Each document number is greater than all + /// that precede it in the enumeration. + virtual TermDocsPtr termDocs(const TermPtr& term); - /// Returns an enumeration of all the documents which contain term. For each document, the - /// document number, the frequency of the term in that document is also provided, for use in - /// search scoring. If term is null, then all non-deleted docs are returned with freq=1. - /// The enumeration is ordered by document number. Each document number is greater than all - /// that precede it in the enumeration. - virtual TermDocsPtr termDocs(const TermPtr& term); + /// Returns an unpositioned {@link TermDocs} enumerator. + virtual TermDocsPtr termDocs(); - /// Returns an unpositioned {@link TermDocs} enumerator. - virtual TermDocsPtr termDocs(); + /// Returns an enumeration of all the documents which contain term. + virtual TermPositionsPtr termPositions(const TermPtr& term); - /// Returns an enumeration of all the documents which contain term. - virtual TermPositionsPtr termPositions(const TermPtr& term); + /// Returns an unpositioned {@link TermPositions} enumerator. + virtual TermPositionsPtr termPositions(); - /// Returns an unpositioned {@link TermPositions} enumerator. - virtual TermPositionsPtr termPositions(); + /// Checks recursively if all subreaders are up to date. + virtual bool isCurrent(); - /// Checks recursively if all subreaders are up to date. - virtual bool isCurrent(); + /// Checks recursively if all subindexes are optimized + virtual bool isOptimized(); - /// Checks recursively if all subindexes are optimized - virtual bool isOptimized(); + /// Not implemented. + virtual int64_t getVersion(); - /// Not implemented. - virtual int64_t getVersion(); + Collection getSubReaders(); - Collection getSubReaders(); + /// Get a list of unique field names that exist in this index and have the specified field option + /// information. + virtual HashSet getFieldNames(FieldOption fieldOption); - /// Get a list of unique field names that exist in this index and have the specified field option - /// information. - virtual HashSet getFieldNames(FieldOption fieldOption); +protected: + IndexReaderPtr doReopen(bool doClone); - protected: - IndexReaderPtr doReopen(bool doClone); + /// Implements deletion of the document numbered docNum. + virtual void doDelete(int32_t docNum); - /// Implements deletion of the document numbered docNum. - virtual void doDelete(int32_t docNum); + /// Implements actual undeleteAll(). + virtual void doUndeleteAll(); - /// Implements actual undeleteAll(). - virtual void doUndeleteAll(); + /// Implements setNorm in subclass. + virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - /// Implements setNorm in subclass. - virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + /// Implements commit. + virtual void doCommit(MapStringString commitUserData); - /// Implements commit. - virtual void doCommit(MapStringString commitUserData); + /// Implements close. + virtual void doClose(); - /// Implements close. - virtual void doClose(); + friend class ParallelTermEnum; + friend class ParallelTermDocs; + friend class ParallelTermPositions; +}; - friend class ParallelTermEnum; - friend class ParallelTermDocs; - friend class ParallelTermPositions; - }; } #endif diff --git a/include/Payload.h b/include/Payload.h index f0bfef1b..7b28c77b 100644 --- a/include/Payload.h +++ b/include/Payload.h @@ -9,80 +9,80 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A Payload is metadata that can be stored together with each occurrence of a term. This metadata is stored - /// inline in the posting list of the specific term. - /// - /// To store payloads in the index a {@link TokenStream} has to be used that produces payload data. - /// - /// Use {@link TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve - /// the payloads from the index. - class LPPAPI Payload : public LuceneObject - { - public: - /// Creates an empty payload and does not allocate a byte array. - Payload(); - - /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, - /// ie. no copy is made. - /// @param data the data of this payload - Payload(ByteArray data); - - /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, - /// ie. no copy is made. - /// @param data the data of this payload - /// @param offset the offset in the data byte array - /// @param length the length of the data - Payload(ByteArray data, int32_t offset, int32_t length); - - virtual ~Payload(); - - LUCENE_CLASS(Payload); - - protected: - /// the byte array containing the payload data - ByteArray data; - - /// the offset within the byte array - int32_t offset; - - /// the length of the payload data - int32_t _length; - - public: - /// Sets this payloads data. A reference to the passed-in array is held, ie. no copy is made. - void setData(ByteArray data); - - /// Sets this payloads data. A reference to the passed-in array is held, ie. no copy is made. - void setData(ByteArray data, int32_t offset, int32_t length); - - /// Returns a reference to the underlying byte array that holds this payloads data. - ByteArray getData(); - - /// Returns the offset in the underlying byte array - int32_t getOffset(); - - /// Returns the length of the payload data. - int32_t length(); - - /// Returns the byte at the given index. - uint8_t byteAt(int32_t index); - - /// Allocates a new byte array, copies the payload data into it and returns it. - ByteArray toByteArray(); - - /// Copies the payload data to a byte array. - /// @param target the target byte array - /// @param targetOffset the offset in the target byte array - void copyTo(ByteArray target, int32_t targetOffset); - - /// Clones this payload by creating a copy of the underlying byte array. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// A Payload is metadata that can be stored together with each occurrence of a term. This metadata is stored +/// inline in the posting list of the specific term. +/// +/// To store payloads in the index a {@link TokenStream} has to be used that produces payload data. +/// +/// Use {@link TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve +/// the payloads from the index. +class LPPAPI Payload : public LuceneObject { +public: + /// Creates an empty payload and does not allocate a byte array. + Payload(); + + /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, + /// ie. no copy is made. + /// @param data the data of this payload + Payload(ByteArray data); + + /// Creates a new payload with the the given array as data. A reference to the passed-in array is held, + /// ie. no copy is made. + /// @param data the data of this payload + /// @param offset the offset in the data byte array + /// @param length the length of the data + Payload(ByteArray data, int32_t offset, int32_t length); + + virtual ~Payload(); + + LUCENE_CLASS(Payload); + +protected: + /// the byte array containing the payload data + ByteArray data; + + /// the offset within the byte array + int32_t offset; + + /// the length of the payload data + int32_t _length; + +public: + /// Sets this payloads data. A reference to the passed-in array is held, ie. no copy is made. + void setData(ByteArray data); + + /// Sets this payloads data. A reference to the passed-in array is held, ie. no copy is made. + void setData(ByteArray data, int32_t offset, int32_t length); + + /// Returns a reference to the underlying byte array that holds this payloads data. + ByteArray getData(); + + /// Returns the offset in the underlying byte array + int32_t getOffset(); + + /// Returns the length of the payload data. + int32_t length(); + + /// Returns the byte at the given index. + uint8_t byteAt(int32_t index); + + /// Allocates a new byte array, copies the payload data into it and returns it. + ByteArray toByteArray(); + + /// Copies the payload data to a byte array. + /// @param target the target byte array + /// @param targetOffset the offset in the target byte array + void copyTo(ByteArray target, int32_t targetOffset); + + /// Clones this payload by creating a copy of the underlying byte array. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/PayloadAttribute.h b/include/PayloadAttribute.h index 5b235abe..2bbe7dc1 100644 --- a/include/PayloadAttribute.h +++ b/include/PayloadAttribute.h @@ -9,40 +9,40 @@ #include "Attribute.h" -namespace Lucene -{ - /// The start and end character offset of a Token. - class LPPAPI PayloadAttribute : public Attribute - { - public: - /// Initialize this attribute with no payload. - PayloadAttribute(); +namespace Lucene { - /// Initialize this attribute with the given payload. - PayloadAttribute(const PayloadPtr& payload); +/// The start and end character offset of a Token. +class LPPAPI PayloadAttribute : public Attribute { +public: + /// Initialize this attribute with no payload. + PayloadAttribute(); - virtual ~PayloadAttribute(); + /// Initialize this attribute with the given payload. + PayloadAttribute(const PayloadPtr& payload); - LUCENE_CLASS(PayloadAttribute); + virtual ~PayloadAttribute(); - protected: - PayloadPtr payload; + LUCENE_CLASS(PayloadAttribute); - public: - virtual String toString(); +protected: + PayloadPtr payload; - /// Returns this Token's payload. - virtual PayloadPtr getPayload(); +public: + virtual String toString(); - /// Sets this Token's payload. - virtual void setPayload(const PayloadPtr& payload); + /// Returns this Token's payload. + virtual PayloadPtr getPayload(); + + /// Sets this Token's payload. + virtual void setPayload(const PayloadPtr& payload); + + virtual void clear(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual void copyTo(const AttributePtr& target); +}; - virtual void clear(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual void copyTo(const AttributePtr& target); - }; } #endif diff --git a/include/PayloadFunction.h b/include/PayloadFunction.h index 67e16aba..5fa6a0b8 100644 --- a/include/PayloadFunction.h +++ b/include/PayloadFunction.h @@ -9,50 +9,50 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// An abstract class that defines a way for Payload*Query instances to transform the cumulative - /// effects of payload scores for a document. +namespace Lucene { + +/// An abstract class that defines a way for Payload*Query instances to transform the cumulative +/// effects of payload scores for a document. +/// +/// @see PayloadTermQuery for more information +class LPPAPI PayloadFunction : public LuceneObject { +protected: + PayloadFunction(); + +public: + virtual ~PayloadFunction(); + LUCENE_CLASS(PayloadFunction); + +public: + /// Calculate the score up to this point for this doc and field + /// @param docId The current doc + /// @param field The field + /// @param start The start position of the matching Span + /// @param end The end position of the matching Span + /// @param numPayloadsSeen The number of payloads seen so far + /// @param currentScore The current score so far + /// @param currentPayloadScore The score for the current payload + /// @return The new current Score /// - /// @see PayloadTermQuery for more information - class LPPAPI PayloadFunction : public LuceneObject - { - protected: - PayloadFunction(); - - public: - virtual ~PayloadFunction(); - LUCENE_CLASS(PayloadFunction); - - public: - /// Calculate the score up to this point for this doc and field - /// @param docId The current doc - /// @param field The field - /// @param start The start position of the matching Span - /// @param end The end position of the matching Span - /// @param numPayloadsSeen The number of payloads seen so far - /// @param currentScore The current score so far - /// @param currentPayloadScore The score for the current payload - /// @return The new current Score - /// - /// @see Spans - virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, - double currentScore, double currentPayloadScore) = 0; - - /// Calculate the final score for all the payloads seen so far for this doc/field - /// @param docId The current doc - /// @param field The current field - /// @param numPayloadsSeen The total number of payloads seen on this document - /// @param payloadScore The raw score for those payloads - /// @return The final score for the payloads - virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) = 0; - - /// Return hash code for this object. - virtual int32_t hashCode() = 0; - - /// Return whether two objects are equal - virtual bool equals(const LuceneObjectPtr& other) = 0; - }; + /// @see Spans + virtual double currentScore(int32_t docId, const String& field, int32_t start, int32_t end, int32_t numPayloadsSeen, + double currentScore, double currentPayloadScore) = 0; + + /// Calculate the final score for all the payloads seen so far for this doc/field + /// @param docId The current doc + /// @param field The current field + /// @param numPayloadsSeen The total number of payloads seen on this document + /// @param payloadScore The raw score for those payloads + /// @return The final score for the payloads + virtual double docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) = 0; + + /// Return hash code for this object. + virtual int32_t hashCode() = 0; + + /// Return whether two objects are equal + virtual bool equals(const LuceneObjectPtr& other) = 0; +}; + } #endif diff --git a/include/PayloadNearQuery.h b/include/PayloadNearQuery.h index 75123123..0b7f54ef 100644 --- a/include/PayloadNearQuery.h +++ b/include/PayloadNearQuery.h @@ -11,91 +11,89 @@ #include "SpanWeight.h" #include "SpanScorer.h" -namespace Lucene -{ - /// This class is very similar to {@link SpanNearQuery} except that it factors in the value of the payloads - /// located at each of the positions where the {@link TermSpans} occurs. - /// - /// In order to take advantage of this, you must override {@link Similarity#scorePayload} which returns 1 - /// by default. - /// - /// Payload scores are aggregated using a pluggable {@link PayloadFunction}. - /// - /// @see Similarity#scorePayload - class LPPAPI PayloadNearQuery : public SpanNearQuery - { - public: - PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder); - PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, const PayloadFunctionPtr& function); - - virtual ~PayloadNearQuery(); - - LUCENE_CLASS(PayloadNearQuery); - - protected: - String fieldName; - PayloadFunctionPtr function; - - public: - using SpanNearQuery::toString; - - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - friend class PayloadNearSpanWeight; - friend class PayloadNearSpanScorer; - }; - - class LPPAPI PayloadNearSpanWeight : public SpanWeight - { - public: - PayloadNearSpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher); - virtual ~PayloadNearSpanWeight(); - - LUCENE_CLASS(PayloadNearSpanWeight); - - public: - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - }; - - class LPPAPI PayloadNearSpanScorer : public SpanScorer - { - public: - PayloadNearSpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); - virtual ~PayloadNearSpanScorer(); - - LUCENE_CLASS(PayloadNearSpanScorer); - - public: - SpansPtr spans; - SimilarityPtr similarity; - - protected: - double payloadScore; - int32_t payloadsSeen; - - public: - /// Get the payloads associated with all underlying subspans - void getPayloads(Collection subSpans); - - virtual double score(); - - protected: - /// By default, uses the {@link PayloadFunction} to score the payloads, but can be overridden to do - /// other things. - /// @param payLoads The payloads - /// @param start The start position of the span being scored - /// @param end The end position of the span being scored - /// @see Spans - void processPayloads(Collection payLoads, int32_t start, int32_t end); - - virtual bool setFreqCurrentDoc(); - virtual ExplanationPtr explain(int32_t doc); - }; +namespace Lucene { + +/// This class is very similar to {@link SpanNearQuery} except that it factors in the value of the payloads +/// located at each of the positions where the {@link TermSpans} occurs. +/// +/// In order to take advantage of this, you must override {@link Similarity#scorePayload} which returns 1 +/// by default. +/// +/// Payload scores are aggregated using a pluggable {@link PayloadFunction}. +/// +/// @see Similarity#scorePayload +class LPPAPI PayloadNearQuery : public SpanNearQuery { +public: + PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder); + PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, const PayloadFunctionPtr& function); + + virtual ~PayloadNearQuery(); + + LUCENE_CLASS(PayloadNearQuery); + +protected: + String fieldName; + PayloadFunctionPtr function; + +public: + using SpanNearQuery::toString; + + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + friend class PayloadNearSpanWeight; + friend class PayloadNearSpanScorer; +}; + +class LPPAPI PayloadNearSpanWeight : public SpanWeight { +public: + PayloadNearSpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher); + virtual ~PayloadNearSpanWeight(); + + LUCENE_CLASS(PayloadNearSpanWeight); + +public: + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); +}; + +class LPPAPI PayloadNearSpanScorer : public SpanScorer { +public: + PayloadNearSpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); + virtual ~PayloadNearSpanScorer(); + + LUCENE_CLASS(PayloadNearSpanScorer); + +public: + SpansPtr spans; + SimilarityPtr similarity; + +protected: + double payloadScore; + int32_t payloadsSeen; + +public: + /// Get the payloads associated with all underlying subspans + void getPayloads(Collection subSpans); + + virtual double score(); + +protected: + /// By default, uses the {@link PayloadFunction} to score the payloads, but can be overridden to do + /// other things. + /// @param payLoads The payloads + /// @param start The start position of the span being scored + /// @param end The end position of the span being scored + /// @see Spans + void processPayloads(Collection payLoads, int32_t start, int32_t end); + + virtual bool setFreqCurrentDoc(); + virtual ExplanationPtr explain(int32_t doc); +}; + } #endif diff --git a/include/PayloadSpanUtil.h b/include/PayloadSpanUtil.h index b1609e74..282c6093 100644 --- a/include/PayloadSpanUtil.h +++ b/include/PayloadSpanUtil.h @@ -9,32 +9,32 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Experimental class to get set of payloads for most standard Lucene queries. Operates like Highlighter - - /// IndexReader should only contain doc of interest, best to use MemoryIndex. - class LPPAPI PayloadSpanUtil : public LuceneObject - { - public: - /// @param reader That contains doc with payloads to extract - PayloadSpanUtil(const IndexReaderPtr& reader); - - virtual ~PayloadSpanUtil(); - - LUCENE_CLASS(PayloadSpanUtil); - - protected: - IndexReaderPtr reader; - - public: - /// Query should be rewritten for wild/fuzzy support. - /// @return payloads Collection - Collection getPayloadsForQuery(const QueryPtr& query); - - protected: - void queryToSpanQuery(const QueryPtr& query, Collection payloads); - void getPayloads(Collection payloads, const SpanQueryPtr& query); - }; +namespace Lucene { + +/// Experimental class to get set of payloads for most standard Lucene queries. Operates like Highlighter - +/// IndexReader should only contain doc of interest, best to use MemoryIndex. +class LPPAPI PayloadSpanUtil : public LuceneObject { +public: + /// @param reader That contains doc with payloads to extract + PayloadSpanUtil(const IndexReaderPtr& reader); + + virtual ~PayloadSpanUtil(); + + LUCENE_CLASS(PayloadSpanUtil); + +protected: + IndexReaderPtr reader; + +public: + /// Query should be rewritten for wild/fuzzy support. + /// @return payloads Collection + Collection getPayloadsForQuery(const QueryPtr& query); + +protected: + void queryToSpanQuery(const QueryPtr& query, Collection payloads); + void getPayloads(Collection payloads, const SpanQueryPtr& query); +}; + } #endif diff --git a/include/PayloadTermQuery.h b/include/PayloadTermQuery.h index bd7b551b..3862e0d0 100644 --- a/include/PayloadTermQuery.h +++ b/include/PayloadTermQuery.h @@ -9,37 +9,37 @@ #include "SpanTermQuery.h" -namespace Lucene -{ - /// This class is very similar to {@link SpanTermQuery} except that it factors in the value of the payload - /// located at each of the positions where the {@link Term} occurs. - /// - /// In order to take advantage of this, you must override {@link Similarity#scorePayload(int32_t, const String&, - /// int32_t, int32_t, ByteArray, int32_t, int32_t)} which returns 1 by default. - /// - /// Payload scores are aggregated using a pluggable {@link PayloadFunction}. - class LPPAPI PayloadTermQuery : public SpanTermQuery - { - public: - PayloadTermQuery(const TermPtr& term, const PayloadFunctionPtr& function, bool includeSpanScore = true); - virtual ~PayloadTermQuery(); - - LUCENE_CLASS(PayloadTermQuery); - - protected: - PayloadFunctionPtr function; - bool includeSpanScore; - - public: - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - friend class PayloadTermWeight; - friend class PayloadTermSpanScorer; - }; +namespace Lucene { + +/// This class is very similar to {@link SpanTermQuery} except that it factors in the value of the payload +/// located at each of the positions where the {@link Term} occurs. +/// +/// In order to take advantage of this, you must override {@link Similarity#scorePayload(int32_t, const String&, +/// int32_t, int32_t, ByteArray, int32_t, int32_t)} which returns 1 by default. +/// +/// Payload scores are aggregated using a pluggable {@link PayloadFunction}. +class LPPAPI PayloadTermQuery : public SpanTermQuery { +public: + PayloadTermQuery(const TermPtr& term, const PayloadFunctionPtr& function, bool includeSpanScore = true); + virtual ~PayloadTermQuery(); + + LUCENE_CLASS(PayloadTermQuery); + +protected: + PayloadFunctionPtr function; + bool includeSpanScore; + +public: + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + friend class PayloadTermWeight; + friend class PayloadTermSpanScorer; +}; + } #endif diff --git a/include/PerFieldAnalyzerWrapper.h b/include/PerFieldAnalyzerWrapper.h index 07a8b31d..14a7ff4d 100644 --- a/include/PerFieldAnalyzerWrapper.h +++ b/include/PerFieldAnalyzerWrapper.h @@ -9,61 +9,61 @@ #include "Analyzer.h" -namespace Lucene -{ - /// This analyzer is used to facilitate scenarios where different fields require different analysis techniques. - /// Use {@link #addAnalyzer} to add a non-default analyzer on a field name basis. - /// - /// Example usage: - /// - ///
      -    /// PerFieldAnalyzerWrapperPtr aWrapper = newLucene(newLucene());
      -    /// aWrapper->addAnalyzer(L"firstname", newLucene());
      -    /// aWrapper->addAnalyzer(L"lastname", newLucene());
      -    /// 
      - /// - /// In this example, StandardAnalyzer will be used for all fields except "firstname" and "lastname", for which - /// KeywordAnalyzer will be used. - /// - /// A PerFieldAnalyzerWrapper can be used like any other analyzer, for both indexing and query parsing. - class LPPAPI PerFieldAnalyzerWrapper : public Analyzer - { - public: - /// Constructs with default analyzer. - /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the - /// one provided here. - PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer); +namespace Lucene { - /// Constructs with default analyzer and a map of analyzers to use for specific fields. - /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the one provided here. - /// @param fieldAnalyzers a Map (String field name to the Analyzer) to be used for those fields - PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer, MapStringAnalyzer fieldAnalyzers); +/// This analyzer is used to facilitate scenarios where different fields require different analysis techniques. +/// Use {@link #addAnalyzer} to add a non-default analyzer on a field name basis. +/// +/// Example usage: +/// +///
      +/// PerFieldAnalyzerWrapperPtr aWrapper = newLucene(newLucene());
      +/// aWrapper->addAnalyzer(L"firstname", newLucene());
      +/// aWrapper->addAnalyzer(L"lastname", newLucene());
      +/// 
      +/// +/// In this example, StandardAnalyzer will be used for all fields except "firstname" and "lastname", for which +/// KeywordAnalyzer will be used. +/// +/// A PerFieldAnalyzerWrapper can be used like any other analyzer, for both indexing and query parsing. +class LPPAPI PerFieldAnalyzerWrapper : public Analyzer { +public: + /// Constructs with default analyzer. + /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the + /// one provided here. + PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer); - virtual ~PerFieldAnalyzerWrapper(); + /// Constructs with default analyzer and a map of analyzers to use for specific fields. + /// @param defaultAnalyzer Any fields not specifically defined to use a different analyzer will use the one provided here. + /// @param fieldAnalyzers a Map (String field name to the Analyzer) to be used for those fields + PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer, MapStringAnalyzer fieldAnalyzers); - LUCENE_CLASS(PerFieldAnalyzerWrapper); + virtual ~PerFieldAnalyzerWrapper(); - protected: - AnalyzerPtr defaultAnalyzer; - MapStringAnalyzer analyzerMap; + LUCENE_CLASS(PerFieldAnalyzerWrapper); - public: - /// Defines an analyzer to use for the specified field. - /// @param fieldName field name requiring a non-default analyzer - /// @param analyzer non-default analyzer to use for field - void addAnalyzer(const String& fieldName, const AnalyzerPtr& analyzer); +protected: + AnalyzerPtr defaultAnalyzer; + MapStringAnalyzer analyzerMap; - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +public: + /// Defines an analyzer to use for the specified field. + /// @param fieldName field name requiring a non-default analyzer + /// @param analyzer non-default analyzer to use for field + void addAnalyzer(const String& fieldName, const AnalyzerPtr& analyzer); - /// Return the positionIncrementGap from the analyzer assigned to fieldName. - virtual int32_t getPositionIncrementGap(const String& fieldName); + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - /// Return the offsetGap from the analyzer assigned to field - virtual int32_t getOffsetGap(const FieldablePtr& field); + /// Return the positionIncrementGap from the analyzer assigned to fieldName. + virtual int32_t getPositionIncrementGap(const String& fieldName); + + /// Return the offsetGap from the analyzer assigned to field + virtual int32_t getOffsetGap(const FieldablePtr& field); + + virtual String toString(); +}; - virtual String toString(); - }; } #endif diff --git a/include/PhrasePositions.h b/include/PhrasePositions.h index e1c917be..0ef67d82 100644 --- a/include/PhrasePositions.h +++ b/include/PhrasePositions.h @@ -9,32 +9,32 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Position of a term in a document that takes into account the term offset within the phrase. - class PhrasePositions : public LuceneObject - { - public: - PhrasePositions(const TermPositionsPtr& t, int32_t o); - virtual ~PhrasePositions(); - - LUCENE_CLASS(PhrasePositions); - - public: - int32_t doc; // current doc - int32_t position; // position in doc - int32_t count; // remaining pos in this doc - int32_t offset; // position in phrase - TermPositionsPtr tp; // stream of positions - PhrasePositionsPtr _next; // used to make lists - bool repeats; // there's other pp for same term (eg. query="1st word 2nd word"~1) - - public: - bool next(); - bool skipTo(int32_t target); - void firstPosition(); - bool nextPosition(); - }; +namespace Lucene { + +/// Position of a term in a document that takes into account the term offset within the phrase. +class PhrasePositions : public LuceneObject { +public: + PhrasePositions(const TermPositionsPtr& t, int32_t o); + virtual ~PhrasePositions(); + + LUCENE_CLASS(PhrasePositions); + +public: + int32_t doc; // current doc + int32_t position; // position in doc + int32_t count; // remaining pos in this doc + int32_t offset; // position in phrase + TermPositionsPtr tp; // stream of positions + PhrasePositionsPtr _next; // used to make lists + bool repeats; // there's other pp for same term (eg. query="1st word 2nd word"~1) + +public: + bool next(); + bool skipTo(int32_t target); + void firstPosition(); + bool nextPosition(); +}; + } #endif diff --git a/include/PhraseQuery.h b/include/PhraseQuery.h index e10f875e..da94df68 100644 --- a/include/PhraseQuery.h +++ b/include/PhraseQuery.h @@ -9,74 +9,74 @@ #include "Query.h" -namespace Lucene -{ - /// A Query that matches documents containing a particular sequence of terms. A PhraseQuery is built by - /// QueryParser for input like "new york". +namespace Lucene { + +/// A Query that matches documents containing a particular sequence of terms. A PhraseQuery is built by +/// QueryParser for input like "new york". +/// +/// This query may be combined with other terms or queries with a {@link BooleanQuery}. +class LPPAPI PhraseQuery : public Query { +public: + /// Constructs an empty phrase query. + PhraseQuery(); + virtual ~PhraseQuery(); + + LUCENE_CLASS(PhraseQuery); + +protected: + String field; + Collection terms; + Collection positions; + int32_t maxPosition; + int32_t slop; + +public: + using Query::toString; + + /// Sets the number of other words permitted between words in query phrase. If zero, then this is an + /// exact phrase search. For larger values this works like a WITHIN or NEAR operator. /// - /// This query may be combined with other terms or queries with a {@link BooleanQuery}. - class LPPAPI PhraseQuery : public Query - { - public: - /// Constructs an empty phrase query. - PhraseQuery(); - virtual ~PhraseQuery(); - - LUCENE_CLASS(PhraseQuery); - - protected: - String field; - Collection terms; - Collection positions; - int32_t maxPosition; - int32_t slop; - - public: - using Query::toString; - - /// Sets the number of other words permitted between words in query phrase. If zero, then this is an - /// exact phrase search. For larger values this works like a WITHIN or NEAR operator. - /// - /// The slop is in fact an edit-distance, where the units correspond to moves of terms in the query phrase - /// out of position. For example, to switch the order of two words requires two moves (the first move - /// places the words atop one another), so to permit re-orderings of phrases, the slop must be at least two. - /// - /// More exact matches are scored higher than sloppier matches, thus search results are sorted by exactness. - /// - /// The slop is zero by default, requiring exact matches. - void setSlop(int32_t slop); - - /// Returns the slop. - /// @see #setSlop() - int32_t getSlop(); - - /// Adds a term to the end of the query phrase. - /// The relative position of the term is the one immediately after the last term added. - void add(const TermPtr& term); - - /// Adds a term to the end of the query phrase. - /// The relative position of the term within the phrase is specified explicitly. This allows eg. phrases - /// with more than one term at the same position or phrases with gaps (eg. in connection with stopwords). - void add(const TermPtr& term, int32_t position); - - /// Returns the set of terms in this phrase. - Collection getTerms(); - - /// Returns the relative positions of terms in this phrase. - Collection getPositions(); - - virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual void extractTerms(SetTerm terms); - - /// Prints a user-readable version of this query. - virtual String toString(const String& field); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - friend class PhraseWeight; - }; + /// The slop is in fact an edit-distance, where the units correspond to moves of terms in the query phrase + /// out of position. For example, to switch the order of two words requires two moves (the first move + /// places the words atop one another), so to permit re-orderings of phrases, the slop must be at least two. + /// + /// More exact matches are scored higher than sloppier matches, thus search results are sorted by exactness. + /// + /// The slop is zero by default, requiring exact matches. + void setSlop(int32_t slop); + + /// Returns the slop. + /// @see #setSlop() + int32_t getSlop(); + + /// Adds a term to the end of the query phrase. + /// The relative position of the term is the one immediately after the last term added. + void add(const TermPtr& term); + + /// Adds a term to the end of the query phrase. + /// The relative position of the term within the phrase is specified explicitly. This allows eg. phrases + /// with more than one term at the same position or phrases with gaps (eg. in connection with stopwords). + void add(const TermPtr& term, int32_t position); + + /// Returns the set of terms in this phrase. + Collection getTerms(); + + /// Returns the relative positions of terms in this phrase. + Collection getPositions(); + + virtual WeightPtr createWeight(const SearcherPtr& searcher); + virtual void extractTerms(SetTerm terms); + + /// Prints a user-readable version of this query. + virtual String toString(const String& field); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + friend class PhraseWeight; +}; + } #endif diff --git a/include/PhraseQueue.h b/include/PhraseQueue.h index 89436c28..ef8b4074 100644 --- a/include/PhraseQueue.h +++ b/include/PhraseQueue.h @@ -9,19 +9,19 @@ #include "PriorityQueue.h" -namespace Lucene -{ - class PhraseQueue : public PriorityQueue - { - public: - PhraseQueue(int32_t size); - virtual ~PhraseQueue(); - - LUCENE_CLASS(PhraseQueue); - - protected: - virtual bool lessThan(const PhrasePositionsPtr& first, const PhrasePositionsPtr& second); - }; +namespace Lucene { + +class PhraseQueue : public PriorityQueue { +public: + PhraseQueue(int32_t size); + virtual ~PhraseQueue(); + + LUCENE_CLASS(PhraseQueue); + +protected: + virtual bool lessThan(const PhrasePositionsPtr& first, const PhrasePositionsPtr& second); +}; + } #endif diff --git a/include/PhraseScorer.h b/include/PhraseScorer.h index be5442f1..2b5c64f4 100644 --- a/include/PhraseScorer.h +++ b/include/PhraseScorer.h @@ -9,63 +9,63 @@ #include "Scorer.h" -namespace Lucene -{ - /// Scoring functionality for phrase queries. A document is considered matching if it contains the - /// phrase-query terms at "valid" positions. What "valid positions" are depends on the type of the - /// phrase query: for an exact phrase query terms are required to appear in adjacent locations, while - /// for a sloppy phrase query some distance between the terms is allowed. The abstract method {@link - /// #phraseFreq()} of extending classes is invoked for each document containing all the phrase query - /// terms, in order to compute the frequency of the phrase query in that document. A non zero frequency - /// means a match. - class PhraseScorer : public Scorer - { - public: - PhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms); - virtual ~PhraseScorer(); - - LUCENE_CLASS(PhraseScorer); - - protected: - WeightPtr weight; - ByteArray norms; - double value; - - bool firstTime; - bool more; - PhraseQueuePtr pq; - PhrasePositionsPtr first; - PhrasePositionsPtr last; - - double freq; // phrase frequency in current doc as computed by phraseFreq(). - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual double score(); - virtual int32_t advance(int32_t target); - - /// Phrase frequency in current doc as computed by phraseFreq(). - double currentFreq(); - - virtual String toString(); - - protected: - /// Next without initial increment - bool doNext(); - - /// For a document containing all the phrase query terms, compute the frequency of the phrase in - /// that document. A non zero frequency means a match. - /// Note, that containing all phrase terms does not guarantee a match - they have to be found in - /// matching locations. - /// @return frequency of the phrase in current doc, 0 if not found. - virtual double phraseFreq() = 0; - - void init(); - void sort(); - void pqToList(); - void firstToLast(); - }; +namespace Lucene { + +/// Scoring functionality for phrase queries. A document is considered matching if it contains the +/// phrase-query terms at "valid" positions. What "valid positions" are depends on the type of the +/// phrase query: for an exact phrase query terms are required to appear in adjacent locations, while +/// for a sloppy phrase query some distance between the terms is allowed. The abstract method {@link +/// #phraseFreq()} of extending classes is invoked for each document containing all the phrase query +/// terms, in order to compute the frequency of the phrase query in that document. A non zero frequency +/// means a match. +class PhraseScorer : public Scorer { +public: + PhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms); + virtual ~PhraseScorer(); + + LUCENE_CLASS(PhraseScorer); + +protected: + WeightPtr weight; + ByteArray norms; + double value; + + bool firstTime; + bool more; + PhraseQueuePtr pq; + PhrasePositionsPtr first; + PhrasePositionsPtr last; + + double freq; // phrase frequency in current doc as computed by phraseFreq(). + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual double score(); + virtual int32_t advance(int32_t target); + + /// Phrase frequency in current doc as computed by phraseFreq(). + double currentFreq(); + + virtual String toString(); + +protected: + /// Next without initial increment + bool doNext(); + + /// For a document containing all the phrase query terms, compute the frequency of the phrase in + /// that document. A non zero frequency means a match. + /// Note, that containing all phrase terms does not guarantee a match - they have to be found in + /// matching locations. + /// @return frequency of the phrase in current doc, 0 if not found. + virtual double phraseFreq() = 0; + + void init(); + void sort(); + void pqToList(); + void firstToLast(); +}; + } #endif diff --git a/include/PorterStemFilter.h b/include/PorterStemFilter.h index 84f151be..ec457aea 100644 --- a/include/PorterStemFilter.h +++ b/include/PorterStemFilter.h @@ -9,40 +9,40 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// Transforms the token stream as per the Porter stemming algorithm. Note: the input to the stemming filter must - /// already be in lower case, so you will need to use LowerCaseFilter or LowerCaseTokenizer further down the Tokenizer - /// chain in order for this to work properly. - /// - /// To use this filter with other analyzers, you'll want to write an Analyzer class that sets up the TokenStream chain - /// as you want it. To use this with LowerCaseTokenizer, for example, you'd write an analyzer like this: - /// - ///
      -    /// class MyAnalyzer : public Analyzer
      -    /// {
      -    /// public:
      -    ///     virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader)
      -    ///     {
      -    ///         return newLucene(newLucene(reader));
      -    ///     }
      -    /// };
      -    /// 
      - class LPPAPI PorterStemFilter : public TokenFilter - { - public: - PorterStemFilter(const TokenStreamPtr& input); - virtual ~PorterStemFilter(); - - LUCENE_CLASS(PorterStemFilter); - - protected: - PorterStemmerPtr stemmer; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - }; +namespace Lucene { + +/// Transforms the token stream as per the Porter stemming algorithm. Note: the input to the stemming filter must +/// already be in lower case, so you will need to use LowerCaseFilter or LowerCaseTokenizer further down the Tokenizer +/// chain in order for this to work properly. +/// +/// To use this filter with other analyzers, you'll want to write an Analyzer class that sets up the TokenStream chain +/// as you want it. To use this with LowerCaseTokenizer, for example, you'd write an analyzer like this: +/// +///
      +/// class MyAnalyzer : public Analyzer
      +/// {
      +/// public:
      +///     virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader)
      +///     {
      +///         return newLucene(newLucene(reader));
      +///     }
      +/// };
      +/// 
      +class LPPAPI PorterStemFilter : public TokenFilter { +public: + PorterStemFilter(const TokenStreamPtr& input); + virtual ~PorterStemFilter(); + + LUCENE_CLASS(PorterStemFilter); + +protected: + PorterStemmerPtr stemmer; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; + } #endif diff --git a/include/PorterStemmer.h b/include/PorterStemmer.h index 95e85248..61461452 100644 --- a/include/PorterStemmer.h +++ b/include/PorterStemmer.h @@ -9,118 +9,118 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This is the Porter stemming algorithm, coded up as thread-safe ANSI C by the author. +namespace Lucene { + +/// This is the Porter stemming algorithm, coded up as thread-safe ANSI C by the author. +/// +/// It may be be regarded as canonical, in that it follows the algorithm presented in Porter, 1980, An algorithm +/// for suffix stripping, Program, Vol. 14, no. 3, pp 130-137, only differing from it at the points marked DEPARTURE. +/// +/// See also http://www.tartarus.org/~martin/PorterStemmer +/// +/// The algorithm as described in the paper could be exactly replicated by adjusting the points of DEPARTURE, but +/// this is barely necessary, because (a) the points of DEPARTURE are definitely improvements, and (b) no encoding +/// of the Porter stemmer I have seen is anything like as exact as this version, even with the points of DEPARTURE! +/// +/// Release 2 (the more old-fashioned, non-thread-safe version may be regarded as release 1.) +class PorterStemmer : public LuceneObject { +public: + PorterStemmer(); + virtual ~PorterStemmer(); + + LUCENE_CLASS(PorterStemmer); + +protected: + wchar_t* b; // buffer for word to be stemmed + int32_t k; // offset to the end of the string + int32_t j; // a general offset into the string + int32_t i; // initial length of word + bool dirty; + +public: + bool stem(CharArray word); + + /// In stem(b, k), b is a char pointer, and the string to be stemmed is from b[0] to b[k] inclusive. + /// Possibly b[k+1] == '\0', but it is not important. The stemmer adjusts the characters b[0] ... b[k] and + /// stores the new end-point of the string, k'. Stemming never increases word length, so 0 <= k' <= k. + bool stem(wchar_t* b, int32_t k); + + wchar_t* getResultBuffer(); + int32_t getResultLength(); + +protected: + /// Returns true if b[i] is a consonant. ('b' means 'z->b', but here and below we drop 'z->' in comments. + bool cons(int32_t i); + + /// Measures the number of consonant sequences between 0 and j. If c is a consonant sequence and v a vowel + /// sequence, and <..> indicates arbitrary presence, /// - /// It may be be regarded as canonical, in that it follows the algorithm presented in Porter, 1980, An algorithm - /// for suffix stripping, Program, Vol. 14, no. 3, pp 130-137, only differing from it at the points marked DEPARTURE. + /// gives 0 + /// vc gives 1 + /// vcvc gives 2 + /// vcvcvc gives 3 + /// ... + int32_t m(); + + /// Return true if 0,...j contains a vowel + bool vowelinstem(); + + /// Return true if j,(j-1) contain a double consonant. + bool doublec(int32_t j); + + /// Return true if i-2,i-1,i has the form consonant - vowel - consonant and also if the second c is not w,x or y. + /// This is used when trying to restore an e at the end of a short word. + /// + /// eg. cav(e), lov(e), hop(e), crim(e), but + /// snow, box, tray. + bool cvc(int32_t i); + + /// Returns true if 0,...k ends with the string s. + bool ends(const wchar_t* s); + + /// Sets (j+1),...k to the characters in the string s, readjusting k. + void setto(const wchar_t* s); + + void r(const wchar_t* s); + + /// step1ab() gets rid of plurals and -ed or -ing. eg. /// - /// See also http://www.tartarus.org/~martin/PorterStemmer + /// caresses -> caress + /// ponies -> poni + /// ties -> ti + /// caress -> caress + /// cats -> cat /// - /// The algorithm as described in the paper could be exactly replicated by adjusting the points of DEPARTURE, but - /// this is barely necessary, because (a) the points of DEPARTURE are definitely improvements, and (b) no encoding - /// of the Porter stemmer I have seen is anything like as exact as this version, even with the points of DEPARTURE! + /// feed -> feed + /// agreed -> agree + /// disabled -> disable /// - /// Release 2 (the more old-fashioned, non-thread-safe version may be regarded as release 1.) - class PorterStemmer : public LuceneObject - { - public: - PorterStemmer(); - virtual ~PorterStemmer(); - - LUCENE_CLASS(PorterStemmer); - - protected: - wchar_t* b; // buffer for word to be stemmed - int32_t k; // offset to the end of the string - int32_t j; // a general offset into the string - int32_t i; // initial length of word - bool dirty; - - public: - bool stem(CharArray word); - - /// In stem(b, k), b is a char pointer, and the string to be stemmed is from b[0] to b[k] inclusive. - /// Possibly b[k+1] == '\0', but it is not important. The stemmer adjusts the characters b[0] ... b[k] and - /// stores the new end-point of the string, k'. Stemming never increases word length, so 0 <= k' <= k. - bool stem(wchar_t* b, int32_t k); - - wchar_t* getResultBuffer(); - int32_t getResultLength(); - - protected: - /// Returns true if b[i] is a consonant. ('b' means 'z->b', but here and below we drop 'z->' in comments. - bool cons(int32_t i); - - /// Measures the number of consonant sequences between 0 and j. If c is a consonant sequence and v a vowel - /// sequence, and <..> indicates arbitrary presence, - /// - /// gives 0 - /// vc gives 1 - /// vcvc gives 2 - /// vcvcvc gives 3 - /// ... - int32_t m(); - - /// Return true if 0,...j contains a vowel - bool vowelinstem(); - - /// Return true if j,(j-1) contain a double consonant. - bool doublec(int32_t j); - - /// Return true if i-2,i-1,i has the form consonant - vowel - consonant and also if the second c is not w,x or y. - /// This is used when trying to restore an e at the end of a short word. - /// - /// eg. cav(e), lov(e), hop(e), crim(e), but - /// snow, box, tray. - bool cvc(int32_t i); - - /// Returns true if 0,...k ends with the string s. - bool ends(const wchar_t* s); - - /// Sets (j+1),...k to the characters in the string s, readjusting k. - void setto(const wchar_t* s); - - void r(const wchar_t* s); - - /// step1ab() gets rid of plurals and -ed or -ing. eg. - /// - /// caresses -> caress - /// ponies -> poni - /// ties -> ti - /// caress -> caress - /// cats -> cat - /// - /// feed -> feed - /// agreed -> agree - /// disabled -> disable - /// - /// matting -> mat - /// mating -> mate - /// meeting -> meet - /// milling -> mill - /// messing -> mess - /// - /// meetings -> meet - void step1ab(); - - /// Turns terminal y to i when there is another vowel in the stem. - void step1c(); - - /// Maps double suffices to single ones. so -ization ( = -ize plus -ation) maps to -ize etc. note that the - /// string before the suffix must give m() > 0. - void step2(); - - /// Deals with -ic-, -full, -ness etc. similar strategy to step2. - void step3(); - - /// Takes off -ant, -ence etc., in context vcvc. - void step4(); - - /// Removes a final -e if m() > 1, and changes -ll to -l if m() > 1. - void step5(); - }; + /// matting -> mat + /// mating -> mate + /// meeting -> meet + /// milling -> mill + /// messing -> mess + /// + /// meetings -> meet + void step1ab(); + + /// Turns terminal y to i when there is another vowel in the stem. + void step1c(); + + /// Maps double suffices to single ones. so -ization ( = -ize plus -ation) maps to -ize etc. note that the + /// string before the suffix must give m() > 0. + void step2(); + + /// Deals with -ic-, -full, -ness etc. similar strategy to step2. + void step3(); + + /// Takes off -ant, -ence etc., in context vcvc. + void step4(); + + /// Removes a final -e if m() > 1, and changes -ll to -l if m() > 1. + void step5(); +}; + } #endif diff --git a/include/PositionBasedTermVectorMapper.h b/include/PositionBasedTermVectorMapper.h index 06cb2d29..5576af7b 100644 --- a/include/PositionBasedTermVectorMapper.h +++ b/include/PositionBasedTermVectorMapper.h @@ -9,72 +9,71 @@ #include "TermVectorMapper.h" -namespace Lucene -{ - class LPPAPI PositionBasedTermVectorMapper : public TermVectorMapper - { - public: - PositionBasedTermVectorMapper(bool ignoringOffsets = false); - virtual ~PositionBasedTermVectorMapper(); +namespace Lucene { - LUCENE_CLASS(PositionBasedTermVectorMapper); +class LPPAPI PositionBasedTermVectorMapper : public TermVectorMapper { +public: + PositionBasedTermVectorMapper(bool ignoringOffsets = false); + virtual ~PositionBasedTermVectorMapper(); - protected: - MapStringMapIntTermVectorsPositionInfo fieldToTerms; + LUCENE_CLASS(PositionBasedTermVectorMapper); - String currentField; +protected: + MapStringMapIntTermVectorsPositionInfo fieldToTerms; - /// A Map of Integer and TermVectorsPositionInfo - MapIntTermVectorsPositionInfo currentPositions; + String currentField; - bool storeOffsets; + /// A Map of Integer and TermVectorsPositionInfo + MapIntTermVectorsPositionInfo currentPositions; - public: - /// Never ignores positions. This mapper doesn't make much sense unless there are positions. - /// @return false - virtual bool isIgnoringPositions(); + bool storeOffsets; - /// Callback for the TermVectorReader. - virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); +public: + /// Never ignores positions. This mapper doesn't make much sense unless there are positions. + /// @return false + virtual bool isIgnoringPositions(); - /// Callback mechanism used by the TermVectorReader. - virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); + /// Callback for the TermVectorReader. + virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); - /// Get the mapping between fields and terms, sorted by the comparator - /// @return A map between field names and a Map. The sub-Map key is the position as the integer, the value is - /// {@link PositionBasedTermVectorMapper}. - MapStringMapIntTermVectorsPositionInfo getFieldToTerms(); - }; + /// Callback mechanism used by the TermVectorReader. + virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); - /// Container for a term at a position - class LPPAPI TermVectorsPositionInfo : public LuceneObject - { - public: - TermVectorsPositionInfo(int32_t position, bool storeOffsets); - virtual ~TermVectorsPositionInfo(); + /// Get the mapping between fields and terms, sorted by the comparator + /// @return A map between field names and a Map. The sub-Map key is the position as the integer, the value is + /// {@link PositionBasedTermVectorMapper}. + MapStringMapIntTermVectorsPositionInfo getFieldToTerms(); +}; - LUCENE_CLASS(TermVectorsPositionInfo); +/// Container for a term at a position +class LPPAPI TermVectorsPositionInfo : public LuceneObject { +public: + TermVectorsPositionInfo(int32_t position, bool storeOffsets); + virtual ~TermVectorsPositionInfo(); - protected: - int32_t position; - Collection terms; - Collection offsets; + LUCENE_CLASS(TermVectorsPositionInfo); - public: - void addTerm(const String& term, const TermVectorOffsetInfoPtr& info); +protected: + int32_t position; + Collection terms; + Collection offsets; - /// @return The position of the term - int32_t getPosition(); +public: + void addTerm(const String& term, const TermVectorOffsetInfoPtr& info); - /// Note, there may be multiple terms at the same position - /// @return A List of Strings - Collection getTerms(); + /// @return The position of the term + int32_t getPosition(); + + /// Note, there may be multiple terms at the same position + /// @return A List of Strings + Collection getTerms(); + + /// Parallel list (to {@link #getTerms()}) of TermVectorOffsetInfo objects. There may be multiple + /// entries since there may be multiple terms at a position. + /// @return A List of TermVectorOffsetInfo objects, if offsets are stored. + Collection getOffsets(); +}; - /// Parallel list (to {@link #getTerms()}) of TermVectorOffsetInfo objects. There may be multiple - /// entries since there may be multiple terms at a position. - /// @return A List of TermVectorOffsetInfo objects, if offsets are stored. - Collection getOffsets(); - }; } #endif diff --git a/include/PositionIncrementAttribute.h b/include/PositionIncrementAttribute.h index 8d4fa5d8..13194116 100644 --- a/include/PositionIncrementAttribute.h +++ b/include/PositionIncrementAttribute.h @@ -9,54 +9,54 @@ #include "Attribute.h" -namespace Lucene -{ - /// The positionIncrement determines the position of this token relative to the previous Token in a - /// TokenStream, used in phrase searching. - /// - /// The default value is one. - /// - /// Some common uses for this are: - /// - /// Set it to zero to put multiple terms in the same position. This is useful if, eg., a word has multiple - /// stems. Searches for phrases including either stem will match. In this case, all but the first stem's - /// increment should be set to zero: the increment of the first instance should be one. Repeating a token - /// with an increment of zero can also be used to boost the scores of matches on that token. - /// - /// Set it to values greater than one to inhibit exact phrase matches. If, for example, one does not want - /// phrases to match across removed stop words, then one could build a stop word filter that removes stop - /// words and also sets the increment to the number of stop words removed before each non-stop word. Then - /// exact phrase queries will only match when the terms occur with no intervening stop words. - /// - /// @see TermPositions - class LPPAPI PositionIncrementAttribute : public Attribute - { - public: - PositionIncrementAttribute(); - virtual ~PositionIncrementAttribute(); - - LUCENE_CLASS(PositionIncrementAttribute); - - protected: - int32_t positionIncrement; - - public: - virtual String toString(); - - /// Set the position increment. The default value is one. - /// @param positionIncrement the distance from the prior term - virtual void setPositionIncrement(int32_t positionIncrement); - - /// Returns the position increment of this Token. - /// @see #setPositionIncrement - virtual int32_t getPositionIncrement(); - - virtual void clear(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual void copyTo(const AttributePtr& target); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// The positionIncrement determines the position of this token relative to the previous Token in a +/// TokenStream, used in phrase searching. +/// +/// The default value is one. +/// +/// Some common uses for this are: +/// +/// Set it to zero to put multiple terms in the same position. This is useful if, eg., a word has multiple +/// stems. Searches for phrases including either stem will match. In this case, all but the first stem's +/// increment should be set to zero: the increment of the first instance should be one. Repeating a token +/// with an increment of zero can also be used to boost the scores of matches on that token. +/// +/// Set it to values greater than one to inhibit exact phrase matches. If, for example, one does not want +/// phrases to match across removed stop words, then one could build a stop word filter that removes stop +/// words and also sets the increment to the number of stop words removed before each non-stop word. Then +/// exact phrase queries will only match when the terms occur with no intervening stop words. +/// +/// @see TermPositions +class LPPAPI PositionIncrementAttribute : public Attribute { +public: + PositionIncrementAttribute(); + virtual ~PositionIncrementAttribute(); + + LUCENE_CLASS(PositionIncrementAttribute); + +protected: + int32_t positionIncrement; + +public: + virtual String toString(); + + /// Set the position increment. The default value is one. + /// @param positionIncrement the distance from the prior term + virtual void setPositionIncrement(int32_t positionIncrement); + + /// Returns the position increment of this Token. + /// @see #setPositionIncrement + virtual int32_t getPositionIncrement(); + + virtual void clear(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/include/PositiveScoresOnlyCollector.h b/include/PositiveScoresOnlyCollector.h index 0f493e67..2c368919 100644 --- a/include/PositiveScoresOnlyCollector.h +++ b/include/PositiveScoresOnlyCollector.h @@ -9,28 +9,28 @@ #include "Collector.h" -namespace Lucene -{ - /// A {@link Collector} implementation which wraps another {@link Collector} and makes sure only - /// documents with scores > 0 are collected. - class LPPAPI PositiveScoresOnlyCollector : public Collector - { - public: - PositiveScoresOnlyCollector(const CollectorPtr& c); - virtual ~PositiveScoresOnlyCollector(); - - LUCENE_CLASS(PositiveScoresOnlyCollector); - - protected: - CollectorPtr collector; - ScorerPtr scorer; - - public: - virtual void collect(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setScorer(const ScorerPtr& scorer); - virtual bool acceptsDocsOutOfOrder(); - }; +namespace Lucene { + +/// A {@link Collector} implementation which wraps another {@link Collector} and makes sure only +/// documents with scores > 0 are collected. +class LPPAPI PositiveScoresOnlyCollector : public Collector { +public: + PositiveScoresOnlyCollector(const CollectorPtr& c); + virtual ~PositiveScoresOnlyCollector(); + + LUCENE_CLASS(PositiveScoresOnlyCollector); + +protected: + CollectorPtr collector; + ScorerPtr scorer; + +public: + virtual void collect(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); + virtual bool acceptsDocsOutOfOrder(); +}; + } #endif diff --git a/include/PrefixFilter.h b/include/PrefixFilter.h index 8ab5e4a8..b4a4318d 100644 --- a/include/PrefixFilter.h +++ b/include/PrefixFilter.h @@ -9,22 +9,22 @@ #include "MultiTermQueryWrapperFilter.h" -namespace Lucene -{ - /// A Filter that restricts search results to values that have a matching prefix in a given field. - class LPPAPI PrefixFilter : public MultiTermQueryWrapperFilter - { - public: - PrefixFilter(const TermPtr& prefix); - virtual ~PrefixFilter(); - - LUCENE_CLASS(PrefixFilter); - - public: - TermPtr getPrefix(); - - virtual String toString(); - }; +namespace Lucene { + +/// A Filter that restricts search results to values that have a matching prefix in a given field. +class LPPAPI PrefixFilter : public MultiTermQueryWrapperFilter { +public: + PrefixFilter(const TermPtr& prefix); + virtual ~PrefixFilter(); + + LUCENE_CLASS(PrefixFilter); + +public: + TermPtr getPrefix(); + + virtual String toString(); +}; + } #endif diff --git a/include/PrefixQuery.h b/include/PrefixQuery.h index 0dc65128..0c45bdf9 100644 --- a/include/PrefixQuery.h +++ b/include/PrefixQuery.h @@ -9,41 +9,41 @@ #include "MultiTermQuery.h" -namespace Lucene -{ - /// A Query that matches documents containing terms with a specified prefix. A PrefixQuery is built by - /// QueryParser for input like app*. - /// - /// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. - class LPPAPI PrefixQuery : public MultiTermQuery - { - public: - /// Constructs a query for terms starting with prefix. - PrefixQuery(const TermPtr& prefix); +namespace Lucene { - virtual ~PrefixQuery(); +/// A Query that matches documents containing terms with a specified prefix. A PrefixQuery is built by +/// QueryParser for input like app*. +/// +/// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. +class LPPAPI PrefixQuery : public MultiTermQuery { +public: + /// Constructs a query for terms starting with prefix. + PrefixQuery(const TermPtr& prefix); - LUCENE_CLASS(PrefixQuery); + virtual ~PrefixQuery(); - protected: - TermPtr prefix; + LUCENE_CLASS(PrefixQuery); - public: - using MultiTermQuery::toString; +protected: + TermPtr prefix; - /// Returns the prefix of this query. - TermPtr getPrefix(); +public: + using MultiTermQuery::toString; - /// Prints a user-readable version of this query. - virtual String toString(const String& field); + /// Returns the prefix of this query. + TermPtr getPrefix(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); + /// Prints a user-readable version of this query. + virtual String toString(const String& field); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + +protected: + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); +}; - protected: - virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); - }; } #endif diff --git a/include/PrefixTermEnum.h b/include/PrefixTermEnum.h index 9f4b09cf..93f658bb 100644 --- a/include/PrefixTermEnum.h +++ b/include/PrefixTermEnum.h @@ -9,33 +9,33 @@ #include "FilteredTermEnum.h" -namespace Lucene -{ - /// Subclass of FilteredTermEnum for enumerating all terms that match the specified prefix filter term. - /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than - /// all that precede it. - class LPPAPI PrefixTermEnum : public FilteredTermEnum - { - public: - PrefixTermEnum(const IndexReaderPtr& reader, const TermPtr& prefix); - virtual ~PrefixTermEnum(); - - LUCENE_CLASS(PrefixTermEnum); - - protected: - TermPtr prefix; - bool _endEnum; - - public: - virtual double difference(); - - protected: - virtual bool endEnum(); - virtual bool termCompare(const TermPtr& term); - - TermPtr getPrefixTerm(); - }; +namespace Lucene { + +/// Subclass of FilteredTermEnum for enumerating all terms that match the specified prefix filter term. +/// +/// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than +/// all that precede it. +class LPPAPI PrefixTermEnum : public FilteredTermEnum { +public: + PrefixTermEnum(const IndexReaderPtr& reader, const TermPtr& prefix); + virtual ~PrefixTermEnum(); + + LUCENE_CLASS(PrefixTermEnum); + +protected: + TermPtr prefix; + bool _endEnum; + +public: + virtual double difference(); + +protected: + virtual bool endEnum(); + virtual bool termCompare(const TermPtr& term); + + TermPtr getPrefixTerm(); +}; + } #endif diff --git a/include/PriorityQueue.h b/include/PriorityQueue.h index 2675412f..ec7e71bb 100644 --- a/include/PriorityQueue.h +++ b/include/PriorityQueue.h @@ -10,216 +10,192 @@ #include "LuceneObject.h" #include "MiscUtils.h" -namespace Lucene -{ - /// A PriorityQueue maintains a partial ordering of its elements such that the least element can always - /// be found in constant time. Put()'s and pop()'s require log(size) time. - /// - /// NOTE: This class pre-allocates a full array of length maxSize + 1. - template - class PriorityQueue : public LuceneObject - { - public: - typedef typename std::vector heap_type; - - PriorityQueue(int32_t maxSize) - { - this->_size = 0; - this->_maxSize = maxSize; - } - - virtual ~PriorityQueue() - { - } - - protected: - heap_type heap; - int32_t _size; - int32_t _maxSize; - - public: - virtual void initialize() - { - bool empty = heap.empty(); - - if (empty) - { - int32_t heapSize = 0; - if (_maxSize == 0) - { - // We allocate 1 extra to avoid if statement in top() - heapSize = 2; - } - else if (_maxSize == INT_MAX) - { - // Don't wrap heapSize to -1, in this case, which causes a confusing NegativeArraySizeException. - // Note that very likely this will simply then hit an OOME, but at least that's more indicative - // to caller that this values is too big. We don't +1 in this case, but it's very unlikely in - // practice one will actually insert this many objects into the PQ - heapSize = INT_MAX; - } - else - { - // NOTE: we add +1 because all access to heap is 1-based not 0-based. heap[0] is unused. - heapSize = _maxSize + 1; - } - this->heap.resize(heapSize); - } - - // If sentinel objects are supported, populate the queue with them - TYPE sentinel = getSentinelObject(); - if (empty && sentinel) - { - heap[1] = sentinel; - for (int32_t i = 2; i < (int32_t)heap.size(); ++i) - heap[i] = getSentinelObject(); - _size = _maxSize; - } - } - - /// Return maximum size of queue - int32_t maxSize() - { - return _maxSize; - } - - /// Adds an Object to a PriorityQueue in log(size) time. If one tries to add more objects - /// than maxSize from initialize an {@link IndexOutOfBoundsException} is thrown. - TYPE add(const TYPE& type) - { - ++_size; - if (_size < 0 || _size >= (int32_t)heap.size()) - boost::throw_exception(IndexOutOfBoundsException()); - heap[_size] = type; - upHeap(); - return heap[1]; - } - - /// Adds an Object to a PriorityQueue in log(size) time. It returns the object (if any) that was - /// dropped off the heap because it was full. This can be the given parameter (in case it is - /// smaller than the full heap's minimum, and couldn't be added), or another object that was - /// previously the smallest value in the heap and now has been replaced by a larger one, or null - /// if the queue wasn't yet full with maxSize elements. - TYPE addOverflow(const TYPE& type) - { - if (_size < _maxSize) - { - add(type); - return TYPE(); - } - else if (_size > 0 && !lessThan(type, heap[1])) - { - TYPE result = heap[1]; - heap[1] = type; - updateTop(); - return result; - } - else - return type; - } - - /// Returns the least element of the PriorityQueue. - TYPE top() - { - // We don't need to check size here: if maxSize is 0, then heap is length 2 array with both - // entries null. If size is 0 then heap[1] is already null. - return heap[1]; - } - - /// Removes and returns the least element of the PriorityQueue. - TYPE pop() - { - if (_size > 0) - { - TYPE result = heap[1]; // save first value - heap[1] = heap[_size]; // move last to first - heap[_size--] = TYPE(); - downHeap(); // adjust heap - return result; +namespace Lucene { + +/// A PriorityQueue maintains a partial ordering of its elements such that the least element can always +/// be found in constant time. Put()'s and pop()'s require log(size) time. +/// +/// NOTE: This class pre-allocates a full array of length maxSize + 1. +template +class PriorityQueue : public LuceneObject { +public: + typedef typename std::vector heap_type; + + PriorityQueue(int32_t maxSize) { + this->_size = 0; + this->_maxSize = maxSize; + } + + virtual ~PriorityQueue() { + } + +protected: + heap_type heap; + int32_t _size; + int32_t _maxSize; + +public: + virtual void initialize() { + bool empty = heap.empty(); + + if (empty) { + int32_t heapSize = 0; + if (_maxSize == 0) { + // We allocate 1 extra to avoid if statement in top() + heapSize = 2; + } else if (_maxSize == INT_MAX) { + // Don't wrap heapSize to -1, in this case, which causes a confusing NegativeArraySizeException. + // Note that very likely this will simply then hit an OOME, but at least that's more indicative + // to caller that this values is too big. We don't +1 in this case, but it's very unlikely in + // practice one will actually insert this many objects into the PQ + heapSize = INT_MAX; + } else { + // NOTE: we add +1 because all access to heap is 1-based not 0-based. heap[0] is unused. + heapSize = _maxSize + 1; } - else - return TYPE(); - } - - /// Should be called when the Object at top changes values. - TYPE updateTop() - { - downHeap(); - return heap[1]; - } - - /// Returns the number of elements currently stored in the PriorityQueue. - int32_t size() const - { - return _size; - } - - /// Returns whether PriorityQueue is currently empty. - bool empty() const - { - return (_size == 0); - } - - /// Removes all entries from the PriorityQueue. - void clear() - { - for (int32_t i = 0; i <= _size; ++i) - heap[i] = TYPE(); - _size = 0; + this->heap.resize(heapSize); } - protected: - void upHeap() - { - int32_t i = _size; - TYPE node = heap[i]; // save bottom node - int32_t j = MiscUtils::unsignedShift(i, 1); - while (j > 0 && lessThan(node, heap[j])) - { - heap[i] = heap[j]; // shift parents down - i = j; - j = MiscUtils::unsignedShift(j, 1); + // If sentinel objects are supported, populate the queue with them + TYPE sentinel = getSentinelObject(); + if (empty && sentinel) { + heap[1] = sentinel; + for (int32_t i = 2; i < (int32_t)heap.size(); ++i) { + heap[i] = getSentinelObject(); } - heap[i] = node; // install saved node + _size = _maxSize; + } + } + + /// Return maximum size of queue + int32_t maxSize() { + return _maxSize; + } + + /// Adds an Object to a PriorityQueue in log(size) time. If one tries to add more objects + /// than maxSize from initialize an {@link IndexOutOfBoundsException} is thrown. + TYPE add(const TYPE& type) { + ++_size; + if (_size < 0 || _size >= (int32_t)heap.size()) { + boost::throw_exception(IndexOutOfBoundsException()); + } + heap[_size] = type; + upHeap(); + return heap[1]; + } + + /// Adds an Object to a PriorityQueue in log(size) time. It returns the object (if any) that was + /// dropped off the heap because it was full. This can be the given parameter (in case it is + /// smaller than the full heap's minimum, and couldn't be added), or another object that was + /// previously the smallest value in the heap and now has been replaced by a larger one, or null + /// if the queue wasn't yet full with maxSize elements. + TYPE addOverflow(const TYPE& type) { + if (_size < _maxSize) { + add(type); + return TYPE(); + } else if (_size > 0 && !lessThan(type, heap[1])) { + TYPE result = heap[1]; + heap[1] = type; + updateTop(); + return result; + } else { + return type; + } + } + + /// Returns the least element of the PriorityQueue. + TYPE top() { + // We don't need to check size here: if maxSize is 0, then heap is length 2 array with both + // entries null. If size is 0 then heap[1] is already null. + return heap[1]; + } + + /// Removes and returns the least element of the PriorityQueue. + TYPE pop() { + if (_size > 0) { + TYPE result = heap[1]; // save first value + heap[1] = heap[_size]; // move last to first + heap[_size--] = TYPE(); + downHeap(); // adjust heap + return result; + } else { + return TYPE(); } - - void downHeap() - { - int32_t i = 1; - TYPE node = heap[i]; // save top node - int32_t j = i << 1; // find smaller child - int32_t k = j + 1; - if (k <= _size && lessThan(heap[k], heap[j])) + } + + /// Should be called when the Object at top changes values. + TYPE updateTop() { + downHeap(); + return heap[1]; + } + + /// Returns the number of elements currently stored in the PriorityQueue. + int32_t size() const { + return _size; + } + + /// Returns whether PriorityQueue is currently empty. + bool empty() const { + return (_size == 0); + } + + /// Removes all entries from the PriorityQueue. + void clear() { + for (int32_t i = 0; i <= _size; ++i) { + heap[i] = TYPE(); + } + _size = 0; + } + +protected: + void upHeap() { + int32_t i = _size; + TYPE node = heap[i]; // save bottom node + int32_t j = MiscUtils::unsignedShift(i, 1); + while (j > 0 && lessThan(node, heap[j])) { + heap[i] = heap[j]; // shift parents down + i = j; + j = MiscUtils::unsignedShift(j, 1); + } + heap[i] = node; // install saved node + } + + void downHeap() { + int32_t i = 1; + TYPE node = heap[i]; // save top node + int32_t j = i << 1; // find smaller child + int32_t k = j + 1; + if (k <= _size && lessThan(heap[k], heap[j])) { + j = k; + } + while (j <= _size && lessThan(heap[j], node)) { + heap[i] = heap[j]; // shift up child + i = j; + j = i << 1; + k = j + 1; + if (k <= _size && lessThan(heap[k], heap[j])) { j = k; - while (j <= _size && lessThan(heap[j], node)) - { - heap[i] = heap[j]; // shift up child - i = j; - j = i << 1; - k = j + 1; - if (k <= _size && lessThan(heap[k], heap[j])) - j = k; } - heap[i] = node; // install saved node } + heap[i] = node; // install saved node + } - /// Determines the ordering of objects in this priority queue. Subclasses must define this one method. - virtual bool lessThan(const TYPE& first, const TYPE& second) - { - return std::less()(first, second); - } + /// Determines the ordering of objects in this priority queue. Subclasses must define this one method. + virtual bool lessThan(const TYPE& first, const TYPE& second) { + return std::less()(first, second); + } + + /// This method can be overridden by extending classes to return a sentinel object which will be used by + /// {@link #initialize} to fill the queue, so that the code which uses that queue can always assume it's + /// full and only change the top without attempting to insert any new object. + /// + /// Those sentinel values should always compare worse than any non-sentinel value (ie., {@link #lessThan} + /// should always favour the non-sentinel values). + virtual TYPE getSentinelObject() { + return TYPE(); + } +}; - /// This method can be overridden by extending classes to return a sentinel object which will be used by - /// {@link #initialize} to fill the queue, so that the code which uses that queue can always assume it's - /// full and only change the top without attempting to insert any new object. - /// - /// Those sentinel values should always compare worse than any non-sentinel value (ie., {@link #lessThan} - /// should always favour the non-sentinel values). - virtual TYPE getSentinelObject() - { - return TYPE(); - } - }; } #endif diff --git a/include/Query.h b/include/Query.h index 5c7200d0..4337b4b1 100644 --- a/include/Query.h +++ b/include/Query.h @@ -9,104 +9,104 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// The abstract base class for queries. +namespace Lucene { + +/// The abstract base class for queries. +/// +/// Instantiable subclasses are: +/// +/// {@link TermQuery} +/// {@link MultiTermQuery} +/// {@link BooleanQuery} +/// {@link WildcardQuery} +/// {@link PhraseQuery} +/// {@link PrefixQuery} +/// {@link MultiPhraseQuery} +/// {@link FuzzyQuery} +/// {@link TermRangeQuery} +/// {@link NumericRangeQuery} +/// {@link org.apache.lucene.search.spans.SpanQuery} +/// +/// A parser for queries is contained in: {@link QueryParser} +class LPPAPI Query : public LuceneObject { +public: + Query(); + virtual ~Query(); + + LUCENE_CLASS(Query); + +protected: + double boost; // query boost factor + +public: + /// Sets the boost for this query clause to b. Documents matching this clause will (in addition to + /// the normal weightings) have their score multiplied by b. + virtual void setBoost(double b); + + /// Gets the boost for this clause. Documents matching this clause will (in addition to the normal + /// weightings) have their score multiplied by b. The boost is 1.0 by default. + virtual double getBoost(); + + /// Prints a query to a string, with field assumed to be the default field and omitted. /// - /// Instantiable subclasses are: + /// The representation used is one that is supposed to be readable by {@link QueryParser}. However, + /// there are the following limitations: /// - /// {@link TermQuery} - /// {@link MultiTermQuery} - /// {@link BooleanQuery} - /// {@link WildcardQuery} - /// {@link PhraseQuery} - /// {@link PrefixQuery} - /// {@link MultiPhraseQuery} - /// {@link FuzzyQuery} - /// {@link TermRangeQuery} - /// {@link NumericRangeQuery} - /// {@link org.apache.lucene.search.spans.SpanQuery} + /// If the query was created by the parser, the printed representation may not be exactly what was + /// parsed. For example, characters that need to be escaped will be represented without the required + /// backslash. /// - /// A parser for queries is contained in: {@link QueryParser} - class LPPAPI Query : public LuceneObject - { - public: - Query(); - virtual ~Query(); - - LUCENE_CLASS(Query); - - protected: - double boost; // query boost factor - - public: - /// Sets the boost for this query clause to b. Documents matching this clause will (in addition to - /// the normal weightings) have their score multiplied by b. - virtual void setBoost(double b); - - /// Gets the boost for this clause. Documents matching this clause will (in addition to the normal - /// weightings) have their score multiplied by b. The boost is 1.0 by default. - virtual double getBoost(); - - /// Prints a query to a string, with field assumed to be the default field and omitted. - /// - /// The representation used is one that is supposed to be readable by {@link QueryParser}. However, - /// there are the following limitations: - /// - /// If the query was created by the parser, the printed representation may not be exactly what was - /// parsed. For example, characters that need to be escaped will be represented without the required - /// backslash. - /// - /// Some of the more complicated queries (eg. span queries) don't have a representation that can be - /// parsed by QueryParser. - virtual String toString(const String& field); - - /// Prints a query to a string. - virtual String toString(); - - /// Constructs an appropriate Weight implementation for this query. - /// Only implemented by primitive queries, which re-write to themselves. - virtual WeightPtr createWeight(const SearcherPtr& searcher); - - /// Constructs and initializes a Weight for a top-level query. - virtual WeightPtr weight(const SearcherPtr& searcher); - - /// Called to re-write queries into primitive queries. For example, a PrefixQuery will be rewritten - /// into a BooleanQuery that consists of TermQuerys. - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - /// Called when re-writing queries under MultiSearcher. - /// - /// Create a single query suitable for use by all subsearchers (in 1-1 correspondence with queries). - /// This is an optimization of the OR of all queries. We handle the common optimization cases of equal - /// queries and overlapping clauses of boolean OR queries (as generated by MultiTermQuery.rewrite()). - /// Be careful overriding this method as queries[0] determines which method will be called and is not - /// necessarily of the same type as the other queries. - virtual QueryPtr combine(Collection queries); - - /// Adds all terms occurring in this query to the terms set. Only works if this query is in its - /// {@link #rewrite rewritten} form. - virtual void extractTerms(SetTerm terms); - - /// Merges the clauses of a set of BooleanQuery's into a single BooleanQuery. - /// - /// A utility for use by {@link #combine(Query[])} implementations. - static QueryPtr mergeBooleanQueries(Collection queries); - - /// Returns the Similarity implementation to be used for this query. Subclasses may override this method - /// to specify their own Similarity implementation, perhaps one that delegates through that of the Searcher. - /// By default the Searcher's Similarity implementation is returned. - virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); - - /// Returns a clone of this query. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - - /// Return given boost value as a string. - String boostString(); - }; + /// Some of the more complicated queries (eg. span queries) don't have a representation that can be + /// parsed by QueryParser. + virtual String toString(const String& field); + + /// Prints a query to a string. + virtual String toString(); + + /// Constructs an appropriate Weight implementation for this query. + /// Only implemented by primitive queries, which re-write to themselves. + virtual WeightPtr createWeight(const SearcherPtr& searcher); + + /// Constructs and initializes a Weight for a top-level query. + virtual WeightPtr weight(const SearcherPtr& searcher); + + /// Called to re-write queries into primitive queries. For example, a PrefixQuery will be rewritten + /// into a BooleanQuery that consists of TermQuerys. + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + /// Called when re-writing queries under MultiSearcher. + /// + /// Create a single query suitable for use by all subsearchers (in 1-1 correspondence with queries). + /// This is an optimization of the OR of all queries. We handle the common optimization cases of equal + /// queries and overlapping clauses of boolean OR queries (as generated by MultiTermQuery.rewrite()). + /// Be careful overriding this method as queries[0] determines which method will be called and is not + /// necessarily of the same type as the other queries. + virtual QueryPtr combine(Collection queries); + + /// Adds all terms occurring in this query to the terms set. Only works if this query is in its + /// {@link #rewrite rewritten} form. + virtual void extractTerms(SetTerm terms); + + /// Merges the clauses of a set of BooleanQuery's into a single BooleanQuery. + /// + /// A utility for use by {@link #combine(Query[])} implementations. + static QueryPtr mergeBooleanQueries(Collection queries); + + /// Returns the Similarity implementation to be used for this query. Subclasses may override this method + /// to specify their own Similarity implementation, perhaps one that delegates through that of the Searcher. + /// By default the Searcher's Similarity implementation is returned. + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher); + + /// Returns a clone of this query. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + + /// Return given boost value as a string. + String boostString(); +}; + } #endif diff --git a/include/QueryParseError.h b/include/QueryParseError.h index bc211e1c..8e05d31f 100644 --- a/include/QueryParseError.h +++ b/include/QueryParseError.h @@ -9,45 +9,45 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Utility class to handle query parse errors - class QueryParseError : public LuceneObject - { - public: - virtual ~QueryParseError(); - LUCENE_CLASS(QueryParseError); - - public: - /// Returns a detailed message for the Error when it is thrown by the token manager to indicate a - /// lexical error. - /// @param EOFSeen Indicates if EOF caused the lexical error - /// @param curLexState Lexical state in which this error occurred - /// @param errorLine Line number when the error occurred - /// @param errorColumn Column number when the error occurred - /// @param errorAfter Prefix that was seen before this error occurred - /// @param curChar The offending character - static String lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, - const String& errorAfter, wchar_t curChar); - - /// Generate a parse error message and returns it. - /// @param currentToken This is the last token that has been consumed successfully. If this object - /// has been created due to a parse error, the token following this token will (therefore) be the first - /// error token. - /// @param expectedTokenSequences Each entry in this array is an array of integers. Each array of - /// integers represents a sequence of tokens (by their ordinal values) that is expected at this point - /// of the parse. - /// @param tokenImage This is a reference to the "tokenImage" array of the generated parser within - /// which the parse error occurred. - static String parseError(const QueryParserTokenPtr& currentToken, Collection< Collection > expectedTokenSequences, - Collection tokenImage); - - - protected: - /// Replaces unprintable characters by their escaped (or unicode escaped) equivalents in the - /// given string - static String addEscapes(const String& str); - }; +namespace Lucene { + +/// Utility class to handle query parse errors +class QueryParseError : public LuceneObject { +public: + virtual ~QueryParseError(); + LUCENE_CLASS(QueryParseError); + +public: + /// Returns a detailed message for the Error when it is thrown by the token manager to indicate a + /// lexical error. + /// @param EOFSeen Indicates if EOF caused the lexical error + /// @param curLexState Lexical state in which this error occurred + /// @param errorLine Line number when the error occurred + /// @param errorColumn Column number when the error occurred + /// @param errorAfter Prefix that was seen before this error occurred + /// @param curChar The offending character + static String lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, + const String& errorAfter, wchar_t curChar); + + /// Generate a parse error message and returns it. + /// @param currentToken This is the last token that has been consumed successfully. If this object + /// has been created due to a parse error, the token following this token will (therefore) be the first + /// error token. + /// @param expectedTokenSequences Each entry in this array is an array of integers. Each array of + /// integers represents a sequence of tokens (by their ordinal values) that is expected at this point + /// of the parse. + /// @param tokenImage This is a reference to the "tokenImage" array of the generated parser within + /// which the parse error occurred. + static String parseError(const QueryParserTokenPtr& currentToken, Collection< Collection > expectedTokenSequences, + Collection tokenImage); + + +protected: + /// Replaces unprintable characters by their escaped (or unicode escaped) equivalents in the + /// given string + static String addEscapes(const String& str); +}; + } #endif diff --git a/include/QueryParser.h b/include/QueryParser.h index 2278bd89..59f8d8d7 100644 --- a/include/QueryParser.h +++ b/include/QueryParser.h @@ -11,465 +11,463 @@ #include "DateTools.h" #include "BooleanClause.h" -namespace Lucene -{ - typedef HashMap MapStringResolution; +namespace Lucene { + +typedef HashMap MapStringResolution; + +/// The most important method is {@link #parse(const String&)}. +/// +/// The syntax for query strings is as follows: +/// A Query is a series of clauses. +/// A clause may be prefixed by: +///
        +///
      • a plus (+) or a minus (-) sign, indicating that the clause is required or prohibited respectively; or +///
      • a term followed by a colon, indicating the field to be searched. This enables one to construct queries +/// which search multiple fields. +///
      +/// +/// A clause may be either: +///
        +///
      • a term, indicating all the documents that contain this term; or +///
      • a nested query, enclosed in parentheses. Note that this may be used with a +/- prefix to require any +/// of a set of terms. +///
      +/// +/// Thus, in BNF, the query grammar is: +///
      +/// Query  ::= ( Clause )*
      +/// Clause ::= ["+", "-"] [ ":"] (  | "(" Query ")" )
      +/// 
      +/// +/// Examples of appropriately formatted queries can be found in the query syntax documentation. +/// +/// In {@link TermRangeQuery}s, QueryParser tries to detect date values, eg. +/// date:[6/1/2005 TO 6/4/2005] produces a range query that searches for "date" fields between +/// 2005-06-01 and 2005-06-04. Note that the format of the accepted input depends on {@link #setLocale(Locale) +/// the locale}. +/// +/// By default a date is converted into a search term using the deprecated {@link DateField} for compatibility +/// reasons. To use the new {@link DateTools} to convert dates, a {@link Resolution} has to be set. +/// +/// The date resolution that shall be used for RangeQueries can be set using {@link #setDateResolution(Resolution)} +/// or {@link #setDateResolution(const String&, Resolution)}. The former sets the default date resolution for +/// all fields, whereas the latter can be used to set field specific date resolutions. Field specific date +/// resolutions take, if set, precedence over the default date resolution. +/// +/// If you use neither {@link DateField} nor {@link DateTools} in your index, you can create your own query +/// parser that inherits QueryParser and overwrites {@link #getRangeQuery(const String&, const String&, +/// const String&, bool)} to use a different method for date conversion. +/// +/// Note that QueryParser is not thread-safe. +/// +/// NOTE: there is a new QueryParser in contrib, which matches the same syntax as this class, but is more modular, +/// enabling substantial customization to how a query is created. +/// +/// NOTE: You must specify the required {@link Version} compatibility when creating QueryParser: +///
        +///
      • As of 2.9, {@link #setEnablePositionIncrements} is true by default. +///
      +class LPPAPI QueryParser : public QueryParserConstants, public LuceneObject { +public: + /// Constructs a query parser. + /// @param matchVersion Lucene version to match. + /// @param field The default field for query terms. + /// @param analyzer Used to find terms in the query text. + QueryParser(LuceneVersion::Version matchVersion, const String& field, const AnalyzerPtr& analyzer); + + /// Constructor with user supplied QueryParserCharStream. + QueryParser(const QueryParserCharStreamPtr& stream); + + /// Constructor with generated Token Manager. + QueryParser(const QueryParserTokenManagerPtr& tokenMgr); + + virtual ~QueryParser(); + + LUCENE_CLASS(QueryParser); + + /// The default operator for parsing queries. Use {@link QueryParser#setDefaultOperator} to change it. + enum Operator { OR_OPERATOR, AND_OPERATOR }; + +protected: + static const int32_t CONJ_NONE; + static const int32_t CONJ_AND; + static const int32_t CONJ_OR; + + static const int32_t MOD_NONE; + static const int32_t MOD_NOT; + static const int32_t MOD_REQ; + + /// The actual operator that parser uses to combine query terms + Operator _operator; + + /// Next token. + int32_t _jj_ntk; + QueryParserTokenPtr jj_scanpos; + QueryParserTokenPtr jj_lastpos; + + int32_t jj_la; + int32_t jj_gen; + Collection jj_la1; + + static const int32_t jj_la1_0[]; + static const int32_t jj_la1_1[]; + + struct JJCalls; + typedef boost::shared_ptr JJCallsPtr; + + struct JJCalls { + JJCalls() { + gen = 0; + arg = 0; + } + + int32_t gen; + QueryParserTokenPtr first; + int32_t arg; + JJCallsPtr next; + }; + + Collection jj_2_rtns; + bool jj_rescan; + int32_t jj_gc; + + Collection< Collection > jj_expentries; + Collection jj_expentry; + int32_t jj_kind; + Collection jj_lasttokens; + int32_t jj_endpos; + +public: + bool lowercaseExpandedTerms; + RewriteMethodPtr multiTermRewriteMethod; + bool allowLeadingWildcard; + bool enablePositionIncrements; + + AnalyzerPtr analyzer; + String field; + int32_t phraseSlop; + double fuzzyMinSim; + int32_t fuzzyPrefixLength; + std::locale locale; + + // the default date resolution + DateTools::Resolution dateResolution; + + // maps field names to date resolutions + MapStringResolution fieldToDateResolution; + + // The collator to use when determining range inclusion, for use when constructing RangeQuerys + CollatorPtr rangeCollator; + + /// Generated Token Manager. + QueryParserTokenManagerPtr token_source; + + /// Current token. + QueryParserTokenPtr token; + + /// Next token. + QueryParserTokenPtr jj_nt; + +public: + /// Parses a query string, returning a {@link Query}. + /// @param query The query string to be parsed. + QueryPtr parse(const String& query); + + /// @return Returns the analyzer. + AnalyzerPtr getAnalyzer(); + + /// @return Returns the field. + String getField(); + + /// Get the minimal similarity for fuzzy queries. + double getFuzzyMinSim(); + + /// Set the minimum similarity for fuzzy queries. Default is 0.5. + void setFuzzyMinSim(double fuzzyMinSim); - /// The most important method is {@link #parse(const String&)}. + /// Get the prefix length for fuzzy queries. + /// @return Returns the fuzzyPrefixLength. + int32_t getFuzzyPrefixLength(); + + /// Set the prefix length for fuzzy queries. Default is 0. + /// @param fuzzyPrefixLength The fuzzyPrefixLength to set. + void setFuzzyPrefixLength(int32_t fuzzyPrefixLength); + + /// Sets the default slop for phrases. If zero, then exact phrase matches are required. + /// Default value is zero. + void setPhraseSlop(int32_t phraseSlop); + + /// Gets the default slop for phrases. + int32_t getPhraseSlop(); + + /// Set to true to allow leading wildcard characters. /// - /// The syntax for query strings is as follows: - /// A Query is a series of clauses. - /// A clause may be prefixed by: - ///
        - ///
      • a plus (+) or a minus (-) sign, indicating that the clause is required or prohibited respectively; or - ///
      • a term followed by a colon, indicating the field to be searched. This enables one to construct queries - /// which search multiple fields. - ///
      + /// When set, * or ? are allowed as the first character of a PrefixQuery and WildcardQuery. + /// Note that this can produce very slow queries on big indexes. Default: false. + void setAllowLeadingWildcard(bool allowLeadingWildcard); + + /// @see #setAllowLeadingWildcard(bool) + bool getAllowLeadingWildcard(); + + /// Set to true to enable position increments in result query. /// - /// A clause may be either: - ///
        - ///
      • a term, indicating all the documents that contain this term; or - ///
      • a nested query, enclosed in parentheses. Note that this may be used with a +/- prefix to require any - /// of a set of terms. - ///
      + /// When set, result phrase and multi-phrase queries will be aware of position increments. + /// Useful when eg. a StopFilter increases the position increment of the token that follows an + /// omitted token. Default: false. + void setEnablePositionIncrements(bool enable); + + /// @see #setEnablePositionIncrements(bool) + bool getEnablePositionIncrements(); + + /// Sets the boolean operator of the QueryParser. In default mode (OR_OPERATOR) terms without + /// any modifiers are considered optional: for example capital of Hungary is equal to capital + /// OR of OR Hungary. + /// In AND_OPERATOR mode terms are considered to be in conjunction: the above mentioned query is + /// parsed as capital AND of AND Hungary + void setDefaultOperator(Operator op); + + /// Gets implicit operator setting, which will be either AND_OPERATOR or OR_OPERATOR. + Operator getDefaultOperator(); + + /// Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically lower-cased + /// or not. Default is true. + void setLowercaseExpandedTerms(bool lowercaseExpandedTerms); + + /// @see #setLowercaseExpandedTerms(bool) + bool getLowercaseExpandedTerms(); + + /// By default QueryParser uses {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} when + /// creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable + /// because it a) Runs faster b) Does not have the scarcity of terms unduly influence score c) avoids + /// any "TooManyClauses" exception. However, if your application really needs to use the old- + /// fashioned BooleanQuery expansion rewriting and the above points are not relevant then use this + /// to change the rewrite method. + void setMultiTermRewriteMethod(const RewriteMethodPtr& method); + + /// @see #setMultiTermRewriteMethod + RewriteMethodPtr getMultiTermRewriteMethod(); + + /// Set locale used by date range parsing. + void setLocale(std::locale locale); + + /// Returns current locale, allowing access by subclasses. + std::locale getLocale(); + + /// Sets the default date resolution used by RangeQueries for fields for which no specific date + /// resolutions has been set. Field specific resolutions can be set with {@link + /// #setDateResolution(const String&, DateTools::Resolution)}. + /// @param dateResolution The default date resolution to set + void setDateResolution(DateTools::Resolution dateResolution); + + /// Sets the date resolution used by RangeQueries for a specific field. + /// @param fieldName Field for which the date resolution is to be set + /// @param dateResolution Date resolution to set + void setDateResolution(const String& fieldName, DateTools::Resolution dateResolution); + + /// Returns the date resolution that is used by RangeQueries for the given field. Returns null, if + /// no default or field specific date resolution has been set for the given field. + DateTools::Resolution getDateResolution(const String& fieldName); + + /// Sets the collator used to determine index term inclusion in ranges for RangeQuerys. /// - /// Thus, in BNF, the query grammar is: - ///
      +    /// WARNING: Setting the rangeCollator to a non-null collator using this method will cause every
      +    /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined.  Depending
      +    /// on the number of index Terms in this Field, the operation could be very slow.
      +    /// @param rc The collator to use when constructing RangeQuerys
      +    void setRangeCollator(const CollatorPtr& rc);
      +
      +    /// @return the collator used to determine index term inclusion in ranges for RangeQuerys.
      +    CollatorPtr getRangeCollator();
      +
      +    /// Command line tool to test QueryParser, using {@link SimpleAnalyzer}.
      +    static int main(Collection args);
      +
           /// Query  ::= ( Clause )*
           /// Clause ::= ["+", "-"] [ ":"] (  | "(" Query ")" )
      -    /// 
      - /// - /// Examples of appropriately formatted queries can be found in the query syntax documentation. - /// - /// In {@link TermRangeQuery}s, QueryParser tries to detect date values, eg. - /// date:[6/1/2005 TO 6/4/2005] produces a range query that searches for "date" fields between - /// 2005-06-01 and 2005-06-04. Note that the format of the accepted input depends on {@link #setLocale(Locale) - /// the locale}. - /// - /// By default a date is converted into a search term using the deprecated {@link DateField} for compatibility - /// reasons. To use the new {@link DateTools} to convert dates, a {@link Resolution} has to be set. - /// - /// The date resolution that shall be used for RangeQueries can be set using {@link #setDateResolution(Resolution)} - /// or {@link #setDateResolution(const String&, Resolution)}. The former sets the default date resolution for - /// all fields, whereas the latter can be used to set field specific date resolutions. Field specific date - /// resolutions take, if set, precedence over the default date resolution. - /// - /// If you use neither {@link DateField} nor {@link DateTools} in your index, you can create your own query - /// parser that inherits QueryParser and overwrites {@link #getRangeQuery(const String&, const String&, - /// const String&, bool)} to use a different method for date conversion. - /// - /// Note that QueryParser is not thread-safe. - /// - /// NOTE: there is a new QueryParser in contrib, which matches the same syntax as this class, but is more modular, - /// enabling substantial customization to how a query is created. - /// - /// NOTE: You must specify the required {@link Version} compatibility when creating QueryParser: - ///
        - ///
      • As of 2.9, {@link #setEnablePositionIncrements} is true by default. - ///
      - class LPPAPI QueryParser : public QueryParserConstants, public LuceneObject - { - public: - /// Constructs a query parser. - /// @param matchVersion Lucene version to match. - /// @param field The default field for query terms. - /// @param analyzer Used to find terms in the query text. - QueryParser(LuceneVersion::Version matchVersion, const String& field, const AnalyzerPtr& analyzer); - - /// Constructor with user supplied QueryParserCharStream. - QueryParser(const QueryParserCharStreamPtr& stream); - - /// Constructor with generated Token Manager. - QueryParser(const QueryParserTokenManagerPtr& tokenMgr); - - virtual ~QueryParser(); - - LUCENE_CLASS(QueryParser); - - /// The default operator for parsing queries. Use {@link QueryParser#setDefaultOperator} to change it. - enum Operator { OR_OPERATOR, AND_OPERATOR }; - - protected: - static const int32_t CONJ_NONE; - static const int32_t CONJ_AND; - static const int32_t CONJ_OR; - - static const int32_t MOD_NONE; - static const int32_t MOD_NOT; - static const int32_t MOD_REQ; - - /// The actual operator that parser uses to combine query terms - Operator _operator; - - /// Next token. - int32_t _jj_ntk; - QueryParserTokenPtr jj_scanpos; - QueryParserTokenPtr jj_lastpos; - - int32_t jj_la; - int32_t jj_gen; - Collection jj_la1; - - static const int32_t jj_la1_0[]; - static const int32_t jj_la1_1[]; - - struct JJCalls; - typedef boost::shared_ptr JJCallsPtr; - - struct JJCalls - { - JJCalls() - { - gen = 0; - arg = 0; - } - - int32_t gen; - QueryParserTokenPtr first; - int32_t arg; - JJCallsPtr next; - }; - - Collection jj_2_rtns; - bool jj_rescan; - int32_t jj_gc; - - Collection< Collection > jj_expentries; - Collection jj_expentry; - int32_t jj_kind; - Collection jj_lasttokens; - int32_t jj_endpos; - - public: - bool lowercaseExpandedTerms; - RewriteMethodPtr multiTermRewriteMethod; - bool allowLeadingWildcard; - bool enablePositionIncrements; - - AnalyzerPtr analyzer; - String field; - int32_t phraseSlop; - double fuzzyMinSim; - int32_t fuzzyPrefixLength; - std::locale locale; - - // the default date resolution - DateTools::Resolution dateResolution; - - // maps field names to date resolutions - MapStringResolution fieldToDateResolution; - - // The collator to use when determining range inclusion, for use when constructing RangeQuerys - CollatorPtr rangeCollator; - - /// Generated Token Manager. - QueryParserTokenManagerPtr token_source; - - /// Current token. - QueryParserTokenPtr token; - - /// Next token. - QueryParserTokenPtr jj_nt; - - public: - /// Parses a query string, returning a {@link Query}. - /// @param query The query string to be parsed. - QueryPtr parse(const String& query); - - /// @return Returns the analyzer. - AnalyzerPtr getAnalyzer(); - - /// @return Returns the field. - String getField(); - - /// Get the minimal similarity for fuzzy queries. - double getFuzzyMinSim(); - - /// Set the minimum similarity for fuzzy queries. Default is 0.5. - void setFuzzyMinSim(double fuzzyMinSim); - - /// Get the prefix length for fuzzy queries. - /// @return Returns the fuzzyPrefixLength. - int32_t getFuzzyPrefixLength(); - - /// Set the prefix length for fuzzy queries. Default is 0. - /// @param fuzzyPrefixLength The fuzzyPrefixLength to set. - void setFuzzyPrefixLength(int32_t fuzzyPrefixLength); - - /// Sets the default slop for phrases. If zero, then exact phrase matches are required. - /// Default value is zero. - void setPhraseSlop(int32_t phraseSlop); - - /// Gets the default slop for phrases. - int32_t getPhraseSlop(); - - /// Set to true to allow leading wildcard characters. - /// - /// When set, * or ? are allowed as the first character of a PrefixQuery and WildcardQuery. - /// Note that this can produce very slow queries on big indexes. Default: false. - void setAllowLeadingWildcard(bool allowLeadingWildcard); - - /// @see #setAllowLeadingWildcard(bool) - bool getAllowLeadingWildcard(); - - /// Set to true to enable position increments in result query. - /// - /// When set, result phrase and multi-phrase queries will be aware of position increments. - /// Useful when eg. a StopFilter increases the position increment of the token that follows an - /// omitted token. Default: false. - void setEnablePositionIncrements(bool enable); - - /// @see #setEnablePositionIncrements(bool) - bool getEnablePositionIncrements(); + int32_t Conjunction(); + int32_t Modifiers(); - /// Sets the boolean operator of the QueryParser. In default mode (OR_OPERATOR) terms without - /// any modifiers are considered optional: for example capital of Hungary is equal to capital - /// OR of OR Hungary. - /// In AND_OPERATOR mode terms are considered to be in conjunction: the above mentioned query is - /// parsed as capital AND of AND Hungary - void setDefaultOperator(Operator op); + /// This makes sure that there is no garbage after the query string + virtual QueryPtr TopLevelQuery(const String& field); - /// Gets implicit operator setting, which will be either AND_OPERATOR or OR_OPERATOR. - Operator getDefaultOperator(); + virtual QueryPtr ParseQuery(const String& field); + virtual QueryPtr ParseClause(const String& field); + virtual QueryPtr ParseTerm(const String& field); - /// Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically lower-cased - /// or not. Default is true. - void setLowercaseExpandedTerms(bool lowercaseExpandedTerms); + /// Reinitialise. + virtual void ReInit(const QueryParserCharStreamPtr& stream); - /// @see #setLowercaseExpandedTerms(bool) - bool getLowercaseExpandedTerms(); + /// Reinitialise. + virtual void ReInit(const QueryParserTokenManagerPtr& tokenMgr); - /// By default QueryParser uses {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} when - /// creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable - /// because it a) Runs faster b) Does not have the scarcity of terms unduly influence score c) avoids - /// any "TooManyClauses" exception. However, if your application really needs to use the old- - /// fashioned BooleanQuery expansion rewriting and the above points are not relevant then use this - /// to change the rewrite method. - void setMultiTermRewriteMethod(const RewriteMethodPtr& method); + /// Get the next Token. + virtual QueryParserTokenPtr getNextToken(); - /// @see #setMultiTermRewriteMethod - RewriteMethodPtr getMultiTermRewriteMethod(); + /// Get the specific Token. + virtual QueryParserTokenPtr getToken(int32_t index); - /// Set locale used by date range parsing. - void setLocale(std::locale locale); + /// Generate QueryParserError exception. + virtual void generateParseException(); - /// Returns current locale, allowing access by subclasses. - std::locale getLocale(); + /// Enable tracing. + virtual void enable_tracing(); - /// Sets the default date resolution used by RangeQueries for fields for which no specific date - /// resolutions has been set. Field specific resolutions can be set with {@link - /// #setDateResolution(const String&, DateTools::Resolution)}. - /// @param dateResolution The default date resolution to set - void setDateResolution(DateTools::Resolution dateResolution); + /// Disable tracing. + virtual void disable_tracing(); - /// Sets the date resolution used by RangeQueries for a specific field. - /// @param fieldName Field for which the date resolution is to be set - /// @param dateResolution Date resolution to set - void setDateResolution(const String& fieldName, DateTools::Resolution dateResolution); +protected: + /// Construct query parser with supplied QueryParserCharStream or TokenManager + void ConstructParser(const QueryParserCharStreamPtr& stream, const QueryParserTokenManagerPtr& tokenMgr); - /// Returns the date resolution that is used by RangeQueries for the given field. Returns null, if - /// no default or field specific date resolution has been set for the given field. - DateTools::Resolution getDateResolution(const String& fieldName); + virtual void addClause(Collection clauses, int32_t conj, int32_t mods, const QueryPtr& q); + + /// Use the analyzer to get all the tokens, and then build a TermQuery, PhraseQuery, or nothing + /// based on the term count. + virtual QueryPtr getFieldQuery(const String& field, const String& queryText); + + /// Base implementation delegates to {@link #getFieldQuery(const String&, const String&)}. + /// This method may be overridden, for example, to return a SpanNearQuery instead of a PhraseQuery. + virtual QueryPtr getFieldQuery(const String& field, const String& queryText, int32_t slop); + + /// Builds a new TermRangeQuery instance for given min/max parts + virtual QueryPtr getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); + + /// Builds a new BooleanQuery instance + /// @param disableCoord disable coord + BooleanQueryPtr newBooleanQuery(bool disableCoord); + + /// Builds a new BooleanClause instance + /// @param q sub query + /// @param occur how this clause should occur when matching documents + /// @return new BooleanClause instance + BooleanClausePtr newBooleanClause(const QueryPtr& q, BooleanClause::Occur occur); + + /// Builds a new TermQuery instance + /// @param term term + /// @return new TermQuery instance + QueryPtr newTermQuery(const TermPtr& term); + + /// Builds a new PhraseQuery instance + /// @return new PhraseQuery instance + PhraseQueryPtr newPhraseQuery(); + + /// Builds a new MultiPhraseQuery instance + /// @return new MultiPhraseQuery instance + MultiPhraseQueryPtr newMultiPhraseQuery(); + + /// Builds a new PrefixQuery instance + /// @param prefix Prefix term + /// @return new PrefixQuery instance + QueryPtr newPrefixQuery(const TermPtr& prefix); + + /// Builds a new FuzzyQuery instance + /// @param term Term + /// @param minimumSimilarity minimum similarity + /// @param prefixLength prefix length + /// @return new FuzzyQuery Instance + QueryPtr newFuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); + + /// Builds a new TermRangeQuery instance + /// @param field Field + /// @param part1 min + /// @param part2 max + /// @param inclusive true if range is inclusive + /// @return new TermRangeQuery instance + QueryPtr newRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); + + /// Builds a new MatchAllDocsQuery instance + /// @return new MatchAllDocsQuery instance + QueryPtr newMatchAllDocsQuery(); + + /// Builds a new WildcardQuery instance + /// @param t wildcard term + /// @return new WildcardQuery instance + QueryPtr newWildcardQuery(const TermPtr& term); + + /// Factory method for generating query, given a set of clauses. By default creates a boolean query + /// composed of clauses passed in. + /// + /// Can be overridden by extending classes, to modify query being returned. + /// + /// @param clauses List that contains {@link BooleanClause} instances to join. + /// @return Resulting {@link Query} object. + virtual QueryPtr getBooleanQuery(Collection clauses); + + /// Factory method for generating query, given a set of clauses. By default creates a boolean query + /// composed of clauses passed in. + /// + /// Can be overridden by extending classes, to modify query being returned. + /// + /// @param clauses List that contains {@link BooleanClause} instances to join. + /// @param disableCoord true if coord scoring should be disabled. + /// @return Resulting {@link Query} object. + virtual QueryPtr getBooleanQuery(Collection clauses, bool disableCoord); + + /// Factory method for generating a query. Called when parser parses an input term token that contains + /// one or more wildcard characters (? and *), but is not a prefix term token (one that has just a + /// single * character at the end) + /// + /// Depending on settings, prefix term may be lower-cased automatically. It will not go through the + /// default Analyzer, however, since normal Analyzers are unlikely to work properly with wildcard + /// templates. + /// + /// Can be overridden by extending classes, to provide custom handling for wildcard queries, which may + /// be necessary due to missing analyzer calls. + /// + /// @param field Name of the field query will use. + /// @param termStr Term token that contains one or more wild card characters (? or *), but is not simple + /// prefix term + /// @return Resulting {@link Query} built for the term + virtual QueryPtr getWildcardQuery(const String& field, const String& termStr); + + /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser + /// parses an input term token that uses prefix notation; that is, contains a single '*' wildcard + /// character as its last character. Since this is a special case of generic wildcard term, and such + /// a query can be optimized easily, this usually results in a different query object. + /// + /// Depending on settings, a prefix term may be lower-cased automatically. It will not go through the + /// default Analyzer, however, since normal Analyzers are unlikely to work properly with wildcard templates. + /// + /// Can be overridden by extending classes, to provide custom handling for wild card queries, which may be + /// necessary due to missing analyzer calls. + /// + /// @param field Name of the field query will use. + /// @param termStr Term token to use for building term for the query (without trailing '*' character) + /// @return Resulting {@link Query} built for the term + virtual QueryPtr getPrefixQuery(const String& field, const String& termStr); + + /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser + /// parses an input term token that has the fuzzy suffix (~) appended. + /// + /// @param field Name of the field query will use. + /// @param termStr Term token to use for building term for the query + /// @return Resulting {@link Query} built for the term + virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity); + + /// Returns a String where the escape char has been removed, or kept only once if there was a double + /// escape. Supports escaped unicode characters, eg. translates \\u0041 to A. + String discardEscapeChar(const String& input); + + /// Returns the numeric value of the hexadecimal character + static int32_t hexToInt(wchar_t c); + + /// Returns a String where those characters that QueryParser expects to be escaped are escaped by + /// a preceding \. + static String escape(const String& s); + + bool jj_2_1(int32_t xla); + bool jj_3R_2(); + bool jj_3_1(); + bool jj_3R_3(); + + QueryParserTokenPtr jj_consume_token(int32_t kind); + bool jj_scan_token(int32_t kind); + int32_t jj_ntk(); + void jj_add_error_token(int32_t kind, int32_t pos); + void jj_rescan_token(); + void jj_save(int32_t index, int32_t xla); +}; - /// Sets the collator used to determine index term inclusion in ranges for RangeQuerys. - /// - /// WARNING: Setting the rangeCollator to a non-null collator using this method will cause every - /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending - /// on the number of index Terms in this Field, the operation could be very slow. - /// @param rc The collator to use when constructing RangeQuerys - void setRangeCollator(const CollatorPtr& rc); - - /// @return the collator used to determine index term inclusion in ranges for RangeQuerys. - CollatorPtr getRangeCollator(); - - /// Command line tool to test QueryParser, using {@link SimpleAnalyzer}. - static int main(Collection args); - - /// Query ::= ( Clause )* - /// Clause ::= ["+", "-"] [ ":"] ( | "(" Query ")" ) - int32_t Conjunction(); - int32_t Modifiers(); - - /// This makes sure that there is no garbage after the query string - virtual QueryPtr TopLevelQuery(const String& field); - - virtual QueryPtr ParseQuery(const String& field); - virtual QueryPtr ParseClause(const String& field); - virtual QueryPtr ParseTerm(const String& field); - - /// Reinitialise. - virtual void ReInit(const QueryParserCharStreamPtr& stream); - - /// Reinitialise. - virtual void ReInit(const QueryParserTokenManagerPtr& tokenMgr); - - /// Get the next Token. - virtual QueryParserTokenPtr getNextToken(); - - /// Get the specific Token. - virtual QueryParserTokenPtr getToken(int32_t index); - - /// Generate QueryParserError exception. - virtual void generateParseException(); - - /// Enable tracing. - virtual void enable_tracing(); - - /// Disable tracing. - virtual void disable_tracing(); - - protected: - /// Construct query parser with supplied QueryParserCharStream or TokenManager - void ConstructParser(const QueryParserCharStreamPtr& stream, const QueryParserTokenManagerPtr& tokenMgr); - - virtual void addClause(Collection clauses, int32_t conj, int32_t mods, const QueryPtr& q); - - /// Use the analyzer to get all the tokens, and then build a TermQuery, PhraseQuery, or nothing - /// based on the term count. - virtual QueryPtr getFieldQuery(const String& field, const String& queryText); - - /// Base implementation delegates to {@link #getFieldQuery(const String&, const String&)}. - /// This method may be overridden, for example, to return a SpanNearQuery instead of a PhraseQuery. - virtual QueryPtr getFieldQuery(const String& field, const String& queryText, int32_t slop); - - /// Builds a new TermRangeQuery instance for given min/max parts - virtual QueryPtr getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); - - /// Builds a new BooleanQuery instance - /// @param disableCoord disable coord - BooleanQueryPtr newBooleanQuery(bool disableCoord); - - /// Builds a new BooleanClause instance - /// @param q sub query - /// @param occur how this clause should occur when matching documents - /// @return new BooleanClause instance - BooleanClausePtr newBooleanClause(const QueryPtr& q, BooleanClause::Occur occur); - - /// Builds a new TermQuery instance - /// @param term term - /// @return new TermQuery instance - QueryPtr newTermQuery(const TermPtr& term); - - /// Builds a new PhraseQuery instance - /// @return new PhraseQuery instance - PhraseQueryPtr newPhraseQuery(); - - /// Builds a new MultiPhraseQuery instance - /// @return new MultiPhraseQuery instance - MultiPhraseQueryPtr newMultiPhraseQuery(); - - /// Builds a new PrefixQuery instance - /// @param prefix Prefix term - /// @return new PrefixQuery instance - QueryPtr newPrefixQuery(const TermPtr& prefix); - - /// Builds a new FuzzyQuery instance - /// @param term Term - /// @param minimumSimilarity minimum similarity - /// @param prefixLength prefix length - /// @return new FuzzyQuery Instance - QueryPtr newFuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength); - - /// Builds a new TermRangeQuery instance - /// @param field Field - /// @param part1 min - /// @param part2 max - /// @param inclusive true if range is inclusive - /// @return new TermRangeQuery instance - QueryPtr newRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive); - - /// Builds a new MatchAllDocsQuery instance - /// @return new MatchAllDocsQuery instance - QueryPtr newMatchAllDocsQuery(); - - /// Builds a new WildcardQuery instance - /// @param t wildcard term - /// @return new WildcardQuery instance - QueryPtr newWildcardQuery(const TermPtr& term); - - /// Factory method for generating query, given a set of clauses. By default creates a boolean query - /// composed of clauses passed in. - /// - /// Can be overridden by extending classes, to modify query being returned. - /// - /// @param clauses List that contains {@link BooleanClause} instances to join. - /// @return Resulting {@link Query} object. - virtual QueryPtr getBooleanQuery(Collection clauses); - - /// Factory method for generating query, given a set of clauses. By default creates a boolean query - /// composed of clauses passed in. - /// - /// Can be overridden by extending classes, to modify query being returned. - /// - /// @param clauses List that contains {@link BooleanClause} instances to join. - /// @param disableCoord true if coord scoring should be disabled. - /// @return Resulting {@link Query} object. - virtual QueryPtr getBooleanQuery(Collection clauses, bool disableCoord); - - /// Factory method for generating a query. Called when parser parses an input term token that contains - /// one or more wildcard characters (? and *), but is not a prefix term token (one that has just a - /// single * character at the end) - /// - /// Depending on settings, prefix term may be lower-cased automatically. It will not go through the - /// default Analyzer, however, since normal Analyzers are unlikely to work properly with wildcard - /// templates. - /// - /// Can be overridden by extending classes, to provide custom handling for wildcard queries, which may - /// be necessary due to missing analyzer calls. - /// - /// @param field Name of the field query will use. - /// @param termStr Term token that contains one or more wild card characters (? or *), but is not simple - /// prefix term - /// @return Resulting {@link Query} built for the term - virtual QueryPtr getWildcardQuery(const String& field, const String& termStr); - - /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser - /// parses an input term token that uses prefix notation; that is, contains a single '*' wildcard - /// character as its last character. Since this is a special case of generic wildcard term, and such - /// a query can be optimized easily, this usually results in a different query object. - /// - /// Depending on settings, a prefix term may be lower-cased automatically. It will not go through the - /// default Analyzer, however, since normal Analyzers are unlikely to work properly with wildcard templates. - /// - /// Can be overridden by extending classes, to provide custom handling for wild card queries, which may be - /// necessary due to missing analyzer calls. - /// - /// @param field Name of the field query will use. - /// @param termStr Term token to use for building term for the query (without trailing '*' character) - /// @return Resulting {@link Query} built for the term - virtual QueryPtr getPrefixQuery(const String& field, const String& termStr); - - /// Factory method for generating a query (similar to {@link #getWildcardQuery}). Called when parser - /// parses an input term token that has the fuzzy suffix (~) appended. - /// - /// @param field Name of the field query will use. - /// @param termStr Term token to use for building term for the query - /// @return Resulting {@link Query} built for the term - virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity); - - /// Returns a String where the escape char has been removed, or kept only once if there was a double - /// escape. Supports escaped unicode characters, eg. translates \\u0041 to A. - String discardEscapeChar(const String& input); - - /// Returns the numeric value of the hexadecimal character - static int32_t hexToInt(wchar_t c); - - /// Returns a String where those characters that QueryParser expects to be escaped are escaped by - /// a preceding \. - static String escape(const String& s); - - bool jj_2_1(int32_t xla); - bool jj_3R_2(); - bool jj_3_1(); - bool jj_3R_3(); - - QueryParserTokenPtr jj_consume_token(int32_t kind); - bool jj_scan_token(int32_t kind); - int32_t jj_ntk(); - void jj_add_error_token(int32_t kind, int32_t pos); - void jj_rescan_token(); - void jj_save(int32_t index, int32_t xla); - }; } #endif diff --git a/include/QueryParserCharStream.h b/include/QueryParserCharStream.h index 8df69a47..771e36bc 100644 --- a/include/QueryParserCharStream.h +++ b/include/QueryParserCharStream.h @@ -9,75 +9,75 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This interface describes a character stream that maintains line and column number positions of - /// the characters. It also has the capability to backup the stream to some extent. An implementation - /// of this interface is used in the QueryParserTokenManager. - /// - /// All the methods except backup can be implemented in any fashion. backup needs to be implemented - /// correctly for the correct operation of the lexer. Rest of the methods are all used to get information - /// like line number, column number and the String that constitutes a token and are not used by the lexer. - /// Hence their implementation won't affect the generated lexer's operation. - class LPPAPI QueryParserCharStream - { - public: - LUCENE_INTERFACE(QueryParserCharStream); - - public: - /// Returns the next character from the selected input. The method of selecting the input is the - /// responsibility of the class implementing this interface. - virtual wchar_t readChar() = 0; - - /// Returns the column position of the character last read. - /// @deprecated - /// @see #getEndColumn - virtual int32_t getColumn() = 0; - - /// Returns the line number of the character last read. - /// @deprecated - /// @see #getEndLine - virtual int32_t getLine() = 0; - - /// Returns the column number of the last character for current token (being matched after the last - /// call to BeginToken). - virtual int32_t getEndColumn() = 0; - - /// Returns the line number of the last character for current token (being matched after the last call - /// to BeginToken). - virtual int32_t getEndLine() = 0; - - /// Returns the column number of the first character for current token (being matched after the last - /// call to BeginToken). - virtual int32_t getBeginColumn() = 0; - - /// Returns the line number of the first character for current token (being matched after the last call - /// to BeginToken). - virtual int32_t getBeginLine() = 0; - - /// Backs up the input stream by amount steps. Lexer calls this method if it had already read some - /// characters, but could not use them to match a (longer) token. So, they will be used again as the - /// prefix of the next token and it is the implementation's's responsibility to do this right. - virtual void backup(int32_t amount) = 0; - - /// Returns the next character that marks the beginning of the next token. All characters must remain - /// in the buffer between two successive calls to this method to implement backup correctly. - virtual wchar_t BeginToken() = 0; - - /// Returns a string made up of characters from the marked token beginning to the current buffer position. - /// Implementations have the choice of returning anything that they want to. For example, for efficiency, - /// one might decide to just return null, which is a valid implementation. - virtual String GetImage() = 0; - - /// Returns an array of characters that make up the suffix of length for the currently matched token. - /// This is used to build up the matched string for use in actions in the case of MORE. - virtual CharArray GetSuffix(int32_t length) = 0; - - /// The lexer calls this function to indicate that it is done with the stream and hence implementations - /// can free any resources held by this class. Again, the body of this function can be just empty and it - /// will not affect the lexer's operation. - virtual void Done() = 0; - }; +namespace Lucene { + +/// This interface describes a character stream that maintains line and column number positions of +/// the characters. It also has the capability to backup the stream to some extent. An implementation +/// of this interface is used in the QueryParserTokenManager. +/// +/// All the methods except backup can be implemented in any fashion. backup needs to be implemented +/// correctly for the correct operation of the lexer. Rest of the methods are all used to get information +/// like line number, column number and the String that constitutes a token and are not used by the lexer. +/// Hence their implementation won't affect the generated lexer's operation. +class LPPAPI QueryParserCharStream { +public: + LUCENE_INTERFACE(QueryParserCharStream); + +public: + /// Returns the next character from the selected input. The method of selecting the input is the + /// responsibility of the class implementing this interface. + virtual wchar_t readChar() = 0; + + /// Returns the column position of the character last read. + /// @deprecated + /// @see #getEndColumn + virtual int32_t getColumn() = 0; + + /// Returns the line number of the character last read. + /// @deprecated + /// @see #getEndLine + virtual int32_t getLine() = 0; + + /// Returns the column number of the last character for current token (being matched after the last + /// call to BeginToken). + virtual int32_t getEndColumn() = 0; + + /// Returns the line number of the last character for current token (being matched after the last call + /// to BeginToken). + virtual int32_t getEndLine() = 0; + + /// Returns the column number of the first character for current token (being matched after the last + /// call to BeginToken). + virtual int32_t getBeginColumn() = 0; + + /// Returns the line number of the first character for current token (being matched after the last call + /// to BeginToken). + virtual int32_t getBeginLine() = 0; + + /// Backs up the input stream by amount steps. Lexer calls this method if it had already read some + /// characters, but could not use them to match a (longer) token. So, they will be used again as the + /// prefix of the next token and it is the implementation's's responsibility to do this right. + virtual void backup(int32_t amount) = 0; + + /// Returns the next character that marks the beginning of the next token. All characters must remain + /// in the buffer between two successive calls to this method to implement backup correctly. + virtual wchar_t BeginToken() = 0; + + /// Returns a string made up of characters from the marked token beginning to the current buffer position. + /// Implementations have the choice of returning anything that they want to. For example, for efficiency, + /// one might decide to just return null, which is a valid implementation. + virtual String GetImage() = 0; + + /// Returns an array of characters that make up the suffix of length for the currently matched token. + /// This is used to build up the matched string for use in actions in the case of MORE. + virtual CharArray GetSuffix(int32_t length) = 0; + + /// The lexer calls this function to indicate that it is done with the stream and hence implementations + /// can free any resources held by this class. Again, the body of this function can be just empty and it + /// will not affect the lexer's operation. + virtual void Done() = 0; +}; + } #endif diff --git a/include/QueryParserConstants.h b/include/QueryParserConstants.h index db65e916..c911c915 100644 --- a/include/QueryParserConstants.h +++ b/include/QueryParserConstants.h @@ -9,71 +9,69 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Token literal values and constants. - class LPPAPI QueryParserConstants - { - protected: - QueryParserConstants(); +namespace Lucene { - public: - virtual ~QueryParserConstants(); - LUCENE_INTERFACE(QueryParserConstants); +/// Token literal values and constants. +class LPPAPI QueryParserConstants { +protected: + QueryParserConstants(); - public: - enum RegularExpressionId - { - _EOF = 0, - _NUM_CHAR = 1, - _ESCAPED_CHAR = 2, - _TERM_START_CHAR = 3, - _TERM_CHAR = 4, - _WHITESPACE = 5, - _QUOTED_CHAR = 6, - AND = 8, - OR = 9, - NOT = 10, - PLUS = 11, - MINUS = 12, - LPAREN = 13, - RPAREN = 14, - COLON = 15, - STAR = 16, - CARAT = 17, - QUOTED = 18, - TERM = 19, - FUZZY_SLOP = 20, - PREFIXTERM = 21, - WILDTERM = 22, - RANGEIN_START = 23, - RANGEEX_START = 24, - NUMBER = 25, - RANGEIN_TO = 26, - RANGEIN_END = 27, - RANGEIN_QUOTED = 28, - RANGEIN_GOOP = 29, - RANGEEX_TO = 30, - RANGEEX_END = 31, - RANGEEX_QUOTED = 32, - RANGEEX_GOOP = 33 - }; +public: + virtual ~QueryParserConstants(); + LUCENE_INTERFACE(QueryParserConstants); - enum LexicalState - { - Boost = 0, - RangeEx = 1, - RangeIn = 2, - DEFAULT = 3 - }; - - /// Literal token values. - static Collection tokenImage; +public: + enum RegularExpressionId { + _EOF = 0, + _NUM_CHAR = 1, + _ESCAPED_CHAR = 2, + _TERM_START_CHAR = 3, + _TERM_CHAR = 4, + _WHITESPACE = 5, + _QUOTED_CHAR = 6, + AND = 8, + OR = 9, + NOT = 10, + PLUS = 11, + MINUS = 12, + LPAREN = 13, + RPAREN = 14, + COLON = 15, + STAR = 16, + CARAT = 17, + QUOTED = 18, + TERM = 19, + FUZZY_SLOP = 20, + PREFIXTERM = 21, + WILDTERM = 22, + RANGEIN_START = 23, + RANGEEX_START = 24, + NUMBER = 25, + RANGEIN_TO = 26, + RANGEIN_END = 27, + RANGEIN_QUOTED = 28, + RANGEIN_GOOP = 29, + RANGEEX_TO = 30, + RANGEEX_END = 31, + RANGEEX_QUOTED = 32, + RANGEEX_GOOP = 33 + }; - protected: - /// Literal token values. - static const wchar_t* _tokenImage[]; + enum LexicalState { + Boost = 0, + RangeEx = 1, + RangeIn = 2, + DEFAULT = 3 }; + + /// Literal token values. + static Collection tokenImage; + +protected: + /// Literal token values. + static const wchar_t* _tokenImage[]; +}; + } #endif diff --git a/include/QueryParserToken.h b/include/QueryParserToken.h index aab2c1b5..568a9203 100644 --- a/include/QueryParserToken.h +++ b/include/QueryParserToken.h @@ -9,62 +9,62 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Describes the input token stream. - class LPPAPI QueryParserToken : public LuceneObject - { - public: - /// Constructs a new token for the specified Image and Kind. - QueryParserToken(int32_t kind = 0, const String& image = EmptyString); - - virtual ~QueryParserToken(); - - LUCENE_CLASS(QueryParserToken); - - public: - /// An integer that describes the kind of this token. - int32_t kind; - - /// The line number of the first character of this Token. - int32_t beginLine; - - /// The column number of the first character of this Token. - int32_t beginColumn; - - /// The line number of the last character of this Token. - int32_t endLine; - - /// The column number of the last character of this Token. - int32_t endColumn; - - /// The string image of the token. - String image; - - /// A reference to the next regular (non-special) token from the input stream. If this is the last - /// token from the input stream, or if the token manager has not read tokens beyond this one, this - /// field is set to null. This is true only if this token is also a regular token. Otherwise, see - /// below for a description of the contents of this field. - QueryParserTokenPtr next; - - /// This field is used to access special tokens that occur prior to this token, but after the - /// immediately preceding regular (non-special) token. If there are no such special tokens, this - /// field is set to null. When there are more than one such special token, this field refers to the - /// last of these special tokens, which in turn refers to the next previous special token through - /// its specialToken field, and so on until the first special token (whose specialToken field is - /// null). The next fields of special tokens refer to other special tokens that immediately follow - /// it (without an intervening regular token). If there is no such token, this field is null. - QueryParserTokenPtr specialToken; - - public: - /// Returns the image. - virtual String toString(); - - /// Returns a new Token object, by default. However, if you want, you can create and return subclass - /// objects based on the value of ofKind. Simply add the cases to the switch for all those special - /// cases. - static QueryParserTokenPtr newToken(int32_t ofKind, const String& image = EmptyString); - }; +namespace Lucene { + +/// Describes the input token stream. +class LPPAPI QueryParserToken : public LuceneObject { +public: + /// Constructs a new token for the specified Image and Kind. + QueryParserToken(int32_t kind = 0, const String& image = EmptyString); + + virtual ~QueryParserToken(); + + LUCENE_CLASS(QueryParserToken); + +public: + /// An integer that describes the kind of this token. + int32_t kind; + + /// The line number of the first character of this Token. + int32_t beginLine; + + /// The column number of the first character of this Token. + int32_t beginColumn; + + /// The line number of the last character of this Token. + int32_t endLine; + + /// The column number of the last character of this Token. + int32_t endColumn; + + /// The string image of the token. + String image; + + /// A reference to the next regular (non-special) token from the input stream. If this is the last + /// token from the input stream, or if the token manager has not read tokens beyond this one, this + /// field is set to null. This is true only if this token is also a regular token. Otherwise, see + /// below for a description of the contents of this field. + QueryParserTokenPtr next; + + /// This field is used to access special tokens that occur prior to this token, but after the + /// immediately preceding regular (non-special) token. If there are no such special tokens, this + /// field is set to null. When there are more than one such special token, this field refers to the + /// last of these special tokens, which in turn refers to the next previous special token through + /// its specialToken field, and so on until the first special token (whose specialToken field is + /// null). The next fields of special tokens refer to other special tokens that immediately follow + /// it (without an intervening regular token). If there is no such token, this field is null. + QueryParserTokenPtr specialToken; + +public: + /// Returns the image. + virtual String toString(); + + /// Returns a new Token object, by default. However, if you want, you can create and return subclass + /// objects based on the value of ofKind. Simply add the cases to the switch for all those special + /// cases. + static QueryParserTokenPtr newToken(int32_t ofKind, const String& image = EmptyString); +}; + } #endif diff --git a/include/QueryParserTokenManager.h b/include/QueryParserTokenManager.h index 726fb419..397f66dc 100644 --- a/include/QueryParserTokenManager.h +++ b/include/QueryParserTokenManager.h @@ -9,103 +9,103 @@ #include "QueryParserConstants.h" -namespace Lucene -{ - /// Token Manager. - class LPPAPI QueryParserTokenManager : public QueryParserConstants, public LuceneObject - { - public: - QueryParserTokenManager(const QueryParserCharStreamPtr& stream); - QueryParserTokenManager(const QueryParserCharStreamPtr& stream, int32_t lexState); - - virtual ~QueryParserTokenManager(); - - LUCENE_CLASS(QueryParserTokenManager); - - public: - /// Debug output. - InfoStreamPtr debugStream; - - protected: - static const int64_t jjbitVec0[]; - static const int64_t jjbitVec1[]; - static const int64_t jjbitVec3[]; - static const int64_t jjbitVec4[]; - static const int32_t jjnextStates[]; - - /// Token literal values. - static const wchar_t* jjstrLiteralImages[]; - - /// Lexer state names. - static const wchar_t* lexStateNames[]; - - /// Lex State array. - static const int32_t jjnewLexState[]; - static const int64_t jjtoToken[]; - static const int64_t jjtoSkip[]; - - int32_t curLexState; - int32_t defaultLexState; - int32_t jjnewStateCnt; - int32_t jjround; - int32_t jjmatchedPos; - int32_t jjmatchedKind; - - QueryParserCharStreamPtr input_stream; - IntArray jjrounds; - IntArray jjstateSet; - wchar_t curChar; - - public: - /// Set debug output. - void setDebugStream(const InfoStreamPtr& debugStream); - - /// Reinitialise parser. - void ReInit(const QueryParserCharStreamPtr& stream); - - /// Reinitialise parser. - void ReInit(const QueryParserCharStreamPtr& stream, int32_t lexState); - - /// Switch to specified lex state. - void SwitchTo(int32_t lexState); - - /// Get the next Token. - QueryParserTokenPtr getNextToken(); - - protected: - int32_t jjStopStringLiteralDfa_3(int32_t pos, int64_t active0); - int32_t jjStartNfa_3(int32_t pos, int64_t active0); - int32_t jjStopAtPos(int32_t pos, int32_t kind); - int32_t jjMoveStringLiteralDfa0_3(); - int32_t jjStartNfaWithStates_3(int32_t pos, int32_t kind, int32_t state); - int32_t jjMoveNfa_3(int32_t startState, int32_t curPos); - int32_t jjStopStringLiteralDfa_1(int32_t pos, int64_t active0); - int32_t jjStartNfa_1(int32_t pos, int64_t active0); - int32_t jjMoveStringLiteralDfa0_1(); - int32_t jjMoveStringLiteralDfa1_1(int64_t active0); - int32_t jjStartNfaWithStates_1(int32_t pos, int32_t kind, int32_t state); - int32_t jjMoveNfa_1(int32_t startState, int32_t curPos); - int32_t jjMoveStringLiteralDfa0_0(); - int32_t jjMoveNfa_0(int32_t startState, int32_t curPos); - int32_t jjStopStringLiteralDfa_2(int32_t pos, int64_t active0); - int32_t jjStartNfa_2(int32_t pos, int64_t active0); - int32_t jjMoveStringLiteralDfa0_2(); - int32_t jjMoveStringLiteralDfa1_2(int64_t active0); - int32_t jjStartNfaWithStates_2(int32_t pos, int32_t kind, int32_t state); - int32_t jjMoveNfa_2(int32_t startState, int32_t curPos); - - static bool jjCanMove_0(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); - static bool jjCanMove_1(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); - static bool jjCanMove_2(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); - - void ReInitRounds(); - QueryParserTokenPtr jjFillToken(); - - void jjCheckNAdd(int32_t state); - void jjAddStates(int32_t start, int32_t end); - void jjCheckNAddTwoStates(int32_t state1, int32_t state2); - void jjCheckNAddStates(int32_t start, int32_t end); - }; +namespace Lucene { + +/// Token Manager. +class LPPAPI QueryParserTokenManager : public QueryParserConstants, public LuceneObject { +public: + QueryParserTokenManager(const QueryParserCharStreamPtr& stream); + QueryParserTokenManager(const QueryParserCharStreamPtr& stream, int32_t lexState); + + virtual ~QueryParserTokenManager(); + + LUCENE_CLASS(QueryParserTokenManager); + +public: + /// Debug output. + InfoStreamPtr debugStream; + +protected: + static const int64_t jjbitVec0[]; + static const int64_t jjbitVec1[]; + static const int64_t jjbitVec3[]; + static const int64_t jjbitVec4[]; + static const int32_t jjnextStates[]; + + /// Token literal values. + static const wchar_t* jjstrLiteralImages[]; + + /// Lexer state names. + static const wchar_t* lexStateNames[]; + + /// Lex State array. + static const int32_t jjnewLexState[]; + static const int64_t jjtoToken[]; + static const int64_t jjtoSkip[]; + + int32_t curLexState; + int32_t defaultLexState; + int32_t jjnewStateCnt; + int32_t jjround; + int32_t jjmatchedPos; + int32_t jjmatchedKind; + + QueryParserCharStreamPtr input_stream; + IntArray jjrounds; + IntArray jjstateSet; + wchar_t curChar; + +public: + /// Set debug output. + void setDebugStream(const InfoStreamPtr& debugStream); + + /// Reinitialise parser. + void ReInit(const QueryParserCharStreamPtr& stream); + + /// Reinitialise parser. + void ReInit(const QueryParserCharStreamPtr& stream, int32_t lexState); + + /// Switch to specified lex state. + void SwitchTo(int32_t lexState); + + /// Get the next Token. + QueryParserTokenPtr getNextToken(); + +protected: + int32_t jjStopStringLiteralDfa_3(int32_t pos, int64_t active0); + int32_t jjStartNfa_3(int32_t pos, int64_t active0); + int32_t jjStopAtPos(int32_t pos, int32_t kind); + int32_t jjMoveStringLiteralDfa0_3(); + int32_t jjStartNfaWithStates_3(int32_t pos, int32_t kind, int32_t state); + int32_t jjMoveNfa_3(int32_t startState, int32_t curPos); + int32_t jjStopStringLiteralDfa_1(int32_t pos, int64_t active0); + int32_t jjStartNfa_1(int32_t pos, int64_t active0); + int32_t jjMoveStringLiteralDfa0_1(); + int32_t jjMoveStringLiteralDfa1_1(int64_t active0); + int32_t jjStartNfaWithStates_1(int32_t pos, int32_t kind, int32_t state); + int32_t jjMoveNfa_1(int32_t startState, int32_t curPos); + int32_t jjMoveStringLiteralDfa0_0(); + int32_t jjMoveNfa_0(int32_t startState, int32_t curPos); + int32_t jjStopStringLiteralDfa_2(int32_t pos, int64_t active0); + int32_t jjStartNfa_2(int32_t pos, int64_t active0); + int32_t jjMoveStringLiteralDfa0_2(); + int32_t jjMoveStringLiteralDfa1_2(int64_t active0); + int32_t jjStartNfaWithStates_2(int32_t pos, int32_t kind, int32_t state); + int32_t jjMoveNfa_2(int32_t startState, int32_t curPos); + + static bool jjCanMove_0(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); + static bool jjCanMove_1(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); + static bool jjCanMove_2(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2); + + void ReInitRounds(); + QueryParserTokenPtr jjFillToken(); + + void jjCheckNAdd(int32_t state); + void jjAddStates(int32_t start, int32_t end); + void jjCheckNAddTwoStates(int32_t state1, int32_t state2); + void jjCheckNAddStates(int32_t start, int32_t end); +}; + } #endif diff --git a/include/QueryTermVector.h b/include/QueryTermVector.h index 929de7f1..d482b998 100644 --- a/include/QueryTermVector.h +++ b/include/QueryTermVector.h @@ -9,35 +9,35 @@ #include "TermFreqVector.h" -namespace Lucene -{ - class LPPAPI QueryTermVector : public TermFreqVector, public LuceneObject - { - public: - /// @param queryTerms The original list of terms from the query, can contain duplicates - QueryTermVector(Collection queryTerms); - QueryTermVector(const String& queryString, const AnalyzerPtr& analyzer); - - virtual ~QueryTermVector(); - - LUCENE_CLASS(QueryTermVector); - - protected: - Collection terms; - Collection termFreqs; - - public: - virtual String toString(); - - int32_t size(); - Collection getTerms(); - Collection getTermFrequencies(); - int32_t indexOf(const String& term); - Collection indexesOf(Collection terms, int32_t start, int32_t length); - - protected: - void processTerms(Collection queryTerms); - }; +namespace Lucene { + +class LPPAPI QueryTermVector : public TermFreqVector, public LuceneObject { +public: + /// @param queryTerms The original list of terms from the query, can contain duplicates + QueryTermVector(Collection queryTerms); + QueryTermVector(const String& queryString, const AnalyzerPtr& analyzer); + + virtual ~QueryTermVector(); + + LUCENE_CLASS(QueryTermVector); + +protected: + Collection terms; + Collection termFreqs; + +public: + virtual String toString(); + + int32_t size(); + Collection getTerms(); + Collection getTermFrequencies(); + int32_t indexOf(const String& term); + Collection indexesOf(Collection terms, int32_t start, int32_t length); + +protected: + void processTerms(Collection queryTerms); +}; + } #endif diff --git a/include/QueryWrapperFilter.h b/include/QueryWrapperFilter.h index 8281ecba..b898a9ea 100644 --- a/include/QueryWrapperFilter.h +++ b/include/QueryWrapperFilter.h @@ -9,33 +9,33 @@ #include "Filter.h" -namespace Lucene -{ - /// Constrains search results to only match those which also match a provided query. - /// - /// This could be used, for example, with a {@link TermRangeQuery} on a suitably formatted date field to - /// implement date filtering. One could re-use a single QueryFilter that matches, eg., only documents - /// modified within the last week. The QueryFilter and TermRangeQuery would only need to be reconstructed - /// once per day. - class LPPAPI QueryWrapperFilter : public Filter - { - public: - /// Constructs a filter which only matches documents matching query. - QueryWrapperFilter(const QueryPtr& query); - - virtual ~QueryWrapperFilter(); - - LUCENE_CLASS(QueryWrapperFilter); - - protected: - QueryPtr query; - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); - virtual String toString(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// Constrains search results to only match those which also match a provided query. +/// +/// This could be used, for example, with a {@link TermRangeQuery} on a suitably formatted date field to +/// implement date filtering. One could re-use a single QueryFilter that matches, eg., only documents +/// modified within the last week. The QueryFilter and TermRangeQuery would only need to be reconstructed +/// once per day. +class LPPAPI QueryWrapperFilter : public Filter { +public: + /// Constructs a filter which only matches documents matching query. + QueryWrapperFilter(const QueryPtr& query); + + virtual ~QueryWrapperFilter(); + + LUCENE_CLASS(QueryWrapperFilter); + +protected: + QueryPtr query; + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + virtual String toString(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/RAMDirectory.h b/include/RAMDirectory.h index e9b9dc81..6e0dc7f7 100644 --- a/include/RAMDirectory.h +++ b/include/RAMDirectory.h @@ -9,78 +9,78 @@ #include "Directory.h" -namespace Lucene -{ - /// A memory-resident {@link Directory} implementation. Locking implementation is by default the - /// {@link SingleInstanceLockFactory} but can be changed with {@link #setLockFactory}. - /// Lock acquisition sequence: RAMDirectory, then RAMFile - class LPPAPI RAMDirectory : public Directory - { - public: - /// Constructs an empty {@link Directory}. - RAMDirectory(); - - /// Creates a new RAMDirectory instance from a different Directory implementation. - /// This can be used to load a disk-based index into memory. - /// - /// This should be used only with indices that can fit into memory. - /// - /// Note that the resulting RAMDirectory instance is fully independent from the - /// original Directory (it is a complete copy). Any subsequent changes to the - /// original Directory will not be visible in the RAMDirectory instance. - /// @param dir a Directory value - RAMDirectory(const DirectoryPtr& dir); - - RAMDirectory(const DirectoryPtr& dir, bool closeDir); - - virtual ~RAMDirectory(); - - LUCENE_CLASS(RAMDirectory); - - INTERNAL: - int64_t _sizeInBytes; - MapStringRAMFile fileMap; - - protected: - DirectoryWeakPtr _dirSource; - bool copyDirectory; - bool closeDir; - - public: - virtual void initialize(); - - /// Returns an array of strings, one for each file in the directory. - virtual HashSet listAll(); - - /// Returns true if a file with the given name exists. - virtual bool fileExists(const String& name); - - /// Returns the time the named file was last modified. - virtual uint64_t fileModified(const String& name); - - /// Set the modified time of an existing file to now. - virtual void touchFile(const String& name); - - /// Returns the length of a file in the directory. - virtual int64_t fileLength(const String& name); - - /// Return total size in bytes of all files in this directory. - /// This is currently quantized to RAMOutputStream::BUFFER_SIZE. - int64_t sizeInBytes(); - - /// Removes an existing file in the directory. - virtual void deleteFile(const String& name); - - /// Creates a new, empty file in the directory with the given name. - /// Returns a stream writing this file. - virtual IndexOutputPtr createOutput(const String& name); - - /// Returns a stream reading an existing file. - virtual IndexInputPtr openInput(const String& name); - - /// Closes the store. - virtual void close(); - }; +namespace Lucene { + +/// A memory-resident {@link Directory} implementation. Locking implementation is by default the +/// {@link SingleInstanceLockFactory} but can be changed with {@link #setLockFactory}. +/// Lock acquisition sequence: RAMDirectory, then RAMFile +class LPPAPI RAMDirectory : public Directory { +public: + /// Constructs an empty {@link Directory}. + RAMDirectory(); + + /// Creates a new RAMDirectory instance from a different Directory implementation. + /// This can be used to load a disk-based index into memory. + /// + /// This should be used only with indices that can fit into memory. + /// + /// Note that the resulting RAMDirectory instance is fully independent from the + /// original Directory (it is a complete copy). Any subsequent changes to the + /// original Directory will not be visible in the RAMDirectory instance. + /// @param dir a Directory value + RAMDirectory(const DirectoryPtr& dir); + + RAMDirectory(const DirectoryPtr& dir, bool closeDir); + + virtual ~RAMDirectory(); + + LUCENE_CLASS(RAMDirectory); + +INTERNAL: + int64_t _sizeInBytes; + MapStringRAMFile fileMap; + +protected: + DirectoryWeakPtr _dirSource; + bool copyDirectory; + bool closeDir; + +public: + virtual void initialize(); + + /// Returns an array of strings, one for each file in the directory. + virtual HashSet listAll(); + + /// Returns true if a file with the given name exists. + virtual bool fileExists(const String& name); + + /// Returns the time the named file was last modified. + virtual uint64_t fileModified(const String& name); + + /// Set the modified time of an existing file to now. + virtual void touchFile(const String& name); + + /// Returns the length of a file in the directory. + virtual int64_t fileLength(const String& name); + + /// Return total size in bytes of all files in this directory. + /// This is currently quantized to RAMOutputStream::BUFFER_SIZE. + int64_t sizeInBytes(); + + /// Removes an existing file in the directory. + virtual void deleteFile(const String& name); + + /// Creates a new, empty file in the directory with the given name. + /// Returns a stream writing this file. + virtual IndexOutputPtr createOutput(const String& name); + + /// Returns a stream reading an existing file. + virtual IndexInputPtr openInput(const String& name); + + /// Closes the store. + virtual void close(); +}; + } #endif diff --git a/include/RAMFile.h b/include/RAMFile.h index dd14a466..798ba5ae 100644 --- a/include/RAMFile.h +++ b/include/RAMFile.h @@ -9,49 +9,49 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// File used as buffer in RAMDirectory - class LPPAPI RAMFile : public LuceneObject - { - public: - RAMFile(); // File used as buffer, in no RAMDirectory - RAMFile(const RAMDirectoryPtr& directory); - virtual ~RAMFile(); +namespace Lucene { - LUCENE_CLASS(RAMFile); +/// File used as buffer in RAMDirectory +class LPPAPI RAMFile : public LuceneObject { +public: + RAMFile(); // File used as buffer, in no RAMDirectory + RAMFile(const RAMDirectoryPtr& directory); + virtual ~RAMFile(); - INTERNAL: - int64_t length; - RAMDirectoryWeakPtr _directory; + LUCENE_CLASS(RAMFile); - protected: - Collection buffers; +INTERNAL: + int64_t length; + RAMDirectoryWeakPtr _directory; - int64_t sizeInBytes; +protected: + Collection buffers; - /// This is publicly modifiable via Directory.touchFile(), so direct access not supported - int64_t lastModified; + int64_t sizeInBytes; - public: - /// For non-stream access from thread that might be concurrent with writing. - int64_t getLength(); - void setLength(int64_t length); + /// This is publicly modifiable via Directory.touchFile(), so direct access not supported + int64_t lastModified; - /// For non-stream access from thread that might be concurrent with writing - int64_t getLastModified(); - void setLastModified(int64_t lastModified); +public: + /// For non-stream access from thread that might be concurrent with writing. + int64_t getLength(); + void setLength(int64_t length); - int64_t getSizeInBytes(); + /// For non-stream access from thread that might be concurrent with writing + int64_t getLastModified(); + void setLastModified(int64_t lastModified); - ByteArray addBuffer(int32_t size); - ByteArray getBuffer(int32_t index); - int32_t numBuffers(); + int64_t getSizeInBytes(); + + ByteArray addBuffer(int32_t size); + ByteArray getBuffer(int32_t index); + int32_t numBuffers(); + +protected: + /// Allocate a new buffer. Subclasses can allocate differently. + virtual ByteArray newBuffer(int32_t size); +}; - protected: - /// Allocate a new buffer. Subclasses can allocate differently. - virtual ByteArray newBuffer(int32_t size); - }; } #endif diff --git a/include/RAMInputStream.h b/include/RAMInputStream.h index 169f0d18..a16342ab 100644 --- a/include/RAMInputStream.h +++ b/include/RAMInputStream.h @@ -9,62 +9,62 @@ #include "IndexInput.h" -namespace Lucene -{ - /// A memory-resident {@link IndexInput} implementation. - class RAMInputStream : public IndexInput - { - public: - RAMInputStream(); - RAMInputStream(const RAMFilePtr& f); - virtual ~RAMInputStream(); - - LUCENE_CLASS(RAMInputStream); - - public: - static const int32_t BUFFER_SIZE; - - protected: - RAMFilePtr file; - int64_t _length; - ByteArray currentBuffer; - int32_t currentBufferIndex; - int32_t bufferPosition; - int64_t bufferStart; - int32_t bufferLength; - - public: - /// Closes the stream to further operations. - virtual void close(); - - /// The number of bytes in the file. - virtual int64_t length(); - - /// Reads and returns a single byte. - /// @see IndexOutput#writeByte(uint8_t) - virtual uint8_t readByte(); - - /// Reads a specified number of bytes into an array at the specified offset. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - /// @see IndexOutput#writeBytes(const uint8_t*,int) - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - - /// Returns the current position in this file, where the next read will occur. - /// @see #seek(int64_t) - virtual int64_t getFilePointer(); - - /// Sets current position in this file, where the next read will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos); - - /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - protected: - void switchCurrentBuffer(bool enforceEOF); - }; +namespace Lucene { + +/// A memory-resident {@link IndexInput} implementation. +class RAMInputStream : public IndexInput { +public: + RAMInputStream(); + RAMInputStream(const RAMFilePtr& f); + virtual ~RAMInputStream(); + + LUCENE_CLASS(RAMInputStream); + +public: + static const int32_t BUFFER_SIZE; + +protected: + RAMFilePtr file; + int64_t _length; + ByteArray currentBuffer; + int32_t currentBufferIndex; + int32_t bufferPosition; + int64_t bufferStart; + int32_t bufferLength; + +public: + /// Closes the stream to further operations. + virtual void close(); + + /// The number of bytes in the file. + virtual int64_t length(); + + /// Reads and returns a single byte. + /// @see IndexOutput#writeByte(uint8_t) + virtual uint8_t readByte(); + + /// Reads a specified number of bytes into an array at the specified offset. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + /// @see IndexOutput#writeBytes(const uint8_t*,int) + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); + + /// Returns the current position in this file, where the next read will occur. + /// @see #seek(int64_t) + virtual int64_t getFilePointer(); + + /// Sets current position in this file, where the next read will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos); + + /// Returns a clone of this stream. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + +protected: + void switchCurrentBuffer(bool enforceEOF); +}; + } #endif diff --git a/include/RAMOutputStream.h b/include/RAMOutputStream.h index d5479e57..26d25ed4 100644 --- a/include/RAMOutputStream.h +++ b/include/RAMOutputStream.h @@ -9,70 +9,70 @@ #include "IndexOutput.h" -namespace Lucene -{ - /// A memory-resident {@link IndexOutput} implementation. - class RAMOutputStream : public IndexOutput - { - public: - /// Construct an empty output buffer. - RAMOutputStream(); - RAMOutputStream(const RAMFilePtr& f); - virtual ~RAMOutputStream(); - - LUCENE_CLASS(RAMOutputStream); - - public: - static const int32_t BUFFER_SIZE; - - protected: - RAMFilePtr file; - ByteArray currentBuffer; - int32_t currentBufferIndex; - int32_t bufferPosition; - int64_t bufferStart; - int32_t bufferLength; - - public: - /// Copy the current contents of this buffer to the named output. - void writeTo(const IndexOutputPtr& out); - - /// Resets this to an empty file. - void reset(); - - /// Closes this stream to further operations. - virtual void close(); - - /// Sets current position in this file, where the next write will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos); - - /// The number of bytes in the file. - virtual int64_t length(); - - /// Writes a single byte. - /// @see IndexInput#readByte() - virtual void writeByte(uint8_t b); - - /// Writes an array of bytes. - /// @param b the bytes to write. - /// @param length the number of bytes to write. - /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) - virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - - /// Forces any buffered output to be written. - virtual void flush(); - - /// Returns the current position in this file, where the next write will occur. - virtual int64_t getFilePointer(); - - /// Returns byte usage of all buffers. - int64_t sizeInBytes(); - - protected: - void switchCurrentBuffer(); - void setFileLength(); - }; +namespace Lucene { + +/// A memory-resident {@link IndexOutput} implementation. +class RAMOutputStream : public IndexOutput { +public: + /// Construct an empty output buffer. + RAMOutputStream(); + RAMOutputStream(const RAMFilePtr& f); + virtual ~RAMOutputStream(); + + LUCENE_CLASS(RAMOutputStream); + +public: + static const int32_t BUFFER_SIZE; + +protected: + RAMFilePtr file; + ByteArray currentBuffer; + int32_t currentBufferIndex; + int32_t bufferPosition; + int64_t bufferStart; + int32_t bufferLength; + +public: + /// Copy the current contents of this buffer to the named output. + void writeTo(const IndexOutputPtr& out); + + /// Resets this to an empty file. + void reset(); + + /// Closes this stream to further operations. + virtual void close(); + + /// Sets current position in this file, where the next write will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos); + + /// The number of bytes in the file. + virtual int64_t length(); + + /// Writes a single byte. + /// @see IndexInput#readByte() + virtual void writeByte(uint8_t b); + + /// Writes an array of bytes. + /// @param b the bytes to write. + /// @param length the number of bytes to write. + /// @see IndexInput#readBytes(uint8_t*, int32_t, int32_t) + virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); + + /// Forces any buffered output to be written. + virtual void flush(); + + /// Returns the current position in this file, where the next write will occur. + virtual int64_t getFilePointer(); + + /// Returns byte usage of all buffers. + int64_t sizeInBytes(); + +protected: + void switchCurrentBuffer(); + void setFileLength(); +}; + } #endif diff --git a/include/Random.h b/include/Random.h index 0fc3031e..1488af80 100644 --- a/include/Random.h +++ b/include/Random.h @@ -9,28 +9,28 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Utility class to generate a stream of pseudorandom numbers. - class LPPAPI Random : public LuceneObject - { - public: - Random(); - Random(int64_t seed); - - virtual ~Random(); - - protected: - int64_t seed; - - public: - void setSeed(int64_t seed); - int32_t nextInt(int32_t limit = INT_MAX); - double nextDouble(); - - protected: - int32_t next(int32_t bits); - }; +namespace Lucene { + +/// Utility class to generate a stream of pseudorandom numbers. +class LPPAPI Random : public LuceneObject { +public: + Random(); + Random(int64_t seed); + + virtual ~Random(); + +protected: + int64_t seed; + +public: + void setSeed(int64_t seed); + int32_t nextInt(int32_t limit = INT_MAX); + double nextDouble(); + +protected: + int32_t next(int32_t bits); +}; + } #endif diff --git a/include/RawPostingList.h b/include/RawPostingList.h index 6440371d..76d9587b 100644 --- a/include/RawPostingList.h +++ b/include/RawPostingList.h @@ -9,28 +9,28 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This is the base class for an in-memory posting list, keyed by a Token. {@link TermsHash} maintains a - /// hash table holding one instance of this per unique Token. Consumers of TermsHash ({@link TermsHashConsumer}) - /// must subclass this class with its own concrete class. FreqProxTermsWriterPostingList is a private inner - /// class used for the freq/prox postings, and TermVectorsTermsWriterPostingList is a private inner class used - /// to hold TermVectors postings. - class RawPostingList : public LuceneObject - { - public: - RawPostingList(); - virtual ~RawPostingList(); - - LUCENE_CLASS(RawPostingList); - - public: - static const int32_t BYTES_SIZE; - - int32_t textStart; - int32_t intStart; - int32_t byteStart; - }; +namespace Lucene { + +/// This is the base class for an in-memory posting list, keyed by a Token. {@link TermsHash} maintains a +/// hash table holding one instance of this per unique Token. Consumers of TermsHash ({@link TermsHashConsumer}) +/// must subclass this class with its own concrete class. FreqProxTermsWriterPostingList is a private inner +/// class used for the freq/prox postings, and TermVectorsTermsWriterPostingList is a private inner class used +/// to hold TermVectors postings. +class RawPostingList : public LuceneObject { +public: + RawPostingList(); + virtual ~RawPostingList(); + + LUCENE_CLASS(RawPostingList); + +public: + static const int32_t BYTES_SIZE; + + int32_t textStart; + int32_t intStart; + int32_t byteStart; +}; + } #endif diff --git a/include/ReadOnlyDirectoryReader.h b/include/ReadOnlyDirectoryReader.h index 215635ce..241a1f0f 100644 --- a/include/ReadOnlyDirectoryReader.h +++ b/include/ReadOnlyDirectoryReader.h @@ -9,24 +9,24 @@ #include "DirectoryReader.h" -namespace Lucene -{ - class ReadOnlyDirectoryReader : public DirectoryReader - { - public: - ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor); - ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, - Collection oldStarts, MapStringByteArray oldNormsCache, bool doClone, int32_t termInfosIndexDivisor); - ReadOnlyDirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor); - virtual ~ReadOnlyDirectoryReader(); - - LUCENE_CLASS(ReadOnlyDirectoryReader); - - public: - /// Tries to acquire the WriteLock on this directory. this method is only valid if this - /// IndexReader is directory owner. - virtual void acquireWriteLock(); - }; +namespace Lucene { + +class ReadOnlyDirectoryReader : public DirectoryReader { +public: + ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor); + ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, + Collection oldStarts, MapStringByteArray oldNormsCache, bool doClone, int32_t termInfosIndexDivisor); + ReadOnlyDirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor); + virtual ~ReadOnlyDirectoryReader(); + + LUCENE_CLASS(ReadOnlyDirectoryReader); + +public: + /// Tries to acquire the WriteLock on this directory. this method is only valid if this + /// IndexReader is directory owner. + virtual void acquireWriteLock(); +}; + } #endif diff --git a/include/ReadOnlySegmentReader.h b/include/ReadOnlySegmentReader.h index 6df79c91..bd641e81 100644 --- a/include/ReadOnlySegmentReader.h +++ b/include/ReadOnlySegmentReader.h @@ -9,21 +9,21 @@ #include "SegmentReader.h" -namespace Lucene -{ - class ReadOnlySegmentReader : public SegmentReader - { - public: - virtual ~ReadOnlySegmentReader(); +namespace Lucene { - LUCENE_CLASS(ReadOnlySegmentReader); +class ReadOnlySegmentReader : public SegmentReader { +public: + virtual ~ReadOnlySegmentReader(); - public: - static void noWrite(); + LUCENE_CLASS(ReadOnlySegmentReader); + +public: + static void noWrite(); + + virtual void acquireWriteLock(); + virtual bool isDeleted(int32_t n); +}; - virtual void acquireWriteLock(); - virtual bool isDeleted(int32_t n); - }; } #endif diff --git a/include/Reader.h b/include/Reader.h index c8ca1c77..150a4f23 100644 --- a/include/Reader.h +++ b/include/Reader.h @@ -9,48 +9,48 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Abstract class for reading character streams. - class LPPAPI Reader : public LuceneObject - { - protected: - Reader(); +namespace Lucene { - public: - virtual ~Reader(); - LUCENE_CLASS(Reader); +/// Abstract class for reading character streams. +class LPPAPI Reader : public LuceneObject { +protected: + Reader(); - public: - static const int32_t READER_EOF; +public: + virtual ~Reader(); + LUCENE_CLASS(Reader); - /// Read a single character. - virtual int32_t read(); +public: + static const int32_t READER_EOF; - /// Read characters into a portion of an array. - virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length) = 0; + /// Read a single character. + virtual int32_t read(); - /// Skip characters. - virtual int64_t skip(int64_t n); + /// Read characters into a portion of an array. + virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length) = 0; - /// Close the stream. - virtual void close() = 0; + /// Skip characters. + virtual int64_t skip(int64_t n); - /// Tell whether this stream supports the mark() operation - virtual bool markSupported(); + /// Close the stream. + virtual void close() = 0; - /// Mark the present position in the stream. Subsequent calls to reset() will attempt to reposition the - /// stream to this point. - virtual void mark(int32_t readAheadLimit); + /// Tell whether this stream supports the mark() operation + virtual bool markSupported(); - /// Reset the stream. If the stream has been marked, then attempt to reposition it at the mark. If the stream - /// has not been marked, then attempt to reset it in some way appropriate to the particular stream, for example - /// by repositioning it to its starting point. - virtual void reset(); + /// Mark the present position in the stream. Subsequent calls to reset() will attempt to reposition the + /// stream to this point. + virtual void mark(int32_t readAheadLimit); + + /// Reset the stream. If the stream has been marked, then attempt to reposition it at the mark. If the stream + /// has not been marked, then attempt to reset it in some way appropriate to the particular stream, for example + /// by repositioning it to its starting point. + virtual void reset(); + + /// The number of bytes in the stream. + virtual int64_t length(); +}; - /// The number of bytes in the stream. - virtual int64_t length(); - }; } #endif diff --git a/include/ReaderUtil.h b/include/ReaderUtil.h index ccd762cf..97ddf36b 100644 --- a/include/ReaderUtil.h +++ b/include/ReaderUtil.h @@ -9,37 +9,37 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Common util methods for dealing with {@link IndexReader}s. - class LPPAPI ReaderUtil : public LuceneObject - { - public: - virtual ~ReaderUtil(); - LUCENE_CLASS(ReaderUtil); - - public: - /// Gathers sub-readers from reader into a List. - static void gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader); - - /// Returns sub IndexReader that contains the given document id. - /// - /// @param doc Id of document - /// @param reader Parent reader - /// @return Sub reader of parent which contains the specified doc id - static IndexReaderPtr subReader(int32_t doc, const IndexReaderPtr& reader); - - /// Returns sub-reader subIndex from reader. - /// - /// @param reader Parent reader - /// @param subIndex Index of desired sub reader - /// @return The subreader at subIndex - static IndexReaderPtr subReader(const IndexReaderPtr& reader, int32_t subIndex); - - /// Returns index of the searcher/reader for document n in the array used to construct this - /// searcher/reader. - static int32_t subIndex(int32_t n, Collection docStarts); - }; +namespace Lucene { + +/// Common util methods for dealing with {@link IndexReader}s. +class LPPAPI ReaderUtil : public LuceneObject { +public: + virtual ~ReaderUtil(); + LUCENE_CLASS(ReaderUtil); + +public: + /// Gathers sub-readers from reader into a List. + static void gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader); + + /// Returns sub IndexReader that contains the given document id. + /// + /// @param doc Id of document + /// @param reader Parent reader + /// @return Sub reader of parent which contains the specified doc id + static IndexReaderPtr subReader(int32_t doc, const IndexReaderPtr& reader); + + /// Returns sub-reader subIndex from reader. + /// + /// @param reader Parent reader + /// @param subIndex Index of desired sub reader + /// @return The subreader at subIndex + static IndexReaderPtr subReader(const IndexReaderPtr& reader, int32_t subIndex); + + /// Returns index of the searcher/reader for document n in the array used to construct this + /// searcher/reader. + static int32_t subIndex(int32_t n, Collection docStarts); +}; + } #endif diff --git a/include/ReqExclScorer.h b/include/ReqExclScorer.h index 7180d5c3..be653c09 100644 --- a/include/ReqExclScorer.h +++ b/include/ReqExclScorer.h @@ -9,50 +9,50 @@ #include "Scorer.h" -namespace Lucene -{ - /// A Scorer for queries with a required subscorer and an excluding (prohibited) sub DocIdSetIterator. - /// This Scorer implements {@link Scorer#skipTo(int32_t)}, and it uses the skipTo() on the given scorers. - class ReqExclScorer : public Scorer - { - public: - /// Construct a ReqExclScorer. - /// @param reqScorer The scorer that must match, except where - /// @param exclDisi indicates exclusion. - ReqExclScorer(const ScorerPtr& reqScorer, const DocIdSetIteratorPtr& exclDisi); - virtual ~ReqExclScorer(); - - LUCENE_CLASS(ReqExclScorer); - - protected: - ScorerPtr reqScorer; - DocIdSetIteratorPtr exclDisi; - int32_t doc; - - public: - virtual int32_t nextDoc(); - virtual int32_t docID(); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} - /// is called the first time. - /// @return The score of the required scorer. - virtual double score(); - - virtual int32_t advance(int32_t target); - - protected: - /// Advance to non excluded doc. - /// - /// On entry: - ///
        - ///
      • reqScorer != null, - ///
      • exclScorer != null, - ///
      • reqScorer was advanced once via next() or skipTo() and reqScorer.doc() may still be excluded. - ///
      - /// Advances reqScorer a non excluded required doc, if any. - /// @return true iff there is a non excluded required doc. - int32_t toNonExcluded(); - }; +namespace Lucene { + +/// A Scorer for queries with a required subscorer and an excluding (prohibited) sub DocIdSetIterator. +/// This Scorer implements {@link Scorer#skipTo(int32_t)}, and it uses the skipTo() on the given scorers. +class ReqExclScorer : public Scorer { +public: + /// Construct a ReqExclScorer. + /// @param reqScorer The scorer that must match, except where + /// @param exclDisi indicates exclusion. + ReqExclScorer(const ScorerPtr& reqScorer, const DocIdSetIteratorPtr& exclDisi); + virtual ~ReqExclScorer(); + + LUCENE_CLASS(ReqExclScorer); + +protected: + ScorerPtr reqScorer; + DocIdSetIteratorPtr exclDisi; + int32_t doc; + +public: + virtual int32_t nextDoc(); + virtual int32_t docID(); + + /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} + /// is called the first time. + /// @return The score of the required scorer. + virtual double score(); + + virtual int32_t advance(int32_t target); + +protected: + /// Advance to non excluded doc. + /// + /// On entry: + ///
        + ///
      • reqScorer != null, + ///
      • exclScorer != null, + ///
      • reqScorer was advanced once via next() or skipTo() and reqScorer.doc() may still be excluded. + ///
      + /// Advances reqScorer a non excluded required doc, if any. + /// @return true iff there is a non excluded required doc. + int32_t toNonExcluded(); +}; + } #endif diff --git a/include/ReqOptSumScorer.h b/include/ReqOptSumScorer.h index 71c59a5b..9af9380b 100644 --- a/include/ReqOptSumScorer.h +++ b/include/ReqOptSumScorer.h @@ -9,33 +9,33 @@ #include "Scorer.h" -namespace Lucene -{ - /// A Scorer for queries with a required part and an optional part. Delays skipTo() on the optional part - /// until a score() is needed. This Scorer implements {@link Scorer#skipTo(int32_t)}. - class ReqOptSumScorer : public Scorer - { - public: - ReqOptSumScorer(const ScorerPtr& reqScorer, const ScorerPtr& optScorer); - virtual ~ReqOptSumScorer(); - - LUCENE_CLASS(ReqOptSumScorer); - - protected: - ScorerPtr reqScorer; - ScorerPtr optScorer; - - public: - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - virtual int32_t docID(); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} - /// is called the first time. - /// @return The score of the required scorer, eventually increased by the score of the optional scorer when - /// it also matches the current document. - virtual double score(); - }; +namespace Lucene { + +/// A Scorer for queries with a required part and an optional part. Delays skipTo() on the optional part +/// until a score() is needed. This Scorer implements {@link Scorer#skipTo(int32_t)}. +class ReqOptSumScorer : public Scorer { +public: + ReqOptSumScorer(const ScorerPtr& reqScorer, const ScorerPtr& optScorer); + virtual ~ReqOptSumScorer(); + + LUCENE_CLASS(ReqOptSumScorer); + +protected: + ScorerPtr reqScorer; + ScorerPtr optScorer; + +public: + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); + virtual int32_t docID(); + + /// Returns the score of the current document matching the query. Initially invalid, until {@link #next()} + /// is called the first time. + /// @return The score of the required scorer, eventually increased by the score of the optional scorer when + /// it also matches the current document. + virtual double score(); +}; + } #endif diff --git a/include/ReusableStringReader.h b/include/ReusableStringReader.h index 172f1d18..ce4879bf 100644 --- a/include/ReusableStringReader.h +++ b/include/ReusableStringReader.h @@ -9,34 +9,34 @@ #include "Reader.h" -namespace Lucene -{ - /// Used by DocumentsWriter to implemented a StringReader that can be reset to a new string; we use this - /// when tokenizing the string value from a Field. - class ReusableStringReader : public Reader - { - public: - ReusableStringReader(); - virtual ~ReusableStringReader(); - - LUCENE_CLASS(ReusableStringReader); - - public: - int32_t upto; - int32_t left; - String s; - - public: - virtual void init(const String& s); - - using Reader::read; - - /// Read characters into a portion of an array. - virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - - /// Close the stream. - virtual void close(); - }; +namespace Lucene { + +/// Used by DocumentsWriter to implemented a StringReader that can be reset to a new string; we use this +/// when tokenizing the string value from a Field. +class ReusableStringReader : public Reader { +public: + ReusableStringReader(); + virtual ~ReusableStringReader(); + + LUCENE_CLASS(ReusableStringReader); + +public: + int32_t upto; + int32_t left; + String s; + +public: + virtual void init(const String& s); + + using Reader::read; + + /// Read characters into a portion of an array. + virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); + + /// Close the stream. + virtual void close(); +}; + } #endif diff --git a/include/ReverseOrdFieldSource.h b/include/ReverseOrdFieldSource.h index bf7bc976..57491aa2 100644 --- a/include/ReverseOrdFieldSource.h +++ b/include/ReverseOrdFieldSource.h @@ -9,44 +9,44 @@ #include "ValueSource.h" -namespace Lucene -{ - /// Obtains the ordinal of the field value from the default Lucene {@link FieldCache} using getStringIndex() - /// and reverses the order. - /// - /// The native lucene index order is used to assign an ordinal value for each field value. - /// - /// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1. Example - /// of reverse ordinal (rord): - /// - /// If there were only three field values: "apple","banana","pear" then rord("apple")=3, rord("banana")=2, - /// ord("pear")=1 - /// - /// WARNING: rord() depends on the position in an index and can thus change when other documents are inserted - /// or deleted, or if a MultiSearcher is used. - /// - /// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite - /// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's - /// best to switch your application to pass only atomic (single segment) readers to this API. - class LPPAPI ReverseOrdFieldSource : public ValueSource - { - public: - /// Constructor for a certain field. - /// @param field field whose values reverse order is used. - ReverseOrdFieldSource(const String& field); - virtual ~ReverseOrdFieldSource(); - - LUCENE_CLASS(ReverseOrdFieldSource); - - protected: - String field; - - public: - virtual String description(); - virtual DocValuesPtr getValues(const IndexReaderPtr& reader); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// Obtains the ordinal of the field value from the default Lucene {@link FieldCache} using getStringIndex() +/// and reverses the order. +/// +/// The native lucene index order is used to assign an ordinal value for each field value. +/// +/// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1. Example +/// of reverse ordinal (rord): +/// +/// If there were only three field values: "apple","banana","pear" then rord("apple")=3, rord("banana")=2, +/// ord("pear")=1 +/// +/// WARNING: rord() depends on the position in an index and can thus change when other documents are inserted +/// or deleted, or if a MultiSearcher is used. +/// +/// NOTE: with the switch in 2.9 to segment-based searching, if {@link #getValues} is invoked with a composite +/// (multi-segment) reader, this can easily cause double RAM usage for the values in the FieldCache. It's +/// best to switch your application to pass only atomic (single segment) readers to this API. +class LPPAPI ReverseOrdFieldSource : public ValueSource { +public: + /// Constructor for a certain field. + /// @param field field whose values reverse order is used. + ReverseOrdFieldSource(const String& field); + virtual ~ReverseOrdFieldSource(); + + LUCENE_CLASS(ReverseOrdFieldSource); + +protected: + String field; + +public: + virtual String description(); + virtual DocValuesPtr getValues(const IndexReaderPtr& reader); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/ScoreCachingWrappingScorer.h b/include/ScoreCachingWrappingScorer.h index 403a47db..5f1d4b79 100644 --- a/include/ScoreCachingWrappingScorer.h +++ b/include/ScoreCachingWrappingScorer.h @@ -9,41 +9,41 @@ #include "Scorer.h" -namespace Lucene -{ - /// A {@link Scorer} which wraps another scorer and caches the score of the current document. Successive - /// calls to {@link #score()} will return the same result and will not invoke the wrapped Scorer's score() - /// method, unless the current document has changed. - /// - /// This class might be useful due to the changes done to the {@link Collector} interface, in which the - /// score is not computed for a document by default, only if the collector requests it. Some collectors - /// may need to use the score in several places, however all they have in hand is a {@link Scorer} object, - /// and might end up computing the score of a document more than once. - class LPPAPI ScoreCachingWrappingScorer : public Scorer - { - public: - /// Creates a new instance by wrapping the given scorer. - ScoreCachingWrappingScorer(const ScorerPtr& scorer); - virtual ~ScoreCachingWrappingScorer(); - - LUCENE_CLASS(ScoreCachingWrappingScorer); - - protected: - ScorerWeakPtr _scorer; - int32_t curDoc; - double curScore; - - public: - SimilarityPtr getSimilarity(); - virtual double score(); - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual void score(const CollectorPtr& collector); - virtual int32_t advance(int32_t target); - - protected: - virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); - }; +namespace Lucene { + +/// A {@link Scorer} which wraps another scorer and caches the score of the current document. Successive +/// calls to {@link #score()} will return the same result and will not invoke the wrapped Scorer's score() +/// method, unless the current document has changed. +/// +/// This class might be useful due to the changes done to the {@link Collector} interface, in which the +/// score is not computed for a document by default, only if the collector requests it. Some collectors +/// may need to use the score in several places, however all they have in hand is a {@link Scorer} object, +/// and might end up computing the score of a document more than once. +class LPPAPI ScoreCachingWrappingScorer : public Scorer { +public: + /// Creates a new instance by wrapping the given scorer. + ScoreCachingWrappingScorer(const ScorerPtr& scorer); + virtual ~ScoreCachingWrappingScorer(); + + LUCENE_CLASS(ScoreCachingWrappingScorer); + +protected: + ScorerWeakPtr _scorer; + int32_t curDoc; + double curScore; + +public: + SimilarityPtr getSimilarity(); + virtual double score(); + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual void score(const CollectorPtr& collector); + virtual int32_t advance(int32_t target); + +protected: + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); +}; + } #endif diff --git a/include/ScoreDoc.h b/include/ScoreDoc.h index 5b35f652..64ce8385 100644 --- a/include/ScoreDoc.h +++ b/include/ScoreDoc.h @@ -9,29 +9,29 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Expert: Returned by low-level search implementations. - /// @see TopDocs - class LPPAPI ScoreDoc : public LuceneObject - { - public: - ScoreDoc(int32_t doc, double score); - virtual ~ScoreDoc(); - - LUCENE_CLASS(ScoreDoc); - - public: - /// The score of this document for the query. - double score; - - /// A hit document's number. - /// @see Searcher#doc(int32_t) - int32_t doc; - - public: - virtual String toString(); - }; +namespace Lucene { + +/// Expert: Returned by low-level search implementations. +/// @see TopDocs +class LPPAPI ScoreDoc : public LuceneObject { +public: + ScoreDoc(int32_t doc, double score); + virtual ~ScoreDoc(); + + LUCENE_CLASS(ScoreDoc); + +public: + /// The score of this document for the query. + double score; + + /// A hit document's number. + /// @see Searcher#doc(int32_t) + int32_t doc; + +public: + virtual String toString(); +}; + } #endif diff --git a/include/Scorer.h b/include/Scorer.h index 0a9dbc74..bb9fd92b 100644 --- a/include/Scorer.h +++ b/include/Scorer.h @@ -9,55 +9,55 @@ #include "DocIdSetIterator.h" -namespace Lucene -{ - /// Common scoring functionality for different types of queries. +namespace Lucene { + +/// Common scoring functionality for different types of queries. +/// +/// A Scorer iterates over documents matching a query in increasing order of doc Id. +/// +/// Document scores are computed using a given Similarity implementation. +/// +/// NOTE: The values NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. Certain collectors +/// (eg {@link TopScoreDocCollector}) will not properly collect hits with these scores. +class LPPAPI Scorer : public DocIdSetIterator { +public: + /// Constructs a Scorer. + /// @param similarity The Similarity implementation used by this scorer. + Scorer(const SimilarityPtr& similarity); + virtual ~Scorer(); + + LUCENE_CLASS(Scorer); + +protected: + SimilarityPtr similarity; + +public: + /// Returns the Similarity implementation used by this scorer. + SimilarityPtr getSimilarity(); + + /// Scores and collects all matching documents. + /// @param collector The collector to which all matching documents are passed. + virtual void score(const CollectorPtr& collector); + + /// Returns the score of the current document matching the query. Initially invalid, until {@link + /// #nextDoc()} or {@link #advance(int32_t)} is called the first time, or when called from within + /// {@link Collector#collect}. + virtual double score() = 0; + +protected: + /// Collects matching documents in a range. Hook for optimization. + /// Note, firstDocID is added to ensure that {@link #nextDoc()} was called before this method. /// - /// A Scorer iterates over documents matching a query in increasing order of doc Id. - /// - /// Document scores are computed using a given Similarity implementation. - /// - /// NOTE: The values NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. Certain collectors - /// (eg {@link TopScoreDocCollector}) will not properly collect hits with these scores. - class LPPAPI Scorer : public DocIdSetIterator - { - public: - /// Constructs a Scorer. - /// @param similarity The Similarity implementation used by this scorer. - Scorer(const SimilarityPtr& similarity); - virtual ~Scorer(); - - LUCENE_CLASS(Scorer); - - protected: - SimilarityPtr similarity; - - public: - /// Returns the Similarity implementation used by this scorer. - SimilarityPtr getSimilarity(); - - /// Scores and collects all matching documents. - /// @param collector The collector to which all matching documents are passed. - virtual void score(const CollectorPtr& collector); - - /// Returns the score of the current document matching the query. Initially invalid, until {@link - /// #nextDoc()} or {@link #advance(int32_t)} is called the first time, or when called from within - /// {@link Collector#collect}. - virtual double score() = 0; - - protected: - /// Collects matching documents in a range. Hook for optimization. - /// Note, firstDocID is added to ensure that {@link #nextDoc()} was called before this method. - /// - /// @param collector The collector to which all matching documents are passed. - /// @param max Do not score documents past this. - /// @param firstDocID The first document ID (ensures {@link #nextDoc()} is called before this method. - /// @return true if more matching documents may remain. - virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); - - friend class BooleanScorer; - friend class ScoreCachingWrappingScorer; - }; + /// @param collector The collector to which all matching documents are passed. + /// @param max Do not score documents past this. + /// @param firstDocID The first document ID (ensures {@link #nextDoc()} is called before this method. + /// @return true if more matching documents may remain. + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); + + friend class BooleanScorer; + friend class ScoreCachingWrappingScorer; +}; + } #endif diff --git a/include/ScorerDocQueue.h b/include/ScorerDocQueue.h index 3613d426..26724749 100644 --- a/include/ScorerDocQueue.h +++ b/include/ScorerDocQueue.h @@ -9,69 +9,69 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A ScorerDocQueue maintains a partial ordering of its Scorers such that the least Scorer can always be - /// found in constant time. Put()'s and pop()'s require log(size) time. The ordering is by Scorer::doc(). - class LPPAPI ScorerDocQueue : public LuceneObject - { - public: - ScorerDocQueue(int32_t maxSize); - virtual ~ScorerDocQueue(); - - LUCENE_CLASS(ScorerDocQueue); - - protected: - Collection heap; - int32_t maxSize; - int32_t _size; - HeapedScorerDocPtr topHSD; // same as heap[1], only for speed - - public: - /// Adds a Scorer to a ScorerDocQueue in log(size) time. If one tries to add more Scorers than maxSize - /// ArrayIndexOutOfBound exception is thrown. - void put(const ScorerPtr& scorer); - - /// Adds a Scorer to the ScorerDocQueue in log(size) time if either the ScorerDocQueue is not full, or - /// not lessThan(scorer, top()). - /// @return true if scorer is added, false otherwise. - bool insert(const ScorerPtr& scorer); - - /// Returns the least Scorer of the ScorerDocQueue in constant time. Should not be used when the queue - /// is empty. - ScorerPtr top(); - - /// Returns document number of the least Scorer of the ScorerDocQueue in constant time. - /// Should not be used when the queue is empty. - int32_t topDoc(); - - double topScore(); - bool topNextAndAdjustElsePop(); - bool topSkipToAndAdjustElsePop(int32_t target); - - /// Removes and returns the least scorer of the ScorerDocQueue in log(size) time. Should not be used - /// when the queue is empty. - ScorerPtr pop(); - - /// Should be called when the scorer at top changes doc() value. - void adjustTop(); - - /// Returns the number of scorers currently stored in the ScorerDocQueue. - int32_t size(); - - /// Removes all entries from the ScorerDocQueue. - void clear(); - - protected: - bool checkAdjustElsePop(bool cond); - - /// Removes the least scorer of the ScorerDocQueue in log(size) time. Should not be used when the - /// queue is empty. - void popNoResult(); - - void upHeap(); - void downHeap(); - }; +namespace Lucene { + +/// A ScorerDocQueue maintains a partial ordering of its Scorers such that the least Scorer can always be +/// found in constant time. Put()'s and pop()'s require log(size) time. The ordering is by Scorer::doc(). +class LPPAPI ScorerDocQueue : public LuceneObject { +public: + ScorerDocQueue(int32_t maxSize); + virtual ~ScorerDocQueue(); + + LUCENE_CLASS(ScorerDocQueue); + +protected: + Collection heap; + int32_t maxSize; + int32_t _size; + HeapedScorerDocPtr topHSD; // same as heap[1], only for speed + +public: + /// Adds a Scorer to a ScorerDocQueue in log(size) time. If one tries to add more Scorers than maxSize + /// ArrayIndexOutOfBound exception is thrown. + void put(const ScorerPtr& scorer); + + /// Adds a Scorer to the ScorerDocQueue in log(size) time if either the ScorerDocQueue is not full, or + /// not lessThan(scorer, top()). + /// @return true if scorer is added, false otherwise. + bool insert(const ScorerPtr& scorer); + + /// Returns the least Scorer of the ScorerDocQueue in constant time. Should not be used when the queue + /// is empty. + ScorerPtr top(); + + /// Returns document number of the least Scorer of the ScorerDocQueue in constant time. + /// Should not be used when the queue is empty. + int32_t topDoc(); + + double topScore(); + bool topNextAndAdjustElsePop(); + bool topSkipToAndAdjustElsePop(int32_t target); + + /// Removes and returns the least scorer of the ScorerDocQueue in log(size) time. Should not be used + /// when the queue is empty. + ScorerPtr pop(); + + /// Should be called when the scorer at top changes doc() value. + void adjustTop(); + + /// Returns the number of scorers currently stored in the ScorerDocQueue. + int32_t size(); + + /// Removes all entries from the ScorerDocQueue. + void clear(); + +protected: + bool checkAdjustElsePop(bool cond); + + /// Removes the least scorer of the ScorerDocQueue in log(size) time. Should not be used when the + /// queue is empty. + void popNoResult(); + + void upHeap(); + void downHeap(); +}; + } #endif diff --git a/include/Searchable.h b/include/Searchable.h index 0b8088ec..856e94d4 100644 --- a/include/Searchable.h +++ b/include/Searchable.h @@ -9,100 +9,100 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// The interface for search implementations. +namespace Lucene { + +/// The interface for search implementations. +/// +/// Searchable is the abstract network protocol for searching. Implementations provide search over a single +/// index, over multiple indices, and over indices on remote servers. +/// +/// Queries, filters and sort criteria are designed to be compact so that they may be efficiently passed to a +/// remote index, with only the top-scoring hits being returned, rather than every matching hit. +/// +/// NOTE: this interface is kept public for convenience. Since it is not expected to be implemented directly, +/// it may be changed unexpectedly between releases. +class LPPAPI Searchable { +public: + LUCENE_INTERFACE(Searchable); + +public: + /// Lower-level search API. + /// + /// {@link Collector#collect(int32_t)} is called for every document. Collector-based access to remote + /// indexes is discouraged. /// - /// Searchable is the abstract network protocol for searching. Implementations provide search over a single - /// index, over multiple indices, and over indices on remote servers. + /// Applications should only use this if they need all of the matching documents. The high-level search + /// API ({@link Searcher#search(QueryPtr, int32_t)}) is usually more efficient, as it skips non-high-scoring + /// hits. /// - /// Queries, filters and sort criteria are designed to be compact so that they may be efficiently passed to a - /// remote index, with only the top-scoring hits being returned, rather than every matching hit. + /// @param weight To match documents + /// @param filter If non-null, used to permit documents to be collected. + /// @param collector To receive hits + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) = 0; + + /// Frees resources associated with this Searcher. Be careful not to call this method while you are still + /// using objects that reference this Searchable. + virtual void close() = 0; + + /// Returns the number of documents containing term. + /// @see IndexReader#docFreq(TermPtr) + virtual int32_t docFreq(const TermPtr& term) = 0; + + /// For each term in the terms array, calculates the number of documents containing term. Returns an array + /// with these document frequencies. Used to minimize number of remote calls. + virtual Collection docFreqs(Collection terms) = 0; + + /// Returns one greater than the largest possible document number. + /// @see IndexReader#maxDoc() + virtual int32_t maxDoc() = 0; + + /// Low-level search implementation. Finds the top n hits for query, applying filter if non-null. + /// Applications should usually call {@link Searcher#search(QueryPtr, int32_t)} or {@link + /// Searcher#search(QueryPtr, FilterPtr, int32_t)} instead. + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) = 0; + + /// Returns the stored fields of document i. + /// @see IndexReader#document(int32_t) + virtual DocumentPtr doc(int32_t n) = 0; + + /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what + /// {@link Field}s to load and how they should be loaded. /// - /// NOTE: this interface is kept public for convenience. Since it is not expected to be implemented directly, - /// it may be changed unexpectedly between releases. - class LPPAPI Searchable - { - public: - LUCENE_INTERFACE(Searchable); - - public: - /// Lower-level search API. - /// - /// {@link Collector#collect(int32_t)} is called for every document. Collector-based access to remote - /// indexes is discouraged. - /// - /// Applications should only use this if they need all of the matching documents. The high-level search - /// API ({@link Searcher#search(QueryPtr, int32_t)}) is usually more efficient, as it skips non-high-scoring - /// hits. - /// - /// @param weight To match documents - /// @param filter If non-null, used to permit documents to be collected. - /// @param collector To receive hits - virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) = 0; - - /// Frees resources associated with this Searcher. Be careful not to call this method while you are still - /// using objects that reference this Searchable. - virtual void close() = 0; - - /// Returns the number of documents containing term. - /// @see IndexReader#docFreq(TermPtr) - virtual int32_t docFreq(const TermPtr& term) = 0; - - /// For each term in the terms array, calculates the number of documents containing term. Returns an array - /// with these document frequencies. Used to minimize number of remote calls. - virtual Collection docFreqs(Collection terms) = 0; - - /// Returns one greater than the largest possible document number. - /// @see IndexReader#maxDoc() - virtual int32_t maxDoc() = 0; - - /// Low-level search implementation. Finds the top n hits for query, applying filter if non-null. - /// Applications should usually call {@link Searcher#search(QueryPtr, int32_t)} or {@link - /// Searcher#search(QueryPtr, FilterPtr, int32_t)} instead. - virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) = 0; - - /// Returns the stored fields of document i. - /// @see IndexReader#document(int32_t) - virtual DocumentPtr doc(int32_t n) = 0; - - /// Get the {@link Document} at the n'th position. The {@link FieldSelector} may be used to determine what - /// {@link Field}s to load and how they should be loaded. - /// - /// NOTE: If the underlying Reader (more specifically, the underlying FieldsReader) is closed before the - /// lazy {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} - /// to be available after closing you must explicitly load it or fetch the Document again with a new loader. - /// - /// @param n Get the document at the n'th position - /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on the - /// Document. May be null, in which case all Fields will be loaded. - /// @return The stored fields of the {@link Document} at the n'th position - /// - /// @see IndexReader#document(int32_t, FieldSelectorPtr) - /// @see Fieldable - /// @see FieldSelector - /// @see SetBasedFieldSelector - /// @see LoadFirstFieldSelector - virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; - - /// Called to re-write queries into primitive queries. - virtual QueryPtr rewrite(const QueryPtr& query) = 0; - - /// Low-level implementation method. Returns an Explanation that describes how doc scored against weight. - /// - /// This is intended to be used in developing Similarity implementations, and for good performance, should - /// not be displayed with every hit. Computing an explanation is as expensive as executing the query over - /// the entire index. - /// - /// Applications should call {@link Searcher#explain(QueryPtr, int32_t)}. - virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc) = 0; - - /// Low-level search implementation with arbitrary sorting. Finds the top n hits for query, applying filter - /// if non-null, and sorting the hits by the criteria in sort. - /// - /// Applications should usually call {@link Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr)} instead. - virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) = 0; - }; + /// NOTE: If the underlying Reader (more specifically, the underlying FieldsReader) is closed before the + /// lazy {@link Field} is loaded an exception may be thrown. If you want the value of a lazy {@link Field} + /// to be available after closing you must explicitly load it or fetch the Document again with a new loader. + /// + /// @param n Get the document at the n'th position + /// @param fieldSelector The {@link FieldSelector} to use to determine what Fields should be loaded on the + /// Document. May be null, in which case all Fields will be loaded. + /// @return The stored fields of the {@link Document} at the n'th position + /// + /// @see IndexReader#document(int32_t, FieldSelectorPtr) + /// @see Fieldable + /// @see FieldSelector + /// @see SetBasedFieldSelector + /// @see LoadFirstFieldSelector + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; + + /// Called to re-write queries into primitive queries. + virtual QueryPtr rewrite(const QueryPtr& query) = 0; + + /// Low-level implementation method. Returns an Explanation that describes how doc scored against weight. + /// + /// This is intended to be used in developing Similarity implementations, and for good performance, should + /// not be displayed with every hit. Computing an explanation is as expensive as executing the query over + /// the entire index. + /// + /// Applications should call {@link Searcher#explain(QueryPtr, int32_t)}. + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc) = 0; + + /// Low-level search implementation with arbitrary sorting. Finds the top n hits for query, applying filter + /// if non-null, and sorting the hits by the criteria in sort. + /// + /// Applications should usually call {@link Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr)} instead. + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) = 0; +}; + } #endif diff --git a/include/Searcher.h b/include/Searcher.h index 4f71a1c0..91b09f43 100644 --- a/include/Searcher.h +++ b/include/Searcher.h @@ -9,97 +9,97 @@ #include "Searchable.h" -namespace Lucene -{ - /// An abstract base class for search implementations. Implements the main search methods. +namespace Lucene { + +/// An abstract base class for search implementations. Implements the main search methods. +/// +/// Note that you can only access hits from a Searcher as long as it is not yet closed, otherwise an IO +/// exception will be thrown. +class LPPAPI Searcher : public Searchable, public LuceneObject { +public: + Searcher(); + virtual ~Searcher(); + + LUCENE_CLASS(Searcher); + +protected: + /// The Similarity implementation used by this searcher. + SimilarityPtr similarity; + +public: + /// Search implementation with arbitrary sorting. Finds the top n hits for query, applying filter if + /// non-null, and sorting the hits by the criteria in sort. /// - /// Note that you can only access hits from a Searcher as long as it is not yet closed, otherwise an IO - /// exception will be thrown. - class LPPAPI Searcher : public Searchable, public LuceneObject - { - public: - Searcher(); - virtual ~Searcher(); - - LUCENE_CLASS(Searcher); - - protected: - /// The Similarity implementation used by this searcher. - SimilarityPtr similarity; - - public: - /// Search implementation with arbitrary sorting. Finds the top n hits for query, applying filter if - /// non-null, and sorting the hits by the criteria in sort. - /// - /// NOTE: this does not compute scores by default; use {@link IndexSearcher#setDefaultFieldSortScoring} - /// to enable scoring. - virtual TopFieldDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort); - - /// Lower-level search API. - /// - /// {@link Collector#collect(int32_t)} is called for every matching document. - /// - /// Applications should only use this if they need all of the matching documents. The high-level - /// search API ({@link Searcher#search(QueryPtr, int32_t)}) is usually more efficient, as it skips - /// non-high-scoring hits. - /// - /// Note: The score passed to this method is a raw score. In other words, the score will not necessarily - /// be a double whose value is between 0 and 1. - virtual void search(const QueryPtr& query, const CollectorPtr& results); - - /// Lower-level search API. - /// - /// {@link Collector#collect(int32_t)} is called for every matching document. Collector-based access to - /// remote indexes is discouraged. - /// - /// Applications should only use this if they need all of the matching documents. The high-level search - /// API ({@link Searcher#search(QueryPtr, FilterPtr, int32_t)}) is usually more efficient, as it skips - /// non-high-scoring hits. - /// - /// @param query To match documents - /// @param filter If non-null, used to permit documents to be collected. - /// @param results To receive hits - virtual void search(const QueryPtr& query, const FilterPtr& filter, const CollectorPtr& results); - - /// Finds the top n hits for query, applying filter if non-null. - virtual TopDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n); - - /// Finds the top n hits for query. - virtual TopDocsPtr search(const QueryPtr& query, int32_t n); - - /// Returns an Explanation that describes how doc scored against query. - /// - /// This is intended to be used in developing Similarity implementations, and for good performance, - /// should not be displayed with every hit. Computing an explanation is as expensive as executing the - /// query over the entire index. - virtual ExplanationPtr explain(const QueryPtr& query, int32_t doc); - - /// Set the Similarity implementation used by this Searcher. - virtual void setSimilarity(const SimilarityPtr& similarity); - - /// Return the Similarity implementation used by this Searcher. - /// - /// This defaults to the current value of {@link Similarity#getDefault()}. - virtual SimilarityPtr getSimilarity(); - - virtual Collection docFreqs(Collection terms); - - virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) = 0; - virtual void close() = 0; - virtual int32_t docFreq(const TermPtr& term) = 0; - virtual int32_t maxDoc() = 0; - virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) = 0; - virtual DocumentPtr doc(int32_t n) = 0; - virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; - virtual QueryPtr rewrite(const QueryPtr& query) = 0; - virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc) = 0; - virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) = 0; - - protected: - /// Creates a weight for query. - /// @return New weight - virtual WeightPtr createWeight(const QueryPtr& query); - }; + /// NOTE: this does not compute scores by default; use {@link IndexSearcher#setDefaultFieldSortScoring} + /// to enable scoring. + virtual TopFieldDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort); + + /// Lower-level search API. + /// + /// {@link Collector#collect(int32_t)} is called for every matching document. + /// + /// Applications should only use this if they need all of the matching documents. The high-level + /// search API ({@link Searcher#search(QueryPtr, int32_t)}) is usually more efficient, as it skips + /// non-high-scoring hits. + /// + /// Note: The score passed to this method is a raw score. In other words, the score will not necessarily + /// be a double whose value is between 0 and 1. + virtual void search(const QueryPtr& query, const CollectorPtr& results); + + /// Lower-level search API. + /// + /// {@link Collector#collect(int32_t)} is called for every matching document. Collector-based access to + /// remote indexes is discouraged. + /// + /// Applications should only use this if they need all of the matching documents. The high-level search + /// API ({@link Searcher#search(QueryPtr, FilterPtr, int32_t)}) is usually more efficient, as it skips + /// non-high-scoring hits. + /// + /// @param query To match documents + /// @param filter If non-null, used to permit documents to be collected. + /// @param results To receive hits + virtual void search(const QueryPtr& query, const FilterPtr& filter, const CollectorPtr& results); + + /// Finds the top n hits for query, applying filter if non-null. + virtual TopDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n); + + /// Finds the top n hits for query. + virtual TopDocsPtr search(const QueryPtr& query, int32_t n); + + /// Returns an Explanation that describes how doc scored against query. + /// + /// This is intended to be used in developing Similarity implementations, and for good performance, + /// should not be displayed with every hit. Computing an explanation is as expensive as executing the + /// query over the entire index. + virtual ExplanationPtr explain(const QueryPtr& query, int32_t doc); + + /// Set the Similarity implementation used by this Searcher. + virtual void setSimilarity(const SimilarityPtr& similarity); + + /// Return the Similarity implementation used by this Searcher. + /// + /// This defaults to the current value of {@link Similarity#getDefault()}. + virtual SimilarityPtr getSimilarity(); + + virtual Collection docFreqs(Collection terms); + + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) = 0; + virtual void close() = 0; + virtual int32_t docFreq(const TermPtr& term) = 0; + virtual int32_t maxDoc() = 0; + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) = 0; + virtual DocumentPtr doc(int32_t n) = 0; + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector) = 0; + virtual QueryPtr rewrite(const QueryPtr& query) = 0; + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc) = 0; + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) = 0; + +protected: + /// Creates a weight for query. + /// @return New weight + virtual WeightPtr createWeight(const QueryPtr& query); +}; + } #endif diff --git a/include/SegmentInfo.h b/include/SegmentInfo.h index 0e431a1f..d1706d14 100644 --- a/include/SegmentInfo.h +++ b/include/SegmentInfo.h @@ -9,165 +9,165 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Information about a segment such as it's name, directory, and files - /// related to the segment. - class LPPAPI SegmentInfo : public LuceneObject - { - public: - SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir); +namespace Lucene { - SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile); +/// Information about a segment such as it's name, directory, and files +/// related to the segment. +class LPPAPI SegmentInfo : public LuceneObject { +public: + SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir); - SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, - bool hasSingleNormFile, int32_t docStoreOffset, const String& docStoreSegment, - bool docStoreIsCompoundFile, bool hasProx); + SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile); - /// Construct a new SegmentInfo instance by reading a previously saved SegmentInfo from input. - /// @param dir directory to load from. - /// @param format format of the segments info file. - /// @param input input handle to read segment info from. - SegmentInfo(const DirectoryPtr& dir, int32_t format, const IndexInputPtr& input); + SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, + bool hasSingleNormFile, int32_t docStoreOffset, const String& docStoreSegment, + bool docStoreIsCompoundFile, bool hasProx); - virtual ~SegmentInfo(); + /// Construct a new SegmentInfo instance by reading a previously saved SegmentInfo from input. + /// @param dir directory to load from. + /// @param format format of the segments info file. + /// @param input input handle to read segment info from. + SegmentInfo(const DirectoryPtr& dir, int32_t format, const IndexInputPtr& input); - LUCENE_CLASS(SegmentInfo); + virtual ~SegmentInfo(); - public: - static const int32_t NO; // no norms; no deletes; - static const int32_t YES; // have norms; have deletes; - static const int32_t CHECK_DIR; // must check dir to see if there are norms/deletions - static const int32_t WITHOUT_GEN; // a file name that has no GEN in it. + LUCENE_CLASS(SegmentInfo); - protected: - // true if this is a segments file written before lock-less commits (2.1) - bool preLockless; +public: + static const int32_t NO; // no norms; no deletes; + static const int32_t YES; // have norms; have deletes; + static const int32_t CHECK_DIR; // must check dir to see if there are norms/deletions + static const int32_t WITHOUT_GEN; // a file name that has no GEN in it. - // current generation of del file; NO if there are no deletes; CHECK_DIR if it's a pre-2.1 segment - // (and we must check filesystem); YES or higher if there are deletes at generation N - int64_t delGen; +protected: + // true if this is a segments file written before lock-less commits (2.1) + bool preLockless; - // current generation of each field's norm file. If this array is null, for lockLess this means no - // separate norms. For preLockLess this means we must check filesystem. If this array is not null, - // its values mean: NO says this field has no separate norms; CHECK_DIR says it is a preLockLess - // segment and filesystem must be checked; >= YES says this field has separate norms with the - // specified generation - Collection normGen; + // current generation of del file; NO if there are no deletes; CHECK_DIR if it's a pre-2.1 segment + // (and we must check filesystem); YES or higher if there are deletes at generation N + int64_t delGen; - // NO if it is not; YES if it is; CHECK_DIR if it's pre-2.1 (ie, must check file system to see if - // .cfs and .nrm exist) - uint8_t isCompoundFile; + // current generation of each field's norm file. If this array is null, for lockLess this means no + // separate norms. For preLockLess this means we must check filesystem. If this array is not null, + // its values mean: NO says this field has no separate norms; CHECK_DIR says it is a preLockLess + // segment and filesystem must be checked; >= YES says this field has separate norms with the + // specified generation + Collection normGen; - // true if this segment maintains norms in a single file; false otherwise this is currently false for - // segments populated by DocumentWriter and true for newly created merged segments (both compound and - // non compound). - bool hasSingleNormFile; + // NO if it is not; YES if it is; CHECK_DIR if it's pre-2.1 (ie, must check file system to see if + // .cfs and .nrm exist) + uint8_t isCompoundFile; - // cached list of files that this segment uses in the Directory - HashSet _files; + // true if this segment maintains norms in a single file; false otherwise this is currently false for + // segments populated by DocumentWriter and true for newly created merged segments (both compound and + // non compound). + bool hasSingleNormFile; - // total byte size of all of our files (computed on demand) - int64_t _sizeInBytes; + // cached list of files that this segment uses in the Directory + HashSet _files; - // if this segment shares stored fields & vectors, this offset is where in that file this segment's - // docs begin - int32_t docStoreOffset; + // total byte size of all of our files (computed on demand) + int64_t _sizeInBytes; - // name used to derive fields/vectors file we share with other segments - String docStoreSegment; + // if this segment shares stored fields & vectors, this offset is where in that file this segment's + // docs begin + int32_t docStoreOffset; - // whether doc store files are stored in compound file (*.cfx) - bool docStoreIsCompoundFile; + // name used to derive fields/vectors file we share with other segments + String docStoreSegment; - // How many deleted docs in this segment, or -1 if not yet known (if it's an older index) - int32_t delCount; + // whether doc store files are stored in compound file (*.cfx) + bool docStoreIsCompoundFile; - // True if this segment has any fields with omitTermFreqAndPositions == false - bool hasProx; + // How many deleted docs in this segment, or -1 if not yet known (if it's an older index) + int32_t delCount; - MapStringString diagnostics; + // True if this segment has any fields with omitTermFreqAndPositions == false + bool hasProx; - public: - String name; // unique name in dir - int32_t docCount; // number of docs in seg - DirectoryPtr dir; // where segment resides + MapStringString diagnostics; - public: - /// Copy everything from src SegmentInfo into our instance. - void reset(const SegmentInfoPtr& src); +public: + String name; // unique name in dir + int32_t docCount; // number of docs in seg + DirectoryPtr dir; // where segment resides - void setDiagnostics(MapStringString diagnostics); - MapStringString getDiagnostics(); +public: + /// Copy everything from src SegmentInfo into our instance. + void reset(const SegmentInfoPtr& src); - void setNumFields(int32_t numFields); + void setDiagnostics(MapStringString diagnostics); + MapStringString getDiagnostics(); - /// Returns total size in bytes of all of files used by this segment. - int64_t sizeInBytes(); + void setNumFields(int32_t numFields); - bool hasDeletions(); - void advanceDelGen(); - void clearDelGen(); + /// Returns total size in bytes of all of files used by this segment. + int64_t sizeInBytes(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + bool hasDeletions(); + void advanceDelGen(); + void clearDelGen(); - String getDelFileName(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - /// Returns true if this field for this segment has saved a separate norms file (__N.sX). - /// @param fieldNumber the field index to check - bool hasSeparateNorms(int32_t fieldNumber); + String getDelFileName(); - /// Returns true if any fields in this segment have separate norms. - bool hasSeparateNorms(); + /// Returns true if this field for this segment has saved a separate norms file (__N.sX). + /// @param fieldNumber the field index to check + bool hasSeparateNorms(int32_t fieldNumber); - /// Increment the generation count for the norms file for this field. - /// @param fieldIndex field whose norm file will be rewritten - void advanceNormGen(int32_t fieldIndex); + /// Returns true if any fields in this segment have separate norms. + bool hasSeparateNorms(); - /// Get the file name for the norms file for this field. - /// @param number field index - String getNormFileName(int32_t number); + /// Increment the generation count for the norms file for this field. + /// @param fieldIndex field whose norm file will be rewritten + void advanceNormGen(int32_t fieldIndex); - /// Mark whether this segment is stored as a compound file. - /// @param isCompoundFile true if this is a compound file; else, false - void setUseCompoundFile(bool isCompoundFile); + /// Get the file name for the norms file for this field. + /// @param number field index + String getNormFileName(int32_t number); - /// Returns true if this segment is stored as a compound file; else, false. - bool getUseCompoundFile(); + /// Mark whether this segment is stored as a compound file. + /// @param isCompoundFile true if this is a compound file; else, false + void setUseCompoundFile(bool isCompoundFile); - int32_t getDelCount(); - void setDelCount(int32_t delCount); - int32_t getDocStoreOffset(); - bool getDocStoreIsCompoundFile(); - void setDocStoreIsCompoundFile(bool v); - String getDocStoreSegment(); - void setDocStoreOffset(int32_t offset); - void setDocStore(int32_t offset, const String& segment, bool isCompoundFile); + /// Returns true if this segment is stored as a compound file; else, false. + bool getUseCompoundFile(); - /// Save this segment's info. - void write(const IndexOutputPtr& output); + int32_t getDelCount(); + void setDelCount(int32_t delCount); + int32_t getDocStoreOffset(); + bool getDocStoreIsCompoundFile(); + void setDocStoreIsCompoundFile(bool v); + String getDocStoreSegment(); + void setDocStoreOffset(int32_t offset); + void setDocStore(int32_t offset, const String& segment, bool isCompoundFile); - void setHasProx(bool hasProx); - bool getHasProx(); + /// Save this segment's info. + void write(const IndexOutputPtr& output); - /// Return all files referenced by this SegmentInfo. The returns List is a locally cached List so - /// you should not modify it. - HashSet files(); + void setHasProx(bool hasProx); + bool getHasProx(); - /// Used for debugging. - String segString(const DirectoryPtr& dir); + /// Return all files referenced by this SegmentInfo. The returns List is a locally cached List so + /// you should not modify it. + HashSet files(); - /// We consider another SegmentInfo instance equal if it has the same dir and same name. - virtual bool equals(const LuceneObjectPtr& other); + /// Used for debugging. + String segString(const DirectoryPtr& dir); - virtual int32_t hashCode(); + /// We consider another SegmentInfo instance equal if it has the same dir and same name. + virtual bool equals(const LuceneObjectPtr& other); - protected: - void addIfExists(HashSet files, const String& fileName); + virtual int32_t hashCode(); + +protected: + void addIfExists(HashSet files, const String& fileName); + + /// Called whenever any change is made that affects which files this segment has. + void clearFiles(); +}; - /// Called whenever any change is made that affects which files this segment has. - void clearFiles(); - }; } #endif diff --git a/include/SegmentInfoCollection.h b/include/SegmentInfoCollection.h index ae5c509d..f05656e7 100644 --- a/include/SegmentInfoCollection.h +++ b/include/SegmentInfoCollection.h @@ -9,35 +9,35 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A collection of SegmentInfo objects to be used as a base class for {@link SegmentInfos} - class LPPAPI SegmentInfoCollection : public LuceneObject - { - public: - SegmentInfoCollection(); - virtual ~SegmentInfoCollection(); - - LUCENE_CLASS(SegmentInfoCollection); - - protected: - Collection segmentInfos; - - public: - int32_t size(); - bool empty(); - void clear(); - void add(const SegmentInfoPtr& info); - void add(int32_t pos, const SegmentInfoPtr& info); - void addAll(const SegmentInfoCollectionPtr& segmentInfos); - bool equals(const SegmentInfoCollectionPtr& other); - int32_t find(const SegmentInfoPtr& info); - bool contains(const SegmentInfoPtr& info); - void remove(int32_t pos); - void remove(int32_t start, int32_t end); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// A collection of SegmentInfo objects to be used as a base class for {@link SegmentInfos} +class LPPAPI SegmentInfoCollection : public LuceneObject { +public: + SegmentInfoCollection(); + virtual ~SegmentInfoCollection(); + + LUCENE_CLASS(SegmentInfoCollection); + +protected: + Collection segmentInfos; + +public: + int32_t size(); + bool empty(); + void clear(); + void add(const SegmentInfoPtr& info); + void add(int32_t pos, const SegmentInfoPtr& info); + void addAll(const SegmentInfoCollectionPtr& segmentInfos); + bool equals(const SegmentInfoCollectionPtr& other); + int32_t find(const SegmentInfoPtr& info); + bool contains(const SegmentInfoPtr& info); + void remove(int32_t pos); + void remove(int32_t start, int32_t end); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/include/SegmentInfos.h b/include/SegmentInfos.h index 69d01749..d883206e 100644 --- a/include/SegmentInfos.h +++ b/include/SegmentInfos.h @@ -9,175 +9,175 @@ #include "SegmentInfoCollection.h" -namespace Lucene -{ - /// A collection of SegmentInfo objects with methods for operating on those segments in relation to the file system. - class LPPAPI SegmentInfos : public SegmentInfoCollection - { - public: - SegmentInfos(); - virtual ~SegmentInfos(); +namespace Lucene { - LUCENE_CLASS(SegmentInfos); +/// A collection of SegmentInfo objects with methods for operating on those segments in relation to the file system. +class LPPAPI SegmentInfos : public SegmentInfoCollection { +public: + SegmentInfos(); + virtual ~SegmentInfos(); - public: - /// The file format version, a negative number. Works since counter, the old 1st entry, is always >= 0 - static const int32_t FORMAT; + LUCENE_CLASS(SegmentInfos); - /// This format adds details used for lockless commits. It differs slightly from the previous format in that file names - /// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, - /// segments_2, etc. This allows us to not use a commit lock. - /// See fileformats for details. - static const int32_t FORMAT_LOCKLESS; +public: + /// The file format version, a negative number. Works since counter, the old 1st entry, is always >= 0 + static const int32_t FORMAT; - /// This format adds a "hasSingleNormFile" flag into each segment info. - static const int32_t FORMAT_SINGLE_NORM_FILE; + /// This format adds details used for lockless commits. It differs slightly from the previous format in that file names + /// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, + /// segments_2, etc. This allows us to not use a commit lock. + /// See fileformats for details. + static const int32_t FORMAT_LOCKLESS; - /// This format allows multiple segments to share a single vectors and stored fields file. - static const int32_t FORMAT_SHARED_DOC_STORE; + /// This format adds a "hasSingleNormFile" flag into each segment info. + static const int32_t FORMAT_SINGLE_NORM_FILE; - /// This format adds a checksum at the end of the file to ensure all bytes were successfully written. - static const int32_t FORMAT_CHECKSUM; + /// This format allows multiple segments to share a single vectors and stored fields file. + static const int32_t FORMAT_SHARED_DOC_STORE; - /// This format adds the deletion count for each segment. This way IndexWriter can efficiently report numDocs(). - static const int32_t FORMAT_DEL_COUNT; + /// This format adds a checksum at the end of the file to ensure all bytes were successfully written. + static const int32_t FORMAT_CHECKSUM; - /// This format adds the boolean hasProx to record if any fields in the segment store prox information (ie, have - /// omitTermFreqAndPositions == false) - static const int32_t FORMAT_HAS_PROX; + /// This format adds the deletion count for each segment. This way IndexWriter can efficiently report numDocs(). + static const int32_t FORMAT_DEL_COUNT; - /// This format adds optional commit userData storage. - static const int32_t FORMAT_USER_DATA; + /// This format adds the boolean hasProx to record if any fields in the segment store prox information (ie, have + /// omitTermFreqAndPositions == false) + static const int32_t FORMAT_HAS_PROX; - /// This format adds optional per-segment string diagnostics storage, and switches userData to Map - static const int32_t FORMAT_DIAGNOSTICS; + /// This format adds optional commit userData storage. + static const int32_t FORMAT_USER_DATA; - /// This must always point to the most recent file format. - static const int32_t CURRENT_FORMAT; + /// This format adds optional per-segment string diagnostics storage, and switches userData to Map + static const int32_t FORMAT_DIAGNOSTICS; - int32_t counter; // used to name new segments + /// This must always point to the most recent file format. + static const int32_t CURRENT_FORMAT; - private: - /// Advanced configuration of retry logic in loading segments_N file. - static int32_t defaultGenFileRetryCount; - static int32_t defaultGenFileRetryPauseMsec; - static int32_t defaultGenLookaheadCount; + int32_t counter; // used to name new segments - /// Counts how often the index has been changed by adding or deleting docs. - /// Starting with the current time in milliseconds forces to create unique version numbers. - int64_t version; +private: + /// Advanced configuration of retry logic in loading segments_N file. + static int32_t defaultGenFileRetryCount; + static int32_t defaultGenFileRetryPauseMsec; + static int32_t defaultGenLookaheadCount; - int64_t generation; // generation of the "segments_N" for the next commit + /// Counts how often the index has been changed by adding or deleting docs. + /// Starting with the current time in milliseconds forces to create unique version numbers. + int64_t version; - int64_t lastGeneration; // generation of the "segments_N" file we last successfully read - // or wrote; this is normally the same as generation except if - // there was an exception that had interrupted a commit + int64_t generation; // generation of the "segments_N" for the next commit - MapStringString userData; // Opaque map that user can specify during IndexWriter::commit + int64_t lastGeneration; // generation of the "segments_N" file we last successfully read + // or wrote; this is normally the same as generation except if + // there was an exception that had interrupted a commit - static MapStringString singletonUserData; + MapStringString userData; // Opaque map that user can specify during IndexWriter::commit - static InfoStreamPtr infoStream; - ChecksumIndexOutputPtr pendingSegnOutput; + static MapStringString singletonUserData; - public: - SegmentInfoPtr info(int32_t i); - String getCurrentSegmentFileName(); - String getNextSegmentFileName(); + static InfoStreamPtr infoStream; + ChecksumIndexOutputPtr pendingSegnOutput; - /// Read a particular segmentFileName. Note that this may throw an IOException if a commit is in process. - void read(const DirectoryPtr& directory, const String& segmentFileName); +public: + SegmentInfoPtr info(int32_t i); + String getCurrentSegmentFileName(); + String getNextSegmentFileName(); - /// This version of read uses the retry logic (for lock-less commits) to find the right segments file to load. - void read(const DirectoryPtr& directory); + /// Read a particular segmentFileName. Note that this may throw an IOException if a commit is in process. + void read(const DirectoryPtr& directory, const String& segmentFileName); - /// Returns a copy of this instance, also copying each SegmentInfo. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + /// This version of read uses the retry logic (for lock-less commits) to find the right segments file to load. + void read(const DirectoryPtr& directory); - /// Version number when this SegmentInfos was generated. - int64_t getVersion(); - int64_t getGeneration(); - int64_t getLastGeneration(); + /// Returns a copy of this instance, also copying each SegmentInfo. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - /// Returns a new SegmentInfos containing the SegmentInfo instances in the specified range first (inclusive) to - /// last (exclusive), so total number of segments returned is last-first. - SegmentInfosPtr range(int32_t first, int32_t last); + /// Version number when this SegmentInfos was generated. + int64_t getVersion(); + int64_t getGeneration(); + int64_t getLastGeneration(); - /// Carry over generation numbers from another SegmentInfos. - void updateGeneration(const SegmentInfosPtr& other); + /// Returns a new SegmentInfos containing the SegmentInfo instances in the specified range first (inclusive) to + /// last (exclusive), so total number of segments returned is last-first. + SegmentInfosPtr range(int32_t first, int32_t last); - void rollbackCommit(const DirectoryPtr& dir); + /// Carry over generation numbers from another SegmentInfos. + void updateGeneration(const SegmentInfosPtr& other); - /// Call this to start a commit. This writes the new segments file, but writes an invalid checksum at the end, so - /// that it is not visible to readers. Once this is called you must call. - /// {@link #finishCommit} to complete the commit or - /// {@link #rollbackCommit} to abort it. - void prepareCommit(const DirectoryPtr& dir); + void rollbackCommit(const DirectoryPtr& dir); - /// Returns all file names referenced by SegmentInfo instances matching the provided Directory (ie files associated - /// with any "external" segments are skipped). The returned collection is recomputed on each invocation. - HashSet files(const DirectoryPtr& dir, bool includeSegmentsFile); + /// Call this to start a commit. This writes the new segments file, but writes an invalid checksum at the end, so + /// that it is not visible to readers. Once this is called you must call. + /// {@link #finishCommit} to complete the commit or + /// {@link #rollbackCommit} to abort it. + void prepareCommit(const DirectoryPtr& dir); - void finishCommit(const DirectoryPtr& dir); + /// Returns all file names referenced by SegmentInfo instances matching the provided Directory (ie files associated + /// with any "external" segments are skipped). The returned collection is recomputed on each invocation. + HashSet files(const DirectoryPtr& dir, bool includeSegmentsFile); - /// Writes & syncs to the Directory dir, taking care to remove the segments file on exception. - void commit(const DirectoryPtr& dir); + void finishCommit(const DirectoryPtr& dir); - String segString(const DirectoryPtr& directory); - MapStringString getUserData(); - void setUserData(MapStringString data); + /// Writes & syncs to the Directory dir, taking care to remove the segments file on exception. + void commit(const DirectoryPtr& dir); - /// Replaces all segments in this instance, but keeps generation, version, counter so that future commits remain - /// write once. - void replace(const SegmentInfosPtr& other); + String segString(const DirectoryPtr& directory); + MapStringString getUserData(); + void setUserData(MapStringString data); - bool hasExternalSegments(const DirectoryPtr& dir); + /// Replaces all segments in this instance, but keeps generation, version, counter so that future commits remain + /// write once. + void replace(const SegmentInfosPtr& other); - static int64_t getCurrentSegmentGeneration(HashSet files); - static int64_t getCurrentSegmentGeneration(const DirectoryPtr& directory); - static String getCurrentSegmentFileName(HashSet files); - static String getCurrentSegmentFileName(const DirectoryPtr& directory); - static int64_t generationFromSegmentsFileName(const String& fileName); + bool hasExternalSegments(const DirectoryPtr& dir); - /// Current version number from segments file. - static int64_t readCurrentVersion(const DirectoryPtr& directory); + static int64_t getCurrentSegmentGeneration(HashSet files); + static int64_t getCurrentSegmentGeneration(const DirectoryPtr& directory); + static String getCurrentSegmentFileName(HashSet files); + static String getCurrentSegmentFileName(const DirectoryPtr& directory); + static int64_t generationFromSegmentsFileName(const String& fileName); - /// Returns userData from latest segments file. - static MapStringString readCurrentUserData(const DirectoryPtr& directory); + /// Current version number from segments file. + static int64_t readCurrentVersion(const DirectoryPtr& directory); - /// If non-null, information about retries when loading the segments file will be printed to this. - static void setInfoStream(const InfoStreamPtr& infoStream); + /// Returns userData from latest segments file. + static MapStringString readCurrentUserData(const DirectoryPtr& directory); - /// Set how many times to try loading the segments.gen file contents to determine current segment generation. This file - /// is only referenced when the primary method (listing the directory) fails. - static void setDefaultGenFileRetryCount(int32_t count); + /// If non-null, information about retries when loading the segments file will be printed to this. + static void setInfoStream(const InfoStreamPtr& infoStream); - /// @see #setDefaultGenFileRetryCount - static int32_t getDefaultGenFileRetryCount(); + /// Set how many times to try loading the segments.gen file contents to determine current segment generation. This file + /// is only referenced when the primary method (listing the directory) fails. + static void setDefaultGenFileRetryCount(int32_t count); - /// Set how many milliseconds to pause in between attempts to load the segments.gen file. - static void setDefaultGenFileRetryPauseMsec(int32_t msec); + /// @see #setDefaultGenFileRetryCount + static int32_t getDefaultGenFileRetryCount(); - /// @see #setDefaultGenFileRetryPauseMsec - static int32_t getDefaultGenFileRetryPauseMsec(); + /// Set how many milliseconds to pause in between attempts to load the segments.gen file. + static void setDefaultGenFileRetryPauseMsec(int32_t msec); - /// Set how many times to try incrementing the gen when loading the segments file. This only runs if the primary - /// (listing directory) and secondary (opening segments.gen file) methods fail to find the segments file. - static void setDefaultGenLookaheadCount(int32_t count); + /// @see #setDefaultGenFileRetryPauseMsec + static int32_t getDefaultGenFileRetryPauseMsec(); - /// @see #setDefaultGenLookaheadCount - static int32_t getDefaultGenLookahedCount(); + /// Set how many times to try incrementing the gen when loading the segments file. This only runs if the primary + /// (listing directory) and secondary (opening segments.gen file) methods fail to find the segments file. + static void setDefaultGenLookaheadCount(int32_t count); - /// @see #setInfoStream - static InfoStreamPtr getInfoStream(); + /// @see #setDefaultGenLookaheadCount + static int32_t getDefaultGenLookahedCount(); - static void message(const String& message); + /// @see #setInfoStream + static InfoStreamPtr getInfoStream(); - protected: - void write(const DirectoryPtr& directory); + static void message(const String& message); + +protected: + void write(const DirectoryPtr& directory); + + friend class FindSegmentsFile; +}; - friend class FindSegmentsFile; - }; } #endif diff --git a/include/SegmentMergeInfo.h b/include/SegmentMergeInfo.h index 6514dc8a..d8b9bfde 100644 --- a/include/SegmentMergeInfo.h +++ b/include/SegmentMergeInfo.h @@ -9,34 +9,34 @@ #include "Term.h" -namespace Lucene -{ - class SegmentMergeInfo : public LuceneObject - { - public: - SegmentMergeInfo(int32_t b, const TermEnumPtr& te, const IndexReaderPtr& r); - virtual ~SegmentMergeInfo(); - - LUCENE_CLASS(SegmentMergeInfo); - - protected: - TermPositionsPtr postings; // use getPositions() - Collection docMap; // use getDocMap() - - public: - TermPtr term; - int32_t base; - int32_t ord; // the position of the segment in a MultiReader - TermEnumPtr termEnum; - IndexReaderWeakPtr _reader; - int32_t delCount; - - public: - Collection getDocMap(); - TermPositionsPtr getPositions(); - bool next(); - void close(); - }; +namespace Lucene { + +class SegmentMergeInfo : public LuceneObject { +public: + SegmentMergeInfo(int32_t b, const TermEnumPtr& te, const IndexReaderPtr& r); + virtual ~SegmentMergeInfo(); + + LUCENE_CLASS(SegmentMergeInfo); + +protected: + TermPositionsPtr postings; // use getPositions() + Collection docMap; // use getDocMap() + +public: + TermPtr term; + int32_t base; + int32_t ord; // the position of the segment in a MultiReader + TermEnumPtr termEnum; + IndexReaderWeakPtr _reader; + int32_t delCount; + +public: + Collection getDocMap(); + TermPositionsPtr getPositions(); + bool next(); + void close(); +}; + } #endif diff --git a/include/SegmentMergeQueue.h b/include/SegmentMergeQueue.h index 573c7dbd..b8817fb0 100644 --- a/include/SegmentMergeQueue.h +++ b/include/SegmentMergeQueue.h @@ -9,22 +9,22 @@ #include "PriorityQueue.h" -namespace Lucene -{ - class SegmentMergeQueue : public PriorityQueue - { - public: - SegmentMergeQueue(int32_t size); - virtual ~SegmentMergeQueue(); - - LUCENE_CLASS(SegmentMergeQueue); - - public: - void close(); - - protected: - virtual bool lessThan(const SegmentMergeInfoPtr& first, const SegmentMergeInfoPtr& second); - }; +namespace Lucene { + +class SegmentMergeQueue : public PriorityQueue { +public: + SegmentMergeQueue(int32_t size); + virtual ~SegmentMergeQueue(); + + LUCENE_CLASS(SegmentMergeQueue); + +public: + void close(); + +protected: + virtual bool lessThan(const SegmentMergeInfoPtr& first, const SegmentMergeInfoPtr& second); +}; + } #endif diff --git a/include/SegmentMerger.h b/include/SegmentMerger.h index 61a71e14..859fab93 100644 --- a/include/SegmentMerger.h +++ b/include/SegmentMerger.h @@ -9,149 +9,147 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// The SegmentMerger class combines two or more Segments, represented by an IndexReader ({@link #add}, into a single - /// Segment. After adding the appropriate readers, call the merge method to combine the segments. - /// - /// If the compoundFile flag is set, then the segments will be merged into a compound file. - /// @see #merge - /// @see #add - class SegmentMerger : public LuceneObject - { - public: - SegmentMerger(const DirectoryPtr& dir, const String& name); - SegmentMerger(const IndexWriterPtr& writer, const String& name, const OneMergePtr& merge); - virtual ~SegmentMerger(); +namespace Lucene { - LUCENE_CLASS(SegmentMerger); +/// The SegmentMerger class combines two or more Segments, represented by an IndexReader ({@link #add}, into a single +/// Segment. After adding the appropriate readers, call the merge method to combine the segments. +/// +/// If the compoundFile flag is set, then the segments will be merged into a compound file. +/// @see #merge +/// @see #add +class SegmentMerger : public LuceneObject { +public: + SegmentMerger(const DirectoryPtr& dir, const String& name); + SegmentMerger(const IndexWriterPtr& writer, const String& name, const OneMergePtr& merge); + virtual ~SegmentMerger(); - protected: - DirectoryPtr directory; - String segment; - int32_t termIndexInterval; + LUCENE_CLASS(SegmentMerger); - Collection readers; - FieldInfosPtr fieldInfos; +protected: + DirectoryPtr directory; + String segment; + int32_t termIndexInterval; - int32_t mergedDocs; - CheckAbortPtr checkAbort; - - /// Whether we should merge doc stores (stored fields and vectors files). When all segments we - /// are merging already share the same doc store files, we don't need to merge the doc stores. - bool mergeDocStores; - - /// Maximum number of contiguous documents to bulk-copy when merging stored fields - static const int32_t MAX_RAW_MERGE_DOCS; - - Collection matchingSegmentReaders; - Collection rawDocLengths; - Collection rawDocLengths2; + Collection readers; + FieldInfosPtr fieldInfos; - SegmentMergeQueuePtr queue; - bool omitTermFreqAndPositions; - - ByteArray payloadBuffer; - Collection< Collection > docMaps; - Collection delCounts; - - public: - /// norms header placeholder - static const uint8_t NORMS_HEADER[]; - static const int32_t NORMS_HEADER_LENGTH; - - public: - bool hasProx(); - - /// Add an IndexReader to the collection of readers that are to be merged - void add(const IndexReaderPtr& reader); - - /// @param i The index of the reader to return - /// @return The i'th reader to be merged - IndexReaderPtr segmentReader(int32_t i); - - /// Merges the readers specified by the {@link #add} method into the directory passed to the constructor. - /// @return The number of documents that were merged - int32_t merge(); - - /// Merges the readers specified by the {@link #add} method into the directory passed to the constructor. - /// @param mergeDocStores if false, we will not merge the stored fields nor vectors files - /// @return The number of documents that were merged - int32_t merge(bool mergeDocStores); - - /// close all IndexReaders that have been added. Should not be called before merge(). - void closeReaders(); - - HashSet getMergedFiles(); - HashSet createCompoundFile(const String& fileName); - - /// @return The number of documents in all of the readers - int32_t mergeFields(); - - Collection< Collection > getDocMaps(); - Collection getDelCounts(); - - protected: - void addIndexed(const IndexReaderPtr& reader, const FieldInfosPtr& fInfos, HashSet names, bool storeTermVectors, - bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool storePayloads, - bool omitTFAndPositions); - - void setMatchingSegmentReaders(); - int32_t copyFieldsWithDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader); - int32_t copyFieldsNoDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader); - - /// Merge the TermVectors from each of the segments into the new one. - void mergeVectors(); - - void copyVectorsWithDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader); - void copyVectorsNoDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader); - - void mergeTerms(); - - void mergeTermInfos(const FormatPostingsFieldsConsumerPtr& consumer); - - /// Process postings from multiple segments all positioned on the same term. Writes out merged entries - /// into freqOutput and the proxOutput streams. - /// @param smis array of segments - /// @param n number of cells in the array actually occupied - /// @return number of documents across all segments where this term was found - int32_t appendPostings(const FormatPostingsTermsConsumerPtr& termsConsumer, Collection smis, int32_t n); + int32_t mergedDocs; + CheckAbortPtr checkAbort; - void mergeNorms(); - }; + /// Whether we should merge doc stores (stored fields and vectors files). When all segments we + /// are merging already share the same doc store files, we don't need to merge the doc stores. + bool mergeDocStores; - class CheckAbort : public LuceneObject - { - public: - CheckAbort(const OneMergePtr& merge, const DirectoryPtr& dir); - virtual ~CheckAbort(); + /// Maximum number of contiguous documents to bulk-copy when merging stored fields + static const int32_t MAX_RAW_MERGE_DOCS; - LUCENE_CLASS(CheckAbort); + Collection matchingSegmentReaders; + Collection rawDocLengths; + Collection rawDocLengths2; - protected: - double workCount; - OneMergePtr merge; - DirectoryWeakPtr _dir; + SegmentMergeQueuePtr queue; + bool omitTermFreqAndPositions; - public: - /// Records the fact that roughly units amount of work have been done since this method was last called. - /// When adding time-consuming code into SegmentMerger, you should test different values for units to - /// ensure that the time in between calls to merge.checkAborted is up to ~ 1 second. - virtual void work(double units); - }; + ByteArray payloadBuffer; + Collection< Collection > docMaps; + Collection delCounts; - class CheckAbortNull : public CheckAbort - { - public: - CheckAbortNull(); - virtual ~CheckAbortNull(); +public: + /// norms header placeholder + static const uint8_t NORMS_HEADER[]; + static const int32_t NORMS_HEADER_LENGTH; - LUCENE_CLASS(CheckAbortNull); +public: + bool hasProx(); + + /// Add an IndexReader to the collection of readers that are to be merged + void add(const IndexReaderPtr& reader); + + /// @param i The index of the reader to return + /// @return The i'th reader to be merged + IndexReaderPtr segmentReader(int32_t i); + + /// Merges the readers specified by the {@link #add} method into the directory passed to the constructor. + /// @return The number of documents that were merged + int32_t merge(); + + /// Merges the readers specified by the {@link #add} method into the directory passed to the constructor. + /// @param mergeDocStores if false, we will not merge the stored fields nor vectors files + /// @return The number of documents that were merged + int32_t merge(bool mergeDocStores); + + /// close all IndexReaders that have been added. Should not be called before merge(). + void closeReaders(); + + HashSet getMergedFiles(); + HashSet createCompoundFile(const String& fileName); + + /// @return The number of documents in all of the readers + int32_t mergeFields(); + + Collection< Collection > getDocMaps(); + Collection getDelCounts(); + +protected: + void addIndexed(const IndexReaderPtr& reader, const FieldInfosPtr& fInfos, HashSet names, bool storeTermVectors, + bool storePositionWithTermVector, bool storeOffsetWithTermVector, bool storePayloads, + bool omitTFAndPositions); + + void setMatchingSegmentReaders(); + int32_t copyFieldsWithDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader); + int32_t copyFieldsNoDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader); + + /// Merge the TermVectors from each of the segments into the new one. + void mergeVectors(); + + void copyVectorsWithDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader); + void copyVectorsNoDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader); + + void mergeTerms(); + + void mergeTermInfos(const FormatPostingsFieldsConsumerPtr& consumer); + + /// Process postings from multiple segments all positioned on the same term. Writes out merged entries + /// into freqOutput and the proxOutput streams. + /// @param smis array of segments + /// @param n number of cells in the array actually occupied + /// @return number of documents across all segments where this term was found + int32_t appendPostings(const FormatPostingsTermsConsumerPtr& termsConsumer, Collection smis, int32_t n); + + void mergeNorms(); +}; + +class CheckAbort : public LuceneObject { +public: + CheckAbort(const OneMergePtr& merge, const DirectoryPtr& dir); + virtual ~CheckAbort(); + + LUCENE_CLASS(CheckAbort); + +protected: + double workCount; + OneMergePtr merge; + DirectoryWeakPtr _dir; + +public: + /// Records the fact that roughly units amount of work have been done since this method was last called. + /// When adding time-consuming code into SegmentMerger, you should test different values for units to + /// ensure that the time in between calls to merge.checkAborted is up to ~ 1 second. + virtual void work(double units); +}; + +class CheckAbortNull : public CheckAbort { +public: + CheckAbortNull(); + virtual ~CheckAbortNull(); + + LUCENE_CLASS(CheckAbortNull); + +public: + /// do nothing + virtual void work(double units); +}; - public: - /// do nothing - virtual void work(double units); - }; } #endif diff --git a/include/SegmentReader.h b/include/SegmentReader.h index 525e283d..445262ac 100644 --- a/include/SegmentReader.h +++ b/include/SegmentReader.h @@ -10,212 +10,212 @@ #include "IndexReader.h" #include "CloseableThreadLocal.h" -namespace Lucene -{ - class LPPAPI SegmentReader : public IndexReader - { - public: - SegmentReader(); - virtual ~SegmentReader(); +namespace Lucene { - LUCENE_CLASS(SegmentReader); +class LPPAPI SegmentReader : public IndexReader { +public: + SegmentReader(); + virtual ~SegmentReader(); - protected: - bool readOnly; + LUCENE_CLASS(SegmentReader); - INTERNAL: - BitVectorPtr deletedDocs; - SegmentReaderRefPtr deletedDocsRef; - CoreReadersPtr core; - FieldsReaderLocalPtr fieldsReaderLocal; - SegmentInfoPtr rollbackSegmentInfo; - CloseableThreadLocal termVectorsLocal; - FieldInfosPtr fieldInfos(); +protected: + bool readOnly; - /// Create a clone from the initial TermVectorsReader and store it in the ThreadLocal. - /// @return TermVectorsReader - TermVectorsReaderPtr getTermVectorsReader(); +INTERNAL: + BitVectorPtr deletedDocs; + SegmentReaderRefPtr deletedDocsRef; + CoreReadersPtr core; + FieldsReaderLocalPtr fieldsReaderLocal; + SegmentInfoPtr rollbackSegmentInfo; + CloseableThreadLocal termVectorsLocal; + FieldInfosPtr fieldInfos(); - TermVectorsReaderPtr getTermVectorsReaderOrig(); - FieldsReaderPtr getFieldsReader(); - MapStringNorm _norms; + /// Create a clone from the initial TermVectorsReader and store it in the ThreadLocal. + /// @return TermVectorsReader + TermVectorsReaderPtr getTermVectorsReader(); - private: - SegmentInfoPtr si; - int32_t readBufferSize; - bool deletedDocsDirty; - bool normsDirty; - int32_t pendingDeleteCount; + TermVectorsReaderPtr getTermVectorsReaderOrig(); + FieldsReaderPtr getFieldsReader(); + MapStringNorm _norms; - bool rollbackHasChanges; - bool rollbackDeletedDocsDirty; - bool rollbackNormsDirty; - int32_t rollbackPendingDeleteCount; +private: + SegmentInfoPtr si; + int32_t readBufferSize; + bool deletedDocsDirty; + bool normsDirty; + int32_t pendingDeleteCount; - // optionally used for the .nrm file shared by multiple norms - IndexInputPtr singleNormStream; - SegmentReaderRefPtr singleNormRef; + bool rollbackHasChanges; + bool rollbackDeletedDocsDirty; + bool rollbackNormsDirty; + int32_t rollbackPendingDeleteCount; - public: - virtual void initialize(); + // optionally used for the .nrm file shared by multiple norms + IndexInputPtr singleNormStream; + SegmentReaderRefPtr singleNormRef; - using IndexReader::document; - using IndexReader::termPositions; +public: + virtual void initialize(); - static SegmentReaderPtr get(bool readOnly, const SegmentInfoPtr& si, int32_t termInfosIndexDivisor); - static SegmentReaderPtr get(bool readOnly, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor); + using IndexReader::document; + using IndexReader::termPositions; - void openDocStores(); + static SegmentReaderPtr get(bool readOnly, const SegmentInfoPtr& si, int32_t termInfosIndexDivisor); + static SegmentReaderPtr get(bool readOnly, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); - SegmentReaderPtr reopenSegment(const SegmentInfoPtr& si, bool doClone, bool openReadOnly); + void openDocStores(); - static bool hasDeletions(const SegmentInfoPtr& si); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual LuceneObjectPtr clone(bool openReadOnly, const LuceneObjectPtr& other = LuceneObjectPtr()); + SegmentReaderPtr reopenSegment(const SegmentInfoPtr& si, bool doClone, bool openReadOnly); - /// Returns true if any documents have been deleted - virtual bool hasDeletions(); + static bool hasDeletions(const SegmentInfoPtr& si); - static bool usesCompoundFile(const SegmentInfoPtr& si); - static bool hasSeparateNorms(const SegmentInfoPtr& si); + /// Returns true if any documents have been deleted + virtual bool hasDeletions(); - HashSet files(); + static bool usesCompoundFile(const SegmentInfoPtr& si); + static bool hasSeparateNorms(const SegmentInfoPtr& si); - /// Returns an enumeration of all the terms in the index. - virtual TermEnumPtr terms(); + HashSet files(); - /// Returns an enumeration of all terms starting at a given term. - virtual TermEnumPtr terms(const TermPtr& t); + /// Returns an enumeration of all the terms in the index. + virtual TermEnumPtr terms(); - /// Get the {@link Document} at the n'th position. - virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); + /// Returns an enumeration of all terms starting at a given term. + virtual TermEnumPtr terms(const TermPtr& t); - /// Returns true if document n has been deleted - virtual bool isDeleted(int32_t n); + /// Get the {@link Document} at the n'th position. + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); - /// Returns an enumeration of all the documents which contain term. - virtual TermDocsPtr termDocs(const TermPtr& term); + /// Returns true if document n has been deleted + virtual bool isDeleted(int32_t n); - /// Returns an unpositioned {@link TermDocs} enumerator. - virtual TermDocsPtr termDocs(); + /// Returns an enumeration of all the documents which contain term. + virtual TermDocsPtr termDocs(const TermPtr& term); - /// Returns an unpositioned {@link TermPositions} enumerator. - virtual TermPositionsPtr termPositions(); + /// Returns an unpositioned {@link TermDocs} enumerator. + virtual TermDocsPtr termDocs(); - /// Returns the number of documents containing the term t. - virtual int32_t docFreq(const TermPtr& t); + /// Returns an unpositioned {@link TermPositions} enumerator. + virtual TermPositionsPtr termPositions(); - /// Returns the number of documents in this index. - virtual int32_t numDocs(); + /// Returns the number of documents containing the term t. + virtual int32_t docFreq(const TermPtr& t); - /// Returns one greater than the largest possible document number. - virtual int32_t maxDoc(); + /// Returns the number of documents in this index. + virtual int32_t numDocs(); - /// Get a list of unique field names that exist in this index and have the specified field option information. - virtual HashSet getFieldNames(FieldOption fieldOption); + /// Returns one greater than the largest possible document number. + virtual int32_t maxDoc(); - /// Returns true if there are norms stored for this field. - virtual bool hasNorms(const String& field); + /// Get a list of unique field names that exist in this index and have the specified field option information. + virtual HashSet getFieldNames(FieldOption fieldOption); - /// Returns the byte-encoded normalization factor for the named field of every document. - virtual ByteArray norms(const String& field); + /// Returns true if there are norms stored for this field. + virtual bool hasNorms(const String& field); - /// Read norms into a pre-allocated array. - virtual void norms(const String& field, ByteArray norms, int32_t offset); + /// Returns the byte-encoded normalization factor for the named field of every document. + virtual ByteArray norms(const String& field); - bool termsIndexLoaded(); + /// Read norms into a pre-allocated array. + virtual void norms(const String& field, ByteArray norms, int32_t offset); - /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, sharing a - /// segment that's still being merged. This method is not thread safe, and relies on the synchronization in IndexWriter - void loadTermsIndex(int32_t termsIndexDivisor); + bool termsIndexLoaded(); - bool normsClosed(); // for testing only - bool normsClosed(const String& field); // for testing only + /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, sharing a + /// segment that's still being merged. This method is not thread safe, and relies on the synchronization in IndexWriter + void loadTermsIndex(int32_t termsIndexDivisor); - /// Return a term frequency vector for the specified document and field. The vector returned contains term - /// numbers and frequencies for all terms in the specified field of this document, if the field had - /// storeTermVector flag set. If the flag was not set, the method returns null. - virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); + bool normsClosed(); // for testing only + bool normsClosed(const String& field); // for testing only - /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays - /// of the {@link TermFreqVector}. - virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + /// Return a term frequency vector for the specified document and field. The vector returned contains term + /// numbers and frequencies for all terms in the specified field of this document, if the field had + /// storeTermVector flag set. If the flag was not set, the method returns null. + virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - /// Map all the term vectors for all fields in a Document - virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); + /// Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays + /// of the {@link TermFreqVector}. + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); - /// Return an array of term frequency vectors for the specified document. The array contains a vector for - /// each vectorized field in the document. Each vector vector contains term numbers and frequencies for all - /// terms in a given vectorized field. If no such fields existed, the method returns null. - virtual Collection getTermFreqVectors(int32_t docNumber); + /// Map all the term vectors for all fields in a Document + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); - /// Return the name of the segment this reader is reading. - String getSegmentName(); + /// Return an array of term frequency vectors for the specified document. The array contains a vector for + /// each vectorized field in the document. Each vector vector contains term numbers and frequencies for all + /// terms in a given vectorized field. If no such fields existed, the method returns null. + virtual Collection getTermFreqVectors(int32_t docNumber); - /// Return the SegmentInfo of the segment this reader is reading. - SegmentInfoPtr getSegmentInfo(); - void setSegmentInfo(const SegmentInfoPtr& info); + /// Return the name of the segment this reader is reading. + String getSegmentName(); - void startCommit(); - void rollbackCommit(); + /// Return the SegmentInfo of the segment this reader is reading. + SegmentInfoPtr getSegmentInfo(); + void setSegmentInfo(const SegmentInfoPtr& info); - /// Returns the directory this index resides in. - virtual DirectoryPtr directory(); + void startCommit(); + void rollbackCommit(); - /// This is necessary so that cloned SegmentReaders (which share the underlying postings data) - /// will map to the same entry in the FieldCache. - virtual LuceneObjectPtr getFieldCacheKey(); - virtual LuceneObjectPtr getDeletesCacheKey(); + /// Returns the directory this index resides in. + virtual DirectoryPtr directory(); - /// Returns the number of unique terms (across all fields) in this reader. - virtual int64_t getUniqueTermCount(); + /// This is necessary so that cloned SegmentReaders (which share the underlying postings data) + /// will map to the same entry in the FieldCache. + virtual LuceneObjectPtr getFieldCacheKey(); + virtual LuceneObjectPtr getDeletesCacheKey(); - static SegmentReaderPtr getOnlySegmentReader(const DirectoryPtr& dir); - static SegmentReaderPtr getOnlySegmentReader(const IndexReaderPtr& reader); + /// Returns the number of unique terms (across all fields) in this reader. + virtual int64_t getUniqueTermCount(); - virtual int32_t getTermInfosIndexDivisor(); + static SegmentReaderPtr getOnlySegmentReader(const DirectoryPtr& dir); + static SegmentReaderPtr getOnlySegmentReader(const IndexReaderPtr& reader); - protected: - bool checkDeletedCounts(); - void loadDeletedDocs(); + virtual int32_t getTermInfosIndexDivisor(); - /// Clones the norm bytes. May be overridden by subclasses. - /// @param bytes Byte array to clone - /// @return New BitVector - virtual ByteArray cloneNormBytes(ByteArray bytes); +protected: + bool checkDeletedCounts(); + void loadDeletedDocs(); - /// Clones the deleteDocs BitVector. May be overridden by subclasses. - /// @param bv BitVector to clone - /// @return New BitVector - virtual BitVectorPtr cloneDeletedDocs(const BitVectorPtr& bv); + /// Clones the norm bytes. May be overridden by subclasses. + /// @param bytes Byte array to clone + /// @return New BitVector + virtual ByteArray cloneNormBytes(ByteArray bytes); - /// Implements commit. - virtual void doCommit(MapStringString commitUserData); + /// Clones the deleteDocs BitVector. May be overridden by subclasses. + /// @param bv BitVector to clone + /// @return New BitVector + virtual BitVectorPtr cloneDeletedDocs(const BitVectorPtr& bv); - virtual void commitChanges(MapStringString commitUserData); + /// Implements commit. + virtual void doCommit(MapStringString commitUserData); - /// Implements close. - virtual void doClose(); + virtual void commitChanges(MapStringString commitUserData); - /// Implements deletion of the document numbered docNum. - /// Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}. - virtual void doDelete(int32_t docNum); + /// Implements close. + virtual void doClose(); - /// Implements actual undeleteAll() in subclass. - virtual void doUndeleteAll(); + /// Implements deletion of the document numbered docNum. + /// Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}. + virtual void doDelete(int32_t docNum); - /// can return null if norms aren't stored - ByteArray getNorms(const String& field); + /// Implements actual undeleteAll() in subclass. + virtual void doUndeleteAll(); - /// Implements setNorm in subclass. - virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + /// can return null if norms aren't stored + ByteArray getNorms(const String& field); - void openNorms(const DirectoryPtr& cfsDir, int32_t readBufferSize); + /// Implements setNorm in subclass. + virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + + void openNorms(const DirectoryPtr& cfsDir, int32_t readBufferSize); + + friend class ReaderPool; + friend class IndexWriter; + friend class Norm; +}; - friend class ReaderPool; - friend class IndexWriter; - friend class Norm; - }; } #endif diff --git a/include/SegmentTermDocs.h b/include/SegmentTermDocs.h index 77c068ae..a3787b83 100644 --- a/include/SegmentTermDocs.h +++ b/include/SegmentTermDocs.h @@ -9,75 +9,75 @@ #include "TermPositions.h" -namespace Lucene -{ - class SegmentTermDocs : public TermPositions, public LuceneObject - { - public: - SegmentTermDocs(const SegmentReaderPtr& parent); - virtual ~SegmentTermDocs(); +namespace Lucene { - LUCENE_CLASS(SegmentTermDocs); +class SegmentTermDocs : public TermPositions, public LuceneObject { +public: + SegmentTermDocs(const SegmentReaderPtr& parent); + virtual ~SegmentTermDocs(); - protected: - SegmentReaderWeakPtr _parent; - IndexInputPtr _freqStream; - int32_t count; - int32_t df; - BitVectorPtr deletedDocs; - int32_t _doc; - int32_t _freq; + LUCENE_CLASS(SegmentTermDocs); - int32_t skipInterval; - int32_t maxSkipLevels; - DefaultSkipListReaderPtr skipListReader; +protected: + SegmentReaderWeakPtr _parent; + IndexInputPtr _freqStream; + int32_t count; + int32_t df; + BitVectorPtr deletedDocs; + int32_t _doc; + int32_t _freq; - int64_t freqBasePointer; - int64_t proxBasePointer; + int32_t skipInterval; + int32_t maxSkipLevels; + DefaultSkipListReaderPtr skipListReader; - int64_t skipPointer; - bool haveSkipped; + int64_t freqBasePointer; + int64_t proxBasePointer; - bool currentFieldStoresPayloads; - bool currentFieldOmitTermFreqAndPositions; + int64_t skipPointer; + bool haveSkipped; - public: - /// Sets this to the data for a term. - virtual void seek(const TermPtr& term); + bool currentFieldStoresPayloads; + bool currentFieldOmitTermFreqAndPositions; - /// Sets this to the data for the current term in a {@link TermEnum}. - virtual void seek(const TermEnumPtr& termEnum); +public: + /// Sets this to the data for a term. + virtual void seek(const TermPtr& term); - virtual void seek(const TermInfoPtr& ti, const TermPtr& term); + /// Sets this to the data for the current term in a {@link TermEnum}. + virtual void seek(const TermEnumPtr& termEnum); - virtual void close(); + virtual void seek(const TermInfoPtr& ti, const TermPtr& term); - /// Returns the current document number. - virtual int32_t doc(); + virtual void close(); - /// Returns the frequency of the term within the current document. - virtual int32_t freq(); + /// Returns the current document number. + virtual int32_t doc(); - /// Moves to the next pair in the enumeration. - virtual bool next(); + /// Returns the frequency of the term within the current document. + virtual int32_t freq(); - /// Optimized implementation. - virtual int32_t read(Collection docs, Collection freqs); + /// Moves to the next pair in the enumeration. + virtual bool next(); - /// Optimized implementation. - virtual bool skipTo(int32_t target); + /// Optimized implementation. + virtual int32_t read(Collection docs, Collection freqs); - /// Used for testing - virtual IndexInputPtr freqStream(); - virtual void freqStream(const IndexInputPtr& freqStream); + /// Optimized implementation. + virtual bool skipTo(int32_t target); - protected: - virtual void skippingDoc(); - virtual int32_t readNoTf(Collection docs, Collection freqs, int32_t length); + /// Used for testing + virtual IndexInputPtr freqStream(); + virtual void freqStream(const IndexInputPtr& freqStream); + +protected: + virtual void skippingDoc(); + virtual int32_t readNoTf(Collection docs, Collection freqs, int32_t length); + + /// Overridden by SegmentTermPositions to skip in prox stream. + virtual void skipProx(int64_t proxPointer, int32_t payloadLength); +}; - /// Overridden by SegmentTermPositions to skip in prox stream. - virtual void skipProx(int64_t proxPointer, int32_t payloadLength); - }; } #endif diff --git a/include/SegmentTermEnum.h b/include/SegmentTermEnum.h index 2dde57c7..fa0672a0 100644 --- a/include/SegmentTermEnum.h +++ b/include/SegmentTermEnum.h @@ -9,80 +9,80 @@ #include "TermEnum.h" -namespace Lucene -{ - class SegmentTermEnum : public TermEnum - { - public: - SegmentTermEnum(); - SegmentTermEnum(const IndexInputPtr& i, const FieldInfosPtr& fis, bool isi); - virtual ~SegmentTermEnum(); +namespace Lucene { - LUCENE_CLASS(SegmentTermEnum); +class SegmentTermEnum : public TermEnum { +public: + SegmentTermEnum(); + SegmentTermEnum(const IndexInputPtr& i, const FieldInfosPtr& fis, bool isi); + virtual ~SegmentTermEnum(); - protected: - IndexInputPtr input; - TermBufferPtr termBuffer; - TermBufferPtr prevBuffer; - TermBufferPtr scanBuffer; // used for scanning + LUCENE_CLASS(SegmentTermEnum); - TermInfoPtr _termInfo; +protected: + IndexInputPtr input; + TermBufferPtr termBuffer; + TermBufferPtr prevBuffer; + TermBufferPtr scanBuffer; // used for scanning - int32_t format; - bool isIndex; - int32_t formatM1SkipInterval; + TermInfoPtr _termInfo; - public: - FieldInfosPtr fieldInfos; - int64_t size; - int64_t position; + int32_t format; + bool isIndex; + int32_t formatM1SkipInterval; - int64_t indexPointer; - int32_t indexInterval; - int32_t skipInterval; - int32_t maxSkipLevels; +public: + FieldInfosPtr fieldInfos; + int64_t size; + int64_t position; - public: - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + int64_t indexPointer; + int32_t indexInterval; + int32_t skipInterval; + int32_t maxSkipLevels; - void seek(int64_t pointer, int64_t p, const TermPtr& t, const TermInfoPtr& ti); +public: + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - /// Increments the enumeration to the next element. True if one exists. - virtual bool next(); + void seek(int64_t pointer, int64_t p, const TermPtr& t, const TermInfoPtr& ti); - /// Optimized scan, without allocating new terms. Return number of invocations to next(). - int32_t scanTo(const TermPtr& term); + /// Increments the enumeration to the next element. True if one exists. + virtual bool next(); - /// Returns the current Term in the enumeration. - /// Initially invalid, valid after next() called for the first time. - virtual TermPtr term(); + /// Optimized scan, without allocating new terms. Return number of invocations to next(). + int32_t scanTo(const TermPtr& term); - /// Returns the previous Term enumerated. Initially null. - TermPtr prev(); + /// Returns the current Term in the enumeration. + /// Initially invalid, valid after next() called for the first time. + virtual TermPtr term(); - /// Returns the current TermInfo in the enumeration. - /// Initially invalid, valid after next() called for the first time. - TermInfoPtr termInfo(); + /// Returns the previous Term enumerated. Initially null. + TermPtr prev(); - /// Sets the argument to the current TermInfo in the enumeration. - /// Initially invalid, valid after next() called for the first time. - void termInfo(const TermInfoPtr& ti); + /// Returns the current TermInfo in the enumeration. + /// Initially invalid, valid after next() called for the first time. + TermInfoPtr termInfo(); - /// Returns the docFreq of the current Term in the enumeration. - /// Initially invalid, valid after next() called for the first time. - virtual int32_t docFreq(); + /// Sets the argument to the current TermInfo in the enumeration. + /// Initially invalid, valid after next() called for the first time. + void termInfo(const TermInfoPtr& ti); - /// Returns the freqPointer from the current TermInfo in the enumeration. - /// Initially invalid, valid after next() called for the first time. - int64_t freqPointer(); + /// Returns the docFreq of the current Term in the enumeration. + /// Initially invalid, valid after next() called for the first time. + virtual int32_t docFreq(); - /// Returns the proxPointer from the current TermInfo in the enumeration. - /// Initially invalid, valid after next() called for the first time. - int64_t proxPointer(); + /// Returns the freqPointer from the current TermInfo in the enumeration. + /// Initially invalid, valid after next() called for the first time. + int64_t freqPointer(); + + /// Returns the proxPointer from the current TermInfo in the enumeration. + /// Initially invalid, valid after next() called for the first time. + int64_t proxPointer(); + + /// Closes the enumeration to further activity, freeing resources. + virtual void close(); +}; - /// Closes the enumeration to further activity, freeing resources. - virtual void close(); - }; } #endif diff --git a/include/SegmentTermPositionVector.h b/include/SegmentTermPositionVector.h index 68414932..1ff31e5e 100644 --- a/include/SegmentTermPositionVector.h +++ b/include/SegmentTermPositionVector.h @@ -9,34 +9,34 @@ #include "SegmentTermVector.h" -namespace Lucene -{ - class SegmentTermPositionVector : public SegmentTermVector - { - public: - SegmentTermPositionVector(const String& field, Collection terms, Collection termFreqs, - Collection< Collection > positions, Collection< Collection > offsets); - virtual ~SegmentTermPositionVector(); - - LUCENE_CLASS(SegmentTermPositionVector); - - protected: - Collection< Collection > positions; - Collection< Collection > offsets; - - protected: - static const Collection EMPTY_TERM_POS(); - - public: - /// Returns an array of TermVectorOffsetInfo in which the term is found. - /// @param index The position in the array to get the offsets from - /// @return An array of TermVectorOffsetInfo objects or the empty list - virtual Collection getOffsets(int32_t index); - - /// Returns an array of positions in which the term is found. - /// Terms are identified by the index at which its number appears in the term String array obtained from the indexOf method. - virtual Collection getTermPositions(int32_t index); - }; +namespace Lucene { + +class SegmentTermPositionVector : public SegmentTermVector { +public: + SegmentTermPositionVector(const String& field, Collection terms, Collection termFreqs, + Collection< Collection > positions, Collection< Collection > offsets); + virtual ~SegmentTermPositionVector(); + + LUCENE_CLASS(SegmentTermPositionVector); + +protected: + Collection< Collection > positions; + Collection< Collection > offsets; + +protected: + static const Collection EMPTY_TERM_POS(); + +public: + /// Returns an array of TermVectorOffsetInfo in which the term is found. + /// @param index The position in the array to get the offsets from + /// @return An array of TermVectorOffsetInfo objects or the empty list + virtual Collection getOffsets(int32_t index); + + /// Returns an array of positions in which the term is found. + /// Terms are identified by the index at which its number appears in the term String array obtained from the indexOf method. + virtual Collection getTermPositions(int32_t index); +}; + } #endif diff --git a/include/SegmentTermPositions.h b/include/SegmentTermPositions.h index e8433881..82904039 100644 --- a/include/SegmentTermPositions.h +++ b/include/SegmentTermPositions.h @@ -9,72 +9,72 @@ #include "SegmentTermDocs.h" -namespace Lucene -{ - class SegmentTermPositions : public SegmentTermDocs - { - public: - SegmentTermPositions(const SegmentReaderPtr& parent); - virtual ~SegmentTermPositions(); +namespace Lucene { - LUCENE_CLASS(SegmentTermPositions); +class SegmentTermPositions : public SegmentTermDocs { +public: + SegmentTermPositions(const SegmentReaderPtr& parent); + virtual ~SegmentTermPositions(); - protected: - IndexInputPtr proxStream; - int32_t proxCount; - int32_t position; + LUCENE_CLASS(SegmentTermPositions); - /// The current payload length - int32_t payloadLength; +protected: + IndexInputPtr proxStream; + int32_t proxCount; + int32_t position; - /// Indicates whether the payload of the current position has been read from the proxStream yet - bool needToLoadPayload; + /// The current payload length + int32_t payloadLength; - // these variables are being used to remember information for a lazy skip - int64_t lazySkipPointer; - int32_t lazySkipProxCount; + /// Indicates whether the payload of the current position has been read from the proxStream yet + bool needToLoadPayload; - public: - using SegmentTermDocs::seek; + // these variables are being used to remember information for a lazy skip + int64_t lazySkipPointer; + int32_t lazySkipProxCount; - virtual void seek(const TermInfoPtr& ti, const TermPtr& term); - virtual void close(); +public: + using SegmentTermDocs::seek; - /// Returns next position in the current document. - virtual int32_t nextPosition(); + virtual void seek(const TermInfoPtr& ti, const TermPtr& term); + virtual void close(); - /// Moves to the next pair in the enumeration. - virtual bool next(); + /// Returns next position in the current document. + virtual int32_t nextPosition(); - /// Not supported - virtual int32_t read(Collection docs, Collection freqs); + /// Moves to the next pair in the enumeration. + virtual bool next(); - /// Returns the length of the payload at the current term position. - virtual int32_t getPayloadLength(); + /// Not supported + virtual int32_t read(Collection docs, Collection freqs); - /// Returns the payload data at the current term position. - virtual ByteArray getPayload(ByteArray data, int32_t offset); + /// Returns the length of the payload at the current term position. + virtual int32_t getPayloadLength(); - /// Checks if a payload can be loaded at this position. - virtual bool isPayloadAvailable(); + /// Returns the payload data at the current term position. + virtual ByteArray getPayload(ByteArray data, int32_t offset); - protected: - int32_t readDeltaPosition(); + /// Checks if a payload can be loaded at this position. + virtual bool isPayloadAvailable(); - virtual void skippingDoc(); +protected: + int32_t readDeltaPosition(); - virtual void skipProx(int64_t proxPointer, int32_t payloadLength); - virtual void skipPositions(int32_t n); - virtual void skipPayload(); + virtual void skippingDoc(); + + virtual void skipProx(int64_t proxPointer, int32_t payloadLength); + virtual void skipPositions(int32_t n); + virtual void skipPayload(); + + /// It is not always necessary to move the prox pointer to a new document after the freq pointer has + /// been moved. Consider for example a phrase query with two terms: the freq pointer for term 1 has to + /// move to document x to answer the question if the term occurs in that document. But only if term 2 + /// also matches document x, the positions have to be read to figure out if term 1 and term 2 appear next + /// to each other in document x and thus satisfy the query. So we move the prox pointer lazily to the + /// document as soon as positions are requested. + virtual void lazySkip(); +}; - /// It is not always necessary to move the prox pointer to a new document after the freq pointer has - /// been moved. Consider for example a phrase query with two terms: the freq pointer for term 1 has to - /// move to document x to answer the question if the term occurs in that document. But only if term 2 - /// also matches document x, the positions have to be read to figure out if term 1 and term 2 appear next - /// to each other in document x and thus satisfy the query. So we move the prox pointer lazily to the - /// document as soon as positions are requested. - virtual void lazySkip(); - }; } #endif diff --git a/include/SegmentTermVector.h b/include/SegmentTermVector.h index 47dbdc63..cf534559 100644 --- a/include/SegmentTermVector.h +++ b/include/SegmentTermVector.h @@ -9,43 +9,43 @@ #include "TermPositionVector.h" -namespace Lucene -{ - class SegmentTermVector : public TermPositionVector, public LuceneObject - { - public: - SegmentTermVector(const String& field, Collection terms, Collection termFreqs); - virtual ~SegmentTermVector(); +namespace Lucene { - LUCENE_CLASS(SegmentTermVector); +class SegmentTermVector : public TermPositionVector, public LuceneObject { +public: + SegmentTermVector(const String& field, Collection terms, Collection termFreqs); + virtual ~SegmentTermVector(); - protected: - String field; - Collection terms; - Collection termFreqs; + LUCENE_CLASS(SegmentTermVector); - public: - /// @return The number of the field this vector is associated with - virtual String getField(); +protected: + String field; + Collection terms; + Collection termFreqs; - virtual String toString(); +public: + /// @return The number of the field this vector is associated with + virtual String getField(); - /// @return The number of terms in the term vector. - virtual int32_t size(); + virtual String toString(); - /// @return An Array of term texts in ascending order. - virtual Collection getTerms(); + /// @return The number of terms in the term vector. + virtual int32_t size(); - /// @return Array of term frequencies. - virtual Collection getTermFrequencies(); + /// @return An Array of term texts in ascending order. + virtual Collection getTerms(); - /// Return an index in the term numbers array returned from getTerms at which the term with the - /// specified term appears. - virtual int32_t indexOf(const String& term); + /// @return Array of term frequencies. + virtual Collection getTermFrequencies(); + + /// Return an index in the term numbers array returned from getTerms at which the term with the + /// specified term appears. + virtual int32_t indexOf(const String& term); + + /// Just like indexOf(int) but searches for a number of terms at the same time. + virtual Collection indexesOf(Collection termNumbers, int32_t start, int32_t length); +}; - /// Just like indexOf(int) but searches for a number of terms at the same time. - virtual Collection indexesOf(Collection termNumbers, int32_t start, int32_t length); - }; } #endif diff --git a/include/SegmentWriteState.h b/include/SegmentWriteState.h index 46003a51..26000787 100644 --- a/include/SegmentWriteState.h +++ b/include/SegmentWriteState.h @@ -9,31 +9,31 @@ #include "LuceneObject.h" -namespace Lucene -{ - class SegmentWriteState : public LuceneObject - { - public: - SegmentWriteState(const DocumentsWriterPtr& docWriter, const DirectoryPtr& directory, const String& segmentName, - const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, - int32_t termIndexInterval); - virtual ~SegmentWriteState(); - - LUCENE_CLASS(SegmentWriteState); - - public: - DocumentsWriterWeakPtr _docWriter; - DirectoryPtr directory; - String segmentName; - String docStoreSegmentName; - int32_t numDocs; - int32_t termIndexInterval; - int32_t numDocsInStore; - HashSet flushedFiles; - - public: - String segmentFileName(const String& ext); - }; +namespace Lucene { + +class SegmentWriteState : public LuceneObject { +public: + SegmentWriteState(const DocumentsWriterPtr& docWriter, const DirectoryPtr& directory, const String& segmentName, + const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, + int32_t termIndexInterval); + virtual ~SegmentWriteState(); + + LUCENE_CLASS(SegmentWriteState); + +public: + DocumentsWriterWeakPtr _docWriter; + DirectoryPtr directory; + String segmentName; + String docStoreSegmentName; + int32_t numDocs; + int32_t termIndexInterval; + int32_t numDocsInStore; + HashSet flushedFiles; + +public: + String segmentFileName(const String& ext); +}; + } #endif diff --git a/include/SerialMergeScheduler.h b/include/SerialMergeScheduler.h index bb0f18a3..484866cf 100644 --- a/include/SerialMergeScheduler.h +++ b/include/SerialMergeScheduler.h @@ -9,24 +9,24 @@ #include "MergeScheduler.h" -namespace Lucene -{ - /// A {@link MergeScheduler} that simply does each merge sequentially, using the current thread. - class LPPAPI SerialMergeScheduler : public MergeScheduler - { - public: - virtual ~SerialMergeScheduler(); - - LUCENE_CLASS(SerialMergeScheduler); - - public: - /// Just do the merges in sequence. We do this "synchronized" so that even if the application is using - /// multiple threads, only one merge may run at a time. - virtual void merge(const IndexWriterPtr& writer); - - /// Close this MergeScheduler. - virtual void close(); - }; +namespace Lucene { + +/// A {@link MergeScheduler} that simply does each merge sequentially, using the current thread. +class LPPAPI SerialMergeScheduler : public MergeScheduler { +public: + virtual ~SerialMergeScheduler(); + + LUCENE_CLASS(SerialMergeScheduler); + +public: + /// Just do the merges in sequence. We do this "synchronized" so that even if the application is using + /// multiple threads, only one merge may run at a time. + virtual void merge(const IndexWriterPtr& writer); + + /// Close this MergeScheduler. + virtual void close(); +}; + } #endif diff --git a/include/Set.h b/include/Set.h index 17a688e7..7282cc96 100644 --- a/include/Set.h +++ b/include/Set.h @@ -10,146 +10,124 @@ #include #include "LuceneSync.h" -namespace Lucene -{ - /// Utility template class to handle set based collections that can be safely copied and shared - template < class TYPE, class LESS = std::less > - class Set : public LuceneSync - { - public: - typedef Set this_type; - typedef std::set set_type; - typedef typename set_type::iterator iterator; - typedef typename set_type::const_iterator const_iterator; - typedef TYPE value_type; - - virtual ~Set() - { - } - - protected: - boost::shared_ptr setContainer; - - public: - static this_type newInstance() - { - this_type instance; - instance.setContainer = Lucene::newInstance(); - return instance; - } - - template - static this_type newInstance(ITER first, ITER last) - { - this_type instance; - instance.setContainer = Lucene::newInstance(first, last); - return instance; - } - - void reset() - { - setContainer.reset(); - } - - int32_t size() const - { - return (int32_t)setContainer->size(); - } - - bool empty() const - { - return setContainer->empty(); - } +namespace Lucene { + +/// Utility template class to handle set based collections that can be safely copied and shared +template < class TYPE, class LESS = std::less > +class Set : public LuceneSync { +public: + typedef Set this_type; + typedef std::set set_type; + typedef typename set_type::iterator iterator; + typedef typename set_type::const_iterator const_iterator; + typedef TYPE value_type; + + virtual ~Set() { + } + +protected: + boost::shared_ptr setContainer; + +public: + static this_type newInstance() { + this_type instance; + instance.setContainer = Lucene::newInstance(); + return instance; + } + + template + static this_type newInstance(ITER first, ITER last) { + this_type instance; + instance.setContainer = Lucene::newInstance(first, last); + return instance; + } + + void reset() { + setContainer.reset(); + } + + int32_t size() const { + return (int32_t)setContainer->size(); + } + + bool empty() const { + return setContainer->empty(); + } + + void clear() { + setContainer->clear(); + } + + iterator begin() { + return setContainer->begin(); + } + + iterator end() { + return setContainer->end(); + } + + const_iterator begin() const { + return setContainer->begin(); + } + + const_iterator end() const { + return setContainer->end(); + } + + bool add(const TYPE& type) { + return setContainer->insert(type).second; + } + + template + void addAll(ITER first, ITER last) { + setContainer->insert(first, last); + } + + bool remove(const TYPE& type) { + return (setContainer->erase(type) > 0); + } + + iterator find(const TYPE& type) { + return setContainer->find(type); + } + + bool contains(const TYPE& type) const { + return (setContainer->find(type) != setContainer->end()); + } + + bool equals(const this_type& other) const { + return equals(other, std::equal_to()); + } + + template + bool equals(const this_type& other, PRED comp) const { + if (setContainer->size() != other.setContainer->size()) { + return false; + } + return std::equal(setContainer->begin(), setContainer->end(), other.setContainer->begin(), comp); + } + + void swap(this_type& other) { + setContainer.swap(other->setContainer); + } + + operator bool() const { + return setContainer.get() != NULL; + } + + bool operator! () const { + return !setContainer; + } + + bool operator== (const this_type& other) { + return (setContainer == other.setContainer); + } + + bool operator!= (const this_type& other) { + return (setContainer != other.setContainer); + } +}; - void clear() - { - setContainer->clear(); - } - - iterator begin() - { - return setContainer->begin(); - } - - iterator end() - { - return setContainer->end(); - } - - const_iterator begin() const - { - return setContainer->begin(); - } - - const_iterator end() const - { - return setContainer->end(); - } - - bool add(const TYPE& type) - { - return setContainer->insert(type).second; - } - - template - void addAll(ITER first, ITER last) - { - setContainer->insert(first, last); - } - - bool remove(const TYPE& type) - { - return (setContainer->erase(type) > 0); - } - - iterator find(const TYPE& type) - { - return setContainer->find(type); - } - - bool contains(const TYPE& type) const - { - return (setContainer->find(type) != setContainer->end()); - } - - bool equals(const this_type& other) const - { - return equals(other, std::equal_to()); - } - - template - bool equals(const this_type& other, PRED comp) const - { - if (setContainer->size() != other.setContainer->size()) - return false; - return std::equal(setContainer->begin(), setContainer->end(), other.setContainer->begin(), comp); - } - - void swap(this_type& other) - { - setContainer.swap(other->setContainer); - } - - operator bool() const - { - return setContainer.get() != NULL; - } - - bool operator! () const - { - return !setContainer; - } - - bool operator== (const this_type& other) - { - return (setContainer == other.setContainer); - } - - bool operator!= (const this_type& other) - { - return (setContainer != other.setContainer); - } - }; } #endif diff --git a/include/SetBasedFieldSelector.h b/include/SetBasedFieldSelector.h index 181b6c4e..db4ed5e5 100644 --- a/include/SetBasedFieldSelector.h +++ b/include/SetBasedFieldSelector.h @@ -9,34 +9,34 @@ #include "FieldSelector.h" -namespace Lucene -{ - /// Declare what fields to load normally and what fields to load lazily - class LPPAPI SetBasedFieldSelector : public FieldSelector - { - public: - /// Pass in the Set of {@link Field} names to load and the Set of {@link Field} names to load lazily. - /// If both are null, the Document will not have any {@link Field} on it. - /// @param fieldsToLoad A Set of {@link String} field names to load. May be empty, but not null - /// @param lazyFieldsToLoad A Set of {@link String} field names to load lazily. May be empty, but not null - SetBasedFieldSelector(HashSet fieldsToLoad, HashSet lazyFieldsToLoad); - - virtual ~SetBasedFieldSelector(); - - LUCENE_CLASS(SetBasedFieldSelector); - - protected: - HashSet fieldsToLoad; - HashSet lazyFieldsToLoad; - - public: - /// Indicate whether to load the field with the given name or not. If the {@link Field#name()} is not in - /// either of the initializing Sets, then {@link FieldSelectorResult#NO_LOAD} is returned. If a Field name - /// is in both fieldsToLoad and lazyFieldsToLoad, lazy has precedence. - /// @param fieldName The {@link Field} name to check - /// @return The {@link FieldSelectorResult} - virtual FieldSelectorResult accept(const String& fieldName); - }; +namespace Lucene { + +/// Declare what fields to load normally and what fields to load lazily +class LPPAPI SetBasedFieldSelector : public FieldSelector { +public: + /// Pass in the Set of {@link Field} names to load and the Set of {@link Field} names to load lazily. + /// If both are null, the Document will not have any {@link Field} on it. + /// @param fieldsToLoad A Set of {@link String} field names to load. May be empty, but not null + /// @param lazyFieldsToLoad A Set of {@link String} field names to load lazily. May be empty, but not null + SetBasedFieldSelector(HashSet fieldsToLoad, HashSet lazyFieldsToLoad); + + virtual ~SetBasedFieldSelector(); + + LUCENE_CLASS(SetBasedFieldSelector); + +protected: + HashSet fieldsToLoad; + HashSet lazyFieldsToLoad; + +public: + /// Indicate whether to load the field with the given name or not. If the {@link Field#name()} is not in + /// either of the initializing Sets, then {@link FieldSelectorResult#NO_LOAD} is returned. If a Field name + /// is in both fieldsToLoad and lazyFieldsToLoad, lazy has precedence. + /// @param fieldName The {@link Field} name to check + /// @return The {@link FieldSelectorResult} + virtual FieldSelectorResult accept(const String& fieldName); +}; + } #endif diff --git a/include/Similarity.h b/include/Similarity.h index 20913205..d34f8aa3 100644 --- a/include/Similarity.h +++ b/include/Similarity.h @@ -9,608 +9,608 @@ #include "Explanation.h" -namespace Lucene -{ - /// Scoring API. - /// - /// Similarity defines the components of Lucene scoring. Overriding computation of these components is - /// a convenient way to alter Lucene scoring. - /// - /// Suggested reading: - /// Introduction To Information Retrieval, Chapter 6. - /// - /// The following describes how Lucene scoring evolves from underlying information retrieval models to - /// (efficient) implementation. We first brief on VSM Score, then derive from it Lucene's Conceptual Scoring - /// Formula, from which, finally, evolves Lucene's Practical Scoring Function (the latter is connected directly - /// with Lucene classes and methods). - /// - /// Lucene combines Boolean model (BM) of - /// Information Retrieval with Vector Space Model - /// (VSM) of Information Retrieval - documents "approved" by BM are scored by VSM. - /// - /// In VSM, documents and queries are represented as weighted vectors in a multi-dimensional space, where each - /// distinct index term is a dimension, and weights are Tf-idf - /// values. - /// - /// VSM does not require weights to be Tf-idf values, but Tf-idf values are believed to produce search results - /// of high quality, and so Lucene is using Tf-idf. Tf and Idf are described in more detail below, but for now, - /// for completion, let's just say that for given term t and document (or query) x, Tf(t,x) varies with the - /// number of occurrences of term t in x (when one increases so does the other) and idf(t) similarly varies with - /// the inverse of the number of index documents containing term t. - /// - /// VSM score of document d for query q is the Cosine - /// Similarity of the weighted query vectors V(q) and V(d): - /// - ///
       
      - /// - /// - /// - ///
      - /// - /// - ///
      - /// - /// - /// - /// - /// - ///
      - /// cosine-similarity(q,d)   =   - /// - /// - /// - /// - /// - ///
      V(q) · V(d)
      –––––––––
      |V(q)| |V(d)|
      - ///
      - ///
      - ///
      - ///
      VSM Score
      - ///
      - ///
       
      - /// - /// Where V(q) · V(d) is the dot product of the - /// weighted vectors, and |V(q)| and |V(d)| are their - /// Euclidean norms. - /// - /// Note: the above equation can be viewed as the dot product of the normalized weighted vectors, in the sense - /// that dividing V(q) by its euclidean norm is normalizing it to a unit vector. - /// - /// Lucene refines VSM score for both search quality and usability: - ///
        - ///
      • Normalizing V(d) to the unit vector is known to be problematic in that it removes all document length - /// information. For some documents removing this info is probably ok, eg. a document made by duplicating a - /// certain paragraph 10 times, especially if that paragraph is made of distinct terms. But for a document which - /// contains no duplicated paragraphs, this might be wrong. To avoid this problem, a different document length - /// normalization factor is used, which normalizes to a vector equal to or larger than the unit vector: - /// doc-len-norm(d). - ///
      • - ///
      • At indexing, users can specify that certain documents are more important than others, by assigning a - /// document boost. For this, the score of each document is also multiplied by its boost value doc-boost(d). - ///
      • - ///
      • Lucene is field based, hence each query term applies to a single field, document length normalization - /// is by the length of the certain field, and in addition to document boost there are also document fields - /// boosts. - ///
      • - ///
      • The same field can be added to a document during indexing several times, and so the boost of that field - /// is the multiplication of the boosts of the separate additions (or parts) of that field within the document. - ///
      • - ///
      • At search time users can specify boosts to each query, sub-query, and each query term, hence the - /// contribution of a query term to the score of a document is multiplied by the boost of that query term - /// query-boost(q). - ///
      • - ///
      • A document may match a multi term query without containing all the terms of that query (this is correct - /// for some of the queries), and users can further reward documents matching more query terms through a - /// coordination factor, which is usually larger when more terms are matched: coord-factor(q,d). - ///
      • - ///
      - /// - /// Under the simplifying assumption of a single field in the index, we get Lucene's Conceptual scoring formula: - /// - ///
       
      - /// - /// - /// - ///
      - /// - /// - ///
      - /// - /// - /// - /// - /// - /// - ///
      - /// score(q,d)   =   - /// coord-factor(q,d) ·   - /// query-boost(q) ·   - /// - /// - /// - /// - /// - ///
      V(q) · V(d)
      –––––––––
      |V(q)|
      - ///
      - ///   ·   doc-len-norm(d) - ///   ·   doc-boost(d) - ///
      - ///
      - ///
      - ///
      Lucene Conceptual Scoring Formula
      - ///
      - ///
       
      - /// - /// The conceptual formula is a simplification in the sense that (1) terms and documents are fielded and (2) - /// boosts are usually per query term rather than per query. - /// - /// We now describe how Lucene implements this conceptual scoring formula, and derive from it Lucene's Practical - /// Scoring Function. - /// - /// For efficient score computation some scoring components are computed and aggregated in advance: - ///
        - ///
      • Query-boost for the query (actually for each query term) is known when search starts. - ///
      • - ///
      • Query Euclidean norm |V(q)| can be computed when search starts, as it is independent of the document - /// being scored. From search optimization perspective, it is a valid question why bother to normalize the - /// query at all, because all scored documents will be multiplied by the same |V(q)|, and hence documents ranks - /// (their order by score) will not be affected by this normalization. There are two good reasons to keep this - /// normalization: - ///
          - ///
        • Recall that Cosine Similarity can be used - /// find how similar two documents are. One can use Lucene for eg. clustering, and use a document as a query to - /// compute its similarity to other documents. In this use case it is important that the score of document d3 - /// for query d1 is comparable to the score of document d3 for query d2. In other words, scores of a document for - /// two distinct queries should be comparable. There are other applications that may require this. And this is - /// exactly what normalizing the query vector V(q) provides: comparability (to a certain extent) of two or more - /// queries. - ///
        • - ///
        • Applying query normalization on the scores helps to keep the scores around the unit vector, hence preventing - /// loss of score data because of floating point precision limitations. - ///
        • - ///
        - ///
      • - ///
      • Document length norm doc-len-norm(d) and document boost doc-boost(d) are known at indexing time. They are - /// computed in advance and their multiplication is saved as a single value in the index: norm(d). (In the equations - /// below, norm(t in d) means norm(field(t) in doc d) where field(t) is the field associated with term t.) - ///
      • - ///
      +namespace Lucene { + +/// Scoring API. +/// +/// Similarity defines the components of Lucene scoring. Overriding computation of these components is +/// a convenient way to alter Lucene scoring. +/// +/// Suggested reading: +/// Introduction To Information Retrieval, Chapter 6. +/// +/// The following describes how Lucene scoring evolves from underlying information retrieval models to +/// (efficient) implementation. We first brief on VSM Score, then derive from it Lucene's Conceptual Scoring +/// Formula, from which, finally, evolves Lucene's Practical Scoring Function (the latter is connected directly +/// with Lucene classes and methods). +/// +/// Lucene combines Boolean model (BM) of +/// Information Retrieval with Vector Space Model +/// (VSM) of Information Retrieval - documents "approved" by BM are scored by VSM. +/// +/// In VSM, documents and queries are represented as weighted vectors in a multi-dimensional space, where each +/// distinct index term is a dimension, and weights are Tf-idf +/// values. +/// +/// VSM does not require weights to be Tf-idf values, but Tf-idf values are believed to produce search results +/// of high quality, and so Lucene is using Tf-idf. Tf and Idf are described in more detail below, but for now, +/// for completion, let's just say that for given term t and document (or query) x, Tf(t,x) varies with the +/// number of occurrences of term t in x (when one increases so does the other) and idf(t) similarly varies with +/// the inverse of the number of index documents containing term t. +/// +/// VSM score of document d for query q is the Cosine +/// Similarity of the weighted query vectors V(q) and V(d): +/// +///
       
      +/// +/// +/// +///
      +/// +/// +///
      +/// +/// +/// +/// +/// +///
      +/// cosine-similarity(q,d)   =   +/// +/// +/// +/// +/// +///
      V(q) · V(d)
      –––––––––
      |V(q)| |V(d)|
      +///
      +///
      +///
      +///
      VSM Score
      +///
      +///
       
      +/// +/// Where V(q) · V(d) is the dot product of the +/// weighted vectors, and |V(q)| and |V(d)| are their +/// Euclidean norms. +/// +/// Note: the above equation can be viewed as the dot product of the normalized weighted vectors, in the sense +/// that dividing V(q) by its euclidean norm is normalizing it to a unit vector. +/// +/// Lucene refines VSM score for both search quality and usability: +///
        +///
      • Normalizing V(d) to the unit vector is known to be problematic in that it removes all document length +/// information. For some documents removing this info is probably ok, eg. a document made by duplicating a +/// certain paragraph 10 times, especially if that paragraph is made of distinct terms. But for a document which +/// contains no duplicated paragraphs, this might be wrong. To avoid this problem, a different document length +/// normalization factor is used, which normalizes to a vector equal to or larger than the unit vector: +/// doc-len-norm(d). +///
      • +///
      • At indexing, users can specify that certain documents are more important than others, by assigning a +/// document boost. For this, the score of each document is also multiplied by its boost value doc-boost(d). +///
      • +///
      • Lucene is field based, hence each query term applies to a single field, document length normalization +/// is by the length of the certain field, and in addition to document boost there are also document fields +/// boosts. +///
      • +///
      • The same field can be added to a document during indexing several times, and so the boost of that field +/// is the multiplication of the boosts of the separate additions (or parts) of that field within the document. +///
      • +///
      • At search time users can specify boosts to each query, sub-query, and each query term, hence the +/// contribution of a query term to the score of a document is multiplied by the boost of that query term +/// query-boost(q). +///
      • +///
      • A document may match a multi term query without containing all the terms of that query (this is correct +/// for some of the queries), and users can further reward documents matching more query terms through a +/// coordination factor, which is usually larger when more terms are matched: coord-factor(q,d). +///
      • +///
      +/// +/// Under the simplifying assumption of a single field in the index, we get Lucene's Conceptual scoring formula: +/// +///
       
      +/// +/// +/// +///
      +/// +/// +///
      +/// +/// +/// +/// +/// +/// +///
      +/// score(q,d)   =   +/// coord-factor(q,d) ·   +/// query-boost(q) ·   +/// +/// +/// +/// +/// +///
      V(q) · V(d)
      –––––––––
      |V(q)|
      +///
      +///   ·   doc-len-norm(d) +///   ·   doc-boost(d) +///
      +///
      +///
      +///
      Lucene Conceptual Scoring Formula
      +///
      +///
       
      +/// +/// The conceptual formula is a simplification in the sense that (1) terms and documents are fielded and (2) +/// boosts are usually per query term rather than per query. +/// +/// We now describe how Lucene implements this conceptual scoring formula, and derive from it Lucene's Practical +/// Scoring Function. +/// +/// For efficient score computation some scoring components are computed and aggregated in advance: +///
        +///
      • Query-boost for the query (actually for each query term) is known when search starts. +///
      • +///
      • Query Euclidean norm |V(q)| can be computed when search starts, as it is independent of the document +/// being scored. From search optimization perspective, it is a valid question why bother to normalize the +/// query at all, because all scored documents will be multiplied by the same |V(q)|, and hence documents ranks +/// (their order by score) will not be affected by this normalization. There are two good reasons to keep this +/// normalization: +///
          +///
        • Recall that Cosine Similarity can be used +/// find how similar two documents are. One can use Lucene for eg. clustering, and use a document as a query to +/// compute its similarity to other documents. In this use case it is important that the score of document d3 +/// for query d1 is comparable to the score of document d3 for query d2. In other words, scores of a document for +/// two distinct queries should be comparable. There are other applications that may require this. And this is +/// exactly what normalizing the query vector V(q) provides: comparability (to a certain extent) of two or more +/// queries. +///
        • +///
        • Applying query normalization on the scores helps to keep the scores around the unit vector, hence preventing +/// loss of score data because of floating point precision limitations. +///
        • +///
        +///
      • +///
      • Document length norm doc-len-norm(d) and document boost doc-boost(d) are known at indexing time. They are +/// computed in advance and their multiplication is saved as a single value in the index: norm(d). (In the equations +/// below, norm(t in d) means norm(field(t) in doc d) where field(t) is the field associated with term t.) +///
      • +///
      +/// +/// Lucene's Practical Scoring Function is derived from the above. The color codes demonstrate how it relates to +/// those of the conceptual formula: +/// +/// +/// +/// +///
      +/// +/// +///
      +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +///
      +/// score(q,d)   =   +/// coord(q,d)  ·  +/// queryNorm(q)  ·  +/// +/// +/// +/// ( +/// tf(t in d)  ·  +/// idf(t)2  ·  +/// t.getBoost() ·  +/// norm(t,d) +/// ) +///
      t in q
      +///
      +///
      +///
      Lucene Practical Scoring Function
      +///
      +/// +/// where +///
        +///
      1. +/// +/// tf(t in d) +/// correlates to the term's frequency, defined as the number of times term t appears in the currently +/// scored document d. Documents that have more occurrences of a given term receive a higher score. +/// Note that tf(t in q) is assumed to be 1 and therefore it does not appear in this equation, +/// However if a query contains twice the same term, there will be two term-queries with that same term +/// and hence the computation would still be correct (although not very efficient). +/// The default computation for tf(t in d) in {@link DefaultSimilarity#tf(float) DefaultSimilarity} is: +/// +///
         
        +/// +/// +/// +/// +/// +///
        +/// {@link DefaultSimilarity#tf(float) tf(t in d)}   =   +/// +/// frequency½ +///
        +///
         
        +///
      2. +/// +///
      3. +/// +/// idf(t) stands for Inverse Document Frequency. This value correlates to the inverse of docFreq +/// (the number of documents in which the term t appears). This means rarer terms give higher contribution +/// to the total score. idf(t) appears for t in both the query and the document, hence it is squared in +/// the equation. The default computation for idf(t) in {@link DefaultSimilarity#idf(int, int) DefaultSimilarity} is: +/// +///
         
        +/// +/// +/// +/// +/// +/// +/// +///
        +/// {@link DefaultSimilarity#idf(int, int) idf(t)}  =   +/// +/// 1 + log ( +/// +/// +/// +/// +/// +///
        numDocs
        –––––––––
        docFreq+1
        +///
        +/// ) +///
        +///
         
        +///
      4. +/// +///
      5. +/// +/// coord(q,d) +/// is a score factor based on how many of the query terms are found in the specified document. Typically, a +/// document that contains more of the query's terms will receive a higher score than another document with +/// fewer query terms. This is a search time factor computed in {@link #coord(int, int) coord(q,d)} by the +/// Similarity in effect at search time. +///
         
        +///
      6. +/// +///
      7. +/// +/// queryNorm(q) +/// +/// is a normalizing factor used to make scores between queries comparable. This factor does not affect +/// document ranking (since all ranked documents are multiplied by the same factor), but rather just attempts +/// to make scores from different queries (or even different indexes) comparable. This is a search time +/// factor computed by the Similarity in effect at search time. +/// +/// The default computation in {@link DefaultSimilarity#queryNorm(float) DefaultSimilarity} +/// produces a Euclidean norm: +///
         
        +/// +/// +/// +/// +/// +///
        +/// queryNorm(q)   =   +/// {@link DefaultSimilarity#queryNorm(float) queryNorm(sumOfSquaredWeights)} +///   =   +/// +/// +/// +/// +/// +///
        1
        +/// –––––––––––––– +///
        sumOfSquaredWeights½
        +///
        +///
         
        +/// +/// The sum of squared weights (of the query terms) is computed by the query {@link Weight} object. For example, +/// a {@link BooleanQuery boolean query} computes this value as: +/// +///
         
        +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +///
        +/// {@link Weight#sumOfSquaredWeights() sumOfSquaredWeights}   =   +/// {@link Query#getBoost() q.getBoost()} 2 +///  ·  +/// +/// +/// +/// ( +/// idf(t)  ·  +/// t.getBoost() +/// ) 2 +///
        t in q
        +///
         
        +/// +///
      8. +/// +///
      9. +/// +/// t.getBoost() +/// is a search time boost of term t in the query q as specified in the query text or as set by application +/// calls to {@link Query#setBoost(float) setBoost()}. Notice that there is really no direct API for accessing +/// a boost of one term in a multi term query, but rather multi terms are represented in a query as multi +/// {@link TermQuery TermQuery} objects, and so the boost of a term in the query is accessible by calling +/// the sub-query {@link Query#getBoost() getBoost()}. +///
         
        +///
      10. +/// +///
      11. +/// +/// norm(t,d) encapsulates a few (indexing time) boost and length factors: +/// +///
          +///
        • Document boost - set by calling +/// {@link Document#setBoost(float) doc.setBoost()} +/// before adding the document to the index. +///
        • +///
        • Field boost - set by calling +/// {@link Fieldable#setBoost(float) field.setBoost()} +/// before adding the field to a document. +///
        • +///
        • {@link #lengthNorm(String, int) lengthNorm(field)} - computed when the document is added to +/// the index in accordance with the number of tokens of this field in the document, so that shorter fields +/// contribute more to the score. LengthNorm is computed by the Similarity class in effect at indexing. +///
        • +///
        +/// +/// When a document is added to the index, all the above factors are multiplied. +/// If the document has multiple fields with the same name, all their boosts are multiplied together: +/// +///
         
        +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +///
        +/// norm(t,d)   =   +/// {@link Document#getBoost() doc.getBoost()} +///  ·  +/// {@link #lengthNorm(String, int) lengthNorm(field)} +///  ·  +/// +/// +/// +/// {@link Fieldable#getBoost() f.getBoost}() +///
        field f in d named as t
        +///
         
        +/// However the resulted norm value is {@link #encodeNorm(float) encoded} as a single byte before being stored. +/// At search time, the norm byte value is read from the index {@link Directory directory} and {@link +/// #decodeNorm(byte) decoded} back to a float norm value. This encoding/decoding, while reducing index size, +/// comes with the price of precision loss - it is not guaranteed that decode(encode(x)) = x. For instance, +/// decode(encode(0.89)) = 0.75. +///
         
        +/// Compression of norm values to a single byte saves memory at search time, because once a field is referenced +/// at search time, its norms - for all documents - are maintained in memory. +///
         
        +/// The rationale supporting such lossy compression of norm values is that given the difficulty (and inaccuracy) +/// of users to express their true information need by a query, only big differences matter. +///
         
        +/// Last, note that search time is too late to modify this norm part of scoring, eg. by using a different +/// {@link Similarity} for search. +///
         
        +///
      12. +///
      +/// +/// @see #setDefault(SimilarityPtr) +/// @see IndexWriter#setSimilarity(SimilarityPtr) +/// @see Searcher#setSimilarity(SimilarityPtr) +class LPPAPI Similarity : public LuceneObject { +public: + Similarity(); + virtual ~Similarity(); + + LUCENE_CLASS(Similarity); + +protected: + static const int32_t NO_DOC_ID_PROVIDED; + +protected: + static const Collection NORM_TABLE(); + +public: + /// Return the default Similarity implementation used by indexing and search code. + /// This is initially an instance of {@link DefaultSimilarity}. + /// @see Searcher#setSimilarity(SimilarityPtr) + /// @see IndexWriter#setSimilarity(SimilarityPtr) + static SimilarityPtr getDefault(); + + /// Decodes a normalization factor stored in an index. + /// @see #encodeNorm(double) + static double decodeNorm(uint8_t b); + + /// Returns a table for decoding normalization bytes. + /// @see #encodeNorm(double) + static const Collection getNormDecoder(); + + /// Compute the normalization value for a field, given the accumulated state of term processing for this + /// field (see {@link FieldInvertState}). /// - /// Lucene's Practical Scoring Function is derived from the above. The color codes demonstrate how it relates to - /// those of the conceptual formula: + /// Implementations should calculate a float value based on the field state and then return that value. /// - /// - /// - /// - ///
      - /// - /// - ///
      - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///
      - /// score(q,d)   =   - /// coord(q,d)  ·  - /// queryNorm(q)  ·  - /// - /// - /// - /// ( - /// tf(t in d)  ·  - /// idf(t)2  ·  - /// t.getBoost() ·  - /// norm(t,d) - /// ) - ///
      t in q
      - ///
      - ///
      - ///
      Lucene Practical Scoring Function
      - ///
      + /// For backward compatibility this method by default calls {@link #lengthNorm(String, int32_t)} passing + /// {@link FieldInvertState#getLength()} as the second argument, and then multiplies this value by {@link + /// FieldInvertState#getBoost()}. /// - /// where - ///
        - ///
      1. - /// - /// tf(t in d) - /// correlates to the term's frequency, defined as the number of times term t appears in the currently - /// scored document d. Documents that have more occurrences of a given term receive a higher score. - /// Note that tf(t in q) is assumed to be 1 and therefore it does not appear in this equation, - /// However if a query contains twice the same term, there will be two term-queries with that same term - /// and hence the computation would still be correct (although not very efficient). - /// The default computation for tf(t in d) in {@link DefaultSimilarity#tf(float) DefaultSimilarity} is: + /// @param field Field name + /// @param state Current processing state for this field + /// @return The calculated float norm + virtual double computeNorm(const String& fieldName, const FieldInvertStatePtr& state); + + /// Computes the normalization value for a field given the total number of terms contained in a field. + /// These values, together with field boosts, are stored in an index and multiplied into scores for hits + /// on each field by the search code. + /// + /// Matches in longer fields are less precise, so implementations of this method usually return smaller + /// values when numTokens is large, and larger values when numTokens is small. + /// + /// Note that the return values are computed under {@link IndexWriter#addDocument(DocumentPtr)} and then + /// stored using {@link #encodeNorm(double)}. Thus they have limited precision, and documents must be + /// re-indexed if this method is altered. + /// + /// @param fieldName The name of the field + /// @param numTokens The total number of tokens contained in fields named fieldName of doc. + /// @return A normalization factor for hits on this field of this document + /// @see Field#setBoost(double) + virtual double lengthNorm(const String& fieldName, int32_t numTokens) = 0; + + /// Computes the normalization value for a query given the sum of the squared weights of each of the query + /// terms. This value is multiplied into the weight of each query term. While the classic query + /// normalization factor is computed as 1/sqrt(sumOfSquaredWeights), other implementations might completely + /// ignore sumOfSquaredWeights (ie return 1). + /// + /// This does not affect ranking, but the default implementation does make scores from different queries + /// more comparable than they would be by eliminating the magnitude of the Query vector as a factor in the + /// score. + /// + /// @param sumOfSquaredWeights The sum of the squares of query term weights + /// @return a normalization factor for query weights + virtual double queryNorm(double sumOfSquaredWeights) = 0; + + /// Encodes a normalization factor for storage in an index. /// - ///
         
        - /// - /// - /// - /// - /// - ///
        - /// {@link DefaultSimilarity#tf(float) tf(t in d)}   =   - /// - /// frequency½ - ///
        - ///
         
        - ///
      2. + /// The encoding uses a three-bit mantissa, a five-bit exponent, and the zero-exponent point at 15, thus + /// representing values from around 7x10^9 to 2x10^-9 with about one significant decimal digit of accuracy. + /// Zero is also represented. Negative numbers are rounded up to zero. Values too large to represent + /// are rounded down to the largest representable value. Positive values too small to represent are rounded + /// up to the smallest positive representable value. /// - ///
      3. - /// - /// idf(t) stands for Inverse Document Frequency. This value correlates to the inverse of docFreq - /// (the number of documents in which the term t appears). This means rarer terms give higher contribution - /// to the total score. idf(t) appears for t in both the query and the document, hence it is squared in - /// the equation. The default computation for idf(t) in {@link DefaultSimilarity#idf(int, int) DefaultSimilarity} is: + /// @see Field#setBoost(double) + static uint8_t encodeNorm(double f); + + /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied + /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then + /// summed to form the initial score for a document. /// - ///
         
        - /// - /// - /// - /// - /// - /// - /// - ///
        - /// {@link DefaultSimilarity#idf(int, int) idf(t)}  =   - /// - /// 1 + log ( - /// - /// - /// - /// - /// - ///
        numDocs
        –––––––––
        docFreq+1
        - ///
        - /// ) - ///
        - ///
         
        - ///
      4. + /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this + /// method usually return larger values when freq is large, and smaller values when freq is small. /// - ///
      5. - /// - /// coord(q,d) - /// is a score factor based on how many of the query terms are found in the specified document. Typically, a - /// document that contains more of the query's terms will receive a higher score than another document with - /// fewer query terms. This is a search time factor computed in {@link #coord(int, int) coord(q,d)} by the - /// Similarity in effect at search time. - ///
         
        - ///
      6. + /// The default implementation calls {@link #tf(double)}. /// - ///
      7. - /// - /// queryNorm(q) - /// - /// is a normalizing factor used to make scores between queries comparable. This factor does not affect - /// document ranking (since all ranked documents are multiplied by the same factor), but rather just attempts - /// to make scores from different queries (or even different indexes) comparable. This is a search time - /// factor computed by the Similarity in effect at search time. + /// @param freq The frequency of a term within a document + /// @return A score factor based on a term's within-document frequency + virtual double tf(int32_t freq); + + /// Computes the amount of a sloppy phrase match, based on an edit distance. This value is summed for + /// each sloppy phrase match in a document to form the frequency that is passed to {@link #tf(double)}. /// - /// The default computation in {@link DefaultSimilarity#queryNorm(float) DefaultSimilarity} - /// produces a Euclidean norm: - ///
         
        - /// - /// - /// - /// - /// - ///
        - /// queryNorm(q)   =   - /// {@link DefaultSimilarity#queryNorm(float) queryNorm(sumOfSquaredWeights)} - ///   =   - /// - /// - /// - /// - /// - ///
        1
        - /// –––––––––––––– - ///
        sumOfSquaredWeights½
        - ///
        - ///
         
        + /// A phrase match with a small edit distance to a document passage more closely matches the document, so + /// implementations of this method usually return larger values when the edit distance is small and + /// smaller values when it is large. /// - /// The sum of squared weights (of the query terms) is computed by the query {@link Weight} object. For example, - /// a {@link BooleanQuery boolean query} computes this value as: + /// @see PhraseQuery#setSlop(int32_t) + /// @param distance The edit distance of this sloppy phrase match + /// @return The frequency increment for this match + virtual double sloppyFreq(int32_t distance) = 0; + + /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied + /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then + /// summed to form the initial score for a document. /// - ///
         
        - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///
        - /// {@link Weight#sumOfSquaredWeights() sumOfSquaredWeights}   =   - /// {@link Query#getBoost() q.getBoost()} 2 - ///  ·  - /// - /// - /// - /// ( - /// idf(t)  ·  - /// t.getBoost() - /// ) 2 - ///
        t in q
        - ///
         
        + /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this + /// method usually return larger values when freq is large, and smaller values when freq is small. /// - ///
      8. + /// @param freq The frequency of a term within a document + /// @return A score factor based on a term's within-document frequency + virtual double tf(double freq) = 0; + + /// Computes a score factor for a simple term and returns an explanation for that score factor. + /// + /// The default implementation uses: + ///
        +    /// idf(searcher->docFreq(term), searcher->maxDoc());
        +    /// 
        + /// + /// Note that {@link Searcher#maxDoc()} is used instead of {@link IndexReader#numDocs() IndexReader#numDocs()} + /// because also {@link Searcher#docFreq(TermPtr)} is used, and when the latter is inaccurate, so is {@link + /// Searcher#maxDoc()}, and in the same direction. In addition, {@link Searcher#maxDoc()} is more efficient + /// to compute. + /// + /// @param term The term in question + /// @param searcher The document collection being searched + /// @return An IDFExplain object that includes both an idf score factor and an explanation for the term. + virtual IDFExplanationPtr idfExplain(const TermPtr& term, const SearcherPtr& searcher); + + /// Computes a score factor for a phrase. /// - ///
      9. - /// - /// t.getBoost() - /// is a search time boost of term t in the query q as specified in the query text or as set by application - /// calls to {@link Query#setBoost(float) setBoost()}. Notice that there is really no direct API for accessing - /// a boost of one term in a multi term query, but rather multi terms are represented in a query as multi - /// {@link TermQuery TermQuery} objects, and so the boost of a term in the query is accessible by calling - /// the sub-query {@link Query#getBoost() getBoost()}. - ///
         
        - ///
      10. + /// The default implementation sums the idf factor for each term in the phrase. /// - ///
      11. - /// - /// norm(t,d) encapsulates a few (indexing time) boost and length factors: + /// @param terms The terms in the phrase + /// @param searcher The document collection being searched + /// @return An IDFExplain object that includes both an idf score factor for the phrase and an explanation + /// for each term. + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher); + + /// Computes a score factor based on a term's document frequency (the number of documents which contain the + /// term). This value is multiplied by the {@link #tf(int32_t)} factor for each term in the query and these + /// products are then summed to form the initial score for a document. /// - ///
          - ///
        • Document boost - set by calling - /// {@link Document#setBoost(float) doc.setBoost()} - /// before adding the document to the index. - ///
        • - ///
        • Field boost - set by calling - /// {@link Fieldable#setBoost(float) field.setBoost()} - /// before adding the field to a document. - ///
        • - ///
        • {@link #lengthNorm(String, int) lengthNorm(field)} - computed when the document is added to - /// the index in accordance with the number of tokens of this field in the document, so that shorter fields - /// contribute more to the score. LengthNorm is computed by the Similarity class in effect at indexing. - ///
        • - ///
        + /// Terms that occur in fewer documents are better indicators of topic, so implementations of this method + /// usually return larger values for rare terms, and smaller values for common terms. /// - /// When a document is added to the index, all the above factors are multiplied. - /// If the document has multiple fields with the same name, all their boosts are multiplied together: + /// @param docFreq The number of documents which contain the term + /// @param numDocs The total number of documents in the collection + /// @return A score factor based on the term's document frequency + virtual double idf(int32_t docFreq, int32_t numDocs) = 0; + + /// Computes a score factor based on the fraction of all query terms that a document contains. This value + /// is multiplied into scores. /// - ///
         
        - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///
        - /// norm(t,d)   =   - /// {@link Document#getBoost() doc.getBoost()} - ///  ·  - /// {@link #lengthNorm(String, int) lengthNorm(field)} - ///  ·  - /// - /// - /// - /// {@link Fieldable#getBoost() f.getBoost}() - ///
        field f in d named as t
        - ///
         
        - /// However the resulted norm value is {@link #encodeNorm(float) encoded} as a single byte before being stored. - /// At search time, the norm byte value is read from the index {@link Directory directory} and {@link - /// #decodeNorm(byte) decoded} back to a float norm value. This encoding/decoding, while reducing index size, - /// comes with the price of precision loss - it is not guaranteed that decode(encode(x)) = x. For instance, - /// decode(encode(0.89)) = 0.75. - ///
         
        - /// Compression of norm values to a single byte saves memory at search time, because once a field is referenced - /// at search time, its norms - for all documents - are maintained in memory. - ///
         
        - /// The rationale supporting such lossy compression of norm values is that given the difficulty (and inaccuracy) - /// of users to express their true information need by a query, only big differences matter. - ///
         
        - /// Last, note that search time is too late to modify this norm part of scoring, eg. by using a different - /// {@link Similarity} for search. - ///
         
        - ///
      12. - ///
      + /// The presence of a large portion of the query terms indicates a better match with the query, so + /// implementations of this method usually return larger values when the ratio between these parameters is + /// large and smaller values when the ratio between them is small. /// - /// @see #setDefault(SimilarityPtr) - /// @see IndexWriter#setSimilarity(SimilarityPtr) - /// @see Searcher#setSimilarity(SimilarityPtr) - class LPPAPI Similarity : public LuceneObject - { - public: - Similarity(); - virtual ~Similarity(); - - LUCENE_CLASS(Similarity); - - protected: - static const int32_t NO_DOC_ID_PROVIDED; - - protected: - static const Collection NORM_TABLE(); - - public: - /// Return the default Similarity implementation used by indexing and search code. - /// This is initially an instance of {@link DefaultSimilarity}. - /// @see Searcher#setSimilarity(SimilarityPtr) - /// @see IndexWriter#setSimilarity(SimilarityPtr) - static SimilarityPtr getDefault(); - - /// Decodes a normalization factor stored in an index. - /// @see #encodeNorm(double) - static double decodeNorm(uint8_t b); - - /// Returns a table for decoding normalization bytes. - /// @see #encodeNorm(double) - static const Collection getNormDecoder(); - - /// Compute the normalization value for a field, given the accumulated state of term processing for this - /// field (see {@link FieldInvertState}). - /// - /// Implementations should calculate a float value based on the field state and then return that value. - /// - /// For backward compatibility this method by default calls {@link #lengthNorm(String, int32_t)} passing - /// {@link FieldInvertState#getLength()} as the second argument, and then multiplies this value by {@link - /// FieldInvertState#getBoost()}. - /// - /// @param field Field name - /// @param state Current processing state for this field - /// @return The calculated float norm - virtual double computeNorm(const String& fieldName, const FieldInvertStatePtr& state); - - /// Computes the normalization value for a field given the total number of terms contained in a field. - /// These values, together with field boosts, are stored in an index and multiplied into scores for hits - /// on each field by the search code. - /// - /// Matches in longer fields are less precise, so implementations of this method usually return smaller - /// values when numTokens is large, and larger values when numTokens is small. - /// - /// Note that the return values are computed under {@link IndexWriter#addDocument(DocumentPtr)} and then - /// stored using {@link #encodeNorm(double)}. Thus they have limited precision, and documents must be - /// re-indexed if this method is altered. - /// - /// @param fieldName The name of the field - /// @param numTokens The total number of tokens contained in fields named fieldName of doc. - /// @return A normalization factor for hits on this field of this document - /// @see Field#setBoost(double) - virtual double lengthNorm(const String& fieldName, int32_t numTokens) = 0; - - /// Computes the normalization value for a query given the sum of the squared weights of each of the query - /// terms. This value is multiplied into the weight of each query term. While the classic query - /// normalization factor is computed as 1/sqrt(sumOfSquaredWeights), other implementations might completely - /// ignore sumOfSquaredWeights (ie return 1). - /// - /// This does not affect ranking, but the default implementation does make scores from different queries - /// more comparable than they would be by eliminating the magnitude of the Query vector as a factor in the - /// score. - /// - /// @param sumOfSquaredWeights The sum of the squares of query term weights - /// @return a normalization factor for query weights - virtual double queryNorm(double sumOfSquaredWeights) = 0; - - /// Encodes a normalization factor for storage in an index. - /// - /// The encoding uses a three-bit mantissa, a five-bit exponent, and the zero-exponent point at 15, thus - /// representing values from around 7x10^9 to 2x10^-9 with about one significant decimal digit of accuracy. - /// Zero is also represented. Negative numbers are rounded up to zero. Values too large to represent - /// are rounded down to the largest representable value. Positive values too small to represent are rounded - /// up to the smallest positive representable value. - /// - /// @see Field#setBoost(double) - static uint8_t encodeNorm(double f); - - /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied - /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then - /// summed to form the initial score for a document. - /// - /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this - /// method usually return larger values when freq is large, and smaller values when freq is small. - /// - /// The default implementation calls {@link #tf(double)}. - /// - /// @param freq The frequency of a term within a document - /// @return A score factor based on a term's within-document frequency - virtual double tf(int32_t freq); - - /// Computes the amount of a sloppy phrase match, based on an edit distance. This value is summed for - /// each sloppy phrase match in a document to form the frequency that is passed to {@link #tf(double)}. - /// - /// A phrase match with a small edit distance to a document passage more closely matches the document, so - /// implementations of this method usually return larger values when the edit distance is small and - /// smaller values when it is large. - /// - /// @see PhraseQuery#setSlop(int32_t) - /// @param distance The edit distance of this sloppy phrase match - /// @return The frequency increment for this match - virtual double sloppyFreq(int32_t distance) = 0; - - /// Computes a score factor based on a term or phrase's frequency in a document. This value is multiplied - /// by the {@link #idf(int32_t, int32_t)} factor for each term in the query and these products are then - /// summed to form the initial score for a document. - /// - /// Terms and phrases repeated in a document indicate the topic of the document, so implementations of this - /// method usually return larger values when freq is large, and smaller values when freq is small. - /// - /// @param freq The frequency of a term within a document - /// @return A score factor based on a term's within-document frequency - virtual double tf(double freq) = 0; - - /// Computes a score factor for a simple term and returns an explanation for that score factor. - /// - /// The default implementation uses: - ///
      -        /// idf(searcher->docFreq(term), searcher->maxDoc());
      -        /// 
      - /// - /// Note that {@link Searcher#maxDoc()} is used instead of {@link IndexReader#numDocs() IndexReader#numDocs()} - /// because also {@link Searcher#docFreq(TermPtr)} is used, and when the latter is inaccurate, so is {@link - /// Searcher#maxDoc()}, and in the same direction. In addition, {@link Searcher#maxDoc()} is more efficient - /// to compute. - /// - /// @param term The term in question - /// @param searcher The document collection being searched - /// @return An IDFExplain object that includes both an idf score factor and an explanation for the term. - virtual IDFExplanationPtr idfExplain(const TermPtr& term, const SearcherPtr& searcher); - - /// Computes a score factor for a phrase. - /// - /// The default implementation sums the idf factor for each term in the phrase. - /// - /// @param terms The terms in the phrase - /// @param searcher The document collection being searched - /// @return An IDFExplain object that includes both an idf score factor for the phrase and an explanation - /// for each term. - virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher); - - /// Computes a score factor based on a term's document frequency (the number of documents which contain the - /// term). This value is multiplied by the {@link #tf(int32_t)} factor for each term in the query and these - /// products are then summed to form the initial score for a document. - /// - /// Terms that occur in fewer documents are better indicators of topic, so implementations of this method - /// usually return larger values for rare terms, and smaller values for common terms. - /// - /// @param docFreq The number of documents which contain the term - /// @param numDocs The total number of documents in the collection - /// @return A score factor based on the term's document frequency - virtual double idf(int32_t docFreq, int32_t numDocs) = 0; + /// @param overlap The number of query terms matched in the document + /// @param maxOverlap The total number of terms in the query + /// @return A score factor based on term overlap with the query + virtual double coord(int32_t overlap, int32_t maxOverlap) = 0; - /// Computes a score factor based on the fraction of all query terms that a document contains. This value - /// is multiplied into scores. - /// - /// The presence of a large portion of the query terms indicates a better match with the query, so - /// implementations of this method usually return larger values when the ratio between these parameters is - /// large and smaller values when the ratio between them is small. - /// - /// @param overlap The number of query terms matched in the document - /// @param maxOverlap The total number of terms in the query - /// @return A score factor based on term overlap with the query - virtual double coord(int32_t overlap, int32_t maxOverlap) = 0; + /// Calculate a scoring factor based on the data in the payload. Overriding implementations are responsible + /// for interpreting what is in the payload. Lucene makes no assumptions about what is in the byte array. + /// + /// The default implementation returns 1. + /// + /// @param docId The docId currently being scored. If this value is {@link #NO_DOC_ID_PROVIDED}, then it + /// should be assumed that the PayloadQuery implementation does not provide document information + /// @param fieldName The fieldName of the term this payload belongs to + /// @param start The start position of the payload + /// @param end The end position of the payload + /// @param payload The payload byte array to be scored + /// @param offset The offset into the payload array + /// @param length The length in the array + /// @return An implementation dependent float to be used as a scoring factor + virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length); +}; - /// Calculate a scoring factor based on the data in the payload. Overriding implementations are responsible - /// for interpreting what is in the payload. Lucene makes no assumptions about what is in the byte array. - /// - /// The default implementation returns 1. - /// - /// @param docId The docId currently being scored. If this value is {@link #NO_DOC_ID_PROVIDED}, then it - /// should be assumed that the PayloadQuery implementation does not provide document information - /// @param fieldName The fieldName of the term this payload belongs to - /// @param start The start position of the payload - /// @param end The end position of the payload - /// @param payload The payload byte array to be scored - /// @param offset The offset into the payload array - /// @param length The length in the array - /// @return An implementation dependent float to be used as a scoring factor - virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length); - }; } #endif diff --git a/include/SimilarityDelegator.h b/include/SimilarityDelegator.h index bf57f470..a4c4f4e1 100644 --- a/include/SimilarityDelegator.h +++ b/include/SimilarityDelegator.h @@ -9,31 +9,31 @@ #include "Similarity.h" -namespace Lucene -{ - /// Delegating scoring implementation. Useful in {@link Query#getSimilarity(Searcher)} implementations, - /// to override only certain methods of a Searcher's Similarity implementation. - class LPPAPI SimilarityDelegator : public Similarity - { - public: - SimilarityDelegator(const SimilarityPtr& delegee); - virtual ~SimilarityDelegator(); - - LUCENE_CLASS(SimilarityDelegator); - - protected: - SimilarityPtr delegee; - - public: - virtual double computeNorm(const String& field, const FieldInvertStatePtr& state); - virtual double lengthNorm(const String& fieldName, int32_t numTokens); - virtual double queryNorm(double sumOfSquaredWeights); - virtual double tf(double freq); - virtual double sloppyFreq(int32_t distance); - virtual double idf(int32_t docFreq, int32_t numDocs); - virtual double coord(int32_t overlap, int32_t maxOverlap); - virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length); - }; +namespace Lucene { + +/// Delegating scoring implementation. Useful in {@link Query#getSimilarity(Searcher)} implementations, +/// to override only certain methods of a Searcher's Similarity implementation. +class LPPAPI SimilarityDelegator : public Similarity { +public: + SimilarityDelegator(const SimilarityPtr& delegee); + virtual ~SimilarityDelegator(); + + LUCENE_CLASS(SimilarityDelegator); + +protected: + SimilarityPtr delegee; + +public: + virtual double computeNorm(const String& field, const FieldInvertStatePtr& state); + virtual double lengthNorm(const String& fieldName, int32_t numTokens); + virtual double queryNorm(double sumOfSquaredWeights); + virtual double tf(double freq); + virtual double sloppyFreq(int32_t distance); + virtual double idf(int32_t docFreq, int32_t numDocs); + virtual double coord(int32_t overlap, int32_t maxOverlap); + virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length); +}; + } #endif diff --git a/include/SimpleAnalyzer.h b/include/SimpleAnalyzer.h index ef046d09..b648da8e 100644 --- a/include/SimpleAnalyzer.h +++ b/include/SimpleAnalyzer.h @@ -9,20 +9,20 @@ #include "Analyzer.h" -namespace Lucene -{ - /// An {@link Analyzer} that filters {@link LetterTokenizer} with {@link LowerCaseFilter} - class LPPAPI SimpleAnalyzer : public Analyzer - { - public: - virtual ~SimpleAnalyzer(); - - LUCENE_CLASS(SimpleAnalyzer); - - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +namespace Lucene { + +/// An {@link Analyzer} that filters {@link LetterTokenizer} with {@link LowerCaseFilter} +class LPPAPI SimpleAnalyzer : public Analyzer { +public: + virtual ~SimpleAnalyzer(); + + LUCENE_CLASS(SimpleAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + } #endif diff --git a/include/SimpleFSDirectory.h b/include/SimpleFSDirectory.h index 1e407e1b..b746fffb 100644 --- a/include/SimpleFSDirectory.h +++ b/include/SimpleFSDirectory.h @@ -9,30 +9,30 @@ #include "FSDirectory.h" -namespace Lucene -{ - /// A straightforward implementation of {@link FSDirectory} using std::ofstream and std::ifstream. - class LPPAPI SimpleFSDirectory : public FSDirectory - { - public: - /// Create a new SimpleFSDirectory for the named location and {@link NativeFSLockFactory}. - /// @param path the path of the directory. - /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) - SimpleFSDirectory(const String& path, const LockFactoryPtr& lockFactory = LockFactoryPtr()); - virtual ~SimpleFSDirectory(); - - LUCENE_CLASS(SimpleFSDirectory); - - public: - /// Creates an IndexOutput for the file with the given name. - virtual IndexOutputPtr createOutput(const String& name); - - /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory implementation may ignore the buffer size. - virtual IndexInputPtr openInput(const String& name); - - /// Creates an IndexInput for the file with the given name. - virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - }; +namespace Lucene { + +/// A straightforward implementation of {@link FSDirectory} using std::ofstream and std::ifstream. +class LPPAPI SimpleFSDirectory : public FSDirectory { +public: + /// Create a new SimpleFSDirectory for the named location and {@link NativeFSLockFactory}. + /// @param path the path of the directory. + /// @param lockFactory the lock factory to use, or null for the default ({@link NativeFSLockFactory}) + SimpleFSDirectory(const String& path, const LockFactoryPtr& lockFactory = LockFactoryPtr()); + virtual ~SimpleFSDirectory(); + + LUCENE_CLASS(SimpleFSDirectory); + +public: + /// Creates an IndexOutput for the file with the given name. + virtual IndexOutputPtr createOutput(const String& name); + + /// Returns a stream reading an existing file, with the specified read buffer size. The particular Directory implementation may ignore the buffer size. + virtual IndexInputPtr openInput(const String& name); + + /// Creates an IndexInput for the file with the given name. + virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); +}; + } #endif diff --git a/include/SimpleFSLockFactory.h b/include/SimpleFSLockFactory.h index a5f215e8..6d9fa7ea 100644 --- a/include/SimpleFSLockFactory.h +++ b/include/SimpleFSLockFactory.h @@ -10,33 +10,33 @@ #include "FSLockFactory.h" #include "Lock.h" -namespace Lucene -{ - /// Implements {@link LockFactory} using {@link File#createNewFile()}. - /// @see LockFactory - class LPPAPI SimpleFSLockFactory : public FSLockFactory - { - public: - /// Create a SimpleFSLockFactory instance, with null (unset) lock directory. When you pass this factory - /// to a {@link FSDirectory} subclass, the lock directory is automatically set to the directory itself. - /// Be sure to create one instance for each directory your create! - SimpleFSLockFactory(); - - /// Instantiate using the provided directory name. - /// @param lockDir where lock files should be created. - SimpleFSLockFactory(const String& lockDir); - - virtual ~SimpleFSLockFactory(); - - LUCENE_CLASS(SimpleFSLockFactory); - - public: - /// Return a new Lock instance identified by lockName. - virtual LockPtr makeLock(const String& lockName); - - /// Attempt to clear (forcefully unlock and remove) the specified lock. - virtual void clearLock(const String& lockName); - }; +namespace Lucene { + +/// Implements {@link LockFactory} using {@link File#createNewFile()}. +/// @see LockFactory +class LPPAPI SimpleFSLockFactory : public FSLockFactory { +public: + /// Create a SimpleFSLockFactory instance, with null (unset) lock directory. When you pass this factory + /// to a {@link FSDirectory} subclass, the lock directory is automatically set to the directory itself. + /// Be sure to create one instance for each directory your create! + SimpleFSLockFactory(); + + /// Instantiate using the provided directory name. + /// @param lockDir where lock files should be created. + SimpleFSLockFactory(const String& lockDir); + + virtual ~SimpleFSLockFactory(); + + LUCENE_CLASS(SimpleFSLockFactory); + +public: + /// Return a new Lock instance identified by lockName. + virtual LockPtr makeLock(const String& lockName); + + /// Attempt to clear (forcefully unlock and remove) the specified lock. + virtual void clearLock(const String& lockName); +}; + } #endif diff --git a/include/SimpleLRUCache.h b/include/SimpleLRUCache.h index f077184d..8db67077 100644 --- a/include/SimpleLRUCache.h +++ b/include/SimpleLRUCache.h @@ -10,82 +10,74 @@ #include #include "LuceneObject.h" -namespace Lucene -{ - /// General purpose LRU cache map. - /// Accessing an entry will keep the entry cached. {@link #get(const KEY&)} and - /// {@link #put(const KEY&, const VALUE&)} results in an access to the corresponding entry. - template - class SimpleLRUCache : public LuceneObject - { - public: - typedef std::pair key_value; - typedef std::list< key_value > key_list; - typedef typename key_list::const_iterator const_iterator; - typedef boost::unordered_map map_type; - typedef typename map_type::const_iterator map_iterator; - - SimpleLRUCache(int32_t cacheSize) - { - this->cacheSize = cacheSize; +namespace Lucene { + +/// General purpose LRU cache map. +/// Accessing an entry will keep the entry cached. {@link #get(const KEY&)} and +/// {@link #put(const KEY&, const VALUE&)} results in an access to the corresponding entry. +template +class SimpleLRUCache : public LuceneObject { +public: + typedef std::pair key_value; + typedef std::list< key_value > key_list; + typedef typename key_list::const_iterator const_iterator; + typedef boost::unordered_map map_type; + typedef typename map_type::const_iterator map_iterator; + + SimpleLRUCache(int32_t cacheSize) { + this->cacheSize = cacheSize; + } + + virtual ~SimpleLRUCache() { + } + +protected: + int32_t cacheSize; + key_list cacheList; + map_type cacheMap; + +public: + void put(const KEY& key, const VALUE& value) { + cacheList.push_front(std::make_pair(key, value)); + cacheMap[key] = cacheList.begin(); + + if ((int32_t)cacheList.size() > cacheSize) { + cacheMap.erase(cacheList.back().first); + cacheList.pop_back(); } + } - virtual ~SimpleLRUCache() - { + VALUE get(const KEY& key) { + map_iterator find = cacheMap.find(key); + if (find == cacheMap.end()) { + return VALUE(); } - protected: - int32_t cacheSize; - key_list cacheList; - map_type cacheMap; - - public: - void put(const KEY& key, const VALUE& value) - { - cacheList.push_front(std::make_pair(key, value)); - cacheMap[key] = cacheList.begin(); - - if ((int32_t)cacheList.size() > cacheSize) - { - cacheMap.erase(cacheList.back().first); - cacheList.pop_back(); - } - } - - VALUE get(const KEY& key) - { - map_iterator find = cacheMap.find(key); - if (find == cacheMap.end()) - return VALUE(); + VALUE value(find->second->second); + cacheList.erase(find->second); + cacheList.push_front(std::make_pair(key, value)); + cacheMap[key] = cacheList.begin(); - VALUE value(find->second->second); - cacheList.erase(find->second); - cacheList.push_front(std::make_pair(key, value)); - cacheMap[key] = cacheList.begin(); + return value; + } - return value; - } + bool contains(const KEY& key) const { + return (cacheMap.find(key) != cacheMap.end()); + } - bool contains(const KEY& key) const - { - return (cacheMap.find(key) != cacheMap.end()); - } + int32_t size() const { + return (int32_t)cacheList.size(); + } - int32_t size() const - { - return (int32_t)cacheList.size(); - } + const_iterator begin() const { + return cacheList.begin(); + } - const_iterator begin() const - { - return cacheList.begin(); - } + const_iterator end() const { + return cacheList.end(); + } +}; - const_iterator end() const - { - return cacheList.end(); - } - }; }; #endif diff --git a/include/SingleInstanceLockFactory.h b/include/SingleInstanceLockFactory.h index 00a61fd6..df19d270 100644 --- a/include/SingleInstanceLockFactory.h +++ b/include/SingleInstanceLockFactory.h @@ -9,36 +9,36 @@ #include "LockFactory.h" -namespace Lucene -{ - /// Implements {@link LockFactory} for a single in-process instance, meaning all - /// locking will take place through this one instance. Only use this {@link LockFactory} - /// when you are certain all IndexReaders and IndexWriters for a given index are running - /// against a single shared in-process Directory instance. This is currently the - /// default locking for RAMDirectory. - /// @see LockFactory - class LPPAPI SingleInstanceLockFactory : public LockFactory - { - public: - SingleInstanceLockFactory(); - virtual ~SingleInstanceLockFactory(); - - LUCENE_CLASS(SingleInstanceLockFactory); - - protected: - HashSet locks; - - public: - /// Return a new Lock instance identified by lockName. - /// @param lockName name of the lock to be created. - virtual LockPtr makeLock(const String& lockName); - - /// Attempt to clear (forcefully unlock and remove) the - /// specified lock. Only call this at a time when you are - /// certain this lock is no longer in use. - /// @param lockName name of the lock to be cleared. - virtual void clearLock(const String& lockName); - }; +namespace Lucene { + +/// Implements {@link LockFactory} for a single in-process instance, meaning all +/// locking will take place through this one instance. Only use this {@link LockFactory} +/// when you are certain all IndexReaders and IndexWriters for a given index are running +/// against a single shared in-process Directory instance. This is currently the +/// default locking for RAMDirectory. +/// @see LockFactory +class LPPAPI SingleInstanceLockFactory : public LockFactory { +public: + SingleInstanceLockFactory(); + virtual ~SingleInstanceLockFactory(); + + LUCENE_CLASS(SingleInstanceLockFactory); + +protected: + HashSet locks; + +public: + /// Return a new Lock instance identified by lockName. + /// @param lockName name of the lock to be created. + virtual LockPtr makeLock(const String& lockName); + + /// Attempt to clear (forcefully unlock and remove) the + /// specified lock. Only call this at a time when you are + /// certain this lock is no longer in use. + /// @param lockName name of the lock to be cleared. + virtual void clearLock(const String& lockName); +}; + } #endif diff --git a/include/SingleTermEnum.h b/include/SingleTermEnum.h index 18fae202..115078fb 100644 --- a/include/SingleTermEnum.h +++ b/include/SingleTermEnum.h @@ -9,31 +9,31 @@ #include "FilteredTermEnum.h" -namespace Lucene -{ - /// Subclass of FilteredTermEnum for enumerating a single term. - /// - /// This can be used by {@link MultiTermQuery}s that need only visit one term, but want to preserve - /// MultiTermQuery semantics such as {@link MultiTermQuery#rewriteMethod}. - class LPPAPI SingleTermEnum : public FilteredTermEnum - { - public: - SingleTermEnum(const IndexReaderPtr& reader, const TermPtr& singleTerm); - virtual ~SingleTermEnum(); - - LUCENE_CLASS(SingleTermEnum); - - protected: - TermPtr singleTerm; - bool _endEnum; - - public: - virtual double difference(); - - protected: - virtual bool endEnum(); - virtual bool termCompare(const TermPtr& term); - }; +namespace Lucene { + +/// Subclass of FilteredTermEnum for enumerating a single term. +/// +/// This can be used by {@link MultiTermQuery}s that need only visit one term, but want to preserve +/// MultiTermQuery semantics such as {@link MultiTermQuery#rewriteMethod}. +class LPPAPI SingleTermEnum : public FilteredTermEnum { +public: + SingleTermEnum(const IndexReaderPtr& reader, const TermPtr& singleTerm); + virtual ~SingleTermEnum(); + + LUCENE_CLASS(SingleTermEnum); + +protected: + TermPtr singleTerm; + bool _endEnum; + +public: + virtual double difference(); + +protected: + virtual bool endEnum(); + virtual bool termCompare(const TermPtr& term); +}; + } #endif diff --git a/include/SloppyPhraseScorer.h b/include/SloppyPhraseScorer.h index e9ea6671..5463b26a 100644 --- a/include/SloppyPhraseScorer.h +++ b/include/SloppyPhraseScorer.h @@ -9,61 +9,61 @@ #include "PhraseScorer.h" -namespace Lucene -{ - class SloppyPhraseScorer : public PhraseScorer - { - public: - SloppyPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, int32_t slop, ByteArray norms); - virtual ~SloppyPhraseScorer(); +namespace Lucene { - LUCENE_CLASS(SloppyPhraseScorer); +class SloppyPhraseScorer : public PhraseScorer { +public: + SloppyPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, int32_t slop, ByteArray norms); + virtual ~SloppyPhraseScorer(); - protected: - int32_t slop; - Collection repeats; - Collection tmpPos; // for flipping repeating pps - bool checkedRepeats; + LUCENE_CLASS(SloppyPhraseScorer); - public: - /// Score a candidate doc for all slop-valid position-combinations (matches) encountered while - /// traversing/hopping the PhrasePositions. The score contribution of a match depends on the distance: - /// - highest score for distance=0 (exact match). - /// - score gets lower as distance gets higher. - /// Example: for query "a b"~2, a document "x a b a y" can be scored twice: once for "a b" (distance=0), - /// and once for "b a" (distance=2). - /// Possibly not all valid combinations are encountered, because for efficiency we always propagate the - /// least PhrasePosition. This allows to base on PriorityQueue and move forward faster. - /// As result, for example, document "a b c b a" would score differently for queries "a b c"~4 and - /// "c b a"~4, although they really are equivalent. Similarly, for doc "a b c b a f g", query "c b"~2 - /// would get same score as "g f"~2, although "c b"~2 could be matched twice. We may want to fix this - /// in the future (currently not, for performance reasons). - virtual double phraseFreq(); +protected: + int32_t slop; + Collection repeats; + Collection tmpPos; // for flipping repeating pps + bool checkedRepeats; - protected: - /// Flip pp2 and pp in the queue: pop until finding pp2, insert back all but pp2, insert pp back. - /// Assumes: pp!=pp2, pp2 in pq, pp not in pq. Called only when there are repeating pps. - PhrasePositionsPtr flip(const PhrasePositionsPtr& pp, const PhrasePositionsPtr& pp2); +public: + /// Score a candidate doc for all slop-valid position-combinations (matches) encountered while + /// traversing/hopping the PhrasePositions. The score contribution of a match depends on the distance: + /// - highest score for distance=0 (exact match). + /// - score gets lower as distance gets higher. + /// Example: for query "a b"~2, a document "x a b a y" can be scored twice: once for "a b" (distance=0), + /// and once for "b a" (distance=2). + /// Possibly not all valid combinations are encountered, because for efficiency we always propagate the + /// least PhrasePosition. This allows to base on PriorityQueue and move forward faster. + /// As result, for example, document "a b c b a" would score differently for queries "a b c"~4 and + /// "c b a"~4, although they really are equivalent. Similarly, for doc "a b c b a f g", query "c b"~2 + /// would get same score as "g f"~2, although "c b"~2 could be matched twice. We may want to fix this + /// in the future (currently not, for performance reasons). + virtual double phraseFreq(); - /// Init PhrasePositions in place. - /// There is a one time initialization for this scorer: - /// - Put in repeats[] each pp that has another pp with same position in the doc. - /// - Also mark each such pp by pp.repeats = true. - /// Later can consult with repeats[] in termPositionsDiffer(pp), making that check efficient. - /// In particular, this allows to score queries with no repetitions with no overhead due to this computation. - /// - Example 1 - query with no repetitions: "ho my"~2 - /// - Example 2 - query with repetitions: "ho my my"~2 - /// - Example 3 - query with repetitions: "my ho my"~2 - /// Init per doc with repeats in query, includes propagating some repeating pp's to avoid false phrase detection. - /// @return end (max position), or -1 if any term ran out (ie. done) - int32_t initPhrasePositions(); +protected: + /// Flip pp2 and pp in the queue: pop until finding pp2, insert back all but pp2, insert pp back. + /// Assumes: pp!=pp2, pp2 in pq, pp not in pq. Called only when there are repeating pps. + PhrasePositionsPtr flip(const PhrasePositionsPtr& pp, const PhrasePositionsPtr& pp2); + + /// Init PhrasePositions in place. + /// There is a one time initialization for this scorer: + /// - Put in repeats[] each pp that has another pp with same position in the doc. + /// - Also mark each such pp by pp.repeats = true. + /// Later can consult with repeats[] in termPositionsDiffer(pp), making that check efficient. + /// In particular, this allows to score queries with no repetitions with no overhead due to this computation. + /// - Example 1 - query with no repetitions: "ho my"~2 + /// - Example 2 - query with repetitions: "ho my my"~2 + /// - Example 3 - query with repetitions: "my ho my"~2 + /// Init per doc with repeats in query, includes propagating some repeating pp's to avoid false phrase detection. + /// @return end (max position), or -1 if any term ran out (ie. done) + int32_t initPhrasePositions(); + + /// We disallow two pp's to have the same TermPosition, thereby verifying multiple occurrences in the query + /// of the same word would go elsewhere in the matched doc. + /// @return null if differ (i.e. valid) otherwise return the higher offset PhrasePositions out of the first + /// two PPs found to not differ. + PhrasePositionsPtr termPositionsDiffer(const PhrasePositionsPtr& pp); +}; - /// We disallow two pp's to have the same TermPosition, thereby verifying multiple occurrences in the query - /// of the same word would go elsewhere in the matched doc. - /// @return null if differ (i.e. valid) otherwise return the higher offset PhrasePositions out of the first - /// two PPs found to not differ. - PhrasePositionsPtr termPositionsDiffer(const PhrasePositionsPtr& pp); - }; } #endif diff --git a/include/SmallDouble.h b/include/SmallDouble.h index de6d1ad1..5cf72440 100644 --- a/include/SmallDouble.h +++ b/include/SmallDouble.h @@ -9,25 +9,25 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Floating point numbers smaller than 32 bits. - class SmallDouble : public LuceneObject - { - public: - virtual ~SmallDouble(); - LUCENE_CLASS(SmallDouble); - - public: - /// Converts a floating point number to an 8 bit float. - /// Values less than zero are all mapped to zero. - /// Values are truncated (rounded down) to the nearest 8 bit value. - /// Values between zero and the smallest representable value are rounded up. - static uint8_t doubleToByte(double f); - - /// Converts an 8 bit floating point number to a double. - static double byteToDouble(uint8_t b); - }; +namespace Lucene { + +/// Floating point numbers smaller than 32 bits. +class SmallDouble : public LuceneObject { +public: + virtual ~SmallDouble(); + LUCENE_CLASS(SmallDouble); + +public: + /// Converts a floating point number to an 8 bit float. + /// Values less than zero are all mapped to zero. + /// Values are truncated (rounded down) to the nearest 8 bit value. + /// Values between zero and the smallest representable value are rounded up. + static uint8_t doubleToByte(double f); + + /// Converts an 8 bit floating point number to a double. + static double byteToDouble(uint8_t b); +}; + } #endif diff --git a/include/SnapshotDeletionPolicy.h b/include/SnapshotDeletionPolicy.h index f7b6f432..1f3ef138 100644 --- a/include/SnapshotDeletionPolicy.h +++ b/include/SnapshotDeletionPolicy.h @@ -9,45 +9,45 @@ #include "IndexDeletionPolicy.h" -namespace Lucene -{ - class LPPAPI SnapshotDeletionPolicy : public IndexDeletionPolicy - { - public: - SnapshotDeletionPolicy(const IndexDeletionPolicyPtr& primary); - virtual ~SnapshotDeletionPolicy(); - - LUCENE_CLASS(SnapshotDeletionPolicy); - - protected: - IndexCommitPtr lastCommit; - IndexDeletionPolicyPtr primary; - String _snapshot; - - public: - /// This is called once when a writer is first instantiated to give the policy a chance to remove old - /// commit points. - virtual void onInit(Collection commits); - - /// This is called each time the writer completed a commit. This gives the policy a chance to remove - /// old commit points with each commit. - virtual void onCommit(Collection commits); - - /// Take a snapshot of the most recent commit to the index. You must call release() to free this snapshot. - /// Note that while the snapshot is held, the files it references will not be deleted, which will consume - /// additional disk space in your index. If you take a snapshot at a particularly bad time (say just before - /// you call optimize()) then in the worst case this could consume an extra 1X of your total index size, - /// until you release the snapshot. - virtual IndexCommitPtr snapshot(); - - /// Release the currently held snapshot. - virtual void release(); - - protected: - Collection wrapCommits(Collection commits); - - friend class MyCommitPoint; - }; +namespace Lucene { + +class LPPAPI SnapshotDeletionPolicy : public IndexDeletionPolicy { +public: + SnapshotDeletionPolicy(const IndexDeletionPolicyPtr& primary); + virtual ~SnapshotDeletionPolicy(); + + LUCENE_CLASS(SnapshotDeletionPolicy); + +protected: + IndexCommitPtr lastCommit; + IndexDeletionPolicyPtr primary; + String _snapshot; + +public: + /// This is called once when a writer is first instantiated to give the policy a chance to remove old + /// commit points. + virtual void onInit(Collection commits); + + /// This is called each time the writer completed a commit. This gives the policy a chance to remove + /// old commit points with each commit. + virtual void onCommit(Collection commits); + + /// Take a snapshot of the most recent commit to the index. You must call release() to free this snapshot. + /// Note that while the snapshot is held, the files it references will not be deleted, which will consume + /// additional disk space in your index. If you take a snapshot at a particularly bad time (say just before + /// you call optimize()) then in the worst case this could consume an extra 1X of your total index size, + /// until you release the snapshot. + virtual IndexCommitPtr snapshot(); + + /// Release the currently held snapshot. + virtual void release(); + +protected: + Collection wrapCommits(Collection commits); + + friend class MyCommitPoint; +}; + } #endif diff --git a/include/Sort.h b/include/Sort.h index 0982c902..e51d5320 100644 --- a/include/Sort.h +++ b/include/Sort.h @@ -9,107 +9,107 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Encapsulates sort criteria for returned hits. - /// - /// The fields used to determine sort order must be carefully chosen. Documents must contain a single term - /// in such a field, and the value of the term should indicate the document's relative position in a given - /// sort order. The field must be indexed, but should not be tokenized, and does not need to be stored - /// (unless you happen to want it back with the rest of your document data). In other words: - /// - ///
      -    /// document->add(newLucene(L"byNumber", StringUtils::toString(x), Field::STORE_NO, Field::INDEX_NOT_ANALYZED));
      -    /// 
      - /// - /// Valid Types of Values - /// - /// There are four possible kinds of term values which may be put into sorting fields: Integers, Longs, Doubles, - /// or Strings. Unless {@link SortField SortField} objects are specified, the type of value in the field is - /// determined by parsing the first term in the field. - /// - /// Integer term values should contain only digits and an optional preceding negative sign. Values must be base - /// 10 and in the range INT_MIN and INT_MAX inclusive. Documents which should appear first in the sort should - /// have low value integers, later documents high values (ie. the documents should be numbered 1..n where 1 is - /// the first and n the last). - /// - /// Long term values should contain only digits and an optional preceding negative sign. Values must be base 10 - /// and in the range LLONG_MIN and LLONG_MAX inclusive. Documents which should appear first in the sort should - /// have low value integers, later documents high values. - /// - /// Double term values should conform to values accepted by Double (except that NaN and Infinity are not - /// supported). Documents which should appear first in the sort should have low values, later documents high - /// values. - /// - /// String term values can contain any valid String, but should not be tokenized. The values are sorted according - /// to their comparable natural order. Note that using this type of term value has higher memory requirements - /// than the other two types. - /// - /// Object Reuse - /// - /// One of these objects can be used multiple times and the sort order changed between usages. - /// This class is thread safe. - /// - /// Memory Usage - /// - /// Sorting uses of caches of term values maintained by the internal HitQueue(s). The cache is static and - /// contains an integer or double array of length IndexReader::maxDoc() for each field name for which a sort is - /// performed. In other words, the size of the cache in bytes is: - /// - ///
      -    /// 4 * IndexReader::maxDoc() * (# of different fields actually used to sort)
      -    /// 
      - /// - /// For String fields, the cache is larger: in addition to the above array, the value of every term in the - /// field is kept in memory. If there are many unique terms in the field, this could be quite large. - /// - /// Note that the size of the cache is not affected by how many fields are in the index and might be used to - /// sort - only by the ones actually used to sort a result set. - class LPPAPI Sort : public LuceneObject - { - public: - /// Sorts by computed relevance. This is the same sort criteria as calling {@link - /// Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly more - /// overhead. - Sort(); - - /// Sorts by the criteria in the given SortField. - Sort(const SortFieldPtr& field); - - /// Sorts in succession by the criteria in each SortField. - Sort(Collection fields); - - virtual ~Sort(); - - LUCENE_CLASS(Sort); - - public: - /// Internal representation of the sort criteria - Collection fields; - - public: - /// Represents sorting by computed relevance. Using this sort criteria returns the same results as calling - /// {@link Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly - /// more overhead. - static SortPtr RELEVANCE(); - - /// Represents sorting by index order. - static SortPtr INDEXORDER(); - - /// Sets the sort to the given criteria. - void setSort(const SortFieldPtr& field); - - /// Sets the sort to the given criteria in succession. - void setSort(Collection fields); - - /// Representation of the sort criteria. - /// @return Array of SortField objects used in this sort criteria - Collection getSort(); - - virtual String toString(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// Encapsulates sort criteria for returned hits. +/// +/// The fields used to determine sort order must be carefully chosen. Documents must contain a single term +/// in such a field, and the value of the term should indicate the document's relative position in a given +/// sort order. The field must be indexed, but should not be tokenized, and does not need to be stored +/// (unless you happen to want it back with the rest of your document data). In other words: +/// +///
      +/// document->add(newLucene(L"byNumber", StringUtils::toString(x), Field::STORE_NO, Field::INDEX_NOT_ANALYZED));
      +/// 
      +/// +/// Valid Types of Values +/// +/// There are four possible kinds of term values which may be put into sorting fields: Integers, Longs, Doubles, +/// or Strings. Unless {@link SortField SortField} objects are specified, the type of value in the field is +/// determined by parsing the first term in the field. +/// +/// Integer term values should contain only digits and an optional preceding negative sign. Values must be base +/// 10 and in the range INT_MIN and INT_MAX inclusive. Documents which should appear first in the sort should +/// have low value integers, later documents high values (ie. the documents should be numbered 1..n where 1 is +/// the first and n the last). +/// +/// Long term values should contain only digits and an optional preceding negative sign. Values must be base 10 +/// and in the range LLONG_MIN and LLONG_MAX inclusive. Documents which should appear first in the sort should +/// have low value integers, later documents high values. +/// +/// Double term values should conform to values accepted by Double (except that NaN and Infinity are not +/// supported). Documents which should appear first in the sort should have low values, later documents high +/// values. +/// +/// String term values can contain any valid String, but should not be tokenized. The values are sorted according +/// to their comparable natural order. Note that using this type of term value has higher memory requirements +/// than the other two types. +/// +/// Object Reuse +/// +/// One of these objects can be used multiple times and the sort order changed between usages. +/// This class is thread safe. +/// +/// Memory Usage +/// +/// Sorting uses of caches of term values maintained by the internal HitQueue(s). The cache is static and +/// contains an integer or double array of length IndexReader::maxDoc() for each field name for which a sort is +/// performed. In other words, the size of the cache in bytes is: +/// +///
      +/// 4 * IndexReader::maxDoc() * (# of different fields actually used to sort)
      +/// 
      +/// +/// For String fields, the cache is larger: in addition to the above array, the value of every term in the +/// field is kept in memory. If there are many unique terms in the field, this could be quite large. +/// +/// Note that the size of the cache is not affected by how many fields are in the index and might be used to +/// sort - only by the ones actually used to sort a result set. +class LPPAPI Sort : public LuceneObject { +public: + /// Sorts by computed relevance. This is the same sort criteria as calling {@link + /// Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly more + /// overhead. + Sort(); + + /// Sorts by the criteria in the given SortField. + Sort(const SortFieldPtr& field); + + /// Sorts in succession by the criteria in each SortField. + Sort(Collection fields); + + virtual ~Sort(); + + LUCENE_CLASS(Sort); + +public: + /// Internal representation of the sort criteria + Collection fields; + +public: + /// Represents sorting by computed relevance. Using this sort criteria returns the same results as calling + /// {@link Searcher#search(QueryPtr, int32_t) Searcher#search()} without a sort criteria, only with slightly + /// more overhead. + static SortPtr RELEVANCE(); + + /// Represents sorting by index order. + static SortPtr INDEXORDER(); + + /// Sets the sort to the given criteria. + void setSort(const SortFieldPtr& field); + + /// Sets the sort to the given criteria in succession. + void setSort(Collection fields); + + /// Representation of the sort criteria. + /// @return Array of SortField objects used in this sort criteria + Collection getSort(); + + virtual String toString(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/SortField.h b/include/SortField.h index 81502f54..893e7450 100644 --- a/include/SortField.h +++ b/include/SortField.h @@ -9,140 +9,140 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Stores information about how to sort documents by terms in an individual field. Fields must be indexed - /// in order to sort by them. - class LPPAPI SortField : public LuceneObject - { - public: - /// Creates a sort by terms in the given field with the type of term values explicitly given. - /// @param field Name of field to sort by. Can be null if type is SCORE or DOC. - /// @param type Type of values in the terms. - /// @param reverse True if natural order should be reversed. - SortField(const String& field, int32_t type, bool reverse = false); - - /// Creates a sort, possibly in reverse, by terms in the given field, parsed to numeric values using a - /// custom {@link Parser}. - /// @param field Name of field to sort by - /// @param parser Instance of a {@link Parser}, which must subclass one of the existing numeric parsers from - /// {@link FieldCache}. Sort type is inferred by testing which numeric parser the parser subclasses. - /// @param reverse True if natural order should be reversed. - SortField(const String& field, const ParserPtr& parser, bool reverse = false); +namespace Lucene { - /// Creates a sort, possibly in reverse, by terms in the given field sorted according to the given locale. - /// @param field Name of field to sort by, cannot be null. - /// @param locale Locale of values in the field. - /// @param reverse True if natural order should be reversed. - SortField(const String& field, const std::locale& locale, bool reverse = false); +/// Stores information about how to sort documents by terms in an individual field. Fields must be indexed +/// in order to sort by them. +class LPPAPI SortField : public LuceneObject { +public: + /// Creates a sort by terms in the given field with the type of term values explicitly given. + /// @param field Name of field to sort by. Can be null if type is SCORE or DOC. + /// @param type Type of values in the terms. + /// @param reverse True if natural order should be reversed. + SortField(const String& field, int32_t type, bool reverse = false); - /// Creates a sort, possibly in reverse, with a custom comparison function. - /// @param field Name of field to sort by; cannot be null. - /// @param comparator Returns a comparator for sorting hits. - /// @param reverse True if natural order should be reversed. - SortField(const String& field, const FieldComparatorSourcePtr& comparator, bool reverse = false); - - virtual ~SortField(); - - LUCENE_CLASS(SortField); - - public: - /// Sort by document score (relevancy). Sort values are Double and higher values are at the front. - static const int32_t SCORE; - - /// Sort by document number (index order). Sort values are Integer and lower values are at the front. - static const int32_t DOC; - - /// Sort using term values as Strings. Sort values are String and lower values are at the front. - static const int32_t STRING; - - /// Sort using term values as Integers. Sort values are Integer and lower values are at the front. - static const int32_t INT; - - /// Sort using term values as Floats. Sort values are Float and lower values are at the front. - static const int32_t FLOAT; - - /// Sort using term values as Longs. Sort values are Long and lower values are at the front. - static const int32_t LONG; - - /// Sort using term values as Doubles. Sort values are Double and lower values are at the front. - static const int32_t DOUBLE; - - /// Sort using term values as Shorts. Sort values are Short and lower values are at the front. - static const int32_t SHORT; - - /// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according - /// to natural order. - static const int32_t CUSTOM; - - /// Sort using term values as Bytes. Sort values are Byte and lower values are at the front. - static const int32_t BYTE; - - /// Sort using term values as Strings, but comparing by value (using String::compare) for all comparisons. - /// This is typically slower than {@link #STRING}, which uses ordinals to do the sorting. - static const int32_t STRING_VAL; - - INTERNAL: - bool reverse; // defaults to natural order - - String field; - int32_t type; // defaults to determining type dynamically - localePtr locale; // defaults to "natural order" (no Locale) - ParserPtr parser; - - private: - /// Used for CUSTOM sort - FieldComparatorSourcePtr comparatorSource; - - public: - /// Represents sorting by document score (relevancy). - static SortFieldPtr FIELD_SCORE(); - - /// Represents sorting by document number (index order). - static SortFieldPtr FIELD_DOC(); - - /// Returns the name of the field. Could return null if the sort is by SCORE or DOC. - /// @return Name of field, possibly null. - String getField(); - - /// Returns the type of contents in the field. - /// @return One of the constants SCORE, DOC, STRING, INT or DOUBLE. - int32_t getType(); - - /// Returns the Locale by which term values are interpreted. - localePtr getLocale(); - - /// Returns the instance of a {@link FieldCache} parser that fits to the given sort type. May return null - /// if no parser was specified. Sorting is using the default parser then. - /// @return An instance of a parser, or null. - ParserPtr getParser(); + /// Creates a sort, possibly in reverse, by terms in the given field, parsed to numeric values using a + /// custom {@link Parser}. + /// @param field Name of field to sort by + /// @param parser Instance of a {@link Parser}, which must subclass one of the existing numeric parsers from + /// {@link FieldCache}. Sort type is inferred by testing which numeric parser the parser subclasses. + /// @param reverse True if natural order should be reversed. + SortField(const String& field, const ParserPtr& parser, bool reverse = false); - /// Returns whether the sort should be reversed. - /// @return True if natural order should be reversed. - bool getReverse(); + /// Creates a sort, possibly in reverse, by terms in the given field sorted according to the given locale. + /// @param field Name of field to sort by, cannot be null. + /// @param locale Locale of values in the field. + /// @param reverse True if natural order should be reversed. + SortField(const String& field, const std::locale& locale, bool reverse = false); - /// Returns the {@link FieldComparatorSource} used for custom sorting - FieldComparatorSourcePtr getComparatorSource(); + /// Creates a sort, possibly in reverse, with a custom comparison function. + /// @param field Name of field to sort by; cannot be null. + /// @param comparator Returns a comparator for sorting hits. + /// @param reverse True if natural order should be reversed. + SortField(const String& field, const FieldComparatorSourcePtr& comparator, bool reverse = false); - virtual String toString(); + virtual ~SortField(); - /// Returns true if other is equal to this. If a {@link FieldComparatorSource} or {@link Parser} was provided, - /// it must properly implement equals (unless a singleton is always used). - virtual bool equals(const LuceneObjectPtr& other); + LUCENE_CLASS(SortField); - virtual int32_t hashCode(); +public: + /// Sort by document score (relevancy). Sort values are Double and higher values are at the front. + static const int32_t SCORE; - /// Returns the {@link FieldComparator} to use for sorting. - /// @param numHits number of top hits the queue will store - /// @param sortPos position of this SortField within {@link Sort}. The comparator is primary if sortPos == 0, - /// secondary if sortPos == 1, etc. Some comparators can optimize themselves when they are the primary sort. - /// @return {@link FieldComparator} to use when sorting - FieldComparatorPtr getComparator(int32_t numHits, int32_t sortPos); + /// Sort by document number (index order). Sort values are Integer and lower values are at the front. + static const int32_t DOC; + + /// Sort using term values as Strings. Sort values are String and lower values are at the front. + static const int32_t STRING; + + /// Sort using term values as Integers. Sort values are Integer and lower values are at the front. + static const int32_t INT; + + /// Sort using term values as Floats. Sort values are Float and lower values are at the front. + static const int32_t FLOAT; + + /// Sort using term values as Longs. Sort values are Long and lower values are at the front. + static const int32_t LONG; + + /// Sort using term values as Doubles. Sort values are Double and lower values are at the front. + static const int32_t DOUBLE; + + /// Sort using term values as Shorts. Sort values are Short and lower values are at the front. + static const int32_t SHORT; + + /// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according + /// to natural order. + static const int32_t CUSTOM; + + /// Sort using term values as Bytes. Sort values are Byte and lower values are at the front. + static const int32_t BYTE; + + /// Sort using term values as Strings, but comparing by value (using String::compare) for all comparisons. + /// This is typically slower than {@link #STRING}, which uses ordinals to do the sorting. + static const int32_t STRING_VAL; + +INTERNAL: + bool reverse; // defaults to natural order + + String field; + int32_t type; // defaults to determining type dynamically + localePtr locale; // defaults to "natural order" (no Locale) + ParserPtr parser; + +private: + /// Used for CUSTOM sort + FieldComparatorSourcePtr comparatorSource; + +public: + /// Represents sorting by document score (relevancy). + static SortFieldPtr FIELD_SCORE(); + + /// Represents sorting by document number (index order). + static SortFieldPtr FIELD_DOC(); + + /// Returns the name of the field. Could return null if the sort is by SCORE or DOC. + /// @return Name of field, possibly null. + String getField(); + + /// Returns the type of contents in the field. + /// @return One of the constants SCORE, DOC, STRING, INT or DOUBLE. + int32_t getType(); + + /// Returns the Locale by which term values are interpreted. + localePtr getLocale(); + + /// Returns the instance of a {@link FieldCache} parser that fits to the given sort type. May return null + /// if no parser was specified. Sorting is using the default parser then. + /// @return An instance of a parser, or null. + ParserPtr getParser(); + + /// Returns whether the sort should be reversed. + /// @return True if natural order should be reversed. + bool getReverse(); + + /// Returns the {@link FieldComparatorSource} used for custom sorting + FieldComparatorSourcePtr getComparatorSource(); + + virtual String toString(); + + /// Returns true if other is equal to this. If a {@link FieldComparatorSource} or {@link Parser} was provided, + /// it must properly implement equals (unless a singleton is always used). + virtual bool equals(const LuceneObjectPtr& other); + + virtual int32_t hashCode(); + + /// Returns the {@link FieldComparator} to use for sorting. + /// @param numHits number of top hits the queue will store + /// @param sortPos position of this SortField within {@link Sort}. The comparator is primary if sortPos == 0, + /// secondary if sortPos == 1, etc. Some comparators can optimize themselves when they are the primary sort. + /// @return {@link FieldComparator} to use when sorting + FieldComparatorPtr getComparator(int32_t numHits, int32_t sortPos); + +protected: + /// Sets field and type, and ensures field is not NULL unless type is SCORE or DOC + void initFieldType(const String& field, int32_t type); +}; - protected: - /// Sets field and type, and ensures field is not NULL unless type is SCORE or DOC - void initFieldType(const String& field, int32_t type); - }; } #endif diff --git a/include/SortedTermVectorMapper.h b/include/SortedTermVectorMapper.h index 66f7fb83..ecb0851d 100644 --- a/include/SortedTermVectorMapper.h +++ b/include/SortedTermVectorMapper.h @@ -10,52 +10,52 @@ #include #include "TermVectorMapper.h" -namespace Lucene -{ - /// Store a sorted collection of {@link TermVectorEntry}s. Collects all term information into a single, - /// sorted set. +namespace Lucene { + +/// Store a sorted collection of {@link TermVectorEntry}s. Collects all term information into a single, +/// sorted set. +/// +/// NOTE: This Mapper ignores all Field information for the Document. This means that if you are using offset/ +/// positions you will not know what Fields they correlate with. +/// +/// This is not thread-safe +class LPPAPI SortedTermVectorMapper : public TermVectorMapper { +public: + /// @param comparator A Comparator for sorting {@link TermVectorEntry}s + SortedTermVectorMapper(TermVectorEntryComparator comparator); + + SortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator); + + virtual ~SortedTermVectorMapper(); + + LUCENE_CLASS(SortedTermVectorMapper); + +protected: + Collection currentSet; + MapStringTermVectorEntry termToTVE; + bool storeOffsets; + bool storePositions; + TermVectorEntryComparator comparator; + +public: + static const wchar_t* ALL; + +public: + /// Map the Term Vector information into your own structure + virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); + + /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. + virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); + + /// The TermVectorEntrySet. A SortedSet of {@link TermVectorEntry} objects. Sort is by the comparator passed + /// into the constructor. /// - /// NOTE: This Mapper ignores all Field information for the Document. This means that if you are using offset/ - /// positions you will not know what Fields they correlate with. + /// This set will be empty until after the mapping process takes place. /// - /// This is not thread-safe - class LPPAPI SortedTermVectorMapper : public TermVectorMapper - { - public: - /// @param comparator A Comparator for sorting {@link TermVectorEntry}s - SortedTermVectorMapper(TermVectorEntryComparator comparator); - - SortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator); - - virtual ~SortedTermVectorMapper(); - - LUCENE_CLASS(SortedTermVectorMapper); - - protected: - Collection currentSet; - MapStringTermVectorEntry termToTVE; - bool storeOffsets; - bool storePositions; - TermVectorEntryComparator comparator; - - public: - static const wchar_t* ALL; - - public: - /// Map the Term Vector information into your own structure - virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); - - /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. - virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); - - /// The TermVectorEntrySet. A SortedSet of {@link TermVectorEntry} objects. Sort is by the comparator passed - /// into the constructor. - /// - /// This set will be empty until after the mapping process takes place. - /// - /// @return The sorted set of {@link TermVectorEntry}. - Collection getTermVectorEntrySet(); - }; + /// @return The sorted set of {@link TermVectorEntry}. + Collection getTermVectorEntrySet(); +}; + } #endif diff --git a/include/SortedVIntList.h b/include/SortedVIntList.h index d1357400..02a9a98f 100644 --- a/include/SortedVIntList.h +++ b/include/SortedVIntList.h @@ -9,80 +9,80 @@ #include "DocIdSet.h" -namespace Lucene -{ - /// Stores and iterate on sorted integers in compressed form in RAM. - /// - /// The code for compressing the differences between ascending integers was borrowed from {@link IndexInput} - /// and {@link IndexOutput}. - /// - /// NOTE: this class assumes the stored integers are doc Ids (hence why it extends {@link DocIdSet}). Therefore - /// its {@link #iterator()} assumes {@link DocIdSetIterator#NO_MORE_DOCS} can be used as sentinel. If you - /// intend to use this value, then make sure it's not used during search flow. - class LPPAPI SortedVIntList : public DocIdSet - { - public: - /// Create a SortedVIntList from all elements of an array of integers. - /// @param sortedInts A sorted array of non negative integers. - SortedVIntList(Collection sortedInts); - - /// Create a SortedVIntList from an array of integers. - /// @param sortedInts A sorted array of non negative integers. - /// @param inputSize The number of integers to be used from the array. - SortedVIntList(Collection sortedInts, int32_t inputSize); - - /// Create a SortedVIntList from a BitSet. - /// @param bits A bit set representing a set of integers. - SortedVIntList(const BitSetPtr& bits); - - /// Create a SortedVIntList from an OpenBitSet. - /// @param bits A bit set representing a set of integers. - SortedVIntList(const OpenBitSetPtr& bits); - - /// Create a SortedVIntList. - /// @param docIdSetIterator An iterator providing document numbers as a set of integers. - /// This DocIdSetIterator is iterated completely when this constructor is called and it must provide the - /// integers in non decreasing order. - SortedVIntList(const DocIdSetIteratorPtr& docIdSetIterator); - - virtual ~SortedVIntList(); - - LUCENE_CLASS(SortedVIntList); - - public: - /// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the - /// index numbers of the set bits will be smaller than that BitSet. - static const int32_t BITS2VINTLIST_SIZE; - - protected: - static const int32_t VB1; - static const int32_t BIT_SHIFT; - static const int32_t MAX_BYTES_PER_INT; - - int32_t _size; - ByteArray bytes; - int32_t lastBytePos; - int32_t lastInt; - - public: - /// @return The total number of sorted integers. - int32_t size(); - - /// @return The size of the byte array storing the compressed sorted integers. - int32_t getByteSize(); - - /// This DocIdSet implementation is cacheable. - virtual bool isCacheable(); - - /// @return An iterator over the sorted integers. - virtual DocIdSetIteratorPtr iterator(); - - protected: - void initBytes(); - void addInt(int32_t nextInt); - - friend class SortedDocIdSetIterator; - }; +namespace Lucene { + +/// Stores and iterate on sorted integers in compressed form in RAM. +/// +/// The code for compressing the differences between ascending integers was borrowed from {@link IndexInput} +/// and {@link IndexOutput}. +/// +/// NOTE: this class assumes the stored integers are doc Ids (hence why it extends {@link DocIdSet}). Therefore +/// its {@link #iterator()} assumes {@link DocIdSetIterator#NO_MORE_DOCS} can be used as sentinel. If you +/// intend to use this value, then make sure it's not used during search flow. +class LPPAPI SortedVIntList : public DocIdSet { +public: + /// Create a SortedVIntList from all elements of an array of integers. + /// @param sortedInts A sorted array of non negative integers. + SortedVIntList(Collection sortedInts); + + /// Create a SortedVIntList from an array of integers. + /// @param sortedInts A sorted array of non negative integers. + /// @param inputSize The number of integers to be used from the array. + SortedVIntList(Collection sortedInts, int32_t inputSize); + + /// Create a SortedVIntList from a BitSet. + /// @param bits A bit set representing a set of integers. + SortedVIntList(const BitSetPtr& bits); + + /// Create a SortedVIntList from an OpenBitSet. + /// @param bits A bit set representing a set of integers. + SortedVIntList(const OpenBitSetPtr& bits); + + /// Create a SortedVIntList. + /// @param docIdSetIterator An iterator providing document numbers as a set of integers. + /// This DocIdSetIterator is iterated completely when this constructor is called and it must provide the + /// integers in non decreasing order. + SortedVIntList(const DocIdSetIteratorPtr& docIdSetIterator); + + virtual ~SortedVIntList(); + + LUCENE_CLASS(SortedVIntList); + +public: + /// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the + /// index numbers of the set bits will be smaller than that BitSet. + static const int32_t BITS2VINTLIST_SIZE; + +protected: + static const int32_t VB1; + static const int32_t BIT_SHIFT; + static const int32_t MAX_BYTES_PER_INT; + + int32_t _size; + ByteArray bytes; + int32_t lastBytePos; + int32_t lastInt; + +public: + /// @return The total number of sorted integers. + int32_t size(); + + /// @return The size of the byte array storing the compressed sorted integers. + int32_t getByteSize(); + + /// This DocIdSet implementation is cacheable. + virtual bool isCacheable(); + + /// @return An iterator over the sorted integers. + virtual DocIdSetIteratorPtr iterator(); + +protected: + void initBytes(); + void addInt(int32_t nextInt); + + friend class SortedDocIdSetIterator; +}; + } #endif diff --git a/include/SpanFilter.h b/include/SpanFilter.h index ba906737..f55f6d9f 100644 --- a/include/SpanFilter.h +++ b/include/SpanFilter.h @@ -9,28 +9,28 @@ #include "Filter.h" -namespace Lucene -{ - /// Abstract base class providing a mechanism to restrict searches to a subset of an index and also maintains - /// and returns position information. - /// - /// This is useful if you want to compare the positions from a SpanQuery with the positions of items in a filter. - /// For instance, if you had a SpanFilter that marked all the occurrences of the word "foo" in documents, and - /// then you entered a new SpanQuery containing bar, you could not only filter by the word foo, but you could - /// then compare position information for post processing. - class LPPAPI SpanFilter : public Filter - { - public: - virtual ~SpanFilter(); - LUCENE_CLASS(SpanFilter); +namespace Lucene { + +/// Abstract base class providing a mechanism to restrict searches to a subset of an index and also maintains +/// and returns position information. +/// +/// This is useful if you want to compare the positions from a SpanQuery with the positions of items in a filter. +/// For instance, if you had a SpanFilter that marked all the occurrences of the word "foo" in documents, and +/// then you entered a new SpanQuery containing bar, you could not only filter by the word foo, but you could +/// then compare position information for post processing. +class LPPAPI SpanFilter : public Filter { +public: + virtual ~SpanFilter(); + LUCENE_CLASS(SpanFilter); + +public: + /// Returns a SpanFilterResult with true for documents which should be permitted in search results, and + /// false for those that should not and Spans for where the true docs match. + /// @param reader The {@link IndexReader} to load position and DocIdSet information from + /// @return A {@link SpanFilterResult} + virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader) = 0; +}; - public: - /// Returns a SpanFilterResult with true for documents which should be permitted in search results, and - /// false for those that should not and Spans for where the true docs match. - /// @param reader The {@link IndexReader} to load position and DocIdSet information from - /// @return A {@link SpanFilterResult} - virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader) = 0; - }; } #endif diff --git a/include/SpanFilterResult.h b/include/SpanFilterResult.h index 3934e0c9..37b87ca3 100644 --- a/include/SpanFilterResult.h +++ b/include/SpanFilterResult.h @@ -9,71 +9,69 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// The results of a SpanQueryFilter. Wraps the BitSet and the position information from the SpanQuery - class LPPAPI SpanFilterResult : public LuceneObject - { - public: - /// @param docIdSet The DocIdSet for the Filter - /// @param positions A List of {@link PositionInfo} objects - SpanFilterResult(const DocIdSetPtr& docIdSet, Collection positions); - - virtual ~SpanFilterResult(); - - LUCENE_CLASS(SpanFilterResult); - - protected: - DocIdSetPtr docIdSet; - Collection positions; // Spans spans - - public: - /// The first entry in the array corresponds to the first "on" bit. Entries are increasing by - /// document order. - /// @return A List of PositionInfo objects - Collection getPositions(); - - /// Returns the docIdSet - DocIdSetPtr getDocIdSet(); - }; - - class LPPAPI PositionInfo : public LuceneObject - { - public: - PositionInfo(int32_t doc); - virtual ~PositionInfo(); - - LUCENE_CLASS(PositionInfo); - - protected: - int32_t doc; - Collection positions; - - public: - void addPosition(int32_t start, int32_t end); - int32_t getDoc(); - Collection getPositions(); - }; - - class LPPAPI StartEnd : public LuceneObject - { - public: - StartEnd(int32_t start, int32_t end); - virtual ~StartEnd(); - - LUCENE_CLASS(StartEnd); - - protected: - int32_t start; - int32_t end; - - public: - /// @return The end position of this match - int32_t getEnd(); - - /// @return The start position of this match - int32_t getStart(); - }; +namespace Lucene { + +/// The results of a SpanQueryFilter. Wraps the BitSet and the position information from the SpanQuery +class LPPAPI SpanFilterResult : public LuceneObject { +public: + /// @param docIdSet The DocIdSet for the Filter + /// @param positions A List of {@link PositionInfo} objects + SpanFilterResult(const DocIdSetPtr& docIdSet, Collection positions); + + virtual ~SpanFilterResult(); + + LUCENE_CLASS(SpanFilterResult); + +protected: + DocIdSetPtr docIdSet; + Collection positions; // Spans spans + +public: + /// The first entry in the array corresponds to the first "on" bit. Entries are increasing by + /// document order. + /// @return A List of PositionInfo objects + Collection getPositions(); + + /// Returns the docIdSet + DocIdSetPtr getDocIdSet(); +}; + +class LPPAPI PositionInfo : public LuceneObject { +public: + PositionInfo(int32_t doc); + virtual ~PositionInfo(); + + LUCENE_CLASS(PositionInfo); + +protected: + int32_t doc; + Collection positions; + +public: + void addPosition(int32_t start, int32_t end); + int32_t getDoc(); + Collection getPositions(); +}; + +class LPPAPI StartEnd : public LuceneObject { +public: + StartEnd(int32_t start, int32_t end); + virtual ~StartEnd(); + + LUCENE_CLASS(StartEnd); + +protected: + int32_t start; + int32_t end; + +public: + /// @return The end position of this match + int32_t getEnd(); + + /// @return The start position of this match + int32_t getStart(); +}; + } #endif diff --git a/include/SpanFirstQuery.h b/include/SpanFirstQuery.h index fba6e765..7d264774 100644 --- a/include/SpanFirstQuery.h +++ b/include/SpanFirstQuery.h @@ -10,43 +10,43 @@ #include "SpanQuery.h" #include "Spans.h" -namespace Lucene -{ - /// Matches spans near the beginning of a field. - class LPPAPI SpanFirstQuery : public SpanQuery - { - public: - /// Construct a SpanFirstQuery matching spans in match whose end position is less than or equal to end. - SpanFirstQuery(const SpanQueryPtr& match, int32_t end); - virtual ~SpanFirstQuery(); - - LUCENE_CLASS(SpanFirstQuery); - - protected: - SpanQueryPtr match; - int32_t end; - - public: - using SpanQuery::toString; - - /// Return the SpanQuery whose matches are filtered. - SpanQueryPtr getMatch(); - - /// Return the maximum end position permitted in a match. - int32_t getEnd(); - - virtual String getField(); - virtual String toString(const String& field); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual void extractTerms(SetTerm terms); - virtual SpansPtr getSpans(const IndexReaderPtr& reader); - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - friend class FirstSpans; - }; +namespace Lucene { + +/// Matches spans near the beginning of a field. +class LPPAPI SpanFirstQuery : public SpanQuery { +public: + /// Construct a SpanFirstQuery matching spans in match whose end position is less than or equal to end. + SpanFirstQuery(const SpanQueryPtr& match, int32_t end); + virtual ~SpanFirstQuery(); + + LUCENE_CLASS(SpanFirstQuery); + +protected: + SpanQueryPtr match; + int32_t end; + +public: + using SpanQuery::toString; + + /// Return the SpanQuery whose matches are filtered. + SpanQueryPtr getMatch(); + + /// Return the maximum end position permitted in a match. + int32_t getEnd(); + + virtual String getField(); + virtual String toString(const String& field); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual void extractTerms(SetTerm terms); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + friend class FirstSpans; +}; + } #endif diff --git a/include/SpanNearQuery.h b/include/SpanNearQuery.h index 75c73c5f..5c321259 100644 --- a/include/SpanNearQuery.h +++ b/include/SpanNearQuery.h @@ -9,50 +9,50 @@ #include "SpanQuery.h" -namespace Lucene -{ - /// Matches spans which are near one another. One can specify slop, the maximum number of intervening - /// unmatched positions, as well as whether matches are required to be in-order. - class LPPAPI SpanNearQuery : public SpanQuery - { - public: - /// Construct a SpanNearQuery. Matches spans matching a span from each clause, with up to slop total - /// unmatched positions between them. * When inOrder is true, the spans from each clause must be - /// ordered as in clauses. - SpanNearQuery(Collection clauses, int32_t slop, bool inOrder, bool collectPayloads = true); - virtual ~SpanNearQuery(); - - LUCENE_CLASS(SpanNearQuery); - - protected: - Collection clauses; - int32_t slop; - bool inOrder; - - String field; - bool collectPayloads; - - public: - using SpanQuery::toString; - - /// Return the clauses whose spans are matched. - Collection getClauses(); - - /// Return the maximum number of intervening unmatched positions permitted. - int32_t getSlop(); - - /// Return true if matches are required to be in-order. - bool isInOrder(); - - virtual String getField(); - virtual void extractTerms(SetTerm terms); - virtual String toString(const String& field); - virtual SpansPtr getSpans(const IndexReaderPtr& reader); - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// Matches spans which are near one another. One can specify slop, the maximum number of intervening +/// unmatched positions, as well as whether matches are required to be in-order. +class LPPAPI SpanNearQuery : public SpanQuery { +public: + /// Construct a SpanNearQuery. Matches spans matching a span from each clause, with up to slop total + /// unmatched positions between them. * When inOrder is true, the spans from each clause must be + /// ordered as in clauses. + SpanNearQuery(Collection clauses, int32_t slop, bool inOrder, bool collectPayloads = true); + virtual ~SpanNearQuery(); + + LUCENE_CLASS(SpanNearQuery); + +protected: + Collection clauses; + int32_t slop; + bool inOrder; + + String field; + bool collectPayloads; + +public: + using SpanQuery::toString; + + /// Return the clauses whose spans are matched. + Collection getClauses(); + + /// Return the maximum number of intervening unmatched positions permitted. + int32_t getSlop(); + + /// Return true if matches are required to be in-order. + bool isInOrder(); + + virtual String getField(); + virtual void extractTerms(SetTerm terms); + virtual String toString(const String& field); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/SpanNotQuery.h b/include/SpanNotQuery.h index 53f74d4b..3b3976c5 100644 --- a/include/SpanNotQuery.h +++ b/include/SpanNotQuery.h @@ -9,41 +9,41 @@ #include "SpanQuery.h" -namespace Lucene -{ - /// Removes matches which overlap with another SpanQuery. - class LPPAPI SpanNotQuery : public SpanQuery - { - public: - /// Construct a SpanNotQuery matching spans from include which have no overlap with spans from exclude. - SpanNotQuery(const SpanQueryPtr& include, const SpanQueryPtr& exclude); - virtual ~SpanNotQuery(); - - LUCENE_CLASS(SpanNotQuery); - - protected: - SpanQueryPtr include; - SpanQueryPtr exclude; - - public: - using SpanQuery::toString; - - /// Return the SpanQuery whose matches are filtered. - SpanQueryPtr getInclude(); - - /// Return the SpanQuery whose matches must not overlap those returned. - SpanQueryPtr getExclude(); - - virtual String getField(); - virtual void extractTerms(SetTerm terms); - virtual String toString(const String& field); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual SpansPtr getSpans(const IndexReaderPtr& reader); - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// Removes matches which overlap with another SpanQuery. +class LPPAPI SpanNotQuery : public SpanQuery { +public: + /// Construct a SpanNotQuery matching spans from include which have no overlap with spans from exclude. + SpanNotQuery(const SpanQueryPtr& include, const SpanQueryPtr& exclude); + virtual ~SpanNotQuery(); + + LUCENE_CLASS(SpanNotQuery); + +protected: + SpanQueryPtr include; + SpanQueryPtr exclude; + +public: + using SpanQuery::toString; + + /// Return the SpanQuery whose matches are filtered. + SpanQueryPtr getInclude(); + + /// Return the SpanQuery whose matches must not overlap those returned. + SpanQueryPtr getExclude(); + + virtual String getField(); + virtual void extractTerms(SetTerm terms); + virtual String toString(const String& field); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/SpanOrQuery.h b/include/SpanOrQuery.h index b3efaeb7..8bee7985 100644 --- a/include/SpanOrQuery.h +++ b/include/SpanOrQuery.h @@ -9,39 +9,39 @@ #include "SpanQuery.h" -namespace Lucene -{ - /// Matches the union of its clauses. - class LPPAPI SpanOrQuery : public SpanQuery - { - public: - /// Construct a SpanOrQuery merging the provided clauses. - SpanOrQuery(Collection clauses); - virtual ~SpanOrQuery(); - - LUCENE_CLASS(SpanOrQuery); - - protected: - Collection clauses; - String field; - - public: - using SpanQuery::toString; - - /// Return the clauses whose spans are matched. - Collection getClauses(); - - virtual String getField(); - virtual void extractTerms(SetTerm terms); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual SpansPtr getSpans(const IndexReaderPtr& reader); - - friend class OrSpans; - }; +namespace Lucene { + +/// Matches the union of its clauses. +class LPPAPI SpanOrQuery : public SpanQuery { +public: + /// Construct a SpanOrQuery merging the provided clauses. + SpanOrQuery(Collection clauses); + virtual ~SpanOrQuery(); + + LUCENE_CLASS(SpanOrQuery); + +protected: + Collection clauses; + String field; + +public: + using SpanQuery::toString; + + /// Return the clauses whose spans are matched. + Collection getClauses(); + + virtual String getField(); + virtual void extractTerms(SetTerm terms); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); + + friend class OrSpans; +}; + } #endif diff --git a/include/SpanQuery.h b/include/SpanQuery.h index 092c9873..8e0773c8 100644 --- a/include/SpanQuery.h +++ b/include/SpanQuery.h @@ -9,24 +9,24 @@ #include "Query.h" -namespace Lucene -{ - /// Base class for span-based queries. - class LPPAPI SpanQuery : public Query - { - public: - virtual ~SpanQuery(); - LUCENE_CLASS(SpanQuery); - - public: - /// Returns the matches for this query in an index. Used internally to search for spans. - virtual SpansPtr getSpans(const IndexReaderPtr& reader) = 0; - - /// Returns the name of the field matched by this query. - virtual String getField() = 0; - - virtual WeightPtr createWeight(const SearcherPtr& searcher); - }; +namespace Lucene { + +/// Base class for span-based queries. +class LPPAPI SpanQuery : public Query { +public: + virtual ~SpanQuery(); + LUCENE_CLASS(SpanQuery); + +public: + /// Returns the matches for this query in an index. Used internally to search for spans. + virtual SpansPtr getSpans(const IndexReaderPtr& reader) = 0; + + /// Returns the name of the field matched by this query. + virtual String getField() = 0; + + virtual WeightPtr createWeight(const SearcherPtr& searcher); +}; + } #endif diff --git a/include/SpanQueryFilter.h b/include/SpanQueryFilter.h index 3a3899bd..0ef18863 100644 --- a/include/SpanQueryFilter.h +++ b/include/SpanQueryFilter.h @@ -9,38 +9,38 @@ #include "SpanFilter.h" -namespace Lucene -{ - /// Constrains search results to only match those which also match a provided query. Also provides position - /// information about where each document matches at the cost of extra space compared with the - /// QueryWrapperFilter. There is an added cost to this above what is stored in a {@link QueryWrapperFilter}. - /// Namely, the position information for each matching document is stored. - /// - /// This filter does not cache. See the {@link CachingSpanFilter} for a wrapper that caches. - class LPPAPI SpanQueryFilter : public SpanFilter - { - public: - /// Constructs a filter which only matches documents matching query. - /// @param query The {@link SpanQuery} to use as the basis for the Filter. - SpanQueryFilter(const SpanQueryPtr& query = SpanQueryPtr()); - - virtual ~SpanQueryFilter(); - - LUCENE_CLASS(SpanQueryFilter); - - protected: - SpanQueryPtr query; - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); - virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader); - - SpanQueryPtr getQuery(); - - virtual String toString(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// Constrains search results to only match those which also match a provided query. Also provides position +/// information about where each document matches at the cost of extra space compared with the +/// QueryWrapperFilter. There is an added cost to this above what is stored in a {@link QueryWrapperFilter}. +/// Namely, the position information for each matching document is stored. +/// +/// This filter does not cache. See the {@link CachingSpanFilter} for a wrapper that caches. +class LPPAPI SpanQueryFilter : public SpanFilter { +public: + /// Constructs a filter which only matches documents matching query. + /// @param query The {@link SpanQuery} to use as the basis for the Filter. + SpanQueryFilter(const SpanQueryPtr& query = SpanQueryPtr()); + + virtual ~SpanQueryFilter(); + + LUCENE_CLASS(SpanQueryFilter); + +protected: + SpanQueryPtr query; + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + virtual SpanFilterResultPtr bitSpans(const IndexReaderPtr& reader); + + SpanQueryPtr getQuery(); + + virtual String toString(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/SpanScorer.h b/include/SpanScorer.h index 8df36d9f..69274aff 100644 --- a/include/SpanScorer.h +++ b/include/SpanScorer.h @@ -9,42 +9,42 @@ #include "Scorer.h" -namespace Lucene -{ - /// Public for extension only. - class LPPAPI SpanScorer : public Scorer - { - public: - SpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); - virtual ~SpanScorer(); - - LUCENE_CLASS(SpanScorer); - - protected: - SpansPtr spans; - WeightPtr weight; - ByteArray norms; - double value; - bool more; - int32_t doc; - double freq; - - public: - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - virtual int32_t docID(); - virtual double score(); - - protected: - virtual bool setFreqCurrentDoc(); - - /// This method is no longer an official member of {@link Scorer}, but it is needed by SpanWeight - /// to build an explanation. - virtual ExplanationPtr explain(int32_t doc); - - friend class SpanWeight; - friend class PayloadNearSpanWeight; - }; +namespace Lucene { + +/// Public for extension only. +class LPPAPI SpanScorer : public Scorer { +public: + SpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); + virtual ~SpanScorer(); + + LUCENE_CLASS(SpanScorer); + +protected: + SpansPtr spans; + WeightPtr weight; + ByteArray norms; + double value; + bool more; + int32_t doc; + double freq; + +public: + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); + virtual int32_t docID(); + virtual double score(); + +protected: + virtual bool setFreqCurrentDoc(); + + /// This method is no longer an official member of {@link Scorer}, but it is needed by SpanWeight + /// to build an explanation. + virtual ExplanationPtr explain(int32_t doc); + + friend class SpanWeight; + friend class PayloadNearSpanWeight; +}; + } #endif diff --git a/include/SpanTermQuery.h b/include/SpanTermQuery.h index 115a81f3..2f11cd10 100644 --- a/include/SpanTermQuery.h +++ b/include/SpanTermQuery.h @@ -9,35 +9,35 @@ #include "SpanQuery.h" -namespace Lucene -{ - /// Matches spans containing a term. - class LPPAPI SpanTermQuery : public SpanQuery - { - public: - /// Construct a SpanTermQuery matching the named term's spans. - SpanTermQuery(const TermPtr& term); - virtual ~SpanTermQuery(); - - LUCENE_CLASS(SpanTermQuery); - - protected: - TermPtr term; - - public: - using SpanQuery::toString; - - /// Return the term whose spans are matched. - TermPtr getTerm(); - - virtual String getField(); - virtual void extractTerms(SetTerm terms); - virtual String toString(const String& field); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual SpansPtr getSpans(const IndexReaderPtr& reader); - }; +namespace Lucene { + +/// Matches spans containing a term. +class LPPAPI SpanTermQuery : public SpanQuery { +public: + /// Construct a SpanTermQuery matching the named term's spans. + SpanTermQuery(const TermPtr& term); + virtual ~SpanTermQuery(); + + LUCENE_CLASS(SpanTermQuery); + +protected: + TermPtr term; + +public: + using SpanQuery::toString; + + /// Return the term whose spans are matched. + TermPtr getTerm(); + + virtual String getField(); + virtual void extractTerms(SetTerm terms); + virtual String toString(const String& field); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual SpansPtr getSpans(const IndexReaderPtr& reader); +}; + } #endif diff --git a/include/SpanWeight.h b/include/SpanWeight.h index 35500b30..11d895a7 100644 --- a/include/SpanWeight.h +++ b/include/SpanWeight.h @@ -9,39 +9,39 @@ #include "Weight.h" -namespace Lucene -{ - /// Public for use by other weight implementations - class LPPAPI SpanWeight : public Weight - { - public: - SpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher); - virtual ~SpanWeight(); - - LUCENE_CLASS(SpanWeight); - - protected: - SimilarityPtr similarity; - double value; - double idf; - double queryNorm; - double queryWeight; - - SetTerm terms; - SpanQueryPtr query; - IDFExplanationPtr idfExp; - - public: - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - - friend class PayloadNearSpanScorer; - friend class PayloadTermSpanScorer; - }; +namespace Lucene { + +/// Public for use by other weight implementations +class LPPAPI SpanWeight : public Weight { +public: + SpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher); + virtual ~SpanWeight(); + + LUCENE_CLASS(SpanWeight); + +protected: + SimilarityPtr similarity; + double value; + double idf; + double queryNorm; + double queryWeight; + + SetTerm terms; + SpanQueryPtr query; + IDFExplanationPtr idfExp; + +public: + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); + + friend class PayloadNearSpanScorer; + friend class PayloadTermSpanScorer; +}; + } #endif diff --git a/include/Spans.h b/include/Spans.h index ed266e1d..8def3dd3 100644 --- a/include/Spans.h +++ b/include/Spans.h @@ -9,70 +9,70 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// An enumeration of span matches. Used to implement span searching. Each span represents a range of term - /// positions within a document. Matches are enumerated in order, by increasing document number, within that - /// by increasing start position and finally by increasing end position. - class LPPAPI Spans : public LuceneObject - { - public: - virtual ~Spans(); - LUCENE_CLASS(Spans); +namespace Lucene { - public: - /// Move to the next match, returning true if any such exists. - virtual bool next() = 0; +/// An enumeration of span matches. Used to implement span searching. Each span represents a range of term +/// positions within a document. Matches are enumerated in order, by increasing document number, within that +/// by increasing start position and finally by increasing end position. +class LPPAPI Spans : public LuceneObject { +public: + virtual ~Spans(); + LUCENE_CLASS(Spans); - /// Skips to the first match beyond the current, whose document number is greater than or equal to target. - /// - /// Returns true if there is such a match. - /// - /// Behaves as if written: - ///
      -        /// bool skipTo(int32_t target)
      -        /// {
      -        ///     do
      -        ///     {
      -        ///         if (!next())
      -        ///             return false;
      -        ///     }
      -        ///     while (target > doc());
      -        ///     return true;
      -        /// }
      -        /// 
      - /// Most implementations are considerably more efficient than that. - virtual bool skipTo(int32_t target) = 0; +public: + /// Move to the next match, returning true if any such exists. + virtual bool next() = 0; - /// Returns the document number of the current match. Initially invalid. - virtual int32_t doc() = 0; + /// Skips to the first match beyond the current, whose document number is greater than or equal to target. + /// + /// Returns true if there is such a match. + /// + /// Behaves as if written: + ///
      +    /// bool skipTo(int32_t target)
      +    /// {
      +    ///     do
      +    ///     {
      +    ///         if (!next())
      +    ///             return false;
      +    ///     }
      +    ///     while (target > doc());
      +    ///     return true;
      +    /// }
      +    /// 
      + /// Most implementations are considerably more efficient than that. + virtual bool skipTo(int32_t target) = 0; - /// Returns the start position of the current match. Initially invalid. - virtual int32_t start() = 0; + /// Returns the document number of the current match. Initially invalid. + virtual int32_t doc() = 0; - /// Returns the end position of the current match. Initially invalid. - virtual int32_t end() = 0; + /// Returns the start position of the current match. Initially invalid. + virtual int32_t start() = 0; - /// Returns the payload data for the current span. This is invalid until {@link #next()} is called for the - /// first time. This method must not be called more than once after each call of {@link #next()}. However, - /// most payloads are loaded lazily, so if the payload data for the current position is not needed, this - /// method may not be called at all for performance reasons. An ordered SpanQuery does not lazy load, so - /// if you have payloads in your index and you do not want ordered SpanNearQuerys to collect payloads, you - /// can disable collection with a constructor option. - /// - /// Note that the return type is a collection, thus the ordering should not be relied upon. - /// - /// @return a List of byte arrays containing the data of this payload, otherwise null if isPayloadAvailable - /// is false - virtual Collection getPayload() = 0; + /// Returns the end position of the current match. Initially invalid. + virtual int32_t end() = 0; + + /// Returns the payload data for the current span. This is invalid until {@link #next()} is called for the + /// first time. This method must not be called more than once after each call of {@link #next()}. However, + /// most payloads are loaded lazily, so if the payload data for the current position is not needed, this + /// method may not be called at all for performance reasons. An ordered SpanQuery does not lazy load, so + /// if you have payloads in your index and you do not want ordered SpanNearQuerys to collect payloads, you + /// can disable collection with a constructor option. + /// + /// Note that the return type is a collection, thus the ordering should not be relied upon. + /// + /// @return a List of byte arrays containing the data of this payload, otherwise null if isPayloadAvailable + /// is false + virtual Collection getPayload() = 0; + + /// Checks if a payload can be loaded at this position. + /// + /// Payloads can only be loaded once per call to {@link #next()}. + /// + /// @return true if there is a payload available at this position that can be loaded + virtual bool isPayloadAvailable() = 0; +}; - /// Checks if a payload can be loaded at this position. - /// - /// Payloads can only be loaded once per call to {@link #next()}. - /// - /// @return true if there is a payload available at this position that can be loaded - virtual bool isPayloadAvailable() = 0; - }; } #endif diff --git a/include/StandardAnalyzer.h b/include/StandardAnalyzer.h index ce202b59..58e28fca 100644 --- a/include/StandardAnalyzer.h +++ b/include/StandardAnalyzer.h @@ -9,78 +9,78 @@ #include "Analyzer.h" -namespace Lucene -{ - /// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter} and {@link StopFilter}, using - /// a list of English stop words. - /// - /// You must specify the required {@link Version} compatibility when creating StandardAnalyzer: - /// - ///
        - ///
      • As of 2.9, StopFilter preserves position increments - ///
      • As of 2.4, Tokens incorrectly identified as acronyms are corrected - ///
      - class LPPAPI StandardAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words ({@link #STOP_WORDS_SET}). - /// @param matchVersion Lucene version to match. - StandardAnalyzer(LuceneVersion::Version matchVersion); - - /// Builds an analyzer with the given stop words. - /// @param matchVersion Lucene version to match. - /// @param stopWords stop words - StandardAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords); - - /// Builds an analyzer with the stop words from the given file. - /// @see WordlistLoader#getWordSet(const String&, const String&) - /// @param matchVersion Lucene version to match. - /// @param stopwords File to read stop words from. - StandardAnalyzer(LuceneVersion::Version matchVersion, const String& stopwords); - - /// Builds an analyzer with the stop words from the given reader. - /// @see WordlistLoader#getWordSet(ReaderPtr, const String&) - /// @param matchVersion Lucene version to match. - /// @param stopwords Reader to read stop words from. - StandardAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords); - - virtual ~StandardAnalyzer(); - - LUCENE_CLASS(StandardAnalyzer); - - public: - /// Default maximum allowed token length - static const int32_t DEFAULT_MAX_TOKEN_LENGTH; - - protected: - HashSet stopSet; - - /// Specifies whether deprecated acronyms should be replaced with HOST type. - bool replaceInvalidAcronym; - bool enableStopPositionIncrements; - - LuceneVersion::Version matchVersion; - - int32_t maxTokenLength; - - protected: - /// Construct an analyzer with the given stop words. - void ConstructAnalyser(LuceneVersion::Version matchVersion, HashSet stopWords); - - public: - /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter} - /// and a {@link StopFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Set maximum allowed token length. If a token is seen that exceeds this length then it is discarded. This setting - /// only takes effect the next time tokenStream or reusableTokenStream is called. - void setMaxTokenLength(int32_t length); - - /// @see #setMaxTokenLength - int32_t getMaxTokenLength(); - - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +namespace Lucene { + +/// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter} and {@link StopFilter}, using +/// a list of English stop words. +/// +/// You must specify the required {@link Version} compatibility when creating StandardAnalyzer: +/// +///
        +///
      • As of 2.9, StopFilter preserves position increments +///
      • As of 2.4, Tokens incorrectly identified as acronyms are corrected +///
      +class LPPAPI StandardAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words ({@link #STOP_WORDS_SET}). + /// @param matchVersion Lucene version to match. + StandardAnalyzer(LuceneVersion::Version matchVersion); + + /// Builds an analyzer with the given stop words. + /// @param matchVersion Lucene version to match. + /// @param stopWords stop words + StandardAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords); + + /// Builds an analyzer with the stop words from the given file. + /// @see WordlistLoader#getWordSet(const String&, const String&) + /// @param matchVersion Lucene version to match. + /// @param stopwords File to read stop words from. + StandardAnalyzer(LuceneVersion::Version matchVersion, const String& stopwords); + + /// Builds an analyzer with the stop words from the given reader. + /// @see WordlistLoader#getWordSet(ReaderPtr, const String&) + /// @param matchVersion Lucene version to match. + /// @param stopwords Reader to read stop words from. + StandardAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords); + + virtual ~StandardAnalyzer(); + + LUCENE_CLASS(StandardAnalyzer); + +public: + /// Default maximum allowed token length + static const int32_t DEFAULT_MAX_TOKEN_LENGTH; + +protected: + HashSet stopSet; + + /// Specifies whether deprecated acronyms should be replaced with HOST type. + bool replaceInvalidAcronym; + bool enableStopPositionIncrements; + + LuceneVersion::Version matchVersion; + + int32_t maxTokenLength; + +protected: + /// Construct an analyzer with the given stop words. + void ConstructAnalyser(LuceneVersion::Version matchVersion, HashSet stopWords); + +public: + /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter} + /// and a {@link StopFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Set maximum allowed token length. If a token is seen that exceeds this length then it is discarded. This setting + /// only takes effect the next time tokenStream or reusableTokenStream is called. + void setMaxTokenLength(int32_t length); + + /// @see #setMaxTokenLength + int32_t getMaxTokenLength(); + + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + } #endif diff --git a/include/StandardFilter.h b/include/StandardFilter.h index 7158c39e..fa30bfab 100644 --- a/include/StandardFilter.h +++ b/include/StandardFilter.h @@ -9,33 +9,33 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// Normalizes tokens extracted with {@link StandardTokenizer}. - class LPPAPI StandardFilter : public TokenFilter - { - public: - /// Construct filtering input. - StandardFilter(const TokenStreamPtr& input); - virtual ~StandardFilter(); - - LUCENE_CLASS(StandardFilter); - - protected: - TypeAttributePtr typeAtt; - TermAttributePtr termAtt; - - protected: - static const String& APOSTROPHE_TYPE(); - static const String& ACRONYM_TYPE(); - - public: - /// Returns the next token in the stream, or null at EOS. - /// - /// Removes 's from the end of words. - /// Removes dots from acronyms. - virtual bool incrementToken(); - }; +namespace Lucene { + +/// Normalizes tokens extracted with {@link StandardTokenizer}. +class LPPAPI StandardFilter : public TokenFilter { +public: + /// Construct filtering input. + StandardFilter(const TokenStreamPtr& input); + virtual ~StandardFilter(); + + LUCENE_CLASS(StandardFilter); + +protected: + TypeAttributePtr typeAtt; + TermAttributePtr termAtt; + +protected: + static const String& APOSTROPHE_TYPE(); + static const String& ACRONYM_TYPE(); + +public: + /// Returns the next token in the stream, or null at EOS. + /// + /// Removes 's from the end of words. + /// Removes dots from acronyms. + virtual bool incrementToken(); +}; + } #endif diff --git a/include/StandardTokenizer.h b/include/StandardTokenizer.h index c6d9f057..050eda67 100644 --- a/include/StandardTokenizer.h +++ b/include/StandardTokenizer.h @@ -9,99 +9,99 @@ #include "Tokenizer.h" -namespace Lucene -{ - /// A grammar-based tokenizer - /// - /// This should be a good tokenizer for most European-language documents: - /// - ///
        - ///
      • Splits words at punctuation characters, removing punctuation. However, a dot that's not followed by - /// whitespace is considered part of a token. - ///
      • Splits words at hyphens, unless there's a number in the token, in which case the whole token is interpreted - /// as a product number and is not split. - ///
      • Recognizes email addresses and internet hostnames as one token. - ///
      - /// - /// Many applications have specific tokenizer needs. If this tokenizer does not suit your application, please consider - /// copying this source code directory to your project and maintaining your own grammar-based tokenizer. - /// - /// You must specify the required {@link Version} compatibility when creating StandardAnalyzer: - /// - ///
        - ///
      • As of 2.4, Tokens incorrectly identified as acronyms are corrected - ///
      - class LPPAPI StandardTokenizer : public Tokenizer - { - public: - /// Creates a new instance of the {@link StandardTokenizer}. Attaches the input to the newly created scanner. - /// @param input The input reader - StandardTokenizer(LuceneVersion::Version matchVersion, const ReaderPtr& input); - - /// Creates a new StandardTokenizer with a given {@link AttributeSource}. - StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeSourcePtr& source, const ReaderPtr& input); - - /// Creates a new StandardTokenizer with a given {@link AttributeSource.AttributeFactory} - StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~StandardTokenizer(); - - LUCENE_CLASS(StandardTokenizer); - - protected: - /// A private instance of the scanner - StandardTokenizerImplPtr scanner; - - bool replaceInvalidAcronym; - int32_t maxTokenLength; - - // this tokenizer generates three attributes: offset, positionIncrement and type - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; - PositionIncrementAttributePtr posIncrAtt; - TypeAttributePtr typeAtt; - - public: - static const int32_t ALPHANUM; - static const int32_t APOSTROPHE; - static const int32_t ACRONYM; - static const int32_t COMPANY; - static const int32_t EMAIL; - static const int32_t HOST; - static const int32_t NUM; - static const int32_t CJ; - - /// @deprecated this solves a bug where HOSTs that end with '.' are identified as ACRONYMs. - static const int32_t ACRONYM_DEP; - - /// String token types that correspond to token type int constants - static const Collection TOKEN_TYPES(); - - protected: - void init(const ReaderPtr& input, LuceneVersion::Version matchVersion); - - public: - /// Set the max allowed token length. Any token longer than this is skipped. - void setMaxTokenLength(int32_t length); - - /// @see #setMaxTokenLength - int32_t getMaxTokenLength(); - - /// @see TokenStream#next() - virtual bool incrementToken(); - - virtual void end(); - - virtual void reset(const ReaderPtr& input); - - /// @return true if StandardTokenizer now returns these tokens as Hosts, otherwise false - /// @deprecated Remove in 3.X and make true the only valid value - bool isReplaceInvalidAcronym(); - - /// @param replaceInvalidAcronym Set to true to replace mischaracterized acronyms as HOST. - /// @deprecated Remove in 3.X and make true the only valid value - void setReplaceInvalidAcronym(bool replaceInvalidAcronym); - }; +namespace Lucene { + +/// A grammar-based tokenizer +/// +/// This should be a good tokenizer for most European-language documents: +/// +///
        +///
      • Splits words at punctuation characters, removing punctuation. However, a dot that's not followed by +/// whitespace is considered part of a token. +///
      • Splits words at hyphens, unless there's a number in the token, in which case the whole token is interpreted +/// as a product number and is not split. +///
      • Recognizes email addresses and internet hostnames as one token. +///
      +/// +/// Many applications have specific tokenizer needs. If this tokenizer does not suit your application, please consider +/// copying this source code directory to your project and maintaining your own grammar-based tokenizer. +/// +/// You must specify the required {@link Version} compatibility when creating StandardAnalyzer: +/// +///
        +///
      • As of 2.4, Tokens incorrectly identified as acronyms are corrected +///
      +class LPPAPI StandardTokenizer : public Tokenizer { +public: + /// Creates a new instance of the {@link StandardTokenizer}. Attaches the input to the newly created scanner. + /// @param input The input reader + StandardTokenizer(LuceneVersion::Version matchVersion, const ReaderPtr& input); + + /// Creates a new StandardTokenizer with a given {@link AttributeSource}. + StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeSourcePtr& source, const ReaderPtr& input); + + /// Creates a new StandardTokenizer with a given {@link AttributeSource.AttributeFactory} + StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~StandardTokenizer(); + + LUCENE_CLASS(StandardTokenizer); + +protected: + /// A private instance of the scanner + StandardTokenizerImplPtr scanner; + + bool replaceInvalidAcronym; + int32_t maxTokenLength; + + // this tokenizer generates three attributes: offset, positionIncrement and type + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + PositionIncrementAttributePtr posIncrAtt; + TypeAttributePtr typeAtt; + +public: + static const int32_t ALPHANUM; + static const int32_t APOSTROPHE; + static const int32_t ACRONYM; + static const int32_t COMPANY; + static const int32_t EMAIL; + static const int32_t HOST; + static const int32_t NUM; + static const int32_t CJ; + + /// @deprecated this solves a bug where HOSTs that end with '.' are identified as ACRONYMs. + static const int32_t ACRONYM_DEP; + + /// String token types that correspond to token type int constants + static const Collection TOKEN_TYPES(); + +protected: + void init(const ReaderPtr& input, LuceneVersion::Version matchVersion); + +public: + /// Set the max allowed token length. Any token longer than this is skipped. + void setMaxTokenLength(int32_t length); + + /// @see #setMaxTokenLength + int32_t getMaxTokenLength(); + + /// @see TokenStream#next() + virtual bool incrementToken(); + + virtual void end(); + + virtual void reset(const ReaderPtr& input); + + /// @return true if StandardTokenizer now returns these tokens as Hosts, otherwise false + /// @deprecated Remove in 3.X and make true the only valid value + bool isReplaceInvalidAcronym(); + + /// @param replaceInvalidAcronym Set to true to replace mischaracterized acronyms as HOST. + /// @deprecated Remove in 3.X and make true the only valid value + void setReplaceInvalidAcronym(bool replaceInvalidAcronym); +}; + } #endif diff --git a/include/StandardTokenizerImpl.h b/include/StandardTokenizerImpl.h index a0e2a853..19e5321a 100644 --- a/include/StandardTokenizerImpl.h +++ b/include/StandardTokenizerImpl.h @@ -9,197 +9,197 @@ #include "LuceneObject.h" -namespace Lucene -{ - class StandardTokenizerImpl : public LuceneObject - { - public: - /// Creates a new scanner - /// @param in the Reader to read input from. - StandardTokenizerImpl(const ReaderPtr& in); +namespace Lucene { - virtual ~StandardTokenizerImpl(); +class StandardTokenizerImpl : public LuceneObject { +public: + /// Creates a new scanner + /// @param in the Reader to read input from. + StandardTokenizerImpl(const ReaderPtr& in); - LUCENE_CLASS(StandardTokenizerImpl); + virtual ~StandardTokenizerImpl(); - protected: - /// Initial size of the lookahead buffer - static const int32_t ZZ_BUFFERSIZE; + LUCENE_CLASS(StandardTokenizerImpl); - /// Translates characters to character classes - static CharArray _ZZ_CMAP; - static const wchar_t ZZ_CMAP_PACKED[]; - static const int32_t ZZ_CMAP_LENGTH; - static const int32_t ZZ_CMAP_PACKED_LENGTH; +protected: + /// Initial size of the lookahead buffer + static const int32_t ZZ_BUFFERSIZE; - /// Translates characters to character classes - static void ZZ_CMAP_INIT(); - static const wchar_t* ZZ_CMAP(); + /// Translates characters to character classes + static CharArray _ZZ_CMAP; + static const wchar_t ZZ_CMAP_PACKED[]; + static const int32_t ZZ_CMAP_LENGTH; + static const int32_t ZZ_CMAP_PACKED_LENGTH; - /// Translates DFA states to action switch labels. - static IntArray _ZZ_ACTION; - static const wchar_t ZZ_ACTION_PACKED_0[]; - static const int32_t ZZ_ACTION_LENGTH; - static const int32_t ZZ_ACTION_PACKED_LENGTH; + /// Translates characters to character classes + static void ZZ_CMAP_INIT(); + static const wchar_t* ZZ_CMAP(); - /// Translates DFA states to action switch labels. - static void ZZ_ACTION_INIT(); - static const int32_t* ZZ_ACTION(); + /// Translates DFA states to action switch labels. + static IntArray _ZZ_ACTION; + static const wchar_t ZZ_ACTION_PACKED_0[]; + static const int32_t ZZ_ACTION_LENGTH; + static const int32_t ZZ_ACTION_PACKED_LENGTH; - /// Translates a state to a row index in the transition table - static IntArray _ZZ_ROWMAP; - static const wchar_t ZZ_ROWMAP_PACKED_0[]; - static const int32_t ZZ_ROWMAP_LENGTH; - static const int32_t ZZ_ROWMAP_PACKED_LENGTH; + /// Translates DFA states to action switch labels. + static void ZZ_ACTION_INIT(); + static const int32_t* ZZ_ACTION(); - /// Translates a state to a row index in the transition table - static void ZZ_ROWMAP_INIT(); - static const int32_t* ZZ_ROWMAP(); + /// Translates a state to a row index in the transition table + static IntArray _ZZ_ROWMAP; + static const wchar_t ZZ_ROWMAP_PACKED_0[]; + static const int32_t ZZ_ROWMAP_LENGTH; + static const int32_t ZZ_ROWMAP_PACKED_LENGTH; - /// The transition table of the DFA - static IntArray _ZZ_TRANS; - static const wchar_t ZZ_TRANS_PACKED_0[]; - static const int32_t ZZ_TRANS_LENGTH; - static const int32_t ZZ_TRANS_PACKED_LENGTH; + /// Translates a state to a row index in the transition table + static void ZZ_ROWMAP_INIT(); + static const int32_t* ZZ_ROWMAP(); - /// The transition table of the DFA - static void ZZ_TRANS_INIT(); - static const int32_t* ZZ_TRANS(); + /// The transition table of the DFA + static IntArray _ZZ_TRANS; + static const wchar_t ZZ_TRANS_PACKED_0[]; + static const int32_t ZZ_TRANS_LENGTH; + static const int32_t ZZ_TRANS_PACKED_LENGTH; - // error codes - static const int32_t ZZ_UNKNOWN_ERROR; - static const int32_t ZZ_NO_MATCH; - static const int32_t ZZ_PUSHBACK_2BIG; + /// The transition table of the DFA + static void ZZ_TRANS_INIT(); + static const int32_t* ZZ_TRANS(); - static const wchar_t* ZZ_ERROR_MSG[]; + // error codes + static const int32_t ZZ_UNKNOWN_ERROR; + static const int32_t ZZ_NO_MATCH; + static const int32_t ZZ_PUSHBACK_2BIG; - /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState - static IntArray _ZZ_ATTRIBUTE; - static const wchar_t ZZ_ATTRIBUTE_PACKED_0[]; - static const int32_t ZZ_ATTRIBUTE_LENGTH; - static const int32_t ZZ_ATTRIBUTE_PACKED_LENGTH; + static const wchar_t* ZZ_ERROR_MSG[]; - /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState - static void ZZ_ATTRIBUTE_INIT(); - static const int32_t* ZZ_ATTRIBUTE(); + /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState + static IntArray _ZZ_ATTRIBUTE; + static const wchar_t ZZ_ATTRIBUTE_PACKED_0[]; + static const int32_t ZZ_ATTRIBUTE_LENGTH; + static const int32_t ZZ_ATTRIBUTE_PACKED_LENGTH; - /// The input device - ReaderPtr zzReader; + /// ZZ_ATTRIBUTE[aState] contains the attributes of state aState + static void ZZ_ATTRIBUTE_INIT(); + static const int32_t* ZZ_ATTRIBUTE(); - /// The current state of the DFA - int32_t zzState; + /// The input device + ReaderPtr zzReader; - /// The current lexical state - int32_t zzLexicalState; + /// The current state of the DFA + int32_t zzState; - /// This buffer contains the current text to be matched and is the source of the yytext() string - CharArray zzBuffer; + /// The current lexical state + int32_t zzLexicalState; - /// The text position at the last accepting state - int32_t zzMarkedPos; - - /// The text position at the last state to be included in yytext - int32_t zzPushbackPos; - - /// The current text position in the buffer - int32_t zzCurrentPos; - - /// StartRead marks the beginning of the yytext() string in the buffer - int32_t zzStartRead; - - /// EndRead marks the last character in the buffer, that has been read from input - int32_t zzEndRead; - - /// Number of newlines encountered up to the start of the matched text - int32_t yyline; - - /// The number of characters up to the start of the matched text - int32_t _yychar; + /// This buffer contains the current text to be matched and is the source of the yytext() string + CharArray zzBuffer; - /// The number of characters from the last newline up to the start of the matched text - int32_t yycolumn; + /// The text position at the last accepting state + int32_t zzMarkedPos; - /// zzAtBOL == true if the scanner is currently at the beginning of a line - bool zzAtBOL; + /// The text position at the last state to be included in yytext + int32_t zzPushbackPos; - /// zzAtEOF == true if the scanner is at the EOF - bool zzAtEOF; - - public: - /// This character denotes the end of file - static const int32_t YYEOF; - - /// Lexical states - static const int32_t YYINITIAL; + /// The current text position in the buffer + int32_t zzCurrentPos; - public: - int32_t yychar(); + /// StartRead marks the beginning of the yytext() string in the buffer + int32_t zzStartRead; - /// Resets the Tokenizer to a new Reader. - void reset(const ReaderPtr& r); + /// EndRead marks the last character in the buffer, that has been read from input + int32_t zzEndRead; - /// Fills Lucene token with the current token text. - void getText(const TokenPtr& t); + /// Number of newlines encountered up to the start of the matched text + int32_t yyline; - /// Fills TermAttribute with the current token text. - void getText(const TermAttributePtr& t); + /// The number of characters up to the start of the matched text + int32_t _yychar; - /// Closes the input stream. - void yyclose(); + /// The number of characters from the last newline up to the start of the matched text + int32_t yycolumn; - /// Resets the scanner to read from a new input stream. Does not close the old reader. - /// - /// All internal variables are reset, the old input stream cannot be reused (internal buffer is discarded and lost). - /// Lexical state is set to ZZ_INITIAL. - /// - /// @param reader the new input stream. - void yyreset(const ReaderPtr& reader); + /// zzAtBOL == true if the scanner is currently at the beginning of a line + bool zzAtBOL; - /// Returns the current lexical state. - int32_t yystate(); + /// zzAtEOF == true if the scanner is at the EOF + bool zzAtEOF; - /// Enters a new lexical state - /// @param newState the new lexical state. - void yybegin(int32_t newState); +public: + /// This character denotes the end of file + static const int32_t YYEOF; - /// Returns the text matched by the current regular expression. - String yytext(); + /// Lexical states + static const int32_t YYINITIAL; - /// Returns the character at position pos from the matched text. - /// - /// It is equivalent to yytext()[pos], but faster - /// @param pos the position of the character to fetch. A value from 0 to yylength() - 1. - /// @return the character at position pos. - wchar_t yycharat(int32_t pos); +public: + int32_t yychar(); - /// Returns the length of the matched text region. - int32_t yylength(); + /// Resets the Tokenizer to a new Reader. + void reset(const ReaderPtr& r); - /// Pushes the specified amount of characters back into the input stream. - /// - /// They will be read again by then next call of the scanning method - /// @param number the number of characters to be read again. This number must not be greater than yylength() - void yypushback(int32_t number); + /// Fills Lucene token with the current token text. + void getText(const TokenPtr& t); - /// Resumes scanning until the next regular expression is matched, the end of input is encountered or an I/O- - /// Error occurs. - int32_t getNextToken(); + /// Fills TermAttribute with the current token text. + void getText(const TermAttributePtr& t); - protected: - /// Refills the input buffer. - bool zzRefill(); + /// Closes the input stream. + void yyclose(); + + /// Resets the scanner to read from a new input stream. Does not close the old reader. + /// + /// All internal variables are reset, the old input stream cannot be reused (internal buffer is discarded and lost). + /// Lexical state is set to ZZ_INITIAL. + /// + /// @param reader the new input stream. + void yyreset(const ReaderPtr& reader); + + /// Returns the current lexical state. + int32_t yystate(); + + /// Enters a new lexical state + /// @param newState the new lexical state. + void yybegin(int32_t newState); + + /// Returns the text matched by the current regular expression. + String yytext(); + + /// Returns the character at position pos from the matched text. + /// + /// It is equivalent to yytext()[pos], but faster + /// @param pos the position of the character to fetch. A value from 0 to yylength() - 1. + /// @return the character at position pos. + wchar_t yycharat(int32_t pos); + + /// Returns the length of the matched text region. + int32_t yylength(); + + /// Pushes the specified amount of characters back into the input stream. + /// + /// They will be read again by then next call of the scanning method + /// @param number the number of characters to be read again. This number must not be greater than yylength() + void yypushback(int32_t number); + + /// Resumes scanning until the next regular expression is matched, the end of input is encountered or an I/O- + /// Error occurs. + int32_t getNextToken(); + +protected: + /// Refills the input buffer. + bool zzRefill(); + + /// Reports an error that occurred while scanning. + /// + /// In a well-formed scanner (no or only correct usage of yypushback(int32_t) and a match-all fallback rule) + /// this method will only be called with things that "Can't Possibly Happen". If this method is called, + /// something is seriously wrong. + /// + /// Usual syntax/scanner level error handling should be done in error fallback rules. + /// + /// @param errorCode The code of the errormessage to display. + void zzScanError(int32_t errorCode); +}; - /// Reports an error that occurred while scanning. - /// - /// In a well-formed scanner (no or only correct usage of yypushback(int32_t) and a match-all fallback rule) - /// this method will only be called with things that "Can't Possibly Happen". If this method is called, - /// something is seriously wrong. - /// - /// Usual syntax/scanner level error handling should be done in error fallback rules. - /// - /// @param errorCode The code of the errormessage to display. - void zzScanError(int32_t errorCode); - }; } #endif diff --git a/include/StopAnalyzer.h b/include/StopAnalyzer.h index a8ed37e7..179262d9 100644 --- a/include/StopAnalyzer.h +++ b/include/StopAnalyzer.h @@ -9,44 +9,44 @@ #include "Analyzer.h" -namespace Lucene -{ - /// Filters {@link LetterTokenizer} with {@link LowerCaseFilter} and {@link StopFilter}. - /// - /// You must specify the required {@link Version} compatibility when creating StopAnalyzer: As of 2.9, position - /// increments are preserved - class LPPAPI StopAnalyzer : public Analyzer - { - public: - /// Builds an analyzer which removes words in {@link #ENGLISH_STOP_WORDS_SET}. - StopAnalyzer(LuceneVersion::Version matchVersion); +namespace Lucene { - /// Builds an analyzer with the stop words from the given set. - StopAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords); +/// Filters {@link LetterTokenizer} with {@link LowerCaseFilter} and {@link StopFilter}. +/// +/// You must specify the required {@link Version} compatibility when creating StopAnalyzer: As of 2.9, position +/// increments are preserved +class LPPAPI StopAnalyzer : public Analyzer { +public: + /// Builds an analyzer which removes words in {@link #ENGLISH_STOP_WORDS_SET}. + StopAnalyzer(LuceneVersion::Version matchVersion); - /// Builds an analyzer with the stop words from the given file. - StopAnalyzer(LuceneVersion::Version matchVersion, const String& stopwordsFile); + /// Builds an analyzer with the stop words from the given set. + StopAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords); - /// Builds an analyzer with the stop words from the given reader. - StopAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords); + /// Builds an analyzer with the stop words from the given file. + StopAnalyzer(LuceneVersion::Version matchVersion, const String& stopwordsFile); - virtual ~StopAnalyzer(); + /// Builds an analyzer with the stop words from the given reader. + StopAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords); - LUCENE_CLASS(StopAnalyzer); + virtual ~StopAnalyzer(); - protected: - HashSet stopWords; - bool enablePositionIncrements; + LUCENE_CLASS(StopAnalyzer); - static const wchar_t* _ENGLISH_STOP_WORDS_SET[]; +protected: + HashSet stopWords; + bool enablePositionIncrements; - public: - /// An unmodifiable set containing some common English words that are usually not useful for searching. - static const HashSet ENGLISH_STOP_WORDS_SET(); + static const wchar_t* _ENGLISH_STOP_WORDS_SET[]; + +public: + /// An unmodifiable set containing some common English words that are usually not useful for searching. + static const HashSet ENGLISH_STOP_WORDS_SET(); + + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; } #endif diff --git a/include/StopFilter.h b/include/StopFilter.h index d6e0f9a9..93c52a52 100644 --- a/include/StopFilter.h +++ b/include/StopFilter.h @@ -9,60 +9,60 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// Removes stop words from a token stream. - class LPPAPI StopFilter : public TokenFilter - { - public: - /// Construct a token stream filtering the given input. If stopWords is an instance of {@link CharArraySet} - /// (true if makeStopSet() was used to construct the set) it will be directly used and ignoreCase will be - /// ignored since CharArraySet directly controls case sensitivity. - /// - /// If stopWords is not an instance of {@link CharArraySet}, a new CharArraySet will be constructed and - /// ignoreCase will be used to specify the case sensitivity of that set. - /// - /// @param enablePositionIncrements true if token positions should record the removed stop words - /// @param input Input TokenStream - /// @param stopWords A Set of Strings or char[] or any other toString()-able set representing the stopwords - /// @param ignoreCase if true, all words are lower cased first - StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, HashSet stopWords, bool ignoreCase = false); - StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, const CharArraySetPtr& stopWords, bool ignoreCase = false); +namespace Lucene { - virtual ~StopFilter(); +/// Removes stop words from a token stream. +class LPPAPI StopFilter : public TokenFilter { +public: + /// Construct a token stream filtering the given input. If stopWords is an instance of {@link CharArraySet} + /// (true if makeStopSet() was used to construct the set) it will be directly used and ignoreCase will be + /// ignored since CharArraySet directly controls case sensitivity. + /// + /// If stopWords is not an instance of {@link CharArraySet}, a new CharArraySet will be constructed and + /// ignoreCase will be used to specify the case sensitivity of that set. + /// + /// @param enablePositionIncrements true if token positions should record the removed stop words + /// @param input Input TokenStream + /// @param stopWords A Set of Strings or char[] or any other toString()-able set representing the stopwords + /// @param ignoreCase if true, all words are lower cased first + StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, HashSet stopWords, bool ignoreCase = false); + StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, const CharArraySetPtr& stopWords, bool ignoreCase = false); - LUCENE_CLASS(StopFilter); + virtual ~StopFilter(); - protected: - CharArraySetPtr stopWords; - bool enablePositionIncrements; + LUCENE_CLASS(StopFilter); - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncrAtt; +protected: + CharArraySetPtr stopWords; + bool enablePositionIncrements; - public: - /// Builds a Set from an array of stop words, appropriate for passing into the StopFilter constructor. - static HashSet makeStopSet(Collection stopWords); + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncrAtt; - /// Returns the next input Token whose term() is not a stop word. - virtual bool incrementToken(); +public: + /// Builds a Set from an array of stop words, appropriate for passing into the StopFilter constructor. + static HashSet makeStopSet(Collection stopWords); - /// Returns version-dependent default for enablePositionIncrements. Analyzers that embed StopFilter use this - /// method when creating the StopFilter. Prior to 2.9, this returns false. On 2.9 or later, it returns true. - static bool getEnablePositionIncrementsVersionDefault(LuceneVersion::Version matchVersion); + /// Returns the next input Token whose term() is not a stop word. + virtual bool incrementToken(); - /// @see #setEnablePositionIncrements(bool). - bool getEnablePositionIncrements(); + /// Returns version-dependent default for enablePositionIncrements. Analyzers that embed StopFilter use this + /// method when creating the StopFilter. Prior to 2.9, this returns false. On 2.9 or later, it returns true. + static bool getEnablePositionIncrementsVersionDefault(LuceneVersion::Version matchVersion); + + /// @see #setEnablePositionIncrements(bool). + bool getEnablePositionIncrements(); + + /// If true, this StopFilter will preserve positions of the incoming tokens (ie, accumulate and set position + /// increments of the removed stop tokens). Generally, true is best as it does not lose information (positions + /// of the original tokens) during indexing. + /// + /// When set, when a token is stopped (omitted), the position increment of the following token is incremented. + /// + /// NOTE: be sure to also set {@link QueryParser#setEnablePositionIncrements} if you use QueryParser to create queries. + void setEnablePositionIncrements(bool enable); +}; - /// If true, this StopFilter will preserve positions of the incoming tokens (ie, accumulate and set position - /// increments of the removed stop tokens). Generally, true is best as it does not lose information (positions - /// of the original tokens) during indexing. - /// - /// When set, when a token is stopped (omitted), the position increment of the following token is incremented. - /// - /// NOTE: be sure to also set {@link QueryParser#setEnablePositionIncrements} if you use QueryParser to create queries. - void setEnablePositionIncrements(bool enable); - }; } #endif diff --git a/include/StoredFieldsWriter.h b/include/StoredFieldsWriter.h index 802ecb7c..ca3c67bb 100644 --- a/include/StoredFieldsWriter.h +++ b/include/StoredFieldsWriter.h @@ -9,67 +9,66 @@ #include "DocumentsWriter.h" -namespace Lucene -{ - /// This is a DocFieldConsumer that writes stored fields. - class StoredFieldsWriter : public LuceneObject - { - public: - StoredFieldsWriter(const DocumentsWriterPtr& docWriter, const FieldInfosPtr& fieldInfos); - virtual ~StoredFieldsWriter(); - - LUCENE_CLASS(StoredFieldsWriter); - - public: - FieldsWriterPtr fieldsWriter; - DocumentsWriterWeakPtr _docWriter; - FieldInfosPtr fieldInfos; - int32_t lastDocID; - - Collection docFreeList; - int32_t freeCount; - int32_t allocCount; - - public: - StoredFieldsWriterPerThreadPtr addThread(const DocStatePtr& docState); - void flush(const SegmentWriteStatePtr& state); - void closeDocStore(const SegmentWriteStatePtr& state); - StoredFieldsWriterPerDocPtr getPerDoc(); - void abort(); - - /// Fills in any hole in the docIDs - void fill(int32_t docID); - - void finishDocument(const StoredFieldsWriterPerDocPtr& perDoc); - bool freeRAM(); - void free(const StoredFieldsWriterPerDocPtr& perDoc); - - protected: - void initFieldsWriter(); - }; - - class StoredFieldsWriterPerDoc : public DocWriter - { - public: - StoredFieldsWriterPerDoc(const StoredFieldsWriterPtr& fieldsWriter); - virtual ~StoredFieldsWriterPerDoc(); - - LUCENE_CLASS(StoredFieldsWriterPerDoc); - - protected: - StoredFieldsWriterWeakPtr _fieldsWriter; - - public: - PerDocBufferPtr buffer; - RAMOutputStreamPtr fdt; - int32_t numStoredFields; - - public: - void reset(); - virtual void abort(); - virtual int64_t sizeInBytes(); - virtual void finish(); - }; +namespace Lucene { + +/// This is a DocFieldConsumer that writes stored fields. +class StoredFieldsWriter : public LuceneObject { +public: + StoredFieldsWriter(const DocumentsWriterPtr& docWriter, const FieldInfosPtr& fieldInfos); + virtual ~StoredFieldsWriter(); + + LUCENE_CLASS(StoredFieldsWriter); + +public: + FieldsWriterPtr fieldsWriter; + DocumentsWriterWeakPtr _docWriter; + FieldInfosPtr fieldInfos; + int32_t lastDocID; + + Collection docFreeList; + int32_t freeCount; + int32_t allocCount; + +public: + StoredFieldsWriterPerThreadPtr addThread(const DocStatePtr& docState); + void flush(const SegmentWriteStatePtr& state); + void closeDocStore(const SegmentWriteStatePtr& state); + StoredFieldsWriterPerDocPtr getPerDoc(); + void abort(); + + /// Fills in any hole in the docIDs + void fill(int32_t docID); + + void finishDocument(const StoredFieldsWriterPerDocPtr& perDoc); + bool freeRAM(); + void free(const StoredFieldsWriterPerDocPtr& perDoc); + +protected: + void initFieldsWriter(); +}; + +class StoredFieldsWriterPerDoc : public DocWriter { +public: + StoredFieldsWriterPerDoc(const StoredFieldsWriterPtr& fieldsWriter); + virtual ~StoredFieldsWriterPerDoc(); + + LUCENE_CLASS(StoredFieldsWriterPerDoc); + +protected: + StoredFieldsWriterWeakPtr _fieldsWriter; + +public: + PerDocBufferPtr buffer; + RAMOutputStreamPtr fdt; + int32_t numStoredFields; + +public: + void reset(); + virtual void abort(); + virtual int64_t sizeInBytes(); + virtual void finish(); +}; + } #endif diff --git a/include/StoredFieldsWriterPerThread.h b/include/StoredFieldsWriterPerThread.h index 2266da03..a20e1dd7 100644 --- a/include/StoredFieldsWriterPerThread.h +++ b/include/StoredFieldsWriterPerThread.h @@ -9,29 +9,29 @@ #include "LuceneObject.h" -namespace Lucene -{ - class StoredFieldsWriterPerThread : public LuceneObject - { - public: - StoredFieldsWriterPerThread(const DocStatePtr& docState, const StoredFieldsWriterPtr& storedFieldsWriter); - virtual ~StoredFieldsWriterPerThread(); - - LUCENE_CLASS(StoredFieldsWriterPerThread); - - public: - FieldsWriterPtr localFieldsWriter; - StoredFieldsWriterWeakPtr _storedFieldsWriter; - DocStatePtr docState; - - StoredFieldsWriterPerDocPtr doc; - - public: - void startDocument(); - void addField(const FieldablePtr& field, const FieldInfoPtr& fieldInfo); - DocWriterPtr finishDocument(); - void abort(); - }; +namespace Lucene { + +class StoredFieldsWriterPerThread : public LuceneObject { +public: + StoredFieldsWriterPerThread(const DocStatePtr& docState, const StoredFieldsWriterPtr& storedFieldsWriter); + virtual ~StoredFieldsWriterPerThread(); + + LUCENE_CLASS(StoredFieldsWriterPerThread); + +public: + FieldsWriterPtr localFieldsWriter; + StoredFieldsWriterWeakPtr _storedFieldsWriter; + DocStatePtr docState; + + StoredFieldsWriterPerDocPtr doc; + +public: + void startDocument(); + void addField(const FieldablePtr& field, const FieldInfoPtr& fieldInfo); + DocWriterPtr finishDocument(); + void abort(); +}; + } #endif diff --git a/include/StringReader.h b/include/StringReader.h index e048cf2f..3684294a 100644 --- a/include/StringReader.h +++ b/include/StringReader.h @@ -9,41 +9,41 @@ #include "Reader.h" -namespace Lucene -{ - /// Convenience class for reading strings. - class LPPAPI StringReader : public Reader - { - public: - /// Creates a new StringReader, given the String to read from. - StringReader(const String& str); - virtual ~StringReader(); +namespace Lucene { - LUCENE_CLASS(StringReader); +/// Convenience class for reading strings. +class LPPAPI StringReader : public Reader { +public: + /// Creates a new StringReader, given the String to read from. + StringReader(const String& str); + virtual ~StringReader(); - protected: - String str; - int32_t position; + LUCENE_CLASS(StringReader); - public: - /// Read a single character. - virtual int32_t read(); +protected: + String str; + int32_t position; - /// Read characters into a portion of an array. - virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); +public: + /// Read a single character. + virtual int32_t read(); - /// Close the stream. - virtual void close(); + /// Read characters into a portion of an array. + virtual int32_t read(wchar_t* buffer, int32_t offset, int32_t length); - /// Tell whether this stream supports the mark() operation - virtual bool markSupported(); + /// Close the stream. + virtual void close(); - /// Reset the stream. - virtual void reset(); + /// Tell whether this stream supports the mark() operation + virtual bool markSupported(); + + /// Reset the stream. + virtual void reset(); + + /// The number of bytes in the stream. + virtual int64_t length(); +}; - /// The number of bytes in the stream. - virtual int64_t length(); - }; } #endif diff --git a/include/StringUtils.h b/include/StringUtils.h index 022851d2..2b698d55 100644 --- a/include/StringUtils.h +++ b/include/StringUtils.h @@ -9,89 +9,87 @@ #include "Lucene.h" -namespace Lucene -{ - class LPPAPI StringUtils - { - public: - /// Maximum length of UTF encoding. - static const int32_t MAX_ENCODING_UTF8_SIZE; +namespace Lucene { - /// Default character radix. - static const int32_t CHARACTER_MAX_RADIX; +class LPPAPI StringUtils { +public: + /// Maximum length of UTF encoding. + static const int32_t MAX_ENCODING_UTF8_SIZE; - public: - /// Convert uft8 buffer into unicode. - static int32_t toUnicode(const uint8_t* utf8, int32_t length, CharArray unicode); + /// Default character radix. + static const int32_t CHARACTER_MAX_RADIX; - /// Convert uft8 buffer into unicode. - static int32_t toUnicode(const uint8_t* utf8, int32_t length, const UnicodeResultPtr& unicodeResult); +public: + /// Convert uft8 buffer into unicode. + static int32_t toUnicode(const uint8_t* utf8, int32_t length, CharArray unicode); - /// Convert uft8 buffer into unicode. - static String toUnicode(const uint8_t* utf8, int32_t length); + /// Convert uft8 buffer into unicode. + static int32_t toUnicode(const uint8_t* utf8, int32_t length, const UnicodeResultPtr& unicodeResult); - /// Convert uft8 string into unicode. - static String toUnicode(const SingleString& s); + /// Convert uft8 buffer into unicode. + static String toUnicode(const uint8_t* utf8, int32_t length); - /// Convert unicode buffer into uft8. - static int32_t toUTF8(const wchar_t* unicode, int32_t length, ByteArray utf8); + /// Convert uft8 string into unicode. + static String toUnicode(const SingleString& s); - /// Convert unicode buffer into uft8. - static int32_t toUTF8(const wchar_t* unicode, int32_t length, const UTF8ResultPtr& utf8Result); + /// Convert unicode buffer into uft8. + static int32_t toUTF8(const wchar_t* unicode, int32_t length, ByteArray utf8); - /// Convert unicode buffer into uft8. - static SingleString toUTF8(const wchar_t* unicode, int32_t length); + /// Convert unicode buffer into uft8. + static int32_t toUTF8(const wchar_t* unicode, int32_t length, const UTF8ResultPtr& utf8Result); - /// Convert unicode string into uft8. - static SingleString toUTF8(const String& s); + /// Convert unicode buffer into uft8. + static SingleString toUTF8(const wchar_t* unicode, int32_t length); - /// Convert given string to lower case using current locale - static void toLower(String& str); + /// Convert unicode string into uft8. + static SingleString toUTF8(const String& s); - /// Convert given string to lower case using current locale - static String toLower(const String& str); + /// Convert given string to lower case using current locale + static void toLower(String& str); - /// Convert given string to upper case using current locale - static void toUpper(String& str); + /// Convert given string to lower case using current locale + static String toLower(const String& str); - /// Convert given string to upper case using current locale - static String toUpper(const String& str); + /// Convert given string to upper case using current locale + static void toUpper(String& str); - /// Compare two strings ignoring case differences - static int32_t compareCase(const String& first, const String& second); + /// Convert given string to upper case using current locale + static String toUpper(const String& str); - /// Splits string using given delimiters - static Collection split(const String& str, const String& delim); + /// Compare two strings ignoring case differences + static int32_t compareCase(const String& first, const String& second); - /// Convert the given string to int32_t. - static int32_t toInt(const String& value); + /// Splits string using given delimiters + static Collection split(const String& str, const String& delim); - /// Convert the given string to int64_t. - static int64_t toLong(const String& value); + /// Convert the given string to int32_t. + static int32_t toInt(const String& value); - /// Return given value as a long integer using base unit. - static int64_t toLong(const String& value, int32_t base); + /// Convert the given string to int64_t. + static int64_t toLong(const String& value); - /// Convert the given string to double. - static double toDouble(const String& value); + /// Return given value as a long integer using base unit. + static int64_t toLong(const String& value, int32_t base); - /// Compute the hash code from string. - static int32_t hashCode(const String& value); + /// Convert the given string to double. + static double toDouble(const String& value); - /// Return given value as a string using base unit. - static String toString(int64_t value, int32_t base); + /// Compute the hash code from string. + static int32_t hashCode(const String& value); - /// Convert any given type to a {@link String}. - template - static String toString(const TYPE& value) - { - StringStream os; - os << value; - return os.str(); - } - }; + /// Return given value as a string using base unit. + static String toString(int64_t value, int32_t base); - #define UTF8_TO_STRING(utf8) StringUtils::toUnicode(utf8, SIZEOF_ARRAY(utf8)) + /// Convert any given type to a {@link String}. + template + static String toString(const TYPE& value) { + StringStream os; + os << value; + return os.str(); + } +}; + +#define UTF8_TO_STRING(utf8) StringUtils::toUnicode(utf8, SIZEOF_ARRAY(utf8)) } #endif diff --git a/include/Synchronize.h b/include/Synchronize.h index 5afb0eb0..d8ba7428 100644 --- a/include/Synchronize.h +++ b/include/Synchronize.h @@ -10,58 +10,56 @@ #include #include "Lucene.h" -namespace Lucene -{ - /// Utility class to support locking via a mutex. - class LPPAPI Synchronize - { - public: - Synchronize(); - virtual ~Synchronize(); - - protected: - boost::recursive_timed_mutex mutexSynchronize; - int64_t lockThread; - int32_t recursionCount; - - public: - /// create a new Synchronize instance atomically. - static void createSync(SynchronizePtr& sync); - - /// Lock mutex using an optional timeout. - void lock(int32_t timeout = 0); - - /// Unlock mutex. - void unlock(); - - /// Unlock all recursive mutex. - int32_t unlockAll(); - - /// Returns true if mutex is currently locked by current thread. - bool holdsLock(); - }; - - /// Utility class to support scope locking. - class LPPAPI SyncLock - { - public: - SyncLock(const SynchronizePtr& sync, int32_t timeout = 0); - - template - SyncLock(OBJECT object, int32_t timeout = 0) - { - this->sync = object->getSync(); - lock(timeout); - } - - virtual ~SyncLock(); - - protected: - SynchronizePtr sync; - - protected: - void lock(int32_t timeout); - }; +namespace Lucene { + +/// Utility class to support locking via a mutex. +class LPPAPI Synchronize { +public: + Synchronize(); + virtual ~Synchronize(); + +protected: + boost::recursive_timed_mutex mutexSynchronize; + int64_t lockThread; + int32_t recursionCount; + +public: + /// create a new Synchronize instance atomically. + static void createSync(SynchronizePtr& sync); + + /// Lock mutex using an optional timeout. + void lock(int32_t timeout = 0); + + /// Unlock mutex. + void unlock(); + + /// Unlock all recursive mutex. + int32_t unlockAll(); + + /// Returns true if mutex is currently locked by current thread. + bool holdsLock(); +}; + +/// Utility class to support scope locking. +class LPPAPI SyncLock { +public: + SyncLock(const SynchronizePtr& sync, int32_t timeout = 0); + + template + SyncLock(OBJECT object, int32_t timeout = 0) { + this->sync = object->getSync(); + lock(timeout); + } + + virtual ~SyncLock(); + +protected: + SynchronizePtr sync; + +protected: + void lock(int32_t timeout); +}; + } #endif diff --git a/include/TeeSinkTokenFilter.h b/include/TeeSinkTokenFilter.h index cd0e1974..65530354 100644 --- a/include/TeeSinkTokenFilter.h +++ b/include/TeeSinkTokenFilter.h @@ -10,143 +10,140 @@ #include "TokenFilter.h" #include "TokenStream.h" -namespace Lucene -{ - /// This TokenFilter provides the ability to set aside attribute states that have already been analyzed. This is - /// useful in situations where multiple fields share many common analysis steps and then go their separate ways. - /// - /// It is also useful for doing things like entity extraction or proper noun analysis as part of the analysis workflow - /// and saving off those tokens for use in another field. - /// - ///
      -    /// TeeSinkTokenFilterPtr source1 = newLucene(newLucene(reader1));
      -    /// SinkTokenStreamPtr sink1 = source1->newSinkTokenStream();
      -    /// SinkTokenStreamPtr sink2 = source1->newSinkTokenStream();
      -    ///
      -    /// TeeSinkTokenFilterPtr source2 = newLucene(newLucene(reader2));
      -    /// source2->addSinkTokenStream(sink1);
      -    /// source2->addSinkTokenStream(sink2);
      -    ///
      -    /// TokenStreamPtr final1 = newLucene(source1);
      -    /// TokenStreamPtr final2 = source2;
      -    /// TokenStreamPtr final3 = newLucene(sink1);
      -    /// TokenStreamPtr final4 = newLucene(sink2);
      -    ///
      -    /// d->add(newLucene(L"f1", final1));
      -    /// d->add(newLucene(L"f2", final2));
      -    /// d->add(newLucene(L"f3", final3));
      -    /// d->add(newLucene(L"f4", final4));
      -    /// 
      - /// - /// In this example, sink1 and sink2 will both get tokens from both reader1 and reader2 after whitespace tokenizer - /// and now we can further wrap any of these in extra analysis, and more "sources" can be inserted if desired. - /// It is important, that tees are consumed before sinks (in the above example, the field names must be less the - /// sink's field names). If you are not sure, which stream is consumed first, you can simply add another sink and - /// then pass all tokens to the sinks at once using {@link #consumeAllTokens}. - /// - /// This TokenFilter is exhausted after this. In the above example, change the example above to: - /// - ///
      -    /// ...
      -    /// TokenStreamPtr final1 = newLucene(source1->newSinkTokenStream());
      -    /// TokenStreamPtr final2 = source2->newSinkTokenStream();
      -    /// sink1->consumeAllTokens();
      -    /// sink2->consumeAllTokens();
      -    /// ...
      -    /// 
      - /// - /// In this case, the fields can be added in any order, because the sources are not used anymore and all sinks are - /// ready. - /// - /// Note, the EntityDetect and URLDetect TokenStreams are for the example and do not currently exist in Lucene. - class LPPAPI TeeSinkTokenFilter : public TokenFilter - { - public: - /// Instantiates a new TeeSinkTokenFilter. - TeeSinkTokenFilter(const TokenStreamPtr& input); - virtual ~TeeSinkTokenFilter(); - - LUCENE_CLASS(TeeSinkTokenFilter); - - protected: - Collection sinks; - - public: - /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream. - SinkTokenStreamPtr newSinkTokenStream(); - - /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream that pass - /// the supplied filter. - /// @see SinkFilter - SinkTokenStreamPtr newSinkTokenStream(const SinkFilterPtr& filter); - - /// Adds a {@link SinkTokenStream} created by another TeeSinkTokenFilter to this one. The supplied stream will - /// also receive all consumed tokens. This method can be used to pass tokens from two different tees to one sink. - void addSinkTokenStream(const SinkTokenStreamPtr& sink); - - /// TeeSinkTokenFilter passes all tokens to the added sinks when itself is consumed. To be sure, that all tokens - /// from the input stream are passed to the sinks, you can call this methods. This instance is exhausted after this, - /// but all sinks are instant available. - void consumeAllTokens(); - - virtual bool incrementToken(); - virtual void end(); - }; - - class LPPAPI SinkFilter : public LuceneObject - { - public: - virtual ~SinkFilter(); - - LUCENE_CLASS(SinkFilter); - - public: - /// Returns true, if the current state of the passed-in {@link AttributeSource} shall be stored in the sink. - virtual bool accept(const AttributeSourcePtr& source) = 0; - - /// Called by {@link SinkTokenStream#reset()}. This method does nothing by default and can optionally be overridden. - virtual void reset(); - }; - - class LPPAPI AcceptAllSinkFilter : public SinkFilter - { - public: - virtual ~AcceptAllSinkFilter(); - - LUCENE_CLASS(AcceptAllSinkFilter); - - public: - virtual bool accept(const AttributeSourcePtr& source); - }; - - /// A filter that decides which {@link AttributeSource} states to store in the sink. - class LPPAPI SinkTokenStream : public TokenStream - { - public: - SinkTokenStream(const AttributeSourcePtr& source, const SinkFilterPtr& filter); - virtual ~SinkTokenStream(); - - LUCENE_CLASS(SinkTokenStream); - - protected: - Collection cachedStates; - AttributeSourceStatePtr finalState; - bool initIterator; - Collection::iterator it; - SinkFilterPtr filter; - - protected: - bool accept(const AttributeSourcePtr& source); - void addState(const AttributeSourceStatePtr& state); - void setFinalState(const AttributeSourceStatePtr& finalState); - - public: - virtual bool incrementToken(); - virtual void end(); - virtual void reset(); - - friend class TeeSinkTokenFilter; - }; +namespace Lucene { + +/// This TokenFilter provides the ability to set aside attribute states that have already been analyzed. This is +/// useful in situations where multiple fields share many common analysis steps and then go their separate ways. +/// +/// It is also useful for doing things like entity extraction or proper noun analysis as part of the analysis workflow +/// and saving off those tokens for use in another field. +/// +///
      +/// TeeSinkTokenFilterPtr source1 = newLucene(newLucene(reader1));
      +/// SinkTokenStreamPtr sink1 = source1->newSinkTokenStream();
      +/// SinkTokenStreamPtr sink2 = source1->newSinkTokenStream();
      +///
      +/// TeeSinkTokenFilterPtr source2 = newLucene(newLucene(reader2));
      +/// source2->addSinkTokenStream(sink1);
      +/// source2->addSinkTokenStream(sink2);
      +///
      +/// TokenStreamPtr final1 = newLucene(source1);
      +/// TokenStreamPtr final2 = source2;
      +/// TokenStreamPtr final3 = newLucene(sink1);
      +/// TokenStreamPtr final4 = newLucene(sink2);
      +///
      +/// d->add(newLucene(L"f1", final1));
      +/// d->add(newLucene(L"f2", final2));
      +/// d->add(newLucene(L"f3", final3));
      +/// d->add(newLucene(L"f4", final4));
      +/// 
      +/// +/// In this example, sink1 and sink2 will both get tokens from both reader1 and reader2 after whitespace tokenizer +/// and now we can further wrap any of these in extra analysis, and more "sources" can be inserted if desired. +/// It is important, that tees are consumed before sinks (in the above example, the field names must be less the +/// sink's field names). If you are not sure, which stream is consumed first, you can simply add another sink and +/// then pass all tokens to the sinks at once using {@link #consumeAllTokens}. +/// +/// This TokenFilter is exhausted after this. In the above example, change the example above to: +/// +///
      +/// ...
      +/// TokenStreamPtr final1 = newLucene(source1->newSinkTokenStream());
      +/// TokenStreamPtr final2 = source2->newSinkTokenStream();
      +/// sink1->consumeAllTokens();
      +/// sink2->consumeAllTokens();
      +/// ...
      +/// 
      +/// +/// In this case, the fields can be added in any order, because the sources are not used anymore and all sinks are +/// ready. +/// +/// Note, the EntityDetect and URLDetect TokenStreams are for the example and do not currently exist in Lucene. +class LPPAPI TeeSinkTokenFilter : public TokenFilter { +public: + /// Instantiates a new TeeSinkTokenFilter. + TeeSinkTokenFilter(const TokenStreamPtr& input); + virtual ~TeeSinkTokenFilter(); + + LUCENE_CLASS(TeeSinkTokenFilter); + +protected: + Collection sinks; + +public: + /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream. + SinkTokenStreamPtr newSinkTokenStream(); + + /// Returns a new {@link SinkTokenStream} that receives all tokens consumed by this stream that pass + /// the supplied filter. + /// @see SinkFilter + SinkTokenStreamPtr newSinkTokenStream(const SinkFilterPtr& filter); + + /// Adds a {@link SinkTokenStream} created by another TeeSinkTokenFilter to this one. The supplied stream will + /// also receive all consumed tokens. This method can be used to pass tokens from two different tees to one sink. + void addSinkTokenStream(const SinkTokenStreamPtr& sink); + + /// TeeSinkTokenFilter passes all tokens to the added sinks when itself is consumed. To be sure, that all tokens + /// from the input stream are passed to the sinks, you can call this methods. This instance is exhausted after this, + /// but all sinks are instant available. + void consumeAllTokens(); + + virtual bool incrementToken(); + virtual void end(); +}; + +class LPPAPI SinkFilter : public LuceneObject { +public: + virtual ~SinkFilter(); + + LUCENE_CLASS(SinkFilter); + +public: + /// Returns true, if the current state of the passed-in {@link AttributeSource} shall be stored in the sink. + virtual bool accept(const AttributeSourcePtr& source) = 0; + + /// Called by {@link SinkTokenStream#reset()}. This method does nothing by default and can optionally be overridden. + virtual void reset(); +}; + +class LPPAPI AcceptAllSinkFilter : public SinkFilter { +public: + virtual ~AcceptAllSinkFilter(); + + LUCENE_CLASS(AcceptAllSinkFilter); + +public: + virtual bool accept(const AttributeSourcePtr& source); +}; + +/// A filter that decides which {@link AttributeSource} states to store in the sink. +class LPPAPI SinkTokenStream : public TokenStream { +public: + SinkTokenStream(const AttributeSourcePtr& source, const SinkFilterPtr& filter); + virtual ~SinkTokenStream(); + + LUCENE_CLASS(SinkTokenStream); + +protected: + Collection cachedStates; + AttributeSourceStatePtr finalState; + bool initIterator; + Collection::iterator it; + SinkFilterPtr filter; + +protected: + bool accept(const AttributeSourcePtr& source); + void addState(const AttributeSourceStatePtr& state); + void setFinalState(const AttributeSourceStatePtr& finalState); + +public: + virtual bool incrementToken(); + virtual void end(); + virtual void reset(); + + friend class TeeSinkTokenFilter; +}; + } #endif diff --git a/include/Term.h b/include/Term.h index 7e55dfae..0ac80c31 100644 --- a/include/Term.h +++ b/include/Term.h @@ -9,54 +9,54 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A Term represents a word from text. This is the unit of search. It is composed of two elements, - /// the text of the word, as a string, and the name of the field that the text occurred in, an interned - /// string. +namespace Lucene { + +/// A Term represents a word from text. This is the unit of search. It is composed of two elements, +/// the text of the word, as a string, and the name of the field that the text occurred in, an interned +/// string. +/// +/// Note that terms may represent more than words from text fields, but also things like dates, email +/// addresses, urls, etc. +class LPPAPI Term : public LuceneObject { +public: + /// Constructs a Term with the given field and text. + Term(const String& fld, const String& txt = EmptyString); + virtual ~Term(); + + LUCENE_CLASS(Term); + +public: + String _field; + String _text; + +public: + /// Returns the field of this term, an interned string. The field indicates the part of a document + /// which this term came from. + String field(); + + /// Returns the text of this term. In the case of words, this is simply the text of the word. In + /// the case of dates and other types, this is an encoding of the object as a string. + String text(); + + /// Optimized construction of new Terms by reusing same field as this Term + /// @param text The text of the new term (field is implicitly same as this Term instance) + /// @return A new Term + TermPtr createTerm(const String& text); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + /// Compares two terms, returning a negative integer if this term belongs before the argument, zero + /// if this term is equal to the argument, and a positive integer if this term belongs after the argument. /// - /// Note that terms may represent more than words from text fields, but also things like dates, email - /// addresses, urls, etc. - class LPPAPI Term : public LuceneObject - { - public: - /// Constructs a Term with the given field and text. - Term(const String& fld, const String& txt = EmptyString); - virtual ~Term(); - - LUCENE_CLASS(Term); - - public: - String _field; - String _text; - - public: - /// Returns the field of this term, an interned string. The field indicates the part of a document - /// which this term came from. - String field(); - - /// Returns the text of this term. In the case of words, this is simply the text of the word. In - /// the case of dates and other types, this is an encoding of the object as a string. - String text(); - - /// Optimized construction of new Terms by reusing same field as this Term - /// @param text The text of the new term (field is implicitly same as this Term instance) - /// @return A new Term - TermPtr createTerm(const String& text); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - /// Compares two terms, returning a negative integer if this term belongs before the argument, zero - /// if this term is equal to the argument, and a positive integer if this term belongs after the argument. - /// - /// The ordering of terms is first by field, then by text. - virtual int32_t compareTo(const LuceneObjectPtr& other); - - void set(const String& fld, const String& txt); - - virtual String toString(); - }; + /// The ordering of terms is first by field, then by text. + virtual int32_t compareTo(const LuceneObjectPtr& other); + + void set(const String& fld, const String& txt); + + virtual String toString(); +}; + } #endif diff --git a/include/TermAttribute.h b/include/TermAttribute.h index 90d1693f..48af610b 100644 --- a/include/TermAttribute.h +++ b/include/TermAttribute.h @@ -9,84 +9,84 @@ #include "Attribute.h" -namespace Lucene -{ - /// The term text of a Token. - class LPPAPI TermAttribute : public Attribute - { - public: - TermAttribute(); - virtual ~TermAttribute(); - - LUCENE_CLASS(TermAttribute); - - protected: - static const int32_t MIN_BUFFER_SIZE; - - CharArray _termBuffer; - int32_t _termLength; - - public: - virtual String toString(); - - /// Returns the Token's term text. - /// - /// This method has a performance penalty because the text is stored internally in a char[]. If possible, - /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use - /// this method, which is nothing more than a convenience call to new String(token.termBuffer(), 0, - /// token.termLength()) - virtual String term(); - - /// Copies the contents of buffer, starting at offset for length characters, into the termBuffer array. - /// @param buffer the buffer to copy - /// @param offset the index in the buffer of the first character to copy - /// @param length the number of characters to copy - virtual void setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length); - - /// Copies the contents of buffer into the termBuffer array. - /// @param buffer the buffer to copy - virtual void setTermBuffer(const String& buffer); - - /// Returns the internal termBuffer character array which you can then directly alter. If the array is - /// too small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer - /// be sure to call {@link #setTermLength} to record the number of valid characters that were placed into - /// the termBuffer. - virtual CharArray termBuffer(); - - /// Optimized implementation of termBuffer. - virtual wchar_t* termBufferArray(); - - /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next - /// operation is to change the contents of the term buffer use {@link #setTermBuffer(char[], int, int)}, - /// {@link #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the - /// resize with the setting of the termBuffer. - /// @param newSize minimum size of the new termBuffer - /// @return newly created termBuffer with length >= newSize - virtual CharArray resizeTermBuffer(int32_t newSize); - - /// Return number of valid characters (length of the term) in the termBuffer array. - virtual int32_t termLength(); - - /// Set number of valid characters (length of the term) in the termBuffer array. Use this to truncate the - /// termBuffer or to synchronize with external manipulation of the termBuffer. Note: to grow the size of - /// the array, use {@link #resizeTermBuffer(int)} first. - /// @param length the truncated length - virtual void setTermLength(int32_t length); - - virtual int32_t hashCode(); - virtual void clear(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual bool equals(const LuceneObjectPtr& other); - virtual void copyTo(const AttributePtr& target); - - protected: - /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always - /// used in places that set the content. - /// @param newSize minimum size of the buffer - void growTermBuffer(int32_t newSize); - - void initTermBuffer(); - }; +namespace Lucene { + +/// The term text of a Token. +class LPPAPI TermAttribute : public Attribute { +public: + TermAttribute(); + virtual ~TermAttribute(); + + LUCENE_CLASS(TermAttribute); + +protected: + static const int32_t MIN_BUFFER_SIZE; + + CharArray _termBuffer; + int32_t _termLength; + +public: + virtual String toString(); + + /// Returns the Token's term text. + /// + /// This method has a performance penalty because the text is stored internally in a char[]. If possible, + /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use + /// this method, which is nothing more than a convenience call to new String(token.termBuffer(), 0, + /// token.termLength()) + virtual String term(); + + /// Copies the contents of buffer, starting at offset for length characters, into the termBuffer array. + /// @param buffer the buffer to copy + /// @param offset the index in the buffer of the first character to copy + /// @param length the number of characters to copy + virtual void setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length); + + /// Copies the contents of buffer into the termBuffer array. + /// @param buffer the buffer to copy + virtual void setTermBuffer(const String& buffer); + + /// Returns the internal termBuffer character array which you can then directly alter. If the array is + /// too small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer + /// be sure to call {@link #setTermLength} to record the number of valid characters that were placed into + /// the termBuffer. + virtual CharArray termBuffer(); + + /// Optimized implementation of termBuffer. + virtual wchar_t* termBufferArray(); + + /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next + /// operation is to change the contents of the term buffer use {@link #setTermBuffer(char[], int, int)}, + /// {@link #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the + /// resize with the setting of the termBuffer. + /// @param newSize minimum size of the new termBuffer + /// @return newly created termBuffer with length >= newSize + virtual CharArray resizeTermBuffer(int32_t newSize); + + /// Return number of valid characters (length of the term) in the termBuffer array. + virtual int32_t termLength(); + + /// Set number of valid characters (length of the term) in the termBuffer array. Use this to truncate the + /// termBuffer or to synchronize with external manipulation of the termBuffer. Note: to grow the size of + /// the array, use {@link #resizeTermBuffer(int)} first. + /// @param length the truncated length + virtual void setTermLength(int32_t length); + + virtual int32_t hashCode(); + virtual void clear(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual bool equals(const LuceneObjectPtr& other); + virtual void copyTo(const AttributePtr& target); + +protected: + /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always + /// used in places that set the content. + /// @param newSize minimum size of the buffer + void growTermBuffer(int32_t newSize); + + void initTermBuffer(); +}; + } #endif diff --git a/include/TermBuffer.h b/include/TermBuffer.h index c20c7405..d43df608 100644 --- a/include/TermBuffer.h +++ b/include/TermBuffer.h @@ -9,43 +9,43 @@ #include "LuceneObject.h" -namespace Lucene -{ - class TermBuffer : public LuceneObject - { - public: - TermBuffer(); - virtual ~TermBuffer(); +namespace Lucene { - LUCENE_CLASS(TermBuffer); +class TermBuffer : public LuceneObject { +public: + TermBuffer(); + virtual ~TermBuffer(); - protected: - String field; - TermPtr term; // cached - bool preUTF8Strings; // true if strings are stored in modified UTF8 encoding + LUCENE_CLASS(TermBuffer); - UnicodeResultPtr text; - UTF8ResultPtr bytes; +protected: + String field; + TermPtr term; // cached + bool preUTF8Strings; // true if strings are stored in modified UTF8 encoding - public: - virtual int32_t compareTo(const LuceneObjectPtr& other); + UnicodeResultPtr text; + UTF8ResultPtr bytes; - /// Call this if the IndexInput passed to {@link #read} stores terms in the "modified UTF8" format. - void setPreUTF8Strings(); +public: + virtual int32_t compareTo(const LuceneObjectPtr& other); - void read(const IndexInputPtr& input, const FieldInfosPtr& fieldInfos); + /// Call this if the IndexInput passed to {@link #read} stores terms in the "modified UTF8" format. + void setPreUTF8Strings(); - void set(const TermPtr& term); - void set(const TermBufferPtr& other); - void reset(); + void read(const IndexInputPtr& input, const FieldInfosPtr& fieldInfos); - TermPtr toTerm(); + void set(const TermPtr& term); + void set(const TermBufferPtr& other); + void reset(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + TermPtr toTerm(); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + +protected: + int32_t compareChars(wchar_t* chars1, int32_t len1, wchar_t* chars2, int32_t len2); +}; - protected: - int32_t compareChars(wchar_t* chars1, int32_t len1, wchar_t* chars2, int32_t len2); - }; } #endif diff --git a/include/TermDocs.h b/include/TermDocs.h index fa9a9ead..6357335a 100644 --- a/include/TermDocs.h +++ b/include/TermDocs.h @@ -9,51 +9,51 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// TermDocs provides an interface for enumerating ; pairs for a term. The document - /// portion names each document containing the term. Documents are indicated by number. The frequency - /// portion gives the number of times the term occurred in each document. The pairs are ordered by document - /// number. - /// @see IndexReader#termDocs() - class LPPAPI TermDocs - { - protected: - TermDocs(); - - public: - LUCENE_INTERFACE(TermDocs); - - public: - /// Sets this to the data for a term. The enumeration is reset to the start of the data for this term. - virtual void seek(const TermPtr& term) = 0; - - /// Sets this to the data for the current term in a {@link TermEnum}. - /// This may be optimized in some implementations. - virtual void seek(const TermEnumPtr& termEnum) = 0; - - /// Returns the current document number. This is invalid until {@link #next()} is called for the first time. - virtual int32_t doc() = 0; - - /// Returns the frequency of the term within the current document. This is invalid until {@link #next()} is - /// called for the first time. - virtual int32_t freq() = 0; - - /// Moves to the next pair in the enumeration. Returns true if there is such a next pair in the enumeration. - virtual bool next() = 0; - - /// Attempts to read multiple entries from the enumeration, up to length of docs. Document numbers are stored - /// in docs, and term frequencies are stored in freqs. Returns the number of entries read. Zero is only - /// returned when the stream has been exhausted. - virtual int32_t read(Collection docs, Collection freqs) = 0; - - /// Skips entries to the first beyond the current whose document number is greater than or equal to target. - /// Returns true if there is such an entry. - virtual bool skipTo(int32_t target) = 0; - - /// Frees associated resources. - virtual void close() = 0; - }; +namespace Lucene { + +/// TermDocs provides an interface for enumerating ; pairs for a term. The document +/// portion names each document containing the term. Documents are indicated by number. The frequency +/// portion gives the number of times the term occurred in each document. The pairs are ordered by document +/// number. +/// @see IndexReader#termDocs() +class LPPAPI TermDocs { +protected: + TermDocs(); + +public: + LUCENE_INTERFACE(TermDocs); + +public: + /// Sets this to the data for a term. The enumeration is reset to the start of the data for this term. + virtual void seek(const TermPtr& term) = 0; + + /// Sets this to the data for the current term in a {@link TermEnum}. + /// This may be optimized in some implementations. + virtual void seek(const TermEnumPtr& termEnum) = 0; + + /// Returns the current document number. This is invalid until {@link #next()} is called for the first time. + virtual int32_t doc() = 0; + + /// Returns the frequency of the term within the current document. This is invalid until {@link #next()} is + /// called for the first time. + virtual int32_t freq() = 0; + + /// Moves to the next pair in the enumeration. Returns true if there is such a next pair in the enumeration. + virtual bool next() = 0; + + /// Attempts to read multiple entries from the enumeration, up to length of docs. Document numbers are stored + /// in docs, and term frequencies are stored in freqs. Returns the number of entries read. Zero is only + /// returned when the stream has been exhausted. + virtual int32_t read(Collection docs, Collection freqs) = 0; + + /// Skips entries to the first beyond the current whose document number is greater than or equal to target. + /// Returns true if there is such an entry. + virtual bool skipTo(int32_t target) = 0; + + /// Frees associated resources. + virtual void close() = 0; +}; + } #endif diff --git a/include/TermEnum.h b/include/TermEnum.h index 7372cae7..550bbc3b 100644 --- a/include/TermEnum.h +++ b/include/TermEnum.h @@ -9,31 +9,31 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Abstract class for enumerating terms. - /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater - /// than all that precede it. - class LPPAPI TermEnum : public LuceneObject - { - public: - virtual ~TermEnum(); - LUCENE_CLASS(TermEnum); - - public: - /// Increments the enumeration to the next element. True if one exists. - virtual bool next() = 0; - - /// Returns the current Term in the enumeration. - virtual TermPtr term() = 0; - - /// Returns the docFreq of the current Term in the enumeration. - virtual int32_t docFreq() = 0; - - /// Closes the enumeration to further activity, freeing resources. - virtual void close() = 0; - }; +namespace Lucene { + +/// Abstract class for enumerating terms. +/// +/// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater +/// than all that precede it. +class LPPAPI TermEnum : public LuceneObject { +public: + virtual ~TermEnum(); + LUCENE_CLASS(TermEnum); + +public: + /// Increments the enumeration to the next element. True if one exists. + virtual bool next() = 0; + + /// Returns the current Term in the enumeration. + virtual TermPtr term() = 0; + + /// Returns the docFreq of the current Term in the enumeration. + virtual int32_t docFreq() = 0; + + /// Closes the enumeration to further activity, freeing resources. + virtual void close() = 0; +}; + } #endif diff --git a/include/TermFreqVector.h b/include/TermFreqVector.h index 34d4a131..5cbf4e67 100644 --- a/include/TermFreqVector.h +++ b/include/TermFreqVector.h @@ -9,49 +9,49 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Provides access to stored term vector of a document field. The vector consists of the name of the field, an - /// array of the terms that occur in the field of the {@link Document} and a parallel array of frequencies. Thus, - /// getTermFrequencies()[5] corresponds with the frequency of getTerms()[5], assuming there are at least 5 terms - /// in the Document. - class LPPAPI TermFreqVector - { - protected: - TermFreqVector(); - - public: - virtual ~TermFreqVector(); - LUCENE_INTERFACE(TermFreqVector); - - public: - /// The {@link Fieldable} name. - /// @return The name of the field this vector is associated with. - virtual String getField(); - - /// @return The number of terms in the term vector. - virtual int32_t size(); - - /// @return An Array of term texts in ascending order. - virtual Collection getTerms(); - - /// Array of term frequencies. Locations of the array correspond one to one to the terms in the array obtained from - /// getTerms method. Each location in the array contains the number of times this term occurs in the document or the - /// document field. - virtual Collection getTermFrequencies(); - - /// Return an index in the term numbers array returned from getTerms at which the term with the specified term appears. - /// If this term does not appear in the array, return -1. - virtual int32_t indexOf(const String& term); - - /// Just like indexOf(int) but searches for a number of terms at the same time. Returns an array that has the same size - /// as the number of terms searched for, each slot containing the result of searching for that term number. - /// - /// @param terms array containing terms to look for - /// @param start index in the array where the list of terms starts - /// @param length the number of terms in the list - virtual Collection indexesOf(Collection terms, int32_t start, int32_t length); - }; +namespace Lucene { + +/// Provides access to stored term vector of a document field. The vector consists of the name of the field, an +/// array of the terms that occur in the field of the {@link Document} and a parallel array of frequencies. Thus, +/// getTermFrequencies()[5] corresponds with the frequency of getTerms()[5], assuming there are at least 5 terms +/// in the Document. +class LPPAPI TermFreqVector { +protected: + TermFreqVector(); + +public: + virtual ~TermFreqVector(); + LUCENE_INTERFACE(TermFreqVector); + +public: + /// The {@link Fieldable} name. + /// @return The name of the field this vector is associated with. + virtual String getField(); + + /// @return The number of terms in the term vector. + virtual int32_t size(); + + /// @return An Array of term texts in ascending order. + virtual Collection getTerms(); + + /// Array of term frequencies. Locations of the array correspond one to one to the terms in the array obtained from + /// getTerms method. Each location in the array contains the number of times this term occurs in the document or the + /// document field. + virtual Collection getTermFrequencies(); + + /// Return an index in the term numbers array returned from getTerms at which the term with the specified term appears. + /// If this term does not appear in the array, return -1. + virtual int32_t indexOf(const String& term); + + /// Just like indexOf(int) but searches for a number of terms at the same time. Returns an array that has the same size + /// as the number of terms searched for, each slot containing the result of searching for that term number. + /// + /// @param terms array containing terms to look for + /// @param start index in the array where the list of terms starts + /// @param length the number of terms in the list + virtual Collection indexesOf(Collection terms, int32_t start, int32_t length); +}; + } #endif diff --git a/include/TermInfo.h b/include/TermInfo.h index 92ea5368..f2331eda 100644 --- a/include/TermInfo.h +++ b/include/TermInfo.h @@ -9,29 +9,29 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// A TermInfo is the record of information stored for a term. - class TermInfo : public LuceneObject - { - public: - TermInfo(const TermInfoPtr& ti); - TermInfo(int32_t df = 0, int64_t fp = 0, int64_t pp = 0); - virtual ~TermInfo(); - - LUCENE_CLASS(TermInfo); - - public: - /// The number of documents which contain the term. - int32_t docFreq; - int64_t freqPointer; - int64_t proxPointer; - int32_t skipOffset; - - public: - void set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer, int32_t skipOffset); - void set(const TermInfoPtr& ti); - }; +namespace Lucene { + +/// A TermInfo is the record of information stored for a term. +class TermInfo : public LuceneObject { +public: + TermInfo(const TermInfoPtr& ti); + TermInfo(int32_t df = 0, int64_t fp = 0, int64_t pp = 0); + virtual ~TermInfo(); + + LUCENE_CLASS(TermInfo); + +public: + /// The number of documents which contain the term. + int32_t docFreq; + int64_t freqPointer; + int64_t proxPointer; + int32_t skipOffset; + +public: + void set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer, int32_t skipOffset); + void set(const TermInfoPtr& ti); +}; + } #endif diff --git a/include/TermInfosReader.h b/include/TermInfosReader.h index 25d41aff..bda7ec76 100644 --- a/include/TermInfosReader.h +++ b/include/TermInfosReader.h @@ -10,81 +10,80 @@ #include "CloseableThreadLocal.h" #include "SimpleLRUCache.h" -namespace Lucene -{ - /// This stores a monotonically increasing set of pairs in a Directory. Pairs are - /// accessed either by Term or by ordinal position the set. - class TermInfosReader : public LuceneObject - { - public: - TermInfosReader(const DirectoryPtr& dir, const String& seg, const FieldInfosPtr& fis, int32_t readBufferSize, int32_t indexDivisor); - virtual ~TermInfosReader(); +namespace Lucene { - LUCENE_CLASS(TermInfosReader); +/// This stores a monotonically increasing set of pairs in a Directory. Pairs are +/// accessed either by Term or by ordinal position the set. +class TermInfosReader : public LuceneObject { +public: + TermInfosReader(const DirectoryPtr& dir, const String& seg, const FieldInfosPtr& fis, int32_t readBufferSize, int32_t indexDivisor); + virtual ~TermInfosReader(); - protected: - DirectoryPtr directory; - String segment; - FieldInfosPtr fieldInfos; - CloseableThreadLocal threadResources; - SegmentTermEnumPtr origEnum; - int64_t _size; + LUCENE_CLASS(TermInfosReader); - Collection indexTerms; - Collection indexInfos; - Collection indexPointers; +protected: + DirectoryPtr directory; + String segment; + FieldInfosPtr fieldInfos; + CloseableThreadLocal threadResources; + SegmentTermEnumPtr origEnum; + int64_t _size; - int32_t totalIndexInterval; + Collection indexTerms; + Collection indexInfos; + Collection indexPointers; - static const int32_t DEFAULT_CACHE_SIZE; + int32_t totalIndexInterval; - public: - int32_t getSkipInterval(); - int32_t getMaxSkipLevels(); - void close(); + static const int32_t DEFAULT_CACHE_SIZE; - /// Returns the number of term/value pairs in the set. - int64_t size(); +public: + int32_t getSkipInterval(); + int32_t getMaxSkipLevels(); + void close(); - /// Returns the TermInfo for a Term in the set, or null. - TermInfoPtr get(const TermPtr& term); + /// Returns the number of term/value pairs in the set. + int64_t size(); - /// Returns the position of a Term in the set or -1. - int64_t getPosition(const TermPtr& term); + /// Returns the TermInfo for a Term in the set, or null. + TermInfoPtr get(const TermPtr& term); - /// Returns an enumeration of all the Terms and TermInfos in the set. - SegmentTermEnumPtr terms(); + /// Returns the position of a Term in the set or -1. + int64_t getPosition(const TermPtr& term); - /// Returns an enumeration of terms starting at or after the named term. - SegmentTermEnumPtr terms(const TermPtr& term); + /// Returns an enumeration of all the Terms and TermInfos in the set. + SegmentTermEnumPtr terms(); - protected: - TermInfosReaderThreadResourcesPtr getThreadResources(); + /// Returns an enumeration of terms starting at or after the named term. + SegmentTermEnumPtr terms(const TermPtr& term); - /// Returns the offset of the greatest index entry which is less than or equal to term. - int32_t getIndexOffset(const TermPtr& term); +protected: + TermInfosReaderThreadResourcesPtr getThreadResources(); - void seekEnum(const SegmentTermEnumPtr& enumerator, int32_t indexOffset); + /// Returns the offset of the greatest index entry which is less than or equal to term. + int32_t getIndexOffset(const TermPtr& term); - /// Returns the TermInfo for a Term in the set, or null. - TermInfoPtr get(const TermPtr& term, bool useCache); + void seekEnum(const SegmentTermEnumPtr& enumerator, int32_t indexOffset); - void ensureIndexIsRead(); - }; + /// Returns the TermInfo for a Term in the set, or null. + TermInfoPtr get(const TermPtr& term, bool useCache); - class TermInfosReaderThreadResources : public LuceneObject - { - public: - virtual ~TermInfosReaderThreadResources(); + void ensureIndexIsRead(); +}; - LUCENE_CLASS(TermInfosReaderThreadResources); +class TermInfosReaderThreadResources : public LuceneObject { +public: + virtual ~TermInfosReaderThreadResources(); - public: - SegmentTermEnumPtr termEnum; + LUCENE_CLASS(TermInfosReaderThreadResources); + +public: + SegmentTermEnumPtr termEnum; + + // Used for caching the least recently looked-up Terms + TermInfoCachePtr termInfoCache; +}; - // Used for caching the least recently looked-up Terms - TermInfoCachePtr termInfoCache; - }; } #endif diff --git a/include/TermInfosWriter.h b/include/TermInfosWriter.h index 8d65f545..b19a2503 100644 --- a/include/TermInfosWriter.h +++ b/include/TermInfosWriter.h @@ -9,87 +9,87 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// This stores a monotonically increasing set of pairs in a Directory. A TermInfos - /// can be written once, in order. - class TermInfosWriter : public LuceneObject - { - public: - TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval); - TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isIndex); - virtual ~TermInfosWriter(); - - LUCENE_CLASS(TermInfosWriter); - - public: - /// The file format version, a negative number. - static const int32_t FORMAT; - - /// Changed strings to true utf8 with length-in-bytes not length-in-chars. - static const int32_t FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; - - /// NOTE: always change this if you switch to a new format. - static const int32_t FORMAT_CURRENT; - - /// The fraction of terms in the "dictionary" which should be stored in RAM. Smaller values use more memory, but - /// make searching slightly faster, while larger values use less memory and make searching slightly slower. - /// Searching is typically not dominated by dictionary lookup, so tweaking this is rarely useful. - int32_t indexInterval; - - /// The fraction of {@link TermDocs} entries stored in skip tables, used to accelerate {@link TermDocs#skipTo(int)}. - /// Larger values result in smaller indexes, greater acceleration, but fewer accelerable cases, while smaller values - /// result in bigger indexes, less acceleration and more accelerable cases. More detailed experiments would be useful - /// here. - int32_t skipInterval; - - /// The maximum number of skip levels. Smaller values result in slightly smaller indexes, but slower skipping - /// in big posting lists. - int32_t maxSkipLevels; - - protected: - FieldInfosPtr fieldInfos; - IndexOutputPtr output; - TermInfoPtr lastTi; - int64_t size; - - int64_t lastIndexPointer; - bool isIndex; - ByteArray lastTermBytes; - int32_t lastTermBytesLength; - int32_t lastFieldNumber; - - TermInfosWriterPtr otherWriter; - TermInfosWriterWeakPtr _other; - UTF8ResultPtr utf8Result; - - // Currently used only by assert statements - UnicodeResultPtr unicodeResult1; - UnicodeResultPtr unicodeResult2; - - public: - virtual void initialize(); - - void add(const TermPtr& term, const TermInfoPtr& ti); - - /// Adds a new <, TermInfo> pair to the set. Term must be lexicographically - /// greater than all previous Terms added. TermInfo pointers must be positive and greater than all previous. - void add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, const TermInfoPtr& ti); - - /// Called to complete TermInfos creation. - void close(); - - protected: - void initialize(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isi); - - /// Currently used only by assert statements - bool initUnicodeResults(); - - /// Currently used only by assert statement - int32_t compareToLastTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength); - - void writeTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength); - }; +namespace Lucene { + +/// This stores a monotonically increasing set of pairs in a Directory. A TermInfos +/// can be written once, in order. +class TermInfosWriter : public LuceneObject { +public: + TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval); + TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isIndex); + virtual ~TermInfosWriter(); + + LUCENE_CLASS(TermInfosWriter); + +public: + /// The file format version, a negative number. + static const int32_t FORMAT; + + /// Changed strings to true utf8 with length-in-bytes not length-in-chars. + static const int32_t FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; + + /// NOTE: always change this if you switch to a new format. + static const int32_t FORMAT_CURRENT; + + /// The fraction of terms in the "dictionary" which should be stored in RAM. Smaller values use more memory, but + /// make searching slightly faster, while larger values use less memory and make searching slightly slower. + /// Searching is typically not dominated by dictionary lookup, so tweaking this is rarely useful. + int32_t indexInterval; + + /// The fraction of {@link TermDocs} entries stored in skip tables, used to accelerate {@link TermDocs#skipTo(int)}. + /// Larger values result in smaller indexes, greater acceleration, but fewer accelerable cases, while smaller values + /// result in bigger indexes, less acceleration and more accelerable cases. More detailed experiments would be useful + /// here. + int32_t skipInterval; + + /// The maximum number of skip levels. Smaller values result in slightly smaller indexes, but slower skipping + /// in big posting lists. + int32_t maxSkipLevels; + +protected: + FieldInfosPtr fieldInfos; + IndexOutputPtr output; + TermInfoPtr lastTi; + int64_t size; + + int64_t lastIndexPointer; + bool isIndex; + ByteArray lastTermBytes; + int32_t lastTermBytesLength; + int32_t lastFieldNumber; + + TermInfosWriterPtr otherWriter; + TermInfosWriterWeakPtr _other; + UTF8ResultPtr utf8Result; + + // Currently used only by assert statements + UnicodeResultPtr unicodeResult1; + UnicodeResultPtr unicodeResult2; + +public: + virtual void initialize(); + + void add(const TermPtr& term, const TermInfoPtr& ti); + + /// Adds a new <, TermInfo> pair to the set. Term must be lexicographically + /// greater than all previous Terms added. TermInfo pointers must be positive and greater than all previous. + void add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, const TermInfoPtr& ti); + + /// Called to complete TermInfos creation. + void close(); + +protected: + void initialize(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isi); + + /// Currently used only by assert statements + bool initUnicodeResults(); + + /// Currently used only by assert statement + int32_t compareToLastTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength); + + void writeTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength); +}; + } #endif diff --git a/include/TermPositionVector.h b/include/TermPositionVector.h index e1ba24d4..e8d79ffd 100644 --- a/include/TermPositionVector.h +++ b/include/TermPositionVector.h @@ -9,30 +9,30 @@ #include "TermFreqVector.h" -namespace Lucene -{ - /// Extends TermFreqVector to provide additional information about positions in which each of the terms is found. A TermPositionVector not necessarily - /// contains both positions and offsets, but at least one of these arrays exists. - class LPPAPI TermPositionVector : public TermFreqVector - { - protected: - TermPositionVector(); - - public: - virtual ~TermPositionVector(); - LUCENE_INTERFACE(TermPositionVector); - - public: - /// Returns an array of positions in which the term is found. Terms are identified by the index at which its number appears in the term String - /// array obtained from the indexOf method. May return null if positions have not been stored. - virtual Collection getTermPositions(int32_t index); - - /// Returns an array of TermVectorOffsetInfo in which the term is found. May return null if offsets have not been stored. - /// @see Token - /// @param index The position in the array to get the offsets from - /// @return An array of TermVectorOffsetInfo objects or the empty list - virtual Collection getOffsets(int32_t index); - }; +namespace Lucene { + +/// Extends TermFreqVector to provide additional information about positions in which each of the terms is found. A TermPositionVector not necessarily +/// contains both positions and offsets, but at least one of these arrays exists. +class LPPAPI TermPositionVector : public TermFreqVector { +protected: + TermPositionVector(); + +public: + virtual ~TermPositionVector(); + LUCENE_INTERFACE(TermPositionVector); + +public: + /// Returns an array of positions in which the term is found. Terms are identified by the index at which its number appears in the term String + /// array obtained from the indexOf method. May return null if positions have not been stored. + virtual Collection getTermPositions(int32_t index); + + /// Returns an array of TermVectorOffsetInfo in which the term is found. May return null if offsets have not been stored. + /// @see Token + /// @param index The position in the array to get the offsets from + /// @return An array of TermVectorOffsetInfo objects or the empty list + virtual Collection getOffsets(int32_t index); +}; + } #endif diff --git a/include/TermPositions.h b/include/TermPositions.h index 7b35b3b5..cf899b61 100644 --- a/include/TermPositions.h +++ b/include/TermPositions.h @@ -9,47 +9,47 @@ #include "TermDocs.h" -namespace Lucene -{ - /// TermPositions provides an interface for enumerating the *> - /// tuples for a term. The document and frequency are the same as for a TermDocs. The positions portion - /// lists the ordinal positions of each occurrence of a term in a document. - /// @see IndexReader#termPositions() - class LPPAPI TermPositions : public TermDocs - { - protected: - TermPositions(); - - public: - virtual ~TermPositions(); - LUCENE_INTERFACE(TermPositions); - - public: - /// Returns next position in the current document. It is an error to call this more than {@link #freq()} - /// times without calling {@link #next()}. This is invalid until {@link #next()} is called for - // the first time. - virtual int32_t nextPosition(); - - /// Returns the length of the payload at the current term position. This is invalid until {@link - /// #nextPosition()} is called for the first time. - /// @return length of the current payload in number of bytes - virtual int32_t getPayloadLength(); - - /// Returns the payload data at the current term position. This is invalid until {@link #nextPosition()} - /// is called for the first time. - /// This method must not be called more than once after each call of {@link #nextPosition()}. However, - /// payloads are loaded lazily, so if the payload data for the current position is not needed, - /// this method may not be called at all for performance reasons. - /// @param data the array into which the data of this payload is to be stored - /// @param offset the offset in the array into which the data of this payload is to be stored. - /// @return a byte array containing the data of this payload - virtual ByteArray getPayload(ByteArray data, int32_t offset); - - /// Checks if a payload can be loaded at this position. - /// Payloads can only be loaded once per call to {@link #nextPosition()}. - /// @return true if there is a payload available at this position that can be loaded - virtual bool isPayloadAvailable(); - }; +namespace Lucene { + +/// TermPositions provides an interface for enumerating the *> +/// tuples for a term. The document and frequency are the same as for a TermDocs. The positions portion +/// lists the ordinal positions of each occurrence of a term in a document. +/// @see IndexReader#termPositions() +class LPPAPI TermPositions : public TermDocs { +protected: + TermPositions(); + +public: + virtual ~TermPositions(); + LUCENE_INTERFACE(TermPositions); + +public: + /// Returns next position in the current document. It is an error to call this more than {@link #freq()} + /// times without calling {@link #next()}. This is invalid until {@link #next()} is called for + // the first time. + virtual int32_t nextPosition(); + + /// Returns the length of the payload at the current term position. This is invalid until {@link + /// #nextPosition()} is called for the first time. + /// @return length of the current payload in number of bytes + virtual int32_t getPayloadLength(); + + /// Returns the payload data at the current term position. This is invalid until {@link #nextPosition()} + /// is called for the first time. + /// This method must not be called more than once after each call of {@link #nextPosition()}. However, + /// payloads are loaded lazily, so if the payload data for the current position is not needed, + /// this method may not be called at all for performance reasons. + /// @param data the array into which the data of this payload is to be stored + /// @param offset the offset in the array into which the data of this payload is to be stored. + /// @return a byte array containing the data of this payload + virtual ByteArray getPayload(ByteArray data, int32_t offset); + + /// Checks if a payload can be loaded at this position. + /// Payloads can only be loaded once per call to {@link #nextPosition()}. + /// @return true if there is a payload available at this position that can be loaded + virtual bool isPayloadAvailable(); +}; + } #endif diff --git a/include/TermQuery.h b/include/TermQuery.h index 81838289..b5788aab 100644 --- a/include/TermQuery.h +++ b/include/TermQuery.h @@ -9,41 +9,41 @@ #include "Query.h" -namespace Lucene -{ - /// A Query that matches documents containing a term. This may be combined with other terms with a - /// {@link BooleanQuery}. - class LPPAPI TermQuery : public Query - { - public: - /// Constructs a query for the term. - TermQuery(const TermPtr& term); +namespace Lucene { - virtual ~TermQuery(); +/// A Query that matches documents containing a term. This may be combined with other terms with a +/// {@link BooleanQuery}. +class LPPAPI TermQuery : public Query { +public: + /// Constructs a query for the term. + TermQuery(const TermPtr& term); - LUCENE_CLASS(TermQuery); + virtual ~TermQuery(); - protected: - TermPtr term; + LUCENE_CLASS(TermQuery); - public: - using Query::toString; +protected: + TermPtr term; - /// Returns the term of this query. - TermPtr getTerm(); +public: + using Query::toString; - virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual void extractTerms(SetTerm terms); + /// Returns the term of this query. + TermPtr getTerm(); - /// Prints a user-readable version of this query. - virtual String toString(const String& field); + virtual WeightPtr createWeight(const SearcherPtr& searcher); + virtual void extractTerms(SetTerm terms); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + /// Prints a user-readable version of this query. + virtual String toString(const String& field); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + friend class TermWeight; +}; - friend class TermWeight; - }; } #endif diff --git a/include/TermRangeFilter.h b/include/TermRangeFilter.h index 7707dcfc..5c785b28 100644 --- a/include/TermRangeFilter.h +++ b/include/TermRangeFilter.h @@ -9,60 +9,60 @@ #include "MultiTermQueryWrapperFilter.h" -namespace Lucene -{ - /// A Filter that restricts search results to a range of term values in a given field. - /// - /// This filter matches the documents looking for terms that fall into the supplied range according to {@link - /// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link - /// NumericRangeFilter} instead. - /// - /// If you construct a large number of range filters with different ranges but on the same field, {@link - /// FieldCacheRangeFilter} may have significantly better performance. - class LPPAPI TermRangeFilter : public MultiTermQueryWrapperFilter - { - public: - /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause - /// every single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending - /// on the number of index Terms in this Field, the operation could be very slow. - /// @param lowerTerm The lower bound on this range - /// @param upperTerm The upper bound on this range - /// @param includeLower Does this range include the lower bound? - /// @param includeUpper Does this range include the upper bound? - /// @param collator The collator to use when determining range inclusion; set to null to use Unicode code - /// point ordering instead of collation. - TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, - bool includeUpper, CollatorPtr collator = CollatorPtr()); - - virtual ~TermRangeFilter(); - - LUCENE_CLASS(TermRangeFilter); - - public: - /// Constructs a filter for field fieldName matching less than or equal to upperTerm. - static TermRangeFilterPtr Less(const String& fieldName, StringValue upperTerm); - - /// Constructs a filter for field fieldName matching greater than or equal to lowerTerm. - static TermRangeFilterPtr More(const String& fieldName, StringValue lowerTerm); - - /// Returns the field name for this filter - String getField(); - - /// Returns the lower value of this range filter - String getLowerTerm(); - - /// Returns the upper value of this range filter - String getUpperTerm(); - - /// Returns true if the lower endpoint is inclusive - bool includesLower(); - - /// Returns true if the upper endpoint is inclusive - bool includesUpper(); - - /// Returns the collator used to determine range inclusion, if any. - CollatorPtr getCollator(); - }; +namespace Lucene { + +/// A Filter that restricts search results to a range of term values in a given field. +/// +/// This filter matches the documents looking for terms that fall into the supplied range according to {@link +/// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link +/// NumericRangeFilter} instead. +/// +/// If you construct a large number of range filters with different ranges but on the same field, {@link +/// FieldCacheRangeFilter} may have significantly better performance. +class LPPAPI TermRangeFilter : public MultiTermQueryWrapperFilter { +public: + /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause + /// every single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending + /// on the number of index Terms in this Field, the operation could be very slow. + /// @param lowerTerm The lower bound on this range + /// @param upperTerm The upper bound on this range + /// @param includeLower Does this range include the lower bound? + /// @param includeUpper Does this range include the upper bound? + /// @param collator The collator to use when determining range inclusion; set to null to use Unicode code + /// point ordering instead of collation. + TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + bool includeUpper, CollatorPtr collator = CollatorPtr()); + + virtual ~TermRangeFilter(); + + LUCENE_CLASS(TermRangeFilter); + +public: + /// Constructs a filter for field fieldName matching less than or equal to upperTerm. + static TermRangeFilterPtr Less(const String& fieldName, StringValue upperTerm); + + /// Constructs a filter for field fieldName matching greater than or equal to lowerTerm. + static TermRangeFilterPtr More(const String& fieldName, StringValue lowerTerm); + + /// Returns the field name for this filter + String getField(); + + /// Returns the lower value of this range filter + String getLowerTerm(); + + /// Returns the upper value of this range filter + String getUpperTerm(); + + /// Returns true if the lower endpoint is inclusive + bool includesLower(); + + /// Returns true if the upper endpoint is inclusive + bool includesUpper(); + + /// Returns the collator used to determine range inclusion, if any. + CollatorPtr getCollator(); +}; + } #endif diff --git a/include/TermRangeQuery.h b/include/TermRangeQuery.h index 2e755d11..cab13405 100644 --- a/include/TermRangeQuery.h +++ b/include/TermRangeQuery.h @@ -9,81 +9,81 @@ #include "MultiTermQuery.h" -namespace Lucene -{ - /// A Query that matches documents within an range of terms. +namespace Lucene { + +/// A Query that matches documents within an range of terms. +/// +/// This query matches the documents looking for terms that fall into the supplied range according to {@link +/// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link +/// NumericRangeQuery} instead. +/// +/// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. +class LPPAPI TermRangeQuery : public MultiTermQuery { +public: + /// Constructs a query selecting all terms greater/equal than lowerTerm but less/equal than upperTerm. /// - /// This query matches the documents looking for terms that fall into the supplied range according to {@link - /// String#compare(String)}, unless a Collator is provided. It is not intended for numerical ranges; use {@link - /// NumericRangeQuery} instead. + /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints + /// may not be exclusive (you can't select all but the first or last term without explicitly specifying the + /// term to exclude.) /// - /// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. - class LPPAPI TermRangeQuery : public MultiTermQuery - { - public: - /// Constructs a query selecting all terms greater/equal than lowerTerm but less/equal than upperTerm. - /// - /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints - /// may not be exclusive (you can't select all but the first or last term without explicitly specifying the - /// term to exclude.) - /// - /// If collator is not null, it will be used to decide whether index terms are within the given range, rather - /// than using the Unicode code point order in which index terms are stored. - /// - /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause every - /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending on the - /// number of index Terms in this Field, the operation could be very slow. - /// - /// @param lowerTerm The Term text at the lower end of the range - /// @param upperTerm The Term text at the upper end of the range - /// @param includeLower If true, the lowerTerm is included in the range. - /// @param includeUpper If true, the upperTerm is included in the range. - /// @param collator The collator to use to collate index Terms, to determine their membership in the range - /// bounded by lowerTerm and upperTerm. - TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, - bool includeUpper, CollatorPtr collator = CollatorPtr()); - - virtual ~TermRangeQuery(); - - LUCENE_CLASS(TermRangeQuery); - - protected: - StringValue lowerTerm; - StringValue upperTerm; - CollatorPtr collator; - String field; - bool includeLower; - bool includeUpper; - - public: - using MultiTermQuery::toString; - - /// Returns the field name for this query - String getField(); - - /// Returns the lower value of this range query - String getLowerTerm(); - - /// Returns the upper value of this range query - String getUpperTerm(); - - /// Returns true if the lower endpoint is inclusive - bool includesLower(); - - /// Returns true if the upper endpoint is inclusive - bool includesUpper(); - - /// Returns the collator used to determine range inclusion, if any. - CollatorPtr getCollator(); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual String toString(const String& field); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - - protected: - virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); - }; + /// If collator is not null, it will be used to decide whether index terms are within the given range, rather + /// than using the Unicode code point order in which index terms are stored. + /// + /// Warning: Using this constructor and supplying a non-null value in the collator parameter will cause every + /// single index Term in the Field referenced by lowerTerm and/or upperTerm to be examined. Depending on the + /// number of index Terms in this Field, the operation could be very slow. + /// + /// @param lowerTerm The Term text at the lower end of the range + /// @param upperTerm The Term text at the upper end of the range + /// @param includeLower If true, the lowerTerm is included in the range. + /// @param includeUpper If true, the upperTerm is included in the range. + /// @param collator The collator to use to collate index Terms, to determine their membership in the range + /// bounded by lowerTerm and upperTerm. + TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + bool includeUpper, CollatorPtr collator = CollatorPtr()); + + virtual ~TermRangeQuery(); + + LUCENE_CLASS(TermRangeQuery); + +protected: + StringValue lowerTerm; + StringValue upperTerm; + CollatorPtr collator; + String field; + bool includeLower; + bool includeUpper; + +public: + using MultiTermQuery::toString; + + /// Returns the field name for this query + String getField(); + + /// Returns the lower value of this range query + String getLowerTerm(); + + /// Returns the upper value of this range query + String getUpperTerm(); + + /// Returns true if the lower endpoint is inclusive + bool includesLower(); + + /// Returns true if the upper endpoint is inclusive + bool includesUpper(); + + /// Returns the collator used to determine range inclusion, if any. + CollatorPtr getCollator(); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual String toString(const String& field); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + +protected: + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); +}; + } #endif diff --git a/include/TermRangeTermEnum.h b/include/TermRangeTermEnum.h index ab4a3738..1b1ad8e9 100644 --- a/include/TermRangeTermEnum.h +++ b/include/TermRangeTermEnum.h @@ -9,52 +9,52 @@ #include "FilteredTermEnum.h" -namespace Lucene -{ - /// Subclass of FilteredTermEnum for enumerating all terms that match the specified range parameters. +namespace Lucene { + +/// Subclass of FilteredTermEnum for enumerating all terms that match the specified range parameters. +/// +/// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than +/// all that precede it. +class LPPAPI TermRangeTermEnum : public FilteredTermEnum { +public: + /// Enumerates all terms greater/equal than lowerTerm but less/equal than upperTerm. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than - /// all that precede it. - class LPPAPI TermRangeTermEnum : public FilteredTermEnum - { - public: - /// Enumerates all terms greater/equal than lowerTerm but less/equal than upperTerm. - /// - /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints - /// may not be exclusive (you can't select all but the first or last term without explicitly specifying - /// the term to exclude.) - /// - /// @param reader - /// @param field An interned field that holds both lower and upper terms. - /// @param lowerTermText The term text at the lower end of the range - /// @param upperTermText The term text at the upper end of the range - /// @param includeLower If true, the lowerTerm is included in the range. - /// @param includeUpper If true, the upperTerm is included in the range. - /// @param collator The collator to use to collate index Terms, to determine their membership in the range - /// bounded by lowerTerm and upperTerm. - TermRangeTermEnum(const IndexReaderPtr& reader, const String& field, StringValue lowerTermText, StringValue upperTermText, - bool includeLower, bool includeUpper, const CollatorPtr& collator); - - virtual ~TermRangeTermEnum(); - - LUCENE_CLASS(TermRangeTermEnum); - - protected: - CollatorPtr collator; - bool _endEnum; - String field; - StringValue upperTermText; - StringValue lowerTermText; - bool includeLower; - bool includeUpper; - - public: - virtual double difference(); - - protected: - virtual bool endEnum(); - virtual bool termCompare(const TermPtr& term); - }; + /// If an endpoint is null, it is said to be "open". Either or both endpoints may be open. Open endpoints + /// may not be exclusive (you can't select all but the first or last term without explicitly specifying + /// the term to exclude.) + /// + /// @param reader + /// @param field An interned field that holds both lower and upper terms. + /// @param lowerTermText The term text at the lower end of the range + /// @param upperTermText The term text at the upper end of the range + /// @param includeLower If true, the lowerTerm is included in the range. + /// @param includeUpper If true, the upperTerm is included in the range. + /// @param collator The collator to use to collate index Terms, to determine their membership in the range + /// bounded by lowerTerm and upperTerm. + TermRangeTermEnum(const IndexReaderPtr& reader, const String& field, StringValue lowerTermText, StringValue upperTermText, + bool includeLower, bool includeUpper, const CollatorPtr& collator); + + virtual ~TermRangeTermEnum(); + + LUCENE_CLASS(TermRangeTermEnum); + +protected: + CollatorPtr collator; + bool _endEnum; + String field; + StringValue upperTermText; + StringValue lowerTermText; + bool includeLower; + bool includeUpper; + +public: + virtual double difference(); + +protected: + virtual bool endEnum(); + virtual bool termCompare(const TermPtr& term); +}; + } #endif diff --git a/include/TermScorer.h b/include/TermScorer.h index 53786b39..5dbc2638 100644 --- a/include/TermScorer.h +++ b/include/TermScorer.h @@ -9,64 +9,64 @@ #include "Scorer.h" -namespace Lucene -{ - /// A Scorer for documents matching a Term. - class TermScorer : public Scorer - { - public: - /// Construct a TermScorer. - /// @param weight The weight of the Term in the query. - /// @param td An iterator over the documents matching the Term. - /// @param similarity The Similarity implementation to be used for score computations. - /// @param norms The field norms of the document fields for the Term. - TermScorer(const WeightPtr& weight, const TermDocsPtr& td, const SimilarityPtr& similarity, ByteArray norms); - - virtual ~TermScorer(); - - LUCENE_CLASS(TermScorer); - - protected: - WeightPtr weight; - TermDocsPtr termDocs; - ByteArray norms; - double weightValue; - int32_t doc; - - Collection docs; // buffered doc numbers - Collection freqs; // buffered term freqs - int32_t pointer; - int32_t pointerMax; - - static const int32_t SCORE_CACHE_SIZE; - Collection scoreCache; - - public: - virtual void score(const CollectorPtr& collector); - virtual int32_t docID(); - - /// Advances to the next document matching the query. - /// The iterator over the matching documents is buffered using {@link - /// TermDocs#read(Collection, Collection)}. - /// @return the document matching the query or -1 if there are no more documents. - virtual int32_t nextDoc(); - - virtual double score(); - - /// Advances to the first match beyond the current whose document number is greater than or equal to a - /// given target. The implementation uses {@link TermDocs#skipTo(int32_t)}. - /// @param target The target document number. - /// @return the matching document or -1 if none exist. - virtual int32_t advance(int32_t target); - - /// Returns a string representation of this TermScorer. - virtual String toString(); - - protected: - static const Collection SIM_NORM_DECODER(); - - virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); - }; +namespace Lucene { + +/// A Scorer for documents matching a Term. +class TermScorer : public Scorer { +public: + /// Construct a TermScorer. + /// @param weight The weight of the Term in the query. + /// @param td An iterator over the documents matching the Term. + /// @param similarity The Similarity implementation to be used for score computations. + /// @param norms The field norms of the document fields for the Term. + TermScorer(const WeightPtr& weight, const TermDocsPtr& td, const SimilarityPtr& similarity, ByteArray norms); + + virtual ~TermScorer(); + + LUCENE_CLASS(TermScorer); + +protected: + WeightPtr weight; + TermDocsPtr termDocs; + ByteArray norms; + double weightValue; + int32_t doc; + + Collection docs; // buffered doc numbers + Collection freqs; // buffered term freqs + int32_t pointer; + int32_t pointerMax; + + static const int32_t SCORE_CACHE_SIZE; + Collection scoreCache; + +public: + virtual void score(const CollectorPtr& collector); + virtual int32_t docID(); + + /// Advances to the next document matching the query. + /// The iterator over the matching documents is buffered using {@link + /// TermDocs#read(Collection, Collection)}. + /// @return the document matching the query or -1 if there are no more documents. + virtual int32_t nextDoc(); + + virtual double score(); + + /// Advances to the first match beyond the current whose document number is greater than or equal to a + /// given target. The implementation uses {@link TermDocs#skipTo(int32_t)}. + /// @param target The target document number. + /// @return the matching document or -1 if none exist. + virtual int32_t advance(int32_t target); + + /// Returns a string representation of this TermScorer. + virtual String toString(); + +protected: + static const Collection SIM_NORM_DECODER(); + + virtual bool score(const CollectorPtr& collector, int32_t max, int32_t firstDocID); +}; + } #endif diff --git a/include/TermSpans.h b/include/TermSpans.h index abf044e8..50944e55 100644 --- a/include/TermSpans.h +++ b/include/TermSpans.h @@ -9,37 +9,37 @@ #include "Spans.h" -namespace Lucene -{ - /// Public for extension only - class LPPAPI TermSpans : public Spans - { - public: - TermSpans(const TermPositionsPtr& positions, const TermPtr& term); - virtual ~TermSpans(); - - LUCENE_CLASS(TermSpans); - - protected: - TermPositionsPtr positions; - TermPtr term; - int32_t _doc; - int32_t freq; - int32_t count; - int32_t position; - - public: - virtual bool next(); - virtual bool skipTo(int32_t target); - virtual int32_t doc(); - virtual int32_t start(); - virtual int32_t end(); - virtual Collection getPayload(); - virtual bool isPayloadAvailable(); - virtual String toString(); - - TermPositionsPtr getPositions(); - }; +namespace Lucene { + +/// Public for extension only +class LPPAPI TermSpans : public Spans { +public: + TermSpans(const TermPositionsPtr& positions, const TermPtr& term); + virtual ~TermSpans(); + + LUCENE_CLASS(TermSpans); + +protected: + TermPositionsPtr positions; + TermPtr term; + int32_t _doc; + int32_t freq; + int32_t count; + int32_t position; + +public: + virtual bool next(); + virtual bool skipTo(int32_t target); + virtual int32_t doc(); + virtual int32_t start(); + virtual int32_t end(); + virtual Collection getPayload(); + virtual bool isPayloadAvailable(); + virtual String toString(); + + TermPositionsPtr getPositions(); +}; + } #endif diff --git a/include/TermVectorEntry.h b/include/TermVectorEntry.h index 5f70c9b0..cf52c923 100644 --- a/include/TermVectorEntry.h +++ b/include/TermVectorEntry.h @@ -9,41 +9,41 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Convenience class for holding TermVector information. - class LPPAPI TermVectorEntry : public LuceneObject - { - public: - TermVectorEntry(const String& field = EmptyString, const String& term = EmptyString, int32_t frequency = 0, - Collection offsets = Collection(), - Collection positions = Collection()); - virtual ~TermVectorEntry(); - - LUCENE_CLASS(TermVectorEntry); - - protected: - String field; - String term; - int32_t frequency; - Collection offsets; - Collection positions; - - public: - String getField(); - int32_t getFrequency(); - Collection getOffsets(); - Collection getPositions(); - String getTerm(); - - void setFrequency(int32_t frequency); - void setOffsets(Collection offsets); - void setPositions(Collection positions); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual String toString(); - }; +namespace Lucene { + +/// Convenience class for holding TermVector information. +class LPPAPI TermVectorEntry : public LuceneObject { +public: + TermVectorEntry(const String& field = EmptyString, const String& term = EmptyString, int32_t frequency = 0, + Collection offsets = Collection(), + Collection positions = Collection()); + virtual ~TermVectorEntry(); + + LUCENE_CLASS(TermVectorEntry); + +protected: + String field; + String term; + int32_t frequency; + Collection offsets; + Collection positions; + +public: + String getField(); + int32_t getFrequency(); + Collection getOffsets(); + Collection getPositions(); + String getTerm(); + + void setFrequency(int32_t frequency); + void setOffsets(Collection offsets); + void setPositions(Collection positions); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual String toString(); +}; + } #endif diff --git a/include/TermVectorEntryFreqSortedComparator.h b/include/TermVectorEntryFreqSortedComparator.h index 7e517977..8cadb852 100644 --- a/include/TermVectorEntryFreqSortedComparator.h +++ b/include/TermVectorEntryFreqSortedComparator.h @@ -9,19 +9,19 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Compares {@link TermVectorEntry}s first by frequency and then by the term (case-sensitive) - class LPPAPI TermVectorEntryFreqSortedComparator : public LuceneObject - { - public: - virtual ~TermVectorEntryFreqSortedComparator(); - - LUCENE_CLASS(TermVectorEntryFreqSortedComparator); - - public: - static bool compare(const TermVectorEntryPtr& first, const TermVectorEntryPtr& second); - }; +namespace Lucene { + +/// Compares {@link TermVectorEntry}s first by frequency and then by the term (case-sensitive) +class LPPAPI TermVectorEntryFreqSortedComparator : public LuceneObject { +public: + virtual ~TermVectorEntryFreqSortedComparator(); + + LUCENE_CLASS(TermVectorEntryFreqSortedComparator); + +public: + static bool compare(const TermVectorEntryPtr& first, const TermVectorEntryPtr& second); +}; + } #endif diff --git a/include/TermVectorMapper.h b/include/TermVectorMapper.h index 39d33691..3be7a305 100644 --- a/include/TermVectorMapper.h +++ b/include/TermVectorMapper.h @@ -9,65 +9,65 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// The TermVectorMapper can be used to map Term Vectors into your own structure instead of the parallel - /// array structure used by {@link IndexReader#getTermFreqVector(int,String)}. - /// - /// It is up to the implementation to make sure it is thread-safe. - class LPPAPI TermVectorMapper : public LuceneObject - { - public: - /// @param ignoringPositions true if this mapper should tell Lucene to ignore positions even if - /// they are stored. - /// @param ignoringOffsets similar to ignoringPositions - TermVectorMapper(bool ignoringPositions = false, bool ignoringOffsets = false); +namespace Lucene { + +/// The TermVectorMapper can be used to map Term Vectors into your own structure instead of the parallel +/// array structure used by {@link IndexReader#getTermFreqVector(int,String)}. +/// +/// It is up to the implementation to make sure it is thread-safe. +class LPPAPI TermVectorMapper : public LuceneObject { +public: + /// @param ignoringPositions true if this mapper should tell Lucene to ignore positions even if + /// they are stored. + /// @param ignoringOffsets similar to ignoringPositions + TermVectorMapper(bool ignoringPositions = false, bool ignoringOffsets = false); - virtual ~TermVectorMapper(); + virtual ~TermVectorMapper(); - LUCENE_CLASS(TermVectorMapper); + LUCENE_CLASS(TermVectorMapper); - protected: - bool ignoringPositions; - bool ignoringOffsets; +protected: + bool ignoringPositions; + bool ignoringOffsets; + +public: + /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. + /// This method will be called once before retrieving the vector for a field. + /// + /// This method will be called before {@link #map(String,int,TermVectorOffsetInfo[],int[])}. + /// @param field The field the vector is for + /// @param numTerms The number of terms that need to be mapped + /// @param storeOffsets true if the mapper should expect offset information + /// @param storePositions true if the mapper should expect positions info + virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) = 0; - public: - /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. - /// This method will be called once before retrieving the vector for a field. - /// - /// This method will be called before {@link #map(String,int,TermVectorOffsetInfo[],int[])}. - /// @param field The field the vector is for - /// @param numTerms The number of terms that need to be mapped - /// @param storeOffsets true if the mapper should expect offset information - /// @param storePositions true if the mapper should expect positions info - virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) = 0; + /// Map the Term Vector information into your own structure + /// @param term The term to add to the vector + /// @param frequency The frequency of the term in the document + /// @param offsets null if the offset is not specified, otherwise the offset into the field of the term + /// @param positions null if the position is not specified, otherwise the position in the field of the term + virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions) = 0; - /// Map the Term Vector information into your own structure - /// @param term The term to add to the vector - /// @param frequency The frequency of the term in the document - /// @param offsets null if the offset is not specified, otherwise the offset into the field of the term - /// @param positions null if the position is not specified, otherwise the position in the field of the term - virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions) = 0; + /// Indicate to Lucene that even if there are positions stored, this mapper is not interested in them and + /// they can be skipped over. Derived classes should set this to true if they want to ignore positions. + /// The default is false, meaning positions will be loaded if they are stored. + virtual bool isIgnoringPositions(); - /// Indicate to Lucene that even if there are positions stored, this mapper is not interested in them and - /// they can be skipped over. Derived classes should set this to true if they want to ignore positions. - /// The default is false, meaning positions will be loaded if they are stored. - virtual bool isIgnoringPositions(); + /// @see #isIgnoringPositions() Same principal as {@link #isIgnoringPositions()}, but applied to offsets. + virtual bool isIgnoringOffsets(); - /// @see #isIgnoringPositions() Same principal as {@link #isIgnoringPositions()}, but applied to offsets. - virtual bool isIgnoringOffsets(); + /// Passes down the index of the document whose term vector is currently being mapped, once for each top + /// level call to a term vector reader. + /// + /// Default implementation IGNORES the document number. Override if your implementation needs the document + /// number. + /// + /// NOTE: Document numbers are internal to Lucene and subject to change depending on indexing operations. + /// + /// @param documentNumber index of document currently being mapped + virtual void setDocumentNumber(int32_t documentNumber); +}; - /// Passes down the index of the document whose term vector is currently being mapped, once for each top - /// level call to a term vector reader. - /// - /// Default implementation IGNORES the document number. Override if your implementation needs the document - /// number. - /// - /// NOTE: Document numbers are internal to Lucene and subject to change depending on indexing operations. - /// - /// @param documentNumber index of document currently being mapped - virtual void setDocumentNumber(int32_t documentNumber); - }; } #endif diff --git a/include/TermVectorOffsetInfo.h b/include/TermVectorOffsetInfo.h index 64d973d1..8ed0ff5f 100644 --- a/include/TermVectorOffsetInfo.h +++ b/include/TermVectorOffsetInfo.h @@ -9,41 +9,41 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// The TermVectorOffsetInfo class holds information pertaining to a Term in a {@link TermPositionVector}'s - /// offset information. This offset information is the character offset as set during the Analysis phase - /// (and thus may not be the actual offset in the original content). - class LPPAPI TermVectorOffsetInfo : public LuceneObject - { - public: - TermVectorOffsetInfo(int32_t startOffset = 0, int32_t endOffset = 0); - virtual ~TermVectorOffsetInfo(); - - LUCENE_CLASS(TermVectorOffsetInfo); - - protected: - int32_t startOffset; - int32_t endOffset; - - public: - /// Convenience declaration when creating a {@link TermPositionVector} that stores only position information. - static const Collection EMPTY_OFFSET_INFO(); - - /// The accessor for the ending offset for the term - int32_t getEndOffset(); - void setEndOffset(int32_t endOffset); - - /// The accessor for the starting offset of the term. - int32_t getStartOffset(); - void setStartOffset(int32_t startOffset); - - /// Two TermVectorOffsetInfos are equals if both the start and end offsets are the same. - /// @return true if both {@link #getStartOffset()} and {@link #getEndOffset()} are the same for both objects. - virtual bool equals(const LuceneObjectPtr& other); - - virtual int32_t hashCode(); - }; +namespace Lucene { + +/// The TermVectorOffsetInfo class holds information pertaining to a Term in a {@link TermPositionVector}'s +/// offset information. This offset information is the character offset as set during the Analysis phase +/// (and thus may not be the actual offset in the original content). +class LPPAPI TermVectorOffsetInfo : public LuceneObject { +public: + TermVectorOffsetInfo(int32_t startOffset = 0, int32_t endOffset = 0); + virtual ~TermVectorOffsetInfo(); + + LUCENE_CLASS(TermVectorOffsetInfo); + +protected: + int32_t startOffset; + int32_t endOffset; + +public: + /// Convenience declaration when creating a {@link TermPositionVector} that stores only position information. + static const Collection EMPTY_OFFSET_INFO(); + + /// The accessor for the ending offset for the term + int32_t getEndOffset(); + void setEndOffset(int32_t endOffset); + + /// The accessor for the starting offset of the term. + int32_t getStartOffset(); + void setStartOffset(int32_t startOffset); + + /// Two TermVectorOffsetInfos are equals if both the start and end offsets are the same. + /// @return true if both {@link #getStartOffset()} and {@link #getEndOffset()} are the same for both objects. + virtual bool equals(const LuceneObjectPtr& other); + + virtual int32_t hashCode(); +}; + } #endif diff --git a/include/TermVectorsReader.h b/include/TermVectorsReader.h index 23d722e9..848f92ae 100644 --- a/include/TermVectorsReader.h +++ b/include/TermVectorsReader.h @@ -9,143 +9,142 @@ #include "TermVectorMapper.h" -namespace Lucene -{ - class TermVectorsReader : public LuceneObject - { - public: - TermVectorsReader(); - TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos); - TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, - int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); - virtual ~TermVectorsReader(); +namespace Lucene { - LUCENE_CLASS(TermVectorsReader); +class TermVectorsReader : public LuceneObject { +public: + TermVectorsReader(); + TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos); + TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, + int32_t readBufferSize, int32_t docStoreOffset = -1, int32_t size = 0); + virtual ~TermVectorsReader(); - public: - /// NOTE: if you make a new format, it must be larger than the current format - static const int32_t FORMAT_VERSION; + LUCENE_CLASS(TermVectorsReader); - /// Changes to speed up bulk merging of term vectors - static const int32_t FORMAT_VERSION2; +public: + /// NOTE: if you make a new format, it must be larger than the current format + static const int32_t FORMAT_VERSION; - /// Changed strings to UTF8 with length-in-bytes not length-in-chars - static const int32_t FORMAT_UTF8_LENGTH_IN_BYTES; + /// Changes to speed up bulk merging of term vectors + static const int32_t FORMAT_VERSION2; - /// NOTE: always change this if you switch to a new format. - static const int32_t FORMAT_CURRENT; + /// Changed strings to UTF8 with length-in-bytes not length-in-chars + static const int32_t FORMAT_UTF8_LENGTH_IN_BYTES; - /// The size in bytes that the FORMAT_VERSION will take up at the beginning of each file - static const int32_t FORMAT_SIZE; + /// NOTE: always change this if you switch to a new format. + static const int32_t FORMAT_CURRENT; - static const uint8_t STORE_POSITIONS_WITH_TERMVECTOR; - static const uint8_t STORE_OFFSET_WITH_TERMVECTOR; + /// The size in bytes that the FORMAT_VERSION will take up at the beginning of each file + static const int32_t FORMAT_SIZE; - protected: - FieldInfosPtr fieldInfos; + static const uint8_t STORE_POSITIONS_WITH_TERMVECTOR; + static const uint8_t STORE_OFFSET_WITH_TERMVECTOR; - IndexInputPtr tvx; - IndexInputPtr tvd; - IndexInputPtr tvf; - int32_t _size; - int32_t numTotalDocs; +protected: + FieldInfosPtr fieldInfos; - /// The docID offset where our docs begin in the index file. This will be 0 if we have our own private file. - int32_t docStoreOffset; + IndexInputPtr tvx; + IndexInputPtr tvd; + IndexInputPtr tvf; + int32_t _size; + int32_t numTotalDocs; - int32_t format; + /// The docID offset where our docs begin in the index file. This will be 0 if we have our own private file. + int32_t docStoreOffset; - public: - /// Used for bulk copy when merging - IndexInputPtr getTvdStream(); + int32_t format; - /// Used for bulk copy when merging - IndexInputPtr getTvfStream(); +public: + /// Used for bulk copy when merging + IndexInputPtr getTvdStream(); - bool canReadRawDocs(); + /// Used for bulk copy when merging + IndexInputPtr getTvfStream(); - /// Retrieve the length (in bytes) of the tvd and tvf entries for the next numDocs starting with - /// startDocID. This is used for bulk copying when merging segments, if the field numbers are - /// congruent. Once this returns, the tvf & tvd streams are seeked to the startDocID. - void rawDocs(Collection tvdLengths, Collection tvfLengths, int32_t startDocID, int32_t numDocs); + bool canReadRawDocs(); - void close(); + /// Retrieve the length (in bytes) of the tvd and tvf entries for the next numDocs starting with + /// startDocID. This is used for bulk copying when merging segments, if the field numbers are + /// congruent. Once this returns, the tvf & tvd streams are seeked to the startDocID. + void rawDocs(Collection tvdLengths, Collection tvfLengths, int32_t startDocID, int32_t numDocs); - /// @return The number of documents in the reader - int32_t size(); + void close(); - void get(int32_t docNum, const String& field, const TermVectorMapperPtr& mapper); + /// @return The number of documents in the reader + int32_t size(); - /// Retrieve the term vector for the given document and field - /// @param docNum The document number to retrieve the vector for - /// @param field The field within the document to retrieve - /// @return The TermFreqVector for the document and field or null if there is no termVector for - /// this field. - TermFreqVectorPtr get(int32_t docNum, const String& field); + void get(int32_t docNum, const String& field, const TermVectorMapperPtr& mapper); - /// Return all term vectors stored for this document or null if the could not be read in. - /// - /// @param docNum The document number to retrieve the vector for - /// @return All term frequency vectors - Collection get(int32_t docNum); + /// Retrieve the term vector for the given document and field + /// @param docNum The document number to retrieve the vector for + /// @param field The field within the document to retrieve + /// @return The TermFreqVector for the document and field or null if there is no termVector for + /// this field. + TermFreqVectorPtr get(int32_t docNum, const String& field); - void get(int32_t docNumber, const TermVectorMapperPtr& mapper); + /// Return all term vectors stored for this document or null if the could not be read in. + /// + /// @param docNum The document number to retrieve the vector for + /// @return All term frequency vectors + Collection get(int32_t docNum); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + void get(int32_t docNumber, const TermVectorMapperPtr& mapper); - protected: - void ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - void seekTvx(int32_t docNum); +protected: + void ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size); - int32_t checkValidFormat(const IndexInputPtr& in); + void seekTvx(int32_t docNum); - /// Reads the String[] fields; you have to pre-seek tvd to the right point - Collection readFields(int32_t fieldCount); + int32_t checkValidFormat(const IndexInputPtr& in); - /// Reads the long[] offsets into TVF; you have to pre-seek tvx/tvd to the right point - Collection readTvfPointers(int32_t fieldCount); + /// Reads the String[] fields; you have to pre-seek tvd to the right point + Collection readFields(int32_t fieldCount); - Collection readTermVectors(int32_t docNum, Collection fields, Collection tvfPointers); - void readTermVectors(Collection fields, Collection tvfPointers, const TermVectorMapperPtr& mapper); + /// Reads the long[] offsets into TVF; you have to pre-seek tvx/tvd to the right point + Collection readTvfPointers(int32_t fieldCount); - /// @param field The field to read in - /// @param tvfPointer The pointer within the tvf file where we should start reading - /// @param mapper The mapper used to map the TermVector - void readTermVector(const String& field, int64_t tvfPointer, const TermVectorMapperPtr& mapper); - }; + Collection readTermVectors(int32_t docNum, Collection fields, Collection tvfPointers); + void readTermVectors(Collection fields, Collection tvfPointers, const TermVectorMapperPtr& mapper); - /// Models the existing parallel array structure - class ParallelArrayTermVectorMapper : public TermVectorMapper - { - public: - ParallelArrayTermVectorMapper(); - virtual ~ParallelArrayTermVectorMapper(); + /// @param field The field to read in + /// @param tvfPointer The pointer within the tvf file where we should start reading + /// @param mapper The mapper used to map the TermVector + void readTermVector(const String& field, int64_t tvfPointer, const TermVectorMapperPtr& mapper); +}; - LUCENE_CLASS(ParallelArrayTermVectorMapper); +/// Models the existing parallel array structure +class ParallelArrayTermVectorMapper : public TermVectorMapper { +public: + ParallelArrayTermVectorMapper(); + virtual ~ParallelArrayTermVectorMapper(); - protected: - Collection terms; - Collection termFreqs; - Collection< Collection > positions; - Collection< Collection > offsets; - int32_t currentPosition; - bool storingOffsets; - bool storingPositions; - String field; + LUCENE_CLASS(ParallelArrayTermVectorMapper); - public: - /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. - /// This method will be called once before retrieving the vector for a field. - virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); +protected: + Collection terms; + Collection termFreqs; + Collection< Collection > positions; + Collection< Collection > offsets; + int32_t currentPosition; + bool storingOffsets; + bool storingPositions; + String field; - /// Map the Term Vector information into your own structure - virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); +public: + /// Tell the mapper what to expect in regards to field, number of terms, offset and position storage. + /// This method will be called once before retrieving the vector for a field. + virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions); + + /// Map the Term Vector information into your own structure + virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions); + + /// Construct the vector + /// @return The {@link TermFreqVector} based on the mappings. + TermFreqVectorPtr materializeVector(); +}; - /// Construct the vector - /// @return The {@link TermFreqVector} based on the mappings. - TermFreqVectorPtr materializeVector(); - }; } #endif diff --git a/include/TermVectorsTermsWriter.h b/include/TermVectorsTermsWriter.h index e9d715e5..0c7303f2 100644 --- a/include/TermVectorsTermsWriter.h +++ b/include/TermVectorsTermsWriter.h @@ -11,87 +11,85 @@ #include "DocumentsWriter.h" #include "RawPostingList.h" -namespace Lucene -{ - class TermVectorsTermsWriter : public TermsHashConsumer - { - public: - TermVectorsTermsWriter(const DocumentsWriterPtr& docWriter); - virtual ~TermVectorsTermsWriter(); - - LUCENE_CLASS(TermVectorsTermsWriter); - - public: - DocumentsWriterWeakPtr _docWriter; - TermVectorsWriterPtr termVectorsWriter; - Collection docFreeList; - int32_t freeCount; - IndexOutputPtr tvx; - IndexOutputPtr tvd; - IndexOutputPtr tvf; - int32_t lastDocID; - int32_t allocCount; - - public: - virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread); - virtual void createPostings(Collection postings, int32_t start, int32_t count); - virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); - virtual void closeDocStore(const SegmentWriteStatePtr& state); - - TermVectorsTermsWriterPerDocPtr getPerDoc(); - - /// Fills in no-term-vectors for all docs we haven't seen since the last doc that had term vectors. - void fill(int32_t docID); - - void initTermVectorsWriter(); - void finishDocument(const TermVectorsTermsWriterPerDocPtr& perDoc); - bool freeRAM(); - void free(const TermVectorsTermsWriterPerDocPtr& doc); - - virtual void abort(); - virtual int32_t bytesPerPosting(); - }; - - class TermVectorsTermsWriterPerDoc : public DocWriter - { - public: - TermVectorsTermsWriterPerDoc(const TermVectorsTermsWriterPtr& termsWriter = TermVectorsTermsWriterPtr()); - virtual ~TermVectorsTermsWriterPerDoc(); - - LUCENE_CLASS(TermVectorsTermsWriterPerDoc); - - protected: - TermVectorsTermsWriterWeakPtr _termsWriter; - - public: - PerDocBufferPtr buffer; - RAMOutputStreamPtr perDocTvf; - int32_t numVectorFields; - - Collection fieldNumbers; - Collection fieldPointers; - - public: - void reset(); - virtual void abort(); - void addField(int32_t fieldNumber); - virtual int64_t sizeInBytes(); - virtual void finish(); - }; - - class TermVectorsTermsWriterPostingList : public RawPostingList - { - public: - TermVectorsTermsWriterPostingList(); - virtual ~TermVectorsTermsWriterPostingList(); - - LUCENE_CLASS(TermVectorsTermsWriterPostingList); - - public: - int32_t freq; // How many times this term occurred in the current doc - int32_t lastOffset; // Last offset we saw - int32_t lastPosition; // Last position where this term occurred - }; +namespace Lucene { + +class TermVectorsTermsWriter : public TermsHashConsumer { +public: + TermVectorsTermsWriter(const DocumentsWriterPtr& docWriter); + virtual ~TermVectorsTermsWriter(); + + LUCENE_CLASS(TermVectorsTermsWriter); + +public: + DocumentsWriterWeakPtr _docWriter; + TermVectorsWriterPtr termVectorsWriter; + Collection docFreeList; + int32_t freeCount; + IndexOutputPtr tvx; + IndexOutputPtr tvd; + IndexOutputPtr tvf; + int32_t lastDocID; + int32_t allocCount; + +public: + virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread); + virtual void createPostings(Collection postings, int32_t start, int32_t count); + virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); + virtual void closeDocStore(const SegmentWriteStatePtr& state); + + TermVectorsTermsWriterPerDocPtr getPerDoc(); + + /// Fills in no-term-vectors for all docs we haven't seen since the last doc that had term vectors. + void fill(int32_t docID); + + void initTermVectorsWriter(); + void finishDocument(const TermVectorsTermsWriterPerDocPtr& perDoc); + bool freeRAM(); + void free(const TermVectorsTermsWriterPerDocPtr& doc); + + virtual void abort(); + virtual int32_t bytesPerPosting(); +}; + +class TermVectorsTermsWriterPerDoc : public DocWriter { +public: + TermVectorsTermsWriterPerDoc(const TermVectorsTermsWriterPtr& termsWriter = TermVectorsTermsWriterPtr()); + virtual ~TermVectorsTermsWriterPerDoc(); + + LUCENE_CLASS(TermVectorsTermsWriterPerDoc); + +protected: + TermVectorsTermsWriterWeakPtr _termsWriter; + +public: + PerDocBufferPtr buffer; + RAMOutputStreamPtr perDocTvf; + int32_t numVectorFields; + + Collection fieldNumbers; + Collection fieldPointers; + +public: + void reset(); + virtual void abort(); + void addField(int32_t fieldNumber); + virtual int64_t sizeInBytes(); + virtual void finish(); +}; + +class TermVectorsTermsWriterPostingList : public RawPostingList { +public: + TermVectorsTermsWriterPostingList(); + virtual ~TermVectorsTermsWriterPostingList(); + + LUCENE_CLASS(TermVectorsTermsWriterPostingList); + +public: + int32_t freq; // How many times this term occurred in the current doc + int32_t lastOffset; // Last offset we saw + int32_t lastPosition; // Last position where this term occurred +}; + } #endif diff --git a/include/TermVectorsTermsWriterPerField.h b/include/TermVectorsTermsWriterPerField.h index b719fd19..68bd35c9 100644 --- a/include/TermVectorsTermsWriterPerField.h +++ b/include/TermVectorsTermsWriterPerField.h @@ -9,47 +9,47 @@ #include "TermsHashConsumerPerField.h" -namespace Lucene -{ - class TermVectorsTermsWriterPerField : public TermsHashConsumerPerField - { - public: - TermVectorsTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const TermVectorsTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); - virtual ~TermVectorsTermsWriterPerField(); - - LUCENE_CLASS(TermVectorsTermsWriterPerField); - - public: - TermVectorsTermsWriterPerThreadWeakPtr _perThread; - TermsHashPerFieldWeakPtr _termsHashPerField; - TermVectorsTermsWriterWeakPtr _termsWriter; - FieldInfoPtr fieldInfo; - DocStateWeakPtr _docState; - FieldInvertStateWeakPtr _fieldState; - - bool doVectors; - bool doVectorPositions; - bool doVectorOffsets; - - int32_t maxNumPostings; - OffsetAttributePtr offsetAttribute; - - public: - virtual int32_t getStreamCount(); - virtual bool start(Collection fields, int32_t count); - virtual void abort(); - - /// Called once per field per document if term vectors are enabled, to write the vectors to RAMOutputStream, - /// which is then quickly flushed to the real term vectors files in the Directory. - virtual void finish(); - - void shrinkHash(); - - virtual void start(const FieldablePtr& field); - virtual void newTerm(const RawPostingListPtr& p0); - virtual void addTerm(const RawPostingListPtr& p0); - virtual void skippingLongTerm(); - }; +namespace Lucene { + +class TermVectorsTermsWriterPerField : public TermsHashConsumerPerField { +public: + TermVectorsTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const TermVectorsTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo); + virtual ~TermVectorsTermsWriterPerField(); + + LUCENE_CLASS(TermVectorsTermsWriterPerField); + +public: + TermVectorsTermsWriterPerThreadWeakPtr _perThread; + TermsHashPerFieldWeakPtr _termsHashPerField; + TermVectorsTermsWriterWeakPtr _termsWriter; + FieldInfoPtr fieldInfo; + DocStateWeakPtr _docState; + FieldInvertStateWeakPtr _fieldState; + + bool doVectors; + bool doVectorPositions; + bool doVectorOffsets; + + int32_t maxNumPostings; + OffsetAttributePtr offsetAttribute; + +public: + virtual int32_t getStreamCount(); + virtual bool start(Collection fields, int32_t count); + virtual void abort(); + + /// Called once per field per document if term vectors are enabled, to write the vectors to RAMOutputStream, + /// which is then quickly flushed to the real term vectors files in the Directory. + virtual void finish(); + + void shrinkHash(); + + virtual void start(const FieldablePtr& field); + virtual void newTerm(const RawPostingListPtr& p0); + virtual void addTerm(const RawPostingListPtr& p0); + virtual void skippingLongTerm(); +}; + } #endif diff --git a/include/TermVectorsTermsWriterPerThread.h b/include/TermVectorsTermsWriterPerThread.h index 2f6eecef..e0ec6a54 100644 --- a/include/TermVectorsTermsWriterPerThread.h +++ b/include/TermVectorsTermsWriterPerThread.h @@ -9,36 +9,36 @@ #include "TermsHashConsumerPerThread.h" -namespace Lucene -{ - class TermVectorsTermsWriterPerThread : public TermsHashConsumerPerThread - { - public: - TermVectorsTermsWriterPerThread(const TermsHashPerThreadPtr& termsHashPerThread, const TermVectorsTermsWriterPtr& termsWriter); - virtual ~TermVectorsTermsWriterPerThread(); - - LUCENE_CLASS(TermVectorsTermsWriterPerThread); - - public: - TermVectorsTermsWriterWeakPtr _termsWriter; - TermsHashPerThreadWeakPtr _termsHashPerThread; - DocStateWeakPtr _docState; - - TermVectorsTermsWriterPerDocPtr doc; - ByteSliceReaderPtr vectorSliceReader; - Collection utf8Results; - String lastVectorFieldName; - - public: - virtual void startDocument(); - virtual DocWriterPtr finishDocument(); - virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo); - virtual void abort(); - - /// Called only by assert - bool clearLastVectorFieldName(); - bool vectorFieldsInOrder(const FieldInfoPtr& fi); - }; +namespace Lucene { + +class TermVectorsTermsWriterPerThread : public TermsHashConsumerPerThread { +public: + TermVectorsTermsWriterPerThread(const TermsHashPerThreadPtr& termsHashPerThread, const TermVectorsTermsWriterPtr& termsWriter); + virtual ~TermVectorsTermsWriterPerThread(); + + LUCENE_CLASS(TermVectorsTermsWriterPerThread); + +public: + TermVectorsTermsWriterWeakPtr _termsWriter; + TermsHashPerThreadWeakPtr _termsHashPerThread; + DocStateWeakPtr _docState; + + TermVectorsTermsWriterPerDocPtr doc; + ByteSliceReaderPtr vectorSliceReader; + Collection utf8Results; + String lastVectorFieldName; + +public: + virtual void startDocument(); + virtual DocWriterPtr finishDocument(); + virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo); + virtual void abort(); + + /// Called only by assert + bool clearLastVectorFieldName(); + bool vectorFieldsInOrder(const FieldInfoPtr& fi); +}; + } #endif diff --git a/include/TermVectorsWriter.h b/include/TermVectorsWriter.h index 2d03d20c..8e5a61e6 100644 --- a/include/TermVectorsWriter.h +++ b/include/TermVectorsWriter.h @@ -9,35 +9,35 @@ #include "LuceneObject.h" -namespace Lucene -{ - class TermVectorsWriter : public LuceneObject - { - public: - TermVectorsWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fieldInfos); - virtual ~TermVectorsWriter(); - - LUCENE_CLASS(TermVectorsWriter); - - protected: - IndexOutputPtr tvx; - IndexOutputPtr tvd; - IndexOutputPtr tvf; - FieldInfosPtr fieldInfos; - Collection utf8Results; - - public: - /// Add a complete document specified by all its term vectors. If document has no term vectors, - /// add value for tvx. - void addAllDocVectors(Collection vectors); - - /// Do a bulk copy of numDocs documents from reader to our streams. This is used to expedite merging, - /// if the field numbers are congruent. - void addRawDocuments(const TermVectorsReaderPtr& reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs); - - /// Close all streams. - void close(); - }; +namespace Lucene { + +class TermVectorsWriter : public LuceneObject { +public: + TermVectorsWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fieldInfos); + virtual ~TermVectorsWriter(); + + LUCENE_CLASS(TermVectorsWriter); + +protected: + IndexOutputPtr tvx; + IndexOutputPtr tvd; + IndexOutputPtr tvf; + FieldInfosPtr fieldInfos; + Collection utf8Results; + +public: + /// Add a complete document specified by all its term vectors. If document has no term vectors, + /// add value for tvx. + void addAllDocVectors(Collection vectors); + + /// Do a bulk copy of numDocs documents from reader to our streams. This is used to expedite merging, + /// if the field numbers are congruent. + void addRawDocuments(const TermVectorsReaderPtr& reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs); + + /// Close all streams. + void close(); +}; + } #endif diff --git a/include/TermsHash.h b/include/TermsHash.h index 5710d5bc..f390bd8d 100644 --- a/include/TermsHash.h +++ b/include/TermsHash.h @@ -9,60 +9,60 @@ #include "InvertedDocConsumer.h" -namespace Lucene -{ - /// This class implements {@link InvertedDocConsumer}, which is passed each token produced by the analyzer on - /// each field. It stores these tokens in a hash table, and allocates separate byte streams per token. Consumers - /// of this class, eg {@link FreqProxTermsWriter} and {@link TermVectorsTermsWriter}, write their own byte streams - /// under each term. - class TermsHash : public InvertedDocConsumer - { - public: - TermsHash(const DocumentsWriterPtr& docWriter, bool trackAllocations, const TermsHashConsumerPtr& consumer, const TermsHashPtr& nextTermsHash); - virtual ~TermsHash(); - - LUCENE_CLASS(TermsHash); - - public: - TermsHashConsumerPtr consumer; - TermsHashPtr nextTermsHash; - int32_t bytesPerPosting; - int32_t postingsFreeChunk; - DocumentsWriterWeakPtr _docWriter; - bool trackAllocations; - - protected: - Collection postingsFreeList; - int32_t postingsFreeCount; - int32_t postingsAllocCount; - - public: - /// Add a new thread - virtual InvertedDocConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread); - virtual TermsHashPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPerThreadPtr& primaryPerThread); - - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); - - /// Abort (called after hitting AbortException) - /// NOTE: do not make this sync'd; it's not necessary (DW ensures all other threads are idle), and it - /// leads to deadlock - virtual void abort(); - - void shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); - - /// Close doc stores - virtual void closeDocStore(const SegmentWriteStatePtr& state); - - /// Flush a new segment - virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); - - /// Attempt to free RAM, returning true if any RAM was freed - virtual bool freeRAM(); - - void recyclePostings(Collection postings, int32_t numPostings); - - void getPostings(Collection postings); - }; +namespace Lucene { + +/// This class implements {@link InvertedDocConsumer}, which is passed each token produced by the analyzer on +/// each field. It stores these tokens in a hash table, and allocates separate byte streams per token. Consumers +/// of this class, eg {@link FreqProxTermsWriter} and {@link TermVectorsTermsWriter}, write their own byte streams +/// under each term. +class TermsHash : public InvertedDocConsumer { +public: + TermsHash(const DocumentsWriterPtr& docWriter, bool trackAllocations, const TermsHashConsumerPtr& consumer, const TermsHashPtr& nextTermsHash); + virtual ~TermsHash(); + + LUCENE_CLASS(TermsHash); + +public: + TermsHashConsumerPtr consumer; + TermsHashPtr nextTermsHash; + int32_t bytesPerPosting; + int32_t postingsFreeChunk; + DocumentsWriterWeakPtr _docWriter; + bool trackAllocations; + +protected: + Collection postingsFreeList; + int32_t postingsFreeCount; + int32_t postingsAllocCount; + +public: + /// Add a new thread + virtual InvertedDocConsumerPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread); + virtual TermsHashPerThreadPtr addThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPerThreadPtr& primaryPerThread); + + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); + + /// Abort (called after hitting AbortException) + /// NOTE: do not make this sync'd; it's not necessary (DW ensures all other threads are idle), and it + /// leads to deadlock + virtual void abort(); + + void shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); + + /// Close doc stores + virtual void closeDocStore(const SegmentWriteStatePtr& state); + + /// Flush a new segment + virtual void flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state); + + /// Attempt to free RAM, returning true if any RAM was freed + virtual bool freeRAM(); + + void recyclePostings(Collection postings, int32_t numPostings); + + void getPostings(Collection postings); +}; + } #endif diff --git a/include/TermsHashConsumer.h b/include/TermsHashConsumer.h index 8c9b87ff..04e8356f 100644 --- a/include/TermsHashConsumer.h +++ b/include/TermsHashConsumer.h @@ -9,28 +9,28 @@ #include "LuceneObject.h" -namespace Lucene -{ - class TermsHashConsumer : public LuceneObject - { - public: - virtual ~TermsHashConsumer(); - - LUCENE_CLASS(TermsHashConsumer); - - public: - FieldInfosPtr fieldInfos; - - public: - virtual int32_t bytesPerPosting() = 0; - virtual void createPostings(Collection postings, int32_t start, int32_t count) = 0; - virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread) = 0; - virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; - virtual void abort() = 0; - virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; - - virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); - }; +namespace Lucene { + +class TermsHashConsumer : public LuceneObject { +public: + virtual ~TermsHashConsumer(); + + LUCENE_CLASS(TermsHashConsumer); + +public: + FieldInfosPtr fieldInfos; + +public: + virtual int32_t bytesPerPosting() = 0; + virtual void createPostings(Collection postings, int32_t start, int32_t count) = 0; + virtual TermsHashConsumerPerThreadPtr addThread(const TermsHashPerThreadPtr& perThread) = 0; + virtual void flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) = 0; + virtual void abort() = 0; + virtual void closeDocStore(const SegmentWriteStatePtr& state) = 0; + + virtual void setFieldInfos(const FieldInfosPtr& fieldInfos); +}; + } #endif diff --git a/include/TermsHashConsumerPerField.h b/include/TermsHashConsumerPerField.h index 7718bc20..b05dc6db 100644 --- a/include/TermsHashConsumerPerField.h +++ b/include/TermsHashConsumerPerField.h @@ -9,26 +9,26 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Implement this class to plug into the TermsHash processor, which inverts & stores Tokens into a hash - /// table and provides an API for writing bytes into multiple streams for each unique Token. - class TermsHashConsumerPerField : public LuceneObject - { - public: - virtual ~TermsHashConsumerPerField(); - - LUCENE_CLASS(TermsHashConsumerPerField); - - public: - virtual bool start(Collection fields, int32_t count) = 0; - virtual void finish() = 0; - virtual void skippingLongTerm() = 0; - virtual void start(const FieldablePtr& field) = 0; - virtual void newTerm(const RawPostingListPtr& p) = 0; - virtual void addTerm(const RawPostingListPtr& p) = 0; - virtual int32_t getStreamCount() = 0; - }; +namespace Lucene { + +/// Implement this class to plug into the TermsHash processor, which inverts & stores Tokens into a hash +/// table and provides an API for writing bytes into multiple streams for each unique Token. +class TermsHashConsumerPerField : public LuceneObject { +public: + virtual ~TermsHashConsumerPerField(); + + LUCENE_CLASS(TermsHashConsumerPerField); + +public: + virtual bool start(Collection fields, int32_t count) = 0; + virtual void finish() = 0; + virtual void skippingLongTerm() = 0; + virtual void start(const FieldablePtr& field) = 0; + virtual void newTerm(const RawPostingListPtr& p) = 0; + virtual void addTerm(const RawPostingListPtr& p) = 0; + virtual int32_t getStreamCount() = 0; +}; + } #endif diff --git a/include/TermsHashConsumerPerThread.h b/include/TermsHashConsumerPerThread.h index b3a443a3..9e074b5b 100644 --- a/include/TermsHashConsumerPerThread.h +++ b/include/TermsHashConsumerPerThread.h @@ -9,21 +9,21 @@ #include "LuceneObject.h" -namespace Lucene -{ - class TermsHashConsumerPerThread : public LuceneObject - { - public: - virtual ~TermsHashConsumerPerThread(); - - LUCENE_CLASS(TermsHashConsumerPerThread); - - public: - virtual void startDocument() = 0; - virtual DocWriterPtr finishDocument() = 0; - virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) = 0; - virtual void abort() = 0; - }; +namespace Lucene { + +class TermsHashConsumerPerThread : public LuceneObject { +public: + virtual ~TermsHashConsumerPerThread(); + + LUCENE_CLASS(TermsHashConsumerPerThread); + +public: + virtual void startDocument() = 0; + virtual DocWriterPtr finishDocument() = 0; + virtual TermsHashConsumerPerFieldPtr addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) = 0; + virtual void abort() = 0; +}; + } #endif diff --git a/include/TermsHashPerField.h b/include/TermsHashPerField.h index aac8e073..bd6cff73 100644 --- a/include/TermsHashPerField.h +++ b/include/TermsHashPerField.h @@ -9,91 +9,91 @@ #include "InvertedDocConsumerPerField.h" -namespace Lucene -{ - class TermsHashPerField : public InvertedDocConsumerPerField - { - public: - TermsHashPerField(const DocInverterPerFieldPtr& docInverterPerField, const TermsHashPerThreadPtr& perThread, const TermsHashPerThreadPtr& nextPerThread, const FieldInfoPtr& fieldInfo); - virtual ~TermsHashPerField(); +namespace Lucene { - LUCENE_CLASS(TermsHashPerField); +class TermsHashPerField : public InvertedDocConsumerPerField { +public: + TermsHashPerField(const DocInverterPerFieldPtr& docInverterPerField, const TermsHashPerThreadPtr& perThread, const TermsHashPerThreadPtr& nextPerThread, const FieldInfoPtr& fieldInfo); + virtual ~TermsHashPerField(); - public: - TermsHashConsumerPerFieldPtr consumer; - TermsHashPerFieldPtr nextPerField; - DocInverterPerFieldWeakPtr _docInverterPerField; - TermsHashPerThreadPtr nextPerThread; - TermsHashPerThreadWeakPtr _perThread; - DocStatePtr docState; - FieldInvertStatePtr fieldState; - TermAttributePtr termAtt; + LUCENE_CLASS(TermsHashPerField); - // Copied from our perThread - CharBlockPoolPtr charPool; - IntBlockPoolPtr intPool; - ByteBlockPoolPtr bytePool; +public: + TermsHashConsumerPerFieldPtr consumer; + TermsHashPerFieldPtr nextPerField; + DocInverterPerFieldWeakPtr _docInverterPerField; + TermsHashPerThreadPtr nextPerThread; + TermsHashPerThreadWeakPtr _perThread; + DocStatePtr docState; + FieldInvertStatePtr fieldState; + TermAttributePtr termAtt; - int32_t streamCount; - int32_t numPostingInt; + // Copied from our perThread + CharBlockPoolPtr charPool; + IntBlockPoolPtr intPool; + ByteBlockPoolPtr bytePool; - FieldInfoPtr fieldInfo; + int32_t streamCount; + int32_t numPostingInt; - bool postingsCompacted; - int32_t numPostings; + FieldInfoPtr fieldInfo; - IntArray intUptos; - int32_t intUptoStart; + bool postingsCompacted; + int32_t numPostings; - protected: - int32_t postingsHashSize; - int32_t postingsHashHalfSize; - int32_t postingsHashMask; - Collection postingsHash; - RawPostingListPtr p; - bool doCall; - bool doNextCall; + IntArray intUptos; + int32_t intUptoStart; - public: - virtual void initialize(); - void shrinkHash(int32_t targetSize); - void reset(); +protected: + int32_t postingsHashSize; + int32_t postingsHashHalfSize; + int32_t postingsHashMask; + Collection postingsHash; + RawPostingListPtr p; + bool doCall; + bool doNextCall; - /// Called on hitting an aborting exception - virtual void abort(); +public: + virtual void initialize(); + void shrinkHash(int32_t targetSize); + void reset(); - void initReader(const ByteSliceReaderPtr& reader, const RawPostingListPtr& p, int32_t stream); + /// Called on hitting an aborting exception + virtual void abort(); - /// Collapse the hash table and sort in-place. - Collection sortPostings(); + void initReader(const ByteSliceReaderPtr& reader, const RawPostingListPtr& p, int32_t stream); - /// Called before a field instance is being processed - virtual void start(const FieldablePtr& field); + /// Collapse the hash table and sort in-place. + Collection sortPostings(); - /// Called once per field, and is given all Fieldable occurrences for this field in the document. - virtual bool start(Collection fields, int32_t count); + /// Called before a field instance is being processed + virtual void start(const FieldablePtr& field); - void add(int32_t textStart); + /// Called once per field, and is given all Fieldable occurrences for this field in the document. + virtual bool start(Collection fields, int32_t count); - /// Primary entry point (for first TermsHash) - virtual void add(); + void add(int32_t textStart); - void writeByte(int32_t stream, int8_t b); - void writeBytes(int32_t stream, const uint8_t* b, int32_t offset, int32_t length); - void writeVInt(int32_t stream, int32_t i); + /// Primary entry point (for first TermsHash) + virtual void add(); - /// Called once per field per document, after all Fieldable occurrences are inverted - virtual void finish(); + void writeByte(int32_t stream, int8_t b); + void writeBytes(int32_t stream, const uint8_t* b, int32_t offset, int32_t length); + void writeVInt(int32_t stream, int32_t i); - /// Called when postings hash is too small (> 50% occupied) or too large (< 20% occupied). - void rehashPostings(int32_t newSize); + /// Called once per field per document, after all Fieldable occurrences are inverted + virtual void finish(); - protected: - void compactPostings(); + /// Called when postings hash is too small (> 50% occupied) or too large (< 20% occupied). + void rehashPostings(int32_t newSize); + +protected: + void compactPostings(); + + /// Test whether the text for current RawPostingList p equals current tokenText. + bool postingEquals(const wchar_t* tokenText, int32_t tokenTextLen); +}; - /// Test whether the text for current RawPostingList p equals current tokenText. - bool postingEquals(const wchar_t* tokenText, int32_t tokenTextLen); - }; } #endif diff --git a/include/TermsHashPerThread.h b/include/TermsHashPerThread.h index da9dba67..7ae0fae9 100644 --- a/include/TermsHashPerThread.h +++ b/include/TermsHashPerThread.h @@ -9,51 +9,51 @@ #include "InvertedDocConsumerPerThread.h" -namespace Lucene -{ - class TermsHashPerThread : public InvertedDocConsumerPerThread - { - public: - TermsHashPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPtr& termsHash, const TermsHashPtr& nextTermsHash, const TermsHashPerThreadPtr& primaryPerThread); - virtual ~TermsHashPerThread(); - - LUCENE_CLASS(TermsHashPerThread); - - public: - DocInverterPerThreadWeakPtr _docInverterPerThread; - TermsHashWeakPtr _termsHash; - TermsHashPtr nextTermsHash; - TermsHashPerThreadWeakPtr _primaryPerThread; - TermsHashConsumerPerThreadPtr consumer; - TermsHashPerThreadPtr nextPerThread; - - CharBlockPoolPtr charPool; - IntBlockPoolPtr intPool; - ByteBlockPoolPtr bytePool; - bool primary; - DocStatePtr docState; - - Collection freePostings; - int32_t freePostingsCount; - - public: - virtual void initialize(); - - virtual InvertedDocConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo); - virtual void abort(); - - /// perField calls this when it needs more postings - void morePostings(); - - virtual void startDocument(); - virtual DocWriterPtr finishDocument(); - - /// Clear all state - void reset(bool recyclePostings); - - protected: - static bool noNullPostings(Collection postings, int32_t count, const String& details); - }; +namespace Lucene { + +class TermsHashPerThread : public InvertedDocConsumerPerThread { +public: + TermsHashPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPtr& termsHash, const TermsHashPtr& nextTermsHash, const TermsHashPerThreadPtr& primaryPerThread); + virtual ~TermsHashPerThread(); + + LUCENE_CLASS(TermsHashPerThread); + +public: + DocInverterPerThreadWeakPtr _docInverterPerThread; + TermsHashWeakPtr _termsHash; + TermsHashPtr nextTermsHash; + TermsHashPerThreadWeakPtr _primaryPerThread; + TermsHashConsumerPerThreadPtr consumer; + TermsHashPerThreadPtr nextPerThread; + + CharBlockPoolPtr charPool; + IntBlockPoolPtr intPool; + ByteBlockPoolPtr bytePool; + bool primary; + DocStatePtr docState; + + Collection freePostings; + int32_t freePostingsCount; + +public: + virtual void initialize(); + + virtual InvertedDocConsumerPerFieldPtr addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo); + virtual void abort(); + + /// perField calls this when it needs more postings + void morePostings(); + + virtual void startDocument(); + virtual DocWriterPtr finishDocument(); + + /// Clear all state + void reset(bool recyclePostings); + +protected: + static bool noNullPostings(Collection postings, int32_t count, const String& details); +}; + } #endif diff --git a/include/TestPoint.h b/include/TestPoint.h index da1ac3dd..b387cd3d 100644 --- a/include/TestPoint.h +++ b/include/TestPoint.h @@ -9,36 +9,35 @@ #include "Lucene.h" -namespace Lucene -{ - /// Used for unit testing as a substitute for stack trace - class TestPoint - { - public: - virtual ~TestPoint(); - - protected: - static MapStringInt testMethods; - static bool enable; - - public: - static void enableTestPoints(); - static void clear(); - static void setTestPoint(const String& object, const String& method, bool point); - static bool getTestPoint(const String& object, const String& method); - static bool getTestPoint(const String& method); - }; - - class TestScope - { - public: - TestScope(const String& object, const String& method); - virtual ~TestScope(); - - protected: - String object; - String method; - }; +namespace Lucene { + +/// Used for unit testing as a substitute for stack trace +class TestPoint { +public: + virtual ~TestPoint(); + +protected: + static MapStringInt testMethods; + static bool enable; + +public: + static void enableTestPoints(); + static void clear(); + static void setTestPoint(const String& object, const String& method, bool point); + static bool getTestPoint(const String& object, const String& method); + static bool getTestPoint(const String& method); +}; + +class TestScope { +public: + TestScope(const String& object, const String& method); + virtual ~TestScope(); + +protected: + String object; + String method; +}; + } #endif diff --git a/include/ThreadPool.h b/include/ThreadPool.h index c94fc690..dc6446ff 100644 --- a/include/ThreadPool.h +++ b/include/ThreadPool.h @@ -12,75 +12,71 @@ #include #include "LuceneObject.h" -namespace Lucene -{ - typedef boost::shared_ptr workPtr; - - /// A Future represents the result of an asynchronous computation. Methods are provided to check if the computation - /// is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be - /// retrieved using method get when the computation has completed, blocking if necessary until it is ready. - class Future : public LuceneObject - { - public: - virtual ~Future(); - - protected: - boost::any value; - - public: - void set(const boost::any& value) - { - SyncLock syncLock(this); - this->value = value; - } +namespace Lucene { - template - TYPE get() - { - SyncLock syncLock(this); - while (value.empty()) - wait(10); - return value.empty() ? TYPE() : boost::any_cast(value); - } - }; - - /// Utility class to handle a pool of threads. - class ThreadPool : public LuceneObject - { - public: - ThreadPool(); - virtual ~ThreadPool(); - - LUCENE_CLASS(ThreadPool); - - protected: - boost::asio::io_service io_service; - workPtr work; - boost::thread_group threadGroup; - - static const int32_t THREADPOOL_SIZE; - - public: - /// Get singleton thread pool instance. - static ThreadPoolPtr getInstance(); - - template - FuturePtr scheduleTask(FUNC func) - { - FuturePtr future(newInstance()); - io_service.post(boost::bind(&ThreadPool::execute, this, func, future)); - return future; - } +typedef boost::shared_ptr workPtr; + +/// A Future represents the result of an asynchronous computation. Methods are provided to check if the computation +/// is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be +/// retrieved using method get when the computation has completed, blocking if necessary until it is ready. +class Future : public LuceneObject { +public: + virtual ~Future(); - protected: - // this will be executed when one of the threads is available - template - void execute(FUNC func, const FuturePtr& future) - { - future->set(func()); - future->notifyAll(); +protected: + boost::any value; + +public: + void set(const boost::any& value) { + SyncLock syncLock(this); + this->value = value; + } + + template + TYPE get() { + SyncLock syncLock(this); + while (value.empty()) { + wait(10); } - }; + return value.empty() ? TYPE() : boost::any_cast(value); + } +}; + +/// Utility class to handle a pool of threads. +class ThreadPool : public LuceneObject { +public: + ThreadPool(); + virtual ~ThreadPool(); + + LUCENE_CLASS(ThreadPool); + +protected: + boost::asio::io_service io_service; + workPtr work; + boost::thread_group threadGroup; + + static const int32_t THREADPOOL_SIZE; + +public: + /// Get singleton thread pool instance. + static ThreadPoolPtr getInstance(); + + template + FuturePtr scheduleTask(FUNC func) { + FuturePtr future(newInstance()); + io_service.post(boost::bind(&ThreadPool::execute, this, func, future)); + return future; + } + +protected: + // this will be executed when one of the threads is available + template + void execute(FUNC func, const FuturePtr& future) { + future->set(func()); + future->notifyAll(); + } +}; + } #endif diff --git a/include/TimeLimitingCollector.h b/include/TimeLimitingCollector.h index 9fb236b4..7f377b09 100644 --- a/include/TimeLimitingCollector.h +++ b/include/TimeLimitingCollector.h @@ -9,89 +9,89 @@ #include "Collector.h" -namespace Lucene -{ - /// The {@link TimeLimitingCollector} is used to timeout search requests that take longer than the maximum - /// allowed search time limit. After this time is exceeded, the search thread is stopped by throwing a - /// {@link TimeExceededException}. - class LPPAPI TimeLimitingCollector : public Collector - { - public: - /// Create a TimeLimitedCollector wrapper over another {@link Collector} with a specified timeout. - /// @param collector the wrapped {@link Collector} - /// @param timeAllowed max time allowed for collecting hits after which TimeExceeded exception is thrown - TimeLimitingCollector(const CollectorPtr& collector, int64_t timeAllowed); - - virtual ~TimeLimitingCollector(); - - LUCENE_CLASS(TimeLimitingCollector); - - public: - /// Default timer resolution. - /// @see #setResolution(int64_t) - static const int32_t DEFAULT_RESOLUTION; - - /// Default for {@link #isGreedy()}. - /// @see #isGreedy() - bool DEFAULT_GREEDY; - - protected: - static int64_t resolution; - bool greedy; - - int64_t t0; - int64_t timeout; - CollectorPtr collector; - - int32_t docBase; - - public: - /// Return the timer resolution. - /// @see #setResolution(int64_t) - static int64_t getResolution(); - - /// Set the timer resolution. - /// The default timer resolution is 20 milliseconds. - /// This means that a search required to take no longer than 800 milliseconds may be stopped after - /// 780 to 820 milliseconds. Note that: - ///
        - ///
      • Finer (smaller) resolution is more accurate but less efficient. - ///
      • Setting resolution to less than 5 milliseconds will be silently modified to 5 milliseconds. - ///
      • Setting resolution smaller than current resolution might take effect only after current resolution. - /// (Assume current resolution of 20 milliseconds is modified to 5 milliseconds, then it can take up to 20 - /// milliseconds for the change to have effect. - ///
      - static void setResolution(int64_t newResolution); - - /// Stop timer thread. - static void stopTimer(); - - /// Checks if this time limited collector is greedy in collecting the last hit. A non greedy collector, - /// upon a timeout, would throw a TimeExceeded without allowing the wrapped collector to collect current - /// doc. A greedy one would first allow the wrapped hit collector to collect current doc and only then - /// throw a TimeExceeded exception. - /// @see #setGreedy(boolean) - bool isGreedy(); - - /// Sets whether this time limited collector is greedy. - /// @param greedy true to make this time limited greedy - /// @see #isGreedy() - void setGreedy(bool greedy); - - /// Calls {@link Collector#collect(int)} on the decorated {@link Collector} unless the allowed time has - /// passed, in which case it throws an exception. - virtual void collect(int32_t doc); - - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setScorer(const ScorerPtr& scorer); - virtual bool acceptsDocsOutOfOrder(); - - protected: - /// Initialize a single static timer thread to be used by all TimeLimitedCollector instances. - static TimerThreadPtr TIMER_THREAD(); - - friend class TimerThread; - }; +namespace Lucene { + +/// The {@link TimeLimitingCollector} is used to timeout search requests that take longer than the maximum +/// allowed search time limit. After this time is exceeded, the search thread is stopped by throwing a +/// {@link TimeExceededException}. +class LPPAPI TimeLimitingCollector : public Collector { +public: + /// Create a TimeLimitedCollector wrapper over another {@link Collector} with a specified timeout. + /// @param collector the wrapped {@link Collector} + /// @param timeAllowed max time allowed for collecting hits after which TimeExceeded exception is thrown + TimeLimitingCollector(const CollectorPtr& collector, int64_t timeAllowed); + + virtual ~TimeLimitingCollector(); + + LUCENE_CLASS(TimeLimitingCollector); + +public: + /// Default timer resolution. + /// @see #setResolution(int64_t) + static const int32_t DEFAULT_RESOLUTION; + + /// Default for {@link #isGreedy()}. + /// @see #isGreedy() + bool DEFAULT_GREEDY; + +protected: + static int64_t resolution; + bool greedy; + + int64_t t0; + int64_t timeout; + CollectorPtr collector; + + int32_t docBase; + +public: + /// Return the timer resolution. + /// @see #setResolution(int64_t) + static int64_t getResolution(); + + /// Set the timer resolution. + /// The default timer resolution is 20 milliseconds. + /// This means that a search required to take no longer than 800 milliseconds may be stopped after + /// 780 to 820 milliseconds. Note that: + ///
        + ///
      • Finer (smaller) resolution is more accurate but less efficient. + ///
      • Setting resolution to less than 5 milliseconds will be silently modified to 5 milliseconds. + ///
      • Setting resolution smaller than current resolution might take effect only after current resolution. + /// (Assume current resolution of 20 milliseconds is modified to 5 milliseconds, then it can take up to 20 + /// milliseconds for the change to have effect. + ///
      + static void setResolution(int64_t newResolution); + + /// Stop timer thread. + static void stopTimer(); + + /// Checks if this time limited collector is greedy in collecting the last hit. A non greedy collector, + /// upon a timeout, would throw a TimeExceeded without allowing the wrapped collector to collect current + /// doc. A greedy one would first allow the wrapped hit collector to collect current doc and only then + /// throw a TimeExceeded exception. + /// @see #setGreedy(boolean) + bool isGreedy(); + + /// Sets whether this time limited collector is greedy. + /// @param greedy true to make this time limited greedy + /// @see #isGreedy() + void setGreedy(bool greedy); + + /// Calls {@link Collector#collect(int)} on the decorated {@link Collector} unless the allowed time has + /// passed, in which case it throws an exception. + virtual void collect(int32_t doc); + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); + virtual bool acceptsDocsOutOfOrder(); + +protected: + /// Initialize a single static timer thread to be used by all TimeLimitedCollector instances. + static TimerThreadPtr TIMER_THREAD(); + + friend class TimerThread; +}; + } #endif diff --git a/include/Token.h b/include/Token.h index 85f52b78..abc50d12 100644 --- a/include/Token.h +++ b/include/Token.h @@ -10,348 +10,347 @@ #include "Attribute.h" #include "AttributeSource.h" -namespace Lucene -{ - /// A Token is an occurrence of a term from the text of a field. It consists of a term's text, the start and end - /// offset of the term in the text of the field and a type string. +namespace Lucene { + +/// A Token is an occurrence of a term from the text of a field. It consists of a term's text, the start and end +/// offset of the term in the text of the field and a type string. +/// +/// The start and end offsets permit applications to re-associate a token with its source text, eg., to display +/// highlighted query terms in a document browser, or to show matching text fragments in a +/// KWIC display, etc. +/// +/// The type is a string, assigned by a lexical analyzer (a.k.a. tokenizer), naming the lexical or syntactic class +/// that the token belongs to. For example an end of sentence marker token might be implemented with type "eos". +/// The default token type is "word". +/// +/// A Token can optionally have metadata (a.k.a. Payload) in the form of a variable length byte array. Use {@link +/// TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve the payloads +/// from the index. +/// +/// Tokenizers and TokenFilters should try to re-use a Token instance when possible for best performance, by implementing +/// the {@link TokenStream#incrementToken()} API. Failing that, to create a new Token you should first use one of +/// the constructors that starts with null text. To load the token from a char[] use +/// {@link #setTermBuffer(char[], int, int)}. To load from a String use {@link #setTermBuffer(String)} or {@link +/// #setTermBuffer(String, int, int)}. Alternatively you can get the Token's termBuffer by calling either {@link +/// #termBuffer()}, if you know that your text is shorter than the capacity of the termBuffer or {@link +/// #resizeTermBuffer(int)}, if there is any possibility that you may need to grow the buffer. Fill in the characters +/// of your term into this buffer, with {@link String#getChars(int, int, char[], int)} if loading from a string, +/// or with {@link System#arraycopy(Object, int, Object, int, int)}, and finally call {@link #setTermLength(int)} to +/// set the length of the term text. +/// +/// Typical Token reuse patterns: +/// +/// Copying text from a string (type is reset to {@link #DEFAULT_TYPE} if not specified): +///
      +/// return reusableToken->reinit(string, startOffset, endOffset[, type]);
      +/// 
      +/// +/// Copying some text from a string (type is reset to {@link #DEFAULT_TYPE} if not specified): +///
      +/// return reusableToken->reinit(string, 0, string.length(), startOffset, endOffset[, type]);
      +/// 
      +/// +/// Copying text from char[] buffer (type is reset to {@link #DEFAULT_TYPE} if not specified): +///
      +/// return reusableToken->reinit(buffer, 0, buffer.length, startOffset, endOffset[, type]);
      +/// 
      +/// +/// Copying some text from a char[] buffer (type is reset to {@link #DEFAULT_TYPE} if not specified): +///
      +/// return reusableToken->reinit(buffer, start, end - start, startOffset, endOffset[, type]);
      +/// 
      +/// +/// Copying from one one Token to another (type is reset to {@link #DEFAULT_TYPE} if not specified): +///
      +/// return reusableToken.reinit(source.termBuffer(), 0, source.termLength(), source.startOffset(), source.endOffset()[, source.type()]);
      +/// 
      +/// +/// A few things to note: +/// clear() initializes all of the fields to default values. This was changed in contrast to Lucene 2.4, but +/// should affect no one. +/// Because TokenStreams can be chained, one cannot assume that the Token's current type is correct. The startOffset +/// and endOffset represent the start and offset in the source text, so be careful in adjusting them. When caching a +/// reusable token, clone it. When injecting a cached token into a stream that can be reset, clone it again. +/// +/// @see Payload +class LPPAPI Token : public Attribute { +public: + /// Constructs a Token will null text. + Token(); + + /// Constructs a Token with null text and start and end offsets. + /// @param start start offset in the source text + /// @param end end offset in the source text + Token(int32_t start, int32_t end); + + /// Constructs a Token with null text and start and end offsets plus the Token type. + /// @param start start offset in the source text + /// @param end end offset in the source text + /// @param type the lexical type of this Token + Token(int32_t start, int32_t end, const String& type); + + /// Constructs a Token with null text and start and end offsets plus flags. + /// @param start start offset in the source text + /// @param end end offset in the source text + /// @param flags The bits to set for this token + Token(int32_t start, int32_t end, int32_t flags); + + /// Constructs a Token with the given term text, start and end offsets. The type defaults to "word." + /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. + /// @param text term text + /// @param start start offset in the source text + /// @param end end offset in the source text + Token(const String& text, int32_t start, int32_t end); + + /// Constructs a Token with the given term text, start and end offsets and type. + /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. + /// @param text term text + /// @param start start offset in the source text + /// @param end end offset in the source text + /// @param type the lexical type of this Token + Token(const String& text, int32_t start, int32_t end, const String& type); + + /// Constructs a Token with the given term text, start and end offsets and flags. + /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. + /// @param text term text + /// @param start start offset in the source text + /// @param end end offset in the source text + /// @param flags The bits to set for this token + Token(const String& text, int32_t start, int32_t end, int32_t flags); + + /// Constructs a Token with the given term buffer (offset and length), start and end offsets + Token(CharArray startTermBuffer, int32_t termBufferOffset, int32_t termBufferLength, int32_t start, int32_t end); + + virtual ~Token(); + + LUCENE_CLASS(Token); + +public: + static const String& DEFAULT_TYPE(); + +protected: + static const int32_t MIN_BUFFER_SIZE; + + CharArray _termBuffer; + int32_t _termLength; + int32_t _startOffset; + int32_t _endOffset; + String _type; + int32_t flags; + PayloadPtr payload; + int32_t positionIncrement; + +public: + /// Set the position increment. This determines the position of this token relative to the previous Token + /// in a {@link TokenStream}, used in phrase searching. /// - /// The start and end offsets permit applications to re-associate a token with its source text, eg., to display - /// highlighted query terms in a document browser, or to show matching text fragments in a - /// KWIC display, etc. + /// The default value is one. /// - /// The type is a string, assigned by a lexical analyzer (a.k.a. tokenizer), naming the lexical or syntactic class - /// that the token belongs to. For example an end of sentence marker token might be implemented with type "eos". - /// The default token type is "word". + /// Some common uses for this are: /// - /// A Token can optionally have metadata (a.k.a. Payload) in the form of a variable length byte array. Use {@link - /// TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} to retrieve the payloads - /// from the index. + /// Set it to zero to put multiple terms in the same position. This is useful if, eg., a word has multiple + /// stems. Searches for phrases including either stem will match. In this case, all but the first stem's + /// increment should be set to zero: the increment of the first instance should be one. Repeating a token + /// with an increment of zero can also be used to boost the scores of matches on that token. /// - /// Tokenizers and TokenFilters should try to re-use a Token instance when possible for best performance, by implementing - /// the {@link TokenStream#incrementToken()} API. Failing that, to create a new Token you should first use one of - /// the constructors that starts with null text. To load the token from a char[] use - /// {@link #setTermBuffer(char[], int, int)}. To load from a String use {@link #setTermBuffer(String)} or {@link - /// #setTermBuffer(String, int, int)}. Alternatively you can get the Token's termBuffer by calling either {@link - /// #termBuffer()}, if you know that your text is shorter than the capacity of the termBuffer or {@link - /// #resizeTermBuffer(int)}, if there is any possibility that you may need to grow the buffer. Fill in the characters - /// of your term into this buffer, with {@link String#getChars(int, int, char[], int)} if loading from a string, - /// or with {@link System#arraycopy(Object, int, Object, int, int)}, and finally call {@link #setTermLength(int)} to - /// set the length of the term text. + /// Set it to values greater than one to inhibit exact phrase matches. If, for example, one does not want + /// phrases to match across removed stop words, then one could build a stop word filter that removes stop + /// words and also sets the increment to the number of stop words removed before each non-stop word. Then + /// exact phrase queries will only match when the terms occur with no intervening stop words. /// - /// Typical Token reuse patterns: - /// - /// Copying text from a string (type is reset to {@link #DEFAULT_TYPE} if not specified): - ///
      -    /// return reusableToken->reinit(string, startOffset, endOffset[, type]);
      -    /// 
      - /// - /// Copying some text from a string (type is reset to {@link #DEFAULT_TYPE} if not specified): - ///
      -    /// return reusableToken->reinit(string, 0, string.length(), startOffset, endOffset[, type]);
      -    /// 
      - /// - /// Copying text from char[] buffer (type is reset to {@link #DEFAULT_TYPE} if not specified): - ///
      -    /// return reusableToken->reinit(buffer, 0, buffer.length, startOffset, endOffset[, type]);
      -    /// 
      - /// - /// Copying some text from a char[] buffer (type is reset to {@link #DEFAULT_TYPE} if not specified): - ///
      -    /// return reusableToken->reinit(buffer, start, end - start, startOffset, endOffset[, type]);
      -    /// 
      + /// @param positionIncrement the distance from the prior term + /// @see TermPositions + virtual void setPositionIncrement(int32_t positionIncrement); + + /// Returns the position increment of this Token. + /// @see #setPositionIncrement + virtual int32_t getPositionIncrement(); + + /// Returns the Token's term text. /// - /// Copying from one one Token to another (type is reset to {@link #DEFAULT_TYPE} if not specified): - ///
      -    /// return reusableToken.reinit(source.termBuffer(), 0, source.termLength(), source.startOffset(), source.endOffset()[, source.type()]);
      -    /// 
      + /// This method has a performance penalty because the text is stored internally in a char[]. If possible, + /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use + /// this method, which is nothing more than a convenience call to String(token->termBuffer(), token->termLength()) + virtual String term(); + + /// Copies the contents of buffer, starting at offset for length characters, into the termBuffer array. + /// @param buffer the buffer to copy + /// @param offset the index in the buffer of the first character to copy + /// @param length the number of characters to copy + virtual void setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length); + + /// Copies the contents of buffer into the termBuffer array. + /// @param buffer the buffer to copy + virtual void setTermBuffer(const String& buffer); + + /// Copies the contents of buffer, starting at offset and continuing for length characters, into the termBuffer array. + /// @param buffer the buffer to copy + /// @param offset the index in the buffer of the first character to copy + /// @param length the number of characters to copy + virtual void setTermBuffer(const String& buffer, int32_t offset, int32_t length); + + /// Returns the internal termBuffer character array which you can then directly alter. If the array is too + /// small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer be sure + /// to call {@link #setTermLength} to record the number of valid characters that were placed into the termBuffer. + virtual CharArray termBuffer(); + + /// Optimized implementation of termBuffer. + virtual wchar_t* termBufferArray(); + + /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next operation is + /// to change the contents of the term buffer use {@link #setTermBuffer(char[], int, int)}, {@link + /// #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the resize with the + /// setting of the termBuffer. + /// @param newSize minimum size of the new termBuffer + /// @return newly created termBuffer with length >= newSize + virtual CharArray resizeTermBuffer(int32_t newSize); + + /// Return number of valid characters (length of the term) in the termBuffer array. + virtual int32_t termLength(); + + /// Set number of valid characters (length of the term) in the termBuffer array. Use this to truncate the termBuffer + /// or to synchronize with external manipulation of the termBuffer. Note: to grow the size of the array, use {@link + /// #resizeTermBuffer(int)} first. + /// @param length the truncated length + virtual void setTermLength(int32_t length); + + /// Returns this Token's starting offset, the position of the first character corresponding to this token in the + /// source text. /// - /// A few things to note: - /// clear() initializes all of the fields to default values. This was changed in contrast to Lucene 2.4, but - /// should affect no one. - /// Because TokenStreams can be chained, one cannot assume that the Token's current type is correct. The startOffset - /// and endOffset represent the start and offset in the source text, so be careful in adjusting them. When caching a - /// reusable token, clone it. When injecting a cached token into a stream that can be reset, clone it again. + /// Note that the difference between endOffset() and startOffset() may not be equal to {@link #termLength}, as the + /// term text may have been altered by a stemmer or some other filter. + virtual int32_t startOffset(); + + /// Set the starting offset. + /// @see #startOffset() + virtual void setStartOffset(int32_t offset); + + /// Returns this Token's ending offset, one greater than the position of the last character corresponding to this + /// token in the source text. The length of the token in the source text is (endOffset - startOffset). + virtual int32_t endOffset(); + + /// Set the ending offset. + /// @see #endOffset() + virtual void setEndOffset(int32_t offset); + + /// Set the starting and ending offset. + /// @see #startOffset() and #endOffset() + virtual void setOffset(int32_t startOffset, int32_t endOffset); + + /// Returns this Token's lexical type. Defaults to "word". + virtual String type(); + + /// Set the lexical type. + /// @see #type() + virtual void setType(const String& type); + + /// Get the bitset for any bits that have been set. This is completely distinct from {@link #type()}, although + /// they do share similar purposes. The flags can be used to encode information about the token for use by other + /// {@link TokenFilter}s. /// - /// @see Payload - class LPPAPI Token : public Attribute - { - public: - /// Constructs a Token will null text. - Token(); - - /// Constructs a Token with null text and start and end offsets. - /// @param start start offset in the source text - /// @param end end offset in the source text - Token(int32_t start, int32_t end); - - /// Constructs a Token with null text and start and end offsets plus the Token type. - /// @param start start offset in the source text - /// @param end end offset in the source text - /// @param type the lexical type of this Token - Token(int32_t start, int32_t end, const String& type); - - /// Constructs a Token with null text and start and end offsets plus flags. - /// @param start start offset in the source text - /// @param end end offset in the source text - /// @param flags The bits to set for this token - Token(int32_t start, int32_t end, int32_t flags); - - /// Constructs a Token with the given term text, start and end offsets. The type defaults to "word." - /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. - /// @param text term text - /// @param start start offset in the source text - /// @param end end offset in the source text - Token(const String& text, int32_t start, int32_t end); - - /// Constructs a Token with the given term text, start and end offsets and type. - /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. - /// @param text term text - /// @param start start offset in the source text - /// @param end end offset in the source text - /// @param type the lexical type of this Token - Token(const String& text, int32_t start, int32_t end, const String& type); - - /// Constructs a Token with the given term text, start and end offsets and flags. - /// NOTE: for better indexing speed you should instead use the char[] termBuffer methods to set the term text. - /// @param text term text - /// @param start start offset in the source text - /// @param end end offset in the source text - /// @param flags The bits to set for this token - Token(const String& text, int32_t start, int32_t end, int32_t flags); - - /// Constructs a Token with the given term buffer (offset and length), start and end offsets - Token(CharArray startTermBuffer, int32_t termBufferOffset, int32_t termBufferLength, int32_t start, int32_t end); - - virtual ~Token(); - - LUCENE_CLASS(Token); - - public: - static const String& DEFAULT_TYPE(); - - protected: - static const int32_t MIN_BUFFER_SIZE; - - CharArray _termBuffer; - int32_t _termLength; - int32_t _startOffset; - int32_t _endOffset; - String _type; - int32_t flags; - PayloadPtr payload; - int32_t positionIncrement; - - public: - /// Set the position increment. This determines the position of this token relative to the previous Token - /// in a {@link TokenStream}, used in phrase searching. - /// - /// The default value is one. - /// - /// Some common uses for this are: - /// - /// Set it to zero to put multiple terms in the same position. This is useful if, eg., a word has multiple - /// stems. Searches for phrases including either stem will match. In this case, all but the first stem's - /// increment should be set to zero: the increment of the first instance should be one. Repeating a token - /// with an increment of zero can also be used to boost the scores of matches on that token. - /// - /// Set it to values greater than one to inhibit exact phrase matches. If, for example, one does not want - /// phrases to match across removed stop words, then one could build a stop word filter that removes stop - /// words and also sets the increment to the number of stop words removed before each non-stop word. Then - /// exact phrase queries will only match when the terms occur with no intervening stop words. - /// - /// @param positionIncrement the distance from the prior term - /// @see TermPositions - virtual void setPositionIncrement(int32_t positionIncrement); - - /// Returns the position increment of this Token. - /// @see #setPositionIncrement - virtual int32_t getPositionIncrement(); - - /// Returns the Token's term text. - /// - /// This method has a performance penalty because the text is stored internally in a char[]. If possible, - /// use {@link #termBuffer()} and {@link #termLength()} directly instead. If you really need a String, use - /// this method, which is nothing more than a convenience call to String(token->termBuffer(), token->termLength()) - virtual String term(); - - /// Copies the contents of buffer, starting at offset for length characters, into the termBuffer array. - /// @param buffer the buffer to copy - /// @param offset the index in the buffer of the first character to copy - /// @param length the number of characters to copy - virtual void setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length); - - /// Copies the contents of buffer into the termBuffer array. - /// @param buffer the buffer to copy - virtual void setTermBuffer(const String& buffer); - - /// Copies the contents of buffer, starting at offset and continuing for length characters, into the termBuffer array. - /// @param buffer the buffer to copy - /// @param offset the index in the buffer of the first character to copy - /// @param length the number of characters to copy - virtual void setTermBuffer(const String& buffer, int32_t offset, int32_t length); - - /// Returns the internal termBuffer character array which you can then directly alter. If the array is too - /// small for your token, use {@link #resizeTermBuffer(int)} to increase it. After altering the buffer be sure - /// to call {@link #setTermLength} to record the number of valid characters that were placed into the termBuffer. - virtual CharArray termBuffer(); - - /// Optimized implementation of termBuffer. - virtual wchar_t* termBufferArray(); - - /// Grows the termBuffer to at least size newSize, preserving the existing content. Note: If the next operation is - /// to change the contents of the term buffer use {@link #setTermBuffer(char[], int, int)}, {@link - /// #setTermBuffer(String)}, or {@link #setTermBuffer(String, int, int)} to optimally combine the resize with the - /// setting of the termBuffer. - /// @param newSize minimum size of the new termBuffer - /// @return newly created termBuffer with length >= newSize - virtual CharArray resizeTermBuffer(int32_t newSize); - - /// Return number of valid characters (length of the term) in the termBuffer array. - virtual int32_t termLength(); - - /// Set number of valid characters (length of the term) in the termBuffer array. Use this to truncate the termBuffer - /// or to synchronize with external manipulation of the termBuffer. Note: to grow the size of the array, use {@link - /// #resizeTermBuffer(int)} first. - /// @param length the truncated length - virtual void setTermLength(int32_t length); - - /// Returns this Token's starting offset, the position of the first character corresponding to this token in the - /// source text. - /// - /// Note that the difference between endOffset() and startOffset() may not be equal to {@link #termLength}, as the - /// term text may have been altered by a stemmer or some other filter. - virtual int32_t startOffset(); - - /// Set the starting offset. - /// @see #startOffset() - virtual void setStartOffset(int32_t offset); - - /// Returns this Token's ending offset, one greater than the position of the last character corresponding to this - /// token in the source text. The length of the token in the source text is (endOffset - startOffset). - virtual int32_t endOffset(); - - /// Set the ending offset. - /// @see #endOffset() - virtual void setEndOffset(int32_t offset); - - /// Set the starting and ending offset. - /// @see #startOffset() and #endOffset() - virtual void setOffset(int32_t startOffset, int32_t endOffset); - - /// Returns this Token's lexical type. Defaults to "word". - virtual String type(); - - /// Set the lexical type. - /// @see #type() - virtual void setType(const String& type); - - /// Get the bitset for any bits that have been set. This is completely distinct from {@link #type()}, although - /// they do share similar purposes. The flags can be used to encode information about the token for use by other - /// {@link TokenFilter}s. - /// - /// @return The bits - virtual int32_t getFlags(); - - /// @see #getFlags() - virtual void setFlags(int32_t flags); - - /// Returns this Token's payload. - virtual PayloadPtr getPayload(); - - /// Sets this Token's payload. - virtual void setPayload(const PayloadPtr& payload); - - virtual String toString(); - - /// Resets the term text, payload, flags, and positionIncrement, startOffset, endOffset and token type to default. - virtual void clear(); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - - /// Makes a clone, but replaces the term buffer and start/end offset in the process. This is more efficient than - /// doing a full clone (and then calling setTermBuffer) because it saves a wasted copy of the old termBuffer. - TokenPtr clone(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); - - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - - /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(char[], int, int)}, {@link #setStartOffset}, - /// {@link #setEndOffset}, {@link #setType} - /// @return this Token instance - TokenPtr reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType); - - /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(char[], int, int)}, {@link #setStartOffset}, - /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE - /// @return this Token instance - TokenPtr reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); - - /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, - /// {@link #setEndOffset}, {@link #setType} - /// @return this Token instance - TokenPtr reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset, const String& newType); + /// @return The bits + virtual int32_t getFlags(); + + /// @see #getFlags() + virtual void setFlags(int32_t flags); + + /// Returns this Token's payload. + virtual PayloadPtr getPayload(); + + /// Sets this Token's payload. + virtual void setPayload(const PayloadPtr& payload); + + virtual String toString(); + + /// Resets the term text, payload, flags, and positionIncrement, startOffset, endOffset and token type to default. + virtual void clear(); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Makes a clone, but replaces the term buffer and start/end offset in the process. This is more efficient than + /// doing a full clone (and then calling setTermBuffer) because it saves a wasted copy of the old termBuffer. + TokenPtr clone(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); + + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(char[], int, int)}, {@link #setStartOffset}, + /// {@link #setEndOffset}, {@link #setType} + /// @return this Token instance + TokenPtr reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType); + + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(char[], int, int)}, {@link #setStartOffset}, + /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE + /// @return this Token instance + TokenPtr reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); + + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, + /// {@link #setEndOffset}, {@link #setType} + /// @return this Token instance + TokenPtr reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset, const String& newType); + + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, + /// {@link #setEndOffset}, {@link #setType} + /// @return this Token instance + TokenPtr reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType); + + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, + /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE + /// @return this Token instance + TokenPtr reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset); - /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, - /// {@link #setEndOffset}, {@link #setType} - /// @return this Token instance - TokenPtr reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType); + /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String, int, int)}, {@link #setStartOffset}, + /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE + /// @return this Token instance + TokenPtr reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); - /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String)}, {@link #setStartOffset}, - /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE - /// @return this Token instance - TokenPtr reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset); - - /// Shorthand for calling {@link #clear}, {@link #setTermBuffer(String, int, int)}, {@link #setStartOffset}, - /// {@link #setEndOffset}, {@link #setType} on Token::DEFAULT_TYPE - /// @return this Token instance - TokenPtr reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset); + /// Copy the prototype token's fields into this one. Note: Payloads are shared. + void reinit(const TokenPtr& prototype); - /// Copy the prototype token's fields into this one. Note: Payloads are shared. - void reinit(const TokenPtr& prototype); + /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. + void reinit(const TokenPtr& prototype, const String& newTerm); - /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. - void reinit(const TokenPtr& prototype, const String& newTerm); + /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. + void reinit(const TokenPtr& prototype, CharArray newTermBuffer, int32_t offset, int32_t length); - /// Copy the prototype token's fields into this one, with a different term. Note: Payloads are shared. - void reinit(const TokenPtr& prototype, CharArray newTermBuffer, int32_t offset, int32_t length); + virtual void copyTo(const AttributePtr& target); - virtual void copyTo(const AttributePtr& target); + /// Convenience factory that returns Token as implementation for the basic attributes + static AttributeFactoryPtr TOKEN_ATTRIBUTE_FACTORY(); - /// Convenience factory that returns Token as implementation for the basic attributes - static AttributeFactoryPtr TOKEN_ATTRIBUTE_FACTORY(); +protected: + /// Construct Token and initialize values + void ConstructToken(int32_t start, int32_t end, const String& type, int32_t flags); - protected: - /// Construct Token and initialize values - void ConstructToken(int32_t start, int32_t end, const String& type, int32_t flags); + /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always used in + /// places that set the content. + /// @param newSize minimum size of the buffer + void growTermBuffer(int32_t newSize); - /// Allocates a buffer char[] of at least newSize, without preserving the existing content. Its always used in - /// places that set the content. - /// @param newSize minimum size of the buffer - void growTermBuffer(int32_t newSize); + void initTermBuffer(); - void initTermBuffer(); + /// Like clear() but doesn't clear termBuffer/text + void clearNoTermBuffer(); +}; - /// Like clear() but doesn't clear termBuffer/text - void clearNoTermBuffer(); - }; +/// Creates a TokenAttributeFactory returning {@link Token} as instance for the basic attributes and for all other +/// attributes calls the given delegate factory. +class LPPAPI TokenAttributeFactory : public AttributeFactory { +public: + TokenAttributeFactory(const AttributeFactoryPtr& delegate); + virtual ~TokenAttributeFactory(); - /// Creates a TokenAttributeFactory returning {@link Token} as instance for the basic attributes and for all other - /// attributes calls the given delegate factory. - class LPPAPI TokenAttributeFactory : public AttributeFactory - { - public: - TokenAttributeFactory(const AttributeFactoryPtr& delegate); - virtual ~TokenAttributeFactory(); + LUCENE_CLASS(TokenAttributeFactory); - LUCENE_CLASS(TokenAttributeFactory); +protected: + AttributeFactoryPtr delegate; - protected: - AttributeFactoryPtr delegate; +public: + virtual AttributePtr createAttributeInstance(const String& className); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; - public: - virtual AttributePtr createAttributeInstance(const String& className); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; } #endif diff --git a/include/TokenFilter.h b/include/TokenFilter.h index 805c52c1..513a4226 100644 --- a/include/TokenFilter.h +++ b/include/TokenFilter.h @@ -9,38 +9,38 @@ #include "TokenStream.h" -namespace Lucene -{ - /// A TokenFilter is a TokenStream whose input is another TokenStream. - /// - /// This is an abstract class; subclasses must override {@link #incrementToken()}. - /// @see TokenStream - class LPPAPI TokenFilter : public TokenStream - { - protected: - /// Construct a token stream filtering the given input. - TokenFilter(const TokenStreamPtr& input); - - public: - virtual ~TokenFilter(); - - LUCENE_CLASS(TokenFilter); - - protected: - /// The source of tokens for this filter. - TokenStreamPtr input; - - public: - /// Performs end-of-stream operations, if any, and calls then end() on the input TokenStream. - /// NOTE: Be sure to call TokenFilter::end() first when overriding this method. - virtual void end(); - - /// Close the input TokenStream. - virtual void close(); - - /// Reset the filter as well as the input TokenStream. - virtual void reset(); - }; +namespace Lucene { + +/// A TokenFilter is a TokenStream whose input is another TokenStream. +/// +/// This is an abstract class; subclasses must override {@link #incrementToken()}. +/// @see TokenStream +class LPPAPI TokenFilter : public TokenStream { +protected: + /// Construct a token stream filtering the given input. + TokenFilter(const TokenStreamPtr& input); + +public: + virtual ~TokenFilter(); + + LUCENE_CLASS(TokenFilter); + +protected: + /// The source of tokens for this filter. + TokenStreamPtr input; + +public: + /// Performs end-of-stream operations, if any, and calls then end() on the input TokenStream. + /// NOTE: Be sure to call TokenFilter::end() first when overriding this method. + virtual void end(); + + /// Close the input TokenStream. + virtual void close(); + + /// Reset the filter as well as the input TokenStream. + virtual void reset(); +}; + } #endif diff --git a/include/TokenStream.h b/include/TokenStream.h index e728dc93..86718746 100644 --- a/include/TokenStream.h +++ b/include/TokenStream.h @@ -9,95 +9,95 @@ #include "AttributeSource.h" -namespace Lucene -{ - /// A TokenStream enumerates the sequence of tokens, either from {@link Field}s of a {@link Document} or from - /// query text. - /// - /// This is an abstract class; concrete subclasses are: {@link Tokenizer}, a TokenStream whose input is a Reader; - /// and {@link TokenFilter}, a TokenStream whose input is another TokenStream. - /// - /// A new TokenStream API has been introduced with Lucene 2.9. This API has moved from being {@link Token}-based - /// to {@link Attribute}-based. While {@link Token} still exists in 2.9 as a convenience class, the preferred way - /// to store the information of a {@link Token} is to use {@link Attribute}s. +namespace Lucene { + +/// A TokenStream enumerates the sequence of tokens, either from {@link Field}s of a {@link Document} or from +/// query text. +/// +/// This is an abstract class; concrete subclasses are: {@link Tokenizer}, a TokenStream whose input is a Reader; +/// and {@link TokenFilter}, a TokenStream whose input is another TokenStream. +/// +/// A new TokenStream API has been introduced with Lucene 2.9. This API has moved from being {@link Token}-based +/// to {@link Attribute}-based. While {@link Token} still exists in 2.9 as a convenience class, the preferred way +/// to store the information of a {@link Token} is to use {@link Attribute}s. +/// +/// TokenStream now extends {@link AttributeSource}, which provides access to all of the token {@link Attribute}s +/// for the TokenStream. Note that only one instance per {@link Attribute} is created and reused for every +/// token. This approach reduces object creation and allows local caching of references to the {@link Attribute}s. +/// See {@link #incrementToken()} for further details. +/// +/// The workflow of the new TokenStream API is as follows: +/// - Instantiation of TokenStream/{@link TokenFilter}s which add/get attributes to/from the {@link AttributeSource}. +/// - The consumer calls {@link TokenStream#reset()}. +/// - The consumer retrieves attributes from the stream and stores local references to all attributes it wants to access. +/// - The consumer calls {@link #incrementToken()} until it returns false consuming the attributes after each call. +/// - The consumer calls {@link #end()} so that any end-of-stream operations can be performed. +/// - The consumer calls {@link #close()} to release any resource when finished using the TokenStream. +/// +/// To make sure that filters and consumers know which attributes are available, the attributes must be added during +/// instantiation. Filters and consumers are not required to check for availability of attributes in {@link +/// #incrementToken()}. +/// +/// Sometimes it is desirable to capture a current state of a TokenStream, eg., for buffering purposes (see {@link +/// CachingTokenFilter}, {@link TeeSinkTokenFilter}). For this use case {@link AttributeSource#captureState} and {@link +/// AttributeSource#restoreState} can be used. +class LPPAPI TokenStream : public AttributeSource { +protected: + /// A TokenStream using the default attribute factory. + TokenStream(); + + /// A TokenStream that uses the same attributes as the supplied one. + TokenStream(const AttributeSourcePtr& input); + + /// A TokenStream using the supplied AttributeFactory for creating new {@link Attribute} instances. + TokenStream(const AttributeFactoryPtr& factory); + +public: + virtual ~TokenStream(); + + LUCENE_CLASS(TokenStream); + +public: + /// Consumers (ie., {@link IndexWriter}) use this method to advance the stream to the next token. Implementing + /// classes must implement this method and update the appropriate {@link Attribute}s with the attributes of + /// the next token. /// - /// TokenStream now extends {@link AttributeSource}, which provides access to all of the token {@link Attribute}s - /// for the TokenStream. Note that only one instance per {@link Attribute} is created and reused for every - /// token. This approach reduces object creation and allows local caching of references to the {@link Attribute}s. - /// See {@link #incrementToken()} for further details. + /// The producer must make no assumptions about the attributes after the method has been returned: the caller may + /// arbitrarily change it. If the producer needs to preserve the state for subsequent calls, it can use {@link + /// #captureState} to create a copy of the current attribute state. /// - /// The workflow of the new TokenStream API is as follows: - /// - Instantiation of TokenStream/{@link TokenFilter}s which add/get attributes to/from the {@link AttributeSource}. - /// - The consumer calls {@link TokenStream#reset()}. - /// - The consumer retrieves attributes from the stream and stores local references to all attributes it wants to access. - /// - The consumer calls {@link #incrementToken()} until it returns false consuming the attributes after each call. - /// - The consumer calls {@link #end()} so that any end-of-stream operations can be performed. - /// - The consumer calls {@link #close()} to release any resource when finished using the TokenStream. + /// This method is called for every token of a document, so an efficient implementation is crucial for good + /// performance. To avoid calls to {@link #addAttribute(Class)} and {@link #getAttribute(Class)}, references to + /// all {@link Attribute}s that this stream uses should be retrieved during instantiation. /// - /// To make sure that filters and consumers know which attributes are available, the attributes must be added during + /// To ensure that filters and consumers know which attributes are available, the attributes must be added during /// instantiation. Filters and consumers are not required to check for availability of attributes in {@link /// #incrementToken()}. /// - /// Sometimes it is desirable to capture a current state of a TokenStream, eg., for buffering purposes (see {@link - /// CachingTokenFilter}, {@link TeeSinkTokenFilter}). For this use case {@link AttributeSource#captureState} and {@link - /// AttributeSource#restoreState} can be used. - class LPPAPI TokenStream : public AttributeSource - { - protected: - /// A TokenStream using the default attribute factory. - TokenStream(); - - /// A TokenStream that uses the same attributes as the supplied one. - TokenStream(const AttributeSourcePtr& input); - - /// A TokenStream using the supplied AttributeFactory for creating new {@link Attribute} instances. - TokenStream(const AttributeFactoryPtr& factory); + /// @return false for end of stream; true otherwise + virtual bool incrementToken() = 0; - public: - virtual ~TokenStream(); - - LUCENE_CLASS(TokenStream); - - public: - /// Consumers (ie., {@link IndexWriter}) use this method to advance the stream to the next token. Implementing - /// classes must implement this method and update the appropriate {@link Attribute}s with the attributes of - /// the next token. - /// - /// The producer must make no assumptions about the attributes after the method has been returned: the caller may - /// arbitrarily change it. If the producer needs to preserve the state for subsequent calls, it can use {@link - /// #captureState} to create a copy of the current attribute state. - /// - /// This method is called for every token of a document, so an efficient implementation is crucial for good - /// performance. To avoid calls to {@link #addAttribute(Class)} and {@link #getAttribute(Class)}, references to - /// all {@link Attribute}s that this stream uses should be retrieved during instantiation. - /// - /// To ensure that filters and consumers know which attributes are available, the attributes must be added during - /// instantiation. Filters and consumers are not required to check for availability of attributes in {@link - /// #incrementToken()}. - /// - /// @return false for end of stream; true otherwise - virtual bool incrementToken() = 0; + /// This method is called by the consumer after the last token has been consumed, after {@link #incrementToken()} + /// returned false (using the new TokenStream API). Streams implementing the old API should upgrade to use this + /// feature. + /// + /// This method can be used to perform any end-of-stream operations, such as setting the final offset of a stream. + /// The final offset of a stream might differ from the offset of the last token eg in case one or more whitespaces + /// followed after the last token, but a {@link WhitespaceTokenizer} was used. + virtual void end(); - /// This method is called by the consumer after the last token has been consumed, after {@link #incrementToken()} - /// returned false (using the new TokenStream API). Streams implementing the old API should upgrade to use this - /// feature. - /// - /// This method can be used to perform any end-of-stream operations, such as setting the final offset of a stream. - /// The final offset of a stream might differ from the offset of the last token eg in case one or more whitespaces - /// followed after the last token, but a {@link WhitespaceTokenizer} was used. - virtual void end(); + /// Resets this stream to the beginning. This is an optional operation, so subclasses may or may not implement + /// this method. {@link #reset()} is not needed for the standard indexing process. However, if the tokens of a + /// TokenStream are intended to be consumed more than once, it is necessary to implement {@link #reset()}. Note that + /// if your TokenStream caches tokens and feeds them back again after a reset, it is imperative that you clone the + /// tokens when you store them away (on the first pass) as well as when you return them (on future passes after + /// {@link #reset()}). + virtual void reset(); - /// Resets this stream to the beginning. This is an optional operation, so subclasses may or may not implement - /// this method. {@link #reset()} is not needed for the standard indexing process. However, if the tokens of a - /// TokenStream are intended to be consumed more than once, it is necessary to implement {@link #reset()}. Note that - /// if your TokenStream caches tokens and feeds them back again after a reset, it is imperative that you clone the - /// tokens when you store them away (on the first pass) as well as when you return them (on future passes after - /// {@link #reset()}). - virtual void reset(); + /// Releases resources associated with this stream. + virtual void close(); +}; - /// Releases resources associated with this stream. - virtual void close(); - }; } #endif diff --git a/include/Tokenizer.h b/include/Tokenizer.h index dfd9e4b8..8b25e407 100644 --- a/include/Tokenizer.h +++ b/include/Tokenizer.h @@ -9,62 +9,62 @@ #include "TokenStream.h" -namespace Lucene -{ - /// A Tokenizer is a TokenStream whose input is a Reader. - /// - /// This is an abstract class; subclasses must override {@link #incrementToken()} - /// - /// Note: Subclasses overriding {@link #incrementToken()} must call {@link AttributeSource#clearAttributes()} - /// before setting attributes. - class LPPAPI Tokenizer : public TokenStream - { - protected: - /// Construct a tokenizer with null input. - Tokenizer(); - - /// Construct a token stream processing the given input. - Tokenizer(const ReaderPtr& input); - - /// Construct a tokenizer with null input using the given AttributeFactory. - Tokenizer(const AttributeFactoryPtr& factory); - - /// Construct a token stream processing the given input using the given AttributeFactory. - Tokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - /// Construct a token stream processing the given input using the given AttributeSource. - Tokenizer(const AttributeSourcePtr& source); - - /// Construct a token stream processing the given input using the given AttributeSource. - Tokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - - public: - virtual ~Tokenizer(); - - LUCENE_CLASS(Tokenizer); - - protected: - /// The text source for this Tokenizer. - ReaderPtr input; - CharStreamPtr charStream; - - public: - /// By default, closes the input Reader. - virtual void close(); - - /// Return the corrected offset. If {@link #input} is a {@link CharStream} subclass this method calls - /// {@link CharStream#correctOffset}, else returns currentOff. - /// @param currentOff offset as seen in the output - /// @return corrected offset based on the input - /// @see CharStream#correctOffset - virtual int32_t correctOffset(int32_t currentOff); - - using TokenStream::reset; - - /// Reset the tokenizer to a new reader. Typically, an analyzer (in its reusableTokenStream method) will - /// use this to re-use a previously created tokenizer. - virtual void reset(const ReaderPtr& input); - }; +namespace Lucene { + +/// A Tokenizer is a TokenStream whose input is a Reader. +/// +/// This is an abstract class; subclasses must override {@link #incrementToken()} +/// +/// Note: Subclasses overriding {@link #incrementToken()} must call {@link AttributeSource#clearAttributes()} +/// before setting attributes. +class LPPAPI Tokenizer : public TokenStream { +protected: + /// Construct a tokenizer with null input. + Tokenizer(); + + /// Construct a token stream processing the given input. + Tokenizer(const ReaderPtr& input); + + /// Construct a tokenizer with null input using the given AttributeFactory. + Tokenizer(const AttributeFactoryPtr& factory); + + /// Construct a token stream processing the given input using the given AttributeFactory. + Tokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + /// Construct a token stream processing the given input using the given AttributeSource. + Tokenizer(const AttributeSourcePtr& source); + + /// Construct a token stream processing the given input using the given AttributeSource. + Tokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + +public: + virtual ~Tokenizer(); + + LUCENE_CLASS(Tokenizer); + +protected: + /// The text source for this Tokenizer. + ReaderPtr input; + CharStreamPtr charStream; + +public: + /// By default, closes the input Reader. + virtual void close(); + + /// Return the corrected offset. If {@link #input} is a {@link CharStream} subclass this method calls + /// {@link CharStream#correctOffset}, else returns currentOff. + /// @param currentOff offset as seen in the output + /// @return corrected offset based on the input + /// @see CharStream#correctOffset + virtual int32_t correctOffset(int32_t currentOff); + + using TokenStream::reset; + + /// Reset the tokenizer to a new reader. Typically, an analyzer (in its reusableTokenStream method) will + /// use this to re-use a previously created tokenizer. + virtual void reset(const ReaderPtr& input); +}; + } #endif diff --git a/include/TopDocs.h b/include/TopDocs.h index bca1e0fc..56735de2 100644 --- a/include/TopDocs.h +++ b/include/TopDocs.h @@ -9,41 +9,41 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Represents hits returned by {@link Searcher#search(QueryPtr, FilterPtr, int32_t)} and {@link - /// Searcher#search(QueryPtr, int32_t)}. - class LPPAPI TopDocs : public LuceneObject - { - public: - /// Constructs a TopDocs with a default maxScore = double.NaN. - TopDocs(int32_t totalHits, Collection scoreDocs); +namespace Lucene { - /// Constructs a TopDocs. - TopDocs(int32_t totalHits, Collection scoreDocs, double maxScore); +/// Represents hits returned by {@link Searcher#search(QueryPtr, FilterPtr, int32_t)} and {@link +/// Searcher#search(QueryPtr, int32_t)}. +class LPPAPI TopDocs : public LuceneObject { +public: + /// Constructs a TopDocs with a default maxScore = double.NaN. + TopDocs(int32_t totalHits, Collection scoreDocs); - virtual ~TopDocs(); + /// Constructs a TopDocs. + TopDocs(int32_t totalHits, Collection scoreDocs, double maxScore); - LUCENE_CLASS(TopDocs); + virtual ~TopDocs(); - public: - /// The total number of hits for the query. - int32_t totalHits; + LUCENE_CLASS(TopDocs); - /// The top hits for the query. - Collection scoreDocs; +public: + /// The total number of hits for the query. + int32_t totalHits; - /// Stores the maximum score value encountered, needed for normalizing. - double maxScore; + /// The top hits for the query. + Collection scoreDocs; - public: - /// Returns the maximum score value encountered. Note that in case scores are not tracked, - /// this returns NaN. - double getMaxScore(); + /// Stores the maximum score value encountered, needed for normalizing. + double maxScore; + +public: + /// Returns the maximum score value encountered. Note that in case scores are not tracked, + /// this returns NaN. + double getMaxScore(); + + /// Sets the maximum score value encountered. + void setMaxScore(double maxScore); +}; - /// Sets the maximum score value encountered. - void setMaxScore(double maxScore); - }; } #endif diff --git a/include/TopDocsCollector.h b/include/TopDocsCollector.h index b232d693..1d4389b7 100644 --- a/include/TopDocsCollector.h +++ b/include/TopDocsCollector.h @@ -10,74 +10,74 @@ #include "Collector.h" #include "PriorityQueue.h" -namespace Lucene -{ - /// A base class for all collectors that return a {@link TopDocs} output. This collector allows easy extension - /// by providing a single constructor which accepts a {@link PriorityQueue} as well as protected members for - /// that priority queue and a counter of the number of total hits. +namespace Lucene { + +/// A base class for all collectors that return a {@link TopDocs} output. This collector allows easy extension +/// by providing a single constructor which accepts a {@link PriorityQueue} as well as protected members for +/// that priority queue and a counter of the number of total hits. +/// +/// Extending classes can override {@link #topDocs(int32_t, int32_t)} and {@link #getTotalHits()} in order to +/// provide their own implementation. +class LPPAPI TopDocsCollector : public Collector { +public: + TopDocsCollector(const HitQueueBasePtr& pq); + virtual ~TopDocsCollector(); + + LUCENE_CLASS(TopDocsCollector); + +protected: + /// The priority queue which holds the top documents. Note that different implementations of PriorityQueue + /// give different meaning to 'top documents'. HitQueue for example aggregates the top scoring documents, + /// while other PQ implementations may hold documents sorted by other criteria. + HitQueueBasePtr pq; + + /// The total number of documents that the collector encountered. + int32_t totalHits; + +public: + /// The total number of documents that matched this query. + virtual int32_t getTotalHits(); + + /// Returns the top docs that were collected by this collector. + virtual TopDocsPtr topDocs(); + + /// Returns the documents in the range [start .. pq.size()) that were collected by this collector. Note that + /// if start >= pq.size(), an empty TopDocs is returned. + /// + /// This method is convenient to call if the application always asks for the last results, starting from the + /// last 'page'. /// - /// Extending classes can override {@link #topDocs(int32_t, int32_t)} and {@link #getTotalHits()} in order to - /// provide their own implementation. - class LPPAPI TopDocsCollector : public Collector - { - public: - TopDocsCollector(const HitQueueBasePtr& pq); - virtual ~TopDocsCollector(); - - LUCENE_CLASS(TopDocsCollector); - - protected: - /// The priority queue which holds the top documents. Note that different implementations of PriorityQueue - /// give different meaning to 'top documents'. HitQueue for example aggregates the top scoring documents, - /// while other PQ implementations may hold documents sorted by other criteria. - HitQueueBasePtr pq; - - /// The total number of documents that the collector encountered. - int32_t totalHits; - - public: - /// The total number of documents that matched this query. - virtual int32_t getTotalHits(); - - /// Returns the top docs that were collected by this collector. - virtual TopDocsPtr topDocs(); - - /// Returns the documents in the range [start .. pq.size()) that were collected by this collector. Note that - /// if start >= pq.size(), an empty TopDocs is returned. - /// - /// This method is convenient to call if the application always asks for the last results, starting from the - /// last 'page'. - /// - /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more - /// than once, passing each time a different start, you should call {@link #topDocs()} and work with the - /// returned {@link TopDocs} object, which will contain all the results this search execution collected. - virtual TopDocsPtr topDocs(int32_t start); - - /// Returns the documents in the rage [start .. start + howMany) that were collected by this collector. Note - /// that if start >= pq.size(), an empty TopDocs is returned, and if pq.size() - start < howMany, then only - /// the available documents in [start .. pq.size()) are returned. - /// - /// This method is useful to call in case pagination of search results is allowed by the search application, - /// as well as it attempts to optimize the memory used by allocating only as much as requested by howMany. - /// - /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more - /// than once, passing each time a different range, you should call {@link #topDocs()} and work with the - /// returned {@link TopDocs} object, which will contain all the results this search execution collected. - virtual TopDocsPtr topDocs(int32_t start, int32_t howMany); - - protected: - /// This is used in case topDocs() is called with illegal parameters, or there simply aren't (enough) results. - static TopDocsPtr EMPTY_TOPDOCS(); - - /// Populates the results array with the ScoreDoc instances. This can be overridden in case a different - /// ScoreDoc type should be returned. - virtual void populateResults(Collection results, int32_t howMany); - - /// Returns a {@link TopDocs} instance containing the given results. If results is null it means there are - /// no results to return, either because there were 0 calls to collect() or because the arguments to topDocs - /// were invalid. - virtual TopDocsPtr newTopDocs(Collection results, int32_t start); - }; + /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more + /// than once, passing each time a different start, you should call {@link #topDocs()} and work with the + /// returned {@link TopDocs} object, which will contain all the results this search execution collected. + virtual TopDocsPtr topDocs(int32_t start); + + /// Returns the documents in the rage [start .. start + howMany) that were collected by this collector. Note + /// that if start >= pq.size(), an empty TopDocs is returned, and if pq.size() - start < howMany, then only + /// the available documents in [start .. pq.size()) are returned. + /// + /// This method is useful to call in case pagination of search results is allowed by the search application, + /// as well as it attempts to optimize the memory used by allocating only as much as requested by howMany. + /// + /// NOTE: you cannot call this method more than once for each search execution. If you need to call it more + /// than once, passing each time a different range, you should call {@link #topDocs()} and work with the + /// returned {@link TopDocs} object, which will contain all the results this search execution collected. + virtual TopDocsPtr topDocs(int32_t start, int32_t howMany); + +protected: + /// This is used in case topDocs() is called with illegal parameters, or there simply aren't (enough) results. + static TopDocsPtr EMPTY_TOPDOCS(); + + /// Populates the results array with the ScoreDoc instances. This can be overridden in case a different + /// ScoreDoc type should be returned. + virtual void populateResults(Collection results, int32_t howMany); + + /// Returns a {@link TopDocs} instance containing the given results. If results is null it means there are + /// no results to return, either because there were 0 calls to collect() or because the arguments to topDocs + /// were invalid. + virtual TopDocsPtr newTopDocs(Collection results, int32_t start); +}; + } #endif diff --git a/include/TopFieldCollector.h b/include/TopFieldCollector.h index 19d6737d..115aa044 100644 --- a/include/TopFieldCollector.h +++ b/include/TopFieldCollector.h @@ -9,65 +9,65 @@ #include "TopDocsCollector.h" -namespace Lucene -{ - /// A {@link Collector} that sorts by {@link SortField} using {@link FieldComparator}s. +namespace Lucene { + +/// A {@link Collector} that sorts by {@link SortField} using {@link FieldComparator}s. +/// +/// See the {@link #create(SortPtr, int32_t, bool, bool, bool, bool)} method for instantiating a TopFieldCollector. +class LPPAPI TopFieldCollector : public TopDocsCollector { +public: + TopFieldCollector(const HitQueueBasePtr& pq, int32_t numHits, bool fillFields); + virtual ~TopFieldCollector(); + + LUCENE_CLASS(TopFieldCollector); + +protected: + bool fillFields; + + /// Stores the maximum score value encountered, needed for normalizing. If document scores are not tracked, + /// this value is initialized to NaN. + double maxScore; + + int32_t numHits; + FieldValueHitQueueEntryPtr bottom; + bool queueFull; + int32_t docBase; + +public: + /// Creates a new {@link TopFieldCollector} from the given arguments. + /// + /// NOTE: The instances returned by this method pre-allocate a full array of length numHits. /// - /// See the {@link #create(SortPtr, int32_t, bool, bool, bool, bool)} method for instantiating a TopFieldCollector. - class LPPAPI TopFieldCollector : public TopDocsCollector - { - public: - TopFieldCollector(const HitQueueBasePtr& pq, int32_t numHits, bool fillFields); - virtual ~TopFieldCollector(); - - LUCENE_CLASS(TopFieldCollector); - - protected: - bool fillFields; - - /// Stores the maximum score value encountered, needed for normalizing. If document scores are not tracked, - /// this value is initialized to NaN. - double maxScore; - - int32_t numHits; - FieldValueHitQueueEntryPtr bottom; - bool queueFull; - int32_t docBase; - - public: - /// Creates a new {@link TopFieldCollector} from the given arguments. - /// - /// NOTE: The instances returned by this method pre-allocate a full array of length numHits. - /// - /// @param sort The sort criteria (SortFields). - /// @param numHits The number of results to collect. - /// @param fillFields Specifies whether the actual field values should be returned on the results (FieldDoc). - /// @param trackDocScores Specifies whether document scores should be tracked and set on the results. Note - /// that if set to false, then the results' scores will be set to NaN. Setting this to true affects - /// performance, as it incurs the score computation on each competitive result. Therefore if document scores - /// are not required by the application, it is recommended to set it to false. - /// @param trackMaxScore Specifies whether the query's maxScore should be tracked and set on the resulting - /// {@link TopDocs}. Note that if set to false, {@link TopDocs#getMaxScore()} returns NaN. Setting this to - /// true affects performance as it incurs the score computation on each result. Also, setting this true - /// automatically sets trackDocScores to true as well. - /// @param docsScoredInOrder Specifies whether documents are scored in doc Id order or not by the given - /// {@link Scorer} in {@link #setScorer(ScorerPtr)}. - /// @return a {@link TopFieldCollector} instance which will sort the results by the sort criteria. - static TopFieldCollectorPtr create(const SortPtr& sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder); - - virtual void add(int32_t slot, int32_t doc, double score); - - virtual bool acceptsDocsOutOfOrder(); - - protected: - static const Collection EMPTY_SCOREDOCS(); - - /// Only the following callback methods need to be overridden since topDocs(int32_t, int32_t) calls them to - /// return the results. - virtual void populateResults(Collection results, int32_t howMany); - - virtual TopDocsPtr newTopDocs(Collection results, int32_t start); - }; + /// @param sort The sort criteria (SortFields). + /// @param numHits The number of results to collect. + /// @param fillFields Specifies whether the actual field values should be returned on the results (FieldDoc). + /// @param trackDocScores Specifies whether document scores should be tracked and set on the results. Note + /// that if set to false, then the results' scores will be set to NaN. Setting this to true affects + /// performance, as it incurs the score computation on each competitive result. Therefore if document scores + /// are not required by the application, it is recommended to set it to false. + /// @param trackMaxScore Specifies whether the query's maxScore should be tracked and set on the resulting + /// {@link TopDocs}. Note that if set to false, {@link TopDocs#getMaxScore()} returns NaN. Setting this to + /// true affects performance as it incurs the score computation on each result. Also, setting this true + /// automatically sets trackDocScores to true as well. + /// @param docsScoredInOrder Specifies whether documents are scored in doc Id order or not by the given + /// {@link Scorer} in {@link #setScorer(ScorerPtr)}. + /// @return a {@link TopFieldCollector} instance which will sort the results by the sort criteria. + static TopFieldCollectorPtr create(const SortPtr& sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder); + + virtual void add(int32_t slot, int32_t doc, double score); + + virtual bool acceptsDocsOutOfOrder(); + +protected: + static const Collection EMPTY_SCOREDOCS(); + + /// Only the following callback methods need to be overridden since topDocs(int32_t, int32_t) calls them to + /// return the results. + virtual void populateResults(Collection results, int32_t howMany); + + virtual TopDocsPtr newTopDocs(Collection results, int32_t start); +}; + } #endif diff --git a/include/TopFieldDocs.h b/include/TopFieldDocs.h index a06a46ae..96da0165 100644 --- a/include/TopFieldDocs.h +++ b/include/TopFieldDocs.h @@ -9,26 +9,26 @@ #include "TopDocs.h" -namespace Lucene -{ - /// Represents hits returned by {@link Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr)}. - class LPPAPI TopFieldDocs : public TopDocs - { - public: - /// @param totalHits Total number of hits for the query. - /// @param scoreDocs The top hits for the query. - /// @param fields The sort criteria used to find the top hits. - /// @param maxScore The maximum score encountered. - TopFieldDocs(int32_t totalHits, Collection scoreDocs, Collection fields, double maxScore); - - virtual ~TopFieldDocs(); - - LUCENE_CLASS(TopFieldDocs); - - public: - /// The fields which were used to sort results by. - Collection fields; - }; +namespace Lucene { + +/// Represents hits returned by {@link Searcher#search(QueryPtr, FilterPtr, int32_t, SortPtr)}. +class LPPAPI TopFieldDocs : public TopDocs { +public: + /// @param totalHits Total number of hits for the query. + /// @param scoreDocs The top hits for the query. + /// @param fields The sort criteria used to find the top hits. + /// @param maxScore The maximum score encountered. + TopFieldDocs(int32_t totalHits, Collection scoreDocs, Collection fields, double maxScore); + + virtual ~TopFieldDocs(); + + LUCENE_CLASS(TopFieldDocs); + +public: + /// The fields which were used to sort results by. + Collection fields; +}; + } #endif diff --git a/include/TopScoreDocCollector.h b/include/TopScoreDocCollector.h index 236e5278..0fb8a69c 100644 --- a/include/TopScoreDocCollector.h +++ b/include/TopScoreDocCollector.h @@ -9,41 +9,41 @@ #include "TopDocsCollector.h" -namespace Lucene -{ - /// A {@link Collector} implementation that collects the top-scoring hits, returning them as a {@link TopDocs}. - /// This is used by {@link IndexSearcher} to implement {@link TopDocs}-based search. Hits are sorted by score - /// descending and then (when the scores are tied) docID ascending. When you create an instance of this - /// collector you should know in advance whether documents are going to be collected in doc Id order or not. +namespace Lucene { + +/// A {@link Collector} implementation that collects the top-scoring hits, returning them as a {@link TopDocs}. +/// This is used by {@link IndexSearcher} to implement {@link TopDocs}-based search. Hits are sorted by score +/// descending and then (when the scores are tied) docID ascending. When you create an instance of this +/// collector you should know in advance whether documents are going to be collected in doc Id order or not. +/// +/// NOTE: The values Nan, NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. This collector will +/// not properly collect hits with such scores. +class LPPAPI TopScoreDocCollector : public TopDocsCollector { +public: + TopScoreDocCollector(int32_t numHits); + virtual ~TopScoreDocCollector(); + + LUCENE_CLASS(TopScoreDocCollector); + +INTERNAL: + ScoreDocPtr pqTop; + int32_t docBase; + ScorerWeakPtr _scorer; + +public: + /// Creates a new {@link TopScoreDocCollector} given the number of hits to collect and whether documents + /// are scored in order by the input {@link Scorer} to {@link #setScorer(ScorerPtr)}. /// - /// NOTE: The values Nan, NEGATIVE_INFINITY and POSITIVE_INFINITY are not valid scores. This collector will - /// not properly collect hits with such scores. - class LPPAPI TopScoreDocCollector : public TopDocsCollector - { - public: - TopScoreDocCollector(int32_t numHits); - virtual ~TopScoreDocCollector(); - - LUCENE_CLASS(TopScoreDocCollector); - - INTERNAL: - ScoreDocPtr pqTop; - int32_t docBase; - ScorerWeakPtr _scorer; - - public: - /// Creates a new {@link TopScoreDocCollector} given the number of hits to collect and whether documents - /// are scored in order by the input {@link Scorer} to {@link #setScorer(ScorerPtr)}. - /// - /// NOTE: The instances returned by this method pre-allocate a full array of length numHits. - static TopScoreDocCollectorPtr create(int32_t numHits, bool docsScoredInOrder); - - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setScorer(const ScorerPtr& scorer); - - protected: - virtual TopDocsPtr newTopDocs(Collection results, int32_t start); - }; + /// NOTE: The instances returned by this method pre-allocate a full array of length numHits. + static TopScoreDocCollectorPtr create(int32_t numHits, bool docsScoredInOrder); + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); + +protected: + virtual TopDocsPtr newTopDocs(Collection results, int32_t start); +}; + } #endif diff --git a/include/TypeAttribute.h b/include/TypeAttribute.h index 75a4a943..5eada91e 100644 --- a/include/TypeAttribute.h +++ b/include/TypeAttribute.h @@ -9,38 +9,38 @@ #include "Attribute.h" -namespace Lucene -{ - /// A Token's lexical type. The Default value is "word". - class LPPAPI TypeAttribute : public Attribute - { - public: - TypeAttribute(); - TypeAttribute(const String& type); - virtual ~TypeAttribute(); - - LUCENE_CLASS(TypeAttribute); - - protected: - String _type; - static const String& DEFAULT_TYPE(); - - public: - virtual String toString(); - - /// Returns this Token's lexical type. Defaults to "word". - String type(); - - /// Set the lexical type. - /// @see #type() - void setType(const String& type); - - virtual void clear(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual void copyTo(const AttributePtr& target); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// A Token's lexical type. The Default value is "word". +class LPPAPI TypeAttribute : public Attribute { +public: + TypeAttribute(); + TypeAttribute(const String& type); + virtual ~TypeAttribute(); + + LUCENE_CLASS(TypeAttribute); + +protected: + String _type; + static const String& DEFAULT_TYPE(); + +public: + virtual String toString(); + + /// Returns this Token's lexical type. Defaults to "word". + String type(); + + /// Set the lexical type. + /// @see #type() + void setType(const String& type); + + virtual void clear(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/include/UTF8Stream.h b/include/UTF8Stream.h index b7cf9349..866b85b8 100644 --- a/include/UTF8Stream.h +++ b/include/UTF8Stream.h @@ -9,140 +9,135 @@ #include "LuceneObject.h" -namespace Lucene -{ - class UTF8Base : public LuceneObject - { - public: - virtual ~UTF8Base(); - LUCENE_CLASS(UTF8Base); - - public: - static const uint16_t LEAD_SURROGATE_MIN; - static const uint16_t LEAD_SURROGATE_MAX; - static const uint16_t TRAIL_SURROGATE_MIN; - static const uint16_t TRAIL_SURROGATE_MAX; - static const uint16_t LEAD_OFFSET; - static const uint32_t SURROGATE_OFFSET; - static const uint32_t CODE_POINT_MAX; - - static const wchar_t UNICODE_REPLACEMENT_CHAR; - static const wchar_t UNICODE_TERMINATOR; - - protected: - virtual uint32_t readNext() = 0; - - uint8_t mask8(uint32_t b); - uint16_t mask16(uint32_t c); - bool isTrail(uint32_t b); - bool isSurrogate(uint32_t cp); - bool isLeadSurrogate(uint32_t cp); - bool isTrailSurrogate(uint32_t cp); - bool isValidCodePoint(uint32_t cp); - bool isOverlongSequence(uint32_t cp, int32_t length); - }; - - class UTF8Encoder : public UTF8Base - { - public: - UTF8Encoder(const wchar_t* unicodeBegin, const wchar_t* unicodeEnd); - virtual ~UTF8Encoder(); - - LUCENE_CLASS(UTF8Encoder); - - protected: - const wchar_t* unicodeBegin; - const wchar_t* unicodeEnd; - - public: - int32_t encode(uint8_t* utf8, int32_t length); - - int32_t utf16to8(uint8_t* utf8, int32_t length); - int32_t utf32to8(uint8_t* utf8, int32_t length); - - protected: - virtual uint32_t readNext(); - - uint8_t* appendChar(uint8_t* utf8, uint32_t cp); - }; - - class UTF8EncoderStream : public UTF8Encoder - { - public: - UTF8EncoderStream(const ReaderPtr& reader); - virtual ~UTF8EncoderStream(); - - LUCENE_CLASS(UTF8EncoderStream); - - protected: - ReaderPtr reader; - - protected: - virtual uint32_t readNext(); - }; - - class UTF8Decoder : public UTF8Base - { - public: - UTF8Decoder(const uint8_t* utf8Begin, const uint8_t* utf8End); - virtual ~UTF8Decoder(); - - LUCENE_CLASS(UTF8Decoder); - - protected: - const uint8_t* utf8Begin; - const uint8_t* utf8End; - - public: - int32_t decode(wchar_t* unicode, int32_t length); - - int32_t utf8to16(wchar_t* unicode, int32_t length); - int32_t utf8to32(wchar_t* unicode, int32_t length); - - protected: - virtual uint32_t readNext(); - - int32_t sequenceLength(uint32_t cp); - bool getSequence(uint32_t& cp, int32_t length); - bool isValidNext(uint32_t& cp); - }; - - class UTF8DecoderStream : public UTF8Decoder - { - public: - UTF8DecoderStream(const ReaderPtr& reader); - virtual ~UTF8DecoderStream(); +namespace Lucene { - LUCENE_CLASS(UTF8DecoderStream); +class UTF8Base : public LuceneObject { +public: + virtual ~UTF8Base(); + LUCENE_CLASS(UTF8Base); - protected: - ReaderPtr reader; +public: + static const uint16_t LEAD_SURROGATE_MIN; + static const uint16_t LEAD_SURROGATE_MAX; + static const uint16_t TRAIL_SURROGATE_MIN; + static const uint16_t TRAIL_SURROGATE_MAX; + static const uint16_t LEAD_OFFSET; + static const uint32_t SURROGATE_OFFSET; + static const uint32_t CODE_POINT_MAX; - protected: - virtual uint32_t readNext(); - }; + static const wchar_t UNICODE_REPLACEMENT_CHAR; + static const wchar_t UNICODE_TERMINATOR; - class UTF16Decoder : public UTF8Base - { - public: - UTF16Decoder(const uint16_t* utf16Begin, const uint16_t* utf16End); - virtual ~UTF16Decoder(); +protected: + virtual uint32_t readNext() = 0; - LUCENE_CLASS(UTF16Decoder); + uint8_t mask8(uint32_t b); + uint16_t mask16(uint32_t c); + bool isTrail(uint32_t b); + bool isSurrogate(uint32_t cp); + bool isLeadSurrogate(uint32_t cp); + bool isTrailSurrogate(uint32_t cp); + bool isValidCodePoint(uint32_t cp); + bool isOverlongSequence(uint32_t cp, int32_t length); +}; - protected: - const uint16_t* utf16Begin; - const uint16_t* utf16End; +class UTF8Encoder : public UTF8Base { +public: + UTF8Encoder(const wchar_t* unicodeBegin, const wchar_t* unicodeEnd); + virtual ~UTF8Encoder(); - public: - int32_t decode(wchar_t* unicode, int32_t length); + LUCENE_CLASS(UTF8Encoder); - int32_t utf16to16(wchar_t* unicode, int32_t length); - int32_t utf16to32(wchar_t* unicode, int32_t length); +protected: + const wchar_t* unicodeBegin; + const wchar_t* unicodeEnd; + +public: + int32_t encode(uint8_t* utf8, int32_t length); + + int32_t utf16to8(uint8_t* utf8, int32_t length); + int32_t utf32to8(uint8_t* utf8, int32_t length); + +protected: + virtual uint32_t readNext(); + + uint8_t* appendChar(uint8_t* utf8, uint32_t cp); +}; + +class UTF8EncoderStream : public UTF8Encoder { +public: + UTF8EncoderStream(const ReaderPtr& reader); + virtual ~UTF8EncoderStream(); + + LUCENE_CLASS(UTF8EncoderStream); + +protected: + ReaderPtr reader; + +protected: + virtual uint32_t readNext(); +}; + +class UTF8Decoder : public UTF8Base { +public: + UTF8Decoder(const uint8_t* utf8Begin, const uint8_t* utf8End); + virtual ~UTF8Decoder(); + + LUCENE_CLASS(UTF8Decoder); + +protected: + const uint8_t* utf8Begin; + const uint8_t* utf8End; + +public: + int32_t decode(wchar_t* unicode, int32_t length); + + int32_t utf8to16(wchar_t* unicode, int32_t length); + int32_t utf8to32(wchar_t* unicode, int32_t length); + +protected: + virtual uint32_t readNext(); + + int32_t sequenceLength(uint32_t cp); + bool getSequence(uint32_t& cp, int32_t length); + bool isValidNext(uint32_t& cp); +}; + +class UTF8DecoderStream : public UTF8Decoder { +public: + UTF8DecoderStream(const ReaderPtr& reader); + virtual ~UTF8DecoderStream(); + + LUCENE_CLASS(UTF8DecoderStream); + +protected: + ReaderPtr reader; + +protected: + virtual uint32_t readNext(); +}; + +class UTF16Decoder : public UTF8Base { +public: + UTF16Decoder(const uint16_t* utf16Begin, const uint16_t* utf16End); + virtual ~UTF16Decoder(); + + LUCENE_CLASS(UTF16Decoder); + +protected: + const uint16_t* utf16Begin; + const uint16_t* utf16End; + +public: + int32_t decode(wchar_t* unicode, int32_t length); + + int32_t utf16to16(wchar_t* unicode, int32_t length); + int32_t utf16to32(wchar_t* unicode, int32_t length); + +protected: + virtual uint32_t readNext(); +}; - protected: - virtual uint32_t readNext(); - }; } #endif diff --git a/include/UnicodeUtils.h b/include/UnicodeUtils.h index 7e6a40a7..768c949c 100644 --- a/include/UnicodeUtils.h +++ b/include/UnicodeUtils.h @@ -9,93 +9,88 @@ #include "LuceneObject.h" -namespace Lucene -{ - class LPPAPI UnicodeUtil - { - public: - virtual ~UnicodeUtil(); - - public: - /// Return true if supplied character is alpha-numeric. - static bool isAlnum(wchar_t c); - - /// Return true if supplied character is alphabetic. - static bool isAlpha(wchar_t c); - - /// Return true if supplied character is numeric. - static bool isDigit(wchar_t c); - - /// Return true if supplied character is a space. - static bool isSpace(wchar_t c); - - /// Return true if supplied character is uppercase. - static bool isUpper(wchar_t c); - - /// Return true if supplied character is lowercase. - static bool isLower(wchar_t c); - - /// Return true if supplied character is other type of letter. - static bool isOther(wchar_t c); - - /// Return true if supplied character is non-spacing. - static bool isNonSpacing(wchar_t c); - - /// Return uppercase representation of a given character. - static wchar_t toUpper(wchar_t c); - - /// Return lowercase representation of a given character. - static wchar_t toLower(wchar_t c); - }; - - /// Utility class that contains utf8 and unicode translations. - template - class TranslationResult : public LuceneObject - { - public: - TranslationResult() - { - result = Array::newInstance(10); - length = 0; - } +namespace Lucene { - public: - Array result; - int32_t length; - - public: - void setLength(int32_t length) - { - if (!result) - result = Array::newInstance((int32_t)(1.5 * (double)length)); - if (result.size() < length) - result.resize((int32_t)(1.5 * (double)length)); - this->length = length; - } +class LPPAPI UnicodeUtil { +public: + virtual ~UnicodeUtil(); - void copyText(const TranslationResult& other) - { - setLength(other.length); - MiscUtils::arrayCopy(other.result.get(), 0, result.get(), 0, other.length); - } +public: + /// Return true if supplied character is alpha-numeric. + static bool isAlnum(wchar_t c); + + /// Return true if supplied character is alphabetic. + static bool isAlpha(wchar_t c); + + /// Return true if supplied character is numeric. + static bool isDigit(wchar_t c); + + /// Return true if supplied character is a space. + static bool isSpace(wchar_t c); + + /// Return true if supplied character is uppercase. + static bool isUpper(wchar_t c); + + /// Return true if supplied character is lowercase. + static bool isLower(wchar_t c); + + /// Return true if supplied character is other type of letter. + static bool isOther(wchar_t c); + + /// Return true if supplied character is non-spacing. + static bool isNonSpacing(wchar_t c); - void copyText(boost::shared_ptr< TranslationResult > other) - { - copyText(*other); + /// Return uppercase representation of a given character. + static wchar_t toUpper(wchar_t c); + + /// Return lowercase representation of a given character. + static wchar_t toLower(wchar_t c); +}; + +/// Utility class that contains utf8 and unicode translations. +template +class TranslationResult : public LuceneObject { +public: + TranslationResult() { + result = Array::newInstance(10); + length = 0; + } + +public: + Array result; + int32_t length; + +public: + void setLength(int32_t length) { + if (!result) { + result = Array::newInstance((int32_t)(1.5 * (double)length)); + } + if (result.size() < length) { + result.resize((int32_t)(1.5 * (double)length)); } - }; - - class LPPAPI UTF8Result : public TranslationResult - { - public: - virtual ~UTF8Result(); - }; - - class LPPAPI UnicodeResult : public TranslationResult - { - public: - virtual ~UnicodeResult(); - }; + this->length = length; + } + + void copyText(const TranslationResult& other) { + setLength(other.length); + MiscUtils::arrayCopy(other.result.get(), 0, result.get(), 0, other.length); + } + + void copyText(boost::shared_ptr< TranslationResult > other) { + copyText(*other); + } +}; + +class LPPAPI UTF8Result : public TranslationResult { +public: + virtual ~UTF8Result(); +}; + +class LPPAPI UnicodeResult : public TranslationResult { +public: + virtual ~UnicodeResult(); +}; + } #endif diff --git a/include/ValueSource.h b/include/ValueSource.h index 9c04fd45..6337be8e 100644 --- a/include/ValueSource.h +++ b/include/ValueSource.h @@ -9,38 +9,38 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Source of values for basic function queries. - /// - /// At its default/simplest form, values - one per doc - are used as the score of that doc. - /// - /// Values are instantiated as {@link DocValues} for a particular reader. - /// ValueSource implementations differ in RAM requirements: it would always be a factor of the number of - /// documents, but for each document the number of bytes can be 1, 2, 4, or 8. - class LPPAPI ValueSource : public LuceneObject - { - public: - virtual ~ValueSource(); - LUCENE_CLASS(ValueSource); - - public: - /// Return the DocValues used by the function query. - /// @param reader The IndexReader used to read these values. If any caching is involved, that caching - /// would also be IndexReader based. - virtual DocValuesPtr getValues(const IndexReaderPtr& reader) = 0; - - /// Description of field, used in explain() - virtual String description() = 0; - - virtual String toString(); - - /// Needed for possible caching of query results - used by {@link ValueSourceQuery#equals(LuceneObjectPtr)}. - virtual bool equals(const LuceneObjectPtr& other) = 0; - - /// Needed for possible caching of query results - used by {@link ValueSourceQuery#hashCode()}. - virtual int32_t hashCode() = 0; - }; +namespace Lucene { + +/// Source of values for basic function queries. +/// +/// At its default/simplest form, values - one per doc - are used as the score of that doc. +/// +/// Values are instantiated as {@link DocValues} for a particular reader. +/// ValueSource implementations differ in RAM requirements: it would always be a factor of the number of +/// documents, but for each document the number of bytes can be 1, 2, 4, or 8. +class LPPAPI ValueSource : public LuceneObject { +public: + virtual ~ValueSource(); + LUCENE_CLASS(ValueSource); + +public: + /// Return the DocValues used by the function query. + /// @param reader The IndexReader used to read these values. If any caching is involved, that caching + /// would also be IndexReader based. + virtual DocValuesPtr getValues(const IndexReaderPtr& reader) = 0; + + /// Description of field, used in explain() + virtual String description() = 0; + + virtual String toString(); + + /// Needed for possible caching of query results - used by {@link ValueSourceQuery#equals(LuceneObjectPtr)}. + virtual bool equals(const LuceneObjectPtr& other) = 0; + + /// Needed for possible caching of query results - used by {@link ValueSourceQuery#hashCode()}. + virtual int32_t hashCode() = 0; +}; + } #endif diff --git a/include/ValueSourceQuery.h b/include/ValueSourceQuery.h index 966b0f9a..c72e11d8 100644 --- a/include/ValueSourceQuery.h +++ b/include/ValueSourceQuery.h @@ -9,41 +9,41 @@ #include "Query.h" -namespace Lucene -{ - /// A Query that sets the scores of document to the values obtained from a {@link ValueSource}. - /// - /// This query provides a score for each and every undeleted document in the index. - /// - /// The value source can be based on a (cached) value of an indexed field, but it can also be based on an - /// external source, eg. values read from an external database. - /// - /// Score is set as: Score(doc,query) = (query.getBoost() * query.getBoost()) * valueSource(doc). - class LPPAPI ValueSourceQuery : public Query - { - public: - /// Create a value source query - /// @param valSrc provides the values defines the function to be used for scoring - ValueSourceQuery(const ValueSourcePtr& valSrc); - - virtual ~ValueSourceQuery(); - - LUCENE_CLASS(ValueSourceQuery); - - public: - ValueSourcePtr valSrc; - - public: - using Query::toString; - - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - virtual void extractTerms(SetTerm terms); - virtual WeightPtr createWeight(const SearcherPtr& searcher); - virtual String toString(const String& field); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// A Query that sets the scores of document to the values obtained from a {@link ValueSource}. +/// +/// This query provides a score for each and every undeleted document in the index. +/// +/// The value source can be based on a (cached) value of an indexed field, but it can also be based on an +/// external source, eg. values read from an external database. +/// +/// Score is set as: Score(doc,query) = (query.getBoost() * query.getBoost()) * valueSource(doc). +class LPPAPI ValueSourceQuery : public Query { +public: + /// Create a value source query + /// @param valSrc provides the values defines the function to be used for scoring + ValueSourceQuery(const ValueSourcePtr& valSrc); + + virtual ~ValueSourceQuery(); + + LUCENE_CLASS(ValueSourceQuery); + +public: + ValueSourcePtr valSrc; + +public: + using Query::toString; + + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + virtual void extractTerms(SetTerm terms); + virtual WeightPtr createWeight(const SearcherPtr& searcher); + virtual String toString(const String& field); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/include/VariantUtils.h b/include/VariantUtils.h index bc5398b3..1e6c2436 100644 --- a/include/VariantUtils.h +++ b/include/VariantUtils.h @@ -11,92 +11,90 @@ #include "Lucene.h" #include "MiscUtils.h" -namespace Lucene -{ - class LPPAPI VariantUtils - { - public: - template - static TYPE get(const boost::any& var) - { - return var.type() == typeid(TYPE) ? boost::any_cast(var) : TYPE(); - } +namespace Lucene { - template - static TYPE get(VAR var) - { - return var.type() == typeid(TYPE) ? boost::get(var) : TYPE(); - } +class LPPAPI VariantUtils { +public: + template + static TYPE get(const boost::any& var) { + return var.type() == typeid(TYPE) ? boost::any_cast(var) : TYPE(); + } - template - static bool typeOf(VAR var) - { - return (var.type() == typeid(TYPE)); - } + template + static TYPE get(VAR var) { + return var.type() == typeid(TYPE) ? boost::get(var) : TYPE(); + } - static VariantNull null() - { - return VariantNull(); - } + template + static bool typeOf(VAR var) { + return (var.type() == typeid(TYPE)); + } - static bool isNull(const boost::any& var) - { - return var.empty(); - } + static VariantNull null() { + return VariantNull(); + } - template - static bool isNull(VAR var) - { - return typeOf(var); - } + static bool isNull(const boost::any& var) { + return var.empty(); + } - template - static int32_t hashCode(VAR var) - { - if (typeOf(var)) - return StringUtils::hashCode(get(var)); - if (typeOf(var)) - return get(var); - if (typeOf(var)) - return (int32_t)get(var); - if (typeOf(var)) - { - int64_t longBits = MiscUtils::doubleToLongBits(get(var)); - return (int32_t)(longBits ^ (longBits >> 32)); - } - if (typeOf< Collection >(var)) - return get< Collection >(var).hashCode(); - if (typeOf< Collection >(var)) - return get< Collection >(var).hashCode(); - if (typeOf< Collection >(var)) - return get< Collection >(var).hashCode(); - if (typeOf< Collection >(var)) - return get< Collection >(var).hashCode(); - if (typeOf< Collection >(var)) - return get< Collection >(var).hashCode(); - if (typeOf(var)) - return get(var)->hashCode(); - return 0; - } + template + static bool isNull(VAR var) { + return typeOf(var); + } - template - static bool equalsType(FIRST first, SECOND second) - { - return (first.type() == second.type()); + template + static int32_t hashCode(VAR var) { + if (typeOf(var)) { + return StringUtils::hashCode(get(var)); } - - template - static bool equals(FIRST first, SECOND second) - { - return first.type() == second.type() ? (first == second) : false; + if (typeOf(var)) { + return get(var); } - - template - static int32_t compareTo(VAR first, VAR second) - { - return first < second ? -1 : (first == second ? 0 : 1); + if (typeOf(var)) { + return (int32_t)get(var); + } + if (typeOf(var)) { + int64_t longBits = MiscUtils::doubleToLongBits(get(var)); + return (int32_t)(longBits ^ (longBits >> 32)); } - }; + if (typeOf< Collection >(var)) { + return get< Collection >(var).hashCode(); + } + if (typeOf< Collection >(var)) { + return get< Collection >(var).hashCode(); + } + if (typeOf< Collection >(var)) { + return get< Collection >(var).hashCode(); + } + if (typeOf< Collection >(var)) { + return get< Collection >(var).hashCode(); + } + if (typeOf< Collection >(var)) { + return get< Collection >(var).hashCode(); + } + if (typeOf(var)) { + return get(var)->hashCode(); + } + return 0; + } + + template + static bool equalsType(FIRST first, SECOND second) { + return (first.type() == second.type()); + } + + template + static bool equals(FIRST first, SECOND second) { + return first.type() == second.type() ? (first == second) : false; + } + + template + static int32_t compareTo(VAR first, VAR second) { + return first < second ? -1 : (first == second ? 0 : 1); + } +}; + } #endif diff --git a/include/Weight.h b/include/Weight.h index 29d33a18..ce733f7d 100644 --- a/include/Weight.h +++ b/include/Weight.h @@ -9,76 +9,76 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Calculate query weights and build query scorers. - /// - /// The purpose of {@link Weight} is to ensure searching does not modify a {@link Query}, so that a - /// {@link Query} instance can be reused. - /// {@link Searcher} dependent state of the query should reside in the {@link Weight}. - /// {@link IndexReader} dependent state should reside in the {@link Scorer}. - /// - /// Weight is used in the following way: - ///
        - ///
      1. A Weight is constructed by a top-level query, given a Searcher ({@link Query#createWeight(Searcher)}). - ///
      2. The {@link #sumOfSquaredWeights()} method is called on the Weight to compute the query normalization - /// factor {@link Similarity#queryNorm(float)} of the query clauses contained in the query. - ///
      3. The query normalization factor is passed to {@link #normalize(float)}. At this point the weighting is - /// complete. - ///
      4. A Scorer is constructed by {@link #scorer(IndexReaderPtr, bool, bool)}. - ///
      - class LPPAPI Weight : public LuceneObject - { - public: - virtual ~Weight(); - LUCENE_CLASS(Weight); +namespace Lucene { + +/// Calculate query weights and build query scorers. +/// +/// The purpose of {@link Weight} is to ensure searching does not modify a {@link Query}, so that a +/// {@link Query} instance can be reused. +/// {@link Searcher} dependent state of the query should reside in the {@link Weight}. +/// {@link IndexReader} dependent state should reside in the {@link Scorer}. +/// +/// Weight is used in the following way: +///
        +///
      1. A Weight is constructed by a top-level query, given a Searcher ({@link Query#createWeight(Searcher)}). +///
      2. The {@link #sumOfSquaredWeights()} method is called on the Weight to compute the query normalization +/// factor {@link Similarity#queryNorm(float)} of the query clauses contained in the query. +///
      3. The query normalization factor is passed to {@link #normalize(float)}. At this point the weighting is +/// complete. +///
      4. A Scorer is constructed by {@link #scorer(IndexReaderPtr, bool, bool)}. +///
      +class LPPAPI Weight : public LuceneObject { +public: + virtual ~Weight(); + LUCENE_CLASS(Weight); + +public: + /// An explanation of the score computation for the named document. + /// @param reader sub-reader containing the give doc + /// @param doc + /// @return an Explanation for the score + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc) = 0; - public: - /// An explanation of the score computation for the named document. - /// @param reader sub-reader containing the give doc - /// @param doc - /// @return an Explanation for the score - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc) = 0; + /// The query that this concerns. + virtual QueryPtr getQuery() = 0; - /// The query that this concerns. - virtual QueryPtr getQuery() = 0; + /// The weight for this query. + virtual double getValue() = 0; - /// The weight for this query. - virtual double getValue() = 0; + /// Assigns the query normalization factor to this. + virtual void normalize(double norm) = 0; - /// Assigns the query normalization factor to this. - virtual void normalize(double norm) = 0; + /// Returns a {@link Scorer} which scores documents in/out-of order according to scoreDocsInOrder. + /// + /// NOTE: even if scoreDocsInOrder is false, it is recommended to check whether the returned Scorer + /// indeed scores documents out of order (ie., call {@link #scoresDocsOutOfOrder()}), as some Scorer + /// implementations will always return documents in-order. + /// + /// NOTE: null can be returned if no documents will be scored by this query. + /// + /// @param reader The {@link IndexReader} for which to return the {@link Scorer}. + /// @param scoreDocsInOrder Specifies whether in-order scoring of documents is required. Note that if + /// set to false (i.e., out-of-order scoring is required), this method can return whatever scoring mode + /// it supports, as every in-order scorer is also an out-of-order one. However, an out-of-order scorer + /// may not support {@link Scorer#nextDoc()} and/or {@link Scorer#advance(int)}, therefore it is + /// recommended to request an in-order scorer if use of these methods is required. + /// @param topScorer If true, {@link Scorer#score(CollectorPtr)} will be called; if false, {@link + /// Scorer#nextDoc()} and/or {@link Scorer#advance(int)} will be called. + /// @return a {@link Scorer} which scores documents in/out-of order. + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) = 0; - /// Returns a {@link Scorer} which scores documents in/out-of order according to scoreDocsInOrder. - /// - /// NOTE: even if scoreDocsInOrder is false, it is recommended to check whether the returned Scorer - /// indeed scores documents out of order (ie., call {@link #scoresDocsOutOfOrder()}), as some Scorer - /// implementations will always return documents in-order. - /// - /// NOTE: null can be returned if no documents will be scored by this query. - /// - /// @param reader The {@link IndexReader} for which to return the {@link Scorer}. - /// @param scoreDocsInOrder Specifies whether in-order scoring of documents is required. Note that if - /// set to false (i.e., out-of-order scoring is required), this method can return whatever scoring mode - /// it supports, as every in-order scorer is also an out-of-order one. However, an out-of-order scorer - /// may not support {@link Scorer#nextDoc()} and/or {@link Scorer#advance(int)}, therefore it is - /// recommended to request an in-order scorer if use of these methods is required. - /// @param topScorer If true, {@link Scorer#score(CollectorPtr)} will be called; if false, {@link - /// Scorer#nextDoc()} and/or {@link Scorer#advance(int)} will be called. - /// @return a {@link Scorer} which scores documents in/out-of order. - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) = 0; + /// The sum of squared weights of contained query clauses. + virtual double sumOfSquaredWeights() = 0; - /// The sum of squared weights of contained query clauses. - virtual double sumOfSquaredWeights() = 0; + /// Returns true if this implementation scores docs only out of order. This method is used in conjunction + /// with {@link Collector}'s {@link Collector#acceptsDocsOutOfOrder() acceptsDocsOutOfOrder} and + /// {@link #scorer(IndexReaderPtr, bool, bool)} to create a matching {@link Scorer} instance for a given + /// {@link Collector}, or vice versa. + /// + /// NOTE: the default implementation returns false, ie. the Scorer scores documents in-order. + virtual bool scoresDocsOutOfOrder(); +}; - /// Returns true if this implementation scores docs only out of order. This method is used in conjunction - /// with {@link Collector}'s {@link Collector#acceptsDocsOutOfOrder() acceptsDocsOutOfOrder} and - /// {@link #scorer(IndexReaderPtr, bool, bool)} to create a matching {@link Scorer} instance for a given - /// {@link Collector}, or vice versa. - /// - /// NOTE: the default implementation returns false, ie. the Scorer scores documents in-order. - virtual bool scoresDocsOutOfOrder(); - }; } #endif diff --git a/include/WhitespaceAnalyzer.h b/include/WhitespaceAnalyzer.h index 5a3afd0f..fe92bee2 100644 --- a/include/WhitespaceAnalyzer.h +++ b/include/WhitespaceAnalyzer.h @@ -9,20 +9,20 @@ #include "Analyzer.h" -namespace Lucene -{ - /// An Analyzer that uses {@link WhitespaceTokenizer}. - class LPPAPI WhitespaceAnalyzer : public Analyzer - { - public: - virtual ~WhitespaceAnalyzer(); - - LUCENE_CLASS(WhitespaceAnalyzer); - - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +namespace Lucene { + +/// An Analyzer that uses {@link WhitespaceTokenizer}. +class LPPAPI WhitespaceAnalyzer : public Analyzer { +public: + virtual ~WhitespaceAnalyzer(); + + LUCENE_CLASS(WhitespaceAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + } #endif diff --git a/include/WhitespaceTokenizer.h b/include/WhitespaceTokenizer.h index 2368b3c6..241becff 100644 --- a/include/WhitespaceTokenizer.h +++ b/include/WhitespaceTokenizer.h @@ -9,30 +9,30 @@ #include "CharTokenizer.h" -namespace Lucene -{ - /// A WhitespaceTokenizer is a tokenizer that divides text at whitespace. Adjacent sequences of non-Whitespace - /// characters form tokens. - class LPPAPI WhitespaceTokenizer : public CharTokenizer - { - public: - /// Construct a new WhitespaceTokenizer. - WhitespaceTokenizer(const ReaderPtr& input); - - /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource}. - WhitespaceTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - - /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource.AttributeFactory}. - WhitespaceTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~WhitespaceTokenizer(); - - LUCENE_CLASS(WhitespaceTokenizer); - - public: - /// Collects only characters which do not satisfy {@link Character#isWhitespace(char)}. - virtual bool isTokenChar(wchar_t c); - }; +namespace Lucene { + +/// A WhitespaceTokenizer is a tokenizer that divides text at whitespace. Adjacent sequences of non-Whitespace +/// characters form tokens. +class LPPAPI WhitespaceTokenizer : public CharTokenizer { +public: + /// Construct a new WhitespaceTokenizer. + WhitespaceTokenizer(const ReaderPtr& input); + + /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource}. + WhitespaceTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + + /// Construct a new WhitespaceTokenizer using a given {@link AttributeSource.AttributeFactory}. + WhitespaceTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~WhitespaceTokenizer(); + + LUCENE_CLASS(WhitespaceTokenizer); + +public: + /// Collects only characters which do not satisfy {@link Character#isWhitespace(char)}. + virtual bool isTokenChar(wchar_t c); +}; + } #endif diff --git a/include/WildcardQuery.h b/include/WildcardQuery.h index dcf87333..05a9d181 100644 --- a/include/WildcardQuery.h +++ b/include/WildcardQuery.h @@ -9,46 +9,46 @@ #include "MultiTermQuery.h" -namespace Lucene -{ - /// Implements the wildcard search query. Supported wildcards are *, which matches any character sequence - /// (including the empty one), and ?, which matches any single character. Note this query can be slow, as - /// it needs to iterate over many terms. In order to prevent extremely slow WildcardQueries, a Wildcard - /// term should not start with one of the wildcards * or ?. - /// - /// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. - /// @see WildcardTermEnum - class LPPAPI WildcardQuery : public MultiTermQuery - { - public: - WildcardQuery(const TermPtr& term); - virtual ~WildcardQuery(); - - LUCENE_CLASS(WildcardQuery); - - protected: - bool termContainsWildcard; - bool termIsPrefix; - TermPtr term; - - public: - using MultiTermQuery::toString; - - /// Returns the pattern term. - TermPtr getTerm(); - - virtual QueryPtr rewrite(const IndexReaderPtr& reader); - - /// Prints a user-readable version of this query. - virtual String toString(const String& field); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - - protected: - virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); - }; +namespace Lucene { + +/// Implements the wildcard search query. Supported wildcards are *, which matches any character sequence +/// (including the empty one), and ?, which matches any single character. Note this query can be slow, as +/// it needs to iterate over many terms. In order to prevent extremely slow WildcardQueries, a Wildcard +/// term should not start with one of the wildcards * or ?. +/// +/// This query uses the {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} rewrite method. +/// @see WildcardTermEnum +class LPPAPI WildcardQuery : public MultiTermQuery { +public: + WildcardQuery(const TermPtr& term); + virtual ~WildcardQuery(); + + LUCENE_CLASS(WildcardQuery); + +protected: + bool termContainsWildcard; + bool termIsPrefix; + TermPtr term; + +public: + using MultiTermQuery::toString; + + /// Returns the pattern term. + TermPtr getTerm(); + + virtual QueryPtr rewrite(const IndexReaderPtr& reader); + + /// Prints a user-readable version of this query. + virtual String toString(const String& field); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + +protected: + virtual FilteredTermEnumPtr getEnum(const IndexReaderPtr& reader); +}; + } #endif diff --git a/include/WildcardTermEnum.h b/include/WildcardTermEnum.h index 9c7eaa8c..596e76d6 100644 --- a/include/WildcardTermEnum.h +++ b/include/WildcardTermEnum.h @@ -9,46 +9,46 @@ #include "FilteredTermEnum.h" -namespace Lucene -{ - /// Subclass of FilteredTermEnum for enumerating all terms that match the specified wildcard filter term. +namespace Lucene { + +/// Subclass of FilteredTermEnum for enumerating all terms that match the specified wildcard filter term. +/// +/// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than +/// all that precede it. +class LPPAPI WildcardTermEnum : public FilteredTermEnum { +public: + /// Creates a new WildcardTermEnum. /// - /// Term enumerations are always ordered by Term.compareTo(). Each term in the enumeration is greater than - /// all that precede it. - class LPPAPI WildcardTermEnum : public FilteredTermEnum - { - public: - /// Creates a new WildcardTermEnum. - /// - /// After calling the constructor the enumeration is already pointing to the first valid term if such - /// a term exists. - WildcardTermEnum(const IndexReaderPtr& reader, const TermPtr& term); - - virtual ~WildcardTermEnum(); - - LUCENE_CLASS(WildcardTermEnum); - - public: - static const wchar_t WILDCARD_STRING; - static const wchar_t WILDCARD_CHAR; - - TermPtr searchTerm; - String field; - String text; - String pre; - int32_t preLen; - bool _endEnum; - - public: - virtual double difference(); - - /// Determines if a word matches a wildcard pattern. - static bool wildcardEquals(const String& pattern, int32_t patternIdx, const String& string, int32_t stringIdx); - - protected: - virtual bool termCompare(const TermPtr& term); - virtual bool endEnum(); - }; + /// After calling the constructor the enumeration is already pointing to the first valid term if such + /// a term exists. + WildcardTermEnum(const IndexReaderPtr& reader, const TermPtr& term); + + virtual ~WildcardTermEnum(); + + LUCENE_CLASS(WildcardTermEnum); + +public: + static const wchar_t WILDCARD_STRING; + static const wchar_t WILDCARD_CHAR; + + TermPtr searchTerm; + String field; + String text; + String pre; + int32_t preLen; + bool _endEnum; + +public: + virtual double difference(); + + /// Determines if a word matches a wildcard pattern. + static bool wildcardEquals(const String& pattern, int32_t patternIdx, const String& string, int32_t stringIdx); + +protected: + virtual bool termCompare(const TermPtr& term); + virtual bool endEnum(); +}; + } #endif diff --git a/include/WordlistLoader.h b/include/WordlistLoader.h index 7fc788f4..e111e129 100644 --- a/include/WordlistLoader.h +++ b/include/WordlistLoader.h @@ -9,41 +9,41 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Loader for text files that represent a list of stopwords. - class LPPAPI WordlistLoader : public LuceneObject - { - public: - virtual ~WordlistLoader(); - - LUCENE_CLASS(WordlistLoader); - - public: - /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). - /// Every line of the file should contain only one word. The words need to be in lowercase if you make use of an - /// Analyzer which uses LowerCaseFilter (like StandardAnalyzer). - /// - /// @param wordfile File name containing the wordlist - /// @param comment The comment string to ignore - /// @return A set with the file's words - static HashSet getWordSet(const String& wordfile, const String& comment = EmptyString); - - /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). - /// Every line of the file should contain only one word. The words need to be in lowercase if you make use of an - /// Analyzer which uses LowerCaseFilter (like StandardAnalyzer). - /// - /// @param reader Reader containing the wordlist - /// @param comment The comment string to ignore - /// @return A set with the file's words - static HashSet getWordSet(const ReaderPtr& reader, const String& comment = EmptyString); - - /// Reads a stem dictionary. Each line contains: - ///
      word\tstem
      - /// (ie. two tab separated words) - /// @return stem dictionary that overrules the stemming algorithm - static MapStringString getStemDict(const String& wordstemfile); - }; +namespace Lucene { + +/// Loader for text files that represent a list of stopwords. +class LPPAPI WordlistLoader : public LuceneObject { +public: + virtual ~WordlistLoader(); + + LUCENE_CLASS(WordlistLoader); + +public: + /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). + /// Every line of the file should contain only one word. The words need to be in lowercase if you make use of an + /// Analyzer which uses LowerCaseFilter (like StandardAnalyzer). + /// + /// @param wordfile File name containing the wordlist + /// @param comment The comment string to ignore + /// @return A set with the file's words + static HashSet getWordSet(const String& wordfile, const String& comment = EmptyString); + + /// Loads a text file and adds every line as an entry to a HashSet (omitting leading and trailing whitespace). + /// Every line of the file should contain only one word. The words need to be in lowercase if you make use of an + /// Analyzer which uses LowerCaseFilter (like StandardAnalyzer). + /// + /// @param reader Reader containing the wordlist + /// @param comment The comment string to ignore + /// @return A set with the file's words + static HashSet getWordSet(const ReaderPtr& reader, const String& comment = EmptyString); + + /// Reads a stem dictionary. Each line contains: + ///
      word\tstem
      + /// (ie. two tab separated words) + /// @return stem dictionary that overrules the stemming algorithm + static MapStringString getStemDict(const String& wordstemfile); +}; + } #endif diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp index 5bc04484..be452bb8 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp @@ -13,127 +13,118 @@ #include "ArabicStemFilter.h" #include "StringUtils.h" -namespace Lucene -{ - /// Default Arabic stopwords in UTF-8 format. - /// - /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html - /// The stopword list is BSD-Licensed. - const uint8_t ArabicAnalyzer::DEFAULT_STOPWORD_FILE[] = - { - 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x86, - 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, - 0x0a, 0xd9, 0x88, 0xd9, 0x81, 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, - 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0x0a, 0xd8, 0xab, - 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0x0a, 0xd8, 0xa3, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, 0x0a, - 0xd8, 0xa8, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0x0a, 0xd8, - 0xa3, 0x0a, 0xd8, 0xa7, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, - 0x0a, 0xd8, 0xa3, 0xd9, 0x89, 0x0a, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd8, - 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, - 0xd8, 0xa5, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x86, 0x0a, 0xd9, 0x85, - 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa7, - 0x0a, 0xd9, 0x81, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd8, - 0xb9, 0x0a, 0xd8, 0xa7, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, - 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, 0xd8, - 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, - 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, - 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, - 0xa8, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, - 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, - 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, - 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, - 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, - 0xb0, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, - 0xa7, 0xd9, 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xa5, 0xd9, - 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa5, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, - 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, - 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, - 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, - 0xb6, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xb6, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, - 0x84, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x88, - 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x84, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x86, - 0x0a, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x87, 0xd9, 0x88, 0x0a, - 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, - 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x81, 0xd9, 0x87, - 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, - 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x84, 0xd9, - 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb0, 0xd9, 0x87, 0x0a, - 0xd9, 0x87, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd8, 0xb0, - 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x83, 0x0a, 0xd9, 0x83, - 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x8a, - 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, - 0xd9, 0x88, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd8, - 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, - 0xb6, 0x0a, 0xd9, 0x82, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xad, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, - 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, - 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb0, 0x0a, 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd8, 0xad, - 0xd9, 0x8a, 0xd8, 0xab, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, - 0xd9, 0x84, 0xd8, 0xa2, 0xd9, 0x86, 0x0a, 0xd8, 0xae, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, - 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd8, 0xad, - 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, - 0xd8, 0xaf, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x89, 0x0a, 0xd8, 0xac, - 0xd9, 0x85, 0xd9, 0x8a, 0xd8, 0xb9, 0x0a - }; +namespace Lucene { - ArabicAnalyzer::ArabicAnalyzer(LuceneVersion::Version matchVersion) - { - this->stoptable = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +/// Default Arabic stopwords in UTF-8 format. +/// +/// Generated from http://members.unine.ch/jacques.savoy/clef/index.html +/// The stopword list is BSD-Licensed. +const uint8_t ArabicAnalyzer::DEFAULT_STOPWORD_FILE[] = { + 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x86, + 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, + 0x0a, 0xd9, 0x88, 0xd9, 0x81, 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, + 0x0a, 0xd9, 0x81, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0x0a, 0xd8, 0xab, + 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0x0a, 0xd8, 0xa3, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, 0x0a, + 0xd8, 0xa8, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0x0a, 0xd8, + 0xa3, 0x0a, 0xd8, 0xa7, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, + 0x0a, 0xd8, 0xa3, 0xd9, 0x89, 0x0a, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd8, + 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, + 0xd8, 0xa5, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x86, 0x0a, 0xd9, 0x85, + 0xd8, 0xa7, 0x0a, 0xd9, 0x88, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xa7, + 0x0a, 0xd9, 0x81, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd8, + 0xb9, 0x0a, 0xd8, 0xa7, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, + 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, 0xd8, + 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, + 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, + 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, + 0xa8, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, + 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x81, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, + 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa3, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd8, 0xa5, 0xd9, 0x86, 0x0a, + 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xaa, 0xd9, + 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, + 0xb0, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, + 0xa7, 0xd9, 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xa5, 0xd9, + 0x84, 0xd9, 0x89, 0x0a, 0xd8, 0xa5, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, + 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb9, 0xd9, + 0x84, 0xd9, 0x8a, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, + 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa5, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, + 0xb6, 0xd8, 0xa7, 0x0a, 0xd8, 0xa3, 0xd9, 0x8a, 0xd8, 0xb6, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, + 0x84, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x88, + 0xd9, 0x84, 0xd9, 0x85, 0x0a, 0xd9, 0x84, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x86, + 0x0a, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x87, 0xd9, 0x88, 0x0a, + 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, + 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x89, 0x0a, 0xd9, 0x81, 0xd9, 0x87, + 0xd9, 0x8a, 0x0a, 0xd9, 0x81, 0xd9, 0x87, 0xd9, 0x88, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, + 0x0a, 0xd8, 0xa3, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x84, 0xd9, + 0x87, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb0, 0xd9, 0x87, 0x0a, + 0xd9, 0x87, 0xd8, 0xb0, 0xd8, 0xa7, 0x0a, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd8, 0xb0, + 0xd9, 0x84, 0xd9, 0x83, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x83, 0x0a, 0xd9, 0x83, + 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x8a, + 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd9, 0x83, 0xd9, 0x88, 0xd9, 0x86, 0x0a, + 0xd9, 0x88, 0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaa, 0x0a, 0xd9, 0x88, 0xd9, 0x83, 0xd8, + 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, + 0xb6, 0x0a, 0xd9, 0x82, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xad, 0xd9, 0x88, 0x0a, 0xd8, 0xa8, + 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, + 0xd9, 0x85, 0xd9, 0x86, 0xd8, 0xb0, 0x0a, 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd8, 0xad, + 0xd9, 0x8a, 0xd8, 0xab, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, + 0xd9, 0x84, 0xd8, 0xa2, 0xd9, 0x86, 0x0a, 0xd8, 0xae, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, + 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd8, 0xad, + 0xd8, 0xaa, 0xd9, 0x89, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, + 0xd8, 0xaf, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x89, 0x0a, 0xd8, 0xac, + 0xd9, 0x85, 0xd9, 0x8a, 0xd8, 0xb9, 0x0a +}; - ArabicAnalyzer::ArabicAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stoptable = stopwords; - this->matchVersion = matchVersion; - } +ArabicAnalyzer::ArabicAnalyzer(LuceneVersion::Version matchVersion) { + this->stoptable = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - ArabicAnalyzer::~ArabicAnalyzer() - { - } +ArabicAnalyzer::ArabicAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stoptable = stopwords; + this->matchVersion = matchVersion; +} + +ArabicAnalyzer::~ArabicAnalyzer() { +} - const HashSet ArabicAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - { - String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE)); - Collection words(StringUtils::split(stopWords, L"\n")); - stopSet = HashSet::newInstance(words.begin(), words.end()); - } - return stopSet; +const HashSet ArabicAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE)); + Collection words(StringUtils::split(stopWords, L"\n")); + stopSet = HashSet::newInstance(words.begin(), words.end()); } + return stopSet; +} + +TokenStreamPtr ArabicAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(reader); + result = newLucene(result); + // the order here is important: the stopword list is not normalized + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); + result = newLucene(result); + result = newLucene(result); + return result; +} - TokenStreamPtr ArabicAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(reader); - result = newLucene(result); +TokenStreamPtr ArabicAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + ArabicAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(reader); + streams->result = newLucene(streams->source); // the order here is important: the stopword list is not normalized - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); - result = newLucene(result); - result = newLucene(result); - return result; + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); + streams->result = newLucene(streams->result); + streams->result = newLucene(streams->result); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} - TokenStreamPtr ArabicAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - ArabicAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(reader); - streams->result = newLucene(streams->source); - // the order here is important: the stopword list is not normalized - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); - streams->result = newLucene(streams->result); - streams->result = newLucene(streams->result); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +ArabicAnalyzerSavedStreams::~ArabicAnalyzerSavedStreams() { +} - ArabicAnalyzerSavedStreams::~ArabicAnalyzerSavedStreams() - { - } } diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp index e71f203f..e5f1ded0 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicLetterTokenizer.cpp @@ -9,26 +9,22 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - ArabicLetterTokenizer::ArabicLetterTokenizer(const ReaderPtr& input) : LetterTokenizer(input) - { - } - - ArabicLetterTokenizer::ArabicLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : LetterTokenizer(source, input) - { - } - - ArabicLetterTokenizer::ArabicLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : LetterTokenizer(factory, input) - { - } - - ArabicLetterTokenizer::~ArabicLetterTokenizer() - { - } - - bool ArabicLetterTokenizer::isTokenChar(wchar_t c) - { - return LetterTokenizer::isTokenChar(c) || UnicodeUtil::isNonSpacing(c); - } +namespace Lucene { + +ArabicLetterTokenizer::ArabicLetterTokenizer(const ReaderPtr& input) : LetterTokenizer(input) { +} + +ArabicLetterTokenizer::ArabicLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : LetterTokenizer(source, input) { +} + +ArabicLetterTokenizer::ArabicLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : LetterTokenizer(factory, input) { +} + +ArabicLetterTokenizer::~ArabicLetterTokenizer() { +} + +bool ArabicLetterTokenizer::isTokenChar(wchar_t c) { + return LetterTokenizer::isTokenChar(c) || UnicodeUtil::isNonSpacing(c); +} + } diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp index 58012e06..6482dce4 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilter.cpp @@ -9,27 +9,24 @@ #include "ArabicNormalizer.h" #include "TermAttribute.h" -namespace Lucene -{ - ArabicNormalizationFilter::ArabicNormalizationFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - normalizer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - ArabicNormalizationFilter::~ArabicNormalizationFilter() - { - } +ArabicNormalizationFilter::ArabicNormalizationFilter(const TokenStreamPtr& input) : TokenFilter(input) { + normalizer = newLucene(); + termAtt = addAttribute(); +} - bool ArabicNormalizationFilter::incrementToken() - { - if (input->incrementToken()) - { - int32_t newlen = normalizer->normalize(termAtt->termBuffer().get(), termAtt->termLength()); - termAtt->setTermLength(newlen); - return true; - } - else - return false; +ArabicNormalizationFilter::~ArabicNormalizationFilter() { +} + +bool ArabicNormalizationFilter::incrementToken() { + if (input->incrementToken()) { + int32_t newlen = normalizer->normalize(termAtt->termBuffer().get(), termAtt->termLength()); + termAtt->setTermLength(newlen); + return true; + } else { + return false; } } + +} diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp index c0b8d805..f94ea2ae 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicNormalizer.cpp @@ -8,73 +8,70 @@ #include "ArabicNormalizer.h" #include "MiscUtils.h" -namespace Lucene -{ - const wchar_t ArabicNormalizer::ALEF = (wchar_t)0x0627; - const wchar_t ArabicNormalizer::ALEF_MADDA = (wchar_t)0x0622; - const wchar_t ArabicNormalizer::ALEF_HAMZA_ABOVE = (wchar_t)0x0623; - const wchar_t ArabicNormalizer::ALEF_HAMZA_BELOW = (wchar_t)0x0625; +namespace Lucene { - const wchar_t ArabicNormalizer::YEH = (wchar_t)0x064a; - const wchar_t ArabicNormalizer::DOTLESS_YEH = (wchar_t)0x0649; +const wchar_t ArabicNormalizer::ALEF = (wchar_t)0x0627; +const wchar_t ArabicNormalizer::ALEF_MADDA = (wchar_t)0x0622; +const wchar_t ArabicNormalizer::ALEF_HAMZA_ABOVE = (wchar_t)0x0623; +const wchar_t ArabicNormalizer::ALEF_HAMZA_BELOW = (wchar_t)0x0625; - const wchar_t ArabicNormalizer::TEH_MARBUTA = (wchar_t)0x0629; - const wchar_t ArabicNormalizer::HEH = (wchar_t)0x0647; +const wchar_t ArabicNormalizer::YEH = (wchar_t)0x064a; +const wchar_t ArabicNormalizer::DOTLESS_YEH = (wchar_t)0x0649; - const wchar_t ArabicNormalizer::TATWEEL = (wchar_t)0x0640; +const wchar_t ArabicNormalizer::TEH_MARBUTA = (wchar_t)0x0629; +const wchar_t ArabicNormalizer::HEH = (wchar_t)0x0647; - const wchar_t ArabicNormalizer::FATHATAN = (wchar_t)0x064b; - const wchar_t ArabicNormalizer::DAMMATAN = (wchar_t)0x064c; - const wchar_t ArabicNormalizer::KASRATAN = (wchar_t)0x064d; - const wchar_t ArabicNormalizer::FATHA = (wchar_t)0x064e; - const wchar_t ArabicNormalizer::DAMMA = (wchar_t)0x064f; - const wchar_t ArabicNormalizer::KASRA = (wchar_t)0x0650; - const wchar_t ArabicNormalizer::SHADDA = (wchar_t)0x0651; - const wchar_t ArabicNormalizer::SUKUN = (wchar_t)0x0652; +const wchar_t ArabicNormalizer::TATWEEL = (wchar_t)0x0640; - ArabicNormalizer::~ArabicNormalizer() - { - } +const wchar_t ArabicNormalizer::FATHATAN = (wchar_t)0x064b; +const wchar_t ArabicNormalizer::DAMMATAN = (wchar_t)0x064c; +const wchar_t ArabicNormalizer::KASRATAN = (wchar_t)0x064d; +const wchar_t ArabicNormalizer::FATHA = (wchar_t)0x064e; +const wchar_t ArabicNormalizer::DAMMA = (wchar_t)0x064f; +const wchar_t ArabicNormalizer::KASRA = (wchar_t)0x0650; +const wchar_t ArabicNormalizer::SHADDA = (wchar_t)0x0651; +const wchar_t ArabicNormalizer::SUKUN = (wchar_t)0x0652; + +ArabicNormalizer::~ArabicNormalizer() { +} - int32_t ArabicNormalizer::normalize(wchar_t* s, int32_t len) - { - for (int32_t i = 0; i < len; ++i) - { - switch (s[i]) - { - case ALEF_MADDA: - case ALEF_HAMZA_ABOVE: - case ALEF_HAMZA_BELOW: - s[i] = ALEF; - break; - case DOTLESS_YEH: - s[i] = YEH; - break; - case TEH_MARBUTA: - s[i] = HEH; - break; - case TATWEEL: - case KASRATAN: - case DAMMATAN: - case FATHATAN: - case FATHA: - case DAMMA: - case KASRA: - case SHADDA: - case SUKUN: - len = deleteChar(s, i--, len); - break; - default: - break; - } +int32_t ArabicNormalizer::normalize(wchar_t* s, int32_t len) { + for (int32_t i = 0; i < len; ++i) { + switch (s[i]) { + case ALEF_MADDA: + case ALEF_HAMZA_ABOVE: + case ALEF_HAMZA_BELOW: + s[i] = ALEF; + break; + case DOTLESS_YEH: + s[i] = YEH; + break; + case TEH_MARBUTA: + s[i] = HEH; + break; + case TATWEEL: + case KASRATAN: + case DAMMATAN: + case FATHATAN: + case FATHA: + case DAMMA: + case KASRA: + case SHADDA: + case SUKUN: + len = deleteChar(s, i--, len); + break; + default: + break; } - return len; } + return len; +} - int32_t ArabicNormalizer::deleteChar(wchar_t* s, int32_t pos, int32_t len) - { - if (pos < len) - MiscUtils::arrayCopy(s, pos + 1, s, pos, len - pos - 1); - return len - 1; +int32_t ArabicNormalizer::deleteChar(wchar_t* s, int32_t pos, int32_t len) { + if (pos < len) { + MiscUtils::arrayCopy(s, pos + 1, s, pos, len - pos - 1); } + return len - 1; +} + } diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp index fb383f97..241761b6 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicStemFilter.cpp @@ -9,27 +9,24 @@ #include "ArabicStemmer.h" #include "TermAttribute.h" -namespace Lucene -{ - ArabicStemFilter::ArabicStemFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - ArabicStemFilter::~ArabicStemFilter() - { - } +ArabicStemFilter::ArabicStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); +} - bool ArabicStemFilter::incrementToken() - { - if (input->incrementToken()) - { - int32_t newlen = stemmer->stem(termAtt->termBuffer().get(), termAtt->termLength()); - termAtt->setTermLength(newlen); - return true; - } - else - return false; +ArabicStemFilter::~ArabicStemFilter() { +} + +bool ArabicStemFilter::incrementToken() { + if (input->incrementToken()) { + int32_t newlen = stemmer->stem(termAtt->termBuffer().get(), termAtt->termLength()); + termAtt->setTermLength(newlen); + return true; + } else { + return false; } } + +} diff --git a/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp b/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp index 576d498b..20a4596a 100644 --- a/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp @@ -8,133 +8,122 @@ #include "ArabicStemmer.h" #include "MiscUtils.h" -namespace Lucene -{ - const wchar_t ArabicStemmer::ALEF = (wchar_t)0x0627; - const wchar_t ArabicStemmer::BEH = (wchar_t)0x0628; - const wchar_t ArabicStemmer::TEH_MARBUTA = (wchar_t)0x0629; - const wchar_t ArabicStemmer::TEH = (wchar_t)0x062a; - const wchar_t ArabicStemmer::FEH = (wchar_t)0x0641; - const wchar_t ArabicStemmer::KAF = (wchar_t)0x0643; - const wchar_t ArabicStemmer::LAM = (wchar_t)0x0644; - const wchar_t ArabicStemmer::NOON = (wchar_t)0x0646; - const wchar_t ArabicStemmer::HEH = (wchar_t)0x0647; - const wchar_t ArabicStemmer::WAW = (wchar_t)0x0648; - const wchar_t ArabicStemmer::YEH = (wchar_t)0x064a; +namespace Lucene { - ArabicStemmer::~ArabicStemmer() - { - } +const wchar_t ArabicStemmer::ALEF = (wchar_t)0x0627; +const wchar_t ArabicStemmer::BEH = (wchar_t)0x0628; +const wchar_t ArabicStemmer::TEH_MARBUTA = (wchar_t)0x0629; +const wchar_t ArabicStemmer::TEH = (wchar_t)0x062a; +const wchar_t ArabicStemmer::FEH = (wchar_t)0x0641; +const wchar_t ArabicStemmer::KAF = (wchar_t)0x0643; +const wchar_t ArabicStemmer::LAM = (wchar_t)0x0644; +const wchar_t ArabicStemmer::NOON = (wchar_t)0x0646; +const wchar_t ArabicStemmer::HEH = (wchar_t)0x0647; +const wchar_t ArabicStemmer::WAW = (wchar_t)0x0648; +const wchar_t ArabicStemmer::YEH = (wchar_t)0x064a; - const Collection ArabicStemmer::prefixes() - { - static Collection _prefixes; - if (!_prefixes) - { - _prefixes = Collection::newInstance(); - _prefixes.add(String(L"") + ALEF + LAM); - _prefixes.add(String(L"") + WAW + ALEF + LAM); - _prefixes.add(String(L"") + BEH + ALEF + LAM); - _prefixes.add(String(L"") + KAF + ALEF + LAM); - _prefixes.add(String(L"") + FEH + ALEF + LAM); - _prefixes.add(String(L"") + LAM + LAM); - _prefixes.add(String(L"") + WAW); - } - return _prefixes; - } +ArabicStemmer::~ArabicStemmer() { +} - const Collection ArabicStemmer::suffixes() - { - static Collection _suffixes; - if (!_suffixes) - { - _suffixes = Collection::newInstance(); - _suffixes.add(String(L"") + HEH + ALEF); - _suffixes.add(String(L"") + ALEF + NOON); - _suffixes.add(String(L"") + ALEF + TEH); - _suffixes.add(String(L"") + WAW + NOON); - _suffixes.add(String(L"") + YEH + NOON); - _suffixes.add(String(L"") + YEH + HEH); - _suffixes.add(String(L"") + YEH + TEH_MARBUTA); - _suffixes.add(String(L"") + HEH); - _suffixes.add(String(L"") + TEH_MARBUTA); - _suffixes.add(String(L"") + YEH); - } - return _suffixes; +const Collection ArabicStemmer::prefixes() { + static Collection _prefixes; + if (!_prefixes) { + _prefixes = Collection::newInstance(); + _prefixes.add(String(L"") + ALEF + LAM); + _prefixes.add(String(L"") + WAW + ALEF + LAM); + _prefixes.add(String(L"") + BEH + ALEF + LAM); + _prefixes.add(String(L"") + KAF + ALEF + LAM); + _prefixes.add(String(L"") + FEH + ALEF + LAM); + _prefixes.add(String(L"") + LAM + LAM); + _prefixes.add(String(L"") + WAW); } + return _prefixes; +} - int32_t ArabicStemmer::stem(wchar_t* s, int32_t len) - { - len = stemPrefix(s, len); - len = stemSuffix(s, len); - return len; +const Collection ArabicStemmer::suffixes() { + static Collection _suffixes; + if (!_suffixes) { + _suffixes = Collection::newInstance(); + _suffixes.add(String(L"") + HEH + ALEF); + _suffixes.add(String(L"") + ALEF + NOON); + _suffixes.add(String(L"") + ALEF + TEH); + _suffixes.add(String(L"") + WAW + NOON); + _suffixes.add(String(L"") + YEH + NOON); + _suffixes.add(String(L"") + YEH + HEH); + _suffixes.add(String(L"") + YEH + TEH_MARBUTA); + _suffixes.add(String(L"") + HEH); + _suffixes.add(String(L"") + TEH_MARBUTA); + _suffixes.add(String(L"") + YEH); } + return _suffixes; +} + +int32_t ArabicStemmer::stem(wchar_t* s, int32_t len) { + len = stemPrefix(s, len); + len = stemSuffix(s, len); + return len; +} - int32_t ArabicStemmer::stemPrefix(wchar_t* s, int32_t len) - { - Collection stemPrefixes(prefixes()); - for (int32_t i = 0; i < stemPrefixes.size(); ++i) - { - if (startsWith(s, len, stemPrefixes[i])) - return deleteChars(s, 0, len, (int32_t)stemPrefixes[i].length()); +int32_t ArabicStemmer::stemPrefix(wchar_t* s, int32_t len) { + Collection stemPrefixes(prefixes()); + for (int32_t i = 0; i < stemPrefixes.size(); ++i) { + if (startsWith(s, len, stemPrefixes[i])) { + return deleteChars(s, 0, len, (int32_t)stemPrefixes[i].length()); } - return len; } + return len; +} - int32_t ArabicStemmer::stemSuffix(wchar_t* s, int32_t len) - { - Collection stemSuffixes(suffixes()); - for (int32_t i = 0; i < stemSuffixes.size(); ++i) - { - if (endsWith(s, len, stemSuffixes[i])) - len = (int32_t)deleteChars(s, (int32_t)(len - stemSuffixes[i].length()), len, (int32_t)stemSuffixes[i].length()); +int32_t ArabicStemmer::stemSuffix(wchar_t* s, int32_t len) { + Collection stemSuffixes(suffixes()); + for (int32_t i = 0; i < stemSuffixes.size(); ++i) { + if (endsWith(s, len, stemSuffixes[i])) { + len = (int32_t)deleteChars(s, (int32_t)(len - stemSuffixes[i].length()), len, (int32_t)stemSuffixes[i].length()); } - return len; } + return len; +} - bool ArabicStemmer::startsWith(wchar_t* s, int32_t len, const String& prefix) - { - if (prefix.length() == 1 && len < 4) // wa- prefix requires at least 3 characters - return false; - else if (len < (int32_t)prefix.length() + 2) // other prefixes require only 2 - return false; - else - { - for (int32_t i = 0; i < (int32_t)prefix.length(); ++i) - { - if (s[i] != prefix[i]) - return false; +bool ArabicStemmer::startsWith(wchar_t* s, int32_t len, const String& prefix) { + if (prefix.length() == 1 && len < 4) { // wa- prefix requires at least 3 characters + return false; + } else if (len < (int32_t)prefix.length() + 2) { // other prefixes require only 2 + return false; + } else { + for (int32_t i = 0; i < (int32_t)prefix.length(); ++i) { + if (s[i] != prefix[i]) { + return false; } - return true; } + return true; } +} - bool ArabicStemmer::endsWith(wchar_t* s, int32_t len, const String& suffix) - { - if (len < (int32_t)suffix.length() + 2) // all suffixes require at least 2 characters after stemming - return false; - else - { - for (int32_t i = 0; i < (int32_t)suffix.length(); ++i) - { - if (s[len - suffix.length() + i] != suffix[i]) - return false; +bool ArabicStemmer::endsWith(wchar_t* s, int32_t len, const String& suffix) { + if (len < (int32_t)suffix.length() + 2) { // all suffixes require at least 2 characters after stemming + return false; + } else { + for (int32_t i = 0; i < (int32_t)suffix.length(); ++i) { + if (s[len - suffix.length() + i] != suffix[i]) { + return false; } - return true; } + return true; } +} - int32_t ArabicStemmer::deleteChars(wchar_t* s, int32_t pos, int32_t len, int32_t chars) - { - for (int32_t i = 0; i < chars; ++i) - len = deleteChar(s, pos, len); - return len; +int32_t ArabicStemmer::deleteChars(wchar_t* s, int32_t pos, int32_t len, int32_t chars) { + for (int32_t i = 0; i < chars; ++i) { + len = deleteChar(s, pos, len); } + return len; +} - int32_t ArabicStemmer::deleteChar(wchar_t* s, int32_t pos, int32_t len) - { - if (pos < len) - MiscUtils::arrayCopy(s, pos + 1, s, pos, len - pos - 1); - return len - 1; +int32_t ArabicStemmer::deleteChar(wchar_t* s, int32_t pos, int32_t len) { + if (pos < len) { + MiscUtils::arrayCopy(s, pos + 1, s, pos, len - pos - 1); } + return len - 1; +} + } diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp index 83715d1b..a5abeda6 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp @@ -12,99 +12,90 @@ #include "StopFilter.h" #include "BrazilianStemFilter.h" -namespace Lucene -{ - const wchar_t* BrazilianAnalyzer::_BRAZILIAN_STOP_WORDS[] = - { - L"a", L"ainda", L"alem", L"ambas", L"ambos", L"antes", - L"ao", L"aonde", L"aos", L"apos", L"aquele", L"aqueles", - L"as", L"assim", L"com", L"como", L"contra", L"contudo", - L"cuja", L"cujas", L"cujo", L"cujos", L"da", L"das", L"de", - L"dela", L"dele", L"deles", L"demais", L"depois", L"desde", - L"desta", L"deste", L"dispoe", L"dispoem", L"diversa", - L"diversas", L"diversos", L"do", L"dos", L"durante", L"e", - L"ela", L"elas", L"ele", L"eles", L"em", L"entao", L"entre", - L"essa", L"essas", L"esse", L"esses", L"esta", L"estas", - L"este", L"estes", L"ha", L"isso", L"isto", L"logo", L"mais", - L"mas", L"mediante", L"menos", L"mesma", L"mesmas", L"mesmo", - L"mesmos", L"na", L"nas", L"nao", L"nas", L"nem", L"nesse", - L"neste", L"nos", L"o", L"os", L"ou", L"outra", L"outras", - L"outro", L"outros", L"pelas", L"pelas", L"pelo", L"pelos", - L"perante", L"pois", L"por", L"porque", L"portanto", - L"proprio", L"propios", L"quais", L"qual", L"qualquer", - L"quando", L"quanto", L"que", L"quem", L"quer", L"se", L"seja", - L"sem", L"sendo", L"seu", L"seus", L"sob", L"sobre", L"sua", - L"suas", L"tal", L"tambem", L"teu", L"teus", L"toda", L"todas", - L"todo", L"todos", L"tua", L"tuas", L"tudo", L"um", L"uma", - L"umas", L"uns" - }; +namespace Lucene { - BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion) - { - this->stoptable = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +const wchar_t* BrazilianAnalyzer::_BRAZILIAN_STOP_WORDS[] = { + L"a", L"ainda", L"alem", L"ambas", L"ambos", L"antes", + L"ao", L"aonde", L"aos", L"apos", L"aquele", L"aqueles", + L"as", L"assim", L"com", L"como", L"contra", L"contudo", + L"cuja", L"cujas", L"cujo", L"cujos", L"da", L"das", L"de", + L"dela", L"dele", L"deles", L"demais", L"depois", L"desde", + L"desta", L"deste", L"dispoe", L"dispoem", L"diversa", + L"diversas", L"diversos", L"do", L"dos", L"durante", L"e", + L"ela", L"elas", L"ele", L"eles", L"em", L"entao", L"entre", + L"essa", L"essas", L"esse", L"esses", L"esta", L"estas", + L"este", L"estes", L"ha", L"isso", L"isto", L"logo", L"mais", + L"mas", L"mediante", L"menos", L"mesma", L"mesmas", L"mesmo", + L"mesmos", L"na", L"nas", L"nao", L"nas", L"nem", L"nesse", + L"neste", L"nos", L"o", L"os", L"ou", L"outra", L"outras", + L"outro", L"outros", L"pelas", L"pelas", L"pelo", L"pelos", + L"perante", L"pois", L"por", L"porque", L"portanto", + L"proprio", L"propios", L"quais", L"qual", L"qualquer", + L"quando", L"quanto", L"que", L"quem", L"quer", L"se", L"seja", + L"sem", L"sendo", L"seu", L"seus", L"sob", L"sobre", L"sua", + L"suas", L"tal", L"tambem", L"teu", L"teus", L"toda", L"todas", + L"todo", L"todos", L"tua", L"tuas", L"tudo", L"um", L"uma", + L"umas", L"uns" +}; - BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stoptable = stopwords; - this->matchVersion = matchVersion; - } +BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion) { + this->stoptable = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) - { - this->stoptable = stopwords; - this->excltable = exclusions; - this->matchVersion = matchVersion; - } +BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stoptable = stopwords; + this->matchVersion = matchVersion; +} - BrazilianAnalyzer::~BrazilianAnalyzer() - { - } +BrazilianAnalyzer::BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { + this->stoptable = stopwords; + this->excltable = exclusions; + this->matchVersion = matchVersion; +} - const HashSet BrazilianAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - stopSet = HashSet::newInstance(_BRAZILIAN_STOP_WORDS, _BRAZILIAN_STOP_WORDS + SIZEOF_ARRAY(_BRAZILIAN_STOP_WORDS)); - return stopSet; - } +BrazilianAnalyzer::~BrazilianAnalyzer() { +} - void BrazilianAnalyzer::setStemExclusionTable(HashSet exclusions) - { - excltable = exclusions; - setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +const HashSet BrazilianAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + stopSet = HashSet::newInstance(_BRAZILIAN_STOP_WORDS, _BRAZILIAN_STOP_WORDS + SIZEOF_ARRAY(_BRAZILIAN_STOP_WORDS)); } + return stopSet; +} - TokenStreamPtr BrazilianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(matchVersion, reader); - result = newLucene(result); - result = newLucene(result); - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); - result = newLucene(result, excltable); - return result; - } +void BrazilianAnalyzer::setStemExclusionTable(HashSet exclusions) { + excltable = exclusions; + setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +} - TokenStreamPtr BrazilianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - BrazilianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(matchVersion, reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(streams->result); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); - streams->result = newLucene(streams->result, excltable); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr BrazilianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(matchVersion, reader); + result = newLucene(result); + result = newLucene(result); + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); + result = newLucene(result, excltable); + return result; +} - BrazilianAnalyzerSavedStreams::~BrazilianAnalyzerSavedStreams() - { +TokenStreamPtr BrazilianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + BrazilianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(matchVersion, reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(streams->result); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); + streams->result = newLucene(streams->result, excltable); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +BrazilianAnalyzerSavedStreams::~BrazilianAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp index aaea50ea..d6ae451e 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianStemFilter.cpp @@ -9,41 +9,37 @@ #include "BrazilianStemmer.h" #include "TermAttribute.h" -namespace Lucene -{ - BrazilianStemFilter::BrazilianStemFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - BrazilianStemFilter::BrazilianStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - exclusions = exclusiontable; - } +BrazilianStemFilter::BrazilianStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); +} - BrazilianStemFilter::~BrazilianStemFilter() - { - } +BrazilianStemFilter::BrazilianStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); + exclusions = exclusiontable; +} - bool BrazilianStemFilter::incrementToken() - { - if (input->incrementToken()) - { - String term(termAtt->term()); - // Check the exclusion table. - if (!exclusions || !exclusions.contains(term)) - { - String s(stemmer->stem(term)); - // If not stemmed, don't waste the time adjusting the token. - if (!s.empty() && s != term) - termAtt->setTermBuffer(s); +BrazilianStemFilter::~BrazilianStemFilter() { +} + +bool BrazilianStemFilter::incrementToken() { + if (input->incrementToken()) { + String term(termAtt->term()); + // Check the exclusion table. + if (!exclusions || !exclusions.contains(term)) { + String s(stemmer->stem(term)); + // If not stemmed, don't waste the time adjusting the token. + if (!s.empty() && s != term) { + termAtt->setTermBuffer(s); } - return true; } - else - return false; + return true; + } else { + return false; } } + +} diff --git a/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp b/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp index 57daac78..e509ba21 100644 --- a/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/br/BrazilianStemmer.cpp @@ -10,1156 +10,984 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - BrazilianStemmer::~BrazilianStemmer() - { - } - - String BrazilianStemmer::stem(const String& term) - { - // creates CT - createCT(term); +namespace Lucene { - if (!isIndexable(CT)) - return L""; - if (!isStemmable(CT)) - return CT; +BrazilianStemmer::~BrazilianStemmer() { +} - R1 = getR1(CT); - R2 = getR1(R1); - RV = getRV(CT); - TERM = term + L";" + CT; +String BrazilianStemmer::stem(const String& term) { + // creates CT + createCT(term); - bool altered = step1(); - if (!altered) - altered = step2(); + if (!isIndexable(CT)) { + return L""; + } + if (!isStemmable(CT)) { + return CT; + } - if (altered) - step3(); - else - step4(); + R1 = getR1(CT); + R2 = getR1(R1); + RV = getRV(CT); + TERM = term + L";" + CT; - step5(); + bool altered = step1(); + if (!altered) { + altered = step2(); + } - return CT; + if (altered) { + step3(); + } else { + step4(); } - bool BrazilianStemmer::isStemmable(const String& term) - { - for (int32_t c = 0; c < (int32_t)term.length(); ++c) - { - // Discard terms that contain non-letter characters. - if (!UnicodeUtil::isAlpha(term[c])) - return false; + step5(); + + return CT; +} + +bool BrazilianStemmer::isStemmable(const String& term) { + for (int32_t c = 0; c < (int32_t)term.length(); ++c) { + // Discard terms that contain non-letter characters. + if (!UnicodeUtil::isAlpha(term[c])) { + return false; } - return true; } + return true; +} - bool BrazilianStemmer::isIndexable(const String& term) - { - return (term.length() < 30) && (term.length() > 2); - } +bool BrazilianStemmer::isIndexable(const String& term) { + return (term.length() < 30) && (term.length() > 2); +} - bool BrazilianStemmer::isVowel(wchar_t value) - { - return (value == L'a' || value == L'e' || value == L'i' || value == L'o' || value == L'u'); - } +bool BrazilianStemmer::isVowel(wchar_t value) { + return (value == L'a' || value == L'e' || value == L'i' || value == L'o' || value == L'u'); +} - String BrazilianStemmer::getR1(const String& value) - { - if (value.empty()) - return L""; +String BrazilianStemmer::getR1(const String& value) { + if (value.empty()) { + return L""; + } - // find 1st vowel - int32_t i = (int32_t)(value.length() - 1); - int32_t j = 0; - for (; j < i; ++j) - { - if (isVowel(value[j])) - break; + // find 1st vowel + int32_t i = (int32_t)(value.length() - 1); + int32_t j = 0; + for (; j < i; ++j) { + if (isVowel(value[j])) { + break; } + } - if (j >= i) - return L""; + if (j >= i) { + return L""; + } - // find 1st non-vowel - for (; j < i; ++j) - { - if (!isVowel(value[j])) - break; + // find 1st non-vowel + for (; j < i; ++j) { + if (!isVowel(value[j])) { + break; } + } - if (j >= i) - return L""; + if (j >= i) { + return L""; + } + + return value.substr(j + 1); +} - return value.substr(j + 1); +String BrazilianStemmer::getRV(const String& value) { + if (value.empty()) { + return L""; } - String BrazilianStemmer::getRV(const String& value) - { - if (value.empty()) - return L""; - - int32_t i = (int32_t)(value.length() - 1); - - // RV - IF the second letter is a consonant, RV is the region after the next following vowel - if (i > 0 && !isVowel(value[1])) - { - int32_t j = 2; - // find 1st vowel - for (; j < i; ++j) - { - if (isVowel(value[j])) - break; + int32_t i = (int32_t)(value.length() - 1); + + // RV - IF the second letter is a consonant, RV is the region after the next following vowel + if (i > 0 && !isVowel(value[1])) { + int32_t j = 2; + // find 1st vowel + for (; j < i; ++j) { + if (isVowel(value[j])) { + break; } + } - if (j < i) - return value.substr(j + 1); + if (j < i) { + return value.substr(j + 1); } + } - // RV - OR if the first two letters are vowels, RV is the region after the next consonant, - if (i > 1 && isVowel(value[0]) && isVowel(value[1])) - { - int32_t j = 2; - // find 1st consonant - for (; j < i; ++j) - { - if (!isVowel(value[j])) - break; + // RV - OR if the first two letters are vowels, RV is the region after the next consonant, + if (i > 1 && isVowel(value[0]) && isVowel(value[1])) { + int32_t j = 2; + // find 1st consonant + for (; j < i; ++j) { + if (!isVowel(value[j])) { + break; } - - if (j < i) - return value.substr(j + 1); } - // RV - AND otherwise (consonant-vowel case) RV is the region after the third letter. - if (i > 2) - return value.substr(3); + if (j < i) { + return value.substr(j + 1); + } + } - return L""; + // RV - AND otherwise (consonant-vowel case) RV is the region after the third letter. + if (i > 2) { + return value.substr(3); } - String BrazilianStemmer::changeTerm(const String& value) - { - if (value.empty()) - return L""; + return L""; +} - String lowerValue(StringUtils::toLower(value)); - String r; +String BrazilianStemmer::changeTerm(const String& value) { + if (value.empty()) { + return L""; + } - for (int32_t j = 0; j < (int32_t)value.length(); ++j) - { - if (value[j] == 0x00e1 || value[j] == 0x00e2 || value[j] == 0x00e3) - { - r += L"a"; - continue; - } - if (value[j] == 0x00e9 || value[j] == 0x00ea) - { - r += L"e"; - continue; - } - if (value[j] == 0x00ed) - { - r += L"i"; - continue; - } - if (value[j] == 0x00f3 || value[j] == 0x00f4 || value[j] == 0x00f5) - { - r += L"o"; - continue; - } - if (value[j] == 0x00fa || value[j] == 0x00fc) - { - r += L"u"; - continue; - } - if (value[j] == 0x00e7) - { - r += L"c"; - continue; - } - if (value[j] == 0x00f1) - { - r += L"n"; - continue; - } + String lowerValue(StringUtils::toLower(value)); + String r; - r += value[j]; + for (int32_t j = 0; j < (int32_t)value.length(); ++j) { + if (value[j] == 0x00e1 || value[j] == 0x00e2 || value[j] == 0x00e3) { + r += L"a"; + continue; + } + if (value[j] == 0x00e9 || value[j] == 0x00ea) { + r += L"e"; + continue; + } + if (value[j] == 0x00ed) { + r += L"i"; + continue; + } + if (value[j] == 0x00f3 || value[j] == 0x00f4 || value[j] == 0x00f5) { + r += L"o"; + continue; + } + if (value[j] == 0x00fa || value[j] == 0x00fc) { + r += L"u"; + continue; + } + if (value[j] == 0x00e7) { + r += L"c"; + continue; + } + if (value[j] == 0x00f1) { + r += L"n"; + continue; } - return r ; + r += value[j]; } - bool BrazilianStemmer::checkSuffix(const String& value, const String& suffix) - { - if (value.empty() || suffix.empty()) - return false; - if (suffix.length() > value.length()) - return false; - return (value.substr(value.length() - suffix.length()) == suffix); + return r ; +} + +bool BrazilianStemmer::checkSuffix(const String& value, const String& suffix) { + if (value.empty() || suffix.empty()) { + return false; } + if (suffix.length() > value.length()) { + return false; + } + return (value.substr(value.length() - suffix.length()) == suffix); +} - String BrazilianStemmer::replaceSuffix(const String& value, const String& toReplace, const String& changeTo) - { - if (value.empty() || toReplace.empty() || changeTo.empty()) - return value; +String BrazilianStemmer::replaceSuffix(const String& value, const String& toReplace, const String& changeTo) { + if (value.empty() || toReplace.empty() || changeTo.empty()) { + return value; + } - String vvalue = removeSuffix(value, toReplace); + String vvalue = removeSuffix(value, toReplace); - if (value == vvalue) - return value; - else - return vvalue + changeTo; + if (value == vvalue) { + return value; + } else { + return vvalue + changeTo; } +} - String BrazilianStemmer::removeSuffix(const String& value, const String& toRemove) - { - if (value.empty() || toRemove.empty() || !checkSuffix(value, toRemove)) - return value; - return value.substr(0, value.length() - toRemove.length()); +String BrazilianStemmer::removeSuffix(const String& value, const String& toRemove) { + if (value.empty() || toRemove.empty() || !checkSuffix(value, toRemove)) { + return value; } + return value.substr(0, value.length() - toRemove.length()); +} - bool BrazilianStemmer::suffixPreceded(const String& value, const String& suffix, const String& preceded) - { - if (value.empty() || suffix.empty() || preceded.empty() || !checkSuffix(value, suffix)) - return false; - return checkSuffix(removeSuffix(value, suffix), preceded); +bool BrazilianStemmer::suffixPreceded(const String& value, const String& suffix, const String& preceded) { + if (value.empty() || suffix.empty() || preceded.empty() || !checkSuffix(value, suffix)) { + return false; } + return checkSuffix(removeSuffix(value, suffix), preceded); +} - void BrazilianStemmer::createCT(const String& term) - { - CT = changeTerm(term); +void BrazilianStemmer::createCT(const String& term) { + CT = changeTerm(term); - if (CT.length() < 2) - return; + if (CT.length() < 2) { + return; + } - // if the first character is ... , remove it - if (CT[0] == L'"' || CT[0] == L'\'' || CT[0] == L'-' || CT[0] == L',' || - CT[0] == L';' || CT[0] == L'.' || CT[0] == L'?' || CT[0] == L'!') - CT = CT.substr(1); + // if the first character is ... , remove it + if (CT[0] == L'"' || CT[0] == L'\'' || CT[0] == L'-' || CT[0] == L',' || + CT[0] == L';' || CT[0] == L'.' || CT[0] == L'?' || CT[0] == L'!') { + CT = CT.substr(1); + } - if (CT.length() < 2) - return; + if (CT.length() < 2) { + return; + } - // if the last character is ... , remove it - if (CT[CT.length() - 1] == L'-' || CT[CT.length() - 1] == L',' || CT[CT.length() - 1] == L';' || + // if the last character is ... , remove it + if (CT[CT.length() - 1] == L'-' || CT[CT.length() - 1] == L',' || CT[CT.length() - 1] == L';' || CT[CT.length() - 1] == L'.' || CT[CT.length() - 1] == L'?' || CT[CT.length() - 1] == L'!' || - CT[CT.length() - 1] == L'\'' || CT[CT.length() - 1] == L'"') - CT = CT.substr(0, CT.length() - 1); + CT[CT.length() - 1] == L'\'' || CT[CT.length() - 1] == L'"') { + CT = CT.substr(0, CT.length() - 1); } +} - bool BrazilianStemmer::step1() - { - if (CT.empty()) - return false; +bool BrazilianStemmer::step1() { + if (CT.empty()) { + return false; + } + + // suffix length = 7 + if (checkSuffix(CT, L"uciones") && checkSuffix(R2, L"uciones")) { + CT = replaceSuffix(CT, L"uciones", L"u"); + return true; + } - // suffix length = 7 - if (checkSuffix(CT, L"uciones") && checkSuffix(R2, L"uciones")) - { - CT = replaceSuffix(CT, L"uciones", L"u"); + // suffix length = 6 + if (CT.length() >= 6) { + if (checkSuffix(CT, L"imentos") && checkSuffix(R2, L"imentos")) { + CT = removeSuffix(CT, L"imentos"); return true; } - - // suffix length = 6 - if (CT.length() >= 6) - { - if (checkSuffix(CT, L"imentos") && checkSuffix(R2, L"imentos")) - { - CT = removeSuffix(CT, L"imentos"); - return true; - } - if (checkSuffix(CT, L"amentos") && checkSuffix(R2, L"amentos")) - { - CT = removeSuffix(CT, L"amentos"); - return true; - } - if (checkSuffix(CT, L"adores") && checkSuffix(R2, L"adores")) - { - CT = removeSuffix(CT, L"adores"); - return true; - } - if (checkSuffix(CT, L"adoras") && checkSuffix(R2, L"adoras")) - { - CT = removeSuffix(CT, L"adoras"); - return true; - } - if (checkSuffix(CT, L"logias") && checkSuffix(R2, L"logias")) - { - replaceSuffix(CT, L"logias", L"log"); - return true; - } - if (checkSuffix(CT, L"encias") && checkSuffix(R2, L"encias")) - { - CT = replaceSuffix(CT, L"encias", L"ente"); - return true; - } - if (checkSuffix(CT, L"amente") && checkSuffix(R1, L"amente")) - { - CT = removeSuffix(CT, L"amente"); - return true; - } - if (checkSuffix(CT, L"idades") && checkSuffix(R2, L"idades")) - { - CT = removeSuffix(CT, L"idades"); - return true; - } + if (checkSuffix(CT, L"amentos") && checkSuffix(R2, L"amentos")) { + CT = removeSuffix(CT, L"amentos"); + return true; + } + if (checkSuffix(CT, L"adores") && checkSuffix(R2, L"adores")) { + CT = removeSuffix(CT, L"adores"); + return true; + } + if (checkSuffix(CT, L"adoras") && checkSuffix(R2, L"adoras")) { + CT = removeSuffix(CT, L"adoras"); + return true; + } + if (checkSuffix(CT, L"logias") && checkSuffix(R2, L"logias")) { + replaceSuffix(CT, L"logias", L"log"); + return true; + } + if (checkSuffix(CT, L"encias") && checkSuffix(R2, L"encias")) { + CT = replaceSuffix(CT, L"encias", L"ente"); + return true; + } + if (checkSuffix(CT, L"amente") && checkSuffix(R1, L"amente")) { + CT = removeSuffix(CT, L"amente"); + return true; + } + if (checkSuffix(CT, L"idades") && checkSuffix(R2, L"idades")) { + CT = removeSuffix(CT, L"idades"); + return true; } + } - // suffix length = 5 - if (CT.length() >= 5) - { - if (checkSuffix(CT, L"acoes") && checkSuffix(R2, L"acoes")) - { - CT = removeSuffix(CT, L"acoes"); - return true; - } - if (checkSuffix(CT, L"imento") && checkSuffix(R2, L"imento")) - { - CT = removeSuffix(CT, L"imento"); - return true; - } - if (checkSuffix(CT, L"amento") && checkSuffix(R2, L"amento")) - { - CT = removeSuffix(CT, L"amento"); - return true; - } - if (checkSuffix(CT, L"adora") && checkSuffix(R2, L"adora")) - { - CT = removeSuffix(CT, L"adora"); - return true; - } - if (checkSuffix(CT, L"ismos") && checkSuffix(R2, L"ismos")) - { - CT = removeSuffix(CT, L"ismos"); - return true; - } - if (checkSuffix(CT, L"istas") && checkSuffix(R2, L"istas")) - { - CT = removeSuffix(CT, L"istas"); - return true; - } - if (checkSuffix(CT, L"logia") && checkSuffix(R2, L"logia")) - { - CT = replaceSuffix(CT, L"logia", L"log"); - return true; - } - if (checkSuffix(CT, L"ucion") && checkSuffix(R2, L"ucion")) - { - CT = replaceSuffix(CT, L"ucion", L"u"); - return true; - } - if (checkSuffix(CT, L"encia") && checkSuffix(R2, L"encia")) - { - CT = replaceSuffix(CT, L"encia", L"ente"); - return true; - } - if (checkSuffix(CT, L"mente") && checkSuffix(R2, L"mente")) - { - CT = removeSuffix(CT, L"mente"); - return true; - } - if (checkSuffix(CT, L"idade") && checkSuffix(R2, L"idade")) - { - CT = removeSuffix(CT, L"idade"); - return true; - } + // suffix length = 5 + if (CT.length() >= 5) { + if (checkSuffix(CT, L"acoes") && checkSuffix(R2, L"acoes")) { + CT = removeSuffix(CT, L"acoes"); + return true; + } + if (checkSuffix(CT, L"imento") && checkSuffix(R2, L"imento")) { + CT = removeSuffix(CT, L"imento"); + return true; + } + if (checkSuffix(CT, L"amento") && checkSuffix(R2, L"amento")) { + CT = removeSuffix(CT, L"amento"); + return true; + } + if (checkSuffix(CT, L"adora") && checkSuffix(R2, L"adora")) { + CT = removeSuffix(CT, L"adora"); + return true; + } + if (checkSuffix(CT, L"ismos") && checkSuffix(R2, L"ismos")) { + CT = removeSuffix(CT, L"ismos"); + return true; } + if (checkSuffix(CT, L"istas") && checkSuffix(R2, L"istas")) { + CT = removeSuffix(CT, L"istas"); + return true; + } + if (checkSuffix(CT, L"logia") && checkSuffix(R2, L"logia")) { + CT = replaceSuffix(CT, L"logia", L"log"); + return true; + } + if (checkSuffix(CT, L"ucion") && checkSuffix(R2, L"ucion")) { + CT = replaceSuffix(CT, L"ucion", L"u"); + return true; + } + if (checkSuffix(CT, L"encia") && checkSuffix(R2, L"encia")) { + CT = replaceSuffix(CT, L"encia", L"ente"); + return true; + } + if (checkSuffix(CT, L"mente") && checkSuffix(R2, L"mente")) { + CT = removeSuffix(CT, L"mente"); + return true; + } + if (checkSuffix(CT, L"idade") && checkSuffix(R2, L"idade")) { + CT = removeSuffix(CT, L"idade"); + return true; + } + } - // suffix length = 4 - if (CT.length() >= 4) - { - if (checkSuffix(CT, L"acao") && checkSuffix(R2, L"acao")) - { - CT = removeSuffix(CT, L"acao"); - return true; - } - if (checkSuffix(CT, L"ezas") && checkSuffix(R2, L"ezas")) - { - CT = removeSuffix(CT, L"ezas"); - return true; - } - if (checkSuffix(CT, L"icos") && checkSuffix(R2, L"icos")) - { - CT = removeSuffix(CT, L"icos"); - return true; - } - if (checkSuffix(CT, L"icas") && checkSuffix(R2, L"icas")) - { - CT = removeSuffix(CT, L"icas"); - return true; - } - if (checkSuffix(CT, L"ismo") && checkSuffix(R2, L"ismo")) - { - CT = removeSuffix(CT, L"ismo"); - return true; - } - if (checkSuffix(CT, L"avel") && checkSuffix(R2, L"avel")) - { - CT = removeSuffix(CT, L"avel"); - return true; - } - if (checkSuffix(CT, L"ivel") && checkSuffix(R2, L"ivel")) - { - CT = removeSuffix(CT, L"ivel"); - return true; - } - if (checkSuffix(CT, L"ista") && checkSuffix(R2, L"ista")) - { - CT = removeSuffix(CT, L"ista"); - return true; - } - if (checkSuffix(CT, L"osos") && checkSuffix(R2, L"osos")) - { - CT = removeSuffix(CT, L"osos"); - return true; - } - if (checkSuffix(CT, L"osas") && checkSuffix(R2, L"osas")) - { - CT = removeSuffix(CT, L"osas"); - return true; - } - if (checkSuffix(CT, L"ador") && checkSuffix(R2, L"ador")) - { - CT = removeSuffix(CT, L"ador"); - return true; - } - if (checkSuffix(CT, L"ivas") && checkSuffix(R2, L"ivas")) - { - CT = removeSuffix(CT, L"ivas"); - return true; - } - if (checkSuffix(CT, L"ivos") && checkSuffix(R2, L"ivos")) - { - CT = removeSuffix(CT, L"ivos"); - return true; - } - if (checkSuffix(CT, L"iras") && checkSuffix(RV, L"iras") && suffixPreceded(CT, L"iras", L"e")) - { - CT = replaceSuffix(CT, L"iras", L"ir"); - return true; - } + // suffix length = 4 + if (CT.length() >= 4) { + if (checkSuffix(CT, L"acao") && checkSuffix(R2, L"acao")) { + CT = removeSuffix(CT, L"acao"); + return true; + } + if (checkSuffix(CT, L"ezas") && checkSuffix(R2, L"ezas")) { + CT = removeSuffix(CT, L"ezas"); + return true; + } + if (checkSuffix(CT, L"icos") && checkSuffix(R2, L"icos")) { + CT = removeSuffix(CT, L"icos"); + return true; } + if (checkSuffix(CT, L"icas") && checkSuffix(R2, L"icas")) { + CT = removeSuffix(CT, L"icas"); + return true; + } + if (checkSuffix(CT, L"ismo") && checkSuffix(R2, L"ismo")) { + CT = removeSuffix(CT, L"ismo"); + return true; + } + if (checkSuffix(CT, L"avel") && checkSuffix(R2, L"avel")) { + CT = removeSuffix(CT, L"avel"); + return true; + } + if (checkSuffix(CT, L"ivel") && checkSuffix(R2, L"ivel")) { + CT = removeSuffix(CT, L"ivel"); + return true; + } + if (checkSuffix(CT, L"ista") && checkSuffix(R2, L"ista")) { + CT = removeSuffix(CT, L"ista"); + return true; + } + if (checkSuffix(CT, L"osos") && checkSuffix(R2, L"osos")) { + CT = removeSuffix(CT, L"osos"); + return true; + } + if (checkSuffix(CT, L"osas") && checkSuffix(R2, L"osas")) { + CT = removeSuffix(CT, L"osas"); + return true; + } + if (checkSuffix(CT, L"ador") && checkSuffix(R2, L"ador")) { + CT = removeSuffix(CT, L"ador"); + return true; + } + if (checkSuffix(CT, L"ivas") && checkSuffix(R2, L"ivas")) { + CT = removeSuffix(CT, L"ivas"); + return true; + } + if (checkSuffix(CT, L"ivos") && checkSuffix(R2, L"ivos")) { + CT = removeSuffix(CT, L"ivos"); + return true; + } + if (checkSuffix(CT, L"iras") && checkSuffix(RV, L"iras") && suffixPreceded(CT, L"iras", L"e")) { + CT = replaceSuffix(CT, L"iras", L"ir"); + return true; + } + } - // suffix length = 3 - if (CT.length() >= 3) - { - if (checkSuffix(CT, L"eza") && checkSuffix(R2, L"eza")) - { - CT = removeSuffix(CT, L"eza"); - return true; - } - if (checkSuffix(CT, L"ico") && checkSuffix(R2, L"ico")) - { - CT = removeSuffix(CT, L"ico"); - return true; - } - if (checkSuffix(CT, L"ica") && checkSuffix(R2, L"ica")) - { - CT = removeSuffix(CT, L"ica"); - return true; - } - if (checkSuffix(CT, L"oso") && checkSuffix(R2, L"oso")) - { - CT = removeSuffix(CT, L"oso"); - return true; - } - if (checkSuffix(CT, L"osa") && checkSuffix(R2, L"osa")) - { - CT = removeSuffix(CT, L"osa"); - return true; - } - if (checkSuffix(CT, L"iva") && checkSuffix(R2, L"iva")) - { - CT = removeSuffix(CT, L"iva"); - return true; - } - if (checkSuffix(CT, L"ivo") && checkSuffix(R2, L"ivo")) - { - CT = removeSuffix(CT, L"ivo"); - return true; - } - if (checkSuffix(CT, L"ira") && checkSuffix(RV, L"ira") && suffixPreceded(CT, L"ira", L"e")) - { - CT = replaceSuffix(CT, L"ira", L"ir"); - return true; - } + // suffix length = 3 + if (CT.length() >= 3) { + if (checkSuffix(CT, L"eza") && checkSuffix(R2, L"eza")) { + CT = removeSuffix(CT, L"eza"); + return true; } + if (checkSuffix(CT, L"ico") && checkSuffix(R2, L"ico")) { + CT = removeSuffix(CT, L"ico"); + return true; + } + if (checkSuffix(CT, L"ica") && checkSuffix(R2, L"ica")) { + CT = removeSuffix(CT, L"ica"); + return true; + } + if (checkSuffix(CT, L"oso") && checkSuffix(R2, L"oso")) { + CT = removeSuffix(CT, L"oso"); + return true; + } + if (checkSuffix(CT, L"osa") && checkSuffix(R2, L"osa")) { + CT = removeSuffix(CT, L"osa"); + return true; + } + if (checkSuffix(CT, L"iva") && checkSuffix(R2, L"iva")) { + CT = removeSuffix(CT, L"iva"); + return true; + } + if (checkSuffix(CT, L"ivo") && checkSuffix(R2, L"ivo")) { + CT = removeSuffix(CT, L"ivo"); + return true; + } + if (checkSuffix(CT, L"ira") && checkSuffix(RV, L"ira") && suffixPreceded(CT, L"ira", L"e")) { + CT = replaceSuffix(CT, L"ira", L"ir"); + return true; + } + } + + // no ending was removed by step1 + return false; +} - // no ending was removed by step1 +bool BrazilianStemmer::step2() { + if (RV.empty()) { return false; } - bool BrazilianStemmer::step2() - { - if (RV.empty()) - return false; - - // suffix lenght = 7 - if (RV.length() >= 7) - { - if (checkSuffix(RV, L"issemos")) - { - CT = removeSuffix(CT, L"issemos"); - return true; - } - if (checkSuffix(RV, L"essemos")) - { - CT = removeSuffix(CT, L"essemos"); - return true; - } - if (checkSuffix(RV, L"assemos")) - { - CT = removeSuffix(CT, L"assemos"); - return true; - } - if (checkSuffix(RV, L"ariamos")) - { - CT = removeSuffix(CT, L"ariamos"); - return true; - } - if (checkSuffix(RV, L"eriamos")) - { - CT = removeSuffix(CT, L"eriamos"); - return true; - } - if (checkSuffix(RV, L"iriamos")) - { - CT = removeSuffix(CT, L"iriamos"); - return true; - } + // suffix lenght = 7 + if (RV.length() >= 7) { + if (checkSuffix(RV, L"issemos")) { + CT = removeSuffix(CT, L"issemos"); + return true; } - - // suffix length = 6 - if (RV.length() >= 6) - { - if (checkSuffix(RV, L"iremos")) - { - CT = removeSuffix(CT, L"iremos"); - return true; - } - if (checkSuffix(RV, L"eremos")) - { - CT = removeSuffix(CT, L"eremos"); - return true; - } - if (checkSuffix(RV, L"aremos")) - { - CT = removeSuffix(CT, L"aremos"); - return true; - } - if (checkSuffix(RV, L"avamos")) - { - CT = removeSuffix(CT, L"avamos"); - return true; - } - if (checkSuffix(RV, L"iramos")) - { - CT = removeSuffix(CT, L"iramos"); - return true; - } - if (checkSuffix(RV, L"eramos")) - { - CT = removeSuffix(CT, L"eramos"); - return true; - } - if (checkSuffix(RV, L"aramos")) - { - CT = removeSuffix(CT, L"aramos"); - return true; - } - if (checkSuffix(RV, L"asseis")) - { - CT = removeSuffix(CT, L"asseis"); - return true; - } - if (checkSuffix(RV, L"esseis")) - { - CT = removeSuffix(CT, L"esseis"); - return true; - } - if (checkSuffix(RV, L"isseis")) - { - CT = removeSuffix(CT, L"isseis"); - return true; - } - if (checkSuffix(RV, L"arieis")) - { - CT = removeSuffix(CT, L"arieis"); - return true; - } - if (checkSuffix(RV, L"erieis")) - { - CT = removeSuffix(CT, L"erieis"); - return true; - } - if (checkSuffix(RV, L"irieis")) - { - CT = removeSuffix(CT, L"irieis"); - return true; - } + if (checkSuffix(RV, L"essemos")) { + CT = removeSuffix(CT, L"essemos"); + return true; + } + if (checkSuffix(RV, L"assemos")) { + CT = removeSuffix(CT, L"assemos"); + return true; + } + if (checkSuffix(RV, L"ariamos")) { + CT = removeSuffix(CT, L"ariamos"); + return true; + } + if (checkSuffix(RV, L"eriamos")) { + CT = removeSuffix(CT, L"eriamos"); + return true; + } + if (checkSuffix(RV, L"iriamos")) { + CT = removeSuffix(CT, L"iriamos"); + return true; } + } - // suffix length = 5 - if (RV.length() >= 5) - { - if (checkSuffix(RV, L"irmos")) - { - CT = removeSuffix(CT, L"irmos"); - return true; - } - if (checkSuffix(RV, L"iamos")) - { - CT = removeSuffix(CT, L"iamos"); - return true; - } - if (checkSuffix(RV, L"armos")) - { - CT = removeSuffix(CT, L"armos"); - return true; - } - if (checkSuffix(RV, L"ermos")) - { - CT = removeSuffix(CT, L"ermos"); - return true; - } - if (checkSuffix(RV, L"areis")) - { - CT = removeSuffix(CT, L"areis"); - return true; - } - if (checkSuffix(RV, L"ereis")) - { - CT = removeSuffix(CT, L"ereis"); - return true; - } - if (checkSuffix(RV, L"ireis")) - { - CT = removeSuffix(CT, L"ireis"); - return true; - } - if (checkSuffix(RV, L"asses")) - { - CT = removeSuffix(CT, L"asses"); - return true; - } - if (checkSuffix(RV, L"esses")) - { - CT = removeSuffix(CT, L"esses"); - return true; - } - if (checkSuffix(RV, L"isses")) - { - CT = removeSuffix(CT, L"isses"); - return true; - } - if (checkSuffix(RV, L"astes")) - { - CT = removeSuffix(CT, L"astes"); - return true; - } - if (checkSuffix(RV, L"assem")) - { - CT = removeSuffix(CT, L"assem"); - return true; - } - if (checkSuffix(RV, L"essem")) - { - CT = removeSuffix(CT, L"essem"); - return true; - } - if (checkSuffix(RV, L"issem")) - { - CT = removeSuffix(CT, L"issem"); - return true; - } - if (checkSuffix(RV, L"ardes")) - { - CT = removeSuffix(CT, L"ardes"); - return true; - } - if (checkSuffix(RV, L"erdes")) - { - CT = removeSuffix(CT, L"erdes"); - return true; - } - if (checkSuffix(RV, L"irdes")) - { - CT = removeSuffix(CT, L"irdes"); - return true; - } - if (checkSuffix(RV, L"ariam")) - { - CT = removeSuffix(CT, L"ariam"); - return true; - } - if (checkSuffix(RV, L"eriam")) - { - CT = removeSuffix(CT, L"eriam"); - return true; - } - if (checkSuffix(RV, L"iriam")) - { - CT = removeSuffix(CT, L"iriam"); - return true; - } - if (checkSuffix(RV, L"arias")) - { - CT = removeSuffix(CT, L"arias"); - return true; - } - if (checkSuffix(RV, L"erias")) - { - CT = removeSuffix(CT, L"erias"); - return true; - } - if (checkSuffix(RV, L"irias")) - { - CT = removeSuffix(CT, L"irias"); - return true; - } - if (checkSuffix(RV, L"estes")) - { - CT = removeSuffix(CT, L"estes"); - return true; - } - if (checkSuffix(RV, L"istes")) - { - CT = removeSuffix(CT, L"istes"); - return true; - } - if (checkSuffix(RV, L"areis")) - { - CT = removeSuffix(CT, L"areis"); - return true; - } - if (checkSuffix(RV, L"aveis")) - { - CT = removeSuffix(CT, L"aveis"); - return true; - } + // suffix length = 6 + if (RV.length() >= 6) { + if (checkSuffix(RV, L"iremos")) { + CT = removeSuffix(CT, L"iremos"); + return true; } - - // suffix length = 4 - if (RV.length() >= 4) - { - if (checkSuffix(RV, L"aria")) - { - CT = removeSuffix(CT, L"aria"); - return true; - } - if (checkSuffix(RV, L"eria")) - { - CT = removeSuffix(CT, L"eria"); - return true; - } - if (checkSuffix(RV, L"iria")) - { - CT = removeSuffix(CT, L"iria"); - return true; - } - if (checkSuffix(RV, L"asse")) - { - CT = removeSuffix(CT, L"asse"); - return true; - } - if (checkSuffix(RV, L"esse")) - { - CT = removeSuffix(CT, L"esse"); - return true; - } - if (checkSuffix(RV, L"isse")) - { - CT = removeSuffix(CT, L"isse"); - return true; - } - if (checkSuffix(RV, L"aste")) - { - CT = removeSuffix(CT, L"aste"); - return true; - } - if (checkSuffix(RV, L"este")) - { - CT = removeSuffix(CT, L"este"); - return true; - } - if (checkSuffix(RV, L"iste")) - { - CT = removeSuffix(CT, L"iste"); - return true; - } - if (checkSuffix(RV, L"arei")) - { - CT = removeSuffix(CT, L"arei"); - return true; - } - if (checkSuffix(RV, L"erei")) - { - CT = removeSuffix(CT, L"erei"); - return true; - } - if (checkSuffix(RV, L"irei")) - { - CT = removeSuffix(CT, L"irei"); - return true; - } - if (checkSuffix(RV, L"aram")) - { - CT = removeSuffix(CT, L"aram"); - return true; - } - if (checkSuffix(RV, L"eram")) - { - CT = removeSuffix(CT, L"eram"); - return true; - } - if (checkSuffix(RV, L"iram")) - { - CT = removeSuffix(CT, L"iram"); - return true; - } - if (checkSuffix(RV, L"avam")) - { - CT = removeSuffix(CT, L"avam"); - return true; - } - if (checkSuffix(RV, L"arem")) - { - CT = removeSuffix(CT, L"arem"); - return true; - } - if (checkSuffix(RV, L"erem")) - { - CT = removeSuffix(CT, L"erem"); - return true; - } - if (checkSuffix(RV, L"irem")) - { - CT = removeSuffix(CT, L"irem"); - return true; - } - if (checkSuffix(RV, L"ando")) - { - CT = removeSuffix(CT, L"ando"); - return true; - } - if (checkSuffix(RV, L"endo")) - { - CT = removeSuffix(CT, L"endo"); - return true; - } - if (checkSuffix(RV, L"indo")) - { - CT = removeSuffix(CT, L"indo"); - return true; - } - if (checkSuffix(RV, L"arao")) - { - CT = removeSuffix(CT, L"arao"); - return true; - } - if (checkSuffix(RV, L"erao")) - { - CT = removeSuffix(CT, L"erao"); - return true; - } - if (checkSuffix(RV, L"irao")) - { - CT = removeSuffix(CT, L"irao"); - return true; - } - if (checkSuffix(RV, L"adas")) - { - CT = removeSuffix(CT, L"adas"); - return true; - } - if (checkSuffix(RV, L"idas")) - { - CT = removeSuffix(CT, L"idas"); - return true; - } - if (checkSuffix(RV, L"aras")) - { - CT = removeSuffix(CT, L"aras"); - return true; - } - if (checkSuffix(RV, L"eras")) - { - CT = removeSuffix(CT, L"eras"); - return true; - } - if (checkSuffix(RV, L"iras")) - { - CT = removeSuffix(CT, L"iras"); - return true; - } - if (checkSuffix(RV, L"avas")) - { - CT = removeSuffix(CT, L"avas"); - return true; - } - if (checkSuffix(RV, L"ares")) - { - CT = removeSuffix(CT, L"ares"); - return true; - } - if (checkSuffix(RV, L"eres")) - { - CT = removeSuffix(CT, L"eres"); - return true; - } - if (checkSuffix(RV, L"ires")) - { - CT = removeSuffix(CT, L"ires"); - return true; - } - if (checkSuffix(RV, L"ados")) - { - CT = removeSuffix(CT, L"ados"); - return true; - } - if (checkSuffix(RV, L"idos")) - { - CT = removeSuffix(CT, L"idos"); - return true; - } - if (checkSuffix(RV, L"amos")) - { - CT = removeSuffix(CT, L"amos"); - return true; - } - if (checkSuffix(RV, L"emos")) - { - CT = removeSuffix(CT, L"emos"); - return true; - } - if (checkSuffix(RV, L"imos")) - { - CT = removeSuffix(CT, L"imos"); - return true; - } - if (checkSuffix(RV, L"iras")) - { - CT = removeSuffix(CT, L"iras"); - return true; - } - if (checkSuffix(RV, L"ieis")) - { - CT = removeSuffix(CT, L"ieis"); - return true; - } + if (checkSuffix(RV, L"eremos")) { + CT = removeSuffix(CT, L"eremos"); + return true; } - - // suffix length = 3 - if (RV.length() >= 3) - { - if (checkSuffix(RV, L"ada")) - { - CT = removeSuffix(CT, L"ada"); - return true; - } - if (checkSuffix(RV, L"ida")) - { - CT = removeSuffix(CT, L"ida"); - return true; - } - if (checkSuffix(RV, L"ara")) - { - CT = removeSuffix(CT, L"ara"); - return true; - } - if (checkSuffix(RV, L"era")) - { - CT = removeSuffix(CT, L"era"); - return true; - } - if (checkSuffix(RV, L"ira")) - { - CT = removeSuffix(CT, L"ava"); - return true; - } - if (checkSuffix(RV, L"iam")) - { - CT = removeSuffix(CT, L"iam"); - return true; - } - if (checkSuffix(RV, L"ado")) - { - CT = removeSuffix(CT, L"ado"); - return true; - } - if (checkSuffix(RV, L"ido")) - { - CT = removeSuffix(CT, L"ido"); - return true; - } - if (checkSuffix(RV, L"ias")) - { - CT = removeSuffix(CT, L"ias"); - return true; - } - if (checkSuffix(RV, L"ais")) - { - CT = removeSuffix(CT, L"ais"); - return true; - } - if (checkSuffix(RV, L"eis")) - { - CT = removeSuffix(CT, L"eis"); - return true; - } - if (checkSuffix(RV, L"ira")) - { - CT = removeSuffix(CT, L"ira"); - return true; - } - if (checkSuffix(RV, L"ear")) - { - CT = removeSuffix(CT, L"ear"); - return true; - } + if (checkSuffix(RV, L"aremos")) { + CT = removeSuffix(CT, L"aremos"); + return true; } - - // suffix length = 2 - if (RV.length() >= 2) - { - if (checkSuffix(RV, L"ia")) - { - CT = removeSuffix(CT, L"ia"); - return true; - } - if (checkSuffix(RV, L"ei")) - { - CT = removeSuffix(CT, L"ei"); - return true; - } - if (checkSuffix(RV, L"am")) - { - CT = removeSuffix(CT, L"am"); - return true; - } - if (checkSuffix(RV, L"em")) - { - CT = removeSuffix(CT, L"em"); - return true; - } - if (checkSuffix(RV, L"ar")) - { - CT = removeSuffix(CT, L"ar"); - return true; - } - if (checkSuffix(RV, L"er")) - { - CT = removeSuffix(CT, L"er"); - return true; - } - if (checkSuffix(RV, L"ir")) - { - CT = removeSuffix(CT, L"ir"); - return true; - } - if (checkSuffix(RV, L"as")) - { - CT = removeSuffix(CT, L"as"); - return true; - } - if (checkSuffix(RV, L"es")) - { - CT = removeSuffix(CT, L"es"); - return true; - } - if (checkSuffix(RV, L"is")) - { - CT = removeSuffix(CT, L"is"); - return true; - } - if (checkSuffix(RV, L"eu")) - { - CT = removeSuffix(CT, L"eu"); - return true; - } - if (checkSuffix(RV, L"iu")) - { - CT = removeSuffix(CT, L"iu"); - return true; - } - if (checkSuffix(RV, L"iu")) - { - CT = removeSuffix(CT, L"iu"); - return true; - } - if (checkSuffix(RV, L"ou")) - { - CT = removeSuffix(CT, L"ou"); - return true; - } + if (checkSuffix(RV, L"avamos")) { + CT = removeSuffix(CT, L"avamos"); + return true; + } + if (checkSuffix(RV, L"iramos")) { + CT = removeSuffix(CT, L"iramos"); + return true; + } + if (checkSuffix(RV, L"eramos")) { + CT = removeSuffix(CT, L"eramos"); + return true; + } + if (checkSuffix(RV, L"aramos")) { + CT = removeSuffix(CT, L"aramos"); + return true; + } + if (checkSuffix(RV, L"asseis")) { + CT = removeSuffix(CT, L"asseis"); + return true; + } + if (checkSuffix(RV, L"esseis")) { + CT = removeSuffix(CT, L"esseis"); + return true; + } + if (checkSuffix(RV, L"isseis")) { + CT = removeSuffix(CT, L"isseis"); + return true; + } + if (checkSuffix(RV, L"arieis")) { + CT = removeSuffix(CT, L"arieis"); + return true; + } + if (checkSuffix(RV, L"erieis")) { + CT = removeSuffix(CT, L"erieis"); + return true; + } + if (checkSuffix(RV, L"irieis")) { + CT = removeSuffix(CT, L"irieis"); + return true; } - - // no ending was removed by step2 - return false; } - void BrazilianStemmer::step3() - { - if (RV.empty()) - return; + // suffix length = 5 + if (RV.length() >= 5) { + if (checkSuffix(RV, L"irmos")) { + CT = removeSuffix(CT, L"irmos"); + return true; + } + if (checkSuffix(RV, L"iamos")) { + CT = removeSuffix(CT, L"iamos"); + return true; + } + if (checkSuffix(RV, L"armos")) { + CT = removeSuffix(CT, L"armos"); + return true; + } + if (checkSuffix(RV, L"ermos")) { + CT = removeSuffix(CT, L"ermos"); + return true; + } + if (checkSuffix(RV, L"areis")) { + CT = removeSuffix(CT, L"areis"); + return true; + } + if (checkSuffix(RV, L"ereis")) { + CT = removeSuffix(CT, L"ereis"); + return true; + } + if (checkSuffix(RV, L"ireis")) { + CT = removeSuffix(CT, L"ireis"); + return true; + } + if (checkSuffix(RV, L"asses")) { + CT = removeSuffix(CT, L"asses"); + return true; + } + if (checkSuffix(RV, L"esses")) { + CT = removeSuffix(CT, L"esses"); + return true; + } + if (checkSuffix(RV, L"isses")) { + CT = removeSuffix(CT, L"isses"); + return true; + } + if (checkSuffix(RV, L"astes")) { + CT = removeSuffix(CT, L"astes"); + return true; + } + if (checkSuffix(RV, L"assem")) { + CT = removeSuffix(CT, L"assem"); + return true; + } + if (checkSuffix(RV, L"essem")) { + CT = removeSuffix(CT, L"essem"); + return true; + } + if (checkSuffix(RV, L"issem")) { + CT = removeSuffix(CT, L"issem"); + return true; + } + if (checkSuffix(RV, L"ardes")) { + CT = removeSuffix(CT, L"ardes"); + return true; + } + if (checkSuffix(RV, L"erdes")) { + CT = removeSuffix(CT, L"erdes"); + return true; + } + if (checkSuffix(RV, L"irdes")) { + CT = removeSuffix(CT, L"irdes"); + return true; + } + if (checkSuffix(RV, L"ariam")) { + CT = removeSuffix(CT, L"ariam"); + return true; + } + if (checkSuffix(RV, L"eriam")) { + CT = removeSuffix(CT, L"eriam"); + return true; + } + if (checkSuffix(RV, L"iriam")) { + CT = removeSuffix(CT, L"iriam"); + return true; + } + if (checkSuffix(RV, L"arias")) { + CT = removeSuffix(CT, L"arias"); + return true; + } + if (checkSuffix(RV, L"erias")) { + CT = removeSuffix(CT, L"erias"); + return true; + } + if (checkSuffix(RV, L"irias")) { + CT = removeSuffix(CT, L"irias"); + return true; + } + if (checkSuffix(RV, L"estes")) { + CT = removeSuffix(CT, L"estes"); + return true; + } + if (checkSuffix(RV, L"istes")) { + CT = removeSuffix(CT, L"istes"); + return true; + } + if (checkSuffix(RV, L"areis")) { + CT = removeSuffix(CT, L"areis"); + return true; + } + if (checkSuffix(RV, L"aveis")) { + CT = removeSuffix(CT, L"aveis"); + return true; + } + } - if (checkSuffix(RV, L"i") && suffixPreceded(RV, L"i", L"c")) - CT = removeSuffix(CT, L"i"); + // suffix length = 4 + if (RV.length() >= 4) { + if (checkSuffix(RV, L"aria")) { + CT = removeSuffix(CT, L"aria"); + return true; + } + if (checkSuffix(RV, L"eria")) { + CT = removeSuffix(CT, L"eria"); + return true; + } + if (checkSuffix(RV, L"iria")) { + CT = removeSuffix(CT, L"iria"); + return true; + } + if (checkSuffix(RV, L"asse")) { + CT = removeSuffix(CT, L"asse"); + return true; + } + if (checkSuffix(RV, L"esse")) { + CT = removeSuffix(CT, L"esse"); + return true; + } + if (checkSuffix(RV, L"isse")) { + CT = removeSuffix(CT, L"isse"); + return true; + } + if (checkSuffix(RV, L"aste")) { + CT = removeSuffix(CT, L"aste"); + return true; + } + if (checkSuffix(RV, L"este")) { + CT = removeSuffix(CT, L"este"); + return true; + } + if (checkSuffix(RV, L"iste")) { + CT = removeSuffix(CT, L"iste"); + return true; + } + if (checkSuffix(RV, L"arei")) { + CT = removeSuffix(CT, L"arei"); + return true; + } + if (checkSuffix(RV, L"erei")) { + CT = removeSuffix(CT, L"erei"); + return true; + } + if (checkSuffix(RV, L"irei")) { + CT = removeSuffix(CT, L"irei"); + return true; + } + if (checkSuffix(RV, L"aram")) { + CT = removeSuffix(CT, L"aram"); + return true; + } + if (checkSuffix(RV, L"eram")) { + CT = removeSuffix(CT, L"eram"); + return true; + } + if (checkSuffix(RV, L"iram")) { + CT = removeSuffix(CT, L"iram"); + return true; + } + if (checkSuffix(RV, L"avam")) { + CT = removeSuffix(CT, L"avam"); + return true; + } + if (checkSuffix(RV, L"arem")) { + CT = removeSuffix(CT, L"arem"); + return true; + } + if (checkSuffix(RV, L"erem")) { + CT = removeSuffix(CT, L"erem"); + return true; + } + if (checkSuffix(RV, L"irem")) { + CT = removeSuffix(CT, L"irem"); + return true; + } + if (checkSuffix(RV, L"ando")) { + CT = removeSuffix(CT, L"ando"); + return true; + } + if (checkSuffix(RV, L"endo")) { + CT = removeSuffix(CT, L"endo"); + return true; + } + if (checkSuffix(RV, L"indo")) { + CT = removeSuffix(CT, L"indo"); + return true; + } + if (checkSuffix(RV, L"arao")) { + CT = removeSuffix(CT, L"arao"); + return true; + } + if (checkSuffix(RV, L"erao")) { + CT = removeSuffix(CT, L"erao"); + return true; + } + if (checkSuffix(RV, L"irao")) { + CT = removeSuffix(CT, L"irao"); + return true; + } + if (checkSuffix(RV, L"adas")) { + CT = removeSuffix(CT, L"adas"); + return true; + } + if (checkSuffix(RV, L"idas")) { + CT = removeSuffix(CT, L"idas"); + return true; + } + if (checkSuffix(RV, L"aras")) { + CT = removeSuffix(CT, L"aras"); + return true; + } + if (checkSuffix(RV, L"eras")) { + CT = removeSuffix(CT, L"eras"); + return true; + } + if (checkSuffix(RV, L"iras")) { + CT = removeSuffix(CT, L"iras"); + return true; + } + if (checkSuffix(RV, L"avas")) { + CT = removeSuffix(CT, L"avas"); + return true; + } + if (checkSuffix(RV, L"ares")) { + CT = removeSuffix(CT, L"ares"); + return true; + } + if (checkSuffix(RV, L"eres")) { + CT = removeSuffix(CT, L"eres"); + return true; + } + if (checkSuffix(RV, L"ires")) { + CT = removeSuffix(CT, L"ires"); + return true; + } + if (checkSuffix(RV, L"ados")) { + CT = removeSuffix(CT, L"ados"); + return true; + } + if (checkSuffix(RV, L"idos")) { + CT = removeSuffix(CT, L"idos"); + return true; + } + if (checkSuffix(RV, L"amos")) { + CT = removeSuffix(CT, L"amos"); + return true; + } + if (checkSuffix(RV, L"emos")) { + CT = removeSuffix(CT, L"emos"); + return true; + } + if (checkSuffix(RV, L"imos")) { + CT = removeSuffix(CT, L"imos"); + return true; + } + if (checkSuffix(RV, L"iras")) { + CT = removeSuffix(CT, L"iras"); + return true; + } + if (checkSuffix(RV, L"ieis")) { + CT = removeSuffix(CT, L"ieis"); + return true; + } } - void BrazilianStemmer::step4() - { - if (RV.empty()) - return; + // suffix length = 3 + if (RV.length() >= 3) { + if (checkSuffix(RV, L"ada")) { + CT = removeSuffix(CT, L"ada"); + return true; + } + if (checkSuffix(RV, L"ida")) { + CT = removeSuffix(CT, L"ida"); + return true; + } + if (checkSuffix(RV, L"ara")) { + CT = removeSuffix(CT, L"ara"); + return true; + } + if (checkSuffix(RV, L"era")) { + CT = removeSuffix(CT, L"era"); + return true; + } + if (checkSuffix(RV, L"ira")) { + CT = removeSuffix(CT, L"ava"); + return true; + } + if (checkSuffix(RV, L"iam")) { + CT = removeSuffix(CT, L"iam"); + return true; + } + if (checkSuffix(RV, L"ado")) { + CT = removeSuffix(CT, L"ado"); + return true; + } + if (checkSuffix(RV, L"ido")) { + CT = removeSuffix(CT, L"ido"); + return true; + } + if (checkSuffix(RV, L"ias")) { + CT = removeSuffix(CT, L"ias"); + return true; + } + if (checkSuffix(RV, L"ais")) { + CT = removeSuffix(CT, L"ais"); + return true; + } + if (checkSuffix(RV, L"eis")) { + CT = removeSuffix(CT, L"eis"); + return true; + } + if (checkSuffix(RV, L"ira")) { + CT = removeSuffix(CT, L"ira"); + return true; + } + if (checkSuffix(RV, L"ear")) { + CT = removeSuffix(CT, L"ear"); + return true; + } + } - if (checkSuffix(RV, L"os")) - { - CT = removeSuffix(CT, L"os"); - return; + // suffix length = 2 + if (RV.length() >= 2) { + if (checkSuffix(RV, L"ia")) { + CT = removeSuffix(CT, L"ia"); + return true; } - if (checkSuffix(RV, L"a")) - { - CT = removeSuffix(CT, L"a"); - return; + if (checkSuffix(RV, L"ei")) { + CT = removeSuffix(CT, L"ei"); + return true; } - if (checkSuffix(RV, L"i")) - { - CT = removeSuffix(CT, L"i"); - return; + if (checkSuffix(RV, L"am")) { + CT = removeSuffix(CT, L"am"); + return true; } - if (checkSuffix(RV, L"o")) - { - CT = removeSuffix(CT, L"o"); - return; + if (checkSuffix(RV, L"em")) { + CT = removeSuffix(CT, L"em"); + return true; + } + if (checkSuffix(RV, L"ar")) { + CT = removeSuffix(CT, L"ar"); + return true; + } + if (checkSuffix(RV, L"er")) { + CT = removeSuffix(CT, L"er"); + return true; + } + if (checkSuffix(RV, L"ir")) { + CT = removeSuffix(CT, L"ir"); + return true; + } + if (checkSuffix(RV, L"as")) { + CT = removeSuffix(CT, L"as"); + return true; + } + if (checkSuffix(RV, L"es")) { + CT = removeSuffix(CT, L"es"); + return true; + } + if (checkSuffix(RV, L"is")) { + CT = removeSuffix(CT, L"is"); + return true; + } + if (checkSuffix(RV, L"eu")) { + CT = removeSuffix(CT, L"eu"); + return true; + } + if (checkSuffix(RV, L"iu")) { + CT = removeSuffix(CT, L"iu"); + return true; + } + if (checkSuffix(RV, L"iu")) { + CT = removeSuffix(CT, L"iu"); + return true; + } + if (checkSuffix(RV, L"ou")) { + CT = removeSuffix(CT, L"ou"); + return true; } } - void BrazilianStemmer::step5() - { - if (RV.empty()) - return; + // no ending was removed by step2 + return false; +} - if (checkSuffix(RV, L"e")) - { - if (suffixPreceded(RV, L"e", L"gu")) - { - CT = removeSuffix(CT, L"e"); - CT = removeSuffix(CT, L"u"); - return; - } +void BrazilianStemmer::step3() { + if (RV.empty()) { + return; + } - if (suffixPreceded(RV, L"e", L"ci")) - { - CT = removeSuffix(CT, L"e"); - CT = removeSuffix(CT, L"i"); - return; - } + if (checkSuffix(RV, L"i") && suffixPreceded(RV, L"i", L"c")) { + CT = removeSuffix(CT, L"i"); + } +} + +void BrazilianStemmer::step4() { + if (RV.empty()) { + return; + } + + if (checkSuffix(RV, L"os")) { + CT = removeSuffix(CT, L"os"); + return; + } + if (checkSuffix(RV, L"a")) { + CT = removeSuffix(CT, L"a"); + return; + } + if (checkSuffix(RV, L"i")) { + CT = removeSuffix(CT, L"i"); + return; + } + if (checkSuffix(RV, L"o")) { + CT = removeSuffix(CT, L"o"); + return; + } +} +void BrazilianStemmer::step5() { + if (RV.empty()) { + return; + } + + if (checkSuffix(RV, L"e")) { + if (suffixPreceded(RV, L"e", L"gu")) { + CT = removeSuffix(CT, L"e"); + CT = removeSuffix(CT, L"u"); + return; + } + + if (suffixPreceded(RV, L"e", L"ci")) { CT = removeSuffix(CT, L"e"); + CT = removeSuffix(CT, L"i"); return; } + + CT = removeSuffix(CT, L"e"); + return; } } + +} diff --git a/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp index 2c0647f3..7a62f308 100644 --- a/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp @@ -9,64 +9,57 @@ #include "CJKTokenizer.h" #include "StopFilter.h" -namespace Lucene -{ - const wchar_t* CJKAnalyzer::_STOP_WORDS[] = - { - L"a", L"and", L"are", L"as", L"at", L"be", - L"but", L"by", L"for", L"if", L"in", L"into", - L"is", L"it", L"no", L"not", L"of", L"on", - L"or", L"s", L"such", L"t", L"that", L"the", - L"their", L"then", L"there", L"these", - L"they", L"this", L"to", L"was", L"will", - L"with", L"", L"www" - }; +namespace Lucene { - CJKAnalyzer::CJKAnalyzer(LuceneVersion::Version matchVersion) - { - this->stoptable = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +const wchar_t* CJKAnalyzer::_STOP_WORDS[] = { + L"a", L"and", L"are", L"as", L"at", L"be", + L"but", L"by", L"for", L"if", L"in", L"into", + L"is", L"it", L"no", L"not", L"of", L"on", + L"or", L"s", L"such", L"t", L"that", L"the", + L"their", L"then", L"there", L"these", + L"they", L"this", L"to", L"was", L"will", + L"with", L"", L"www" +}; - CJKAnalyzer::CJKAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stoptable = stopwords; - this->matchVersion = matchVersion; - } +CJKAnalyzer::CJKAnalyzer(LuceneVersion::Version matchVersion) { + this->stoptable = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - CJKAnalyzer::~CJKAnalyzer() - { - } +CJKAnalyzer::CJKAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stoptable = stopwords; + this->matchVersion = matchVersion; +} - const HashSet CJKAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - stopSet = HashSet::newInstance(_STOP_WORDS, _STOP_WORDS + SIZEOF_ARRAY(_STOP_WORDS)); - return stopSet; - } +CJKAnalyzer::~CJKAnalyzer() { +} - TokenStreamPtr CJKAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), newLucene(reader), stoptable); +const HashSet CJKAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + stopSet = HashSet::newInstance(_STOP_WORDS, _STOP_WORDS + SIZEOF_ARRAY(_STOP_WORDS)); } + return stopSet; +} - TokenStreamPtr CJKAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - CJKAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(reader); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->source, stoptable); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr CJKAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), newLucene(reader), stoptable); +} - CJKAnalyzerSavedStreams::~CJKAnalyzerSavedStreams() - { +TokenStreamPtr CJKAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + CJKAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(reader); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->source, stoptable); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +CJKAnalyzerSavedStreams::~CJKAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp b/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp index 4a4abdf4..ba3426da 100644 --- a/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/cjk/CJKTokenizer.cpp @@ -14,265 +14,221 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - /// Word token type - const int32_t CJKTokenizer::WORD_TYPE = 0; +namespace Lucene { - /// Single byte token type - const int32_t CJKTokenizer::SINGLE_TOKEN_TYPE = 1; +/// Word token type +const int32_t CJKTokenizer::WORD_TYPE = 0; - /// Double byte token type - const int32_t CJKTokenizer::DOUBLE_TOKEN_TYPE = 2; +/// Single byte token type +const int32_t CJKTokenizer::SINGLE_TOKEN_TYPE = 1; - /// Names for token types - const wchar_t* CJKTokenizer::TOKEN_TYPE_NAMES[] = {L"word", L"single", L"double"}; +/// Double byte token type +const int32_t CJKTokenizer::DOUBLE_TOKEN_TYPE = 2; - const int32_t CJKTokenizer::MAX_WORD_LEN = 255; +/// Names for token types +const wchar_t* CJKTokenizer::TOKEN_TYPE_NAMES[] = {L"word", L"single", L"double"}; - const int32_t CJKTokenizer::IO_BUFFER_SIZE = 256; +const int32_t CJKTokenizer::MAX_WORD_LEN = 255; - CJKTokenizer::CJKTokenizer(const ReaderPtr& input) : Tokenizer(input) - { - } +const int32_t CJKTokenizer::IO_BUFFER_SIZE = 256; - CJKTokenizer::CJKTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) - { - } +CJKTokenizer::CJKTokenizer(const ReaderPtr& input) : Tokenizer(input) { +} - CJKTokenizer::CJKTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) - { - } +CJKTokenizer::CJKTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) { +} - CJKTokenizer::~CJKTokenizer() - { - } +CJKTokenizer::CJKTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) { +} - void CJKTokenizer::initialize() - { - offset = 0; - bufferIndex = 0; - dataLen = 0; - buffer = CharArray::newInstance(MAX_WORD_LEN); - ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - tokenType = WORD_TYPE; - preIsTokened = false; - - termAtt = addAttribute(); - offsetAtt = addAttribute(); - typeAtt = addAttribute(); - } +CJKTokenizer::~CJKTokenizer() { +} - CJKTokenizer::UnicodeBlock CJKTokenizer::unicodeBlock(wchar_t c) - { - if (c >= 0x0000 && c <= 0x007f) - return BASIC_LATIN; - else if (c >= 0xff00 && c <= 0xffef) - return HALFWIDTH_AND_FULLWIDTH_FORMS; - return NONE; +void CJKTokenizer::initialize() { + offset = 0; + bufferIndex = 0; + dataLen = 0; + buffer = CharArray::newInstance(MAX_WORD_LEN); + ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); + tokenType = WORD_TYPE; + preIsTokened = false; + + termAtt = addAttribute(); + offsetAtt = addAttribute(); + typeAtt = addAttribute(); +} + +CJKTokenizer::UnicodeBlock CJKTokenizer::unicodeBlock(wchar_t c) { + if (c >= 0x0000 && c <= 0x007f) { + return BASIC_LATIN; + } else if (c >= 0xff00 && c <= 0xffef) { + return HALFWIDTH_AND_FULLWIDTH_FORMS; } + return NONE; +} - bool CJKTokenizer::incrementToken() - { - clearAttributes(); +bool CJKTokenizer::incrementToken() { + clearAttributes(); - while (true) // loop until we find a non-empty token - { - int32_t length = 0; + while (true) { // loop until we find a non-empty token + int32_t length = 0; - // the position used to create Token - int32_t start = offset; + // the position used to create Token + int32_t start = offset; - while (true) // loop until we've found a full token - { - wchar_t c = 0; - UnicodeBlock ub = NONE; + while (true) { // loop until we've found a full token + wchar_t c = 0; + UnicodeBlock ub = NONE; - ++offset; + ++offset; - if (bufferIndex >= dataLen) - { - dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); - bufferIndex = 0; - } + if (bufferIndex >= dataLen) { + dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); + bufferIndex = 0; + } - if (dataLen == -1) - { - if (length > 0) - { - if (preIsTokened == true) - { - length = 0; - preIsTokened = false; - } - else - --offset; - break; - } - else - { + if (dataLen == -1) { + if (length > 0) { + if (preIsTokened == true) { + length = 0; + preIsTokened = false; + } else { --offset; - return false; } + break; + } else { + --offset; + return false; } - else - { - // get current character - c = ioBuffer[bufferIndex++]; + } else { + // get current character + c = ioBuffer[bufferIndex++]; - // get the UnicodeBlock of the current character - ub = unicodeBlock(c); - } + // get the UnicodeBlock of the current character + ub = unicodeBlock(c); + } - // if the current character is ASCII or Extend ASCII - if (ub == BASIC_LATIN || ub == HALFWIDTH_AND_FULLWIDTH_FORMS) - { - if (ub == HALFWIDTH_AND_FULLWIDTH_FORMS) - { - int32_t i = (int32_t)c; - if (i >= 65281 && i <= 65374) - { - // convert certain HALFWIDTH_AND_FULLWIDTH_FORMS to BASIC_LATIN - i = i - 65248; - c = (wchar_t)i; - } + // if the current character is ASCII or Extend ASCII + if (ub == BASIC_LATIN || ub == HALFWIDTH_AND_FULLWIDTH_FORMS) { + if (ub == HALFWIDTH_AND_FULLWIDTH_FORMS) { + int32_t i = (int32_t)c; + if (i >= 65281 && i <= 65374) { + // convert certain HALFWIDTH_AND_FULLWIDTH_FORMS to BASIC_LATIN + i = i - 65248; + c = (wchar_t)i; } + } - // if the current character is a letter or "_" "+" "#" - if (UnicodeUtil::isAlnum(c) || c == L'_' || c == L'+' || c == L'#') - { - if (length == 0) - { - // "javaC1C2C3C4linux"
      - // ^--: the current character begin to token the ASCII - // letter - start = offset - 1; - } - else if (tokenType == DOUBLE_TOKEN_TYPE) - { - // "javaC1C2C3C4linux"
      - // ^--: the previous non-ASCII - // : the current character - --offset; - --bufferIndex; + // if the current character is a letter or "_" "+" "#" + if (UnicodeUtil::isAlnum(c) || c == L'_' || c == L'+' || c == L'#') { + if (length == 0) { + // "javaC1C2C3C4linux"
      + // ^--: the current character begin to token the ASCII + // letter + start = offset - 1; + } else if (tokenType == DOUBLE_TOKEN_TYPE) { + // "javaC1C2C3C4linux"
      + // ^--: the previous non-ASCII + // : the current character + --offset; + --bufferIndex; - if (preIsTokened) - { - // there is only one non-ASCII has been stored - length = 0; - preIsTokened = false; - break; - } - else - break; + if (preIsTokened) { + // there is only one non-ASCII has been stored + length = 0; + preIsTokened = false; + break; + } else { + break; } + } - // store the LowerCase(c) in the buffer - buffer[length++] = CharFolder::toLower(c); - tokenType = SINGLE_TOKEN_TYPE; + // store the LowerCase(c) in the buffer + buffer[length++] = CharFolder::toLower(c); + tokenType = SINGLE_TOKEN_TYPE; - // break the procedure if buffer overflowed! - if (length == MAX_WORD_LEN) - break; + // break the procedure if buffer overflowed! + if (length == MAX_WORD_LEN) { + break; } - else if (length > 0) - { - if (preIsTokened) - { - length = 0; - preIsTokened = false; - } - else - break; + } else if (length > 0) { + if (preIsTokened) { + length = 0; + preIsTokened = false; + } else { + break; } } - else - { - // non-ASCII letter, e.g."C1C2C3C4" - if (UnicodeUtil::isAlpha(c)) - { - if (length == 0) - { - start = offset - 1; + } else { + // non-ASCII letter, e.g."C1C2C3C4" + if (UnicodeUtil::isAlpha(c)) { + if (length == 0) { + start = offset - 1; + buffer[length++] = c; + tokenType = DOUBLE_TOKEN_TYPE; + } else { + if (tokenType == SINGLE_TOKEN_TYPE) { + --offset; + --bufferIndex; + + // return the previous ASCII characters + break; + } else { buffer[length++] = c; tokenType = DOUBLE_TOKEN_TYPE; - } - else - { - if (tokenType == SINGLE_TOKEN_TYPE) - { + + if (length == 2) { --offset; --bufferIndex; - - // return the previous ASCII characters + preIsTokened = true; break; } - else - { - buffer[length++] = c; - tokenType = DOUBLE_TOKEN_TYPE; - - if (length == 2) - { - --offset; - --bufferIndex; - preIsTokened = true; - break; - } - } } } - else if (length > 0) - { - if (preIsTokened) - { - // empty the buffer - length = 0; - preIsTokened = false; - } - else - break; + } else if (length > 0) { + if (preIsTokened) { + // empty the buffer + length = 0; + preIsTokened = false; + } else { + break; } } } + } - if (length > 0) - { - termAtt->setTermBuffer(buffer.get(), 0, length); - offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); - typeAtt->setType(TOKEN_TYPE_NAMES[tokenType]); - return true; - } - else if (dataLen == -1) - { - --offset; - return false; - } - - // Cycle back and try for the next token (don't return an empty string) + if (length > 0) { + termAtt->setTermBuffer(buffer.get(), 0, length); + offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); + typeAtt->setType(TOKEN_TYPE_NAMES[tokenType]); + return true; + } else if (dataLen == -1) { + --offset; + return false; } - } - void CJKTokenizer::end() - { - // set final offset - int32_t finalOffset = correctOffset(offset); - offsetAtt->setOffset(finalOffset, finalOffset); + // Cycle back and try for the next token (don't return an empty string) } +} - void CJKTokenizer::reset() - { - Tokenizer::reset(); - offset = 0; - bufferIndex = 0; - dataLen = 0; - preIsTokened = false; - tokenType = WORD_TYPE; - } +void CJKTokenizer::end() { + // set final offset + int32_t finalOffset = correctOffset(offset); + offsetAtt->setOffset(finalOffset, finalOffset); +} + +void CJKTokenizer::reset() { + Tokenizer::reset(); + offset = 0; + bufferIndex = 0; + dataLen = 0; + preIsTokened = false; + tokenType = WORD_TYPE; +} + +void CJKTokenizer::reset(const ReaderPtr& input) { + Tokenizer::reset(input); + reset(); +} - void CJKTokenizer::reset(const ReaderPtr& input) - { - Tokenizer::reset(input); - reset(); - } } diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp index ecca602f..a31117a8 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseAnalyzer.cpp @@ -9,35 +9,31 @@ #include "ChineseTokenizer.h" #include "ChineseFilter.h" -namespace Lucene -{ - ChineseAnalyzer::~ChineseAnalyzer() - { - } +namespace Lucene { - TokenStreamPtr ChineseAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(reader); - result = newLucene(result); - return result; - } +ChineseAnalyzer::~ChineseAnalyzer() { +} - TokenStreamPtr ChineseAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - ChineseAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(reader); - streams->result = newLucene(streams->source); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr ChineseAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(reader); + result = newLucene(result); + return result; +} - ChineseAnalyzerSavedStreams::~ChineseAnalyzerSavedStreams() - { +TokenStreamPtr ChineseAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + ChineseAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(reader); + streams->result = newLucene(streams->source); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +ChineseAnalyzerSavedStreams::~ChineseAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp index 97fbe0bf..d2a19f3f 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseFilter.cpp @@ -10,49 +10,42 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - const wchar_t* ChineseFilter::STOP_WORDS[] = - { - L"and", L"are", L"as", L"at", L"be", L"but", L"by", - L"for", L"if", L"in", L"into", L"is", L"it", - L"no", L"not", L"of", L"on", L"or", L"such", - L"that", L"the", L"their", L"then", L"there", L"these", - L"they", L"this", L"to", L"was", L"will", L"with" - }; - - ChineseFilter::ChineseFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stopTable = HashSet::newInstance(STOP_WORDS, STOP_WORDS + SIZEOF_ARRAY(STOP_WORDS)); - termAtt = addAttribute(); - } +namespace Lucene { - ChineseFilter::~ChineseFilter() - { - } +const wchar_t* ChineseFilter::STOP_WORDS[] = { + L"and", L"are", L"as", L"at", L"be", L"but", L"by", + L"for", L"if", L"in", L"into", L"is", L"it", + L"no", L"not", L"of", L"on", L"or", L"such", + L"that", L"the", L"their", L"then", L"there", L"these", + L"they", L"this", L"to", L"was", L"will", L"with" +}; - bool ChineseFilter::incrementToken() - { - while (input->incrementToken()) - { - String text(termAtt->term()); - - if (!stopTable.contains(text)) - { - if (UnicodeUtil::isLower(text[0]) || UnicodeUtil::isUpper(text[0])) - { - // English word/token should larger than 1 character. - if (text.length() > 1) - return true; - } - else if (UnicodeUtil::isOther(text[0])) - { - // One Chinese character as one Chinese word. - // Chinese word extraction to be added later here. +ChineseFilter::ChineseFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stopTable = HashSet::newInstance(STOP_WORDS, STOP_WORDS + SIZEOF_ARRAY(STOP_WORDS)); + termAtt = addAttribute(); +} + +ChineseFilter::~ChineseFilter() { +} + +bool ChineseFilter::incrementToken() { + while (input->incrementToken()) { + String text(termAtt->term()); + + if (!stopTable.contains(text)) { + if (UnicodeUtil::isLower(text[0]) || UnicodeUtil::isUpper(text[0])) { + // English word/token should larger than 1 character. + if (text.length() > 1) { return true; } + } else if (UnicodeUtil::isOther(text[0])) { + // One Chinese character as one Chinese word. + // Chinese word extraction to be added later here. + return true; } } - return false; } + return false; +} + } diff --git a/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp b/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp index 8b35a865..38bf9875 100644 --- a/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/cn/ChineseTokenizer.cpp @@ -13,126 +13,110 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - const int32_t ChineseTokenizer::MAX_WORD_LEN = 255; - const int32_t ChineseTokenizer::IO_BUFFER_SIZE = 1024; +namespace Lucene { - ChineseTokenizer::ChineseTokenizer(const ReaderPtr& input) : Tokenizer(input) - { - } +const int32_t ChineseTokenizer::MAX_WORD_LEN = 255; +const int32_t ChineseTokenizer::IO_BUFFER_SIZE = 1024; - ChineseTokenizer::ChineseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) - { - } +ChineseTokenizer::ChineseTokenizer(const ReaderPtr& input) : Tokenizer(input) { +} - ChineseTokenizer::ChineseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) - { - } +ChineseTokenizer::ChineseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) { +} - ChineseTokenizer::~ChineseTokenizer() - { - } +ChineseTokenizer::ChineseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) { +} - void ChineseTokenizer::initialize() - { - offset = 0; - bufferIndex = 0; - dataLen = 0; - buffer = CharArray::newInstance(MAX_WORD_LEN); - ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - length = 0; - start = 0; - - termAtt = addAttribute(); - offsetAtt = addAttribute(); - } +ChineseTokenizer::~ChineseTokenizer() { +} + +void ChineseTokenizer::initialize() { + offset = 0; + bufferIndex = 0; + dataLen = 0; + buffer = CharArray::newInstance(MAX_WORD_LEN); + ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); + length = 0; + start = 0; + + termAtt = addAttribute(); + offsetAtt = addAttribute(); +} - void ChineseTokenizer::push(wchar_t c) - { - if (length == 0) - start = offset - 1; // start of token - buffer[length++] = CharFolder::toLower(c); // buffer it +void ChineseTokenizer::push(wchar_t c) { + if (length == 0) { + start = offset - 1; // start of token } + buffer[length++] = CharFolder::toLower(c); // buffer it +} - bool ChineseTokenizer::flush() - { - if (length > 0) - { - termAtt->setTermBuffer(buffer.get(), 0, length); - offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); - return true; - } - else - return false; +bool ChineseTokenizer::flush() { + if (length > 0) { + termAtt->setTermBuffer(buffer.get(), 0, length); + offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); + return true; + } else { + return false; } +} - bool ChineseTokenizer::incrementToken() - { - clearAttributes(); +bool ChineseTokenizer::incrementToken() { + clearAttributes(); - length = 0; - start = offset; + length = 0; + start = offset; - while (true) - { - wchar_t c; - ++offset; + while (true) { + wchar_t c; + ++offset; - if (bufferIndex >= dataLen) - { - dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); - bufferIndex = 0; - } + if (bufferIndex >= dataLen) { + dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); + bufferIndex = 0; + } - if (dataLen == -1) - { - --offset; + if (dataLen == -1) { + --offset; + return flush(); + } else { + c = ioBuffer[bufferIndex++]; + } + + if (UnicodeUtil::isDigit(c) || UnicodeUtil::isLower(c) || UnicodeUtil::isUpper(c)) { + push(c); + if (length == MAX_WORD_LEN) { return flush(); } - else - c = ioBuffer[bufferIndex++]; - - if (UnicodeUtil::isDigit(c) || UnicodeUtil::isLower(c) || UnicodeUtil::isUpper(c)) - { - push(c); - if (length == MAX_WORD_LEN) - return flush(); - } - else if (UnicodeUtil::isOther(c)) - { - if (length > 0) - { - --bufferIndex; - --offset; - return flush(); - } - push(c); + } else if (UnicodeUtil::isOther(c)) { + if (length > 0) { + --bufferIndex; + --offset; return flush(); } - else if (length > 0) - return flush(); + push(c); + return flush(); + } else if (length > 0) { + return flush(); } } +} - void ChineseTokenizer::end() - { - // set final offset - int32_t finalOffset = correctOffset(offset); - offsetAtt->setOffset(finalOffset, finalOffset); - } +void ChineseTokenizer::end() { + // set final offset + int32_t finalOffset = correctOffset(offset); + offsetAtt->setOffset(finalOffset, finalOffset); +} - void ChineseTokenizer::reset() - { - Tokenizer::reset(); - offset = 0; - bufferIndex = 0; - dataLen = 0; - } +void ChineseTokenizer::reset() { + Tokenizer::reset(); + offset = 0; + bufferIndex = 0; + dataLen = 0; +} + +void ChineseTokenizer::reset(const ReaderPtr& input) { + Tokenizer::reset(input); + reset(); +} - void ChineseTokenizer::reset(const ReaderPtr& input) - { - Tokenizer::reset(input); - reset(); - } } diff --git a/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp b/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp index 84a5842c..6136aa6c 100644 --- a/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp @@ -12,121 +12,112 @@ #include "StopFilter.h" #include "StringUtils.h" -namespace Lucene -{ - /// Default Czech stopwords in UTF-8 format. - const uint8_t CzechAnalyzer::_CZECH_STOP_WORDS[] = - { - 0x61, 0x0a, 0x73, 0x0a, 0x6b, 0x0a, 0x6f, 0x0a, 0x69, 0x0a, 0x75, 0x0a, 0x76, 0x0a, 0x7a, 0x0a, - 0x64, 0x6e, 0x65, 0x73, 0x0a, 0x63, 0x7a, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x74, 0x6f, 0x0a, 0x62, - 0x75, 0x64, 0x65, 0xc5, 0xa1, 0x0a, 0x62, 0x75, 0x64, 0x65, 0x6d, 0x0a, 0x62, 0x79, 0x6c, 0x69, - 0x0a, 0x6a, 0x73, 0x65, 0xc5, 0xa1, 0x0a, 0x6d, 0x75, 0x6a, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, - 0x0a, 0x74, 0x61, 0x0a, 0x74, 0x6f, 0x6d, 0x74, 0x6f, 0x0a, 0x74, 0x6f, 0x68, 0x6c, 0x65, 0x0a, - 0x74, 0x75, 0x74, 0x6f, 0x0a, 0x74, 0x79, 0x74, 0x6f, 0x0a, 0x6a, 0x65, 0x6a, 0x0a, 0x7a, 0x64, - 0x61, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x0a, 0x6d, 0xc3, 0xa1, 0x74, 0x65, 0x0a, 0x74, 0x61, 0x74, - 0x6f, 0x0a, 0x6b, 0x61, 0x6d, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x64, 0x6f, - 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xad, 0x0a, 0x6d, 0x69, 0x0a, 0x6e, 0xc3, 0xa1, 0x6d, 0x0a, - 0x74, 0x6f, 0x6d, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x74, 0x6f, 0x0a, 0x6d, 0xc3, 0xad, 0x74, 0x0a, - 0x6e, 0x69, 0x63, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0x6f, 0x75, - 0x0a, 0x62, 0x79, 0x6c, 0x61, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0xc5, 0xbe, 0x65, 0x0a, 0x61, 0x73, 0x69, 0x0a, 0x68, 0x6f, 0x0a, 0x6e, 0x61, 0xc5, 0xa1, 0x69, - 0x0a, 0x6e, 0x61, 0x70, 0x69, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x72, 0x65, 0x0a, 0x63, 0x6f, 0xc5, - 0xbe, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x0a, 0x74, 0x61, 0x6b, 0xc5, 0xbe, 0x65, 0x0a, 0x73, 0x76, - 0xc3, 0xbd, 0x63, 0x68, 0x0a, 0x6a, 0x65, 0x6a, 0xc3, 0xad, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, - 0x69, 0x0a, 0x6a, 0x73, 0x74, 0x65, 0x0a, 0x61, 0x6a, 0x0a, 0x74, 0x75, 0x0a, 0x74, 0x65, 0x64, - 0x79, 0x0a, 0x74, 0x65, 0x74, 0x6f, 0x0a, 0x62, 0x79, 0x6c, 0x6f, 0x0a, 0x6b, 0x64, 0x65, 0x0a, - 0x6b, 0x65, 0x0a, 0x70, 0x72, 0x61, 0x76, 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x0a, 0x6e, 0x61, 0x64, - 0x0a, 0x6e, 0x65, 0x6a, 0x73, 0x6f, 0x75, 0x0a, 0x63, 0x69, 0x0a, 0x70, 0x6f, 0x64, 0x0a, 0x74, - 0xc3, 0xa9, 0x6d, 0x61, 0x0a, 0x6d, 0x65, 0x7a, 0x69, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x0a, 0x74, - 0x79, 0x0a, 0x70, 0x61, 0x6b, 0x0a, 0x76, 0xc3, 0xa1, 0x6d, 0x0a, 0x61, 0x6e, 0x69, 0x0a, 0x6b, - 0x64, 0x79, 0xc5, 0xbe, 0x0a, 0x76, 0xc5, 0xa1, 0x61, 0x6b, 0x0a, 0x6e, 0x65, 0x67, 0x0a, 0x6a, - 0x73, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6e, 0x74, 0x6f, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, - 0x75, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, 0x79, 0x0a, 0x61, 0x62, 0x79, 0x0a, 0x6a, 0x73, - 0x6d, 0x65, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x0a, 0x70, 0x74, 0x61, 0x0a, 0x6a, 0x65, 0x6a, 0x69, - 0x63, 0x68, 0x0a, 0x62, 0x79, 0x6c, 0x0a, 0x6a, 0x65, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x61, 0xc5, - 0xbe, 0x0a, 0x62, 0x65, 0x7a, 0x0a, 0x74, 0x61, 0x6b, 0xc3, 0xa9, 0x0a, 0x70, 0x6f, 0x75, 0x7a, - 0x65, 0x0a, 0x70, 0x72, 0x76, 0x6e, 0xc3, 0xad, 0x0a, 0x76, 0x61, 0xc5, 0xa1, 0x65, 0x0a, 0x6b, - 0x74, 0x65, 0x72, 0xc3, 0xa1, 0x0a, 0x6e, 0xc3, 0xa1, 0x73, 0x0a, 0x6e, 0x6f, 0x76, 0xc3, 0xbd, - 0x0a, 0x74, 0x69, 0x70, 0x79, 0x0a, 0x70, 0x6f, 0x6b, 0x75, 0x64, 0x0a, 0x6d, 0x75, 0xc5, 0xbe, - 0x65, 0x0a, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x61, 0x0a, 0x6a, 0x65, 0x68, 0x6f, 0x0a, 0x73, 0x76, - 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x6e, 0xc3, 0xa9, 0x0a, 0x7a, 0x70, 0x72, 0xc3, 0xa1, 0x76, 0x79, - 0x0a, 0x6e, 0x6f, 0x76, 0xc3, 0xa9, 0x0a, 0x6e, 0x65, 0x6e, 0xc3, 0xad, 0x0a, 0x76, 0xc3, 0xa1, - 0x73, 0x0a, 0x6a, 0x65, 0x6e, 0x0a, 0x70, 0x6f, 0x64, 0x6c, 0x65, 0x0a, 0x7a, 0x64, 0x65, 0x0a, - 0x75, 0xc5, 0xbe, 0x0a, 0x62, 0xc3, 0xbd, 0x74, 0x0a, 0x76, 0xc3, 0xad, 0x63, 0x65, 0x0a, 0x62, - 0x75, 0x64, 0x65, 0x0a, 0x6a, 0x69, 0xc5, 0xbe, 0x0a, 0x6e, 0x65, 0xc5, 0xbe, 0x0a, 0x6b, 0x74, - 0x65, 0x72, 0xc3, 0xbd, 0x0a, 0x62, 0x79, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xa9, 0x0a, 0x63, - 0x6f, 0x0a, 0x6e, 0x65, 0x62, 0x6f, 0x0a, 0x74, 0x65, 0x6e, 0x0a, 0x74, 0x61, 0x6b, 0x0a, 0x6d, - 0xc3, 0xa1, 0x0a, 0x70, 0x72, 0x69, 0x0a, 0x6f, 0x64, 0x0a, 0x70, 0x6f, 0x0a, 0x6a, 0x73, 0x6f, - 0x75, 0x0a, 0x6a, 0x61, 0x6b, 0x0a, 0x64, 0x61, 0x6c, 0xc5, 0xa1, 0xc3, 0xad, 0x0a, 0x61, 0x6c, - 0x65, 0x0a, 0x73, 0x69, 0x0a, 0x73, 0x65, 0x0a, 0x76, 0x65, 0x0a, 0x74, 0x6f, 0x0a, 0x6a, 0x61, - 0x6b, 0x6f, 0x0a, 0x7a, 0x61, 0x0a, 0x7a, 0x70, 0x65, 0x74, 0x0a, 0x7a, 0x65, 0x0a, 0x64, 0x6f, - 0x0a, 0x70, 0x72, 0x6f, 0x0a, 0x6a, 0x65, 0x0a, 0x6e, 0x61, 0x0a, 0x61, 0x74, 0x64, 0x0a, 0x61, - 0x74, 0x70, 0x0a, 0x6a, 0x61, 0x6b, 0x6d, 0x69, 0x6c, 0x65, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x6d, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xa1, 0x0a, 0x6f, 0x6e, 0x0a, 0x6f, 0x6e, 0x61, 0x0a, 0x6f, - 0x6e, 0x6f, 0x0a, 0x6f, 0x6e, 0x69, 0x0a, 0x6f, 0x6e, 0x79, 0x0a, 0x6d, 0x79, 0x0a, 0x76, 0x79, - 0x0a, 0x6a, 0xc3, 0xad, 0x0a, 0x6a, 0x69, 0x0a, 0x6d, 0x65, 0x0a, 0x6d, 0x6e, 0x65, 0x0a, 0x6a, - 0x65, 0x6d, 0x75, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x0a, 0x74, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6d, - 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, - 0x68, 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xad, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0x6c, 0x69, 0x6b, - 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0xc5, 0xbe, 0x0a, 0x6a, 0x61, 0x6b, 0x6f, 0xc5, 0xbe, 0x0a, - 0x6e, 0x61, 0x63, 0x65, 0xc5, 0xbe, 0x0a - }; +namespace Lucene { - CzechAnalyzer::CzechAnalyzer(LuceneVersion::Version matchVersion) - { - this->stoptable = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +/// Default Czech stopwords in UTF-8 format. +const uint8_t CzechAnalyzer::_CZECH_STOP_WORDS[] = { + 0x61, 0x0a, 0x73, 0x0a, 0x6b, 0x0a, 0x6f, 0x0a, 0x69, 0x0a, 0x75, 0x0a, 0x76, 0x0a, 0x7a, 0x0a, + 0x64, 0x6e, 0x65, 0x73, 0x0a, 0x63, 0x7a, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x74, 0x6f, 0x0a, 0x62, + 0x75, 0x64, 0x65, 0xc5, 0xa1, 0x0a, 0x62, 0x75, 0x64, 0x65, 0x6d, 0x0a, 0x62, 0x79, 0x6c, 0x69, + 0x0a, 0x6a, 0x73, 0x65, 0xc5, 0xa1, 0x0a, 0x6d, 0x75, 0x6a, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, + 0x0a, 0x74, 0x61, 0x0a, 0x74, 0x6f, 0x6d, 0x74, 0x6f, 0x0a, 0x74, 0x6f, 0x68, 0x6c, 0x65, 0x0a, + 0x74, 0x75, 0x74, 0x6f, 0x0a, 0x74, 0x79, 0x74, 0x6f, 0x0a, 0x6a, 0x65, 0x6a, 0x0a, 0x7a, 0x64, + 0x61, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x0a, 0x6d, 0xc3, 0xa1, 0x74, 0x65, 0x0a, 0x74, 0x61, 0x74, + 0x6f, 0x0a, 0x6b, 0x61, 0x6d, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x64, 0x6f, + 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xad, 0x0a, 0x6d, 0x69, 0x0a, 0x6e, 0xc3, 0xa1, 0x6d, 0x0a, + 0x74, 0x6f, 0x6d, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x74, 0x6f, 0x0a, 0x6d, 0xc3, 0xad, 0x74, 0x0a, + 0x6e, 0x69, 0x63, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0x6f, 0x75, + 0x0a, 0x62, 0x79, 0x6c, 0x61, 0x0a, 0x74, 0x6f, 0x68, 0x6f, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0xc5, 0xbe, 0x65, 0x0a, 0x61, 0x73, 0x69, 0x0a, 0x68, 0x6f, 0x0a, 0x6e, 0x61, 0xc5, 0xa1, 0x69, + 0x0a, 0x6e, 0x61, 0x70, 0x69, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x72, 0x65, 0x0a, 0x63, 0x6f, 0xc5, + 0xbe, 0x0a, 0x74, 0xc3, 0xad, 0x6d, 0x0a, 0x74, 0x61, 0x6b, 0xc5, 0xbe, 0x65, 0x0a, 0x73, 0x76, + 0xc3, 0xbd, 0x63, 0x68, 0x0a, 0x6a, 0x65, 0x6a, 0xc3, 0xad, 0x0a, 0x73, 0x76, 0xc3, 0xbd, 0x6d, + 0x69, 0x0a, 0x6a, 0x73, 0x74, 0x65, 0x0a, 0x61, 0x6a, 0x0a, 0x74, 0x75, 0x0a, 0x74, 0x65, 0x64, + 0x79, 0x0a, 0x74, 0x65, 0x74, 0x6f, 0x0a, 0x62, 0x79, 0x6c, 0x6f, 0x0a, 0x6b, 0x64, 0x65, 0x0a, + 0x6b, 0x65, 0x0a, 0x70, 0x72, 0x61, 0x76, 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x0a, 0x6e, 0x61, 0x64, + 0x0a, 0x6e, 0x65, 0x6a, 0x73, 0x6f, 0x75, 0x0a, 0x63, 0x69, 0x0a, 0x70, 0x6f, 0x64, 0x0a, 0x74, + 0xc3, 0xa9, 0x6d, 0x61, 0x0a, 0x6d, 0x65, 0x7a, 0x69, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x0a, 0x74, + 0x79, 0x0a, 0x70, 0x61, 0x6b, 0x0a, 0x76, 0xc3, 0xa1, 0x6d, 0x0a, 0x61, 0x6e, 0x69, 0x0a, 0x6b, + 0x64, 0x79, 0xc5, 0xbe, 0x0a, 0x76, 0xc5, 0xa1, 0x61, 0x6b, 0x0a, 0x6e, 0x65, 0x67, 0x0a, 0x6a, + 0x73, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6e, 0x74, 0x6f, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, + 0x75, 0x0a, 0x63, 0x6c, 0xc3, 0xa1, 0x6e, 0x6b, 0x79, 0x0a, 0x61, 0x62, 0x79, 0x0a, 0x6a, 0x73, + 0x6d, 0x65, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x0a, 0x70, 0x74, 0x61, 0x0a, 0x6a, 0x65, 0x6a, 0x69, + 0x63, 0x68, 0x0a, 0x62, 0x79, 0x6c, 0x0a, 0x6a, 0x65, 0xc5, 0xa1, 0x74, 0x65, 0x0a, 0x61, 0xc5, + 0xbe, 0x0a, 0x62, 0x65, 0x7a, 0x0a, 0x74, 0x61, 0x6b, 0xc3, 0xa9, 0x0a, 0x70, 0x6f, 0x75, 0x7a, + 0x65, 0x0a, 0x70, 0x72, 0x76, 0x6e, 0xc3, 0xad, 0x0a, 0x76, 0x61, 0xc5, 0xa1, 0x65, 0x0a, 0x6b, + 0x74, 0x65, 0x72, 0xc3, 0xa1, 0x0a, 0x6e, 0xc3, 0xa1, 0x73, 0x0a, 0x6e, 0x6f, 0x76, 0xc3, 0xbd, + 0x0a, 0x74, 0x69, 0x70, 0x79, 0x0a, 0x70, 0x6f, 0x6b, 0x75, 0x64, 0x0a, 0x6d, 0x75, 0xc5, 0xbe, + 0x65, 0x0a, 0x73, 0x74, 0x72, 0x61, 0x6e, 0x61, 0x0a, 0x6a, 0x65, 0x68, 0x6f, 0x0a, 0x73, 0x76, + 0xc3, 0xa9, 0x0a, 0x6a, 0x69, 0x6e, 0xc3, 0xa9, 0x0a, 0x7a, 0x70, 0x72, 0xc3, 0xa1, 0x76, 0x79, + 0x0a, 0x6e, 0x6f, 0x76, 0xc3, 0xa9, 0x0a, 0x6e, 0x65, 0x6e, 0xc3, 0xad, 0x0a, 0x76, 0xc3, 0xa1, + 0x73, 0x0a, 0x6a, 0x65, 0x6e, 0x0a, 0x70, 0x6f, 0x64, 0x6c, 0x65, 0x0a, 0x7a, 0x64, 0x65, 0x0a, + 0x75, 0xc5, 0xbe, 0x0a, 0x62, 0xc3, 0xbd, 0x74, 0x0a, 0x76, 0xc3, 0xad, 0x63, 0x65, 0x0a, 0x62, + 0x75, 0x64, 0x65, 0x0a, 0x6a, 0x69, 0xc5, 0xbe, 0x0a, 0x6e, 0x65, 0xc5, 0xbe, 0x0a, 0x6b, 0x74, + 0x65, 0x72, 0xc3, 0xbd, 0x0a, 0x62, 0x79, 0x0a, 0x6b, 0x74, 0x65, 0x72, 0xc3, 0xa9, 0x0a, 0x63, + 0x6f, 0x0a, 0x6e, 0x65, 0x62, 0x6f, 0x0a, 0x74, 0x65, 0x6e, 0x0a, 0x74, 0x61, 0x6b, 0x0a, 0x6d, + 0xc3, 0xa1, 0x0a, 0x70, 0x72, 0x69, 0x0a, 0x6f, 0x64, 0x0a, 0x70, 0x6f, 0x0a, 0x6a, 0x73, 0x6f, + 0x75, 0x0a, 0x6a, 0x61, 0x6b, 0x0a, 0x64, 0x61, 0x6c, 0xc5, 0xa1, 0xc3, 0xad, 0x0a, 0x61, 0x6c, + 0x65, 0x0a, 0x73, 0x69, 0x0a, 0x73, 0x65, 0x0a, 0x76, 0x65, 0x0a, 0x74, 0x6f, 0x0a, 0x6a, 0x61, + 0x6b, 0x6f, 0x0a, 0x7a, 0x61, 0x0a, 0x7a, 0x70, 0x65, 0x74, 0x0a, 0x7a, 0x65, 0x0a, 0x64, 0x6f, + 0x0a, 0x70, 0x72, 0x6f, 0x0a, 0x6a, 0x65, 0x0a, 0x6e, 0x61, 0x0a, 0x61, 0x74, 0x64, 0x0a, 0x61, + 0x74, 0x70, 0x0a, 0x6a, 0x61, 0x6b, 0x6d, 0x69, 0x6c, 0x65, 0x0a, 0x70, 0x72, 0x69, 0x63, 0x65, + 0x6d, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xa1, 0x0a, 0x6f, 0x6e, 0x0a, 0x6f, 0x6e, 0x61, 0x0a, 0x6f, + 0x6e, 0x6f, 0x0a, 0x6f, 0x6e, 0x69, 0x0a, 0x6f, 0x6e, 0x79, 0x0a, 0x6d, 0x79, 0x0a, 0x76, 0x79, + 0x0a, 0x6a, 0xc3, 0xad, 0x0a, 0x6a, 0x69, 0x0a, 0x6d, 0x65, 0x0a, 0x6d, 0x6e, 0x65, 0x0a, 0x6a, + 0x65, 0x6d, 0x75, 0x0a, 0x74, 0x6f, 0x6d, 0x75, 0x0a, 0x74, 0x65, 0x6d, 0x0a, 0x74, 0x65, 0x6d, + 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0x0a, 0x6e, 0x65, 0x6d, 0x75, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, + 0x68, 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0xc3, 0xad, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0x6c, 0x69, 0x6b, + 0x6f, 0xc5, 0xbe, 0x0a, 0x6a, 0x65, 0xc5, 0xbe, 0x0a, 0x6a, 0x61, 0x6b, 0x6f, 0xc5, 0xbe, 0x0a, + 0x6e, 0x61, 0x63, 0x65, 0xc5, 0xbe, 0x0a +}; - CzechAnalyzer::CzechAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stoptable = stopwords; - this->matchVersion = matchVersion; - } +CzechAnalyzer::CzechAnalyzer(LuceneVersion::Version matchVersion) { + this->stoptable = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - CzechAnalyzer::~CzechAnalyzer() - { - } +CzechAnalyzer::CzechAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stoptable = stopwords; + this->matchVersion = matchVersion; +} - const HashSet CzechAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - { - String stopWords(UTF8_TO_STRING(_CZECH_STOP_WORDS)); - Collection words(StringUtils::split(stopWords, L"\n")); - stopSet = HashSet::newInstance(words.begin(), words.end()); - } - return stopSet; - } +CzechAnalyzer::~CzechAnalyzer() { +} - TokenStreamPtr CzechAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(matchVersion, reader); - result = newLucene(result); - result = newLucene(result); - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); - return result; +const HashSet CzechAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + String stopWords(UTF8_TO_STRING(_CZECH_STOP_WORDS)); + Collection words(StringUtils::split(stopWords, L"\n")); + stopSet = HashSet::newInstance(words.begin(), words.end()); } + return stopSet; +} - TokenStreamPtr CzechAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - CzechAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(matchVersion, reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(streams->result); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr CzechAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(matchVersion, reader); + result = newLucene(result); + result = newLucene(result); + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); + return result; +} - CzechAnalyzerSavedStreams::~CzechAnalyzerSavedStreams() - { +TokenStreamPtr CzechAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + CzechAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(matchVersion, reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(streams->result); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +CzechAnalyzerSavedStreams::~CzechAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp b/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp index db166586..54313441 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp @@ -12,85 +12,76 @@ #include "StopFilter.h" #include "GermanStemFilter.h" -namespace Lucene -{ - const wchar_t* GermanAnalyzer::_GERMAN_STOP_WORDS[] = - { - L"einer", L"eine", L"eines", L"einem", L"einen", L"der", L"die", - L"das", L"dass", L"da\x00df", L"du", L"er", L"sie", L"es", L"was", - L"wer", L"wie", L"wir", L"und", L"oder", L"ohne", L"mit", L"am", - L"im", L"in", L"aus", L"auf", L"ist", L"sein", L"war", L"wird", - L"ihr", L"ihre", L"ihres", L"als", L"f\x00fcr", L"von", L"mit", - L"dich", L"dir", L"mich", L"mir", L"mein", L"sein", L"kein", - L"durch", L"wegen", L"wird" - }; +namespace Lucene { - GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion) - { - this->stopSet = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +const wchar_t* GermanAnalyzer::_GERMAN_STOP_WORDS[] = { + L"einer", L"eine", L"eines", L"einem", L"einen", L"der", L"die", + L"das", L"dass", L"da\x00df", L"du", L"er", L"sie", L"es", L"was", + L"wer", L"wie", L"wir", L"und", L"oder", L"ohne", L"mit", L"am", + L"im", L"in", L"aus", L"auf", L"ist", L"sein", L"war", L"wird", + L"ihr", L"ihre", L"ihres", L"als", L"f\x00fcr", L"von", L"mit", + L"dich", L"dir", L"mich", L"mir", L"mein", L"sein", L"kein", + L"durch", L"wegen", L"wird" +}; - GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stopSet = stopwords; - this->matchVersion = matchVersion; - } +GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion) { + this->stopSet = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) - { - this->stopSet = stopwords; - this->exclusionSet = exclusions; - this->matchVersion = matchVersion; - } +GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stopSet = stopwords; + this->matchVersion = matchVersion; +} - GermanAnalyzer::~GermanAnalyzer() - { - } +GermanAnalyzer::GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { + this->stopSet = stopwords; + this->exclusionSet = exclusions; + this->matchVersion = matchVersion; +} - const HashSet GermanAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - stopSet = HashSet::newInstance(_GERMAN_STOP_WORDS, _GERMAN_STOP_WORDS + SIZEOF_ARRAY(_GERMAN_STOP_WORDS)); - return stopSet; - } +GermanAnalyzer::~GermanAnalyzer() { +} - void GermanAnalyzer::setStemExclusionTable(HashSet exclusions) - { - exclusionSet = exclusions; - setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +const HashSet GermanAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + stopSet = HashSet::newInstance(_GERMAN_STOP_WORDS, _GERMAN_STOP_WORDS + SIZEOF_ARRAY(_GERMAN_STOP_WORDS)); } + return stopSet; +} - TokenStreamPtr GermanAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(matchVersion, reader); - result = newLucene(result); - result = newLucene(result); - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); - result = newLucene(result, exclusionSet); - return result; - } +void GermanAnalyzer::setStemExclusionTable(HashSet exclusions) { + exclusionSet = exclusions; + setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +} - TokenStreamPtr GermanAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - GermanAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(matchVersion, reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(streams->result); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); - streams->result = newLucene(streams->result, exclusionSet); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr GermanAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(matchVersion, reader); + result = newLucene(result); + result = newLucene(result); + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); + result = newLucene(result, exclusionSet); + return result; +} - GermanAnalyzerSavedStreams::~GermanAnalyzerSavedStreams() - { +TokenStreamPtr GermanAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + GermanAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(matchVersion, reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(streams->result); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); + streams->result = newLucene(streams->result, exclusionSet); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +GermanAnalyzerSavedStreams::~GermanAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp b/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp index 6d5d1210..9b760b7c 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanStemFilter.cpp @@ -9,52 +9,47 @@ #include "GermanStemmer.h" #include "TermAttribute.h" -namespace Lucene -{ - GermanStemFilter::GermanStemFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - GermanStemFilter::GermanStemFilter(const TokenStreamPtr& input, HashSet exclusionSet) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - this->exclusionSet = exclusionSet; - } +GermanStemFilter::GermanStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); +} - GermanStemFilter::~GermanStemFilter() - { - } +GermanStemFilter::GermanStemFilter(const TokenStreamPtr& input, HashSet exclusionSet) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); + this->exclusionSet = exclusionSet; +} + +GermanStemFilter::~GermanStemFilter() { +} - bool GermanStemFilter::incrementToken() - { - if (input->incrementToken()) - { - String term(termAtt->term()); - // Check the exclusion table. - if (!exclusionSet || !exclusionSet.contains(term)) - { - String s(stemmer->stem(term)); - // If not stemmed, don't waste the time adjusting the token. - if (!s.empty() && s != term) - termAtt->setTermBuffer(s); +bool GermanStemFilter::incrementToken() { + if (input->incrementToken()) { + String term(termAtt->term()); + // Check the exclusion table. + if (!exclusionSet || !exclusionSet.contains(term)) { + String s(stemmer->stem(term)); + // If not stemmed, don't waste the time adjusting the token. + if (!s.empty() && s != term) { + termAtt->setTermBuffer(s); } - return true; } - else - return false; + return true; + } else { + return false; } +} - void GermanStemFilter::setStemmer(const GermanStemmerPtr& stemmer) - { - if (stemmer) - this->stemmer = stemmer; +void GermanStemFilter::setStemmer(const GermanStemmerPtr& stemmer) { + if (stemmer) { + this->stemmer = stemmer; } +} + +void GermanStemFilter::setExclusionSet(HashSet exclusionSet) { + this->exclusionSet = exclusionSet; +} - void GermanStemFilter::setExclusionSet(HashSet exclusionSet) - { - this->exclusionSet = exclusionSet; - } } diff --git a/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp b/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp index 9cbd81af..d6631ec7 100644 --- a/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/de/GermanStemmer.cpp @@ -11,200 +11,167 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - GermanStemmer::GermanStemmer() - { - substCount = 0; - } - - GermanStemmer::~GermanStemmer() - { - } +namespace Lucene { - String GermanStemmer::stem(const String& term) - { - // Use lowercase for medium stemming. - buffer = StringUtils::toLower(term); - if (!isStemmable()) - return buffer; +GermanStemmer::GermanStemmer() { + substCount = 0; +} - // Stemming starts here - substitute(); - strip(); - optimize(); - resubstitute(); - removeParticleDenotion(); +GermanStemmer::~GermanStemmer() { +} +String GermanStemmer::stem(const String& term) { + // Use lowercase for medium stemming. + buffer = StringUtils::toLower(term); + if (!isStemmable()) { return buffer; } - bool GermanStemmer::isStemmable() - { - for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) - { - if (!UnicodeUtil::isAlpha(buffer[c])) - return false; - } - return true; - } + // Stemming starts here + substitute(); + strip(); + optimize(); + resubstitute(); + removeParticleDenotion(); + + return buffer; +} - void GermanStemmer::strip() - { - bool doMore = true; - while (doMore && buffer.length() > 3) - { - if (buffer.length() + substCount > 5 && boost::ends_with(buffer, L"nd")) - buffer.resize(buffer.length() - 2); - else if (buffer.length() + substCount > 4 && boost::ends_with(buffer, L"em")) - buffer.resize(buffer.length() - 2); - else if (buffer.length() + substCount > 4 && boost::ends_with(buffer, L"er")) - buffer.resize(buffer.length() - 2); - else if (buffer[buffer.length() - 1] == L'e') - buffer.resize(buffer.length() - 1); - else if (buffer[buffer.length() - 1] == L's') - buffer.resize(buffer.length() - 1); - else if (buffer[buffer.length() - 1] == L'n') - buffer.resize(buffer.length() - 1); - // "t" occurs only as suffix of verbs. - else if (buffer[buffer.length() - 1] == L't') - buffer.resize(buffer.length() - 1); - else - doMore = false; +bool GermanStemmer::isStemmable() { + for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) { + if (!UnicodeUtil::isAlpha(buffer[c])) { + return false; } } + return true; +} - void GermanStemmer::optimize() - { - // Additional step for female plurals of professions and inhabitants. - if (buffer.length() > 5 && boost::ends_with(buffer, L"erin*")) - { +void GermanStemmer::strip() { + bool doMore = true; + while (doMore && buffer.length() > 3) { + if (buffer.length() + substCount > 5 && boost::ends_with(buffer, L"nd")) { + buffer.resize(buffer.length() - 2); + } else if (buffer.length() + substCount > 4 && boost::ends_with(buffer, L"em")) { + buffer.resize(buffer.length() - 2); + } else if (buffer.length() + substCount > 4 && boost::ends_with(buffer, L"er")) { + buffer.resize(buffer.length() - 2); + } else if (buffer[buffer.length() - 1] == L'e') { + buffer.resize(buffer.length() - 1); + } else if (buffer[buffer.length() - 1] == L's') { + buffer.resize(buffer.length() - 1); + } else if (buffer[buffer.length() - 1] == L'n') { + buffer.resize(buffer.length() - 1); + } + // "t" occurs only as suffix of verbs. + else if (buffer[buffer.length() - 1] == L't') { buffer.resize(buffer.length() - 1); - strip(); + } else { + doMore = false; } + } +} - // Additional step for irregular plural nouns like "Matrizen -> Matrix". - if (buffer[buffer.length() - 1] == L'z') - buffer[buffer.length() - 1] = L'x'; +void GermanStemmer::optimize() { + // Additional step for female plurals of professions and inhabitants. + if (buffer.length() > 5 && boost::ends_with(buffer, L"erin*")) { + buffer.resize(buffer.length() - 1); + strip(); } - void GermanStemmer::removeParticleDenotion() - { - if (buffer.length() > 4) - { - for (int32_t c = 0; c < (int32_t)buffer.length() - 3; ++c) - { - if (buffer.substr(c, 4) == L"gege") - { - buffer.erase(c, 2); - return; - } + // Additional step for irregular plural nouns like "Matrizen -> Matrix". + if (buffer[buffer.length() - 1] == L'z') { + buffer[buffer.length() - 1] = L'x'; + } +} + +void GermanStemmer::removeParticleDenotion() { + if (buffer.length() > 4) { + for (int32_t c = 0; c < (int32_t)buffer.length() - 3; ++c) { + if (buffer.substr(c, 4) == L"gege") { + buffer.erase(c, 2); + return; } } } +} - void GermanStemmer::substitute() - { - substCount = 0; - for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) - { - // Replace the second char of a pair of the equal characters with an asterisk - if (c > 0 && buffer[c] == buffer[c - 1]) - buffer[c] = L'*'; - // Substitute Umlauts. - else if (buffer[c] == L'\x00e4') - buffer[c] = L'a'; - else if (buffer[c] == L'\x00f6') - buffer[c] = L'o'; - else if (buffer[c] == L'\x00fc') - buffer[c] = L'u'; - // Fix bug so that 'ß' at the end of a word is replaced. - else if (buffer[c] == L'\x00df') - { - buffer[c] = L's'; - buffer.insert(c + 1, 1, L's'); +void GermanStemmer::substitute() { + substCount = 0; + for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) { + // Replace the second char of a pair of the equal characters with an asterisk + if (c > 0 && buffer[c] == buffer[c - 1]) { + buffer[c] = L'*'; + } + // Substitute Umlauts. + else if (buffer[c] == L'\x00e4') { + buffer[c] = L'a'; + } else if (buffer[c] == L'\x00f6') { + buffer[c] = L'o'; + } else if (buffer[c] == L'\x00fc') { + buffer[c] = L'u'; + } + // Fix bug so that 'ß' at the end of a word is replaced. + else if (buffer[c] == L'\x00df') { + buffer[c] = L's'; + buffer.insert(c + 1, 1, L's'); + ++substCount; + } + // Take care that at least one character is left left side from the current one + if (c < (int32_t)buffer.length() - 1) { + // Masking several common character combinations with an token + if (c < (int32_t)buffer.length() - 2 && buffer[c] == L's' && buffer[c + 1] == L'c' && buffer[c + 2] == L'h') { + buffer[c] = L'$'; + buffer.erase(c + 1, 2); + substCount += 2; + } else if (buffer[c] == L'c' && buffer[c + 1] == L'h') { + buffer[c] = L'\x00a7'; + buffer.erase(c + 1, 1); + ++substCount; + } else if (buffer[c] == L'e' && buffer[c + 1] == L'i') { + buffer[c] = L'%'; + buffer.erase(c + 1, 1); + ++substCount; + } else if (buffer[c] == L'i' && buffer[c + 1] == L'e') { + buffer[c] = L'&'; + buffer.erase(c + 1, 1); + ++substCount; + } else if (buffer[c] == L'i' && buffer[c + 1] == L'g') { + buffer[c] = L'#'; + buffer.erase(c + 1, 1); + ++substCount; + } else if (buffer[c] == L's' && buffer[c + 1] == L't') { + buffer[c] = L'!'; + buffer.erase(c + 1, 1); ++substCount; - } - // Take care that at least one character is left left side from the current one - if (c < (int32_t)buffer.length() - 1) - { - // Masking several common character combinations with an token - if (c < (int32_t)buffer.length() - 2 && buffer[c] == L's' && buffer[c + 1] == L'c' && buffer[c + 2] == L'h') - { - buffer[c] = L'$'; - buffer.erase(c + 1, 2); - substCount += 2; - } - else if (buffer[c] == L'c' && buffer[c + 1] == L'h') - { - buffer[c] = L'\x00a7'; - buffer.erase(c + 1, 1); - ++substCount; - } - else if (buffer[c] == L'e' && buffer[c + 1] == L'i') - { - buffer[c] = L'%'; - buffer.erase(c + 1, 1); - ++substCount; - } - else if (buffer[c] == L'i' && buffer[c + 1] == L'e') - { - buffer[c] = L'&'; - buffer.erase(c + 1, 1); - ++substCount; - } - else if (buffer[c] == L'i' && buffer[c + 1] == L'g') - { - buffer[c] = L'#'; - buffer.erase(c + 1, 1); - ++substCount; - } - else if (buffer[c] == L's' && buffer[c + 1] == L't') - { - buffer[c] = L'!'; - buffer.erase(c + 1, 1); - ++substCount; - } } } } +} - void GermanStemmer::resubstitute() - { - for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) - { - if (buffer[c] == L'*') - buffer[c] = buffer[c - 1]; - else if (buffer[c] == L'$') - { - buffer[c] = L's'; - buffer.insert(c + 1, L"ch"); - } - else if (buffer[c] == L'\x00a7') - { - buffer[c] = L'c'; - buffer.insert(c + 1, 1, L'h'); - } - else if (buffer[c] == L'%') - { - buffer[c] = L'e'; - buffer.insert(c + 1, 1, L'i'); - } - else if (buffer[c] == L'&') - { - buffer[c] = L'i'; - buffer.insert(c + 1, 1, L'e'); - } - else if (buffer[c] == L'#') - { - buffer[c] = L'i'; - buffer.insert(c + 1, 1, L'g'); - } - else if (buffer[c] == L'!') - { - buffer[c] = L's'; - buffer.insert(c + 1, 1, L't'); - } +void GermanStemmer::resubstitute() { + for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) { + if (buffer[c] == L'*') { + buffer[c] = buffer[c - 1]; + } else if (buffer[c] == L'$') { + buffer[c] = L's'; + buffer.insert(c + 1, L"ch"); + } else if (buffer[c] == L'\x00a7') { + buffer[c] = L'c'; + buffer.insert(c + 1, 1, L'h'); + } else if (buffer[c] == L'%') { + buffer[c] = L'e'; + buffer.insert(c + 1, 1, L'i'); + } else if (buffer[c] == L'&') { + buffer[c] = L'i'; + buffer.insert(c + 1, 1, L'e'); + } else if (buffer[c] == L'#') { + buffer[c] = L'i'; + buffer.insert(c + 1, 1, L'g'); + } else if (buffer[c] == L'!') { + buffer[c] = L's'; + buffer.insert(c + 1, 1, L't'); } } } + +} diff --git a/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp b/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp index 74b1c04a..732491dd 100644 --- a/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp @@ -11,107 +11,98 @@ #include "StopFilter.h" #include "StringUtils.h" -namespace Lucene -{ - /// Default Greek stopwords in UTF-8 format. - const uint8_t GreekAnalyzer::_GREEK_STOP_WORDS[] = - { - 0xce, 0xbf, 0x0a, 0xce, 0xb7, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xce, 0xbf, 0xce, 0xb9, 0x0a, - 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x84, 0xce, 0xb7, - 0xcf, 0x83, 0x0a, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xbd, - 0x0a, 0xcf, 0x84, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, - 0xba, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, 0xce, - 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, - 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, - 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x84, 0xce, - 0xb5, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xce, - 0xbd, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0xce, - 0xbd, 0x0a, 0xce, 0xbc, 0xce, 0xb1, 0x0a, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0x0a, - 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbf, 0x0a, 0xce, 0xb3, 0xce, 0xb9, 0xce, 0xb1, 0x0a, 0xcf, 0x80, - 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0x0a, 0xcf, 0x83, 0xce, 0xb5, - 0x0a, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0x0a, 0xce, - 0xb1, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xcf, 0x84, 0xce, 0xb1, - 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb8, 0xce, 0xb1, 0x0a, 0xce, - 0xbd, 0xce, 0xb1, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0xce, 0xbd, 0x0a, - 0xce, 0xbc, 0xce, 0xb7, 0x0a, 0xce, 0xbc, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xb5, 0xcf, 0x80, - 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xbd, 0xcf, 0x89, 0x0a, 0xce, 0xb5, 0xce, 0xb1, 0xce, 0xbd, - 0x0a, 0xce, 0xb1, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xcf, - 0x80, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, - 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb1, - 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, - 0xce, 0xbf, 0xce, 0xb9, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb5, 0xcf, 0x83, 0x0a, - 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, - 0xb9, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, - 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xce, 0xb1, 0xcf, 0x85, - 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xb9, 0x0a, - 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, - 0x84, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb5, - 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb5, 0xce, 0xba, - 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, - 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb7, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, - 0xce, 0xbd, 0xce, 0xbf, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, - 0xbf, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb5, - 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0x0a, - 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, - 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, - 0xce, 0xbf, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xce, 0xbc, 0xcf, 0x89, 0xcf, - 0x83, 0x0a, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xcf, 0x83, 0xce, - 0xbf, 0x0a, 0xce, 0xbf, 0xcf, 0x84, 0xce, 0xb9, 0x0a - }; +namespace Lucene { - GreekAnalyzer::GreekAnalyzer(LuceneVersion::Version matchVersion) - { - this->stopSet = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +/// Default Greek stopwords in UTF-8 format. +const uint8_t GreekAnalyzer::_GREEK_STOP_WORDS[] = { + 0xce, 0xbf, 0x0a, 0xce, 0xb7, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xce, 0xbf, 0xce, 0xb9, 0x0a, + 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x84, 0xce, 0xb7, + 0xcf, 0x83, 0x0a, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xbd, + 0x0a, 0xcf, 0x84, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, + 0xba, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, 0xce, + 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, + 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbc, 0xce, 0xb1, + 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x84, 0xce, + 0xb5, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xce, + 0xbd, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xb7, 0xce, + 0xbd, 0x0a, 0xce, 0xbc, 0xce, 0xb1, 0x0a, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0x0a, + 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbf, 0x0a, 0xce, 0xb3, 0xce, 0xb9, 0xce, 0xb1, 0x0a, 0xcf, 0x80, + 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0x0a, 0xcf, 0x83, 0xce, 0xb5, + 0x0a, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0x0a, 0xce, + 0xb1, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb9, 0x0a, 0xce, 0xba, 0xce, 0xb1, 0xcf, 0x84, 0xce, 0xb1, + 0x0a, 0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb8, 0xce, 0xb1, 0x0a, 0xce, + 0xbd, 0xce, 0xb1, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0x0a, 0xce, 0xb4, 0xce, 0xb5, 0xce, 0xbd, 0x0a, + 0xce, 0xbc, 0xce, 0xb7, 0x0a, 0xce, 0xbc, 0xce, 0xb7, 0xce, 0xbd, 0x0a, 0xce, 0xb5, 0xcf, 0x80, + 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xbd, 0xcf, 0x89, 0x0a, 0xce, 0xb5, 0xce, 0xb1, 0xce, 0xbd, + 0x0a, 0xce, 0xb1, 0xce, 0xbd, 0x0a, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x84, 0xce, 0xb5, 0x0a, 0xcf, + 0x80, 0xce, 0xbf, 0xcf, 0x85, 0x0a, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, + 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb1, + 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, + 0xce, 0xbf, 0xce, 0xb9, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xb5, 0xcf, 0x83, 0x0a, + 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xb9, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xcf, 0x80, 0xce, 0xbf, 0xce, + 0xb9, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, + 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb7, 0x0a, 0xce, 0xb1, 0xcf, 0x85, + 0xcf, 0x84, 0xce, 0xbf, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xbf, 0xce, 0xb9, 0x0a, + 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, + 0x84, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb5, + 0xcf, 0x83, 0x0a, 0xce, 0xb1, 0xcf, 0x85, 0xcf, 0x84, 0xce, 0xb1, 0x0a, 0xce, 0xb5, 0xce, 0xba, + 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, + 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb7, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, + 0xce, 0xbd, 0xce, 0xbf, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, + 0xbf, 0xce, 0xb9, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb5, + 0xcf, 0x83, 0x0a, 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xb1, 0x0a, + 0xce, 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xcf, 0x89, 0xce, 0xbd, 0x0a, 0xce, + 0xb5, 0xce, 0xba, 0xce, 0xb5, 0xce, 0xb9, 0xce, 0xbd, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0x0a, + 0xce, 0xbf, 0xcf, 0x80, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xce, 0xbc, 0xcf, 0x89, 0xcf, + 0x83, 0x0a, 0xce, 0xb9, 0xcf, 0x83, 0xcf, 0x89, 0xcf, 0x83, 0x0a, 0xce, 0xbf, 0xcf, 0x83, 0xce, + 0xbf, 0x0a, 0xce, 0xbf, 0xcf, 0x84, 0xce, 0xb9, 0x0a +}; - GreekAnalyzer::GreekAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stopSet = stopwords; - this->matchVersion = matchVersion; - } +GreekAnalyzer::GreekAnalyzer(LuceneVersion::Version matchVersion) { + this->stopSet = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - GreekAnalyzer::~GreekAnalyzer() - { - } +GreekAnalyzer::GreekAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stopSet = stopwords; + this->matchVersion = matchVersion; +} - const HashSet GreekAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - { - String stopWords(UTF8_TO_STRING(_GREEK_STOP_WORDS)); - Collection words(StringUtils::split(stopWords, L"\n")); - stopSet = HashSet::newInstance(words.begin(), words.end()); - } - return stopSet; - } +GreekAnalyzer::~GreekAnalyzer() { +} - TokenStreamPtr GreekAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(matchVersion, reader); - result = newLucene(result); - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); - return result; +const HashSet GreekAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + String stopWords(UTF8_TO_STRING(_GREEK_STOP_WORDS)); + Collection words(StringUtils::split(stopWords, L"\n")); + stopSet = HashSet::newInstance(words.begin(), words.end()); } + return stopSet; +} - TokenStreamPtr GreekAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - GreekAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(matchVersion, reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr GreekAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(matchVersion, reader); + result = newLucene(result); + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); + return result; +} - GreekAnalyzerSavedStreams::~GreekAnalyzerSavedStreams() - { +TokenStreamPtr GreekAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + GreekAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(matchVersion, reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +GreekAnalyzerSavedStreams::~GreekAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp b/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp index 61771c3c..af9ca45c 100644 --- a/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/el/GreekLowerCaseFilter.cpp @@ -9,85 +9,81 @@ #include "TermAttribute.h" #include "CharFolder.h" -namespace Lucene -{ - GreekLowerCaseFilter::GreekLowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - termAtt = addAttribute(); - } +namespace Lucene { - GreekLowerCaseFilter::~GreekLowerCaseFilter() - { - } +GreekLowerCaseFilter::GreekLowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) { + termAtt = addAttribute(); +} - bool GreekLowerCaseFilter::incrementToken() - { - if (input->incrementToken()) - { - wchar_t* chArray = termAtt->termBufferArray(); - int32_t chLen = termAtt->termLength(); +GreekLowerCaseFilter::~GreekLowerCaseFilter() { +} - for (int32_t i = 0; i < chLen; ++i) - chArray[i] = lowerCase(chArray[i]); +bool GreekLowerCaseFilter::incrementToken() { + if (input->incrementToken()) { + wchar_t* chArray = termAtt->termBufferArray(); + int32_t chLen = termAtt->termLength(); - return true; + for (int32_t i = 0; i < chLen; ++i) { + chArray[i] = lowerCase(chArray[i]); } - else - return false; + + return true; + } else { + return false; } +} - wchar_t GreekLowerCaseFilter::lowerCase(wchar_t codepoint) - { - switch (codepoint) - { - case L'\x03c2': // small final sigma - return 0x03c3; // small sigma - - // Some Greek characters contain diacritics. - // This filter removes these, converting to the lowercase base form. - - case L'\x0386': // capital alpha with tonos - case L'\x03ac': // small alpha with tonos - return L'\x03b1'; // small alpha - - case L'\x0388': // capital epsilon with tonos - case L'\x03ad': // small epsilon with tonos - return L'\x03b5'; // small epsilon - - case L'\x0389': // capital eta with tonos - case L'\x03ae': // small eta with tonos - return L'\x03b7'; // small eta - - case L'\x038a': // capital iota with tonos - case L'\x03aa': // capital iota with dialytika - case L'\x03af': // small iota with tonos - case L'\x03ca': // small iota with dialytika - case L'\x0390': // small iota with dialytika and tonos - return L'\x03b9'; // small iota - - case L'\x038e': // capital upsilon with tonos - case L'\x03ab': // capital upsilon with dialytika - case L'\x03cd': // small upsilon with tonos - case L'\x03cb': // small upsilon with dialytika - case L'\x03b0': // small upsilon with dialytika and tonos - return L'\x03c5'; // small upsilon - - case L'\x038c': // capital omicron with tonos - case L'\x03cc': // small omicron with tonos - return L'\x03bf'; // small omicron - - case L'\x038f': // capital omega with tonos - case L'\x03ce': // small omega with tonos - return L'\x03c9'; // small omega - - // The previous implementation did the conversion below. - // Only implemented for backwards compatibility with old indexes. - - case L'\x03a2': // reserved - return L'\x03c2'; // small final sigma - - default: - return CharFolder::toLower(codepoint); - } +wchar_t GreekLowerCaseFilter::lowerCase(wchar_t codepoint) { + switch (codepoint) { + case L'\x03c2': // small final sigma + return 0x03c3; // small sigma + + // Some Greek characters contain diacritics. + // This filter removes these, converting to the lowercase base form. + + case L'\x0386': // capital alpha with tonos + case L'\x03ac': // small alpha with tonos + return L'\x03b1'; // small alpha + + case L'\x0388': // capital epsilon with tonos + case L'\x03ad': // small epsilon with tonos + return L'\x03b5'; // small epsilon + + case L'\x0389': // capital eta with tonos + case L'\x03ae': // small eta with tonos + return L'\x03b7'; // small eta + + case L'\x038a': // capital iota with tonos + case L'\x03aa': // capital iota with dialytika + case L'\x03af': // small iota with tonos + case L'\x03ca': // small iota with dialytika + case L'\x0390': // small iota with dialytika and tonos + return L'\x03b9'; // small iota + + case L'\x038e': // capital upsilon with tonos + case L'\x03ab': // capital upsilon with dialytika + case L'\x03cd': // small upsilon with tonos + case L'\x03cb': // small upsilon with dialytika + case L'\x03b0': // small upsilon with dialytika and tonos + return L'\x03c5'; // small upsilon + + case L'\x038c': // capital omicron with tonos + case L'\x03cc': // small omicron with tonos + return L'\x03bf'; // small omicron + + case L'\x038f': // capital omega with tonos + case L'\x03ce': // small omega with tonos + return L'\x03c9'; // small omega + + // The previous implementation did the conversion below. + // Only implemented for backwards compatibility with old indexes. + + case L'\x03a2': // reserved + return L'\x03c2'; // small final sigma + + default: + return CharFolder::toLower(codepoint); } } + +} diff --git a/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp index 0d26d9ba..97b02aae 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp @@ -13,245 +13,236 @@ #include "PersianNormalizationFilter.h" #include "StringUtils.h" -namespace Lucene -{ - /// Default Persian stopwords in UTF-8 format. - /// - /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html - /// The stopword list is BSD-Licensed. - const uint8_t PersianAnalyzer::DEFAULT_STOPWORD_FILE[] = - { - 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, - 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xb1, - 0x0a, 0xd8, 0xae, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xb4, - 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x83, - 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, 0xaa, 0xd8, - 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x85, 0x0a, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, - 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x88, 0x0a, - 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, 0xd8, - 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, - 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0xda, 0xaf, 0xd8, 0xb2, 0x0a, 0xd9, 0xbe, 0xd9, - 0x86, 0xd8, 0xac, 0x0a, 0xd9, 0x86, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, - 0x85, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, - 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd8, 0xb7, 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, - 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, - 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xda, - 0x86, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, - 0xb7, 0x0a, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x82, - 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb1, 0xd9, 0x81, - 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, 0x86, - 0xd9, 0x86, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x87, 0xd8, 0xb2, - 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, - 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, - 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, - 0xd8, 0xb1, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, - 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, - 0x86, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, - 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, - 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x88, 0xd9, - 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, - 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, 0xd8, 0xac, 0xd8, 0xb2, - 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd8, 0xaf, - 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xaa, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, - 0xd8, 0xb1, 0xd8, 0xae, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, - 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd9, - 0x84, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd9, 0x82, - 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd9, 0x88, - 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, - 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xb8, 0xd9, 0x8a, 0xd8, - 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, - 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, - 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, - 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, - 0xb4, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, - 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, - 0xd8, 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, - 0xda, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, - 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x83, - 0xd8, 0xac, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, - 0xaf, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, - 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, - 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, - 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd8, 0xa7, 0x0a, - 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xda, - 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, - 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd9, 0x86, - 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, - 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, - 0x0a, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, - 0x86, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd8, - 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaf, - 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xab, - 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, - 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, - 0xaa, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, - 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb3, - 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, - 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb6, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, - 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, - 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, - 0xd9, 0x88, 0x0a, 0xd8, 0xac, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, - 0xd9, 0x88, 0xd9, 0x84, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, - 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, - 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, 0xd8, 0xaf, 0xd8, - 0xaa, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, - 0xa7, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0x0a, 0xd8, - 0xaa, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, - 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, - 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd9, - 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xaf, - 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, - 0xd9, 0x85, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, - 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xb5, 0xd8, 0xaf, 0x0a, 0xd9, - 0x81, 0xd9, 0x82, 0xd8, 0xb7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x8a, - 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, - 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, - 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xb7, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x85, 0x0a, - 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, - 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, - 0x81, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, - 0x83, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, - 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb7, - 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, - 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, - 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, 0xd9, - 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb7, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, - 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb2, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, - 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, - 0xb4, 0xd8, 0xaa, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xd8, 0xb7, 0xd8, 0xb1, 0xd9, - 0x8a, 0xd9, 0x82, 0x0a, 0xd8, 0xa7, 0xd8, 0xb4, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, - 0xaa, 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, - 0x8a, 0xd8, 0xaf, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, - 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, - 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, - 0xa7, 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, - 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, - 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, - 0xaf, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, - 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, - 0x87, 0xd9, 0x85, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0xbe, 0xd8, 0xa7, - 0xd8, 0xb9, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0x0a, 0xd8, 0xad, 0xd8, 0xaf, - 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x81, 0x0a, - 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, - 0xb2, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, - 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xb6, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, - 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, - 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, - 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xb3, 0xd9, 0x8a, - 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xae, - 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xda, 0x86, 0xd9, 0x88, 0xd9, - 0x86, 0x0a, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xac, 0x0a, 0xd8, 0xb4, 0xd8, 0xb4, 0x0a, - 0xd9, 0x87, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaa, 0x0a, - 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, - 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x83, 0xd8, - 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0xbe, 0xd9, - 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd9, - 0x88, 0xd8, 0xb2, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, - 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, - 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x88, - 0xd9, 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xda, 0x86, 0xd9, 0x86, - 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, - 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, - 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xaf, - 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0x0a, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaf, - 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd8, 0xaa, 0xd9, 0x8a, - 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, - 0xd9, 0x82, 0xd8, 0xa8, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, - 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, - 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x87, 0x0a, - 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, - 0xd9, 0x85, 0xd8, 0xab, 0xd9, 0x84, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, - 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, - 0xd9, 0x87, 0x0a, 0xd8, 0xb7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, - 0x0a, 0xd8, 0xa7, 0xda, 0xaf, 0xd8, 0xb1, 0x0a, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaa, - 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, - 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, - 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, - 0x86, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, - 0x0a, 0xd9, 0x84, 0xd8, 0xb7, 0xd9, 0x81, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, - 0xaf, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd9, 0x86, - 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x8a, - 0xd9, 0x86, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, - 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd8, - 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, - 0x87, 0xd9, 0x85, 0x0a, 0xd9, 0x81, 0xd9, 0x88, 0xd9, 0x82, 0x0a, 0xd9, 0x86, 0xd9, 0x87, 0x0a, - 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x88, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, - 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, - 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd9, 0x84, 0x0a, - 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd9, - 0x87, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, - 0x85, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, - 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x83, 0xd9, - 0x86, 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, - 0xb2, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, - 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd9, 0x84, 0xd9, - 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, - 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0x0a - }; +namespace Lucene { - PersianAnalyzer::PersianAnalyzer(LuceneVersion::Version matchVersion) - { - this->stoptable = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +/// Default Persian stopwords in UTF-8 format. +/// +/// Generated from http://members.unine.ch/jacques.savoy/clef/index.html +/// The stopword list is BSD-Licensed. +const uint8_t PersianAnalyzer::DEFAULT_STOPWORD_FILE[] = { + 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, + 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xb1, + 0x0a, 0xd8, 0xae, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xb4, + 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x83, + 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, 0xaa, 0xd8, + 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x85, 0x0a, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, + 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0x0a, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x88, 0x0a, + 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, 0xd8, + 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0xbe, 0xd8, 0xb3, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, + 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0xda, 0xaf, 0xd8, 0xb2, 0x0a, 0xd9, 0xbe, 0xd9, + 0x86, 0xd8, 0xac, 0x0a, 0xd9, 0x86, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x84, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, + 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x87, 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, + 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd8, 0xb7, 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, + 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0x0a, 0xd8, 0xaf, 0xd9, 0x88, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, + 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x8a, 0x0a, 0xda, + 0x86, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, + 0xb7, 0x0a, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x82, + 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb1, 0xd9, 0x81, + 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, 0x86, + 0xd9, 0x86, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x87, 0xd8, 0xb2, + 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, + 0xd9, 0x8a, 0x0a, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, + 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, + 0xd8, 0xb1, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, + 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, + 0x86, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x86, + 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, + 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x88, 0xd9, + 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, + 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, 0xd8, 0xac, 0xd8, 0xb2, + 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, + 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x84, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd8, 0xaf, + 0xd9, 0x85, 0xd8, 0xa7, 0xd8, 0xaa, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, + 0xd8, 0xb1, 0xd8, 0xae, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, + 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd9, + 0x84, 0xd9, 0x88, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd9, 0x82, + 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd9, 0x88, + 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, + 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xb8, 0xd9, 0x8a, 0xd8, + 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, + 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, + 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, + 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, + 0xb4, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, + 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x8a, + 0xd8, 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd9, 0x87, 0xd9, 0x8a, + 0xda, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, + 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x85, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x83, + 0xd8, 0xac, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, + 0xaf, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, + 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, + 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, + 0xaf, 0x0a, 0xd8, 0xb3, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd8, 0xa7, 0x0a, + 0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xda, + 0xaf, 0xd8, 0xb1, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, + 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd9, 0x87, 0xd9, 0x86, + 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, + 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd9, 0x86, 0xda, 0xaf, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, + 0x0a, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xaa, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, + 0x86, 0xda, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd8, 0xaf, 0xd8, + 0xa7, 0xd8, 0xaf, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xaf, + 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xab, + 0xd8, 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x87, + 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0xd8, + 0xaa, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa8, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, + 0xa8, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb3, + 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, + 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xb6, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd8, 0xb1, + 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x8a, + 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x8a, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, + 0xd9, 0x88, 0x0a, 0xd8, 0xac, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, + 0xd9, 0x88, 0xd9, 0x84, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, + 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xb1, 0x0a, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd9, 0x85, 0xd8, 0xaf, 0xd8, + 0xaa, 0xd9, 0x8a, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, + 0xa7, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0x0a, 0xd8, + 0xaa, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xac, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, + 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, + 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x86, 0x0a, 0xd9, + 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xaf, + 0x0a, 0xd9, 0x83, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, + 0xd9, 0x85, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, + 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xb5, 0xd8, 0xaf, 0x0a, 0xd9, + 0x81, 0xd9, 0x82, 0xd8, 0xb7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x8a, + 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, 0xaf, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, 0xa7, + 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, + 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xb7, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x85, 0x0a, + 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x85, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, + 0xaf, 0x0a, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, + 0x81, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb4, 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd9, + 0x83, 0xd9, 0x86, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, + 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd8, 0xb7, + 0xd9, 0x88, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, + 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, + 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd9, 0x86, 0xd8, 0xb2, 0xd8, 0xaf, 0xd9, + 0x8a, 0xd9, 0x83, 0x0a, 0xd8, 0xb7, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, + 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb2, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x87, 0xd8, 0xa7, 0x0a, + 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, + 0xb4, 0xd8, 0xaa, 0x0a, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xd8, 0xb7, 0xd8, 0xb1, 0xd9, + 0x8a, 0xd9, 0x82, 0x0a, 0xd8, 0xa7, 0xd8, 0xb4, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, + 0xaa, 0x0a, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0x0a, 0xd9, 0x86, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, + 0x8a, 0xd8, 0xaf, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0x0a, 0xda, 0x86, 0xd9, 0x86, 0xd8, + 0xaf, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, + 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, + 0xa7, 0xd9, 0x8a, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, + 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xaf, 0x0a, 0xd8, 0xaa, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, + 0xd8, 0xa7, 0xd9, 0x8a, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xda, + 0xaf, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, + 0xa7, 0xd9, 0x8a, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, + 0x87, 0xd9, 0x85, 0xda, 0x86, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0xbe, 0xd8, 0xa7, + 0xd8, 0xb9, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd8, 0xb3, 0x0a, 0xd8, 0xad, 0xd8, 0xaf, + 0xd9, 0x88, 0xd8, 0xaf, 0x0a, 0xd9, 0x85, 0xd8, 0xae, 0xd8, 0xaa, 0xd9, 0x84, 0xd9, 0x81, 0x0a, + 0xd9, 0x85, 0xd9, 0x82, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xda, 0x86, 0xd9, 0x8a, 0xd8, + 0xb2, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd9, 0x86, 0xd8, 0xaf, 0xd8, + 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, 0xb6, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xda, + 0x86, 0xd9, 0x88, 0xd9, 0x86, 0x0a, 0xd8, 0xb3, 0xd8, 0xa7, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, + 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0x0a, 0xd8, + 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd8, 0xb1, 0xd8, 0xb3, 0xd9, 0x8a, + 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xae, + 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xda, 0x86, 0xd9, 0x88, 0xd9, + 0x86, 0x0a, 0xd8, 0xae, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xac, 0x0a, 0xd8, 0xb4, 0xd8, 0xb4, 0x0a, + 0xd9, 0x87, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd8, 0xaa, 0xd8, 0xad, 0xd8, 0xaa, 0x0a, + 0xd8, 0xb6, 0xd9, 0x85, 0xd9, 0x86, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, 0x8a, 0xd9, + 0x85, 0x0a, 0xda, 0xaf, 0xd9, 0x81, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, 0x81, 0xd9, 0x83, 0xd8, + 0xb1, 0x0a, 0xd8, 0xa8, 0xd8, 0xb3, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0xbe, 0xd9, + 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xb1, 0xd9, + 0x88, 0xd8, 0xb2, 0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, + 0xd9, 0x87, 0x0a, 0xd9, 0x86, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x0a, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x84, 0x0a, 0xd9, 0x88, + 0xd9, 0x82, 0xd8, 0xaa, 0xd9, 0x8a, 0x0a, 0xd9, 0x83, 0xd9, 0x8a, 0x0a, 0xda, 0x86, 0xd9, 0x86, + 0xd9, 0x8a, 0xd9, 0x86, 0x0a, 0xd9, 0x83, 0xd9, 0x87, 0x0a, 0xda, 0xaf, 0xd9, 0x8a, 0xd8, 0xb1, + 0xd9, 0x8a, 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, 0xd8, 0xa7, 0xd8, 0xb3, + 0xd8, 0xaa, 0x0a, 0xd9, 0x83, 0xd8, 0xac, 0xd8, 0xa7, 0x0a, 0xd9, 0x83, 0xd9, 0x86, 0xd8, 0xaf, + 0x0a, 0xd9, 0x86, 0xd9, 0x8a, 0xd8, 0xb2, 0x0a, 0xd9, 0x8a, 0xd8, 0xa7, 0xd8, 0xa8, 0xd8, 0xaf, + 0x0a, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x8a, 0x0a, 0xd8, 0xad, 0xd8, 0xaa, 0xd9, 0x8a, + 0x0a, 0xd8, 0xaa, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb9, + 0xd9, 0x82, 0xd8, 0xa8, 0x0a, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa, 0x0a, + 0xd9, 0x83, 0xd9, 0x86, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x86, 0x0a, + 0xd8, 0xaa, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x87, 0x0a, + 0xd9, 0x85, 0xd8, 0xa7, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, + 0xd9, 0x85, 0xd8, 0xab, 0xd9, 0x84, 0x0a, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, 0xd8, 0xb1, + 0xd9, 0x87, 0x0a, 0xd8, 0xb7, 0xd8, 0xa8, 0xd9, 0x82, 0x0a, 0xd8, 0xa8, 0xd8, 0xb9, 0xd8, 0xaf, + 0x0a, 0xd8, 0xa7, 0xda, 0xaf, 0xd8, 0xb1, 0x0a, 0xd8, 0xb5, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaa, + 0x0a, 0xd8, 0xba, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd8, + 0xa8, 0xd9, 0x8a, 0xd8, 0xb4, 0x0a, 0xd8, 0xb1, 0xd9, 0x8a, 0xd8, 0xb2, 0xd9, 0x8a, 0x0a, 0xd8, + 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xda, + 0x86, 0xda, 0xaf, 0xd9, 0x88, 0xd9, 0x86, 0xd9, 0x87, 0x0a, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, + 0x0a, 0xd9, 0x84, 0xd8, 0xb7, 0xd9, 0x81, 0xd8, 0xa7, 0x0a, 0xd9, 0x85, 0xd9, 0x8a, 0x0a, 0xd8, + 0xaf, 0xd8, 0xb1, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x85, 0xd9, 0x86, + 0x0a, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xaf, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x8a, + 0xd9, 0x86, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xa8, + 0xd8, 0xb1, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x84, 0xd8, + 0xaa, 0x0a, 0xda, 0xaf, 0xd8, 0xb0, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87, 0x0a, 0xd9, + 0x87, 0xd9, 0x85, 0x0a, 0xd9, 0x81, 0xd9, 0x88, 0xd9, 0x82, 0x0a, 0xd9, 0x86, 0xd9, 0x87, 0x0a, + 0xd9, 0x87, 0xd8, 0xa7, 0x0a, 0xd8, 0xb4, 0xd9, 0x88, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xa7, + 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xaf, 0x0a, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, + 0xb1, 0xd9, 0x87, 0x0a, 0xd9, 0x87, 0xd8, 0xb1, 0x0a, 0xd8, 0xa7, 0xd9, 0x88, 0xd9, 0x84, 0x0a, + 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd9, 0x86, 0xd8, 0xaf, 0x0a, 0xda, 0x86, 0xd9, + 0x87, 0xd8, 0xa7, 0xd8, 0xb1, 0x0a, 0xd9, 0x86, 0xd8, 0xa7, 0xd9, 0x85, 0x0a, 0xd8, 0xa7, 0xd9, + 0x85, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xb2, 0x0a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd9, + 0x87, 0xd8, 0xa7, 0xd9, 0x8a, 0x0a, 0xd9, 0x82, 0xd8, 0xa8, 0xd9, 0x84, 0x0a, 0xd9, 0x83, 0xd9, + 0x86, 0xd9, 0x85, 0x0a, 0xd8, 0xb3, 0xd8, 0xb9, 0xd9, 0x8a, 0x0a, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, + 0xb2, 0xd9, 0x87, 0x0a, 0xd8, 0xb1, 0xd8, 0xa7, 0x0a, 0xd9, 0x87, 0xd8, 0xb3, 0xd8, 0xaa, 0xd9, + 0x86, 0xd8, 0xaf, 0x0a, 0xd8, 0xb2, 0xd9, 0x8a, 0xd8, 0xb1, 0x0a, 0xd8, 0xac, 0xd9, 0x84, 0xd9, + 0x88, 0xd9, 0x8a, 0x0a, 0xd8, 0xb9, 0xd9, 0x86, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x86, 0x0a, 0xd8, + 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0x0a +}; - PersianAnalyzer::PersianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stoptable = stopwords; - this->matchVersion = matchVersion; - } +PersianAnalyzer::PersianAnalyzer(LuceneVersion::Version matchVersion) { + this->stoptable = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - PersianAnalyzer::~PersianAnalyzer() - { - } +PersianAnalyzer::PersianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stoptable = stopwords; + this->matchVersion = matchVersion; +} + +PersianAnalyzer::~PersianAnalyzer() { +} - const HashSet PersianAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - { - String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE)); - Collection words(StringUtils::split(stopWords, L"\n")); - stopSet = HashSet::newInstance(words.begin(), words.end()); - } - return stopSet; +const HashSet PersianAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE)); + Collection words(StringUtils::split(stopWords, L"\n")); + stopSet = HashSet::newInstance(words.begin(), words.end()); } + return stopSet; +} + +TokenStreamPtr PersianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(reader); + result = newLucene(result); + result = newLucene(result); + // additional Persian-specific normalization + result = newLucene(result); + // the order here is important: the stopword list is not normalized + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); + return result; +} - TokenStreamPtr PersianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(reader); - result = newLucene(result); - result = newLucene(result); +TokenStreamPtr PersianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + PersianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(streams->result); // additional Persian-specific normalization - result = newLucene(result); - // the order here is important: the stopword list is not normalized - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); - return result; + streams->result = newLucene(streams->result); + // the order here is important: the stopword list is not normalized + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} - TokenStreamPtr PersianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - PersianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(streams->result); - // additional Persian-specific normalization - streams->result = newLucene(streams->result); - // the order here is important: the stopword list is not normalized - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +PersianAnalyzerSavedStreams::~PersianAnalyzerSavedStreams() { +} - PersianAnalyzerSavedStreams::~PersianAnalyzerSavedStreams() - { - } } diff --git a/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp b/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp index c5ef30b1..1510376d 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianNormalizationFilter.cpp @@ -9,27 +9,24 @@ #include "PersianNormalizer.h" #include "TermAttribute.h" -namespace Lucene -{ - PersianNormalizationFilter::PersianNormalizationFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - normalizer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - PersianNormalizationFilter::~PersianNormalizationFilter() - { - } +PersianNormalizationFilter::PersianNormalizationFilter(const TokenStreamPtr& input) : TokenFilter(input) { + normalizer = newLucene(); + termAtt = addAttribute(); +} - bool PersianNormalizationFilter::incrementToken() - { - if (input->incrementToken()) - { - int32_t newlen = normalizer->normalize(termAtt->termBuffer().get(), termAtt->termLength()); - termAtt->setTermLength(newlen); - return true; - } - else - return false; +PersianNormalizationFilter::~PersianNormalizationFilter() { +} + +bool PersianNormalizationFilter::incrementToken() { + if (input->incrementToken()) { + int32_t newlen = normalizer->normalize(termAtt->termBuffer().get(), termAtt->termLength()); + termAtt->setTermLength(newlen); + return true; + } else { + return false; } } + +} diff --git a/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp b/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp index b0883b88..d65512f2 100644 --- a/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp +++ b/src/contrib/analyzers/common/analysis/fa/PersianNormalizer.cpp @@ -8,53 +8,50 @@ #include "PersianNormalizer.h" #include "MiscUtils.h" -namespace Lucene -{ - const wchar_t PersianNormalizer::YEH = (wchar_t)0x064a; - const wchar_t PersianNormalizer::FARSI_YEH = (wchar_t)0x06cc; - const wchar_t PersianNormalizer::YEH_BARREE = (wchar_t)0x06d2; - const wchar_t PersianNormalizer::KEHEH = (wchar_t)0x06a9; - const wchar_t PersianNormalizer::KAF = (wchar_t)0x0643; - const wchar_t PersianNormalizer::HAMZA_ABOVE = (wchar_t)0x0654; - const wchar_t PersianNormalizer::HEH_YEH = (wchar_t)0x06c0; - const wchar_t PersianNormalizer::HEH_GOAL = (wchar_t)0x06c1; - const wchar_t PersianNormalizer::HEH = (wchar_t)0x0647; +namespace Lucene { - PersianNormalizer::~PersianNormalizer() - { - } +const wchar_t PersianNormalizer::YEH = (wchar_t)0x064a; +const wchar_t PersianNormalizer::FARSI_YEH = (wchar_t)0x06cc; +const wchar_t PersianNormalizer::YEH_BARREE = (wchar_t)0x06d2; +const wchar_t PersianNormalizer::KEHEH = (wchar_t)0x06a9; +const wchar_t PersianNormalizer::KAF = (wchar_t)0x0643; +const wchar_t PersianNormalizer::HAMZA_ABOVE = (wchar_t)0x0654; +const wchar_t PersianNormalizer::HEH_YEH = (wchar_t)0x06c0; +const wchar_t PersianNormalizer::HEH_GOAL = (wchar_t)0x06c1; +const wchar_t PersianNormalizer::HEH = (wchar_t)0x0647; + +PersianNormalizer::~PersianNormalizer() { +} - int32_t PersianNormalizer::normalize(wchar_t* s, int32_t len) - { - for (int32_t i = 0; i < len; ++i) - { - switch (s[i]) - { - case FARSI_YEH: - case YEH_BARREE: - s[i] = YEH; - break; - case KEHEH: - s[i] = KAF; - break; - case HEH_YEH: - case HEH_GOAL: - s[i] = HEH; - break; - case HAMZA_ABOVE: // necessary for HEH + HAMZA - len = deleteChar(s, i--, len); - break; - default: - break; - } +int32_t PersianNormalizer::normalize(wchar_t* s, int32_t len) { + for (int32_t i = 0; i < len; ++i) { + switch (s[i]) { + case FARSI_YEH: + case YEH_BARREE: + s[i] = YEH; + break; + case KEHEH: + s[i] = KAF; + break; + case HEH_YEH: + case HEH_GOAL: + s[i] = HEH; + break; + case HAMZA_ABOVE: // necessary for HEH + HAMZA + len = deleteChar(s, i--, len); + break; + default: + break; } - return len; } + return len; +} - int32_t PersianNormalizer::deleteChar(wchar_t* s, int32_t pos, int32_t len) - { - if (pos < len) - MiscUtils::arrayCopy(s, pos + 1, s, pos, len - pos - 1); - return len - 1; +int32_t PersianNormalizer::deleteChar(wchar_t* s, int32_t pos, int32_t len) { + if (pos < len) { + MiscUtils::arrayCopy(s, pos + 1, s, pos, len - pos - 1); } + return len - 1; +} + } diff --git a/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp b/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp index b3c33b2b..7d0b7566 100644 --- a/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fr/ElisionFilter.cpp @@ -9,59 +9,52 @@ #include "CharArraySet.h" #include "TermAttribute.h" -namespace Lucene -{ - const wchar_t ElisionFilter::apostrophes[] = {L'\'', L'\x2019'}; +namespace Lucene { - ElisionFilter::ElisionFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - articles = newLucene(newCollection(L"l", L"m", L"t", L"qu", L"n", L"s", L"j"), true); - termAtt = addAttribute(); - } +const wchar_t ElisionFilter::apostrophes[] = {L'\'', L'\x2019'}; - ElisionFilter::ElisionFilter(const TokenStreamPtr& input, HashSet articles) : TokenFilter(input) - { - setArticles(articles); - termAtt = addAttribute(); - } +ElisionFilter::ElisionFilter(const TokenStreamPtr& input) : TokenFilter(input) { + articles = newLucene(newCollection(L"l", L"m", L"t", L"qu", L"n", L"s", L"j"), true); + termAtt = addAttribute(); +} - ElisionFilter::~ElisionFilter() - { - } +ElisionFilter::ElisionFilter(const TokenStreamPtr& input, HashSet articles) : TokenFilter(input) { + setArticles(articles); + termAtt = addAttribute(); +} - void ElisionFilter::setArticles(HashSet articles) - { - this->articles = newLucene(articles, true); - } +ElisionFilter::~ElisionFilter() { +} - bool ElisionFilter::incrementToken() - { - if (input->incrementToken()) - { - wchar_t* termBuffer = termAtt->termBufferArray(); - int32_t termLength = termAtt->termLength(); +void ElisionFilter::setArticles(HashSet articles) { + this->articles = newLucene(articles, true); +} - int32_t minPoz = INT_MAX; - for (int32_t i = 0; i < SIZEOF_ARRAY(apostrophes); ++i) - { - wchar_t apos = apostrophes[i]; - for (int32_t poz = 0; poz < termLength; ++poz) - { - if (termBuffer[poz] == apos) - { - minPoz = std::min(poz, minPoz); - break; - } +bool ElisionFilter::incrementToken() { + if (input->incrementToken()) { + wchar_t* termBuffer = termAtt->termBufferArray(); + int32_t termLength = termAtt->termLength(); + + int32_t minPoz = INT_MAX; + for (int32_t i = 0; i < SIZEOF_ARRAY(apostrophes); ++i) { + wchar_t apos = apostrophes[i]; + for (int32_t poz = 0; poz < termLength; ++poz) { + if (termBuffer[poz] == apos) { + minPoz = std::min(poz, minPoz); + break; } } + } - // An apostrophe has been found. If the prefix is an article strip it off. - if (minPoz != INT_MAX && articles->contains(termBuffer, 0, minPoz)) - termAtt->setTermBuffer(termBuffer, minPoz + 1, termLength - (minPoz + 1)); - - return true; + // An apostrophe has been found. If the prefix is an article strip it off. + if (minPoz != INT_MAX && articles->contains(termBuffer, 0, minPoz)) { + termAtt->setTermBuffer(termBuffer, minPoz + 1, termLength - (minPoz + 1)); } - else - return false; + + return true; + } else { + return false; } } + +} diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp index 3d95f658..b14d09db 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp @@ -12,103 +12,94 @@ #include "StopFilter.h" #include "FrenchStemFilter.h" -namespace Lucene -{ - const wchar_t* FrenchAnalyzer::_FRENCH_STOP_WORDS[] = - { - L"a", L"afin", L"ai", L"ainsi", L"apr\x00e8s", L"attendu", L"au", L"aujourd", L"auquel", L"aussi", - L"autre", L"autres", L"aux", L"auxquelles", L"auxquels", L"avait", L"avant", L"avec", L"avoir", - L"c", L"car", L"ce", L"ceci", L"cela", L"celle", L"celles", L"celui", L"cependant", L"certain", - L"certaine", L"certaines", L"certains", L"ces", L"cet", L"cette", L"ceux", L"chez", L"ci", - L"combien", L"comme", L"comment", L"concernant", L"contre", L"d", L"dans", L"de", L"debout", - L"dedans", L"dehors", L"del\x00e0", L"depuis", L"derri\x00e8re", L"des", L"d\x00e9sormais", - L"desquelles", L"desquels", L"dessous", L"dessus", L"devant", L"devers", L"devra", L"divers", - L"diverse", L"diverses", L"doit", L"donc", L"dont", L"du", L"duquel", L"durant", L"d\x00e8s", - L"elle", L"elles", L"en", L"entre", L"environ", L"est", L"et", L"etc", L"etre", L"eu", L"eux", - L"except\x00e9", L"hormis", L"hors", L"h\x00e9las", L"hui", L"il", L"ils", L"j", L"je", L"jusqu", - L"jusque", L"l", L"la", L"laquelle", L"le", L"lequel", L"les", L"lesquelles", L"lesquels", L"leur", - L"leurs", L"lorsque", L"lui", L"l\x00e0", L"ma", L"mais", L"malgr\x00e9", L"me", L"merci", L"mes", - L"mien", L"mienne", L"miennes", L"miens", L"moi", L"moins", L"mon", L"moyennant", L"m\x00eame", - L"m\x00eames", L"n", L"ne", L"ni", L"non", L"nos", L"notre", L"nous", L"n\x00e9anmoins", - L"n\x00f4tre", L"n\x00f4tres", L"on", L"ont", L"ou", L"outre", L"o\x00f9", L"par", L"parmi", - L"partant", L"pas", L"pass\x00e9", L"pendant", L"plein", L"plus", L"plusieurs", L"pour", L"pourquoi", - L"proche", L"pr\x00e8s", L"puisque", L"qu", L"quand", L"que", L"quel", L"quelle", L"quelles", - L"quels", L"qui", L"quoi", L"quoique", L"revoici", L"revoil\x00e0", L"s", L"sa", L"sans", L"sauf", - L"se", L"selon", L"seront", L"ses", L"si", L"sien", L"sienne", L"siennes", L"siens", L"sinon", - L"soi", L"soit", L"son", L"sont", L"sous", L"suivant", L"sur", L"ta", L"te", L"tes", L"tien", - L"tienne", L"tiennes", L"tiens", L"toi", L"ton", L"tous", L"tout", L"toute", L"toutes", L"tu", L"un", - L"une", L"va", L"vers", L"voici", L"voil\x00e0", L"vos", L"votre", L"vous", L"vu", L"v\x00f4tre", - L"v\x00f4tres", L"y", L"\x00e0", L"\x00e7a", L"\x00e8s", L"\x00e9t\x00e9", L"\x00eatre", L"\x00f4" - }; +namespace Lucene { - FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion) - { - this->stoptable = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +const wchar_t* FrenchAnalyzer::_FRENCH_STOP_WORDS[] = { + L"a", L"afin", L"ai", L"ainsi", L"apr\x00e8s", L"attendu", L"au", L"aujourd", L"auquel", L"aussi", + L"autre", L"autres", L"aux", L"auxquelles", L"auxquels", L"avait", L"avant", L"avec", L"avoir", + L"c", L"car", L"ce", L"ceci", L"cela", L"celle", L"celles", L"celui", L"cependant", L"certain", + L"certaine", L"certaines", L"certains", L"ces", L"cet", L"cette", L"ceux", L"chez", L"ci", + L"combien", L"comme", L"comment", L"concernant", L"contre", L"d", L"dans", L"de", L"debout", + L"dedans", L"dehors", L"del\x00e0", L"depuis", L"derri\x00e8re", L"des", L"d\x00e9sormais", + L"desquelles", L"desquels", L"dessous", L"dessus", L"devant", L"devers", L"devra", L"divers", + L"diverse", L"diverses", L"doit", L"donc", L"dont", L"du", L"duquel", L"durant", L"d\x00e8s", + L"elle", L"elles", L"en", L"entre", L"environ", L"est", L"et", L"etc", L"etre", L"eu", L"eux", + L"except\x00e9", L"hormis", L"hors", L"h\x00e9las", L"hui", L"il", L"ils", L"j", L"je", L"jusqu", + L"jusque", L"l", L"la", L"laquelle", L"le", L"lequel", L"les", L"lesquelles", L"lesquels", L"leur", + L"leurs", L"lorsque", L"lui", L"l\x00e0", L"ma", L"mais", L"malgr\x00e9", L"me", L"merci", L"mes", + L"mien", L"mienne", L"miennes", L"miens", L"moi", L"moins", L"mon", L"moyennant", L"m\x00eame", + L"m\x00eames", L"n", L"ne", L"ni", L"non", L"nos", L"notre", L"nous", L"n\x00e9anmoins", + L"n\x00f4tre", L"n\x00f4tres", L"on", L"ont", L"ou", L"outre", L"o\x00f9", L"par", L"parmi", + L"partant", L"pas", L"pass\x00e9", L"pendant", L"plein", L"plus", L"plusieurs", L"pour", L"pourquoi", + L"proche", L"pr\x00e8s", L"puisque", L"qu", L"quand", L"que", L"quel", L"quelle", L"quelles", + L"quels", L"qui", L"quoi", L"quoique", L"revoici", L"revoil\x00e0", L"s", L"sa", L"sans", L"sauf", + L"se", L"selon", L"seront", L"ses", L"si", L"sien", L"sienne", L"siennes", L"siens", L"sinon", + L"soi", L"soit", L"son", L"sont", L"sous", L"suivant", L"sur", L"ta", L"te", L"tes", L"tien", + L"tienne", L"tiennes", L"tiens", L"toi", L"ton", L"tous", L"tout", L"toute", L"toutes", L"tu", L"un", + L"une", L"va", L"vers", L"voici", L"voil\x00e0", L"vos", L"votre", L"vous", L"vu", L"v\x00f4tre", + L"v\x00f4tres", L"y", L"\x00e0", L"\x00e7a", L"\x00e8s", L"\x00e9t\x00e9", L"\x00eatre", L"\x00f4" +}; - FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stoptable = stopwords; - this->matchVersion = matchVersion; - } +FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion) { + this->stoptable = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) - { - this->stoptable = stopwords; - this->excltable = exclusions; - this->matchVersion = matchVersion; - } +FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stoptable = stopwords; + this->matchVersion = matchVersion; +} - FrenchAnalyzer::~FrenchAnalyzer() - { - } +FrenchAnalyzer::FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { + this->stoptable = stopwords; + this->excltable = exclusions; + this->matchVersion = matchVersion; +} - const HashSet FrenchAnalyzer::getDefaultStopSet() - { - static HashSet stoptable; - if (!stoptable) - stoptable = HashSet::newInstance(_FRENCH_STOP_WORDS, _FRENCH_STOP_WORDS + SIZEOF_ARRAY(_FRENCH_STOP_WORDS)); - return stoptable; - } +FrenchAnalyzer::~FrenchAnalyzer() { +} - void FrenchAnalyzer::setStemExclusionTable(HashSet exclusions) - { - excltable = exclusions; - setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +const HashSet FrenchAnalyzer::getDefaultStopSet() { + static HashSet stoptable; + if (!stoptable) { + stoptable = HashSet::newInstance(_FRENCH_STOP_WORDS, _FRENCH_STOP_WORDS + SIZEOF_ARRAY(_FRENCH_STOP_WORDS)); } + return stoptable; +} + +void FrenchAnalyzer::setStemExclusionTable(HashSet exclusions) { + excltable = exclusions; + setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +} + +TokenStreamPtr FrenchAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(matchVersion, reader); + result = newLucene(result); + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); + result = newLucene(result, excltable); + // Convert to lowercase after stemming + result = newLucene(result); + return result; +} - TokenStreamPtr FrenchAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(matchVersion, reader); - result = newLucene(result); - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); - result = newLucene(result, excltable); +TokenStreamPtr FrenchAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + FrenchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(matchVersion, reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); + streams->result = newLucene(streams->result, excltable); // Convert to lowercase after stemming - result = newLucene(result); - return result; + streams->result = newLucene(streams->result); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} - TokenStreamPtr FrenchAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - FrenchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(matchVersion, reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); - streams->result = newLucene(streams->result, excltable); - // Convert to lowercase after stemming - streams->result = newLucene(streams->result); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +FrenchAnalyzerSavedStreams::~FrenchAnalyzerSavedStreams() { +} - FrenchAnalyzerSavedStreams::~FrenchAnalyzerSavedStreams() - { - } } diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp index 374fe386..ed71f480 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchStemFilter.cpp @@ -9,52 +9,47 @@ #include "FrenchStemmer.h" #include "TermAttribute.h" -namespace Lucene -{ - FrenchStemFilter::FrenchStemFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - FrenchStemFilter::FrenchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - this->exclusions = exclusiontable; - } +FrenchStemFilter::FrenchStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); +} - FrenchStemFilter::~FrenchStemFilter() - { - } +FrenchStemFilter::FrenchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); + this->exclusions = exclusiontable; +} + +FrenchStemFilter::~FrenchStemFilter() { +} - bool FrenchStemFilter::incrementToken() - { - if (input->incrementToken()) - { - String term(termAtt->term()); - // Check the exclusion table. - if (!exclusions || !exclusions.contains(term)) - { - String s(stemmer->stem(term)); - // If not stemmed, don't waste the time adjusting the token. - if (!s.empty() && s != term) - termAtt->setTermBuffer(s); +bool FrenchStemFilter::incrementToken() { + if (input->incrementToken()) { + String term(termAtt->term()); + // Check the exclusion table. + if (!exclusions || !exclusions.contains(term)) { + String s(stemmer->stem(term)); + // If not stemmed, don't waste the time adjusting the token. + if (!s.empty() && s != term) { + termAtt->setTermBuffer(s); } - return true; } - else - return false; + return true; + } else { + return false; } +} - void FrenchStemFilter::setStemmer(const FrenchStemmerPtr& stemmer) - { - if (stemmer) - this->stemmer = stemmer; +void FrenchStemFilter::setStemmer(const FrenchStemmerPtr& stemmer) { + if (stemmer) { + this->stemmer = stemmer; } +} + +void FrenchStemFilter::setExclusionSet(HashSet exclusiontable) { + this->exclusions = exclusiontable; +} - void FrenchStemFilter::setExclusionSet(HashSet exclusiontable) - { - this->exclusions = exclusiontable; - } } diff --git a/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp b/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp index 6d0e176b..567569e7 100644 --- a/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp @@ -11,269 +11,257 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - FrenchStemmer::FrenchStemmer() - { - suite = false; - modified = false; - } +namespace Lucene { - FrenchStemmer::~FrenchStemmer() - { - } +FrenchStemmer::FrenchStemmer() { + suite = false; + modified = false; +} - String FrenchStemmer::stem(const String& term) - { - if (!isStemmable(term)) - return term; +FrenchStemmer::~FrenchStemmer() { +} - // Use lowercase for medium stemming. - stringBuffer = StringUtils::toLower(term); +String FrenchStemmer::stem(const String& term) { + if (!isStemmable(term)) { + return term; + } - // reset the booleans - modified = false; - suite = false; + // Use lowercase for medium stemming. + stringBuffer = StringUtils::toLower(term); - treatVowels(stringBuffer); + // reset the booleans + modified = false; + suite = false; - setStrings(); + treatVowels(stringBuffer); - step1(); + setStrings(); - if (!modified || suite) - { - if (!RV.empty()) - { - suite = step2a(); - if (!suite) - step2b(); + step1(); + + if (!modified || suite) { + if (!RV.empty()) { + suite = step2a(); + if (!suite) { + step2b(); } } + } - if (modified || suite) - step3(); - else - step4(); + if (modified || suite) { + step3(); + } else { + step4(); + } - step5(); + step5(); - step6(); + step6(); - return stringBuffer; - } + return stringBuffer; +} - void FrenchStemmer::setStrings() - { - // set the strings - R0 = stringBuffer; - RV = retrieveRV(stringBuffer); - R1 = retrieveR(stringBuffer); - if (!R1.empty()) - { - tempBuffer = R1; - R2 = retrieveR(tempBuffer); - } - else - R2.clear(); +void FrenchStemmer::setStrings() { + // set the strings + R0 = stringBuffer; + RV = retrieveRV(stringBuffer); + R1 = retrieveR(stringBuffer); + if (!R1.empty()) { + tempBuffer = R1; + R2 = retrieveR(tempBuffer); + } else { + R2.clear(); } +} - void FrenchStemmer::step1() - { - Collection suffix = newCollection(L"ances", L"iqUes", L"ismes", L"ables", L"istes", L"ance", L"iqUe", L"isme", L"able", L"iste"); - deleteFrom(R2, suffix); +void FrenchStemmer::step1() { + Collection suffix = newCollection(L"ances", L"iqUes", L"ismes", L"ables", L"istes", L"ance", L"iqUe", L"isme", L"able", L"iste"); + deleteFrom(R2, suffix); - replaceFrom(R2, newCollection(L"logies", L"logie"), L"log"); - replaceFrom(R2, newCollection(L"usions", L"utions", L"usion", L"ution"), L"u"); - replaceFrom(R2, newCollection(L"ences", L"ence"), L"ent"); + replaceFrom(R2, newCollection(L"logies", L"logie"), L"log"); + replaceFrom(R2, newCollection(L"usions", L"utions", L"usion", L"ution"), L"u"); + replaceFrom(R2, newCollection(L"ences", L"ence"), L"ent"); - Collection search = newCollection(L"atrices", L"ateurs", L"ations", L"atrice", L"ateur", L"ation"); - deleteButSuffixFromElseReplace(R2, search, L"ic", true, R0, L"iqU"); + Collection search = newCollection(L"atrices", L"ateurs", L"ations", L"atrice", L"ateur", L"ation"); + deleteButSuffixFromElseReplace(R2, search, L"ic", true, R0, L"iqU"); - deleteButSuffixFromElseReplace(R2, newCollection(L"ements", L"ement"), L"eus", false, R0, L"eux"); - deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"ativ", false); - deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"iv", false); - deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"abl", false); - deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"iqU", false); + deleteButSuffixFromElseReplace(R2, newCollection(L"ements", L"ement"), L"eus", false, R0, L"eux"); + deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"ativ", false); + deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"iv", false); + deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"abl", false); + deleteButSuffixFrom(R2, newCollection(L"ements", L"ement"), L"iqU", false); - deleteFromIfTestVowelBeforeIn(R1, newCollection(L"issements", L"issement"), false, R0); - deleteFrom(RV, newCollection(L"ements", L"ement")); + deleteFromIfTestVowelBeforeIn(R1, newCollection(L"issements", L"issement"), false, R0); + deleteFrom(RV, newCollection(L"ements", L"ement")); - deleteButSuffixFromElseReplace(R2, newCollection(L"it\x00e9s", L"it\x00e9"), L"abil", false, R0, L"abl"); - deleteButSuffixFromElseReplace(R2, newCollection(L"it\x00e9s", L"it\x00e9"), L"ic", false, R0, L"iqU"); - deleteButSuffixFrom(R2, newCollection(L"it\x00e9s", L"it\x00e9"), L"iv", true); + deleteButSuffixFromElseReplace(R2, newCollection(L"it\x00e9s", L"it\x00e9"), L"abil", false, R0, L"abl"); + deleteButSuffixFromElseReplace(R2, newCollection(L"it\x00e9s", L"it\x00e9"), L"ic", false, R0, L"iqU"); + deleteButSuffixFrom(R2, newCollection(L"it\x00e9s", L"it\x00e9"), L"iv", true); - Collection autre = newCollection(L"ifs", L"ives", L"if", L"ive"); - deleteButSuffixFromElseReplace(R2, autre, L"icat", false, R0, L"iqU"); - deleteButSuffixFromElseReplace(R2, autre, L"at", true, R2, L"iqU"); + Collection autre = newCollection(L"ifs", L"ives", L"if", L"ive"); + deleteButSuffixFromElseReplace(R2, autre, L"icat", false, R0, L"iqU"); + deleteButSuffixFromElseReplace(R2, autre, L"at", true, R2, L"iqU"); - replaceFrom(R0, newCollection(L"eaux"), L"eau"); + replaceFrom(R0, newCollection(L"eaux"), L"eau"); - replaceFrom(R1, newCollection(L"aux"), L"al"); + replaceFrom(R1, newCollection(L"aux"), L"al"); - deleteButSuffixFromElseReplace(R2, newCollection(L"euses", L"euse"), L"", true, R1, L"eux"); + deleteButSuffixFromElseReplace(R2, newCollection(L"euses", L"euse"), L"", true, R1, L"eux"); - deleteFrom(R2, newCollection(L"eux")); + deleteFrom(R2, newCollection(L"eux")); - // if one of the next steps is performed, we will need to perform step2a - if (replaceFrom(RV, newCollection(L"amment"), L"ant")) - suite = true; - if (replaceFrom(RV, newCollection(L"emment"), L"ent")) - suite = true; - if (deleteFromIfTestVowelBeforeIn(RV, newCollection(L"ments", L"ment"), true, RV)) - suite = true; + // if one of the next steps is performed, we will need to perform step2a + if (replaceFrom(RV, newCollection(L"amment"), L"ant")) { + suite = true; + } + if (replaceFrom(RV, newCollection(L"emment"), L"ent")) { + suite = true; + } + if (deleteFromIfTestVowelBeforeIn(RV, newCollection(L"ments", L"ment"), true, RV)) { + suite = true; } +} - bool FrenchStemmer::step2a() - { - static Collection search; - if (!search) - { - static const wchar_t* _search[] = - { - L"\x00eemes", L"\x00eetes", L"iraIent", L"irait", L"irais", L"irai", L"iras", L"ira", - L"irent", L"iriez", L"irez", L"irions", L"irons", L"iront", L"issaIent", - L"issais", L"issantes", L"issante", L"issants", L"issant", L"issait", - L"issais", L"issions", L"issons", L"issiez", L"issez", L"issent", L"isses", - L"isse", L"ir", L"is", L"\x00eet", L"it", L"ies", L"ie", L"i" - }; - search = Collection::newInstance(_search, _search + SIZEOF_ARRAY(_search)); - } - return deleteFromIfTestVowelBeforeIn(RV, search, false, RV); +bool FrenchStemmer::step2a() { + static Collection search; + if (!search) { + static const wchar_t* _search[] = { + L"\x00eemes", L"\x00eetes", L"iraIent", L"irait", L"irais", L"irai", L"iras", L"ira", + L"irent", L"iriez", L"irez", L"irions", L"irons", L"iront", L"issaIent", + L"issais", L"issantes", L"issante", L"issants", L"issant", L"issait", + L"issais", L"issions", L"issons", L"issiez", L"issez", L"issent", L"isses", + L"isse", L"ir", L"is", L"\x00eet", L"it", L"ies", L"ie", L"i" + }; + search = Collection::newInstance(_search, _search + SIZEOF_ARRAY(_search)); } + return deleteFromIfTestVowelBeforeIn(RV, search, false, RV); +} - void FrenchStemmer::step2b() - { - static Collection suffix; - if (!suffix) - { - static const wchar_t* _suffix[] = - { - L"eraIent", L"erais", L"erait", L"erai", L"eras", L"erions", L"eriez", - L"erons", L"eront", L"erez", L"\x00e8rent", L"era", L"\x00e9es", L"iez", L"\x00e9e", L"\x00e9s", - L"er", L"ez", L"\x00e9" - }; - suffix = Collection::newInstance(_suffix, _suffix + SIZEOF_ARRAY(_suffix)); - } - deleteFrom(RV, suffix); - - static Collection search; - if (!search) - { - static const wchar_t* _search[] = - { - L"assions", L"assiez", L"assent", L"asses", L"asse", L"aIent", L"antes", - L"aIent", L"Aient", L"ante", L"\x00e2mes", L"\x00e2tes", L"ants", L"ant", L"ait", - L"a\x00eet", L"ais", L"Ait", L"A\x00eet", L"Ais", L"\x00e2t", L"as", L"ai", L"Ai", L"a" - }; - search = Collection::newInstance(_search, _search + SIZEOF_ARRAY(_search)); - } - deleteButSuffixFrom(RV, search, L"e", true); +void FrenchStemmer::step2b() { + static Collection suffix; + if (!suffix) { + static const wchar_t* _suffix[] = { + L"eraIent", L"erais", L"erait", L"erai", L"eras", L"erions", L"eriez", + L"erons", L"eront", L"erez", L"\x00e8rent", L"era", L"\x00e9es", L"iez", L"\x00e9e", L"\x00e9s", + L"er", L"ez", L"\x00e9" + }; + suffix = Collection::newInstance(_suffix, _suffix + SIZEOF_ARRAY(_suffix)); + } + deleteFrom(RV, suffix); + + static Collection search; + if (!search) { + static const wchar_t* _search[] = { + L"assions", L"assiez", L"assent", L"asses", L"asse", L"aIent", L"antes", + L"aIent", L"Aient", L"ante", L"\x00e2mes", L"\x00e2tes", L"ants", L"ant", L"ait", + L"a\x00eet", L"ais", L"Ait", L"A\x00eet", L"Ais", L"\x00e2t", L"as", L"ai", L"Ai", L"a" + }; + search = Collection::newInstance(_search, _search + SIZEOF_ARRAY(_search)); + } + deleteButSuffixFrom(RV, search, L"e", true); + + deleteFrom(R2, newCollection(L"ions")); +} - deleteFrom(R2, newCollection(L"ions")); +void FrenchStemmer::step3() { + if (!stringBuffer.empty()) { + wchar_t ch = stringBuffer[stringBuffer.length() - 1]; + if (ch == L'Y') { + stringBuffer[stringBuffer.length() - 1] = L'i'; + setStrings(); + } else if (ch == L'\x00e7') { + stringBuffer[stringBuffer.length() - 1] = L'c'; + setStrings(); + } } +} - void FrenchStemmer::step3() - { - if (!stringBuffer.empty()) - { - wchar_t ch = stringBuffer[stringBuffer.length() - 1]; - if (ch == L'Y') - { - stringBuffer[stringBuffer.length() - 1] = L'i'; - setStrings(); - } - else if (ch == L'\x00e7') - { - stringBuffer[stringBuffer.length() - 1] = L'c'; +void FrenchStemmer::step4() { + if (stringBuffer.length() > 1) { + wchar_t ch = stringBuffer[stringBuffer.length() - 1]; + if (ch == L's') { + wchar_t b = stringBuffer[stringBuffer.length() - 2]; + if (b != L'a' && b != L'i' && b != L'o' && b != L'u' && b != L'\x00e8' && b != L's') { + stringBuffer.resize(stringBuffer.length() - 1); setStrings(); } } } + if (!deleteFromIfPrecededIn(R2, newCollection(L"ion"), RV, L"s")) { + deleteFromIfPrecededIn(R2, newCollection(L"ion"), RV, L"t"); + } - void FrenchStemmer::step4() - { - if (stringBuffer.length() > 1) - { - wchar_t ch = stringBuffer[stringBuffer.length() - 1]; - if (ch == L's') - { - wchar_t b = stringBuffer[stringBuffer.length() - 2]; - if (b != L'a' && b != L'i' && b != L'o' && b != L'u' && b != L'\x00e8' && b != L's') - { - stringBuffer.resize(stringBuffer.length() - 1); - setStrings(); - } - } - } - if (!deleteFromIfPrecededIn(R2, newCollection(L"ion"), RV, L"s")) - deleteFromIfPrecededIn(R2, newCollection(L"ion"), RV, L"t"); + replaceFrom(RV, newCollection(L"I\x00e8re", L"i\x00e8re", L"Ier", L"ier"), L"i"); + deleteFrom(RV, newCollection(L"e")); + deleteFromIfPrecededIn(RV, newCollection(L"\x00eb"), R0, L"gu"); +} - replaceFrom(RV, newCollection(L"I\x00e8re", L"i\x00e8re", L"Ier", L"ier"), L"i"); - deleteFrom(RV, newCollection(L"e")); - deleteFromIfPrecededIn(RV, newCollection(L"\x00eb"), R0, L"gu"); +void FrenchStemmer::step5() { + if (!R0.empty()) { + if (boost::ends_with(R0, L"enn") || boost::ends_with(R0, L"onn") || + boost::ends_with(R0, L"ett") || boost::ends_with(R0, L"ell") || boost::ends_with(R0, L"eill")) { + stringBuffer.resize(stringBuffer.length() - 1); + setStrings(); + } } +} - void FrenchStemmer::step5() - { - if (!R0.empty()) - { - if (boost::ends_with(R0, L"enn") || boost::ends_with(R0, L"onn") || - boost::ends_with(R0, L"ett") || boost::ends_with(R0, L"ell") || boost::ends_with(R0, L"eill")) - { - stringBuffer.resize(stringBuffer.length() - 1); - setStrings(); +void FrenchStemmer::step6() { + if (!R0.empty()) { + bool seenVowel = false; + bool seenConson = false; + int32_t pos = -1; + for (int32_t i = (int32_t)(R0.length() - 1); i > -1; --i) { + wchar_t ch = R0[i]; + if (isVowel(ch)) { + if (!seenVowel) { + if (ch == L'\x00e9' || ch == L'\x00e8') { + pos = i; + break; + } + } + seenVowel = true; + } else { + if (seenVowel) { + break; + } else { + seenConson = true; + } } } + if (pos > -1 && seenConson && !seenVowel) { + stringBuffer[pos] = L'e'; + } } +} - void FrenchStemmer::step6() - { - if (!R0.empty()) - { - bool seenVowel = false; - bool seenConson = false; - int32_t pos = -1; - for (int32_t i = (int32_t)(R0.length() - 1); i > -1; --i) - { - wchar_t ch = R0[i]; - if (isVowel(ch)) - { - if (!seenVowel) - { - if (ch == L'\x00e9' || ch == L'\x00e8') - { - pos = i; - break; - } - } - seenVowel = true; - } - else - { - if (seenVowel) - break; - else - seenConson = true; +bool FrenchStemmer::deleteFromIfPrecededIn(const String& source, Collection search, const String& from, const String& prefix) { + bool found = false; + if (!source.empty()) { + for (int32_t i = 0; i < search.size(); ++i) { + if (boost::ends_with(source, search[i])) { + if (!from.empty() && boost::ends_with(from, prefix + search[i])) { + stringBuffer.resize(stringBuffer.length() - search[i].length()); + found = true; + setStrings(); + break; } } - if (pos > -1 && seenConson && !seenVowel) - stringBuffer[pos] = L'e'; } } + return found; +} - bool FrenchStemmer::deleteFromIfPrecededIn(const String& source, Collection search, const String& from, const String& prefix) - { - bool found = false; - if (!source.empty()) - { - for (int32_t i = 0; i < search.size(); ++i) - { - if (boost::ends_with(source, search[i])) - { - if (!from.empty() && boost::ends_with(from, prefix + search[i])) - { +bool FrenchStemmer::deleteFromIfTestVowelBeforeIn(const String& source, Collection search, bool vowel, const String& from) { + bool found = false; + if (!source.empty() && !from.empty()) { + for (int32_t i = 0; i < search.size(); ++i) { + if (boost::ends_with(source, search[i])) { + if ((search[i].length() + 1) <= from.length()) { + bool test = isVowel(stringBuffer[stringBuffer.length() - (search[i].length() + 1)]); + if (test == vowel) { stringBuffer.resize(stringBuffer.length() - search[i].length()); + modified = true; found = true; setStrings(); break; @@ -281,288 +269,223 @@ namespace Lucene } } } - return found; } + return found; +} - bool FrenchStemmer::deleteFromIfTestVowelBeforeIn(const String& source, Collection search, bool vowel, const String& from) - { - bool found = false; - if (!source.empty() && !from.empty()) - { - for (int32_t i = 0; i < search.size(); ++i) - { - if (boost::ends_with(source, search[i])) - { - if ((search[i].length() + 1) <= from.length()) - { - bool test = isVowel(stringBuffer[stringBuffer.length() - (search[i].length() + 1)]); - if (test == vowel) - { - stringBuffer.resize(stringBuffer.length() - search[i].length()); - modified = true; - found = true; - setStrings(); - break; - } - } - } +void FrenchStemmer::deleteButSuffixFrom(const String& source, Collection search, const String& prefix, bool without) { + if (!source.empty()) { + for (int32_t i = 0; i < search.size(); ++i) { + if (boost::ends_with(source, prefix + search[i])) { + stringBuffer.resize(stringBuffer.length() - (prefix.length() + search[i].length())); + modified = true; + setStrings(); + break; + } else if (without && boost::ends_with(source, search[i])) { + stringBuffer.resize(stringBuffer.length() - search[i].length()); + modified = true; + setStrings(); + break; } } - return found; } +} - void FrenchStemmer::deleteButSuffixFrom(const String& source, Collection search, const String& prefix, bool without) - { - if (!source.empty()) - { - for (int32_t i = 0; i < search.size(); ++i) - { - if (boost::ends_with(source, prefix + search[i])) - { - stringBuffer.resize(stringBuffer.length() - (prefix.length() + search[i].length())); - modified = true; - setStrings(); - break; - } - else if (without && boost::ends_with(source, search[i])) - { - stringBuffer.resize(stringBuffer.length() - search[i].length()); - modified = true; - setStrings(); - break; - } +void FrenchStemmer::deleteButSuffixFromElseReplace(const String& source, Collection search, const String& prefix, bool without, const String& from, const String& replace) { + if (!source.empty()) { + for (int32_t i = 0; i < search.size(); ++i) { + if (boost::ends_with(source, prefix + search[i])) { + stringBuffer.resize(stringBuffer.length() - (prefix.length() + search[i].length())); + modified = true; + setStrings(); + break; + } else if (!from.empty() && boost::ends_with(from, prefix + search[i])) { + stringBuffer.resize(stringBuffer.length() - (prefix.length() + search[i].length())); + stringBuffer += replace; + modified = true; + setStrings(); + break; + } else if (without && boost::ends_with(source, search[i])) { + stringBuffer.resize(stringBuffer.length() - search[i].length()); + modified = true; + setStrings(); + break; } } } +} - void FrenchStemmer::deleteButSuffixFromElseReplace(const String& source, Collection search, const String& prefix, bool without, const String& from, const String& replace) - { - if (!source.empty()) - { - for (int32_t i = 0; i < search.size(); ++i) - { - if (boost::ends_with(source, prefix + search[i])) - { - stringBuffer.resize(stringBuffer.length() - (prefix.length() + search[i].length())); - modified = true; - setStrings(); - break; - } - else if (!from.empty() && boost::ends_with(from, prefix + search[i])) - { - stringBuffer.resize(stringBuffer.length() - (prefix.length() + search[i].length())); - stringBuffer += replace; - modified = true; - setStrings(); - break; - } - else if (without && boost::ends_with(source, search[i])) - { - stringBuffer.resize(stringBuffer.length() - search[i].length()); - modified = true; - setStrings(); - break; - } +bool FrenchStemmer::replaceFrom(const String& source, Collection search, const String& replace) { + bool found = false; + if (!source.empty()) { + for (int32_t i = 0; i < search.size(); ++i) { + if (boost::ends_with(source, search[i])) { + stringBuffer.resize(stringBuffer.length() - search[i].length()); + stringBuffer += replace; + modified = true; + found = true; + setStrings(); + break; } } } + return found; +} - bool FrenchStemmer::replaceFrom(const String& source, Collection search, const String& replace) - { - bool found = false; - if (!source.empty()) - { - for (int32_t i = 0; i < search.size(); ++i) - { - if (boost::ends_with(source, search[i])) - { - stringBuffer.resize(stringBuffer.length() - search[i].length()); - stringBuffer += replace; - modified = true; - found = true; - setStrings(); - break; - } +void FrenchStemmer::deleteFrom(const String& source, Collection suffix) { + if (!source.empty()) { + for (int32_t i = 0; i < suffix.size(); ++i) { + if (boost::ends_with(source, suffix[i])) { + stringBuffer.resize(stringBuffer.length() - suffix[i].length()); + modified = true; + setStrings(); + break; } } - return found; } +} - void FrenchStemmer::deleteFrom(const String& source, Collection suffix) - { - if (!source.empty()) - { - for (int32_t i = 0; i < suffix.size(); ++i) - { - if (boost::ends_with(source, suffix[i])) - { - stringBuffer.resize(stringBuffer.length() - suffix[i].length()); - modified = true; - setStrings(); - break; - } - } - } +bool FrenchStemmer::isVowel(wchar_t ch) { + switch (ch) { + case L'a': + case L'e': + case L'i': + case L'o': + case L'u': + case L'y': + case L'\x00e2': + case L'\x00e0': + case L'\x00eb': + case L'\x00e9': + case L'\x00ea': + case L'\x00e8': + case L'\x00ef': + case L'\x00ee': + case L'\x00f4': + case L'\x00fc': + case L'\x00f9': + case L'\x00fb': + return true; + default: + return false; } +} - bool FrenchStemmer::isVowel(wchar_t ch) - { - switch (ch) - { - case L'a': - case L'e': - case L'i': - case L'o': - case L'u': - case L'y': - case L'\x00e2': - case L'\x00e0': - case L'\x00eb': - case L'\x00e9': - case L'\x00ea': - case L'\x00e8': - case L'\x00ef': - case L'\x00ee': - case L'\x00f4': - case L'\x00fc': - case L'\x00f9': - case L'\x00fb': - return true; - default: - return false; +String FrenchStemmer::retrieveR(const String& buffer) { + int32_t len = (int32_t)buffer.length(); + int32_t pos = -1; + for (int32_t c = 0; c < len; ++c) { + if (isVowel(buffer[c])) { + pos = c; + break; } } - - String FrenchStemmer::retrieveR(const String& buffer) - { - int32_t len = (int32_t)buffer.length(); - int32_t pos = -1; - for (int32_t c = 0; c < len; ++c) - { - if (isVowel(buffer[c])) - { - pos = c; + if (pos > -1) { + int32_t consonne = -1; + for (int32_t c = pos; c < len; ++c) { + if (!isVowel(buffer[c])) { + consonne = c; break; } } - if (pos > -1) - { - int32_t consonne = -1; - for (int32_t c = pos; c < len; ++c) - { - if (!isVowel(buffer[c])) - { - consonne = c; - break; - } - } - if (consonne > -1 && (consonne + 1) < len) - return buffer.substr(consonne + 1); - else - return L""; - } - else + if (consonne > -1 && (consonne + 1) < len) { + return buffer.substr(consonne + 1); + } else { return L""; + } + } else { + return L""; } +} - String FrenchStemmer::retrieveRV(const String& buffer) - { - int32_t len = (int32_t)buffer.length(); - if (buffer.length() > 3) - { - if (isVowel(buffer[0]) && isVowel(buffer[1])) - return buffer.substr(3); - else - { - int32_t pos = 0; - for (int32_t c = 1; c < len; ++c) - { - if (isVowel(buffer[c])) - { - pos = c; - break; - } +String FrenchStemmer::retrieveRV(const String& buffer) { + int32_t len = (int32_t)buffer.length(); + if (buffer.length() > 3) { + if (isVowel(buffer[0]) && isVowel(buffer[1])) { + return buffer.substr(3); + } else { + int32_t pos = 0; + for (int32_t c = 1; c < len; ++c) { + if (isVowel(buffer[c])) { + pos = c; + break; } - if (pos + 1 < len) - return buffer.substr(pos + 1); - else - return L""; + } + if (pos + 1 < len) { + return buffer.substr(pos + 1); + } else { + return L""; } } - else - return L""; + } else { + return L""; } +} - void FrenchStemmer::treatVowels(String& buffer) - { +void FrenchStemmer::treatVowels(String& buffer) { - for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) - { - wchar_t ch = buffer[c]; + for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) { + wchar_t ch = buffer[c]; - if (c == 0) // first char - { - if (buffer.length() > 1) - { - if (ch == L'y' && isVowel(buffer[c + 1])) - buffer[c] = L'Y'; + if (c == 0) { // first char + if (buffer.length() > 1) { + if (ch == L'y' && isVowel(buffer[c + 1])) { + buffer[c] = L'Y'; } } - else if (c == buffer.length() - 1) // last char - { - if (ch == L'u' && buffer[c - 1] == L'q') - buffer[c] = L'U'; - if (ch == L'y' && isVowel(buffer[c - 1])) - buffer[c] = L'Y'; + } else if (c == buffer.length() - 1) { // last char + if (ch == L'u' && buffer[c - 1] == L'q') { + buffer[c] = L'U'; } - else // other cases - { - if (ch == L'u') - { - if (buffer[c - 1] == L'q') - buffer[c] = L'U'; - else if (isVowel(buffer[c - 1]) && isVowel(buffer[c + 1])) + if (ch == L'y' && isVowel(buffer[c - 1])) { + buffer[c] = L'Y'; + } + } else { // other cases + if (ch == L'u') { + if (buffer[c - 1] == L'q') { + buffer[c] = L'U'; + } else if (isVowel(buffer[c - 1]) && isVowel(buffer[c + 1])) { buffer[c] = L'U'; } - if (ch == L'i') - { - if (isVowel(buffer[c - 1]) && isVowel(buffer[c + 1])) - buffer[c] = L'I'; + } + if (ch == L'i') { + if (isVowel(buffer[c - 1]) && isVowel(buffer[c + 1])) { + buffer[c] = L'I'; } - if (ch == L'y') - { - if (isVowel(buffer[c - 1]) || isVowel(buffer[c + 1])) - buffer[c] = L'Y'; + } + if (ch == L'y') { + if (isVowel(buffer[c - 1]) || isVowel(buffer[c + 1])) { + buffer[c] = L'Y'; } } } } +} - bool FrenchStemmer::isStemmable(const String& term) - { - bool upper = false; - int32_t first = -1; - for (int32_t c = 0; c < (int32_t)term.length(); ++c) - { - // Discard terms that contain non-letter characters. - if (!UnicodeUtil::isAlpha(term[c])) +bool FrenchStemmer::isStemmable(const String& term) { + bool upper = false; + int32_t first = -1; + for (int32_t c = 0; c < (int32_t)term.length(); ++c) { + // Discard terms that contain non-letter characters. + if (!UnicodeUtil::isAlpha(term[c])) { + return false; + } + // Discard terms that contain multiple uppercase letters. + if (UnicodeUtil::isUpper(term[c])) { + if (upper) { return false; - // Discard terms that contain multiple uppercase letters. - if (UnicodeUtil::isUpper(term[c])) - { - if (upper) - return false; - else // First encountered uppercase letter, set flag and save position. - { - first = c; - upper = true; - } + } else { // First encountered uppercase letter, set flag and save position. + first = c; + upper = true; } } - // Discard the term if it contains a single uppercase letter that - // is not starting the term. - if (first > 0) - return false; - return true; } + // Discard the term if it contains a single uppercase letter that + // is not starting the term. + if (first > 0) { + return false; + } + return true; +} + } diff --git a/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp b/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp index 13b3c468..ce1593c1 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp @@ -11,97 +11,87 @@ #include "StopFilter.h" #include "DutchStemFilter.h" -namespace Lucene -{ - const wchar_t* DutchAnalyzer::_DUTCH_STOP_WORDS[] = - { - L"de", L"en", L"van", L"ik", L"te", L"dat", L"die", L"in", L"een", L"hij", L"het", L"niet", - L"zijn", L"is", L"was", L"op", L"aan", L"met", L"als", L"voor", L"had", L"er", L"maar", - L"om", L"hem", L"dan", L"zou", L"of", L"wat", L"mijn", L"men", L"dit", L"zo", L"door", - L"over", L"ze", L"zich", L"bij", L"ook", L"tot", L"je", L"mij", L"uit", L"der", L"daar", - L"haar", L"naar", L"heb", L"hoe", L"heeft", L"hebben", L"deze", L"u", L"want", L"nog", - L"zal", L"me", L"zij", L"nu", L"ge", L"geen", L"omdat", L"iets", L"worden", L"toch", - L"al", L"waren", L"veel", L"meer", L"doen", L"toen", L"moet", L"ben", L"zonder", L"kan", - L"hun", L"dus", L"alles", L"onder", L"ja", L"eens", L"hier", L"wie", L"werd", L"altijd", - L"doch", L"wordt", L"wezen", L"kunnen", L"ons", L"zelf", L"tegen", L"na", L"reeds", L"wil", - L"kon", L"niets", L"uw", L"iemand", L"geweest", L"andere" - }; +namespace Lucene { - DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion) - { - this->stoptable = getDefaultStopSet(); - this->excltable = HashSet::newInstance(); - this->stemdict = MapStringString::newInstance(); - this->matchVersion = matchVersion; - } +const wchar_t* DutchAnalyzer::_DUTCH_STOP_WORDS[] = { + L"de", L"en", L"van", L"ik", L"te", L"dat", L"die", L"in", L"een", L"hij", L"het", L"niet", + L"zijn", L"is", L"was", L"op", L"aan", L"met", L"als", L"voor", L"had", L"er", L"maar", + L"om", L"hem", L"dan", L"zou", L"of", L"wat", L"mijn", L"men", L"dit", L"zo", L"door", + L"over", L"ze", L"zich", L"bij", L"ook", L"tot", L"je", L"mij", L"uit", L"der", L"daar", + L"haar", L"naar", L"heb", L"hoe", L"heeft", L"hebben", L"deze", L"u", L"want", L"nog", + L"zal", L"me", L"zij", L"nu", L"ge", L"geen", L"omdat", L"iets", L"worden", L"toch", + L"al", L"waren", L"veel", L"meer", L"doen", L"toen", L"moet", L"ben", L"zonder", L"kan", + L"hun", L"dus", L"alles", L"onder", L"ja", L"eens", L"hier", L"wie", L"werd", L"altijd", + L"doch", L"wordt", L"wezen", L"kunnen", L"ons", L"zelf", L"tegen", L"na", L"reeds", L"wil", + L"kon", L"niets", L"uw", L"iemand", L"geweest", L"andere" +}; - DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stoptable = stopwords; - this->excltable = HashSet::newInstance(); - this->matchVersion = matchVersion; - } +DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion) { + this->stoptable = getDefaultStopSet(); + this->excltable = HashSet::newInstance(); + this->stemdict = MapStringString::newInstance(); + this->matchVersion = matchVersion; +} - DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) - { - this->stoptable = stopwords; - this->excltable = exclusions; - this->matchVersion = matchVersion; - } +DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stoptable = stopwords; + this->excltable = HashSet::newInstance(); + this->matchVersion = matchVersion; +} - DutchAnalyzer::~DutchAnalyzer() - { - } +DutchAnalyzer::DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions) { + this->stoptable = stopwords; + this->excltable = exclusions; + this->matchVersion = matchVersion; +} - void DutchAnalyzer::initialize() - { - stemdict.put(L"fiets", L"fiets"); // otherwise fiet - stemdict.put(L"bromfiets", L"bromfiets"); // otherwise bromfiet - stemdict.put(L"ei", L"eier"); - stemdict.put(L"kind", L"kinder"); - } +DutchAnalyzer::~DutchAnalyzer() { +} - const HashSet DutchAnalyzer::getDefaultStopSet() - { - static HashSet stoptable; - if (!stoptable) - stoptable = HashSet::newInstance(_DUTCH_STOP_WORDS, _DUTCH_STOP_WORDS + SIZEOF_ARRAY(_DUTCH_STOP_WORDS)); - return stoptable; - } +void DutchAnalyzer::initialize() { + stemdict.put(L"fiets", L"fiets"); // otherwise fiet + stemdict.put(L"bromfiets", L"bromfiets"); // otherwise bromfiet + stemdict.put(L"ei", L"eier"); + stemdict.put(L"kind", L"kinder"); +} - void DutchAnalyzer::setStemExclusionTable(HashSet exclusions) - { - excltable = exclusions; - setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +const HashSet DutchAnalyzer::getDefaultStopSet() { + static HashSet stoptable; + if (!stoptable) { + stoptable = HashSet::newInstance(_DUTCH_STOP_WORDS, _DUTCH_STOP_WORDS + SIZEOF_ARRAY(_DUTCH_STOP_WORDS)); } + return stoptable; +} - TokenStreamPtr DutchAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(matchVersion, reader); - result = newLucene(result); - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); - result = newLucene(result, excltable); - return result; - } +void DutchAnalyzer::setStemExclusionTable(HashSet exclusions) { + excltable = exclusions; + setPreviousTokenStream(LuceneObjectPtr()); // force a new stemmer to be created +} - TokenStreamPtr DutchAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - DutchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(matchVersion, reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); - streams->result = newLucene(streams->result, excltable); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr DutchAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(matchVersion, reader); + result = newLucene(result); + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stoptable); + result = newLucene(result, excltable); + return result; +} - DutchAnalyzerSavedStreams::~DutchAnalyzerSavedStreams() - { +TokenStreamPtr DutchAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + DutchAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(matchVersion, reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stoptable); + streams->result = newLucene(streams->result, excltable); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +DutchAnalyzerSavedStreams::~DutchAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp b/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp index 455e9882..cc4e1a07 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchStemFilter.cpp @@ -9,67 +9,61 @@ #include "DutchStemmer.h" #include "TermAttribute.h" -namespace Lucene -{ - DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - this->exclusions = exclusiontable; - } +DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); +} - DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable, MapStringString stemdictionary) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - this->exclusions = exclusiontable; - this->stemmer->setStemDictionary(stemdictionary); - } +DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); + this->exclusions = exclusiontable; +} - DutchStemFilter::~DutchStemFilter() - { - } +DutchStemFilter::DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable, MapStringString stemdictionary) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); + this->exclusions = exclusiontable; + this->stemmer->setStemDictionary(stemdictionary); +} - bool DutchStemFilter::incrementToken() - { - if (input->incrementToken()) - { - String term(termAtt->term()); +DutchStemFilter::~DutchStemFilter() { +} - // Check the exclusion table. - if (!exclusions || !exclusions.contains(term)) - { - String s(stemmer->stem(term)); - // If not stemmed, don't waste the time adjusting the token. - if (!s.empty() && s != term) - termAtt->setTermBuffer(s); +bool DutchStemFilter::incrementToken() { + if (input->incrementToken()) { + String term(termAtt->term()); + + // Check the exclusion table. + if (!exclusions || !exclusions.contains(term)) { + String s(stemmer->stem(term)); + // If not stemmed, don't waste the time adjusting the token. + if (!s.empty() && s != term) { + termAtt->setTermBuffer(s); } - return true; } - else - return false; + return true; + } else { + return false; } +} - void DutchStemFilter::setStemmer(const DutchStemmerPtr& stemmer) - { - if (stemmer) - this->stemmer = stemmer; +void DutchStemFilter::setStemmer(const DutchStemmerPtr& stemmer) { + if (stemmer) { + this->stemmer = stemmer; } +} - void DutchStemFilter::setExclusionSet(HashSet exclusiontable) - { - this->exclusions = exclusiontable; - } +void DutchStemFilter::setExclusionSet(HashSet exclusiontable) { + this->exclusions = exclusiontable; +} - void DutchStemFilter::setStemDictionary(MapStringString dict) - { - if (stemmer) - this->stemmer->setStemDictionary(dict); +void DutchStemFilter::setStemDictionary(MapStringString dict) { + if (stemmer) { + this->stemmer->setStemDictionary(dict); } } + +} diff --git a/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp b/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp index ad2f8c6f..9d6a8fbb 100644 --- a/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/nl/DutchStemmer.cpp @@ -11,313 +11,298 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - DutchStemmer::DutchStemmer() - { - removedE = false; - R1 = 0; - R2 = 0; - } - - DutchStemmer::~DutchStemmer() - { - } - - String DutchStemmer::stem(const String& term) - { - // Use lowercase for medium stemming. - buffer = StringUtils::toLower(term); - if (!isStemmable()) - return buffer; - - if (stemDict && stemDict.contains(term)) - return stemDict.get(term); - - // Stemming starts here... - substitute(); - storeYandI(); - R1 = getRIndex(0); - R1 = std::max((int32_t)3, R1); - step1(); - step2(); - R2 = getRIndex(R1); - step3a(); - step3b(); - step4(); - reStoreYandI(); +namespace Lucene { + +DutchStemmer::DutchStemmer() { + removedE = false; + R1 = 0; + R2 = 0; +} + +DutchStemmer::~DutchStemmer() { +} + +String DutchStemmer::stem(const String& term) { + // Use lowercase for medium stemming. + buffer = StringUtils::toLower(term); + if (!isStemmable()) { return buffer; } - bool DutchStemmer::enEnding() - { - Collection enend = newCollection(L"ene", L"en"); - for (int32_t i = 0; i < enend.size(); ++i) - { - String end = enend[i]; - int32_t index = (int32_t)(buffer.length() - end.length()); - if (boost::ends_with(buffer, end) && index >= R1 && isValidEnEnding(index - 1)) - { - buffer.erase(index, end.length()); - unDouble(index); - return true; - } + if (stemDict && stemDict.contains(term)) { + return stemDict.get(term); + } + + // Stemming starts here... + substitute(); + storeYandI(); + R1 = getRIndex(0); + R1 = std::max((int32_t)3, R1); + step1(); + step2(); + R2 = getRIndex(R1); + step3a(); + step3b(); + step4(); + reStoreYandI(); + return buffer; +} + +bool DutchStemmer::enEnding() { + Collection enend = newCollection(L"ene", L"en"); + for (int32_t i = 0; i < enend.size(); ++i) { + String end = enend[i]; + int32_t index = (int32_t)(buffer.length() - end.length()); + if (boost::ends_with(buffer, end) && index >= R1 && isValidEnEnding(index - 1)) { + buffer.erase(index, end.length()); + unDouble(index); + return true; } - return false; } + return false; +} - void DutchStemmer::step1() - { - if (R1 >= (int32_t)buffer.length()) - return; +void DutchStemmer::step1() { + if (R1 >= (int32_t)buffer.length()) { + return; + } - int32_t lengthR1 = (int32_t)(buffer.length() - R1); - int32_t index; + int32_t lengthR1 = (int32_t)(buffer.length() - R1); + int32_t index; - if (boost::ends_with(buffer, L"heden")) - { - buffer.replace(R1, lengthR1, boost::replace_all_copy(buffer.substr(R1, lengthR1), L"heden", L"heid")); - return; - } + if (boost::ends_with(buffer, L"heden")) { + buffer.replace(R1, lengthR1, boost::replace_all_copy(buffer.substr(R1, lengthR1), L"heden", L"heid")); + return; + } - if (enEnding()) - return; + if (enEnding()) { + return; + } - index = (int32_t)buffer.length() - 2; - if (boost::ends_with(buffer, L"se") && index >= R1 && isValidSEnding(index - 1)) - { - buffer.erase(index, 2); - return; - } + index = (int32_t)buffer.length() - 2; + if (boost::ends_with(buffer, L"se") && index >= R1 && isValidSEnding(index - 1)) { + buffer.erase(index, 2); + return; + } - index = (int32_t)(buffer.length() - 1); - if (boost::ends_with(buffer, L"s") && index >= R1 && isValidSEnding(index - 1)) - buffer.erase(index, 1); - } - - void DutchStemmer::step2() - { - removedE = false; - if (R1 >= (int32_t)buffer.length()) - return; - int32_t index = (int32_t)(buffer.length() - 1); - if (index >= R1 && boost::ends_with(buffer, L"e") && !isVowel(buffer[index - 1])) - { - buffer.erase(index, 1); - unDouble(); - removedE = true; - } + index = (int32_t)(buffer.length() - 1); + if (boost::ends_with(buffer, L"s") && index >= R1 && isValidSEnding(index - 1)) { + buffer.erase(index, 1); } +} - void DutchStemmer::step3a() - { - if (R2 >= (int32_t)buffer.length()) - return; - int32_t index = (int32_t)(buffer.length() - 4); - if (boost::ends_with(buffer, L"heid") && index >= R2 && buffer[index - 1] != L'c') - { - buffer.erase(index, 4); // remove heid - enEnding(); - } +void DutchStemmer::step2() { + removedE = false; + if (R1 >= (int32_t)buffer.length()) { + return; + } + int32_t index = (int32_t)(buffer.length() - 1); + if (index >= R1 && boost::ends_with(buffer, L"e") && !isVowel(buffer[index - 1])) { + buffer.erase(index, 1); + unDouble(); + removedE = true; } +} - void DutchStemmer::step3b() - { - if (R2 >= (int32_t)buffer.length()) - return; +void DutchStemmer::step3a() { + if (R2 >= (int32_t)buffer.length()) { + return; + } + int32_t index = (int32_t)(buffer.length() - 4); + if (boost::ends_with(buffer, L"heid") && index >= R2 && buffer[index - 1] != L'c') { + buffer.erase(index, 4); // remove heid + enEnding(); + } +} - int32_t index = (int32_t)(buffer.length() - 3); - if ((boost::ends_with(buffer, L"end") || boost::ends_with(buffer, L"ing")) && index >= R2) - { - buffer.erase(index, 3); - if (buffer[index - 2] == L'i' && buffer[index - 1] == L'g') - { - if (buffer[index - 3] != L'e' && index - 2 >= R2) - { - index -= 2; - buffer.erase(index, 2); - } - } - else - unDouble(index); - return; - } - index = (int32_t)(buffer.length() - 2); - if (boost::ends_with(buffer, L"ig") && index >= R2) - { - if (buffer[index - 1] != L'e') +void DutchStemmer::step3b() { + if (R2 >= (int32_t)buffer.length()) { + return; + } + + int32_t index = (int32_t)(buffer.length() - 3); + if ((boost::ends_with(buffer, L"end") || boost::ends_with(buffer, L"ing")) && index >= R2) { + buffer.erase(index, 3); + if (buffer[index - 2] == L'i' && buffer[index - 1] == L'g') { + if (buffer[index - 3] != L'e' && index - 2 >= R2) { + index -= 2; buffer.erase(index, 2); - return; - } - index = (int32_t)(buffer.length() - 4); - if (boost::ends_with(buffer, L"lijk") && index >= R2) - { - buffer.erase(index, 4); - step2(); - return; + } + } else { + unDouble(index); } - index = (int32_t)(buffer.length() - 4); - if (boost::ends_with(buffer, L"baar") && index >= R2) - { - buffer.erase(index, 4); - return; + return; + } + index = (int32_t)(buffer.length() - 2); + if (boost::ends_with(buffer, L"ig") && index >= R2) { + if (buffer[index - 1] != L'e') { + buffer.erase(index, 2); } - index = (int32_t)(buffer.length() - 3); - if (boost::ends_with(buffer, L"bar") && index >= R2) - { - if (removedE) - buffer.erase(index, 3); - return; + return; + } + index = (int32_t)(buffer.length() - 4); + if (boost::ends_with(buffer, L"lijk") && index >= R2) { + buffer.erase(index, 4); + step2(); + return; + } + index = (int32_t)(buffer.length() - 4); + if (boost::ends_with(buffer, L"baar") && index >= R2) { + buffer.erase(index, 4); + return; + } + index = (int32_t)(buffer.length() - 3); + if (boost::ends_with(buffer, L"bar") && index >= R2) { + if (removedE) { + buffer.erase(index, 3); } + return; } +} - void DutchStemmer::step4() - { - if (buffer.length() < 4) - return; - String end(buffer.substr(buffer.length() - 4)); - if (end[1] == end[2] && end[3] != L'I' && end[1] != L'i' && isVowel(end[1]) && !isVowel(end[3]) && !isVowel(end[0])) - buffer.erase(buffer.length() - 2, 1); +void DutchStemmer::step4() { + if (buffer.length() < 4) { + return; } + String end(buffer.substr(buffer.length() - 4)); + if (end[1] == end[2] && end[3] != L'I' && end[1] != L'i' && isVowel(end[1]) && !isVowel(end[3]) && !isVowel(end[0])) { + buffer.erase(buffer.length() - 2, 1); + } +} - bool DutchStemmer::isStemmable() - { - for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) - { - if (!UnicodeUtil::isAlnum(buffer[c])) - return false; +bool DutchStemmer::isStemmable() { + for (int32_t c = 0; c < (int32_t)buffer.length(); ++c) { + if (!UnicodeUtil::isAlnum(buffer[c])) { + return false; } - return true; } + return true; +} - void DutchStemmer::substitute() - { - for (int32_t i = 0; i < (int32_t)buffer.length(); ++i) - { - switch (buffer[i]) - { - case L'\x00e4': - case L'\x00e1': - buffer[i] = L'a'; - break; - case L'\x00eb': - case L'\x00e9': - buffer[i] = L'e'; - break; - case L'\x00fc': - case L'\x00fa': - buffer[i] = L'u'; - break; - case L'\x00ef': - case L'i': - buffer[i] = L'i'; - break; - case L'\x00f6': - case L'\x00f3': - buffer[i] = L'o'; - break; - } +void DutchStemmer::substitute() { + for (int32_t i = 0; i < (int32_t)buffer.length(); ++i) { + switch (buffer[i]) { + case L'\x00e4': + case L'\x00e1': + buffer[i] = L'a'; + break; + case L'\x00eb': + case L'\x00e9': + buffer[i] = L'e'; + break; + case L'\x00fc': + case L'\x00fa': + buffer[i] = L'u'; + break; + case L'\x00ef': + case L'i': + buffer[i] = L'i'; + break; + case L'\x00f6': + case L'\x00f3': + buffer[i] = L'o'; + break; } } +} - bool DutchStemmer::isValidSEnding(int32_t index) - { - wchar_t c = buffer[index]; - if (isVowel(c) || c == L'j') - return false; - return true; +bool DutchStemmer::isValidSEnding(int32_t index) { + wchar_t c = buffer[index]; + if (isVowel(c) || c == L'j') { + return false; } + return true; +} - bool DutchStemmer::isValidEnEnding(int32_t index) - { - wchar_t c = buffer[index]; - if (isVowel(c)) - return false; - if (c < 3) - return false; - // ends with "gem"? - if (c == L'm' && buffer[index - 2] == L'g' && buffer[index - 1] == L'e') - return false; - return true; +bool DutchStemmer::isValidEnEnding(int32_t index) { + wchar_t c = buffer[index]; + if (isVowel(c)) { + return false; } - - void DutchStemmer::unDouble() - { - unDouble((int32_t)buffer.length()); + if (c < 3) { + return false; + } + // ends with "gem"? + if (c == L'm' && buffer[index - 2] == L'g' && buffer[index - 1] == L'e') { + return false; } + return true; +} - void DutchStemmer::unDouble(int32_t endIndex) - { - String s = buffer.substr(0, endIndex); - if (boost::ends_with(s, L"kk") || boost::ends_with(s, L"tt") || boost::ends_with(s, L"dd") || - boost::ends_with(s, L"nn") || boost::ends_with(s, L"mm") || boost::ends_with(s, L"ff")) - buffer.resize(endIndex - 1); +void DutchStemmer::unDouble() { + unDouble((int32_t)buffer.length()); +} + +void DutchStemmer::unDouble(int32_t endIndex) { + String s = buffer.substr(0, endIndex); + if (boost::ends_with(s, L"kk") || boost::ends_with(s, L"tt") || boost::ends_with(s, L"dd") || + boost::ends_with(s, L"nn") || boost::ends_with(s, L"mm") || boost::ends_with(s, L"ff")) { + buffer.resize(endIndex - 1); } +} - int32_t DutchStemmer::getRIndex(int32_t start) - { - if (start == 0) - start = 1; - int32_t i = start; - for (; i < (int32_t)buffer.length(); ++i) - { - // first non-vowel preceded by a vowel - if (!isVowel(buffer[i]) && isVowel(buffer[i - 1])) - return i + 1; +int32_t DutchStemmer::getRIndex(int32_t start) { + if (start == 0) { + start = 1; + } + int32_t i = start; + for (; i < (int32_t)buffer.length(); ++i) { + // first non-vowel preceded by a vowel + if (!isVowel(buffer[i]) && isVowel(buffer[i - 1])) { + return i + 1; } - return i + 1; - } - - void DutchStemmer::storeYandI() - { - if (buffer[0] == L'y') - buffer[0] = L'Y'; - - int32_t last = (int32_t)(buffer.length() - 1); - - for (int32_t i = 1; i < last; i++) - { - switch (buffer[i]) - { - case L'i': - if (isVowel(buffer[i - 1]) && isVowel(buffer[i + 1])) - buffer[i] = L'I'; - break; - case L'y': - if (isVowel(buffer[i - 1])) - buffer[i] = L'Y'; - break; + } + return i + 1; +} + +void DutchStemmer::storeYandI() { + if (buffer[0] == L'y') { + buffer[0] = L'Y'; + } + + int32_t last = (int32_t)(buffer.length() - 1); + + for (int32_t i = 1; i < last; i++) { + switch (buffer[i]) { + case L'i': + if (isVowel(buffer[i - 1]) && isVowel(buffer[i + 1])) { + buffer[i] = L'I'; } - } - if (last > 0 && buffer[last] == L'y' && isVowel(buffer[last - 1])) - buffer[last] = L'Y'; - } - - void DutchStemmer::reStoreYandI() - { - boost::replace_all(buffer, L"I", L"i"); - boost::replace_all(buffer, L"Y", L"y"); - } - - bool DutchStemmer::isVowel(wchar_t c) - { - switch (c) - { - case L'e': - case L'a': - case L'o': - case L'i': - case L'u': - case L'y': - case L'\x00e8': - return true; - default: - return false; + break; + case L'y': + if (isVowel(buffer[i - 1])) { + buffer[i] = L'Y'; + } + break; } } + if (last > 0 && buffer[last] == L'y' && isVowel(buffer[last - 1])) { + buffer[last] = L'Y'; + } +} - void DutchStemmer::setStemDictionary(MapStringString dict) - { - stemDict = dict; +void DutchStemmer::reStoreYandI() { + boost::replace_all(buffer, L"I", L"i"); + boost::replace_all(buffer, L"Y", L"y"); +} + +bool DutchStemmer::isVowel(wchar_t c) { + switch (c) { + case L'e': + case L'a': + case L'o': + case L'i': + case L'u': + case L'y': + case L'\x00e8': + return true; + default: + return false; } } + +void DutchStemmer::setStemDictionary(MapStringString dict) { + stemDict = dict; +} + +} diff --git a/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp b/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp index 04b3c7f0..9a93e0ae 100644 --- a/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp +++ b/src/contrib/analyzers/common/analysis/reverse/ReverseStringFilter.cpp @@ -8,55 +8,50 @@ #include "ReverseStringFilter.h" #include "TermAttribute.h" -namespace Lucene -{ - const wchar_t ReverseStringFilter::NOMARKER = (wchar_t)0xffff; +namespace Lucene { - /// Example marker character: U+0001 (START OF HEADING) - const wchar_t ReverseStringFilter::START_OF_HEADING_MARKER = (wchar_t)0x0001; +const wchar_t ReverseStringFilter::NOMARKER = (wchar_t)0xffff; - /// Example marker character: U+001F (INFORMATION SEPARATOR ONE) - const wchar_t ReverseStringFilter::INFORMATION_SEPARATOR_MARKER = (wchar_t)0x001f; +/// Example marker character: U+0001 (START OF HEADING) +const wchar_t ReverseStringFilter::START_OF_HEADING_MARKER = (wchar_t)0x0001; - /// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) - const wchar_t ReverseStringFilter::PUA_EC00_MARKER = (wchar_t)0xec00; +/// Example marker character: U+001F (INFORMATION SEPARATOR ONE) +const wchar_t ReverseStringFilter::INFORMATION_SEPARATOR_MARKER = (wchar_t)0x001f; - /// Example marker character: U+200F (RIGHT-TO-LEFT MARK) - const wchar_t ReverseStringFilter::RTL_DIRECTION_MARKER = (wchar_t)0x200f; +/// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) +const wchar_t ReverseStringFilter::PUA_EC00_MARKER = (wchar_t)0xec00; - ReverseStringFilter::ReverseStringFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - this->marker = NOMARKER; - termAtt = addAttribute(); - } +/// Example marker character: U+200F (RIGHT-TO-LEFT MARK) +const wchar_t ReverseStringFilter::RTL_DIRECTION_MARKER = (wchar_t)0x200f; - ReverseStringFilter::ReverseStringFilter(const TokenStreamPtr& input, wchar_t marker) : TokenFilter(input) - { - this->marker = marker; - termAtt = addAttribute(); - } +ReverseStringFilter::ReverseStringFilter(const TokenStreamPtr& input) : TokenFilter(input) { + this->marker = NOMARKER; + termAtt = addAttribute(); +} - ReverseStringFilter::~ReverseStringFilter() - { - } +ReverseStringFilter::ReverseStringFilter(const TokenStreamPtr& input, wchar_t marker) : TokenFilter(input) { + this->marker = marker; + termAtt = addAttribute(); +} - bool ReverseStringFilter::incrementToken() - { - if (input->incrementToken()) - { - int32_t len = termAtt->termLength(); - if (marker != NOMARKER) - { - ++len; - termAtt->resizeTermBuffer(len); - termAtt->termBuffer()[len - 1] = marker; - } - CharArray term(termAtt->termBuffer()); - std::reverse(term.get(), term.get() + len); - termAtt->setTermLength(len); - return true; +ReverseStringFilter::~ReverseStringFilter() { +} + +bool ReverseStringFilter::incrementToken() { + if (input->incrementToken()) { + int32_t len = termAtt->termLength(); + if (marker != NOMARKER) { + ++len; + termAtt->resizeTermBuffer(len); + termAtt->termBuffer()[len - 1] = marker; } - else - return false; + CharArray term(termAtt->termBuffer()); + std::reverse(term.get(), term.get() + len); + termAtt->setTermLength(len); + return true; + } else { + return false; } } + +} diff --git a/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp index 3b6a44d5..18907a43 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp @@ -12,112 +12,103 @@ #include "RussianStemFilter.h" #include "StringUtils.h" -namespace Lucene -{ - /// Default Russian stopwords in UTF-8 format. - const uint8_t RussianAnalyzer::DEFAULT_STOPWORD_FILE[] = - { - 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb7, 0x0a, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, 0xbb, - 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, - 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, - 0xd0, 0xb8, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xbe, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, - 0xd1, 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb2, 0x0a, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbc, 0x0a, 0xd0, - 0xb2, 0xd0, 0xb0, 0xd1, 0x81, 0x0a, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, 0xd0, - 0xb2, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, - 0xb5, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd1, - 0x81, 0xd0, 0xb5, 0xd1, 0x85, 0x0a, 0xd0, 0xb2, 0xd1, 0x8b, 0x0a, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, - 0xb5, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, - 0xd0, 0xb4, 0xd0, 0xbb, 0xd1, 0x8f, 0x0a, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb3, - 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd0, 0xb5, 0xd1, - 0x8e, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, - 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb5, 0xd1, 0x89, 0xd0, 0xb5, 0x0a, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, - 0xd0, 0xb7, 0xd0, 0xb0, 0x0a, 0xd0, 0xb7, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, - 0xd0, 0xb8, 0x0a, 0xd0, 0xb8, 0xd0, 0xb7, 0x0a, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, - 0xb8, 0xd0, 0xbc, 0x0a, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xb0, - 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, - 0xd0, 0xb0, 0x0a, 0xd0, 0xba, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, - 0xbb, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, 0xbe, 0x0a, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, - 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, 0xd0, 0xbc, 0xd1, 0x8b, 0x0a, 0xd0, - 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, - 0xb0, 0xd1, 0x88, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, - 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, - 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xbd, 0xd0, 0xbe, - 0x0a, 0xd0, 0xbd, 0xd1, 0x83, 0x0a, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xb1, 0x0a, 0xd0, 0xbe, - 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0x0a, - 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbe, - 0xd0, 0xbd, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, 0xb5, - 0xd0, 0xbd, 0xd1, 0x8c, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xb4, - 0x0a, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb8, 0x0a, 0xd1, 0x81, 0x0a, 0xd1, 0x81, 0xd0, 0xbe, 0x0a, - 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb6, 0xd0, - 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, 0xd0, - 0xb0, 0xd0, 0xbc, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0x0a, - 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, - 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, - 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, - 0xbc, 0x0a, 0xd1, 0x82, 0xd1, 0x8b, 0x0a, 0xd1, 0x83, 0x0a, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb5, - 0x0a, 0xd1, 0x85, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x8f, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, - 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbc, - 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb1, - 0xd1, 0x8b, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd0, 0xb5, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd1, 0x8f, - 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb0, 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb8, 0x0a, 0xd1, - 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x8f, 0x0a - }; +namespace Lucene { - RussianAnalyzer::RussianAnalyzer(LuceneVersion::Version matchVersion) - { - this->stopSet = getDefaultStopSet(); - this->matchVersion = matchVersion; - } +/// Default Russian stopwords in UTF-8 format. +const uint8_t RussianAnalyzer::DEFAULT_STOPWORD_FILE[] = { + 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd0, 0xb5, 0xd0, 0xb7, 0x0a, 0xd0, 0xb1, 0xd0, 0xbe, 0xd0, 0xbb, + 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, + 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xb0, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, + 0xd0, 0xb8, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbb, 0xd0, 0xbe, 0x0a, 0xd0, 0xb1, 0xd1, 0x8b, + 0xd1, 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb2, 0x0a, 0xd0, 0xb2, 0xd0, 0xb0, 0xd0, 0xbc, 0x0a, 0xd0, + 0xb2, 0xd0, 0xb0, 0xd1, 0x81, 0x0a, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, 0xd0, + 0xb2, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, + 0xb5, 0x0a, 0xd0, 0xb2, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd0, 0xb2, 0xd1, + 0x81, 0xd0, 0xb5, 0xd1, 0x85, 0x0a, 0xd0, 0xb2, 0xd1, 0x8b, 0x0a, 0xd0, 0xb3, 0xd0, 0xb4, 0xd0, + 0xb5, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0x0a, 0xd0, 0xb4, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, + 0xd0, 0xb4, 0xd0, 0xbb, 0xd1, 0x8f, 0x0a, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb3, + 0xd0, 0xbe, 0x0a, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd0, 0xb5, 0xd1, + 0x8e, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, + 0x82, 0xd1, 0x8c, 0x0a, 0xd0, 0xb5, 0xd1, 0x89, 0xd0, 0xb5, 0x0a, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, + 0xd0, 0xb7, 0xd0, 0xb0, 0x0a, 0xd0, 0xb7, 0xd0, 0xb4, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x8c, 0x0a, + 0xd0, 0xb8, 0x0a, 0xd0, 0xb8, 0xd0, 0xb7, 0x0a, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, + 0xb8, 0xd0, 0xbc, 0x0a, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xb0, + 0xd0, 0xba, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xb4, + 0xd0, 0xb0, 0x0a, 0xd0, 0xba, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd0, 0xbb, 0xd0, 0xb8, 0x0a, 0xd0, + 0xbb, 0xd0, 0xb8, 0xd0, 0xb1, 0xd0, 0xbe, 0x0a, 0xd0, 0xbc, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, + 0xbc, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, 0xd0, 0xbc, 0xd1, 0x8b, 0x0a, 0xd0, + 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xb4, 0xd0, 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, + 0xb0, 0xd1, 0x88, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb3, 0xd0, + 0xbe, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd0, 0xb5, 0x0a, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x82, 0x0a, + 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0x0a, 0xd0, 0xbd, 0xd0, 0xbe, + 0x0a, 0xd0, 0xbd, 0xd1, 0x83, 0x0a, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xb1, 0x0a, 0xd0, 0xbe, + 0xd0, 0xb4, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0x0a, + 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb0, 0x0a, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0x0a, 0xd0, 0xbe, + 0xd0, 0xbd, 0xd0, 0xbe, 0x0a, 0xd0, 0xbe, 0xd1, 0x82, 0x0a, 0xd0, 0xbe, 0xd1, 0x87, 0xd0, 0xb5, + 0xd0, 0xbd, 0xd1, 0x8c, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0x0a, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xb4, + 0x0a, 0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb8, 0x0a, 0xd1, 0x81, 0x0a, 0xd1, 0x81, 0xd0, 0xbe, 0x0a, + 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xb6, 0xd0, + 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xba, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, 0xd0, + 0xb0, 0xd0, 0xbc, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0x0a, + 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb3, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb5, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb9, 0x0a, 0xd1, 0x82, + 0xd0, 0xbe, 0xd0, 0xbb, 0xd1, 0x8c, 0xd0, 0xba, 0xd0, 0xbe, 0x0a, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, + 0xbc, 0x0a, 0xd1, 0x82, 0xd1, 0x8b, 0x0a, 0xd1, 0x83, 0x0a, 0xd1, 0x83, 0xd0, 0xb6, 0xd0, 0xb5, + 0x0a, 0xd1, 0x85, 0xd0, 0xbe, 0xd1, 0x82, 0xd1, 0x8f, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb3, + 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xb9, 0x0a, 0xd1, 0x87, 0xd0, 0xb5, 0xd0, 0xbc, + 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x87, 0xd1, 0x82, 0xd0, 0xbe, 0xd0, 0xb1, + 0xd1, 0x8b, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd0, 0xb5, 0x0a, 0xd1, 0x87, 0xd1, 0x8c, 0xd1, 0x8f, + 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb0, 0x0a, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xb8, 0x0a, 0xd1, + 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0x0a, 0xd1, 0x8f, 0x0a +}; - RussianAnalyzer::RussianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) - { - this->stopSet = stopwords; - this->matchVersion = matchVersion; - } +RussianAnalyzer::RussianAnalyzer(LuceneVersion::Version matchVersion) { + this->stopSet = getDefaultStopSet(); + this->matchVersion = matchVersion; +} - RussianAnalyzer::~RussianAnalyzer() - { - } +RussianAnalyzer::RussianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords) { + this->stopSet = stopwords; + this->matchVersion = matchVersion; +} - const HashSet RussianAnalyzer::getDefaultStopSet() - { - static HashSet stopSet; - if (!stopSet) - { - String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE)); - Collection words(StringUtils::split(stopWords, L"\n")); - stopSet = HashSet::newInstance(words.begin(), words.end()); - } - return stopSet; - } +RussianAnalyzer::~RussianAnalyzer() { +} - TokenStreamPtr RussianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(reader); - result = newLucene(result); - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); - result = newLucene(result); - return result; +const HashSet RussianAnalyzer::getDefaultStopSet() { + static HashSet stopSet; + if (!stopSet) { + String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE)); + Collection words(StringUtils::split(stopWords, L"\n")); + stopSet = HashSet::newInstance(words.begin(), words.end()); } + return stopSet; +} - TokenStreamPtr RussianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - RussianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); - streams->result = newLucene(streams->result); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr RussianAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(reader); + result = newLucene(result); + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); + result = newLucene(result); + return result; +} - RussianAnalyzerSavedStreams::~RussianAnalyzerSavedStreams() - { +TokenStreamPtr RussianAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + RussianAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); + streams->result = newLucene(streams->result); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +RussianAnalyzerSavedStreams::~RussianAnalyzerSavedStreams() { +} + } diff --git a/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp index 1359d926..43ef0fe0 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianLetterTokenizer.cpp @@ -9,26 +9,22 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - RussianLetterTokenizer::RussianLetterTokenizer(const ReaderPtr& input) : CharTokenizer(input) - { - } - - RussianLetterTokenizer::RussianLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) - { - } - - RussianLetterTokenizer::RussianLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) - { - } - - RussianLetterTokenizer::~RussianLetterTokenizer() - { - } - - bool RussianLetterTokenizer::isTokenChar(wchar_t c) - { - return (UnicodeUtil::isAlpha(c) || UnicodeUtil::isDigit(c)); - } +namespace Lucene { + +RussianLetterTokenizer::RussianLetterTokenizer(const ReaderPtr& input) : CharTokenizer(input) { +} + +RussianLetterTokenizer::RussianLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) { +} + +RussianLetterTokenizer::RussianLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) { +} + +RussianLetterTokenizer::~RussianLetterTokenizer() { +} + +bool RussianLetterTokenizer::isTokenChar(wchar_t c) { + return (UnicodeUtil::isAlpha(c) || UnicodeUtil::isDigit(c)); +} + } diff --git a/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp b/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp index 8bbc1842..45a12f72 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianLowerCaseFilter.cpp @@ -9,28 +9,26 @@ #include "TermAttribute.h" #include "CharFolder.h" -namespace Lucene -{ - RussianLowerCaseFilter::RussianLowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - termAtt = addAttribute(); - } +namespace Lucene { - RussianLowerCaseFilter::~RussianLowerCaseFilter() - { - } +RussianLowerCaseFilter::RussianLowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) { + termAtt = addAttribute(); +} - bool RussianLowerCaseFilter::incrementToken() - { - if (input->incrementToken()) - { - wchar_t* buffer = termAtt->termBufferArray(); - int32_t length = termAtt->termLength(); - for (int32_t i = 0; i < length; ++i) - buffer[i] = CharFolder::toLower(buffer[i]); - return true; +RussianLowerCaseFilter::~RussianLowerCaseFilter() { +} + +bool RussianLowerCaseFilter::incrementToken() { + if (input->incrementToken()) { + wchar_t* buffer = termAtt->termBufferArray(); + int32_t length = termAtt->termLength(); + for (int32_t i = 0; i < length; ++i) { + buffer[i] = CharFolder::toLower(buffer[i]); } - else - return false; + return true; + } else { + return false; } } + +} diff --git a/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp b/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp index ec3cf8af..4b0a72e3 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianStemFilter.cpp @@ -9,35 +9,33 @@ #include "RussianStemmer.h" #include "TermAttribute.h" -namespace Lucene -{ - RussianStemFilter::RussianStemFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - RussianStemFilter::~RussianStemFilter() - { - } +RussianStemFilter::RussianStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); +} + +RussianStemFilter::~RussianStemFilter() { +} - bool RussianStemFilter::incrementToken() - { - if (input->incrementToken()) - { - String term(termAtt->term()); - String s(stemmer->stem(term)); - if (!s.empty() && s != term) - termAtt->setTermBuffer(s); - return true; +bool RussianStemFilter::incrementToken() { + if (input->incrementToken()) { + String term(termAtt->term()); + String s(stemmer->stem(term)); + if (!s.empty() && s != term) { + termAtt->setTermBuffer(s); } - else - return false; + return true; + } else { + return false; } +} - void RussianStemFilter::setStemmer(const RussianStemmerPtr& stemmer) - { - if (stemmer) - this->stemmer = stemmer; +void RussianStemFilter::setStemmer(const RussianStemmerPtr& stemmer) { + if (stemmer) { + this->stemmer = stemmer; } } + +} diff --git a/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp b/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp index ff489fa8..08550811 100644 --- a/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp +++ b/src/contrib/analyzers/common/analysis/ru/RussianStemmer.cpp @@ -9,563 +9,513 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - const wchar_t RussianStemmer::A = L'\x0430'; - const wchar_t RussianStemmer::V = L'\x0432'; - const wchar_t RussianStemmer::G = L'\x0433'; - const wchar_t RussianStemmer::E = L'\x0435'; - const wchar_t RussianStemmer::I = L'\x0438'; - const wchar_t RussianStemmer::I_ = L'\x0439'; - const wchar_t RussianStemmer::L = L'\x043b'; - const wchar_t RussianStemmer::M = L'\x043c'; - const wchar_t RussianStemmer::N = L'\x043d'; - const wchar_t RussianStemmer::O = L'\x043e'; - const wchar_t RussianStemmer::S = L'\x0441'; - const wchar_t RussianStemmer::T = L'\x0442'; - const wchar_t RussianStemmer::U = L'\x0443'; - const wchar_t RussianStemmer::X = L'\x0445'; - const wchar_t RussianStemmer::SH = L'\x0448'; - const wchar_t RussianStemmer::SHCH = L'\x0449'; - const wchar_t RussianStemmer::Y = L'\x044b'; - const wchar_t RussianStemmer::SOFT = L'\x044c'; - const wchar_t RussianStemmer::AE = L'\x044d'; - const wchar_t RussianStemmer::IU = L'\x044e'; - const wchar_t RussianStemmer::IA = L'\x044f'; - - const wchar_t RussianStemmer::vowels[] = {A, E, I, O, U, Y, AE, IU, IA}; - - RussianStemmer::RussianStemmer() - { - RV = 0; - R1 = 0; - R2 = 0; - } - - RussianStemmer::~RussianStemmer() - { - } - - Collection RussianStemmer::perfectiveGerundEndings1() - { - static Collection _perfectiveGerundEndings1; - if (!_perfectiveGerundEndings1) - { - _perfectiveGerundEndings1 = Collection::newInstance(); - _perfectiveGerundEndings1.add(String(L"") + V); - _perfectiveGerundEndings1.add(String(L"") + V + SH + I); - _perfectiveGerundEndings1.add(String(L"") + V + SH + I + S + SOFT); - } - return _perfectiveGerundEndings1; +namespace Lucene { + +const wchar_t RussianStemmer::A = L'\x0430'; +const wchar_t RussianStemmer::V = L'\x0432'; +const wchar_t RussianStemmer::G = L'\x0433'; +const wchar_t RussianStemmer::E = L'\x0435'; +const wchar_t RussianStemmer::I = L'\x0438'; +const wchar_t RussianStemmer::I_ = L'\x0439'; +const wchar_t RussianStemmer::L = L'\x043b'; +const wchar_t RussianStemmer::M = L'\x043c'; +const wchar_t RussianStemmer::N = L'\x043d'; +const wchar_t RussianStemmer::O = L'\x043e'; +const wchar_t RussianStemmer::S = L'\x0441'; +const wchar_t RussianStemmer::T = L'\x0442'; +const wchar_t RussianStemmer::U = L'\x0443'; +const wchar_t RussianStemmer::X = L'\x0445'; +const wchar_t RussianStemmer::SH = L'\x0448'; +const wchar_t RussianStemmer::SHCH = L'\x0449'; +const wchar_t RussianStemmer::Y = L'\x044b'; +const wchar_t RussianStemmer::SOFT = L'\x044c'; +const wchar_t RussianStemmer::AE = L'\x044d'; +const wchar_t RussianStemmer::IU = L'\x044e'; +const wchar_t RussianStemmer::IA = L'\x044f'; + +const wchar_t RussianStemmer::vowels[] = {A, E, I, O, U, Y, AE, IU, IA}; + +RussianStemmer::RussianStemmer() { + RV = 0; + R1 = 0; + R2 = 0; +} + +RussianStemmer::~RussianStemmer() { +} + +Collection RussianStemmer::perfectiveGerundEndings1() { + static Collection _perfectiveGerundEndings1; + if (!_perfectiveGerundEndings1) { + _perfectiveGerundEndings1 = Collection::newInstance(); + _perfectiveGerundEndings1.add(String(L"") + V); + _perfectiveGerundEndings1.add(String(L"") + V + SH + I); + _perfectiveGerundEndings1.add(String(L"") + V + SH + I + S + SOFT); } + return _perfectiveGerundEndings1; +} - Collection RussianStemmer::perfectiveGerund1Predessors() - { - static Collection _perfectiveGerund1Predessors; - if (!_perfectiveGerund1Predessors) - { - _perfectiveGerund1Predessors = Collection::newInstance(); - _perfectiveGerund1Predessors.add(String(L"") + A); - _perfectiveGerund1Predessors.add(String(L"") + IA); - } - return _perfectiveGerund1Predessors; - } - - Collection RussianStemmer::perfectiveGerundEndings2() - { - static Collection _perfectiveGerundEndings2; - if (!_perfectiveGerundEndings2) - { - _perfectiveGerundEndings2 = Collection::newInstance(); - _perfectiveGerundEndings2.add(String(L"") + I + V); - _perfectiveGerundEndings2.add(String(L"") + Y + V); - _perfectiveGerundEndings2.add(String(L"") + I + V + SH + I); - _perfectiveGerundEndings2.add(String(L"") + Y + V + SH + I); - _perfectiveGerundEndings2.add(String(L"") + I + V + SH + I + S + SOFT); - _perfectiveGerundEndings2.add(String(L"") + Y + V + SH + I + S + SOFT); - } - return _perfectiveGerundEndings2; - } - - Collection RussianStemmer::adjectiveEndings() - { - static Collection _adjectiveEndings; - if (!_adjectiveEndings) - { - _adjectiveEndings = Collection::newInstance(); - _adjectiveEndings.add(String(L"") + E + E); - _adjectiveEndings.add(String(L"") + I + E); - _adjectiveEndings.add(String(L"") + Y + E); - _adjectiveEndings.add(String(L"") + O + E); - _adjectiveEndings.add(String(L"") + E + I_); - _adjectiveEndings.add(String(L"") + I + I_); - _adjectiveEndings.add(String(L"") + Y + I_); - _adjectiveEndings.add(String(L"") + O + I_); - _adjectiveEndings.add(String(L"") + E + M); - _adjectiveEndings.add(String(L"") + I + M); - _adjectiveEndings.add(String(L"") + Y + M); - _adjectiveEndings.add(String(L"") + O + M); - _adjectiveEndings.add(String(L"") + I + X); - _adjectiveEndings.add(String(L"") + Y + X); - _adjectiveEndings.add(String(L"") + U + IU); - _adjectiveEndings.add(String(L"") + IU + IU); - _adjectiveEndings.add(String(L"") + A + IA); - _adjectiveEndings.add(String(L"") + IA + IA); - _adjectiveEndings.add(String(L"") + O + IU); - _adjectiveEndings.add(String(L"") + E + IU); - _adjectiveEndings.add(String(L"") + I + M + I); - _adjectiveEndings.add(String(L"") + Y + M + I); - _adjectiveEndings.add(String(L"") + E + G + O); - _adjectiveEndings.add(String(L"") + O + G + O); - _adjectiveEndings.add(String(L"") + E + M + U); - _adjectiveEndings.add(String(L"") + O + M + U); - } - return _adjectiveEndings; - } - - Collection RussianStemmer::participleEndings1() - { - static Collection _participleEndings1; - if (!_participleEndings1) - { - _participleEndings1 = Collection::newInstance(); - _participleEndings1.add(String(L"") + SHCH); - _participleEndings1.add(String(L"") + E + M); - _participleEndings1.add(String(L"") + N + N); - _participleEndings1.add(String(L"") + V + SH); - _participleEndings1.add(String(L"") + IU + SHCH); - } - return _participleEndings1; - } - - Collection RussianStemmer::participleEndings2() - { - static Collection _participleEndings2; - if (!_participleEndings2) - { - _participleEndings2 = Collection::newInstance(); - _participleEndings2.add(String(L"") + I + V + SH); - _participleEndings2.add(String(L"") + Y + V + SH); - _participleEndings2.add(String(L"") + U + IU + SHCH); - } - return _participleEndings2; +Collection RussianStemmer::perfectiveGerund1Predessors() { + static Collection _perfectiveGerund1Predessors; + if (!_perfectiveGerund1Predessors) { + _perfectiveGerund1Predessors = Collection::newInstance(); + _perfectiveGerund1Predessors.add(String(L"") + A); + _perfectiveGerund1Predessors.add(String(L"") + IA); } + return _perfectiveGerund1Predessors; +} - Collection RussianStemmer::participle1Predessors() - { - static Collection _participle1Predessors; - if (!_participle1Predessors) - { - _participle1Predessors = Collection::newInstance(); - _participle1Predessors.add(String(L"") + A); - _participle1Predessors.add(String(L"") + IA); - } - return _participle1Predessors; +Collection RussianStemmer::perfectiveGerundEndings2() { + static Collection _perfectiveGerundEndings2; + if (!_perfectiveGerundEndings2) { + _perfectiveGerundEndings2 = Collection::newInstance(); + _perfectiveGerundEndings2.add(String(L"") + I + V); + _perfectiveGerundEndings2.add(String(L"") + Y + V); + _perfectiveGerundEndings2.add(String(L"") + I + V + SH + I); + _perfectiveGerundEndings2.add(String(L"") + Y + V + SH + I); + _perfectiveGerundEndings2.add(String(L"") + I + V + SH + I + S + SOFT); + _perfectiveGerundEndings2.add(String(L"") + Y + V + SH + I + S + SOFT); + } + return _perfectiveGerundEndings2; +} + +Collection RussianStemmer::adjectiveEndings() { + static Collection _adjectiveEndings; + if (!_adjectiveEndings) { + _adjectiveEndings = Collection::newInstance(); + _adjectiveEndings.add(String(L"") + E + E); + _adjectiveEndings.add(String(L"") + I + E); + _adjectiveEndings.add(String(L"") + Y + E); + _adjectiveEndings.add(String(L"") + O + E); + _adjectiveEndings.add(String(L"") + E + I_); + _adjectiveEndings.add(String(L"") + I + I_); + _adjectiveEndings.add(String(L"") + Y + I_); + _adjectiveEndings.add(String(L"") + O + I_); + _adjectiveEndings.add(String(L"") + E + M); + _adjectiveEndings.add(String(L"") + I + M); + _adjectiveEndings.add(String(L"") + Y + M); + _adjectiveEndings.add(String(L"") + O + M); + _adjectiveEndings.add(String(L"") + I + X); + _adjectiveEndings.add(String(L"") + Y + X); + _adjectiveEndings.add(String(L"") + U + IU); + _adjectiveEndings.add(String(L"") + IU + IU); + _adjectiveEndings.add(String(L"") + A + IA); + _adjectiveEndings.add(String(L"") + IA + IA); + _adjectiveEndings.add(String(L"") + O + IU); + _adjectiveEndings.add(String(L"") + E + IU); + _adjectiveEndings.add(String(L"") + I + M + I); + _adjectiveEndings.add(String(L"") + Y + M + I); + _adjectiveEndings.add(String(L"") + E + G + O); + _adjectiveEndings.add(String(L"") + O + G + O); + _adjectiveEndings.add(String(L"") + E + M + U); + _adjectiveEndings.add(String(L"") + O + M + U); + } + return _adjectiveEndings; +} + +Collection RussianStemmer::participleEndings1() { + static Collection _participleEndings1; + if (!_participleEndings1) { + _participleEndings1 = Collection::newInstance(); + _participleEndings1.add(String(L"") + SHCH); + _participleEndings1.add(String(L"") + E + M); + _participleEndings1.add(String(L"") + N + N); + _participleEndings1.add(String(L"") + V + SH); + _participleEndings1.add(String(L"") + IU + SHCH); + } + return _participleEndings1; +} + +Collection RussianStemmer::participleEndings2() { + static Collection _participleEndings2; + if (!_participleEndings2) { + _participleEndings2 = Collection::newInstance(); + _participleEndings2.add(String(L"") + I + V + SH); + _participleEndings2.add(String(L"") + Y + V + SH); + _participleEndings2.add(String(L"") + U + IU + SHCH); } + return _participleEndings2; +} - Collection RussianStemmer::reflexiveEndings() - { - static Collection _participle1Predessors; - if (!_participle1Predessors) - { - _participle1Predessors = Collection::newInstance(); - _participle1Predessors.add(String(L"") + S + IA); - _participle1Predessors.add(String(L"") + S + SOFT); - } - return _participle1Predessors; - } - - Collection RussianStemmer::verbEndings1() - { - static Collection _verbEndings1; - if (!_verbEndings1) - { - _verbEndings1 = Collection::newInstance(); - _verbEndings1.add(String(L"") + I_); - _verbEndings1.add(String(L"") + L); - _verbEndings1.add(String(L"") + N); - _verbEndings1.add(String(L"") + L + O); - _verbEndings1.add(String(L"") + N + O); - _verbEndings1.add(String(L"") + E + T); - _verbEndings1.add(String(L"") + IU + T); - _verbEndings1.add(String(L"") + L + A); - _verbEndings1.add(String(L"") + N + A); - _verbEndings1.add(String(L"") + L + I); - _verbEndings1.add(String(L"") + E + M); - _verbEndings1.add(String(L"") + N + Y); - _verbEndings1.add(String(L"") + E + T + E); - _verbEndings1.add(String(L"") + I_ + T + E); - _verbEndings1.add(String(L"") + T + SOFT); - _verbEndings1.add(String(L"") + E + SH + SOFT); - _verbEndings1.add(String(L"") + N + N + O); - } - return _verbEndings1; - } - - Collection RussianStemmer::verbEndings2() - { - static Collection _verbEndings2; - if (!_verbEndings2) - { - _verbEndings2 = Collection::newInstance(); - _verbEndings2.add(String(L"") + IU); - _verbEndings2.add(String(L"") + U + IU); - _verbEndings2.add(String(L"") + E + N); - _verbEndings2.add(String(L"") + E + I_); - _verbEndings2.add(String(L"") + IA + T); - _verbEndings2.add(String(L"") + U + I_); - _verbEndings2.add(String(L"") + I + L); - _verbEndings2.add(String(L"") + Y + L); - _verbEndings2.add(String(L"") + I + M); - _verbEndings2.add(String(L"") + Y + M); - _verbEndings2.add(String(L"") + I + T); - _verbEndings2.add(String(L"") + Y + T); - _verbEndings2.add(String(L"") + I + L + A); - _verbEndings2.add(String(L"") + Y + L + A); - _verbEndings2.add(String(L"") + E + N + A); - _verbEndings2.add(String(L"") + I + T + E); - _verbEndings2.add(String(L"") + I + L + I); - _verbEndings2.add(String(L"") + Y + L + I); - _verbEndings2.add(String(L"") + I + L + O); - _verbEndings2.add(String(L"") + Y + L + O); - _verbEndings2.add(String(L"") + E + N + O); - _verbEndings2.add(String(L"") + U + E + T); - _verbEndings2.add(String(L"") + U + IU + T); - _verbEndings2.add(String(L"") + E + N + Y); - _verbEndings2.add(String(L"") + I + T + SOFT); - _verbEndings2.add(String(L"") + Y + T + SOFT); - _verbEndings2.add(String(L"") + I + SH + SOFT); - _verbEndings2.add(String(L"") + E + I_ + T + E); - _verbEndings2.add(String(L"") + U + I_ + T + E); - } - return _verbEndings2; +Collection RussianStemmer::participle1Predessors() { + static Collection _participle1Predessors; + if (!_participle1Predessors) { + _participle1Predessors = Collection::newInstance(); + _participle1Predessors.add(String(L"") + A); + _participle1Predessors.add(String(L"") + IA); } + return _participle1Predessors; +} - Collection RussianStemmer::verb1Predessors() - { - static Collection _verb1Predessors; - if (!_verb1Predessors) - { - _verb1Predessors = Collection::newInstance(); - _verb1Predessors.add(String(L"") + A); - _verb1Predessors.add(String(L"") + IA); - } - return _verb1Predessors; - } - - Collection RussianStemmer::nounEndings() - { - static Collection _nounEndings; - if (!_nounEndings) - { - _nounEndings = Collection::newInstance(); - _nounEndings.add(String(L"") + A); - _nounEndings.add(String(L"") + U); - _nounEndings.add(String(L"") + I_); - _nounEndings.add(String(L"") + O); - _nounEndings.add(String(L"") + U); - _nounEndings.add(String(L"") + E); - _nounEndings.add(String(L"") + Y); - _nounEndings.add(String(L"") + I); - _nounEndings.add(String(L"") + SOFT); - _nounEndings.add(String(L"") + IA); - _nounEndings.add(String(L"") + E + V); - _nounEndings.add(String(L"") + O + V); - _nounEndings.add(String(L"") + I + E); - _nounEndings.add(String(L"") + SOFT + E); - _nounEndings.add(String(L"") + IA + X); - _nounEndings.add(String(L"") + I + IU); - _nounEndings.add(String(L"") + E + I); - _nounEndings.add(String(L"") + I + I); - _nounEndings.add(String(L"") + E + I_); - _nounEndings.add(String(L"") + O + I_); - _nounEndings.add(String(L"") + E + M); - _nounEndings.add(String(L"") + A + M); - _nounEndings.add(String(L"") + O + M); - _nounEndings.add(String(L"") + A + X); - _nounEndings.add(String(L"") + SOFT + IU); - _nounEndings.add(String(L"") + I + IA); - _nounEndings.add(String(L"") + SOFT + IA); - _nounEndings.add(String(L"") + I + I_); - _nounEndings.add(String(L"") + IA + M); - _nounEndings.add(String(L"") + IA + M + I); - _nounEndings.add(String(L"") + A + M + I); - _nounEndings.add(String(L"") + I + E + I_); - _nounEndings.add(String(L"") + I + IA + M); - _nounEndings.add(String(L"") + I + E + M); - _nounEndings.add(String(L"") + I + IA + X); - _nounEndings.add(String(L"") + I + IA + M + I); - } - return _nounEndings; +Collection RussianStemmer::reflexiveEndings() { + static Collection _participle1Predessors; + if (!_participle1Predessors) { + _participle1Predessors = Collection::newInstance(); + _participle1Predessors.add(String(L"") + S + IA); + _participle1Predessors.add(String(L"") + S + SOFT); + } + return _participle1Predessors; +} + +Collection RussianStemmer::verbEndings1() { + static Collection _verbEndings1; + if (!_verbEndings1) { + _verbEndings1 = Collection::newInstance(); + _verbEndings1.add(String(L"") + I_); + _verbEndings1.add(String(L"") + L); + _verbEndings1.add(String(L"") + N); + _verbEndings1.add(String(L"") + L + O); + _verbEndings1.add(String(L"") + N + O); + _verbEndings1.add(String(L"") + E + T); + _verbEndings1.add(String(L"") + IU + T); + _verbEndings1.add(String(L"") + L + A); + _verbEndings1.add(String(L"") + N + A); + _verbEndings1.add(String(L"") + L + I); + _verbEndings1.add(String(L"") + E + M); + _verbEndings1.add(String(L"") + N + Y); + _verbEndings1.add(String(L"") + E + T + E); + _verbEndings1.add(String(L"") + I_ + T + E); + _verbEndings1.add(String(L"") + T + SOFT); + _verbEndings1.add(String(L"") + E + SH + SOFT); + _verbEndings1.add(String(L"") + N + N + O); + } + return _verbEndings1; +} + +Collection RussianStemmer::verbEndings2() { + static Collection _verbEndings2; + if (!_verbEndings2) { + _verbEndings2 = Collection::newInstance(); + _verbEndings2.add(String(L"") + IU); + _verbEndings2.add(String(L"") + U + IU); + _verbEndings2.add(String(L"") + E + N); + _verbEndings2.add(String(L"") + E + I_); + _verbEndings2.add(String(L"") + IA + T); + _verbEndings2.add(String(L"") + U + I_); + _verbEndings2.add(String(L"") + I + L); + _verbEndings2.add(String(L"") + Y + L); + _verbEndings2.add(String(L"") + I + M); + _verbEndings2.add(String(L"") + Y + M); + _verbEndings2.add(String(L"") + I + T); + _verbEndings2.add(String(L"") + Y + T); + _verbEndings2.add(String(L"") + I + L + A); + _verbEndings2.add(String(L"") + Y + L + A); + _verbEndings2.add(String(L"") + E + N + A); + _verbEndings2.add(String(L"") + I + T + E); + _verbEndings2.add(String(L"") + I + L + I); + _verbEndings2.add(String(L"") + Y + L + I); + _verbEndings2.add(String(L"") + I + L + O); + _verbEndings2.add(String(L"") + Y + L + O); + _verbEndings2.add(String(L"") + E + N + O); + _verbEndings2.add(String(L"") + U + E + T); + _verbEndings2.add(String(L"") + U + IU + T); + _verbEndings2.add(String(L"") + E + N + Y); + _verbEndings2.add(String(L"") + I + T + SOFT); + _verbEndings2.add(String(L"") + Y + T + SOFT); + _verbEndings2.add(String(L"") + I + SH + SOFT); + _verbEndings2.add(String(L"") + E + I_ + T + E); + _verbEndings2.add(String(L"") + U + I_ + T + E); + } + return _verbEndings2; +} + +Collection RussianStemmer::verb1Predessors() { + static Collection _verb1Predessors; + if (!_verb1Predessors) { + _verb1Predessors = Collection::newInstance(); + _verb1Predessors.add(String(L"") + A); + _verb1Predessors.add(String(L"") + IA); } + return _verb1Predessors; +} - Collection RussianStemmer::superlativeEndings() - { - static Collection _superlativeEndings; - if (!_superlativeEndings) - { - _superlativeEndings = Collection::newInstance(); - _superlativeEndings.add(String(L"") + E + I_ + SH); - _superlativeEndings.add(String(L"") + E + I_ + SH + E); - } - return _superlativeEndings; +Collection RussianStemmer::nounEndings() { + static Collection _nounEndings; + if (!_nounEndings) { + _nounEndings = Collection::newInstance(); + _nounEndings.add(String(L"") + A); + _nounEndings.add(String(L"") + U); + _nounEndings.add(String(L"") + I_); + _nounEndings.add(String(L"") + O); + _nounEndings.add(String(L"") + U); + _nounEndings.add(String(L"") + E); + _nounEndings.add(String(L"") + Y); + _nounEndings.add(String(L"") + I); + _nounEndings.add(String(L"") + SOFT); + _nounEndings.add(String(L"") + IA); + _nounEndings.add(String(L"") + E + V); + _nounEndings.add(String(L"") + O + V); + _nounEndings.add(String(L"") + I + E); + _nounEndings.add(String(L"") + SOFT + E); + _nounEndings.add(String(L"") + IA + X); + _nounEndings.add(String(L"") + I + IU); + _nounEndings.add(String(L"") + E + I); + _nounEndings.add(String(L"") + I + I); + _nounEndings.add(String(L"") + E + I_); + _nounEndings.add(String(L"") + O + I_); + _nounEndings.add(String(L"") + E + M); + _nounEndings.add(String(L"") + A + M); + _nounEndings.add(String(L"") + O + M); + _nounEndings.add(String(L"") + A + X); + _nounEndings.add(String(L"") + SOFT + IU); + _nounEndings.add(String(L"") + I + IA); + _nounEndings.add(String(L"") + SOFT + IA); + _nounEndings.add(String(L"") + I + I_); + _nounEndings.add(String(L"") + IA + M); + _nounEndings.add(String(L"") + IA + M + I); + _nounEndings.add(String(L"") + A + M + I); + _nounEndings.add(String(L"") + I + E + I_); + _nounEndings.add(String(L"") + I + IA + M); + _nounEndings.add(String(L"") + I + E + M); + _nounEndings.add(String(L"") + I + IA + X); + _nounEndings.add(String(L"") + I + IA + M + I); + } + return _nounEndings; +} + +Collection RussianStemmer::superlativeEndings() { + static Collection _superlativeEndings; + if (!_superlativeEndings) { + _superlativeEndings = Collection::newInstance(); + _superlativeEndings.add(String(L"") + E + I_ + SH); + _superlativeEndings.add(String(L"") + E + I_ + SH + E); } + return _superlativeEndings; +} - Collection RussianStemmer::derivationalEndings() - { - static Collection _derivationalEndings; - if (!_derivationalEndings) - { - _derivationalEndings = Collection::newInstance(); - _derivationalEndings.add(String(L"") + O + S + T); - _derivationalEndings.add(String(L"") + O + S + T + SOFT); - } - return _derivationalEndings; +Collection RussianStemmer::derivationalEndings() { + static Collection _derivationalEndings; + if (!_derivationalEndings) { + _derivationalEndings = Collection::newInstance(); + _derivationalEndings.add(String(L"") + O + S + T); + _derivationalEndings.add(String(L"") + O + S + T + SOFT); } + return _derivationalEndings; +} - Collection RussianStemmer::doubleN() - { - static Collection _doubleN; - if (!_doubleN) - { - _doubleN = Collection::newInstance(); - _doubleN.add(String(L"") + N + N); - } - return _doubleN; +Collection RussianStemmer::doubleN() { + static Collection _doubleN; + if (!_doubleN) { + _doubleN = Collection::newInstance(); + _doubleN.add(String(L"") + N + N); } + return _doubleN; +} - String RussianStemmer::stem(const String& input) - { - markPositions(input); - if (RV == 0) - return input; // RV wasn't detected, nothing to stem +String RussianStemmer::stem(const String& input) { + markPositions(input); + if (RV == 0) { + return input; // RV wasn't detected, nothing to stem + } - String stemmingZone(input.substr(RV)); + String stemmingZone(input.substr(RV)); - // stemming goes on in RV + // stemming goes on in RV - // Step 1 - if (!perfectiveGerund(stemmingZone)) - { - reflexive(stemmingZone); + // Step 1 + if (!perfectiveGerund(stemmingZone)) { + reflexive(stemmingZone); - if (!adjectival(stemmingZone)) - { - if (!verb(stemmingZone)) - noun(stemmingZone); + if (!adjectival(stemmingZone)) { + if (!verb(stemmingZone)) { + noun(stemmingZone); } } + } - // Step 2 - removeI(stemmingZone); + // Step 2 + removeI(stemmingZone); - // Step 3 - derivational(stemmingZone); + // Step 3 + derivational(stemmingZone); - // Step 4 - superlative(stemmingZone); - undoubleN(stemmingZone); - removeSoft(stemmingZone); + // Step 4 + superlative(stemmingZone); + undoubleN(stemmingZone); + removeSoft(stemmingZone); - // return result - return input.substr(0, RV) + stemmingZone; - } - - String RussianStemmer::stemWord(const String& word) - { - return newLucene()->stem(word); - } + // return result + return input.substr(0, RV) + stemmingZone; +} - bool RussianStemmer::adjectival(String& stemmingZone) - { - // look for adjective ending in a stemming zone - if (!findAndRemoveEnding(stemmingZone, adjectiveEndings())) - return false; +String RussianStemmer::stemWord(const String& word) { + return newLucene()->stem(word); +} - if (!findAndRemoveEnding(stemmingZone, participleEndings1(), participle1Predessors())) - findAndRemoveEnding(stemmingZone, participleEndings2()); +bool RussianStemmer::adjectival(String& stemmingZone) { + // look for adjective ending in a stemming zone + if (!findAndRemoveEnding(stemmingZone, adjectiveEndings())) { + return false; + } - return true; + if (!findAndRemoveEnding(stemmingZone, participleEndings1(), participle1Predessors())) { + findAndRemoveEnding(stemmingZone, participleEndings2()); } - bool RussianStemmer::derivational(String& stemmingZone) - { - int32_t endingLength = findEnding(stemmingZone, derivationalEndings()); - if (endingLength == 0) - return false; // no derivational ending found - else - { - // Ensure that the ending locates in R2 - if (R2 - RV <= (int32_t)stemmingZone.length() - endingLength) - { - stemmingZone.resize(stemmingZone.length() - endingLength); - return true; - } - else - return false; + return true; +} + +bool RussianStemmer::derivational(String& stemmingZone) { + int32_t endingLength = findEnding(stemmingZone, derivationalEndings()); + if (endingLength == 0) { + return false; // no derivational ending found + } else { + // Ensure that the ending locates in R2 + if (R2 - RV <= (int32_t)stemmingZone.length() - endingLength) { + stemmingZone.resize(stemmingZone.length() - endingLength); + return true; + } else { + return false; } } +} - int32_t RussianStemmer::findEnding(String& stemmingZone, int32_t startIndex, Collection theEndingClass) - { - bool match = false; - for (int32_t i = theEndingClass.size() - 1; i >= 0; --i) - { - String theEnding(theEndingClass[i]); - // check if the ending is bigger than stemming zone - if (startIndex < (int32_t)theEnding.length() - 1) - { +int32_t RussianStemmer::findEnding(String& stemmingZone, int32_t startIndex, Collection theEndingClass) { + bool match = false; + for (int32_t i = theEndingClass.size() - 1; i >= 0; --i) { + String theEnding(theEndingClass[i]); + // check if the ending is bigger than stemming zone + if (startIndex < (int32_t)theEnding.length() - 1) { + match = false; + continue; + } + match = true; + int32_t stemmingIndex = startIndex; + for (int32_t j = (int32_t)theEnding.length() - 1; j >= 0; --j) { + if (stemmingZone[stemmingIndex--] != theEnding[j]) { match = false; - continue; + break; } - match = true; - int32_t stemmingIndex = startIndex; - for (int32_t j = (int32_t)theEnding.length() - 1; j >= 0; --j) - { - if (stemmingZone[stemmingIndex--] != theEnding[j]) - { - match = false; - break; - } - } - // check if ending was found - if (match) - return (int32_t)theEndingClass[i].size(); // cut ending } - return 0; + // check if ending was found + if (match) { + return (int32_t)theEndingClass[i].size(); // cut ending + } } + return 0; +} - int32_t RussianStemmer::findEnding(String& stemmingZone, Collection theEndingClass) - { - return findEnding(stemmingZone, (int32_t)(stemmingZone.length() - 1), theEndingClass); +int32_t RussianStemmer::findEnding(String& stemmingZone, Collection theEndingClass) { + return findEnding(stemmingZone, (int32_t)(stemmingZone.length() - 1), theEndingClass); +} + +bool RussianStemmer::findAndRemoveEnding(String& stemmingZone, Collection theEndingClass) { + int32_t endingLength = findEnding(stemmingZone, theEndingClass); + if (endingLength == 0) { + return false; // not found + } else { + stemmingZone.resize(stemmingZone.length() - endingLength); + return true; // cut the ending found } +} - bool RussianStemmer::findAndRemoveEnding(String& stemmingZone, Collection theEndingClass) - { - int32_t endingLength = findEnding(stemmingZone, theEndingClass); - if (endingLength == 0) - return false; // not found - else - { +bool RussianStemmer::findAndRemoveEnding(String& stemmingZone, Collection theEndingClass, Collection thePredessors) { + int32_t endingLength = findEnding(stemmingZone, theEndingClass); + if (endingLength == 0) { + return false; // not found + } else { + int32_t predessorLength = findEnding(stemmingZone, (int32_t)(stemmingZone.length() - endingLength - 1), thePredessors); + if (predessorLength == 0) { + return false; + } else { stemmingZone.resize(stemmingZone.length() - endingLength); return true; // cut the ending found } } +} - bool RussianStemmer::findAndRemoveEnding(String& stemmingZone, Collection theEndingClass, Collection thePredessors) - { - int32_t endingLength = findEnding(stemmingZone, theEndingClass); - if (endingLength == 0) - return false; // not found - else - { - int32_t predessorLength = findEnding(stemmingZone, (int32_t)(stemmingZone.length() - endingLength - 1), thePredessors); - if (predessorLength == 0) - return false; - else - { - stemmingZone.resize(stemmingZone.length() - endingLength); - return true; // cut the ending found - } - } +void RussianStemmer::markPositions(const String& word) { + RV = 0; + R1 = 0; + R2 = 0; + int32_t i = 0; + // find RV + while ((int32_t)word.length() > i && !isVowel(word[i])) { + ++i; } - - void RussianStemmer::markPositions(const String& word) - { - RV = 0; - R1 = 0; - R2 = 0; - int32_t i = 0; - // find RV - while ((int32_t)word.length() > i && !isVowel(word[i])) - ++i; - if ((int32_t)word.length() - 1 < ++i) - return; // RV zone is empty - RV = i; - // find R1 - while ((int32_t)word.length() > i && isVowel(word[i])) - ++i; - if ((int32_t)word.length() - 1 < ++i) - return; // R1 zone is empty - R1 = i; - // find R2 - while ((int32_t)word.length() > i && !isVowel(word[i])) - ++i; - if ((int32_t)word.length() - 1 < ++i) - return; // R2 zone is empty - while ((int32_t)word.length() > i && isVowel(word[i])) - ++i; - if ((int32_t)word.length() - 1 < ++i) - return; // R2 zone is empty - R2 = i; - } - - bool RussianStemmer::isVowel(wchar_t letter) - { - for (int32_t i = 0; i < SIZEOF_ARRAY(vowels); ++i) - { - if (letter == vowels[i]) - return true; - } - return false; + if ((int32_t)word.length() - 1 < ++i) { + return; // RV zone is empty } - - bool RussianStemmer::noun(String& stemmingZone) - { - return findAndRemoveEnding(stemmingZone, nounEndings()); + RV = i; + // find R1 + while ((int32_t)word.length() > i && isVowel(word[i])) { + ++i; } - - bool RussianStemmer::perfectiveGerund(String& stemmingZone) - { - return findAndRemoveEnding(stemmingZone, perfectiveGerundEndings1(), perfectiveGerund1Predessors()) || - findAndRemoveEnding(stemmingZone, perfectiveGerundEndings2()); + if ((int32_t)word.length() - 1 < ++i) { + return; // R1 zone is empty } - - bool RussianStemmer::reflexive(String& stemmingZone) - { - return findAndRemoveEnding(stemmingZone, reflexiveEndings()); + R1 = i; + // find R2 + while ((int32_t)word.length() > i && !isVowel(word[i])) { + ++i; } - - bool RussianStemmer::removeI(String& stemmingZone) - { - if ((int32_t)stemmingZone.length() > 0 && stemmingZone[stemmingZone.length() - 1] == I) - { - stemmingZone.resize(stemmingZone.length() - 1); - return true; - } - else - return false; + if ((int32_t)word.length() - 1 < ++i) { + return; // R2 zone is empty } + while ((int32_t)word.length() > i && isVowel(word[i])) { + ++i; + } + if ((int32_t)word.length() - 1 < ++i) { + return; // R2 zone is empty + } + R2 = i; +} - bool RussianStemmer::removeSoft(String& stemmingZone) - { - if ((int32_t)stemmingZone.length() > 0 && stemmingZone[stemmingZone.length() - 1] == SOFT) - { - stemmingZone.resize(stemmingZone.length() - 1); +bool RussianStemmer::isVowel(wchar_t letter) { + for (int32_t i = 0; i < SIZEOF_ARRAY(vowels); ++i) { + if (letter == vowels[i]) { return true; } - return false; } + return false; +} + +bool RussianStemmer::noun(String& stemmingZone) { + return findAndRemoveEnding(stemmingZone, nounEndings()); +} - bool RussianStemmer::superlative(String& stemmingZone) - { - return findAndRemoveEnding(stemmingZone, superlativeEndings()); +bool RussianStemmer::perfectiveGerund(String& stemmingZone) { + return findAndRemoveEnding(stemmingZone, perfectiveGerundEndings1(), perfectiveGerund1Predessors()) || + findAndRemoveEnding(stemmingZone, perfectiveGerundEndings2()); +} + +bool RussianStemmer::reflexive(String& stemmingZone) { + return findAndRemoveEnding(stemmingZone, reflexiveEndings()); +} + +bool RussianStemmer::removeI(String& stemmingZone) { + if ((int32_t)stemmingZone.length() > 0 && stemmingZone[stemmingZone.length() - 1] == I) { + stemmingZone.resize(stemmingZone.length() - 1); + return true; + } else { + return false; } +} - bool RussianStemmer::undoubleN(String& stemmingZone) - { - if (findEnding(stemmingZone, doubleN()) != 0) - { - stemmingZone.resize(stemmingZone.length() - 1); - return true; - } - else - return false; +bool RussianStemmer::removeSoft(String& stemmingZone) { + if ((int32_t)stemmingZone.length() > 0 && stemmingZone[stemmingZone.length() - 1] == SOFT) { + stemmingZone.resize(stemmingZone.length() - 1); + return true; } + return false; +} + +bool RussianStemmer::superlative(String& stemmingZone) { + return findAndRemoveEnding(stemmingZone, superlativeEndings()); +} - bool RussianStemmer::verb(String& stemmingZone) - { - return findAndRemoveEnding(stemmingZone, verbEndings1(), verb1Predessors()) || - findAndRemoveEnding(stemmingZone, verbEndings2()); +bool RussianStemmer::undoubleN(String& stemmingZone) { + if (findEnding(stemmingZone, doubleN()) != 0) { + stemmingZone.resize(stemmingZone.length() - 1); + return true; + } else { + return false; } } + +bool RussianStemmer::verb(String& stemmingZone) { + return findAndRemoveEnding(stemmingZone, verbEndings1(), verb1Predessors()) || + findAndRemoveEnding(stemmingZone, verbEndings2()); +} + +} diff --git a/src/contrib/highlighter/DefaultEncoder.cpp b/src/contrib/highlighter/DefaultEncoder.cpp index bf0ec07c..c23bbb88 100644 --- a/src/contrib/highlighter/DefaultEncoder.cpp +++ b/src/contrib/highlighter/DefaultEncoder.cpp @@ -7,14 +7,13 @@ #include "ContribInc.h" #include "DefaultEncoder.h" -namespace Lucene -{ - DefaultEncoder::~DefaultEncoder() - { - } +namespace Lucene { + +DefaultEncoder::~DefaultEncoder() { +} + +String DefaultEncoder::encodeText(const String& originalText) { + return originalText; +} - String DefaultEncoder::encodeText(const String& originalText) - { - return originalText; - } } diff --git a/src/contrib/highlighter/Encoder.cpp b/src/contrib/highlighter/Encoder.cpp index c3db84da..d5882db4 100644 --- a/src/contrib/highlighter/Encoder.cpp +++ b/src/contrib/highlighter/Encoder.cpp @@ -7,15 +7,14 @@ #include "ContribInc.h" #include "Encoder.h" -namespace Lucene -{ - Encoder::~Encoder() - { - } +namespace Lucene { + +Encoder::~Encoder() { +} + +String Encoder::encodeText(const String& originalText) { + BOOST_ASSERT(false); + return L""; // override +} - String Encoder::encodeText(const String& originalText) - { - BOOST_ASSERT(false); - return L""; // override - } } diff --git a/src/contrib/highlighter/Formatter.cpp b/src/contrib/highlighter/Formatter.cpp index 1f832c79..24b28083 100644 --- a/src/contrib/highlighter/Formatter.cpp +++ b/src/contrib/highlighter/Formatter.cpp @@ -7,15 +7,14 @@ #include "ContribInc.h" #include "Formatter.h" -namespace Lucene -{ - Formatter::~Formatter() - { - } +namespace Lucene { + +Formatter::~Formatter() { +} + +String Formatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { + BOOST_ASSERT(false); + return L""; // override +} - String Formatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) - { - BOOST_ASSERT(false); - return L""; // override - } } diff --git a/src/contrib/highlighter/Fragmenter.cpp b/src/contrib/highlighter/Fragmenter.cpp index df74f99b..70723cf0 100644 --- a/src/contrib/highlighter/Fragmenter.cpp +++ b/src/contrib/highlighter/Fragmenter.cpp @@ -7,21 +7,19 @@ #include "ContribInc.h" #include "Fragmenter.h" -namespace Lucene -{ - Fragmenter::~Fragmenter() - { - } +namespace Lucene { - void Fragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) - { - BOOST_ASSERT(false); - // override - } +Fragmenter::~Fragmenter() { +} + +void Fragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { + BOOST_ASSERT(false); + // override +} + +bool Fragmenter::isNewFragment() { + BOOST_ASSERT(false); + return false; // override +} - bool Fragmenter::isNewFragment() - { - BOOST_ASSERT(false); - return false; // override - } } diff --git a/src/contrib/highlighter/GradientFormatter.cpp b/src/contrib/highlighter/GradientFormatter.cpp index 9a03eb74..9a32ba41 100644 --- a/src/contrib/highlighter/GradientFormatter.cpp +++ b/src/contrib/highlighter/GradientFormatter.cpp @@ -9,120 +9,121 @@ #include "TokenGroup.h" #include "StringUtils.h" -namespace Lucene -{ - GradientFormatter::GradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor) - { - highlightForeground = (!minForegroundColor.empty() && !maxForegroundColor.empty()); - if (highlightForeground) - { - if (minForegroundColor.length() != 7) - boost::throw_exception(IllegalArgumentException(L"minForegroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); - if (maxForegroundColor.length() != 7) - boost::throw_exception(IllegalArgumentException(L"maxForegroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); - - fgRMin = hexToInt(minForegroundColor.substr(1, 2)); - fgGMin = hexToInt(minForegroundColor.substr(3, 2)); - fgBMin = hexToInt(minForegroundColor.substr(5, 2)); - - fgRMax = hexToInt(maxForegroundColor.substr(1, 2)); - fgGMax = hexToInt(maxForegroundColor.substr(3, 2)); - fgBMax = hexToInt(maxForegroundColor.substr(5, 2)); - } +namespace Lucene { - highlightBackground = (!minBackgroundColor.empty() && !maxBackgroundColor.empty()); - if (highlightBackground) - { - if (minBackgroundColor.length() != 7) - boost::throw_exception(IllegalArgumentException(L"minBackgroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); - if (maxBackgroundColor.length() != 7) - boost::throw_exception(IllegalArgumentException(L"maxBackgroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); - - bgRMin = hexToInt(minBackgroundColor.substr(1, 2)); - bgGMin = hexToInt(minBackgroundColor.substr(3, 2)); - bgBMin = hexToInt(minBackgroundColor.substr(5, 2)); - - bgRMax = hexToInt(maxBackgroundColor.substr(1, 2)); - bgGMax = hexToInt(maxBackgroundColor.substr(3, 2)); - bgBMax = hexToInt(maxBackgroundColor.substr(5, 2)); +GradientFormatter::GradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor) { + highlightForeground = (!minForegroundColor.empty() && !maxForegroundColor.empty()); + if (highlightForeground) { + if (minForegroundColor.length() != 7) { + boost::throw_exception(IllegalArgumentException(L"minForegroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); + } + if (maxForegroundColor.length() != 7) { + boost::throw_exception(IllegalArgumentException(L"maxForegroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); } - this->maxScore = maxScore; - } + fgRMin = hexToInt(minForegroundColor.substr(1, 2)); + fgGMin = hexToInt(minForegroundColor.substr(3, 2)); + fgBMin = hexToInt(minForegroundColor.substr(5, 2)); - GradientFormatter::~GradientFormatter() - { + fgRMax = hexToInt(maxForegroundColor.substr(1, 2)); + fgGMax = hexToInt(maxForegroundColor.substr(3, 2)); + fgBMax = hexToInt(maxForegroundColor.substr(5, 2)); } - String GradientFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) - { - if (tokenGroup->getTotalScore() == 0) - return originalText; - double score = tokenGroup->getTotalScore(); - if (score == 0.0) - return originalText; - StringStream buffer; - buffer << L"" << originalText << L""; - return buffer.str(); - } + highlightBackground = (!minBackgroundColor.empty() && !maxBackgroundColor.empty()); + if (highlightBackground) { + if (minBackgroundColor.length() != 7) { + boost::throw_exception(IllegalArgumentException(L"minBackgroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); + } + if (maxBackgroundColor.length() != 7) { + boost::throw_exception(IllegalArgumentException(L"maxBackgroundColor is not 7 bytes long eg a hex RGB value such as #FFFFFF")); + } - String GradientFormatter::getForegroundColorString(double score) - { - int32_t rVal = getColorVal(fgRMin, fgRMax, score); - int32_t gVal = getColorVal(fgGMin, fgGMax, score); - int32_t bVal = getColorVal(fgBMin, fgBMax, score); - StringStream buffer; - buffer << L"#" << intToHex(rVal) << intToHex(gVal) << intToHex(bVal); - return buffer.str(); - } + bgRMin = hexToInt(minBackgroundColor.substr(1, 2)); + bgGMin = hexToInt(minBackgroundColor.substr(3, 2)); + bgBMin = hexToInt(minBackgroundColor.substr(5, 2)); - String GradientFormatter::getBackgroundColorString(double score) - { - int32_t rVal = getColorVal(bgRMin, bgRMax, score); - int32_t gVal = getColorVal(bgGMin, bgGMax, score); - int32_t bVal = getColorVal(bgBMin, bgBMax, score); - StringStream buffer; - buffer << L"#" << intToHex(rVal) << intToHex(gVal) << intToHex(bVal); - return buffer.str(); + bgRMax = hexToInt(maxBackgroundColor.substr(1, 2)); + bgGMax = hexToInt(maxBackgroundColor.substr(3, 2)); + bgBMax = hexToInt(maxBackgroundColor.substr(5, 2)); } - int32_t GradientFormatter::getColorVal(int32_t colorMin, int32_t colorMax, double score) - { - if (colorMin == colorMax) - return colorMin; - double scale = std::abs((double)(colorMin - colorMax)); - double relScorePercent = std::min(maxScore, score) / maxScore; - double colScore = scale * relScorePercent; - return std::min(colorMin, colorMax) + (int32_t)colScore; + this->maxScore = maxScore; +} + +GradientFormatter::~GradientFormatter() { +} + +String GradientFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { + if (tokenGroup->getTotalScore() == 0) { + return originalText; + } + double score = tokenGroup->getTotalScore(); + if (score == 0.0) { + return originalText; + } + StringStream buffer; + buffer << L"" << originalText << L""; + return buffer.str(); +} + +String GradientFormatter::getForegroundColorString(double score) { + int32_t rVal = getColorVal(fgRMin, fgRMax, score); + int32_t gVal = getColorVal(fgGMin, fgGMax, score); + int32_t bVal = getColorVal(fgBMin, fgBMax, score); + StringStream buffer; + buffer << L"#" << intToHex(rVal) << intToHex(gVal) << intToHex(bVal); + return buffer.str(); +} + +String GradientFormatter::getBackgroundColorString(double score) { + int32_t rVal = getColorVal(bgRMin, bgRMax, score); + int32_t gVal = getColorVal(bgGMin, bgGMax, score); + int32_t bVal = getColorVal(bgBMin, bgBMax, score); + StringStream buffer; + buffer << L"#" << intToHex(rVal) << intToHex(gVal) << intToHex(bVal); + return buffer.str(); +} - String GradientFormatter::intToHex(int32_t i) - { - static const wchar_t* hexDigits = L"0123456789abcdef"; - StringStream buffer; - buffer << hexDigits[(i & 0xf0) >> 4] << hexDigits[i & 0x0f]; - return buffer.str(); +int32_t GradientFormatter::getColorVal(int32_t colorMin, int32_t colorMax, double score) { + if (colorMin == colorMax) { + return colorMin; } + double scale = std::abs((double)(colorMin - colorMax)); + double relScorePercent = std::min(maxScore, score) / maxScore; + double colScore = scale * relScorePercent; + return std::min(colorMin, colorMax) + (int32_t)colScore; +} + +String GradientFormatter::intToHex(int32_t i) { + static const wchar_t* hexDigits = L"0123456789abcdef"; + StringStream buffer; + buffer << hexDigits[(i & 0xf0) >> 4] << hexDigits[i & 0x0f]; + return buffer.str(); +} - int32_t GradientFormatter::hexToInt(const String& hex) - { - int32_t len = (int32_t)hex.length(); - if (len > 16) +int32_t GradientFormatter::hexToInt(const String& hex) { + int32_t len = (int32_t)hex.length(); + if (len > 16) { + boost::throw_exception(NumberFormatException()); + } + int32_t l = 0; + for (int32_t i = 0; i < len; ++i) { + l <<= 4; + int32_t c = (int32_t)StringUtils::toLong(hex.substr(i, 1), 16); + if (c < 0) { boost::throw_exception(NumberFormatException()); - int32_t l = 0; - for (int32_t i = 0; i < len; ++i) - { - l <<= 4; - int32_t c = (int32_t)StringUtils::toLong(hex.substr(i, 1), 16); - if (c < 0) - boost::throw_exception(NumberFormatException()); - l |= c; } - return l; + l |= c; } + return l; +} + } diff --git a/src/contrib/highlighter/Highlighter.cpp b/src/contrib/highlighter/Highlighter.cpp index a8ad89d1..9f9f2ede 100644 --- a/src/contrib/highlighter/Highlighter.cpp +++ b/src/contrib/highlighter/Highlighter.cpp @@ -21,338 +21,302 @@ #include "SimpleFragmenter.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t Highlighter::DEFAULT_MAX_CHARS_TO_ANALYZE = 50 * 1024; - - Highlighter::Highlighter(const HighlighterScorerPtr& fragmentScorer) - { - this->formatter = newLucene(); - this->encoder = newLucene(); - this->fragmentScorer = fragmentScorer; - this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; - this->textFragmenter = newLucene(); - } +namespace Lucene { - Highlighter::Highlighter(const FormatterPtr& formatter, const HighlighterScorerPtr& fragmentScorer) - { - this->formatter = formatter; - this->encoder = newLucene(); - this->fragmentScorer = fragmentScorer; - this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; - this->textFragmenter = newLucene(); - } +const int32_t Highlighter::DEFAULT_MAX_CHARS_TO_ANALYZE = 50 * 1024; - Highlighter::Highlighter(const FormatterPtr& formatter, const EncoderPtr& encoder, const HighlighterScorerPtr& fragmentScorer) - { - this->formatter = formatter; - this->encoder = encoder; - this->fragmentScorer = fragmentScorer; - this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; - this->textFragmenter = newLucene(); - } +Highlighter::Highlighter(const HighlighterScorerPtr& fragmentScorer) { + this->formatter = newLucene(); + this->encoder = newLucene(); + this->fragmentScorer = fragmentScorer; + this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; + this->textFragmenter = newLucene(); +} - Highlighter::~Highlighter() - { - } +Highlighter::Highlighter(const FormatterPtr& formatter, const HighlighterScorerPtr& fragmentScorer) { + this->formatter = formatter; + this->encoder = newLucene(); + this->fragmentScorer = fragmentScorer; + this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; + this->textFragmenter = newLucene(); +} - String Highlighter::getBestFragment(const AnalyzerPtr& analyzer, const String& fieldName, const String& text) - { - TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); - return getBestFragment(tokenStream, text); - } +Highlighter::Highlighter(const FormatterPtr& formatter, const EncoderPtr& encoder, const HighlighterScorerPtr& fragmentScorer) { + this->formatter = formatter; + this->encoder = encoder; + this->fragmentScorer = fragmentScorer; + this->maxDocCharsToAnalyze = DEFAULT_MAX_CHARS_TO_ANALYZE; + this->textFragmenter = newLucene(); +} - String Highlighter::getBestFragment(const TokenStreamPtr& tokenStream, const String& text) - { - Collection results(getBestFragments(tokenStream,text, 1)); - return results.empty() ? L"" : results[0]; - } +Highlighter::~Highlighter() { +} - Collection Highlighter::getBestFragments(const AnalyzerPtr& analyzer, const String& fieldName, const String& text, int32_t maxNumFragments) - { - TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); - return getBestFragments(tokenStream, text, maxNumFragments); - } +String Highlighter::getBestFragment(const AnalyzerPtr& analyzer, const String& fieldName, const String& text) { + TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); + return getBestFragment(tokenStream, text); +} - Collection Highlighter::getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments) - { - maxNumFragments = std::max((int32_t)1, maxNumFragments); //sanity check +String Highlighter::getBestFragment(const TokenStreamPtr& tokenStream, const String& text) { + Collection results(getBestFragments(tokenStream,text, 1)); + return results.empty() ? L"" : results[0]; +} - Collection frag(getBestTextFragments(tokenStream, text, true, maxNumFragments)); +Collection Highlighter::getBestFragments(const AnalyzerPtr& analyzer, const String& fieldName, const String& text, int32_t maxNumFragments) { + TokenStreamPtr tokenStream(analyzer->tokenStream(fieldName, newLucene(text))); + return getBestFragments(tokenStream, text, maxNumFragments); +} - // Get text - Collection fragTexts(Collection::newInstance()); - for (int32_t i = 0; i < frag.size(); ++i) - { - if (frag[i] && frag[i]->getScore() > 0) - fragTexts.add(frag[i]->toString()); +Collection Highlighter::getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments) { + maxNumFragments = std::max((int32_t)1, maxNumFragments); //sanity check + + Collection frag(getBestTextFragments(tokenStream, text, true, maxNumFragments)); + + // Get text + Collection fragTexts(Collection::newInstance()); + for (int32_t i = 0; i < frag.size(); ++i) { + if (frag[i] && frag[i]->getScore() > 0) { + fragTexts.add(frag[i]->toString()); } - return fragTexts; } + return fragTexts; +} - Collection Highlighter::getBestTextFragments(const TokenStreamPtr& tokenStream, const String& text, bool merge, int32_t maxNumFragments) - { - Collection docFrags(Collection::newInstance()); - StringBufferPtr newText(newLucene()); - - TokenStreamPtr _tokenStream(tokenStream); - TermAttributePtr termAtt(_tokenStream->addAttribute()); - OffsetAttributePtr offsetAtt(_tokenStream->addAttribute()); - _tokenStream->addAttribute(); - _tokenStream->reset(); - - TextFragmentPtr currentFrag(newLucene(newText, newText->length(), docFrags.size())); - TokenStreamPtr newStream(fragmentScorer->init(_tokenStream)); - if (newStream) - _tokenStream = newStream; - fragmentScorer->startFragment(currentFrag); - docFrags.add(currentFrag); - - FragmentQueuePtr fragQueue(newLucene(maxNumFragments)); - Collection frag; - - LuceneException finally; - try - { - textFragmenter->start(text, _tokenStream); - TokenGroupPtr tokenGroup(newLucene(_tokenStream)); - String tokenText; - int32_t startOffset = 0; - int32_t endOffset = 0; - int32_t lastEndOffset = 0; - - for (bool next = _tokenStream->incrementToken(); next && offsetAtt->startOffset() < maxDocCharsToAnalyze; next = _tokenStream->incrementToken()) - { - if (offsetAtt->endOffset() > (int32_t)text.length() || offsetAtt->startOffset() > (int32_t)text.length()) - boost::throw_exception(RuntimeException(L"InvalidTokenOffsets: Token " + termAtt->term() + L" exceeds length of provided text sized " + StringUtils::toString(text.length()))); - - if (tokenGroup->numTokens > 0 && tokenGroup->isDistinct()) - { - // the current token is distinct from previous tokens - markup the cached token group info - startOffset = tokenGroup->matchStartOffset; - endOffset = tokenGroup->matchEndOffset; - tokenText = text.substr(startOffset, endOffset - startOffset); - String markedUpText(formatter->highlightTerm(encoder->encodeText(tokenText), tokenGroup)); - // store any whitespace etc from between this and last group - if (startOffset > lastEndOffset) - newText->append(encoder->encodeText(text.substr(lastEndOffset, startOffset - lastEndOffset))); - newText->append(markedUpText); - lastEndOffset = std::max(endOffset, lastEndOffset); - tokenGroup->clear(); - - // check if current token marks the start of a new fragment - if (textFragmenter->isNewFragment()) - { - currentFrag->setScore(fragmentScorer->getFragmentScore()); - // record stats for a new fragment - currentFrag->textEndPos = newText->length(); - currentFrag = newLucene(newText, newText->length(), docFrags.size()); - fragmentScorer->startFragment(currentFrag); - docFrags.add(currentFrag); - } - } +Collection Highlighter::getBestTextFragments(const TokenStreamPtr& tokenStream, const String& text, bool merge, int32_t maxNumFragments) { + Collection docFrags(Collection::newInstance()); + StringBufferPtr newText(newLucene()); - tokenGroup->addToken(fragmentScorer->getTokenScore()); - } + TokenStreamPtr _tokenStream(tokenStream); + TermAttributePtr termAtt(_tokenStream->addAttribute()); + OffsetAttributePtr offsetAtt(_tokenStream->addAttribute()); + _tokenStream->addAttribute(); + _tokenStream->reset(); - currentFrag->setScore(fragmentScorer->getFragmentScore()); + TextFragmentPtr currentFrag(newLucene(newText, newText->length(), docFrags.size())); + TokenStreamPtr newStream(fragmentScorer->init(_tokenStream)); + if (newStream) { + _tokenStream = newStream; + } + fragmentScorer->startFragment(currentFrag); + docFrags.add(currentFrag); + + FragmentQueuePtr fragQueue(newLucene(maxNumFragments)); + Collection frag; + + LuceneException finally; + try { + textFragmenter->start(text, _tokenStream); + TokenGroupPtr tokenGroup(newLucene(_tokenStream)); + String tokenText; + int32_t startOffset = 0; + int32_t endOffset = 0; + int32_t lastEndOffset = 0; + + for (bool next = _tokenStream->incrementToken(); next && offsetAtt->startOffset() < maxDocCharsToAnalyze; next = _tokenStream->incrementToken()) { + if (offsetAtt->endOffset() > (int32_t)text.length() || offsetAtt->startOffset() > (int32_t)text.length()) { + boost::throw_exception(RuntimeException(L"InvalidTokenOffsets: Token " + termAtt->term() + L" exceeds length of provided text sized " + StringUtils::toString(text.length()))); + } - if (tokenGroup->numTokens > 0) - { - // flush the accumulated text (same code as in above loop) + if (tokenGroup->numTokens > 0 && tokenGroup->isDistinct()) { + // the current token is distinct from previous tokens - markup the cached token group info startOffset = tokenGroup->matchStartOffset; endOffset = tokenGroup->matchEndOffset; tokenText = text.substr(startOffset, endOffset - startOffset); String markedUpText(formatter->highlightTerm(encoder->encodeText(tokenText), tokenGroup)); // store any whitespace etc from between this and last group - if (startOffset > lastEndOffset) + if (startOffset > lastEndOffset) { newText->append(encoder->encodeText(text.substr(lastEndOffset, startOffset - lastEndOffset))); + } newText->append(markedUpText); - lastEndOffset = std::max(lastEndOffset, endOffset); + lastEndOffset = std::max(endOffset, lastEndOffset); + tokenGroup->clear(); + + // check if current token marks the start of a new fragment + if (textFragmenter->isNewFragment()) { + currentFrag->setScore(fragmentScorer->getFragmentScore()); + // record stats for a new fragment + currentFrag->textEndPos = newText->length(); + currentFrag = newLucene(newText, newText->length(), docFrags.size()); + fragmentScorer->startFragment(currentFrag); + docFrags.add(currentFrag); + } } - // Test what remains of the original text beyond the point where we stopped analyzing - if (lastEndOffset < (int32_t)text.length() && (int32_t)text.length() <= maxDocCharsToAnalyze) - { - // append it to the last fragment - newText->append(encoder->encodeText(text.substr(lastEndOffset))); - } + tokenGroup->addToken(fragmentScorer->getTokenScore()); + } - currentFrag->textEndPos = newText->length(); - - // sort the most relevant sections of the text - for (Collection::iterator i = docFrags.begin(); i != docFrags.end(); ++i) - fragQueue->addOverflow(*i); - - // return the most relevant fragments - frag = Collection::newInstance(fragQueue->size()); - for (int32_t i = frag.size() - 1; i >= 0; --i) - frag[i] = fragQueue->pop(); - - // merge any contiguous fragments to improve readability - if (merge) - { - mergeContiguousFragments(frag); - Collection fragTexts(Collection::newInstance()); - for (int32_t i = 0; i < frag.size(); ++i) - { - if (frag[i] && frag[i]->getScore() > 0) - fragTexts.add(frag[i]); - } - frag = fragTexts; + currentFrag->setScore(fragmentScorer->getFragmentScore()); + + if (tokenGroup->numTokens > 0) { + // flush the accumulated text (same code as in above loop) + startOffset = tokenGroup->matchStartOffset; + endOffset = tokenGroup->matchEndOffset; + tokenText = text.substr(startOffset, endOffset - startOffset); + String markedUpText(formatter->highlightTerm(encoder->encodeText(tokenText), tokenGroup)); + // store any whitespace etc from between this and last group + if (startOffset > lastEndOffset) { + newText->append(encoder->encodeText(text.substr(lastEndOffset, startOffset - lastEndOffset))); } + newText->append(markedUpText); + lastEndOffset = std::max(lastEndOffset, endOffset); } - catch (LuceneException& e) - { - finally = e; + + // Test what remains of the original text beyond the point where we stopped analyzing + if (lastEndOffset < (int32_t)text.length() && (int32_t)text.length() <= maxDocCharsToAnalyze) { + // append it to the last fragment + newText->append(encoder->encodeText(text.substr(lastEndOffset))); } - if (_tokenStream) - { - try - { - _tokenStream->close(); - } - catch (...) - { + + currentFrag->textEndPos = newText->length(); + + // sort the most relevant sections of the text + for (Collection::iterator i = docFrags.begin(); i != docFrags.end(); ++i) { + fragQueue->addOverflow(*i); + } + + // return the most relevant fragments + frag = Collection::newInstance(fragQueue->size()); + for (int32_t i = frag.size() - 1; i >= 0; --i) { + frag[i] = fragQueue->pop(); + } + + // merge any contiguous fragments to improve readability + if (merge) { + mergeContiguousFragments(frag); + Collection fragTexts(Collection::newInstance()); + for (int32_t i = 0; i < frag.size(); ++i) { + if (frag[i] && frag[i]->getScore() > 0) { + fragTexts.add(frag[i]); + } } + frag = fragTexts; + } + } catch (LuceneException& e) { + finally = e; + } + if (_tokenStream) { + try { + _tokenStream->close(); + } catch (...) { } - finally.throwException(); - return frag; } + finally.throwException(); + return frag; +} - void Highlighter::mergeContiguousFragments(Collection frag) - { - if (frag.size() > 1) - { - bool mergingStillBeingDone = false; - do - { - mergingStillBeingDone = false; // initialise loop control flag - // for each fragment, scan other frags looking for contiguous blocks - for (int32_t i = 0; i < frag.size(); ++i) - { - if (!frag[i]) +void Highlighter::mergeContiguousFragments(Collection frag) { + if (frag.size() > 1) { + bool mergingStillBeingDone = false; + do { + mergingStillBeingDone = false; // initialise loop control flag + // for each fragment, scan other frags looking for contiguous blocks + for (int32_t i = 0; i < frag.size(); ++i) { + if (!frag[i]) { + continue; + } + // merge any contiguous blocks + for (int32_t x = 0; x < frag.size(); ++x) { + if (!frag[x]) { continue; - // merge any contiguous blocks - for (int32_t x = 0; x < frag.size(); ++x) - { - if (!frag[x]) - continue; - if (!frag[i]) - break; - TextFragmentPtr frag1; - TextFragmentPtr frag2; - int32_t frag1Num = 0; - int32_t frag2Num = 0; - int32_t bestScoringFragNum = 0; - int32_t worstScoringFragNum = 0; - // if blocks are contiguous - if (frag[i]->follows(frag[x])) - { - frag1 = frag[x]; - frag1Num = x; - frag2 = frag[i]; - frag2Num = i; - } - else if (frag[x]->follows(frag[i])) - { - frag1 = frag[i]; - frag1Num = i; - frag2 = frag[x]; - frag2Num = x; - } + } + if (!frag[i]) { + break; + } + TextFragmentPtr frag1; + TextFragmentPtr frag2; + int32_t frag1Num = 0; + int32_t frag2Num = 0; + int32_t bestScoringFragNum = 0; + int32_t worstScoringFragNum = 0; + // if blocks are contiguous + if (frag[i]->follows(frag[x])) { + frag1 = frag[x]; + frag1Num = x; + frag2 = frag[i]; + frag2Num = i; + } else if (frag[x]->follows(frag[i])) { + frag1 = frag[i]; + frag1Num = i; + frag2 = frag[x]; + frag2Num = x; + } - // merging required - if (frag1) - { - if (frag1->getScore() > frag2->getScore()) - { - bestScoringFragNum = frag1Num; - worstScoringFragNum = frag2Num; - } - else - { - bestScoringFragNum = frag2Num; - worstScoringFragNum = frag1Num; - } - frag1->merge(frag2); - frag[worstScoringFragNum].reset(); - mergingStillBeingDone = true; - frag[bestScoringFragNum] = frag1; + // merging required + if (frag1) { + if (frag1->getScore() > frag2->getScore()) { + bestScoringFragNum = frag1Num; + worstScoringFragNum = frag2Num; + } else { + bestScoringFragNum = frag2Num; + worstScoringFragNum = frag1Num; } + frag1->merge(frag2); + frag[worstScoringFragNum].reset(); + mergingStillBeingDone = true; + frag[bestScoringFragNum] = frag1; } } } - while (mergingStillBeingDone); - } + } while (mergingStillBeingDone); } +} - String Highlighter::getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments, const String& separator) - { - Collection sections(getBestFragments(tokenStream, text, maxNumFragments)); - StringStream result; - for (int32_t i = 0; i < sections.size(); ++i) - { - if (i > 0) - result << separator; - result << sections[i]; +String Highlighter::getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments, const String& separator) { + Collection sections(getBestFragments(tokenStream, text, maxNumFragments)); + StringStream result; + for (int32_t i = 0; i < sections.size(); ++i) { + if (i > 0) { + result << separator; } - return result.str(); + result << sections[i]; } + return result.str(); +} - int32_t Highlighter::getMaxDocCharsToAnalyze() - { - return maxDocCharsToAnalyze; - } +int32_t Highlighter::getMaxDocCharsToAnalyze() { + return maxDocCharsToAnalyze; +} - void Highlighter::setMaxDocCharsToAnalyze(int32_t maxDocCharsToAnalyze) - { - this->maxDocCharsToAnalyze = maxDocCharsToAnalyze; - } +void Highlighter::setMaxDocCharsToAnalyze(int32_t maxDocCharsToAnalyze) { + this->maxDocCharsToAnalyze = maxDocCharsToAnalyze; +} - FragmenterPtr Highlighter::getTextFragmenter() - { - return textFragmenter; - } +FragmenterPtr Highlighter::getTextFragmenter() { + return textFragmenter; +} - void Highlighter::setTextFragmenter(const FragmenterPtr& fragmenter) - { - textFragmenter = fragmenter; - } +void Highlighter::setTextFragmenter(const FragmenterPtr& fragmenter) { + textFragmenter = fragmenter; +} - HighlighterScorerPtr Highlighter::getFragmentScorer() - { - return fragmentScorer; - } +HighlighterScorerPtr Highlighter::getFragmentScorer() { + return fragmentScorer; +} - void Highlighter::setFragmentScorer(const HighlighterScorerPtr& scorer) - { - fragmentScorer = scorer; - } +void Highlighter::setFragmentScorer(const HighlighterScorerPtr& scorer) { + fragmentScorer = scorer; +} - EncoderPtr Highlighter::getEncoder() - { - return encoder; - } +EncoderPtr Highlighter::getEncoder() { + return encoder; +} - void Highlighter::setEncoder(const EncoderPtr& encoder) - { - this->encoder = encoder; - } +void Highlighter::setEncoder(const EncoderPtr& encoder) { + this->encoder = encoder; +} - FragmentQueue::FragmentQueue(int32_t size) : PriorityQueue(size) - { - } +FragmentQueue::FragmentQueue(int32_t size) : PriorityQueue(size) { +} - FragmentQueue::~FragmentQueue() - { - } +FragmentQueue::~FragmentQueue() { +} - bool FragmentQueue::lessThan(const TextFragmentPtr& first, const TextFragmentPtr& second) - { - if (first->getScore() == second->getScore()) - return first->fragNum > second->fragNum; - else - return first->getScore() < second->getScore(); +bool FragmentQueue::lessThan(const TextFragmentPtr& first, const TextFragmentPtr& second) { + if (first->getScore() == second->getScore()) { + return first->fragNum > second->fragNum; + } else { + return first->getScore() < second->getScore(); } } + +} diff --git a/src/contrib/highlighter/HighlighterScorer.cpp b/src/contrib/highlighter/HighlighterScorer.cpp index f041435a..17ca78ad 100644 --- a/src/contrib/highlighter/HighlighterScorer.cpp +++ b/src/contrib/highlighter/HighlighterScorer.cpp @@ -7,33 +7,29 @@ #include "ContribInc.h" #include "HighlighterScorer.h" -namespace Lucene -{ - HighlighterScorer::~HighlighterScorer() - { - } - - TokenStreamPtr HighlighterScorer::init(const TokenStreamPtr& tokenStream) - { - BOOST_ASSERT(false); - return TokenStreamPtr(); // override - } - - void HighlighterScorer::startFragment(const TextFragmentPtr& newFragment) - { - BOOST_ASSERT(false); - // override - } - - double HighlighterScorer::getTokenScore() - { - BOOST_ASSERT(false); - return 0; // override - } - - double HighlighterScorer::getFragmentScore() - { - BOOST_ASSERT(false); - return 0; // override - } +namespace Lucene { + +HighlighterScorer::~HighlighterScorer() { +} + +TokenStreamPtr HighlighterScorer::init(const TokenStreamPtr& tokenStream) { + BOOST_ASSERT(false); + return TokenStreamPtr(); // override +} + +void HighlighterScorer::startFragment(const TextFragmentPtr& newFragment) { + BOOST_ASSERT(false); + // override +} + +double HighlighterScorer::getTokenScore() { + BOOST_ASSERT(false); + return 0; // override +} + +double HighlighterScorer::getFragmentScore() { + BOOST_ASSERT(false); + return 0; // override +} + } diff --git a/src/contrib/highlighter/MapWeightedSpanTerm.cpp b/src/contrib/highlighter/MapWeightedSpanTerm.cpp index e87a3f08..e5e8c765 100644 --- a/src/contrib/highlighter/MapWeightedSpanTerm.cpp +++ b/src/contrib/highlighter/MapWeightedSpanTerm.cpp @@ -7,39 +7,33 @@ #include "ContribInc.h" #include "MapWeightedSpanTerm.h" -namespace Lucene -{ - MapWeightedSpanTerm::MapWeightedSpanTerm() - { - map = MapStringWeightedSpanTerm::newInstance(); - } - - MapWeightedSpanTerm::~MapWeightedSpanTerm() - { - } - - MapStringWeightedSpanTerm::iterator MapWeightedSpanTerm::begin() - { - return map.begin(); - } - - MapStringWeightedSpanTerm::iterator MapWeightedSpanTerm::end() - { - return map.end(); - } - - void MapWeightedSpanTerm::put(const String& key, const WeightedSpanTermPtr& val) - { - return map.put(key, val); - } - - WeightedSpanTermPtr MapWeightedSpanTerm::get(const String& key) const - { - return map.get(key); - } - - void MapWeightedSpanTerm::clear() - { - map.clear(); - } +namespace Lucene { + +MapWeightedSpanTerm::MapWeightedSpanTerm() { + map = MapStringWeightedSpanTerm::newInstance(); +} + +MapWeightedSpanTerm::~MapWeightedSpanTerm() { +} + +MapStringWeightedSpanTerm::iterator MapWeightedSpanTerm::begin() { + return map.begin(); +} + +MapStringWeightedSpanTerm::iterator MapWeightedSpanTerm::end() { + return map.end(); +} + +void MapWeightedSpanTerm::put(const String& key, const WeightedSpanTermPtr& val) { + return map.put(key, val); +} + +WeightedSpanTermPtr MapWeightedSpanTerm::get(const String& key) const { + return map.get(key); +} + +void MapWeightedSpanTerm::clear() { + map.clear(); +} + } diff --git a/src/contrib/highlighter/NullFragmenter.cpp b/src/contrib/highlighter/NullFragmenter.cpp index 7d0399ce..3e5fa31d 100644 --- a/src/contrib/highlighter/NullFragmenter.cpp +++ b/src/contrib/highlighter/NullFragmenter.cpp @@ -7,18 +7,16 @@ #include "ContribInc.h" #include "NullFragmenter.h" -namespace Lucene -{ - NullFragmenter::~NullFragmenter() - { - } +namespace Lucene { - void NullFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) - { - } +NullFragmenter::~NullFragmenter() { +} + +void NullFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { +} + +bool NullFragmenter::isNewFragment() { + return false; +} - bool NullFragmenter::isNewFragment() - { - return false; - } } diff --git a/src/contrib/highlighter/QueryScorer.cpp b/src/contrib/highlighter/QueryScorer.cpp index 0a46ab7b..cbd5177f 100644 --- a/src/contrib/highlighter/QueryScorer.cpp +++ b/src/contrib/highlighter/QueryScorer.cpp @@ -13,158 +13,142 @@ #include "MapWeightedSpanTerm.h" #include "WeightedSpanTermExtractor.h" -namespace Lucene -{ - QueryScorer::QueryScorer(const QueryPtr& query) - { - init(query, L"", IndexReaderPtr(), true); - } +namespace Lucene { - QueryScorer::QueryScorer(const QueryPtr& query, const String& field) - { - init(query, field, IndexReaderPtr(), true); - } +QueryScorer::QueryScorer(const QueryPtr& query) { + init(query, L"", IndexReaderPtr(), true); +} - QueryScorer::QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field) - { - init(query, field, reader, true); - } +QueryScorer::QueryScorer(const QueryPtr& query, const String& field) { + init(query, field, IndexReaderPtr(), true); +} - QueryScorer::QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field, const String& defaultField) - { - this->defaultField = defaultField; - init(query, field, reader, true); - } +QueryScorer::QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field) { + init(query, field, reader, true); +} - QueryScorer::QueryScorer(const QueryPtr& query, const String& field, const String& defaultField) - { - this->defaultField = defaultField; - init(query, field, IndexReaderPtr(), true); - } +QueryScorer::QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field, const String& defaultField) { + this->defaultField = defaultField; + init(query, field, reader, true); +} - QueryScorer::QueryScorer(Collection weightedTerms) - { - init(QueryPtr(), L"", IndexReaderPtr(), true); - - this->fieldWeightedSpanTerms = newLucene(); - for (int32_t i = 0; i < weightedTerms.size(); ++i) - { - WeightedSpanTermPtr existingTerm(fieldWeightedSpanTerms->get(weightedTerms[i]->term)); - if (!existingTerm || existingTerm->weight < weightedTerms[i]->weight) - { - // if a term is defined more than once, always use the highest scoring weight - fieldWeightedSpanTerms->put(weightedTerms[i]->term, weightedTerms[i]); - maxTermWeight = std::max(maxTermWeight, weightedTerms[i]->getWeight()); - } - } - skipInitExtractor = true; - } +QueryScorer::QueryScorer(const QueryPtr& query, const String& field, const String& defaultField) { + this->defaultField = defaultField; + init(query, field, IndexReaderPtr(), true); +} - QueryScorer::~QueryScorer() - { - } +QueryScorer::QueryScorer(Collection weightedTerms) { + init(QueryPtr(), L"", IndexReaderPtr(), true); - void QueryScorer::init(const QueryPtr& query, const String& field, const IndexReaderPtr& reader, bool expandMultiTermQuery) - { - this->totalScore = 0; - this->maxTermWeight = 0; - this->position = -1; - this->skipInitExtractor = false; - this->wrapToCaching = true; - - this->reader = reader; - this->expandMultiTermQuery = expandMultiTermQuery; - this->query = query; - this->field = field; + this->fieldWeightedSpanTerms = newLucene(); + for (int32_t i = 0; i < weightedTerms.size(); ++i) { + WeightedSpanTermPtr existingTerm(fieldWeightedSpanTerms->get(weightedTerms[i]->term)); + if (!existingTerm || existingTerm->weight < weightedTerms[i]->weight) { + // if a term is defined more than once, always use the highest scoring weight + fieldWeightedSpanTerms->put(weightedTerms[i]->term, weightedTerms[i]); + maxTermWeight = std::max(maxTermWeight, weightedTerms[i]->getWeight()); + } } + skipInitExtractor = true; +} - double QueryScorer::getFragmentScore() - { - return totalScore; - } +QueryScorer::~QueryScorer() { +} - double QueryScorer::getMaxTermWeight() - { - return maxTermWeight; - } +void QueryScorer::init(const QueryPtr& query, const String& field, const IndexReaderPtr& reader, bool expandMultiTermQuery) { + this->totalScore = 0; + this->maxTermWeight = 0; + this->position = -1; + this->skipInitExtractor = false; + this->wrapToCaching = true; + + this->reader = reader; + this->expandMultiTermQuery = expandMultiTermQuery; + this->query = query; + this->field = field; +} + +double QueryScorer::getFragmentScore() { + return totalScore; +} - double QueryScorer::getTokenScore() - { - position += posIncAtt->getPositionIncrement(); - String termText(termAtt->term()); +double QueryScorer::getMaxTermWeight() { + return maxTermWeight; +} - WeightedSpanTermPtr weightedSpanTerm(fieldWeightedSpanTerms->get(termText)); +double QueryScorer::getTokenScore() { + position += posIncAtt->getPositionIncrement(); + String termText(termAtt->term()); - if (!weightedSpanTerm) - return 0.0; + WeightedSpanTermPtr weightedSpanTerm(fieldWeightedSpanTerms->get(termText)); - if (weightedSpanTerm->positionSensitive && !weightedSpanTerm->checkPosition(position)) - return 0.0; + if (!weightedSpanTerm) { + return 0.0; + } - double score = weightedSpanTerm->getWeight(); + if (weightedSpanTerm->positionSensitive && !weightedSpanTerm->checkPosition(position)) { + return 0.0; + } - // found a query term - is it unique in this doc? - if (!foundTerms.contains(termText)) - { - totalScore += score; - foundTerms.add(termText); - } + double score = weightedSpanTerm->getWeight(); - return score; + // found a query term - is it unique in this doc? + if (!foundTerms.contains(termText)) { + totalScore += score; + foundTerms.add(termText); } - TokenStreamPtr QueryScorer::init(const TokenStreamPtr& tokenStream) - { - position = -1; - termAtt = tokenStream->addAttribute(); - posIncAtt = tokenStream->addAttribute(); - if (!skipInitExtractor) - { - if (fieldWeightedSpanTerms) - fieldWeightedSpanTerms->clear(); - return initExtractor(tokenStream); + return score; +} + +TokenStreamPtr QueryScorer::init(const TokenStreamPtr& tokenStream) { + position = -1; + termAtt = tokenStream->addAttribute(); + posIncAtt = tokenStream->addAttribute(); + if (!skipInitExtractor) { + if (fieldWeightedSpanTerms) { + fieldWeightedSpanTerms->clear(); } - return TokenStreamPtr(); + return initExtractor(tokenStream); } + return TokenStreamPtr(); +} - WeightedSpanTermPtr QueryScorer::getWeightedSpanTerm(const String& token) - { - return fieldWeightedSpanTerms->get(token); - } +WeightedSpanTermPtr QueryScorer::getWeightedSpanTerm(const String& token) { + return fieldWeightedSpanTerms->get(token); +} - TokenStreamPtr QueryScorer::initExtractor(const TokenStreamPtr& tokenStream) - { - WeightedSpanTermExtractorPtr qse(newLucene(defaultField)); - - qse->setExpandMultiTermQuery(expandMultiTermQuery); - qse->setWrapIfNotCachingTokenFilter(wrapToCaching); - if (!reader) - this->fieldWeightedSpanTerms = qse->getWeightedSpanTerms(query, tokenStream, field); - else - this->fieldWeightedSpanTerms = qse->getWeightedSpanTermsWithScores(query, tokenStream, field, reader); - if (qse->isCachedTokenStream()) - return qse->getTokenStream(); - return TokenStreamPtr(); - } +TokenStreamPtr QueryScorer::initExtractor(const TokenStreamPtr& tokenStream) { + WeightedSpanTermExtractorPtr qse(newLucene(defaultField)); - void QueryScorer::startFragment(const TextFragmentPtr& newFragment) - { - foundTerms = HashSet::newInstance(); - totalScore = 0; + qse->setExpandMultiTermQuery(expandMultiTermQuery); + qse->setWrapIfNotCachingTokenFilter(wrapToCaching); + if (!reader) { + this->fieldWeightedSpanTerms = qse->getWeightedSpanTerms(query, tokenStream, field); + } else { + this->fieldWeightedSpanTerms = qse->getWeightedSpanTermsWithScores(query, tokenStream, field, reader); } - - bool QueryScorer::isExpandMultiTermQuery() - { - return expandMultiTermQuery; + if (qse->isCachedTokenStream()) { + return qse->getTokenStream(); } + return TokenStreamPtr(); +} - void QueryScorer::setExpandMultiTermQuery(bool expandMultiTermQuery) - { - this->expandMultiTermQuery = expandMultiTermQuery; - } +void QueryScorer::startFragment(const TextFragmentPtr& newFragment) { + foundTerms = HashSet::newInstance(); + totalScore = 0; +} + +bool QueryScorer::isExpandMultiTermQuery() { + return expandMultiTermQuery; +} + +void QueryScorer::setExpandMultiTermQuery(bool expandMultiTermQuery) { + this->expandMultiTermQuery = expandMultiTermQuery; +} + +void QueryScorer::setWrapIfNotCachingTokenFilter(bool wrap) { + this->wrapToCaching = wrap; +} - void QueryScorer::setWrapIfNotCachingTokenFilter(bool wrap) - { - this->wrapToCaching = wrap; - } } diff --git a/src/contrib/highlighter/QueryTermExtractor.cpp b/src/contrib/highlighter/QueryTermExtractor.cpp index d6cbf241..b1666886 100644 --- a/src/contrib/highlighter/QueryTermExtractor.cpp +++ b/src/contrib/highlighter/QueryTermExtractor.cpp @@ -14,92 +14,78 @@ #include "IndexReader.h" #include "MiscUtils.h" -namespace Lucene -{ - QueryTermExtractor::~QueryTermExtractor() - { - } +namespace Lucene { - Collection QueryTermExtractor::getTerms(const QueryPtr& query) - { - return getTerms(query, false); - } +QueryTermExtractor::~QueryTermExtractor() { +} - Collection QueryTermExtractor::getIdfWeightedTerms(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName) - { - Collection terms(getTerms(query, false, fieldName)); - int32_t totalNumDocs = reader->numDocs(); - for (int32_t i = 0; i < terms.size(); ++i) - { - try - { - int32_t docFreq = reader->docFreq(newLucene(fieldName, terms[i]->term)); - // docFreq counts deletes - if (totalNumDocs < docFreq) - docFreq = totalNumDocs; - // IDF algorithm taken from DefaultSimilarity class - double idf = (double)(std::log((double)totalNumDocs / (double)(docFreq + 1)) + 1.0); - terms[i]->weight *= idf; - } - catch (...) - { - // ignore +Collection QueryTermExtractor::getTerms(const QueryPtr& query) { + return getTerms(query, false); +} + +Collection QueryTermExtractor::getIdfWeightedTerms(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName) { + Collection terms(getTerms(query, false, fieldName)); + int32_t totalNumDocs = reader->numDocs(); + for (int32_t i = 0; i < terms.size(); ++i) { + try { + int32_t docFreq = reader->docFreq(newLucene(fieldName, terms[i]->term)); + // docFreq counts deletes + if (totalNumDocs < docFreq) { + docFreq = totalNumDocs; } + // IDF algorithm taken from DefaultSimilarity class + double idf = (double)(std::log((double)totalNumDocs / (double)(docFreq + 1)) + 1.0); + terms[i]->weight *= idf; + } catch (...) { + // ignore } - return terms; } + return terms; +} - Collection QueryTermExtractor::getTerms(const QueryPtr& query, bool prohibited, const String& fieldName) - { - SetWeightedTerm terms(SetWeightedTerm::newInstance()); - getTerms(query, terms, prohibited, fieldName); - return Collection::newInstance(terms.begin(), terms.end()); - } +Collection QueryTermExtractor::getTerms(const QueryPtr& query, bool prohibited, const String& fieldName) { + SetWeightedTerm terms(SetWeightedTerm::newInstance()); + getTerms(query, terms, prohibited, fieldName); + return Collection::newInstance(terms.begin(), terms.end()); +} - Collection QueryTermExtractor::getTerms(const QueryPtr& query, bool prohibited) - { - SetWeightedTerm terms(SetWeightedTerm::newInstance()); - getTerms(query, terms, prohibited, L""); - return Collection::newInstance(terms.begin(), terms.end()); - } +Collection QueryTermExtractor::getTerms(const QueryPtr& query, bool prohibited) { + SetWeightedTerm terms(SetWeightedTerm::newInstance()); + getTerms(query, terms, prohibited, L""); + return Collection::newInstance(terms.begin(), terms.end()); +} - void QueryTermExtractor::getTerms(const QueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) - { - try - { - if (MiscUtils::typeOf(query)) - getTermsFromBooleanQuery(boost::dynamic_pointer_cast(query), terms, prohibited, fieldName); - else if (MiscUtils::typeOf(query)) - getTermsFromFilteredQuery(boost::dynamic_pointer_cast(query), terms, prohibited, fieldName); - else - { - SetTerm nonWeightedTerms(SetTerm::newInstance()); - query->extractTerms(nonWeightedTerms); - for (SetTerm::iterator term = nonWeightedTerms.begin(); term != nonWeightedTerms.end(); ++term) - { - if (fieldName.empty() || (*term)->field() == fieldName) - terms.add(newLucene(query->getBoost(), (*term)->text())); +void QueryTermExtractor::getTerms(const QueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { + try { + if (MiscUtils::typeOf(query)) { + getTermsFromBooleanQuery(boost::dynamic_pointer_cast(query), terms, prohibited, fieldName); + } else if (MiscUtils::typeOf(query)) { + getTermsFromFilteredQuery(boost::dynamic_pointer_cast(query), terms, prohibited, fieldName); + } else { + SetTerm nonWeightedTerms(SetTerm::newInstance()); + query->extractTerms(nonWeightedTerms); + for (SetTerm::iterator term = nonWeightedTerms.begin(); term != nonWeightedTerms.end(); ++term) { + if (fieldName.empty() || (*term)->field() == fieldName) { + terms.add(newLucene(query->getBoost(), (*term)->text())); } } } - catch (UnsupportedOperationException&) - { - // this is non-fatal for our purposes - } + } catch (UnsupportedOperationException&) { + // this is non-fatal for our purposes } +} - void QueryTermExtractor::getTermsFromBooleanQuery(const BooleanQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) - { - Collection queryClauses(query->getClauses()); - for (int32_t i = 0; i < queryClauses.size(); ++i) - { - if (prohibited || queryClauses[i]->getOccur() != BooleanClause::MUST_NOT) - getTerms(queryClauses[i]->getQuery(), terms, prohibited, fieldName); +void QueryTermExtractor::getTermsFromBooleanQuery(const BooleanQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { + Collection queryClauses(query->getClauses()); + for (int32_t i = 0; i < queryClauses.size(); ++i) { + if (prohibited || queryClauses[i]->getOccur() != BooleanClause::MUST_NOT) { + getTerms(queryClauses[i]->getQuery(), terms, prohibited, fieldName); } } +} + +void QueryTermExtractor::getTermsFromFilteredQuery(const FilteredQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) { + getTerms(query->getQuery(), terms, prohibited, fieldName); +} - void QueryTermExtractor::getTermsFromFilteredQuery(const FilteredQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName) - { - getTerms(query->getQuery(), terms, prohibited, fieldName); - } } diff --git a/src/contrib/highlighter/QueryTermScorer.cpp b/src/contrib/highlighter/QueryTermScorer.cpp index be4efe0e..da31587a 100644 --- a/src/contrib/highlighter/QueryTermScorer.cpp +++ b/src/contrib/highlighter/QueryTermScorer.cpp @@ -11,93 +11,80 @@ #include "WeightedTerm.h" #include "TokenStream.h" -namespace Lucene -{ - QueryTermScorer::QueryTermScorer(const QueryPtr& query) - { - ConstructQueryTermScorer(QueryTermExtractor::getTerms(query)); - } - - QueryTermScorer::QueryTermScorer(const QueryPtr& query, const String& fieldName) - { - ConstructQueryTermScorer(QueryTermExtractor::getTerms(query, false, fieldName)); - } +namespace Lucene { - QueryTermScorer::QueryTermScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName) - { - ConstructQueryTermScorer(QueryTermExtractor::getIdfWeightedTerms(query, reader, fieldName)); - } +QueryTermScorer::QueryTermScorer(const QueryPtr& query) { + ConstructQueryTermScorer(QueryTermExtractor::getTerms(query)); +} - QueryTermScorer::QueryTermScorer(Collection weightedTerms) - { - ConstructQueryTermScorer(weightedTerms); - } +QueryTermScorer::QueryTermScorer(const QueryPtr& query, const String& fieldName) { + ConstructQueryTermScorer(QueryTermExtractor::getTerms(query, false, fieldName)); +} - QueryTermScorer::~QueryTermScorer() - { - } +QueryTermScorer::QueryTermScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName) { + ConstructQueryTermScorer(QueryTermExtractor::getIdfWeightedTerms(query, reader, fieldName)); +} - void QueryTermScorer::ConstructQueryTermScorer(Collection weightedTerms) - { - totalScore = 0; - maxTermWeight = 0; - - termsToFind = MapStringWeightedTerm::newInstance(); - for (int32_t i = 0; i < weightedTerms.size(); ++i) - { - WeightedTermPtr existingTerm(termsToFind.get(weightedTerms[i]->term)); - if (!existingTerm || existingTerm->weight < weightedTerms[i]->weight) - { - // if a term is defined more than once, always use the highest scoring weight - termsToFind.put(weightedTerms[i]->term, weightedTerms[i]); - maxTermWeight = std::max(maxTermWeight, weightedTerms[i]->getWeight()); - } - } - } +QueryTermScorer::QueryTermScorer(Collection weightedTerms) { + ConstructQueryTermScorer(weightedTerms); +} - TokenStreamPtr QueryTermScorer::init(const TokenStreamPtr& tokenStream) - { - termAtt = tokenStream->addAttribute(); - return TokenStreamPtr(); - } +QueryTermScorer::~QueryTermScorer() { +} - void QueryTermScorer::startFragment(const TextFragmentPtr& newFragment) - { - uniqueTermsInFragment = HashSet::newInstance(); - currentTextFragment = newFragment; - totalScore = 0; +void QueryTermScorer::ConstructQueryTermScorer(Collection weightedTerms) { + totalScore = 0; + maxTermWeight = 0; + + termsToFind = MapStringWeightedTerm::newInstance(); + for (int32_t i = 0; i < weightedTerms.size(); ++i) { + WeightedTermPtr existingTerm(termsToFind.get(weightedTerms[i]->term)); + if (!existingTerm || existingTerm->weight < weightedTerms[i]->weight) { + // if a term is defined more than once, always use the highest scoring weight + termsToFind.put(weightedTerms[i]->term, weightedTerms[i]); + maxTermWeight = std::max(maxTermWeight, weightedTerms[i]->getWeight()); + } } +} - double QueryTermScorer::getTokenScore() - { - String termText(termAtt->term()); +TokenStreamPtr QueryTermScorer::init(const TokenStreamPtr& tokenStream) { + termAtt = tokenStream->addAttribute(); + return TokenStreamPtr(); +} - WeightedTermPtr queryTerm(termsToFind.get(termText)); - if (!queryTerm) - return 0.0; // not a query term - return +void QueryTermScorer::startFragment(const TextFragmentPtr& newFragment) { + uniqueTermsInFragment = HashSet::newInstance(); + currentTextFragment = newFragment; + totalScore = 0; +} - // found a query term - is it unique in this doc? - if (!uniqueTermsInFragment.contains(termText)) - { - totalScore += queryTerm->getWeight();; - uniqueTermsInFragment.add(termText); - } +double QueryTermScorer::getTokenScore() { + String termText(termAtt->term()); - return queryTerm->getWeight(); + WeightedTermPtr queryTerm(termsToFind.get(termText)); + if (!queryTerm) { + return 0.0; // not a query term - return } - double QueryTermScorer::getFragmentScore() - { - return totalScore; + // found a query term - is it unique in this doc? + if (!uniqueTermsInFragment.contains(termText)) { + totalScore += queryTerm->getWeight();; + uniqueTermsInFragment.add(termText); } - void QueryTermScorer::allFragmentsProcessed() - { - // this class has no special operations to perform at end of processing - } + return queryTerm->getWeight(); +} + +double QueryTermScorer::getFragmentScore() { + return totalScore; +} + +void QueryTermScorer::allFragmentsProcessed() { + // this class has no special operations to perform at end of processing +} + +double QueryTermScorer::getMaxTermWeight() { + return maxTermWeight; +} - double QueryTermScorer::getMaxTermWeight() - { - return maxTermWeight; - } } diff --git a/src/contrib/highlighter/SimpleFragmenter.cpp b/src/contrib/highlighter/SimpleFragmenter.cpp index 2b8d557d..4a3df9d1 100644 --- a/src/contrib/highlighter/SimpleFragmenter.cpp +++ b/src/contrib/highlighter/SimpleFragmenter.cpp @@ -10,47 +10,42 @@ #include "OffsetAttribute.h" #include "TokenStream.h" -namespace Lucene -{ - const int32_t SimpleFragmenter::DEFAULT_FRAGMENT_SIZE = 100; - - SimpleFragmenter::SimpleFragmenter() - { - this->currentNumFrags = 0; - this->fragmentSize = DEFAULT_FRAGMENT_SIZE; - } +namespace Lucene { - SimpleFragmenter::SimpleFragmenter(int32_t fragmentSize) - { - this->currentNumFrags = 0; - this->fragmentSize = fragmentSize; - } +const int32_t SimpleFragmenter::DEFAULT_FRAGMENT_SIZE = 100; - SimpleFragmenter::~SimpleFragmenter() - { - } +SimpleFragmenter::SimpleFragmenter() { + this->currentNumFrags = 0; + this->fragmentSize = DEFAULT_FRAGMENT_SIZE; +} - void SimpleFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) - { - offsetAtt = tokenStream->addAttribute(); - currentNumFrags = 1; - } +SimpleFragmenter::SimpleFragmenter(int32_t fragmentSize) { + this->currentNumFrags = 0; + this->fragmentSize = fragmentSize; +} - bool SimpleFragmenter::isNewFragment() - { - bool isNewFrag = (offsetAtt->endOffset() >= (fragmentSize * currentNumFrags)); - if (isNewFrag) - ++currentNumFrags; - return isNewFrag; - } +SimpleFragmenter::~SimpleFragmenter() { +} - int32_t SimpleFragmenter::getFragmentSize() - { - return fragmentSize; - } +void SimpleFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { + offsetAtt = tokenStream->addAttribute(); + currentNumFrags = 1; +} - void SimpleFragmenter::setFragmentSize(int32_t size) - { - fragmentSize = size; +bool SimpleFragmenter::isNewFragment() { + bool isNewFrag = (offsetAtt->endOffset() >= (fragmentSize * currentNumFrags)); + if (isNewFrag) { + ++currentNumFrags; } + return isNewFrag; +} + +int32_t SimpleFragmenter::getFragmentSize() { + return fragmentSize; +} + +void SimpleFragmenter::setFragmentSize(int32_t size) { + fragmentSize = size; +} + } diff --git a/src/contrib/highlighter/SimpleHTMLEncoder.cpp b/src/contrib/highlighter/SimpleHTMLEncoder.cpp index fb4dc03e..bfe9e035 100644 --- a/src/contrib/highlighter/SimpleHTMLEncoder.cpp +++ b/src/contrib/highlighter/SimpleHTMLEncoder.cpp @@ -7,51 +7,49 @@ #include "ContribInc.h" #include "SimpleHTMLEncoder.h" -namespace Lucene -{ - SimpleHTMLEncoder::~SimpleHTMLEncoder() - { - } +namespace Lucene { + +SimpleHTMLEncoder::~SimpleHTMLEncoder() { +} + +String SimpleHTMLEncoder::encodeText(const String& originalText) { + return htmlEncode(originalText); +} - String SimpleHTMLEncoder::encodeText(const String& originalText) - { - return htmlEncode(originalText); +String SimpleHTMLEncoder::htmlEncode(const String& plainText) { + if (plainText.empty()) { + return L""; } - String SimpleHTMLEncoder::htmlEncode(const String& plainText) - { - if (plainText.empty()) - return L""; - - StringStream result; - - for (int32_t index = 0; index < (int32_t)plainText.length(); ++index) - { - wchar_t ch = plainText[index]; - - switch (ch) - { - case L'\"': - result << L"""; - break; - case L'&': - result << L"&"; - break; - case L'<': - result << L"<"; - break; - case L'>': - result << L">"; - break; - default: - if (ch < 128) - result << ch; - else - result << L"&#" << (int32_t)ch << L";"; - break; + StringStream result; + + for (int32_t index = 0; index < (int32_t)plainText.length(); ++index) { + wchar_t ch = plainText[index]; + + switch (ch) { + case L'\"': + result << L"""; + break; + case L'&': + result << L"&"; + break; + case L'<': + result << L"<"; + break; + case L'>': + result << L">"; + break; + default: + if (ch < 128) { + result << ch; + } else { + result << L"&#" << (int32_t)ch << L";"; } + break; } - - return result.str(); } + + return result.str(); +} + } diff --git a/src/contrib/highlighter/SimpleHTMLFormatter.cpp b/src/contrib/highlighter/SimpleHTMLFormatter.cpp index 0247d9ca..80fc9be5 100644 --- a/src/contrib/highlighter/SimpleHTMLFormatter.cpp +++ b/src/contrib/highlighter/SimpleHTMLFormatter.cpp @@ -8,33 +8,31 @@ #include "SimpleHTMLFormatter.h" #include "TokenGroup.h" -namespace Lucene -{ - const String SimpleHTMLFormatter::DEFAULT_PRE_TAG = L""; - const String SimpleHTMLFormatter::DEFAULT_POST_TAG = L""; - - SimpleHTMLFormatter::SimpleHTMLFormatter() - { - this->preTag = DEFAULT_PRE_TAG; - this->postTag = DEFAULT_POST_TAG; - } +namespace Lucene { - SimpleHTMLFormatter::SimpleHTMLFormatter(const String& preTag, const String& postTag) - { - this->preTag = preTag; - this->postTag = postTag; - } +const String SimpleHTMLFormatter::DEFAULT_PRE_TAG = L""; +const String SimpleHTMLFormatter::DEFAULT_POST_TAG = L""; - SimpleHTMLFormatter::~SimpleHTMLFormatter() - { - } +SimpleHTMLFormatter::SimpleHTMLFormatter() { + this->preTag = DEFAULT_PRE_TAG; + this->postTag = DEFAULT_POST_TAG; +} + +SimpleHTMLFormatter::SimpleHTMLFormatter(const String& preTag, const String& postTag) { + this->preTag = preTag; + this->postTag = postTag; +} + +SimpleHTMLFormatter::~SimpleHTMLFormatter() { +} - String SimpleHTMLFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) - { - if (tokenGroup->getTotalScore() == 0) - return originalText; - StringStream buffer; - buffer << preTag << originalText << postTag; - return buffer.str(); +String SimpleHTMLFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { + if (tokenGroup->getTotalScore() == 0) { + return originalText; } + StringStream buffer; + buffer << preTag << originalText << postTag; + return buffer.str(); +} + } diff --git a/src/contrib/highlighter/SimpleSpanFragmenter.cpp b/src/contrib/highlighter/SimpleSpanFragmenter.cpp index 819cbcab..1e34b5ad 100644 --- a/src/contrib/highlighter/SimpleSpanFragmenter.cpp +++ b/src/contrib/highlighter/SimpleSpanFragmenter.cpp @@ -14,76 +14,71 @@ #include "TokenStream.h" #include "MiscUtils.h" -namespace Lucene -{ - const int32_t SimpleSpanFragmenter::DEFAULT_FRAGMENT_SIZE = 100; - - SimpleSpanFragmenter::SimpleSpanFragmenter(const QueryScorerPtr& queryScorer) - { - this->currentNumFrags = 0; - this->position = -1; - this->waitForPos = -1; - this->textSize = 0; - - this->queryScorer = queryScorer; - this->fragmentSize = DEFAULT_FRAGMENT_SIZE; - } +namespace Lucene { - SimpleSpanFragmenter::SimpleSpanFragmenter(const QueryScorerPtr& queryScorer, int32_t fragmentSize) - { - this->currentNumFrags = 0; - this->position = -1; - this->waitForPos = -1; - this->textSize = 0; +const int32_t SimpleSpanFragmenter::DEFAULT_FRAGMENT_SIZE = 100; - this->queryScorer = queryScorer; - this->fragmentSize = fragmentSize; - } +SimpleSpanFragmenter::SimpleSpanFragmenter(const QueryScorerPtr& queryScorer) { + this->currentNumFrags = 0; + this->position = -1; + this->waitForPos = -1; + this->textSize = 0; - SimpleSpanFragmenter::~SimpleSpanFragmenter() - { - } + this->queryScorer = queryScorer; + this->fragmentSize = DEFAULT_FRAGMENT_SIZE; +} - bool SimpleSpanFragmenter::isNewFragment() - { - position += posIncAtt->getPositionIncrement(); +SimpleSpanFragmenter::SimpleSpanFragmenter(const QueryScorerPtr& queryScorer, int32_t fragmentSize) { + this->currentNumFrags = 0; + this->position = -1; + this->waitForPos = -1; + this->textSize = 0; - if (waitForPos == position) - waitForPos = -1; - else if (waitForPos != -1) - return false; + this->queryScorer = queryScorer; + this->fragmentSize = fragmentSize; +} - WeightedSpanTermPtr wSpanTerm(queryScorer->getWeightedSpanTerm(termAtt->term())); +SimpleSpanFragmenter::~SimpleSpanFragmenter() { +} - if (wSpanTerm) - { - Collection positionSpans(wSpanTerm->getPositionSpans()); +bool SimpleSpanFragmenter::isNewFragment() { + position += posIncAtt->getPositionIncrement(); - for (int32_t i = 0; i < positionSpans.size(); ++i) - { - if (positionSpans[i]->start == position) - { - waitForPos = positionSpans[i]->end + 1; - break; - } - } - } + if (waitForPos == position) { + waitForPos = -1; + } else if (waitForPos != -1) { + return false; + } - bool isNewFrag = (offsetAtt->endOffset() >= (fragmentSize * currentNumFrags) && (textSize - offsetAtt->endOffset()) >= MiscUtils::unsignedShift(fragmentSize, 1)); + WeightedSpanTermPtr wSpanTerm(queryScorer->getWeightedSpanTerm(termAtt->term())); - if (isNewFrag) - ++currentNumFrags; + if (wSpanTerm) { + Collection positionSpans(wSpanTerm->getPositionSpans()); - return isNewFrag; + for (int32_t i = 0; i < positionSpans.size(); ++i) { + if (positionSpans[i]->start == position) { + waitForPos = positionSpans[i]->end + 1; + break; + } + } } - void SimpleSpanFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) - { - position = -1; - currentNumFrags = 1; - textSize = originalText.length(); - termAtt = tokenStream->addAttribute(); - posIncAtt = tokenStream->addAttribute(); - offsetAtt = tokenStream->addAttribute(); + bool isNewFrag = (offsetAtt->endOffset() >= (fragmentSize * currentNumFrags) && (textSize - offsetAtt->endOffset()) >= MiscUtils::unsignedShift(fragmentSize, 1)); + + if (isNewFrag) { + ++currentNumFrags; } + + return isNewFrag; +} + +void SimpleSpanFragmenter::start(const String& originalText, const TokenStreamPtr& tokenStream) { + position = -1; + currentNumFrags = 1; + textSize = originalText.length(); + termAtt = tokenStream->addAttribute(); + posIncAtt = tokenStream->addAttribute(); + offsetAtt = tokenStream->addAttribute(); +} + } diff --git a/src/contrib/highlighter/SpanGradientFormatter.cpp b/src/contrib/highlighter/SpanGradientFormatter.cpp index 0332ec18..d218cdcf 100644 --- a/src/contrib/highlighter/SpanGradientFormatter.cpp +++ b/src/contrib/highlighter/SpanGradientFormatter.cpp @@ -8,31 +8,33 @@ #include "SpanGradientFormatter.h" #include "TokenGroup.h" -namespace Lucene -{ - SpanGradientFormatter::SpanGradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor) : - GradientFormatter(maxScore, minForegroundColor, maxForegroundColor, minBackgroundColor, maxBackgroundColor) - { - } +namespace Lucene { - SpanGradientFormatter::~SpanGradientFormatter() - { - } +SpanGradientFormatter::SpanGradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor) : + GradientFormatter(maxScore, minForegroundColor, maxForegroundColor, minBackgroundColor, maxBackgroundColor) { +} + +SpanGradientFormatter::~SpanGradientFormatter() { +} - String SpanGradientFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) - { - if (tokenGroup->getTotalScore() == 0) - return originalText; - double score = tokenGroup->getTotalScore(); - if (score == 0.0) - return originalText; - StringStream buffer; - buffer << L"" << originalText << L""; - return buffer.str(); +String SpanGradientFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { + if (tokenGroup->getTotalScore() == 0) { + return originalText; } + double score = tokenGroup->getTotalScore(); + if (score == 0.0) { + return originalText; + } + StringStream buffer; + buffer << L"" << originalText << L""; + return buffer.str(); +} + } diff --git a/src/contrib/highlighter/TextFragment.cpp b/src/contrib/highlighter/TextFragment.cpp index 71ac9ad8..6bcafbfe 100644 --- a/src/contrib/highlighter/TextFragment.cpp +++ b/src/contrib/highlighter/TextFragment.cpp @@ -7,73 +7,61 @@ #include "ContribInc.h" #include "TextFragment.h" -namespace Lucene -{ - TextFragment::TextFragment(const StringBufferPtr& markedUpText, int32_t textStartPos, int32_t fragNum) - { - this->markedUpText = markedUpText; - this->textStartPos = textStartPos; - this->textEndPos = 0; - this->fragNum = fragNum; - this->score = 0; - } - - TextFragment::~TextFragment() - { - } - - void TextFragment::setScore(double score) - { - this->score = score; - } - - double TextFragment::getScore() - { - return score; - } - - void TextFragment::merge(const TextFragmentPtr& frag2) - { - textEndPos = frag2->textEndPos; - score = std::max(score, frag2->score); - } - - bool TextFragment::follows(const TextFragmentPtr& fragment) - { - return (textStartPos == fragment->textEndPos); - } - - int32_t TextFragment::getFragNum() - { - return fragNum; - } - - String TextFragment::toString() - { - return markedUpText->toString().substr(textStartPos, textEndPos - textStartPos); - } - - StringBuffer::~StringBuffer() - { - } - - int32_t StringBuffer::length() - { - return buffer.str().length(); - } - - String StringBuffer::toString() - { - return buffer.str(); - } - - void StringBuffer::append(const String& str) - { - buffer << str; - } - - void StringBuffer::clear() - { - buffer.str(L""); - } +namespace Lucene { + +TextFragment::TextFragment(const StringBufferPtr& markedUpText, int32_t textStartPos, int32_t fragNum) { + this->markedUpText = markedUpText; + this->textStartPos = textStartPos; + this->textEndPos = 0; + this->fragNum = fragNum; + this->score = 0; +} + +TextFragment::~TextFragment() { +} + +void TextFragment::setScore(double score) { + this->score = score; +} + +double TextFragment::getScore() { + return score; +} + +void TextFragment::merge(const TextFragmentPtr& frag2) { + textEndPos = frag2->textEndPos; + score = std::max(score, frag2->score); +} + +bool TextFragment::follows(const TextFragmentPtr& fragment) { + return (textStartPos == fragment->textEndPos); +} + +int32_t TextFragment::getFragNum() { + return fragNum; +} + +String TextFragment::toString() { + return markedUpText->toString().substr(textStartPos, textEndPos - textStartPos); +} + +StringBuffer::~StringBuffer() { +} + +int32_t StringBuffer::length() { + return buffer.str().length(); +} + +String StringBuffer::toString() { + return buffer.str(); +} + +void StringBuffer::append(const String& str) { + buffer << str; +} + +void StringBuffer::clear() { + buffer.str(L""); +} + } diff --git a/src/contrib/highlighter/TokenGroup.cpp b/src/contrib/highlighter/TokenGroup.cpp index 2883d876..5e448bad 100644 --- a/src/contrib/highlighter/TokenGroup.cpp +++ b/src/contrib/highlighter/TokenGroup.cpp @@ -11,108 +11,90 @@ #include "TokenStream.h" #include "Token.h" -namespace Lucene -{ - const int32_t TokenGroup::MAX_NUM_TOKENS_PER_GROUP = 50; - - TokenGroup::TokenGroup(const TokenStreamPtr& tokenStream) - { - offsetAtt = tokenStream->addAttribute(); - termAtt = tokenStream->addAttribute(); - - tokens = Collection::newInstance(MAX_NUM_TOKENS_PER_GROUP); - scores = Collection::newInstance(MAX_NUM_TOKENS_PER_GROUP); - numTokens = 0; - startOffset = 0; - endOffset = 0; - tot = 0.0; - matchStartOffset = 0; - matchEndOffset = 0; - } +namespace Lucene { - TokenGroup::~TokenGroup() - { - } +const int32_t TokenGroup::MAX_NUM_TOKENS_PER_GROUP = 50; - void TokenGroup::addToken(double score) - { - if (numTokens < MAX_NUM_TOKENS_PER_GROUP) - { - int32_t termStartOffset = offsetAtt->startOffset(); - int32_t termEndOffset = offsetAtt->endOffset(); - if (numTokens == 0) - { - matchStartOffset = termStartOffset; - startOffset = termStartOffset; - matchEndOffset = termEndOffset; - endOffset = termEndOffset; - tot += score; - } - else - { - startOffset = std::min(startOffset, termStartOffset); - endOffset = std::max(endOffset, termEndOffset); - if (score > 0) - { - if (tot == 0) - { - matchStartOffset = offsetAtt->startOffset(); - matchEndOffset = offsetAtt->endOffset(); - } - else - { - matchStartOffset = std::min(matchStartOffset, termStartOffset); - matchEndOffset = std::max(matchEndOffset, termEndOffset); - } - tot += score; +TokenGroup::TokenGroup(const TokenStreamPtr& tokenStream) { + offsetAtt = tokenStream->addAttribute(); + termAtt = tokenStream->addAttribute(); + + tokens = Collection::newInstance(MAX_NUM_TOKENS_PER_GROUP); + scores = Collection::newInstance(MAX_NUM_TOKENS_PER_GROUP); + numTokens = 0; + startOffset = 0; + endOffset = 0; + tot = 0.0; + matchStartOffset = 0; + matchEndOffset = 0; +} + +TokenGroup::~TokenGroup() { +} + +void TokenGroup::addToken(double score) { + if (numTokens < MAX_NUM_TOKENS_PER_GROUP) { + int32_t termStartOffset = offsetAtt->startOffset(); + int32_t termEndOffset = offsetAtt->endOffset(); + if (numTokens == 0) { + matchStartOffset = termStartOffset; + startOffset = termStartOffset; + matchEndOffset = termEndOffset; + endOffset = termEndOffset; + tot += score; + } else { + startOffset = std::min(startOffset, termStartOffset); + endOffset = std::max(endOffset, termEndOffset); + if (score > 0) { + if (tot == 0) { + matchStartOffset = offsetAtt->startOffset(); + matchEndOffset = offsetAtt->endOffset(); + } else { + matchStartOffset = std::min(matchStartOffset, termStartOffset); + matchEndOffset = std::max(matchEndOffset, termEndOffset); } + tot += score; } - TokenPtr token(newLucene(termStartOffset, termEndOffset)); - token->setTermBuffer(termAtt->term()); - tokens[numTokens] = token; - scores[numTokens] = score; - ++numTokens; } + TokenPtr token(newLucene(termStartOffset, termEndOffset)); + token->setTermBuffer(termAtt->term()); + tokens[numTokens] = token; + scores[numTokens] = score; + ++numTokens; } +} - bool TokenGroup::isDistinct() - { - return (offsetAtt->startOffset() >= endOffset); - } +bool TokenGroup::isDistinct() { + return (offsetAtt->startOffset() >= endOffset); +} - void TokenGroup::clear() - { - numTokens = 0; - tot = 0; - } +void TokenGroup::clear() { + numTokens = 0; + tot = 0; +} - TokenPtr TokenGroup::getToken(int32_t index) - { - return tokens[index]; - } +TokenPtr TokenGroup::getToken(int32_t index) { + return tokens[index]; +} - double TokenGroup::getScore(int32_t index) - { - return scores[index]; - } +double TokenGroup::getScore(int32_t index) { + return scores[index]; +} - int32_t TokenGroup::getEndOffset() - { - return endOffset; - } +int32_t TokenGroup::getEndOffset() { + return endOffset; +} - int32_t TokenGroup::getNumTokens() - { - return numTokens; - } +int32_t TokenGroup::getNumTokens() { + return numTokens; +} - int32_t TokenGroup::getStartOffset() - { - return startOffset; - } +int32_t TokenGroup::getStartOffset() { + return startOffset; +} + +double TokenGroup::getTotalScore() { + return tot; +} - double TokenGroup::getTotalScore() - { - return tot; - } } diff --git a/src/contrib/highlighter/TokenSources.cpp b/src/contrib/highlighter/TokenSources.cpp index 8facc957..9810f331 100644 --- a/src/contrib/highlighter/TokenSources.cpp +++ b/src/contrib/highlighter/TokenSources.cpp @@ -19,170 +19,157 @@ #include "StringReader.h" #include "StringUtils.h" -namespace Lucene -{ - TokenSources::~TokenSources() - { +namespace Lucene { + +TokenSources::~TokenSources() { +} + +TokenStreamPtr TokenSources::getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const DocumentPtr& doc, const AnalyzerPtr& analyzer) { + TokenStreamPtr ts; + TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); + if (tfv) { + if (boost::dynamic_pointer_cast(tfv)) { + ts = getTokenStream(boost::dynamic_pointer_cast(tfv)); + } } + // No token info stored so fall back to analyzing raw content + if (!ts) { + ts = getTokenStream(doc, field, analyzer); + } + return ts; +} - TokenStreamPtr TokenSources::getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const DocumentPtr& doc, const AnalyzerPtr& analyzer) - { - TokenStreamPtr ts; - TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); - if (tfv) - { - if (boost::dynamic_pointer_cast(tfv)) - ts = getTokenStream(boost::dynamic_pointer_cast(tfv)); +TokenStreamPtr TokenSources::getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer) { + TokenStreamPtr ts; + TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); + if (tfv) { + if (boost::dynamic_pointer_cast(tfv)) { + ts = getTokenStream(boost::dynamic_pointer_cast(tfv)); } - // No token info stored so fall back to analyzing raw content - if (!ts) - ts = getTokenStream(doc, field, analyzer); - return ts; } + // No token info stored so fall back to analyzing raw content + if (!ts) { + ts = getTokenStream(reader, docId, field, analyzer); + } + return ts; +} - TokenStreamPtr TokenSources::getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer) - { - TokenStreamPtr ts; - TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); - if (tfv) - { - if (boost::dynamic_pointer_cast(tfv)) - ts = getTokenStream(boost::dynamic_pointer_cast(tfv)); +TokenStreamPtr TokenSources::getTokenStream(const TermPositionVectorPtr& tpv) { + // assumes the worst and makes no assumptions about token position sequences. + return getTokenStream(tpv, false); +} + +struct lessTokenOffset { + inline bool operator()(const TokenPtr& first, const TokenPtr& second) const { + if (first->startOffset() < second->startOffset()) { + return true; } - // No token info stored so fall back to analyzing raw content - if (!ts) - ts = getTokenStream(reader, docId, field, analyzer); - return ts; + return (first->startOffset() > second->endOffset()); } +}; - TokenStreamPtr TokenSources::getTokenStream(const TermPositionVectorPtr& tpv) - { - // assumes the worst and makes no assumptions about token position sequences. - return getTokenStream(tpv, false); +TokenStreamPtr TokenSources::getTokenStream(const TermPositionVectorPtr& tpv, bool tokenPositionsGuaranteedContiguous) { + // code to reconstruct the original sequence of Tokens + Collection terms(tpv->getTerms()); + Collection freq(tpv->getTermFrequencies()); + int32_t totalTokens = 0; + + for (int32_t t = 0; t < freq.size(); ++t) { + totalTokens += freq[t]; } - struct lessTokenOffset - { - inline bool operator()(const TokenPtr& first, const TokenPtr& second) const - { - if (first->startOffset() < second->startOffset()) - return true; - return (first->startOffset() > second->endOffset()); + Collection tokensInOriginalOrder(Collection::newInstance(totalTokens)); + Collection unsortedTokens; + for (int32_t t = 0; t < freq.size(); ++t) { + Collection offsets(tpv->getOffsets(t)); + if (!offsets) { + return TokenStreamPtr(); + } + Collection pos; + if (tokenPositionsGuaranteedContiguous) { + // try get the token position info to speed up assembly of tokens into sorted sequence + pos = tpv->getTermPositions(t); } - }; - - TokenStreamPtr TokenSources::getTokenStream(const TermPositionVectorPtr& tpv, bool tokenPositionsGuaranteedContiguous) - { - // code to reconstruct the original sequence of Tokens - Collection terms(tpv->getTerms()); - Collection freq(tpv->getTermFrequencies()); - int32_t totalTokens = 0; - - for (int32_t t = 0; t < freq.size(); ++t) - totalTokens += freq[t]; - - Collection tokensInOriginalOrder(Collection::newInstance(totalTokens)); - Collection unsortedTokens; - for (int32_t t = 0; t < freq.size(); ++t) - { - Collection offsets(tpv->getOffsets(t)); - if (!offsets) - return TokenStreamPtr(); - Collection pos; - if (tokenPositionsGuaranteedContiguous) - { - // try get the token position info to speed up assembly of tokens into sorted sequence - pos = tpv->getTermPositions(t); + if (!pos) { + // tokens NOT stored with positions or not guaranteed contiguous - must add to list and sort later + if (!unsortedTokens) { + unsortedTokens = Collection::newInstance(); } - if (!pos) - { - // tokens NOT stored with positions or not guaranteed contiguous - must add to list and sort later - if (!unsortedTokens) - unsortedTokens = Collection::newInstance(); - for (int32_t tp = 0; tp < offsets.size(); ++tp) - { - TokenPtr token(newLucene(offsets[tp]->getStartOffset(), offsets[tp]->getEndOffset())); - token->setTermBuffer(terms[t]); - unsortedTokens.add(token); - } + for (int32_t tp = 0; tp < offsets.size(); ++tp) { + TokenPtr token(newLucene(offsets[tp]->getStartOffset(), offsets[tp]->getEndOffset())); + token->setTermBuffer(terms[t]); + unsortedTokens.add(token); } - else - { - // We have positions stored and a guarantee that the token position information is contiguous - - // This may be fast BUT wont work if Tokenizers used which create >1 token in same position or - // creates jumps in position numbers - this code would fail under those circumstances - - // Tokens stored with positions - can use this to index straight into sorted array - for (int32_t tp = 0; tp < pos.size(); ++tp) - { - TokenPtr token(newLucene(terms[t], offsets[tp]->getStartOffset(), offsets[tp]->getEndOffset())); - tokensInOriginalOrder[pos[tp]] = token; - } + } else { + // We have positions stored and a guarantee that the token position information is contiguous + + // This may be fast BUT wont work if Tokenizers used which create >1 token in same position or + // creates jumps in position numbers - this code would fail under those circumstances + + // Tokens stored with positions - can use this to index straight into sorted array + for (int32_t tp = 0; tp < pos.size(); ++tp) { + TokenPtr token(newLucene(terms[t], offsets[tp]->getStartOffset(), offsets[tp]->getEndOffset())); + tokensInOriginalOrder[pos[tp]] = token; } } - // If the field has been stored without position data we must perform a sort - if (unsortedTokens) - { - tokensInOriginalOrder = unsortedTokens; - std::sort(tokensInOriginalOrder.begin(), tokensInOriginalOrder.end(), lessTokenOffset()); - } - return newLucene(tokensInOriginalOrder); } + // If the field has been stored without position data we must perform a sort + if (unsortedTokens) { + tokensInOriginalOrder = unsortedTokens; + std::sort(tokensInOriginalOrder.begin(), tokensInOriginalOrder.end(), lessTokenOffset()); + } + return newLucene(tokensInOriginalOrder); +} - TokenStreamPtr TokenSources::getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field) - { - TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); - if (!tfv) - boost::throw_exception(IllegalArgumentException(field + L" in doc #" + StringUtils::toString(docId) + L"does not have any term position data stored")); - - if (boost::dynamic_pointer_cast(tfv)) - { - TermPositionVectorPtr tpv(boost::dynamic_pointer_cast(reader->getTermFreqVector(docId, field))); - return getTokenStream(tpv); - } +TokenStreamPtr TokenSources::getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field) { + TermFreqVectorPtr tfv(reader->getTermFreqVector(docId, field)); + if (!tfv) { boost::throw_exception(IllegalArgumentException(field + L" in doc #" + StringUtils::toString(docId) + L"does not have any term position data stored")); - return TokenStreamPtr(); } - TokenStreamPtr TokenSources::getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer) - { - DocumentPtr doc(reader->document(docId)); - return getTokenStream(doc, field, analyzer); + if (boost::dynamic_pointer_cast(tfv)) { + TermPositionVectorPtr tpv(boost::dynamic_pointer_cast(reader->getTermFreqVector(docId, field))); + return getTokenStream(tpv); } + boost::throw_exception(IllegalArgumentException(field + L" in doc #" + StringUtils::toString(docId) + L"does not have any term position data stored")); + return TokenStreamPtr(); +} - TokenStreamPtr TokenSources::getTokenStream(const DocumentPtr& doc, const String& field, const AnalyzerPtr& analyzer) - { - String contents(doc->get(field)); - if (contents.empty()) - boost::throw_exception(IllegalArgumentException(L"Field " + field + L" in document is not stored and cannot be analyzed")); - return getTokenStream(field, contents, analyzer); - } +TokenStreamPtr TokenSources::getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer) { + DocumentPtr doc(reader->document(docId)); + return getTokenStream(doc, field, analyzer); +} - TokenStreamPtr TokenSources::getTokenStream(const String& field, const String& contents, const AnalyzerPtr& analyzer) - { - return analyzer->tokenStream(field, newLucene(contents)); +TokenStreamPtr TokenSources::getTokenStream(const DocumentPtr& doc, const String& field, const AnalyzerPtr& analyzer) { + String contents(doc->get(field)); + if (contents.empty()) { + boost::throw_exception(IllegalArgumentException(L"Field " + field + L" in document is not stored and cannot be analyzed")); } + return getTokenStream(field, contents, analyzer); +} - StoredTokenStream::StoredTokenStream(Collection tokens) - { - this->tokens = tokens; - this->termAtt = addAttribute(); - this->offsetAtt = addAttribute(); - } +TokenStreamPtr TokenSources::getTokenStream(const String& field, const String& contents, const AnalyzerPtr& analyzer) { + return analyzer->tokenStream(field, newLucene(contents)); +} - StoredTokenStream::~StoredTokenStream() - { - } +StoredTokenStream::StoredTokenStream(Collection tokens) { + this->tokens = tokens; + this->termAtt = addAttribute(); + this->offsetAtt = addAttribute(); +} - bool StoredTokenStream::incrementToken() - { - if (currentToken >= tokens.size()) - return false; - clearAttributes(); - TokenPtr token(tokens[currentToken++]); - termAtt->setTermBuffer(token->term()); - offsetAtt->setOffset(token->startOffset(), token->endOffset()); - return true; +StoredTokenStream::~StoredTokenStream() { +} + +bool StoredTokenStream::incrementToken() { + if (currentToken >= tokens.size()) { + return false; } + clearAttributes(); + TokenPtr token(tokens[currentToken++]); + termAtt->setTermBuffer(token->term()); + offsetAtt->setOffset(token->startOffset(), token->endOffset()); + return true; +} + } diff --git a/src/contrib/highlighter/WeightedSpanTerm.cpp b/src/contrib/highlighter/WeightedSpanTerm.cpp index 44a5f1be..99fe4dd2 100644 --- a/src/contrib/highlighter/WeightedSpanTerm.cpp +++ b/src/contrib/highlighter/WeightedSpanTerm.cpp @@ -7,57 +7,49 @@ #include "ContribInc.h" #include "WeightedSpanTerm.h" -namespace Lucene -{ - WeightedSpanTerm::WeightedSpanTerm(double weight, const String& term, bool positionSensitive) : WeightedTerm(weight, term) - { - this->positionSensitive = positionSensitive; - this->positionSpans = Collection::newInstance(); - } +namespace Lucene { - WeightedSpanTerm::~WeightedSpanTerm() - { - } +WeightedSpanTerm::WeightedSpanTerm(double weight, const String& term, bool positionSensitive) : WeightedTerm(weight, term) { + this->positionSensitive = positionSensitive; + this->positionSpans = Collection::newInstance(); +} + +WeightedSpanTerm::~WeightedSpanTerm() { +} - bool WeightedSpanTerm::checkPosition(int32_t position) - { - // There would probably be a slight speed improvement if PositionSpans where kept in some sort of priority queue - - // that way this method could bail early without checking each PositionSpan. - for (Collection::iterator posSpan = positionSpans.begin(); posSpan != positionSpans.end(); ++posSpan) - { - if (position >= (*posSpan)->start && position <= (*posSpan)->end) - return true; +bool WeightedSpanTerm::checkPosition(int32_t position) { + // There would probably be a slight speed improvement if PositionSpans where kept in some sort of priority queue - + // that way this method could bail early without checking each PositionSpan. + for (Collection::iterator posSpan = positionSpans.begin(); posSpan != positionSpans.end(); ++posSpan) { + if (position >= (*posSpan)->start && position <= (*posSpan)->end) { + return true; } - return false; } + return false; +} - void WeightedSpanTerm::addPositionSpans(Collection positionSpans) - { - this->positionSpans.addAll(positionSpans.begin(), positionSpans.end()); - } +void WeightedSpanTerm::addPositionSpans(Collection positionSpans) { + this->positionSpans.addAll(positionSpans.begin(), positionSpans.end()); +} - bool WeightedSpanTerm::isPositionSensitive() - { - return positionSensitive; - } +bool WeightedSpanTerm::isPositionSensitive() { + return positionSensitive; +} - void WeightedSpanTerm::setPositionSensitive(bool positionSensitive) - { - this->positionSensitive = positionSensitive; - } +void WeightedSpanTerm::setPositionSensitive(bool positionSensitive) { + this->positionSensitive = positionSensitive; +} - Collection WeightedSpanTerm::getPositionSpans() - { - return positionSpans; - } +Collection WeightedSpanTerm::getPositionSpans() { + return positionSpans; +} - PositionSpan::PositionSpan(int32_t start, int32_t end) - { - this->start = start; - this->end = end; - } +PositionSpan::PositionSpan(int32_t start, int32_t end) { + this->start = start; + this->end = end; +} + +PositionSpan::~PositionSpan() { +} - PositionSpan::~PositionSpan() - { - } } diff --git a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp index a4c82231..774967ce 100644 --- a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp +++ b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp @@ -30,465 +30,409 @@ #include "MemoryIndex.h" #include "MiscUtils.h" -namespace Lucene -{ - WeightedSpanTermExtractor::WeightedSpanTermExtractor(const String& defaultField) - { - this->defaultField = defaultField; - this->expandMultiTermQuery = false; - this->cachedTokenStream = false; - this->wrapToCaching = true; - this->readers = MapStringIndexReader::newInstance(); - } +namespace Lucene { + +WeightedSpanTermExtractor::WeightedSpanTermExtractor(const String& defaultField) { + this->defaultField = defaultField; + this->expandMultiTermQuery = false; + this->cachedTokenStream = false; + this->wrapToCaching = true; + this->readers = MapStringIndexReader::newInstance(); +} - WeightedSpanTermExtractor::~WeightedSpanTermExtractor() - { - } +WeightedSpanTermExtractor::~WeightedSpanTermExtractor() { +} - void WeightedSpanTermExtractor::closeReaders() - { - for (MapStringIndexReader::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - try - { - reader->second->close(); - } - catch (...) - { - } +void WeightedSpanTermExtractor::closeReaders() { + for (MapStringIndexReader::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + try { + reader->second->close(); + } catch (...) { } } +} - void WeightedSpanTermExtractor::extract(const QueryPtr& query, const MapWeightedSpanTermPtr& terms) - { - QueryPtr _query(query); - if (MiscUtils::typeOf(_query)) - { - Collection queryClauses(boost::dynamic_pointer_cast(_query)->getClauses()); - for (int32_t i = 0; i < queryClauses.size(); ++i) - { - if (!queryClauses[i]->isProhibited()) - extract(queryClauses[i]->getQuery(), terms); +void WeightedSpanTermExtractor::extract(const QueryPtr& query, const MapWeightedSpanTermPtr& terms) { + QueryPtr _query(query); + if (MiscUtils::typeOf(_query)) { + Collection queryClauses(boost::dynamic_pointer_cast(_query)->getClauses()); + for (int32_t i = 0; i < queryClauses.size(); ++i) { + if (!queryClauses[i]->isProhibited()) { + extract(queryClauses[i]->getQuery(), terms); } } - else if (MiscUtils::typeOf(_query)) - { - PhraseQueryPtr phraseQuery(boost::dynamic_pointer_cast(_query)); - Collection phraseQueryTerms(phraseQuery->getTerms()); - Collection clauses(Collection::newInstance(phraseQueryTerms.size())); - for (int32_t i = 0; i < phraseQueryTerms.size(); ++i) - clauses[i] = newLucene(phraseQueryTerms[i]); - int32_t slop = phraseQuery->getSlop(); - Collection positions(phraseQuery->getPositions()); - // add largest position increment to slop - if (!positions.empty()) - { - int32_t lastPos = positions[0]; - int32_t largestInc = 0; - int32_t sz = positions.size(); - for (int32_t i = 1; i < sz; ++i) - { - int32_t pos = positions[i]; - int32_t inc = pos - lastPos; - if (inc > largestInc) - largestInc = inc; - lastPos = pos; + } else if (MiscUtils::typeOf(_query)) { + PhraseQueryPtr phraseQuery(boost::dynamic_pointer_cast(_query)); + Collection phraseQueryTerms(phraseQuery->getTerms()); + Collection clauses(Collection::newInstance(phraseQueryTerms.size())); + for (int32_t i = 0; i < phraseQueryTerms.size(); ++i) { + clauses[i] = newLucene(phraseQueryTerms[i]); + } + int32_t slop = phraseQuery->getSlop(); + Collection positions(phraseQuery->getPositions()); + // add largest position increment to slop + if (!positions.empty()) { + int32_t lastPos = positions[0]; + int32_t largestInc = 0; + int32_t sz = positions.size(); + for (int32_t i = 1; i < sz; ++i) { + int32_t pos = positions[i]; + int32_t inc = pos - lastPos; + if (inc > largestInc) { + largestInc = inc; } - if (largestInc > 1) - slop += largestInc; + lastPos = pos; } + if (largestInc > 1) { + slop += largestInc; + } + } - bool inorder = (slop == 0); - - SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); - sp->setBoost(_query->getBoost()); - extractWeightedSpanTerms(terms, sp); + bool inorder = (slop == 0); + + SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); + sp->setBoost(_query->getBoost()); + extractWeightedSpanTerms(terms, sp); + } else if (MiscUtils::typeOf(_query)) { + extractWeightedTerms(terms, _query); + } else if (MiscUtils::typeOf(_query)) { + extractWeightedSpanTerms(terms, boost::dynamic_pointer_cast(_query)); + } else if (MiscUtils::typeOf(_query)) { + extract(boost::dynamic_pointer_cast(_query)->getQuery(), terms); + } else if (MiscUtils::typeOf(_query)) { + DisjunctionMaxQueryPtr dmq(boost::dynamic_pointer_cast(_query)); + for (Collection::iterator q = dmq->begin(); q != dmq->end(); ++q) { + extract(*q, terms); } - else if (MiscUtils::typeOf(_query)) - extractWeightedTerms(terms, _query); - else if (MiscUtils::typeOf(_query)) - extractWeightedSpanTerms(terms, boost::dynamic_pointer_cast(_query)); - else if (MiscUtils::typeOf(_query)) - extract(boost::dynamic_pointer_cast(_query)->getQuery(), terms); - else if (MiscUtils::typeOf(_query)) - { - DisjunctionMaxQueryPtr dmq(boost::dynamic_pointer_cast(_query)); - for (Collection::iterator q = dmq->begin(); q != dmq->end(); ++q) - extract(*q, terms); + } else if (MiscUtils::typeOf(_query) && expandMultiTermQuery) { + MultiTermQueryPtr mtq(boost::dynamic_pointer_cast(_query)); + if (mtq->getRewriteMethod() != MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()) { + mtq = boost::dynamic_pointer_cast(mtq->clone()); + mtq->setRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); + _query = mtq; } - else if (MiscUtils::typeOf(_query) && expandMultiTermQuery) - { - MultiTermQueryPtr mtq(boost::dynamic_pointer_cast(_query)); - if (mtq->getRewriteMethod() != MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()) - { - mtq = boost::dynamic_pointer_cast(mtq->clone()); - mtq->setRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); - _query = mtq; - } - FakeReaderPtr fReader(newLucene()); - MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()->rewrite(fReader, mtq); - if (!fReader->field.empty()) - { - IndexReaderPtr ir(getReaderForField(fReader->field)); - extract(_query->rewrite(ir), terms); - } + FakeReaderPtr fReader(newLucene()); + MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()->rewrite(fReader, mtq); + if (!fReader->field.empty()) { + IndexReaderPtr ir(getReaderForField(fReader->field)); + extract(_query->rewrite(ir), terms); } - else if (MiscUtils::typeOf(_query)) - { - MultiPhraseQueryPtr mpq(boost::dynamic_pointer_cast(_query)); - Collection< Collection > termArrays(mpq->getTermArrays()); - Collection positions(mpq->getPositions()); - if (!positions.empty()) - { - int32_t maxPosition = positions[positions.size() - 1]; - for (int32_t i = 0; i < positions.size() - 1; ++i) - { - if (positions[i] > maxPosition) - maxPosition = positions[i]; + } else if (MiscUtils::typeOf(_query)) { + MultiPhraseQueryPtr mpq(boost::dynamic_pointer_cast(_query)); + Collection< Collection > termArrays(mpq->getTermArrays()); + Collection positions(mpq->getPositions()); + if (!positions.empty()) { + int32_t maxPosition = positions[positions.size() - 1]; + for (int32_t i = 0; i < positions.size() - 1; ++i) { + if (positions[i] > maxPosition) { + maxPosition = positions[i]; } + } - Collection< Collection > disjunctLists(Collection< Collection >::newInstance(maxPosition + 1)); - int32_t distinctPositions = 0; - for (int32_t i = 0; i < termArrays.size(); ++i) - { - Collection termArray(termArrays[i]); - Collection disjuncts(disjunctLists[positions[i]]); - if (!disjuncts) - { - disjunctLists[positions[i]] = Collection::newInstance(); - disjuncts = disjunctLists[positions[i]]; - ++distinctPositions; - } - for (int32_t j = 0; j < termArray.size(); ++j) - disjuncts.add(newLucene(termArray[j])); + Collection< Collection > disjunctLists(Collection< Collection >::newInstance(maxPosition + 1)); + int32_t distinctPositions = 0; + for (int32_t i = 0; i < termArrays.size(); ++i) { + Collection termArray(termArrays[i]); + Collection disjuncts(disjunctLists[positions[i]]); + if (!disjuncts) { + disjunctLists[positions[i]] = Collection::newInstance(); + disjuncts = disjunctLists[positions[i]]; + ++distinctPositions; + } + for (int32_t j = 0; j < termArray.size(); ++j) { + disjuncts.add(newLucene(termArray[j])); } + } - int32_t positionGaps = 0; - int32_t position = 0; - Collection clauses(Collection::newInstance(distinctPositions)); - for (int32_t i = 0; i < disjunctLists.size(); ++i) - { - Collection disjuncts(disjunctLists[i]); - if (disjuncts) - clauses[position++] = newLucene(disjuncts); - else - ++positionGaps; + int32_t positionGaps = 0; + int32_t position = 0; + Collection clauses(Collection::newInstance(distinctPositions)); + for (int32_t i = 0; i < disjunctLists.size(); ++i) { + Collection disjuncts(disjunctLists[i]); + if (disjuncts) { + clauses[position++] = newLucene(disjuncts); + } else { + ++positionGaps; } + } - int32_t slop = mpq->getSlop(); - bool inorder = (slop == 0); + int32_t slop = mpq->getSlop(); + bool inorder = (slop == 0); - SpanNearQueryPtr sp(newLucene(clauses, slop + positionGaps, inorder)); - sp->setBoost(_query->getBoost()); - extractWeightedSpanTerms(terms, sp); - } + SpanNearQueryPtr sp(newLucene(clauses, slop + positionGaps, inorder)); + sp->setBoost(_query->getBoost()); + extractWeightedSpanTerms(terms, sp); } } +} - void WeightedSpanTermExtractor::extractWeightedSpanTerms(const MapWeightedSpanTermPtr& terms, const SpanQueryPtr& spanQuery) - { - HashSet fieldNames(HashSet::newInstance()); - if (fieldName.empty()) - collectSpanQueryFields(spanQuery, fieldNames); - else - fieldNames.add(fieldName); - // To support the use of the default field name - if (!defaultField.empty()) - fieldNames.add(defaultField); - - MapStringSpanQuery queries(MapStringSpanQuery::newInstance()); - SetTerm nonWeightedTerms(SetTerm::newInstance()); - - bool rewriteQuery = mustRewriteQuery(spanQuery); - if (rewriteQuery) - { - for (HashSet::iterator field = fieldNames.begin(); field != fieldNames.end(); ++field) - { - SpanQueryPtr rewrittenQuery(boost::dynamic_pointer_cast(spanQuery->rewrite(getReaderForField(*field)))); - queries.put(*field, rewrittenQuery); - rewrittenQuery->extractTerms(nonWeightedTerms); - } +void WeightedSpanTermExtractor::extractWeightedSpanTerms(const MapWeightedSpanTermPtr& terms, const SpanQueryPtr& spanQuery) { + HashSet fieldNames(HashSet::newInstance()); + if (fieldName.empty()) { + collectSpanQueryFields(spanQuery, fieldNames); + } else { + fieldNames.add(fieldName); + } + // To support the use of the default field name + if (!defaultField.empty()) { + fieldNames.add(defaultField); + } + + MapStringSpanQuery queries(MapStringSpanQuery::newInstance()); + SetTerm nonWeightedTerms(SetTerm::newInstance()); + + bool rewriteQuery = mustRewriteQuery(spanQuery); + if (rewriteQuery) { + for (HashSet::iterator field = fieldNames.begin(); field != fieldNames.end(); ++field) { + SpanQueryPtr rewrittenQuery(boost::dynamic_pointer_cast(spanQuery->rewrite(getReaderForField(*field)))); + queries.put(*field, rewrittenQuery); + rewrittenQuery->extractTerms(nonWeightedTerms); } - else - spanQuery->extractTerms(nonWeightedTerms); - - Collection spanPositions(Collection::newInstance()); - - for (HashSet::iterator field = fieldNames.begin(); field != fieldNames.end(); ++field) - { - IndexReaderPtr reader(getReaderForField(*field)); - SpansPtr spans; - if (rewriteQuery) - spans = queries.get(*field)->getSpans(reader); - else - spans = spanQuery->getSpans(reader); - - // collect span positions - while (spans->next()) - spanPositions.add(newLucene(spans->start(), spans->end() - 1)); + } else { + spanQuery->extractTerms(nonWeightedTerms); + } + + Collection spanPositions(Collection::newInstance()); + + for (HashSet::iterator field = fieldNames.begin(); field != fieldNames.end(); ++field) { + IndexReaderPtr reader(getReaderForField(*field)); + SpansPtr spans; + if (rewriteQuery) { + spans = queries.get(*field)->getSpans(reader); + } else { + spans = spanQuery->getSpans(reader); } - if (spanPositions.empty()) - { - // no spans found - return; + // collect span positions + while (spans->next()) { + spanPositions.add(newLucene(spans->start(), spans->end() - 1)); } + } - for (SetTerm::iterator queryTerm = nonWeightedTerms.begin(); queryTerm != nonWeightedTerms.end(); ++queryTerm) - { - if (fieldNameComparator((*queryTerm)->field())) - { - WeightedSpanTermPtr weightedSpanTerm(terms->get((*queryTerm)->text())); - if (!weightedSpanTerm) - { - weightedSpanTerm = newLucene(spanQuery->getBoost(), (*queryTerm)->text()); + if (spanPositions.empty()) { + // no spans found + return; + } + + for (SetTerm::iterator queryTerm = nonWeightedTerms.begin(); queryTerm != nonWeightedTerms.end(); ++queryTerm) { + if (fieldNameComparator((*queryTerm)->field())) { + WeightedSpanTermPtr weightedSpanTerm(terms->get((*queryTerm)->text())); + if (!weightedSpanTerm) { + weightedSpanTerm = newLucene(spanQuery->getBoost(), (*queryTerm)->text()); + weightedSpanTerm->addPositionSpans(spanPositions); + weightedSpanTerm->positionSensitive = true; + terms->put((*queryTerm)->text(), weightedSpanTerm); + } else { + if (!spanPositions.empty()) { weightedSpanTerm->addPositionSpans(spanPositions); - weightedSpanTerm->positionSensitive = true; - terms->put((*queryTerm)->text(), weightedSpanTerm); - } - else - { - if (!spanPositions.empty()) - weightedSpanTerm->addPositionSpans(spanPositions); } } } } +} - void WeightedSpanTermExtractor::extractWeightedTerms(const MapWeightedSpanTermPtr& terms, const QueryPtr& query) - { - SetTerm nonWeightedTerms(SetTerm::newInstance()); - query->extractTerms(nonWeightedTerms); +void WeightedSpanTermExtractor::extractWeightedTerms(const MapWeightedSpanTermPtr& terms, const QueryPtr& query) { + SetTerm nonWeightedTerms(SetTerm::newInstance()); + query->extractTerms(nonWeightedTerms); - for (SetTerm::iterator queryTerm = nonWeightedTerms.begin(); queryTerm != nonWeightedTerms.end(); ++queryTerm) - { - if (fieldNameComparator((*queryTerm)->field())) - { - WeightedSpanTermPtr weightedSpanTerm(newLucene(query->getBoost(), (*queryTerm)->text())); - terms->put((*queryTerm)->text(), weightedSpanTerm); - } + for (SetTerm::iterator queryTerm = nonWeightedTerms.begin(); queryTerm != nonWeightedTerms.end(); ++queryTerm) { + if (fieldNameComparator((*queryTerm)->field())) { + WeightedSpanTermPtr weightedSpanTerm(newLucene(query->getBoost(), (*queryTerm)->text())); + terms->put((*queryTerm)->text(), weightedSpanTerm); } } +} - bool WeightedSpanTermExtractor::fieldNameComparator(const String& fieldNameToCheck) - { - return (fieldName.empty() || fieldNameToCheck == fieldName || fieldNameToCheck == defaultField); - } +bool WeightedSpanTermExtractor::fieldNameComparator(const String& fieldNameToCheck) { + return (fieldName.empty() || fieldNameToCheck == fieldName || fieldNameToCheck == defaultField); +} - IndexReaderPtr WeightedSpanTermExtractor::getReaderForField(const String& field) - { - if (wrapToCaching && !cachedTokenStream && !MiscUtils::typeOf(tokenStream)) - { - tokenStream = newLucene(tokenStream); - cachedTokenStream = true; - } - IndexReaderPtr reader(readers.get(field)); - if (!reader) - { - MemoryIndexPtr indexer(newLucene()); - indexer->addField(field, tokenStream); - tokenStream->reset(); - IndexSearcherPtr searcher(indexer->createSearcher()); - reader = searcher->getIndexReader(); - readers.put(field, reader); - } - return reader; +IndexReaderPtr WeightedSpanTermExtractor::getReaderForField(const String& field) { + if (wrapToCaching && !cachedTokenStream && !MiscUtils::typeOf(tokenStream)) { + tokenStream = newLucene(tokenStream); + cachedTokenStream = true; + } + IndexReaderPtr reader(readers.get(field)); + if (!reader) { + MemoryIndexPtr indexer(newLucene()); + indexer->addField(field, tokenStream); + tokenStream->reset(); + IndexSearcherPtr searcher(indexer->createSearcher()); + reader = searcher->getIndexReader(); + readers.put(field, reader); } + return reader; +} - MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream) - { - return getWeightedSpanTerms(query, tokenStream, L""); +MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream) { + return getWeightedSpanTerms(query, tokenStream, L""); +} + +MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName) { + if (!fieldName.empty()) { + this->fieldName = fieldName; + } else { + this->fieldName.clear(); } - MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName) - { - if (!fieldName.empty()) - this->fieldName = fieldName; - else - this->fieldName.clear(); + MapWeightedSpanTermPtr terms(newLucene()); + this->tokenStream = tokenStream; - MapWeightedSpanTermPtr terms(newLucene()); - this->tokenStream = tokenStream; + LuceneException finally; + try { + extract(query, terms); + } catch (LuceneException& e) { + finally = e; + } + closeReaders(); + finally.throwException(); + return terms; +} - LuceneException finally; - try - { - extract(query, terms); - } - catch (LuceneException& e) - { - finally = e; - } - closeReaders(); - finally.throwException(); - return terms; +MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTermsWithScores(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName, const IndexReaderPtr& reader) { + if (!fieldName.empty()) { + this->fieldName = fieldName; + } else { + this->fieldName.clear(); } - MapWeightedSpanTermPtr WeightedSpanTermExtractor::getWeightedSpanTermsWithScores(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName, const IndexReaderPtr& reader) - { - if (!fieldName.empty()) - this->fieldName = fieldName; - else - this->fieldName.clear(); + MapWeightedSpanTermPtr terms(newLucene()); + extract(query, terms); - MapWeightedSpanTermPtr terms(newLucene()); - extract(query, terms); + int32_t totalNumDocs = reader->numDocs(); - int32_t totalNumDocs = reader->numDocs(); - - LuceneException finally; - try - { - for (MapStringWeightedSpanTerm::iterator weightedSpanTerm = terms->begin(); weightedSpanTerm != terms->end(); ++weightedSpanTerm) - { - int32_t docFreq = reader->docFreq(newLucene(fieldName, weightedSpanTerm->second->term)); - // docFreq counts deletes - if (totalNumDocs < docFreq) - docFreq = totalNumDocs; - // IDF algorithm taken from DefaultSimilarity class - double idf = (double)(std::log((double)totalNumDocs / (double)(docFreq + 1)) + 1.0); - weightedSpanTerm->second->weight *= idf; + LuceneException finally; + try { + for (MapStringWeightedSpanTerm::iterator weightedSpanTerm = terms->begin(); weightedSpanTerm != terms->end(); ++weightedSpanTerm) { + int32_t docFreq = reader->docFreq(newLucene(fieldName, weightedSpanTerm->second->term)); + // docFreq counts deletes + if (totalNumDocs < docFreq) { + docFreq = totalNumDocs; } + // IDF algorithm taken from DefaultSimilarity class + double idf = (double)(std::log((double)totalNumDocs / (double)(docFreq + 1)) + 1.0); + weightedSpanTerm->second->weight *= idf; } - catch (LuceneException& e) - { - finally = e; - } - closeReaders(); - finally.throwException(); - return terms; + } catch (LuceneException& e) { + finally = e; } + closeReaders(); + finally.throwException(); + return terms; +} - void WeightedSpanTermExtractor::collectSpanQueryFields(const SpanQueryPtr& spanQuery, HashSet fieldNames) - { - if (MiscUtils::typeOf(spanQuery)) - collectSpanQueryFields(boost::dynamic_pointer_cast(spanQuery)->getMaskedQuery(), fieldNames); - else if (MiscUtils::typeOf(spanQuery)) - collectSpanQueryFields(boost::dynamic_pointer_cast(spanQuery)->getMatch(), fieldNames); - else if (MiscUtils::typeOf(spanQuery)) - { - Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - collectSpanQueryFields(*clause, fieldNames); +void WeightedSpanTermExtractor::collectSpanQueryFields(const SpanQueryPtr& spanQuery, HashSet fieldNames) { + if (MiscUtils::typeOf(spanQuery)) { + collectSpanQueryFields(boost::dynamic_pointer_cast(spanQuery)->getMaskedQuery(), fieldNames); + } else if (MiscUtils::typeOf(spanQuery)) { + collectSpanQueryFields(boost::dynamic_pointer_cast(spanQuery)->getMatch(), fieldNames); + } else if (MiscUtils::typeOf(spanQuery)) { + Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + collectSpanQueryFields(*clause, fieldNames); } - else if (MiscUtils::typeOf(spanQuery)) - collectSpanQueryFields(boost::dynamic_pointer_cast(spanQuery)->getInclude(), fieldNames); - else if (MiscUtils::typeOf(spanQuery)) - { - Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - collectSpanQueryFields(*clause, fieldNames); + } else if (MiscUtils::typeOf(spanQuery)) { + collectSpanQueryFields(boost::dynamic_pointer_cast(spanQuery)->getInclude(), fieldNames); + } else if (MiscUtils::typeOf(spanQuery)) { + Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + collectSpanQueryFields(*clause, fieldNames); } - else - fieldNames.add(spanQuery->getField()); + } else { + fieldNames.add(spanQuery->getField()); } +} - bool WeightedSpanTermExtractor::mustRewriteQuery(const SpanQueryPtr& spanQuery) - { - if (!expandMultiTermQuery) - return false; // Will throw UnsupportedOperationException in case of a SpanRegexQuery. - else if (MiscUtils::typeOf(spanQuery)) - return mustRewriteQuery(boost::dynamic_pointer_cast(spanQuery)->getMaskedQuery()); - else if (MiscUtils::typeOf(spanQuery)) - return mustRewriteQuery(boost::dynamic_pointer_cast(spanQuery)->getMatch()); - else if (MiscUtils::typeOf(spanQuery)) - { - Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - { - if (mustRewriteQuery(*clause)) - return true; +bool WeightedSpanTermExtractor::mustRewriteQuery(const SpanQueryPtr& spanQuery) { + if (!expandMultiTermQuery) { + return false; // Will throw UnsupportedOperationException in case of a SpanRegexQuery. + } else if (MiscUtils::typeOf(spanQuery)) { + return mustRewriteQuery(boost::dynamic_pointer_cast(spanQuery)->getMaskedQuery()); + } else if (MiscUtils::typeOf(spanQuery)) { + return mustRewriteQuery(boost::dynamic_pointer_cast(spanQuery)->getMatch()); + } else if (MiscUtils::typeOf(spanQuery)) { + Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + if (mustRewriteQuery(*clause)) { + return true; } - return false; - } - else if (MiscUtils::typeOf(spanQuery)) - { - SpanNotQueryPtr spanNotQuery(boost::dynamic_pointer_cast(spanQuery)); - return mustRewriteQuery(spanNotQuery->getInclude()) || mustRewriteQuery(spanNotQuery->getExclude()); } - else if (MiscUtils::typeOf(spanQuery)) - { - Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - { - if (mustRewriteQuery(*clause)) - return true; + return false; + } else if (MiscUtils::typeOf(spanQuery)) { + SpanNotQueryPtr spanNotQuery(boost::dynamic_pointer_cast(spanQuery)); + return mustRewriteQuery(spanNotQuery->getInclude()) || mustRewriteQuery(spanNotQuery->getExclude()); + } else if (MiscUtils::typeOf(spanQuery)) { + Collection clauses(boost::dynamic_pointer_cast(spanQuery)->getClauses()); + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + if (mustRewriteQuery(*clause)) { + return true; } - return false; } - else if (MiscUtils::typeOf(spanQuery)) - return false; - else - return true; + return false; + } else if (MiscUtils::typeOf(spanQuery)) { + return false; + } else { + return true; } +} - bool WeightedSpanTermExtractor::getExpandMultiTermQuery() - { - return expandMultiTermQuery; - } +bool WeightedSpanTermExtractor::getExpandMultiTermQuery() { + return expandMultiTermQuery; +} - void WeightedSpanTermExtractor::setExpandMultiTermQuery(bool expandMultiTermQuery) - { - this->expandMultiTermQuery = expandMultiTermQuery; - } +void WeightedSpanTermExtractor::setExpandMultiTermQuery(bool expandMultiTermQuery) { + this->expandMultiTermQuery = expandMultiTermQuery; +} - bool WeightedSpanTermExtractor::isCachedTokenStream() - { - return cachedTokenStream; - } +bool WeightedSpanTermExtractor::isCachedTokenStream() { + return cachedTokenStream; +} - TokenStreamPtr WeightedSpanTermExtractor::getTokenStream() - { - return tokenStream; - } +TokenStreamPtr WeightedSpanTermExtractor::getTokenStream() { + return tokenStream; +} - void WeightedSpanTermExtractor::setWrapIfNotCachingTokenFilter(bool wrap) - { - this->wrapToCaching = wrap; - } +void WeightedSpanTermExtractor::setWrapIfNotCachingTokenFilter(bool wrap) { + this->wrapToCaching = wrap; +} - PositionCheckingMap::~PositionCheckingMap() - { - } +PositionCheckingMap::~PositionCheckingMap() { +} - void PositionCheckingMap::put(const String& key, const WeightedSpanTermPtr& val) - { - MapStringWeightedSpanTerm::iterator prev = map.find(key); - if (prev == map.end()) - { - map.put(key, val); - return; - } - bool positionSensitive = prev->second->positionSensitive; - prev->second = val; - if (!positionSensitive) - prev->second->positionSensitive = false; +void PositionCheckingMap::put(const String& key, const WeightedSpanTermPtr& val) { + MapStringWeightedSpanTerm::iterator prev = map.find(key); + if (prev == map.end()) { + map.put(key, val); + return; } - - FakeReader::FakeReader() : FilterIndexReader(EMPTY_MEMORY_INDEX_READER()) - { + bool positionSensitive = prev->second->positionSensitive; + prev->second = val; + if (!positionSensitive) { + prev->second->positionSensitive = false; } +} - FakeReader::~FakeReader() - { - } +FakeReader::FakeReader() : FilterIndexReader(EMPTY_MEMORY_INDEX_READER()) { +} - IndexReaderPtr FakeReader::EMPTY_MEMORY_INDEX_READER() - { - static IndexReaderPtr _EMPTY_MEMORY_INDEX_READER; - if (!_EMPTY_MEMORY_INDEX_READER) - { - _EMPTY_MEMORY_INDEX_READER = newLucene()->createSearcher()->getIndexReader(); - CycleCheck::addStatic(_EMPTY_MEMORY_INDEX_READER); - } - return _EMPTY_MEMORY_INDEX_READER; +FakeReader::~FakeReader() { +} + +IndexReaderPtr FakeReader::EMPTY_MEMORY_INDEX_READER() { + static IndexReaderPtr _EMPTY_MEMORY_INDEX_READER; + if (!_EMPTY_MEMORY_INDEX_READER) { + _EMPTY_MEMORY_INDEX_READER = newLucene()->createSearcher()->getIndexReader(); + CycleCheck::addStatic(_EMPTY_MEMORY_INDEX_READER); } + return _EMPTY_MEMORY_INDEX_READER; +} - TermEnumPtr FakeReader::terms(const TermPtr& t) - { - // only set first fieldname - if (t && field.empty()) - field = t->field(); - return FilterIndexReader::terms(t); +TermEnumPtr FakeReader::terms(const TermPtr& t) { + // only set first fieldname + if (t && field.empty()) { + field = t->field(); } + return FilterIndexReader::terms(t); +} + } diff --git a/src/contrib/highlighter/WeightedTerm.cpp b/src/contrib/highlighter/WeightedTerm.cpp index c7c3fb14..2635ce71 100644 --- a/src/contrib/highlighter/WeightedTerm.cpp +++ b/src/contrib/highlighter/WeightedTerm.cpp @@ -7,35 +7,30 @@ #include "ContribInc.h" #include "WeightedTerm.h" -namespace Lucene -{ - WeightedTerm::WeightedTerm(double weight, const String& term) - { - this->weight = weight; - this->term = term; - } - - WeightedTerm::~WeightedTerm() - { - } - - String WeightedTerm::getTerm() - { - return term; - } - - double WeightedTerm::getWeight() - { - return weight; - } - - void WeightedTerm::setTerm(const String& term) - { - this->term = term; - } - - void WeightedTerm::setWeight(double weight) - { - this->weight = weight; - } +namespace Lucene { + +WeightedTerm::WeightedTerm(double weight, const String& term) { + this->weight = weight; + this->term = term; +} + +WeightedTerm::~WeightedTerm() { +} + +String WeightedTerm::getTerm() { + return term; +} + +double WeightedTerm::getWeight() { + return weight; +} + +void WeightedTerm::setTerm(const String& term) { + this->term = term; +} + +void WeightedTerm::setWeight(double weight) { + this->weight = weight; +} + } diff --git a/src/contrib/include/ArabicAnalyzer.h b/src/contrib/include/ArabicAnalyzer.h index 3d299750..f38c2ad2 100644 --- a/src/contrib/include/ArabicAnalyzer.h +++ b/src/contrib/include/ArabicAnalyzer.h @@ -10,78 +10,77 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for Arabic. +namespace Lucene { + +/// {@link Analyzer} for Arabic. +/// +/// This analyzer implements light-stemming as specified by: +/// Light Stemming for Arabic Information Retrieval +/// +/// http://www.mtholyoke.edu/~lballest/Pubs/arab_stem05.pdf +/// +/// The analysis package contains three primary components: +///
        +///
      • {@link ArabicNormalizationFilter}: Arabic orthographic normalization. +///
      • {@link ArabicStemFilter}: Arabic light stemming. +///
      • Arabic stop words file: a set of default Arabic stop words. +///
      +class LPPCONTRIBAPI ArabicAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + ArabicAnalyzer(LuceneVersion::Version matchVersion); + + /// Builds an analyzer with the given stop words. + ArabicAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + + virtual ~ArabicAnalyzer(); + + LUCENE_CLASS(ArabicAnalyzer); + +public: + /// Default Arabic stopwords in UTF-8 format. /// - /// This analyzer implements light-stemming as specified by: - /// Light Stemming for Arabic Information Retrieval + /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html + /// The stopword list is BSD-Licensed. + static const uint8_t DEFAULT_STOPWORD_FILE[]; + +protected: + /// Contains the stopwords used with the StopFilter. + HashSet stoptable; + + LuceneVersion::Version matchVersion; + +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); + + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// - /// http://www.mtholyoke.edu/~lballest/Pubs/arab_stem05.pdf + /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and + /// {@link ArabicStemFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. /// - /// The analysis package contains three primary components: - ///
        - ///
      • {@link ArabicNormalizationFilter}: Arabic orthographic normalization. - ///
      • {@link ArabicStemFilter}: Arabic light stemming. - ///
      • Arabic stop words file: a set of default Arabic stop words. - ///
      - class LPPCONTRIBAPI ArabicAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - ArabicAnalyzer(LuceneVersion::Version matchVersion); - - /// Builds an analyzer with the given stop words. - ArabicAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - - virtual ~ArabicAnalyzer(); - - LUCENE_CLASS(ArabicAnalyzer); - - public: - /// Default Arabic stopwords in UTF-8 format. - /// - /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html - /// The stopword list is BSD-Licensed. - static const uint8_t DEFAULT_STOPWORD_FILE[]; - - protected: - /// Contains the stopwords used with the StopFilter. - HashSet stoptable; - - LuceneVersion::Version matchVersion; - - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); - - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and - /// {@link ArabicStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and - /// {@link ArabicStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI ArabicAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~ArabicAnalyzerSavedStreams(); - - LUCENE_CLASS(ArabicAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; + /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link ArabicNormalizationFilter} and + /// {@link ArabicStemFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI ArabicAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~ArabicAnalyzerSavedStreams(); + + LUCENE_CLASS(ArabicAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/ArabicLetterTokenizer.h b/src/contrib/include/ArabicLetterTokenizer.h index b97831e3..79622877 100644 --- a/src/contrib/include/ArabicLetterTokenizer.h +++ b/src/contrib/include/ArabicLetterTokenizer.h @@ -10,33 +10,33 @@ #include "LuceneContrib.h" #include "LetterTokenizer.h" -namespace Lucene -{ - /// Tokenizer that breaks text into runs of letters and diacritics. - /// - /// The problem with the standard Letter tokenizer is that it fails on diacritics. - /// Handling similar to this is necessary for Indic Scripts, Hebrew, Thaana, etc. - /// - class LPPCONTRIBAPI ArabicLetterTokenizer : public LetterTokenizer - { - public: - /// Construct a new ArabicLetterTokenizer. - ArabicLetterTokenizer(const ReaderPtr& input); - - /// Construct a new ArabicLetterTokenizer using a given {@link AttributeSource}. - ArabicLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - - /// Construct a new ArabicLetterTokenizer using a given {@link AttributeFactory}. - ArabicLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~ArabicLetterTokenizer(); - - LUCENE_CLASS(ArabicLetterTokenizer); - - public: - /// Allows for Letter category or NonspacingMark category - virtual bool isTokenChar(wchar_t c); - }; +namespace Lucene { + +/// Tokenizer that breaks text into runs of letters and diacritics. +/// +/// The problem with the standard Letter tokenizer is that it fails on diacritics. +/// Handling similar to this is necessary for Indic Scripts, Hebrew, Thaana, etc. +/// +class LPPCONTRIBAPI ArabicLetterTokenizer : public LetterTokenizer { +public: + /// Construct a new ArabicLetterTokenizer. + ArabicLetterTokenizer(const ReaderPtr& input); + + /// Construct a new ArabicLetterTokenizer using a given {@link AttributeSource}. + ArabicLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + + /// Construct a new ArabicLetterTokenizer using a given {@link AttributeFactory}. + ArabicLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~ArabicLetterTokenizer(); + + LUCENE_CLASS(ArabicLetterTokenizer); + +public: + /// Allows for Letter category or NonspacingMark category + virtual bool isTokenChar(wchar_t c); +}; + } #endif diff --git a/src/contrib/include/ArabicNormalizationFilter.h b/src/contrib/include/ArabicNormalizationFilter.h index 4844a20c..47b4ed31 100644 --- a/src/contrib/include/ArabicNormalizationFilter.h +++ b/src/contrib/include/ArabicNormalizationFilter.h @@ -10,24 +10,24 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that applies {@link ArabicNormalizer} to normalize the orthography. - class LPPCONTRIBAPI ArabicNormalizationFilter : public TokenFilter - { - public: - ArabicNormalizationFilter(const TokenStreamPtr& input); - virtual ~ArabicNormalizationFilter(); - - LUCENE_CLASS(ArabicNormalizationFilter); - - protected: - ArabicNormalizerPtr normalizer; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - }; +namespace Lucene { + +/// A {@link TokenFilter} that applies {@link ArabicNormalizer} to normalize the orthography. +class LPPCONTRIBAPI ArabicNormalizationFilter : public TokenFilter { +public: + ArabicNormalizationFilter(const TokenStreamPtr& input); + virtual ~ArabicNormalizationFilter(); + + LUCENE_CLASS(ArabicNormalizationFilter); + +protected: + ArabicNormalizerPtr normalizer; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; + } #endif diff --git a/src/contrib/include/ArabicNormalizer.h b/src/contrib/include/ArabicNormalizer.h index 8061abad..318414a0 100644 --- a/src/contrib/include/ArabicNormalizer.h +++ b/src/contrib/include/ArabicNormalizer.h @@ -10,64 +10,64 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Normalizer for Arabic. - /// - /// Normalization is done in-place for efficiency, operating on a termbuffer. - /// - /// Normalization is defined as: - ///
        - ///
      • Normalization of hamza with alef seat to a bare alef. - ///
      • Normalization of teh marbuta to heh - ///
      • Normalization of dotless yeh (alef maksura) to yeh. - ///
      • Removal of Arabic diacritics (the harakat) - ///
      • Removal of tatweel (stretching character). - ///
      - class LPPCONTRIBAPI ArabicNormalizer : public LuceneObject - { - public: - virtual ~ArabicNormalizer(); +namespace Lucene { - LUCENE_CLASS(ArabicNormalizer); +/// Normalizer for Arabic. +/// +/// Normalization is done in-place for efficiency, operating on a termbuffer. +/// +/// Normalization is defined as: +///
        +///
      • Normalization of hamza with alef seat to a bare alef. +///
      • Normalization of teh marbuta to heh +///
      • Normalization of dotless yeh (alef maksura) to yeh. +///
      • Removal of Arabic diacritics (the harakat) +///
      • Removal of tatweel (stretching character). +///
      +class LPPCONTRIBAPI ArabicNormalizer : public LuceneObject { +public: + virtual ~ArabicNormalizer(); - public: - static const wchar_t ALEF; - static const wchar_t ALEF_MADDA; - static const wchar_t ALEF_HAMZA_ABOVE; - static const wchar_t ALEF_HAMZA_BELOW; + LUCENE_CLASS(ArabicNormalizer); - static const wchar_t YEH; - static const wchar_t DOTLESS_YEH; +public: + static const wchar_t ALEF; + static const wchar_t ALEF_MADDA; + static const wchar_t ALEF_HAMZA_ABOVE; + static const wchar_t ALEF_HAMZA_BELOW; - static const wchar_t TEH_MARBUTA; - static const wchar_t HEH; + static const wchar_t YEH; + static const wchar_t DOTLESS_YEH; - static const wchar_t TATWEEL; + static const wchar_t TEH_MARBUTA; + static const wchar_t HEH; - static const wchar_t FATHATAN; - static const wchar_t DAMMATAN; - static const wchar_t KASRATAN; - static const wchar_t FATHA; - static const wchar_t DAMMA; - static const wchar_t KASRA; - static const wchar_t SHADDA; - static const wchar_t SUKUN; + static const wchar_t TATWEEL; - public: - /// Normalize an input buffer of Arabic text - /// @param s input buffer - /// @param len length of input buffer - /// @return length of input buffer after normalization - int32_t normalize(wchar_t* s, int32_t len); + static const wchar_t FATHATAN; + static const wchar_t DAMMATAN; + static const wchar_t KASRATAN; + static const wchar_t FATHA; + static const wchar_t DAMMA; + static const wchar_t KASRA; + static const wchar_t SHADDA; + static const wchar_t SUKUN; + +public: + /// Normalize an input buffer of Arabic text + /// @param s input buffer + /// @param len length of input buffer + /// @return length of input buffer after normalization + int32_t normalize(wchar_t* s, int32_t len); + + /// Delete a character in-place + /// @param s Input Buffer + /// @param pos Position of character to delete + /// @param len length of input buffer + /// @return length of input buffer after deletion + int32_t deleteChar(wchar_t* s, int32_t pos, int32_t len); +}; - /// Delete a character in-place - /// @param s Input Buffer - /// @param pos Position of character to delete - /// @param len length of input buffer - /// @return length of input buffer after deletion - int32_t deleteChar(wchar_t* s, int32_t pos, int32_t len); - }; } #endif diff --git a/src/contrib/include/ArabicStemFilter.h b/src/contrib/include/ArabicStemFilter.h index de31dc9d..3cbd93cb 100644 --- a/src/contrib/include/ArabicStemFilter.h +++ b/src/contrib/include/ArabicStemFilter.h @@ -10,24 +10,24 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that applies {@link ArabicStemmer} to stem Arabic words. - class LPPCONTRIBAPI ArabicStemFilter : public TokenFilter - { - public: - ArabicStemFilter(const TokenStreamPtr& input); - virtual ~ArabicStemFilter(); - - LUCENE_CLASS(ArabicStemFilter); - - protected: - ArabicStemmerPtr stemmer; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - }; +namespace Lucene { + +/// A {@link TokenFilter} that applies {@link ArabicStemmer} to stem Arabic words. +class LPPCONTRIBAPI ArabicStemFilter : public TokenFilter { +public: + ArabicStemFilter(const TokenStreamPtr& input); + virtual ~ArabicStemFilter(); + + LUCENE_CLASS(ArabicStemFilter); + +protected: + ArabicStemmerPtr stemmer; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; + } #endif diff --git a/src/contrib/include/ArabicStemmer.h b/src/contrib/include/ArabicStemmer.h index 55a61bb5..51787f5f 100644 --- a/src/contrib/include/ArabicStemmer.h +++ b/src/contrib/include/ArabicStemmer.h @@ -10,89 +10,89 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Stemmer for Arabic. - /// - /// Stemming is done in-place for efficiency, operating on a termbuffer. - /// - /// Stemming is defined as: - ///
        - ///
      • Removal of attached definite article, conjunction, and prepositions. - ///
      • Stemming of common suffixes. - ///
      - class LPPCONTRIBAPI ArabicStemmer : public LuceneObject - { - public: - virtual ~ArabicStemmer(); - - LUCENE_CLASS(ArabicStemmer); - - public: - static const wchar_t ALEF; - static const wchar_t BEH; - static const wchar_t TEH_MARBUTA; - static const wchar_t TEH; - static const wchar_t FEH; - static const wchar_t KAF; - static const wchar_t LAM; - static const wchar_t NOON; - static const wchar_t HEH; - static const wchar_t WAW; - static const wchar_t YEH; - - public: - static const Collection prefixes(); - static const Collection suffixes(); - - /// Stem an input buffer of Arabic text. - /// @param s input buffer - /// @param len length of input buffer - /// @return length of input buffer after normalization - int32_t stem(wchar_t* s, int32_t len); - - /// Stem a prefix off an Arabic word. - /// @param s input buffer - /// @param len length of input buffer - /// @return new length of input buffer after stemming. - int32_t stemPrefix(wchar_t* s, int32_t len); - - /// Stem suffix(es) off an Arabic word. - /// @param s input buffer - /// @param len length of input buffer - /// @return new length of input buffer after stemming - int32_t stemSuffix(wchar_t* s, int32_t len); - - /// Returns true if the prefix matches and can be stemmed - /// @param s input buffer - /// @param len length of input buffer - /// @param prefix prefix to check - /// @return true if the prefix matches and can be stemmed - bool startsWith(wchar_t* s, int32_t len, const String& prefix); - - /// Returns true if the suffix matches and can be stemmed - /// @param s input buffer - /// @param len length of input buffer - /// @param suffix suffix to check - /// @return true if the suffix matches and can be stemmed - bool endsWith(wchar_t* s, int32_t len, const String& suffix); - - protected: - /// Delete n characters in-place - /// @param s Input Buffer - /// @param pos Position of character to delete - /// @param len Length of input buffer - /// @param chars number of characters to delete - /// @return length of input buffer after deletion - int32_t deleteChars(wchar_t* s, int32_t pos, int32_t len, int32_t chars); - - /// Delete a character in-place - /// @param s Input Buffer - /// @param pos Position of character to delete - /// @param len length of input buffer - /// @return length of input buffer after deletion - int32_t deleteChar(wchar_t* s, int32_t pos, int32_t len); - }; +namespace Lucene { + +/// Stemmer for Arabic. +/// +/// Stemming is done in-place for efficiency, operating on a termbuffer. +/// +/// Stemming is defined as: +///
        +///
      • Removal of attached definite article, conjunction, and prepositions. +///
      • Stemming of common suffixes. +///
      +class LPPCONTRIBAPI ArabicStemmer : public LuceneObject { +public: + virtual ~ArabicStemmer(); + + LUCENE_CLASS(ArabicStemmer); + +public: + static const wchar_t ALEF; + static const wchar_t BEH; + static const wchar_t TEH_MARBUTA; + static const wchar_t TEH; + static const wchar_t FEH; + static const wchar_t KAF; + static const wchar_t LAM; + static const wchar_t NOON; + static const wchar_t HEH; + static const wchar_t WAW; + static const wchar_t YEH; + +public: + static const Collection prefixes(); + static const Collection suffixes(); + + /// Stem an input buffer of Arabic text. + /// @param s input buffer + /// @param len length of input buffer + /// @return length of input buffer after normalization + int32_t stem(wchar_t* s, int32_t len); + + /// Stem a prefix off an Arabic word. + /// @param s input buffer + /// @param len length of input buffer + /// @return new length of input buffer after stemming. + int32_t stemPrefix(wchar_t* s, int32_t len); + + /// Stem suffix(es) off an Arabic word. + /// @param s input buffer + /// @param len length of input buffer + /// @return new length of input buffer after stemming + int32_t stemSuffix(wchar_t* s, int32_t len); + + /// Returns true if the prefix matches and can be stemmed + /// @param s input buffer + /// @param len length of input buffer + /// @param prefix prefix to check + /// @return true if the prefix matches and can be stemmed + bool startsWith(wchar_t* s, int32_t len, const String& prefix); + + /// Returns true if the suffix matches and can be stemmed + /// @param s input buffer + /// @param len length of input buffer + /// @param suffix suffix to check + /// @return true if the suffix matches and can be stemmed + bool endsWith(wchar_t* s, int32_t len, const String& suffix); + +protected: + /// Delete n characters in-place + /// @param s Input Buffer + /// @param pos Position of character to delete + /// @param len Length of input buffer + /// @param chars number of characters to delete + /// @return length of input buffer after deletion + int32_t deleteChars(wchar_t* s, int32_t pos, int32_t len, int32_t chars); + + /// Delete a character in-place + /// @param s Input Buffer + /// @param pos Position of character to delete + /// @param len length of input buffer + /// @return length of input buffer after deletion + int32_t deleteChar(wchar_t* s, int32_t pos, int32_t len); +}; + } #endif diff --git a/src/contrib/include/BrazilianAnalyzer.h b/src/contrib/include/BrazilianAnalyzer.h index 17addfb6..7fe72c47 100644 --- a/src/contrib/include/BrazilianAnalyzer.h +++ b/src/contrib/include/BrazilianAnalyzer.h @@ -10,74 +10,73 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for Brazilian Portuguese language. - /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of - /// exclusions (words that will not be stemmed, but indexed). - /// - /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. - class LPPCONTRIBAPI BrazilianAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - BrazilianAnalyzer(LuceneVersion::Version matchVersion); +namespace Lucene { + +/// {@link Analyzer} for Brazilian Portuguese language. +/// +/// Supports an external list of stopwords (words that will not be indexed at all) and an external list of +/// exclusions (words that will not be stemmed, but indexed). +/// +/// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. +class LPPCONTRIBAPI BrazilianAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + BrazilianAnalyzer(LuceneVersion::Version matchVersion); - /// Builds an analyzer with the given stop words. - BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + /// Builds an analyzer with the given stop words. + BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - /// Builds an analyzer with the given stop words and stemming exclusion words. - BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); + /// Builds an analyzer with the given stop words and stemming exclusion words. + BrazilianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - virtual ~BrazilianAnalyzer(); + virtual ~BrazilianAnalyzer(); - LUCENE_CLASS(BrazilianAnalyzer); + LUCENE_CLASS(BrazilianAnalyzer); - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stoptable; +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stoptable; - /// Contains words that should be indexed but not stemmed. - HashSet excltable; + /// Contains words that should be indexed but not stemmed. + HashSet excltable; - LuceneVersion::Version matchVersion; + LuceneVersion::Version matchVersion; - /// List of typical Brazilian Portuguese stopwords. - static const wchar_t* _BRAZILIAN_STOP_WORDS[]; + /// List of typical Brazilian Portuguese stopwords. + static const wchar_t* _BRAZILIAN_STOP_WORDS[]; - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); - void setStemExclusionTable(HashSet exclusions); + void setStemExclusionTable(HashSet exclusions); - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link BrazilianStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link BrazilianStemFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from an {@link BrazilianLetterTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link BrazilianNormalizationFilter} and + /// {@link BrazilianStemFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link BrazilianLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link BrazilianNormalizationFilter} and - /// {@link BrazilianStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +class LPPCONTRIBAPI BrazilianAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~BrazilianAnalyzerSavedStreams(); - class LPPCONTRIBAPI BrazilianAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~BrazilianAnalyzerSavedStreams(); + LUCENE_CLASS(BrazilianAnalyzerSavedStreams); - LUCENE_CLASS(BrazilianAnalyzerSavedStreams); +public: + TokenizerPtr source; + TokenStreamPtr result; +}; - public: - TokenizerPtr source; - TokenStreamPtr result; - }; } #endif diff --git a/src/contrib/include/BrazilianStemFilter.h b/src/contrib/include/BrazilianStemFilter.h index 24d6fe5d..05bf6297 100644 --- a/src/contrib/include/BrazilianStemFilter.h +++ b/src/contrib/include/BrazilianStemFilter.h @@ -10,29 +10,29 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that applies {@link BrazilianStemmer}. - class LPPCONTRIBAPI BrazilianStemFilter : public TokenFilter - { - public: - BrazilianStemFilter(const TokenStreamPtr& input); - BrazilianStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); +namespace Lucene { - virtual ~BrazilianStemFilter(); +/// A {@link TokenFilter} that applies {@link BrazilianStemmer}. +class LPPCONTRIBAPI BrazilianStemFilter : public TokenFilter { +public: + BrazilianStemFilter(const TokenStreamPtr& input); + BrazilianStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); - LUCENE_CLASS(BrazilianStemFilter); + virtual ~BrazilianStemFilter(); - protected: - /// {@link BrazilianStemmer} in use by this filter. - BrazilianStemmerPtr stemmer; + LUCENE_CLASS(BrazilianStemFilter); - HashSet exclusions; - TermAttributePtr termAtt; +protected: + /// {@link BrazilianStemmer} in use by this filter. + BrazilianStemmerPtr stemmer; + + HashSet exclusions; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; - public: - virtual bool incrementToken(); - }; } #endif diff --git a/src/contrib/include/BrazilianStemmer.h b/src/contrib/include/BrazilianStemmer.h index bcb2a1d7..11f59c9b 100644 --- a/src/contrib/include/BrazilianStemmer.h +++ b/src/contrib/include/BrazilianStemmer.h @@ -10,108 +10,108 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// A stemmer for Brazilian Portuguese words. - class LPPCONTRIBAPI BrazilianStemmer : public LuceneObject - { - public: - virtual ~BrazilianStemmer(); - - LUCENE_CLASS(BrazilianStemmer); - - protected: - String TERM; - String CT; - String R1; - String R2; - String RV; - - public: - /// Stems the given term to a unique discriminator. - /// - /// @param term The term that should be stemmed. - /// @return Discriminator for term. - String stem(const String& term); - - protected: - /// Checks a term if it can be processed correctly. - /// @return true if, and only if, the given term consists in letters. - bool isStemmable(const String& term); - - /// Checks a term if it can be processed indexed. - /// @return true if it can be indexed - bool isIndexable(const String& term); - - /// See if string is 'a','e','i','o','u' - /// @return true if is vowel - bool isVowel(wchar_t value); - - /// Gets R1. - /// R1 - is the region after the first non-vowel following a vowel, or is the null region at the end of the - /// word if there is no such non-vowel. - /// @return null or a string representing R1 - String getR1(const String& value); - - /// Gets RV. - /// RV - if the second letter is a consonant, RV is the region after the next following vowel, - /// - /// OR if the first two letters are vowels, RV is the region after the next consonant, - /// - /// AND otherwise (consonant-vowel case) RV is the region after the third letter. - /// - /// BUT RV is the end of the word if this positions cannot be found. - /// @return null or a string representing RV - String getRV(const String& value); - - /// 1) Turn to lowercase - /// 2) Remove accents - /// 3) ã -> a ; õ -> o - /// 4) ç -> c - /// @return null or a string transformed - String changeTerm(const String& value); - - /// Check if a string ends with a suffix. - /// @return true if the string ends with the specified suffix. - bool checkSuffix(const String& value, const String& suffix); - - /// Replace a string suffix by another - /// @return the replaced String - String replaceSuffix(const String& value, const String& toReplace, const String& changeTo); - - /// Remove a string suffix. - /// @return the String without the suffix; - String removeSuffix(const String& value, const String& toRemove); - - /// See if a suffix is preceded by a String. - /// @return true if the suffix is preceded. - bool suffixPreceded(const String& value, const String& suffix, const String& preceded); - - /// Creates CT (changed term) , substituting * 'ã' and 'õ' for 'a~' and 'o~'. - void createCT(const String& term); - - /// Standard suffix removal. - /// @return false if no ending was removed - bool step1(); - - /// Verb suffixes. - /// Search for the longest among the following suffixes in RV, and if found, delete. - /// @return false if no ending was removed - bool step2(); - - /// Delete suffix 'i' if in RV and preceded by 'c' - void step3(); - - /// Residual suffix - /// If the word ends with one of the suffixes (os a i o á í ó) in RV, delete it. - void step4(); - - /// If the word ends with one of (e é ê) in RV,delete it, and if preceded by 'gu' (or 'ci') with - /// the 'u' (or 'i') in RV, delete the 'u' (or 'i') - /// - /// Or if the word ends ç remove the cedilha. - void step5(); - }; +namespace Lucene { + +/// A stemmer for Brazilian Portuguese words. +class LPPCONTRIBAPI BrazilianStemmer : public LuceneObject { +public: + virtual ~BrazilianStemmer(); + + LUCENE_CLASS(BrazilianStemmer); + +protected: + String TERM; + String CT; + String R1; + String R2; + String RV; + +public: + /// Stems the given term to a unique discriminator. + /// + /// @param term The term that should be stemmed. + /// @return Discriminator for term. + String stem(const String& term); + +protected: + /// Checks a term if it can be processed correctly. + /// @return true if, and only if, the given term consists in letters. + bool isStemmable(const String& term); + + /// Checks a term if it can be processed indexed. + /// @return true if it can be indexed + bool isIndexable(const String& term); + + /// See if string is 'a','e','i','o','u' + /// @return true if is vowel + bool isVowel(wchar_t value); + + /// Gets R1. + /// R1 - is the region after the first non-vowel following a vowel, or is the null region at the end of the + /// word if there is no such non-vowel. + /// @return null or a string representing R1 + String getR1(const String& value); + + /// Gets RV. + /// RV - if the second letter is a consonant, RV is the region after the next following vowel, + /// + /// OR if the first two letters are vowels, RV is the region after the next consonant, + /// + /// AND otherwise (consonant-vowel case) RV is the region after the third letter. + /// + /// BUT RV is the end of the word if this positions cannot be found. + /// @return null or a string representing RV + String getRV(const String& value); + + /// 1) Turn to lowercase + /// 2) Remove accents + /// 3) ã -> a ; õ -> o + /// 4) ç -> c + /// @return null or a string transformed + String changeTerm(const String& value); + + /// Check if a string ends with a suffix. + /// @return true if the string ends with the specified suffix. + bool checkSuffix(const String& value, const String& suffix); + + /// Replace a string suffix by another + /// @return the replaced String + String replaceSuffix(const String& value, const String& toReplace, const String& changeTo); + + /// Remove a string suffix. + /// @return the String without the suffix; + String removeSuffix(const String& value, const String& toRemove); + + /// See if a suffix is preceded by a String. + /// @return true if the suffix is preceded. + bool suffixPreceded(const String& value, const String& suffix, const String& preceded); + + /// Creates CT (changed term) , substituting * 'ã' and 'õ' for 'a~' and 'o~'. + void createCT(const String& term); + + /// Standard suffix removal. + /// @return false if no ending was removed + bool step1(); + + /// Verb suffixes. + /// Search for the longest among the following suffixes in RV, and if found, delete. + /// @return false if no ending was removed + bool step2(); + + /// Delete suffix 'i' if in RV and preceded by 'c' + void step3(); + + /// Residual suffix + /// If the word ends with one of the suffixes (os a i o á í ó) in RV, delete it. + void step4(); + + /// If the word ends with one of (e é ê) in RV,delete it, and if preceded by 'gu' (or 'ci') with + /// the 'u' (or 'i') in RV, delete the 'u' (or 'i') + /// + /// Or if the word ends ç remove the cedilha. + void step5(); +}; + } #endif diff --git a/src/contrib/include/CJKAnalyzer.h b/src/contrib/include/CJKAnalyzer.h index 81e368f2..d420f567 100644 --- a/src/contrib/include/CJKAnalyzer.h +++ b/src/contrib/include/CJKAnalyzer.h @@ -10,58 +10,57 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// An {@link Analyzer} that tokenizes text with {@link CJKTokenizer} and filters with {@link StopFilter} - class LPPCONTRIBAPI CJKAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - CJKAnalyzer(LuceneVersion::Version matchVersion); - - /// Builds an analyzer with the given stop words. - CJKAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - - virtual ~CJKAnalyzer(); - - LUCENE_CLASS(CJKAnalyzer); - - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stoptable; - - LuceneVersion::Version matchVersion; - - /// List of typical English stopwords. - static const wchar_t* _STOP_WORDS[]; - - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); - - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI CJKAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~CJKAnalyzerSavedStreams(); - - LUCENE_CLASS(CJKAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; +namespace Lucene { + +/// An {@link Analyzer} that tokenizes text with {@link CJKTokenizer} and filters with {@link StopFilter} +class LPPCONTRIBAPI CJKAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + CJKAnalyzer(LuceneVersion::Version matchVersion); + + /// Builds an analyzer with the given stop words. + CJKAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + + virtual ~CJKAnalyzer(); + + LUCENE_CLASS(CJKAnalyzer); + +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stoptable; + + LuceneVersion::Version matchVersion; + + /// List of typical English stopwords. + static const wchar_t* _STOP_WORDS[]; + +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); + + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from {@link CJKTokenizer}, filtered with {@link StopFilter} + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI CJKAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~CJKAnalyzerSavedStreams(); + + LUCENE_CLASS(CJKAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/CJKTokenizer.h b/src/contrib/include/CJKTokenizer.h index e7103483..0209d441 100644 --- a/src/contrib/include/CJKTokenizer.h +++ b/src/contrib/include/CJKTokenizer.h @@ -9,93 +9,93 @@ #include "Tokenizer.h" -namespace Lucene -{ - /// CJKTokenizer is designed for Chinese, Japanese, and Korean languages. - /// - /// The tokens returned are every two adjacent characters with overlap match. - /// - /// Example: "lucene C1C2C3C4" will be segmented to: "lucene" "C1C2" "C2C3" "C3C4". - /// - /// Additionally, the following is applied to Latin text (such as English): - ///
        - ///
      • Text is converted to lowercase. - ///
      • Numeric digits, '+', '#', and '_' are tokenized as letters. - ///
      • Full-width forms are converted to half-width forms. - ///
      - /// For more info on Asian language (Chinese, Japanese, and Korean) text segmentation: - /// please search google - class LPPCONTRIBAPI CJKTokenizer : public Tokenizer - { - public: - CJKTokenizer(const ReaderPtr& input); - CJKTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - CJKTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~CJKTokenizer(); - - LUCENE_CLASS(CJKTokenizer); - - public: - /// Word token type - static const int32_t WORD_TYPE; - - /// Single byte token type - static const int32_t SINGLE_TOKEN_TYPE; - - /// Double byte token type - static const int32_t DOUBLE_TOKEN_TYPE; - - /// Names for token types - static const wchar_t* TOKEN_TYPE_NAMES[]; - - protected: - /// Max word length - static const int32_t MAX_WORD_LEN; - - static const int32_t IO_BUFFER_SIZE; - - enum UnicodeBlock { NONE, BASIC_LATIN, HALFWIDTH_AND_FULLWIDTH_FORMS }; - - protected: - /// word offset, used to imply which character(in) is parsed - int32_t offset; - - /// the index used only for ioBuffer - int32_t bufferIndex; - - /// data length - int32_t dataLen; - - /// character buffer, store the characters which are used to compose the returned Token - CharArray buffer; - - /// I/O buffer, used to store the content of the input (one of the members of Tokenizer) - CharArray ioBuffer; - - /// word type: single=>ASCII double=>non-ASCII word=>default - int32_t tokenType; - - /// tag: previous character is a cached double-byte character "C1C2C3C4" - /// ----(set the C1 isTokened) C1C2 "C2C3C4" ----(set the C2 isTokened) - /// C1C2 C2C3 "C3C4" ----(set the C3 isTokened) "C1C2 C2C3 C3C4" - bool preIsTokened; - - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; - TypeAttributePtr typeAtt; - - protected: - /// return unicode block for given character (see http://unicode.org/Public/UNIDATA/Blocks.txt) - UnicodeBlock unicodeBlock(wchar_t c); - - public: - virtual void initialize(); - virtual bool incrementToken(); - virtual void end(); - virtual void reset(); - virtual void reset(const ReaderPtr& input); - }; +namespace Lucene { + +/// CJKTokenizer is designed for Chinese, Japanese, and Korean languages. +/// +/// The tokens returned are every two adjacent characters with overlap match. +/// +/// Example: "lucene C1C2C3C4" will be segmented to: "lucene" "C1C2" "C2C3" "C3C4". +/// +/// Additionally, the following is applied to Latin text (such as English): +///
        +///
      • Text is converted to lowercase. +///
      • Numeric digits, '+', '#', and '_' are tokenized as letters. +///
      • Full-width forms are converted to half-width forms. +///
      +/// For more info on Asian language (Chinese, Japanese, and Korean) text segmentation: +/// please search google +class LPPCONTRIBAPI CJKTokenizer : public Tokenizer { +public: + CJKTokenizer(const ReaderPtr& input); + CJKTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + CJKTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~CJKTokenizer(); + + LUCENE_CLASS(CJKTokenizer); + +public: + /// Word token type + static const int32_t WORD_TYPE; + + /// Single byte token type + static const int32_t SINGLE_TOKEN_TYPE; + + /// Double byte token type + static const int32_t DOUBLE_TOKEN_TYPE; + + /// Names for token types + static const wchar_t* TOKEN_TYPE_NAMES[]; + +protected: + /// Max word length + static const int32_t MAX_WORD_LEN; + + static const int32_t IO_BUFFER_SIZE; + + enum UnicodeBlock { NONE, BASIC_LATIN, HALFWIDTH_AND_FULLWIDTH_FORMS }; + +protected: + /// word offset, used to imply which character(in) is parsed + int32_t offset; + + /// the index used only for ioBuffer + int32_t bufferIndex; + + /// data length + int32_t dataLen; + + /// character buffer, store the characters which are used to compose the returned Token + CharArray buffer; + + /// I/O buffer, used to store the content of the input (one of the members of Tokenizer) + CharArray ioBuffer; + + /// word type: single=>ASCII double=>non-ASCII word=>default + int32_t tokenType; + + /// tag: previous character is a cached double-byte character "C1C2C3C4" + /// ----(set the C1 isTokened) C1C2 "C2C3C4" ----(set the C2 isTokened) + /// C1C2 C2C3 "C3C4" ----(set the C3 isTokened) "C1C2 C2C3 C3C4" + bool preIsTokened; + + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + TypeAttributePtr typeAtt; + +protected: + /// return unicode block for given character (see http://unicode.org/Public/UNIDATA/Blocks.txt) + UnicodeBlock unicodeBlock(wchar_t c); + +public: + virtual void initialize(); + virtual bool incrementToken(); + virtual void end(); + virtual void reset(); + virtual void reset(const ReaderPtr& input); +}; + } #endif diff --git a/src/contrib/include/ChineseAnalyzer.h b/src/contrib/include/ChineseAnalyzer.h index 0de01e2b..118ffa61 100644 --- a/src/contrib/include/ChineseAnalyzer.h +++ b/src/contrib/include/ChineseAnalyzer.h @@ -10,40 +10,39 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// An {@link Analyzer} that tokenizes text with {@link ChineseTokenizer} and filters with {@link ChineseFilter} - class LPPCONTRIBAPI ChineseAnalyzer : public Analyzer - { - public: - virtual ~ChineseAnalyzer(); - - LUCENE_CLASS(ChineseAnalyzer); - - public: - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI ChineseAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~ChineseAnalyzerSavedStreams(); - - LUCENE_CLASS(ChineseAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; +namespace Lucene { + +/// An {@link Analyzer} that tokenizes text with {@link ChineseTokenizer} and filters with {@link ChineseFilter} +class LPPCONTRIBAPI ChineseAnalyzer : public Analyzer { +public: + virtual ~ChineseAnalyzer(); + + LUCENE_CLASS(ChineseAnalyzer); + +public: + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI ChineseAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~ChineseAnalyzerSavedStreams(); + + LUCENE_CLASS(ChineseAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/ChineseFilter.h b/src/contrib/include/ChineseFilter.h index fd9d2d27..1c15788d 100644 --- a/src/contrib/include/ChineseFilter.h +++ b/src/contrib/include/ChineseFilter.h @@ -10,33 +10,33 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} with a stop word table. - ///
        - ///
      • Numeric tokens are removed. - ///
      • English tokens must be larger than 1 character. - ///
      • One Chinese character as one Chinese word. - ///
      - class LPPCONTRIBAPI ChineseFilter : public TokenFilter - { - public: - ChineseFilter(const TokenStreamPtr& input); - virtual ~ChineseFilter(); - - LUCENE_CLASS(ChineseFilter); - - public: - /// Only English now, Chinese to be added later. - static const wchar_t* STOP_WORDS[]; - - protected: - HashSet stopTable; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - }; +namespace Lucene { + +/// A {@link TokenFilter} with a stop word table. +///
        +///
      • Numeric tokens are removed. +///
      • English tokens must be larger than 1 character. +///
      • One Chinese character as one Chinese word. +///
      +class LPPCONTRIBAPI ChineseFilter : public TokenFilter { +public: + ChineseFilter(const TokenStreamPtr& input); + virtual ~ChineseFilter(); + + LUCENE_CLASS(ChineseFilter); + +public: + /// Only English now, Chinese to be added later. + static const wchar_t* STOP_WORDS[]; + +protected: + HashSet stopTable; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; + } #endif diff --git a/src/contrib/include/ChineseTokenizer.h b/src/contrib/include/ChineseTokenizer.h index 3ff325d9..968ee105 100644 --- a/src/contrib/include/ChineseTokenizer.h +++ b/src/contrib/include/ChineseTokenizer.h @@ -9,73 +9,73 @@ #include "Tokenizer.h" -namespace Lucene -{ - /// Tokenize Chinese text as individual Chinese characters. - /// - /// The difference between ChineseTokenizer and ChineseTokenizer is that they have different - /// token parsing logic. - /// - /// For example, if the Chinese text "C1C2C3C4" is to be indexed: - ///
        - ///
      • The tokens returned from ChineseTokenizer are C1, C2, C3, C4. - ///
      • The tokens returned from the ChineseTokenizer are C1C2, C2C3, C3C4. - ///
      - /// - /// Therefore the index created by ChineseTokenizer is much larger. - /// - /// The problem is that when searching for C1, C1C2, C1C3, C4C2, C1C2C3 ... the - /// ChineseTokenizer works, but the ChineseTokenizer will not work. - class LPPCONTRIBAPI ChineseTokenizer : public Tokenizer - { - public: - ChineseTokenizer(const ReaderPtr& input); - ChineseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - ChineseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~ChineseTokenizer(); - - LUCENE_CLASS(ChineseTokenizer); - - protected: - /// Max word length - static const int32_t MAX_WORD_LEN; - - static const int32_t IO_BUFFER_SIZE; - - protected: - /// word offset, used to imply which character(in) is parsed - int32_t offset; - - /// the index used only for ioBuffer - int32_t bufferIndex; - - /// data length - int32_t dataLen; - - /// character buffer, store the characters which are used to compose the returned Token - CharArray buffer; - - /// I/O buffer, used to store the content of the input (one of the members of Tokenizer) - CharArray ioBuffer; - - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; - - int32_t length; - int32_t start; - - public: - virtual void initialize(); - virtual bool incrementToken(); - virtual void end(); - virtual void reset(); - virtual void reset(const ReaderPtr& input); - - protected: - void push(wchar_t c); - bool flush(); - }; +namespace Lucene { + +/// Tokenize Chinese text as individual Chinese characters. +/// +/// The difference between ChineseTokenizer and ChineseTokenizer is that they have different +/// token parsing logic. +/// +/// For example, if the Chinese text "C1C2C3C4" is to be indexed: +///
        +///
      • The tokens returned from ChineseTokenizer are C1, C2, C3, C4. +///
      • The tokens returned from the ChineseTokenizer are C1C2, C2C3, C3C4. +///
      +/// +/// Therefore the index created by ChineseTokenizer is much larger. +/// +/// The problem is that when searching for C1, C1C2, C1C3, C4C2, C1C2C3 ... the +/// ChineseTokenizer works, but the ChineseTokenizer will not work. +class LPPCONTRIBAPI ChineseTokenizer : public Tokenizer { +public: + ChineseTokenizer(const ReaderPtr& input); + ChineseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + ChineseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~ChineseTokenizer(); + + LUCENE_CLASS(ChineseTokenizer); + +protected: + /// Max word length + static const int32_t MAX_WORD_LEN; + + static const int32_t IO_BUFFER_SIZE; + +protected: + /// word offset, used to imply which character(in) is parsed + int32_t offset; + + /// the index used only for ioBuffer + int32_t bufferIndex; + + /// data length + int32_t dataLen; + + /// character buffer, store the characters which are used to compose the returned Token + CharArray buffer; + + /// I/O buffer, used to store the content of the input (one of the members of Tokenizer) + CharArray ioBuffer; + + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + + int32_t length; + int32_t start; + +public: + virtual void initialize(); + virtual bool incrementToken(); + virtual void end(); + virtual void reset(); + virtual void reset(const ReaderPtr& input); + +protected: + void push(wchar_t c); + bool flush(); +}; + } #endif diff --git a/src/contrib/include/CzechAnalyzer.h b/src/contrib/include/CzechAnalyzer.h index b29689ad..93c7d229 100644 --- a/src/contrib/include/CzechAnalyzer.h +++ b/src/contrib/include/CzechAnalyzer.h @@ -10,65 +10,64 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for Czech language. +namespace Lucene { + +/// {@link Analyzer} for Czech language. +/// +/// Supports an external list of stopwords (words that will not be indexed at all). +/// A default set of stopwords is used unless an alternative list is specified. +/// +/// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. +class LPPCONTRIBAPI CzechAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + CzechAnalyzer(LuceneVersion::Version matchVersion); + + /// Builds an analyzer with the given stop words. + CzechAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + + virtual ~CzechAnalyzer(); + + LUCENE_CLASS(CzechAnalyzer); + +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stoptable; + + LuceneVersion::Version matchVersion; + + /// Default Czech stopwords in UTF-8 format. + static const uint8_t _CZECH_STOP_WORDS[]; + +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); + + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// - /// Supports an external list of stopwords (words that will not be indexed at all). - /// A default set of stopwords is used unless an alternative list is specified. + /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, + /// {@link LowerCaseFilter}, and {@link StopFilter} + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. /// - /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. - class LPPCONTRIBAPI CzechAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - CzechAnalyzer(LuceneVersion::Version matchVersion); - - /// Builds an analyzer with the given stop words. - CzechAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - - virtual ~CzechAnalyzer(); - - LUCENE_CLASS(CzechAnalyzer); - - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stoptable; - - LuceneVersion::Version matchVersion; - - /// Default Czech stopwords in UTF-8 format. - static const uint8_t _CZECH_STOP_WORDS[]; - - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); - - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, - /// {@link LowerCaseFilter}, and {@link StopFilter} - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, - /// {@link LowerCaseFilter}, and {@link StopFilter} - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI CzechAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~CzechAnalyzerSavedStreams(); - - LUCENE_CLASS(CzechAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; + /// @return A {@link TokenStream} built from {@link StandardTokenizer}, filtered with {@link StandardFilter}, + /// {@link LowerCaseFilter}, and {@link StopFilter} + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI CzechAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~CzechAnalyzerSavedStreams(); + + LUCENE_CLASS(CzechAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/DefaultEncoder.h b/src/contrib/include/DefaultEncoder.h index 57082ae7..25b27328 100644 --- a/src/contrib/include/DefaultEncoder.h +++ b/src/contrib/include/DefaultEncoder.h @@ -9,18 +9,18 @@ #include "Encoder.h" -namespace Lucene -{ - /// Simple {@link Encoder} implementation that does not modify the output. - class LPPCONTRIBAPI DefaultEncoder : public Encoder, public LuceneObject - { - public: - virtual ~DefaultEncoder(); - LUCENE_CLASS(DefaultEncoder); +namespace Lucene { + +/// Simple {@link Encoder} implementation that does not modify the output. +class LPPCONTRIBAPI DefaultEncoder : public Encoder, public LuceneObject { +public: + virtual ~DefaultEncoder(); + LUCENE_CLASS(DefaultEncoder); + +public: + virtual String encodeText(const String& originalText); +}; - public: - virtual String encodeText(const String& originalText); - }; } #endif diff --git a/src/contrib/include/DutchAnalyzer.h b/src/contrib/include/DutchAnalyzer.h index 5b34ebe2..83cfc585 100644 --- a/src/contrib/include/DutchAnalyzer.h +++ b/src/contrib/include/DutchAnalyzer.h @@ -10,78 +10,77 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for Dutch language. - /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of - /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an - /// alternative list is specified, but the exclusion list is empty by default. - /// - /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. - class LPPCONTRIBAPI DutchAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - DutchAnalyzer(LuceneVersion::Version matchVersion); +namespace Lucene { + +/// {@link Analyzer} for Dutch language. +/// +/// Supports an external list of stopwords (words that will not be indexed at all) and an external list of +/// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an +/// alternative list is specified, but the exclusion list is empty by default. +/// +/// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. +class LPPCONTRIBAPI DutchAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + DutchAnalyzer(LuceneVersion::Version matchVersion); - /// Builds an analyzer with the given stop words. - DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + /// Builds an analyzer with the given stop words. + DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - /// Builds an analyzer with the given stop words and stemming exclusion words. - DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); + /// Builds an analyzer with the given stop words and stemming exclusion words. + DutchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - virtual ~DutchAnalyzer(); + virtual ~DutchAnalyzer(); - LUCENE_CLASS(DutchAnalyzer); + LUCENE_CLASS(DutchAnalyzer); - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stoptable; +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stoptable; - /// Contains words that should be indexed but not stemmed. - HashSet excltable; + /// Contains words that should be indexed but not stemmed. + HashSet excltable; - MapStringString stemdict; + MapStringString stemdict; - LuceneVersion::Version matchVersion; + LuceneVersion::Version matchVersion; - /// List of typical Dutch stopwords. - static const wchar_t* _DUTCH_STOP_WORDS[]; + /// List of typical Dutch stopwords. + static const wchar_t* _DUTCH_STOP_WORDS[]; - public: - virtual void initialize(); +public: + virtual void initialize(); - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); - void setStemExclusionTable(HashSet exclusions); + void setStemExclusionTable(HashSet exclusions); - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with - /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with + /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with + /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with - /// {@link StandardFilter}, {@link StopFilter} and {@link DutchStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +class LPPCONTRIBAPI DutchAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~DutchAnalyzerSavedStreams(); - class LPPCONTRIBAPI DutchAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~DutchAnalyzerSavedStreams(); + LUCENE_CLASS(DutchAnalyzerSavedStreams); - LUCENE_CLASS(DutchAnalyzerSavedStreams); +public: + TokenizerPtr source; + TokenStreamPtr result; +}; - public: - TokenizerPtr source; - TokenStreamPtr result; - }; } #endif diff --git a/src/contrib/include/DutchStemFilter.h b/src/contrib/include/DutchStemFilter.h index 340bd377..86ba03e4 100644 --- a/src/contrib/include/DutchStemFilter.h +++ b/src/contrib/include/DutchStemFilter.h @@ -10,53 +10,53 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that stems Dutch words. - /// - /// It supports a table of words that should not be stemmed at all. The stemmer used can - /// be changed at runtime after the filter object is created (as long as it is a - /// {@link DutchStemmer}). - /// - /// NOTE: This stemmer does not implement the Snowball algorithm correctly, specifically - /// doubled consonants. It is recommended that you consider using the "Dutch" stemmer in - /// the snowball package instead. This stemmer will likely be deprecated in a future release. - class LPPCONTRIBAPI DutchStemFilter : public TokenFilter - { - public: - DutchStemFilter(const TokenStreamPtr& input); - - /// Builds a DutchStemFilter that uses an exclusion table. - DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); - - /// Builds a DutchStemFilter that uses an exclusion table and dictionary of word stem - /// pairs, that overrule the algorithm. - DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable, MapStringString stemdictionary); - - virtual ~DutchStemFilter(); - - LUCENE_CLASS(DutchStemFilter); - - protected: - /// {@link DutchStemmer} in use by this filter. - DutchStemmerPtr stemmer; - - HashSet exclusions; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - - /// Set a alternative/custom {@link DutchStemmer} for this filter. - void setStemmer(const DutchStemmerPtr& stemmer); - - /// Set an alternative exclusion list for this filter. - void setExclusionSet(HashSet exclusiontable); - - /// Set dictionary for stemming, this dictionary overrules the algorithm, so you can - /// correct for a particular unwanted word-stem pair. - void setStemDictionary(MapStringString dict); - }; +namespace Lucene { + +/// A {@link TokenFilter} that stems Dutch words. +/// +/// It supports a table of words that should not be stemmed at all. The stemmer used can +/// be changed at runtime after the filter object is created (as long as it is a +/// {@link DutchStemmer}). +/// +/// NOTE: This stemmer does not implement the Snowball algorithm correctly, specifically +/// doubled consonants. It is recommended that you consider using the "Dutch" stemmer in +/// the snowball package instead. This stemmer will likely be deprecated in a future release. +class LPPCONTRIBAPI DutchStemFilter : public TokenFilter { +public: + DutchStemFilter(const TokenStreamPtr& input); + + /// Builds a DutchStemFilter that uses an exclusion table. + DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); + + /// Builds a DutchStemFilter that uses an exclusion table and dictionary of word stem + /// pairs, that overrule the algorithm. + DutchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable, MapStringString stemdictionary); + + virtual ~DutchStemFilter(); + + LUCENE_CLASS(DutchStemFilter); + +protected: + /// {@link DutchStemmer} in use by this filter. + DutchStemmerPtr stemmer; + + HashSet exclusions; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); + + /// Set a alternative/custom {@link DutchStemmer} for this filter. + void setStemmer(const DutchStemmerPtr& stemmer); + + /// Set an alternative exclusion list for this filter. + void setExclusionSet(HashSet exclusiontable); + + /// Set dictionary for stemming, this dictionary overrules the algorithm, so you can + /// correct for a particular unwanted word-stem pair. + void setStemDictionary(MapStringString dict); +}; + } #endif diff --git a/src/contrib/include/DutchStemmer.h b/src/contrib/include/DutchStemmer.h index 1adf969d..1b400069 100644 --- a/src/contrib/include/DutchStemmer.h +++ b/src/contrib/include/DutchStemmer.h @@ -10,84 +10,84 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// A stemmer for Dutch words. - /// - /// The algorithm is an implementation of the - /// dutch stemming - /// algorithm in Martin Porter's snowball project. - class LPPCONTRIBAPI DutchStemmer : public LuceneObject - { - public: - DutchStemmer(); - virtual ~DutchStemmer(); +namespace Lucene { + +/// A stemmer for Dutch words. +/// +/// The algorithm is an implementation of the +/// dutch stemming +/// algorithm in Martin Porter's snowball project. +class LPPCONTRIBAPI DutchStemmer : public LuceneObject { +public: + DutchStemmer(); + virtual ~DutchStemmer(); - LUCENE_CLASS(DutchStemmer); + LUCENE_CLASS(DutchStemmer); - protected: - /// Buffer for the terms while stemming them. - String buffer; +protected: + /// Buffer for the terms while stemming them. + String buffer; - bool removedE; - MapStringString stemDict; + bool removedE; + MapStringString stemDict; - int32_t R1; - int32_t R2; + int32_t R1; + int32_t R2; + +public: + /// Stems the given term to a unique discriminator. + /// + /// @param term The term that should be stemmed. + /// @return Discriminator for term. + String stem(const String& term); - public: - /// Stems the given term to a unique discriminator. - /// - /// @param term The term that should be stemmed. - /// @return Discriminator for term. - String stem(const String& term); + void setStemDictionary(MapStringString dict); - void setStemDictionary(MapStringString dict); +protected: + bool enEnding(); - protected: - bool enEnding(); + void step1(); - void step1(); + /// Delete suffix e if in R1 and preceded by a non-vowel, and then undouble the ending. + void step2(); - /// Delete suffix e if in R1 and preceded by a non-vowel, and then undouble the ending. - void step2(); + /// Delete "heid" + void step3a(); - /// Delete "heid" - void step3a(); + /// A d-suffix, or derivational suffix, enables a new word, often with a different grammatical + /// category, or with a different sense, to be built from another word. Whether a d-suffix can + /// be attached is discovered not from the rules of grammar, but by referring to a dictionary. + /// So in English, ness can be added to certain adjectives to form corresponding nouns + /// (littleness, kindness, foolishness ...) but not to all adjectives (not for example, to big, + /// cruel, wise ...) d-suffixes can be used to change meaning, often in rather exotic ways. + /// Remove "ing", "end", "ig", "lijk", "baar" and "bar" + void step3b(); - /// A d-suffix, or derivational suffix, enables a new word, often with a different grammatical - /// category, or with a different sense, to be built from another word. Whether a d-suffix can - /// be attached is discovered not from the rules of grammar, but by referring to a dictionary. - /// So in English, ness can be added to certain adjectives to form corresponding nouns - /// (littleness, kindness, foolishness ...) but not to all adjectives (not for example, to big, - /// cruel, wise ...) d-suffixes can be used to change meaning, often in rather exotic ways. - /// Remove "ing", "end", "ig", "lijk", "baar" and "bar" - void step3b(); + /// Undouble vowel. If the words ends CVD, where C is a non-vowel, D is a non-vowel other than + /// I, and V is double a, e, o or u, remove one of the vowels from V (for example, maan -> man, + /// brood -> brod). + void step4(); - /// Undouble vowel. If the words ends CVD, where C is a non-vowel, D is a non-vowel other than - /// I, and V is double a, e, o or u, remove one of the vowels from V (for example, maan -> man, - /// brood -> brod). - void step4(); + /// Checks if a term could be stemmed. + bool isStemmable(); - /// Checks if a term could be stemmed. - bool isStemmable(); + /// Substitute ä, ë, ï, ö, ü, á , é, í, ó, ú + void substitute(); - /// Substitute ä, ë, ï, ö, ü, á , é, í, ó, ú - void substitute(); + bool isValidSEnding(int32_t index); + bool isValidEnEnding(int32_t index); - bool isValidSEnding(int32_t index); - bool isValidEnEnding(int32_t index); + void unDouble(); + void unDouble(int32_t endIndex); - void unDouble(); - void unDouble(int32_t endIndex); + int32_t getRIndex(int32_t start); - int32_t getRIndex(int32_t start); + void storeYandI(); + void reStoreYandI(); - void storeYandI(); - void reStoreYandI(); + bool isVowel(wchar_t c); +}; - bool isVowel(wchar_t c); - }; } #endif diff --git a/src/contrib/include/ElisionFilter.h b/src/contrib/include/ElisionFilter.h index 14cd5114..32ff4c07 100644 --- a/src/contrib/include/ElisionFilter.h +++ b/src/contrib/include/ElisionFilter.h @@ -10,37 +10,37 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// Removes elisions from a {@link TokenStream}. For example, "l'avion" (the plane) will be - /// tokenized as "avion" (plane). - /// - /// Note that {@link StandardTokenizer} sees " ' " as a space, and cuts it out. - /// @see Elision in Wikipedia - class LPPCONTRIBAPI ElisionFilter : public TokenFilter - { - public: - /// Constructs an elision filter with standard stop words. - ElisionFilter(const TokenStreamPtr& input); +namespace Lucene { - /// Constructs an elision filter with a Set of stop words - ElisionFilter(const TokenStreamPtr& input, HashSet articles); +/// Removes elisions from a {@link TokenStream}. For example, "l'avion" (the plane) will be +/// tokenized as "avion" (plane). +/// +/// Note that {@link StandardTokenizer} sees " ' " as a space, and cuts it out. +/// @see Elision in Wikipedia +class LPPCONTRIBAPI ElisionFilter : public TokenFilter { +public: + /// Constructs an elision filter with standard stop words. + ElisionFilter(const TokenStreamPtr& input); - virtual ~ElisionFilter(); + /// Constructs an elision filter with a Set of stop words + ElisionFilter(const TokenStreamPtr& input, HashSet articles); - LUCENE_CLASS(ElisionFilter); + virtual ~ElisionFilter(); - protected: - static const wchar_t apostrophes[]; + LUCENE_CLASS(ElisionFilter); - CharArraySetPtr articles; - TermAttributePtr termAtt; +protected: + static const wchar_t apostrophes[]; - public: - void setArticles(HashSet articles); + CharArraySetPtr articles; + TermAttributePtr termAtt; + +public: + void setArticles(HashSet articles); + + virtual bool incrementToken(); +}; - virtual bool incrementToken(); - }; } #endif diff --git a/src/contrib/include/Encoder.h b/src/contrib/include/Encoder.h index 0883f81d..d2ecdea8 100644 --- a/src/contrib/include/Encoder.h +++ b/src/contrib/include/Encoder.h @@ -10,18 +10,18 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Encodes original text. The Encoder works with the {@link Formatter} to generate output. - class LPPCONTRIBAPI Encoder - { - public: - virtual ~Encoder(); - LUCENE_INTERFACE(Encoder); +namespace Lucene { + +/// Encodes original text. The Encoder works with the {@link Formatter} to generate output. +class LPPCONTRIBAPI Encoder { +public: + virtual ~Encoder(); + LUCENE_INTERFACE(Encoder); + +public: + virtual String encodeText(const String& originalText); +}; - public: - virtual String encodeText(const String& originalText); - }; } #endif diff --git a/src/contrib/include/Formatter.h b/src/contrib/include/Formatter.h index 287cc9d7..b090ff9a 100644 --- a/src/contrib/include/Formatter.h +++ b/src/contrib/include/Formatter.h @@ -10,21 +10,21 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Processes terms found in the original text, typically by applying some form of mark-up to highlight - /// terms in HTML search results pages. - class LPPCONTRIBAPI Formatter - { - public: - virtual ~Formatter(); - LUCENE_INTERFACE(Formatter); +namespace Lucene { + +/// Processes terms found in the original text, typically by applying some form of mark-up to highlight +/// terms in HTML search results pages. +class LPPCONTRIBAPI Formatter { +public: + virtual ~Formatter(); + LUCENE_INTERFACE(Formatter); + +public: + /// @param originalText The section of text being considered for markup + /// @param tokenGroup contains one or several overlapping Tokens along with their scores and positions. + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); +}; - public: - /// @param originalText The section of text being considered for markup - /// @param tokenGroup contains one or several overlapping Tokens along with their scores and positions. - virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); - }; } #endif diff --git a/src/contrib/include/Fragmenter.h b/src/contrib/include/Fragmenter.h index 0d1601fa..897c4bbe 100644 --- a/src/contrib/include/Fragmenter.h +++ b/src/contrib/include/Fragmenter.h @@ -10,29 +10,29 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Implements the policy for breaking text into multiple fragments for consideration by the - /// {@link Highlighter} class. A sophisticated implementation may do this on the basis of - /// detecting end of sentences in the text. - class LPPCONTRIBAPI Fragmenter - { - public: - virtual ~Fragmenter(); - LUCENE_INTERFACE(Fragmenter); - - public: - /// Initializes the Fragmenter. You can grab references to the Attributes you are - /// interested in from tokenStream and then access the values in {@link #isNewFragment()}. - /// @param originalText the original source text. - /// @param tokenStream the {@link TokenStream} to be fragmented. - virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); - - /// Test to see if this token from the stream should be held in a new TextFragment. - /// Every time this is called, the TokenStream passed to start(String, TokenStream) - /// will have been incremented. - virtual bool isNewFragment(); - }; +namespace Lucene { + +/// Implements the policy for breaking text into multiple fragments for consideration by the +/// {@link Highlighter} class. A sophisticated implementation may do this on the basis of +/// detecting end of sentences in the text. +class LPPCONTRIBAPI Fragmenter { +public: + virtual ~Fragmenter(); + LUCENE_INTERFACE(Fragmenter); + +public: + /// Initializes the Fragmenter. You can grab references to the Attributes you are + /// interested in from tokenStream and then access the values in {@link #isNewFragment()}. + /// @param originalText the original source text. + /// @param tokenStream the {@link TokenStream} to be fragmented. + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); + + /// Test to see if this token from the stream should be held in a new TextFragment. + /// Every time this is called, the TokenStream passed to start(String, TokenStream) + /// will have been incremented. + virtual bool isNewFragment(); +}; + } #endif diff --git a/src/contrib/include/FrenchAnalyzer.h b/src/contrib/include/FrenchAnalyzer.h index 7fd49cb9..efabd495 100644 --- a/src/contrib/include/FrenchAnalyzer.h +++ b/src/contrib/include/FrenchAnalyzer.h @@ -10,74 +10,73 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for French language. - /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of - /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an - /// alternative list is specified, but the exclusion list is empty by default. - /// - /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. - class LPPCONTRIBAPI FrenchAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - FrenchAnalyzer(LuceneVersion::Version matchVersion); +namespace Lucene { + +/// {@link Analyzer} for French language. +/// +/// Supports an external list of stopwords (words that will not be indexed at all) and an external list of +/// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an +/// alternative list is specified, but the exclusion list is empty by default. +/// +/// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. +class LPPCONTRIBAPI FrenchAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + FrenchAnalyzer(LuceneVersion::Version matchVersion); - /// Builds an analyzer with the given stop words. - FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + /// Builds an analyzer with the given stop words. + FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - /// Builds an analyzer with the given stop words and stemming exclusion words. - FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); + /// Builds an analyzer with the given stop words and stemming exclusion words. + FrenchAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - virtual ~FrenchAnalyzer(); + virtual ~FrenchAnalyzer(); - LUCENE_CLASS(FrenchAnalyzer); + LUCENE_CLASS(FrenchAnalyzer); - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stoptable; +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stoptable; - /// Contains words that should be indexed but not stemmed. - HashSet excltable; + /// Contains words that should be indexed but not stemmed. + HashSet excltable; - LuceneVersion::Version matchVersion; + LuceneVersion::Version matchVersion; - /// List of typical French stopwords. - static const wchar_t* _FRENCH_STOP_WORDS[]; + /// List of typical French stopwords. + static const wchar_t* _FRENCH_STOP_WORDS[]; - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); - void setStemExclusionTable(HashSet exclusions); + void setStemExclusionTable(HashSet exclusions); - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with - /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter}, and {@link LowerCaseFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with + /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter}, and {@link LowerCaseFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from an {@link StandardTokenizer} filtered with + /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter} and {@link LowerCaseFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link StandardTokenizer} filtered with - /// {@link StandardFilter}, {@link StopFilter}, {@link FrenchStemFilter} and {@link LowerCaseFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +class LPPCONTRIBAPI FrenchAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~FrenchAnalyzerSavedStreams(); - class LPPCONTRIBAPI FrenchAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~FrenchAnalyzerSavedStreams(); + LUCENE_CLASS(FrenchAnalyzerSavedStreams); - LUCENE_CLASS(FrenchAnalyzerSavedStreams); +public: + TokenizerPtr source; + TokenStreamPtr result; +}; - public: - TokenizerPtr source; - TokenStreamPtr result; - }; } #endif diff --git a/src/contrib/include/FrenchStemFilter.h b/src/contrib/include/FrenchStemFilter.h index e3a4b1a2..40413d54 100644 --- a/src/contrib/include/FrenchStemFilter.h +++ b/src/contrib/include/FrenchStemFilter.h @@ -10,45 +10,45 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that stems French words. - /// - /// It supports a table of words that should not be stemmed at all. The stemmer used can - /// be changed at runtime after the filter object is created (as long as it is a - /// {@link FrenchStemmer}). - /// - /// NOTE: This stemmer does not implement the Snowball algorithm correctly, especially - /// involving case problems. It is recommended that you consider using the "French" stemmer - /// in the snowball package instead. This stemmer will likely be deprecated in a future release. - class LPPCONTRIBAPI FrenchStemFilter : public TokenFilter - { - public: - FrenchStemFilter(const TokenStreamPtr& input); - - /// Builds a FrenchStemFilter that uses an exclusion table. - FrenchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); - - virtual ~FrenchStemFilter(); - - LUCENE_CLASS(FrenchStemFilter); - - protected: - /// {@link FrenchStemmer} in use by this filter. - FrenchStemmerPtr stemmer; - - HashSet exclusions; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - - /// Set a alternative/custom {@link FrenchStemmer} for this filter. - void setStemmer(const FrenchStemmerPtr& stemmer); - - /// Set an alternative exclusion list for this filter. - void setExclusionSet(HashSet exclusiontable); - }; +namespace Lucene { + +/// A {@link TokenFilter} that stems French words. +/// +/// It supports a table of words that should not be stemmed at all. The stemmer used can +/// be changed at runtime after the filter object is created (as long as it is a +/// {@link FrenchStemmer}). +/// +/// NOTE: This stemmer does not implement the Snowball algorithm correctly, especially +/// involving case problems. It is recommended that you consider using the "French" stemmer +/// in the snowball package instead. This stemmer will likely be deprecated in a future release. +class LPPCONTRIBAPI FrenchStemFilter : public TokenFilter { +public: + FrenchStemFilter(const TokenStreamPtr& input); + + /// Builds a FrenchStemFilter that uses an exclusion table. + FrenchStemFilter(const TokenStreamPtr& input, HashSet exclusiontable); + + virtual ~FrenchStemFilter(); + + LUCENE_CLASS(FrenchStemFilter); + +protected: + /// {@link FrenchStemmer} in use by this filter. + FrenchStemmerPtr stemmer; + + HashSet exclusions; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); + + /// Set a alternative/custom {@link FrenchStemmer} for this filter. + void setStemmer(const FrenchStemmerPtr& stemmer); + + /// Set an alternative exclusion list for this filter. + void setExclusionSet(HashSet exclusiontable); +}; + } #endif diff --git a/src/contrib/include/FrenchStemmer.h b/src/contrib/include/FrenchStemmer.h index 4a2dc3be..b17b2dcd 100644 --- a/src/contrib/include/FrenchStemmer.h +++ b/src/contrib/include/FrenchStemmer.h @@ -10,170 +10,170 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// A stemmer for French words. +namespace Lucene { + +/// A stemmer for French words. +/// +/// The algorithm is based on the work of Dr Martin Porter on his snowball project refer to +/// http://snowball.sourceforge.net/french/stemmer.html (French stemming algorithm) for details. +class LPPCONTRIBAPI FrenchStemmer : public LuceneObject { +public: + FrenchStemmer(); + virtual ~FrenchStemmer(); + + LUCENE_CLASS(FrenchStemmer); + +protected: + /// Buffer for the terms while stemming them. + String stringBuffer; + + /// A temporary buffer, used to reconstruct R2. + String tempBuffer; + + /// Region R0 is equal to the whole buffer. + String R0; + + /// Region RV + /// + /// "If the word begins with two vowels, RV is the region after the third letter, otherwise + /// the region after the first vowel not at the beginning of the word, or the end of the + /// word if these positions cannot be found." + String RV; + + /// Region R1 /// - /// The algorithm is based on the work of Dr Martin Porter on his snowball project refer to - /// http://snowball.sourceforge.net/french/stemmer.html (French stemming algorithm) for details. - class LPPCONTRIBAPI FrenchStemmer : public LuceneObject - { - public: - FrenchStemmer(); - virtual ~FrenchStemmer(); - - LUCENE_CLASS(FrenchStemmer); - - protected: - /// Buffer for the terms while stemming them. - String stringBuffer; - - /// A temporary buffer, used to reconstruct R2. - String tempBuffer; - - /// Region R0 is equal to the whole buffer. - String R0; - - /// Region RV - /// - /// "If the word begins with two vowels, RV is the region after the third letter, otherwise - /// the region after the first vowel not at the beginning of the word, or the end of the - /// word if these positions cannot be found." - String RV; - - /// Region R1 - /// - /// "R1 is the region after the first non-vowel following a vowel or is the null region at - /// the end of the word if there is no such non-vowel" - String R1; - - /// Region R2 - /// - /// "R2 is the region after the first non-vowel in R1 following a vowel or is the null region - /// at the end of the word if there is no such non-vowel" - String R2; - - /// Set to true if we need to perform step 2 - bool suite; - - /// Set to true if the buffer was modified - bool modified; - - public: - /// Stems the given term to a unique discriminator. - /// - /// @param term The term that should be stemmed. - /// @return Discriminator for term. - String stem(const String& term); - - protected: - /// Sets the search region Strings it needs to be done each time the buffer was modified. - void setStrings(); - - /// First step of the Porter Algorithm. - /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. - void step1(); - - /// Second step (A) of the Porter Algorithm. - /// Will be performed if nothing changed from the first step or changed were done in the amment, - /// emment, ments or ment suffixes. - /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. - /// @return true if something changed in the buffer - bool step2a(); - - /// Second step (B) of the Porter Algorithm. - /// Will be performed if step 2 A was performed unsuccessfully. - /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. - void step2b(); - - /// Third step of the Porter Algorithm. - /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. - void step3(); - - /// Fourth step of the Porter Algorithm. - /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. - void step4(); - - /// Fifth step of the Porter Algorithm. - /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. - void step5(); - - /// Sixth step of the Porter Algorithm. - /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. - void step6(); - - /// Delete a suffix searched in zone "source" if zone "from" contains prefix + search string. - /// @param source String - the primary source zone for search. - /// @param search String[] - the strings to search for suppression. - /// @param from String - the secondary source zone for search. - /// @param prefix String - the prefix to add to the search string to test. - /// @return true if modified - bool deleteFromIfPrecededIn(const String& source, Collection search, const String& from, const String& prefix); - - /// Delete a suffix searched in zone "source" if the preceding letter is (or isn't) a vowel. - /// @param source String - the primary source zone for search. - /// @param search String[] - the strings to search for suppression. - /// @param vowel boolean - true if we need a vowel before the search string. - /// @param from String - the secondary source zone for search (where vowel could be). - /// @return true if modified - bool deleteFromIfTestVowelBeforeIn(const String& source, Collection search, bool vowel, const String& from); - - /// Delete a suffix searched in zone "source" if preceded by the prefix. - /// @param source String - the primary source zone for search. - /// @param search String[] - the strings to search for suppression. - /// @param prefix String - the prefix to add to the search string to test. - /// @param without boolean - true if it will be deleted even without prefix found. - void deleteButSuffixFrom(const String& source, Collection search, const String& prefix, bool without); - - /// Delete a suffix searched in zone "source" if preceded by prefix or replace it with the - /// replace string if preceded by the prefix in the zone "from" or delete the suffix if specified. - /// @param source String - the primary source zone for search. - /// @param search String[] - the strings to search for suppression. - /// @param prefix String - the prefix to add to the search string to test. - /// @param without boolean - true if it will be deleted even without prefix found. - void deleteButSuffixFromElseReplace(const String& source, Collection search, const String& prefix, bool without, const String& from, const String& replace); - - /// Replace a search string with another within the source zone. - /// @param source String - the source zone for search. - /// @param search String[] - the strings to search for replacement. - /// @param replace String - the replacement string. - bool replaceFrom(const String& source, Collection search, const String& replace); - - /// Delete a search string within the source zone. - /// @param source the source zone for search. - /// @param suffix the strings to search for suppression. - void deleteFrom(const String& source, Collection suffix); - - /// Test if a char is a French vowel, including accentuated ones. - /// @param ch the char to test. - /// @return true if the char is a vowel - bool isVowel(wchar_t ch); - - /// Retrieve the "R zone" (1 or 2 depending on the buffer) and return the corresponding string. - /// "R is the region after the first non-vowel following a vowel or is the null region at the - /// end of the word if there is no such non-vowel". - /// @param buffer the in buffer. - /// @return the resulting string. - String retrieveR(const String& buffer); - - /// Retrieve the "RV zone" from a buffer an return the corresponding string. - /// "If the word begins with two vowels, RV is the region after the third letter, otherwise the - /// region after the first vowel not at the beginning of the word, or the end of the word if - /// these positions cannot be found." - /// @param buffer the in buffer - /// @return the resulting string - String retrieveRV(const String& buffer); - - /// Turns u and i preceded AND followed by a vowel to UpperCase<. - /// Turns y preceded OR followed by a vowel to UpperCase. - /// Turns u preceded by q to UpperCase. - /// @param buffer the buffer to treat - void treatVowels(String& buffer); - - /// Checks a term if it can be processed correctly. - /// @return boolean - true if, and only if, the given term consists in letters. - bool isStemmable(const String& term); - }; + /// "R1 is the region after the first non-vowel following a vowel or is the null region at + /// the end of the word if there is no such non-vowel" + String R1; + + /// Region R2 + /// + /// "R2 is the region after the first non-vowel in R1 following a vowel or is the null region + /// at the end of the word if there is no such non-vowel" + String R2; + + /// Set to true if we need to perform step 2 + bool suite; + + /// Set to true if the buffer was modified + bool modified; + +public: + /// Stems the given term to a unique discriminator. + /// + /// @param term The term that should be stemmed. + /// @return Discriminator for term. + String stem(const String& term); + +protected: + /// Sets the search region Strings it needs to be done each time the buffer was modified. + void setStrings(); + + /// First step of the Porter Algorithm. + /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. + void step1(); + + /// Second step (A) of the Porter Algorithm. + /// Will be performed if nothing changed from the first step or changed were done in the amment, + /// emment, ments or ment suffixes. + /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. + /// @return true if something changed in the buffer + bool step2a(); + + /// Second step (B) of the Porter Algorithm. + /// Will be performed if step 2 A was performed unsuccessfully. + /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. + void step2b(); + + /// Third step of the Porter Algorithm. + /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. + void step3(); + + /// Fourth step of the Porter Algorithm. + /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. + void step4(); + + /// Fifth step of the Porter Algorithm. + /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. + void step5(); + + /// Sixth step of the Porter Algorithm. + /// Refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation. + void step6(); + + /// Delete a suffix searched in zone "source" if zone "from" contains prefix + search string. + /// @param source String - the primary source zone for search. + /// @param search String[] - the strings to search for suppression. + /// @param from String - the secondary source zone for search. + /// @param prefix String - the prefix to add to the search string to test. + /// @return true if modified + bool deleteFromIfPrecededIn(const String& source, Collection search, const String& from, const String& prefix); + + /// Delete a suffix searched in zone "source" if the preceding letter is (or isn't) a vowel. + /// @param source String - the primary source zone for search. + /// @param search String[] - the strings to search for suppression. + /// @param vowel boolean - true if we need a vowel before the search string. + /// @param from String - the secondary source zone for search (where vowel could be). + /// @return true if modified + bool deleteFromIfTestVowelBeforeIn(const String& source, Collection search, bool vowel, const String& from); + + /// Delete a suffix searched in zone "source" if preceded by the prefix. + /// @param source String - the primary source zone for search. + /// @param search String[] - the strings to search for suppression. + /// @param prefix String - the prefix to add to the search string to test. + /// @param without boolean - true if it will be deleted even without prefix found. + void deleteButSuffixFrom(const String& source, Collection search, const String& prefix, bool without); + + /// Delete a suffix searched in zone "source" if preceded by prefix or replace it with the + /// replace string if preceded by the prefix in the zone "from" or delete the suffix if specified. + /// @param source String - the primary source zone for search. + /// @param search String[] - the strings to search for suppression. + /// @param prefix String - the prefix to add to the search string to test. + /// @param without boolean - true if it will be deleted even without prefix found. + void deleteButSuffixFromElseReplace(const String& source, Collection search, const String& prefix, bool without, const String& from, const String& replace); + + /// Replace a search string with another within the source zone. + /// @param source String - the source zone for search. + /// @param search String[] - the strings to search for replacement. + /// @param replace String - the replacement string. + bool replaceFrom(const String& source, Collection search, const String& replace); + + /// Delete a search string within the source zone. + /// @param source the source zone for search. + /// @param suffix the strings to search for suppression. + void deleteFrom(const String& source, Collection suffix); + + /// Test if a char is a French vowel, including accentuated ones. + /// @param ch the char to test. + /// @return true if the char is a vowel + bool isVowel(wchar_t ch); + + /// Retrieve the "R zone" (1 or 2 depending on the buffer) and return the corresponding string. + /// "R is the region after the first non-vowel following a vowel or is the null region at the + /// end of the word if there is no such non-vowel". + /// @param buffer the in buffer. + /// @return the resulting string. + String retrieveR(const String& buffer); + + /// Retrieve the "RV zone" from a buffer an return the corresponding string. + /// "If the word begins with two vowels, RV is the region after the third letter, otherwise the + /// region after the first vowel not at the beginning of the word, or the end of the word if + /// these positions cannot be found." + /// @param buffer the in buffer + /// @return the resulting string + String retrieveRV(const String& buffer); + + /// Turns u and i preceded AND followed by a vowel to UpperCase<. + /// Turns y preceded OR followed by a vowel to UpperCase. + /// Turns u preceded by q to UpperCase. + /// @param buffer the buffer to treat + void treatVowels(String& buffer); + + /// Checks a term if it can be processed correctly. + /// @return boolean - true if, and only if, the given term consists in letters. + bool isStemmable(const String& term); +}; + } #endif diff --git a/src/contrib/include/GermanAnalyzer.h b/src/contrib/include/GermanAnalyzer.h index b18ce4e5..16adc7ec 100644 --- a/src/contrib/include/GermanAnalyzer.h +++ b/src/contrib/include/GermanAnalyzer.h @@ -10,75 +10,74 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for German language. - /// - /// Supports an external list of stopwords (words that will not be indexed at all) and an external list of - /// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an - /// alternative list is specified, but the exclusion list is empty by default. - /// - /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. - class LPPCONTRIBAPI GermanAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - GermanAnalyzer(LuceneVersion::Version matchVersion); +namespace Lucene { + +/// {@link Analyzer} for German language. +/// +/// Supports an external list of stopwords (words that will not be indexed at all) and an external list of +/// exclusions (words that will not be stemmed, but indexed). A default set of stopwords is used unless an +/// alternative list is specified, but the exclusion list is empty by default. +/// +/// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. +class LPPCONTRIBAPI GermanAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + GermanAnalyzer(LuceneVersion::Version matchVersion); - /// Builds an analyzer with the given stop words. - GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + /// Builds an analyzer with the given stop words. + GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - /// Builds an analyzer with the given stop words and stemming exclusion words. - GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); + /// Builds an analyzer with the given stop words and stemming exclusion words. + GermanAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords, HashSet exclusions); - virtual ~GermanAnalyzer(); + virtual ~GermanAnalyzer(); - LUCENE_CLASS(GermanAnalyzer); + LUCENE_CLASS(GermanAnalyzer); - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stopSet; +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stopSet; - /// Contains words that should be indexed but not stemmed. - HashSet exclusionSet; + /// Contains words that should be indexed but not stemmed. + HashSet exclusionSet; - LuceneVersion::Version matchVersion; + LuceneVersion::Version matchVersion; - /// List of typical German stopwords. - static const wchar_t* _GERMAN_STOP_WORDS[]; + /// List of typical German stopwords. + static const wchar_t* _GERMAN_STOP_WORDS[]; - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); - void setStemExclusionTable(HashSet exclusions); + void setStemExclusionTable(HashSet exclusions); - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link GermanStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link StandardFilter}, {@link StopFilter}, and {@link GermanStemFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from an {@link GermanLetterTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link StopFilter}, {@link GermanNormalizationFilter} and + /// {@link GermanStemFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link GermanLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link StopFilter}, {@link GermanNormalizationFilter} and - /// {@link GermanStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; +class LPPCONTRIBAPI GermanAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~GermanAnalyzerSavedStreams(); - class LPPCONTRIBAPI GermanAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~GermanAnalyzerSavedStreams(); + LUCENE_CLASS(GermanAnalyzerSavedStreams); - LUCENE_CLASS(GermanAnalyzerSavedStreams); +public: + TokenizerPtr source; + TokenStreamPtr result; +}; - public: - TokenizerPtr source; - TokenStreamPtr result; - }; } #endif diff --git a/src/contrib/include/GermanStemFilter.h b/src/contrib/include/GermanStemFilter.h index 7993b404..35b45279 100644 --- a/src/contrib/include/GermanStemFilter.h +++ b/src/contrib/include/GermanStemFilter.h @@ -10,41 +10,41 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that stems German words. - /// - /// It supports a table of words that should not be stemmed at all. The stemmer used can - /// be changed at runtime after the filter object is created (as long as it is a - /// {@link GermanStemmer}). - class LPPCONTRIBAPI GermanStemFilter : public TokenFilter - { - public: - GermanStemFilter(const TokenStreamPtr& input); +namespace Lucene { - /// Builds a GermanStemFilter that uses an exclusion table. - GermanStemFilter(const TokenStreamPtr& input, HashSet exclusionSet); +/// A {@link TokenFilter} that stems German words. +/// +/// It supports a table of words that should not be stemmed at all. The stemmer used can +/// be changed at runtime after the filter object is created (as long as it is a +/// {@link GermanStemmer}). +class LPPCONTRIBAPI GermanStemFilter : public TokenFilter { +public: + GermanStemFilter(const TokenStreamPtr& input); - virtual ~GermanStemFilter(); + /// Builds a GermanStemFilter that uses an exclusion table. + GermanStemFilter(const TokenStreamPtr& input, HashSet exclusionSet); - LUCENE_CLASS(GermanStemFilter); + virtual ~GermanStemFilter(); - protected: - /// {@link GermanStemmer} in use by this filter. - GermanStemmerPtr stemmer; + LUCENE_CLASS(GermanStemFilter); - HashSet exclusionSet; - TermAttributePtr termAtt; +protected: + /// {@link GermanStemmer} in use by this filter. + GermanStemmerPtr stemmer; - public: - virtual bool incrementToken(); + HashSet exclusionSet; + TermAttributePtr termAtt; - /// Set a alternative/custom {@link GermanStemmer} for this filter. - void setStemmer(const GermanStemmerPtr& stemmer); +public: + virtual bool incrementToken(); + + /// Set a alternative/custom {@link GermanStemmer} for this filter. + void setStemmer(const GermanStemmerPtr& stemmer); + + /// Set an alternative exclusion list for this filter. + void setExclusionSet(HashSet exclusionSet); +}; - /// Set an alternative exclusion list for this filter. - void setExclusionSet(HashSet exclusionSet); - }; } #endif diff --git a/src/contrib/include/GermanStemmer.h b/src/contrib/include/GermanStemmer.h index 53a4ee83..66534293 100644 --- a/src/contrib/include/GermanStemmer.h +++ b/src/contrib/include/GermanStemmer.h @@ -10,64 +10,64 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// A stemmer for German words. +namespace Lucene { + +/// A stemmer for German words. +/// +/// The algorithm is based on the report "A Fast and Simple Stemming Algorithm for German Words" by Jörg +/// Caumanns (joerg.caumanns at isst.fhg.de). +class LPPCONTRIBAPI GermanStemmer : public LuceneObject { +public: + GermanStemmer(); + virtual ~GermanStemmer(); + + LUCENE_CLASS(GermanStemmer); + +protected: + /// Buffer for the terms while stemming them. + String buffer; + + /// Amount of characters that are removed with substitute() while stemming. + int32_t substCount; + +public: + /// Stems the given term to a unique discriminator. /// - /// The algorithm is based on the report "A Fast and Simple Stemming Algorithm for German Words" by Jörg - /// Caumanns (joerg.caumanns at isst.fhg.de). - class LPPCONTRIBAPI GermanStemmer : public LuceneObject - { - public: - GermanStemmer(); - virtual ~GermanStemmer(); - - LUCENE_CLASS(GermanStemmer); - - protected: - /// Buffer for the terms while stemming them. - String buffer; - - /// Amount of characters that are removed with substitute() while stemming. - int32_t substCount; - - public: - /// Stems the given term to a unique discriminator. - /// - /// @param term The term that should be stemmed. - /// @return Discriminator for term. - String stem(const String& term); - - protected: - /// Checks if a term could be stemmed. - /// @return true if, and only if, the given term consists in letters. - bool isStemmable(); - - /// Suffix stripping (stemming) on the current term. The stripping is reduced to the seven "base" - /// suffixes "e", "s", "n", "t", "em", "er" and * "nd", from which all regular suffixes are build - /// of. The simplification causes some overstemming, and way more irregular stems, but still - /// provides unique. - /// Discriminators in the most of those cases. - /// The algorithm is context free, except of the length restrictions. - void strip(); - - /// Does some optimizations on the term. This optimisations are contextual. - void optimize(); - - /// Removes a particle denotion ("ge") from a term. - void removeParticleDenotion(); - - /// Do some substitutions for the term to reduce overstemming: - /// - /// - Substitute Umlauts with their corresponding vowel: äöü -> aou, "ß" is substituted by "ss" - /// - Substitute a second char of a pair of equal characters with an asterisk: ?? -> ?* - /// - Substitute some common character combinations with a token: sch/ch/ei/ie/ig/st -> $/§/%/&/#/! - void substitute(); - - /// Undoes the changes made by substitute(). That are character pairs and character combinations. - /// Umlauts will remain as their corresponding vowel, as "ß" remains as "ss". - void resubstitute(); - }; + /// @param term The term that should be stemmed. + /// @return Discriminator for term. + String stem(const String& term); + +protected: + /// Checks if a term could be stemmed. + /// @return true if, and only if, the given term consists in letters. + bool isStemmable(); + + /// Suffix stripping (stemming) on the current term. The stripping is reduced to the seven "base" + /// suffixes "e", "s", "n", "t", "em", "er" and * "nd", from which all regular suffixes are build + /// of. The simplification causes some overstemming, and way more irregular stems, but still + /// provides unique. + /// Discriminators in the most of those cases. + /// The algorithm is context free, except of the length restrictions. + void strip(); + + /// Does some optimizations on the term. This optimisations are contextual. + void optimize(); + + /// Removes a particle denotion ("ge") from a term. + void removeParticleDenotion(); + + /// Do some substitutions for the term to reduce overstemming: + /// + /// - Substitute Umlauts with their corresponding vowel: äöü -> aou, "ß" is substituted by "ss" + /// - Substitute a second char of a pair of equal characters with an asterisk: ?? -> ?* + /// - Substitute some common character combinations with a token: sch/ch/ei/ie/ig/st -> $/§/%/&/#/! + void substitute(); + + /// Undoes the changes made by substitute(). That are character pairs and character combinations. + /// Umlauts will remain as their corresponding vowel, as "ß" remains as "ss". + void resubstitute(); +}; + } #endif diff --git a/src/contrib/include/GradientFormatter.h b/src/contrib/include/GradientFormatter.h index 28b7085b..853b243e 100644 --- a/src/contrib/include/GradientFormatter.h +++ b/src/contrib/include/GradientFormatter.h @@ -9,52 +9,52 @@ #include "Formatter.h" -namespace Lucene -{ - /// Formats text with different color intensity depending on the score of the term. - class LPPCONTRIBAPI GradientFormatter : public Formatter, public LuceneObject - { - public: - GradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor); - virtual ~GradientFormatter(); - - LUCENE_CLASS(GradientFormatter); - - protected: - double maxScore; - bool highlightForeground; - bool highlightBackground; - - public: - int32_t fgRMin; - int32_t fgGMin; - int32_t fgBMin; - - int32_t fgRMax; - int32_t fgGMax; - int32_t fgBMax; - - int32_t bgRMin; - int32_t bgGMin; - int32_t bgBMin; - - int32_t bgRMax; - int32_t bgGMax; - int32_t bgBMax; - - public: - virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); - - protected: - String getForegroundColorString(double score); - String getBackgroundColorString(double score); - int32_t getColorVal(int32_t colorMin, int32_t colorMax, double score); - - static String intToHex(int32_t i); - - /// Converts a hex string into an int. - static int32_t hexToInt(const String& hex); - }; +namespace Lucene { + +/// Formats text with different color intensity depending on the score of the term. +class LPPCONTRIBAPI GradientFormatter : public Formatter, public LuceneObject { +public: + GradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor); + virtual ~GradientFormatter(); + + LUCENE_CLASS(GradientFormatter); + +protected: + double maxScore; + bool highlightForeground; + bool highlightBackground; + +public: + int32_t fgRMin; + int32_t fgGMin; + int32_t fgBMin; + + int32_t fgRMax; + int32_t fgGMax; + int32_t fgBMax; + + int32_t bgRMin; + int32_t bgGMin; + int32_t bgBMin; + + int32_t bgRMax; + int32_t bgGMax; + int32_t bgBMax; + +public: + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); + +protected: + String getForegroundColorString(double score); + String getBackgroundColorString(double score); + int32_t getColorVal(int32_t colorMin, int32_t colorMax, double score); + + static String intToHex(int32_t i); + + /// Converts a hex string into an int. + static int32_t hexToInt(const String& hex); +}; + } #endif diff --git a/src/contrib/include/GreekAnalyzer.h b/src/contrib/include/GreekAnalyzer.h index 13d194a3..966d9f70 100644 --- a/src/contrib/include/GreekAnalyzer.h +++ b/src/contrib/include/GreekAnalyzer.h @@ -10,65 +10,64 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for Greek language. +namespace Lucene { + +/// {@link Analyzer} for Greek language. +/// +/// Supports an external list of stopwords (words that will not be indexed at all). A default set of stopwords +/// is used unless an alternative list is specified. +/// +/// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. +class LPPCONTRIBAPI GreekAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + GreekAnalyzer(LuceneVersion::Version matchVersion); + + /// Builds an analyzer with the given stop words. + GreekAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + + virtual ~GreekAnalyzer(); + + LUCENE_CLASS(GreekAnalyzer); + +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stopSet; + + LuceneVersion::Version matchVersion; + + /// Default Greek stopwords in UTF-8 format. + static const uint8_t _GREEK_STOP_WORDS[]; + +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); + + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. /// - /// Supports an external list of stopwords (words that will not be indexed at all). A default set of stopwords - /// is used unless an alternative list is specified. + /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with + /// {@link GreekLowerCaseFilter} and {@link StopFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. /// - /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. - class LPPCONTRIBAPI GreekAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - GreekAnalyzer(LuceneVersion::Version matchVersion); - - /// Builds an analyzer with the given stop words. - GreekAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - - virtual ~GreekAnalyzer(); - - LUCENE_CLASS(GreekAnalyzer); - - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stopSet; - - LuceneVersion::Version matchVersion; - - /// Default Greek stopwords in UTF-8 format. - static const uint8_t _GREEK_STOP_WORDS[]; - - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); - - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link StandardTokenizer} filtered with - /// {@link GreekLowerCaseFilter} and {@link StopFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link GreekLetterTokenizer} filtered with - /// {@link GreekLowerCaseFilter} and {@link StopFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI GreekAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~GreekAnalyzerSavedStreams(); - - LUCENE_CLASS(GreekAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; + /// @return A {@link TokenStream} built from an {@link GreekLetterTokenizer} filtered with + /// {@link GreekLowerCaseFilter} and {@link StopFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI GreekAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~GreekAnalyzerSavedStreams(); + + LUCENE_CLASS(GreekAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/GreekLowerCaseFilter.h b/src/contrib/include/GreekLowerCaseFilter.h index fec2b2de..d2bdc416 100644 --- a/src/contrib/include/GreekLowerCaseFilter.h +++ b/src/contrib/include/GreekLowerCaseFilter.h @@ -10,27 +10,27 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// Normalizes token text to lower case, removes some Greek diacritics, and standardizes - /// final sigma to sigma. - class LPPCONTRIBAPI GreekLowerCaseFilter : public TokenFilter - { - public: - GreekLowerCaseFilter(const TokenStreamPtr& input); - virtual ~GreekLowerCaseFilter(); - - LUCENE_CLASS(GreekLowerCaseFilter); - - protected: - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - - protected: - wchar_t lowerCase(wchar_t codepoint); - }; +namespace Lucene { + +/// Normalizes token text to lower case, removes some Greek diacritics, and standardizes +/// final sigma to sigma. +class LPPCONTRIBAPI GreekLowerCaseFilter : public TokenFilter { +public: + GreekLowerCaseFilter(const TokenStreamPtr& input); + virtual ~GreekLowerCaseFilter(); + + LUCENE_CLASS(GreekLowerCaseFilter); + +protected: + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); + +protected: + wchar_t lowerCase(wchar_t codepoint); +}; + } #endif diff --git a/src/contrib/include/Highlighter.h b/src/contrib/include/Highlighter.h index 15fecdf5..b71c9c47 100644 --- a/src/contrib/include/Highlighter.h +++ b/src/contrib/include/Highlighter.h @@ -10,120 +10,119 @@ #include "LuceneContrib.h" #include "PriorityQueue.h" -namespace Lucene -{ - /// Class used to markup highlighted terms found in the best sections of a text, using configurable - /// {@link Fragmenter}, {@link Scorer}, {@link Formatter}, {@link Encoder} and tokenizers. - class LPPCONTRIBAPI Highlighter : public LuceneObject - { - public: - Highlighter(const HighlighterScorerPtr& fragmentScorer); - Highlighter(const FormatterPtr& formatter, const HighlighterScorerPtr& fragmentScorer); - Highlighter(const FormatterPtr& formatter, const EncoderPtr& encoder, const HighlighterScorerPtr& fragmentScorer); - - virtual ~Highlighter(); - - LUCENE_CLASS(Highlighter); - - public: - static const int32_t DEFAULT_MAX_CHARS_TO_ANALYZE; - - protected: - int32_t maxDocCharsToAnalyze; - FormatterPtr formatter; - EncoderPtr encoder; - FragmenterPtr textFragmenter; - HighlighterScorerPtr fragmentScorer; - - public: - /// Highlights chosen terms in a text, extracting the most relevant section. This is a convenience - /// method that calls {@link #getBestFragment(TokenStreamPtr, const String&)} - /// - /// @param analyzer The analyzer that will be used to split text into chunks - /// @param text Text to highlight terms in - /// @param fieldName Name of field used to influence analyzer's tokenization policy - /// @return highlighted text fragment or null if no terms found - String getBestFragment(const AnalyzerPtr& analyzer, const String& fieldName, const String& text); - - /// Highlights chosen terms in a text, extracting the most relevant section. The document text is - /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the - /// fragment with the highest score is returned. - /// - /// @param tokenStream A stream of tokens identified in the text parameter, including offset - /// information. This is typically produced by an analyzer re-parsing a document's text. Some - /// work may be done on retrieving TokenStreams more efficiently by adding support for storing - /// original text position data in the Lucene index but this support is not currently available. - /// @param text Text to highlight terms in - /// @return highlighted text fragment or null if no terms found - String getBestFragment(const TokenStreamPtr& tokenStream, const String& text); - - /// Highlights chosen terms in a text, extracting the most relevant sections. This is a convenience - /// method that calls {@link #getBestFragments(TokenStreamPtr, const String&, int32_t)} - /// - /// @param analyzer The analyzer that will be used to split text into chunks - /// @param fieldName The name of the field being highlighted (used by analyzer) - /// @param text Text to highlight terms in - /// @param maxNumFragments The maximum number of fragments. - /// @return highlighted text fragments (between 0 and maxNumFragments number of fragments) - Collection getBestFragments(const AnalyzerPtr& analyzer, const String& fieldName, const String& text, int32_t maxNumFragments); - - /// Highlights chosen terms in a text, extracting the most relevant sections. The document text is - /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the - /// fragments with the highest scores are returned as an array of strings in order of score (contiguous - /// fragments are merged into one in their original order to improve readability) - /// - /// @param text Text to highlight terms in - /// @param maxNumFragments The maximum number of fragments. - /// @return highlighted Text fragments (between 0 and maxNumFragments number of fragments) - Collection getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments); - - /// Low level api to get the most relevant (formatted) sections of the document. - /// This method has been made public to allow visibility of score information held in TextFragment objects. - Collection getBestTextFragments(const TokenStreamPtr& tokenStream, const String& text, bool merge, int32_t maxNumFragments); - - /// Improves readability of a score-sorted list of TextFragments by merging any fragments that were - /// contiguous in the original text into one larger fragment with the correct order. This will leave - /// a "null" in the array entry for the lesser scored fragment. - /// - /// @param frag An array of document fragments in descending score - void mergeContiguousFragments(Collection frag); - - /// Highlights terms in the text , extracting the most relevant sections and concatenating the chosen - /// fragments with a separator (typically "..."). The document text is analyzed in chunks to record - /// hit statistics across the document. After accumulating stats, the fragments with the highest scores - /// are returned in order as "separator" delimited strings. - /// - /// @param text Text to highlight terms in - /// @param maxNumFragments The maximum number of fragments. - /// @param separator The separator used to intersperse the document fragments (typically "...") - /// @return highlighted text - String getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments, const String& separator); - - int32_t getMaxDocCharsToAnalyze(); - void setMaxDocCharsToAnalyze(int32_t maxDocCharsToAnalyze); - FragmenterPtr getTextFragmenter(); - void setTextFragmenter(const FragmenterPtr& fragmenter); - - /// @return Object used to score each text fragment - HighlighterScorerPtr getFragmentScorer(); - - void setFragmentScorer(const HighlighterScorerPtr& scorer); - - EncoderPtr getEncoder(); - void setEncoder(const EncoderPtr& encoder); - }; - - class LPPCONTRIBAPI FragmentQueue : public PriorityQueue - { - public: - FragmentQueue(int32_t size); - virtual ~FragmentQueue(); - - LUCENE_CLASS(FragmentQueue); - - protected: - virtual bool lessThan(const TextFragmentPtr& first, const TextFragmentPtr& second); - }; +namespace Lucene { + +/// Class used to markup highlighted terms found in the best sections of a text, using configurable +/// {@link Fragmenter}, {@link Scorer}, {@link Formatter}, {@link Encoder} and tokenizers. +class LPPCONTRIBAPI Highlighter : public LuceneObject { +public: + Highlighter(const HighlighterScorerPtr& fragmentScorer); + Highlighter(const FormatterPtr& formatter, const HighlighterScorerPtr& fragmentScorer); + Highlighter(const FormatterPtr& formatter, const EncoderPtr& encoder, const HighlighterScorerPtr& fragmentScorer); + + virtual ~Highlighter(); + + LUCENE_CLASS(Highlighter); + +public: + static const int32_t DEFAULT_MAX_CHARS_TO_ANALYZE; + +protected: + int32_t maxDocCharsToAnalyze; + FormatterPtr formatter; + EncoderPtr encoder; + FragmenterPtr textFragmenter; + HighlighterScorerPtr fragmentScorer; + +public: + /// Highlights chosen terms in a text, extracting the most relevant section. This is a convenience + /// method that calls {@link #getBestFragment(TokenStreamPtr, const String&)} + /// + /// @param analyzer The analyzer that will be used to split text into chunks + /// @param text Text to highlight terms in + /// @param fieldName Name of field used to influence analyzer's tokenization policy + /// @return highlighted text fragment or null if no terms found + String getBestFragment(const AnalyzerPtr& analyzer, const String& fieldName, const String& text); + + /// Highlights chosen terms in a text, extracting the most relevant section. The document text is + /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the + /// fragment with the highest score is returned. + /// + /// @param tokenStream A stream of tokens identified in the text parameter, including offset + /// information. This is typically produced by an analyzer re-parsing a document's text. Some + /// work may be done on retrieving TokenStreams more efficiently by adding support for storing + /// original text position data in the Lucene index but this support is not currently available. + /// @param text Text to highlight terms in + /// @return highlighted text fragment or null if no terms found + String getBestFragment(const TokenStreamPtr& tokenStream, const String& text); + + /// Highlights chosen terms in a text, extracting the most relevant sections. This is a convenience + /// method that calls {@link #getBestFragments(TokenStreamPtr, const String&, int32_t)} + /// + /// @param analyzer The analyzer that will be used to split text into chunks + /// @param fieldName The name of the field being highlighted (used by analyzer) + /// @param text Text to highlight terms in + /// @param maxNumFragments The maximum number of fragments. + /// @return highlighted text fragments (between 0 and maxNumFragments number of fragments) + Collection getBestFragments(const AnalyzerPtr& analyzer, const String& fieldName, const String& text, int32_t maxNumFragments); + + /// Highlights chosen terms in a text, extracting the most relevant sections. The document text is + /// analyzed in chunks to record hit statistics across the document. After accumulating stats, the + /// fragments with the highest scores are returned as an array of strings in order of score (contiguous + /// fragments are merged into one in their original order to improve readability) + /// + /// @param text Text to highlight terms in + /// @param maxNumFragments The maximum number of fragments. + /// @return highlighted Text fragments (between 0 and maxNumFragments number of fragments) + Collection getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments); + + /// Low level api to get the most relevant (formatted) sections of the document. + /// This method has been made public to allow visibility of score information held in TextFragment objects. + Collection getBestTextFragments(const TokenStreamPtr& tokenStream, const String& text, bool merge, int32_t maxNumFragments); + + /// Improves readability of a score-sorted list of TextFragments by merging any fragments that were + /// contiguous in the original text into one larger fragment with the correct order. This will leave + /// a "null" in the array entry for the lesser scored fragment. + /// + /// @param frag An array of document fragments in descending score + void mergeContiguousFragments(Collection frag); + + /// Highlights terms in the text , extracting the most relevant sections and concatenating the chosen + /// fragments with a separator (typically "..."). The document text is analyzed in chunks to record + /// hit statistics across the document. After accumulating stats, the fragments with the highest scores + /// are returned in order as "separator" delimited strings. + /// + /// @param text Text to highlight terms in + /// @param maxNumFragments The maximum number of fragments. + /// @param separator The separator used to intersperse the document fragments (typically "...") + /// @return highlighted text + String getBestFragments(const TokenStreamPtr& tokenStream, const String& text, int32_t maxNumFragments, const String& separator); + + int32_t getMaxDocCharsToAnalyze(); + void setMaxDocCharsToAnalyze(int32_t maxDocCharsToAnalyze); + FragmenterPtr getTextFragmenter(); + void setTextFragmenter(const FragmenterPtr& fragmenter); + + /// @return Object used to score each text fragment + HighlighterScorerPtr getFragmentScorer(); + + void setFragmentScorer(const HighlighterScorerPtr& scorer); + + EncoderPtr getEncoder(); + void setEncoder(const EncoderPtr& encoder); +}; + +class LPPCONTRIBAPI FragmentQueue : public PriorityQueue { +public: + FragmentQueue(int32_t size); + virtual ~FragmentQueue(); + + LUCENE_CLASS(FragmentQueue); + +protected: + virtual bool lessThan(const TextFragmentPtr& first, const TextFragmentPtr& second); +}; + } #endif diff --git a/src/contrib/include/HighlighterScorer.h b/src/contrib/include/HighlighterScorer.h index 9273ef7e..1fdd054d 100644 --- a/src/contrib/include/HighlighterScorer.h +++ b/src/contrib/include/HighlighterScorer.h @@ -10,43 +10,43 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// A HighlighterScorer is responsible for scoring a stream of tokens. These token scores - /// can then be used to compute {@link TextFragment} scores. - class LPPCONTRIBAPI HighlighterScorer - { - public: - virtual ~HighlighterScorer(); - LUCENE_INTERFACE(HighlighterScorer); - - public: - /// Called to init the Scorer with a {@link TokenStream}. You can grab references to the - /// attributes you are interested in here and access them from {@link #getTokenScore()}. - /// - /// @param tokenStream the {@link TokenStream} that will be scored. - /// @return either a {@link TokenStream} that the Highlighter should continue using (eg - /// if you read the tokenSream in this method) or null to continue using the same {@link - /// TokenStream} that was passed in. - virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); - - /// Called when a new fragment is started for consideration. - /// - /// @param newFragment the fragment that will be scored next - virtual void startFragment(const TextFragmentPtr& newFragment); - - /// Called for each token in the current fragment. The {@link Highlighter} will increment - /// the {@link TokenStream} passed to init on every call. - /// - /// @return a score which is passed to the {@link Highlighter} class to influence the - /// mark-up of the text (this return value is NOT used to score the fragment) - virtual double getTokenScore(); - - /// Called when the {@link Highlighter} has no more tokens for the current fragment - the - /// Scorer returns the weighting it has derived for the most recent fragment, typically - /// based on the results of {@link #getTokenScore()}. - virtual double getFragmentScore(); - }; +namespace Lucene { + +/// A HighlighterScorer is responsible for scoring a stream of tokens. These token scores +/// can then be used to compute {@link TextFragment} scores. +class LPPCONTRIBAPI HighlighterScorer { +public: + virtual ~HighlighterScorer(); + LUCENE_INTERFACE(HighlighterScorer); + +public: + /// Called to init the Scorer with a {@link TokenStream}. You can grab references to the + /// attributes you are interested in here and access them from {@link #getTokenScore()}. + /// + /// @param tokenStream the {@link TokenStream} that will be scored. + /// @return either a {@link TokenStream} that the Highlighter should continue using (eg + /// if you read the tokenSream in this method) or null to continue using the same {@link + /// TokenStream} that was passed in. + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); + + /// Called when a new fragment is started for consideration. + /// + /// @param newFragment the fragment that will be scored next + virtual void startFragment(const TextFragmentPtr& newFragment); + + /// Called for each token in the current fragment. The {@link Highlighter} will increment + /// the {@link TokenStream} passed to init on every call. + /// + /// @return a score which is passed to the {@link Highlighter} class to influence the + /// mark-up of the text (this return value is NOT used to score the fragment) + virtual double getTokenScore(); + + /// Called when the {@link Highlighter} has no more tokens for the current fragment - the + /// Scorer returns the weighting it has derived for the most recent fragment, typically + /// based on the results of {@link #getTokenScore()}. + virtual double getFragmentScore(); +}; + } #endif diff --git a/src/contrib/include/LuceneContrib.h b/src/contrib/include/LuceneContrib.h index f240b24b..d1dd2c33 100644 --- a/src/contrib/include/LuceneContrib.h +++ b/src/contrib/include/LuceneContrib.h @@ -9,108 +9,108 @@ #include "Lucene.h" -namespace Lucene -{ - // analyzers - DECLARE_SHARED_PTR(ArabicAnalyzer) - DECLARE_SHARED_PTR(ArabicAnalyzerSavedStreams) - DECLARE_SHARED_PTR(ArabicLetterTokenizer) - DECLARE_SHARED_PTR(ArabicNormalizationFilter) - DECLARE_SHARED_PTR(ArabicNormalizer) - DECLARE_SHARED_PTR(ArabicStemFilter) - DECLARE_SHARED_PTR(ArabicStemmer) - DECLARE_SHARED_PTR(BrazilianAnalyzer) - DECLARE_SHARED_PTR(BrazilianAnalyzerSavedStreams) - DECLARE_SHARED_PTR(BrazilianStemFilter) - DECLARE_SHARED_PTR(BrazilianStemmer) - DECLARE_SHARED_PTR(CJKAnalyzer) - DECLARE_SHARED_PTR(CJKAnalyzerSavedStreams) - DECLARE_SHARED_PTR(CJKTokenizer) - DECLARE_SHARED_PTR(ChineseAnalyzer) - DECLARE_SHARED_PTR(ChineseAnalyzerSavedStreams) - DECLARE_SHARED_PTR(ChineseFilter) - DECLARE_SHARED_PTR(ChineseTokenizer) - DECLARE_SHARED_PTR(CzechAnalyzer) - DECLARE_SHARED_PTR(CzechAnalyzerSavedStreams) - DECLARE_SHARED_PTR(DutchAnalyzer) - DECLARE_SHARED_PTR(DutchAnalyzerSavedStreams) - DECLARE_SHARED_PTR(DutchStemFilter) - DECLARE_SHARED_PTR(DutchStemmer) - DECLARE_SHARED_PTR(ElisionFilter) - DECLARE_SHARED_PTR(FrenchAnalyzer) - DECLARE_SHARED_PTR(FrenchAnalyzerSavedStreams) - DECLARE_SHARED_PTR(FrenchStemFilter) - DECLARE_SHARED_PTR(FrenchStemmer) - DECLARE_SHARED_PTR(GermanAnalyzer) - DECLARE_SHARED_PTR(GermanAnalyzerSavedStreams) - DECLARE_SHARED_PTR(GermanStemFilter) - DECLARE_SHARED_PTR(GermanStemmer) - DECLARE_SHARED_PTR(GreekLowerCaseFilter) - DECLARE_SHARED_PTR(GreekAnalyzer) - DECLARE_SHARED_PTR(GreekAnalyzerSavedStreams) - DECLARE_SHARED_PTR(PersianAnalyzer) - DECLARE_SHARED_PTR(PersianAnalyzerSavedStreams) - DECLARE_SHARED_PTR(PersianNormalizationFilter) - DECLARE_SHARED_PTR(PersianNormalizer) - DECLARE_SHARED_PTR(ReverseStringFilter) - DECLARE_SHARED_PTR(RussianAnalyzer) - DECLARE_SHARED_PTR(RussianAnalyzerSavedStreams) - DECLARE_SHARED_PTR(RussianLetterTokenizer) - DECLARE_SHARED_PTR(RussianLowerCaseFilter) - DECLARE_SHARED_PTR(RussianStemFilter) - DECLARE_SHARED_PTR(RussianStemmer) - DECLARE_SHARED_PTR(SnowballFilter) - DECLARE_SHARED_PTR(SnowballAnalyzer) - DECLARE_SHARED_PTR(SnowballAnalyzerSavedStreams) +namespace Lucene { - // highlighter - DECLARE_SHARED_PTR(DefaultEncoder) - DECLARE_SHARED_PTR(Encoder) - DECLARE_SHARED_PTR(FakeReader) - DECLARE_SHARED_PTR(Formatter) - DECLARE_SHARED_PTR(Fragmenter) - DECLARE_SHARED_PTR(FragmentQueue) - DECLARE_SHARED_PTR(GradientFormatter) - DECLARE_SHARED_PTR(Highlighter) - DECLARE_SHARED_PTR(HighlighterScorer) - DECLARE_SHARED_PTR(MapWeightedSpanTerm) - DECLARE_SHARED_PTR(NullFragmenter) - DECLARE_SHARED_PTR(PositionCheckingMap) - DECLARE_SHARED_PTR(PositionSpan) - DECLARE_SHARED_PTR(QueryScorer) - DECLARE_SHARED_PTR(QueryTermExtractor) - DECLARE_SHARED_PTR(QueryTermScorer) - DECLARE_SHARED_PTR(SimpleFragmenter) - DECLARE_SHARED_PTR(SimpleHTMLEncoder) - DECLARE_SHARED_PTR(SimpleHTMLFormatter) - DECLARE_SHARED_PTR(SimpleSpanFragmenter) - DECLARE_SHARED_PTR(SpanGradientFormatter) - DECLARE_SHARED_PTR(StringBuffer) - DECLARE_SHARED_PTR(TextFragment) - DECLARE_SHARED_PTR(TokenGroup) - DECLARE_SHARED_PTR(TokenSources) - DECLARE_SHARED_PTR(WeightedSpanTerm) - DECLARE_SHARED_PTR(WeightedSpanTermExtractor) - DECLARE_SHARED_PTR(WeightedTerm) +// analyzers +DECLARE_SHARED_PTR(ArabicAnalyzer) +DECLARE_SHARED_PTR(ArabicAnalyzerSavedStreams) +DECLARE_SHARED_PTR(ArabicLetterTokenizer) +DECLARE_SHARED_PTR(ArabicNormalizationFilter) +DECLARE_SHARED_PTR(ArabicNormalizer) +DECLARE_SHARED_PTR(ArabicStemFilter) +DECLARE_SHARED_PTR(ArabicStemmer) +DECLARE_SHARED_PTR(BrazilianAnalyzer) +DECLARE_SHARED_PTR(BrazilianAnalyzerSavedStreams) +DECLARE_SHARED_PTR(BrazilianStemFilter) +DECLARE_SHARED_PTR(BrazilianStemmer) +DECLARE_SHARED_PTR(CJKAnalyzer) +DECLARE_SHARED_PTR(CJKAnalyzerSavedStreams) +DECLARE_SHARED_PTR(CJKTokenizer) +DECLARE_SHARED_PTR(ChineseAnalyzer) +DECLARE_SHARED_PTR(ChineseAnalyzerSavedStreams) +DECLARE_SHARED_PTR(ChineseFilter) +DECLARE_SHARED_PTR(ChineseTokenizer) +DECLARE_SHARED_PTR(CzechAnalyzer) +DECLARE_SHARED_PTR(CzechAnalyzerSavedStreams) +DECLARE_SHARED_PTR(DutchAnalyzer) +DECLARE_SHARED_PTR(DutchAnalyzerSavedStreams) +DECLARE_SHARED_PTR(DutchStemFilter) +DECLARE_SHARED_PTR(DutchStemmer) +DECLARE_SHARED_PTR(ElisionFilter) +DECLARE_SHARED_PTR(FrenchAnalyzer) +DECLARE_SHARED_PTR(FrenchAnalyzerSavedStreams) +DECLARE_SHARED_PTR(FrenchStemFilter) +DECLARE_SHARED_PTR(FrenchStemmer) +DECLARE_SHARED_PTR(GermanAnalyzer) +DECLARE_SHARED_PTR(GermanAnalyzerSavedStreams) +DECLARE_SHARED_PTR(GermanStemFilter) +DECLARE_SHARED_PTR(GermanStemmer) +DECLARE_SHARED_PTR(GreekLowerCaseFilter) +DECLARE_SHARED_PTR(GreekAnalyzer) +DECLARE_SHARED_PTR(GreekAnalyzerSavedStreams) +DECLARE_SHARED_PTR(PersianAnalyzer) +DECLARE_SHARED_PTR(PersianAnalyzerSavedStreams) +DECLARE_SHARED_PTR(PersianNormalizationFilter) +DECLARE_SHARED_PTR(PersianNormalizer) +DECLARE_SHARED_PTR(ReverseStringFilter) +DECLARE_SHARED_PTR(RussianAnalyzer) +DECLARE_SHARED_PTR(RussianAnalyzerSavedStreams) +DECLARE_SHARED_PTR(RussianLetterTokenizer) +DECLARE_SHARED_PTR(RussianLowerCaseFilter) +DECLARE_SHARED_PTR(RussianStemFilter) +DECLARE_SHARED_PTR(RussianStemmer) +DECLARE_SHARED_PTR(SnowballFilter) +DECLARE_SHARED_PTR(SnowballAnalyzer) +DECLARE_SHARED_PTR(SnowballAnalyzerSavedStreams) - // memory - DECLARE_SHARED_PTR(MemoryIndex) - DECLARE_SHARED_PTR(MemoryIndexInfo) - DECLARE_SHARED_PTR(MemoryIndexReader) +// highlighter +DECLARE_SHARED_PTR(DefaultEncoder) +DECLARE_SHARED_PTR(Encoder) +DECLARE_SHARED_PTR(FakeReader) +DECLARE_SHARED_PTR(Formatter) +DECLARE_SHARED_PTR(Fragmenter) +DECLARE_SHARED_PTR(FragmentQueue) +DECLARE_SHARED_PTR(GradientFormatter) +DECLARE_SHARED_PTR(Highlighter) +DECLARE_SHARED_PTR(HighlighterScorer) +DECLARE_SHARED_PTR(MapWeightedSpanTerm) +DECLARE_SHARED_PTR(NullFragmenter) +DECLARE_SHARED_PTR(PositionCheckingMap) +DECLARE_SHARED_PTR(PositionSpan) +DECLARE_SHARED_PTR(QueryScorer) +DECLARE_SHARED_PTR(QueryTermExtractor) +DECLARE_SHARED_PTR(QueryTermScorer) +DECLARE_SHARED_PTR(SimpleFragmenter) +DECLARE_SHARED_PTR(SimpleHTMLEncoder) +DECLARE_SHARED_PTR(SimpleHTMLFormatter) +DECLARE_SHARED_PTR(SimpleSpanFragmenter) +DECLARE_SHARED_PTR(SpanGradientFormatter) +DECLARE_SHARED_PTR(StringBuffer) +DECLARE_SHARED_PTR(TextFragment) +DECLARE_SHARED_PTR(TokenGroup) +DECLARE_SHARED_PTR(TokenSources) +DECLARE_SHARED_PTR(WeightedSpanTerm) +DECLARE_SHARED_PTR(WeightedSpanTermExtractor) +DECLARE_SHARED_PTR(WeightedTerm) - typedef HashMap< String, WeightedSpanTermPtr > MapStringWeightedSpanTerm; - typedef HashMap< String, WeightedTermPtr > MapStringWeightedTerm; - typedef HashMap< String, SpanQueryPtr > MapStringSpanQuery; - typedef HashMap< String, Collection > MapStringIntCollection; - typedef HashMap< String, MemoryIndexInfoPtr > MapStringMemoryIndexInfo; +// memory +DECLARE_SHARED_PTR(MemoryIndex) +DECLARE_SHARED_PTR(MemoryIndexInfo) +DECLARE_SHARED_PTR(MemoryIndexReader) - typedef std::pair< String, Collection > PairStringIntCollection; - typedef Collection< PairStringIntCollection > CollectionStringIntCollection; +typedef HashMap< String, WeightedSpanTermPtr > MapStringWeightedSpanTerm; +typedef HashMap< String, WeightedTermPtr > MapStringWeightedTerm; +typedef HashMap< String, SpanQueryPtr > MapStringSpanQuery; +typedef HashMap< String, Collection > MapStringIntCollection; +typedef HashMap< String, MemoryIndexInfoPtr > MapStringMemoryIndexInfo; - typedef std::pair< String, MemoryIndexInfoPtr > PairStringMemoryIndexInfo; - typedef Collection< PairStringMemoryIndexInfo > CollectionStringMemoryIndexInfo; +typedef std::pair< String, Collection > PairStringIntCollection; +typedef Collection< PairStringIntCollection > CollectionStringIntCollection; - typedef HashSet< WeightedTermPtr, luceneHash, luceneEquals > SetWeightedTerm; +typedef std::pair< String, MemoryIndexInfoPtr > PairStringMemoryIndexInfo; +typedef Collection< PairStringMemoryIndexInfo > CollectionStringMemoryIndexInfo; + +typedef HashSet< WeightedTermPtr, luceneHash, luceneEquals > SetWeightedTerm; } #endif diff --git a/src/contrib/include/MapWeightedSpanTerm.h b/src/contrib/include/MapWeightedSpanTerm.h index 3f7277a8..abab0872 100644 --- a/src/contrib/include/MapWeightedSpanTerm.h +++ b/src/contrib/include/MapWeightedSpanTerm.h @@ -10,27 +10,27 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Utility class that encapsulates a StringWeightedSpanTerm map that can be overridden. - class LPPCONTRIBAPI MapWeightedSpanTerm : public LuceneObject - { - public: - MapWeightedSpanTerm(); - virtual ~MapWeightedSpanTerm(); - - LUCENE_CLASS(MapWeightedSpanTerm); - - protected: - MapStringWeightedSpanTerm map; - - public: - virtual MapStringWeightedSpanTerm::iterator begin(); - virtual MapStringWeightedSpanTerm::iterator end(); - virtual void put(const String& key, const WeightedSpanTermPtr& val); - virtual WeightedSpanTermPtr get(const String& key) const; - virtual void clear(); - }; +namespace Lucene { + +/// Utility class that encapsulates a StringWeightedSpanTerm map that can be overridden. +class LPPCONTRIBAPI MapWeightedSpanTerm : public LuceneObject { +public: + MapWeightedSpanTerm(); + virtual ~MapWeightedSpanTerm(); + + LUCENE_CLASS(MapWeightedSpanTerm); + +protected: + MapStringWeightedSpanTerm map; + +public: + virtual MapStringWeightedSpanTerm::iterator begin(); + virtual MapStringWeightedSpanTerm::iterator end(); + virtual void put(const String& key, const WeightedSpanTermPtr& val); + virtual WeightedSpanTermPtr get(const String& key) const; + virtual void clear(); +}; + } #endif diff --git a/src/contrib/include/MemoryIndex.h b/src/contrib/include/MemoryIndex.h index 3423ff40..d6cdd1e5 100644 --- a/src/contrib/include/MemoryIndex.h +++ b/src/contrib/include/MemoryIndex.h @@ -14,355 +14,349 @@ #include "TermPositions.h" #include "TermPositionVector.h" -namespace Lucene -{ - /// High-performance single-document main memory Lucene fulltext search index. - /// - /// Overview - /// - /// This class is a replacement/substitute for a large subset of {@link RAMDirectory} functionality. - /// It is designed to enable maximum efficiency for on-the-fly matchmaking combining structured and - /// fuzzy fulltext search in realtime streaming applications such as Nux XQuery based XML message - /// queues, publish-subscribe systems for Blogs/newsfeeds, text chat, data acquisition and - /// distribution systems, application level routers, firewalls, classifiers, etc. Rather than - /// targeting fulltext search of infrequent queries over huge persistent data archives (historic - /// search), this class targets fulltext search of huge numbers of queries over comparatively small - /// transient realtime data (prospective search). - /// - /// For example as in - ///
      -    /// double score = search(const String& text, const QueryPtr& query)
      -    /// 
      - /// - /// Each instance can hold at most one Lucene "document", with a document containing zero or more - /// "fields", each field having a name and a fulltext value. The fulltext value is tokenized - /// (split and transformed) into zero or more index terms (aka words) on addField(), according to - /// the policy implemented by an Analyzer. For example, Lucene analyzers can split on whitespace, - /// normalize to lower case for case insensitivity, ignore common terms with little discriminatory - /// value such as "he", "in", "and" (stop words), reduce the terms to their natural linguistic root - /// form such as "fishing" being reduced to "fish" (stemming), resolve synonyms/inflexions/thesauri - /// (upon indexing and/or querying), etc. - /// - /// Note that a Lucene query selects on the field names and associated (indexed) tokenized terms, - /// not on the original fulltext(s) - the latter are not stored but rather thrown away immediately - /// after tokenization. - /// - /// For some interesting background information on search technology, see Bob Wyman's Prospective Search, - /// Jim Gray's - /// A Call to Arms - Custom subscriptions, and Tim Bray's On Search, the Series. - /// - /// - /// Example Usage - ///
      -    /// AnalyzerPtr analyzer = newLucene();
      -    /// MemoryIndexPtr index = newLucene();
      -    /// index->addField(L"content", L"Readings about Salmons and other select Alaska fishing Manuals", analyzer);
      -    /// index->addField(L"author", L"Tales of James", analyzer);
      -    /// QueryParserPtr parser = newLucene(L"content", analyzer);
      -    /// double score = index->search(parser->parse(L"+author:james +salmon~ +fish* manual~"));
      -    /// if (score > 0.0)
      -    /// {
      -    ///     // it's a match
      -    /// }
      -    /// else
      -    /// {
      -    ///     // no match found
      -    /// }
      -    /// 
      - /// - /// - /// Performance Notes - /// - /// Internally there's a new data structure geared towards efficient indexing and searching, plus - /// the necessary support code to seamlessly plug into the Lucene framework. - /// - /// This class performs very well for very small texts (eg. 10 chars) as well as for large texts - /// (eg. 10 MB) and everything in between. Typically, it is about 10-100 times faster than - /// RAMDirectory. Note that RAMDirectory has particularly large efficiency overheads for small to - /// medium sized texts, both in time and space. Indexing a field with N tokens takes O(N) in the - /// best case, and O(N logN) in the worst case. Memory consumption is probably larger than for - /// RAMDirectory. - /// - class LPPCONTRIBAPI MemoryIndex : public LuceneObject - { - public: - /// Constructs an empty instance that can optionally store the start and end character offset - /// of each token term in the text. This can be useful for highlighting of hit locations with - /// the Lucene highlighter package. Private until the highlighter package matures, so that - /// this can actually be meaningfully integrated. - /// @param storeOffsets Whether or not to store the start and end character offset of each - /// token term in the text. - MemoryIndex(bool storeOffsets = false); - - virtual ~MemoryIndex(); - - LUCENE_CLASS(MemoryIndex); - - protected: - /// info for each field - MapStringMemoryIndexInfo fields; - - /// fields sorted ascending by fieldName; lazily computed on demand - CollectionStringMemoryIndexInfo sortedFields; - - /// pos: positions[3 * i], startOffset: positions[3 * i + 1], endOffset: positions[3 * i + 2] - int32_t stride; - - static const double docBoost; - - public: - /// Convenience method; Tokenizes the given field text and adds the resulting terms to the - /// index; Equivalent to adding an indexed non-keyword Lucene {@link Field} that is {@link - /// Field::INDEX_ANALYZED tokenized}, {@link Field::STORE_NO not stored}, {@link - /// Field::TERM_VECTOR_WITH_POSITIONS termVectorStored with positions} (or {@link - /// Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS termVectorStored with positions and offsets}) - /// @param fieldName A name to be associated with the text - /// @param text The text to tokenize and index. - /// @param analyzer The analyzer to use for tokenization - void addField(const String& fieldName, const String& text, const AnalyzerPtr& analyzer); - - /// Iterates over the given token stream and adds the resulting terms to the index; - /// Equivalent to adding a tokenized, indexed, termVectorStored, unstored, Lucene {@link - /// Field}. Finally closes the token stream. Note that untokenized keywords can be added - /// with this method via {@link #keywordTokenStream(Collection)}, the Lucene contrib - /// KeywordTokenizer or similar utilities. - /// @param fieldName A name to be associated with the text. - /// @param stream The token stream to retrieve tokens from. - /// @param boost The boost factor for hits for this field. - /// @see Field#setBoost(double) - void addField(const String& fieldName, const TokenStreamPtr& stream, double boost = 1.0); - - /// Creates and returns a searcher that can be used to execute arbitrary Lucene queries - /// and to collect the resulting query results as hits. - /// @return a searcher - IndexSearcherPtr createSearcher(); - - /// Convenience method that efficiently returns the relevance score by matching this index - /// against the given Lucene query expression. - /// @param query An arbitrary Lucene query to run against this index - /// @return the relevance score of the matchmaking; A number in the range [0.0 .. 1.0], - /// with 0.0 indicating no match. The higher the number the better the match. - double search(const QueryPtr& query); - - protected: - int32_t numPositions(Collection positions); - - /// sorts into ascending order (on demand), reusing memory along the way - void sortFields(); - - friend class MemoryIndexReader; - friend class MemoryIndexInfo; - friend class MemoryIndexTermEnum; - friend class MemoryIndexTermPositions; - friend class MemoryIndexTermPositionVector; - }; - - /// Index data structure for a field; Contains the tokenized term texts and their positions. - class LPPCONTRIBAPI MemoryIndexInfo : public LuceneObject - { - public: - MemoryIndexInfo(MapStringIntCollection terms, int32_t numTokens, int32_t numOverlapTokens, double boost); - virtual ~MemoryIndexInfo(); - - LUCENE_CLASS(MemoryIndexInfo); - - protected: - /// Term strings and their positions for this field - MapStringIntCollection terms; - - /// Terms sorted ascending by term text; computed on demand - CollectionStringIntCollection sortedTerms; - - /// Number of added tokens for this field - int32_t numTokens; - - /// Number of overlapping tokens for this field - int32_t numOverlapTokens; - - /// Boost factor for hits for this field - double boost; - - /// Term for this field's fieldName, lazily computed on demand - TermPtr _template; - - public: - /// Sorts hashed terms into ascending order, reusing memory along the way. Note that - /// sorting is lazily delayed until required (often it's not required at all). - void sortTerms(); - - /// Note that the frequency can be calculated as numPosition(getPositions(x)) - Collection getPositions(const String& term); - - /// Note that the frequency can be calculated as numPosition(getPositions(x)) - Collection getPositions(int32_t pos); - - double getBoost(); - - friend class MemoryIndexReader; - friend class MemoryIndexTermEnum; - friend class MemoryIndexTermPositions; - friend class MemoryIndexTermPositionVector; - }; - - /// Search support for Lucene framework integration; implements all methods required by the - /// Lucene IndexReader contracts. - class LPPCONTRIBAPI MemoryIndexReader : public IndexReader - { - public: - MemoryIndexReader(const MemoryIndexPtr& memoryIndex); - virtual ~MemoryIndexReader(); - - LUCENE_CLASS(MemoryIndexReader); - - public: - static TermPtr MATCH_ALL_TERM(); - - protected: - MemoryIndexPtr memoryIndex; - SearcherWeakPtr _searcher; // needed to find searcher.getSimilarity() - - /// cache norms to avoid repeated expensive calculations - ByteArray cachedNorms; - String cachedFieldName; - SimilarityPtr cachedSimilarity; - - protected: - MemoryIndexInfoPtr getInfo(const String& fieldName); - MemoryIndexInfoPtr getInfo(int32_t pos); - - SimilarityPtr getSimilarity(); - void setSearcher(const SearcherPtr& searcher); - - public: - virtual int32_t docFreq(const TermPtr& t); - virtual TermEnumPtr terms(); - virtual TermEnumPtr terms(const TermPtr& t); - virtual TermPositionsPtr termPositions(); - virtual TermDocsPtr termDocs(); - virtual Collection getTermFreqVectors(int32_t docNumber); - virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); - virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); - virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); - virtual ByteArray norms(const String& field); - virtual void norms(const String& field, ByteArray norms, int32_t offset); - virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); - virtual int32_t numDocs(); - virtual int32_t maxDoc(); - virtual DocumentPtr document(int32_t n); - virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); - virtual bool isDeleted(int32_t n); - virtual bool hasDeletions(); - virtual void doDelete(int32_t docNum); - virtual void doUndeleteAll(); - virtual void doCommit(MapStringString commitUserData); - virtual void doClose(); - virtual HashSet getFieldNames(FieldOption fieldOption); - - friend class MemoryIndex; - friend class MemoryIndexTermEnum; - friend class MemoryIndexTermPositions; - friend class MemoryIndexTermPositionVector; - }; - - class LPPCONTRIBAPI MemoryIndexTermEnum : public TermEnum - { - public: - MemoryIndexTermEnum(const MemoryIndexReaderPtr& reader, int32_t ix, int32_t jx); - virtual ~MemoryIndexTermEnum(); - - LUCENE_CLASS(MemoryIndexTermEnum); - - protected: - MemoryIndexReaderWeakPtr _reader; - int32_t i; - int32_t j; - - public: - virtual bool next(); - virtual TermPtr term(); - virtual int32_t docFreq(); - virtual void close(); - - protected: - TermPtr createTerm(const MemoryIndexInfoPtr& info, int32_t pos, const String& text); - }; - - class LPPCONTRIBAPI MemoryIndexCollector : public Collector - { - public: - MemoryIndexCollector(Collection scores); - virtual ~MemoryIndexCollector(); - - LUCENE_CLASS(MemoryIndexCollector); - - protected: - Collection scores; - ScorerPtr scorer; - - public: - virtual void collect(int32_t doc); - virtual void setScorer(const ScorerPtr& scorer); - virtual bool acceptsDocsOutOfOrder(); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - }; - - class LPPCONTRIBAPI MemoryIndexTermPositions : public TermPositions, public LuceneObject - { - public: - MemoryIndexTermPositions(const MemoryIndexReaderPtr& reader); - virtual ~MemoryIndexTermPositions(); - - LUCENE_CLASS(MemoryIndexTermPositions); - - protected: - MemoryIndexReaderWeakPtr _reader; - bool hasNext; - int32_t cursor; - Collection current; - TermPtr term; - - public: - virtual void seek(const TermPtr& term); - virtual void seek(const TermEnumPtr& termEnum); - virtual int32_t doc(); - virtual int32_t freq(); - virtual bool next(); - virtual int32_t read(Collection docs, Collection freqs); - virtual bool skipTo(int32_t target); - virtual void close(); - - virtual int32_t nextPosition(); - virtual int32_t getPayloadLength(); - virtual ByteArray getPayload(ByteArray data, int32_t offset); - virtual bool isPayloadAvailable(); - }; - - class MemoryIndexTermPositionVector : public TermPositionVector, public LuceneObject - { - public: - MemoryIndexTermPositionVector(const MemoryIndexReaderPtr& reader, const MemoryIndexInfoPtr& info, const String& fieldName); - virtual ~MemoryIndexTermPositionVector(); - - LUCENE_CLASS(MemoryIndexTermPositionVector); - - protected: - MemoryIndexReaderWeakPtr _reader; - CollectionStringIntCollection sortedTerms; - String fieldName; - - public: - virtual String getField(); - virtual int32_t size(); - virtual Collection getTerms(); - virtual Collection getTermFrequencies(); - virtual int32_t indexOf(const String& term); - virtual Collection indexesOf(Collection terms, int32_t start, int32_t length); - - virtual Collection getTermPositions(int32_t index); - virtual Collection getOffsets(int32_t index); - }; +namespace Lucene { + +/// High-performance single-document main memory Lucene fulltext search index. +/// +/// Overview +/// +/// This class is a replacement/substitute for a large subset of {@link RAMDirectory} functionality. +/// It is designed to enable maximum efficiency for on-the-fly matchmaking combining structured and +/// fuzzy fulltext search in realtime streaming applications such as Nux XQuery based XML message +/// queues, publish-subscribe systems for Blogs/newsfeeds, text chat, data acquisition and +/// distribution systems, application level routers, firewalls, classifiers, etc. Rather than +/// targeting fulltext search of infrequent queries over huge persistent data archives (historic +/// search), this class targets fulltext search of huge numbers of queries over comparatively small +/// transient realtime data (prospective search). +/// +/// For example as in +///
      +/// double score = search(const String& text, const QueryPtr& query)
      +/// 
      +/// +/// Each instance can hold at most one Lucene "document", with a document containing zero or more +/// "fields", each field having a name and a fulltext value. The fulltext value is tokenized +/// (split and transformed) into zero or more index terms (aka words) on addField(), according to +/// the policy implemented by an Analyzer. For example, Lucene analyzers can split on whitespace, +/// normalize to lower case for case insensitivity, ignore common terms with little discriminatory +/// value such as "he", "in", "and" (stop words), reduce the terms to their natural linguistic root +/// form such as "fishing" being reduced to "fish" (stemming), resolve synonyms/inflexions/thesauri +/// (upon indexing and/or querying), etc. +/// +/// Note that a Lucene query selects on the field names and associated (indexed) tokenized terms, +/// not on the original fulltext(s) - the latter are not stored but rather thrown away immediately +/// after tokenization. +/// +/// For some interesting background information on search technology, see Bob Wyman's Prospective Search, +/// Jim Gray's +/// A Call to Arms - Custom subscriptions, and Tim Bray's On Search, the Series. +/// +/// +/// Example Usage +///
      +/// AnalyzerPtr analyzer = newLucene();
      +/// MemoryIndexPtr index = newLucene();
      +/// index->addField(L"content", L"Readings about Salmons and other select Alaska fishing Manuals", analyzer);
      +/// index->addField(L"author", L"Tales of James", analyzer);
      +/// QueryParserPtr parser = newLucene(L"content", analyzer);
      +/// double score = index->search(parser->parse(L"+author:james +salmon~ +fish* manual~"));
      +/// if (score > 0.0)
      +/// {
      +///     // it's a match
      +/// }
      +/// else
      +/// {
      +///     // no match found
      +/// }
      +/// 
      +/// +/// +/// Performance Notes +/// +/// Internally there's a new data structure geared towards efficient indexing and searching, plus +/// the necessary support code to seamlessly plug into the Lucene framework. +/// +/// This class performs very well for very small texts (eg. 10 chars) as well as for large texts +/// (eg. 10 MB) and everything in between. Typically, it is about 10-100 times faster than +/// RAMDirectory. Note that RAMDirectory has particularly large efficiency overheads for small to +/// medium sized texts, both in time and space. Indexing a field with N tokens takes O(N) in the +/// best case, and O(N logN) in the worst case. Memory consumption is probably larger than for +/// RAMDirectory. +/// +class LPPCONTRIBAPI MemoryIndex : public LuceneObject { +public: + /// Constructs an empty instance that can optionally store the start and end character offset + /// of each token term in the text. This can be useful for highlighting of hit locations with + /// the Lucene highlighter package. Private until the highlighter package matures, so that + /// this can actually be meaningfully integrated. + /// @param storeOffsets Whether or not to store the start and end character offset of each + /// token term in the text. + MemoryIndex(bool storeOffsets = false); + + virtual ~MemoryIndex(); + + LUCENE_CLASS(MemoryIndex); + +protected: + /// info for each field + MapStringMemoryIndexInfo fields; + + /// fields sorted ascending by fieldName; lazily computed on demand + CollectionStringMemoryIndexInfo sortedFields; + + /// pos: positions[3 * i], startOffset: positions[3 * i + 1], endOffset: positions[3 * i + 2] + int32_t stride; + + static const double docBoost; + +public: + /// Convenience method; Tokenizes the given field text and adds the resulting terms to the + /// index; Equivalent to adding an indexed non-keyword Lucene {@link Field} that is {@link + /// Field::INDEX_ANALYZED tokenized}, {@link Field::STORE_NO not stored}, {@link + /// Field::TERM_VECTOR_WITH_POSITIONS termVectorStored with positions} (or {@link + /// Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS termVectorStored with positions and offsets}) + /// @param fieldName A name to be associated with the text + /// @param text The text to tokenize and index. + /// @param analyzer The analyzer to use for tokenization + void addField(const String& fieldName, const String& text, const AnalyzerPtr& analyzer); + + /// Iterates over the given token stream and adds the resulting terms to the index; + /// Equivalent to adding a tokenized, indexed, termVectorStored, unstored, Lucene {@link + /// Field}. Finally closes the token stream. Note that untokenized keywords can be added + /// with this method via {@link #keywordTokenStream(Collection)}, the Lucene contrib + /// KeywordTokenizer or similar utilities. + /// @param fieldName A name to be associated with the text. + /// @param stream The token stream to retrieve tokens from. + /// @param boost The boost factor for hits for this field. + /// @see Field#setBoost(double) + void addField(const String& fieldName, const TokenStreamPtr& stream, double boost = 1.0); + + /// Creates and returns a searcher that can be used to execute arbitrary Lucene queries + /// and to collect the resulting query results as hits. + /// @return a searcher + IndexSearcherPtr createSearcher(); + + /// Convenience method that efficiently returns the relevance score by matching this index + /// against the given Lucene query expression. + /// @param query An arbitrary Lucene query to run against this index + /// @return the relevance score of the matchmaking; A number in the range [0.0 .. 1.0], + /// with 0.0 indicating no match. The higher the number the better the match. + double search(const QueryPtr& query); + +protected: + int32_t numPositions(Collection positions); + + /// sorts into ascending order (on demand), reusing memory along the way + void sortFields(); + + friend class MemoryIndexReader; + friend class MemoryIndexInfo; + friend class MemoryIndexTermEnum; + friend class MemoryIndexTermPositions; + friend class MemoryIndexTermPositionVector; +}; + +/// Index data structure for a field; Contains the tokenized term texts and their positions. +class LPPCONTRIBAPI MemoryIndexInfo : public LuceneObject { +public: + MemoryIndexInfo(MapStringIntCollection terms, int32_t numTokens, int32_t numOverlapTokens, double boost); + virtual ~MemoryIndexInfo(); + + LUCENE_CLASS(MemoryIndexInfo); + +protected: + /// Term strings and their positions for this field + MapStringIntCollection terms; + + /// Terms sorted ascending by term text; computed on demand + CollectionStringIntCollection sortedTerms; + + /// Number of added tokens for this field + int32_t numTokens; + + /// Number of overlapping tokens for this field + int32_t numOverlapTokens; + + /// Boost factor for hits for this field + double boost; + + /// Term for this field's fieldName, lazily computed on demand + TermPtr _template; + +public: + /// Sorts hashed terms into ascending order, reusing memory along the way. Note that + /// sorting is lazily delayed until required (often it's not required at all). + void sortTerms(); + + /// Note that the frequency can be calculated as numPosition(getPositions(x)) + Collection getPositions(const String& term); + + /// Note that the frequency can be calculated as numPosition(getPositions(x)) + Collection getPositions(int32_t pos); + + double getBoost(); + + friend class MemoryIndexReader; + friend class MemoryIndexTermEnum; + friend class MemoryIndexTermPositions; + friend class MemoryIndexTermPositionVector; +}; + +/// Search support for Lucene framework integration; implements all methods required by the +/// Lucene IndexReader contracts. +class LPPCONTRIBAPI MemoryIndexReader : public IndexReader { +public: + MemoryIndexReader(const MemoryIndexPtr& memoryIndex); + virtual ~MemoryIndexReader(); + + LUCENE_CLASS(MemoryIndexReader); + +public: + static TermPtr MATCH_ALL_TERM(); + +protected: + MemoryIndexPtr memoryIndex; + SearcherWeakPtr _searcher; // needed to find searcher.getSimilarity() + + /// cache norms to avoid repeated expensive calculations + ByteArray cachedNorms; + String cachedFieldName; + SimilarityPtr cachedSimilarity; + +protected: + MemoryIndexInfoPtr getInfo(const String& fieldName); + MemoryIndexInfoPtr getInfo(int32_t pos); + + SimilarityPtr getSimilarity(); + void setSearcher(const SearcherPtr& searcher); + +public: + virtual int32_t docFreq(const TermPtr& t); + virtual TermEnumPtr terms(); + virtual TermEnumPtr terms(const TermPtr& t); + virtual TermPositionsPtr termPositions(); + virtual TermDocsPtr termDocs(); + virtual Collection getTermFreqVectors(int32_t docNumber); + virtual void getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper); + virtual void getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper); + virtual TermFreqVectorPtr getTermFreqVector(int32_t docNumber, const String& field); + virtual ByteArray norms(const String& field); + virtual void norms(const String& field, ByteArray norms, int32_t offset); + virtual void doSetNorm(int32_t doc, const String& field, uint8_t value); + virtual int32_t numDocs(); + virtual int32_t maxDoc(); + virtual DocumentPtr document(int32_t n); + virtual DocumentPtr document(int32_t n, const FieldSelectorPtr& fieldSelector); + virtual bool isDeleted(int32_t n); + virtual bool hasDeletions(); + virtual void doDelete(int32_t docNum); + virtual void doUndeleteAll(); + virtual void doCommit(MapStringString commitUserData); + virtual void doClose(); + virtual HashSet getFieldNames(FieldOption fieldOption); + + friend class MemoryIndex; + friend class MemoryIndexTermEnum; + friend class MemoryIndexTermPositions; + friend class MemoryIndexTermPositionVector; +}; + +class LPPCONTRIBAPI MemoryIndexTermEnum : public TermEnum { +public: + MemoryIndexTermEnum(const MemoryIndexReaderPtr& reader, int32_t ix, int32_t jx); + virtual ~MemoryIndexTermEnum(); + + LUCENE_CLASS(MemoryIndexTermEnum); + +protected: + MemoryIndexReaderWeakPtr _reader; + int32_t i; + int32_t j; + +public: + virtual bool next(); + virtual TermPtr term(); + virtual int32_t docFreq(); + virtual void close(); + +protected: + TermPtr createTerm(const MemoryIndexInfoPtr& info, int32_t pos, const String& text); +}; + +class LPPCONTRIBAPI MemoryIndexCollector : public Collector { +public: + MemoryIndexCollector(Collection scores); + virtual ~MemoryIndexCollector(); + + LUCENE_CLASS(MemoryIndexCollector); + +protected: + Collection scores; + ScorerPtr scorer; + +public: + virtual void collect(int32_t doc); + virtual void setScorer(const ScorerPtr& scorer); + virtual bool acceptsDocsOutOfOrder(); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); +}; + +class LPPCONTRIBAPI MemoryIndexTermPositions : public TermPositions, public LuceneObject { +public: + MemoryIndexTermPositions(const MemoryIndexReaderPtr& reader); + virtual ~MemoryIndexTermPositions(); + + LUCENE_CLASS(MemoryIndexTermPositions); + +protected: + MemoryIndexReaderWeakPtr _reader; + bool hasNext; + int32_t cursor; + Collection current; + TermPtr term; + +public: + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); + virtual int32_t doc(); + virtual int32_t freq(); + virtual bool next(); + virtual int32_t read(Collection docs, Collection freqs); + virtual bool skipTo(int32_t target); + virtual void close(); + + virtual int32_t nextPosition(); + virtual int32_t getPayloadLength(); + virtual ByteArray getPayload(ByteArray data, int32_t offset); + virtual bool isPayloadAvailable(); +}; + +class MemoryIndexTermPositionVector : public TermPositionVector, public LuceneObject { +public: + MemoryIndexTermPositionVector(const MemoryIndexReaderPtr& reader, const MemoryIndexInfoPtr& info, const String& fieldName); + virtual ~MemoryIndexTermPositionVector(); + + LUCENE_CLASS(MemoryIndexTermPositionVector); + +protected: + MemoryIndexReaderWeakPtr _reader; + CollectionStringIntCollection sortedTerms; + String fieldName; + +public: + virtual String getField(); + virtual int32_t size(); + virtual Collection getTerms(); + virtual Collection getTermFrequencies(); + virtual int32_t indexOf(const String& term); + virtual Collection indexesOf(Collection terms, int32_t start, int32_t length); + + virtual Collection getTermPositions(int32_t index); + virtual Collection getOffsets(int32_t index); +}; + } #endif diff --git a/src/contrib/include/NullFragmenter.h b/src/contrib/include/NullFragmenter.h index 6b73d42d..7ab7386f 100644 --- a/src/contrib/include/NullFragmenter.h +++ b/src/contrib/include/NullFragmenter.h @@ -9,20 +9,20 @@ #include "Fragmenter.h" -namespace Lucene -{ - /// {@link Fragmenter} implementation which does not fragment the text. This is useful for - /// highlighting the entire content of a document or field. - class LPPCONTRIBAPI NullFragmenter : public Fragmenter, public LuceneObject - { - public: - virtual ~NullFragmenter(); - LUCENE_CLASS(NullFragmenter); +namespace Lucene { + +/// {@link Fragmenter} implementation which does not fragment the text. This is useful for +/// highlighting the entire content of a document or field. +class LPPCONTRIBAPI NullFragmenter : public Fragmenter, public LuceneObject { +public: + virtual ~NullFragmenter(); + LUCENE_CLASS(NullFragmenter); + +public: + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); + virtual bool isNewFragment(); +}; - public: - virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); - virtual bool isNewFragment(); - }; } #endif diff --git a/src/contrib/include/PersianAnalyzer.h b/src/contrib/include/PersianAnalyzer.h index f3632ba8..7a0ae59b 100644 --- a/src/contrib/include/PersianAnalyzer.h +++ b/src/contrib/include/PersianAnalyzer.h @@ -10,71 +10,70 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for Persian. +namespace Lucene { + +/// {@link Analyzer} for Persian. +/// +/// This Analyzer uses {@link ArabicLetterTokenizer} which implies tokenizing around +/// zero-width non-joiner in addition to whitespace. Some persian-specific variant +/// forms (such as farsi yeh and keheh) are standardized. "Stemming" is accomplished +/// via stopwords. +class LPPCONTRIBAPI PersianAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + PersianAnalyzer(LuceneVersion::Version matchVersion); + + /// Builds an analyzer with the given stop words. + PersianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + + virtual ~PersianAnalyzer(); + + LUCENE_CLASS(PersianAnalyzer); + +public: + /// Default Persian stopwords in UTF-8 format. + /// + /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html + /// The stopword list is BSD-Licensed. + static const uint8_t DEFAULT_STOPWORD_FILE[]; + +protected: + /// Contains the stopwords used with the StopFilter. + HashSet stoptable; + + LuceneVersion::Version matchVersion; + +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); + + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} + /// and Persian Stop words. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. /// - /// This Analyzer uses {@link ArabicLetterTokenizer} which implies tokenizing around - /// zero-width non-joiner in addition to whitespace. Some persian-specific variant - /// forms (such as farsi yeh and keheh) are standardized. "Stemming" is accomplished - /// via stopwords. - class LPPCONTRIBAPI PersianAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - PersianAnalyzer(LuceneVersion::Version matchVersion); - - /// Builds an analyzer with the given stop words. - PersianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - - virtual ~PersianAnalyzer(); - - LUCENE_CLASS(PersianAnalyzer); - - public: - /// Default Persian stopwords in UTF-8 format. - /// - /// Generated from http://members.unine.ch/jacques.savoy/clef/index.html - /// The stopword list is BSD-Licensed. - static const uint8_t DEFAULT_STOPWORD_FILE[]; - - protected: - /// Contains the stopwords used with the StopFilter. - HashSet stoptable; - - LuceneVersion::Version matchVersion; - - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); - - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} - /// and Persian Stop words. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with - /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} - /// and Persian Stop words. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI PersianAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~PersianAnalyzerSavedStreams(); - - LUCENE_CLASS(PersianAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; + /// @return A {@link TokenStream} built from an {@link ArabicLetterTokenizer} filtered with + /// {@link LowerCaseFilter}, {@link ArabicNormalizationFilter}, {@link PersianNormalizationFilter} + /// and Persian Stop words. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI PersianAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~PersianAnalyzerSavedStreams(); + + LUCENE_CLASS(PersianAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/PersianNormalizationFilter.h b/src/contrib/include/PersianNormalizationFilter.h index 6b68c908..3ad23728 100644 --- a/src/contrib/include/PersianNormalizationFilter.h +++ b/src/contrib/include/PersianNormalizationFilter.h @@ -10,24 +10,24 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that applies {@link PersianNormalizer} to normalize the orthography. - class LPPCONTRIBAPI PersianNormalizationFilter : public TokenFilter - { - public: - PersianNormalizationFilter(const TokenStreamPtr& input); - virtual ~PersianNormalizationFilter(); - - LUCENE_CLASS(PersianNormalizationFilter); - - protected: - PersianNormalizerPtr normalizer; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - }; +namespace Lucene { + +/// A {@link TokenFilter} that applies {@link PersianNormalizer} to normalize the orthography. +class LPPCONTRIBAPI PersianNormalizationFilter : public TokenFilter { +public: + PersianNormalizationFilter(const TokenStreamPtr& input); + virtual ~PersianNormalizationFilter(); + + LUCENE_CLASS(PersianNormalizationFilter); + +protected: + PersianNormalizerPtr normalizer; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; + } #endif diff --git a/src/contrib/include/PersianNormalizer.h b/src/contrib/include/PersianNormalizer.h index 4e1b692b..f12f9b5b 100644 --- a/src/contrib/include/PersianNormalizer.h +++ b/src/contrib/include/PersianNormalizer.h @@ -10,50 +10,50 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Normalizer for Persian. - /// - /// Normalization is done in-place for efficiency, operating on a termbuffer. - /// - /// Normalization is defined as: - ///
        - ///
      • Normalization of various heh + hamza forms and heh goal to heh. - ///
      • Normalization of farsi yeh and yeh barree to arabic yeh. - ///
      • Normalization of persian keheh to arabic kaf. - ///
      - class LPPCONTRIBAPI PersianNormalizer : public LuceneObject - { - public: - virtual ~PersianNormalizer(); - - LUCENE_CLASS(PersianNormalizer); - - public: - static const wchar_t YEH; - static const wchar_t FARSI_YEH; - static const wchar_t YEH_BARREE; - static const wchar_t KEHEH; - static const wchar_t KAF; - static const wchar_t HAMZA_ABOVE; - static const wchar_t HEH_YEH; - static const wchar_t HEH_GOAL; - static const wchar_t HEH; - - public: - /// Normalize an input buffer of Persian text - /// @param s input buffer - /// @param len length of input buffer - /// @return length of input buffer after normalization - int32_t normalize(wchar_t* s, int32_t len); - - /// Delete a character in-place - /// @param s Input Buffer - /// @param pos Position of character to delete - /// @param len length of input buffer - /// @return length of input buffer after deletion - int32_t deleteChar(wchar_t* s, int32_t pos, int32_t len); - }; +namespace Lucene { + +/// Normalizer for Persian. +/// +/// Normalization is done in-place for efficiency, operating on a termbuffer. +/// +/// Normalization is defined as: +///
        +///
      • Normalization of various heh + hamza forms and heh goal to heh. +///
      • Normalization of farsi yeh and yeh barree to arabic yeh. +///
      • Normalization of persian keheh to arabic kaf. +///
      +class LPPCONTRIBAPI PersianNormalizer : public LuceneObject { +public: + virtual ~PersianNormalizer(); + + LUCENE_CLASS(PersianNormalizer); + +public: + static const wchar_t YEH; + static const wchar_t FARSI_YEH; + static const wchar_t YEH_BARREE; + static const wchar_t KEHEH; + static const wchar_t KAF; + static const wchar_t HAMZA_ABOVE; + static const wchar_t HEH_YEH; + static const wchar_t HEH_GOAL; + static const wchar_t HEH; + +public: + /// Normalize an input buffer of Persian text + /// @param s input buffer + /// @param len length of input buffer + /// @return length of input buffer after normalization + int32_t normalize(wchar_t* s, int32_t len); + + /// Delete a character in-place + /// @param s Input Buffer + /// @param pos Position of character to delete + /// @param len length of input buffer + /// @return length of input buffer after deletion + int32_t deleteChar(wchar_t* s, int32_t pos, int32_t len); +}; + } #endif diff --git a/src/contrib/include/QueryScorer.h b/src/contrib/include/QueryScorer.h index cf9f531c..9389d7bd 100644 --- a/src/contrib/include/QueryScorer.h +++ b/src/contrib/include/QueryScorer.h @@ -10,87 +10,87 @@ #include "LuceneContrib.h" #include "HighlighterScorer.h" -namespace Lucene -{ - /// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. - /// This class converts appropriate {@link Query}s to {@link SpanQuery}s and attempts to score only - /// those terms that participated in generating the 'hit' on the document. - class LPPCONTRIBAPI QueryScorer : public HighlighterScorer, public LuceneObject - { - public: - /// @param query Query to use for highlighting - QueryScorer(const QueryPtr& query); - - /// @param query Query to use for highlighting - /// @param field Field to highlight - pass empty string to ignore fields - QueryScorer(const QueryPtr& query, const String& field); - - /// @param query Query to use for highlighting - /// @param reader {@link IndexReader} to use for quasi tf/idf scoring - /// @param field Field to highlight - pass empty string to ignore fields - QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field); - - /// @param query Query to use for highlighting - /// @param reader {@link IndexReader} to use for quasi tf/idf scoring - /// @param field Field to highlight - pass empty string to ignore fields - /// @param defaultField - QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field, const String& defaultField); - - /// @param query Query to use for highlighting - /// @param field Field to highlight - pass empty string to ignore fields - /// @param defaultField - QueryScorer(const QueryPtr& query, const String& field, const String& defaultField); - - /// @param weightedTerms an array of pre-created {@link WeightedSpanTerm}s - QueryScorer(Collection weightedTerms); - - virtual ~QueryScorer(); - - LUCENE_CLASS(QueryScorer); - - protected: - double totalScore; - HashSet foundTerms; - MapWeightedSpanTermPtr fieldWeightedSpanTerms; - double maxTermWeight; - int32_t position; - String defaultField; - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncAtt; - bool expandMultiTermQuery; - QueryPtr query; - String field; - IndexReaderPtr reader; - bool skipInitExtractor; - bool wrapToCaching; - - protected: - void init(const QueryPtr& query, const String& field, const IndexReaderPtr& reader, bool expandMultiTermQuery); - TokenStreamPtr initExtractor(const TokenStreamPtr& tokenStream); - - public: - virtual double getFragmentScore(); - - /// @return The highest weighted term (useful for passing to GradientFormatter to set top end of coloring scale). - virtual double getMaxTermWeight(); - - virtual double getTokenScore(); - virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); - virtual WeightedSpanTermPtr getWeightedSpanTerm(const String& token); - virtual void startFragment(const TextFragmentPtr& newFragment); - - /// @return true if multi-term queries should be expanded - virtual bool isExpandMultiTermQuery(); - - /// Controls whether or not multi-term queries are expanded against a {@link MemoryIndex} {@link IndexReader}. - /// @param expandMultiTermQuery true if multi-term queries should be expanded - virtual void setExpandMultiTermQuery(bool expandMultiTermQuery); - - /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} are wrapped in a {@link - /// CachingTokenFilter} to ensure an efficient reset - if you are already using a different caching {@link - /// TokenStream} impl and you don't want it to be wrapped, set this to false. - virtual void setWrapIfNotCachingTokenFilter(bool wrap); - }; +namespace Lucene { + +/// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. +/// This class converts appropriate {@link Query}s to {@link SpanQuery}s and attempts to score only +/// those terms that participated in generating the 'hit' on the document. +class LPPCONTRIBAPI QueryScorer : public HighlighterScorer, public LuceneObject { +public: + /// @param query Query to use for highlighting + QueryScorer(const QueryPtr& query); + + /// @param query Query to use for highlighting + /// @param field Field to highlight - pass empty string to ignore fields + QueryScorer(const QueryPtr& query, const String& field); + + /// @param query Query to use for highlighting + /// @param reader {@link IndexReader} to use for quasi tf/idf scoring + /// @param field Field to highlight - pass empty string to ignore fields + QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field); + + /// @param query Query to use for highlighting + /// @param reader {@link IndexReader} to use for quasi tf/idf scoring + /// @param field Field to highlight - pass empty string to ignore fields + /// @param defaultField + QueryScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& field, const String& defaultField); + + /// @param query Query to use for highlighting + /// @param field Field to highlight - pass empty string to ignore fields + /// @param defaultField + QueryScorer(const QueryPtr& query, const String& field, const String& defaultField); + + /// @param weightedTerms an array of pre-created {@link WeightedSpanTerm}s + QueryScorer(Collection weightedTerms); + + virtual ~QueryScorer(); + + LUCENE_CLASS(QueryScorer); + +protected: + double totalScore; + HashSet foundTerms; + MapWeightedSpanTermPtr fieldWeightedSpanTerms; + double maxTermWeight; + int32_t position; + String defaultField; + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncAtt; + bool expandMultiTermQuery; + QueryPtr query; + String field; + IndexReaderPtr reader; + bool skipInitExtractor; + bool wrapToCaching; + +protected: + void init(const QueryPtr& query, const String& field, const IndexReaderPtr& reader, bool expandMultiTermQuery); + TokenStreamPtr initExtractor(const TokenStreamPtr& tokenStream); + +public: + virtual double getFragmentScore(); + + /// @return The highest weighted term (useful for passing to GradientFormatter to set top end of coloring scale). + virtual double getMaxTermWeight(); + + virtual double getTokenScore(); + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); + virtual WeightedSpanTermPtr getWeightedSpanTerm(const String& token); + virtual void startFragment(const TextFragmentPtr& newFragment); + + /// @return true if multi-term queries should be expanded + virtual bool isExpandMultiTermQuery(); + + /// Controls whether or not multi-term queries are expanded against a {@link MemoryIndex} {@link IndexReader}. + /// @param expandMultiTermQuery true if multi-term queries should be expanded + virtual void setExpandMultiTermQuery(bool expandMultiTermQuery); + + /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} are wrapped in a {@link + /// CachingTokenFilter} to ensure an efficient reset - if you are already using a different caching {@link + /// TokenStream} impl and you don't want it to be wrapped, set this to false. + virtual void setWrapIfNotCachingTokenFilter(bool wrap); +}; + } #endif diff --git a/src/contrib/include/QueryTermExtractor.h b/src/contrib/include/QueryTermExtractor.h index 18b5a3dd..b6bbabf6 100644 --- a/src/contrib/include/QueryTermExtractor.h +++ b/src/contrib/include/QueryTermExtractor.h @@ -10,59 +10,59 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Utility class used to extract the terms used in a query, plus any weights. This class will not - /// find terms for MultiTermQuery, TermRangeQuery and PrefixQuery classes so the caller must pass a - /// rewritten query (see Query.rewrite) to obtain a list of expanded terms. - class LPPCONTRIBAPI QueryTermExtractor : public LuceneObject - { - public: - virtual ~QueryTermExtractor(); - LUCENE_CLASS(QueryTermExtractor); +namespace Lucene { - public: - /// Extracts all terms texts of a given Query into an array of WeightedTerms - /// - /// @param query Query to extract term texts from. - /// @return an array of the terms used in a query, plus their weights. - static Collection getTerms(const QueryPtr& query); +/// Utility class used to extract the terms used in a query, plus any weights. This class will not +/// find terms for MultiTermQuery, TermRangeQuery and PrefixQuery classes so the caller must pass a +/// rewritten query (see Query.rewrite) to obtain a list of expanded terms. +class LPPCONTRIBAPI QueryTermExtractor : public LuceneObject { +public: + virtual ~QueryTermExtractor(); + LUCENE_CLASS(QueryTermExtractor); - /// Extracts all terms texts of a given Query into an array of WeightedTerms - /// - /// @param query Query to extract term texts from. - /// @param reader used to compute IDF which can be used to - /// a) score selected fragments better - /// b) use graded highlights eg changing intensity of font color - /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based. - /// @return an array of the terms used in a query, plus their weights. - static Collection getIdfWeightedTerms(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName); +public: + /// Extracts all terms texts of a given Query into an array of WeightedTerms + /// + /// @param query Query to extract term texts from. + /// @return an array of the terms used in a query, plus their weights. + static Collection getTerms(const QueryPtr& query); - /// Extracts all terms texts of a given Query into an array of WeightedTerms - /// - /// @param query Query to extract term texts from. - /// @param prohibited true to extract "prohibited" terms, too. - /// @param fieldName The fieldName used to filter query terms. - /// @return an array of the terms used in a query, plus their weights. - static Collection getTerms(const QueryPtr& query, bool prohibited, const String& fieldName); + /// Extracts all terms texts of a given Query into an array of WeightedTerms + /// + /// @param query Query to extract term texts from. + /// @param reader used to compute IDF which can be used to + /// a) score selected fragments better + /// b) use graded highlights eg changing intensity of font color + /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based. + /// @return an array of the terms used in a query, plus their weights. + static Collection getIdfWeightedTerms(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName); - /// Extracts all terms texts of a given Query into an array of WeightedTerms - /// - /// @param query Query to extract term texts from. - /// @param prohibited true to extract "prohibited" terms, too. - /// @return an array of the terms used in a query, plus their weights. - static Collection getTerms(const QueryPtr& query, bool prohibited); + /// Extracts all terms texts of a given Query into an array of WeightedTerms + /// + /// @param query Query to extract term texts from. + /// @param prohibited true to extract "prohibited" terms, too. + /// @param fieldName The fieldName used to filter query terms. + /// @return an array of the terms used in a query, plus their weights. + static Collection getTerms(const QueryPtr& query, bool prohibited, const String& fieldName); - static void getTerms(const QueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); + /// Extracts all terms texts of a given Query into an array of WeightedTerms + /// + /// @param query Query to extract term texts from. + /// @param prohibited true to extract "prohibited" terms, too. + /// @return an array of the terms used in a query, plus their weights. + static Collection getTerms(const QueryPtr& query, bool prohibited); + + static void getTerms(const QueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); + +protected: + /// extractTerms is currently the only query-independent means of introspecting queries but it only reveals + /// a list of terms for that query - not the boosts each individual term in that query may or may not have. + /// "Container" queries such as BooleanQuery should be unwrapped to get at the boost info held in each child + /// element. + static void getTermsFromBooleanQuery(const BooleanQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); + static void getTermsFromFilteredQuery(const FilteredQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); +}; - protected: - /// extractTerms is currently the only query-independent means of introspecting queries but it only reveals - /// a list of terms for that query - not the boosts each individual term in that query may or may not have. - /// "Container" queries such as BooleanQuery should be unwrapped to get at the boost info held in each child - /// element. - static void getTermsFromBooleanQuery(const BooleanQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); - static void getTermsFromFilteredQuery(const FilteredQueryPtr& query, SetWeightedTerm terms, bool prohibited, const String& fieldName); - }; } #endif diff --git a/src/contrib/include/QueryTermScorer.h b/src/contrib/include/QueryTermScorer.h index d73d6e27..9a1c1fa6 100644 --- a/src/contrib/include/QueryTermScorer.h +++ b/src/contrib/include/QueryTermScorer.h @@ -10,62 +10,62 @@ #include "LuceneContrib.h" #include "HighlighterScorer.h" -namespace Lucene -{ - /// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. - /// This class uses the {@link QueryTermExtractor} class to process determine the query terms and their - /// boosts to be used. - class LPPCONTRIBAPI QueryTermScorer : public HighlighterScorer, public LuceneObject - { - public: - /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class - /// and the searcher) - QueryTermScorer(const QueryPtr& query); - - /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class - /// and the searcher) - /// @param fieldName the Field name which is used to match Query terms - QueryTermScorer(const QueryPtr& query, const String& fieldName); - - /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class - /// and the searcher) - /// @param reader used to compute IDF which can be used to - /// a) score selected fragments better - /// b) use graded highlights eg set font color intensity - /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based - QueryTermScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName); - - /// @param weightedTerms an array of pre-created {@link WeightedTerm}s - QueryTermScorer(Collection weightedTerms); - - virtual ~QueryTermScorer(); - - LUCENE_CLASS(QueryTermScorer); - - public: - TextFragmentPtr currentTextFragment; - HashSet uniqueTermsInFragment; - - double totalScore; - double maxTermWeight; - - protected: - MapStringWeightedTerm termsToFind; - TermAttributePtr termAtt; - - protected: - void ConstructQueryTermScorer(Collection weightedTerms); - - public: - virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); - virtual void startFragment(const TextFragmentPtr& newFragment); - virtual double getTokenScore(); - virtual double getFragmentScore(); - virtual void allFragmentsProcessed(); - - /// @return The highest weighted term (useful for passing to GradientFormatter to set top end of coloring scale. - virtual double getMaxTermWeight(); - }; +namespace Lucene { + +/// {@link HighlighterScorer} implementation which scores text fragments by the number of unique query terms found. +/// This class uses the {@link QueryTermExtractor} class to process determine the query terms and their +/// boosts to be used. +class LPPCONTRIBAPI QueryTermScorer : public HighlighterScorer, public LuceneObject { +public: + /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class + /// and the searcher) + QueryTermScorer(const QueryPtr& query); + + /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class + /// and the searcher) + /// @param fieldName the Field name which is used to match Query terms + QueryTermScorer(const QueryPtr& query, const String& fieldName); + + /// @param query a Lucene query (ideally rewritten using query.rewrite before being passed to this class + /// and the searcher) + /// @param reader used to compute IDF which can be used to + /// a) score selected fragments better + /// b) use graded highlights eg set font color intensity + /// @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based + QueryTermScorer(const QueryPtr& query, const IndexReaderPtr& reader, const String& fieldName); + + /// @param weightedTerms an array of pre-created {@link WeightedTerm}s + QueryTermScorer(Collection weightedTerms); + + virtual ~QueryTermScorer(); + + LUCENE_CLASS(QueryTermScorer); + +public: + TextFragmentPtr currentTextFragment; + HashSet uniqueTermsInFragment; + + double totalScore; + double maxTermWeight; + +protected: + MapStringWeightedTerm termsToFind; + TermAttributePtr termAtt; + +protected: + void ConstructQueryTermScorer(Collection weightedTerms); + +public: + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream); + virtual void startFragment(const TextFragmentPtr& newFragment); + virtual double getTokenScore(); + virtual double getFragmentScore(); + virtual void allFragmentsProcessed(); + + /// @return The highest weighted term (useful for passing to GradientFormatter to set top end of coloring scale. + virtual double getMaxTermWeight(); +}; + } #endif diff --git a/src/contrib/include/ReverseStringFilter.h b/src/contrib/include/ReverseStringFilter.h index ba0c6b54..20124e5e 100644 --- a/src/contrib/include/ReverseStringFilter.h +++ b/src/contrib/include/ReverseStringFilter.h @@ -9,53 +9,53 @@ #include "TokenFilter.h" -namespace Lucene -{ - /// Reverse token string, for example "country" => "yrtnuoc". +namespace Lucene { + +/// Reverse token string, for example "country" => "yrtnuoc". +/// +/// If marker is supplied, then tokens will be also prepended by that character. For example, with a +/// marker of \u0001, "country" => "\u0001yrtnuoc". This is useful when implementing efficient +/// leading wildcards search. +class LPPCONTRIBAPI ReverseStringFilter : public TokenFilter { +public: + /// Create a new ReverseStringFilter that reverses all tokens in the supplied {@link TokenStream}. /// - /// If marker is supplied, then tokens will be also prepended by that character. For example, with a - /// marker of \u0001, "country" => "\u0001yrtnuoc". This is useful when implementing efficient - /// leading wildcards search. - class LPPCONTRIBAPI ReverseStringFilter : public TokenFilter - { - public: - /// Create a new ReverseStringFilter that reverses all tokens in the supplied {@link TokenStream}. - /// - /// The reversed tokens will not be marked. - ReverseStringFilter(const TokenStreamPtr& input); + /// The reversed tokens will not be marked. + ReverseStringFilter(const TokenStreamPtr& input); - /// Create a new ReverseStringFilter that reverses and marks all tokens in the supplied {@link - /// TokenStream}. - /// - /// The reversed tokens will be prepended (marked) by the marker character. - ReverseStringFilter(const TokenStreamPtr& input, wchar_t marker); + /// Create a new ReverseStringFilter that reverses and marks all tokens in the supplied {@link + /// TokenStream}. + /// + /// The reversed tokens will be prepended (marked) by the marker character. + ReverseStringFilter(const TokenStreamPtr& input, wchar_t marker); + + virtual ~ReverseStringFilter(); - virtual ~ReverseStringFilter(); + LUCENE_CLASS(ReverseStringFilter); - LUCENE_CLASS(ReverseStringFilter); +protected: + TermAttributePtr termAtt; + wchar_t marker; - protected: - TermAttributePtr termAtt; - wchar_t marker; + static const wchar_t NOMARKER; - static const wchar_t NOMARKER; +public: + /// Example marker character: U+0001 (START OF HEADING) + static const wchar_t START_OF_HEADING_MARKER; - public: - /// Example marker character: U+0001 (START OF HEADING) - static const wchar_t START_OF_HEADING_MARKER; + /// Example marker character: U+001F (INFORMATION SEPARATOR ONE) + static const wchar_t INFORMATION_SEPARATOR_MARKER; - /// Example marker character: U+001F (INFORMATION SEPARATOR ONE) - static const wchar_t INFORMATION_SEPARATOR_MARKER; + /// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) + static const wchar_t PUA_EC00_MARKER; - /// Example marker character: U+EC00 (PRIVATE USE AREA: EC00) - static const wchar_t PUA_EC00_MARKER; + /// Example marker character: U+200F (RIGHT-TO-LEFT MARK) + static const wchar_t RTL_DIRECTION_MARKER; - /// Example marker character: U+200F (RIGHT-TO-LEFT MARK) - static const wchar_t RTL_DIRECTION_MARKER; +public: + virtual bool incrementToken(); +}; - public: - virtual bool incrementToken(); - }; } #endif diff --git a/src/contrib/include/RussianAnalyzer.h b/src/contrib/include/RussianAnalyzer.h index 413ef2d7..86f8aebd 100644 --- a/src/contrib/include/RussianAnalyzer.h +++ b/src/contrib/include/RussianAnalyzer.h @@ -10,63 +10,62 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// {@link Analyzer} for Russian language. +namespace Lucene { + +/// {@link Analyzer} for Russian language. +/// +/// Supports an external list of stopwords (words that will not be indexed at all). +/// A default set of stopwords is used unless an alternative list is specified. +class LPPCONTRIBAPI RussianAnalyzer : public Analyzer { +public: + /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. + RussianAnalyzer(LuceneVersion::Version matchVersion); + + /// Builds an analyzer with the given stop words. + RussianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); + + virtual ~RussianAnalyzer(); + + LUCENE_CLASS(RussianAnalyzer); + +protected: + /// Contains the stopwords used with the {@link StopFilter}. + HashSet stopSet; + + LuceneVersion::Version matchVersion; + + /// List of typical Russian stopwords. + static const uint8_t DEFAULT_STOPWORD_FILE[]; + +public: + /// Returns an unmodifiable instance of the default stop-words set. + static const HashSet getDefaultStopSet(); + + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with + /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. /// - /// Supports an external list of stopwords (words that will not be indexed at all). - /// A default set of stopwords is used unless an alternative list is specified. - class LPPCONTRIBAPI RussianAnalyzer : public Analyzer - { - public: - /// Builds an analyzer with the default stop words: {@link #getDefaultStopSet}. - RussianAnalyzer(LuceneVersion::Version matchVersion); - - /// Builds an analyzer with the given stop words. - RussianAnalyzer(LuceneVersion::Version matchVersion, HashSet stopwords); - - virtual ~RussianAnalyzer(); - - LUCENE_CLASS(RussianAnalyzer); - - protected: - /// Contains the stopwords used with the {@link StopFilter}. - HashSet stopSet; - - LuceneVersion::Version matchVersion; - - /// List of typical Russian stopwords. - static const uint8_t DEFAULT_STOPWORD_FILE[]; - - public: - /// Returns an unmodifiable instance of the default stop-words set. - static const HashSet getDefaultStopSet(); - - /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with - /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the - /// provided {@link Reader}. - /// - /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with - /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI RussianAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~RussianAnalyzerSavedStreams(); - - LUCENE_CLASS(RussianAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; + /// @return A {@link TokenStream} built from a {@link RussianLetterTokenizer} filtered with + /// {@link RussianLowerCaseFilter}, {@link StopFilter} and {@link RussianStemFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI RussianAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~RussianAnalyzerSavedStreams(); + + LUCENE_CLASS(RussianAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/RussianLetterTokenizer.h b/src/contrib/include/RussianLetterTokenizer.h index a646c788..5bbe1544 100644 --- a/src/contrib/include/RussianLetterTokenizer.h +++ b/src/contrib/include/RussianLetterTokenizer.h @@ -9,30 +9,30 @@ #include "CharTokenizer.h" -namespace Lucene -{ - /// A RussianLetterTokenizer is a {@link Tokenizer} that extends {@link LetterTokenizer} by also - /// allowing the basic Latin digits 0-9. - class LPPCONTRIBAPI RussianLetterTokenizer : public CharTokenizer - { - public: - /// Construct a new RussianLetterTokenizer. - RussianLetterTokenizer(const ReaderPtr& input); - - /// Construct a new RussianLetterTokenizer using a given {@link AttributeSource}. - RussianLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); - - /// Construct a new RussianLetterTokenizer using a given {@link AttributeFactory}. - RussianLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); - - virtual ~RussianLetterTokenizer(); - - LUCENE_CLASS(RussianLetterTokenizer); - - public: - /// Collects only characters which satisfy UnicodeUtil::isAlpha(c). - virtual bool isTokenChar(wchar_t c); - }; +namespace Lucene { + +/// A RussianLetterTokenizer is a {@link Tokenizer} that extends {@link LetterTokenizer} by also +/// allowing the basic Latin digits 0-9. +class LPPCONTRIBAPI RussianLetterTokenizer : public CharTokenizer { +public: + /// Construct a new RussianLetterTokenizer. + RussianLetterTokenizer(const ReaderPtr& input); + + /// Construct a new RussianLetterTokenizer using a given {@link AttributeSource}. + RussianLetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input); + + /// Construct a new RussianLetterTokenizer using a given {@link AttributeFactory}. + RussianLetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input); + + virtual ~RussianLetterTokenizer(); + + LUCENE_CLASS(RussianLetterTokenizer); + +public: + /// Collects only characters which satisfy UnicodeUtil::isAlpha(c). + virtual bool isTokenChar(wchar_t c); +}; + } #endif diff --git a/src/contrib/include/RussianLowerCaseFilter.h b/src/contrib/include/RussianLowerCaseFilter.h index a7eb56f9..6fffec0f 100644 --- a/src/contrib/include/RussianLowerCaseFilter.h +++ b/src/contrib/include/RussianLowerCaseFilter.h @@ -10,24 +10,24 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// Normalizes token text to lower case. - class LPPCONTRIBAPI RussianLowerCaseFilter : public TokenFilter - { - public: - RussianLowerCaseFilter(const TokenStreamPtr& input); +namespace Lucene { - virtual ~RussianLowerCaseFilter(); +/// Normalizes token text to lower case. +class LPPCONTRIBAPI RussianLowerCaseFilter : public TokenFilter { +public: + RussianLowerCaseFilter(const TokenStreamPtr& input); - LUCENE_CLASS(RussianLowerCaseFilter); + virtual ~RussianLowerCaseFilter(); - protected: - TermAttributePtr termAtt; + LUCENE_CLASS(RussianLowerCaseFilter); + +protected: + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; - public: - virtual bool incrementToken(); - }; } #endif diff --git a/src/contrib/include/RussianStemFilter.h b/src/contrib/include/RussianStemFilter.h index 4a695d97..72e05c30 100644 --- a/src/contrib/include/RussianStemFilter.h +++ b/src/contrib/include/RussianStemFilter.h @@ -10,35 +10,35 @@ #include "LuceneContrib.h" #include "TokenFilter.h" -namespace Lucene -{ - /// A {@link TokenFilter} that stems Russian words. - /// - /// The implementation was inspired by GermanStemFilter. - /// - /// The input should be filtered by {@link LowerCaseFilter} before passing it to RussianStemFilter, - /// because RussianStemFilter only works with lowercase characters. - class LPPCONTRIBAPI RussianStemFilter : public TokenFilter - { - public: - RussianStemFilter(const TokenStreamPtr& input); - - virtual ~RussianStemFilter(); - - LUCENE_CLASS(RussianStemFilter); - - protected: - /// {@link RussianStemmer} in use by this filter. - RussianStemmerPtr stemmer; - - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - - /// Set a alternative/custom {@link RussianStemmer} for this filter. - void setStemmer(const RussianStemmerPtr& stemmer); - }; +namespace Lucene { + +/// A {@link TokenFilter} that stems Russian words. +/// +/// The implementation was inspired by GermanStemFilter. +/// +/// The input should be filtered by {@link LowerCaseFilter} before passing it to RussianStemFilter, +/// because RussianStemFilter only works with lowercase characters. +class LPPCONTRIBAPI RussianStemFilter : public TokenFilter { +public: + RussianStemFilter(const TokenStreamPtr& input); + + virtual ~RussianStemFilter(); + + LUCENE_CLASS(RussianStemFilter); + +protected: + /// {@link RussianStemmer} in use by this filter. + RussianStemmerPtr stemmer; + + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); + + /// Set a alternative/custom {@link RussianStemmer} for this filter. + void setStemmer(const RussianStemmerPtr& stemmer); +}; + } #endif diff --git a/src/contrib/include/RussianStemmer.h b/src/contrib/include/RussianStemmer.h index fef8e0ce..5b5e12d4 100644 --- a/src/contrib/include/RussianStemmer.h +++ b/src/contrib/include/RussianStemmer.h @@ -10,117 +10,117 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Russian stemming algorithm implementation (see http://snowball.sourceforge.net for - /// detailed description). - class LPPCONTRIBAPI RussianStemmer : public LuceneObject - { - public: - RussianStemmer(); - virtual ~RussianStemmer(); - - LUCENE_CLASS(RussianStemmer); - - protected: - /// positions of RV, R1 and R2 respectively - int32_t RV; - int32_t R1; - int32_t R2; - - static const wchar_t A; - static const wchar_t V; - static const wchar_t G; - static const wchar_t E; - static const wchar_t I; - static const wchar_t I_; - static const wchar_t L; - static const wchar_t M; - static const wchar_t N; - static const wchar_t O; - static const wchar_t S; - static const wchar_t T; - static const wchar_t U; - static const wchar_t X; - static const wchar_t SH; - static const wchar_t SHCH; - static const wchar_t Y; - static const wchar_t SOFT; - static const wchar_t AE; - static const wchar_t IU; - static const wchar_t IA; - - /// stem definitions - static const wchar_t vowels[]; - - Collection perfectiveGerundEndings1(); - Collection perfectiveGerund1Predessors(); - Collection perfectiveGerundEndings2(); - Collection adjectiveEndings(); - Collection participleEndings1(); - Collection participleEndings2(); - Collection participle1Predessors(); - Collection reflexiveEndings(); - Collection verbEndings1(); - Collection verbEndings2(); - Collection verb1Predessors(); - Collection nounEndings(); - Collection superlativeEndings(); - Collection derivationalEndings(); - Collection doubleN(); - - public: - /// Finds the stem for given Russian word. - String stem(const String& input); - - /// Static method for stemming. - static String stemWord(const String& word); - - protected: - /// Adjectival ending is an adjective ending, optionally preceded by participle ending. - bool adjectival(String& stemmingZone); - - /// Derivational endings - bool derivational(String& stemmingZone); - - /// Finds ending among given ending class and returns the length of ending found(0, if not found). - int32_t findEnding(String& stemmingZone, int32_t startIndex, Collection theEndingClass); - int32_t findEnding(String& stemmingZone, Collection theEndingClass); - - /// Finds the ending among the given class of endings and removes it from stemming zone. - bool findAndRemoveEnding(String& stemmingZone, Collection theEndingClass); - - /// Finds the ending among the given class of endings, then checks if this ending was - /// preceded by any of given predecessors, and if so, removes it from stemming zone. - bool findAndRemoveEnding(String& stemmingZone, Collection theEndingClass, Collection thePredessors); - - /// Marks positions of RV, R1 and R2 in a given word. - void markPositions(const String& word); - - /// Checks if character is a vowel. - bool isVowel(wchar_t letter); - - /// Noun endings. - bool noun(String& stemmingZone); - - /// Perfective gerund endings. - bool perfectiveGerund(String& stemmingZone); - - /// Reflexive endings. - bool reflexive(String& stemmingZone); - - bool removeI(String& stemmingZone); - bool removeSoft(String& stemmingZone); - - /// Superlative endings. - bool superlative(String& stemmingZone); - - /// Undoubles N. - bool undoubleN(String& stemmingZone); - - /// Verb endings. - bool verb(String& stemmingZone); - }; +namespace Lucene { + +/// Russian stemming algorithm implementation (see http://snowball.sourceforge.net for +/// detailed description). +class LPPCONTRIBAPI RussianStemmer : public LuceneObject { +public: + RussianStemmer(); + virtual ~RussianStemmer(); + + LUCENE_CLASS(RussianStemmer); + +protected: + /// positions of RV, R1 and R2 respectively + int32_t RV; + int32_t R1; + int32_t R2; + + static const wchar_t A; + static const wchar_t V; + static const wchar_t G; + static const wchar_t E; + static const wchar_t I; + static const wchar_t I_; + static const wchar_t L; + static const wchar_t M; + static const wchar_t N; + static const wchar_t O; + static const wchar_t S; + static const wchar_t T; + static const wchar_t U; + static const wchar_t X; + static const wchar_t SH; + static const wchar_t SHCH; + static const wchar_t Y; + static const wchar_t SOFT; + static const wchar_t AE; + static const wchar_t IU; + static const wchar_t IA; + + /// stem definitions + static const wchar_t vowels[]; + + Collection perfectiveGerundEndings1(); + Collection perfectiveGerund1Predessors(); + Collection perfectiveGerundEndings2(); + Collection adjectiveEndings(); + Collection participleEndings1(); + Collection participleEndings2(); + Collection participle1Predessors(); + Collection reflexiveEndings(); + Collection verbEndings1(); + Collection verbEndings2(); + Collection verb1Predessors(); + Collection nounEndings(); + Collection superlativeEndings(); + Collection derivationalEndings(); + Collection doubleN(); + +public: + /// Finds the stem for given Russian word. + String stem(const String& input); + + /// Static method for stemming. + static String stemWord(const String& word); + +protected: + /// Adjectival ending is an adjective ending, optionally preceded by participle ending. + bool adjectival(String& stemmingZone); + + /// Derivational endings + bool derivational(String& stemmingZone); + + /// Finds ending among given ending class and returns the length of ending found(0, if not found). + int32_t findEnding(String& stemmingZone, int32_t startIndex, Collection theEndingClass); + int32_t findEnding(String& stemmingZone, Collection theEndingClass); + + /// Finds the ending among the given class of endings and removes it from stemming zone. + bool findAndRemoveEnding(String& stemmingZone, Collection theEndingClass); + + /// Finds the ending among the given class of endings, then checks if this ending was + /// preceded by any of given predecessors, and if so, removes it from stemming zone. + bool findAndRemoveEnding(String& stemmingZone, Collection theEndingClass, Collection thePredessors); + + /// Marks positions of RV, R1 and R2 in a given word. + void markPositions(const String& word); + + /// Checks if character is a vowel. + bool isVowel(wchar_t letter); + + /// Noun endings. + bool noun(String& stemmingZone); + + /// Perfective gerund endings. + bool perfectiveGerund(String& stemmingZone); + + /// Reflexive endings. + bool reflexive(String& stemmingZone); + + bool removeI(String& stemmingZone); + bool removeSoft(String& stemmingZone); + + /// Superlative endings. + bool superlative(String& stemmingZone); + + /// Undoubles N. + bool undoubleN(String& stemmingZone); + + /// Verb endings. + bool verb(String& stemmingZone); +}; + } #endif diff --git a/src/contrib/include/SimpleFragmenter.h b/src/contrib/include/SimpleFragmenter.h index 3e310e2e..1d61077c 100644 --- a/src/contrib/include/SimpleFragmenter.h +++ b/src/contrib/include/SimpleFragmenter.h @@ -9,36 +9,36 @@ #include "Fragmenter.h" -namespace Lucene -{ - /// {@link Fragmenter} implementation which breaks text up into same-size fragments with - /// no concerns over spotting sentence boundaries. - class LPPCONTRIBAPI SimpleFragmenter : public Fragmenter, public LuceneObject - { - public: - SimpleFragmenter(); - SimpleFragmenter(int32_t fragmentSize); - - virtual ~SimpleFragmenter(); - - LUCENE_CLASS(SimpleFragmenter); - - protected: - static const int32_t DEFAULT_FRAGMENT_SIZE; - int32_t currentNumFrags; - int32_t fragmentSize; - OffsetAttributePtr offsetAtt; - - public: - virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); - virtual bool isNewFragment(); - - /// @return size in number of characters of each fragment - int32_t getFragmentSize(); - - /// @param size size in characters of each fragment - void setFragmentSize(int32_t size); - }; +namespace Lucene { + +/// {@link Fragmenter} implementation which breaks text up into same-size fragments with +/// no concerns over spotting sentence boundaries. +class LPPCONTRIBAPI SimpleFragmenter : public Fragmenter, public LuceneObject { +public: + SimpleFragmenter(); + SimpleFragmenter(int32_t fragmentSize); + + virtual ~SimpleFragmenter(); + + LUCENE_CLASS(SimpleFragmenter); + +protected: + static const int32_t DEFAULT_FRAGMENT_SIZE; + int32_t currentNumFrags; + int32_t fragmentSize; + OffsetAttributePtr offsetAtt; + +public: + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); + virtual bool isNewFragment(); + + /// @return size in number of characters of each fragment + int32_t getFragmentSize(); + + /// @param size size in characters of each fragment + void setFragmentSize(int32_t size); +}; + } #endif diff --git a/src/contrib/include/SimpleHTMLEncoder.h b/src/contrib/include/SimpleHTMLEncoder.h index c201a53e..8051209a 100644 --- a/src/contrib/include/SimpleHTMLEncoder.h +++ b/src/contrib/include/SimpleHTMLEncoder.h @@ -9,21 +9,21 @@ #include "Encoder.h" -namespace Lucene -{ - /// Simple {@link Encoder} implementation to escape text for HTML output. - class LPPCONTRIBAPI SimpleHTMLEncoder : public Encoder, public LuceneObject - { - public: - virtual ~SimpleHTMLEncoder(); - LUCENE_CLASS(SimpleHTMLEncoder); - - public: - virtual String encodeText(const String& originalText); - - /// Encode string into HTML - static String htmlEncode(const String& plainText); - }; +namespace Lucene { + +/// Simple {@link Encoder} implementation to escape text for HTML output. +class LPPCONTRIBAPI SimpleHTMLEncoder : public Encoder, public LuceneObject { +public: + virtual ~SimpleHTMLEncoder(); + LUCENE_CLASS(SimpleHTMLEncoder); + +public: + virtual String encodeText(const String& originalText); + + /// Encode string into HTML + static String htmlEncode(const String& plainText); +}; + } #endif diff --git a/src/contrib/include/SimpleHTMLFormatter.h b/src/contrib/include/SimpleHTMLFormatter.h index ea7de8d0..efdac7f6 100644 --- a/src/contrib/include/SimpleHTMLFormatter.h +++ b/src/contrib/include/SimpleHTMLFormatter.h @@ -9,31 +9,31 @@ #include "Formatter.h" -namespace Lucene -{ - /// Simple {@link Formatter} implementation to highlight terms with a pre and post tag. - class LPPCONTRIBAPI SimpleHTMLFormatter : public Formatter, public LuceneObject - { - public: - /// Default constructor uses HTML: <B> tags to markup terms. - SimpleHTMLFormatter(); +namespace Lucene { - SimpleHTMLFormatter(const String& preTag, const String& postTag); +/// Simple {@link Formatter} implementation to highlight terms with a pre and post tag. +class LPPCONTRIBAPI SimpleHTMLFormatter : public Formatter, public LuceneObject { +public: + /// Default constructor uses HTML: <B> tags to markup terms. + SimpleHTMLFormatter(); - virtual ~SimpleHTMLFormatter(); + SimpleHTMLFormatter(const String& preTag, const String& postTag); - LUCENE_CLASS(SimpleHTMLFormatter); + virtual ~SimpleHTMLFormatter(); - protected: - static const String DEFAULT_PRE_TAG; - static const String DEFAULT_POST_TAG; + LUCENE_CLASS(SimpleHTMLFormatter); - String preTag; - String postTag; +protected: + static const String DEFAULT_PRE_TAG; + static const String DEFAULT_POST_TAG; + + String preTag; + String postTag; + +public: + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); +}; - public: - virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); - }; } #endif diff --git a/src/contrib/include/SimpleSpanFragmenter.h b/src/contrib/include/SimpleSpanFragmenter.h index 293b3ebd..f058d8a8 100644 --- a/src/contrib/include/SimpleSpanFragmenter.h +++ b/src/contrib/include/SimpleSpanFragmenter.h @@ -9,41 +9,41 @@ #include "Fragmenter.h" -namespace Lucene -{ - /// {@link Fragmenter} implementation which breaks text up into same-size fragments but - /// does not split up {@link Spans}. This is a simple sample class. - class LPPCONTRIBAPI SimpleSpanFragmenter : public Fragmenter, public LuceneObject - { - public: - /// @param queryScorer QueryScorer that was used to score hits - SimpleSpanFragmenter(const QueryScorerPtr& queryScorer); - - /// @param queryScorer QueryScorer that was used to score hits - /// @param fragmentSize size in bytes of each fragment - SimpleSpanFragmenter(const QueryScorerPtr& queryScorer, int32_t fragmentSize); - - virtual ~SimpleSpanFragmenter(); - - LUCENE_CLASS(SimpleSpanFragmenter); - - protected: - static const int32_t DEFAULT_FRAGMENT_SIZE; - - int32_t fragmentSize; - int32_t currentNumFrags; - int32_t position; - QueryScorerPtr queryScorer; - int32_t waitForPos; - int32_t textSize; - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncAtt; - OffsetAttributePtr offsetAtt; - - public: - virtual bool isNewFragment(); - virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); - }; +namespace Lucene { + +/// {@link Fragmenter} implementation which breaks text up into same-size fragments but +/// does not split up {@link Spans}. This is a simple sample class. +class LPPCONTRIBAPI SimpleSpanFragmenter : public Fragmenter, public LuceneObject { +public: + /// @param queryScorer QueryScorer that was used to score hits + SimpleSpanFragmenter(const QueryScorerPtr& queryScorer); + + /// @param queryScorer QueryScorer that was used to score hits + /// @param fragmentSize size in bytes of each fragment + SimpleSpanFragmenter(const QueryScorerPtr& queryScorer, int32_t fragmentSize); + + virtual ~SimpleSpanFragmenter(); + + LUCENE_CLASS(SimpleSpanFragmenter); + +protected: + static const int32_t DEFAULT_FRAGMENT_SIZE; + + int32_t fragmentSize; + int32_t currentNumFrags; + int32_t position; + QueryScorerPtr queryScorer; + int32_t waitForPos; + int32_t textSize; + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncAtt; + OffsetAttributePtr offsetAtt; + +public: + virtual bool isNewFragment(); + virtual void start(const String& originalText, const TokenStreamPtr& tokenStream); +}; + } #endif diff --git a/src/contrib/include/SnowballAnalyzer.h b/src/contrib/include/SnowballAnalyzer.h index a680455a..f342e89a 100644 --- a/src/contrib/include/SnowballAnalyzer.h +++ b/src/contrib/include/SnowballAnalyzer.h @@ -10,53 +10,52 @@ #include "LuceneContrib.h" #include "Analyzer.h" -namespace Lucene -{ - /// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter}, {@link StopFilter} - /// and {@link SnowballFilter}. - /// - /// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. - class LPPCONTRIBAPI SnowballAnalyzer : public Analyzer - { - public: - /// Builds the named analyzer with no stop words. - SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name); - - /// Builds an analyzer with the given stop words. - SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name, HashSet stopwords); - - virtual ~SnowballAnalyzer(); - - LUCENE_CLASS(SnowballAnalyzer); - - protected: - /// Contains the stopwords used with the StopFilter. - HashSet stopSet; - - String name; - LuceneVersion::Version matchVersion; - - public: - /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter}, - /// a {@link StopFilter} and a {@link SnowballFilter}. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); - - /// Returns a (possibly reused) {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link - /// LowerCaseFilter}, a {@link StopFilter} and a {@link SnowballFilter}. - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); - }; - - class LPPCONTRIBAPI SnowballAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~SnowballAnalyzerSavedStreams(); - - LUCENE_CLASS(SnowballAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; +namespace Lucene { + +/// Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link LowerCaseFilter}, {@link StopFilter} +/// and {@link SnowballFilter}. +/// +/// NOTE: This class uses the same {@link LuceneVersion#Version} dependent settings as {@link StandardAnalyzer}. +class LPPCONTRIBAPI SnowballAnalyzer : public Analyzer { +public: + /// Builds the named analyzer with no stop words. + SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name); + + /// Builds an analyzer with the given stop words. + SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name, HashSet stopwords); + + virtual ~SnowballAnalyzer(); + + LUCENE_CLASS(SnowballAnalyzer); + +protected: + /// Contains the stopwords used with the StopFilter. + HashSet stopSet; + + String name; + LuceneVersion::Version matchVersion; + +public: + /// Constructs a {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link LowerCaseFilter}, + /// a {@link StopFilter} and a {@link SnowballFilter}. + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader); + + /// Returns a (possibly reused) {@link StandardTokenizer} filtered by a {@link StandardFilter}, a {@link + /// LowerCaseFilter}, a {@link StopFilter} and a {@link SnowballFilter}. + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader); +}; + +class LPPCONTRIBAPI SnowballAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~SnowballAnalyzerSavedStreams(); + + LUCENE_CLASS(SnowballAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/contrib/include/SnowballFilter.h b/src/contrib/include/SnowballFilter.h index 8dd56224..8364d7b0 100644 --- a/src/contrib/include/SnowballFilter.h +++ b/src/contrib/include/SnowballFilter.h @@ -12,25 +12,25 @@ struct sb_stemmer; -namespace Lucene -{ - /// A filter that stems words using a Snowball-generated stemmer. - class LPPCONTRIBAPI SnowballFilter : public TokenFilter - { - public: - SnowballFilter(const TokenStreamPtr& input, const String& name); - virtual ~SnowballFilter(); - - LUCENE_CLASS(SnowballFilter); - - protected: - struct sb_stemmer* stemmer; - UTF8ResultPtr utf8Result; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken(); - }; +namespace Lucene { + +/// A filter that stems words using a Snowball-generated stemmer. +class LPPCONTRIBAPI SnowballFilter : public TokenFilter { +public: + SnowballFilter(const TokenStreamPtr& input, const String& name); + virtual ~SnowballFilter(); + + LUCENE_CLASS(SnowballFilter); + +protected: + struct sb_stemmer* stemmer; + UTF8ResultPtr utf8Result; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken(); +}; + } #endif diff --git a/src/contrib/include/SpanGradientFormatter.h b/src/contrib/include/SpanGradientFormatter.h index dde5f011..d89ee204 100644 --- a/src/contrib/include/SpanGradientFormatter.h +++ b/src/contrib/include/SpanGradientFormatter.h @@ -9,23 +9,23 @@ #include "GradientFormatter.h" -namespace Lucene -{ - /// Formats text with different color intensity depending on the score of the term using the - /// span tag. GradientFormatter uses a bgcolor argument to the font tag which doesn't work - /// in Mozilla, thus this class. - /// @see GradientFormatter - class LPPCONTRIBAPI SpanGradientFormatter : public GradientFormatter - { - public: - SpanGradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor); - virtual ~SpanGradientFormatter(); - - LUCENE_CLASS(SpanGradientFormatter); - - public: - virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); - }; +namespace Lucene { + +/// Formats text with different color intensity depending on the score of the term using the +/// span tag. GradientFormatter uses a bgcolor argument to the font tag which doesn't work +/// in Mozilla, thus this class. +/// @see GradientFormatter +class LPPCONTRIBAPI SpanGradientFormatter : public GradientFormatter { +public: + SpanGradientFormatter(double maxScore, const String& minForegroundColor, const String& maxForegroundColor, const String& minBackgroundColor, const String& maxBackgroundColor); + virtual ~SpanGradientFormatter(); + + LUCENE_CLASS(SpanGradientFormatter); + +public: + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); +}; + } #endif diff --git a/src/contrib/include/TextFragment.h b/src/contrib/include/TextFragment.h index e2ffd6dc..f077e78e 100644 --- a/src/contrib/include/TextFragment.h +++ b/src/contrib/include/TextFragment.h @@ -10,57 +10,56 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Low-level class used to record information about a section of a document with a score. - class LPPCONTRIBAPI TextFragment : public LuceneObject - { - public: - TextFragment(const StringBufferPtr& markedUpText, int32_t textStartPos, int32_t fragNum); - virtual ~TextFragment(); - - LUCENE_CLASS(TextFragment); - - public: - StringBufferPtr markedUpText; - int32_t fragNum; - int32_t textStartPos; - int32_t textEndPos; - double score; - - public: - void setScore(double score); - double getScore(); - - /// @param frag2 Fragment to be merged into this one - void merge(const TextFragmentPtr& frag2); - - /// @return true if this fragment follows the one passed - bool follows(const TextFragmentPtr& fragment); - - /// @return the fragment sequence number - int32_t getFragNum(); - - /// Returns the marked-up text for this text fragment - virtual String toString(); - }; - - /// Utility class to store a string buffer that contains text fragment - class LPPCONTRIBAPI StringBuffer : public LuceneObject - { - public: - virtual ~StringBuffer(); - LUCENE_CLASS(StringBuffer); - - protected: - StringStream buffer; - - public: - virtual String toString(); - virtual int32_t length(); - virtual void append(const String& str); - virtual void clear(); - }; +namespace Lucene { + +/// Low-level class used to record information about a section of a document with a score. +class LPPCONTRIBAPI TextFragment : public LuceneObject { +public: + TextFragment(const StringBufferPtr& markedUpText, int32_t textStartPos, int32_t fragNum); + virtual ~TextFragment(); + + LUCENE_CLASS(TextFragment); + +public: + StringBufferPtr markedUpText; + int32_t fragNum; + int32_t textStartPos; + int32_t textEndPos; + double score; + +public: + void setScore(double score); + double getScore(); + + /// @param frag2 Fragment to be merged into this one + void merge(const TextFragmentPtr& frag2); + + /// @return true if this fragment follows the one passed + bool follows(const TextFragmentPtr& fragment); + + /// @return the fragment sequence number + int32_t getFragNum(); + + /// Returns the marked-up text for this text fragment + virtual String toString(); +}; + +/// Utility class to store a string buffer that contains text fragment +class LPPCONTRIBAPI StringBuffer : public LuceneObject { +public: + virtual ~StringBuffer(); + LUCENE_CLASS(StringBuffer); + +protected: + StringStream buffer; + +public: + virtual String toString(); + virtual int32_t length(); + virtual void append(const String& str); + virtual void clear(); +}; + } #endif diff --git a/src/contrib/include/TokenGroup.h b/src/contrib/include/TokenGroup.h index a43ec527..ba563196 100644 --- a/src/contrib/include/TokenGroup.h +++ b/src/contrib/include/TokenGroup.h @@ -10,59 +10,59 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// One, or several overlapping tokens, along with the score(s) and the scope of the original text - class LPPCONTRIBAPI TokenGroup : public LuceneObject - { - public: - TokenGroup(const TokenStreamPtr& tokenStream); - virtual ~TokenGroup(); - - LUCENE_CLASS(TokenGroup); - - protected: - static const int32_t MAX_NUM_TOKENS_PER_GROUP; - - OffsetAttributePtr offsetAtt; - TermAttributePtr termAtt; - - public: - Collection tokens; - Collection scores; - - int32_t numTokens; - int32_t startOffset; - int32_t endOffset; - double tot; - int32_t matchStartOffset; - int32_t matchEndOffset; - - public: - void addToken(double score); - bool isDistinct(); - void clear(); - - /// @param index a value between 0 and numTokens -1 - /// @return the "n"th token - TokenPtr getToken(int32_t index); - - /// @param index a value between 0 and numTokens -1 - /// @return the "n"th score - double getScore(int32_t index); - - /// @return the end position in the original text - int32_t getEndOffset(); - - /// @return the number of tokens in this group - int32_t getNumTokens(); - - /// @return the start position in the original text - int32_t getStartOffset(); - - /// @return all tokens' scores summed up - double getTotalScore(); - }; +namespace Lucene { + +/// One, or several overlapping tokens, along with the score(s) and the scope of the original text +class LPPCONTRIBAPI TokenGroup : public LuceneObject { +public: + TokenGroup(const TokenStreamPtr& tokenStream); + virtual ~TokenGroup(); + + LUCENE_CLASS(TokenGroup); + +protected: + static const int32_t MAX_NUM_TOKENS_PER_GROUP; + + OffsetAttributePtr offsetAtt; + TermAttributePtr termAtt; + +public: + Collection tokens; + Collection scores; + + int32_t numTokens; + int32_t startOffset; + int32_t endOffset; + double tot; + int32_t matchStartOffset; + int32_t matchEndOffset; + +public: + void addToken(double score); + bool isDistinct(); + void clear(); + + /// @param index a value between 0 and numTokens -1 + /// @return the "n"th token + TokenPtr getToken(int32_t index); + + /// @param index a value between 0 and numTokens -1 + /// @return the "n"th score + double getScore(int32_t index); + + /// @return the end position in the original text + int32_t getEndOffset(); + + /// @return the number of tokens in this group + int32_t getNumTokens(); + + /// @return the start position in the original text + int32_t getStartOffset(); + + /// @return all tokens' scores summed up + double getTotalScore(); +}; + } #endif diff --git a/src/contrib/include/TokenSources.h b/src/contrib/include/TokenSources.h index 3b7ec06d..671a81fc 100644 --- a/src/contrib/include/TokenSources.h +++ b/src/contrib/include/TokenSources.h @@ -10,83 +10,82 @@ #include "LuceneContrib.h" #include "TokenStream.h" -namespace Lucene -{ - /// Hides implementation issues associated with obtaining a TokenStream for use with the highlighter - can obtain - /// from TermFreqVectors with offsets and (optionally) positions or from Analyzer class re-parsing the stored content. - class LPPCONTRIBAPI TokenSources : public LuceneObject - { - public: - virtual ~TokenSources(); - LUCENE_CLASS(TokenSources); +namespace Lucene { - public: - /// A convenience method that tries to first get a TermPositionVector for the specified docId, then, falls back to - /// using the passed in {@link Document} to retrieve the TokenStream. This is useful when you already have the - /// document, but would prefer to use the vector first. - /// @param reader The {@link IndexReader} to use to try and get the vector from. - /// @param docId The docId to retrieve. - /// @param field The field to retrieve on the document. - /// @param doc The document to fall back on. - /// @param analyzer The analyzer to use for creating the TokenStream if the vector doesn't exist. - /// @return The {@link TokenStream} for the {@link Fieldable} on the {@link Document} - static TokenStreamPtr getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const DocumentPtr& doc, const AnalyzerPtr& analyzer); +/// Hides implementation issues associated with obtaining a TokenStream for use with the highlighter - can obtain +/// from TermFreqVectors with offsets and (optionally) positions or from Analyzer class re-parsing the stored content. +class LPPCONTRIBAPI TokenSources : public LuceneObject { +public: + virtual ~TokenSources(); + LUCENE_CLASS(TokenSources); - /// A convenience method that tries a number of approaches to getting a token stream. The cost of finding there - /// are no termVectors in the index is minimal (1000 invocations still registers 0 ms). So this "lazy" (flexible?) - /// approach to coding is probably acceptable - static TokenStreamPtr getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer); +public: + /// A convenience method that tries to first get a TermPositionVector for the specified docId, then, falls back to + /// using the passed in {@link Document} to retrieve the TokenStream. This is useful when you already have the + /// document, but would prefer to use the vector first. + /// @param reader The {@link IndexReader} to use to try and get the vector from. + /// @param docId The docId to retrieve. + /// @param field The field to retrieve on the document. + /// @param doc The document to fall back on. + /// @param analyzer The analyzer to use for creating the TokenStream if the vector doesn't exist. + /// @return The {@link TokenStream} for the {@link Fieldable} on the {@link Document} + static TokenStreamPtr getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const DocumentPtr& doc, const AnalyzerPtr& analyzer); - static TokenStreamPtr getTokenStream(const TermPositionVectorPtr& tpv); + /// A convenience method that tries a number of approaches to getting a token stream. The cost of finding there + /// are no termVectors in the index is minimal (1000 invocations still registers 0 ms). So this "lazy" (flexible?) + /// approach to coding is probably acceptable + static TokenStreamPtr getAnyTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer); - /// Low level api. - /// Returns a token stream or null if no offset info available in index. This can be used to feed the highlighter - /// with a pre-parsed token stream. - /// - /// In my tests the speeds to recreate 1000 token streams using this method are: - /// - with TermVector offset only data stored - 420 milliseconds - /// - with TermVector offset AND position data stored - 271 milliseconds - /// (nb timings for TermVector with position data are based on a tokenizer with contiguous positions - no overlaps - /// or gaps) The cost of not using TermPositionVector to store pre-parsed content and using an analyzer to re-parse - /// the original content: - /// - reanalyzing the original content - 980 milliseconds - /// - /// The re-analyze timings will typically vary depending on - - /// 1) The complexity of the analyzer code (timings above were using a stemmer/lowercaser/stopword combo) - /// 2) The number of other fields (Lucene reads ALL fields off the disk when accessing just one document field - - /// can cost dear!) - /// 3) Use of compression on field storage - could be faster due to compression (less disk IO) or slower (more CPU - /// burn) depending on the content. - /// - /// @param tpv - /// @param tokenPositionsGuaranteedContiguous true if the token position numbers have no overlaps or gaps. If looking - /// to eek out the last drops of performance, set to true. If in doubt, set to false. - static TokenStreamPtr getTokenStream(const TermPositionVectorPtr& tpv, bool tokenPositionsGuaranteedContiguous); + static TokenStreamPtr getTokenStream(const TermPositionVectorPtr& tpv); - static TokenStreamPtr getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field); - static TokenStreamPtr getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer); - static TokenStreamPtr getTokenStream(const DocumentPtr& doc, const String& field, const AnalyzerPtr& analyzer); - static TokenStreamPtr getTokenStream(const String& field, const String& contents, const AnalyzerPtr& analyzer); - }; + /// Low level api. + /// Returns a token stream or null if no offset info available in index. This can be used to feed the highlighter + /// with a pre-parsed token stream. + /// + /// In my tests the speeds to recreate 1000 token streams using this method are: + /// - with TermVector offset only data stored - 420 milliseconds + /// - with TermVector offset AND position data stored - 271 milliseconds + /// (nb timings for TermVector with position data are based on a tokenizer with contiguous positions - no overlaps + /// or gaps) The cost of not using TermPositionVector to store pre-parsed content and using an analyzer to re-parse + /// the original content: + /// - reanalyzing the original content - 980 milliseconds + /// + /// The re-analyze timings will typically vary depending on - + /// 1) The complexity of the analyzer code (timings above were using a stemmer/lowercaser/stopword combo) + /// 2) The number of other fields (Lucene reads ALL fields off the disk when accessing just one document field - + /// can cost dear!) + /// 3) Use of compression on field storage - could be faster due to compression (less disk IO) or slower (more CPU + /// burn) depending on the content. + /// + /// @param tpv + /// @param tokenPositionsGuaranteedContiguous true if the token position numbers have no overlaps or gaps. If looking + /// to eek out the last drops of performance, set to true. If in doubt, set to false. + static TokenStreamPtr getTokenStream(const TermPositionVectorPtr& tpv, bool tokenPositionsGuaranteedContiguous); - /// an object used to iterate across an array of tokens - class LPPCONTRIBAPI StoredTokenStream : public TokenStream - { - public: - StoredTokenStream(Collection tokens); - virtual ~StoredTokenStream(); + static TokenStreamPtr getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field); + static TokenStreamPtr getTokenStream(const IndexReaderPtr& reader, int32_t docId, const String& field, const AnalyzerPtr& analyzer); + static TokenStreamPtr getTokenStream(const DocumentPtr& doc, const String& field, const AnalyzerPtr& analyzer); + static TokenStreamPtr getTokenStream(const String& field, const String& contents, const AnalyzerPtr& analyzer); +}; - LUCENE_CLASS(StoredTokenStream); +/// an object used to iterate across an array of tokens +class LPPCONTRIBAPI StoredTokenStream : public TokenStream { +public: + StoredTokenStream(Collection tokens); + virtual ~StoredTokenStream(); - public: - Collection tokens; - int32_t currentToken; - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; + LUCENE_CLASS(StoredTokenStream); + +public: + Collection tokens; + int32_t currentToken; + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + +public: + virtual bool incrementToken(); +}; - public: - virtual bool incrementToken(); - }; } #endif diff --git a/src/contrib/include/WeightedSpanTerm.h b/src/contrib/include/WeightedSpanTerm.h index 83c89d4b..9b8eccf1 100644 --- a/src/contrib/include/WeightedSpanTerm.h +++ b/src/contrib/include/WeightedSpanTerm.h @@ -9,48 +9,47 @@ #include "WeightedTerm.h" -namespace Lucene -{ - /// Lightweight class to hold term, weight, and positions used for scoring this term. - class LPPCONTRIBAPI WeightedSpanTerm : public WeightedTerm - { - public: - WeightedSpanTerm(double weight, const String& term, bool positionSensitive = false); - virtual ~WeightedSpanTerm(); - - LUCENE_CLASS(WeightedSpanTerm); - - public: - bool positionSensitive; - - protected: - Collection positionSpans; - - public: - /// Checks to see if this term is valid at position. - /// @param position To check against valid term positions. - /// @return true if this term is a hit at this position. - bool checkPosition(int32_t position); - - void addPositionSpans(Collection positionSpans); - bool isPositionSensitive(); - void setPositionSensitive(bool positionSensitive); - Collection getPositionSpans(); - }; - - /// Utility class to store a Span - class LPPCONTRIBAPI PositionSpan : public LuceneObject - { - public: - PositionSpan(int32_t start, int32_t end); - virtual ~PositionSpan(); - - LUCENE_CLASS(PositionSpan); - - public: - int32_t start; - int32_t end; - }; +namespace Lucene { + +/// Lightweight class to hold term, weight, and positions used for scoring this term. +class LPPCONTRIBAPI WeightedSpanTerm : public WeightedTerm { +public: + WeightedSpanTerm(double weight, const String& term, bool positionSensitive = false); + virtual ~WeightedSpanTerm(); + + LUCENE_CLASS(WeightedSpanTerm); + +public: + bool positionSensitive; + +protected: + Collection positionSpans; + +public: + /// Checks to see if this term is valid at position. + /// @param position To check against valid term positions. + /// @return true if this term is a hit at this position. + bool checkPosition(int32_t position); + + void addPositionSpans(Collection positionSpans); + bool isPositionSensitive(); + void setPositionSensitive(bool positionSensitive); + Collection getPositionSpans(); +}; + +/// Utility class to store a Span +class LPPCONTRIBAPI PositionSpan : public LuceneObject { +public: + PositionSpan(int32_t start, int32_t end); + virtual ~PositionSpan(); + + LUCENE_CLASS(PositionSpan); + +public: + int32_t start; + int32_t end; +}; + } #endif diff --git a/src/contrib/include/WeightedSpanTermExtractor.h b/src/contrib/include/WeightedSpanTermExtractor.h index c46cce2d..7a178ddd 100644 --- a/src/contrib/include/WeightedSpanTermExtractor.h +++ b/src/contrib/include/WeightedSpanTermExtractor.h @@ -11,124 +11,122 @@ #include "FilterIndexReader.h" #include "MapWeightedSpanTerm.h" -namespace Lucene -{ - /// Class used to extract {@link WeightedSpanTerm}s from a {@link Query} based on whether {@link Term}s - /// from the {@link Query} are contained in a supplied {@link TokenStream}. - class LPPCONTRIBAPI WeightedSpanTermExtractor : public LuceneObject - { - public: - WeightedSpanTermExtractor(const String& defaultField = L""); - virtual ~WeightedSpanTermExtractor(); - - LUCENE_CLASS(WeightedSpanTermExtractor); - - protected: - String fieldName; - TokenStreamPtr tokenStream; - MapStringIndexReader readers; - String defaultField; - bool expandMultiTermQuery; - bool cachedTokenStream; - bool wrapToCaching; - - protected: - void closeReaders(); - - /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied Query. - /// - /// @param query Query to extract Terms from - /// @param terms Map to place created WeightedSpanTerms in - void extract(const QueryPtr& query, const MapWeightedSpanTermPtr& terms); - - /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied SpanQuery. - /// - /// @param terms Map to place created WeightedSpanTerms in. - /// @param spanQuery SpanQuery to extract Terms from - void extractWeightedSpanTerms(const MapWeightedSpanTermPtr& terms, const SpanQueryPtr& spanQuery); - - /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied Query. - /// @param terms Map to place created WeightedSpanTerms in - /// @param query Query to extract Terms from - void extractWeightedTerms(const MapWeightedSpanTermPtr& terms, const QueryPtr& query); - - /// Necessary to implement matches for queries against defaultField - bool fieldNameComparator(const String& fieldNameToCheck); - - IndexReaderPtr getReaderForField(const String& field); - - void collectSpanQueryFields(const SpanQueryPtr& spanQuery, HashSet fieldNames); - bool mustRewriteQuery(const SpanQueryPtr& spanQuery); - - public: - /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. - /// - /// @param query That caused hit - /// @param tokenStream Of text to be highlighted - /// @return Map containing WeightedSpanTerms - MapWeightedSpanTermPtr getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream); - - /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. - /// - /// @param query That caused hit - /// @param tokenStream Of text to be highlighted - /// @param fieldName Restricts Term's used based on field name - /// @return Map containing WeightedSpanTerms - MapWeightedSpanTermPtr getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName); - - /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. Uses a supplied - /// IndexReader to properly weight terms (for gradient highlighting). - /// - /// @param query That caused hit - /// @param tokenStream Of text to be highlighted - /// @param fieldName Restricts Term's used based on field name - /// @param reader To use for scoring - /// @return Map containing WeightedSpanTerms - MapWeightedSpanTermPtr getWeightedSpanTermsWithScores(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName, const IndexReaderPtr& reader); - - bool getExpandMultiTermQuery(); - void setExpandMultiTermQuery(bool expandMultiTermQuery); - - bool isCachedTokenStream(); - TokenStreamPtr getTokenStream(); - - /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} - /// are wrapped in a {@link CachingTokenFilter} to ensure an efficient reset - if you - /// are already using a different caching {@link TokenStream} impl and you don't want - /// it to be wrapped, set this to false. - void setWrapIfNotCachingTokenFilter(bool wrap); - }; - - /// This class makes sure that if both position sensitive and insensitive versions of the same - /// term are added, the position insensitive one wins. - class LPPCONTRIBAPI PositionCheckingMap : public MapWeightedSpanTerm - { - public: - virtual ~PositionCheckingMap(); - LUCENE_CLASS(PositionCheckingMap); - - public: - virtual void put(const String& key, const WeightedSpanTermPtr& val); - }; - - /// A fake IndexReader class to extract the field from a MultiTermQuery - class LPPCONTRIBAPI FakeReader : public FilterIndexReader - { - public: - FakeReader(); - virtual ~FakeReader(); - - LUCENE_CLASS(FakeReader); - - public: - String field; - - protected: - static IndexReaderPtr EMPTY_MEMORY_INDEX_READER(); - - public: - virtual TermEnumPtr terms(const TermPtr& t); - }; +namespace Lucene { + +/// Class used to extract {@link WeightedSpanTerm}s from a {@link Query} based on whether {@link Term}s +/// from the {@link Query} are contained in a supplied {@link TokenStream}. +class LPPCONTRIBAPI WeightedSpanTermExtractor : public LuceneObject { +public: + WeightedSpanTermExtractor(const String& defaultField = L""); + virtual ~WeightedSpanTermExtractor(); + + LUCENE_CLASS(WeightedSpanTermExtractor); + +protected: + String fieldName; + TokenStreamPtr tokenStream; + MapStringIndexReader readers; + String defaultField; + bool expandMultiTermQuery; + bool cachedTokenStream; + bool wrapToCaching; + +protected: + void closeReaders(); + + /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied Query. + /// + /// @param query Query to extract Terms from + /// @param terms Map to place created WeightedSpanTerms in + void extract(const QueryPtr& query, const MapWeightedSpanTermPtr& terms); + + /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied SpanQuery. + /// + /// @param terms Map to place created WeightedSpanTerms in. + /// @param spanQuery SpanQuery to extract Terms from + void extractWeightedSpanTerms(const MapWeightedSpanTermPtr& terms, const SpanQueryPtr& spanQuery); + + /// Fills a Map with {@link WeightedSpanTerm}s using the terms from the supplied Query. + /// @param terms Map to place created WeightedSpanTerms in + /// @param query Query to extract Terms from + void extractWeightedTerms(const MapWeightedSpanTermPtr& terms, const QueryPtr& query); + + /// Necessary to implement matches for queries against defaultField + bool fieldNameComparator(const String& fieldNameToCheck); + + IndexReaderPtr getReaderForField(const String& field); + + void collectSpanQueryFields(const SpanQueryPtr& spanQuery, HashSet fieldNames); + bool mustRewriteQuery(const SpanQueryPtr& spanQuery); + +public: + /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. + /// + /// @param query That caused hit + /// @param tokenStream Of text to be highlighted + /// @return Map containing WeightedSpanTerms + MapWeightedSpanTermPtr getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream); + + /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. + /// + /// @param query That caused hit + /// @param tokenStream Of text to be highlighted + /// @param fieldName Restricts Term's used based on field name + /// @return Map containing WeightedSpanTerms + MapWeightedSpanTermPtr getWeightedSpanTerms(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName); + + /// Creates a Map of WeightedSpanTerms from the given Query and TokenStream. Uses a supplied + /// IndexReader to properly weight terms (for gradient highlighting). + /// + /// @param query That caused hit + /// @param tokenStream Of text to be highlighted + /// @param fieldName Restricts Term's used based on field name + /// @param reader To use for scoring + /// @return Map containing WeightedSpanTerms + MapWeightedSpanTermPtr getWeightedSpanTermsWithScores(const QueryPtr& query, const TokenStreamPtr& tokenStream, const String& fieldName, const IndexReaderPtr& reader); + + bool getExpandMultiTermQuery(); + void setExpandMultiTermQuery(bool expandMultiTermQuery); + + bool isCachedTokenStream(); + TokenStreamPtr getTokenStream(); + + /// By default, {@link TokenStream}s that are not of the type {@link CachingTokenFilter} + /// are wrapped in a {@link CachingTokenFilter} to ensure an efficient reset - if you + /// are already using a different caching {@link TokenStream} impl and you don't want + /// it to be wrapped, set this to false. + void setWrapIfNotCachingTokenFilter(bool wrap); +}; + +/// This class makes sure that if both position sensitive and insensitive versions of the same +/// term are added, the position insensitive one wins. +class LPPCONTRIBAPI PositionCheckingMap : public MapWeightedSpanTerm { +public: + virtual ~PositionCheckingMap(); + LUCENE_CLASS(PositionCheckingMap); + +public: + virtual void put(const String& key, const WeightedSpanTermPtr& val); +}; + +/// A fake IndexReader class to extract the field from a MultiTermQuery +class LPPCONTRIBAPI FakeReader : public FilterIndexReader { +public: + FakeReader(); + virtual ~FakeReader(); + + LUCENE_CLASS(FakeReader); + +public: + String field; + +protected: + static IndexReaderPtr EMPTY_MEMORY_INDEX_READER(); + +public: + virtual TermEnumPtr terms(const TermPtr& t); +}; + } #endif diff --git a/src/contrib/include/WeightedTerm.h b/src/contrib/include/WeightedTerm.h index cc380181..15985424 100644 --- a/src/contrib/include/WeightedTerm.h +++ b/src/contrib/include/WeightedTerm.h @@ -10,34 +10,34 @@ #include "LuceneContrib.h" #include "LuceneObject.h" -namespace Lucene -{ - /// Lightweight class to hold term and a weight value used for scoring this term - class LPPCONTRIBAPI WeightedTerm : public LuceneObject - { - public: - WeightedTerm(double weight, const String& term); - virtual ~WeightedTerm(); - - LUCENE_CLASS(WeightedTerm); - - public: - double weight; // multiplier - String term; // stemmed form - - public: - /// @return the term value (stemmed) - String getTerm(); - - /// @return the weight associated with this term - double getWeight(); - - /// @param term the term value (stemmed) - void setTerm(const String& term); - - /// @param weight the weight associated with this term - void setWeight(double weight); - }; +namespace Lucene { + +/// Lightweight class to hold term and a weight value used for scoring this term +class LPPCONTRIBAPI WeightedTerm : public LuceneObject { +public: + WeightedTerm(double weight, const String& term); + virtual ~WeightedTerm(); + + LUCENE_CLASS(WeightedTerm); + +public: + double weight; // multiplier + String term; // stemmed form + +public: + /// @return the term value (stemmed) + String getTerm(); + + /// @return the weight associated with this term + double getWeight(); + + /// @param term the term value (stemmed) + void setTerm(const String& term); + + /// @param weight the weight associated with this term + void setWeight(double weight); +}; + } #endif diff --git a/src/contrib/memory/MemoryIndex.cpp b/src/contrib/memory/MemoryIndex.cpp index d8098e17..9c17ddaf 100644 --- a/src/contrib/memory/MemoryIndex.cpp +++ b/src/contrib/memory/MemoryIndex.cpp @@ -23,735 +23,656 @@ #include "Document.h" #include "MiscUtils.h" -namespace Lucene -{ - const double MemoryIndex::docBoost = 1.0; +namespace Lucene { - MemoryIndex::MemoryIndex(bool storeOffsets) - { - stride = storeOffsets ? 3 : 1; - fields = MapStringMemoryIndexInfo::newInstance(); - } +const double MemoryIndex::docBoost = 1.0; + +MemoryIndex::MemoryIndex(bool storeOffsets) { + stride = storeOffsets ? 3 : 1; + fields = MapStringMemoryIndexInfo::newInstance(); +} - MemoryIndex::~MemoryIndex() - { +MemoryIndex::~MemoryIndex() { +} + +void MemoryIndex::addField(const String& fieldName, const String& text, const AnalyzerPtr& analyzer) { + if (fieldName.empty()) { + boost::throw_exception(IllegalArgumentException(L"fieldName must not be empty")); + } + if (text.empty()) { + boost::throw_exception(IllegalArgumentException(L"text must not be empty")); + } + if (!analyzer) { + boost::throw_exception(IllegalArgumentException(L"analyzer must not be null")); } - void MemoryIndex::addField(const String& fieldName, const String& text, const AnalyzerPtr& analyzer) - { - if (fieldName.empty()) + TokenStreamPtr stream(analyzer->tokenStream(fieldName, newLucene(text))); + addField(fieldName, stream); +} + +void MemoryIndex::addField(const String& fieldName, const TokenStreamPtr& stream, double boost) { + LuceneException finally; + try { + if (fieldName.empty()) { boost::throw_exception(IllegalArgumentException(L"fieldName must not be empty")); - if (text.empty()) - boost::throw_exception(IllegalArgumentException(L"text must not be empty")); - if (!analyzer) - boost::throw_exception(IllegalArgumentException(L"analyzer must not be null")); - - TokenStreamPtr stream(analyzer->tokenStream(fieldName, newLucene(text))); - addField(fieldName, stream); - } - - void MemoryIndex::addField(const String& fieldName, const TokenStreamPtr& stream, double boost) - { - LuceneException finally; - try - { - if (fieldName.empty()) - boost::throw_exception(IllegalArgumentException(L"fieldName must not be empty")); - if (!stream) - boost::throw_exception(IllegalArgumentException(L"token stream must not be null")); - if (boost <= 0.0) - boost::throw_exception(IllegalArgumentException(L"boost factor must be greater than 0.0")); - if (fields.contains(fieldName)) - boost::throw_exception(IllegalArgumentException(L"field must not be added more than once")); - - MapStringIntCollection terms(MapStringIntCollection::newInstance()); - int32_t numTokens = 0; - int32_t numOverlapTokens = 0; - int32_t pos = -1; - - TermAttributePtr termAtt(stream->addAttribute()); - PositionIncrementAttributePtr posIncrAttribute(stream->addAttribute()); - OffsetAttributePtr offsetAtt(stream->addAttribute()); - - stream->reset(); - while (stream->incrementToken()) - { - String term(termAtt->term()); - if (term.empty()) - continue; // nothing to do - ++numTokens; - int32_t posIncr = posIncrAttribute->getPositionIncrement(); - if (posIncr == 0) - ++numOverlapTokens; - pos += posIncr; - - Collection positions(terms.get(term)); - if (!positions) - { - // term not seen before - positions = Collection::newInstance(); - terms.put(term, positions); - } - positions.add(pos); - if (stride != 1) - { - positions.add(offsetAtt->startOffset()); - positions.add(offsetAtt->endOffset()); - } - } - stream->end(); - - // ensure infos.numTokens > 0 invariant; needed for correct operation of terms() - if (numTokens > 0) - { - boost = boost * docBoost; // see DocumentWriter.addDocument(...) - fields.put(fieldName, newLucene(terms, numTokens, numOverlapTokens, boost)); - sortedFields.reset(); // invalidate sorted view, if any - } - } - catch (IOException& e) - { - // can never happen - boost::throw_exception(RuntimeException(e.getError())); } - catch (LuceneException& e) - { - finally = e; + if (!stream) { + boost::throw_exception(IllegalArgumentException(L"token stream must not be null")); } - try - { - if (stream) - stream->close(); + if (boost <= 0.0) { + boost::throw_exception(IllegalArgumentException(L"boost factor must be greater than 0.0")); } - catch (IOException& e) - { - boost::throw_exception(RuntimeException(e.getError())); + if (fields.contains(fieldName)) { + boost::throw_exception(IllegalArgumentException(L"field must not be added more than once")); } - finally.throwException(); - } - - IndexSearcherPtr MemoryIndex::createSearcher() - { - MemoryIndexReaderPtr reader(newLucene(shared_from_this())); - IndexSearcherPtr searcher(newLucene(reader)); // ensures no auto-close - reader->setSearcher(searcher); // to later get hold of searcher.getSimilarity() - return searcher; - } - - double MemoryIndex::search(const QueryPtr& query) - { - if (!query) - boost::throw_exception(IllegalArgumentException(L"query must not be null")); - - SearcherPtr searcher(createSearcher()); - LuceneException finally; - try - { - Collection scores = Collection::newInstance(1); - scores[0] = 0.0; // inits to 0.0 (no match) - searcher->search(query, newLucene(scores)); - return scores[0]; + + MapStringIntCollection terms(MapStringIntCollection::newInstance()); + int32_t numTokens = 0; + int32_t numOverlapTokens = 0; + int32_t pos = -1; + + TermAttributePtr termAtt(stream->addAttribute()); + PositionIncrementAttributePtr posIncrAttribute(stream->addAttribute()); + OffsetAttributePtr offsetAtt(stream->addAttribute()); + + stream->reset(); + while (stream->incrementToken()) { + String term(termAtt->term()); + if (term.empty()) { + continue; // nothing to do + } + ++numTokens; + int32_t posIncr = posIncrAttribute->getPositionIncrement(); + if (posIncr == 0) { + ++numOverlapTokens; + } + pos += posIncr; + + Collection positions(terms.get(term)); + if (!positions) { + // term not seen before + positions = Collection::newInstance(); + terms.put(term, positions); + } + positions.add(pos); + if (stride != 1) { + positions.add(offsetAtt->startOffset()); + positions.add(offsetAtt->endOffset()); + } } - catch (IOException& e) - { - // can never happen - boost::throw_exception(RuntimeException(e.getError())); + stream->end(); + + // ensure infos.numTokens > 0 invariant; needed for correct operation of terms() + if (numTokens > 0) { + boost = boost * docBoost; // see DocumentWriter.addDocument(...) + fields.put(fieldName, newLucene(terms, numTokens, numOverlapTokens, boost)); + sortedFields.reset(); // invalidate sorted view, if any } - catch (LuceneException& e) - { - finally = e; + } catch (IOException& e) { + // can never happen + boost::throw_exception(RuntimeException(e.getError())); + } catch (LuceneException& e) { + finally = e; + } + try { + if (stream) { + stream->close(); } - finally.throwException(); - return 0; // silence static analyzers + } catch (IOException& e) { + boost::throw_exception(RuntimeException(e.getError())); } + finally.throwException(); +} - int32_t MemoryIndex::numPositions(Collection positions) - { - return (positions.size() / stride); - } +IndexSearcherPtr MemoryIndex::createSearcher() { + MemoryIndexReaderPtr reader(newLucene(shared_from_this())); + IndexSearcherPtr searcher(newLucene(reader)); // ensures no auto-close + reader->setSearcher(searcher); // to later get hold of searcher.getSimilarity() + return searcher; +} - struct lessField - { - inline bool operator()(const PairStringMemoryIndexInfo& first, const PairStringMemoryIndexInfo& second) const - { - return (first.first < second.first); - } - }; - - void MemoryIndex::sortFields() - { - if (!sortedFields) - { - sortedFields = CollectionStringMemoryIndexInfo::newInstance(fields.begin(), fields.end()); - std::sort(sortedFields.begin(), sortedFields.end(), lessField()); - } - } +double MemoryIndex::search(const QueryPtr& query) { + if (!query) { + boost::throw_exception(IllegalArgumentException(L"query must not be null")); + } + + SearcherPtr searcher(createSearcher()); + LuceneException finally; + try { + Collection scores = Collection::newInstance(1); + scores[0] = 0.0; // inits to 0.0 (no match) + searcher->search(query, newLucene(scores)); + return scores[0]; + } catch (IOException& e) { + // can never happen + boost::throw_exception(RuntimeException(e.getError())); + } catch (LuceneException& e) { + finally = e; + } + finally.throwException(); + return 0; // silence static analyzers +} - MemoryIndexInfo::MemoryIndexInfo(MapStringIntCollection terms, int32_t numTokens, int32_t numOverlapTokens, double boost) - { - this->terms = terms; - this->numTokens = numTokens; - this->numOverlapTokens = numOverlapTokens; - this->boost = boost; - } +int32_t MemoryIndex::numPositions(Collection positions) { + return (positions.size() / stride); +} - MemoryIndexInfo::~MemoryIndexInfo() - { +struct lessField { + inline bool operator()(const PairStringMemoryIndexInfo& first, const PairStringMemoryIndexInfo& second) const { + return (first.first < second.first); } +}; - struct lessTerm - { - inline bool operator()(const PairStringIntCollection& first, const PairStringIntCollection& second) const - { - return (first.first < second.first); - } - }; - - void MemoryIndexInfo::sortTerms() - { - if (!sortedTerms) - { - sortedTerms = CollectionStringIntCollection::newInstance(terms.begin(), terms.end()); - std::sort(sortedTerms.begin(), sortedTerms.end(), lessTerm()); - } +void MemoryIndex::sortFields() { + if (!sortedFields) { + sortedFields = CollectionStringMemoryIndexInfo::newInstance(fields.begin(), fields.end()); + std::sort(sortedFields.begin(), sortedFields.end(), lessField()); } +} - Collection MemoryIndexInfo::getPositions(const String& term) - { - return terms.get(term); - } +MemoryIndexInfo::MemoryIndexInfo(MapStringIntCollection terms, int32_t numTokens, int32_t numOverlapTokens, double boost) { + this->terms = terms; + this->numTokens = numTokens; + this->numOverlapTokens = numOverlapTokens; + this->boost = boost; +} - Collection MemoryIndexInfo::getPositions(int32_t pos) - { - return sortedTerms[pos].second; - } +MemoryIndexInfo::~MemoryIndexInfo() { +} - double MemoryIndexInfo::getBoost() - { - return boost; +struct lessTerm { + inline bool operator()(const PairStringIntCollection& first, const PairStringIntCollection& second) const { + return (first.first < second.first); } +}; - MemoryIndexReader::MemoryIndexReader(const MemoryIndexPtr& memoryIndex) - { - this->memoryIndex = memoryIndex; +void MemoryIndexInfo::sortTerms() { + if (!sortedTerms) { + sortedTerms = CollectionStringIntCollection::newInstance(terms.begin(), terms.end()); + std::sort(sortedTerms.begin(), sortedTerms.end(), lessTerm()); } +} - MemoryIndexReader::~MemoryIndexReader() - { - } +Collection MemoryIndexInfo::getPositions(const String& term) { + return terms.get(term); +} - TermPtr MemoryIndexReader::MATCH_ALL_TERM() - { - static TermPtr _MATCH_ALL_TERM; - if (!_MATCH_ALL_TERM) - { - _MATCH_ALL_TERM = newLucene(L""); - CycleCheck::addStatic(_MATCH_ALL_TERM); - } - return _MATCH_ALL_TERM; - } +Collection MemoryIndexInfo::getPositions(int32_t pos) { + return sortedTerms[pos].second; +} - MemoryIndexInfoPtr MemoryIndexReader::getInfo(const String& fieldName) - { - return memoryIndex->fields.get(fieldName); - } +double MemoryIndexInfo::getBoost() { + return boost; +} - MemoryIndexInfoPtr MemoryIndexReader::getInfo(int32_t pos) - { - return memoryIndex->sortedFields[pos].second; - } +MemoryIndexReader::MemoryIndexReader(const MemoryIndexPtr& memoryIndex) { + this->memoryIndex = memoryIndex; +} + +MemoryIndexReader::~MemoryIndexReader() { +} - int32_t MemoryIndexReader::docFreq(const TermPtr& t) - { - MemoryIndexInfoPtr info(getInfo(t->field())); - int32_t freq = 0; - if (info) - freq = info->getPositions(t->text()) ? 1 : 0; - return freq; +TermPtr MemoryIndexReader::MATCH_ALL_TERM() { + static TermPtr _MATCH_ALL_TERM; + if (!_MATCH_ALL_TERM) { + _MATCH_ALL_TERM = newLucene(L""); + CycleCheck::addStatic(_MATCH_ALL_TERM); } + return _MATCH_ALL_TERM; +} + +MemoryIndexInfoPtr MemoryIndexReader::getInfo(const String& fieldName) { + return memoryIndex->fields.get(fieldName); +} + +MemoryIndexInfoPtr MemoryIndexReader::getInfo(int32_t pos) { + return memoryIndex->sortedFields[pos].second; +} - TermEnumPtr MemoryIndexReader::terms() - { - return terms(MATCH_ALL_TERM()); +int32_t MemoryIndexReader::docFreq(const TermPtr& t) { + MemoryIndexInfoPtr info(getInfo(t->field())); + int32_t freq = 0; + if (info) { + freq = info->getPositions(t->text()) ? 1 : 0; } + return freq; +} - TermEnumPtr MemoryIndexReader::terms(const TermPtr& t) - { - int32_t i = 0; // index into info.sortedTerms - int32_t j = 0; // index into sortedFields +TermEnumPtr MemoryIndexReader::terms() { + return terms(MATCH_ALL_TERM()); +} - memoryIndex->sortFields(); - if (memoryIndex->sortedFields.size() == 1 && memoryIndex->sortedFields[0].first == t->field()) - j = 0; // fast path - else - { - CollectionStringMemoryIndexInfo::iterator search = std::lower_bound(memoryIndex->sortedFields.begin(), memoryIndex->sortedFields.end(), std::make_pair(t->field(), MemoryIndexInfoPtr()), lessField()); - int32_t keyPos = std::distance(memoryIndex->sortedFields.begin(), search); - j = (search == memoryIndex->sortedFields.end() || t->field() < search->first) ? -(keyPos + 1) : keyPos; - } +TermEnumPtr MemoryIndexReader::terms(const TermPtr& t) { + int32_t i = 0; // index into info.sortedTerms + int32_t j = 0; // index into sortedFields + + memoryIndex->sortFields(); + if (memoryIndex->sortedFields.size() == 1 && memoryIndex->sortedFields[0].first == t->field()) { + j = 0; // fast path + } else { + CollectionStringMemoryIndexInfo::iterator search = std::lower_bound(memoryIndex->sortedFields.begin(), memoryIndex->sortedFields.end(), std::make_pair(t->field(), MemoryIndexInfoPtr()), lessField()); + int32_t keyPos = std::distance(memoryIndex->sortedFields.begin(), search); + j = (search == memoryIndex->sortedFields.end() || t->field() < search->first) ? -(keyPos + 1) : keyPos; + } - if (j < 0) // not found; choose successor - { - j = -j - 1; - i = 0; - if (j < memoryIndex->sortedFields.size()) - getInfo(j)->sortTerms(); + if (j < 0) { // not found; choose successor + j = -j - 1; + i = 0; + if (j < memoryIndex->sortedFields.size()) { + getInfo(j)->sortTerms(); } - else // found - { - MemoryIndexInfoPtr info(getInfo(j)); - info->sortTerms(); - CollectionStringIntCollection::iterator search = std::lower_bound(info->sortedTerms.begin(), info->sortedTerms.end(), std::make_pair(t->text(), Collection()), lessTerm()); - int32_t keyPos = std::distance(info->sortedTerms.begin(), search); - i = (search == info->sortedTerms.end() || t->text() < search->first) ? -(keyPos + 1) : keyPos; - if (i < 0) // not found; choose successor - { - i = -i - 1; - if (i >= info->sortedTerms.size()) // move to next successor - { - ++j; - i = 0; - if (j < memoryIndex->sortedFields.size()) - getInfo(j)->sortTerms(); + } else { // found + MemoryIndexInfoPtr info(getInfo(j)); + info->sortTerms(); + CollectionStringIntCollection::iterator search = std::lower_bound(info->sortedTerms.begin(), info->sortedTerms.end(), std::make_pair(t->text(), Collection()), lessTerm()); + int32_t keyPos = std::distance(info->sortedTerms.begin(), search); + i = (search == info->sortedTerms.end() || t->text() < search->first) ? -(keyPos + 1) : keyPos; + if (i < 0) { // not found; choose successor + i = -i - 1; + if (i >= info->sortedTerms.size()) { // move to next successor + ++j; + i = 0; + if (j < memoryIndex->sortedFields.size()) { + getInfo(j)->sortTerms(); } } } - - return newLucene(shared_from_this(), i, j); } - TermPositionsPtr MemoryIndexReader::termPositions() - { - return newLucene(shared_from_this()); - } + return newLucene(shared_from_this(), i, j); +} - TermDocsPtr MemoryIndexReader::termDocs() - { - return termPositions(); - } +TermPositionsPtr MemoryIndexReader::termPositions() { + return newLucene(shared_from_this()); +} - Collection MemoryIndexReader::getTermFreqVectors(int32_t docNumber) - { - Collection vectors(Collection::newInstance()); - for (MapStringMemoryIndexInfo::iterator fieldName = memoryIndex->fields.begin(); fieldName != memoryIndex->fields.end(); ++fieldName) - vectors.add(getTermFreqVector(docNumber, fieldName->first)); - return vectors; - } +TermDocsPtr MemoryIndexReader::termDocs() { + return termPositions(); +} - void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) - { - for (MapStringMemoryIndexInfo::iterator fieldName = memoryIndex->fields.begin(); fieldName != memoryIndex->fields.end(); ++fieldName) - getTermFreqVector(docNumber, fieldName->first, mapper); +Collection MemoryIndexReader::getTermFreqVectors(int32_t docNumber) { + Collection vectors(Collection::newInstance()); + for (MapStringMemoryIndexInfo::iterator fieldName = memoryIndex->fields.begin(); fieldName != memoryIndex->fields.end(); ++fieldName) { + vectors.add(getTermFreqVector(docNumber, fieldName->first)); } + return vectors; +} - void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) - { - MemoryIndexInfoPtr info(getInfo(field)); - if (!info) - return; - info->sortTerms(); - mapper->setExpectations(field, info->sortedTerms.size(), memoryIndex->stride != 1, true); - for (int32_t i = info->sortedTerms.size(); --i >=0;) - { - Collection positions(info->sortedTerms[i].second); - int32_t size = positions.size(); - Collection offsets(Collection::newInstance(size / memoryIndex->stride)); - for (int32_t k = 0, j = 1; j < size; ++k, j += memoryIndex->stride) - { - int32_t start = positions[j]; - int32_t end = positions[j + 1]; - offsets[k] = newLucene(start, end); - } - mapper->map(info->sortedTerms[i].first, memoryIndex->numPositions(info->sortedTerms[i].second), offsets, info->sortedTerms[i].second); - } +void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { + for (MapStringMemoryIndexInfo::iterator fieldName = memoryIndex->fields.begin(); fieldName != memoryIndex->fields.end(); ++fieldName) { + getTermFreqVector(docNumber, fieldName->first, mapper); } +} - TermFreqVectorPtr MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field) - { - MemoryIndexInfoPtr info(getInfo(field)); - if (!info) - return TermFreqVectorPtr(); - info->sortTerms(); - return newLucene(shared_from_this(), info, field); - } - - SimilarityPtr MemoryIndexReader::getSimilarity() - { - SearcherPtr searcher(_searcher.lock()); - if (searcher) - return searcher->getSimilarity(); - return Similarity::getDefault(); - } - - void MemoryIndexReader::setSearcher(const SearcherPtr& searcher) - { - _searcher = searcher; - } - - ByteArray MemoryIndexReader::norms(const String& field) - { - ByteArray norms(cachedNorms); - SimilarityPtr sim(getSimilarity()); - if (field != cachedFieldName || sim != cachedSimilarity) // not cached? - { - MemoryIndexInfoPtr info(getInfo(field)); - int32_t numTokens = info ? info->numTokens : 0; - int32_t numOverlapTokens = info ? info->numOverlapTokens : 0; - double boost = info ? info->getBoost() : 1.0; - FieldInvertStatePtr invertState(newLucene(0, numTokens, numOverlapTokens, 0, boost)); - double n = sim->computeNorm(field, invertState); - uint8_t norm = Similarity::encodeNorm(n); - norms = ByteArray::newInstance(1); - norms[0] = norm; - - // cache it for future reuse - cachedNorms = norms; - cachedFieldName = field; - cachedSimilarity = sim; +void MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { + MemoryIndexInfoPtr info(getInfo(field)); + if (!info) { + return; + } + info->sortTerms(); + mapper->setExpectations(field, info->sortedTerms.size(), memoryIndex->stride != 1, true); + for (int32_t i = info->sortedTerms.size(); --i >=0;) { + Collection positions(info->sortedTerms[i].second); + int32_t size = positions.size(); + Collection offsets(Collection::newInstance(size / memoryIndex->stride)); + for (int32_t k = 0, j = 1; j < size; ++k, j += memoryIndex->stride) { + int32_t start = positions[j]; + int32_t end = positions[j + 1]; + offsets[k] = newLucene(start, end); } - return norms; + mapper->map(info->sortedTerms[i].first, memoryIndex->numPositions(info->sortedTerms[i].second), offsets, info->sortedTerms[i].second); } +} - void MemoryIndexReader::norms(const String& field, ByteArray norms, int32_t offset) - { - ByteArray _norms(this->norms(field)); - MiscUtils::arrayCopy(_norms.get(), 0, norms.get(), offset, _norms.size()); +TermFreqVectorPtr MemoryIndexReader::getTermFreqVector(int32_t docNumber, const String& field) { + MemoryIndexInfoPtr info(getInfo(field)); + if (!info) { + return TermFreqVectorPtr(); } + info->sortTerms(); + return newLucene(shared_from_this(), info, field); +} - void MemoryIndexReader::doSetNorm(int32_t doc, const String& field, uint8_t value) - { - boost::throw_exception(UnsupportedOperationException()); +SimilarityPtr MemoryIndexReader::getSimilarity() { + SearcherPtr searcher(_searcher.lock()); + if (searcher) { + return searcher->getSimilarity(); } + return Similarity::getDefault(); +} - int32_t MemoryIndexReader::numDocs() - { - return memoryIndex->fields.empty() ? 0 : 1; - } +void MemoryIndexReader::setSearcher(const SearcherPtr& searcher) { + _searcher = searcher; +} - int32_t MemoryIndexReader::maxDoc() - { - return 1; - } +ByteArray MemoryIndexReader::norms(const String& field) { + ByteArray norms(cachedNorms); + SimilarityPtr sim(getSimilarity()); + if (field != cachedFieldName || sim != cachedSimilarity) { // not cached? + MemoryIndexInfoPtr info(getInfo(field)); + int32_t numTokens = info ? info->numTokens : 0; + int32_t numOverlapTokens = info ? info->numOverlapTokens : 0; + double boost = info ? info->getBoost() : 1.0; + FieldInvertStatePtr invertState(newLucene(0, numTokens, numOverlapTokens, 0, boost)); + double n = sim->computeNorm(field, invertState); + uint8_t norm = Similarity::encodeNorm(n); + norms = ByteArray::newInstance(1); + norms[0] = norm; + + // cache it for future reuse + cachedNorms = norms; + cachedFieldName = field; + cachedSimilarity = sim; + } + return norms; +} - DocumentPtr MemoryIndexReader::document(int32_t n) - { - return newLucene(); // there are no stored fields - } +void MemoryIndexReader::norms(const String& field, ByteArray norms, int32_t offset) { + ByteArray _norms(this->norms(field)); + MiscUtils::arrayCopy(_norms.get(), 0, norms.get(), offset, _norms.size()); +} - DocumentPtr MemoryIndexReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) - { - return newLucene(); // there are no stored fields - } +void MemoryIndexReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { + boost::throw_exception(UnsupportedOperationException()); +} - bool MemoryIndexReader::isDeleted(int32_t n) - { - return false; - } +int32_t MemoryIndexReader::numDocs() { + return memoryIndex->fields.empty() ? 0 : 1; +} - bool MemoryIndexReader::hasDeletions() - { - return false; - } +int32_t MemoryIndexReader::maxDoc() { + return 1; +} - void MemoryIndexReader::doDelete(int32_t docNum) - { - boost::throw_exception(UnsupportedOperationException()); - } +DocumentPtr MemoryIndexReader::document(int32_t n) { + return newLucene(); // there are no stored fields +} - void MemoryIndexReader::doUndeleteAll() - { - boost::throw_exception(UnsupportedOperationException()); - } +DocumentPtr MemoryIndexReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { + return newLucene(); // there are no stored fields +} - void MemoryIndexReader::doCommit(MapStringString commitUserData) - { - } +bool MemoryIndexReader::isDeleted(int32_t n) { + return false; +} - void MemoryIndexReader::doClose() - { - } +bool MemoryIndexReader::hasDeletions() { + return false; +} - HashSet MemoryIndexReader::getFieldNames(FieldOption fieldOption) - { - static HashSet emptySet; - if (!emptySet) - emptySet = HashSet::newInstance(); - if (fieldOption == FIELD_OPTION_UNINDEXED) - return emptySet; - if (fieldOption == FIELD_OPTION_INDEXED_NO_TERMVECTOR) - return emptySet; - if (fieldOption == FIELD_OPTION_TERMVECTOR_WITH_OFFSET && memoryIndex->stride == 1) - return emptySet; - if (fieldOption == FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET && memoryIndex->stride == 1) - return emptySet; - HashSet fieldSet(HashSet::newInstance()); - for (MapStringMemoryIndexInfo::iterator field = memoryIndex->fields.begin(); field != memoryIndex->fields.end(); ++field) - fieldSet.add(field->first); - return fieldSet; - } +void MemoryIndexReader::doDelete(int32_t docNum) { + boost::throw_exception(UnsupportedOperationException()); +} - MemoryIndexTermEnum::MemoryIndexTermEnum(const MemoryIndexReaderPtr& reader, int32_t ix, int32_t jx) - { - _reader = reader; - i = ix; - j = jx; - } +void MemoryIndexReader::doUndeleteAll() { + boost::throw_exception(UnsupportedOperationException()); +} - MemoryIndexTermEnum::~MemoryIndexTermEnum() - { - } +void MemoryIndexReader::doCommit(MapStringString commitUserData) { +} - bool MemoryIndexTermEnum::next() - { - MemoryIndexReaderPtr reader(_reader); - if (j >= reader->memoryIndex->sortedFields.size()) - return false; - MemoryIndexInfoPtr info(reader->getInfo(j)); - if (++i < info->sortedTerms.size()) - return true; - - // move to successor - ++j; - i = 0; - if (j >= reader->memoryIndex->sortedFields.size()) - return false; - reader->getInfo(j)->sortTerms(); - return true; - } +void MemoryIndexReader::doClose() { +} - TermPtr MemoryIndexTermEnum::term() - { - MemoryIndexReaderPtr reader(_reader); - if (j >= reader->memoryIndex->sortedFields.size()) - return TermPtr(); - MemoryIndexInfoPtr info(reader->getInfo(j)); - if (i >= info->sortedTerms.size()) - return TermPtr(); - return createTerm(info, j, info->sortedTerms[i].first); +HashSet MemoryIndexReader::getFieldNames(FieldOption fieldOption) { + static HashSet emptySet; + if (!emptySet) { + emptySet = HashSet::newInstance(); } - - int32_t MemoryIndexTermEnum::docFreq() - { - MemoryIndexReaderPtr reader(_reader); - if (j >= reader->memoryIndex->sortedFields.size()) - return 0; - MemoryIndexInfoPtr info(reader->getInfo(j)); - if (i >= info->sortedTerms.size()) - return 0; - return reader->memoryIndex->numPositions(info->getPositions(i)); - } - - void MemoryIndexTermEnum::close() - { - } - - TermPtr MemoryIndexTermEnum::createTerm(const MemoryIndexInfoPtr& info, int32_t pos, const String& text) - { - TermPtr _template(info->_template); - if (!_template) // not yet cached? - { - MemoryIndexReaderPtr reader(_reader); - String fieldName(reader->memoryIndex->sortedFields[pos].first); - _template = newLucene(fieldName); - info->_template = _template; - } - return _template->createTerm(text); + if (fieldOption == FIELD_OPTION_UNINDEXED) { + return emptySet; } - - MemoryIndexCollector::MemoryIndexCollector(Collection scores) - { - this->scores = scores; + if (fieldOption == FIELD_OPTION_INDEXED_NO_TERMVECTOR) { + return emptySet; } - - MemoryIndexCollector::~MemoryIndexCollector() - { + if (fieldOption == FIELD_OPTION_TERMVECTOR_WITH_OFFSET && memoryIndex->stride == 1) { + return emptySet; } - - void MemoryIndexCollector::collect(int32_t doc) - { - scores[0] = scorer->score(); + if (fieldOption == FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET && memoryIndex->stride == 1) { + return emptySet; } - - void MemoryIndexCollector::setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; + HashSet fieldSet(HashSet::newInstance()); + for (MapStringMemoryIndexInfo::iterator field = memoryIndex->fields.begin(); field != memoryIndex->fields.end(); ++field) { + fieldSet.add(field->first); } + return fieldSet; +} - bool MemoryIndexCollector::acceptsDocsOutOfOrder() - { - return true; - } +MemoryIndexTermEnum::MemoryIndexTermEnum(const MemoryIndexReaderPtr& reader, int32_t ix, int32_t jx) { + _reader = reader; + i = ix; + j = jx; +} - void MemoryIndexCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - } +MemoryIndexTermEnum::~MemoryIndexTermEnum() { +} - MemoryIndexTermPositions::MemoryIndexTermPositions(const MemoryIndexReaderPtr& reader) - { - _reader = reader; - hasNext = false; - cursor = 0; +bool MemoryIndexTermEnum::next() { + MemoryIndexReaderPtr reader(_reader); + if (j >= reader->memoryIndex->sortedFields.size()) { + return false; } - - MemoryIndexTermPositions::~MemoryIndexTermPositions() - { + MemoryIndexInfoPtr info(reader->getInfo(j)); + if (++i < info->sortedTerms.size()) { + return true; } - void MemoryIndexTermPositions::seek(const TermPtr& term) - { - this->term = term; - if (!term) - hasNext = true; // term == null means match all docs - else - { - MemoryIndexReaderPtr reader(_reader); - MemoryIndexInfoPtr info(reader->getInfo(term->field())); - current = info ? info->getPositions(term->text()) : Collection(); - hasNext = current; - cursor = 0; - } + // move to successor + ++j; + i = 0; + if (j >= reader->memoryIndex->sortedFields.size()) { + return false; } + reader->getInfo(j)->sortTerms(); + return true; +} - void MemoryIndexTermPositions::seek(const TermEnumPtr& termEnum) - { - seek(termEnum->term()); +TermPtr MemoryIndexTermEnum::term() { + MemoryIndexReaderPtr reader(_reader); + if (j >= reader->memoryIndex->sortedFields.size()) { + return TermPtr(); } + MemoryIndexInfoPtr info(reader->getInfo(j)); + if (i >= info->sortedTerms.size()) { + return TermPtr(); + } + return createTerm(info, j, info->sortedTerms[i].first); +} - int32_t MemoryIndexTermPositions::doc() - { +int32_t MemoryIndexTermEnum::docFreq() { + MemoryIndexReaderPtr reader(_reader); + if (j >= reader->memoryIndex->sortedFields.size()) { + return 0; + } + MemoryIndexInfoPtr info(reader->getInfo(j)); + if (i >= info->sortedTerms.size()) { return 0; } + return reader->memoryIndex->numPositions(info->getPositions(i)); +} + +void MemoryIndexTermEnum::close() { +} - int32_t MemoryIndexTermPositions::freq() - { +TermPtr MemoryIndexTermEnum::createTerm(const MemoryIndexInfoPtr& info, int32_t pos, const String& text) { + TermPtr _template(info->_template); + if (!_template) { // not yet cached? MemoryIndexReaderPtr reader(_reader); - int32_t freq = current ? reader->memoryIndex->numPositions(current) : (term ? 0 : 1); - return freq; + String fieldName(reader->memoryIndex->sortedFields[pos].first); + _template = newLucene(fieldName); + info->_template = _template; } + return _template->createTerm(text); +} - bool MemoryIndexTermPositions::next() - { - bool _next = hasNext; - hasNext = false; - return _next; - } +MemoryIndexCollector::MemoryIndexCollector(Collection scores) { + this->scores = scores; +} - int32_t MemoryIndexTermPositions::read(Collection docs, Collection freqs) - { - if (!hasNext) - return 0; - hasNext = false; - docs[0] = 0; - freqs[0] = freq(); - return 1; - } +MemoryIndexCollector::~MemoryIndexCollector() { +} - bool MemoryIndexTermPositions::skipTo(int32_t target) - { - return next(); - } +void MemoryIndexCollector::collect(int32_t doc) { + scores[0] = scorer->score(); +} - void MemoryIndexTermPositions::close() - { - } +void MemoryIndexCollector::setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; +} + +bool MemoryIndexCollector::acceptsDocsOutOfOrder() { + return true; +} + +void MemoryIndexCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { +} + +MemoryIndexTermPositions::MemoryIndexTermPositions(const MemoryIndexReaderPtr& reader) { + _reader = reader; + hasNext = false; + cursor = 0; +} - int32_t MemoryIndexTermPositions::nextPosition() - { - // implements TermPositions +MemoryIndexTermPositions::~MemoryIndexTermPositions() { +} + +void MemoryIndexTermPositions::seek(const TermPtr& term) { + this->term = term; + if (!term) { + hasNext = true; // term == null means match all docs + } else { MemoryIndexReaderPtr reader(_reader); - int32_t pos = current[cursor]; - cursor += reader->memoryIndex->stride; - return pos; + MemoryIndexInfoPtr info(reader->getInfo(term->field())); + current = info ? info->getPositions(term->text()) : Collection(); + hasNext = current; + cursor = 0; } +} - int32_t MemoryIndexTermPositions::getPayloadLength() - { - boost::throw_exception(UnsupportedOperationException()); - } +void MemoryIndexTermPositions::seek(const TermEnumPtr& termEnum) { + seek(termEnum->term()); +} - ByteArray MemoryIndexTermPositions::getPayload(ByteArray data, int32_t offset) - { - boost::throw_exception(UnsupportedOperationException()); - return ByteArray(); - } +int32_t MemoryIndexTermPositions::doc() { + return 0; +} - bool MemoryIndexTermPositions::isPayloadAvailable() - { - return false; // unsupported - } +int32_t MemoryIndexTermPositions::freq() { + MemoryIndexReaderPtr reader(_reader); + int32_t freq = current ? reader->memoryIndex->numPositions(current) : (term ? 0 : 1); + return freq; +} - MemoryIndexTermPositionVector::MemoryIndexTermPositionVector(const MemoryIndexReaderPtr& reader, const MemoryIndexInfoPtr& info, const String& fieldName) - { - this->_reader = reader; - this->sortedTerms = info->sortedTerms; - this->fieldName = fieldName; - } +bool MemoryIndexTermPositions::next() { + bool _next = hasNext; + hasNext = false; + return _next; +} - MemoryIndexTermPositionVector::~MemoryIndexTermPositionVector() - { +int32_t MemoryIndexTermPositions::read(Collection docs, Collection freqs) { + if (!hasNext) { + return 0; } + hasNext = false; + docs[0] = 0; + freqs[0] = freq(); + return 1; +} - String MemoryIndexTermPositionVector::getField() - { - return fieldName; - } +bool MemoryIndexTermPositions::skipTo(int32_t target) { + return next(); +} - int32_t MemoryIndexTermPositionVector::size() - { - return sortedTerms.size(); - } +void MemoryIndexTermPositions::close() { +} - Collection MemoryIndexTermPositionVector::getTerms() - { - Collection terms(Collection::newInstance(sortedTerms.size())); - for (int32_t i = sortedTerms.size(); --i >= 0;) - terms[i] = sortedTerms[i].first; - return terms; - } +int32_t MemoryIndexTermPositions::nextPosition() { + // implements TermPositions + MemoryIndexReaderPtr reader(_reader); + int32_t pos = current[cursor]; + cursor += reader->memoryIndex->stride; + return pos; +} - Collection MemoryIndexTermPositionVector::getTermFrequencies() - { - MemoryIndexReaderPtr reader(_reader); - Collection freqs(Collection::newInstance(sortedTerms.size())); - for (int32_t i = sortedTerms.size(); --i >= 0;) - freqs[i] = reader->memoryIndex->numPositions(sortedTerms[i].second); - return freqs; - } +int32_t MemoryIndexTermPositions::getPayloadLength() { + boost::throw_exception(UnsupportedOperationException()); +} - int32_t MemoryIndexTermPositionVector::indexOf(const String& term) - { - CollectionStringIntCollection::iterator search = std::lower_bound(sortedTerms.begin(), sortedTerms.end(), std::make_pair(term, Collection()), lessTerm()); - return (search == sortedTerms.end() || term < search->first) ? -1 : std::distance(sortedTerms.begin(), search); +ByteArray MemoryIndexTermPositions::getPayload(ByteArray data, int32_t offset) { + boost::throw_exception(UnsupportedOperationException()); + return ByteArray(); +} + +bool MemoryIndexTermPositions::isPayloadAvailable() { + return false; // unsupported +} + +MemoryIndexTermPositionVector::MemoryIndexTermPositionVector(const MemoryIndexReaderPtr& reader, const MemoryIndexInfoPtr& info, const String& fieldName) { + this->_reader = reader; + this->sortedTerms = info->sortedTerms; + this->fieldName = fieldName; +} + +MemoryIndexTermPositionVector::~MemoryIndexTermPositionVector() { +} + +String MemoryIndexTermPositionVector::getField() { + return fieldName; +} + +int32_t MemoryIndexTermPositionVector::size() { + return sortedTerms.size(); +} + +Collection MemoryIndexTermPositionVector::getTerms() { + Collection terms(Collection::newInstance(sortedTerms.size())); + for (int32_t i = sortedTerms.size(); --i >= 0;) { + terms[i] = sortedTerms[i].first; } + return terms; +} - Collection MemoryIndexTermPositionVector::indexesOf(Collection terms, int32_t start, int32_t length) - { - Collection indexes(Collection::newInstance(length)); - for (int32_t i = 0; i < length; ++i) - indexes[i] = indexOf(terms[start++]); - return indexes; +Collection MemoryIndexTermPositionVector::getTermFrequencies() { + MemoryIndexReaderPtr reader(_reader); + Collection freqs(Collection::newInstance(sortedTerms.size())); + for (int32_t i = sortedTerms.size(); --i >= 0;) { + freqs[i] = reader->memoryIndex->numPositions(sortedTerms[i].second); } + return freqs; +} - Collection MemoryIndexTermPositionVector::getTermPositions(int32_t index) - { - return sortedTerms[index].second; +int32_t MemoryIndexTermPositionVector::indexOf(const String& term) { + CollectionStringIntCollection::iterator search = std::lower_bound(sortedTerms.begin(), sortedTerms.end(), std::make_pair(term, Collection()), lessTerm()); + return (search == sortedTerms.end() || term < search->first) ? -1 : std::distance(sortedTerms.begin(), search); +} + +Collection MemoryIndexTermPositionVector::indexesOf(Collection terms, int32_t start, int32_t length) { + Collection indexes(Collection::newInstance(length)); + for (int32_t i = 0; i < length; ++i) { + indexes[i] = indexOf(terms[start++]); } + return indexes; +} - Collection MemoryIndexTermPositionVector::getOffsets(int32_t index) - { - MemoryIndexReaderPtr reader(_reader); - if (reader->memoryIndex->stride == 1) - return Collection(); // no offsets stored +Collection MemoryIndexTermPositionVector::getTermPositions(int32_t index) { + return sortedTerms[index].second; +} - Collection positions(sortedTerms[index].second); - int32_t size = positions.size(); - Collection offsets(Collection::newInstance(size / reader->memoryIndex->stride)); - for (int32_t i = 0, j = 1; j < size; ++i, j += reader->memoryIndex->stride) - { - int32_t start = positions[j]; - int32_t end = positions[j + 1]; - offsets[i] = newLucene(start, end); - } - return offsets; +Collection MemoryIndexTermPositionVector::getOffsets(int32_t index) { + MemoryIndexReaderPtr reader(_reader); + if (reader->memoryIndex->stride == 1) { + return Collection(); // no offsets stored + } + + Collection positions(sortedTerms[index].second); + int32_t size = positions.size(); + Collection offsets(Collection::newInstance(size / reader->memoryIndex->stride)); + for (int32_t i = 0, j = 1; j < size; ++i, j += reader->memoryIndex->stride) { + int32_t start = positions[j]; + int32_t end = positions[j + 1]; + offsets[i] = newLucene(start, end); } + return offsets; +} + } diff --git a/src/contrib/msvc/dllmain.cpp b/src/contrib/msvc/dllmain.cpp index 4373bf84..a7be1fca 100644 --- a/src/contrib/msvc/dllmain.cpp +++ b/src/contrib/msvc/dllmain.cpp @@ -8,15 +8,13 @@ #if defined(_WIN32) && defined(LPP_HAVE_DLL) -BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; +BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; } return TRUE; } diff --git a/src/contrib/snowball/SnowballAnalyzer.cpp b/src/contrib/snowball/SnowballAnalyzer.cpp index d93845a0..2fa4444e 100644 --- a/src/contrib/snowball/SnowballAnalyzer.cpp +++ b/src/contrib/snowball/SnowballAnalyzer.cpp @@ -12,56 +12,52 @@ #include "StopFilter.h" #include "SnowballFilter.h" -namespace Lucene -{ - SnowballAnalyzer::SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name) - { - this->matchVersion = matchVersion; - this->name = name; - } +namespace Lucene { - SnowballAnalyzer::SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name, HashSet stopwords) - { - this->stopSet = stopwords; - this->matchVersion = matchVersion; - this->name = name; - } +SnowballAnalyzer::SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name) { + this->matchVersion = matchVersion; + this->name = name; +} - SnowballAnalyzer::~SnowballAnalyzer() - { - } +SnowballAnalyzer::SnowballAnalyzer(LuceneVersion::Version matchVersion, const String& name, HashSet stopwords) { + this->stopSet = stopwords; + this->matchVersion = matchVersion; + this->name = name; +} + +SnowballAnalyzer::~SnowballAnalyzer() { +} - TokenStreamPtr SnowballAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(matchVersion, reader); - result = newLucene(result); - result = newLucene(result); - if (stopSet) - result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); - result = newLucene(result, name); - return result; +TokenStreamPtr SnowballAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(matchVersion, reader); + result = newLucene(result); + result = newLucene(result); + if (stopSet) { + result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), result, stopSet); } + result = newLucene(result, name); + return result; +} - TokenStreamPtr SnowballAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - SnowballAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(matchVersion, reader); - streams->result = newLucene(streams->source); - streams->result = newLucene(streams->result); - if (stopSet) - streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); - streams->result = newLucene(streams->result, name); - setPreviousTokenStream(streams); +TokenStreamPtr SnowballAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + SnowballAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(matchVersion, reader); + streams->result = newLucene(streams->source); + streams->result = newLucene(streams->result); + if (stopSet) { + streams->result = newLucene(StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion), streams->result, stopSet); } - else - streams->source->reset(reader); - return streams->result; + streams->result = newLucene(streams->result, name); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +SnowballAnalyzerSavedStreams::~SnowballAnalyzerSavedStreams() { +} - SnowballAnalyzerSavedStreams::~SnowballAnalyzerSavedStreams() - { - } } diff --git a/src/contrib/snowball/SnowballFilter.cpp b/src/contrib/snowball/SnowballFilter.cpp index 6e0d5deb..adb86b53 100644 --- a/src/contrib/snowball/SnowballFilter.cpp +++ b/src/contrib/snowball/SnowballFilter.cpp @@ -12,34 +12,33 @@ #include "StringUtils.h" #include "libstemmer_c/include/libstemmer.h" -namespace Lucene -{ - SnowballFilter::SnowballFilter(const TokenStreamPtr& input, const String& name) : TokenFilter(input) - { - stemmer = sb_stemmer_new(StringUtils::toUTF8(name).c_str(), "UTF_8"); - if (stemmer == NULL) - boost::throw_exception(IllegalArgumentException(L"language not available for stemming:" + name)); - termAtt = addAttribute(); - utf8Result = newLucene(); - } +namespace Lucene { - SnowballFilter::~SnowballFilter() - { +SnowballFilter::SnowballFilter(const TokenStreamPtr& input, const String& name) : TokenFilter(input) { + stemmer = sb_stemmer_new(StringUtils::toUTF8(name).c_str(), "UTF_8"); + if (stemmer == NULL) { + boost::throw_exception(IllegalArgumentException(L"language not available for stemming:" + name)); } + termAtt = addAttribute(); + utf8Result = newLucene(); +} + +SnowballFilter::~SnowballFilter() { +} - bool SnowballFilter::incrementToken() - { - if (input->incrementToken()) - { - StringUtils::toUTF8(termAtt->termBuffer().get(), termAtt->termLength(), utf8Result); - const sb_symbol* stemmed = sb_stemmer_stem(stemmer, utf8Result->result.get(), utf8Result->length); - if (stemmed == NULL) - boost::throw_exception(RuntimeException(L"exception stemming word:" + termAtt->term())); - int32_t newlen = StringUtils::toUnicode(stemmed, sb_stemmer_length(stemmer), termAtt->termBuffer()); - termAtt->setTermLength(newlen); - return true; +bool SnowballFilter::incrementToken() { + if (input->incrementToken()) { + StringUtils::toUTF8(termAtt->termBuffer().get(), termAtt->termLength(), utf8Result); + const sb_symbol* stemmed = sb_stemmer_stem(stemmer, utf8Result->result.get(), utf8Result->length); + if (stemmed == NULL) { + boost::throw_exception(RuntimeException(L"exception stemming word:" + termAtt->term())); } - else - return false; + int32_t newlen = StringUtils::toUnicode(stemmed, sb_stemmer_length(stemmer), termAtt->termBuffer()); + termAtt->setTermLength(newlen); + return true; + } else { + return false; } } + +} diff --git a/src/contrib/snowball/libstemmer_c/include/libstemmer.h b/src/contrib/snowball/libstemmer_c/include/libstemmer.h index 9d86b858..8892a2b0 100644 --- a/src/contrib/snowball/libstemmer_c/include/libstemmer.h +++ b/src/contrib/snowball/libstemmer_c/include/libstemmer.h @@ -17,7 +17,7 @@ typedef unsigned char sb_symbol; * * The list must not be modified in any way. */ -const char ** sb_stemmer_list(void); +const char** sb_stemmer_list(void); /** Create a new stemmer object, using the specified algorithm, for the * specified character encoding. @@ -43,7 +43,7 @@ const char ** sb_stemmer_list(void); * * @note NULL will also be returned if an out of memory error occurs. */ -struct sb_stemmer * sb_stemmer_new(const char * algorithm, const char * charenc); +struct sb_stemmer* sb_stemmer_new(const char* algorithm, const char* charenc); /** Delete a stemmer object. * @@ -53,7 +53,7 @@ struct sb_stemmer * sb_stemmer_new(const char * algorithm, const char * charenc) * It is safe to pass a null pointer to this function - this will have * no effect. */ -void sb_stemmer_delete(struct sb_stemmer * stemmer); +void sb_stemmer_delete(struct sb_stemmer* stemmer); /** Stem a word. * @@ -65,13 +65,13 @@ void sb_stemmer_delete(struct sb_stemmer * stemmer); * * If an out-of-memory error occurs, this will return NULL. */ -const sb_symbol * sb_stemmer_stem(struct sb_stemmer * stemmer, - const sb_symbol * word, int size); +const sb_symbol* sb_stemmer_stem(struct sb_stemmer* stemmer, + const sb_symbol* word, int size); /** Get the length of the result of the last stemmed word. * This should not be called before sb_stemmer_stem() has been called. */ -int sb_stemmer_length(struct sb_stemmer * stemmer); +int sb_stemmer_length(struct sb_stemmer* stemmer); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/libstemmer/modules.h b/src/contrib/snowball/libstemmer_c/libstemmer/modules.h index 7a1f6856..cbe0431c 100644 --- a/src/contrib/snowball/libstemmer_c/libstemmer/modules.h +++ b/src/contrib/snowball/libstemmer_c/libstemmer/modules.h @@ -41,150 +41,150 @@ #include "../src_c/stem_UTF_8_turkish.h" typedef enum { - ENC_UNKNOWN=0, - ENC_ISO_8859_1, - ENC_ISO_8859_2, - ENC_KOI8_R, - ENC_UTF_8 + ENC_UNKNOWN=0, + ENC_ISO_8859_1, + ENC_ISO_8859_2, + ENC_KOI8_R, + ENC_UTF_8 } stemmer_encoding_t; struct stemmer_encoding { - const char * name; - stemmer_encoding_t enc; + const char* name; + stemmer_encoding_t enc; }; static struct stemmer_encoding encodings[] = { - {"ISO_8859_1", ENC_ISO_8859_1}, - {"ISO_8859_2", ENC_ISO_8859_2}, - {"KOI8_R", ENC_KOI8_R}, - {"UTF_8", ENC_UTF_8}, - {0,ENC_UNKNOWN} + {"ISO_8859_1", ENC_ISO_8859_1}, + {"ISO_8859_2", ENC_ISO_8859_2}, + {"KOI8_R", ENC_KOI8_R}, + {"UTF_8", ENC_UTF_8}, + {0,ENC_UNKNOWN} }; struct stemmer_modules { - const char * name; - stemmer_encoding_t enc; - struct SN_env * (*create)(void); - void (*close)(struct SN_env *); - int (*stem)(struct SN_env *); + const char* name; + stemmer_encoding_t enc; + struct SN_env* (*create)(void); + void (*close)(struct SN_env*); + int (*stem)(struct SN_env*); }; static struct stemmer_modules modules[] = { - {"da", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, - {"da", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, - {"dan", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, - {"dan", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, - {"danish", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, - {"danish", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, - {"de", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, - {"de", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"deu", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, - {"deu", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"dut", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, - {"dut", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"dutch", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, - {"dutch", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"en", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, - {"en", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, - {"eng", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, - {"eng", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, - {"english", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, - {"english", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, - {"es", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, - {"es", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"esl", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, - {"esl", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"fi", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, - {"fi", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, - {"fin", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, - {"fin", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, - {"finnish", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, - {"finnish", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, - {"fr", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, - {"fr", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"fra", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, - {"fra", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"fre", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, - {"fre", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"french", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, - {"french", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"ger", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, - {"ger", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"german", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, - {"german", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"hu", ENC_ISO_8859_1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem}, - {"hu", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, - {"hun", ENC_ISO_8859_1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem}, - {"hun", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, - {"hungarian", ENC_ISO_8859_1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem}, - {"hungarian", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, - {"it", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, - {"it", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, - {"ita", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, - {"ita", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, - {"italian", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, - {"italian", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, - {"nl", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, - {"nl", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"nld", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, - {"nld", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"no", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, - {"no", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, - {"nor", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, - {"nor", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, - {"norwegian", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, - {"norwegian", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, - {"por", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, - {"por", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, - {"porter", ENC_ISO_8859_1, porter_ISO_8859_1_create_env, porter_ISO_8859_1_close_env, porter_ISO_8859_1_stem}, - {"porter", ENC_UTF_8, porter_UTF_8_create_env, porter_UTF_8_close_env, porter_UTF_8_stem}, - {"portuguese", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, - {"portuguese", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, - {"pt", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, - {"pt", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, - {"ro", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, - {"ro", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"romanian", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, - {"romanian", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"ron", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, - {"ron", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"ru", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, - {"ru", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, - {"rum", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, - {"rum", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"rus", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, - {"rus", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, - {"russian", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, - {"russian", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, - {"spa", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, - {"spa", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"spanish", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, - {"spanish", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"sv", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, - {"sv", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, - {"swe", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, - {"swe", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, - {"swedish", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, - {"swedish", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, - {"tr", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, - {"tur", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, - {"turkish", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, - {0,ENC_UNKNOWN,0,0,0} + {"da", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, + {"da", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"dan", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, + {"dan", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"danish", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, + {"danish", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"de", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"de", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"deu", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"deu", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"dut", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"dut", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"dutch", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"dutch", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"en", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, + {"en", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"eng", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, + {"eng", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"english", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, + {"english", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"es", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"es", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"esl", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"esl", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"fi", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, + {"fi", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"fin", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, + {"fin", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"finnish", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, + {"finnish", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"fr", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"fr", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"fra", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"fra", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"fre", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"fre", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"french", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"french", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"ger", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"ger", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"german", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"german", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"hu", ENC_ISO_8859_1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem}, + {"hu", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, + {"hun", ENC_ISO_8859_1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem}, + {"hun", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, + {"hungarian", ENC_ISO_8859_1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem}, + {"hungarian", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, + {"it", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, + {"it", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"ita", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, + {"ita", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"italian", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, + {"italian", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"nl", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"nl", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"nld", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"nld", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"no", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, + {"no", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"nor", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, + {"nor", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"norwegian", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, + {"norwegian", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"por", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, + {"por", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"porter", ENC_ISO_8859_1, porter_ISO_8859_1_create_env, porter_ISO_8859_1_close_env, porter_ISO_8859_1_stem}, + {"porter", ENC_UTF_8, porter_UTF_8_create_env, porter_UTF_8_close_env, porter_UTF_8_stem}, + {"portuguese", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, + {"portuguese", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"pt", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, + {"pt", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"ro", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, + {"ro", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"romanian", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, + {"romanian", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"ron", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, + {"ron", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"ru", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, + {"ru", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"rum", ENC_ISO_8859_2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, + {"rum", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"rus", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, + {"rus", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"russian", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, + {"russian", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"spa", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"spa", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"spanish", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"spanish", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"sv", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, + {"sv", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"swe", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, + {"swe", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"swedish", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, + {"swedish", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"tr", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, + {"tur", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, + {"turkish", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, + {0,ENC_UNKNOWN,0,0,0} }; -static const char * algorithm_names[] = { - "danish", - "dutch", - "english", - "finnish", - "french", - "german", - "hungarian", - "italian", - "norwegian", - "porter", - "portuguese", - "romanian", - "russian", - "spanish", - "swedish", - "turkish", - 0 +static const char* algorithm_names[] = { + "danish", + "dutch", + "english", + "finnish", + "french", + "german", + "hungarian", + "italian", + "norwegian", + "porter", + "portuguese", + "romanian", + "russian", + "spanish", + "swedish", + "turkish", + 0 }; diff --git a/src/contrib/snowball/libstemmer_c/libstemmer/modules_utf8.h b/src/contrib/snowball/libstemmer_c/libstemmer/modules_utf8.h index 6a7cc924..47c845fb 100644 --- a/src/contrib/snowball/libstemmer_c/libstemmer/modules_utf8.h +++ b/src/contrib/snowball/libstemmer_c/libstemmer/modules_utf8.h @@ -26,96 +26,96 @@ #include "../src_c/stem_UTF_8_turkish.h" typedef enum { - ENC_UNKNOWN=0, - ENC_UTF_8 + ENC_UNKNOWN=0, + ENC_UTF_8 } stemmer_encoding_t; struct stemmer_encoding { - const char * name; - stemmer_encoding_t enc; + const char* name; + stemmer_encoding_t enc; }; static struct stemmer_encoding encodings[] = { - {"UTF_8", ENC_UTF_8}, - {0,ENC_UNKNOWN} + {"UTF_8", ENC_UTF_8}, + {0,ENC_UNKNOWN} }; struct stemmer_modules { - const char * name; - stemmer_encoding_t enc; - struct SN_env * (*create)(void); - void (*close)(struct SN_env *); - int (*stem)(struct SN_env *); + const char* name; + stemmer_encoding_t enc; + struct SN_env* (*create)(void); + void (*close)(struct SN_env*); + int (*stem)(struct SN_env*); }; static struct stemmer_modules modules[] = { - {"da", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, - {"dan", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, - {"danish", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, - {"de", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"deu", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"dut", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"dutch", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"en", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, - {"eng", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, - {"english", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, - {"es", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"esl", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"fi", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, - {"fin", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, - {"finnish", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, - {"fr", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"fra", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"fre", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"french", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"ger", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"german", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"hu", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, - {"hun", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, - {"hungarian", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, - {"it", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, - {"ita", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, - {"italian", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, - {"nl", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"nld", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"no", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, - {"nor", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, - {"norwegian", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, - {"por", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, - {"porter", ENC_UTF_8, porter_UTF_8_create_env, porter_UTF_8_close_env, porter_UTF_8_stem}, - {"portuguese", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, - {"pt", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, - {"ro", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"romanian", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"ron", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"ru", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, - {"rum", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"rus", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, - {"russian", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, - {"spa", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"spanish", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"sv", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, - {"swe", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, - {"swedish", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, - {"tr", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, - {"tur", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, - {"turkish", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, - {0,ENC_UNKNOWN,0,0,0} + {"da", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"dan", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"danish", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"de", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"deu", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"dut", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"dutch", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"en", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"eng", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"english", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"es", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"esl", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"fi", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"fin", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"finnish", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"fr", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"fra", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"fre", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"french", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"ger", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"german", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"hu", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, + {"hun", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, + {"hungarian", ENC_UTF_8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, + {"it", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"ita", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"italian", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"nl", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"nld", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"no", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"nor", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"norwegian", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"por", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"porter", ENC_UTF_8, porter_UTF_8_create_env, porter_UTF_8_close_env, porter_UTF_8_stem}, + {"portuguese", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"pt", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"ro", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"romanian", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"ron", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"ru", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"rum", ENC_UTF_8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, + {"rus", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"russian", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"spa", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"spanish", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"sv", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"swe", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"swedish", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"tr", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, + {"tur", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, + {"turkish", ENC_UTF_8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, + {0,ENC_UNKNOWN,0,0,0} }; -static const char * algorithm_names[] = { - "danish", - "dutch", - "english", - "finnish", - "french", - "german", - "hungarian", - "italian", - "norwegian", - "porter", - "portuguese", - "romanian", - "russian", - "spanish", - "swedish", - "turkish", - 0 +static const char* algorithm_names[] = { + "danish", + "dutch", + "english", + "finnish", + "french", + "german", + "hungarian", + "italian", + "norwegian", + "porter", + "portuguese", + "romanian", + "russian", + "spanish", + "swedish", + "turkish", + 0 }; diff --git a/src/contrib/snowball/libstemmer_c/runtime/api.h b/src/contrib/snowball/libstemmer_c/runtime/api.h index 8b997f0c..5498aa0f 100644 --- a/src/contrib/snowball/libstemmer_c/runtime/api.h +++ b/src/contrib/snowball/libstemmer_c/runtime/api.h @@ -12,15 +12,19 @@ typedef unsigned char symbol; */ struct SN_env { - symbol * p; - int c; int l; int lb; int bra; int ket; - symbol * * S; - int * I; - unsigned char * B; + symbol* p; + int c; + int l; + int lb; + int bra; + int ket; + symbol** S; + int* I; + unsigned char* B; }; -extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size); -extern void SN_close_env(struct SN_env * z, int S_size); +extern struct SN_env* SN_create_env(int S_size, int I_size, int B_size); +extern void SN_close_env(struct SN_env* z, int S_size); -extern int SN_set_current(struct SN_env * z, int size, const symbol * s); +extern int SN_set_current(struct SN_env* z, int size, const symbol* s); diff --git a/src/contrib/snowball/libstemmer_c/runtime/header.h b/src/contrib/snowball/libstemmer_c/runtime/header.h index 4d3078f5..7609f726 100644 --- a/src/contrib/snowball/libstemmer_c/runtime/header.h +++ b/src/contrib/snowball/libstemmer_c/runtime/header.h @@ -12,47 +12,47 @@ #define SET_SIZE(p, n) ((int *)(p))[-1] = n #define CAPACITY(p) ((int *)(p))[-2] -struct among -{ int s_size; /* number of chars in string */ - const symbol * s; /* search string */ +struct among { + int s_size; /* number of chars in string */ + const symbol* s; /* search string */ int substring_i;/* index to longest matching substring */ int result; /* result of the lookup */ - int (* function)(struct SN_env *); + int (* function)(struct SN_env*); }; -extern symbol * create_s(void); -extern void lose_s(symbol * p); +extern symbol* create_s(void); +extern void lose_s(symbol* p); -extern int skip_utf8(const symbol * p, int c, int lb, int l, int n); +extern int skip_utf8(const symbol* p, int c, int lb, int l, int n); -extern int in_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); -extern int in_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); -extern int out_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); -extern int out_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int in_grouping_U(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); +extern int in_grouping_b_U(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); +extern int out_grouping_U(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); +extern int out_grouping_b_U(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); -extern int in_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); -extern int in_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); -extern int out_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); -extern int out_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat); +extern int in_grouping(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); +extern int in_grouping_b(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); +extern int out_grouping(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); +extern int out_grouping_b(struct SN_env* z, const unsigned char* s, int min, int max, int repeat); -extern int eq_s(struct SN_env * z, int s_size, const symbol * s); -extern int eq_s_b(struct SN_env * z, int s_size, const symbol * s); -extern int eq_v(struct SN_env * z, const symbol * p); -extern int eq_v_b(struct SN_env * z, const symbol * p); +extern int eq_s(struct SN_env* z, int s_size, const symbol* s); +extern int eq_s_b(struct SN_env* z, int s_size, const symbol* s); +extern int eq_v(struct SN_env* z, const symbol* p); +extern int eq_v_b(struct SN_env* z, const symbol* p); -extern int find_among(struct SN_env * z, const struct among * v, int v_size); -extern int find_among_b(struct SN_env * z, const struct among * v, int v_size); +extern int find_among(struct SN_env* z, const struct among* v, int v_size); +extern int find_among_b(struct SN_env* z, const struct among* v, int v_size); -extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int * adjustment); -extern int slice_from_s(struct SN_env * z, int s_size, const symbol * s); -extern int slice_from_v(struct SN_env * z, const symbol * p); -extern int slice_del(struct SN_env * z); +extern int replace_s(struct SN_env* z, int c_bra, int c_ket, int s_size, const symbol* s, int* adjustment); +extern int slice_from_s(struct SN_env* z, int s_size, const symbol* s); +extern int slice_from_v(struct SN_env* z, const symbol* p); +extern int slice_del(struct SN_env* z); -extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, const symbol * s); -extern int insert_v(struct SN_env * z, int bra, int ket, const symbol * p); +extern int insert_s(struct SN_env* z, int bra, int ket, int s_size, const symbol* s); +extern int insert_v(struct SN_env* z, int bra, int ket, const symbol* p); -extern symbol * slice_to(struct SN_env * z, symbol * p); -extern symbol * assign_to(struct SN_env * z, symbol * p); +extern symbol* slice_to(struct SN_env* z, symbol* p); +extern symbol* assign_to(struct SN_env* z, symbol* p); -extern void debug(struct SN_env * z, int number, int line_count); +extern void debug(struct SN_env* z, int number, int line_count); diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_danish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_danish.h index 49c5559c..36aba971 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_danish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_danish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * danish_ISO_8859_1_create_env(void); -extern void danish_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* danish_ISO_8859_1_create_env(void); +extern void danish_ISO_8859_1_close_env(struct SN_env* z); -extern int danish_ISO_8859_1_stem(struct SN_env * z); +extern int danish_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_dutch.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_dutch.h index e67d1115..76d06b77 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_dutch.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_dutch.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * dutch_ISO_8859_1_create_env(void); -extern void dutch_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* dutch_ISO_8859_1_create_env(void); +extern void dutch_ISO_8859_1_close_env(struct SN_env* z); -extern int dutch_ISO_8859_1_stem(struct SN_env * z); +extern int dutch_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_english.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_english.h index e685dcf7..2af9dd3d 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_english.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_english.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * english_ISO_8859_1_create_env(void); -extern void english_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* english_ISO_8859_1_create_env(void); +extern void english_ISO_8859_1_close_env(struct SN_env* z); -extern int english_ISO_8859_1_stem(struct SN_env * z); +extern int english_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_finnish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_finnish.h index c67b67b9..3f76446c 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_finnish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_finnish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * finnish_ISO_8859_1_create_env(void); -extern void finnish_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* finnish_ISO_8859_1_create_env(void); +extern void finnish_ISO_8859_1_close_env(struct SN_env* z); -extern int finnish_ISO_8859_1_stem(struct SN_env * z); +extern int finnish_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_french.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_french.h index 21244d61..b966be81 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_french.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_french.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * french_ISO_8859_1_create_env(void); -extern void french_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* french_ISO_8859_1_create_env(void); +extern void french_ISO_8859_1_close_env(struct SN_env* z); -extern int french_ISO_8859_1_stem(struct SN_env * z); +extern int french_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_german.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_german.h index 85253892..0a039f94 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_german.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_german.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * german_ISO_8859_1_create_env(void); -extern void german_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* german_ISO_8859_1_create_env(void); +extern void german_ISO_8859_1_close_env(struct SN_env* z); -extern int german_ISO_8859_1_stem(struct SN_env * z); +extern int german_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_hungarian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_hungarian.h index c3177e50..fb8c6356 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_hungarian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_hungarian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * hungarian_ISO_8859_1_create_env(void); -extern void hungarian_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* hungarian_ISO_8859_1_create_env(void); +extern void hungarian_ISO_8859_1_close_env(struct SN_env* z); -extern int hungarian_ISO_8859_1_stem(struct SN_env * z); +extern int hungarian_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_italian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_italian.h index dccbfd5e..36638442 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_italian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_italian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * italian_ISO_8859_1_create_env(void); -extern void italian_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* italian_ISO_8859_1_create_env(void); +extern void italian_ISO_8859_1_close_env(struct SN_env* z); -extern int italian_ISO_8859_1_stem(struct SN_env * z); +extern int italian_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_norwegian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_norwegian.h index e09e34e5..7764998a 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_norwegian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_norwegian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * norwegian_ISO_8859_1_create_env(void); -extern void norwegian_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* norwegian_ISO_8859_1_create_env(void); +extern void norwegian_ISO_8859_1_close_env(struct SN_env* z); -extern int norwegian_ISO_8859_1_stem(struct SN_env * z); +extern int norwegian_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_porter.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_porter.h index 5c8fd01d..35304144 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_porter.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_porter.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * porter_ISO_8859_1_create_env(void); -extern void porter_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* porter_ISO_8859_1_create_env(void); +extern void porter_ISO_8859_1_close_env(struct SN_env* z); -extern int porter_ISO_8859_1_stem(struct SN_env * z); +extern int porter_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_portuguese.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_portuguese.h index 0279bc94..aa4133bd 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_portuguese.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_portuguese.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * portuguese_ISO_8859_1_create_env(void); -extern void portuguese_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* portuguese_ISO_8859_1_create_env(void); +extern void portuguese_ISO_8859_1_close_env(struct SN_env* z); -extern int portuguese_ISO_8859_1_stem(struct SN_env * z); +extern int portuguese_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_spanish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_spanish.h index 83f14984..2235ac84 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_spanish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_spanish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * spanish_ISO_8859_1_create_env(void); -extern void spanish_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* spanish_ISO_8859_1_create_env(void); +extern void spanish_ISO_8859_1_close_env(struct SN_env* z); -extern int spanish_ISO_8859_1_stem(struct SN_env * z); +extern int spanish_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_swedish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_swedish.h index 4184e5ca..81ae66b5 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_swedish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_1_swedish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * swedish_ISO_8859_1_create_env(void); -extern void swedish_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env* swedish_ISO_8859_1_create_env(void); +extern void swedish_ISO_8859_1_close_env(struct SN_env* z); -extern int swedish_ISO_8859_1_stem(struct SN_env * z); +extern int swedish_ISO_8859_1_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_2_romanian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_2_romanian.h index 931f269c..ebb15c5d 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_2_romanian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_ISO_8859_2_romanian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * romanian_ISO_8859_2_create_env(void); -extern void romanian_ISO_8859_2_close_env(struct SN_env * z); +extern struct SN_env* romanian_ISO_8859_2_create_env(void); +extern void romanian_ISO_8859_2_close_env(struct SN_env* z); -extern int romanian_ISO_8859_2_stem(struct SN_env * z); +extern int romanian_ISO_8859_2_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_KOI8_R_russian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_KOI8_R_russian.h index de2179d2..e3b90be0 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_KOI8_R_russian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_KOI8_R_russian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * russian_KOI8_R_create_env(void); -extern void russian_KOI8_R_close_env(struct SN_env * z); +extern struct SN_env* russian_KOI8_R_create_env(void); +extern void russian_KOI8_R_close_env(struct SN_env* z); -extern int russian_KOI8_R_stem(struct SN_env * z); +extern int russian_KOI8_R_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_danish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_danish.h index ed744d45..bd54c88a 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_danish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_danish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * danish_UTF_8_create_env(void); -extern void danish_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* danish_UTF_8_create_env(void); +extern void danish_UTF_8_close_env(struct SN_env* z); -extern int danish_UTF_8_stem(struct SN_env * z); +extern int danish_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_dutch.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_dutch.h index a9964645..7990b174 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_dutch.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_dutch.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * dutch_UTF_8_create_env(void); -extern void dutch_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* dutch_UTF_8_create_env(void); +extern void dutch_UTF_8_close_env(struct SN_env* z); -extern int dutch_UTF_8_stem(struct SN_env * z); +extern int dutch_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_english.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_english.h index 619a8bc7..e6c5e507 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_english.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_english.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * english_UTF_8_create_env(void); -extern void english_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* english_UTF_8_create_env(void); +extern void english_UTF_8_close_env(struct SN_env* z); -extern int english_UTF_8_stem(struct SN_env * z); +extern int english_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_finnish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_finnish.h index d2f2fd96..9fb23a22 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_finnish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_finnish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * finnish_UTF_8_create_env(void); -extern void finnish_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* finnish_UTF_8_create_env(void); +extern void finnish_UTF_8_close_env(struct SN_env* z); -extern int finnish_UTF_8_stem(struct SN_env * z); +extern int finnish_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_french.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_french.h index 08e34184..2964fe29 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_french.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_french.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * french_UTF_8_create_env(void); -extern void french_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* french_UTF_8_create_env(void); +extern void french_UTF_8_close_env(struct SN_env* z); -extern int french_UTF_8_stem(struct SN_env * z); +extern int french_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_german.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_german.h index 5bd84d43..2dc04c2d 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_german.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_german.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * german_UTF_8_create_env(void); -extern void german_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* german_UTF_8_create_env(void); +extern void german_UTF_8_close_env(struct SN_env* z); -extern int german_UTF_8_stem(struct SN_env * z); +extern int german_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_hungarian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_hungarian.h index d81bd234..f66eb2e2 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_hungarian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_hungarian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * hungarian_UTF_8_create_env(void); -extern void hungarian_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* hungarian_UTF_8_create_env(void); +extern void hungarian_UTF_8_close_env(struct SN_env* z); -extern int hungarian_UTF_8_stem(struct SN_env * z); +extern int hungarian_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_italian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_italian.h index 3bee080d..62a1a425 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_italian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_italian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * italian_UTF_8_create_env(void); -extern void italian_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* italian_UTF_8_create_env(void); +extern void italian_UTF_8_close_env(struct SN_env* z); -extern int italian_UTF_8_stem(struct SN_env * z); +extern int italian_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_norwegian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_norwegian.h index c75444bc..475de029 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_norwegian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_norwegian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * norwegian_UTF_8_create_env(void); -extern void norwegian_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* norwegian_UTF_8_create_env(void); +extern void norwegian_UTF_8_close_env(struct SN_env* z); -extern int norwegian_UTF_8_stem(struct SN_env * z); +extern int norwegian_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_porter.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_porter.h index 82d469ac..af3acefb 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_porter.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_porter.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * porter_UTF_8_create_env(void); -extern void porter_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* porter_UTF_8_create_env(void); +extern void porter_UTF_8_close_env(struct SN_env* z); -extern int porter_UTF_8_stem(struct SN_env * z); +extern int porter_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_portuguese.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_portuguese.h index 9fe7f9aa..27f99936 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_portuguese.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_portuguese.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * portuguese_UTF_8_create_env(void); -extern void portuguese_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* portuguese_UTF_8_create_env(void); +extern void portuguese_UTF_8_close_env(struct SN_env* z); -extern int portuguese_UTF_8_stem(struct SN_env * z); +extern int portuguese_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_romanian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_romanian.h index d01e8132..e7a14166 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_romanian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_romanian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * romanian_UTF_8_create_env(void); -extern void romanian_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* romanian_UTF_8_create_env(void); +extern void romanian_UTF_8_close_env(struct SN_env* z); -extern int romanian_UTF_8_stem(struct SN_env * z); +extern int romanian_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_russian.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_russian.h index 4ef774dd..c7b02965 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_russian.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_russian.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * russian_UTF_8_create_env(void); -extern void russian_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* russian_UTF_8_create_env(void); +extern void russian_UTF_8_close_env(struct SN_env* z); -extern int russian_UTF_8_stem(struct SN_env * z); +extern int russian_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_spanish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_spanish.h index 10572ecc..c76297b6 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_spanish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_spanish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * spanish_UTF_8_create_env(void); -extern void spanish_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* spanish_UTF_8_create_env(void); +extern void spanish_UTF_8_close_env(struct SN_env* z); -extern int spanish_UTF_8_stem(struct SN_env * z); +extern int spanish_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_swedish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_swedish.h index 1444ebb4..6f2625e1 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_swedish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_swedish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * swedish_UTF_8_create_env(void); -extern void swedish_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* swedish_UTF_8_create_env(void); +extern void swedish_UTF_8_close_env(struct SN_env* z); -extern int swedish_UTF_8_stem(struct SN_env * z); +extern int swedish_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_turkish.h b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_turkish.h index 8173a174..05974aba 100644 --- a/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_turkish.h +++ b/src/contrib/snowball/libstemmer_c/src_c/stem_UTF_8_turkish.h @@ -5,10 +5,10 @@ extern "C" { #endif -extern struct SN_env * turkish_UTF_8_create_env(void); -extern void turkish_UTF_8_close_env(struct SN_env * z); +extern struct SN_env* turkish_UTF_8_create_env(void); +extern void turkish_UTF_8_close_env(struct SN_env* z); -extern int turkish_UTF_8_stem(struct SN_env * z); +extern int turkish_UTF_8_stem(struct SN_env* z); #ifdef __cplusplus } diff --git a/src/core/analysis/ASCIIFoldingFilter.cpp b/src/core/analysis/ASCIIFoldingFilter.cpp index dbd3353e..0d0ca4fe 100644 --- a/src/core/analysis/ASCIIFoldingFilter.cpp +++ b/src/core/analysis/ASCIIFoldingFilter.cpp @@ -9,1976 +9,1968 @@ #include "TermAttribute.h" #include "MiscUtils.h" -namespace Lucene -{ - ASCIIFoldingFilter::ASCIIFoldingFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - output = CharArray::newInstance(512); - outputPos = 0; - termAtt = addAttribute(); - } +namespace Lucene { - ASCIIFoldingFilter::~ASCIIFoldingFilter() - { - } +ASCIIFoldingFilter::ASCIIFoldingFilter(const TokenStreamPtr& input) : TokenFilter(input) { + output = CharArray::newInstance(512); + outputPos = 0; + termAtt = addAttribute(); +} + +ASCIIFoldingFilter::~ASCIIFoldingFilter() { +} - bool ASCIIFoldingFilter::incrementToken() - { - if (input->incrementToken()) - { - wchar_t* buffer = termAtt->termBufferArray(); - int32_t length = termAtt->termLength(); +bool ASCIIFoldingFilter::incrementToken() { + if (input->incrementToken()) { + wchar_t* buffer = termAtt->termBufferArray(); + int32_t length = termAtt->termLength(); - // If no characters actually require rewriting then we just return token as-is - for (int32_t i = 0; i < length; ++i) - { - wchar_t c = buffer[i]; - if (c >= 0x0080) - { - foldToASCII(buffer, length); - termAtt->setTermBuffer(output.get(), 0, outputPos); - break; - } + // If no characters actually require rewriting then we just return token as-is + for (int32_t i = 0; i < length; ++i) { + wchar_t c = buffer[i]; + if (c >= 0x0080) { + foldToASCII(buffer, length); + termAtt->setTermBuffer(output.get(), 0, outputPos); + break; } - return true; } - else - return false; + return true; + } else { + return false; } +} - void ASCIIFoldingFilter::foldToASCII(const wchar_t* input, int32_t length) - { - // Worst-case length required - int32_t maxSizeNeeded = 4 * length; - if (output.size() < maxSizeNeeded) - output.resize(MiscUtils::getNextSize(maxSizeNeeded)); +void ASCIIFoldingFilter::foldToASCII(const wchar_t* input, int32_t length) { + // Worst-case length required + int32_t maxSizeNeeded = 4 * length; + if (output.size() < maxSizeNeeded) { + output.resize(MiscUtils::getNextSize(maxSizeNeeded)); + } - outputPos = 0; - wchar_t* output = this->output.get(); + outputPos = 0; + wchar_t* output = this->output.get(); - for (int32_t pos = 0; pos < length; ++pos) - { - wchar_t c = input[pos]; + for (int32_t pos = 0; pos < length; ++pos) { + wchar_t c = input[pos]; - // Quick test: if it's not in range then just keep current character - if (c < 0x0080) + // Quick test: if it's not in range then just keep current character + if (c < 0x0080) { + output[outputPos++] = c; + } else { + switch (c) { + case 0x00C0: // [LATIN CAPITAL LETTER A WITH GRAVE] + case 0x00C1: // [LATIN CAPITAL LETTER A WITH ACUTE] + case 0x00C2: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX] + case 0x00C3: // [LATIN CAPITAL LETTER A WITH TILDE] + case 0x00C4: // [LATIN CAPITAL LETTER A WITH DIAERESIS] + case 0x00C5: // [LATIN CAPITAL LETTER A WITH RING ABOVE] + case 0x0100: // [LATIN CAPITAL LETTER A WITH MACRON] + case 0x0102: // [LATIN CAPITAL LETTER A WITH BREVE] + case 0x0104: // [LATIN CAPITAL LETTER A WITH OGONEK] + case 0x018F: // [LATIN CAPITAL LETTER SCHWA] + case 0x01CD: // [LATIN CAPITAL LETTER A WITH CARON] + case 0x01DE: // [LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON] + case 0x01E0: // [LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON] + case 0x01FA: // [LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE] + case 0x0200: // [LATIN CAPITAL LETTER A WITH DOUBLE GRAVE] + case 0x0202: // [LATIN CAPITAL LETTER A WITH INVERTED BREVE] + case 0x0226: // [LATIN CAPITAL LETTER A WITH DOT ABOVE] + case 0x023A: // [LATIN CAPITAL LETTER A WITH STROKE] + case 0x1D00: // [LATIN LETTER SMALL CAPITAL A] + case 0x1E00: // [LATIN CAPITAL LETTER A WITH RING BELOW] + case 0x1EA0: // [LATIN CAPITAL LETTER A WITH DOT BELOW] + case 0x1EA2: // [LATIN CAPITAL LETTER A WITH HOOK ABOVE] + case 0x1EA4: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE] + case 0x1EA6: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE] + case 0x1EA8: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE] + case 0x1EAA: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE] + case 0x1EAC: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW] + case 0x1EAE: // [LATIN CAPITAL LETTER A WITH BREVE AND ACUTE] + case 0x1EB0: // [LATIN CAPITAL LETTER A WITH BREVE AND GRAVE] + case 0x1EB2: // [LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE] + case 0x1EB4: // [LATIN CAPITAL LETTER A WITH BREVE AND TILDE] + case 0x1EB6: // [LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW] + case 0x24B6: // [CIRCLED LATIN CAPITAL LETTER A] + case 0xFF21: // [FULLWIDTH LATIN CAPITAL LETTER A] + output[outputPos++] = L'A'; + break; + case 0x00E0: // [LATIN SMALL LETTER A WITH GRAVE] + case 0x00E1: // [LATIN SMALL LETTER A WITH ACUTE] + case 0x00E2: // [LATIN SMALL LETTER A WITH CIRCUMFLEX] + case 0x00E3: // [LATIN SMALL LETTER A WITH TILDE] + case 0x00E4: // [LATIN SMALL LETTER A WITH DIAERESIS] + case 0x00E5: // [LATIN SMALL LETTER A WITH RING ABOVE] + case 0x0101: // [LATIN SMALL LETTER A WITH MACRON] + case 0x0103: // [LATIN SMALL LETTER A WITH BREVE] + case 0x0105: // [LATIN SMALL LETTER A WITH OGONEK] + case 0x01CE: // [LATIN SMALL LETTER A WITH CARON] + case 0x01DF: // [LATIN SMALL LETTER A WITH DIAERESIS AND MACRON] + case 0x01E1: // [LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON] + case 0x01FB: // [LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE] + case 0x0201: // [LATIN SMALL LETTER A WITH DOUBLE GRAVE] + case 0x0203: // [LATIN SMALL LETTER A WITH INVERTED BREVE] + case 0x0227: // [LATIN SMALL LETTER A WITH DOT ABOVE] + case 0x0250: // [LATIN SMALL LETTER TURNED A] + case 0x0259: // [LATIN SMALL LETTER SCHWA] + case 0x025A: // [LATIN SMALL LETTER SCHWA WITH HOOK] + case 0x1D8F: // [LATIN SMALL LETTER A WITH RETROFLEX HOOK] + case 0x1D95: // [LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK] + case 0x1E01: // [LATIN SMALL LETTER A WITH RING BELOW] + case 0x1E9A: // [LATIN SMALL LETTER A WITH RIGHT HALF RING] + case 0x1EA1: // [LATIN SMALL LETTER A WITH DOT BELOW] + case 0x1EA3: // [LATIN SMALL LETTER A WITH HOOK ABOVE] + case 0x1EA5: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE] + case 0x1EA7: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE] + case 0x1EA9: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE] + case 0x1EAB: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE] + case 0x1EAD: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW] + case 0x1EAF: // [LATIN SMALL LETTER A WITH BREVE AND ACUTE] + case 0x1EB1: // [LATIN SMALL LETTER A WITH BREVE AND GRAVE] + case 0x1EB3: // [LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE] + case 0x1EB5: // [LATIN SMALL LETTER A WITH BREVE AND TILDE] + case 0x1EB7: // [LATIN SMALL LETTER A WITH BREVE AND DOT BELOW] + case 0x2090: // [LATIN SUBSCRIPT SMALL LETTER A] + case 0x2094: // [LATIN SUBSCRIPT SMALL LETTER SCHWA] + case 0x24D0: // [CIRCLED LATIN SMALL LETTER A] + case 0x2C65: // [LATIN SMALL LETTER A WITH STROKE] + case 0x2C6F: // [LATIN CAPITAL LETTER TURNED A] + case 0xFF41: // [FULLWIDTH LATIN SMALL LETTER A] + output[outputPos++] = L'a'; + break; + case 0xA732: // [LATIN CAPITAL LETTER AA] + output[outputPos++] = L'A'; + output[outputPos++] = L'A'; + break; + case 0x00C6: // [LATIN CAPITAL LETTER AE] + case 0x01E2: // [LATIN CAPITAL LETTER AE WITH MACRON] + case 0x01FC: // [LATIN CAPITAL LETTER AE WITH ACUTE] + case 0x1D01: // [LATIN LETTER SMALL CAPITAL AE] + output[outputPos++] = L'A'; + output[outputPos++] = L'E'; + break; + case 0xA734: // [LATIN CAPITAL LETTER AO] + output[outputPos++] = L'A'; + output[outputPos++] = L'O'; + break; + case 0xA736: // [LATIN CAPITAL LETTER AU] + output[outputPos++] = L'A'; + output[outputPos++] = L'U'; + break; + case 0xA738: // [LATIN CAPITAL LETTER AV] + case 0xA73A: // [LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR] + output[outputPos++] = L'A'; + output[outputPos++] = L'V'; + break; + case 0xA73C: // [LATIN CAPITAL LETTER AY] + output[outputPos++] = L'A'; + output[outputPos++] = L'Y'; + break; + case 0x249C: // [PARENTHESIZED LATIN SMALL LETTER A] + output[outputPos++] = L'('; + output[outputPos++] = L'a'; + output[outputPos++] = L')'; + break; + case 0xA733: // [LATIN SMALL LETTER AA] + output[outputPos++] = L'a'; + output[outputPos++] = L'a'; + break; + case 0x00E6: // [LATIN SMALL LETTER AE] + case 0x01E3: // [LATIN SMALL LETTER AE WITH MACRON] + case 0x01FD: // [LATIN SMALL LETTER AE WITH ACUTE] + case 0x1D02: // [LATIN SMALL LETTER TURNED AE] + output[outputPos++] = L'a'; + output[outputPos++] = L'e'; + break; + case 0xA735: // [LATIN SMALL LETTER AO] + output[outputPos++] = L'a'; + output[outputPos++] = L'o'; + break; + case 0xA737: // [LATIN SMALL LETTER AU] + output[outputPos++] = L'a'; + output[outputPos++] = L'u'; + break; + case 0xA739: // [LATIN SMALL LETTER AV] + case 0xA73B: // [LATIN SMALL LETTER AV WITH HORIZONTAL BAR] + output[outputPos++] = L'a'; + output[outputPos++] = L'v'; + break; + case 0xA73D: // [LATIN SMALL LETTER AY] + output[outputPos++] = L'a'; + output[outputPos++] = L'y'; + break; + case 0x0181: // [LATIN CAPITAL LETTER B WITH HOOK] + case 0x0182: // [LATIN CAPITAL LETTER B WITH TOPBAR] + case 0x0243: // [LATIN CAPITAL LETTER B WITH STROKE] + case 0x0299: // [LATIN LETTER SMALL CAPITAL B] + case 0x1D03: // [LATIN LETTER SMALL CAPITAL BARRED B] + case 0x1E02: // [LATIN CAPITAL LETTER B WITH DOT ABOVE] + case 0x1E04: // [LATIN CAPITAL LETTER B WITH DOT BELOW] + case 0x1E06: // [LATIN CAPITAL LETTER B WITH LINE BELOW] + case 0x24B7: // [CIRCLED LATIN CAPITAL LETTER B] + case 0xFF22: // [FULLWIDTH LATIN CAPITAL LETTER B] + output[outputPos++] = L'B'; + break; + case 0x0180: // [LATIN SMALL LETTER B WITH STROKE] + case 0x0183: // [LATIN SMALL LETTER B WITH TOPBAR] + case 0x0253: // [LATIN SMALL LETTER B WITH HOOK] + case 0x1D6C: // [LATIN SMALL LETTER B WITH MIDDLE TILDE] + case 0x1D80: // [LATIN SMALL LETTER B WITH PALATAL HOOK] + case 0x1E03: // [LATIN SMALL LETTER B WITH DOT ABOVE] + case 0x1E05: // [LATIN SMALL LETTER B WITH DOT BELOW] + case 0x1E07: // [LATIN SMALL LETTER B WITH LINE BELOW] + case 0x24D1: // [CIRCLED LATIN SMALL LETTER B] + case 0xFF42: // [FULLWIDTH LATIN SMALL LETTER B] + output[outputPos++] = L'b'; + break; + case 0x249D: // [PARENTHESIZED LATIN SMALL LETTER B] + output[outputPos++] = L'('; + output[outputPos++] = L'b'; + output[outputPos++] = L')'; + break; + case 0x00C7: // [LATIN CAPITAL LETTER C WITH CEDILLA] + case 0x0106: // [LATIN CAPITAL LETTER C WITH ACUTE] + case 0x0108: // [LATIN CAPITAL LETTER C WITH CIRCUMFLEX] + case 0x010A: // [LATIN CAPITAL LETTER C WITH DOT ABOVE] + case 0x010C: // [LATIN CAPITAL LETTER C WITH CARON] + case 0x0187: // [LATIN CAPITAL LETTER C WITH HOOK] + case 0x023B: // [LATIN CAPITAL LETTER C WITH STROKE] + case 0x0297: // [LATIN LETTER STRETCHED C] + case 0x1D04: // [LATIN LETTER SMALL CAPITAL C] + case 0x1E08: // [LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE] + case 0x24B8: // [CIRCLED LATIN CAPITAL LETTER C] + case 0xFF23: // [FULLWIDTH LATIN CAPITAL LETTER C] + output[outputPos++] = L'C'; + break; + case 0x00E7: // [LATIN SMALL LETTER C WITH CEDILLA] + case 0x0107: // [LATIN SMALL LETTER C WITH ACUTE] + case 0x0109: // [LATIN SMALL LETTER C WITH CIRCUMFLEX] + case 0x010B: // [LATIN SMALL LETTER C WITH DOT ABOVE] + case 0x010D: // [LATIN SMALL LETTER C WITH CARON] + case 0x0188: // [LATIN SMALL LETTER C WITH HOOK] + case 0x023C: // [LATIN SMALL LETTER C WITH STROKE] + case 0x0255: // [LATIN SMALL LETTER C WITH CURL] + case 0x1E09: // [LATIN SMALL LETTER C WITH CEDILLA AND ACUTE] + case 0x2184: // [LATIN SMALL LETTER REVERSED C] + case 0x24D2: // [CIRCLED LATIN SMALL LETTER C] + case 0xA73E: // [LATIN CAPITAL LETTER REVERSED C WITH DOT] + case 0xA73F: // [LATIN SMALL LETTER REVERSED C WITH DOT] + case 0xFF43: // [FULLWIDTH LATIN SMALL LETTER C] + output[outputPos++] = L'c'; + break; + case 0x249E: // [PARENTHESIZED LATIN SMALL LETTER C] + output[outputPos++] = L'('; + output[outputPos++] = L'c'; + output[outputPos++] = L')'; + break; + case 0x00D0: // [LATIN CAPITAL LETTER ETH] + case 0x010E: // [LATIN CAPITAL LETTER D WITH CARON] + case 0x0110: // [LATIN CAPITAL LETTER D WITH STROKE] + case 0x0189: // [LATIN CAPITAL LETTER AFRICAN D] + case 0x018A: // [LATIN CAPITAL LETTER D WITH HOOK] + case 0x018B: // [LATIN CAPITAL LETTER D WITH TOPBAR] + case 0x1D05: // [LATIN LETTER SMALL CAPITAL D] + case 0x1D06: // [LATIN LETTER SMALL CAPITAL ETH] + case 0x1E0A: // [LATIN CAPITAL LETTER D WITH DOT ABOVE] + case 0x1E0C: // [LATIN CAPITAL LETTER D WITH DOT BELOW] + case 0x1E0E: // [LATIN CAPITAL LETTER D WITH LINE BELOW] + case 0x1E10: // [LATIN CAPITAL LETTER D WITH CEDILLA] + case 0x1E12: // [LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW] + case 0x24B9: // [CIRCLED LATIN CAPITAL LETTER D] + case 0xA779: // [LATIN CAPITAL LETTER INSULAR D] + case 0xFF24: // [FULLWIDTH LATIN CAPITAL LETTER D] + output[outputPos++] = L'D'; + break; + case 0x00F0: // [LATIN SMALL LETTER ETH] + case 0x010F: // [LATIN SMALL LETTER D WITH CARON] + case 0x0111: // [LATIN SMALL LETTER D WITH STROKE] + case 0x018C: // [LATIN SMALL LETTER D WITH TOPBAR] + case 0x0221: // [LATIN SMALL LETTER D WITH CURL] + case 0x0256: // [LATIN SMALL LETTER D WITH TAIL] + case 0x0257: // [LATIN SMALL LETTER D WITH HOOK] + case 0x1D6D: // [LATIN SMALL LETTER D WITH MIDDLE TILDE] + case 0x1D81: // [LATIN SMALL LETTER D WITH PALATAL HOOK] + case 0x1D91: // [LATIN SMALL LETTER D WITH HOOK AND TAIL] + case 0x1E0B: // [LATIN SMALL LETTER D WITH DOT ABOVE] + case 0x1E0D: // [LATIN SMALL LETTER D WITH DOT BELOW] + case 0x1E0F: // [LATIN SMALL LETTER D WITH LINE BELOW] + case 0x1E11: // [LATIN SMALL LETTER D WITH CEDILLA] + case 0x1E13: // [LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW] + case 0x24D3: // [CIRCLED LATIN SMALL LETTER D] + case 0xA77A: // [LATIN SMALL LETTER INSULAR D] + case 0xFF44: // [FULLWIDTH LATIN SMALL LETTER D] + output[outputPos++] = L'd'; + break; + case 0x01C4: // [LATIN CAPITAL LETTER DZ WITH CARON] + case 0x01F1: // [LATIN CAPITAL LETTER DZ] + output[outputPos++] = L'D'; + output[outputPos++] = L'Z'; + break; + case 0x01C5: // [LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON] + case 0x01F2: // [LATIN CAPITAL LETTER D WITH SMALL LETTER Z] + output[outputPos++] = L'D'; + output[outputPos++] = L'z'; + break; + case 0x249F: // [PARENTHESIZED LATIN SMALL LETTER D] + output[outputPos++] = L'('; + output[outputPos++] = L'd'; + output[outputPos++] = L')'; + break; + case 0x0238: // [LATIN SMALL LETTER DB DIGRAPH] + output[outputPos++] = L'd'; + output[outputPos++] = L'b'; + break; + case 0x01C6: // [LATIN SMALL LETTER DZ WITH CARON] + case 0x01F3: // [LATIN SMALL LETTER DZ] + case 0x02A3: // [LATIN SMALL LETTER DZ DIGRAPH] + case 0x02A5: // [LATIN SMALL LETTER DZ DIGRAPH WITH CURL] + output[outputPos++] = L'd'; + output[outputPos++] = L'z'; + break; + case 0x00C8: // [LATIN CAPITAL LETTER E WITH GRAVE] + case 0x00C9: // [LATIN CAPITAL LETTER E WITH ACUTE] + case 0x00CA: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX] + case 0x00CB: // [LATIN CAPITAL LETTER E WITH DIAERESIS] + case 0x0112: // [LATIN CAPITAL LETTER E WITH MACRON] + case 0x0114: // [LATIN CAPITAL LETTER E WITH BREVE] + case 0x0116: // [LATIN CAPITAL LETTER E WITH DOT ABOVE] + case 0x0118: // [LATIN CAPITAL LETTER E WITH OGONEK] + case 0x011A: // [LATIN CAPITAL LETTER E WITH CARON] + case 0x018E: // [LATIN CAPITAL LETTER REVERSED E] + case 0x0190: // [LATIN CAPITAL LETTER OPEN E] + case 0x0204: // [LATIN CAPITAL LETTER E WITH DOUBLE GRAVE] + case 0x0206: // [LATIN CAPITAL LETTER E WITH INVERTED BREVE] + case 0x0228: // [LATIN CAPITAL LETTER E WITH CEDILLA] + case 0x0246: // [LATIN CAPITAL LETTER E WITH STROKE] + case 0x1D07: // [LATIN LETTER SMALL CAPITAL E] + case 0x1E14: // [LATIN CAPITAL LETTER E WITH MACRON AND GRAVE] + case 0x1E16: // [LATIN CAPITAL LETTER E WITH MACRON AND ACUTE] + case 0x1E18: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW] + case 0x1E1A: // [LATIN CAPITAL LETTER E WITH TILDE BELOW] + case 0x1E1C: // [LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE] + case 0x1EB8: // [LATIN CAPITAL LETTER E WITH DOT BELOW] + case 0x1EBA: // [LATIN CAPITAL LETTER E WITH HOOK ABOVE] + case 0x1EBC: // [LATIN CAPITAL LETTER E WITH TILDE] + case 0x1EBE: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE] + case 0x1EC0: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE] + case 0x1EC2: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE] + case 0x1EC4: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE] + case 0x1EC6: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW] + case 0x24BA: // [CIRCLED LATIN CAPITAL LETTER E] + case 0x2C7B: // [LATIN LETTER SMALL CAPITAL TURNED E] + case 0xFF25: // [FULLWIDTH LATIN CAPITAL LETTER E] + output[outputPos++] = L'E'; + break; + case 0x00E8: // [LATIN SMALL LETTER E WITH GRAVE] + case 0x00E9: // [LATIN SMALL LETTER E WITH ACUTE] + case 0x00EA: // [LATIN SMALL LETTER E WITH CIRCUMFLEX] + case 0x00EB: // [LATIN SMALL LETTER E WITH DIAERESIS] + case 0x0113: // [LATIN SMALL LETTER E WITH MACRON] + case 0x0115: // [LATIN SMALL LETTER E WITH BREVE] + case 0x0117: // [LATIN SMALL LETTER E WITH DOT ABOVE] + case 0x0119: // [LATIN SMALL LETTER E WITH OGONEK] + case 0x011B: // [LATIN SMALL LETTER E WITH CARON] + case 0x01DD: // [LATIN SMALL LETTER TURNED E] + case 0x0205: // [LATIN SMALL LETTER E WITH DOUBLE GRAVE] + case 0x0207: // [LATIN SMALL LETTER E WITH INVERTED BREVE] + case 0x0229: // [LATIN SMALL LETTER E WITH CEDILLA] + case 0x0247: // [LATIN SMALL LETTER E WITH STROKE] + case 0x0258: // [LATIN SMALL LETTER REVERSED E] + case 0x025B: // [LATIN SMALL LETTER OPEN E] + case 0x025C: // [LATIN SMALL LETTER REVERSED OPEN E] + case 0x025D: // [LATIN SMALL LETTER REVERSED OPEN E WITH HOOK] + case 0x025E: // [LATIN SMALL LETTER CLOSED REVERSED OPEN E] + case 0x029A: // [LATIN SMALL LETTER CLOSED OPEN E] + case 0x1D08: // [LATIN SMALL LETTER TURNED OPEN E] + case 0x1D92: // [LATIN SMALL LETTER E WITH RETROFLEX HOOK] + case 0x1D93: // [LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK] + case 0x1D94: // [LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK] + case 0x1E15: // [LATIN SMALL LETTER E WITH MACRON AND GRAVE] + case 0x1E17: // [LATIN SMALL LETTER E WITH MACRON AND ACUTE] + case 0x1E19: // [LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW] + case 0x1E1B: // [LATIN SMALL LETTER E WITH TILDE BELOW] + case 0x1E1D: // [LATIN SMALL LETTER E WITH CEDILLA AND BREVE] + case 0x1EB9: // [LATIN SMALL LETTER E WITH DOT BELOW] + case 0x1EBB: // [LATIN SMALL LETTER E WITH HOOK ABOVE] + case 0x1EBD: // [LATIN SMALL LETTER E WITH TILDE] + case 0x1EBF: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE] + case 0x1EC1: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE] + case 0x1EC3: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE] + case 0x1EC5: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE] + case 0x1EC7: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW] + case 0x2091: // [LATIN SUBSCRIPT SMALL LETTER E] + case 0x24D4: // [CIRCLED LATIN SMALL LETTER E] + case 0x2C78: // [LATIN SMALL LETTER E WITH NOTCH] + case 0xFF45: // [FULLWIDTH LATIN SMALL LETTER E] + output[outputPos++] = L'e'; + break; + case 0x24A0: // [PARENTHESIZED LATIN SMALL LETTER E] + output[outputPos++] = L'('; + output[outputPos++] = L'e'; + output[outputPos++] = L')'; + break; + case 0x0191: // [LATIN CAPITAL LETTER F WITH HOOK] + case 0x1E1E: // [LATIN CAPITAL LETTER F WITH DOT ABOVE] + case 0x24BB: // [CIRCLED LATIN CAPITAL LETTER F] + case 0xA730: // [LATIN LETTER SMALL CAPITAL F] + case 0xA77B: // [LATIN CAPITAL LETTER INSULAR F] + case 0xA7FB: // [LATIN EPIGRAPHIC LETTER REVERSED F] + case 0xFF26: // [FULLWIDTH LATIN CAPITAL LETTER F] + output[outputPos++] = L'F'; + break; + case 0x0192: // [LATIN SMALL LETTER F WITH HOOK] + case 0x1D6E: // [LATIN SMALL LETTER F WITH MIDDLE TILDE] + case 0x1D82: // [LATIN SMALL LETTER F WITH PALATAL HOOK] + case 0x1E1F: // [LATIN SMALL LETTER F WITH DOT ABOVE] + case 0x1E9B: // [LATIN SMALL LETTER LONG S WITH DOT ABOVE] + case 0x24D5: // [CIRCLED LATIN SMALL LETTER F] + case 0xA77C: // [LATIN SMALL LETTER INSULAR F] + case 0xFF46: // [FULLWIDTH LATIN SMALL LETTER F] + output[outputPos++] = L'f'; + break; + case 0x24A1: // [PARENTHESIZED LATIN SMALL LETTER F] + output[outputPos++] = L'('; + output[outputPos++] = L'f'; + output[outputPos++] = L')'; + break; + case 0xFB00: // [LATIN SMALL LIGATURE FF] + output[outputPos++] = L'f'; + output[outputPos++] = L'f'; + break; + case 0xFB03: // [LATIN SMALL LIGATURE FFI] + output[outputPos++] = L'f'; + output[outputPos++] = L'f'; + output[outputPos++] = L'i'; + break; + case 0xFB04: // [LATIN SMALL LIGATURE FFL] + output[outputPos++] = L'f'; + output[outputPos++] = L'f'; + output[outputPos++] = L'l'; + break; + case 0xFB01: // [LATIN SMALL LIGATURE FI] + output[outputPos++] = L'f'; + output[outputPos++] = L'i'; + break; + case 0xFB02: // [LATIN SMALL LIGATURE FL] + output[outputPos++] = L'f'; + output[outputPos++] = L'l'; + break; + case 0x011C: // [LATIN CAPITAL LETTER G WITH CIRCUMFLEX] + case 0x011E: // [LATIN CAPITAL LETTER G WITH BREVE] + case 0x0120: // [LATIN CAPITAL LETTER G WITH DOT ABOVE] + case 0x0122: // [LATIN CAPITAL LETTER G WITH CEDILLA] + case 0x0193: // [LATIN CAPITAL LETTER G WITH HOOK] + case 0x01E4: // [LATIN CAPITAL LETTER G WITH STROKE] + case 0x01E5: // [LATIN SMALL LETTER G WITH STROKE] + case 0x01E6: // [LATIN CAPITAL LETTER G WITH CARON] + case 0x01E7: // [LATIN SMALL LETTER G WITH CARON] + case 0x01F4: // [LATIN CAPITAL LETTER G WITH ACUTE] + case 0x0262: // [LATIN LETTER SMALL CAPITAL G] + case 0x029B: // [LATIN LETTER SMALL CAPITAL G WITH HOOK] + case 0x1E20: // [LATIN CAPITAL LETTER G WITH MACRON] + case 0x24BC: // [CIRCLED LATIN CAPITAL LETTER G] + case 0xA77D: // [LATIN CAPITAL LETTER INSULAR G] + case 0xA77E: // [LATIN CAPITAL LETTER TURNED INSULAR G] + case 0xFF27: // [FULLWIDTH LATIN CAPITAL LETTER G] + output[outputPos++] = L'G'; + break; + case 0x011D: // [LATIN SMALL LETTER G WITH CIRCUMFLEX] + case 0x011F: // [LATIN SMALL LETTER G WITH BREVE] + case 0x0121: // [LATIN SMALL LETTER G WITH DOT ABOVE] + case 0x0123: // [LATIN SMALL LETTER G WITH CEDILLA] + case 0x01F5: // [LATIN SMALL LETTER G WITH ACUTE] + case 0x0260: // [LATIN SMALL LETTER G WITH HOOK] + case 0x0261: // [LATIN SMALL LETTER SCRIPT G] + case 0x1D77: // [LATIN SMALL LETTER TURNED G] + case 0x1D79: // [LATIN SMALL LETTER INSULAR G] + case 0x1D83: // [LATIN SMALL LETTER G WITH PALATAL HOOK] + case 0x1E21: // [LATIN SMALL LETTER G WITH MACRON] + case 0x24D6: // [CIRCLED LATIN SMALL LETTER G] + case 0xA77F: // [LATIN SMALL LETTER TURNED INSULAR G] + case 0xFF47: // [FULLWIDTH LATIN SMALL LETTER G] + output[outputPos++] = L'g'; + break; + case 0x24A2: // [PARENTHESIZED LATIN SMALL LETTER G] + output[outputPos++] = L'('; + output[outputPos++] = L'g'; + output[outputPos++] = L')'; + break; + case 0x0124: // [LATIN CAPITAL LETTER H WITH CIRCUMFLEX] + case 0x0126: // [LATIN CAPITAL LETTER H WITH STROKE] + case 0x021E: // [LATIN CAPITAL LETTER H WITH CARON] + case 0x029C: // [LATIN LETTER SMALL CAPITAL H] + case 0x1E22: // [LATIN CAPITAL LETTER H WITH DOT ABOVE] + case 0x1E24: // [LATIN CAPITAL LETTER H WITH DOT BELOW] + case 0x1E26: // [LATIN CAPITAL LETTER H WITH DIAERESIS] + case 0x1E28: // [LATIN CAPITAL LETTER H WITH CEDILLA] + case 0x1E2A: // [LATIN CAPITAL LETTER H WITH BREVE BELOW] + case 0x24BD: // [CIRCLED LATIN CAPITAL LETTER H] + case 0x2C67: // [LATIN CAPITAL LETTER H WITH DESCENDER] + case 0x2C75: // [LATIN CAPITAL LETTER HALF H] + case 0xFF28: // [FULLWIDTH LATIN CAPITAL LETTER H] + output[outputPos++] = L'H'; + break; + case 0x0125: // [LATIN SMALL LETTER H WITH CIRCUMFLEX] + case 0x0127: // [LATIN SMALL LETTER H WITH STROKE] + case 0x021F: // [LATIN SMALL LETTER H WITH CARON] + case 0x0265: // [LATIN SMALL LETTER TURNED H] + case 0x0266: // [LATIN SMALL LETTER H WITH HOOK] + case 0x02AE: // [LATIN SMALL LETTER TURNED H WITH FISHHOOK] + case 0x02AF: // [LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL] + case 0x1E23: // [LATIN SMALL LETTER H WITH DOT ABOVE] + case 0x1E25: // [LATIN SMALL LETTER H WITH DOT BELOW] + case 0x1E27: // [LATIN SMALL LETTER H WITH DIAERESIS] + case 0x1E29: // [LATIN SMALL LETTER H WITH CEDILLA] + case 0x1E2B: // [LATIN SMALL LETTER H WITH BREVE BELOW] + case 0x1E96: // [LATIN SMALL LETTER H WITH LINE BELOW] + case 0x24D7: // [CIRCLED LATIN SMALL LETTER H] + case 0x2C68: // [LATIN SMALL LETTER H WITH DESCENDER] + case 0x2C76: // [LATIN SMALL LETTER HALF H] + case 0xFF48: // [FULLWIDTH LATIN SMALL LETTER H] + output[outputPos++] = L'h'; + break; + case 0x01F6: // [LATIN CAPITAL LETTER HWAIR] + output[outputPos++] = L'H'; + output[outputPos++] = L'V'; + break; + case 0x24A3: // [PARENTHESIZED LATIN SMALL LETTER H] + output[outputPos++] = L'('; + output[outputPos++] = L'h'; + output[outputPos++] = L')'; + break; + case 0x0195: // [LATIN SMALL LETTER HV] + output[outputPos++] = L'h'; + output[outputPos++] = L'v'; + break; + case 0x00CC: // [LATIN CAPITAL LETTER I WITH GRAVE] + case 0x00CD: // [LATIN CAPITAL LETTER I WITH ACUTE] + case 0x00CE: // [LATIN CAPITAL LETTER I WITH CIRCUMFLEX] + case 0x00CF: // [LATIN CAPITAL LETTER I WITH DIAERESIS] + case 0x0128: // [LATIN CAPITAL LETTER I WITH TILDE] + case 0x012A: // [LATIN CAPITAL LETTER I WITH MACRON] + case 0x012C: // [LATIN CAPITAL LETTER I WITH BREVE] + case 0x012E: // [LATIN CAPITAL LETTER I WITH OGONEK] + case 0x0130: // [LATIN CAPITAL LETTER I WITH DOT ABOVE] + case 0x0196: // [LATIN CAPITAL LETTER IOTA] + case 0x0197: // [LATIN CAPITAL LETTER I WITH STROKE] + case 0x01CF: // [LATIN CAPITAL LETTER I WITH CARON] + case 0x0208: // [LATIN CAPITAL LETTER I WITH DOUBLE GRAVE] + case 0x020A: // [LATIN CAPITAL LETTER I WITH INVERTED BREVE] + case 0x026A: // [LATIN LETTER SMALL CAPITAL I] + case 0x1D7B: // [LATIN SMALL CAPITAL LETTER I WITH STROKE] + case 0x1E2C: // [LATIN CAPITAL LETTER I WITH TILDE BELOW] + case 0x1E2E: // [LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE] + case 0x1EC8: // [LATIN CAPITAL LETTER I WITH HOOK ABOVE] + case 0x1ECA: // [LATIN CAPITAL LETTER I WITH DOT BELOW] + case 0x24BE: // [CIRCLED LATIN CAPITAL LETTER I] + case 0xA7FE: // [LATIN EPIGRAPHIC LETTER I LONGA] + case 0xFF29: // [FULLWIDTH LATIN CAPITAL LETTER I] + output[outputPos++] = L'I'; + break; + case 0x00EC: // [LATIN SMALL LETTER I WITH GRAVE] + case 0x00ED: // [LATIN SMALL LETTER I WITH ACUTE] + case 0x00EE: // [LATIN SMALL LETTER I WITH CIRCUMFLEX] + case 0x00EF: // [LATIN SMALL LETTER I WITH DIAERESIS] + case 0x0129: // [LATIN SMALL LETTER I WITH TILDE] + case 0x012B: // [LATIN SMALL LETTER I WITH MACRON] + case 0x012D: // [LATIN SMALL LETTER I WITH BREVE] + case 0x012F: // [LATIN SMALL LETTER I WITH OGONEK] + case 0x0131: // [LATIN SMALL LETTER DOTLESS I] + case 0x01D0: // [LATIN SMALL LETTER I WITH CARON] + case 0x0209: // [LATIN SMALL LETTER I WITH DOUBLE GRAVE] + case 0x020B: // [LATIN SMALL LETTER I WITH INVERTED BREVE] + case 0x0268: // [LATIN SMALL LETTER I WITH STROKE] + case 0x1D09: // [LATIN SMALL LETTER TURNED I] + case 0x1D62: // [LATIN SUBSCRIPT SMALL LETTER I] + case 0x1D7C: // [LATIN SMALL LETTER IOTA WITH STROKE] + case 0x1D96: // [LATIN SMALL LETTER I WITH RETROFLEX HOOK] + case 0x1E2D: // [LATIN SMALL LETTER I WITH TILDE BELOW] + case 0x1E2F: // [LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE] + case 0x1EC9: // [LATIN SMALL LETTER I WITH HOOK ABOVE] + case 0x1ECB: // [LATIN SMALL LETTER I WITH DOT BELOW] + case 0x2071: // [SUPERSCRIPT LATIN SMALL LETTER I] + case 0x24D8: // [CIRCLED LATIN SMALL LETTER I] + case 0xFF49: // [FULLWIDTH LATIN SMALL LETTER I] + output[outputPos++] = L'i'; + break; + case 0x0132: // [LATIN CAPITAL LIGATURE IJ] + output[outputPos++] = L'I'; + output[outputPos++] = L'J'; + break; + case 0x24A4: // [PARENTHESIZED LATIN SMALL LETTER I] + output[outputPos++] = L'('; + output[outputPos++] = L'i'; + output[outputPos++] = L')'; + break; + case 0x0133: // [LATIN SMALL LIGATURE IJ] + output[outputPos++] = L'i'; + output[outputPos++] = L'j'; + break; + case 0x0134: // [LATIN CAPITAL LETTER J WITH CIRCUMFLEX] + case 0x0248: // [LATIN CAPITAL LETTER J WITH STROKE] + case 0x1D0A: // [LATIN LETTER SMALL CAPITAL J] + case 0x24BF: // [CIRCLED LATIN CAPITAL LETTER J] + case 0xFF2A: // [FULLWIDTH LATIN CAPITAL LETTER J] + output[outputPos++] = L'J'; + break; + case 0x0135: // [LATIN SMALL LETTER J WITH CIRCUMFLEX] + case 0x01F0: // [LATIN SMALL LETTER J WITH CARON] + case 0x0237: // [LATIN SMALL LETTER DOTLESS J] + case 0x0249: // [LATIN SMALL LETTER J WITH STROKE] + case 0x025F: // [LATIN SMALL LETTER DOTLESS J WITH STROKE] + case 0x0284: // [LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK] + case 0x029D: // [LATIN SMALL LETTER J WITH CROSSED-TAIL] + case 0x24D9: // [CIRCLED LATIN SMALL LETTER J] + case 0x2C7C: // [LATIN SUBSCRIPT SMALL LETTER J] + case 0xFF4A: // [FULLWIDTH LATIN SMALL LETTER J] + output[outputPos++] = L'j'; + break; + case 0x24A5: // [PARENTHESIZED LATIN SMALL LETTER J] + output[outputPos++] = L'('; + output[outputPos++] = L'j'; + output[outputPos++] = L')'; + break; + case 0x0136: // [LATIN CAPITAL LETTER K WITH CEDILLA] + case 0x0198: // [LATIN CAPITAL LETTER K WITH HOOK] + case 0x01E8: // [LATIN CAPITAL LETTER K WITH CARON] + case 0x1D0B: // [LATIN LETTER SMALL CAPITAL K] + case 0x1E30: // [LATIN CAPITAL LETTER K WITH ACUTE] + case 0x1E32: // [LATIN CAPITAL LETTER K WITH DOT BELOW] + case 0x1E34: // [LATIN CAPITAL LETTER K WITH LINE BELOW] + case 0x24C0: // [CIRCLED LATIN CAPITAL LETTER K] + case 0x2C69: // [LATIN CAPITAL LETTER K WITH DESCENDER] + case 0xA740: // [LATIN CAPITAL LETTER K WITH STROKE] + case 0xA742: // [LATIN CAPITAL LETTER K WITH DIAGONAL STROKE] + case 0xA744: // [LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE] + case 0xFF2B: // [FULLWIDTH LATIN CAPITAL LETTER K] + output[outputPos++] = L'K'; + break; + case 0x0137: // [LATIN SMALL LETTER K WITH CEDILLA] + case 0x0199: // [LATIN SMALL LETTER K WITH HOOK] + case 0x01E9: // [LATIN SMALL LETTER K WITH CARON] + case 0x029E: // [LATIN SMALL LETTER TURNED K] + case 0x1D84: // [LATIN SMALL LETTER K WITH PALATAL HOOK] + case 0x1E31: // [LATIN SMALL LETTER K WITH ACUTE] + case 0x1E33: // [LATIN SMALL LETTER K WITH DOT BELOW] + case 0x1E35: // [LATIN SMALL LETTER K WITH LINE BELOW] + case 0x24DA: // [CIRCLED LATIN SMALL LETTER K] + case 0x2C6A: // [LATIN SMALL LETTER K WITH DESCENDER] + case 0xA741: // [LATIN SMALL LETTER K WITH STROKE] + case 0xA743: // [LATIN SMALL LETTER K WITH DIAGONAL STROKE] + case 0xA745: // [LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE] + case 0xFF4B: // [FULLWIDTH LATIN SMALL LETTER K] + output[outputPos++] = L'k'; + break; + case 0x24A6: // [PARENTHESIZED LATIN SMALL LETTER K] + output[outputPos++] = L'('; + output[outputPos++] = L'k'; + output[outputPos++] = L')'; + break; + case 0x0139: // [LATIN CAPITAL LETTER L WITH ACUTE] + case 0x013B: // [LATIN CAPITAL LETTER L WITH CEDILLA] + case 0x013D: // [LATIN CAPITAL LETTER L WITH CARON] + case 0x013F: // [LATIN CAPITAL LETTER L WITH MIDDLE DOT] + case 0x0141: // [LATIN CAPITAL LETTER L WITH STROKE] + case 0x023D: // [LATIN CAPITAL LETTER L WITH BAR] + case 0x029F: // [LATIN LETTER SMALL CAPITAL L] + case 0x1D0C: // [LATIN LETTER SMALL CAPITAL L WITH STROKE] + case 0x1E36: // [LATIN CAPITAL LETTER L WITH DOT BELOW] + case 0x1E38: // [LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON] + case 0x1E3A: // [LATIN CAPITAL LETTER L WITH LINE BELOW] + case 0x1E3C: // [LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW] + case 0x24C1: // [CIRCLED LATIN CAPITAL LETTER L] + case 0x2C60: // [LATIN CAPITAL LETTER L WITH DOUBLE BAR] + case 0x2C62: // [LATIN CAPITAL LETTER L WITH MIDDLE TILDE] + case 0xA746: // [LATIN CAPITAL LETTER BROKEN L] + case 0xA748: // [LATIN CAPITAL LETTER L WITH HIGH STROKE] + case 0xA780: // [LATIN CAPITAL LETTER TURNED L] + case 0xFF2C: // [FULLWIDTH LATIN CAPITAL LETTER L] + output[outputPos++] = L'L'; + break; + case 0x013A: // [LATIN SMALL LETTER L WITH ACUTE] + case 0x013C: // [LATIN SMALL LETTER L WITH CEDILLA] + case 0x013E: // [LATIN SMALL LETTER L WITH CARON] + case 0x0140: // [LATIN SMALL LETTER L WITH MIDDLE DOT] + case 0x0142: // [LATIN SMALL LETTER L WITH STROKE] + case 0x019A: // [LATIN SMALL LETTER L WITH BAR] + case 0x0234: // [LATIN SMALL LETTER L WITH CURL] + case 0x026B: // [LATIN SMALL LETTER L WITH MIDDLE TILDE] + case 0x026C: // [LATIN SMALL LETTER L WITH BELT] + case 0x026D: // [LATIN SMALL LETTER L WITH RETROFLEX HOOK] + case 0x1D85: // [LATIN SMALL LETTER L WITH PALATAL HOOK] + case 0x1E37: // [LATIN SMALL LETTER L WITH DOT BELOW] + case 0x1E39: // [LATIN SMALL LETTER L WITH DOT BELOW AND MACRON] + case 0x1E3B: // [LATIN SMALL LETTER L WITH LINE BELOW] + case 0x1E3D: // [LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW] + case 0x24DB: // [CIRCLED LATIN SMALL LETTER L] + case 0x2C61: // [LATIN SMALL LETTER L WITH DOUBLE BAR] + case 0xA747: // [LATIN SMALL LETTER BROKEN L] + case 0xA749: // [LATIN SMALL LETTER L WITH HIGH STROKE] + case 0xA781: // [LATIN SMALL LETTER TURNED L] + case 0xFF4C: // [FULLWIDTH LATIN SMALL LETTER L] + output[outputPos++] = L'l'; + break; + case 0x01C7: // [LATIN CAPITAL LETTER LJ] + output[outputPos++] = L'L'; + output[outputPos++] = L'J'; + break; + case 0x1EFA: // [LATIN CAPITAL LETTER MIDDLE-WELSH LL] + output[outputPos++] = L'L'; + output[outputPos++] = L'L'; + break; + case 0x01C8: // [LATIN CAPITAL LETTER L WITH SMALL LETTER J] + output[outputPos++] = L'L'; + output[outputPos++] = L'j'; + break; + case 0x24A7: // [PARENTHESIZED LATIN SMALL LETTER L] + output[outputPos++] = L'('; + output[outputPos++] = L'l'; + output[outputPos++] = L')'; + break; + case 0x01C9: // [LATIN SMALL LETTER LJ] + output[outputPos++] = L'l'; + output[outputPos++] = L'j'; + break; + case 0x1EFB: // [LATIN SMALL LETTER MIDDLE-WELSH LL] + output[outputPos++] = L'l'; + output[outputPos++] = L'l'; + break; + case 0x02AA: // [LATIN SMALL LETTER LS DIGRAPH] + output[outputPos++] = L'l'; + output[outputPos++] = L's'; + break; + case 0x02AB: // [LATIN SMALL LETTER LZ DIGRAPH] + output[outputPos++] = L'l'; + output[outputPos++] = L'z'; + break; + case 0x019C: // [LATIN CAPITAL LETTER TURNED M] + case 0x1D0D: // [LATIN LETTER SMALL CAPITAL M] + case 0x1E3E: // [LATIN CAPITAL LETTER M WITH ACUTE] + case 0x1E40: // [LATIN CAPITAL LETTER M WITH DOT ABOVE] + case 0x1E42: // [LATIN CAPITAL LETTER M WITH DOT BELOW] + case 0x24C2: // [CIRCLED LATIN CAPITAL LETTER M] + case 0x2C6E: // [LATIN CAPITAL LETTER M WITH HOOK] + case 0xA7FD: // [LATIN EPIGRAPHIC LETTER INVERTED M] + case 0xA7FF: // [LATIN EPIGRAPHIC LETTER ARCHAIC M] + case 0xFF2D: // [FULLWIDTH LATIN CAPITAL LETTER M] + output[outputPos++] = L'M'; + break; + case 0x026F: // [LATIN SMALL LETTER TURNED M] + case 0x0270: // [LATIN SMALL LETTER TURNED M WITH LONG LEG] + case 0x0271: // [LATIN SMALL LETTER M WITH HOOK] + case 0x1D6F: // [LATIN SMALL LETTER M WITH MIDDLE TILDE] + case 0x1D86: // [LATIN SMALL LETTER M WITH PALATAL HOOK] + case 0x1E3F: // [LATIN SMALL LETTER M WITH ACUTE] + case 0x1E41: // [LATIN SMALL LETTER M WITH DOT ABOVE] + case 0x1E43: // [LATIN SMALL LETTER M WITH DOT BELOW] + case 0x24DC: // [CIRCLED LATIN SMALL LETTER M] + case 0xFF4D: // [FULLWIDTH LATIN SMALL LETTER M] + output[outputPos++] = L'm'; + break; + case 0x24A8: // [PARENTHESIZED LATIN SMALL LETTER M] + output[outputPos++] = L'('; + output[outputPos++] = L'm'; + output[outputPos++] = L')'; + break; + case 0x00D1: // [LATIN CAPITAL LETTER N WITH TILDE] + case 0x0143: // [LATIN CAPITAL LETTER N WITH ACUTE] + case 0x0145: // [LATIN CAPITAL LETTER N WITH CEDILLA] + case 0x0147: // [LATIN CAPITAL LETTER N WITH CARON] + case 0x014A: // [LATIN CAPITAL LETTER ENG] + case 0x019D: // [LATIN CAPITAL LETTER N WITH LEFT HOOK] + case 0x01F8: // [LATIN CAPITAL LETTER N WITH GRAVE] + case 0x0220: // [LATIN CAPITAL LETTER N WITH LONG RIGHT LEG] + case 0x0274: // [LATIN LETTER SMALL CAPITAL N] + case 0x1D0E: // [LATIN LETTER SMALL CAPITAL REVERSED N] + case 0x1E44: // [LATIN CAPITAL LETTER N WITH DOT ABOVE] + case 0x1E46: // [LATIN CAPITAL LETTER N WITH DOT BELOW] + case 0x1E48: // [LATIN CAPITAL LETTER N WITH LINE BELOW] + case 0x1E4A: // [LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW] + case 0x24C3: // [CIRCLED LATIN CAPITAL LETTER N] + case 0xFF2E: // [FULLWIDTH LATIN CAPITAL LETTER N] + output[outputPos++] = L'N'; + break; + case 0x00F1: // [LATIN SMALL LETTER N WITH TILDE] + case 0x0144: // [LATIN SMALL LETTER N WITH ACUTE] + case 0x0146: // [LATIN SMALL LETTER N WITH CEDILLA] + case 0x0148: // [LATIN SMALL LETTER N WITH CARON] + case 0x0149: // [LATIN SMALL LETTER N PRECEDED BY APOSTROPHE] + case 0x014B: // [LATIN SMALL LETTER ENG] + case 0x019E: // [LATIN SMALL LETTER N WITH LONG RIGHT LEG] + case 0x01F9: // [LATIN SMALL LETTER N WITH GRAVE] + case 0x0235: // [LATIN SMALL LETTER N WITH CURL] + case 0x0272: // [LATIN SMALL LETTER N WITH LEFT HOOK] + case 0x0273: // [LATIN SMALL LETTER N WITH RETROFLEX HOOK] + case 0x1D70: // [LATIN SMALL LETTER N WITH MIDDLE TILDE] + case 0x1D87: // [LATIN SMALL LETTER N WITH PALATAL HOOK] + case 0x1E45: // [LATIN SMALL LETTER N WITH DOT ABOVE] + case 0x1E47: // [LATIN SMALL LETTER N WITH DOT BELOW] + case 0x1E49: // [LATIN SMALL LETTER N WITH LINE BELOW] + case 0x1E4B: // [LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW] + case 0x207F: // [SUPERSCRIPT LATIN SMALL LETTER N] + case 0x24DD: // [CIRCLED LATIN SMALL LETTER N] + case 0xFF4E: // [FULLWIDTH LATIN SMALL LETTER N] + output[outputPos++] = L'n'; + break; + case 0x01CA: // [LATIN CAPITAL LETTER NJ] + output[outputPos++] = L'N'; + output[outputPos++] = L'J'; + break; + case 0x01CB: // [LATIN CAPITAL LETTER N WITH SMALL LETTER J] + output[outputPos++] = L'N'; + output[outputPos++] = L'j'; + break; + case 0x24A9: // [PARENTHESIZED LATIN SMALL LETTER N] + output[outputPos++] = L'('; + output[outputPos++] = L'n'; + output[outputPos++] = L')'; + break; + case 0x01CC: // [LATIN SMALL LETTER NJ] + output[outputPos++] = L'n'; + output[outputPos++] = L'j'; + break; + case 0x00D2: // [LATIN CAPITAL LETTER O WITH GRAVE] + case 0x00D3: // [LATIN CAPITAL LETTER O WITH ACUTE] + case 0x00D4: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX] + case 0x00D5: // [LATIN CAPITAL LETTER O WITH TILDE] + case 0x00D6: // [LATIN CAPITAL LETTER O WITH DIAERESIS] + case 0x00D8: // [LATIN CAPITAL LETTER O WITH STROKE] + case 0x014C: // [LATIN CAPITAL LETTER O WITH MACRON] + case 0x014E: // [LATIN CAPITAL LETTER O WITH BREVE] + case 0x0150: // [LATIN CAPITAL LETTER O WITH DOUBLE ACUTE] + case 0x0186: // [LATIN CAPITAL LETTER OPEN O] + case 0x019F: // [LATIN CAPITAL LETTER O WITH MIDDLE TILDE] + case 0x01A0: // [LATIN CAPITAL LETTER O WITH HORN] + case 0x01D1: // [LATIN CAPITAL LETTER O WITH CARON] + case 0x01EA: // [LATIN CAPITAL LETTER O WITH OGONEK] + case 0x01EC: // [LATIN CAPITAL LETTER O WITH OGONEK AND MACRON] + case 0x01FE: // [LATIN CAPITAL LETTER O WITH STROKE AND ACUTE] + case 0x020C: // [LATIN CAPITAL LETTER O WITH DOUBLE GRAVE] + case 0x020E: // [LATIN CAPITAL LETTER O WITH INVERTED BREVE] + case 0x022A: // [LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON] + case 0x022C: // [LATIN CAPITAL LETTER O WITH TILDE AND MACRON] + case 0x022E: // [LATIN CAPITAL LETTER O WITH DOT ABOVE] + case 0x0230: // [LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON] + case 0x1D0F: // [LATIN LETTER SMALL CAPITAL O] + case 0x1D10: // [LATIN LETTER SMALL CAPITAL OPEN O] + case 0x1E4C: // [LATIN CAPITAL LETTER O WITH TILDE AND ACUTE] + case 0x1E4E: // [LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS] + case 0x1E50: // [LATIN CAPITAL LETTER O WITH MACRON AND GRAVE] + case 0x1E52: // [LATIN CAPITAL LETTER O WITH MACRON AND ACUTE] + case 0x1ECC: // [LATIN CAPITAL LETTER O WITH DOT BELOW] + case 0x1ECE: // [LATIN CAPITAL LETTER O WITH HOOK ABOVE] + case 0x1ED0: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE] + case 0x1ED2: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE] + case 0x1ED4: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE] + case 0x1ED6: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE] + case 0x1ED8: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW] + case 0x1EDA: // [LATIN CAPITAL LETTER O WITH HORN AND ACUTE] + case 0x1EDC: // [LATIN CAPITAL LETTER O WITH HORN AND GRAVE] + case 0x1EDE: // [LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE] + case 0x1EE0: // [LATIN CAPITAL LETTER O WITH HORN AND TILDE] + case 0x1EE2: // [LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW] + case 0x24C4: // [CIRCLED LATIN CAPITAL LETTER O] + case 0xA74A: // [LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY] + case 0xA74C: // [LATIN CAPITAL LETTER O WITH LOOP] + case 0xFF2F: // [FULLWIDTH LATIN CAPITAL LETTER O] + output[outputPos++] = L'O'; + break; + case 0x00F2: // [LATIN SMALL LETTER O WITH GRAVE] + case 0x00F3: // [LATIN SMALL LETTER O WITH ACUTE] + case 0x00F4: // [LATIN SMALL LETTER O WITH CIRCUMFLEX] + case 0x00F5: // [LATIN SMALL LETTER O WITH TILDE] + case 0x00F6: // [LATIN SMALL LETTER O WITH DIAERESIS] + case 0x00F8: // [LATIN SMALL LETTER O WITH STROKE] + case 0x014D: // [LATIN SMALL LETTER O WITH MACRON] + case 0x014F: // [LATIN SMALL LETTER O WITH BREVE] + case 0x0151: // [LATIN SMALL LETTER O WITH DOUBLE ACUTE] + case 0x01A1: // [LATIN SMALL LETTER O WITH HORN] + case 0x01D2: // [LATIN SMALL LETTER O WITH CARON] + case 0x01EB: // [LATIN SMALL LETTER O WITH OGONEK] + case 0x01ED: // [LATIN SMALL LETTER O WITH OGONEK AND MACRON] + case 0x01FF: // [LATIN SMALL LETTER O WITH STROKE AND ACUTE] + case 0x020D: // [LATIN SMALL LETTER O WITH DOUBLE GRAVE] + case 0x020F: // [LATIN SMALL LETTER O WITH INVERTED BREVE] + case 0x022B: // [LATIN SMALL LETTER O WITH DIAERESIS AND MACRON] + case 0x022D: // [LATIN SMALL LETTER O WITH TILDE AND MACRON] + case 0x022F: // [LATIN SMALL LETTER O WITH DOT ABOVE] + case 0x0231: // [LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON] + case 0x0254: // [LATIN SMALL LETTER OPEN O] + case 0x0275: // [LATIN SMALL LETTER BARRED O] + case 0x1D16: // [LATIN SMALL LETTER TOP HALF O] + case 0x1D17: // [LATIN SMALL LETTER BOTTOM HALF O] + case 0x1D97: // [LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK] + case 0x1E4D: // [LATIN SMALL LETTER O WITH TILDE AND ACUTE] + case 0x1E4F: // [LATIN SMALL LETTER O WITH TILDE AND DIAERESIS] + case 0x1E51: // [LATIN SMALL LETTER O WITH MACRON AND GRAVE] + case 0x1E53: // [LATIN SMALL LETTER O WITH MACRON AND ACUTE] + case 0x1ECD: // [LATIN SMALL LETTER O WITH DOT BELOW] + case 0x1ECF: // [LATIN SMALL LETTER O WITH HOOK ABOVE] + case 0x1ED1: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE] + case 0x1ED3: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE] + case 0x1ED5: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE] + case 0x1ED7: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE] + case 0x1ED9: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW] + case 0x1EDB: // [LATIN SMALL LETTER O WITH HORN AND ACUTE] + case 0x1EDD: // [LATIN SMALL LETTER O WITH HORN AND GRAVE] + case 0x1EDF: // [LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE] + case 0x1EE1: // [LATIN SMALL LETTER O WITH HORN AND TILDE] + case 0x1EE3: // [LATIN SMALL LETTER O WITH HORN AND DOT BELOW] + case 0x2092: // [LATIN SUBSCRIPT SMALL LETTER O] + case 0x24DE: // [CIRCLED LATIN SMALL LETTER O] + case 0x2C7A: // [LATIN SMALL LETTER O WITH LOW RING INSIDE] + case 0xA74B: // [LATIN SMALL LETTER O WITH LONG STROKE OVERLAY] + case 0xA74D: // [LATIN SMALL LETTER O WITH LOOP] + case 0xFF4F: // [FULLWIDTH LATIN SMALL LETTER O] + output[outputPos++] = L'o'; + break; + case 0x0152: // [LATIN CAPITAL LIGATURE OE] + case 0x0276: // [LATIN LETTER SMALL CAPITAL OE] + output[outputPos++] = L'O'; + output[outputPos++] = L'E'; + break; + case 0xA74E: // [LATIN CAPITAL LETTER OO] + output[outputPos++] = L'O'; + output[outputPos++] = L'O'; + break; + case 0x0222: // [LATIN CAPITAL LETTER OU] + case 0x1D15: // [LATIN LETTER SMALL CAPITAL OU] + output[outputPos++] = L'O'; + output[outputPos++] = L'U'; + break; + case 0x24AA: // [PARENTHESIZED LATIN SMALL LETTER O] + output[outputPos++] = L'('; + output[outputPos++] = L'o'; + output[outputPos++] = L')'; + break; + case 0x0153: // [LATIN SMALL LIGATURE OE] + case 0x1D14: // [LATIN SMALL LETTER TURNED OE] + output[outputPos++] = L'o'; + output[outputPos++] = L'e'; + break; + case 0xA74F: // [LATIN SMALL LETTER OO] + output[outputPos++] = L'o'; + output[outputPos++] = L'o'; + break; + case 0x0223: // [LATIN SMALL LETTER OU] + output[outputPos++] = L'o'; + output[outputPos++] = L'u'; + break; + case 0x01A4: // [LATIN CAPITAL LETTER P WITH HOOK] + case 0x1D18: // [LATIN LETTER SMALL CAPITAL P] + case 0x1E54: // [LATIN CAPITAL LETTER P WITH ACUTE] + case 0x1E56: // [LATIN CAPITAL LETTER P WITH DOT ABOVE] + case 0x24C5: // [CIRCLED LATIN CAPITAL LETTER P] + case 0x2C63: // [LATIN CAPITAL LETTER P WITH STROKE] + case 0xA750: // [LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER] + case 0xA752: // [LATIN CAPITAL LETTER P WITH FLOURISH] + case 0xA754: // [LATIN CAPITAL LETTER P WITH SQUIRREL TAIL] + case 0xFF30: // [FULLWIDTH LATIN CAPITAL LETTER P] + output[outputPos++] = L'P'; + break; + case 0x01A5: // [LATIN SMALL LETTER P WITH HOOK] + case 0x1D71: // [LATIN SMALL LETTER P WITH MIDDLE TILDE] + case 0x1D7D: // [LATIN SMALL LETTER P WITH STROKE] + case 0x1D88: // [LATIN SMALL LETTER P WITH PALATAL HOOK] + case 0x1E55: // [LATIN SMALL LETTER P WITH ACUTE] + case 0x1E57: // [LATIN SMALL LETTER P WITH DOT ABOVE] + case 0x24DF: // [CIRCLED LATIN SMALL LETTER P] + case 0xA751: // [LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER] + case 0xA753: // [LATIN SMALL LETTER P WITH FLOURISH] + case 0xA755: // [LATIN SMALL LETTER P WITH SQUIRREL TAIL] + case 0xA7FC: // [LATIN EPIGRAPHIC LETTER REVERSED P] + case 0xFF50: // [FULLWIDTH LATIN SMALL LETTER P] + output[outputPos++] = L'p'; + break; + case 0x24AB: // [PARENTHESIZED LATIN SMALL LETTER P] + output[outputPos++] = L'('; + output[outputPos++] = L'p'; + output[outputPos++] = L')'; + break; + case 0x024A: // [LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL] + case 0x24C6: // [CIRCLED LATIN CAPITAL LETTER Q] + case 0xA756: // [LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER] + case 0xA758: // [LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE] + case 0xFF31: // [FULLWIDTH LATIN CAPITAL LETTER Q] + output[outputPos++] = L'Q'; + break; + case 0x0138: // [LATIN SMALL LETTER KRA] + case 0x024B: // [LATIN SMALL LETTER Q WITH HOOK TAIL] + case 0x02A0: // [LATIN SMALL LETTER Q WITH HOOK] + case 0x24E0: // [CIRCLED LATIN SMALL LETTER Q] + case 0xA757: // [LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER] + case 0xA759: // [LATIN SMALL LETTER Q WITH DIAGONAL STROKE] + case 0xFF51: // [FULLWIDTH LATIN SMALL LETTER Q] + output[outputPos++] = L'q'; + break; + case 0x24AC: // [PARENTHESIZED LATIN SMALL LETTER Q] + output[outputPos++] = L'('; + output[outputPos++] = L'q'; + output[outputPos++] = L')'; + break; + case 0x0239: // [LATIN SMALL LETTER QP DIGRAPH] + output[outputPos++] = L'q'; + output[outputPos++] = L'p'; + break; + case 0x0154: // [LATIN CAPITAL LETTER R WITH ACUTE] + case 0x0156: // [LATIN CAPITAL LETTER R WITH CEDILLA] + case 0x0158: // [LATIN CAPITAL LETTER R WITH CARON] + case 0x0210: // [LATIN CAPITAL LETTER R WITH DOUBLE GRAVE] + case 0x0212: // [LATIN CAPITAL LETTER R WITH INVERTED BREVE] + case 0x024C: // [LATIN CAPITAL LETTER R WITH STROKE] + case 0x0280: // [LATIN LETTER SMALL CAPITAL R] + case 0x0281: // [LATIN LETTER SMALL CAPITAL INVERTED R] + case 0x1D19: // [LATIN LETTER SMALL CAPITAL REVERSED R] + case 0x1D1A: // [LATIN LETTER SMALL CAPITAL TURNED R] + case 0x1E58: // [LATIN CAPITAL LETTER R WITH DOT ABOVE] + case 0x1E5A: // [LATIN CAPITAL LETTER R WITH DOT BELOW] + case 0x1E5C: // [LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON] + case 0x1E5E: // [LATIN CAPITAL LETTER R WITH LINE BELOW] + case 0x24C7: // [CIRCLED LATIN CAPITAL LETTER R] + case 0x2C64: // [LATIN CAPITAL LETTER R WITH TAIL] + case 0xA75A: // [LATIN CAPITAL LETTER R ROTUNDA] + case 0xA782: // [LATIN CAPITAL LETTER INSULAR R] + case 0xFF32: // [FULLWIDTH LATIN CAPITAL LETTER R] + output[outputPos++] = L'R'; + break; + case 0x0155: // [LATIN SMALL LETTER R WITH ACUTE] + case 0x0157: // [LATIN SMALL LETTER R WITH CEDILLA] + case 0x0159: // [LATIN SMALL LETTER R WITH CARON] + case 0x0211: // [LATIN SMALL LETTER R WITH DOUBLE GRAVE] + case 0x0213: // [LATIN SMALL LETTER R WITH INVERTED BREVE] + case 0x024D: // [LATIN SMALL LETTER R WITH STROKE] + case 0x027C: // [LATIN SMALL LETTER R WITH LONG LEG] + case 0x027D: // [LATIN SMALL LETTER R WITH TAIL] + case 0x027E: // [LATIN SMALL LETTER R WITH FISHHOOK] + case 0x027F: // [LATIN SMALL LETTER REVERSED R WITH FISHHOOK] + case 0x1D63: // [LATIN SUBSCRIPT SMALL LETTER R] + case 0x1D72: // [LATIN SMALL LETTER R WITH MIDDLE TILDE] + case 0x1D73: // [LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE] + case 0x1D89: // [LATIN SMALL LETTER R WITH PALATAL HOOK] + case 0x1E59: // [LATIN SMALL LETTER R WITH DOT ABOVE] + case 0x1E5B: // [LATIN SMALL LETTER R WITH DOT BELOW] + case 0x1E5D: // [LATIN SMALL LETTER R WITH DOT BELOW AND MACRON] + case 0x1E5F: // [LATIN SMALL LETTER R WITH LINE BELOW] + case 0x24E1: // [CIRCLED LATIN SMALL LETTER R] + case 0xA75B: // [LATIN SMALL LETTER R ROTUNDA] + case 0xA783: // [LATIN SMALL LETTER INSULAR R] + case 0xFF52: // [FULLWIDTH LATIN SMALL LETTER R] + output[outputPos++] = L'r'; + break; + case 0x24AD: // [PARENTHESIZED LATIN SMALL LETTER R] + output[outputPos++] = L'('; + output[outputPos++] = L'r'; + output[outputPos++] = L')'; + break; + case 0x015A: // [LATIN CAPITAL LETTER S WITH ACUTE] + case 0x015C: // [LATIN CAPITAL LETTER S WITH CIRCUMFLEX] + case 0x015E: // [LATIN CAPITAL LETTER S WITH CEDILLA] + case 0x0160: // [LATIN CAPITAL LETTER S WITH CARON] + case 0x0218: // [LATIN CAPITAL LETTER S WITH COMMA BELOW] + case 0x1E60: // [LATIN CAPITAL LETTER S WITH DOT ABOVE] + case 0x1E62: // [LATIN CAPITAL LETTER S WITH DOT BELOW] + case 0x1E64: // [LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE] + case 0x1E66: // [LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE] + case 0x1E68: // [LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE] + case 0x24C8: // [CIRCLED LATIN CAPITAL LETTER S] + case 0xA731: // [LATIN LETTER SMALL CAPITAL S] + case 0xA785: // [LATIN SMALL LETTER INSULAR S] + case 0xFF33: // [FULLWIDTH LATIN CAPITAL LETTER S] + output[outputPos++] = L'S'; + break; + case 0x015B: // [LATIN SMALL LETTER S WITH ACUTE] + case 0x015D: // [LATIN SMALL LETTER S WITH CIRCUMFLEX] + case 0x015F: // [LATIN SMALL LETTER S WITH CEDILLA] + case 0x0161: // [LATIN SMALL LETTER S WITH CARON] + case 0x017F: // [LATIN SMALL LETTER LONG S] + case 0x0219: // [LATIN SMALL LETTER S WITH COMMA BELOW] + case 0x023F: // [LATIN SMALL LETTER S WITH SWASH TAIL] + case 0x0282: // [LATIN SMALL LETTER S WITH HOOK] + case 0x1D74: // [LATIN SMALL LETTER S WITH MIDDLE TILDE] + case 0x1D8A: // [LATIN SMALL LETTER S WITH PALATAL HOOK] + case 0x1E61: // [LATIN SMALL LETTER S WITH DOT ABOVE] + case 0x1E63: // [LATIN SMALL LETTER S WITH DOT BELOW] + case 0x1E65: // [LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE] + case 0x1E67: // [LATIN SMALL LETTER S WITH CARON AND DOT ABOVE] + case 0x1E69: // [LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE] + case 0x1E9C: // [LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE] + case 0x1E9D: // [LATIN SMALL LETTER LONG S WITH HIGH STROKE] + case 0x24E2: // [CIRCLED LATIN SMALL LETTER S] + case 0xA784: // [LATIN CAPITAL LETTER INSULAR S] + case 0xFF53: // [FULLWIDTH LATIN SMALL LETTER S] + output[outputPos++] = L's'; + break; + case 0x1E9E: // [LATIN CAPITAL LETTER SHARP S] + output[outputPos++] = L'S'; + output[outputPos++] = L'S'; + break; + case 0x24AE: // [PARENTHESIZED LATIN SMALL LETTER S] + output[outputPos++] = L'('; + output[outputPos++] = L's'; + output[outputPos++] = L')'; + break; + case 0x00DF: // [LATIN SMALL LETTER SHARP S] + output[outputPos++] = L's'; + output[outputPos++] = L's'; + break; + case 0xFB06: // [LATIN SMALL LIGATURE ST] + output[outputPos++] = L's'; + output[outputPos++] = L't'; + break; + case 0x0162: // [LATIN CAPITAL LETTER T WITH CEDILLA] + case 0x0164: // [LATIN CAPITAL LETTER T WITH CARON] + case 0x0166: // [LATIN CAPITAL LETTER T WITH STROKE] + case 0x01AC: // [LATIN CAPITAL LETTER T WITH HOOK] + case 0x01AE: // [LATIN CAPITAL LETTER T WITH RETROFLEX HOOK] + case 0x021A: // [LATIN CAPITAL LETTER T WITH COMMA BELOW] + case 0x023E: // [LATIN CAPITAL LETTER T WITH DIAGONAL STROKE] + case 0x1D1B: // [LATIN LETTER SMALL CAPITAL T] + case 0x1E6A: // [LATIN CAPITAL LETTER T WITH DOT ABOVE] + case 0x1E6C: // [LATIN CAPITAL LETTER T WITH DOT BELOW] + case 0x1E6E: // [LATIN CAPITAL LETTER T WITH LINE BELOW] + case 0x1E70: // [LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW] + case 0x24C9: // [CIRCLED LATIN CAPITAL LETTER T] + case 0xA786: // [LATIN CAPITAL LETTER INSULAR T] + case 0xFF34: // [FULLWIDTH LATIN CAPITAL LETTER T] + output[outputPos++] = L'T'; + break; + case 0x0163: // [LATIN SMALL LETTER T WITH CEDILLA] + case 0x0165: // [LATIN SMALL LETTER T WITH CARON] + case 0x0167: // [LATIN SMALL LETTER T WITH STROKE] + case 0x01AB: // [LATIN SMALL LETTER T WITH PALATAL HOOK] + case 0x01AD: // [LATIN SMALL LETTER T WITH HOOK] + case 0x021B: // [LATIN SMALL LETTER T WITH COMMA BELOW] + case 0x0236: // [LATIN SMALL LETTER T WITH CURL] + case 0x0287: // [LATIN SMALL LETTER TURNED T] + case 0x0288: // [LATIN SMALL LETTER T WITH RETROFLEX HOOK] + case 0x1D75: // [LATIN SMALL LETTER T WITH MIDDLE TILDE] + case 0x1E6B: // [LATIN SMALL LETTER T WITH DOT ABOVE] + case 0x1E6D: // [LATIN SMALL LETTER T WITH DOT BELOW] + case 0x1E6F: // [LATIN SMALL LETTER T WITH LINE BELOW] + case 0x1E71: // [LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW] + case 0x1E97: // [LATIN SMALL LETTER T WITH DIAERESIS] + case 0x24E3: // [CIRCLED LATIN SMALL LETTER T] + case 0x2C66: // [LATIN SMALL LETTER T WITH DIAGONAL STROKE] + case 0xFF54: // [FULLWIDTH LATIN SMALL LETTER T] + output[outputPos++] = L't'; + break; + case 0x00DE: // [LATIN CAPITAL LETTER THORN] + case 0xA766: // [LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER] + output[outputPos++] = L'T'; + output[outputPos++] = L'H'; + break; + case 0xA728: // [LATIN CAPITAL LETTER TZ] + output[outputPos++] = L'T'; + output[outputPos++] = L'Z'; + break; + case 0x24AF: // [PARENTHESIZED LATIN SMALL LETTER T] + output[outputPos++] = L'('; + output[outputPos++] = L't'; + output[outputPos++] = L')'; + break; + case 0x02A8: // [LATIN SMALL LETTER TC DIGRAPH WITH CURL] + output[outputPos++] = L't'; + output[outputPos++] = L'c'; + break; + case 0x00FE: // [LATIN SMALL LETTER THORN] + case 0x1D7A: // [LATIN SMALL LETTER TH WITH STRIKETHROUGH] + case 0xA767: // [LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER] + output[outputPos++] = L't'; + output[outputPos++] = L'h'; + break; + case 0x02A6: // [LATIN SMALL LETTER TS DIGRAPH] + output[outputPos++] = L't'; + output[outputPos++] = L's'; + break; + case 0xA729: // [LATIN SMALL LETTER TZ] + output[outputPos++] = L't'; + output[outputPos++] = L'z'; + break; + case 0x00D9: // [LATIN CAPITAL LETTER U WITH GRAVE] + case 0x00DA: // [LATIN CAPITAL LETTER U WITH ACUTE] + case 0x00DB: // [LATIN CAPITAL LETTER U WITH CIRCUMFLEX] + case 0x00DC: // [LATIN CAPITAL LETTER U WITH DIAERESIS] + case 0x0168: // [LATIN CAPITAL LETTER U WITH TILDE] + case 0x016A: // [LATIN CAPITAL LETTER U WITH MACRON] + case 0x016C: // [LATIN CAPITAL LETTER U WITH BREVE] + case 0x016E: // [LATIN CAPITAL LETTER U WITH RING ABOVE] + case 0x0170: // [LATIN CAPITAL LETTER U WITH DOUBLE ACUTE] + case 0x0172: // [LATIN CAPITAL LETTER U WITH OGONEK] + case 0x01AF: // [LATIN CAPITAL LETTER U WITH HORN] + case 0x01D3: // [LATIN CAPITAL LETTER U WITH CARON] + case 0x01D5: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON] + case 0x01D7: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE] + case 0x01D9: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON] + case 0x01DB: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE] + case 0x0214: // [LATIN CAPITAL LETTER U WITH DOUBLE GRAVE] + case 0x0216: // [LATIN CAPITAL LETTER U WITH INVERTED BREVE] + case 0x0244: // [LATIN CAPITAL LETTER U BAR] + case 0x1D1C: // [LATIN LETTER SMALL CAPITAL U] + case 0x1D7E: // [LATIN SMALL CAPITAL LETTER U WITH STROKE] + case 0x1E72: // [LATIN CAPITAL LETTER U WITH DIAERESIS BELOW] + case 0x1E74: // [LATIN CAPITAL LETTER U WITH TILDE BELOW] + case 0x1E76: // [LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW] + case 0x1E78: // [LATIN CAPITAL LETTER U WITH TILDE AND ACUTE] + case 0x1E7A: // [LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS] + case 0x1EE4: // [LATIN CAPITAL LETTER U WITH DOT BELOW] + case 0x1EE6: // [LATIN CAPITAL LETTER U WITH HOOK ABOVE] + case 0x1EE8: // [LATIN CAPITAL LETTER U WITH HORN AND ACUTE] + case 0x1EEA: // [LATIN CAPITAL LETTER U WITH HORN AND GRAVE] + case 0x1EEC: // [LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE] + case 0x1EEE: // [LATIN CAPITAL LETTER U WITH HORN AND TILDE] + case 0x1EF0: // [LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW] + case 0x24CA: // [CIRCLED LATIN CAPITAL LETTER U] + case 0xFF35: // [FULLWIDTH LATIN CAPITAL LETTER U] + output[outputPos++] = L'U'; + break; + case 0x00F9: // [LATIN SMALL LETTER U WITH GRAVE] + case 0x00FA: // [LATIN SMALL LETTER U WITH ACUTE] + case 0x00FB: // [LATIN SMALL LETTER U WITH CIRCUMFLEX] + case 0x00FC: // [LATIN SMALL LETTER U WITH DIAERESIS] + case 0x0169: // [LATIN SMALL LETTER U WITH TILDE] + case 0x016B: // [LATIN SMALL LETTER U WITH MACRON] + case 0x016D: // [LATIN SMALL LETTER U WITH BREVE] + case 0x016F: // [LATIN SMALL LETTER U WITH RING ABOVE] + case 0x0171: // [LATIN SMALL LETTER U WITH DOUBLE ACUTE] + case 0x0173: // [LATIN SMALL LETTER U WITH OGONEK] + case 0x01B0: // [LATIN SMALL LETTER U WITH HORN] + case 0x01D4: // [LATIN SMALL LETTER U WITH CARON] + case 0x01D6: // [LATIN SMALL LETTER U WITH DIAERESIS AND MACRON] + case 0x01D8: // [LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE] + case 0x01DA: // [LATIN SMALL LETTER U WITH DIAERESIS AND CARON] + case 0x01DC: // [LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE] + case 0x0215: // [LATIN SMALL LETTER U WITH DOUBLE GRAVE] + case 0x0217: // [LATIN SMALL LETTER U WITH INVERTED BREVE] + case 0x0289: // [LATIN SMALL LETTER U BAR] + case 0x1D64: // [LATIN SUBSCRIPT SMALL LETTER U] + case 0x1D99: // [LATIN SMALL LETTER U WITH RETROFLEX HOOK] + case 0x1E73: // [LATIN SMALL LETTER U WITH DIAERESIS BELOW] + case 0x1E75: // [LATIN SMALL LETTER U WITH TILDE BELOW] + case 0x1E77: // [LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW] + case 0x1E79: // [LATIN SMALL LETTER U WITH TILDE AND ACUTE] + case 0x1E7B: // [LATIN SMALL LETTER U WITH MACRON AND DIAERESIS] + case 0x1EE5: // [LATIN SMALL LETTER U WITH DOT BELOW] + case 0x1EE7: // [LATIN SMALL LETTER U WITH HOOK ABOVE] + case 0x1EE9: // [LATIN SMALL LETTER U WITH HORN AND ACUTE] + case 0x1EEB: // [LATIN SMALL LETTER U WITH HORN AND GRAVE] + case 0x1EED: // [LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE] + case 0x1EEF: // [LATIN SMALL LETTER U WITH HORN AND TILDE] + case 0x1EF1: // [LATIN SMALL LETTER U WITH HORN AND DOT BELOW] + case 0x24E4: // [CIRCLED LATIN SMALL LETTER U] + case 0xFF55: // [FULLWIDTH LATIN SMALL LETTER U] + output[outputPos++] = L'u'; + break; + case 0x24B0: // [PARENTHESIZED LATIN SMALL LETTER U] + output[outputPos++] = L'('; + output[outputPos++] = L'u'; + output[outputPos++] = L')'; + break; + case 0x1D6B: // [LATIN SMALL LETTER UE] + output[outputPos++] = L'u'; + output[outputPos++] = L'e'; + break; + case 0x01B2: // [LATIN CAPITAL LETTER V WITH HOOK] + case 0x0245: // [LATIN CAPITAL LETTER TURNED V] + case 0x1D20: // [LATIN LETTER SMALL CAPITAL V] + case 0x1E7C: // [LATIN CAPITAL LETTER V WITH TILDE] + case 0x1E7E: // [LATIN CAPITAL LETTER V WITH DOT BELOW] + case 0x1EFC: // [LATIN CAPITAL LETTER MIDDLE-WELSH V] + case 0x24CB: // [CIRCLED LATIN CAPITAL LETTER V] + case 0xA75E: // [LATIN CAPITAL LETTER V WITH DIAGONAL STROKE] + case 0xA768: // [LATIN CAPITAL LETTER VEND] + case 0xFF36: // [FULLWIDTH LATIN CAPITAL LETTER V] + output[outputPos++] = L'V'; + break; + case 0x028B: // [LATIN SMALL LETTER V WITH HOOK] + case 0x028C: // [LATIN SMALL LETTER TURNED V] + case 0x1D65: // [LATIN SUBSCRIPT SMALL LETTER V] + case 0x1D8C: // [LATIN SMALL LETTER V WITH PALATAL HOOK] + case 0x1E7D: // [LATIN SMALL LETTER V WITH TILDE] + case 0x1E7F: // [LATIN SMALL LETTER V WITH DOT BELOW] + case 0x24E5: // [CIRCLED LATIN SMALL LETTER V] + case 0x2C71: // [LATIN SMALL LETTER V WITH RIGHT HOOK] + case 0x2C74: // [LATIN SMALL LETTER V WITH CURL] + case 0xA75F: // [LATIN SMALL LETTER V WITH DIAGONAL STROKE] + case 0xFF56: // [FULLWIDTH LATIN SMALL LETTER V] + output[outputPos++] = L'v'; + break; + case 0xA760: // [LATIN CAPITAL LETTER VY] + output[outputPos++] = L'V'; + output[outputPos++] = L'Y'; + break; + case 0x24B1: // [PARENTHESIZED LATIN SMALL LETTER V] + output[outputPos++] = L'('; + output[outputPos++] = L'v'; + output[outputPos++] = L')'; + break; + case 0xA761: // [LATIN SMALL LETTER VY] + output[outputPos++] = L'v'; + output[outputPos++] = L'y'; + break; + case 0x0174: // [LATIN CAPITAL LETTER W WITH CIRCUMFLEX] + case 0x01F7: // [LATIN CAPITAL LETTER WYNN] + case 0x1D21: // [LATIN LETTER SMALL CAPITAL W] + case 0x1E80: // [LATIN CAPITAL LETTER W WITH GRAVE] + case 0x1E82: // [LATIN CAPITAL LETTER W WITH ACUTE] + case 0x1E84: // [LATIN CAPITAL LETTER W WITH DIAERESIS] + case 0x1E86: // [LATIN CAPITAL LETTER W WITH DOT ABOVE] + case 0x1E88: // [LATIN CAPITAL LETTER W WITH DOT BELOW] + case 0x24CC: // [CIRCLED LATIN CAPITAL LETTER W] + case 0x2C72: // [LATIN CAPITAL LETTER W WITH HOOK] + case 0xFF37: // [FULLWIDTH LATIN CAPITAL LETTER W] + output[outputPos++] = L'W'; + break; + case 0x0175: // [LATIN SMALL LETTER W WITH CIRCUMFLEX] + case 0x01BF: // [LATIN LETTER WYNN] + case 0x028D: // [LATIN SMALL LETTER TURNED W] + case 0x1E81: // [LATIN SMALL LETTER W WITH GRAVE] + case 0x1E83: // [LATIN SMALL LETTER W WITH ACUTE] + case 0x1E85: // [LATIN SMALL LETTER W WITH DIAERESIS] + case 0x1E87: // [LATIN SMALL LETTER W WITH DOT ABOVE] + case 0x1E89: // [LATIN SMALL LETTER W WITH DOT BELOW] + case 0x1E98: // [LATIN SMALL LETTER W WITH RING ABOVE] + case 0x24E6: // [CIRCLED LATIN SMALL LETTER W] + case 0x2C73: // [LATIN SMALL LETTER W WITH HOOK] + case 0xFF57: // [FULLWIDTH LATIN SMALL LETTER W] + output[outputPos++] = L'w'; + break; + case 0x24B2: // [PARENTHESIZED LATIN SMALL LETTER W] + output[outputPos++] = L'('; + output[outputPos++] = L'w'; + output[outputPos++] = L')'; + break; + case 0x1E8A: // [LATIN CAPITAL LETTER X WITH DOT ABOVE] + case 0x1E8C: // [LATIN CAPITAL LETTER X WITH DIAERESIS] + case 0x24CD: // [CIRCLED LATIN CAPITAL LETTER X] + case 0xFF38: // [FULLWIDTH LATIN CAPITAL LETTER X] + output[outputPos++] = L'X'; + break; + case 0x1D8D: // [LATIN SMALL LETTER X WITH PALATAL HOOK] + case 0x1E8B: // [LATIN SMALL LETTER X WITH DOT ABOVE] + case 0x1E8D: // [LATIN SMALL LETTER X WITH DIAERESIS] + case 0x2093: // [LATIN SUBSCRIPT SMALL LETTER X] + case 0x24E7: // [CIRCLED LATIN SMALL LETTER X] + case 0xFF58: // [FULLWIDTH LATIN SMALL LETTER X] + output[outputPos++] = L'x'; + break; + case 0x24B3: // [PARENTHESIZED LATIN SMALL LETTER X] + output[outputPos++] = L'('; + output[outputPos++] = L'x'; + output[outputPos++] = L')'; + break; + case 0x00DD: // [LATIN CAPITAL LETTER Y WITH ACUTE] + case 0x0176: // [LATIN CAPITAL LETTER Y WITH CIRCUMFLEX] + case 0x0178: // [LATIN CAPITAL LETTER Y WITH DIAERESIS] + case 0x01B3: // [LATIN CAPITAL LETTER Y WITH HOOK] + case 0x0232: // [LATIN CAPITAL LETTER Y WITH MACRON] + case 0x024E: // [LATIN CAPITAL LETTER Y WITH STROKE] + case 0x028F: // [LATIN LETTER SMALL CAPITAL Y] + case 0x1E8E: // [LATIN CAPITAL LETTER Y WITH DOT ABOVE] + case 0x1EF2: // [LATIN CAPITAL LETTER Y WITH GRAVE] + case 0x1EF4: // [LATIN CAPITAL LETTER Y WITH DOT BELOW] + case 0x1EF6: // [LATIN CAPITAL LETTER Y WITH HOOK ABOVE] + case 0x1EF8: // [LATIN CAPITAL LETTER Y WITH TILDE] + case 0x1EFE: // [LATIN CAPITAL LETTER Y WITH LOOP] + case 0x24CE: // [CIRCLED LATIN CAPITAL LETTER Y] + case 0xFF39: // [FULLWIDTH LATIN CAPITAL LETTER Y] + output[outputPos++] = L'Y'; + break; + case 0x00FD: // [LATIN SMALL LETTER Y WITH ACUTE] + case 0x00FF: // [LATIN SMALL LETTER Y WITH DIAERESIS] + case 0x0177: // [LATIN SMALL LETTER Y WITH CIRCUMFLEX] + case 0x01B4: // [LATIN SMALL LETTER Y WITH HOOK] + case 0x0233: // [LATIN SMALL LETTER Y WITH MACRON] + case 0x024F: // [LATIN SMALL LETTER Y WITH STROKE] + case 0x028E: // [LATIN SMALL LETTER TURNED Y] + case 0x1E8F: // [LATIN SMALL LETTER Y WITH DOT ABOVE] + case 0x1E99: // [LATIN SMALL LETTER Y WITH RING ABOVE] + case 0x1EF3: // [LATIN SMALL LETTER Y WITH GRAVE] + case 0x1EF5: // [LATIN SMALL LETTER Y WITH DOT BELOW] + case 0x1EF7: // [LATIN SMALL LETTER Y WITH HOOK ABOVE] + case 0x1EF9: // [LATIN SMALL LETTER Y WITH TILDE] + case 0x1EFF: // [LATIN SMALL LETTER Y WITH LOOP] + case 0x24E8: // [CIRCLED LATIN SMALL LETTER Y] + case 0xFF59: // [FULLWIDTH LATIN SMALL LETTER Y] + output[outputPos++] = L'y'; + break; + case 0x24B4: // [PARENTHESIZED LATIN SMALL LETTER Y] + output[outputPos++] = L'('; + output[outputPos++] = L'y'; + output[outputPos++] = L')'; + break; + case 0x0179: // [LATIN CAPITAL LETTER Z WITH ACUTE] + case 0x017B: // [LATIN CAPITAL LETTER Z WITH DOT ABOVE] + case 0x017D: // [LATIN CAPITAL LETTER Z WITH CARON] + case 0x01B5: // [LATIN CAPITAL LETTER Z WITH STROKE] + case 0x021C: // [LATIN CAPITAL LETTER YOGH] + case 0x0224: // [LATIN CAPITAL LETTER Z WITH HOOK] + case 0x1D22: // [LATIN LETTER SMALL CAPITAL Z] + case 0x1E90: // [LATIN CAPITAL LETTER Z WITH CIRCUMFLEX] + case 0x1E92: // [LATIN CAPITAL LETTER Z WITH DOT BELOW] + case 0x1E94: // [LATIN CAPITAL LETTER Z WITH LINE BELOW] + case 0x24CF: // [CIRCLED LATIN CAPITAL LETTER Z] + case 0x2C6B: // [LATIN CAPITAL LETTER Z WITH DESCENDER] + case 0xA762: // [LATIN CAPITAL LETTER VISIGOTHIC Z] + case 0xFF3A: // [FULLWIDTH LATIN CAPITAL LETTER Z] + output[outputPos++] = L'Z'; + break; + case 0x017A: // [LATIN SMALL LETTER Z WITH ACUTE] + case 0x017C: // [LATIN SMALL LETTER Z WITH DOT ABOVE] + case 0x017E: // [LATIN SMALL LETTER Z WITH CARON] + case 0x01B6: // [LATIN SMALL LETTER Z WITH STROKE] + case 0x021D: // [LATIN SMALL LETTER YOGH] + case 0x0225: // [LATIN SMALL LETTER Z WITH HOOK] + case 0x0240: // [LATIN SMALL LETTER Z WITH SWASH TAIL] + case 0x0290: // [LATIN SMALL LETTER Z WITH RETROFLEX HOOK] + case 0x0291: // [LATIN SMALL LETTER Z WITH CURL] + case 0x1D76: // [LATIN SMALL LETTER Z WITH MIDDLE TILDE] + case 0x1D8E: // [LATIN SMALL LETTER Z WITH PALATAL HOOK] + case 0x1E91: // [LATIN SMALL LETTER Z WITH CIRCUMFLEX] + case 0x1E93: // [LATIN SMALL LETTER Z WITH DOT BELOW] + case 0x1E95: // [LATIN SMALL LETTER Z WITH LINE BELOW] + case 0x24E9: // [CIRCLED LATIN SMALL LETTER Z] + case 0x2C6C: // [LATIN SMALL LETTER Z WITH DESCENDER] + case 0xA763: // [LATIN SMALL LETTER VISIGOTHIC Z] + case 0xFF5A: // [FULLWIDTH LATIN SMALL LETTER Z] + output[outputPos++] = L'z'; + break; + case 0x24B5: // [PARENTHESIZED LATIN SMALL LETTER Z] + output[outputPos++] = L'('; + output[outputPos++] = L'z'; + output[outputPos++] = L')'; + break; + case 0x2070: // [SUPERSCRIPT ZERO] + case 0x2080: // [SUBSCRIPT ZERO] + case 0x24EA: // [CIRCLED DIGIT ZERO] + case 0x24FF: // [NEGATIVE CIRCLED DIGIT ZERO] + case 0xFF10: // [FULLWIDTH DIGIT ZERO] + output[outputPos++] = L'0'; + break; + case 0x00B9: // [SUPERSCRIPT ONE] + case 0x2081: // [SUBSCRIPT ONE] + case 0x2460: // [CIRCLED DIGIT ONE] + case 0x24F5: // [DOUBLE CIRCLED DIGIT ONE] + case 0x2776: // [DINGBAT NEGATIVE CIRCLED DIGIT ONE] + case 0x2780: // [DINGBAT CIRCLED SANS-SERIF DIGIT ONE] + case 0x278A: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE] + case 0xFF11: // [FULLWIDTH DIGIT ONE] + output[outputPos++] = L'1'; + break; + case 0x2488: // [DIGIT ONE FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'.'; + break; + case 0x2474: // [PARENTHESIZED DIGIT ONE] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L')'; + break; + case 0x00B2: // [SUPERSCRIPT TWO] + case 0x2082: // [SUBSCRIPT TWO] + case 0x2461: // [CIRCLED DIGIT TWO] + case 0x24F6: // [DOUBLE CIRCLED DIGIT TWO] + case 0x2777: // [DINGBAT NEGATIVE CIRCLED DIGIT TWO] + case 0x2781: // [DINGBAT CIRCLED SANS-SERIF DIGIT TWO] + case 0x278B: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO] + case 0xFF12: // [FULLWIDTH DIGIT TWO] + output[outputPos++] = L'2'; + break; + case 0x2489: // [DIGIT TWO FULL STOP] + output[outputPos++] = L'2'; + output[outputPos++] = L'.'; + break; + case 0x2475: // [PARENTHESIZED DIGIT TWO] + output[outputPos++] = L'('; + output[outputPos++] = L'2'; + output[outputPos++] = L')'; + break; + case 0x00B3: // [SUPERSCRIPT THREE] + case 0x2083: // [SUBSCRIPT THREE] + case 0x2462: // [CIRCLED DIGIT THREE] + case 0x24F7: // [DOUBLE CIRCLED DIGIT THREE] + case 0x2778: // [DINGBAT NEGATIVE CIRCLED DIGIT THREE] + case 0x2782: // [DINGBAT CIRCLED SANS-SERIF DIGIT THREE] + case 0x278C: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE] + case 0xFF13: // [FULLWIDTH DIGIT THREE] + output[outputPos++] = L'3'; + break; + case 0x248A: // [DIGIT THREE FULL STOP] + output[outputPos++] = L'3'; + output[outputPos++] = L'.'; + break; + case 0x2476: // [PARENTHESIZED DIGIT THREE] + output[outputPos++] = L'('; + output[outputPos++] = L'3'; + output[outputPos++] = L')'; + break; + case 0x2074: // [SUPERSCRIPT FOUR] + case 0x2084: // [SUBSCRIPT FOUR] + case 0x2463: // [CIRCLED DIGIT FOUR] + case 0x24F8: // [DOUBLE CIRCLED DIGIT FOUR] + case 0x2779: // [DINGBAT NEGATIVE CIRCLED DIGIT FOUR] + case 0x2783: // [DINGBAT CIRCLED SANS-SERIF DIGIT FOUR] + case 0x278D: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR] + case 0xFF14: // [FULLWIDTH DIGIT FOUR] + output[outputPos++] = L'4'; + break; + case 0x248B: // [DIGIT FOUR FULL STOP] + output[outputPos++] = L'4'; + output[outputPos++] = L'.'; + break; + case 0x2477: // [PARENTHESIZED DIGIT FOUR] + output[outputPos++] = L'('; + output[outputPos++] = L'4'; + output[outputPos++] = L')'; + break; + case 0x2075: // [SUPERSCRIPT FIVE] + case 0x2085: // [SUBSCRIPT FIVE] + case 0x2464: // [CIRCLED DIGIT FIVE] + case 0x24F9: // [DOUBLE CIRCLED DIGIT FIVE] + case 0x277A: // [DINGBAT NEGATIVE CIRCLED DIGIT FIVE] + case 0x2784: // [DINGBAT CIRCLED SANS-SERIF DIGIT FIVE] + case 0x278E: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE] + case 0xFF15: // [FULLWIDTH DIGIT FIVE] + output[outputPos++] = L'5'; + break; + case 0x248C: // [DIGIT FIVE FULL STOP] + output[outputPos++] = L'5'; + output[outputPos++] = L'.'; + break; + case 0x2478: // [PARENTHESIZED DIGIT FIVE] + output[outputPos++] = L'('; + output[outputPos++] = L'5'; + output[outputPos++] = L')'; + break; + case 0x2076: // [SUPERSCRIPT SIX] + case 0x2086: // [SUBSCRIPT SIX] + case 0x2465: // [CIRCLED DIGIT SIX] + case 0x24FA: // [DOUBLE CIRCLED DIGIT SIX] + case 0x277B: // [DINGBAT NEGATIVE CIRCLED DIGIT SIX] + case 0x2785: // [DINGBAT CIRCLED SANS-SERIF DIGIT SIX] + case 0x278F: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX] + case 0xFF16: // [FULLWIDTH DIGIT SIX] + output[outputPos++] = L'6'; + break; + case 0x248D: // [DIGIT SIX FULL STOP] + output[outputPos++] = L'6'; + output[outputPos++] = L'.'; + break; + case 0x2479: // [PARENTHESIZED DIGIT SIX] + output[outputPos++] = L'('; + output[outputPos++] = L'6'; + output[outputPos++] = L')'; + break; + case 0x2077: // [SUPERSCRIPT SEVEN] + case 0x2087: // [SUBSCRIPT SEVEN] + case 0x2466: // [CIRCLED DIGIT SEVEN] + case 0x24FB: // [DOUBLE CIRCLED DIGIT SEVEN] + case 0x277C: // [DINGBAT NEGATIVE CIRCLED DIGIT SEVEN] + case 0x2786: // [DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN] + case 0x2790: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN] + case 0xFF17: // [FULLWIDTH DIGIT SEVEN] + output[outputPos++] = L'7'; + break; + case 0x248E: // [DIGIT SEVEN FULL STOP] + output[outputPos++] = L'7'; + output[outputPos++] = L'.'; + break; + case 0x247A: // [PARENTHESIZED DIGIT SEVEN] + output[outputPos++] = L'('; + output[outputPos++] = L'7'; + output[outputPos++] = L')'; + break; + case 0x2078: // [SUPERSCRIPT EIGHT] + case 0x2088: // [SUBSCRIPT EIGHT] + case 0x2467: // [CIRCLED DIGIT EIGHT] + case 0x24FC: // [DOUBLE CIRCLED DIGIT EIGHT] + case 0x277D: // [DINGBAT NEGATIVE CIRCLED DIGIT EIGHT] + case 0x2787: // [DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT] + case 0x2791: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT] + case 0xFF18: // [FULLWIDTH DIGIT EIGHT] + output[outputPos++] = L'8'; + break; + case 0x248F: // [DIGIT EIGHT FULL STOP] + output[outputPos++] = L'8'; + output[outputPos++] = L'.'; + break; + case 0x247B: // [PARENTHESIZED DIGIT EIGHT] + output[outputPos++] = L'('; + output[outputPos++] = L'8'; + output[outputPos++] = L')'; + break; + case 0x2079: // [SUPERSCRIPT NINE] + case 0x2089: // [SUBSCRIPT NINE] + case 0x2468: // [CIRCLED DIGIT NINE] + case 0x24FD: // [DOUBLE CIRCLED DIGIT NINE] + case 0x277E: // [DINGBAT NEGATIVE CIRCLED DIGIT NINE] + case 0x2788: // [DINGBAT CIRCLED SANS-SERIF DIGIT NINE] + case 0x2792: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE] + case 0xFF19: // [FULLWIDTH DIGIT NINE] + output[outputPos++] = L'9'; + break; + case 0x2490: // [DIGIT NINE FULL STOP] + output[outputPos++] = L'9'; + output[outputPos++] = L'.'; + break; + case 0x247C: // [PARENTHESIZED DIGIT NINE] + output[outputPos++] = L'('; + output[outputPos++] = L'9'; + output[outputPos++] = L')'; + break; + case 0x2469: // [CIRCLED NUMBER TEN] + case 0x24FE: // [DOUBLE CIRCLED NUMBER TEN] + case 0x277F: // [DINGBAT NEGATIVE CIRCLED NUMBER TEN] + case 0x2789: // [DINGBAT CIRCLED SANS-SERIF NUMBER TEN] + case 0x2793: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'0'; + break; + case 0x2491: // [NUMBER TEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'0'; + output[outputPos++] = L'.'; + break; + case 0x247D: // [PARENTHESIZED NUMBER TEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'0'; + output[outputPos++] = L')'; + break; + case 0x246A: // [CIRCLED NUMBER ELEVEN] + case 0x24EB: // [NEGATIVE CIRCLED NUMBER ELEVEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'1'; + break; + case 0x2492: // [NUMBER ELEVEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'1'; + output[outputPos++] = L'.'; + break; + case 0x247E: // [PARENTHESIZED NUMBER ELEVEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'1'; + output[outputPos++] = L')'; + break; + case 0x246B: // [CIRCLED NUMBER TWELVE] + case 0x24EC: // [NEGATIVE CIRCLED NUMBER TWELVE] + output[outputPos++] = L'1'; + output[outputPos++] = L'2'; + break; + case 0x2493: // [NUMBER TWELVE FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'2'; + output[outputPos++] = L'.'; + break; + case 0x247F: // [PARENTHESIZED NUMBER TWELVE] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'2'; + output[outputPos++] = L')'; + break; + case 0x246C: // [CIRCLED NUMBER THIRTEEN] + case 0x24ED: // [NEGATIVE CIRCLED NUMBER THIRTEEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'3'; + break; + case 0x2494: // [NUMBER THIRTEEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'3'; + output[outputPos++] = L'.'; + break; + case 0x2480: // [PARENTHESIZED NUMBER THIRTEEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'3'; + output[outputPos++] = L')'; + break; + case 0x246D: // [CIRCLED NUMBER FOURTEEN] + case 0x24EE: // [NEGATIVE CIRCLED NUMBER FOURTEEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'4'; + break; + case 0x2495: // [NUMBER FOURTEEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'4'; + output[outputPos++] = L'.'; + break; + case 0x2481: // [PARENTHESIZED NUMBER FOURTEEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'4'; + output[outputPos++] = L')'; + break; + case 0x246E: // [CIRCLED NUMBER FIFTEEN] + case 0x24EF: // [NEGATIVE CIRCLED NUMBER FIFTEEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'5'; + break; + case 0x2496: // [NUMBER FIFTEEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'5'; + output[outputPos++] = L'.'; + break; + case 0x2482: // [PARENTHESIZED NUMBER FIFTEEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'5'; + output[outputPos++] = L')'; + break; + case 0x246F: // [CIRCLED NUMBER SIXTEEN] + case 0x24F0: // [NEGATIVE CIRCLED NUMBER SIXTEEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'6'; + break; + case 0x2497: // [NUMBER SIXTEEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'6'; + output[outputPos++] = L'.'; + break; + case 0x2483: // [PARENTHESIZED NUMBER SIXTEEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'6'; + output[outputPos++] = L')'; + break; + case 0x2470: // [CIRCLED NUMBER SEVENTEEN] + case 0x24F1: // [NEGATIVE CIRCLED NUMBER SEVENTEEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'7'; + break; + case 0x2498: // [NUMBER SEVENTEEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'7'; + output[outputPos++] = L'.'; + break; + case 0x2484: // [PARENTHESIZED NUMBER SEVENTEEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'7'; + output[outputPos++] = L')'; + break; + case 0x2471: // [CIRCLED NUMBER EIGHTEEN] + case 0x24F2: // [NEGATIVE CIRCLED NUMBER EIGHTEEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'8'; + break; + case 0x2499: // [NUMBER EIGHTEEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'8'; + output[outputPos++] = L'.'; + break; + case 0x2485: // [PARENTHESIZED NUMBER EIGHTEEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'8'; + output[outputPos++] = L')'; + break; + case 0x2472: // [CIRCLED NUMBER NINETEEN] + case 0x24F3: // [NEGATIVE CIRCLED NUMBER NINETEEN] + output[outputPos++] = L'1'; + output[outputPos++] = L'9'; + break; + case 0x249A: // [NUMBER NINETEEN FULL STOP] + output[outputPos++] = L'1'; + output[outputPos++] = L'9'; + output[outputPos++] = L'.'; + break; + case 0x2486: // [PARENTHESIZED NUMBER NINETEEN] + output[outputPos++] = L'('; + output[outputPos++] = L'1'; + output[outputPos++] = L'9'; + output[outputPos++] = L')'; + break; + case 0x2473: // [CIRCLED NUMBER TWENTY] + case 0x24F4: // [NEGATIVE CIRCLED NUMBER TWENTY] + output[outputPos++] = L'2'; + output[outputPos++] = L'0'; + break; + case 0x249B: // [NUMBER TWENTY FULL STOP] + output[outputPos++] = L'2'; + output[outputPos++] = L'0'; + output[outputPos++] = L'.'; + break; + case 0x2487: // [PARENTHESIZED NUMBER TWENTY] + output[outputPos++] = L'('; + output[outputPos++] = L'2'; + output[outputPos++] = L'0'; + output[outputPos++] = L')'; + break; + case 0x00AB: // [LEFT-POINTING DOUBLE ANGLE QUOTATION MARK] + case 0x00BB: // [RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK] + case 0x201C: // [LEFT DOUBLE QUOTATION MARK] + case 0x201D: // [RIGHT DOUBLE QUOTATION MARK] + case 0x201E: // [DOUBLE LOW-9 QUOTATION MARK] + case 0x2033: // [DOUBLE PRIME] + case 0x2036: // [REVERSED DOUBLE PRIME] + case 0x275D: // [HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT] + case 0x275E: // [HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT] + case 0x276E: // [HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT] + case 0x276F: // [HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT] + case 0xFF02: // [FULLWIDTH QUOTATION MARK] + output[outputPos++] = L'"'; + break; + case 0x2018: // [LEFT SINGLE QUOTATION MARK] + case 0x2019: // [RIGHT SINGLE QUOTATION MARK] + case 0x201A: // [SINGLE LOW-9 QUOTATION MARK] + case 0x201B: // [SINGLE HIGH-REVERSED-9 QUOTATION MARK] + case 0x2032: // [PRIME] + case 0x2035: // [REVERSED PRIME] + case 0x2039: // [SINGLE LEFT-POINTING ANGLE QUOTATION MARK] + case 0x203A: // [SINGLE RIGHT-POINTING ANGLE QUOTATION MARK] + case 0x275B: // [HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT] + case 0x275C: // [HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT] + case 0xFF07: // [FULLWIDTH APOSTROPHE] + output[outputPos++] = L'\''; + break; + case 0x2010: // [HYPHEN] + case 0x2011: // [NON-BREAKING HYPHEN] + case 0x2012: // [FIGURE DASH] + case 0x2013: // [EN DASH] + case 0x2014: // [EM DASH] + case 0x207B: // [SUPERSCRIPT MINUS] + case 0x208B: // [SUBSCRIPT MINUS] + case 0xFF0D: // [FULLWIDTH HYPHEN-MINUS] + output[outputPos++] = L'-'; + break; + case 0x2045: // [LEFT SQUARE BRACKET WITH QUILL] + case 0x2772: // [LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT] + case 0xFF3B: // [FULLWIDTH LEFT SQUARE BRACKET] + output[outputPos++] = L'['; + break; + case 0x2046: // [RIGHT SQUARE BRACKET WITH QUILL] + case 0x2773: // [LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT] + case 0xFF3D: // [FULLWIDTH RIGHT SQUARE BRACKET] + output[outputPos++] = L']'; + break; + case 0x207D: // [SUPERSCRIPT LEFT PARENTHESIS] + case 0x208D: // [SUBSCRIPT LEFT PARENTHESIS] + case 0x2768: // [MEDIUM LEFT PARENTHESIS ORNAMENT] + case 0x276A: // [MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT] + case 0xFF08: // [FULLWIDTH LEFT PARENTHESIS] + output[outputPos++] = L'('; + break; + case 0x2E28: // [LEFT DOUBLE PARENTHESIS] + output[outputPos++] = L'('; + output[outputPos++] = L'('; + break; + case 0x207E: // [SUPERSCRIPT RIGHT PARENTHESIS] + case 0x208E: // [SUBSCRIPT RIGHT PARENTHESIS] + case 0x2769: // [MEDIUM RIGHT PARENTHESIS ORNAMENT] + case 0x276B: // [MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT] + case 0xFF09: // [FULLWIDTH RIGHT PARENTHESIS] + output[outputPos++] = L')'; + break; + case 0x2E29: // [RIGHT DOUBLE PARENTHESIS] + output[outputPos++] = L')'; + output[outputPos++] = L')'; + break; + case 0x276C: // [MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT] + case 0x2770: // [HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT] + case 0xFF1C: // [FULLWIDTH LESS-THAN SIGN] + output[outputPos++] = L'<'; + break; + case 0x276D: // [MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT] + case 0x2771: // [HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT] + case 0xFF1E: // [FULLWIDTH GREATER-THAN SIGN] + output[outputPos++] = L'>'; + break; + case 0x2774: // [MEDIUM LEFT CURLY BRACKET ORNAMENT] + case 0xFF5B: // [FULLWIDTH LEFT CURLY BRACKET] + output[outputPos++] = L'{'; + break; + case 0x2775: // [MEDIUM RIGHT CURLY BRACKET ORNAMENT] + case 0xFF5D: // [FULLWIDTH RIGHT CURLY BRACKET] + output[outputPos++] = L'}'; + break; + case 0x207A: // [SUPERSCRIPT PLUS SIGN] + case 0x208A: // [SUBSCRIPT PLUS SIGN] + case 0xFF0B: // [FULLWIDTH PLUS SIGN] + output[outputPos++] = L'+'; + break; + case 0x207C: // [SUPERSCRIPT EQUALS SIGN] + case 0x208C: // [SUBSCRIPT EQUALS SIGN] + case 0xFF1D: // [FULLWIDTH EQUALS SIGN] + output[outputPos++] = L'='; + break; + case 0xFF01: // [FULLWIDTH EXCLAMATION MARK] + output[outputPos++] = L'!'; + break; + case 0x203C: // [DOUBLE EXCLAMATION MARK] + output[outputPos++] = L'!'; + output[outputPos++] = L'!'; + break; + case 0x2049: // [EXCLAMATION QUESTION MARK] + output[outputPos++] = L'!'; + output[outputPos++] = L'?'; + break; + case 0xFF03: // [FULLWIDTH NUMBER SIGN] + output[outputPos++] = L'#'; + break; + case 0xFF04: // [FULLWIDTH DOLLAR SIGN] + output[outputPos++] = L'$'; + break; + case 0x2052: // [COMMERCIAL MINUS SIGN] + case 0xFF05: // [FULLWIDTH PERCENT SIGN] + output[outputPos++] = L'%'; + break; + case 0xFF06: // [FULLWIDTH AMPERSAND] + output[outputPos++] = L'&'; + break; + case 0x204E: // [LOW ASTERISK] + case 0xFF0A: // [FULLWIDTH ASTERISK] + output[outputPos++] = L'*'; + break; + case 0xFF0C: // [FULLWIDTH COMMA] + output[outputPos++] = L','; + break; + case 0xFF0E: // [FULLWIDTH FULL STOP] + output[outputPos++] = L'.'; + break; + case 0x2044: // [FRACTION SLASH] + case 0xFF0F: // [FULLWIDTH SOLIDUS] + output[outputPos++] = L'/'; + break; + case 0xFF1A: // [FULLWIDTH COLON] + output[outputPos++] = L':'; + break; + case 0x204F: // [REVERSED SEMICOLON] + case 0xFF1B: // [FULLWIDTH SEMICOLON] + output[outputPos++] = L';'; + break; + case 0xFF1F: // [FULLWIDTH QUESTION MARK] + output[outputPos++] = L'?'; + break; + case 0x2047: // [DOUBLE QUESTION MARK] + output[outputPos++] = L'?'; + output[outputPos++] = L'?'; + break; + case 0x2048: // [QUESTION EXCLAMATION MARK] + output[outputPos++] = L'?'; + output[outputPos++] = L'!'; + break; + case 0xFF20: // [FULLWIDTH COMMERCIAL AT] + output[outputPos++] = L'@'; + break; + case 0xFF3C: // [FULLWIDTH REVERSE SOLIDUS] + output[outputPos++] = L'\\'; + break; + case 0x2038: // [CARET] + case 0xFF3E: // [FULLWIDTH CIRCUMFLEX ACCENT] + output[outputPos++] = L'^'; + break; + case 0xFF3F: // [FULLWIDTH LOW LINE] + output[outputPos++] = L'_'; + break; + case 0x2053: // [SWUNG DASH] + case 0xFF5E: // [FULLWIDTH TILDE] + output[outputPos++] = L'~'; + break; + default: output[outputPos++] = c; - else - { - switch (c) - { - case 0x00C0: // [LATIN CAPITAL LETTER A WITH GRAVE] - case 0x00C1: // [LATIN CAPITAL LETTER A WITH ACUTE] - case 0x00C2: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX] - case 0x00C3: // [LATIN CAPITAL LETTER A WITH TILDE] - case 0x00C4: // [LATIN CAPITAL LETTER A WITH DIAERESIS] - case 0x00C5: // [LATIN CAPITAL LETTER A WITH RING ABOVE] - case 0x0100: // [LATIN CAPITAL LETTER A WITH MACRON] - case 0x0102: // [LATIN CAPITAL LETTER A WITH BREVE] - case 0x0104: // [LATIN CAPITAL LETTER A WITH OGONEK] - case 0x018F: // [LATIN CAPITAL LETTER SCHWA] - case 0x01CD: // [LATIN CAPITAL LETTER A WITH CARON] - case 0x01DE: // [LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON] - case 0x01E0: // [LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON] - case 0x01FA: // [LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE] - case 0x0200: // [LATIN CAPITAL LETTER A WITH DOUBLE GRAVE] - case 0x0202: // [LATIN CAPITAL LETTER A WITH INVERTED BREVE] - case 0x0226: // [LATIN CAPITAL LETTER A WITH DOT ABOVE] - case 0x023A: // [LATIN CAPITAL LETTER A WITH STROKE] - case 0x1D00: // [LATIN LETTER SMALL CAPITAL A] - case 0x1E00: // [LATIN CAPITAL LETTER A WITH RING BELOW] - case 0x1EA0: // [LATIN CAPITAL LETTER A WITH DOT BELOW] - case 0x1EA2: // [LATIN CAPITAL LETTER A WITH HOOK ABOVE] - case 0x1EA4: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE] - case 0x1EA6: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE] - case 0x1EA8: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE] - case 0x1EAA: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE] - case 0x1EAC: // [LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW] - case 0x1EAE: // [LATIN CAPITAL LETTER A WITH BREVE AND ACUTE] - case 0x1EB0: // [LATIN CAPITAL LETTER A WITH BREVE AND GRAVE] - case 0x1EB2: // [LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE] - case 0x1EB4: // [LATIN CAPITAL LETTER A WITH BREVE AND TILDE] - case 0x1EB6: // [LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW] - case 0x24B6: // [CIRCLED LATIN CAPITAL LETTER A] - case 0xFF21: // [FULLWIDTH LATIN CAPITAL LETTER A] - output[outputPos++] = L'A'; - break; - case 0x00E0: // [LATIN SMALL LETTER A WITH GRAVE] - case 0x00E1: // [LATIN SMALL LETTER A WITH ACUTE] - case 0x00E2: // [LATIN SMALL LETTER A WITH CIRCUMFLEX] - case 0x00E3: // [LATIN SMALL LETTER A WITH TILDE] - case 0x00E4: // [LATIN SMALL LETTER A WITH DIAERESIS] - case 0x00E5: // [LATIN SMALL LETTER A WITH RING ABOVE] - case 0x0101: // [LATIN SMALL LETTER A WITH MACRON] - case 0x0103: // [LATIN SMALL LETTER A WITH BREVE] - case 0x0105: // [LATIN SMALL LETTER A WITH OGONEK] - case 0x01CE: // [LATIN SMALL LETTER A WITH CARON] - case 0x01DF: // [LATIN SMALL LETTER A WITH DIAERESIS AND MACRON] - case 0x01E1: // [LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON] - case 0x01FB: // [LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE] - case 0x0201: // [LATIN SMALL LETTER A WITH DOUBLE GRAVE] - case 0x0203: // [LATIN SMALL LETTER A WITH INVERTED BREVE] - case 0x0227: // [LATIN SMALL LETTER A WITH DOT ABOVE] - case 0x0250: // [LATIN SMALL LETTER TURNED A] - case 0x0259: // [LATIN SMALL LETTER SCHWA] - case 0x025A: // [LATIN SMALL LETTER SCHWA WITH HOOK] - case 0x1D8F: // [LATIN SMALL LETTER A WITH RETROFLEX HOOK] - case 0x1D95: // [LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK] - case 0x1E01: // [LATIN SMALL LETTER A WITH RING BELOW] - case 0x1E9A: // [LATIN SMALL LETTER A WITH RIGHT HALF RING] - case 0x1EA1: // [LATIN SMALL LETTER A WITH DOT BELOW] - case 0x1EA3: // [LATIN SMALL LETTER A WITH HOOK ABOVE] - case 0x1EA5: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE] - case 0x1EA7: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE] - case 0x1EA9: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE] - case 0x1EAB: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE] - case 0x1EAD: // [LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW] - case 0x1EAF: // [LATIN SMALL LETTER A WITH BREVE AND ACUTE] - case 0x1EB1: // [LATIN SMALL LETTER A WITH BREVE AND GRAVE] - case 0x1EB3: // [LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE] - case 0x1EB5: // [LATIN SMALL LETTER A WITH BREVE AND TILDE] - case 0x1EB7: // [LATIN SMALL LETTER A WITH BREVE AND DOT BELOW] - case 0x2090: // [LATIN SUBSCRIPT SMALL LETTER A] - case 0x2094: // [LATIN SUBSCRIPT SMALL LETTER SCHWA] - case 0x24D0: // [CIRCLED LATIN SMALL LETTER A] - case 0x2C65: // [LATIN SMALL LETTER A WITH STROKE] - case 0x2C6F: // [LATIN CAPITAL LETTER TURNED A] - case 0xFF41: // [FULLWIDTH LATIN SMALL LETTER A] - output[outputPos++] = L'a'; - break; - case 0xA732: // [LATIN CAPITAL LETTER AA] - output[outputPos++] = L'A'; - output[outputPos++] = L'A'; - break; - case 0x00C6: // [LATIN CAPITAL LETTER AE] - case 0x01E2: // [LATIN CAPITAL LETTER AE WITH MACRON] - case 0x01FC: // [LATIN CAPITAL LETTER AE WITH ACUTE] - case 0x1D01: // [LATIN LETTER SMALL CAPITAL AE] - output[outputPos++] = L'A'; - output[outputPos++] = L'E'; - break; - case 0xA734: // [LATIN CAPITAL LETTER AO] - output[outputPos++] = L'A'; - output[outputPos++] = L'O'; - break; - case 0xA736: // [LATIN CAPITAL LETTER AU] - output[outputPos++] = L'A'; - output[outputPos++] = L'U'; - break; - case 0xA738: // [LATIN CAPITAL LETTER AV] - case 0xA73A: // [LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR] - output[outputPos++] = L'A'; - output[outputPos++] = L'V'; - break; - case 0xA73C: // [LATIN CAPITAL LETTER AY] - output[outputPos++] = L'A'; - output[outputPos++] = L'Y'; - break; - case 0x249C: // [PARENTHESIZED LATIN SMALL LETTER A] - output[outputPos++] = L'('; - output[outputPos++] = L'a'; - output[outputPos++] = L')'; - break; - case 0xA733: // [LATIN SMALL LETTER AA] - output[outputPos++] = L'a'; - output[outputPos++] = L'a'; - break; - case 0x00E6: // [LATIN SMALL LETTER AE] - case 0x01E3: // [LATIN SMALL LETTER AE WITH MACRON] - case 0x01FD: // [LATIN SMALL LETTER AE WITH ACUTE] - case 0x1D02: // [LATIN SMALL LETTER TURNED AE] - output[outputPos++] = L'a'; - output[outputPos++] = L'e'; - break; - case 0xA735: // [LATIN SMALL LETTER AO] - output[outputPos++] = L'a'; - output[outputPos++] = L'o'; - break; - case 0xA737: // [LATIN SMALL LETTER AU] - output[outputPos++] = L'a'; - output[outputPos++] = L'u'; - break; - case 0xA739: // [LATIN SMALL LETTER AV] - case 0xA73B: // [LATIN SMALL LETTER AV WITH HORIZONTAL BAR] - output[outputPos++] = L'a'; - output[outputPos++] = L'v'; - break; - case 0xA73D: // [LATIN SMALL LETTER AY] - output[outputPos++] = L'a'; - output[outputPos++] = L'y'; - break; - case 0x0181: // [LATIN CAPITAL LETTER B WITH HOOK] - case 0x0182: // [LATIN CAPITAL LETTER B WITH TOPBAR] - case 0x0243: // [LATIN CAPITAL LETTER B WITH STROKE] - case 0x0299: // [LATIN LETTER SMALL CAPITAL B] - case 0x1D03: // [LATIN LETTER SMALL CAPITAL BARRED B] - case 0x1E02: // [LATIN CAPITAL LETTER B WITH DOT ABOVE] - case 0x1E04: // [LATIN CAPITAL LETTER B WITH DOT BELOW] - case 0x1E06: // [LATIN CAPITAL LETTER B WITH LINE BELOW] - case 0x24B7: // [CIRCLED LATIN CAPITAL LETTER B] - case 0xFF22: // [FULLWIDTH LATIN CAPITAL LETTER B] - output[outputPos++] = L'B'; - break; - case 0x0180: // [LATIN SMALL LETTER B WITH STROKE] - case 0x0183: // [LATIN SMALL LETTER B WITH TOPBAR] - case 0x0253: // [LATIN SMALL LETTER B WITH HOOK] - case 0x1D6C: // [LATIN SMALL LETTER B WITH MIDDLE TILDE] - case 0x1D80: // [LATIN SMALL LETTER B WITH PALATAL HOOK] - case 0x1E03: // [LATIN SMALL LETTER B WITH DOT ABOVE] - case 0x1E05: // [LATIN SMALL LETTER B WITH DOT BELOW] - case 0x1E07: // [LATIN SMALL LETTER B WITH LINE BELOW] - case 0x24D1: // [CIRCLED LATIN SMALL LETTER B] - case 0xFF42: // [FULLWIDTH LATIN SMALL LETTER B] - output[outputPos++] = L'b'; - break; - case 0x249D: // [PARENTHESIZED LATIN SMALL LETTER B] - output[outputPos++] = L'('; - output[outputPos++] = L'b'; - output[outputPos++] = L')'; - break; - case 0x00C7: // [LATIN CAPITAL LETTER C WITH CEDILLA] - case 0x0106: // [LATIN CAPITAL LETTER C WITH ACUTE] - case 0x0108: // [LATIN CAPITAL LETTER C WITH CIRCUMFLEX] - case 0x010A: // [LATIN CAPITAL LETTER C WITH DOT ABOVE] - case 0x010C: // [LATIN CAPITAL LETTER C WITH CARON] - case 0x0187: // [LATIN CAPITAL LETTER C WITH HOOK] - case 0x023B: // [LATIN CAPITAL LETTER C WITH STROKE] - case 0x0297: // [LATIN LETTER STRETCHED C] - case 0x1D04: // [LATIN LETTER SMALL CAPITAL C] - case 0x1E08: // [LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE] - case 0x24B8: // [CIRCLED LATIN CAPITAL LETTER C] - case 0xFF23: // [FULLWIDTH LATIN CAPITAL LETTER C] - output[outputPos++] = L'C'; - break; - case 0x00E7: // [LATIN SMALL LETTER C WITH CEDILLA] - case 0x0107: // [LATIN SMALL LETTER C WITH ACUTE] - case 0x0109: // [LATIN SMALL LETTER C WITH CIRCUMFLEX] - case 0x010B: // [LATIN SMALL LETTER C WITH DOT ABOVE] - case 0x010D: // [LATIN SMALL LETTER C WITH CARON] - case 0x0188: // [LATIN SMALL LETTER C WITH HOOK] - case 0x023C: // [LATIN SMALL LETTER C WITH STROKE] - case 0x0255: // [LATIN SMALL LETTER C WITH CURL] - case 0x1E09: // [LATIN SMALL LETTER C WITH CEDILLA AND ACUTE] - case 0x2184: // [LATIN SMALL LETTER REVERSED C] - case 0x24D2: // [CIRCLED LATIN SMALL LETTER C] - case 0xA73E: // [LATIN CAPITAL LETTER REVERSED C WITH DOT] - case 0xA73F: // [LATIN SMALL LETTER REVERSED C WITH DOT] - case 0xFF43: // [FULLWIDTH LATIN SMALL LETTER C] - output[outputPos++] = L'c'; - break; - case 0x249E: // [PARENTHESIZED LATIN SMALL LETTER C] - output[outputPos++] = L'('; - output[outputPos++] = L'c'; - output[outputPos++] = L')'; - break; - case 0x00D0: // [LATIN CAPITAL LETTER ETH] - case 0x010E: // [LATIN CAPITAL LETTER D WITH CARON] - case 0x0110: // [LATIN CAPITAL LETTER D WITH STROKE] - case 0x0189: // [LATIN CAPITAL LETTER AFRICAN D] - case 0x018A: // [LATIN CAPITAL LETTER D WITH HOOK] - case 0x018B: // [LATIN CAPITAL LETTER D WITH TOPBAR] - case 0x1D05: // [LATIN LETTER SMALL CAPITAL D] - case 0x1D06: // [LATIN LETTER SMALL CAPITAL ETH] - case 0x1E0A: // [LATIN CAPITAL LETTER D WITH DOT ABOVE] - case 0x1E0C: // [LATIN CAPITAL LETTER D WITH DOT BELOW] - case 0x1E0E: // [LATIN CAPITAL LETTER D WITH LINE BELOW] - case 0x1E10: // [LATIN CAPITAL LETTER D WITH CEDILLA] - case 0x1E12: // [LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW] - case 0x24B9: // [CIRCLED LATIN CAPITAL LETTER D] - case 0xA779: // [LATIN CAPITAL LETTER INSULAR D] - case 0xFF24: // [FULLWIDTH LATIN CAPITAL LETTER D] - output[outputPos++] = L'D'; - break; - case 0x00F0: // [LATIN SMALL LETTER ETH] - case 0x010F: // [LATIN SMALL LETTER D WITH CARON] - case 0x0111: // [LATIN SMALL LETTER D WITH STROKE] - case 0x018C: // [LATIN SMALL LETTER D WITH TOPBAR] - case 0x0221: // [LATIN SMALL LETTER D WITH CURL] - case 0x0256: // [LATIN SMALL LETTER D WITH TAIL] - case 0x0257: // [LATIN SMALL LETTER D WITH HOOK] - case 0x1D6D: // [LATIN SMALL LETTER D WITH MIDDLE TILDE] - case 0x1D81: // [LATIN SMALL LETTER D WITH PALATAL HOOK] - case 0x1D91: // [LATIN SMALL LETTER D WITH HOOK AND TAIL] - case 0x1E0B: // [LATIN SMALL LETTER D WITH DOT ABOVE] - case 0x1E0D: // [LATIN SMALL LETTER D WITH DOT BELOW] - case 0x1E0F: // [LATIN SMALL LETTER D WITH LINE BELOW] - case 0x1E11: // [LATIN SMALL LETTER D WITH CEDILLA] - case 0x1E13: // [LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW] - case 0x24D3: // [CIRCLED LATIN SMALL LETTER D] - case 0xA77A: // [LATIN SMALL LETTER INSULAR D] - case 0xFF44: // [FULLWIDTH LATIN SMALL LETTER D] - output[outputPos++] = L'd'; - break; - case 0x01C4: // [LATIN CAPITAL LETTER DZ WITH CARON] - case 0x01F1: // [LATIN CAPITAL LETTER DZ] - output[outputPos++] = L'D'; - output[outputPos++] = L'Z'; - break; - case 0x01C5: // [LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON] - case 0x01F2: // [LATIN CAPITAL LETTER D WITH SMALL LETTER Z] - output[outputPos++] = L'D'; - output[outputPos++] = L'z'; - break; - case 0x249F: // [PARENTHESIZED LATIN SMALL LETTER D] - output[outputPos++] = L'('; - output[outputPos++] = L'd'; - output[outputPos++] = L')'; - break; - case 0x0238: // [LATIN SMALL LETTER DB DIGRAPH] - output[outputPos++] = L'd'; - output[outputPos++] = L'b'; - break; - case 0x01C6: // [LATIN SMALL LETTER DZ WITH CARON] - case 0x01F3: // [LATIN SMALL LETTER DZ] - case 0x02A3: // [LATIN SMALL LETTER DZ DIGRAPH] - case 0x02A5: // [LATIN SMALL LETTER DZ DIGRAPH WITH CURL] - output[outputPos++] = L'd'; - output[outputPos++] = L'z'; - break; - case 0x00C8: // [LATIN CAPITAL LETTER E WITH GRAVE] - case 0x00C9: // [LATIN CAPITAL LETTER E WITH ACUTE] - case 0x00CA: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX] - case 0x00CB: // [LATIN CAPITAL LETTER E WITH DIAERESIS] - case 0x0112: // [LATIN CAPITAL LETTER E WITH MACRON] - case 0x0114: // [LATIN CAPITAL LETTER E WITH BREVE] - case 0x0116: // [LATIN CAPITAL LETTER E WITH DOT ABOVE] - case 0x0118: // [LATIN CAPITAL LETTER E WITH OGONEK] - case 0x011A: // [LATIN CAPITAL LETTER E WITH CARON] - case 0x018E: // [LATIN CAPITAL LETTER REVERSED E] - case 0x0190: // [LATIN CAPITAL LETTER OPEN E] - case 0x0204: // [LATIN CAPITAL LETTER E WITH DOUBLE GRAVE] - case 0x0206: // [LATIN CAPITAL LETTER E WITH INVERTED BREVE] - case 0x0228: // [LATIN CAPITAL LETTER E WITH CEDILLA] - case 0x0246: // [LATIN CAPITAL LETTER E WITH STROKE] - case 0x1D07: // [LATIN LETTER SMALL CAPITAL E] - case 0x1E14: // [LATIN CAPITAL LETTER E WITH MACRON AND GRAVE] - case 0x1E16: // [LATIN CAPITAL LETTER E WITH MACRON AND ACUTE] - case 0x1E18: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW] - case 0x1E1A: // [LATIN CAPITAL LETTER E WITH TILDE BELOW] - case 0x1E1C: // [LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE] - case 0x1EB8: // [LATIN CAPITAL LETTER E WITH DOT BELOW] - case 0x1EBA: // [LATIN CAPITAL LETTER E WITH HOOK ABOVE] - case 0x1EBC: // [LATIN CAPITAL LETTER E WITH TILDE] - case 0x1EBE: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE] - case 0x1EC0: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE] - case 0x1EC2: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE] - case 0x1EC4: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE] - case 0x1EC6: // [LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW] - case 0x24BA: // [CIRCLED LATIN CAPITAL LETTER E] - case 0x2C7B: // [LATIN LETTER SMALL CAPITAL TURNED E] - case 0xFF25: // [FULLWIDTH LATIN CAPITAL LETTER E] - output[outputPos++] = L'E'; - break; - case 0x00E8: // [LATIN SMALL LETTER E WITH GRAVE] - case 0x00E9: // [LATIN SMALL LETTER E WITH ACUTE] - case 0x00EA: // [LATIN SMALL LETTER E WITH CIRCUMFLEX] - case 0x00EB: // [LATIN SMALL LETTER E WITH DIAERESIS] - case 0x0113: // [LATIN SMALL LETTER E WITH MACRON] - case 0x0115: // [LATIN SMALL LETTER E WITH BREVE] - case 0x0117: // [LATIN SMALL LETTER E WITH DOT ABOVE] - case 0x0119: // [LATIN SMALL LETTER E WITH OGONEK] - case 0x011B: // [LATIN SMALL LETTER E WITH CARON] - case 0x01DD: // [LATIN SMALL LETTER TURNED E] - case 0x0205: // [LATIN SMALL LETTER E WITH DOUBLE GRAVE] - case 0x0207: // [LATIN SMALL LETTER E WITH INVERTED BREVE] - case 0x0229: // [LATIN SMALL LETTER E WITH CEDILLA] - case 0x0247: // [LATIN SMALL LETTER E WITH STROKE] - case 0x0258: // [LATIN SMALL LETTER REVERSED E] - case 0x025B: // [LATIN SMALL LETTER OPEN E] - case 0x025C: // [LATIN SMALL LETTER REVERSED OPEN E] - case 0x025D: // [LATIN SMALL LETTER REVERSED OPEN E WITH HOOK] - case 0x025E: // [LATIN SMALL LETTER CLOSED REVERSED OPEN E] - case 0x029A: // [LATIN SMALL LETTER CLOSED OPEN E] - case 0x1D08: // [LATIN SMALL LETTER TURNED OPEN E] - case 0x1D92: // [LATIN SMALL LETTER E WITH RETROFLEX HOOK] - case 0x1D93: // [LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK] - case 0x1D94: // [LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK] - case 0x1E15: // [LATIN SMALL LETTER E WITH MACRON AND GRAVE] - case 0x1E17: // [LATIN SMALL LETTER E WITH MACRON AND ACUTE] - case 0x1E19: // [LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW] - case 0x1E1B: // [LATIN SMALL LETTER E WITH TILDE BELOW] - case 0x1E1D: // [LATIN SMALL LETTER E WITH CEDILLA AND BREVE] - case 0x1EB9: // [LATIN SMALL LETTER E WITH DOT BELOW] - case 0x1EBB: // [LATIN SMALL LETTER E WITH HOOK ABOVE] - case 0x1EBD: // [LATIN SMALL LETTER E WITH TILDE] - case 0x1EBF: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE] - case 0x1EC1: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE] - case 0x1EC3: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE] - case 0x1EC5: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE] - case 0x1EC7: // [LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW] - case 0x2091: // [LATIN SUBSCRIPT SMALL LETTER E] - case 0x24D4: // [CIRCLED LATIN SMALL LETTER E] - case 0x2C78: // [LATIN SMALL LETTER E WITH NOTCH] - case 0xFF45: // [FULLWIDTH LATIN SMALL LETTER E] - output[outputPos++] = L'e'; - break; - case 0x24A0: // [PARENTHESIZED LATIN SMALL LETTER E] - output[outputPos++] = L'('; - output[outputPos++] = L'e'; - output[outputPos++] = L')'; - break; - case 0x0191: // [LATIN CAPITAL LETTER F WITH HOOK] - case 0x1E1E: // [LATIN CAPITAL LETTER F WITH DOT ABOVE] - case 0x24BB: // [CIRCLED LATIN CAPITAL LETTER F] - case 0xA730: // [LATIN LETTER SMALL CAPITAL F] - case 0xA77B: // [LATIN CAPITAL LETTER INSULAR F] - case 0xA7FB: // [LATIN EPIGRAPHIC LETTER REVERSED F] - case 0xFF26: // [FULLWIDTH LATIN CAPITAL LETTER F] - output[outputPos++] = L'F'; - break; - case 0x0192: // [LATIN SMALL LETTER F WITH HOOK] - case 0x1D6E: // [LATIN SMALL LETTER F WITH MIDDLE TILDE] - case 0x1D82: // [LATIN SMALL LETTER F WITH PALATAL HOOK] - case 0x1E1F: // [LATIN SMALL LETTER F WITH DOT ABOVE] - case 0x1E9B: // [LATIN SMALL LETTER LONG S WITH DOT ABOVE] - case 0x24D5: // [CIRCLED LATIN SMALL LETTER F] - case 0xA77C: // [LATIN SMALL LETTER INSULAR F] - case 0xFF46: // [FULLWIDTH LATIN SMALL LETTER F] - output[outputPos++] = L'f'; - break; - case 0x24A1: // [PARENTHESIZED LATIN SMALL LETTER F] - output[outputPos++] = L'('; - output[outputPos++] = L'f'; - output[outputPos++] = L')'; - break; - case 0xFB00: // [LATIN SMALL LIGATURE FF] - output[outputPos++] = L'f'; - output[outputPos++] = L'f'; - break; - case 0xFB03: // [LATIN SMALL LIGATURE FFI] - output[outputPos++] = L'f'; - output[outputPos++] = L'f'; - output[outputPos++] = L'i'; - break; - case 0xFB04: // [LATIN SMALL LIGATURE FFL] - output[outputPos++] = L'f'; - output[outputPos++] = L'f'; - output[outputPos++] = L'l'; - break; - case 0xFB01: // [LATIN SMALL LIGATURE FI] - output[outputPos++] = L'f'; - output[outputPos++] = L'i'; - break; - case 0xFB02: // [LATIN SMALL LIGATURE FL] - output[outputPos++] = L'f'; - output[outputPos++] = L'l'; - break; - case 0x011C: // [LATIN CAPITAL LETTER G WITH CIRCUMFLEX] - case 0x011E: // [LATIN CAPITAL LETTER G WITH BREVE] - case 0x0120: // [LATIN CAPITAL LETTER G WITH DOT ABOVE] - case 0x0122: // [LATIN CAPITAL LETTER G WITH CEDILLA] - case 0x0193: // [LATIN CAPITAL LETTER G WITH HOOK] - case 0x01E4: // [LATIN CAPITAL LETTER G WITH STROKE] - case 0x01E5: // [LATIN SMALL LETTER G WITH STROKE] - case 0x01E6: // [LATIN CAPITAL LETTER G WITH CARON] - case 0x01E7: // [LATIN SMALL LETTER G WITH CARON] - case 0x01F4: // [LATIN CAPITAL LETTER G WITH ACUTE] - case 0x0262: // [LATIN LETTER SMALL CAPITAL G] - case 0x029B: // [LATIN LETTER SMALL CAPITAL G WITH HOOK] - case 0x1E20: // [LATIN CAPITAL LETTER G WITH MACRON] - case 0x24BC: // [CIRCLED LATIN CAPITAL LETTER G] - case 0xA77D: // [LATIN CAPITAL LETTER INSULAR G] - case 0xA77E: // [LATIN CAPITAL LETTER TURNED INSULAR G] - case 0xFF27: // [FULLWIDTH LATIN CAPITAL LETTER G] - output[outputPos++] = L'G'; - break; - case 0x011D: // [LATIN SMALL LETTER G WITH CIRCUMFLEX] - case 0x011F: // [LATIN SMALL LETTER G WITH BREVE] - case 0x0121: // [LATIN SMALL LETTER G WITH DOT ABOVE] - case 0x0123: // [LATIN SMALL LETTER G WITH CEDILLA] - case 0x01F5: // [LATIN SMALL LETTER G WITH ACUTE] - case 0x0260: // [LATIN SMALL LETTER G WITH HOOK] - case 0x0261: // [LATIN SMALL LETTER SCRIPT G] - case 0x1D77: // [LATIN SMALL LETTER TURNED G] - case 0x1D79: // [LATIN SMALL LETTER INSULAR G] - case 0x1D83: // [LATIN SMALL LETTER G WITH PALATAL HOOK] - case 0x1E21: // [LATIN SMALL LETTER G WITH MACRON] - case 0x24D6: // [CIRCLED LATIN SMALL LETTER G] - case 0xA77F: // [LATIN SMALL LETTER TURNED INSULAR G] - case 0xFF47: // [FULLWIDTH LATIN SMALL LETTER G] - output[outputPos++] = L'g'; - break; - case 0x24A2: // [PARENTHESIZED LATIN SMALL LETTER G] - output[outputPos++] = L'('; - output[outputPos++] = L'g'; - output[outputPos++] = L')'; - break; - case 0x0124: // [LATIN CAPITAL LETTER H WITH CIRCUMFLEX] - case 0x0126: // [LATIN CAPITAL LETTER H WITH STROKE] - case 0x021E: // [LATIN CAPITAL LETTER H WITH CARON] - case 0x029C: // [LATIN LETTER SMALL CAPITAL H] - case 0x1E22: // [LATIN CAPITAL LETTER H WITH DOT ABOVE] - case 0x1E24: // [LATIN CAPITAL LETTER H WITH DOT BELOW] - case 0x1E26: // [LATIN CAPITAL LETTER H WITH DIAERESIS] - case 0x1E28: // [LATIN CAPITAL LETTER H WITH CEDILLA] - case 0x1E2A: // [LATIN CAPITAL LETTER H WITH BREVE BELOW] - case 0x24BD: // [CIRCLED LATIN CAPITAL LETTER H] - case 0x2C67: // [LATIN CAPITAL LETTER H WITH DESCENDER] - case 0x2C75: // [LATIN CAPITAL LETTER HALF H] - case 0xFF28: // [FULLWIDTH LATIN CAPITAL LETTER H] - output[outputPos++] = L'H'; - break; - case 0x0125: // [LATIN SMALL LETTER H WITH CIRCUMFLEX] - case 0x0127: // [LATIN SMALL LETTER H WITH STROKE] - case 0x021F: // [LATIN SMALL LETTER H WITH CARON] - case 0x0265: // [LATIN SMALL LETTER TURNED H] - case 0x0266: // [LATIN SMALL LETTER H WITH HOOK] - case 0x02AE: // [LATIN SMALL LETTER TURNED H WITH FISHHOOK] - case 0x02AF: // [LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL] - case 0x1E23: // [LATIN SMALL LETTER H WITH DOT ABOVE] - case 0x1E25: // [LATIN SMALL LETTER H WITH DOT BELOW] - case 0x1E27: // [LATIN SMALL LETTER H WITH DIAERESIS] - case 0x1E29: // [LATIN SMALL LETTER H WITH CEDILLA] - case 0x1E2B: // [LATIN SMALL LETTER H WITH BREVE BELOW] - case 0x1E96: // [LATIN SMALL LETTER H WITH LINE BELOW] - case 0x24D7: // [CIRCLED LATIN SMALL LETTER H] - case 0x2C68: // [LATIN SMALL LETTER H WITH DESCENDER] - case 0x2C76: // [LATIN SMALL LETTER HALF H] - case 0xFF48: // [FULLWIDTH LATIN SMALL LETTER H] - output[outputPos++] = L'h'; - break; - case 0x01F6: // [LATIN CAPITAL LETTER HWAIR] - output[outputPos++] = L'H'; - output[outputPos++] = L'V'; - break; - case 0x24A3: // [PARENTHESIZED LATIN SMALL LETTER H] - output[outputPos++] = L'('; - output[outputPos++] = L'h'; - output[outputPos++] = L')'; - break; - case 0x0195: // [LATIN SMALL LETTER HV] - output[outputPos++] = L'h'; - output[outputPos++] = L'v'; - break; - case 0x00CC: // [LATIN CAPITAL LETTER I WITH GRAVE] - case 0x00CD: // [LATIN CAPITAL LETTER I WITH ACUTE] - case 0x00CE: // [LATIN CAPITAL LETTER I WITH CIRCUMFLEX] - case 0x00CF: // [LATIN CAPITAL LETTER I WITH DIAERESIS] - case 0x0128: // [LATIN CAPITAL LETTER I WITH TILDE] - case 0x012A: // [LATIN CAPITAL LETTER I WITH MACRON] - case 0x012C: // [LATIN CAPITAL LETTER I WITH BREVE] - case 0x012E: // [LATIN CAPITAL LETTER I WITH OGONEK] - case 0x0130: // [LATIN CAPITAL LETTER I WITH DOT ABOVE] - case 0x0196: // [LATIN CAPITAL LETTER IOTA] - case 0x0197: // [LATIN CAPITAL LETTER I WITH STROKE] - case 0x01CF: // [LATIN CAPITAL LETTER I WITH CARON] - case 0x0208: // [LATIN CAPITAL LETTER I WITH DOUBLE GRAVE] - case 0x020A: // [LATIN CAPITAL LETTER I WITH INVERTED BREVE] - case 0x026A: // [LATIN LETTER SMALL CAPITAL I] - case 0x1D7B: // [LATIN SMALL CAPITAL LETTER I WITH STROKE] - case 0x1E2C: // [LATIN CAPITAL LETTER I WITH TILDE BELOW] - case 0x1E2E: // [LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE] - case 0x1EC8: // [LATIN CAPITAL LETTER I WITH HOOK ABOVE] - case 0x1ECA: // [LATIN CAPITAL LETTER I WITH DOT BELOW] - case 0x24BE: // [CIRCLED LATIN CAPITAL LETTER I] - case 0xA7FE: // [LATIN EPIGRAPHIC LETTER I LONGA] - case 0xFF29: // [FULLWIDTH LATIN CAPITAL LETTER I] - output[outputPos++] = L'I'; - break; - case 0x00EC: // [LATIN SMALL LETTER I WITH GRAVE] - case 0x00ED: // [LATIN SMALL LETTER I WITH ACUTE] - case 0x00EE: // [LATIN SMALL LETTER I WITH CIRCUMFLEX] - case 0x00EF: // [LATIN SMALL LETTER I WITH DIAERESIS] - case 0x0129: // [LATIN SMALL LETTER I WITH TILDE] - case 0x012B: // [LATIN SMALL LETTER I WITH MACRON] - case 0x012D: // [LATIN SMALL LETTER I WITH BREVE] - case 0x012F: // [LATIN SMALL LETTER I WITH OGONEK] - case 0x0131: // [LATIN SMALL LETTER DOTLESS I] - case 0x01D0: // [LATIN SMALL LETTER I WITH CARON] - case 0x0209: // [LATIN SMALL LETTER I WITH DOUBLE GRAVE] - case 0x020B: // [LATIN SMALL LETTER I WITH INVERTED BREVE] - case 0x0268: // [LATIN SMALL LETTER I WITH STROKE] - case 0x1D09: // [LATIN SMALL LETTER TURNED I] - case 0x1D62: // [LATIN SUBSCRIPT SMALL LETTER I] - case 0x1D7C: // [LATIN SMALL LETTER IOTA WITH STROKE] - case 0x1D96: // [LATIN SMALL LETTER I WITH RETROFLEX HOOK] - case 0x1E2D: // [LATIN SMALL LETTER I WITH TILDE BELOW] - case 0x1E2F: // [LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE] - case 0x1EC9: // [LATIN SMALL LETTER I WITH HOOK ABOVE] - case 0x1ECB: // [LATIN SMALL LETTER I WITH DOT BELOW] - case 0x2071: // [SUPERSCRIPT LATIN SMALL LETTER I] - case 0x24D8: // [CIRCLED LATIN SMALL LETTER I] - case 0xFF49: // [FULLWIDTH LATIN SMALL LETTER I] - output[outputPos++] = L'i'; - break; - case 0x0132: // [LATIN CAPITAL LIGATURE IJ] - output[outputPos++] = L'I'; - output[outputPos++] = L'J'; - break; - case 0x24A4: // [PARENTHESIZED LATIN SMALL LETTER I] - output[outputPos++] = L'('; - output[outputPos++] = L'i'; - output[outputPos++] = L')'; - break; - case 0x0133: // [LATIN SMALL LIGATURE IJ] - output[outputPos++] = L'i'; - output[outputPos++] = L'j'; - break; - case 0x0134: // [LATIN CAPITAL LETTER J WITH CIRCUMFLEX] - case 0x0248: // [LATIN CAPITAL LETTER J WITH STROKE] - case 0x1D0A: // [LATIN LETTER SMALL CAPITAL J] - case 0x24BF: // [CIRCLED LATIN CAPITAL LETTER J] - case 0xFF2A: // [FULLWIDTH LATIN CAPITAL LETTER J] - output[outputPos++] = L'J'; - break; - case 0x0135: // [LATIN SMALL LETTER J WITH CIRCUMFLEX] - case 0x01F0: // [LATIN SMALL LETTER J WITH CARON] - case 0x0237: // [LATIN SMALL LETTER DOTLESS J] - case 0x0249: // [LATIN SMALL LETTER J WITH STROKE] - case 0x025F: // [LATIN SMALL LETTER DOTLESS J WITH STROKE] - case 0x0284: // [LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK] - case 0x029D: // [LATIN SMALL LETTER J WITH CROSSED-TAIL] - case 0x24D9: // [CIRCLED LATIN SMALL LETTER J] - case 0x2C7C: // [LATIN SUBSCRIPT SMALL LETTER J] - case 0xFF4A: // [FULLWIDTH LATIN SMALL LETTER J] - output[outputPos++] = L'j'; - break; - case 0x24A5: // [PARENTHESIZED LATIN SMALL LETTER J] - output[outputPos++] = L'('; - output[outputPos++] = L'j'; - output[outputPos++] = L')'; - break; - case 0x0136: // [LATIN CAPITAL LETTER K WITH CEDILLA] - case 0x0198: // [LATIN CAPITAL LETTER K WITH HOOK] - case 0x01E8: // [LATIN CAPITAL LETTER K WITH CARON] - case 0x1D0B: // [LATIN LETTER SMALL CAPITAL K] - case 0x1E30: // [LATIN CAPITAL LETTER K WITH ACUTE] - case 0x1E32: // [LATIN CAPITAL LETTER K WITH DOT BELOW] - case 0x1E34: // [LATIN CAPITAL LETTER K WITH LINE BELOW] - case 0x24C0: // [CIRCLED LATIN CAPITAL LETTER K] - case 0x2C69: // [LATIN CAPITAL LETTER K WITH DESCENDER] - case 0xA740: // [LATIN CAPITAL LETTER K WITH STROKE] - case 0xA742: // [LATIN CAPITAL LETTER K WITH DIAGONAL STROKE] - case 0xA744: // [LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE] - case 0xFF2B: // [FULLWIDTH LATIN CAPITAL LETTER K] - output[outputPos++] = L'K'; - break; - case 0x0137: // [LATIN SMALL LETTER K WITH CEDILLA] - case 0x0199: // [LATIN SMALL LETTER K WITH HOOK] - case 0x01E9: // [LATIN SMALL LETTER K WITH CARON] - case 0x029E: // [LATIN SMALL LETTER TURNED K] - case 0x1D84: // [LATIN SMALL LETTER K WITH PALATAL HOOK] - case 0x1E31: // [LATIN SMALL LETTER K WITH ACUTE] - case 0x1E33: // [LATIN SMALL LETTER K WITH DOT BELOW] - case 0x1E35: // [LATIN SMALL LETTER K WITH LINE BELOW] - case 0x24DA: // [CIRCLED LATIN SMALL LETTER K] - case 0x2C6A: // [LATIN SMALL LETTER K WITH DESCENDER] - case 0xA741: // [LATIN SMALL LETTER K WITH STROKE] - case 0xA743: // [LATIN SMALL LETTER K WITH DIAGONAL STROKE] - case 0xA745: // [LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE] - case 0xFF4B: // [FULLWIDTH LATIN SMALL LETTER K] - output[outputPos++] = L'k'; - break; - case 0x24A6: // [PARENTHESIZED LATIN SMALL LETTER K] - output[outputPos++] = L'('; - output[outputPos++] = L'k'; - output[outputPos++] = L')'; - break; - case 0x0139: // [LATIN CAPITAL LETTER L WITH ACUTE] - case 0x013B: // [LATIN CAPITAL LETTER L WITH CEDILLA] - case 0x013D: // [LATIN CAPITAL LETTER L WITH CARON] - case 0x013F: // [LATIN CAPITAL LETTER L WITH MIDDLE DOT] - case 0x0141: // [LATIN CAPITAL LETTER L WITH STROKE] - case 0x023D: // [LATIN CAPITAL LETTER L WITH BAR] - case 0x029F: // [LATIN LETTER SMALL CAPITAL L] - case 0x1D0C: // [LATIN LETTER SMALL CAPITAL L WITH STROKE] - case 0x1E36: // [LATIN CAPITAL LETTER L WITH DOT BELOW] - case 0x1E38: // [LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON] - case 0x1E3A: // [LATIN CAPITAL LETTER L WITH LINE BELOW] - case 0x1E3C: // [LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW] - case 0x24C1: // [CIRCLED LATIN CAPITAL LETTER L] - case 0x2C60: // [LATIN CAPITAL LETTER L WITH DOUBLE BAR] - case 0x2C62: // [LATIN CAPITAL LETTER L WITH MIDDLE TILDE] - case 0xA746: // [LATIN CAPITAL LETTER BROKEN L] - case 0xA748: // [LATIN CAPITAL LETTER L WITH HIGH STROKE] - case 0xA780: // [LATIN CAPITAL LETTER TURNED L] - case 0xFF2C: // [FULLWIDTH LATIN CAPITAL LETTER L] - output[outputPos++] = L'L'; - break; - case 0x013A: // [LATIN SMALL LETTER L WITH ACUTE] - case 0x013C: // [LATIN SMALL LETTER L WITH CEDILLA] - case 0x013E: // [LATIN SMALL LETTER L WITH CARON] - case 0x0140: // [LATIN SMALL LETTER L WITH MIDDLE DOT] - case 0x0142: // [LATIN SMALL LETTER L WITH STROKE] - case 0x019A: // [LATIN SMALL LETTER L WITH BAR] - case 0x0234: // [LATIN SMALL LETTER L WITH CURL] - case 0x026B: // [LATIN SMALL LETTER L WITH MIDDLE TILDE] - case 0x026C: // [LATIN SMALL LETTER L WITH BELT] - case 0x026D: // [LATIN SMALL LETTER L WITH RETROFLEX HOOK] - case 0x1D85: // [LATIN SMALL LETTER L WITH PALATAL HOOK] - case 0x1E37: // [LATIN SMALL LETTER L WITH DOT BELOW] - case 0x1E39: // [LATIN SMALL LETTER L WITH DOT BELOW AND MACRON] - case 0x1E3B: // [LATIN SMALL LETTER L WITH LINE BELOW] - case 0x1E3D: // [LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW] - case 0x24DB: // [CIRCLED LATIN SMALL LETTER L] - case 0x2C61: // [LATIN SMALL LETTER L WITH DOUBLE BAR] - case 0xA747: // [LATIN SMALL LETTER BROKEN L] - case 0xA749: // [LATIN SMALL LETTER L WITH HIGH STROKE] - case 0xA781: // [LATIN SMALL LETTER TURNED L] - case 0xFF4C: // [FULLWIDTH LATIN SMALL LETTER L] - output[outputPos++] = L'l'; - break; - case 0x01C7: // [LATIN CAPITAL LETTER LJ] - output[outputPos++] = L'L'; - output[outputPos++] = L'J'; - break; - case 0x1EFA: // [LATIN CAPITAL LETTER MIDDLE-WELSH LL] - output[outputPos++] = L'L'; - output[outputPos++] = L'L'; - break; - case 0x01C8: // [LATIN CAPITAL LETTER L WITH SMALL LETTER J] - output[outputPos++] = L'L'; - output[outputPos++] = L'j'; - break; - case 0x24A7: // [PARENTHESIZED LATIN SMALL LETTER L] - output[outputPos++] = L'('; - output[outputPos++] = L'l'; - output[outputPos++] = L')'; - break; - case 0x01C9: // [LATIN SMALL LETTER LJ] - output[outputPos++] = L'l'; - output[outputPos++] = L'j'; - break; - case 0x1EFB: // [LATIN SMALL LETTER MIDDLE-WELSH LL] - output[outputPos++] = L'l'; - output[outputPos++] = L'l'; - break; - case 0x02AA: // [LATIN SMALL LETTER LS DIGRAPH] - output[outputPos++] = L'l'; - output[outputPos++] = L's'; - break; - case 0x02AB: // [LATIN SMALL LETTER LZ DIGRAPH] - output[outputPos++] = L'l'; - output[outputPos++] = L'z'; - break; - case 0x019C: // [LATIN CAPITAL LETTER TURNED M] - case 0x1D0D: // [LATIN LETTER SMALL CAPITAL M] - case 0x1E3E: // [LATIN CAPITAL LETTER M WITH ACUTE] - case 0x1E40: // [LATIN CAPITAL LETTER M WITH DOT ABOVE] - case 0x1E42: // [LATIN CAPITAL LETTER M WITH DOT BELOW] - case 0x24C2: // [CIRCLED LATIN CAPITAL LETTER M] - case 0x2C6E: // [LATIN CAPITAL LETTER M WITH HOOK] - case 0xA7FD: // [LATIN EPIGRAPHIC LETTER INVERTED M] - case 0xA7FF: // [LATIN EPIGRAPHIC LETTER ARCHAIC M] - case 0xFF2D: // [FULLWIDTH LATIN CAPITAL LETTER M] - output[outputPos++] = L'M'; - break; - case 0x026F: // [LATIN SMALL LETTER TURNED M] - case 0x0270: // [LATIN SMALL LETTER TURNED M WITH LONG LEG] - case 0x0271: // [LATIN SMALL LETTER M WITH HOOK] - case 0x1D6F: // [LATIN SMALL LETTER M WITH MIDDLE TILDE] - case 0x1D86: // [LATIN SMALL LETTER M WITH PALATAL HOOK] - case 0x1E3F: // [LATIN SMALL LETTER M WITH ACUTE] - case 0x1E41: // [LATIN SMALL LETTER M WITH DOT ABOVE] - case 0x1E43: // [LATIN SMALL LETTER M WITH DOT BELOW] - case 0x24DC: // [CIRCLED LATIN SMALL LETTER M] - case 0xFF4D: // [FULLWIDTH LATIN SMALL LETTER M] - output[outputPos++] = L'm'; - break; - case 0x24A8: // [PARENTHESIZED LATIN SMALL LETTER M] - output[outputPos++] = L'('; - output[outputPos++] = L'm'; - output[outputPos++] = L')'; - break; - case 0x00D1: // [LATIN CAPITAL LETTER N WITH TILDE] - case 0x0143: // [LATIN CAPITAL LETTER N WITH ACUTE] - case 0x0145: // [LATIN CAPITAL LETTER N WITH CEDILLA] - case 0x0147: // [LATIN CAPITAL LETTER N WITH CARON] - case 0x014A: // [LATIN CAPITAL LETTER ENG] - case 0x019D: // [LATIN CAPITAL LETTER N WITH LEFT HOOK] - case 0x01F8: // [LATIN CAPITAL LETTER N WITH GRAVE] - case 0x0220: // [LATIN CAPITAL LETTER N WITH LONG RIGHT LEG] - case 0x0274: // [LATIN LETTER SMALL CAPITAL N] - case 0x1D0E: // [LATIN LETTER SMALL CAPITAL REVERSED N] - case 0x1E44: // [LATIN CAPITAL LETTER N WITH DOT ABOVE] - case 0x1E46: // [LATIN CAPITAL LETTER N WITH DOT BELOW] - case 0x1E48: // [LATIN CAPITAL LETTER N WITH LINE BELOW] - case 0x1E4A: // [LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW] - case 0x24C3: // [CIRCLED LATIN CAPITAL LETTER N] - case 0xFF2E: // [FULLWIDTH LATIN CAPITAL LETTER N] - output[outputPos++] = L'N'; - break; - case 0x00F1: // [LATIN SMALL LETTER N WITH TILDE] - case 0x0144: // [LATIN SMALL LETTER N WITH ACUTE] - case 0x0146: // [LATIN SMALL LETTER N WITH CEDILLA] - case 0x0148: // [LATIN SMALL LETTER N WITH CARON] - case 0x0149: // [LATIN SMALL LETTER N PRECEDED BY APOSTROPHE] - case 0x014B: // [LATIN SMALL LETTER ENG] - case 0x019E: // [LATIN SMALL LETTER N WITH LONG RIGHT LEG] - case 0x01F9: // [LATIN SMALL LETTER N WITH GRAVE] - case 0x0235: // [LATIN SMALL LETTER N WITH CURL] - case 0x0272: // [LATIN SMALL LETTER N WITH LEFT HOOK] - case 0x0273: // [LATIN SMALL LETTER N WITH RETROFLEX HOOK] - case 0x1D70: // [LATIN SMALL LETTER N WITH MIDDLE TILDE] - case 0x1D87: // [LATIN SMALL LETTER N WITH PALATAL HOOK] - case 0x1E45: // [LATIN SMALL LETTER N WITH DOT ABOVE] - case 0x1E47: // [LATIN SMALL LETTER N WITH DOT BELOW] - case 0x1E49: // [LATIN SMALL LETTER N WITH LINE BELOW] - case 0x1E4B: // [LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW] - case 0x207F: // [SUPERSCRIPT LATIN SMALL LETTER N] - case 0x24DD: // [CIRCLED LATIN SMALL LETTER N] - case 0xFF4E: // [FULLWIDTH LATIN SMALL LETTER N] - output[outputPos++] = L'n'; - break; - case 0x01CA: // [LATIN CAPITAL LETTER NJ] - output[outputPos++] = L'N'; - output[outputPos++] = L'J'; - break; - case 0x01CB: // [LATIN CAPITAL LETTER N WITH SMALL LETTER J] - output[outputPos++] = L'N'; - output[outputPos++] = L'j'; - break; - case 0x24A9: // [PARENTHESIZED LATIN SMALL LETTER N] - output[outputPos++] = L'('; - output[outputPos++] = L'n'; - output[outputPos++] = L')'; - break; - case 0x01CC: // [LATIN SMALL LETTER NJ] - output[outputPos++] = L'n'; - output[outputPos++] = L'j'; - break; - case 0x00D2: // [LATIN CAPITAL LETTER O WITH GRAVE] - case 0x00D3: // [LATIN CAPITAL LETTER O WITH ACUTE] - case 0x00D4: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX] - case 0x00D5: // [LATIN CAPITAL LETTER O WITH TILDE] - case 0x00D6: // [LATIN CAPITAL LETTER O WITH DIAERESIS] - case 0x00D8: // [LATIN CAPITAL LETTER O WITH STROKE] - case 0x014C: // [LATIN CAPITAL LETTER O WITH MACRON] - case 0x014E: // [LATIN CAPITAL LETTER O WITH BREVE] - case 0x0150: // [LATIN CAPITAL LETTER O WITH DOUBLE ACUTE] - case 0x0186: // [LATIN CAPITAL LETTER OPEN O] - case 0x019F: // [LATIN CAPITAL LETTER O WITH MIDDLE TILDE] - case 0x01A0: // [LATIN CAPITAL LETTER O WITH HORN] - case 0x01D1: // [LATIN CAPITAL LETTER O WITH CARON] - case 0x01EA: // [LATIN CAPITAL LETTER O WITH OGONEK] - case 0x01EC: // [LATIN CAPITAL LETTER O WITH OGONEK AND MACRON] - case 0x01FE: // [LATIN CAPITAL LETTER O WITH STROKE AND ACUTE] - case 0x020C: // [LATIN CAPITAL LETTER O WITH DOUBLE GRAVE] - case 0x020E: // [LATIN CAPITAL LETTER O WITH INVERTED BREVE] - case 0x022A: // [LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON] - case 0x022C: // [LATIN CAPITAL LETTER O WITH TILDE AND MACRON] - case 0x022E: // [LATIN CAPITAL LETTER O WITH DOT ABOVE] - case 0x0230: // [LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON] - case 0x1D0F: // [LATIN LETTER SMALL CAPITAL O] - case 0x1D10: // [LATIN LETTER SMALL CAPITAL OPEN O] - case 0x1E4C: // [LATIN CAPITAL LETTER O WITH TILDE AND ACUTE] - case 0x1E4E: // [LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS] - case 0x1E50: // [LATIN CAPITAL LETTER O WITH MACRON AND GRAVE] - case 0x1E52: // [LATIN CAPITAL LETTER O WITH MACRON AND ACUTE] - case 0x1ECC: // [LATIN CAPITAL LETTER O WITH DOT BELOW] - case 0x1ECE: // [LATIN CAPITAL LETTER O WITH HOOK ABOVE] - case 0x1ED0: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE] - case 0x1ED2: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE] - case 0x1ED4: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE] - case 0x1ED6: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE] - case 0x1ED8: // [LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW] - case 0x1EDA: // [LATIN CAPITAL LETTER O WITH HORN AND ACUTE] - case 0x1EDC: // [LATIN CAPITAL LETTER O WITH HORN AND GRAVE] - case 0x1EDE: // [LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE] - case 0x1EE0: // [LATIN CAPITAL LETTER O WITH HORN AND TILDE] - case 0x1EE2: // [LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW] - case 0x24C4: // [CIRCLED LATIN CAPITAL LETTER O] - case 0xA74A: // [LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY] - case 0xA74C: // [LATIN CAPITAL LETTER O WITH LOOP] - case 0xFF2F: // [FULLWIDTH LATIN CAPITAL LETTER O] - output[outputPos++] = L'O'; - break; - case 0x00F2: // [LATIN SMALL LETTER O WITH GRAVE] - case 0x00F3: // [LATIN SMALL LETTER O WITH ACUTE] - case 0x00F4: // [LATIN SMALL LETTER O WITH CIRCUMFLEX] - case 0x00F5: // [LATIN SMALL LETTER O WITH TILDE] - case 0x00F6: // [LATIN SMALL LETTER O WITH DIAERESIS] - case 0x00F8: // [LATIN SMALL LETTER O WITH STROKE] - case 0x014D: // [LATIN SMALL LETTER O WITH MACRON] - case 0x014F: // [LATIN SMALL LETTER O WITH BREVE] - case 0x0151: // [LATIN SMALL LETTER O WITH DOUBLE ACUTE] - case 0x01A1: // [LATIN SMALL LETTER O WITH HORN] - case 0x01D2: // [LATIN SMALL LETTER O WITH CARON] - case 0x01EB: // [LATIN SMALL LETTER O WITH OGONEK] - case 0x01ED: // [LATIN SMALL LETTER O WITH OGONEK AND MACRON] - case 0x01FF: // [LATIN SMALL LETTER O WITH STROKE AND ACUTE] - case 0x020D: // [LATIN SMALL LETTER O WITH DOUBLE GRAVE] - case 0x020F: // [LATIN SMALL LETTER O WITH INVERTED BREVE] - case 0x022B: // [LATIN SMALL LETTER O WITH DIAERESIS AND MACRON] - case 0x022D: // [LATIN SMALL LETTER O WITH TILDE AND MACRON] - case 0x022F: // [LATIN SMALL LETTER O WITH DOT ABOVE] - case 0x0231: // [LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON] - case 0x0254: // [LATIN SMALL LETTER OPEN O] - case 0x0275: // [LATIN SMALL LETTER BARRED O] - case 0x1D16: // [LATIN SMALL LETTER TOP HALF O] - case 0x1D17: // [LATIN SMALL LETTER BOTTOM HALF O] - case 0x1D97: // [LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK] - case 0x1E4D: // [LATIN SMALL LETTER O WITH TILDE AND ACUTE] - case 0x1E4F: // [LATIN SMALL LETTER O WITH TILDE AND DIAERESIS] - case 0x1E51: // [LATIN SMALL LETTER O WITH MACRON AND GRAVE] - case 0x1E53: // [LATIN SMALL LETTER O WITH MACRON AND ACUTE] - case 0x1ECD: // [LATIN SMALL LETTER O WITH DOT BELOW] - case 0x1ECF: // [LATIN SMALL LETTER O WITH HOOK ABOVE] - case 0x1ED1: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE] - case 0x1ED3: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE] - case 0x1ED5: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE] - case 0x1ED7: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE] - case 0x1ED9: // [LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW] - case 0x1EDB: // [LATIN SMALL LETTER O WITH HORN AND ACUTE] - case 0x1EDD: // [LATIN SMALL LETTER O WITH HORN AND GRAVE] - case 0x1EDF: // [LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE] - case 0x1EE1: // [LATIN SMALL LETTER O WITH HORN AND TILDE] - case 0x1EE3: // [LATIN SMALL LETTER O WITH HORN AND DOT BELOW] - case 0x2092: // [LATIN SUBSCRIPT SMALL LETTER O] - case 0x24DE: // [CIRCLED LATIN SMALL LETTER O] - case 0x2C7A: // [LATIN SMALL LETTER O WITH LOW RING INSIDE] - case 0xA74B: // [LATIN SMALL LETTER O WITH LONG STROKE OVERLAY] - case 0xA74D: // [LATIN SMALL LETTER O WITH LOOP] - case 0xFF4F: // [FULLWIDTH LATIN SMALL LETTER O] - output[outputPos++] = L'o'; - break; - case 0x0152: // [LATIN CAPITAL LIGATURE OE] - case 0x0276: // [LATIN LETTER SMALL CAPITAL OE] - output[outputPos++] = L'O'; - output[outputPos++] = L'E'; - break; - case 0xA74E: // [LATIN CAPITAL LETTER OO] - output[outputPos++] = L'O'; - output[outputPos++] = L'O'; - break; - case 0x0222: // [LATIN CAPITAL LETTER OU] - case 0x1D15: // [LATIN LETTER SMALL CAPITAL OU] - output[outputPos++] = L'O'; - output[outputPos++] = L'U'; - break; - case 0x24AA: // [PARENTHESIZED LATIN SMALL LETTER O] - output[outputPos++] = L'('; - output[outputPos++] = L'o'; - output[outputPos++] = L')'; - break; - case 0x0153: // [LATIN SMALL LIGATURE OE] - case 0x1D14: // [LATIN SMALL LETTER TURNED OE] - output[outputPos++] = L'o'; - output[outputPos++] = L'e'; - break; - case 0xA74F: // [LATIN SMALL LETTER OO] - output[outputPos++] = L'o'; - output[outputPos++] = L'o'; - break; - case 0x0223: // [LATIN SMALL LETTER OU] - output[outputPos++] = L'o'; - output[outputPos++] = L'u'; - break; - case 0x01A4: // [LATIN CAPITAL LETTER P WITH HOOK] - case 0x1D18: // [LATIN LETTER SMALL CAPITAL P] - case 0x1E54: // [LATIN CAPITAL LETTER P WITH ACUTE] - case 0x1E56: // [LATIN CAPITAL LETTER P WITH DOT ABOVE] - case 0x24C5: // [CIRCLED LATIN CAPITAL LETTER P] - case 0x2C63: // [LATIN CAPITAL LETTER P WITH STROKE] - case 0xA750: // [LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER] - case 0xA752: // [LATIN CAPITAL LETTER P WITH FLOURISH] - case 0xA754: // [LATIN CAPITAL LETTER P WITH SQUIRREL TAIL] - case 0xFF30: // [FULLWIDTH LATIN CAPITAL LETTER P] - output[outputPos++] = L'P'; - break; - case 0x01A5: // [LATIN SMALL LETTER P WITH HOOK] - case 0x1D71: // [LATIN SMALL LETTER P WITH MIDDLE TILDE] - case 0x1D7D: // [LATIN SMALL LETTER P WITH STROKE] - case 0x1D88: // [LATIN SMALL LETTER P WITH PALATAL HOOK] - case 0x1E55: // [LATIN SMALL LETTER P WITH ACUTE] - case 0x1E57: // [LATIN SMALL LETTER P WITH DOT ABOVE] - case 0x24DF: // [CIRCLED LATIN SMALL LETTER P] - case 0xA751: // [LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER] - case 0xA753: // [LATIN SMALL LETTER P WITH FLOURISH] - case 0xA755: // [LATIN SMALL LETTER P WITH SQUIRREL TAIL] - case 0xA7FC: // [LATIN EPIGRAPHIC LETTER REVERSED P] - case 0xFF50: // [FULLWIDTH LATIN SMALL LETTER P] - output[outputPos++] = L'p'; - break; - case 0x24AB: // [PARENTHESIZED LATIN SMALL LETTER P] - output[outputPos++] = L'('; - output[outputPos++] = L'p'; - output[outputPos++] = L')'; - break; - case 0x024A: // [LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL] - case 0x24C6: // [CIRCLED LATIN CAPITAL LETTER Q] - case 0xA756: // [LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER] - case 0xA758: // [LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE] - case 0xFF31: // [FULLWIDTH LATIN CAPITAL LETTER Q] - output[outputPos++] = L'Q'; - break; - case 0x0138: // [LATIN SMALL LETTER KRA] - case 0x024B: // [LATIN SMALL LETTER Q WITH HOOK TAIL] - case 0x02A0: // [LATIN SMALL LETTER Q WITH HOOK] - case 0x24E0: // [CIRCLED LATIN SMALL LETTER Q] - case 0xA757: // [LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER] - case 0xA759: // [LATIN SMALL LETTER Q WITH DIAGONAL STROKE] - case 0xFF51: // [FULLWIDTH LATIN SMALL LETTER Q] - output[outputPos++] = L'q'; - break; - case 0x24AC: // [PARENTHESIZED LATIN SMALL LETTER Q] - output[outputPos++] = L'('; - output[outputPos++] = L'q'; - output[outputPos++] = L')'; - break; - case 0x0239: // [LATIN SMALL LETTER QP DIGRAPH] - output[outputPos++] = L'q'; - output[outputPos++] = L'p'; - break; - case 0x0154: // [LATIN CAPITAL LETTER R WITH ACUTE] - case 0x0156: // [LATIN CAPITAL LETTER R WITH CEDILLA] - case 0x0158: // [LATIN CAPITAL LETTER R WITH CARON] - case 0x0210: // [LATIN CAPITAL LETTER R WITH DOUBLE GRAVE] - case 0x0212: // [LATIN CAPITAL LETTER R WITH INVERTED BREVE] - case 0x024C: // [LATIN CAPITAL LETTER R WITH STROKE] - case 0x0280: // [LATIN LETTER SMALL CAPITAL R] - case 0x0281: // [LATIN LETTER SMALL CAPITAL INVERTED R] - case 0x1D19: // [LATIN LETTER SMALL CAPITAL REVERSED R] - case 0x1D1A: // [LATIN LETTER SMALL CAPITAL TURNED R] - case 0x1E58: // [LATIN CAPITAL LETTER R WITH DOT ABOVE] - case 0x1E5A: // [LATIN CAPITAL LETTER R WITH DOT BELOW] - case 0x1E5C: // [LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON] - case 0x1E5E: // [LATIN CAPITAL LETTER R WITH LINE BELOW] - case 0x24C7: // [CIRCLED LATIN CAPITAL LETTER R] - case 0x2C64: // [LATIN CAPITAL LETTER R WITH TAIL] - case 0xA75A: // [LATIN CAPITAL LETTER R ROTUNDA] - case 0xA782: // [LATIN CAPITAL LETTER INSULAR R] - case 0xFF32: // [FULLWIDTH LATIN CAPITAL LETTER R] - output[outputPos++] = L'R'; - break; - case 0x0155: // [LATIN SMALL LETTER R WITH ACUTE] - case 0x0157: // [LATIN SMALL LETTER R WITH CEDILLA] - case 0x0159: // [LATIN SMALL LETTER R WITH CARON] - case 0x0211: // [LATIN SMALL LETTER R WITH DOUBLE GRAVE] - case 0x0213: // [LATIN SMALL LETTER R WITH INVERTED BREVE] - case 0x024D: // [LATIN SMALL LETTER R WITH STROKE] - case 0x027C: // [LATIN SMALL LETTER R WITH LONG LEG] - case 0x027D: // [LATIN SMALL LETTER R WITH TAIL] - case 0x027E: // [LATIN SMALL LETTER R WITH FISHHOOK] - case 0x027F: // [LATIN SMALL LETTER REVERSED R WITH FISHHOOK] - case 0x1D63: // [LATIN SUBSCRIPT SMALL LETTER R] - case 0x1D72: // [LATIN SMALL LETTER R WITH MIDDLE TILDE] - case 0x1D73: // [LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE] - case 0x1D89: // [LATIN SMALL LETTER R WITH PALATAL HOOK] - case 0x1E59: // [LATIN SMALL LETTER R WITH DOT ABOVE] - case 0x1E5B: // [LATIN SMALL LETTER R WITH DOT BELOW] - case 0x1E5D: // [LATIN SMALL LETTER R WITH DOT BELOW AND MACRON] - case 0x1E5F: // [LATIN SMALL LETTER R WITH LINE BELOW] - case 0x24E1: // [CIRCLED LATIN SMALL LETTER R] - case 0xA75B: // [LATIN SMALL LETTER R ROTUNDA] - case 0xA783: // [LATIN SMALL LETTER INSULAR R] - case 0xFF52: // [FULLWIDTH LATIN SMALL LETTER R] - output[outputPos++] = L'r'; - break; - case 0x24AD: // [PARENTHESIZED LATIN SMALL LETTER R] - output[outputPos++] = L'('; - output[outputPos++] = L'r'; - output[outputPos++] = L')'; - break; - case 0x015A: // [LATIN CAPITAL LETTER S WITH ACUTE] - case 0x015C: // [LATIN CAPITAL LETTER S WITH CIRCUMFLEX] - case 0x015E: // [LATIN CAPITAL LETTER S WITH CEDILLA] - case 0x0160: // [LATIN CAPITAL LETTER S WITH CARON] - case 0x0218: // [LATIN CAPITAL LETTER S WITH COMMA BELOW] - case 0x1E60: // [LATIN CAPITAL LETTER S WITH DOT ABOVE] - case 0x1E62: // [LATIN CAPITAL LETTER S WITH DOT BELOW] - case 0x1E64: // [LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE] - case 0x1E66: // [LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE] - case 0x1E68: // [LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE] - case 0x24C8: // [CIRCLED LATIN CAPITAL LETTER S] - case 0xA731: // [LATIN LETTER SMALL CAPITAL S] - case 0xA785: // [LATIN SMALL LETTER INSULAR S] - case 0xFF33: // [FULLWIDTH LATIN CAPITAL LETTER S] - output[outputPos++] = L'S'; - break; - case 0x015B: // [LATIN SMALL LETTER S WITH ACUTE] - case 0x015D: // [LATIN SMALL LETTER S WITH CIRCUMFLEX] - case 0x015F: // [LATIN SMALL LETTER S WITH CEDILLA] - case 0x0161: // [LATIN SMALL LETTER S WITH CARON] - case 0x017F: // [LATIN SMALL LETTER LONG S] - case 0x0219: // [LATIN SMALL LETTER S WITH COMMA BELOW] - case 0x023F: // [LATIN SMALL LETTER S WITH SWASH TAIL] - case 0x0282: // [LATIN SMALL LETTER S WITH HOOK] - case 0x1D74: // [LATIN SMALL LETTER S WITH MIDDLE TILDE] - case 0x1D8A: // [LATIN SMALL LETTER S WITH PALATAL HOOK] - case 0x1E61: // [LATIN SMALL LETTER S WITH DOT ABOVE] - case 0x1E63: // [LATIN SMALL LETTER S WITH DOT BELOW] - case 0x1E65: // [LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE] - case 0x1E67: // [LATIN SMALL LETTER S WITH CARON AND DOT ABOVE] - case 0x1E69: // [LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE] - case 0x1E9C: // [LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE] - case 0x1E9D: // [LATIN SMALL LETTER LONG S WITH HIGH STROKE] - case 0x24E2: // [CIRCLED LATIN SMALL LETTER S] - case 0xA784: // [LATIN CAPITAL LETTER INSULAR S] - case 0xFF53: // [FULLWIDTH LATIN SMALL LETTER S] - output[outputPos++] = L's'; - break; - case 0x1E9E: // [LATIN CAPITAL LETTER SHARP S] - output[outputPos++] = L'S'; - output[outputPos++] = L'S'; - break; - case 0x24AE: // [PARENTHESIZED LATIN SMALL LETTER S] - output[outputPos++] = L'('; - output[outputPos++] = L's'; - output[outputPos++] = L')'; - break; - case 0x00DF: // [LATIN SMALL LETTER SHARP S] - output[outputPos++] = L's'; - output[outputPos++] = L's'; - break; - case 0xFB06: // [LATIN SMALL LIGATURE ST] - output[outputPos++] = L's'; - output[outputPos++] = L't'; - break; - case 0x0162: // [LATIN CAPITAL LETTER T WITH CEDILLA] - case 0x0164: // [LATIN CAPITAL LETTER T WITH CARON] - case 0x0166: // [LATIN CAPITAL LETTER T WITH STROKE] - case 0x01AC: // [LATIN CAPITAL LETTER T WITH HOOK] - case 0x01AE: // [LATIN CAPITAL LETTER T WITH RETROFLEX HOOK] - case 0x021A: // [LATIN CAPITAL LETTER T WITH COMMA BELOW] - case 0x023E: // [LATIN CAPITAL LETTER T WITH DIAGONAL STROKE] - case 0x1D1B: // [LATIN LETTER SMALL CAPITAL T] - case 0x1E6A: // [LATIN CAPITAL LETTER T WITH DOT ABOVE] - case 0x1E6C: // [LATIN CAPITAL LETTER T WITH DOT BELOW] - case 0x1E6E: // [LATIN CAPITAL LETTER T WITH LINE BELOW] - case 0x1E70: // [LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW] - case 0x24C9: // [CIRCLED LATIN CAPITAL LETTER T] - case 0xA786: // [LATIN CAPITAL LETTER INSULAR T] - case 0xFF34: // [FULLWIDTH LATIN CAPITAL LETTER T] - output[outputPos++] = L'T'; - break; - case 0x0163: // [LATIN SMALL LETTER T WITH CEDILLA] - case 0x0165: // [LATIN SMALL LETTER T WITH CARON] - case 0x0167: // [LATIN SMALL LETTER T WITH STROKE] - case 0x01AB: // [LATIN SMALL LETTER T WITH PALATAL HOOK] - case 0x01AD: // [LATIN SMALL LETTER T WITH HOOK] - case 0x021B: // [LATIN SMALL LETTER T WITH COMMA BELOW] - case 0x0236: // [LATIN SMALL LETTER T WITH CURL] - case 0x0287: // [LATIN SMALL LETTER TURNED T] - case 0x0288: // [LATIN SMALL LETTER T WITH RETROFLEX HOOK] - case 0x1D75: // [LATIN SMALL LETTER T WITH MIDDLE TILDE] - case 0x1E6B: // [LATIN SMALL LETTER T WITH DOT ABOVE] - case 0x1E6D: // [LATIN SMALL LETTER T WITH DOT BELOW] - case 0x1E6F: // [LATIN SMALL LETTER T WITH LINE BELOW] - case 0x1E71: // [LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW] - case 0x1E97: // [LATIN SMALL LETTER T WITH DIAERESIS] - case 0x24E3: // [CIRCLED LATIN SMALL LETTER T] - case 0x2C66: // [LATIN SMALL LETTER T WITH DIAGONAL STROKE] - case 0xFF54: // [FULLWIDTH LATIN SMALL LETTER T] - output[outputPos++] = L't'; - break; - case 0x00DE: // [LATIN CAPITAL LETTER THORN] - case 0xA766: // [LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER] - output[outputPos++] = L'T'; - output[outputPos++] = L'H'; - break; - case 0xA728: // [LATIN CAPITAL LETTER TZ] - output[outputPos++] = L'T'; - output[outputPos++] = L'Z'; - break; - case 0x24AF: // [PARENTHESIZED LATIN SMALL LETTER T] - output[outputPos++] = L'('; - output[outputPos++] = L't'; - output[outputPos++] = L')'; - break; - case 0x02A8: // [LATIN SMALL LETTER TC DIGRAPH WITH CURL] - output[outputPos++] = L't'; - output[outputPos++] = L'c'; - break; - case 0x00FE: // [LATIN SMALL LETTER THORN] - case 0x1D7A: // [LATIN SMALL LETTER TH WITH STRIKETHROUGH] - case 0xA767: // [LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER] - output[outputPos++] = L't'; - output[outputPos++] = L'h'; - break; - case 0x02A6: // [LATIN SMALL LETTER TS DIGRAPH] - output[outputPos++] = L't'; - output[outputPos++] = L's'; - break; - case 0xA729: // [LATIN SMALL LETTER TZ] - output[outputPos++] = L't'; - output[outputPos++] = L'z'; - break; - case 0x00D9: // [LATIN CAPITAL LETTER U WITH GRAVE] - case 0x00DA: // [LATIN CAPITAL LETTER U WITH ACUTE] - case 0x00DB: // [LATIN CAPITAL LETTER U WITH CIRCUMFLEX] - case 0x00DC: // [LATIN CAPITAL LETTER U WITH DIAERESIS] - case 0x0168: // [LATIN CAPITAL LETTER U WITH TILDE] - case 0x016A: // [LATIN CAPITAL LETTER U WITH MACRON] - case 0x016C: // [LATIN CAPITAL LETTER U WITH BREVE] - case 0x016E: // [LATIN CAPITAL LETTER U WITH RING ABOVE] - case 0x0170: // [LATIN CAPITAL LETTER U WITH DOUBLE ACUTE] - case 0x0172: // [LATIN CAPITAL LETTER U WITH OGONEK] - case 0x01AF: // [LATIN CAPITAL LETTER U WITH HORN] - case 0x01D3: // [LATIN CAPITAL LETTER U WITH CARON] - case 0x01D5: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON] - case 0x01D7: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE] - case 0x01D9: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON] - case 0x01DB: // [LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE] - case 0x0214: // [LATIN CAPITAL LETTER U WITH DOUBLE GRAVE] - case 0x0216: // [LATIN CAPITAL LETTER U WITH INVERTED BREVE] - case 0x0244: // [LATIN CAPITAL LETTER U BAR] - case 0x1D1C: // [LATIN LETTER SMALL CAPITAL U] - case 0x1D7E: // [LATIN SMALL CAPITAL LETTER U WITH STROKE] - case 0x1E72: // [LATIN CAPITAL LETTER U WITH DIAERESIS BELOW] - case 0x1E74: // [LATIN CAPITAL LETTER U WITH TILDE BELOW] - case 0x1E76: // [LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW] - case 0x1E78: // [LATIN CAPITAL LETTER U WITH TILDE AND ACUTE] - case 0x1E7A: // [LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS] - case 0x1EE4: // [LATIN CAPITAL LETTER U WITH DOT BELOW] - case 0x1EE6: // [LATIN CAPITAL LETTER U WITH HOOK ABOVE] - case 0x1EE8: // [LATIN CAPITAL LETTER U WITH HORN AND ACUTE] - case 0x1EEA: // [LATIN CAPITAL LETTER U WITH HORN AND GRAVE] - case 0x1EEC: // [LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE] - case 0x1EEE: // [LATIN CAPITAL LETTER U WITH HORN AND TILDE] - case 0x1EF0: // [LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW] - case 0x24CA: // [CIRCLED LATIN CAPITAL LETTER U] - case 0xFF35: // [FULLWIDTH LATIN CAPITAL LETTER U] - output[outputPos++] = L'U'; - break; - case 0x00F9: // [LATIN SMALL LETTER U WITH GRAVE] - case 0x00FA: // [LATIN SMALL LETTER U WITH ACUTE] - case 0x00FB: // [LATIN SMALL LETTER U WITH CIRCUMFLEX] - case 0x00FC: // [LATIN SMALL LETTER U WITH DIAERESIS] - case 0x0169: // [LATIN SMALL LETTER U WITH TILDE] - case 0x016B: // [LATIN SMALL LETTER U WITH MACRON] - case 0x016D: // [LATIN SMALL LETTER U WITH BREVE] - case 0x016F: // [LATIN SMALL LETTER U WITH RING ABOVE] - case 0x0171: // [LATIN SMALL LETTER U WITH DOUBLE ACUTE] - case 0x0173: // [LATIN SMALL LETTER U WITH OGONEK] - case 0x01B0: // [LATIN SMALL LETTER U WITH HORN] - case 0x01D4: // [LATIN SMALL LETTER U WITH CARON] - case 0x01D6: // [LATIN SMALL LETTER U WITH DIAERESIS AND MACRON] - case 0x01D8: // [LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE] - case 0x01DA: // [LATIN SMALL LETTER U WITH DIAERESIS AND CARON] - case 0x01DC: // [LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE] - case 0x0215: // [LATIN SMALL LETTER U WITH DOUBLE GRAVE] - case 0x0217: // [LATIN SMALL LETTER U WITH INVERTED BREVE] - case 0x0289: // [LATIN SMALL LETTER U BAR] - case 0x1D64: // [LATIN SUBSCRIPT SMALL LETTER U] - case 0x1D99: // [LATIN SMALL LETTER U WITH RETROFLEX HOOK] - case 0x1E73: // [LATIN SMALL LETTER U WITH DIAERESIS BELOW] - case 0x1E75: // [LATIN SMALL LETTER U WITH TILDE BELOW] - case 0x1E77: // [LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW] - case 0x1E79: // [LATIN SMALL LETTER U WITH TILDE AND ACUTE] - case 0x1E7B: // [LATIN SMALL LETTER U WITH MACRON AND DIAERESIS] - case 0x1EE5: // [LATIN SMALL LETTER U WITH DOT BELOW] - case 0x1EE7: // [LATIN SMALL LETTER U WITH HOOK ABOVE] - case 0x1EE9: // [LATIN SMALL LETTER U WITH HORN AND ACUTE] - case 0x1EEB: // [LATIN SMALL LETTER U WITH HORN AND GRAVE] - case 0x1EED: // [LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE] - case 0x1EEF: // [LATIN SMALL LETTER U WITH HORN AND TILDE] - case 0x1EF1: // [LATIN SMALL LETTER U WITH HORN AND DOT BELOW] - case 0x24E4: // [CIRCLED LATIN SMALL LETTER U] - case 0xFF55: // [FULLWIDTH LATIN SMALL LETTER U] - output[outputPos++] = L'u'; - break; - case 0x24B0: // [PARENTHESIZED LATIN SMALL LETTER U] - output[outputPos++] = L'('; - output[outputPos++] = L'u'; - output[outputPos++] = L')'; - break; - case 0x1D6B: // [LATIN SMALL LETTER UE] - output[outputPos++] = L'u'; - output[outputPos++] = L'e'; - break; - case 0x01B2: // [LATIN CAPITAL LETTER V WITH HOOK] - case 0x0245: // [LATIN CAPITAL LETTER TURNED V] - case 0x1D20: // [LATIN LETTER SMALL CAPITAL V] - case 0x1E7C: // [LATIN CAPITAL LETTER V WITH TILDE] - case 0x1E7E: // [LATIN CAPITAL LETTER V WITH DOT BELOW] - case 0x1EFC: // [LATIN CAPITAL LETTER MIDDLE-WELSH V] - case 0x24CB: // [CIRCLED LATIN CAPITAL LETTER V] - case 0xA75E: // [LATIN CAPITAL LETTER V WITH DIAGONAL STROKE] - case 0xA768: // [LATIN CAPITAL LETTER VEND] - case 0xFF36: // [FULLWIDTH LATIN CAPITAL LETTER V] - output[outputPos++] = L'V'; - break; - case 0x028B: // [LATIN SMALL LETTER V WITH HOOK] - case 0x028C: // [LATIN SMALL LETTER TURNED V] - case 0x1D65: // [LATIN SUBSCRIPT SMALL LETTER V] - case 0x1D8C: // [LATIN SMALL LETTER V WITH PALATAL HOOK] - case 0x1E7D: // [LATIN SMALL LETTER V WITH TILDE] - case 0x1E7F: // [LATIN SMALL LETTER V WITH DOT BELOW] - case 0x24E5: // [CIRCLED LATIN SMALL LETTER V] - case 0x2C71: // [LATIN SMALL LETTER V WITH RIGHT HOOK] - case 0x2C74: // [LATIN SMALL LETTER V WITH CURL] - case 0xA75F: // [LATIN SMALL LETTER V WITH DIAGONAL STROKE] - case 0xFF56: // [FULLWIDTH LATIN SMALL LETTER V] - output[outputPos++] = L'v'; - break; - case 0xA760: // [LATIN CAPITAL LETTER VY] - output[outputPos++] = L'V'; - output[outputPos++] = L'Y'; - break; - case 0x24B1: // [PARENTHESIZED LATIN SMALL LETTER V] - output[outputPos++] = L'('; - output[outputPos++] = L'v'; - output[outputPos++] = L')'; - break; - case 0xA761: // [LATIN SMALL LETTER VY] - output[outputPos++] = L'v'; - output[outputPos++] = L'y'; - break; - case 0x0174: // [LATIN CAPITAL LETTER W WITH CIRCUMFLEX] - case 0x01F7: // [LATIN CAPITAL LETTER WYNN] - case 0x1D21: // [LATIN LETTER SMALL CAPITAL W] - case 0x1E80: // [LATIN CAPITAL LETTER W WITH GRAVE] - case 0x1E82: // [LATIN CAPITAL LETTER W WITH ACUTE] - case 0x1E84: // [LATIN CAPITAL LETTER W WITH DIAERESIS] - case 0x1E86: // [LATIN CAPITAL LETTER W WITH DOT ABOVE] - case 0x1E88: // [LATIN CAPITAL LETTER W WITH DOT BELOW] - case 0x24CC: // [CIRCLED LATIN CAPITAL LETTER W] - case 0x2C72: // [LATIN CAPITAL LETTER W WITH HOOK] - case 0xFF37: // [FULLWIDTH LATIN CAPITAL LETTER W] - output[outputPos++] = L'W'; - break; - case 0x0175: // [LATIN SMALL LETTER W WITH CIRCUMFLEX] - case 0x01BF: // [LATIN LETTER WYNN] - case 0x028D: // [LATIN SMALL LETTER TURNED W] - case 0x1E81: // [LATIN SMALL LETTER W WITH GRAVE] - case 0x1E83: // [LATIN SMALL LETTER W WITH ACUTE] - case 0x1E85: // [LATIN SMALL LETTER W WITH DIAERESIS] - case 0x1E87: // [LATIN SMALL LETTER W WITH DOT ABOVE] - case 0x1E89: // [LATIN SMALL LETTER W WITH DOT BELOW] - case 0x1E98: // [LATIN SMALL LETTER W WITH RING ABOVE] - case 0x24E6: // [CIRCLED LATIN SMALL LETTER W] - case 0x2C73: // [LATIN SMALL LETTER W WITH HOOK] - case 0xFF57: // [FULLWIDTH LATIN SMALL LETTER W] - output[outputPos++] = L'w'; - break; - case 0x24B2: // [PARENTHESIZED LATIN SMALL LETTER W] - output[outputPos++] = L'('; - output[outputPos++] = L'w'; - output[outputPos++] = L')'; - break; - case 0x1E8A: // [LATIN CAPITAL LETTER X WITH DOT ABOVE] - case 0x1E8C: // [LATIN CAPITAL LETTER X WITH DIAERESIS] - case 0x24CD: // [CIRCLED LATIN CAPITAL LETTER X] - case 0xFF38: // [FULLWIDTH LATIN CAPITAL LETTER X] - output[outputPos++] = L'X'; - break; - case 0x1D8D: // [LATIN SMALL LETTER X WITH PALATAL HOOK] - case 0x1E8B: // [LATIN SMALL LETTER X WITH DOT ABOVE] - case 0x1E8D: // [LATIN SMALL LETTER X WITH DIAERESIS] - case 0x2093: // [LATIN SUBSCRIPT SMALL LETTER X] - case 0x24E7: // [CIRCLED LATIN SMALL LETTER X] - case 0xFF58: // [FULLWIDTH LATIN SMALL LETTER X] - output[outputPos++] = L'x'; - break; - case 0x24B3: // [PARENTHESIZED LATIN SMALL LETTER X] - output[outputPos++] = L'('; - output[outputPos++] = L'x'; - output[outputPos++] = L')'; - break; - case 0x00DD: // [LATIN CAPITAL LETTER Y WITH ACUTE] - case 0x0176: // [LATIN CAPITAL LETTER Y WITH CIRCUMFLEX] - case 0x0178: // [LATIN CAPITAL LETTER Y WITH DIAERESIS] - case 0x01B3: // [LATIN CAPITAL LETTER Y WITH HOOK] - case 0x0232: // [LATIN CAPITAL LETTER Y WITH MACRON] - case 0x024E: // [LATIN CAPITAL LETTER Y WITH STROKE] - case 0x028F: // [LATIN LETTER SMALL CAPITAL Y] - case 0x1E8E: // [LATIN CAPITAL LETTER Y WITH DOT ABOVE] - case 0x1EF2: // [LATIN CAPITAL LETTER Y WITH GRAVE] - case 0x1EF4: // [LATIN CAPITAL LETTER Y WITH DOT BELOW] - case 0x1EF6: // [LATIN CAPITAL LETTER Y WITH HOOK ABOVE] - case 0x1EF8: // [LATIN CAPITAL LETTER Y WITH TILDE] - case 0x1EFE: // [LATIN CAPITAL LETTER Y WITH LOOP] - case 0x24CE: // [CIRCLED LATIN CAPITAL LETTER Y] - case 0xFF39: // [FULLWIDTH LATIN CAPITAL LETTER Y] - output[outputPos++] = L'Y'; - break; - case 0x00FD: // [LATIN SMALL LETTER Y WITH ACUTE] - case 0x00FF: // [LATIN SMALL LETTER Y WITH DIAERESIS] - case 0x0177: // [LATIN SMALL LETTER Y WITH CIRCUMFLEX] - case 0x01B4: // [LATIN SMALL LETTER Y WITH HOOK] - case 0x0233: // [LATIN SMALL LETTER Y WITH MACRON] - case 0x024F: // [LATIN SMALL LETTER Y WITH STROKE] - case 0x028E: // [LATIN SMALL LETTER TURNED Y] - case 0x1E8F: // [LATIN SMALL LETTER Y WITH DOT ABOVE] - case 0x1E99: // [LATIN SMALL LETTER Y WITH RING ABOVE] - case 0x1EF3: // [LATIN SMALL LETTER Y WITH GRAVE] - case 0x1EF5: // [LATIN SMALL LETTER Y WITH DOT BELOW] - case 0x1EF7: // [LATIN SMALL LETTER Y WITH HOOK ABOVE] - case 0x1EF9: // [LATIN SMALL LETTER Y WITH TILDE] - case 0x1EFF: // [LATIN SMALL LETTER Y WITH LOOP] - case 0x24E8: // [CIRCLED LATIN SMALL LETTER Y] - case 0xFF59: // [FULLWIDTH LATIN SMALL LETTER Y] - output[outputPos++] = L'y'; - break; - case 0x24B4: // [PARENTHESIZED LATIN SMALL LETTER Y] - output[outputPos++] = L'('; - output[outputPos++] = L'y'; - output[outputPos++] = L')'; - break; - case 0x0179: // [LATIN CAPITAL LETTER Z WITH ACUTE] - case 0x017B: // [LATIN CAPITAL LETTER Z WITH DOT ABOVE] - case 0x017D: // [LATIN CAPITAL LETTER Z WITH CARON] - case 0x01B5: // [LATIN CAPITAL LETTER Z WITH STROKE] - case 0x021C: // [LATIN CAPITAL LETTER YOGH] - case 0x0224: // [LATIN CAPITAL LETTER Z WITH HOOK] - case 0x1D22: // [LATIN LETTER SMALL CAPITAL Z] - case 0x1E90: // [LATIN CAPITAL LETTER Z WITH CIRCUMFLEX] - case 0x1E92: // [LATIN CAPITAL LETTER Z WITH DOT BELOW] - case 0x1E94: // [LATIN CAPITAL LETTER Z WITH LINE BELOW] - case 0x24CF: // [CIRCLED LATIN CAPITAL LETTER Z] - case 0x2C6B: // [LATIN CAPITAL LETTER Z WITH DESCENDER] - case 0xA762: // [LATIN CAPITAL LETTER VISIGOTHIC Z] - case 0xFF3A: // [FULLWIDTH LATIN CAPITAL LETTER Z] - output[outputPos++] = L'Z'; - break; - case 0x017A: // [LATIN SMALL LETTER Z WITH ACUTE] - case 0x017C: // [LATIN SMALL LETTER Z WITH DOT ABOVE] - case 0x017E: // [LATIN SMALL LETTER Z WITH CARON] - case 0x01B6: // [LATIN SMALL LETTER Z WITH STROKE] - case 0x021D: // [LATIN SMALL LETTER YOGH] - case 0x0225: // [LATIN SMALL LETTER Z WITH HOOK] - case 0x0240: // [LATIN SMALL LETTER Z WITH SWASH TAIL] - case 0x0290: // [LATIN SMALL LETTER Z WITH RETROFLEX HOOK] - case 0x0291: // [LATIN SMALL LETTER Z WITH CURL] - case 0x1D76: // [LATIN SMALL LETTER Z WITH MIDDLE TILDE] - case 0x1D8E: // [LATIN SMALL LETTER Z WITH PALATAL HOOK] - case 0x1E91: // [LATIN SMALL LETTER Z WITH CIRCUMFLEX] - case 0x1E93: // [LATIN SMALL LETTER Z WITH DOT BELOW] - case 0x1E95: // [LATIN SMALL LETTER Z WITH LINE BELOW] - case 0x24E9: // [CIRCLED LATIN SMALL LETTER Z] - case 0x2C6C: // [LATIN SMALL LETTER Z WITH DESCENDER] - case 0xA763: // [LATIN SMALL LETTER VISIGOTHIC Z] - case 0xFF5A: // [FULLWIDTH LATIN SMALL LETTER Z] - output[outputPos++] = L'z'; - break; - case 0x24B5: // [PARENTHESIZED LATIN SMALL LETTER Z] - output[outputPos++] = L'('; - output[outputPos++] = L'z'; - output[outputPos++] = L')'; - break; - case 0x2070: // [SUPERSCRIPT ZERO] - case 0x2080: // [SUBSCRIPT ZERO] - case 0x24EA: // [CIRCLED DIGIT ZERO] - case 0x24FF: // [NEGATIVE CIRCLED DIGIT ZERO] - case 0xFF10: // [FULLWIDTH DIGIT ZERO] - output[outputPos++] = L'0'; - break; - case 0x00B9: // [SUPERSCRIPT ONE] - case 0x2081: // [SUBSCRIPT ONE] - case 0x2460: // [CIRCLED DIGIT ONE] - case 0x24F5: // [DOUBLE CIRCLED DIGIT ONE] - case 0x2776: // [DINGBAT NEGATIVE CIRCLED DIGIT ONE] - case 0x2780: // [DINGBAT CIRCLED SANS-SERIF DIGIT ONE] - case 0x278A: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE] - case 0xFF11: // [FULLWIDTH DIGIT ONE] - output[outputPos++] = L'1'; - break; - case 0x2488: // [DIGIT ONE FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'.'; - break; - case 0x2474: // [PARENTHESIZED DIGIT ONE] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L')'; - break; - case 0x00B2: // [SUPERSCRIPT TWO] - case 0x2082: // [SUBSCRIPT TWO] - case 0x2461: // [CIRCLED DIGIT TWO] - case 0x24F6: // [DOUBLE CIRCLED DIGIT TWO] - case 0x2777: // [DINGBAT NEGATIVE CIRCLED DIGIT TWO] - case 0x2781: // [DINGBAT CIRCLED SANS-SERIF DIGIT TWO] - case 0x278B: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO] - case 0xFF12: // [FULLWIDTH DIGIT TWO] - output[outputPos++] = L'2'; - break; - case 0x2489: // [DIGIT TWO FULL STOP] - output[outputPos++] = L'2'; - output[outputPos++] = L'.'; - break; - case 0x2475: // [PARENTHESIZED DIGIT TWO] - output[outputPos++] = L'('; - output[outputPos++] = L'2'; - output[outputPos++] = L')'; - break; - case 0x00B3: // [SUPERSCRIPT THREE] - case 0x2083: // [SUBSCRIPT THREE] - case 0x2462: // [CIRCLED DIGIT THREE] - case 0x24F7: // [DOUBLE CIRCLED DIGIT THREE] - case 0x2778: // [DINGBAT NEGATIVE CIRCLED DIGIT THREE] - case 0x2782: // [DINGBAT CIRCLED SANS-SERIF DIGIT THREE] - case 0x278C: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE] - case 0xFF13: // [FULLWIDTH DIGIT THREE] - output[outputPos++] = L'3'; - break; - case 0x248A: // [DIGIT THREE FULL STOP] - output[outputPos++] = L'3'; - output[outputPos++] = L'.'; - break; - case 0x2476: // [PARENTHESIZED DIGIT THREE] - output[outputPos++] = L'('; - output[outputPos++] = L'3'; - output[outputPos++] = L')'; - break; - case 0x2074: // [SUPERSCRIPT FOUR] - case 0x2084: // [SUBSCRIPT FOUR] - case 0x2463: // [CIRCLED DIGIT FOUR] - case 0x24F8: // [DOUBLE CIRCLED DIGIT FOUR] - case 0x2779: // [DINGBAT NEGATIVE CIRCLED DIGIT FOUR] - case 0x2783: // [DINGBAT CIRCLED SANS-SERIF DIGIT FOUR] - case 0x278D: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR] - case 0xFF14: // [FULLWIDTH DIGIT FOUR] - output[outputPos++] = L'4'; - break; - case 0x248B: // [DIGIT FOUR FULL STOP] - output[outputPos++] = L'4'; - output[outputPos++] = L'.'; - break; - case 0x2477: // [PARENTHESIZED DIGIT FOUR] - output[outputPos++] = L'('; - output[outputPos++] = L'4'; - output[outputPos++] = L')'; - break; - case 0x2075: // [SUPERSCRIPT FIVE] - case 0x2085: // [SUBSCRIPT FIVE] - case 0x2464: // [CIRCLED DIGIT FIVE] - case 0x24F9: // [DOUBLE CIRCLED DIGIT FIVE] - case 0x277A: // [DINGBAT NEGATIVE CIRCLED DIGIT FIVE] - case 0x2784: // [DINGBAT CIRCLED SANS-SERIF DIGIT FIVE] - case 0x278E: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE] - case 0xFF15: // [FULLWIDTH DIGIT FIVE] - output[outputPos++] = L'5'; - break; - case 0x248C: // [DIGIT FIVE FULL STOP] - output[outputPos++] = L'5'; - output[outputPos++] = L'.'; - break; - case 0x2478: // [PARENTHESIZED DIGIT FIVE] - output[outputPos++] = L'('; - output[outputPos++] = L'5'; - output[outputPos++] = L')'; - break; - case 0x2076: // [SUPERSCRIPT SIX] - case 0x2086: // [SUBSCRIPT SIX] - case 0x2465: // [CIRCLED DIGIT SIX] - case 0x24FA: // [DOUBLE CIRCLED DIGIT SIX] - case 0x277B: // [DINGBAT NEGATIVE CIRCLED DIGIT SIX] - case 0x2785: // [DINGBAT CIRCLED SANS-SERIF DIGIT SIX] - case 0x278F: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX] - case 0xFF16: // [FULLWIDTH DIGIT SIX] - output[outputPos++] = L'6'; - break; - case 0x248D: // [DIGIT SIX FULL STOP] - output[outputPos++] = L'6'; - output[outputPos++] = L'.'; - break; - case 0x2479: // [PARENTHESIZED DIGIT SIX] - output[outputPos++] = L'('; - output[outputPos++] = L'6'; - output[outputPos++] = L')'; - break; - case 0x2077: // [SUPERSCRIPT SEVEN] - case 0x2087: // [SUBSCRIPT SEVEN] - case 0x2466: // [CIRCLED DIGIT SEVEN] - case 0x24FB: // [DOUBLE CIRCLED DIGIT SEVEN] - case 0x277C: // [DINGBAT NEGATIVE CIRCLED DIGIT SEVEN] - case 0x2786: // [DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN] - case 0x2790: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN] - case 0xFF17: // [FULLWIDTH DIGIT SEVEN] - output[outputPos++] = L'7'; - break; - case 0x248E: // [DIGIT SEVEN FULL STOP] - output[outputPos++] = L'7'; - output[outputPos++] = L'.'; - break; - case 0x247A: // [PARENTHESIZED DIGIT SEVEN] - output[outputPos++] = L'('; - output[outputPos++] = L'7'; - output[outputPos++] = L')'; - break; - case 0x2078: // [SUPERSCRIPT EIGHT] - case 0x2088: // [SUBSCRIPT EIGHT] - case 0x2467: // [CIRCLED DIGIT EIGHT] - case 0x24FC: // [DOUBLE CIRCLED DIGIT EIGHT] - case 0x277D: // [DINGBAT NEGATIVE CIRCLED DIGIT EIGHT] - case 0x2787: // [DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT] - case 0x2791: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT] - case 0xFF18: // [FULLWIDTH DIGIT EIGHT] - output[outputPos++] = L'8'; - break; - case 0x248F: // [DIGIT EIGHT FULL STOP] - output[outputPos++] = L'8'; - output[outputPos++] = L'.'; - break; - case 0x247B: // [PARENTHESIZED DIGIT EIGHT] - output[outputPos++] = L'('; - output[outputPos++] = L'8'; - output[outputPos++] = L')'; - break; - case 0x2079: // [SUPERSCRIPT NINE] - case 0x2089: // [SUBSCRIPT NINE] - case 0x2468: // [CIRCLED DIGIT NINE] - case 0x24FD: // [DOUBLE CIRCLED DIGIT NINE] - case 0x277E: // [DINGBAT NEGATIVE CIRCLED DIGIT NINE] - case 0x2788: // [DINGBAT CIRCLED SANS-SERIF DIGIT NINE] - case 0x2792: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE] - case 0xFF19: // [FULLWIDTH DIGIT NINE] - output[outputPos++] = L'9'; - break; - case 0x2490: // [DIGIT NINE FULL STOP] - output[outputPos++] = L'9'; - output[outputPos++] = L'.'; - break; - case 0x247C: // [PARENTHESIZED DIGIT NINE] - output[outputPos++] = L'('; - output[outputPos++] = L'9'; - output[outputPos++] = L')'; - break; - case 0x2469: // [CIRCLED NUMBER TEN] - case 0x24FE: // [DOUBLE CIRCLED NUMBER TEN] - case 0x277F: // [DINGBAT NEGATIVE CIRCLED NUMBER TEN] - case 0x2789: // [DINGBAT CIRCLED SANS-SERIF NUMBER TEN] - case 0x2793: // [DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'0'; - break; - case 0x2491: // [NUMBER TEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'0'; - output[outputPos++] = L'.'; - break; - case 0x247D: // [PARENTHESIZED NUMBER TEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'0'; - output[outputPos++] = L')'; - break; - case 0x246A: // [CIRCLED NUMBER ELEVEN] - case 0x24EB: // [NEGATIVE CIRCLED NUMBER ELEVEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'1'; - break; - case 0x2492: // [NUMBER ELEVEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'1'; - output[outputPos++] = L'.'; - break; - case 0x247E: // [PARENTHESIZED NUMBER ELEVEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'1'; - output[outputPos++] = L')'; - break; - case 0x246B: // [CIRCLED NUMBER TWELVE] - case 0x24EC: // [NEGATIVE CIRCLED NUMBER TWELVE] - output[outputPos++] = L'1'; - output[outputPos++] = L'2'; - break; - case 0x2493: // [NUMBER TWELVE FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'2'; - output[outputPos++] = L'.'; - break; - case 0x247F: // [PARENTHESIZED NUMBER TWELVE] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'2'; - output[outputPos++] = L')'; - break; - case 0x246C: // [CIRCLED NUMBER THIRTEEN] - case 0x24ED: // [NEGATIVE CIRCLED NUMBER THIRTEEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'3'; - break; - case 0x2494: // [NUMBER THIRTEEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'3'; - output[outputPos++] = L'.'; - break; - case 0x2480: // [PARENTHESIZED NUMBER THIRTEEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'3'; - output[outputPos++] = L')'; - break; - case 0x246D: // [CIRCLED NUMBER FOURTEEN] - case 0x24EE: // [NEGATIVE CIRCLED NUMBER FOURTEEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'4'; - break; - case 0x2495: // [NUMBER FOURTEEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'4'; - output[outputPos++] = L'.'; - break; - case 0x2481: // [PARENTHESIZED NUMBER FOURTEEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'4'; - output[outputPos++] = L')'; - break; - case 0x246E: // [CIRCLED NUMBER FIFTEEN] - case 0x24EF: // [NEGATIVE CIRCLED NUMBER FIFTEEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'5'; - break; - case 0x2496: // [NUMBER FIFTEEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'5'; - output[outputPos++] = L'.'; - break; - case 0x2482: // [PARENTHESIZED NUMBER FIFTEEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'5'; - output[outputPos++] = L')'; - break; - case 0x246F: // [CIRCLED NUMBER SIXTEEN] - case 0x24F0: // [NEGATIVE CIRCLED NUMBER SIXTEEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'6'; - break; - case 0x2497: // [NUMBER SIXTEEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'6'; - output[outputPos++] = L'.'; - break; - case 0x2483: // [PARENTHESIZED NUMBER SIXTEEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'6'; - output[outputPos++] = L')'; - break; - case 0x2470: // [CIRCLED NUMBER SEVENTEEN] - case 0x24F1: // [NEGATIVE CIRCLED NUMBER SEVENTEEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'7'; - break; - case 0x2498: // [NUMBER SEVENTEEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'7'; - output[outputPos++] = L'.'; - break; - case 0x2484: // [PARENTHESIZED NUMBER SEVENTEEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'7'; - output[outputPos++] = L')'; - break; - case 0x2471: // [CIRCLED NUMBER EIGHTEEN] - case 0x24F2: // [NEGATIVE CIRCLED NUMBER EIGHTEEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'8'; - break; - case 0x2499: // [NUMBER EIGHTEEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'8'; - output[outputPos++] = L'.'; - break; - case 0x2485: // [PARENTHESIZED NUMBER EIGHTEEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'8'; - output[outputPos++] = L')'; - break; - case 0x2472: // [CIRCLED NUMBER NINETEEN] - case 0x24F3: // [NEGATIVE CIRCLED NUMBER NINETEEN] - output[outputPos++] = L'1'; - output[outputPos++] = L'9'; - break; - case 0x249A: // [NUMBER NINETEEN FULL STOP] - output[outputPos++] = L'1'; - output[outputPos++] = L'9'; - output[outputPos++] = L'.'; - break; - case 0x2486: // [PARENTHESIZED NUMBER NINETEEN] - output[outputPos++] = L'('; - output[outputPos++] = L'1'; - output[outputPos++] = L'9'; - output[outputPos++] = L')'; - break; - case 0x2473: // [CIRCLED NUMBER TWENTY] - case 0x24F4: // [NEGATIVE CIRCLED NUMBER TWENTY] - output[outputPos++] = L'2'; - output[outputPos++] = L'0'; - break; - case 0x249B: // [NUMBER TWENTY FULL STOP] - output[outputPos++] = L'2'; - output[outputPos++] = L'0'; - output[outputPos++] = L'.'; - break; - case 0x2487: // [PARENTHESIZED NUMBER TWENTY] - output[outputPos++] = L'('; - output[outputPos++] = L'2'; - output[outputPos++] = L'0'; - output[outputPos++] = L')'; - break; - case 0x00AB: // [LEFT-POINTING DOUBLE ANGLE QUOTATION MARK] - case 0x00BB: // [RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK] - case 0x201C: // [LEFT DOUBLE QUOTATION MARK] - case 0x201D: // [RIGHT DOUBLE QUOTATION MARK] - case 0x201E: // [DOUBLE LOW-9 QUOTATION MARK] - case 0x2033: // [DOUBLE PRIME] - case 0x2036: // [REVERSED DOUBLE PRIME] - case 0x275D: // [HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT] - case 0x275E: // [HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT] - case 0x276E: // [HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT] - case 0x276F: // [HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT] - case 0xFF02: // [FULLWIDTH QUOTATION MARK] - output[outputPos++] = L'"'; - break; - case 0x2018: // [LEFT SINGLE QUOTATION MARK] - case 0x2019: // [RIGHT SINGLE QUOTATION MARK] - case 0x201A: // [SINGLE LOW-9 QUOTATION MARK] - case 0x201B: // [SINGLE HIGH-REVERSED-9 QUOTATION MARK] - case 0x2032: // [PRIME] - case 0x2035: // [REVERSED PRIME] - case 0x2039: // [SINGLE LEFT-POINTING ANGLE QUOTATION MARK] - case 0x203A: // [SINGLE RIGHT-POINTING ANGLE QUOTATION MARK] - case 0x275B: // [HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT] - case 0x275C: // [HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT] - case 0xFF07: // [FULLWIDTH APOSTROPHE] - output[outputPos++] = L'\''; - break; - case 0x2010: // [HYPHEN] - case 0x2011: // [NON-BREAKING HYPHEN] - case 0x2012: // [FIGURE DASH] - case 0x2013: // [EN DASH] - case 0x2014: // [EM DASH] - case 0x207B: // [SUPERSCRIPT MINUS] - case 0x208B: // [SUBSCRIPT MINUS] - case 0xFF0D: // [FULLWIDTH HYPHEN-MINUS] - output[outputPos++] = L'-'; - break; - case 0x2045: // [LEFT SQUARE BRACKET WITH QUILL] - case 0x2772: // [LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT] - case 0xFF3B: // [FULLWIDTH LEFT SQUARE BRACKET] - output[outputPos++] = L'['; - break; - case 0x2046: // [RIGHT SQUARE BRACKET WITH QUILL] - case 0x2773: // [LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT] - case 0xFF3D: // [FULLWIDTH RIGHT SQUARE BRACKET] - output[outputPos++] = L']'; - break; - case 0x207D: // [SUPERSCRIPT LEFT PARENTHESIS] - case 0x208D: // [SUBSCRIPT LEFT PARENTHESIS] - case 0x2768: // [MEDIUM LEFT PARENTHESIS ORNAMENT] - case 0x276A: // [MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT] - case 0xFF08: // [FULLWIDTH LEFT PARENTHESIS] - output[outputPos++] = L'('; - break; - case 0x2E28: // [LEFT DOUBLE PARENTHESIS] - output[outputPos++] = L'('; - output[outputPos++] = L'('; - break; - case 0x207E: // [SUPERSCRIPT RIGHT PARENTHESIS] - case 0x208E: // [SUBSCRIPT RIGHT PARENTHESIS] - case 0x2769: // [MEDIUM RIGHT PARENTHESIS ORNAMENT] - case 0x276B: // [MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT] - case 0xFF09: // [FULLWIDTH RIGHT PARENTHESIS] - output[outputPos++] = L')'; - break; - case 0x2E29: // [RIGHT DOUBLE PARENTHESIS] - output[outputPos++] = L')'; - output[outputPos++] = L')'; - break; - case 0x276C: // [MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT] - case 0x2770: // [HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT] - case 0xFF1C: // [FULLWIDTH LESS-THAN SIGN] - output[outputPos++] = L'<'; - break; - case 0x276D: // [MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT] - case 0x2771: // [HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT] - case 0xFF1E: // [FULLWIDTH GREATER-THAN SIGN] - output[outputPos++] = L'>'; - break; - case 0x2774: // [MEDIUM LEFT CURLY BRACKET ORNAMENT] - case 0xFF5B: // [FULLWIDTH LEFT CURLY BRACKET] - output[outputPos++] = L'{'; - break; - case 0x2775: // [MEDIUM RIGHT CURLY BRACKET ORNAMENT] - case 0xFF5D: // [FULLWIDTH RIGHT CURLY BRACKET] - output[outputPos++] = L'}'; - break; - case 0x207A: // [SUPERSCRIPT PLUS SIGN] - case 0x208A: // [SUBSCRIPT PLUS SIGN] - case 0xFF0B: // [FULLWIDTH PLUS SIGN] - output[outputPos++] = L'+'; - break; - case 0x207C: // [SUPERSCRIPT EQUALS SIGN] - case 0x208C: // [SUBSCRIPT EQUALS SIGN] - case 0xFF1D: // [FULLWIDTH EQUALS SIGN] - output[outputPos++] = L'='; - break; - case 0xFF01: // [FULLWIDTH EXCLAMATION MARK] - output[outputPos++] = L'!'; - break; - case 0x203C: // [DOUBLE EXCLAMATION MARK] - output[outputPos++] = L'!'; - output[outputPos++] = L'!'; - break; - case 0x2049: // [EXCLAMATION QUESTION MARK] - output[outputPos++] = L'!'; - output[outputPos++] = L'?'; - break; - case 0xFF03: // [FULLWIDTH NUMBER SIGN] - output[outputPos++] = L'#'; - break; - case 0xFF04: // [FULLWIDTH DOLLAR SIGN] - output[outputPos++] = L'$'; - break; - case 0x2052: // [COMMERCIAL MINUS SIGN] - case 0xFF05: // [FULLWIDTH PERCENT SIGN] - output[outputPos++] = L'%'; - break; - case 0xFF06: // [FULLWIDTH AMPERSAND] - output[outputPos++] = L'&'; - break; - case 0x204E: // [LOW ASTERISK] - case 0xFF0A: // [FULLWIDTH ASTERISK] - output[outputPos++] = L'*'; - break; - case 0xFF0C: // [FULLWIDTH COMMA] - output[outputPos++] = L','; - break; - case 0xFF0E: // [FULLWIDTH FULL STOP] - output[outputPos++] = L'.'; - break; - case 0x2044: // [FRACTION SLASH] - case 0xFF0F: // [FULLWIDTH SOLIDUS] - output[outputPos++] = L'/'; - break; - case 0xFF1A: // [FULLWIDTH COLON] - output[outputPos++] = L':'; - break; - case 0x204F: // [REVERSED SEMICOLON] - case 0xFF1B: // [FULLWIDTH SEMICOLON] - output[outputPos++] = L';'; - break; - case 0xFF1F: // [FULLWIDTH QUESTION MARK] - output[outputPos++] = L'?'; - break; - case 0x2047: // [DOUBLE QUESTION MARK] - output[outputPos++] = L'?'; - output[outputPos++] = L'?'; - break; - case 0x2048: // [QUESTION EXCLAMATION MARK] - output[outputPos++] = L'?'; - output[outputPos++] = L'!'; - break; - case 0xFF20: // [FULLWIDTH COMMERCIAL AT] - output[outputPos++] = L'@'; - break; - case 0xFF3C: // [FULLWIDTH REVERSE SOLIDUS] - output[outputPos++] = L'\\'; - break; - case 0x2038: // [CARET] - case 0xFF3E: // [FULLWIDTH CIRCUMFLEX ACCENT] - output[outputPos++] = L'^'; - break; - case 0xFF3F: // [FULLWIDTH LOW LINE] - output[outputPos++] = L'_'; - break; - case 0x2053: // [SWUNG DASH] - case 0xFF5E: // [FULLWIDTH TILDE] - output[outputPos++] = L'~'; - break; - default: - output[outputPos++] = c; - break; - } + break; } } } } + +} diff --git a/src/core/analysis/Analyzer.cpp b/src/core/analysis/Analyzer.cpp index fd211ebf..f7eb99ac 100644 --- a/src/core/analysis/Analyzer.cpp +++ b/src/core/analysis/Analyzer.cpp @@ -8,39 +8,33 @@ #include "Analyzer.h" #include "Fieldable.h" -namespace Lucene -{ - Analyzer::~Analyzer() - { - } - - TokenStreamPtr Analyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - return tokenStream(fieldName, reader); - } - - LuceneObjectPtr Analyzer::getPreviousTokenStream() - { - return tokenStreams.get(); - } - - void Analyzer::setPreviousTokenStream(const LuceneObjectPtr& stream) - { - tokenStreams.set(stream); - } - - int32_t Analyzer::getPositionIncrementGap(const String& fieldName) - { - return 0; - } - - int32_t Analyzer::getOffsetGap(const FieldablePtr& field) - { - return field->isTokenized() ? 1 : 0; - } - - void Analyzer::close() - { - tokenStreams.close(); - } +namespace Lucene { + +Analyzer::~Analyzer() { +} + +TokenStreamPtr Analyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + return tokenStream(fieldName, reader); +} + +LuceneObjectPtr Analyzer::getPreviousTokenStream() { + return tokenStreams.get(); +} + +void Analyzer::setPreviousTokenStream(const LuceneObjectPtr& stream) { + tokenStreams.set(stream); +} + +int32_t Analyzer::getPositionIncrementGap(const String& fieldName) { + return 0; +} + +int32_t Analyzer::getOffsetGap(const FieldablePtr& field) { + return field->isTokenized() ? 1 : 0; +} + +void Analyzer::close() { + tokenStreams.close(); +} + } diff --git a/src/core/analysis/BaseCharFilter.cpp b/src/core/analysis/BaseCharFilter.cpp index 1eb4c3dd..0681139f 100644 --- a/src/core/analysis/BaseCharFilter.cpp +++ b/src/core/analysis/BaseCharFilter.cpp @@ -8,65 +8,61 @@ #include "BaseCharFilter.h" #include "MiscUtils.h" -namespace Lucene -{ - BaseCharFilter::BaseCharFilter(const CharStreamPtr& in) : CharFilter(in) - { - size = 0; - } +namespace Lucene { - BaseCharFilter::~BaseCharFilter() - { - } +BaseCharFilter::BaseCharFilter(const CharStreamPtr& in) : CharFilter(in) { + size = 0; +} - int32_t BaseCharFilter::correct(int32_t currentOff) - { - if (!offsets || currentOff < offsets[0]) - return currentOff; +BaseCharFilter::~BaseCharFilter() { +} - int32_t hi = size - 1; - if (currentOff >= offsets[hi]) - return currentOff + diffs[hi]; +int32_t BaseCharFilter::correct(int32_t currentOff) { + if (!offsets || currentOff < offsets[0]) { + return currentOff; + } - int32_t lo = 0; - int32_t mid = -1; + int32_t hi = size - 1; + if (currentOff >= offsets[hi]) { + return currentOff + diffs[hi]; + } - while (hi >= lo) - { - mid = MiscUtils::unsignedShift(lo + hi, 1); - if (currentOff < offsets[mid]) - hi = mid - 1; - else if (currentOff > offsets[mid]) - lo = mid + 1; - else - return currentOff + diffs[mid]; - } + int32_t lo = 0; + int32_t mid = -1; - if (currentOff < offsets[mid]) - return mid == 0 ? currentOff : currentOff + diffs[mid - 1]; - else + while (hi >= lo) { + mid = MiscUtils::unsignedShift(lo + hi, 1); + if (currentOff < offsets[mid]) { + hi = mid - 1; + } else if (currentOff > offsets[mid]) { + lo = mid + 1; + } else { return currentOff + diffs[mid]; + } } - int32_t BaseCharFilter::getLastCumulativeDiff() - { - return !offsets ? 0 : diffs[size - 1]; + if (currentOff < offsets[mid]) { + return mid == 0 ? currentOff : currentOff + diffs[mid - 1]; + } else { + return currentOff + diffs[mid]; } +} - void BaseCharFilter::addOffCorrectMap(int32_t off, int32_t cumulativeDiff) - { - if (!offsets) - { - offsets = IntArray::newInstance(64); - diffs = IntArray::newInstance(64); - } - else if (size == offsets.size()) - { - offsets.resize(MiscUtils::getNextSize(offsets.size())); - diffs.resize(MiscUtils::getNextSize(diffs.size())); - } +int32_t BaseCharFilter::getLastCumulativeDiff() { + return !offsets ? 0 : diffs[size - 1]; +} - offsets[size] = off; - diffs[size++] = cumulativeDiff; +void BaseCharFilter::addOffCorrectMap(int32_t off, int32_t cumulativeDiff) { + if (!offsets) { + offsets = IntArray::newInstance(64); + diffs = IntArray::newInstance(64); + } else if (size == offsets.size()) { + offsets.resize(MiscUtils::getNextSize(offsets.size())); + diffs.resize(MiscUtils::getNextSize(diffs.size())); } + + offsets[size] = off; + diffs[size++] = cumulativeDiff; +} + } diff --git a/src/core/analysis/CachingTokenFilter.cpp b/src/core/analysis/CachingTokenFilter.cpp index cb11701f..1365705e 100644 --- a/src/core/analysis/CachingTokenFilter.cpp +++ b/src/core/analysis/CachingTokenFilter.cpp @@ -7,55 +7,51 @@ #include "LuceneInc.h" #include "CachingTokenFilter.h" -namespace Lucene -{ - CachingTokenFilter::CachingTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - } +namespace Lucene { + +CachingTokenFilter::CachingTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) { +} - CachingTokenFilter::~CachingTokenFilter() - { +CachingTokenFilter::~CachingTokenFilter() { +} + +bool CachingTokenFilter::incrementToken() { + if (!cache) { + // fill cache lazily + cache = Collection::newInstance(); + fillCache(); + iterator = cache.begin(); } - bool CachingTokenFilter::incrementToken() - { - if (!cache) - { - // fill cache lazily - cache = Collection::newInstance(); - fillCache(); - iterator = cache.begin(); - } - - if (iterator == cache.end()) - { - // the cache is exhausted, return false - return false; - } - - // Since the TokenFilter can be reset, the tokens need to be preserved as immutable. - restoreState(*iterator++); - return true; + if (iterator == cache.end()) { + // the cache is exhausted, return false + return false; } - void CachingTokenFilter::end() - { - if (finalState) - restoreState(finalState); + // Since the TokenFilter can be reset, the tokens need to be preserved as immutable. + restoreState(*iterator++); + return true; +} + +void CachingTokenFilter::end() { + if (finalState) { + restoreState(finalState); } +} - void CachingTokenFilter::reset() - { - if (cache) - iterator = cache.begin(); +void CachingTokenFilter::reset() { + if (cache) { + iterator = cache.begin(); } +} - void CachingTokenFilter::fillCache() - { - while (input->incrementToken()) - cache.add(captureState()); - // capture final state - input->end(); - finalState = captureState(); +void CachingTokenFilter::fillCache() { + while (input->incrementToken()) { + cache.add(captureState()); } + // capture final state + input->end(); + finalState = captureState(); +} + } diff --git a/src/core/analysis/CharArraySet.cpp b/src/core/analysis/CharArraySet.cpp index 33c88a44..5e36fda5 100644 --- a/src/core/analysis/CharArraySet.cpp +++ b/src/core/analysis/CharArraySet.cpp @@ -8,77 +8,66 @@ #include "CharArraySet.h" #include "StringUtils.h" -namespace Lucene -{ - CharArraySet::CharArraySet(bool ignoreCase) - { - this->ignoreCase = ignoreCase; - this->entries = HashSet::newInstance(); - } +namespace Lucene { + +CharArraySet::CharArraySet(bool ignoreCase) { + this->ignoreCase = ignoreCase; + this->entries = HashSet::newInstance(); +} - CharArraySet::CharArraySet(HashSet entries, bool ignoreCase) - { - this->ignoreCase = ignoreCase; - this->entries = HashSet::newInstance(); - if (entries) - { - for (HashSet::iterator entry = entries.begin(); entry != entries.end(); ++entry) - add(*entry); +CharArraySet::CharArraySet(HashSet entries, bool ignoreCase) { + this->ignoreCase = ignoreCase; + this->entries = HashSet::newInstance(); + if (entries) { + for (HashSet::iterator entry = entries.begin(); entry != entries.end(); ++entry) { + add(*entry); } } +} - CharArraySet::CharArraySet(Collection entries, bool ignoreCase) - { - this->ignoreCase = ignoreCase; - this->entries = HashSet::newInstance(); - if (entries) - { - for (Collection::iterator entry = entries.begin(); entry != entries.end(); ++entry) - add(*entry); +CharArraySet::CharArraySet(Collection entries, bool ignoreCase) { + this->ignoreCase = ignoreCase; + this->entries = HashSet::newInstance(); + if (entries) { + for (Collection::iterator entry = entries.begin(); entry != entries.end(); ++entry) { + add(*entry); } } +} - CharArraySet::~CharArraySet() - { - } +CharArraySet::~CharArraySet() { +} - bool CharArraySet::contains(const String& text) - { - return entries.contains(ignoreCase ? StringUtils::toLower(text) : text); - } +bool CharArraySet::contains(const String& text) { + return entries.contains(ignoreCase ? StringUtils::toLower(text) : text); +} - bool CharArraySet::contains(const wchar_t* text, int32_t offset, int32_t length) - { - return contains(String(text + offset, length)); - } +bool CharArraySet::contains(const wchar_t* text, int32_t offset, int32_t length) { + return contains(String(text + offset, length)); +} - bool CharArraySet::add(const String& text) - { - return entries.add(ignoreCase ? StringUtils::toLower(text) : text); - } +bool CharArraySet::add(const String& text) { + return entries.add(ignoreCase ? StringUtils::toLower(text) : text); +} - bool CharArraySet::add(CharArray text) - { - return add(String(text.get(), text.size())); - } +bool CharArraySet::add(CharArray text) { + return add(String(text.get(), text.size())); +} - int32_t CharArraySet::size() - { - return entries.size(); - } +int32_t CharArraySet::size() { + return entries.size(); +} - bool CharArraySet::isEmpty() - { - return entries.empty(); - } +bool CharArraySet::isEmpty() { + return entries.empty(); +} - HashSet::iterator CharArraySet::begin() - { - return entries.begin(); - } +HashSet::iterator CharArraySet::begin() { + return entries.begin(); +} + +HashSet::iterator CharArraySet::end() { + return entries.end(); +} - HashSet::iterator CharArraySet::end() - { - return entries.end(); - } } diff --git a/src/core/analysis/CharFilter.cpp b/src/core/analysis/CharFilter.cpp index 0f1f154c..eca8caf7 100644 --- a/src/core/analysis/CharFilter.cpp +++ b/src/core/analysis/CharFilter.cpp @@ -7,49 +7,41 @@ #include "LuceneInc.h" #include "CharFilter.h" -namespace Lucene -{ - CharFilter::CharFilter(const CharStreamPtr& in) - { - input = in; - } - - CharFilter::~CharFilter() - { - } - - int32_t CharFilter::correct(int32_t currentOff) - { - return currentOff; - } - - int32_t CharFilter::correctOffset(int32_t currentOff) - { - return input->correctOffset(correct(currentOff)); - } - - void CharFilter::close() - { - input->close(); - } - - int32_t CharFilter::read(wchar_t* buffer, int32_t offset, int32_t length) - { - return input->read(buffer, offset, length); - } - - bool CharFilter::markSupported() - { - return input->markSupported(); - } - - void CharFilter::mark(int32_t readAheadLimit) - { - input->mark(readAheadLimit); - } - - void CharFilter::reset() - { - input->reset(); - } +namespace Lucene { + +CharFilter::CharFilter(const CharStreamPtr& in) { + input = in; +} + +CharFilter::~CharFilter() { +} + +int32_t CharFilter::correct(int32_t currentOff) { + return currentOff; +} + +int32_t CharFilter::correctOffset(int32_t currentOff) { + return input->correctOffset(correct(currentOff)); +} + +void CharFilter::close() { + input->close(); +} + +int32_t CharFilter::read(wchar_t* buffer, int32_t offset, int32_t length) { + return input->read(buffer, offset, length); +} + +bool CharFilter::markSupported() { + return input->markSupported(); +} + +void CharFilter::mark(int32_t readAheadLimit) { + input->mark(readAheadLimit); +} + +void CharFilter::reset() { + input->reset(); +} + } diff --git a/src/core/analysis/CharReader.cpp b/src/core/analysis/CharReader.cpp index ef166eba..4356d893 100644 --- a/src/core/analysis/CharReader.cpp +++ b/src/core/analysis/CharReader.cpp @@ -7,51 +7,44 @@ #include "LuceneInc.h" #include "CharReader.h" -namespace Lucene -{ - CharReader::CharReader(const ReaderPtr& in) - { - input = in; - } +namespace Lucene { - CharReader::~CharReader() - { - } +CharReader::CharReader(const ReaderPtr& in) { + input = in; +} - CharStreamPtr CharReader::get(const ReaderPtr& input) - { - CharStreamPtr charStream(boost::dynamic_pointer_cast(input)); - return charStream ? charStream : newLucene(input); - } +CharReader::~CharReader() { +} - int32_t CharReader::correctOffset(int32_t currentOff) - { - return currentOff; - } +CharStreamPtr CharReader::get(const ReaderPtr& input) { + CharStreamPtr charStream(boost::dynamic_pointer_cast(input)); + return charStream ? charStream : newLucene(input); +} - void CharReader::close() - { - if (input) - input->close(); - } +int32_t CharReader::correctOffset(int32_t currentOff) { + return currentOff; +} - int32_t CharReader::read(wchar_t* buffer, int32_t offset, int32_t length) - { - return input->read(buffer, offset, length); +void CharReader::close() { + if (input) { + input->close(); } +} - bool CharReader::markSupported() - { - return input->markSupported(); - } +int32_t CharReader::read(wchar_t* buffer, int32_t offset, int32_t length) { + return input->read(buffer, offset, length); +} - void CharReader::mark(int32_t readAheadLimit) - { - input->mark(readAheadLimit); - } +bool CharReader::markSupported() { + return input->markSupported(); +} + +void CharReader::mark(int32_t readAheadLimit) { + input->mark(readAheadLimit); +} + +void CharReader::reset() { + input->reset(); +} - void CharReader::reset() - { - input->reset(); - } } diff --git a/src/core/analysis/CharStream.cpp b/src/core/analysis/CharStream.cpp index ecaeeec5..3c74f4f8 100644 --- a/src/core/analysis/CharStream.cpp +++ b/src/core/analysis/CharStream.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "CharStream.h" -namespace Lucene -{ - CharStream::~CharStream() - { - } +namespace Lucene { + +CharStream::~CharStream() { +} + } diff --git a/src/core/analysis/CharTokenizer.cpp b/src/core/analysis/CharTokenizer.cpp index a72a6e6f..5827dffd 100644 --- a/src/core/analysis/CharTokenizer.cpp +++ b/src/core/analysis/CharTokenizer.cpp @@ -10,112 +10,104 @@ #include "TermAttribute.h" #include "Reader.h" -namespace Lucene -{ - const int32_t CharTokenizer::MAX_WORD_LEN = 255; - const int32_t CharTokenizer::IO_BUFFER_SIZE = 4096; - - CharTokenizer::CharTokenizer(const ReaderPtr& input) : Tokenizer(input) - { - offset = 0; - bufferIndex = 0; - dataLen = 0; - ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - - offsetAtt = addAttribute(); - termAtt = addAttribute(); - } +namespace Lucene { - CharTokenizer::CharTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) - { - offset = 0; - bufferIndex = 0; - dataLen = 0; - ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); +const int32_t CharTokenizer::MAX_WORD_LEN = 255; +const int32_t CharTokenizer::IO_BUFFER_SIZE = 4096; - offsetAtt = addAttribute(); - termAtt = addAttribute(); - } +CharTokenizer::CharTokenizer(const ReaderPtr& input) : Tokenizer(input) { + offset = 0; + bufferIndex = 0; + dataLen = 0; + ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - CharTokenizer::CharTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) - { - offset = 0; - bufferIndex = 0; - dataLen = 0; - ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); + offsetAtt = addAttribute(); + termAtt = addAttribute(); +} - offsetAtt = addAttribute(); - termAtt = addAttribute(); - } +CharTokenizer::CharTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source, input) { + offset = 0; + bufferIndex = 0; + dataLen = 0; + ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); - CharTokenizer::~CharTokenizer() - { - } + offsetAtt = addAttribute(); + termAtt = addAttribute(); +} - wchar_t CharTokenizer::normalize(wchar_t c) - { - return c; - } +CharTokenizer::CharTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory, input) { + offset = 0; + bufferIndex = 0; + dataLen = 0; + ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); + + offsetAtt = addAttribute(); + termAtt = addAttribute(); +} + +CharTokenizer::~CharTokenizer() { +} + +wchar_t CharTokenizer::normalize(wchar_t c) { + return c; +} - bool CharTokenizer::incrementToken() - { - clearAttributes(); - int32_t length = 0; - int32_t start = bufferIndex; - CharArray buffer(termAtt->termBuffer()); - while (true) - { - if (bufferIndex >= dataLen) - { - offset += dataLen; - dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); - if (dataLen == -1) - { - dataLen = 0; // so next offset += dataLen won't decrement offset - if (length > 0) - break; - else - return false; +bool CharTokenizer::incrementToken() { + clearAttributes(); + int32_t length = 0; + int32_t start = bufferIndex; + CharArray buffer(termAtt->termBuffer()); + while (true) { + if (bufferIndex >= dataLen) { + offset += dataLen; + dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); + if (dataLen == -1) { + dataLen = 0; // so next offset += dataLen won't decrement offset + if (length > 0) { + break; + } else { + return false; } - bufferIndex = 0; } + bufferIndex = 0; + } - wchar_t c = ioBuffer[bufferIndex++]; + wchar_t c = ioBuffer[bufferIndex++]; - if (isTokenChar(c)) // if it's a token char - { - if (length == 0) - start = offset + bufferIndex - 1; - else if (length == buffer.size()) - buffer = termAtt->resizeTermBuffer(1 + length); + if (isTokenChar(c)) { // if it's a token char + if (length == 0) { + start = offset + bufferIndex - 1; + } else if (length == buffer.size()) { + buffer = termAtt->resizeTermBuffer(1 + length); + } - buffer[length++] = normalize(c); // buffer it, normalized + buffer[length++] = normalize(c); // buffer it, normalized - if (length == MAX_WORD_LEN) // buffer overflow! - break; + if (length == MAX_WORD_LEN) { // buffer overflow! + break; } - else if (length > 0) // at non-Letter with chars - break; // return them + } else if (length > 0) { // at non-Letter with chars + break; // return them } + } - termAtt->setTermLength(length); - offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); + termAtt->setTermLength(length); + offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); - return true; - } + return true; +} - void CharTokenizer::end() - { - // set final offset - int32_t finalOffset = correctOffset(offset); - offsetAtt->setOffset(finalOffset, finalOffset); - } +void CharTokenizer::end() { + // set final offset + int32_t finalOffset = correctOffset(offset); + offsetAtt->setOffset(finalOffset, finalOffset); +} + +void CharTokenizer::reset(const ReaderPtr& input) { + Tokenizer::reset(input); + bufferIndex = 0; + offset = 0; + dataLen = 0; +} - void CharTokenizer::reset(const ReaderPtr& input) - { - Tokenizer::reset(input); - bufferIndex = 0; - offset = 0; - dataLen = 0; - } } diff --git a/src/core/analysis/ISOLatin1AccentFilter.cpp b/src/core/analysis/ISOLatin1AccentFilter.cpp index d22d0244..4c31fe13 100644 --- a/src/core/analysis/ISOLatin1AccentFilter.cpp +++ b/src/core/analysis/ISOLatin1AccentFilter.cpp @@ -8,226 +8,219 @@ #include "ISOLatin1AccentFilter.h" #include "TermAttribute.h" -namespace Lucene -{ - ISOLatin1AccentFilter::ISOLatin1AccentFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - output = CharArray::newInstance(256); - outputPos = 0; - termAtt = addAttribute(); - } +namespace Lucene { - ISOLatin1AccentFilter::~ISOLatin1AccentFilter() - { - } +ISOLatin1AccentFilter::ISOLatin1AccentFilter(const TokenStreamPtr& input) : TokenFilter(input) { + output = CharArray::newInstance(256); + outputPos = 0; + termAtt = addAttribute(); +} + +ISOLatin1AccentFilter::~ISOLatin1AccentFilter() { +} - bool ISOLatin1AccentFilter::incrementToken() - { - if (input->incrementToken()) - { - wchar_t* buffer = termAtt->termBufferArray(); - int32_t length = termAtt->termLength(); +bool ISOLatin1AccentFilter::incrementToken() { + if (input->incrementToken()) { + wchar_t* buffer = termAtt->termBufferArray(); + int32_t length = termAtt->termLength(); - // If no characters actually require rewriting then we just return token as-is - for (int32_t i = 0; i < length; ++i) - { - wchar_t c = buffer[i]; - if (c >= 0x00c0 && c <= 0xfb06) - { - removeAccents(buffer, length); - termAtt->setTermBuffer(output.get(), 0, outputPos); - break; - } + // If no characters actually require rewriting then we just return token as-is + for (int32_t i = 0; i < length; ++i) { + wchar_t c = buffer[i]; + if (c >= 0x00c0 && c <= 0xfb06) { + removeAccents(buffer, length); + termAtt->setTermBuffer(output.get(), 0, outputPos); + break; } - return true; } - else - return false; + return true; + } else { + return false; } +} - void ISOLatin1AccentFilter::removeAccents(const wchar_t* input, int32_t length) - { - // Worst-case length required - int32_t maxSizeNeeded = 2 * length; +void ISOLatin1AccentFilter::removeAccents(const wchar_t* input, int32_t length) { + // Worst-case length required + int32_t maxSizeNeeded = 2 * length; - int32_t size = output.size(); - while (size < maxSizeNeeded) - size *= 2; + int32_t size = output.size(); + while (size < maxSizeNeeded) { + size *= 2; + } - if (size != output.size()) - output.resize(size); + if (size != output.size()) { + output.resize(size); + } - outputPos = 0; - int32_t pos = 0; + outputPos = 0; + int32_t pos = 0; - wchar_t* output = this->output.get(); + wchar_t* output = this->output.get(); - for (int32_t i = 0; i < length; ++i, ++pos) - { - wchar_t c = input[pos]; + for (int32_t i = 0; i < length; ++i, ++pos) { + wchar_t c = input[pos]; - // Quick test: if it's not in range then just keep current character - if (c < 0x00C0 || c > 0xFB06) + // Quick test: if it's not in range then just keep current character + if (c < 0x00C0 || c > 0xFB06) { + output[outputPos++] = c; + } else { + switch (c) { + case 0x00C0: + case 0x00C1: + case 0x00C2: + case 0x00C3: + case 0x00C4: + case 0x00C5: + output[outputPos++] = L'A'; + break; + case 0x00C6: + output[outputPos++] = L'A'; + output[outputPos++] = L'E'; + break; + case 0x00C7: + output[outputPos++] = L'C'; + break; + case 0x00C8: + case 0x00C9: + case 0x00CA: + case 0x00CB: + output[outputPos++] = L'E'; + break; + case 0x00CC: + case 0x00CD: + case 0x00CE: + case 0x00CF: + output[outputPos++] = L'I'; + break; + case 0x0132: + output[outputPos++] = L'I'; + output[outputPos++] = L'J'; + break; + case 0x00D0: + output[outputPos++] = L'D'; + break; + case 0x00D1: + output[outputPos++] = L'N'; + break; + case 0x00D2: + case 0x00D3: + case 0x00D4: + case 0x00D5: + case 0x00D6: + case 0x00D8: + output[outputPos++] = L'O'; + break; + case 0x0152: + output[outputPos++] = L'O'; + output[outputPos++] = L'E'; + break; + case 0x00DE: + output[outputPos++] = L'T'; + output[outputPos++] = L'H'; + break; + case 0x00D9: + case 0x00DA: + case 0x00DB: + case 0x00DC: + output[outputPos++] = L'U'; + break; + case 0x00DD: + case 0x0178: + output[outputPos++] = L'Y'; + break; + case 0x00E0: + case 0x00E1: + case 0x00E2: + case 0x00E3: + case 0x00E4: + case 0x00E5: + output[outputPos++] = L'a'; + break; + case 0x00E6: + output[outputPos++] = L'a'; + output[outputPos++] = L'e'; + break; + case 0x00E7: + output[outputPos++] = L'c'; + break; + case 0x00E8: + case 0x00E9: + case 0x00EA: + case 0x00EB: + output[outputPos++] = L'e'; + break; + case 0x00EC: + case 0x00ED: + case 0x00EE: + case 0x00EF: + output[outputPos++] = L'i'; + break; + case 0x0133: + output[outputPos++] = L'i'; + output[outputPos++] = L'j'; + break; + case 0x00F0: + output[outputPos++] = L'd'; + break; + case 0x00F1: + output[outputPos++] = L'n'; + break; + case 0x00F2: + case 0x00F3: + case 0x00F4: + case 0x00F5: + case 0x00F6: + case 0x00F8: + output[outputPos++] = L'o'; + break; + case 0x0153: + output[outputPos++] = L'o'; + output[outputPos++] = L'e'; + break; + case 0x00DF: + output[outputPos++] = L's'; + output[outputPos++] = L's'; + break; + case 0x00FE: + output[outputPos++] = L't'; + output[outputPos++] = L'h'; + break; + case 0x00F9: + case 0x00FA: + case 0x00FB: + case 0x00FC: + output[outputPos++] = L'u'; + break; + case 0x00FD: + case 0x00FF: + output[outputPos++] = L'y'; + break; + case 0xFB00: + output[outputPos++] = L'f'; + output[outputPos++] = L'f'; + break; + case 0xFB01: + output[outputPos++] = L'f'; + output[outputPos++] = L'i'; + break; + case 0xFB02: + output[outputPos++] = L'f'; + output[outputPos++] = L'l'; + break; + case 0xFB05: + output[outputPos++] = L'f'; + output[outputPos++] = L't'; + break; + case 0xFB06: + output[outputPos++] = L's'; + output[outputPos++] = L't'; + break; + default : output[outputPos++] = c; - else - { - switch (c) - { - case 0x00C0: - case 0x00C1: - case 0x00C2: - case 0x00C3: - case 0x00C4: - case 0x00C5: - output[outputPos++] = L'A'; - break; - case 0x00C6: - output[outputPos++] = L'A'; - output[outputPos++] = L'E'; - break; - case 0x00C7: - output[outputPos++] = L'C'; - break; - case 0x00C8: - case 0x00C9: - case 0x00CA: - case 0x00CB: - output[outputPos++] = L'E'; - break; - case 0x00CC: - case 0x00CD: - case 0x00CE: - case 0x00CF: - output[outputPos++] = L'I'; - break; - case 0x0132: - output[outputPos++] = L'I'; - output[outputPos++] = L'J'; - break; - case 0x00D0: - output[outputPos++] = L'D'; - break; - case 0x00D1: - output[outputPos++] = L'N'; - break; - case 0x00D2: - case 0x00D3: - case 0x00D4: - case 0x00D5: - case 0x00D6: - case 0x00D8: - output[outputPos++] = L'O'; - break; - case 0x0152: - output[outputPos++] = L'O'; - output[outputPos++] = L'E'; - break; - case 0x00DE: - output[outputPos++] = L'T'; - output[outputPos++] = L'H'; - break; - case 0x00D9: - case 0x00DA: - case 0x00DB: - case 0x00DC: - output[outputPos++] = L'U'; - break; - case 0x00DD: - case 0x0178: - output[outputPos++] = L'Y'; - break; - case 0x00E0: - case 0x00E1: - case 0x00E2: - case 0x00E3: - case 0x00E4: - case 0x00E5: - output[outputPos++] = L'a'; - break; - case 0x00E6: - output[outputPos++] = L'a'; - output[outputPos++] = L'e'; - break; - case 0x00E7: - output[outputPos++] = L'c'; - break; - case 0x00E8: - case 0x00E9: - case 0x00EA: - case 0x00EB: - output[outputPos++] = L'e'; - break; - case 0x00EC: - case 0x00ED: - case 0x00EE: - case 0x00EF: - output[outputPos++] = L'i'; - break; - case 0x0133: - output[outputPos++] = L'i'; - output[outputPos++] = L'j'; - break; - case 0x00F0: - output[outputPos++] = L'd'; - break; - case 0x00F1: - output[outputPos++] = L'n'; - break; - case 0x00F2: - case 0x00F3: - case 0x00F4: - case 0x00F5: - case 0x00F6: - case 0x00F8: - output[outputPos++] = L'o'; - break; - case 0x0153: - output[outputPos++] = L'o'; - output[outputPos++] = L'e'; - break; - case 0x00DF: - output[outputPos++] = L's'; - output[outputPos++] = L's'; - break; - case 0x00FE: - output[outputPos++] = L't'; - output[outputPos++] = L'h'; - break; - case 0x00F9: - case 0x00FA: - case 0x00FB: - case 0x00FC: - output[outputPos++] = L'u'; - break; - case 0x00FD: - case 0x00FF: - output[outputPos++] = L'y'; - break; - case 0xFB00: - output[outputPos++] = L'f'; - output[outputPos++] = L'f'; - break; - case 0xFB01: - output[outputPos++] = L'f'; - output[outputPos++] = L'i'; - break; - case 0xFB02: - output[outputPos++] = L'f'; - output[outputPos++] = L'l'; - break; - case 0xFB05: - output[outputPos++] = L'f'; - output[outputPos++] = L't'; - break; - case 0xFB06: - output[outputPos++] = L's'; - output[outputPos++] = L't'; - break; - default : - output[outputPos++] = c; - break; - } + break; } } } } + +} diff --git a/src/core/analysis/KeywordAnalyzer.cpp b/src/core/analysis/KeywordAnalyzer.cpp index 1d281746..3f19c83b 100644 --- a/src/core/analysis/KeywordAnalyzer.cpp +++ b/src/core/analysis/KeywordAnalyzer.cpp @@ -8,27 +8,24 @@ #include "KeywordAnalyzer.h" #include "KeywordTokenizer.h" -namespace Lucene -{ - KeywordAnalyzer::~KeywordAnalyzer() - { - } +namespace Lucene { - TokenStreamPtr KeywordAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(reader); - } +KeywordAnalyzer::~KeywordAnalyzer() { +} - TokenStreamPtr KeywordAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!tokenizer) - { - tokenizer = newLucene(reader); - setPreviousTokenStream(tokenizer); - } - else - tokenizer->reset(reader); - return tokenizer; +TokenStreamPtr KeywordAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(reader); +} + +TokenStreamPtr KeywordAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!tokenizer) { + tokenizer = newLucene(reader); + setPreviousTokenStream(tokenizer); + } else { + tokenizer->reset(reader); } + return tokenizer; +} + } diff --git a/src/core/analysis/KeywordTokenizer.cpp b/src/core/analysis/KeywordTokenizer.cpp index 64421a46..7d0d2ee7 100644 --- a/src/core/analysis/KeywordTokenizer.cpp +++ b/src/core/analysis/KeywordTokenizer.cpp @@ -10,77 +10,69 @@ #include "OffsetAttribute.h" #include "Reader.h" -namespace Lucene -{ - const int32_t KeywordTokenizer::DEFAULT_BUFFER_SIZE = 256; +namespace Lucene { - KeywordTokenizer::KeywordTokenizer(const ReaderPtr& input) : Tokenizer(input) - { - init(DEFAULT_BUFFER_SIZE); - } +const int32_t KeywordTokenizer::DEFAULT_BUFFER_SIZE = 256; - KeywordTokenizer::KeywordTokenizer(const ReaderPtr& input, int32_t bufferSize) : Tokenizer(input) - { - init(bufferSize); - } +KeywordTokenizer::KeywordTokenizer(const ReaderPtr& input) : Tokenizer(input) { + init(DEFAULT_BUFFER_SIZE); +} - KeywordTokenizer::KeywordTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input, int32_t bufferSize) : Tokenizer(source, input) - { - init(bufferSize); - } +KeywordTokenizer::KeywordTokenizer(const ReaderPtr& input, int32_t bufferSize) : Tokenizer(input) { + init(bufferSize); +} - KeywordTokenizer::KeywordTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input, int32_t bufferSize) : Tokenizer(factory, input) - { - init(bufferSize); - } +KeywordTokenizer::KeywordTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input, int32_t bufferSize) : Tokenizer(source, input) { + init(bufferSize); +} - KeywordTokenizer::~KeywordTokenizer() - { - } +KeywordTokenizer::KeywordTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input, int32_t bufferSize) : Tokenizer(factory, input) { + init(bufferSize); +} - void KeywordTokenizer::init(int32_t bufferSize) - { - this->done = false; - this->finalOffset = 0; - this->termAtt = addAttribute(); - this->offsetAtt = addAttribute(); - this->termAtt->resizeTermBuffer(bufferSize); - } +KeywordTokenizer::~KeywordTokenizer() { +} + +void KeywordTokenizer::init(int32_t bufferSize) { + this->done = false; + this->finalOffset = 0; + this->termAtt = addAttribute(); + this->offsetAtt = addAttribute(); + this->termAtt->resizeTermBuffer(bufferSize); +} - bool KeywordTokenizer::incrementToken() - { - if (!done) - { - clearAttributes(); - done = true; - int32_t upto = 0; - CharArray buffer(termAtt->termBuffer()); - while (true) - { - int32_t length = input->read(buffer.get(), upto, buffer.size() - upto); - if (length == -1) - break; - upto += length; - if (upto == buffer.size()) - buffer = termAtt->resizeTermBuffer(buffer.size() + 1); +bool KeywordTokenizer::incrementToken() { + if (!done) { + clearAttributes(); + done = true; + int32_t upto = 0; + CharArray buffer(termAtt->termBuffer()); + while (true) { + int32_t length = input->read(buffer.get(), upto, buffer.size() - upto); + if (length == -1) { + break; + } + upto += length; + if (upto == buffer.size()) { + buffer = termAtt->resizeTermBuffer(buffer.size() + 1); } - termAtt->setTermLength(upto); - finalOffset = correctOffset(upto); - offsetAtt->setOffset(correctOffset(0), finalOffset); - return true; } - return false; + termAtt->setTermLength(upto); + finalOffset = correctOffset(upto); + offsetAtt->setOffset(correctOffset(0), finalOffset); + return true; } + return false; +} - void KeywordTokenizer::end() - { - // set final offset - offsetAtt->setOffset(finalOffset, finalOffset); - } +void KeywordTokenizer::end() { + // set final offset + offsetAtt->setOffset(finalOffset, finalOffset); +} + +void KeywordTokenizer::reset() { + Tokenizer::reset(input); + done = false; +} - void KeywordTokenizer::reset() - { - Tokenizer::reset(input); - done = false; - } } diff --git a/src/core/analysis/LengthFilter.cpp b/src/core/analysis/LengthFilter.cpp index c9283683..28dfddab 100644 --- a/src/core/analysis/LengthFilter.cpp +++ b/src/core/analysis/LengthFilter.cpp @@ -8,30 +8,28 @@ #include "LengthFilter.h" #include "TermAttribute.h" -namespace Lucene -{ - LengthFilter::LengthFilter(const TokenStreamPtr& input, int32_t min, int32_t max) : TokenFilter(input) - { - this->min = min; - this->max = max; - this->termAtt = addAttribute(); - } +namespace Lucene { - LengthFilter::~LengthFilter() - { - } +LengthFilter::LengthFilter(const TokenStreamPtr& input, int32_t min, int32_t max) : TokenFilter(input) { + this->min = min; + this->max = max; + this->termAtt = addAttribute(); +} - bool LengthFilter::incrementToken() - { - // return the first non-stop word found - while (input->incrementToken()) - { - int32_t len = termAtt->termLength(); - if (len >= min && len <= max) - return true; - // note: else we ignore it but should we index each part of it? +LengthFilter::~LengthFilter() { +} + +bool LengthFilter::incrementToken() { + // return the first non-stop word found + while (input->incrementToken()) { + int32_t len = termAtt->termLength(); + if (len >= min && len <= max) { + return true; } - // reached EOS -- return false - return false; + // note: else we ignore it but should we index each part of it? } + // reached EOS -- return false + return false; +} + } diff --git a/src/core/analysis/LetterTokenizer.cpp b/src/core/analysis/LetterTokenizer.cpp index 60683057..953f8afd 100644 --- a/src/core/analysis/LetterTokenizer.cpp +++ b/src/core/analysis/LetterTokenizer.cpp @@ -9,26 +9,22 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - LetterTokenizer::LetterTokenizer(const ReaderPtr& input) : CharTokenizer(input) - { - } - - LetterTokenizer::LetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) - { - } - - LetterTokenizer::LetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) - { - } - - LetterTokenizer::~LetterTokenizer() - { - } - - bool LetterTokenizer::isTokenChar(wchar_t c) - { - return UnicodeUtil::isAlpha(c); - } +namespace Lucene { + +LetterTokenizer::LetterTokenizer(const ReaderPtr& input) : CharTokenizer(input) { +} + +LetterTokenizer::LetterTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) { +} + +LetterTokenizer::LetterTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) { +} + +LetterTokenizer::~LetterTokenizer() { +} + +bool LetterTokenizer::isTokenChar(wchar_t c) { + return UnicodeUtil::isAlpha(c); +} + } diff --git a/src/core/analysis/LowerCaseFilter.cpp b/src/core/analysis/LowerCaseFilter.cpp index 8fdb200c..2d4afd47 100644 --- a/src/core/analysis/LowerCaseFilter.cpp +++ b/src/core/analysis/LowerCaseFilter.cpp @@ -9,25 +9,22 @@ #include "TermAttribute.h" #include "CharFolder.h" -namespace Lucene -{ - LowerCaseFilter::LowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - termAtt = addAttribute(); - } +namespace Lucene { - LowerCaseFilter::~LowerCaseFilter() - { - } +LowerCaseFilter::LowerCaseFilter(const TokenStreamPtr& input) : TokenFilter(input) { + termAtt = addAttribute(); +} - bool LowerCaseFilter::incrementToken() - { - if (input->incrementToken()) - { - wchar_t* buffer = termAtt->termBufferArray(); - CharFolder::toLower(buffer, buffer + termAtt->termLength()); - return true; - } - return false; +LowerCaseFilter::~LowerCaseFilter() { +} + +bool LowerCaseFilter::incrementToken() { + if (input->incrementToken()) { + wchar_t* buffer = termAtt->termBufferArray(); + CharFolder::toLower(buffer, buffer + termAtt->termLength()); + return true; } + return false; +} + } diff --git a/src/core/analysis/LowerCaseTokenizer.cpp b/src/core/analysis/LowerCaseTokenizer.cpp index 3462efe2..71ff6556 100644 --- a/src/core/analysis/LowerCaseTokenizer.cpp +++ b/src/core/analysis/LowerCaseTokenizer.cpp @@ -8,26 +8,22 @@ #include "LowerCaseTokenizer.h" #include "CharFolder.h" -namespace Lucene -{ - LowerCaseTokenizer::LowerCaseTokenizer(const ReaderPtr& input) : LetterTokenizer(input) - { - } - - LowerCaseTokenizer::LowerCaseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : LetterTokenizer(source, input) - { - } - - LowerCaseTokenizer::LowerCaseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : LetterTokenizer(factory, input) - { - } - - LowerCaseTokenizer::~LowerCaseTokenizer() - { - } - - wchar_t LowerCaseTokenizer::normalize(wchar_t c) - { - return CharFolder::toLower(c); - } +namespace Lucene { + +LowerCaseTokenizer::LowerCaseTokenizer(const ReaderPtr& input) : LetterTokenizer(input) { +} + +LowerCaseTokenizer::LowerCaseTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : LetterTokenizer(source, input) { +} + +LowerCaseTokenizer::LowerCaseTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : LetterTokenizer(factory, input) { +} + +LowerCaseTokenizer::~LowerCaseTokenizer() { +} + +wchar_t LowerCaseTokenizer::normalize(wchar_t c) { + return CharFolder::toLower(c); +} + } diff --git a/src/core/analysis/MappingCharFilter.cpp b/src/core/analysis/MappingCharFilter.cpp index 0834c2d3..da8761cd 100644 --- a/src/core/analysis/MappingCharFilter.cpp +++ b/src/core/analysis/MappingCharFilter.cpp @@ -9,120 +9,118 @@ #include "NormalizeCharMap.h" #include "CharReader.h" -namespace Lucene -{ - MappingCharFilter::MappingCharFilter(const NormalizeCharMapPtr& normMap, const CharStreamPtr& in) : BaseCharFilter(in) - { - this->normMap = normMap; - this->charPointer = 0; - this->nextCharCounter = 0; - } +namespace Lucene { - MappingCharFilter::MappingCharFilter(const NormalizeCharMapPtr& normMap, const ReaderPtr& in) : BaseCharFilter(CharReader::get(in)) - { - this->normMap = normMap; - this->charPointer = 0; - this->nextCharCounter = 0; - } +MappingCharFilter::MappingCharFilter(const NormalizeCharMapPtr& normMap, const CharStreamPtr& in) : BaseCharFilter(in) { + this->normMap = normMap; + this->charPointer = 0; + this->nextCharCounter = 0; +} - MappingCharFilter::~MappingCharFilter() - { - } +MappingCharFilter::MappingCharFilter(const NormalizeCharMapPtr& normMap, const ReaderPtr& in) : BaseCharFilter(CharReader::get(in)) { + this->normMap = normMap; + this->charPointer = 0; + this->nextCharCounter = 0; +} + +MappingCharFilter::~MappingCharFilter() { +} - int32_t MappingCharFilter::read() - { - while (true) - { - if (charPointer < (int32_t)replacement.length()) - return (int32_t)replacement[charPointer++]; +int32_t MappingCharFilter::read() { + while (true) { + if (charPointer < (int32_t)replacement.length()) { + return (int32_t)replacement[charPointer++]; + } - int32_t firstChar = nextChar(); - if (firstChar == -1) - return -1; - NormalizeCharMapPtr nm(normMap->submap ? normMap->submap.get((wchar_t)firstChar) : NormalizeCharMapPtr()); - if (!nm) - return firstChar; - NormalizeCharMapPtr result(match(nm)); - if (!result) - return firstChar; - replacement = result->normStr; - charPointer = 0; - if (result->diff != 0) - { - int32_t prevCumulativeDiff = getLastCumulativeDiff(); - if (result->diff < 0) - { - for (int32_t i = 0; i < -result->diff; ++i) - addOffCorrectMap(nextCharCounter + i - prevCumulativeDiff, prevCumulativeDiff - 1 - i); + int32_t firstChar = nextChar(); + if (firstChar == -1) { + return -1; + } + NormalizeCharMapPtr nm(normMap->submap ? normMap->submap.get((wchar_t)firstChar) : NormalizeCharMapPtr()); + if (!nm) { + return firstChar; + } + NormalizeCharMapPtr result(match(nm)); + if (!result) { + return firstChar; + } + replacement = result->normStr; + charPointer = 0; + if (result->diff != 0) { + int32_t prevCumulativeDiff = getLastCumulativeDiff(); + if (result->diff < 0) { + for (int32_t i = 0; i < -result->diff; ++i) { + addOffCorrectMap(nextCharCounter + i - prevCumulativeDiff, prevCumulativeDiff - 1 - i); } - else - addOffCorrectMap(nextCharCounter - result->diff - prevCumulativeDiff, prevCumulativeDiff + result->diff); + } else { + addOffCorrectMap(nextCharCounter - result->diff - prevCumulativeDiff, prevCumulativeDiff + result->diff); } - } + } +} - int32_t MappingCharFilter::nextChar() - { - ++nextCharCounter; - if (buffer && !buffer.empty()) - return buffer.removeFirst(); - return input->read(); +int32_t MappingCharFilter::nextChar() { + ++nextCharCounter; + if (buffer && !buffer.empty()) { + return buffer.removeFirst(); } + return input->read(); +} - void MappingCharFilter::pushChar(int32_t c) - { - --nextCharCounter; - if (!buffer) - buffer = Collection::newInstance(); - buffer.add(0, (wchar_t)c); +void MappingCharFilter::pushChar(int32_t c) { + --nextCharCounter; + if (!buffer) { + buffer = Collection::newInstance(); } + buffer.add(0, (wchar_t)c); +} - void MappingCharFilter::pushLastChar(int32_t c) - { - if (!buffer) - buffer = Collection::newInstance(); - buffer.add((wchar_t)c); +void MappingCharFilter::pushLastChar(int32_t c) { + if (!buffer) { + buffer = Collection::newInstance(); } + buffer.add((wchar_t)c); +} - NormalizeCharMapPtr MappingCharFilter::match(const NormalizeCharMapPtr& map) - { - NormalizeCharMapPtr result; - if (map->submap) - { - int32_t chr = nextChar(); - if (chr != -1) - { - NormalizeCharMapPtr subMap(map->submap.get((wchar_t)chr)); - if (subMap) - result = match(subMap); - if (!result) - pushChar(chr); +NormalizeCharMapPtr MappingCharFilter::match(const NormalizeCharMapPtr& map) { + NormalizeCharMapPtr result; + if (map->submap) { + int32_t chr = nextChar(); + if (chr != -1) { + NormalizeCharMapPtr subMap(map->submap.get((wchar_t)chr)); + if (subMap) { + result = match(subMap); + } + if (!result) { + pushChar(chr); } } - if (!result) - result = map; - return result; } + if (!result) { + result = map; + } + return result; +} - int32_t MappingCharFilter::read(wchar_t* buffer, int32_t offset, int32_t length) - { - CharArray tmp(CharArray::newInstance(length)); - int32_t l = input->read(tmp.get(), 0, length); - if (l != -1) - { - for (int32_t i = 0; i < l; ++i) - pushLastChar(tmp[i]); +int32_t MappingCharFilter::read(wchar_t* buffer, int32_t offset, int32_t length) { + CharArray tmp(CharArray::newInstance(length)); + int32_t l = input->read(tmp.get(), 0, length); + if (l != -1) { + for (int32_t i = 0; i < l; ++i) { + pushLastChar(tmp[i]); } - l = 0; - for (int32_t i = offset; i < offset + length; ++i) - { - int32_t c = read(); - if (c == -1) - break; - buffer[i] = (wchar_t)c; - ++l; + } + l = 0; + for (int32_t i = offset; i < offset + length; ++i) { + int32_t c = read(); + if (c == -1) { + break; } - return l == 0 ? -1 : l; + buffer[i] = (wchar_t)c; + ++l; } + return l == 0 ? -1 : l; +} + } diff --git a/src/core/analysis/NormalizeCharMap.cpp b/src/core/analysis/NormalizeCharMap.cpp index ea2cd54c..df1a6af9 100644 --- a/src/core/analysis/NormalizeCharMap.cpp +++ b/src/core/analysis/NormalizeCharMap.cpp @@ -7,35 +7,33 @@ #include "LuceneInc.h" #include "NormalizeCharMap.h" -namespace Lucene -{ - NormalizeCharMap::NormalizeCharMap() - { - diff = 0; - } +namespace Lucene { - NormalizeCharMap::~NormalizeCharMap() - { - } +NormalizeCharMap::NormalizeCharMap() { + diff = 0; +} + +NormalizeCharMap::~NormalizeCharMap() { +} - void NormalizeCharMap::add(const String& singleMatch, const String& replacement) - { - NormalizeCharMapPtr currMap(shared_from_this()); - for (String::const_iterator c = singleMatch.begin(); c != singleMatch.end(); ++c) - { - if (!currMap->submap) - currMap->submap = MapCharNormalizeCharMap::newInstance(); - NormalizeCharMapPtr map(currMap->submap.get(*c)); - if (!map) - { - map = newLucene(); - currMap->submap.put(*c, map); - } - currMap = map; +void NormalizeCharMap::add(const String& singleMatch, const String& replacement) { + NormalizeCharMapPtr currMap(shared_from_this()); + for (String::const_iterator c = singleMatch.begin(); c != singleMatch.end(); ++c) { + if (!currMap->submap) { + currMap->submap = MapCharNormalizeCharMap::newInstance(); } - if (!currMap->normStr.empty()) - boost::throw_exception(RuntimeException(L"MappingCharFilter: there is already a mapping for " + singleMatch)); - currMap->normStr = replacement; - currMap->diff = (int32_t)(singleMatch.length() - replacement.length()); + NormalizeCharMapPtr map(currMap->submap.get(*c)); + if (!map) { + map = newLucene(); + currMap->submap.put(*c, map); + } + currMap = map; + } + if (!currMap->normStr.empty()) { + boost::throw_exception(RuntimeException(L"MappingCharFilter: there is already a mapping for " + singleMatch)); } + currMap->normStr = replacement; + currMap->diff = (int32_t)(singleMatch.length() - replacement.length()); +} + } diff --git a/src/core/analysis/NumericTokenStream.cpp b/src/core/analysis/NumericTokenStream.cpp index f510db38..06aacf01 100644 --- a/src/core/analysis/NumericTokenStream.cpp +++ b/src/core/analysis/NumericTokenStream.cpp @@ -12,135 +12,128 @@ #include "TypeAttribute.h" #include "PositionIncrementAttribute.h" -namespace Lucene -{ - NumericTokenStream::NumericTokenStream() - { - this->shift = 0; - this->valSize = 0; - this->termAtt = addAttribute(); - this->typeAtt = addAttribute(); - this->posIncrAtt = addAttribute(); - this->precisionStep = NumericUtils::PRECISION_STEP_DEFAULT; - } +namespace Lucene { + +NumericTokenStream::NumericTokenStream() { + this->shift = 0; + this->valSize = 0; + this->termAtt = addAttribute(); + this->typeAtt = addAttribute(); + this->posIncrAtt = addAttribute(); + this->precisionStep = NumericUtils::PRECISION_STEP_DEFAULT; +} - NumericTokenStream::NumericTokenStream(int32_t precisionStep) - { - this->shift = 0; - this->valSize = 0; - this->termAtt = addAttribute(); - this->typeAtt = addAttribute(); - this->posIncrAtt = addAttribute(); - this->precisionStep = precisionStep; - if (precisionStep < 1) - boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); +NumericTokenStream::NumericTokenStream(int32_t precisionStep) { + this->shift = 0; + this->valSize = 0; + this->termAtt = addAttribute(); + this->typeAtt = addAttribute(); + this->posIncrAtt = addAttribute(); + this->precisionStep = precisionStep; + if (precisionStep < 1) { + boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } +} - NumericTokenStream::NumericTokenStream(const AttributeSourcePtr& source, int32_t precisionStep) : TokenStream(source) - { - this->shift = 0; - this->valSize = 0; - this->termAtt = addAttribute(); - this->typeAtt = addAttribute(); - this->posIncrAtt = addAttribute(); - this->precisionStep = precisionStep; - if (precisionStep < 1) - boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); +NumericTokenStream::NumericTokenStream(const AttributeSourcePtr& source, int32_t precisionStep) : TokenStream(source) { + this->shift = 0; + this->valSize = 0; + this->termAtt = addAttribute(); + this->typeAtt = addAttribute(); + this->posIncrAtt = addAttribute(); + this->precisionStep = precisionStep; + if (precisionStep < 1) { + boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } +} - NumericTokenStream::NumericTokenStream(const AttributeFactoryPtr& factory, int32_t precisionStep) : TokenStream(factory) - { - this->shift = 0; - this->valSize = 0; - this->termAtt = addAttribute(); - this->typeAtt = addAttribute(); - this->posIncrAtt = addAttribute(); - this->precisionStep = precisionStep; - if (precisionStep < 1) - boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); +NumericTokenStream::NumericTokenStream(const AttributeFactoryPtr& factory, int32_t precisionStep) : TokenStream(factory) { + this->shift = 0; + this->valSize = 0; + this->termAtt = addAttribute(); + this->typeAtt = addAttribute(); + this->posIncrAtt = addAttribute(); + this->precisionStep = precisionStep; + if (precisionStep < 1) { + boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); } +} - NumericTokenStream::~NumericTokenStream() - { - } +NumericTokenStream::~NumericTokenStream() { +} - const String& NumericTokenStream::TOKEN_TYPE_FULL_PREC() - { - static String _TOKEN_TYPE_FULL_PREC(L"fullPrecNumeric"); - return _TOKEN_TYPE_FULL_PREC; - } +const String& NumericTokenStream::TOKEN_TYPE_FULL_PREC() { + static String _TOKEN_TYPE_FULL_PREC(L"fullPrecNumeric"); + return _TOKEN_TYPE_FULL_PREC; +} - const String& NumericTokenStream::TOKEN_TYPE_LOWER_PREC() - { - static String _TOKEN_TYPE_LOWER_PREC(L"lowerPrecNumeric"); - return _TOKEN_TYPE_LOWER_PREC; - } +const String& NumericTokenStream::TOKEN_TYPE_LOWER_PREC() { + static String _TOKEN_TYPE_LOWER_PREC(L"lowerPrecNumeric"); + return _TOKEN_TYPE_LOWER_PREC; +} - NumericTokenStreamPtr NumericTokenStream::setLongValue(int64_t value) - { - this->value = value; - valSize = 64; - shift = 0; - return shared_from_this(); - } +NumericTokenStreamPtr NumericTokenStream::setLongValue(int64_t value) { + this->value = value; + valSize = 64; + shift = 0; + return shared_from_this(); +} - NumericTokenStreamPtr NumericTokenStream::setIntValue(int32_t value) - { - this->value = (int64_t)value; - valSize = 32; - shift = 0; - return shared_from_this(); - } +NumericTokenStreamPtr NumericTokenStream::setIntValue(int32_t value) { + this->value = (int64_t)value; + valSize = 32; + shift = 0; + return shared_from_this(); +} - NumericTokenStreamPtr NumericTokenStream::setDoubleValue(double value) - { - this->value = (int64_t)value; - valSize = 64; - shift = 0; - return shared_from_this(); - } +NumericTokenStreamPtr NumericTokenStream::setDoubleValue(double value) { + this->value = (int64_t)value; + valSize = 64; + shift = 0; + return shared_from_this(); +} - void NumericTokenStream::reset() - { - if (valSize == 0) - boost::throw_exception(IllegalStateException(L"call setValue() before usage")); - shift = 0; +void NumericTokenStream::reset() { + if (valSize == 0) { + boost::throw_exception(IllegalStateException(L"call setValue() before usage")); } + shift = 0; +} - bool NumericTokenStream::incrementToken() - { - if (valSize == 0) - boost::throw_exception(IllegalStateException(L"call setValue() before usage")); - if (shift >= valSize) - return false; - - clearAttributes(); - CharArray buffer; - switch (valSize) - { - case 64: - buffer = termAtt->resizeTermBuffer(NumericUtils::BUF_SIZE_LONG); - termAtt->setTermLength(NumericUtils::longToPrefixCoded(value, shift, buffer)); - break; - case 32: - buffer = termAtt->resizeTermBuffer(NumericUtils::BUF_SIZE_INT); - termAtt->setTermLength(NumericUtils::intToPrefixCoded((int32_t)value, shift, buffer)); - break; - default: - // should not happen - boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); - } - - typeAtt->setType(shift == 0 ? TOKEN_TYPE_FULL_PREC() : TOKEN_TYPE_LOWER_PREC()); - posIncrAtt->setPositionIncrement(shift == 0 ? 1 : 0); - shift += precisionStep; - return true; +bool NumericTokenStream::incrementToken() { + if (valSize == 0) { + boost::throw_exception(IllegalStateException(L"call setValue() before usage")); + } + if (shift >= valSize) { + return false; } - String NumericTokenStream::toString() - { - StringStream buffer; - buffer << L"(numeric,valSize=" << valSize << L",precisionStep=" << precisionStep << L")"; - return buffer.str(); + clearAttributes(); + CharArray buffer; + switch (valSize) { + case 64: + buffer = termAtt->resizeTermBuffer(NumericUtils::BUF_SIZE_LONG); + termAtt->setTermLength(NumericUtils::longToPrefixCoded(value, shift, buffer)); + break; + case 32: + buffer = termAtt->resizeTermBuffer(NumericUtils::BUF_SIZE_INT); + termAtt->setTermLength(NumericUtils::intToPrefixCoded((int32_t)value, shift, buffer)); + break; + default: + // should not happen + boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); } + + typeAtt->setType(shift == 0 ? TOKEN_TYPE_FULL_PREC() : TOKEN_TYPE_LOWER_PREC()); + posIncrAtt->setPositionIncrement(shift == 0 ? 1 : 0); + shift += precisionStep; + return true; +} + +String NumericTokenStream::toString() { + StringStream buffer; + buffer << L"(numeric,valSize=" << valSize << L",precisionStep=" << precisionStep << L")"; + return buffer.str(); +} + } diff --git a/src/core/analysis/PerFieldAnalyzerWrapper.cpp b/src/core/analysis/PerFieldAnalyzerWrapper.cpp index 0d813b8e..bbbec3a1 100644 --- a/src/core/analysis/PerFieldAnalyzerWrapper.cpp +++ b/src/core/analysis/PerFieldAnalyzerWrapper.cpp @@ -8,65 +8,62 @@ #include "PerFieldAnalyzerWrapper.h" #include "Fieldable.h" -namespace Lucene -{ - PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer) - { - this->defaultAnalyzer = defaultAnalyzer; - this->analyzerMap = MapStringAnalyzer::newInstance(); - } +namespace Lucene { - PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer, MapStringAnalyzer fieldAnalyzers) - { - this->defaultAnalyzer = defaultAnalyzer; - this->analyzerMap = MapStringAnalyzer::newInstance(); - if (fieldAnalyzers) - analyzerMap.putAll(fieldAnalyzers.begin(), fieldAnalyzers.end()); - } +PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer) { + this->defaultAnalyzer = defaultAnalyzer; + this->analyzerMap = MapStringAnalyzer::newInstance(); +} - PerFieldAnalyzerWrapper::~PerFieldAnalyzerWrapper() - { +PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(const AnalyzerPtr& defaultAnalyzer, MapStringAnalyzer fieldAnalyzers) { + this->defaultAnalyzer = defaultAnalyzer; + this->analyzerMap = MapStringAnalyzer::newInstance(); + if (fieldAnalyzers) { + analyzerMap.putAll(fieldAnalyzers.begin(), fieldAnalyzers.end()); } +} - void PerFieldAnalyzerWrapper::addAnalyzer(const String& fieldName, const AnalyzerPtr& analyzer) - { - analyzerMap.put(fieldName, analyzer); - } +PerFieldAnalyzerWrapper::~PerFieldAnalyzerWrapper() { +} - TokenStreamPtr PerFieldAnalyzerWrapper::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - AnalyzerPtr analyzer(analyzerMap.get(fieldName)); - if (!analyzer) - analyzer = defaultAnalyzer; - return analyzer->tokenStream(fieldName, reader); - } +void PerFieldAnalyzerWrapper::addAnalyzer(const String& fieldName, const AnalyzerPtr& analyzer) { + analyzerMap.put(fieldName, analyzer); +} - TokenStreamPtr PerFieldAnalyzerWrapper::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - AnalyzerPtr analyzer(analyzerMap.get(fieldName)); - if (!analyzer) - analyzer = defaultAnalyzer; - return analyzer->reusableTokenStream(fieldName, reader); +TokenStreamPtr PerFieldAnalyzerWrapper::tokenStream(const String& fieldName, const ReaderPtr& reader) { + AnalyzerPtr analyzer(analyzerMap.get(fieldName)); + if (!analyzer) { + analyzer = defaultAnalyzer; } + return analyzer->tokenStream(fieldName, reader); +} - int32_t PerFieldAnalyzerWrapper::getPositionIncrementGap(const String& fieldName) - { - AnalyzerPtr analyzer(analyzerMap.get(fieldName)); - if (!analyzer) - analyzer = defaultAnalyzer; - return analyzer->getPositionIncrementGap(fieldName); +TokenStreamPtr PerFieldAnalyzerWrapper::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + AnalyzerPtr analyzer(analyzerMap.get(fieldName)); + if (!analyzer) { + analyzer = defaultAnalyzer; } + return analyzer->reusableTokenStream(fieldName, reader); +} - int32_t PerFieldAnalyzerWrapper::getOffsetGap(const FieldablePtr& field) - { - AnalyzerPtr analyzer(analyzerMap.get(field->name())); - if (!analyzer) - analyzer = defaultAnalyzer; - return analyzer->getOffsetGap(field); +int32_t PerFieldAnalyzerWrapper::getPositionIncrementGap(const String& fieldName) { + AnalyzerPtr analyzer(analyzerMap.get(fieldName)); + if (!analyzer) { + analyzer = defaultAnalyzer; } + return analyzer->getPositionIncrementGap(fieldName); +} - String PerFieldAnalyzerWrapper::toString() - { - return L"PerFieldAnalyzerWrapper(default=" + defaultAnalyzer->toString() + L")"; +int32_t PerFieldAnalyzerWrapper::getOffsetGap(const FieldablePtr& field) { + AnalyzerPtr analyzer(analyzerMap.get(field->name())); + if (!analyzer) { + analyzer = defaultAnalyzer; } + return analyzer->getOffsetGap(field); +} + +String PerFieldAnalyzerWrapper::toString() { + return L"PerFieldAnalyzerWrapper(default=" + defaultAnalyzer->toString() + L")"; +} + } diff --git a/src/core/analysis/PorterStemFilter.cpp b/src/core/analysis/PorterStemFilter.cpp index 8dff5257..0ae5689f 100644 --- a/src/core/analysis/PorterStemFilter.cpp +++ b/src/core/analysis/PorterStemFilter.cpp @@ -9,25 +9,25 @@ #include "PorterStemmer.h" #include "TermAttribute.h" -namespace Lucene -{ - PorterStemFilter::PorterStemFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - stemmer = newLucene(); - termAtt = addAttribute(); - } +namespace Lucene { - PorterStemFilter::~PorterStemFilter() - { - } +PorterStemFilter::PorterStemFilter(const TokenStreamPtr& input) : TokenFilter(input) { + stemmer = newLucene(); + termAtt = addAttribute(); +} + +PorterStemFilter::~PorterStemFilter() { +} - bool PorterStemFilter::incrementToken() - { - if (!input->incrementToken()) - return false; +bool PorterStemFilter::incrementToken() { + if (!input->incrementToken()) { + return false; + } - if (stemmer->stem(termAtt->termBuffer())) - termAtt->setTermBuffer(stemmer->getResultBuffer(), 0, stemmer->getResultLength()); - return true; + if (stemmer->stem(termAtt->termBuffer())) { + termAtt->setTermBuffer(stemmer->getResultBuffer(), 0, stemmer->getResultLength()); } + return true; +} + } diff --git a/src/core/analysis/PorterStemmer.cpp b/src/core/analysis/PorterStemmer.cpp index 855b47f6..8947eeff 100644 --- a/src/core/analysis/PorterStemmer.cpp +++ b/src/core/analysis/PorterStemmer.cpp @@ -7,482 +7,463 @@ #include "LuceneInc.h" #include "PorterStemmer.h" -namespace Lucene -{ - PorterStemmer::PorterStemmer() - { - b = NULL; - k = 0; - j = 0; - i = 0; - dirty = false; - } - - PorterStemmer::~PorterStemmer() - { - } +namespace Lucene { - bool PorterStemmer::stem(CharArray word) - { - return stem(word.get(), word.size() - 1); - } +PorterStemmer::PorterStemmer() { + b = NULL; + k = 0; + j = 0; + i = 0; + dirty = false; +} - bool PorterStemmer::stem(wchar_t* b, int32_t k) - { - this->b = b; - this->k = k; - this->j = 0; - this->i = k; - dirty = false; +PorterStemmer::~PorterStemmer() { +} - if (k <= 1) - return false; // DEPARTURE +bool PorterStemmer::stem(CharArray word) { + return stem(word.get(), word.size() - 1); +} - // With these lines, strings of length 1 or 2 don't go through the stemming process, although no mention - // is made of this in the published algorithm. Remove the line to match the published algorithm. - step1ab(); - step1c(); - step2(); - step3(); - step4(); - step5(); +bool PorterStemmer::stem(wchar_t* b, int32_t k) { + this->b = b; + this->k = k; + this->j = 0; + this->i = k; + dirty = false; - if (i != this->k) - dirty = true; - return dirty; + if (k <= 1) { + return false; // DEPARTURE } - wchar_t* PorterStemmer::getResultBuffer() - { - return b; + // With these lines, strings of length 1 or 2 don't go through the stemming process, although no mention + // is made of this in the published algorithm. Remove the line to match the published algorithm. + step1ab(); + step1c(); + step2(); + step3(); + step4(); + step5(); + + if (i != this->k) { + dirty = true; } + return dirty; +} + +wchar_t* PorterStemmer::getResultBuffer() { + return b; +} - int32_t PorterStemmer::getResultLength() - { - return k + 1; +int32_t PorterStemmer::getResultLength() { + return k + 1; +} + +bool PorterStemmer::cons(int32_t i) { + switch (b[i]) { + case L'a': + case L'e': + case L'i': + case L'o': + case L'u': + return false; + case L'y': + return (i == 0) ? true : !cons(i - 1); + default: + return true; } +} - bool PorterStemmer::cons(int32_t i) - { - switch (b[i]) - { - case L'a': - case L'e': - case L'i': - case L'o': - case L'u': - return false; - case L'y': - return (i == 0) ? true : !cons(i - 1); - default: - return true; +int32_t PorterStemmer::m() { + int32_t n = 0; + int32_t i = 0; + while (true) { + if (i > j) { + return n; + } + if (!cons(i)) { + break; } + ++i; } - - int32_t PorterStemmer::m() - { - int32_t n = 0; - int32_t i = 0; - while (true) - { - if (i > j) + ++i; + while (true) { + while (true) { + if (i > j) { return n; - if (!cons(i)) + } + if (cons(i)) { break; + } ++i; } ++i; - while (true) - { - while (true) - { - if (i > j) - return n; - if (cons(i)) - break; - ++i; + ++n; + while (true) { + if (i > j) { + return n; } - ++i; - ++n; - while (true) - { - if (i > j) - return n; - if (!cons(i)) - break; - ++i; + if (!cons(i)) { + break; } ++i; } + ++i; } +} - bool PorterStemmer::vowelinstem() - { - for (int32_t i = 0; i <= j; ++i) - { - if (!cons(i)) - return true; +bool PorterStemmer::vowelinstem() { + for (int32_t i = 0; i <= j; ++i) { + if (!cons(i)) { + return true; } - return false; } + return false; +} - bool PorterStemmer::doublec(int32_t j) - { - if (j < 1) - return false; - if (b[j] != b[j - 1]) - return false; - return cons(j); +bool PorterStemmer::doublec(int32_t j) { + if (j < 1) { + return false; } - - bool PorterStemmer::cvc(int32_t i) - { - if (i < 2 || !cons(i) || cons(i - 1) || !cons(i - 2)) - return false; - int32_t ch = b[i]; - if (ch == L'w' || ch == L'x' || ch == L'y') - return false; - return true; + if (b[j] != b[j - 1]) { + return false; } + return cons(j); +} - bool PorterStemmer::ends(const wchar_t* s) - { - int32_t length = s[0]; - if (s[length] != b[k]) - return false; // tiny speed-up - if (length > k + 1) - return false; - if (std::memcmp(b + k - length + 1, s + 1, length) != 0) - return false; - j = k - length; - return true; +bool PorterStemmer::cvc(int32_t i) { + if (i < 2 || !cons(i) || cons(i - 1) || !cons(i - 2)) { + return false; + } + int32_t ch = b[i]; + if (ch == L'w' || ch == L'x' || ch == L'y') { + return false; } + return true; +} - void PorterStemmer::setto(const wchar_t* s) - { - int32_t length = s[0]; - std::memmove(b + j + 1, s + 1, length); - k = j + length; - dirty = true; +bool PorterStemmer::ends(const wchar_t* s) { + int32_t length = s[0]; + if (s[length] != b[k]) { + return false; // tiny speed-up + } + if (length > k + 1) { + return false; + } + if (std::memcmp(b + k - length + 1, s + 1, length) != 0) { + return false; } + j = k - length; + return true; +} + +void PorterStemmer::setto(const wchar_t* s) { + int32_t length = s[0]; + std::memmove(b + j + 1, s + 1, length); + k = j + length; + dirty = true; +} - void PorterStemmer::r(const wchar_t* s) - { - if (m() > 0) - setto(s); +void PorterStemmer::r(const wchar_t* s) { + if (m() > 0) { + setto(s); } +} - void PorterStemmer::step1ab() - { - if (b[k] == L's') - { - if (ends(L"\04" L"sses")) - k -= 2; - else if (ends(L"\03" L"ies")) - setto(L"\01" L"i"); - else if (b[k - 1] != L's') - --k; - } - if (ends(L"\03" L"eed")) - { - if (m() > 0) - --k; - } - else if ((ends(L"\02" L"ed") || ends(L"\03" L"ing")) && vowelinstem()) - { - k = j; - if (ends(L"\02" L"at")) - setto(L"\03" L"ate"); - else if (ends(L"\02" L"bl")) - setto(L"\03" L"ble"); - else if (ends(L"\02" L"iz")) - setto(L"\03" L"ize"); - else if (doublec(k)) - { - --k; - int32_t ch = b[k]; - if (ch == L'l' || ch == L's' || ch == L'z') - ++k; +void PorterStemmer::step1ab() { + if (b[k] == L's') { + if (ends(L"\04" L"sses")) { + k -= 2; + } else if (ends(L"\03" L"ies")) { + setto(L"\01" L"i"); + } else if (b[k - 1] != L's') { + --k; + } + } + if (ends(L"\03" L"eed")) { + if (m() > 0) { + --k; + } + } else if ((ends(L"\02" L"ed") || ends(L"\03" L"ing")) && vowelinstem()) { + k = j; + if (ends(L"\02" L"at")) { + setto(L"\03" L"ate"); + } else if (ends(L"\02" L"bl")) { + setto(L"\03" L"ble"); + } else if (ends(L"\02" L"iz")) { + setto(L"\03" L"ize"); + } else if (doublec(k)) { + --k; + int32_t ch = b[k]; + if (ch == L'l' || ch == L's' || ch == L'z') { + ++k; } - else if (m() == 1 && cvc(k)) - setto(L"\01" L"e"); + } else if (m() == 1 && cvc(k)) { + setto(L"\01" L"e"); } } +} - void PorterStemmer::step1c() - { - if (ends(L"\01" L"y") && vowelinstem()) - { - b[k] = L'i'; - dirty = true; - } +void PorterStemmer::step1c() { + if (ends(L"\01" L"y") && vowelinstem()) { + b[k] = L'i'; + dirty = true; } +} - void PorterStemmer::step2() - { - if (k == 0) - return; - switch (b[k - 1]) - { - case L'a': - if (ends(L"\07" L"ational")) - { - r(L"\03" L"ate"); - break; - } - if (ends(L"\06" L"tional")) - { - r(L"\04" L"tion"); - break; - } - break; - case L'c': - if (ends(L"\04" L"enci")) - { - r(L"\04" L"ence"); - break; - } - if (ends(L"\04" L"anci")) - { - r(L"\04" L"ance"); - break; - } - break; - case L'e': - if (ends(L"\04" L"izer")) - { - r(L"\03" L"ize"); - break; - } - break; - case L'l': - if (ends(L"\03" L"bli")) // DEPARTURE - { - r(L"\03" L"ble"); - break; - } - if (ends(L"\04" L"alli")) - { - r(L"\02" L"al"); - break; - } - if (ends(L"\05" L"entli")) - { - r(L"\03" L"ent"); - break; - } - if (ends(L"\03" L"eli")) - { - r(L"\01" L"e"); - break; - } - if (ends(L"\05" L"ousli")) - { - r(L"\03" L"ous"); - break; - } - break; - case L'o': - if (ends(L"\07" L"ization")) - { - r(L"\03" L"ize"); - break; - } - if (ends(L"\05" L"ation")) - { - r(L"\03" L"ate"); - break; - } - if (ends(L"\04" L"ator")) - { - r(L"\03" L"ate"); - break; - } - break; - case L's': - if (ends(L"\05" L"alism")) - { - r(L"\02" L"al"); - break; - } - if (ends(L"\07" L"iveness")) - { - r(L"\03" L"ive"); - break; - } - if (ends(L"\07" L"fulness")) - { - r(L"\03" L"ful"); - break; - } - if (ends(L"\07" L"ousness")) - { - r(L"\03" L"ous"); - break; - } - break; - case L't': - if (ends(L"\05" L"aliti")) - { - r(L"\02" L"al"); - break; - } - if (ends(L"\05" L"iviti")) - { - r(L"\03" L"ive"); - break; - } - if (ends(L"\06" L"biliti")) - { - r(L"\03" L"ble"); - break; - } - break; - case L'g': - if (ends(L"\04" L"logi")) // DEPARTURE - { - r(L"\03" L"log"); - break; - } +void PorterStemmer::step2() { + if (k == 0) { + return; + } + switch (b[k - 1]) { + case L'a': + if (ends(L"\07" L"ational")) { + r(L"\03" L"ate"); + break; + } + if (ends(L"\06" L"tional")) { + r(L"\04" L"tion"); + break; + } + break; + case L'c': + if (ends(L"\04" L"enci")) { + r(L"\04" L"ence"); + break; + } + if (ends(L"\04" L"anci")) { + r(L"\04" L"ance"); + break; + } + break; + case L'e': + if (ends(L"\04" L"izer")) { + r(L"\03" L"ize"); + break; + } + break; + case L'l': + if (ends(L"\03" L"bli")) { // DEPARTURE + r(L"\03" L"ble"); + break; + } + if (ends(L"\04" L"alli")) { + r(L"\02" L"al"); + break; + } + if (ends(L"\05" L"entli")) { + r(L"\03" L"ent"); + break; + } + if (ends(L"\03" L"eli")) { + r(L"\01" L"e"); + break; + } + if (ends(L"\05" L"ousli")) { + r(L"\03" L"ous"); + break; + } + break; + case L'o': + if (ends(L"\07" L"ization")) { + r(L"\03" L"ize"); + break; + } + if (ends(L"\05" L"ation")) { + r(L"\03" L"ate"); + break; + } + if (ends(L"\04" L"ator")) { + r(L"\03" L"ate"); + break; + } + break; + case L's': + if (ends(L"\05" L"alism")) { + r(L"\02" L"al"); + break; + } + if (ends(L"\07" L"iveness")) { + r(L"\03" L"ive"); + break; + } + if (ends(L"\07" L"fulness")) { + r(L"\03" L"ful"); + break; + } + if (ends(L"\07" L"ousness")) { + r(L"\03" L"ous"); + break; + } + break; + case L't': + if (ends(L"\05" L"aliti")) { + r(L"\02" L"al"); + break; + } + if (ends(L"\05" L"iviti")) { + r(L"\03" L"ive"); + break; + } + if (ends(L"\06" L"biliti")) { + r(L"\03" L"ble"); + break; + } + break; + case L'g': + if (ends(L"\04" L"logi")) { // DEPARTURE + r(L"\03" L"log"); + break; } } +} - void PorterStemmer::step3() - { - switch (b[k]) - { - case L'e': - if (ends(L"\05" L"icate")) - { - r(L"\02" L"ic"); - break; - } - if (ends(L"\05" L"ative")) - { - r(L"\00" L""); - break; - } - if (ends(L"\05" L"alize")) - { - r(L"\02" L"al"); - break; - } - break; - case L'i': - if (ends(L"\05" L"iciti")) - { - r(L"\02" L"ic"); - break; - } - break; - case L'l': - if (ends(L"\04" L"ical")) - { - r(L"\02" L"ic"); - break; - } - if (ends(L"\03" L"ful")) - { - r(L"\00" L""); - break; - } - break; - case L's': - if (ends(L"\04" L"ness")) - { - r(L"\00" L""); - break; - } - break; +void PorterStemmer::step3() { + switch (b[k]) { + case L'e': + if (ends(L"\05" L"icate")) { + r(L"\02" L"ic"); + break; + } + if (ends(L"\05" L"ative")) { + r(L"\00" L""); + break; + } + if (ends(L"\05" L"alize")) { + r(L"\02" L"al"); + break; } + break; + case L'i': + if (ends(L"\05" L"iciti")) { + r(L"\02" L"ic"); + break; + } + break; + case L'l': + if (ends(L"\04" L"ical")) { + r(L"\02" L"ic"); + break; + } + if (ends(L"\03" L"ful")) { + r(L"\00" L""); + break; + } + break; + case L's': + if (ends(L"\04" L"ness")) { + r(L"\00" L""); + break; + } + break; } +} - void PorterStemmer::step4() - { - if (k == 0) - return; - switch (b[k - 1]) - { - case L'a': - if (ends(L"\02" L"al")) - break; - return; - case L'c': - if (ends(L"\04" L"ance")) - break; - if (ends(L"\04" L"ence")) - break; - return; - case L'e': - if (ends(L"\02" L"er")) - break; - return; - case L'i': - if (ends(L"\02" L"ic")) - break; - return; - case L'l': - if (ends(L"\04" L"able")) - break; - if (ends(L"\04" L"ible")) - break; - return; - case L'n': - if (ends(L"\03" L"ant")) - break; - if (ends(L"\05" L"ement")) - break; - if (ends(L"\04" L"ment")) - break; - if (ends(L"\03" L"ent")) - break; - return; - case L'o': - if (ends(L"\03" L"ion") && (b[j] == L's' || b[j] == L't')) - break; - if (ends(L"\02" L"ou")) - break; - return; - // takes care of -ous - case L's': - if (ends(L"\03" L"ism")) - break; - return; - case L't': - if (ends(L"\03" L"ate")) - break; - if (ends(L"\03" L"iti")) - break; - return; - case L'u': - if (ends(L"\03" L"ous")) - break; - return; - case L'v': - if (ends(L"\03" L"ive")) - break; - return; - case L'z': - if (ends(L"\03" L"ize")) - break; - return; - default: - return; - } - if (m() > 1) - k = j; +void PorterStemmer::step4() { + if (k == 0) { + return; } + switch (b[k - 1]) { + case L'a': + if (ends(L"\02" L"al")) { + break; + } + return; + case L'c': + if (ends(L"\04" L"ance")) { + break; + } + if (ends(L"\04" L"ence")) { + break; + } + return; + case L'e': + if (ends(L"\02" L"er")) { + break; + } + return; + case L'i': + if (ends(L"\02" L"ic")) { + break; + } + return; + case L'l': + if (ends(L"\04" L"able")) { + break; + } + if (ends(L"\04" L"ible")) { + break; + } + return; + case L'n': + if (ends(L"\03" L"ant")) { + break; + } + if (ends(L"\05" L"ement")) { + break; + } + if (ends(L"\04" L"ment")) { + break; + } + if (ends(L"\03" L"ent")) { + break; + } + return; + case L'o': + if (ends(L"\03" L"ion") && (b[j] == L's' || b[j] == L't')) { + break; + } + if (ends(L"\02" L"ou")) { + break; + } + return; + // takes care of -ous + case L's': + if (ends(L"\03" L"ism")) { + break; + } + return; + case L't': + if (ends(L"\03" L"ate")) { + break; + } + if (ends(L"\03" L"iti")) { + break; + } + return; + case L'u': + if (ends(L"\03" L"ous")) { + break; + } + return; + case L'v': + if (ends(L"\03" L"ive")) { + break; + } + return; + case L'z': + if (ends(L"\03" L"ize")) { + break; + } + return; + default: + return; + } + if (m() > 1) { + k = j; + } +} - void PorterStemmer::step5() - { - j = k; - if (b[k] == L'e') - { - int32_t a = m(); - if (a > 1 || (a == 1 && !cvc(k - 1))) - --k; - } - if (b[k] == L'l' && doublec(k) && m() > 1) +void PorterStemmer::step5() { + j = k; + if (b[k] == L'e') { + int32_t a = m(); + if (a > 1 || (a == 1 && !cvc(k - 1))) { --k; + } } + if (b[k] == L'l' && doublec(k) && m() > 1) { + --k; + } +} + } diff --git a/src/core/analysis/SimpleAnalyzer.cpp b/src/core/analysis/SimpleAnalyzer.cpp index 99798299..49f55902 100644 --- a/src/core/analysis/SimpleAnalyzer.cpp +++ b/src/core/analysis/SimpleAnalyzer.cpp @@ -8,27 +8,24 @@ #include "SimpleAnalyzer.h" #include "LowerCaseTokenizer.h" -namespace Lucene -{ - SimpleAnalyzer::~SimpleAnalyzer() - { - } +namespace Lucene { - TokenStreamPtr SimpleAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(reader); - } +SimpleAnalyzer::~SimpleAnalyzer() { +} - TokenStreamPtr SimpleAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!tokenizer) - { - tokenizer = newLucene(reader); - setPreviousTokenStream(tokenizer); - } - else - tokenizer->reset(reader); - return tokenizer; +TokenStreamPtr SimpleAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(reader); +} + +TokenStreamPtr SimpleAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!tokenizer) { + tokenizer = newLucene(reader); + setPreviousTokenStream(tokenizer); + } else { + tokenizer->reset(reader); } + return tokenizer; +} + } diff --git a/src/core/analysis/StopAnalyzer.cpp b/src/core/analysis/StopAnalyzer.cpp index 51dd7024..3538031b 100644 --- a/src/core/analysis/StopAnalyzer.cpp +++ b/src/core/analysis/StopAnalyzer.cpp @@ -12,73 +12,64 @@ #include "Reader.h" #include "LowerCaseTokenizer.h" -namespace Lucene -{ - const wchar_t* StopAnalyzer::_ENGLISH_STOP_WORDS_SET[] = - { - L"a", L"an", L"and", L"are", L"as", L"at", L"be", L"but", L"by", - L"for", L"if", L"in", L"into", L"is", L"it", L"no", L"not", L"of", - L"on", L"or", L"such", L"that", L"the", L"their", L"then", L"there", - L"these", L"they", L"this", L"to", L"was", L"will", L"with" - }; +namespace Lucene { - StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion) - { - stopWords = ENGLISH_STOP_WORDS_SET(); - enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); - } +const wchar_t* StopAnalyzer::_ENGLISH_STOP_WORDS_SET[] = { + L"a", L"an", L"and", L"are", L"as", L"at", L"be", L"but", L"by", + L"for", L"if", L"in", L"into", L"is", L"it", L"no", L"not", L"of", + L"on", L"or", L"such", L"that", L"the", L"their", L"then", L"there", + L"these", L"they", L"this", L"to", L"was", L"will", L"with" +}; - StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords) - { - this->stopWords = stopWords; - enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); - } +StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion) { + stopWords = ENGLISH_STOP_WORDS_SET(); + enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); +} - StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, const String& stopwordsFile) - { - stopWords = WordlistLoader::getWordSet(stopwordsFile); - enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); - } +StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords) { + this->stopWords = stopWords; + enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); +} - StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords) - { - stopWords = WordlistLoader::getWordSet(stopwords); - enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); - } +StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, const String& stopwordsFile) { + stopWords = WordlistLoader::getWordSet(stopwordsFile); + enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); +} - StopAnalyzer::~StopAnalyzer() - { - } +StopAnalyzer::StopAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords) { + stopWords = WordlistLoader::getWordSet(stopwords); + enablePositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); +} - const HashSet StopAnalyzer::ENGLISH_STOP_WORDS_SET() - { - static HashSet __ENGLISH_STOP_WORDS_SET; - if (!__ENGLISH_STOP_WORDS_SET) - __ENGLISH_STOP_WORDS_SET = HashSet::newInstance(_ENGLISH_STOP_WORDS_SET, _ENGLISH_STOP_WORDS_SET + SIZEOF_ARRAY(_ENGLISH_STOP_WORDS_SET)); - return __ENGLISH_STOP_WORDS_SET; - } +StopAnalyzer::~StopAnalyzer() { +} - TokenStreamPtr StopAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(enablePositionIncrements, newLucene(reader), stopWords); +const HashSet StopAnalyzer::ENGLISH_STOP_WORDS_SET() { + static HashSet __ENGLISH_STOP_WORDS_SET; + if (!__ENGLISH_STOP_WORDS_SET) { + __ENGLISH_STOP_WORDS_SET = HashSet::newInstance(_ENGLISH_STOP_WORDS_SET, _ENGLISH_STOP_WORDS_SET + SIZEOF_ARRAY(_ENGLISH_STOP_WORDS_SET)); } + return __ENGLISH_STOP_WORDS_SET; +} - TokenStreamPtr StopAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - StopAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!streams) - { - streams = newLucene(); - streams->source = newLucene(reader); - streams->result = newLucene(enablePositionIncrements, streams->source, stopWords); - setPreviousTokenStream(streams); - } - else - streams->source->reset(reader); - return streams->result; - } +TokenStreamPtr StopAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(enablePositionIncrements, newLucene(reader), stopWords); +} - StopAnalyzerSavedStreams::~StopAnalyzerSavedStreams() - { +TokenStreamPtr StopAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + StopAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(reader); + streams->result = newLucene(enablePositionIncrements, streams->source, stopWords); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); } + return streams->result; +} + +StopAnalyzerSavedStreams::~StopAnalyzerSavedStreams() { +} + } diff --git a/src/core/analysis/StopFilter.cpp b/src/core/analysis/StopFilter.cpp index 6ac29215..5cfa6c50 100644 --- a/src/core/analysis/StopFilter.cpp +++ b/src/core/analysis/StopFilter.cpp @@ -10,63 +10,55 @@ #include "TermAttribute.h" #include "PositionIncrementAttribute.h" -namespace Lucene -{ - StopFilter::StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, HashSet stopWords, bool ignoreCase) : TokenFilter(input) - { - this->stopWords = newLucene(stopWords, ignoreCase); - this->enablePositionIncrements = enablePositionIncrements; - termAtt = addAttribute(); - posIncrAtt = addAttribute(); - } +namespace Lucene { - StopFilter::StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, const CharArraySetPtr& stopWords, bool ignoreCase) : TokenFilter(input) - { - this->stopWords = stopWords; - this->enablePositionIncrements = enablePositionIncrements; - termAtt = addAttribute(); - posIncrAtt = addAttribute(); - } +StopFilter::StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, HashSet stopWords, bool ignoreCase) : TokenFilter(input) { + this->stopWords = newLucene(stopWords, ignoreCase); + this->enablePositionIncrements = enablePositionIncrements; + termAtt = addAttribute(); + posIncrAtt = addAttribute(); +} - StopFilter::~StopFilter() - { - } +StopFilter::StopFilter(bool enablePositionIncrements, const TokenStreamPtr& input, const CharArraySetPtr& stopWords, bool ignoreCase) : TokenFilter(input) { + this->stopWords = stopWords; + this->enablePositionIncrements = enablePositionIncrements; + termAtt = addAttribute(); + posIncrAtt = addAttribute(); +} - HashSet StopFilter::makeStopSet(Collection stopWords) - { - return HashSet::newInstance(stopWords.begin(), stopWords.end()); - } +StopFilter::~StopFilter() { +} + +HashSet StopFilter::makeStopSet(Collection stopWords) { + return HashSet::newInstance(stopWords.begin(), stopWords.end()); +} - bool StopFilter::incrementToken() - { - // return the first non-stop word found - int32_t skippedPositions = 0; - while (input->incrementToken()) - { - if (!stopWords->contains(termAtt->termBufferArray(), 0, termAtt->termLength())) - { - if (enablePositionIncrements) - posIncrAtt->setPositionIncrement(posIncrAtt->getPositionIncrement() + skippedPositions); - return true; +bool StopFilter::incrementToken() { + // return the first non-stop word found + int32_t skippedPositions = 0; + while (input->incrementToken()) { + if (!stopWords->contains(termAtt->termBufferArray(), 0, termAtt->termLength())) { + if (enablePositionIncrements) { + posIncrAtt->setPositionIncrement(posIncrAtt->getPositionIncrement() + skippedPositions); } - skippedPositions += posIncrAtt->getPositionIncrement(); + return true; } - // reached EOS -- return false - return false; + skippedPositions += posIncrAtt->getPositionIncrement(); } + // reached EOS -- return false + return false; +} - bool StopFilter::getEnablePositionIncrementsVersionDefault(LuceneVersion::Version matchVersion) - { - return LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_29); - } +bool StopFilter::getEnablePositionIncrementsVersionDefault(LuceneVersion::Version matchVersion) { + return LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_29); +} - bool StopFilter::getEnablePositionIncrements() - { - return enablePositionIncrements; - } +bool StopFilter::getEnablePositionIncrements() { + return enablePositionIncrements; +} + +void StopFilter::setEnablePositionIncrements(bool enable) { + this->enablePositionIncrements = enable; +} - void StopFilter::setEnablePositionIncrements(bool enable) - { - this->enablePositionIncrements = enable; - } } diff --git a/src/core/analysis/TeeSinkTokenFilter.cpp b/src/core/analysis/TeeSinkTokenFilter.cpp index 3f36ec79..a9d7257a 100644 --- a/src/core/analysis/TeeSinkTokenFilter.cpp +++ b/src/core/analysis/TeeSinkTokenFilter.cpp @@ -8,162 +8,142 @@ #include "TeeSinkTokenFilter.h" #include "Attribute.h" -namespace Lucene -{ - TeeSinkTokenFilter::TeeSinkTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - this->sinks = Collection::newInstance(); - } +namespace Lucene { - TeeSinkTokenFilter::~TeeSinkTokenFilter() - { - } +TeeSinkTokenFilter::TeeSinkTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) { + this->sinks = Collection::newInstance(); +} - SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream() - { - static SinkFilterPtr ACCEPT_ALL_FILTER; - if (!ACCEPT_ALL_FILTER) - { - ACCEPT_ALL_FILTER = newLucene(); - CycleCheck::addStatic(ACCEPT_ALL_FILTER); - } - return newSinkTokenStream(ACCEPT_ALL_FILTER); - } +TeeSinkTokenFilter::~TeeSinkTokenFilter() { +} - SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream(const SinkFilterPtr& filter) - { - SinkTokenStreamPtr sink(newLucene(this->cloneAttributes(), filter)); - this->sinks.add(sink); - return sink; +SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream() { + static SinkFilterPtr ACCEPT_ALL_FILTER; + if (!ACCEPT_ALL_FILTER) { + ACCEPT_ALL_FILTER = newLucene(); + CycleCheck::addStatic(ACCEPT_ALL_FILTER); } + return newSinkTokenStream(ACCEPT_ALL_FILTER); +} + +SinkTokenStreamPtr TeeSinkTokenFilter::newSinkTokenStream(const SinkFilterPtr& filter) { + SinkTokenStreamPtr sink(newLucene(this->cloneAttributes(), filter)); + this->sinks.add(sink); + return sink; +} - void TeeSinkTokenFilter::addSinkTokenStream(const SinkTokenStreamPtr& sink) - { - // check that sink has correct factory - if (this->getAttributeFactory() != sink->getAttributeFactory()) - boost::throw_exception(IllegalArgumentException(L"The supplied sink is not compatible to this tee.")); - // add eventually missing attribute impls to the existing sink - Collection attrImpls(this->cloneAttributes()->getAttributes()); - for (Collection::iterator it = attrImpls.begin(); it != attrImpls.end(); ++it) - sink->addAttribute((*it)->getClassName(), *it); - this->sinks.add(sink); +void TeeSinkTokenFilter::addSinkTokenStream(const SinkTokenStreamPtr& sink) { + // check that sink has correct factory + if (this->getAttributeFactory() != sink->getAttributeFactory()) { + boost::throw_exception(IllegalArgumentException(L"The supplied sink is not compatible to this tee.")); } + // add eventually missing attribute impls to the existing sink + Collection attrImpls(this->cloneAttributes()->getAttributes()); + for (Collection::iterator it = attrImpls.begin(); it != attrImpls.end(); ++it) { + sink->addAttribute((*it)->getClassName(), *it); + } + this->sinks.add(sink); +} - void TeeSinkTokenFilter::consumeAllTokens() - { - while (incrementToken()) - { - } +void TeeSinkTokenFilter::consumeAllTokens() { + while (incrementToken()) { } +} - bool TeeSinkTokenFilter::incrementToken() - { - if (input->incrementToken()) - { - // capture state lazily - maybe no SinkFilter accepts this state - AttributeSourceStatePtr state; - for (Collection::iterator ref = sinks.begin(); ref != sinks.end(); ++ref) - { - if (*ref) - { - if ((*ref)->accept(shared_from_this())) - { - if (!state) - state = this->captureState(); - (*ref)->addState(state); +bool TeeSinkTokenFilter::incrementToken() { + if (input->incrementToken()) { + // capture state lazily - maybe no SinkFilter accepts this state + AttributeSourceStatePtr state; + for (Collection::iterator ref = sinks.begin(); ref != sinks.end(); ++ref) { + if (*ref) { + if ((*ref)->accept(shared_from_this())) { + if (!state) { + state = this->captureState(); } + (*ref)->addState(state); } } - return true; } - - return false; + return true; } - void TeeSinkTokenFilter::end() - { - TokenFilter::end(); - AttributeSourceStatePtr finalState(captureState()); - for (Collection::iterator ref = sinks.begin(); ref != sinks.end(); ++ref) - { - if (*ref) - (*ref)->setFinalState(finalState); + return false; +} + +void TeeSinkTokenFilter::end() { + TokenFilter::end(); + AttributeSourceStatePtr finalState(captureState()); + for (Collection::iterator ref = sinks.begin(); ref != sinks.end(); ++ref) { + if (*ref) { + (*ref)->setFinalState(finalState); } } +} - SinkFilter::~SinkFilter() - { - } +SinkFilter::~SinkFilter() { +} - void SinkFilter::reset() - { - // nothing to do; can be overridden - } +void SinkFilter::reset() { + // nothing to do; can be overridden +} - AcceptAllSinkFilter::~AcceptAllSinkFilter() - { - } +AcceptAllSinkFilter::~AcceptAllSinkFilter() { +} - bool AcceptAllSinkFilter::accept(const AttributeSourcePtr& source) - { - return true; - } +bool AcceptAllSinkFilter::accept(const AttributeSourcePtr& source) { + return true; +} - SinkTokenStream::SinkTokenStream(const AttributeSourcePtr& source, const SinkFilterPtr& filter) : TokenStream(source) - { - this->filter = filter; - this->cachedStates = Collection::newInstance(); - this->it = cachedStates.begin(); - this->initIterator = false; - } +SinkTokenStream::SinkTokenStream(const AttributeSourcePtr& source, const SinkFilterPtr& filter) : TokenStream(source) { + this->filter = filter; + this->cachedStates = Collection::newInstance(); + this->it = cachedStates.begin(); + this->initIterator = false; +} - SinkTokenStream::~SinkTokenStream() - { - } +SinkTokenStream::~SinkTokenStream() { +} - bool SinkTokenStream::accept(const AttributeSourcePtr& source) - { - return filter->accept(source); - } +bool SinkTokenStream::accept(const AttributeSourcePtr& source) { + return filter->accept(source); +} - void SinkTokenStream::addState(const AttributeSourceStatePtr& state) - { - if (initIterator) - boost::throw_exception(IllegalStateException(L"The tee must be consumed before sinks are consumed.")); - cachedStates.add(state); +void SinkTokenStream::addState(const AttributeSourceStatePtr& state) { + if (initIterator) { + boost::throw_exception(IllegalStateException(L"The tee must be consumed before sinks are consumed.")); } + cachedStates.add(state); +} + +void SinkTokenStream::setFinalState(const AttributeSourceStatePtr& finalState) { + this->finalState = finalState; +} - void SinkTokenStream::setFinalState(const AttributeSourceStatePtr& finalState) - { - this->finalState = finalState; +bool SinkTokenStream::incrementToken() { + // lazy init the iterator + if (!initIterator) { + it = cachedStates.begin(); + initIterator = true; } - bool SinkTokenStream::incrementToken() - { - // lazy init the iterator - if (!initIterator) - { - it = cachedStates.begin(); - initIterator = true; - } + if (it == cachedStates.end()) { + return false; + } - if (it == cachedStates.end()) - return false; + AttributeSourceStatePtr state = *it++; + restoreState(state); + return true; +} - AttributeSourceStatePtr state = *it++; - restoreState(state); - return true; +void SinkTokenStream::end() { + if (finalState) { + restoreState(finalState); } +} - void SinkTokenStream::end() - { - if (finalState) - restoreState(finalState); - } +void SinkTokenStream::reset() { + it = cachedStates.begin(); + initIterator = false; +} - void SinkTokenStream::reset() - { - it = cachedStates.begin(); - initIterator = false; - } } diff --git a/src/core/analysis/Token.cpp b/src/core/analysis/Token.cpp index 11791489..53269727 100644 --- a/src/core/analysis/Token.cpp +++ b/src/core/analysis/Token.cpp @@ -16,522 +16,471 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t Token::MIN_BUFFER_SIZE = 10; +namespace Lucene { - Token::Token() - { - ConstructToken(0, 0, DEFAULT_TYPE(), 0); - } - - Token::Token(int32_t start, int32_t end) - { - ConstructToken(start, end, DEFAULT_TYPE(), 0); - } +const int32_t Token::MIN_BUFFER_SIZE = 10; - Token::Token(int32_t start, int32_t end, const String& type) - { - ConstructToken(start, end, type, 0); - } +Token::Token() { + ConstructToken(0, 0, DEFAULT_TYPE(), 0); +} - Token::Token(int32_t start, int32_t end, int32_t flags) - { - ConstructToken(start, end, DEFAULT_TYPE(), flags); - } +Token::Token(int32_t start, int32_t end) { + ConstructToken(start, end, DEFAULT_TYPE(), 0); +} - Token::Token(const String& text, int32_t start, int32_t end) - { - ConstructToken(start, end, DEFAULT_TYPE(), 0); - setTermBuffer(text); - } +Token::Token(int32_t start, int32_t end, const String& type) { + ConstructToken(start, end, type, 0); +} - Token::Token(const String& text, int32_t start, int32_t end, const String& type) - { - ConstructToken(start, end, type, 0); - setTermBuffer(text); - } +Token::Token(int32_t start, int32_t end, int32_t flags) { + ConstructToken(start, end, DEFAULT_TYPE(), flags); +} - Token::Token(const String& text, int32_t start, int32_t end, int32_t flags) - { - ConstructToken(start, end, DEFAULT_TYPE(), flags); - setTermBuffer(text); - } +Token::Token(const String& text, int32_t start, int32_t end) { + ConstructToken(start, end, DEFAULT_TYPE(), 0); + setTermBuffer(text); +} - Token::Token(CharArray startTermBuffer, int32_t termBufferOffset, int32_t termBufferLength, int32_t start, int32_t end) - { - ConstructToken(start, end, DEFAULT_TYPE(), 0); - setTermBuffer(startTermBuffer.get(), termBufferOffset, termBufferLength); - } +Token::Token(const String& text, int32_t start, int32_t end, const String& type) { + ConstructToken(start, end, type, 0); + setTermBuffer(text); +} - Token::~Token() - { - } +Token::Token(const String& text, int32_t start, int32_t end, int32_t flags) { + ConstructToken(start, end, DEFAULT_TYPE(), flags); + setTermBuffer(text); +} - void Token::ConstructToken(int32_t start, int32_t end, const String& type, int32_t flags) - { - this->_termLength = 0; - this->_startOffset = start; - this->_endOffset = end; - this->_type = type; - this->flags = flags; - this->positionIncrement = 1; - } +Token::Token(CharArray startTermBuffer, int32_t termBufferOffset, int32_t termBufferLength, int32_t start, int32_t end) { + ConstructToken(start, end, DEFAULT_TYPE(), 0); + setTermBuffer(startTermBuffer.get(), termBufferOffset, termBufferLength); +} - const String& Token::DEFAULT_TYPE() - { - static String _DEFAULT_TYPE(L"word"); - return _DEFAULT_TYPE; - } +Token::~Token() { +} - void Token::setPositionIncrement(int32_t positionIncrement) - { - if (positionIncrement < 0) - boost::throw_exception(IllegalArgumentException(L"Increment must be zero or greater: " + StringUtils::toString(positionIncrement))); - this->positionIncrement = positionIncrement; - } +void Token::ConstructToken(int32_t start, int32_t end, const String& type, int32_t flags) { + this->_termLength = 0; + this->_startOffset = start; + this->_endOffset = end; + this->_type = type; + this->flags = flags; + this->positionIncrement = 1; +} - int32_t Token::getPositionIncrement() - { - return positionIncrement; - } +const String& Token::DEFAULT_TYPE() { + static String _DEFAULT_TYPE(L"word"); + return _DEFAULT_TYPE; +} - String Token::term() - { - initTermBuffer(); - return String(_termBuffer.get(), _termLength); +void Token::setPositionIncrement(int32_t positionIncrement) { + if (positionIncrement < 0) { + boost::throw_exception(IllegalArgumentException(L"Increment must be zero or greater: " + StringUtils::toString(positionIncrement))); } + this->positionIncrement = positionIncrement; +} - void Token::setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length) - { - growTermBuffer(length); - MiscUtils::arrayCopy(buffer, offset, _termBuffer.get(), 0, length); - _termLength = length; - } +int32_t Token::getPositionIncrement() { + return positionIncrement; +} - void Token::setTermBuffer(const String& buffer) - { - int32_t length = (int32_t)buffer.size(); - growTermBuffer(length); - MiscUtils::arrayCopy(buffer.begin(), 0, _termBuffer.get(), 0, length); - _termLength = length; - } +String Token::term() { + initTermBuffer(); + return String(_termBuffer.get(), _termLength); +} - void Token::setTermBuffer(const String& buffer, int32_t offset, int32_t length) - { - BOOST_ASSERT(offset <= (int32_t)buffer.length()); - BOOST_ASSERT(offset + length <= (int32_t)buffer.length()); - growTermBuffer(length); - MiscUtils::arrayCopy(buffer.begin(), offset, _termBuffer.get(), 0, length); - _termLength = length; - } +void Token::setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length) { + growTermBuffer(length); + MiscUtils::arrayCopy(buffer, offset, _termBuffer.get(), 0, length); + _termLength = length; +} - CharArray Token::termBuffer() - { - if (!_termBuffer) - initTermBuffer(); - return _termBuffer; - } +void Token::setTermBuffer(const String& buffer) { + int32_t length = (int32_t)buffer.size(); + growTermBuffer(length); + MiscUtils::arrayCopy(buffer.begin(), 0, _termBuffer.get(), 0, length); + _termLength = length; +} - wchar_t* Token::termBufferArray() - { - if (!_termBuffer) - initTermBuffer(); - return _termBuffer.get(); - } +void Token::setTermBuffer(const String& buffer, int32_t offset, int32_t length) { + BOOST_ASSERT(offset <= (int32_t)buffer.length()); + BOOST_ASSERT(offset + length <= (int32_t)buffer.length()); + growTermBuffer(length); + MiscUtils::arrayCopy(buffer.begin(), offset, _termBuffer.get(), 0, length); + _termLength = length; +} - CharArray Token::resizeTermBuffer(int32_t newSize) - { - if (!_termBuffer) - { - // The buffer is always at least MIN_BUFFER_SIZE - _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(std::max(newSize, MIN_BUFFER_SIZE))); - } - else - { - if (_termBuffer.size() < newSize) - { - // Not big enough; create a new array with slight over allocation and preserve content - _termBuffer.resize(MiscUtils::getNextSize(newSize)); - } - } - return _termBuffer; +CharArray Token::termBuffer() { + if (!_termBuffer) { + initTermBuffer(); } + return _termBuffer; +} - void Token::growTermBuffer(int32_t newSize) - { - _termBuffer = resizeTermBuffer(newSize); +wchar_t* Token::termBufferArray() { + if (!_termBuffer) { + initTermBuffer(); } + return _termBuffer.get(); +} - void Token::initTermBuffer() - { - if (!_termBuffer) - { - _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(MIN_BUFFER_SIZE)); - _termLength = 0; +CharArray Token::resizeTermBuffer(int32_t newSize) { + if (!_termBuffer) { + // The buffer is always at least MIN_BUFFER_SIZE + _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(std::max(newSize, MIN_BUFFER_SIZE))); + } else { + if (_termBuffer.size() < newSize) { + // Not big enough; create a new array with slight over allocation and preserve content + _termBuffer.resize(MiscUtils::getNextSize(newSize)); } } + return _termBuffer; +} + +void Token::growTermBuffer(int32_t newSize) { + _termBuffer = resizeTermBuffer(newSize); +} - int32_t Token::termLength() - { - if (!_termBuffer) - initTermBuffer(); - return _termLength; +void Token::initTermBuffer() { + if (!_termBuffer) { + _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(MIN_BUFFER_SIZE)); + _termLength = 0; } +} - void Token::setTermLength(int32_t length) - { +int32_t Token::termLength() { + if (!_termBuffer) { initTermBuffer(); - if (length > _termBuffer.size()) - { - boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + - L" exceeds the size of the termBuffer (" + - StringUtils::toString(_termBuffer.size()) + L")")); - } - _termLength = length; } + return _termLength; +} - int32_t Token::startOffset() - { - return _startOffset; +void Token::setTermLength(int32_t length) { + initTermBuffer(); + if (length > _termBuffer.size()) { + boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + + L" exceeds the size of the termBuffer (" + + StringUtils::toString(_termBuffer.size()) + L")")); } + _termLength = length; +} - void Token::setStartOffset(int32_t offset) - { - this->_startOffset = offset; - } +int32_t Token::startOffset() { + return _startOffset; +} - int32_t Token::endOffset() - { - return _endOffset; - } +void Token::setStartOffset(int32_t offset) { + this->_startOffset = offset; +} - void Token::setEndOffset(int32_t offset) - { - this->_endOffset = offset; - } +int32_t Token::endOffset() { + return _endOffset; +} - void Token::setOffset(int32_t startOffset, int32_t endOffset) - { - this->_startOffset = startOffset; - this->_endOffset = endOffset; - } +void Token::setEndOffset(int32_t offset) { + this->_endOffset = offset; +} - String Token::type() - { - return _type; - } +void Token::setOffset(int32_t startOffset, int32_t endOffset) { + this->_startOffset = startOffset; + this->_endOffset = endOffset; +} - void Token::setType(const String& type) - { - this->_type = type; - } +String Token::type() { + return _type; +} - int32_t Token::getFlags() - { - return flags; - } +void Token::setType(const String& type) { + this->_type = type; +} - void Token::setFlags(int32_t flags) - { - this->flags = flags; - } +int32_t Token::getFlags() { + return flags; +} - PayloadPtr Token::getPayload() - { - return this->payload; - } +void Token::setFlags(int32_t flags) { + this->flags = flags; +} - void Token::setPayload(const PayloadPtr& payload) - { - this->payload = payload; - } +PayloadPtr Token::getPayload() { + return this->payload; +} - String Token::toString() - { - StringStream buffer; - initTermBuffer(); - buffer << L"("; - if (!_termBuffer) - buffer << L"null"; - else - buffer << term() << L"," << _startOffset << L"," << _endOffset; - if (_type != L"word") - buffer << L",type=" << _type; - if (positionIncrement != 1) - buffer << L",posIncr=" << positionIncrement; - buffer << L")"; - return buffer.str(); - } +void Token::setPayload(const PayloadPtr& payload) { + this->payload = payload; +} - void Token::clear() - { - payload.reset(); - // Leave termBuffer to allow re-use - _termLength = 0; - positionIncrement = 1; - flags = 0; - _startOffset = 0; - _endOffset = 0; - _type = DEFAULT_TYPE(); +String Token::toString() { + StringStream buffer; + initTermBuffer(); + buffer << L"("; + if (!_termBuffer) { + buffer << L"null"; + } else { + buffer << term() << L"," << _startOffset << L"," << _endOffset; + } + if (_type != L"word") { + buffer << L",type=" << _type; + } + if (positionIncrement != 1) { + buffer << L",posIncr=" << positionIncrement; } + buffer << L")"; + return buffer.str(); +} - LuceneObjectPtr Token::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); - TokenPtr cloneToken(boost::dynamic_pointer_cast(clone)); - cloneToken->_termLength = _termLength; - cloneToken->_startOffset = _startOffset; - cloneToken->_endOffset = _endOffset; - cloneToken->_type = _type; - cloneToken->flags = flags; - cloneToken->positionIncrement = positionIncrement; - - // Do a deep clone - if (_termBuffer) - { - cloneToken->_termBuffer = CharArray::newInstance(_termBuffer.size()); - MiscUtils::arrayCopy(_termBuffer.get(), 0, cloneToken->_termBuffer.get(), 0, _termBuffer.size()); - } - if (payload) - cloneToken->payload = boost::dynamic_pointer_cast(payload->clone()); +void Token::clear() { + payload.reset(); + // Leave termBuffer to allow re-use + _termLength = 0; + positionIncrement = 1; + flags = 0; + _startOffset = 0; + _endOffset = 0; + _type = DEFAULT_TYPE(); +} + +LuceneObjectPtr Token::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); + TokenPtr cloneToken(boost::dynamic_pointer_cast(clone)); + cloneToken->_termLength = _termLength; + cloneToken->_startOffset = _startOffset; + cloneToken->_endOffset = _endOffset; + cloneToken->_type = _type; + cloneToken->flags = flags; + cloneToken->positionIncrement = positionIncrement; - return cloneToken; + // Do a deep clone + if (_termBuffer) { + cloneToken->_termBuffer = CharArray::newInstance(_termBuffer.size()); + MiscUtils::arrayCopy(_termBuffer.get(), 0, cloneToken->_termBuffer.get(), 0, _termBuffer.size()); } + if (payload) { + cloneToken->payload = boost::dynamic_pointer_cast(payload->clone()); + } + + return cloneToken; +} - TokenPtr Token::clone(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) - { - TokenPtr clone(newLucene(newTermBuffer, newTermOffset, newTermLength, newStartOffset, newEndOffset)); - clone->positionIncrement = positionIncrement; - clone->flags = flags; - clone->_type = _type; - if (payload) - clone->payload = boost::dynamic_pointer_cast(payload->clone()); - return clone; +TokenPtr Token::clone(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) { + TokenPtr clone(newLucene(newTermBuffer, newTermOffset, newTermLength, newStartOffset, newEndOffset)); + clone->positionIncrement = positionIncrement; + clone->flags = flags; + clone->_type = _type; + if (payload) { + clone->payload = boost::dynamic_pointer_cast(payload->clone()); } + return clone; +} - bool Token::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; +bool Token::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } - TokenPtr otherToken(boost::dynamic_pointer_cast(other)); - if (otherToken) - { - initTermBuffer(); - otherToken->initTermBuffer(); + TokenPtr otherToken(boost::dynamic_pointer_cast(other)); + if (otherToken) { + initTermBuffer(); + otherToken->initTermBuffer(); - if (_termLength == otherToken->_termLength && _startOffset == otherToken->_startOffset && + if (_termLength == otherToken->_termLength && _startOffset == otherToken->_startOffset && _endOffset == otherToken->_endOffset && flags == otherToken->flags && positionIncrement == otherToken->positionIncrement && _type == otherToken->_type && - (payload ? payload->equals(otherToken->payload) : !otherToken->payload)) - { - for (int32_t i = 0; i < _termLength; ++i) - { - if (_termBuffer[i] != otherToken->_termBuffer[i]) - return false; + (payload ? payload->equals(otherToken->payload) : !otherToken->payload)) { + for (int32_t i = 0; i < _termLength; ++i) { + if (_termBuffer[i] != otherToken->_termBuffer[i]) { + return false; } - return true; } - else - return false; - } - else + return true; + } else { return false; + } + } else { + return false; } +} - int32_t Token::hashCode() - { - initTermBuffer(); - int32_t code = _termLength; - code = code * 31 + _startOffset; - code = code * 31 + _endOffset; - code = code * 31 + flags; - code = code * 31 + positionIncrement; - code = code * 31 + StringUtils::hashCode(_type); - code = payload ? code * 31 + payload->hashCode() : code; - code = code * 31 + MiscUtils::hashCode(_termBuffer.get(), 0, _termLength); - return code; - } +int32_t Token::hashCode() { + initTermBuffer(); + int32_t code = _termLength; + code = code * 31 + _startOffset; + code = code * 31 + _endOffset; + code = code * 31 + flags; + code = code * 31 + positionIncrement; + code = code * 31 + StringUtils::hashCode(_type); + code = payload ? code * 31 + payload->hashCode() : code; + code = code * 31 + MiscUtils::hashCode(_termBuffer.get(), 0, _termLength); + return code; +} - void Token::clearNoTermBuffer() - { - payload.reset(); - positionIncrement = 1; - flags = 0; - _startOffset = 0; - _endOffset = 0; - _type = DEFAULT_TYPE(); - } +void Token::clearNoTermBuffer() { + payload.reset(); + positionIncrement = 1; + flags = 0; + _startOffset = 0; + _endOffset = 0; + _type = DEFAULT_TYPE(); +} - TokenPtr Token::reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType) - { - clearNoTermBuffer(); - payload.reset(); - positionIncrement = 1; - setTermBuffer(newTermBuffer.get(), newTermOffset, newTermLength); - _startOffset = newStartOffset; - _endOffset = newEndOffset; - _type = newType; - return shared_from_this(); - } +TokenPtr Token::reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType) { + clearNoTermBuffer(); + payload.reset(); + positionIncrement = 1; + setTermBuffer(newTermBuffer.get(), newTermOffset, newTermLength); + _startOffset = newStartOffset; + _endOffset = newEndOffset; + _type = newType; + return shared_from_this(); +} - TokenPtr Token::reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) - { - clearNoTermBuffer(); - setTermBuffer(newTermBuffer.get(), newTermOffset, newTermLength); - _startOffset = newStartOffset; - _endOffset = newEndOffset; - _type = DEFAULT_TYPE(); - return shared_from_this(); - } +TokenPtr Token::reinit(CharArray newTermBuffer, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) { + clearNoTermBuffer(); + setTermBuffer(newTermBuffer.get(), newTermOffset, newTermLength); + _startOffset = newStartOffset; + _endOffset = newEndOffset; + _type = DEFAULT_TYPE(); + return shared_from_this(); +} - TokenPtr Token::reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset, const String& newType) - { - clearNoTermBuffer(); - setTermBuffer(newTerm); - _startOffset = newStartOffset; - _endOffset = newEndOffset; - _type = newType; - return shared_from_this(); - } +TokenPtr Token::reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset, const String& newType) { + clearNoTermBuffer(); + setTermBuffer(newTerm); + _startOffset = newStartOffset; + _endOffset = newEndOffset; + _type = newType; + return shared_from_this(); +} - TokenPtr Token::reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType) - { - clearNoTermBuffer(); - setTermBuffer(newTerm, newTermOffset, newTermLength); - _startOffset = newStartOffset; - _endOffset = newEndOffset; - _type = newType; - return shared_from_this(); - } +TokenPtr Token::reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset, const String& newType) { + clearNoTermBuffer(); + setTermBuffer(newTerm, newTermOffset, newTermLength); + _startOffset = newStartOffset; + _endOffset = newEndOffset; + _type = newType; + return shared_from_this(); +} - TokenPtr Token::reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset) - { - clearNoTermBuffer(); - setTermBuffer(newTerm); - _startOffset = newStartOffset; - _endOffset = newEndOffset; - _type = DEFAULT_TYPE(); - return shared_from_this(); - } +TokenPtr Token::reinit(const String& newTerm, int32_t newStartOffset, int32_t newEndOffset) { + clearNoTermBuffer(); + setTermBuffer(newTerm); + _startOffset = newStartOffset; + _endOffset = newEndOffset; + _type = DEFAULT_TYPE(); + return shared_from_this(); +} - TokenPtr Token::reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) - { - clearNoTermBuffer(); - setTermBuffer(newTerm, newTermOffset, newTermLength); - _startOffset = newStartOffset; - _endOffset = newEndOffset; - _type = DEFAULT_TYPE(); - return shared_from_this(); - } +TokenPtr Token::reinit(const String& newTerm, int32_t newTermOffset, int32_t newTermLength, int32_t newStartOffset, int32_t newEndOffset) { + clearNoTermBuffer(); + setTermBuffer(newTerm, newTermOffset, newTermLength); + _startOffset = newStartOffset; + _endOffset = newEndOffset; + _type = DEFAULT_TYPE(); + return shared_from_this(); +} - void Token::reinit(const TokenPtr& prototype) - { - prototype->initTermBuffer(); - setTermBuffer(prototype->_termBuffer.get(), 0, prototype->_termLength); - positionIncrement = prototype->positionIncrement; - flags = prototype->flags; - _startOffset = prototype->_startOffset; - _endOffset = prototype->_endOffset; - _type = prototype->_type; - payload = prototype->payload; - } +void Token::reinit(const TokenPtr& prototype) { + prototype->initTermBuffer(); + setTermBuffer(prototype->_termBuffer.get(), 0, prototype->_termLength); + positionIncrement = prototype->positionIncrement; + flags = prototype->flags; + _startOffset = prototype->_startOffset; + _endOffset = prototype->_endOffset; + _type = prototype->_type; + payload = prototype->payload; +} - void Token::reinit(const TokenPtr& prototype, const String& newTerm) - { - setTermBuffer(newTerm); - positionIncrement = prototype->positionIncrement; - flags = prototype->flags; - _startOffset = prototype->_startOffset; - _endOffset = prototype->_endOffset; - _type = prototype->_type; - payload = prototype->payload; - } +void Token::reinit(const TokenPtr& prototype, const String& newTerm) { + setTermBuffer(newTerm); + positionIncrement = prototype->positionIncrement; + flags = prototype->flags; + _startOffset = prototype->_startOffset; + _endOffset = prototype->_endOffset; + _type = prototype->_type; + payload = prototype->payload; +} - void Token::reinit(const TokenPtr& prototype, CharArray newTermBuffer, int32_t offset, int32_t length) - { - setTermBuffer(newTermBuffer.get(), offset, length); - positionIncrement = prototype->positionIncrement; - flags = prototype->flags; - _startOffset = prototype->_startOffset; - _endOffset = prototype->_endOffset; - _type = prototype->_type; - payload = prototype->payload; - } +void Token::reinit(const TokenPtr& prototype, CharArray newTermBuffer, int32_t offset, int32_t length) { + setTermBuffer(newTermBuffer.get(), offset, length); + positionIncrement = prototype->positionIncrement; + flags = prototype->flags; + _startOffset = prototype->_startOffset; + _endOffset = prototype->_endOffset; + _type = prototype->_type; + payload = prototype->payload; +} - void Token::copyTo(const AttributePtr& target) - { - TokenPtr targetToken(boost::dynamic_pointer_cast(target)); - if (targetToken) - { - targetToken->reinit(shared_from_this()); - // reinit shares the payload, so clone it - if (payload) - targetToken->payload = boost::dynamic_pointer_cast(payload->clone()); +void Token::copyTo(const AttributePtr& target) { + TokenPtr targetToken(boost::dynamic_pointer_cast(target)); + if (targetToken) { + targetToken->reinit(shared_from_this()); + // reinit shares the payload, so clone it + if (payload) { + targetToken->payload = boost::dynamic_pointer_cast(payload->clone()); } - else - { - initTermBuffer(); - TermAttributePtr targetTermAttribute(boost::dynamic_pointer_cast(target)); - if (targetTermAttribute) - targetTermAttribute->setTermBuffer(_termBuffer.get(), 0, _termLength); - OffsetAttributePtr targetOffsetAttribute(boost::dynamic_pointer_cast(target)); - if (targetOffsetAttribute) - targetOffsetAttribute->setOffset(_startOffset, _endOffset); - PositionIncrementAttributePtr targetPositionIncrementAttribute(boost::dynamic_pointer_cast(target)); - if (targetPositionIncrementAttribute) - targetPositionIncrementAttribute->setPositionIncrement(positionIncrement); - PayloadAttributePtr targetPayloadAttribute(boost::dynamic_pointer_cast(target)); - if (targetPayloadAttribute) - targetPayloadAttribute->setPayload(payload ? boost::dynamic_pointer_cast(payload->clone()) : PayloadPtr()); - FlagsAttributePtr targetFlagsAttribute(boost::dynamic_pointer_cast(target)); - if (targetFlagsAttribute) - targetFlagsAttribute->setFlags(flags); - TypeAttributePtr targetTypeAttribute(boost::dynamic_pointer_cast(target)); - if (targetTypeAttribute) - targetTypeAttribute->setType(_type); + } else { + initTermBuffer(); + TermAttributePtr targetTermAttribute(boost::dynamic_pointer_cast(target)); + if (targetTermAttribute) { + targetTermAttribute->setTermBuffer(_termBuffer.get(), 0, _termLength); } - } - - AttributeFactoryPtr Token::TOKEN_ATTRIBUTE_FACTORY() - { - static AttributeFactoryPtr _TOKEN_ATTRIBUTE_FACTORY; - if (!_TOKEN_ATTRIBUTE_FACTORY) - { - _TOKEN_ATTRIBUTE_FACTORY = newLucene(AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY()); - CycleCheck::addStatic(_TOKEN_ATTRIBUTE_FACTORY); + OffsetAttributePtr targetOffsetAttribute(boost::dynamic_pointer_cast(target)); + if (targetOffsetAttribute) { + targetOffsetAttribute->setOffset(_startOffset, _endOffset); + } + PositionIncrementAttributePtr targetPositionIncrementAttribute(boost::dynamic_pointer_cast(target)); + if (targetPositionIncrementAttribute) { + targetPositionIncrementAttribute->setPositionIncrement(positionIncrement); + } + PayloadAttributePtr targetPayloadAttribute(boost::dynamic_pointer_cast(target)); + if (targetPayloadAttribute) { + targetPayloadAttribute->setPayload(payload ? boost::dynamic_pointer_cast(payload->clone()) : PayloadPtr()); + } + FlagsAttributePtr targetFlagsAttribute(boost::dynamic_pointer_cast(target)); + if (targetFlagsAttribute) { + targetFlagsAttribute->setFlags(flags); + } + TypeAttributePtr targetTypeAttribute(boost::dynamic_pointer_cast(target)); + if (targetTypeAttribute) { + targetTypeAttribute->setType(_type); } - return _TOKEN_ATTRIBUTE_FACTORY; } +} - TokenAttributeFactory::TokenAttributeFactory(const AttributeFactoryPtr& delegate) - { - this->delegate = delegate; +AttributeFactoryPtr Token::TOKEN_ATTRIBUTE_FACTORY() { + static AttributeFactoryPtr _TOKEN_ATTRIBUTE_FACTORY; + if (!_TOKEN_ATTRIBUTE_FACTORY) { + _TOKEN_ATTRIBUTE_FACTORY = newLucene(AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY()); + CycleCheck::addStatic(_TOKEN_ATTRIBUTE_FACTORY); } + return _TOKEN_ATTRIBUTE_FACTORY; +} - TokenAttributeFactory::~TokenAttributeFactory() - { - } +TokenAttributeFactory::TokenAttributeFactory(const AttributeFactoryPtr& delegate) { + this->delegate = delegate; +} - AttributePtr TokenAttributeFactory::createAttributeInstance(const String& className) - { - return newLucene(); - } +TokenAttributeFactory::~TokenAttributeFactory() { +} - bool TokenAttributeFactory::equals(const LuceneObjectPtr& other) - { - if (AttributeFactory::equals(other)) - return true; +AttributePtr TokenAttributeFactory::createAttributeInstance(const String& className) { + return newLucene(); +} - TokenAttributeFactoryPtr otherTokenAttributeFactory(boost::dynamic_pointer_cast(other)); - if (otherTokenAttributeFactory) - return this->delegate->equals(otherTokenAttributeFactory->delegate); - return false; +bool TokenAttributeFactory::equals(const LuceneObjectPtr& other) { + if (AttributeFactory::equals(other)) { + return true; } - int32_t TokenAttributeFactory::hashCode() - { - return (delegate->hashCode() ^ 0x0a45aa31); + TokenAttributeFactoryPtr otherTokenAttributeFactory(boost::dynamic_pointer_cast(other)); + if (otherTokenAttributeFactory) { + return this->delegate->equals(otherTokenAttributeFactory->delegate); } + return false; +} + +int32_t TokenAttributeFactory::hashCode() { + return (delegate->hashCode() ^ 0x0a45aa31); +} + } diff --git a/src/core/analysis/TokenFilter.cpp b/src/core/analysis/TokenFilter.cpp index 28b0fc88..bba3789d 100644 --- a/src/core/analysis/TokenFilter.cpp +++ b/src/core/analysis/TokenFilter.cpp @@ -7,29 +7,25 @@ #include "LuceneInc.h" #include "TokenFilter.h" -namespace Lucene -{ - TokenFilter::TokenFilter(const TokenStreamPtr& input) : TokenStream(input) - { - this->input = input; - } - - TokenFilter::~TokenFilter() - { - } - - void TokenFilter::end() - { - input->end(); - } - - void TokenFilter::close() - { - input->close(); - } - - void TokenFilter::reset() - { - input->reset(); - } +namespace Lucene { + +TokenFilter::TokenFilter(const TokenStreamPtr& input) : TokenStream(input) { + this->input = input; +} + +TokenFilter::~TokenFilter() { +} + +void TokenFilter::end() { + input->end(); +} + +void TokenFilter::close() { + input->close(); +} + +void TokenFilter::reset() { + input->reset(); +} + } diff --git a/src/core/analysis/TokenStream.cpp b/src/core/analysis/TokenStream.cpp index ed304438..d2967ac4 100644 --- a/src/core/analysis/TokenStream.cpp +++ b/src/core/analysis/TokenStream.cpp @@ -7,34 +7,28 @@ #include "LuceneInc.h" #include "TokenStream.h" -namespace Lucene -{ - TokenStream::TokenStream() - { - } - - TokenStream::TokenStream(const AttributeSourcePtr& input) : AttributeSource(input) - { - } - - TokenStream::TokenStream(const AttributeFactoryPtr& factory) : AttributeSource(factory) - { - } - - TokenStream::~TokenStream() - { - } - - void TokenStream::end() - { - // do nothing by default - } - - void TokenStream::reset() - { - } - - void TokenStream::close() - { - } +namespace Lucene { + +TokenStream::TokenStream() { +} + +TokenStream::TokenStream(const AttributeSourcePtr& input) : AttributeSource(input) { +} + +TokenStream::TokenStream(const AttributeFactoryPtr& factory) : AttributeSource(factory) { +} + +TokenStream::~TokenStream() { +} + +void TokenStream::end() { + // do nothing by default +} + +void TokenStream::reset() { +} + +void TokenStream::close() { +} + } diff --git a/src/core/analysis/Tokenizer.cpp b/src/core/analysis/Tokenizer.cpp index 8338eadb..67ff5afa 100644 --- a/src/core/analysis/Tokenizer.cpp +++ b/src/core/analysis/Tokenizer.cpp @@ -8,58 +8,48 @@ #include "Tokenizer.h" #include "CharReader.h" -namespace Lucene -{ - Tokenizer::Tokenizer() - { - } +namespace Lucene { - Tokenizer::Tokenizer(const ReaderPtr& input) - { - this->input = CharReader::get(input); - this->charStream = boost::dynamic_pointer_cast(this->input); - } +Tokenizer::Tokenizer() { +} - Tokenizer::Tokenizer(const AttributeFactoryPtr& factory) : TokenStream(factory) - { - } +Tokenizer::Tokenizer(const ReaderPtr& input) { + this->input = CharReader::get(input); + this->charStream = boost::dynamic_pointer_cast(this->input); +} - Tokenizer::Tokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : TokenStream(factory) - { - this->input = CharReader::get(input); - this->charStream = boost::dynamic_pointer_cast(this->input); - } +Tokenizer::Tokenizer(const AttributeFactoryPtr& factory) : TokenStream(factory) { +} - Tokenizer::Tokenizer(const AttributeSourcePtr& source) : TokenStream(source) - { - } +Tokenizer::Tokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : TokenStream(factory) { + this->input = CharReader::get(input); + this->charStream = boost::dynamic_pointer_cast(this->input); +} - Tokenizer::Tokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : TokenStream(source) - { - this->input = CharReader::get(input); - this->charStream = boost::dynamic_pointer_cast(this->input); - } +Tokenizer::Tokenizer(const AttributeSourcePtr& source) : TokenStream(source) { +} - Tokenizer::~Tokenizer() - { - } +Tokenizer::Tokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : TokenStream(source) { + this->input = CharReader::get(input); + this->charStream = boost::dynamic_pointer_cast(this->input); +} - void Tokenizer::close() - { - if (input) - { - input->close(); - input.reset(); // don't hold onto Reader after close - } - } +Tokenizer::~Tokenizer() { +} - int32_t Tokenizer::correctOffset(int32_t currentOff) - { - return charStream ? charStream->correctOffset(currentOff) : currentOff; +void Tokenizer::close() { + if (input) { + input->close(); + input.reset(); // don't hold onto Reader after close } +} + +int32_t Tokenizer::correctOffset(int32_t currentOff) { + return charStream ? charStream->correctOffset(currentOff) : currentOff; +} + +void Tokenizer::reset(const ReaderPtr& input) { + this->input = input; +} - void Tokenizer::reset(const ReaderPtr& input) - { - this->input = input; - } } diff --git a/src/core/analysis/WhitespaceAnalyzer.cpp b/src/core/analysis/WhitespaceAnalyzer.cpp index 72850a4c..6353e0ee 100644 --- a/src/core/analysis/WhitespaceAnalyzer.cpp +++ b/src/core/analysis/WhitespaceAnalyzer.cpp @@ -8,27 +8,24 @@ #include "WhitespaceAnalyzer.h" #include "WhitespaceTokenizer.h" -namespace Lucene -{ - WhitespaceAnalyzer::~WhitespaceAnalyzer() - { - } +namespace Lucene { - TokenStreamPtr WhitespaceAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(reader); - } +WhitespaceAnalyzer::~WhitespaceAnalyzer() { +} - TokenStreamPtr WhitespaceAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); - if (!tokenizer) - { - tokenizer = newLucene(reader); - setPreviousTokenStream(tokenizer); - } - else - tokenizer->reset(reader); - return tokenizer; +TokenStreamPtr WhitespaceAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(reader); +} + +TokenStreamPtr WhitespaceAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenizerPtr tokenizer(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!tokenizer) { + tokenizer = newLucene(reader); + setPreviousTokenStream(tokenizer); + } else { + tokenizer->reset(reader); } + return tokenizer; +} + } diff --git a/src/core/analysis/WhitespaceTokenizer.cpp b/src/core/analysis/WhitespaceTokenizer.cpp index 039a4747..a5492020 100644 --- a/src/core/analysis/WhitespaceTokenizer.cpp +++ b/src/core/analysis/WhitespaceTokenizer.cpp @@ -9,26 +9,22 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - WhitespaceTokenizer::WhitespaceTokenizer(const ReaderPtr& input) : CharTokenizer(input) - { - } - - WhitespaceTokenizer::WhitespaceTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) - { - } - - WhitespaceTokenizer::WhitespaceTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) - { - } - - WhitespaceTokenizer::~WhitespaceTokenizer() - { - } - - bool WhitespaceTokenizer::isTokenChar(wchar_t c) - { - return !UnicodeUtil::isSpace(c); - } +namespace Lucene { + +WhitespaceTokenizer::WhitespaceTokenizer(const ReaderPtr& input) : CharTokenizer(input) { +} + +WhitespaceTokenizer::WhitespaceTokenizer(const AttributeSourcePtr& source, const ReaderPtr& input) : CharTokenizer(source, input) { +} + +WhitespaceTokenizer::WhitespaceTokenizer(const AttributeFactoryPtr& factory, const ReaderPtr& input) : CharTokenizer(factory, input) { +} + +WhitespaceTokenizer::~WhitespaceTokenizer() { +} + +bool WhitespaceTokenizer::isTokenChar(wchar_t c) { + return !UnicodeUtil::isSpace(c); +} + } diff --git a/src/core/analysis/WordlistLoader.cpp b/src/core/analysis/WordlistLoader.cpp index 520c04ea..6db85c96 100644 --- a/src/core/analysis/WordlistLoader.cpp +++ b/src/core/analysis/WordlistLoader.cpp @@ -10,88 +10,79 @@ #include "FileReader.h" #include "BufferedReader.h" -namespace Lucene -{ - WordlistLoader::~WordlistLoader() - { - } +namespace Lucene { - HashSet WordlistLoader::getWordSet(const String& wordfile, const String& comment) - { - HashSet result(HashSet::newInstance()); - FileReaderPtr reader; - LuceneException finally; - try - { - reader = newLucene(wordfile); - result = getWordSet(reader, comment); - } - catch (LuceneException& e) - { - finally = e; - } - if (reader) - reader->close(); - finally.throwException(); - return result; +WordlistLoader::~WordlistLoader() { +} + +HashSet WordlistLoader::getWordSet(const String& wordfile, const String& comment) { + HashSet result(HashSet::newInstance()); + FileReaderPtr reader; + LuceneException finally; + try { + reader = newLucene(wordfile); + result = getWordSet(reader, comment); + } catch (LuceneException& e) { + finally = e; } + if (reader) { + reader->close(); + } + finally.throwException(); + return result; +} - HashSet WordlistLoader::getWordSet(const ReaderPtr& reader, const String& comment) - { - HashSet result(HashSet::newInstance()); - LuceneException finally; - BufferedReaderPtr bufferedReader(boost::dynamic_pointer_cast(reader)); - try - { - if (!bufferedReader) - bufferedReader = newLucene(reader); - String word; - while (bufferedReader->readLine(word)) - { - if (comment.empty() || !boost::starts_with(word, comment)) - { - boost::trim(word); - result.add(word); - } - } +HashSet WordlistLoader::getWordSet(const ReaderPtr& reader, const String& comment) { + HashSet result(HashSet::newInstance()); + LuceneException finally; + BufferedReaderPtr bufferedReader(boost::dynamic_pointer_cast(reader)); + try { + if (!bufferedReader) { + bufferedReader = newLucene(reader); } - catch (LuceneException& e) - { - finally = e; + String word; + while (bufferedReader->readLine(word)) { + if (comment.empty() || !boost::starts_with(word, comment)) { + boost::trim(word); + result.add(word); + } } - if (bufferedReader) - bufferedReader->close(); - finally.throwException(); - return result; + } catch (LuceneException& e) { + finally = e; + } + if (bufferedReader) { + bufferedReader->close(); } + finally.throwException(); + return result; +} - MapStringString WordlistLoader::getStemDict(const String& wordstemfile) - { - MapStringString result(MapStringString::newInstance()); - BufferedReaderPtr bufferedReader; - FileReaderPtr reader; - LuceneException finally; - try - { - reader = newLucene(wordstemfile); - bufferedReader = newLucene(reader); - String line; - while (bufferedReader->readLine(line)) - { - String::size_type sep = line.find(L'\t'); - if (sep != String::npos) - result.put(line.substr(0, sep), line.substr(sep + 1)); +MapStringString WordlistLoader::getStemDict(const String& wordstemfile) { + MapStringString result(MapStringString::newInstance()); + BufferedReaderPtr bufferedReader; + FileReaderPtr reader; + LuceneException finally; + try { + reader = newLucene(wordstemfile); + bufferedReader = newLucene(reader); + String line; + while (bufferedReader->readLine(line)) { + String::size_type sep = line.find(L'\t'); + if (sep != String::npos) { + result.put(line.substr(0, sep), line.substr(sep + 1)); } } - catch (LuceneException& e) - { - finally = e; - } - if (reader) - reader->close(); - if (bufferedReader) - bufferedReader->close(); - finally.throwException(); - return result; + } catch (LuceneException& e) { + finally = e; } + if (reader) { + reader->close(); + } + if (bufferedReader) { + bufferedReader->close(); + } + finally.throwException(); + return result; +} + } diff --git a/src/core/analysis/standard/StandardAnalyzer.cpp b/src/core/analysis/standard/StandardAnalyzer.cpp index 94b13795..d1ec2eb7 100644 --- a/src/core/analysis/standard/StandardAnalyzer.cpp +++ b/src/core/analysis/standard/StandardAnalyzer.cpp @@ -14,86 +14,75 @@ #include "StopFilter.h" #include "WordlistLoader.h" -namespace Lucene -{ - /// Construct an analyzer with the given stop words. - const int32_t StandardAnalyzer::DEFAULT_MAX_TOKEN_LENGTH = 255; - - StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion) - { - ConstructAnalyser(matchVersion, StopAnalyzer::ENGLISH_STOP_WORDS_SET()); - } +namespace Lucene { - StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords) - { - ConstructAnalyser(matchVersion, stopWords); - } +/// Construct an analyzer with the given stop words. +const int32_t StandardAnalyzer::DEFAULT_MAX_TOKEN_LENGTH = 255; - StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, const String& stopwords) - { - ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); - } +StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion) { + ConstructAnalyser(matchVersion, StopAnalyzer::ENGLISH_STOP_WORDS_SET()); +} - StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords) - { - ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); - } +StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, HashSet stopWords) { + ConstructAnalyser(matchVersion, stopWords); +} - StandardAnalyzer::~StandardAnalyzer() - { - } +StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, const String& stopwords) { + ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); +} - void StandardAnalyzer::ConstructAnalyser(LuceneVersion::Version matchVersion, HashSet stopWords) - { - stopSet = stopWords; - enableStopPositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); - replaceInvalidAcronym = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_24); - this->matchVersion = matchVersion; - this->maxTokenLength = DEFAULT_MAX_TOKEN_LENGTH; - } +StandardAnalyzer::StandardAnalyzer(LuceneVersion::Version matchVersion, const ReaderPtr& stopwords) { + ConstructAnalyser(matchVersion, WordlistLoader::getWordSet(stopwords)); +} - TokenStreamPtr StandardAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) - { - StandardTokenizerPtr tokenStream(newLucene(matchVersion, reader)); - tokenStream->setMaxTokenLength(maxTokenLength); - TokenStreamPtr result(newLucene(tokenStream)); - result = newLucene(result); - result = newLucene(enableStopPositionIncrements, result, stopSet); - return result; - } +StandardAnalyzer::~StandardAnalyzer() { +} - void StandardAnalyzer::setMaxTokenLength(int32_t length) - { - maxTokenLength = length; - } +void StandardAnalyzer::ConstructAnalyser(LuceneVersion::Version matchVersion, HashSet stopWords) { + stopSet = stopWords; + enableStopPositionIncrements = StopFilter::getEnablePositionIncrementsVersionDefault(matchVersion); + replaceInvalidAcronym = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_24); + this->matchVersion = matchVersion; + this->maxTokenLength = DEFAULT_MAX_TOKEN_LENGTH; +} - int32_t StandardAnalyzer::getMaxTokenLength() - { - return maxTokenLength; - } +TokenStreamPtr StandardAnalyzer::tokenStream(const String& fieldName, const ReaderPtr& reader) { + StandardTokenizerPtr tokenStream(newLucene(matchVersion, reader)); + tokenStream->setMaxTokenLength(maxTokenLength); + TokenStreamPtr result(newLucene(tokenStream)); + result = newLucene(result); + result = newLucene(enableStopPositionIncrements, result, stopSet); + return result; +} - TokenStreamPtr StandardAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { - StandardAnalyzerSavedStreamsPtr streams = boost::dynamic_pointer_cast(getPreviousTokenStream()); - if (!streams) - { - streams = newLucene(); - setPreviousTokenStream(streams); - streams->tokenStream = newLucene(matchVersion, reader); - streams->filteredTokenStream = newLucene(streams->tokenStream); - streams->filteredTokenStream = newLucene(streams->filteredTokenStream); - streams->filteredTokenStream = newLucene(enableStopPositionIncrements, streams->filteredTokenStream, stopSet); - } - else - streams->tokenStream->reset(reader); - streams->tokenStream->setMaxTokenLength(maxTokenLength); - - streams->tokenStream->setReplaceInvalidAcronym(replaceInvalidAcronym); - - return streams->filteredTokenStream; - } +void StandardAnalyzer::setMaxTokenLength(int32_t length) { + maxTokenLength = length; +} + +int32_t StandardAnalyzer::getMaxTokenLength() { + return maxTokenLength; +} - StandardAnalyzerSavedStreams::~StandardAnalyzerSavedStreams() - { +TokenStreamPtr StandardAnalyzer::reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { + StandardAnalyzerSavedStreamsPtr streams = boost::dynamic_pointer_cast(getPreviousTokenStream()); + if (!streams) { + streams = newLucene(); + setPreviousTokenStream(streams); + streams->tokenStream = newLucene(matchVersion, reader); + streams->filteredTokenStream = newLucene(streams->tokenStream); + streams->filteredTokenStream = newLucene(streams->filteredTokenStream); + streams->filteredTokenStream = newLucene(enableStopPositionIncrements, streams->filteredTokenStream, stopSet); + } else { + streams->tokenStream->reset(reader); } + streams->tokenStream->setMaxTokenLength(maxTokenLength); + + streams->tokenStream->setReplaceInvalidAcronym(replaceInvalidAcronym); + + return streams->filteredTokenStream; +} + +StandardAnalyzerSavedStreams::~StandardAnalyzerSavedStreams() { +} + } diff --git a/src/core/analysis/standard/StandardFilter.cpp b/src/core/analysis/standard/StandardFilter.cpp index 707dc8c0..32e32241 100644 --- a/src/core/analysis/standard/StandardFilter.cpp +++ b/src/core/analysis/standard/StandardFilter.cpp @@ -10,61 +10,57 @@ #include "TermAttribute.h" #include "TypeAttribute.h" -namespace Lucene -{ - StandardFilter::StandardFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - termAtt = addAttribute(); - typeAtt = addAttribute(); - } +namespace Lucene { - StandardFilter::~StandardFilter() - { - } +StandardFilter::StandardFilter(const TokenStreamPtr& input) : TokenFilter(input) { + termAtt = addAttribute(); + typeAtt = addAttribute(); +} - const String& StandardFilter::APOSTROPHE_TYPE() - { - static String _APOSTROPHE_TYPE; - if (_APOSTROPHE_TYPE.empty()) - _APOSTROPHE_TYPE = StandardTokenizer::TOKEN_TYPES()[StandardTokenizer::APOSTROPHE]; - return _APOSTROPHE_TYPE; +StandardFilter::~StandardFilter() { +} + +const String& StandardFilter::APOSTROPHE_TYPE() { + static String _APOSTROPHE_TYPE; + if (_APOSTROPHE_TYPE.empty()) { + _APOSTROPHE_TYPE = StandardTokenizer::TOKEN_TYPES()[StandardTokenizer::APOSTROPHE]; } + return _APOSTROPHE_TYPE; +} - const String& StandardFilter::ACRONYM_TYPE() - { - static String _ACRONYM_TYPE; - if (_ACRONYM_TYPE.empty()) - _ACRONYM_TYPE = StandardTokenizer::TOKEN_TYPES()[StandardTokenizer::ACRONYM]; - return _ACRONYM_TYPE; +const String& StandardFilter::ACRONYM_TYPE() { + static String _ACRONYM_TYPE; + if (_ACRONYM_TYPE.empty()) { + _ACRONYM_TYPE = StandardTokenizer::TOKEN_TYPES()[StandardTokenizer::ACRONYM]; } + return _ACRONYM_TYPE; +} - bool StandardFilter::incrementToken() - { - if (!input->incrementToken()) - return false; +bool StandardFilter::incrementToken() { + if (!input->incrementToken()) { + return false; + } - wchar_t* termBuffer = termAtt->termBufferArray(); - int32_t bufferLength = termAtt->termLength(); - String type(typeAtt->type()); + wchar_t* termBuffer = termAtt->termBufferArray(); + int32_t bufferLength = termAtt->termLength(); + String type(typeAtt->type()); - if (type == APOSTROPHE_TYPE() && bufferLength >= 2 && termBuffer[bufferLength - 2] == L'\'' && - (termBuffer[bufferLength - 1] == L's' || termBuffer[bufferLength - 1] == L'S')) // remove 's - { - // Strip last 2 characters off - termAtt->setTermLength(bufferLength - 2); - } - else if (type == ACRONYM_TYPE()) // remove dots - { - int32_t upto = 0; - for (int32_t i = 0; i < bufferLength; ++i) - { - wchar_t c = termBuffer[i]; - if (c != L'.') - termBuffer[upto++] = c; + if (type == APOSTROPHE_TYPE() && bufferLength >= 2 && termBuffer[bufferLength - 2] == L'\'' && + (termBuffer[bufferLength - 1] == L's' || termBuffer[bufferLength - 1] == L'S')) { // remove 's + // Strip last 2 characters off + termAtt->setTermLength(bufferLength - 2); + } else if (type == ACRONYM_TYPE()) { // remove dots + int32_t upto = 0; + for (int32_t i = 0; i < bufferLength; ++i) { + wchar_t c = termBuffer[i]; + if (c != L'.') { + termBuffer[upto++] = c; } - termAtt->setTermLength(upto); } - - return true; + termAtt->setTermLength(upto); } + + return true; +} + } diff --git a/src/core/analysis/standard/StandardTokenizer.cpp b/src/core/analysis/standard/StandardTokenizer.cpp index e6c9656b..8f85ab3c 100644 --- a/src/core/analysis/standard/StandardTokenizer.cpp +++ b/src/core/analysis/standard/StandardTokenizer.cpp @@ -13,146 +13,128 @@ #include "PositionIncrementAttribute.h" #include "TypeAttribute.h" -namespace Lucene -{ - const int32_t StandardTokenizer::ALPHANUM = 0; - const int32_t StandardTokenizer::APOSTROPHE = 1; - const int32_t StandardTokenizer::ACRONYM = 2; - const int32_t StandardTokenizer::COMPANY = 3; - const int32_t StandardTokenizer::EMAIL = 4; - const int32_t StandardTokenizer::HOST = 5; - const int32_t StandardTokenizer::NUM = 6; - const int32_t StandardTokenizer::CJ = 7; - - /// @deprecated this solves a bug where HOSTs that end with '.' are identified as ACRONYMs. - const int32_t StandardTokenizer::ACRONYM_DEP = 8; - - StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const ReaderPtr& input) - { - this->scanner = newLucene(input); - init(input, matchVersion); - } +namespace Lucene { + +const int32_t StandardTokenizer::ALPHANUM = 0; +const int32_t StandardTokenizer::APOSTROPHE = 1; +const int32_t StandardTokenizer::ACRONYM = 2; +const int32_t StandardTokenizer::COMPANY = 3; +const int32_t StandardTokenizer::EMAIL = 4; +const int32_t StandardTokenizer::HOST = 5; +const int32_t StandardTokenizer::NUM = 6; +const int32_t StandardTokenizer::CJ = 7; + +/// @deprecated this solves a bug where HOSTs that end with '.' are identified as ACRONYMs. +const int32_t StandardTokenizer::ACRONYM_DEP = 8; + +StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const ReaderPtr& input) { + this->scanner = newLucene(input); + init(input, matchVersion); +} - StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source) - { - this->scanner = newLucene(input); - init(input, matchVersion); - } +StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeSourcePtr& source, const ReaderPtr& input) : Tokenizer(source) { + this->scanner = newLucene(input); + init(input, matchVersion); +} - StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory) - { - this->scanner = newLucene(input); - init(input, matchVersion); - } +StandardTokenizer::StandardTokenizer(LuceneVersion::Version matchVersion, const AttributeFactoryPtr& factory, const ReaderPtr& input) : Tokenizer(factory) { + this->scanner = newLucene(input); + init(input, matchVersion); +} - StandardTokenizer::~StandardTokenizer() - { - } +StandardTokenizer::~StandardTokenizer() { +} - const Collection StandardTokenizer::TOKEN_TYPES() - { - static Collection _TOKEN_TYPES; - if (!_TOKEN_TYPES) - { - _TOKEN_TYPES = newCollection( - L"", - L"", - L"", - L"", - L"", - L"", - L"", - L"", - L"" - ); - } - return _TOKEN_TYPES; +const Collection StandardTokenizer::TOKEN_TYPES() { + static Collection _TOKEN_TYPES; + if (!_TOKEN_TYPES) { + _TOKEN_TYPES = newCollection( + L"", + L"", + L"", + L"", + L"", + L"", + L"", + L"", + L"" + ); } + return _TOKEN_TYPES; +} - void StandardTokenizer::init(const ReaderPtr& input, LuceneVersion::Version matchVersion) - { - replaceInvalidAcronym = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_24); - maxTokenLength = StandardAnalyzer::DEFAULT_MAX_TOKEN_LENGTH; - this->input = input; - termAtt = addAttribute(); - offsetAtt = addAttribute(); - posIncrAtt = addAttribute(); - typeAtt = addAttribute(); - } +void StandardTokenizer::init(const ReaderPtr& input, LuceneVersion::Version matchVersion) { + replaceInvalidAcronym = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_24); + maxTokenLength = StandardAnalyzer::DEFAULT_MAX_TOKEN_LENGTH; + this->input = input; + termAtt = addAttribute(); + offsetAtt = addAttribute(); + posIncrAtt = addAttribute(); + typeAtt = addAttribute(); +} - void StandardTokenizer::setMaxTokenLength(int32_t length) - { - this->maxTokenLength = length; - } +void StandardTokenizer::setMaxTokenLength(int32_t length) { + this->maxTokenLength = length; +} - int32_t StandardTokenizer::getMaxTokenLength() - { - return maxTokenLength; - } +int32_t StandardTokenizer::getMaxTokenLength() { + return maxTokenLength; +} - bool StandardTokenizer::incrementToken() - { - clearAttributes(); - int32_t posIncr = 1; - - while (true) - { - int32_t tokenType = scanner->getNextToken(); - - if (tokenType == StandardTokenizerImpl::YYEOF) - return false; - - if (scanner->yylength() <= maxTokenLength) - { - posIncrAtt->setPositionIncrement(posIncr); - scanner->getText(termAtt); - int32_t start = scanner->yychar(); - offsetAtt->setOffset(correctOffset(start), correctOffset(start + termAtt->termLength())); - - // This 'if' should be removed in the next release. For now, it converts invalid acronyms to HOST. - /// When removed, only the 'else' part should remain. - if (tokenType == ACRONYM_DEP) - { - if (replaceInvalidAcronym) - { - typeAtt->setType(TOKEN_TYPES()[HOST]); - termAtt->setTermLength(termAtt->termLength() - 1); // remove extra '.' - } - else - typeAtt->setType(TOKEN_TYPES()[ACRONYM]); +bool StandardTokenizer::incrementToken() { + clearAttributes(); + int32_t posIncr = 1; + + while (true) { + int32_t tokenType = scanner->getNextToken(); + + if (tokenType == StandardTokenizerImpl::YYEOF) { + return false; + } + + if (scanner->yylength() <= maxTokenLength) { + posIncrAtt->setPositionIncrement(posIncr); + scanner->getText(termAtt); + int32_t start = scanner->yychar(); + offsetAtt->setOffset(correctOffset(start), correctOffset(start + termAtt->termLength())); + + // This 'if' should be removed in the next release. For now, it converts invalid acronyms to HOST. + /// When removed, only the 'else' part should remain. + if (tokenType == ACRONYM_DEP) { + if (replaceInvalidAcronym) { + typeAtt->setType(TOKEN_TYPES()[HOST]); + termAtt->setTermLength(termAtt->termLength() - 1); // remove extra '.' + } else { + typeAtt->setType(TOKEN_TYPES()[ACRONYM]); } - else - typeAtt->setType(TOKEN_TYPES()[tokenType]); - return true; - } - else - { - // When we skip a too-long term, we still increment the position increment - ++posIncr; + } else { + typeAtt->setType(TOKEN_TYPES()[tokenType]); } + return true; + } else { + // When we skip a too-long term, we still increment the position increment + ++posIncr; } } +} - void StandardTokenizer::end() - { - // set final offset - int32_t finalOffset = correctOffset(scanner->yychar() + scanner->yylength()); - offsetAtt->setOffset(finalOffset, finalOffset); - } +void StandardTokenizer::end() { + // set final offset + int32_t finalOffset = correctOffset(scanner->yychar() + scanner->yylength()); + offsetAtt->setOffset(finalOffset, finalOffset); +} - void StandardTokenizer::reset(const ReaderPtr& input) - { - Tokenizer::reset(input); - scanner->reset(input); - } +void StandardTokenizer::reset(const ReaderPtr& input) { + Tokenizer::reset(input); + scanner->reset(input); +} - bool StandardTokenizer::isReplaceInvalidAcronym() - { - return replaceInvalidAcronym; - } +bool StandardTokenizer::isReplaceInvalidAcronym() { + return replaceInvalidAcronym; +} + +void StandardTokenizer::setReplaceInvalidAcronym(bool replaceInvalidAcronym) { + this->replaceInvalidAcronym = replaceInvalidAcronym; +} - void StandardTokenizer::setReplaceInvalidAcronym(bool replaceInvalidAcronym) - { - this->replaceInvalidAcronym = replaceInvalidAcronym; - } } diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index 993cfeaf..8384d966 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -14,562 +14,520 @@ #include -namespace Lucene -{ - /// Initial size of the lookahead buffer - const int32_t StandardTokenizerImpl::ZZ_BUFFERSIZE = 16384; - - /// Translates characters to character classes - CharArray StandardTokenizerImpl::_ZZ_CMAP; - const wchar_t StandardTokenizerImpl::ZZ_CMAP_PACKED[] = - { - L"\11\0\1\0\1\15\1\0\1\0\1\14\22\0\1\0\5\0\1\5" - L"\1\3\4\0\1\11\1\7\1\4\1\11\12\2\6\0\1\6\32\12" - L"\4\0\1\10\1\0\32\12\57\0\1\12\12\0\1\12\4\0\1\12" - L"\5\0\27\12\1\0\37\12\1\0\u0128\12\2\0\22\12\34\0\136\12" - L"\2\0\11\12\2\0\7\12\16\0\2\12\16\0\5\12\11\0\1\12" - L"\213\0\1\12\13\0\1\12\1\0\3\12\1\0\1\12\1\0\24\12" - L"\1\0\54\12\1\0\10\12\2\0\32\12\14\0\202\12\12\0\71\12" - L"\2\0\2\12\2\0\2\12\3\0\46\12\2\0\2\12\67\0\46\12" - L"\2\0\1\12\7\0\47\12\110\0\33\12\5\0\3\12\56\0\32\12" - L"\5\0\13\12\25\0\12\2\7\0\143\12\1\0\1\12\17\0\2\12" - L"\11\0\12\2\3\12\23\0\1\12\1\0\33\12\123\0\46\12\u015f\0" - L"\65\12\3\0\1\12\22\0\1\12\7\0\12\12\4\0\12\2\25\0" - L"\10\12\2\0\2\12\2\0\26\12\1\0\7\12\1\0\1\12\3\0" - L"\4\12\42\0\2\12\1\0\3\12\4\0\12\2\2\12\23\0\6\12" - L"\4\0\2\12\2\0\26\12\1\0\7\12\1\0\2\12\1\0\2\12" - L"\1\0\2\12\37\0\4\12\1\0\1\12\7\0\12\2\2\0\3\12" - L"\20\0\7\12\1\0\1\12\1\0\3\12\1\0\26\12\1\0\7\12" - L"\1\0\2\12\1\0\5\12\3\0\1\12\22\0\1\12\17\0\1\12" - L"\5\0\12\2\25\0\10\12\2\0\2\12\2\0\26\12\1\0\7\12" - L"\1\0\2\12\2\0\4\12\3\0\1\12\36\0\2\12\1\0\3\12" - L"\4\0\12\2\25\0\6\12\3\0\3\12\1\0\4\12\3\0\2\12" - L"\1\0\1\12\1\0\2\12\3\0\2\12\3\0\3\12\3\0\10\12" - L"\1\0\3\12\55\0\11\2\25\0\10\12\1\0\3\12\1\0\27\12" - L"\1\0\12\12\1\0\5\12\46\0\2\12\4\0\12\2\25\0\10\12" - L"\1\0\3\12\1\0\27\12\1\0\12\12\1\0\5\12\44\0\1\12" - L"\1\0\2\12\4\0\12\2\25\0\10\12\1\0\3\12\1\0\27\12" - L"\1\0\20\12\46\0\2\12\4\0\12\2\25\0\22\12\3\0\30\12" - L"\1\0\11\12\1\0\1\12\2\0\7\12\71\0\1\1\60\12\1\1" - L"\2\12\14\1\7\12\11\1\12\2\47\0\2\12\1\0\1\12\2\0" - L"\2\12\1\0\1\12\2\0\1\12\6\0\4\12\1\0\7\12\1\0" - L"\3\12\1\0\1\12\1\0\1\12\2\0\2\12\1\0\4\12\1\0" - L"\2\12\11\0\1\12\2\0\5\12\1\0\1\12\11\0\12\2\2\0" - L"\2\12\42\0\1\12\37\0\12\2\26\0\10\12\1\0\42\12\35\0" - L"\4\12\164\0\42\12\1\0\5\12\1\0\2\12\25\0\12\2\6\0" - L"\6\12\112\0\46\12\12\0\47\12\11\0\132\12\5\0\104\12\5\0" - L"\122\12\6\0\7\12\1\0\77\12\1\0\1\12\1\0\4\12\2\0" - L"\7\12\1\0\1\12\1\0\4\12\2\0\47\12\1\0\1\12\1\0" - L"\4\12\2\0\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0" - L"\1\12\1\0\4\12\2\0\7\12\1\0\7\12\1\0\27\12\1\0" - L"\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0\47\12\1\0" - L"\23\12\16\0\11\2\56\0\125\12\14\0\u026c\12\2\0\10\12\12\0" - L"\32\12\5\0\113\12\225\0\64\12\54\0\12\2\46\0\12\2\6\0" - L"\130\12\10\0\51\12\u0557\0\234\12\4\0\132\12\6\0\26\12\2\0" - L"\6\12\2\0\46\12\2\0\6\12\2\0\10\12\1\0\1\12\1\0" - L"\1\12\1\0\1\12\1\0\37\12\2\0\65\12\1\0\7\12\1\0" - L"\1\12\3\0\3\12\1\0\7\12\3\0\4\12\2\0\6\12\4\0" - L"\15\12\5\0\3\12\1\0\7\12\202\0\1\12\202\0\1\12\4\0" - L"\1\12\2\0\12\12\1\0\1\12\3\0\5\12\6\0\1\12\1\0" - L"\1\12\1\0\1\12\1\0\4\12\1\0\3\12\1\0\7\12\u0ecb\0" - L"\2\12\52\0\5\12\12\0\1\13\124\13\10\13\2\13\2\13\132\13" - L"\1\13\3\13\6\13\50\13\3\13\1\0\136\12\21\0\30\12\70\0" - L"\20\13\u0100\0\200\13\200\0\u19b6\13\12\13\100\0\u51a6\13\132\13\u048d\12" - L"\u0773\0\u2ba4\12\u215c\0\u012e\13\322\13\7\12\14\0\5\12\5\0\1\12" - L"\1\0\12\12\1\0\15\12\1\0\5\12\1\0\1\12\1\0\2\12" - L"\1\0\2\12\1\0\154\12\41\0\u016b\12\22\0\100\12\2\0\66\12" - L"\50\0\14\12\164\0\3\12\1\0\1\12\1\0\207\12\23\0\12\2" - L"\7\0\32\12\6\0\32\12\12\0\1\13\72\13\37\12\3\0\6\12" - L"\2\0\6\12\2\0\6\12\2\0\3\12\43\0" - }; - - const int32_t StandardTokenizerImpl::ZZ_CMAP_LENGTH = 65536; - const int32_t StandardTokenizerImpl::ZZ_CMAP_PACKED_LENGTH = 1154; - - IntArray StandardTokenizerImpl::_ZZ_ACTION; - const wchar_t StandardTokenizerImpl::ZZ_ACTION_PACKED_0[] = - { - L"\1\0\1\1\3\2\1\3\1\1\13\0\1\2\3\4" - L"\2\0\1\5\1\0\1\5\3\4\6\5\1\6\1\4" - L"\2\7\1\10\1\0\1\10\3\0\2\10\1\11\1\12" - L"\1\4" - }; - - const int32_t StandardTokenizerImpl::ZZ_ACTION_LENGTH = 51; - const int32_t StandardTokenizerImpl::ZZ_ACTION_PACKED_LENGTH = 50; - - IntArray StandardTokenizerImpl::_ZZ_ROWMAP; - const wchar_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_0[] = - { - L"\0\0\0\16\0\34\0\52\0\70\0\16\0\106\0\124" - L"\0\142\0\160\0\176\0\214\0\232\0\250\0\266\0\304" - L"\0\322\0\340\0\356\0\374\0\u010a\0\u0118\0\u0126\0\u0134" - L"\0\u0142\0\u0150\0\u015e\0\u016c\0\u017a\0\u0188\0\u0196\0\u01a4" - L"\0\u01b2\0\u01c0\0\u01ce\0\u01dc\0\u01ea\0\u01f8\0\322\0\u0206" - L"\0\u0214\0\u0222\0\u0230\0\u023e\0\u024c\0\u025a\0\124\0\214" - L"\0\u0268\0\u0276\0\u0284" - }; - - const int32_t StandardTokenizerImpl::ZZ_ROWMAP_LENGTH = 51; - const int32_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_LENGTH = 102; - - IntArray StandardTokenizerImpl::_ZZ_TRANS; - const wchar_t StandardTokenizerImpl::ZZ_TRANS_PACKED_0[] = - { - L"\1\2\1\3\1\4\7\2\1\5\1\6\1\7\1\2" - L"\17\0\2\3\1\0\1\10\1\0\1\11\2\12\1\13" - L"\1\3\4\0\1\3\1\4\1\0\1\14\1\0\1\11" - L"\2\15\1\16\1\4\4\0\1\3\1\4\1\17\1\20" - L"\1\21\1\22\2\12\1\13\1\23\20\0\1\2\1\0" - L"\1\24\1\25\7\0\1\26\4\0\2\27\7\0\1\27" - L"\4\0\1\30\1\31\7\0\1\32\5\0\1\33\7\0" - L"\1\13\4\0\1\34\1\35\7\0\1\36\4\0\1\37" - L"\1\40\7\0\1\41\4\0\1\42\1\43\7\0\1\44" - L"\15\0\1\45\4\0\1\24\1\25\7\0\1\46\15\0" - L"\1\47\4\0\2\27\7\0\1\50\4\0\1\3\1\4" - L"\1\17\1\10\1\21\1\22\2\12\1\13\1\23\4\0" - L"\2\24\1\0\1\51\1\0\1\11\2\52\1\0\1\24" - L"\4\0\1\24\1\25\1\0\1\53\1\0\1\11\2\54" - L"\1\55\1\25\4\0\1\24\1\25\1\0\1\51\1\0" - L"\1\11\2\52\1\0\1\26\4\0\2\27\1\0\1\56" - L"\2\0\1\56\2\0\1\27\4\0\2\30\1\0\1\52" - L"\1\0\1\11\2\52\1\0\1\30\4\0\1\30\1\31" - L"\1\0\1\54\1\0\1\11\2\54\1\55\1\31\4\0" - L"\1\30\1\31\1\0\1\52\1\0\1\11\2\52\1\0" - L"\1\32\5\0\1\33\1\0\1\55\2\0\3\55\1\33" - L"\4\0\2\34\1\0\1\57\1\0\1\11\2\12\1\13" - L"\1\34\4\0\1\34\1\35\1\0\1\60\1\0\1\11" - L"\2\15\1\16\1\35\4\0\1\34\1\35\1\0\1\57" - L"\1\0\1\11\2\12\1\13\1\36\4\0\2\37\1\0" - L"\1\12\1\0\1\11\2\12\1\13\1\37\4\0\1\37" - L"\1\40\1\0\1\15\1\0\1\11\2\15\1\16\1\40" - L"\4\0\1\37\1\40\1\0\1\12\1\0\1\11\2\12" - L"\1\13\1\41\4\0\2\42\1\0\1\13\2\0\3\13" - L"\1\42\4\0\1\42\1\43\1\0\1\16\2\0\3\16" - L"\1\43\4\0\1\42\1\43\1\0\1\13\2\0\3\13" - L"\1\44\6\0\1\17\6\0\1\45\4\0\1\24\1\25" - L"\1\0\1\61\1\0\1\11\2\52\1\0\1\26\4\0" - L"\2\27\1\0\1\56\2\0\1\56\2\0\1\50\4\0" - L"\2\24\7\0\1\24\4\0\2\30\7\0\1\30\4\0" - L"\2\34\7\0\1\34\4\0\2\37\7\0\1\37\4\0" - L"\2\42\7\0\1\42\4\0\2\62\7\0\1\62\4\0" - L"\2\24\7\0\1\63\4\0\2\62\1\0\1\56\2\0" - L"\1\56\2\0\1\62\4\0\2\24\1\0\1\61\1\0" - L"\1\11\2\52\1\0\1\24\3\0" - }; - - const int32_t StandardTokenizerImpl::ZZ_TRANS_LENGTH = 658; - const int32_t StandardTokenizerImpl::ZZ_TRANS_PACKED_LENGTH = 634; - - const int32_t StandardTokenizerImpl::ZZ_UNKNOWN_ERROR = 0; - const int32_t StandardTokenizerImpl::ZZ_NO_MATCH = 1; - const int32_t StandardTokenizerImpl::ZZ_PUSHBACK_2BIG = 2; - - const wchar_t* StandardTokenizerImpl::ZZ_ERROR_MSG[] = - { - L"Unknown internal scanner error", - L"Error: could not match input", - L"Error: pushback value was too large" - }; - - IntArray StandardTokenizerImpl::_ZZ_ATTRIBUTE; - const wchar_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_0[] = - { - L"\1\0\1\11\3\1\1\11\1\1\13\0\4\1\2\0" - L"\1\1\1\0\17\1\1\0\1\1\3\0\5\1" - }; - - const int32_t StandardTokenizerImpl::ZZ_ATTRIBUTE_LENGTH = 51; - const int32_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_LENGTH = 30; - - /// This character denotes the end of file - const int32_t StandardTokenizerImpl::YYEOF = -1; - - /// Lexical states - const int32_t StandardTokenizerImpl::YYINITIAL = 0; - - StandardTokenizerImpl::StandardTokenizerImpl(const ReaderPtr& in) - { - this->zzState = 0; - this->zzLexicalState = YYINITIAL; - this->zzBuffer = CharArray::newInstance(ZZ_BUFFERSIZE); - this->zzMarkedPos = 0; - this->zzPushbackPos = 0; - this->zzCurrentPos = 0; - this->zzStartRead = 0; - this->zzEndRead = 0; - this->yyline = 0; - this->_yychar = 0; - this->yycolumn = 0; - this->zzAtBOL = true; - this->zzAtEOF = false; - this->zzReader = in; - } +namespace Lucene { + +/// Initial size of the lookahead buffer +const int32_t StandardTokenizerImpl::ZZ_BUFFERSIZE = 16384; + +/// Translates characters to character classes +CharArray StandardTokenizerImpl::_ZZ_CMAP; +const wchar_t StandardTokenizerImpl::ZZ_CMAP_PACKED[] = { + L"\11\0\1\0\1\15\1\0\1\0\1\14\22\0\1\0\5\0\1\5" + L"\1\3\4\0\1\11\1\7\1\4\1\11\12\2\6\0\1\6\32\12" + L"\4\0\1\10\1\0\32\12\57\0\1\12\12\0\1\12\4\0\1\12" + L"\5\0\27\12\1\0\37\12\1\0\u0128\12\2\0\22\12\34\0\136\12" + L"\2\0\11\12\2\0\7\12\16\0\2\12\16\0\5\12\11\0\1\12" + L"\213\0\1\12\13\0\1\12\1\0\3\12\1\0\1\12\1\0\24\12" + L"\1\0\54\12\1\0\10\12\2\0\32\12\14\0\202\12\12\0\71\12" + L"\2\0\2\12\2\0\2\12\3\0\46\12\2\0\2\12\67\0\46\12" + L"\2\0\1\12\7\0\47\12\110\0\33\12\5\0\3\12\56\0\32\12" + L"\5\0\13\12\25\0\12\2\7\0\143\12\1\0\1\12\17\0\2\12" + L"\11\0\12\2\3\12\23\0\1\12\1\0\33\12\123\0\46\12\u015f\0" + L"\65\12\3\0\1\12\22\0\1\12\7\0\12\12\4\0\12\2\25\0" + L"\10\12\2\0\2\12\2\0\26\12\1\0\7\12\1\0\1\12\3\0" + L"\4\12\42\0\2\12\1\0\3\12\4\0\12\2\2\12\23\0\6\12" + L"\4\0\2\12\2\0\26\12\1\0\7\12\1\0\2\12\1\0\2\12" + L"\1\0\2\12\37\0\4\12\1\0\1\12\7\0\12\2\2\0\3\12" + L"\20\0\7\12\1\0\1\12\1\0\3\12\1\0\26\12\1\0\7\12" + L"\1\0\2\12\1\0\5\12\3\0\1\12\22\0\1\12\17\0\1\12" + L"\5\0\12\2\25\0\10\12\2\0\2\12\2\0\26\12\1\0\7\12" + L"\1\0\2\12\2\0\4\12\3\0\1\12\36\0\2\12\1\0\3\12" + L"\4\0\12\2\25\0\6\12\3\0\3\12\1\0\4\12\3\0\2\12" + L"\1\0\1\12\1\0\2\12\3\0\2\12\3\0\3\12\3\0\10\12" + L"\1\0\3\12\55\0\11\2\25\0\10\12\1\0\3\12\1\0\27\12" + L"\1\0\12\12\1\0\5\12\46\0\2\12\4\0\12\2\25\0\10\12" + L"\1\0\3\12\1\0\27\12\1\0\12\12\1\0\5\12\44\0\1\12" + L"\1\0\2\12\4\0\12\2\25\0\10\12\1\0\3\12\1\0\27\12" + L"\1\0\20\12\46\0\2\12\4\0\12\2\25\0\22\12\3\0\30\12" + L"\1\0\11\12\1\0\1\12\2\0\7\12\71\0\1\1\60\12\1\1" + L"\2\12\14\1\7\12\11\1\12\2\47\0\2\12\1\0\1\12\2\0" + L"\2\12\1\0\1\12\2\0\1\12\6\0\4\12\1\0\7\12\1\0" + L"\3\12\1\0\1\12\1\0\1\12\2\0\2\12\1\0\4\12\1\0" + L"\2\12\11\0\1\12\2\0\5\12\1\0\1\12\11\0\12\2\2\0" + L"\2\12\42\0\1\12\37\0\12\2\26\0\10\12\1\0\42\12\35\0" + L"\4\12\164\0\42\12\1\0\5\12\1\0\2\12\25\0\12\2\6\0" + L"\6\12\112\0\46\12\12\0\47\12\11\0\132\12\5\0\104\12\5\0" + L"\122\12\6\0\7\12\1\0\77\12\1\0\1\12\1\0\4\12\2\0" + L"\7\12\1\0\1\12\1\0\4\12\2\0\47\12\1\0\1\12\1\0" + L"\4\12\2\0\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0" + L"\1\12\1\0\4\12\2\0\7\12\1\0\7\12\1\0\27\12\1\0" + L"\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0\47\12\1\0" + L"\23\12\16\0\11\2\56\0\125\12\14\0\u026c\12\2\0\10\12\12\0" + L"\32\12\5\0\113\12\225\0\64\12\54\0\12\2\46\0\12\2\6\0" + L"\130\12\10\0\51\12\u0557\0\234\12\4\0\132\12\6\0\26\12\2\0" + L"\6\12\2\0\46\12\2\0\6\12\2\0\10\12\1\0\1\12\1\0" + L"\1\12\1\0\1\12\1\0\37\12\2\0\65\12\1\0\7\12\1\0" + L"\1\12\3\0\3\12\1\0\7\12\3\0\4\12\2\0\6\12\4\0" + L"\15\12\5\0\3\12\1\0\7\12\202\0\1\12\202\0\1\12\4\0" + L"\1\12\2\0\12\12\1\0\1\12\3\0\5\12\6\0\1\12\1\0" + L"\1\12\1\0\1\12\1\0\4\12\1\0\3\12\1\0\7\12\u0ecb\0" + L"\2\12\52\0\5\12\12\0\1\13\124\13\10\13\2\13\2\13\132\13" + L"\1\13\3\13\6\13\50\13\3\13\1\0\136\12\21\0\30\12\70\0" + L"\20\13\u0100\0\200\13\200\0\u19b6\13\12\13\100\0\u51a6\13\132\13\u048d\12" + L"\u0773\0\u2ba4\12\u215c\0\u012e\13\322\13\7\12\14\0\5\12\5\0\1\12" + L"\1\0\12\12\1\0\15\12\1\0\5\12\1\0\1\12\1\0\2\12" + L"\1\0\2\12\1\0\154\12\41\0\u016b\12\22\0\100\12\2\0\66\12" + L"\50\0\14\12\164\0\3\12\1\0\1\12\1\0\207\12\23\0\12\2" + L"\7\0\32\12\6\0\32\12\12\0\1\13\72\13\37\12\3\0\6\12" + L"\2\0\6\12\2\0\6\12\2\0\3\12\43\0" +}; + +const int32_t StandardTokenizerImpl::ZZ_CMAP_LENGTH = 65536; +const int32_t StandardTokenizerImpl::ZZ_CMAP_PACKED_LENGTH = 1154; + +IntArray StandardTokenizerImpl::_ZZ_ACTION; +const wchar_t StandardTokenizerImpl::ZZ_ACTION_PACKED_0[] = { + L"\1\0\1\1\3\2\1\3\1\1\13\0\1\2\3\4" + L"\2\0\1\5\1\0\1\5\3\4\6\5\1\6\1\4" + L"\2\7\1\10\1\0\1\10\3\0\2\10\1\11\1\12" + L"\1\4" +}; + +const int32_t StandardTokenizerImpl::ZZ_ACTION_LENGTH = 51; +const int32_t StandardTokenizerImpl::ZZ_ACTION_PACKED_LENGTH = 50; + +IntArray StandardTokenizerImpl::_ZZ_ROWMAP; +const wchar_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_0[] = { + L"\0\0\0\16\0\34\0\52\0\70\0\16\0\106\0\124" + L"\0\142\0\160\0\176\0\214\0\232\0\250\0\266\0\304" + L"\0\322\0\340\0\356\0\374\0\u010a\0\u0118\0\u0126\0\u0134" + L"\0\u0142\0\u0150\0\u015e\0\u016c\0\u017a\0\u0188\0\u0196\0\u01a4" + L"\0\u01b2\0\u01c0\0\u01ce\0\u01dc\0\u01ea\0\u01f8\0\322\0\u0206" + L"\0\u0214\0\u0222\0\u0230\0\u023e\0\u024c\0\u025a\0\124\0\214" + L"\0\u0268\0\u0276\0\u0284" +}; + +const int32_t StandardTokenizerImpl::ZZ_ROWMAP_LENGTH = 51; +const int32_t StandardTokenizerImpl::ZZ_ROWMAP_PACKED_LENGTH = 102; + +IntArray StandardTokenizerImpl::_ZZ_TRANS; +const wchar_t StandardTokenizerImpl::ZZ_TRANS_PACKED_0[] = { + L"\1\2\1\3\1\4\7\2\1\5\1\6\1\7\1\2" + L"\17\0\2\3\1\0\1\10\1\0\1\11\2\12\1\13" + L"\1\3\4\0\1\3\1\4\1\0\1\14\1\0\1\11" + L"\2\15\1\16\1\4\4\0\1\3\1\4\1\17\1\20" + L"\1\21\1\22\2\12\1\13\1\23\20\0\1\2\1\0" + L"\1\24\1\25\7\0\1\26\4\0\2\27\7\0\1\27" + L"\4\0\1\30\1\31\7\0\1\32\5\0\1\33\7\0" + L"\1\13\4\0\1\34\1\35\7\0\1\36\4\0\1\37" + L"\1\40\7\0\1\41\4\0\1\42\1\43\7\0\1\44" + L"\15\0\1\45\4\0\1\24\1\25\7\0\1\46\15\0" + L"\1\47\4\0\2\27\7\0\1\50\4\0\1\3\1\4" + L"\1\17\1\10\1\21\1\22\2\12\1\13\1\23\4\0" + L"\2\24\1\0\1\51\1\0\1\11\2\52\1\0\1\24" + L"\4\0\1\24\1\25\1\0\1\53\1\0\1\11\2\54" + L"\1\55\1\25\4\0\1\24\1\25\1\0\1\51\1\0" + L"\1\11\2\52\1\0\1\26\4\0\2\27\1\0\1\56" + L"\2\0\1\56\2\0\1\27\4\0\2\30\1\0\1\52" + L"\1\0\1\11\2\52\1\0\1\30\4\0\1\30\1\31" + L"\1\0\1\54\1\0\1\11\2\54\1\55\1\31\4\0" + L"\1\30\1\31\1\0\1\52\1\0\1\11\2\52\1\0" + L"\1\32\5\0\1\33\1\0\1\55\2\0\3\55\1\33" + L"\4\0\2\34\1\0\1\57\1\0\1\11\2\12\1\13" + L"\1\34\4\0\1\34\1\35\1\0\1\60\1\0\1\11" + L"\2\15\1\16\1\35\4\0\1\34\1\35\1\0\1\57" + L"\1\0\1\11\2\12\1\13\1\36\4\0\2\37\1\0" + L"\1\12\1\0\1\11\2\12\1\13\1\37\4\0\1\37" + L"\1\40\1\0\1\15\1\0\1\11\2\15\1\16\1\40" + L"\4\0\1\37\1\40\1\0\1\12\1\0\1\11\2\12" + L"\1\13\1\41\4\0\2\42\1\0\1\13\2\0\3\13" + L"\1\42\4\0\1\42\1\43\1\0\1\16\2\0\3\16" + L"\1\43\4\0\1\42\1\43\1\0\1\13\2\0\3\13" + L"\1\44\6\0\1\17\6\0\1\45\4\0\1\24\1\25" + L"\1\0\1\61\1\0\1\11\2\52\1\0\1\26\4\0" + L"\2\27\1\0\1\56\2\0\1\56\2\0\1\50\4\0" + L"\2\24\7\0\1\24\4\0\2\30\7\0\1\30\4\0" + L"\2\34\7\0\1\34\4\0\2\37\7\0\1\37\4\0" + L"\2\42\7\0\1\42\4\0\2\62\7\0\1\62\4\0" + L"\2\24\7\0\1\63\4\0\2\62\1\0\1\56\2\0" + L"\1\56\2\0\1\62\4\0\2\24\1\0\1\61\1\0" + L"\1\11\2\52\1\0\1\24\3\0" +}; + +const int32_t StandardTokenizerImpl::ZZ_TRANS_LENGTH = 658; +const int32_t StandardTokenizerImpl::ZZ_TRANS_PACKED_LENGTH = 634; + +const int32_t StandardTokenizerImpl::ZZ_UNKNOWN_ERROR = 0; +const int32_t StandardTokenizerImpl::ZZ_NO_MATCH = 1; +const int32_t StandardTokenizerImpl::ZZ_PUSHBACK_2BIG = 2; + +const wchar_t* StandardTokenizerImpl::ZZ_ERROR_MSG[] = { + L"Unknown internal scanner error", + L"Error: could not match input", + L"Error: pushback value was too large" +}; + +IntArray StandardTokenizerImpl::_ZZ_ATTRIBUTE; +const wchar_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_0[] = { + L"\1\0\1\11\3\1\1\11\1\1\13\0\4\1\2\0" + L"\1\1\1\0\17\1\1\0\1\1\3\0\5\1" +}; + +const int32_t StandardTokenizerImpl::ZZ_ATTRIBUTE_LENGTH = 51; +const int32_t StandardTokenizerImpl::ZZ_ATTRIBUTE_PACKED_LENGTH = 30; + +/// This character denotes the end of file +const int32_t StandardTokenizerImpl::YYEOF = -1; + +/// Lexical states +const int32_t StandardTokenizerImpl::YYINITIAL = 0; + +StandardTokenizerImpl::StandardTokenizerImpl(const ReaderPtr& in) { + this->zzState = 0; + this->zzLexicalState = YYINITIAL; + this->zzBuffer = CharArray::newInstance(ZZ_BUFFERSIZE); + this->zzMarkedPos = 0; + this->zzPushbackPos = 0; + this->zzCurrentPos = 0; + this->zzStartRead = 0; + this->zzEndRead = 0; + this->yyline = 0; + this->_yychar = 0; + this->yycolumn = 0; + this->zzAtBOL = true; + this->zzAtEOF = false; + this->zzReader = in; +} - StandardTokenizerImpl::~StandardTokenizerImpl() - { - } +StandardTokenizerImpl::~StandardTokenizerImpl() { +} - void StandardTokenizerImpl::ZZ_CMAP_INIT() - { - _ZZ_CMAP = CharArray::newInstance(ZZ_CMAP_LENGTH); - wchar_t* result = _ZZ_CMAP.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_CMAP_PACKED_LENGTH) - { - int32_t count = ZZ_CMAP_PACKED[i++]; - wchar_t value = ZZ_CMAP_PACKED[i++]; - do - result[j++] = value; - while (--count > 0); - } +void StandardTokenizerImpl::ZZ_CMAP_INIT() { + _ZZ_CMAP = CharArray::newInstance(ZZ_CMAP_LENGTH); + wchar_t* result = _ZZ_CMAP.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_CMAP_PACKED_LENGTH) { + int32_t count = ZZ_CMAP_PACKED[i++]; + wchar_t value = ZZ_CMAP_PACKED[i++]; + do { + result[j++] = value; + } while (--count > 0); } +} - const wchar_t* StandardTokenizerImpl::ZZ_CMAP() - { - static boost::once_flag once = BOOST_ONCE_INIT; - boost::call_once(once, ZZ_CMAP_INIT); - return _ZZ_CMAP.get(); - } +const wchar_t* StandardTokenizerImpl::ZZ_CMAP() { + static boost::once_flag once = BOOST_ONCE_INIT; + boost::call_once(once, ZZ_CMAP_INIT); + return _ZZ_CMAP.get(); +} - void StandardTokenizerImpl::ZZ_ACTION_INIT() - { - _ZZ_ACTION = IntArray::newInstance(ZZ_ACTION_LENGTH); - int32_t* result = _ZZ_ACTION.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_ACTION_PACKED_LENGTH) - { - int32_t count = ZZ_ACTION_PACKED_0[i++]; - int32_t value = ZZ_ACTION_PACKED_0[i++]; - do - result[j++] = value; - while (--count > 0); - } +void StandardTokenizerImpl::ZZ_ACTION_INIT() { + _ZZ_ACTION = IntArray::newInstance(ZZ_ACTION_LENGTH); + int32_t* result = _ZZ_ACTION.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_ACTION_PACKED_LENGTH) { + int32_t count = ZZ_ACTION_PACKED_0[i++]; + int32_t value = ZZ_ACTION_PACKED_0[i++]; + do { + result[j++] = value; + } while (--count > 0); } +} - const int32_t* StandardTokenizerImpl::ZZ_ACTION() - { - static boost::once_flag once = BOOST_ONCE_INIT; - boost::call_once(once, ZZ_ACTION_INIT); - return _ZZ_ACTION.get(); - } +const int32_t* StandardTokenizerImpl::ZZ_ACTION() { + static boost::once_flag once = BOOST_ONCE_INIT; + boost::call_once(once, ZZ_ACTION_INIT); + return _ZZ_ACTION.get(); +} - void StandardTokenizerImpl::ZZ_ROWMAP_INIT() - { - _ZZ_ROWMAP = IntArray::newInstance(ZZ_ROWMAP_LENGTH); - int32_t* result = _ZZ_ROWMAP.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_ROWMAP_PACKED_LENGTH) - { - int32_t high = ZZ_ROWMAP_PACKED_0[i++] << 16; - result[j++] = high | ZZ_ROWMAP_PACKED_0[i++]; - } - } +void StandardTokenizerImpl::ZZ_ROWMAP_INIT() { + _ZZ_ROWMAP = IntArray::newInstance(ZZ_ROWMAP_LENGTH); + int32_t* result = _ZZ_ROWMAP.get(); - const int32_t* StandardTokenizerImpl::ZZ_ROWMAP() - { - static boost::once_flag once = BOOST_ONCE_INIT; - boost::call_once(once, ZZ_ROWMAP_INIT); - return _ZZ_ROWMAP.get(); + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_ROWMAP_PACKED_LENGTH) { + int32_t high = ZZ_ROWMAP_PACKED_0[i++] << 16; + result[j++] = high | ZZ_ROWMAP_PACKED_0[i++]; } +} - void StandardTokenizerImpl::ZZ_TRANS_INIT() - { - _ZZ_TRANS = IntArray::newInstance(ZZ_TRANS_LENGTH); - int32_t* result = _ZZ_TRANS.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_TRANS_PACKED_LENGTH) - { - int32_t count = ZZ_TRANS_PACKED_0[i++]; - int32_t value = ZZ_TRANS_PACKED_0[i++]; - --value; - do - result[j++] = value; - while (--count > 0); - } - } +const int32_t* StandardTokenizerImpl::ZZ_ROWMAP() { + static boost::once_flag once = BOOST_ONCE_INIT; + boost::call_once(once, ZZ_ROWMAP_INIT); + return _ZZ_ROWMAP.get(); +} - const int32_t* StandardTokenizerImpl::ZZ_TRANS() - { - static boost::once_flag once = BOOST_ONCE_INIT; - boost::call_once(once, ZZ_TRANS_INIT); - return _ZZ_TRANS.get(); +void StandardTokenizerImpl::ZZ_TRANS_INIT() { + _ZZ_TRANS = IntArray::newInstance(ZZ_TRANS_LENGTH); + int32_t* result = _ZZ_TRANS.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_TRANS_PACKED_LENGTH) { + int32_t count = ZZ_TRANS_PACKED_0[i++]; + int32_t value = ZZ_TRANS_PACKED_0[i++]; + --value; + do { + result[j++] = value; + } while (--count > 0); } +} - void StandardTokenizerImpl::ZZ_ATTRIBUTE_INIT() - { - _ZZ_ATTRIBUTE = IntArray::newInstance(ZZ_ATTRIBUTE_LENGTH); - int32_t* result = _ZZ_ATTRIBUTE.get(); - - int32_t i = 0; // index in packed string - int32_t j = 0; // index in unpacked array - while (i < ZZ_ATTRIBUTE_PACKED_LENGTH) - { - int32_t count = ZZ_ATTRIBUTE_PACKED_0[i++]; - int32_t value = ZZ_ATTRIBUTE_PACKED_0[i++]; - do - result[j++] = value; - while (--count > 0); - } - } +const int32_t* StandardTokenizerImpl::ZZ_TRANS() { + static boost::once_flag once = BOOST_ONCE_INIT; + boost::call_once(once, ZZ_TRANS_INIT); + return _ZZ_TRANS.get(); +} - const int32_t* StandardTokenizerImpl::ZZ_ATTRIBUTE() - { - static boost::once_flag once = BOOST_ONCE_INIT; - boost::call_once(once, ZZ_ATTRIBUTE_INIT); - return _ZZ_ATTRIBUTE.get(); +void StandardTokenizerImpl::ZZ_ATTRIBUTE_INIT() { + _ZZ_ATTRIBUTE = IntArray::newInstance(ZZ_ATTRIBUTE_LENGTH); + int32_t* result = _ZZ_ATTRIBUTE.get(); + + int32_t i = 0; // index in packed string + int32_t j = 0; // index in unpacked array + while (i < ZZ_ATTRIBUTE_PACKED_LENGTH) { + int32_t count = ZZ_ATTRIBUTE_PACKED_0[i++]; + int32_t value = ZZ_ATTRIBUTE_PACKED_0[i++]; + do { + result[j++] = value; + } while (--count > 0); } +} - int32_t StandardTokenizerImpl::yychar() - { - return _yychar; - } +const int32_t* StandardTokenizerImpl::ZZ_ATTRIBUTE() { + static boost::once_flag once = BOOST_ONCE_INIT; + boost::call_once(once, ZZ_ATTRIBUTE_INIT); + return _ZZ_ATTRIBUTE.get(); +} - void StandardTokenizerImpl::reset(const ReaderPtr& r) - { - // reset to default buffer size, if buffer has grown - if (zzBuffer.size() > ZZ_BUFFERSIZE) - zzBuffer.resize(ZZ_BUFFERSIZE); - yyreset(r); - } +int32_t StandardTokenizerImpl::yychar() { + return _yychar; +} - void StandardTokenizerImpl::getText(const TokenPtr& t) - { - t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); +void StandardTokenizerImpl::reset(const ReaderPtr& r) { + // reset to default buffer size, if buffer has grown + if (zzBuffer.size() > ZZ_BUFFERSIZE) { + zzBuffer.resize(ZZ_BUFFERSIZE); } + yyreset(r); +} - void StandardTokenizerImpl::getText(const TermAttributePtr& t) - { - t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); - } +void StandardTokenizerImpl::getText(const TokenPtr& t) { + t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); +} - bool StandardTokenizerImpl::zzRefill() - { - // first: make room (if you can) - if (zzStartRead > 0) - { - MiscUtils::arrayCopy(zzBuffer.get(), zzStartRead, zzBuffer.get(), 0, zzEndRead - zzStartRead); - - // translate stored positions - zzEndRead -= zzStartRead; - zzCurrentPos -= zzStartRead; - zzMarkedPos -= zzStartRead; - zzPushbackPos -= zzStartRead; - zzStartRead = 0; - } +void StandardTokenizerImpl::getText(const TermAttributePtr& t) { + t->setTermBuffer(zzBuffer.get(), zzStartRead, zzMarkedPos - zzStartRead); +} - // is the buffer big enough? - if (zzCurrentPos >= zzBuffer.size()) - zzBuffer.resize(zzCurrentPos * 2); +bool StandardTokenizerImpl::zzRefill() { + // first: make room (if you can) + if (zzStartRead > 0) { + MiscUtils::arrayCopy(zzBuffer.get(), zzStartRead, zzBuffer.get(), 0, zzEndRead - zzStartRead); - // finally: fill the buffer with new input - int32_t numRead = zzReader->read(zzBuffer.get(), zzEndRead, zzBuffer.size() - zzEndRead); + // translate stored positions + zzEndRead -= zzStartRead; + zzCurrentPos -= zzStartRead; + zzMarkedPos -= zzStartRead; + zzPushbackPos -= zzStartRead; + zzStartRead = 0; + } - if (numRead < 0) - return true; - else - { - zzEndRead += numRead; - return false; - } + // is the buffer big enough? + if (zzCurrentPos >= zzBuffer.size()) { + zzBuffer.resize(zzCurrentPos * 2); } - void StandardTokenizerImpl::yyclose() - { - zzAtEOF = true; // indicate end of file - zzEndRead = zzStartRead; // invalidate buffer + // finally: fill the buffer with new input + int32_t numRead = zzReader->read(zzBuffer.get(), zzEndRead, zzBuffer.size() - zzEndRead); - if (zzReader) - zzReader->close(); + if (numRead < 0) { + return true; + } else { + zzEndRead += numRead; + return false; } +} - void StandardTokenizerImpl::yyreset(const ReaderPtr& reader) - { - zzReader = reader; - zzAtBOL = true; - zzAtEOF = false; - zzEndRead = 0; - zzStartRead = 0; - zzCurrentPos = 0; - zzMarkedPos = 0; - zzPushbackPos = 0; - yyline = 0; - _yychar = 0; - yycolumn = 0; - zzLexicalState = YYINITIAL; - } +void StandardTokenizerImpl::yyclose() { + zzAtEOF = true; // indicate end of file + zzEndRead = zzStartRead; // invalidate buffer - int32_t StandardTokenizerImpl::yystate() - { - return zzLexicalState; + if (zzReader) { + zzReader->close(); } +} - void StandardTokenizerImpl::yybegin(int32_t newState) - { - zzLexicalState = newState; - } +void StandardTokenizerImpl::yyreset(const ReaderPtr& reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = 0; + zzStartRead = 0; + zzCurrentPos = 0; + zzMarkedPos = 0; + zzPushbackPos = 0; + yyline = 0; + _yychar = 0; + yycolumn = 0; + zzLexicalState = YYINITIAL; +} - String StandardTokenizerImpl::yytext() - { - return String(zzBuffer.get() + zzStartRead, zzMarkedPos - zzStartRead); - } +int32_t StandardTokenizerImpl::yystate() { + return zzLexicalState; +} - wchar_t StandardTokenizerImpl::yycharat(int32_t pos) - { - return zzBuffer[zzStartRead + pos]; - } +void StandardTokenizerImpl::yybegin(int32_t newState) { + zzLexicalState = newState; +} - int32_t StandardTokenizerImpl::yylength() - { - return zzMarkedPos - zzStartRead; - } +String StandardTokenizerImpl::yytext() { + return String(zzBuffer.get() + zzStartRead, zzMarkedPos - zzStartRead); +} - void StandardTokenizerImpl::zzScanError(int32_t errorCode) - { - boost::throw_exception(ParseException(ZZ_ERROR_MSG[errorCode])); - } +wchar_t StandardTokenizerImpl::yycharat(int32_t pos) { + return zzBuffer[zzStartRead + pos]; +} + +int32_t StandardTokenizerImpl::yylength() { + return zzMarkedPos - zzStartRead; +} + +void StandardTokenizerImpl::zzScanError(int32_t errorCode) { + boost::throw_exception(ParseException(ZZ_ERROR_MSG[errorCode])); +} - void StandardTokenizerImpl::yypushback(int32_t number) - { - if (number > yylength()) - zzScanError(ZZ_PUSHBACK_2BIG); - zzMarkedPos -= number; +void StandardTokenizerImpl::yypushback(int32_t number) { + if (number > yylength()) { + zzScanError(ZZ_PUSHBACK_2BIG); } + zzMarkedPos -= number; +} - int32_t StandardTokenizerImpl::getNextToken() - { - int32_t zzInput; - int32_t zzAction; - - // cached fields - int32_t zzCurrentPosL; - int32_t zzMarkedPosL; - int32_t zzEndReadL = zzEndRead; - wchar_t* zzBufferL = zzBuffer.get(); - const wchar_t* zzCMapL = ZZ_CMAP(); - - const int32_t* zzTransL = ZZ_TRANS(); - const int32_t* zzRowMapL = ZZ_ROWMAP(); - const int32_t* zzAttrL = ZZ_ATTRIBUTE(); - const int32_t* zzActionL = ZZ_ACTION(); - - while (true) - { - zzMarkedPosL = zzMarkedPos; - _yychar += zzMarkedPosL - zzStartRead; - zzAction = -1; - zzCurrentPosL = zzMarkedPosL; - zzCurrentPos = zzMarkedPosL; - zzStartRead = zzMarkedPosL; - zzState = zzLexicalState; - - while (true) - { - if (zzCurrentPosL < zzEndReadL) - zzInput = zzBufferL[zzCurrentPosL++]; - else if (zzAtEOF) - { +int32_t StandardTokenizerImpl::getNextToken() { + int32_t zzInput; + int32_t zzAction; + + // cached fields + int32_t zzCurrentPosL; + int32_t zzMarkedPosL; + int32_t zzEndReadL = zzEndRead; + wchar_t* zzBufferL = zzBuffer.get(); + const wchar_t* zzCMapL = ZZ_CMAP(); + + const int32_t* zzTransL = ZZ_TRANS(); + const int32_t* zzRowMapL = ZZ_ROWMAP(); + const int32_t* zzAttrL = ZZ_ATTRIBUTE(); + const int32_t* zzActionL = ZZ_ACTION(); + + while (true) { + zzMarkedPosL = zzMarkedPos; + _yychar += zzMarkedPosL - zzStartRead; + zzAction = -1; + zzCurrentPosL = zzMarkedPosL; + zzCurrentPos = zzMarkedPosL; + zzStartRead = zzMarkedPosL; + zzState = zzLexicalState; + + while (true) { + if (zzCurrentPosL < zzEndReadL) { + zzInput = zzBufferL[zzCurrentPosL++]; + } else if (zzAtEOF) { + zzInput = YYEOF; + break; + } else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + bool eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer.get(); + zzEndReadL = zzEndRead; + if (eof) { zzInput = YYEOF; break; - } - else - { - // store back cached positions - zzCurrentPos = zzCurrentPosL; - zzMarkedPos = zzMarkedPosL; - bool eof = zzRefill(); - // get translated positions and possibly new buffer - zzCurrentPosL = zzCurrentPos; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer.get(); - zzEndReadL = zzEndRead; - if (eof) - { - zzInput = YYEOF; - break; - } - else - zzInput = zzBufferL[zzCurrentPosL++]; - } - - int32_t zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; - if (zzNext == -1) - break; - zzState = zzNext; - - int32_t zzAttributes = zzAttrL[zzState]; - if ((zzAttributes & 1) == 1) - { - zzAction = zzState; - zzMarkedPosL = zzCurrentPosL; - if ((zzAttributes & 8) == 8) - break; + } else { + zzInput = zzBufferL[zzCurrentPosL++]; } } - // store back cached position - zzMarkedPos = zzMarkedPosL; + int32_t zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; + if (zzNext == -1) { + break; + } + zzState = zzNext; - switch (zzAction < 0 ? zzAction : zzActionL[zzAction]) - { - case 4: - return StandardTokenizer::HOST; - case 11: - break; - case 9: - return StandardTokenizer::ACRONYM; - case 12: - break; - case 8: - return StandardTokenizer::ACRONYM_DEP; - case 13: - break; - case 1: // ignore - case 14: - break; - case 5: - return StandardTokenizer::NUM; - case 15: - break; - case 3: - return StandardTokenizer::CJ; - case 16: - break; - case 2: - return StandardTokenizer::ALPHANUM; - case 17: + int32_t zzAttributes = zzAttrL[zzState]; + if ((zzAttributes & 1) == 1) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ((zzAttributes & 8) == 8) { break; - case 7: - return StandardTokenizer::COMPANY; - case 18: - break; - case 6: - return StandardTokenizer::APOSTROPHE; - case 19: - break; - case 10: - return StandardTokenizer::EMAIL; - case 20: - break; - default: - if (zzInput == YYEOF && zzStartRead == zzCurrentPos) - { - zzAtEOF = true; - return YYEOF; - } - else - zzScanError(ZZ_NO_MATCH); + } } } - return YYINITIAL; + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : zzActionL[zzAction]) { + case 4: + return StandardTokenizer::HOST; + case 11: + break; + case 9: + return StandardTokenizer::ACRONYM; + case 12: + break; + case 8: + return StandardTokenizer::ACRONYM_DEP; + case 13: + break; + case 1: // ignore + case 14: + break; + case 5: + return StandardTokenizer::NUM; + case 15: + break; + case 3: + return StandardTokenizer::CJ; + case 16: + break; + case 2: + return StandardTokenizer::ALPHANUM; + case 17: + break; + case 7: + return StandardTokenizer::COMPANY; + case 18: + break; + case 6: + return StandardTokenizer::APOSTROPHE; + case 19: + break; + case 10: + return StandardTokenizer::EMAIL; + case 20: + break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + return YYEOF; + } else { + zzScanError(ZZ_NO_MATCH); + } + } } + + return YYINITIAL; +} + } diff --git a/src/core/analysis/tokenattributes/FlagsAttribute.cpp b/src/core/analysis/tokenattributes/FlagsAttribute.cpp index aa86a64f..67a260cd 100644 --- a/src/core/analysis/tokenattributes/FlagsAttribute.cpp +++ b/src/core/analysis/tokenattributes/FlagsAttribute.cpp @@ -8,64 +8,57 @@ #include "FlagsAttribute.h" #include "StringUtils.h" -namespace Lucene -{ - FlagsAttribute::FlagsAttribute() - { - flags = 0; - } - - FlagsAttribute::~FlagsAttribute() - { - } +namespace Lucene { - String FlagsAttribute::toString() - { - return L"flags=" + StringUtils::toString(flags); - } +FlagsAttribute::FlagsAttribute() { + flags = 0; +} - int32_t FlagsAttribute::getFlags() - { - return flags; - } +FlagsAttribute::~FlagsAttribute() { +} - void FlagsAttribute::setFlags(int32_t flags) - { - this->flags = flags; - } +String FlagsAttribute::toString() { + return L"flags=" + StringUtils::toString(flags); +} - void FlagsAttribute::clear() - { - flags = 0; - } +int32_t FlagsAttribute::getFlags() { + return flags; +} - bool FlagsAttribute::equals(const LuceneObjectPtr& other) - { - if (Attribute::equals(other)) - return true; +void FlagsAttribute::setFlags(int32_t flags) { + this->flags = flags; +} - FlagsAttributePtr otherFlagsAttribute(boost::dynamic_pointer_cast(other)); - if (otherFlagsAttribute) - return (otherFlagsAttribute->flags == flags); +void FlagsAttribute::clear() { + flags = 0; +} - return false; +bool FlagsAttribute::equals(const LuceneObjectPtr& other) { + if (Attribute::equals(other)) { + return true; } - int32_t FlagsAttribute::hashCode() - { - return flags; + FlagsAttributePtr otherFlagsAttribute(boost::dynamic_pointer_cast(other)); + if (otherFlagsAttribute) { + return (otherFlagsAttribute->flags == flags); } - void FlagsAttribute::copyTo(const AttributePtr& target) - { - boost::dynamic_pointer_cast(target)->setFlags(flags); - } + return false; +} + +int32_t FlagsAttribute::hashCode() { + return flags; +} + +void FlagsAttribute::copyTo(const AttributePtr& target) { + boost::dynamic_pointer_cast(target)->setFlags(flags); +} + +LuceneObjectPtr FlagsAttribute::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + FlagsAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); + cloneAttribute->flags = flags; + return cloneAttribute; +} - LuceneObjectPtr FlagsAttribute::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - FlagsAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); - cloneAttribute->flags = flags; - return cloneAttribute; - } } diff --git a/src/core/analysis/tokenattributes/OffsetAttribute.cpp b/src/core/analysis/tokenattributes/OffsetAttribute.cpp index bde260af..4f20c61c 100644 --- a/src/core/analysis/tokenattributes/OffsetAttribute.cpp +++ b/src/core/analysis/tokenattributes/OffsetAttribute.cpp @@ -8,76 +8,68 @@ #include "OffsetAttribute.h" #include "StringUtils.h" -namespace Lucene -{ - OffsetAttribute::OffsetAttribute() - { - _startOffset = 0; - _endOffset = 0; - } - - OffsetAttribute::~OffsetAttribute() - { - } +namespace Lucene { - String OffsetAttribute::toString() - { - return L"startOffset=" + StringUtils::toString(_startOffset) + L";endOffset=" + StringUtils::toString(_endOffset); - } +OffsetAttribute::OffsetAttribute() { + _startOffset = 0; + _endOffset = 0; +} - int32_t OffsetAttribute::startOffset() - { - return _startOffset; - } +OffsetAttribute::~OffsetAttribute() { +} - void OffsetAttribute::setOffset(int32_t startOffset, int32_t endOffset) - { - this->_startOffset = startOffset; - this->_endOffset = endOffset; - } +String OffsetAttribute::toString() { + return L"startOffset=" + StringUtils::toString(_startOffset) + L";endOffset=" + StringUtils::toString(_endOffset); +} - int32_t OffsetAttribute::endOffset() - { - return _endOffset; - } +int32_t OffsetAttribute::startOffset() { + return _startOffset; +} - void OffsetAttribute::clear() - { - _startOffset = 0; - _endOffset = 0; - } +void OffsetAttribute::setOffset(int32_t startOffset, int32_t endOffset) { + this->_startOffset = startOffset; + this->_endOffset = endOffset; +} - bool OffsetAttribute::equals(const LuceneObjectPtr& other) - { - if (Attribute::equals(other)) - return true; +int32_t OffsetAttribute::endOffset() { + return _endOffset; +} - OffsetAttributePtr otherOffsetAttribute(boost::dynamic_pointer_cast(other)); - if (otherOffsetAttribute) - return (otherOffsetAttribute->_startOffset == _startOffset && otherOffsetAttribute->_endOffset == _endOffset); +void OffsetAttribute::clear() { + _startOffset = 0; + _endOffset = 0; +} - return false; +bool OffsetAttribute::equals(const LuceneObjectPtr& other) { + if (Attribute::equals(other)) { + return true; } - int32_t OffsetAttribute::hashCode() - { - int32_t code = _startOffset; - code = code * 31 + _endOffset; - return code; + OffsetAttributePtr otherOffsetAttribute(boost::dynamic_pointer_cast(other)); + if (otherOffsetAttribute) { + return (otherOffsetAttribute->_startOffset == _startOffset && otherOffsetAttribute->_endOffset == _endOffset); } - void OffsetAttribute::copyTo(const AttributePtr& target) - { - OffsetAttributePtr targetOffsetAttribute(boost::dynamic_pointer_cast(target)); - targetOffsetAttribute->setOffset(_startOffset, _endOffset); - } + return false; +} + +int32_t OffsetAttribute::hashCode() { + int32_t code = _startOffset; + code = code * 31 + _endOffset; + return code; +} + +void OffsetAttribute::copyTo(const AttributePtr& target) { + OffsetAttributePtr targetOffsetAttribute(boost::dynamic_pointer_cast(target)); + targetOffsetAttribute->setOffset(_startOffset, _endOffset); +} + +LuceneObjectPtr OffsetAttribute::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + OffsetAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); + cloneAttribute->_startOffset = _startOffset; + cloneAttribute->_endOffset = _endOffset; + return cloneAttribute; +} - LuceneObjectPtr OffsetAttribute::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - OffsetAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); - cloneAttribute->_startOffset = _startOffset; - cloneAttribute->_endOffset = _endOffset; - return cloneAttribute; - } } diff --git a/src/core/analysis/tokenattributes/PayloadAttribute.cpp b/src/core/analysis/tokenattributes/PayloadAttribute.cpp index c9ae6d83..217056da 100644 --- a/src/core/analysis/tokenattributes/PayloadAttribute.cpp +++ b/src/core/analysis/tokenattributes/PayloadAttribute.cpp @@ -9,74 +9,66 @@ #include "Payload.h" #include "StringUtils.h" -namespace Lucene -{ - PayloadAttribute::PayloadAttribute() - { - } +namespace Lucene { - PayloadAttribute::PayloadAttribute(const PayloadPtr& payload) - { - this->payload = payload; - } +PayloadAttribute::PayloadAttribute() { +} - PayloadAttribute::~PayloadAttribute() - { - } +PayloadAttribute::PayloadAttribute(const PayloadPtr& payload) { + this->payload = payload; +} - String PayloadAttribute::toString() - { - return L"payload(length)=" + StringUtils::toString(payload->length()); - } +PayloadAttribute::~PayloadAttribute() { +} - PayloadPtr PayloadAttribute::getPayload() - { - return this->payload; - } +String PayloadAttribute::toString() { + return L"payload(length)=" + StringUtils::toString(payload->length()); +} - void PayloadAttribute::setPayload(const PayloadPtr& payload) - { - this->payload = payload; - } +PayloadPtr PayloadAttribute::getPayload() { + return this->payload; +} + +void PayloadAttribute::setPayload(const PayloadPtr& payload) { + this->payload = payload; +} - void PayloadAttribute::clear() - { - payload.reset(); +void PayloadAttribute::clear() { + payload.reset(); +} + +LuceneObjectPtr PayloadAttribute::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); + PayloadAttributePtr cloneAttribute(boost::dynamic_pointer_cast(clone)); + if (payload) { + cloneAttribute->payload = boost::dynamic_pointer_cast(payload->clone()); } + return cloneAttribute; +} - LuceneObjectPtr PayloadAttribute::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); - PayloadAttributePtr cloneAttribute(boost::dynamic_pointer_cast(clone)); - if (payload) - cloneAttribute->payload = boost::dynamic_pointer_cast(payload->clone()); - return cloneAttribute; +bool PayloadAttribute::equals(const LuceneObjectPtr& other) { + if (Attribute::equals(other)) { + return true; } - bool PayloadAttribute::equals(const LuceneObjectPtr& other) - { - if (Attribute::equals(other)) + PayloadAttributePtr otherAttribute(boost::dynamic_pointer_cast(other)); + if (otherAttribute) { + if (!otherAttribute->payload && !payload) { return true; - - PayloadAttributePtr otherAttribute(boost::dynamic_pointer_cast(other)); - if (otherAttribute) - { - if (!otherAttribute->payload && !payload) - return true; - return otherAttribute->payload->equals(payload); } - - return false; + return otherAttribute->payload->equals(payload); } - int32_t PayloadAttribute::hashCode() - { - return payload ? payload->hashCode() : 0; - } + return false; +} + +int32_t PayloadAttribute::hashCode() { + return payload ? payload->hashCode() : 0; +} + +void PayloadAttribute::copyTo(const AttributePtr& target) { + PayloadAttributePtr targetPayloadAttribute(boost::dynamic_pointer_cast(target)); + targetPayloadAttribute->setPayload(payload ? boost::dynamic_pointer_cast(payload->clone()) : PayloadPtr()); +} - void PayloadAttribute::copyTo(const AttributePtr& target) - { - PayloadAttributePtr targetPayloadAttribute(boost::dynamic_pointer_cast(target)); - targetPayloadAttribute->setPayload(payload ? boost::dynamic_pointer_cast(payload->clone()) : PayloadPtr()); - } } diff --git a/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp b/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp index 8fc16e34..a6610aa3 100644 --- a/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp +++ b/src/core/analysis/tokenattributes/PositionIncrementAttribute.cpp @@ -8,67 +8,61 @@ #include "PositionIncrementAttribute.h" #include "StringUtils.h" -namespace Lucene -{ - PositionIncrementAttribute::PositionIncrementAttribute() - { - positionIncrement = 1; - } - - PositionIncrementAttribute::~PositionIncrementAttribute() - { - } +namespace Lucene { - String PositionIncrementAttribute::toString() - { - return L"positionIncrement=" + StringUtils::toString(positionIncrement); - } +PositionIncrementAttribute::PositionIncrementAttribute() { + positionIncrement = 1; +} - void PositionIncrementAttribute::setPositionIncrement(int32_t positionIncrement) - { - if (positionIncrement < 0) - boost::throw_exception(IllegalArgumentException(L"Increment must be zero or greater: " + StringUtils::toString(positionIncrement))); - this->positionIncrement = positionIncrement; - } +PositionIncrementAttribute::~PositionIncrementAttribute() { +} - int32_t PositionIncrementAttribute::getPositionIncrement() - { - return positionIncrement; - } +String PositionIncrementAttribute::toString() { + return L"positionIncrement=" + StringUtils::toString(positionIncrement); +} - void PositionIncrementAttribute::clear() - { - this->positionIncrement = 1; +void PositionIncrementAttribute::setPositionIncrement(int32_t positionIncrement) { + if (positionIncrement < 0) { + boost::throw_exception(IllegalArgumentException(L"Increment must be zero or greater: " + StringUtils::toString(positionIncrement))); } + this->positionIncrement = positionIncrement; +} - bool PositionIncrementAttribute::equals(const LuceneObjectPtr& other) - { - if (Attribute::equals(other)) - return true; +int32_t PositionIncrementAttribute::getPositionIncrement() { + return positionIncrement; +} - PositionIncrementAttributePtr otherPositionIncrementAttribute(boost::dynamic_pointer_cast(other)); - if (otherPositionIncrementAttribute) - return positionIncrement == otherPositionIncrementAttribute->positionIncrement; +void PositionIncrementAttribute::clear() { + this->positionIncrement = 1; +} - return false; +bool PositionIncrementAttribute::equals(const LuceneObjectPtr& other) { + if (Attribute::equals(other)) { + return true; } - int32_t PositionIncrementAttribute::hashCode() - { - return positionIncrement; + PositionIncrementAttributePtr otherPositionIncrementAttribute(boost::dynamic_pointer_cast(other)); + if (otherPositionIncrementAttribute) { + return positionIncrement == otherPositionIncrementAttribute->positionIncrement; } - void PositionIncrementAttribute::copyTo(const AttributePtr& target) - { - PositionIncrementAttributePtr targetPositionIncrementAttribute(boost::dynamic_pointer_cast(target)); - targetPositionIncrementAttribute->setPositionIncrement(positionIncrement); - } + return false; +} + +int32_t PositionIncrementAttribute::hashCode() { + return positionIncrement; +} + +void PositionIncrementAttribute::copyTo(const AttributePtr& target) { + PositionIncrementAttributePtr targetPositionIncrementAttribute(boost::dynamic_pointer_cast(target)); + targetPositionIncrementAttribute->setPositionIncrement(positionIncrement); +} + +LuceneObjectPtr PositionIncrementAttribute::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + PositionIncrementAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); + cloneAttribute->positionIncrement = positionIncrement; + return cloneAttribute; +} - LuceneObjectPtr PositionIncrementAttribute::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - PositionIncrementAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); - cloneAttribute->positionIncrement = positionIncrement; - return cloneAttribute; - } } diff --git a/src/core/analysis/tokenattributes/TermAttribute.cpp b/src/core/analysis/tokenattributes/TermAttribute.cpp index aaf2aaa6..e98fe628 100644 --- a/src/core/analysis/tokenattributes/TermAttribute.cpp +++ b/src/core/analysis/tokenattributes/TermAttribute.cpp @@ -9,159 +9,141 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t TermAttribute::MIN_BUFFER_SIZE = 10; +namespace Lucene { - TermAttribute::TermAttribute() - { - _termLength = 0; - } +const int32_t TermAttribute::MIN_BUFFER_SIZE = 10; - TermAttribute::~TermAttribute() - { - } +TermAttribute::TermAttribute() { + _termLength = 0; +} - String TermAttribute::toString() - { - return L"term=" + term(); - } +TermAttribute::~TermAttribute() { +} - String TermAttribute::term() - { - initTermBuffer(); - return String(_termBuffer.get(), _termLength); - } +String TermAttribute::toString() { + return L"term=" + term(); +} - void TermAttribute::setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length) - { - growTermBuffer(length); - MiscUtils::arrayCopy(buffer, offset, _termBuffer.get(), 0, length); - _termLength = length; - } +String TermAttribute::term() { + initTermBuffer(); + return String(_termBuffer.get(), _termLength); +} - void TermAttribute::setTermBuffer(const String& buffer) - { - int32_t length = (int32_t)buffer.size(); - growTermBuffer(length); - MiscUtils::arrayCopy(buffer.begin(), 0, _termBuffer.get(), 0, length); - _termLength = length; - } +void TermAttribute::setTermBuffer(const wchar_t* buffer, int32_t offset, int32_t length) { + growTermBuffer(length); + MiscUtils::arrayCopy(buffer, offset, _termBuffer.get(), 0, length); + _termLength = length; +} - CharArray TermAttribute::termBuffer() - { - if (!_termBuffer) - initTermBuffer(); - return _termBuffer; - } +void TermAttribute::setTermBuffer(const String& buffer) { + int32_t length = (int32_t)buffer.size(); + growTermBuffer(length); + MiscUtils::arrayCopy(buffer.begin(), 0, _termBuffer.get(), 0, length); + _termLength = length; +} - wchar_t* TermAttribute::termBufferArray() - { - if (!_termBuffer) - initTermBuffer(); - return _termBuffer.get(); +CharArray TermAttribute::termBuffer() { + if (!_termBuffer) { + initTermBuffer(); } + return _termBuffer; +} - CharArray TermAttribute::resizeTermBuffer(int32_t newSize) - { - if (!_termBuffer) - { - // The buffer is always at least MIN_BUFFER_SIZE - _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(std::max(newSize, MIN_BUFFER_SIZE))); - } - else if (_termBuffer.size() < newSize) - _termBuffer.resize(MiscUtils::getNextSize(newSize)); - return _termBuffer; +wchar_t* TermAttribute::termBufferArray() { + if (!_termBuffer) { + initTermBuffer(); } + return _termBuffer.get(); +} - void TermAttribute::growTermBuffer(int32_t newSize) - { - if (!_termBuffer) - { - // The buffer is always at least MIN_BUFFER_SIZE - _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(std::max(newSize, MIN_BUFFER_SIZE))); - } - else if (_termBuffer.size() < newSize) - _termBuffer.resize(MiscUtils::getNextSize(newSize)); +CharArray TermAttribute::resizeTermBuffer(int32_t newSize) { + if (!_termBuffer) { + // The buffer is always at least MIN_BUFFER_SIZE + _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(std::max(newSize, MIN_BUFFER_SIZE))); + } else if (_termBuffer.size() < newSize) { + _termBuffer.resize(MiscUtils::getNextSize(newSize)); } + return _termBuffer; +} - void TermAttribute::initTermBuffer() - { - if (!_termBuffer) - { - _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(MIN_BUFFER_SIZE)); - _termLength = 0; - } +void TermAttribute::growTermBuffer(int32_t newSize) { + if (!_termBuffer) { + // The buffer is always at least MIN_BUFFER_SIZE + _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(std::max(newSize, MIN_BUFFER_SIZE))); + } else if (_termBuffer.size() < newSize) { + _termBuffer.resize(MiscUtils::getNextSize(newSize)); } +} - int32_t TermAttribute::termLength() - { - return _termLength; +void TermAttribute::initTermBuffer() { + if (!_termBuffer) { + _termBuffer = CharArray::newInstance(MiscUtils::getNextSize(MIN_BUFFER_SIZE)); + _termLength = 0; } +} - void TermAttribute::setTermLength(int32_t length) - { - if (!_termBuffer) - initTermBuffer(); - if (length > _termBuffer.size()) - { - boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + - L" exceeds the size of the termBuffer (" + - StringUtils::toString(_termBuffer.size()) + L")")); - } - _termLength = length; - } +int32_t TermAttribute::termLength() { + return _termLength; +} - int32_t TermAttribute::hashCode() - { +void TermAttribute::setTermLength(int32_t length) { + if (!_termBuffer) { initTermBuffer(); - int32_t code = _termLength; - code = code * 31 + MiscUtils::hashCode(_termBuffer.get(), 0, _termLength); - return code; } - - void TermAttribute::clear() - { - _termLength = 0; + if (length > _termBuffer.size()) { + boost::throw_exception(IllegalArgumentException(L"length " + StringUtils::toString(length) + + L" exceeds the size of the termBuffer (" + + StringUtils::toString(_termBuffer.size()) + L")")); } + _termLength = length; +} - LuceneObjectPtr TermAttribute::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); - TermAttributePtr cloneAttribute(boost::dynamic_pointer_cast(clone)); - cloneAttribute->_termLength = _termLength; - if (_termBuffer) - { - cloneAttribute->_termBuffer = CharArray::newInstance(_termBuffer.size()); - MiscUtils::arrayCopy(_termBuffer.get(), 0, cloneAttribute->_termBuffer.get(), 0, _termBuffer.size()); - } - return cloneAttribute; - } +int32_t TermAttribute::hashCode() { + initTermBuffer(); + int32_t code = _termLength; + code = code * 31 + MiscUtils::hashCode(_termBuffer.get(), 0, _termLength); + return code; +} - bool TermAttribute::equals(const LuceneObjectPtr& other) - { - if (Attribute::equals(other)) - return true; +void TermAttribute::clear() { + _termLength = 0; +} - TermAttributePtr otherTermAttribute(boost::dynamic_pointer_cast(other)); - if (otherTermAttribute) - { - initTermBuffer(); - otherTermAttribute->initTermBuffer(); +LuceneObjectPtr TermAttribute::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = Attribute::clone(other ? other : newLucene()); + TermAttributePtr cloneAttribute(boost::dynamic_pointer_cast(clone)); + cloneAttribute->_termLength = _termLength; + if (_termBuffer) { + cloneAttribute->_termBuffer = CharArray::newInstance(_termBuffer.size()); + MiscUtils::arrayCopy(_termBuffer.get(), 0, cloneAttribute->_termBuffer.get(), 0, _termBuffer.size()); + } + return cloneAttribute; +} + +bool TermAttribute::equals(const LuceneObjectPtr& other) { + if (Attribute::equals(other)) { + return true; + } - if (_termLength != otherTermAttribute->_termLength) - return false; + TermAttributePtr otherTermAttribute(boost::dynamic_pointer_cast(other)); + if (otherTermAttribute) { + initTermBuffer(); + otherTermAttribute->initTermBuffer(); - return (std::memcmp(_termBuffer.get(), otherTermAttribute->_termBuffer.get(), _termLength) == 0); + if (_termLength != otherTermAttribute->_termLength) { + return false; } - return false; + return (std::memcmp(_termBuffer.get(), otherTermAttribute->_termBuffer.get(), _termLength) == 0); } - void TermAttribute::copyTo(const AttributePtr& target) - { - initTermBuffer(); - TermAttributePtr targetTermAttribute(boost::dynamic_pointer_cast(target)); - targetTermAttribute->setTermBuffer(_termBuffer.get(), 0, _termLength); - } + return false; +} + +void TermAttribute::copyTo(const AttributePtr& target) { + initTermBuffer(); + TermAttributePtr targetTermAttribute(boost::dynamic_pointer_cast(target)); + targetTermAttribute->setTermBuffer(_termBuffer.get(), 0, _termLength); +} + } diff --git a/src/core/analysis/tokenattributes/TypeAttribute.cpp b/src/core/analysis/tokenattributes/TypeAttribute.cpp index a2664189..9da99b61 100644 --- a/src/core/analysis/tokenattributes/TypeAttribute.cpp +++ b/src/core/analysis/tokenattributes/TypeAttribute.cpp @@ -8,75 +8,66 @@ #include "TypeAttribute.h" #include "StringUtils.h" -namespace Lucene -{ - TypeAttribute::TypeAttribute() - { - _type = DEFAULT_TYPE(); - } - - TypeAttribute::TypeAttribute(const String& type) - { - _type = type; - } +namespace Lucene { - TypeAttribute::~TypeAttribute() - { - } +TypeAttribute::TypeAttribute() { + _type = DEFAULT_TYPE(); +} - const String& TypeAttribute::DEFAULT_TYPE() - { - static String _DEFAULT_TYPE(L"word"); - return _DEFAULT_TYPE; - } +TypeAttribute::TypeAttribute(const String& type) { + _type = type; +} - String TypeAttribute::toString() - { - return L"type=" + _type; - } +TypeAttribute::~TypeAttribute() { +} - String TypeAttribute::type() - { - return _type; - } +const String& TypeAttribute::DEFAULT_TYPE() { + static String _DEFAULT_TYPE(L"word"); + return _DEFAULT_TYPE; +} - void TypeAttribute::setType(const String& type) - { - _type = type; - } +String TypeAttribute::toString() { + return L"type=" + _type; +} - void TypeAttribute::clear() - { - _type = DEFAULT_TYPE(); - } +String TypeAttribute::type() { + return _type; +} - bool TypeAttribute::equals(const LuceneObjectPtr& other) - { - if (Attribute::equals(other)) - return true; +void TypeAttribute::setType(const String& type) { + _type = type; +} - TypeAttributePtr otherTypeAttribute(boost::dynamic_pointer_cast(other)); - if (otherTypeAttribute) - return (otherTypeAttribute->_type == _type); +void TypeAttribute::clear() { + _type = DEFAULT_TYPE(); +} - return false; +bool TypeAttribute::equals(const LuceneObjectPtr& other) { + if (Attribute::equals(other)) { + return true; } - int32_t TypeAttribute::hashCode() - { - return StringUtils::hashCode(_type); + TypeAttributePtr otherTypeAttribute(boost::dynamic_pointer_cast(other)); + if (otherTypeAttribute) { + return (otherTypeAttribute->_type == _type); } - void TypeAttribute::copyTo(const AttributePtr& target) - { - boost::dynamic_pointer_cast(target)->setType(_type); - } + return false; +} + +int32_t TypeAttribute::hashCode() { + return StringUtils::hashCode(_type); +} + +void TypeAttribute::copyTo(const AttributePtr& target) { + boost::dynamic_pointer_cast(target)->setType(_type); +} + +LuceneObjectPtr TypeAttribute::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + TypeAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); + cloneAttribute->_type = _type; + return cloneAttribute; +} - LuceneObjectPtr TypeAttribute::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - TypeAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); - cloneAttribute->_type = _type; - return cloneAttribute; - } } diff --git a/src/core/document/AbstractField.cpp b/src/core/document/AbstractField.cpp index aee3fe24..a7ca3e46 100644 --- a/src/core/document/AbstractField.cpp +++ b/src/core/document/AbstractField.cpp @@ -10,215 +10,198 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - AbstractField::AbstractField() - { - this->_name = L"body"; - this->storeTermVector = false; - this->storeOffsetWithTermVector = false; - this->storePositionWithTermVector = false; - this->_omitNorms = false; - this->_isStored = false; - this->_isIndexed = true; - this->_isTokenized = true; - this->_isBinary = false; - - this->lazy = false; - this->omitTermFreqAndPositions = false; - this->boost = 1.0; - this->fieldsData = VariantUtils::null(); - - this->binaryLength = 0; - this->binaryOffset = 0; - } +namespace Lucene { + +AbstractField::AbstractField() { + this->_name = L"body"; + this->storeTermVector = false; + this->storeOffsetWithTermVector = false; + this->storePositionWithTermVector = false; + this->_omitNorms = false; + this->_isStored = false; + this->_isIndexed = true; + this->_isTokenized = true; + this->_isBinary = false; + + this->lazy = false; + this->omitTermFreqAndPositions = false; + this->boost = 1.0; + this->fieldsData = VariantUtils::null(); + + this->binaryLength = 0; + this->binaryOffset = 0; +} - AbstractField::AbstractField(const String& name, Field::Store store, Field::Index index, Field::TermVector termVector) - { - this->_name = name; - this->_isStored = Field::isStored(store); - this->_isIndexed = Field::isIndexed(index); - this->_isTokenized = Field::isAnalyzed(index); - this->_omitNorms = Field::omitNorms(index); - this->_isBinary = false; +AbstractField::AbstractField(const String& name, Field::Store store, Field::Index index, Field::TermVector termVector) { + this->_name = name; + this->_isStored = Field::isStored(store); + this->_isIndexed = Field::isIndexed(index); + this->_isTokenized = Field::isAnalyzed(index); + this->_omitNorms = Field::omitNorms(index); + this->_isBinary = false; - this->lazy = false; - this->omitTermFreqAndPositions = false; - this->boost = 1.0; - this->fieldsData = VariantUtils::null(); + this->lazy = false; + this->omitTermFreqAndPositions = false; + this->boost = 1.0; + this->fieldsData = VariantUtils::null(); - this->binaryLength = 0; - this->binaryOffset = 0; + this->binaryLength = 0; + this->binaryOffset = 0; - setStoreTermVector(termVector); - } + setStoreTermVector(termVector); +} - AbstractField::~AbstractField() - { - } +AbstractField::~AbstractField() { +} - void AbstractField::setBoost(double boost) - { - this->boost = boost; - } +void AbstractField::setBoost(double boost) { + this->boost = boost; +} - double AbstractField::getBoost() - { - return boost; - } +double AbstractField::getBoost() { + return boost; +} - String AbstractField::name() - { - return _name; - } +String AbstractField::name() { + return _name; +} - void AbstractField::setStoreTermVector(Field::TermVector termVector) - { - this->storeTermVector = Field::isStored(termVector); - this->storePositionWithTermVector = Field::withPositions(termVector); - this->storeOffsetWithTermVector = Field::withOffsets(termVector); - } +void AbstractField::setStoreTermVector(Field::TermVector termVector) { + this->storeTermVector = Field::isStored(termVector); + this->storePositionWithTermVector = Field::withPositions(termVector); + this->storeOffsetWithTermVector = Field::withOffsets(termVector); +} - bool AbstractField::isStored() - { - return _isStored; - } +bool AbstractField::isStored() { + return _isStored; +} - bool AbstractField::isIndexed() - { - return _isIndexed; - } +bool AbstractField::isIndexed() { + return _isIndexed; +} - bool AbstractField::isTokenized() - { - return _isTokenized; - } +bool AbstractField::isTokenized() { + return _isTokenized; +} - bool AbstractField::isTermVectorStored() - { - return storeTermVector; - } +bool AbstractField::isTermVectorStored() { + return storeTermVector; +} - bool AbstractField::isStoreOffsetWithTermVector() - { - return storeOffsetWithTermVector; - } +bool AbstractField::isStoreOffsetWithTermVector() { + return storeOffsetWithTermVector; +} - bool AbstractField::isStorePositionWithTermVector() - { - return storePositionWithTermVector; - } +bool AbstractField::isStorePositionWithTermVector() { + return storePositionWithTermVector; +} - bool AbstractField::isBinary() - { - return _isBinary; - } +bool AbstractField::isBinary() { + return _isBinary; +} - ByteArray AbstractField::getBinaryValue() - { - return getBinaryValue(ByteArray()); - } +ByteArray AbstractField::getBinaryValue() { + return getBinaryValue(ByteArray()); +} - ByteArray AbstractField::getBinaryValue(ByteArray result) - { - return VariantUtils::get(fieldsData); - } +ByteArray AbstractField::getBinaryValue(ByteArray result) { + return VariantUtils::get(fieldsData); +} - int32_t AbstractField::getBinaryLength() - { - if (_isBinary) - return binaryLength; - ByteArray binary(VariantUtils::get(fieldsData)); - return binary ? binary.size() : 0; +int32_t AbstractField::getBinaryLength() { + if (_isBinary) { + return binaryLength; } + ByteArray binary(VariantUtils::get(fieldsData)); + return binary ? binary.size() : 0; +} - int32_t AbstractField::getBinaryOffset() - { - return binaryOffset; - } +int32_t AbstractField::getBinaryOffset() { + return binaryOffset; +} - bool AbstractField::getOmitNorms() - { - return _omitNorms; - } +bool AbstractField::getOmitNorms() { + return _omitNorms; +} - bool AbstractField::getOmitTermFreqAndPositions() - { - return omitTermFreqAndPositions; - } +bool AbstractField::getOmitTermFreqAndPositions() { + return omitTermFreqAndPositions; +} - void AbstractField::setOmitNorms(bool omitNorms) - { - this->_omitNorms = omitNorms; - } +void AbstractField::setOmitNorms(bool omitNorms) { + this->_omitNorms = omitNorms; +} - void AbstractField::setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) - { - this->omitTermFreqAndPositions = omitTermFreqAndPositions; - } +void AbstractField::setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) { + this->omitTermFreqAndPositions = omitTermFreqAndPositions; +} - bool AbstractField::isLazy() - { - return lazy; - } +bool AbstractField::isLazy() { + return lazy; +} - String AbstractField::toString() - { - StringStream result; - if (_isStored) - result << L"stored"; - if (_isIndexed) - { - if (!result.str().empty()) - result << L","; - result << L"indexed"; +String AbstractField::toString() { + StringStream result; + if (_isStored) { + result << L"stored"; + } + if (_isIndexed) { + if (!result.str().empty()) { + result << L","; } - if (_isTokenized) - { - if (!result.str().empty()) - result << L","; - result << L"tokenized"; + result << L"indexed"; + } + if (_isTokenized) { + if (!result.str().empty()) { + result << L","; } - if (storeTermVector) - { - if (!result.str().empty()) - result << L","; - result << L"termVector"; + result << L"tokenized"; + } + if (storeTermVector) { + if (!result.str().empty()) { + result << L","; } - if (storeOffsetWithTermVector) - { - if (!result.str().empty()) - result << L","; - result << L"termVectorOffsets"; + result << L"termVector"; + } + if (storeOffsetWithTermVector) { + if (!result.str().empty()) { + result << L","; } - if (storePositionWithTermVector) - { - if (!result.str().empty()) - result << L","; - result << L"termVectorPosition"; + result << L"termVectorOffsets"; + } + if (storePositionWithTermVector) { + if (!result.str().empty()) { + result << L","; } - if (_isBinary) - { - if (!result.str().empty()) - result << L","; - result << L"binary"; + result << L"termVectorPosition"; + } + if (_isBinary) { + if (!result.str().empty()) { + result << L","; } - if (_omitNorms) - result << L",omitNorms"; - if (omitTermFreqAndPositions) - result << L",omitTermFreqAndPositions"; - if (lazy) - result << L",lazy"; - result << L"<" << _name << L":"; - - if (VariantUtils::typeOf(fieldsData)) - result << VariantUtils::get(fieldsData); - else if (VariantUtils::typeOf(fieldsData)) - result << L"Reader"; - else if (VariantUtils::typeOf(fieldsData)) - result << L"Binary [size=" << StringUtils::toString(VariantUtils::get(fieldsData).size()) << L"]"; - - result << L">"; - return result.str(); + result << L"binary"; + } + if (_omitNorms) { + result << L",omitNorms"; } + if (omitTermFreqAndPositions) { + result << L",omitTermFreqAndPositions"; + } + if (lazy) { + result << L",lazy"; + } + result << L"<" << _name << L":"; + + if (VariantUtils::typeOf(fieldsData)) { + result << VariantUtils::get(fieldsData); + } else if (VariantUtils::typeOf(fieldsData)) { + result << L"Reader"; + } else if (VariantUtils::typeOf(fieldsData)) { + result << L"Binary [size=" << StringUtils::toString(VariantUtils::get(fieldsData).size()) << L"]"; + } + + result << L">"; + return result.str(); +} + } diff --git a/src/core/document/CompressionTools.cpp b/src/core/document/CompressionTools.cpp index dd1c02c0..227fb618 100644 --- a/src/core/document/CompressionTools.cpp +++ b/src/core/document/CompressionTools.cpp @@ -15,147 +15,130 @@ #include #include -namespace Lucene -{ - const int32_t CompressionTools::COMPRESS_BUFFER = 4096; - - String ZLibToMessage(int32_t error) - { - if (error == boost::iostreams::zlib::okay) - return L"okay"; - else if (error == boost::iostreams::zlib::stream_end) - return L"stream_end"; - else if (error == boost::iostreams::zlib::stream_error) - return L"stream_error"; - else if (error == boost::iostreams::zlib::version_error) - return L"version_error"; - else if (error == boost::iostreams::zlib::data_error) - return L"data_error"; - else if (error == boost::iostreams::zlib::mem_error) - return L"mem_error"; - else if (error == boost::iostreams::zlib::buf_error ) - return L"buf_error"; - else - return L"unknown"; +namespace Lucene { + +const int32_t CompressionTools::COMPRESS_BUFFER = 4096; + +String ZLibToMessage(int32_t error) { + if (error == boost::iostreams::zlib::okay) { + return L"okay"; + } else if (error == boost::iostreams::zlib::stream_end) { + return L"stream_end"; + } else if (error == boost::iostreams::zlib::stream_error) { + return L"stream_error"; + } else if (error == boost::iostreams::zlib::version_error) { + return L"version_error"; + } else if (error == boost::iostreams::zlib::data_error) { + return L"data_error"; + } else if (error == boost::iostreams::zlib::mem_error) { + return L"mem_error"; + } else if (error == boost::iostreams::zlib::buf_error ) { + return L"buf_error"; + } else { + return L"unknown"; } +} - class BufferArraySink : public boost::iostreams::sink - { - public: - BufferArraySink(ByteArray& _buffer, std::streamsize& _position, size_t allocSize) : buffer(_buffer), position(_position) - { - this->allocSize = allocSize; - this->buffer.resize((int32_t)allocSize); - } +class BufferArraySink : public boost::iostreams::sink { +public: + BufferArraySink(ByteArray& _buffer, std::streamsize& _position, size_t allocSize) : buffer(_buffer), position(_position) { + this->allocSize = allocSize; + this->buffer.resize((int32_t)allocSize); + } - public: - ByteArray& buffer; - std::streamsize& position; - - private: - size_t allocSize; - - public: - std::streamsize write(const char* s, std::streamsize n) - { - if (position + n >= (std::streamsize)allocSize) - { - // grow buffer - allocSize <<= 1; - buffer.resize((int32_t)allocSize); - } - MiscUtils::arrayCopy(s, 0, buffer.get(), position, n); - position += n; - return n; - } - }; +public: + ByteArray& buffer; + std::streamsize& position; - CompressionTools::~CompressionTools() - { - } +private: + size_t allocSize; - ByteArray CompressionTools::compress(uint8_t* value, int32_t offset, int32_t length, int32_t compressionLevel) - { - // setup the outStream - boost::iostreams::filtering_ostreambuf outStream; - boost::iostreams::zlib_compressor zcompressor(compressionLevel); - outStream.push(zcompressor); +public: + std::streamsize write(const char* s, std::streamsize n) { + if (position + n >= (std::streamsize)allocSize) { + // grow buffer + allocSize <<= 1; + buffer.resize((int32_t)allocSize); + } + MiscUtils::arrayCopy(s, 0, buffer.get(), position, n); + position += n; + return n; + } +}; - // and the output buffer - ByteArray buffer(ByteArray::newInstance(COMPRESS_BUFFER)); - std::streamsize position = 0; - outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); +CompressionTools::~CompressionTools() { +} - // setup the source stream, and then copy it to the outStream - boost::iostreams::stream< boost::iostreams::array_source > source((char*)(value + offset), length); +ByteArray CompressionTools::compress(uint8_t* value, int32_t offset, int32_t length, int32_t compressionLevel) { + // setup the outStream + boost::iostreams::filtering_ostreambuf outStream; + boost::iostreams::zlib_compressor zcompressor(compressionLevel); + outStream.push(zcompressor); - try - { - boost::iostreams::copy(source, outStream); - } - catch (boost::iostreams::zlib_error& err) - { - boost::throw_exception(CompressionException(L"deflate failure: " + ZLibToMessage(err.error()))); - } + // and the output buffer + ByteArray buffer(ByteArray::newInstance(COMPRESS_BUFFER)); + std::streamsize position = 0; + outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); - buffer.resize((int32_t)position); + // setup the source stream, and then copy it to the outStream + boost::iostreams::stream< boost::iostreams::array_source > source((char*)(value + offset), length); - return buffer; + try { + boost::iostreams::copy(source, outStream); + } catch (boost::iostreams::zlib_error& err) { + boost::throw_exception(CompressionException(L"deflate failure: " + ZLibToMessage(err.error()))); } - ByteArray CompressionTools::compress(uint8_t* value, int32_t offset, int32_t length) - { - return compress(value, offset, length, boost::iostreams::zlib::best_compression); - } + buffer.resize((int32_t)position); - ByteArray CompressionTools::compress(ByteArray value) - { - return compress(value.get(), 0, value.size(), boost::iostreams::zlib::best_compression); - } + return buffer; +} - ByteArray CompressionTools::compressString(const String& value) - { - return compressString(value, boost::iostreams::zlib::best_compression); - } +ByteArray CompressionTools::compress(uint8_t* value, int32_t offset, int32_t length) { + return compress(value, offset, length, boost::iostreams::zlib::best_compression); +} - ByteArray CompressionTools::compressString(const String& value, int32_t compressionLevel) - { - UTF8ResultPtr utf8Result(newLucene()); - StringUtils::toUTF8(value.c_str(), (int32_t)value.length(), utf8Result); - return compress(utf8Result->result.get(), 0, utf8Result->length, compressionLevel); - } +ByteArray CompressionTools::compress(ByteArray value) { + return compress(value.get(), 0, value.size(), boost::iostreams::zlib::best_compression); +} - ByteArray CompressionTools::decompress(ByteArray value) - { - // setup the outStream - boost::iostreams::filtering_ostreambuf outStream; - outStream.push(boost::iostreams::zlib_decompressor()); +ByteArray CompressionTools::compressString(const String& value) { + return compressString(value, boost::iostreams::zlib::best_compression); +} - // and the output buffer - ByteArray buffer(ByteArray::newInstance(COMPRESS_BUFFER)); - std::streamsize position = 0; - outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); +ByteArray CompressionTools::compressString(const String& value, int32_t compressionLevel) { + UTF8ResultPtr utf8Result(newLucene()); + StringUtils::toUTF8(value.c_str(), (int32_t)value.length(), utf8Result); + return compress(utf8Result->result.get(), 0, utf8Result->length, compressionLevel); +} - //setup the source stream, and then copy it to the outStream - boost::iostreams::stream< boost::iostreams::array_source > source((char*)value.get(), value.size()); +ByteArray CompressionTools::decompress(ByteArray value) { + // setup the outStream + boost::iostreams::filtering_ostreambuf outStream; + outStream.push(boost::iostreams::zlib_decompressor()); - try - { - boost::iostreams::copy(source, outStream); - } - catch (boost::iostreams::zlib_error& err) - { - boost::throw_exception(CompressionException(L"deflate failure: " + ZLibToMessage(err.error()))); - } + // and the output buffer + ByteArray buffer(ByteArray::newInstance(COMPRESS_BUFFER)); + std::streamsize position = 0; + outStream.push(BufferArraySink(buffer, position, COMPRESS_BUFFER)); - buffer.resize((int32_t)position); + //setup the source stream, and then copy it to the outStream + boost::iostreams::stream< boost::iostreams::array_source > source((char*)value.get(), value.size()); - return buffer; + try { + boost::iostreams::copy(source, outStream); + } catch (boost::iostreams::zlib_error& err) { + boost::throw_exception(CompressionException(L"deflate failure: " + ZLibToMessage(err.error()))); } - String CompressionTools::decompressString(ByteArray value) - { - ByteArray bytes(decompress(value)); - return StringUtils::toUnicode(bytes.get(), bytes.size()); - } + buffer.resize((int32_t)position); + + return buffer; +} + +String CompressionTools::decompressString(ByteArray value) { + ByteArray bytes(decompress(value)); + return StringUtils::toUnicode(bytes.get(), bytes.size()); +} + } diff --git a/src/core/document/DateField.cpp b/src/core/document/DateField.cpp index 449845f7..12ab1724 100644 --- a/src/core/document/DateField.cpp +++ b/src/core/document/DateField.cpp @@ -9,60 +9,54 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - DateField::~DateField() - { - } +namespace Lucene { + +DateField::~DateField() { +} - int32_t DateField::DATE_LEN() - { - static int32_t _DATE_LEN = 0; - if (_DATE_LEN == 0) - { - // make date strings long enough to last a millennium - _DATE_LEN = (int32_t)StringUtils::toString((int64_t)(1000 * 365 * 24) * (int64_t)(60 * 60 * 1000), StringUtils::CHARACTER_MAX_RADIX).length(); - } - return _DATE_LEN; +int32_t DateField::DATE_LEN() { + static int32_t _DATE_LEN = 0; + if (_DATE_LEN == 0) { + // make date strings long enough to last a millennium + _DATE_LEN = (int32_t)StringUtils::toString((int64_t)(1000 * 365 * 24) * (int64_t)(60 * 60 * 1000), StringUtils::CHARACTER_MAX_RADIX).length(); } + return _DATE_LEN; +} - const String& DateField::MIN_DATE_STRING() - { - static String _MIN_DATE_STRING; - if (_MIN_DATE_STRING.empty()) - _MIN_DATE_STRING = timeToString(0); - return _MIN_DATE_STRING; +const String& DateField::MIN_DATE_STRING() { + static String _MIN_DATE_STRING; + if (_MIN_DATE_STRING.empty()) { + _MIN_DATE_STRING = timeToString(0); } + return _MIN_DATE_STRING; +} - const String& DateField::MAX_DATE_STRING() - { - static String _MAX_DATE_STRING; - if (_MAX_DATE_STRING.empty()) - { - _MAX_DATE_STRING.resize(DATE_LEN()); - std::fill(_MAX_DATE_STRING.begin(), _MAX_DATE_STRING.end(), L'z'); - } - return _MAX_DATE_STRING; +const String& DateField::MAX_DATE_STRING() { + static String _MAX_DATE_STRING; + if (_MAX_DATE_STRING.empty()) { + _MAX_DATE_STRING.resize(DATE_LEN()); + std::fill(_MAX_DATE_STRING.begin(), _MAX_DATE_STRING.end(), L'z'); } + return _MAX_DATE_STRING; +} - String DateField::dateToString(const boost::posix_time::ptime& date) - { - return timeToString(MiscUtils::getTimeMillis(date)); +String DateField::dateToString(const boost::posix_time::ptime& date) { + return timeToString(MiscUtils::getTimeMillis(date)); +} + +String DateField::timeToString(int64_t time) { + if (time < 0) { + boost::throw_exception(RuntimeException(L"time '" + StringUtils::toString(time) + L"' is too early, must be >= 0")); } - String DateField::timeToString(int64_t time) - { - if (time < 0) - boost::throw_exception(RuntimeException(L"time '" + StringUtils::toString(time) + L"' is too early, must be >= 0")); + String timeString(DATE_LEN(), L'0'); + timeString += StringUtils::toString(time, StringUtils::CHARACTER_MAX_RADIX); - String timeString(DATE_LEN(), L'0'); - timeString += StringUtils::toString(time, StringUtils::CHARACTER_MAX_RADIX); + return timeString.substr(timeString.length() - DATE_LEN(), DATE_LEN()); +} - return timeString.substr(timeString.length() - DATE_LEN(), DATE_LEN()); - } +int64_t DateField::stringToTime(const String& s) { + return StringUtils::toLong(s, StringUtils::CHARACTER_MAX_RADIX); +} - int64_t DateField::stringToTime(const String& s) - { - return StringUtils::toLong(s, StringUtils::CHARACTER_MAX_RADIX); - } } diff --git a/src/core/document/DateTools.cpp b/src/core/document/DateTools.cpp index f0234980..87f7927f 100644 --- a/src/core/document/DateTools.cpp +++ b/src/core/document/DateTools.cpp @@ -11,215 +11,200 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - DateTools::DateOrder DateTools::dateOrder = DateTools::DATEORDER_LOCALE; +namespace Lucene { - DateTools::~DateTools() - { - } +DateTools::DateOrder DateTools::dateOrder = DateTools::DATEORDER_LOCALE; - String DateTools::dateToString(const boost::posix_time::ptime& date, Resolution resolution) - { - return timeToString(MiscUtils::getTimeMillis(date), resolution); - } +DateTools::~DateTools() { +} - String DateTools::timeToString(int64_t time, Resolution resolution) - { - std::string timeString(boost::posix_time::to_iso_string(boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1), boost::posix_time::milliseconds(time)))); - switch (resolution) - { - case RESOLUTION_YEAR: - return StringUtils::toUnicode(timeString.substr(0, 4).c_str()); - case RESOLUTION_MONTH: - return StringUtils::toUnicode(timeString.substr(0, 6).c_str()); - case RESOLUTION_DAY: - return StringUtils::toUnicode(timeString.substr(0, 8).c_str()); - case RESOLUTION_HOUR: - return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 2)).c_str()); - case RESOLUTION_MINUTE: - return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 4)).c_str()); - case RESOLUTION_SECOND: - return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 6)).c_str()); - case RESOLUTION_MILLISECOND: - { - std::string fraction(timeString.length() > 16 ? timeString.substr(16, 3) : "000" ); - return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 6) + fraction).c_str()); - } - case RESOLUTION_NULL: - // silence static analyzers - break; - } +String DateTools::dateToString(const boost::posix_time::ptime& date, Resolution resolution) { + return timeToString(MiscUtils::getTimeMillis(date), resolution); +} - boost::throw_exception(IllegalArgumentException(L"unknown resolution '" + StringUtils::toString(resolution) + L"'")); - return L""; +String DateTools::timeToString(int64_t time, Resolution resolution) { + std::string timeString(boost::posix_time::to_iso_string(boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1), boost::posix_time::milliseconds(time)))); + switch (resolution) { + case RESOLUTION_YEAR: + return StringUtils::toUnicode(timeString.substr(0, 4).c_str()); + case RESOLUTION_MONTH: + return StringUtils::toUnicode(timeString.substr(0, 6).c_str()); + case RESOLUTION_DAY: + return StringUtils::toUnicode(timeString.substr(0, 8).c_str()); + case RESOLUTION_HOUR: + return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 2)).c_str()); + case RESOLUTION_MINUTE: + return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 4)).c_str()); + case RESOLUTION_SECOND: + return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 6)).c_str()); + case RESOLUTION_MILLISECOND: { + std::string fraction(timeString.length() > 16 ? timeString.substr(16, 3) : "000" ); + return StringUtils::toUnicode(std::string(timeString.substr(0, 8) + timeString.substr(9, 6) + fraction).c_str()); + } + case RESOLUTION_NULL: + // silence static analyzers + break; } - int64_t DateTools::stringToTime(const String& dateString) - { - return MiscUtils::getTimeMillis(stringToDate(dateString)); + boost::throw_exception(IllegalArgumentException(L"unknown resolution '" + StringUtils::toString(resolution) + L"'")); + return L""; +} + +int64_t DateTools::stringToTime(const String& dateString) { + return MiscUtils::getTimeMillis(stringToDate(dateString)); +} + +boost::posix_time::ptime DateTools::stringToDate(const String& dateString) { + uint16_t year = dateString.length() >= 4 ? (uint16_t)wcstol(dateString.substr(0, 4).c_str(), 0, 10) : 1970; + uint16_t month = dateString.length() >= 6 ? (uint16_t)wcstol(dateString.substr(4, 2).c_str(), 0, 10) : 1; + uint16_t day = dateString.length() >= 8 ? (uint16_t)wcstol(dateString.substr(6, 2).c_str(), 0, 10) : 1; + uint16_t hour = dateString.length() >= 10 ? (uint16_t)wcstol(dateString.substr(8, 2).c_str(), 0, 10) : 0; + uint16_t minute = dateString.length() >= 12 ? (uint16_t)wcstol(dateString.substr(10, 2).c_str(), 0, 10) : 0; + uint16_t second = dateString.length() >= 14 ? (uint16_t)wcstol(dateString.substr(12, 2).c_str(), 0, 10) : 0; + uint16_t millisecond = dateString.length() >= 16 ? (uint16_t)wcstol(dateString.substr(14, 3).c_str(), 0, 10) : 0; + boost::posix_time::ptime date; + try { + date = boost::posix_time::ptime(boost::gregorian::date(year, month, day), + boost::posix_time::hours(hour) + + boost::posix_time::minutes(minute) + + boost::posix_time::seconds(second) + + boost::posix_time::milliseconds(millisecond)); + } catch (...) { + boost::throw_exception(ParseException(L"Input is not valid date string: " + dateString)); } + return date; +} - boost::posix_time::ptime DateTools::stringToDate(const String& dateString) - { - uint16_t year = dateString.length() >= 4 ? (uint16_t)wcstol(dateString.substr(0, 4).c_str(), 0, 10) : 1970; - uint16_t month = dateString.length() >= 6 ? (uint16_t)wcstol(dateString.substr(4, 2).c_str(), 0, 10) : 1; - uint16_t day = dateString.length() >= 8 ? (uint16_t)wcstol(dateString.substr(6, 2).c_str(), 0, 10) : 1; - uint16_t hour = dateString.length() >= 10 ? (uint16_t)wcstol(dateString.substr(8, 2).c_str(), 0, 10) : 0; - uint16_t minute = dateString.length() >= 12 ? (uint16_t)wcstol(dateString.substr(10, 2).c_str(), 0, 10) : 0; - uint16_t second = dateString.length() >= 14 ? (uint16_t)wcstol(dateString.substr(12, 2).c_str(), 0, 10) : 0; - uint16_t millisecond = dateString.length() >= 16 ? (uint16_t)wcstol(dateString.substr(14, 3).c_str(), 0, 10) : 0; - boost::posix_time::ptime date; - try - { - date = boost::posix_time::ptime(boost::gregorian::date(year, month, day), - boost::posix_time::hours(hour) + - boost::posix_time::minutes(minute) + - boost::posix_time::seconds(second) + - boost::posix_time::milliseconds(millisecond)); - } - catch (...) - { - boost::throw_exception(ParseException(L"Input is not valid date string: " + dateString)); - } +boost::posix_time::ptime DateTools::round(const boost::posix_time::ptime& date, Resolution resolution) { + boost::posix_time::ptime roundDate; + + switch (resolution) { + case RESOLUTION_YEAR: + return boost::posix_time::ptime(boost::gregorian::date(date.date().year(), 1, 1)); + case RESOLUTION_MONTH: + return boost::posix_time::ptime(boost::gregorian::date(date.date().year(), date.date().month(), 1)); + case RESOLUTION_DAY: + return boost::posix_time::ptime(date.date()); + case RESOLUTION_HOUR: + return boost::posix_time::ptime(date.date(), + boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours())); + case RESOLUTION_MINUTE: + return boost::posix_time::ptime(date.date(), + boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours()) + + boost::posix_time::minutes(boost::posix_time::time_duration(date.time_of_day()).minutes())); + case RESOLUTION_SECOND: + return boost::posix_time::ptime(date.date(), + boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours()) + + boost::posix_time::minutes(boost::posix_time::time_duration(date.time_of_day()).minutes()) + + boost::posix_time::seconds(boost::posix_time::time_duration(date.time_of_day()).seconds())); + case RESOLUTION_MILLISECOND: return date; + case RESOLUTION_NULL: + // silence static analyzers + break; } - boost::posix_time::ptime DateTools::round(const boost::posix_time::ptime& date, Resolution resolution) - { - boost::posix_time::ptime roundDate; - - switch (resolution) - { - case RESOLUTION_YEAR: - return boost::posix_time::ptime(boost::gregorian::date(date.date().year(), 1, 1)); - case RESOLUTION_MONTH: - return boost::posix_time::ptime(boost::gregorian::date(date.date().year(), date.date().month(), 1)); - case RESOLUTION_DAY: - return boost::posix_time::ptime(date.date()); - case RESOLUTION_HOUR: - return boost::posix_time::ptime(date.date(), - boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours())); - case RESOLUTION_MINUTE: - return boost::posix_time::ptime(date.date(), - boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours()) + - boost::posix_time::minutes(boost::posix_time::time_duration(date.time_of_day()).minutes())); - case RESOLUTION_SECOND: - return boost::posix_time::ptime(date.date(), - boost::posix_time::hours(boost::posix_time::time_duration(date.time_of_day()).hours()) + - boost::posix_time::minutes(boost::posix_time::time_duration(date.time_of_day()).minutes()) + - boost::posix_time::seconds(boost::posix_time::time_duration(date.time_of_day()).seconds())); - case RESOLUTION_MILLISECOND: - return date; - case RESOLUTION_NULL: - // silence static analyzers - break; - } + return boost::posix_time::ptime(); +} - return boost::posix_time::ptime(); - } +int64_t DateTools::round(int64_t time, Resolution resolution) { + return MiscUtils::getTimeMillis(round(boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1), boost::posix_time::milliseconds(time)), resolution)); +} - int64_t DateTools::round(int64_t time, Resolution resolution) - { - return MiscUtils::getTimeMillis(round(boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1), boost::posix_time::milliseconds(time)), resolution)); - } +void DateTools::setDateOrder(DateTools::DateOrder order) { + dateOrder = order; +} - void DateTools::setDateOrder(DateTools::DateOrder order) - { - dateOrder = order; +DateTools::DateOrder DateTools::getDateOrder(std::locale locale) { + if (dateOrder != DATEORDER_LOCALE) { + return dateOrder; } - DateTools::DateOrder DateTools::getDateOrder(std::locale locale) - { - if (dateOrder != DATEORDER_LOCALE) - return dateOrder; - - std::locale localeDate(std::locale(locale, new boost::gregorian::date_facet("%x"))); - SingleStringStream controlStream; - - controlStream.imbue(localeDate); - controlStream << boost::gregorian::date(1974, 10, 20); // Oct 20th 1974 - - SingleString controlDate(controlStream.str()); - SingleString::size_type year = controlDate.find("74"); - SingleString::size_type month = controlDate.find("10"); - if (month == SingleString::npos) - month = controlDate.find("O"); // safety - SingleString::size_type day = controlDate.find("20"); - - if (year < month) - return DATEORDER_YMD; - else if (month < day) - return DATEORDER_MDY; - else - return DATEORDER_DMY; + std::locale localeDate(std::locale(locale, new boost::gregorian::date_facet("%x"))); + SingleStringStream controlStream; + + controlStream.imbue(localeDate); + controlStream << boost::gregorian::date(1974, 10, 20); // Oct 20th 1974 + + SingleString controlDate(controlStream.str()); + SingleString::size_type year = controlDate.find("74"); + SingleString::size_type month = controlDate.find("10"); + if (month == SingleString::npos) { + month = controlDate.find("O"); // safety + } + SingleString::size_type day = controlDate.find("20"); + + if (year < month) { + return DATEORDER_YMD; + } else if (month < day) { + return DATEORDER_MDY; + } else { + return DATEORDER_DMY; } +} - boost::posix_time::ptime DateTools::parseDate(const String& dateString, std::locale locale) - { - Collection dateTokens(StringUtils::split(dateString, L",-. /")); - String delimiter(dateTokens.size() == 1 ? L"" : L"/"); - String paddedDate; - for (Collection::iterator token = dateTokens.begin(); token != dateTokens.end(); ++token) - { - if (token != dateTokens.begin()) - paddedDate += delimiter; - if (token->length() == 1) - paddedDate += L"0" + *token; - else - paddedDate += *token; +boost::posix_time::ptime DateTools::parseDate(const String& dateString, std::locale locale) { + Collection dateTokens(StringUtils::split(dateString, L",-. /")); + String delimiter(dateTokens.size() == 1 ? L"" : L"/"); + String paddedDate; + for (Collection::iterator token = dateTokens.begin(); token != dateTokens.end(); ++token) { + if (token != dateTokens.begin()) { + paddedDate += delimiter; } - - Collection dateFormats(Collection::newInstance()); - - switch (getDateOrder(locale)) - { - case DATEORDER_DMY: - dateFormats.add(L"%d" + delimiter + L"%m" + delimiter + L"%Y"); - dateFormats.add(L"%d" + delimiter + L"%m" + delimiter + L"%y"); - dateFormats.add(L"%d" + delimiter + L"%b" + delimiter + L"%Y"); - dateFormats.add(L"%d" + delimiter + L"%b" + delimiter + L"%y"); - dateFormats.add(L"%d" + delimiter + L"%B" + delimiter + L"%Y"); - dateFormats.add(L"%d" + delimiter + L"%B" + delimiter + L"%y"); - break; - case DATEORDER_MDY: - dateFormats.add(L"%m" + delimiter + L"%d" + delimiter + L"%Y"); - dateFormats.add(L"%m" + delimiter + L"%d" + delimiter + L"%y"); - dateFormats.add(L"%b" + delimiter + L"%d" + delimiter + L"%Y"); - dateFormats.add(L"%b" + delimiter + L"%d" + delimiter + L"%y"); - dateFormats.add(L"%B" + delimiter + L"%d" + delimiter + L"%Y"); - dateFormats.add(L"%B" + delimiter + L"%d" + delimiter + L"%y"); - break; - case DATEORDER_YMD: - dateFormats.add(L"%Y" + delimiter + L"%m" + delimiter + L"%d"); - dateFormats.add(L"%y" + delimiter + L"%m" + delimiter + L"%d"); - dateFormats.add(L"%Y" + delimiter + L"%b" + delimiter + L"%d"); - dateFormats.add(L"%y" + delimiter + L"%b" + delimiter + L"%d"); - dateFormats.add(L"%Y" + delimiter + L"%B" + delimiter + L"%d"); - dateFormats.add(L"%y" + delimiter + L"%B" + delimiter + L"%d"); - break; - case DATEORDER_LOCALE: - // silence static analyzers - break; + if (token->length() == 1) { + paddedDate += L"0" + *token; + } else { + paddedDate += *token; } + } + + Collection dateFormats(Collection::newInstance()); + + switch (getDateOrder(locale)) { + case DATEORDER_DMY: + dateFormats.add(L"%d" + delimiter + L"%m" + delimiter + L"%Y"); + dateFormats.add(L"%d" + delimiter + L"%m" + delimiter + L"%y"); + dateFormats.add(L"%d" + delimiter + L"%b" + delimiter + L"%Y"); + dateFormats.add(L"%d" + delimiter + L"%b" + delimiter + L"%y"); + dateFormats.add(L"%d" + delimiter + L"%B" + delimiter + L"%Y"); + dateFormats.add(L"%d" + delimiter + L"%B" + delimiter + L"%y"); + break; + case DATEORDER_MDY: + dateFormats.add(L"%m" + delimiter + L"%d" + delimiter + L"%Y"); + dateFormats.add(L"%m" + delimiter + L"%d" + delimiter + L"%y"); + dateFormats.add(L"%b" + delimiter + L"%d" + delimiter + L"%Y"); + dateFormats.add(L"%b" + delimiter + L"%d" + delimiter + L"%y"); + dateFormats.add(L"%B" + delimiter + L"%d" + delimiter + L"%Y"); + dateFormats.add(L"%B" + delimiter + L"%d" + delimiter + L"%y"); + break; + case DATEORDER_YMD: + dateFormats.add(L"%Y" + delimiter + L"%m" + delimiter + L"%d"); + dateFormats.add(L"%y" + delimiter + L"%m" + delimiter + L"%d"); + dateFormats.add(L"%Y" + delimiter + L"%b" + delimiter + L"%d"); + dateFormats.add(L"%y" + delimiter + L"%b" + delimiter + L"%d"); + dateFormats.add(L"%Y" + delimiter + L"%B" + delimiter + L"%d"); + dateFormats.add(L"%y" + delimiter + L"%B" + delimiter + L"%d"); + break; + case DATEORDER_LOCALE: + // silence static analyzers + break; + } - boost::date_time::format_date_parser parser(L"", locale); - boost::date_time::special_values_parser svp; + boost::date_time::format_date_parser parser(L"", locale); + boost::date_time::special_values_parser svp; - for (Collection::iterator dateFormat = dateFormats.begin(); dateFormat != dateFormats.end(); ++dateFormat) - { - try - { - boost::gregorian::date date = parser.parse_date(paddedDate.c_str(), dateFormat->c_str(), svp); - if (!date.is_not_a_date()) - return boost::posix_time::ptime(date); - } - catch (...) - { + for (Collection::iterator dateFormat = dateFormats.begin(); dateFormat != dateFormats.end(); ++dateFormat) { + try { + boost::gregorian::date date = parser.parse_date(paddedDate.c_str(), dateFormat->c_str(), svp); + if (!date.is_not_a_date()) { + return boost::posix_time::ptime(date); } + } catch (...) { } - - boost::throw_exception(ParseException(L"Invalid date '" + dateString + L"'")); - return boost::posix_time::ptime(); } + + boost::throw_exception(ParseException(L"Invalid date '" + dateString + L"'")); + return boost::posix_time::ptime(); +} + } diff --git a/src/core/document/Document.cpp b/src/core/document/Document.cpp index 5490e4b8..21e6f203 100644 --- a/src/core/document/Document.cpp +++ b/src/core/document/Document.cpp @@ -9,148 +9,131 @@ #include "Fieldable.h" #include "Field.h" -namespace Lucene -{ - Document::Document() - { - fields = Collection::newInstance(); - boost = 1.0; - } +namespace Lucene { - Document::~Document() - { - } +Document::Document() { + fields = Collection::newInstance(); + boost = 1.0; +} - void Document::setBoost(double boost) - { - this->boost = boost; - } +Document::~Document() { +} - double Document::getBoost() - { - return boost; - } +void Document::setBoost(double boost) { + this->boost = boost; +} - void Document::add(const FieldablePtr& field) - { - fields.add(field); - } +double Document::getBoost() { + return boost; +} - /// Utility functor for comparing fieldable names. - /// see {@link Document}. - struct equalFieldableName - { - equalFieldableName(const String& name) : equalName(name) {} - inline bool operator()(const FieldablePtr& other) const - { - return (equalName == other->name()); - } - const String& equalName; - }; - - void Document::removeField(const String& name) - { - Collection::iterator field = fields.find_if(equalFieldableName(name)); - if (field != fields.end()) - fields.remove(field); - } +void Document::add(const FieldablePtr& field) { + fields.add(field); +} - void Document::removeFields(const String& name) - { - fields.remove_if(equalFieldableName(name)); +/// Utility functor for comparing fieldable names. +/// see {@link Document}. +struct equalFieldableName { + equalFieldableName(const String& name) : equalName(name) {} + inline bool operator()(const FieldablePtr& other) const { + return (equalName == other->name()); } + const String& equalName; +}; - FieldPtr Document::getField(const String& name) - { - return boost::static_pointer_cast(getFieldable(name)); +void Document::removeField(const String& name) { + Collection::iterator field = fields.find_if(equalFieldableName(name)); + if (field != fields.end()) { + fields.remove(field); } +} - FieldablePtr Document::getFieldable(const String& name) - { - Collection::iterator field = fields.find_if(equalFieldableName(name)); - return field == fields.end() ? FieldablePtr() : *field; - } +void Document::removeFields(const String& name) { + fields.remove_if(equalFieldableName(name)); +} - String Document::get(const String& name) - { - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->name() == name && !(*field)->isBinary()) - return (*field)->stringValue(); +FieldPtr Document::getField(const String& name) { + return boost::static_pointer_cast(getFieldable(name)); +} + +FieldablePtr Document::getFieldable(const String& name) { + Collection::iterator field = fields.find_if(equalFieldableName(name)); + return field == fields.end() ? FieldablePtr() : *field; +} + +String Document::get(const String& name) { + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->name() == name && !(*field)->isBinary()) { + return (*field)->stringValue(); } - return L""; } + return L""; +} - Collection Document::getFields() - { - return fields; - } +Collection Document::getFields() { + return fields; +} - Collection Document::getFields(const String& name) - { - Collection result(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->name() == name) - result.add(boost::static_pointer_cast(*field)); +Collection Document::getFields(const String& name) { + Collection result(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->name() == name) { + result.add(boost::static_pointer_cast(*field)); } - return result; } + return result; +} - Collection Document::getFieldables(const String& name) - { - Collection result(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->name() == name) - result.add(*field); +Collection Document::getFieldables(const String& name) { + Collection result(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->name() == name) { + result.add(*field); } - return result; } + return result; +} - Collection Document::getValues(const String& name) - { - Collection result(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->name() == name && !(*field)->isBinary()) - result.add((*field)->stringValue()); +Collection Document::getValues(const String& name) { + Collection result(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->name() == name && !(*field)->isBinary()) { + result.add((*field)->stringValue()); } - return result; } + return result; +} - Collection Document::getBinaryValues(const String& name) - { - Collection result(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->name() == name && (*field)->isBinary()) - result.add((*field)->getBinaryValue()); +Collection Document::getBinaryValues(const String& name) { + Collection result(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->name() == name && (*field)->isBinary()) { + result.add((*field)->getBinaryValue()); } - return result; } + return result; +} - ByteArray Document::getBinaryValue(const String& name) - { - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->name() == name && (*field)->isBinary()) - return (*field)->getBinaryValue(); +ByteArray Document::getBinaryValue(const String& name) { + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->name() == name && (*field)->isBinary()) { + return (*field)->getBinaryValue(); } - return ByteArray(); } + return ByteArray(); +} - String Document::toString() - { - StringStream buffer; - buffer << L"Document<"; - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if (field != fields.begin()) - buffer << L" "; - buffer << (*field)->stringValue(); +String Document::toString() { + StringStream buffer; + buffer << L"Document<"; + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if (field != fields.begin()) { + buffer << L" "; } - buffer << L">"; - return buffer.str(); + buffer << (*field)->stringValue(); } + buffer << L">"; + return buffer.str(); +} + } diff --git a/src/core/document/Field.cpp b/src/core/document/Field.cpp index 72878191..1d4e439c 100644 --- a/src/core/document/Field.cpp +++ b/src/core/document/Field.cpp @@ -10,369 +10,346 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - Field::Field(const String& name, const String& value, Store store, Index index) - { - ConstructField(name, value, store, index, TERM_VECTOR_NO); - } +namespace Lucene { - Field::Field(const String& name, const String& value, Store store, Index index, TermVector termVector) - { - ConstructField(name, value, store, index, termVector); - } +Field::Field(const String& name, const String& value, Store store, Index index) { + ConstructField(name, value, store, index, TERM_VECTOR_NO); +} - Field::Field(const String& name, const ReaderPtr& reader) - { - ConstructField(name, reader, TERM_VECTOR_NO); - } +Field::Field(const String& name, const String& value, Store store, Index index, TermVector termVector) { + ConstructField(name, value, store, index, termVector); +} - Field::Field(const String& name, const ReaderPtr& reader, TermVector termVector) - { - ConstructField(name, reader, termVector); - } +Field::Field(const String& name, const ReaderPtr& reader) { + ConstructField(name, reader, TERM_VECTOR_NO); +} - Field::Field(const String& name, const TokenStreamPtr& tokenStream) - { - ConstructField(name, tokenStream, TERM_VECTOR_NO); - } +Field::Field(const String& name, const ReaderPtr& reader, TermVector termVector) { + ConstructField(name, reader, termVector); +} - Field::Field(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector) - { - ConstructField(name, tokenStream, termVector); - } +Field::Field(const String& name, const TokenStreamPtr& tokenStream) { + ConstructField(name, tokenStream, TERM_VECTOR_NO); +} - Field::Field(const String& name, ByteArray value, Store store) - { - ConstructField(name, value, 0, value.size(), store); - } +Field::Field(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector) { + ConstructField(name, tokenStream, termVector); +} - Field::Field(const String& name, ByteArray value, int32_t offset, int32_t length, Store store) - { - ConstructField(name, value, offset, length, store); - } +Field::Field(const String& name, ByteArray value, Store store) { + ConstructField(name, value, 0, value.size(), store); +} - void Field::ConstructField(const String& name, const String& value, Store store, Index index, TermVector termVector) - { - if (name.empty() && value.empty()) - boost::throw_exception(IllegalArgumentException(L"name and value cannot both be empty")); - if (index == INDEX_NO && store == STORE_NO) - boost::throw_exception(IllegalArgumentException(L"it doesn't make sense to have a field that is neither indexed nor stored")); - if (index == INDEX_NO && termVector != TERM_VECTOR_NO) - boost::throw_exception(IllegalArgumentException(L"cannot store term vector information for a field that is not indexed")); - - this->_name = name; - this->fieldsData = value; - this->_isStored = isStored(store); - this->_isIndexed = isIndexed(index); - this->_isTokenized = isAnalyzed(index); - this->_omitNorms = omitNorms(index); - this->_isBinary = false; - - if (index == INDEX_NO) - this->omitTermFreqAndPositions = false; - - setStoreTermVector(termVector); +Field::Field(const String& name, ByteArray value, int32_t offset, int32_t length, Store store) { + ConstructField(name, value, offset, length, store); +} + +void Field::ConstructField(const String& name, const String& value, Store store, Index index, TermVector termVector) { + if (name.empty() && value.empty()) { + boost::throw_exception(IllegalArgumentException(L"name and value cannot both be empty")); + } + if (index == INDEX_NO && store == STORE_NO) { + boost::throw_exception(IllegalArgumentException(L"it doesn't make sense to have a field that is neither indexed nor stored")); + } + if (index == INDEX_NO && termVector != TERM_VECTOR_NO) { + boost::throw_exception(IllegalArgumentException(L"cannot store term vector information for a field that is not indexed")); } - void Field::ConstructField(const String& name, const ReaderPtr& reader, TermVector termVector) - { - this->_name = name; - this->fieldsData = reader; - this->_isStored = false; - this->_isIndexed = true; - this->_isTokenized = true; - this->_isBinary = false; + this->_name = name; + this->fieldsData = value; + this->_isStored = isStored(store); + this->_isIndexed = isIndexed(index); + this->_isTokenized = isAnalyzed(index); + this->_omitNorms = omitNorms(index); + this->_isBinary = false; - setStoreTermVector(termVector); + if (index == INDEX_NO) { + this->omitTermFreqAndPositions = false; } - void Field::ConstructField(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector) - { - this->_name = name; - this->fieldsData = VariantUtils::null(); - this->tokenStream = tokenStream; - this->_isStored = false; - this->_isIndexed = true; - this->_isTokenized = true; - this->_isBinary = false; - - setStoreTermVector(termVector); - } + setStoreTermVector(termVector); +} - void Field::ConstructField(const String& name, ByteArray value, int32_t offset, int32_t length, Store store) - { - if (store == STORE_NO) - boost::throw_exception(IllegalArgumentException(L"binary values can't be unstored")); +void Field::ConstructField(const String& name, const ReaderPtr& reader, TermVector termVector) { + this->_name = name; + this->fieldsData = reader; + this->_isStored = false; + this->_isIndexed = true; + this->_isTokenized = true; + this->_isBinary = false; - this->_name = name; - this->fieldsData = value; - this->_isStored = isStored(store); - this->_isIndexed = false; - this->_isTokenized = false; - this->omitTermFreqAndPositions = false; - this->_omitNorms = true; - this->_isBinary = true; - this->binaryLength = length; - this->binaryOffset = offset; + setStoreTermVector(termVector); +} - setStoreTermVector(TERM_VECTOR_NO); - } +void Field::ConstructField(const String& name, const TokenStreamPtr& tokenStream, TermVector termVector) { + this->_name = name; + this->fieldsData = VariantUtils::null(); + this->tokenStream = tokenStream; + this->_isStored = false; + this->_isIndexed = true; + this->_isTokenized = true; + this->_isBinary = false; - Field::~Field() - { - } + setStoreTermVector(termVector); +} - String Field::stringValue() - { - return VariantUtils::get(fieldsData); +void Field::ConstructField(const String& name, ByteArray value, int32_t offset, int32_t length, Store store) { + if (store == STORE_NO) { + boost::throw_exception(IllegalArgumentException(L"binary values can't be unstored")); } - ReaderPtr Field::readerValue() - { - return VariantUtils::get(fieldsData); - } + this->_name = name; + this->fieldsData = value; + this->_isStored = isStored(store); + this->_isIndexed = false; + this->_isTokenized = false; + this->omitTermFreqAndPositions = false; + this->_omitNorms = true; + this->_isBinary = true; + this->binaryLength = length; + this->binaryOffset = offset; + + setStoreTermVector(TERM_VECTOR_NO); +} - TokenStreamPtr Field::tokenStreamValue() - { - return tokenStream; - } +Field::~Field() { +} - void Field::setValue(const String& value) - { - if (_isBinary) - boost::throw_exception(IllegalArgumentException(L"cannot set a String value on a binary field")); - fieldsData = value; - } +String Field::stringValue() { + return VariantUtils::get(fieldsData); +} + +ReaderPtr Field::readerValue() { + return VariantUtils::get(fieldsData); +} - void Field::setValue(const ReaderPtr& value) - { - if (_isBinary) - boost::throw_exception(IllegalArgumentException(L"cannot set a Reader value on a binary field")); - if (_isStored) - boost::throw_exception(IllegalArgumentException(L"cannot set a Reader value on a stored field")); - fieldsData = value; +TokenStreamPtr Field::tokenStreamValue() { + return tokenStream; +} + +void Field::setValue(const String& value) { + if (_isBinary) { + boost::throw_exception(IllegalArgumentException(L"cannot set a String value on a binary field")); } + fieldsData = value; +} - void Field::setValue(ByteArray value) - { - if (!_isBinary) - boost::throw_exception(IllegalArgumentException(L"cannot set a byte[] value on a non-binary field")); - fieldsData = value; - binaryLength = value.size(); - binaryOffset = 0; +void Field::setValue(const ReaderPtr& value) { + if (_isBinary) { + boost::throw_exception(IllegalArgumentException(L"cannot set a Reader value on a binary field")); + } + if (_isStored) { + boost::throw_exception(IllegalArgumentException(L"cannot set a Reader value on a stored field")); } + fieldsData = value; +} - void Field::setValue(ByteArray value, int32_t offset, int32_t length) - { - if (!_isBinary) - boost::throw_exception(IllegalArgumentException(L"cannot set a byte[] value on a non-binary field")); - fieldsData = value; - binaryLength = length; - binaryOffset = offset; +void Field::setValue(ByteArray value) { + if (!_isBinary) { + boost::throw_exception(IllegalArgumentException(L"cannot set a byte[] value on a non-binary field")); } + fieldsData = value; + binaryLength = value.size(); + binaryOffset = 0; +} - void Field::setTokenStream(const TokenStreamPtr& tokenStream) - { - this->_isIndexed = true; - this->_isTokenized = true; - this->tokenStream = tokenStream; +void Field::setValue(ByteArray value, int32_t offset, int32_t length) { + if (!_isBinary) { + boost::throw_exception(IllegalArgumentException(L"cannot set a byte[] value on a non-binary field")); } + fieldsData = value; + binaryLength = length; + binaryOffset = offset; +} + +void Field::setTokenStream(const TokenStreamPtr& tokenStream) { + this->_isIndexed = true; + this->_isTokenized = true; + this->tokenStream = tokenStream; +} - bool Field::isStored(Store store) - { - switch (store) - { - case STORE_YES: - return true; +bool Field::isStored(Store store) { + switch (store) { + case STORE_YES: + return true; - case STORE_NO: - return false; + case STORE_NO: + return false; - default: - boost::throw_exception(IllegalArgumentException(L"Invalid field store")); - return false; - } + default: + boost::throw_exception(IllegalArgumentException(L"Invalid field store")); + return false; } +} - bool Field::isIndexed(Index index) - { - switch (index) - { - case INDEX_NO: - return false; +bool Field::isIndexed(Index index) { + switch (index) { + case INDEX_NO: + return false; - case INDEX_ANALYZED: - return true; + case INDEX_ANALYZED: + return true; - case INDEX_NOT_ANALYZED: - return true; + case INDEX_NOT_ANALYZED: + return true; - case INDEX_NOT_ANALYZED_NO_NORMS: - return true; + case INDEX_NOT_ANALYZED_NO_NORMS: + return true; - case INDEX_ANALYZED_NO_NORMS: - return true; + case INDEX_ANALYZED_NO_NORMS: + return true; - default: - boost::throw_exception(IllegalArgumentException(L"Invalid field index")); - return false; - } + default: + boost::throw_exception(IllegalArgumentException(L"Invalid field index")); + return false; } +} - bool Field::isAnalyzed(Index index) - { - switch (index) - { - case INDEX_NO: - return false; +bool Field::isAnalyzed(Index index) { + switch (index) { + case INDEX_NO: + return false; - case INDEX_ANALYZED: - return true; + case INDEX_ANALYZED: + return true; - case INDEX_NOT_ANALYZED: - return false; + case INDEX_NOT_ANALYZED: + return false; - case INDEX_NOT_ANALYZED_NO_NORMS: - return false; + case INDEX_NOT_ANALYZED_NO_NORMS: + return false; - case INDEX_ANALYZED_NO_NORMS: - return true; + case INDEX_ANALYZED_NO_NORMS: + return true; - default: - boost::throw_exception(IllegalArgumentException(L"Invalid field index")); - return false; - } + default: + boost::throw_exception(IllegalArgumentException(L"Invalid field index")); + return false; } +} - bool Field::omitNorms(Index index) - { - switch (index) - { - case INDEX_NO: - return true; - - case INDEX_ANALYZED: - return false; +bool Field::omitNorms(Index index) { + switch (index) { + case INDEX_NO: + return true; - case INDEX_NOT_ANALYZED: - return false; + case INDEX_ANALYZED: + return false; - case INDEX_NOT_ANALYZED_NO_NORMS: - return true; + case INDEX_NOT_ANALYZED: + return false; - case INDEX_ANALYZED_NO_NORMS: - return true; + case INDEX_NOT_ANALYZED_NO_NORMS: + return true; - default: - boost::throw_exception(IllegalArgumentException(L"Invalid field index")); - return false; - } - } + case INDEX_ANALYZED_NO_NORMS: + return true; - Field::Index Field::toIndex(bool indexed, bool analyzed) - { - return toIndex(indexed, analyzed, false); + default: + boost::throw_exception(IllegalArgumentException(L"Invalid field index")); + return false; } +} - Field::Index Field::toIndex(bool indexed, bool analyzed, bool omitNorms) - { - // If it is not indexed nothing else matters - if (!indexed) - return INDEX_NO; +Field::Index Field::toIndex(bool indexed, bool analyzed) { + return toIndex(indexed, analyzed, false); +} - // typical, non-expert - if (!omitNorms) - return analyzed ? INDEX_ANALYZED : INDEX_NOT_ANALYZED; +Field::Index Field::toIndex(bool indexed, bool analyzed, bool omitNorms) { + // If it is not indexed nothing else matters + if (!indexed) { + return INDEX_NO; + } - // Expert: Norms omitted - return analyzed ? INDEX_ANALYZED_NO_NORMS : INDEX_NOT_ANALYZED_NO_NORMS; + // typical, non-expert + if (!omitNorms) { + return analyzed ? INDEX_ANALYZED : INDEX_NOT_ANALYZED; } - bool Field::isStored(TermVector termVector) - { - switch (termVector) - { - case TERM_VECTOR_NO: - return false; + // Expert: Norms omitted + return analyzed ? INDEX_ANALYZED_NO_NORMS : INDEX_NOT_ANALYZED_NO_NORMS; +} + +bool Field::isStored(TermVector termVector) { + switch (termVector) { + case TERM_VECTOR_NO: + return false; - case TERM_VECTOR_YES: - return true; + case TERM_VECTOR_YES: + return true; - case TERM_VECTOR_WITH_POSITIONS: - return true; + case TERM_VECTOR_WITH_POSITIONS: + return true; - case TERM_VECTOR_WITH_OFFSETS: - return true; + case TERM_VECTOR_WITH_OFFSETS: + return true; - case TERM_VECTOR_WITH_POSITIONS_OFFSETS: - return true; + case TERM_VECTOR_WITH_POSITIONS_OFFSETS: + return true; - default: - boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); - return false; - } + default: + boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); + return false; } +} - bool Field::withPositions(TermVector termVector) - { - switch (termVector) - { - case TERM_VECTOR_NO: - return false; +bool Field::withPositions(TermVector termVector) { + switch (termVector) { + case TERM_VECTOR_NO: + return false; - case TERM_VECTOR_YES: - return false; + case TERM_VECTOR_YES: + return false; - case TERM_VECTOR_WITH_POSITIONS: - return true; + case TERM_VECTOR_WITH_POSITIONS: + return true; - case TERM_VECTOR_WITH_OFFSETS: - return false; + case TERM_VECTOR_WITH_OFFSETS: + return false; - case TERM_VECTOR_WITH_POSITIONS_OFFSETS: - return true; + case TERM_VECTOR_WITH_POSITIONS_OFFSETS: + return true; - default: - boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); - return false; - } + default: + boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); + return false; } +} - bool Field::withOffsets(TermVector termVector) - { - switch (termVector) - { - case TERM_VECTOR_NO: - return false; +bool Field::withOffsets(TermVector termVector) { + switch (termVector) { + case TERM_VECTOR_NO: + return false; - case TERM_VECTOR_YES: - return false; + case TERM_VECTOR_YES: + return false; - case TERM_VECTOR_WITH_POSITIONS: - return false; + case TERM_VECTOR_WITH_POSITIONS: + return false; - case TERM_VECTOR_WITH_OFFSETS: - return true; + case TERM_VECTOR_WITH_OFFSETS: + return true; - case TERM_VECTOR_WITH_POSITIONS_OFFSETS: - return true; + case TERM_VECTOR_WITH_POSITIONS_OFFSETS: + return true; - default: - boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); - return false; - } + default: + boost::throw_exception(IllegalArgumentException(L"Invalid field term vector")); + return false; } +} - Field::TermVector Field::toTermVector(bool stored, bool withOffsets, bool withPositions) - { - // If it is not stored, nothing else matters. - if (!stored) - return TERM_VECTOR_NO; - - if (withOffsets) - return withPositions ? TERM_VECTOR_WITH_POSITIONS_OFFSETS : TERM_VECTOR_WITH_OFFSETS; +Field::TermVector Field::toTermVector(bool stored, bool withOffsets, bool withPositions) { + // If it is not stored, nothing else matters. + if (!stored) { + return TERM_VECTOR_NO; + } - return withPositions ? TERM_VECTOR_WITH_POSITIONS : TERM_VECTOR_YES; + if (withOffsets) { + return withPositions ? TERM_VECTOR_WITH_POSITIONS_OFFSETS : TERM_VECTOR_WITH_OFFSETS; } + + return withPositions ? TERM_VECTOR_WITH_POSITIONS : TERM_VECTOR_YES; +} + } diff --git a/src/core/document/FieldSelector.cpp b/src/core/document/FieldSelector.cpp index a8fbf2b2..5a7db90a 100644 --- a/src/core/document/FieldSelector.cpp +++ b/src/core/document/FieldSelector.cpp @@ -7,13 +7,12 @@ #include "LuceneInc.h" #include "FieldSelector.h" -namespace Lucene -{ - FieldSelector::FieldSelector() - { - } +namespace Lucene { + +FieldSelector::FieldSelector() { +} + +FieldSelector::~FieldSelector() { +} - FieldSelector::~FieldSelector() - { - } } diff --git a/src/core/document/Fieldable.cpp b/src/core/document/Fieldable.cpp index 514d1517..1059b04e 100644 --- a/src/core/document/Fieldable.cpp +++ b/src/core/document/Fieldable.cpp @@ -7,137 +7,116 @@ #include "LuceneInc.h" #include "Fieldable.h" -namespace Lucene -{ - void Fieldable::setBoost(double boost) - { - BOOST_ASSERT(false); - // override - } - - double Fieldable::getBoost() - { - BOOST_ASSERT(false); - return 0; // override - } - - String Fieldable::name() - { - BOOST_ASSERT(false); - return L""; // override - } - - String Fieldable::stringValue() - { - BOOST_ASSERT(false); - return L""; // override - } - - ReaderPtr Fieldable::readerValue() - { - BOOST_ASSERT(false); - return ReaderPtr(); // override - } - - TokenStreamPtr Fieldable::tokenStreamValue() - { - BOOST_ASSERT(false); - return TokenStreamPtr(); // override - } - - bool Fieldable::isStored() - { - BOOST_ASSERT(false); - return false; // override - } - - bool Fieldable::isIndexed() - { - BOOST_ASSERT(false); - return false; // override - } - - bool Fieldable::isTokenized() - { - BOOST_ASSERT(false); - return false; // override - } - - bool Fieldable::isTermVectorStored() - { - BOOST_ASSERT(false); - return false; // override - } - - bool Fieldable::isStoreOffsetWithTermVector() - { - BOOST_ASSERT(false); - return false; // override - } - - bool Fieldable::isStorePositionWithTermVector() - { - BOOST_ASSERT(false); - return false; // override - } - - bool Fieldable::isBinary() - { - BOOST_ASSERT(false); - return false; // override - } - - bool Fieldable::getOmitNorms() - { - BOOST_ASSERT(false); - return false; // override - } - - void Fieldable::setOmitNorms(bool omitNorms) - { - BOOST_ASSERT(false); - // override - } - - bool Fieldable::isLazy() - { - BOOST_ASSERT(false); - return false; // override - } - - int32_t Fieldable::getBinaryOffset() - { - BOOST_ASSERT(false); - return 0; // override - } - - int32_t Fieldable::getBinaryLength() - { - BOOST_ASSERT(false); - return 0; // override - } - - ByteArray Fieldable::getBinaryValue() - { - BOOST_ASSERT(false); - return ByteArray(); // override - } - - ByteArray Fieldable::getBinaryValue(ByteArray result) - { - BOOST_ASSERT(false); - return ByteArray(); // override - } - - bool Fieldable::getOmitTermFreqAndPositions() - { - BOOST_ASSERT(false); - return false; // override - } - - void Fieldable::setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) - { - BOOST_ASSERT(false); - // override - } +namespace Lucene { + +void Fieldable::setBoost(double boost) { + BOOST_ASSERT(false); + // override +} + +double Fieldable::getBoost() { + BOOST_ASSERT(false); + return 0; // override +} + +String Fieldable::name() { + BOOST_ASSERT(false); + return L""; // override +} + +String Fieldable::stringValue() { + BOOST_ASSERT(false); + return L""; // override +} + +ReaderPtr Fieldable::readerValue() { + BOOST_ASSERT(false); + return ReaderPtr(); // override +} + +TokenStreamPtr Fieldable::tokenStreamValue() { + BOOST_ASSERT(false); + return TokenStreamPtr(); // override +} + +bool Fieldable::isStored() { + BOOST_ASSERT(false); + return false; // override +} + +bool Fieldable::isIndexed() { + BOOST_ASSERT(false); + return false; // override +} + +bool Fieldable::isTokenized() { + BOOST_ASSERT(false); + return false; // override +} + +bool Fieldable::isTermVectorStored() { + BOOST_ASSERT(false); + return false; // override +} + +bool Fieldable::isStoreOffsetWithTermVector() { + BOOST_ASSERT(false); + return false; // override +} + +bool Fieldable::isStorePositionWithTermVector() { + BOOST_ASSERT(false); + return false; // override +} + +bool Fieldable::isBinary() { + BOOST_ASSERT(false); + return false; // override +} + +bool Fieldable::getOmitNorms() { + BOOST_ASSERT(false); + return false; // override +} + +void Fieldable::setOmitNorms(bool omitNorms) { + BOOST_ASSERT(false); + // override +} + +bool Fieldable::isLazy() { + BOOST_ASSERT(false); + return false; // override +} + +int32_t Fieldable::getBinaryOffset() { + BOOST_ASSERT(false); + return 0; // override +} + +int32_t Fieldable::getBinaryLength() { + BOOST_ASSERT(false); + return 0; // override +} + +ByteArray Fieldable::getBinaryValue() { + BOOST_ASSERT(false); + return ByteArray(); // override +} + +ByteArray Fieldable::getBinaryValue(ByteArray result) { + BOOST_ASSERT(false); + return ByteArray(); // override +} + +bool Fieldable::getOmitTermFreqAndPositions() { + BOOST_ASSERT(false); + return false; // override +} + +void Fieldable::setOmitTermFreqAndPositions(bool omitTermFreqAndPositions) { + BOOST_ASSERT(false); + // override +} + } diff --git a/src/core/document/LoadFirstFieldSelector.cpp b/src/core/document/LoadFirstFieldSelector.cpp index cfe9686a..2f0747c5 100644 --- a/src/core/document/LoadFirstFieldSelector.cpp +++ b/src/core/document/LoadFirstFieldSelector.cpp @@ -7,14 +7,13 @@ #include "LuceneInc.h" #include "LoadFirstFieldSelector.h" -namespace Lucene -{ - LoadFirstFieldSelector::~LoadFirstFieldSelector() - { - } +namespace Lucene { + +LoadFirstFieldSelector::~LoadFirstFieldSelector() { +} + +FieldSelector::FieldSelectorResult LoadFirstFieldSelector::accept(const String& fieldName) { + return FieldSelector::SELECTOR_LOAD_AND_BREAK; +} - FieldSelector::FieldSelectorResult LoadFirstFieldSelector::accept(const String& fieldName) - { - return FieldSelector::SELECTOR_LOAD_AND_BREAK; - } } diff --git a/src/core/document/MapFieldSelector.cpp b/src/core/document/MapFieldSelector.cpp index f5e0739e..7b033e67 100644 --- a/src/core/document/MapFieldSelector.cpp +++ b/src/core/document/MapFieldSelector.cpp @@ -7,27 +7,25 @@ #include "LuceneInc.h" #include "MapFieldSelector.h" -namespace Lucene -{ - MapFieldSelector::MapFieldSelector(MapStringFieldSelectorResult fieldSelections) - { - this->fieldSelections = fieldSelections; - } +namespace Lucene { - MapFieldSelector::MapFieldSelector(Collection fields) - { - fieldSelections = MapStringFieldSelectorResult::newInstance(); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - fieldSelections.put(*field, FieldSelector::SELECTOR_LOAD); - } +MapFieldSelector::MapFieldSelector(MapStringFieldSelectorResult fieldSelections) { + this->fieldSelections = fieldSelections; +} - MapFieldSelector::~MapFieldSelector() - { +MapFieldSelector::MapFieldSelector(Collection fields) { + fieldSelections = MapStringFieldSelectorResult::newInstance(); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + fieldSelections.put(*field, FieldSelector::SELECTOR_LOAD); } +} + +MapFieldSelector::~MapFieldSelector() { +} + +FieldSelector::FieldSelectorResult MapFieldSelector::accept(const String& fieldName) { + MapStringFieldSelectorResult::iterator selection = fieldSelections.find(fieldName); + return selection != fieldSelections.end() ? selection->second : FieldSelector::SELECTOR_NO_LOAD; +} - FieldSelector::FieldSelectorResult MapFieldSelector::accept(const String& fieldName) - { - MapStringFieldSelectorResult::iterator selection = fieldSelections.find(fieldName); - return selection != fieldSelections.end() ? selection->second : FieldSelector::SELECTOR_NO_LOAD; - } } diff --git a/src/core/document/NumberTools.cpp b/src/core/document/NumberTools.cpp index 86a13499..954c09e5 100644 --- a/src/core/document/NumberTools.cpp +++ b/src/core/document/NumberTools.cpp @@ -8,92 +8,87 @@ #include "NumberTools.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t NumberTools::RADIX = 36; - const wchar_t NumberTools::NEGATIVE_PREFIX = L'-'; - const wchar_t NumberTools::POSITIVE_PREFIX = L'0'; - - NumberTools::~NumberTools() - { +namespace Lucene { + +const int32_t NumberTools::RADIX = 36; +const wchar_t NumberTools::NEGATIVE_PREFIX = L'-'; +const wchar_t NumberTools::POSITIVE_PREFIX = L'0'; + +NumberTools::~NumberTools() { +} + +const String& NumberTools::MIN_STRING_VALUE() { + static String _MIN_STRING_VALUE; + if (_MIN_STRING_VALUE.empty()) { + _MIN_STRING_VALUE += NEGATIVE_PREFIX; + _MIN_STRING_VALUE += L"0000000000000"; } + return _MIN_STRING_VALUE; +} - const String& NumberTools::MIN_STRING_VALUE() - { - static String _MIN_STRING_VALUE; - if (_MIN_STRING_VALUE.empty()) - { - _MIN_STRING_VALUE += NEGATIVE_PREFIX; - _MIN_STRING_VALUE += L"0000000000000"; - } - return _MIN_STRING_VALUE; +const String& NumberTools::MAX_STRING_VALUE() { + static String _MAX_STRING_VALUE; + if (_MAX_STRING_VALUE.empty()) { + _MAX_STRING_VALUE += POSITIVE_PREFIX; + _MAX_STRING_VALUE += L"1y2p0ij32e8e7"; } + return _MAX_STRING_VALUE; +} - const String& NumberTools::MAX_STRING_VALUE() - { - static String _MAX_STRING_VALUE; - if (_MAX_STRING_VALUE.empty()) - { - _MAX_STRING_VALUE += POSITIVE_PREFIX; - _MAX_STRING_VALUE += L"1y2p0ij32e8e7"; - } - return _MAX_STRING_VALUE; +int32_t NumberTools::STR_SIZE() { + static int32_t _STR_SIZE = 0; + if (_STR_SIZE == 0) { + _STR_SIZE = (int32_t)MIN_STRING_VALUE().length(); } + return _STR_SIZE; +} - int32_t NumberTools::STR_SIZE() - { - static int32_t _STR_SIZE = 0; - if (_STR_SIZE == 0) - _STR_SIZE = (int32_t)MIN_STRING_VALUE().length(); - return _STR_SIZE; +String NumberTools::longToString(int64_t l) { + if (l == std::numeric_limits::min()) { + // special case, because long is not symmetric around zero + return MIN_STRING_VALUE(); } - String NumberTools::longToString(int64_t l) - { - if (l == std::numeric_limits::min()) - { - // special case, because long is not symmetric around zero - return MIN_STRING_VALUE(); - } + String buf; + buf.reserve(STR_SIZE()); - String buf; - buf.reserve(STR_SIZE()); + if (l < 0) { + buf += NEGATIVE_PREFIX; + l = std::numeric_limits::max() + l + 1; + } + buf += POSITIVE_PREFIX; - if (l < 0) - { - buf += NEGATIVE_PREFIX; - l = std::numeric_limits::max() + l + 1; - } - buf += POSITIVE_PREFIX; + String num(StringUtils::toString(l, RADIX)); - String num(StringUtils::toString(l, RADIX)); + int32_t padLen = (int32_t)(STR_SIZE() - num.length() - buf.length()); + while (padLen-- > 0) { + buf += L'0'; + } - int32_t padLen = (int32_t)(STR_SIZE() - num.length() - buf.length()); - while (padLen-- > 0) - buf += L'0'; + return buf + num; +} - return buf + num; +int64_t NumberTools::stringToLong(const String& str) { + if ((int32_t)str.length() != STR_SIZE()) { + boost::throw_exception(NumberFormatException(L"string is the wrong size")); } - int64_t NumberTools::stringToLong(const String& str) - { - if ((int32_t)str.length() != STR_SIZE()) - boost::throw_exception(NumberFormatException(L"string is the wrong size")); + if (str == MIN_STRING_VALUE()) { + return std::numeric_limits::min(); + } - if (str == MIN_STRING_VALUE()) - return std::numeric_limits::min(); + wchar_t prefix = str[0]; + int64_t l = StringUtils::toLong(str.substr(1), RADIX); - wchar_t prefix = str[0]; - int64_t l = StringUtils::toLong(str.substr(1), RADIX); + if (prefix == POSITIVE_PREFIX) { + // nop + } else if (prefix == NEGATIVE_PREFIX) { + l = l - std::numeric_limits::max() - 1; + } else { + boost::throw_exception(NumberFormatException(L"string does not begin with the correct prefix")); + } - if (prefix == POSITIVE_PREFIX) - { // nop - } - else if (prefix == NEGATIVE_PREFIX) - l = l - std::numeric_limits::max() - 1; - else - boost::throw_exception(NumberFormatException(L"string does not begin with the correct prefix")); + return l; +} - return l; - } } diff --git a/src/core/document/NumericField.cpp b/src/core/document/NumericField.cpp index b1a839ca..da356a55 100644 --- a/src/core/document/NumericField.cpp +++ b/src/core/document/NumericField.cpp @@ -11,85 +11,73 @@ #include "NumericTokenStream.h" #include "StringUtils.h" -namespace Lucene -{ - NumericField::NumericField(const String& name) - : AbstractField(name, Field::STORE_NO, Field::INDEX_ANALYZED_NO_NORMS, Field::TERM_VECTOR_NO) - { - setOmitTermFreqAndPositions(true); - tokenStream = newLucene(NumericUtils::PRECISION_STEP_DEFAULT); - } - - NumericField::NumericField(const String& name, Field::Store store, bool index) - : AbstractField(name, store, index ? Field::INDEX_ANALYZED_NO_NORMS : Field::INDEX_NO, Field::TERM_VECTOR_NO) - { - setOmitTermFreqAndPositions(true); - tokenStream = newLucene(NumericUtils::PRECISION_STEP_DEFAULT); - } - - NumericField::NumericField(const String& name, int32_t precisionStep) - : AbstractField(name, Field::STORE_NO, Field::INDEX_ANALYZED_NO_NORMS, Field::TERM_VECTOR_NO) - { - setOmitTermFreqAndPositions(true); - tokenStream = newLucene(precisionStep); - } - - NumericField::NumericField(const String& name, int32_t precisionStep, Field::Store store, bool index) - : AbstractField(name, store, index ? Field::INDEX_ANALYZED_NO_NORMS : Field::INDEX_NO, Field::TERM_VECTOR_NO) - { - setOmitTermFreqAndPositions(true); - tokenStream = newLucene(precisionStep); - } - - NumericField::~NumericField() - { - } - - TokenStreamPtr NumericField::tokenStreamValue() - { - return isIndexed() ? boost::static_pointer_cast(tokenStream) : TokenStreamPtr(); - } - - ByteArray NumericField::getBinaryValue(ByteArray result) - { - return ByteArray(); - } - - ReaderPtr NumericField::readerValue() - { - return ReaderPtr(); - } - - String NumericField::stringValue() - { - StringStream value; - value << fieldsData; - return value.str(); - } - - int64_t NumericField::getNumericValue() - { - return StringUtils::toLong(stringValue()); - } - - NumericFieldPtr NumericField::setLongValue(int64_t value) - { - tokenStream->setLongValue(value); - fieldsData = value; - return shared_from_this(); - } - - NumericFieldPtr NumericField::setIntValue(int32_t value) - { - tokenStream->setIntValue(value); - fieldsData = value; - return shared_from_this(); - } - - NumericFieldPtr NumericField::setDoubleValue(double value) - { - tokenStream->setDoubleValue(value); - fieldsData = value; - return shared_from_this(); - } +namespace Lucene { + +NumericField::NumericField(const String& name) + : AbstractField(name, Field::STORE_NO, Field::INDEX_ANALYZED_NO_NORMS, Field::TERM_VECTOR_NO) { + setOmitTermFreqAndPositions(true); + tokenStream = newLucene(NumericUtils::PRECISION_STEP_DEFAULT); +} + +NumericField::NumericField(const String& name, Field::Store store, bool index) + : AbstractField(name, store, index ? Field::INDEX_ANALYZED_NO_NORMS : Field::INDEX_NO, Field::TERM_VECTOR_NO) { + setOmitTermFreqAndPositions(true); + tokenStream = newLucene(NumericUtils::PRECISION_STEP_DEFAULT); +} + +NumericField::NumericField(const String& name, int32_t precisionStep) + : AbstractField(name, Field::STORE_NO, Field::INDEX_ANALYZED_NO_NORMS, Field::TERM_VECTOR_NO) { + setOmitTermFreqAndPositions(true); + tokenStream = newLucene(precisionStep); +} + +NumericField::NumericField(const String& name, int32_t precisionStep, Field::Store store, bool index) + : AbstractField(name, store, index ? Field::INDEX_ANALYZED_NO_NORMS : Field::INDEX_NO, Field::TERM_VECTOR_NO) { + setOmitTermFreqAndPositions(true); + tokenStream = newLucene(precisionStep); +} + +NumericField::~NumericField() { +} + +TokenStreamPtr NumericField::tokenStreamValue() { + return isIndexed() ? boost::static_pointer_cast(tokenStream) : TokenStreamPtr(); +} + +ByteArray NumericField::getBinaryValue(ByteArray result) { + return ByteArray(); +} + +ReaderPtr NumericField::readerValue() { + return ReaderPtr(); +} + +String NumericField::stringValue() { + StringStream value; + value << fieldsData; + return value.str(); +} + +int64_t NumericField::getNumericValue() { + return StringUtils::toLong(stringValue()); +} + +NumericFieldPtr NumericField::setLongValue(int64_t value) { + tokenStream->setLongValue(value); + fieldsData = value; + return shared_from_this(); +} + +NumericFieldPtr NumericField::setIntValue(int32_t value) { + tokenStream->setIntValue(value); + fieldsData = value; + return shared_from_this(); +} + +NumericFieldPtr NumericField::setDoubleValue(double value) { + tokenStream->setDoubleValue(value); + fieldsData = value; + return shared_from_this(); +} + } diff --git a/src/core/document/SetBasedFieldSelector.cpp b/src/core/document/SetBasedFieldSelector.cpp index 067d2994..f42be80c 100644 --- a/src/core/document/SetBasedFieldSelector.cpp +++ b/src/core/document/SetBasedFieldSelector.cpp @@ -7,25 +7,25 @@ #include "LuceneInc.h" #include "SetBasedFieldSelector.h" -namespace Lucene -{ - SetBasedFieldSelector::SetBasedFieldSelector(HashSet fieldsToLoad, HashSet lazyFieldsToLoad) - { - this->fieldsToLoad = fieldsToLoad; - this->lazyFieldsToLoad = lazyFieldsToLoad; - } +namespace Lucene { - SetBasedFieldSelector::~SetBasedFieldSelector() - { - } +SetBasedFieldSelector::SetBasedFieldSelector(HashSet fieldsToLoad, HashSet lazyFieldsToLoad) { + this->fieldsToLoad = fieldsToLoad; + this->lazyFieldsToLoad = lazyFieldsToLoad; +} + +SetBasedFieldSelector::~SetBasedFieldSelector() { +} - FieldSelector::FieldSelectorResult SetBasedFieldSelector::accept(const String& fieldName) - { - FieldSelector::FieldSelectorResult result = FieldSelector::SELECTOR_NO_LOAD; - if (fieldsToLoad.contains(fieldName)) - result = FieldSelector::SELECTOR_LOAD; - if (lazyFieldsToLoad.contains(fieldName)) - result = FieldSelector::SELECTOR_LAZY_LOAD; - return result; +FieldSelector::FieldSelectorResult SetBasedFieldSelector::accept(const String& fieldName) { + FieldSelector::FieldSelectorResult result = FieldSelector::SELECTOR_NO_LOAD; + if (fieldsToLoad.contains(fieldName)) { + result = FieldSelector::SELECTOR_LOAD; + } + if (lazyFieldsToLoad.contains(fieldName)) { + result = FieldSelector::SELECTOR_LAZY_LOAD; } + return result; +} + } diff --git a/src/core/include/_BooleanQuery.h b/src/core/include/_BooleanQuery.h index ef58d365..f23a79ef 100644 --- a/src/core/include/_BooleanQuery.h +++ b/src/core/include/_BooleanQuery.h @@ -9,46 +9,45 @@ #include "SimilarityDelegator.h" -namespace Lucene -{ - /// The Weight for BooleanQuery, used to normalize, score and explain these queries. - class BooleanWeight : public Weight - { - public: - BooleanWeight(const BooleanQueryPtr& query, const SearcherPtr& searcher); - virtual ~BooleanWeight(); - - LUCENE_CLASS(BooleanWeight); - - protected: - BooleanQueryPtr query; - - /// The Similarity implementation. - SimilarityPtr similarity; - Collection weights; - - public: - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual bool scoresDocsOutOfOrder(); - }; - - /// Disabled coord Similarity - class SimilarityDisableCoord : public SimilarityDelegator - { - public: - SimilarityDisableCoord(const SimilarityPtr& delegee); - virtual ~SimilarityDisableCoord(); - - LUCENE_CLASS(SimilarityDisableCoord); - - public: - virtual double coord(int32_t overlap, int32_t maxOverlap); - }; +namespace Lucene { + +/// The Weight for BooleanQuery, used to normalize, score and explain these queries. +class BooleanWeight : public Weight { +public: + BooleanWeight(const BooleanQueryPtr& query, const SearcherPtr& searcher); + virtual ~BooleanWeight(); + + LUCENE_CLASS(BooleanWeight); + +protected: + BooleanQueryPtr query; + + /// The Similarity implementation. + SimilarityPtr similarity; + Collection weights; + +public: + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual bool scoresDocsOutOfOrder(); +}; + +/// Disabled coord Similarity +class SimilarityDisableCoord : public SimilarityDelegator { +public: + SimilarityDisableCoord(const SimilarityPtr& delegee); + virtual ~SimilarityDisableCoord(); + + LUCENE_CLASS(SimilarityDisableCoord); + +public: + virtual double coord(int32_t overlap, int32_t maxOverlap); +}; + } #endif diff --git a/src/core/include/_ByteFieldSource.h b/src/core/include/_ByteFieldSource.h index a4cd3e97..0bff03fe 100644 --- a/src/core/include/_ByteFieldSource.h +++ b/src/core/include/_ByteFieldSource.h @@ -9,26 +9,26 @@ #include "DocValues.h" -namespace Lucene -{ - class ByteDocValues : public DocValues - { - public: - ByteDocValues(const ByteFieldSourcePtr& source, Collection arr); - virtual ~ByteDocValues(); - - LUCENE_CLASS(ByteDocValues); - - protected: - ByteFieldSourceWeakPtr _source; - Collection arr; - - public: - virtual double doubleVal(int32_t doc); - virtual int32_t intVal(int32_t doc); - virtual String toString(int32_t doc); - virtual CollectionValue getInnerArray(); - }; +namespace Lucene { + +class ByteDocValues : public DocValues { +public: + ByteDocValues(const ByteFieldSourcePtr& source, Collection arr); + virtual ~ByteDocValues(); + + LUCENE_CLASS(ByteDocValues); + +protected: + ByteFieldSourceWeakPtr _source; + Collection arr; + +public: + virtual double doubleVal(int32_t doc); + virtual int32_t intVal(int32_t doc); + virtual String toString(int32_t doc); + virtual CollectionValue getInnerArray(); +}; + } #endif diff --git a/src/core/include/_CachingSpanFilter.h b/src/core/include/_CachingSpanFilter.h index b7f956cf..271db3f3 100644 --- a/src/core/include/_CachingSpanFilter.h +++ b/src/core/include/_CachingSpanFilter.h @@ -9,19 +9,19 @@ #include "_CachingWrapperFilter.h" -namespace Lucene -{ - class FilterCacheSpanFilterResult : public FilterCache - { - public: - FilterCacheSpanFilterResult(CachingWrapperFilter::DeletesMode deletesMode); - virtual ~FilterCacheSpanFilterResult(); - - LUCENE_CLASS(FilterCacheSpanFilterResult); - - protected: - virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value); - }; +namespace Lucene { + +class FilterCacheSpanFilterResult : public FilterCache { +public: + FilterCacheSpanFilterResult(CachingWrapperFilter::DeletesMode deletesMode); + virtual ~FilterCacheSpanFilterResult(); + + LUCENE_CLASS(FilterCacheSpanFilterResult); + +protected: + virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value); +}; + } #endif diff --git a/src/core/include/_CachingWrapperFilter.h b/src/core/include/_CachingWrapperFilter.h index 903b9487..7cf76e65 100644 --- a/src/core/include/_CachingWrapperFilter.h +++ b/src/core/include/_CachingWrapperFilter.h @@ -9,54 +9,52 @@ #include "FilteredDocIdSet.h" -namespace Lucene -{ - class FilterCache : public LuceneObject - { - public: - FilterCache(CachingWrapperFilter::DeletesMode deletesMode); - virtual ~FilterCache(); - - LUCENE_CLASS(FilterCache); - - public: - WeakMapObjectObject cache; - CachingWrapperFilter::DeletesMode deletesMode; - - public: - virtual LuceneObjectPtr get(const IndexReaderPtr& reader, const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey); - virtual void put(const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey, const LuceneObjectPtr& value); - - protected: - virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) = 0; - }; - - class FilterCacheDocIdSet : public FilterCache - { - public: - FilterCacheDocIdSet(CachingWrapperFilter::DeletesMode deletesMode); - virtual ~FilterCacheDocIdSet(); - - LUCENE_CLASS(FilterCacheDocIdSet); - - protected: - virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value); - }; - - class FilteredCacheDocIdSet : public FilteredDocIdSet - { - public: - FilteredCacheDocIdSet(const IndexReaderPtr& reader, const DocIdSetPtr& innerSet); - virtual ~FilteredCacheDocIdSet(); - - LUCENE_CLASS(FilteredCacheDocIdSet); - - protected: - IndexReaderPtr reader; - - protected: - virtual bool match(int32_t docid); - }; +namespace Lucene { + +class FilterCache : public LuceneObject { +public: + FilterCache(CachingWrapperFilter::DeletesMode deletesMode); + virtual ~FilterCache(); + + LUCENE_CLASS(FilterCache); + +public: + WeakMapObjectObject cache; + CachingWrapperFilter::DeletesMode deletesMode; + +public: + virtual LuceneObjectPtr get(const IndexReaderPtr& reader, const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey); + virtual void put(const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey, const LuceneObjectPtr& value); + +protected: + virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) = 0; +}; + +class FilterCacheDocIdSet : public FilterCache { +public: + FilterCacheDocIdSet(CachingWrapperFilter::DeletesMode deletesMode); + virtual ~FilterCacheDocIdSet(); + + LUCENE_CLASS(FilterCacheDocIdSet); + +protected: + virtual LuceneObjectPtr mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value); +}; + +class FilteredCacheDocIdSet : public FilteredDocIdSet { +public: + FilteredCacheDocIdSet(const IndexReaderPtr& reader, const DocIdSetPtr& innerSet); + virtual ~FilteredCacheDocIdSet(); + + LUCENE_CLASS(FilteredCacheDocIdSet); + +protected: + IndexReaderPtr reader; + +protected: + virtual bool match(int32_t docid); +}; + } #endif diff --git a/src/core/include/_CheckIndex.h b/src/core/include/_CheckIndex.h index fd8c870f..ab716487 100644 --- a/src/core/include/_CheckIndex.h +++ b/src/core/include/_CheckIndex.h @@ -9,23 +9,23 @@ #include "SegmentTermDocs.h" -namespace Lucene -{ - class MySegmentTermDocs : public SegmentTermDocs - { - public: - MySegmentTermDocs(const SegmentReaderPtr& p); - virtual ~MySegmentTermDocs(); - - LUCENE_CLASS(MySegmentTermDocs); - - public: - int32_t delCount; - - public: - virtual void seek(const TermPtr& term); - virtual void skippingDoc(); - }; +namespace Lucene { + +class MySegmentTermDocs : public SegmentTermDocs { +public: + MySegmentTermDocs(const SegmentReaderPtr& p); + virtual ~MySegmentTermDocs(); + + LUCENE_CLASS(MySegmentTermDocs); + +public: + int32_t delCount; + +public: + virtual void seek(const TermPtr& term); + virtual void skippingDoc(); +}; + } #endif diff --git a/src/core/include/_ConcurrentMergeScheduler.h b/src/core/include/_ConcurrentMergeScheduler.h index cde81c8d..9aeb46d9 100644 --- a/src/core/include/_ConcurrentMergeScheduler.h +++ b/src/core/include/_ConcurrentMergeScheduler.h @@ -9,28 +9,28 @@ #include "LuceneThread.h" -namespace Lucene -{ - class MergeThread : public LuceneThread - { - public: - MergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge); - virtual ~MergeThread(); - - LUCENE_CLASS(MergeThread); - - protected: - ConcurrentMergeSchedulerWeakPtr _merger; - IndexWriterWeakPtr _writer; - OneMergePtr startMerge; - OneMergePtr runningMerge; - - public: - void setRunningMerge(const OneMergePtr& merge); - OneMergePtr getRunningMerge(); - void setThreadPriority(int32_t pri); - virtual void run(); - }; +namespace Lucene { + +class MergeThread : public LuceneThread { +public: + MergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge); + virtual ~MergeThread(); + + LUCENE_CLASS(MergeThread); + +protected: + ConcurrentMergeSchedulerWeakPtr _merger; + IndexWriterWeakPtr _writer; + OneMergePtr startMerge; + OneMergePtr runningMerge; + +public: + void setRunningMerge(const OneMergePtr& merge); + OneMergePtr getRunningMerge(); + void setThreadPriority(int32_t pri); + virtual void run(); +}; + } #endif diff --git a/src/core/include/_ConstantScoreQuery.h b/src/core/include/_ConstantScoreQuery.h index 0e7acc90..5cba90b3 100644 --- a/src/core/include/_ConstantScoreQuery.h +++ b/src/core/include/_ConstantScoreQuery.h @@ -9,50 +9,49 @@ #include "Weight.h" -namespace Lucene -{ - class ConstantWeight : public Weight - { - public: - ConstantWeight(const ConstantScoreQueryPtr& constantScorer, const SearcherPtr& searcher); - virtual ~ConstantWeight(); - - LUCENE_CLASS(ConstantWeight); - - protected: - ConstantScoreQueryPtr constantScorer; - SimilarityPtr similarity; - double queryNorm; - double queryWeight; - - public: - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - }; - - class ConstantScorer : public Scorer - { - public: - ConstantScorer(const ConstantScoreQueryPtr& constantScorer, const SimilarityPtr& similarity, const IndexReaderPtr& reader, const WeightPtr& w); - virtual ~ConstantScorer(); - - LUCENE_CLASS(ConstantScorer); - - public: - DocIdSetIteratorPtr docIdSetIterator; - double theScore; - int32_t doc; - - public: - virtual int32_t nextDoc(); - virtual int32_t docID(); - virtual double score(); - virtual int32_t advance(int32_t target); - }; +namespace Lucene { + +class ConstantWeight : public Weight { +public: + ConstantWeight(const ConstantScoreQueryPtr& constantScorer, const SearcherPtr& searcher); + virtual ~ConstantWeight(); + + LUCENE_CLASS(ConstantWeight); + +protected: + ConstantScoreQueryPtr constantScorer; + SimilarityPtr similarity; + double queryNorm; + double queryWeight; + +public: + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); +}; + +class ConstantScorer : public Scorer { +public: + ConstantScorer(const ConstantScoreQueryPtr& constantScorer, const SimilarityPtr& similarity, const IndexReaderPtr& reader, const WeightPtr& w); + virtual ~ConstantScorer(); + + LUCENE_CLASS(ConstantScorer); + +public: + DocIdSetIteratorPtr docIdSetIterator; + double theScore; + int32_t doc; + +public: + virtual int32_t nextDoc(); + virtual int32_t docID(); + virtual double score(); + virtual int32_t advance(int32_t target); +}; + } #endif diff --git a/src/core/include/_CustomScoreQuery.h b/src/core/include/_CustomScoreQuery.h index 00d5fb6b..e9524236 100644 --- a/src/core/include/_CustomScoreQuery.h +++ b/src/core/include/_CustomScoreQuery.h @@ -11,78 +11,76 @@ #include "Scorer.h" #include "CustomScoreProvider.h" -namespace Lucene -{ - // when deprecated methods are removed, do not extend class here, just return new default CustomScoreProvider - class DefaultCustomScoreProvider : public CustomScoreProvider - { - public: - DefaultCustomScoreProvider(const CustomScoreQueryPtr& customQuery, const IndexReaderPtr& reader); - virtual ~DefaultCustomScoreProvider(); - - LUCENE_CLASS(DefaultCustomScoreProvider); - - protected: - CustomScoreQueryWeakPtr _customQuery; - - public: - virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); - virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); - }; - - class CustomWeight : public Weight - { - public: - CustomWeight(const CustomScoreQueryPtr& query, const SearcherPtr& searcher); - virtual ~CustomWeight(); - - LUCENE_CLASS(CustomWeight); - - public: - CustomScoreQueryPtr query; - SimilarityPtr similarity; - WeightPtr subQueryWeight; - Collection valSrcWeights; - bool qStrict; - - public: - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - virtual bool scoresDocsOutOfOrder(); - - protected: - ExplanationPtr doExplain(const IndexReaderPtr& reader, int32_t doc); - }; - - /// A scorer that applies a (callback) function on scores of the subQuery. - class CustomScorer : public Scorer - { - public: - CustomScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const CustomWeightPtr& weight, const ScorerPtr& subQueryScorer, Collection valSrcScorers); - virtual ~CustomScorer(); - - LUCENE_CLASS(CustomScorer); - - protected: - double qWeight; - ScorerPtr subQueryScorer; - Collection valSrcScorers; - IndexReaderPtr reader; - CustomScoreProviderPtr provider; - Collection vScores; // reused in score() to avoid allocating this array for each doc - - public: - virtual int32_t nextDoc(); - virtual int32_t docID(); - virtual double score(); - virtual int32_t advance(int32_t target); - }; +namespace Lucene { + +// when deprecated methods are removed, do not extend class here, just return new default CustomScoreProvider +class DefaultCustomScoreProvider : public CustomScoreProvider { +public: + DefaultCustomScoreProvider(const CustomScoreQueryPtr& customQuery, const IndexReaderPtr& reader); + virtual ~DefaultCustomScoreProvider(); + + LUCENE_CLASS(DefaultCustomScoreProvider); + +protected: + CustomScoreQueryWeakPtr _customQuery; + +public: + virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores); + virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls); + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl); +}; + +class CustomWeight : public Weight { +public: + CustomWeight(const CustomScoreQueryPtr& query, const SearcherPtr& searcher); + virtual ~CustomWeight(); + + LUCENE_CLASS(CustomWeight); + +public: + CustomScoreQueryPtr query; + SimilarityPtr similarity; + WeightPtr subQueryWeight; + Collection valSrcWeights; + bool qStrict; + +public: + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); + virtual bool scoresDocsOutOfOrder(); + +protected: + ExplanationPtr doExplain(const IndexReaderPtr& reader, int32_t doc); +}; + +/// A scorer that applies a (callback) function on scores of the subQuery. +class CustomScorer : public Scorer { +public: + CustomScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const CustomWeightPtr& weight, const ScorerPtr& subQueryScorer, Collection valSrcScorers); + virtual ~CustomScorer(); + + LUCENE_CLASS(CustomScorer); + +protected: + double qWeight; + ScorerPtr subQueryScorer; + Collection valSrcScorers; + IndexReaderPtr reader; + CustomScoreProviderPtr provider; + Collection vScores; // reused in score() to avoid allocating this array for each doc + +public: + virtual int32_t nextDoc(); + virtual int32_t docID(); + virtual double score(); + virtual int32_t advance(int32_t target); +}; + } #endif diff --git a/src/core/include/_DirectoryReader.h b/src/core/include/_DirectoryReader.h index b686d32d..d0e7e26a 100644 --- a/src/core/include/_DirectoryReader.h +++ b/src/core/include/_DirectoryReader.h @@ -9,40 +9,39 @@ #include "_SegmentInfos.h" -namespace Lucene -{ - class FindSegmentsOpen : public FindSegmentsFileT - { - public: - FindSegmentsOpen(bool readOnly, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor, const SegmentInfosPtr& infos, const DirectoryPtr& directory); - virtual ~FindSegmentsOpen(); - - LUCENE_CLASS(FindSegmentsOpen); - - protected: - bool readOnly; - IndexDeletionPolicyPtr deletionPolicy; - int32_t termInfosIndexDivisor; - - public: - virtual IndexReaderPtr doBody(const String& segmentFileName); - }; - - class FindSegmentsReopen : public FindSegmentsFileT - { - public: - FindSegmentsReopen(const DirectoryReaderPtr& reader, bool openReadOnly, const SegmentInfosPtr& infos, const DirectoryPtr& directory); - virtual ~FindSegmentsReopen(); - - LUCENE_CLASS(FindSegmentsReopen); - - protected: - DirectoryReaderWeakPtr _reader; - bool openReadOnly; - - public: - virtual DirectoryReaderPtr doBody(const String& segmentFileName); - }; +namespace Lucene { + +class FindSegmentsOpen : public FindSegmentsFileT { +public: + FindSegmentsOpen(bool readOnly, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor, const SegmentInfosPtr& infos, const DirectoryPtr& directory); + virtual ~FindSegmentsOpen(); + + LUCENE_CLASS(FindSegmentsOpen); + +protected: + bool readOnly; + IndexDeletionPolicyPtr deletionPolicy; + int32_t termInfosIndexDivisor; + +public: + virtual IndexReaderPtr doBody(const String& segmentFileName); +}; + +class FindSegmentsReopen : public FindSegmentsFileT { +public: + FindSegmentsReopen(const DirectoryReaderPtr& reader, bool openReadOnly, const SegmentInfosPtr& infos, const DirectoryPtr& directory); + virtual ~FindSegmentsReopen(); + + LUCENE_CLASS(FindSegmentsReopen); + +protected: + DirectoryReaderWeakPtr _reader; + bool openReadOnly; + +public: + virtual DirectoryReaderPtr doBody(const String& segmentFileName); +}; + } #endif diff --git a/src/core/include/_DisjunctionMaxQuery.h b/src/core/include/_DisjunctionMaxQuery.h index ff90f898..6b047cc3 100644 --- a/src/core/include/_DisjunctionMaxQuery.h +++ b/src/core/include/_DisjunctionMaxQuery.h @@ -9,46 +9,46 @@ #include "Weight.h" -namespace Lucene -{ - /// The Weight for DisjunctionMaxQuery, used to normalize, score and explain these queries. - class DisjunctionMaxWeight : public Weight - { - public: - /// Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. - DisjunctionMaxWeight(const DisjunctionMaxQueryPtr& query, const SearcherPtr& searcher); - virtual ~DisjunctionMaxWeight(); +namespace Lucene { - LUCENE_CLASS(DisjunctionMaxWeight); +/// The Weight for DisjunctionMaxQuery, used to normalize, score and explain these queries. +class DisjunctionMaxWeight : public Weight { +public: + /// Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. + DisjunctionMaxWeight(const DisjunctionMaxQueryPtr& query, const SearcherPtr& searcher); + virtual ~DisjunctionMaxWeight(); - protected: - DisjunctionMaxQueryPtr query; + LUCENE_CLASS(DisjunctionMaxWeight); - /// The Similarity implementation. - SimilarityPtr similarity; +protected: + DisjunctionMaxQueryPtr query; - /// The Weights for our subqueries, in 1-1 correspondence with disjuncts - Collection weights; + /// The Similarity implementation. + SimilarityPtr similarity; - public: - /// Return our associated DisjunctionMaxQuery - virtual QueryPtr getQuery(); + /// The Weights for our subqueries, in 1-1 correspondence with disjuncts + Collection weights; - /// Return our boost - virtual double getValue(); +public: + /// Return our associated DisjunctionMaxQuery + virtual QueryPtr getQuery(); - /// Compute the sub of squared weights of us applied to our subqueries. Used for normalization. - virtual double sumOfSquaredWeights(); + /// Return our boost + virtual double getValue(); - /// Apply the computed normalization factor to our subqueries - virtual void normalize(double norm); + /// Compute the sub of squared weights of us applied to our subqueries. Used for normalization. + virtual double sumOfSquaredWeights(); - /// Create the scorer used to score our associated DisjunctionMaxQuery - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + /// Apply the computed normalization factor to our subqueries + virtual void normalize(double norm); + + /// Create the scorer used to score our associated DisjunctionMaxQuery + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + + /// Explain the score we computed for doc + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); +}; - /// Explain the score we computed for doc - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - }; } #endif diff --git a/src/core/include/_DocIdBitSet.h b/src/core/include/_DocIdBitSet.h index 24f3657b..1c6162f1 100644 --- a/src/core/include/_DocIdBitSet.h +++ b/src/core/include/_DocIdBitSet.h @@ -9,25 +9,25 @@ #include "DocIdSet.h" -namespace Lucene -{ - class DocIdBitSetIterator : public DocIdSetIterator - { - public: - DocIdBitSetIterator(const BitSetPtr& bitSet); - virtual ~DocIdBitSetIterator(); - - LUCENE_CLASS(DocIdBitSetIterator); - - protected: - int32_t docId; - BitSetPtr bitSet; - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - }; +namespace Lucene { + +class DocIdBitSetIterator : public DocIdSetIterator { +public: + DocIdBitSetIterator(const BitSetPtr& bitSet); + virtual ~DocIdBitSetIterator(); + + LUCENE_CLASS(DocIdBitSetIterator); + +protected: + int32_t docId; + BitSetPtr bitSet; + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); +}; + } #endif diff --git a/src/core/include/_DocIdSet.h b/src/core/include/_DocIdSet.h index 3cf2bc98..3eb1fd89 100644 --- a/src/core/include/_DocIdSet.h +++ b/src/core/include/_DocIdSet.h @@ -9,31 +9,30 @@ #include "DocIdSetIterator.h" -namespace Lucene -{ - class EmptyDocIdSetIterator : public DocIdSetIterator - { - public: - virtual ~EmptyDocIdSetIterator(); - LUCENE_CLASS(EmptyDocIdSetIterator); - - public: - virtual int32_t advance(int32_t target); - virtual int32_t docID(); - virtual int32_t nextDoc(); - }; - - /// An empty {@code DocIdSet} instance for easy use, eg. in Filters that hit no documents. - class EmptyDocIdSet : public DocIdSet - { - public: - virtual ~EmptyDocIdSet(); - LUCENE_CLASS(EmptyDocIdSet); - - public: - virtual DocIdSetIteratorPtr iterator(); - virtual bool isCacheable(); - }; +namespace Lucene { + +class EmptyDocIdSetIterator : public DocIdSetIterator { +public: + virtual ~EmptyDocIdSetIterator(); + LUCENE_CLASS(EmptyDocIdSetIterator); + +public: + virtual int32_t advance(int32_t target); + virtual int32_t docID(); + virtual int32_t nextDoc(); +}; + +/// An empty {@code DocIdSet} instance for easy use, eg. in Filters that hit no documents. +class EmptyDocIdSet : public DocIdSet { +public: + virtual ~EmptyDocIdSet(); + LUCENE_CLASS(EmptyDocIdSet); + +public: + virtual DocIdSetIteratorPtr iterator(); + virtual bool isCacheable(); +}; + } #endif diff --git a/src/core/include/_FieldCache.h b/src/core/include/_FieldCache.h index 76d38e0d..efbfa7c4 100644 --- a/src/core/include/_FieldCache.h +++ b/src/core/include/_FieldCache.h @@ -9,91 +9,85 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// @see FieldCache#DEFAULT_BYTE_PARSER() - class DefaultByteParser : public ByteParser - { - public: - virtual ~DefaultByteParser(); - LUCENE_CLASS(DefaultByteParser); - - public: - virtual uint8_t parseByte(const String& string); - virtual String toString(); - }; - - /// @see FieldCache#DEFAULT_INT_PARSER() - class DefaultIntParser : public IntParser - { - public: - virtual ~DefaultIntParser(); - LUCENE_CLASS(DefaultIntParser); - - public: - virtual int32_t parseInt(const String& string); - virtual String toString(); - }; - - /// @see FieldCache#NUMERIC_UTILS_INT_PARSER() - class NumericUtilsIntParser : public IntParser - { - public: - virtual ~NumericUtilsIntParser(); - LUCENE_CLASS(NumericUtilsIntParser); - - public: - virtual int32_t parseInt(const String& string); - virtual String toString(); - }; - - /// @see FieldCache#DEFAULT_LONG_PARSER() - class DefaultLongParser : public LongParser - { - public: - virtual ~DefaultLongParser(); - LUCENE_CLASS(DefaultLongParser); - - public: - virtual int64_t parseLong(const String& string); - virtual String toString(); - }; - - /// @see FieldCache#NUMERIC_UTILS_LONG_PARSER() - class NumericUtilsLongParser : public LongParser - { - public: - virtual ~NumericUtilsLongParser(); - LUCENE_CLASS(NumericUtilsLongParser); - - public: - virtual int64_t parseLong(const String& string); - virtual String toString(); - }; - - /// @see FieldCache#DEFAULT_DOUBLE_PARSER() - class DefaultDoubleParser : public DoubleParser - { - public: - virtual ~DefaultDoubleParser(); - LUCENE_CLASS(DefaultDoubleParser); - - public: - virtual double parseDouble(const String& string); - virtual String toString(); - }; - - /// @see FieldCache#NUMERIC_UTILS_DOUBLE_PARSER() - class NumericUtilsDoubleParser : public DoubleParser - { - public: - virtual ~NumericUtilsDoubleParser(); - LUCENE_CLASS(NumericUtilsDoubleParser); - - public: - virtual double parseDouble(const String& string); - virtual String toString(); - }; +namespace Lucene { + +/// @see FieldCache#DEFAULT_BYTE_PARSER() +class DefaultByteParser : public ByteParser { +public: + virtual ~DefaultByteParser(); + LUCENE_CLASS(DefaultByteParser); + +public: + virtual uint8_t parseByte(const String& string); + virtual String toString(); +}; + +/// @see FieldCache#DEFAULT_INT_PARSER() +class DefaultIntParser : public IntParser { +public: + virtual ~DefaultIntParser(); + LUCENE_CLASS(DefaultIntParser); + +public: + virtual int32_t parseInt(const String& string); + virtual String toString(); +}; + +/// @see FieldCache#NUMERIC_UTILS_INT_PARSER() +class NumericUtilsIntParser : public IntParser { +public: + virtual ~NumericUtilsIntParser(); + LUCENE_CLASS(NumericUtilsIntParser); + +public: + virtual int32_t parseInt(const String& string); + virtual String toString(); +}; + +/// @see FieldCache#DEFAULT_LONG_PARSER() +class DefaultLongParser : public LongParser { +public: + virtual ~DefaultLongParser(); + LUCENE_CLASS(DefaultLongParser); + +public: + virtual int64_t parseLong(const String& string); + virtual String toString(); +}; + +/// @see FieldCache#NUMERIC_UTILS_LONG_PARSER() +class NumericUtilsLongParser : public LongParser { +public: + virtual ~NumericUtilsLongParser(); + LUCENE_CLASS(NumericUtilsLongParser); + +public: + virtual int64_t parseLong(const String& string); + virtual String toString(); +}; + +/// @see FieldCache#DEFAULT_DOUBLE_PARSER() +class DefaultDoubleParser : public DoubleParser { +public: + virtual ~DefaultDoubleParser(); + LUCENE_CLASS(DefaultDoubleParser); + +public: + virtual double parseDouble(const String& string); + virtual String toString(); +}; + +/// @see FieldCache#NUMERIC_UTILS_DOUBLE_PARSER() +class NumericUtilsDoubleParser : public DoubleParser { +public: + virtual ~NumericUtilsDoubleParser(); + LUCENE_CLASS(NumericUtilsDoubleParser); + +public: + virtual double parseDouble(const String& string); + virtual String toString(); +}; + } #endif diff --git a/src/core/include/_FieldCacheRangeFilter.h b/src/core/include/_FieldCacheRangeFilter.h index 5542b5f8..22b52fd6 100644 --- a/src/core/include/_FieldCacheRangeFilter.h +++ b/src/core/include/_FieldCacheRangeFilter.h @@ -13,261 +13,251 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - class FieldCacheRangeFilterString : public FieldCacheRangeFilter - { - public: - FieldCacheRangeFilterString(const String& field, const ParserPtr& parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); - virtual ~FieldCacheRangeFilterString(); - - LUCENE_CLASS(FieldCacheRangeFilterString); - - public: - String lowerVal; - String upperVal; - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); - - virtual String toString(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - }; - - class FieldCacheDocIdSet : public DocIdSet - { - public: - FieldCacheDocIdSet(const IndexReaderPtr& reader, bool mayUseTermDocs); - virtual ~FieldCacheDocIdSet(); - - LUCENE_CLASS(FieldCacheDocIdSet); - - protected: - IndexReaderPtr reader; - bool mayUseTermDocs; - - public: - /// This method checks, if a doc is a hit, should throw ArrayIndexOutOfBounds, when position invalid - virtual bool matchDoc(int32_t doc) = 0; - - /// This DocIdSet is cacheable, if it works solely with FieldCache and no TermDocs. - virtual bool isCacheable(); - - virtual DocIdSetIteratorPtr iterator(); - }; - - template - class FieldCacheDocIdSetNumeric : public FieldCacheDocIdSet - { - public: - FieldCacheDocIdSetNumeric(const IndexReaderPtr& reader, bool mayUseTermDocs, Collection values, TYPE inclusiveLowerPoint, TYPE inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) - { - this->values = values; - this->inclusiveLowerPoint = inclusiveLowerPoint; - this->inclusiveUpperPoint = inclusiveUpperPoint; - } +namespace Lucene { - virtual ~FieldCacheDocIdSetNumeric() - { - } +class FieldCacheRangeFilterString : public FieldCacheRangeFilter { +public: + FieldCacheRangeFilterString(const String& field, const ParserPtr& parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper); + virtual ~FieldCacheRangeFilterString(); - protected: - Collection values; - TYPE inclusiveLowerPoint; - TYPE inclusiveUpperPoint; - - public: - virtual bool matchDoc(int32_t doc) - { - if (doc < 0 || doc >= values.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint); - } - }; - - template - class FieldCacheRangeFilterNumeric : public FieldCacheRangeFilter - { - public: - FieldCacheRangeFilterNumeric(const String& field, const ParserPtr& parser, TYPE lowerVal, TYPE upperVal, TYPE maxVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) - { - this->lowerVal = lowerVal; - this->upperVal = upperVal; - this->maxVal = maxVal; - } + LUCENE_CLASS(FieldCacheRangeFilterString); - virtual ~FieldCacheRangeFilterNumeric() - { - } +public: + String lowerVal; + String upperVal; + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + + virtual String toString(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); +}; + +class FieldCacheDocIdSet : public DocIdSet { +public: + FieldCacheDocIdSet(const IndexReaderPtr& reader, bool mayUseTermDocs); + virtual ~FieldCacheDocIdSet(); + + LUCENE_CLASS(FieldCacheDocIdSet); + +protected: + IndexReaderPtr reader; + bool mayUseTermDocs; + +public: + /// This method checks, if a doc is a hit, should throw ArrayIndexOutOfBounds, when position invalid + virtual bool matchDoc(int32_t doc) = 0; - public: - TYPE lowerVal; - TYPE upperVal; - TYPE maxVal; + /// This DocIdSet is cacheable, if it works solely with FieldCache and no TermDocs. + virtual bool isCacheable(); - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { - if (!includeLower && lowerVal == maxVal) - return DocIdSet::EMPTY_DOCIDSET(); - int64_t inclusiveLowerPoint = (int64_t)(includeLower ? lowerVal : (lowerVal + 1)); + virtual DocIdSetIteratorPtr iterator(); +}; - if (!includeUpper && upperVal == 0) - return DocIdSet::EMPTY_DOCIDSET(); - int64_t inclusiveUpperPoint = (int64_t)(includeUpper ? upperVal : (upperVal - 1)); +template +class FieldCacheDocIdSetNumeric : public FieldCacheDocIdSet { +public: + FieldCacheDocIdSetNumeric(const IndexReaderPtr& reader, bool mayUseTermDocs, Collection values, TYPE inclusiveLowerPoint, TYPE inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) { + this->values = values; + this->inclusiveLowerPoint = inclusiveLowerPoint; + this->inclusiveUpperPoint = inclusiveUpperPoint; + } - if (inclusiveLowerPoint > inclusiveUpperPoint) - return DocIdSet::EMPTY_DOCIDSET(); + virtual ~FieldCacheDocIdSetNumeric() { + } - // we only request the usage of termDocs, if the range contains 0 - return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); +protected: + Collection values; + TYPE inclusiveLowerPoint; + TYPE inclusiveUpperPoint; + +public: + virtual bool matchDoc(int32_t doc) { + if (doc < 0 || doc >= values.size()) { + boost::throw_exception(IndexOutOfBoundsException()); + } + return (values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint); + } +}; + +template +class FieldCacheRangeFilterNumeric : public FieldCacheRangeFilter { +public: + FieldCacheRangeFilterNumeric(const String& field, const ParserPtr& parser, TYPE lowerVal, TYPE upperVal, TYPE maxVal, bool includeLower, bool includeUpper) : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) { + this->lowerVal = lowerVal; + this->upperVal = upperVal; + this->maxVal = maxVal; + } + + virtual ~FieldCacheRangeFilterNumeric() { + } + +public: + TYPE lowerVal; + TYPE upperVal; + TYPE maxVal; + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { + if (!includeLower && lowerVal == maxVal) { + return DocIdSet::EMPTY_DOCIDSET(); } + int64_t inclusiveLowerPoint = (int64_t)(includeLower ? lowerVal : (lowerVal + 1)); - virtual Collection getValues(const IndexReaderPtr& reader) = 0; + if (!includeUpper && upperVal == 0) { + return DocIdSet::EMPTY_DOCIDSET(); + } + int64_t inclusiveUpperPoint = (int64_t)(includeUpper ? upperVal : (upperVal - 1)); - virtual String toString() - { - StringStream buffer; - buffer << field << L":" << (includeLower ? L"[" : L"{"); - buffer << lowerVal << L" TO " << lowerVal; - buffer << (includeLower ? L"]" : L"}"); - return buffer.str(); + if (inclusiveLowerPoint > inclusiveUpperPoint) { + return DocIdSet::EMPTY_DOCIDSET(); } - virtual bool equals(const LuceneObjectPtr& other) - { - if (Filter::equals(other)) - return true; - boost::shared_ptr< FieldCacheRangeFilterNumeric > otherFilter(boost::dynamic_pointer_cast< FieldCacheRangeFilterNumeric >(other)); - if (!otherFilter) - return false; - if (field != otherFilter->field || includeLower != otherFilter->includeLower || includeUpper != otherFilter->includeUpper) - return false; - if (lowerVal != otherFilter->lowerVal || upperVal != otherFilter->upperVal) - return false; - if (parser.get() != NULL ? !parser->equals(otherFilter->parser) : otherFilter->parser.get() != NULL) - return false; + // we only request the usage of termDocs, if the range contains 0 + return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); + } + + virtual Collection getValues(const IndexReaderPtr& reader) = 0; + + virtual String toString() { + StringStream buffer; + buffer << field << L":" << (includeLower ? L"[" : L"{"); + buffer << lowerVal << L" TO " << lowerVal; + buffer << (includeLower ? L"]" : L"}"); + return buffer.str(); + } + + virtual bool equals(const LuceneObjectPtr& other) { + if (Filter::equals(other)) { return true; } - - int32_t hashCode() - { - int32_t code = StringUtils::hashCode(field); - code ^= lowerVal == 0 ? 550356204 : (int32_t)lowerVal; - code = (code << 1) | MiscUtils::unsignedShift(code, 31); // rotate to distinguish lower from upper - code ^= upperVal == 0 ? -1674416163 : (int32_t)upperVal; - code ^= parser ? parser->hashCode() : -1572457324; - code ^= (includeLower ? 1549299360 : -365038026) ^ (includeUpper ? 1721088258 : 1948649653); - return code; + boost::shared_ptr< FieldCacheRangeFilterNumeric > otherFilter(boost::dynamic_pointer_cast< FieldCacheRangeFilterNumeric >(other)); + if (!otherFilter) { + return false; + } + if (field != otherFilter->field || includeLower != otherFilter->includeLower || includeUpper != otherFilter->includeUpper) { + return false; + } + if (lowerVal != otherFilter->lowerVal || upperVal != otherFilter->upperVal) { + return false; } - }; - - class FieldCacheRangeFilterByte : public FieldCacheRangeFilterNumeric - { - public: - FieldCacheRangeFilterByte(const String& field, const ParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); - virtual ~FieldCacheRangeFilterByte(); - - LUCENE_CLASS(FieldCacheRangeFilterByte); - - public: - virtual Collection getValues(const IndexReaderPtr& reader); - }; - - class FieldCacheRangeFilterInt : public FieldCacheRangeFilterNumeric - { - public: - FieldCacheRangeFilterInt(const String& field, const ParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); - virtual ~FieldCacheRangeFilterInt(); - - LUCENE_CLASS(FieldCacheRangeFilterInt); - - public: - virtual Collection getValues(const IndexReaderPtr& reader); - }; - - class FieldCacheRangeFilterLong : public FieldCacheRangeFilterNumeric - { - public: - FieldCacheRangeFilterLong(const String& field, const ParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); - virtual ~FieldCacheRangeFilterLong(); - - LUCENE_CLASS(FieldCacheRangeFilterLong); - - public: - virtual Collection getValues(const IndexReaderPtr& reader); - }; - - class FieldCacheRangeFilterDouble : public FieldCacheRangeFilterNumeric - { - public: - FieldCacheRangeFilterDouble(const String& field, const ParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); - virtual ~FieldCacheRangeFilterDouble(); - - LUCENE_CLASS(FieldCacheRangeFilterDouble); - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); - virtual Collection getValues(const IndexReaderPtr& reader); - }; - - class FieldCacheDocIdSetString : public FieldCacheDocIdSet - { - public: - FieldCacheDocIdSetString(const IndexReaderPtr& reader, bool mayUseTermDocs, const StringIndexPtr& fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint); - virtual ~FieldCacheDocIdSetString(); - - LUCENE_CLASS(FieldCacheDocIdSetString); - - protected: - StringIndexPtr fcsi; - int32_t inclusiveLowerPoint; - int32_t inclusiveUpperPoint; - - public: - virtual bool matchDoc(int32_t doc); - }; - - /// A DocIdSetIterator using TermDocs to iterate valid docIds - class FieldDocIdSetIteratorTermDocs : public DocIdSetIterator - { - public: - FieldDocIdSetIteratorTermDocs(const FieldCacheDocIdSetPtr& cacheDocIdSet, const TermDocsPtr& termDocs); - virtual ~FieldDocIdSetIteratorTermDocs(); - - LUCENE_CLASS(FieldDocIdSetIteratorTermDocs); - - protected: - FieldCacheDocIdSetWeakPtr _cacheDocIdSet; - TermDocsPtr termDocs; - int32_t doc; - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - }; - - /// A DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there - /// are no deletions are on the index. - class FieldDocIdSetIteratorIncrement : public DocIdSetIterator - { - public: - FieldDocIdSetIteratorIncrement(const FieldCacheDocIdSetPtr& cacheDocIdSet); - virtual ~FieldDocIdSetIteratorIncrement(); - - LUCENE_CLASS(FieldDocIdSetIteratorIncrement); - - protected: - FieldCacheDocIdSetWeakPtr _cacheDocIdSet; - int32_t doc; - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - }; + if (parser.get() != NULL ? !parser->equals(otherFilter->parser) : otherFilter->parser.get() != NULL) { + return false; + } + return true; + } + + int32_t hashCode() { + int32_t code = StringUtils::hashCode(field); + code ^= lowerVal == 0 ? 550356204 : (int32_t)lowerVal; + code = (code << 1) | MiscUtils::unsignedShift(code, 31); // rotate to distinguish lower from upper + code ^= upperVal == 0 ? -1674416163 : (int32_t)upperVal; + code ^= parser ? parser->hashCode() : -1572457324; + code ^= (includeLower ? 1549299360 : -365038026) ^ (includeUpper ? 1721088258 : 1948649653); + return code; + } +}; + +class FieldCacheRangeFilterByte : public FieldCacheRangeFilterNumeric { +public: + FieldCacheRangeFilterByte(const String& field, const ParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper); + virtual ~FieldCacheRangeFilterByte(); + + LUCENE_CLASS(FieldCacheRangeFilterByte); + +public: + virtual Collection getValues(const IndexReaderPtr& reader); +}; + +class FieldCacheRangeFilterInt : public FieldCacheRangeFilterNumeric { +public: + FieldCacheRangeFilterInt(const String& field, const ParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper); + virtual ~FieldCacheRangeFilterInt(); + + LUCENE_CLASS(FieldCacheRangeFilterInt); + +public: + virtual Collection getValues(const IndexReaderPtr& reader); +}; + +class FieldCacheRangeFilterLong : public FieldCacheRangeFilterNumeric { +public: + FieldCacheRangeFilterLong(const String& field, const ParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper); + virtual ~FieldCacheRangeFilterLong(); + + LUCENE_CLASS(FieldCacheRangeFilterLong); + +public: + virtual Collection getValues(const IndexReaderPtr& reader); +}; + +class FieldCacheRangeFilterDouble : public FieldCacheRangeFilterNumeric { +public: + FieldCacheRangeFilterDouble(const String& field, const ParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper); + virtual ~FieldCacheRangeFilterDouble(); + + LUCENE_CLASS(FieldCacheRangeFilterDouble); + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + virtual Collection getValues(const IndexReaderPtr& reader); +}; + +class FieldCacheDocIdSetString : public FieldCacheDocIdSet { +public: + FieldCacheDocIdSetString(const IndexReaderPtr& reader, bool mayUseTermDocs, const StringIndexPtr& fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint); + virtual ~FieldCacheDocIdSetString(); + + LUCENE_CLASS(FieldCacheDocIdSetString); + +protected: + StringIndexPtr fcsi; + int32_t inclusiveLowerPoint; + int32_t inclusiveUpperPoint; + +public: + virtual bool matchDoc(int32_t doc); +}; + +/// A DocIdSetIterator using TermDocs to iterate valid docIds +class FieldDocIdSetIteratorTermDocs : public DocIdSetIterator { +public: + FieldDocIdSetIteratorTermDocs(const FieldCacheDocIdSetPtr& cacheDocIdSet, const TermDocsPtr& termDocs); + virtual ~FieldDocIdSetIteratorTermDocs(); + + LUCENE_CLASS(FieldDocIdSetIteratorTermDocs); + +protected: + FieldCacheDocIdSetWeakPtr _cacheDocIdSet; + TermDocsPtr termDocs; + int32_t doc; + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); +}; + +/// A DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there +/// are no deletions are on the index. +class FieldDocIdSetIteratorIncrement : public DocIdSetIterator { +public: + FieldDocIdSetIteratorIncrement(const FieldCacheDocIdSetPtr& cacheDocIdSet); + virtual ~FieldDocIdSetIteratorIncrement(); + + LUCENE_CLASS(FieldDocIdSetIteratorIncrement); + +protected: + FieldCacheDocIdSetWeakPtr _cacheDocIdSet; + int32_t doc; + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); +}; + } #endif diff --git a/src/core/include/_FieldCacheSanityChecker.h b/src/core/include/_FieldCacheSanityChecker.h index 624c38c0..f6216f67 100644 --- a/src/core/include/_FieldCacheSanityChecker.h +++ b/src/core/include/_FieldCacheSanityChecker.h @@ -9,26 +9,26 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Simple pair object for using "readerKey + fieldName" a Map key - class ReaderField : public LuceneObject - { - public: - ReaderField(const LuceneObjectPtr& readerKey, const String& fieldName); - virtual ~ReaderField(); - - LUCENE_CLASS(ReaderField); - - public: - LuceneObjectPtr readerKey; - String fieldName; - - public: - virtual int32_t hashCode(); - virtual bool equals(const LuceneObjectPtr& other); - virtual String toString(); - }; +namespace Lucene { + +/// Simple pair object for using "readerKey + fieldName" a Map key +class ReaderField : public LuceneObject { +public: + ReaderField(const LuceneObjectPtr& readerKey, const String& fieldName); + virtual ~ReaderField(); + + LUCENE_CLASS(ReaderField); + +public: + LuceneObjectPtr readerKey; + String fieldName; + +public: + virtual int32_t hashCode(); + virtual bool equals(const LuceneObjectPtr& other); + virtual String toString(); +}; + } #endif diff --git a/src/core/include/_FieldCacheTermsFilter.h b/src/core/include/_FieldCacheTermsFilter.h index 14310f7e..68708bd4 100644 --- a/src/core/include/_FieldCacheTermsFilter.h +++ b/src/core/include/_FieldCacheTermsFilter.h @@ -10,45 +10,44 @@ #include "DocIdSet.h" #include "DocIdSetIterator.h" -namespace Lucene -{ - class FieldCacheTermsFilterDocIdSet : public DocIdSet - { - public: - FieldCacheTermsFilterDocIdSet(Collection terms, const StringIndexPtr& fcsi); - virtual ~FieldCacheTermsFilterDocIdSet(); - - LUCENE_CLASS(FieldCacheTermsFilterDocIdSet); - - protected: - StringIndexPtr fcsi; - OpenBitSetPtr openBitSet; - - public: - virtual DocIdSetIteratorPtr iterator(); - - /// This DocIdSet implementation is cacheable. - virtual bool isCacheable(); - }; - - class FieldCacheTermsFilterDocIdSetIterator : public DocIdSetIterator - { - public: - FieldCacheTermsFilterDocIdSetIterator(const StringIndexPtr& fcsi, const OpenBitSetPtr& openBitSet); - virtual ~FieldCacheTermsFilterDocIdSetIterator(); - - LUCENE_CLASS(FieldCacheTermsFilterDocIdSetIterator); - - protected: - StringIndexPtr fcsi; - OpenBitSetPtr openBitSet; - int32_t doc; - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - }; +namespace Lucene { + +class FieldCacheTermsFilterDocIdSet : public DocIdSet { +public: + FieldCacheTermsFilterDocIdSet(Collection terms, const StringIndexPtr& fcsi); + virtual ~FieldCacheTermsFilterDocIdSet(); + + LUCENE_CLASS(FieldCacheTermsFilterDocIdSet); + +protected: + StringIndexPtr fcsi; + OpenBitSetPtr openBitSet; + +public: + virtual DocIdSetIteratorPtr iterator(); + + /// This DocIdSet implementation is cacheable. + virtual bool isCacheable(); +}; + +class FieldCacheTermsFilterDocIdSetIterator : public DocIdSetIterator { +public: + FieldCacheTermsFilterDocIdSetIterator(const StringIndexPtr& fcsi, const OpenBitSetPtr& openBitSet); + virtual ~FieldCacheTermsFilterDocIdSetIterator(); + + LUCENE_CLASS(FieldCacheTermsFilterDocIdSetIterator); + +protected: + StringIndexPtr fcsi; + OpenBitSetPtr openBitSet; + int32_t doc; + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); +}; + } #endif diff --git a/src/core/include/_FieldValueHitQueue.h b/src/core/include/_FieldValueHitQueue.h index c104f243..ea1bba2c 100644 --- a/src/core/include/_FieldValueHitQueue.h +++ b/src/core/include/_FieldValueHitQueue.h @@ -9,37 +9,36 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// An implementation of {@link FieldValueHitQueue} which is optimized in case there is just one comparator. - class OneComparatorFieldValueHitQueue : public FieldValueHitQueue - { - public: - OneComparatorFieldValueHitQueue(Collection fields, int32_t size); - virtual ~OneComparatorFieldValueHitQueue(); - - LUCENE_CLASS(OneComparatorFieldValueHitQueue); - - public: - FieldComparatorPtr comparator; - int32_t oneReverseMul; - - protected: - virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); - }; - - /// An implementation of {@link FieldValueHitQueue} which is optimized in case there is more than one comparator. - class MultiComparatorsFieldValueHitQueue : public FieldValueHitQueue - { - public: - MultiComparatorsFieldValueHitQueue(Collection fields, int32_t size); - virtual ~MultiComparatorsFieldValueHitQueue(); - - LUCENE_CLASS(MultiComparatorsFieldValueHitQueue); - - protected: - virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); - }; +namespace Lucene { + +/// An implementation of {@link FieldValueHitQueue} which is optimized in case there is just one comparator. +class OneComparatorFieldValueHitQueue : public FieldValueHitQueue { +public: + OneComparatorFieldValueHitQueue(Collection fields, int32_t size); + virtual ~OneComparatorFieldValueHitQueue(); + + LUCENE_CLASS(OneComparatorFieldValueHitQueue); + +public: + FieldComparatorPtr comparator; + int32_t oneReverseMul; + +protected: + virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); +}; + +/// An implementation of {@link FieldValueHitQueue} which is optimized in case there is more than one comparator. +class MultiComparatorsFieldValueHitQueue : public FieldValueHitQueue { +public: + MultiComparatorsFieldValueHitQueue(Collection fields, int32_t size); + virtual ~MultiComparatorsFieldValueHitQueue(); + + LUCENE_CLASS(MultiComparatorsFieldValueHitQueue); + +protected: + virtual bool lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second); +}; + } #endif diff --git a/src/core/include/_FilterManager.h b/src/core/include/_FilterManager.h index 1e1f3d41..5ccbe58d 100644 --- a/src/core/include/_FilterManager.h +++ b/src/core/include/_FilterManager.h @@ -9,47 +9,46 @@ #include "LuceneThread.h" -namespace Lucene -{ - /// Holds the filter and the last time the filter was used, to make LRU-based cache cleaning possible. - class FilterItem : public LuceneObject - { - public: - FilterItem(const FilterPtr& filter); - virtual ~FilterItem(); - - LUCENE_CLASS(FilterItem); - - public: - FilterPtr filter; - int64_t timestamp; - }; - - /// Keeps the cache from getting too big. - /// - /// The SortedSet sortedFilterItems is used only to sort the items from the cache, so when it's time to clean - /// up we have the TreeSet sort the FilterItems by timestamp. - /// - /// Removes 1.5 * the numbers of items to make the cache smaller. - /// For example: If cache clean size is 10, and the cache is at 15, we would remove (15 - 10) * 1.5 = 7.5 - /// round up to 8. This way we clean the cache a bit more, and avoid having the cache cleaner having to do - /// it frequently. - class FilterCleaner : public LuceneThread - { - public: - FilterCleaner(const FilterManagerPtr& manager); - virtual ~FilterCleaner(); - - LUCENE_CLASS(FilterCleaner); - - protected: - FilterManagerWeakPtr _manager; - bool running; - MapLongInt sortedFilterItems; - - public: - virtual void run(); - }; +namespace Lucene { + +/// Holds the filter and the last time the filter was used, to make LRU-based cache cleaning possible. +class FilterItem : public LuceneObject { +public: + FilterItem(const FilterPtr& filter); + virtual ~FilterItem(); + + LUCENE_CLASS(FilterItem); + +public: + FilterPtr filter; + int64_t timestamp; +}; + +/// Keeps the cache from getting too big. +/// +/// The SortedSet sortedFilterItems is used only to sort the items from the cache, so when it's time to clean +/// up we have the TreeSet sort the FilterItems by timestamp. +/// +/// Removes 1.5 * the numbers of items to make the cache smaller. +/// For example: If cache clean size is 10, and the cache is at 15, we would remove (15 - 10) * 1.5 = 7.5 +/// round up to 8. This way we clean the cache a bit more, and avoid having the cache cleaner having to do +/// it frequently. +class FilterCleaner : public LuceneThread { +public: + FilterCleaner(const FilterManagerPtr& manager); + virtual ~FilterCleaner(); + + LUCENE_CLASS(FilterCleaner); + +protected: + FilterManagerWeakPtr _manager; + bool running; + MapLongInt sortedFilterItems; + +public: + virtual void run(); +}; + } #endif diff --git a/src/core/include/_FilteredDocIdSet.h b/src/core/include/_FilteredDocIdSet.h index d2f7b0b3..c71dc58b 100644 --- a/src/core/include/_FilteredDocIdSet.h +++ b/src/core/include/_FilteredDocIdSet.h @@ -9,23 +9,23 @@ #include "FilteredDocIdSetIterator.h" -namespace Lucene -{ - /// Implementation of the contract to build a DocIdSetIterator. - class DefaultFilteredDocIdSetIterator : public FilteredDocIdSetIterator - { - public: - DefaultFilteredDocIdSetIterator(const FilteredDocIdSetPtr& filtered, const DocIdSetIteratorPtr& innerIter); - virtual ~DefaultFilteredDocIdSetIterator(); - - LUCENE_CLASS(DefaultFilteredDocIdSetIterator); - - protected: - FilteredDocIdSetPtr filtered; - - protected: - virtual bool match(int32_t docid); - }; +namespace Lucene { + +/// Implementation of the contract to build a DocIdSetIterator. +class DefaultFilteredDocIdSetIterator : public FilteredDocIdSetIterator { +public: + DefaultFilteredDocIdSetIterator(const FilteredDocIdSetPtr& filtered, const DocIdSetIteratorPtr& innerIter); + virtual ~DefaultFilteredDocIdSetIterator(); + + LUCENE_CLASS(DefaultFilteredDocIdSetIterator); + +protected: + FilteredDocIdSetPtr filtered; + +protected: + virtual bool match(int32_t docid); +}; + } #endif diff --git a/src/core/include/_FilteredQuery.h b/src/core/include/_FilteredQuery.h index 83ca70e6..80d91d2c 100644 --- a/src/core/include/_FilteredQuery.h +++ b/src/core/include/_FilteredQuery.h @@ -10,56 +10,55 @@ #include "Weight.h" #include "Scorer.h" -namespace Lucene -{ - class FilteredQueryWeight : public Weight - { - public: - FilteredQueryWeight(const FilteredQueryPtr& query, const WeightPtr& weight, const SimilarityPtr& similarity); - virtual ~FilteredQueryWeight(); +namespace Lucene { - LUCENE_CLASS(FilteredQueryWeight); +class FilteredQueryWeight : public Weight { +public: + FilteredQueryWeight(const FilteredQueryPtr& query, const WeightPtr& weight, const SimilarityPtr& similarity); + virtual ~FilteredQueryWeight(); - protected: - FilteredQueryPtr query; - WeightPtr weight; - SimilarityPtr similarity; - double value; + LUCENE_CLASS(FilteredQueryWeight); - public: - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - virtual QueryPtr getQuery(); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); +protected: + FilteredQueryPtr query; + WeightPtr weight; + SimilarityPtr similarity; + double value; - friend class FilteredQueryWeightScorer; - }; +public: + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); + virtual QueryPtr getQuery(); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - class FilteredQueryWeightScorer : public Scorer - { - public: - FilteredQueryWeightScorer(const FilteredQueryWeightPtr& weight, const ScorerPtr& scorer, const DocIdSetIteratorPtr& docIdSetIterator, const SimilarityPtr& similarity); - virtual ~FilteredQueryWeightScorer(); + friend class FilteredQueryWeightScorer; +}; - LUCENE_CLASS(FilteredQueryWeightScorer); +class FilteredQueryWeightScorer : public Scorer { +public: + FilteredQueryWeightScorer(const FilteredQueryWeightPtr& weight, const ScorerPtr& scorer, const DocIdSetIteratorPtr& docIdSetIterator, const SimilarityPtr& similarity); + virtual ~FilteredQueryWeightScorer(); - protected: - FilteredQueryWeightPtr weight; - ScorerPtr scorer; - DocIdSetIteratorPtr docIdSetIterator; - int32_t doc; + LUCENE_CLASS(FilteredQueryWeightScorer); - public: - virtual int32_t nextDoc(); - virtual int32_t docID(); - virtual int32_t advance(int32_t target); - virtual double score(); +protected: + FilteredQueryWeightPtr weight; + ScorerPtr scorer; + DocIdSetIteratorPtr docIdSetIterator; + int32_t doc; + +public: + virtual int32_t nextDoc(); + virtual int32_t docID(); + virtual int32_t advance(int32_t target); + virtual double score(); + +protected: + int32_t advanceToCommon(int32_t scorerDoc, int32_t disiDoc); +}; - protected: - int32_t advanceToCommon(int32_t scorerDoc, int32_t disiDoc); - }; } #endif diff --git a/src/core/include/_FuzzyQuery.h b/src/core/include/_FuzzyQuery.h index db71aa0f..4e9cc6d1 100644 --- a/src/core/include/_FuzzyQuery.h +++ b/src/core/include/_FuzzyQuery.h @@ -9,33 +9,32 @@ #include "PriorityQueue.h" -namespace Lucene -{ - class ScoreTerm : public LuceneObject - { - public: - virtual ~ScoreTerm(); - LUCENE_CLASS(ScoreTerm); - - public: - TermPtr term; - double score; - - public: - int32_t compareTo(const ScoreTermPtr& other); - }; - - class ScoreTermQueue : public PriorityQueue - { - public: - ScoreTermQueue(int32_t size); - virtual ~ScoreTermQueue(); - - LUCENE_CLASS(ScoreTermQueue); - - protected: - virtual bool lessThan(const ScoreTermPtr& first, const ScoreTermPtr& second); - }; +namespace Lucene { + +class ScoreTerm : public LuceneObject { +public: + virtual ~ScoreTerm(); + LUCENE_CLASS(ScoreTerm); + +public: + TermPtr term; + double score; + +public: + int32_t compareTo(const ScoreTermPtr& other); +}; + +class ScoreTermQueue : public PriorityQueue { +public: + ScoreTermQueue(int32_t size); + virtual ~ScoreTermQueue(); + + LUCENE_CLASS(ScoreTermQueue); + +protected: + virtual bool lessThan(const ScoreTermPtr& first, const ScoreTermPtr& second); +}; + } #endif diff --git a/src/core/include/_IndexReader.h b/src/core/include/_IndexReader.h index 9ead99b5..ca252774 100644 --- a/src/core/include/_IndexReader.h +++ b/src/core/include/_IndexReader.h @@ -9,19 +9,19 @@ #include "_SegmentInfos.h" -namespace Lucene -{ - class FindSegmentsModified : public FindSegmentsFileT - { - public: - FindSegmentsModified(const SegmentInfosPtr& infos, const DirectoryPtr& directory); - virtual ~FindSegmentsModified(); - - LUCENE_CLASS(FindSegmentsModified); - - public: - virtual uint64_t doBody(const String& segmentFileName); - }; +namespace Lucene { + +class FindSegmentsModified : public FindSegmentsFileT { +public: + FindSegmentsModified(const SegmentInfosPtr& infos, const DirectoryPtr& directory); + virtual ~FindSegmentsModified(); + + LUCENE_CLASS(FindSegmentsModified); + +public: + virtual uint64_t doBody(const String& segmentFileName); +}; + } #endif diff --git a/src/core/include/_IndexWriter.h b/src/core/include/_IndexWriter.h index d337ec06..a6837576 100644 --- a/src/core/include/_IndexWriter.h +++ b/src/core/include/_IndexWriter.h @@ -9,59 +9,59 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Holds shared SegmentReader instances. IndexWriter uses SegmentReaders for 1) applying deletes, - /// 2) doing merges, 3) handing out a real-time reader. This pool reuses instances of the SegmentReaders - /// in all these places if it is in "near real-time mode" (getReader() has been called on this instance). - class ReaderPool : public LuceneObject - { - public: - ReaderPool(const IndexWriterPtr& writer); - virtual ~ReaderPool(); - - LUCENE_CLASS(ReaderPool); - - protected: - IndexWriterWeakPtr _indexWriter; - MapSegmentInfoSegmentReader readerMap; - - public: - /// Forcefully clear changes for the specified segments, and remove from the pool. - /// This is called on successful merge. - void clear(const SegmentInfosPtr& infos); - - /// used only by asserts - bool infoIsLive(const SegmentInfoPtr& info); - SegmentInfoPtr mapToLive(const SegmentInfoPtr& info); - - /// Release the segment reader (i.e. decRef it and close if there are no more references. - void release(const SegmentReaderPtr& sr); - - /// Release the segment reader (i.e. decRef it and close if there are no more references. - void release(const SegmentReaderPtr& sr, bool drop); - - /// Remove all our references to readers, and commits any pending changes. - void close(); - - /// Commit all segment reader in the pool. - void commit(); - - /// Returns a ref to a clone. NOTE: this clone is not enrolled in the pool, so you should - /// simply close() it when you're done (ie, do not call release()). - IndexReaderPtr getReadOnlyClone(const SegmentInfoPtr& info, bool doOpenStores, int32_t termInfosIndexDivisor); - - /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling - /// {@link #release(SegmentReader)} - SegmentReaderPtr get(const SegmentInfoPtr& info, bool doOpenStores); - - /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling - /// {@link #release(SegmentReader)} - SegmentReaderPtr get(const SegmentInfoPtr& info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor); - - /// Returns a ref - SegmentReaderPtr getIfExists(const SegmentInfoPtr& info); - }; +namespace Lucene { + +/// Holds shared SegmentReader instances. IndexWriter uses SegmentReaders for 1) applying deletes, +/// 2) doing merges, 3) handing out a real-time reader. This pool reuses instances of the SegmentReaders +/// in all these places if it is in "near real-time mode" (getReader() has been called on this instance). +class ReaderPool : public LuceneObject { +public: + ReaderPool(const IndexWriterPtr& writer); + virtual ~ReaderPool(); + + LUCENE_CLASS(ReaderPool); + +protected: + IndexWriterWeakPtr _indexWriter; + MapSegmentInfoSegmentReader readerMap; + +public: + /// Forcefully clear changes for the specified segments, and remove from the pool. + /// This is called on successful merge. + void clear(const SegmentInfosPtr& infos); + + /// used only by asserts + bool infoIsLive(const SegmentInfoPtr& info); + SegmentInfoPtr mapToLive(const SegmentInfoPtr& info); + + /// Release the segment reader (i.e. decRef it and close if there are no more references. + void release(const SegmentReaderPtr& sr); + + /// Release the segment reader (i.e. decRef it and close if there are no more references. + void release(const SegmentReaderPtr& sr, bool drop); + + /// Remove all our references to readers, and commits any pending changes. + void close(); + + /// Commit all segment reader in the pool. + void commit(); + + /// Returns a ref to a clone. NOTE: this clone is not enrolled in the pool, so you should + /// simply close() it when you're done (ie, do not call release()). + IndexReaderPtr getReadOnlyClone(const SegmentInfoPtr& info, bool doOpenStores, int32_t termInfosIndexDivisor); + + /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling + /// {@link #release(SegmentReader)} + SegmentReaderPtr get(const SegmentInfoPtr& info, bool doOpenStores); + + /// Obtain a SegmentReader from the readerPool. The reader must be returned by calling + /// {@link #release(SegmentReader)} + SegmentReaderPtr get(const SegmentInfoPtr& info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor); + + /// Returns a ref + SegmentReaderPtr getIfExists(const SegmentInfoPtr& info); +}; + } #endif diff --git a/src/core/include/_IntFieldSource.h b/src/core/include/_IntFieldSource.h index 061a7ff0..bbf25ae4 100644 --- a/src/core/include/_IntFieldSource.h +++ b/src/core/include/_IntFieldSource.h @@ -9,26 +9,26 @@ #include "DocValues.h" -namespace Lucene -{ - class IntDocValues : public DocValues - { - public: - IntDocValues(const IntFieldSourcePtr& source, Collection arr); - virtual ~IntDocValues(); - - LUCENE_CLASS(IntDocValues); - - protected: - IntFieldSourceWeakPtr _source; - Collection arr; - - public: - virtual double doubleVal(int32_t doc); - virtual int32_t intVal(int32_t doc); - virtual String toString(int32_t doc); - virtual CollectionValue getInnerArray(); - }; +namespace Lucene { + +class IntDocValues : public DocValues { +public: + IntDocValues(const IntFieldSourcePtr& source, Collection arr); + virtual ~IntDocValues(); + + LUCENE_CLASS(IntDocValues); + +protected: + IntFieldSourceWeakPtr _source; + Collection arr; + +public: + virtual double doubleVal(int32_t doc); + virtual int32_t intVal(int32_t doc); + virtual String toString(int32_t doc); + virtual CollectionValue getInnerArray(); +}; + } #endif diff --git a/src/core/include/_MMapDirectory.h b/src/core/include/_MMapDirectory.h index ccb44242..3438f666 100644 --- a/src/core/include/_MMapDirectory.h +++ b/src/core/include/_MMapDirectory.h @@ -10,51 +10,51 @@ #include #include "IndexInput.h" -namespace Lucene -{ - class MMapIndexInput : public IndexInput - { - public: - MMapIndexInput(const String& path = L""); - virtual ~MMapIndexInput(); - - LUCENE_CLASS(MMapIndexInput); - - protected: - int32_t _length; - bool isClone; - boost::iostreams::mapped_file_source file; - int32_t bufferPosition; // next byte to read - - public: - /// Reads and returns a single byte. - /// @see IndexOutput#writeByte(uint8_t) - virtual uint8_t readByte(); - - /// Reads a specified number of bytes into an array at the specified offset. - /// @param b the array to read bytes into. - /// @param offset the offset in the array to start storing bytes. - /// @param length the number of bytes to read. - /// @see IndexOutput#writeBytes(const uint8_t*,int) - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); - - /// Returns the current position in this file, where the next read will occur. - /// @see #seek(int64_t) - virtual int64_t getFilePointer(); - - /// Sets current position in this file, where the next read will occur. - /// @see #getFilePointer() - virtual void seek(int64_t pos); - - /// The number of bytes in the file. - virtual int64_t length(); - - /// Closes the stream to further operations. - virtual void close(); - - /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +class MMapIndexInput : public IndexInput { +public: + MMapIndexInput(const String& path = L""); + virtual ~MMapIndexInput(); + + LUCENE_CLASS(MMapIndexInput); + +protected: + int32_t _length; + bool isClone; + boost::iostreams::mapped_file_source file; + int32_t bufferPosition; // next byte to read + +public: + /// Reads and returns a single byte. + /// @see IndexOutput#writeByte(uint8_t) + virtual uint8_t readByte(); + + /// Reads a specified number of bytes into an array at the specified offset. + /// @param b the array to read bytes into. + /// @param offset the offset in the array to start storing bytes. + /// @param length the number of bytes to read. + /// @see IndexOutput#writeBytes(const uint8_t*,int) + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length); + + /// Returns the current position in this file, where the next read will occur. + /// @see #seek(int64_t) + virtual int64_t getFilePointer(); + + /// Sets current position in this file, where the next read will occur. + /// @see #getFilePointer() + virtual void seek(int64_t pos); + + /// The number of bytes in the file. + virtual int64_t length(); + + /// Closes the stream to further operations. + virtual void close(); + + /// Returns a clone of this stream. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/src/core/include/_MatchAllDocsQuery.h b/src/core/include/_MatchAllDocsQuery.h index ce5edccb..6ac81734 100644 --- a/src/core/include/_MatchAllDocsQuery.h +++ b/src/core/include/_MatchAllDocsQuery.h @@ -10,55 +10,54 @@ #include "Weight.h" #include "Scorer.h" -namespace Lucene -{ - class MatchAllDocsWeight : public Weight - { - public: - MatchAllDocsWeight(const MatchAllDocsQueryPtr& query, const SearcherPtr& searcher); - virtual ~MatchAllDocsWeight(); +namespace Lucene { + +class MatchAllDocsWeight : public Weight { +public: + MatchAllDocsWeight(const MatchAllDocsQueryPtr& query, const SearcherPtr& searcher); + virtual ~MatchAllDocsWeight(); + + LUCENE_CLASS(MatchAllDocsWeight); + +protected: + MatchAllDocsQueryPtr query; + SimilarityPtr similarity; + double queryWeight; + double queryNorm; + +public: + virtual String toString(); + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); +}; + +class MatchAllScorer : public Scorer { +public: + MatchAllScorer(const MatchAllDocsQueryPtr& query, const IndexReaderPtr& reader, const SimilarityPtr& similarity, const WeightPtr& weight, ByteArray norms); + virtual ~MatchAllScorer(); + + LUCENE_CLASS(MatchAllScorer); + +public: + TermDocsPtr termDocs; + double _score; + ByteArray norms; + +protected: + MatchAllDocsQueryPtr query; + int32_t doc; + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual double score(); + virtual int32_t advance(int32_t target); +}; - LUCENE_CLASS(MatchAllDocsWeight); - - protected: - MatchAllDocsQueryPtr query; - SimilarityPtr similarity; - double queryWeight; - double queryNorm; - - public: - virtual String toString(); - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - }; - - class MatchAllScorer : public Scorer - { - public: - MatchAllScorer(const MatchAllDocsQueryPtr& query, const IndexReaderPtr& reader, const SimilarityPtr& similarity, const WeightPtr& weight, ByteArray norms); - virtual ~MatchAllScorer(); - - LUCENE_CLASS(MatchAllScorer); - - public: - TermDocsPtr termDocs; - double _score; - ByteArray norms; - - protected: - MatchAllDocsQueryPtr query; - int32_t doc; - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual double score(); - virtual int32_t advance(int32_t target); - }; } #endif diff --git a/src/core/include/_MultiPhraseQuery.h b/src/core/include/_MultiPhraseQuery.h index b211e4a9..d161dc6e 100644 --- a/src/core/include/_MultiPhraseQuery.h +++ b/src/core/include/_MultiPhraseQuery.h @@ -9,32 +9,32 @@ #include "Weight.h" -namespace Lucene -{ - class MultiPhraseWeight : public Weight - { - public: - MultiPhraseWeight(const MultiPhraseQueryPtr& query, const SearcherPtr& searcher); - virtual ~MultiPhraseWeight(); - - LUCENE_CLASS(MultiPhraseWeight); - - protected: - MultiPhraseQueryPtr query; - SimilarityPtr similarity; - double value; - double idf; - double queryNorm; - double queryWeight; - - public: - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - }; +namespace Lucene { + +class MultiPhraseWeight : public Weight { +public: + MultiPhraseWeight(const MultiPhraseQueryPtr& query, const SearcherPtr& searcher); + virtual ~MultiPhraseWeight(); + + LUCENE_CLASS(MultiPhraseWeight); + +protected: + MultiPhraseQueryPtr query; + SimilarityPtr similarity; + double value; + double idf; + double queryNorm; + double queryWeight; + +public: + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); +}; + } #endif diff --git a/src/core/include/_MultiSearcher.h b/src/core/include/_MultiSearcher.h index 0bb85761..0b2b3433 100644 --- a/src/core/include/_MultiSearcher.h +++ b/src/core/include/_MultiSearcher.h @@ -10,103 +10,100 @@ #include "Searcher.h" #include "Collector.h" -namespace Lucene -{ - /// Document Frequency cache acting as a Dummy-Searcher. This class is not a full-fledged Searcher, but - /// only supports the methods necessary to initialize Weights. - class CachedDfSource : public Searcher - { - public: - CachedDfSource(MapTermInt dfMap, int32_t maxDoc, const SimilarityPtr& similarity); - virtual ~CachedDfSource(); - - LUCENE_CLASS(CachedDfSource); - - protected: - MapTermInt dfMap; // Map from Terms to corresponding doc freqs - int32_t _maxDoc; // document count - - public: - virtual int32_t docFreq(const TermPtr& term); - virtual Collection docFreqs(Collection terms); - virtual int32_t maxDoc(); - virtual QueryPtr rewrite(const QueryPtr& query); - virtual void close(); - virtual DocumentPtr doc(int32_t n); - virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); - virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); - virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); - virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); - virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); - }; - - /// A subclass for searching a single searchable - class MultiSearcherCallableNoSort : public LuceneObject - { - public: - MultiSearcherCallableNoSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, const FilterPtr& filter, int32_t nDocs, - const HitQueuePtr& hq, int32_t i, Collection starts); - virtual ~MultiSearcherCallableNoSort(); - - LUCENE_CLASS(MultiSearcherCallableNoSort); - - protected: - SynchronizePtr lock; - SearchablePtr searchable; - WeightPtr weight; - FilterPtr filter; - int32_t nDocs; - int32_t i; - HitQueuePtr hq; - Collection starts; - - public: - TopDocsPtr call(); - }; - - /// A subclass for searching a single searchable - class MultiSearcherCallableWithSort : public LuceneObject - { - public: - MultiSearcherCallableWithSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, const FilterPtr& filter, - int32_t nDocs, const FieldDocSortedHitQueuePtr& hq, const SortPtr& sort, int32_t i, Collection starts); - virtual ~MultiSearcherCallableWithSort(); - - LUCENE_CLASS(MultiSearcherCallableWithSort); - - protected: - SynchronizePtr lock; - SearchablePtr searchable; - WeightPtr weight; - FilterPtr filter; - int32_t nDocs; - int32_t i; - FieldDocSortedHitQueuePtr hq; - Collection starts; - SortPtr sort; - - public: - TopFieldDocsPtr call(); - }; - - class MultiSearcherCollector : public Collector - { - public: - MultiSearcherCollector(const CollectorPtr& collector, int32_t start); - virtual ~MultiSearcherCollector(); - - LUCENE_CLASS(MultiSearcherCollector); - - protected: - CollectorPtr collector; - int32_t start; - - public: - virtual void setScorer(const ScorerPtr& scorer); - virtual void collect(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual bool acceptsDocsOutOfOrder(); - }; +namespace Lucene { + +/// Document Frequency cache acting as a Dummy-Searcher. This class is not a full-fledged Searcher, but +/// only supports the methods necessary to initialize Weights. +class CachedDfSource : public Searcher { +public: + CachedDfSource(MapTermInt dfMap, int32_t maxDoc, const SimilarityPtr& similarity); + virtual ~CachedDfSource(); + + LUCENE_CLASS(CachedDfSource); + +protected: + MapTermInt dfMap; // Map from Terms to corresponding doc freqs + int32_t _maxDoc; // document count + +public: + virtual int32_t docFreq(const TermPtr& term); + virtual Collection docFreqs(Collection terms); + virtual int32_t maxDoc(); + virtual QueryPtr rewrite(const QueryPtr& query); + virtual void close(); + virtual DocumentPtr doc(int32_t n); + virtual DocumentPtr doc(int32_t n, const FieldSelectorPtr& fieldSelector); + virtual ExplanationPtr explain(const WeightPtr& weight, int32_t doc); + virtual void search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results); + virtual TopDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n); + virtual TopFieldDocsPtr search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort); +}; + +/// A subclass for searching a single searchable +class MultiSearcherCallableNoSort : public LuceneObject { +public: + MultiSearcherCallableNoSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, const FilterPtr& filter, int32_t nDocs, + const HitQueuePtr& hq, int32_t i, Collection starts); + virtual ~MultiSearcherCallableNoSort(); + + LUCENE_CLASS(MultiSearcherCallableNoSort); + +protected: + SynchronizePtr lock; + SearchablePtr searchable; + WeightPtr weight; + FilterPtr filter; + int32_t nDocs; + int32_t i; + HitQueuePtr hq; + Collection starts; + +public: + TopDocsPtr call(); +}; + +/// A subclass for searching a single searchable +class MultiSearcherCallableWithSort : public LuceneObject { +public: + MultiSearcherCallableWithSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, const FilterPtr& filter, + int32_t nDocs, const FieldDocSortedHitQueuePtr& hq, const SortPtr& sort, int32_t i, Collection starts); + virtual ~MultiSearcherCallableWithSort(); + + LUCENE_CLASS(MultiSearcherCallableWithSort); + +protected: + SynchronizePtr lock; + SearchablePtr searchable; + WeightPtr weight; + FilterPtr filter; + int32_t nDocs; + int32_t i; + FieldDocSortedHitQueuePtr hq; + Collection starts; + SortPtr sort; + +public: + TopFieldDocsPtr call(); +}; + +class MultiSearcherCollector : public Collector { +public: + MultiSearcherCollector(const CollectorPtr& collector, int32_t start); + virtual ~MultiSearcherCollector(); + + LUCENE_CLASS(MultiSearcherCollector); + +protected: + CollectorPtr collector; + int32_t start; + +public: + virtual void setScorer(const ScorerPtr& scorer); + virtual void collect(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual bool acceptsDocsOutOfOrder(); +}; + } #endif diff --git a/src/core/include/_MultiTermQuery.h b/src/core/include/_MultiTermQuery.h index 0d3bcb91..27e8635d 100644 --- a/src/core/include/_MultiTermQuery.h +++ b/src/core/include/_MultiTermQuery.h @@ -9,48 +9,45 @@ #include "LuceneObject.h" -namespace Lucene -{ - class ConstantScoreFilterRewrite : public RewriteMethod - { - public: - virtual ~ConstantScoreFilterRewrite(); - LUCENE_CLASS(ConstantScoreFilterRewrite); - - public: - virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); - }; - - class ScoringBooleanQueryRewrite : public RewriteMethod - { - public: - virtual ~ScoringBooleanQueryRewrite(); - LUCENE_CLASS(ScoringBooleanQueryRewrite); - - public: - virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); - }; - - class ConstantScoreBooleanQueryRewrite : public ScoringBooleanQueryRewrite - { - public: - virtual ~ConstantScoreBooleanQueryRewrite(); - LUCENE_CLASS(ConstantScoreBooleanQueryRewrite); - - public: - virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); - }; - - class ConstantScoreAutoRewriteDefault : public ConstantScoreAutoRewrite - { - public: - virtual ~ConstantScoreAutoRewriteDefault(); - LUCENE_CLASS(ConstantScoreAutoRewriteDefault); - - public: - virtual void setTermCountCutoff(int32_t count); - virtual void setDocCountPercent(double percent); - }; +namespace Lucene { + +class ConstantScoreFilterRewrite : public RewriteMethod { +public: + virtual ~ConstantScoreFilterRewrite(); + LUCENE_CLASS(ConstantScoreFilterRewrite); + +public: + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); +}; + +class ScoringBooleanQueryRewrite : public RewriteMethod { +public: + virtual ~ScoringBooleanQueryRewrite(); + LUCENE_CLASS(ScoringBooleanQueryRewrite); + +public: + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); +}; + +class ConstantScoreBooleanQueryRewrite : public ScoringBooleanQueryRewrite { +public: + virtual ~ConstantScoreBooleanQueryRewrite(); + LUCENE_CLASS(ConstantScoreBooleanQueryRewrite); + +public: + virtual QueryPtr rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query); +}; + +class ConstantScoreAutoRewriteDefault : public ConstantScoreAutoRewrite { +public: + virtual ~ConstantScoreAutoRewriteDefault(); + LUCENE_CLASS(ConstantScoreAutoRewriteDefault); + +public: + virtual void setTermCountCutoff(int32_t count); + virtual void setDocCountPercent(double percent); +}; + } #endif diff --git a/src/core/include/_MultipleTermPositions.h b/src/core/include/_MultipleTermPositions.h index b99d9c03..b87536b3 100644 --- a/src/core/include/_MultipleTermPositions.h +++ b/src/core/include/_MultipleTermPositions.h @@ -9,50 +9,49 @@ #include "PriorityQueue.h" -namespace Lucene -{ - class TermPositionsQueue : public PriorityQueue - { - public: - TermPositionsQueue(Collection termPositions); - virtual ~TermPositionsQueue(); - - LUCENE_CLASS(TermPositionsQueue); - - protected: - Collection termPositions; - - public: - virtual void initialize(); - - protected: - virtual bool lessThan(const TermPositionsPtr& first, const TermPositionsPtr& second); - }; - - class IntQueue : public LuceneObject - { - public: - IntQueue(); - virtual ~IntQueue(); - - LUCENE_CLASS(IntQueue); - - protected: - int32_t arraySize; - int32_t index; - int32_t lastIndex; - Collection array; - - public: - void add(int32_t i); - int32_t next(); - void sort(); - void clear(); - int32_t size(); - - protected: - void growArray(); - }; +namespace Lucene { + +class TermPositionsQueue : public PriorityQueue { +public: + TermPositionsQueue(Collection termPositions); + virtual ~TermPositionsQueue(); + + LUCENE_CLASS(TermPositionsQueue); + +protected: + Collection termPositions; + +public: + virtual void initialize(); + +protected: + virtual bool lessThan(const TermPositionsPtr& first, const TermPositionsPtr& second); +}; + +class IntQueue : public LuceneObject { +public: + IntQueue(); + virtual ~IntQueue(); + + LUCENE_CLASS(IntQueue); + +protected: + int32_t arraySize; + int32_t index; + int32_t lastIndex; + Collection array; + +public: + void add(int32_t i); + int32_t next(); + void sort(); + void clear(); + int32_t size(); + +protected: + void growArray(); +}; + } #endif diff --git a/src/core/include/_NativeFSLockFactory.h b/src/core/include/_NativeFSLockFactory.h index c0f0904a..0a2ef999 100644 --- a/src/core/include/_NativeFSLockFactory.h +++ b/src/core/include/_NativeFSLockFactory.h @@ -9,33 +9,33 @@ #include "Lock.h" -namespace Lucene -{ - class NativeFSLock : public Lock - { - public: - NativeFSLock(const String& lockDir, const String& lockFileName); - virtual ~NativeFSLock(); - - LUCENE_CLASS(NativeFSLock); - - protected: - String lockDir; - String path; - filelockPtr lock; - - static SynchronizePtr LOCK_HELD_LOCK(); - static HashSet LOCK_HELD(); - - public: - virtual bool obtain(); - virtual void release(); - virtual bool isLocked(); - virtual String toString(); - - protected: - bool lockExists(); - }; +namespace Lucene { + +class NativeFSLock : public Lock { +public: + NativeFSLock(const String& lockDir, const String& lockFileName); + virtual ~NativeFSLock(); + + LUCENE_CLASS(NativeFSLock); + +protected: + String lockDir; + String path; + filelockPtr lock; + + static SynchronizePtr LOCK_HELD_LOCK(); + static HashSet LOCK_HELD(); + +public: + virtual bool obtain(); + virtual void release(); + virtual bool isLocked(); + virtual String toString(); + +protected: + bool lockExists(); +}; + } #endif diff --git a/src/core/include/_NearSpansUnordered.h b/src/core/include/_NearSpansUnordered.h index 932f8622..02ab5406 100644 --- a/src/core/include/_NearSpansUnordered.h +++ b/src/core/include/_NearSpansUnordered.h @@ -10,51 +10,50 @@ #include "Spans.h" #include "PriorityQueue.h" -namespace Lucene -{ - /// Wraps a Spans, and can be used to form a linked list. - class SpansCell : public Spans - { - public: - SpansCell(const NearSpansUnorderedPtr& unordered, const SpansPtr& spans, int32_t index); - virtual ~SpansCell(); - - LUCENE_CLASS(SpansCell); - - protected: - NearSpansUnorderedWeakPtr _unordered; - SpansPtr spans; - SpansCellPtr _next; - int32_t length; - int32_t index; - - public: - virtual bool next(); - virtual bool skipTo(int32_t target); - virtual int32_t doc(); - virtual int32_t start(); - virtual int32_t end(); - virtual Collection getPayload(); - virtual bool isPayloadAvailable(); - virtual String toString(); - - protected: - bool adjust(bool condition); - - friend class NearSpansUnordered; - }; - - class CellQueue : public PriorityQueue - { - public: - CellQueue(int32_t size); - virtual ~CellQueue(); - - LUCENE_CLASS(CellQueue); - - protected: - virtual bool lessThan(const SpansCellPtr& first, const SpansCellPtr& second); - }; +namespace Lucene { + +/// Wraps a Spans, and can be used to form a linked list. +class SpansCell : public Spans { +public: + SpansCell(const NearSpansUnorderedPtr& unordered, const SpansPtr& spans, int32_t index); + virtual ~SpansCell(); + + LUCENE_CLASS(SpansCell); + +protected: + NearSpansUnorderedWeakPtr _unordered; + SpansPtr spans; + SpansCellPtr _next; + int32_t length; + int32_t index; + +public: + virtual bool next(); + virtual bool skipTo(int32_t target); + virtual int32_t doc(); + virtual int32_t start(); + virtual int32_t end(); + virtual Collection getPayload(); + virtual bool isPayloadAvailable(); + virtual String toString(); + +protected: + bool adjust(bool condition); + + friend class NearSpansUnordered; +}; + +class CellQueue : public PriorityQueue { +public: + CellQueue(int32_t size); + virtual ~CellQueue(); + + LUCENE_CLASS(CellQueue); + +protected: + virtual bool lessThan(const SpansCellPtr& first, const SpansCellPtr& second); +}; + } #endif diff --git a/src/core/include/_NoLockFactory.h b/src/core/include/_NoLockFactory.h index b766af6e..cc80befc 100644 --- a/src/core/include/_NoLockFactory.h +++ b/src/core/include/_NoLockFactory.h @@ -9,21 +9,21 @@ #include "Lock.h" -namespace Lucene -{ - class NoLock : public Lock - { - public: - virtual ~NoLock(); - - LUCENE_CLASS(NoLock); - - public: - virtual bool obtain(); - virtual void release(); - virtual bool isLocked(); - virtual String toString(); - }; +namespace Lucene { + +class NoLock : public Lock { +public: + virtual ~NoLock(); + + LUCENE_CLASS(NoLock); + +public: + virtual bool obtain(); + virtual void release(); + virtual bool isLocked(); + virtual String toString(); +}; + } #endif diff --git a/src/core/include/_NumericRangeQuery.h b/src/core/include/_NumericRangeQuery.h index bc2e2c62..375f0f6e 100644 --- a/src/core/include/_NumericRangeQuery.h +++ b/src/core/include/_NumericRangeQuery.h @@ -10,79 +10,77 @@ #include "FilteredTermEnum.h" #include "NumericUtils.h" -namespace Lucene -{ - /// Subclass of FilteredTermEnum for enumerating all terms that match the sub-ranges for trie range queries. - /// - /// Warning: This term enumeration is not guaranteed to be always ordered by {@link Term#compareTo}. The - /// ordering depends on how {@link NumericUtils#splitLongRange} and {@link NumericUtils#splitIntRange} - /// generates the sub-ranges. For {@link MultiTermQuery} ordering is not relevant. - class NumericRangeTermEnum : public FilteredTermEnum - { - public: - NumericRangeTermEnum(const NumericRangeQueryPtr& query, const IndexReaderPtr& reader); - virtual ~NumericRangeTermEnum(); - - LUCENE_CLASS(NumericRangeTermEnum); - - protected: - NumericRangeQueryWeakPtr _query; - IndexReaderPtr reader; - Collection rangeBounds; - TermPtr termTemplate; - String currentUpperBound; - - public: - virtual double difference(); - - /// Increments the enumeration to the next element. True if one exists. - virtual bool next(); - - /// Closes the enumeration to further activity, freeing resources. - virtual void close(); - - protected: - /// This is a dummy, it is not used by this class. - virtual bool endEnum(); - - /// This is a dummy, it is not used by this class. - virtual void setEnum(const TermEnumPtr& actualEnum); - - /// Compares if current upper bound is reached, this also updates the term count for statistics. - /// In contrast to {@link FilteredTermEnum}, a return value of false ends iterating the current enum - /// and forwards to the next sub-range. - virtual bool termCompare(const TermPtr& term); - }; - - class NumericLongRangeBuilder : public LongRangeBuilder - { - public: - NumericLongRangeBuilder(Collection rangeBounds); - virtual ~NumericLongRangeBuilder(); - - LUCENE_CLASS(NumericLongRangeBuilder); - - protected: - Collection rangeBounds; - - public: - virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); - }; - - class NumericIntRangeBuilder : public IntRangeBuilder - { - public: - NumericIntRangeBuilder(Collection rangeBounds); - virtual ~NumericIntRangeBuilder(); - - LUCENE_CLASS(NumericIntRangeBuilder); - - protected: - Collection rangeBounds; - - public: - virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); - }; +namespace Lucene { + +/// Subclass of FilteredTermEnum for enumerating all terms that match the sub-ranges for trie range queries. +/// +/// Warning: This term enumeration is not guaranteed to be always ordered by {@link Term#compareTo}. The +/// ordering depends on how {@link NumericUtils#splitLongRange} and {@link NumericUtils#splitIntRange} +/// generates the sub-ranges. For {@link MultiTermQuery} ordering is not relevant. +class NumericRangeTermEnum : public FilteredTermEnum { +public: + NumericRangeTermEnum(const NumericRangeQueryPtr& query, const IndexReaderPtr& reader); + virtual ~NumericRangeTermEnum(); + + LUCENE_CLASS(NumericRangeTermEnum); + +protected: + NumericRangeQueryWeakPtr _query; + IndexReaderPtr reader; + Collection rangeBounds; + TermPtr termTemplate; + String currentUpperBound; + +public: + virtual double difference(); + + /// Increments the enumeration to the next element. True if one exists. + virtual bool next(); + + /// Closes the enumeration to further activity, freeing resources. + virtual void close(); + +protected: + /// This is a dummy, it is not used by this class. + virtual bool endEnum(); + + /// This is a dummy, it is not used by this class. + virtual void setEnum(const TermEnumPtr& actualEnum); + + /// Compares if current upper bound is reached, this also updates the term count for statistics. + /// In contrast to {@link FilteredTermEnum}, a return value of false ends iterating the current enum + /// and forwards to the next sub-range. + virtual bool termCompare(const TermPtr& term); +}; + +class NumericLongRangeBuilder : public LongRangeBuilder { +public: + NumericLongRangeBuilder(Collection rangeBounds); + virtual ~NumericLongRangeBuilder(); + + LUCENE_CLASS(NumericLongRangeBuilder); + +protected: + Collection rangeBounds; + +public: + virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); +}; + +class NumericIntRangeBuilder : public IntRangeBuilder { +public: + NumericIntRangeBuilder(Collection rangeBounds); + virtual ~NumericIntRangeBuilder(); + + LUCENE_CLASS(NumericIntRangeBuilder); + +protected: + Collection rangeBounds; + +public: + virtual void addRange(const String& minPrefixCoded, const String& maxPrefixCoded); +}; + } #endif diff --git a/src/core/include/_OrdFieldSource.h b/src/core/include/_OrdFieldSource.h index 77fb6f4b..df0687ff 100644 --- a/src/core/include/_OrdFieldSource.h +++ b/src/core/include/_OrdFieldSource.h @@ -9,26 +9,26 @@ #include "DocValues.h" -namespace Lucene -{ - class LPPAPI OrdDocValues : public DocValues - { - public: - OrdDocValues(const OrdFieldSourcePtr& source, Collection arr); - virtual ~OrdDocValues(); - - LUCENE_CLASS(OrdDocValues); - - protected: - OrdFieldSourceWeakPtr _source; - Collection arr; - - public: - virtual double doubleVal(int32_t doc); - virtual String strVal(int32_t doc); - virtual String toString(int32_t doc); - virtual CollectionValue getInnerArray(); - }; +namespace Lucene { + +class LPPAPI OrdDocValues : public DocValues { +public: + OrdDocValues(const OrdFieldSourcePtr& source, Collection arr); + virtual ~OrdDocValues(); + + LUCENE_CLASS(OrdDocValues); + +protected: + OrdFieldSourceWeakPtr _source; + Collection arr; + +public: + virtual double doubleVal(int32_t doc); + virtual String strVal(int32_t doc); + virtual String toString(int32_t doc); + virtual CollectionValue getInnerArray(); +}; + } #endif diff --git a/src/core/include/_ParallelReader.h b/src/core/include/_ParallelReader.h index 8263d57b..d308c4fa 100644 --- a/src/core/include/_ParallelReader.h +++ b/src/core/include/_ParallelReader.h @@ -11,79 +11,77 @@ #include "TermDocs.h" #include "TermPositions.h" -namespace Lucene -{ - class ParallelTermEnum : public TermEnum - { - public: - ParallelTermEnum(const ParallelReaderPtr& reader); - ParallelTermEnum(const ParallelReaderPtr& reader, const TermPtr& term); - virtual ~ParallelTermEnum(); - - LUCENE_CLASS(ParallelTermEnum); - - protected: - ParallelReaderWeakPtr _reader; - String field; - MapStringIndexReader::iterator fieldIterator; - bool setIterator; - TermEnumPtr termEnum; - - public: - /// Increments the enumeration to the next element. True if one exists. - virtual bool next(); - - /// Returns the current Term in the enumeration. - virtual TermPtr term(); - - /// Returns the docFreq of the current Term in the enumeration. - virtual int32_t docFreq(); - - /// Closes the enumeration to further activity, freeing resources. - virtual void close(); - }; - - /// Wrap a TermDocs in order to support seek(Term) - class ParallelTermDocs : public TermPositions, public LuceneObject - { - public: - ParallelTermDocs(const ParallelReaderPtr& reader); - ParallelTermDocs(const ParallelReaderPtr& reader, const TermPtr& term); - virtual ~ParallelTermDocs(); - - LUCENE_CLASS(ParallelTermDocs); - - protected: - ParallelReaderWeakPtr _reader; - TermDocsPtr termDocs; - - public: - virtual int32_t doc(); - virtual int32_t freq(); - virtual void seek(const TermPtr& term); - virtual void seek(const TermEnumPtr& termEnum); - virtual bool next(); - virtual int32_t read(Collection docs, Collection freqs); - virtual bool skipTo(int32_t target); - virtual void close(); - }; - - class ParallelTermPositions : public ParallelTermDocs - { - public: - ParallelTermPositions(const ParallelReaderPtr& reader); - ParallelTermPositions(const ParallelReaderPtr& reader, const TermPtr& term); - virtual ~ParallelTermPositions(); - - LUCENE_CLASS(ParallelTermPositions); - - public: - virtual void seek(const TermPtr& term); - virtual int32_t nextPosition(); - virtual int32_t getPayloadLength(); - virtual ByteArray getPayload(ByteArray data, int32_t offset); - virtual bool isPayloadAvailable(); - }; +namespace Lucene { + +class ParallelTermEnum : public TermEnum { +public: + ParallelTermEnum(const ParallelReaderPtr& reader); + ParallelTermEnum(const ParallelReaderPtr& reader, const TermPtr& term); + virtual ~ParallelTermEnum(); + + LUCENE_CLASS(ParallelTermEnum); + +protected: + ParallelReaderWeakPtr _reader; + String field; + MapStringIndexReader::iterator fieldIterator; + bool setIterator; + TermEnumPtr termEnum; + +public: + /// Increments the enumeration to the next element. True if one exists. + virtual bool next(); + + /// Returns the current Term in the enumeration. + virtual TermPtr term(); + + /// Returns the docFreq of the current Term in the enumeration. + virtual int32_t docFreq(); + + /// Closes the enumeration to further activity, freeing resources. + virtual void close(); +}; + +/// Wrap a TermDocs in order to support seek(Term) +class ParallelTermDocs : public TermPositions, public LuceneObject { +public: + ParallelTermDocs(const ParallelReaderPtr& reader); + ParallelTermDocs(const ParallelReaderPtr& reader, const TermPtr& term); + virtual ~ParallelTermDocs(); + + LUCENE_CLASS(ParallelTermDocs); + +protected: + ParallelReaderWeakPtr _reader; + TermDocsPtr termDocs; + +public: + virtual int32_t doc(); + virtual int32_t freq(); + virtual void seek(const TermPtr& term); + virtual void seek(const TermEnumPtr& termEnum); + virtual bool next(); + virtual int32_t read(Collection docs, Collection freqs); + virtual bool skipTo(int32_t target); + virtual void close(); +}; + +class ParallelTermPositions : public ParallelTermDocs { +public: + ParallelTermPositions(const ParallelReaderPtr& reader); + ParallelTermPositions(const ParallelReaderPtr& reader, const TermPtr& term); + virtual ~ParallelTermPositions(); + + LUCENE_CLASS(ParallelTermPositions); + +public: + virtual void seek(const TermPtr& term); + virtual int32_t nextPosition(); + virtual int32_t getPayloadLength(); + virtual ByteArray getPayload(ByteArray data, int32_t offset); + virtual bool isPayloadAvailable(); +}; + } #endif diff --git a/src/core/include/_PayloadTermQuery.h b/src/core/include/_PayloadTermQuery.h index d441c58c..d82a7d0d 100644 --- a/src/core/include/_PayloadTermQuery.h +++ b/src/core/include/_PayloadTermQuery.h @@ -10,58 +10,57 @@ #include "SpanWeight.h" #include "SpanScorer.h" -namespace Lucene -{ - class PayloadTermWeight : public SpanWeight - { - public: - PayloadTermWeight(const PayloadTermQueryPtr& query, const SearcherPtr& searcher); - virtual ~PayloadTermWeight(); - - LUCENE_CLASS(PayloadTermWeight); - - public: - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - }; - - class PayloadTermSpanScorer : public SpanScorer - { - public: - PayloadTermSpanScorer(const TermSpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); - virtual ~PayloadTermSpanScorer(); - - LUCENE_CLASS(PayloadTermSpanScorer); - - protected: - ByteArray payload; - TermPositionsPtr positions; - double payloadScore; - int32_t payloadsSeen; - - public: - virtual double score(); - - protected: - virtual bool setFreqCurrentDoc(); - - void processPayload(const SimilarityPtr& similarity); - - /// Returns the SpanScorer score only. - /// - /// Should not be overridden without good cause - /// - /// @return the score for just the Span part without the payload - /// @see #score() - virtual double getSpanScore(); - - /// The score for the payload - /// - /// @return The score, as calculated by {@link PayloadFunction#docScore(int32_t, const String&, - /// int32_t, double)} - virtual double getPayloadScore(); - - virtual ExplanationPtr explain(int32_t doc); - }; +namespace Lucene { + +class PayloadTermWeight : public SpanWeight { +public: + PayloadTermWeight(const PayloadTermQueryPtr& query, const SearcherPtr& searcher); + virtual ~PayloadTermWeight(); + + LUCENE_CLASS(PayloadTermWeight); + +public: + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); +}; + +class PayloadTermSpanScorer : public SpanScorer { +public: + PayloadTermSpanScorer(const TermSpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms); + virtual ~PayloadTermSpanScorer(); + + LUCENE_CLASS(PayloadTermSpanScorer); + +protected: + ByteArray payload; + TermPositionsPtr positions; + double payloadScore; + int32_t payloadsSeen; + +public: + virtual double score(); + +protected: + virtual bool setFreqCurrentDoc(); + + void processPayload(const SimilarityPtr& similarity); + + /// Returns the SpanScorer score only. + /// + /// Should not be overridden without good cause + /// + /// @return the score for just the Span part without the payload + /// @see #score() + virtual double getSpanScore(); + + /// The score for the payload + /// + /// @return The score, as calculated by {@link PayloadFunction#docScore(int32_t, const String&, + /// int32_t, double)} + virtual double getPayloadScore(); + + virtual ExplanationPtr explain(int32_t doc); +}; + } #endif diff --git a/src/core/include/_PhraseQuery.h b/src/core/include/_PhraseQuery.h index a4b654c8..c82bf289 100644 --- a/src/core/include/_PhraseQuery.h +++ b/src/core/include/_PhraseQuery.h @@ -9,34 +9,34 @@ #include "Weight.h" -namespace Lucene -{ - class PhraseWeight : public Weight - { - public: - PhraseWeight(const PhraseQueryPtr& query, const SearcherPtr& searcher); - virtual ~PhraseWeight(); - - LUCENE_CLASS(PhraseWeight); - - protected: - PhraseQueryPtr query; - SimilarityPtr similarity; - double value; - double idf; - double queryNorm; - double queryWeight; - IDFExplanationPtr idfExp; - - public: - virtual String toString(); - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - }; +namespace Lucene { + +class PhraseWeight : public Weight { +public: + PhraseWeight(const PhraseQueryPtr& query, const SearcherPtr& searcher); + virtual ~PhraseWeight(); + + LUCENE_CLASS(PhraseWeight); + +protected: + PhraseQueryPtr query; + SimilarityPtr similarity; + double value; + double idf; + double queryNorm; + double queryWeight; + IDFExplanationPtr idfExp; + +public: + virtual String toString(); + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); +}; + } #endif diff --git a/src/core/include/_QueryWrapperFilter.h b/src/core/include/_QueryWrapperFilter.h index 87d104fe..658a3d1b 100644 --- a/src/core/include/_QueryWrapperFilter.h +++ b/src/core/include/_QueryWrapperFilter.h @@ -9,24 +9,24 @@ #include "DocIdSet.h" -namespace Lucene -{ - class QueryWrapperFilterDocIdSet : public DocIdSet - { - public: - QueryWrapperFilterDocIdSet(const IndexReaderPtr& reader, const WeightPtr& weight); - virtual ~QueryWrapperFilterDocIdSet(); - - LUCENE_CLASS(QueryWrapperFilterDocIdSet); - - protected: - IndexReaderPtr reader; - WeightPtr weight; - - public: - virtual DocIdSetIteratorPtr iterator(); - virtual bool isCacheable(); - }; +namespace Lucene { + +class QueryWrapperFilterDocIdSet : public DocIdSet { +public: + QueryWrapperFilterDocIdSet(const IndexReaderPtr& reader, const WeightPtr& weight); + virtual ~QueryWrapperFilterDocIdSet(); + + LUCENE_CLASS(QueryWrapperFilterDocIdSet); + +protected: + IndexReaderPtr reader; + WeightPtr weight; + +public: + virtual DocIdSetIteratorPtr iterator(); + virtual bool isCacheable(); +}; + } #endif diff --git a/src/core/include/_ReverseOrdFieldSource.h b/src/core/include/_ReverseOrdFieldSource.h index 24573066..18c8e28f 100644 --- a/src/core/include/_ReverseOrdFieldSource.h +++ b/src/core/include/_ReverseOrdFieldSource.h @@ -9,28 +9,28 @@ #include "DocValues.h" -namespace Lucene -{ - class ReverseOrdDocValues : public DocValues - { - public: - ReverseOrdDocValues(const ReverseOrdFieldSourcePtr& source, Collection arr, int32_t end); - virtual ~ReverseOrdDocValues(); - - LUCENE_CLASS(ReverseOrdDocValues); - - protected: - ReverseOrdFieldSourceWeakPtr _source; - Collection arr; - int32_t end; - - public: - virtual double doubleVal(int32_t doc); - virtual int32_t intVal(int32_t doc); - virtual String strVal(int32_t doc); - virtual String toString(int32_t doc); - virtual CollectionValue getInnerArray(); - }; +namespace Lucene { + +class ReverseOrdDocValues : public DocValues { +public: + ReverseOrdDocValues(const ReverseOrdFieldSourcePtr& source, Collection arr, int32_t end); + virtual ~ReverseOrdDocValues(); + + LUCENE_CLASS(ReverseOrdDocValues); + +protected: + ReverseOrdFieldSourceWeakPtr _source; + Collection arr; + int32_t end; + +public: + virtual double doubleVal(int32_t doc); + virtual int32_t intVal(int32_t doc); + virtual String strVal(int32_t doc); + virtual String toString(int32_t doc); + virtual CollectionValue getInnerArray(); +}; + } #endif diff --git a/src/core/include/_ScorerDocQueue.h b/src/core/include/_ScorerDocQueue.h index 04663372..e994af3c 100644 --- a/src/core/include/_ScorerDocQueue.h +++ b/src/core/include/_ScorerDocQueue.h @@ -9,24 +9,24 @@ #include "LuceneObject.h" -namespace Lucene -{ - class HeapedScorerDoc : public LuceneObject - { - public: - HeapedScorerDoc(const ScorerPtr& scorer); - HeapedScorerDoc(const ScorerPtr& scorer, int32_t doc); - virtual ~HeapedScorerDoc(); - - LUCENE_CLASS(HeapedScorerDoc); - - public: - ScorerPtr scorer; - int32_t doc; - - public: - void adjust(); - }; +namespace Lucene { + +class HeapedScorerDoc : public LuceneObject { +public: + HeapedScorerDoc(const ScorerPtr& scorer); + HeapedScorerDoc(const ScorerPtr& scorer, int32_t doc); + virtual ~HeapedScorerDoc(); + + LUCENE_CLASS(HeapedScorerDoc); + +public: + ScorerPtr scorer; + int32_t doc; + +public: + void adjust(); +}; + } #endif diff --git a/src/core/include/_SegmentInfos.h b/src/core/include/_SegmentInfos.h index 12c78592..ec714ebf 100644 --- a/src/core/include/_SegmentInfos.h +++ b/src/core/include/_SegmentInfos.h @@ -9,65 +9,61 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Utility class for executing code that needs to do something with the current segments file. - class FindSegmentsFile : public LuceneObject - { - public: - FindSegmentsFile(const SegmentInfosPtr& infos, const DirectoryPtr& directory); - virtual ~FindSegmentsFile(); - - LUCENE_CLASS(FindSegmentsFile); - - protected: - SegmentInfosWeakPtr _segmentInfos; - DirectoryPtr directory; - - public: - void doRun(const IndexCommitPtr& commit = IndexCommitPtr()); - virtual void runBody(const String& segmentFileName) = 0; - }; - - template - class FindSegmentsFileT : public FindSegmentsFile - { - public: - FindSegmentsFileT(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFile(infos, directory) {} - virtual ~FindSegmentsFileT() {} - - protected: - TYPE result; - - public: - virtual TYPE run(const IndexCommitPtr& commit = IndexCommitPtr()) - { - doRun(commit); - return result; - } - - virtual void runBody(const String& segmentFileName) - { - result = doBody(segmentFileName); - } - - virtual TYPE doBody(const String& segmentFileName) = 0; - }; - - /// Utility class for executing code that needs to do something with the current segments file. This is necessary with - /// lock-less commits because from the time you locate the current segments file name, until you actually open it, read - /// its contents, or check modified time, etc., it could have been deleted due to a writer commit finishing. - class FindSegmentsRead : public FindSegmentsFileT - { - public: - FindSegmentsRead(const SegmentInfosPtr& infos, const DirectoryPtr& directory); - virtual ~FindSegmentsRead(); - - LUCENE_CLASS(FindSegmentsRead); - - public: - virtual int64_t doBody(const String& segmentFileName); - }; +namespace Lucene { + +/// Utility class for executing code that needs to do something with the current segments file. +class FindSegmentsFile : public LuceneObject { +public: + FindSegmentsFile(const SegmentInfosPtr& infos, const DirectoryPtr& directory); + virtual ~FindSegmentsFile(); + + LUCENE_CLASS(FindSegmentsFile); + +protected: + SegmentInfosWeakPtr _segmentInfos; + DirectoryPtr directory; + +public: + void doRun(const IndexCommitPtr& commit = IndexCommitPtr()); + virtual void runBody(const String& segmentFileName) = 0; +}; + +template +class FindSegmentsFileT : public FindSegmentsFile { +public: + FindSegmentsFileT(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFile(infos, directory) {} + virtual ~FindSegmentsFileT() {} + +protected: + TYPE result; + +public: + virtual TYPE run(const IndexCommitPtr& commit = IndexCommitPtr()) { + doRun(commit); + return result; + } + + virtual void runBody(const String& segmentFileName) { + result = doBody(segmentFileName); + } + + virtual TYPE doBody(const String& segmentFileName) = 0; +}; + +/// Utility class for executing code that needs to do something with the current segments file. This is necessary with +/// lock-less commits because from the time you locate the current segments file name, until you actually open it, read +/// its contents, or check modified time, etc., it could have been deleted due to a writer commit finishing. +class FindSegmentsRead : public FindSegmentsFileT { +public: + FindSegmentsRead(const SegmentInfosPtr& infos, const DirectoryPtr& directory); + virtual ~FindSegmentsRead(); + + LUCENE_CLASS(FindSegmentsRead); + +public: + virtual int64_t doBody(const String& segmentFileName); +}; + } #endif diff --git a/src/core/include/_SegmentReader.h b/src/core/include/_SegmentReader.h index fefca9fd..e04c2fcb 100644 --- a/src/core/include/_SegmentReader.h +++ b/src/core/include/_SegmentReader.h @@ -9,154 +9,151 @@ #include "CloseableThreadLocal.h" -namespace Lucene -{ - /// Holds core readers that are shared (unchanged) when SegmentReader is cloned or reopened - class CoreReaders : public LuceneObject - { - public: - CoreReaders(const SegmentReaderPtr& origInstance, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, int32_t termsIndexDivisor); - virtual ~CoreReaders(); - - LUCENE_CLASS(CoreReaders); - - protected: - /// Counts how many other reader share the core objects (freqStream, proxStream, tis, etc.) of this reader; - /// when coreRef drops to 0, these core objects may be closed. A given instance of SegmentReader may be - /// closed, even those it shares core objects with other SegmentReaders - SegmentReaderRefPtr ref; - - SegmentReaderWeakPtr _origInstance; - - public: - String segment; - FieldInfosPtr fieldInfos; - IndexInputPtr freqStream; - IndexInputPtr proxStream; - TermInfosReaderPtr tisNoIndex; - - DirectoryPtr dir; - DirectoryPtr cfsDir; - int32_t readBufferSize; - int32_t termsIndexDivisor; - - TermInfosReaderPtr tis; - FieldsReaderPtr fieldsReaderOrig; - TermVectorsReaderPtr termVectorsReaderOrig; - CompoundFileReaderPtr cfsReader; - CompoundFileReaderPtr storeCFSReader; - - public: - TermVectorsReaderPtr getTermVectorsReaderOrig(); - FieldsReaderPtr getFieldsReaderOrig(); - void incRef(); - DirectoryPtr getCFSReader(); - TermInfosReaderPtr getTermsReader(); - bool termsIndexIsLoaded(); - - /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, - /// sharing a segment that's still being merged. This method is not fully thread safe, and relies on the - /// synchronization in IndexWriter - void loadTermsIndex(const SegmentInfoPtr& si, int32_t termsIndexDivisor); - - void openDocStores(const SegmentInfoPtr& si); - - void decRef(); - - friend class SegmentReader; - }; - - /// Sets the initial value - class FieldsReaderLocal : public CloseableThreadLocal - { - public: - FieldsReaderLocal(const SegmentReaderPtr& reader); - - protected: - SegmentReaderWeakPtr _reader; - - protected: - virtual FieldsReaderPtr initialValue(); - }; - - class SegmentReaderRef : public LuceneObject - { - public: - SegmentReaderRef(); - virtual ~SegmentReaderRef(); - - LUCENE_CLASS(SegmentReaderRef); - - protected: - int32_t _refCount; - - public: - virtual String toString(); - int32_t refCount(); - int32_t incRef(); - int32_t decRef(); - - friend class SegmentReader; - }; - - /// Byte[] referencing is used because a new norm object needs to be created for each clone, and the byte - /// array is all that is needed for sharing between cloned readers. The current norm referencing is for - /// sharing between readers whereas the byte[] referencing is for copy on write which is independent of - /// reader references (i.e. incRef, decRef). - class Norm : public LuceneObject - { - public: - Norm(); - Norm(const SegmentReaderPtr& reader, const IndexInputPtr& in, int32_t number, int64_t normSeek); - virtual ~Norm(); - - LUCENE_CLASS(Norm); - - protected: - SegmentReaderWeakPtr _reader; - int32_t refCount; - - /// If this instance is a clone, the originalNorm references the Norm that has a real open IndexInput - NormPtr origNorm; - SegmentReaderPtr origReader; - - IndexInputPtr in; - int64_t normSeek; - - SegmentReaderRefPtr _bytesRef; - ByteArray _bytes; - bool dirty; - int32_t number; - bool rollbackDirty; - - public: - void incRef(); - void decRef(); - - /// Load bytes but do not cache them if they were not already cached - void bytes(uint8_t* bytesOut, int32_t offset, int32_t length); - - /// Load & cache full bytes array. Returns bytes. - ByteArray bytes(); +namespace Lucene { + +/// Holds core readers that are shared (unchanged) when SegmentReader is cloned or reopened +class CoreReaders : public LuceneObject { +public: + CoreReaders(const SegmentReaderPtr& origInstance, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, int32_t termsIndexDivisor); + virtual ~CoreReaders(); + + LUCENE_CLASS(CoreReaders); + +protected: + /// Counts how many other reader share the core objects (freqStream, proxStream, tis, etc.) of this reader; + /// when coreRef drops to 0, these core objects may be closed. A given instance of SegmentReader may be + /// closed, even those it shares core objects with other SegmentReaders + SegmentReaderRefPtr ref; + + SegmentReaderWeakPtr _origInstance; + +public: + String segment; + FieldInfosPtr fieldInfos; + IndexInputPtr freqStream; + IndexInputPtr proxStream; + TermInfosReaderPtr tisNoIndex; + + DirectoryPtr dir; + DirectoryPtr cfsDir; + int32_t readBufferSize; + int32_t termsIndexDivisor; + + TermInfosReaderPtr tis; + FieldsReaderPtr fieldsReaderOrig; + TermVectorsReaderPtr termVectorsReaderOrig; + CompoundFileReaderPtr cfsReader; + CompoundFileReaderPtr storeCFSReader; + +public: + TermVectorsReaderPtr getTermVectorsReaderOrig(); + FieldsReaderPtr getFieldsReaderOrig(); + void incRef(); + DirectoryPtr getCFSReader(); + TermInfosReaderPtr getTermsReader(); + bool termsIndexIsLoaded(); + + /// NOTE: only called from IndexWriter when a near real-time reader is opened, or applyDeletes is run, + /// sharing a segment that's still being merged. This method is not fully thread safe, and relies on the + /// synchronization in IndexWriter + void loadTermsIndex(const SegmentInfoPtr& si, int32_t termsIndexDivisor); - /// Only for testing - SegmentReaderRefPtr bytesRef(); - - /// Called if we intend to change a norm value. We make a private copy of bytes if it's shared - // with others - ByteArray copyOnWrite(); + void openDocStores(const SegmentInfoPtr& si); - /// Returns a copy of this Norm instance that shares IndexInput & bytes with the original one - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + void decRef(); - /// Flush all pending changes to the next generation separate norms file. - void reWrite(const SegmentInfoPtr& si); + friend class SegmentReader; +}; - protected: - void closeInput(); +/// Sets the initial value +class FieldsReaderLocal : public CloseableThreadLocal { +public: + FieldsReaderLocal(const SegmentReaderPtr& reader); + +protected: + SegmentReaderWeakPtr _reader; + +protected: + virtual FieldsReaderPtr initialValue(); +}; + +class SegmentReaderRef : public LuceneObject { +public: + SegmentReaderRef(); + virtual ~SegmentReaderRef(); + + LUCENE_CLASS(SegmentReaderRef); + +protected: + int32_t _refCount; + +public: + virtual String toString(); + int32_t refCount(); + int32_t incRef(); + int32_t decRef(); + + friend class SegmentReader; +}; + +/// Byte[] referencing is used because a new norm object needs to be created for each clone, and the byte +/// array is all that is needed for sharing between cloned readers. The current norm referencing is for +/// sharing between readers whereas the byte[] referencing is for copy on write which is independent of +/// reader references (i.e. incRef, decRef). +class Norm : public LuceneObject { +public: + Norm(); + Norm(const SegmentReaderPtr& reader, const IndexInputPtr& in, int32_t number, int64_t normSeek); + virtual ~Norm(); + + LUCENE_CLASS(Norm); + +protected: + SegmentReaderWeakPtr _reader; + int32_t refCount; + + /// If this instance is a clone, the originalNorm references the Norm that has a real open IndexInput + NormPtr origNorm; + SegmentReaderPtr origReader; + + IndexInputPtr in; + int64_t normSeek; + + SegmentReaderRefPtr _bytesRef; + ByteArray _bytes; + bool dirty; + int32_t number; + bool rollbackDirty; + +public: + void incRef(); + void decRef(); + + /// Load bytes but do not cache them if they were not already cached + void bytes(uint8_t* bytesOut, int32_t offset, int32_t length); + + /// Load & cache full bytes array. Returns bytes. + ByteArray bytes(); + + /// Only for testing + SegmentReaderRefPtr bytesRef(); + + /// Called if we intend to change a norm value. We make a private copy of bytes if it's shared + // with others + ByteArray copyOnWrite(); + + /// Returns a copy of this Norm instance that shares IndexInput & bytes with the original one + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); + + /// Flush all pending changes to the next generation separate norms file. + void reWrite(const SegmentInfoPtr& si); + +protected: + void closeInput(); + + friend class SegmentReader; +}; - friend class SegmentReader; - }; } #endif diff --git a/src/core/include/_Similarity.h b/src/core/include/_Similarity.h index 95b43315..a3d189bd 100644 --- a/src/core/include/_Similarity.h +++ b/src/core/include/_Similarity.h @@ -9,28 +9,28 @@ #include "Explanation.h" -namespace Lucene -{ - class SimilarityIDFExplanation : public IDFExplanation - { - public: - SimilarityIDFExplanation(int32_t df, int32_t max, double idf); - SimilarityIDFExplanation(const String& exp, double idf); - - virtual ~SimilarityIDFExplanation(); - - LUCENE_CLASS(SimilarityIDFExplanation); - - protected: - String exp; - int32_t df; - int32_t max; - double idf; - - public: - virtual String explain(); - virtual double getIdf(); - }; +namespace Lucene { + +class SimilarityIDFExplanation : public IDFExplanation { +public: + SimilarityIDFExplanation(int32_t df, int32_t max, double idf); + SimilarityIDFExplanation(const String& exp, double idf); + + virtual ~SimilarityIDFExplanation(); + + LUCENE_CLASS(SimilarityIDFExplanation); + +protected: + String exp; + int32_t df; + int32_t max; + double idf; + +public: + virtual String explain(); + virtual double getIdf(); +}; + } #endif diff --git a/src/core/include/_SimpleFSDirectory.h b/src/core/include/_SimpleFSDirectory.h index 6fbf31a5..379f3aaa 100644 --- a/src/core/include/_SimpleFSDirectory.h +++ b/src/core/include/_SimpleFSDirectory.h @@ -10,105 +10,102 @@ #include "BufferedIndexInput.h" #include "BufferedIndexOutput.h" -namespace Lucene -{ - class InputFile : public LuceneObject - { - public: - InputFile(const String& path); - virtual ~InputFile(); - - LUCENE_CLASS(InputFile); - - public: - static const int32_t FILE_EOF; - static const int32_t FILE_ERROR; - - protected: - ifstreamPtr file; - int64_t position; - int64_t length; - - public: - void setPosition(int64_t position); - int64_t getPosition(); - int64_t getLength(); - int32_t read(uint8_t* b, int32_t offset, int32_t length); - void close(); - bool isValid(); - }; - - class SimpleFSIndexInput : public BufferedIndexInput - { - public: - SimpleFSIndexInput(); - SimpleFSIndexInput(const String& path, int32_t bufferSize, int32_t chunkSize); - virtual ~SimpleFSIndexInput(); - - LUCENE_CLASS(SimpleFSIndexInput); - - protected: - String path; - InputFilePtr file; - bool isClone; - int32_t chunkSize; - - protected: - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); - virtual void seekInternal(int64_t pos); - - public: - virtual int64_t length(); - virtual void close(); - - /// Method used for testing. - bool isValid(); - - /// Returns a clone of this stream. - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; - - class OutputFile : public LuceneObject - { - public: - OutputFile(const String& path); - virtual ~OutputFile(); - - LUCENE_CLASS(OutputFile); - - protected: - ofstreamPtr file; - String path; - - public: - bool write(const uint8_t* b, int32_t offset, int32_t length); - void close(); - void setPosition(int64_t position); - int64_t getLength(); - void setLength(int64_t length); - void flush(); - bool isValid(); - }; - - class SimpleFSIndexOutput : public BufferedIndexOutput - { - public: - SimpleFSIndexOutput(const String& path); - virtual ~SimpleFSIndexOutput(); - - LUCENE_CLASS(SimpleFSIndexOutput); - - protected: - OutputFilePtr file; - bool isOpen; - - public: - virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length); - virtual void close(); - virtual void seek(int64_t pos); - virtual int64_t length(); - virtual void setLength(int64_t length); - }; +namespace Lucene { + +class InputFile : public LuceneObject { +public: + InputFile(const String& path); + virtual ~InputFile(); + + LUCENE_CLASS(InputFile); + +public: + static const int32_t FILE_EOF; + static const int32_t FILE_ERROR; + +protected: + ifstreamPtr file; + int64_t position; + int64_t length; + +public: + void setPosition(int64_t position); + int64_t getPosition(); + int64_t getLength(); + int32_t read(uint8_t* b, int32_t offset, int32_t length); + void close(); + bool isValid(); +}; + +class SimpleFSIndexInput : public BufferedIndexInput { +public: + SimpleFSIndexInput(); + SimpleFSIndexInput(const String& path, int32_t bufferSize, int32_t chunkSize); + virtual ~SimpleFSIndexInput(); + + LUCENE_CLASS(SimpleFSIndexInput); + +protected: + String path; + InputFilePtr file; + bool isClone; + int32_t chunkSize; + +protected: + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); + virtual void seekInternal(int64_t pos); + +public: + virtual int64_t length(); + virtual void close(); + + /// Method used for testing. + bool isValid(); + + /// Returns a clone of this stream. + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + +class OutputFile : public LuceneObject { +public: + OutputFile(const String& path); + virtual ~OutputFile(); + + LUCENE_CLASS(OutputFile); + +protected: + ofstreamPtr file; + String path; + +public: + bool write(const uint8_t* b, int32_t offset, int32_t length); + void close(); + void setPosition(int64_t position); + int64_t getLength(); + void setLength(int64_t length); + void flush(); + bool isValid(); +}; + +class SimpleFSIndexOutput : public BufferedIndexOutput { +public: + SimpleFSIndexOutput(const String& path); + virtual ~SimpleFSIndexOutput(); + + LUCENE_CLASS(SimpleFSIndexOutput); + +protected: + OutputFilePtr file; + bool isOpen; + +public: + virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length); + virtual void close(); + virtual void seek(int64_t pos); + virtual int64_t length(); + virtual void setLength(int64_t length); +}; + } #endif diff --git a/src/core/include/_SimpleFSLockFactory.h b/src/core/include/_SimpleFSLockFactory.h index cedb8907..fdb4c1d5 100644 --- a/src/core/include/_SimpleFSLockFactory.h +++ b/src/core/include/_SimpleFSLockFactory.h @@ -9,35 +9,35 @@ #include "Lock.h" -namespace Lucene -{ - class SimpleFSLock : public Lock - { - public: - SimpleFSLock(const String& lockDir, const String& lockFileName); - virtual ~SimpleFSLock(); - - LUCENE_CLASS(SimpleFSLock); - - public: - String lockDir; - String lockFile; - - public: - /// Attempts to obtain exclusive access and immediately return upon success or failure. - /// @return true if exclusive access is obtained. - virtual bool obtain(); - - /// Releases exclusive access. - virtual void release(); - - /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} - /// before using the resource. - virtual bool isLocked(); - - /// Returns derived object name. - virtual String toString(); - }; +namespace Lucene { + +class SimpleFSLock : public Lock { +public: + SimpleFSLock(const String& lockDir, const String& lockFileName); + virtual ~SimpleFSLock(); + + LUCENE_CLASS(SimpleFSLock); + +public: + String lockDir; + String lockFile; + +public: + /// Attempts to obtain exclusive access and immediately return upon success or failure. + /// @return true if exclusive access is obtained. + virtual bool obtain(); + + /// Releases exclusive access. + virtual void release(); + + /// Returns true if the resource is currently locked. Note that one must still call {@link #obtain()} + /// before using the resource. + virtual bool isLocked(); + + /// Returns derived object name. + virtual String toString(); +}; + } #endif diff --git a/src/core/include/_SingleInstanceLockFactory.h b/src/core/include/_SingleInstanceLockFactory.h index ea2d56a8..77259fca 100644 --- a/src/core/include/_SingleInstanceLockFactory.h +++ b/src/core/include/_SingleInstanceLockFactory.h @@ -9,36 +9,36 @@ #include "Lock.h" -namespace Lucene -{ - class SingleInstanceLock : public Lock - { - public: - SingleInstanceLock(HashSet locks, const String& lockName); - virtual ~SingleInstanceLock(); - - LUCENE_CLASS(SingleInstanceLock); - - protected: - HashSet locks; - String lockName; - - public: - /// Attempts to obtain exclusive access and immediately return - /// upon success or failure. - /// @return true if exclusive access is obtained. - virtual bool obtain(); - - /// Releases exclusive access. - virtual void release(); - - /// Returns true if the resource is currently locked. Note that - /// one must still call {@link #obtain()} before using the resource. - virtual bool isLocked(); - - /// Returns derived object name. - virtual String toString(); - }; +namespace Lucene { + +class SingleInstanceLock : public Lock { +public: + SingleInstanceLock(HashSet locks, const String& lockName); + virtual ~SingleInstanceLock(); + + LUCENE_CLASS(SingleInstanceLock); + +protected: + HashSet locks; + String lockName; + +public: + /// Attempts to obtain exclusive access and immediately return + /// upon success or failure. + /// @return true if exclusive access is obtained. + virtual bool obtain(); + + /// Releases exclusive access. + virtual void release(); + + /// Returns true if the resource is currently locked. Note that + /// one must still call {@link #obtain()} before using the resource. + virtual bool isLocked(); + + /// Returns derived object name. + virtual String toString(); +}; + } #endif diff --git a/src/core/include/_SnapshotDeletionPolicy.h b/src/core/include/_SnapshotDeletionPolicy.h index b53bc5a1..9327fa5f 100644 --- a/src/core/include/_SnapshotDeletionPolicy.h +++ b/src/core/include/_SnapshotDeletionPolicy.h @@ -9,50 +9,50 @@ #include "IndexCommit.h" -namespace Lucene -{ - class MyCommitPoint : public IndexCommit - { - public: - MyCommitPoint(const SnapshotDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& cp); - virtual ~MyCommitPoint(); +namespace Lucene { - LUCENE_CLASS(MyCommitPoint); +class MyCommitPoint : public IndexCommit { +public: + MyCommitPoint(const SnapshotDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& cp); + virtual ~MyCommitPoint(); - protected: - SnapshotDeletionPolicyWeakPtr _deletionPolicy; + LUCENE_CLASS(MyCommitPoint); - public: - IndexCommitPtr cp; +protected: + SnapshotDeletionPolicyWeakPtr _deletionPolicy; - public: - virtual String toString(); +public: + IndexCommitPtr cp; - /// Get the segments file (segments_N) associated with this commit point. - virtual String getSegmentsFileName(); +public: + virtual String toString(); - /// Returns all index files referenced by this commit point. - virtual HashSet getFileNames(); + /// Get the segments file (segments_N) associated with this commit point. + virtual String getSegmentsFileName(); - /// Returns the {@link Directory} for the index. - virtual DirectoryPtr getDirectory(); + /// Returns all index files referenced by this commit point. + virtual HashSet getFileNames(); - /// Delete this commit point. - virtual void deleteCommit(); + /// Returns the {@link Directory} for the index. + virtual DirectoryPtr getDirectory(); - virtual bool isDeleted(); + /// Delete this commit point. + virtual void deleteCommit(); - /// Returns the version for this IndexCommit. - virtual int64_t getVersion(); + virtual bool isDeleted(); - /// Returns the generation (the _N in segments_N) for this IndexCommit. - virtual int64_t getGeneration(); + /// Returns the version for this IndexCommit. + virtual int64_t getVersion(); - /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. - virtual MapStringString getUserData(); + /// Returns the generation (the _N in segments_N) for this IndexCommit. + virtual int64_t getGeneration(); + + /// Returns userData, previously passed to {@link IndexWriter#commit(Map)} for this commit. + virtual MapStringString getUserData(); + + virtual bool isOptimized(); +}; - virtual bool isOptimized(); - }; } #endif diff --git a/src/core/include/_SortedVIntList.h b/src/core/include/_SortedVIntList.h index b641722c..c5318ef3 100644 --- a/src/core/include/_SortedVIntList.h +++ b/src/core/include/_SortedVIntList.h @@ -9,30 +9,30 @@ #include "DocIdSetIterator.h" -namespace Lucene -{ - class SortedDocIdSetIterator : public DocIdSetIterator - { - public: - SortedDocIdSetIterator(const SortedVIntListPtr& list); - virtual ~SortedDocIdSetIterator(); - - LUCENE_CLASS(SortedDocIdSetIterator); - - public: - SortedVIntListWeakPtr _list; - int32_t bytePos; - int32_t lastInt; - int32_t doc; - - public: - virtual int32_t docID(); - virtual int32_t nextDoc(); - virtual int32_t advance(int32_t target); - - protected: - void advance(); - }; +namespace Lucene { + +class SortedDocIdSetIterator : public DocIdSetIterator { +public: + SortedDocIdSetIterator(const SortedVIntListPtr& list); + virtual ~SortedDocIdSetIterator(); + + LUCENE_CLASS(SortedDocIdSetIterator); + +public: + SortedVIntListWeakPtr _list; + int32_t bytePos; + int32_t lastInt; + int32_t doc; + +public: + virtual int32_t docID(); + virtual int32_t nextDoc(); + virtual int32_t advance(int32_t target); + +protected: + void advance(); +}; + } #endif diff --git a/src/core/include/_SpanFirstQuery.h b/src/core/include/_SpanFirstQuery.h index 34b9aae6..399e54a1 100644 --- a/src/core/include/_SpanFirstQuery.h +++ b/src/core/include/_SpanFirstQuery.h @@ -9,29 +9,29 @@ #include "Spans.h" -namespace Lucene -{ - class FirstSpans : public Spans - { - public: - FirstSpans(const SpanFirstQueryPtr& query, const SpansPtr& spans); - virtual ~FirstSpans(); - - LUCENE_CLASS(FirstSpans); - - protected: - SpanFirstQueryPtr query; - SpansPtr spans; - - public: - virtual bool next(); - virtual bool skipTo(int32_t target); - virtual int32_t doc(); - virtual int32_t start(); - virtual int32_t end(); - virtual Collection getPayload(); - virtual bool isPayloadAvailable(); - }; +namespace Lucene { + +class FirstSpans : public Spans { +public: + FirstSpans(const SpanFirstQueryPtr& query, const SpansPtr& spans); + virtual ~FirstSpans(); + + LUCENE_CLASS(FirstSpans); + +protected: + SpanFirstQueryPtr query; + SpansPtr spans; + +public: + virtual bool next(); + virtual bool skipTo(int32_t target); + virtual int32_t doc(); + virtual int32_t start(); + virtual int32_t end(); + virtual Collection getPayload(); + virtual bool isPayloadAvailable(); +}; + } #endif diff --git a/src/core/include/_SpanNotQuery.h b/src/core/include/_SpanNotQuery.h index 95209b7e..584f238b 100644 --- a/src/core/include/_SpanNotQuery.h +++ b/src/core/include/_SpanNotQuery.h @@ -9,33 +9,33 @@ #include "Spans.h" -namespace Lucene -{ - class NotSpans : public Spans - { - public: - NotSpans(const SpanNotQueryPtr& query, const SpansPtr& includeSpans, const SpansPtr& excludeSpans); - virtual ~NotSpans(); - - LUCENE_CLASS(NotSpans); - - protected: - SpanNotQueryPtr query; - SpansPtr includeSpans; - bool moreInclude; - SpansPtr excludeSpans; - bool moreExclude; - - public: - virtual bool next(); - virtual bool skipTo(int32_t target); - virtual int32_t doc(); - virtual int32_t start(); - virtual int32_t end(); - virtual Collection getPayload(); - virtual bool isPayloadAvailable(); - virtual String toString(); - }; +namespace Lucene { + +class NotSpans : public Spans { +public: + NotSpans(const SpanNotQueryPtr& query, const SpansPtr& includeSpans, const SpansPtr& excludeSpans); + virtual ~NotSpans(); + + LUCENE_CLASS(NotSpans); + +protected: + SpanNotQueryPtr query; + SpansPtr includeSpans; + bool moreInclude; + SpansPtr excludeSpans; + bool moreExclude; + +public: + virtual bool next(); + virtual bool skipTo(int32_t target); + virtual int32_t doc(); + virtual int32_t start(); + virtual int32_t end(); + virtual Collection getPayload(); + virtual bool isPayloadAvailable(); + virtual String toString(); +}; + } #endif diff --git a/src/core/include/_SpanOrQuery.h b/src/core/include/_SpanOrQuery.h index 6f63875f..92763ab3 100644 --- a/src/core/include/_SpanOrQuery.h +++ b/src/core/include/_SpanOrQuery.h @@ -10,47 +10,46 @@ #include "PriorityQueue.h" #include "Spans.h" -namespace Lucene -{ - class SpanQueue : public PriorityQueue - { - public: - SpanQueue(int32_t size); - virtual ~SpanQueue(); - - LUCENE_CLASS(SpanQueue); - - protected: - virtual bool lessThan(const SpansPtr& first, const SpansPtr& second); - }; - - class OrSpans : public Spans - { - public: - OrSpans(const SpanOrQueryPtr& query, const IndexReaderPtr& reader); - virtual ~OrSpans(); - - LUCENE_CLASS(OrSpans); - - protected: - SpanOrQueryPtr query; - IndexReaderPtr reader; - SpanQueuePtr queue; - - public: - virtual bool next(); - virtual bool skipTo(int32_t target); - virtual int32_t doc(); - virtual int32_t start(); - virtual int32_t end(); - virtual Collection getPayload(); - virtual bool isPayloadAvailable(); - virtual String toString(); - - protected: - bool initSpanQueue(int32_t target); - SpansPtr top(); - }; +namespace Lucene { + +class SpanQueue : public PriorityQueue { +public: + SpanQueue(int32_t size); + virtual ~SpanQueue(); + + LUCENE_CLASS(SpanQueue); + +protected: + virtual bool lessThan(const SpansPtr& first, const SpansPtr& second); +}; + +class OrSpans : public Spans { +public: + OrSpans(const SpanOrQueryPtr& query, const IndexReaderPtr& reader); + virtual ~OrSpans(); + + LUCENE_CLASS(OrSpans); + +protected: + SpanOrQueryPtr query; + IndexReaderPtr reader; + SpanQueuePtr queue; + +public: + virtual bool next(); + virtual bool skipTo(int32_t target); + virtual int32_t doc(); + virtual int32_t start(); + virtual int32_t end(); + virtual Collection getPayload(); + virtual bool isPayloadAvailable(); + virtual String toString(); + +protected: + bool initSpanQueue(int32_t target); + SpansPtr top(); +}; + } #endif diff --git a/src/core/include/_StandardAnalyzer.h b/src/core/include/_StandardAnalyzer.h index 96c8b7b8..f9dbf51a 100644 --- a/src/core/include/_StandardAnalyzer.h +++ b/src/core/include/_StandardAnalyzer.h @@ -9,17 +9,17 @@ #include "LuceneObject.h" -namespace Lucene -{ - class StandardAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~StandardAnalyzerSavedStreams(); +namespace Lucene { + +class StandardAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~StandardAnalyzerSavedStreams(); + +public: + StandardTokenizerPtr tokenStream; + TokenStreamPtr filteredTokenStream; +}; - public: - StandardTokenizerPtr tokenStream; - TokenStreamPtr filteredTokenStream; - }; } #endif diff --git a/src/core/include/_StopAnalyzer.h b/src/core/include/_StopAnalyzer.h index 799a6200..678aace5 100644 --- a/src/core/include/_StopAnalyzer.h +++ b/src/core/include/_StopAnalyzer.h @@ -9,20 +9,20 @@ #include "LuceneObject.h" -namespace Lucene -{ - /// Filters LowerCaseTokenizer with StopFilter. - class StopAnalyzerSavedStreams : public LuceneObject - { - public: - virtual ~StopAnalyzerSavedStreams(); - - LUCENE_CLASS(StopAnalyzerSavedStreams); - - public: - TokenizerPtr source; - TokenStreamPtr result; - }; +namespace Lucene { + +/// Filters LowerCaseTokenizer with StopFilter. +class StopAnalyzerSavedStreams : public LuceneObject { +public: + virtual ~StopAnalyzerSavedStreams(); + + LUCENE_CLASS(StopAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + } #endif diff --git a/src/core/include/_TermQuery.h b/src/core/include/_TermQuery.h index d66ce390..d6589ab5 100644 --- a/src/core/include/_TermQuery.h +++ b/src/core/include/_TermQuery.h @@ -9,34 +9,34 @@ #include "Weight.h" -namespace Lucene -{ - class TermWeight : public Weight - { - public: - TermWeight(const TermQueryPtr& query, const SearcherPtr& searcher); - virtual ~TermWeight(); - - LUCENE_CLASS(TermWeight); - - protected: - TermQueryPtr query; - SimilarityPtr similarity; - double value; - double idf; - double queryNorm; - double queryWeight; - IDFExplanationPtr idfExp; - - public: - virtual String toString(); - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - }; +namespace Lucene { + +class TermWeight : public Weight { +public: + TermWeight(const TermQueryPtr& query, const SearcherPtr& searcher); + virtual ~TermWeight(); + + LUCENE_CLASS(TermWeight); + +protected: + TermQueryPtr query; + SimilarityPtr similarity; + double value; + double idf; + double queryNorm; + double queryWeight; + IDFExplanationPtr idfExp; + +public: + virtual String toString(); + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); +}; + } #endif diff --git a/src/core/include/_TimeLimitingCollector.h b/src/core/include/_TimeLimitingCollector.h index a2879cbc..a0cd94fd 100644 --- a/src/core/include/_TimeLimitingCollector.h +++ b/src/core/include/_TimeLimitingCollector.h @@ -9,30 +9,30 @@ #include "LuceneThread.h" -namespace Lucene -{ - class TimerThread : public LuceneThread - { - public: - TimerThread(); - virtual ~TimerThread(); - - LUCENE_CLASS(TimerThread); - - protected: - int64_t time; - bool _stopThread; - - public: - virtual void start(); - virtual void run(); - - /// Get the timer value in milliseconds. - int64_t getMilliseconds(); - - /// Stop timer thread. - void stopThread(); - }; +namespace Lucene { + +class TimerThread : public LuceneThread { +public: + TimerThread(); + virtual ~TimerThread(); + + LUCENE_CLASS(TimerThread); + +protected: + int64_t time; + bool _stopThread; + +public: + virtual void start(); + virtual void run(); + + /// Get the timer value in milliseconds. + int64_t getMilliseconds(); + + /// Stop timer thread. + void stopThread(); +}; + } #endif diff --git a/src/core/include/_TopFieldCollector.h b/src/core/include/_TopFieldCollector.h index fd4d7df1..611dc3f4 100644 --- a/src/core/include/_TopFieldCollector.h +++ b/src/core/include/_TopFieldCollector.h @@ -9,210 +9,199 @@ #include "TopDocsCollector.h" -namespace Lucene -{ - /// Implements a TopFieldCollector over one SortField criteria, without tracking document scores and maxScore. - class OneComparatorNonScoringCollector : public TopFieldCollector - { - public: - OneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OneComparatorNonScoringCollector(); - - LUCENE_CLASS(OneComparatorNonScoringCollector); - - public: - FieldComparatorPtr comparator; - int32_t reverseMul; - - public: - virtual void initialize(); - virtual void updateBottom(int32_t doc); - virtual void collect(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setScorer(const ScorerPtr& scorer); - }; - - /// Implements a TopFieldCollector over one SortField criteria, without tracking document scores and maxScore, - /// and assumes out of orderness in doc Ids collection. - class OutOfOrderOneComparatorNonScoringCollector : public OneComparatorNonScoringCollector - { - public: - OutOfOrderOneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OutOfOrderOneComparatorNonScoringCollector(); - - LUCENE_CLASS(OutOfOrderOneComparatorNonScoringCollector); - - public: - virtual void collect(int32_t doc); - virtual bool acceptsDocsOutOfOrder(); - }; - - /// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore. - class OneComparatorScoringNoMaxScoreCollector : public OneComparatorNonScoringCollector - { - public: - OneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OneComparatorScoringNoMaxScoreCollector(); - - LUCENE_CLASS(OneComparatorScoringNoMaxScoreCollector); - - public: - ScorerPtr scorer; - - public: - virtual void updateBottom(int32_t doc, double score); - virtual void collect(int32_t doc); - virtual void setScorer(const ScorerPtr& scorer); - }; - - /// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore, - /// and assumes out of orderness in doc Ids collection. - class OutOfOrderOneComparatorScoringNoMaxScoreCollector : public OneComparatorScoringNoMaxScoreCollector - { - public: - OutOfOrderOneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OutOfOrderOneComparatorScoringNoMaxScoreCollector(); - - LUCENE_CLASS(OutOfOrderOneComparatorScoringNoMaxScoreCollector); - - public: - virtual void collect(int32_t doc); - virtual bool acceptsDocsOutOfOrder(); - }; - - /// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore. - class OneComparatorScoringMaxScoreCollector : public OneComparatorNonScoringCollector - { - public: - OneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OneComparatorScoringMaxScoreCollector(); - - LUCENE_CLASS(OneComparatorScoringMaxScoreCollector); - - public: - ScorerPtr scorer; - - public: - virtual void updateBottom(int32_t doc, double score); - virtual void collect(int32_t doc); - virtual void setScorer(const ScorerPtr& scorer); - }; - - /// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore, - /// and assumes out of orderness in doc Ids collection. - class OutOfOrderOneComparatorScoringMaxScoreCollector : public OneComparatorScoringMaxScoreCollector - { - public: - OutOfOrderOneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OutOfOrderOneComparatorScoringMaxScoreCollector(); - - LUCENE_CLASS(OutOfOrderOneComparatorScoringMaxScoreCollector); - - public: - virtual void collect(int32_t doc); - virtual bool acceptsDocsOutOfOrder(); - }; - - /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. - class MultiComparatorNonScoringCollector : public TopFieldCollector - { - public: - MultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~MultiComparatorNonScoringCollector(); - - LUCENE_CLASS(MultiComparatorNonScoringCollector); - - public: - Collection comparators; - Collection reverseMul; - - public: - virtual void initialize(); - virtual void updateBottom(int32_t doc); - virtual void collect(int32_t doc); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); - virtual void setScorer(const ScorerPtr& scorer); - }; - - /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. - class OutOfOrderMultiComparatorNonScoringCollector : public MultiComparatorNonScoringCollector - { - public: - OutOfOrderMultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OutOfOrderMultiComparatorNonScoringCollector(); - - LUCENE_CLASS(OutOfOrderMultiComparatorNonScoringCollector); - - public: - virtual void collect(int32_t doc); - virtual bool acceptsDocsOutOfOrder(); - }; - - /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore. - class MultiComparatorScoringMaxScoreCollector : public MultiComparatorNonScoringCollector - { - public: - MultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~MultiComparatorScoringMaxScoreCollector(); - - LUCENE_CLASS(MultiComparatorScoringMaxScoreCollector); - - public: - ScorerWeakPtr _scorer; - - public: - virtual void updateBottom(int32_t doc, double score); - virtual void collect(int32_t doc); - virtual void setScorer(const ScorerPtr& scorer); - }; - - /// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. - class OutOfOrderMultiComparatorScoringMaxScoreCollector : public MultiComparatorScoringMaxScoreCollector - { - public: - OutOfOrderMultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OutOfOrderMultiComparatorScoringMaxScoreCollector(); - - LUCENE_CLASS(OutOfOrderMultiComparatorScoringMaxScoreCollector); - - public: - virtual void collect(int32_t doc); - virtual bool acceptsDocsOutOfOrder(); - }; - - /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore. - class MultiComparatorScoringNoMaxScoreCollector : public MultiComparatorNonScoringCollector - { - public: - MultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~MultiComparatorScoringNoMaxScoreCollector(); - - LUCENE_CLASS(MultiComparatorScoringNoMaxScoreCollector); - - public: - ScorerWeakPtr _scorer; - - public: - virtual void updateBottom(int32_t doc, double score); - virtual void collect(int32_t doc); - virtual void setScorer(const ScorerPtr& scorer); - }; - - /// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore, - /// and assumes out of orderness in doc Ids collection. - class OutOfOrderMultiComparatorScoringNoMaxScoreCollector : public MultiComparatorScoringNoMaxScoreCollector - { - public: - OutOfOrderMultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); - virtual ~OutOfOrderMultiComparatorScoringNoMaxScoreCollector(); - - LUCENE_CLASS(OutOfOrderMultiComparatorScoringNoMaxScoreCollector); - - public: - virtual void collect(int32_t doc); - virtual void setScorer(const ScorerPtr& scorer); - virtual bool acceptsDocsOutOfOrder(); - }; +namespace Lucene { + +/// Implements a TopFieldCollector over one SortField criteria, without tracking document scores and maxScore. +class OneComparatorNonScoringCollector : public TopFieldCollector { +public: + OneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OneComparatorNonScoringCollector(); + + LUCENE_CLASS(OneComparatorNonScoringCollector); + +public: + FieldComparatorPtr comparator; + int32_t reverseMul; + +public: + virtual void initialize(); + virtual void updateBottom(int32_t doc); + virtual void collect(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); +}; + +/// Implements a TopFieldCollector over one SortField criteria, without tracking document scores and maxScore, +/// and assumes out of orderness in doc Ids collection. +class OutOfOrderOneComparatorNonScoringCollector : public OneComparatorNonScoringCollector { +public: + OutOfOrderOneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OutOfOrderOneComparatorNonScoringCollector(); + + LUCENE_CLASS(OutOfOrderOneComparatorNonScoringCollector); + +public: + virtual void collect(int32_t doc); + virtual bool acceptsDocsOutOfOrder(); +}; + +/// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore. +class OneComparatorScoringNoMaxScoreCollector : public OneComparatorNonScoringCollector { +public: + OneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OneComparatorScoringNoMaxScoreCollector(); + + LUCENE_CLASS(OneComparatorScoringNoMaxScoreCollector); + +public: + ScorerPtr scorer; + +public: + virtual void updateBottom(int32_t doc, double score); + virtual void collect(int32_t doc); + virtual void setScorer(const ScorerPtr& scorer); +}; + +/// Implements a TopFieldCollector over one SortField criteria, while tracking document scores but no maxScore, +/// and assumes out of orderness in doc Ids collection. +class OutOfOrderOneComparatorScoringNoMaxScoreCollector : public OneComparatorScoringNoMaxScoreCollector { +public: + OutOfOrderOneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OutOfOrderOneComparatorScoringNoMaxScoreCollector(); + + LUCENE_CLASS(OutOfOrderOneComparatorScoringNoMaxScoreCollector); + +public: + virtual void collect(int32_t doc); + virtual bool acceptsDocsOutOfOrder(); +}; + +/// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore. +class OneComparatorScoringMaxScoreCollector : public OneComparatorNonScoringCollector { +public: + OneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OneComparatorScoringMaxScoreCollector(); + + LUCENE_CLASS(OneComparatorScoringMaxScoreCollector); + +public: + ScorerPtr scorer; + +public: + virtual void updateBottom(int32_t doc, double score); + virtual void collect(int32_t doc); + virtual void setScorer(const ScorerPtr& scorer); +}; + +/// Implements a TopFieldCollector over one SortField criteria, with tracking document scores and maxScore, +/// and assumes out of orderness in doc Ids collection. +class OutOfOrderOneComparatorScoringMaxScoreCollector : public OneComparatorScoringMaxScoreCollector { +public: + OutOfOrderOneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OutOfOrderOneComparatorScoringMaxScoreCollector(); + + LUCENE_CLASS(OutOfOrderOneComparatorScoringMaxScoreCollector); + +public: + virtual void collect(int32_t doc); + virtual bool acceptsDocsOutOfOrder(); +}; + +/// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. +class MultiComparatorNonScoringCollector : public TopFieldCollector { +public: + MultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~MultiComparatorNonScoringCollector(); + + LUCENE_CLASS(MultiComparatorNonScoringCollector); + +public: + Collection comparators; + Collection reverseMul; + +public: + virtual void initialize(); + virtual void updateBottom(int32_t doc); + virtual void collect(int32_t doc); + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase); + virtual void setScorer(const ScorerPtr& scorer); +}; + +/// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. +class OutOfOrderMultiComparatorNonScoringCollector : public MultiComparatorNonScoringCollector { +public: + OutOfOrderMultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OutOfOrderMultiComparatorNonScoringCollector(); + + LUCENE_CLASS(OutOfOrderMultiComparatorNonScoringCollector); + +public: + virtual void collect(int32_t doc); + virtual bool acceptsDocsOutOfOrder(); +}; + +/// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore. +class MultiComparatorScoringMaxScoreCollector : public MultiComparatorNonScoringCollector { +public: + MultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~MultiComparatorScoringMaxScoreCollector(); + + LUCENE_CLASS(MultiComparatorScoringMaxScoreCollector); + +public: + ScorerWeakPtr _scorer; + +public: + virtual void updateBottom(int32_t doc, double score); + virtual void collect(int32_t doc); + virtual void setScorer(const ScorerPtr& scorer); +}; + +/// Implements a TopFieldCollector over multiple SortField criteria, without tracking document scores and maxScore. +class OutOfOrderMultiComparatorScoringMaxScoreCollector : public MultiComparatorScoringMaxScoreCollector { +public: + OutOfOrderMultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OutOfOrderMultiComparatorScoringMaxScoreCollector(); + + LUCENE_CLASS(OutOfOrderMultiComparatorScoringMaxScoreCollector); + +public: + virtual void collect(int32_t doc); + virtual bool acceptsDocsOutOfOrder(); +}; + +/// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore. +class MultiComparatorScoringNoMaxScoreCollector : public MultiComparatorNonScoringCollector { +public: + MultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~MultiComparatorScoringNoMaxScoreCollector(); + + LUCENE_CLASS(MultiComparatorScoringNoMaxScoreCollector); + +public: + ScorerWeakPtr _scorer; + +public: + virtual void updateBottom(int32_t doc, double score); + virtual void collect(int32_t doc); + virtual void setScorer(const ScorerPtr& scorer); +}; + +/// Implements a TopFieldCollector over multiple SortField criteria, with tracking document scores and maxScore, +/// and assumes out of orderness in doc Ids collection. +class OutOfOrderMultiComparatorScoringNoMaxScoreCollector : public MultiComparatorScoringNoMaxScoreCollector { +public: + OutOfOrderMultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields); + virtual ~OutOfOrderMultiComparatorScoringNoMaxScoreCollector(); + + LUCENE_CLASS(OutOfOrderMultiComparatorScoringNoMaxScoreCollector); + +public: + virtual void collect(int32_t doc); + virtual void setScorer(const ScorerPtr& scorer); + virtual bool acceptsDocsOutOfOrder(); +}; + } #endif diff --git a/src/core/include/_TopScoreDocCollector.h b/src/core/include/_TopScoreDocCollector.h index fdaf0185..668b2d7a 100644 --- a/src/core/include/_TopScoreDocCollector.h +++ b/src/core/include/_TopScoreDocCollector.h @@ -9,35 +9,34 @@ #include "TopDocsCollector.h" -namespace Lucene -{ - /// Assumes docs are scored in order. - class InOrderTopScoreDocCollector : public TopScoreDocCollector - { - public: - InOrderTopScoreDocCollector(int32_t numHits); - virtual ~InOrderTopScoreDocCollector(); - - LUCENE_CLASS(InOrderTopScoreDocCollector); - - public: - virtual void collect(int32_t doc); - virtual bool acceptsDocsOutOfOrder(); - }; - - /// Assumes docs are scored out of order. - class OutOfOrderTopScoreDocCollector : public TopScoreDocCollector - { - public: - OutOfOrderTopScoreDocCollector(int32_t numHits); - virtual ~OutOfOrderTopScoreDocCollector(); - - LUCENE_CLASS(OutOfOrderTopScoreDocCollector); - - public: - virtual void collect(int32_t doc); - virtual bool acceptsDocsOutOfOrder(); - }; +namespace Lucene { + +/// Assumes docs are scored in order. +class InOrderTopScoreDocCollector : public TopScoreDocCollector { +public: + InOrderTopScoreDocCollector(int32_t numHits); + virtual ~InOrderTopScoreDocCollector(); + + LUCENE_CLASS(InOrderTopScoreDocCollector); + +public: + virtual void collect(int32_t doc); + virtual bool acceptsDocsOutOfOrder(); +}; + +/// Assumes docs are scored out of order. +class OutOfOrderTopScoreDocCollector : public TopScoreDocCollector { +public: + OutOfOrderTopScoreDocCollector(int32_t numHits); + virtual ~OutOfOrderTopScoreDocCollector(); + + LUCENE_CLASS(OutOfOrderTopScoreDocCollector); + +public: + virtual void collect(int32_t doc); + virtual bool acceptsDocsOutOfOrder(); +}; + } #endif diff --git a/src/core/include/_ValueSourceQuery.h b/src/core/include/_ValueSourceQuery.h index 6ea879b6..004722e3 100644 --- a/src/core/include/_ValueSourceQuery.h +++ b/src/core/include/_ValueSourceQuery.h @@ -10,55 +10,54 @@ #include "Weight.h" #include "Scorer.h" -namespace Lucene -{ - class ValueSourceWeight : public Weight - { - public: - ValueSourceWeight(const ValueSourceQueryPtr& query, const SearcherPtr& searcher); - virtual ~ValueSourceWeight(); +namespace Lucene { + +class ValueSourceWeight : public Weight { +public: + ValueSourceWeight(const ValueSourceQueryPtr& query, const SearcherPtr& searcher); + virtual ~ValueSourceWeight(); + + LUCENE_CLASS(ValueSourceWeight); + +public: + ValueSourceQueryPtr query; + SimilarityPtr similarity; + double queryNorm; + double queryWeight; + +public: + virtual QueryPtr getQuery(); + virtual double getValue(); + virtual double sumOfSquaredWeights(); + virtual void normalize(double norm); + virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); + virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); +}; + +/// A scorer that (simply) matches all documents, and scores each document with the value of the value +/// source in effect. As an example, if the value source is a (cached) field source, then value of that +/// field in that document will be used. (assuming field is indexed for this doc, with a single token.) +class ValueSourceScorer : public Scorer { +public: + ValueSourceScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const ValueSourceWeightPtr& weight); + virtual ~ValueSourceScorer(); + + LUCENE_CLASS(ValueSourceScorer); + +public: + ValueSourceWeightPtr weight; + double qWeight; + DocValuesPtr vals; + TermDocsPtr termDocs; + int32_t doc; + +public: + virtual int32_t nextDoc(); + virtual int32_t docID(); + virtual int32_t advance(int32_t target); + virtual double score(); +}; - LUCENE_CLASS(ValueSourceWeight); - - public: - ValueSourceQueryPtr query; - SimilarityPtr similarity; - double queryNorm; - double queryWeight; - - public: - virtual QueryPtr getQuery(); - virtual double getValue(); - virtual double sumOfSquaredWeights(); - virtual void normalize(double norm); - virtual ScorerPtr scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer); - virtual ExplanationPtr explain(const IndexReaderPtr& reader, int32_t doc); - }; - - /// A scorer that (simply) matches all documents, and scores each document with the value of the value - /// source in effect. As an example, if the value source is a (cached) field source, then value of that - /// field in that document will be used. (assuming field is indexed for this doc, with a single token.) - class ValueSourceScorer : public Scorer - { - public: - ValueSourceScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const ValueSourceWeightPtr& weight); - virtual ~ValueSourceScorer(); - - LUCENE_CLASS(ValueSourceScorer); - - public: - ValueSourceWeightPtr weight; - double qWeight; - DocValuesPtr vals; - TermDocsPtr termDocs; - int32_t doc; - - public: - virtual int32_t nextDoc(); - virtual int32_t docID(); - virtual int32_t advance(int32_t target); - virtual double score(); - }; } #endif diff --git a/src/core/index/AbstractAllTermDocs.cpp b/src/core/index/AbstractAllTermDocs.cpp index 222d122d..ea6e6acf 100644 --- a/src/core/index/AbstractAllTermDocs.cpp +++ b/src/core/index/AbstractAllTermDocs.cpp @@ -7,76 +7,66 @@ #include "LuceneInc.h" #include "AbstractAllTermDocs.h" -namespace Lucene -{ - AbstractAllTermDocs::AbstractAllTermDocs(int32_t maxDoc) - { - this->maxDoc = maxDoc; - this->_doc = -1; - } +namespace Lucene { - AbstractAllTermDocs::~AbstractAllTermDocs() - { - } +AbstractAllTermDocs::AbstractAllTermDocs(int32_t maxDoc) { + this->maxDoc = maxDoc; + this->_doc = -1; +} - void AbstractAllTermDocs::seek(const TermPtr& term) - { - if (!term) - _doc = -1; - else - boost::throw_exception(UnsupportedOperationException()); - } +AbstractAllTermDocs::~AbstractAllTermDocs() { +} - void AbstractAllTermDocs::seek(const TermEnumPtr& termEnum) - { +void AbstractAllTermDocs::seek(const TermPtr& term) { + if (!term) { + _doc = -1; + } else { boost::throw_exception(UnsupportedOperationException()); } +} - int32_t AbstractAllTermDocs::doc() - { - return _doc; - } +void AbstractAllTermDocs::seek(const TermEnumPtr& termEnum) { + boost::throw_exception(UnsupportedOperationException()); +} - int32_t AbstractAllTermDocs::freq() - { - return 1; - } +int32_t AbstractAllTermDocs::doc() { + return _doc; +} - bool AbstractAllTermDocs::next() - { - return skipTo(_doc + 1); - } +int32_t AbstractAllTermDocs::freq() { + return 1; +} - int32_t AbstractAllTermDocs::read(Collection docs, Collection freqs) - { - int32_t length = docs.size(); - int32_t i = 0; - while (i < length && _doc < maxDoc) - { - if (!isDeleted(_doc)) - { - docs[i] = _doc; - freqs[i] = 1; - ++i; - } - ++_doc; +bool AbstractAllTermDocs::next() { + return skipTo(_doc + 1); +} + +int32_t AbstractAllTermDocs::read(Collection docs, Collection freqs) { + int32_t length = docs.size(); + int32_t i = 0; + while (i < length && _doc < maxDoc) { + if (!isDeleted(_doc)) { + docs[i] = _doc; + freqs[i] = 1; + ++i; } - return i; + ++_doc; } + return i; +} - bool AbstractAllTermDocs::skipTo(int32_t target) - { - _doc = target; - while (_doc < maxDoc) - { - if (!isDeleted(_doc)) - return true; - ++_doc; +bool AbstractAllTermDocs::skipTo(int32_t target) { + _doc = target; + while (_doc < maxDoc) { + if (!isDeleted(_doc)) { + return true; } - return false; + ++_doc; } + return false; +} + +void AbstractAllTermDocs::close() { +} - void AbstractAllTermDocs::close() - { - } } diff --git a/src/core/index/AllTermDocs.cpp b/src/core/index/AllTermDocs.cpp index 0a27b564..96186ea8 100644 --- a/src/core/index/AllTermDocs.cpp +++ b/src/core/index/AllTermDocs.cpp @@ -9,21 +9,19 @@ #include "SegmentReader.h" #include "BitVector.h" -namespace Lucene -{ - AllTermDocs::AllTermDocs(const SegmentReaderPtr& parent) : AbstractAllTermDocs(parent->maxDoc()) - { - SyncLock parentLock(parent); - this->_deletedDocs = parent->deletedDocs; - } +namespace Lucene { - AllTermDocs::~AllTermDocs() - { - } +AllTermDocs::AllTermDocs(const SegmentReaderPtr& parent) : AbstractAllTermDocs(parent->maxDoc()) { + SyncLock parentLock(parent); + this->_deletedDocs = parent->deletedDocs; +} + +AllTermDocs::~AllTermDocs() { +} + +bool AllTermDocs::isDeleted(int32_t doc) { + BitVectorPtr deletedDocs(_deletedDocs.lock()); + return (deletedDocs && deletedDocs->get(_doc)); +} - bool AllTermDocs::isDeleted(int32_t doc) - { - BitVectorPtr deletedDocs(_deletedDocs.lock()); - return (deletedDocs && deletedDocs->get(_doc)); - } } diff --git a/src/core/index/BufferedDeletes.cpp b/src/core/index/BufferedDeletes.cpp index 3aa86840..97d941da 100644 --- a/src/core/index/BufferedDeletes.cpp +++ b/src/core/index/BufferedDeletes.cpp @@ -8,116 +8,109 @@ #include "BufferedDeletes.h" #include "MergeDocIDRemapper.h" -namespace Lucene -{ - BufferedDeletes::BufferedDeletes(bool doTermSort) - { - // doTermSort not used: always use sorted term map - terms = MapTermNum::newInstance(); - queries = MapQueryInt::newInstance(); - docIDs = Collection::newInstance(); - numTerms = 0; - bytesUsed = 0; - } +namespace Lucene { + +BufferedDeletes::BufferedDeletes(bool doTermSort) { + // doTermSort not used: always use sorted term map + terms = MapTermNum::newInstance(); + queries = MapQueryInt::newInstance(); + docIDs = Collection::newInstance(); + numTerms = 0; + bytesUsed = 0; +} - BufferedDeletes::~BufferedDeletes() - { - } +BufferedDeletes::~BufferedDeletes() { +} - int32_t BufferedDeletes::size() - { - // We use numTerms not terms.size() intentionally, so that deletes by the same term - // multiple times "count", ie if you ask to flush every 1000 deletes then even dup'd - // terms are counted towards that 1000 - return numTerms + queries.size() + docIDs.size(); - } +int32_t BufferedDeletes::size() { + // We use numTerms not terms.size() intentionally, so that deletes by the same term + // multiple times "count", ie if you ask to flush every 1000 deletes then even dup'd + // terms are counted towards that 1000 + return numTerms + queries.size() + docIDs.size(); +} - void BufferedDeletes::update(const BufferedDeletesPtr& in) - { - numTerms += in->numTerms; - bytesUsed += in->bytesUsed; - terms.putAll(in->terms.begin(), in->terms.end()); - queries.putAll(in->queries.begin(), in->queries.end()); - docIDs.addAll(in->docIDs.begin(), in->docIDs.end()); - in->clear(); - } +void BufferedDeletes::update(const BufferedDeletesPtr& in) { + numTerms += in->numTerms; + bytesUsed += in->bytesUsed; + terms.putAll(in->terms.begin(), in->terms.end()); + queries.putAll(in->queries.begin(), in->queries.end()); + docIDs.addAll(in->docIDs.begin(), in->docIDs.end()); + in->clear(); +} - void BufferedDeletes::clear() - { - terms.clear(); - queries.clear(); - docIDs.clear(); - numTerms = 0; - bytesUsed = 0; - } +void BufferedDeletes::clear() { + terms.clear(); + queries.clear(); + docIDs.clear(); + numTerms = 0; + bytesUsed = 0; +} - void BufferedDeletes::addBytesUsed(int64_t b) - { - bytesUsed += b; - } +void BufferedDeletes::addBytesUsed(int64_t b) { + bytesUsed += b; +} - bool BufferedDeletes::any() - { - return (!terms.empty() || !docIDs.empty() || !queries.empty()); - } +bool BufferedDeletes::any() { + return (!terms.empty() || !docIDs.empty() || !queries.empty()); +} - void BufferedDeletes::remap(const MergeDocIDRemapperPtr& mapper, const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount) - { - SyncLock syncLock(this); +void BufferedDeletes::remap(const MergeDocIDRemapperPtr& mapper, const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount) { + SyncLock syncLock(this); - MapTermNum newDeleteTerms; + MapTermNum newDeleteTerms; - // Remap delete-by-term - if (!terms.empty()) - { - newDeleteTerms = MapTermNum::newInstance(); - for (MapTermNum::iterator entry = terms.begin(); entry != terms.end(); ++entry) - newDeleteTerms.put(entry->first, newLucene(mapper->remap(entry->second->getNum()))); + // Remap delete-by-term + if (!terms.empty()) { + newDeleteTerms = MapTermNum::newInstance(); + for (MapTermNum::iterator entry = terms.begin(); entry != terms.end(); ++entry) { + newDeleteTerms.put(entry->first, newLucene(mapper->remap(entry->second->getNum()))); } + } - // Remap delete-by-docID - Collection newDeleteDocIDs; + // Remap delete-by-docID + Collection newDeleteDocIDs; - if (!docIDs.empty()) - { - newDeleteDocIDs = Collection::newInstance(); - for (Collection::iterator num = docIDs.begin(); num != docIDs.end(); ++num) - newDeleteDocIDs.add(mapper->remap(*num)); + if (!docIDs.empty()) { + newDeleteDocIDs = Collection::newInstance(); + for (Collection::iterator num = docIDs.begin(); num != docIDs.end(); ++num) { + newDeleteDocIDs.add(mapper->remap(*num)); } + } - // Remap delete-by-query - MapQueryInt newDeleteQueries; + // Remap delete-by-query + MapQueryInt newDeleteQueries; - if (!queries.empty()) - { - newDeleteQueries = MapQueryInt::newInstance(); - for (MapQueryInt::iterator entry = queries.begin(); entry != queries.end(); ++entry) - newDeleteQueries.put(entry->first, mapper->remap(entry->second)); + if (!queries.empty()) { + newDeleteQueries = MapQueryInt::newInstance(); + for (MapQueryInt::iterator entry = queries.begin(); entry != queries.end(); ++entry) { + newDeleteQueries.put(entry->first, mapper->remap(entry->second)); } - - if (newDeleteTerms) - terms = newDeleteTerms; - if (newDeleteDocIDs) - docIDs = newDeleteDocIDs; - if (newDeleteQueries) - queries = newDeleteQueries; } - Num::Num(int32_t num) - { - this->num = num; + if (newDeleteTerms) { + terms = newDeleteTerms; } - - int32_t Num::getNum() - { - return num; + if (newDeleteDocIDs) { + docIDs = newDeleteDocIDs; } - - void Num::setNum(int32_t num) - { - // Only record the new number if it's greater than the current one. This is important - // because if multiple threads are replacing the same doc at nearly the same time, it's - // possible that one thread that got a higher docID is scheduled before the other threads. - this->num = std::max(this->num, num); + if (newDeleteQueries) { + queries = newDeleteQueries; } } + +Num::Num(int32_t num) { + this->num = num; +} + +int32_t Num::getNum() { + return num; +} + +void Num::setNum(int32_t num) { + // Only record the new number if it's greater than the current one. This is important + // because if multiple threads are replacing the same doc at nearly the same time, it's + // possible that one thread that got a higher docID is scheduled before the other threads. + this->num = std::max(this->num, num); +} + +} diff --git a/src/core/index/ByteBlockPool.cpp b/src/core/index/ByteBlockPool.cpp index bbbf5c8f..c8f344dc 100644 --- a/src/core/index/ByteBlockPool.cpp +++ b/src/core/index/ByteBlockPool.cpp @@ -9,116 +9,109 @@ #include "DocumentsWriter.h" #include "MiscUtils.h" -namespace Lucene -{ - // Size of each slice. These arrays should be at most 16 elements (index is encoded with 4 bits). First array - // is just a compact way to encode X+1 with a max. Second array is the length of each slice, ie first slice is - // 5 bytes, next slice is 14 bytes, etc. - const int32_t ByteBlockPool::nextLevelArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9}; - const int32_t ByteBlockPool::levelSizeArray[] = {5, 14, 20, 30, 40, 40, 80, 80, 120, 200}; - - ByteBlockPool::ByteBlockPool(const ByteBlockPoolAllocatorBasePtr& allocator, bool trackAllocations) - { - buffers = Collection::newInstance(10); - bufferUpto = -1; - byteUpto = DocumentsWriter::BYTE_BLOCK_SIZE; - byteOffset = -DocumentsWriter::BYTE_BLOCK_SIZE; - - this->allocator = allocator; - this->trackAllocations = trackAllocations; - } +namespace Lucene { + +// Size of each slice. These arrays should be at most 16 elements (index is encoded with 4 bits). First array +// is just a compact way to encode X+1 with a max. Second array is the length of each slice, ie first slice is +// 5 bytes, next slice is 14 bytes, etc. +const int32_t ByteBlockPool::nextLevelArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9}; +const int32_t ByteBlockPool::levelSizeArray[] = {5, 14, 20, 30, 40, 40, 80, 80, 120, 200}; + +ByteBlockPool::ByteBlockPool(const ByteBlockPoolAllocatorBasePtr& allocator, bool trackAllocations) { + buffers = Collection::newInstance(10); + bufferUpto = -1; + byteUpto = DocumentsWriter::BYTE_BLOCK_SIZE; + byteOffset = -DocumentsWriter::BYTE_BLOCK_SIZE; + + this->allocator = allocator; + this->trackAllocations = trackAllocations; +} - ByteBlockPool::~ByteBlockPool() - { - } +ByteBlockPool::~ByteBlockPool() { +} - int32_t ByteBlockPool::FIRST_LEVEL_SIZE() - { - return levelSizeArray[0]; - } +int32_t ByteBlockPool::FIRST_LEVEL_SIZE() { + return levelSizeArray[0]; +} - void ByteBlockPool::reset() - { - if (bufferUpto != -1) - { - // We allocated at least one buffer - for (int32_t i = 0; i < bufferUpto; ++i) - { - // Fully zero fill buffers that we fully used - MiscUtils::arrayFill(buffers[i].get(), 0, buffers[i].size(), 0); - } - - // Partial zero fill the final buffer - MiscUtils::arrayFill(buffers[bufferUpto].get(), 0, byteUpto, 0); - - if (bufferUpto > 0) - { - // Recycle all but the first buffer - allocator->recycleByteBlocks(buffers, 1, 1 + bufferUpto); - } - - // Re-use the first buffer - bufferUpto = 0; - byteUpto = 0; - byteOffset = 0; - buffer = buffers[0]; +void ByteBlockPool::reset() { + if (bufferUpto != -1) { + // We allocated at least one buffer + for (int32_t i = 0; i < bufferUpto; ++i) { + // Fully zero fill buffers that we fully used + MiscUtils::arrayFill(buffers[i].get(), 0, buffers[i].size(), 0); } - } - void ByteBlockPool::nextBuffer() - { - if (1 + bufferUpto == buffers.size()) - buffers.resize((int32_t)((double)buffers.size() * 1.5)); - buffers[1 + bufferUpto] = allocator->getByteBlock(trackAllocations); - buffer = buffers[1 + bufferUpto]; - ++bufferUpto; + // Partial zero fill the final buffer + MiscUtils::arrayFill(buffers[bufferUpto].get(), 0, byteUpto, 0); + + if (bufferUpto > 0) { + // Recycle all but the first buffer + allocator->recycleByteBlocks(buffers, 1, 1 + bufferUpto); + } + // Re-use the first buffer + bufferUpto = 0; byteUpto = 0; - byteOffset += DocumentsWriter::BYTE_BLOCK_SIZE; + byteOffset = 0; + buffer = buffers[0]; } +} - int32_t ByteBlockPool::newSlice(int32_t size) - { - if (byteUpto > DocumentsWriter::BYTE_BLOCK_SIZE - size) - nextBuffer(); - int32_t upto = byteUpto; - byteUpto += size; - buffer[byteUpto - 1] = 16; - return upto; +void ByteBlockPool::nextBuffer() { + if (1 + bufferUpto == buffers.size()) { + buffers.resize((int32_t)((double)buffers.size() * 1.5)); } + buffers[1 + bufferUpto] = allocator->getByteBlock(trackAllocations); + buffer = buffers[1 + bufferUpto]; + ++bufferUpto; - int32_t ByteBlockPool::allocSlice(ByteArray slice, int32_t upto) - { - int32_t level = slice[upto] & 15; - int32_t newLevel = nextLevelArray[level]; - int32_t newSize = levelSizeArray[newLevel]; + byteUpto = 0; + byteOffset += DocumentsWriter::BYTE_BLOCK_SIZE; +} - // Maybe allocate another block - if (byteUpto > DocumentsWriter::BYTE_BLOCK_SIZE - newSize) - nextBuffer(); +int32_t ByteBlockPool::newSlice(int32_t size) { + if (byteUpto > DocumentsWriter::BYTE_BLOCK_SIZE - size) { + nextBuffer(); + } + int32_t upto = byteUpto; + byteUpto += size; + buffer[byteUpto - 1] = 16; + return upto; +} - int32_t newUpto = byteUpto; - int32_t offset = newUpto + byteOffset; - byteUpto += newSize; +int32_t ByteBlockPool::allocSlice(ByteArray slice, int32_t upto) { + int32_t level = slice[upto] & 15; + int32_t newLevel = nextLevelArray[level]; + int32_t newSize = levelSizeArray[newLevel]; - // Copy forward the past 3 bytes (which we are about to overwrite with the forwarding address) - buffer[newUpto] = slice[upto - 3]; - buffer[newUpto + 1] = slice[upto - 2]; - buffer[newUpto + 2] = slice[upto - 1]; + // Maybe allocate another block + if (byteUpto > DocumentsWriter::BYTE_BLOCK_SIZE - newSize) { + nextBuffer(); + } - // Write forwarding address at end of last slice - slice[upto - 3] = (uint8_t)MiscUtils::unsignedShift(offset, 24); - slice[upto - 2] = (uint8_t)MiscUtils::unsignedShift(offset, 16); - slice[upto - 1] = (uint8_t)MiscUtils::unsignedShift(offset, 8); - slice[upto] = (uint8_t)offset; + int32_t newUpto = byteUpto; + int32_t offset = newUpto + byteOffset; + byteUpto += newSize; - // Write new level - buffer[byteUpto - 1] = (uint8_t)(16 | newLevel); + // Copy forward the past 3 bytes (which we are about to overwrite with the forwarding address) + buffer[newUpto] = slice[upto - 3]; + buffer[newUpto + 1] = slice[upto - 2]; + buffer[newUpto + 2] = slice[upto - 1]; - return (newUpto + 3); - } + // Write forwarding address at end of last slice + slice[upto - 3] = (uint8_t)MiscUtils::unsignedShift(offset, 24); + slice[upto - 2] = (uint8_t)MiscUtils::unsignedShift(offset, 16); + slice[upto - 1] = (uint8_t)MiscUtils::unsignedShift(offset, 8); + slice[upto] = (uint8_t)offset; + + // Write new level + buffer[byteUpto - 1] = (uint8_t)(16 | newLevel); + + return (newUpto + 3); +} + +ByteBlockPoolAllocatorBase::~ByteBlockPoolAllocatorBase() { +} - ByteBlockPoolAllocatorBase::~ByteBlockPoolAllocatorBase() - { - } } diff --git a/src/core/index/ByteSliceReader.cpp b/src/core/index/ByteSliceReader.cpp index c0dd05a8..b609510f 100644 --- a/src/core/index/ByteSliceReader.cpp +++ b/src/core/index/ByteSliceReader.cpp @@ -10,155 +10,133 @@ #include "IndexOutput.h" #include "MiscUtils.h" -namespace Lucene -{ - ByteSliceReader::ByteSliceReader() - { - bufferUpto = 0; - upto = 0; - limit = 0; - level = 0; - bufferOffset = 0; - endIndex = 0; - } +namespace Lucene { + +ByteSliceReader::ByteSliceReader() { + bufferUpto = 0; + upto = 0; + limit = 0; + level = 0; + bufferOffset = 0; + endIndex = 0; +} - ByteSliceReader::~ByteSliceReader() - { - } +ByteSliceReader::~ByteSliceReader() { +} - void ByteSliceReader::init(const ByteBlockPoolPtr& pool, int32_t startIndex, int32_t endIndex) - { - BOOST_ASSERT(endIndex - startIndex >= 0); - BOOST_ASSERT(startIndex >= 0); - BOOST_ASSERT(endIndex >= 0); +void ByteSliceReader::init(const ByteBlockPoolPtr& pool, int32_t startIndex, int32_t endIndex) { + BOOST_ASSERT(endIndex - startIndex >= 0); + BOOST_ASSERT(startIndex >= 0); + BOOST_ASSERT(endIndex >= 0); - this->pool = pool; - this->endIndex = endIndex; + this->pool = pool; + this->endIndex = endIndex; - level = 0; - bufferUpto = startIndex / DocumentsWriter::BYTE_BLOCK_SIZE; - bufferOffset = bufferUpto * DocumentsWriter::BYTE_BLOCK_SIZE; - buffer = pool->buffers[bufferUpto]; - upto = startIndex & DocumentsWriter::BYTE_BLOCK_MASK; + level = 0; + bufferUpto = startIndex / DocumentsWriter::BYTE_BLOCK_SIZE; + bufferOffset = bufferUpto * DocumentsWriter::BYTE_BLOCK_SIZE; + buffer = pool->buffers[bufferUpto]; + upto = startIndex & DocumentsWriter::BYTE_BLOCK_MASK; - int32_t firstSize = ByteBlockPool::levelSizeArray[0]; + int32_t firstSize = ByteBlockPool::levelSizeArray[0]; - if (startIndex + firstSize >= endIndex) - { - // There is only this one slice to read - limit = endIndex & DocumentsWriter::BYTE_BLOCK_MASK; - } - else - limit = upto + firstSize - 4; + if (startIndex + firstSize >= endIndex) { + // There is only this one slice to read + limit = endIndex & DocumentsWriter::BYTE_BLOCK_MASK; + } else { + limit = upto + firstSize - 4; } +} - bool ByteSliceReader::eof() - { - BOOST_ASSERT(upto + bufferOffset <= endIndex); - return (upto + bufferOffset == endIndex); - } +bool ByteSliceReader::eof() { + BOOST_ASSERT(upto + bufferOffset <= endIndex); + return (upto + bufferOffset == endIndex); +} - uint8_t ByteSliceReader::readByte() - { - BOOST_ASSERT(!eof()); - BOOST_ASSERT(upto <= limit); - if (upto == limit) - nextSlice(); - return buffer[upto++]; +uint8_t ByteSliceReader::readByte() { + BOOST_ASSERT(!eof()); + BOOST_ASSERT(upto <= limit); + if (upto == limit) { + nextSlice(); } + return buffer[upto++]; +} - int64_t ByteSliceReader::writeTo(const IndexOutputPtr& out) - { - int64_t size = 0; - while (true) - { - if (limit + bufferOffset == endIndex) - { - BOOST_ASSERT(endIndex - bufferOffset >= upto); - out->writeBytes(buffer.get(), upto, limit - upto); - size += limit - upto; - break; - } - else - { - out->writeBytes(buffer.get(), upto, limit - upto); - size += limit-upto; - nextSlice(); - } +int64_t ByteSliceReader::writeTo(const IndexOutputPtr& out) { + int64_t size = 0; + while (true) { + if (limit + bufferOffset == endIndex) { + BOOST_ASSERT(endIndex - bufferOffset >= upto); + out->writeBytes(buffer.get(), upto, limit - upto); + size += limit - upto; + break; + } else { + out->writeBytes(buffer.get(), upto, limit - upto); + size += limit-upto; + nextSlice(); } - return size; } + return size; +} - void ByteSliceReader::nextSlice() - { - // Skip to our next slice - int32_t nextIndex = ((buffer[limit] & 0xff) << 24) + ((buffer[1 + limit] & 0xff) << 16) + - ((buffer[2 + limit] & 0xff) << 8) + (buffer[3 + limit] & 0xff); +void ByteSliceReader::nextSlice() { + // Skip to our next slice + int32_t nextIndex = ((buffer[limit] & 0xff) << 24) + ((buffer[1 + limit] & 0xff) << 16) + + ((buffer[2 + limit] & 0xff) << 8) + (buffer[3 + limit] & 0xff); - level = ByteBlockPool::nextLevelArray[level]; - int32_t newSize = ByteBlockPool::levelSizeArray[level]; + level = ByteBlockPool::nextLevelArray[level]; + int32_t newSize = ByteBlockPool::levelSizeArray[level]; - bufferUpto = nextIndex / DocumentsWriter::BYTE_BLOCK_SIZE; - bufferOffset = bufferUpto * DocumentsWriter::BYTE_BLOCK_SIZE; + bufferUpto = nextIndex / DocumentsWriter::BYTE_BLOCK_SIZE; + bufferOffset = bufferUpto * DocumentsWriter::BYTE_BLOCK_SIZE; - this->buffer = pool->buffers[bufferUpto]; - upto = nextIndex & DocumentsWriter::BYTE_BLOCK_MASK; + this->buffer = pool->buffers[bufferUpto]; + upto = nextIndex & DocumentsWriter::BYTE_BLOCK_MASK; - if (nextIndex + newSize >= endIndex) - { - // We are advancing to the final slice - BOOST_ASSERT(endIndex - nextIndex > 0); - limit = endIndex - bufferOffset; - } - else - { - // This is not the final slice (subtract 4 for the forwarding address at the end of this new slice) - limit = upto + newSize - 4; - } + if (nextIndex + newSize >= endIndex) { + // We are advancing to the final slice + BOOST_ASSERT(endIndex - nextIndex > 0); + limit = endIndex - bufferOffset; + } else { + // This is not the final slice (subtract 4 for the forwarding address at the end of this new slice) + limit = upto + newSize - 4; } +} - void ByteSliceReader::readBytes(uint8_t* b, int32_t offset, int32_t length) - { - while (length > 0) - { - int32_t numLeft = limit - upto; - if (numLeft < length) - { - // Read entire slice - MiscUtils::arrayCopy(buffer.get(), upto, b, offset, numLeft); - offset += numLeft; - length -= numLeft; - nextSlice(); - } - else - { - // This slice is the last one - MiscUtils::arrayCopy(buffer.get(), upto, b, offset, length); - upto += length; - break; - } +void ByteSliceReader::readBytes(uint8_t* b, int32_t offset, int32_t length) { + while (length > 0) { + int32_t numLeft = limit - upto; + if (numLeft < length) { + // Read entire slice + MiscUtils::arrayCopy(buffer.get(), upto, b, offset, numLeft); + offset += numLeft; + length -= numLeft; + nextSlice(); + } else { + // This slice is the last one + MiscUtils::arrayCopy(buffer.get(), upto, b, offset, length); + upto += length; + break; } } +} - int64_t ByteSliceReader::getFilePointer() - { - boost::throw_exception(RuntimeException(L"not implemented")); - return 0; - } +int64_t ByteSliceReader::getFilePointer() { + boost::throw_exception(RuntimeException(L"not implemented")); + return 0; +} - int64_t ByteSliceReader::length() - { - boost::throw_exception(RuntimeException(L"not implemented")); - return 0; - } +int64_t ByteSliceReader::length() { + boost::throw_exception(RuntimeException(L"not implemented")); + return 0; +} - void ByteSliceReader::seek(int64_t pos) - { - boost::throw_exception(RuntimeException(L"not implemented")); - } +void ByteSliceReader::seek(int64_t pos) { + boost::throw_exception(RuntimeException(L"not implemented")); +} + +void ByteSliceReader::close() { + boost::throw_exception(RuntimeException(L"not implemented")); +} - void ByteSliceReader::close() - { - boost::throw_exception(RuntimeException(L"not implemented")); - } } diff --git a/src/core/index/ByteSliceWriter.cpp b/src/core/index/ByteSliceWriter.cpp index a9cefccd..c68bb2b1 100644 --- a/src/core/index/ByteSliceWriter.cpp +++ b/src/core/index/ByteSliceWriter.cpp @@ -9,72 +9,62 @@ #include "DocumentsWriter.h" #include "MiscUtils.h" -namespace Lucene -{ - ByteSliceWriter::ByteSliceWriter(const ByteBlockPoolPtr& pool) - { - this->pool = pool; - upto = 0; - offset0 = 0; - } +namespace Lucene { - ByteSliceWriter::~ByteSliceWriter() - { - } +ByteSliceWriter::ByteSliceWriter(const ByteBlockPoolPtr& pool) { + this->pool = pool; + upto = 0; + offset0 = 0; +} + +ByteSliceWriter::~ByteSliceWriter() { +} - void ByteSliceWriter::init(int32_t address) - { - slice = pool->buffers[address >> DocumentsWriter::BYTE_BLOCK_SHIFT]; +void ByteSliceWriter::init(int32_t address) { + slice = pool->buffers[address >> DocumentsWriter::BYTE_BLOCK_SHIFT]; + BOOST_ASSERT(slice); + upto = (address & DocumentsWriter::BYTE_BLOCK_MASK); + offset0 = address; + BOOST_ASSERT(upto < slice.size()); +} + +void ByteSliceWriter::writeByte(uint8_t b) { + BOOST_ASSERT(slice); + if (slice[upto] != 0) { + upto = pool->allocSlice(slice, upto); + slice = pool->buffer; + offset0 = pool->byteOffset; BOOST_ASSERT(slice); - upto = (address & DocumentsWriter::BYTE_BLOCK_MASK); - offset0 = address; - BOOST_ASSERT(upto < slice.size()); } + slice[upto++] = b; + BOOST_ASSERT(upto != slice.size()); +} - void ByteSliceWriter::writeByte(uint8_t b) - { - BOOST_ASSERT(slice); - if (slice[upto] != 0) - { +void ByteSliceWriter::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { + int32_t offsetEnd = offset + length; + while (offset < offsetEnd) { + if (slice[upto] != 0) { + // End marker upto = pool->allocSlice(slice, upto); slice = pool->buffer; offset0 = pool->byteOffset; - BOOST_ASSERT(slice); } - slice[upto++] = b; + + slice[upto++] = b[offset++]; BOOST_ASSERT(upto != slice.size()); } +} - void ByteSliceWriter::writeBytes(const uint8_t* b, int32_t offset, int32_t length) - { - int32_t offsetEnd = offset + length; - while (offset < offsetEnd) - { - if (slice[upto] != 0) - { - // End marker - upto = pool->allocSlice(slice, upto); - slice = pool->buffer; - offset0 = pool->byteOffset; - } - - slice[upto++] = b[offset++]; - BOOST_ASSERT(upto != slice.size()); - } - } +int32_t ByteSliceWriter::getAddress() { + return upto + (offset0 & DocumentsWriter::BYTE_BLOCK_NOT_MASK); +} - int32_t ByteSliceWriter::getAddress() - { - return upto + (offset0 & DocumentsWriter::BYTE_BLOCK_NOT_MASK); +void ByteSliceWriter::writeVInt(int32_t i) { + while ((i & ~0x7f) != 0) { + writeByte((uint8_t)((i & 0x7f) | 0x80)); + i = MiscUtils::unsignedShift(i, 7); } + writeByte((uint8_t)i); +} - void ByteSliceWriter::writeVInt(int32_t i) - { - while ((i & ~0x7f) != 0) - { - writeByte((uint8_t)((i & 0x7f) | 0x80)); - i = MiscUtils::unsignedShift(i, 7); - } - writeByte((uint8_t)i); - } } diff --git a/src/core/index/CharBlockPool.cpp b/src/core/index/CharBlockPool.cpp index 8f8efdf1..b552d7cd 100644 --- a/src/core/index/CharBlockPool.cpp +++ b/src/core/index/CharBlockPool.cpp @@ -8,39 +8,37 @@ #include "CharBlockPool.h" #include "DocumentsWriter.h" -namespace Lucene -{ - CharBlockPool::CharBlockPool(const DocumentsWriterPtr& docWriter) - { - numBuffer = 0; - bufferUpto = -1; - charUpto = DocumentsWriter::CHAR_BLOCK_SIZE; - charOffset = -DocumentsWriter::CHAR_BLOCK_SIZE; - buffers = Collection::newInstance(10); - this->_docWriter = docWriter; - } +namespace Lucene { - CharBlockPool::~CharBlockPool() - { - } +CharBlockPool::CharBlockPool(const DocumentsWriterPtr& docWriter) { + numBuffer = 0; + bufferUpto = -1; + charUpto = DocumentsWriter::CHAR_BLOCK_SIZE; + charOffset = -DocumentsWriter::CHAR_BLOCK_SIZE; + buffers = Collection::newInstance(10); + this->_docWriter = docWriter; +} - void CharBlockPool::reset() - { - DocumentsWriterPtr(_docWriter)->recycleCharBlocks(buffers, 1 + bufferUpto); - bufferUpto = -1; - charUpto = DocumentsWriter::CHAR_BLOCK_SIZE; - charOffset = -DocumentsWriter::CHAR_BLOCK_SIZE; - } +CharBlockPool::~CharBlockPool() { +} - void CharBlockPool::nextBuffer() - { - if (1 + bufferUpto == buffers.size()) - buffers.resize((int32_t)((double)buffers.size() * 1.5)); - buffers[1 + bufferUpto] = DocumentsWriterPtr(_docWriter)->getCharBlock(); - buffer = buffers[1 + bufferUpto]; - ++bufferUpto; +void CharBlockPool::reset() { + DocumentsWriterPtr(_docWriter)->recycleCharBlocks(buffers, 1 + bufferUpto); + bufferUpto = -1; + charUpto = DocumentsWriter::CHAR_BLOCK_SIZE; + charOffset = -DocumentsWriter::CHAR_BLOCK_SIZE; +} - charUpto = 0; - charOffset += DocumentsWriter::CHAR_BLOCK_SIZE; +void CharBlockPool::nextBuffer() { + if (1 + bufferUpto == buffers.size()) { + buffers.resize((int32_t)((double)buffers.size() * 1.5)); } + buffers[1 + bufferUpto] = DocumentsWriterPtr(_docWriter)->getCharBlock(); + buffer = buffers[1 + bufferUpto]; + ++bufferUpto; + + charUpto = 0; + charOffset += DocumentsWriter::CHAR_BLOCK_SIZE; +} + } diff --git a/src/core/index/CheckIndex.cpp b/src/core/index/CheckIndex.cpp index a6279efa..289cb27e 100644 --- a/src/core/index/CheckIndex.cpp +++ b/src/core/index/CheckIndex.cpp @@ -22,738 +22,648 @@ #include "InfoStream.h" #include "StringUtils.h" -namespace Lucene -{ - bool CheckIndex::_assertsOn = false; +namespace Lucene { - CheckIndex::CheckIndex(const DirectoryPtr& dir) - { - this->dir = dir; - } +bool CheckIndex::_assertsOn = false; - CheckIndex::~CheckIndex() - { - } +CheckIndex::CheckIndex(const DirectoryPtr& dir) { + this->dir = dir; +} + +CheckIndex::~CheckIndex() { +} - void CheckIndex::setInfoStream(const InfoStreamPtr& out) - { - infoStream = out; +void CheckIndex::setInfoStream(const InfoStreamPtr& out) { + infoStream = out; +} + +void CheckIndex::msg(const String& msg) { + if (infoStream) { + *infoStream << msg << L"\n"; } +} + +IndexStatusPtr CheckIndex::checkIndex() { + return checkIndex(Collection()); +} - void CheckIndex::msg(const String& msg) - { - if (infoStream) - *infoStream << msg << L"\n"; +IndexStatusPtr CheckIndex::checkIndex(Collection onlySegments) { + SegmentInfosPtr sis(newLucene()); + IndexStatusPtr result(newLucene()); + result->dir = dir; + try { + sis->read(dir); + } catch (...) { + msg(L"ERROR: could not read any segments file in directory"); + result->missingSegments = true; + return result; } - IndexStatusPtr CheckIndex::checkIndex() - { - return checkIndex(Collection()); + int32_t numSegments = sis->size(); + String segmentsFileName(sis->getCurrentSegmentFileName()); + IndexInputPtr input; + + try { + input = dir->openInput(segmentsFileName); + } catch (...) { + msg(L"ERROR: could not open segments file in directory"); + result->cantOpenSegments = true; + return result; } - IndexStatusPtr CheckIndex::checkIndex(Collection onlySegments) - { - SegmentInfosPtr sis(newLucene()); - IndexStatusPtr result(newLucene()); - result->dir = dir; - try - { - sis->read(dir); - } - catch (...) - { - msg(L"ERROR: could not read any segments file in directory"); - result->missingSegments = true; - return result; + int32_t format = 0; + try { + format = input->readInt(); + } catch (...) { + msg(L"ERROR: could not read segment file version in directory"); + result->missingSegmentVersion = true; + if (input) { + input->close(); } + return result; + } + if (input) { + input->close(); + } - int32_t numSegments = sis->size(); - String segmentsFileName(sis->getCurrentSegmentFileName()); - IndexInputPtr input; + String sFormat; + bool skip = false; - try - { - input = dir->openInput(segmentsFileName); - } - catch (...) - { - msg(L"ERROR: could not open segments file in directory"); - result->cantOpenSegments = true; - return result; + if (format == SegmentInfos::FORMAT) { + sFormat = L"FORMAT [Lucene Pre-2.1]"; + } + if (format == SegmentInfos::FORMAT_LOCKLESS) { + sFormat = L"FORMAT_LOCKLESS [Lucene 2.1]"; + } else if (format == SegmentInfos::FORMAT_SINGLE_NORM_FILE) { + sFormat = L"FORMAT_SINGLE_NORM_FILE [Lucene 2.2]"; + } else if (format == SegmentInfos::FORMAT_SHARED_DOC_STORE) { + sFormat = L"FORMAT_SHARED_DOC_STORE [Lucene 2.3]"; + } else { + if (format == SegmentInfos::FORMAT_CHECKSUM) { + sFormat = L"FORMAT_CHECKSUM [Lucene 2.4]"; + } else if (format == SegmentInfos::FORMAT_DEL_COUNT) { + sFormat = L"FORMAT_DEL_COUNT [Lucene 2.4]"; + } else if (format == SegmentInfos::FORMAT_HAS_PROX) { + sFormat = L"FORMAT_HAS_PROX [Lucene 2.4]"; + } else if (format == SegmentInfos::FORMAT_USER_DATA) { + sFormat = L"FORMAT_USER_DATA [Lucene 2.9]"; + } else if (format == SegmentInfos::FORMAT_DIAGNOSTICS) { + sFormat = L"FORMAT_DIAGNOSTICS [Lucene 2.9]"; + } else if (format < SegmentInfos::CURRENT_FORMAT) { + sFormat = L"int=" + StringUtils::toString(format) + L" [newer version of Lucene than this tool]"; + skip = true; + } else { + sFormat = StringUtils::toString(format) + L" [Lucene 1.3 or prior]"; } + } - int32_t format = 0; - try - { - format = input->readInt(); - } - catch (...) - { - msg(L"ERROR: could not read segment file version in directory"); - result->missingSegmentVersion = true; - if (input) - input->close(); - return result; - } - if (input) - input->close(); + result->segmentsFileName = segmentsFileName; + result->numSegments = numSegments; + result->segmentFormat = sFormat; + result->userData = sis->getUserData(); + String userDataString; + if (!sis->getUserData().empty()) { + userDataString = L" userData(size)=" + StringUtils::toString(sis->getUserData().size()); + } - String sFormat; - bool skip = false; - - if (format == SegmentInfos::FORMAT) - sFormat = L"FORMAT [Lucene Pre-2.1]"; - if (format == SegmentInfos::FORMAT_LOCKLESS) - sFormat = L"FORMAT_LOCKLESS [Lucene 2.1]"; - else if (format == SegmentInfos::FORMAT_SINGLE_NORM_FILE) - sFormat = L"FORMAT_SINGLE_NORM_FILE [Lucene 2.2]"; - else if (format == SegmentInfos::FORMAT_SHARED_DOC_STORE) - sFormat = L"FORMAT_SHARED_DOC_STORE [Lucene 2.3]"; - else - { - if (format == SegmentInfos::FORMAT_CHECKSUM) - sFormat = L"FORMAT_CHECKSUM [Lucene 2.4]"; - else if (format == SegmentInfos::FORMAT_DEL_COUNT) - sFormat = L"FORMAT_DEL_COUNT [Lucene 2.4]"; - else if (format == SegmentInfos::FORMAT_HAS_PROX) - sFormat = L"FORMAT_HAS_PROX [Lucene 2.4]"; - else if (format == SegmentInfos::FORMAT_USER_DATA) - sFormat = L"FORMAT_USER_DATA [Lucene 2.9]"; - else if (format == SegmentInfos::FORMAT_DIAGNOSTICS) - sFormat = L"FORMAT_DIAGNOSTICS [Lucene 2.9]"; - else if (format < SegmentInfos::CURRENT_FORMAT) - { - sFormat = L"int=" + StringUtils::toString(format) + L" [newer version of Lucene than this tool]"; - skip = true; - } - else - sFormat = StringUtils::toString(format) + L" [Lucene 1.3 or prior]"; - } + msg(L"Segments file=" + segmentsFileName + L" numSegments=" + StringUtils::toString(numSegments) + + L" version=" + sFormat + userDataString); - result->segmentsFileName = segmentsFileName; - result->numSegments = numSegments; - result->segmentFormat = sFormat; - result->userData = sis->getUserData(); - String userDataString; - if (!sis->getUserData().empty()) - userDataString = L" userData(size)=" + StringUtils::toString(sis->getUserData().size()); - - msg(L"Segments file=" + segmentsFileName + L" numSegments=" + StringUtils::toString(numSegments) + - L" version=" + sFormat + userDataString); - - if (onlySegments) - { - result->partial = true; - msg(L"\nChecking only these segments:"); - for (Collection::iterator s = onlySegments.begin(); s != onlySegments.end(); ++s) - msg(L" " + *s); - result->segmentsChecked.addAll(onlySegments.begin(), onlySegments.end()); - msg(L":"); + if (onlySegments) { + result->partial = true; + msg(L"\nChecking only these segments:"); + for (Collection::iterator s = onlySegments.begin(); s != onlySegments.end(); ++s) { + msg(L" " + *s); } + result->segmentsChecked.addAll(onlySegments.begin(), onlySegments.end()); + msg(L":"); + } + + if (skip) { + msg(L"\nERROR: this index appears to be created by a newer version of Lucene than this tool was compiled on;" \ + L" please re-compile this tool on the matching version of Lucene; exiting"); + result->toolOutOfDate = true; + return result; + } + + result->newSegments = boost::dynamic_pointer_cast(sis->clone()); + result->newSegments->clear(); - if (skip) - { - msg(L"\nERROR: this index appears to be created by a newer version of Lucene than this tool was compiled on;" \ - L" please re-compile this tool on the matching version of Lucene; exiting"); - result->toolOutOfDate = true; - return result; + for (int32_t i = 0; i < numSegments; ++i) { + SegmentInfoPtr info(sis->info(i)); + if (onlySegments && !onlySegments.contains(info->name)) { + continue; } + SegmentInfoStatusPtr segInfoStat(newLucene()); + result->segmentInfos.add(segInfoStat); + msg(L" name=" + info->name + L" docCount=" + StringUtils::toString(info->docCount)); + segInfoStat->name = info->name; + segInfoStat->docCount = info->docCount; + + int32_t toLoseDocCount = info->docCount; + + SegmentReaderPtr reader; + + try { + msg(L" compound=" + StringUtils::toString(info->getUseCompoundFile())); + segInfoStat->compound = info->getUseCompoundFile(); + msg(L" hasProx=" + StringUtils::toString(info->getHasProx())); + segInfoStat->hasProx = info->getHasProx(); + msg(L" numFiles=" + StringUtils::toString(info->files().size())); + segInfoStat->numFiles = info->files().size(); + msg(L" size (MB)=" + StringUtils::toString((double)info->sizeInBytes() / (double)(1024 * 1024))); + segInfoStat->sizeMB = (double)info->sizeInBytes() / (double)(1024 * 1024); + MapStringString diagnostics(info->getDiagnostics()); + segInfoStat->diagnostics = diagnostics; + if (!diagnostics.empty()) { + msg(L" diagnostics (size)= " + StringUtils::toString(diagnostics.size())); + } + + int32_t docStoreOffset = info->getDocStoreOffset(); + if (docStoreOffset != -1) { + msg(L" docStoreOffset=" + StringUtils::toString(docStoreOffset)); + segInfoStat->docStoreOffset = docStoreOffset; + msg(L" docStoreSegment=" + info->getDocStoreSegment()); + segInfoStat->docStoreSegment = info->getDocStoreSegment(); + msg(L" docStoreIsCompoundFile=" + StringUtils::toString(info->getDocStoreIsCompoundFile())); + segInfoStat->docStoreCompoundFile = info->getDocStoreIsCompoundFile(); + } + String delFileName(info->getDelFileName()); + if (delFileName.empty()) { + msg(L" no deletions"); + segInfoStat->hasDeletions = false; + } else { + msg(L" has deletions [delFileName=" + delFileName + L"]"); + segInfoStat->hasDeletions = true; + segInfoStat->deletionsFileName = delFileName; + } + msg(L" test: open reader........."); + reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); + + segInfoStat->openReaderPassed = true; - result->newSegments = boost::dynamic_pointer_cast(sis->clone()); - result->newSegments->clear(); - - for (int32_t i = 0; i < numSegments; ++i) - { - SegmentInfoPtr info(sis->info(i)); - if (onlySegments && !onlySegments.contains(info->name)) - continue; - SegmentInfoStatusPtr segInfoStat(newLucene()); - result->segmentInfos.add(segInfoStat); - msg(L" name=" + info->name + L" docCount=" + StringUtils::toString(info->docCount)); - segInfoStat->name = info->name; - segInfoStat->docCount = info->docCount; - - int32_t toLoseDocCount = info->docCount; - - SegmentReaderPtr reader; - - try - { - msg(L" compound=" + StringUtils::toString(info->getUseCompoundFile())); - segInfoStat->compound = info->getUseCompoundFile(); - msg(L" hasProx=" + StringUtils::toString(info->getHasProx())); - segInfoStat->hasProx = info->getHasProx(); - msg(L" numFiles=" + StringUtils::toString(info->files().size())); - segInfoStat->numFiles = info->files().size(); - msg(L" size (MB)=" + StringUtils::toString((double)info->sizeInBytes() / (double)(1024 * 1024))); - segInfoStat->sizeMB = (double)info->sizeInBytes() / (double)(1024 * 1024); - MapStringString diagnostics(info->getDiagnostics()); - segInfoStat->diagnostics = diagnostics; - if (!diagnostics.empty()) - msg(L" diagnostics (size)= " + StringUtils::toString(diagnostics.size())); - - int32_t docStoreOffset = info->getDocStoreOffset(); - if (docStoreOffset != -1) - { - msg(L" docStoreOffset=" + StringUtils::toString(docStoreOffset)); - segInfoStat->docStoreOffset = docStoreOffset; - msg(L" docStoreSegment=" + info->getDocStoreSegment()); - segInfoStat->docStoreSegment = info->getDocStoreSegment(); - msg(L" docStoreIsCompoundFile=" + StringUtils::toString(info->getDocStoreIsCompoundFile())); - segInfoStat->docStoreCompoundFile = info->getDocStoreIsCompoundFile(); + int32_t numDocs = reader->numDocs(); + toLoseDocCount = numDocs; + if (reader->hasDeletions()) { + if (reader->deletedDocs->count() != info->getDelCount()) { + boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + + L" vs deletedDocs.count()=" + StringUtils::toString(reader->deletedDocs->count()))); } - String delFileName(info->getDelFileName()); - if (delFileName.empty()) - { - msg(L" no deletions"); - segInfoStat->hasDeletions = false; + if (reader->deletedDocs->count() > reader->maxDoc()) { + boost::throw_exception(RuntimeException(L"too many deleted docs: maxDoc()=" + StringUtils::toString(reader->maxDoc()) + + L" vs deletedDocs.count()=" + StringUtils::toString(reader->deletedDocs->count()))); } - else - { - msg(L" has deletions [delFileName=" + delFileName + L"]"); - segInfoStat->hasDeletions = true; - segInfoStat->deletionsFileName = delFileName; + if (info->docCount - numDocs != info->getDelCount()) { + boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + + L" vs reader=" + StringUtils::toString((info->docCount - numDocs)))); } - msg(L" test: open reader........."); - reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); - - segInfoStat->openReaderPassed = true; - - int32_t numDocs = reader->numDocs(); - toLoseDocCount = numDocs; - if (reader->hasDeletions()) - { - if (reader->deletedDocs->count() != info->getDelCount()) - { - boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + - L" vs deletedDocs.count()=" + StringUtils::toString(reader->deletedDocs->count()))); - } - if (reader->deletedDocs->count() > reader->maxDoc()) - { - boost::throw_exception(RuntimeException(L"too many deleted docs: maxDoc()=" + StringUtils::toString(reader->maxDoc()) + - L" vs deletedDocs.count()=" + StringUtils::toString(reader->deletedDocs->count()))); - } - if (info->docCount - numDocs != info->getDelCount()) - { - boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + - L" vs reader=" + StringUtils::toString((info->docCount - numDocs)))); - } - segInfoStat->numDeleted = info->docCount - numDocs; - msg(L"OK [" + StringUtils::toString(segInfoStat->numDeleted) + L" deleted docs]"); + segInfoStat->numDeleted = info->docCount - numDocs; + msg(L"OK [" + StringUtils::toString(segInfoStat->numDeleted) + L" deleted docs]"); + } else { + if (info->getDelCount() != 0) { + boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + + L" vs reader=" + StringUtils::toString(info->docCount - numDocs))); } - else - { - if (info->getDelCount() != 0) - { - boost::throw_exception(RuntimeException(L"delete count mismatch: info=" + StringUtils::toString(info->getDelCount()) + - L" vs reader=" + StringUtils::toString(info->docCount - numDocs))); - } - msg(L"OK"); - } - if (reader->maxDoc() != info->docCount) - { - boost::throw_exception(RuntimeException(L"SegmentReader.maxDoc() " + StringUtils::toString(reader->maxDoc()) + - L" != SegmentInfos.docCount " + StringUtils::toString(info->docCount))); - } - msg(L" test: fields.............."); - HashSet fieldNames(reader->getFieldNames(IndexReader::FIELD_OPTION_ALL)); - msg(L"OK [" + StringUtils::toString(fieldNames.size()) + L" fields]"); - segInfoStat->numFields = fieldNames.size(); - - // Test Field Norms - segInfoStat->fieldNormStatus = testFieldNorms(Collection::newInstance(fieldNames.begin(), fieldNames.end()), reader); - - // Test the Term Index - segInfoStat->termIndexStatus = testTermIndex(info, reader); - - // Test Stored Fields - segInfoStat->storedFieldStatus = testStoredFields(info, reader); - - // Test Term Vectors - segInfoStat->termVectorStatus = testTermVectors(info, reader); - - // Rethrow the first exception we encountered. This will cause stats for failed segments to be incremented properly - if (!segInfoStat->fieldNormStatus->error.isNull()) - boost::throw_exception(RuntimeException(L"Field Norm test failed")); - else if (!segInfoStat->termIndexStatus->error.isNull()) - boost::throw_exception(RuntimeException(L"Term Index test failed")); - else if (!segInfoStat->storedFieldStatus->error.isNull()) - boost::throw_exception(RuntimeException(L"Stored Field test failed")); - else if (!segInfoStat->termVectorStatus->error.isNull()) - boost::throw_exception(RuntimeException(L"Term Vector test failed")); - - msg(L""); + msg(L"OK"); } - catch (...) - { - msg(L"FAILED"); - String comment(L"fixIndex() would remove reference to this segment"); - msg(L" WARNING: " + comment + L"; full exception:"); - msg(L""); - result->totLoseDocCount += toLoseDocCount; - ++result->numBadSegments; - - if (reader) - reader->close(); - - continue; + if (reader->maxDoc() != info->docCount) { + boost::throw_exception(RuntimeException(L"SegmentReader.maxDoc() " + StringUtils::toString(reader->maxDoc()) + + L" != SegmentInfos.docCount " + StringUtils::toString(info->docCount))); } - if (reader) - reader->close(); + msg(L" test: fields.............."); + HashSet fieldNames(reader->getFieldNames(IndexReader::FIELD_OPTION_ALL)); + msg(L"OK [" + StringUtils::toString(fieldNames.size()) + L" fields]"); + segInfoStat->numFields = fieldNames.size(); - // Keeper - result->newSegments->add(boost::dynamic_pointer_cast(info->clone())); - } + // Test Field Norms + segInfoStat->fieldNormStatus = testFieldNorms(Collection::newInstance(fieldNames.begin(), fieldNames.end()), reader); + + // Test the Term Index + segInfoStat->termIndexStatus = testTermIndex(info, reader); + + // Test Stored Fields + segInfoStat->storedFieldStatus = testStoredFields(info, reader); + + // Test Term Vectors + segInfoStat->termVectorStatus = testTermVectors(info, reader); + + // Rethrow the first exception we encountered. This will cause stats for failed segments to be incremented properly + if (!segInfoStat->fieldNormStatus->error.isNull()) { + boost::throw_exception(RuntimeException(L"Field Norm test failed")); + } else if (!segInfoStat->termIndexStatus->error.isNull()) { + boost::throw_exception(RuntimeException(L"Term Index test failed")); + } else if (!segInfoStat->storedFieldStatus->error.isNull()) { + boost::throw_exception(RuntimeException(L"Stored Field test failed")); + } else if (!segInfoStat->termVectorStatus->error.isNull()) { + boost::throw_exception(RuntimeException(L"Term Vector test failed")); + } + + msg(L""); + } catch (...) { + msg(L"FAILED"); + String comment(L"fixIndex() would remove reference to this segment"); + msg(L" WARNING: " + comment + L"; full exception:"); + msg(L""); + result->totLoseDocCount += toLoseDocCount; + ++result->numBadSegments; + + if (reader) { + reader->close(); + } - if (result->numBadSegments == 0) - { - result->clean = true; - msg(L"No problems were detected with this index.\n"); + continue; } - else - { - msg(L"WARNING: " + StringUtils::toString(result->numBadSegments) + - L" broken segments (containing " + StringUtils::toString(result->totLoseDocCount) + - L" documents) detected"); + if (reader) { + reader->close(); } - return result; + // Keeper + result->newSegments->add(boost::dynamic_pointer_cast(info->clone())); } - FieldNormStatusPtr CheckIndex::testFieldNorms(Collection fieldNames, const SegmentReaderPtr& reader) - { - FieldNormStatusPtr status(newLucene()); + if (result->numBadSegments == 0) { + result->clean = true; + msg(L"No problems were detected with this index.\n"); + } else { + msg(L"WARNING: " + StringUtils::toString(result->numBadSegments) + + L" broken segments (containing " + StringUtils::toString(result->totLoseDocCount) + + L" documents) detected"); + } - try - { - // Test Field Norms - msg(L" test: field norms........."); - - ByteArray b(ByteArray::newInstance(reader->maxDoc())); - for (Collection::iterator fieldName = fieldNames.begin(); fieldName != fieldNames.end(); ++fieldName) - { - if (reader->hasNorms(*fieldName)) - { - reader->norms(*fieldName, b, 0); - ++status->totFields; - } - } + return result; +} - msg(L"OK [" + StringUtils::toString(status->totFields) + L" fields]"); - } - catch (LuceneException& e) - { - msg(L"ERROR [" + e.getError() + L"]"); - status->error = e; +FieldNormStatusPtr CheckIndex::testFieldNorms(Collection fieldNames, const SegmentReaderPtr& reader) { + FieldNormStatusPtr status(newLucene()); + + try { + // Test Field Norms + msg(L" test: field norms........."); + + ByteArray b(ByteArray::newInstance(reader->maxDoc())); + for (Collection::iterator fieldName = fieldNames.begin(); fieldName != fieldNames.end(); ++fieldName) { + if (reader->hasNorms(*fieldName)) { + reader->norms(*fieldName, b, 0); + ++status->totFields; + } } - return status; + msg(L"OK [" + StringUtils::toString(status->totFields) + L" fields]"); + } catch (LuceneException& e) { + msg(L"ERROR [" + e.getError() + L"]"); + status->error = e; } - TermIndexStatusPtr CheckIndex::testTermIndex(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) - { - TermIndexStatusPtr status(newLucene()); - - try - { - msg(L" test: terms, freq, prox..."); - - TermEnumPtr termEnum(reader->terms()); - TermPositionsPtr termPositions(reader->termPositions()); - - // Used only to count up # deleted docs for this term - MySegmentTermDocsPtr myTermDocs(newLucene(reader)); - - int32_t maxDoc = reader->maxDoc(); - - while (termEnum->next()) - { - ++status->termCount; - TermPtr term(termEnum->term()); - int32_t docFreq = termEnum->docFreq(); - termPositions->seek(term); - int32_t lastDoc = -1; - int32_t freq0 = 0; - status->totFreq += docFreq; - while (termPositions->next()) - { - ++freq0; - int32_t doc = termPositions->doc(); - int32_t freq = termPositions->freq(); - if (doc <= lastDoc) - { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + - L" <= lastDoc " + StringUtils::toString(lastDoc))); - } - if (doc >= maxDoc) - { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + - L" >= maxDoc " + StringUtils::toString(maxDoc))); - } + return status; +} - lastDoc = doc; - if (freq <= 0) - { +TermIndexStatusPtr CheckIndex::testTermIndex(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) { + TermIndexStatusPtr status(newLucene()); + + try { + msg(L" test: terms, freq, prox..."); + + TermEnumPtr termEnum(reader->terms()); + TermPositionsPtr termPositions(reader->termPositions()); + + // Used only to count up # deleted docs for this term + MySegmentTermDocsPtr myTermDocs(newLucene(reader)); + + int32_t maxDoc = reader->maxDoc(); + + while (termEnum->next()) { + ++status->termCount; + TermPtr term(termEnum->term()); + int32_t docFreq = termEnum->docFreq(); + termPositions->seek(term); + int32_t lastDoc = -1; + int32_t freq0 = 0; + status->totFreq += docFreq; + while (termPositions->next()) { + ++freq0; + int32_t doc = termPositions->doc(); + int32_t freq = termPositions->freq(); + if (doc <= lastDoc) { + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + + L" <= lastDoc " + StringUtils::toString(lastDoc))); + } + if (doc >= maxDoc) { + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + + L" >= maxDoc " + StringUtils::toString(maxDoc))); + } + + lastDoc = doc; + if (freq <= 0) { + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + + L": freq " + StringUtils::toString(freq) + + L" is out of bounds")); + } + + int32_t lastPos = -1; + status->totPos += freq; + for (int32_t j = 0; j < freq; ++j) { + int32_t pos = termPositions->nextPosition(); + if (pos < -1) { boost::throw_exception(RuntimeException(L"term " + term->toString() + L": doc " + StringUtils::toString(doc) + - L": freq " + StringUtils::toString(freq) + + L": pos " + StringUtils::toString(pos) + L" is out of bounds")); } - - int32_t lastPos = -1; - status->totPos += freq; - for (int32_t j = 0; j < freq; ++j) - { - int32_t pos = termPositions->nextPosition(); - if (pos < -1) - { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + - L": pos " + StringUtils::toString(pos) + - L" is out of bounds")); - } - if (pos < lastPos) - { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L": doc " + StringUtils::toString(doc) + - L": pos " + StringUtils::toString(pos) + - L" < lastPos " + StringUtils::toString(lastPos))); - } - lastPos = pos; - } - } - - // Now count how many deleted docs occurred in this term - int32_t delCount; - if (reader->hasDeletions()) - { - myTermDocs->seek(term); - while (myTermDocs->next()) - { + if (pos < lastPos) { + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L": doc " + StringUtils::toString(doc) + + L": pos " + StringUtils::toString(pos) + + L" < lastPos " + StringUtils::toString(lastPos))); } - delCount = myTermDocs->delCount; + lastPos = pos; } - else - delCount = 0; + } - if (freq0 + delCount != docFreq) - { - boost::throw_exception(RuntimeException(L"term " + term->toString() + - L"docFreq=" + StringUtils::toString(docFreq) + - L" != num docs seen " + StringUtils::toString(freq0) + - L" + num docs deleted " + StringUtils::toString(delCount))); + // Now count how many deleted docs occurred in this term + int32_t delCount; + if (reader->hasDeletions()) { + myTermDocs->seek(term); + while (myTermDocs->next()) { } + delCount = myTermDocs->delCount; + } else { + delCount = 0; } - msg(L"OK [" + StringUtils::toString(status->termCount) + L" terms; " + StringUtils::toString(status->totFreq) + - L" terms/docs pairs; " + StringUtils::toString(status->totPos) + L" tokens]"); - } - catch (LuceneException& e) - { - msg(L"ERROR [" + e.getError() + L"]"); - status->error = e; + if (freq0 + delCount != docFreq) { + boost::throw_exception(RuntimeException(L"term " + term->toString() + + L"docFreq=" + StringUtils::toString(docFreq) + + L" != num docs seen " + StringUtils::toString(freq0) + + L" + num docs deleted " + StringUtils::toString(delCount))); + } } - return status; + msg(L"OK [" + StringUtils::toString(status->termCount) + L" terms; " + StringUtils::toString(status->totFreq) + + L" terms/docs pairs; " + StringUtils::toString(status->totPos) + L" tokens]"); + } catch (LuceneException& e) { + msg(L"ERROR [" + e.getError() + L"]"); + status->error = e; } - StoredFieldStatusPtr CheckIndex::testStoredFields(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) - { - StoredFieldStatusPtr status(newLucene()); - - try - { - msg(L" test: stored fields......."); - - // Scan stored fields for all documents - for (int32_t j = 0; j < info->docCount; ++j) - { - if (!reader->isDeleted(j)) - { - ++status->docCount; - DocumentPtr doc(reader->document(j, FieldSelectorPtr())); - status->totFields += doc->getFields().size(); - } - } - - // Validate docCount - if (status->docCount != reader->numDocs()) - { - boost::throw_exception(RuntimeException(L"docCount=" + StringUtils::toString(status->docCount) + - L" but saw " + StringUtils::toString(status->docCount) + - L" undeleted docs")); - } + return status; +} - msg(L"OK [" + StringUtils::toString(status->totFields) + L" total field count; avg " + - StringUtils::toString((double)status->totFields / (double)status->docCount) + L" fields per doc]"); - } - catch (LuceneException& e) - { - msg(L"ERROR [" + e.getError() + L"]"); - status->error = e; - } +StoredFieldStatusPtr CheckIndex::testStoredFields(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) { + StoredFieldStatusPtr status(newLucene()); - return status; - } + try { + msg(L" test: stored fields......."); - TermVectorStatusPtr CheckIndex::testTermVectors(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) - { - TermVectorStatusPtr status(newLucene()); - - try - { - msg(L" test: term vectors........"); - - for (int32_t j = 0; j < info->docCount; ++j) - { - if (!reader->isDeleted(j)) - { - ++status->docCount; - Collection tfv(reader->getTermFreqVectors(j)); - if (tfv) - status->totVectors += tfv.size(); - } + // Scan stored fields for all documents + for (int32_t j = 0; j < info->docCount; ++j) { + if (!reader->isDeleted(j)) { + ++status->docCount; + DocumentPtr doc(reader->document(j, FieldSelectorPtr())); + status->totFields += doc->getFields().size(); } - - msg(L"OK [" + StringUtils::toString(status->totVectors) + L" total vector count; avg " + - StringUtils::toString((double)status->totVectors / (double)status->docCount) + L" term/freq vector fields per doc]"); } - catch (LuceneException& e) - { - msg(L"ERROR [" + e.getError() + L"]"); - status->error = e; + + // Validate docCount + if (status->docCount != reader->numDocs()) { + boost::throw_exception(RuntimeException(L"docCount=" + StringUtils::toString(status->docCount) + + L" but saw " + StringUtils::toString(status->docCount) + + L" undeleted docs")); } - return status; + msg(L"OK [" + StringUtils::toString(status->totFields) + L" total field count; avg " + + StringUtils::toString((double)status->totFields / (double)status->docCount) + L" fields per doc]"); + } catch (LuceneException& e) { + msg(L"ERROR [" + e.getError() + L"]"); + status->error = e; } - void CheckIndex::fixIndex(const IndexStatusPtr& result) - { - if (result->partial) - boost::throw_exception(IllegalArgumentException(L"can only fix an index that was fully checked (this status checked a subset of segments)")); - result->newSegments->commit(result->dir); - } + return status; +} - bool CheckIndex::testAsserts() - { - _assertsOn = true; - return true; - } +TermVectorStatusPtr CheckIndex::testTermVectors(const SegmentInfoPtr& info, const SegmentReaderPtr& reader) { + TermVectorStatusPtr status(newLucene()); - bool CheckIndex::assertsOn() - { - BOOST_ASSERT(testAsserts()); - return _assertsOn; - } + try { + msg(L" test: term vectors........"); - int CheckIndex::main(Collection args) - { - bool doFix = false; - Collection onlySegments(Collection::newInstance()); - String indexPath; - for (Collection::iterator arg = args.begin(); arg != args.end(); ++arg) - { - if (*arg == L"-fix") - doFix = true; - else if (*arg == L"-segment") - { - if (arg + 1 == args.end()) - { - std::wcout << L"ERROR: missing name for -segment option\n"; - return 1; + for (int32_t j = 0; j < info->docCount; ++j) { + if (!reader->isDeleted(j)) { + ++status->docCount; + Collection tfv(reader->getTermFreqVectors(j)); + if (tfv) { + status->totVectors += tfv.size(); } - ++arg; - onlySegments.add(*arg); - } - else - { - if (!indexPath.empty()) - { - std::wcout << L"ERROR: unexpected extra argument '" << *arg << L"'\n"; - return 1; - } - indexPath = *arg; } } - if (indexPath.empty()) - { - std::wcout << L"\nERROR: index path not specified\n"; - std::wcout << L"Usage: CheckIndex pathToIndex [-fix] [-segment X] [-segment Y]\n"; - std::wcout << L"\n"; - std::wcout << L" -fix: actually write a new segments_N file, removing any problematic segments\n"; - std::wcout << L" -segment X: only check the specified segments. This can be specified multiple\n"; - std::wcout << L" times, to check more than one segment, eg '-segment _2 -segment _a'.\n"; - std::wcout << L" You can't use this with the -fix option\n"; - std::wcout << L"\n"; - std::wcout << L"**WARNING**: -fix should only be used on an emergency basis as it will cause\n"; - std::wcout << L"documents (perhaps many) to be permanently removed from the index. Always make\n"; - std::wcout << L"a backup copy of your index before running this! Do not run this tool on an index\n"; - std::wcout << L"that is actively being written to. You have been warned!\n"; - std::wcout << L"\n"; - std::wcout << L"Run without -fix, this tool will open the index, report version information\n"; - std::wcout << L"and report any exceptions it hits and what action it would take if -fix were\n"; - std::wcout << L"specified. With -fix, this tool will remove any segments that have issues and\n"; - std::wcout << L"write a new segments_N file. This means all documents contained in the affected\n"; - std::wcout << L"segments will be removed.\n"; - std::wcout << L"\n"; - std::wcout << L"This tool exits with exit code 1 if the index cannot be opened or has any\n"; - std::wcout << L"corruption, else 0.\n\n"; - return 1; - } + msg(L"OK [" + StringUtils::toString(status->totVectors) + L" total vector count; avg " + + StringUtils::toString((double)status->totVectors / (double)status->docCount) + L" term/freq vector fields per doc]"); + } catch (LuceneException& e) { + msg(L"ERROR [" + e.getError() + L"]"); + status->error = e; + } - if (!assertsOn()) - std::wcout << L"\nNOTE: testing will be more thorough if you run with '-ea', so assertions are enabled\n"; + return status; +} - if (onlySegments.empty()) - onlySegments.reset(); - else if (doFix) - { - std::wcout << L"ERROR: cannot specify both -fix and -segment\n"; - return 1; - } +void CheckIndex::fixIndex(const IndexStatusPtr& result) { + if (result->partial) { + boost::throw_exception(IllegalArgumentException(L"can only fix an index that was fully checked (this status checked a subset of segments)")); + } + result->newSegments->commit(result->dir); +} - std::wcout << L"\nOpening index @ " << indexPath << L"\n\n"; - DirectoryPtr dir; - try - { - dir = FSDirectory::open(indexPath); - } - catch (...) - { - std::wcout << L"ERROR: could not open directory \"" << indexPath << L"\"; exiting\n"; - return 1; - } +bool CheckIndex::testAsserts() { + _assertsOn = true; + return true; +} - CheckIndexPtr checker(newLucene(dir)); - checker->setInfoStream(newLucene()); - - IndexStatusPtr result(checker->checkIndex(onlySegments)); - if (result->missingSegments) - return 1; - - if (!result->clean) - { - if (!doFix) - std::wcout << L"WARNING: would write new segments file, and " << result->totLoseDocCount << L" documents would be lost, if -fix were specified\n\n"; - else - { - std::wcout << L"WARNING: " << result->totLoseDocCount << L" documents will be lost\n"; - std::wcout << L"NOTE: will write new segments file in 5 seconds; this will remove " << result->totLoseDocCount; - std::wcout << L" docs from the index. THIS IS YOUR LAST CHANCE TO CTRL+C!\n"; - for (int32_t sec = 0; sec < 5; ++sec) - { - LuceneThread::threadSleep(1000); - std::wcout << L" " << (5 - sec) << L"...\n"; - } - std::wcout << L"Writing...\n"; - checker->fixIndex(result); - std::wcout << L"OK\n"; - std::wcout << L"Wrote new segments file \"" << result->newSegments->getCurrentSegmentFileName() << L"\"\n"; +bool CheckIndex::assertsOn() { + BOOST_ASSERT(testAsserts()); + return _assertsOn; +} + +int CheckIndex::main(Collection args) { + bool doFix = false; + Collection onlySegments(Collection::newInstance()); + String indexPath; + for (Collection::iterator arg = args.begin(); arg != args.end(); ++arg) { + if (*arg == L"-fix") { + doFix = true; + } else if (*arg == L"-segment") { + if (arg + 1 == args.end()) { + std::wcout << L"ERROR: missing name for -segment option\n"; + return 1; + } + ++arg; + onlySegments.add(*arg); + } else { + if (!indexPath.empty()) { + std::wcout << L"ERROR: unexpected extra argument '" << *arg << L"'\n"; + return 1; } + indexPath = *arg; } + } + if (indexPath.empty()) { + std::wcout << L"\nERROR: index path not specified\n"; + std::wcout << L"Usage: CheckIndex pathToIndex [-fix] [-segment X] [-segment Y]\n"; + std::wcout << L"\n"; + std::wcout << L" -fix: actually write a new segments_N file, removing any problematic segments\n"; + std::wcout << L" -segment X: only check the specified segments. This can be specified multiple\n"; + std::wcout << L" times, to check more than one segment, eg '-segment _2 -segment _a'.\n"; + std::wcout << L" You can't use this with the -fix option\n"; + std::wcout << L"\n"; + std::wcout << L"**WARNING**: -fix should only be used on an emergency basis as it will cause\n"; + std::wcout << L"documents (perhaps many) to be permanently removed from the index. Always make\n"; + std::wcout << L"a backup copy of your index before running this! Do not run this tool on an index\n"; + std::wcout << L"that is actively being written to. You have been warned!\n"; std::wcout << L"\n"; - return ((result && result->clean) ? 0 : 1); + std::wcout << L"Run without -fix, this tool will open the index, report version information\n"; + std::wcout << L"and report any exceptions it hits and what action it would take if -fix were\n"; + std::wcout << L"specified. With -fix, this tool will remove any segments that have issues and\n"; + std::wcout << L"write a new segments_N file. This means all documents contained in the affected\n"; + std::wcout << L"segments will be removed.\n"; + std::wcout << L"\n"; + std::wcout << L"This tool exits with exit code 1 if the index cannot be opened or has any\n"; + std::wcout << L"corruption, else 0.\n\n"; + return 1; } - IndexStatus::IndexStatus() - { - clean = false; - missingSegments = false; - cantOpenSegments = false; - missingSegmentVersion = false; - numSegments = false; - segmentInfos = Collection::newInstance(); - segmentsChecked = Collection::newInstance(); - toolOutOfDate = false; - totLoseDocCount = 0; - numBadSegments = 0; - partial = false; + if (!assertsOn()) { + std::wcout << L"\nNOTE: testing will be more thorough if you run with '-ea', so assertions are enabled\n"; } - IndexStatus::~IndexStatus() - { + if (onlySegments.empty()) { + onlySegments.reset(); + } else if (doFix) { + std::wcout << L"ERROR: cannot specify both -fix and -segment\n"; + return 1; } - SegmentInfoStatus::SegmentInfoStatus() - { - docCount = 0; - compound = false; - numFiles = 0; - sizeMB = 0; - docStoreOffset = -1; - docStoreCompoundFile = false; - hasDeletions = false; - numDeleted = 0; - openReaderPassed = false; - numFields = 0; - hasProx = false; + std::wcout << L"\nOpening index @ " << indexPath << L"\n\n"; + DirectoryPtr dir; + try { + dir = FSDirectory::open(indexPath); + } catch (...) { + std::wcout << L"ERROR: could not open directory \"" << indexPath << L"\"; exiting\n"; + return 1; } - SegmentInfoStatus::~SegmentInfoStatus() - { - } + CheckIndexPtr checker(newLucene(dir)); + checker->setInfoStream(newLucene()); - FieldNormStatus::FieldNormStatus() - { - totFields = 0; + IndexStatusPtr result(checker->checkIndex(onlySegments)); + if (result->missingSegments) { + return 1; } - FieldNormStatus::~FieldNormStatus() - { + if (!result->clean) { + if (!doFix) { + std::wcout << L"WARNING: would write new segments file, and " << result->totLoseDocCount << L" documents would be lost, if -fix were specified\n\n"; + } else { + std::wcout << L"WARNING: " << result->totLoseDocCount << L" documents will be lost\n"; + std::wcout << L"NOTE: will write new segments file in 5 seconds; this will remove " << result->totLoseDocCount; + std::wcout << L" docs from the index. THIS IS YOUR LAST CHANCE TO CTRL+C!\n"; + for (int32_t sec = 0; sec < 5; ++sec) { + LuceneThread::threadSleep(1000); + std::wcout << L" " << (5 - sec) << L"...\n"; + } + std::wcout << L"Writing...\n"; + checker->fixIndex(result); + std::wcout << L"OK\n"; + std::wcout << L"Wrote new segments file \"" << result->newSegments->getCurrentSegmentFileName() << L"\"\n"; + } } - TermIndexStatus::TermIndexStatus() - { - termCount = 0; - totFreq = 0; - totPos = 0; - } + std::wcout << L"\n"; + return ((result && result->clean) ? 0 : 1); +} - TermIndexStatus::~TermIndexStatus() - { - } +IndexStatus::IndexStatus() { + clean = false; + missingSegments = false; + cantOpenSegments = false; + missingSegmentVersion = false; + numSegments = false; + segmentInfos = Collection::newInstance(); + segmentsChecked = Collection::newInstance(); + toolOutOfDate = false; + totLoseDocCount = 0; + numBadSegments = 0; + partial = false; +} - StoredFieldStatus::StoredFieldStatus() - { - docCount = 0; - totFields = 0; - } +IndexStatus::~IndexStatus() { +} - StoredFieldStatus::~StoredFieldStatus() - { - } +SegmentInfoStatus::SegmentInfoStatus() { + docCount = 0; + compound = false; + numFiles = 0; + sizeMB = 0; + docStoreOffset = -1; + docStoreCompoundFile = false; + hasDeletions = false; + numDeleted = 0; + openReaderPassed = false; + numFields = 0; + hasProx = false; +} - TermVectorStatus::TermVectorStatus() - { - docCount = 0; - totVectors = 0; - } +SegmentInfoStatus::~SegmentInfoStatus() { +} - TermVectorStatus::~TermVectorStatus() - { - } +FieldNormStatus::FieldNormStatus() { + totFields = 0; +} - MySegmentTermDocs::MySegmentTermDocs(const SegmentReaderPtr& p) : SegmentTermDocs(p) - { - delCount = 0; - } +FieldNormStatus::~FieldNormStatus() { +} - MySegmentTermDocs::~MySegmentTermDocs() - { - } +TermIndexStatus::TermIndexStatus() { + termCount = 0; + totFreq = 0; + totPos = 0; +} - void MySegmentTermDocs::seek(const TermPtr& term) - { - SegmentTermDocs::seek(term); - delCount = 0; - } +TermIndexStatus::~TermIndexStatus() { +} + +StoredFieldStatus::StoredFieldStatus() { + docCount = 0; + totFields = 0; +} + +StoredFieldStatus::~StoredFieldStatus() { +} + +TermVectorStatus::TermVectorStatus() { + docCount = 0; + totVectors = 0; +} + +TermVectorStatus::~TermVectorStatus() { +} + +MySegmentTermDocs::MySegmentTermDocs(const SegmentReaderPtr& p) : SegmentTermDocs(p) { + delCount = 0; +} + +MySegmentTermDocs::~MySegmentTermDocs() { +} + +void MySegmentTermDocs::seek(const TermPtr& term) { + SegmentTermDocs::seek(term); + delCount = 0; +} + +void MySegmentTermDocs::skippingDoc() { + ++delCount; +} - void MySegmentTermDocs::skippingDoc() - { - ++delCount; - } } diff --git a/src/core/index/CompoundFileReader.cpp b/src/core/index/CompoundFileReader.cpp index bcc2684d..48d8accc 100644 --- a/src/core/index/CompoundFileReader.cpp +++ b/src/core/index/CompoundFileReader.cpp @@ -7,229 +7,201 @@ #include "LuceneInc.h" #include "CompoundFileReader.h" -namespace Lucene -{ - CompoundFileReader::CompoundFileReader(const DirectoryPtr& dir, const String& name) - { - ConstructReader(dir, name, BufferedIndexInput::BUFFER_SIZE); - } +namespace Lucene { - CompoundFileReader::CompoundFileReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize) - { - ConstructReader(dir, name, readBufferSize); - } +CompoundFileReader::CompoundFileReader(const DirectoryPtr& dir, const String& name) { + ConstructReader(dir, name, BufferedIndexInput::BUFFER_SIZE); +} - CompoundFileReader::~CompoundFileReader() - { - } +CompoundFileReader::CompoundFileReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize) { + ConstructReader(dir, name, readBufferSize); +} - void CompoundFileReader::ConstructReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize) - { - directory = dir; - fileName = name; - this->readBufferSize = readBufferSize; - this->entries = MapStringFileEntryPtr::newInstance(); - - bool success = false; - - LuceneException finally; - try - { - stream = dir->openInput(name, readBufferSize); - - // read the directory and init files - int32_t count = stream->readVInt(); - - FileEntryPtr entry; - for (int32_t i = 0; i < count; ++i) - { - int64_t offset = stream->readLong(); - String id(stream->readString()); - - if (entry) - { - // set length of the previous entry - entry->length = offset - entry->offset; - } - - entry = newInstance(); - entry->offset = offset; - entries.put(id, entry); - } +CompoundFileReader::~CompoundFileReader() { +} - // set the length of the final entry - if (entry) - entry->length = stream->length() - entry->offset; +void CompoundFileReader::ConstructReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize) { + directory = dir; + fileName = name; + this->readBufferSize = readBufferSize; + this->entries = MapStringFileEntryPtr::newInstance(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } + bool success = false; - if (!success && stream) - { - try - { - stream->close(); - } - catch (...) - { + LuceneException finally; + try { + stream = dir->openInput(name, readBufferSize); + + // read the directory and init files + int32_t count = stream->readVInt(); + + FileEntryPtr entry; + for (int32_t i = 0; i < count; ++i) { + int64_t offset = stream->readLong(); + String id(stream->readString()); + + if (entry) { + // set length of the previous entry + entry->length = offset - entry->offset; } + + entry = newInstance(); + entry->offset = offset; + entries.put(id, entry); } - finally.throwException(); - } + // set the length of the final entry + if (entry) { + entry->length = stream->length() - entry->offset; + } - DirectoryPtr CompoundFileReader::getDirectory() - { - return directory; + success = true; + } catch (LuceneException& e) { + finally = e; } - String CompoundFileReader::getName() - { - return fileName; + if (!success && stream) { + try { + stream->close(); + } catch (...) { + } } - void CompoundFileReader::close() - { - SyncLock syncLock(this); - if (!stream) - boost::throw_exception(IOException(L"Already closed")); + finally.throwException(); +} - entries.clear(); - stream->close(); - stream.reset(); - } +DirectoryPtr CompoundFileReader::getDirectory() { + return directory; +} + +String CompoundFileReader::getName() { + return fileName; +} - IndexInputPtr CompoundFileReader::openInput(const String& name) - { - SyncLock syncLock(this); - // Default to readBufferSize passed in when we were opened - return openInput(name, readBufferSize); +void CompoundFileReader::close() { + SyncLock syncLock(this); + if (!stream) { + boost::throw_exception(IOException(L"Already closed")); } - IndexInputPtr CompoundFileReader::openInput(const String& name, int32_t bufferSize) - { - SyncLock syncLock(this); - if (!stream) - boost::throw_exception(IOException(L"Stream closed")); + entries.clear(); + stream->close(); + stream.reset(); +} - MapStringFileEntryPtr::iterator entry = entries.find(name); - if (entry == entries.end()) - boost::throw_exception(IOException(L"No sub-file with id " + name + L" found")); +IndexInputPtr CompoundFileReader::openInput(const String& name) { + SyncLock syncLock(this); + // Default to readBufferSize passed in when we were opened + return openInput(name, readBufferSize); +} - return newLucene(stream, entry->second->offset, entry->second->length, readBufferSize); +IndexInputPtr CompoundFileReader::openInput(const String& name, int32_t bufferSize) { + SyncLock syncLock(this); + if (!stream) { + boost::throw_exception(IOException(L"Stream closed")); } - HashSet CompoundFileReader::listAll() - { - HashSet res(HashSet::newInstance()); - for (MapStringFileEntryPtr::iterator entry = entries.begin(); entry != entries.end(); ++entry) - res.add(entry->first); - return res; + MapStringFileEntryPtr::iterator entry = entries.find(name); + if (entry == entries.end()) { + boost::throw_exception(IOException(L"No sub-file with id " + name + L" found")); } - bool CompoundFileReader::fileExists(const String& name) - { - return entries.contains(name); - } + return newLucene(stream, entry->second->offset, entry->second->length, readBufferSize); +} - uint64_t CompoundFileReader::fileModified(const String& name) - { - return directory->fileModified(fileName); +HashSet CompoundFileReader::listAll() { + HashSet res(HashSet::newInstance()); + for (MapStringFileEntryPtr::iterator entry = entries.begin(); entry != entries.end(); ++entry) { + res.add(entry->first); } + return res; +} - void CompoundFileReader::touchFile(const String& name) - { - directory->touchFile(fileName); - } +bool CompoundFileReader::fileExists(const String& name) { + return entries.contains(name); +} - void CompoundFileReader::deleteFile(const String& name) - { - boost::throw_exception(UnsupportedOperationException()); - } +uint64_t CompoundFileReader::fileModified(const String& name) { + return directory->fileModified(fileName); +} - void CompoundFileReader::renameFile(const String& from, const String& to) - { - boost::throw_exception(UnsupportedOperationException()); - } +void CompoundFileReader::touchFile(const String& name) { + directory->touchFile(fileName); +} - int64_t CompoundFileReader::fileLength(const String& name) - { - MapStringFileEntryPtr::iterator entry = entries.find(name); - if (entry == entries.end()) - boost::throw_exception(IOException(L"File " + name + L" does not exist")); - return entry->second->length; - } +void CompoundFileReader::deleteFile(const String& name) { + boost::throw_exception(UnsupportedOperationException()); +} - IndexOutputPtr CompoundFileReader::createOutput(const String& name) - { - boost::throw_exception(UnsupportedOperationException()); - return IndexOutputPtr(); - } +void CompoundFileReader::renameFile(const String& from, const String& to) { + boost::throw_exception(UnsupportedOperationException()); +} - LockPtr CompoundFileReader::makeLock(const String& name) - { - boost::throw_exception(UnsupportedOperationException()); - return LockPtr(); +int64_t CompoundFileReader::fileLength(const String& name) { + MapStringFileEntryPtr::iterator entry = entries.find(name); + if (entry == entries.end()) { + boost::throw_exception(IOException(L"File " + name + L" does not exist")); } + return entry->second->length; +} - CSIndexInput::CSIndexInput() - { - fileOffset = 0; - _length = 0; - } +IndexOutputPtr CompoundFileReader::createOutput(const String& name) { + boost::throw_exception(UnsupportedOperationException()); + return IndexOutputPtr(); +} - CSIndexInput::CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length) : BufferedIndexInput(BufferedIndexInput::BUFFER_SIZE) - { - this->base = boost::dynamic_pointer_cast(base->clone()); - this->fileOffset = fileOffset; - this->_length = length; - } +LockPtr CompoundFileReader::makeLock(const String& name) { + boost::throw_exception(UnsupportedOperationException()); + return LockPtr(); +} - CSIndexInput::CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length, int32_t readBufferSize) : BufferedIndexInput(readBufferSize) - { - this->base = boost::dynamic_pointer_cast(base->clone()); - this->fileOffset = fileOffset; - this->_length = length; - } +CSIndexInput::CSIndexInput() { + fileOffset = 0; + _length = 0; +} - CSIndexInput::~CSIndexInput() - { - } +CSIndexInput::CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length) : BufferedIndexInput(BufferedIndexInput::BUFFER_SIZE) { + this->base = boost::dynamic_pointer_cast(base->clone()); + this->fileOffset = fileOffset; + this->_length = length; +} - void CSIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) - { - int64_t start = getFilePointer(); - if (start + length > _length) - boost::throw_exception(IOException(L"read past EOF")); - base->seek(fileOffset + start); - base->readBytes(b, offset, length, false); - } +CSIndexInput::CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length, int32_t readBufferSize) : BufferedIndexInput(readBufferSize) { + this->base = boost::dynamic_pointer_cast(base->clone()); + this->fileOffset = fileOffset; + this->_length = length; +} - void CSIndexInput::seekInternal(int64_t pos) - { - } +CSIndexInput::~CSIndexInput() { +} - void CSIndexInput::close() - { - base->close(); +void CSIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) { + int64_t start = getFilePointer(); + if (start + length > _length) { + boost::throw_exception(IOException(L"read past EOF")); } + base->seek(fileOffset + start); + base->readBytes(b, offset, length, false); +} - int64_t CSIndexInput::length() - { - return _length; - } +void CSIndexInput::seekInternal(int64_t pos) { +} + +void CSIndexInput::close() { + base->close(); +} + +int64_t CSIndexInput::length() { + return _length; +} + +LuceneObjectPtr CSIndexInput::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + CSIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(BufferedIndexInput::clone(clone))); + cloneIndexInput->base = boost::dynamic_pointer_cast(this->base->clone()); + cloneIndexInput->fileOffset = fileOffset; + cloneIndexInput->_length = _length; + return cloneIndexInput; +} - LuceneObjectPtr CSIndexInput::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - CSIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(BufferedIndexInput::clone(clone))); - cloneIndexInput->base = boost::dynamic_pointer_cast(this->base->clone()); - cloneIndexInput->fileOffset = fileOffset; - cloneIndexInput->_length = _length; - return cloneIndexInput; - } } diff --git a/src/core/index/CompoundFileWriter.cpp b/src/core/index/CompoundFileWriter.cpp index ed7c63a9..002c8677 100644 --- a/src/core/index/CompoundFileWriter.cpp +++ b/src/core/index/CompoundFileWriter.cpp @@ -12,183 +12,168 @@ #include "IndexOutput.h" #include "StringUtils.h" -namespace Lucene -{ - CompoundFileWriter::CompoundFileWriter(const DirectoryPtr& dir, const String& name, const CheckAbortPtr& checkAbort) - { - if (!dir) - boost::throw_exception(IllegalArgumentException(L"directory cannot be empty")); - if (name.empty()) - boost::throw_exception(IllegalArgumentException(L"name cannot be empty")); - this->checkAbort = checkAbort; - _directory = dir; - fileName = name; - ids = HashSet::newInstance(); - entries = Collection::newInstance(); - merged = false; - } +namespace Lucene { - CompoundFileWriter::~CompoundFileWriter() - { +CompoundFileWriter::CompoundFileWriter(const DirectoryPtr& dir, const String& name, const CheckAbortPtr& checkAbort) { + if (!dir) { + boost::throw_exception(IllegalArgumentException(L"directory cannot be empty")); + } + if (name.empty()) { + boost::throw_exception(IllegalArgumentException(L"name cannot be empty")); } + this->checkAbort = checkAbort; + _directory = dir; + fileName = name; + ids = HashSet::newInstance(); + entries = Collection::newInstance(); + merged = false; +} + +CompoundFileWriter::~CompoundFileWriter() { +} + +DirectoryPtr CompoundFileWriter::getDirectory() { + return DirectoryPtr(_directory); +} - DirectoryPtr CompoundFileWriter::getDirectory() - { - return DirectoryPtr(_directory); +String CompoundFileWriter::getName() { + return fileName; +} + +void CompoundFileWriter::addFile(const String& file) { + if (merged) { + boost::throw_exception(IllegalStateException(L"Can't add extensions after merge has been called")); } - String CompoundFileWriter::getName() - { - return fileName; + if (file.empty()) { + boost::throw_exception(IllegalArgumentException(L"file cannot be empty")); } - void CompoundFileWriter::addFile(const String& file) - { - if (merged) - boost::throw_exception(IllegalStateException(L"Can't add extensions after merge has been called")); + if (!ids.add(file)) { + boost::throw_exception(IllegalArgumentException(L"File " + file + L" already added")); + } - if (file.empty()) - boost::throw_exception(IllegalArgumentException(L"file cannot be empty")); + FileEntry entry; + entry.file = file; + entries.add(entry); +} - if (!ids.add(file)) - boost::throw_exception(IllegalArgumentException(L"File " + file + L" already added")); +void CompoundFileWriter::close() { + if (merged) { + boost::throw_exception(IllegalStateException(L"Merge already performed")); + } - FileEntry entry; - entry.file = file; - entries.add(entry); + if (entries.empty()) { + boost::throw_exception(IllegalStateException(L"No entries to merge have been defined")); } - void CompoundFileWriter::close() - { - if (merged) - boost::throw_exception(IllegalStateException(L"Merge already performed")); - - if (entries.empty()) - boost::throw_exception(IllegalStateException(L"No entries to merge have been defined")); - - merged = true; - - DirectoryPtr directory(_directory); - - // open the compound stream - IndexOutputPtr os; - LuceneException finally; - try - { - os = directory->createOutput(fileName); - - // Write the number of entries - os->writeVInt(entries.size()); - - // Write the directory with all offsets at 0. Remember the positions of directory entries so that we - // can adjust the offsets later - int64_t totalSize = 0; - for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) - { - fe->directoryOffset = os->getFilePointer(); - os->writeLong(0); // for now - os->writeString(fe->file); - totalSize += directory->fileLength(fe->file); - } + merged = true; - // Pre-allocate size of file as optimization - this can potentially help IO performance as we write the - // file and also later during searching. It also uncovers a disk-full situation earlier and hopefully - // without actually filling disk to 100% - int64_t finalLength = totalSize + os->getFilePointer(); - os->setLength(finalLength); - - // Open the files and copy their data into the stream. Remember the locations of each file's data section. - ByteArray buffer(ByteArray::newInstance(16384)); - for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) - { - fe->dataOffset = os->getFilePointer(); - copyFile(*fe, os, buffer); - } + DirectoryPtr directory(_directory); - // Write the data offsets into the directory of the compound stream - for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) - { - os->seek(fe->directoryOffset); - os->writeLong(fe->dataOffset); - } + // open the compound stream + IndexOutputPtr os; + LuceneException finally; + try { + os = directory->createOutput(fileName); - BOOST_ASSERT(finalLength == os->length()); + // Write the number of entries + os->writeVInt(entries.size()); - // Close the output stream. Set the os to null before trying to close so that if an exception occurs during - // the close, the finally clause below will not attempt to close the stream the second time. - IndexOutputPtr tmp(os); - os.reset(); - tmp->close(); + // Write the directory with all offsets at 0. Remember the positions of directory entries so that we + // can adjust the offsets later + int64_t totalSize = 0; + for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) { + fe->directoryOffset = os->getFilePointer(); + os->writeLong(0); // for now + os->writeString(fe->file); + totalSize += directory->fileLength(fe->file); } - catch (LuceneException& e) - { - finally = e; + + // Pre-allocate size of file as optimization - this can potentially help IO performance as we write the + // file and also later during searching. It also uncovers a disk-full situation earlier and hopefully + // without actually filling disk to 100% + int64_t finalLength = totalSize + os->getFilePointer(); + os->setLength(finalLength); + + // Open the files and copy their data into the stream. Remember the locations of each file's data section. + ByteArray buffer(ByteArray::newInstance(16384)); + for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) { + fe->dataOffset = os->getFilePointer(); + copyFile(*fe, os, buffer); } - if (os) - { - try - { - os->close(); - } - catch (LuceneException&) - { - } + // Write the data offsets into the directory of the compound stream + for (Collection::iterator fe = entries.begin(); fe != entries.end(); ++fe) { + os->seek(fe->directoryOffset); + os->writeLong(fe->dataOffset); } - finally.throwException(); + + BOOST_ASSERT(finalLength == os->length()); + + // Close the output stream. Set the os to null before trying to close so that if an exception occurs during + // the close, the finally clause below will not attempt to close the stream the second time. + IndexOutputPtr tmp(os); + os.reset(); + tmp->close(); + } catch (LuceneException& e) { + finally = e; } - void CompoundFileWriter::copyFile(const FileEntry& source, const IndexOutputPtr& os, ByteArray buffer) - { - IndexInputPtr is; - DirectoryPtr directory(_directory); - LuceneException finally; - try - { - int64_t startPtr = os->getFilePointer(); - - is = directory->openInput(source.file); - int64_t length = is->length(); - int64_t remainder = length; - int64_t chunk = buffer.size(); - - while (remainder > 0) - { - int32_t len = (int32_t)std::min(chunk, remainder); - is->readBytes(buffer.get(), 0, len, false); - os->writeBytes(buffer.get(), len); - remainder -= len; - if (checkAbort) - { - // Roughly every 2 MB we will check if it's time to abort - checkAbort->work(80); - } - } + if (os) { + try { + os->close(); + } catch (LuceneException&) { + } + } + finally.throwException(); +} - // Verify that remainder is 0 - if (remainder != 0) - { - boost::throw_exception(IOException(L"Non-zero remainder length after copying: " + StringUtils::toString(remainder) + - L" (id: " + source.file + L", length: " + StringUtils::toString(length) + - L", buffer size: " + StringUtils::toString(chunk) + L")")); +void CompoundFileWriter::copyFile(const FileEntry& source, const IndexOutputPtr& os, ByteArray buffer) { + IndexInputPtr is; + DirectoryPtr directory(_directory); + LuceneException finally; + try { + int64_t startPtr = os->getFilePointer(); + + is = directory->openInput(source.file); + int64_t length = is->length(); + int64_t remainder = length; + int64_t chunk = buffer.size(); + + while (remainder > 0) { + int32_t len = (int32_t)std::min(chunk, remainder); + is->readBytes(buffer.get(), 0, len, false); + os->writeBytes(buffer.get(), len); + remainder -= len; + if (checkAbort) { + // Roughly every 2 MB we will check if it's time to abort + checkAbort->work(80); } + } - // Verify that the output length diff is equal to original file - int64_t endPtr = os->getFilePointer(); - int64_t diff = endPtr - startPtr; - if (diff != length) - { - boost::throw_exception(IOException(L"Difference in the output file offsets " + StringUtils::toString(diff) + - L" does not match the original file length " + StringUtils::toString(length))); - } + // Verify that remainder is 0 + if (remainder != 0) { + boost::throw_exception(IOException(L"Non-zero remainder length after copying: " + StringUtils::toString(remainder) + + L" (id: " + source.file + L", length: " + StringUtils::toString(length) + + L", buffer size: " + StringUtils::toString(chunk) + L")")); } - catch (LuceneException& e) - { - finally = e; + + // Verify that the output length diff is equal to original file + int64_t endPtr = os->getFilePointer(); + int64_t diff = endPtr - startPtr; + if (diff != length) { + boost::throw_exception(IOException(L"Difference in the output file offsets " + StringUtils::toString(diff) + + L" does not match the original file length " + StringUtils::toString(length))); } + } catch (LuceneException& e) { + finally = e; + } - if (is) - is->close(); - finally.throwException(); + if (is) { + is->close(); } + finally.throwException(); +} + } diff --git a/src/core/index/ConcurrentMergeScheduler.cpp b/src/core/index/ConcurrentMergeScheduler.cpp index d6db8220..a24a261e 100644 --- a/src/core/index/ConcurrentMergeScheduler.cpp +++ b/src/core/index/ConcurrentMergeScheduler.cpp @@ -11,341 +11,298 @@ #include "TestPoint.h" #include "StringUtils.h" -namespace Lucene -{ - Collection ConcurrentMergeScheduler::allInstances; - bool ConcurrentMergeScheduler::anyExceptions = false; +namespace Lucene { - ConcurrentMergeScheduler::ConcurrentMergeScheduler() - { - mergeThreadPriority = -1; - mergeThreads = SetMergeThread::newInstance(); - maxThreadCount = 1; - suppressExceptions = false; - closed = false; - } +Collection ConcurrentMergeScheduler::allInstances; +bool ConcurrentMergeScheduler::anyExceptions = false; - ConcurrentMergeScheduler::~ConcurrentMergeScheduler() - { - } +ConcurrentMergeScheduler::ConcurrentMergeScheduler() { + mergeThreadPriority = -1; + mergeThreads = SetMergeThread::newInstance(); + maxThreadCount = 1; + suppressExceptions = false; + closed = false; +} - void ConcurrentMergeScheduler::initialize() - { - // Only for testing - if (allInstances) - addMyself(); - } +ConcurrentMergeScheduler::~ConcurrentMergeScheduler() { +} - void ConcurrentMergeScheduler::setMaxThreadCount(int32_t count) - { - if (count < 1) - boost::throw_exception(IllegalArgumentException(L"count should be at least 1")); - maxThreadCount = count; +void ConcurrentMergeScheduler::initialize() { + // Only for testing + if (allInstances) { + addMyself(); } +} - int32_t ConcurrentMergeScheduler::getMaxThreadCount() - { - return maxThreadCount; +void ConcurrentMergeScheduler::setMaxThreadCount(int32_t count) { + if (count < 1) { + boost::throw_exception(IllegalArgumentException(L"count should be at least 1")); } + maxThreadCount = count; +} - int32_t ConcurrentMergeScheduler::getMergeThreadPriority() - { - SyncLock syncLock(this); - initMergeThreadPriority(); - return mergeThreadPriority; - } +int32_t ConcurrentMergeScheduler::getMaxThreadCount() { + return maxThreadCount; +} - void ConcurrentMergeScheduler::setMergeThreadPriority(int32_t pri) - { - SyncLock syncLock(this); - if (pri > LuceneThread::MAX_PRIORITY || pri < LuceneThread::MIN_PRIORITY) - { - boost::throw_exception(IllegalArgumentException(L"priority must be in range " + StringUtils::toString(LuceneThread::MIN_PRIORITY) + - L" .. " + StringUtils::toString(LuceneThread::MAX_PRIORITY) + L" inclusive")); - } - mergeThreadPriority = pri; +int32_t ConcurrentMergeScheduler::getMergeThreadPriority() { + SyncLock syncLock(this); + initMergeThreadPriority(); + return mergeThreadPriority; +} - for (SetMergeThread::iterator merge = mergeThreads.begin(); merge != mergeThreads.end(); ++merge) - (*merge)->setThreadPriority(pri); +void ConcurrentMergeScheduler::setMergeThreadPriority(int32_t pri) { + SyncLock syncLock(this); + if (pri > LuceneThread::MAX_PRIORITY || pri < LuceneThread::MIN_PRIORITY) { + boost::throw_exception(IllegalArgumentException(L"priority must be in range " + StringUtils::toString(LuceneThread::MIN_PRIORITY) + + L" .. " + StringUtils::toString(LuceneThread::MAX_PRIORITY) + L" inclusive")); } + mergeThreadPriority = pri; - bool ConcurrentMergeScheduler::verbose() - { - return (!_writer.expired() && IndexWriterPtr(_writer)->verbose()); + for (SetMergeThread::iterator merge = mergeThreads.begin(); merge != mergeThreads.end(); ++merge) { + (*merge)->setThreadPriority(pri); } +} - void ConcurrentMergeScheduler::message(const String& message) - { - if (verbose() && !_writer.expired()) - IndexWriterPtr(_writer)->message(L"CMS: " + message); - } +bool ConcurrentMergeScheduler::verbose() { + return (!_writer.expired() && IndexWriterPtr(_writer)->verbose()); +} - void ConcurrentMergeScheduler::initMergeThreadPriority() - { - SyncLock syncLock(this); - if (mergeThreadPriority == -1) - { - // Default to slightly higher priority than our calling thread - mergeThreadPriority = std::min(LuceneThread::NORM_PRIORITY + 1, LuceneThread::MAX_PRIORITY); - } +void ConcurrentMergeScheduler::message(const String& message) { + if (verbose() && !_writer.expired()) { + IndexWriterPtr(_writer)->message(L"CMS: " + message); } +} - void ConcurrentMergeScheduler::close() - { - sync(); - closed = true; +void ConcurrentMergeScheduler::initMergeThreadPriority() { + SyncLock syncLock(this); + if (mergeThreadPriority == -1) { + // Default to slightly higher priority than our calling thread + mergeThreadPriority = std::min(LuceneThread::NORM_PRIORITY + 1, LuceneThread::MAX_PRIORITY); } +} - void ConcurrentMergeScheduler::sync() - { - SyncLock syncLock(this); - while (mergeThreadCount() > 0) - { - message(L"now wait for threads; currently " + StringUtils::toString(mergeThreads.size()) + L" still running"); - wait(1000); - } - mergeThreads.clear(); +void ConcurrentMergeScheduler::close() { + sync(); + closed = true; +} + +void ConcurrentMergeScheduler::sync() { + SyncLock syncLock(this); + while (mergeThreadCount() > 0) { + message(L"now wait for threads; currently " + StringUtils::toString(mergeThreads.size()) + L" still running"); + wait(1000); } + mergeThreads.clear(); +} - int32_t ConcurrentMergeScheduler::mergeThreadCount() - { - SyncLock syncLock(this); - int32_t count = 0; - for (SetMergeThread::iterator merge = mergeThreads.begin(); merge != mergeThreads.end(); ++merge) - { - if ((*merge)->isAlive()) - ++count; +int32_t ConcurrentMergeScheduler::mergeThreadCount() { + SyncLock syncLock(this); + int32_t count = 0; + for (SetMergeThread::iterator merge = mergeThreads.begin(); merge != mergeThreads.end(); ++merge) { + if ((*merge)->isAlive()) { + ++count; } - return count; } + return count; +} - void ConcurrentMergeScheduler::merge(const IndexWriterPtr& writer) - { - BOOST_ASSERT(!writer->holdsLock()); +void ConcurrentMergeScheduler::merge(const IndexWriterPtr& writer) { + BOOST_ASSERT(!writer->holdsLock()); - this->_writer = writer; + this->_writer = writer; - initMergeThreadPriority(); + initMergeThreadPriority(); - dir = writer->getDirectory(); + dir = writer->getDirectory(); - // First, quickly run through the newly proposed merges and add any orthogonal merges (ie a merge not - // involving segments already pending to be merged) to the queue. If we are way behind on merging, - // many of these newly proposed merges will likely already be registered. - message(L"now merge"); - message(L" index: " + writer->segString()); + // First, quickly run through the newly proposed merges and add any orthogonal merges (ie a merge not + // involving segments already pending to be merged) to the queue. If we are way behind on merging, + // many of these newly proposed merges will likely already be registered. + message(L"now merge"); + message(L" index: " + writer->segString()); - // Iterate, pulling from the IndexWriter's queue of pending merges, until it's empty - while (true) - { - OneMergePtr merge(writer->getNextMerge()); - if (!merge) - { - message(L" no more merges pending; now return"); - return; - } + // Iterate, pulling from the IndexWriter's queue of pending merges, until it's empty + while (true) { + OneMergePtr merge(writer->getNextMerge()); + if (!merge) { + message(L" no more merges pending; now return"); + return; + } - // We do this with the primary thread to keep deterministic assignment of segment names - writer->mergeInit(merge); + // We do this with the primary thread to keep deterministic assignment of segment names + writer->mergeInit(merge); - bool success = false; - LuceneException finally; - try - { - SyncLock syncLock(this); - MergeThreadPtr merger; - while (mergeThreadCount() >= maxThreadCount) - { - message(L" too many merge threads running; stalling..."); - wait(1000); - } + bool success = false; + LuceneException finally; + try { + SyncLock syncLock(this); + MergeThreadPtr merger; + while (mergeThreadCount() >= maxThreadCount) { + message(L" too many merge threads running; stalling..."); + wait(1000); + } - message(L" consider merge " + merge->segString(dir)); + message(L" consider merge " + merge->segString(dir)); - BOOST_ASSERT(mergeThreadCount() < maxThreadCount); + BOOST_ASSERT(mergeThreadCount() < maxThreadCount); - // OK to spawn a new merge thread to handle this merge - merger = getMergeThread(writer, merge); - mergeThreads.add(merger); - message(L" launch new thread"); + // OK to spawn a new merge thread to handle this merge + merger = getMergeThread(writer, merge); + mergeThreads.add(merger); + message(L" launch new thread"); - merger->start(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - writer->mergeFinish(merge); - finally.throwException(); + merger->start(); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + writer->mergeFinish(merge); } + finally.throwException(); } +} - void ConcurrentMergeScheduler::doMerge(const OneMergePtr& merge) - { - TestScope testScope(L"ConcurrentMergeScheduler", L"doMerge"); - IndexWriterPtr(_writer)->merge(merge); - } +void ConcurrentMergeScheduler::doMerge(const OneMergePtr& merge) { + TestScope testScope(L"ConcurrentMergeScheduler", L"doMerge"); + IndexWriterPtr(_writer)->merge(merge); +} - MergeThreadPtr ConcurrentMergeScheduler::getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge) - { - SyncLock syncLock(this); - MergeThreadPtr thread(newLucene(shared_from_this(), writer, merge)); - thread->setThreadPriority(mergeThreadPriority); - return thread; - } +MergeThreadPtr ConcurrentMergeScheduler::getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge) { + SyncLock syncLock(this); + MergeThreadPtr thread(newLucene(shared_from_this(), writer, merge)); + thread->setThreadPriority(mergeThreadPriority); + return thread; +} - void ConcurrentMergeScheduler::handleMergeException(const LuceneException& exc) - { - // When an exception is hit during merge, IndexWriter removes any partial files and then - // allows another merge to run. If whatever caused the error is not transient then the - // exception will keep happening, so, we sleep here to avoid saturating CPU in such cases - LuceneThread::threadSleep(250); // pause 250 msec - boost::throw_exception(MergeException()); - } +void ConcurrentMergeScheduler::handleMergeException(const LuceneException& exc) { + // When an exception is hit during merge, IndexWriter removes any partial files and then + // allows another merge to run. If whatever caused the error is not transient then the + // exception will keep happening, so, we sleep here to avoid saturating CPU in such cases + LuceneThread::threadSleep(250); // pause 250 msec + boost::throw_exception(MergeException()); +} - bool ConcurrentMergeScheduler::anyUnhandledExceptions() - { - if (!allInstances) - boost::throw_exception(RuntimeException(L"setTestMode() was not called")); - SyncLock instancesLock(&allInstances); - for (Collection::iterator instance = allInstances.begin(); instance != allInstances.end(); ++instance) - (*instance)->sync(); - bool v = anyExceptions; - anyExceptions = false; - return v; +bool ConcurrentMergeScheduler::anyUnhandledExceptions() { + if (!allInstances) { + boost::throw_exception(RuntimeException(L"setTestMode() was not called")); } - - void ConcurrentMergeScheduler::clearUnhandledExceptions() - { - SyncLock instancesLock(&allInstances); - anyExceptions = false; + SyncLock instancesLock(&allInstances); + for (Collection::iterator instance = allInstances.begin(); instance != allInstances.end(); ++instance) { + (*instance)->sync(); } + bool v = anyExceptions; + anyExceptions = false; + return v; +} - void ConcurrentMergeScheduler::addMyself() - { - SyncLock instancesLock(&allInstances); - int32_t size = allInstances.size(); - int32_t upto = 0; - for (int32_t i = 0; i < size; ++i) - { - ConcurrentMergeSchedulerPtr other(allInstances[i]); - if (!(other->closed && other->mergeThreadCount() == 0)) - { - // Keep this one for now: it still has threads or may spawn new threads - allInstances[upto++] = other; - } +void ConcurrentMergeScheduler::clearUnhandledExceptions() { + SyncLock instancesLock(&allInstances); + anyExceptions = false; +} - allInstances.remove(allInstances.begin() + upto, allInstances.end()); - allInstances.add(shared_from_this()); +void ConcurrentMergeScheduler::addMyself() { + SyncLock instancesLock(&allInstances); + int32_t size = allInstances.size(); + int32_t upto = 0; + for (int32_t i = 0; i < size; ++i) { + ConcurrentMergeSchedulerPtr other(allInstances[i]); + if (!(other->closed && other->mergeThreadCount() == 0)) { + // Keep this one for now: it still has threads or may spawn new threads + allInstances[upto++] = other; } - } - void ConcurrentMergeScheduler::setSuppressExceptions() - { - suppressExceptions = true; + allInstances.remove(allInstances.begin() + upto, allInstances.end()); + allInstances.add(shared_from_this()); } +} - void ConcurrentMergeScheduler::clearSuppressExceptions() - { - suppressExceptions = false; - } +void ConcurrentMergeScheduler::setSuppressExceptions() { + suppressExceptions = true; +} - void ConcurrentMergeScheduler::setTestMode() - { - allInstances = Collection::newInstance(); - } +void ConcurrentMergeScheduler::clearSuppressExceptions() { + suppressExceptions = false; +} - MergeThread::MergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge) - { - this->_merger = merger; - this->_writer = writer; - this->startMerge = startMerge; - } +void ConcurrentMergeScheduler::setTestMode() { + allInstances = Collection::newInstance(); +} - MergeThread::~MergeThread() - { - } +MergeThread::MergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge) { + this->_merger = merger; + this->_writer = writer; + this->startMerge = startMerge; +} - void MergeThread::setRunningMerge(const OneMergePtr& merge) - { - ConcurrentMergeSchedulerPtr merger(_merger); - SyncLock syncLock(merger); - runningMerge = merge; - } +MergeThread::~MergeThread() { +} - OneMergePtr MergeThread::getRunningMerge() - { - ConcurrentMergeSchedulerPtr merger(_merger); - SyncLock syncLock(merger); - return runningMerge; - } +void MergeThread::setRunningMerge(const OneMergePtr& merge) { + ConcurrentMergeSchedulerPtr merger(_merger); + SyncLock syncLock(merger); + runningMerge = merge; +} - void MergeThread::setThreadPriority(int32_t pri) - { - try - { - setPriority(pri); - } - catch (...) - { - } - } +OneMergePtr MergeThread::getRunningMerge() { + ConcurrentMergeSchedulerPtr merger(_merger); + SyncLock syncLock(merger); + return runningMerge; +} - void MergeThread::run() - { - // First time through the while loop we do the merge that we were started with - OneMergePtr merge(this->startMerge); - ConcurrentMergeSchedulerPtr merger(_merger); +void MergeThread::setThreadPriority(int32_t pri) { + try { + setPriority(pri); + } catch (...) { + } +} - LuceneException finally; - try - { - merger->message(L" merge thread: start"); - IndexWriterPtr writer(_writer); - - while (true) - { - setRunningMerge(merge); - merger->doMerge(merge); - - // Subsequent times through the loop we do any new merge that writer says is necessary - merge = writer->getNextMerge(); - if (merge) - { - writer->mergeInit(merge); - merger->message(L" merge thread: do another merge " + merge->segString(merger->dir)); - } - else - break; +void MergeThread::run() { + // First time through the while loop we do the merge that we were started with + OneMergePtr merge(this->startMerge); + ConcurrentMergeSchedulerPtr merger(_merger); + + LuceneException finally; + try { + merger->message(L" merge thread: start"); + IndexWriterPtr writer(_writer); + + while (true) { + setRunningMerge(merge); + merger->doMerge(merge); + + // Subsequent times through the loop we do any new merge that writer says is necessary + merge = writer->getNextMerge(); + if (merge) { + writer->mergeInit(merge); + merger->message(L" merge thread: do another merge " + merge->segString(merger->dir)); + } else { + break; } - - merger->message(L" merge thread: done"); - } - catch (MergeAbortedException&) - { - // Ignore the exception if it was due to abort } - catch (LuceneException& e) - { - if (!merger->suppressExceptions) - { - // suppressExceptions is normally only set during testing. - merger->anyExceptions = true; - merger->handleMergeException(e); - } - else - finally = e; + + merger->message(L" merge thread: done"); + } catch (MergeAbortedException&) { + // Ignore the exception if it was due to abort + } catch (LuceneException& e) { + if (!merger->suppressExceptions) { + // suppressExceptions is normally only set during testing. + merger->anyExceptions = true; + merger->handleMergeException(e); + } else { + finally = e; } + } - { - SyncLock syncLock(merger); - merger->notifyAll(); + { + SyncLock syncLock(merger); + merger->notifyAll(); - bool removed = merger->mergeThreads.remove(shared_from_this()); - BOOST_ASSERT(removed); - } - finally.throwException(); + bool removed = merger->mergeThreads.remove(shared_from_this()); + BOOST_ASSERT(removed); } + finally.throwException(); +} + } diff --git a/src/core/index/DefaultSkipListReader.cpp b/src/core/index/DefaultSkipListReader.cpp index f9141864..486f5e9a 100644 --- a/src/core/index/DefaultSkipListReader.cpp +++ b/src/core/index/DefaultSkipListReader.cpp @@ -8,90 +8,82 @@ #include "DefaultSkipListReader.h" #include "MiscUtils.h" -namespace Lucene -{ - DefaultSkipListReader::DefaultSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval) - : MultiLevelSkipListReader(skipStream, maxSkipLevels, skipInterval) - { - currentFieldStoresPayloads = false; - lastFreqPointer = 0; - lastProxPointer = 0; - lastPayloadLength = 0; - - freqPointer = Collection::newInstance(maxSkipLevels); - proxPointer = Collection::newInstance(maxSkipLevels); - payloadLength = Collection::newInstance(maxSkipLevels); - - MiscUtils::arrayFill(freqPointer.begin(), 0, freqPointer.size(), 0); - MiscUtils::arrayFill(proxPointer.begin(), 0, proxPointer.size(), 0); - MiscUtils::arrayFill(payloadLength.begin(), 0, payloadLength.size(), 0); - } +namespace Lucene { - DefaultSkipListReader::~DefaultSkipListReader() - { - } +DefaultSkipListReader::DefaultSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval) + : MultiLevelSkipListReader(skipStream, maxSkipLevels, skipInterval) { + currentFieldStoresPayloads = false; + lastFreqPointer = 0; + lastProxPointer = 0; + lastPayloadLength = 0; - void DefaultSkipListReader::init(int64_t skipPointer, int64_t freqBasePointer, int64_t proxBasePointer, int32_t df, bool storesPayloads) - { - MultiLevelSkipListReader::init(skipPointer, df); - this->currentFieldStoresPayloads = storesPayloads; - lastFreqPointer = freqBasePointer; - lastProxPointer = proxBasePointer; + freqPointer = Collection::newInstance(maxSkipLevels); + proxPointer = Collection::newInstance(maxSkipLevels); + payloadLength = Collection::newInstance(maxSkipLevels); - MiscUtils::arrayFill(freqPointer.begin(), 0, freqPointer.size(), freqBasePointer); - MiscUtils::arrayFill(proxPointer.begin(), 0, proxPointer.size(), proxBasePointer); - MiscUtils::arrayFill(payloadLength.begin(), 0, payloadLength.size(), 0); - } + MiscUtils::arrayFill(freqPointer.begin(), 0, freqPointer.size(), 0); + MiscUtils::arrayFill(proxPointer.begin(), 0, proxPointer.size(), 0); + MiscUtils::arrayFill(payloadLength.begin(), 0, payloadLength.size(), 0); +} - int64_t DefaultSkipListReader::getFreqPointer() - { - return lastFreqPointer; - } +DefaultSkipListReader::~DefaultSkipListReader() { +} - int64_t DefaultSkipListReader::getProxPointer() - { - return lastProxPointer; - } +void DefaultSkipListReader::init(int64_t skipPointer, int64_t freqBasePointer, int64_t proxBasePointer, int32_t df, bool storesPayloads) { + MultiLevelSkipListReader::init(skipPointer, df); + this->currentFieldStoresPayloads = storesPayloads; + lastFreqPointer = freqBasePointer; + lastProxPointer = proxBasePointer; - int32_t DefaultSkipListReader::getPayloadLength() - { - return lastPayloadLength; - } + MiscUtils::arrayFill(freqPointer.begin(), 0, freqPointer.size(), freqBasePointer); + MiscUtils::arrayFill(proxPointer.begin(), 0, proxPointer.size(), proxBasePointer); + MiscUtils::arrayFill(payloadLength.begin(), 0, payloadLength.size(), 0); +} - void DefaultSkipListReader::seekChild(int32_t level) - { - MultiLevelSkipListReader::seekChild(level); - freqPointer[level] = lastFreqPointer; - proxPointer[level] = lastProxPointer; - payloadLength[level] = lastPayloadLength; - } +int64_t DefaultSkipListReader::getFreqPointer() { + return lastFreqPointer; +} - void DefaultSkipListReader::setLastSkipData(int32_t level) - { - MultiLevelSkipListReader::setLastSkipData(level); - lastFreqPointer = freqPointer[level]; - lastProxPointer = proxPointer[level]; - lastPayloadLength = payloadLength[level]; - } +int64_t DefaultSkipListReader::getProxPointer() { + return lastProxPointer; +} - int32_t DefaultSkipListReader::readSkipData(int32_t level, const IndexInputPtr& skipStream) - { - int32_t delta; - if (currentFieldStoresPayloads) - { - // The current field stores payloads. If the doc delta is odd then we have to read the current - // payload length because it differs from the length of the previous payload - delta = skipStream->readVInt(); - if ((delta & 1) != 0) - payloadLength[level] = skipStream->readVInt(); - delta = MiscUtils::unsignedShift(delta, 1); - } - else - delta = skipStream->readVInt(); +int32_t DefaultSkipListReader::getPayloadLength() { + return lastPayloadLength; +} - freqPointer[level] += skipStream->readVInt(); - proxPointer[level] += skipStream->readVInt(); +void DefaultSkipListReader::seekChild(int32_t level) { + MultiLevelSkipListReader::seekChild(level); + freqPointer[level] = lastFreqPointer; + proxPointer[level] = lastProxPointer; + payloadLength[level] = lastPayloadLength; +} + +void DefaultSkipListReader::setLastSkipData(int32_t level) { + MultiLevelSkipListReader::setLastSkipData(level); + lastFreqPointer = freqPointer[level]; + lastProxPointer = proxPointer[level]; + lastPayloadLength = payloadLength[level]; +} - return delta; +int32_t DefaultSkipListReader::readSkipData(int32_t level, const IndexInputPtr& skipStream) { + int32_t delta; + if (currentFieldStoresPayloads) { + // The current field stores payloads. If the doc delta is odd then we have to read the current + // payload length because it differs from the length of the previous payload + delta = skipStream->readVInt(); + if ((delta & 1) != 0) { + payloadLength[level] = skipStream->readVInt(); + } + delta = MiscUtils::unsignedShift(delta, 1); + } else { + delta = skipStream->readVInt(); } + + freqPointer[level] += skipStream->readVInt(); + proxPointer[level] += skipStream->readVInt(); + + return delta; +} + } diff --git a/src/core/index/DefaultSkipListWriter.cpp b/src/core/index/DefaultSkipListWriter.cpp index e1ee7a68..64c5a2cb 100644 --- a/src/core/index/DefaultSkipListWriter.cpp +++ b/src/core/index/DefaultSkipListWriter.cpp @@ -9,110 +9,100 @@ #include "IndexOutput.h" #include "MiscUtils.h" -namespace Lucene -{ - DefaultSkipListWriter::DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, const IndexOutputPtr& freqOutput, const IndexOutputPtr& proxOutput) : MultiLevelSkipListWriter(skipInterval, numberOfSkipLevels, docCount) - { - curDoc = 0; - curStorePayloads = false; - curPayloadLength = 0; - curFreqPointer = 0; - curProxPointer = 0; +namespace Lucene { - this->freqOutput = freqOutput; - this->proxOutput = proxOutput; +DefaultSkipListWriter::DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, const IndexOutputPtr& freqOutput, const IndexOutputPtr& proxOutput) : MultiLevelSkipListWriter(skipInterval, numberOfSkipLevels, docCount) { + curDoc = 0; + curStorePayloads = false; + curPayloadLength = 0; + curFreqPointer = 0; + curProxPointer = 0; - lastSkipDoc = Collection::newInstance(numberOfSkipLevels); - lastSkipPayloadLength = Collection::newInstance(numberOfSkipLevels); - lastSkipFreqPointer = Collection::newInstance(numberOfSkipLevels); - lastSkipProxPointer = Collection::newInstance(numberOfSkipLevels); - } + this->freqOutput = freqOutput; + this->proxOutput = proxOutput; - DefaultSkipListWriter::~DefaultSkipListWriter() - { - } + lastSkipDoc = Collection::newInstance(numberOfSkipLevels); + lastSkipPayloadLength = Collection::newInstance(numberOfSkipLevels); + lastSkipFreqPointer = Collection::newInstance(numberOfSkipLevels); + lastSkipProxPointer = Collection::newInstance(numberOfSkipLevels); +} - void DefaultSkipListWriter::setFreqOutput(const IndexOutputPtr& freqOutput) - { - this->freqOutput = freqOutput; - } +DefaultSkipListWriter::~DefaultSkipListWriter() { +} - void DefaultSkipListWriter::setProxOutput(const IndexOutputPtr& proxOutput) - { - this->proxOutput = proxOutput; - } +void DefaultSkipListWriter::setFreqOutput(const IndexOutputPtr& freqOutput) { + this->freqOutput = freqOutput; +} + +void DefaultSkipListWriter::setProxOutput(const IndexOutputPtr& proxOutput) { + this->proxOutput = proxOutput; +} - void DefaultSkipListWriter::setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength) - { - this->curDoc = doc; - this->curStorePayloads = storePayloads; - this->curPayloadLength = payloadLength; - this->curFreqPointer = freqOutput->getFilePointer(); - if (proxOutput) - this->curProxPointer = proxOutput->getFilePointer(); +void DefaultSkipListWriter::setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength) { + this->curDoc = doc; + this->curStorePayloads = storePayloads; + this->curPayloadLength = payloadLength; + this->curFreqPointer = freqOutput->getFilePointer(); + if (proxOutput) { + this->curProxPointer = proxOutput->getFilePointer(); } +} - void DefaultSkipListWriter::resetSkip() - { - MultiLevelSkipListWriter::resetSkip(); - MiscUtils::arrayFill(lastSkipDoc.begin(), 0, lastSkipDoc.size(), 0); - MiscUtils::arrayFill(lastSkipPayloadLength.begin(), 0, lastSkipPayloadLength.size(), -1); // we don't have to write the first length in the skip list - MiscUtils::arrayFill(lastSkipFreqPointer.begin(), 0, lastSkipFreqPointer.size(), freqOutput->getFilePointer()); - if (proxOutput) - MiscUtils::arrayFill(lastSkipProxPointer.begin(), 0, lastSkipProxPointer.size(), proxOutput->getFilePointer()); +void DefaultSkipListWriter::resetSkip() { + MultiLevelSkipListWriter::resetSkip(); + MiscUtils::arrayFill(lastSkipDoc.begin(), 0, lastSkipDoc.size(), 0); + MiscUtils::arrayFill(lastSkipPayloadLength.begin(), 0, lastSkipPayloadLength.size(), -1); // we don't have to write the first length in the skip list + MiscUtils::arrayFill(lastSkipFreqPointer.begin(), 0, lastSkipFreqPointer.size(), freqOutput->getFilePointer()); + if (proxOutput) { + MiscUtils::arrayFill(lastSkipProxPointer.begin(), 0, lastSkipProxPointer.size(), proxOutput->getFilePointer()); } +} - void DefaultSkipListWriter::writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer) - { - // To efficiently store payloads in the posting lists we do not store the length of - // every payload. Instead we omit the length for a payload if the previous payload had - // the same length. - // However, in order to support skipping the payload length at every skip point must be known. - // So we use the same length encoding that we use for the posting lists for the skip data as well: - // Case 1: current field does not store payloads - // SkipDatum --> DocSkip, FreqSkip, ProxSkip - // DocSkip,FreqSkip,ProxSkip --> VInt - // DocSkip records the document number before every SkipInterval th document in TermFreqs. - // Document numbers are represented as differences from the previous value in the sequence. - // Case 2: current field stores payloads - // SkipDatum --> DocSkip, PayloadLength?, FreqSkip,ProxSkip - // DocSkip,FreqSkip,ProxSkip --> VInt - // PayloadLength --> VInt - // In this case DocSkip/2 is the difference between - // the current and the previous value. If DocSkip - // is odd, then a PayloadLength encoded as VInt follows, - // if DocSkip is even, then it is assumed that the - // current payload length equals the length at the previous - // skip point - if (curStorePayloads) - { - int32_t delta = curDoc - lastSkipDoc[level]; - if (curPayloadLength == lastSkipPayloadLength[level]) - { - // the current payload length equals the length at the previous skip point, so we don't store - // the length again - skipBuffer->writeVInt(delta * 2); - } - else - { - // the payload length is different from the previous one. We shift the DocSkip, set the lowest - // bit and store the current payload length as VInt. - skipBuffer->writeVInt(delta * 2 + 1); - skipBuffer->writeVInt(curPayloadLength); - lastSkipPayloadLength[level] = curPayloadLength; - } - } - else - { - // current field does not store payloads - skipBuffer->writeVInt(curDoc - lastSkipDoc[level]); +void DefaultSkipListWriter::writeSkipData(int32_t level, const IndexOutputPtr& skipBuffer) { + // To efficiently store payloads in the posting lists we do not store the length of + // every payload. Instead we omit the length for a payload if the previous payload had + // the same length. + // However, in order to support skipping the payload length at every skip point must be known. + // So we use the same length encoding that we use for the posting lists for the skip data as well: + // Case 1: current field does not store payloads + // SkipDatum --> DocSkip, FreqSkip, ProxSkip + // DocSkip,FreqSkip,ProxSkip --> VInt + // DocSkip records the document number before every SkipInterval th document in TermFreqs. + // Document numbers are represented as differences from the previous value in the sequence. + // Case 2: current field stores payloads + // SkipDatum --> DocSkip, PayloadLength?, FreqSkip,ProxSkip + // DocSkip,FreqSkip,ProxSkip --> VInt + // PayloadLength --> VInt + // In this case DocSkip/2 is the difference between + // the current and the previous value. If DocSkip + // is odd, then a PayloadLength encoded as VInt follows, + // if DocSkip is even, then it is assumed that the + // current payload length equals the length at the previous + // skip point + if (curStorePayloads) { + int32_t delta = curDoc - lastSkipDoc[level]; + if (curPayloadLength == lastSkipPayloadLength[level]) { + // the current payload length equals the length at the previous skip point, so we don't store + // the length again + skipBuffer->writeVInt(delta * 2); + } else { + // the payload length is different from the previous one. We shift the DocSkip, set the lowest + // bit and store the current payload length as VInt. + skipBuffer->writeVInt(delta * 2 + 1); + skipBuffer->writeVInt(curPayloadLength); + lastSkipPayloadLength[level] = curPayloadLength; } - skipBuffer->writeVInt((int32_t)(curFreqPointer - lastSkipFreqPointer[level])); - skipBuffer->writeVInt((int32_t)(curProxPointer - lastSkipProxPointer[level])); + } else { + // current field does not store payloads + skipBuffer->writeVInt(curDoc - lastSkipDoc[level]); + } + skipBuffer->writeVInt((int32_t)(curFreqPointer - lastSkipFreqPointer[level])); + skipBuffer->writeVInt((int32_t)(curProxPointer - lastSkipProxPointer[level])); - lastSkipDoc[level] = curDoc; + lastSkipDoc[level] = curDoc; + + lastSkipFreqPointer[level] = curFreqPointer; + lastSkipProxPointer[level] = curProxPointer; +} - lastSkipFreqPointer[level] = curFreqPointer; - lastSkipProxPointer[level] = curProxPointer; - } } diff --git a/src/core/index/DirectoryReader.cpp b/src/core/index/DirectoryReader.cpp index 4ab018ea..c59bb404 100644 --- a/src/core/index/DirectoryReader.cpp +++ b/src/core/index/DirectoryReader.cpp @@ -27,1286 +27,1120 @@ #include "FieldCache.h" #include "MiscUtils.h" -namespace Lucene -{ - DirectoryReader::DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) - { - normsCache = MapStringByteArray::newInstance(); - _maxDoc = 0; - _numDocs = -1; - _hasDeletions = false; - synced = HashSet::newInstance(); - stale = false; - rollbackHasChanges = false; - - this->_directory = directory; - this->readOnly = readOnly; - this->segmentInfos = sis; - this->deletionPolicy = deletionPolicy; - this->termInfosIndexDivisor = termInfosIndexDivisor; - - if (!readOnly) - { - // We assume that this segments_N was previously properly sync'd - HashSet files(sis->files(directory, true)); - synced.addAll(files.begin(), files.end()); +namespace Lucene { + +DirectoryReader::DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { + normsCache = MapStringByteArray::newInstance(); + _maxDoc = 0; + _numDocs = -1; + _hasDeletions = false; + synced = HashSet::newInstance(); + stale = false; + rollbackHasChanges = false; + + this->_directory = directory; + this->readOnly = readOnly; + this->segmentInfos = sis; + this->deletionPolicy = deletionPolicy; + this->termInfosIndexDivisor = termInfosIndexDivisor; + + if (!readOnly) { + // We assume that this segments_N was previously properly sync'd + HashSet files(sis->files(directory, true)); + synced.addAll(files.begin(), files.end()); + } + + // To reduce the chance of hitting FileNotFound (and having to retry), we open segments in + // reverse because IndexWriter merges & deletes the newest segments first. + Collection readers(Collection::newInstance(sis->size())); + + for (int32_t i = sis->size() - 1; i >= 0; --i) { + bool success = false; + LuceneException finally; + try { + readers[i] = SegmentReader::get(readOnly, sis->info(i), termInfosIndexDivisor); + success = true; + } catch (LuceneException& e) { + finally = e; } - - // To reduce the chance of hitting FileNotFound (and having to retry), we open segments in - // reverse because IndexWriter merges & deletes the newest segments first. - Collection readers(Collection::newInstance(sis->size())); - - for (int32_t i = sis->size() - 1; i >= 0; --i) - { - bool success = false; - LuceneException finally; - try - { - readers[i] = SegmentReader::get(readOnly, sis->info(i), termInfosIndexDivisor); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - { - // Close all readers we had opened - for (Collection::iterator closeReader = readers.begin(); closeReader != readers.end(); ++closeReader) - { - try - { - if (*closeReader) - (*closeReader)->close(); - } - catch (...) - { - // keep going - we want to clean up as much as possible + if (!success) { + // Close all readers we had opened + for (Collection::iterator closeReader = readers.begin(); closeReader != readers.end(); ++closeReader) { + try { + if (*closeReader) { + (*closeReader)->close(); } + } catch (...) { + // keep going - we want to clean up as much as possible } } - finally.throwException(); } - - _initialize(readers); + finally.throwException(); } - DirectoryReader::DirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor) - { - normsCache = MapStringByteArray::newInstance(); - _maxDoc = 0; - _numDocs = -1; - _hasDeletions = false; - synced = HashSet::newInstance(); - stale = false; - rollbackHasChanges = false; - - this->_directory = writer->getDirectory(); - this->readOnly = true; - this->segmentInfos = infos; - this->segmentInfosStart = boost::dynamic_pointer_cast(infos->clone()); - this->termInfosIndexDivisor = termInfosIndexDivisor; - - if (!readOnly) - { - // We assume that this segments_N was previously properly sync'd - HashSet files(infos->files(_directory, true)); - synced.addAll(files.begin(), files.end()); - } + _initialize(readers); +} - // IndexWriter synchronizes externally before calling us, which ensures infos will not change; so there's - // no need to process segments in reverse order - int32_t numSegments = infos->size(); - Collection readers(Collection::newInstance(numSegments)); - DirectoryPtr dir(writer->getDirectory()); - int32_t upto = 0; - - for (int32_t i = 0; i < numSegments; ++i) - { - bool success = false; - LuceneException finally; - try - { - SegmentInfoPtr info(infos->info(i)); - if (info->dir == dir) - readers[upto++] = boost::dynamic_pointer_cast(writer->readerPool->getReadOnlyClone(info, true, termInfosIndexDivisor)); - success = true; +DirectoryReader::DirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor) { + normsCache = MapStringByteArray::newInstance(); + _maxDoc = 0; + _numDocs = -1; + _hasDeletions = false; + synced = HashSet::newInstance(); + stale = false; + rollbackHasChanges = false; + + this->_directory = writer->getDirectory(); + this->readOnly = true; + this->segmentInfos = infos; + this->segmentInfosStart = boost::dynamic_pointer_cast(infos->clone()); + this->termInfosIndexDivisor = termInfosIndexDivisor; + + if (!readOnly) { + // We assume that this segments_N was previously properly sync'd + HashSet files(infos->files(_directory, true)); + synced.addAll(files.begin(), files.end()); + } + + // IndexWriter synchronizes externally before calling us, which ensures infos will not change; so there's + // no need to process segments in reverse order + int32_t numSegments = infos->size(); + Collection readers(Collection::newInstance(numSegments)); + DirectoryPtr dir(writer->getDirectory()); + int32_t upto = 0; + + for (int32_t i = 0; i < numSegments; ++i) { + bool success = false; + LuceneException finally; + try { + SegmentInfoPtr info(infos->info(i)); + if (info->dir == dir) { + readers[upto++] = boost::dynamic_pointer_cast(writer->readerPool->getReadOnlyClone(info, true, termInfosIndexDivisor)); } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - { - // Close all readers we had opened - for (--upto; upto >= 0; --upto) - { - try - { - if (readers[upto]) - readers[upto]->close(); - } - catch (...) - { - // keep going - we want to clean up as much as possible + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + // Close all readers we had opened + for (--upto; upto >= 0; --upto) { + try { + if (readers[upto]) { + readers[upto]->close(); } + } catch (...) { + // keep going - we want to clean up as much as possible } } - finally.throwException(); } + finally.throwException(); + } - this->_writer = writer; - - if (upto < readers.size()) - { - // This means some segments were in a foreign Directory - readers.resize(upto); - } + this->_writer = writer; - _initialize(readers); + if (upto < readers.size()) { + // This means some segments were in a foreign Directory + readers.resize(upto); } - DirectoryReader::DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, - Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, - bool doClone, int32_t termInfosIndexDivisor) - { - normsCache = MapStringByteArray::newInstance(); - _maxDoc = 0; - _numDocs = -1; - _hasDeletions = false; - synced = HashSet::newInstance(); - stale = false; - rollbackHasChanges = false; - - this->_directory = directory; - this->readOnly = readOnly; - this->segmentInfos = infos; - this->termInfosIndexDivisor = termInfosIndexDivisor; - if (!readOnly) - { - // We assume that this segments_N was previously properly sync'd - HashSet files(infos->files(directory, true)); - synced.addAll(files.begin(), files.end()); - } - - // we put the old SegmentReaders in a map, that allows us to lookup a reader using its segment name - MapStringInt segmentReaders(MapStringInt::newInstance()); + _initialize(readers); +} - if (oldReaders) - { - int32_t segReader = 0; - // create a Map SegmentName->SegmentReader - for (Collection::iterator reader = oldReaders.begin(); reader != oldReaders.end(); ++reader) - segmentReaders.put((*reader)->getSegmentName(), segReader++); +DirectoryReader::DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, + Collection oldStarts, MapStringByteArray oldNormsCache, bool readOnly, + bool doClone, int32_t termInfosIndexDivisor) { + normsCache = MapStringByteArray::newInstance(); + _maxDoc = 0; + _numDocs = -1; + _hasDeletions = false; + synced = HashSet::newInstance(); + stale = false; + rollbackHasChanges = false; + + this->_directory = directory; + this->readOnly = readOnly; + this->segmentInfos = infos; + this->termInfosIndexDivisor = termInfosIndexDivisor; + if (!readOnly) { + // We assume that this segments_N was previously properly sync'd + HashSet files(infos->files(directory, true)); + synced.addAll(files.begin(), files.end()); + } + + // we put the old SegmentReaders in a map, that allows us to lookup a reader using its segment name + MapStringInt segmentReaders(MapStringInt::newInstance()); + + if (oldReaders) { + int32_t segReader = 0; + // create a Map SegmentName->SegmentReader + for (Collection::iterator reader = oldReaders.begin(); reader != oldReaders.end(); ++reader) { + segmentReaders.put((*reader)->getSegmentName(), segReader++); } + } - Collection newReaders(Collection::newInstance(infos->size())); + Collection newReaders(Collection::newInstance(infos->size())); - // remember which readers are shared between the old and the re-opened DirectoryReader - we have to incRef those readers - Collection readerShared(Collection::newInstance(infos->size())); + // remember which readers are shared between the old and the re-opened DirectoryReader - we have to incRef those readers + Collection readerShared(Collection::newInstance(infos->size())); - for (int32_t i = infos->size() - 1; i >= 0; --i) - { - // find SegmentReader for this segment - MapStringInt::iterator oldReaderIndex = segmentReaders.find(infos->info(i)->name); - if (oldReaderIndex == segmentReaders.end()) - { - // this is a new segment, no old SegmentReader can be reused - newReaders[i].reset(); - } - else - { - // there is an old reader for this segment - we'll try to reopen it - newReaders[i] = oldReaders[oldReaderIndex->second]; - } + for (int32_t i = infos->size() - 1; i >= 0; --i) { + // find SegmentReader for this segment + MapStringInt::iterator oldReaderIndex = segmentReaders.find(infos->info(i)->name); + if (oldReaderIndex == segmentReaders.end()) { + // this is a new segment, no old SegmentReader can be reused + newReaders[i].reset(); + } else { + // there is an old reader for this segment - we'll try to reopen it + newReaders[i] = oldReaders[oldReaderIndex->second]; + } - bool success = false; - LuceneException finally; - try - { - SegmentReaderPtr newReader; - if (!newReaders[i] || infos->info(i)->getUseCompoundFile() != newReaders[i]->getSegmentInfo()->getUseCompoundFile()) - { - // We should never see a totally new segment during cloning - BOOST_ASSERT(!doClone); - - // this is a new reader; in case we hit an exception we can close it safely - newReader = SegmentReader::get(readOnly, infos->info(i), termInfosIndexDivisor); - } - else - newReader = newReaders[i]->reopenSegment(infos->info(i), doClone, readOnly); - - if (newReader == newReaders[i]) - { - // this reader will be shared between the old and the new one, so we must incRef it - readerShared[i] = true; - newReader->incRef(); - } - else - { - readerShared[i] = false; - newReaders[i] = newReader; - } - success = true; + bool success = false; + LuceneException finally; + try { + SegmentReaderPtr newReader; + if (!newReaders[i] || infos->info(i)->getUseCompoundFile() != newReaders[i]->getSegmentInfo()->getUseCompoundFile()) { + // We should never see a totally new segment during cloning + BOOST_ASSERT(!doClone); + + // this is a new reader; in case we hit an exception we can close it safely + newReader = SegmentReader::get(readOnly, infos->info(i), termInfosIndexDivisor); + } else { + newReader = newReaders[i]->reopenSegment(infos->info(i), doClone, readOnly); } - catch (LuceneException& e) - { - finally = e; + + if (newReader == newReaders[i]) { + // this reader will be shared between the old and the new one, so we must incRef it + readerShared[i] = true; + newReader->incRef(); + } else { + readerShared[i] = false; + newReaders[i] = newReader; } - if (!success) - { - for (++i; i < infos->size(); ++i) - { - if (newReaders[i]) - { - try - { - if (!readerShared[i]) - { - // this is a new subReader that is not used by the old one, we can close it - newReaders[i]->close(); - } - else - { - // this subReader is also used by the old reader, so instead closing we must decRef it - newReaders[i]->decRef(); - } - } - catch (...) - { - // keep going - we want to clean up as much as possible + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + for (++i; i < infos->size(); ++i) { + if (newReaders[i]) { + try { + if (!readerShared[i]) { + // this is a new subReader that is not used by the old one, we can close it + newReaders[i]->close(); + } else { + // this subReader is also used by the old reader, so instead closing we must decRef it + newReaders[i]->decRef(); } + } catch (...) { + // keep going - we want to clean up as much as possible } } } - finally.throwException(); } + finally.throwException(); + } - // initialize the readers to calculate maxDoc before we try to reuse the old normsCache - _initialize(newReaders); - - // try to copy unchanged norms from the old normsCache to the new one - if (oldNormsCache) - { - for (MapStringByteArray::iterator entry = oldNormsCache.begin(); entry != oldNormsCache.end(); ++entry) - { - if (!hasNorms(entry->first)) - continue; - - ByteArray bytes(ByteArray::newInstance(maxDoc())); - - for (int32_t i = 0; i < subReaders.size(); ++i) - { - MapStringInt::iterator oldReaderIndex = segmentReaders.find(subReaders[i]->getSegmentName()); - - // this SegmentReader was not re-opened, we can copy all of its norms - if (oldReaderIndex != segmentReaders.end() && (oldReaders[oldReaderIndex->second] == subReaders[i] - || oldReaders[oldReaderIndex->second]->_norms.get(entry->first) == subReaders[i]->_norms.get(entry->first))) - { - // we don't have to synchronize here: either this constructor is called from a SegmentReader, in which - // case no old norms cache is present, or it is called from MultiReader.reopen(), which is synchronized - MiscUtils::arrayCopy(entry->second.get(), oldStarts[oldReaderIndex->second], bytes.get(), starts[i], starts[i + 1] - starts[i]); - } - else - subReaders[i]->norms(entry->first, bytes, starts[i]); - } + // initialize the readers to calculate maxDoc before we try to reuse the old normsCache + _initialize(newReaders); + + // try to copy unchanged norms from the old normsCache to the new one + if (oldNormsCache) { + for (MapStringByteArray::iterator entry = oldNormsCache.begin(); entry != oldNormsCache.end(); ++entry) { + if (!hasNorms(entry->first)) { + continue; + } - normsCache.put(entry->first, bytes); // update cache + ByteArray bytes(ByteArray::newInstance(maxDoc())); + + for (int32_t i = 0; i < subReaders.size(); ++i) { + MapStringInt::iterator oldReaderIndex = segmentReaders.find(subReaders[i]->getSegmentName()); + + // this SegmentReader was not re-opened, we can copy all of its norms + if (oldReaderIndex != segmentReaders.end() && (oldReaders[oldReaderIndex->second] == subReaders[i] + || oldReaders[oldReaderIndex->second]->_norms.get(entry->first) == subReaders[i]->_norms.get(entry->first))) { + // we don't have to synchronize here: either this constructor is called from a SegmentReader, in which + // case no old norms cache is present, or it is called from MultiReader.reopen(), which is synchronized + MiscUtils::arrayCopy(entry->second.get(), oldStarts[oldReaderIndex->second], bytes.get(), starts[i], starts[i + 1] - starts[i]); + } else { + subReaders[i]->norms(entry->first, bytes, starts[i]); + } } + + normsCache.put(entry->first, bytes); // update cache } } +} - DirectoryReader::~DirectoryReader() - { - } +DirectoryReader::~DirectoryReader() { +} - void DirectoryReader::_initialize(Collection subReaders) - { - this->subReaders = subReaders; - starts = Collection::newInstance(subReaders.size() + 1); - for (int32_t i = 0; i < subReaders.size(); ++i) - { - starts[i] = _maxDoc; - _maxDoc += subReaders[i]->maxDoc(); // compute maxDocs - - if (subReaders[i]->hasDeletions()) - _hasDeletions = true; - } - starts[subReaders.size()] = _maxDoc; +void DirectoryReader::_initialize(Collection subReaders) { + this->subReaders = subReaders; + starts = Collection::newInstance(subReaders.size() + 1); + for (int32_t i = 0; i < subReaders.size(); ++i) { + starts[i] = _maxDoc; + _maxDoc += subReaders[i]->maxDoc(); // compute maxDocs - if (!readOnly) - maxIndexVersion = SegmentInfos::readCurrentVersion(_directory); + if (subReaders[i]->hasDeletions()) { + _hasDeletions = true; + } } + starts[subReaders.size()] = _maxDoc; - IndexReaderPtr DirectoryReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor) - { - return newLucene(readOnly, deletionPolicy, termInfosIndexDivisor, newLucene(), directory)->run(commit); + if (!readOnly) { + maxIndexVersion = SegmentInfos::readCurrentVersion(_directory); } +} - LuceneObjectPtr DirectoryReader::clone(const LuceneObjectPtr& other) - { - try - { - return DirectoryReader::clone(readOnly, other); // Preserve current readOnly - } - catch (LuceneException& e) - { - boost::throw_exception(RuntimeException(e.getError())); - } - return DirectoryReaderPtr(); +IndexReaderPtr DirectoryReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor) { + return newLucene(readOnly, deletionPolicy, termInfosIndexDivisor, newLucene(), directory)->run(commit); +} + +LuceneObjectPtr DirectoryReader::clone(const LuceneObjectPtr& other) { + try { + return DirectoryReader::clone(readOnly, other); // Preserve current readOnly + } catch (LuceneException& e) { + boost::throw_exception(RuntimeException(e.getError())); } + return DirectoryReaderPtr(); +} - LuceneObjectPtr DirectoryReader::clone(bool openReadOnly, const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - DirectoryReaderPtr newReader(doReopen(boost::dynamic_pointer_cast(segmentInfos->clone()), true, openReadOnly)); - - if (shared_from_this() != newReader) - newReader->deletionPolicy = deletionPolicy; - - newReader->_writer = _writer; - - // If we're cloning a non-readOnly reader, move the writeLock (if there is one) to the new reader - if (!openReadOnly && writeLock) - { - // In near real-time search, reader is always readonly - BOOST_ASSERT(_writer.expired()); - newReader->writeLock = writeLock; - newReader->_hasChanges = _hasChanges; - newReader->_hasDeletions = _hasDeletions; - writeLock.reset(); - _hasChanges = false; - } +LuceneObjectPtr DirectoryReader::clone(bool openReadOnly, const LuceneObjectPtr& other) { + SyncLock syncLock(this); + DirectoryReaderPtr newReader(doReopen(boost::dynamic_pointer_cast(segmentInfos->clone()), true, openReadOnly)); - return newReader; + if (shared_from_this() != newReader) { + newReader->deletionPolicy = deletionPolicy; } - IndexReaderPtr DirectoryReader::reopen() - { - // Preserve current readOnly - return doReopen(readOnly, IndexCommitPtr()); - } + newReader->_writer = _writer; - IndexReaderPtr DirectoryReader::reopen(bool openReadOnly) - { - return doReopen(openReadOnly, IndexCommitPtr()); + // If we're cloning a non-readOnly reader, move the writeLock (if there is one) to the new reader + if (!openReadOnly && writeLock) { + // In near real-time search, reader is always readonly + BOOST_ASSERT(_writer.expired()); + newReader->writeLock = writeLock; + newReader->_hasChanges = _hasChanges; + newReader->_hasDeletions = _hasDeletions; + writeLock.reset(); + _hasChanges = false; } - IndexReaderPtr DirectoryReader::reopen(const IndexCommitPtr& commit) - { - return doReopen(true, commit); - } + return newReader; +} - IndexReaderPtr DirectoryReader::doReopenFromWriter(bool openReadOnly, const IndexCommitPtr& commit) - { - BOOST_ASSERT(readOnly); +IndexReaderPtr DirectoryReader::reopen() { + // Preserve current readOnly + return doReopen(readOnly, IndexCommitPtr()); +} + +IndexReaderPtr DirectoryReader::reopen(bool openReadOnly) { + return doReopen(openReadOnly, IndexCommitPtr()); +} - if (!openReadOnly) - boost::throw_exception(IllegalArgumentException(L"a reader obtained from IndexWriter.getReader() can only be reopened with openReadOnly=true (got false)")); +IndexReaderPtr DirectoryReader::reopen(const IndexCommitPtr& commit) { + return doReopen(true, commit); +} - if (commit) - boost::throw_exception(IllegalArgumentException(L"a reader obtained from IndexWriter.getReader() cannot currently accept a commit")); +IndexReaderPtr DirectoryReader::doReopenFromWriter(bool openReadOnly, const IndexCommitPtr& commit) { + BOOST_ASSERT(readOnly); - return IndexWriterPtr(_writer)->getReader(); + if (!openReadOnly) { + boost::throw_exception(IllegalArgumentException(L"a reader obtained from IndexWriter.getReader() can only be reopened with openReadOnly=true (got false)")); } - IndexReaderPtr DirectoryReader::doReopen(bool openReadOnly, const IndexCommitPtr& commit) - { - ensureOpen(); + if (commit) { + boost::throw_exception(IllegalArgumentException(L"a reader obtained from IndexWriter.getReader() cannot currently accept a commit")); + } + + return IndexWriterPtr(_writer)->getReader(); +} - BOOST_ASSERT(!commit || openReadOnly); +IndexReaderPtr DirectoryReader::doReopen(bool openReadOnly, const IndexCommitPtr& commit) { + ensureOpen(); - IndexWriterPtr writer(_writer.lock()); + BOOST_ASSERT(!commit || openReadOnly); - // If we were obtained by writer.getReader(), re-ask the writer to get a new reader. - if (writer) - return doReopenFromWriter(openReadOnly, commit); - else - return doReopenNoWriter(openReadOnly, commit); + IndexWriterPtr writer(_writer.lock()); + + // If we were obtained by writer.getReader(), re-ask the writer to get a new reader. + if (writer) { + return doReopenFromWriter(openReadOnly, commit); + } else { + return doReopenNoWriter(openReadOnly, commit); } +} - IndexReaderPtr DirectoryReader::doReopenNoWriter(bool openReadOnly, const IndexCommitPtr& commit) - { - SyncLock syncLock(this); - if (!commit) - { - if (_hasChanges) - { - // We have changes, which means we are not readOnly - BOOST_ASSERT(!readOnly); - // and we hold the write lock - BOOST_ASSERT(writeLock); - // so no other writer holds the write lock, which means no changes could have been done to the index - BOOST_ASSERT(isCurrent()); - - if (openReadOnly) - return boost::dynamic_pointer_cast(clone(openReadOnly)); - else - return shared_from_this(); +IndexReaderPtr DirectoryReader::doReopenNoWriter(bool openReadOnly, const IndexCommitPtr& commit) { + SyncLock syncLock(this); + if (!commit) { + if (_hasChanges) { + // We have changes, which means we are not readOnly + BOOST_ASSERT(!readOnly); + // and we hold the write lock + BOOST_ASSERT(writeLock); + // so no other writer holds the write lock, which means no changes could have been done to the index + BOOST_ASSERT(isCurrent()); + + if (openReadOnly) { + return boost::dynamic_pointer_cast(clone(openReadOnly)); + } else { + return shared_from_this(); } - else if (isCurrent()) - { - if (openReadOnly != readOnly) - { - // Just fallback to clone - return boost::dynamic_pointer_cast(clone(openReadOnly)); - } - else - return shared_from_this(); + } else if (isCurrent()) { + if (openReadOnly != readOnly) { + // Just fallback to clone + return boost::dynamic_pointer_cast(clone(openReadOnly)); + } else { + return shared_from_this(); } } - else - { - if (_directory != commit->getDirectory()) - boost::throw_exception(IOException(L"the specified commit does not match the specified Directory")); - if (segmentInfos && commit->getSegmentsFileName() == segmentInfos->getCurrentSegmentFileName()) - { - if (readOnly != openReadOnly) - { - // Just fallback to clone - return boost::dynamic_pointer_cast(clone(openReadOnly)); - } - else - return shared_from_this(); + } else { + if (_directory != commit->getDirectory()) { + boost::throw_exception(IOException(L"the specified commit does not match the specified Directory")); + } + if (segmentInfos && commit->getSegmentsFileName() == segmentInfos->getCurrentSegmentFileName()) { + if (readOnly != openReadOnly) { + // Just fallback to clone + return boost::dynamic_pointer_cast(clone(openReadOnly)); + } else { + return shared_from_this(); } } - - return newLucene(shared_from_this(), openReadOnly, newLucene(), _directory)->run(commit); } - DirectoryReaderPtr DirectoryReader::doReopen(const SegmentInfosPtr& infos, bool doClone, bool openReadOnly) - { - SyncLock syncLock(this); - if (openReadOnly) - return newLucene(_directory, infos, subReaders, starts, normsCache, doClone, termInfosIndexDivisor); - else - return newLucene(_directory, infos, subReaders, starts, normsCache, false, doClone, termInfosIndexDivisor); - } + return newLucene(shared_from_this(), openReadOnly, newLucene(), _directory)->run(commit); +} - int64_t DirectoryReader::getVersion() - { - ensureOpen(); - return segmentInfos->getVersion(); +DirectoryReaderPtr DirectoryReader::doReopen(const SegmentInfosPtr& infos, bool doClone, bool openReadOnly) { + SyncLock syncLock(this); + if (openReadOnly) { + return newLucene(_directory, infos, subReaders, starts, normsCache, doClone, termInfosIndexDivisor); + } else { + return newLucene(_directory, infos, subReaders, starts, normsCache, false, doClone, termInfosIndexDivisor); } +} - Collection DirectoryReader::getTermFreqVectors(int32_t docNumber) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - return subReaders[i]->getTermFreqVectors(docNumber - starts[i]); // dispatch to segment - } +int64_t DirectoryReader::getVersion() { + ensureOpen(); + return segmentInfos->getVersion(); +} - TermFreqVectorPtr DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); - } +Collection DirectoryReader::getTermFreqVectors(int32_t docNumber) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + return subReaders[i]->getTermFreqVectors(docNumber - starts[i]); // dispatch to segment +} - void DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); - } +TermFreqVectorPtr DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); +} - void DirectoryReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - subReaders[i]->getTermFreqVector(docNumber - starts[i], mapper); - } +void DirectoryReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); +} - bool DirectoryReader::isOptimized() - { - ensureOpen(); - return (segmentInfos->size() == 1 && !hasDeletions()); - } +void DirectoryReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + subReaders[i]->getTermFreqVector(docNumber - starts[i], mapper); +} - int32_t DirectoryReader::numDocs() - { - // Don't call ensureOpen() here (it could affect performance) - - // NOTE: multiple threads may wind up init'ing numDocs... but that's harmless - if (_numDocs == -1) // check cache - { - int32_t n = 0; // cache miss - recompute - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - n += (*reader)->numDocs(); // sum from readers - _numDocs = n; +bool DirectoryReader::isOptimized() { + ensureOpen(); + return (segmentInfos->size() == 1 && !hasDeletions()); +} + +int32_t DirectoryReader::numDocs() { + // Don't call ensureOpen() here (it could affect performance) + + // NOTE: multiple threads may wind up init'ing numDocs... but that's harmless + if (_numDocs == -1) { // check cache + int32_t n = 0; // cache miss - recompute + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + n += (*reader)->numDocs(); // sum from readers } - return _numDocs; + _numDocs = n; } + return _numDocs; +} - int32_t DirectoryReader::maxDoc() - { - // Don't call ensureOpen() here (it could affect performance) - return _maxDoc; - } +int32_t DirectoryReader::maxDoc() { + // Don't call ensureOpen() here (it could affect performance) + return _maxDoc; +} - DocumentPtr DirectoryReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) - { - ensureOpen(); - int32_t i = readerIndex(n); // find segment num - return subReaders[i]->document(n - starts[i], fieldSelector); // dispatch to segment reader - } +DocumentPtr DirectoryReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return subReaders[i]->document(n - starts[i], fieldSelector); // dispatch to segment reader +} - bool DirectoryReader::isDeleted(int32_t n) - { - // Don't call ensureOpen() here (it could affect performance) - int32_t i = readerIndex(n); // find segment num - return subReaders[i]->isDeleted(n - starts[i]); // dispatch to segment reader - } +bool DirectoryReader::isDeleted(int32_t n) { + // Don't call ensureOpen() here (it could affect performance) + int32_t i = readerIndex(n); // find segment num + return subReaders[i]->isDeleted(n - starts[i]); // dispatch to segment reader +} - bool DirectoryReader::hasDeletions() - { - // Don't call ensureOpen() here (it could affect performance) - return _hasDeletions; - } +bool DirectoryReader::hasDeletions() { + // Don't call ensureOpen() here (it could affect performance) + return _hasDeletions; +} - void DirectoryReader::doDelete(int32_t docNum) - { - _numDocs = -1; // invalidate cache - int32_t i = readerIndex(docNum); // find segment num - subReaders[i]->deleteDocument(docNum - starts[i]); // dispatch to segment reader - _hasDeletions = true; - } +void DirectoryReader::doDelete(int32_t docNum) { + _numDocs = -1; // invalidate cache + int32_t i = readerIndex(docNum); // find segment num + subReaders[i]->deleteDocument(docNum - starts[i]); // dispatch to segment reader + _hasDeletions = true; +} - void DirectoryReader::doUndeleteAll() - { - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - (*reader)->undeleteAll(); - _hasDeletions = false; - _numDocs = -1; // invalidate cache +void DirectoryReader::doUndeleteAll() { + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + (*reader)->undeleteAll(); } + _hasDeletions = false; + _numDocs = -1; // invalidate cache +} - int32_t DirectoryReader::readerIndex(int32_t n) - { - return readerIndex(n, this->starts, this->subReaders.size()); - } +int32_t DirectoryReader::readerIndex(int32_t n) { + return readerIndex(n, this->starts, this->subReaders.size()); +} - int32_t DirectoryReader::readerIndex(int32_t n, Collection starts, int32_t numSubReaders) - { - // Binary search to locate reader - Collection::iterator reader = std::upper_bound(starts.begin(), starts.begin() + numSubReaders, n); - return (int32_t)(std::distance(starts.begin(), reader) - 1); - } +int32_t DirectoryReader::readerIndex(int32_t n, Collection starts, int32_t numSubReaders) { + // Binary search to locate reader + Collection::iterator reader = std::upper_bound(starts.begin(), starts.begin() + numSubReaders, n); + return (int32_t)(std::distance(starts.begin(), reader) - 1); +} - bool DirectoryReader::hasNorms(const String& field) - { - ensureOpen(); - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - { - if ((*reader)->hasNorms(field)) - return true; +bool DirectoryReader::hasNorms(const String& field) { + ensureOpen(); + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + if ((*reader)->hasNorms(field)) { + return true; } - return false; } + return false; +} - ByteArray DirectoryReader::norms(const String& field) - { - SyncLock syncLock(this); - ensureOpen(); - ByteArray bytes(normsCache.get(field)); - if (bytes) - return bytes; // cache hit - if (!hasNorms(field)) - return ByteArray(); - - bytes = ByteArray::newInstance(maxDoc()); - for (int32_t i = 0; i < subReaders.size(); ++i) - subReaders[i]->norms(field, bytes, starts[i]); - normsCache.put(field, bytes); // update cache - return bytes; +ByteArray DirectoryReader::norms(const String& field) { + SyncLock syncLock(this); + ensureOpen(); + ByteArray bytes(normsCache.get(field)); + if (bytes) { + return bytes; // cache hit + } + if (!hasNorms(field)) { + return ByteArray(); } - void DirectoryReader::norms(const String& field, ByteArray norms, int32_t offset) - { - SyncLock syncLock(this); - ensureOpen(); - ByteArray bytes(normsCache.get(field)); - if (!bytes && !hasNorms(field)) - MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); - else if (bytes) // cache hit - MiscUtils::arrayCopy(bytes.get(), 0, norms.get(), offset, maxDoc()); - else - { - for (int32_t i = 0; i < subReaders.size(); ++i) // read from segments - subReaders[i]->norms(field, norms, offset + starts[i]); - } + bytes = ByteArray::newInstance(maxDoc()); + for (int32_t i = 0; i < subReaders.size(); ++i) { + subReaders[i]->norms(field, bytes, starts[i]); } + normsCache.put(field, bytes); // update cache + return bytes; +} - void DirectoryReader::doSetNorm(int32_t doc, const String& field, uint8_t value) - { - { - SyncLock normsLock(&normsCache); - normsCache.remove(field); // clear cache +void DirectoryReader::norms(const String& field, ByteArray norms, int32_t offset) { + SyncLock syncLock(this); + ensureOpen(); + ByteArray bytes(normsCache.get(field)); + if (!bytes && !hasNorms(field)) { + MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); + } else if (bytes) { // cache hit + MiscUtils::arrayCopy(bytes.get(), 0, norms.get(), offset, maxDoc()); + } else { + for (int32_t i = 0; i < subReaders.size(); ++i) { // read from segments + subReaders[i]->norms(field, norms, offset + starts[i]); } - int32_t i = readerIndex(doc); // find segment num - subReaders[i]->setNorm(doc - starts[i], field, value); // dispatch } +} - TermEnumPtr DirectoryReader::terms() +void DirectoryReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { { - ensureOpen(); - return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, TermPtr()); + SyncLock normsLock(&normsCache); + normsCache.remove(field); // clear cache } + int32_t i = readerIndex(doc); // find segment num + subReaders[i]->setNorm(doc - starts[i], field, value); // dispatch +} - TermEnumPtr DirectoryReader::terms(const TermPtr& t) - { - ensureOpen(); - return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, t); - } +TermEnumPtr DirectoryReader::terms() { + ensureOpen(); + return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, TermPtr()); +} - int32_t DirectoryReader::docFreq(const TermPtr& t) - { - ensureOpen(); - int32_t total = 0; // sum freqs in segments - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - total += (*reader)->docFreq(t); - return total; - } +TermEnumPtr DirectoryReader::terms(const TermPtr& t) { + ensureOpen(); + return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts, t); +} - TermDocsPtr DirectoryReader::termDocs() - { - ensureOpen(); - return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts); +int32_t DirectoryReader::docFreq(const TermPtr& t) { + ensureOpen(); + int32_t total = 0; // sum freqs in segments + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + total += (*reader)->docFreq(t); } + return total; +} - TermPositionsPtr DirectoryReader::termPositions() - { - ensureOpen(); - return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts); +TermDocsPtr DirectoryReader::termDocs() { + ensureOpen(); + return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts); +} + +TermPositionsPtr DirectoryReader::termPositions() { + ensureOpen(); + return newLucene(shared_from_this(), Collection::newInstance(subReaders.begin(), subReaders.end()), starts); +} + +void DirectoryReader::acquireWriteLock() { + if (readOnly) { + // NOTE: we should not reach this code with the core IndexReader classes; + // however, an external subclass of IndexReader could reach this. + ReadOnlySegmentReader::noWrite(); } - void DirectoryReader::acquireWriteLock() - { - if (readOnly) - { - // NOTE: we should not reach this code with the core IndexReader classes; - // however, an external subclass of IndexReader could reach this. - ReadOnlySegmentReader::noWrite(); + if (segmentInfos) { + ensureOpen(); + if (stale) { + boost::throw_exception(StaleReaderException(L"IndexReader out of date and no longer valid for delete, undelete, or setNorm operations")); } - if (segmentInfos) - { - ensureOpen(); - if (stale) + if (!writeLock) { + LockPtr writeLock(_directory->makeLock(IndexWriter::WRITE_LOCK_NAME)); + if (!writeLock->obtain((int32_t)IndexWriter::WRITE_LOCK_TIMEOUT)) { // obtain write lock + boost::throw_exception(LockObtainFailedException(L"Index locked for write: " + writeLock->toString())); + } + this->writeLock = writeLock; + + // we have to check whether index has changed since this reader was opened. + // if so, this reader is no longer valid for deletion + if (SegmentInfos::readCurrentVersion(_directory) > maxIndexVersion) { + stale = true; + this->writeLock->release(); + this->writeLock.reset(); boost::throw_exception(StaleReaderException(L"IndexReader out of date and no longer valid for delete, undelete, or setNorm operations")); - - if (!writeLock) - { - LockPtr writeLock(_directory->makeLock(IndexWriter::WRITE_LOCK_NAME)); - if (!writeLock->obtain((int32_t)IndexWriter::WRITE_LOCK_TIMEOUT)) // obtain write lock - boost::throw_exception(LockObtainFailedException(L"Index locked for write: " + writeLock->toString())); - this->writeLock = writeLock; - - // we have to check whether index has changed since this reader was opened. - // if so, this reader is no longer valid for deletion - if (SegmentInfos::readCurrentVersion(_directory) > maxIndexVersion) - { - stale = true; - this->writeLock->release(); - this->writeLock.reset(); - boost::throw_exception(StaleReaderException(L"IndexReader out of date and no longer valid for delete, undelete, or setNorm operations")); - } } } } +} - void DirectoryReader::doCommit(MapStringString commitUserData) - { - if (_hasChanges) - { - segmentInfos->setUserData(commitUserData); - - // Default deleter (for backwards compatibility) is KeepOnlyLastCommitDeleter - IndexFileDeleterPtr deleter(newLucene(_directory, deletionPolicy ? deletionPolicy : newLucene(), segmentInfos, InfoStreamPtr(), DocumentsWriterPtr(), synced)); - segmentInfos->updateGeneration(deleter->getLastSegmentInfos()); - - // Checkpoint the state we are about to change, in case we have to roll back - startCommit(); - - bool success = false; - LuceneException finally; - try - { - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - (*reader)->commit(); - - // Sync all files we just wrote - HashSet files(segmentInfos->files(_directory, false)); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { - if (!synced.contains(*fileName)) - { - BOOST_ASSERT(_directory->fileExists(*fileName)); - _directory->sync(*fileName); - synced.add(*fileName); - } - } +void DirectoryReader::doCommit(MapStringString commitUserData) { + if (_hasChanges) { + segmentInfos->setUserData(commitUserData); + + // Default deleter (for backwards compatibility) is KeepOnlyLastCommitDeleter + IndexFileDeleterPtr deleter(newLucene(_directory, deletionPolicy ? deletionPolicy : newLucene(), segmentInfos, InfoStreamPtr(), DocumentsWriterPtr(), synced)); + segmentInfos->updateGeneration(deleter->getLastSegmentInfos()); + + // Checkpoint the state we are about to change, in case we have to roll back + startCommit(); - segmentInfos->commit(_directory); - success = true; + bool success = false; + LuceneException finally; + try { + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + (*reader)->commit(); } - catch (LuceneException& e) - { - finally = e; + + // Sync all files we just wrote + HashSet files(segmentInfos->files(_directory, false)); + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + if (!synced.contains(*fileName)) { + BOOST_ASSERT(_directory->fileExists(*fileName)); + _directory->sync(*fileName); + synced.add(*fileName); + } } - if (!success) - { - // Rollback changes that were made to SegmentInfos but failed to get [fully] - // committed. This way this reader instance remains consistent (matched to what's - // actually in the index) - rollbackCommit(); + segmentInfos->commit(_directory); + success = true; + } catch (LuceneException& e) { + finally = e; + } - // Recompute deletable files & remove them (so partially written .del files, etc, - // are removed) - deleter->refresh(); - } - finally.throwException(); + if (!success) { + // Rollback changes that were made to SegmentInfos but failed to get [fully] + // committed. This way this reader instance remains consistent (matched to what's + // actually in the index) + rollbackCommit(); - // Have the deleter remove any now unreferenced files due to this commit - deleter->checkpoint(segmentInfos, true); - deleter->close(); + // Recompute deletable files & remove them (so partially written .del files, etc, + // are removed) + deleter->refresh(); + } + finally.throwException(); - maxIndexVersion = segmentInfos->getVersion(); + // Have the deleter remove any now unreferenced files due to this commit + deleter->checkpoint(segmentInfos, true); + deleter->close(); - if (writeLock) - { - writeLock->release(); // release write lock - writeLock.reset(); - } + maxIndexVersion = segmentInfos->getVersion(); + + if (writeLock) { + writeLock->release(); // release write lock + writeLock.reset(); } - _hasChanges = false; } + _hasChanges = false; +} - void DirectoryReader::startCommit() - { - rollbackHasChanges = _hasChanges; - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - (*reader)->startCommit(); +void DirectoryReader::startCommit() { + rollbackHasChanges = _hasChanges; + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + (*reader)->startCommit(); } +} - void DirectoryReader::rollbackCommit() - { - _hasChanges = rollbackHasChanges; - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - (*reader)->rollbackCommit(); +void DirectoryReader::rollbackCommit() { + _hasChanges = rollbackHasChanges; + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + (*reader)->rollbackCommit(); } +} - MapStringString DirectoryReader::getCommitUserData() - { - ensureOpen(); - return segmentInfos->getUserData(); - } +MapStringString DirectoryReader::getCommitUserData() { + ensureOpen(); + return segmentInfos->getUserData(); +} - bool DirectoryReader::isCurrent() - { - ensureOpen(); - IndexWriterPtr writer(_writer.lock()); - if (!writer || writer->isClosed()) - { - // we loaded SegmentInfos from the directory - return (SegmentInfos::readCurrentVersion(_directory) == segmentInfos->getVersion()); - } - else - return writer->nrtIsCurrent(segmentInfosStart); +bool DirectoryReader::isCurrent() { + ensureOpen(); + IndexWriterPtr writer(_writer.lock()); + if (!writer || writer->isClosed()) { + // we loaded SegmentInfos from the directory + return (SegmentInfos::readCurrentVersion(_directory) == segmentInfos->getVersion()); + } else { + return writer->nrtIsCurrent(segmentInfosStart); } +} - void DirectoryReader::doClose() - { - SyncLock syncLock(this); - LuceneException ioe; - normsCache.reset(); - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - { - // try to close each reader, even if an exception is thrown - try - { - (*reader)->decRef(); - } - catch (LuceneException& e) - { - if (ioe.isNull()) - ioe = e; +void DirectoryReader::doClose() { + SyncLock syncLock(this); + LuceneException ioe; + normsCache.reset(); + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + // try to close each reader, even if an exception is thrown + try { + (*reader)->decRef(); + } catch (LuceneException& e) { + if (ioe.isNull()) { + ioe = e; } } + } - // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is - // generally not a good idea): - FieldCache::DEFAULT()->purge(shared_from_this()); + // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is + // generally not a good idea): + FieldCache::DEFAULT()->purge(shared_from_this()); - // throw the first exception - ioe.throwException(); - } + // throw the first exception + ioe.throwException(); +} - HashSet DirectoryReader::getFieldNames(FieldOption fieldOption) - { - ensureOpen(); - return getFieldNames(fieldOption, Collection::newInstance(subReaders.begin(), subReaders.end())); - } +HashSet DirectoryReader::getFieldNames(FieldOption fieldOption) { + ensureOpen(); + return getFieldNames(fieldOption, Collection::newInstance(subReaders.begin(), subReaders.end())); +} - HashSet DirectoryReader::getFieldNames(FieldOption fieldOption, Collection subReaders) - { - // maintain a unique set of field names - HashSet fieldSet(HashSet::newInstance()); +HashSet DirectoryReader::getFieldNames(FieldOption fieldOption, Collection subReaders) { + // maintain a unique set of field names + HashSet fieldSet(HashSet::newInstance()); - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - { - HashSet names((*reader)->getFieldNames(fieldOption)); - fieldSet.addAll(names.begin(), names.end()); - } - return fieldSet; + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + HashSet names((*reader)->getFieldNames(fieldOption)); + fieldSet.addAll(names.begin(), names.end()); } + return fieldSet; +} - Collection DirectoryReader::getSequentialSubReaders() - { - return Collection::newInstance(subReaders.begin(), subReaders.end()); - } +Collection DirectoryReader::getSequentialSubReaders() { + return Collection::newInstance(subReaders.begin(), subReaders.end()); +} - DirectoryPtr DirectoryReader::directory() - { - // Don't ensureOpen here -- in certain cases, when a cloned/reopened reader needs to commit, it may call - // this method on the closed original reader - return _directory; - } +DirectoryPtr DirectoryReader::directory() { + // Don't ensureOpen here -- in certain cases, when a cloned/reopened reader needs to commit, it may call + // this method on the closed original reader + return _directory; +} - int32_t DirectoryReader::getTermInfosIndexDivisor() - { - return termInfosIndexDivisor; - } +int32_t DirectoryReader::getTermInfosIndexDivisor() { + return termInfosIndexDivisor; +} - IndexCommitPtr DirectoryReader::getIndexCommit() - { - return newLucene(segmentInfos, _directory); - } +IndexCommitPtr DirectoryReader::getIndexCommit() { + return newLucene(segmentInfos, _directory); +} - Collection DirectoryReader::listCommits(const DirectoryPtr& dir) - { - HashSet files(dir->listAll()); +Collection DirectoryReader::listCommits(const DirectoryPtr& dir) { + HashSet files(dir->listAll()); - Collection commits(Collection::newInstance()); + Collection commits(Collection::newInstance()); - SegmentInfosPtr latest(newLucene()); - latest->read(dir); - int64_t currentGen = latest->getGeneration(); + SegmentInfosPtr latest(newLucene()); + latest->read(dir); + int64_t currentGen = latest->getGeneration(); - commits.add(newLucene(latest, dir)); + commits.add(newLucene(latest, dir)); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { - if (boost::starts_with(*fileName, IndexFileNames::SEGMENTS()) && + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + if (boost::starts_with(*fileName, IndexFileNames::SEGMENTS()) && *fileName != IndexFileNames::SEGMENTS_GEN() && - SegmentInfos::generationFromSegmentsFileName(*fileName) < currentGen) - { - SegmentInfosPtr sis(newLucene()); - try - { - // IOException allowed to throw there, in case segments_N is corrupt - sis->read(dir, *fileName); - } - catch (FileNotFoundException&) - { - sis.reset(); - } + SegmentInfos::generationFromSegmentsFileName(*fileName) < currentGen) { + SegmentInfosPtr sis(newLucene()); + try { + // IOException allowed to throw there, in case segments_N is corrupt + sis->read(dir, *fileName); + } catch (FileNotFoundException&) { + sis.reset(); + } - if (sis) - commits.add(newLucene(sis, dir)); + if (sis) { + commits.add(newLucene(sis, dir)); } } - - return commits; } - FindSegmentsOpen::FindSegmentsOpen(bool readOnly, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor, const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) - { - this->readOnly = readOnly; - this->deletionPolicy = deletionPolicy; - this->termInfosIndexDivisor = termInfosIndexDivisor; - } + return commits; +} - FindSegmentsOpen::~FindSegmentsOpen() - { - } +FindSegmentsOpen::FindSegmentsOpen(bool readOnly, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor, const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { + this->readOnly = readOnly; + this->deletionPolicy = deletionPolicy; + this->termInfosIndexDivisor = termInfosIndexDivisor; +} - IndexReaderPtr FindSegmentsOpen::doBody(const String& segmentFileName) - { - SegmentInfosPtr segmentInfos(_segmentInfos); - segmentInfos->read(directory, segmentFileName); - if (readOnly) - return newLucene(directory, segmentInfos, deletionPolicy, termInfosIndexDivisor); - else - return newLucene(directory, segmentInfos, deletionPolicy, false, termInfosIndexDivisor); - } +FindSegmentsOpen::~FindSegmentsOpen() { +} - FindSegmentsReopen::FindSegmentsReopen(const DirectoryReaderPtr& reader, bool openReadOnly, const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) - { - this->_reader = reader; - this->openReadOnly = openReadOnly; +IndexReaderPtr FindSegmentsOpen::doBody(const String& segmentFileName) { + SegmentInfosPtr segmentInfos(_segmentInfos); + segmentInfos->read(directory, segmentFileName); + if (readOnly) { + return newLucene(directory, segmentInfos, deletionPolicy, termInfosIndexDivisor); + } else { + return newLucene(directory, segmentInfos, deletionPolicy, false, termInfosIndexDivisor); } +} - FindSegmentsReopen::~FindSegmentsReopen() - { - } +FindSegmentsReopen::FindSegmentsReopen(const DirectoryReaderPtr& reader, bool openReadOnly, const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { + this->_reader = reader; + this->openReadOnly = openReadOnly; +} - DirectoryReaderPtr FindSegmentsReopen::doBody(const String& segmentFileName) - { - SegmentInfosPtr segmentInfos(_segmentInfos); - segmentInfos->read(directory, segmentFileName); - return DirectoryReaderPtr(_reader)->doReopen(segmentInfos, false, openReadOnly); - } +FindSegmentsReopen::~FindSegmentsReopen() { +} - MultiTermEnum::MultiTermEnum(const IndexReaderPtr& topReader, Collection readers, Collection starts, const TermPtr& t) - { - _docFreq = 0; - this->_topReader = topReader; - queue = newLucene(readers.size()); - matchingSegments = Collection::newInstance(readers.size() + 1); - for (int32_t i = 0; i < readers.size(); ++i) - { - IndexReaderPtr reader(readers[i]); - TermEnumPtr termEnum; - - if (t) - termEnum = reader->terms(t); - else - termEnum = reader->terms(); - - SegmentMergeInfoPtr smi(newLucene(starts[i], termEnum, reader)); - smi->ord = i; - if (t.get() != NULL ? termEnum->term().get() != NULL : smi->next()) - queue->add(smi); // initialize queue - else - smi->close(); +DirectoryReaderPtr FindSegmentsReopen::doBody(const String& segmentFileName) { + SegmentInfosPtr segmentInfos(_segmentInfos); + segmentInfos->read(directory, segmentFileName); + return DirectoryReaderPtr(_reader)->doReopen(segmentInfos, false, openReadOnly); +} + +MultiTermEnum::MultiTermEnum(const IndexReaderPtr& topReader, Collection readers, Collection starts, const TermPtr& t) { + _docFreq = 0; + this->_topReader = topReader; + queue = newLucene(readers.size()); + matchingSegments = Collection::newInstance(readers.size() + 1); + for (int32_t i = 0; i < readers.size(); ++i) { + IndexReaderPtr reader(readers[i]); + TermEnumPtr termEnum; + + if (t) { + termEnum = reader->terms(t); + } else { + termEnum = reader->terms(); } - if (t && !queue->empty()) - next(); + SegmentMergeInfoPtr smi(newLucene(starts[i], termEnum, reader)); + smi->ord = i; + if (t.get() != NULL ? termEnum->term().get() != NULL : smi->next()) { + queue->add(smi); // initialize queue + } else { + smi->close(); + } } - MultiTermEnum::~MultiTermEnum() - { + if (t && !queue->empty()) { + next(); } +} - bool MultiTermEnum::next() - { - for (Collection::iterator smi = matchingSegments.begin(); smi != matchingSegments.end(); ++smi) - { - if (!(*smi)) - break; - if ((*smi)->next()) - queue->add(*smi); - else - (*smi)->close(); // done with segment - } - - int32_t numMatchingSegments = 0; - matchingSegments[0].reset(); - - SegmentMergeInfoPtr top(queue->top()); +MultiTermEnum::~MultiTermEnum() { +} - if (!top) - { - _term.reset(); - return false; +bool MultiTermEnum::next() { + for (Collection::iterator smi = matchingSegments.begin(); smi != matchingSegments.end(); ++smi) { + if (!(*smi)) { + break; + } + if ((*smi)->next()) { + queue->add(*smi); + } else { + (*smi)->close(); // done with segment } + } - _term = top->term; - _docFreq = 0; + int32_t numMatchingSegments = 0; + matchingSegments[0].reset(); - while (top && _term->compareTo(top->term) == 0) - { - matchingSegments[numMatchingSegments++] = top; - queue->pop(); - _docFreq += top->termEnum->docFreq(); // increment freq - top = queue->top(); - } + SegmentMergeInfoPtr top(queue->top()); - matchingSegments[numMatchingSegments].reset(); - return true; + if (!top) { + _term.reset(); + return false; } - TermPtr MultiTermEnum::term() - { - return _term; - } + _term = top->term; + _docFreq = 0; - int32_t MultiTermEnum::docFreq() - { - return _docFreq; + while (top && _term->compareTo(top->term) == 0) { + matchingSegments[numMatchingSegments++] = top; + queue->pop(); + _docFreq += top->termEnum->docFreq(); // increment freq + top = queue->top(); } - void MultiTermEnum::close() - { - queue->close(); - } + matchingSegments[numMatchingSegments].reset(); + return true; +} - MultiTermDocs::MultiTermDocs(const IndexReaderPtr& topReader, Collection r, Collection s) - { - this->_topReader = topReader; - readers = r; - starts = s; - base = 0; - pointer = 0; - readerTermDocs = Collection::newInstance(r.size()); - } +TermPtr MultiTermEnum::term() { + return _term; +} - MultiTermDocs::~MultiTermDocs() - { - } +int32_t MultiTermEnum::docFreq() { + return _docFreq; +} - int32_t MultiTermDocs::doc() - { - return base + current->doc(); - } +void MultiTermEnum::close() { + queue->close(); +} - int32_t MultiTermDocs::freq() - { - return current->freq(); - } +MultiTermDocs::MultiTermDocs(const IndexReaderPtr& topReader, Collection r, Collection s) { + this->_topReader = topReader; + readers = r; + starts = s; + base = 0; + pointer = 0; + readerTermDocs = Collection::newInstance(r.size()); +} - void MultiTermDocs::seek(const TermPtr& term) - { - this->term = term; - this->base = 0; - this->pointer = 0; - this->current.reset(); - this->tenum.reset(); - this->smi.reset(); - this->matchingSegmentPos = 0; - } +MultiTermDocs::~MultiTermDocs() { +} - void MultiTermDocs::seek(const TermEnumPtr& termEnum) - { - seek(termEnum->term()); - MultiTermEnumPtr multiTermEnum(boost::dynamic_pointer_cast(termEnum)); - if (multiTermEnum) - { - tenum = multiTermEnum; - if (IndexReaderPtr(_topReader) != IndexReaderPtr(tenum->_topReader)) - tenum.reset(); - } - } +int32_t MultiTermDocs::doc() { + return base + current->doc(); +} - bool MultiTermDocs::next() - { - while (true) - { - if (current && current->next()) - return true; - else if (pointer < readers.size()) - { - if (tenum) - { - smi = tenum->matchingSegments[matchingSegmentPos++]; - if (!smi) - { - pointer = readers.size(); - return false; - } - pointer = smi->ord; - } - base = starts[pointer]; - current = termDocs(pointer++); - } - else - return false; +int32_t MultiTermDocs::freq() { + return current->freq(); +} + +void MultiTermDocs::seek(const TermPtr& term) { + this->term = term; + this->base = 0; + this->pointer = 0; + this->current.reset(); + this->tenum.reset(); + this->smi.reset(); + this->matchingSegmentPos = 0; +} + +void MultiTermDocs::seek(const TermEnumPtr& termEnum) { + seek(termEnum->term()); + MultiTermEnumPtr multiTermEnum(boost::dynamic_pointer_cast(termEnum)); + if (multiTermEnum) { + tenum = multiTermEnum; + if (IndexReaderPtr(_topReader) != IndexReaderPtr(tenum->_topReader)) { + tenum.reset(); } } +} - int32_t MultiTermDocs::read(Collection docs, Collection freqs) - { - while (true) - { - while (!current) - { - if (pointer < readers.size()) // try next segment - { - if (tenum) - { - smi = tenum->matchingSegments[matchingSegmentPos++]; - if (!smi) - { - pointer = readers.size(); - return 0; - } - pointer = smi->ord; - } - base = starts[pointer]; - current = termDocs(pointer++); +bool MultiTermDocs::next() { + while (true) { + if (current && current->next()) { + return true; + } else if (pointer < readers.size()) { + if (tenum) { + smi = tenum->matchingSegments[matchingSegmentPos++]; + if (!smi) { + pointer = readers.size(); + return false; } - else - return 0; - } - int32_t end = current->read(docs, freqs); - if (end == 0) // none left in segment - current.reset(); - else // got some - { - for (int32_t i = 0; i < end; ++i) // adjust doc numbers - docs[i] += base; - return end; + pointer = smi->ord; } + base = starts[pointer]; + current = termDocs(pointer++); + } else { + return false; } } +} - bool MultiTermDocs::skipTo(int32_t target) - { - while (true) - { - if (current && current->skipTo(target - base)) - return true; - else if (pointer < readers.size()) - { - if (tenum) - { +int32_t MultiTermDocs::read(Collection docs, Collection freqs) { + while (true) { + while (!current) { + if (pointer < readers.size()) { // try next segment + if (tenum) { smi = tenum->matchingSegments[matchingSegmentPos++]; - if (!smi) - { + if (!smi) { pointer = readers.size(); - return false; + return 0; } pointer = smi->ord; } base = starts[pointer]; current = termDocs(pointer++); + } else { + return 0; } - else - return false; + } + int32_t end = current->read(docs, freqs); + if (end == 0) { // none left in segment + current.reset(); + } else { // got some + for (int32_t i = 0; i < end; ++i) { // adjust doc numbers + docs[i] += base; + } + return end; } } +} - TermDocsPtr MultiTermDocs::termDocs(int32_t i) - { - TermDocsPtr result(readerTermDocs[i]); - if (!result) - { - readerTermDocs[i] = termDocs(readers[i]); - result = readerTermDocs[i]; - } - if (smi) - { - BOOST_ASSERT(smi->ord == i); - BOOST_ASSERT(smi->termEnum->term()->equals(term)); - result->seek(smi->termEnum); +bool MultiTermDocs::skipTo(int32_t target) { + while (true) { + if (current && current->skipTo(target - base)) { + return true; + } else if (pointer < readers.size()) { + if (tenum) { + smi = tenum->matchingSegments[matchingSegmentPos++]; + if (!smi) { + pointer = readers.size(); + return false; + } + pointer = smi->ord; + } + base = starts[pointer]; + current = termDocs(pointer++); + } else { + return false; } - else - result->seek(term); - return result; } +} - TermDocsPtr MultiTermDocs::termDocs(const IndexReaderPtr& reader) - { - return term ? reader->termDocs() : reader->termDocs(TermPtr()); +TermDocsPtr MultiTermDocs::termDocs(int32_t i) { + TermDocsPtr result(readerTermDocs[i]); + if (!result) { + readerTermDocs[i] = termDocs(readers[i]); + result = readerTermDocs[i]; + } + if (smi) { + BOOST_ASSERT(smi->ord == i); + BOOST_ASSERT(smi->termEnum->term()->equals(term)); + result->seek(smi->termEnum); + } else { + result->seek(term); } + return result; +} - void MultiTermDocs::close() - { - for (Collection::iterator termDoc = readerTermDocs.begin(); termDoc != readerTermDocs.end(); ++termDoc) - { - if (*termDoc) - (*termDoc)->close(); +TermDocsPtr MultiTermDocs::termDocs(const IndexReaderPtr& reader) { + return term ? reader->termDocs() : reader->termDocs(TermPtr()); +} + +void MultiTermDocs::close() { + for (Collection::iterator termDoc = readerTermDocs.begin(); termDoc != readerTermDocs.end(); ++termDoc) { + if (*termDoc) { + (*termDoc)->close(); } } +} - MultiTermPositions::MultiTermPositions(const IndexReaderPtr& topReader, Collection r, Collection s) : MultiTermDocs(topReader, r, s) - { - } +MultiTermPositions::MultiTermPositions(const IndexReaderPtr& topReader, Collection r, Collection s) : MultiTermDocs(topReader, r, s) { +} - MultiTermPositions::~MultiTermPositions() - { - } +MultiTermPositions::~MultiTermPositions() { +} - TermDocsPtr MultiTermPositions::termDocs(const IndexReaderPtr& reader) - { - return reader->termPositions(); - } +TermDocsPtr MultiTermPositions::termDocs(const IndexReaderPtr& reader) { + return reader->termPositions(); +} - int32_t MultiTermPositions::nextPosition() - { - return boost::static_pointer_cast(current)->nextPosition(); - } +int32_t MultiTermPositions::nextPosition() { + return boost::static_pointer_cast(current)->nextPosition(); +} - int32_t MultiTermPositions::getPayloadLength() - { - return boost::static_pointer_cast(current)->getPayloadLength(); - } +int32_t MultiTermPositions::getPayloadLength() { + return boost::static_pointer_cast(current)->getPayloadLength(); +} - ByteArray MultiTermPositions::getPayload(ByteArray data, int32_t offset) - { - return boost::static_pointer_cast(current)->getPayload(data, offset); - } +ByteArray MultiTermPositions::getPayload(ByteArray data, int32_t offset) { + return boost::static_pointer_cast(current)->getPayload(data, offset); +} - bool MultiTermPositions::isPayloadAvailable() - { - return boost::static_pointer_cast(current)->isPayloadAvailable(); - } +bool MultiTermPositions::isPayloadAvailable() { + return boost::static_pointer_cast(current)->isPayloadAvailable(); +} - ReaderCommit::ReaderCommit(const SegmentInfosPtr& infos, const DirectoryPtr& dir) - { - segmentsFileName = infos->getCurrentSegmentFileName(); - this->dir = dir; - userData = infos->getUserData(); - HashSet files(infos->files(dir, true)); - this->files = HashSet::newInstance(files.begin(), files.end()); - version = infos->getVersion(); - generation = infos->getGeneration(); - _isOptimized = infos->size() == 1 && !infos->info(0)->hasDeletions(); - } +ReaderCommit::ReaderCommit(const SegmentInfosPtr& infos, const DirectoryPtr& dir) { + segmentsFileName = infos->getCurrentSegmentFileName(); + this->dir = dir; + userData = infos->getUserData(); + HashSet files(infos->files(dir, true)); + this->files = HashSet::newInstance(files.begin(), files.end()); + version = infos->getVersion(); + generation = infos->getGeneration(); + _isOptimized = infos->size() == 1 && !infos->info(0)->hasDeletions(); +} - ReaderCommit::~ReaderCommit() - { - } +ReaderCommit::~ReaderCommit() { +} - String ReaderCommit::toString() - { - return L"DirectoryReader::ReaderCommit(" + segmentsFileName + L")"; - } +String ReaderCommit::toString() { + return L"DirectoryReader::ReaderCommit(" + segmentsFileName + L")"; +} - bool ReaderCommit::isOptimized() - { - return _isOptimized; - } +bool ReaderCommit::isOptimized() { + return _isOptimized; +} - String ReaderCommit::getSegmentsFileName() - { - return segmentsFileName; - } +String ReaderCommit::getSegmentsFileName() { + return segmentsFileName; +} - HashSet ReaderCommit::getFileNames() - { - return files; - } +HashSet ReaderCommit::getFileNames() { + return files; +} - DirectoryPtr ReaderCommit::getDirectory() - { - return dir; - } +DirectoryPtr ReaderCommit::getDirectory() { + return dir; +} - int64_t ReaderCommit::getVersion() - { - return version; - } +int64_t ReaderCommit::getVersion() { + return version; +} - int64_t ReaderCommit::getGeneration() - { - return generation; - } +int64_t ReaderCommit::getGeneration() { + return generation; +} - bool ReaderCommit::isDeleted() - { - return false; - } +bool ReaderCommit::isDeleted() { + return false; +} - MapStringString ReaderCommit::getUserData() - { - return userData; - } +MapStringString ReaderCommit::getUserData() { + return userData; +} + +void ReaderCommit::deleteCommit() { + boost::throw_exception(UnsupportedOperationException(L"This IndexCommit does not support deletions.")); +} - void ReaderCommit::deleteCommit() - { - boost::throw_exception(UnsupportedOperationException(L"This IndexCommit does not support deletions.")); - } } diff --git a/src/core/index/DocConsumer.cpp b/src/core/index/DocConsumer.cpp index c90a8670..8004ff73 100644 --- a/src/core/index/DocConsumer.cpp +++ b/src/core/index/DocConsumer.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "DocConsumer.h" -namespace Lucene -{ - DocConsumer::~DocConsumer() - { - } +namespace Lucene { + +DocConsumer::~DocConsumer() { +} + } diff --git a/src/core/index/DocConsumerPerThread.cpp b/src/core/index/DocConsumerPerThread.cpp index 07dec8ec..28997c0d 100644 --- a/src/core/index/DocConsumerPerThread.cpp +++ b/src/core/index/DocConsumerPerThread.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "DocConsumerPerThread.h" -namespace Lucene -{ - DocConsumerPerThread::~DocConsumerPerThread() - { - } +namespace Lucene { + +DocConsumerPerThread::~DocConsumerPerThread() { +} + } diff --git a/src/core/index/DocFieldConsumer.cpp b/src/core/index/DocFieldConsumer.cpp index 3f25a330..bee555bf 100644 --- a/src/core/index/DocFieldConsumer.cpp +++ b/src/core/index/DocFieldConsumer.cpp @@ -7,14 +7,13 @@ #include "LuceneInc.h" #include "DocFieldConsumer.h" -namespace Lucene -{ - DocFieldConsumer::~DocFieldConsumer() - { - } +namespace Lucene { + +DocFieldConsumer::~DocFieldConsumer() { +} + +void DocFieldConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) { + this->fieldInfos = fieldInfos; +} - void DocFieldConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) - { - this->fieldInfos = fieldInfos; - } } diff --git a/src/core/index/DocFieldConsumerPerField.cpp b/src/core/index/DocFieldConsumerPerField.cpp index f93a1a74..0fb3b5a8 100644 --- a/src/core/index/DocFieldConsumerPerField.cpp +++ b/src/core/index/DocFieldConsumerPerField.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "DocFieldConsumerPerField.h" -namespace Lucene -{ - DocFieldConsumerPerField::~DocFieldConsumerPerField() - { - } +namespace Lucene { + +DocFieldConsumerPerField::~DocFieldConsumerPerField() { +} + } diff --git a/src/core/index/DocFieldConsumerPerThread.cpp b/src/core/index/DocFieldConsumerPerThread.cpp index 2495f8e2..ecbbec23 100644 --- a/src/core/index/DocFieldConsumerPerThread.cpp +++ b/src/core/index/DocFieldConsumerPerThread.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "DocFieldConsumerPerThread.h" -namespace Lucene -{ - DocFieldConsumerPerThread::~DocFieldConsumerPerThread() - { - } +namespace Lucene { + +DocFieldConsumerPerThread::~DocFieldConsumerPerThread() { +} + } diff --git a/src/core/index/DocFieldConsumers.cpp b/src/core/index/DocFieldConsumers.cpp index 859a88e5..5198962b 100644 --- a/src/core/index/DocFieldConsumers.cpp +++ b/src/core/index/DocFieldConsumers.cpp @@ -10,168 +10,133 @@ #include "DocFieldConsumersPerThread.h" #include "MiscUtils.h" -namespace Lucene -{ - DocFieldConsumers::DocFieldConsumers(const DocFieldConsumerPtr& one, const DocFieldConsumerPtr& two) - { - freeCount = 0; - allocCount = 0; - docFreeList = Collection::newInstance(1); - - this->one = one; - this->two = two; - } +namespace Lucene { - DocFieldConsumers::~DocFieldConsumers() - { - } +DocFieldConsumers::DocFieldConsumers(const DocFieldConsumerPtr& one, const DocFieldConsumerPtr& two) { + freeCount = 0; + allocCount = 0; + docFreeList = Collection::newInstance(1); - void DocFieldConsumers::setFieldInfos(const FieldInfosPtr& fieldInfos) - { - DocFieldConsumer::setFieldInfos(fieldInfos); - one->setFieldInfos(fieldInfos); - two->setFieldInfos(fieldInfos); - } + this->one = one; + this->two = two; +} - void DocFieldConsumers::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) - { - MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField oneThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); - MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField twoThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); +DocFieldConsumers::~DocFieldConsumers() { +} - for (MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) - { - Collection oneFields(Collection::newInstance()); - Collection twoFields(Collection::newInstance()); +void DocFieldConsumers::setFieldInfos(const FieldInfosPtr& fieldInfos) { + DocFieldConsumer::setFieldInfos(fieldInfos); + one->setFieldInfos(fieldInfos); + two->setFieldInfos(fieldInfos); +} - for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) - { - oneFields.add(boost::static_pointer_cast(*perField)->one); - twoFields.add(boost::static_pointer_cast(*perField)->two); - } +void DocFieldConsumers::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { + MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField oneThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); + MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField twoThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); - oneThreadsAndFields.put(boost::static_pointer_cast(entry->first)->one, oneFields); - twoThreadsAndFields.put(boost::static_pointer_cast(entry->first)->two, oneFields); + for (MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { + Collection oneFields(Collection::newInstance()); + Collection twoFields(Collection::newInstance()); + + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) { + oneFields.add(boost::static_pointer_cast(*perField)->one); + twoFields.add(boost::static_pointer_cast(*perField)->two); } - one->flush(oneThreadsAndFields, state); - two->flush(twoThreadsAndFields, state); + oneThreadsAndFields.put(boost::static_pointer_cast(entry->first)->one, oneFields); + twoThreadsAndFields.put(boost::static_pointer_cast(entry->first)->two, oneFields); } - void DocFieldConsumers::closeDocStore(const SegmentWriteStatePtr& state) - { - LuceneException finally; - try - { - one->closeDocStore(state); - } - catch (LuceneException& e) - { - finally = e; - } - try - { - two->closeDocStore(state); - } - catch (LuceneException& e) - { - finally = e; - } - finally.throwException(); - } + one->flush(oneThreadsAndFields, state); + two->flush(twoThreadsAndFields, state); +} - bool DocFieldConsumers::freeRAM() - { - return (one->freeRAM() || two->freeRAM()); +void DocFieldConsumers::closeDocStore(const SegmentWriteStatePtr& state) { + LuceneException finally; + try { + one->closeDocStore(state); + } catch (LuceneException& e) { + finally = e; } - - DocFieldConsumerPerThreadPtr DocFieldConsumers::addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) - { - return newLucene(docFieldProcessorPerThread, shared_from_this(), one->addThread(docFieldProcessorPerThread), two->addThread(docFieldProcessorPerThread)); + try { + two->closeDocStore(state); + } catch (LuceneException& e) { + finally = e; } + finally.throwException(); +} + +bool DocFieldConsumers::freeRAM() { + return (one->freeRAM() || two->freeRAM()); +} + +DocFieldConsumerPerThreadPtr DocFieldConsumers::addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) { + return newLucene(docFieldProcessorPerThread, shared_from_this(), one->addThread(docFieldProcessorPerThread), two->addThread(docFieldProcessorPerThread)); +} - DocFieldConsumersPerDocPtr DocFieldConsumers::getPerDoc() - { - SyncLock syncLock(this); - if (freeCount == 0) - { - ++allocCount; - if (allocCount > docFreeList.size()) - { - // Grow our free list up front to make sure we have enough space to recycle all outstanding - // PerDoc instances - BOOST_ASSERT(allocCount == 1 + docFreeList.size()); - docFreeList.resize(MiscUtils::getNextSize(allocCount)); - } - return newLucene(shared_from_this()); +DocFieldConsumersPerDocPtr DocFieldConsumers::getPerDoc() { + SyncLock syncLock(this); + if (freeCount == 0) { + ++allocCount; + if (allocCount > docFreeList.size()) { + // Grow our free list up front to make sure we have enough space to recycle all outstanding + // PerDoc instances + BOOST_ASSERT(allocCount == 1 + docFreeList.size()); + docFreeList.resize(MiscUtils::getNextSize(allocCount)); } - else - return docFreeList[--freeCount]; + return newLucene(shared_from_this()); + } else { + return docFreeList[--freeCount]; } +} - void DocFieldConsumers::freePerDoc(const DocFieldConsumersPerDocPtr& perDoc) - { - SyncLock syncLock(this); - BOOST_ASSERT(freeCount < docFreeList.size()); - docFreeList[freeCount++] = perDoc; - } +void DocFieldConsumers::freePerDoc(const DocFieldConsumersPerDocPtr& perDoc) { + SyncLock syncLock(this); + BOOST_ASSERT(freeCount < docFreeList.size()); + docFreeList[freeCount++] = perDoc; +} - DocFieldConsumersPerDoc::DocFieldConsumersPerDoc(const DocFieldConsumersPtr& fieldConsumers) - { - this->_fieldConsumers = fieldConsumers; - } +DocFieldConsumersPerDoc::DocFieldConsumersPerDoc(const DocFieldConsumersPtr& fieldConsumers) { + this->_fieldConsumers = fieldConsumers; +} - DocFieldConsumersPerDoc::~DocFieldConsumersPerDoc() - { - } +DocFieldConsumersPerDoc::~DocFieldConsumersPerDoc() { +} - int64_t DocFieldConsumersPerDoc::sizeInBytes() - { - return one->sizeInBytes() + two->sizeInBytes(); - } +int64_t DocFieldConsumersPerDoc::sizeInBytes() { + return one->sizeInBytes() + two->sizeInBytes(); +} - void DocFieldConsumersPerDoc::finish() - { - LuceneException finally; - try - { - one->finish(); - } - catch (LuceneException& e) - { - finally = e; - } - try - { - two->finish(); - } - catch (LuceneException& e) - { - finally = e; - } - DocFieldConsumersPtr(_fieldConsumers)->freePerDoc(shared_from_this()); - finally.throwException(); +void DocFieldConsumersPerDoc::finish() { + LuceneException finally; + try { + one->finish(); + } catch (LuceneException& e) { + finally = e; + } + try { + two->finish(); + } catch (LuceneException& e) { + finally = e; } + DocFieldConsumersPtr(_fieldConsumers)->freePerDoc(shared_from_this()); + finally.throwException(); +} - void DocFieldConsumersPerDoc::abort() - { - LuceneException finally; - try - { - one->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - try - { - two->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - DocFieldConsumersPtr(_fieldConsumers)->freePerDoc(shared_from_this()); - finally.throwException(); +void DocFieldConsumersPerDoc::abort() { + LuceneException finally; + try { + one->abort(); + } catch (LuceneException& e) { + finally = e; + } + try { + two->abort(); + } catch (LuceneException& e) { + finally = e; } + DocFieldConsumersPtr(_fieldConsumers)->freePerDoc(shared_from_this()); + finally.throwException(); +} + } diff --git a/src/core/index/DocFieldConsumersPerField.cpp b/src/core/index/DocFieldConsumersPerField.cpp index 5b6de8eb..a2f80951 100644 --- a/src/core/index/DocFieldConsumersPerField.cpp +++ b/src/core/index/DocFieldConsumersPerField.cpp @@ -7,44 +7,35 @@ #include "LuceneInc.h" #include "DocFieldConsumersPerField.h" -namespace Lucene -{ - DocFieldConsumersPerField::DocFieldConsumersPerField(const DocFieldConsumersPerThreadPtr& perThread, const DocFieldConsumerPerFieldPtr& one, const DocFieldConsumerPerFieldPtr& two) - { - this->_perThread = perThread; - this->one = one; - this->two = two; - } +namespace Lucene { - DocFieldConsumersPerField::~DocFieldConsumersPerField() - { - } +DocFieldConsumersPerField::DocFieldConsumersPerField(const DocFieldConsumersPerThreadPtr& perThread, const DocFieldConsumerPerFieldPtr& one, const DocFieldConsumerPerFieldPtr& two) { + this->_perThread = perThread; + this->one = one; + this->two = two; +} - void DocFieldConsumersPerField::processFields(Collection fields, int32_t count) - { - one->processFields(fields, count); - two->processFields(fields, count); - } +DocFieldConsumersPerField::~DocFieldConsumersPerField() { +} - void DocFieldConsumersPerField::abort() - { - LuceneException finally; - try - { - one->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - try - { - two->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - finally.throwException(); +void DocFieldConsumersPerField::processFields(Collection fields, int32_t count) { + one->processFields(fields, count); + two->processFields(fields, count); +} + +void DocFieldConsumersPerField::abort() { + LuceneException finally; + try { + one->abort(); + } catch (LuceneException& e) { + finally = e; + } + try { + two->abort(); + } catch (LuceneException& e) { + finally = e; } + finally.throwException(); +} + } diff --git a/src/core/index/DocFieldConsumersPerThread.cpp b/src/core/index/DocFieldConsumersPerThread.cpp index 137a332e..6a7a9bd8 100644 --- a/src/core/index/DocFieldConsumersPerThread.cpp +++ b/src/core/index/DocFieldConsumersPerThread.cpp @@ -10,72 +10,60 @@ #include "DocFieldConsumers.h" #include "DocFieldConsumersPerField.h" -namespace Lucene -{ - DocFieldConsumersPerThread::DocFieldConsumersPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, - const DocFieldConsumersPtr& parent, - const DocFieldConsumerPerThreadPtr& one, const DocFieldConsumerPerThreadPtr& two) - { - this->_parent = parent; - this->one = one; - this->two = two; - docState = docFieldProcessorPerThread->docState; - } +namespace Lucene { - DocFieldConsumersPerThread::~DocFieldConsumersPerThread() - { - } +DocFieldConsumersPerThread::DocFieldConsumersPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, + const DocFieldConsumersPtr& parent, + const DocFieldConsumerPerThreadPtr& one, const DocFieldConsumerPerThreadPtr& two) { + this->_parent = parent; + this->one = one; + this->two = two; + docState = docFieldProcessorPerThread->docState; +} - void DocFieldConsumersPerThread::startDocument() - { - one->startDocument(); - two->startDocument(); - } +DocFieldConsumersPerThread::~DocFieldConsumersPerThread() { +} - void DocFieldConsumersPerThread::abort() - { - LuceneException finally; - try - { - one->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - try - { - two->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - finally.throwException(); - } +void DocFieldConsumersPerThread::startDocument() { + one->startDocument(); + two->startDocument(); +} - DocWriterPtr DocFieldConsumersPerThread::finishDocument() - { - DocWriterPtr oneDoc(one->finishDocument()); - DocWriterPtr twoDoc(two->finishDocument()); - if (!oneDoc) - return twoDoc; - else if (!twoDoc) - return oneDoc; - else - { - DocFieldConsumersPerDocPtr both(DocFieldConsumersPtr(_parent)->getPerDoc()); - both->docID = docState->docID; - BOOST_ASSERT(oneDoc->docID == docState->docID); - BOOST_ASSERT(twoDoc->docID == docState->docID); - both->one = oneDoc; - both->two = twoDoc; - return both; - } +void DocFieldConsumersPerThread::abort() { + LuceneException finally; + try { + one->abort(); + } catch (LuceneException& e) { + finally = e; } + try { + two->abort(); + } catch (LuceneException& e) { + finally = e; + } + finally.throwException(); +} - DocFieldConsumerPerFieldPtr DocFieldConsumersPerThread::addField(const FieldInfoPtr& fi) - { - return newLucene(shared_from_this(), one->addField(fi), two->addField(fi)); +DocWriterPtr DocFieldConsumersPerThread::finishDocument() { + DocWriterPtr oneDoc(one->finishDocument()); + DocWriterPtr twoDoc(two->finishDocument()); + if (!oneDoc) { + return twoDoc; + } else if (!twoDoc) { + return oneDoc; + } else { + DocFieldConsumersPerDocPtr both(DocFieldConsumersPtr(_parent)->getPerDoc()); + both->docID = docState->docID; + BOOST_ASSERT(oneDoc->docID == docState->docID); + BOOST_ASSERT(twoDoc->docID == docState->docID); + both->one = oneDoc; + both->two = twoDoc; + return both; } } + +DocFieldConsumerPerFieldPtr DocFieldConsumersPerThread::addField(const FieldInfoPtr& fi) { + return newLucene(shared_from_this(), one->addField(fi), two->addField(fi)); +} + +} diff --git a/src/core/index/DocFieldProcessor.cpp b/src/core/index/DocFieldProcessor.cpp index 4b109671..d0c18317 100644 --- a/src/core/index/DocFieldProcessor.cpp +++ b/src/core/index/DocFieldProcessor.cpp @@ -15,61 +15,54 @@ #include "FieldInfos.h" #include "TestPoint.h" -namespace Lucene -{ - DocFieldProcessor::DocFieldProcessor(const DocumentsWriterPtr& docWriter, const DocFieldConsumerPtr& consumer) - { - this->fieldInfos = newLucene(); - this->_docWriter = docWriter; - this->consumer = consumer; - consumer->setFieldInfos(fieldInfos); - fieldsWriter = newLucene(docWriter, fieldInfos); - } +namespace Lucene { - DocFieldProcessor::~DocFieldProcessor() - { - } +DocFieldProcessor::DocFieldProcessor(const DocumentsWriterPtr& docWriter, const DocFieldConsumerPtr& consumer) { + this->fieldInfos = newLucene(); + this->_docWriter = docWriter; + this->consumer = consumer; + consumer->setFieldInfos(fieldInfos); + fieldsWriter = newLucene(docWriter, fieldInfos); +} - void DocFieldProcessor::closeDocStore(const SegmentWriteStatePtr& state) - { - consumer->closeDocStore(state); - fieldsWriter->closeDocStore(state); - } +DocFieldProcessor::~DocFieldProcessor() { +} - void DocFieldProcessor::flush(Collection threads, const SegmentWriteStatePtr& state) - { - TestScope testScope(L"DocFieldProcessor", L"flush"); - MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField childThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); +void DocFieldProcessor::closeDocStore(const SegmentWriteStatePtr& state) { + consumer->closeDocStore(state); + fieldsWriter->closeDocStore(state); +} - for (Collection::iterator thread = threads.begin(); thread != threads.end(); ++thread) - { - DocFieldProcessorPerThreadPtr perThread(boost::static_pointer_cast(*thread)); - childThreadsAndFields.put(perThread->consumer, perThread->fields()); - perThread->trimFields(state); - } - fieldsWriter->flush(state); - consumer->flush(childThreadsAndFields, state); +void DocFieldProcessor::flush(Collection threads, const SegmentWriteStatePtr& state) { + TestScope testScope(L"DocFieldProcessor", L"flush"); + MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField childThreadsAndFields(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::newInstance()); - // Important to save after asking consumer to flush so consumer can alter the FieldInfo* if necessary. - // eg FreqProxTermsWriter does this with FieldInfo.storePayload. - String fileName(state->segmentFileName(IndexFileNames::FIELD_INFOS_EXTENSION())); - fieldInfos->write(state->directory, fileName); - state->flushedFiles.add(fileName); + for (Collection::iterator thread = threads.begin(); thread != threads.end(); ++thread) { + DocFieldProcessorPerThreadPtr perThread(boost::static_pointer_cast(*thread)); + childThreadsAndFields.put(perThread->consumer, perThread->fields()); + perThread->trimFields(state); } + fieldsWriter->flush(state); + consumer->flush(childThreadsAndFields, state); - void DocFieldProcessor::abort() - { - fieldsWriter->abort(); - consumer->abort(); - } + // Important to save after asking consumer to flush so consumer can alter the FieldInfo* if necessary. + // eg FreqProxTermsWriter does this with FieldInfo.storePayload. + String fileName(state->segmentFileName(IndexFileNames::FIELD_INFOS_EXTENSION())); + fieldInfos->write(state->directory, fileName); + state->flushedFiles.add(fileName); +} - bool DocFieldProcessor::freeRAM() - { - return consumer->freeRAM(); - } +void DocFieldProcessor::abort() { + fieldsWriter->abort(); + consumer->abort(); +} + +bool DocFieldProcessor::freeRAM() { + return consumer->freeRAM(); +} + +DocConsumerPerThreadPtr DocFieldProcessor::addThread(const DocumentsWriterThreadStatePtr& perThread) { + return newLucene(perThread, shared_from_this()); +} - DocConsumerPerThreadPtr DocFieldProcessor::addThread(const DocumentsWriterThreadStatePtr& perThread) - { - return newLucene(perThread, shared_from_this()); - } } diff --git a/src/core/index/DocFieldProcessorPerField.cpp b/src/core/index/DocFieldProcessorPerField.cpp index 0d95bf8e..63f1044a 100644 --- a/src/core/index/DocFieldProcessorPerField.cpp +++ b/src/core/index/DocFieldProcessorPerField.cpp @@ -10,23 +10,21 @@ #include "DocFieldConsumerPerThread.h" #include "DocFieldConsumerPerField.h" -namespace Lucene -{ - DocFieldProcessorPerField::DocFieldProcessorPerField(const DocFieldProcessorPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) - { - lastGen = -1; - fieldCount = 0; - fields = Collection::newInstance(1); - this->consumer = perThread->consumer->addField(fieldInfo); - this->fieldInfo = fieldInfo; - } +namespace Lucene { - DocFieldProcessorPerField::~DocFieldProcessorPerField() - { - } +DocFieldProcessorPerField::DocFieldProcessorPerField(const DocFieldProcessorPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { + lastGen = -1; + fieldCount = 0; + fields = Collection::newInstance(1); + this->consumer = perThread->consumer->addField(fieldInfo); + this->fieldInfo = fieldInfo; +} + +DocFieldProcessorPerField::~DocFieldProcessorPerField() { +} + +void DocFieldProcessorPerField::abort() { + consumer->abort(); +} - void DocFieldProcessorPerField::abort() - { - consumer->abort(); - } } diff --git a/src/core/index/DocFieldProcessorPerThread.cpp b/src/core/index/DocFieldProcessorPerThread.cpp index fec2c53e..827ee32c 100644 --- a/src/core/index/DocFieldProcessorPerThread.cpp +++ b/src/core/index/DocFieldProcessorPerThread.cpp @@ -25,329 +25,289 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - DocFieldProcessorPerThread::DocFieldProcessorPerThread(const DocumentsWriterThreadStatePtr& threadState, const DocFieldProcessorPtr& docFieldProcessor) - { - _fields = Collection::newInstance(1); - fieldHash = Collection::newInstance(2); - hashMask = 1; - fieldGen = 0; - fieldCount = 0; - totalFieldCount = 0; - - this->docState = threadState->docState; - this->_docFieldProcessor = docFieldProcessor; - this->fieldInfos = docFieldProcessor->fieldInfos; - - docFreeList = Collection::newInstance(1); - freeCount = 0; - allocCount = 0; - } +namespace Lucene { + +DocFieldProcessorPerThread::DocFieldProcessorPerThread(const DocumentsWriterThreadStatePtr& threadState, const DocFieldProcessorPtr& docFieldProcessor) { + _fields = Collection::newInstance(1); + fieldHash = Collection::newInstance(2); + hashMask = 1; + fieldGen = 0; + fieldCount = 0; + totalFieldCount = 0; + + this->docState = threadState->docState; + this->_docFieldProcessor = docFieldProcessor; + this->fieldInfos = docFieldProcessor->fieldInfos; + + docFreeList = Collection::newInstance(1); + freeCount = 0; + allocCount = 0; +} - DocFieldProcessorPerThread::~DocFieldProcessorPerThread() - { - } +DocFieldProcessorPerThread::~DocFieldProcessorPerThread() { +} - void DocFieldProcessorPerThread::initialize() - { - DocFieldProcessorPtr docFieldProcessor(_docFieldProcessor); - consumer = docFieldProcessor->consumer->addThread(shared_from_this()); - fieldsWriter = docFieldProcessor->fieldsWriter->addThread(docState); - } +void DocFieldProcessorPerThread::initialize() { + DocFieldProcessorPtr docFieldProcessor(_docFieldProcessor); + consumer = docFieldProcessor->consumer->addThread(shared_from_this()); + fieldsWriter = docFieldProcessor->fieldsWriter->addThread(docState); +} - void DocFieldProcessorPerThread::abort() - { - for (Collection::iterator field = fieldHash.begin(); field != fieldHash.end(); ++field) - { - DocFieldProcessorPerFieldPtr current(*field); - while (current) - { - DocFieldProcessorPerFieldPtr next(current->next); - current->abort(); - current = next; - } +void DocFieldProcessorPerThread::abort() { + for (Collection::iterator field = fieldHash.begin(); field != fieldHash.end(); ++field) { + DocFieldProcessorPerFieldPtr current(*field); + while (current) { + DocFieldProcessorPerFieldPtr next(current->next); + current->abort(); + current = next; } - fieldsWriter->abort(); - consumer->abort(); } + fieldsWriter->abort(); + consumer->abort(); +} - Collection DocFieldProcessorPerThread::fields() - { - Collection fields(Collection::newInstance()); - for (Collection::iterator field = fieldHash.begin(); field != fieldHash.end(); ++field) - { - DocFieldProcessorPerFieldPtr current(*field); - while (current) - { - fields.add(current->consumer); - current = current->next; - } +Collection DocFieldProcessorPerThread::fields() { + Collection fields(Collection::newInstance()); + for (Collection::iterator field = fieldHash.begin(); field != fieldHash.end(); ++field) { + DocFieldProcessorPerFieldPtr current(*field); + while (current) { + fields.add(current->consumer); + current = current->next; } - BOOST_ASSERT(fields.size() == totalFieldCount); - return fields; } + BOOST_ASSERT(fields.size() == totalFieldCount); + return fields; +} - void DocFieldProcessorPerThread::trimFields(const SegmentWriteStatePtr& state) - { - for (Collection::iterator perField = fieldHash.begin(); perField != fieldHash.end(); ++perField) - { - DocFieldProcessorPerFieldPtr current(*perField); - DocFieldProcessorPerFieldPtr lastPerField; - - while (current) - { - if (current->lastGen == -1) - { - // This field was not seen since the previous flush, so, free up its resources now - - // Unhash - if (!lastPerField) - *perField = current->next; - else - lastPerField->next = current->next; - - DocumentsWriterPtr docWriter(state->_docWriter); - if (docWriter->infoStream) - *(docWriter->infoStream) << L" purge field=" << current->fieldInfo->name << L"\n"; - - --totalFieldCount; +void DocFieldProcessorPerThread::trimFields(const SegmentWriteStatePtr& state) { + for (Collection::iterator perField = fieldHash.begin(); perField != fieldHash.end(); ++perField) { + DocFieldProcessorPerFieldPtr current(*perField); + DocFieldProcessorPerFieldPtr lastPerField; + + while (current) { + if (current->lastGen == -1) { + // This field was not seen since the previous flush, so, free up its resources now + + // Unhash + if (!lastPerField) { + *perField = current->next; + } else { + lastPerField->next = current->next; } - else - { - // Reset - current->lastGen = -1; - lastPerField = current; + + DocumentsWriterPtr docWriter(state->_docWriter); + if (docWriter->infoStream) { + *(docWriter->infoStream) << L" purge field=" << current->fieldInfo->name << L"\n"; } - current = current->next; + --totalFieldCount; + } else { + // Reset + current->lastGen = -1; + lastPerField = current; } - } - } - void DocFieldProcessorPerThread::rehash() - { - int32_t newHashSize = (fieldHash.size() * 2); - BOOST_ASSERT(newHashSize > fieldHash.size()); - - Collection newHashArray(Collection::newInstance(newHashSize)); - - // Rehash - int32_t newHashMask = newHashSize - 1; - for (Collection::iterator fp0 = fieldHash.begin(); fp0 != fieldHash.end(); ++fp0) - { - DocFieldProcessorPerFieldPtr current(*fp0); - while (current) - { - int32_t hashPos2 = StringUtils::hashCode(current->fieldInfo->name) & newHashMask; - DocFieldProcessorPerFieldPtr nextFP0(current->next); - current->next = newHashArray[hashPos2]; - newHashArray[hashPos2] = current; - current = nextFP0; - } + current = current->next; } - - fieldHash = newHashArray; - hashMask = newHashMask; } +} - struct lessFieldInfoName - { - inline bool operator()(const DocFieldProcessorPerFieldPtr& first, const DocFieldProcessorPerFieldPtr& second) const - { - return (first->fieldInfo->name < second->fieldInfo->name); +void DocFieldProcessorPerThread::rehash() { + int32_t newHashSize = (fieldHash.size() * 2); + BOOST_ASSERT(newHashSize > fieldHash.size()); + + Collection newHashArray(Collection::newInstance(newHashSize)); + + // Rehash + int32_t newHashMask = newHashSize - 1; + for (Collection::iterator fp0 = fieldHash.begin(); fp0 != fieldHash.end(); ++fp0) { + DocFieldProcessorPerFieldPtr current(*fp0); + while (current) { + int32_t hashPos2 = StringUtils::hashCode(current->fieldInfo->name) & newHashMask; + DocFieldProcessorPerFieldPtr nextFP0(current->next); + current->next = newHashArray[hashPos2]; + newHashArray[hashPos2] = current; + current = nextFP0; } - }; - - DocWriterPtr DocFieldProcessorPerThread::processDocument() - { - consumer->startDocument(); - fieldsWriter->startDocument(); + } - DocumentPtr doc(docState->doc); + fieldHash = newHashArray; + hashMask = newHashMask; +} - DocFieldProcessorPtr docFieldProcessor(_docFieldProcessor); - DocumentsWriterPtr docWriter(docFieldProcessor->_docWriter); - bool testPoint = IndexWriterPtr(docWriter->_writer)->testPoint(L"DocumentsWriter.ThreadState.init start"); - BOOST_ASSERT(testPoint); +struct lessFieldInfoName { + inline bool operator()(const DocFieldProcessorPerFieldPtr& first, const DocFieldProcessorPerFieldPtr& second) const { + return (first->fieldInfo->name < second->fieldInfo->name); + } +}; - fieldCount = 0; - int32_t thisFieldGen = fieldGen++; +DocWriterPtr DocFieldProcessorPerThread::processDocument() { + consumer->startDocument(); + fieldsWriter->startDocument(); - Collection docFields(doc->getFields()); + DocumentPtr doc(docState->doc); - // Absorb any new fields first seen in this document. - // Also absorb any changes to fields we had already seen before (eg suddenly turning on norms or - // vectors, etc.) - for (Collection::iterator field = docFields.begin(); field != docFields.end(); ++field) - { - String fieldName((*field)->name()); + DocFieldProcessorPtr docFieldProcessor(_docFieldProcessor); + DocumentsWriterPtr docWriter(docFieldProcessor->_docWriter); + bool testPoint = IndexWriterPtr(docWriter->_writer)->testPoint(L"DocumentsWriter.ThreadState.init start"); + BOOST_ASSERT(testPoint); - // Make sure we have a PerField allocated - int32_t hashPos = StringUtils::hashCode(fieldName) & hashMask; + fieldCount = 0; + int32_t thisFieldGen = fieldGen++; - DocFieldProcessorPerFieldPtr fp(fieldHash[hashPos]); - while (fp && fp->fieldInfo->name != fieldName) - fp = fp->next; + Collection docFields(doc->getFields()); - if (!fp) - { - FieldInfoPtr fi(fieldInfos->add(fieldName, (*field)->isIndexed(), (*field)->isTermVectorStored(), - (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), - (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions())); + // Absorb any new fields first seen in this document. + // Also absorb any changes to fields we had already seen before (eg suddenly turning on norms or + // vectors, etc.) + for (Collection::iterator field = docFields.begin(); field != docFields.end(); ++field) { + String fieldName((*field)->name()); - fp = newLucene(shared_from_this(), fi); - fp->next = fieldHash[hashPos]; - fieldHash[hashPos] = fp; - ++totalFieldCount; + // Make sure we have a PerField allocated + int32_t hashPos = StringUtils::hashCode(fieldName) & hashMask; - if (totalFieldCount >= fieldHash.size() / 2) - rehash(); - } - else - { - fp->fieldInfo->update((*field)->isIndexed(), (*field)->isTermVectorStored(), - (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), - (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions()); - } + DocFieldProcessorPerFieldPtr fp(fieldHash[hashPos]); + while (fp && fp->fieldInfo->name != fieldName) { + fp = fp->next; + } - if (thisFieldGen != fp->lastGen) - { - // First time we're seeing this field for this doc - fp->fieldCount = 0; + if (!fp) { + FieldInfoPtr fi(fieldInfos->add(fieldName, (*field)->isIndexed(), (*field)->isTermVectorStored(), + (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), + (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions())); - if (fieldCount == _fields.size()) - _fields.resize(_fields.size() * 2); + fp = newLucene(shared_from_this(), fi); + fp->next = fieldHash[hashPos]; + fieldHash[hashPos] = fp; + ++totalFieldCount; - _fields[fieldCount++] = fp; - fp->lastGen = thisFieldGen; + if (totalFieldCount >= fieldHash.size() / 2) { + rehash(); } - - if (fp->fieldCount == fp->fields.size()) - fp->fields.resize(fp->fields.size() * 2); - - fp->fields[fp->fieldCount++] = *field; - if ((*field)->isStored()) - fieldsWriter->addField(*field, fp->fieldInfo); + } else { + fp->fieldInfo->update((*field)->isIndexed(), (*field)->isTermVectorStored(), + (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), + (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions()); } - // If we are writing vectors then we must visit fields in sorted order so they are written in sorted order. - std::sort(_fields.begin(), _fields.begin() + fieldCount, lessFieldInfoName()); + if (thisFieldGen != fp->lastGen) { + // First time we're seeing this field for this doc + fp->fieldCount = 0; - for (int32_t i = 0; i < fieldCount; ++i) - _fields[i]->consumer->processFields(_fields[i]->fields, _fields[i]->fieldCount); + if (fieldCount == _fields.size()) { + _fields.resize(_fields.size() * 2); + } - if (!docState->maxTermPrefix.empty() && docState->infoStream) - { - *(docState->infoStream) << L"WARNING: document contains at least one immense term (longer than the max length " << - StringUtils::toString(DocumentsWriter::MAX_TERM_LENGTH) << L"), all of which were skipped. " << - L"Please correct the analyzer to not produce such terms. The prefix of the first immense " << - L"term is: '" << StringUtils::toString(docState->maxTermPrefix) << L"...'\n"; - docState->maxTermPrefix.clear(); + _fields[fieldCount++] = fp; + fp->lastGen = thisFieldGen; } - DocWriterPtr one(fieldsWriter->finishDocument()); - DocWriterPtr two(consumer->finishDocument()); - - if (!one) - return two; - else if (!two) - return one; - else - { - DocFieldProcessorPerThreadPerDocPtr both(getPerDoc()); - both->docID = docState->docID; - BOOST_ASSERT(one->docID == docState->docID); - BOOST_ASSERT(two->docID == docState->docID); - both->one = one; - both->two = two; - return both; + if (fp->fieldCount == fp->fields.size()) { + fp->fields.resize(fp->fields.size() * 2); } - } - DocFieldProcessorPerThreadPerDocPtr DocFieldProcessorPerThread::getPerDoc() - { - SyncLock syncLock(this); - if (freeCount == 0) - { - ++allocCount; - if (allocCount > docFreeList.size()) - { - // Grow our free list up front to make sure we have enough space to recycle all - // outstanding PerDoc instances - BOOST_ASSERT(allocCount == docFreeList.size() + 1); - docFreeList.resize(MiscUtils::getNextSize(allocCount)); - } - return newLucene(shared_from_this()); + fp->fields[fp->fieldCount++] = *field; + if ((*field)->isStored()) { + fieldsWriter->addField(*field, fp->fieldInfo); } - else - return docFreeList[--freeCount]; } - void DocFieldProcessorPerThread::freePerDoc(const DocFieldProcessorPerThreadPerDocPtr& perDoc) - { - SyncLock syncLock(this); - BOOST_ASSERT(freeCount < docFreeList.size()); - docFreeList[freeCount++] = perDoc; - } + // If we are writing vectors then we must visit fields in sorted order so they are written in sorted order. + std::sort(_fields.begin(), _fields.begin() + fieldCount, lessFieldInfoName()); - DocFieldProcessorPerThreadPerDoc::DocFieldProcessorPerThreadPerDoc(const DocFieldProcessorPerThreadPtr& docProcessor) - { - this->_docProcessor = docProcessor; + for (int32_t i = 0; i < fieldCount; ++i) { + _fields[i]->consumer->processFields(_fields[i]->fields, _fields[i]->fieldCount); } - DocFieldProcessorPerThreadPerDoc::~DocFieldProcessorPerThreadPerDoc() - { + if (!docState->maxTermPrefix.empty() && docState->infoStream) { + *(docState->infoStream) << L"WARNING: document contains at least one immense term (longer than the max length " << + StringUtils::toString(DocumentsWriter::MAX_TERM_LENGTH) << L"), all of which were skipped. " << + L"Please correct the analyzer to not produce such terms. The prefix of the first immense " << + L"term is: '" << StringUtils::toString(docState->maxTermPrefix) << L"...'\n"; + docState->maxTermPrefix.clear(); } - int64_t DocFieldProcessorPerThreadPerDoc::sizeInBytes() - { - return one->sizeInBytes() + two->sizeInBytes(); + DocWriterPtr one(fieldsWriter->finishDocument()); + DocWriterPtr two(consumer->finishDocument()); + + if (!one) { + return two; + } else if (!two) { + return one; + } else { + DocFieldProcessorPerThreadPerDocPtr both(getPerDoc()); + both->docID = docState->docID; + BOOST_ASSERT(one->docID == docState->docID); + BOOST_ASSERT(two->docID == docState->docID); + both->one = one; + both->two = two; + return both; } +} - void DocFieldProcessorPerThreadPerDoc::finish() - { - LuceneException finally; - try - { - try - { - one->finish(); - } - catch (LuceneException& e) - { - finally = e; - } - two->finish(); +DocFieldProcessorPerThreadPerDocPtr DocFieldProcessorPerThread::getPerDoc() { + SyncLock syncLock(this); + if (freeCount == 0) { + ++allocCount; + if (allocCount > docFreeList.size()) { + // Grow our free list up front to make sure we have enough space to recycle all + // outstanding PerDoc instances + BOOST_ASSERT(allocCount == docFreeList.size() + 1); + docFreeList.resize(MiscUtils::getNextSize(allocCount)); } - catch (LuceneException& e) - { + return newLucene(shared_from_this()); + } else { + return docFreeList[--freeCount]; + } +} + +void DocFieldProcessorPerThread::freePerDoc(const DocFieldProcessorPerThreadPerDocPtr& perDoc) { + SyncLock syncLock(this); + BOOST_ASSERT(freeCount < docFreeList.size()); + docFreeList[freeCount++] = perDoc; +} + +DocFieldProcessorPerThreadPerDoc::DocFieldProcessorPerThreadPerDoc(const DocFieldProcessorPerThreadPtr& docProcessor) { + this->_docProcessor = docProcessor; +} + +DocFieldProcessorPerThreadPerDoc::~DocFieldProcessorPerThreadPerDoc() { +} + +int64_t DocFieldProcessorPerThreadPerDoc::sizeInBytes() { + return one->sizeInBytes() + two->sizeInBytes(); +} + +void DocFieldProcessorPerThreadPerDoc::finish() { + LuceneException finally; + try { + try { + one->finish(); + } catch (LuceneException& e) { finally = e; } - DocFieldProcessorPerThreadPtr(_docProcessor)->freePerDoc(shared_from_this()); - finally.throwException(); + two->finish(); + } catch (LuceneException& e) { + finally = e; } + DocFieldProcessorPerThreadPtr(_docProcessor)->freePerDoc(shared_from_this()); + finally.throwException(); +} - void DocFieldProcessorPerThreadPerDoc::abort() - { - LuceneException finally; - try - { - try - { - one->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - two->abort(); - } - catch (LuceneException& e) - { +void DocFieldProcessorPerThreadPerDoc::abort() { + LuceneException finally; + try { + try { + one->abort(); + } catch (LuceneException& e) { finally = e; } - DocFieldProcessorPerThreadPtr(_docProcessor)->freePerDoc(shared_from_this()); - finally.throwException(); + two->abort(); + } catch (LuceneException& e) { + finally = e; } + DocFieldProcessorPerThreadPtr(_docProcessor)->freePerDoc(shared_from_this()); + finally.throwException(); +} + } diff --git a/src/core/index/DocInverter.cpp b/src/core/index/DocInverter.cpp index 4220b230..ed7a39c7 100644 --- a/src/core/index/DocInverter.cpp +++ b/src/core/index/DocInverter.cpp @@ -15,68 +15,59 @@ #include "DocInverterPerField.h" #include "DocInverterPerThread.h" -namespace Lucene -{ - DocInverter::DocInverter(const InvertedDocConsumerPtr& consumer, const InvertedDocEndConsumerPtr& endConsumer) - { - this->consumer = consumer; - this->endConsumer = endConsumer; - } +namespace Lucene { - DocInverter::~DocInverter() - { - } +DocInverter::DocInverter(const InvertedDocConsumerPtr& consumer, const InvertedDocEndConsumerPtr& endConsumer) { + this->consumer = consumer; + this->endConsumer = endConsumer; +} - void DocInverter::setFieldInfos(const FieldInfosPtr& fieldInfos) - { - DocFieldConsumer::setFieldInfos(fieldInfos); - consumer->setFieldInfos(fieldInfos); - endConsumer->setFieldInfos(fieldInfos); - } +DocInverter::~DocInverter() { +} - void DocInverter::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) - { - MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField childThreadsAndFields(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::newInstance()); - MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField endChildThreadsAndFields(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField::newInstance()); +void DocInverter::setFieldInfos(const FieldInfosPtr& fieldInfos) { + DocFieldConsumer::setFieldInfos(fieldInfos); + consumer->setFieldInfos(fieldInfos); + endConsumer->setFieldInfos(fieldInfos); +} - for (MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) - { - Collection childFields(Collection::newInstance()); - Collection endChildFields(Collection::newInstance()); +void DocInverter::flush(MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { + MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField childThreadsAndFields(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::newInstance()); + MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField endChildThreadsAndFields(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField::newInstance()); - for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) - { - childFields.add(boost::static_pointer_cast(*perField)->consumer); - endChildFields.add(boost::static_pointer_cast(*perField)->endConsumer); - } + for (MapDocFieldConsumerPerThreadCollectionDocFieldConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { + Collection childFields(Collection::newInstance()); + Collection endChildFields(Collection::newInstance()); - childThreadsAndFields.put(boost::static_pointer_cast(entry->first)->consumer, childFields); - endChildThreadsAndFields.put(boost::static_pointer_cast(entry->first)->endConsumer, endChildFields); + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) { + childFields.add(boost::static_pointer_cast(*perField)->consumer); + endChildFields.add(boost::static_pointer_cast(*perField)->endConsumer); } - consumer->flush(childThreadsAndFields, state); - endConsumer->flush(endChildThreadsAndFields, state); + childThreadsAndFields.put(boost::static_pointer_cast(entry->first)->consumer, childFields); + endChildThreadsAndFields.put(boost::static_pointer_cast(entry->first)->endConsumer, endChildFields); } - void DocInverter::closeDocStore(const SegmentWriteStatePtr& state) - { - consumer->closeDocStore(state); - endConsumer->closeDocStore(state); - } + consumer->flush(childThreadsAndFields, state); + endConsumer->flush(endChildThreadsAndFields, state); +} - void DocInverter::abort() - { - consumer->abort(); - endConsumer->abort(); - } +void DocInverter::closeDocStore(const SegmentWriteStatePtr& state) { + consumer->closeDocStore(state); + endConsumer->closeDocStore(state); +} - bool DocInverter::freeRAM() - { - return consumer->freeRAM(); - } +void DocInverter::abort() { + consumer->abort(); + endConsumer->abort(); +} + +bool DocInverter::freeRAM() { + return consumer->freeRAM(); +} + +DocFieldConsumerPerThreadPtr DocInverter::addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) { + return newLucene(docFieldProcessorPerThread, shared_from_this()); +} - DocFieldConsumerPerThreadPtr DocInverter::addThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread) - { - return newLucene(docFieldProcessorPerThread, shared_from_this()); - } } diff --git a/src/core/index/DocInverterPerField.cpp b/src/core/index/DocInverterPerField.cpp index e75f34e6..669c72b9 100644 --- a/src/core/index/DocInverterPerField.cpp +++ b/src/core/index/DocInverterPerField.cpp @@ -25,194 +25,180 @@ #include "InfoStream.h" #include "StringUtils.h" -namespace Lucene -{ - DocInverterPerField::DocInverterPerField(const DocInverterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) - { - this->_perThread = perThread; - this->fieldInfo = fieldInfo; - docState = perThread->docState; - fieldState = perThread->fieldState; - } +namespace Lucene { - DocInverterPerField::~DocInverterPerField() - { - } +DocInverterPerField::DocInverterPerField(const DocInverterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { + this->_perThread = perThread; + this->fieldInfo = fieldInfo; + docState = perThread->docState; + fieldState = perThread->fieldState; +} - void DocInverterPerField::initialize() - { - DocInverterPerThreadPtr perThread(_perThread); - consumer = perThread->consumer->addField(shared_from_this(), fieldInfo); - endConsumer = perThread->endConsumer->addField(shared_from_this(), fieldInfo); - } +DocInverterPerField::~DocInverterPerField() { +} - void DocInverterPerField::abort() - { - consumer->abort(); - endConsumer->abort(); - } +void DocInverterPerField::initialize() { + DocInverterPerThreadPtr perThread(_perThread); + consumer = perThread->consumer->addField(shared_from_this(), fieldInfo); + endConsumer = perThread->endConsumer->addField(shared_from_this(), fieldInfo); +} - void DocInverterPerField::processFields(Collection fields, int32_t count) - { - fieldState->reset(docState->doc->getBoost()); - - int32_t maxFieldLength = docState->maxFieldLength; - bool doInvert = consumer->start(fields, count); - DocumentsWriterPtr docWriter(docState->_docWriter); - DocInverterPerThreadPtr perThread(_perThread); - - for (int32_t i = 0; i < count; ++i) - { - FieldablePtr field = fields[i]; - if (field->isIndexed() && doInvert) - { - bool anyToken; - - if (fieldState->length > 0) - fieldState->position += docState->analyzer->getPositionIncrementGap(fieldInfo->name); - - if (!field->isTokenized()) - { - // un-tokenized field - String stringValue(field->stringValue()); - int32_t valueLength = (int32_t)stringValue.length(); - perThread->singleToken->reinit(stringValue, 0, valueLength); - fieldState->attributeSource = perThread->singleToken; - consumer->start(field); +void DocInverterPerField::abort() { + consumer->abort(); + endConsumer->abort(); +} - bool success = false; - LuceneException finally; - try - { - consumer->add(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - docWriter->setAborting(); - finally.throwException(); - fieldState->offset += valueLength; - ++fieldState->length; - ++fieldState->position; - anyToken = (valueLength > 0); - } - else - { - // tokenized field - TokenStreamPtr stream; - TokenStreamPtr streamValue(field->tokenStreamValue()); - - if (streamValue) - stream = streamValue; - else - { - // the field does not have a TokenStream, so we have to obtain one from the analyzer - ReaderPtr reader; // find or make Reader - ReaderPtr readerValue(field->readerValue()); - - if (readerValue) - reader = readerValue; - else - { - String stringValue(field->stringValue()); - perThread->stringReader->init(stringValue); - reader = perThread->stringReader; - } +void DocInverterPerField::processFields(Collection fields, int32_t count) { + fieldState->reset(docState->doc->getBoost()); - // Tokenize field and add to postingTable - stream = docState->analyzer->reusableTokenStream(fieldInfo->name, reader); - } + int32_t maxFieldLength = docState->maxFieldLength; + bool doInvert = consumer->start(fields, count); + DocumentsWriterPtr docWriter(docState->_docWriter); + DocInverterPerThreadPtr perThread(_perThread); - // reset the TokenStream to the first token - stream->reset(); + for (int32_t i = 0; i < count; ++i) { + FieldablePtr field = fields[i]; + if (field->isIndexed() && doInvert) { + bool anyToken; - int32_t startLength = fieldState->length; + if (fieldState->length > 0) { + fieldState->position += docState->analyzer->getPositionIncrementGap(fieldInfo->name); + } - LuceneException finally; - try - { - int32_t offsetEnd = fieldState->offset - 1; + if (!field->isTokenized()) { + // un-tokenized field + String stringValue(field->stringValue()); + int32_t valueLength = (int32_t)stringValue.length(); + perThread->singleToken->reinit(stringValue, 0, valueLength); + fieldState->attributeSource = perThread->singleToken; + consumer->start(field); + + bool success = false; + LuceneException finally; + try { + consumer->add(); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + docWriter->setAborting(); + } + finally.throwException(); + fieldState->offset += valueLength; + ++fieldState->length; + ++fieldState->position; + anyToken = (valueLength > 0); + } else { + // tokenized field + TokenStreamPtr stream; + TokenStreamPtr streamValue(field->tokenStreamValue()); + + if (streamValue) { + stream = streamValue; + } else { + // the field does not have a TokenStream, so we have to obtain one from the analyzer + ReaderPtr reader; // find or make Reader + ReaderPtr readerValue(field->readerValue()); + + if (readerValue) { + reader = readerValue; + } else { + String stringValue(field->stringValue()); + perThread->stringReader->init(stringValue); + reader = perThread->stringReader; + } - bool hasMoreTokens = stream->incrementToken(); + // Tokenize field and add to postingTable + stream = docState->analyzer->reusableTokenStream(fieldInfo->name, reader); + } - fieldState->attributeSource = stream; + // reset the TokenStream to the first token + stream->reset(); - OffsetAttributePtr offsetAttribute(fieldState->attributeSource->addAttribute()); - PositionIncrementAttributePtr posIncrAttribute(fieldState->attributeSource->addAttribute()); + int32_t startLength = fieldState->length; - consumer->start(field); + LuceneException finally; + try { + int32_t offsetEnd = fieldState->offset - 1; - while (true) - { - // If we hit an exception in stream.next below (which is fairly common, eg if analyzer - // chokes on a given document), then it's non-aborting and (above) this one document - // will be marked as deleted, but still consume a docID - if (!hasMoreTokens) - break; + bool hasMoreTokens = stream->incrementToken(); - int32_t posIncr = posIncrAttribute->getPositionIncrement(); - fieldState->position += posIncr; - if (fieldState->position > 0) - --fieldState->position; + fieldState->attributeSource = stream; - if (posIncr == 0) - ++fieldState->numOverlap; + OffsetAttributePtr offsetAttribute(fieldState->attributeSource->addAttribute()); + PositionIncrementAttributePtr posIncrAttribute(fieldState->attributeSource->addAttribute()); - bool success = false; - try - { - // If we hit an exception in here, we abort all buffered documents since the last - // flush, on the likelihood that the internal state of the consumer is now corrupt - // and should not be flushed to a new segment - consumer->add(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - docWriter->setAborting(); - finally.throwException(); - ++fieldState->position; - offsetEnd = fieldState->offset + offsetAttribute->endOffset(); - if (++fieldState->length >= maxFieldLength) - { - if (docState->infoStream) - *docState->infoStream << L"maxFieldLength " << StringUtils::toString(maxFieldLength) << L" reached for field " << fieldInfo->name << L", ignoring following tokens\n"; - break; - } + consumer->start(field); - hasMoreTokens = stream->incrementToken(); + while (true) { + // If we hit an exception in stream.next below (which is fairly common, eg if analyzer + // chokes on a given document), then it's non-aborting and (above) this one document + // will be marked as deleted, but still consume a docID + if (!hasMoreTokens) { + break; } - // trigger streams to perform end-of-stream operations - stream->end(); + int32_t posIncr = posIncrAttribute->getPositionIncrement(); + fieldState->position += posIncr; + if (fieldState->position > 0) { + --fieldState->position; + } - fieldState->offset += offsetAttribute->endOffset(); - anyToken = (fieldState->length > startLength); - } - catch (LuceneException& e) - { - finally = e; + if (posIncr == 0) { + ++fieldState->numOverlap; + } + + bool success = false; + try { + // If we hit an exception in here, we abort all buffered documents since the last + // flush, on the likelihood that the internal state of the consumer is now corrupt + // and should not be flushed to a new segment + consumer->add(); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + docWriter->setAborting(); + } + finally.throwException(); + ++fieldState->position; + offsetEnd = fieldState->offset + offsetAttribute->endOffset(); + if (++fieldState->length >= maxFieldLength) { + if (docState->infoStream) { + *docState->infoStream << L"maxFieldLength " << StringUtils::toString(maxFieldLength) << L" reached for field " << fieldInfo->name << L", ignoring following tokens\n"; + } + break; + } + + hasMoreTokens = stream->incrementToken(); } - stream->close(); - finally.throwException(); - } - if (anyToken) - fieldState->offset += docState->analyzer->getOffsetGap(field); - fieldState->boost *= field->getBoost(); + // trigger streams to perform end-of-stream operations + stream->end(); + + fieldState->offset += offsetAttribute->endOffset(); + anyToken = (fieldState->length > startLength); + } catch (LuceneException& e) { + finally = e; + } + stream->close(); + finally.throwException(); } - // don't hang onto the field - fields[i].reset(); + if (anyToken) { + fieldState->offset += docState->analyzer->getOffsetGap(field); + } + fieldState->boost *= field->getBoost(); } - consumer->finish(); - endConsumer->finish(); + // don't hang onto the field + fields[i].reset(); } + + consumer->finish(); + endConsumer->finish(); +} + } diff --git a/src/core/index/DocInverterPerThread.cpp b/src/core/index/DocInverterPerThread.cpp index 60df927e..c02747d3 100644 --- a/src/core/index/DocInverterPerThread.cpp +++ b/src/core/index/DocInverterPerThread.cpp @@ -18,80 +18,65 @@ #include "FieldInvertState.h" #include "ReusableStringReader.h" -namespace Lucene -{ - DocInverterPerThread::DocInverterPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocInverterPtr& docInverter) - { - this->fieldState = newLucene(); - this->stringReader = newLucene(); - this->singleToken = newLucene(); - this->_docInverter = docInverter; - this->docState = docFieldProcessorPerThread->docState; - } +namespace Lucene { - DocInverterPerThread::~DocInverterPerThread() - { - } +DocInverterPerThread::DocInverterPerThread(const DocFieldProcessorPerThreadPtr& docFieldProcessorPerThread, const DocInverterPtr& docInverter) { + this->fieldState = newLucene(); + this->stringReader = newLucene(); + this->singleToken = newLucene(); + this->_docInverter = docInverter; + this->docState = docFieldProcessorPerThread->docState; +} - void DocInverterPerThread::initialize() - { - DocInverterPtr docInverter(_docInverter); - consumer = docInverter->consumer->addThread(shared_from_this()); - endConsumer = docInverter->endConsumer->addThread(shared_from_this()); - } +DocInverterPerThread::~DocInverterPerThread() { +} - void DocInverterPerThread::startDocument() - { - consumer->startDocument(); - endConsumer->startDocument(); - } +void DocInverterPerThread::initialize() { + DocInverterPtr docInverter(_docInverter); + consumer = docInverter->consumer->addThread(shared_from_this()); + endConsumer = docInverter->endConsumer->addThread(shared_from_this()); +} - DocWriterPtr DocInverterPerThread::finishDocument() - { - endConsumer->finishDocument(); - return consumer->finishDocument(); - } +void DocInverterPerThread::startDocument() { + consumer->startDocument(); + endConsumer->startDocument(); +} - void DocInverterPerThread::abort() - { - LuceneException finally; - try - { - consumer->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - try - { - endConsumer->abort(); - } - catch (LuceneException& e) - { - finally = e; - } - finally.throwException(); - } +DocWriterPtr DocInverterPerThread::finishDocument() { + endConsumer->finishDocument(); + return consumer->finishDocument(); +} - DocFieldConsumerPerFieldPtr DocInverterPerThread::addField(const FieldInfoPtr& fi) - { - return newLucene(shared_from_this(), fi); +void DocInverterPerThread::abort() { + LuceneException finally; + try { + consumer->abort(); + } catch (LuceneException& e) { + finally = e; } - - SingleTokenAttributeSource::SingleTokenAttributeSource() - { - termAttribute = addAttribute(); - offsetAttribute = addAttribute(); + try { + endConsumer->abort(); + } catch (LuceneException& e) { + finally = e; } + finally.throwException(); +} - SingleTokenAttributeSource::~SingleTokenAttributeSource() - { - } +DocFieldConsumerPerFieldPtr DocInverterPerThread::addField(const FieldInfoPtr& fi) { + return newLucene(shared_from_this(), fi); +} + +SingleTokenAttributeSource::SingleTokenAttributeSource() { + termAttribute = addAttribute(); + offsetAttribute = addAttribute(); +} + +SingleTokenAttributeSource::~SingleTokenAttributeSource() { +} + +void SingleTokenAttributeSource::reinit(const String& stringValue, int32_t startOffset, int32_t endOffset) { + termAttribute->setTermBuffer(stringValue); + offsetAttribute->setOffset(startOffset, endOffset); +} - void SingleTokenAttributeSource::reinit(const String& stringValue, int32_t startOffset, int32_t endOffset) - { - termAttribute->setTermBuffer(stringValue); - offsetAttribute->setOffset(startOffset, endOffset); - } } diff --git a/src/core/index/DocumentsWriter.cpp b/src/core/index/DocumentsWriter.cpp index a458c6f4..29b36c75 100644 --- a/src/core/index/DocumentsWriter.cpp +++ b/src/core/index/DocumentsWriter.cpp @@ -40,1604 +40,1411 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// Max # ThreadState instances; if there are more threads than this they share ThreadStates - const int32_t DocumentsWriter::MAX_THREAD_STATE = 5; - - /// Coarse estimates used to measure RAM usage of buffered deletes - const int32_t DocumentsWriter::OBJECT_HEADER_BYTES = 8; - #ifdef LPP_BUILD_64 - const int32_t DocumentsWriter::POINTER_NUM_BYTE = 8; - #else - const int32_t DocumentsWriter::POINTER_NUM_BYTE = 4; - #endif - const int32_t DocumentsWriter::INT_NUM_BYTE = 4; - #ifdef LPP_UNICODE_CHAR_SIZE_4 - const int32_t DocumentsWriter::CHAR_NUM_BYTE = 4; - #else - const int32_t DocumentsWriter::CHAR_NUM_BYTE = 2; - #endif - - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is - /// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since - /// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). - /// BufferedDeletes.num is OBJ_HEADER + INT. - const int32_t DocumentsWriter::BYTES_PER_DEL_TERM = 8 * DocumentsWriter::POINTER_NUM_BYTE + 5 * - DocumentsWriter::OBJECT_HEADER_BYTES + 6 * - DocumentsWriter::INT_NUM_BYTE; - - /// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is - /// OBJ_HEADER + int - const int32_t DocumentsWriter::BYTES_PER_DEL_DOCID = 2 * DocumentsWriter::POINTER_NUM_BYTE + - DocumentsWriter::OBJECT_HEADER_BYTES + - DocumentsWriter::INT_NUM_BYTE; - - /// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object - /// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount - /// (say 24 bytes). Integer is OBJ_HEADER + INT. - const int32_t DocumentsWriter::BYTES_PER_DEL_QUERY = 5 * DocumentsWriter::POINTER_NUM_BYTE + 2 * - DocumentsWriter::OBJECT_HEADER_BYTES + 2 * - DocumentsWriter::INT_NUM_BYTE + 24; - - /// Initial chunks size of the shared byte[] blocks used to store postings data - const int32_t DocumentsWriter::BYTE_BLOCK_SHIFT = 15; - const int32_t DocumentsWriter::BYTE_BLOCK_SIZE = 1 << DocumentsWriter::BYTE_BLOCK_SHIFT; - const int32_t DocumentsWriter::BYTE_BLOCK_MASK = DocumentsWriter::BYTE_BLOCK_SIZE - 1; - const int32_t DocumentsWriter::BYTE_BLOCK_NOT_MASK = ~DocumentsWriter::BYTE_BLOCK_MASK; - - /// Initial chunk size of the shared char[] blocks used to store term text - const int32_t DocumentsWriter::CHAR_BLOCK_SHIFT = 14; - const int32_t DocumentsWriter::CHAR_BLOCK_SIZE = 1 << DocumentsWriter::CHAR_BLOCK_SHIFT; - const int32_t DocumentsWriter::CHAR_BLOCK_MASK = DocumentsWriter::CHAR_BLOCK_SIZE - 1; - - const int32_t DocumentsWriter::MAX_TERM_LENGTH = DocumentsWriter::CHAR_BLOCK_SIZE - 1; - - /// Initial chunks size of the shared int[] blocks used to store postings data - const int32_t DocumentsWriter::INT_BLOCK_SHIFT = 13; - const int32_t DocumentsWriter::INT_BLOCK_SIZE = 1 << DocumentsWriter::INT_BLOCK_SHIFT; - const int32_t DocumentsWriter::INT_BLOCK_MASK = DocumentsWriter::INT_BLOCK_SIZE - 1; - - const int32_t DocumentsWriter::PER_DOC_BLOCK_SIZE = 1024; - - DocumentsWriter::DocumentsWriter(const DirectoryPtr& directory, const IndexWriterPtr& writer, const IndexingChainPtr& indexingChain) - { - this->threadStates = Collection::newInstance(); - this->threadBindings = MapThreadDocumentsWriterThreadState::newInstance(); - this->_openFiles = HashSet::newInstance(); - this->_closedFiles = HashSet::newInstance(); - this->freeIntBlocks = Collection::newInstance(); - this->freeCharBlocks = Collection::newInstance(); - - this->directory = directory; - this->_writer = writer; - this->indexingChain = indexingChain; - } +namespace Lucene { + +/// Max # ThreadState instances; if there are more threads than this they share ThreadStates +const int32_t DocumentsWriter::MAX_THREAD_STATE = 5; + +/// Coarse estimates used to measure RAM usage of buffered deletes +const int32_t DocumentsWriter::OBJECT_HEADER_BYTES = 8; +#ifdef LPP_BUILD_64 +const int32_t DocumentsWriter::POINTER_NUM_BYTE = 8; +#else +const int32_t DocumentsWriter::POINTER_NUM_BYTE = 4; +#endif +const int32_t DocumentsWriter::INT_NUM_BYTE = 4; +#ifdef LPP_UNICODE_CHAR_SIZE_4 +const int32_t DocumentsWriter::CHAR_NUM_BYTE = 4; +#else +const int32_t DocumentsWriter::CHAR_NUM_BYTE = 2; +#endif + +/// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object +/// with Term key, BufferedDeletes.Num val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Term is +/// object with String field and String text (OBJ_HEADER + 2*POINTER). We don't count Term's field since +/// it's interned. Term's text is String (OBJ_HEADER + 4*INT + POINTER + OBJ_HEADER + string.length*CHAR). +/// BufferedDeletes.num is OBJ_HEADER + INT. +const int32_t DocumentsWriter::BYTES_PER_DEL_TERM = 8 * DocumentsWriter::POINTER_NUM_BYTE + 5 * + DocumentsWriter::OBJECT_HEADER_BYTES + 6 * + DocumentsWriter::INT_NUM_BYTE; + +/// Rough logic: del docIDs are List. Say list allocates ~2X size (2*POINTER). Integer is +/// OBJ_HEADER + int +const int32_t DocumentsWriter::BYTES_PER_DEL_DOCID = 2 * DocumentsWriter::POINTER_NUM_BYTE + + DocumentsWriter::OBJECT_HEADER_BYTES + + DocumentsWriter::INT_NUM_BYTE; + +/// Rough logic: HashMap has an array[Entry] with varying load factor (say 2 * POINTER). Entry is object +/// with Query key, Integer val, int hash, Entry next (OBJ_HEADER + 3*POINTER + INT). Query we often undercount +/// (say 24 bytes). Integer is OBJ_HEADER + INT. +const int32_t DocumentsWriter::BYTES_PER_DEL_QUERY = 5 * DocumentsWriter::POINTER_NUM_BYTE + 2 * + DocumentsWriter::OBJECT_HEADER_BYTES + 2 * + DocumentsWriter::INT_NUM_BYTE + 24; + +/// Initial chunks size of the shared byte[] blocks used to store postings data +const int32_t DocumentsWriter::BYTE_BLOCK_SHIFT = 15; +const int32_t DocumentsWriter::BYTE_BLOCK_SIZE = 1 << DocumentsWriter::BYTE_BLOCK_SHIFT; +const int32_t DocumentsWriter::BYTE_BLOCK_MASK = DocumentsWriter::BYTE_BLOCK_SIZE - 1; +const int32_t DocumentsWriter::BYTE_BLOCK_NOT_MASK = ~DocumentsWriter::BYTE_BLOCK_MASK; + +/// Initial chunk size of the shared char[] blocks used to store term text +const int32_t DocumentsWriter::CHAR_BLOCK_SHIFT = 14; +const int32_t DocumentsWriter::CHAR_BLOCK_SIZE = 1 << DocumentsWriter::CHAR_BLOCK_SHIFT; +const int32_t DocumentsWriter::CHAR_BLOCK_MASK = DocumentsWriter::CHAR_BLOCK_SIZE - 1; + +const int32_t DocumentsWriter::MAX_TERM_LENGTH = DocumentsWriter::CHAR_BLOCK_SIZE - 1; + +/// Initial chunks size of the shared int[] blocks used to store postings data +const int32_t DocumentsWriter::INT_BLOCK_SHIFT = 13; +const int32_t DocumentsWriter::INT_BLOCK_SIZE = 1 << DocumentsWriter::INT_BLOCK_SHIFT; +const int32_t DocumentsWriter::INT_BLOCK_MASK = DocumentsWriter::INT_BLOCK_SIZE - 1; + +const int32_t DocumentsWriter::PER_DOC_BLOCK_SIZE = 1024; + +DocumentsWriter::DocumentsWriter(const DirectoryPtr& directory, const IndexWriterPtr& writer, const IndexingChainPtr& indexingChain) { + this->threadStates = Collection::newInstance(); + this->threadBindings = MapThreadDocumentsWriterThreadState::newInstance(); + this->_openFiles = HashSet::newInstance(); + this->_closedFiles = HashSet::newInstance(); + this->freeIntBlocks = Collection::newInstance(); + this->freeCharBlocks = Collection::newInstance(); + + this->directory = directory; + this->_writer = writer; + this->indexingChain = indexingChain; +} - DocumentsWriter::~DocumentsWriter() - { - } +DocumentsWriter::~DocumentsWriter() { +} - void DocumentsWriter::initialize() - { - docStoreOffset = 0; - nextDocID = 0; - numDocsInRAM = 0; - numDocsInStore = 0; - pauseThreads = 0; - flushPending = false; - bufferIsFull = false; - aborting = false; - maxFieldLength = IndexWriter::DEFAULT_MAX_FIELD_LENGTH; - deletesInRAM = newLucene(false); - deletesFlushed = newLucene(true); - maxBufferedDeleteTerms = IndexWriter::DEFAULT_MAX_BUFFERED_DELETE_TERMS; - ramBufferSize = (int64_t)(IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB * 1024 * 1024); - waitQueuePauseBytes = (int64_t)((double)ramBufferSize * 0.1); - waitQueueResumeBytes = (int64_t)((double)ramBufferSize * 0.05); - freeTrigger = (int64_t)(IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB * 1024.0 * 1024.0 * 1.05); - freeLevel = (int64_t)(IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB * 1024.0 * 1024.0 * 0.95); - maxBufferedDocs = IndexWriter::DEFAULT_MAX_BUFFERED_DOCS; - flushedDocCount = 0; - closed = false; - waitQueue = newLucene(shared_from_this()); - skipDocWriter = newLucene(); - numBytesAlloc = 0; - numBytesUsed = 0; - byteBlockAllocator = newLucene(shared_from_this(), BYTE_BLOCK_SIZE); - perDocAllocator = newLucene(shared_from_this(), PER_DOC_BLOCK_SIZE); - - IndexWriterPtr writer(_writer); - this->similarity = writer->getSimilarity(); - flushedDocCount = writer->maxDoc(); - - consumer = indexingChain->getChain(shared_from_this()); - docFieldProcessor = boost::dynamic_pointer_cast(consumer); - } +void DocumentsWriter::initialize() { + docStoreOffset = 0; + nextDocID = 0; + numDocsInRAM = 0; + numDocsInStore = 0; + pauseThreads = 0; + flushPending = false; + bufferIsFull = false; + aborting = false; + maxFieldLength = IndexWriter::DEFAULT_MAX_FIELD_LENGTH; + deletesInRAM = newLucene(false); + deletesFlushed = newLucene(true); + maxBufferedDeleteTerms = IndexWriter::DEFAULT_MAX_BUFFERED_DELETE_TERMS; + ramBufferSize = (int64_t)(IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB * 1024 * 1024); + waitQueuePauseBytes = (int64_t)((double)ramBufferSize * 0.1); + waitQueueResumeBytes = (int64_t)((double)ramBufferSize * 0.05); + freeTrigger = (int64_t)(IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB * 1024.0 * 1024.0 * 1.05); + freeLevel = (int64_t)(IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB * 1024.0 * 1024.0 * 0.95); + maxBufferedDocs = IndexWriter::DEFAULT_MAX_BUFFERED_DOCS; + flushedDocCount = 0; + closed = false; + waitQueue = newLucene(shared_from_this()); + skipDocWriter = newLucene(); + numBytesAlloc = 0; + numBytesUsed = 0; + byteBlockAllocator = newLucene(shared_from_this(), BYTE_BLOCK_SIZE); + perDocAllocator = newLucene(shared_from_this(), PER_DOC_BLOCK_SIZE); + + IndexWriterPtr writer(_writer); + this->similarity = writer->getSimilarity(); + flushedDocCount = writer->maxDoc(); + + consumer = indexingChain->getChain(shared_from_this()); + docFieldProcessor = boost::dynamic_pointer_cast(consumer); +} - PerDocBufferPtr DocumentsWriter::newPerDocBuffer() - { - return newLucene(shared_from_this()); - } +PerDocBufferPtr DocumentsWriter::newPerDocBuffer() { + return newLucene(shared_from_this()); +} - IndexingChainPtr DocumentsWriter::getDefaultIndexingChain() - { - static DefaultIndexingChainPtr defaultIndexingChain; - if (!defaultIndexingChain) - { - defaultIndexingChain = newLucene(); - CycleCheck::addStatic(defaultIndexingChain); - } - return defaultIndexingChain; +IndexingChainPtr DocumentsWriter::getDefaultIndexingChain() { + static DefaultIndexingChainPtr defaultIndexingChain; + if (!defaultIndexingChain) { + defaultIndexingChain = newLucene(); + CycleCheck::addStatic(defaultIndexingChain); } + return defaultIndexingChain; +} - void DocumentsWriter::updateFlushedDocCount(int32_t n) - { - SyncLock syncLock(this); - flushedDocCount += n; - } +void DocumentsWriter::updateFlushedDocCount(int32_t n) { + SyncLock syncLock(this); + flushedDocCount += n; +} - int32_t DocumentsWriter::getFlushedDocCount() - { - SyncLock syncLock(this); - return flushedDocCount; - } +int32_t DocumentsWriter::getFlushedDocCount() { + SyncLock syncLock(this); + return flushedDocCount; +} - void DocumentsWriter::setFlushedDocCount(int32_t n) - { - SyncLock syncLock(this); - flushedDocCount = n; - } +void DocumentsWriter::setFlushedDocCount(int32_t n) { + SyncLock syncLock(this); + flushedDocCount = n; +} - bool DocumentsWriter::hasProx() - { - return docFieldProcessor ? docFieldProcessor->fieldInfos->hasProx() : true; - } +bool DocumentsWriter::hasProx() { + return docFieldProcessor ? docFieldProcessor->fieldInfos->hasProx() : true; +} - void DocumentsWriter::setInfoStream(const InfoStreamPtr& infoStream) - { - SyncLock syncLock(this); - this->infoStream = infoStream; - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - (*threadState)->docState->infoStream = infoStream; +void DocumentsWriter::setInfoStream(const InfoStreamPtr& infoStream) { + SyncLock syncLock(this); + this->infoStream = infoStream; + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + (*threadState)->docState->infoStream = infoStream; } +} - void DocumentsWriter::setMaxFieldLength(int32_t maxFieldLength) - { - SyncLock syncLock(this); - this->maxFieldLength = maxFieldLength; - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - (*threadState)->docState->maxFieldLength = maxFieldLength; +void DocumentsWriter::setMaxFieldLength(int32_t maxFieldLength) { + SyncLock syncLock(this); + this->maxFieldLength = maxFieldLength; + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + (*threadState)->docState->maxFieldLength = maxFieldLength; } +} - void DocumentsWriter::setSimilarity(const SimilarityPtr& similarity) - { - SyncLock syncLock(this); - this->similarity = similarity; - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - (*threadState)->docState->similarity = similarity; +void DocumentsWriter::setSimilarity(const SimilarityPtr& similarity) { + SyncLock syncLock(this); + this->similarity = similarity; + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + (*threadState)->docState->similarity = similarity; } +} - void DocumentsWriter::setRAMBufferSizeMB(double mb) - { - SyncLock syncLock(this); - if (mb == IndexWriter::DISABLE_AUTO_FLUSH) - { - ramBufferSize = IndexWriter::DISABLE_AUTO_FLUSH; - waitQueuePauseBytes = 4 * 1024 * 1024; - waitQueueResumeBytes = 2 * 1024 * 1024; - } - else - { - ramBufferSize = (int64_t)(mb * 1024.0 * 1024.0); - waitQueuePauseBytes = (int64_t)((double)ramBufferSize * 0.1); - waitQueueResumeBytes = (int64_t)((double)ramBufferSize * 0.05); - freeTrigger = (int64_t)(1.05 * (double)ramBufferSize); - freeLevel = (int64_t)(0.95 * (double)ramBufferSize); - } +void DocumentsWriter::setRAMBufferSizeMB(double mb) { + SyncLock syncLock(this); + if (mb == IndexWriter::DISABLE_AUTO_FLUSH) { + ramBufferSize = IndexWriter::DISABLE_AUTO_FLUSH; + waitQueuePauseBytes = 4 * 1024 * 1024; + waitQueueResumeBytes = 2 * 1024 * 1024; + } else { + ramBufferSize = (int64_t)(mb * 1024.0 * 1024.0); + waitQueuePauseBytes = (int64_t)((double)ramBufferSize * 0.1); + waitQueueResumeBytes = (int64_t)((double)ramBufferSize * 0.05); + freeTrigger = (int64_t)(1.05 * (double)ramBufferSize); + freeLevel = (int64_t)(0.95 * (double)ramBufferSize); } +} - double DocumentsWriter::getRAMBufferSizeMB() - { - SyncLock syncLock(this); - if (ramBufferSize == IndexWriter::DISABLE_AUTO_FLUSH) - return (double)ramBufferSize; - else - return (double)ramBufferSize / 1024.0 / 1024.0; +double DocumentsWriter::getRAMBufferSizeMB() { + SyncLock syncLock(this); + if (ramBufferSize == IndexWriter::DISABLE_AUTO_FLUSH) { + return (double)ramBufferSize; + } else { + return (double)ramBufferSize / 1024.0 / 1024.0; } +} - void DocumentsWriter::setMaxBufferedDocs(int32_t count) - { - maxBufferedDocs = count; - } +void DocumentsWriter::setMaxBufferedDocs(int32_t count) { + maxBufferedDocs = count; +} - int32_t DocumentsWriter::getMaxBufferedDocs() - { - return maxBufferedDocs; - } +int32_t DocumentsWriter::getMaxBufferedDocs() { + return maxBufferedDocs; +} - String DocumentsWriter::getSegment() - { - return segment; - } +String DocumentsWriter::getSegment() { + return segment; +} - int32_t DocumentsWriter::getNumDocsInRAM() - { - return numDocsInRAM; - } +int32_t DocumentsWriter::getNumDocsInRAM() { + return numDocsInRAM; +} - String DocumentsWriter::getDocStoreSegment() - { - SyncLock syncLock(this); - return docStoreSegment; - } +String DocumentsWriter::getDocStoreSegment() { + SyncLock syncLock(this); + return docStoreSegment; +} - int32_t DocumentsWriter::getDocStoreOffset() - { - return docStoreOffset; - } +int32_t DocumentsWriter::getDocStoreOffset() { + return docStoreOffset; +} - String DocumentsWriter::closeDocStore() - { - TestScope testScope(L"DocumentsWriter", L"closeDocStore"); - SyncLock syncLock(this); - BOOST_ASSERT(allThreadsIdle()); +String DocumentsWriter::closeDocStore() { + TestScope testScope(L"DocumentsWriter", L"closeDocStore"); + SyncLock syncLock(this); + BOOST_ASSERT(allThreadsIdle()); - if (infoStream) - { - message(L"closeDocStore: " + StringUtils::toString(_openFiles.size()) + L" files to flush to segment " + - docStoreSegment + L" numDocs=" + StringUtils::toString(numDocsInStore)); - } + if (infoStream) { + message(L"closeDocStore: " + StringUtils::toString(_openFiles.size()) + L" files to flush to segment " + + docStoreSegment + L" numDocs=" + StringUtils::toString(numDocsInStore)); + } - bool success = false; - LuceneException finally; - String s; - try - { - initFlushState(true); - _closedFiles.clear(); + bool success = false; + LuceneException finally; + String s; + try { + initFlushState(true); + _closedFiles.clear(); - consumer->closeDocStore(flushState); - BOOST_ASSERT(_openFiles.empty()); + consumer->closeDocStore(flushState); + BOOST_ASSERT(_openFiles.empty()); - s = docStoreSegment; - docStoreSegment.clear(); - docStoreOffset = 0; - numDocsInStore = 0; - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - abort(); - finally.throwException(); - return s; + s = docStoreSegment; + docStoreSegment.clear(); + docStoreOffset = 0; + numDocsInStore = 0; + success = true; + } catch (LuceneException& e) { + finally = e; } - - HashSet DocumentsWriter::abortedFiles() - { - return _abortedFiles; + if (!success) { + abort(); } + finally.throwException(); + return s; +} - void DocumentsWriter::message(const String& message) - { - if (infoStream) - *infoStream << L"DW " << message << L"\n"; - } +HashSet DocumentsWriter::abortedFiles() { + return _abortedFiles; +} - HashSet DocumentsWriter::openFiles() - { - SyncLock syncLock(this); - return HashSet::newInstance(_openFiles.begin(), _openFiles.end()); +void DocumentsWriter::message(const String& message) { + if (infoStream) { + *infoStream << L"DW " << message << L"\n"; } +} - HashSet DocumentsWriter::closedFiles() - { - SyncLock syncLock(this); - return HashSet::newInstance(_closedFiles.begin(), _closedFiles.end()); - } +HashSet DocumentsWriter::openFiles() { + SyncLock syncLock(this); + return HashSet::newInstance(_openFiles.begin(), _openFiles.end()); +} - void DocumentsWriter::addOpenFile(const String& name) - { - SyncLock syncLock(this); - BOOST_ASSERT(!_openFiles.contains(name)); - _openFiles.add(name); - } +HashSet DocumentsWriter::closedFiles() { + SyncLock syncLock(this); + return HashSet::newInstance(_closedFiles.begin(), _closedFiles.end()); +} - void DocumentsWriter::removeOpenFile(const String& name) - { - SyncLock syncLock(this); - BOOST_ASSERT(_openFiles.contains(name)); - _openFiles.remove(name); - _closedFiles.add(name); - } +void DocumentsWriter::addOpenFile(const String& name) { + SyncLock syncLock(this); + BOOST_ASSERT(!_openFiles.contains(name)); + _openFiles.add(name); +} - void DocumentsWriter::setAborting() - { - SyncLock syncLock(this); - aborting = true; - } +void DocumentsWriter::removeOpenFile(const String& name) { + SyncLock syncLock(this); + BOOST_ASSERT(_openFiles.contains(name)); + _openFiles.remove(name); + _closedFiles.add(name); +} - void DocumentsWriter::abort() - { - TestScope testScope(L"DocumentsWriter", L"abort"); - SyncLock syncLock(this); - LuceneException finally; - try - { - if (infoStream) - message(L"docWriter: now abort"); +void DocumentsWriter::setAborting() { + SyncLock syncLock(this); + aborting = true; +} - // Forcefully remove waiting ThreadStates from line - waitQueue->abort(); +void DocumentsWriter::abort() { + TestScope testScope(L"DocumentsWriter", L"abort"); + SyncLock syncLock(this); + LuceneException finally; + try { + if (infoStream) { + message(L"docWriter: now abort"); + } - // Wait for all other threads to finish with DocumentsWriter - pauseAllThreads(); + // Forcefully remove waiting ThreadStates from line + waitQueue->abort(); - try - { - BOOST_ASSERT(waitQueue->numWaiting == 0); + // Wait for all other threads to finish with DocumentsWriter + pauseAllThreads(); - waitQueue->waitingBytes = 0; + try { + BOOST_ASSERT(waitQueue->numWaiting == 0); - try - { - _abortedFiles = openFiles(); - } - catch (...) - { - _abortedFiles.reset(); - } + waitQueue->waitingBytes = 0; - deletesInRAM->clear(); - deletesFlushed->clear(); - _openFiles.clear(); + try { + _abortedFiles = openFiles(); + } catch (...) { + _abortedFiles.reset(); + } - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - { - try - { - (*threadState)->consumer->abort(); - } - catch (...) - { - } - } + deletesInRAM->clear(); + deletesFlushed->clear(); + _openFiles.clear(); - try - { - consumer->abort(); + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + try { + (*threadState)->consumer->abort(); + } catch (...) { } - catch (...) - { - } - - docStoreSegment.clear(); - numDocsInStore = 0; - docStoreOffset = 0; - - // Reset all postings data - doAfterFlush(); } - catch (LuceneException& e) - { - finally = e; + + try { + consumer->abort(); + } catch (...) { } - resumeAllThreads(); + + docStoreSegment.clear(); + numDocsInStore = 0; + docStoreOffset = 0; + + // Reset all postings data + doAfterFlush(); + } catch (LuceneException& e) { + finally = e; } - catch (LuceneException& e) - { - if (finally.isNull()) - finally = e; + resumeAllThreads(); + } catch (LuceneException& e) { + if (finally.isNull()) { + finally = e; } - aborting = false; - notifyAll(); - if (infoStream) - message(L"docWriter: done abort"); - finally.throwException(); } - - void DocumentsWriter::doAfterFlush() - { - // All ThreadStates should be idle when we are called - BOOST_ASSERT(allThreadsIdle()); - threadBindings.clear(); - waitQueue->reset(); - segment.clear(); - numDocsInRAM = 0; - nextDocID = 0; - bufferIsFull = false; - flushPending = false; - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - (*threadState)->doAfterFlush(); - numBytesUsed = 0; + aborting = false; + notifyAll(); + if (infoStream) { + message(L"docWriter: done abort"); } + finally.throwException(); +} - bool DocumentsWriter::pauseAllThreads() - { - SyncLock syncLock(this); - ++pauseThreads; - while (!allThreadsIdle()) - wait(1000); - return aborting; - } +void DocumentsWriter::doAfterFlush() { + // All ThreadStates should be idle when we are called + BOOST_ASSERT(allThreadsIdle()); + threadBindings.clear(); + waitQueue->reset(); + segment.clear(); + numDocsInRAM = 0; + nextDocID = 0; + bufferIsFull = false; + flushPending = false; + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + (*threadState)->doAfterFlush(); + } + numBytesUsed = 0; +} - void DocumentsWriter::resumeAllThreads() - { - SyncLock syncLock(this); - --pauseThreads; - BOOST_ASSERT(pauseThreads >= 0); - if (pauseThreads == 0) - notifyAll(); +bool DocumentsWriter::pauseAllThreads() { + SyncLock syncLock(this); + ++pauseThreads; + while (!allThreadsIdle()) { + wait(1000); } + return aborting; +} - bool DocumentsWriter::allThreadsIdle() - { - SyncLock syncLock(this); - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - { - if (!(*threadState)->isIdle) - return false; - } - return true; +void DocumentsWriter::resumeAllThreads() { + SyncLock syncLock(this); + --pauseThreads; + BOOST_ASSERT(pauseThreads >= 0); + if (pauseThreads == 0) { + notifyAll(); } +} - bool DocumentsWriter::anyChanges() - { - SyncLock syncLock(this); - return (numDocsInRAM != 0 || deletesInRAM->numTerms != 0 || !deletesInRAM->docIDs.empty() || !deletesInRAM->queries.empty()); +bool DocumentsWriter::allThreadsIdle() { + SyncLock syncLock(this); + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + if (!(*threadState)->isIdle) { + return false; + } } + return true; +} - void DocumentsWriter::initFlushState(bool onlyDocStore) - { - SyncLock syncLock(this); - initSegmentName(onlyDocStore); - flushState = newLucene(shared_from_this(), directory, segment, docStoreSegment, numDocsInRAM, numDocsInStore, IndexWriterPtr(_writer)->getTermIndexInterval()); - } +bool DocumentsWriter::anyChanges() { + SyncLock syncLock(this); + return (numDocsInRAM != 0 || deletesInRAM->numTerms != 0 || !deletesInRAM->docIDs.empty() || !deletesInRAM->queries.empty()); +} - int32_t DocumentsWriter::flush(bool _closeDocStore) - { - SyncLock syncLock(this); - BOOST_ASSERT(allThreadsIdle()); +void DocumentsWriter::initFlushState(bool onlyDocStore) { + SyncLock syncLock(this); + initSegmentName(onlyDocStore); + flushState = newLucene(shared_from_this(), directory, segment, docStoreSegment, numDocsInRAM, numDocsInStore, IndexWriterPtr(_writer)->getTermIndexInterval()); +} - BOOST_ASSERT(numDocsInRAM > 0); +int32_t DocumentsWriter::flush(bool _closeDocStore) { + SyncLock syncLock(this); + BOOST_ASSERT(allThreadsIdle()); - BOOST_ASSERT(nextDocID == numDocsInRAM); - BOOST_ASSERT(waitQueue->numWaiting == 0); - BOOST_ASSERT(waitQueue->waitingBytes == 0); + BOOST_ASSERT(numDocsInRAM > 0); - initFlushState(false); + BOOST_ASSERT(nextDocID == numDocsInRAM); + BOOST_ASSERT(waitQueue->numWaiting == 0); + BOOST_ASSERT(waitQueue->waitingBytes == 0); - docStoreOffset = numDocsInStore; + initFlushState(false); - if (infoStream) - message(L"flush postings as segment " + flushState->segmentName + L" numDocs=" + StringUtils::toString(numDocsInRAM)); + docStoreOffset = numDocsInStore; - bool success = false; - LuceneException finally; + if (infoStream) { + message(L"flush postings as segment " + flushState->segmentName + L" numDocs=" + StringUtils::toString(numDocsInRAM)); + } - try - { - if (_closeDocStore) - { - BOOST_ASSERT(!flushState->docStoreSegmentName.empty()); - BOOST_ASSERT(flushState->docStoreSegmentName == flushState->segmentName); + bool success = false; + LuceneException finally; - closeDocStore(); - flushState->numDocsInStore = 0; - } + try { + if (_closeDocStore) { + BOOST_ASSERT(!flushState->docStoreSegmentName.empty()); + BOOST_ASSERT(flushState->docStoreSegmentName == flushState->segmentName); - Collection threads(Collection::newInstance()); - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - threads.add((*threadState)->consumer); - consumer->flush(threads, flushState); + closeDocStore(); + flushState->numDocsInStore = 0; + } - if (infoStream) - { - SegmentInfoPtr si(newLucene(flushState->segmentName, flushState->numDocs, directory)); - int64_t newSegmentSize = si->sizeInBytes(); - if (infoStream) - { - message(L" oldRAMSize=" + StringUtils::toString(numBytesUsed) + L" newFlushedSize=" + - StringUtils::toString(newSegmentSize) + L" docs/MB=" + - StringUtils::toString((double)numDocsInRAM / ((double)newSegmentSize / 1024.0 / 1024.0)) + - L" new/old=" + StringUtils::toString(100.0 * (double)newSegmentSize / (double)numBytesUsed) + L"%"); - } + Collection threads(Collection::newInstance()); + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + threads.add((*threadState)->consumer); + } + consumer->flush(threads, flushState); + + if (infoStream) { + SegmentInfoPtr si(newLucene(flushState->segmentName, flushState->numDocs, directory)); + int64_t newSegmentSize = si->sizeInBytes(); + if (infoStream) { + message(L" oldRAMSize=" + StringUtils::toString(numBytesUsed) + L" newFlushedSize=" + + StringUtils::toString(newSegmentSize) + L" docs/MB=" + + StringUtils::toString((double)numDocsInRAM / ((double)newSegmentSize / 1024.0 / 1024.0)) + + L" new/old=" + StringUtils::toString(100.0 * (double)newSegmentSize / (double)numBytesUsed) + L"%"); } + } - flushedDocCount += flushState->numDocs; + flushedDocCount += flushState->numDocs; - doAfterFlush(); + doAfterFlush(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - abort(); - finally.throwException(); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + abort(); + } + finally.throwException(); - BOOST_ASSERT(waitQueue->waitingBytes == 0); + BOOST_ASSERT(waitQueue->waitingBytes == 0); - return flushState->numDocs; - } + return flushState->numDocs; +} - HashSet DocumentsWriter::getFlushedFiles() - { - return flushState->flushedFiles; +HashSet DocumentsWriter::getFlushedFiles() { + return flushState->flushedFiles; +} + +void DocumentsWriter::createCompoundFile(const String& segment) { + CompoundFileWriterPtr cfsWriter(newLucene(directory, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION())); + for (HashSet::iterator flushedFile = flushState->flushedFiles.begin(); flushedFile != flushState->flushedFiles.end(); ++flushedFile) { + cfsWriter->addFile(*flushedFile); } - void DocumentsWriter::createCompoundFile(const String& segment) - { - CompoundFileWriterPtr cfsWriter(newLucene(directory, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION())); - for (HashSet::iterator flushedFile = flushState->flushedFiles.begin(); flushedFile != flushState->flushedFiles.end(); ++flushedFile) - cfsWriter->addFile(*flushedFile); + // Perform the merge + cfsWriter->close(); +} - // Perform the merge - cfsWriter->close(); +bool DocumentsWriter::setFlushPending() { + SyncLock syncLock(this); + if (flushPending) { + return false; + } else { + flushPending = true; + return true; } +} - bool DocumentsWriter::setFlushPending() - { - SyncLock syncLock(this); - if (flushPending) - return false; - else - { - flushPending = true; - return true; - } - } +void DocumentsWriter::clearFlushPending() { + SyncLock syncLock(this); + flushPending = false; +} - void DocumentsWriter::clearFlushPending() - { - SyncLock syncLock(this); - flushPending = false; - } +void DocumentsWriter::pushDeletes() { + SyncLock syncLock(this); + deletesFlushed->update(deletesInRAM); +} - void DocumentsWriter::pushDeletes() - { - SyncLock syncLock(this); - deletesFlushed->update(deletesInRAM); - } +void DocumentsWriter::close() { + SyncLock syncLock(this); + closed = true; + notifyAll(); +} - void DocumentsWriter::close() - { - SyncLock syncLock(this); - closed = true; - notifyAll(); +void DocumentsWriter::initSegmentName(bool onlyDocStore) { + SyncLock syncLock(this); + if (segment.empty() && (!onlyDocStore || docStoreSegment.empty())) { + segment = IndexWriterPtr(_writer)->newSegmentName(); + BOOST_ASSERT(numDocsInRAM == 0); } - - void DocumentsWriter::initSegmentName(bool onlyDocStore) - { - SyncLock syncLock(this); - if (segment.empty() && (!onlyDocStore || docStoreSegment.empty())) - { - segment = IndexWriterPtr(_writer)->newSegmentName(); - BOOST_ASSERT(numDocsInRAM == 0); - } - if (docStoreSegment.empty()) - { - docStoreSegment = segment; - BOOST_ASSERT(numDocsInStore == 0); - } + if (docStoreSegment.empty()) { + docStoreSegment = segment; + BOOST_ASSERT(numDocsInStore == 0); } +} - DocumentsWriterThreadStatePtr DocumentsWriter::getThreadState(const DocumentPtr& doc, const TermPtr& delTerm) - { - SyncLock syncLock(this); - // First, find a thread state. If this thread already has affinity to a specific ThreadState, use that one again. - DocumentsWriterThreadStatePtr state(threadBindings.get(LuceneThread::currentId())); - if (!state) - { - // First time this thread has called us since last flush. Find the least loaded thread state - DocumentsWriterThreadStatePtr minThreadState; - for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) - { - if (!minThreadState || (*threadState)->numThreads < minThreadState->numThreads) - minThreadState = *threadState; +DocumentsWriterThreadStatePtr DocumentsWriter::getThreadState(const DocumentPtr& doc, const TermPtr& delTerm) { + SyncLock syncLock(this); + // First, find a thread state. If this thread already has affinity to a specific ThreadState, use that one again. + DocumentsWriterThreadStatePtr state(threadBindings.get(LuceneThread::currentId())); + if (!state) { + // First time this thread has called us since last flush. Find the least loaded thread state + DocumentsWriterThreadStatePtr minThreadState; + for (Collection::iterator threadState = threadStates.begin(); threadState != threadStates.end(); ++threadState) { + if (!minThreadState || (*threadState)->numThreads < minThreadState->numThreads) { + minThreadState = *threadState; } - if (minThreadState && (minThreadState->numThreads == 0 || threadStates.size() >= MAX_THREAD_STATE)) - { - state = minThreadState; - ++state->numThreads; - } - else - { - // Just create a new "private" thread state - threadStates.resize(threadStates.size() + 1); - state = newLucene(shared_from_this()); - threadStates[threadStates.size() - 1] = state; - } - threadBindings.put(LuceneThread::currentId(), state); } + if (minThreadState && (minThreadState->numThreads == 0 || threadStates.size() >= MAX_THREAD_STATE)) { + state = minThreadState; + ++state->numThreads; + } else { + // Just create a new "private" thread state + threadStates.resize(threadStates.size() + 1); + state = newLucene(shared_from_this()); + threadStates[threadStates.size() - 1] = state; + } + threadBindings.put(LuceneThread::currentId(), state); + } - // Next, wait until my thread state is idle (in case it's shared with other threads) and for threads to - // not be paused nor a flush pending - waitReady(state); - - // Allocate segment name if this is the first doc since last flush - initSegmentName(false); + // Next, wait until my thread state is idle (in case it's shared with other threads) and for threads to + // not be paused nor a flush pending + waitReady(state); - state->isIdle = false; + // Allocate segment name if this is the first doc since last flush + initSegmentName(false); - bool success = false; - LuceneException finally; - try - { - state->docState->docID = nextDocID; + state->isIdle = false; - BOOST_ASSERT(IndexWriterPtr(_writer)->testPoint(L"DocumentsWriter.ThreadState.init start")); + bool success = false; + LuceneException finally; + try { + state->docState->docID = nextDocID; - if (delTerm) - { - addDeleteTerm(delTerm, state->docState->docID); - state->doFlushAfter = timeToFlushDeletes(); - } + BOOST_ASSERT(IndexWriterPtr(_writer)->testPoint(L"DocumentsWriter.ThreadState.init start")); - BOOST_ASSERT(IndexWriterPtr(_writer)->testPoint(L"DocumentsWriter.ThreadState.init after delTerm")); + if (delTerm) { + addDeleteTerm(delTerm, state->docState->docID); + state->doFlushAfter = timeToFlushDeletes(); + } - ++nextDocID; - ++numDocsInRAM; + BOOST_ASSERT(IndexWriterPtr(_writer)->testPoint(L"DocumentsWriter.ThreadState.init after delTerm")); - // We must at this point commit to flushing to ensure we always get N docs when we flush by doc - // count, even if > 1 thread is adding documents - if (!flushPending && maxBufferedDocs != IndexWriter::DISABLE_AUTO_FLUSH && numDocsInRAM >= maxBufferedDocs) - { - flushPending = true; - state->doFlushAfter = true; - } + ++nextDocID; + ++numDocsInRAM; - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - { - // Forcefully idle this ThreadState - state->isIdle = true; - notifyAll(); - if (state->doFlushAfter) - { - state->doFlushAfter = false; - flushPending = false; - } + // We must at this point commit to flushing to ensure we always get N docs when we flush by doc + // count, even if > 1 thread is adding documents + if (!flushPending && maxBufferedDocs != IndexWriter::DISABLE_AUTO_FLUSH && numDocsInRAM >= maxBufferedDocs) { + flushPending = true; + state->doFlushAfter = true; } - finally.throwException(); - return state; + success = true; + } catch (LuceneException& e) { + finally = e; } - - bool DocumentsWriter::addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer) - { - return updateDocument(doc, analyzer, TermPtr()); - } - - bool DocumentsWriter::updateDocument(const TermPtr& t, const DocumentPtr& doc, const AnalyzerPtr& analyzer) - { - return updateDocument(doc, analyzer, t); + if (!success) { + // Forcefully idle this ThreadState + state->isIdle = true; + notifyAll(); + if (state->doFlushAfter) { + state->doFlushAfter = false; + flushPending = false; + } } + finally.throwException(); - bool DocumentsWriter::updateDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer, const TermPtr& delTerm) - { - // This call is synchronized but fast - DocumentsWriterThreadStatePtr state(getThreadState(doc, delTerm)); - - DocStatePtr docState(state->docState); - docState->doc = doc; - docState->analyzer = analyzer; + return state; +} - bool success = false; - LuceneException finally; - try - { - // This call is not synchronized and does all the work - DocWriterPtr perDoc; - try - { - perDoc = state->consumer->processDocument(); - } - catch (LuceneException& e) - { - finally = e; - } - docState->clear(); - finally.throwException(); +bool DocumentsWriter::addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer) { + return updateDocument(doc, analyzer, TermPtr()); +} - // This call is synchronized but fast - finishDocument(state, perDoc); +bool DocumentsWriter::updateDocument(const TermPtr& t, const DocumentPtr& doc, const AnalyzerPtr& analyzer) { + return updateDocument(doc, analyzer, t); +} - success = true; - } - catch (LuceneException& e) - { +bool DocumentsWriter::updateDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer, const TermPtr& delTerm) { + // This call is synchronized but fast + DocumentsWriterThreadStatePtr state(getThreadState(doc, delTerm)); + + DocStatePtr docState(state->docState); + docState->doc = doc; + docState->analyzer = analyzer; + + bool success = false; + LuceneException finally; + try { + // This call is not synchronized and does all the work + DocWriterPtr perDoc; + try { + perDoc = state->consumer->processDocument(); + } catch (LuceneException& e) { finally = e; } - if (!success) - { - SyncLock syncLock(this); - if (aborting) - { + docState->clear(); + finally.throwException(); + + // This call is synchronized but fast + finishDocument(state, perDoc); + + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + SyncLock syncLock(this); + if (aborting) { + state->isIdle = true; + notifyAll(); + abort(); + } else { + skipDocWriter->docID = docState->docID; + bool success2 = false; + try { + waitQueue->add(skipDocWriter); + success2 = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success2) { state->isIdle = true; notifyAll(); abort(); + return false; } - else - { - skipDocWriter->docID = docState->docID; - bool success2 = false; - try - { - waitQueue->add(skipDocWriter); - success2 = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success2) - { - state->isIdle = true; - notifyAll(); - abort(); - return false; - } - - state->isIdle = true; - notifyAll(); - // If this thread state had decided to flush, we must clear it so another thread can flush - if (state->doFlushAfter) - { - state->doFlushAfter = false; - flushPending = false; - notifyAll(); - } + state->isIdle = true; + notifyAll(); - // Immediately mark this document as deleted since likely it was partially added. This keeps - // indexing as "all or none" (atomic) when adding a document - addDeleteDocID(state->docState->docID); + // If this thread state had decided to flush, we must clear it so another thread can flush + if (state->doFlushAfter) { + state->doFlushAfter = false; + flushPending = false; + notifyAll(); } - } - finally.throwException(); - - return (state->doFlushAfter || timeToFlushDeletes()); - } - - int32_t DocumentsWriter::getNumBufferedDeleteTerms() - { - SyncLock syncLock(this); - return deletesInRAM->numTerms; - } - - MapTermNum DocumentsWriter::getBufferedDeleteTerms() - { - SyncLock syncLock(this); - return deletesInRAM->terms; - } - - void DocumentsWriter::remapDeletes(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergeDocCount) - { - SyncLock syncLock(this); - if (!docMaps) - { - // The merged segments had no deletes so docIDs did not change and we have nothing to do - return; + // Immediately mark this document as deleted since likely it was partially added. This keeps + // indexing as "all or none" (atomic) when adding a document + addDeleteDocID(state->docState->docID); } - MergeDocIDRemapperPtr mapper(newLucene(infos, docMaps, delCounts, merge, mergeDocCount)); - deletesInRAM->remap(mapper, infos, docMaps, delCounts, merge, mergeDocCount); - deletesFlushed->remap(mapper, infos, docMaps, delCounts, merge, mergeDocCount); - flushedDocCount -= mapper->docShift; } - void DocumentsWriter::waitReady(const DocumentsWriterThreadStatePtr& state) - { - SyncLock syncLock(this); - while (!closed && ((state && !state->isIdle) || pauseThreads != 0 || flushPending || aborting)) - wait(1000); - if (closed) - boost::throw_exception(AlreadyClosedException(L"this IndexWriter is closed")); - } + finally.throwException(); - bool DocumentsWriter::bufferDeleteTerms(Collection terms) - { - SyncLock syncLock(this); - waitReady(DocumentsWriterThreadStatePtr()); - for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) - addDeleteTerm(*term, numDocsInRAM); - return timeToFlushDeletes(); - } + return (state->doFlushAfter || timeToFlushDeletes()); +} - bool DocumentsWriter::bufferDeleteTerm(const TermPtr& term) - { - SyncLock syncLock(this); - waitReady(DocumentsWriterThreadStatePtr()); - addDeleteTerm(term, numDocsInRAM); - return timeToFlushDeletes(); - } +int32_t DocumentsWriter::getNumBufferedDeleteTerms() { + SyncLock syncLock(this); + return deletesInRAM->numTerms; +} - bool DocumentsWriter::bufferDeleteQueries(Collection queries) - { - SyncLock syncLock(this); - waitReady(DocumentsWriterThreadStatePtr()); - for (Collection::iterator query = queries.begin(); query != queries.end(); ++query) - addDeleteQuery(*query, numDocsInRAM); - return timeToFlushDeletes(); - } +MapTermNum DocumentsWriter::getBufferedDeleteTerms() { + SyncLock syncLock(this); + return deletesInRAM->terms; +} - bool DocumentsWriter::bufferDeleteQuery(const QueryPtr& query) - { - SyncLock syncLock(this); - waitReady(DocumentsWriterThreadStatePtr()); - addDeleteQuery(query, numDocsInRAM); - return timeToFlushDeletes(); +void DocumentsWriter::remapDeletes(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergeDocCount) { + SyncLock syncLock(this); + if (!docMaps) { + // The merged segments had no deletes so docIDs did not change and we have nothing to do + return; } + MergeDocIDRemapperPtr mapper(newLucene(infos, docMaps, delCounts, merge, mergeDocCount)); + deletesInRAM->remap(mapper, infos, docMaps, delCounts, merge, mergeDocCount); + deletesFlushed->remap(mapper, infos, docMaps, delCounts, merge, mergeDocCount); + flushedDocCount -= mapper->docShift; +} - bool DocumentsWriter::deletesFull() - { - SyncLock syncLock(this); - return ((ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && - (deletesInRAM->bytesUsed + deletesFlushed->bytesUsed + numBytesUsed) >= ramBufferSize) || - (maxBufferedDeleteTerms != IndexWriter::DISABLE_AUTO_FLUSH && - ((deletesInRAM->size() + deletesFlushed->size()) >= maxBufferedDeleteTerms))); +void DocumentsWriter::waitReady(const DocumentsWriterThreadStatePtr& state) { + SyncLock syncLock(this); + while (!closed && ((state && !state->isIdle) || pauseThreads != 0 || flushPending || aborting)) { + wait(1000); } - - bool DocumentsWriter::doApplyDeletes() - { - SyncLock syncLock(this); - // Very similar to deletesFull(), except we don't count numBytesAlloc, because we are checking whether - // deletes (alone) are consuming too many resources now and thus should be applied. We apply deletes - // if RAM usage is > 1/2 of our allowed RAM buffer, to prevent too-frequent flushing of a long tail of - // tiny segments when merges (which always apply deletes) are infrequent. - return ((ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && - (deletesInRAM->bytesUsed + deletesFlushed->bytesUsed) >= ramBufferSize / 2) || - (maxBufferedDeleteTerms != IndexWriter::DISABLE_AUTO_FLUSH && - ((deletesInRAM->size() + deletesFlushed->size()) >= maxBufferedDeleteTerms))); + if (closed) { + boost::throw_exception(AlreadyClosedException(L"this IndexWriter is closed")); } +} - bool DocumentsWriter::timeToFlushDeletes() - { - SyncLock syncLock(this); - return ((bufferIsFull || deletesFull()) && setFlushPending()); +bool DocumentsWriter::bufferDeleteTerms(Collection terms) { + SyncLock syncLock(this); + waitReady(DocumentsWriterThreadStatePtr()); + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) { + addDeleteTerm(*term, numDocsInRAM); } + return timeToFlushDeletes(); +} - bool DocumentsWriter::checkDeleteTerm(const TermPtr& term) - { - if (term) - BOOST_ASSERT(!lastDeleteTerm || term->compareTo(lastDeleteTerm) > 0); - lastDeleteTerm = term; - return true; - } +bool DocumentsWriter::bufferDeleteTerm(const TermPtr& term) { + SyncLock syncLock(this); + waitReady(DocumentsWriterThreadStatePtr()); + addDeleteTerm(term, numDocsInRAM); + return timeToFlushDeletes(); +} - void DocumentsWriter::setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms) - { - this->maxBufferedDeleteTerms = maxBufferedDeleteTerms; +bool DocumentsWriter::bufferDeleteQueries(Collection queries) { + SyncLock syncLock(this); + waitReady(DocumentsWriterThreadStatePtr()); + for (Collection::iterator query = queries.begin(); query != queries.end(); ++query) { + addDeleteQuery(*query, numDocsInRAM); } + return timeToFlushDeletes(); +} - int32_t DocumentsWriter::getMaxBufferedDeleteTerms() - { - return maxBufferedDeleteTerms; - } +bool DocumentsWriter::bufferDeleteQuery(const QueryPtr& query) { + SyncLock syncLock(this); + waitReady(DocumentsWriterThreadStatePtr()); + addDeleteQuery(query, numDocsInRAM); + return timeToFlushDeletes(); +} - bool DocumentsWriter::hasDeletes() - { - SyncLock syncLock(this); - return deletesFlushed->any(); - } +bool DocumentsWriter::deletesFull() { + SyncLock syncLock(this); + return ((ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && + (deletesInRAM->bytesUsed + deletesFlushed->bytesUsed + numBytesUsed) >= ramBufferSize) || + (maxBufferedDeleteTerms != IndexWriter::DISABLE_AUTO_FLUSH && + ((deletesInRAM->size() + deletesFlushed->size()) >= maxBufferedDeleteTerms))); +} - bool DocumentsWriter::applyDeletes(const SegmentInfosPtr& infos) - { - SyncLock syncLock(this); - if (!hasDeletes()) - return false; +bool DocumentsWriter::doApplyDeletes() { + SyncLock syncLock(this); + // Very similar to deletesFull(), except we don't count numBytesAlloc, because we are checking whether + // deletes (alone) are consuming too many resources now and thus should be applied. We apply deletes + // if RAM usage is > 1/2 of our allowed RAM buffer, to prevent too-frequent flushing of a long tail of + // tiny segments when merges (which always apply deletes) are infrequent. + return ((ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && + (deletesInRAM->bytesUsed + deletesFlushed->bytesUsed) >= ramBufferSize / 2) || + (maxBufferedDeleteTerms != IndexWriter::DISABLE_AUTO_FLUSH && + ((deletesInRAM->size() + deletesFlushed->size()) >= maxBufferedDeleteTerms))); +} - if (infoStream) - { - message(L"apply " + StringUtils::toString(deletesFlushed->numTerms) + L" buffered deleted terms and " + - StringUtils::toString(deletesFlushed->docIDs.size()) + L" deleted docIDs and " + - StringUtils::toString(deletesFlushed->queries.size()) + L" deleted queries on " + - StringUtils::toString(infos->size()) + L" segments."); - } +bool DocumentsWriter::timeToFlushDeletes() { + SyncLock syncLock(this); + return ((bufferIsFull || deletesFull()) && setFlushPending()); +} - int32_t infosEnd = infos->size(); +bool DocumentsWriter::checkDeleteTerm(const TermPtr& term) { + if (term) { + BOOST_ASSERT(!lastDeleteTerm || term->compareTo(lastDeleteTerm) > 0); + } + lastDeleteTerm = term; + return true; +} - int32_t docStart = 0; - bool any = false; - IndexWriterPtr writer(_writer); +void DocumentsWriter::setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms) { + this->maxBufferedDeleteTerms = maxBufferedDeleteTerms; +} - for (int32_t i = 0; i < infosEnd; ++i) - { - // Make sure we never attempt to apply deletes to segment in external dir - BOOST_ASSERT(infos->info(i)->dir == directory); +int32_t DocumentsWriter::getMaxBufferedDeleteTerms() { + return maxBufferedDeleteTerms; +} - SegmentReaderPtr reader(writer->readerPool->get(infos->info(i), false)); - LuceneException finally; - try - { - if (applyDeletes(reader, docStart)) - any = true; - docStart += reader->maxDoc(); - } - catch (LuceneException& e) - { - finally = e; - } - writer->readerPool->release(reader); - finally.throwException(); - } +bool DocumentsWriter::hasDeletes() { + SyncLock syncLock(this); + return deletesFlushed->any(); +} - deletesFlushed->clear(); +bool DocumentsWriter::applyDeletes(const SegmentInfosPtr& infos) { + SyncLock syncLock(this); + if (!hasDeletes()) { + return false; + } - return any; + if (infoStream) { + message(L"apply " + StringUtils::toString(deletesFlushed->numTerms) + L" buffered deleted terms and " + + StringUtils::toString(deletesFlushed->docIDs.size()) + L" deleted docIDs and " + + StringUtils::toString(deletesFlushed->queries.size()) + L" deleted queries on " + + StringUtils::toString(infos->size()) + L" segments."); } - bool DocumentsWriter::applyDeletes(const IndexReaderPtr& reader, int32_t docIDStart) - { - SyncLock syncLock(this); - int32_t docEnd = docIDStart + reader->maxDoc(); - bool any = false; + int32_t infosEnd = infos->size(); + + int32_t docStart = 0; + bool any = false; + IndexWriterPtr writer(_writer); - BOOST_ASSERT(checkDeleteTerm(TermPtr())); + for (int32_t i = 0; i < infosEnd; ++i) { + // Make sure we never attempt to apply deletes to segment in external dir + BOOST_ASSERT(infos->info(i)->dir == directory); - // Delete by term - TermDocsPtr docs(reader->termDocs()); + SegmentReaderPtr reader(writer->readerPool->get(infos->info(i), false)); LuceneException finally; - try - { - for (MapTermNum::iterator entry = deletesFlushed->terms.begin(); entry != deletesFlushed->terms.end(); ++entry) - { - // we should be iterating a Map here, so terms better be in order - BOOST_ASSERT(checkDeleteTerm(entry->first)); - docs->seek(entry->first); - int32_t limit = entry->second->getNum(); - while (docs->next()) - { - int32_t docID = docs->doc(); - if (docIDStart + docID >= limit) - break; - reader->deleteDocument(docID); - any = true; - } + try { + if (applyDeletes(reader, docStart)) { + any = true; } - } - catch (LuceneException& e) - { + docStart += reader->maxDoc(); + } catch (LuceneException& e) { finally = e; } - docs->close(); + writer->readerPool->release(reader); finally.throwException(); + } - // Delete by docID - for (Collection::iterator docID = deletesFlushed->docIDs.begin(); docID != deletesFlushed->docIDs.end(); ++docID) - { - if (*docID >= docIDStart && *docID < docEnd) - { - reader->deleteDocument(*docID - docIDStart); - any = true; - } - } + deletesFlushed->clear(); - // Delete by query - IndexSearcherPtr searcher(newLucene(reader)); - for (MapQueryInt::iterator entry = deletesFlushed->queries.begin(); entry != deletesFlushed->queries.end(); ++entry) - { - WeightPtr weight(entry->first->weight(searcher)); - ScorerPtr scorer(weight->scorer(reader, true, false)); - if (scorer) - { - while (true) - { - int32_t doc = scorer->nextDoc(); - if ((int64_t)docIDStart + doc >= entry->second) - break; - reader->deleteDocument(doc); - any = true; + return any; +} + +bool DocumentsWriter::applyDeletes(const IndexReaderPtr& reader, int32_t docIDStart) { + SyncLock syncLock(this); + int32_t docEnd = docIDStart + reader->maxDoc(); + bool any = false; + + BOOST_ASSERT(checkDeleteTerm(TermPtr())); + + // Delete by term + TermDocsPtr docs(reader->termDocs()); + LuceneException finally; + try { + for (MapTermNum::iterator entry = deletesFlushed->terms.begin(); entry != deletesFlushed->terms.end(); ++entry) { + // we should be iterating a Map here, so terms better be in order + BOOST_ASSERT(checkDeleteTerm(entry->first)); + docs->seek(entry->first); + int32_t limit = entry->second->getNum(); + while (docs->next()) { + int32_t docID = docs->doc(); + if (docIDStart + docID >= limit) { + break; } + reader->deleteDocument(docID); + any = true; } } - searcher->close(); - return any; - } - - void DocumentsWriter::addDeleteTerm(const TermPtr& term, int32_t docCount) - { - SyncLock syncLock(this); - NumPtr num(deletesInRAM->terms.get(term)); - int32_t docIDUpto = flushedDocCount + docCount; - if (!num) - deletesInRAM->terms.put(term, newLucene(docIDUpto)); - else - num->setNum(docIDUpto); - ++deletesInRAM->numTerms; - - deletesInRAM->addBytesUsed(BYTES_PER_DEL_TERM + term->_text.length() * CHAR_NUM_BYTE); + } catch (LuceneException& e) { + finally = e; } + docs->close(); + finally.throwException(); - void DocumentsWriter::addDeleteDocID(int32_t docID) - { - SyncLock syncLock(this); - deletesInRAM->docIDs.add(flushedDocCount + docID); - deletesInRAM->addBytesUsed(BYTES_PER_DEL_DOCID); + // Delete by docID + for (Collection::iterator docID = deletesFlushed->docIDs.begin(); docID != deletesFlushed->docIDs.end(); ++docID) { + if (*docID >= docIDStart && *docID < docEnd) { + reader->deleteDocument(*docID - docIDStart); + any = true; + } } - void DocumentsWriter::addDeleteQuery(const QueryPtr& query, int32_t docID) - { - SyncLock syncLock(this); - deletesInRAM->queries.put(query, flushedDocCount + docID); - deletesInRAM->addBytesUsed(BYTES_PER_DEL_QUERY); + // Delete by query + IndexSearcherPtr searcher(newLucene(reader)); + for (MapQueryInt::iterator entry = deletesFlushed->queries.begin(); entry != deletesFlushed->queries.end(); ++entry) { + WeightPtr weight(entry->first->weight(searcher)); + ScorerPtr scorer(weight->scorer(reader, true, false)); + if (scorer) { + while (true) { + int32_t doc = scorer->nextDoc(); + if ((int64_t)docIDStart + doc >= entry->second) { + break; + } + reader->deleteDocument(doc); + any = true; + } + } } + searcher->close(); + return any; +} - bool DocumentsWriter::doBalanceRAM() - { - SyncLock syncLock(this); - return (ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && !bufferIsFull && - (numBytesUsed + deletesInRAM->bytesUsed + deletesFlushed->bytesUsed >= ramBufferSize || - numBytesAlloc >= freeTrigger)); +void DocumentsWriter::addDeleteTerm(const TermPtr& term, int32_t docCount) { + SyncLock syncLock(this); + NumPtr num(deletesInRAM->terms.get(term)); + int32_t docIDUpto = flushedDocCount + docCount; + if (!num) { + deletesInRAM->terms.put(term, newLucene(docIDUpto)); + } else { + num->setNum(docIDUpto); } + ++deletesInRAM->numTerms; - void DocumentsWriter::finishDocument(const DocumentsWriterThreadStatePtr& perThread, const DocWriterPtr& docWriter) - { - if (doBalanceRAM()) - { - // Must call this without holding synchronized(this) else we'll hit deadlock - balanceRAM(); - } - - { - SyncLock syncLock(this); - BOOST_ASSERT(!docWriter || docWriter->docID == perThread->docState->docID); - - if (aborting) - { - // We are currently aborting, and another thread is waiting for me to become idle. We - // just forcefully idle this threadState; it will be fully reset by abort() - if (docWriter) - { - try - { - docWriter->abort(); - } - catch (...) - { - } - } + deletesInRAM->addBytesUsed(BYTES_PER_DEL_TERM + term->_text.length() * CHAR_NUM_BYTE); +} - perThread->isIdle = true; - notifyAll(); - return; - } +void DocumentsWriter::addDeleteDocID(int32_t docID) { + SyncLock syncLock(this); + deletesInRAM->docIDs.add(flushedDocCount + docID); + deletesInRAM->addBytesUsed(BYTES_PER_DEL_DOCID); +} - bool doPause; +void DocumentsWriter::addDeleteQuery(const QueryPtr& query, int32_t docID) { + SyncLock syncLock(this); + deletesInRAM->queries.put(query, flushedDocCount + docID); + deletesInRAM->addBytesUsed(BYTES_PER_DEL_QUERY); +} - if (docWriter) - doPause = waitQueue->add(docWriter); - else - { - skipDocWriter->docID = perThread->docState->docID; - doPause = waitQueue->add(skipDocWriter); - } +bool DocumentsWriter::doBalanceRAM() { + SyncLock syncLock(this); + return (ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && !bufferIsFull && + (numBytesUsed + deletesInRAM->bytesUsed + deletesFlushed->bytesUsed >= ramBufferSize || + numBytesAlloc >= freeTrigger)); +} - if (doPause) - waitForWaitQueue(); +void DocumentsWriter::finishDocument(const DocumentsWriterThreadStatePtr& perThread, const DocWriterPtr& docWriter) { + if (doBalanceRAM()) { + // Must call this without holding synchronized(this) else we'll hit deadlock + balanceRAM(); + } - if (bufferIsFull && !flushPending) - { - flushPending = true; - perThread->doFlushAfter = true; + { + SyncLock syncLock(this); + BOOST_ASSERT(!docWriter || docWriter->docID == perThread->docState->docID); + + if (aborting) { + // We are currently aborting, and another thread is waiting for me to become idle. We + // just forcefully idle this threadState; it will be fully reset by abort() + if (docWriter) { + try { + docWriter->abort(); + } catch (...) { + } } perThread->isIdle = true; notifyAll(); + return; } - } - void DocumentsWriter::waitForWaitQueue() - { - SyncLock syncLock(this); - do - { - wait(1000); + bool doPause; + + if (docWriter) { + doPause = waitQueue->add(docWriter); + } else { + skipDocWriter->docID = perThread->docState->docID; + doPause = waitQueue->add(skipDocWriter); } - while (!waitQueue->doResume()); - } - int64_t DocumentsWriter::getRAMUsed() - { - return numBytesUsed + deletesInRAM->bytesUsed + deletesFlushed->bytesUsed; - } + if (doPause) { + waitForWaitQueue(); + } - IntArray DocumentsWriter::getIntBlock(bool trackAllocations) - { - SyncLock syncLock(this); - int32_t size = freeIntBlocks.size(); - IntArray b; - if (size == 0) - { - // Always record a block allocated, even if trackAllocations is false. This is necessary because - // this block will be shared between things that don't track allocations (term vectors) and things - // that do (freq/prox postings). - numBytesAlloc += INT_BLOCK_SIZE * INT_NUM_BYTE; - b = IntArray::newInstance(INT_BLOCK_SIZE); + if (bufferIsFull && !flushPending) { + flushPending = true; + perThread->doFlushAfter = true; } - else - b = freeIntBlocks.removeLast(); - if (trackAllocations) - numBytesUsed += INT_BLOCK_SIZE * INT_NUM_BYTE; - BOOST_ASSERT(numBytesUsed <= numBytesAlloc); - return b; - } - void DocumentsWriter::bytesAllocated(int64_t numBytes) - { - SyncLock syncLock(this); - numBytesAlloc += numBytes; + perThread->isIdle = true; + notifyAll(); } +} - void DocumentsWriter::bytesUsed(int64_t numBytes) - { - SyncLock syncLock(this); - numBytesUsed += numBytes; - BOOST_ASSERT(numBytesUsed <= numBytesAlloc); - } +void DocumentsWriter::waitForWaitQueue() { + SyncLock syncLock(this); + do { + wait(1000); + } while (!waitQueue->doResume()); +} - void DocumentsWriter::recycleIntBlocks(Collection blocks, int32_t start, int32_t end) - { - SyncLock syncLock(this); - for (int32_t i = start; i < end; ++i) - { - freeIntBlocks.add(blocks[i]); - blocks[i].reset(); - } - } +int64_t DocumentsWriter::getRAMUsed() { + return numBytesUsed + deletesInRAM->bytesUsed + deletesFlushed->bytesUsed; +} - CharArray DocumentsWriter::getCharBlock() - { - SyncLock syncLock(this); - int32_t size = freeCharBlocks.size(); - CharArray c; - if (size == 0) - { - numBytesAlloc += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; - c = CharArray::newInstance(CHAR_BLOCK_SIZE); - } - else - c = freeCharBlocks.removeLast(); - // We always track allocations of char blocks for now because nothing that skips allocation tracking - // (currently only term vectors) uses its own char blocks. - numBytesUsed += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; - BOOST_ASSERT(numBytesUsed <= numBytesAlloc); - return c; - } +IntArray DocumentsWriter::getIntBlock(bool trackAllocations) { + SyncLock syncLock(this); + int32_t size = freeIntBlocks.size(); + IntArray b; + if (size == 0) { + // Always record a block allocated, even if trackAllocations is false. This is necessary because + // this block will be shared between things that don't track allocations (term vectors) and things + // that do (freq/prox postings). + numBytesAlloc += INT_BLOCK_SIZE * INT_NUM_BYTE; + b = IntArray::newInstance(INT_BLOCK_SIZE); + } else { + b = freeIntBlocks.removeLast(); + } + if (trackAllocations) { + numBytesUsed += INT_BLOCK_SIZE * INT_NUM_BYTE; + } + BOOST_ASSERT(numBytesUsed <= numBytesAlloc); + return b; +} - void DocumentsWriter::recycleCharBlocks(Collection blocks, int32_t numBlocks) - { - SyncLock syncLock(this); - for (int32_t i = 0; i < numBlocks; ++i) - { - freeCharBlocks.add(blocks[i]); - blocks[i].reset(); - } - } +void DocumentsWriter::bytesAllocated(int64_t numBytes) { + SyncLock syncLock(this); + numBytesAlloc += numBytes; +} - String DocumentsWriter::toMB(int64_t v) - { - return StringUtils::toString((double)v / 1024.0 / 1024.0); +void DocumentsWriter::bytesUsed(int64_t numBytes) { + SyncLock syncLock(this); + numBytesUsed += numBytes; + BOOST_ASSERT(numBytesUsed <= numBytesAlloc); +} + +void DocumentsWriter::recycleIntBlocks(Collection blocks, int32_t start, int32_t end) { + SyncLock syncLock(this); + for (int32_t i = start; i < end; ++i) { + freeIntBlocks.add(blocks[i]); + blocks[i].reset(); } +} - void DocumentsWriter::balanceRAM() - { - // We flush when we've used our target usage - int64_t flushTrigger = ramBufferSize; +CharArray DocumentsWriter::getCharBlock() { + SyncLock syncLock(this); + int32_t size = freeCharBlocks.size(); + CharArray c; + if (size == 0) { + numBytesAlloc += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + c = CharArray::newInstance(CHAR_BLOCK_SIZE); + } else { + c = freeCharBlocks.removeLast(); + } + // We always track allocations of char blocks for now because nothing that skips allocation tracking + // (currently only term vectors) uses its own char blocks. + numBytesUsed += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + BOOST_ASSERT(numBytesUsed <= numBytesAlloc); + return c; +} - int64_t deletesRAMUsed = deletesInRAM->bytesUsed + deletesFlushed->bytesUsed; +void DocumentsWriter::recycleCharBlocks(Collection blocks, int32_t numBlocks) { + SyncLock syncLock(this); + for (int32_t i = 0; i < numBlocks; ++i) { + freeCharBlocks.add(blocks[i]); + blocks[i].reset(); + } +} - if (numBytesAlloc + deletesRAMUsed > freeTrigger) - { - if (infoStream) - { - message(L" RAM: now balance allocations: usedMB=" + toMB(numBytesUsed) + - L" vs trigger=" + toMB(flushTrigger) + - L" allocMB=" + toMB(numBytesAlloc) + - L" deletesMB=" + toMB(deletesRAMUsed) + - L" vs trigger=" + toMB(freeTrigger) + - L" byteBlockFree=" + toMB(byteBlockAllocator->freeByteBlocks.size() * BYTE_BLOCK_SIZE) + - L" perDocFree=" + toMB(perDocAllocator->freeByteBlocks.size() * PER_DOC_BLOCK_SIZE) + - L" charBlockFree=" + toMB(freeCharBlocks.size() * CHAR_BLOCK_SIZE * CHAR_NUM_BYTE)); - } +String DocumentsWriter::toMB(int64_t v) { + return StringUtils::toString((double)v / 1024.0 / 1024.0); +} + +void DocumentsWriter::balanceRAM() { + // We flush when we've used our target usage + int64_t flushTrigger = ramBufferSize; + + int64_t deletesRAMUsed = deletesInRAM->bytesUsed + deletesFlushed->bytesUsed; + + if (numBytesAlloc + deletesRAMUsed > freeTrigger) { + if (infoStream) { + message(L" RAM: now balance allocations: usedMB=" + toMB(numBytesUsed) + + L" vs trigger=" + toMB(flushTrigger) + + L" allocMB=" + toMB(numBytesAlloc) + + L" deletesMB=" + toMB(deletesRAMUsed) + + L" vs trigger=" + toMB(freeTrigger) + + L" byteBlockFree=" + toMB(byteBlockAllocator->freeByteBlocks.size() * BYTE_BLOCK_SIZE) + + L" perDocFree=" + toMB(perDocAllocator->freeByteBlocks.size() * PER_DOC_BLOCK_SIZE) + + L" charBlockFree=" + toMB(freeCharBlocks.size() * CHAR_BLOCK_SIZE * CHAR_NUM_BYTE)); + } - int64_t startBytesAlloc = numBytesAlloc + deletesRAMUsed; + int64_t startBytesAlloc = numBytesAlloc + deletesRAMUsed; - int32_t iter = 0; + int32_t iter = 0; - // We free equally from each pool in 32 KB chunks until we are below our threshold (freeLevel) + // We free equally from each pool in 32 KB chunks until we are below our threshold (freeLevel) - bool any = true; + bool any = true; - while (numBytesAlloc + deletesRAMUsed > freeLevel) + while (numBytesAlloc + deletesRAMUsed > freeLevel) { { - { - SyncLock syncLock(this); - if (perDocAllocator->freeByteBlocks.empty() && byteBlockAllocator->freeByteBlocks.empty() && - freeCharBlocks.empty() && freeIntBlocks.empty() && !any) - { - // Nothing else to free -- must flush now. - bufferIsFull = (numBytesUsed + deletesRAMUsed > flushTrigger); - if (infoStream) - { - if (bufferIsFull) - message(L" nothing to free; now set bufferIsFull"); - else - message(L" nothing to free"); + SyncLock syncLock(this); + if (perDocAllocator->freeByteBlocks.empty() && byteBlockAllocator->freeByteBlocks.empty() && + freeCharBlocks.empty() && freeIntBlocks.empty() && !any) { + // Nothing else to free -- must flush now. + bufferIsFull = (numBytesUsed + deletesRAMUsed > flushTrigger); + if (infoStream) { + if (bufferIsFull) { + message(L" nothing to free; now set bufferIsFull"); + } else { + message(L" nothing to free"); } - BOOST_ASSERT(numBytesUsed <= numBytesAlloc); - break; } + BOOST_ASSERT(numBytesUsed <= numBytesAlloc); + break; + } - if ((iter % 5) == 0 && !byteBlockAllocator->freeByteBlocks.empty()) - { - byteBlockAllocator->freeByteBlocks.removeLast(); - numBytesAlloc -= BYTE_BLOCK_SIZE; - } + if ((iter % 5) == 0 && !byteBlockAllocator->freeByteBlocks.empty()) { + byteBlockAllocator->freeByteBlocks.removeLast(); + numBytesAlloc -= BYTE_BLOCK_SIZE; + } - if ((iter % 5) == 1 && !freeCharBlocks.empty()) - { - freeCharBlocks.removeLast(); - numBytesAlloc -= CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; - } + if ((iter % 5) == 1 && !freeCharBlocks.empty()) { + freeCharBlocks.removeLast(); + numBytesAlloc -= CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + } - if ((iter % 5) == 2 && !freeIntBlocks.empty()) - { - freeIntBlocks.removeLast(); - numBytesAlloc -= INT_BLOCK_SIZE * INT_NUM_BYTE; - } + if ((iter % 5) == 2 && !freeIntBlocks.empty()) { + freeIntBlocks.removeLast(); + numBytesAlloc -= INT_BLOCK_SIZE * INT_NUM_BYTE; + } - if ((iter % 5) == 3 && !perDocAllocator->freeByteBlocks.empty()) - { - // Remove upwards of 32 blocks (each block is 1K) - for (int32_t i = 0; i < 32; ++i) - { - perDocAllocator->freeByteBlocks.removeLast(); - numBytesAlloc -= PER_DOC_BLOCK_SIZE; - if (perDocAllocator->freeByteBlocks.empty()) - break; + if ((iter % 5) == 3 && !perDocAllocator->freeByteBlocks.empty()) { + // Remove upwards of 32 blocks (each block is 1K) + for (int32_t i = 0; i < 32; ++i) { + perDocAllocator->freeByteBlocks.removeLast(); + numBytesAlloc -= PER_DOC_BLOCK_SIZE; + if (perDocAllocator->freeByteBlocks.empty()) { + break; } } } - - if ((iter % 5) == 4 && any) - { - // Ask consumer to free any recycled state - any = consumer->freeRAM(); - } - - ++iter; } - if (infoStream) - { - message(L" after free: freedMB=" + StringUtils::toString((double)(startBytesAlloc - numBytesAlloc - deletesRAMUsed) / 1024.0 / 1024.0) + - L" usedMB=" + StringUtils::toString((double)(numBytesUsed + deletesRAMUsed) / 1024.0 / 1024.0) + - L" allocMB=" + StringUtils::toString((double)numBytesAlloc / 1024.0 / 1024.0)); + if ((iter % 5) == 4 && any) { + // Ask consumer to free any recycled state + any = consumer->freeRAM(); } + + ++iter; } - else - { - // If we have not crossed the 100% mark, but have crossed the 95% mark of RAM we are actually - // using, go ahead and flush. This prevents over-allocating and then freeing, with every flush. - SyncLock syncLock(this); - if (numBytesUsed + deletesRAMUsed > flushTrigger) - { - if (infoStream) - { - message(L" RAM: now flush @ usedMB=" + StringUtils::toString((double)numBytesUsed / 1024.0 / 1024.0) + - L" allocMB=" + StringUtils::toString((double)numBytesAlloc / 1024.0 / 1024.0) + - L" deletesMB=" + StringUtils::toString((double)deletesRAMUsed / 1024.0 / 1024.0) + - L" triggerMB=" + StringUtils::toString((double)flushTrigger / 1024.0 / 1024.0)); - } - bufferIsFull = true; + + if (infoStream) { + message(L" after free: freedMB=" + StringUtils::toString((double)(startBytesAlloc - numBytesAlloc - deletesRAMUsed) / 1024.0 / 1024.0) + + L" usedMB=" + StringUtils::toString((double)(numBytesUsed + deletesRAMUsed) / 1024.0 / 1024.0) + + L" allocMB=" + StringUtils::toString((double)numBytesAlloc / 1024.0 / 1024.0)); + } + } else { + // If we have not crossed the 100% mark, but have crossed the 95% mark of RAM we are actually + // using, go ahead and flush. This prevents over-allocating and then freeing, with every flush. + SyncLock syncLock(this); + if (numBytesUsed + deletesRAMUsed > flushTrigger) { + if (infoStream) { + message(L" RAM: now flush @ usedMB=" + StringUtils::toString((double)numBytesUsed / 1024.0 / 1024.0) + + L" allocMB=" + StringUtils::toString((double)numBytesAlloc / 1024.0 / 1024.0) + + L" deletesMB=" + StringUtils::toString((double)deletesRAMUsed / 1024.0 / 1024.0) + + L" triggerMB=" + StringUtils::toString((double)flushTrigger / 1024.0 / 1024.0)); } + bufferIsFull = true; } } +} - DocState::DocState() - { - maxFieldLength = 0; - docID = 0; - } +DocState::DocState() { + maxFieldLength = 0; + docID = 0; +} - DocState::~DocState() - { - } +DocState::~DocState() { +} - bool DocState::testPoint(const String& name) - { - return IndexWriterPtr(DocumentsWriterPtr(_docWriter)->_writer)->testPoint(name); - } +bool DocState::testPoint(const String& name) { + return IndexWriterPtr(DocumentsWriterPtr(_docWriter)->_writer)->testPoint(name); +} - void DocState::clear() - { - // don't hold onto doc nor analyzer, in case it is large - doc.reset(); - analyzer.reset(); - } +void DocState::clear() { + // don't hold onto doc nor analyzer, in case it is large + doc.reset(); + analyzer.reset(); +} - PerDocBuffer::PerDocBuffer(const DocumentsWriterPtr& docWriter) - { - _docWriter = docWriter; - } +PerDocBuffer::PerDocBuffer(const DocumentsWriterPtr& docWriter) { + _docWriter = docWriter; +} - PerDocBuffer::~PerDocBuffer() - { - } +PerDocBuffer::~PerDocBuffer() { +} - ByteArray PerDocBuffer::newBuffer(int32_t size) - { - BOOST_ASSERT(size == DocumentsWriter::PER_DOC_BLOCK_SIZE); - return DocumentsWriterPtr(_docWriter)->perDocAllocator->getByteBlock(false); - } +ByteArray PerDocBuffer::newBuffer(int32_t size) { + BOOST_ASSERT(size == DocumentsWriter::PER_DOC_BLOCK_SIZE); + return DocumentsWriterPtr(_docWriter)->perDocAllocator->getByteBlock(false); +} - void PerDocBuffer::recycle() - { - SyncLock syncLock(this); - if (!buffers.empty()) - { - setLength(0); +void PerDocBuffer::recycle() { + SyncLock syncLock(this); + if (!buffers.empty()) { + setLength(0); - // Recycle the blocks - DocumentsWriterPtr(_docWriter)->perDocAllocator->recycleByteBlocks(buffers); - buffers.clear(); - sizeInBytes = 0; + // Recycle the blocks + DocumentsWriterPtr(_docWriter)->perDocAllocator->recycleByteBlocks(buffers); + buffers.clear(); + sizeInBytes = 0; - BOOST_ASSERT(numBuffers() == 0); - } + BOOST_ASSERT(numBuffers() == 0); } +} - DocWriter::DocWriter() - { - docID = 0; - } +DocWriter::DocWriter() { + docID = 0; +} - DocWriter::~DocWriter() - { - } +DocWriter::~DocWriter() { +} - void DocWriter::setNext(const DocWriterPtr& next) - { - this->next = next; - } +void DocWriter::setNext(const DocWriterPtr& next) { + this->next = next; +} - IndexingChain::~IndexingChain() - { - } +IndexingChain::~IndexingChain() { +} - DefaultIndexingChain::~DefaultIndexingChain() - { - } +DefaultIndexingChain::~DefaultIndexingChain() { +} - DocConsumerPtr DefaultIndexingChain::getChain(const DocumentsWriterPtr& documentsWriter) - { - TermsHashConsumerPtr termVectorsWriter(newLucene(documentsWriter)); - TermsHashConsumerPtr freqProxWriter(newLucene()); +DocConsumerPtr DefaultIndexingChain::getChain(const DocumentsWriterPtr& documentsWriter) { + TermsHashConsumerPtr termVectorsWriter(newLucene(documentsWriter)); + TermsHashConsumerPtr freqProxWriter(newLucene()); - InvertedDocConsumerPtr termsHash(newLucene(documentsWriter, true, freqProxWriter, - newLucene(documentsWriter, false, - termVectorsWriter, TermsHashPtr()))); + InvertedDocConsumerPtr termsHash(newLucene(documentsWriter, true, freqProxWriter, + newLucene(documentsWriter, false, + termVectorsWriter, TermsHashPtr()))); - DocInverterPtr docInverter(newLucene(termsHash, newLucene())); - return newLucene(documentsWriter, docInverter); - } + DocInverterPtr docInverter(newLucene(termsHash, newLucene())); + return newLucene(documentsWriter, docInverter); +} - SkipDocWriter::~SkipDocWriter() - { - } +SkipDocWriter::~SkipDocWriter() { +} - void SkipDocWriter::finish() - { - } +void SkipDocWriter::finish() { +} - void SkipDocWriter::abort() - { - } +void SkipDocWriter::abort() { +} - int64_t SkipDocWriter::sizeInBytes() - { - return 0; - } +int64_t SkipDocWriter::sizeInBytes() { + return 0; +} - WaitQueue::WaitQueue(const DocumentsWriterPtr& docWriter) - { - this->_docWriter = docWriter; - waiting = Collection::newInstance(10); - nextWriteDocID = 0; - nextWriteLoc = 0; - numWaiting = 0; - waitingBytes = 0; - } +WaitQueue::WaitQueue(const DocumentsWriterPtr& docWriter) { + this->_docWriter = docWriter; + waiting = Collection::newInstance(10); + nextWriteDocID = 0; + nextWriteLoc = 0; + numWaiting = 0; + waitingBytes = 0; +} - WaitQueue::~WaitQueue() - { - } +WaitQueue::~WaitQueue() { +} - void WaitQueue::reset() - { - SyncLock syncLock(this); - // NOTE: nextWriteLoc doesn't need to be reset - BOOST_ASSERT(numWaiting == 0); - BOOST_ASSERT(waitingBytes == 0); - nextWriteDocID = 0; - } +void WaitQueue::reset() { + SyncLock syncLock(this); + // NOTE: nextWriteLoc doesn't need to be reset + BOOST_ASSERT(numWaiting == 0); + BOOST_ASSERT(waitingBytes == 0); + nextWriteDocID = 0; +} - bool WaitQueue::doResume() - { - SyncLock syncLock(this); - return (waitingBytes <= DocumentsWriterPtr(_docWriter)->waitQueueResumeBytes); - } +bool WaitQueue::doResume() { + SyncLock syncLock(this); + return (waitingBytes <= DocumentsWriterPtr(_docWriter)->waitQueueResumeBytes); +} - bool WaitQueue::doPause() - { - SyncLock syncLock(this); - return (waitingBytes > DocumentsWriterPtr(_docWriter)->waitQueuePauseBytes); - } +bool WaitQueue::doPause() { + SyncLock syncLock(this); + return (waitingBytes > DocumentsWriterPtr(_docWriter)->waitQueuePauseBytes); +} - void WaitQueue::abort() - { - SyncLock syncLock(this); - int32_t count = 0; - for (Collection::iterator doc = waiting.begin(); doc != waiting.end(); ++doc) - { - if (*doc) - { - (*doc)->abort(); - doc->reset(); - ++count; - } +void WaitQueue::abort() { + SyncLock syncLock(this); + int32_t count = 0; + for (Collection::iterator doc = waiting.begin(); doc != waiting.end(); ++doc) { + if (*doc) { + (*doc)->abort(); + doc->reset(); + ++count; } - waitingBytes = 0; - BOOST_ASSERT(count == numWaiting); - numWaiting = 0; } + waitingBytes = 0; + BOOST_ASSERT(count == numWaiting); + numWaiting = 0; +} - void WaitQueue::writeDocument(const DocWriterPtr& doc) - { - DocumentsWriterPtr docWriter(_docWriter); - BOOST_ASSERT(doc == DocumentsWriterPtr(docWriter)->skipDocWriter || nextWriteDocID == doc->docID); - bool success = false; - LuceneException finally; - try - { - doc->finish(); - ++nextWriteDocID; - ++docWriter->numDocsInStore; - ++nextWriteLoc; - BOOST_ASSERT(nextWriteLoc <= waiting.size()); - if (nextWriteLoc == waiting.size()) - nextWriteLoc = 0; - success = true; - } - catch (LuceneException& e) - { - finally = e; +void WaitQueue::writeDocument(const DocWriterPtr& doc) { + DocumentsWriterPtr docWriter(_docWriter); + BOOST_ASSERT(doc == DocumentsWriterPtr(docWriter)->skipDocWriter || nextWriteDocID == doc->docID); + bool success = false; + LuceneException finally; + try { + doc->finish(); + ++nextWriteDocID; + ++docWriter->numDocsInStore; + ++nextWriteLoc; + BOOST_ASSERT(nextWriteLoc <= waiting.size()); + if (nextWriteLoc == waiting.size()) { + nextWriteLoc = 0; } - if (!success) - docWriter->setAborting(); - finally.throwException(); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + docWriter->setAborting(); } + finally.throwException(); +} - bool WaitQueue::add(const DocWriterPtr& doc) - { - DocWriterPtr _doc(doc); - SyncLock syncLock(this); - BOOST_ASSERT(_doc->docID >= nextWriteDocID); - if (_doc->docID == nextWriteDocID) - { - writeDocument(_doc); - while (true) - { - _doc = waiting[nextWriteLoc]; - if (_doc) - { - --numWaiting; - waiting[nextWriteLoc].reset(); - waitingBytes -= _doc->sizeInBytes(); - writeDocument(_doc); - } - else - break; +bool WaitQueue::add(const DocWriterPtr& doc) { + DocWriterPtr _doc(doc); + SyncLock syncLock(this); + BOOST_ASSERT(_doc->docID >= nextWriteDocID); + if (_doc->docID == nextWriteDocID) { + writeDocument(_doc); + while (true) { + _doc = waiting[nextWriteLoc]; + if (_doc) { + --numWaiting; + waiting[nextWriteLoc].reset(); + waitingBytes -= _doc->sizeInBytes(); + writeDocument(_doc); + } else { + break; } } - else - { - // I finished before documents that were added before me. This can easily happen when I am a small doc - // and the docs before me were large, or just due to luck in the thread scheduling. Just add myself to - // the queue and when that large doc finishes, it will flush me - int32_t gap = _doc->docID - nextWriteDocID; - if (gap >= waiting.size()) - { - // Grow queue - Collection newArray(Collection::newInstance(MiscUtils::getNextSize(gap))); - BOOST_ASSERT(nextWriteLoc >= 0); - MiscUtils::arrayCopy(waiting.begin(), nextWriteLoc, newArray.begin(), 0, waiting.size() - nextWriteLoc); - MiscUtils::arrayCopy(waiting.begin(), 0, newArray.begin(), waiting.size() - nextWriteLoc, nextWriteLoc); - nextWriteLoc = 0; - waiting = newArray; - gap = _doc->docID - nextWriteDocID; - } - - int32_t loc = nextWriteLoc + gap; - if (loc >= waiting.size()) - loc -= waiting.size(); - - // We should only wrap one time - BOOST_ASSERT(loc < waiting.size()); + } else { + // I finished before documents that were added before me. This can easily happen when I am a small doc + // and the docs before me were large, or just due to luck in the thread scheduling. Just add myself to + // the queue and when that large doc finishes, it will flush me + int32_t gap = _doc->docID - nextWriteDocID; + if (gap >= waiting.size()) { + // Grow queue + Collection newArray(Collection::newInstance(MiscUtils::getNextSize(gap))); + BOOST_ASSERT(nextWriteLoc >= 0); + MiscUtils::arrayCopy(waiting.begin(), nextWriteLoc, newArray.begin(), 0, waiting.size() - nextWriteLoc); + MiscUtils::arrayCopy(waiting.begin(), 0, newArray.begin(), waiting.size() - nextWriteLoc, nextWriteLoc); + nextWriteLoc = 0; + waiting = newArray; + gap = _doc->docID - nextWriteDocID; + } - // Nobody should be in my spot! - BOOST_ASSERT(!waiting[loc]); - waiting[loc] = _doc; - ++numWaiting; - waitingBytes += _doc->sizeInBytes(); + int32_t loc = nextWriteLoc + gap; + if (loc >= waiting.size()) { + loc -= waiting.size(); } - return doPause(); - } + // We should only wrap one time + BOOST_ASSERT(loc < waiting.size()); - ByteBlockAllocator::ByteBlockAllocator(const DocumentsWriterPtr& docWriter, int32_t blockSize) - { - this->blockSize = blockSize; - this->freeByteBlocks = Collection::newInstance(); - this->_docWriter = docWriter; + // Nobody should be in my spot! + BOOST_ASSERT(!waiting[loc]); + waiting[loc] = _doc; + ++numWaiting; + waitingBytes += _doc->sizeInBytes(); } - ByteBlockAllocator::~ByteBlockAllocator() - { - } + return doPause(); +} - ByteArray ByteBlockAllocator::getByteBlock(bool trackAllocations) - { - DocumentsWriterPtr docWriter(_docWriter); - SyncLock syncLock(docWriter); - int32_t size = freeByteBlocks.size(); - ByteArray b; - if (size == 0) - { - // Always record a block allocated, even if trackAllocations is false. This is necessary because this block will - // be shared between things that don't track allocations (term vectors) and things that do (freq/prox postings). - docWriter->numBytesAlloc += blockSize; - b = ByteArray::newInstance(blockSize); - MiscUtils::arrayFill(b.get(), 0, b.size(), 0); - } - else - b = freeByteBlocks.removeLast(); - if (trackAllocations) - docWriter->numBytesUsed += blockSize; - BOOST_ASSERT(docWriter->numBytesUsed <= docWriter->numBytesAlloc); - return b; - } +ByteBlockAllocator::ByteBlockAllocator(const DocumentsWriterPtr& docWriter, int32_t blockSize) { + this->blockSize = blockSize; + this->freeByteBlocks = Collection::newInstance(); + this->_docWriter = docWriter; +} - void ByteBlockAllocator::recycleByteBlocks(Collection blocks, int32_t start, int32_t end) - { - DocumentsWriterPtr docWriter(_docWriter); - SyncLock syncLock(docWriter); - for (int32_t i = start; i < end; ++i) - { - freeByteBlocks.add(blocks[i]); - blocks[i].reset(); - } +ByteBlockAllocator::~ByteBlockAllocator() { +} + +ByteArray ByteBlockAllocator::getByteBlock(bool trackAllocations) { + DocumentsWriterPtr docWriter(_docWriter); + SyncLock syncLock(docWriter); + int32_t size = freeByteBlocks.size(); + ByteArray b; + if (size == 0) { + // Always record a block allocated, even if trackAllocations is false. This is necessary because this block will + // be shared between things that don't track allocations (term vectors) and things that do (freq/prox postings). + docWriter->numBytesAlloc += blockSize; + b = ByteArray::newInstance(blockSize); + MiscUtils::arrayFill(b.get(), 0, b.size(), 0); + } else { + b = freeByteBlocks.removeLast(); + } + if (trackAllocations) { + docWriter->numBytesUsed += blockSize; + } + BOOST_ASSERT(docWriter->numBytesUsed <= docWriter->numBytesAlloc); + return b; +} + +void ByteBlockAllocator::recycleByteBlocks(Collection blocks, int32_t start, int32_t end) { + DocumentsWriterPtr docWriter(_docWriter); + SyncLock syncLock(docWriter); + for (int32_t i = start; i < end; ++i) { + freeByteBlocks.add(blocks[i]); + blocks[i].reset(); } +} - void ByteBlockAllocator::recycleByteBlocks(Collection blocks) - { - DocumentsWriterPtr docWriter(_docWriter); - SyncLock syncLock(docWriter); - int32_t size = blocks.size(); - for (int32_t i = 0; i < size; ++i) - freeByteBlocks.add(blocks[i]); +void ByteBlockAllocator::recycleByteBlocks(Collection blocks) { + DocumentsWriterPtr docWriter(_docWriter); + SyncLock syncLock(docWriter); + int32_t size = blocks.size(); + for (int32_t i = 0; i < size; ++i) { + freeByteBlocks.add(blocks[i]); } } + +} diff --git a/src/core/index/DocumentsWriterThreadState.cpp b/src/core/index/DocumentsWriterThreadState.cpp index 21791cd9..edb18df8 100644 --- a/src/core/index/DocumentsWriterThreadState.cpp +++ b/src/core/index/DocumentsWriterThreadState.cpp @@ -9,34 +9,31 @@ #include "DocumentsWriter.h" #include "DocConsumer.h" -namespace Lucene -{ - DocumentsWriterThreadState::DocumentsWriterThreadState(const DocumentsWriterPtr& docWriter) - { - this->_docWriter = docWriter; - } +namespace Lucene { - DocumentsWriterThreadState::~DocumentsWriterThreadState() - { - } +DocumentsWriterThreadState::DocumentsWriterThreadState(const DocumentsWriterPtr& docWriter) { + this->_docWriter = docWriter; +} + +DocumentsWriterThreadState::~DocumentsWriterThreadState() { +} - void DocumentsWriterThreadState::initialize() - { - isIdle = true; - doFlushAfter = false; - numThreads = 1; - DocumentsWriterPtr docWriter(_docWriter); - docState = newLucene(); - docState->maxFieldLength = docWriter->maxFieldLength; - docState->infoStream = docWriter->infoStream; - docState->similarity = docWriter->similarity; - docState->_docWriter = docWriter; - consumer = docWriter->consumer->addThread(shared_from_this()); - } +void DocumentsWriterThreadState::initialize() { + isIdle = true; + doFlushAfter = false; + numThreads = 1; + DocumentsWriterPtr docWriter(_docWriter); + docState = newLucene(); + docState->maxFieldLength = docWriter->maxFieldLength; + docState->infoStream = docWriter->infoStream; + docState->similarity = docWriter->similarity; + docState->_docWriter = docWriter; + consumer = docWriter->consumer->addThread(shared_from_this()); +} + +void DocumentsWriterThreadState::doAfterFlush() { + numThreads = 0; + doFlushAfter = false; +} - void DocumentsWriterThreadState::doAfterFlush() - { - numThreads = 0; - doFlushAfter = false; - } } diff --git a/src/core/index/FieldInfo.cpp b/src/core/index/FieldInfo.cpp index 05f31674..ccd0f2c3 100644 --- a/src/core/index/FieldInfo.cpp +++ b/src/core/index/FieldInfo.cpp @@ -7,54 +7,57 @@ #include "LuceneInc.h" #include "FieldInfo.h" -namespace Lucene -{ - FieldInfo::FieldInfo(const String& name, bool isIndexed, int32_t number, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) - { - this->name = name; - this->isIndexed = isIndexed; - this->number = number; - - // for non-indexed fields, leave defaults - this->storeTermVector = isIndexed ? storeTermVector : false; - this->storeOffsetWithTermVector = isIndexed ? storeOffsetWithTermVector : false; - this->storePositionWithTermVector = isIndexed ? storePositionWithTermVector : false; - this->storePayloads = isIndexed ? storePayloads : false; - this->omitNorms = isIndexed ? omitNorms : true; - this->omitTermFreqAndPositions = isIndexed ? omitTermFreqAndPositions : false; - } +namespace Lucene { - FieldInfo::~FieldInfo() - { - } +FieldInfo::FieldInfo(const String& name, bool isIndexed, int32_t number, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) { + this->name = name; + this->isIndexed = isIndexed; + this->number = number; - LuceneObjectPtr FieldInfo::clone(const LuceneObjectPtr& other) - { - return newLucene(name, isIndexed, number, storeTermVector, storePositionWithTermVector, - storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); - } + // for non-indexed fields, leave defaults + this->storeTermVector = isIndexed ? storeTermVector : false; + this->storeOffsetWithTermVector = isIndexed ? storeOffsetWithTermVector : false; + this->storePositionWithTermVector = isIndexed ? storePositionWithTermVector : false; + this->storePayloads = isIndexed ? storePayloads : false; + this->omitNorms = isIndexed ? omitNorms : true; + this->omitTermFreqAndPositions = isIndexed ? omitTermFreqAndPositions : false; +} + +FieldInfo::~FieldInfo() { +} + +LuceneObjectPtr FieldInfo::clone(const LuceneObjectPtr& other) { + return newLucene(name, isIndexed, number, storeTermVector, storePositionWithTermVector, + storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); +} - void FieldInfo::update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, - bool omitTermFreqAndPositions) - { - if (this->isIndexed != isIndexed) - this->isIndexed = true; // once indexed, always index - if (isIndexed) // if updated field data is not for indexing, leave the updates out - { - if (this->storeTermVector != storeTermVector) - this->storeTermVector = true; // once vector, always vector - if (this->storePositionWithTermVector != storePositionWithTermVector) - this->storePositionWithTermVector = true; // once vector, always vector - if (this->storeOffsetWithTermVector != storeOffsetWithTermVector) - this->storeOffsetWithTermVector = true; // once vector, always vector - if (this->storePayloads != storePayloads) - this->storePayloads = true; - if (this->omitNorms != omitNorms) - this->omitNorms = false; // once norms are stored, always store - if (this->omitTermFreqAndPositions != omitTermFreqAndPositions) - this->omitTermFreqAndPositions = true; // if one require omitTermFreqAndPositions at least once, it remains off for life +void FieldInfo::update(bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, + bool omitTermFreqAndPositions) { + if (this->isIndexed != isIndexed) { + this->isIndexed = true; // once indexed, always index + } + if (isIndexed) { // if updated field data is not for indexing, leave the updates out + if (this->storeTermVector != storeTermVector) { + this->storeTermVector = true; // once vector, always vector + } + if (this->storePositionWithTermVector != storePositionWithTermVector) { + this->storePositionWithTermVector = true; // once vector, always vector + } + if (this->storeOffsetWithTermVector != storeOffsetWithTermVector) { + this->storeOffsetWithTermVector = true; // once vector, always vector + } + if (this->storePayloads != storePayloads) { + this->storePayloads = true; + } + if (this->omitNorms != omitNorms) { + this->omitNorms = false; // once norms are stored, always store + } + if (this->omitTermFreqAndPositions != omitTermFreqAndPositions) { + this->omitTermFreqAndPositions = true; // if one require omitTermFreqAndPositions at least once, it remains off for life } } } + +} diff --git a/src/core/index/FieldInfos.cpp b/src/core/index/FieldInfos.cpp index d2c0733c..05d7499d 100644 --- a/src/core/index/FieldInfos.cpp +++ b/src/core/index/FieldInfos.cpp @@ -14,275 +14,246 @@ #include "Fieldable.h" #include "StringUtils.h" -namespace Lucene -{ - // Used internally (ie not written to *.fnm files) for pre-2.9 files - const int32_t FieldInfos::FORMAT_PRE = -1; - - // First used in 2.9; prior to 2.9 there was no format header - const int32_t FieldInfos::FORMAT_START = -2; - - const int32_t FieldInfos::CURRENT_FORMAT = FieldInfos::FORMAT_START; - - const uint8_t FieldInfos::IS_INDEXED = 0x1; - const uint8_t FieldInfos::STORE_TERMVECTOR = 0x2; - const uint8_t FieldInfos::STORE_POSITIONS_WITH_TERMVECTOR = 0x4; - const uint8_t FieldInfos::STORE_OFFSET_WITH_TERMVECTOR = 0x8; - const uint8_t FieldInfos::OMIT_NORMS = 0x10; - const uint8_t FieldInfos::STORE_PAYLOADS = 0x20; - const uint8_t FieldInfos::OMIT_TERM_FREQ_AND_POSITIONS = 0x40; - - FieldInfos::FieldInfos() - { - format = 0; - byNumber = Collection::newInstance(); - byName = MapStringFieldInfo::newInstance(); - } +namespace Lucene { - FieldInfos::FieldInfos(const DirectoryPtr& d, const String& name) - { - format = 0; - byNumber = Collection::newInstance(); - byName = MapStringFieldInfo::newInstance(); - IndexInputPtr input(d->openInput(name)); - LuceneException finally; - try - { - try - { - read(input, name); - } - catch (IOException& e) - { - if (format == FORMAT_PRE) - { - input->seek(0); - input->setModifiedUTF8StringsMode(); - byNumber.clear(); - byName.clear(); - try - { - read(input, name); - } - catch (...) - { - // Ignore any new exception & throw original IOE - finally = e; - } - } - else +// Used internally (ie not written to *.fnm files) for pre-2.9 files +const int32_t FieldInfos::FORMAT_PRE = -1; + +// First used in 2.9; prior to 2.9 there was no format header +const int32_t FieldInfos::FORMAT_START = -2; + +const int32_t FieldInfos::CURRENT_FORMAT = FieldInfos::FORMAT_START; + +const uint8_t FieldInfos::IS_INDEXED = 0x1; +const uint8_t FieldInfos::STORE_TERMVECTOR = 0x2; +const uint8_t FieldInfos::STORE_POSITIONS_WITH_TERMVECTOR = 0x4; +const uint8_t FieldInfos::STORE_OFFSET_WITH_TERMVECTOR = 0x8; +const uint8_t FieldInfos::OMIT_NORMS = 0x10; +const uint8_t FieldInfos::STORE_PAYLOADS = 0x20; +const uint8_t FieldInfos::OMIT_TERM_FREQ_AND_POSITIONS = 0x40; + +FieldInfos::FieldInfos() { + format = 0; + byNumber = Collection::newInstance(); + byName = MapStringFieldInfo::newInstance(); +} + +FieldInfos::FieldInfos(const DirectoryPtr& d, const String& name) { + format = 0; + byNumber = Collection::newInstance(); + byName = MapStringFieldInfo::newInstance(); + IndexInputPtr input(d->openInput(name)); + LuceneException finally; + try { + try { + read(input, name); + } catch (IOException& e) { + if (format == FORMAT_PRE) { + input->seek(0); + input->setModifiedUTF8StringsMode(); + byNumber.clear(); + byName.clear(); + try { + read(input, name); + } catch (...) { + // Ignore any new exception & throw original IOE finally = e; + } + } else { + finally = e; } } - catch (LuceneException& e) - { - finally = e; - } - input->close(); - finally.throwException(); + } catch (LuceneException& e) { + finally = e; } + input->close(); + finally.throwException(); +} - FieldInfos::~FieldInfos() - { - } +FieldInfos::~FieldInfos() { +} - LuceneObjectPtr FieldInfos::clone(const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - FieldInfosPtr fis(newLucene()); - for (Collection::iterator field = byNumber.begin(); field != byNumber.end(); ++field) - { - FieldInfoPtr fi(boost::dynamic_pointer_cast((*field)->clone())); - fis->byNumber.add(fi); - fis->byName.put(fi->name, fi); - } - return fis; +LuceneObjectPtr FieldInfos::clone(const LuceneObjectPtr& other) { + SyncLock syncLock(this); + FieldInfosPtr fis(newLucene()); + for (Collection::iterator field = byNumber.begin(); field != byNumber.end(); ++field) { + FieldInfoPtr fi(boost::dynamic_pointer_cast((*field)->clone())); + fis->byNumber.add(fi); + fis->byName.put(fi->name, fi); } + return fis; +} - void FieldInfos::add(const DocumentPtr& doc) - { - SyncLock syncLock(this); - Collection fields(doc->getFields()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - add((*field)->name(), (*field)->isIndexed(), (*field)->isTermVectorStored(), - (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), - (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions()); - } +void FieldInfos::add(const DocumentPtr& doc) { + SyncLock syncLock(this); + Collection fields(doc->getFields()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + add((*field)->name(), (*field)->isIndexed(), (*field)->isTermVectorStored(), + (*field)->isStorePositionWithTermVector(), (*field)->isStoreOffsetWithTermVector(), + (*field)->getOmitNorms(), false, (*field)->getOmitTermFreqAndPositions()); } +} - bool FieldInfos::hasProx() - { - for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) - { - if ((*fi)->isIndexed && !(*fi)->omitTermFreqAndPositions) - return true; +bool FieldInfos::hasProx() { + for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) { + if ((*fi)->isIndexed && !(*fi)->omitTermFreqAndPositions) { + return true; } - return false; } + return false; +} - void FieldInfos::addIndexed(HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector) - { - SyncLock syncLock(this); - for (HashSet::iterator name = names.begin(); name != names.end(); ++name) - add(*name, true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector); +void FieldInfos::addIndexed(HashSet names, bool storeTermVectors, bool storePositionWithTermVector, bool storeOffsetWithTermVector) { + SyncLock syncLock(this); + for (HashSet::iterator name = names.begin(); name != names.end(); ++name) { + add(*name, true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector); } +} - void FieldInfos::add(HashSet names, bool isIndexed) - { - SyncLock syncLock(this); - for (HashSet::iterator name = names.begin(); name != names.end(); ++name) - add(*name, isIndexed); +void FieldInfos::add(HashSet names, bool isIndexed) { + SyncLock syncLock(this); + for (HashSet::iterator name = names.begin(); name != names.end(); ++name) { + add(*name, isIndexed); } +} - void FieldInfos::add(const String& name, bool isIndexed) - { - add(name, isIndexed, false, false, false, false); - } +void FieldInfos::add(const String& name, bool isIndexed) { + add(name, isIndexed, false, false, false, false); +} - void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector) - { - add(name, isIndexed, storeTermVector, false, false, false); - } +void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector) { + add(name, isIndexed, storeTermVector, false, false, false); +} - void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector) - { - add(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, false); - } +void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, bool storeOffsetWithTermVector) { + add(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, false); +} - void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms) - { - add(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, false, false); - } +void FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms) { + add(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, false, false); +} - FieldInfoPtr FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) - { - SyncLock syncLock(this); - FieldInfoPtr fi(fieldInfo(name)); - if (!fi) - return addInternal(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); - else - fi->update(isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); - return fi; +FieldInfoPtr FieldInfos::add(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) { + SyncLock syncLock(this); + FieldInfoPtr fi(fieldInfo(name)); + if (!fi) { + return addInternal(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); + } else { + fi->update(isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions); } + return fi; +} - FieldInfoPtr FieldInfos::addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) - { - FieldInfoPtr fi(newLucene(name, isIndexed, byNumber.size(), storeTermVector, - storePositionWithTermVector, storeOffsetWithTermVector, - omitNorms, storePayloads, omitTermFreqAndPositions)); - byNumber.add(fi); - byName.put(name, fi); - return fi; - } +FieldInfoPtr FieldInfos::addInternal(const String& name, bool isIndexed, bool storeTermVector, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool omitNorms, bool storePayloads, bool omitTermFreqAndPositions) { + FieldInfoPtr fi(newLucene(name, isIndexed, byNumber.size(), storeTermVector, + storePositionWithTermVector, storeOffsetWithTermVector, + omitNorms, storePayloads, omitTermFreqAndPositions)); + byNumber.add(fi); + byName.put(name, fi); + return fi; +} - int32_t FieldInfos::fieldNumber(const String& fieldName) - { - FieldInfoPtr fi(fieldInfo(fieldName)); - return fi ? fi->number : -1; - } +int32_t FieldInfos::fieldNumber(const String& fieldName) { + FieldInfoPtr fi(fieldInfo(fieldName)); + return fi ? fi->number : -1; +} - FieldInfoPtr FieldInfos::fieldInfo(const String& fieldName) - { - return byName.get(fieldName); - } +FieldInfoPtr FieldInfos::fieldInfo(const String& fieldName) { + return byName.get(fieldName); +} - String FieldInfos::fieldName(int32_t fieldNumber) - { - FieldInfoPtr fi(fieldInfo(fieldNumber)); - return fi ? fi->name : L""; - } +String FieldInfos::fieldName(int32_t fieldNumber) { + FieldInfoPtr fi(fieldInfo(fieldNumber)); + return fi ? fi->name : L""; +} - FieldInfoPtr FieldInfos::fieldInfo(int32_t fieldNumber) - { - return (fieldNumber >= 0 && fieldNumber < byNumber.size()) ? byNumber[fieldNumber] : FieldInfoPtr(); - } +FieldInfoPtr FieldInfos::fieldInfo(int32_t fieldNumber) { + return (fieldNumber >= 0 && fieldNumber < byNumber.size()) ? byNumber[fieldNumber] : FieldInfoPtr(); +} - int32_t FieldInfos::size() - { - return byNumber.size(); - } +int32_t FieldInfos::size() { + return byNumber.size(); +} - bool FieldInfos::hasVectors() - { - for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) - { - if ((*fi)->storeTermVector) - return true; +bool FieldInfos::hasVectors() { + for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) { + if ((*fi)->storeTermVector) { + return true; } - return false; } + return false; +} - void FieldInfos::write(const DirectoryPtr& d, const String& name) - { - IndexOutputPtr output(d->createOutput(name)); - LuceneException finally; - try - { - write(output); - } - catch (LuceneException& e) - { - finally = e; - } - output->close(); - finally.throwException(); +void FieldInfos::write(const DirectoryPtr& d, const String& name) { + IndexOutputPtr output(d->createOutput(name)); + LuceneException finally; + try { + write(output); + } catch (LuceneException& e) { + finally = e; } + output->close(); + finally.throwException(); +} - void FieldInfos::write(const IndexOutputPtr& output) - { - output->writeVInt(CURRENT_FORMAT); - output->writeVInt(size()); - for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) - { - uint8_t bits = 0x0; - if ((*fi)->isIndexed) - bits |= IS_INDEXED; - if ((*fi)->storeTermVector) - bits |= STORE_TERMVECTOR; - if ((*fi)->storePositionWithTermVector) - bits |= STORE_POSITIONS_WITH_TERMVECTOR; - if ((*fi)->storeOffsetWithTermVector) - bits |= STORE_OFFSET_WITH_TERMVECTOR; - if ((*fi)->omitNorms) - bits |= OMIT_NORMS; - if ((*fi)->storePayloads) - bits |= STORE_PAYLOADS; - if ((*fi)->omitTermFreqAndPositions) - bits |= OMIT_TERM_FREQ_AND_POSITIONS; - - output->writeString((*fi)->name); - output->writeByte(bits); +void FieldInfos::write(const IndexOutputPtr& output) { + output->writeVInt(CURRENT_FORMAT); + output->writeVInt(size()); + for (Collection::iterator fi = byNumber.begin(); fi != byNumber.end(); ++fi) { + uint8_t bits = 0x0; + if ((*fi)->isIndexed) { + bits |= IS_INDEXED; + } + if ((*fi)->storeTermVector) { + bits |= STORE_TERMVECTOR; + } + if ((*fi)->storePositionWithTermVector) { + bits |= STORE_POSITIONS_WITH_TERMVECTOR; + } + if ((*fi)->storeOffsetWithTermVector) { + bits |= STORE_OFFSET_WITH_TERMVECTOR; } + if ((*fi)->omitNorms) { + bits |= OMIT_NORMS; + } + if ((*fi)->storePayloads) { + bits |= STORE_PAYLOADS; + } + if ((*fi)->omitTermFreqAndPositions) { + bits |= OMIT_TERM_FREQ_AND_POSITIONS; + } + + output->writeString((*fi)->name); + output->writeByte(bits); } +} - void FieldInfos::read(const IndexInputPtr& input, const String& fileName) - { - int32_t firstInt = input->readVInt(); - format = firstInt < 0 ? firstInt : FORMAT_PRE; // This is a real format? +void FieldInfos::read(const IndexInputPtr& input, const String& fileName) { + int32_t firstInt = input->readVInt(); + format = firstInt < 0 ? firstInt : FORMAT_PRE; // This is a real format? - if (format != FORMAT_PRE && format != FORMAT_START) - boost::throw_exception(CorruptIndexException(L"unrecognized format " + StringUtils::toString(format) + L" in file \"" + fileName + L"\"")); + if (format != FORMAT_PRE && format != FORMAT_START) { + boost::throw_exception(CorruptIndexException(L"unrecognized format " + StringUtils::toString(format) + L" in file \"" + fileName + L"\"")); + } - int32_t size = format == FORMAT_PRE ? firstInt : input->readVInt(); // read in the size if required - for (int32_t i = 0; i < size; ++i) - { - String name(input->readString()); - uint8_t bits = input->readByte(); + int32_t size = format == FORMAT_PRE ? firstInt : input->readVInt(); // read in the size if required + for (int32_t i = 0; i < size; ++i) { + String name(input->readString()); + uint8_t bits = input->readByte(); - addInternal(name, (bits & IS_INDEXED) != 0, (bits & STORE_TERMVECTOR) != 0, (bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0, - (bits & STORE_OFFSET_WITH_TERMVECTOR) != 0, (bits & OMIT_NORMS) != 0, (bits & STORE_PAYLOADS) != 0, - (bits & OMIT_TERM_FREQ_AND_POSITIONS) != 0); - } + addInternal(name, (bits & IS_INDEXED) != 0, (bits & STORE_TERMVECTOR) != 0, (bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0, + (bits & STORE_OFFSET_WITH_TERMVECTOR) != 0, (bits & OMIT_NORMS) != 0, (bits & STORE_PAYLOADS) != 0, + (bits & OMIT_TERM_FREQ_AND_POSITIONS) != 0); + } - if (input->getFilePointer() != input->length()) - { - boost::throw_exception(CorruptIndexException(L"did not read all bytes from file \"" + fileName + L"\": read " + - StringUtils::toString(input->getFilePointer()) + L" vs size " + - StringUtils::toString(input->length()))); - } + if (input->getFilePointer() != input->length()) { + boost::throw_exception(CorruptIndexException(L"did not read all bytes from file \"" + fileName + L"\": read " + + StringUtils::toString(input->getFilePointer()) + L" vs size " + + StringUtils::toString(input->length()))); } } + +} diff --git a/src/core/index/FieldInvertState.cpp b/src/core/index/FieldInvertState.cpp index c98d67ec..554363ee 100644 --- a/src/core/index/FieldInvertState.cpp +++ b/src/core/index/FieldInvertState.cpp @@ -7,58 +7,50 @@ #include "LuceneInc.h" #include "FieldInvertState.h" -namespace Lucene -{ - FieldInvertState::FieldInvertState(int32_t position, int32_t length, int32_t numOverlap, int32_t offset, double boost) - { - this->position = position; - this->length = length; - this->numOverlap = numOverlap; - this->offset = offset; - this->boost = boost; - } +namespace Lucene { + +FieldInvertState::FieldInvertState(int32_t position, int32_t length, int32_t numOverlap, int32_t offset, double boost) { + this->position = position; + this->length = length; + this->numOverlap = numOverlap; + this->offset = offset; + this->boost = boost; +} - FieldInvertState::~FieldInvertState() - { - } +FieldInvertState::~FieldInvertState() { +} - void FieldInvertState::reset(double docBoost) - { - position = 0; - length = 0; - numOverlap = 0; - offset = 0; - boost = docBoost; - attributeSource.reset(); - } +void FieldInvertState::reset(double docBoost) { + position = 0; + length = 0; + numOverlap = 0; + offset = 0; + boost = docBoost; + attributeSource.reset(); +} + +int32_t FieldInvertState::getPosition() { + return position; +} - int32_t FieldInvertState::getPosition() - { - return position; - } +int32_t FieldInvertState::getLength() { + return length; +} - int32_t FieldInvertState::getLength() - { - return length; - } +int32_t FieldInvertState::getNumOverlap() { + return numOverlap; +} - int32_t FieldInvertState::getNumOverlap() - { - return numOverlap; - } +int32_t FieldInvertState::getOffset() { + return offset; +} - int32_t FieldInvertState::getOffset() - { - return offset; - } +double FieldInvertState::getBoost() { + return boost; +} - double FieldInvertState::getBoost() - { - return boost; - } +AttributeSourcePtr FieldInvertState::getAttributeSource() { + return attributeSource; +} - AttributeSourcePtr FieldInvertState::getAttributeSource() - { - return attributeSource; - } } diff --git a/src/core/index/FieldSortedTermVectorMapper.cpp b/src/core/index/FieldSortedTermVectorMapper.cpp index ab43124d..cf095d9c 100644 --- a/src/core/index/FieldSortedTermVectorMapper.cpp +++ b/src/core/index/FieldSortedTermVectorMapper.cpp @@ -8,47 +8,42 @@ #include "FieldSortedTermVectorMapper.h" #include "TermVectorEntry.h" -namespace Lucene -{ - FieldSortedTermVectorMapper::FieldSortedTermVectorMapper(TermVectorEntryComparator comparator) - : TermVectorMapper(false, false) - { - this->fieldToTerms = MapStringCollectionTermVectorEntry::newInstance(); - this->comparator = comparator; - } +namespace Lucene { - FieldSortedTermVectorMapper::FieldSortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator) - : TermVectorMapper(ignoringPositions, ignoringOffsets) - { - this->fieldToTerms = MapStringCollectionTermVectorEntry::newInstance(); - this->comparator = comparator; - } +FieldSortedTermVectorMapper::FieldSortedTermVectorMapper(TermVectorEntryComparator comparator) + : TermVectorMapper(false, false) { + this->fieldToTerms = MapStringCollectionTermVectorEntry::newInstance(); + this->comparator = comparator; +} - FieldSortedTermVectorMapper::~FieldSortedTermVectorMapper() - { - } +FieldSortedTermVectorMapper::FieldSortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator) + : TermVectorMapper(ignoringPositions, ignoringOffsets) { + this->fieldToTerms = MapStringCollectionTermVectorEntry::newInstance(); + this->comparator = comparator; +} - void FieldSortedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) - { - TermVectorEntryPtr entry(newLucene(currentField, term, frequency, offsets, positions)); - if (!currentSet.contains_if(luceneEqualTo(entry))) - currentSet.insert(std::upper_bound(currentSet.begin(), currentSet.end(), entry, comparator), entry); - } +FieldSortedTermVectorMapper::~FieldSortedTermVectorMapper() { +} - void FieldSortedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) - { - currentSet = Collection::newInstance(); - currentField = field; - fieldToTerms.put(field, currentSet); +void FieldSortedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { + TermVectorEntryPtr entry(newLucene(currentField, term, frequency, offsets, positions)); + if (!currentSet.contains_if(luceneEqualTo(entry))) { + currentSet.insert(std::upper_bound(currentSet.begin(), currentSet.end(), entry, comparator), entry); } +} - MapStringCollectionTermVectorEntry FieldSortedTermVectorMapper::getFieldToTerms() - { - return fieldToTerms; - } +void FieldSortedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { + currentSet = Collection::newInstance(); + currentField = field; + fieldToTerms.put(field, currentSet); +} + +MapStringCollectionTermVectorEntry FieldSortedTermVectorMapper::getFieldToTerms() { + return fieldToTerms; +} + +TermVectorEntryComparator FieldSortedTermVectorMapper::getComparator() { + return comparator; +} - TermVectorEntryComparator FieldSortedTermVectorMapper::getComparator() - { - return comparator; - } } diff --git a/src/core/index/FieldsReader.cpp b/src/core/index/FieldsReader.cpp index b5ec7b26..0f0653d7 100644 --- a/src/core/index/FieldsReader.cpp +++ b/src/core/index/FieldsReader.cpp @@ -20,530 +20,462 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - FieldsReader::FieldsReader(const FieldInfosPtr& fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, - int32_t formatSize, int32_t docStoreOffset, const IndexInputPtr& cloneableFieldsStream, - const IndexInputPtr& cloneableIndexStream) - { - closed = false; - isOriginal = false; - this->fieldInfos = fieldInfos; - this->numTotalDocs = numTotalDocs; - this->_size = size; - this->format = format; - this->formatSize = formatSize; - this->docStoreOffset = docStoreOffset; - this->cloneableFieldsStream = cloneableFieldsStream; - this->cloneableIndexStream = cloneableIndexStream; - fieldsStream = boost::dynamic_pointer_cast(cloneableFieldsStream->clone()); - indexStream = boost::dynamic_pointer_cast(cloneableIndexStream->clone()); - } - - FieldsReader::FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn) - { - ConstructReader(d, segment, fn, BufferedIndexInput::BUFFER_SIZE, -1, 0); - } +namespace Lucene { + +FieldsReader::FieldsReader(const FieldInfosPtr& fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, + int32_t formatSize, int32_t docStoreOffset, const IndexInputPtr& cloneableFieldsStream, + const IndexInputPtr& cloneableIndexStream) { + closed = false; + isOriginal = false; + this->fieldInfos = fieldInfos; + this->numTotalDocs = numTotalDocs; + this->_size = size; + this->format = format; + this->formatSize = formatSize; + this->docStoreOffset = docStoreOffset; + this->cloneableFieldsStream = cloneableFieldsStream; + this->cloneableIndexStream = cloneableIndexStream; + fieldsStream = boost::dynamic_pointer_cast(cloneableFieldsStream->clone()); + indexStream = boost::dynamic_pointer_cast(cloneableIndexStream->clone()); +} - FieldsReader::FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) - { - ConstructReader(d, segment, fn, readBufferSize, docStoreOffset, size); - } +FieldsReader::FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn) { + ConstructReader(d, segment, fn, BufferedIndexInput::BUFFER_SIZE, -1, 0); +} - FieldsReader::~FieldsReader() - { - } +FieldsReader::FieldsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { + ConstructReader(d, segment, fn, readBufferSize, docStoreOffset, size); +} - void FieldsReader::ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) - { - bool success = false; - isOriginal = true; - numTotalDocs = 0; - _size = 0; - closed = false; - format = 0; - formatSize = 0; - docStoreOffset = docStoreOffset; - LuceneException finally; - try - { - fieldInfos = fn; - - cloneableFieldsStream = d->openInput(segment + L"." + IndexFileNames::FIELDS_EXTENSION(), readBufferSize); - cloneableIndexStream = d->openInput(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION(), readBufferSize); - - // First version of fdx did not include a format header, but, the first int will always be 0 in that case - format = cloneableIndexStream->readInt(); - - if (format > FieldsWriter::FORMAT_CURRENT) - { - boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + StringUtils::toString(format) + - L" expected " + StringUtils::toString(FieldsWriter::FORMAT_CURRENT) + - L" or lower")); - } +FieldsReader::~FieldsReader() { +} - formatSize = format > FieldsWriter::FORMAT ? 4 : 0; +void FieldsReader::ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { + bool success = false; + isOriginal = true; + numTotalDocs = 0; + _size = 0; + closed = false; + format = 0; + formatSize = 0; + docStoreOffset = docStoreOffset; + LuceneException finally; + try { + fieldInfos = fn; + + cloneableFieldsStream = d->openInput(segment + L"." + IndexFileNames::FIELDS_EXTENSION(), readBufferSize); + cloneableIndexStream = d->openInput(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION(), readBufferSize); + + // First version of fdx did not include a format header, but, the first int will always be 0 in that case + format = cloneableIndexStream->readInt(); + + if (format > FieldsWriter::FORMAT_CURRENT) { + boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + StringUtils::toString(format) + + L" expected " + StringUtils::toString(FieldsWriter::FORMAT_CURRENT) + + L" or lower")); + } - if (format < FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) - cloneableFieldsStream->setModifiedUTF8StringsMode(); + formatSize = format > FieldsWriter::FORMAT ? 4 : 0; - fieldsStream = boost::dynamic_pointer_cast(cloneableFieldsStream->clone()); + if (format < FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) { + cloneableFieldsStream->setModifiedUTF8StringsMode(); + } - int64_t indexSize = cloneableIndexStream->length() - formatSize; + fieldsStream = boost::dynamic_pointer_cast(cloneableFieldsStream->clone()); - if (docStoreOffset != -1) - { - // We read only a slice out of this shared fields file - this->docStoreOffset = docStoreOffset; - this->_size = size; + int64_t indexSize = cloneableIndexStream->length() - formatSize; - // Verify the file is long enough to hold all of our docs - BOOST_ASSERT(((int32_t)((double)indexSize / 8.0)) >= _size + this->docStoreOffset); - } - else - { - this->docStoreOffset = 0; - this->_size = (int32_t)(indexSize >> 3); - } + if (docStoreOffset != -1) { + // We read only a slice out of this shared fields file + this->docStoreOffset = docStoreOffset; + this->_size = size; - indexStream = boost::dynamic_pointer_cast(cloneableIndexStream->clone()); - numTotalDocs = (int32_t)(indexSize >> 3); - success = true; - } - catch (LuceneException& e) - { - finally = e; + // Verify the file is long enough to hold all of our docs + BOOST_ASSERT(((int32_t)((double)indexSize / 8.0)) >= _size + this->docStoreOffset); + } else { + this->docStoreOffset = 0; + this->_size = (int32_t)(indexSize >> 3); } - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. - // In this case, we want to explicitly close any subset of things that were opened - if (!success) - close(); - finally.throwException(); - } - LuceneObjectPtr FieldsReader::clone(const LuceneObjectPtr& other) - { - ensureOpen(); - return newLucene(fieldInfos, numTotalDocs, _size, format, formatSize, docStoreOffset, cloneableFieldsStream, cloneableIndexStream); + indexStream = boost::dynamic_pointer_cast(cloneableIndexStream->clone()); + numTotalDocs = (int32_t)(indexSize >> 3); + success = true; + } catch (LuceneException& e) { + finally = e; + } + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. + // In this case, we want to explicitly close any subset of things that were opened + if (!success) { + close(); } + finally.throwException(); +} + +LuceneObjectPtr FieldsReader::clone(const LuceneObjectPtr& other) { + ensureOpen(); + return newLucene(fieldInfos, numTotalDocs, _size, format, formatSize, docStoreOffset, cloneableFieldsStream, cloneableIndexStream); +} - void FieldsReader::ensureOpen() - { - if (closed) - boost::throw_exception(AlreadyClosedException(L"this FieldsReader is closed")); +void FieldsReader::ensureOpen() { + if (closed) { + boost::throw_exception(AlreadyClosedException(L"this FieldsReader is closed")); } +} - void FieldsReader::close() - { - if (!closed) - { - if (fieldsStream) - fieldsStream->close(); - if (isOriginal) - { - if (cloneableFieldsStream) - cloneableFieldsStream->close(); - if (cloneableIndexStream) - cloneableIndexStream->close(); +void FieldsReader::close() { + if (!closed) { + if (fieldsStream) { + fieldsStream->close(); + } + if (isOriginal) { + if (cloneableFieldsStream) { + cloneableFieldsStream->close(); + } + if (cloneableIndexStream) { + cloneableIndexStream->close(); } - if (indexStream) - indexStream->close(); - fieldsStreamTL.close(); - closed = true; } + if (indexStream) { + indexStream->close(); + } + fieldsStreamTL.close(); + closed = true; } +} - int32_t FieldsReader::size() - { - return _size; - } +int32_t FieldsReader::size() { + return _size; +} - void FieldsReader::seekIndex(int32_t docID) - { - indexStream->seek(formatSize + (docID + docStoreOffset) * 8); - } +void FieldsReader::seekIndex(int32_t docID) { + indexStream->seek(formatSize + (docID + docStoreOffset) * 8); +} - bool FieldsReader::canReadRawDocs() - { - // Disable reading raw docs in 2.x format, because of the removal of compressed fields in 3.0. - // We don't want rawDocs() to decode field bits to figure out if a field was compressed, hence - // we enforce ordinary (non-raw) stored field merges for <3.0 indexes. - return (format >= FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS); - } +bool FieldsReader::canReadRawDocs() { + // Disable reading raw docs in 2.x format, because of the removal of compressed fields in 3.0. + // We don't want rawDocs() to decode field bits to figure out if a field was compressed, hence + // we enforce ordinary (non-raw) stored field merges for <3.0 indexes. + return (format >= FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS); +} - DocumentPtr FieldsReader::doc(int32_t n, const FieldSelectorPtr& fieldSelector) - { - seekIndex(n); - int64_t position = indexStream->readLong(); - fieldsStream->seek(position); - - DocumentPtr doc(newLucene()); - int32_t numFields = fieldsStream->readVInt(); - for (int32_t i = 0; i < numFields; ++i) - { - int32_t fieldNumber = fieldsStream->readVInt(); - FieldInfoPtr fi = fieldInfos->fieldInfo(fieldNumber); - FieldSelector::FieldSelectorResult acceptField = fieldSelector ? fieldSelector->accept(fi->name) : FieldSelector::SELECTOR_LOAD; - - uint8_t bits = fieldsStream->readByte(); - BOOST_ASSERT(bits <= FieldsWriter::FIELD_IS_COMPRESSED + FieldsWriter::FIELD_IS_TOKENIZED + FieldsWriter::FIELD_IS_BINARY); - - bool compressed = ((bits & FieldsWriter::FIELD_IS_COMPRESSED) != 0); - - // compressed fields are only allowed in indexes of version <= 2.9 - BOOST_ASSERT(compressed ? (format < FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS) : true); - - bool tokenize = ((bits & FieldsWriter::FIELD_IS_TOKENIZED) != 0); - bool binary = ((bits & FieldsWriter::FIELD_IS_BINARY) != 0); - - if (acceptField == FieldSelector::SELECTOR_LOAD) - addField(doc, fi, binary, compressed, tokenize); - else if (acceptField == FieldSelector::SELECTOR_LOAD_AND_BREAK) - { - addField(doc, fi, binary, compressed, tokenize); - break; // Get out of this loop - } - else if (acceptField == FieldSelector::SELECTOR_LAZY_LOAD) - addFieldLazy(doc, fi, binary, compressed, tokenize); - else if (acceptField == FieldSelector::SELECTOR_SIZE) - skipField(binary, compressed, addFieldSize(doc, fi, binary, compressed)); - else if (acceptField == FieldSelector::SELECTOR_SIZE_AND_BREAK) - { - addFieldSize(doc, fi, binary, compressed); - break; - } - else - skipField(binary, compressed); +DocumentPtr FieldsReader::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { + seekIndex(n); + int64_t position = indexStream->readLong(); + fieldsStream->seek(position); + + DocumentPtr doc(newLucene()); + int32_t numFields = fieldsStream->readVInt(); + for (int32_t i = 0; i < numFields; ++i) { + int32_t fieldNumber = fieldsStream->readVInt(); + FieldInfoPtr fi = fieldInfos->fieldInfo(fieldNumber); + FieldSelector::FieldSelectorResult acceptField = fieldSelector ? fieldSelector->accept(fi->name) : FieldSelector::SELECTOR_LOAD; + + uint8_t bits = fieldsStream->readByte(); + BOOST_ASSERT(bits <= FieldsWriter::FIELD_IS_COMPRESSED + FieldsWriter::FIELD_IS_TOKENIZED + FieldsWriter::FIELD_IS_BINARY); + + bool compressed = ((bits & FieldsWriter::FIELD_IS_COMPRESSED) != 0); + + // compressed fields are only allowed in indexes of version <= 2.9 + BOOST_ASSERT(compressed ? (format < FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS) : true); + + bool tokenize = ((bits & FieldsWriter::FIELD_IS_TOKENIZED) != 0); + bool binary = ((bits & FieldsWriter::FIELD_IS_BINARY) != 0); + + if (acceptField == FieldSelector::SELECTOR_LOAD) { + addField(doc, fi, binary, compressed, tokenize); + } else if (acceptField == FieldSelector::SELECTOR_LOAD_AND_BREAK) { + addField(doc, fi, binary, compressed, tokenize); + break; // Get out of this loop + } else if (acceptField == FieldSelector::SELECTOR_LAZY_LOAD) { + addFieldLazy(doc, fi, binary, compressed, tokenize); + } else if (acceptField == FieldSelector::SELECTOR_SIZE) { + skipField(binary, compressed, addFieldSize(doc, fi, binary, compressed)); + } else if (acceptField == FieldSelector::SELECTOR_SIZE_AND_BREAK) { + addFieldSize(doc, fi, binary, compressed); + break; + } else { + skipField(binary, compressed); } - - return doc; } - IndexInputPtr FieldsReader::rawDocs(Collection lengths, int32_t startDocID, int32_t numDocs) - { - seekIndex(startDocID); - int64_t startOffset = indexStream->readLong(); - int64_t lastOffset = startOffset; - int32_t count = 0; - while (count < numDocs) - { - int32_t docID = docStoreOffset + startDocID + count + 1; - BOOST_ASSERT(docID <= numTotalDocs); - int64_t offset = docID < numTotalDocs ? indexStream->readLong() : fieldsStream->length(); - lengths[count++] = (int32_t)(offset - lastOffset); - lastOffset = offset; - } - - fieldsStream->seek(startOffset); + return doc; +} - return fieldsStream; +IndexInputPtr FieldsReader::rawDocs(Collection lengths, int32_t startDocID, int32_t numDocs) { + seekIndex(startDocID); + int64_t startOffset = indexStream->readLong(); + int64_t lastOffset = startOffset; + int32_t count = 0; + while (count < numDocs) { + int32_t docID = docStoreOffset + startDocID + count + 1; + BOOST_ASSERT(docID <= numTotalDocs); + int64_t offset = docID < numTotalDocs ? indexStream->readLong() : fieldsStream->length(); + lengths[count++] = (int32_t)(offset - lastOffset); + lastOffset = offset; } - void FieldsReader::skipField(bool binary, bool compressed) - { - skipField(binary, compressed, fieldsStream->readVInt()); - } + fieldsStream->seek(startOffset); - void FieldsReader::skipField(bool binary, bool compressed, int32_t toRead) - { - if (format >= FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES || binary || compressed) - fieldsStream->seek(fieldsStream->getFilePointer() + toRead); - else - { - // We need to skip chars. This will slow us down, but still better - fieldsStream->skipChars(toRead); - } + return fieldsStream; +} + +void FieldsReader::skipField(bool binary, bool compressed) { + skipField(binary, compressed, fieldsStream->readVInt()); +} + +void FieldsReader::skipField(bool binary, bool compressed, int32_t toRead) { + if (format >= FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES || binary || compressed) { + fieldsStream->seek(fieldsStream->getFilePointer() + toRead); + } else { + // We need to skip chars. This will slow us down, but still better + fieldsStream->skipChars(toRead); } +} - void FieldsReader::addFieldLazy(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize) - { - if (binary) - { +void FieldsReader::addFieldLazy(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize) { + if (binary) { + int32_t toRead = fieldsStream->readVInt(); + int64_t pointer = fieldsStream->getFilePointer(); + doc->add(newLucene(shared_from_this(), fi->name, Field::STORE_YES, toRead, pointer, binary, compressed)); + fieldsStream->seek(pointer + toRead); + } else { + Field::Store store = Field::STORE_YES; + Field::Index index = Field::toIndex(fi->isIndexed, tokenize); + Field::TermVector termVector = Field::toTermVector(fi->storeTermVector, fi->storeOffsetWithTermVector, fi->storePositionWithTermVector); + + AbstractFieldPtr f; + if (compressed) { int32_t toRead = fieldsStream->readVInt(); int64_t pointer = fieldsStream->getFilePointer(); - doc->add(newLucene(shared_from_this(), fi->name, Field::STORE_YES, toRead, pointer, binary, compressed)); + f = newLucene(shared_from_this(), fi->name, store, toRead, pointer, binary, compressed); + // skip over the part that we aren't loading fieldsStream->seek(pointer + toRead); - } - else - { - Field::Store store = Field::STORE_YES; - Field::Index index = Field::toIndex(fi->isIndexed, tokenize); - Field::TermVector termVector = Field::toTermVector(fi->storeTermVector, fi->storeOffsetWithTermVector, fi->storePositionWithTermVector); - - AbstractFieldPtr f; - if (compressed) - { - int32_t toRead = fieldsStream->readVInt(); - int64_t pointer = fieldsStream->getFilePointer(); - f = newLucene(shared_from_this(), fi->name, store, toRead, pointer, binary, compressed); - // skip over the part that we aren't loading - fieldsStream->seek(pointer + toRead); - f->setOmitNorms(fi->omitNorms); - f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); - } - else - { - int32_t length = fieldsStream->readVInt(); - int64_t pointer = fieldsStream->getFilePointer(); - // skip ahead of where we are by the length of what is stored - if (format >= FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) - fieldsStream->seek(pointer + length); - else - fieldsStream->skipChars(length); - f = newLucene(shared_from_this(), fi->name, store, index, termVector, length, pointer, binary, compressed); - f->setOmitNorms(fi->omitNorms); - f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); + f->setOmitNorms(fi->omitNorms); + f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); + } else { + int32_t length = fieldsStream->readVInt(); + int64_t pointer = fieldsStream->getFilePointer(); + // skip ahead of where we are by the length of what is stored + if (format >= FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) { + fieldsStream->seek(pointer + length); + } else { + fieldsStream->skipChars(length); } - - doc->add(f); + f = newLucene(shared_from_this(), fi->name, store, index, termVector, length, pointer, binary, compressed); + f->setOmitNorms(fi->omitNorms); + f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); } + + doc->add(f); } +} - void FieldsReader::addField(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize) - { - // we have a binary stored field, and it may be compressed - if (binary) - { +void FieldsReader::addField(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed, bool tokenize) { + // we have a binary stored field, and it may be compressed + if (binary) { + int32_t toRead = fieldsStream->readVInt(); + ByteArray b(ByteArray::newInstance(toRead)); + fieldsStream->readBytes(b.get(), 0, b.size()); + if (compressed) { + doc->add(newLucene(fi->name, uncompress(b), Field::STORE_YES)); + } else { + doc->add(newLucene(fi->name, b, Field::STORE_YES)); + } + } else { + Field::Store store = Field::STORE_YES; + Field::Index index = Field::toIndex(fi->isIndexed, tokenize); + Field::TermVector termVector = Field::toTermVector(fi->storeTermVector, fi->storeOffsetWithTermVector, fi->storePositionWithTermVector); + + AbstractFieldPtr f; + if (compressed) { int32_t toRead = fieldsStream->readVInt(); + ByteArray b(ByteArray::newInstance(toRead)); fieldsStream->readBytes(b.get(), 0, b.size()); - if (compressed) - doc->add(newLucene(fi->name, uncompress(b), Field::STORE_YES)); - else - doc->add(newLucene(fi->name, b, Field::STORE_YES)); + f = newLucene(fi->name, uncompressString(b), store, index, termVector); + f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); + f->setOmitNorms(fi->omitNorms); + } else { + f = newLucene(fi->name, fieldsStream->readString(), store, index, termVector); + f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); + f->setOmitNorms(fi->omitNorms); } - else - { - Field::Store store = Field::STORE_YES; - Field::Index index = Field::toIndex(fi->isIndexed, tokenize); - Field::TermVector termVector = Field::toTermVector(fi->storeTermVector, fi->storeOffsetWithTermVector, fi->storePositionWithTermVector); - - AbstractFieldPtr f; - if (compressed) - { - int32_t toRead = fieldsStream->readVInt(); - - ByteArray b(ByteArray::newInstance(toRead)); - fieldsStream->readBytes(b.get(), 0, b.size()); - f = newLucene(fi->name, uncompressString(b), store, index, termVector); - f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); - f->setOmitNorms(fi->omitNorms); - } - else - { - f = newLucene(fi->name, fieldsStream->readString(), store, index, termVector); - f->setOmitTermFreqAndPositions(fi->omitTermFreqAndPositions); - f->setOmitNorms(fi->omitNorms); - } - doc->add(f); - } + doc->add(f); } +} - int32_t FieldsReader::addFieldSize(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed) - { - int32_t size = fieldsStream->readVInt(); - int32_t bytesize = (binary || compressed) ? size : 2 * size; - ByteArray sizebytes(ByteArray::newInstance(4)); - sizebytes[0] = (uint8_t)MiscUtils::unsignedShift(bytesize, 24); - sizebytes[1] = (uint8_t)MiscUtils::unsignedShift(bytesize, 16); - sizebytes[2] = (uint8_t)MiscUtils::unsignedShift(bytesize, 8); - sizebytes[3] = (uint8_t)(bytesize); - doc->add(newLucene(fi->name, sizebytes, Field::STORE_YES)); - return size; - } +int32_t FieldsReader::addFieldSize(const DocumentPtr& doc, const FieldInfoPtr& fi, bool binary, bool compressed) { + int32_t size = fieldsStream->readVInt(); + int32_t bytesize = (binary || compressed) ? size : 2 * size; + ByteArray sizebytes(ByteArray::newInstance(4)); + sizebytes[0] = (uint8_t)MiscUtils::unsignedShift(bytesize, 24); + sizebytes[1] = (uint8_t)MiscUtils::unsignedShift(bytesize, 16); + sizebytes[2] = (uint8_t)MiscUtils::unsignedShift(bytesize, 8); + sizebytes[3] = (uint8_t)(bytesize); + doc->add(newLucene(fi->name, sizebytes, Field::STORE_YES)); + return size; +} - ByteArray FieldsReader::uncompress(ByteArray b) - { - try - { - return CompressionTools::decompress(b); - } - catch (LuceneException& e) - { - boost::throw_exception(CorruptIndexException(L"field data are in wrong format [" + e.getError() + L"]")); - } - return ByteArray(); +ByteArray FieldsReader::uncompress(ByteArray b) { + try { + return CompressionTools::decompress(b); + } catch (LuceneException& e) { + boost::throw_exception(CorruptIndexException(L"field data are in wrong format [" + e.getError() + L"]")); } + return ByteArray(); +} - String FieldsReader::uncompressString(ByteArray b) - { - try - { - return CompressionTools::decompressString(b); - } - catch (LuceneException& e) - { - boost::throw_exception(CorruptIndexException(L"field data are in wrong format [" + e.getError() + L"]")); - } - return L""; +String FieldsReader::uncompressString(ByteArray b) { + try { + return CompressionTools::decompressString(b); + } catch (LuceneException& e) { + boost::throw_exception(CorruptIndexException(L"field data are in wrong format [" + e.getError() + L"]")); } + return L""; +} - LazyField::LazyField(const FieldsReaderPtr& reader, const String& name, Field::Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : - AbstractField(name, store, Field::INDEX_NO, Field::TERM_VECTOR_NO) - { - this->_reader = reader; - this->toRead = toRead; - this->pointer = pointer; - this->_isBinary = isBinary; - if (isBinary) - binaryLength = toRead; - lazy = true; - this->isCompressed = isCompressed; - } +LazyField::LazyField(const FieldsReaderPtr& reader, const String& name, Field::Store store, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : + AbstractField(name, store, Field::INDEX_NO, Field::TERM_VECTOR_NO) { + this->_reader = reader; + this->toRead = toRead; + this->pointer = pointer; + this->_isBinary = isBinary; + if (isBinary) { + binaryLength = toRead; + } + lazy = true; + this->isCompressed = isCompressed; +} - LazyField::LazyField(const FieldsReaderPtr& reader, const String& name, Field::Store store, Field::Index index, Field::TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : - AbstractField(name, store, index, termVector) - { - this->_reader = reader; - this->toRead = toRead; - this->pointer = pointer; - this->_isBinary = isBinary; - if (isBinary) - binaryLength = toRead; - lazy = true; - this->isCompressed = isCompressed; - } +LazyField::LazyField(const FieldsReaderPtr& reader, const String& name, Field::Store store, Field::Index index, Field::TermVector termVector, int32_t toRead, int64_t pointer, bool isBinary, bool isCompressed) : + AbstractField(name, store, index, termVector) { + this->_reader = reader; + this->toRead = toRead; + this->pointer = pointer; + this->_isBinary = isBinary; + if (isBinary) { + binaryLength = toRead; + } + lazy = true; + this->isCompressed = isCompressed; +} - LazyField::~LazyField() - { - } +LazyField::~LazyField() { +} - IndexInputPtr LazyField::getFieldStream() - { - FieldsReaderPtr reader(_reader); - IndexInputPtr localFieldsStream = reader->fieldsStreamTL.get(); - if (!localFieldsStream) - { - localFieldsStream = boost::static_pointer_cast(reader->cloneableFieldsStream->clone()); - reader->fieldsStreamTL.set(localFieldsStream); - } - return localFieldsStream; +IndexInputPtr LazyField::getFieldStream() { + FieldsReaderPtr reader(_reader); + IndexInputPtr localFieldsStream = reader->fieldsStreamTL.get(); + if (!localFieldsStream) { + localFieldsStream = boost::static_pointer_cast(reader->cloneableFieldsStream->clone()); + reader->fieldsStreamTL.set(localFieldsStream); } + return localFieldsStream; +} - ReaderPtr LazyField::readerValue() - { - FieldsReaderPtr(_reader)->ensureOpen(); - return ReaderPtr(); - } +ReaderPtr LazyField::readerValue() { + FieldsReaderPtr(_reader)->ensureOpen(); + return ReaderPtr(); +} - TokenStreamPtr LazyField::tokenStreamValue() - { - FieldsReaderPtr(_reader)->ensureOpen(); - return TokenStreamPtr(); - } +TokenStreamPtr LazyField::tokenStreamValue() { + FieldsReaderPtr(_reader)->ensureOpen(); + return TokenStreamPtr(); +} - String LazyField::stringValue() - { - FieldsReaderPtr reader(_reader); - reader->ensureOpen(); - if (_isBinary) - return L""; - else - { - if (VariantUtils::isNull(fieldsData)) - { - IndexInputPtr localFieldsStream(getFieldStream()); - try - { - localFieldsStream->seek(pointer); - if (isCompressed) - { - ByteArray b(ByteArray::newInstance(toRead)); - localFieldsStream->readBytes(b.get(), 0, b.size()); - fieldsData = reader->uncompressString(b); - } - else - { - if (reader->format >= FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) - { - ByteArray bytes(ByteArray::newInstance(toRead)); - localFieldsStream->readBytes(bytes.get(), 0, toRead); - fieldsData = StringUtils::toUnicode(bytes.get(), toRead); - } - else - { - // read in chars because we already know the length we need to read - CharArray chars(CharArray::newInstance(toRead)); - int32_t length = localFieldsStream->readChars(chars.get(), 0, toRead); - fieldsData = String(chars.get(), length); - } +String LazyField::stringValue() { + FieldsReaderPtr reader(_reader); + reader->ensureOpen(); + if (_isBinary) { + return L""; + } else { + if (VariantUtils::isNull(fieldsData)) { + IndexInputPtr localFieldsStream(getFieldStream()); + try { + localFieldsStream->seek(pointer); + if (isCompressed) { + ByteArray b(ByteArray::newInstance(toRead)); + localFieldsStream->readBytes(b.get(), 0, b.size()); + fieldsData = reader->uncompressString(b); + } else { + if (reader->format >= FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) { + ByteArray bytes(ByteArray::newInstance(toRead)); + localFieldsStream->readBytes(bytes.get(), 0, toRead); + fieldsData = StringUtils::toUnicode(bytes.get(), toRead); + } else { + // read in chars because we already know the length we need to read + CharArray chars(CharArray::newInstance(toRead)); + int32_t length = localFieldsStream->readChars(chars.get(), 0, toRead); + fieldsData = String(chars.get(), length); } } - catch (IOException& e) - { - boost::throw_exception(FieldReaderException(e.getError())); - } + } catch (IOException& e) { + boost::throw_exception(FieldReaderException(e.getError())); } - return VariantUtils::get(fieldsData); } + return VariantUtils::get(fieldsData); } +} - int64_t LazyField::getPointer() - { - FieldsReaderPtr(_reader)->ensureOpen(); - return pointer; - } +int64_t LazyField::getPointer() { + FieldsReaderPtr(_reader)->ensureOpen(); + return pointer; +} - void LazyField::setPointer(int64_t pointer) - { - FieldsReaderPtr(_reader)->ensureOpen(); - this->pointer = pointer; - } +void LazyField::setPointer(int64_t pointer) { + FieldsReaderPtr(_reader)->ensureOpen(); + this->pointer = pointer; +} - int32_t LazyField::getToRead() - { - FieldsReaderPtr(_reader)->ensureOpen(); - return toRead; - } +int32_t LazyField::getToRead() { + FieldsReaderPtr(_reader)->ensureOpen(); + return toRead; +} - void LazyField::setToRead(int32_t toRead) - { - FieldsReaderPtr(_reader)->ensureOpen(); - this->toRead = toRead; - } +void LazyField::setToRead(int32_t toRead) { + FieldsReaderPtr(_reader)->ensureOpen(); + this->toRead = toRead; +} - ByteArray LazyField::getBinaryValue(ByteArray result) - { - FieldsReaderPtr reader(_reader); - reader->ensureOpen(); - - if (_isBinary) - { - if (VariantUtils::isNull(fieldsData)) - { - ByteArray b; - - // Allocate new buffer if result is null or too small - if (!result || result.size() < toRead) - b = ByteArray::newInstance(toRead); - else - b = result; - - IndexInputPtr localFieldsStream(getFieldStream()); - - // Throw this IOException since IndexReader.document does so anyway, so probably not that big of a - // change for people since they are already handling this exception when getting the document. - try - { - localFieldsStream->seek(pointer); - localFieldsStream->readBytes(b.get(), 0, toRead); - if (isCompressed) - fieldsData = reader->uncompress(b); - else - fieldsData = b; - } - catch (IOException& e) - { - boost::throw_exception(FieldReaderException(e.getError())); - } +ByteArray LazyField::getBinaryValue(ByteArray result) { + FieldsReaderPtr reader(_reader); + reader->ensureOpen(); - binaryOffset = 0; - binaryLength = toRead; + if (_isBinary) { + if (VariantUtils::isNull(fieldsData)) { + ByteArray b; + + // Allocate new buffer if result is null or too small + if (!result || result.size() < toRead) { + b = ByteArray::newInstance(toRead); + } else { + b = result; } - return VariantUtils::get(fieldsData); + + IndexInputPtr localFieldsStream(getFieldStream()); + + // Throw this IOException since IndexReader.document does so anyway, so probably not that big of a + // change for people since they are already handling this exception when getting the document. + try { + localFieldsStream->seek(pointer); + localFieldsStream->readBytes(b.get(), 0, toRead); + if (isCompressed) { + fieldsData = reader->uncompress(b); + } else { + fieldsData = b; + } + } catch (IOException& e) { + boost::throw_exception(FieldReaderException(e.getError())); + } + + binaryOffset = 0; + binaryLength = toRead; } - else - return ByteArray(); + return VariantUtils::get(fieldsData); + } else { + return ByteArray(); } } + +} diff --git a/src/core/index/FieldsWriter.cpp b/src/core/index/FieldsWriter.cpp index cb53dcae..85c651d7 100644 --- a/src/core/index/FieldsWriter.cpp +++ b/src/core/index/FieldsWriter.cpp @@ -16,206 +16,174 @@ #include "Document.h" #include "TestPoint.h" -namespace Lucene -{ - const uint8_t FieldsWriter::FIELD_IS_TOKENIZED = 0x1; - const uint8_t FieldsWriter::FIELD_IS_BINARY = 0x2; - const uint8_t FieldsWriter::FIELD_IS_COMPRESSED = 0x4; - - const int32_t FieldsWriter::FORMAT = 0; // Original format - const int32_t FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES = 1; // Changed strings to UTF8 - const int32_t FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS = 2; // Lucene 3.0: Removal of compressed fields - - // NOTE: if you introduce a new format, make it 1 higher than the current one, and always change this if you - // switch to a new format! - const int32_t FieldsWriter::FORMAT_CURRENT = FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS; - - FieldsWriter::FieldsWriter(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn) - { - fieldInfos = fn; - - bool success = false; - String fieldsName(segment + L"." + IndexFileNames::FIELDS_EXTENSION()); - LuceneException finally; - try - { - fieldsStream = d->createOutput(fieldsName); - fieldsStream->writeInt(FORMAT_CURRENT); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - { - try - { - close(); - d->deleteFile(fieldsName); - } - catch (...) - { - // Suppress so we keep throwing the original exception - } - } - finally.throwException(); - - success = false; - String indexName(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - try - { - indexStream = d->createOutput(indexName); - indexStream->writeInt(FORMAT_CURRENT); - success = true; - } - catch (LuceneException& e) - { - finally = e; +namespace Lucene { + +const uint8_t FieldsWriter::FIELD_IS_TOKENIZED = 0x1; +const uint8_t FieldsWriter::FIELD_IS_BINARY = 0x2; +const uint8_t FieldsWriter::FIELD_IS_COMPRESSED = 0x4; + +const int32_t FieldsWriter::FORMAT = 0; // Original format +const int32_t FieldsWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES = 1; // Changed strings to UTF8 +const int32_t FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS = 2; // Lucene 3.0: Removal of compressed fields + +// NOTE: if you introduce a new format, make it 1 higher than the current one, and always change this if you +// switch to a new format! +const int32_t FieldsWriter::FORMAT_CURRENT = FieldsWriter::FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS; + +FieldsWriter::FieldsWriter(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fn) { + fieldInfos = fn; + + bool success = false; + String fieldsName(segment + L"." + IndexFileNames::FIELDS_EXTENSION()); + LuceneException finally; + try { + fieldsStream = d->createOutput(fieldsName); + fieldsStream->writeInt(FORMAT_CURRENT); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + try { + close(); + d->deleteFile(fieldsName); + } catch (...) { + // Suppress so we keep throwing the original exception } - if (!success) - { - try - { - close(); - d->deleteFile(fieldsName); - d->deleteFile(indexName); - } - catch (...) - { - // Suppress so we keep throwing the original exception - } + } + finally.throwException(); + + success = false; + String indexName(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); + try { + indexStream = d->createOutput(indexName); + indexStream->writeInt(FORMAT_CURRENT); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + try { + close(); + d->deleteFile(fieldsName); + d->deleteFile(indexName); + } catch (...) { + // Suppress so we keep throwing the original exception } - finally.throwException(); - - doClose = true; } + finally.throwException(); - FieldsWriter::FieldsWriter(const IndexOutputPtr& fdx, const IndexOutputPtr& fdt, const FieldInfosPtr& fn) - { - fieldInfos = fn; - fieldsStream = fdt; - indexStream = fdx; - doClose = false; - } + doClose = true; +} - FieldsWriter::~FieldsWriter() - { - } +FieldsWriter::FieldsWriter(const IndexOutputPtr& fdx, const IndexOutputPtr& fdt, const FieldInfosPtr& fn) { + fieldInfos = fn; + fieldsStream = fdt; + indexStream = fdx; + doClose = false; +} - void FieldsWriter::setFieldsStream(const IndexOutputPtr& stream) - { - this->fieldsStream = stream; - } +FieldsWriter::~FieldsWriter() { +} - void FieldsWriter::flushDocument(int32_t numStoredFields, const RAMOutputStreamPtr& buffer) - { - TestScope testScope(L"FieldsWriter", L"flushDocument"); - indexStream->writeLong(fieldsStream->getFilePointer()); - fieldsStream->writeVInt(numStoredFields); - buffer->writeTo(fieldsStream); - } +void FieldsWriter::setFieldsStream(const IndexOutputPtr& stream) { + this->fieldsStream = stream; +} - void FieldsWriter::skipDocument() - { - indexStream->writeLong(fieldsStream->getFilePointer()); - fieldsStream->writeVInt(0); - } +void FieldsWriter::flushDocument(int32_t numStoredFields, const RAMOutputStreamPtr& buffer) { + TestScope testScope(L"FieldsWriter", L"flushDocument"); + indexStream->writeLong(fieldsStream->getFilePointer()); + fieldsStream->writeVInt(numStoredFields); + buffer->writeTo(fieldsStream); +} - void FieldsWriter::flush() - { - indexStream->flush(); - fieldsStream->flush(); - } +void FieldsWriter::skipDocument() { + indexStream->writeLong(fieldsStream->getFilePointer()); + fieldsStream->writeVInt(0); +} - void FieldsWriter::close() - { - if (doClose) - { - LuceneException finally; - if (fieldsStream) - { - try - { - fieldsStream->close(); - } - catch (LuceneException& e) - { - finally = e; - } - fieldsStream.reset(); +void FieldsWriter::flush() { + indexStream->flush(); + fieldsStream->flush(); +} + +void FieldsWriter::close() { + if (doClose) { + LuceneException finally; + if (fieldsStream) { + try { + fieldsStream->close(); + } catch (LuceneException& e) { + finally = e; } - if (indexStream) - { - try - { - indexStream->close(); - } - catch (LuceneException& e) - { - if (finally.isNull()) // throw first exception hit - finally = e; + fieldsStream.reset(); + } + if (indexStream) { + try { + indexStream->close(); + } catch (LuceneException& e) { + if (finally.isNull()) { // throw first exception hit + finally = e; } - indexStream.reset(); } - finally.throwException(); + indexStream.reset(); } + finally.throwException(); } +} - void FieldsWriter::writeField(const FieldInfoPtr& fi, const FieldablePtr& field) - { - fieldsStream->writeVInt(fi->number); - uint8_t bits = 0; - if (field->isTokenized()) - bits |= FIELD_IS_TOKENIZED; - if (field->isBinary()) - bits |= FIELD_IS_BINARY; - - fieldsStream->writeByte(bits); - - if (field->isBinary()) - { - ByteArray data(field->getBinaryValue()); - int32_t len = field->getBinaryLength(); - int32_t offset = field->getBinaryOffset(); - - fieldsStream->writeVInt(len); - fieldsStream->writeBytes(data.get(), offset, len); - } - else - fieldsStream->writeString(field->stringValue()); +void FieldsWriter::writeField(const FieldInfoPtr& fi, const FieldablePtr& field) { + fieldsStream->writeVInt(fi->number); + uint8_t bits = 0; + if (field->isTokenized()) { + bits |= FIELD_IS_TOKENIZED; + } + if (field->isBinary()) { + bits |= FIELD_IS_BINARY; } - void FieldsWriter::addRawDocuments(const IndexInputPtr& stream, Collection lengths, int32_t numDocs) - { - int64_t position = fieldsStream->getFilePointer(); - int64_t start = position; - for (int32_t i = 0; i < numDocs; ++i) - { - indexStream->writeLong(position); - position += lengths[i]; - } - fieldsStream->copyBytes(stream, position - start); - BOOST_ASSERT(fieldsStream->getFilePointer() == position); + fieldsStream->writeByte(bits); + + if (field->isBinary()) { + ByteArray data(field->getBinaryValue()); + int32_t len = field->getBinaryLength(); + int32_t offset = field->getBinaryOffset(); + + fieldsStream->writeVInt(len); + fieldsStream->writeBytes(data.get(), offset, len); + } else { + fieldsStream->writeString(field->stringValue()); + } +} + +void FieldsWriter::addRawDocuments(const IndexInputPtr& stream, Collection lengths, int32_t numDocs) { + int64_t position = fieldsStream->getFilePointer(); + int64_t start = position; + for (int32_t i = 0; i < numDocs; ++i) { + indexStream->writeLong(position); + position += lengths[i]; } + fieldsStream->copyBytes(stream, position - start); + BOOST_ASSERT(fieldsStream->getFilePointer() == position); +} - void FieldsWriter::addDocument(const DocumentPtr& doc) - { - indexStream->writeLong(fieldsStream->getFilePointer()); +void FieldsWriter::addDocument(const DocumentPtr& doc) { + indexStream->writeLong(fieldsStream->getFilePointer()); - int32_t storedCount = 0; - Collection fields(doc->getFields()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->isStored()) - ++storedCount; + int32_t storedCount = 0; + Collection fields(doc->getFields()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->isStored()) { + ++storedCount; } - fieldsStream->writeVInt(storedCount); + } + fieldsStream->writeVInt(storedCount); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if ((*field)->isStored()) - writeField(fieldInfos->fieldInfo((*field)->name()), *field); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if ((*field)->isStored()) { + writeField(fieldInfos->fieldInfo((*field)->name()), *field); } } } + +} diff --git a/src/core/index/FilterIndexReader.cpp b/src/core/index/FilterIndexReader.cpp index 0cce9635..8dbcf931 100644 --- a/src/core/index/FilterIndexReader.cpp +++ b/src/core/index/FilterIndexReader.cpp @@ -8,301 +8,247 @@ #include "FilterIndexReader.h" #include "FieldCache.h" -namespace Lucene -{ - FilterIndexReader::FilterIndexReader(const IndexReaderPtr& in) - { - this->in = in; - } - - FilterIndexReader::~FilterIndexReader() - { - } - - DirectoryPtr FilterIndexReader::directory() - { - return in->directory(); - } - - Collection FilterIndexReader::getTermFreqVectors(int32_t docNumber) - { - ensureOpen(); - return in->getTermFreqVectors(docNumber); - } - - TermFreqVectorPtr FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field) - { - ensureOpen(); - return in->getTermFreqVector(docNumber, field); - } - - void FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - in->getTermFreqVector(docNumber, field, mapper); - } - - void FilterIndexReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - in->getTermFreqVector(docNumber, mapper); - } - - int32_t FilterIndexReader::numDocs() - { - // Don't call ensureOpen() here (it could affect performance) - return in->numDocs(); - } - - int32_t FilterIndexReader::maxDoc() - { - // Don't call ensureOpen() here (it could affect performance) - return in->maxDoc(); - } - - DocumentPtr FilterIndexReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) - { - ensureOpen(); - return in->document(n, fieldSelector); - } - - bool FilterIndexReader::isDeleted(int32_t n) - { - // Don't call ensureOpen() here (it could affect performance) - return in->isDeleted(n); - } - - bool FilterIndexReader::hasDeletions() - { - // Don't call ensureOpen() here (it could affect performance) - return in->hasDeletions(); - } - - void FilterIndexReader::doUndeleteAll() - { - in->undeleteAll(); - } - - bool FilterIndexReader::hasNorms(const String& field) - { - ensureOpen(); - return in->hasNorms(field); - } - - ByteArray FilterIndexReader::norms(const String& field) - { - ensureOpen(); - return in->norms(field); - } - - void FilterIndexReader::norms(const String& field, ByteArray norms, int32_t offset) - { - ensureOpen(); - in->norms(field, norms, offset); - } - - void FilterIndexReader::doSetNorm(int32_t doc, const String& field, uint8_t value) - { - in->setNorm(doc, field, value); - } - - TermEnumPtr FilterIndexReader::terms() - { - ensureOpen(); - return in->terms(); - } - - TermEnumPtr FilterIndexReader::terms(const TermPtr& t) - { - ensureOpen(); - return in->terms(t); - } - - int32_t FilterIndexReader::docFreq(const TermPtr& t) - { - ensureOpen(); - return in->docFreq(t); - } - - TermDocsPtr FilterIndexReader::termDocs() - { - ensureOpen(); - return in->termDocs(); - } - - TermDocsPtr FilterIndexReader::termDocs(const TermPtr& term) - { - ensureOpen(); - return in->termDocs(term); - } - - TermPositionsPtr FilterIndexReader::termPositions() - { - ensureOpen(); - return in->termPositions(); - } - - void FilterIndexReader::doDelete(int32_t docNum) - { - in->deleteDocument(docNum); - } - - void FilterIndexReader::doCommit(MapStringString commitUserData) - { - in->commit(commitUserData); - } - - void FilterIndexReader::doClose() - { - in->close(); - - // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is - // generally not a good idea) - FieldCache::DEFAULT()->purge(shared_from_this()); - } - - HashSet FilterIndexReader::getFieldNames(FieldOption fieldOption) - { - ensureOpen(); - return in->getFieldNames(fieldOption); - } - - int64_t FilterIndexReader::getVersion() - { - ensureOpen(); - return in->getVersion(); - } - - bool FilterIndexReader::isCurrent() - { - ensureOpen(); - return in->isCurrent(); - } - - bool FilterIndexReader::isOptimized() - { - ensureOpen(); - return in->isOptimized(); - } - - Collection FilterIndexReader::getSequentialSubReaders() - { - return in->getSequentialSubReaders(); - } - - LuceneObjectPtr FilterIndexReader::getFieldCacheKey() - { - return in->getFieldCacheKey(); - } - - LuceneObjectPtr FilterIndexReader::getDeletesCacheKey() - { - return in->getDeletesCacheKey(); - } - - FilterTermDocs::FilterTermDocs(const TermDocsPtr& in) - { - this->in = in; - } - - FilterTermDocs::~FilterTermDocs() - { - } - - void FilterTermDocs::seek(const TermPtr& term) - { - in->seek(term); - } - - void FilterTermDocs::seek(const TermEnumPtr& termEnum) - { - in->seek(termEnum); - } - - int32_t FilterTermDocs::doc() - { - return in->doc(); - } - - int32_t FilterTermDocs::freq() - { - return in->freq(); - } - - bool FilterTermDocs::next() - { - return in->next(); - } - - int32_t FilterTermDocs::read(Collection docs, Collection freqs) - { - return in->read(docs, freqs); - } - - bool FilterTermDocs::skipTo(int32_t target) - { - return in->skipTo(target); - } - - void FilterTermDocs::close() - { - in->close(); - } - - FilterTermPositions::FilterTermPositions(const TermPositionsPtr& in) : FilterTermDocs(in) - { - } - - FilterTermPositions::~FilterTermPositions() - { - } - - int32_t FilterTermPositions::nextPosition() - { - return boost::static_pointer_cast(in)->nextPosition(); - } - - int32_t FilterTermPositions::getPayloadLength() - { - return boost::static_pointer_cast(in)->getPayloadLength(); - } - - ByteArray FilterTermPositions::getPayload(ByteArray data, int32_t offset) - { - return boost::static_pointer_cast(in)->getPayload(data, offset); - } - - bool FilterTermPositions::isPayloadAvailable() - { - return boost::static_pointer_cast(in)->isPayloadAvailable(); - } - - FilterTermEnum::FilterTermEnum(const TermEnumPtr& in) - { - this->in = in; - } - - FilterTermEnum::~FilterTermEnum() - { - } - - bool FilterTermEnum::next() - { - return in->next(); - } - - TermPtr FilterTermEnum::term() - { - return in->term(); - } - - int32_t FilterTermEnum::docFreq() - { - return in->docFreq(); - } - - void FilterTermEnum::close() - { - in->close(); - } +namespace Lucene { + +FilterIndexReader::FilterIndexReader(const IndexReaderPtr& in) { + this->in = in; +} + +FilterIndexReader::~FilterIndexReader() { +} + +DirectoryPtr FilterIndexReader::directory() { + return in->directory(); +} + +Collection FilterIndexReader::getTermFreqVectors(int32_t docNumber) { + ensureOpen(); + return in->getTermFreqVectors(docNumber); +} + +TermFreqVectorPtr FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field) { + ensureOpen(); + return in->getTermFreqVector(docNumber, field); +} + +void FilterIndexReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { + ensureOpen(); + in->getTermFreqVector(docNumber, field, mapper); +} + +void FilterIndexReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { + ensureOpen(); + in->getTermFreqVector(docNumber, mapper); +} + +int32_t FilterIndexReader::numDocs() { + // Don't call ensureOpen() here (it could affect performance) + return in->numDocs(); +} + +int32_t FilterIndexReader::maxDoc() { + // Don't call ensureOpen() here (it could affect performance) + return in->maxDoc(); +} + +DocumentPtr FilterIndexReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { + ensureOpen(); + return in->document(n, fieldSelector); +} + +bool FilterIndexReader::isDeleted(int32_t n) { + // Don't call ensureOpen() here (it could affect performance) + return in->isDeleted(n); +} + +bool FilterIndexReader::hasDeletions() { + // Don't call ensureOpen() here (it could affect performance) + return in->hasDeletions(); +} + +void FilterIndexReader::doUndeleteAll() { + in->undeleteAll(); +} + +bool FilterIndexReader::hasNorms(const String& field) { + ensureOpen(); + return in->hasNorms(field); +} + +ByteArray FilterIndexReader::norms(const String& field) { + ensureOpen(); + return in->norms(field); +} + +void FilterIndexReader::norms(const String& field, ByteArray norms, int32_t offset) { + ensureOpen(); + in->norms(field, norms, offset); +} + +void FilterIndexReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { + in->setNorm(doc, field, value); +} + +TermEnumPtr FilterIndexReader::terms() { + ensureOpen(); + return in->terms(); +} + +TermEnumPtr FilterIndexReader::terms(const TermPtr& t) { + ensureOpen(); + return in->terms(t); +} + +int32_t FilterIndexReader::docFreq(const TermPtr& t) { + ensureOpen(); + return in->docFreq(t); +} + +TermDocsPtr FilterIndexReader::termDocs() { + ensureOpen(); + return in->termDocs(); +} + +TermDocsPtr FilterIndexReader::termDocs(const TermPtr& term) { + ensureOpen(); + return in->termDocs(term); +} + +TermPositionsPtr FilterIndexReader::termPositions() { + ensureOpen(); + return in->termPositions(); +} + +void FilterIndexReader::doDelete(int32_t docNum) { + in->deleteDocument(docNum); +} + +void FilterIndexReader::doCommit(MapStringString commitUserData) { + in->commit(commitUserData); +} + +void FilterIndexReader::doClose() { + in->close(); + + // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is + // generally not a good idea) + FieldCache::DEFAULT()->purge(shared_from_this()); +} + +HashSet FilterIndexReader::getFieldNames(FieldOption fieldOption) { + ensureOpen(); + return in->getFieldNames(fieldOption); +} + +int64_t FilterIndexReader::getVersion() { + ensureOpen(); + return in->getVersion(); +} + +bool FilterIndexReader::isCurrent() { + ensureOpen(); + return in->isCurrent(); +} + +bool FilterIndexReader::isOptimized() { + ensureOpen(); + return in->isOptimized(); +} + +Collection FilterIndexReader::getSequentialSubReaders() { + return in->getSequentialSubReaders(); +} + +LuceneObjectPtr FilterIndexReader::getFieldCacheKey() { + return in->getFieldCacheKey(); +} + +LuceneObjectPtr FilterIndexReader::getDeletesCacheKey() { + return in->getDeletesCacheKey(); +} + +FilterTermDocs::FilterTermDocs(const TermDocsPtr& in) { + this->in = in; +} + +FilterTermDocs::~FilterTermDocs() { +} + +void FilterTermDocs::seek(const TermPtr& term) { + in->seek(term); +} + +void FilterTermDocs::seek(const TermEnumPtr& termEnum) { + in->seek(termEnum); +} + +int32_t FilterTermDocs::doc() { + return in->doc(); +} + +int32_t FilterTermDocs::freq() { + return in->freq(); +} + +bool FilterTermDocs::next() { + return in->next(); +} + +int32_t FilterTermDocs::read(Collection docs, Collection freqs) { + return in->read(docs, freqs); +} + +bool FilterTermDocs::skipTo(int32_t target) { + return in->skipTo(target); +} + +void FilterTermDocs::close() { + in->close(); +} + +FilterTermPositions::FilterTermPositions(const TermPositionsPtr& in) : FilterTermDocs(in) { +} + +FilterTermPositions::~FilterTermPositions() { +} + +int32_t FilterTermPositions::nextPosition() { + return boost::static_pointer_cast(in)->nextPosition(); +} + +int32_t FilterTermPositions::getPayloadLength() { + return boost::static_pointer_cast(in)->getPayloadLength(); +} + +ByteArray FilterTermPositions::getPayload(ByteArray data, int32_t offset) { + return boost::static_pointer_cast(in)->getPayload(data, offset); +} + +bool FilterTermPositions::isPayloadAvailable() { + return boost::static_pointer_cast(in)->isPayloadAvailable(); +} + +FilterTermEnum::FilterTermEnum(const TermEnumPtr& in) { + this->in = in; +} + +FilterTermEnum::~FilterTermEnum() { +} + +bool FilterTermEnum::next() { + return in->next(); +} + +TermPtr FilterTermEnum::term() { + return in->term(); +} + +int32_t FilterTermEnum::docFreq() { + return in->docFreq(); +} + +void FilterTermEnum::close() { + in->close(); +} + } diff --git a/src/core/index/FormatPostingsDocsConsumer.cpp b/src/core/index/FormatPostingsDocsConsumer.cpp index ec221611..6f711f52 100644 --- a/src/core/index/FormatPostingsDocsConsumer.cpp +++ b/src/core/index/FormatPostingsDocsConsumer.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "FormatPostingsDocsConsumer.h" -namespace Lucene -{ - FormatPostingsDocsConsumer::~FormatPostingsDocsConsumer() - { - } +namespace Lucene { + +FormatPostingsDocsConsumer::~FormatPostingsDocsConsumer() { +} + } diff --git a/src/core/index/FormatPostingsDocsWriter.cpp b/src/core/index/FormatPostingsDocsWriter.cpp index 975227cc..8e576dfa 100644 --- a/src/core/index/FormatPostingsDocsWriter.cpp +++ b/src/core/index/FormatPostingsDocsWriter.cpp @@ -21,96 +21,90 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - FormatPostingsDocsWriter::FormatPostingsDocsWriter(const SegmentWriteStatePtr& state, const FormatPostingsTermsWriterPtr& parent) - { - this->lastDocID = 0; - this->df = 0; - this->omitTermFreqAndPositions = false; - this->storePayloads = false; - this->freqStart = 0; - - FormatPostingsFieldsWriterPtr parentPostings(parent->_parent); - this->_parent = parent; - this->state = state; - String fileName(IndexFileNames::segmentFileName(parentPostings->segment, IndexFileNames::FREQ_EXTENSION())); - state->flushedFiles.add(fileName); - out = parentPostings->dir->createOutput(fileName); - totalNumDocs = parentPostings->totalNumDocs; - - skipInterval = parentPostings->termsOut->skipInterval; - skipListWriter = parentPostings->skipListWriter; - skipListWriter->setFreqOutput(out); - - termInfo = newLucene(); - utf8 = newLucene(); - } +namespace Lucene { + +FormatPostingsDocsWriter::FormatPostingsDocsWriter(const SegmentWriteStatePtr& state, const FormatPostingsTermsWriterPtr& parent) { + this->lastDocID = 0; + this->df = 0; + this->omitTermFreqAndPositions = false; + this->storePayloads = false; + this->freqStart = 0; + + FormatPostingsFieldsWriterPtr parentPostings(parent->_parent); + this->_parent = parent; + this->state = state; + String fileName(IndexFileNames::segmentFileName(parentPostings->segment, IndexFileNames::FREQ_EXTENSION())); + state->flushedFiles.add(fileName); + out = parentPostings->dir->createOutput(fileName); + totalNumDocs = parentPostings->totalNumDocs; + + skipInterval = parentPostings->termsOut->skipInterval; + skipListWriter = parentPostings->skipListWriter; + skipListWriter->setFreqOutput(out); + + termInfo = newLucene(); + utf8 = newLucene(); +} - FormatPostingsDocsWriter::~FormatPostingsDocsWriter() - { - } +FormatPostingsDocsWriter::~FormatPostingsDocsWriter() { +} + +void FormatPostingsDocsWriter::initialize() { + posWriter = newLucene(state, shared_from_this()); +} + +void FormatPostingsDocsWriter::setField(const FieldInfoPtr& fieldInfo) { + this->fieldInfo = fieldInfo; + omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; + storePayloads = fieldInfo->storePayloads; + posWriter->setField(fieldInfo); +} - void FormatPostingsDocsWriter::initialize() - { - posWriter = newLucene(state, shared_from_this()); +FormatPostingsPositionsConsumerPtr FormatPostingsDocsWriter::addDoc(int32_t docID, int32_t termDocFreq) { + int32_t delta = docID - lastDocID; + + if (docID < 0 || (df > 0 && delta <= 0)) { + boost::throw_exception(CorruptIndexException(L"docs out of order (" + StringUtils::toString(docID) + L" <= " + StringUtils::toString(lastDocID) + L" )")); } - void FormatPostingsDocsWriter::setField(const FieldInfoPtr& fieldInfo) - { - this->fieldInfo = fieldInfo; - omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; - storePayloads = fieldInfo->storePayloads; - posWriter->setField(fieldInfo); + if ((++df % skipInterval) == 0) { + skipListWriter->setSkipData(lastDocID, storePayloads, posWriter->lastPayloadLength); + skipListWriter->bufferSkip(df); } - FormatPostingsPositionsConsumerPtr FormatPostingsDocsWriter::addDoc(int32_t docID, int32_t termDocFreq) - { - int32_t delta = docID - lastDocID; - - if (docID < 0 || (df > 0 && delta <= 0)) - boost::throw_exception(CorruptIndexException(L"docs out of order (" + StringUtils::toString(docID) + L" <= " + StringUtils::toString(lastDocID) + L" )")); - - if ((++df % skipInterval) == 0) - { - skipListWriter->setSkipData(lastDocID, storePayloads, posWriter->lastPayloadLength); - skipListWriter->bufferSkip(df); - } - - BOOST_ASSERT(docID < totalNumDocs); - - lastDocID = docID; - if (omitTermFreqAndPositions) - out->writeVInt(delta); - else if (termDocFreq == 1) - out->writeVInt((delta << 1) | 1); - else - { - out->writeVInt(delta << 1); - out->writeVInt(termDocFreq); - } - - return posWriter; + BOOST_ASSERT(docID < totalNumDocs); + + lastDocID = docID; + if (omitTermFreqAndPositions) { + out->writeVInt(delta); + } else if (termDocFreq == 1) { + out->writeVInt((delta << 1) | 1); + } else { + out->writeVInt(delta << 1); + out->writeVInt(termDocFreq); } - void FormatPostingsDocsWriter::finish() - { - int64_t skipPointer = skipListWriter->writeSkip(out); - FormatPostingsTermsWriterPtr parent(_parent); - termInfo->set(df, parent->freqStart, parent->proxStart, (int32_t)(skipPointer - parent->freqStart)); + return posWriter; +} - StringUtils::toUTF8(parent->currentTerm.get() + parent->currentTermStart, parent->currentTerm.size(), utf8); +void FormatPostingsDocsWriter::finish() { + int64_t skipPointer = skipListWriter->writeSkip(out); + FormatPostingsTermsWriterPtr parent(_parent); + termInfo->set(df, parent->freqStart, parent->proxStart, (int32_t)(skipPointer - parent->freqStart)); - if (df > 0) - parent->termsOut->add(fieldInfo->number, utf8->result, utf8->length, termInfo); + StringUtils::toUTF8(parent->currentTerm.get() + parent->currentTermStart, parent->currentTerm.size(), utf8); - lastDocID = 0; - df = 0; + if (df > 0) { + parent->termsOut->add(fieldInfo->number, utf8->result, utf8->length, termInfo); } - void FormatPostingsDocsWriter::close() - { - out->close(); - posWriter->close(); - } + lastDocID = 0; + df = 0; +} + +void FormatPostingsDocsWriter::close() { + out->close(); + posWriter->close(); +} + } diff --git a/src/core/index/FormatPostingsFieldsConsumer.cpp b/src/core/index/FormatPostingsFieldsConsumer.cpp index d7373eb1..1063e211 100644 --- a/src/core/index/FormatPostingsFieldsConsumer.cpp +++ b/src/core/index/FormatPostingsFieldsConsumer.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "FormatPostingsFieldsConsumer.h" -namespace Lucene -{ - FormatPostingsFieldsConsumer::~FormatPostingsFieldsConsumer() - { - } +namespace Lucene { + +FormatPostingsFieldsConsumer::~FormatPostingsFieldsConsumer() { +} + } diff --git a/src/core/index/FormatPostingsFieldsWriter.cpp b/src/core/index/FormatPostingsFieldsWriter.cpp index 64804ad3..e0a8cc58 100644 --- a/src/core/index/FormatPostingsFieldsWriter.cpp +++ b/src/core/index/FormatPostingsFieldsWriter.cpp @@ -12,41 +12,37 @@ #include "IndexFileNames.h" #include "DefaultSkipListWriter.h" -namespace Lucene -{ - FormatPostingsFieldsWriter::FormatPostingsFieldsWriter(const SegmentWriteStatePtr& state, const FieldInfosPtr& fieldInfos) - { - dir = state->directory; - segment = state->segmentName; - totalNumDocs = state->numDocs; - this->state = state; - this->fieldInfos = fieldInfos; - termsOut = newLucene(dir, segment, fieldInfos, state->termIndexInterval); - - skipListWriter = newLucene(termsOut->skipInterval, termsOut->maxSkipLevels, totalNumDocs, IndexOutputPtr(), IndexOutputPtr()); - - state->flushedFiles.add(state->segmentFileName(IndexFileNames::TERMS_EXTENSION())); - state->flushedFiles.add(state->segmentFileName(IndexFileNames::TERMS_INDEX_EXTENSION())); - } - - FormatPostingsFieldsWriter::~FormatPostingsFieldsWriter() - { - } - - void FormatPostingsFieldsWriter::initialize() - { - termsWriter = newLucene(state, shared_from_this()); - } - - FormatPostingsTermsConsumerPtr FormatPostingsFieldsWriter::addField(const FieldInfoPtr& field) - { - termsWriter->setField(field); - return termsWriter; - } - - void FormatPostingsFieldsWriter::finish() - { - termsOut->close(); - termsWriter->close(); - } +namespace Lucene { + +FormatPostingsFieldsWriter::FormatPostingsFieldsWriter(const SegmentWriteStatePtr& state, const FieldInfosPtr& fieldInfos) { + dir = state->directory; + segment = state->segmentName; + totalNumDocs = state->numDocs; + this->state = state; + this->fieldInfos = fieldInfos; + termsOut = newLucene(dir, segment, fieldInfos, state->termIndexInterval); + + skipListWriter = newLucene(termsOut->skipInterval, termsOut->maxSkipLevels, totalNumDocs, IndexOutputPtr(), IndexOutputPtr()); + + state->flushedFiles.add(state->segmentFileName(IndexFileNames::TERMS_EXTENSION())); + state->flushedFiles.add(state->segmentFileName(IndexFileNames::TERMS_INDEX_EXTENSION())); +} + +FormatPostingsFieldsWriter::~FormatPostingsFieldsWriter() { +} + +void FormatPostingsFieldsWriter::initialize() { + termsWriter = newLucene(state, shared_from_this()); +} + +FormatPostingsTermsConsumerPtr FormatPostingsFieldsWriter::addField(const FieldInfoPtr& field) { + termsWriter->setField(field); + return termsWriter; +} + +void FormatPostingsFieldsWriter::finish() { + termsOut->close(); + termsWriter->close(); +} + } diff --git a/src/core/index/FormatPostingsPositionsConsumer.cpp b/src/core/index/FormatPostingsPositionsConsumer.cpp index 252f4222..a239aa9a 100644 --- a/src/core/index/FormatPostingsPositionsConsumer.cpp +++ b/src/core/index/FormatPostingsPositionsConsumer.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "FormatPostingsPositionsConsumer.h" -namespace Lucene -{ - FormatPostingsPositionsConsumer::~FormatPostingsPositionsConsumer() - { - } +namespace Lucene { + +FormatPostingsPositionsConsumer::~FormatPostingsPositionsConsumer() { +} + } diff --git a/src/core/index/FormatPostingsPositionsWriter.cpp b/src/core/index/FormatPostingsPositionsWriter.cpp index 7ccf8fae..b3f80833 100644 --- a/src/core/index/FormatPostingsPositionsWriter.cpp +++ b/src/core/index/FormatPostingsPositionsWriter.cpp @@ -17,77 +17,69 @@ #include "DefaultSkipListWriter.h" #include "IndexOutput.h" -namespace Lucene -{ - FormatPostingsPositionsWriter::FormatPostingsPositionsWriter(const SegmentWriteStatePtr& state, const FormatPostingsDocsWriterPtr& parent) - { - lastPosition = 0; - storePayloads = false; - lastPayloadLength = -1; +namespace Lucene { - this->_parent = parent; - FormatPostingsFieldsWriterPtr parentFieldsWriter(FormatPostingsTermsWriterPtr(parent->_parent)->_parent); +FormatPostingsPositionsWriter::FormatPostingsPositionsWriter(const SegmentWriteStatePtr& state, const FormatPostingsDocsWriterPtr& parent) { + lastPosition = 0; + storePayloads = false; + lastPayloadLength = -1; - omitTermFreqAndPositions = parent->omitTermFreqAndPositions; + this->_parent = parent; + FormatPostingsFieldsWriterPtr parentFieldsWriter(FormatPostingsTermsWriterPtr(parent->_parent)->_parent); - if (parentFieldsWriter->fieldInfos->hasProx()) - { - // At least one field does not omit TF, so create the prox file - String fileName(IndexFileNames::segmentFileName(parentFieldsWriter->segment, IndexFileNames::PROX_EXTENSION())); - state->flushedFiles.add(fileName); - out = parentFieldsWriter->dir->createOutput(fileName); - parent->skipListWriter->setProxOutput(out); - } - else - { - // Every field omits TF so we will write no prox file - } - } + omitTermFreqAndPositions = parent->omitTermFreqAndPositions; - FormatPostingsPositionsWriter::~FormatPostingsPositionsWriter() - { + if (parentFieldsWriter->fieldInfos->hasProx()) { + // At least one field does not omit TF, so create the prox file + String fileName(IndexFileNames::segmentFileName(parentFieldsWriter->segment, IndexFileNames::PROX_EXTENSION())); + state->flushedFiles.add(fileName); + out = parentFieldsWriter->dir->createOutput(fileName); + parent->skipListWriter->setProxOutput(out); + } else { + // Every field omits TF so we will write no prox file } +} - void FormatPostingsPositionsWriter::addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength) - { - BOOST_ASSERT(!omitTermFreqAndPositions); - BOOST_ASSERT(out); +FormatPostingsPositionsWriter::~FormatPostingsPositionsWriter() { +} + +void FormatPostingsPositionsWriter::addPosition(int32_t position, ByteArray payload, int32_t payloadOffset, int32_t payloadLength) { + BOOST_ASSERT(!omitTermFreqAndPositions); + BOOST_ASSERT(out); - int32_t delta = position - lastPosition; - lastPosition = position; + int32_t delta = position - lastPosition; + lastPosition = position; - if (storePayloads) - { - if (payloadLength != lastPayloadLength) - { - lastPayloadLength = payloadLength; - out->writeVInt((delta << 1) | 1); - out->writeVInt(payloadLength); - } - else - out->writeVInt(delta << 1); - if (payloadLength > 0) - out->writeBytes(payload.get(), payloadLength); + if (storePayloads) { + if (payloadLength != lastPayloadLength) { + lastPayloadLength = payloadLength; + out->writeVInt((delta << 1) | 1); + out->writeVInt(payloadLength); + } else { + out->writeVInt(delta << 1); + } + if (payloadLength > 0) { + out->writeBytes(payload.get(), payloadLength); } - else - out->writeVInt(delta); + } else { + out->writeVInt(delta); } +} - void FormatPostingsPositionsWriter::setField(const FieldInfoPtr& fieldInfo) - { - omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; - storePayloads = omitTermFreqAndPositions ? false : fieldInfo->storePayloads; - } +void FormatPostingsPositionsWriter::setField(const FieldInfoPtr& fieldInfo) { + omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; + storePayloads = omitTermFreqAndPositions ? false : fieldInfo->storePayloads; +} - void FormatPostingsPositionsWriter::finish() - { - lastPosition = 0; - lastPayloadLength = -1; - } +void FormatPostingsPositionsWriter::finish() { + lastPosition = 0; + lastPayloadLength = -1; +} - void FormatPostingsPositionsWriter::close() - { - if (out) - out->close(); +void FormatPostingsPositionsWriter::close() { + if (out) { + out->close(); } } + +} diff --git a/src/core/index/FormatPostingsTermsConsumer.cpp b/src/core/index/FormatPostingsTermsConsumer.cpp index a2ad2dfc..4894527a 100644 --- a/src/core/index/FormatPostingsTermsConsumer.cpp +++ b/src/core/index/FormatPostingsTermsConsumer.cpp @@ -9,21 +9,22 @@ #include "UTF8Stream.h" #include "MiscUtils.h" -namespace Lucene -{ - FormatPostingsTermsConsumer::~FormatPostingsTermsConsumer() - { - } +namespace Lucene { + +FormatPostingsTermsConsumer::~FormatPostingsTermsConsumer() { +} - FormatPostingsDocsConsumerPtr FormatPostingsTermsConsumer::addTerm(const String& text) - { - int32_t len = text.length(); - if (!termBuffer) - termBuffer = CharArray::newInstance(MiscUtils::getNextSize(len + 1)); - if (termBuffer.size() < len + 1) - termBuffer.resize(MiscUtils::getNextSize(len + 1)); - MiscUtils::arrayCopy(text.begin(), 0, termBuffer.get(), 0, len); - termBuffer[len] = UTF8Base::UNICODE_TERMINATOR; - return addTerm(termBuffer, 0); +FormatPostingsDocsConsumerPtr FormatPostingsTermsConsumer::addTerm(const String& text) { + int32_t len = text.length(); + if (!termBuffer) { + termBuffer = CharArray::newInstance(MiscUtils::getNextSize(len + 1)); } + if (termBuffer.size() < len + 1) { + termBuffer.resize(MiscUtils::getNextSize(len + 1)); + } + MiscUtils::arrayCopy(text.begin(), 0, termBuffer.get(), 0, len); + termBuffer[len] = UTF8Base::UNICODE_TERMINATOR; + return addTerm(termBuffer, 0); +} + } diff --git a/src/core/index/FormatPostingsTermsWriter.cpp b/src/core/index/FormatPostingsTermsWriter.cpp index 8e83260b..48ce1563 100644 --- a/src/core/index/FormatPostingsTermsWriter.cpp +++ b/src/core/index/FormatPostingsTermsWriter.cpp @@ -12,54 +12,49 @@ #include "IndexOutput.h" #include "DefaultSkipListWriter.h" -namespace Lucene -{ - FormatPostingsTermsWriter::FormatPostingsTermsWriter(const SegmentWriteStatePtr& state, const FormatPostingsFieldsWriterPtr& parent) - { - currentTermStart = 0; - freqStart = 0; - proxStart = 0; +namespace Lucene { - this->_parent = parent; - this->state = state; - termsOut = parent->termsOut; - } - - FormatPostingsTermsWriter::~FormatPostingsTermsWriter() - { - } +FormatPostingsTermsWriter::FormatPostingsTermsWriter(const SegmentWriteStatePtr& state, const FormatPostingsFieldsWriterPtr& parent) { + currentTermStart = 0; + freqStart = 0; + proxStart = 0; - void FormatPostingsTermsWriter::initialize() - { - docsWriter = newLucene(state, shared_from_this()); - } + this->_parent = parent; + this->state = state; + termsOut = parent->termsOut; +} - void FormatPostingsTermsWriter::setField(const FieldInfoPtr& fieldInfo) - { - this->fieldInfo = fieldInfo; - docsWriter->setField(fieldInfo); - } +FormatPostingsTermsWriter::~FormatPostingsTermsWriter() { +} - FormatPostingsDocsConsumerPtr FormatPostingsTermsWriter::addTerm(CharArray text, int32_t start) - { - currentTerm = text; - currentTermStart = start; +void FormatPostingsTermsWriter::initialize() { + docsWriter = newLucene(state, shared_from_this()); +} - freqStart = docsWriter->out->getFilePointer(); - if (docsWriter->posWriter->out) - proxStart = docsWriter->posWriter->out->getFilePointer(); +void FormatPostingsTermsWriter::setField(const FieldInfoPtr& fieldInfo) { + this->fieldInfo = fieldInfo; + docsWriter->setField(fieldInfo); +} - FormatPostingsFieldsWriterPtr(_parent)->skipListWriter->resetSkip(); +FormatPostingsDocsConsumerPtr FormatPostingsTermsWriter::addTerm(CharArray text, int32_t start) { + currentTerm = text; + currentTermStart = start; - return docsWriter; + freqStart = docsWriter->out->getFilePointer(); + if (docsWriter->posWriter->out) { + proxStart = docsWriter->posWriter->out->getFilePointer(); } - void FormatPostingsTermsWriter::finish() - { - } + FormatPostingsFieldsWriterPtr(_parent)->skipListWriter->resetSkip(); + + return docsWriter; +} + +void FormatPostingsTermsWriter::finish() { +} + +void FormatPostingsTermsWriter::close() { + docsWriter->close(); +} - void FormatPostingsTermsWriter::close() - { - docsWriter->close(); - } } diff --git a/src/core/index/FreqProxFieldMergeState.cpp b/src/core/index/FreqProxFieldMergeState.cpp index 7f6e4ef4..838d5d32 100644 --- a/src/core/index/FreqProxFieldMergeState.cpp +++ b/src/core/index/FreqProxFieldMergeState.cpp @@ -17,88 +17,84 @@ #include "FieldInfo.h" #include "MiscUtils.h" -namespace Lucene -{ - FreqProxFieldMergeState::FreqProxFieldMergeState(const FreqProxTermsWriterPerFieldPtr& field) - { - this->numPostings = 0; - this->textOffset = 0; - this->docID = 0; - this->termFreq = 0; - this->postingUpto = -1; - this->freq = newLucene(); - this->prox = newLucene(); - - this->field = field; - this->charPool = TermsHashPerThreadPtr(FreqProxTermsWriterPerThreadPtr(field->_perThread)->_termsHashPerThread)->charPool; - - TermsHashPerFieldPtr termsHashPerField(field->_termsHashPerField); - this->numPostings = termsHashPerField->numPostings; - this->postings = termsHashPerField->sortPostings(); - } +namespace Lucene { - FreqProxFieldMergeState::~FreqProxFieldMergeState() - { - } +FreqProxFieldMergeState::FreqProxFieldMergeState(const FreqProxTermsWriterPerFieldPtr& field) { + this->numPostings = 0; + this->textOffset = 0; + this->docID = 0; + this->termFreq = 0; + this->postingUpto = -1; + this->freq = newLucene(); + this->prox = newLucene(); - bool FreqProxFieldMergeState::nextTerm() - { - ++postingUpto; - if (postingUpto == numPostings) - return false; + this->field = field; + this->charPool = TermsHashPerThreadPtr(FreqProxTermsWriterPerThreadPtr(field->_perThread)->_termsHashPerThread)->charPool; - p = boost::static_pointer_cast(postings[postingUpto]); - docID = 0; + TermsHashPerFieldPtr termsHashPerField(field->_termsHashPerField); + this->numPostings = termsHashPerField->numPostings; + this->postings = termsHashPerField->sortPostings(); +} - text = charPool->buffers[p->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]; - textOffset = (p->textStart & DocumentsWriter::CHAR_BLOCK_MASK); +FreqProxFieldMergeState::~FreqProxFieldMergeState() { +} - TermsHashPerFieldPtr termsHashPerField(field->_termsHashPerField); - termsHashPerField->initReader(freq, p, 0); - if (!field->fieldInfo->omitTermFreqAndPositions) - termsHashPerField->initReader(prox, p, 1); +bool FreqProxFieldMergeState::nextTerm() { + ++postingUpto; + if (postingUpto == numPostings) { + return false; + } + + p = boost::static_pointer_cast(postings[postingUpto]); + docID = 0; - // Should always be true - bool result = nextDoc(); - BOOST_ASSERT(result); + text = charPool->buffers[p->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]; + textOffset = (p->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - return true; + TermsHashPerFieldPtr termsHashPerField(field->_termsHashPerField); + termsHashPerField->initReader(freq, p, 0); + if (!field->fieldInfo->omitTermFreqAndPositions) { + termsHashPerField->initReader(prox, p, 1); } - bool FreqProxFieldMergeState::nextDoc() - { - if (freq->eof()) - { - if (p->lastDocCode != -1) - { - // Return last doc - docID = p->lastDocID; - if (!field->omitTermFreqAndPositions) - termFreq = p->docFreq; - p->lastDocCode = -1; - return true; - } - else - { - // EOF - return false; + // Should always be true + bool result = nextDoc(); + BOOST_ASSERT(result); + + return true; +} + +bool FreqProxFieldMergeState::nextDoc() { + if (freq->eof()) { + if (p->lastDocCode != -1) { + // Return last doc + docID = p->lastDocID; + if (!field->omitTermFreqAndPositions) { + termFreq = p->docFreq; } + p->lastDocCode = -1; + return true; + } else { + // EOF + return false; } + } - int32_t code = freq->readVInt(); - if (field->omitTermFreqAndPositions) - docID += code; - else - { - docID += MiscUtils::unsignedShift(code, 1); - if ((code & 1) != 0) - termFreq = 1; - else - termFreq = freq->readVInt(); + int32_t code = freq->readVInt(); + if (field->omitTermFreqAndPositions) { + docID += code; + } else { + docID += MiscUtils::unsignedShift(code, 1); + if ((code & 1) != 0) { + termFreq = 1; + } else { + termFreq = freq->readVInt(); } + } - BOOST_ASSERT(docID != p->lastDocID); + BOOST_ASSERT(docID != p->lastDocID); + + return true; +} - return true; - } } diff --git a/src/core/index/FreqProxTermsWriter.cpp b/src/core/index/FreqProxTermsWriter.cpp index 10fc5f84..c1a4a1cd 100644 --- a/src/core/index/FreqProxTermsWriter.cpp +++ b/src/core/index/FreqProxTermsWriter.cpp @@ -25,271 +25,252 @@ #include "UTF8Stream.h" #include "TestPoint.h" -namespace Lucene -{ - FreqProxTermsWriter::~FreqProxTermsWriter() - { - } +namespace Lucene { - TermsHashConsumerPerThreadPtr FreqProxTermsWriter::addThread(const TermsHashPerThreadPtr& perThread) - { - return newLucene(perThread); - } +FreqProxTermsWriter::~FreqProxTermsWriter() { +} - void FreqProxTermsWriter::createPostings(Collection postings, int32_t start, int32_t count) - { - int32_t end = start + count; - for (int32_t i = start; i < end; ++i) - postings[i] = newLucene(); +TermsHashConsumerPerThreadPtr FreqProxTermsWriter::addThread(const TermsHashPerThreadPtr& perThread) { + return newLucene(perThread); +} + +void FreqProxTermsWriter::createPostings(Collection postings, int32_t start, int32_t count) { + int32_t end = start + count; + for (int32_t i = start; i < end; ++i) { + postings[i] = newLucene(); } +} - int32_t FreqProxTermsWriter::compareText(const wchar_t* text1, int32_t pos1, const wchar_t* text2, int32_t pos2) - { - while (true) - { - wchar_t c1 = text1[pos1++]; - wchar_t c2 = text2[pos2++]; - if (c1 != c2) - { - if (c2 == UTF8Base::UNICODE_TERMINATOR) - return 1; - else if (c1 == UTF8Base::UNICODE_TERMINATOR) - return -1; - else - return (c1 - c2); +int32_t FreqProxTermsWriter::compareText(const wchar_t* text1, int32_t pos1, const wchar_t* text2, int32_t pos2) { + while (true) { + wchar_t c1 = text1[pos1++]; + wchar_t c2 = text2[pos2++]; + if (c1 != c2) { + if (c2 == UTF8Base::UNICODE_TERMINATOR) { + return 1; + } else if (c1 == UTF8Base::UNICODE_TERMINATOR) { + return -1; + } else { + return (c1 - c2); } - else if (c1 == UTF8Base::UNICODE_TERMINATOR) - return 0; + } else if (c1 == UTF8Base::UNICODE_TERMINATOR) { + return 0; } } +} - void FreqProxTermsWriter::closeDocStore(const SegmentWriteStatePtr& state) - { - } +void FreqProxTermsWriter::closeDocStore(const SegmentWriteStatePtr& state) { +} - void FreqProxTermsWriter::abort() - { - } +void FreqProxTermsWriter::abort() { +} + +void FreqProxTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { + // Gather all FieldData's that have postings, across all ThreadStates + Collection allFields(Collection::newInstance()); - void FreqProxTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) - { - // Gather all FieldData's that have postings, across all ThreadStates - Collection allFields(Collection::newInstance()); - - for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) - { - for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) - { - FreqProxTermsWriterPerFieldPtr freqProxPerField(boost::static_pointer_cast(*perField)); - if (TermsHashPerFieldPtr(freqProxPerField->_termsHashPerField)->numPostings > 0) - allFields.add(freqProxPerField); + for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) { + FreqProxTermsWriterPerFieldPtr freqProxPerField(boost::static_pointer_cast(*perField)); + if (TermsHashPerFieldPtr(freqProxPerField->_termsHashPerField)->numPostings > 0) { + allFields.add(freqProxPerField); } } + } - // Sort by field name - std::sort(allFields.begin(), allFields.end(), luceneCompare()); - - int32_t numAllFields = allFields.size(); - - FormatPostingsFieldsConsumerPtr consumer(newLucene(state, fieldInfos)); - - // Current writer chain: - // FormatPostingsFieldsConsumer - // -> IMPL: FormatPostingsFieldsWriter - // -> FormatPostingsTermsConsumer - // -> IMPL: FormatPostingsTermsWriter - // -> FormatPostingsDocConsumer - // -> IMPL: FormatPostingsDocWriter - // -> FormatPostingsPositionsConsumer - // -> IMPL: FormatPostingsPositionsWriter - - int32_t start = 0; - while (start < numAllFields) - { - FieldInfoPtr fieldInfo(allFields[start]->fieldInfo); - String fieldName(fieldInfo->name); - - int32_t end = start + 1; - while (end < numAllFields && allFields[end]->fieldInfo->name == fieldName) - ++end; - - Collection fields(Collection::newInstance(end - start)); - for (int32_t i = start; i < end; ++i) - { - fields[i - start] = allFields[i]; - - // Aggregate the storePayload as seen by the same field across multiple threads - if (fields[i - start]->hasPayloads) - fieldInfo->storePayloads = true; - } + // Sort by field name + std::sort(allFields.begin(), allFields.end(), luceneCompare()); + + int32_t numAllFields = allFields.size(); + + FormatPostingsFieldsConsumerPtr consumer(newLucene(state, fieldInfos)); + + // Current writer chain: + // FormatPostingsFieldsConsumer + // -> IMPL: FormatPostingsFieldsWriter + // -> FormatPostingsTermsConsumer + // -> IMPL: FormatPostingsTermsWriter + // -> FormatPostingsDocConsumer + // -> IMPL: FormatPostingsDocWriter + // -> FormatPostingsPositionsConsumer + // -> IMPL: FormatPostingsPositionsWriter + + int32_t start = 0; + while (start < numAllFields) { + FieldInfoPtr fieldInfo(allFields[start]->fieldInfo); + String fieldName(fieldInfo->name); - // If this field has postings then add them to the segment - appendPostings(fields, consumer); + int32_t end = start + 1; + while (end < numAllFields && allFields[end]->fieldInfo->name == fieldName) { + ++end; + } + + Collection fields(Collection::newInstance(end - start)); + for (int32_t i = start; i < end; ++i) { + fields[i - start] = allFields[i]; - for (int32_t i = 0; i < fields.size(); ++i) - { - TermsHashPerFieldPtr perField(fields[i]->_termsHashPerField); - int32_t numPostings = perField->numPostings; - perField->reset(); - perField->shrinkHash(numPostings); - fields[i]->reset(); + // Aggregate the storePayload as seen by the same field across multiple threads + if (fields[i - start]->hasPayloads) { + fieldInfo->storePayloads = true; } + } - start = end; + // If this field has postings then add them to the segment + appendPostings(fields, consumer); + + for (int32_t i = 0; i < fields.size(); ++i) { + TermsHashPerFieldPtr perField(fields[i]->_termsHashPerField); + int32_t numPostings = perField->numPostings; + perField->reset(); + perField->shrinkHash(numPostings); + fields[i]->reset(); } - for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) - TermsHashPerThreadPtr(boost::static_pointer_cast(entry->first)->_termsHashPerThread)->reset(true); + start = end; + } - consumer->finish(); + for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { + TermsHashPerThreadPtr(boost::static_pointer_cast(entry->first)->_termsHashPerThread)->reset(true); } - void FreqProxTermsWriter::appendPostings(Collection fields, const FormatPostingsFieldsConsumerPtr& consumer) - { - TestScope testScope(L"FreqProxTermsWriter", L"appendPostings"); - int32_t numFields = fields.size(); + consumer->finish(); +} + +void FreqProxTermsWriter::appendPostings(Collection fields, const FormatPostingsFieldsConsumerPtr& consumer) { + TestScope testScope(L"FreqProxTermsWriter", L"appendPostings"); + int32_t numFields = fields.size(); - Collection mergeStates(Collection::newInstance(numFields)); + Collection mergeStates(Collection::newInstance(numFields)); - for (int32_t i = 0; i < numFields; ++i) - { - FreqProxFieldMergeStatePtr fms(newLucene(fields[i])); - mergeStates[i] = fms; + for (int32_t i = 0; i < numFields; ++i) { + FreqProxFieldMergeStatePtr fms(newLucene(fields[i])); + mergeStates[i] = fms; - BOOST_ASSERT(fms->field->fieldInfo == fields[0]->fieldInfo); + BOOST_ASSERT(fms->field->fieldInfo == fields[0]->fieldInfo); - // Should always be true - bool result = fms->nextTerm(); - BOOST_ASSERT(result); - } + // Should always be true + bool result = fms->nextTerm(); + BOOST_ASSERT(result); + } - FormatPostingsTermsConsumerPtr termsConsumer(consumer->addField(fields[0]->fieldInfo)); + FormatPostingsTermsConsumerPtr termsConsumer(consumer->addField(fields[0]->fieldInfo)); - Collection termStates(Collection::newInstance(numFields)); + Collection termStates(Collection::newInstance(numFields)); - bool currentFieldOmitTermFreqAndPositions = fields[0]->fieldInfo->omitTermFreqAndPositions; + bool currentFieldOmitTermFreqAndPositions = fields[0]->fieldInfo->omitTermFreqAndPositions; - while (numFields > 0) - { - // Get the next term to merge - termStates[0] = mergeStates[0]; - int32_t numToMerge = 1; + while (numFields > 0) { + // Get the next term to merge + termStates[0] = mergeStates[0]; + int32_t numToMerge = 1; - for (int32_t i = 1; i < numFields; ++i) - { - CharArray text = mergeStates[i]->text; - int32_t textOffset = mergeStates[i]->textOffset; - int32_t cmp = compareText(text.get(), textOffset, termStates[0]->text.get(), termStates[0]->textOffset); + for (int32_t i = 1; i < numFields; ++i) { + CharArray text = mergeStates[i]->text; + int32_t textOffset = mergeStates[i]->textOffset; + int32_t cmp = compareText(text.get(), textOffset, termStates[0]->text.get(), termStates[0]->textOffset); - if (cmp < 0) - { - termStates[0] = mergeStates[i]; - numToMerge = 1; - } - else if (cmp == 0) - termStates[numToMerge++] = mergeStates[i]; + if (cmp < 0) { + termStates[0] = mergeStates[i]; + numToMerge = 1; + } else if (cmp == 0) { + termStates[numToMerge++] = mergeStates[i]; } + } - FormatPostingsDocsConsumerPtr docConsumer(termsConsumer->addTerm(termStates[0]->text, termStates[0]->textOffset)); - - // Now termStates has numToMerge FieldMergeStates which all share the same term. Now we must - // interleave the docID streams. - while (numToMerge > 0) - { - FreqProxFieldMergeStatePtr minState(termStates[0]); - for (int32_t i = 1; i < numToMerge; ++i) - { - if (termStates[i]->docID < minState->docID) - minState = termStates[i]; - } + FormatPostingsDocsConsumerPtr docConsumer(termsConsumer->addTerm(termStates[0]->text, termStates[0]->textOffset)); - int32_t termDocFreq = minState->termFreq; + // Now termStates has numToMerge FieldMergeStates which all share the same term. Now we must + // interleave the docID streams. + while (numToMerge > 0) { + FreqProxFieldMergeStatePtr minState(termStates[0]); + for (int32_t i = 1; i < numToMerge; ++i) { + if (termStates[i]->docID < minState->docID) { + minState = termStates[i]; + } + } - FormatPostingsPositionsConsumerPtr posConsumer(docConsumer->addDoc(minState->docID, termDocFreq)); + int32_t termDocFreq = minState->termFreq; - ByteSliceReaderPtr prox(minState->prox); + FormatPostingsPositionsConsumerPtr posConsumer(docConsumer->addDoc(minState->docID, termDocFreq)); - // Carefully copy over the prox + payload info, changing the format to match Lucene's segment format. - if (!currentFieldOmitTermFreqAndPositions) - { - // omitTermFreqAndPositions == false so we do write positions & payload - int32_t position = 0; - for (int32_t j = 0; j < termDocFreq; ++j) - { - int32_t code = prox->readVInt(); - position += (code >> 1); + ByteSliceReaderPtr prox(minState->prox); - int32_t payloadLength; - if ((code & 1) != 0) - { - // This position has a payload - payloadLength = prox->readVInt(); + // Carefully copy over the prox + payload info, changing the format to match Lucene's segment format. + if (!currentFieldOmitTermFreqAndPositions) { + // omitTermFreqAndPositions == false so we do write positions & payload + int32_t position = 0; + for (int32_t j = 0; j < termDocFreq; ++j) { + int32_t code = prox->readVInt(); + position += (code >> 1); - if (!payloadBuffer) - payloadBuffer = ByteArray::newInstance(payloadLength); - if (payloadBuffer.size() < payloadLength) - payloadBuffer.resize(payloadLength); + int32_t payloadLength; + if ((code & 1) != 0) { + // This position has a payload + payloadLength = prox->readVInt(); - prox->readBytes(payloadBuffer.get(), 0, payloadLength); + if (!payloadBuffer) { + payloadBuffer = ByteArray::newInstance(payloadLength); + } + if (payloadBuffer.size() < payloadLength) { + payloadBuffer.resize(payloadLength); } - else - payloadLength = 0; - posConsumer->addPosition(position, payloadBuffer, 0, payloadLength); + prox->readBytes(payloadBuffer.get(), 0, payloadLength); + } else { + payloadLength = 0; } - posConsumer->finish(); + posConsumer->addPosition(position, payloadBuffer, 0, payloadLength); } - if (!minState->nextDoc()) - { - // Remove from termStates - int32_t upto = 0; - for (int32_t i = 0; i < numToMerge; ++i) - { - if (termStates[i] != minState) - termStates[upto++] = termStates[i]; + posConsumer->finish(); + } + + if (!minState->nextDoc()) { + // Remove from termStates + int32_t upto = 0; + for (int32_t i = 0; i < numToMerge; ++i) { + if (termStates[i] != minState) { + termStates[upto++] = termStates[i]; } - --numToMerge; - BOOST_ASSERT(upto == numToMerge); - - // Advance this state to the next term - - if (!minState->nextTerm()) - { - // OK, no more terms, so remove from mergeStates as well - upto = 0; - for (int32_t i = 0; i < numFields; ++i) - { - if (mergeStates[i] != minState) - mergeStates[upto++] = mergeStates[i]; + } + --numToMerge; + BOOST_ASSERT(upto == numToMerge); + + // Advance this state to the next term + + if (!minState->nextTerm()) { + // OK, no more terms, so remove from mergeStates as well + upto = 0; + for (int32_t i = 0; i < numFields; ++i) { + if (mergeStates[i] != minState) { + mergeStates[upto++] = mergeStates[i]; } - --numFields; - BOOST_ASSERT(upto == numFields); } + --numFields; + BOOST_ASSERT(upto == numFields); } } - - docConsumer->finish(); } - termsConsumer->finish(); + docConsumer->finish(); } - int32_t FreqProxTermsWriter::bytesPerPosting() - { - return RawPostingList::BYTES_SIZE + 4 * DocumentsWriter::INT_NUM_BYTE; - } + termsConsumer->finish(); +} - FreqProxTermsWriterPostingList::FreqProxTermsWriterPostingList() - { - docFreq = 0; - lastDocID = 0; - lastDocCode = 0; - lastPosition = 0; - } +int32_t FreqProxTermsWriter::bytesPerPosting() { + return RawPostingList::BYTES_SIZE + 4 * DocumentsWriter::INT_NUM_BYTE; +} + +FreqProxTermsWriterPostingList::FreqProxTermsWriterPostingList() { + docFreq = 0; + lastDocID = 0; + lastDocCode = 0; + lastPosition = 0; +} + +FreqProxTermsWriterPostingList::~FreqProxTermsWriterPostingList() { +} - FreqProxTermsWriterPostingList::~FreqProxTermsWriterPostingList() - { - } } diff --git a/src/core/index/FreqProxTermsWriterPerField.cpp b/src/core/index/FreqProxTermsWriterPerField.cpp index 2e630e67..6404dc89 100644 --- a/src/core/index/FreqProxTermsWriterPerField.cpp +++ b/src/core/index/FreqProxTermsWriterPerField.cpp @@ -17,151 +17,131 @@ #include "DocumentsWriter.h" #include "RawPostingList.h" -namespace Lucene -{ - FreqProxTermsWriterPerField::FreqProxTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const FreqProxTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) - { - this->hasPayloads = false; - this->_termsHashPerField = termsHashPerField; - this->_perThread = perThread; - this->fieldInfo = fieldInfo; - docState = termsHashPerField->docState; - fieldState = termsHashPerField->fieldState; - omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; - } +namespace Lucene { + +FreqProxTermsWriterPerField::FreqProxTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const FreqProxTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { + this->hasPayloads = false; + this->_termsHashPerField = termsHashPerField; + this->_perThread = perThread; + this->fieldInfo = fieldInfo; + docState = termsHashPerField->docState; + fieldState = termsHashPerField->fieldState; + omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; +} - FreqProxTermsWriterPerField::~FreqProxTermsWriterPerField() - { - } +FreqProxTermsWriterPerField::~FreqProxTermsWriterPerField() { +} - int32_t FreqProxTermsWriterPerField::getStreamCount() - { - return fieldInfo->omitTermFreqAndPositions ? 1 : 2; - } +int32_t FreqProxTermsWriterPerField::getStreamCount() { + return fieldInfo->omitTermFreqAndPositions ? 1 : 2; +} - void FreqProxTermsWriterPerField::finish() - { - } +void FreqProxTermsWriterPerField::finish() { +} - void FreqProxTermsWriterPerField::skippingLongTerm() - { - } +void FreqProxTermsWriterPerField::skippingLongTerm() { +} - int32_t FreqProxTermsWriterPerField::compareTo(const LuceneObjectPtr& other) - { - return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); - } +int32_t FreqProxTermsWriterPerField::compareTo(const LuceneObjectPtr& other) { + return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); +} - void FreqProxTermsWriterPerField::reset() - { - // Record, up front, whether our in-RAM format will be with or without term freqs - omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; - payloadAttribute.reset(); - } +void FreqProxTermsWriterPerField::reset() { + // Record, up front, whether our in-RAM format will be with or without term freqs + omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; + payloadAttribute.reset(); +} - bool FreqProxTermsWriterPerField::start(Collection fields, int32_t count) - { - for (int32_t i = 0; i < count; ++i) - { - if (fields[i]->isIndexed()) - return true; +bool FreqProxTermsWriterPerField::start(Collection fields, int32_t count) { + for (int32_t i = 0; i < count; ++i) { + if (fields[i]->isIndexed()) { + return true; } - return false; } + return false; +} - void FreqProxTermsWriterPerField::start(const FieldablePtr& field) - { - if (fieldState->attributeSource->hasAttribute()) - payloadAttribute = fieldState->attributeSource->getAttribute(); - else - payloadAttribute.reset(); +void FreqProxTermsWriterPerField::start(const FieldablePtr& field) { + if (fieldState->attributeSource->hasAttribute()) { + payloadAttribute = fieldState->attributeSource->getAttribute(); + } else { + payloadAttribute.reset(); } +} - void FreqProxTermsWriterPerField::writeProx(const FreqProxTermsWriterPostingListPtr& p, int32_t proxCode) - { - PayloadPtr payload; - if (payloadAttribute) - payload = payloadAttribute->getPayload(); +void FreqProxTermsWriterPerField::writeProx(const FreqProxTermsWriterPostingListPtr& p, int32_t proxCode) { + PayloadPtr payload; + if (payloadAttribute) { + payload = payloadAttribute->getPayload(); + } - TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - if (payload && payload->length() > 0) - { - termsHashPerField->writeVInt(1, (proxCode << 1) | 1); - termsHashPerField->writeVInt(1, payload->length()); - termsHashPerField->writeBytes(1, payload->getData().get(), payload->getOffset(), payload->length()); - hasPayloads = true; - } - else - termsHashPerField->writeVInt(1, proxCode << 1); - p->lastPosition = fieldState->position; + if (payload && payload->length() > 0) { + termsHashPerField->writeVInt(1, (proxCode << 1) | 1); + termsHashPerField->writeVInt(1, payload->length()); + termsHashPerField->writeBytes(1, payload->getData().get(), payload->getOffset(), payload->length()); + hasPayloads = true; + } else { + termsHashPerField->writeVInt(1, proxCode << 1); } + p->lastPosition = fieldState->position; +} - void FreqProxTermsWriterPerField::newTerm(const RawPostingListPtr& p) - { - // First time we're seeing this term since the last flush - BOOST_ASSERT(docState->testPoint(L"FreqProxTermsWriterPerField.newTerm start")); - FreqProxTermsWriterPostingListPtr newPostingList(boost::static_pointer_cast(p)); - newPostingList->lastDocID = docState->docID; - if (omitTermFreqAndPositions) - newPostingList->lastDocCode = docState->docID; - else - { - newPostingList->lastDocCode = docState->docID << 1; - newPostingList->docFreq = 1; - writeProx(newPostingList, fieldState->position); - } +void FreqProxTermsWriterPerField::newTerm(const RawPostingListPtr& p) { + // First time we're seeing this term since the last flush + BOOST_ASSERT(docState->testPoint(L"FreqProxTermsWriterPerField.newTerm start")); + FreqProxTermsWriterPostingListPtr newPostingList(boost::static_pointer_cast(p)); + newPostingList->lastDocID = docState->docID; + if (omitTermFreqAndPositions) { + newPostingList->lastDocCode = docState->docID; + } else { + newPostingList->lastDocCode = docState->docID << 1; + newPostingList->docFreq = 1; + writeProx(newPostingList, fieldState->position); } +} - void FreqProxTermsWriterPerField::addTerm(const RawPostingListPtr& p) - { - BOOST_ASSERT(docState->testPoint(L"FreqProxTermsWriterPerField.addTerm start")); +void FreqProxTermsWriterPerField::addTerm(const RawPostingListPtr& p) { + BOOST_ASSERT(docState->testPoint(L"FreqProxTermsWriterPerField.addTerm start")); - FreqProxTermsWriterPostingListPtr addPostingList(boost::static_pointer_cast(p)); + FreqProxTermsWriterPostingListPtr addPostingList(boost::static_pointer_cast(p)); - BOOST_ASSERT(omitTermFreqAndPositions || addPostingList->docFreq > 0); - TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); + BOOST_ASSERT(omitTermFreqAndPositions || addPostingList->docFreq > 0); + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - if (omitTermFreqAndPositions) - { - if (docState->docID != addPostingList->lastDocID) - { - BOOST_ASSERT(docState->docID > addPostingList->lastDocID); - termsHashPerField->writeVInt(0, addPostingList->lastDocCode); - addPostingList->lastDocCode = docState->docID - addPostingList->lastDocID; - addPostingList->lastDocID = docState->docID; - } + if (omitTermFreqAndPositions) { + if (docState->docID != addPostingList->lastDocID) { + BOOST_ASSERT(docState->docID > addPostingList->lastDocID); + termsHashPerField->writeVInt(0, addPostingList->lastDocCode); + addPostingList->lastDocCode = docState->docID - addPostingList->lastDocID; + addPostingList->lastDocID = docState->docID; } - else - { - if (docState->docID != addPostingList->lastDocID) - { - BOOST_ASSERT(docState->docID > addPostingList->lastDocID); - // Term not yet seen in the current doc but previously seen in other doc(s) since - // the last flush - - // Now that we know doc freq for previous doc, write it & lastDocCode - if (addPostingList->docFreq == 1) - termsHashPerField->writeVInt(0, addPostingList->lastDocCode | 1); - else - { - termsHashPerField->writeVInt(0, addPostingList->lastDocCode); - termsHashPerField->writeVInt(0, addPostingList->docFreq); - } - addPostingList->docFreq = 1; - addPostingList->lastDocCode = (docState->docID - addPostingList->lastDocID) << 1; - addPostingList->lastDocID = docState->docID; - writeProx(addPostingList, fieldState->position); - } - else - { - ++addPostingList->docFreq; - writeProx(addPostingList, fieldState->position - addPostingList->lastPosition); + } else { + if (docState->docID != addPostingList->lastDocID) { + BOOST_ASSERT(docState->docID > addPostingList->lastDocID); + // Term not yet seen in the current doc but previously seen in other doc(s) since + // the last flush + + // Now that we know doc freq for previous doc, write it & lastDocCode + if (addPostingList->docFreq == 1) { + termsHashPerField->writeVInt(0, addPostingList->lastDocCode | 1); + } else { + termsHashPerField->writeVInt(0, addPostingList->lastDocCode); + termsHashPerField->writeVInt(0, addPostingList->docFreq); } + addPostingList->docFreq = 1; + addPostingList->lastDocCode = (docState->docID - addPostingList->lastDocID) << 1; + addPostingList->lastDocID = docState->docID; + writeProx(addPostingList, fieldState->position); + } else { + ++addPostingList->docFreq; + writeProx(addPostingList, fieldState->position - addPostingList->lastPosition); } } +} + +void FreqProxTermsWriterPerField::abort() { +} - void FreqProxTermsWriterPerField::abort() - { - } } diff --git a/src/core/index/FreqProxTermsWriterPerThread.cpp b/src/core/index/FreqProxTermsWriterPerThread.cpp index 4fd7d4cd..8c3a1626 100644 --- a/src/core/index/FreqProxTermsWriterPerThread.cpp +++ b/src/core/index/FreqProxTermsWriterPerThread.cpp @@ -9,33 +9,28 @@ #include "FreqProxTermsWriterPerField.h" #include "TermsHashPerThread.h" -namespace Lucene -{ - FreqProxTermsWriterPerThread::FreqProxTermsWriterPerThread(const TermsHashPerThreadPtr& perThread) - { - docState = perThread->docState; - _termsHashPerThread = perThread; - } - - FreqProxTermsWriterPerThread::~FreqProxTermsWriterPerThread() - { - } - - TermsHashConsumerPerFieldPtr FreqProxTermsWriterPerThread::addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) - { - return newLucene(termsHashPerField, shared_from_this(), fieldInfo); - } - - void FreqProxTermsWriterPerThread::startDocument() - { - } - - DocWriterPtr FreqProxTermsWriterPerThread::finishDocument() - { - return DocWriterPtr(); - } - - void FreqProxTermsWriterPerThread::abort() - { - } +namespace Lucene { + +FreqProxTermsWriterPerThread::FreqProxTermsWriterPerThread(const TermsHashPerThreadPtr& perThread) { + docState = perThread->docState; + _termsHashPerThread = perThread; +} + +FreqProxTermsWriterPerThread::~FreqProxTermsWriterPerThread() { +} + +TermsHashConsumerPerFieldPtr FreqProxTermsWriterPerThread::addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) { + return newLucene(termsHashPerField, shared_from_this(), fieldInfo); +} + +void FreqProxTermsWriterPerThread::startDocument() { +} + +DocWriterPtr FreqProxTermsWriterPerThread::finishDocument() { + return DocWriterPtr(); +} + +void FreqProxTermsWriterPerThread::abort() { +} + } diff --git a/src/core/index/IndexCommit.cpp b/src/core/index/IndexCommit.cpp index ca2059fe..466d425b 100644 --- a/src/core/index/IndexCommit.cpp +++ b/src/core/index/IndexCommit.cpp @@ -8,29 +8,28 @@ #include "IndexCommit.h" #include "Directory.h" -namespace Lucene -{ - IndexCommit::~IndexCommit() - { - } +namespace Lucene { - bool IndexCommit::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - IndexCommitPtr otherCommit(boost::dynamic_pointer_cast(other)); - if (!otherCommit) - return false; - return (otherCommit->getDirectory()->equals(getDirectory()) && otherCommit->getVersion() == getVersion()); - } +IndexCommit::~IndexCommit() { +} - int32_t IndexCommit::hashCode() - { - return (getDirectory()->hashCode() + (int32_t)getVersion()); +bool IndexCommit::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - - int64_t IndexCommit::getTimestamp() - { - return getDirectory()->fileModified(getSegmentsFileName()); + IndexCommitPtr otherCommit(boost::dynamic_pointer_cast(other)); + if (!otherCommit) { + return false; } + return (otherCommit->getDirectory()->equals(getDirectory()) && otherCommit->getVersion() == getVersion()); +} + +int32_t IndexCommit::hashCode() { + return (getDirectory()->hashCode() + (int32_t)getVersion()); +} + +int64_t IndexCommit::getTimestamp() { + return getDirectory()->fileModified(getSegmentsFileName()); +} + } diff --git a/src/core/index/IndexDeletionPolicy.cpp b/src/core/index/IndexDeletionPolicy.cpp index 8fae6f4a..ece07e52 100644 --- a/src/core/index/IndexDeletionPolicy.cpp +++ b/src/core/index/IndexDeletionPolicy.cpp @@ -7,13 +7,12 @@ #include "LuceneInc.h" #include "IndexDeletionPolicy.h" -namespace Lucene -{ - IndexDeletionPolicy::IndexDeletionPolicy() - { - } +namespace Lucene { + +IndexDeletionPolicy::IndexDeletionPolicy() { +} + +IndexDeletionPolicy::~IndexDeletionPolicy() { +} - IndexDeletionPolicy::~IndexDeletionPolicy() - { - } } diff --git a/src/core/index/IndexFileDeleter.cpp b/src/core/index/IndexFileDeleter.cpp index e0564512..cb30e2f4 100644 --- a/src/core/index/IndexFileDeleter.cpp +++ b/src/core/index/IndexFileDeleter.cpp @@ -20,514 +20,464 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// Change to true to see details of reference counts when infoStream != null - bool IndexFileDeleter::VERBOSE_REF_COUNTS = false; - - IndexFileDeleter::IndexFileDeleter(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& policy, const SegmentInfosPtr& segmentInfos, const InfoStreamPtr& infoStream, const DocumentsWriterPtr& docWriter, HashSet synced) - { - this->lastFiles = Collection< HashSet >::newInstance(); - this->commits = Collection::newInstance(); - this->commitsToDelete = Collection::newInstance(); - this->refCounts = MapStringRefCount::newInstance(); - this->docWriter = docWriter; - this->infoStream = infoStream; - this->synced = synced; - - if (infoStream) - message(L"init: current segments file is \"" + segmentInfos->getCurrentSegmentFileName()); - - this->policy = policy; - this->directory = directory; - - // First pass: walk the files and initialize our ref counts - int64_t currentGen = segmentInfos->getGeneration(); - IndexFileNameFilterPtr filter(IndexFileNameFilter::getFilter()); - - HashSet files(directory->listAll()); - CommitPointPtr currentCommitPoint; - - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { - if (filter->accept(L"", *fileName) && *fileName != IndexFileNames::SEGMENTS_GEN()) - { - // Add this file to refCounts with initial count 0 - getRefCount(*fileName); - - if (boost::starts_with(*fileName, IndexFileNames::SEGMENTS())) - { - // This is a commit (segments or segments_N), and it's valid (<= the max gen). - // Load it, then incref all files it refers to - if (infoStream) - message(L"init: load commit \"" + *fileName + L"\""); - SegmentInfosPtr sis(newLucene()); - try - { - sis->read(directory, *fileName); +namespace Lucene { + +/// Change to true to see details of reference counts when infoStream != null +bool IndexFileDeleter::VERBOSE_REF_COUNTS = false; + +IndexFileDeleter::IndexFileDeleter(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& policy, const SegmentInfosPtr& segmentInfos, const InfoStreamPtr& infoStream, const DocumentsWriterPtr& docWriter, HashSet synced) { + this->lastFiles = Collection< HashSet >::newInstance(); + this->commits = Collection::newInstance(); + this->commitsToDelete = Collection::newInstance(); + this->refCounts = MapStringRefCount::newInstance(); + this->docWriter = docWriter; + this->infoStream = infoStream; + this->synced = synced; + + if (infoStream) { + message(L"init: current segments file is \"" + segmentInfos->getCurrentSegmentFileName()); + } + + this->policy = policy; + this->directory = directory; + + // First pass: walk the files and initialize our ref counts + int64_t currentGen = segmentInfos->getGeneration(); + IndexFileNameFilterPtr filter(IndexFileNameFilter::getFilter()); + + HashSet files(directory->listAll()); + CommitPointPtr currentCommitPoint; + + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + if (filter->accept(L"", *fileName) && *fileName != IndexFileNames::SEGMENTS_GEN()) { + // Add this file to refCounts with initial count 0 + getRefCount(*fileName); + + if (boost::starts_with(*fileName, IndexFileNames::SEGMENTS())) { + // This is a commit (segments or segments_N), and it's valid (<= the max gen). + // Load it, then incref all files it refers to + if (infoStream) { + message(L"init: load commit \"" + *fileName + L"\""); + } + SegmentInfosPtr sis(newLucene()); + try { + sis->read(directory, *fileName); + } catch (IOException& e) { + if (SegmentInfos::generationFromSegmentsFileName(*fileName) <= currentGen) { + boost::throw_exception(e); + } else { + // Most likely we are opening an index that has an aborted "future" commit, + // so suppress exc in this case + sis.reset(); } - catch (IOException& e) - { - if (SegmentInfos::generationFromSegmentsFileName(*fileName) <= currentGen) - boost::throw_exception(e); - else - { - // Most likely we are opening an index that has an aborted "future" commit, - // so suppress exc in this case - sis.reset(); - } + } catch (...) { + if (infoStream) { + message(L"init: hit exception when loading commit \"" + *fileName + L"\"; skipping this commit point"); } - catch (...) - { - if (infoStream) - message(L"init: hit exception when loading commit \"" + *fileName + L"\"; skipping this commit point"); - sis.reset(); + sis.reset(); + } + if (sis) { + CommitPointPtr commitPoint(newLucene(commitsToDelete, directory, sis)); + if (sis->getGeneration() == segmentInfos->getGeneration()) { + currentCommitPoint = commitPoint; } - if (sis) - { - CommitPointPtr commitPoint(newLucene(commitsToDelete, directory, sis)); - if (sis->getGeneration() == segmentInfos->getGeneration()) - currentCommitPoint = commitPoint; - commits.add(commitPoint); - incRef(sis, true); - - if (!lastSegmentInfos || sis->getGeneration() > lastSegmentInfos->getGeneration()) - lastSegmentInfos = sis; + commits.add(commitPoint); + incRef(sis, true); + + if (!lastSegmentInfos || sis->getGeneration() > lastSegmentInfos->getGeneration()) { + lastSegmentInfos = sis; } } } } + } - if (!currentCommitPoint) - { - // We did not in fact see the segments_N file corresponding to the segmentInfos that was passed - // in. Yet, it must exist, because our caller holds the write lock. This can happen when the - // directory listing was stale (eg when index accessed via NFS client with stale directory listing - // cache). So we try now to explicitly open this commit point. - SegmentInfosPtr sis(newLucene()); - try - { - sis->read(directory, segmentInfos->getCurrentSegmentFileName()); - } - catch (LuceneException&) - { - boost::throw_exception(CorruptIndexException(L"failed to locate current segments_N file")); - } - if (infoStream) - message(L"forced open of current segments file " + segmentInfos->getCurrentSegmentFileName()); - currentCommitPoint = newLucene(commitsToDelete, directory, sis); - commits.add(currentCommitPoint); - incRef(sis, true); + if (!currentCommitPoint) { + // We did not in fact see the segments_N file corresponding to the segmentInfos that was passed + // in. Yet, it must exist, because our caller holds the write lock. This can happen when the + // directory listing was stale (eg when index accessed via NFS client with stale directory listing + // cache). So we try now to explicitly open this commit point. + SegmentInfosPtr sis(newLucene()); + try { + sis->read(directory, segmentInfos->getCurrentSegmentFileName()); + } catch (LuceneException&) { + boost::throw_exception(CorruptIndexException(L"failed to locate current segments_N file")); + } + if (infoStream) { + message(L"forced open of current segments file " + segmentInfos->getCurrentSegmentFileName()); } + currentCommitPoint = newLucene(commitsToDelete, directory, sis); + commits.add(currentCommitPoint); + incRef(sis, true); + } + + // We keep commits list in sorted order (oldest to newest) + std::sort(commits.begin(), commits.end(), luceneCompare()); - // We keep commits list in sorted order (oldest to newest) - std::sort(commits.begin(), commits.end(), luceneCompare()); - - // Now delete anything with ref count at 0. These are presumably abandoned files eg due to crash of IndexWriter. - for (MapStringRefCount::iterator entry = refCounts.begin(); entry != refCounts.end(); ++entry) - { - if (entry->second->count == 0) - { - if (infoStream) - message(L"init: removing unreferenced file \"" + entry->first + L"\""); - deleteFile(entry->first); + // Now delete anything with ref count at 0. These are presumably abandoned files eg due to crash of IndexWriter. + for (MapStringRefCount::iterator entry = refCounts.begin(); entry != refCounts.end(); ++entry) { + if (entry->second->count == 0) { + if (infoStream) { + message(L"init: removing unreferenced file \"" + entry->first + L"\""); } + deleteFile(entry->first); } + } - // Finally, give policy a chance to remove things on startup - policy->onInit(commits); + // Finally, give policy a chance to remove things on startup + policy->onInit(commits); - // Always protect the incoming segmentInfos since sometime it may not be the most recent commit - checkpoint(segmentInfos, false); + // Always protect the incoming segmentInfos since sometime it may not be the most recent commit + checkpoint(segmentInfos, false); - startingCommitDeleted = currentCommitPoint->isDeleted(); + startingCommitDeleted = currentCommitPoint->isDeleted(); - deleteCommits(); - } + deleteCommits(); +} - IndexFileDeleter::~IndexFileDeleter() - { - } +IndexFileDeleter::~IndexFileDeleter() { +} - void IndexFileDeleter::setInfoStream(const InfoStreamPtr& infoStream) - { - this->infoStream = infoStream; - } +void IndexFileDeleter::setInfoStream(const InfoStreamPtr& infoStream) { + this->infoStream = infoStream; +} - void IndexFileDeleter::message(const String& message) - { - if (infoStream) - { - *infoStream << L"IFD [" << DateTools::timeToString(MiscUtils::currentTimeMillis(), DateTools::RESOLUTION_SECOND); - *infoStream << L"; " << StringUtils::toString(LuceneThread::currentId()) << L"]: " << message << L"\n"; - } +void IndexFileDeleter::message(const String& message) { + if (infoStream) { + *infoStream << L"IFD [" << DateTools::timeToString(MiscUtils::currentTimeMillis(), DateTools::RESOLUTION_SECOND); + *infoStream << L"; " << StringUtils::toString(LuceneThread::currentId()) << L"]: " << message << L"\n"; } +} - SegmentInfosPtr IndexFileDeleter::getLastSegmentInfos() - { - return lastSegmentInfos; - } +SegmentInfosPtr IndexFileDeleter::getLastSegmentInfos() { + return lastSegmentInfos; +} - void IndexFileDeleter::deleteCommits() - { - if (!commitsToDelete.empty()) - { - // First decref all files that had been referred to by the now-deleted commits - for (Collection::iterator commit = commitsToDelete.begin(); commit != commitsToDelete.end(); ++commit) - { - if (infoStream) - message(L"deleteCommits: now decRef commit \"" + (*commit)->getSegmentsFileName() + L"\""); - for (HashSet::iterator file = (*commit)->files.begin(); file != (*commit)->files.end(); ++file) - decRef(*file); +void IndexFileDeleter::deleteCommits() { + if (!commitsToDelete.empty()) { + // First decref all files that had been referred to by the now-deleted commits + for (Collection::iterator commit = commitsToDelete.begin(); commit != commitsToDelete.end(); ++commit) { + if (infoStream) { + message(L"deleteCommits: now decRef commit \"" + (*commit)->getSegmentsFileName() + L"\""); } - commitsToDelete.clear(); - - // Now compact commits to remove deleted ones (preserving the sort) - int32_t size = commits.size(); - int32_t readFrom = 0; - int32_t writeTo = 0; - while (readFrom < size) - { - CommitPointPtr commit(boost::dynamic_pointer_cast(commits[readFrom])); - if (!commit->deleted) - { - if (writeTo != readFrom) - commits[writeTo] = commits[readFrom]; - ++writeTo; + for (HashSet::iterator file = (*commit)->files.begin(); file != (*commit)->files.end(); ++file) { + decRef(*file); + } + } + commitsToDelete.clear(); + + // Now compact commits to remove deleted ones (preserving the sort) + int32_t size = commits.size(); + int32_t readFrom = 0; + int32_t writeTo = 0; + while (readFrom < size) { + CommitPointPtr commit(boost::dynamic_pointer_cast(commits[readFrom])); + if (!commit->deleted) { + if (writeTo != readFrom) { + commits[writeTo] = commits[readFrom]; } - ++readFrom; + ++writeTo; } + ++readFrom; + } - while (size > writeTo) - { - commits.removeLast(); - --size; - } + while (size > writeTo) { + commits.removeLast(); + --size; } } +} - void IndexFileDeleter::refresh(const String& segmentName) - { - HashSet files(directory->listAll()); - IndexFileNameFilterPtr filter(IndexFileNameFilter::getFilter()); - String segmentPrefix1(segmentName + L"."); - String segmentPrefix2(segmentName + L"_"); +void IndexFileDeleter::refresh(const String& segmentName) { + HashSet files(directory->listAll()); + IndexFileNameFilterPtr filter(IndexFileNameFilter::getFilter()); + String segmentPrefix1(segmentName + L"."); + String segmentPrefix2(segmentName + L"_"); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { - if (filter->accept(L"", *fileName) && + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + if (filter->accept(L"", *fileName) && (segmentName.empty() || boost::starts_with(*fileName, segmentPrefix1) || boost::starts_with(*fileName, segmentPrefix2)) && - !refCounts.contains(*fileName) && *fileName != IndexFileNames::SEGMENTS_GEN()) - { - // Unreferenced file, so remove it - if (infoStream) - message(L"refresh [prefix=" + segmentName + L"]: removing newly created unreferenced file \"" + *fileName + L"\""); - deleteFile(*fileName); + !refCounts.contains(*fileName) && *fileName != IndexFileNames::SEGMENTS_GEN()) { + // Unreferenced file, so remove it + if (infoStream) { + message(L"refresh [prefix=" + segmentName + L"]: removing newly created unreferenced file \"" + *fileName + L"\""); } + deleteFile(*fileName); } } +} - void IndexFileDeleter::refresh() - { - refresh(L""); - } +void IndexFileDeleter::refresh() { + refresh(L""); +} - void IndexFileDeleter::close() - { - // DecRef old files from the last checkpoint, if any - for (Collection< HashSet >::iterator file = lastFiles.begin(); file != lastFiles.end(); ++file) - decRef(*file); - lastFiles.clear(); - deletePendingFiles(); +void IndexFileDeleter::close() { + // DecRef old files from the last checkpoint, if any + for (Collection< HashSet >::iterator file = lastFiles.begin(); file != lastFiles.end(); ++file) { + decRef(*file); } + lastFiles.clear(); + deletePendingFiles(); +} - void IndexFileDeleter::deletePendingFiles() - { - if (deletable) - { - HashSet oldDeletable(deletable); - deletable.reset(); - for (HashSet::iterator fileName = oldDeletable.begin(); fileName != oldDeletable.end(); ++fileName) - { - if (infoStream) - message(L"delete pending file " + *fileName); - deleteFile(*fileName); +void IndexFileDeleter::deletePendingFiles() { + if (deletable) { + HashSet oldDeletable(deletable); + deletable.reset(); + for (HashSet::iterator fileName = oldDeletable.begin(); fileName != oldDeletable.end(); ++fileName) { + if (infoStream) { + message(L"delete pending file " + *fileName); } + deleteFile(*fileName); } } +} - void IndexFileDeleter::checkpoint(const SegmentInfosPtr& segmentInfos, bool isCommit) - { - if (infoStream) - message(L"now checkpoint \"" + segmentInfos->getCurrentSegmentFileName() + L"\" [" + StringUtils::toString(segmentInfos->size()) + L" segments; isCommit = " + StringUtils::toString(isCommit) + L"]"); +void IndexFileDeleter::checkpoint(const SegmentInfosPtr& segmentInfos, bool isCommit) { + if (infoStream) { + message(L"now checkpoint \"" + segmentInfos->getCurrentSegmentFileName() + L"\" [" + StringUtils::toString(segmentInfos->size()) + L" segments; isCommit = " + StringUtils::toString(isCommit) + L"]"); + } - // Try again now to delete any previously un-deletable files (because they were in use, on Windows) - deletePendingFiles(); + // Try again now to delete any previously un-deletable files (because they were in use, on Windows) + deletePendingFiles(); - // Incref the files - incRef(segmentInfos, isCommit); + // Incref the files + incRef(segmentInfos, isCommit); - if (isCommit) - { - // Append to our commits list - commits.add(newLucene(commitsToDelete, directory, segmentInfos)); + if (isCommit) { + // Append to our commits list + commits.add(newLucene(commitsToDelete, directory, segmentInfos)); - // Tell policy so it can remove commits - policy->onCommit(commits); + // Tell policy so it can remove commits + policy->onCommit(commits); - // Decref files for commits that were deleted by the policy - deleteCommits(); - } - else - { - HashSet docWriterFiles; - if (docWriter) - { - docWriterFiles = docWriter->openFiles(); - if (docWriterFiles) - { - // We must incRef these files before decRef'ing last files to make sure we - // don't accidentally delete them - incRef(docWriterFiles); - } + // Decref files for commits that were deleted by the policy + deleteCommits(); + } else { + HashSet docWriterFiles; + if (docWriter) { + docWriterFiles = docWriter->openFiles(); + if (docWriterFiles) { + // We must incRef these files before decRef'ing last files to make sure we + // don't accidentally delete them + incRef(docWriterFiles); } + } - // DecRef old files from the last checkpoint, if any - for (Collection< HashSet >::iterator file = lastFiles.begin(); file != lastFiles.end(); ++file) - decRef(*file); - lastFiles.clear(); + // DecRef old files from the last checkpoint, if any + for (Collection< HashSet >::iterator file = lastFiles.begin(); file != lastFiles.end(); ++file) { + decRef(*file); + } + lastFiles.clear(); - // Save files so we can decr on next checkpoint/commit - lastFiles.add(segmentInfos->files(directory, false)); + // Save files so we can decr on next checkpoint/commit + lastFiles.add(segmentInfos->files(directory, false)); - if (docWriterFiles) - lastFiles.add(docWriterFiles); + if (docWriterFiles) { + lastFiles.add(docWriterFiles); } } +} - void IndexFileDeleter::incRef(const SegmentInfosPtr& segmentInfos, bool isCommit) - { - // If this is a commit point, also incRef the segments_N file - HashSet files(segmentInfos->files(directory, isCommit)); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - incRef(*fileName); +void IndexFileDeleter::incRef(const SegmentInfosPtr& segmentInfos, bool isCommit) { + // If this is a commit point, also incRef the segments_N file + HashSet files(segmentInfos->files(directory, isCommit)); + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + incRef(*fileName); } +} - void IndexFileDeleter::incRef(HashSet files) - { - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - incRef(*file); +void IndexFileDeleter::incRef(HashSet files) { + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { + incRef(*file); } +} - void IndexFileDeleter::incRef(const String& fileName) - { - RefCountPtr rc(getRefCount(fileName)); - if (infoStream && VERBOSE_REF_COUNTS) - message(L" IncRef \"" + fileName + L"\": pre-incr count is " + StringUtils::toString(rc->count)); - rc->IncRef(); +void IndexFileDeleter::incRef(const String& fileName) { + RefCountPtr rc(getRefCount(fileName)); + if (infoStream && VERBOSE_REF_COUNTS) { + message(L" IncRef \"" + fileName + L"\": pre-incr count is " + StringUtils::toString(rc->count)); } + rc->IncRef(); +} - void IndexFileDeleter::decRef(HashSet files) - { - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - decRef(*file); +void IndexFileDeleter::decRef(HashSet files) { + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { + decRef(*file); } +} - void IndexFileDeleter::decRef(const String& fileName) - { - RefCountPtr rc(getRefCount(fileName)); - if (infoStream && VERBOSE_REF_COUNTS) - message(L" DecRef \"" + fileName + L"\": pre-decr count is " + StringUtils::toString(rc->count)); - if (rc->DecRef() == 0) - { - // This file is no longer referenced by any past commit points nor by the in-memory SegmentInfos - deleteFile(fileName); - refCounts.remove(fileName); - - if (synced) - { - SyncLock syncLock(&synced); - synced.remove(fileName); - } - } +void IndexFileDeleter::decRef(const String& fileName) { + RefCountPtr rc(getRefCount(fileName)); + if (infoStream && VERBOSE_REF_COUNTS) { + message(L" DecRef \"" + fileName + L"\": pre-decr count is " + StringUtils::toString(rc->count)); } + if (rc->DecRef() == 0) { + // This file is no longer referenced by any past commit points nor by the in-memory SegmentInfos + deleteFile(fileName); + refCounts.remove(fileName); - void IndexFileDeleter::decRef(const SegmentInfosPtr& segmentInfos) - { - decRef(segmentInfos->files(directory, false)); + if (synced) { + SyncLock syncLock(&synced); + synced.remove(fileName); + } } +} - bool IndexFileDeleter::exists(const String& fileName) - { - return refCounts.contains(fileName) ? getRefCount(fileName)->count > 0 : false; - } +void IndexFileDeleter::decRef(const SegmentInfosPtr& segmentInfos) { + decRef(segmentInfos->files(directory, false)); +} - RefCountPtr IndexFileDeleter::getRefCount(const String& fileName) - { - RefCountPtr rc; - MapStringRefCount::iterator ref = refCounts.find(fileName); - if (ref == refCounts.end()) - { - rc = newLucene(fileName); - refCounts.put(fileName, rc); - } - else - rc = ref->second; - return rc; +bool IndexFileDeleter::exists(const String& fileName) { + return refCounts.contains(fileName) ? getRefCount(fileName)->count > 0 : false; +} + +RefCountPtr IndexFileDeleter::getRefCount(const String& fileName) { + RefCountPtr rc; + MapStringRefCount::iterator ref = refCounts.find(fileName); + if (ref == refCounts.end()) { + rc = newLucene(fileName); + refCounts.put(fileName, rc); + } else { + rc = ref->second; } + return rc; +} - void IndexFileDeleter::deleteFiles(HashSet files) - { - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - deleteFile(*file); +void IndexFileDeleter::deleteFiles(HashSet files) { + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { + deleteFile(*file); } +} - void IndexFileDeleter::deleteNewFiles(HashSet files) - { - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { - if (!refCounts.contains(*fileName)) - { - if (infoStream) - message(L"delete new file \"" + *fileName + L"\""); - deleteFile(*fileName); +void IndexFileDeleter::deleteNewFiles(HashSet files) { + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + if (!refCounts.contains(*fileName)) { + if (infoStream) { + message(L"delete new file \"" + *fileName + L"\""); } + deleteFile(*fileName); } } +} - void IndexFileDeleter::deleteFile(const String& fileName) - { - try - { - if (infoStream) - message(L"delete \"" + fileName + L"\""); - directory->deleteFile(fileName); +void IndexFileDeleter::deleteFile(const String& fileName) { + try { + if (infoStream) { + message(L"delete \"" + fileName + L"\""); } - catch (IOException& e) // if delete fails - { - if (directory->fileExists(fileName)) // if delete fails - { - // Some operating systems (eg. Windows) don't permit a file to be deleted while it is opened - // for read (eg. by another process or thread). So we assume that when a delete fails it is - // because the file is open in another process, and queue the file for subsequent deletion. - if (infoStream) - message(L"IndexFileDeleter: unable to remove file \"" + fileName + L"\": " + e.getError() + L"; Will re-try later."); - if (!deletable) - deletable = HashSet::newInstance(); - deletable.add(fileName); // add to deletable + directory->deleteFile(fileName); + } catch (IOException& e) { // if delete fails + if (directory->fileExists(fileName)) { // if delete fails + // Some operating systems (eg. Windows) don't permit a file to be deleted while it is opened + // for read (eg. by another process or thread). So we assume that when a delete fails it is + // because the file is open in another process, and queue the file for subsequent deletion. + if (infoStream) { + message(L"IndexFileDeleter: unable to remove file \"" + fileName + L"\": " + e.getError() + L"; Will re-try later."); } + if (!deletable) { + deletable = HashSet::newInstance(); + } + deletable.add(fileName); // add to deletable } } +} - RefCount::RefCount(const String& fileName) - { - initDone = false; - count = 0; - this->fileName = fileName; - } - - RefCount::~RefCount() - { - } +RefCount::RefCount(const String& fileName) { + initDone = false; + count = 0; + this->fileName = fileName; +} - int32_t RefCount::IncRef() - { - if (!initDone) - initDone = true; - else - BOOST_ASSERT(count > 0); - return ++count; - } +RefCount::~RefCount() { +} - int32_t RefCount::DecRef() - { +int32_t RefCount::IncRef() { + if (!initDone) { + initDone = true; + } else { BOOST_ASSERT(count > 0); - return --count; } + return ++count; +} - CommitPoint::CommitPoint(Collection commitsToDelete, const DirectoryPtr& directory, const SegmentInfosPtr& segmentInfos) - { - deleted = false; - - this->directory = directory; - this->commitsToDelete = commitsToDelete; - userData = segmentInfos->getUserData(); - segmentsFileName = segmentInfos->getCurrentSegmentFileName(); - version = segmentInfos->getVersion(); - generation = segmentInfos->getGeneration(); - HashSet files(segmentInfos->files(directory, true)); - this->files = HashSet::newInstance(files.begin(), files.end()); - gen = segmentInfos->getGeneration(); - _isOptimized = (segmentInfos->size() == 1 && !segmentInfos->info(0)->hasDeletions()); - - BOOST_ASSERT(!segmentInfos->hasExternalSegments(directory)); - } +int32_t RefCount::DecRef() { + BOOST_ASSERT(count > 0); + return --count; +} - CommitPoint::~CommitPoint() - { - } +CommitPoint::CommitPoint(Collection commitsToDelete, const DirectoryPtr& directory, const SegmentInfosPtr& segmentInfos) { + deleted = false; + + this->directory = directory; + this->commitsToDelete = commitsToDelete; + userData = segmentInfos->getUserData(); + segmentsFileName = segmentInfos->getCurrentSegmentFileName(); + version = segmentInfos->getVersion(); + generation = segmentInfos->getGeneration(); + HashSet files(segmentInfos->files(directory, true)); + this->files = HashSet::newInstance(files.begin(), files.end()); + gen = segmentInfos->getGeneration(); + _isOptimized = (segmentInfos->size() == 1 && !segmentInfos->info(0)->hasDeletions()); + + BOOST_ASSERT(!segmentInfos->hasExternalSegments(directory)); +} - String CommitPoint::toString() - { - return L"IndexFileDeleter::CommitPoint(" + segmentsFileName + L")"; - } +CommitPoint::~CommitPoint() { +} - bool CommitPoint::isOptimized() - { - return _isOptimized; - } +String CommitPoint::toString() { + return L"IndexFileDeleter::CommitPoint(" + segmentsFileName + L")"; +} - String CommitPoint::getSegmentsFileName() - { - return segmentsFileName; - } +bool CommitPoint::isOptimized() { + return _isOptimized; +} - HashSet CommitPoint::getFileNames() - { - return files; - } +String CommitPoint::getSegmentsFileName() { + return segmentsFileName; +} - DirectoryPtr CommitPoint::getDirectory() - { - return directory; - } +HashSet CommitPoint::getFileNames() { + return files; +} - int64_t CommitPoint::getVersion() - { - return version; - } +DirectoryPtr CommitPoint::getDirectory() { + return directory; +} - int64_t CommitPoint::getGeneration() - { - return generation; - } +int64_t CommitPoint::getVersion() { + return version; +} - MapStringString CommitPoint::getUserData() - { - return userData; - } +int64_t CommitPoint::getGeneration() { + return generation; +} - void CommitPoint::deleteCommit() - { - if (!deleted) - { - deleted = true; - commitsToDelete.add(shared_from_this()); - } - } +MapStringString CommitPoint::getUserData() { + return userData; +} - bool CommitPoint::isDeleted() - { - return deleted; +void CommitPoint::deleteCommit() { + if (!deleted) { + deleted = true; + commitsToDelete.add(shared_from_this()); } +} + +bool CommitPoint::isDeleted() { + return deleted; +} - int32_t CommitPoint::compareTo(const LuceneObjectPtr& other) - { - CommitPointPtr otherCommit(boost::static_pointer_cast(other)); - if (gen < otherCommit->gen) - return -1; - if (gen > otherCommit->gen) - return 1; - return 0; +int32_t CommitPoint::compareTo(const LuceneObjectPtr& other) { + CommitPointPtr otherCommit(boost::static_pointer_cast(other)); + if (gen < otherCommit->gen) { + return -1; } + if (gen > otherCommit->gen) { + return 1; + } + return 0; +} + } diff --git a/src/core/index/IndexFileNameFilter.cpp b/src/core/index/IndexFileNameFilter.cpp index 189d1800..9cc9db3e 100644 --- a/src/core/index/IndexFileNameFilter.cpp +++ b/src/core/index/IndexFileNameFilter.cpp @@ -10,56 +10,53 @@ #include "IndexFileNameFilter.h" #include "IndexFileNames.h" -namespace Lucene -{ - bool IndexFileNameFilter::accept(const String& directory, const String& name) - { - String::size_type i = name.find_last_of(L'.'); - if (i != String::npos) - { - String extension(name.substr(i+1)); - if (IndexFileNames::INDEX_EXTENSIONS().contains(extension)) +namespace Lucene { + +bool IndexFileNameFilter::accept(const String& directory, const String& name) { + String::size_type i = name.find_last_of(L'.'); + if (i != String::npos) { + String extension(name.substr(i+1)); + if (IndexFileNames::INDEX_EXTENSIONS().contains(extension)) { + return true; + } else if (!extension.empty()) { + if (extension[0] == L'f' && boost::regex_search(extension, boost::wregex(L"f\\d+"))) { return true; - else if (!extension.empty()) - { - if (extension[0] == L'f' && boost::regex_search(extension, boost::wregex(L"f\\d+"))) - return true; - if (extension[0] == L's' && boost::regex_search(extension, boost::wregex(L"s\\d+"))) - return true; } - } - else - { - if (name == IndexFileNames::DELETABLE()) - return true; - if (boost::starts_with(name, IndexFileNames::SEGMENTS())) + if (extension[0] == L's' && boost::regex_search(extension, boost::wregex(L"s\\d+"))) { return true; + } + } + } else { + if (name == IndexFileNames::DELETABLE()) { + return true; + } + if (boost::starts_with(name, IndexFileNames::SEGMENTS())) { + return true; } - return false; } + return false; +} - bool IndexFileNameFilter::isCFSFile(const String& name) - { - String::size_type i = name.find_last_of(L'.'); - if (i != String::npos) - { - String extension(name.substr(i+1)); - if (IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE().contains(extension)) - return true; - else if (!extension.empty() && extension[0] == L'f' && boost::regex_search(extension, boost::wregex(L"f\\d+"))) - return true; +bool IndexFileNameFilter::isCFSFile(const String& name) { + String::size_type i = name.find_last_of(L'.'); + if (i != String::npos) { + String extension(name.substr(i+1)); + if (IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE().contains(extension)) { + return true; + } else if (!extension.empty() && extension[0] == L'f' && boost::regex_search(extension, boost::wregex(L"f\\d+"))) { + return true; } - return false; } + return false; +} - IndexFileNameFilterPtr IndexFileNameFilter::getFilter() - { - static IndexFileNameFilterPtr singleton; - if (!singleton) - { - singleton = newLucene(); - CycleCheck::addStatic(singleton); - } - return singleton; +IndexFileNameFilterPtr IndexFileNameFilter::getFilter() { + static IndexFileNameFilterPtr singleton; + if (!singleton) { + singleton = newLucene(); + CycleCheck::addStatic(singleton); } + return singleton; +} + } diff --git a/src/core/index/IndexFileNames.cpp b/src/core/index/IndexFileNames.cpp index 3dcba767..c140cd1a 100644 --- a/src/core/index/IndexFileNames.cpp +++ b/src/core/index/IndexFileNames.cpp @@ -10,263 +10,230 @@ #include "SegmentInfo.h" #include "StringUtils.h" -namespace Lucene -{ - IndexFileNames::~IndexFileNames() - { - } +namespace Lucene { - const String& IndexFileNames::SEGMENTS() - { - static String _SEGMENTS(L"segments"); - return _SEGMENTS; - } +IndexFileNames::~IndexFileNames() { +} - const String& IndexFileNames::SEGMENTS_GEN() - { - static String _SEGMENTS_GEN(L"segments.gen"); - return _SEGMENTS_GEN; - } +const String& IndexFileNames::SEGMENTS() { + static String _SEGMENTS(L"segments"); + return _SEGMENTS; +} - const String& IndexFileNames::DELETABLE() - { - static String _DELETABLE(L"deletable"); - return _DELETABLE; - } +const String& IndexFileNames::SEGMENTS_GEN() { + static String _SEGMENTS_GEN(L"segments.gen"); + return _SEGMENTS_GEN; +} - const String& IndexFileNames::NORMS_EXTENSION() - { - static String _NORMS_EXTENSION(L"nrm"); - return _NORMS_EXTENSION; - } +const String& IndexFileNames::DELETABLE() { + static String _DELETABLE(L"deletable"); + return _DELETABLE; +} - const String& IndexFileNames::FREQ_EXTENSION() - { - static String _FREQ_EXTENSION(L"frq"); - return _FREQ_EXTENSION; - } +const String& IndexFileNames::NORMS_EXTENSION() { + static String _NORMS_EXTENSION(L"nrm"); + return _NORMS_EXTENSION; +} - const String& IndexFileNames::PROX_EXTENSION() - { - static String _PROX_EXTENSION(L"prx"); - return _PROX_EXTENSION; - } +const String& IndexFileNames::FREQ_EXTENSION() { + static String _FREQ_EXTENSION(L"frq"); + return _FREQ_EXTENSION; +} - const String& IndexFileNames::TERMS_EXTENSION() - { - static String _TERMS_EXTENSION(L"tis"); - return _TERMS_EXTENSION; - } +const String& IndexFileNames::PROX_EXTENSION() { + static String _PROX_EXTENSION(L"prx"); + return _PROX_EXTENSION; +} - const String& IndexFileNames::TERMS_INDEX_EXTENSION() - { - static String _TERMS_INDEX_EXTENSION(L"tii"); - return _TERMS_INDEX_EXTENSION; - } +const String& IndexFileNames::TERMS_EXTENSION() { + static String _TERMS_EXTENSION(L"tis"); + return _TERMS_EXTENSION; +} - const String& IndexFileNames::FIELDS_INDEX_EXTENSION() - { - static String _FIELDS_INDEX_EXTENSION(L"fdx"); - return _FIELDS_INDEX_EXTENSION; - } +const String& IndexFileNames::TERMS_INDEX_EXTENSION() { + static String _TERMS_INDEX_EXTENSION(L"tii"); + return _TERMS_INDEX_EXTENSION; +} - const String& IndexFileNames::FIELDS_EXTENSION() - { - static String _FIELDS_EXTENSION(L"fdt"); - return _FIELDS_EXTENSION; - } +const String& IndexFileNames::FIELDS_INDEX_EXTENSION() { + static String _FIELDS_INDEX_EXTENSION(L"fdx"); + return _FIELDS_INDEX_EXTENSION; +} - const String& IndexFileNames::VECTORS_FIELDS_EXTENSION() - { - static String _VECTORS_FIELDS_EXTENSION(L"tvf"); - return _VECTORS_FIELDS_EXTENSION; - } +const String& IndexFileNames::FIELDS_EXTENSION() { + static String _FIELDS_EXTENSION(L"fdt"); + return _FIELDS_EXTENSION; +} - const String& IndexFileNames::VECTORS_DOCUMENTS_EXTENSION() - { - static String _VECTORS_DOCUMENTS_EXTENSION(L"tvd"); - return _VECTORS_DOCUMENTS_EXTENSION; - } +const String& IndexFileNames::VECTORS_FIELDS_EXTENSION() { + static String _VECTORS_FIELDS_EXTENSION(L"tvf"); + return _VECTORS_FIELDS_EXTENSION; +} - const String& IndexFileNames::VECTORS_INDEX_EXTENSION() - { - static String _VECTORS_INDEX_EXTENSION(L"tvx"); - return _VECTORS_INDEX_EXTENSION; - } +const String& IndexFileNames::VECTORS_DOCUMENTS_EXTENSION() { + static String _VECTORS_DOCUMENTS_EXTENSION(L"tvd"); + return _VECTORS_DOCUMENTS_EXTENSION; +} - const String& IndexFileNames::COMPOUND_FILE_EXTENSION() - { - static String _COMPOUND_FILE_EXTENSION(L"cfs"); - return _COMPOUND_FILE_EXTENSION; - } +const String& IndexFileNames::VECTORS_INDEX_EXTENSION() { + static String _VECTORS_INDEX_EXTENSION(L"tvx"); + return _VECTORS_INDEX_EXTENSION; +} - const String& IndexFileNames::COMPOUND_FILE_STORE_EXTENSION() - { - static String _COMPOUND_FILE_STORE_EXTENSION(L"cfx"); - return _COMPOUND_FILE_STORE_EXTENSION; - } +const String& IndexFileNames::COMPOUND_FILE_EXTENSION() { + static String _COMPOUND_FILE_EXTENSION(L"cfs"); + return _COMPOUND_FILE_EXTENSION; +} - const String& IndexFileNames::DELETES_EXTENSION() - { - static String _DELETES_EXTENSION(L"del"); - return _DELETES_EXTENSION; - } +const String& IndexFileNames::COMPOUND_FILE_STORE_EXTENSION() { + static String _COMPOUND_FILE_STORE_EXTENSION(L"cfx"); + return _COMPOUND_FILE_STORE_EXTENSION; +} - const String& IndexFileNames::FIELD_INFOS_EXTENSION() - { - static String _FIELD_INFOS_EXTENSION(L"fnm"); - return _FIELD_INFOS_EXTENSION; - } +const String& IndexFileNames::DELETES_EXTENSION() { + static String _DELETES_EXTENSION(L"del"); + return _DELETES_EXTENSION; +} - const String& IndexFileNames::PLAIN_NORMS_EXTENSION() - { - static String _PLAIN_NORMS_EXTENSION(L"f"); - return _PLAIN_NORMS_EXTENSION; - } +const String& IndexFileNames::FIELD_INFOS_EXTENSION() { + static String _FIELD_INFOS_EXTENSION(L"fnm"); + return _FIELD_INFOS_EXTENSION; +} - const String& IndexFileNames::SEPARATE_NORMS_EXTENSION() - { - static String _SEPARATE_NORMS_EXTENSION(L"s"); - return _SEPARATE_NORMS_EXTENSION; - } +const String& IndexFileNames::PLAIN_NORMS_EXTENSION() { + static String _PLAIN_NORMS_EXTENSION(L"f"); + return _PLAIN_NORMS_EXTENSION; +} - const String& IndexFileNames::GEN_EXTENSION() - { - static String _GEN_EXTENSION(L"gen"); - return _GEN_EXTENSION; - } +const String& IndexFileNames::SEPARATE_NORMS_EXTENSION() { + static String _SEPARATE_NORMS_EXTENSION(L"s"); + return _SEPARATE_NORMS_EXTENSION; +} - const HashSet IndexFileNames::INDEX_EXTENSIONS() - { - static HashSet _INDEX_EXTENSIONS; - if (!_INDEX_EXTENSIONS) - { - _INDEX_EXTENSIONS = HashSet::newInstance(); - _INDEX_EXTENSIONS.add(COMPOUND_FILE_EXTENSION()); - _INDEX_EXTENSIONS.add(FIELD_INFOS_EXTENSION()); - _INDEX_EXTENSIONS.add(FIELDS_INDEX_EXTENSION()); - _INDEX_EXTENSIONS.add(FIELDS_EXTENSION()); - _INDEX_EXTENSIONS.add(TERMS_INDEX_EXTENSION()); - _INDEX_EXTENSIONS.add(TERMS_EXTENSION()); - _INDEX_EXTENSIONS.add(FREQ_EXTENSION()); - _INDEX_EXTENSIONS.add(PROX_EXTENSION()); - _INDEX_EXTENSIONS.add(DELETES_EXTENSION()); - _INDEX_EXTENSIONS.add(VECTORS_INDEX_EXTENSION()); - _INDEX_EXTENSIONS.add(VECTORS_DOCUMENTS_EXTENSION()); - _INDEX_EXTENSIONS.add(VECTORS_FIELDS_EXTENSION()); - _INDEX_EXTENSIONS.add(GEN_EXTENSION()); - _INDEX_EXTENSIONS.add(NORMS_EXTENSION()); - _INDEX_EXTENSIONS.add(COMPOUND_FILE_STORE_EXTENSION()); - } - return _INDEX_EXTENSIONS; - }; - - const HashSet IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE() - { - static HashSet _INDEX_EXTENSIONS_IN_COMPOUND_FILE; - if (!_INDEX_EXTENSIONS_IN_COMPOUND_FILE) - { - _INDEX_EXTENSIONS_IN_COMPOUND_FILE = HashSet::newInstance(); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FIELD_INFOS_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FIELDS_INDEX_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FIELDS_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(TERMS_INDEX_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(TERMS_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FREQ_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(PROX_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(VECTORS_INDEX_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(VECTORS_DOCUMENTS_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(VECTORS_FIELDS_EXTENSION()); - _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(NORMS_EXTENSION()); - } - return _INDEX_EXTENSIONS_IN_COMPOUND_FILE; - }; - - const HashSet IndexFileNames::STORE_INDEX_EXTENSIONS() - { - static HashSet _STORE_INDEX_EXTENSIONS; - if (!_STORE_INDEX_EXTENSIONS) - { - _STORE_INDEX_EXTENSIONS = HashSet::newInstance(); - _STORE_INDEX_EXTENSIONS.add(VECTORS_INDEX_EXTENSION()); - _STORE_INDEX_EXTENSIONS.add(VECTORS_FIELDS_EXTENSION()); - _STORE_INDEX_EXTENSIONS.add(VECTORS_DOCUMENTS_EXTENSION()); - _STORE_INDEX_EXTENSIONS.add(FIELDS_INDEX_EXTENSION()); - _STORE_INDEX_EXTENSIONS.add(FIELDS_EXTENSION()); - } - return _STORE_INDEX_EXTENSIONS; - }; - - const HashSet IndexFileNames::NON_STORE_INDEX_EXTENSIONS() - { - static HashSet _NON_STORE_INDEX_EXTENSIONS; - if (!_NON_STORE_INDEX_EXTENSIONS) - { - _NON_STORE_INDEX_EXTENSIONS = HashSet::newInstance(); - _NON_STORE_INDEX_EXTENSIONS.add(FIELD_INFOS_EXTENSION()); - _NON_STORE_INDEX_EXTENSIONS.add(FREQ_EXTENSION()); - _NON_STORE_INDEX_EXTENSIONS.add(PROX_EXTENSION()); - _NON_STORE_INDEX_EXTENSIONS.add(TERMS_EXTENSION()); - _NON_STORE_INDEX_EXTENSIONS.add(TERMS_INDEX_EXTENSION()); - _NON_STORE_INDEX_EXTENSIONS.add(NORMS_EXTENSION()); - } - return _NON_STORE_INDEX_EXTENSIONS; - }; - - const HashSet IndexFileNames::COMPOUND_EXTENSIONS() - { - static HashSet _COMPOUND_EXTENSIONS; - if (!_COMPOUND_EXTENSIONS) - { - _COMPOUND_EXTENSIONS = HashSet::newInstance(); - _COMPOUND_EXTENSIONS.add(FIELD_INFOS_EXTENSION()); - _COMPOUND_EXTENSIONS.add(FREQ_EXTENSION()); - _COMPOUND_EXTENSIONS.add(PROX_EXTENSION()); - _COMPOUND_EXTENSIONS.add(FIELDS_INDEX_EXTENSION()); - _COMPOUND_EXTENSIONS.add(FIELDS_EXTENSION()); - _COMPOUND_EXTENSIONS.add(TERMS_INDEX_EXTENSION()); - _COMPOUND_EXTENSIONS.add(TERMS_EXTENSION()); - } - return _COMPOUND_EXTENSIONS; - }; - - const HashSet IndexFileNames::VECTOR_EXTENSIONS() - { - static HashSet _VECTOR_EXTENSIONS; - if (!_VECTOR_EXTENSIONS) - { - _VECTOR_EXTENSIONS = HashSet::newInstance(); - _VECTOR_EXTENSIONS.add(VECTORS_INDEX_EXTENSION()); - _VECTOR_EXTENSIONS.add(VECTORS_DOCUMENTS_EXTENSION()); - _VECTOR_EXTENSIONS.add(VECTORS_FIELDS_EXTENSION()); - } - return _VECTOR_EXTENSIONS; - }; - - String IndexFileNames::fileNameFromGeneration(const String& base, const String& extension, int64_t gen) - { - if (gen == SegmentInfo::NO) - return L""; - else if (gen == SegmentInfo::WITHOUT_GEN) - return base + extension; - else - return base + L"_" + StringUtils::toString(gen, StringUtils::CHARACTER_MAX_RADIX) + extension; +const String& IndexFileNames::GEN_EXTENSION() { + static String _GEN_EXTENSION(L"gen"); + return _GEN_EXTENSION; +} + +const HashSet IndexFileNames::INDEX_EXTENSIONS() { + static HashSet _INDEX_EXTENSIONS; + if (!_INDEX_EXTENSIONS) { + _INDEX_EXTENSIONS = HashSet::newInstance(); + _INDEX_EXTENSIONS.add(COMPOUND_FILE_EXTENSION()); + _INDEX_EXTENSIONS.add(FIELD_INFOS_EXTENSION()); + _INDEX_EXTENSIONS.add(FIELDS_INDEX_EXTENSION()); + _INDEX_EXTENSIONS.add(FIELDS_EXTENSION()); + _INDEX_EXTENSIONS.add(TERMS_INDEX_EXTENSION()); + _INDEX_EXTENSIONS.add(TERMS_EXTENSION()); + _INDEX_EXTENSIONS.add(FREQ_EXTENSION()); + _INDEX_EXTENSIONS.add(PROX_EXTENSION()); + _INDEX_EXTENSIONS.add(DELETES_EXTENSION()); + _INDEX_EXTENSIONS.add(VECTORS_INDEX_EXTENSION()); + _INDEX_EXTENSIONS.add(VECTORS_DOCUMENTS_EXTENSION()); + _INDEX_EXTENSIONS.add(VECTORS_FIELDS_EXTENSION()); + _INDEX_EXTENSIONS.add(GEN_EXTENSION()); + _INDEX_EXTENSIONS.add(NORMS_EXTENSION()); + _INDEX_EXTENSIONS.add(COMPOUND_FILE_STORE_EXTENSION()); + } + return _INDEX_EXTENSIONS; +}; + +const HashSet IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE() { + static HashSet _INDEX_EXTENSIONS_IN_COMPOUND_FILE; + if (!_INDEX_EXTENSIONS_IN_COMPOUND_FILE) { + _INDEX_EXTENSIONS_IN_COMPOUND_FILE = HashSet::newInstance(); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FIELD_INFOS_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FIELDS_INDEX_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FIELDS_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(TERMS_INDEX_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(TERMS_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(FREQ_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(PROX_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(VECTORS_INDEX_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(VECTORS_DOCUMENTS_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(VECTORS_FIELDS_EXTENSION()); + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.add(NORMS_EXTENSION()); + } + return _INDEX_EXTENSIONS_IN_COMPOUND_FILE; +}; + +const HashSet IndexFileNames::STORE_INDEX_EXTENSIONS() { + static HashSet _STORE_INDEX_EXTENSIONS; + if (!_STORE_INDEX_EXTENSIONS) { + _STORE_INDEX_EXTENSIONS = HashSet::newInstance(); + _STORE_INDEX_EXTENSIONS.add(VECTORS_INDEX_EXTENSION()); + _STORE_INDEX_EXTENSIONS.add(VECTORS_FIELDS_EXTENSION()); + _STORE_INDEX_EXTENSIONS.add(VECTORS_DOCUMENTS_EXTENSION()); + _STORE_INDEX_EXTENSIONS.add(FIELDS_INDEX_EXTENSION()); + _STORE_INDEX_EXTENSIONS.add(FIELDS_EXTENSION()); + } + return _STORE_INDEX_EXTENSIONS; +}; + +const HashSet IndexFileNames::NON_STORE_INDEX_EXTENSIONS() { + static HashSet _NON_STORE_INDEX_EXTENSIONS; + if (!_NON_STORE_INDEX_EXTENSIONS) { + _NON_STORE_INDEX_EXTENSIONS = HashSet::newInstance(); + _NON_STORE_INDEX_EXTENSIONS.add(FIELD_INFOS_EXTENSION()); + _NON_STORE_INDEX_EXTENSIONS.add(FREQ_EXTENSION()); + _NON_STORE_INDEX_EXTENSIONS.add(PROX_EXTENSION()); + _NON_STORE_INDEX_EXTENSIONS.add(TERMS_EXTENSION()); + _NON_STORE_INDEX_EXTENSIONS.add(TERMS_INDEX_EXTENSION()); + _NON_STORE_INDEX_EXTENSIONS.add(NORMS_EXTENSION()); + } + return _NON_STORE_INDEX_EXTENSIONS; +}; + +const HashSet IndexFileNames::COMPOUND_EXTENSIONS() { + static HashSet _COMPOUND_EXTENSIONS; + if (!_COMPOUND_EXTENSIONS) { + _COMPOUND_EXTENSIONS = HashSet::newInstance(); + _COMPOUND_EXTENSIONS.add(FIELD_INFOS_EXTENSION()); + _COMPOUND_EXTENSIONS.add(FREQ_EXTENSION()); + _COMPOUND_EXTENSIONS.add(PROX_EXTENSION()); + _COMPOUND_EXTENSIONS.add(FIELDS_INDEX_EXTENSION()); + _COMPOUND_EXTENSIONS.add(FIELDS_EXTENSION()); + _COMPOUND_EXTENSIONS.add(TERMS_INDEX_EXTENSION()); + _COMPOUND_EXTENSIONS.add(TERMS_EXTENSION()); + } + return _COMPOUND_EXTENSIONS; +}; + +const HashSet IndexFileNames::VECTOR_EXTENSIONS() { + static HashSet _VECTOR_EXTENSIONS; + if (!_VECTOR_EXTENSIONS) { + _VECTOR_EXTENSIONS = HashSet::newInstance(); + _VECTOR_EXTENSIONS.add(VECTORS_INDEX_EXTENSION()); + _VECTOR_EXTENSIONS.add(VECTORS_DOCUMENTS_EXTENSION()); + _VECTOR_EXTENSIONS.add(VECTORS_FIELDS_EXTENSION()); + } + return _VECTOR_EXTENSIONS; +}; + +String IndexFileNames::fileNameFromGeneration(const String& base, const String& extension, int64_t gen) { + if (gen == SegmentInfo::NO) { + return L""; + } else if (gen == SegmentInfo::WITHOUT_GEN) { + return base + extension; + } else { + return base + L"_" + StringUtils::toString(gen, StringUtils::CHARACTER_MAX_RADIX) + extension; } +} - bool IndexFileNames::isDocStoreFile(const String& fileName) - { - if (boost::ends_with(fileName, COMPOUND_FILE_STORE_EXTENSION())) +bool IndexFileNames::isDocStoreFile(const String& fileName) { + if (boost::ends_with(fileName, COMPOUND_FILE_STORE_EXTENSION())) { + return true; + } + for (HashSet::iterator index = STORE_INDEX_EXTENSIONS().begin(); index != STORE_INDEX_EXTENSIONS().end(); ++index) { + if (boost::ends_with(fileName, *index)) { return true; - for (HashSet::iterator index = STORE_INDEX_EXTENSIONS().begin(); index != STORE_INDEX_EXTENSIONS().end(); ++index) - { - if (boost::ends_with(fileName, *index)) - return true; } - return false; } + return false; +} + +String IndexFileNames::segmentFileName(const String& segmentName, const String& ext) { + return segmentName + L"." + ext; +} - String IndexFileNames::segmentFileName(const String& segmentName, const String& ext) - { - return segmentName + L"." + ext; - } } diff --git a/src/core/index/IndexReader.cpp b/src/core/index/IndexReader.cpp index 08561449..a6cd3372 100644 --- a/src/core/index/IndexReader.cpp +++ b/src/core/index/IndexReader.cpp @@ -18,447 +18,386 @@ #include "FileUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t IndexReader::DEFAULT_TERMS_INDEX_DIVISOR = 1; - - IndexReader::IndexReader() - { - refCount = 1; - closed = false; - _hasChanges = false; - } +namespace Lucene { - IndexReader::~IndexReader() - { - } +const int32_t IndexReader::DEFAULT_TERMS_INDEX_DIVISOR = 1; - int32_t IndexReader::getRefCount() - { - SyncLock syncLock(this); - return refCount; - } +IndexReader::IndexReader() { + refCount = 1; + closed = false; + _hasChanges = false; +} - void IndexReader::incRef() - { - SyncLock syncLock(this); - BOOST_ASSERT(refCount > 0); - ensureOpen(); - ++refCount; - } +IndexReader::~IndexReader() { +} - void IndexReader::decRef() - { - SyncLock syncLock(this); - BOOST_ASSERT(refCount > 0); - ensureOpen(); - if (refCount == 1) - { - commit(); - doClose(); - } - --refCount; - } +int32_t IndexReader::getRefCount() { + SyncLock syncLock(this); + return refCount; +} - void IndexReader::ensureOpen() - { - if (refCount <= 0) - boost::throw_exception(AlreadyClosedException(L"this IndexReader is closed")); - } +void IndexReader::incRef() { + SyncLock syncLock(this); + BOOST_ASSERT(refCount > 0); + ensureOpen(); + ++refCount; +} - IndexReaderPtr IndexReader::open(const DirectoryPtr& directory) - { - return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), true, DEFAULT_TERMS_INDEX_DIVISOR); +void IndexReader::decRef() { + SyncLock syncLock(this); + BOOST_ASSERT(refCount > 0); + ensureOpen(); + if (refCount == 1) { + commit(); + doClose(); } + --refCount; +} - IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, bool readOnly) - { - return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); +void IndexReader::ensureOpen() { + if (refCount <= 0) { + boost::throw_exception(AlreadyClosedException(L"this IndexReader is closed")); } +} - IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, bool readOnly) - { - return open(commit->getDirectory(), IndexDeletionPolicyPtr(), commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); - } +IndexReaderPtr IndexReader::open(const DirectoryPtr& directory) { + return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), true, DEFAULT_TERMS_INDEX_DIVISOR); +} - IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly) - { - return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); - } +IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, bool readOnly) { + return open(directory, IndexDeletionPolicyPtr(), IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); +} - IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) - { - return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, termInfosIndexDivisor); - } +IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, bool readOnly) { + return open(commit->getDirectory(), IndexDeletionPolicyPtr(), commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); +} - IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly) - { - return open(commit->getDirectory(), deletionPolicy, commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); - } +IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly) { + return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, DEFAULT_TERMS_INDEX_DIVISOR); +} - IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) - { - return open(commit->getDirectory(), deletionPolicy, commit, readOnly, termInfosIndexDivisor); - } +IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { + return open(directory, deletionPolicy, IndexCommitPtr(), readOnly, termInfosIndexDivisor); +} - IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor) - { - return DirectoryReader::open(directory, deletionPolicy, commit, readOnly, termInfosIndexDivisor); - } +IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly) { + return open(commit->getDirectory(), deletionPolicy, commit, readOnly, DEFAULT_TERMS_INDEX_DIVISOR); +} - IndexReaderPtr IndexReader::reopen() - { - SyncLock syncLock(this); - boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen().")); - return IndexReaderPtr(); - } +IndexReaderPtr IndexReader::open(const IndexCommitPtr& commit, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor) { + return open(commit->getDirectory(), deletionPolicy, commit, readOnly, termInfosIndexDivisor); +} - IndexReaderPtr IndexReader::reopen(bool openReadOnly) - { - SyncLock syncLock(this); - boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen().")); - return IndexReaderPtr(); - } +IndexReaderPtr IndexReader::open(const DirectoryPtr& directory, const IndexDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& commit, bool readOnly, int32_t termInfosIndexDivisor) { + return DirectoryReader::open(directory, deletionPolicy, commit, readOnly, termInfosIndexDivisor); +} - IndexReaderPtr IndexReader::reopen(const IndexCommitPtr& commit) - { - SyncLock syncLock(this); - boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen(IndexCommit).")); - return IndexReaderPtr(); - } +IndexReaderPtr IndexReader::reopen() { + SyncLock syncLock(this); + boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen().")); + return IndexReaderPtr(); +} - LuceneObjectPtr IndexReader::clone(const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - if (!other) - boost::throw_exception(UnsupportedOperationException(L"This reader does not implement clone().")); - return other; - } +IndexReaderPtr IndexReader::reopen(bool openReadOnly) { + SyncLock syncLock(this); + boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen().")); + return IndexReaderPtr(); +} - LuceneObjectPtr IndexReader::clone(bool openReadOnly, const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - if (!other) - boost::throw_exception(UnsupportedOperationException(L"This reader does not implement clone(bool).")); - return other; - } +IndexReaderPtr IndexReader::reopen(const IndexCommitPtr& commit) { + SyncLock syncLock(this); + boost::throw_exception(UnsupportedOperationException(L"This reader does not support reopen(IndexCommit).")); + return IndexReaderPtr(); +} - DirectoryPtr IndexReader::directory() - { - ensureOpen(); - boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); - return DirectoryPtr(); +LuceneObjectPtr IndexReader::clone(const LuceneObjectPtr& other) { + SyncLock syncLock(this); + if (!other) { + boost::throw_exception(UnsupportedOperationException(L"This reader does not implement clone().")); } + return other; +} - int64_t IndexReader::lastModified(const DirectoryPtr& directory2) - { - return newLucene(newLucene(), directory2)->run(); +LuceneObjectPtr IndexReader::clone(bool openReadOnly, const LuceneObjectPtr& other) { + SyncLock syncLock(this); + if (!other) { + boost::throw_exception(UnsupportedOperationException(L"This reader does not implement clone(bool).")); } + return other; +} - int64_t IndexReader::getCurrentVersion(const DirectoryPtr& directory) - { - return SegmentInfos::readCurrentVersion(directory); - } +DirectoryPtr IndexReader::directory() { + ensureOpen(); + boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); + return DirectoryPtr(); +} - MapStringString IndexReader::getCommitUserData(const DirectoryPtr& directory) - { - return SegmentInfos::readCurrentUserData(directory); - } +int64_t IndexReader::lastModified(const DirectoryPtr& directory2) { + return newLucene(newLucene(), directory2)->run(); +} - int64_t IndexReader::getVersion() - { - boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); - return 0; - } +int64_t IndexReader::getCurrentVersion(const DirectoryPtr& directory) { + return SegmentInfos::readCurrentVersion(directory); +} - MapStringString IndexReader::getCommitUserData() - { - boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); - return MapStringString(); - } +MapStringString IndexReader::getCommitUserData(const DirectoryPtr& directory) { + return SegmentInfos::readCurrentUserData(directory); +} - bool IndexReader::isCurrent() - { - boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); - return false; - } +int64_t IndexReader::getVersion() { + boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); + return 0; +} - bool IndexReader::isOptimized() - { - boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); - return false; - } +MapStringString IndexReader::getCommitUserData() { + boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); + return MapStringString(); +} - bool IndexReader::indexExists(const DirectoryPtr& directory) - { - return (SegmentInfos::getCurrentSegmentGeneration(directory) != -1); - } +bool IndexReader::isCurrent() { + boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); + return false; +} - int32_t IndexReader::numDeletedDocs() - { - return (maxDoc() - numDocs()); - } +bool IndexReader::isOptimized() { + boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); + return false; +} - DocumentPtr IndexReader::document(int32_t n) - { - ensureOpen(); - return document(n, FieldSelectorPtr()); - } +bool IndexReader::indexExists(const DirectoryPtr& directory) { + return (SegmentInfos::getCurrentSegmentGeneration(directory) != -1); +} - bool IndexReader::hasChanges() - { - return _hasChanges; - } +int32_t IndexReader::numDeletedDocs() { + return (maxDoc() - numDocs()); +} - bool IndexReader::hasNorms(const String& field) - { - // backward compatible implementation. - // SegmentReader has an efficient implementation. - ensureOpen(); - return norms(field); - } +DocumentPtr IndexReader::document(int32_t n) { + ensureOpen(); + return document(n, FieldSelectorPtr()); +} - void IndexReader::setNorm(int32_t doc, const String& field, uint8_t value) - { - SyncLock syncLock(this); - ensureOpen(); - acquireWriteLock(); - _hasChanges = true; - doSetNorm(doc, field, value); - } +bool IndexReader::hasChanges() { + return _hasChanges; +} - void IndexReader::setNorm(int32_t doc, const String& field, double value) - { - ensureOpen(); - setNorm(doc, field, Similarity::encodeNorm(value)); - } +bool IndexReader::hasNorms(const String& field) { + // backward compatible implementation. + // SegmentReader has an efficient implementation. + ensureOpen(); + return norms(field); +} - TermDocsPtr IndexReader::termDocs(const TermPtr& term) - { - ensureOpen(); - TermDocsPtr _termDocs(termDocs()); - _termDocs->seek(term); - return _termDocs; - } +void IndexReader::setNorm(int32_t doc, const String& field, uint8_t value) { + SyncLock syncLock(this); + ensureOpen(); + acquireWriteLock(); + _hasChanges = true; + doSetNorm(doc, field, value); +} - TermPositionsPtr IndexReader::termPositions(const TermPtr& term) - { - ensureOpen(); - TermPositionsPtr _termPositions(termPositions()); - _termPositions->seek(term); - return _termPositions; - } +void IndexReader::setNorm(int32_t doc, const String& field, double value) { + ensureOpen(); + setNorm(doc, field, Similarity::encodeNorm(value)); +} - void IndexReader::deleteDocument(int32_t docNum) - { - SyncLock syncLock(this); - ensureOpen(); - acquireWriteLock(); - _hasChanges = true; - doDelete(docNum); - } +TermDocsPtr IndexReader::termDocs(const TermPtr& term) { + ensureOpen(); + TermDocsPtr _termDocs(termDocs()); + _termDocs->seek(term); + return _termDocs; +} - int32_t IndexReader::deleteDocuments(const TermPtr& term) - { - ensureOpen(); - TermDocsPtr docs(termDocs(term)); - if (!docs) - return 0; - int32_t n = 0; - LuceneException finally; - try - { - while (docs->next()) - { - deleteDocument(docs->doc()); - ++n; - } - } - catch (LuceneException& e) - { - finally = e; +TermPositionsPtr IndexReader::termPositions(const TermPtr& term) { + ensureOpen(); + TermPositionsPtr _termPositions(termPositions()); + _termPositions->seek(term); + return _termPositions; +} + +void IndexReader::deleteDocument(int32_t docNum) { + SyncLock syncLock(this); + ensureOpen(); + acquireWriteLock(); + _hasChanges = true; + doDelete(docNum); +} + +int32_t IndexReader::deleteDocuments(const TermPtr& term) { + ensureOpen(); + TermDocsPtr docs(termDocs(term)); + if (!docs) { + return 0; + } + int32_t n = 0; + LuceneException finally; + try { + while (docs->next()) { + deleteDocument(docs->doc()); + ++n; } - docs->close(); - finally.throwException(); - return n; + } catch (LuceneException& e) { + finally = e; } + docs->close(); + finally.throwException(); + return n; +} - void IndexReader::undeleteAll() - { - SyncLock syncLock(this); - ensureOpen(); - acquireWriteLock(); - _hasChanges = true; - doUndeleteAll(); - } +void IndexReader::undeleteAll() { + SyncLock syncLock(this); + ensureOpen(); + acquireWriteLock(); + _hasChanges = true; + doUndeleteAll(); +} - void IndexReader::acquireWriteLock() - { - SyncLock syncLock(this); - // NOOP - } +void IndexReader::acquireWriteLock() { + SyncLock syncLock(this); + // NOOP +} - void IndexReader::flush() - { - SyncLock syncLock(this); - ensureOpen(); - commit(); - } +void IndexReader::flush() { + SyncLock syncLock(this); + ensureOpen(); + commit(); +} - void IndexReader::flush(MapStringString commitUserData) - { - SyncLock syncLock(this); - ensureOpen(); - commit(commitUserData); - } +void IndexReader::flush(MapStringString commitUserData) { + SyncLock syncLock(this); + ensureOpen(); + commit(commitUserData); +} + +void IndexReader::commit() { + commit(MapStringString()); +} - void IndexReader::commit() - { - commit(MapStringString()); +void IndexReader::commit(MapStringString commitUserData) { + SyncLock syncLock(this); + if (_hasChanges) { + doCommit(commitUserData); } + _hasChanges = false; +} - void IndexReader::commit(MapStringString commitUserData) - { - SyncLock syncLock(this); - if (_hasChanges) - doCommit(commitUserData); - _hasChanges = false; +void IndexReader::close() { + SyncLock syncLock(this); + if (!closed) { + decRef(); + closed = true; } +} + +IndexCommitPtr IndexReader::getIndexCommit() { + boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); + return IndexCommitPtr(); +} + +void IndexReader::main(Collection args) { + String filename; + bool extract = false; - void IndexReader::close() - { - SyncLock syncLock(this); - if (!closed) - { - decRef(); - closed = true; + for (Collection::iterator arg = args.begin(); arg != args.end(); ++arg) { + if (*arg == L"-extract") { + extract = true; + } else if (filename.empty()) { + filename = *arg; } } - IndexCommitPtr IndexReader::getIndexCommit() - { - boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); - return IndexCommitPtr(); + if (filename.empty()) { + std::wcout << L"Usage: IndexReader [-extract] "; + return; } - void IndexReader::main(Collection args) - { - String filename; - bool extract = false; - - for (Collection::iterator arg = args.begin(); arg != args.end(); ++arg) - { - if (*arg == L"-extract") - extract = true; - else if (filename.empty()) - filename = *arg; - } + DirectoryPtr dir; + CompoundFileReaderPtr cfr; - if (filename.empty()) - { - std::wcout << L"Usage: IndexReader [-extract] "; - return; - } + LuceneException finally; + try { + String dirname(FileUtils::extractPath(filename)); + filename = FileUtils::extractPath(filename); + dir = FSDirectory::open(dirname); + cfr = newLucene(dir, filename); - DirectoryPtr dir; - CompoundFileReaderPtr cfr; - - LuceneException finally; - try - { - String dirname(FileUtils::extractPath(filename)); - filename = FileUtils::extractPath(filename); - dir = FSDirectory::open(dirname); - cfr = newLucene(dir, filename); - - HashSet _files(cfr->listAll()); - Collection files(Collection::newInstance(_files.begin(), _files.end())); - std::sort(files.begin(), files.end()); // sort the array of filename so that the output is more readable - - for (Collection::iterator file = files.begin(); file != files.end(); ++file) - { - int64_t len = cfr->fileLength(*file); - - if (extract) - { - std::wcout << L"extract " << *file << L" with " << len << L" bytes to local directory..."; - IndexInputPtr ii(cfr->openInput(*file)); - - boost::filesystem::ofstream f(*file, std::ios::binary | std::ios::out); - - // read and write with a small buffer, which is more effective than reading byte by byte - ByteArray buffer(ByteArray::newInstance(1024)); - - int32_t chunk = buffer.size(); - while (len > 0) - { - int32_t bufLen = std::min(chunk, (int32_t)len); - ii->readBytes(buffer.get(), 0, bufLen); - f.write((char*)buffer.get(), bufLen); - len -= bufLen; - } - ii->close(); + HashSet _files(cfr->listAll()); + Collection files(Collection::newInstance(_files.begin(), _files.end())); + std::sort(files.begin(), files.end()); // sort the array of filename so that the output is more readable + + for (Collection::iterator file = files.begin(); file != files.end(); ++file) { + int64_t len = cfr->fileLength(*file); + + if (extract) { + std::wcout << L"extract " << *file << L" with " << len << L" bytes to local directory..."; + IndexInputPtr ii(cfr->openInput(*file)); + + boost::filesystem::ofstream f(*file, std::ios::binary | std::ios::out); + + // read and write with a small buffer, which is more effective than reading byte by byte + ByteArray buffer(ByteArray::newInstance(1024)); + + int32_t chunk = buffer.size(); + while (len > 0) { + int32_t bufLen = std::min(chunk, (int32_t)len); + ii->readBytes(buffer.get(), 0, bufLen); + f.write((char*)buffer.get(), bufLen); + len -= bufLen; } - else - std::wcout << *file << L": " << len << " bytes\n"; + ii->close(); + } else { + std::wcout << *file << L": " << len << " bytes\n"; } } - catch (LuceneException& e) - { - finally = e; - } - - if (dir) - dir->close(); - if (cfr) - cfr->close(); - - finally.throwException(); + } catch (LuceneException& e) { + finally = e; } - Collection IndexReader::listCommits(const DirectoryPtr& dir) - { - return DirectoryReader::listCommits(dir); + if (dir) { + dir->close(); } - - Collection IndexReader::getSequentialSubReaders() - { - return Collection(); // override + if (cfr) { + cfr->close(); } - LuceneObjectPtr IndexReader::getFieldCacheKey() - { - return shared_from_this(); - } + finally.throwException(); +} - LuceneObjectPtr IndexReader::getDeletesCacheKey() - { - return shared_from_this(); - } +Collection IndexReader::listCommits(const DirectoryPtr& dir) { + return DirectoryReader::listCommits(dir); +} - int64_t IndexReader::getUniqueTermCount() - { - boost::throw_exception(UnsupportedOperationException(L"This reader does not implement getUniqueTermCount()")); - return 0; - } +Collection IndexReader::getSequentialSubReaders() { + return Collection(); // override +} - int32_t IndexReader::getTermInfosIndexDivisor() - { - boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); - return 0; - } +LuceneObjectPtr IndexReader::getFieldCacheKey() { + return shared_from_this(); +} - FindSegmentsModified::FindSegmentsModified(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) - { - result = 0; - } +LuceneObjectPtr IndexReader::getDeletesCacheKey() { + return shared_from_this(); +} - FindSegmentsModified::~FindSegmentsModified() - { - } +int64_t IndexReader::getUniqueTermCount() { + boost::throw_exception(UnsupportedOperationException(L"This reader does not implement getUniqueTermCount()")); + return 0; +} + +int32_t IndexReader::getTermInfosIndexDivisor() { + boost::throw_exception(UnsupportedOperationException(L"This reader does not support this method.")); + return 0; +} + +FindSegmentsModified::FindSegmentsModified(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { + result = 0; +} + +FindSegmentsModified::~FindSegmentsModified() { +} + +uint64_t FindSegmentsModified::doBody(const String& segmentFileName) { + return directory->fileModified(segmentFileName); +} - uint64_t FindSegmentsModified::doBody(const String& segmentFileName) - { - return directory->fileModified(segmentFileName); - } } diff --git a/src/core/index/IndexWriter.cpp b/src/core/index/IndexWriter.cpp index 3b1aec9e..c7d30890 100644 --- a/src/core/index/IndexWriter.cpp +++ b/src/core/index/IndexWriter.cpp @@ -30,3829 +30,3521 @@ #include "TestPoint.h" #include "StringUtils.h" -namespace Lucene -{ - /// The normal read buffer size defaults to 1024, but increasing this during merging seems to - /// yield performance gains. However we don't want to increase it too much because there are - /// quite a few BufferedIndexInputs created during merging. - const int32_t IndexWriter::MERGE_READ_BUFFER_SIZE = 4096; +namespace Lucene { - int32_t IndexWriter::MESSAGE_ID = 0; - InfoStreamPtr IndexWriter::defaultInfoStream; +/// The normal read buffer size defaults to 1024, but increasing this during merging seems to +/// yield performance gains. However we don't want to increase it too much because there are +/// quite a few BufferedIndexInputs created during merging. +const int32_t IndexWriter::MERGE_READ_BUFFER_SIZE = 4096; - /// Default value for the write lock timeout (1,000). - int64_t IndexWriter::WRITE_LOCK_TIMEOUT = 1000; +int32_t IndexWriter::MESSAGE_ID = 0; +InfoStreamPtr IndexWriter::defaultInfoStream; - const String IndexWriter::WRITE_LOCK_NAME = L"write.lock"; +/// Default value for the write lock timeout (1,000). +int64_t IndexWriter::WRITE_LOCK_TIMEOUT = 1000; - /// Value to denote a flush trigger is disabled. - const int32_t IndexWriter::DISABLE_AUTO_FLUSH = -1; +const String IndexWriter::WRITE_LOCK_NAME = L"write.lock"; - /// Disabled by default (because IndexWriter flushes by RAM usage by default). - const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DOCS = IndexWriter::DISABLE_AUTO_FLUSH; +/// Value to denote a flush trigger is disabled. +const int32_t IndexWriter::DISABLE_AUTO_FLUSH = -1; - /// Default value is 16 MB (which means flush when buffered docs consume 16 MB RAM). - const double IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB = 16.0; +/// Disabled by default (because IndexWriter flushes by RAM usage by default). +const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DOCS = IndexWriter::DISABLE_AUTO_FLUSH; - /// Disabled by default (because IndexWriter flushes by RAM usage by default). - const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DELETE_TERMS = IndexWriter::DISABLE_AUTO_FLUSH; +/// Default value is 16 MB (which means flush when buffered docs consume 16 MB RAM). +const double IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB = 16.0; - /// Default value is 10000. - const int32_t IndexWriter::DEFAULT_MAX_FIELD_LENGTH = 10000; +/// Disabled by default (because IndexWriter flushes by RAM usage by default). +const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DELETE_TERMS = IndexWriter::DISABLE_AUTO_FLUSH; - /// Default value is 128. - const int32_t IndexWriter::DEFAULT_TERM_INDEX_INTERVAL = 128; +/// Default value is 10000. +const int32_t IndexWriter::DEFAULT_MAX_FIELD_LENGTH = 10000; - /// Sets the maximum field length to INT_MAX - const int32_t IndexWriter::MaxFieldLengthUNLIMITED = INT_MAX; +/// Default value is 128. +const int32_t IndexWriter::DEFAULT_TERM_INDEX_INTERVAL = 128; - /// Sets the maximum field length to {@link #DEFAULT_MAX_FIELD_LENGTH} - const int32_t IndexWriter::MaxFieldLengthLIMITED = IndexWriter::DEFAULT_MAX_FIELD_LENGTH; +/// Sets the maximum field length to INT_MAX +const int32_t IndexWriter::MaxFieldLengthUNLIMITED = INT_MAX; - IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) - { - this->directory = d; - this->analyzer = a; - this->create = create; - this->maxFieldLength = mfl; - } - - IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl) - { - this->directory = d; - this->analyzer = a; - this->create = !IndexReader::indexExists(d); - this->maxFieldLength = mfl; - } - - IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl) - { - this->directory = d; - this->analyzer = a; - this->deletionPolicy = deletionPolicy; - this->create = !IndexReader::indexExists(d); - this->maxFieldLength = mfl; - } - - IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl) - { - this->directory = d; - this->analyzer = a; - this->create = create; - this->deletionPolicy = deletionPolicy; - this->maxFieldLength = mfl; - } - - IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexingChainPtr& indexingChain, const IndexCommitPtr& commit) - { - this->directory = d; - this->analyzer = a; - this->create = create; - this->deletionPolicy = deletionPolicy; - this->maxFieldLength = mfl; - this->indexingChain = indexingChain; - this->indexCommit = commit; - } - - IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexCommitPtr& commit) - { - this->directory = d; - this->analyzer = a; - this->create = false; - this->deletionPolicy = deletionPolicy; - this->maxFieldLength = mfl; - this->indexCommit = commit; - } - - IndexWriter::~IndexWriter() - { - } +/// Sets the maximum field length to {@link #DEFAULT_MAX_FIELD_LENGTH} +const int32_t IndexWriter::MaxFieldLengthLIMITED = IndexWriter::DEFAULT_MAX_FIELD_LENGTH; - void IndexWriter::initialize() - { - messageID = -1; - messageIDLock = newInstance(); - setMessageID(defaultInfoStream); - this->writeLockTimeout = WRITE_LOCK_TIMEOUT; - this->segmentInfos = newLucene(); - pendingMerges = Collection::newInstance(); - mergeExceptions = Collection::newInstance(); - segmentsToOptimize = SetSegmentInfo::newInstance(); - optimizeMaxNumSegments = 0; - mergingSegments = SetSegmentInfo::newInstance(); - runningMerges = SetOneMerge::newInstance(); - synced = HashSet::newInstance(); - syncing = HashSet::newInstance(); - changeCount = 0; - lastCommitChangeCount = 0; - poolReaders = false; - readCount = 0; - writeThread = 0; - upgradeCount = 0; - readerTermsIndexDivisor = IndexReader::DEFAULT_TERMS_INDEX_DIVISOR; - readerPool = newLucene(shared_from_this()); - closed = false; - closing = false; - hitOOM = false; - stopMerges = false; - mergeGen = 0; - flushCount = 0; - flushDeletesCount = 0; - localFlushedDocCount = 0; - pendingCommitChangeCount = 0; - mergePolicy = newLucene(shared_from_this()); - mergeScheduler = newLucene(); - similarity = Similarity::getDefault(); - termIndexInterval = DEFAULT_TERM_INDEX_INTERVAL; - commitLock = newInstance(); +IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) { + this->directory = d; + this->analyzer = a; + this->create = create; + this->maxFieldLength = mfl; +} - if (!indexingChain) - indexingChain = DocumentsWriter::getDefaultIndexingChain(); +IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl) { + this->directory = d; + this->analyzer = a; + this->create = !IndexReader::indexExists(d); + this->maxFieldLength = mfl; +} - if (create) - directory->clearLock(WRITE_LOCK_NAME); // clear the write lock in case it's leftover +IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl) { + this->directory = d; + this->analyzer = a; + this->deletionPolicy = deletionPolicy; + this->create = !IndexReader::indexExists(d); + this->maxFieldLength = mfl; +} - LockPtr writeLock(directory->makeLock(WRITE_LOCK_NAME)); +IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl) { + this->directory = d; + this->analyzer = a; + this->create = create; + this->deletionPolicy = deletionPolicy; + this->maxFieldLength = mfl; +} - if (!writeLock->obtain((int32_t)writeLockTimeout)) // obtain write lock - boost::throw_exception(LockObtainFailedException(L"Index locked for write: " + writeLock->toString())); - this->writeLock = writeLock; +IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexingChainPtr& indexingChain, const IndexCommitPtr& commit) { + this->directory = d; + this->analyzer = a; + this->create = create; + this->deletionPolicy = deletionPolicy; + this->maxFieldLength = mfl; + this->indexingChain = indexingChain; + this->indexCommit = commit; +} - bool success = false; - LuceneException finally; +IndexWriter::IndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, const IndexDeletionPolicyPtr& deletionPolicy, int32_t mfl, const IndexCommitPtr& commit) { + this->directory = d; + this->analyzer = a; + this->create = false; + this->deletionPolicy = deletionPolicy; + this->maxFieldLength = mfl; + this->indexCommit = commit; +} - try - { - if (create) - { - // Try to read first. This is to allow create against an index that's currently open for - // searching. In this case we write the next segments_N file with no segments - bool doCommit; - try - { - segmentInfos->read(directory); - segmentInfos->clear(); - doCommit = false; - } - catch (LuceneException&) - { - // Likely this means it's a fresh directory - doCommit = true; - } +IndexWriter::~IndexWriter() { +} - if (doCommit) - { - // Only commit if there is no segments file in this dir already. - segmentInfos->commit(directory); - HashSet files(segmentInfos->files(directory, true)); - synced.addAll(files.begin(), files.end()); - } - else - { - // Record that we have a change (zero out all segments) pending - ++changeCount; - } - } - else - { +void IndexWriter::initialize() { + messageID = -1; + messageIDLock = newInstance(); + setMessageID(defaultInfoStream); + this->writeLockTimeout = WRITE_LOCK_TIMEOUT; + this->segmentInfos = newLucene(); + pendingMerges = Collection::newInstance(); + mergeExceptions = Collection::newInstance(); + segmentsToOptimize = SetSegmentInfo::newInstance(); + optimizeMaxNumSegments = 0; + mergingSegments = SetSegmentInfo::newInstance(); + runningMerges = SetOneMerge::newInstance(); + synced = HashSet::newInstance(); + syncing = HashSet::newInstance(); + changeCount = 0; + lastCommitChangeCount = 0; + poolReaders = false; + readCount = 0; + writeThread = 0; + upgradeCount = 0; + readerTermsIndexDivisor = IndexReader::DEFAULT_TERMS_INDEX_DIVISOR; + readerPool = newLucene(shared_from_this()); + closed = false; + closing = false; + hitOOM = false; + stopMerges = false; + mergeGen = 0; + flushCount = 0; + flushDeletesCount = 0; + localFlushedDocCount = 0; + pendingCommitChangeCount = 0; + mergePolicy = newLucene(shared_from_this()); + mergeScheduler = newLucene(); + similarity = Similarity::getDefault(); + termIndexInterval = DEFAULT_TERM_INDEX_INTERVAL; + commitLock = newInstance(); + + if (!indexingChain) { + indexingChain = DocumentsWriter::getDefaultIndexingChain(); + } + + if (create) { + directory->clearLock(WRITE_LOCK_NAME); // clear the write lock in case it's leftover + } + + LockPtr writeLock(directory->makeLock(WRITE_LOCK_NAME)); + + if (!writeLock->obtain((int32_t)writeLockTimeout)) { // obtain write lock + boost::throw_exception(LockObtainFailedException(L"Index locked for write: " + writeLock->toString())); + } + this->writeLock = writeLock; + + bool success = false; + LuceneException finally; + + try { + if (create) { + // Try to read first. This is to allow create against an index that's currently open for + // searching. In this case we write the next segments_N file with no segments + bool doCommit; + try { segmentInfos->read(directory); + segmentInfos->clear(); + doCommit = false; + } catch (LuceneException&) { + // Likely this means it's a fresh directory + doCommit = true; + } - if (indexCommit) - { - // Swap out all segments, but, keep metadata in SegmentInfos, like version & generation, to - // preserve write-once. This is important if readers are open against the future commit points. - if (indexCommit->getDirectory() != directory) - boost::throw_exception(IllegalArgumentException(L"IndexCommit's directory doesn't match my directory")); - SegmentInfosPtr oldInfos(newLucene()); - oldInfos->read(directory, indexCommit->getSegmentsFileName()); - segmentInfos->replace(oldInfos); - ++changeCount; - if (infoStream) - message(L"init: loaded commit \"" + indexCommit->getSegmentsFileName() + L"\""); - } - - // We assume that this segments_N was previously properly sync'd + if (doCommit) { + // Only commit if there is no segments file in this dir already. + segmentInfos->commit(directory); HashSet files(segmentInfos->files(directory, true)); synced.addAll(files.begin(), files.end()); + } else { + // Record that we have a change (zero out all segments) pending + ++changeCount; } + } else { + segmentInfos->read(directory); - setRollbackSegmentInfos(segmentInfos); - - docWriter = newLucene(directory, shared_from_this(), indexingChain); - docWriter->setInfoStream(infoStream); - docWriter->setMaxFieldLength(maxFieldLength); - - // Default deleter (for backwards compatibility) is KeepOnlyLastCommitDeleter - deleter = newLucene(directory, deletionPolicy ? deletionPolicy : newLucene(), segmentInfos, infoStream, docWriter, synced); - - if (deleter->startingCommitDeleted) - { - // Deletion policy deleted the "head" commit point. We have to mark ourself as changed so that if we - // are closed without any further changes we write a new segments_N file. + if (indexCommit) { + // Swap out all segments, but, keep metadata in SegmentInfos, like version & generation, to + // preserve write-once. This is important if readers are open against the future commit points. + if (indexCommit->getDirectory() != directory) { + boost::throw_exception(IllegalArgumentException(L"IndexCommit's directory doesn't match my directory")); + } + SegmentInfosPtr oldInfos(newLucene()); + oldInfos->read(directory, indexCommit->getSegmentsFileName()); + segmentInfos->replace(oldInfos); ++changeCount; + if (infoStream) { + message(L"init: loaded commit \"" + indexCommit->getSegmentsFileName() + L"\""); + } } - pushMaxBufferedDocs(); - - if (infoStream) - message(L"init: create=" + StringUtils::toString(create)); - messageState(); - - success = true; - } - catch (LuceneException& e) - { - finally = e; + // We assume that this segments_N was previously properly sync'd + HashSet files(segmentInfos->files(directory, true)); + synced.addAll(files.begin(), files.end()); } - if (!success) - { - if (infoStream) - message(L"init: hit exception on init; releasing write lock"); - try - { - this->writeLock->release(); - } - catch (...) - { - // don't mask the original exception - } - this->writeLock.reset(); - } - - finally.throwException(); - } - - int32_t IndexWriter::MAX_TERM_LENGTH() - { - static int32_t _MAX_TERM_LENGTH = 0; - if (_MAX_TERM_LENGTH == 0) - _MAX_TERM_LENGTH = DocumentsWriter::MAX_TERM_LENGTH; - return _MAX_TERM_LENGTH; - } + setRollbackSegmentInfos(segmentInfos); - IndexReaderPtr IndexWriter::getReader() - { - return getReader(readerTermsIndexDivisor); - } + docWriter = newLucene(directory, shared_from_this(), indexingChain); + docWriter->setInfoStream(infoStream); + docWriter->setMaxFieldLength(maxFieldLength); - IndexReaderPtr IndexWriter::getReader(int32_t termInfosIndexDivisor) - { - ensureOpen(); + // Default deleter (for backwards compatibility) is KeepOnlyLastCommitDeleter + deleter = newLucene(directory, deletionPolicy ? deletionPolicy : newLucene(), segmentInfos, infoStream, docWriter, synced); - if (infoStream) - message(L"flush at getReader"); + if (deleter->startingCommitDeleted) { + // Deletion policy deleted the "head" commit point. We have to mark ourself as changed so that if we + // are closed without any further changes we write a new segments_N file. + ++changeCount; + } - // Do this up front before flushing so that the readers obtained during this flush are pooled, the first time - // this method is called - poolReaders = true; + pushMaxBufferedDocs(); - // Prevent segmentInfos from changing while opening the reader; in theory we could do similar retry logic, - // just like we do when loading segments_N - IndexReaderPtr r; - { - SyncLock syncLock(this); - flush(false, true, true); - r = newLucene(shared_from_this(), segmentInfos, termInfosIndexDivisor); + if (infoStream) { + message(L"init: create=" + StringUtils::toString(create)); } - maybeMerge(); - return r; + messageState(); + + success = true; + } catch (LuceneException& e) { + finally = e; } - int32_t IndexWriter::numDeletedDocs(const SegmentInfoPtr& info) - { - SegmentReaderPtr reader(readerPool->getIfExists(info)); - int32_t deletedDocs = 0; - LuceneException finally; - try - { - deletedDocs = reader ? reader->numDeletedDocs() : info->getDelCount(); + if (!success) { + if (infoStream) { + message(L"init: hit exception on init; releasing write lock"); } - catch (LuceneException& e) - { - finally = e; + try { + this->writeLock->release(); + } catch (...) { + // don't mask the original exception } - if (reader) - readerPool->release(reader); - finally.throwException(); - return deletedDocs; + this->writeLock.reset(); } - void IndexWriter::acquireWrite() - { - SyncLock syncLock(this); - BOOST_ASSERT(writeThread != LuceneThread::currentId()); - while (writeThread != 0 || readCount > 0) - doWait(); - - // we could have been closed while we were waiting - ensureOpen(); + finally.throwException(); +} - writeThread = LuceneThread::currentId(); +int32_t IndexWriter::MAX_TERM_LENGTH() { + static int32_t _MAX_TERM_LENGTH = 0; + if (_MAX_TERM_LENGTH == 0) { + _MAX_TERM_LENGTH = DocumentsWriter::MAX_TERM_LENGTH; } + return _MAX_TERM_LENGTH; +} - void IndexWriter::releaseWrite() - { - SyncLock syncLock(this); - BOOST_ASSERT(writeThread == LuceneThread::currentId()); - writeThread = 0; - notifyAll(); - } +IndexReaderPtr IndexWriter::getReader() { + return getReader(readerTermsIndexDivisor); +} - void IndexWriter::acquireRead() - { - SyncLock syncLock(this); - int64_t current = LuceneThread::currentId(); - while (writeThread != 0 && writeThread != current) - doWait(); - ++readCount; - } +IndexReaderPtr IndexWriter::getReader(int32_t termInfosIndexDivisor) { + ensureOpen(); - void IndexWriter::upgradeReadToWrite() - { - SyncLock syncLock(this); - BOOST_ASSERT(readCount > 0); - ++upgradeCount; - while (readCount > upgradeCount || writeThread != 0) - doWait(); - writeThread = LuceneThread::currentId(); - --readCount; - --upgradeCount; + if (infoStream) { + message(L"flush at getReader"); } - void IndexWriter::releaseRead() - { - SyncLock syncLock(this); - --readCount; - BOOST_ASSERT(readCount >= 0); - notifyAll(); - } + // Do this up front before flushing so that the readers obtained during this flush are pooled, the first time + // this method is called + poolReaders = true; - bool IndexWriter::isOpen(bool includePendingClose) + // Prevent segmentInfos from changing while opening the reader; in theory we could do similar retry logic, + // just like we do when loading segments_N + IndexReaderPtr r; { SyncLock syncLock(this); - return !(closed || (includePendingClose && closing)); + flush(false, true, true); + r = newLucene(shared_from_this(), segmentInfos, termInfosIndexDivisor); } + maybeMerge(); + return r; +} - void IndexWriter::ensureOpen(bool includePendingClose) - { - SyncLock syncLock(this); - if (!isOpen(includePendingClose)) - boost::throw_exception(AlreadyClosedException(L"This IndexWriter is closed")); +int32_t IndexWriter::numDeletedDocs(const SegmentInfoPtr& info) { + SegmentReaderPtr reader(readerPool->getIfExists(info)); + int32_t deletedDocs = 0; + LuceneException finally; + try { + deletedDocs = reader ? reader->numDeletedDocs() : info->getDelCount(); + } catch (LuceneException& e) { + finally = e; } - - void IndexWriter::ensureOpen() - { - ensureOpen(true); + if (reader) { + readerPool->release(reader); } + finally.throwException(); + return deletedDocs; +} - void IndexWriter::message(const String& message) - { - if (infoStream) - { - *infoStream << L"IW " << StringUtils::toString(messageID); - *infoStream << L" [" << DateTools::timeToString(MiscUtils::currentTimeMillis(), DateTools::RESOLUTION_SECOND); - *infoStream << L"; " << StringUtils::toString(LuceneThread::currentId()) << L"]: " << message << L"\n"; - } +void IndexWriter::acquireWrite() { + SyncLock syncLock(this); + BOOST_ASSERT(writeThread != LuceneThread::currentId()); + while (writeThread != 0 || readCount > 0) { + doWait(); } - void IndexWriter::setMessageID(const InfoStreamPtr& infoStream) - { - SyncLock syncLock(this); - if (infoStream && messageID == -1) - { - SyncLock messageLock(messageIDLock); - messageID = MESSAGE_ID++; - } - this->infoStream = infoStream; - } + // we could have been closed while we were waiting + ensureOpen(); - LogMergePolicyPtr IndexWriter::getLogMergePolicy() - { - LogMergePolicyPtr logMergePolicy(boost::dynamic_pointer_cast(mergePolicy)); - if (logMergePolicy) - return logMergePolicy; - boost::throw_exception(IllegalArgumentException(L"This method can only be called when the merge policy is the default LogMergePolicy")); - return LogMergePolicyPtr(); - } + writeThread = LuceneThread::currentId(); +} - bool IndexWriter::getUseCompoundFile() - { - return getLogMergePolicy()->getUseCompoundFile(); - } +void IndexWriter::releaseWrite() { + SyncLock syncLock(this); + BOOST_ASSERT(writeThread == LuceneThread::currentId()); + writeThread = 0; + notifyAll(); +} - void IndexWriter::setUseCompoundFile(bool value) - { - getLogMergePolicy()->setUseCompoundFile(value); - getLogMergePolicy()->setUseCompoundDocStore(value); +void IndexWriter::acquireRead() { + SyncLock syncLock(this); + int64_t current = LuceneThread::currentId(); + while (writeThread != 0 && writeThread != current) { + doWait(); } + ++readCount; +} - void IndexWriter::setSimilarity(const SimilarityPtr& similarity) - { - ensureOpen(); - this->similarity = similarity; - docWriter->setSimilarity(similarity); +void IndexWriter::upgradeReadToWrite() { + SyncLock syncLock(this); + BOOST_ASSERT(readCount > 0); + ++upgradeCount; + while (readCount > upgradeCount || writeThread != 0) { + doWait(); } + writeThread = LuceneThread::currentId(); + --readCount; + --upgradeCount; +} - SimilarityPtr IndexWriter::getSimilarity() - { - ensureOpen(); - return this->similarity; +void IndexWriter::releaseRead() { + SyncLock syncLock(this); + --readCount; + BOOST_ASSERT(readCount >= 0); + notifyAll(); +} + +bool IndexWriter::isOpen(bool includePendingClose) { + SyncLock syncLock(this); + return !(closed || (includePendingClose && closing)); +} + +void IndexWriter::ensureOpen(bool includePendingClose) { + SyncLock syncLock(this); + if (!isOpen(includePendingClose)) { + boost::throw_exception(AlreadyClosedException(L"This IndexWriter is closed")); } +} - void IndexWriter::setTermIndexInterval(int32_t interval) - { - ensureOpen(); - this->termIndexInterval = interval; +void IndexWriter::ensureOpen() { + ensureOpen(true); +} + +void IndexWriter::message(const String& message) { + if (infoStream) { + *infoStream << L"IW " << StringUtils::toString(messageID); + *infoStream << L" [" << DateTools::timeToString(MiscUtils::currentTimeMillis(), DateTools::RESOLUTION_SECOND); + *infoStream << L"; " << StringUtils::toString(LuceneThread::currentId()) << L"]: " << message << L"\n"; } +} - int32_t IndexWriter::getTermIndexInterval() - { - // We pass false because this method is called by SegmentMerger while we are in the process of closing - ensureOpen(false); - return termIndexInterval; +void IndexWriter::setMessageID(const InfoStreamPtr& infoStream) { + SyncLock syncLock(this); + if (infoStream && messageID == -1) { + SyncLock messageLock(messageIDLock); + messageID = MESSAGE_ID++; } + this->infoStream = infoStream; +} - void IndexWriter::setRollbackSegmentInfos(const SegmentInfosPtr& infos) - { - SyncLock syncLock(this); - rollbackSegmentInfos = boost::dynamic_pointer_cast(infos->clone()); - BOOST_ASSERT(!rollbackSegmentInfos->hasExternalSegments(directory)); - rollbackSegments = MapSegmentInfoInt::newInstance(); - int32_t size = rollbackSegmentInfos->size(); - for (int32_t i = 0; i < size; ++i) - rollbackSegments.put(rollbackSegmentInfos->info(i), i); +LogMergePolicyPtr IndexWriter::getLogMergePolicy() { + LogMergePolicyPtr logMergePolicy(boost::dynamic_pointer_cast(mergePolicy)); + if (logMergePolicy) { + return logMergePolicy; } + boost::throw_exception(IllegalArgumentException(L"This method can only be called when the merge policy is the default LogMergePolicy")); + return LogMergePolicyPtr(); +} - void IndexWriter::setMergePolicy(const MergePolicyPtr& mp) - { - ensureOpen(); - if (!mp) - boost::throw_exception(NullPointerException(L"MergePolicy must be non-null")); +bool IndexWriter::getUseCompoundFile() { + return getLogMergePolicy()->getUseCompoundFile(); +} - if (mergePolicy != mp) - mergePolicy->close(); - mergePolicy = mp; - pushMaxBufferedDocs(); - if (infoStream) - message(L"setMergePolicy"); - } +void IndexWriter::setUseCompoundFile(bool value) { + getLogMergePolicy()->setUseCompoundFile(value); + getLogMergePolicy()->setUseCompoundDocStore(value); +} - MergePolicyPtr IndexWriter::getMergePolicy() - { - ensureOpen(); - return mergePolicy; - } +void IndexWriter::setSimilarity(const SimilarityPtr& similarity) { + ensureOpen(); + this->similarity = similarity; + docWriter->setSimilarity(similarity); +} - void IndexWriter::setMergeScheduler(const MergeSchedulerPtr& mergeScheduler) - { - SyncLock syncLock(this); - ensureOpen(); - if (!mergeScheduler) - boost::throw_exception(NullPointerException(L"MergeScheduler must be non-null")); - if (this->mergeScheduler != mergeScheduler) - { - finishMerges(true); - this->mergeScheduler->close(); - } - this->mergeScheduler = mergeScheduler; - if (infoStream) - message(L"setMergeScheduler"); - } +SimilarityPtr IndexWriter::getSimilarity() { + ensureOpen(); + return this->similarity; +} - MergeSchedulerPtr IndexWriter::getMergeScheduler() - { - ensureOpen(); - return mergeScheduler; - } +void IndexWriter::setTermIndexInterval(int32_t interval) { + ensureOpen(); + this->termIndexInterval = interval; +} - void IndexWriter::setMaxMergeDocs(int32_t maxMergeDocs) - { - getLogMergePolicy()->setMaxMergeDocs(maxMergeDocs); +int32_t IndexWriter::getTermIndexInterval() { + // We pass false because this method is called by SegmentMerger while we are in the process of closing + ensureOpen(false); + return termIndexInterval; +} + +void IndexWriter::setRollbackSegmentInfos(const SegmentInfosPtr& infos) { + SyncLock syncLock(this); + rollbackSegmentInfos = boost::dynamic_pointer_cast(infos->clone()); + BOOST_ASSERT(!rollbackSegmentInfos->hasExternalSegments(directory)); + rollbackSegments = MapSegmentInfoInt::newInstance(); + int32_t size = rollbackSegmentInfos->size(); + for (int32_t i = 0; i < size; ++i) { + rollbackSegments.put(rollbackSegmentInfos->info(i), i); } +} - int32_t IndexWriter::getMaxMergeDocs() - { - return getLogMergePolicy()->getMaxMergeDocs(); +void IndexWriter::setMergePolicy(const MergePolicyPtr& mp) { + ensureOpen(); + if (!mp) { + boost::throw_exception(NullPointerException(L"MergePolicy must be non-null")); } - void IndexWriter::setMaxFieldLength(int32_t maxFieldLength) - { - ensureOpen(); - this->maxFieldLength = maxFieldLength; - docWriter->setMaxFieldLength(maxFieldLength); - if (infoStream) - message(L"setMaxFieldLength " + StringUtils::toString(maxFieldLength)); + if (mergePolicy != mp) { + mergePolicy->close(); + } + mergePolicy = mp; + pushMaxBufferedDocs(); + if (infoStream) { + message(L"setMergePolicy"); } +} - int32_t IndexWriter::getMaxFieldLength() - { - ensureOpen(); - return maxFieldLength; +MergePolicyPtr IndexWriter::getMergePolicy() { + ensureOpen(); + return mergePolicy; +} + +void IndexWriter::setMergeScheduler(const MergeSchedulerPtr& mergeScheduler) { + SyncLock syncLock(this); + ensureOpen(); + if (!mergeScheduler) { + boost::throw_exception(NullPointerException(L"MergeScheduler must be non-null")); + } + if (this->mergeScheduler != mergeScheduler) { + finishMerges(true); + this->mergeScheduler->close(); + } + this->mergeScheduler = mergeScheduler; + if (infoStream) { + message(L"setMergeScheduler"); } +} - void IndexWriter::setReaderTermsIndexDivisor(int32_t divisor) - { - ensureOpen(); - if (divisor <= 0) - boost::throw_exception(IllegalArgumentException(L"divisor must be >= 1 (got " + StringUtils::toString(divisor) + L")")); - readerTermsIndexDivisor = divisor; - if (infoStream) - message(L"setReaderTermsIndexDivisor " + StringUtils::toString(readerTermsIndexDivisor)); +MergeSchedulerPtr IndexWriter::getMergeScheduler() { + ensureOpen(); + return mergeScheduler; +} + +void IndexWriter::setMaxMergeDocs(int32_t maxMergeDocs) { + getLogMergePolicy()->setMaxMergeDocs(maxMergeDocs); +} + +int32_t IndexWriter::getMaxMergeDocs() { + return getLogMergePolicy()->getMaxMergeDocs(); +} + +void IndexWriter::setMaxFieldLength(int32_t maxFieldLength) { + ensureOpen(); + this->maxFieldLength = maxFieldLength; + docWriter->setMaxFieldLength(maxFieldLength); + if (infoStream) { + message(L"setMaxFieldLength " + StringUtils::toString(maxFieldLength)); } +} - int32_t IndexWriter::getReaderTermsIndexDivisor() - { - ensureOpen(); - return readerTermsIndexDivisor; +int32_t IndexWriter::getMaxFieldLength() { + ensureOpen(); + return maxFieldLength; +} + +void IndexWriter::setReaderTermsIndexDivisor(int32_t divisor) { + ensureOpen(); + if (divisor <= 0) { + boost::throw_exception(IllegalArgumentException(L"divisor must be >= 1 (got " + StringUtils::toString(divisor) + L")")); + } + readerTermsIndexDivisor = divisor; + if (infoStream) { + message(L"setReaderTermsIndexDivisor " + StringUtils::toString(readerTermsIndexDivisor)); } +} - void IndexWriter::setMaxBufferedDocs(int32_t maxBufferedDocs) - { - ensureOpen(); - if (maxBufferedDocs != DISABLE_AUTO_FLUSH && maxBufferedDocs < 2) - boost::throw_exception(IllegalArgumentException(L"maxBufferedDocs must at least be 2 when enabled")); - if (maxBufferedDocs == DISABLE_AUTO_FLUSH && getRAMBufferSizeMB() == DISABLE_AUTO_FLUSH) - boost::throw_exception(IllegalArgumentException(L"at least one of ramBufferSize and maxBufferedDocs must be enabled")); - docWriter->setMaxBufferedDocs(maxBufferedDocs); - pushMaxBufferedDocs(); - if (infoStream) - message(L"setMaxBufferedDocs " + StringUtils::toString(maxBufferedDocs)); +int32_t IndexWriter::getReaderTermsIndexDivisor() { + ensureOpen(); + return readerTermsIndexDivisor; +} + +void IndexWriter::setMaxBufferedDocs(int32_t maxBufferedDocs) { + ensureOpen(); + if (maxBufferedDocs != DISABLE_AUTO_FLUSH && maxBufferedDocs < 2) { + boost::throw_exception(IllegalArgumentException(L"maxBufferedDocs must at least be 2 when enabled")); + } + if (maxBufferedDocs == DISABLE_AUTO_FLUSH && getRAMBufferSizeMB() == DISABLE_AUTO_FLUSH) { + boost::throw_exception(IllegalArgumentException(L"at least one of ramBufferSize and maxBufferedDocs must be enabled")); + } + docWriter->setMaxBufferedDocs(maxBufferedDocs); + pushMaxBufferedDocs(); + if (infoStream) { + message(L"setMaxBufferedDocs " + StringUtils::toString(maxBufferedDocs)); } +} - void IndexWriter::pushMaxBufferedDocs() - { - if (docWriter->getMaxBufferedDocs() != DISABLE_AUTO_FLUSH) - { - LogDocMergePolicyPtr lmp(boost::dynamic_pointer_cast(mergePolicy)); - if (lmp) - { - int32_t maxBufferedDocs = docWriter->getMaxBufferedDocs(); - if (lmp->getMinMergeDocs() != maxBufferedDocs) - { - if (infoStream) - message(L"now push maxBufferedDocs " + StringUtils::toString(maxBufferedDocs) + L" to LogDocMergePolicy"); - lmp->setMinMergeDocs(maxBufferedDocs); +void IndexWriter::pushMaxBufferedDocs() { + if (docWriter->getMaxBufferedDocs() != DISABLE_AUTO_FLUSH) { + LogDocMergePolicyPtr lmp(boost::dynamic_pointer_cast(mergePolicy)); + if (lmp) { + int32_t maxBufferedDocs = docWriter->getMaxBufferedDocs(); + if (lmp->getMinMergeDocs() != maxBufferedDocs) { + if (infoStream) { + message(L"now push maxBufferedDocs " + StringUtils::toString(maxBufferedDocs) + L" to LogDocMergePolicy"); } + lmp->setMinMergeDocs(maxBufferedDocs); } } } +} - int32_t IndexWriter::getMaxBufferedDocs() - { - ensureOpen(); - return docWriter->getMaxBufferedDocs(); - } +int32_t IndexWriter::getMaxBufferedDocs() { + ensureOpen(); + return docWriter->getMaxBufferedDocs(); +} - void IndexWriter::setRAMBufferSizeMB(double mb) - { - if (mb > 2048.0) - boost::throw_exception(IllegalArgumentException(L"ramBufferSize " + StringUtils::toString(mb) + L" is too large; should be comfortably less than 2048")); - if (mb != DISABLE_AUTO_FLUSH && mb <= 0.0) - boost::throw_exception(IllegalArgumentException(L"ramBufferSize should be > 0.0 MB when enabled")); - if (mb == DISABLE_AUTO_FLUSH && getMaxBufferedDocs() == DISABLE_AUTO_FLUSH) - boost::throw_exception(IllegalArgumentException(L"at least one of ramBufferSize and maxBufferedDocs must be enabled")); - docWriter->setRAMBufferSizeMB(mb); - if (infoStream) - message(L"setRAMBufferSizeMB " + StringUtils::toString(mb)); - } - - double IndexWriter::getRAMBufferSizeMB() - { - return docWriter->getRAMBufferSizeMB(); +void IndexWriter::setRAMBufferSizeMB(double mb) { + if (mb > 2048.0) { + boost::throw_exception(IllegalArgumentException(L"ramBufferSize " + StringUtils::toString(mb) + L" is too large; should be comfortably less than 2048")); } - - void IndexWriter::setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms) - { - ensureOpen(); - if (maxBufferedDeleteTerms != DISABLE_AUTO_FLUSH && maxBufferedDeleteTerms < 1) - boost::throw_exception(IllegalArgumentException(L"maxBufferedDeleteTerms must at least be 1 when enabled")); - docWriter->setMaxBufferedDeleteTerms(maxBufferedDeleteTerms); - if (infoStream) - message(L"setMaxBufferedDeleteTerms " + StringUtils::toString(maxBufferedDeleteTerms)); + if (mb != DISABLE_AUTO_FLUSH && mb <= 0.0) { + boost::throw_exception(IllegalArgumentException(L"ramBufferSize should be > 0.0 MB when enabled")); } - - int32_t IndexWriter::getMaxBufferedDeleteTerms() - { - ensureOpen(); - return docWriter->getMaxBufferedDeleteTerms(); + if (mb == DISABLE_AUTO_FLUSH && getMaxBufferedDocs() == DISABLE_AUTO_FLUSH) { + boost::throw_exception(IllegalArgumentException(L"at least one of ramBufferSize and maxBufferedDocs must be enabled")); } - - void IndexWriter::setMergeFactor(int32_t mergeFactor) - { - getLogMergePolicy()->setMergeFactor(mergeFactor); + docWriter->setRAMBufferSizeMB(mb); + if (infoStream) { + message(L"setRAMBufferSizeMB " + StringUtils::toString(mb)); } +} - int32_t IndexWriter::getMergeFactor() - { - return getLogMergePolicy()->getMergeFactor(); - } +double IndexWriter::getRAMBufferSizeMB() { + return docWriter->getRAMBufferSizeMB(); +} - void IndexWriter::setDefaultInfoStream(const InfoStreamPtr& infoStream) - { - IndexWriter::defaultInfoStream = infoStream; +void IndexWriter::setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms) { + ensureOpen(); + if (maxBufferedDeleteTerms != DISABLE_AUTO_FLUSH && maxBufferedDeleteTerms < 1) { + boost::throw_exception(IllegalArgumentException(L"maxBufferedDeleteTerms must at least be 1 when enabled")); } - - InfoStreamPtr IndexWriter::getDefaultInfoStream() - { - return IndexWriter::defaultInfoStream; + docWriter->setMaxBufferedDeleteTerms(maxBufferedDeleteTerms); + if (infoStream) { + message(L"setMaxBufferedDeleteTerms " + StringUtils::toString(maxBufferedDeleteTerms)); } +} - void IndexWriter::setInfoStream(const InfoStreamPtr& infoStream) - { - ensureOpen(); - setMessageID(infoStream); - docWriter->setInfoStream(infoStream); - deleter->setInfoStream(infoStream); - messageState(); - } +int32_t IndexWriter::getMaxBufferedDeleteTerms() { + ensureOpen(); + return docWriter->getMaxBufferedDeleteTerms(); +} - void IndexWriter::messageState() - { - if (infoStream) - { - message(L"ramBufferSizeMB=" + StringUtils::toString(docWriter->getRAMBufferSizeMB()) + - L" maxBufferedDocs=" + StringUtils::toString(docWriter->getMaxBufferedDocs()) + - L" maxBuffereDeleteTerms=" + StringUtils::toString(docWriter->getMaxBufferedDeleteTerms()) + - L" maxFieldLength=" + StringUtils::toString(maxFieldLength) + - L" index=" + segString()); - } - } +void IndexWriter::setMergeFactor(int32_t mergeFactor) { + getLogMergePolicy()->setMergeFactor(mergeFactor); +} - InfoStreamPtr IndexWriter::getInfoStream() - { - ensureOpen(); - return infoStream; - } +int32_t IndexWriter::getMergeFactor() { + return getLogMergePolicy()->getMergeFactor(); +} - bool IndexWriter::verbose() - { - return infoStream.get() != NULL; - } +void IndexWriter::setDefaultInfoStream(const InfoStreamPtr& infoStream) { + IndexWriter::defaultInfoStream = infoStream; +} - void IndexWriter::setWriteLockTimeout(int64_t writeLockTimeout) - { - ensureOpen(); - this->writeLockTimeout = writeLockTimeout; - } +InfoStreamPtr IndexWriter::getDefaultInfoStream() { + return IndexWriter::defaultInfoStream; +} - int64_t IndexWriter::getWriteLockTimeout() - { - ensureOpen(); - return writeLockTimeout; - } +void IndexWriter::setInfoStream(const InfoStreamPtr& infoStream) { + ensureOpen(); + setMessageID(infoStream); + docWriter->setInfoStream(infoStream); + deleter->setInfoStream(infoStream); + messageState(); +} - void IndexWriter::setDefaultWriteLockTimeout(int64_t writeLockTimeout) - { - IndexWriter::WRITE_LOCK_TIMEOUT = writeLockTimeout; +void IndexWriter::messageState() { + if (infoStream) { + message(L"ramBufferSizeMB=" + StringUtils::toString(docWriter->getRAMBufferSizeMB()) + + L" maxBufferedDocs=" + StringUtils::toString(docWriter->getMaxBufferedDocs()) + + L" maxBuffereDeleteTerms=" + StringUtils::toString(docWriter->getMaxBufferedDeleteTerms()) + + L" maxFieldLength=" + StringUtils::toString(maxFieldLength) + + L" index=" + segString()); } +} - int64_t IndexWriter::getDefaultWriteLockTimeout() - { - return IndexWriter::WRITE_LOCK_TIMEOUT; - } +InfoStreamPtr IndexWriter::getInfoStream() { + ensureOpen(); + return infoStream; +} - void IndexWriter::close() - { - close(true); - } +bool IndexWriter::verbose() { + return infoStream.get() != NULL; +} - void IndexWriter::close(bool waitForMerges) - { - // Ensure that only one thread actually gets to do the closing - if (shouldClose()) - { - // If any methods have hit std::bad_alloc, then abort on close, in case the internal state of IndexWriter - // or DocumentsWriter is corrupt - if (hitOOM) - rollbackInternal(); - else - closeInternal(waitForMerges); +void IndexWriter::setWriteLockTimeout(int64_t writeLockTimeout) { + ensureOpen(); + this->writeLockTimeout = writeLockTimeout; +} + +int64_t IndexWriter::getWriteLockTimeout() { + ensureOpen(); + return writeLockTimeout; +} + +void IndexWriter::setDefaultWriteLockTimeout(int64_t writeLockTimeout) { + IndexWriter::WRITE_LOCK_TIMEOUT = writeLockTimeout; +} + +int64_t IndexWriter::getDefaultWriteLockTimeout() { + return IndexWriter::WRITE_LOCK_TIMEOUT; +} + +void IndexWriter::close() { + close(true); +} + +void IndexWriter::close(bool waitForMerges) { + // Ensure that only one thread actually gets to do the closing + if (shouldClose()) { + // If any methods have hit std::bad_alloc, then abort on close, in case the internal state of IndexWriter + // or DocumentsWriter is corrupt + if (hitOOM) { + rollbackInternal(); + } else { + closeInternal(waitForMerges); } } +} - bool IndexWriter::shouldClose() - { - SyncLock syncLock(this); - while (true) - { - if (!closed) - { - if (!closing) - { - closing = true; - return true; - } - else - { - // Another thread is presently trying to close; wait until it finishes one way (closes - // successfully) or another (fails to close) - doWait(); - } +bool IndexWriter::shouldClose() { + SyncLock syncLock(this); + while (true) { + if (!closed) { + if (!closing) { + closing = true; + return true; + } else { + // Another thread is presently trying to close; wait until it finishes one way (closes + // successfully) or another (fails to close) + doWait(); } - else - return false; + } else { + return false; } } +} - void IndexWriter::closeInternal(bool waitForMerges) - { - docWriter->pauseAllThreads(); - - LuceneException finally; - try - { - if (infoStream) - message(L"now flush at close"); - - docWriter->close(); - - // Only allow a new merge to be triggered if we are going to wait for merges - if (!hitOOM) - flush(waitForMerges, true, true); +void IndexWriter::closeInternal(bool waitForMerges) { + docWriter->pauseAllThreads(); - // Give merge scheduler last chance to run, in case any pending merges are waiting - if (waitForMerges) - mergeScheduler->merge(shared_from_this()); + LuceneException finally; + try { + if (infoStream) { + message(L"now flush at close"); + } - mergePolicy->close(); + docWriter->close(); - finishMerges(waitForMerges); - stopMerges = true; + // Only allow a new merge to be triggered if we are going to wait for merges + if (!hitOOM) { + flush(waitForMerges, true, true); + } - mergeScheduler->close(); + // Give merge scheduler last chance to run, in case any pending merges are waiting + if (waitForMerges) { + mergeScheduler->merge(shared_from_this()); + } - if (infoStream) - message(L"now call final commit()"); + mergePolicy->close(); - if (!hitOOM) - commit(0); + finishMerges(waitForMerges); + stopMerges = true; - if (infoStream) - message(L"at close: " + segString()); + mergeScheduler->close(); - { - SyncLock syncLock(this); - readerPool->close(); - docWriter.reset(); - deleter->close(); - } + if (infoStream) { + message(L"now call final commit()"); + } - if (writeLock) - { - writeLock->release(); // release write lock - writeLock.reset(); - } + if (!hitOOM) { + commit(0); + } - { - SyncLock syncLock(this); - closed = true; - } + if (infoStream) { + message(L"at close: " + segString()); } - catch (std::bad_alloc& oom) + { - finally = handleOOM(oom, L"closeInternal"); + SyncLock syncLock(this); + readerPool->close(); + docWriter.reset(); + deleter->close(); } - catch (LuceneException& e) - { - finally = e; + + if (writeLock) { + writeLock->release(); // release write lock + writeLock.reset(); } + { SyncLock syncLock(this); - closing = false; - notifyAll(); - if (!closed) - { - if (docWriter) - docWriter->resumeAllThreads(); - if (infoStream) - message(L"hit exception while closing"); - } + closed = true; } - finally.throwException(); + } catch (std::bad_alloc& oom) { + finally = handleOOM(oom, L"closeInternal"); + } catch (LuceneException& e) { + finally = e; } - - bool IndexWriter::flushDocStores() { SyncLock syncLock(this); + closing = false; + notifyAll(); + if (!closed) { + if (docWriter) { + docWriter->resumeAllThreads(); + } + if (infoStream) { + message(L"hit exception while closing"); + } + } + } + finally.throwException(); +} - if (infoStream) - message(L"flushDocStores segment=" + docWriter->getDocStoreSegment()); +bool IndexWriter::flushDocStores() { + SyncLock syncLock(this); - bool useCompoundDocStore = false; + if (infoStream) { + message(L"flushDocStores segment=" + docWriter->getDocStoreSegment()); + } - if (infoStream) - message(L"closeDocStores segment=" + docWriter->getDocStoreSegment()); + bool useCompoundDocStore = false; - String docStoreSegment; + if (infoStream) { + message(L"closeDocStores segment=" + docWriter->getDocStoreSegment()); + } - bool success = false; - LuceneException finally; - try - { - docStoreSegment = docWriter->closeDocStore(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success && infoStream) - message(L"hit exception closing doc store segment"); - finally.throwException(); + String docStoreSegment; - if (infoStream) - message(L"flushDocStores files=" + StringUtils::toString(docWriter->closedFiles())); + bool success = false; + LuceneException finally; + try { + docStoreSegment = docWriter->closeDocStore(); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success && infoStream) { + message(L"hit exception closing doc store segment"); + } + finally.throwException(); - useCompoundDocStore = mergePolicy->useCompoundDocStore(segmentInfos); - HashSet closedFiles(docWriter->closedFiles()); + if (infoStream) { + message(L"flushDocStores files=" + StringUtils::toString(docWriter->closedFiles())); + } - if (useCompoundDocStore && !docStoreSegment.empty() && !closedFiles.empty()) - { - // Now build compound doc store file - if (infoStream) - message(L"create compound file " + docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); + useCompoundDocStore = mergePolicy->useCompoundDocStore(segmentInfos); + HashSet closedFiles(docWriter->closedFiles()); - success = false; + if (useCompoundDocStore && !docStoreSegment.empty() && !closedFiles.empty()) { + // Now build compound doc store file + if (infoStream) { + message(L"create compound file " + docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); + } - int32_t numSegments = segmentInfos->size(); - String compoundFileName(docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); + success = false; - try - { - CompoundFileWriterPtr cfsWriter(newLucene(directory, compoundFileName)); - for (HashSet::iterator file = closedFiles.begin(); file != closedFiles.end(); ++file) - cfsWriter->addFile(*file); + int32_t numSegments = segmentInfos->size(); + String compoundFileName(docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); - // Perform the merge - cfsWriter->close(); - success = true; - } - catch (LuceneException& e) - { - finally = e; + try { + CompoundFileWriterPtr cfsWriter(newLucene(directory, compoundFileName)); + for (HashSet::iterator file = closedFiles.begin(); file != closedFiles.end(); ++file) { + cfsWriter->addFile(*file); } - if (!success) - { - if (infoStream) - message(L"hit exception building compound file doc store for segment " + docStoreSegment); - deleter->deleteFile(compoundFileName); - docWriter->abort(); - } - finally.throwException(); + // Perform the merge + cfsWriter->close(); + success = true; + } catch (LuceneException& e) { + finally = e; + } - for (int32_t i = 0; i < numSegments; ++i) - { - SegmentInfoPtr si(segmentInfos->info(i)); - if (si->getDocStoreOffset() != -1 && si->getDocStoreSegment() == docStoreSegment) - si->setDocStoreIsCompoundFile(true); + if (!success) { + if (infoStream) { + message(L"hit exception building compound file doc store for segment " + docStoreSegment); } + deleter->deleteFile(compoundFileName); + docWriter->abort(); + } + finally.throwException(); - checkpoint(); - - // In case the files we just merged into a CFS were not previously checkpointed - deleter->deleteNewFiles(docWriter->closedFiles()); + for (int32_t i = 0; i < numSegments; ++i) { + SegmentInfoPtr si(segmentInfos->info(i)); + if (si->getDocStoreOffset() != -1 && si->getDocStoreSegment() == docStoreSegment) { + si->setDocStoreIsCompoundFile(true); + } } - return useCompoundDocStore; - } + checkpoint(); - DirectoryPtr IndexWriter::getDirectory() - { - ensureOpen(false); // Pass false because the flush during closing calls getDirectory - return directory; + // In case the files we just merged into a CFS were not previously checkpointed + deleter->deleteNewFiles(docWriter->closedFiles()); } - AnalyzerPtr IndexWriter::getAnalyzer() - { - ensureOpen(); - return analyzer; - } + return useCompoundDocStore; +} - int32_t IndexWriter::maxDoc() - { - SyncLock syncLock(this); - int32_t count = docWriter ? docWriter->getNumDocsInRAM() : 0; - for (int32_t i = 0; i < segmentInfos->size(); ++i) - count += segmentInfos->info(i)->docCount; - return count; - } +DirectoryPtr IndexWriter::getDirectory() { + ensureOpen(false); // Pass false because the flush during closing calls getDirectory + return directory; +} - int32_t IndexWriter::numDocs() - { - SyncLock syncLock(this); - int32_t count = docWriter ? docWriter->getNumDocsInRAM() : 0; - for (int32_t i = 0; i < segmentInfos->size(); ++i) - { - SegmentInfoPtr info(segmentInfos->info(i)); - count += info->docCount - info->getDelCount(); - } - return count; +AnalyzerPtr IndexWriter::getAnalyzer() { + ensureOpen(); + return analyzer; +} + +int32_t IndexWriter::maxDoc() { + SyncLock syncLock(this); + int32_t count = docWriter ? docWriter->getNumDocsInRAM() : 0; + for (int32_t i = 0; i < segmentInfos->size(); ++i) { + count += segmentInfos->info(i)->docCount; } + return count; +} - bool IndexWriter::hasDeletions() - { - SyncLock syncLock(this); - ensureOpen(); - if (docWriter->hasDeletes()) +int32_t IndexWriter::numDocs() { + SyncLock syncLock(this); + int32_t count = docWriter ? docWriter->getNumDocsInRAM() : 0; + for (int32_t i = 0; i < segmentInfos->size(); ++i) { + SegmentInfoPtr info(segmentInfos->info(i)); + count += info->docCount - info->getDelCount(); + } + return count; +} + +bool IndexWriter::hasDeletions() { + SyncLock syncLock(this); + ensureOpen(); + if (docWriter->hasDeletes()) { + return true; + } + for (int32_t i = 0; i < segmentInfos->size(); ++i) { + if (segmentInfos->info(i)->hasDeletions()) { return true; - for (int32_t i = 0; i < segmentInfos->size(); ++i) - { - if (segmentInfos->info(i)->hasDeletions()) - return true; } - return false; } + return false; +} - void IndexWriter::addDocument(const DocumentPtr& doc) - { - addDocument(doc, analyzer); - } +void IndexWriter::addDocument(const DocumentPtr& doc) { + addDocument(doc, analyzer); +} - void IndexWriter::addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer) - { - ensureOpen(); - bool doFlush = false; - bool success = false; - try - { - LuceneException finally; - try - { - doFlush = docWriter->addDocument(doc, analyzer); - success = true; - } - catch (LuceneException& e) - { - finally = e; +void IndexWriter::addDocument(const DocumentPtr& doc, const AnalyzerPtr& analyzer) { + ensureOpen(); + bool doFlush = false; + bool success = false; + try { + LuceneException finally; + try { + doFlush = docWriter->addDocument(doc, analyzer); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + if (infoStream) { + message(L"hit exception adding document"); } - if (!success) { - if (infoStream) - message(L"hit exception adding document"); - { - SyncLock syncLock(this); - // If docWriter has some aborted files that were never incref'd, then we clean them up here - if (docWriter) - { - HashSet files(docWriter->abortedFiles()); - if (files) - deleter->deleteNewFiles(files); + SyncLock syncLock(this); + // If docWriter has some aborted files that were never incref'd, then we clean them up here + if (docWriter) { + HashSet files(docWriter->abortedFiles()); + if (files) { + deleter->deleteNewFiles(files); } } } - finally.throwException(); - if (doFlush) - flush(true, false, false); } - catch (std::bad_alloc& oom) - { - boost::throw_exception(handleOOM(oom, L"addDocument")); + finally.throwException(); + if (doFlush) { + flush(true, false, false); } + } catch (std::bad_alloc& oom) { + boost::throw_exception(handleOOM(oom, L"addDocument")); } +} - void IndexWriter::deleteDocuments(const TermPtr& term) - { - ensureOpen(); - try - { - bool doFlush = docWriter->bufferDeleteTerm(term); - if (doFlush) - flush(true, false, false); - } - catch (std::bad_alloc& oom) - { - boost::throw_exception(handleOOM(oom, L"deleteDocuments(Term)")); +void IndexWriter::deleteDocuments(const TermPtr& term) { + ensureOpen(); + try { + bool doFlush = docWriter->bufferDeleteTerm(term); + if (doFlush) { + flush(true, false, false); } + } catch (std::bad_alloc& oom) { + boost::throw_exception(handleOOM(oom, L"deleteDocuments(Term)")); } +} - void IndexWriter::deleteDocuments(Collection terms) - { - ensureOpen(); - try - { - bool doFlush = docWriter->bufferDeleteTerms(terms); - if (doFlush) - flush(true, false, false); - } - catch (std::bad_alloc& oom) - { - boost::throw_exception(handleOOM(oom, L"deleteDocuments(VectorTerm)")); +void IndexWriter::deleteDocuments(Collection terms) { + ensureOpen(); + try { + bool doFlush = docWriter->bufferDeleteTerms(terms); + if (doFlush) { + flush(true, false, false); } + } catch (std::bad_alloc& oom) { + boost::throw_exception(handleOOM(oom, L"deleteDocuments(VectorTerm)")); } +} - void IndexWriter::deleteDocuments(const QueryPtr& query) - { - ensureOpen(); - bool doFlush = docWriter->bufferDeleteQuery(query); - if (doFlush) - flush(true, false, false); +void IndexWriter::deleteDocuments(const QueryPtr& query) { + ensureOpen(); + bool doFlush = docWriter->bufferDeleteQuery(query); + if (doFlush) { + flush(true, false, false); } +} - void IndexWriter::deleteDocuments(Collection queries) - { - ensureOpen(); - bool doFlush = docWriter->bufferDeleteQueries(queries); - if (doFlush) - flush(true, false, false); +void IndexWriter::deleteDocuments(Collection queries) { + ensureOpen(); + bool doFlush = docWriter->bufferDeleteQueries(queries); + if (doFlush) { + flush(true, false, false); } +} - void IndexWriter::updateDocument(const TermPtr& term, const DocumentPtr& doc) - { - ensureOpen(); - updateDocument(term, doc, getAnalyzer()); - } +void IndexWriter::updateDocument(const TermPtr& term, const DocumentPtr& doc) { + ensureOpen(); + updateDocument(term, doc, getAnalyzer()); +} - void IndexWriter::updateDocument(const TermPtr& term, const DocumentPtr& doc, const AnalyzerPtr& analyzer) - { - ensureOpen(); - try - { - bool doFlush = false; - bool success = false; - LuceneException finally; - try - { - doFlush = docWriter->updateDocument(term, doc, analyzer); - success = true; - } - catch (LuceneException& e) - { - finally = e; +void IndexWriter::updateDocument(const TermPtr& term, const DocumentPtr& doc, const AnalyzerPtr& analyzer) { + ensureOpen(); + try { + bool doFlush = false; + bool success = false; + LuceneException finally; + try { + doFlush = docWriter->updateDocument(term, doc, analyzer); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + if (infoStream) { + message(L"hit exception updating document"); } - if (!success) - { - if (infoStream) - message(L"hit exception updating document"); - { - SyncLock syncLock(this); - // If docWriter has some aborted files that were never incref'd, then we clean them up here - if (docWriter) - { - HashSet files(docWriter->abortedFiles()); - if (files) - deleter->deleteNewFiles(files); + { + SyncLock syncLock(this); + // If docWriter has some aborted files that were never incref'd, then we clean them up here + if (docWriter) { + HashSet files(docWriter->abortedFiles()); + if (files) { + deleter->deleteNewFiles(files); } } } - finally.throwException(); - if (doFlush) - flush(true, false, false); } - catch (std::bad_alloc& oom) - { - boost::throw_exception(handleOOM(oom, L"updateDocument")); + finally.throwException(); + if (doFlush) { + flush(true, false, false); } + } catch (std::bad_alloc& oom) { + boost::throw_exception(handleOOM(oom, L"updateDocument")); } +} - int32_t IndexWriter::getSegmentCount() - { - SyncLock syncLock(this); - return segmentInfos->size(); - } +int32_t IndexWriter::getSegmentCount() { + SyncLock syncLock(this); + return segmentInfos->size(); +} - int32_t IndexWriter::getNumBufferedDocuments() - { - SyncLock syncLock(this); - return docWriter->getNumDocsInRAM(); - } +int32_t IndexWriter::getNumBufferedDocuments() { + SyncLock syncLock(this); + return docWriter->getNumDocsInRAM(); +} - int32_t IndexWriter::getDocCount(int32_t i) - { - SyncLock syncLock(this); - return (i >= 0 && i < segmentInfos->size()) ? segmentInfos->info(i)->docCount : -1; - } +int32_t IndexWriter::getDocCount(int32_t i) { + SyncLock syncLock(this); + return (i >= 0 && i < segmentInfos->size()) ? segmentInfos->info(i)->docCount : -1; +} - int32_t IndexWriter::getFlushCount() - { - SyncLock syncLock(this); - return flushCount; - } +int32_t IndexWriter::getFlushCount() { + SyncLock syncLock(this); + return flushCount; +} - int32_t IndexWriter::getFlushDeletesCount() - { - SyncLock syncLock(this); - return flushDeletesCount; - } +int32_t IndexWriter::getFlushDeletesCount() { + SyncLock syncLock(this); + return flushDeletesCount; +} - String IndexWriter::newSegmentName() - { - // Cannot synchronize on IndexWriter because that causes deadlock - SyncLock segmentLock(segmentInfos); +String IndexWriter::newSegmentName() { + // Cannot synchronize on IndexWriter because that causes deadlock + SyncLock segmentLock(segmentInfos); - // Important to increment changeCount so that the segmentInfos is written on close. - // Otherwise we could close, re-open and re-return the same segment name that was - // previously returned which can cause problems at least with ConcurrentMergeScheduler. - ++changeCount; - return L"_" + StringUtils::toString(segmentInfos->counter++, StringUtils::CHARACTER_MAX_RADIX); - } + // Important to increment changeCount so that the segmentInfos is written on close. + // Otherwise we could close, re-open and re-return the same segment name that was + // previously returned which can cause problems at least with ConcurrentMergeScheduler. + ++changeCount; + return L"_" + StringUtils::toString(segmentInfos->counter++, StringUtils::CHARACTER_MAX_RADIX); +} - void IndexWriter::optimize() - { - optimize(true); - } +void IndexWriter::optimize() { + optimize(true); +} - void IndexWriter::optimize(int32_t maxNumSegments) - { - optimize(maxNumSegments, true); - } +void IndexWriter::optimize(int32_t maxNumSegments) { + optimize(maxNumSegments, true); +} - void IndexWriter::optimize(bool doWait) - { - optimize(1, doWait); - } +void IndexWriter::optimize(bool doWait) { + optimize(1, doWait); +} - void IndexWriter::optimize(int32_t maxNumSegments, bool doWait) - { - ensureOpen(); +void IndexWriter::optimize(int32_t maxNumSegments, bool doWait) { + ensureOpen(); - if (maxNumSegments < 1) - boost::throw_exception(IllegalArgumentException(L"maxNumSegments must be >= 1; got " + StringUtils::toString(maxNumSegments))); + if (maxNumSegments < 1) { + boost::throw_exception(IllegalArgumentException(L"maxNumSegments must be >= 1; got " + StringUtils::toString(maxNumSegments))); + } - if (infoStream) - message(L"optimize: index now " + segString()); + if (infoStream) { + message(L"optimize: index now " + segString()); + } - flush(true, false, true); + flush(true, false, true); - { - SyncLock syncLock(this); + { + SyncLock syncLock(this); - resetMergeExceptions(); - segmentsToOptimize.clear(); - optimizeMaxNumSegments = maxNumSegments; - int32_t numSegments = segmentInfos->size(); - for (int32_t i = 0; i < numSegments; ++i) - segmentsToOptimize.add(segmentInfos->info(i)); + resetMergeExceptions(); + segmentsToOptimize.clear(); + optimizeMaxNumSegments = maxNumSegments; + int32_t numSegments = segmentInfos->size(); + for (int32_t i = 0; i < numSegments; ++i) { + segmentsToOptimize.add(segmentInfos->info(i)); + } - // Now mark all pending & running merges as optimize merge - for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) - { - (*merge)->optimize = true; - (*merge)->maxNumSegmentsOptimize = maxNumSegments; - } + // Now mark all pending & running merges as optimize merge + for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) { + (*merge)->optimize = true; + (*merge)->maxNumSegmentsOptimize = maxNumSegments; + } - for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) - { - (*merge)->optimize = true; - (*merge)->maxNumSegmentsOptimize = maxNumSegments; - } + for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) { + (*merge)->optimize = true; + (*merge)->maxNumSegmentsOptimize = maxNumSegments; } + } - maybeMerge(maxNumSegments, true); + maybeMerge(maxNumSegments, true); - if (doWait) + if (doWait) { { - { - SyncLock syncLock(this); - while (true) - { - if (hitOOM) - boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete optimize")); + SyncLock syncLock(this); + while (true) { + if (hitOOM) { + boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete optimize")); + } - if (!mergeExceptions.empty()) - { - // Forward any exceptions in background merge threads to the current thread - for (Collection::iterator merge = mergeExceptions.begin(); merge != mergeExceptions.end(); ++merge) - { - if ((*merge)->optimize) - { - LuceneException err = (*merge)->getException(); - if (!err.isNull()) - boost::throw_exception(IOException(L"background merge hit exception: " + (*merge)->segString(directory))); + if (!mergeExceptions.empty()) { + // Forward any exceptions in background merge threads to the current thread + for (Collection::iterator merge = mergeExceptions.begin(); merge != mergeExceptions.end(); ++merge) { + if ((*merge)->optimize) { + LuceneException err = (*merge)->getException(); + if (!err.isNull()) { + boost::throw_exception(IOException(L"background merge hit exception: " + (*merge)->segString(directory))); } } } + } - if (optimizeMergesPending()) - IndexWriter::doWait(); - else - break; + if (optimizeMergesPending()) { + IndexWriter::doWait(); + } else { + break; } } - - // If close is called while we are still running, throw an exception so the calling thread will know the - // optimize did not complete - ensureOpen(); } - // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background - // threads accomplish the optimization + // If close is called while we are still running, throw an exception so the calling thread will know the + // optimize did not complete + ensureOpen(); } - bool IndexWriter::optimizeMergesPending() - { - SyncLock syncLock(this); + // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background + // threads accomplish the optimization +} - for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) - { - if ((*merge)->optimize) - return true; - } +bool IndexWriter::optimizeMergesPending() { + SyncLock syncLock(this); - for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) - { - if ((*merge)->optimize) - return true; + for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) { + if ((*merge)->optimize) { + return true; } + } - return false; + for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) { + if ((*merge)->optimize) { + return true; + } } - void IndexWriter::expungeDeletes(bool doWait) - { - ensureOpen(); + return false; +} - if (infoStream) - message(L"expungeDeletes: index now " + segString()); +void IndexWriter::expungeDeletes(bool doWait) { + ensureOpen(); - MergeSpecificationPtr spec; + if (infoStream) { + message(L"expungeDeletes: index now " + segString()); + } - { - SyncLock syncLock(this); - spec = mergePolicy->findMergesToExpungeDeletes(segmentInfos); - for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) - registerMerge(*merge); + MergeSpecificationPtr spec; + + { + SyncLock syncLock(this); + spec = mergePolicy->findMergesToExpungeDeletes(segmentInfos); + for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) { + registerMerge(*merge); } + } - mergeScheduler->merge(shared_from_this()); + mergeScheduler->merge(shared_from_this()); - if (doWait) + if (doWait) { { - { - SyncLock syncLock(this); - bool running = true; - while (running) - { - if (hitOOM) - boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete expungeDeletes")); + SyncLock syncLock(this); + bool running = true; + while (running) { + if (hitOOM) { + boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete expungeDeletes")); + } - // Check each merge that MergePolicy asked us to do, to see if any of them are still running and - // if any of them have hit an exception. - running = false; - for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) - { - if (pendingMerges.contains(*merge) || runningMerges.contains(*merge)) - running = true; - LuceneException err = (*merge)->getException(); - if (!err.isNull()) - boost::throw_exception(IOException(L"background merge hit exception: " + (*merge)->segString(directory))); + // Check each merge that MergePolicy asked us to do, to see if any of them are still running and + // if any of them have hit an exception. + running = false; + for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) { + if (pendingMerges.contains(*merge) || runningMerges.contains(*merge)) { + running = true; } + LuceneException err = (*merge)->getException(); + if (!err.isNull()) { + boost::throw_exception(IOException(L"background merge hit exception: " + (*merge)->segString(directory))); + } + } - // If any of our merges are still running, wait - if (running) - IndexWriter::doWait(); + // If any of our merges are still running, wait + if (running) { + IndexWriter::doWait(); } } } - - // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background - // threads accomplish the optimization } - void IndexWriter::expungeDeletes() - { - expungeDeletes(true); - } + // NOTE: in the ConcurrentMergeScheduler case, when doWait is false, we can return immediately while background + // threads accomplish the optimization +} - void IndexWriter::maybeMerge() - { - maybeMerge(false); - } +void IndexWriter::expungeDeletes() { + expungeDeletes(true); +} - void IndexWriter::maybeMerge(bool optimize) - { - maybeMerge(1, optimize); - } +void IndexWriter::maybeMerge() { + maybeMerge(false); +} - void IndexWriter::maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize) - { - updatePendingMerges(maxNumSegmentsOptimize, optimize); - mergeScheduler->merge(shared_from_this()); - } +void IndexWriter::maybeMerge(bool optimize) { + maybeMerge(1, optimize); +} - void IndexWriter::updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize) - { - SyncLock syncLock(this); - BOOST_ASSERT(!optimize || maxNumSegmentsOptimize > 0); +void IndexWriter::maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize) { + updatePendingMerges(maxNumSegmentsOptimize, optimize); + mergeScheduler->merge(shared_from_this()); +} - if (stopMerges) - return; +void IndexWriter::updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize) { + SyncLock syncLock(this); + BOOST_ASSERT(!optimize || maxNumSegmentsOptimize > 0); - // Do not start new merges if we've hit std::bad_alloc - if (hitOOM) - return; + if (stopMerges) { + return; + } - MergeSpecificationPtr spec; + // Do not start new merges if we've hit std::bad_alloc + if (hitOOM) { + return; + } - if (optimize) - { - spec = mergePolicy->findMergesForOptimize(segmentInfos, maxNumSegmentsOptimize, segmentsToOptimize); + MergeSpecificationPtr spec; - if (spec) - { - for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) - { - (*merge)->optimize = true; - (*merge)->maxNumSegmentsOptimize = maxNumSegmentsOptimize; - } - } - } - else - spec = mergePolicy->findMerges(segmentInfos); + if (optimize) { + spec = mergePolicy->findMergesForOptimize(segmentInfos, maxNumSegmentsOptimize, segmentsToOptimize); - if (spec) - { - for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) - registerMerge(*merge); + if (spec) { + for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) { + (*merge)->optimize = true; + (*merge)->maxNumSegmentsOptimize = maxNumSegmentsOptimize; + } } + } else { + spec = mergePolicy->findMerges(segmentInfos); } - OneMergePtr IndexWriter::getNextMerge() - { - SyncLock syncLock(this); - if (pendingMerges.empty()) - return OneMergePtr(); - else - { - // Advance the merge from pending to running - OneMergePtr merge(pendingMerges.removeFirst()); - runningMerges.add(merge); - return merge; + if (spec) { + for (Collection::iterator merge = spec->merges.begin(); merge != spec->merges.end(); ++merge) { + registerMerge(*merge); } } +} - OneMergePtr IndexWriter::getNextExternalMerge() - { - SyncLock syncLock(this); - if (pendingMerges.empty()) - return OneMergePtr(); - else - { - for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) - { - if ((*merge)->isExternal) - { - // Advance the merge from pending to running - OneMergePtr running(*merge); - runningMerges.add(*merge); - pendingMerges.remove(merge); - return running; - } - } - } - - // All existing merges do not involve external segments +OneMergePtr IndexWriter::getNextMerge() { + SyncLock syncLock(this); + if (pendingMerges.empty()) { return OneMergePtr(); + } else { + // Advance the merge from pending to running + OneMergePtr merge(pendingMerges.removeFirst()); + runningMerges.add(merge); + return merge; } +} - void IndexWriter::startTransaction(bool haveReadLock) - { - SyncLock syncLock(this); - bool success = false; - LuceneException finally; - try - { - if (infoStream) - message(L"now start transaction"); - - BOOST_ASSERT(docWriter->getNumBufferedDeleteTerms() == 0); // calling startTransaction with buffered delete terms not supported - BOOST_ASSERT(docWriter->getNumDocsInRAM() == 0); // calling startTransaction with buffered documents not supported - - ensureOpen(); - - // If a transaction is trying to roll back (because addIndexes hit an exception) then wait here until that's done - while (stopMerges) - doWait(); - - success = true; - } - catch (LuceneException& e) - { - finally = e; +OneMergePtr IndexWriter::getNextExternalMerge() { + SyncLock syncLock(this); + if (pendingMerges.empty()) { + return OneMergePtr(); + } else { + for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) { + if ((*merge)->isExternal) { + // Advance the merge from pending to running + OneMergePtr running(*merge); + runningMerges.add(*merge); + pendingMerges.remove(merge); + return running; + } } + } - // Release the write lock if our caller held it, on hitting an exception - if (!success && haveReadLock) - releaseRead(); - finally.throwException(); - - if (haveReadLock) - upgradeReadToWrite(); - else - acquireWrite(); - - success = false; - - try - { - localRollbackSegmentInfos = boost::dynamic_pointer_cast(segmentInfos->clone()); + // All existing merges do not involve external segments + return OneMergePtr(); +} - BOOST_ASSERT(!hasExternalSegments()); +void IndexWriter::startTransaction(bool haveReadLock) { + SyncLock syncLock(this); + bool success = false; + LuceneException finally; + try { + if (infoStream) { + message(L"now start transaction"); + } - localFlushedDocCount = docWriter->getFlushedDocCount(); + BOOST_ASSERT(docWriter->getNumBufferedDeleteTerms() == 0); // calling startTransaction with buffered delete terms not supported + BOOST_ASSERT(docWriter->getNumDocsInRAM() == 0); // calling startTransaction with buffered documents not supported - // We must "protect" our files at this point from deletion in case we need to rollback - deleter->incRef(segmentInfos, false); + ensureOpen(); - success = true; - } - catch (LuceneException& e) - { - finally = e; + // If a transaction is trying to roll back (because addIndexes hit an exception) then wait here until that's done + while (stopMerges) { + doWait(); } - if (!success) - finishAddIndexes(); - finally.throwException(); + success = true; + } catch (LuceneException& e) { + finally = e; } - void IndexWriter::rollbackTransaction() - { - SyncLock syncLock(this); + // Release the write lock if our caller held it, on hitting an exception + if (!success && haveReadLock) { + releaseRead(); + } + finally.throwException(); - if (infoStream) - message(L"now rollback transaction"); + if (haveReadLock) { + upgradeReadToWrite(); + } else { + acquireWrite(); + } - if (docWriter) - docWriter->setFlushedDocCount(localFlushedDocCount); + success = false; - // Must finish merges before rolling back segmentInfos so merges don't hit exceptions on trying to commit - // themselves, don't get files deleted out from under them, etc. - finishMerges(false); + try { + localRollbackSegmentInfos = boost::dynamic_pointer_cast(segmentInfos->clone()); - // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next - // attempt to commit using this instance of IndexWriter will always write to a new generation ("write once"). - segmentInfos->clear(); - segmentInfos->addAll(localRollbackSegmentInfos); - localRollbackSegmentInfos.reset(); + BOOST_ASSERT(!hasExternalSegments()); - // This must come after we rollback segmentInfos, so that if a commit() kicks off it does not see the - // segmentInfos with external segments. - finishAddIndexes(); + localFlushedDocCount = docWriter->getFlushedDocCount(); - // Ask deleter to locate unreferenced files we had created & remove them - deleter->checkpoint(segmentInfos, false); + // We must "protect" our files at this point from deletion in case we need to rollback + deleter->incRef(segmentInfos, false); - // Remove the incRef we did in startTransaction - deleter->decRef(segmentInfos); + success = true; + } catch (LuceneException& e) { + finally = e; + } - // Also ask deleter to remove any newly created files that were never incref'd; this "garbage" is created - // when a merge kicks off but aborts part way through before it had a chance to incRef the files it had - // partially created - deleter->refresh(); + if (!success) { + finishAddIndexes(); + } + finally.throwException(); +} - notifyAll(); +void IndexWriter::rollbackTransaction() { + SyncLock syncLock(this); - BOOST_ASSERT(!hasExternalSegments()); + if (infoStream) { + message(L"now rollback transaction"); } - void IndexWriter::commitTransaction() - { - SyncLock syncLock(this); + if (docWriter) { + docWriter->setFlushedDocCount(localFlushedDocCount); + } - if (infoStream) - message(L"now commit transaction"); + // Must finish merges before rolling back segmentInfos so merges don't hit exceptions on trying to commit + // themselves, don't get files deleted out from under them, etc. + finishMerges(false); - // Give deleter a chance to remove files now - checkpoint(); + // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next + // attempt to commit using this instance of IndexWriter will always write to a new generation ("write once"). + segmentInfos->clear(); + segmentInfos->addAll(localRollbackSegmentInfos); + localRollbackSegmentInfos.reset(); - // Remove the incRef we did in startTransaction. - deleter->decRef(localRollbackSegmentInfos); + // This must come after we rollback segmentInfos, so that if a commit() kicks off it does not see the + // segmentInfos with external segments. + finishAddIndexes(); - localRollbackSegmentInfos.reset(); + // Ask deleter to locate unreferenced files we had created & remove them + deleter->checkpoint(segmentInfos, false); - BOOST_ASSERT(!hasExternalSegments()); + // Remove the incRef we did in startTransaction + deleter->decRef(segmentInfos); - finishAddIndexes(); - } + // Also ask deleter to remove any newly created files that were never incref'd; this "garbage" is created + // when a merge kicks off but aborts part way through before it had a chance to incRef the files it had + // partially created + deleter->refresh(); - void IndexWriter::rollback() - { - ensureOpen(); + notifyAll(); - // Ensure that only one thread actually gets to do the closing - if (shouldClose()) - rollbackInternal(); - } + BOOST_ASSERT(!hasExternalSegments()); +} - void IndexWriter::rollbackInternal() - { - bool success = false; +void IndexWriter::commitTransaction() { + SyncLock syncLock(this); - if (infoStream) - message(L"rollback"); + if (infoStream) { + message(L"now commit transaction"); + } - docWriter->pauseAllThreads(); - LuceneException finally; - try - { - finishMerges(false); + // Give deleter a chance to remove files now + checkpoint(); - // Must pre-close these two, in case they increment changeCount so that we can then set it to false before - // calling closeInternal - mergePolicy->close(); - mergeScheduler->close(); + // Remove the incRef we did in startTransaction. + deleter->decRef(localRollbackSegmentInfos); - { - SyncLock syncLock(this); + localRollbackSegmentInfos.reset(); - if (pendingCommit) - { - pendingCommit->rollbackCommit(directory); - deleter->decRef(pendingCommit); - pendingCommit.reset(); - notifyAll(); - } + BOOST_ASSERT(!hasExternalSegments()); - // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next - // attempt to commit using this instance of IndexWriter will always write to a new generation ("write once"). - segmentInfos->clear(); - segmentInfos->addAll(rollbackSegmentInfos); + finishAddIndexes(); +} - BOOST_ASSERT(!hasExternalSegments()); +void IndexWriter::rollback() { + ensureOpen(); - docWriter->abort(); + // Ensure that only one thread actually gets to do the closing + if (shouldClose()) { + rollbackInternal(); + } +} - bool test = testPoint(L"rollback before checkpoint"); - BOOST_ASSERT(test); +void IndexWriter::rollbackInternal() { + bool success = false; - // Ask deleter to locate unreferenced files & remove them - deleter->checkpoint(segmentInfos, false); - deleter->refresh(); - } + if (infoStream) { + message(L"rollback"); + } - // Don't bother saving any changes in our segmentInfos - readerPool->clear(SegmentInfosPtr()); + docWriter->pauseAllThreads(); + LuceneException finally; + try { + finishMerges(false); - lastCommitChangeCount = changeCount; + // Must pre-close these two, in case they increment changeCount so that we can then set it to false before + // calling closeInternal + mergePolicy->close(); + mergeScheduler->close(); - success = true; - } - catch (std::bad_alloc& oom) - { - finally = handleOOM(oom, L"rollbackInternal"); - } - catch (LuceneException& e) - { - finally = e; - } { SyncLock syncLock(this); - if (!success) - { - docWriter->resumeAllThreads(); - closing = false; + if (pendingCommit) { + pendingCommit->rollbackCommit(directory); + deleter->decRef(pendingCommit); + pendingCommit.reset(); notifyAll(); - if (infoStream) - message(L"hit exception during rollback"); } - } - finally.throwException(); - closeInternal(false); - } + // Keep the same segmentInfos instance but replace all of its SegmentInfo instances. This is so the next + // attempt to commit using this instance of IndexWriter will always write to a new generation ("write once"). + segmentInfos->clear(); + segmentInfos->addAll(rollbackSegmentInfos); - void IndexWriter::deleteAll() - { - SyncLock syncLock(this); - bool success = false; - docWriter->pauseAllThreads(); - LuceneException finally; - try - { - // Abort any running merges - finishMerges(false); + BOOST_ASSERT(!hasExternalSegments()); - // Remove any buffered docs docWriter->abort(); - docWriter->setFlushedDocCount(0); - // Remove all segments - segmentInfos->clear(); + bool test = testPoint(L"rollback before checkpoint"); + BOOST_ASSERT(test); // Ask deleter to locate unreferenced files & remove them deleter->checkpoint(segmentInfos, false); deleter->refresh(); - - // Don't bother saving any changes in our segmentInfos - readerPool->clear(SegmentInfosPtr()); - - // Mark that the index has changed - ++changeCount; - - success = true; - } - catch (std::bad_alloc& oom) - { - finally = handleOOM(oom, L"deleteAll"); - } - catch (LuceneException& e) - { - finally = e; } - docWriter->resumeAllThreads(); - if (!success && infoStream) - message(L"hit exception during deleteAll"); + // Don't bother saving any changes in our segmentInfos + readerPool->clear(SegmentInfosPtr()); - finally.throwException(); - } + lastCommitChangeCount = changeCount; - void IndexWriter::finishMerges(bool waitForMerges) + success = true; + } catch (std::bad_alloc& oom) { + finally = handleOOM(oom, L"rollbackInternal"); + } catch (LuceneException& e) { + finally = e; + } { SyncLock syncLock(this); - if (!waitForMerges) - { - stopMerges = true; - // Abort all pending and running merges - for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) - { - if (infoStream) - message(L"now abort pending merge " + (*merge)->segString(directory)); - (*merge)->abort(); - mergeFinish(*merge); + if (!success) { + docWriter->resumeAllThreads(); + closing = false; + notifyAll(); + if (infoStream) { + message(L"hit exception during rollback"); } - pendingMerges.clear(); + } + } + finally.throwException(); - for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) - { - if (infoStream) - message(L"now abort running merge " + (*merge)->segString(directory)); - (*merge)->abort(); - } + closeInternal(false); +} - // Ensure any running addIndexes finishes. It's fine if a new one attempts to start because its merges - // will quickly see the stopMerges == true and abort. - acquireRead(); - releaseRead(); +void IndexWriter::deleteAll() { + SyncLock syncLock(this); + bool success = false; + docWriter->pauseAllThreads(); + LuceneException finally; + try { + // Abort any running merges + finishMerges(false); - // These merges periodically check whether they have been aborted, and stop if so. We wait here to make - // sure they all stop. It should not take very long because the merge threads periodically check if they - // are aborted. - while (!runningMerges.empty()) - { - if (infoStream) - message(L"now wait for " + StringUtils::toString(runningMerges.size()) + L" running merge to abort"); - doWait(); - } + // Remove any buffered docs + docWriter->abort(); + docWriter->setFlushedDocCount(0); - stopMerges = false; - notifyAll(); + // Remove all segments + segmentInfos->clear(); + + // Ask deleter to locate unreferenced files & remove them + deleter->checkpoint(segmentInfos, false); + deleter->refresh(); + + // Don't bother saving any changes in our segmentInfos + readerPool->clear(SegmentInfosPtr()); + + // Mark that the index has changed + ++changeCount; + + success = true; + } catch (std::bad_alloc& oom) { + finally = handleOOM(oom, L"deleteAll"); + } catch (LuceneException& e) { + finally = e; + } + + docWriter->resumeAllThreads(); + if (!success && infoStream) { + message(L"hit exception during deleteAll"); + } + + finally.throwException(); +} - BOOST_ASSERT(mergingSegments.empty()); +void IndexWriter::finishMerges(bool waitForMerges) { + SyncLock syncLock(this); + if (!waitForMerges) { + stopMerges = true; - if (infoStream) - message(L"all running merges have aborted"); + // Abort all pending and running merges + for (Collection::iterator merge = pendingMerges.begin(); merge != pendingMerges.end(); ++merge) { + if (infoStream) { + message(L"now abort pending merge " + (*merge)->segString(directory)); + } + (*merge)->abort(); + mergeFinish(*merge); } - else - { - // waitForMerges() will ensure any running addIndexes finishes. It's fine if a new one attempts to start - // because from our caller above the call will see that we are in the process of closing, and will throw - // an AlreadyClosed exception. - IndexWriter::waitForMerges(); + pendingMerges.clear(); + + for (SetOneMerge::iterator merge = runningMerges.begin(); merge != runningMerges.end(); ++merge) { + if (infoStream) { + message(L"now abort running merge " + (*merge)->segString(directory)); + } + (*merge)->abort(); } - } - void IndexWriter::waitForMerges() - { - SyncLock syncLock(this); - // Ensure any running addIndexes finishes. + // Ensure any running addIndexes finishes. It's fine if a new one attempts to start because its merges + // will quickly see the stopMerges == true and abort. acquireRead(); releaseRead(); - while (!pendingMerges.empty() || !runningMerges.empty()) + // These merges periodically check whether they have been aborted, and stop if so. We wait here to make + // sure they all stop. It should not take very long because the merge threads periodically check if they + // are aborted. + while (!runningMerges.empty()) { + if (infoStream) { + message(L"now wait for " + StringUtils::toString(runningMerges.size()) + L" running merge to abort"); + } doWait(); + } + + stopMerges = false; + notifyAll(); - // sanity check BOOST_ASSERT(mergingSegments.empty()); - } - void IndexWriter::checkpoint() - { - SyncLock syncLock(this); - ++changeCount; - deleter->checkpoint(segmentInfos, false); + if (infoStream) { + message(L"all running merges have aborted"); + } + } else { + // waitForMerges() will ensure any running addIndexes finishes. It's fine if a new one attempts to start + // because from our caller above the call will see that we are in the process of closing, and will throw + // an AlreadyClosed exception. + IndexWriter::waitForMerges(); } +} - void IndexWriter::finishAddIndexes() - { - releaseWrite(); +void IndexWriter::waitForMerges() { + SyncLock syncLock(this); + // Ensure any running addIndexes finishes. + acquireRead(); + releaseRead(); + + while (!pendingMerges.empty() || !runningMerges.empty()) { + doWait(); } - void IndexWriter::blockAddIndexes(bool includePendingClose) - { - acquireRead(); + // sanity check + BOOST_ASSERT(mergingSegments.empty()); +} - bool success = false; - LuceneException finally; - try - { - // Make sure we are still open since we could have waited quite a while for last addIndexes to finish - ensureOpen(includePendingClose); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } +void IndexWriter::checkpoint() { + SyncLock syncLock(this); + ++changeCount; + deleter->checkpoint(segmentInfos, false); +} - if (!success) - releaseRead(); - finally.throwException(); +void IndexWriter::finishAddIndexes() { + releaseWrite(); +} + +void IndexWriter::blockAddIndexes(bool includePendingClose) { + acquireRead(); + + bool success = false; + LuceneException finally; + try { + // Make sure we are still open since we could have waited quite a while for last addIndexes to finish + ensureOpen(includePendingClose); + success = true; + } catch (LuceneException& e) { + finally = e; } - void IndexWriter::resumeAddIndexes() - { + if (!success) { releaseRead(); } + finally.throwException(); +} - void IndexWriter::resetMergeExceptions() - { - SyncLock syncLock(this); - mergeExceptions.clear(); - ++mergeGen; - } +void IndexWriter::resumeAddIndexes() { + releaseRead(); +} - void IndexWriter::noDupDirs(Collection dirs) - { - Collection dups(Collection::newInstance()); +void IndexWriter::resetMergeExceptions() { + SyncLock syncLock(this); + mergeExceptions.clear(); + ++mergeGen; +} - for (Collection::iterator dir = dirs.begin(); dir != dirs.end(); ++dir) - { - for (Collection::iterator dup = dups.begin(); dup != dups.end(); ++dup) - { - if (*dup == *dir) - boost::throw_exception(IllegalArgumentException(L"Directory " + (*dir)->getLockID() + L" appears more than once")); +void IndexWriter::noDupDirs(Collection dirs) { + Collection dups(Collection::newInstance()); + + for (Collection::iterator dir = dirs.begin(); dir != dirs.end(); ++dir) { + for (Collection::iterator dup = dups.begin(); dup != dups.end(); ++dup) { + if (*dup == *dir) { + boost::throw_exception(IllegalArgumentException(L"Directory " + (*dir)->getLockID() + L" appears more than once")); } - if (*dir == directory) - boost::throw_exception(IllegalArgumentException(L"Cannot add directory to itself")); - dups.add(*dir); } + if (*dir == directory) { + boost::throw_exception(IllegalArgumentException(L"Cannot add directory to itself")); + } + dups.add(*dir); } +} - void IndexWriter::addIndexesNoOptimize(Collection dirs) - { - ensureOpen(); +void IndexWriter::addIndexesNoOptimize(Collection dirs) { + ensureOpen(); - noDupDirs(dirs); + noDupDirs(dirs); - // Do not allow add docs or deletes while we are running - docWriter->pauseAllThreads(); + // Do not allow add docs or deletes while we are running + docWriter->pauseAllThreads(); - LuceneException finally; - try - { - if (infoStream) - message(L"flush at addIndexesNoOptimize"); - flush(true, false, true); + LuceneException finally; + try { + if (infoStream) { + message(L"flush at addIndexesNoOptimize"); + } + flush(true, false, true); - bool success = false; + bool success = false; - startTransaction(false); + startTransaction(false); - try - { - int32_t docCount = 0; + try { + int32_t docCount = 0; - { - SyncLock syncLock(this); - ensureOpen(); + { + SyncLock syncLock(this); + ensureOpen(); - for (Collection::iterator dir = dirs.begin(); dir != dirs.end(); ++dir) - { - if (directory == *dir) - { - // cannot add this index: segments may be deleted in merge before added - boost::throw_exception(IllegalArgumentException(L"Cannot add this index to itself")); - } + for (Collection::iterator dir = dirs.begin(); dir != dirs.end(); ++dir) { + if (directory == *dir) { + // cannot add this index: segments may be deleted in merge before added + boost::throw_exception(IllegalArgumentException(L"Cannot add this index to itself")); + } - SegmentInfosPtr sis(newLucene()); // read infos from dir - sis->read(*dir); + SegmentInfosPtr sis(newLucene()); // read infos from dir + sis->read(*dir); - for (int32_t j = 0; j < sis->size(); ++j) - { - SegmentInfoPtr info(sis->info(j)); - BOOST_ASSERT(!segmentInfos->contains(info)); - docCount += info->docCount; - segmentInfos->add(info); // add each info - } + for (int32_t j = 0; j < sis->size(); ++j) { + SegmentInfoPtr info(sis->info(j)); + BOOST_ASSERT(!segmentInfos->contains(info)); + docCount += info->docCount; + segmentInfos->add(info); // add each info } } + } - // Notify DocumentsWriter that the flushed count just increased - docWriter->updateFlushedDocCount(docCount); + // Notify DocumentsWriter that the flushed count just increased + docWriter->updateFlushedDocCount(docCount); - maybeMerge(); + maybeMerge(); - ensureOpen(); + ensureOpen(); - // If after merging there remain segments in the index that are in a different directory, just copy these - // over into our index. This is necessary (before finishing the transaction) to avoid leaving the index - // in an unusable (inconsistent) state. - resolveExternalSegments(); + // If after merging there remain segments in the index that are in a different directory, just copy these + // over into our index. This is necessary (before finishing the transaction) to avoid leaving the index + // in an unusable (inconsistent) state. + resolveExternalSegments(); - ensureOpen(); + ensureOpen(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } + success = true; + } catch (LuceneException& e) { + finally = e; + } - if (success) - commitTransaction(); - else - rollbackTransaction(); + if (success) { + commitTransaction(); + } else { + rollbackTransaction(); } - catch (std::bad_alloc& oom) + } catch (std::bad_alloc& oom) { + finally = handleOOM(oom, L"addIndexesNoOptimize"); + } catch (LuceneException& e) { + finally = e; + } + if (docWriter) { + docWriter->resumeAllThreads(); + } + finally.throwException(); +} + +bool IndexWriter::hasExternalSegments() { + return segmentInfos->hasExternalSegments(directory); +} + +void IndexWriter::resolveExternalSegments() { + bool any = false; + bool done = false; + + while (!done) { + SegmentInfoPtr info; + OneMergePtr merge; + { - finally = handleOOM(oom, L"addIndexesNoOptimize"); + SyncLock syncLock(this); + if (stopMerges) { + boost::throw_exception(MergeAbortedException(L"rollback() was called or addIndexes* hit an unhandled exception")); + } + + int32_t numSegments = segmentInfos->size(); + + done = true; + for (int32_t i = 0; i < numSegments; ++i) { + info = segmentInfos->info(i); + if (info->dir != directory) { + done = false; + OneMergePtr newMerge(newLucene(segmentInfos->range(i, i + 1), boost::dynamic_pointer_cast(mergePolicy) && getUseCompoundFile())); + + // Returns true if no running merge conflicts with this one (and, records this merge as + // pending), ie, this segment is not currently being merged + if (registerMerge(newMerge)) { + merge = newMerge; + + // If this segment is not currently being merged, then advance it to running & run + // the merge ourself (below) + pendingMerges.remove(merge); + runningMerges.add(merge); + break; + } + } + } + + if (!done && !merge) { + // We are not yet done (external segments still exist in segmentInfos), yet, all such segments + // are currently "covered" by a pending or running merge. We now try to grab any pending merge + // that involves external segments + merge = getNextExternalMerge(); + } + + if (!done && !merge) { + // We are not yet done, and, all external segments fall under merges that the merge scheduler is + // currently running. So, we now wait and check back to see if the merge has completed. + doWait(); + } } - catch (LuceneException& e) - { - finally = e; + + if (merge) { + any = true; + IndexWriter::merge(merge); } - if (docWriter) - docWriter->resumeAllThreads(); - finally.throwException(); } - bool IndexWriter::hasExternalSegments() - { - return segmentInfos->hasExternalSegments(directory); + if (any) { + // Sometimes, on copying an external segment over, more merges may become necessary + mergeScheduler->merge(shared_from_this()); } +} - void IndexWriter::resolveExternalSegments() - { - bool any = false; - bool done = false; +void IndexWriter::addIndexes(Collection readers) { + ensureOpen(); - while (!done) - { - SegmentInfoPtr info; - OneMergePtr merge; + // Do not allow add docs or deletes while we are running + docWriter->pauseAllThreads(); - { - SyncLock syncLock(this); - if (stopMerges) - boost::throw_exception(MergeAbortedException(L"rollback() was called or addIndexes* hit an unhandled exception")); + // We must pre-acquire a read lock here (and upgrade to write lock in startTransaction below) so that no + // other addIndexes is allowed to start up after we have flushed & optimized but before we then start our + // transaction. This is because the merging below requires that only one segment is present in the index + acquireRead(); - int32_t numSegments = segmentInfos->size(); + LuceneException finally; + try { + SegmentInfoPtr info; + String mergedName; + SegmentMergerPtr merger; - done = true; - for (int32_t i = 0; i < numSegments; ++i) - { - info = segmentInfos->info(i); - if (info->dir != directory) - { - done = false; - OneMergePtr newMerge(newLucene(segmentInfos->range(i, i + 1), boost::dynamic_pointer_cast(mergePolicy) && getUseCompoundFile())); - - // Returns true if no running merge conflicts with this one (and, records this merge as - // pending), ie, this segment is not currently being merged - if (registerMerge(newMerge)) - { - merge = newMerge; - - // If this segment is not currently being merged, then advance it to running & run - // the merge ourself (below) - pendingMerges.remove(merge); - runningMerges.add(merge); - break; - } - } - } + bool success = false; - if (!done && !merge) - { - // We are not yet done (external segments still exist in segmentInfos), yet, all such segments - // are currently "covered" by a pending or running merge. We now try to grab any pending merge - // that involves external segments - merge = getNextExternalMerge(); - } + try { + flush(true, false, true); + optimize(); // start with zero or 1 seg + success = true; + } catch (LuceneException& e) { + finally = e; + } + + // Take care to release the read lock if we hit an exception before starting the transaction + if (!success) { + releaseRead(); + } + finally.throwException(); + + // true means we already have a read lock; if this call hits an exception it will release the write lock + startTransaction(true); - if (!done && !merge) - { - // We are not yet done, and, all external segments fall under merges that the merge scheduler is - // currently running. So, we now wait and check back to see if the merge has completed. - doWait(); - } - } + try { + mergedName = newSegmentName(); + merger = newLucene(shared_from_this(), mergedName, OneMergePtr()); + + SegmentReaderPtr sReader; - if (merge) { - any = true; - IndexWriter::merge(merge); + SyncLock syncLock(this); + if (segmentInfos->size() == 1) { // add existing index, if any + sReader = readerPool->get(segmentInfos->info(0), true, BufferedIndexInput::BUFFER_SIZE, -1); + } } - } - if (any) - { - // Sometimes, on copying an external segment over, more merges may become necessary - mergeScheduler->merge(shared_from_this()); - } - } + success = false; - void IndexWriter::addIndexes(Collection readers) - { - ensureOpen(); + try { + if (sReader) { + merger->add(sReader); + } - // Do not allow add docs or deletes while we are running - docWriter->pauseAllThreads(); + for (Collection::iterator i = readers.begin(); i != readers.end(); ++i) { + merger->add(*i); + } - // We must pre-acquire a read lock here (and upgrade to write lock in startTransaction below) so that no - // other addIndexes is allowed to start up after we have flushed & optimized but before we then start our - // transaction. This is because the merging below requires that only one segment is present in the index - acquireRead(); + int32_t docCount = merger->merge(); // merge 'em - LuceneException finally; - try - { - SegmentInfoPtr info; - String mergedName; - SegmentMergerPtr merger; + { + SyncLock syncLock(this); + segmentInfos->clear(); // pop old infos & add new + info = newLucene(mergedName, docCount, directory, false, true, -1, L"", false, merger->hasProx()); + setDiagnostics(info, L"addIndexes(Collection)"); + segmentInfos->add(info); + } - bool success = false; + // Notify DocumentsWriter that the flushed count just increased + docWriter->updateFlushedDocCount(docCount); - try - { - flush(true, false, true); - optimize(); // start with zero or 1 seg success = true; - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } - // Take care to release the read lock if we hit an exception before starting the transaction - if (!success) - releaseRead(); - finally.throwException(); + if (sReader) { + readerPool->release(sReader); + } + } catch (LuceneException& e) { + finally = e; + } - // true means we already have a read lock; if this call hits an exception it will release the write lock - startTransaction(true); + if (!success) { + if (infoStream) { + message(L"hit exception in addIndexes during merge"); + } + rollbackTransaction(); + } else { + commitTransaction(); + } - try - { - mergedName = newSegmentName(); - merger = newLucene(shared_from_this(), mergedName, OneMergePtr()); + finally.throwException(); - SegmentReaderPtr sReader; + if (boost::dynamic_pointer_cast(mergePolicy) && getUseCompoundFile()) { + HashSet files; - { - SyncLock syncLock(this); - if (segmentInfos->size() == 1) // add existing index, if any - sReader = readerPool->get(segmentInfos->info(0), true, BufferedIndexInput::BUFFER_SIZE, -1); + { + SyncLock syncLock(this); + // Must incRef our files so that if another thread is running merge/optimize, it doesn't delete our + // segment's files before we have a change to finish making the compound file. + if (segmentInfos->contains(info)) { + files = info->files(); + deleter->incRef(files); } + } + if (files) { success = false; - try - { - if (sReader) - merger->add(sReader); - - for (Collection::iterator i = readers.begin(); i != readers.end(); ++i) - merger->add(*i); + startTransaction(false); - int32_t docCount = merger->merge(); // merge 'em + try { + merger->createCompoundFile(mergedName + L".cfs"); { SyncLock syncLock(this); - segmentInfos->clear(); // pop old infos & add new - info = newLucene(mergedName, docCount, directory, false, true, -1, L"", false, merger->hasProx()); - setDiagnostics(info, L"addIndexes(Collection)"); - segmentInfos->add(info); + info->setUseCompoundFile(true); } - // Notify DocumentsWriter that the flushed count just increased - docWriter->updateFlushedDocCount(docCount); - success = true; - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } - if (sReader) - readerPool->release(sReader); - } - catch (LuceneException& e) - { - finally = e; - } - - if (!success) - { - if (infoStream) - message(L"hit exception in addIndexes during merge"); - rollbackTransaction(); - } - else - commitTransaction(); - - finally.throwException(); - - if (boost::dynamic_pointer_cast(mergePolicy) && getUseCompoundFile()) - { - HashSet files; - { SyncLock syncLock(this); - // Must incRef our files so that if another thread is running merge/optimize, it doesn't delete our - // segment's files before we have a change to finish making the compound file. - if (segmentInfos->contains(info)) - { - files = info->files(); - deleter->incRef(files); - } + deleter->decRef(files); } - if (files) - { - success = false; - - startTransaction(false); - - try - { - merger->createCompoundFile(mergedName + L".cfs"); - - { - SyncLock syncLock(this); - info->setUseCompoundFile(true); - } - - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - - { - SyncLock syncLock(this); - deleter->decRef(files); - } - - if (!success) - { - if (infoStream) - message(L"hit exception building compound file in addIndexes during merge"); - rollbackTransaction(); + if (!success) { + if (infoStream) { + message(L"hit exception building compound file in addIndexes during merge"); } - else - commitTransaction(); + rollbackTransaction(); + } else { + commitTransaction(); } } } - catch (std::bad_alloc& oom) - { - finally = handleOOM(oom, L"addIndexes(Collection)"); - } - catch (LuceneException& e) - { - finally = e; - } - if (docWriter) - docWriter->resumeAllThreads(); - finally.throwException(); - } - - void IndexWriter::doAfterFlush() - { - // override - } - - void IndexWriter::doBeforeFlush() - { - // override + } catch (std::bad_alloc& oom) { + finally = handleOOM(oom, L"addIndexes(Collection)"); + } catch (LuceneException& e) { + finally = e; } - - void IndexWriter::prepareCommit() - { - ensureOpen(); - prepareCommit(MapStringString()); + if (docWriter) { + docWriter->resumeAllThreads(); } + finally.throwException(); +} - void IndexWriter::prepareCommit(MapStringString commitUserData) - { - if (hitOOM) - boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot commit")); - - if (pendingCommit) - boost::throw_exception(IllegalStateException(L"prepareCommit was already called with no corresponding call to commit")); +void IndexWriter::doAfterFlush() { + // override +} - if (infoStream) - message(L"prepareCommit: flush"); +void IndexWriter::doBeforeFlush() { + // override +} - flush(true, true, true); +void IndexWriter::prepareCommit() { + ensureOpen(); + prepareCommit(MapStringString()); +} - startCommit(0, commitUserData); +void IndexWriter::prepareCommit(MapStringString commitUserData) { + if (hitOOM) { + boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot commit")); } - void IndexWriter::commit(int64_t sizeInBytes) - { - SyncLock messageLock(commitLock); - startCommit(sizeInBytes, MapStringString()); - finishCommit(); + if (pendingCommit) { + boost::throw_exception(IllegalStateException(L"prepareCommit was already called with no corresponding call to commit")); } - void IndexWriter::commit() - { - commit(MapStringString()); + if (infoStream) { + message(L"prepareCommit: flush"); } - void IndexWriter::commit(MapStringString commitUserData) - { - ensureOpen(); + flush(true, true, true); - if (infoStream) - message(L"commit: start"); + startCommit(0, commitUserData); +} - { - SyncLock messageLock(commitLock); +void IndexWriter::commit(int64_t sizeInBytes) { + SyncLock messageLock(commitLock); + startCommit(sizeInBytes, MapStringString()); + finishCommit(); +} - if (infoStream) - message(L"commit: enter lock"); +void IndexWriter::commit() { + commit(MapStringString()); +} - if (!pendingCommit) - { - if (infoStream) - message(L"commit: now prepare"); - prepareCommit(commitUserData); - } - else if (infoStream) - message(L"commit: already prepared"); +void IndexWriter::commit(MapStringString commitUserData) { + ensureOpen(); - finishCommit(); - } + if (infoStream) { + message(L"commit: start"); } - void IndexWriter::finishCommit() { - SyncLock syncLock(this); - if (pendingCommit) - { - LuceneException finally; - try - { - if (infoStream) - message(L"commit: pendingCommit != null"); - pendingCommit->finishCommit(directory); - if (infoStream) - message(L"commit: wrote segments file \"" + pendingCommit->getCurrentSegmentFileName() + L"\""); - lastCommitChangeCount = pendingCommitChangeCount; - segmentInfos->updateGeneration(pendingCommit); - segmentInfos->setUserData(pendingCommit->getUserData()); - setRollbackSegmentInfos(pendingCommit); - deleter->checkpoint(pendingCommit, true); - } - catch (LuceneException& e) - { - finally = e; - } + SyncLock messageLock(commitLock); - deleter->decRef(pendingCommit); - pendingCommit.reset(); - notifyAll(); - finally.throwException(); + if (infoStream) { + message(L"commit: enter lock"); } - else if (infoStream) - message(L"commit: pendingCommit == null; skip"); - if (infoStream) - message(L"commit: done"); - } + if (!pendingCommit) { + if (infoStream) { + message(L"commit: now prepare"); + } + prepareCommit(commitUserData); + } else if (infoStream) { + message(L"commit: already prepared"); + } - void IndexWriter::flush(bool triggerMerge, bool flushDocStores, bool flushDeletes) - { - // We can be called during close, when closing = true, so we must pass false to ensureOpen - ensureOpen(false); - if (doFlush(flushDocStores, flushDeletes) && triggerMerge) - maybeMerge(); + finishCommit(); } +} - bool IndexWriter::doFlush(bool flushDocStores, bool flushDeletes) - { - TestScope testScope(L"IndexWriter", L"doFlush"); - SyncLock syncLock(this); - bool success = false; +void IndexWriter::finishCommit() { + SyncLock syncLock(this); + if (pendingCommit) { LuceneException finally; - try - { - try - { - success = doFlushInternal(flushDocStores, flushDeletes); - } - catch (LuceneException& e) - { - finally = e; - } - if (docWriter->doBalanceRAM()) - docWriter->balanceRAM(); - finally.throwException(); + try { + if (infoStream) { + message(L"commit: pendingCommit != null"); + } + pendingCommit->finishCommit(directory); + if (infoStream) { + message(L"commit: wrote segments file \"" + pendingCommit->getCurrentSegmentFileName() + L"\""); + } + lastCommitChangeCount = pendingCommitChangeCount; + segmentInfos->updateGeneration(pendingCommit); + segmentInfos->setUserData(pendingCommit->getUserData()); + setRollbackSegmentInfos(pendingCommit); + deleter->checkpoint(pendingCommit, true); + } catch (LuceneException& e) { + finally = e; } - catch (LuceneException& e) - { + + deleter->decRef(pendingCommit); + pendingCommit.reset(); + notifyAll(); + finally.throwException(); + } else if (infoStream) { + message(L"commit: pendingCommit == null; skip"); + } + + if (infoStream) { + message(L"commit: done"); + } +} + +void IndexWriter::flush(bool triggerMerge, bool flushDocStores, bool flushDeletes) { + // We can be called during close, when closing = true, so we must pass false to ensureOpen + ensureOpen(false); + if (doFlush(flushDocStores, flushDeletes) && triggerMerge) { + maybeMerge(); + } +} + +bool IndexWriter::doFlush(bool flushDocStores, bool flushDeletes) { + TestScope testScope(L"IndexWriter", L"doFlush"); + SyncLock syncLock(this); + bool success = false; + LuceneException finally; + try { + try { + success = doFlushInternal(flushDocStores, flushDeletes); + } catch (LuceneException& e) { finally = e; } - docWriter->clearFlushPending(); + if (docWriter->doBalanceRAM()) { + docWriter->balanceRAM(); + } finally.throwException(); - return success; + } catch (LuceneException& e) { + finally = e; } + docWriter->clearFlushPending(); + finally.throwException(); + return success; +} - bool IndexWriter::doFlushInternal(bool flushDocStores, bool flushDeletes) - { - SyncLock syncLock(this); - if (hitOOM) - boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot flush")); +bool IndexWriter::doFlushInternal(bool flushDocStores, bool flushDeletes) { + SyncLock syncLock(this); + if (hitOOM) { + boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot flush")); + } - ensureOpen(false); + ensureOpen(false); - BOOST_ASSERT(testPoint(L"startDoFlush")); + BOOST_ASSERT(testPoint(L"startDoFlush")); - doBeforeFlush(); + doBeforeFlush(); - ++flushCount; + ++flushCount; - // If we are flushing because too many deletes accumulated, then we should apply the deletes to free RAM - if (docWriter->doApplyDeletes()) - flushDeletes = true; + // If we are flushing because too many deletes accumulated, then we should apply the deletes to free RAM + if (docWriter->doApplyDeletes()) { + flushDeletes = true; + } - // Make sure no threads are actively adding a document. Returns true if docWriter is currently aborting, in - // which case we skip flushing this segment - if (infoStream) - message(L"flush: now pause all indexing threads"); - if (docWriter->pauseAllThreads()) - { - docWriter->resumeAllThreads(); - return false; - } + // Make sure no threads are actively adding a document. Returns true if docWriter is currently aborting, in + // which case we skip flushing this segment + if (infoStream) { + message(L"flush: now pause all indexing threads"); + } + if (docWriter->pauseAllThreads()) { + docWriter->resumeAllThreads(); + return false; + } - bool flushDocs = false; + bool flushDocs = false; - LuceneException finally; - try - { - SegmentInfoPtr newSegment; + LuceneException finally; + try { + SegmentInfoPtr newSegment; - int32_t numDocs = docWriter->getNumDocsInRAM(); + int32_t numDocs = docWriter->getNumDocsInRAM(); - // Always flush docs if there are any - flushDocs = (numDocs > 0); + // Always flush docs if there are any + flushDocs = (numDocs > 0); - String docStoreSegment(docWriter->getDocStoreSegment()); + String docStoreSegment(docWriter->getDocStoreSegment()); - BOOST_ASSERT(!docStoreSegment.empty() || numDocs == 0); + BOOST_ASSERT(!docStoreSegment.empty() || numDocs == 0); - if (docStoreSegment.empty()) - flushDocStores = false; + if (docStoreSegment.empty()) { + flushDocStores = false; + } - int32_t docStoreOffset = docWriter->getDocStoreOffset(); + int32_t docStoreOffset = docWriter->getDocStoreOffset(); - bool docStoreIsCompoundFile = false; + bool docStoreIsCompoundFile = false; - if (infoStream) - { - message(L" flush: segment=" + docWriter->getSegment() + - L" docStoreSegment=" + StringUtils::toString(docWriter->getDocStoreSegment()) + - L" docStoreOffset=" + StringUtils::toString(docStoreOffset) + - L" flushDocs=" + StringUtils::toString(flushDocs) + - L" flushDeletes=" + StringUtils::toString(flushDeletes) + - L" flushDocStores=" + StringUtils::toString(flushDocStores) + - L" numDocs=" + StringUtils::toString(numDocs) + - L" numBufDelTerms=" + StringUtils::toString(docWriter->getNumBufferedDeleteTerms())); - message(L" index before flush " + segString()); - } - - // Check if the doc stores must be separately flushed because other segments, besides the one we are - // about to flush, reference it - if (flushDocStores && (!flushDocs || docWriter->getSegment() != docWriter->getDocStoreSegment())) - { - // We must separately flush the doc store - if (infoStream) - message(L" flush shared docStore segment " + docStoreSegment); + if (infoStream) { + message(L" flush: segment=" + docWriter->getSegment() + + L" docStoreSegment=" + StringUtils::toString(docWriter->getDocStoreSegment()) + + L" docStoreOffset=" + StringUtils::toString(docStoreOffset) + + L" flushDocs=" + StringUtils::toString(flushDocs) + + L" flushDeletes=" + StringUtils::toString(flushDeletes) + + L" flushDocStores=" + StringUtils::toString(flushDocStores) + + L" numDocs=" + StringUtils::toString(numDocs) + + L" numBufDelTerms=" + StringUtils::toString(docWriter->getNumBufferedDeleteTerms())); + message(L" index before flush " + segString()); + } - docStoreIsCompoundFile = IndexWriter::flushDocStores(); - flushDocStores = false; + // Check if the doc stores must be separately flushed because other segments, besides the one we are + // about to flush, reference it + if (flushDocStores && (!flushDocs || docWriter->getSegment() != docWriter->getDocStoreSegment())) { + // We must separately flush the doc store + if (infoStream) { + message(L" flush shared docStore segment " + docStoreSegment); } - String segment(docWriter->getSegment()); + docStoreIsCompoundFile = IndexWriter::flushDocStores(); + flushDocStores = false; + } - // If we are flushing docs, segment must not be null - BOOST_ASSERT(!segment.empty() || !flushDocs); + String segment(docWriter->getSegment()); - if (flushDocs) - { - bool success = false; - int32_t flushedDocCount; + // If we are flushing docs, segment must not be null + BOOST_ASSERT(!segment.empty() || !flushDocs); - try - { - flushedDocCount = docWriter->flush(flushDocStores); - if (infoStream) - message(L"flushedFiles=" + StringUtils::toString(docWriter->getFlushedFiles())); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } + if (flushDocs) { + bool success = false; + int32_t flushedDocCount; - if (!success) - { - if (infoStream) - message(L"hit exception flushing segment " + segment); - deleter->refresh(segment); + try { + flushedDocCount = docWriter->flush(flushDocStores); + if (infoStream) { + message(L"flushedFiles=" + StringUtils::toString(docWriter->getFlushedFiles())); } + success = true; + } catch (LuceneException& e) { + finally = e; + } - finally.throwException(); - - if (docStoreOffset == 0 && flushDocStores) - { - // This means we are flushing private doc stores with this segment, so it will not be shared - // with other segments - BOOST_ASSERT(!docStoreSegment.empty()); - BOOST_ASSERT(docStoreSegment == segment); - docStoreOffset = -1; - docStoreIsCompoundFile = false; - docStoreSegment.clear(); + if (!success) { + if (infoStream) { + message(L"hit exception flushing segment " + segment); } - - // Create new SegmentInfo, but do not add to our segmentInfos until deletes are flushed successfully. - newSegment = newLucene(segment, flushedDocCount, directory, false, true, docStoreOffset, docStoreSegment, docStoreIsCompoundFile, docWriter->hasProx()); - setDiagnostics(newSegment, L"flush"); + deleter->refresh(segment); } - docWriter->pushDeletes(); + finally.throwException(); - if (flushDocs) - { - segmentInfos->add(newSegment); - checkpoint(); + if (docStoreOffset == 0 && flushDocStores) { + // This means we are flushing private doc stores with this segment, so it will not be shared + // with other segments + BOOST_ASSERT(!docStoreSegment.empty()); + BOOST_ASSERT(docStoreSegment == segment); + docStoreOffset = -1; + docStoreIsCompoundFile = false; + docStoreSegment.clear(); } - if (flushDocs && mergePolicy->useCompoundFile(segmentInfos, newSegment)) - { - // Now build compound file - bool success = false; - try - { - docWriter->createCompoundFile(segment); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } + // Create new SegmentInfo, but do not add to our segmentInfos until deletes are flushed successfully. + newSegment = newLucene(segment, flushedDocCount, directory, false, true, docStoreOffset, docStoreSegment, docStoreIsCompoundFile, docWriter->hasProx()); + setDiagnostics(newSegment, L"flush"); + } - if (!success) - { - if (infoStream) - message(L"hit exception creating compound file for newly flushed segment " + segment); - deleter->deleteFile(segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); - } + docWriter->pushDeletes(); - finally.throwException(); + if (flushDocs) { + segmentInfos->add(newSegment); + checkpoint(); + } - newSegment->setUseCompoundFile(true); - checkpoint(); + if (flushDocs && mergePolicy->useCompoundFile(segmentInfos, newSegment)) { + // Now build compound file + bool success = false; + try { + docWriter->createCompoundFile(segment); + success = true; + } catch (LuceneException& e) { + finally = e; } - if (flushDeletes) - applyDeletes(); + if (!success) { + if (infoStream) { + message(L"hit exception creating compound file for newly flushed segment " + segment); + } + deleter->deleteFile(segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); + } - if (flushDocs) - checkpoint(); + finally.throwException(); - doAfterFlush(); + newSegment->setUseCompoundFile(true); + checkpoint(); } - catch (std::bad_alloc& oom) - { - finally = handleOOM(oom, L"doFlush"); - flushDocs = false; + + if (flushDeletes) { + applyDeletes(); } - catch (LuceneException& e) - { - finally = e; + + if (flushDocs) { + checkpoint(); } - docWriter->resumeAllThreads(); - finally.throwException(); - return flushDocs; + doAfterFlush(); + } catch (std::bad_alloc& oom) { + finally = handleOOM(oom, L"doFlush"); + flushDocs = false; + } catch (LuceneException& e) { + finally = e; } + docWriter->resumeAllThreads(); + finally.throwException(); - int64_t IndexWriter::ramSizeInBytes() - { - ensureOpen(); - return docWriter->getRAMUsed(); - } + return flushDocs; +} - int32_t IndexWriter::numRamDocs() - { - SyncLock syncLock(this); - ensureOpen(); - return docWriter->getNumDocsInRAM(); - } +int64_t IndexWriter::ramSizeInBytes() { + ensureOpen(); + return docWriter->getRAMUsed(); +} - int32_t IndexWriter::ensureContiguousMerge(const OneMergePtr& merge) - { - int32_t first = segmentInfos->find(merge->segments->info(0)); - if (first == -1) - boost::throw_exception(MergeException(L"Could not find segment " + merge->segments->info(0)->name + L" in current index " + segString())); +int32_t IndexWriter::numRamDocs() { + SyncLock syncLock(this); + ensureOpen(); + return docWriter->getNumDocsInRAM(); +} - int32_t numSegments = segmentInfos->size(); - int32_t numSegmentsToMerge = merge->segments->size(); +int32_t IndexWriter::ensureContiguousMerge(const OneMergePtr& merge) { + int32_t first = segmentInfos->find(merge->segments->info(0)); + if (first == -1) { + boost::throw_exception(MergeException(L"Could not find segment " + merge->segments->info(0)->name + L" in current index " + segString())); + } - for (int32_t i = 0; i < numSegmentsToMerge; ++i) - { - SegmentInfoPtr info(merge->segments->info(i)); + int32_t numSegments = segmentInfos->size(); + int32_t numSegmentsToMerge = merge->segments->size(); - if (first + i >= numSegments || !segmentInfos->info(first + i)->equals(info)) - { - if (!segmentInfos->contains(info)) - boost::throw_exception(MergeException(L"MergePolicy selected a segment (" + info->name + L") that is not in the current index " + segString())); - else - boost::throw_exception(MergeException(L"MergePolicy selected non-contiguous segments to merge (" + merge->segString(directory) + L" vs " + segString() + L"), which IndexWriter (currently) cannot handle")); + for (int32_t i = 0; i < numSegmentsToMerge; ++i) { + SegmentInfoPtr info(merge->segments->info(i)); + + if (first + i >= numSegments || !segmentInfos->info(first + i)->equals(info)) { + if (!segmentInfos->contains(info)) { + boost::throw_exception(MergeException(L"MergePolicy selected a segment (" + info->name + L") that is not in the current index " + segString())); + } else { + boost::throw_exception(MergeException(L"MergePolicy selected non-contiguous segments to merge (" + merge->segString(directory) + L" vs " + segString() + L"), which IndexWriter (currently) cannot handle")); } } - - return first; } - void IndexWriter::commitMergedDeletes(const OneMergePtr& merge, const SegmentReaderPtr& mergeReader) - { - SyncLock syncLock(this); - BOOST_ASSERT(testPoint(L"startCommitMergeDeletes")); - - SegmentInfosPtr sourceSegments(merge->segments); - - if (infoStream) - message(L"commitMergeDeletes " + merge->segString(directory)); - - // Carefully merge deletes that occurred after we started merging - int32_t docUpto = 0; - int32_t delCount = 0; - - for (int32_t i = 0; i < sourceSegments->size(); ++i) - { - SegmentInfoPtr info(sourceSegments->info(i)); - int32_t docCount = info->docCount; - SegmentReaderPtr previousReader(merge->readersClone[i]); - SegmentReaderPtr currentReader(merge->readers[i]); - if (previousReader->hasDeletions()) - { - // There were deletes on this segment when the merge started. The merge has collapsed away those deletes, - // but if new deletes were flushed since the merge started, we must now carefully keep any newly flushed - // deletes but mapping them to the new docIDs. + return first; +} - if (currentReader->numDeletedDocs() > previousReader->numDeletedDocs()) - { - // This means this segment has had new deletes committed since we started the merge, so we must merge them - for (int32_t j = 0; j < docCount; ++j) - { - if (previousReader->isDeleted(j)) - BOOST_ASSERT(currentReader->isDeleted(j)); - else - { - if (currentReader->isDeleted(j)) - { - mergeReader->doDelete(docUpto); - ++delCount; - } - ++docUpto; +void IndexWriter::commitMergedDeletes(const OneMergePtr& merge, const SegmentReaderPtr& mergeReader) { + SyncLock syncLock(this); + BOOST_ASSERT(testPoint(L"startCommitMergeDeletes")); + + SegmentInfosPtr sourceSegments(merge->segments); + + if (infoStream) { + message(L"commitMergeDeletes " + merge->segString(directory)); + } + + // Carefully merge deletes that occurred after we started merging + int32_t docUpto = 0; + int32_t delCount = 0; + + for (int32_t i = 0; i < sourceSegments->size(); ++i) { + SegmentInfoPtr info(sourceSegments->info(i)); + int32_t docCount = info->docCount; + SegmentReaderPtr previousReader(merge->readersClone[i]); + SegmentReaderPtr currentReader(merge->readers[i]); + if (previousReader->hasDeletions()) { + // There were deletes on this segment when the merge started. The merge has collapsed away those deletes, + // but if new deletes were flushed since the merge started, we must now carefully keep any newly flushed + // deletes but mapping them to the new docIDs. + + if (currentReader->numDeletedDocs() > previousReader->numDeletedDocs()) { + // This means this segment has had new deletes committed since we started the merge, so we must merge them + for (int32_t j = 0; j < docCount; ++j) { + if (previousReader->isDeleted(j)) { + BOOST_ASSERT(currentReader->isDeleted(j)); + } else { + if (currentReader->isDeleted(j)) { + mergeReader->doDelete(docUpto); + ++delCount; } + ++docUpto; } } - else - docUpto += docCount - previousReader->numDeletedDocs(); - } - else if (currentReader->hasDeletions()) - { - // This segment had no deletes before but now it does - for (int32_t j = 0; j < docCount; ++j) - { - if (currentReader->isDeleted(j)) - { - mergeReader->doDelete(docUpto); - ++delCount; - } - ++docUpto; - } - } - else - { - // No deletes before or after - docUpto += info->docCount; + } else { + docUpto += docCount - previousReader->numDeletedDocs(); + } + } else if (currentReader->hasDeletions()) { + // This segment had no deletes before but now it does + for (int32_t j = 0; j < docCount; ++j) { + if (currentReader->isDeleted(j)) { + mergeReader->doDelete(docUpto); + ++delCount; + } + ++docUpto; } + } else { + // No deletes before or after + docUpto += info->docCount; } + } - BOOST_ASSERT(mergeReader->numDeletedDocs() == delCount); + BOOST_ASSERT(mergeReader->numDeletedDocs() == delCount); - mergeReader->_hasChanges = (delCount > 0); - } + mergeReader->_hasChanges = (delCount > 0); +} - bool IndexWriter::commitMerge(const OneMergePtr& merge, const SegmentMergerPtr& merger, int32_t mergedDocCount, const SegmentReaderPtr& mergedReader) - { - SyncLock syncLock(this); - BOOST_ASSERT(testPoint(L"startCommitMerge")); +bool IndexWriter::commitMerge(const OneMergePtr& merge, const SegmentMergerPtr& merger, int32_t mergedDocCount, const SegmentReaderPtr& mergedReader) { + SyncLock syncLock(this); + BOOST_ASSERT(testPoint(L"startCommitMerge")); - if (hitOOM) - boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete merge")); + if (hitOOM) { + boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot complete merge")); + } - if (infoStream) - message(L"commitMerge: " + merge->segString(directory) + L" index=" + segString()); + if (infoStream) { + message(L"commitMerge: " + merge->segString(directory) + L" index=" + segString()); + } - BOOST_ASSERT(merge->registerDone); + BOOST_ASSERT(merge->registerDone); - // If merge was explicitly aborted, or, if rollback() or rollbackTransaction() had been called since our merge - // started (which results in an unqualified deleter.refresh() call that will remove any index file that current - // segments does not reference), we abort this merge - if (merge->isAborted()) - { - if (infoStream) - message(L"commitMerge: skipping merge " + merge->segString(directory) + L": it was aborted"); - return false; + // If merge was explicitly aborted, or, if rollback() or rollbackTransaction() had been called since our merge + // started (which results in an unqualified deleter.refresh() call that will remove any index file that current + // segments does not reference), we abort this merge + if (merge->isAborted()) { + if (infoStream) { + message(L"commitMerge: skipping merge " + merge->segString(directory) + L": it was aborted"); } + return false; + } - int32_t start = ensureContiguousMerge(merge); + int32_t start = ensureContiguousMerge(merge); - commitMergedDeletes(merge, mergedReader); - docWriter->remapDeletes(segmentInfos, merger->getDocMaps(), merger->getDelCounts(), merge, mergedDocCount); + commitMergedDeletes(merge, mergedReader); + docWriter->remapDeletes(segmentInfos, merger->getDocMaps(), merger->getDelCounts(), merge, mergedDocCount); - // If the doc store we are using has been closed and is in now compound format (but wasn't when we started), - // then we will switch to the compound format as well - setMergeDocStoreIsCompoundFile(merge); + // If the doc store we are using has been closed and is in now compound format (but wasn't when we started), + // then we will switch to the compound format as well + setMergeDocStoreIsCompoundFile(merge); - merge->info->setHasProx(merger->hasProx()); + merge->info->setHasProx(merger->hasProx()); - segmentInfos->remove(start, start + merge->segments->size()); - BOOST_ASSERT(!segmentInfos->contains(merge->info)); - segmentInfos->add(start, merge->info); + segmentInfos->remove(start, start + merge->segments->size()); + BOOST_ASSERT(!segmentInfos->contains(merge->info)); + segmentInfos->add(start, merge->info); - closeMergeReaders(merge, false); + closeMergeReaders(merge, false); - // Must note the change to segmentInfos so any commits in-flight don't lose it - checkpoint(); + // Must note the change to segmentInfos so any commits in-flight don't lose it + checkpoint(); - // If the merged segments had pending changes, clear them so that they don't bother writing - // them to disk, updating SegmentInfo, etc. - readerPool->clear(merge->segments); + // If the merged segments had pending changes, clear them so that they don't bother writing + // them to disk, updating SegmentInfo, etc. + readerPool->clear(merge->segments); - if (merge->optimize) - { - // cascade the optimize - segmentsToOptimize.add(merge->info); - } - return true; + if (merge->optimize) { + // cascade the optimize + segmentsToOptimize.add(merge->info); } + return true; +} - LuceneException IndexWriter::handleMergeException(const LuceneException& exc, const OneMergePtr& merge) - { - if (infoStream) - message(L"handleMergeException: merge=" + merge->segString(directory) + L" exc=" + exc.getError()); +LuceneException IndexWriter::handleMergeException(const LuceneException& exc, const OneMergePtr& merge) { + if (infoStream) { + message(L"handleMergeException: merge=" + merge->segString(directory) + L" exc=" + exc.getError()); + } - // Set the exception on the merge, so if optimize() is waiting on us it sees the root cause exception - merge->setException(exc); - addMergeException(merge); + // Set the exception on the merge, so if optimize() is waiting on us it sees the root cause exception + merge->setException(exc); + addMergeException(merge); - switch (exc.getType()) - { - case LuceneException::MergeAborted: - // We can ignore this exception (it happens when close(false) or rollback is called), unless the - // merge involves segments from external directories, in which case we must throw it so, for - // example, the rollbackTransaction code in addIndexes* is executed. - if (merge->isExternal) - return exc; - break; - case LuceneException::IO: - case LuceneException::Runtime: - return exc; - default: - return RuntimeException(); // Should not get here + switch (exc.getType()) { + case LuceneException::MergeAborted: + // We can ignore this exception (it happens when close(false) or rollback is called), unless the + // merge involves segments from external directories, in which case we must throw it so, for + // example, the rollbackTransaction code in addIndexes* is executed. + if (merge->isExternal) { + return exc; } - return LuceneException(); + break; + case LuceneException::IO: + case LuceneException::Runtime: + return exc; + default: + return RuntimeException(); // Should not get here } + return LuceneException(); +} - void IndexWriter::merge(const OneMergePtr& merge) - { - bool success = false; - - try - { - LuceneException finally; - try - { - try - { - mergeInit(merge); - if (infoStream) - message(L"now merge\n merge=" + merge->segString(directory) + L"\n index=" + segString()); +void IndexWriter::merge(const OneMergePtr& merge) { + bool success = false; - mergeMiddle(merge); - mergeSuccess(merge); - success = true; - } - catch (LuceneException& e) - { - finally = handleMergeException(e, merge); + try { + LuceneException finally; + try { + try { + mergeInit(merge); + if (infoStream) { + message(L"now merge\n merge=" + merge->segString(directory) + L"\n index=" + segString()); } - { - SyncLock syncLock(this); - mergeFinish(merge); + mergeMiddle(merge); + mergeSuccess(merge); + success = true; + } catch (LuceneException& e) { + finally = handleMergeException(e, merge); + } - if (!success) - { - if (infoStream) - message(L"hit exception during merge"); + { + SyncLock syncLock(this); + mergeFinish(merge); + + if (!success) { + if (infoStream) { + message(L"hit exception during merge"); + } - if (merge->info && !segmentInfos->contains(merge->info)) - deleter->refresh(merge->info->name); + if (merge->info && !segmentInfos->contains(merge->info)) { + deleter->refresh(merge->info->name); } + } - // This merge (and, generally, any change to the segments) may now enable - // new merges, so we call merge policy & update pending merges. - if (success && !merge->isAborted() && !closed && !closing) - updatePendingMerges(merge->maxNumSegmentsOptimize, merge->optimize); + // This merge (and, generally, any change to the segments) may now enable + // new merges, so we call merge policy & update pending merges. + if (success && !merge->isAborted() && !closed && !closing) { + updatePendingMerges(merge->maxNumSegmentsOptimize, merge->optimize); } } - catch (LuceneException& e) - { - finally = e; - } - finally.throwException(); - } - catch (std::bad_alloc& oom) - { - boost::throw_exception(handleOOM(oom, L"merge")); + } catch (LuceneException& e) { + finally = e; } + finally.throwException(); + } catch (std::bad_alloc& oom) { + boost::throw_exception(handleOOM(oom, L"merge")); } +} - void IndexWriter::mergeSuccess(const OneMergePtr& merge) - { - // override - } +void IndexWriter::mergeSuccess(const OneMergePtr& merge) { + // override +} - bool IndexWriter::registerMerge(const OneMergePtr& merge) - { - SyncLock syncLock(this); +bool IndexWriter::registerMerge(const OneMergePtr& merge) { + SyncLock syncLock(this); - if (merge->registerDone) - return true; + if (merge->registerDone) { + return true; + } - if (stopMerges) - { - merge->abort(); - boost::throw_exception(MergeAbortedException(L"merge is aborted: " + merge->segString(directory))); - } + if (stopMerges) { + merge->abort(); + boost::throw_exception(MergeAbortedException(L"merge is aborted: " + merge->segString(directory))); + } - int32_t count = merge->segments->size(); - bool isExternal = false; - for (int32_t i = 0; i < count; ++i) - { - SegmentInfoPtr info(merge->segments->info(i)); - if (mergingSegments.contains(info)) - return false; - if (!segmentInfos->contains(info)) - return false; - if (info->dir != directory) - isExternal = true; - if (segmentsToOptimize.contains(info)) - { - merge->optimize = true; - merge->maxNumSegmentsOptimize = optimizeMaxNumSegments; - } + int32_t count = merge->segments->size(); + bool isExternal = false; + for (int32_t i = 0; i < count; ++i) { + SegmentInfoPtr info(merge->segments->info(i)); + if (mergingSegments.contains(info)) { + return false; } + if (!segmentInfos->contains(info)) { + return false; + } + if (info->dir != directory) { + isExternal = true; + } + if (segmentsToOptimize.contains(info)) { + merge->optimize = true; + merge->maxNumSegmentsOptimize = optimizeMaxNumSegments; + } + } - ensureContiguousMerge(merge); - - pendingMerges.add(merge); - - if (infoStream) - message(L"add merge to pendingMerges: " + merge->segString(directory) + L" [total " + StringUtils::toString(pendingMerges.size()) + L" pending]"); - - merge->mergeGen = mergeGen; - merge->isExternal = isExternal; + ensureContiguousMerge(merge); - // OK it does not conflict; now record that this merge is running (while synchronized) - // to avoid race condition where two conflicting merges from different threads, start - for (int32_t i = 0; i < count; ++i) - mergingSegments.add(merge->segments->info(i)); + pendingMerges.add(merge); - // Merge is now registered - merge->registerDone = true; - return true; + if (infoStream) { + message(L"add merge to pendingMerges: " + merge->segString(directory) + L" [total " + StringUtils::toString(pendingMerges.size()) + L" pending]"); } - void IndexWriter::mergeInit(const OneMergePtr& merge) - { - SyncLock syncLock(this); - bool success = false; - LuceneException finally; - try - { - _mergeInit(merge); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } + merge->mergeGen = mergeGen; + merge->isExternal = isExternal; - if (!success) - mergeFinish(merge); - finally.throwException(); + // OK it does not conflict; now record that this merge is running (while synchronized) + // to avoid race condition where two conflicting merges from different threads, start + for (int32_t i = 0; i < count; ++i) { + mergingSegments.add(merge->segments->info(i)); } - void IndexWriter::_mergeInit(const OneMergePtr& merge) - { - SyncLock syncLock(this); - bool test = testPoint(L"startMergeInit"); - BOOST_ASSERT(test); - - BOOST_ASSERT(merge->registerDone); - BOOST_ASSERT(!merge->optimize || merge->maxNumSegmentsOptimize > 0); - - if (hitOOM) - boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot merge")); + // Merge is now registered + merge->registerDone = true; + return true; +} - if (merge->info) - { - // mergeInit already done - return; - } +void IndexWriter::mergeInit(const OneMergePtr& merge) { + SyncLock syncLock(this); + bool success = false; + LuceneException finally; + try { + _mergeInit(merge); + success = true; + } catch (LuceneException& e) { + finally = e; + } - if (merge->isAborted()) - return; + if (!success) { + mergeFinish(merge); + } + finally.throwException(); +} - applyDeletes(); +void IndexWriter::_mergeInit(const OneMergePtr& merge) { + SyncLock syncLock(this); + bool test = testPoint(L"startMergeInit"); + BOOST_ASSERT(test); - SegmentInfosPtr sourceSegments(merge->segments); - int32_t end = sourceSegments->size(); + BOOST_ASSERT(merge->registerDone); + BOOST_ASSERT(!merge->optimize || merge->maxNumSegmentsOptimize > 0); - // Check whether this merge will allow us to skip merging the doc stores (stored field & vectors). - // This is a very substantial optimization (saves tons of IO). - DirectoryPtr lastDir(directory); - String lastDocStoreSegment; - int32_t next = -1; + if (hitOOM) { + boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot merge")); + } - bool mergeDocStores = false; - bool doFlushDocStore = false; - String currentDocStoreSegment(docWriter->getDocStoreSegment()); + if (merge->info) { + // mergeInit already done + return; + } - // Test each segment to be merged: check if we need to flush/merge doc stores - for (int32_t i = 0; i < end; ++i) - { - SegmentInfoPtr si(sourceSegments->info(i)); + if (merge->isAborted()) { + return; + } - // If it has deletions we must merge the doc stores - if (si->hasDeletions()) - mergeDocStores = true; + applyDeletes(); - // If it has its own (private) doc stores we must merge the doc stores - if (si->getDocStoreOffset() == -1) - mergeDocStores = true; + SegmentInfosPtr sourceSegments(merge->segments); + int32_t end = sourceSegments->size(); - // If it has a different doc store segment than previous segments, we must merge the doc stores - String docStoreSegment(si->getDocStoreSegment()); - if (docStoreSegment.empty()) - mergeDocStores = true; - else if (lastDocStoreSegment.empty()) - lastDocStoreSegment = docStoreSegment; - else if (lastDocStoreSegment != docStoreSegment) - mergeDocStores = true; + // Check whether this merge will allow us to skip merging the doc stores (stored field & vectors). + // This is a very substantial optimization (saves tons of IO). + DirectoryPtr lastDir(directory); + String lastDocStoreSegment; + int32_t next = -1; - // Segments' docScoreOffsets must be in-order, contiguous. For the default merge policy now - // this will always be the case but for an arbitrary merge policy this may not be the case - if (next == -1) - next = si->getDocStoreOffset() + si->docCount; - else if (next != si->getDocStoreOffset()) - mergeDocStores = true; - else - next = si->getDocStoreOffset() + si->docCount; + bool mergeDocStores = false; + bool doFlushDocStore = false; + String currentDocStoreSegment(docWriter->getDocStoreSegment()); - // If the segment comes from a different directory we must merge - if (lastDir != si->dir) - mergeDocStores = true; + // Test each segment to be merged: check if we need to flush/merge doc stores + for (int32_t i = 0; i < end; ++i) { + SegmentInfoPtr si(sourceSegments->info(i)); - // If the segment is referencing the current "live" doc store outputs then we must merge - if (si->getDocStoreOffset() != -1 && !currentDocStoreSegment.empty() && si->getDocStoreSegment() == currentDocStoreSegment) - doFlushDocStore = true; + // If it has deletions we must merge the doc stores + if (si->hasDeletions()) { + mergeDocStores = true; } - // if a mergedSegmentWarmer is installed, we must merge the doc stores because we will open a full - // SegmentReader on the merged segment - if (!mergeDocStores && mergedSegmentWarmer && !currentDocStoreSegment.empty() && !lastDocStoreSegment.empty() && lastDocStoreSegment == currentDocStoreSegment) + // If it has its own (private) doc stores we must merge the doc stores + if (si->getDocStoreOffset() == -1) { mergeDocStores = true; + } - int32_t docStoreOffset; - String docStoreSegment; - bool docStoreIsCompoundFile; - - if (mergeDocStores) - { - docStoreOffset = -1; - docStoreSegment.clear(); - docStoreIsCompoundFile = false; + // If it has a different doc store segment than previous segments, we must merge the doc stores + String docStoreSegment(si->getDocStoreSegment()); + if (docStoreSegment.empty()) { + mergeDocStores = true; + } else if (lastDocStoreSegment.empty()) { + lastDocStoreSegment = docStoreSegment; + } else if (lastDocStoreSegment != docStoreSegment) { + mergeDocStores = true; } - else - { - SegmentInfoPtr si(sourceSegments->info(0)); - docStoreOffset = si->getDocStoreOffset(); - docStoreSegment = si->getDocStoreSegment(); - docStoreIsCompoundFile = si->getDocStoreIsCompoundFile(); + + // Segments' docScoreOffsets must be in-order, contiguous. For the default merge policy now + // this will always be the case but for an arbitrary merge policy this may not be the case + if (next == -1) { + next = si->getDocStoreOffset() + si->docCount; + } else if (next != si->getDocStoreOffset()) { + mergeDocStores = true; + } else { + next = si->getDocStoreOffset() + si->docCount; } - if (mergeDocStores && doFlushDocStore) - { - // SegmentMerger intends to merge the doc stores (stored fields, vectors), and at - // least one of the segments to be merged refers to the currently live doc stores. - if (infoStream) - message(L"now flush at merge"); - doFlush(true, false); + // If the segment comes from a different directory we must merge + if (lastDir != si->dir) { + mergeDocStores = true; } - merge->mergeDocStores = mergeDocStores; + // If the segment is referencing the current "live" doc store outputs then we must merge + if (si->getDocStoreOffset() != -1 && !currentDocStoreSegment.empty() && si->getDocStoreSegment() == currentDocStoreSegment) { + doFlushDocStore = true; + } + } - // Bind a new segment name here so even with ConcurrentMergePolicy we keep deterministic segment names. - merge->info = newLucene(newSegmentName(), 0, directory, false, true, docStoreOffset, docStoreSegment, docStoreIsCompoundFile, false); + // if a mergedSegmentWarmer is installed, we must merge the doc stores because we will open a full + // SegmentReader on the merged segment + if (!mergeDocStores && mergedSegmentWarmer && !currentDocStoreSegment.empty() && !lastDocStoreSegment.empty() && lastDocStoreSegment == currentDocStoreSegment) { + mergeDocStores = true; + } - MapStringString details(MapStringString::newInstance()); - details.put(L"optimize", StringUtils::toString(merge->optimize)); - details.put(L"mergeFactor", StringUtils::toString(end)); - details.put(L"mergeDocStores", StringUtils::toString(mergeDocStores)); - setDiagnostics(merge->info, L"merge", details); + int32_t docStoreOffset; + String docStoreSegment; + bool docStoreIsCompoundFile; - // Also enroll the merged segment into mergingSegments; this prevents it from getting - // selected for a merge after our merge is done but while we are building the CFS - mergingSegments.add(merge->info); + if (mergeDocStores) { + docStoreOffset = -1; + docStoreSegment.clear(); + docStoreIsCompoundFile = false; + } else { + SegmentInfoPtr si(sourceSegments->info(0)); + docStoreOffset = si->getDocStoreOffset(); + docStoreSegment = si->getDocStoreSegment(); + docStoreIsCompoundFile = si->getDocStoreIsCompoundFile(); } - void IndexWriter::setDiagnostics(const SegmentInfoPtr& info, const String& source) - { - setDiagnostics(info, source, MapStringString()); + if (mergeDocStores && doFlushDocStore) { + // SegmentMerger intends to merge the doc stores (stored fields, vectors), and at + // least one of the segments to be merged refers to the currently live doc stores. + if (infoStream) { + message(L"now flush at merge"); + } + doFlush(true, false); } - void IndexWriter::setDiagnostics(const SegmentInfoPtr& info, const String& source, MapStringString details) - { - MapStringString diagnostics(MapStringString::newInstance()); - diagnostics.put(L"source", source); - diagnostics.put(L"lucene.version", Constants::LUCENE_VERSION); - diagnostics.put(L"os", Constants::OS_NAME); - if (details) - diagnostics.putAll(details.begin(), details.end()); - info->setDiagnostics(diagnostics); - } + merge->mergeDocStores = mergeDocStores; - void IndexWriter::mergeFinish(const OneMergePtr& merge) - { - SyncLock syncLock(this); - // Optimize, addIndexes or finishMerges may be waiting on merges to finish. - notifyAll(); + // Bind a new segment name here so even with ConcurrentMergePolicy we keep deterministic segment names. + merge->info = newLucene(newSegmentName(), 0, directory, false, true, docStoreOffset, docStoreSegment, docStoreIsCompoundFile, false); - // It's possible we are called twice, eg if there was an exception inside mergeInit - if (merge->registerDone) - { - SegmentInfosPtr sourceSegments(merge->segments); - int32_t end = sourceSegments->size(); - for (int32_t i = 0; i < end; ++i) - mergingSegments.remove(sourceSegments->info(i)); + MapStringString details(MapStringString::newInstance()); + details.put(L"optimize", StringUtils::toString(merge->optimize)); + details.put(L"mergeFactor", StringUtils::toString(end)); + details.put(L"mergeDocStores", StringUtils::toString(mergeDocStores)); + setDiagnostics(merge->info, L"merge", details); - mergingSegments.remove(merge->info); - merge->registerDone = false; - } + // Also enroll the merged segment into mergingSegments; this prevents it from getting + // selected for a merge after our merge is done but while we are building the CFS + mergingSegments.add(merge->info); +} + +void IndexWriter::setDiagnostics(const SegmentInfoPtr& info, const String& source) { + setDiagnostics(info, source, MapStringString()); +} - runningMerges.remove(merge); +void IndexWriter::setDiagnostics(const SegmentInfoPtr& info, const String& source, MapStringString details) { + MapStringString diagnostics(MapStringString::newInstance()); + diagnostics.put(L"source", source); + diagnostics.put(L"lucene.version", Constants::LUCENE_VERSION); + diagnostics.put(L"os", Constants::OS_NAME); + if (details) { + diagnostics.putAll(details.begin(), details.end()); } + info->setDiagnostics(diagnostics); +} - void IndexWriter::setMergeDocStoreIsCompoundFile(const OneMergePtr& merge) - { - SyncLock syncLock(this); +void IndexWriter::mergeFinish(const OneMergePtr& merge) { + SyncLock syncLock(this); + // Optimize, addIndexes or finishMerges may be waiting on merges to finish. + notifyAll(); - String mergeDocStoreSegment(merge->info->getDocStoreSegment()); - if (!mergeDocStoreSegment.empty() && !merge->info->getDocStoreIsCompoundFile()) - { - int32_t size = segmentInfos->size(); - for (int32_t i = 0; i < size; ++i) - { - SegmentInfoPtr info(segmentInfos->info(i)); - String docStoreSegment(info->getDocStoreSegment()); - if (!docStoreSegment.empty() && docStoreSegment == mergeDocStoreSegment && info->getDocStoreIsCompoundFile()) - { - merge->info->setDocStoreIsCompoundFile(true); - break; - } - } + // It's possible we are called twice, eg if there was an exception inside mergeInit + if (merge->registerDone) { + SegmentInfosPtr sourceSegments(merge->segments); + int32_t end = sourceSegments->size(); + for (int32_t i = 0; i < end; ++i) { + mergingSegments.remove(sourceSegments->info(i)); } + + mergingSegments.remove(merge->info); + merge->registerDone = false; } - void IndexWriter::closeMergeReaders(const OneMergePtr& merge, bool suppressExceptions) - { - SyncLock syncLock(this); + runningMerges.remove(merge); +} - int32_t numSegments = merge->segments->size(); - if (suppressExceptions) - { - // Suppress any new exceptions so we throw the original cause - for (int32_t i = 0; i < numSegments; ++i) - { - if (merge->readers[i]) - { - try - { - readerPool->release(merge->readers[i], false); - } - catch (...) - { - } - merge->readers[i].reset(); - } +void IndexWriter::setMergeDocStoreIsCompoundFile(const OneMergePtr& merge) { + SyncLock syncLock(this); - if (merge->readersClone[i]) - { - try - { - merge->readersClone[i]->close(); - } - catch (...) - { - } - // This was a private clone and we had the only reference - BOOST_ASSERT(merge->readersClone[i]->getRefCount() == 0); - merge->readersClone[i].reset(); - } + String mergeDocStoreSegment(merge->info->getDocStoreSegment()); + if (!mergeDocStoreSegment.empty() && !merge->info->getDocStoreIsCompoundFile()) { + int32_t size = segmentInfos->size(); + for (int32_t i = 0; i < size; ++i) { + SegmentInfoPtr info(segmentInfos->info(i)); + String docStoreSegment(info->getDocStoreSegment()); + if (!docStoreSegment.empty() && docStoreSegment == mergeDocStoreSegment && info->getDocStoreIsCompoundFile()) { + merge->info->setDocStoreIsCompoundFile(true); + break; } } - else - { - for (int32_t i = 0; i < numSegments; ++i) - { - if (merge->readers[i]) - { - readerPool->release(merge->readers[i], true); - merge->readers[i].reset(); + } +} + +void IndexWriter::closeMergeReaders(const OneMergePtr& merge, bool suppressExceptions) { + SyncLock syncLock(this); + + int32_t numSegments = merge->segments->size(); + if (suppressExceptions) { + // Suppress any new exceptions so we throw the original cause + for (int32_t i = 0; i < numSegments; ++i) { + if (merge->readers[i]) { + try { + readerPool->release(merge->readers[i], false); + } catch (...) { } + merge->readers[i].reset(); + } - if (merge->readersClone[i]) - { + if (merge->readersClone[i]) { + try { merge->readersClone[i]->close(); - // This was a private clone and we had the only reference - BOOST_ASSERT(merge->readersClone[i]->getRefCount() == 0); - merge->readersClone[i].reset(); + } catch (...) { } + // This was a private clone and we had the only reference + BOOST_ASSERT(merge->readersClone[i]->getRefCount() == 0); + merge->readersClone[i].reset(); } } - } + } else { + for (int32_t i = 0; i < numSegments; ++i) { + if (merge->readers[i]) { + readerPool->release(merge->readers[i], true); + merge->readers[i].reset(); + } - int32_t IndexWriter::mergeMiddle(const OneMergePtr& merge) - { - merge->checkAborted(directory); + if (merge->readersClone[i]) { + merge->readersClone[i]->close(); + // This was a private clone and we had the only reference + BOOST_ASSERT(merge->readersClone[i]->getRefCount() == 0); + merge->readersClone[i].reset(); + } + } + } +} - String mergedName(merge->info->name); - int32_t mergedDocCount = 0; +int32_t IndexWriter::mergeMiddle(const OneMergePtr& merge) { + merge->checkAborted(directory); - SegmentInfosPtr sourceSegments(merge->segments); - int32_t numSegments = sourceSegments->size(); + String mergedName(merge->info->name); + int32_t mergedDocCount = 0; - if (infoStream) - message(L"merging " + merge->segString(directory)); + SegmentInfosPtr sourceSegments(merge->segments); + int32_t numSegments = sourceSegments->size(); - SegmentMergerPtr merger(newLucene(shared_from_this(), mergedName, merge)); + if (infoStream) { + message(L"merging " + merge->segString(directory)); + } - merge->readers = Collection::newInstance(numSegments); - merge->readersClone = Collection::newInstance(numSegments); + SegmentMergerPtr merger(newLucene(shared_from_this(), mergedName, merge)); - bool mergeDocStores = false; + merge->readers = Collection::newInstance(numSegments); + merge->readersClone = Collection::newInstance(numSegments); - String currentDocStoreSegment; - { - SyncLock syncLock(this); - currentDocStoreSegment = docWriter->getDocStoreSegment(); - } + bool mergeDocStores = false; - bool currentDSSMerged = false; + String currentDocStoreSegment; + { + SyncLock syncLock(this); + currentDocStoreSegment = docWriter->getDocStoreSegment(); + } - LuceneException finally; - // This is try/finally to make sure merger's readers are closed - bool success = false; - try - { - int32_t totDocCount = 0; - for (int32_t i = 0; i < numSegments; ++i) - { - SegmentInfoPtr info(sourceSegments->info(i)); + bool currentDSSMerged = false; - // Hold onto the "live" reader; we will use this to commit merged deletes - merge->readers[i] = readerPool->get(info, merge->mergeDocStores, MERGE_READ_BUFFER_SIZE, -1); - SegmentReaderPtr reader(merge->readers[i]); + LuceneException finally; + // This is try/finally to make sure merger's readers are closed + bool success = false; + try { + int32_t totDocCount = 0; + for (int32_t i = 0; i < numSegments; ++i) { + SegmentInfoPtr info(sourceSegments->info(i)); - // We clone the segment readers because other deletes may come in while we're merging so we need readers that will not change - merge->readersClone[i] = boost::dynamic_pointer_cast(reader->clone(true)); - SegmentReaderPtr clone(merge->readersClone[i]); - merger->add(clone); + // Hold onto the "live" reader; we will use this to commit merged deletes + merge->readers[i] = readerPool->get(info, merge->mergeDocStores, MERGE_READ_BUFFER_SIZE, -1); + SegmentReaderPtr reader(merge->readers[i]); - if (clone->hasDeletions()) - mergeDocStores = true; + // We clone the segment readers because other deletes may come in while we're merging so we need readers that will not change + merge->readersClone[i] = boost::dynamic_pointer_cast(reader->clone(true)); + SegmentReaderPtr clone(merge->readersClone[i]); + merger->add(clone); - if (info->getDocStoreOffset() != -1 && !currentDocStoreSegment.empty()) - currentDSSMerged = currentDSSMerged || (currentDocStoreSegment == info->getDocStoreSegment()); + if (clone->hasDeletions()) { + mergeDocStores = true; + } - totDocCount += clone->numDocs(); + if (info->getDocStoreOffset() != -1 && !currentDocStoreSegment.empty()) { + currentDSSMerged = currentDSSMerged || (currentDocStoreSegment == info->getDocStoreSegment()); } - if (infoStream) - message(L"merge: total " + StringUtils::toString(totDocCount) + L" docs"); + totDocCount += clone->numDocs(); + } + + if (infoStream) { + message(L"merge: total " + StringUtils::toString(totDocCount) + L" docs"); + } - merge->checkAborted(directory); + merge->checkAborted(directory); - // If deletions have arrived and it has now become necessary to merge doc stores, go and open them - if (mergeDocStores && !merge->mergeDocStores) - { - merge->mergeDocStores = true; + // If deletions have arrived and it has now become necessary to merge doc stores, go and open them + if (mergeDocStores && !merge->mergeDocStores) { + merge->mergeDocStores = true; - { - SyncLock syncLock(this); - if (currentDSSMerged) - { - if (infoStream) - message(L"now flush at mergeMiddle"); - doFlush(true, false); + { + SyncLock syncLock(this); + if (currentDSSMerged) { + if (infoStream) { + message(L"now flush at mergeMiddle"); } + doFlush(true, false); } + } - for (Collection::iterator reader = merge->readersClone.begin(); reader != merge->readersClone.end(); ++reader) - (*reader)->openDocStores(); - - // Clear DSS - merge->info->setDocStore(-1, L"", false); + for (Collection::iterator reader = merge->readersClone.begin(); reader != merge->readersClone.end(); ++reader) { + (*reader)->openDocStores(); } - // This is where all the work happens - merge->info->docCount = merger->merge(merge->mergeDocStores); - mergedDocCount = merge->info->docCount; + // Clear DSS + merge->info->setDocStore(-1, L"", false); + } - BOOST_ASSERT(mergedDocCount == totDocCount); + // This is where all the work happens + merge->info->docCount = merger->merge(merge->mergeDocStores); + mergedDocCount = merge->info->docCount; - if (merge->useCompoundFile) - { - success = false; + BOOST_ASSERT(mergedDocCount == totDocCount); - String compoundFileName(IndexFileNames::segmentFileName(mergedName, IndexFileNames::COMPOUND_FILE_EXTENSION())); + if (merge->useCompoundFile) { + success = false; - try - { - if (infoStream) - message(L"create compound file " + compoundFileName); - merger->createCompoundFile(compoundFileName); - success = true; - } - catch (IOException& ioe) - { - SyncLock syncLock(this); - if (merge->isAborted()) - { - // This can happen if rollback or close(false) is called - fall through to logic - // below to remove the partially created CFS - } - else - finally = handleMergeException(ioe, merge); + String compoundFileName(IndexFileNames::segmentFileName(mergedName, IndexFileNames::COMPOUND_FILE_EXTENSION())); + + try { + if (infoStream) { + message(L"create compound file " + compoundFileName); } - catch (LuceneException& e) - { - finally = handleMergeException(e, merge); + merger->createCompoundFile(compoundFileName); + success = true; + } catch (IOException& ioe) { + SyncLock syncLock(this); + if (merge->isAborted()) { + // This can happen if rollback or close(false) is called - fall through to logic + // below to remove the partially created CFS + } else { + finally = handleMergeException(ioe, merge); } + } catch (LuceneException& e) { + finally = handleMergeException(e, merge); + } - if (!success) - { - if (infoStream) - message(L"hit exception creating compound file during merge"); - { - SyncLock syncLock(this); - deleter->deleteFile(compoundFileName); - deleter->deleteNewFiles(merger->getMergedFiles()); - } + if (!success) { + if (infoStream) { + message(L"hit exception creating compound file during merge"); } - - finally.throwException(); - - success = false; - { SyncLock syncLock(this); - - // delete new non cfs files directly: they were never registered with IFD + deleter->deleteFile(compoundFileName); deleter->deleteNewFiles(merger->getMergedFiles()); - - if (merge->isAborted()) - { - if (infoStream) - message(L"abort merge after building CFS"); - deleter->deleteFile(compoundFileName); - boost::throw_exception(TemporaryException()); - } } - - merge->info->setUseCompoundFile(true); } - int32_t termsIndexDivisor = -1; - bool loadDocStores = false; + finally.throwException(); - // if the merged segment warmer was not installed when this merge was started, causing us - // to not force the docStores to close, we can't warm it now - bool canWarm = (merge->info->getDocStoreSegment().empty() || currentDocStoreSegment.empty() || merge->info->getDocStoreSegment() == currentDocStoreSegment); + success = false; - if (poolReaders && mergedSegmentWarmer && canWarm) { - // Load terms index & doc stores so the segment warmer can run searches, load documents/term vectors - termsIndexDivisor = readerTermsIndexDivisor; - loadDocStores = true; - } + SyncLock syncLock(this); - SegmentReaderPtr mergedReader(readerPool->get(merge->info, loadDocStores, BufferedIndexInput::BUFFER_SIZE, termsIndexDivisor)); + // delete new non cfs files directly: they were never registered with IFD + deleter->deleteNewFiles(merger->getMergedFiles()); - try - { - if (poolReaders && mergedSegmentWarmer) - mergedSegmentWarmer->warm(mergedReader); - if (!commitMerge(merge, merger, mergedDocCount, mergedReader)) - { - // commitMerge will return false if this merge was aborted + if (merge->isAborted()) { + if (infoStream) { + message(L"abort merge after building CFS"); + } + deleter->deleteFile(compoundFileName); boost::throw_exception(TemporaryException()); } } - catch (LuceneException& e) - { - finally = e; - } - { - SyncLock syncLock(this); - readerPool->release(mergedReader); - } + merge->info->setUseCompoundFile(true); + } - finally.throwException(); + int32_t termsIndexDivisor = -1; + bool loadDocStores = false; - success = true; + // if the merged segment warmer was not installed when this merge was started, causing us + // to not force the docStores to close, we can't warm it now + bool canWarm = (merge->info->getDocStoreSegment().empty() || currentDocStoreSegment.empty() || merge->info->getDocStoreSegment() == currentDocStoreSegment); + + if (poolReaders && mergedSegmentWarmer && canWarm) { + // Load terms index & doc stores so the segment warmer can run searches, load documents/term vectors + termsIndexDivisor = readerTermsIndexDivisor; + loadDocStores = true; } - catch (LuceneException& e) - { + + SegmentReaderPtr mergedReader(readerPool->get(merge->info, loadDocStores, BufferedIndexInput::BUFFER_SIZE, termsIndexDivisor)); + + try { + if (poolReaders && mergedSegmentWarmer) { + mergedSegmentWarmer->warm(mergedReader); + } + if (!commitMerge(merge, merger, mergedDocCount, mergedReader)) { + // commitMerge will return false if this merge was aborted + boost::throw_exception(TemporaryException()); + } + } catch (LuceneException& e) { finally = e; } - // Readers are already closed in commitMerge if we didn't hit an exc - if (!success) - closeMergeReaders(merge, true); - - // has this merge been aborted? - if (finally.getType() == LuceneException::Temporary) - return 0; + { + SyncLock syncLock(this); + readerPool->release(mergedReader); + } finally.throwException(); - return mergedDocCount; + success = true; + } catch (LuceneException& e) { + finally = e; } - void IndexWriter::addMergeException(const OneMergePtr& merge) - { - SyncLock syncLock(this); - BOOST_ASSERT(!merge->getException().isNull()); - if (!mergeExceptions.contains(merge) && mergeGen == merge->mergeGen) - mergeExceptions.add(merge); + // Readers are already closed in commitMerge if we didn't hit an exc + if (!success) { + closeMergeReaders(merge, true); } - bool IndexWriter::applyDeletes() - { - TestScope testScope(L"IndexWriter", L"applyDeletes"); - SyncLock syncLock(this); - BOOST_ASSERT(testPoint(L"startApplyDeletes")); - ++flushDeletesCount; - bool success = false; - bool changed = false; - - LuceneException finally; - try - { - changed = docWriter->applyDeletes(segmentInfos); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } + // has this merge been aborted? + if (finally.getType() == LuceneException::Temporary) { + return 0; + } - if (!success && infoStream) - message(L"hit exception flushing deletes"); + finally.throwException(); - finally.throwException(); + return mergedDocCount; +} - if (changed) - checkpoint(); - return changed; +void IndexWriter::addMergeException(const OneMergePtr& merge) { + SyncLock syncLock(this); + BOOST_ASSERT(!merge->getException().isNull()); + if (!mergeExceptions.contains(merge) && mergeGen == merge->mergeGen) { + mergeExceptions.add(merge); } +} - int32_t IndexWriter::getBufferedDeleteTermsSize() - { - SyncLock syncLock(this); - return docWriter->getBufferedDeleteTerms().size(); - } +bool IndexWriter::applyDeletes() { + TestScope testScope(L"IndexWriter", L"applyDeletes"); + SyncLock syncLock(this); + BOOST_ASSERT(testPoint(L"startApplyDeletes")); + ++flushDeletesCount; + bool success = false; + bool changed = false; - int32_t IndexWriter::getNumBufferedDeleteTerms() - { - SyncLock syncLock(this); - return docWriter->getNumBufferedDeleteTerms(); + LuceneException finally; + try { + changed = docWriter->applyDeletes(segmentInfos); + success = true; + } catch (LuceneException& e) { + finally = e; } - SegmentInfoPtr IndexWriter::newestSegment() - { - return !segmentInfos->empty() ? segmentInfos->info(segmentInfos->size() - 1) : SegmentInfoPtr(); + if (!success && infoStream) { + message(L"hit exception flushing deletes"); } - String IndexWriter::segString() - { - return segString(segmentInfos); + finally.throwException(); + + if (changed) { + checkpoint(); } + return changed; +} - String IndexWriter::segString(const SegmentInfosPtr& infos) - { - SyncLock syncLock(this); - StringStream buffer; - int32_t count = infos->size(); - for (int32_t i = 0; i < count; ++i) - { - if (i > 0) - buffer << L" "; - SegmentInfoPtr info(infos->info(i)); - buffer << info->segString(directory); - if (info->dir != directory) - buffer << L"**"; +int32_t IndexWriter::getBufferedDeleteTermsSize() { + SyncLock syncLock(this); + return docWriter->getBufferedDeleteTerms().size(); +} + +int32_t IndexWriter::getNumBufferedDeleteTerms() { + SyncLock syncLock(this); + return docWriter->getNumBufferedDeleteTerms(); +} + +SegmentInfoPtr IndexWriter::newestSegment() { + return !segmentInfos->empty() ? segmentInfos->info(segmentInfos->size() - 1) : SegmentInfoPtr(); +} + +String IndexWriter::segString() { + return segString(segmentInfos); +} + +String IndexWriter::segString(const SegmentInfosPtr& infos) { + SyncLock syncLock(this); + StringStream buffer; + int32_t count = infos->size(); + for (int32_t i = 0; i < count; ++i) { + if (i > 0) { + buffer << L" "; + } + SegmentInfoPtr info(infos->info(i)); + buffer << info->segString(directory); + if (info->dir != directory) { + buffer << L"**"; } - return buffer.str(); } + return buffer.str(); +} - bool IndexWriter::startSync(const String& fileName, HashSet pending) - { - SyncLock syncedLock(&synced); - if (!synced.contains(fileName)) - { - if (!syncing.contains(fileName)) - { - syncing.add(fileName); - return true; - } - else - { - pending.add(fileName); - return false; - } - } - else +bool IndexWriter::startSync(const String& fileName, HashSet pending) { + SyncLock syncedLock(&synced); + if (!synced.contains(fileName)) { + if (!syncing.contains(fileName)) { + syncing.add(fileName); + return true; + } else { + pending.add(fileName); return false; + } + } else { + return false; } +} - void IndexWriter::finishSync(const String& fileName, bool success) - { - SyncLock syncedLock(&synced); - BOOST_ASSERT(syncing.contains(fileName)); - syncing.remove(fileName); - if (success) - synced.add(fileName); - synced.notifyAll(); +void IndexWriter::finishSync(const String& fileName, bool success) { + SyncLock syncedLock(&synced); + BOOST_ASSERT(syncing.contains(fileName)); + syncing.remove(fileName); + if (success) { + synced.add(fileName); } + synced.notifyAll(); +} - bool IndexWriter::waitForAllSynced(HashSet syncing) - { - SyncLock syncedLock(&synced); - for (HashSet::iterator fileName = syncing.begin(); fileName != syncing.end(); ++fileName) - { - while (!synced.contains(*fileName)) - { - if (!syncing.contains(*fileName)) - { - // There was an error because a file that was previously syncing failed to appear in synced - return false; - } - else - synced.wait(); +bool IndexWriter::waitForAllSynced(HashSet syncing) { + SyncLock syncedLock(&synced); + for (HashSet::iterator fileName = syncing.begin(); fileName != syncing.end(); ++fileName) { + while (!synced.contains(*fileName)) { + if (!syncing.contains(*fileName)) { + // There was an error because a file that was previously syncing failed to appear in synced + return false; + } else { + synced.wait(); } } - return true; } + return true; +} - void IndexWriter::doWait() - { - SyncLock syncLock(this); - // NOTE: the callers of this method should in theory be able to do simply wait(), but, as a defense against - // thread timing hazards where notifyAll() fails to be called, we wait for at most 1 second and then return - // so caller can check if wait conditions are satisfied - wait(1000); - } +void IndexWriter::doWait() { + SyncLock syncLock(this); + // NOTE: the callers of this method should in theory be able to do simply wait(), but, as a defense against + // thread timing hazards where notifyAll() fails to be called, we wait for at most 1 second and then return + // so caller can check if wait conditions are satisfied + wait(1000); +} - void IndexWriter::startCommit(int64_t sizeInBytes, MapStringString commitUserData) - { - BOOST_ASSERT(testPoint(L"startStartCommit")); +void IndexWriter::startCommit(int64_t sizeInBytes, MapStringString commitUserData) { + BOOST_ASSERT(testPoint(L"startStartCommit")); - if (hitOOM) - boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot commit")); + if (hitOOM) { + boost::throw_exception(IllegalStateException(L"this writer hit an OutOfMemoryError; cannot commit")); + } - try - { - if (infoStream) - message(L"startCommit(): start sizeInBytes=" + StringUtils::toString(sizeInBytes)); + try { + if (infoStream) { + message(L"startCommit(): start sizeInBytes=" + StringUtils::toString(sizeInBytes)); + } - SegmentInfosPtr toSync; - int64_t myChangeCount = 0; - LuceneException finally; + SegmentInfosPtr toSync; + int64_t myChangeCount = 0; + LuceneException finally; - { - SyncLock syncLock(this); + { + SyncLock syncLock(this); - // Wait for any running addIndexes to complete first, then block any from running - // until we've copied the segmentInfos we intend to sync - blockAddIndexes(false); + // Wait for any running addIndexes to complete first, then block any from running + // until we've copied the segmentInfos we intend to sync + blockAddIndexes(false); - // On commit the segmentInfos must never reference a segment in another directory - BOOST_ASSERT(!hasExternalSegments()); + // On commit the segmentInfos must never reference a segment in another directory + BOOST_ASSERT(!hasExternalSegments()); - try - { - BOOST_ASSERT(lastCommitChangeCount <= changeCount); - myChangeCount = changeCount; + try { + BOOST_ASSERT(lastCommitChangeCount <= changeCount); + myChangeCount = changeCount; - if (changeCount == lastCommitChangeCount) - { - if (infoStream) - message(L" skip startCommit(): no changes pending"); - boost::throw_exception(TemporaryException()); + if (changeCount == lastCommitChangeCount) { + if (infoStream) { + message(L" skip startCommit(): no changes pending"); } + boost::throw_exception(TemporaryException()); + } - // First, we clone & incref the segmentInfos we intend to sync, then, without locking, we sync() each - // file referenced by toSync, in the background. Multiple threads can be doing this at once, if say - // a large merge and a small merge finish at the same time + // First, we clone & incref the segmentInfos we intend to sync, then, without locking, we sync() each + // file referenced by toSync, in the background. Multiple threads can be doing this at once, if say + // a large merge and a small merge finish at the same time - if (infoStream) - message(L"startCommit index=" + segString(segmentInfos) + L" changeCount=" + StringUtils::toString(changeCount)); + if (infoStream) { + message(L"startCommit index=" + segString(segmentInfos) + L" changeCount=" + StringUtils::toString(changeCount)); + } - readerPool->commit(); + readerPool->commit(); - // It's possible another flush (that did not close the open do stores) snook in after the flush we - // just did, so we remove any tail segments referencing the open doc store from the SegmentInfos - // we are about to sync (the main SegmentInfos will keep them) - toSync = boost::dynamic_pointer_cast(segmentInfos->clone()); + // It's possible another flush (that did not close the open do stores) snook in after the flush we + // just did, so we remove any tail segments referencing the open doc store from the SegmentInfos + // we are about to sync (the main SegmentInfos will keep them) + toSync = boost::dynamic_pointer_cast(segmentInfos->clone()); - String dss(docWriter->getDocStoreSegment()); - if (!dss.empty()) - { - while(true) - { - String dss2(toSync->info(toSync->size() - 1)->getDocStoreSegment()); - if (dss2.empty() || dss2 != dss) - break; - toSync->remove(toSync->size() - 1); - ++changeCount; + String dss(docWriter->getDocStoreSegment()); + if (!dss.empty()) { + while (true) { + String dss2(toSync->info(toSync->size() - 1)->getDocStoreSegment()); + if (dss2.empty() || dss2 != dss) { + break; } + toSync->remove(toSync->size() - 1); + ++changeCount; } + } - if (commitUserData) - toSync->setUserData(commitUserData); + if (commitUserData) { + toSync->setUserData(commitUserData); + } - deleter->incRef(toSync, false); + deleter->incRef(toSync, false); - HashSet files(toSync->files(directory, false)); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { - BOOST_ASSERT(directory->fileExists(*fileName)); + HashSet files(toSync->files(directory, false)); + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + BOOST_ASSERT(directory->fileExists(*fileName)); - // If this trips it means we are missing a call to .checkpoint somewhere, because by the - // time we are called, deleter should know about every file referenced by the current head - // segmentInfos - BOOST_ASSERT(deleter->exists(*fileName)); - } - } - catch (LuceneException& e) - { - finally = e; + // If this trips it means we are missing a call to .checkpoint somewhere, because by the + // time we are called, deleter should know about every file referenced by the current head + // segmentInfos + BOOST_ASSERT(deleter->exists(*fileName)); } - resumeAddIndexes(); - - // no changes pending? - if (finally.getType() == LuceneException::Temporary) - return; + } catch (LuceneException& e) { + finally = e; + } + resumeAddIndexes(); - finally.throwException(); + // no changes pending? + if (finally.getType() == LuceneException::Temporary) { + return; } - BOOST_ASSERT(testPoint(L"midStartCommit")); + finally.throwException(); + } - bool setPending = false; + BOOST_ASSERT(testPoint(L"midStartCommit")); - try - { - // Loop until all files toSync references are sync'd - while (true) - { - HashSet pending(HashSet::newInstance()); - HashSet files(toSync->files(directory, false)); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { - if (startSync(*fileName, pending)) - { - bool success = false; - try - { - // Because we incRef'd this commit point above, the file had better exist - BOOST_ASSERT(directory->fileExists(*fileName)); - - if (infoStream) - message(L"now sync " + *fileName); - directory->sync(*fileName); - success = true; - } - catch (LuceneException& e) - { - finally = e; + bool setPending = false; + + try { + // Loop until all files toSync references are sync'd + while (true) { + HashSet pending(HashSet::newInstance()); + HashSet files(toSync->files(directory, false)); + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { + if (startSync(*fileName, pending)) { + bool success = false; + try { + // Because we incRef'd this commit point above, the file had better exist + BOOST_ASSERT(directory->fileExists(*fileName)); + + if (infoStream) { + message(L"now sync " + *fileName); } - finishSync(*fileName, success); - finally.throwException(); + directory->sync(*fileName); + success = true; + } catch (LuceneException& e) { + finally = e; } + finishSync(*fileName, success); + finally.throwException(); } + } - // All files that I require are either synced or being synced by other threads. If they are being - // synced, we must at this point block until they are done. If this returns false, that means an - // error in another thread resulted in failing to actually sync one of our files, so we repeat - if (waitForAllSynced(pending)) - break; + // All files that I require are either synced or being synced by other threads. If they are being + // synced, we must at this point block until they are done. If this returns false, that means an + // error in another thread resulted in failing to actually sync one of our files, so we repeat + if (waitForAllSynced(pending)) { + break; } + } - BOOST_ASSERT(testPoint(L"midStartCommit2")); + BOOST_ASSERT(testPoint(L"midStartCommit2")); - { - SyncLock syncLock(this); + { + SyncLock syncLock(this); - // If someone saved a newer version of segments file since I first started syncing - // my version, I can safely skip saving myself since I've been superseded + // If someone saved a newer version of segments file since I first started syncing + // my version, I can safely skip saving myself since I've been superseded - while (true) - { - if (myChangeCount <= lastCommitChangeCount) - { - if (infoStream) - message(L"sync superseded by newer infos"); - break; + while (true) { + if (myChangeCount <= lastCommitChangeCount) { + if (infoStream) { + message(L"sync superseded by newer infos"); } - else if (!pendingCommit) - { - // My turn to commit - if (segmentInfos->getGeneration() > toSync->getGeneration()) - toSync->updateGeneration(segmentInfos); - - bool success = false; - try - { - // Exception here means nothing is prepared (this method unwinds - // everything it did on an exception) - try - { - toSync->prepareCommit(directory); - } - catch (LuceneException& e) - { - finally = e; - } - - // Have our master segmentInfos record the generations we just prepared. We do this on - // error or success so we don't double-write a segments_N file. - segmentInfos->updateGeneration(toSync); - finally.throwException(); - - BOOST_ASSERT(!pendingCommit); - setPending = true; - pendingCommit = toSync; - pendingCommitChangeCount = myChangeCount; - success = true; - } - catch (LuceneException& e) - { + break; + } else if (!pendingCommit) { + // My turn to commit + if (segmentInfos->getGeneration() > toSync->getGeneration()) { + toSync->updateGeneration(segmentInfos); + } + + bool success = false; + try { + // Exception here means nothing is prepared (this method unwinds + // everything it did on an exception) + try { + toSync->prepareCommit(directory); + } catch (LuceneException& e) { finally = e; } - if (!success && infoStream) - message(L"hit exception committing segments file"); + // Have our master segmentInfos record the generations we just prepared. We do this on + // error or success so we don't double-write a segments_N file. + segmentInfos->updateGeneration(toSync); finally.throwException(); - break; + + BOOST_ASSERT(!pendingCommit); + setPending = true; + pendingCommit = toSync; + pendingCommitChangeCount = myChangeCount; + success = true; + } catch (LuceneException& e) { + finally = e; } - else - { - // Must wait for other commit to complete - doWait(); + + if (!success && infoStream) { + message(L"hit exception committing segments file"); } + finally.throwException(); + break; + } else { + // Must wait for other commit to complete + doWait(); } } - - if (infoStream) - message(L"done all syncs"); - BOOST_ASSERT(testPoint(L"midStartCommitSuccess")); - } - catch (LuceneException& e) - { - finally = e; } - { - SyncLock syncLock(this); - if (!setPending) - deleter->decRef(toSync); + if (infoStream) { + message(L"done all syncs"); } - finally.throwException(); + BOOST_ASSERT(testPoint(L"midStartCommitSuccess")); + } catch (LuceneException& e) { + finally = e; } - catch (std::bad_alloc& oom) + { - boost::throw_exception(handleOOM(oom, L"startCommit")); + SyncLock syncLock(this); + if (!setPending) { + deleter->decRef(toSync); + } } - BOOST_ASSERT(testPoint(L"finishStartCommit")); + finally.throwException(); + } catch (std::bad_alloc& oom) { + boost::throw_exception(handleOOM(oom, L"startCommit")); } + BOOST_ASSERT(testPoint(L"finishStartCommit")); +} - bool IndexWriter::isLocked(const DirectoryPtr& directory) - { - return directory->makeLock(WRITE_LOCK_NAME)->isLocked(); - } +bool IndexWriter::isLocked(const DirectoryPtr& directory) { + return directory->makeLock(WRITE_LOCK_NAME)->isLocked(); +} - void IndexWriter::unlock(const DirectoryPtr& directory) - { - directory->makeLock(IndexWriter::WRITE_LOCK_NAME)->release(); - } +void IndexWriter::unlock(const DirectoryPtr& directory) { + directory->makeLock(IndexWriter::WRITE_LOCK_NAME)->release(); +} - void IndexWriter::setMergedSegmentWarmer(const IndexReaderWarmerPtr& warmer) - { - mergedSegmentWarmer = warmer; - } +void IndexWriter::setMergedSegmentWarmer(const IndexReaderWarmerPtr& warmer) { + mergedSegmentWarmer = warmer; +} - IndexReaderWarmerPtr IndexWriter::getMergedSegmentWarmer() - { - return mergedSegmentWarmer; - } +IndexReaderWarmerPtr IndexWriter::getMergedSegmentWarmer() { + return mergedSegmentWarmer; +} - LuceneException IndexWriter::handleOOM(const std::bad_alloc& oom, const String& location) - { - if (infoStream) - message(L"hit OutOfMemoryError inside " + location); - hitOOM = true; - return OutOfMemoryError(); +LuceneException IndexWriter::handleOOM(const std::bad_alloc& oom, const String& location) { + if (infoStream) { + message(L"hit OutOfMemoryError inside " + location); } + hitOOM = true; + return OutOfMemoryError(); +} - bool IndexWriter::testPoint(const String& name) - { - return true; - } +bool IndexWriter::testPoint(const String& name) { + return true; +} - bool IndexWriter::nrtIsCurrent(const SegmentInfosPtr& infos) - { - SyncLock syncLock(this); - if (!infos->equals(segmentInfos)) - { - // if any structural changes (new segments), we are stale - return false; - } - else if (infos->getGeneration() != segmentInfos->getGeneration()) - { - // if any commit took place since we were opened, we are stale - return false; - } - else - return !docWriter->anyChanges(); +bool IndexWriter::nrtIsCurrent(const SegmentInfosPtr& infos) { + SyncLock syncLock(this); + if (!infos->equals(segmentInfos)) { + // if any structural changes (new segments), we are stale + return false; + } else if (infos->getGeneration() != segmentInfos->getGeneration()) { + // if any commit took place since we were opened, we are stale + return false; + } else { + return !docWriter->anyChanges(); } +} - bool IndexWriter::isClosed() - { - SyncLock syncLock(this); - return closed; - } +bool IndexWriter::isClosed() { + SyncLock syncLock(this); + return closed; +} - ReaderPool::ReaderPool(const IndexWriterPtr& writer) - { - readerMap = MapSegmentInfoSegmentReader::newInstance(); - _indexWriter = writer; - } +ReaderPool::ReaderPool(const IndexWriterPtr& writer) { + readerMap = MapSegmentInfoSegmentReader::newInstance(); + _indexWriter = writer; +} - ReaderPool::~ReaderPool() - { - } +ReaderPool::~ReaderPool() { +} - void ReaderPool::clear(const SegmentInfosPtr& infos) - { - SyncLock syncLock(this); - if (!infos) - { - for (MapSegmentInfoSegmentReader::iterator ent = readerMap.begin(); ent != readerMap.end(); ++ent) - ent->second->_hasChanges = false; +void ReaderPool::clear(const SegmentInfosPtr& infos) { + SyncLock syncLock(this); + if (!infos) { + for (MapSegmentInfoSegmentReader::iterator ent = readerMap.begin(); ent != readerMap.end(); ++ent) { + ent->second->_hasChanges = false; } - else - { - for (int32_t i = 0; i < infos->size(); ++i) - { - MapSegmentInfoSegmentReader::iterator ent = readerMap.find(infos->info(i)); - if (ent != readerMap.end()) - ent->second->_hasChanges = false; + } else { + for (int32_t i = 0; i < infos->size(); ++i) { + MapSegmentInfoSegmentReader::iterator ent = readerMap.find(infos->info(i)); + if (ent != readerMap.end()) { + ent->second->_hasChanges = false; } } } +} - bool ReaderPool::infoIsLive(const SegmentInfoPtr& info) - { - SyncLock syncLock(this); - IndexWriterPtr indexWriter(_indexWriter); - int32_t idx = indexWriter->segmentInfos->find(info); - BOOST_ASSERT(idx != -1); - BOOST_ASSERT(indexWriter->segmentInfos->info(idx) == info); - return true; - } +bool ReaderPool::infoIsLive(const SegmentInfoPtr& info) { + SyncLock syncLock(this); + IndexWriterPtr indexWriter(_indexWriter); + int32_t idx = indexWriter->segmentInfos->find(info); + BOOST_ASSERT(idx != -1); + BOOST_ASSERT(indexWriter->segmentInfos->info(idx) == info); + return true; +} - SegmentInfoPtr ReaderPool::mapToLive(const SegmentInfoPtr& info) - { - SyncLock syncLock(this); - IndexWriterPtr indexWriter(_indexWriter); - int32_t idx = indexWriter->segmentInfos->find(info); - SegmentInfoPtr _info(info); - if (idx != -1) - _info = indexWriter->segmentInfos->info(idx); - return _info; +SegmentInfoPtr ReaderPool::mapToLive(const SegmentInfoPtr& info) { + SyncLock syncLock(this); + IndexWriterPtr indexWriter(_indexWriter); + int32_t idx = indexWriter->segmentInfos->find(info); + SegmentInfoPtr _info(info); + if (idx != -1) { + _info = indexWriter->segmentInfos->info(idx); } + return _info; +} - void ReaderPool::release(const SegmentReaderPtr& sr) - { - release(sr, false); - } +void ReaderPool::release(const SegmentReaderPtr& sr) { + release(sr, false); +} - void ReaderPool::release(const SegmentReaderPtr& sr, bool drop) - { - SyncLock syncLock(this); - IndexWriterPtr indexWriter(_indexWriter); +void ReaderPool::release(const SegmentReaderPtr& sr, bool drop) { + SyncLock syncLock(this); + IndexWriterPtr indexWriter(_indexWriter); - bool pooled = readerMap.contains(sr->getSegmentInfo()); + bool pooled = readerMap.contains(sr->getSegmentInfo()); - BOOST_ASSERT(!pooled || readerMap.get(sr->getSegmentInfo()) == sr); + BOOST_ASSERT(!pooled || readerMap.get(sr->getSegmentInfo()) == sr); - // Drop caller's ref; for an external reader (not pooled), this decRef will close it - sr->decRef(); + // Drop caller's ref; for an external reader (not pooled), this decRef will close it + sr->decRef(); - if (pooled && (drop || (!indexWriter->poolReaders && sr->getRefCount() == 1))) - { - // We invoke deleter.checkpoint below, so we must be sync'd on IW if there are changes - BOOST_ASSERT(!sr->_hasChanges || holdsLock()); + if (pooled && (drop || (!indexWriter->poolReaders && sr->getRefCount() == 1))) { + // We invoke deleter.checkpoint below, so we must be sync'd on IW if there are changes + BOOST_ASSERT(!sr->_hasChanges || holdsLock()); - // Discard (don't save) changes when we are dropping the reader; this is used only on the - // sub-readers after a successful merge. - sr->_hasChanges = sr->_hasChanges && !drop; + // Discard (don't save) changes when we are dropping the reader; this is used only on the + // sub-readers after a successful merge. + sr->_hasChanges = sr->_hasChanges && !drop; - bool hasChanges = sr->_hasChanges; + bool hasChanges = sr->_hasChanges; - // Drop our ref - this will commit any pending changes to the dir - sr->close(); + // Drop our ref - this will commit any pending changes to the dir + sr->close(); - // We are the last ref to this reader; since we're not pooling readers, we release it - readerMap.remove(sr->getSegmentInfo()); + // We are the last ref to this reader; since we're not pooling readers, we release it + readerMap.remove(sr->getSegmentInfo()); - if (hasChanges) - { - // Must checkpoint with deleter, because this segment reader will have created new - // _X_N.del file. - indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); - } + if (hasChanges) { + // Must checkpoint with deleter, because this segment reader will have created new + // _X_N.del file. + indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); } } +} - void ReaderPool::close() - { - SyncLock syncLock(this); - IndexWriterPtr indexWriter(_indexWriter); - - // We invoke deleter.checkpoint below, so we must be sync'd on IW - BOOST_ASSERT(holdsLock()); +void ReaderPool::close() { + SyncLock syncLock(this); + IndexWriterPtr indexWriter(_indexWriter); - for (MapSegmentInfoSegmentReader::iterator iter = readerMap.begin(); iter != readerMap.end(); ++iter) - { - if (iter->second->_hasChanges) - { - BOOST_ASSERT(infoIsLive(iter->second->getSegmentInfo())); - iter->second->doCommit(MapStringString()); + // We invoke deleter.checkpoint below, so we must be sync'd on IW + BOOST_ASSERT(holdsLock()); - // Must checkpoint with deleter, because this segment reader will have created - // new _X_N.del file. - indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); - } + for (MapSegmentInfoSegmentReader::iterator iter = readerMap.begin(); iter != readerMap.end(); ++iter) { + if (iter->second->_hasChanges) { + BOOST_ASSERT(infoIsLive(iter->second->getSegmentInfo())); + iter->second->doCommit(MapStringString()); - // NOTE: it is allowed that this decRef does not actually close the SR; this can happen when a - // near real-time reader is kept open after the IndexWriter instance is closed - iter->second->decRef(); + // Must checkpoint with deleter, because this segment reader will have created + // new _X_N.del file. + indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); } - readerMap.clear(); + + // NOTE: it is allowed that this decRef does not actually close the SR; this can happen when a + // near real-time reader is kept open after the IndexWriter instance is closed + iter->second->decRef(); } + readerMap.clear(); +} - void ReaderPool::commit() - { - SyncLock syncLock(this); - IndexWriterPtr indexWriter(_indexWriter); +void ReaderPool::commit() { + SyncLock syncLock(this); + IndexWriterPtr indexWriter(_indexWriter); - // We invoke deleter.checkpoint below, so we must be sync'd on IW - BOOST_ASSERT(holdsLock()); + // We invoke deleter.checkpoint below, so we must be sync'd on IW + BOOST_ASSERT(holdsLock()); - for (MapSegmentInfoSegmentReader::iterator ent = readerMap.begin(); ent != readerMap.end(); ++ent) - { - if (ent->second->_hasChanges) - { - BOOST_ASSERT(infoIsLive(ent->second->getSegmentInfo())); - ent->second->doCommit(MapStringString()); + for (MapSegmentInfoSegmentReader::iterator ent = readerMap.begin(); ent != readerMap.end(); ++ent) { + if (ent->second->_hasChanges) { + BOOST_ASSERT(infoIsLive(ent->second->getSegmentInfo())); + ent->second->doCommit(MapStringString()); - // Must checkpoint with deleter, because this segment reader will have created - // new _X_N.del file. - indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); - } + // Must checkpoint with deleter, because this segment reader will have created + // new _X_N.del file. + indexWriter->deleter->checkpoint(indexWriter->segmentInfos, false); } } +} - IndexReaderPtr ReaderPool::getReadOnlyClone(const SegmentInfoPtr& info, bool doOpenStores, int32_t termInfosIndexDivisor) - { - SyncLock syncLock(this); - SegmentReaderPtr sr(get(info, doOpenStores, BufferedIndexInput::BUFFER_SIZE, termInfosIndexDivisor)); - IndexReaderPtr clone; - LuceneException finally; - try - { - clone = boost::dynamic_pointer_cast(sr->clone(true)); - } - catch (LuceneException& e) - { - finally = e; - } - sr->decRef(); - finally.throwException(); - return clone; - } +IndexReaderPtr ReaderPool::getReadOnlyClone(const SegmentInfoPtr& info, bool doOpenStores, int32_t termInfosIndexDivisor) { + SyncLock syncLock(this); + SegmentReaderPtr sr(get(info, doOpenStores, BufferedIndexInput::BUFFER_SIZE, termInfosIndexDivisor)); + IndexReaderPtr clone; + LuceneException finally; + try { + clone = boost::dynamic_pointer_cast(sr->clone(true)); + } catch (LuceneException& e) { + finally = e; + } + sr->decRef(); + finally.throwException(); + return clone; +} - SegmentReaderPtr ReaderPool::get(const SegmentInfoPtr& info, bool doOpenStores) - { - return get(info, doOpenStores, BufferedIndexInput::BUFFER_SIZE, IndexWriterPtr(_indexWriter)->readerTermsIndexDivisor); - } +SegmentReaderPtr ReaderPool::get(const SegmentInfoPtr& info, bool doOpenStores) { + return get(info, doOpenStores, BufferedIndexInput::BUFFER_SIZE, IndexWriterPtr(_indexWriter)->readerTermsIndexDivisor); +} - SegmentReaderPtr ReaderPool::get(const SegmentInfoPtr& info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor) - { - SyncLock syncLock(this); - IndexWriterPtr indexWriter(_indexWriter); - if (indexWriter->poolReaders) - readBufferSize = BufferedIndexInput::BUFFER_SIZE; +SegmentReaderPtr ReaderPool::get(const SegmentInfoPtr& info, bool doOpenStores, int32_t readBufferSize, int32_t termsIndexDivisor) { + SyncLock syncLock(this); + IndexWriterPtr indexWriter(_indexWriter); + if (indexWriter->poolReaders) { + readBufferSize = BufferedIndexInput::BUFFER_SIZE; + } - SegmentReaderPtr sr(readerMap.get(info)); - if (!sr) - { - // Returns a ref, which we xfer to readerMap - sr = SegmentReader::get(false, info->dir, info, readBufferSize, doOpenStores, termsIndexDivisor); - if (info->dir == indexWriter->directory) - { - // Only pool if reader is not external - readerMap.put(info, sr); - } + SegmentReaderPtr sr(readerMap.get(info)); + if (!sr) { + // Returns a ref, which we xfer to readerMap + sr = SegmentReader::get(false, info->dir, info, readBufferSize, doOpenStores, termsIndexDivisor); + if (info->dir == indexWriter->directory) { + // Only pool if reader is not external + readerMap.put(info, sr); } - else - { - if (doOpenStores) - sr->openDocStores(); - if (termsIndexDivisor != -1 && !sr->termsIndexLoaded()) - { - // If this reader was originally opened because we needed to merge it, we didn't load the terms - // index. But now, if the caller wants the terms index (eg because it's doing deletes, or an NRT - // reader is being opened) we ask the reader to load its terms index. - sr->loadTermsIndex(termsIndexDivisor); - } + } else { + if (doOpenStores) { + sr->openDocStores(); } - - // Return a ref to our caller - if (info->dir == indexWriter->directory) - { - // Only incRef if we pooled (reader is not external) - sr->incRef(); + if (termsIndexDivisor != -1 && !sr->termsIndexLoaded()) { + // If this reader was originally opened because we needed to merge it, we didn't load the terms + // index. But now, if the caller wants the terms index (eg because it's doing deletes, or an NRT + // reader is being opened) we ask the reader to load its terms index. + sr->loadTermsIndex(termsIndexDivisor); } - return sr; } - SegmentReaderPtr ReaderPool::getIfExists(const SegmentInfoPtr& info) - { - SyncLock syncLock(this); - SegmentReaderPtr sr(readerMap.get(info)); - if (sr) - sr->incRef(); - return sr; + // Return a ref to our caller + if (info->dir == indexWriter->directory) { + // Only incRef if we pooled (reader is not external) + sr->incRef(); } + return sr; +} - IndexReaderWarmer::~IndexReaderWarmer() - { +SegmentReaderPtr ReaderPool::getIfExists(const SegmentInfoPtr& info) { + SyncLock syncLock(this); + SegmentReaderPtr sr(readerMap.get(info)); + if (sr) { + sr->incRef(); } + return sr; +} + +IndexReaderWarmer::~IndexReaderWarmer() { +} + } diff --git a/src/core/index/IntBlockPool.cpp b/src/core/index/IntBlockPool.cpp index c43e17d3..898c56f1 100644 --- a/src/core/index/IntBlockPool.cpp +++ b/src/core/index/IntBlockPool.cpp @@ -8,49 +8,45 @@ #include "IntBlockPool.h" #include "DocumentsWriter.h" -namespace Lucene -{ - IntBlockPool::IntBlockPool(const DocumentsWriterPtr& docWriter, bool trackAllocations) - { - this->buffers = Collection::newInstance(10); - this->bufferUpto = -1; - this->intUpto = DocumentsWriter::INT_BLOCK_SIZE; - this->intOffset = -DocumentsWriter::INT_BLOCK_SIZE; - this->_docWriter = docWriter; - this->trackAllocations = trackAllocations; - } +namespace Lucene { - IntBlockPool::~IntBlockPool() - { - } +IntBlockPool::IntBlockPool(const DocumentsWriterPtr& docWriter, bool trackAllocations) { + this->buffers = Collection::newInstance(10); + this->bufferUpto = -1; + this->intUpto = DocumentsWriter::INT_BLOCK_SIZE; + this->intOffset = -DocumentsWriter::INT_BLOCK_SIZE; + this->_docWriter = docWriter; + this->trackAllocations = trackAllocations; +} - void IntBlockPool::reset() - { - if (bufferUpto != -1) - { - if (bufferUpto > 0) - { - // Recycle all but the first buffer - DocumentsWriterPtr(_docWriter)->recycleIntBlocks(buffers, 1, 1 + bufferUpto); - } - - // Reuse first buffer - bufferUpto = 0; - intUpto = 0; - intOffset = 0; - buffer = buffers[0]; - } - } +IntBlockPool::~IntBlockPool() { +} - void IntBlockPool::nextBuffer() - { - if (bufferUpto + 1 == buffers.size()) - buffers.resize((int32_t)((double)buffers.size() * 1.5)); - buffer = DocumentsWriterPtr(_docWriter)->getIntBlock(trackAllocations); - buffers[1 + bufferUpto] = buffer; - ++bufferUpto; +void IntBlockPool::reset() { + if (bufferUpto != -1) { + if (bufferUpto > 0) { + // Recycle all but the first buffer + DocumentsWriterPtr(_docWriter)->recycleIntBlocks(buffers, 1, 1 + bufferUpto); + } + // Reuse first buffer + bufferUpto = 0; intUpto = 0; - intOffset += DocumentsWriter::INT_BLOCK_SIZE; + intOffset = 0; + buffer = buffers[0]; } } + +void IntBlockPool::nextBuffer() { + if (bufferUpto + 1 == buffers.size()) { + buffers.resize((int32_t)((double)buffers.size() * 1.5)); + } + buffer = DocumentsWriterPtr(_docWriter)->getIntBlock(trackAllocations); + buffers[1 + bufferUpto] = buffer; + ++bufferUpto; + + intUpto = 0; + intOffset += DocumentsWriter::INT_BLOCK_SIZE; +} + +} diff --git a/src/core/index/InvertedDocConsumer.cpp b/src/core/index/InvertedDocConsumer.cpp index 9ab0b33d..4dbb102b 100644 --- a/src/core/index/InvertedDocConsumer.cpp +++ b/src/core/index/InvertedDocConsumer.cpp @@ -7,14 +7,13 @@ #include "LuceneInc.h" #include "InvertedDocConsumer.h" -namespace Lucene -{ - InvertedDocConsumer::~InvertedDocConsumer() - { - } +namespace Lucene { + +InvertedDocConsumer::~InvertedDocConsumer() { +} + +void InvertedDocConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) { + this->fieldInfos = fieldInfos; +} - void InvertedDocConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) - { - this->fieldInfos = fieldInfos; - } } diff --git a/src/core/index/InvertedDocConsumerPerField.cpp b/src/core/index/InvertedDocConsumerPerField.cpp index e3aaea5e..501eb8b8 100644 --- a/src/core/index/InvertedDocConsumerPerField.cpp +++ b/src/core/index/InvertedDocConsumerPerField.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "InvertedDocConsumerPerField.h" -namespace Lucene -{ - InvertedDocConsumerPerField::~InvertedDocConsumerPerField() - { - } +namespace Lucene { + +InvertedDocConsumerPerField::~InvertedDocConsumerPerField() { +} + } diff --git a/src/core/index/InvertedDocConsumerPerThread.cpp b/src/core/index/InvertedDocConsumerPerThread.cpp index 636cda1f..50db8771 100644 --- a/src/core/index/InvertedDocConsumerPerThread.cpp +++ b/src/core/index/InvertedDocConsumerPerThread.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "InvertedDocConsumerPerThread.h" -namespace Lucene -{ - InvertedDocConsumerPerThread::~InvertedDocConsumerPerThread() - { - } +namespace Lucene { + +InvertedDocConsumerPerThread::~InvertedDocConsumerPerThread() { +} + } diff --git a/src/core/index/InvertedDocEndConsumer.cpp b/src/core/index/InvertedDocEndConsumer.cpp index 6df08e41..e921e4c8 100644 --- a/src/core/index/InvertedDocEndConsumer.cpp +++ b/src/core/index/InvertedDocEndConsumer.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "InvertedDocEndConsumer.h" -namespace Lucene -{ - InvertedDocEndConsumer::~InvertedDocEndConsumer() - { - } +namespace Lucene { + +InvertedDocEndConsumer::~InvertedDocEndConsumer() { +} + } diff --git a/src/core/index/InvertedDocEndConsumerPerField.cpp b/src/core/index/InvertedDocEndConsumerPerField.cpp index dc3f5c3a..a3e785a0 100644 --- a/src/core/index/InvertedDocEndConsumerPerField.cpp +++ b/src/core/index/InvertedDocEndConsumerPerField.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "InvertedDocEndConsumerPerField.h" -namespace Lucene -{ - InvertedDocEndConsumerPerField::~InvertedDocEndConsumerPerField() - { - } +namespace Lucene { + +InvertedDocEndConsumerPerField::~InvertedDocEndConsumerPerField() { +} + } diff --git a/src/core/index/InvertedDocEndConsumerPerThread.cpp b/src/core/index/InvertedDocEndConsumerPerThread.cpp index b1cabe40..5deb4103 100644 --- a/src/core/index/InvertedDocEndConsumerPerThread.cpp +++ b/src/core/index/InvertedDocEndConsumerPerThread.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "InvertedDocEndConsumerPerThread.h" -namespace Lucene -{ - InvertedDocEndConsumerPerThread::~InvertedDocEndConsumerPerThread() - { - } +namespace Lucene { + +InvertedDocEndConsumerPerThread::~InvertedDocEndConsumerPerThread() { +} + } diff --git a/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp b/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp index 19399047..8d1ca782 100644 --- a/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp +++ b/src/core/index/KeepOnlyLastCommitDeletionPolicy.cpp @@ -8,23 +8,22 @@ #include "KeepOnlyLastCommitDeletionPolicy.h" #include "IndexCommit.h" -namespace Lucene -{ - KeepOnlyLastCommitDeletionPolicy::~KeepOnlyLastCommitDeletionPolicy() - { - } +namespace Lucene { - void KeepOnlyLastCommitDeletionPolicy::onInit(Collection commits) - { - // Note that commits.size() should normally be 1 - onCommit(commits); - } +KeepOnlyLastCommitDeletionPolicy::~KeepOnlyLastCommitDeletionPolicy() { +} - void KeepOnlyLastCommitDeletionPolicy::onCommit(Collection commits) - { - // Note that commits.size() should normally be 2 (if not called by onInit above) - int32_t size = commits.size(); - for (int32_t i = 0; i < size - 1; ++i) - commits[i]->deleteCommit(); +void KeepOnlyLastCommitDeletionPolicy::onInit(Collection commits) { + // Note that commits.size() should normally be 1 + onCommit(commits); +} + +void KeepOnlyLastCommitDeletionPolicy::onCommit(Collection commits) { + // Note that commits.size() should normally be 2 (if not called by onInit above) + int32_t size = commits.size(); + for (int32_t i = 0; i < size - 1; ++i) { + commits[i]->deleteCommit(); } } + +} diff --git a/src/core/index/LogByteSizeMergePolicy.cpp b/src/core/index/LogByteSizeMergePolicy.cpp index 75aa4e47..8127f80e 100644 --- a/src/core/index/LogByteSizeMergePolicy.cpp +++ b/src/core/index/LogByteSizeMergePolicy.cpp @@ -8,46 +8,40 @@ #include #include "LogByteSizeMergePolicy.h" -namespace Lucene -{ - /// Default minimum segment size. - const double LogByteSizeMergePolicy::DEFAULT_MIN_MERGE_MB = 1.6; - - /// Default maximum segment size. A segment of this size or larger will never be merged. - const double LogByteSizeMergePolicy::DEFAULT_MAX_MERGE_MB = DBL_MAX; - - LogByteSizeMergePolicy::LogByteSizeMergePolicy(const IndexWriterPtr& writer) : LogMergePolicy(writer) - { - minMergeSize = (int64_t)(DEFAULT_MIN_MERGE_MB * 1024 * 1024); - maxMergeSize = DEFAULT_MAX_MERGE_MB == DBL_MAX ? std::numeric_limits::max() : (int64_t)(DEFAULT_MAX_MERGE_MB * 1024 * 1024); - } - - LogByteSizeMergePolicy::~LogByteSizeMergePolicy() - { - } - - int64_t LogByteSizeMergePolicy::size(const SegmentInfoPtr& info) - { - return sizeBytes(info); - } - - void LogByteSizeMergePolicy::setMaxMergeMB(double mb) - { - maxMergeSize = (int64_t)(mb * 1024 * 1024); - } - - double LogByteSizeMergePolicy::getMaxMergeMB() - { - return ((double)maxMergeSize) / 1024 / 1024; - } - - void LogByteSizeMergePolicy::setMinMergeMB(double mb) - { - minMergeSize = (int64_t)(mb * 1024 * 1024); - } - - double LogByteSizeMergePolicy::getMinMergeMB() - { - return ((double)minMergeSize) / 1024 / 1024; - } +namespace Lucene { + +/// Default minimum segment size. +const double LogByteSizeMergePolicy::DEFAULT_MIN_MERGE_MB = 1.6; + +/// Default maximum segment size. A segment of this size or larger will never be merged. +const double LogByteSizeMergePolicy::DEFAULT_MAX_MERGE_MB = DBL_MAX; + +LogByteSizeMergePolicy::LogByteSizeMergePolicy(const IndexWriterPtr& writer) : LogMergePolicy(writer) { + minMergeSize = (int64_t)(DEFAULT_MIN_MERGE_MB * 1024 * 1024); + maxMergeSize = DEFAULT_MAX_MERGE_MB == DBL_MAX ? std::numeric_limits::max() : (int64_t)(DEFAULT_MAX_MERGE_MB * 1024 * 1024); +} + +LogByteSizeMergePolicy::~LogByteSizeMergePolicy() { +} + +int64_t LogByteSizeMergePolicy::size(const SegmentInfoPtr& info) { + return sizeBytes(info); +} + +void LogByteSizeMergePolicy::setMaxMergeMB(double mb) { + maxMergeSize = (int64_t)(mb * 1024 * 1024); +} + +double LogByteSizeMergePolicy::getMaxMergeMB() { + return ((double)maxMergeSize) / 1024 / 1024; +} + +void LogByteSizeMergePolicy::setMinMergeMB(double mb) { + minMergeSize = (int64_t)(mb * 1024 * 1024); +} + +double LogByteSizeMergePolicy::getMinMergeMB() { + return ((double)minMergeSize) / 1024 / 1024; +} + } diff --git a/src/core/index/LogDocMergePolicy.cpp b/src/core/index/LogDocMergePolicy.cpp index 375d789f..309da70a 100644 --- a/src/core/index/LogDocMergePolicy.cpp +++ b/src/core/index/LogDocMergePolicy.cpp @@ -7,35 +7,31 @@ #include "LuceneInc.h" #include "LogDocMergePolicy.h" -namespace Lucene -{ - /// Default minimum segment size. @see setMinMergeDocs - const int32_t LogDocMergePolicy::DEFAULT_MIN_MERGE_DOCS = 1000; - - LogDocMergePolicy::LogDocMergePolicy(const IndexWriterPtr& writer) : LogMergePolicy(writer) - { - minMergeSize = DEFAULT_MIN_MERGE_DOCS; - - // maxMergeSize is never used by LogDocMergePolicy; set it to LLONG_MAX to disable it - maxMergeSize = std::numeric_limits::max(); - } - - LogDocMergePolicy::~LogDocMergePolicy() - { - } - - int64_t LogDocMergePolicy::size(const SegmentInfoPtr& info) - { - return sizeDocs(info); - } - - void LogDocMergePolicy::setMinMergeDocs(int32_t minMergeDocs) - { - minMergeSize = minMergeDocs; - } - - int32_t LogDocMergePolicy::getMinMergeDocs() - { - return (int32_t)minMergeSize; - } +namespace Lucene { + +/// Default minimum segment size. @see setMinMergeDocs +const int32_t LogDocMergePolicy::DEFAULT_MIN_MERGE_DOCS = 1000; + +LogDocMergePolicy::LogDocMergePolicy(const IndexWriterPtr& writer) : LogMergePolicy(writer) { + minMergeSize = DEFAULT_MIN_MERGE_DOCS; + + // maxMergeSize is never used by LogDocMergePolicy; set it to LLONG_MAX to disable it + maxMergeSize = std::numeric_limits::max(); +} + +LogDocMergePolicy::~LogDocMergePolicy() { +} + +int64_t LogDocMergePolicy::size(const SegmentInfoPtr& info) { + return sizeDocs(info); +} + +void LogDocMergePolicy::setMinMergeDocs(int32_t minMergeDocs) { + minMergeSize = minMergeDocs; +} + +int32_t LogDocMergePolicy::getMinMergeDocs() { + return (int32_t)minMergeSize; +} + } diff --git a/src/core/index/LogMergePolicy.cpp b/src/core/index/LogMergePolicy.cpp index 7e14782a..ed835b43 100644 --- a/src/core/index/LogMergePolicy.cpp +++ b/src/core/index/LogMergePolicy.cpp @@ -10,414 +10,365 @@ #include "SegmentInfo.h" #include "StringUtils.h" -namespace Lucene -{ - /// Defines the allowed range of log(size) for each level. A level is computed by taking the max segment - /// log size, minus LEVEL_LOG_SPAN, and finding all segments falling within that range. - const double LogMergePolicy::LEVEL_LOG_SPAN = 0.75; - - /// Default merge factor, which is how many segments are merged at a time. - const int32_t LogMergePolicy::DEFAULT_MERGE_FACTOR = 10; - - /// Default maximum segment size. A segment of this size or larger will never be merged. - const int32_t LogMergePolicy::DEFAULT_MAX_MERGE_DOCS = INT_MAX; - - /// Default noCFSRatio. If a merge's size is >= 10% of the index, then we disable compound file for it. - const double LogMergePolicy::DEFAULT_NO_CFS_RATIO = 0.1; - - LogMergePolicy::LogMergePolicy(const IndexWriterPtr& writer) : MergePolicy(writer) - { - mergeFactor = DEFAULT_MERGE_FACTOR; - noCFSRatio = DEFAULT_NO_CFS_RATIO; - minMergeSize = 0; - maxMergeSize = 0; - maxMergeDocs = DEFAULT_MAX_MERGE_DOCS; - calibrateSizeByDeletes = false; - _useCompoundFile = true; - _useCompoundDocStore = true; - } +namespace Lucene { + +/// Defines the allowed range of log(size) for each level. A level is computed by taking the max segment +/// log size, minus LEVEL_LOG_SPAN, and finding all segments falling within that range. +const double LogMergePolicy::LEVEL_LOG_SPAN = 0.75; + +/// Default merge factor, which is how many segments are merged at a time. +const int32_t LogMergePolicy::DEFAULT_MERGE_FACTOR = 10; + +/// Default maximum segment size. A segment of this size or larger will never be merged. +const int32_t LogMergePolicy::DEFAULT_MAX_MERGE_DOCS = INT_MAX; + +/// Default noCFSRatio. If a merge's size is >= 10% of the index, then we disable compound file for it. +const double LogMergePolicy::DEFAULT_NO_CFS_RATIO = 0.1; + +LogMergePolicy::LogMergePolicy(const IndexWriterPtr& writer) : MergePolicy(writer) { + mergeFactor = DEFAULT_MERGE_FACTOR; + noCFSRatio = DEFAULT_NO_CFS_RATIO; + minMergeSize = 0; + maxMergeSize = 0; + maxMergeDocs = DEFAULT_MAX_MERGE_DOCS; + calibrateSizeByDeletes = false; + _useCompoundFile = true; + _useCompoundDocStore = true; +} - LogMergePolicy::~LogMergePolicy() - { - } +LogMergePolicy::~LogMergePolicy() { +} - double LogMergePolicy::getNoCFSRatio() - { - return noCFSRatio; - } +double LogMergePolicy::getNoCFSRatio() { + return noCFSRatio; +} - void LogMergePolicy::setNoCFSRatio(double noCFSRatio) - { - if (noCFSRatio < 0.0 || noCFSRatio > 1.0) - boost::throw_exception(IllegalArgumentException(L"noCFSRatio must be 0.0 to 1.0 inclusive; got " + StringUtils::toString(noCFSRatio))); - this->noCFSRatio = noCFSRatio; +void LogMergePolicy::setNoCFSRatio(double noCFSRatio) { + if (noCFSRatio < 0.0 || noCFSRatio > 1.0) { + boost::throw_exception(IllegalArgumentException(L"noCFSRatio must be 0.0 to 1.0 inclusive; got " + StringUtils::toString(noCFSRatio))); } + this->noCFSRatio = noCFSRatio; +} - bool LogMergePolicy::verbose() - { - return (!_writer.expired() && IndexWriterPtr(_writer)->verbose()); - } +bool LogMergePolicy::verbose() { + return (!_writer.expired() && IndexWriterPtr(_writer)->verbose()); +} - void LogMergePolicy::message(const String& message) - { - if (verbose()) - IndexWriterPtr(_writer)->message(L"LMP: " + message); +void LogMergePolicy::message(const String& message) { + if (verbose()) { + IndexWriterPtr(_writer)->message(L"LMP: " + message); } +} - int32_t LogMergePolicy::getMergeFactor() - { - return mergeFactor; - } +int32_t LogMergePolicy::getMergeFactor() { + return mergeFactor; +} - void LogMergePolicy::setMergeFactor(int32_t mergeFactor) - { - if (mergeFactor < 2) - boost::throw_exception(IllegalArgumentException(L"mergeFactor cannot be less than 2")); - this->mergeFactor = mergeFactor; +void LogMergePolicy::setMergeFactor(int32_t mergeFactor) { + if (mergeFactor < 2) { + boost::throw_exception(IllegalArgumentException(L"mergeFactor cannot be less than 2")); } + this->mergeFactor = mergeFactor; +} - bool LogMergePolicy::getUseCompoundFile() - { - return _useCompoundFile; - } +bool LogMergePolicy::getUseCompoundFile() { + return _useCompoundFile; +} - void LogMergePolicy::setUseCompoundFile(bool useCompoundFile) - { - _useCompoundFile = useCompoundFile; - } +void LogMergePolicy::setUseCompoundFile(bool useCompoundFile) { + _useCompoundFile = useCompoundFile; +} - bool LogMergePolicy::useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment) - { - return _useCompoundFile; - } +bool LogMergePolicy::useCompoundFile(const SegmentInfosPtr& segments, const SegmentInfoPtr& newSegment) { + return _useCompoundFile; +} - bool LogMergePolicy::useCompoundDocStore(const SegmentInfosPtr& segments) - { - return _useCompoundDocStore; - } +bool LogMergePolicy::useCompoundDocStore(const SegmentInfosPtr& segments) { + return _useCompoundDocStore; +} - void LogMergePolicy::setUseCompoundDocStore(bool useCompoundDocStore) - { - _useCompoundDocStore = useCompoundDocStore; - } +void LogMergePolicy::setUseCompoundDocStore(bool useCompoundDocStore) { + _useCompoundDocStore = useCompoundDocStore; +} - bool LogMergePolicy::getUseCompoundDocStore() - { - return _useCompoundDocStore; - } +bool LogMergePolicy::getUseCompoundDocStore() { + return _useCompoundDocStore; +} - void LogMergePolicy::setCalibrateSizeByDeletes(bool calibrateSizeByDeletes) - { - this->calibrateSizeByDeletes = calibrateSizeByDeletes; - } +void LogMergePolicy::setCalibrateSizeByDeletes(bool calibrateSizeByDeletes) { + this->calibrateSizeByDeletes = calibrateSizeByDeletes; +} - bool LogMergePolicy::getCalibrateSizeByDeletes() - { - return calibrateSizeByDeletes; - } +bool LogMergePolicy::getCalibrateSizeByDeletes() { + return calibrateSizeByDeletes; +} - void LogMergePolicy::close() - { - } +void LogMergePolicy::close() { +} - int64_t LogMergePolicy::sizeDocs(const SegmentInfoPtr& info) - { - if (calibrateSizeByDeletes) - { - int32_t delCount = IndexWriterPtr(_writer)->numDeletedDocs(info); - return (info->docCount - (int64_t)delCount); - } - else - return info->docCount; +int64_t LogMergePolicy::sizeDocs(const SegmentInfoPtr& info) { + if (calibrateSizeByDeletes) { + int32_t delCount = IndexWriterPtr(_writer)->numDeletedDocs(info); + return (info->docCount - (int64_t)delCount); + } else { + return info->docCount; } +} - int64_t LogMergePolicy::sizeBytes(const SegmentInfoPtr& info) - { - int64_t byteSize = info->sizeInBytes(); - if (calibrateSizeByDeletes) - { - int32_t delCount = IndexWriterPtr(_writer)->numDeletedDocs(info); - double delRatio = info->docCount <= 0 ? 0.0 : ((double)delCount / (double)info->docCount); - return info->docCount <= 0 ? byteSize : (int64_t)(byteSize * (1.0 - delRatio)); - } - else - return byteSize; +int64_t LogMergePolicy::sizeBytes(const SegmentInfoPtr& info) { + int64_t byteSize = info->sizeInBytes(); + if (calibrateSizeByDeletes) { + int32_t delCount = IndexWriterPtr(_writer)->numDeletedDocs(info); + double delRatio = info->docCount <= 0 ? 0.0 : ((double)delCount / (double)info->docCount); + return info->docCount <= 0 ? byteSize : (int64_t)(byteSize * (1.0 - delRatio)); + } else { + return byteSize; } +} - bool LogMergePolicy::isOptimized(const SegmentInfosPtr& infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize) - { - int32_t numSegments = infos->size(); - int32_t numToOptimize = 0; - SegmentInfoPtr optimizeInfo; - for (int32_t i = 0; i < numSegments && numToOptimize <= maxNumSegments; ++i) - { - SegmentInfoPtr info(infos->info(i)); - if (segmentsToOptimize.contains(info)) - { - ++numToOptimize; - optimizeInfo = info; - } +bool LogMergePolicy::isOptimized(const SegmentInfosPtr& infos, int32_t maxNumSegments, SetSegmentInfo segmentsToOptimize) { + int32_t numSegments = infos->size(); + int32_t numToOptimize = 0; + SegmentInfoPtr optimizeInfo; + for (int32_t i = 0; i < numSegments && numToOptimize <= maxNumSegments; ++i) { + SegmentInfoPtr info(infos->info(i)); + if (segmentsToOptimize.contains(info)) { + ++numToOptimize; + optimizeInfo = info; } - return (numToOptimize <= maxNumSegments && (numToOptimize != 1 || isOptimized(optimizeInfo))); } + return (numToOptimize <= maxNumSegments && (numToOptimize != 1 || isOptimized(optimizeInfo))); +} - bool LogMergePolicy::isOptimized(const SegmentInfoPtr& info) - { - IndexWriterPtr writer(_writer); - bool hasDeletions = (writer->numDeletedDocs(info) > 0); - return (!hasDeletions && !info->hasSeparateNorms() && info->dir == writer->getDirectory() && (info->getUseCompoundFile() == _useCompoundFile || noCFSRatio < 1.0)); - } +bool LogMergePolicy::isOptimized(const SegmentInfoPtr& info) { + IndexWriterPtr writer(_writer); + bool hasDeletions = (writer->numDeletedDocs(info) > 0); + return (!hasDeletions && !info->hasSeparateNorms() && info->dir == writer->getDirectory() && (info->getUseCompoundFile() == _useCompoundFile || noCFSRatio < 1.0)); +} - MergeSpecificationPtr LogMergePolicy::findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) - { - MergeSpecificationPtr spec; - - BOOST_ASSERT(maxSegmentCount > 0); - - if (!isOptimized(segmentInfos, maxSegmentCount, segmentsToOptimize)) - { - // Find the newest (rightmost) segment that needs to be optimized (other segments may have been - // flushed since optimize started) - int32_t last = segmentInfos->size(); - while (last > 0) - { - if (segmentsToOptimize.contains(segmentInfos->info(--last))) - { - ++last; - break; - } +MergeSpecificationPtr LogMergePolicy::findMergesForOptimize(const SegmentInfosPtr& segmentInfos, int32_t maxSegmentCount, SetSegmentInfo segmentsToOptimize) { + MergeSpecificationPtr spec; + + BOOST_ASSERT(maxSegmentCount > 0); + + if (!isOptimized(segmentInfos, maxSegmentCount, segmentsToOptimize)) { + // Find the newest (rightmost) segment that needs to be optimized (other segments may have been + // flushed since optimize started) + int32_t last = segmentInfos->size(); + while (last > 0) { + if (segmentsToOptimize.contains(segmentInfos->info(--last))) { + ++last; + break; } + } - if (last > 0) - { - spec = newLucene(); + if (last > 0) { + spec = newLucene(); - // First, enroll all "full" merges (size mergeFactor) to potentially be run concurrently - while (last - maxSegmentCount + 1 >= mergeFactor) - { - spec->add(makeOneMerge(segmentInfos, segmentInfos->range(last - mergeFactor, last))); - last -= mergeFactor; - } + // First, enroll all "full" merges (size mergeFactor) to potentially be run concurrently + while (last - maxSegmentCount + 1 >= mergeFactor) { + spec->add(makeOneMerge(segmentInfos, segmentInfos->range(last - mergeFactor, last))); + last -= mergeFactor; + } - // Only if there are no full merges pending do we add a final partial (< mergeFactor segments) merge - if (spec->merges.empty()) - { - if (maxSegmentCount == 1) - { - // Since we must optimize down to 1 segment, the choice is simple - if (last > 1 || !isOptimized(segmentInfos->info(0))) - spec->add(makeOneMerge(segmentInfos, segmentInfos->range(0, last))); + // Only if there are no full merges pending do we add a final partial (< mergeFactor segments) merge + if (spec->merges.empty()) { + if (maxSegmentCount == 1) { + // Since we must optimize down to 1 segment, the choice is simple + if (last > 1 || !isOptimized(segmentInfos->info(0))) { + spec->add(makeOneMerge(segmentInfos, segmentInfos->range(0, last))); } - else if (last > maxSegmentCount) - { - // Take care to pick a partial merge that is least cost, but does not make the index too - // lopsided. If we always just picked the partial tail then we could produce a highly - // lopsided index over time - - // We must merge this many segments to leave maxNumSegments in the index (from when - // optimize was first kicked off) - int32_t finalMergeSize = last - maxSegmentCount + 1; - - // Consider all possible starting points - int64_t bestSize = 0; - int32_t bestStart = 0; - - for (int32_t i = 0; i < last - finalMergeSize + 1; ++i) - { - int64_t sumSize = 0; - for (int32_t j = 0; j < finalMergeSize; ++j) - sumSize += size(segmentInfos->info(j + i)); - if (i == 0 || (sumSize < 2 * size(segmentInfos->info(i - 1)) && sumSize < bestSize)) - { - bestStart = i; - bestSize = sumSize; - } + } else if (last > maxSegmentCount) { + // Take care to pick a partial merge that is least cost, but does not make the index too + // lopsided. If we always just picked the partial tail then we could produce a highly + // lopsided index over time + + // We must merge this many segments to leave maxNumSegments in the index (from when + // optimize was first kicked off) + int32_t finalMergeSize = last - maxSegmentCount + 1; + + // Consider all possible starting points + int64_t bestSize = 0; + int32_t bestStart = 0; + + for (int32_t i = 0; i < last - finalMergeSize + 1; ++i) { + int64_t sumSize = 0; + for (int32_t j = 0; j < finalMergeSize; ++j) { + sumSize += size(segmentInfos->info(j + i)); + } + if (i == 0 || (sumSize < 2 * size(segmentInfos->info(i - 1)) && sumSize < bestSize)) { + bestStart = i; + bestSize = sumSize; } - - spec->add(makeOneMerge(segmentInfos, segmentInfos->range(bestStart, bestStart + finalMergeSize))); } + + spec->add(makeOneMerge(segmentInfos, segmentInfos->range(bestStart, bestStart + finalMergeSize))); } } - else - spec.reset(); - } - else + } else { spec.reset(); - - return spec; + } + } else { + spec.reset(); } - MergeSpecificationPtr LogMergePolicy::findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos) - { - int32_t numSegments = segmentInfos->size(); - - message(L"findMergesToExpungeDeletes: " + StringUtils::toString(numSegments) + L" segments"); - - MergeSpecificationPtr spec(newLucene()); - int32_t firstSegmentWithDeletions = -1; - for (int32_t i = 0; i < numSegments; ++i) - { - SegmentInfoPtr info(segmentInfos->info(i)); - int32_t delCount = IndexWriterPtr(_writer)->numDeletedDocs(info); - if (delCount > 0) - { - message(L" segment " + info->name + L" has deletions"); - if (firstSegmentWithDeletions == -1) - firstSegmentWithDeletions = i; - else if (i - firstSegmentWithDeletions == mergeFactor) - { - // We've seen mergeFactor segments in a row with deletions, so force a merge now - message(L" add merge " + StringUtils::toString(firstSegmentWithDeletions) + L" to " + StringUtils::toString(i - 1) + L" inclusive"); - spec->add(makeOneMerge(segmentInfos, segmentInfos->range(firstSegmentWithDeletions, i))); - firstSegmentWithDeletions = i; - } - } - else if (firstSegmentWithDeletions != -1) - { - // End of a sequence of segments with deletions, so merge those past segments even if - // it's fewer than mergeFactor segments + return spec; +} + +MergeSpecificationPtr LogMergePolicy::findMergesToExpungeDeletes(const SegmentInfosPtr& segmentInfos) { + int32_t numSegments = segmentInfos->size(); + + message(L"findMergesToExpungeDeletes: " + StringUtils::toString(numSegments) + L" segments"); + + MergeSpecificationPtr spec(newLucene()); + int32_t firstSegmentWithDeletions = -1; + for (int32_t i = 0; i < numSegments; ++i) { + SegmentInfoPtr info(segmentInfos->info(i)); + int32_t delCount = IndexWriterPtr(_writer)->numDeletedDocs(info); + if (delCount > 0) { + message(L" segment " + info->name + L" has deletions"); + if (firstSegmentWithDeletions == -1) { + firstSegmentWithDeletions = i; + } else if (i - firstSegmentWithDeletions == mergeFactor) { + // We've seen mergeFactor segments in a row with deletions, so force a merge now message(L" add merge " + StringUtils::toString(firstSegmentWithDeletions) + L" to " + StringUtils::toString(i - 1) + L" inclusive"); spec->add(makeOneMerge(segmentInfos, segmentInfos->range(firstSegmentWithDeletions, i))); - firstSegmentWithDeletions = -1; + firstSegmentWithDeletions = i; } + } else if (firstSegmentWithDeletions != -1) { + // End of a sequence of segments with deletions, so merge those past segments even if + // it's fewer than mergeFactor segments + message(L" add merge " + StringUtils::toString(firstSegmentWithDeletions) + L" to " + StringUtils::toString(i - 1) + L" inclusive"); + spec->add(makeOneMerge(segmentInfos, segmentInfos->range(firstSegmentWithDeletions, i))); + firstSegmentWithDeletions = -1; } + } - if (firstSegmentWithDeletions != -1) - { - message(L" add merge " + StringUtils::toString(firstSegmentWithDeletions) + L" to " + StringUtils::toString(numSegments - 1) + L" inclusive"); - spec->add(makeOneMerge(segmentInfos, segmentInfos->range(firstSegmentWithDeletions, numSegments))); - } + if (firstSegmentWithDeletions != -1) { + message(L" add merge " + StringUtils::toString(firstSegmentWithDeletions) + L" to " + StringUtils::toString(numSegments - 1) + L" inclusive"); + spec->add(makeOneMerge(segmentInfos, segmentInfos->range(firstSegmentWithDeletions, numSegments))); + } + + return spec; +} + +MergeSpecificationPtr LogMergePolicy::findMerges(const SegmentInfosPtr& segmentInfos) { + int32_t numSegments = segmentInfos->size(); + message(L"findMerges: " + StringUtils::toString(numSegments) + L" segments"); + + // Compute levels, which is just log (base mergeFactor) of the size of each segment + Collection levels(Collection::newInstance(numSegments)); + double norm = std::log((double)mergeFactor); - return spec; + for (int32_t i = 0; i < numSegments; ++i) { + SegmentInfoPtr info(segmentInfos->info(i)); + int64_t _size = size(info); + + // Floor tiny segments + _size = std::max(_size, (int64_t)1); + levels[i] = std::log((double)_size) / norm; } - MergeSpecificationPtr LogMergePolicy::findMerges(const SegmentInfosPtr& segmentInfos) - { - int32_t numSegments = segmentInfos->size(); - message(L"findMerges: " + StringUtils::toString(numSegments) + L" segments"); + double levelFloor = minMergeSize <= 0 ? 0 : (std::log((double)minMergeSize) / norm); - // Compute levels, which is just log (base mergeFactor) of the size of each segment - Collection levels(Collection::newInstance(numSegments)); - double norm = std::log((double)mergeFactor); + // Now, we quantize the log values into levels. The first level is any segment whose log + // size is within LEVEL_LOG_SPAN of the max size, or, who has such as segment "to the right". + // Then, we find the max of all other segments and use that to define the next level segment, etc. - for (int32_t i = 0; i < numSegments; ++i) - { - SegmentInfoPtr info(segmentInfos->info(i)); - int64_t _size = size(info); + MergeSpecificationPtr spec; - // Floor tiny segments - _size = std::max(_size, (int64_t)1); - levels[i] = std::log((double)_size) / norm; + int32_t start = 0; + while (start < numSegments) { + // Find max level of all segments not already quantized + double maxLevel = levels[start]; + for (int32_t i = 1 + start; i < numSegments; ++i) { + maxLevel = std::max(maxLevel, levels[i]); } - double levelFloor = minMergeSize <= 0 ? 0 : (std::log((double)minMergeSize) / norm); - - // Now, we quantize the log values into levels. The first level is any segment whose log - // size is within LEVEL_LOG_SPAN of the max size, or, who has such as segment "to the right". - // Then, we find the max of all other segments and use that to define the next level segment, etc. - - MergeSpecificationPtr spec; - - int32_t start = 0; - while (start < numSegments) - { - // Find max level of all segments not already quantized - double maxLevel = levels[start]; - for (int32_t i = 1 + start; i < numSegments; ++i) - maxLevel = std::max(maxLevel, levels[i]); - - // Now search backwards for the rightmost segment that falls into this level - double levelBottom; - if (maxLevel < levelFloor) - levelBottom = -1.0; - else - { - levelBottom = (double)(maxLevel - LEVEL_LOG_SPAN); - - // Force a boundary at the level floor - if (levelBottom < levelFloor && maxLevel >= levelFloor) - levelBottom = levelFloor; + // Now search backwards for the rightmost segment that falls into this level + double levelBottom; + if (maxLevel < levelFloor) { + levelBottom = -1.0; + } else { + levelBottom = (double)(maxLevel - LEVEL_LOG_SPAN); + + // Force a boundary at the level floor + if (levelBottom < levelFloor && maxLevel >= levelFloor) { + levelBottom = levelFloor; } + } - int32_t upto = numSegments - 1; - while (upto >= start) - { - if (levels[upto] >= levelBottom) - break; - --upto; + int32_t upto = numSegments - 1; + while (upto >= start) { + if (levels[upto] >= levelBottom) { + break; } - message(L" level " + StringUtils::toString(levelBottom) + L" to " + StringUtils::toString(maxLevel) + L": " + StringUtils::toString(1 + upto - start) + L" segments"); - - // Finally, record all merges that are viable at this level - int32_t end = start + mergeFactor; - while (end <= 1 + upto) - { - bool anyTooLarge = false; - for (int32_t i = start; i < end; ++i) - { - SegmentInfoPtr info(segmentInfos->info(i)); - if (size(info) >= maxMergeSize || sizeDocs(info) >= maxMergeDocs) - { - anyTooLarge = true; - break; - } + --upto; + } + message(L" level " + StringUtils::toString(levelBottom) + L" to " + StringUtils::toString(maxLevel) + L": " + StringUtils::toString(1 + upto - start) + L" segments"); + + // Finally, record all merges that are viable at this level + int32_t end = start + mergeFactor; + while (end <= 1 + upto) { + bool anyTooLarge = false; + for (int32_t i = start; i < end; ++i) { + SegmentInfoPtr info(segmentInfos->info(i)); + if (size(info) >= maxMergeSize || sizeDocs(info) >= maxMergeDocs) { + anyTooLarge = true; + break; } + } - if (!anyTooLarge) - { - if (!spec) - spec = newLucene(); - message(L" " + StringUtils::toString(start) + L" to " + StringUtils::toString(end) + L": add this merge"); - spec->add(makeOneMerge(segmentInfos, segmentInfos->range(start, end))); + if (!anyTooLarge) { + if (!spec) { + spec = newLucene(); } - else - message(L" " + StringUtils::toString(start) + L" to " + StringUtils::toString(end) + L": contains segment over maxMergeSize or maxMergeDocs; skipping"); - - start = end; - end = start + mergeFactor; + message(L" " + StringUtils::toString(start) + L" to " + StringUtils::toString(end) + L": add this merge"); + spec->add(makeOneMerge(segmentInfos, segmentInfos->range(start, end))); + } else { + message(L" " + StringUtils::toString(start) + L" to " + StringUtils::toString(end) + L": contains segment over maxMergeSize or maxMergeDocs; skipping"); } - start = 1 + upto; + start = end; + end = start + mergeFactor; } - return spec; + start = 1 + upto; } - OneMergePtr LogMergePolicy::makeOneMerge(const SegmentInfosPtr& infos, const SegmentInfosPtr& infosToMerge) - { - bool doCFS; - if (!_useCompoundFile) - doCFS = false; - else if (noCFSRatio == 1.0) - doCFS = true; - else - { - int64_t totSize = 0; - int32_t numInfos = infos->size(); - for (int32_t i = 0; i < numInfos; ++i) - { - SegmentInfoPtr info(infos->info(i)); - totSize += size(info); - } - int64_t mergeSize = 0; - int32_t numMerges = infosToMerge->size(); - for (int32_t i = 0; i < numMerges; ++i) - { - SegmentInfoPtr info(infosToMerge->info(i)); - mergeSize += size(info); - } - doCFS = mergeSize <= noCFSRatio * totSize; + return spec; +} + +OneMergePtr LogMergePolicy::makeOneMerge(const SegmentInfosPtr& infos, const SegmentInfosPtr& infosToMerge) { + bool doCFS; + if (!_useCompoundFile) { + doCFS = false; + } else if (noCFSRatio == 1.0) { + doCFS = true; + } else { + int64_t totSize = 0; + int32_t numInfos = infos->size(); + for (int32_t i = 0; i < numInfos; ++i) { + SegmentInfoPtr info(infos->info(i)); + totSize += size(info); } - return newLucene(infosToMerge, doCFS); + int64_t mergeSize = 0; + int32_t numMerges = infosToMerge->size(); + for (int32_t i = 0; i < numMerges; ++i) { + SegmentInfoPtr info(infosToMerge->info(i)); + mergeSize += size(info); + } + doCFS = mergeSize <= noCFSRatio * totSize; } + return newLucene(infosToMerge, doCFS); +} - void LogMergePolicy::setMaxMergeDocs(int32_t maxMergeDocs) - { - this->maxMergeDocs = maxMergeDocs; - } +void LogMergePolicy::setMaxMergeDocs(int32_t maxMergeDocs) { + this->maxMergeDocs = maxMergeDocs; +} + +int32_t LogMergePolicy::getMaxMergeDocs() { + return maxMergeDocs; +} - int32_t LogMergePolicy::getMaxMergeDocs() - { - return maxMergeDocs; - } } diff --git a/src/core/index/MergeDocIDRemapper.cpp b/src/core/index/MergeDocIDRemapper.cpp index 7f197f56..4ed090ec 100644 --- a/src/core/index/MergeDocIDRemapper.cpp +++ b/src/core/index/MergeDocIDRemapper.cpp @@ -10,78 +10,70 @@ #include "MergePolicy.h" #include "SegmentInfo.h" -namespace Lucene -{ - MergeDocIDRemapper::MergeDocIDRemapper(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount) - { - this->docMaps = docMaps; - SegmentInfoPtr firstSegment(merge->segments->info(0)); - int32_t i = 0; - this->minDocID = 0; - while (true) - { - SegmentInfoPtr info(infos->info(i)); - if (info->equals(firstSegment)) - break; - minDocID += info->docCount; - ++i; - } +namespace Lucene { - int32_t numDocs = 0; - for (int32_t j = 0; j < docMaps.size(); ++i, ++j) - { - numDocs += infos->info(i)->docCount; - BOOST_ASSERT(infos->info(i)->equals(merge->segments->info(j))); +MergeDocIDRemapper::MergeDocIDRemapper(const SegmentInfosPtr& infos, Collection< Collection > docMaps, Collection delCounts, const OneMergePtr& merge, int32_t mergedDocCount) { + this->docMaps = docMaps; + SegmentInfoPtr firstSegment(merge->segments->info(0)); + int32_t i = 0; + this->minDocID = 0; + while (true) { + SegmentInfoPtr info(infos->info(i)); + if (info->equals(firstSegment)) { + break; } - this->maxDocID = minDocID + numDocs; - - starts = Collection::newInstance(docMaps.size()); - newStarts = Collection::newInstance(docMaps.size()); + minDocID += info->docCount; + ++i; + } - starts[0] = minDocID; - newStarts[0] = minDocID; - for (i = 1; i < docMaps.size(); ++i) - { - int32_t lastDocCount = merge->segments->info(i - 1)->docCount; - starts[i] = starts[i - 1] + lastDocCount; - newStarts[i] = newStarts[i - 1] + lastDocCount - delCounts[i - 1]; - } - this->docShift = numDocs - mergedDocCount; + int32_t numDocs = 0; + for (int32_t j = 0; j < docMaps.size(); ++i, ++j) { + numDocs += infos->info(i)->docCount; + BOOST_ASSERT(infos->info(i)->equals(merge->segments->info(j))); + } + this->maxDocID = minDocID + numDocs; - // There are rare cases when docShift is 0. It happens if you try to delete a docID that's - // out of bounds, because the SegmentReader still allocates deletedDocs and pretends it has - // deletions ... so we can't make this assert here: BOOST_ASSERT(docShift > 0); + starts = Collection::newInstance(docMaps.size()); + newStarts = Collection::newInstance(docMaps.size()); - // Make sure it all adds up - BOOST_ASSERT(docShift == maxDocID - (newStarts[docMaps.size() - 1] + merge->segments->info(docMaps.size() - 1)->docCount - delCounts[docMaps.size() - 1])); + starts[0] = minDocID; + newStarts[0] = minDocID; + for (i = 1; i < docMaps.size(); ++i) { + int32_t lastDocCount = merge->segments->info(i - 1)->docCount; + starts[i] = starts[i - 1] + lastDocCount; + newStarts[i] = newStarts[i - 1] + lastDocCount - delCounts[i - 1]; } + this->docShift = numDocs - mergedDocCount; - MergeDocIDRemapper::~MergeDocIDRemapper() - { - } + // There are rare cases when docShift is 0. It happens if you try to delete a docID that's + // out of bounds, because the SegmentReader still allocates deletedDocs and pretends it has + // deletions ... so we can't make this assert here: BOOST_ASSERT(docShift > 0); - int32_t MergeDocIDRemapper::remap(int32_t oldDocID) - { - if (oldDocID < minDocID) - { - // Unaffected by merge - return oldDocID; - } - else if (oldDocID >= maxDocID) - { - // This doc was "after" the merge, so simple shift - return oldDocID - docShift; - } - else - { - // Binary search to locate this document & find its new docID - Collection::iterator doc = std::upper_bound(starts.begin(), starts.begin() + docMaps.size(), oldDocID); - int32_t docMap = std::distance(starts.begin(), doc) - 1; + // Make sure it all adds up + BOOST_ASSERT(docShift == maxDocID - (newStarts[docMaps.size() - 1] + merge->segments->info(docMaps.size() - 1)->docCount - delCounts[docMaps.size() - 1])); +} + +MergeDocIDRemapper::~MergeDocIDRemapper() { +} - if (docMaps[docMap]) - return newStarts[docMap] + docMaps[docMap][oldDocID - starts[docMap]]; - else - return newStarts[docMap] + oldDocID - starts[docMap]; +int32_t MergeDocIDRemapper::remap(int32_t oldDocID) { + if (oldDocID < minDocID) { + // Unaffected by merge + return oldDocID; + } else if (oldDocID >= maxDocID) { + // This doc was "after" the merge, so simple shift + return oldDocID - docShift; + } else { + // Binary search to locate this document & find its new docID + Collection::iterator doc = std::upper_bound(starts.begin(), starts.begin() + docMaps.size(), oldDocID); + int32_t docMap = std::distance(starts.begin(), doc) - 1; + + if (docMaps[docMap]) { + return newStarts[docMap] + docMaps[docMap][oldDocID - starts[docMap]]; + } else { + return newStarts[docMap] + oldDocID - starts[docMap]; } } } + +} diff --git a/src/core/index/MergePolicy.cpp b/src/core/index/MergePolicy.cpp index 6d807041..77bd83f5 100644 --- a/src/core/index/MergePolicy.cpp +++ b/src/core/index/MergePolicy.cpp @@ -10,107 +10,100 @@ #include "SegmentInfo.h" #include "StringUtils.h" -namespace Lucene -{ - MergePolicy::MergePolicy(const IndexWriterPtr& writer) - { - this->_writer = writer; - } +namespace Lucene { - MergePolicy::~MergePolicy() - { - } +MergePolicy::MergePolicy(const IndexWriterPtr& writer) { + this->_writer = writer; +} - OneMerge::OneMerge(const SegmentInfosPtr& segments, bool useCompoundFile) - { - mergeDocStores = false; - optimize = false; - registerDone = false; - mergeGen = 0; - isExternal = false; - maxNumSegmentsOptimize = 0; - aborted = false; - - if (segments->empty()) - boost::throw_exception(RuntimeException(L"segments must include at least one segment")); - this->segments = segments; - this->useCompoundFile = useCompoundFile; - } +MergePolicy::~MergePolicy() { +} - OneMerge::~OneMerge() - { +OneMerge::OneMerge(const SegmentInfosPtr& segments, bool useCompoundFile) { + mergeDocStores = false; + optimize = false; + registerDone = false; + mergeGen = 0; + isExternal = false; + maxNumSegmentsOptimize = 0; + aborted = false; + + if (segments->empty()) { + boost::throw_exception(RuntimeException(L"segments must include at least one segment")); } + this->segments = segments; + this->useCompoundFile = useCompoundFile; +} - void OneMerge::setException(const LuceneException& error) - { - SyncLock syncLock(this); - this->error = error; - } +OneMerge::~OneMerge() { +} - LuceneException OneMerge::getException() - { - SyncLock syncLock(this); - return error; - } +void OneMerge::setException(const LuceneException& error) { + SyncLock syncLock(this); + this->error = error; +} - void OneMerge::abort() - { - SyncLock syncLock(this); - aborted = true; - } +LuceneException OneMerge::getException() { + SyncLock syncLock(this); + return error; +} - bool OneMerge::isAborted() - { - SyncLock syncLock(this); - return aborted; - } +void OneMerge::abort() { + SyncLock syncLock(this); + aborted = true; +} - void OneMerge::checkAborted(const DirectoryPtr& dir) - { - SyncLock syncLock(this); - if (aborted) - boost::throw_exception(MergeAbortedException(L"merge is aborted: " + segString(dir))); +bool OneMerge::isAborted() { + SyncLock syncLock(this); + return aborted; +} + +void OneMerge::checkAborted(const DirectoryPtr& dir) { + SyncLock syncLock(this); + if (aborted) { + boost::throw_exception(MergeAbortedException(L"merge is aborted: " + segString(dir))); } +} - String OneMerge::segString(const DirectoryPtr& dir) - { - StringStream buffer; - int32_t numSegments = segments->size(); - for (int32_t i = 0; i < numSegments; ++i) - { - if (i > 0) - buffer << L" "; - buffer << segments->info(i)->segString(dir); +String OneMerge::segString(const DirectoryPtr& dir) { + StringStream buffer; + int32_t numSegments = segments->size(); + for (int32_t i = 0; i < numSegments; ++i) { + if (i > 0) { + buffer << L" "; } - if (info) - buffer << L" into " + info->name; - if (optimize) - buffer << L" [optimize]"; - if (mergeDocStores) - buffer << L" [mergeDocStores]"; - return buffer.str(); + buffer << segments->info(i)->segString(dir); } - - MergeSpecification::MergeSpecification() - { - merges = Collection::newInstance(); + if (info) { + buffer << L" into " + info->name; } - - MergeSpecification::~MergeSpecification() - { + if (optimize) { + buffer << L" [optimize]"; } - - void MergeSpecification::add(const OneMergePtr& merge) - { - merges.add(merge); + if (mergeDocStores) { + buffer << L" [mergeDocStores]"; } + return buffer.str(); +} + +MergeSpecification::MergeSpecification() { + merges = Collection::newInstance(); +} + +MergeSpecification::~MergeSpecification() { +} - String MergeSpecification::segString(const DirectoryPtr& dir) - { - String seg(L"MergeSpec:\n"); - int32_t i = 1; - for (Collection::iterator merge = merges.begin(); merge != merges.end(); ++merge) - seg += L" " + StringUtils::toString(i++) + L": " + (*merge)->segString(dir); - return seg; +void MergeSpecification::add(const OneMergePtr& merge) { + merges.add(merge); +} + +String MergeSpecification::segString(const DirectoryPtr& dir) { + String seg(L"MergeSpec:\n"); + int32_t i = 1; + for (Collection::iterator merge = merges.begin(); merge != merges.end(); ++merge) { + seg += L" " + StringUtils::toString(i++) + L": " + (*merge)->segString(dir); } + return seg; +} + } diff --git a/src/core/index/MergeScheduler.cpp b/src/core/index/MergeScheduler.cpp index 9aaf7f47..785f628e 100644 --- a/src/core/index/MergeScheduler.cpp +++ b/src/core/index/MergeScheduler.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "MergeScheduler.h" -namespace Lucene -{ - MergeScheduler::~MergeScheduler() - { - } +namespace Lucene { + +MergeScheduler::~MergeScheduler() { +} + } diff --git a/src/core/index/MultiLevelSkipListReader.cpp b/src/core/index/MultiLevelSkipListReader.cpp index 89869f4d..c31dd767 100644 --- a/src/core/index/MultiLevelSkipListReader.cpp +++ b/src/core/index/MultiLevelSkipListReader.cpp @@ -9,227 +9,206 @@ #include "BufferedIndexInput.h" #include "MiscUtils.h" -namespace Lucene -{ - MultiLevelSkipListReader::MultiLevelSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval) - { - this->numberOfLevelsToBuffer = 1; - this->numberOfSkipLevels = 0; - this->docCount = 0; - this->haveSkipped = false; - this->lastDoc = 0; - this->lastChildPointer = 0; - - this->skipStream = Collection::newInstance(maxSkipLevels); - this->skipPointer = Collection::newInstance(maxSkipLevels); - this->childPointer = Collection::newInstance(maxSkipLevels); - this->numSkipped = Collection::newInstance(maxSkipLevels); - this->maxNumberOfSkipLevels = maxSkipLevels; - this->skipInterval = Collection::newInstance(maxSkipLevels); - this->skipStream[0] = skipStream; - this->inputIsBuffered = boost::dynamic_pointer_cast(skipStream).get() != NULL; - this->skipInterval[0] = skipInterval; - this->skipDoc = Collection::newInstance(maxSkipLevels); - - MiscUtils::arrayFill(this->skipPointer.begin(), 0, this->skipPointer.size(), 0); - MiscUtils::arrayFill(this->childPointer.begin(), 0, this->childPointer.size(), 0); - MiscUtils::arrayFill(this->numSkipped.begin(), 0, this->numSkipped.size(), 0); - MiscUtils::arrayFill(this->skipDoc.begin(), 0, this->skipDoc.size(), 0); - - for (int32_t i = 1; i < maxSkipLevels; ++i) - { - // cache skip intervals - this->skipInterval[i] = this->skipInterval[i - 1] * skipInterval; - } +namespace Lucene { + +MultiLevelSkipListReader::MultiLevelSkipListReader(const IndexInputPtr& skipStream, int32_t maxSkipLevels, int32_t skipInterval) { + this->numberOfLevelsToBuffer = 1; + this->numberOfSkipLevels = 0; + this->docCount = 0; + this->haveSkipped = false; + this->lastDoc = 0; + this->lastChildPointer = 0; + + this->skipStream = Collection::newInstance(maxSkipLevels); + this->skipPointer = Collection::newInstance(maxSkipLevels); + this->childPointer = Collection::newInstance(maxSkipLevels); + this->numSkipped = Collection::newInstance(maxSkipLevels); + this->maxNumberOfSkipLevels = maxSkipLevels; + this->skipInterval = Collection::newInstance(maxSkipLevels); + this->skipStream[0] = skipStream; + this->inputIsBuffered = boost::dynamic_pointer_cast(skipStream).get() != NULL; + this->skipInterval[0] = skipInterval; + this->skipDoc = Collection::newInstance(maxSkipLevels); + + MiscUtils::arrayFill(this->skipPointer.begin(), 0, this->skipPointer.size(), 0); + MiscUtils::arrayFill(this->childPointer.begin(), 0, this->childPointer.size(), 0); + MiscUtils::arrayFill(this->numSkipped.begin(), 0, this->numSkipped.size(), 0); + MiscUtils::arrayFill(this->skipDoc.begin(), 0, this->skipDoc.size(), 0); + + for (int32_t i = 1; i < maxSkipLevels; ++i) { + // cache skip intervals + this->skipInterval[i] = this->skipInterval[i - 1] * skipInterval; } +} - MultiLevelSkipListReader::~MultiLevelSkipListReader() - { - } +MultiLevelSkipListReader::~MultiLevelSkipListReader() { +} + +int32_t MultiLevelSkipListReader::getDoc() { + return lastDoc; +} - int32_t MultiLevelSkipListReader::getDoc() - { - return lastDoc; +int32_t MultiLevelSkipListReader::skipTo(int32_t target) { + if (!haveSkipped) { + // first time, load skip levels + loadSkipLevels(); + haveSkipped = true; } - int32_t MultiLevelSkipListReader::skipTo(int32_t target) - { - if (!haveSkipped) - { - // first time, load skip levels - loadSkipLevels(); - haveSkipped = true; - } + // walk up the levels until highest level is found that has a skip for this target + int32_t level = 0; + while (level < numberOfSkipLevels - 1 && target > skipDoc[level + 1]) { + ++level; + } - // walk up the levels until highest level is found that has a skip for this target - int32_t level = 0; - while (level < numberOfSkipLevels - 1 && target > skipDoc[level + 1]) - ++level; - - while (level >= 0) - { - if (target > skipDoc[level]) - { - if (!loadNextSkip(level)) - continue; + while (level >= 0) { + if (target > skipDoc[level]) { + if (!loadNextSkip(level)) { + continue; } - else - { - // no more skips on this level, go down one level - if (level > 0 && lastChildPointer > skipStream[level - 1]->getFilePointer()) - seekChild(level - 1); - --level; + } else { + // no more skips on this level, go down one level + if (level > 0 && lastChildPointer > skipStream[level - 1]->getFilePointer()) { + seekChild(level - 1); } + --level; } - - return numSkipped[0] - skipInterval[0] - 1; } - bool MultiLevelSkipListReader::loadNextSkip(int32_t level) - { - // we have to skip, the target document is greater than the current skip list entry - setLastSkipData(level); - - numSkipped[level] += skipInterval[level]; + return numSkipped[0] - skipInterval[0] - 1; +} - if (numSkipped[level] > docCount) - { - // this skip list is exhausted - skipDoc[level] = INT_MAX; - if (numberOfSkipLevels > level) - numberOfSkipLevels = level; - return false; - } +bool MultiLevelSkipListReader::loadNextSkip(int32_t level) { + // we have to skip, the target document is greater than the current skip list entry + setLastSkipData(level); - // read next skip entry - skipDoc[level] += readSkipData(level, skipStream[level]); + numSkipped[level] += skipInterval[level]; - if (level != 0) - { - // read the child pointer if we are not on the leaf level - childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; + if (numSkipped[level] > docCount) { + // this skip list is exhausted + skipDoc[level] = INT_MAX; + if (numberOfSkipLevels > level) { + numberOfSkipLevels = level; } + return false; + } + + // read next skip entry + skipDoc[level] += readSkipData(level, skipStream[level]); - return true; + if (level != 0) { + // read the child pointer if we are not on the leaf level + childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; } - void MultiLevelSkipListReader::seekChild(int32_t level) - { - skipStream[level]->seek(lastChildPointer); - numSkipped[level] = numSkipped[level + 1] - skipInterval[level + 1]; - skipDoc[level] = lastDoc; - if (level > 0) - childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; + return true; +} + +void MultiLevelSkipListReader::seekChild(int32_t level) { + skipStream[level]->seek(lastChildPointer); + numSkipped[level] = numSkipped[level + 1] - skipInterval[level + 1]; + skipDoc[level] = lastDoc; + if (level > 0) { + childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; } +} - void MultiLevelSkipListReader::close() - { - for (int32_t i = 1; i < skipStream.size(); ++i) - { - if (skipStream[i]) - skipStream[i]->close(); +void MultiLevelSkipListReader::close() { + for (int32_t i = 1; i < skipStream.size(); ++i) { + if (skipStream[i]) { + skipStream[i]->close(); } } +} - void MultiLevelSkipListReader::init(int64_t skipPointer, int32_t df) - { - this->skipPointer[0] = skipPointer; - this->docCount = df; - MiscUtils::arrayFill(skipDoc.begin(), 0, skipDoc.size(), 0); - MiscUtils::arrayFill(numSkipped.begin(), 0, numSkipped.size(), 0); - MiscUtils::arrayFill(childPointer.begin(), 0, childPointer.size(), 0); - - haveSkipped = false; - for (int32_t i = 1; i < numberOfSkipLevels; ++i) - skipStream[i].reset(); +void MultiLevelSkipListReader::init(int64_t skipPointer, int32_t df) { + this->skipPointer[0] = skipPointer; + this->docCount = df; + MiscUtils::arrayFill(skipDoc.begin(), 0, skipDoc.size(), 0); + MiscUtils::arrayFill(numSkipped.begin(), 0, numSkipped.size(), 0); + MiscUtils::arrayFill(childPointer.begin(), 0, childPointer.size(), 0); + + haveSkipped = false; + for (int32_t i = 1; i < numberOfSkipLevels; ++i) { + skipStream[i].reset(); } +} - void MultiLevelSkipListReader::loadSkipLevels() - { - numberOfSkipLevels = docCount == 0 ? 0 : (int32_t)std::floor(std::log((double)docCount) / std::log((double)skipInterval[0])); - if (numberOfSkipLevels > maxNumberOfSkipLevels) - numberOfSkipLevels = maxNumberOfSkipLevels; +void MultiLevelSkipListReader::loadSkipLevels() { + numberOfSkipLevels = docCount == 0 ? 0 : (int32_t)std::floor(std::log((double)docCount) / std::log((double)skipInterval[0])); + if (numberOfSkipLevels > maxNumberOfSkipLevels) { + numberOfSkipLevels = maxNumberOfSkipLevels; + } - skipStream[0]->seek(skipPointer[0]); + skipStream[0]->seek(skipPointer[0]); - int32_t toBuffer = numberOfLevelsToBuffer; + int32_t toBuffer = numberOfLevelsToBuffer; - for (int32_t i = numberOfSkipLevels - 1; i > 0; --i) - { - // the length of the current level - int64_t length = skipStream[0]->readVLong(); + for (int32_t i = numberOfSkipLevels - 1; i > 0; --i) { + // the length of the current level + int64_t length = skipStream[0]->readVLong(); - // the start pointer of the current level - skipPointer[i] = skipStream[0]->getFilePointer(); + // the start pointer of the current level + skipPointer[i] = skipStream[0]->getFilePointer(); - if (toBuffer > 0) - { - // buffer this level - skipStream[i] = newLucene(skipStream[0], (int32_t)length); - --toBuffer; + if (toBuffer > 0) { + // buffer this level + skipStream[i] = newLucene(skipStream[0], (int32_t)length); + --toBuffer; + } else { + // clone this stream, it is already at the start of the current level + skipStream[i] = boost::dynamic_pointer_cast(skipStream[0]->clone()); + if (inputIsBuffered && length < BufferedIndexInput::BUFFER_SIZE) { + boost::dynamic_pointer_cast(skipStream[i])->setBufferSize((int32_t)length); } - else - { - // clone this stream, it is already at the start of the current level - skipStream[i] = boost::dynamic_pointer_cast(skipStream[0]->clone()); - if (inputIsBuffered && length < BufferedIndexInput::BUFFER_SIZE) - boost::dynamic_pointer_cast(skipStream[i])->setBufferSize((int32_t)length); - - // move base stream beyond the current level - skipStream[0]->seek(skipStream[0]->getFilePointer() + length); - } - } - // use base stream for the lowest level - skipPointer[0] = skipStream[0]->getFilePointer(); + // move base stream beyond the current level + skipStream[0]->seek(skipStream[0]->getFilePointer() + length); + } } - void MultiLevelSkipListReader::setLastSkipData(int32_t level) - { - lastDoc = skipDoc[level]; - lastChildPointer = childPointer[level]; - } + // use base stream for the lowest level + skipPointer[0] = skipStream[0]->getFilePointer(); +} - SkipBuffer::SkipBuffer(const IndexInputPtr& input, int32_t length) - { - pos = 0; - data = ByteArray::newInstance(length); - pointer = input->getFilePointer(); - input->readBytes(data.get(), 0, length); - } +void MultiLevelSkipListReader::setLastSkipData(int32_t level) { + lastDoc = skipDoc[level]; + lastChildPointer = childPointer[level]; +} - SkipBuffer::~SkipBuffer() - { - } +SkipBuffer::SkipBuffer(const IndexInputPtr& input, int32_t length) { + pos = 0; + data = ByteArray::newInstance(length); + pointer = input->getFilePointer(); + input->readBytes(data.get(), 0, length); +} - void SkipBuffer::close() - { - data.reset(); - } +SkipBuffer::~SkipBuffer() { +} - int64_t SkipBuffer::getFilePointer() - { - return (pointer + pos); - } +void SkipBuffer::close() { + data.reset(); +} - int64_t SkipBuffer::length() - { - return data.size(); - } +int64_t SkipBuffer::getFilePointer() { + return (pointer + pos); +} - uint8_t SkipBuffer::readByte() - { - return data[pos++]; - } +int64_t SkipBuffer::length() { + return data.size(); +} - void SkipBuffer::readBytes(uint8_t* b, int32_t offset, int32_t length) - { - MiscUtils::arrayCopy(data.get(), pos, b, offset, length); - pos += length; - } +uint8_t SkipBuffer::readByte() { + return data[pos++]; +} + +void SkipBuffer::readBytes(uint8_t* b, int32_t offset, int32_t length) { + MiscUtils::arrayCopy(data.get(), pos, b, offset, length); + pos += length; +} + +void SkipBuffer::seek(int64_t pos) { + this->pos = (int32_t)(pos - pointer); +} - void SkipBuffer::seek(int64_t pos) - { - this->pos = (int32_t)(pos - pointer); - } } diff --git a/src/core/index/MultiLevelSkipListWriter.cpp b/src/core/index/MultiLevelSkipListWriter.cpp index 63dc5839..6400000d 100644 --- a/src/core/index/MultiLevelSkipListWriter.cpp +++ b/src/core/index/MultiLevelSkipListWriter.cpp @@ -8,87 +8,80 @@ #include "MultiLevelSkipListWriter.h" #include "RAMOutputStream.h" -namespace Lucene -{ - MultiLevelSkipListWriter::MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df) - { - this->skipInterval = skipInterval; +namespace Lucene { - // calculate the maximum number of skip levels for this document frequency - numberOfSkipLevels = df == 0 ? 0 : (int32_t)std::floor(std::log((double)df) / std::log((double)skipInterval)); +MultiLevelSkipListWriter::MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df) { + this->skipInterval = skipInterval; - // make sure it does not exceed maxSkipLevels - numberOfSkipLevels = std::max(numberOfSkipLevels, maxSkipLevels); - } + // calculate the maximum number of skip levels for this document frequency + numberOfSkipLevels = df == 0 ? 0 : (int32_t)std::floor(std::log((double)df) / std::log((double)skipInterval)); - MultiLevelSkipListWriter::~MultiLevelSkipListWriter() - { - } + // make sure it does not exceed maxSkipLevels + numberOfSkipLevels = std::max(numberOfSkipLevels, maxSkipLevels); +} + +MultiLevelSkipListWriter::~MultiLevelSkipListWriter() { +} - void MultiLevelSkipListWriter::init() - { - skipBuffer = Collection::newInstance(numberOfSkipLevels); - for (int32_t i = 0; i < numberOfSkipLevels; ++i) - skipBuffer[i] = newLucene(); +void MultiLevelSkipListWriter::init() { + skipBuffer = Collection::newInstance(numberOfSkipLevels); + for (int32_t i = 0; i < numberOfSkipLevels; ++i) { + skipBuffer[i] = newLucene(); } +} - void MultiLevelSkipListWriter::resetSkip() - { - // creates new buffers or empties the existing ones - if (!skipBuffer) - init(); - else - { - for (Collection::iterator buffer = skipBuffer.begin(); buffer != skipBuffer.end(); ++buffer) - (*buffer)->reset(); +void MultiLevelSkipListWriter::resetSkip() { + // creates new buffers or empties the existing ones + if (!skipBuffer) { + init(); + } else { + for (Collection::iterator buffer = skipBuffer.begin(); buffer != skipBuffer.end(); ++buffer) { + (*buffer)->reset(); } } +} - void MultiLevelSkipListWriter::bufferSkip(int32_t df) - { - int32_t numLevels = 0; - - // determine max level - for (; (df % skipInterval) == 0 && numLevels < numberOfSkipLevels; df /= skipInterval) - ++numLevels; +void MultiLevelSkipListWriter::bufferSkip(int32_t df) { + int32_t numLevels = 0; - int64_t childPointer = 0; + // determine max level + for (; (df % skipInterval) == 0 && numLevels < numberOfSkipLevels; df /= skipInterval) { + ++numLevels; + } - for (int32_t level = 0; level < numLevels; ++level) - { - writeSkipData(level, skipBuffer[level]); + int64_t childPointer = 0; - int64_t newChildPointer = skipBuffer[level]->getFilePointer(); + for (int32_t level = 0; level < numLevels; ++level) { + writeSkipData(level, skipBuffer[level]); - if (level != 0) - { - // store child pointers for all levels except the lowest - skipBuffer[level]->writeVLong(childPointer); - } + int64_t newChildPointer = skipBuffer[level]->getFilePointer(); - // remember the childPointer for the next level - childPointer = newChildPointer; + if (level != 0) { + // store child pointers for all levels except the lowest + skipBuffer[level]->writeVLong(childPointer); } + + // remember the childPointer for the next level + childPointer = newChildPointer; } +} - int64_t MultiLevelSkipListWriter::writeSkip(const IndexOutputPtr& output) - { - int64_t skipPointer = output->getFilePointer(); - if (!skipBuffer || skipBuffer.empty()) - return skipPointer; - - for (int32_t level = numberOfSkipLevels - 1; level > 0; --level) - { - int64_t length = skipBuffer[level]->getFilePointer(); - if (length > 0) - { - output->writeVLong(length); - skipBuffer[level]->writeTo(output); - } - } - skipBuffer[0]->writeTo(output); +int64_t MultiLevelSkipListWriter::writeSkip(const IndexOutputPtr& output) { + int64_t skipPointer = output->getFilePointer(); + if (!skipBuffer || skipBuffer.empty()) { return skipPointer; } + for (int32_t level = numberOfSkipLevels - 1; level > 0; --level) { + int64_t length = skipBuffer[level]->getFilePointer(); + if (length > 0) { + output->writeVLong(length); + skipBuffer[level]->writeTo(output); + } + } + skipBuffer[0]->writeTo(output); + return skipPointer; +} + } diff --git a/src/core/index/MultiReader.cpp b/src/core/index/MultiReader.cpp index 55860cc4..8b012aa1 100644 --- a/src/core/index/MultiReader.cpp +++ b/src/core/index/MultiReader.cpp @@ -11,360 +11,321 @@ #include "FieldCache.h" #include "MiscUtils.h" -namespace Lucene -{ - MultiReader::MultiReader(Collection subReaders, bool closeSubReaders) - { - this->normsCache = MapStringByteArray::newInstance(); - this->_maxDoc = 0; - this->_numDocs = -1; - this->_hasDeletions = false; - this->subReaders = subReaders; - starts = Collection::newInstance(subReaders.size() + 1); // build starts array - decrefOnClose = Collection::newInstance(subReaders.size()); - for (int32_t i = 0; i < subReaders.size(); ++i) - { - starts[i] = _maxDoc; - _maxDoc += subReaders[i]->maxDoc(); // compute maxDocs - - if (!closeSubReaders) - { - subReaders[i]->incRef(); - decrefOnClose[i] = true; - } - else - decrefOnClose[i] = false; +namespace Lucene { + +MultiReader::MultiReader(Collection subReaders, bool closeSubReaders) { + this->normsCache = MapStringByteArray::newInstance(); + this->_maxDoc = 0; + this->_numDocs = -1; + this->_hasDeletions = false; + this->subReaders = subReaders; + starts = Collection::newInstance(subReaders.size() + 1); // build starts array + decrefOnClose = Collection::newInstance(subReaders.size()); + for (int32_t i = 0; i < subReaders.size(); ++i) { + starts[i] = _maxDoc; + _maxDoc += subReaders[i]->maxDoc(); // compute maxDocs + + if (!closeSubReaders) { + subReaders[i]->incRef(); + decrefOnClose[i] = true; + } else { + decrefOnClose[i] = false; + } - if (subReaders[i]->hasDeletions()) - _hasDeletions = true; + if (subReaders[i]->hasDeletions()) { + _hasDeletions = true; } - starts[subReaders.size()] = _maxDoc; } + starts[subReaders.size()] = _maxDoc; +} - MultiReader::~MultiReader() - { - } +MultiReader::~MultiReader() { +} - IndexReaderPtr MultiReader::reopen() - { - SyncLock syncLock(this); - return doReopen(false); - } +IndexReaderPtr MultiReader::reopen() { + SyncLock syncLock(this); + return doReopen(false); +} - LuceneObjectPtr MultiReader::clone(const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - try - { - return doReopen(true); - } - catch (LuceneException& e) - { - boost::throw_exception(RuntimeException(e.getError())); - } - return LuceneObjectPtr(); +LuceneObjectPtr MultiReader::clone(const LuceneObjectPtr& other) { + SyncLock syncLock(this); + try { + return doReopen(true); + } catch (LuceneException& e) { + boost::throw_exception(RuntimeException(e.getError())); } + return LuceneObjectPtr(); +} - IndexReaderPtr MultiReader::doReopen(bool doClone) - { - ensureOpen(); - - bool reopened = false; - Collection newSubReaders(Collection::newInstance(subReaders.size())); - - bool success = false; - LuceneException finally; - try - { - for (int32_t i = 0; i < subReaders.size(); ++i) - { - if (doClone) - newSubReaders[i] = boost::dynamic_pointer_cast(subReaders[i]->clone()); - else - newSubReaders[i] = subReaders[i]->reopen(); - // if at least one of the subreaders was updated we remember that and return a new MultiReader - if (newSubReaders[i] != subReaders[i]) - reopened = true; +IndexReaderPtr MultiReader::doReopen(bool doClone) { + ensureOpen(); + + bool reopened = false; + Collection newSubReaders(Collection::newInstance(subReaders.size())); + + bool success = false; + LuceneException finally; + try { + for (int32_t i = 0; i < subReaders.size(); ++i) { + if (doClone) { + newSubReaders[i] = boost::dynamic_pointer_cast(subReaders[i]->clone()); + } else { + newSubReaders[i] = subReaders[i]->reopen(); + } + // if at least one of the subreaders was updated we remember that and return a new MultiReader + if (newSubReaders[i] != subReaders[i]) { + reopened = true; } - success = true; - } - catch (LuceneException& e) - { - finally = e; } - if (!success && reopened) - { - for (int32_t i = 0; i < newSubReaders.size(); ++i) - { - if (newSubReaders[i] != subReaders[i]) - { - try - { - if (newSubReaders[i]) - newSubReaders[i]->close(); - } - catch (...) - { - // keep going - we want to clean up as much as possible + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success && reopened) { + for (int32_t i = 0; i < newSubReaders.size(); ++i) { + if (newSubReaders[i] != subReaders[i]) { + try { + if (newSubReaders[i]) { + newSubReaders[i]->close(); } + } catch (...) { + // keep going - we want to clean up as much as possible } } } - finally.throwException(); - - if (reopened) - { - Collection newDecrefOnClose(Collection::newInstance(subReaders.size())); - for (int32_t i = 0; i < subReaders.size(); ++i) - { - if (newSubReaders[i] == subReaders[i]) - { - newSubReaders[i]->incRef(); - newDecrefOnClose[i] = true; - } - } + } + finally.throwException(); - MultiReaderPtr mr(newLucene(newSubReaders)); - mr->decrefOnClose = newDecrefOnClose; - return mr; + if (reopened) { + Collection newDecrefOnClose(Collection::newInstance(subReaders.size())); + for (int32_t i = 0; i < subReaders.size(); ++i) { + if (newSubReaders[i] == subReaders[i]) { + newSubReaders[i]->incRef(); + newDecrefOnClose[i] = true; + } } - else - return shared_from_this(); - } - Collection MultiReader::getTermFreqVectors(int32_t docNumber) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - return subReaders[i]->getTermFreqVectors(docNumber - starts[i]); // dispatch to segment + MultiReaderPtr mr(newLucene(newSubReaders)); + mr->decrefOnClose = newDecrefOnClose; + return mr; + } else { + return shared_from_this(); } +} - TermFreqVectorPtr MultiReader::getTermFreqVector(int32_t docNumber, const String& field) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); - } +Collection MultiReader::getTermFreqVectors(int32_t docNumber) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + return subReaders[i]->getTermFreqVectors(docNumber - starts[i]); // dispatch to segment +} - void MultiReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); - } +TermFreqVectorPtr MultiReader::getTermFreqVector(int32_t docNumber, const String& field) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + return subReaders[i]->getTermFreqVector(docNumber - starts[i], field); +} - void MultiReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - int32_t i = readerIndex(docNumber); // find segment num - subReaders[i]->getTermFreqVector(docNumber - starts[i], mapper); - } +void MultiReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + subReaders[i]->getTermFreqVector(docNumber - starts[i], field, mapper); +} - bool MultiReader::isOptimized() - { - return false; - } +void MultiReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + subReaders[i]->getTermFreqVector(docNumber - starts[i], mapper); +} - int32_t MultiReader::numDocs() - { - // Don't call ensureOpen() here (it could affect performance) - - // NOTE: multiple threads may wind up init'ing numDocs... but that's harmless - if (_numDocs == -1) - { - // check cache - int32_t n = 0; // cache miss - recompute - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - n += (*reader)->numDocs(); // sum from readers - _numDocs = n; +bool MultiReader::isOptimized() { + return false; +} + +int32_t MultiReader::numDocs() { + // Don't call ensureOpen() here (it could affect performance) + + // NOTE: multiple threads may wind up init'ing numDocs... but that's harmless + if (_numDocs == -1) { + // check cache + int32_t n = 0; // cache miss - recompute + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + n += (*reader)->numDocs(); // sum from readers } - return _numDocs; + _numDocs = n; } + return _numDocs; +} - int32_t MultiReader::maxDoc() - { - // Don't call ensureOpen() here (it could affect performance) - return _maxDoc; - } +int32_t MultiReader::maxDoc() { + // Don't call ensureOpen() here (it could affect performance) + return _maxDoc; +} - DocumentPtr MultiReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) - { - ensureOpen(); - int32_t i = readerIndex(n); // find segment num - return subReaders[i]->document(n - starts[i], fieldSelector); // dispatch to segment reader - } +DocumentPtr MultiReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return subReaders[i]->document(n - starts[i], fieldSelector); // dispatch to segment reader +} - bool MultiReader::isDeleted(int32_t n) - { - // Don't call ensureOpen() here (it could affect performance) - int32_t i = readerIndex(n); // find segment num - return subReaders[i]->isDeleted(n - starts[i]); // dispatch to segment reader - } +bool MultiReader::isDeleted(int32_t n) { + // Don't call ensureOpen() here (it could affect performance) + int32_t i = readerIndex(n); // find segment num + return subReaders[i]->isDeleted(n - starts[i]); // dispatch to segment reader +} - bool MultiReader::hasDeletions() - { - // Don't call ensureOpen() here (it could affect performance) - return _hasDeletions; - } +bool MultiReader::hasDeletions() { + // Don't call ensureOpen() here (it could affect performance) + return _hasDeletions; +} - void MultiReader::doDelete(int32_t docNum) - { - _numDocs = -1; // invalidate cache - int32_t i = readerIndex(docNum); // find segment num - subReaders[i]->deleteDocument(docNum - starts[i]); // dispatch to segment reader - _hasDeletions = true; - } +void MultiReader::doDelete(int32_t docNum) { + _numDocs = -1; // invalidate cache + int32_t i = readerIndex(docNum); // find segment num + subReaders[i]->deleteDocument(docNum - starts[i]); // dispatch to segment reader + _hasDeletions = true; +} - void MultiReader::doUndeleteAll() - { - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - (*reader)->undeleteAll(); - _hasDeletions = false; - _numDocs = -1; // invalidate cache +void MultiReader::doUndeleteAll() { + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + (*reader)->undeleteAll(); } + _hasDeletions = false; + _numDocs = -1; // invalidate cache +} - int32_t MultiReader::readerIndex(int32_t n) - { - return DirectoryReader::readerIndex(n, this->starts, this->subReaders.size()); - } +int32_t MultiReader::readerIndex(int32_t n) { + return DirectoryReader::readerIndex(n, this->starts, this->subReaders.size()); +} - bool MultiReader::hasNorms(const String& field) - { - ensureOpen(); - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - { - if ((*reader)->hasNorms(field)) - return true; +bool MultiReader::hasNorms(const String& field) { + ensureOpen(); + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + if ((*reader)->hasNorms(field)) { + return true; } - return false; } + return false; +} - ByteArray MultiReader::norms(const String& field) - { - SyncLock syncLock(this); - ensureOpen(); - ByteArray bytes(normsCache.get(field)); - if (bytes) - return bytes; // cache hit - if (!hasNorms(field)) - return ByteArray(); - - bytes = ByteArray::newInstance(maxDoc()); - for (int32_t i = 0; i < subReaders.size(); ++i) - subReaders[i]->norms(field, bytes, starts[i]); - normsCache.put(field, bytes); // update cache - return bytes; +ByteArray MultiReader::norms(const String& field) { + SyncLock syncLock(this); + ensureOpen(); + ByteArray bytes(normsCache.get(field)); + if (bytes) { + return bytes; // cache hit + } + if (!hasNorms(field)) { + return ByteArray(); } - void MultiReader::norms(const String& field, ByteArray norms, int32_t offset) - { - SyncLock syncLock(this); - ensureOpen(); - ByteArray bytes(normsCache.get(field)); - for (int32_t i = 0; i < subReaders.size(); ++i) // read from segments - subReaders[i]->norms(field, norms, offset + starts[i]); + bytes = ByteArray::newInstance(maxDoc()); + for (int32_t i = 0; i < subReaders.size(); ++i) { + subReaders[i]->norms(field, bytes, starts[i]); + } + normsCache.put(field, bytes); // update cache + return bytes; +} - if (!bytes && !hasNorms(field)) - MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); - else if (bytes) // cache hit - MiscUtils::arrayCopy(bytes.get(), 0, norms.get(), offset, maxDoc()); - else - { - for (int32_t i = 0; i < subReaders.size(); ++i) - subReaders[i]->norms(field, norms, offset + starts[i]); - } +void MultiReader::norms(const String& field, ByteArray norms, int32_t offset) { + SyncLock syncLock(this); + ensureOpen(); + ByteArray bytes(normsCache.get(field)); + for (int32_t i = 0; i < subReaders.size(); ++i) { // read from segments + subReaders[i]->norms(field, norms, offset + starts[i]); } - void MultiReader::doSetNorm(int32_t doc, const String& field, uint8_t value) - { - { - SyncLock normsLock(&normsCache); - normsCache.remove(field); // clear cache + if (!bytes && !hasNorms(field)) { + MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); + } else if (bytes) { // cache hit + MiscUtils::arrayCopy(bytes.get(), 0, norms.get(), offset, maxDoc()); + } else { + for (int32_t i = 0; i < subReaders.size(); ++i) { + subReaders[i]->norms(field, norms, offset + starts[i]); } - int32_t i = readerIndex(doc); // find segment num - subReaders[i]->setNorm(doc - starts[i], field, value); // dispatch } +} - TermEnumPtr MultiReader::terms() +void MultiReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { { - ensureOpen(); - return newLucene(shared_from_this(), subReaders, starts, TermPtr()); + SyncLock normsLock(&normsCache); + normsCache.remove(field); // clear cache } + int32_t i = readerIndex(doc); // find segment num + subReaders[i]->setNorm(doc - starts[i], field, value); // dispatch +} - TermEnumPtr MultiReader::terms(const TermPtr& t) - { - ensureOpen(); - return newLucene(shared_from_this(), subReaders, starts, t); - } +TermEnumPtr MultiReader::terms() { + ensureOpen(); + return newLucene(shared_from_this(), subReaders, starts, TermPtr()); +} - int32_t MultiReader::docFreq(const TermPtr& t) - { - ensureOpen(); - int32_t total = 0; // sum freqs in segments - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - total += (*reader)->docFreq(t); - return total; - } +TermEnumPtr MultiReader::terms(const TermPtr& t) { + ensureOpen(); + return newLucene(shared_from_this(), subReaders, starts, t); +} - TermDocsPtr MultiReader::termDocs() - { - ensureOpen(); - return newLucene(shared_from_this(), subReaders, starts); +int32_t MultiReader::docFreq(const TermPtr& t) { + ensureOpen(); + int32_t total = 0; // sum freqs in segments + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + total += (*reader)->docFreq(t); } + return total; +} - TermPositionsPtr MultiReader::termPositions() - { - ensureOpen(); - return newLucene(shared_from_this(), subReaders, starts); - } +TermDocsPtr MultiReader::termDocs() { + ensureOpen(); + return newLucene(shared_from_this(), subReaders, starts); +} - void MultiReader::doCommit(MapStringString commitUserData) - { - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - (*reader)->commit(commitUserData); +TermPositionsPtr MultiReader::termPositions() { + ensureOpen(); + return newLucene(shared_from_this(), subReaders, starts); +} + +void MultiReader::doCommit(MapStringString commitUserData) { + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + (*reader)->commit(commitUserData); } +} - void MultiReader::doClose() - { - SyncLock syncLock(this); - for (int32_t i = 0; i < subReaders.size(); ++i) - { - if (decrefOnClose[i]) - subReaders[i]->decRef(); - else - subReaders[i]->close(); +void MultiReader::doClose() { + SyncLock syncLock(this); + for (int32_t i = 0; i < subReaders.size(); ++i) { + if (decrefOnClose[i]) { + subReaders[i]->decRef(); + } else { + subReaders[i]->close(); } - - // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is - // generally not a good idea) - FieldCache::DEFAULT()->purge(shared_from_this()); } - HashSet MultiReader::getFieldNames(FieldOption fieldOption) - { - ensureOpen(); - return DirectoryReader::getFieldNames(fieldOption, this->subReaders); - } + // NOTE: only needed in case someone had asked for FieldCache for top-level reader (which is + // generally not a good idea) + FieldCache::DEFAULT()->purge(shared_from_this()); +} - bool MultiReader::isCurrent() - { - for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) - { - if (!(*reader)->isCurrent()) - return false; +HashSet MultiReader::getFieldNames(FieldOption fieldOption) { + ensureOpen(); + return DirectoryReader::getFieldNames(fieldOption, this->subReaders); +} + +bool MultiReader::isCurrent() { + for (Collection::iterator reader = subReaders.begin(); reader != subReaders.end(); ++reader) { + if (!(*reader)->isCurrent()) { + return false; } - // all subreaders are up to date - return true; } + // all subreaders are up to date + return true; +} - int64_t MultiReader::getVersion() - { - boost::throw_exception(UnsupportedOperationException()); - return 0; - } +int64_t MultiReader::getVersion() { + boost::throw_exception(UnsupportedOperationException()); + return 0; +} + +Collection MultiReader::getSequentialSubReaders() { + return subReaders; +} - Collection MultiReader::getSequentialSubReaders() - { - return subReaders; - } } diff --git a/src/core/index/MultipleTermPositions.cpp b/src/core/index/MultipleTermPositions.cpp index e89d9157..f5c5a1ba 100644 --- a/src/core/index/MultipleTermPositions.cpp +++ b/src/core/index/MultipleTermPositions.cpp @@ -10,187 +10,165 @@ #include "IndexReader.h" #include "Term.h" -namespace Lucene -{ - MultipleTermPositions::MultipleTermPositions(const IndexReaderPtr& indexReader, Collection terms) - { - Collection termPositions(Collection::newInstance()); - - for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) - termPositions.add(indexReader->termPositions(*term)); - - termPositionsQueue = newLucene(termPositions); - posList = newLucene(); - _doc = 0; - _freq = 0; - } +namespace Lucene { + +MultipleTermPositions::MultipleTermPositions(const IndexReaderPtr& indexReader, Collection terms) { + Collection termPositions(Collection::newInstance()); - MultipleTermPositions::~MultipleTermPositions() - { + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) { + termPositions.add(indexReader->termPositions(*term)); } - bool MultipleTermPositions::next() - { - if (termPositionsQueue->empty()) - return false; - - posList->clear(); - _doc = termPositionsQueue->top()->doc(); - - TermPositionsPtr tp; - do - { - tp = termPositionsQueue->top(); - - for (int32_t i = 0; i < tp->freq(); ++i) - posList->add(tp->nextPosition()); - - if (tp->next()) - termPositionsQueue->updateTop(); - else - { - termPositionsQueue->pop(); - tp->close(); - } - } - while (!termPositionsQueue->empty() && termPositionsQueue->top()->doc() == _doc); + termPositionsQueue = newLucene(termPositions); + posList = newLucene(); + _doc = 0; + _freq = 0; +} - posList->sort(); - _freq = posList->size(); +MultipleTermPositions::~MultipleTermPositions() { +} - return true; +bool MultipleTermPositions::next() { + if (termPositionsQueue->empty()) { + return false; } - int32_t MultipleTermPositions::nextPosition() - { - return posList->next(); - } + posList->clear(); + _doc = termPositionsQueue->top()->doc(); + + TermPositionsPtr tp; + do { + tp = termPositionsQueue->top(); - bool MultipleTermPositions::skipTo(int32_t target) - { - while (termPositionsQueue->top() && target > termPositionsQueue->top()->doc()) - { - TermPositionsPtr tp(termPositionsQueue->top()); + for (int32_t i = 0; i < tp->freq(); ++i) { + posList->add(tp->nextPosition()); + } + + if (tp->next()) { + termPositionsQueue->updateTop(); + } else { termPositionsQueue->pop(); + tp->close(); + } + } while (!termPositionsQueue->empty() && termPositionsQueue->top()->doc() == _doc); + + posList->sort(); + _freq = posList->size(); - if (tp->skipTo(target)) - termPositionsQueue->add(tp); - else - tp->close(); + return true; +} + +int32_t MultipleTermPositions::nextPosition() { + return posList->next(); +} + +bool MultipleTermPositions::skipTo(int32_t target) { + while (termPositionsQueue->top() && target > termPositionsQueue->top()->doc()) { + TermPositionsPtr tp(termPositionsQueue->top()); + termPositionsQueue->pop(); + + if (tp->skipTo(target)) { + termPositionsQueue->add(tp); + } else { + tp->close(); } - return next(); } + return next(); +} - int32_t MultipleTermPositions::doc() - { - return _doc; - } +int32_t MultipleTermPositions::doc() { + return _doc; +} - int32_t MultipleTermPositions::freq() - { - return _freq; - } +int32_t MultipleTermPositions::freq() { + return _freq; +} - void MultipleTermPositions::close() - { - while (!termPositionsQueue->empty()) - termPositionsQueue->pop()->close(); +void MultipleTermPositions::close() { + while (!termPositionsQueue->empty()) { + termPositionsQueue->pop()->close(); } +} - void MultipleTermPositions::seek(const TermPtr& term) - { - boost::throw_exception(UnsupportedOperationException()); - } +void MultipleTermPositions::seek(const TermPtr& term) { + boost::throw_exception(UnsupportedOperationException()); +} - void MultipleTermPositions::seek(const TermEnumPtr& termEnum) - { - boost::throw_exception(UnsupportedOperationException()); - } +void MultipleTermPositions::seek(const TermEnumPtr& termEnum) { + boost::throw_exception(UnsupportedOperationException()); +} - int32_t MultipleTermPositions::read(Collection docs, Collection freqs) - { - boost::throw_exception(UnsupportedOperationException()); - return 0; - } +int32_t MultipleTermPositions::read(Collection docs, Collection freqs) { + boost::throw_exception(UnsupportedOperationException()); + return 0; +} - ByteArray MultipleTermPositions::getPayload(ByteArray data, int32_t offset) - { - boost::throw_exception(UnsupportedOperationException()); - return ByteArray(); - } +ByteArray MultipleTermPositions::getPayload(ByteArray data, int32_t offset) { + boost::throw_exception(UnsupportedOperationException()); + return ByteArray(); +} - bool MultipleTermPositions::isPayloadAvailable() - { - return false; - } +bool MultipleTermPositions::isPayloadAvailable() { + return false; +} - TermPositionsQueue::TermPositionsQueue(Collection termPositions) : PriorityQueue(termPositions.size()) - { - this->termPositions = termPositions; - } +TermPositionsQueue::TermPositionsQueue(Collection termPositions) : PriorityQueue(termPositions.size()) { + this->termPositions = termPositions; +} - TermPositionsQueue::~TermPositionsQueue() - { - } +TermPositionsQueue::~TermPositionsQueue() { +} - void TermPositionsQueue::initialize() - { - PriorityQueue::initialize(); - for (Collection::iterator tp = termPositions.begin(); tp != termPositions.end(); ++tp) - { - if ((*tp)->next()) - add(*tp); +void TermPositionsQueue::initialize() { + PriorityQueue::initialize(); + for (Collection::iterator tp = termPositions.begin(); tp != termPositions.end(); ++tp) { + if ((*tp)->next()) { + add(*tp); } } +} - bool TermPositionsQueue::lessThan(const TermPositionsPtr& first, const TermPositionsPtr& second) - { - return (first->doc() < second->doc()); - } +bool TermPositionsQueue::lessThan(const TermPositionsPtr& first, const TermPositionsPtr& second) { + return (first->doc() < second->doc()); +} - IntQueue::IntQueue() - { - arraySize = 16; - index = 0; - lastIndex = 0; - array = Collection::newInstance(arraySize); - } +IntQueue::IntQueue() { + arraySize = 16; + index = 0; + lastIndex = 0; + array = Collection::newInstance(arraySize); +} - IntQueue::~IntQueue() - { - } +IntQueue::~IntQueue() { +} - void IntQueue::add(int32_t i) - { - if (lastIndex == arraySize) - growArray(); - array[lastIndex++] = i; +void IntQueue::add(int32_t i) { + if (lastIndex == arraySize) { + growArray(); } + array[lastIndex++] = i; +} - int32_t IntQueue::next() - { - return array[index++]; - } +int32_t IntQueue::next() { + return array[index++]; +} - void IntQueue::sort() - { - std::sort(array.begin() + index, array.begin() + lastIndex); - } +void IntQueue::sort() { + std::sort(array.begin() + index, array.begin() + lastIndex); +} - void IntQueue::clear() - { - index = 0; - lastIndex = 0; - } +void IntQueue::clear() { + index = 0; + lastIndex = 0; +} - int32_t IntQueue::size() - { - return (lastIndex - index); - } +int32_t IntQueue::size() { + return (lastIndex - index); +} + +void IntQueue::growArray() { + array.resize(arraySize * 2); + arraySize *= 2; +} - void IntQueue::growArray() - { - array.resize(arraySize * 2); - arraySize *= 2; - } } diff --git a/src/core/index/NormsWriter.cpp b/src/core/index/NormsWriter.cpp index c7ef422a..54ef2a68 100644 --- a/src/core/index/NormsWriter.cpp +++ b/src/core/index/NormsWriter.cpp @@ -18,172 +18,151 @@ #include "FieldInfo.h" #include "Directory.h" -namespace Lucene -{ - NormsWriter::NormsWriter() - { - } +namespace Lucene { - NormsWriter::~NormsWriter() - { - } +NormsWriter::NormsWriter() { +} - uint8_t NormsWriter::getDefaultNorm() - { - static uint8_t defaultNorm = 0; - if (defaultNorm == 0) - defaultNorm = Similarity::encodeNorm(1.0); - return defaultNorm; - } +NormsWriter::~NormsWriter() { +} - InvertedDocEndConsumerPerThreadPtr NormsWriter::addThread(const DocInverterPerThreadPtr& docInverterPerThread) - { - return newLucene(docInverterPerThread, shared_from_this()); +uint8_t NormsWriter::getDefaultNorm() { + static uint8_t defaultNorm = 0; + if (defaultNorm == 0) { + defaultNorm = Similarity::encodeNorm(1.0); } + return defaultNorm; +} - void NormsWriter::abort() - { - } +InvertedDocEndConsumerPerThreadPtr NormsWriter::addThread(const DocInverterPerThreadPtr& docInverterPerThread) { + return newLucene(docInverterPerThread, shared_from_this()); +} - void NormsWriter::files(HashSet files) - { - } +void NormsWriter::abort() { +} - void NormsWriter::setFieldInfos(const FieldInfosPtr& fieldInfos) - { - this->fieldInfos = fieldInfos; - } +void NormsWriter::files(HashSet files) { +} - void NormsWriter::flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) - { - MapFieldInfoCollectionNormsWriterPerField byField(MapFieldInfoCollectionNormsWriterPerField::newInstance()); - - // Typically, each thread will have encountered the same field. So first we collate by field, ie all - // per-thread field instances that correspond to the same FieldInfo - for (MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) - { - for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end();) - { - NormsWriterPerFieldPtr normsPerField(boost::static_pointer_cast(*perField)); - if (normsPerField->upto > 0) - { - // It has some norms - Collection l = byField.get(normsPerField->fieldInfo); - if (!l) - { - l = Collection::newInstance(); - byField.put(normsPerField->fieldInfo, l); - } - l.add(normsPerField); - ++perField; - } - else - { - // Remove this field since we haven't seen it since the previous flush - perField = entry->second.remove(perField); +void NormsWriter::setFieldInfos(const FieldInfosPtr& fieldInfos) { + this->fieldInfos = fieldInfos; +} + +void NormsWriter::flush(MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { + MapFieldInfoCollectionNormsWriterPerField byField(MapFieldInfoCollectionNormsWriterPerField::newInstance()); + + // Typically, each thread will have encountered the same field. So first we collate by field, ie all + // per-thread field instances that correspond to the same FieldInfo + for (MapInvertedDocEndConsumerPerThreadCollectionInvertedDocEndConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end();) { + NormsWriterPerFieldPtr normsPerField(boost::static_pointer_cast(*perField)); + if (normsPerField->upto > 0) { + // It has some norms + Collection l = byField.get(normsPerField->fieldInfo); + if (!l) { + l = Collection::newInstance(); + byField.put(normsPerField->fieldInfo, l); } + l.add(normsPerField); + ++perField; + } else { + // Remove this field since we haven't seen it since the previous flush + perField = entry->second.remove(perField); } } + } - String normsFileName(state->segmentName + L"." + IndexFileNames::NORMS_EXTENSION()); - state->flushedFiles.add(normsFileName); - IndexOutputPtr normsOut(state->directory->createOutput(normsFileName)); + String normsFileName(state->segmentName + L"." + IndexFileNames::NORMS_EXTENSION()); + state->flushedFiles.add(normsFileName); + IndexOutputPtr normsOut(state->directory->createOutput(normsFileName)); - LuceneException finally; - try - { - normsOut->writeBytes(SegmentMerger::NORMS_HEADER, 0, SegmentMerger::NORMS_HEADER_LENGTH); + LuceneException finally; + try { + normsOut->writeBytes(SegmentMerger::NORMS_HEADER, 0, SegmentMerger::NORMS_HEADER_LENGTH); - int32_t numField = fieldInfos->size(); + int32_t numField = fieldInfos->size(); - int32_t normCount = 0; + int32_t normCount = 0; - for (int32_t fieldNumber = 0; fieldNumber < numField; ++fieldNumber) - { - FieldInfoPtr fieldInfo(fieldInfos->fieldInfo(fieldNumber)); + for (int32_t fieldNumber = 0; fieldNumber < numField; ++fieldNumber) { + FieldInfoPtr fieldInfo(fieldInfos->fieldInfo(fieldNumber)); - Collection toMerge = byField.get(fieldInfo); - int32_t upto = 0; + Collection toMerge = byField.get(fieldInfo); + int32_t upto = 0; - if (toMerge) - { - int32_t numFields = toMerge.size(); + if (toMerge) { + int32_t numFields = toMerge.size(); - ++normCount; + ++normCount; - Collection fields(Collection::newInstance(numFields)); - Collection uptos(Collection::newInstance(numFields)); + Collection fields(Collection::newInstance(numFields)); + Collection uptos(Collection::newInstance(numFields)); - for (int32_t j = 0; j < numFields; ++j) - fields[j] = toMerge[j]; + for (int32_t j = 0; j < numFields; ++j) { + fields[j] = toMerge[j]; + } - int32_t numLeft = numFields; + int32_t numLeft = numFields; - while (numLeft > 0) - { - BOOST_ASSERT(uptos[0] < fields[0]->docIDs.size()); + while (numLeft > 0) { + BOOST_ASSERT(uptos[0] < fields[0]->docIDs.size()); - int32_t minLoc = 0; - int32_t minDocID = fields[0]->docIDs[uptos[0]]; + int32_t minLoc = 0; + int32_t minDocID = fields[0]->docIDs[uptos[0]]; - for (int32_t j = 1; j < numLeft; ++j) - { - int32_t docID = fields[j]->docIDs[uptos[j]]; - if (docID < minDocID) - { - minDocID = docID; - minLoc = j; - } + for (int32_t j = 1; j < numLeft; ++j) { + int32_t docID = fields[j]->docIDs[uptos[j]]; + if (docID < minDocID) { + minDocID = docID; + minLoc = j; } + } + + BOOST_ASSERT(minDocID < state->numDocs); + + // Fill hole + for (; upto < minDocID; ++upto) { + normsOut->writeByte(getDefaultNorm()); + } - BOOST_ASSERT(minDocID < state->numDocs); - - // Fill hole - for (;upto < minDocID; ++upto) - normsOut->writeByte(getDefaultNorm()); - - normsOut->writeByte(fields[minLoc]->norms[uptos[minLoc]]); - ++(uptos[minLoc]); - ++upto; - - if (uptos[minLoc] == fields[minLoc]->upto) - { - fields[minLoc]->reset(); - if (minLoc != numLeft - 1) - { - fields[minLoc] = fields[numLeft - 1]; - uptos[minLoc] = uptos[numLeft - 1]; - } - --numLeft; + normsOut->writeByte(fields[minLoc]->norms[uptos[minLoc]]); + ++(uptos[minLoc]); + ++upto; + + if (uptos[minLoc] == fields[minLoc]->upto) { + fields[minLoc]->reset(); + if (minLoc != numLeft - 1) { + fields[minLoc] = fields[numLeft - 1]; + uptos[minLoc] = uptos[numLeft - 1]; } + --numLeft; } + } - // Fill final hole with defaultNorm - for (;upto < state->numDocs; ++upto) - normsOut->writeByte(getDefaultNorm()); + // Fill final hole with defaultNorm + for (; upto < state->numDocs; ++upto) { + normsOut->writeByte(getDefaultNorm()); } - else if (fieldInfo->isIndexed && !fieldInfo->omitNorms) - { - ++normCount; - // Fill entire field with default norm - for (;upto < state->numDocs; ++upto) - normsOut->writeByte(getDefaultNorm()); + } else if (fieldInfo->isIndexed && !fieldInfo->omitNorms) { + ++normCount; + // Fill entire field with default norm + for (; upto < state->numDocs; ++upto) { + normsOut->writeByte(getDefaultNorm()); } - - BOOST_ASSERT(4 + normCount * state->numDocs == normsOut->getFilePointer()); // .nrm file size mismatch? } + + BOOST_ASSERT(4 + normCount * state->numDocs == normsOut->getFilePointer()); // .nrm file size mismatch? } - catch (LuceneException& e) - { - finally = e; - } + } catch (LuceneException& e) { + finally = e; + } - normsOut->close(); + normsOut->close(); - finally.throwException(); - } + finally.throwException(); +} + +void NormsWriter::closeDocStore(const SegmentWriteStatePtr& state) { +} - void NormsWriter::closeDocStore(const SegmentWriteStatePtr& state) - { - } } diff --git a/src/core/index/NormsWriterPerField.cpp b/src/core/index/NormsWriterPerField.cpp index 488ae856..11377235 100644 --- a/src/core/index/NormsWriterPerField.cpp +++ b/src/core/index/NormsWriterPerField.cpp @@ -13,57 +13,50 @@ #include "FieldInfo.h" #include "MiscUtils.h" -namespace Lucene -{ - NormsWriterPerField::NormsWriterPerField(const DocInverterPerFieldPtr& docInverterPerField, const NormsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) - { - docIDs = Collection::newInstance(1); - norms = ByteArray::newInstance(1); - upto = 0; +namespace Lucene { - this->_perThread = perThread; - this->fieldInfo = fieldInfo; - docState = perThread->docState; - fieldState = docInverterPerField->fieldState; - } +NormsWriterPerField::NormsWriterPerField(const DocInverterPerFieldPtr& docInverterPerField, const NormsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { + docIDs = Collection::newInstance(1); + norms = ByteArray::newInstance(1); + upto = 0; - NormsWriterPerField::~NormsWriterPerField() - { - } + this->_perThread = perThread; + this->fieldInfo = fieldInfo; + docState = perThread->docState; + fieldState = docInverterPerField->fieldState; +} - void NormsWriterPerField::reset() - { - // Shrink back if we are over allocated now - docIDs.resize(MiscUtils::getShrinkSize(docIDs.size(), upto)); - norms.resize(MiscUtils::getShrinkSize(norms.size(), upto)); - upto = 0; - } +NormsWriterPerField::~NormsWriterPerField() { +} - void NormsWriterPerField::abort() - { - upto = 0; - } +void NormsWriterPerField::reset() { + // Shrink back if we are over allocated now + docIDs.resize(MiscUtils::getShrinkSize(docIDs.size(), upto)); + norms.resize(MiscUtils::getShrinkSize(norms.size(), upto)); + upto = 0; +} - int32_t NormsWriterPerField::compareTo(const LuceneObjectPtr& other) - { - return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); - } +void NormsWriterPerField::abort() { + upto = 0; +} + +int32_t NormsWriterPerField::compareTo(const LuceneObjectPtr& other) { + return fieldInfo->name.compare(boost::static_pointer_cast(other)->fieldInfo->name); +} - void NormsWriterPerField::finish() - { - BOOST_ASSERT(docIDs.size() == norms.size()); - if (fieldInfo->isIndexed && !fieldInfo->omitNorms) - { - if (docIDs.size() <= upto) - { - BOOST_ASSERT(docIDs.size() == upto); - docIDs.resize(MiscUtils::getNextSize(1 + upto)); - norms.resize(MiscUtils::getNextSize(1 + upto)); - } - double norm = docState->similarity->computeNorm(fieldInfo->name, fieldState); - norms[upto] = Similarity::encodeNorm(norm); - docIDs[upto] = docState->docID; - ++upto; +void NormsWriterPerField::finish() { + BOOST_ASSERT(docIDs.size() == norms.size()); + if (fieldInfo->isIndexed && !fieldInfo->omitNorms) { + if (docIDs.size() <= upto) { + BOOST_ASSERT(docIDs.size() == upto); + docIDs.resize(MiscUtils::getNextSize(1 + upto)); + norms.resize(MiscUtils::getNextSize(1 + upto)); } + double norm = docState->similarity->computeNorm(fieldInfo->name, fieldState); + norms[upto] = Similarity::encodeNorm(norm); + docIDs[upto] = docState->docID; + ++upto; } } + +} diff --git a/src/core/index/NormsWriterPerThread.cpp b/src/core/index/NormsWriterPerThread.cpp index 0dcdb03c..75b8fea7 100644 --- a/src/core/index/NormsWriterPerThread.cpp +++ b/src/core/index/NormsWriterPerThread.cpp @@ -9,37 +9,31 @@ #include "NormsWriterPerField.h" #include "DocInverterPerThread.h" -namespace Lucene -{ - NormsWriterPerThread::NormsWriterPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const NormsWriterPtr& normsWriter) - { - this->_normsWriter = normsWriter; - docState = docInverterPerThread->docState; - } - - NormsWriterPerThread::~NormsWriterPerThread() - { - } - - InvertedDocEndConsumerPerFieldPtr NormsWriterPerThread::addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) - { - return newLucene(docInverterPerField, shared_from_this(), fieldInfo); - } - - void NormsWriterPerThread::abort() - { - } - - void NormsWriterPerThread::startDocument() - { - } - - void NormsWriterPerThread::finishDocument() - { - } - - bool NormsWriterPerThread::freeRAM() - { - return false; - } +namespace Lucene { + +NormsWriterPerThread::NormsWriterPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const NormsWriterPtr& normsWriter) { + this->_normsWriter = normsWriter; + docState = docInverterPerThread->docState; +} + +NormsWriterPerThread::~NormsWriterPerThread() { +} + +InvertedDocEndConsumerPerFieldPtr NormsWriterPerThread::addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) { + return newLucene(docInverterPerField, shared_from_this(), fieldInfo); +} + +void NormsWriterPerThread::abort() { +} + +void NormsWriterPerThread::startDocument() { +} + +void NormsWriterPerThread::finishDocument() { +} + +bool NormsWriterPerThread::freeRAM() { + return false; +} + } diff --git a/src/core/index/ParallelReader.cpp b/src/core/index/ParallelReader.cpp index eabca996..fb258e1f 100644 --- a/src/core/index/ParallelReader.cpp +++ b/src/core/index/ParallelReader.cpp @@ -13,599 +13,529 @@ #include "FieldCache.h" #include "StringUtils.h" -namespace Lucene -{ - ParallelReader::ParallelReader(bool closeSubReaders) - { - this->readers = Collection::newInstance(); - this->decrefOnClose = Collection::newInstance(); - this->fieldToReader = MapStringIndexReader::newInstance(); - this->readerToFields = MapIndexReaderSetString::newInstance(); - this->storedFieldReaders = Collection::newInstance(); - this->_maxDoc = 0; - this->_numDocs = 0; - this->_hasDeletions = false; - - this->incRefReaders = !closeSubReaders; - } - - ParallelReader::~ParallelReader() - { - } - - void ParallelReader::add(const IndexReaderPtr& reader) - { - ensureOpen(); - add(reader, false); - } - - void ParallelReader::add(const IndexReaderPtr& reader, bool ignoreStoredFields) - { - ensureOpen(); - if (readers.empty()) - { - this->_maxDoc = reader->maxDoc(); - this->_numDocs = reader->numDocs(); - this->_hasDeletions = reader->hasDeletions(); - } +namespace Lucene { + +ParallelReader::ParallelReader(bool closeSubReaders) { + this->readers = Collection::newInstance(); + this->decrefOnClose = Collection::newInstance(); + this->fieldToReader = MapStringIndexReader::newInstance(); + this->readerToFields = MapIndexReaderSetString::newInstance(); + this->storedFieldReaders = Collection::newInstance(); + this->_maxDoc = 0; + this->_numDocs = 0; + this->_hasDeletions = false; + + this->incRefReaders = !closeSubReaders; +} - if (reader->maxDoc() != _maxDoc) // check compatibility - { - boost::throw_exception(IllegalArgumentException(L"All readers must have same maxDoc: " + StringUtils::toString(_maxDoc) + - L" != " + StringUtils::toString(reader->maxDoc()))); - } - if (reader->numDocs() != _numDocs) - { - boost::throw_exception(IllegalArgumentException(L"All readers must have same numDocs: " + StringUtils::toString(_numDocs) + - L" != " + StringUtils::toString(reader->numDocs()))); - } +ParallelReader::~ParallelReader() { +} - HashSet fields(reader->getFieldNames(IndexReader::FIELD_OPTION_ALL)); - readerToFields.put(reader, fields); - for (HashSet::iterator field = fields.begin(); field != fields.end(); ++field) // update fieldToReader map - { - if (!fieldToReader.contains(*field)) - fieldToReader.put(*field, reader); +void ParallelReader::add(const IndexReaderPtr& reader) { + ensureOpen(); + add(reader, false); +} + +void ParallelReader::add(const IndexReaderPtr& reader, bool ignoreStoredFields) { + ensureOpen(); + if (readers.empty()) { + this->_maxDoc = reader->maxDoc(); + this->_numDocs = reader->numDocs(); + this->_hasDeletions = reader->hasDeletions(); + } + + if (reader->maxDoc() != _maxDoc) { // check compatibility + boost::throw_exception(IllegalArgumentException(L"All readers must have same maxDoc: " + StringUtils::toString(_maxDoc) + + L" != " + StringUtils::toString(reader->maxDoc()))); + } + if (reader->numDocs() != _numDocs) { + boost::throw_exception(IllegalArgumentException(L"All readers must have same numDocs: " + StringUtils::toString(_numDocs) + + L" != " + StringUtils::toString(reader->numDocs()))); + } + + HashSet fields(reader->getFieldNames(IndexReader::FIELD_OPTION_ALL)); + readerToFields.put(reader, fields); + for (HashSet::iterator field = fields.begin(); field != fields.end(); ++field) { // update fieldToReader map + if (!fieldToReader.contains(*field)) { + fieldToReader.put(*field, reader); } + } - if (!ignoreStoredFields) - storedFieldReaders.add(reader); // add to storedFieldReaders - readers.add(reader); + if (!ignoreStoredFields) { + storedFieldReaders.add(reader); // add to storedFieldReaders + } + readers.add(reader); - if (incRefReaders) - reader->incRef(); + if (incRefReaders) { + reader->incRef(); + } - decrefOnClose.add(incRefReaders); + decrefOnClose.add(incRefReaders); +} + +LuceneObjectPtr ParallelReader::clone(const LuceneObjectPtr& other) { + SyncLock syncLock(this); + try { + return doReopen(true); + } catch (LuceneException& e) { + boost::throw_exception(RuntimeException(e.getError())); } + return LuceneObjectPtr(); +} - LuceneObjectPtr ParallelReader::clone(const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - try - { - return doReopen(true); - } - catch (LuceneException& e) - { - boost::throw_exception(RuntimeException(e.getError())); - } - return LuceneObjectPtr(); - } - - IndexReaderPtr ParallelReader::reopen() - { - SyncLock syncLock(this); - return doReopen(false); - } - - IndexReaderPtr ParallelReader::doReopen(bool doClone) - { - ensureOpen(); - - bool reopened = false; - Collection newReaders(Collection::newInstance()); - - bool success = false; - LuceneException finally; - try - { - for (Collection::iterator oldReader = readers.begin(); oldReader != readers.end(); ++oldReader) - { - IndexReaderPtr newReader; - if (doClone) - newReader = boost::dynamic_pointer_cast((*oldReader)->clone()); - else - newReader = (*oldReader)->reopen(); - newReaders.add(newReader); - // if at least one of the subreaders was updated we remember that and return a new ParallelReader - if (newReader != *oldReader) - reopened = true; +IndexReaderPtr ParallelReader::reopen() { + SyncLock syncLock(this); + return doReopen(false); +} + +IndexReaderPtr ParallelReader::doReopen(bool doClone) { + ensureOpen(); + + bool reopened = false; + Collection newReaders(Collection::newInstance()); + + bool success = false; + LuceneException finally; + try { + for (Collection::iterator oldReader = readers.begin(); oldReader != readers.end(); ++oldReader) { + IndexReaderPtr newReader; + if (doClone) { + newReader = boost::dynamic_pointer_cast((*oldReader)->clone()); + } else { + newReader = (*oldReader)->reopen(); + } + newReaders.add(newReader); + // if at least one of the subreaders was updated we remember that and return a new ParallelReader + if (newReader != *oldReader) { + reopened = true; } - success = true; - } - catch (LuceneException& e) - { - finally = e; } - if (!success && reopened) - { - for (int32_t i = 0; i < newReaders.size(); ++i) - { - if (newReaders[i] != readers[i]) - { - try - { - if (newReaders[i]) - newReaders[i]->close(); - } - catch (...) - { - // keep going - we want to clean up as much as possible + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success && reopened) { + for (int32_t i = 0; i < newReaders.size(); ++i) { + if (newReaders[i] != readers[i]) { + try { + if (newReaders[i]) { + newReaders[i]->close(); } + } catch (...) { + // keep going - we want to clean up as much as possible } } } - finally.throwException(); - - if (reopened) - { - Collection newDecrefOnClose(Collection::newInstance()); - ParallelReaderPtr pr(newLucene()); - for (int32_t i = 0; i < readers.size(); ++i) - { - IndexReaderPtr oldReader(readers[i]); - IndexReaderPtr newReader(newReaders[i]); - if (newReader == oldReader) - { - newDecrefOnClose.add(true); - newReader->incRef(); - } - else - { - // this is a new subreader instance, so on close() we don't decRef but close it - newDecrefOnClose.add(false); - } - pr->add(newReader, !storedFieldReaders.contains(oldReader)); + } + finally.throwException(); + + if (reopened) { + Collection newDecrefOnClose(Collection::newInstance()); + ParallelReaderPtr pr(newLucene()); + for (int32_t i = 0; i < readers.size(); ++i) { + IndexReaderPtr oldReader(readers[i]); + IndexReaderPtr newReader(newReaders[i]); + if (newReader == oldReader) { + newDecrefOnClose.add(true); + newReader->incRef(); + } else { + // this is a new subreader instance, so on close() we don't decRef but close it + newDecrefOnClose.add(false); } - pr->decrefOnClose = newDecrefOnClose; - pr->incRefReaders = incRefReaders; - return pr; - } - else - { - // No subreader was refreshed - return shared_from_this(); + pr->add(newReader, !storedFieldReaders.contains(oldReader)); } + pr->decrefOnClose = newDecrefOnClose; + pr->incRefReaders = incRefReaders; + return pr; + } else { + // No subreader was refreshed + return shared_from_this(); } +} - int32_t ParallelReader::numDocs() - { - // Don't call ensureOpen() here (it could affect performance) - return _numDocs; - } +int32_t ParallelReader::numDocs() { + // Don't call ensureOpen() here (it could affect performance) + return _numDocs; +} - int32_t ParallelReader::maxDoc() - { - // Don't call ensureOpen() here (it could affect performance) - return _maxDoc; - } +int32_t ParallelReader::maxDoc() { + // Don't call ensureOpen() here (it could affect performance) + return _maxDoc; +} - bool ParallelReader::hasDeletions() - { - // Don't call ensureOpen() here (it could affect performance) - return _hasDeletions; - } +bool ParallelReader::hasDeletions() { + // Don't call ensureOpen() here (it could affect performance) + return _hasDeletions; +} - bool ParallelReader::isDeleted(int32_t n) - { - // Don't call ensureOpen() here (it could affect performance) - return !readers.empty() ? readers[0]->isDeleted(n) : false; // check first reader - } +bool ParallelReader::isDeleted(int32_t n) { + // Don't call ensureOpen() here (it could affect performance) + return !readers.empty() ? readers[0]->isDeleted(n) : false; // check first reader +} - void ParallelReader::doDelete(int32_t docNum) - { - // delete in all readers - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - (*reader)->deleteDocument(docNum); - _hasDeletions = true; +void ParallelReader::doDelete(int32_t docNum) { + // delete in all readers + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + (*reader)->deleteDocument(docNum); } + _hasDeletions = true; +} - void ParallelReader::doUndeleteAll() - { - // undeleteAll in all readers - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - (*reader)->undeleteAll(); - _hasDeletions = false; +void ParallelReader::doUndeleteAll() { + // undeleteAll in all readers + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + (*reader)->undeleteAll(); } + _hasDeletions = false; +} - DocumentPtr ParallelReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) - { - ensureOpen(); - DocumentPtr result(newLucene()); - - // append fields from storedFieldReaders - for (Collection::iterator reader = storedFieldReaders.begin(); reader != storedFieldReaders.end(); ++reader) - { - bool include = !fieldSelector; - if (!include) - { - HashSet fields = readerToFields.get(*reader); - for (HashSet::iterator field = fields.begin(); field != fields.end(); ++field) - { - if (fieldSelector->accept(*field) != FieldSelector::SELECTOR_NO_LOAD) - { - include = true; - break; - } +DocumentPtr ParallelReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { + ensureOpen(); + DocumentPtr result(newLucene()); + + // append fields from storedFieldReaders + for (Collection::iterator reader = storedFieldReaders.begin(); reader != storedFieldReaders.end(); ++reader) { + bool include = !fieldSelector; + if (!include) { + HashSet fields = readerToFields.get(*reader); + for (HashSet::iterator field = fields.begin(); field != fields.end(); ++field) { + if (fieldSelector->accept(*field) != FieldSelector::SELECTOR_NO_LOAD) { + include = true; + break; } } - if (include) - { - Collection fields((*reader)->document(n, fieldSelector)->getFields()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - result->add(*field); + } + if (include) { + Collection fields((*reader)->document(n, fieldSelector)->getFields()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + result->add(*field); } } - return result; } + return result; +} - Collection ParallelReader::getTermFreqVectors(int32_t docNumber) - { - ensureOpen(); +Collection ParallelReader::getTermFreqVectors(int32_t docNumber) { + ensureOpen(); - Collection results(Collection::newInstance()); + Collection results(Collection::newInstance()); - // get all vectors - for (MapStringIndexReader::iterator entry = fieldToReader.begin(); entry != fieldToReader.end(); ++entry) - { - TermFreqVectorPtr vector(entry->second->getTermFreqVector(docNumber, entry->first)); - if (vector) - results.add(vector); + // get all vectors + for (MapStringIndexReader::iterator entry = fieldToReader.begin(); entry != fieldToReader.end(); ++entry) { + TermFreqVectorPtr vector(entry->second->getTermFreqVector(docNumber, entry->first)); + if (vector) { + results.add(vector); } - - return results; } - TermFreqVectorPtr ParallelReader::getTermFreqVector(int32_t docNumber, const String& field) - { - ensureOpen(); - MapStringIndexReader::iterator reader = fieldToReader.find(field); - return reader == fieldToReader.end() ? TermFreqVectorPtr() : reader->second->getTermFreqVector(docNumber, field); - } + return results; +} - void ParallelReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - MapStringIndexReader::iterator reader = fieldToReader.find(field); - if (reader != fieldToReader.end()) - reader->second->getTermFreqVector(docNumber, field, mapper); - } +TermFreqVectorPtr ParallelReader::getTermFreqVector(int32_t docNumber, const String& field) { + ensureOpen(); + MapStringIndexReader::iterator reader = fieldToReader.find(field); + return reader == fieldToReader.end() ? TermFreqVectorPtr() : reader->second->getTermFreqVector(docNumber, field); +} - void ParallelReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - for (MapStringIndexReader::iterator entry = fieldToReader.begin(); entry != fieldToReader.end(); ++entry) - entry->second->getTermFreqVector(docNumber, entry->first, mapper); +void ParallelReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { + ensureOpen(); + MapStringIndexReader::iterator reader = fieldToReader.find(field); + if (reader != fieldToReader.end()) { + reader->second->getTermFreqVector(docNumber, field, mapper); } +} - bool ParallelReader::hasNorms(const String& field) - { - ensureOpen(); - MapStringIndexReader::iterator reader = fieldToReader.find(field); - return reader == fieldToReader.end() ? false : reader->second->hasNorms(field); +void ParallelReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { + ensureOpen(); + for (MapStringIndexReader::iterator entry = fieldToReader.begin(); entry != fieldToReader.end(); ++entry) { + entry->second->getTermFreqVector(docNumber, entry->first, mapper); } +} - ByteArray ParallelReader::norms(const String& field) - { - ensureOpen(); - MapStringIndexReader::iterator reader = fieldToReader.find(field); - return reader == fieldToReader.end() ? ByteArray() : reader->second->norms(field); - } +bool ParallelReader::hasNorms(const String& field) { + ensureOpen(); + MapStringIndexReader::iterator reader = fieldToReader.find(field); + return reader == fieldToReader.end() ? false : reader->second->hasNorms(field); +} - void ParallelReader::norms(const String& field, ByteArray norms, int32_t offset) - { - ensureOpen(); - MapStringIndexReader::iterator reader = fieldToReader.find(field); - if (reader != fieldToReader.end()) - reader->second->norms(field, norms, offset); - } +ByteArray ParallelReader::norms(const String& field) { + ensureOpen(); + MapStringIndexReader::iterator reader = fieldToReader.find(field); + return reader == fieldToReader.end() ? ByteArray() : reader->second->norms(field); +} - void ParallelReader::doSetNorm(int32_t doc, const String& field, uint8_t value) - { - ensureOpen(); - MapStringIndexReader::iterator reader = fieldToReader.find(field); - if (reader != fieldToReader.end()) - reader->second->doSetNorm(doc, field, value); +void ParallelReader::norms(const String& field, ByteArray norms, int32_t offset) { + ensureOpen(); + MapStringIndexReader::iterator reader = fieldToReader.find(field); + if (reader != fieldToReader.end()) { + reader->second->norms(field, norms, offset); } +} - TermEnumPtr ParallelReader::terms() - { - ensureOpen(); - return newLucene(shared_from_this()); +void ParallelReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { + ensureOpen(); + MapStringIndexReader::iterator reader = fieldToReader.find(field); + if (reader != fieldToReader.end()) { + reader->second->doSetNorm(doc, field, value); } +} - TermEnumPtr ParallelReader::terms(const TermPtr& t) - { - ensureOpen(); - return newLucene(shared_from_this(), t); - } +TermEnumPtr ParallelReader::terms() { + ensureOpen(); + return newLucene(shared_from_this()); +} - int32_t ParallelReader::docFreq(const TermPtr& t) - { - ensureOpen(); - MapStringIndexReader::iterator reader = fieldToReader.find(t->field()); - return reader == fieldToReader.end() ? 0 : reader->second->docFreq(t); - } +TermEnumPtr ParallelReader::terms(const TermPtr& t) { + ensureOpen(); + return newLucene(shared_from_this(), t); +} - TermDocsPtr ParallelReader::termDocs(const TermPtr& term) - { - ensureOpen(); - return newLucene(shared_from_this(), term); - } +int32_t ParallelReader::docFreq(const TermPtr& t) { + ensureOpen(); + MapStringIndexReader::iterator reader = fieldToReader.find(t->field()); + return reader == fieldToReader.end() ? 0 : reader->second->docFreq(t); +} - TermDocsPtr ParallelReader::termDocs() - { - ensureOpen(); - return newLucene(shared_from_this()); - } +TermDocsPtr ParallelReader::termDocs(const TermPtr& term) { + ensureOpen(); + return newLucene(shared_from_this(), term); +} - TermPositionsPtr ParallelReader::termPositions(const TermPtr& term) - { - ensureOpen(); - return newLucene(shared_from_this(), term); - } +TermDocsPtr ParallelReader::termDocs() { + ensureOpen(); + return newLucene(shared_from_this()); +} - TermPositionsPtr ParallelReader::termPositions() - { - ensureOpen(); - return newLucene(shared_from_this()); - } +TermPositionsPtr ParallelReader::termPositions(const TermPtr& term) { + ensureOpen(); + return newLucene(shared_from_this(), term); +} - bool ParallelReader::isCurrent() - { - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - if (!(*reader)->isCurrent()) - return false; - } +TermPositionsPtr ParallelReader::termPositions() { + ensureOpen(); + return newLucene(shared_from_this()); +} - // all subreaders are up to date - return true; +bool ParallelReader::isCurrent() { + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + if (!(*reader)->isCurrent()) { + return false; + } } - bool ParallelReader::isOptimized() - { - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - if (!(*reader)->isOptimized()) - return false; - } + // all subreaders are up to date + return true; +} - // all subindexes are optimized - return true; +bool ParallelReader::isOptimized() { + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + if (!(*reader)->isOptimized()) { + return false; + } } - int64_t ParallelReader::getVersion() - { - boost::throw_exception(UnsupportedOperationException(L"ParallelReader does not support this method.")); - return 0; - } + // all subindexes are optimized + return true; +} - Collection ParallelReader::getSubReaders() - { - return readers; - } +int64_t ParallelReader::getVersion() { + boost::throw_exception(UnsupportedOperationException(L"ParallelReader does not support this method.")); + return 0; +} + +Collection ParallelReader::getSubReaders() { + return readers; +} - void ParallelReader::doCommit(MapStringString commitUserData) - { - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - (*reader)->commit(commitUserData); +void ParallelReader::doCommit(MapStringString commitUserData) { + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + (*reader)->commit(commitUserData); } +} - void ParallelReader::doClose() - { - SyncLock syncLock(this); - for (int32_t i = 0; i < readers.size(); ++i) - { - if (decrefOnClose[i]) - readers[i]->decRef(); - else - readers[i]->close(); +void ParallelReader::doClose() { + SyncLock syncLock(this); + for (int32_t i = 0; i < readers.size(); ++i) { + if (decrefOnClose[i]) { + readers[i]->decRef(); + } else { + readers[i]->close(); } - - FieldCache::DEFAULT()->purge(shared_from_this()); } - HashSet ParallelReader::getFieldNames(FieldOption fieldOption) - { - ensureOpen(); - HashSet fieldSet(HashSet::newInstance()); - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - HashSet names((*reader)->getFieldNames(fieldOption)); - fieldSet.addAll(names.begin(), names.end()); - } - return fieldSet; + FieldCache::DEFAULT()->purge(shared_from_this()); +} + +HashSet ParallelReader::getFieldNames(FieldOption fieldOption) { + ensureOpen(); + HashSet fieldSet(HashSet::newInstance()); + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + HashSet names((*reader)->getFieldNames(fieldOption)); + fieldSet.addAll(names.begin(), names.end()); } + return fieldSet; +} - ParallelTermEnum::ParallelTermEnum(const ParallelReaderPtr& reader) - { - this->setIterator = false; - this->_reader = reader; - MapStringIndexReader::iterator indexReader = reader->fieldToReader.begin(); - if (indexReader != reader->fieldToReader.end()) - this->field = indexReader->first; - if (!field.empty()) - this->termEnum = reader->fieldToReader[field]->terms(); +ParallelTermEnum::ParallelTermEnum(const ParallelReaderPtr& reader) { + this->setIterator = false; + this->_reader = reader; + MapStringIndexReader::iterator indexReader = reader->fieldToReader.begin(); + if (indexReader != reader->fieldToReader.end()) { + this->field = indexReader->first; + } + if (!field.empty()) { + this->termEnum = reader->fieldToReader[field]->terms(); } +} - ParallelTermEnum::ParallelTermEnum(const ParallelReaderPtr& reader, const TermPtr& term) - { - this->setIterator = false; - this->_reader = reader; - this->field = term->field(); - MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(field); - if (indexReader != reader->fieldToReader.end()) - this->termEnum = indexReader->second->terms(term); +ParallelTermEnum::ParallelTermEnum(const ParallelReaderPtr& reader, const TermPtr& term) { + this->setIterator = false; + this->_reader = reader; + this->field = term->field(); + MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(field); + if (indexReader != reader->fieldToReader.end()) { + this->termEnum = indexReader->second->terms(term); } +} - ParallelTermEnum::~ParallelTermEnum() - { +ParallelTermEnum::~ParallelTermEnum() { +} + +bool ParallelTermEnum::next() { + if (!termEnum) { + return false; } - bool ParallelTermEnum::next() - { - if (!termEnum) - return false; + // another term in this field? + if (termEnum->next() && termEnum->term()->field() == field) { + return true; // yes, keep going + } - // another term in this field? - if (termEnum->next() && termEnum->term()->field() == field) - return true; // yes, keep going + termEnum->close(); // close old termEnum + ParallelReaderPtr reader(_reader); - termEnum->close(); // close old termEnum - ParallelReaderPtr reader(_reader); + // find the next field with terms, if any + if (!setIterator) { + fieldIterator = reader->fieldToReader.find(field); + ++fieldIterator; // Skip field to get next one + setIterator = false; + } - // find the next field with terms, if any - if (!setIterator) - { - fieldIterator = reader->fieldToReader.find(field); - ++fieldIterator; // Skip field to get next one - setIterator = false; + while (fieldIterator != reader->fieldToReader.end()) { + field = fieldIterator->first; + termEnum = fieldIterator->second->terms(newLucene(field)); + ++fieldIterator; + TermPtr term(termEnum->term()); + if (term && term->field() == field) { + return true; + } else { + termEnum->close(); } + } - while (fieldIterator != reader->fieldToReader.end()) - { - field = fieldIterator->first; - termEnum = fieldIterator->second->terms(newLucene(field)); - ++fieldIterator; - TermPtr term(termEnum->term()); - if (term && term->field() == field) - return true; - else - termEnum->close(); - } + return false; // no more fields +} - return false; // no more fields - } +TermPtr ParallelTermEnum::term() { + return termEnum ? termEnum->term() : TermPtr(); +} - TermPtr ParallelTermEnum::term() - { - return termEnum ? termEnum->term() : TermPtr(); - } +int32_t ParallelTermEnum::docFreq() { + return termEnum ? termEnum->docFreq() : 0; +} - int32_t ParallelTermEnum::docFreq() - { - return termEnum ? termEnum->docFreq() : 0; +void ParallelTermEnum::close() { + if (termEnum) { + termEnum->close(); } +} - void ParallelTermEnum::close() - { - if (termEnum) - termEnum->close(); - } +ParallelTermDocs::ParallelTermDocs(const ParallelReaderPtr& reader) { + this->_reader = reader; +} - ParallelTermDocs::ParallelTermDocs(const ParallelReaderPtr& reader) - { - this->_reader = reader; +ParallelTermDocs::ParallelTermDocs(const ParallelReaderPtr& reader, const TermPtr& term) { + this->_reader = reader; + if (!term) { + termDocs = reader->readers.empty() ? TermDocsPtr() : reader->readers[0]->termDocs(TermPtr()); + } else { + seek(term); } +} - ParallelTermDocs::ParallelTermDocs(const ParallelReaderPtr& reader, const TermPtr& term) - { - this->_reader = reader; - if (!term) - termDocs = reader->readers.empty() ? TermDocsPtr() : reader->readers[0]->termDocs(TermPtr()); - else - seek(term); - } +ParallelTermDocs::~ParallelTermDocs() { +} - ParallelTermDocs::~ParallelTermDocs() - { - } +int32_t ParallelTermDocs::doc() { + return termDocs->doc(); +} - int32_t ParallelTermDocs::doc() - { - return termDocs->doc(); - } +int32_t ParallelTermDocs::freq() { + return termDocs->freq(); +} - int32_t ParallelTermDocs::freq() - { - return termDocs->freq(); - } +void ParallelTermDocs::seek(const TermPtr& term) { + ParallelReaderPtr reader(_reader); + MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); + termDocs = indexReader != reader->fieldToReader.end() ? indexReader->second->termDocs(term) : TermDocsPtr(); +} - void ParallelTermDocs::seek(const TermPtr& term) - { - ParallelReaderPtr reader(_reader); - MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); - termDocs = indexReader != reader->fieldToReader.end() ? indexReader->second->termDocs(term) : TermDocsPtr(); - } +void ParallelTermDocs::seek(const TermEnumPtr& termEnum) { + seek(termEnum->term()); +} - void ParallelTermDocs::seek(const TermEnumPtr& termEnum) - { - seek(termEnum->term()); - } +bool ParallelTermDocs::next() { + return termDocs ? termDocs->next() : false; +} - bool ParallelTermDocs::next() - { - return termDocs ? termDocs->next() : false; - } +int32_t ParallelTermDocs::read(Collection docs, Collection freqs) { + return termDocs ? termDocs->read(docs, freqs) : 0; +} - int32_t ParallelTermDocs::read(Collection docs, Collection freqs) - { - return termDocs ? termDocs->read(docs, freqs) : 0; - } +bool ParallelTermDocs::skipTo(int32_t target) { + return termDocs ? termDocs->skipTo(target) : false; +} - bool ParallelTermDocs::skipTo(int32_t target) - { - return termDocs ? termDocs->skipTo(target) : false; +void ParallelTermDocs::close() { + if (termDocs) { + termDocs->close(); } +} - void ParallelTermDocs::close() - { - if (termDocs) - termDocs->close(); - } +ParallelTermPositions::ParallelTermPositions(const ParallelReaderPtr& reader) : ParallelTermDocs(reader) { +} - ParallelTermPositions::ParallelTermPositions(const ParallelReaderPtr& reader) : ParallelTermDocs(reader) - { - } +ParallelTermPositions::ParallelTermPositions(const ParallelReaderPtr& reader, const TermPtr& term) : ParallelTermDocs(reader) { + seek(term); +} - ParallelTermPositions::ParallelTermPositions(const ParallelReaderPtr& reader, const TermPtr& term) : ParallelTermDocs(reader) - { - seek(term); - } +ParallelTermPositions::~ParallelTermPositions() { +} - ParallelTermPositions::~ParallelTermPositions() - { - } +void ParallelTermPositions::seek(const TermPtr& term) { + ParallelReaderPtr reader(_reader); + MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); + termDocs = indexReader != reader->fieldToReader.end() ? indexReader->second->termPositions(term) : TermDocsPtr(); +} - void ParallelTermPositions::seek(const TermPtr& term) - { - ParallelReaderPtr reader(_reader); - MapStringIndexReader::iterator indexReader = reader->fieldToReader.find(term->field()); - termDocs = indexReader != reader->fieldToReader.end() ? indexReader->second->termPositions(term) : TermDocsPtr(); - } +int32_t ParallelTermPositions::nextPosition() { + // It is an error to call this if there is no next position, eg. if termDocs==null + return boost::static_pointer_cast(termDocs)->nextPosition(); +} - int32_t ParallelTermPositions::nextPosition() - { - // It is an error to call this if there is no next position, eg. if termDocs==null - return boost::static_pointer_cast(termDocs)->nextPosition(); - } +int32_t ParallelTermPositions::getPayloadLength() { + // It is an error to call this if there is no next position, eg. if termDocs==null + return boost::static_pointer_cast(termDocs)->getPayloadLength(); +} - int32_t ParallelTermPositions::getPayloadLength() - { - // It is an error to call this if there is no next position, eg. if termDocs==null - return boost::static_pointer_cast(termDocs)->getPayloadLength(); - } +ByteArray ParallelTermPositions::getPayload(ByteArray data, int32_t offset) { + // It is an error to call this if there is no next position, eg. if termDocs==null + return boost::static_pointer_cast(termDocs)->getPayload(data, offset); +} - ByteArray ParallelTermPositions::getPayload(ByteArray data, int32_t offset) - { - // It is an error to call this if there is no next position, eg. if termDocs==null - return boost::static_pointer_cast(termDocs)->getPayload(data, offset); - } +bool ParallelTermPositions::isPayloadAvailable() { + // It is an error to call this if there is no next position, eg. if termDocs==null + return boost::static_pointer_cast(termDocs)->isPayloadAvailable(); +} - bool ParallelTermPositions::isPayloadAvailable() - { - // It is an error to call this if there is no next position, eg. if termDocs==null - return boost::static_pointer_cast(termDocs)->isPayloadAvailable(); - } } diff --git a/src/core/index/Payload.cpp b/src/core/index/Payload.cpp index 379bc663..1b01e978 100644 --- a/src/core/index/Payload.cpp +++ b/src/core/index/Payload.cpp @@ -8,126 +8,113 @@ #include "Payload.h" #include "MiscUtils.h" -namespace Lucene -{ - Payload::Payload() - { - this->offset = 0; - this->_length = 0; - } +namespace Lucene { - Payload::Payload(ByteArray data) - { - this->data = data; - this->offset = 0; - this->_length = data.size(); - } +Payload::Payload() { + this->offset = 0; + this->_length = 0; +} - Payload::Payload(ByteArray data, int32_t offset, int32_t length) - { - if (offset < 0 || offset + length > data.size()) - boost::throw_exception(IllegalArgumentException()); - this->data = data; - this->offset = offset; - this->_length = length; - } +Payload::Payload(ByteArray data) { + this->data = data; + this->offset = 0; + this->_length = data.size(); +} - Payload::~Payload() - { +Payload::Payload(ByteArray data, int32_t offset, int32_t length) { + if (offset < 0 || offset + length > data.size()) { + boost::throw_exception(IllegalArgumentException()); } + this->data = data; + this->offset = offset; + this->_length = length; +} - void Payload::setData(ByteArray data) - { - setData(data, 0, data.size()); - } +Payload::~Payload() { +} - void Payload::setData(ByteArray data, int32_t offset, int32_t length) - { - this->data = data; - this->offset = offset; - this->_length = length; - } +void Payload::setData(ByteArray data) { + setData(data, 0, data.size()); +} - ByteArray Payload::getData() - { - return this->data; - } +void Payload::setData(ByteArray data, int32_t offset, int32_t length) { + this->data = data; + this->offset = offset; + this->_length = length; +} - int32_t Payload::getOffset() - { - return this->offset; - } +ByteArray Payload::getData() { + return this->data; +} - int32_t Payload::length() - { - return this->_length; +int32_t Payload::getOffset() { + return this->offset; +} + +int32_t Payload::length() { + return this->_length; +} + +uint8_t Payload::byteAt(int32_t index) { + if (0 <= index && index < this->_length) { + return this->data[this->offset + index]; } + boost::throw_exception(IndexOutOfBoundsException()); + return 0; +} - uint8_t Payload::byteAt(int32_t index) - { - if (0 <= index && index < this->_length) - return this->data[this->offset + index]; +ByteArray Payload::toByteArray() { + ByteArray retArray(ByteArray::newInstance(this->_length)); + MiscUtils::arrayCopy(this->data.get(), this->offset, retArray.get(), 0, this->_length); + return retArray; +} + +void Payload::copyTo(ByteArray target, int32_t targetOffset) { + if (this->_length > target.size() + targetOffset) { boost::throw_exception(IndexOutOfBoundsException()); - return 0; } + MiscUtils::arrayCopy(this->data.get(), this->offset, target.get(), targetOffset, this->_length); +} - ByteArray Payload::toByteArray() - { - ByteArray retArray(ByteArray::newInstance(this->_length)); - MiscUtils::arrayCopy(this->data.get(), this->offset, retArray.get(), 0, this->_length); - return retArray; +LuceneObjectPtr Payload::clone(const LuceneObjectPtr& other) { + // Start with a shallow copy of data + LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); + PayloadPtr clonePayload(boost::dynamic_pointer_cast(clone)); + clonePayload->offset = offset; + clonePayload->_length = _length; + + // Only copy the part of data that belongs to this Payload + if (offset == 0 && _length == data.size()) { + // It is the whole thing, so just clone it. + clonePayload->data = ByteArray::newInstance(data.size()); + MiscUtils::arrayCopy(data.get(), 0, clonePayload->data.get(), 0, data.size()); + } else { + // Just get the part + clonePayload->data = toByteArray(); + clonePayload->offset = 0; } + return clonePayload; +} - void Payload::copyTo(ByteArray target, int32_t targetOffset) - { - if (this->_length > target.size() + targetOffset) - boost::throw_exception(IndexOutOfBoundsException()); - MiscUtils::arrayCopy(this->data.get(), this->offset, target.get(), targetOffset, this->_length); +bool Payload::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - LuceneObjectPtr Payload::clone(const LuceneObjectPtr& other) - { - // Start with a shallow copy of data - LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); - PayloadPtr clonePayload(boost::dynamic_pointer_cast(clone)); - clonePayload->offset = offset; - clonePayload->_length = _length; - - // Only copy the part of data that belongs to this Payload - if (offset == 0 && _length == data.size()) - { - // It is the whole thing, so just clone it. - clonePayload->data = ByteArray::newInstance(data.size()); - MiscUtils::arrayCopy(data.get(), 0, clonePayload->data.get(), 0, data.size()); - } - else - { - // Just get the part - clonePayload->data = toByteArray(); - clonePayload->offset = 0; + PayloadPtr otherPayload(boost::dynamic_pointer_cast(other)); + if (otherPayload) { + if (_length == otherPayload->_length) { + return (std::memcmp(data.get(), otherPayload->data.get(), _length) == 0); + } else { + return false; } - return clonePayload; } - bool Payload::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - - PayloadPtr otherPayload(boost::dynamic_pointer_cast(other)); - if (otherPayload) - { - if (_length == otherPayload->_length) - return (std::memcmp(data.get(), otherPayload->data.get(), _length) == 0); - else - return false; - } + return false; +} - return false; - } +int32_t Payload::hashCode() { + return MiscUtils::hashCode(data.get(), offset, offset + _length); +} - int32_t Payload::hashCode() - { - return MiscUtils::hashCode(data.get(), offset, offset + _length); - } } diff --git a/src/core/index/PositionBasedTermVectorMapper.cpp b/src/core/index/PositionBasedTermVectorMapper.cpp index cff9665a..3bb8ddeb 100644 --- a/src/core/index/PositionBasedTermVectorMapper.cpp +++ b/src/core/index/PositionBasedTermVectorMapper.cpp @@ -7,87 +7,76 @@ #include "LuceneInc.h" #include "PositionBasedTermVectorMapper.h" -namespace Lucene -{ - PositionBasedTermVectorMapper::PositionBasedTermVectorMapper(bool ignoringOffsets) : TermVectorMapper(false, ignoringOffsets) - { - storeOffsets = false; - } +namespace Lucene { - PositionBasedTermVectorMapper::~PositionBasedTermVectorMapper() - { - } +PositionBasedTermVectorMapper::PositionBasedTermVectorMapper(bool ignoringOffsets) : TermVectorMapper(false, ignoringOffsets) { + storeOffsets = false; +} - bool PositionBasedTermVectorMapper::isIgnoringPositions() - { - return false; - } +PositionBasedTermVectorMapper::~PositionBasedTermVectorMapper() { +} - void PositionBasedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) - { - for (int32_t i = 0; i < positions.size(); ++i) - { - TermVectorsPositionInfoPtr pos(currentPositions.get(positions[i])); - if (!pos) - { - pos = newLucene(positions[i], storeOffsets); - currentPositions.put(positions[i], pos); - } - pos->addTerm(term, offsets ? offsets[i] : TermVectorOffsetInfoPtr()); - } - } +bool PositionBasedTermVectorMapper::isIgnoringPositions() { + return false; +} - void PositionBasedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) - { - if (storePositions == false) - boost::throw_exception(RuntimeException(L"You must store positions in order to use this Mapper")); - if (storeOffsets == true) - { - // ignoring offsets +void PositionBasedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { + for (int32_t i = 0; i < positions.size(); ++i) { + TermVectorsPositionInfoPtr pos(currentPositions.get(positions[i])); + if (!pos) { + pos = newLucene(positions[i], storeOffsets); + currentPositions.put(positions[i], pos); } - this->fieldToTerms = MapStringMapIntTermVectorsPositionInfo::newInstance(); - this->storeOffsets = storeOffsets; - currentField = field; - this->currentPositions = MapIntTermVectorsPositionInfo::newInstance(); - fieldToTerms.put(currentField, currentPositions); + pos->addTerm(term, offsets ? offsets[i] : TermVectorOffsetInfoPtr()); } +} - MapStringMapIntTermVectorsPositionInfo PositionBasedTermVectorMapper::getFieldToTerms() - { - return fieldToTerms; +void PositionBasedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { + if (storePositions == false) { + boost::throw_exception(RuntimeException(L"You must store positions in order to use this Mapper")); } - - TermVectorsPositionInfo::TermVectorsPositionInfo(int32_t position, bool storeOffsets) - { - this->position = position; - this->terms = Collection::newInstance(); - if (storeOffsets) - offsets = Collection::newInstance(); + if (storeOffsets == true) { + // ignoring offsets } + this->fieldToTerms = MapStringMapIntTermVectorsPositionInfo::newInstance(); + this->storeOffsets = storeOffsets; + currentField = field; + this->currentPositions = MapIntTermVectorsPositionInfo::newInstance(); + fieldToTerms.put(currentField, currentPositions); +} - TermVectorsPositionInfo::~TermVectorsPositionInfo() - { - } +MapStringMapIntTermVectorsPositionInfo PositionBasedTermVectorMapper::getFieldToTerms() { + return fieldToTerms; +} - void TermVectorsPositionInfo::addTerm(const String& term, const TermVectorOffsetInfoPtr& info) - { - terms.add(term); - if (offsets) - offsets.add(info); +TermVectorsPositionInfo::TermVectorsPositionInfo(int32_t position, bool storeOffsets) { + this->position = position; + this->terms = Collection::newInstance(); + if (storeOffsets) { + offsets = Collection::newInstance(); } +} - int32_t TermVectorsPositionInfo::getPosition() - { - return position; - } +TermVectorsPositionInfo::~TermVectorsPositionInfo() { +} - Collection TermVectorsPositionInfo::getTerms() - { - return terms; +void TermVectorsPositionInfo::addTerm(const String& term, const TermVectorOffsetInfoPtr& info) { + terms.add(term); + if (offsets) { + offsets.add(info); } +} + +int32_t TermVectorsPositionInfo::getPosition() { + return position; +} + +Collection TermVectorsPositionInfo::getTerms() { + return terms; +} + +Collection TermVectorsPositionInfo::getOffsets() { + return offsets; +} - Collection TermVectorsPositionInfo::getOffsets() - { - return offsets; - } } diff --git a/src/core/index/RawPostingList.cpp b/src/core/index/RawPostingList.cpp index 6f5eac3d..251f1096 100644 --- a/src/core/index/RawPostingList.cpp +++ b/src/core/index/RawPostingList.cpp @@ -8,18 +8,17 @@ #include "RawPostingList.h" #include "DocumentsWriter.h" -namespace Lucene -{ - const int32_t RawPostingList::BYTES_SIZE = DocumentsWriter::OBJECT_HEADER_BYTES + 3 * DocumentsWriter::INT_NUM_BYTE; +namespace Lucene { - RawPostingList::RawPostingList() - { - textStart = 0; - intStart = 0; - byteStart = 0; - } +const int32_t RawPostingList::BYTES_SIZE = DocumentsWriter::OBJECT_HEADER_BYTES + 3 * DocumentsWriter::INT_NUM_BYTE; + +RawPostingList::RawPostingList() { + textStart = 0; + intStart = 0; + byteStart = 0; +} + +RawPostingList::~RawPostingList() { +} - RawPostingList::~RawPostingList() - { - } } diff --git a/src/core/index/ReadOnlyDirectoryReader.cpp b/src/core/index/ReadOnlyDirectoryReader.cpp index 2fd2d2c0..3c7da5e7 100644 --- a/src/core/index/ReadOnlyDirectoryReader.cpp +++ b/src/core/index/ReadOnlyDirectoryReader.cpp @@ -8,33 +8,29 @@ #include "ReadOnlyDirectoryReader.h" #include "ReadOnlySegmentReader.h" -namespace Lucene -{ - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, - const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor) : - DirectoryReader(directory, sis, deletionPolicy, true, termInfosIndexDivisor) - { - } - - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, - Collection oldReaders, Collection oldStarts, - MapStringByteArray oldNormsCache, bool doClone, - int32_t termInfosIndexDivisor) : - DirectoryReader(directory, infos, oldReaders, oldStarts, oldNormsCache, true, doClone, termInfosIndexDivisor) - { - } - - ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor) : - DirectoryReader(writer, infos, termInfosIndexDivisor) - { - } - - ReadOnlyDirectoryReader::~ReadOnlyDirectoryReader() - { - } - - void ReadOnlyDirectoryReader::acquireWriteLock() - { - ReadOnlySegmentReader::noWrite(); - } +namespace Lucene { + +ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, + const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor) : + DirectoryReader(directory, sis, deletionPolicy, true, termInfosIndexDivisor) { +} + +ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, + Collection oldReaders, Collection oldStarts, + MapStringByteArray oldNormsCache, bool doClone, + int32_t termInfosIndexDivisor) : + DirectoryReader(directory, infos, oldReaders, oldStarts, oldNormsCache, true, doClone, termInfosIndexDivisor) { +} + +ReadOnlyDirectoryReader::ReadOnlyDirectoryReader(const IndexWriterPtr& writer, const SegmentInfosPtr& infos, int32_t termInfosIndexDivisor) : + DirectoryReader(writer, infos, termInfosIndexDivisor) { +} + +ReadOnlyDirectoryReader::~ReadOnlyDirectoryReader() { +} + +void ReadOnlyDirectoryReader::acquireWriteLock() { + ReadOnlySegmentReader::noWrite(); +} + } diff --git a/src/core/index/ReadOnlySegmentReader.cpp b/src/core/index/ReadOnlySegmentReader.cpp index 30b4577b..46ac0813 100644 --- a/src/core/index/ReadOnlySegmentReader.cpp +++ b/src/core/index/ReadOnlySegmentReader.cpp @@ -8,24 +8,21 @@ #include "ReadOnlySegmentReader.h" #include "BitVector.h" -namespace Lucene -{ - ReadOnlySegmentReader::~ReadOnlySegmentReader() - { - } +namespace Lucene { - void ReadOnlySegmentReader::noWrite() - { - boost::throw_exception(UnsupportedOperationException(L"This IndexReader cannot make any changes to the index (it was opened with readOnly = true)")); - } +ReadOnlySegmentReader::~ReadOnlySegmentReader() { +} + +void ReadOnlySegmentReader::noWrite() { + boost::throw_exception(UnsupportedOperationException(L"This IndexReader cannot make any changes to the index (it was opened with readOnly = true)")); +} - void ReadOnlySegmentReader::acquireWriteLock() - { - noWrite(); - } +void ReadOnlySegmentReader::acquireWriteLock() { + noWrite(); +} + +bool ReadOnlySegmentReader::isDeleted(int32_t n) { + return (deletedDocs && deletedDocs->get(n)); +} - bool ReadOnlySegmentReader::isDeleted(int32_t n) - { - return (deletedDocs && deletedDocs->get(n)); - } } diff --git a/src/core/index/ReusableStringReader.cpp b/src/core/index/ReusableStringReader.cpp index 4d848d09..1a6adf7e 100644 --- a/src/core/index/ReusableStringReader.cpp +++ b/src/core/index/ReusableStringReader.cpp @@ -8,50 +8,41 @@ #include "ReusableStringReader.h" #include "MiscUtils.h" -namespace Lucene -{ - ReusableStringReader::ReusableStringReader() - { - upto = 0; - left = 0; - } +namespace Lucene { - ReusableStringReader::~ReusableStringReader() - { - } +ReusableStringReader::ReusableStringReader() { + upto = 0; + left = 0; +} - void ReusableStringReader::init(const String& s) - { - this->s = s; - left = s.length(); - this->upto = 0; - } +ReusableStringReader::~ReusableStringReader() { +} - int32_t ReusableStringReader::read(wchar_t* buffer, int32_t offset, int32_t length) - { - if (left > length) - { - MiscUtils::arrayCopy(s.begin(), upto, buffer, offset, length); - upto += length; - left -= length; - return length; - } - else if (left == 0) - { - s.clear(); - return -1; - } - else - { - MiscUtils::arrayCopy(s.begin(), upto, buffer, offset, left); - int32_t r = left; - left = 0; - upto = s.length(); - return r; - } - } +void ReusableStringReader::init(const String& s) { + this->s = s; + left = s.length(); + this->upto = 0; +} - void ReusableStringReader::close() - { +int32_t ReusableStringReader::read(wchar_t* buffer, int32_t offset, int32_t length) { + if (left > length) { + MiscUtils::arrayCopy(s.begin(), upto, buffer, offset, length); + upto += length; + left -= length; + return length; + } else if (left == 0) { + s.clear(); + return -1; + } else { + MiscUtils::arrayCopy(s.begin(), upto, buffer, offset, left); + int32_t r = left; + left = 0; + upto = s.length(); + return r; } } + +void ReusableStringReader::close() { +} + +} diff --git a/src/core/index/SegmentInfo.cpp b/src/core/index/SegmentInfo.cpp index 038b7d22..ed8deb3d 100644 --- a/src/core/index/SegmentInfo.cpp +++ b/src/core/index/SegmentInfo.cpp @@ -18,595 +18,537 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t SegmentInfo::NO = -1; // no norms; no deletes; - const int32_t SegmentInfo::YES = 1; // have norms; have deletes; - const int32_t SegmentInfo::CHECK_DIR = 0; // must check dir to see if there are norms/deletions - const int32_t SegmentInfo::WITHOUT_GEN = 0; // a file name that has no GEN in it. - - SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir) - { - _sizeInBytes = -1; - this->name = name; - this->docCount = docCount; - this->dir = dir; - delGen = NO; - this->isCompoundFile = CHECK_DIR; - preLockless = true; - hasSingleNormFile = false; - docStoreOffset = -1; - docStoreSegment = name; - docStoreIsCompoundFile = false; - delCount = 0; - hasProx = true; - } +namespace Lucene { + +const int32_t SegmentInfo::NO = -1; // no norms; no deletes; +const int32_t SegmentInfo::YES = 1; // have norms; have deletes; +const int32_t SegmentInfo::CHECK_DIR = 0; // must check dir to see if there are norms/deletions +const int32_t SegmentInfo::WITHOUT_GEN = 0; // a file name that has no GEN in it. + +SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir) { + _sizeInBytes = -1; + this->name = name; + this->docCount = docCount; + this->dir = dir; + delGen = NO; + this->isCompoundFile = CHECK_DIR; + preLockless = true; + hasSingleNormFile = false; + docStoreOffset = -1; + docStoreSegment = name; + docStoreIsCompoundFile = false; + delCount = 0; + hasProx = true; +} - SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile) - { - _sizeInBytes = -1; - this->name = name; - this->docCount = docCount; - this->dir = dir; - delGen = NO; - this->isCompoundFile = (uint8_t)(isCompoundFile ? YES : NO); - this->hasSingleNormFile = hasSingleNormFile; - preLockless = false; - docStoreOffset = -1; - docStoreIsCompoundFile = false; - delCount = 0; - hasProx = true; - } +SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile) { + _sizeInBytes = -1; + this->name = name; + this->docCount = docCount; + this->dir = dir; + delGen = NO; + this->isCompoundFile = (uint8_t)(isCompoundFile ? YES : NO); + this->hasSingleNormFile = hasSingleNormFile; + preLockless = false; + docStoreOffset = -1; + docStoreIsCompoundFile = false; + delCount = 0; + hasProx = true; +} - SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile, - int32_t docStoreOffset, const String& docStoreSegment, bool docStoreIsCompoundFile, bool hasProx) - { - _sizeInBytes = -1; - this->name = name; - this->docCount = docCount; - this->dir = dir; - delGen = NO; - this->isCompoundFile = (uint8_t)(isCompoundFile ? YES : NO); - this->hasSingleNormFile = hasSingleNormFile; - preLockless = false; - this->docStoreOffset = docStoreOffset; - this->docStoreSegment = docStoreSegment; - this->docStoreIsCompoundFile = docStoreIsCompoundFile; - delCount = 0; - this->hasProx = hasProx; - } +SegmentInfo::SegmentInfo(const String& name, int32_t docCount, const DirectoryPtr& dir, bool isCompoundFile, bool hasSingleNormFile, + int32_t docStoreOffset, const String& docStoreSegment, bool docStoreIsCompoundFile, bool hasProx) { + _sizeInBytes = -1; + this->name = name; + this->docCount = docCount; + this->dir = dir; + delGen = NO; + this->isCompoundFile = (uint8_t)(isCompoundFile ? YES : NO); + this->hasSingleNormFile = hasSingleNormFile; + preLockless = false; + this->docStoreOffset = docStoreOffset; + this->docStoreSegment = docStoreSegment; + this->docStoreIsCompoundFile = docStoreIsCompoundFile; + delCount = 0; + this->hasProx = hasProx; +} - SegmentInfo::SegmentInfo(const DirectoryPtr& dir, int32_t format, const IndexInputPtr& input) - { - _sizeInBytes = -1; - this->dir = dir; - name = input->readString(); - docCount = input->readInt(); - if (format <= SegmentInfos::FORMAT_LOCKLESS) - { - delGen = input->readLong(); - if (format <= SegmentInfos::FORMAT_SHARED_DOC_STORE) - { - docStoreOffset = input->readInt(); - if (docStoreOffset != -1) - { - docStoreSegment = input->readString(); - docStoreIsCompoundFile = (input->readByte() == 1); - } - else - { - docStoreSegment = name; - docStoreIsCompoundFile = false; - } - } - else - { - docStoreOffset = -1; +SegmentInfo::SegmentInfo(const DirectoryPtr& dir, int32_t format, const IndexInputPtr& input) { + _sizeInBytes = -1; + this->dir = dir; + name = input->readString(); + docCount = input->readInt(); + if (format <= SegmentInfos::FORMAT_LOCKLESS) { + delGen = input->readLong(); + if (format <= SegmentInfos::FORMAT_SHARED_DOC_STORE) { + docStoreOffset = input->readInt(); + if (docStoreOffset != -1) { + docStoreSegment = input->readString(); + docStoreIsCompoundFile = (input->readByte() == 1); + } else { docStoreSegment = name; docStoreIsCompoundFile = false; } - if (format <= SegmentInfos::FORMAT_SINGLE_NORM_FILE) - hasSingleNormFile = (input->readByte() == 1); - else - hasSingleNormFile = false; - int32_t numNormGen = input->readInt(); - if (numNormGen != NO) - { - normGen = Collection::newInstance(numNormGen); - for (int32_t j = 0; j < numNormGen; ++j) - normGen[j] = input->readLong(); - } - isCompoundFile = input->readByte(); - preLockless = (isCompoundFile == CHECK_DIR); - if (format <= SegmentInfos::FORMAT_DEL_COUNT) - { - delCount = input->readInt(); - BOOST_ASSERT(delCount <= docCount); - } - else - delCount = -1; - if (format <= SegmentInfos::FORMAT_HAS_PROX) - hasProx = (input->readByte() == 1); - else - hasProx = true; - - if (format <= SegmentInfos::FORMAT_DIAGNOSTICS) - diagnostics = input->readStringStringMap(); - else - diagnostics = MapStringString::newInstance(); - } - else - { - delGen = CHECK_DIR; - isCompoundFile = CHECK_DIR; - preLockless = true; - hasSingleNormFile = false; + } else { docStoreOffset = -1; + docStoreSegment = name; docStoreIsCompoundFile = false; + } + if (format <= SegmentInfos::FORMAT_SINGLE_NORM_FILE) { + hasSingleNormFile = (input->readByte() == 1); + } else { + hasSingleNormFile = false; + } + int32_t numNormGen = input->readInt(); + if (numNormGen != NO) { + normGen = Collection::newInstance(numNormGen); + for (int32_t j = 0; j < numNormGen; ++j) { + normGen[j] = input->readLong(); + } + } + isCompoundFile = input->readByte(); + preLockless = (isCompoundFile == CHECK_DIR); + if (format <= SegmentInfos::FORMAT_DEL_COUNT) { + delCount = input->readInt(); + BOOST_ASSERT(delCount <= docCount); + } else { delCount = -1; + } + if (format <= SegmentInfos::FORMAT_HAS_PROX) { + hasProx = (input->readByte() == 1); + } else { hasProx = true; + } + + if (format <= SegmentInfos::FORMAT_DIAGNOSTICS) { + diagnostics = input->readStringStringMap(); + } else { diagnostics = MapStringString::newInstance(); } + } else { + delGen = CHECK_DIR; + isCompoundFile = CHECK_DIR; + preLockless = true; + hasSingleNormFile = false; + docStoreOffset = -1; + docStoreIsCompoundFile = false; + delCount = -1; + hasProx = true; + diagnostics = MapStringString::newInstance(); } +} - SegmentInfo::~SegmentInfo() - { - } +SegmentInfo::~SegmentInfo() { +} - void SegmentInfo::reset(const SegmentInfoPtr& src) - { - clearFiles(); - name = src->name; - docCount = src->docCount; - dir = src->dir; - preLockless = src->preLockless; - delGen = src->delGen; - docStoreOffset = src->docStoreOffset; - docStoreIsCompoundFile = src->docStoreIsCompoundFile; - if (!src->normGen) - normGen = src->normGen; - else - normGen = Collection::newInstance(src->normGen.begin(), src->normGen.end()); - isCompoundFile = src->isCompoundFile; - hasSingleNormFile = src->hasSingleNormFile; - delCount = src->delCount; - } +void SegmentInfo::reset(const SegmentInfoPtr& src) { + clearFiles(); + name = src->name; + docCount = src->docCount; + dir = src->dir; + preLockless = src->preLockless; + delGen = src->delGen; + docStoreOffset = src->docStoreOffset; + docStoreIsCompoundFile = src->docStoreIsCompoundFile; + if (!src->normGen) { + normGen = src->normGen; + } else { + normGen = Collection::newInstance(src->normGen.begin(), src->normGen.end()); + } + isCompoundFile = src->isCompoundFile; + hasSingleNormFile = src->hasSingleNormFile; + delCount = src->delCount; +} - void SegmentInfo::setDiagnostics(MapStringString diagnostics) - { - this->diagnostics = diagnostics; - } +void SegmentInfo::setDiagnostics(MapStringString diagnostics) { + this->diagnostics = diagnostics; +} - MapStringString SegmentInfo::getDiagnostics() - { - return diagnostics; - } +MapStringString SegmentInfo::getDiagnostics() { + return diagnostics; +} - void SegmentInfo::setNumFields(int32_t numFields) - { - if (!normGen) - { - // normGen is null if we loaded a pre-2.1 segment file, or, if this segments file hasn't had any - // norms set against it yet - normGen = Collection::newInstance(numFields); - - if (!preLockless) - { // Do nothing: thus leaving normGen[k] == CHECK_DIR (==0), so that later we know - } // we have to check filesystem for norm files, because this is prelockless. - else - { - // This is a FORMAT_LOCKLESS segment, which means there are no separate norms - for (int32_t i = 0; i < numFields; ++i) - normGen[i] = NO; +void SegmentInfo::setNumFields(int32_t numFields) { + if (!normGen) { + // normGen is null if we loaded a pre-2.1 segment file, or, if this segments file hasn't had any + // norms set against it yet + normGen = Collection::newInstance(numFields); + + if (!preLockless) { + // Do nothing: thus leaving normGen[k] == CHECK_DIR (==0), so that later we know + } // we have to check filesystem for norm files, because this is prelockless. + else { + // This is a FORMAT_LOCKLESS segment, which means there are no separate norms + for (int32_t i = 0; i < numFields; ++i) { + normGen[i] = NO; } } } +} - int64_t SegmentInfo::sizeInBytes() - { - if (_sizeInBytes == -1) - { - HashSet _files(files()); - _sizeInBytes = 0; - for (HashSet::iterator fileName = _files.begin(); fileName != _files.end(); ++fileName) - { - // we don't count bytes used by a shared doc store against this segment - if (docStoreOffset == -1 || !IndexFileNames::isDocStoreFile(*fileName)) - _sizeInBytes += dir->fileLength(*fileName); +int64_t SegmentInfo::sizeInBytes() { + if (_sizeInBytes == -1) { + HashSet _files(files()); + _sizeInBytes = 0; + for (HashSet::iterator fileName = _files.begin(); fileName != _files.end(); ++fileName) { + // we don't count bytes used by a shared doc store against this segment + if (docStoreOffset == -1 || !IndexFileNames::isDocStoreFile(*fileName)) { + _sizeInBytes += dir->fileLength(*fileName); } } - return _sizeInBytes; } + return _sizeInBytes; +} - bool SegmentInfo::hasDeletions() - { - if (delGen == NO) - return false; - else if (delGen >= YES) - return true; - else - return dir->fileExists(getDelFileName()); +bool SegmentInfo::hasDeletions() { + if (delGen == NO) { + return false; + } else if (delGen >= YES) { + return true; + } else { + return dir->fileExists(getDelFileName()); } +} - void SegmentInfo::advanceDelGen() - { - // delGen 0 is reserved for pre-LOCKLESS format - if (delGen == NO) - delGen = YES; - else - delGen++; - clearFiles(); +void SegmentInfo::advanceDelGen() { + // delGen 0 is reserved for pre-LOCKLESS format + if (delGen == NO) { + delGen = YES; + } else { + delGen++; } + clearFiles(); +} - void SegmentInfo::clearDelGen() - { - delGen = NO; - clearFiles(); - } +void SegmentInfo::clearDelGen() { + delGen = NO; + clearFiles(); +} - LuceneObjectPtr SegmentInfo::clone(const LuceneObjectPtr& other) - { - SegmentInfoPtr si(newLucene(name, docCount, dir)); - si->isCompoundFile = isCompoundFile; - si->delGen = delGen; - si->delCount = delCount; - si->hasProx = hasProx; - si->preLockless = preLockless; - si->hasSingleNormFile = hasSingleNormFile; - si->diagnostics = MapStringString::newInstance(); - si->diagnostics.putAll(diagnostics.begin(), diagnostics.end()); - if (normGen) - si->normGen = Collection::newInstance(normGen.begin(), normGen.end()); - si->docStoreOffset = docStoreOffset; - si->docStoreSegment = docStoreSegment; - si->docStoreIsCompoundFile = docStoreIsCompoundFile; - return si; - } +LuceneObjectPtr SegmentInfo::clone(const LuceneObjectPtr& other) { + SegmentInfoPtr si(newLucene(name, docCount, dir)); + si->isCompoundFile = isCompoundFile; + si->delGen = delGen; + si->delCount = delCount; + si->hasProx = hasProx; + si->preLockless = preLockless; + si->hasSingleNormFile = hasSingleNormFile; + si->diagnostics = MapStringString::newInstance(); + si->diagnostics.putAll(diagnostics.begin(), diagnostics.end()); + if (normGen) { + si->normGen = Collection::newInstance(normGen.begin(), normGen.end()); + } + si->docStoreOffset = docStoreOffset; + si->docStoreSegment = docStoreSegment; + si->docStoreIsCompoundFile = docStoreIsCompoundFile; + return si; +} - String SegmentInfo::getDelFileName() - { - if (delGen == NO) - { - // in this case we know there is no deletion filename against this segment - return L""; - } - else - { - // if delgen is check_dir, it's the pre-lockless-commit file format - return IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::DELETES_EXTENSION(), delGen); - } +String SegmentInfo::getDelFileName() { + if (delGen == NO) { + // in this case we know there is no deletion filename against this segment + return L""; + } else { + // if delgen is check_dir, it's the pre-lockless-commit file format + return IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::DELETES_EXTENSION(), delGen); } +} - bool SegmentInfo::hasSeparateNorms(int32_t fieldNumber) - { - if ((!normGen && preLockless) || (normGen && normGen[fieldNumber] == CHECK_DIR)) - { - // must fallback to directory file exists check - return dir->fileExists(name + L".s" + StringUtils::toString(fieldNumber)); - } - else if (!normGen || normGen[fieldNumber] == NO) - return false; - else - return true; +bool SegmentInfo::hasSeparateNorms(int32_t fieldNumber) { + if ((!normGen && preLockless) || (normGen && normGen[fieldNumber] == CHECK_DIR)) { + // must fallback to directory file exists check + return dir->fileExists(name + L".s" + StringUtils::toString(fieldNumber)); + } else if (!normGen || normGen[fieldNumber] == NO) { + return false; + } else { + return true; } +} - bool SegmentInfo::hasSeparateNorms() - { - if (!normGen) - { - if (!preLockless) - { - // this means we were created with lockless code and no norms are written yet - return false; +bool SegmentInfo::hasSeparateNorms() { + if (!normGen) { + if (!preLockless) { + // this means we were created with lockless code and no norms are written yet + return false; + } else { + HashSet result(dir->listAll()); + if (!result) { + boost::throw_exception(IOException(L"Cannot read directory " + dir->toString() + L": listAll() returned null")); } - else - { - HashSet result(dir->listAll()); - if (!result) - boost::throw_exception(IOException(L"Cannot read directory " + dir->toString() + L": listAll() returned null")); - String pattern(name + L".s"); - int32_t patternLength = pattern.length(); - for (HashSet::iterator fileName = result.begin(); fileName != result.end(); ++fileName) - { - if (IndexFileNameFilter::accept(L"", *fileName) && boost::starts_with(*fileName, pattern) && UnicodeUtil::isDigit((*fileName)[patternLength])) - return true; + String pattern(name + L".s"); + int32_t patternLength = pattern.length(); + for (HashSet::iterator fileName = result.begin(); fileName != result.end(); ++fileName) { + if (IndexFileNameFilter::accept(L"", *fileName) && boost::starts_with(*fileName, pattern) && UnicodeUtil::isDigit((*fileName)[patternLength])) { + return true; } - return false; } + return false; } - else - { - // This means this segment was saved with LOCKLESS code so we first check whether any normGen's are >= 1 - // (meaning they definitely have separate norms) - for (Collection::iterator gen = normGen.begin(); gen != normGen.end(); ++gen) - { - if (*gen >= YES) - return true; + } else { + // This means this segment was saved with LOCKLESS code so we first check whether any normGen's are >= 1 + // (meaning they definitely have separate norms) + for (Collection::iterator gen = normGen.begin(); gen != normGen.end(); ++gen) { + if (*gen >= YES) { + return true; } + } - // Next we look for any == 0. These cases were pre-LOCKLESS and must be checked in directory - for (int32_t gen = 0; gen < normGen.size(); ++gen) - { - if (normGen[gen] == CHECK_DIR && hasSeparateNorms(gen)) - return true; + // Next we look for any == 0. These cases were pre-LOCKLESS and must be checked in directory + for (int32_t gen = 0; gen < normGen.size(); ++gen) { + if (normGen[gen] == CHECK_DIR && hasSeparateNorms(gen)) { + return true; } } - return false; } + return false; +} - void SegmentInfo::advanceNormGen(int32_t fieldIndex) - { - if (normGen[fieldIndex] == NO) - normGen[fieldIndex] = YES; - else - normGen[fieldIndex]++; - clearFiles(); +void SegmentInfo::advanceNormGen(int32_t fieldIndex) { + if (normGen[fieldIndex] == NO) { + normGen[fieldIndex] = YES; + } else { + normGen[fieldIndex]++; } + clearFiles(); +} - String SegmentInfo::getNormFileName(int32_t number) - { - String prefix; - int64_t gen = !normGen ? CHECK_DIR : normGen[number]; - - if (hasSeparateNorms(number)) - { - // case 1: separate norm - prefix = L".s"; - return IndexFileNames::fileNameFromGeneration(name, prefix + StringUtils::toString(number), gen); - } - - if (hasSingleNormFile) - { - // case 2: lockless (or nrm file exists) - single file for all norms - prefix = String(L".") + IndexFileNames::NORMS_EXTENSION(); - return IndexFileNames::fileNameFromGeneration(name, prefix, WITHOUT_GEN); - } +String SegmentInfo::getNormFileName(int32_t number) { + String prefix; + int64_t gen = !normGen ? CHECK_DIR : normGen[number]; - // case 3: norm file for each field - prefix = L".f"; - return IndexFileNames::fileNameFromGeneration(name, prefix + StringUtils::toString(number), WITHOUT_GEN); + if (hasSeparateNorms(number)) { + // case 1: separate norm + prefix = L".s"; + return IndexFileNames::fileNameFromGeneration(name, prefix + StringUtils::toString(number), gen); } - void SegmentInfo::setUseCompoundFile(bool isCompoundFile) - { - this->isCompoundFile = (uint8_t)(isCompoundFile ? YES : NO); - clearFiles(); + if (hasSingleNormFile) { + // case 2: lockless (or nrm file exists) - single file for all norms + prefix = String(L".") + IndexFileNames::NORMS_EXTENSION(); + return IndexFileNames::fileNameFromGeneration(name, prefix, WITHOUT_GEN); } - bool SegmentInfo::getUseCompoundFile() - { - if (isCompoundFile == (uint8_t)NO) - return false; - else if (isCompoundFile == (uint8_t)YES) - return true; - else - return dir->fileExists(name + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); - } + // case 3: norm file for each field + prefix = L".f"; + return IndexFileNames::fileNameFromGeneration(name, prefix + StringUtils::toString(number), WITHOUT_GEN); +} - int32_t SegmentInfo::getDelCount() - { - if (delCount == -1) - delCount = hasDeletions() ? BitVector(dir, getDelFileName()).count() : 0; - BOOST_ASSERT(delCount <= docCount); - return delCount; - } +void SegmentInfo::setUseCompoundFile(bool isCompoundFile) { + this->isCompoundFile = (uint8_t)(isCompoundFile ? YES : NO); + clearFiles(); +} - void SegmentInfo::setDelCount(int32_t delCount) - { - this->delCount = delCount; - BOOST_ASSERT(delCount <= docCount); +bool SegmentInfo::getUseCompoundFile() { + if (isCompoundFile == (uint8_t)NO) { + return false; + } else if (isCompoundFile == (uint8_t)YES) { + return true; + } else { + return dir->fileExists(name + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); } +} - int32_t SegmentInfo::getDocStoreOffset() - { - return docStoreOffset; +int32_t SegmentInfo::getDelCount() { + if (delCount == -1) { + delCount = hasDeletions() ? BitVector(dir, getDelFileName()).count() : 0; } + BOOST_ASSERT(delCount <= docCount); + return delCount; +} - bool SegmentInfo::getDocStoreIsCompoundFile() - { - return docStoreIsCompoundFile; - } +void SegmentInfo::setDelCount(int32_t delCount) { + this->delCount = delCount; + BOOST_ASSERT(delCount <= docCount); +} - void SegmentInfo::setDocStoreIsCompoundFile(bool v) - { - docStoreIsCompoundFile = v; - clearFiles(); - } +int32_t SegmentInfo::getDocStoreOffset() { + return docStoreOffset; +} - String SegmentInfo::getDocStoreSegment() - { - return docStoreSegment; - } +bool SegmentInfo::getDocStoreIsCompoundFile() { + return docStoreIsCompoundFile; +} - void SegmentInfo::setDocStoreOffset(int32_t offset) - { - docStoreOffset = offset; - clearFiles(); - } +void SegmentInfo::setDocStoreIsCompoundFile(bool v) { + docStoreIsCompoundFile = v; + clearFiles(); +} - void SegmentInfo::setDocStore(int32_t offset, const String& segment, bool isCompoundFile) - { - docStoreOffset = offset; - docStoreSegment = segment; - docStoreIsCompoundFile = isCompoundFile; - } +String SegmentInfo::getDocStoreSegment() { + return docStoreSegment; +} - void SegmentInfo::write(const IndexOutputPtr& output) - { - output->writeString(name); - output->writeInt(docCount); - output->writeLong(delGen); - output->writeInt(docStoreOffset); - if (docStoreOffset != -1) - { - output->writeString(docStoreSegment); - output->writeByte((uint8_t)(docStoreIsCompoundFile ? 1 : 0)); - } +void SegmentInfo::setDocStoreOffset(int32_t offset) { + docStoreOffset = offset; + clearFiles(); +} - output->writeByte((uint8_t)(hasSingleNormFile ? 1 : 0)); - if (!normGen) - output->writeInt(NO); - else - { - output->writeInt(normGen.size()); - for (Collection::iterator gen = normGen.begin(); gen != normGen.end(); ++gen) - output->writeLong(*gen); +void SegmentInfo::setDocStore(int32_t offset, const String& segment, bool isCompoundFile) { + docStoreOffset = offset; + docStoreSegment = segment; + docStoreIsCompoundFile = isCompoundFile; +} + +void SegmentInfo::write(const IndexOutputPtr& output) { + output->writeString(name); + output->writeInt(docCount); + output->writeLong(delGen); + output->writeInt(docStoreOffset); + if (docStoreOffset != -1) { + output->writeString(docStoreSegment); + output->writeByte((uint8_t)(docStoreIsCompoundFile ? 1 : 0)); + } + + output->writeByte((uint8_t)(hasSingleNormFile ? 1 : 0)); + if (!normGen) { + output->writeInt(NO); + } else { + output->writeInt(normGen.size()); + for (Collection::iterator gen = normGen.begin(); gen != normGen.end(); ++gen) { + output->writeLong(*gen); } - output->writeByte(isCompoundFile); - output->writeInt(delCount); - output->writeByte((uint8_t)(hasProx ? 1 : 0)); - output->writeStringStringMap(diagnostics); } + output->writeByte(isCompoundFile); + output->writeInt(delCount); + output->writeByte((uint8_t)(hasProx ? 1 : 0)); + output->writeStringStringMap(diagnostics); +} - void SegmentInfo::setHasProx(bool hasProx) - { - this->hasProx = hasProx; - clearFiles(); - } +void SegmentInfo::setHasProx(bool hasProx) { + this->hasProx = hasProx; + clearFiles(); +} - bool SegmentInfo::getHasProx() - { - return hasProx; - } +bool SegmentInfo::getHasProx() { + return hasProx; +} - void SegmentInfo::addIfExists(HashSet files, const String& fileName) - { - if (dir->fileExists(fileName)) - files.add(fileName); +void SegmentInfo::addIfExists(HashSet files, const String& fileName) { + if (dir->fileExists(fileName)) { + files.add(fileName); } +} - HashSet SegmentInfo::files() - { - if (_files) - { - // already cached - return _files; - } +HashSet SegmentInfo::files() { + if (_files) { + // already cached + return _files; + } - _files = HashSet::newInstance(); - bool useCompoundFile = getUseCompoundFile(); + _files = HashSet::newInstance(); + bool useCompoundFile = getUseCompoundFile(); - if (useCompoundFile) - _files.add(name + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); - else - { - for (HashSet::iterator ext = IndexFileNames::NON_STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::NON_STORE_INDEX_EXTENSIONS().end(); ++ext) - addIfExists(_files, name + L"." + *ext); + if (useCompoundFile) { + _files.add(name + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION()); + } else { + for (HashSet::iterator ext = IndexFileNames::NON_STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::NON_STORE_INDEX_EXTENSIONS().end(); ++ext) { + addIfExists(_files, name + L"." + *ext); } + } - if (docStoreOffset != -1) - { - // we are sharing doc stores (stored fields, term vectors) with other segments - BOOST_ASSERT(!docStoreSegment.empty()); - if (docStoreIsCompoundFile) - _files.add(docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); - else - { - for (HashSet::iterator ext = IndexFileNames::STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::STORE_INDEX_EXTENSIONS().end(); ++ext) - addIfExists(_files, docStoreSegment + L"." + *ext); + if (docStoreOffset != -1) { + // we are sharing doc stores (stored fields, term vectors) with other segments + BOOST_ASSERT(!docStoreSegment.empty()); + if (docStoreIsCompoundFile) { + _files.add(docStoreSegment + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION()); + } else { + for (HashSet::iterator ext = IndexFileNames::STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::STORE_INDEX_EXTENSIONS().end(); ++ext) { + addIfExists(_files, docStoreSegment + L"." + *ext); } } - else if (!useCompoundFile) - { - // we are not sharing, and, these files were not included in the compound file - for (HashSet::iterator ext = IndexFileNames::STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::STORE_INDEX_EXTENSIONS().end(); ++ext) - addIfExists(_files, name + L"." + *ext); + } else if (!useCompoundFile) { + // we are not sharing, and, these files were not included in the compound file + for (HashSet::iterator ext = IndexFileNames::STORE_INDEX_EXTENSIONS().begin(); ext != IndexFileNames::STORE_INDEX_EXTENSIONS().end(); ++ext) { + addIfExists(_files, name + L"." + *ext); } + } - String delFileName(IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::DELETES_EXTENSION(), delGen)); - if (!delFileName.empty() && (delGen >= YES || dir->fileExists(delFileName))) - _files.add(delFileName); - - // careful logic for norms files - if (normGen) - { - for (int32_t gen = 0; gen < normGen.size(); ++gen) - { - if (normGen[gen] >= YES) - { - // definitely a separate norm file, with generation - _files.add(IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::SEPARATE_NORMS_EXTENSION() + StringUtils::toString(gen), normGen[gen])); - } - else if (normGen[gen] == NO) - { - // no separate norms but maybe plain norms in the non compound file case - if (!hasSingleNormFile && !useCompoundFile) - { - String fileName(name + L"." + IndexFileNames::PLAIN_NORMS_EXTENSION() + StringUtils::toString(gen)); - if (dir->fileExists(fileName)) - _files.add(fileName); + String delFileName(IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::DELETES_EXTENSION(), delGen)); + if (!delFileName.empty() && (delGen >= YES || dir->fileExists(delFileName))) { + _files.add(delFileName); + } + + // careful logic for norms files + if (normGen) { + for (int32_t gen = 0; gen < normGen.size(); ++gen) { + if (normGen[gen] >= YES) { + // definitely a separate norm file, with generation + _files.add(IndexFileNames::fileNameFromGeneration(name, String(L".") + IndexFileNames::SEPARATE_NORMS_EXTENSION() + StringUtils::toString(gen), normGen[gen])); + } else if (normGen[gen] == NO) { + // no separate norms but maybe plain norms in the non compound file case + if (!hasSingleNormFile && !useCompoundFile) { + String fileName(name + L"." + IndexFileNames::PLAIN_NORMS_EXTENSION() + StringUtils::toString(gen)); + if (dir->fileExists(fileName)) { + _files.add(fileName); } } - else if (normGen[gen] == CHECK_DIR) - { - // pre-2.1: we have to check file existence - String fileName; - if (useCompoundFile) - fileName = name + L"." + IndexFileNames::SEPARATE_NORMS_EXTENSION() + StringUtils::toString(gen); - else if (!hasSingleNormFile) - fileName = name + L"." + IndexFileNames::PLAIN_NORMS_EXTENSION() + StringUtils::toString(gen); - if (!fileName.empty() && dir->fileExists(fileName)) - _files.add(fileName); + } else if (normGen[gen] == CHECK_DIR) { + // pre-2.1: we have to check file existence + String fileName; + if (useCompoundFile) { + fileName = name + L"." + IndexFileNames::SEPARATE_NORMS_EXTENSION() + StringUtils::toString(gen); + } else if (!hasSingleNormFile) { + fileName = name + L"." + IndexFileNames::PLAIN_NORMS_EXTENSION() + StringUtils::toString(gen); + } + if (!fileName.empty() && dir->fileExists(fileName)) { + _files.add(fileName); } } } - else if (preLockless || (!hasSingleNormFile && !useCompoundFile)) - { - // pre-2.1: we have to scan the dir to find all matching _x.sn/_x.fn files for our segment - String prefix; - if (useCompoundFile) - prefix = name + L"." + IndexFileNames::SEPARATE_NORMS_EXTENSION(); - else - prefix = name + L"." + IndexFileNames::PLAIN_NORMS_EXTENSION(); - int32_t prefixLength = prefix.length(); - HashSet allFiles(dir->listAll()); - for (HashSet::iterator fileName = allFiles.begin(); fileName != allFiles.end(); ++fileName) - { - if (IndexFileNameFilter::accept(L"", *fileName) && (int32_t)fileName->length() > prefixLength && - UnicodeUtil::isDigit((*fileName)[prefixLength]) && boost::starts_with(*fileName, prefix)) - _files.add(*fileName); + } else if (preLockless || (!hasSingleNormFile && !useCompoundFile)) { + // pre-2.1: we have to scan the dir to find all matching _x.sn/_x.fn files for our segment + String prefix; + if (useCompoundFile) { + prefix = name + L"." + IndexFileNames::SEPARATE_NORMS_EXTENSION(); + } else { + prefix = name + L"." + IndexFileNames::PLAIN_NORMS_EXTENSION(); + } + int32_t prefixLength = prefix.length(); + HashSet allFiles(dir->listAll()); + for (HashSet::iterator fileName = allFiles.begin(); fileName != allFiles.end(); ++fileName) { + if (IndexFileNameFilter::accept(L"", *fileName) && (int32_t)fileName->length() > prefixLength && + UnicodeUtil::isDigit((*fileName)[prefixLength]) && boost::starts_with(*fileName, prefix)) { + _files.add(*fileName); } } - return _files; } + return _files; +} + +void SegmentInfo::clearFiles() { + _files.reset(); + _sizeInBytes = -1; +} - void SegmentInfo::clearFiles() - { - _files.reset(); - _sizeInBytes = -1; +String SegmentInfo::segString(const DirectoryPtr& dir) { + String cfs; + try { + cfs = getUseCompoundFile() ? L"c" : L"C"; + } catch (LuceneException&) { + cfs = L"?"; } - String SegmentInfo::segString(const DirectoryPtr& dir) - { - String cfs; - try - { - cfs = getUseCompoundFile() ? L"c" : L"C"; - } - catch (LuceneException&) - { - cfs = L"?"; - } + String docStore; + if (docStoreOffset != -1) { + docStore = L"->" + docStoreSegment; + } - String docStore; - if (docStoreOffset != -1) - docStore = L"->" + docStoreSegment; + return name + L":" + cfs + (this->dir == dir ? L"" : L"x") + StringUtils::toString(docCount) + docStore; +} - return name + L":" + cfs + (this->dir == dir ? L"" : L"x") + StringUtils::toString(docCount) + docStore; +bool SegmentInfo::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - - bool SegmentInfo::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - SegmentInfoPtr otherSegmentInfo(boost::dynamic_pointer_cast(other)); - if (!otherSegmentInfo) - return false; - return (otherSegmentInfo->dir == dir && otherSegmentInfo->name == name); + SegmentInfoPtr otherSegmentInfo(boost::dynamic_pointer_cast(other)); + if (!otherSegmentInfo) { + return false; } + return (otherSegmentInfo->dir == dir && otherSegmentInfo->name == name); +} + +int32_t SegmentInfo::hashCode() { + return dir->hashCode() + StringUtils::hashCode(name); +} - int32_t SegmentInfo::hashCode() - { - return dir->hashCode() + StringUtils::hashCode(name); - } } diff --git a/src/core/index/SegmentInfoCollection.cpp b/src/core/index/SegmentInfoCollection.cpp index 98298f81..7e5fa7ce 100644 --- a/src/core/index/SegmentInfoCollection.cpp +++ b/src/core/index/SegmentInfoCollection.cpp @@ -8,81 +8,70 @@ #include "SegmentInfoCollection.h" #include "SegmentInfo.h" -namespace Lucene -{ - SegmentInfoCollection::SegmentInfoCollection() - { - segmentInfos = Collection::newInstance(); - } +namespace Lucene { - SegmentInfoCollection::~SegmentInfoCollection() - { - } +SegmentInfoCollection::SegmentInfoCollection() { + segmentInfos = Collection::newInstance(); +} - int32_t SegmentInfoCollection::size() - { - return segmentInfos.size(); - } +SegmentInfoCollection::~SegmentInfoCollection() { +} - bool SegmentInfoCollection::empty() - { - return segmentInfos.empty(); - } +int32_t SegmentInfoCollection::size() { + return segmentInfos.size(); +} - void SegmentInfoCollection::clear() - { - segmentInfos.clear(); - } +bool SegmentInfoCollection::empty() { + return segmentInfos.empty(); +} - void SegmentInfoCollection::add(const SegmentInfoPtr& info) - { - segmentInfos.add(info); - } +void SegmentInfoCollection::clear() { + segmentInfos.clear(); +} - void SegmentInfoCollection::add(int32_t pos, const SegmentInfoPtr& info) - { - segmentInfos.add(pos, info); - } +void SegmentInfoCollection::add(const SegmentInfoPtr& info) { + segmentInfos.add(info); +} - void SegmentInfoCollection::addAll(const SegmentInfoCollectionPtr& segmentInfos) - { - this->segmentInfos.addAll(segmentInfos->segmentInfos.begin(), segmentInfos->segmentInfos.end()); - } +void SegmentInfoCollection::add(int32_t pos, const SegmentInfoPtr& info) { + segmentInfos.add(pos, info); +} - bool SegmentInfoCollection::equals(const SegmentInfoCollectionPtr& other) - { - if (LuceneObject::equals(other)) - return true; - return segmentInfos.equals(other->segmentInfos, luceneEquals()); - } +void SegmentInfoCollection::addAll(const SegmentInfoCollectionPtr& segmentInfos) { + this->segmentInfos.addAll(segmentInfos->segmentInfos.begin(), segmentInfos->segmentInfos.end()); +} - int32_t SegmentInfoCollection::find(const SegmentInfoPtr& info) - { - Collection::iterator idx = segmentInfos.find_if(luceneEqualTo(info)); - return idx == segmentInfos.end() ? -1 : std::distance(segmentInfos.begin(), idx); +bool SegmentInfoCollection::equals(const SegmentInfoCollectionPtr& other) { + if (LuceneObject::equals(other)) { + return true; } + return segmentInfos.equals(other->segmentInfos, luceneEquals()); +} - bool SegmentInfoCollection::contains(const SegmentInfoPtr& info) - { - return segmentInfos.contains_if(luceneEqualTo(info)); - } +int32_t SegmentInfoCollection::find(const SegmentInfoPtr& info) { + Collection::iterator idx = segmentInfos.find_if(luceneEqualTo(info)); + return idx == segmentInfos.end() ? -1 : std::distance(segmentInfos.begin(), idx); +} - void SegmentInfoCollection::remove(int32_t pos) - { - segmentInfos.remove(segmentInfos.begin() + pos); - } +bool SegmentInfoCollection::contains(const SegmentInfoPtr& info) { + return segmentInfos.contains_if(luceneEqualTo(info)); +} - void SegmentInfoCollection::remove(int32_t start, int32_t end) - { - segmentInfos.remove(segmentInfos.begin() + start, segmentInfos.begin() + end); - } +void SegmentInfoCollection::remove(int32_t pos) { + segmentInfos.remove(segmentInfos.begin() + pos); +} - LuceneObjectPtr SegmentInfoCollection::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); - SegmentInfoCollectionPtr cloneInfos(boost::dynamic_pointer_cast(clone)); - for (Collection::iterator info = segmentInfos.begin(); info != segmentInfos.end(); ++info) - cloneInfos->segmentInfos.add(*info); - return cloneInfos; +void SegmentInfoCollection::remove(int32_t start, int32_t end) { + segmentInfos.remove(segmentInfos.begin() + start, segmentInfos.begin() + end); +} + +LuceneObjectPtr SegmentInfoCollection::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); + SegmentInfoCollectionPtr cloneInfos(boost::dynamic_pointer_cast(clone)); + for (Collection::iterator info = segmentInfos.begin(); info != segmentInfos.end(); ++info) { + cloneInfos->segmentInfos.add(*info); } + return cloneInfos; +} + } diff --git a/src/core/index/SegmentInfos.cpp b/src/core/index/SegmentInfos.cpp index 48ce4564..2593152e 100644 --- a/src/core/index/SegmentInfos.cpp +++ b/src/core/index/SegmentInfos.cpp @@ -20,750 +20,656 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// The file format version, a negative number. Works since counter, the old 1st entry, is always >= 0 - const int32_t SegmentInfos::FORMAT = -1; +namespace Lucene { - /// This format adds details used for lockless commits. It differs slightly from the previous format in that file names - /// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, - /// segments_2, etc. This allows us to not use a commit lock. - const int32_t SegmentInfos::FORMAT_LOCKLESS = -2; +/// The file format version, a negative number. Works since counter, the old 1st entry, is always >= 0 +const int32_t SegmentInfos::FORMAT = -1; - /// This format adds a "hasSingleNormFile" flag into each segment info. - const int32_t SegmentInfos::FORMAT_SINGLE_NORM_FILE = -3; +/// This format adds details used for lockless commits. It differs slightly from the previous format in that file names +/// are never re-used (write once). Instead, each file is written to the next generation. For example, segments_1, +/// segments_2, etc. This allows us to not use a commit lock. +const int32_t SegmentInfos::FORMAT_LOCKLESS = -2; - /// This format allows multiple segments to share a single vectors and stored fields file. - const int32_t SegmentInfos::FORMAT_SHARED_DOC_STORE = -4; +/// This format adds a "hasSingleNormFile" flag into each segment info. +const int32_t SegmentInfos::FORMAT_SINGLE_NORM_FILE = -3; - /// This format adds a checksum at the end of the file to ensure all bytes were successfully written. - const int32_t SegmentInfos::FORMAT_CHECKSUM = -5; +/// This format allows multiple segments to share a single vectors and stored fields file. +const int32_t SegmentInfos::FORMAT_SHARED_DOC_STORE = -4; - /// This format adds the deletion count for each segment. This way IndexWriter can efficiently report numDocs(). - const int32_t SegmentInfos::FORMAT_DEL_COUNT = -6; +/// This format adds a checksum at the end of the file to ensure all bytes were successfully written. +const int32_t SegmentInfos::FORMAT_CHECKSUM = -5; - /// This format adds the boolean hasProx to record if any fields in the segment store prox information (ie, have - /// omitTermFreqAndPositions == false) - const int32_t SegmentInfos::FORMAT_HAS_PROX = -7; +/// This format adds the deletion count for each segment. This way IndexWriter can efficiently report numDocs(). +const int32_t SegmentInfos::FORMAT_DEL_COUNT = -6; - /// This format adds optional commit userData storage. - const int32_t SegmentInfos::FORMAT_USER_DATA = -8; +/// This format adds the boolean hasProx to record if any fields in the segment store prox information (ie, have +/// omitTermFreqAndPositions == false) +const int32_t SegmentInfos::FORMAT_HAS_PROX = -7; - /// This format adds optional per-segment string diagnostics storage, and switches userData to Map - const int32_t SegmentInfos::FORMAT_DIAGNOSTICS = -9; +/// This format adds optional commit userData storage. +const int32_t SegmentInfos::FORMAT_USER_DATA = -8; - /// This must always point to the most recent file format. - const int32_t SegmentInfos::CURRENT_FORMAT = SegmentInfos::FORMAT_DIAGNOSTICS; +/// This format adds optional per-segment string diagnostics storage, and switches userData to Map +const int32_t SegmentInfos::FORMAT_DIAGNOSTICS = -9; - /// Advanced configuration of retry logic in loading segments_N file. - int32_t SegmentInfos::defaultGenFileRetryCount = 10; - int32_t SegmentInfos::defaultGenFileRetryPauseMsec = 50; - int32_t SegmentInfos::defaultGenLookaheadCount = 10; +/// This must always point to the most recent file format. +const int32_t SegmentInfos::CURRENT_FORMAT = SegmentInfos::FORMAT_DIAGNOSTICS; - MapStringString SegmentInfos::singletonUserData; - InfoStreamPtr SegmentInfos::infoStream; +/// Advanced configuration of retry logic in loading segments_N file. +int32_t SegmentInfos::defaultGenFileRetryCount = 10; +int32_t SegmentInfos::defaultGenFileRetryPauseMsec = 50; +int32_t SegmentInfos::defaultGenLookaheadCount = 10; - SegmentInfos::SegmentInfos() - { - userData = MapStringString::newInstance(); - lastGeneration = 0; - generation = 0; - counter = 0; - version = MiscUtils::currentTimeMillis(); - } +MapStringString SegmentInfos::singletonUserData; +InfoStreamPtr SegmentInfos::infoStream; - SegmentInfos::~SegmentInfos() - { - } +SegmentInfos::SegmentInfos() { + userData = MapStringString::newInstance(); + lastGeneration = 0; + generation = 0; + counter = 0; + version = MiscUtils::currentTimeMillis(); +} - SegmentInfoPtr SegmentInfos::info(int32_t i) - { - return segmentInfos[i]; - } +SegmentInfos::~SegmentInfos() { +} - int64_t SegmentInfos::getCurrentSegmentGeneration(HashSet files) - { - if (!files) - return -1; - int64_t max = -1; - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - { - if (boost::starts_with(*file, IndexFileNames::SEGMENTS()) && *file != IndexFileNames::SEGMENTS_GEN()) - max = std::max(generationFromSegmentsFileName(*file), max); - } - return max; - } +SegmentInfoPtr SegmentInfos::info(int32_t i) { + return segmentInfos[i]; +} - int64_t SegmentInfos::getCurrentSegmentGeneration(const DirectoryPtr& directory) - { - try - { - return getCurrentSegmentGeneration(directory->listAll()); - } - catch (LuceneException&) - { - return -1; +int64_t SegmentInfos::getCurrentSegmentGeneration(HashSet files) { + if (!files) { + return -1; + } + int64_t max = -1; + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { + if (boost::starts_with(*file, IndexFileNames::SEGMENTS()) && *file != IndexFileNames::SEGMENTS_GEN()) { + max = std::max(generationFromSegmentsFileName(*file), max); } } + return max; +} - String SegmentInfos::getCurrentSegmentFileName(HashSet files) - { - return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(files)); +int64_t SegmentInfos::getCurrentSegmentGeneration(const DirectoryPtr& directory) { + try { + return getCurrentSegmentGeneration(directory->listAll()); + } catch (LuceneException&) { + return -1; } +} - String SegmentInfos::getCurrentSegmentFileName(const DirectoryPtr& directory) - { - return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(directory)); - } +String SegmentInfos::getCurrentSegmentFileName(HashSet files) { + return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(files)); +} - String SegmentInfos::getCurrentSegmentFileName() - { - return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", lastGeneration); - } +String SegmentInfos::getCurrentSegmentFileName(const DirectoryPtr& directory) { + return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", getCurrentSegmentGeneration(directory)); +} - int64_t SegmentInfos::generationFromSegmentsFileName(const String& fileName) - { - if (fileName == IndexFileNames::SEGMENTS()) - return 0; - else if (boost::starts_with(fileName, IndexFileNames::SEGMENTS())) - return StringUtils::toLong(fileName.substr(wcslen(IndexFileNames::SEGMENTS().c_str()) + 1), StringUtils::CHARACTER_MAX_RADIX); - else - boost::throw_exception(IllegalArgumentException(L"FileName '" + fileName + L"' is not a segments file")); +String SegmentInfos::getCurrentSegmentFileName() { + return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", lastGeneration); +} + +int64_t SegmentInfos::generationFromSegmentsFileName(const String& fileName) { + if (fileName == IndexFileNames::SEGMENTS()) { return 0; + } else if (boost::starts_with(fileName, IndexFileNames::SEGMENTS())) { + return StringUtils::toLong(fileName.substr(wcslen(IndexFileNames::SEGMENTS().c_str()) + 1), StringUtils::CHARACTER_MAX_RADIX); + } else { + boost::throw_exception(IllegalArgumentException(L"FileName '" + fileName + L"' is not a segments file")); } + return 0; +} - String SegmentInfos::getNextSegmentFileName() - { - return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation == -1 ? 1 : generation + 1); - } +String SegmentInfos::getNextSegmentFileName() { + return IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation == -1 ? 1 : generation + 1); +} - void SegmentInfos::read(const DirectoryPtr& directory, const String& segmentFileName) - { - bool success = false; +void SegmentInfos::read(const DirectoryPtr& directory, const String& segmentFileName) { + bool success = false; - // clear any previous segments - segmentInfos.clear(); + // clear any previous segments + segmentInfos.clear(); + + ChecksumIndexInputPtr input(newLucene(directory->openInput(segmentFileName))); + + generation = generationFromSegmentsFileName(segmentFileName); + lastGeneration = generation; + LuceneException finally; + try { + int32_t format = input->readInt(); - ChecksumIndexInputPtr input(newLucene(directory->openInput(segmentFileName))); - - generation = generationFromSegmentsFileName(segmentFileName); - lastGeneration = generation; - LuceneException finally; - try - { - int32_t format = input->readInt(); - - if (format < 0) // file contains explicit format info - { - if (format < CURRENT_FORMAT) - boost::throw_exception(CorruptIndexException(L"Unknown format version: " + StringUtils::toString(format))); - version = input->readLong(); // read version - counter = input->readInt(); // read counter + if (format < 0) { // file contains explicit format info + if (format < CURRENT_FORMAT) { + boost::throw_exception(CorruptIndexException(L"Unknown format version: " + StringUtils::toString(format))); } - else - counter = format; - - for (int32_t i = input->readInt(); i > 0; --i) // read segmentInfos - segmentInfos.add(newLucene(directory, format, input)); - - // in old format the version number may be at the end of the file - if (format >= 0) - { - if (input->getFilePointer() >= input->length()) - version = MiscUtils::currentTimeMillis(); // old file format without version number - else - input->readLong(); // read version + version = input->readLong(); // read version + counter = input->readInt(); // read counter + } else { + counter = format; + } + + for (int32_t i = input->readInt(); i > 0; --i) { // read segmentInfos + segmentInfos.add(newLucene(directory, format, input)); + } + + // in old format the version number may be at the end of the file + if (format >= 0) { + if (input->getFilePointer() >= input->length()) { + version = MiscUtils::currentTimeMillis(); // old file format without version number + } else { + input->readLong(); // read version } + } - if (format <= FORMAT_USER_DATA) - { - if (format <= FORMAT_DIAGNOSTICS) - userData = input->readStringStringMap(); - else if (input->readByte() != 0) - { - if (!singletonUserData) - singletonUserData = MapStringString::newInstance(); - singletonUserData[String(L"userData")] = input->readString(); - userData = singletonUserData; + if (format <= FORMAT_USER_DATA) { + if (format <= FORMAT_DIAGNOSTICS) { + userData = input->readStringStringMap(); + } else if (input->readByte() != 0) { + if (!singletonUserData) { + singletonUserData = MapStringString::newInstance(); } - else - userData.clear(); - } - else + singletonUserData[String(L"userData")] = input->readString(); + userData = singletonUserData; + } else { userData.clear(); - - if (format <= FORMAT_CHECKSUM) - { - int64_t checksumNow = input->getChecksum(); - int64_t checksumThen = input->readLong(); - if (checksumNow != checksumThen) - boost::throw_exception(CorruptIndexException(L"Checksum mismatch in segments file")); } - - success = true; + } else { + userData.clear(); } - catch (LuceneException& e) - { - finally = e; + + if (format <= FORMAT_CHECKSUM) { + int64_t checksumNow = input->getChecksum(); + int64_t checksumThen = input->readLong(); + if (checksumNow != checksumThen) { + boost::throw_exception(CorruptIndexException(L"Checksum mismatch in segments file")); + } } - input->close(); + success = true; + } catch (LuceneException& e) { + finally = e; + } - // clear any segment infos we had loaded so we have a clean slate on retry - if (!success) - segmentInfos.clear(); + input->close(); - finally.throwException(); + // clear any segment infos we had loaded so we have a clean slate on retry + if (!success) { + segmentInfos.clear(); } - void SegmentInfos::read(const DirectoryPtr& directory) - { - lastGeneration = -1; - generation = lastGeneration; - newLucene(shared_from_this(), directory)->run(); + finally.throwException(); +} + +void SegmentInfos::read(const DirectoryPtr& directory) { + lastGeneration = -1; + generation = lastGeneration; + newLucene(shared_from_this(), directory)->run(); +} + +void SegmentInfos::write(const DirectoryPtr& directory) { + String segmentFileName(getNextSegmentFileName()); + + // always advance the generation on write + if (generation == -1) { + generation = 1; + } else { + ++generation; } - void SegmentInfos::write(const DirectoryPtr& directory) - { - String segmentFileName(getNextSegmentFileName()); - - // always advance the generation on write - if (generation == -1) - generation = 1; - else - ++generation; - - ChecksumIndexOutputPtr segnOutput(newLucene(directory->createOutput(segmentFileName))); - - bool success = false; - LuceneException finally; - try - { - segnOutput->writeInt(CURRENT_FORMAT); // write FORMAT - segnOutput->writeLong(++version); // every write changes the index - segnOutput->writeInt(counter); // write counter - segnOutput->writeInt(segmentInfos.size()); // write infos - for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) - (*seginfo)->write(segnOutput); - segnOutput->writeStringStringMap(userData); - segnOutput->prepareCommit(); - success = true; - pendingSegnOutput = segnOutput; + ChecksumIndexOutputPtr segnOutput(newLucene(directory->createOutput(segmentFileName))); + + bool success = false; + LuceneException finally; + try { + segnOutput->writeInt(CURRENT_FORMAT); // write FORMAT + segnOutput->writeLong(++version); // every write changes the index + segnOutput->writeInt(counter); // write counter + segnOutput->writeInt(segmentInfos.size()); // write infos + for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) { + (*seginfo)->write(segnOutput); } - catch (LuceneException& e) - { - finally = e; + segnOutput->writeStringStringMap(userData); + segnOutput->prepareCommit(); + success = true; + pendingSegnOutput = segnOutput; + } catch (LuceneException& e) { + finally = e; + } + + if (!success) { + // We hit an exception above; try to close the file but suppress any exception + try { + segnOutput->close(); + } catch (...) { + // Suppress so we keep throwing the original exception } - if (!success) - { - // We hit an exception above; try to close the file but suppress any exception - try - { - segnOutput->close(); - } - catch (...) - { - // Suppress so we keep throwing the original exception - } - - try - { - // try not to leave a truncated segments_n file in the index - directory->deleteFile(segmentFileName); - } - catch (...) - { - // Suppress so we keep throwing the original exception - } + try { + // try not to leave a truncated segments_n file in the index + directory->deleteFile(segmentFileName); + } catch (...) { + // Suppress so we keep throwing the original exception } - - finally.throwException(); } - LuceneObjectPtr SegmentInfos::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = SegmentInfoCollection::clone(other ? other : newLucene()); - SegmentInfosPtr cloneInfos(boost::dynamic_pointer_cast(clone)); - cloneInfos->counter = counter; - cloneInfos->generation = generation; - cloneInfos->lastGeneration = lastGeneration; - cloneInfos->version = version; - cloneInfos->pendingSegnOutput = pendingSegnOutput; - for (int32_t i = 0; i < cloneInfos->size(); ++i) - cloneInfos->segmentInfos[i] = boost::dynamic_pointer_cast(cloneInfos->info(i)->clone()); - cloneInfos->userData = MapStringString::newInstance(); - cloneInfos->userData.putAll(userData.begin(), userData.end()); - return cloneInfos; - } + finally.throwException(); +} - int64_t SegmentInfos::getVersion() - { - return version; - } +LuceneObjectPtr SegmentInfos::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = SegmentInfoCollection::clone(other ? other : newLucene()); + SegmentInfosPtr cloneInfos(boost::dynamic_pointer_cast(clone)); + cloneInfos->counter = counter; + cloneInfos->generation = generation; + cloneInfos->lastGeneration = lastGeneration; + cloneInfos->version = version; + cloneInfos->pendingSegnOutput = pendingSegnOutput; + for (int32_t i = 0; i < cloneInfos->size(); ++i) { + cloneInfos->segmentInfos[i] = boost::dynamic_pointer_cast(cloneInfos->info(i)->clone()); + } + cloneInfos->userData = MapStringString::newInstance(); + cloneInfos->userData.putAll(userData.begin(), userData.end()); + return cloneInfos; +} - int64_t SegmentInfos::getGeneration() - { - return generation; - } +int64_t SegmentInfos::getVersion() { + return version; +} - int64_t SegmentInfos::getLastGeneration() - { - return lastGeneration; - } +int64_t SegmentInfos::getGeneration() { + return generation; +} - int64_t SegmentInfos::readCurrentVersion(const DirectoryPtr& directory) - { - // Fully read the segments file: this ensures that it's completely written so that if IndexWriter.prepareCommit has been called - // (but not yet commit), then the reader will still see itself as current. - SegmentInfosPtr sis(newLucene()); - sis->read(directory); - return sis->getVersion(); - } +int64_t SegmentInfos::getLastGeneration() { + return lastGeneration; +} - MapStringString SegmentInfos::readCurrentUserData(const DirectoryPtr& directory) - { - SegmentInfosPtr sis(newLucene()); - sis->read(directory); - return sis->getUserData(); - } +int64_t SegmentInfos::readCurrentVersion(const DirectoryPtr& directory) { + // Fully read the segments file: this ensures that it's completely written so that if IndexWriter.prepareCommit has been called + // (but not yet commit), then the reader will still see itself as current. + SegmentInfosPtr sis(newLucene()); + sis->read(directory); + return sis->getVersion(); +} - void SegmentInfos::setInfoStream(const InfoStreamPtr& infoStream) - { - SegmentInfos::infoStream = infoStream; - } +MapStringString SegmentInfos::readCurrentUserData(const DirectoryPtr& directory) { + SegmentInfosPtr sis(newLucene()); + sis->read(directory); + return sis->getUserData(); +} - void SegmentInfos::setDefaultGenFileRetryCount(int32_t count) - { - defaultGenFileRetryCount = count; - } +void SegmentInfos::setInfoStream(const InfoStreamPtr& infoStream) { + SegmentInfos::infoStream = infoStream; +} - int32_t SegmentInfos::getDefaultGenFileRetryCount() - { - return defaultGenFileRetryCount; - } +void SegmentInfos::setDefaultGenFileRetryCount(int32_t count) { + defaultGenFileRetryCount = count; +} - void SegmentInfos::setDefaultGenFileRetryPauseMsec(int32_t msec) - { - defaultGenFileRetryPauseMsec = msec; - } +int32_t SegmentInfos::getDefaultGenFileRetryCount() { + return defaultGenFileRetryCount; +} - int32_t SegmentInfos::getDefaultGenFileRetryPauseMsec() - { - return defaultGenFileRetryPauseMsec; - } +void SegmentInfos::setDefaultGenFileRetryPauseMsec(int32_t msec) { + defaultGenFileRetryPauseMsec = msec; +} - void SegmentInfos::setDefaultGenLookaheadCount(int32_t count) - { - defaultGenLookaheadCount = count; - } +int32_t SegmentInfos::getDefaultGenFileRetryPauseMsec() { + return defaultGenFileRetryPauseMsec; +} - int32_t SegmentInfos::getDefaultGenLookahedCount() - { - return defaultGenLookaheadCount; - } +void SegmentInfos::setDefaultGenLookaheadCount(int32_t count) { + defaultGenLookaheadCount = count; +} - InfoStreamPtr SegmentInfos::getInfoStream() - { - return infoStream; - } +int32_t SegmentInfos::getDefaultGenLookahedCount() { + return defaultGenLookaheadCount; +} - void SegmentInfos::message(const String& message) - { - if (infoStream) - *infoStream << L"SIS [" << message << L"]\n"; - } +InfoStreamPtr SegmentInfos::getInfoStream() { + return infoStream; +} - FindSegmentsFile::FindSegmentsFile(const SegmentInfosPtr& infos, const DirectoryPtr& directory) - { - this->_segmentInfos = infos; - this->directory = directory; +void SegmentInfos::message(const String& message) { + if (infoStream) { + *infoStream << L"SIS [" << message << L"]\n"; } +} - FindSegmentsFile::~FindSegmentsFile() - { - } +FindSegmentsFile::FindSegmentsFile(const SegmentInfosPtr& infos, const DirectoryPtr& directory) { + this->_segmentInfos = infos; + this->directory = directory; +} - void FindSegmentsFile::doRun(const IndexCommitPtr& commit) - { - if (commit) - { - if (directory != commit->getDirectory()) - boost::throw_exception(IOException(L"The specified commit does not match the specified Directory")); - runBody(commit->getSegmentsFileName()); - return; - } +FindSegmentsFile::~FindSegmentsFile() { +} - String segmentFileName; - int64_t lastGen = -1; - int64_t gen = 0; - int32_t genLookaheadCount = 0; - bool retry = false; - LuceneException exc; - SegmentInfosPtr segmentInfos(_segmentInfos); - - int32_t method = 0; - - // Loop until we succeed in calling runBody() without hitting an IOException. An IOException most likely - // means a commit was in process and has finished, in the time it took us to load the now-old infos files - // (and segments files). It's also possible it's a true error (corrupt index). To distinguish these, - // on each retry we must see "forward progress" on which generation we are trying to load. If we don't, - // then the original error is real and we throw it. - - // We have three methods for determining the current generation. We try the first two in parallel, and - // fall back to the third when necessary. - - while (true) - { - if (method == 0) - { - // Method 1: list the directory and use the highest segments_N file. This method works well as long - // as there is no stale caching on the directory contents (NOTE: NFS clients often have such stale caching) - HashSet files(directory->listAll()); - int64_t genA = segmentInfos->getCurrentSegmentGeneration(files); - - segmentInfos->message(L"directory listing genA=" + StringUtils::toString(genA)); - - // Method 2: open segments.gen and read its contents. Then we take the larger of the two gens. This way, - // if either approach is hitting a stale cache (NFS) we have a better chance of getting the right generation. - int64_t genB = -1; - for (int32_t i = 0; i < SegmentInfos::defaultGenFileRetryCount; ++i) - { - IndexInputPtr genInput; - try - { - genInput = directory->openInput(IndexFileNames::SEGMENTS_GEN()); - } - catch (FileNotFoundException& e) - { - segmentInfos->message(L"Segments.gen open: FileNotFoundException " + e.getError()); - break; - } - catch (IOException& e) - { - segmentInfos->message(L"Segments.gen open: IOException " + e.getError()); - } +void FindSegmentsFile::doRun(const IndexCommitPtr& commit) { + if (commit) { + if (directory != commit->getDirectory()) { + boost::throw_exception(IOException(L"The specified commit does not match the specified Directory")); + } + runBody(commit->getSegmentsFileName()); + return; + } + + String segmentFileName; + int64_t lastGen = -1; + int64_t gen = 0; + int32_t genLookaheadCount = 0; + bool retry = false; + LuceneException exc; + SegmentInfosPtr segmentInfos(_segmentInfos); + + int32_t method = 0; + + // Loop until we succeed in calling runBody() without hitting an IOException. An IOException most likely + // means a commit was in process and has finished, in the time it took us to load the now-old infos files + // (and segments files). It's also possible it's a true error (corrupt index). To distinguish these, + // on each retry we must see "forward progress" on which generation we are trying to load. If we don't, + // then the original error is real and we throw it. + + // We have three methods for determining the current generation. We try the first two in parallel, and + // fall back to the third when necessary. + + while (true) { + if (method == 0) { + // Method 1: list the directory and use the highest segments_N file. This method works well as long + // as there is no stale caching on the directory contents (NOTE: NFS clients often have such stale caching) + HashSet files(directory->listAll()); + int64_t genA = segmentInfos->getCurrentSegmentGeneration(files); + + segmentInfos->message(L"directory listing genA=" + StringUtils::toString(genA)); + + // Method 2: open segments.gen and read its contents. Then we take the larger of the two gens. This way, + // if either approach is hitting a stale cache (NFS) we have a better chance of getting the right generation. + int64_t genB = -1; + for (int32_t i = 0; i < SegmentInfos::defaultGenFileRetryCount; ++i) { + IndexInputPtr genInput; + try { + genInput = directory->openInput(IndexFileNames::SEGMENTS_GEN()); + } catch (FileNotFoundException& e) { + segmentInfos->message(L"Segments.gen open: FileNotFoundException " + e.getError()); + break; + } catch (IOException& e) { + segmentInfos->message(L"Segments.gen open: IOException " + e.getError()); + } - if (genInput) - { - LuceneException finally; - bool fileConsistent = false; - try - { - int32_t version = genInput->readInt(); - if (version == SegmentInfos::FORMAT_LOCKLESS) - { - int64_t gen0 = genInput->readLong(); - int64_t gen1 = genInput->readLong(); - segmentInfos->message(L"fallback check: " + StringUtils::toString(gen0) + L"; " + StringUtils::toString(gen1)); - if (gen0 == gen1) - { - // the file is consistent - genB = gen0; - fileConsistent = true; - } + if (genInput) { + LuceneException finally; + bool fileConsistent = false; + try { + int32_t version = genInput->readInt(); + if (version == SegmentInfos::FORMAT_LOCKLESS) { + int64_t gen0 = genInput->readLong(); + int64_t gen1 = genInput->readLong(); + segmentInfos->message(L"fallback check: " + StringUtils::toString(gen0) + L"; " + StringUtils::toString(gen1)); + if (gen0 == gen1) { + // the file is consistent + genB = gen0; + fileConsistent = true; } } - catch (IOException&) - { - // will retry - } - catch (LuceneException& e) - { - finally = e; - } - genInput->close(); - finally.throwException(); - if (fileConsistent) - break; + } catch (IOException&) { + // will retry + } catch (LuceneException& e) { + finally = e; + } + genInput->close(); + finally.throwException(); + if (fileConsistent) { + break; } - - LuceneThread::threadSleep(SegmentInfos::defaultGenFileRetryPauseMsec); } - segmentInfos->message(String(IndexFileNames::SEGMENTS_GEN()) + L" check: genB=" + StringUtils::toString(genB)); + LuceneThread::threadSleep(SegmentInfos::defaultGenFileRetryPauseMsec); + } - // pick the larger of the two gen's - gen = std::max(genA, genB); + segmentInfos->message(String(IndexFileNames::SEGMENTS_GEN()) + L" check: genB=" + StringUtils::toString(genB)); - // neither approach found a generation - if (gen == -1) - boost::throw_exception(FileNotFoundException(L"No segments* file found in directory")); - } + // pick the larger of the two gen's + gen = std::max(genA, genB); - // Third method (fallback if first & second methods are not reliable): since both directory cache and - // file contents cache seem to be stale, just advance the generation. - if (method == 1 || (method == 0 && lastGen == gen && retry)) - { - method = 1; - - if (genLookaheadCount < SegmentInfos::defaultGenLookaheadCount) - { - ++gen; - ++genLookaheadCount; - segmentInfos->message(L"look ahead increment gen to " + StringUtils::toString(gen)); - } + // neither approach found a generation + if (gen == -1) { + boost::throw_exception(FileNotFoundException(L"No segments* file found in directory")); } + } - if (lastGen == gen) - { - // This means we're about to try the same segments_N last tried. This is allowed, exactly once, because - // writer could have been in the process of writing segments_N last time. + // Third method (fallback if first & second methods are not reliable): since both directory cache and + // file contents cache seem to be stale, just advance the generation. + if (method == 1 || (method == 0 && lastGen == gen && retry)) { + method = 1; - if (retry) - { - // OK, we've tried the same segments_N file twice in a row, so this must be a real error. - exc.throwException(); - } - else - retry = true; + if (genLookaheadCount < SegmentInfos::defaultGenLookaheadCount) { + ++gen; + ++genLookaheadCount; + segmentInfos->message(L"look ahead increment gen to " + StringUtils::toString(gen)); } - else if (method == 0) - { - // Segment file has advanced since our last loop, so reset retry - retry = false; + } + + if (lastGen == gen) { + // This means we're about to try the same segments_N last tried. This is allowed, exactly once, because + // writer could have been in the process of writing segments_N last time. + + if (retry) { + // OK, we've tried the same segments_N file twice in a row, so this must be a real error. + exc.throwException(); + } else { + retry = true; } + } else if (method == 0) { + // Segment file has advanced since our last loop, so reset retry + retry = false; + } - lastGen = gen; + lastGen = gen; - segmentFileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen); + segmentFileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen); - try - { - runBody(segmentFileName); - segmentInfos->message(L"success on " + segmentFileName); - return; + try { + runBody(segmentFileName); + segmentInfos->message(L"success on " + segmentFileName); + return; + } catch (LuceneException& err) { + // Save the original root cause + if (exc.isNull()) { + exc = err; } - catch (LuceneException& err) - { - // Save the original root cause - if (exc.isNull()) - exc = err; - - segmentInfos->message(L"primary Exception on '" + segmentFileName + L"': " + err.getError() + L"'; will retry: retry=" + StringUtils::toString(retry) + L"; gen = " + StringUtils::toString(gen)); - - if (!retry && gen > 1) - { - // This is our first time trying this segments file (because retry is false), and, there is possibly a - // segments_(N-1) (because gen > 1). So, check if the segments_(N-1) exists and try it if so. - String prevSegmentFileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen - 1)); - - if (directory->fileExists(prevSegmentFileName)) - { - segmentInfos->message(L"fallback to prior segment file '" + prevSegmentFileName + L"'"); - - try - { - runBody(prevSegmentFileName); - if (!exc.isNull()) - segmentInfos->message(L"success on fallback " + prevSegmentFileName); - return; - } - catch (LuceneException& err2) - { - segmentInfos->message(L"secondary Exception on '" + prevSegmentFileName + L"': " + err2.getError() + L"'; will retry"); + + segmentInfos->message(L"primary Exception on '" + segmentFileName + L"': " + err.getError() + L"'; will retry: retry=" + StringUtils::toString(retry) + L"; gen = " + StringUtils::toString(gen)); + + if (!retry && gen > 1) { + // This is our first time trying this segments file (because retry is false), and, there is possibly a + // segments_(N-1) (because gen > 1). So, check if the segments_(N-1) exists and try it if so. + String prevSegmentFileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen - 1)); + + if (directory->fileExists(prevSegmentFileName)) { + segmentInfos->message(L"fallback to prior segment file '" + prevSegmentFileName + L"'"); + + try { + runBody(prevSegmentFileName); + if (!exc.isNull()) { + segmentInfos->message(L"success on fallback " + prevSegmentFileName); } + return; + } catch (LuceneException& err2) { + segmentInfos->message(L"secondary Exception on '" + prevSegmentFileName + L"': " + err2.getError() + L"'; will retry"); } } } } } +} - FindSegmentsRead::FindSegmentsRead(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) - { - result = 0; - } +FindSegmentsRead::FindSegmentsRead(const SegmentInfosPtr& infos, const DirectoryPtr& directory) : FindSegmentsFileT(infos, directory) { + result = 0; +} - FindSegmentsRead::~FindSegmentsRead() - { - } +FindSegmentsRead::~FindSegmentsRead() { +} - int64_t FindSegmentsRead::doBody(const String& segmentFileName) - { - SegmentInfosPtr(_segmentInfos)->read(directory, segmentFileName); - return 0; - } +int64_t FindSegmentsRead::doBody(const String& segmentFileName) { + SegmentInfosPtr(_segmentInfos)->read(directory, segmentFileName); + return 0; +} - SegmentInfosPtr SegmentInfos::range(int32_t first, int32_t last) - { - SegmentInfosPtr infos(newLucene()); - infos->segmentInfos.addAll(segmentInfos.begin() + first, segmentInfos.begin() + last); - return infos; - } +SegmentInfosPtr SegmentInfos::range(int32_t first, int32_t last) { + SegmentInfosPtr infos(newLucene()); + infos->segmentInfos.addAll(segmentInfos.begin() + first, segmentInfos.begin() + last); + return infos; +} - void SegmentInfos::updateGeneration(const SegmentInfosPtr& other) - { - lastGeneration = other->lastGeneration; - generation = other->generation; - version = other->version; - } +void SegmentInfos::updateGeneration(const SegmentInfosPtr& other) { + lastGeneration = other->lastGeneration; + generation = other->generation; + version = other->version; +} - void SegmentInfos::rollbackCommit(const DirectoryPtr& dir) - { - if (pendingSegnOutput) - { - try - { - pendingSegnOutput->close(); - } - catch (...) - { - } +void SegmentInfos::rollbackCommit(const DirectoryPtr& dir) { + if (pendingSegnOutput) { + try { + pendingSegnOutput->close(); + } catch (...) { + } - // must carefully compute filename from "generation" since lastgeneration isn't incremented - try - { - String segmentFileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation)); - dir->deleteFile(segmentFileName); - } - catch (...) - { - } - pendingSegnOutput.reset(); + // must carefully compute filename from "generation" since lastgeneration isn't incremented + try { + String segmentFileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation)); + dir->deleteFile(segmentFileName); + } catch (...) { } + pendingSegnOutput.reset(); } +} - void SegmentInfos::prepareCommit(const DirectoryPtr& dir) - { - TestScope testScope(L"SegmentInfos", L"prepareCommit"); - if (pendingSegnOutput) - boost::throw_exception(IllegalStateException(L"prepareCommit was already called")); - write(dir); +void SegmentInfos::prepareCommit(const DirectoryPtr& dir) { + TestScope testScope(L"SegmentInfos", L"prepareCommit"); + if (pendingSegnOutput) { + boost::throw_exception(IllegalStateException(L"prepareCommit was already called")); } + write(dir); +} - HashSet SegmentInfos::files(const DirectoryPtr& dir, bool includeSegmentsFile) - { - HashSet files(HashSet::newInstance()); - if (includeSegmentsFile) - files.add(getCurrentSegmentFileName()); - for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) - { - if ((*seginfo)->dir == dir) - { - HashSet segFiles((*seginfo)->files()); - files.addAll(segFiles.begin(), segFiles.end()); - } +HashSet SegmentInfos::files(const DirectoryPtr& dir, bool includeSegmentsFile) { + HashSet files(HashSet::newInstance()); + if (includeSegmentsFile) { + files.add(getCurrentSegmentFileName()); + } + for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) { + if ((*seginfo)->dir == dir) { + HashSet segFiles((*seginfo)->files()); + files.addAll(segFiles.begin(), segFiles.end()); } - return files; } + return files; +} - void SegmentInfos::finishCommit(const DirectoryPtr& dir) - { - if (!pendingSegnOutput) - boost::throw_exception(IllegalStateException(L"prepareCommit was not called")); - - bool success = false; - LuceneException finally; - try - { - pendingSegnOutput->finishCommit(); - pendingSegnOutput->close(); - pendingSegnOutput.reset(); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } +void SegmentInfos::finishCommit(const DirectoryPtr& dir) { + if (!pendingSegnOutput) { + boost::throw_exception(IllegalStateException(L"prepareCommit was not called")); + } - if (!success) - rollbackCommit(dir); - finally.throwException(); + bool success = false; + LuceneException finally; + try { + pendingSegnOutput->finishCommit(); + pendingSegnOutput->close(); + pendingSegnOutput.reset(); + success = true; + } catch (LuceneException& e) { + finally = e; + } - // NOTE: if we crash here, we have left a segments_N file in the directory in a possibly corrupt state (if - // some bytes made it to stable storage and others didn't). But, the segments_N file includes checksum - // at the end, which should catch this case. So when a reader tries to read it, it will throw a - // CorruptIndexException, which should cause the retry logic in SegmentInfos to kick in and load the last - // good (previous) segments_N-1 file. + if (!success) { + rollbackCommit(dir); + } + finally.throwException(); - String fileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation)); + // NOTE: if we crash here, we have left a segments_N file in the directory in a possibly corrupt state (if + // some bytes made it to stable storage and others didn't). But, the segments_N file includes checksum + // at the end, which should catch this case. So when a reader tries to read it, it will throw a + // CorruptIndexException, which should cause the retry logic in SegmentInfos to kick in and load the last + // good (previous) segments_N-1 file. - success = false; - try - { - dir->sync(fileName); - success = true; - } - catch (...) - { - } + String fileName(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", generation)); - if (!success) - dir->deleteFile(fileName); + success = false; + try { + dir->sync(fileName); + success = true; + } catch (...) { + } - lastGeneration = generation; - IndexOutputPtr genOutput; - try - { - genOutput = dir->createOutput(IndexFileNames::SEGMENTS_GEN()); + if (!success) { + dir->deleteFile(fileName); + } - try - { - genOutput->writeInt(FORMAT_LOCKLESS); - genOutput->writeLong(generation); - genOutput->writeLong(generation); - } - catch (LuceneException& e) - { - finally = e; - } + lastGeneration = generation; + IndexOutputPtr genOutput; + try { + genOutput = dir->createOutput(IndexFileNames::SEGMENTS_GEN()); - genOutput->close(); - finally.throwException(); - } - catch (...) - { + try { + genOutput->writeInt(FORMAT_LOCKLESS); + genOutput->writeLong(generation); + genOutput->writeLong(generation); + } catch (LuceneException& e) { + finally = e; } - } - void SegmentInfos::commit(const DirectoryPtr& dir) - { - prepareCommit(dir); - finishCommit(dir); + genOutput->close(); + finally.throwException(); + } catch (...) { } +} - String SegmentInfos::segString(const DirectoryPtr& directory) - { - SyncLock syncLock(this); - String buffer; - for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) - { - if (seginfo != segmentInfos.begin()) - buffer += L' '; - buffer += (*seginfo)->segString(directory); - if ((*seginfo)->dir != directory) - buffer += L"**"; +void SegmentInfos::commit(const DirectoryPtr& dir) { + prepareCommit(dir); + finishCommit(dir); +} + +String SegmentInfos::segString(const DirectoryPtr& directory) { + SyncLock syncLock(this); + String buffer; + for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) { + if (seginfo != segmentInfos.begin()) { + buffer += L' '; + } + buffer += (*seginfo)->segString(directory); + if ((*seginfo)->dir != directory) { + buffer += L"**"; } - return buffer; } + return buffer; +} - MapStringString SegmentInfos::getUserData() - { - return userData; - } +MapStringString SegmentInfos::getUserData() { + return userData; +} - void SegmentInfos::setUserData(MapStringString data) - { - if (!data) - userData = MapStringString::newInstance(); - else - userData = data; +void SegmentInfos::setUserData(MapStringString data) { + if (!data) { + userData = MapStringString::newInstance(); + } else { + userData = data; } +} - void SegmentInfos::replace(const SegmentInfosPtr& other) - { - segmentInfos.clear(); - segmentInfos.addAll(other->segmentInfos.begin(), other->segmentInfos.end()); - lastGeneration = other->lastGeneration; - } +void SegmentInfos::replace(const SegmentInfosPtr& other) { + segmentInfos.clear(); + segmentInfos.addAll(other->segmentInfos.begin(), other->segmentInfos.end()); + lastGeneration = other->lastGeneration; +} - bool SegmentInfos::hasExternalSegments(const DirectoryPtr& dir) - { - for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) - { - if ((*seginfo)->dir != dir) - return true; +bool SegmentInfos::hasExternalSegments(const DirectoryPtr& dir) { + for (Collection::iterator seginfo = segmentInfos.begin(); seginfo != segmentInfos.end(); ++seginfo) { + if ((*seginfo)->dir != dir) { + return true; } - return false; } + return false; +} + } diff --git a/src/core/index/SegmentMergeInfo.cpp b/src/core/index/SegmentMergeInfo.cpp index aeafe13a..0379e38e 100644 --- a/src/core/index/SegmentMergeInfo.cpp +++ b/src/core/index/SegmentMergeInfo.cpp @@ -10,75 +10,65 @@ #include "TermEnum.h" #include "TermPositions.h" -namespace Lucene -{ - SegmentMergeInfo::SegmentMergeInfo(int32_t b, const TermEnumPtr& te, const IndexReaderPtr& r) - { - base = b; - _reader = r; - termEnum = te; - term = te->term(); - ord = 0; - delCount = 0; - } +namespace Lucene { - SegmentMergeInfo::~SegmentMergeInfo() - { - } +SegmentMergeInfo::SegmentMergeInfo(int32_t b, const TermEnumPtr& te, const IndexReaderPtr& r) { + base = b; + _reader = r; + termEnum = te; + term = te->term(); + ord = 0; + delCount = 0; +} - Collection SegmentMergeInfo::getDocMap() - { - if (!docMap) - { - delCount = 0; - IndexReaderPtr reader(_reader); +SegmentMergeInfo::~SegmentMergeInfo() { +} + +Collection SegmentMergeInfo::getDocMap() { + if (!docMap) { + delCount = 0; + IndexReaderPtr reader(_reader); - // build array which maps document numbers around deletions - if (reader->hasDeletions()) - { - int32_t maxDoc = reader->maxDoc(); - docMap = Collection::newInstance(maxDoc); - int32_t j = 0; - for (int32_t i = 0; i < maxDoc; ++i) - { - if (reader->isDeleted(i)) - { - ++delCount; - docMap[i] = -1; - } - else - docMap[i] = j++; + // build array which maps document numbers around deletions + if (reader->hasDeletions()) { + int32_t maxDoc = reader->maxDoc(); + docMap = Collection::newInstance(maxDoc); + int32_t j = 0; + for (int32_t i = 0; i < maxDoc; ++i) { + if (reader->isDeleted(i)) { + ++delCount; + docMap[i] = -1; + } else { + docMap[i] = j++; } } } - return docMap; } + return docMap; +} - TermPositionsPtr SegmentMergeInfo::getPositions() - { - if (!postings) - postings = IndexReaderPtr(_reader)->termPositions(); - return postings; +TermPositionsPtr SegmentMergeInfo::getPositions() { + if (!postings) { + postings = IndexReaderPtr(_reader)->termPositions(); } + return postings; +} - bool SegmentMergeInfo::next() - { - if (termEnum->next()) - { - term = termEnum->term(); - return true; - } - else - { - term.reset(); - return false; - } +bool SegmentMergeInfo::next() { + if (termEnum->next()) { + term = termEnum->term(); + return true; + } else { + term.reset(); + return false; } +} - void SegmentMergeInfo::close() - { - termEnum->close(); - if (postings) - postings->close(); +void SegmentMergeInfo::close() { + termEnum->close(); + if (postings) { + postings->close(); } } + +} diff --git a/src/core/index/SegmentMergeQueue.cpp b/src/core/index/SegmentMergeQueue.cpp index 257f8f37..1dfd7a24 100644 --- a/src/core/index/SegmentMergeQueue.cpp +++ b/src/core/index/SegmentMergeQueue.cpp @@ -8,25 +8,23 @@ #include "SegmentMergeQueue.h" #include "SegmentMergeInfo.h" -namespace Lucene -{ - SegmentMergeQueue::SegmentMergeQueue(int32_t size) : PriorityQueue(size) - { - } +namespace Lucene { - SegmentMergeQueue::~SegmentMergeQueue() - { - } +SegmentMergeQueue::SegmentMergeQueue(int32_t size) : PriorityQueue(size) { +} - void SegmentMergeQueue::close() - { - while (top()) - pop()->close(); - } +SegmentMergeQueue::~SegmentMergeQueue() { +} - bool SegmentMergeQueue::lessThan(const SegmentMergeInfoPtr& first, const SegmentMergeInfoPtr& second) - { - int32_t comparison = first->term->compareTo(second->term); - return comparison == 0 ? (first->base < second->base) : (comparison < 0); +void SegmentMergeQueue::close() { + while (top()) { + pop()->close(); } } + +bool SegmentMergeQueue::lessThan(const SegmentMergeInfoPtr& first, const SegmentMergeInfoPtr& second) { + int32_t comparison = first->term->compareTo(second->term); + return comparison == 0 ? (first->base < second->base) : (comparison < 0); +} + +} diff --git a/src/core/index/SegmentMerger.cpp b/src/core/index/SegmentMerger.cpp index d6984cd3..630b0f88 100644 --- a/src/core/index/SegmentMerger.cpp +++ b/src/core/index/SegmentMerger.cpp @@ -32,738 +32,650 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// Maximum number of contiguous documents to bulk-copy when merging stored fields - const int32_t SegmentMerger::MAX_RAW_MERGE_DOCS = 4192; - - /// norms header placeholder - const uint8_t SegmentMerger::NORMS_HEADER[] = {'N', 'R', 'M', static_cast(-1) }; - const int32_t SegmentMerger::NORMS_HEADER_LENGTH = 4; - - SegmentMerger::SegmentMerger(const DirectoryPtr& dir, const String& name) - { - readers = Collection::newInstance(); - termIndexInterval = IndexWriter::DEFAULT_TERM_INDEX_INTERVAL; - mergedDocs = 0; - mergeDocStores = false; - omitTermFreqAndPositions = false; - - directory = dir; - segment = name; - checkAbort = newLucene(); - } +namespace Lucene { - SegmentMerger::SegmentMerger(const IndexWriterPtr& writer, const String& name, const OneMergePtr& merge) - { - readers = Collection::newInstance(); - mergedDocs = 0; - mergeDocStores = false; - omitTermFreqAndPositions = false; - - directory = writer->getDirectory(); - segment = name; - - if (merge) - checkAbort = newLucene(merge, directory); - else - checkAbort = newLucene(); - termIndexInterval = writer->getTermIndexInterval(); - } +/// Maximum number of contiguous documents to bulk-copy when merging stored fields +const int32_t SegmentMerger::MAX_RAW_MERGE_DOCS = 4192; - SegmentMerger::~SegmentMerger() - { - } +/// norms header placeholder +const uint8_t SegmentMerger::NORMS_HEADER[] = {'N', 'R', 'M', static_cast(-1) }; +const int32_t SegmentMerger::NORMS_HEADER_LENGTH = 4; - bool SegmentMerger::hasProx() - { - return fieldInfos->hasProx(); - } +SegmentMerger::SegmentMerger(const DirectoryPtr& dir, const String& name) { + readers = Collection::newInstance(); + termIndexInterval = IndexWriter::DEFAULT_TERM_INDEX_INTERVAL; + mergedDocs = 0; + mergeDocStores = false; + omitTermFreqAndPositions = false; - void SegmentMerger::add(const IndexReaderPtr& reader) - { - readers.add(reader); - } + directory = dir; + segment = name; + checkAbort = newLucene(); +} - IndexReaderPtr SegmentMerger::segmentReader(int32_t i) - { - return readers[i]; - } +SegmentMerger::SegmentMerger(const IndexWriterPtr& writer, const String& name, const OneMergePtr& merge) { + readers = Collection::newInstance(); + mergedDocs = 0; + mergeDocStores = false; + omitTermFreqAndPositions = false; - int32_t SegmentMerger::merge() - { - return merge(true); + directory = writer->getDirectory(); + segment = name; + + if (merge) { + checkAbort = newLucene(merge, directory); + } else { + checkAbort = newLucene(); } + termIndexInterval = writer->getTermIndexInterval(); +} + +SegmentMerger::~SegmentMerger() { +} + +bool SegmentMerger::hasProx() { + return fieldInfos->hasProx(); +} - int32_t SegmentMerger::merge(bool mergeDocStores) - { - this->mergeDocStores = mergeDocStores; +void SegmentMerger::add(const IndexReaderPtr& reader) { + readers.add(reader); +} - // NOTE: it's important to add calls to checkAbort.work(...) if you make any changes to this method that will spend a lot of time. - // The frequency of this check impacts how long IndexWriter.close(false) takes to actually stop the threads. +IndexReaderPtr SegmentMerger::segmentReader(int32_t i) { + return readers[i]; +} - mergedDocs = mergeFields(); - mergeTerms(); - mergeNorms(); +int32_t SegmentMerger::merge() { + return merge(true); +} - if (mergeDocStores && fieldInfos->hasVectors()) - mergeVectors(); +int32_t SegmentMerger::merge(bool mergeDocStores) { + this->mergeDocStores = mergeDocStores; - return mergedDocs; - } + // NOTE: it's important to add calls to checkAbort.work(...) if you make any changes to this method that will spend a lot of time. + // The frequency of this check impacts how long IndexWriter.close(false) takes to actually stop the threads. + + mergedDocs = mergeFields(); + mergeTerms(); + mergeNorms(); - void SegmentMerger::closeReaders() - { - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - (*reader)->close(); + if (mergeDocStores && fieldInfos->hasVectors()) { + mergeVectors(); } - HashSet SegmentMerger::getMergedFiles() - { - HashSet fileSet(HashSet::newInstance()); + return mergedDocs; +} - // Basic files - for (HashSet::iterator ext = IndexFileNames::COMPOUND_EXTENSIONS().begin(); ext != IndexFileNames::COMPOUND_EXTENSIONS().end(); ++ext) - { - if (*ext == IndexFileNames::PROX_EXTENSION() && !hasProx()) - continue; +void SegmentMerger::closeReaders() { + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + (*reader)->close(); + } +} - if (mergeDocStores || (*ext != IndexFileNames::FIELDS_EXTENSION() && *ext != IndexFileNames::FIELDS_INDEX_EXTENSION())) - fileSet.add(segment + L"." + *ext); - } +HashSet SegmentMerger::getMergedFiles() { + HashSet fileSet(HashSet::newInstance()); - // Fieldable norm files - for (int32_t i = 0; i < fieldInfos->size(); ++i) - { - FieldInfoPtr fi(fieldInfos->fieldInfo(i)); - if (fi->isIndexed && !fi->omitNorms) - { - fileSet.add(segment + L"." + IndexFileNames::NORMS_EXTENSION()); - break; - } + // Basic files + for (HashSet::iterator ext = IndexFileNames::COMPOUND_EXTENSIONS().begin(); ext != IndexFileNames::COMPOUND_EXTENSIONS().end(); ++ext) { + if (*ext == IndexFileNames::PROX_EXTENSION() && !hasProx()) { + continue; } - // Vector files - if (fieldInfos->hasVectors() && mergeDocStores) - { - for (HashSet::iterator ext = IndexFileNames::VECTOR_EXTENSIONS().begin(); ext != IndexFileNames::VECTOR_EXTENSIONS().end(); ++ext) - fileSet.add(segment + L"." + *ext); + if (mergeDocStores || (*ext != IndexFileNames::FIELDS_EXTENSION() && *ext != IndexFileNames::FIELDS_INDEX_EXTENSION())) { + fileSet.add(segment + L"." + *ext); } + } - return fileSet; + // Fieldable norm files + for (int32_t i = 0; i < fieldInfos->size(); ++i) { + FieldInfoPtr fi(fieldInfos->fieldInfo(i)); + if (fi->isIndexed && !fi->omitNorms) { + fileSet.add(segment + L"." + IndexFileNames::NORMS_EXTENSION()); + break; + } } - HashSet SegmentMerger::createCompoundFile(const String& fileName) - { - HashSet files(getMergedFiles()); - CompoundFileWriterPtr cfsWriter(newLucene(directory, fileName, checkAbort)); + // Vector files + if (fieldInfos->hasVectors() && mergeDocStores) { + for (HashSet::iterator ext = IndexFileNames::VECTOR_EXTENSIONS().begin(); ext != IndexFileNames::VECTOR_EXTENSIONS().end(); ++ext) { + fileSet.add(segment + L"." + *ext); + } + } - // Now merge all added files - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - cfsWriter->addFile(*file); + return fileSet; +} - // Perform the merge - cfsWriter->close(); +HashSet SegmentMerger::createCompoundFile(const String& fileName) { + HashSet files(getMergedFiles()); + CompoundFileWriterPtr cfsWriter(newLucene(directory, fileName, checkAbort)); - return files; + // Now merge all added files + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { + cfsWriter->addFile(*file); } - void SegmentMerger::addIndexed(const IndexReaderPtr& reader, const FieldInfosPtr& fInfos, HashSet names, - bool storeTermVectors, bool storePositionWithTermVector, - bool storeOffsetWithTermVector, bool storePayloads, bool omitTFAndPositions) - { - for (HashSet::iterator field = names.begin(); field != names.end(); ++field) - { - fInfos->add(*field, true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector, - !reader->hasNorms(*field), storePayloads, omitTFAndPositions); - } + // Perform the merge + cfsWriter->close(); + + return files; +} + +void SegmentMerger::addIndexed(const IndexReaderPtr& reader, const FieldInfosPtr& fInfos, HashSet names, + bool storeTermVectors, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool storePayloads, bool omitTFAndPositions) { + for (HashSet::iterator field = names.begin(); field != names.end(); ++field) { + fInfos->add(*field, true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector, + !reader->hasNorms(*field), storePayloads, omitTFAndPositions); } +} - void SegmentMerger::setMatchingSegmentReaders() - { - // If the i'th reader is a SegmentReader and has identical fieldName -> number mapping, then - // this array will be non-null at position i - int32_t numReaders = readers.size(); - matchingSegmentReaders = Collection::newInstance(numReaders); - - // If this reader is a SegmentReader, and all of its field name -> number mappings match the - // "merged" FieldInfos, then we can do a bulk copy of the stored fields - for (int32_t i = 0; i < numReaders; ++i) - { - IndexReaderPtr reader(readers[i]); - SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(reader)); - if (segmentReader) - { - bool same = true; - FieldInfosPtr segmentFieldInfos(segmentReader->fieldInfos()); - int32_t numFieldInfos = segmentFieldInfos->size(); - for (int32_t j = 0; same && j < numFieldInfos; ++j) - same = (fieldInfos->fieldName(j) == segmentFieldInfos->fieldName(j)); - if (same) - matchingSegmentReaders[i] = segmentReader; +void SegmentMerger::setMatchingSegmentReaders() { + // If the i'th reader is a SegmentReader and has identical fieldName -> number mapping, then + // this array will be non-null at position i + int32_t numReaders = readers.size(); + matchingSegmentReaders = Collection::newInstance(numReaders); + + // If this reader is a SegmentReader, and all of its field name -> number mappings match the + // "merged" FieldInfos, then we can do a bulk copy of the stored fields + for (int32_t i = 0; i < numReaders; ++i) { + IndexReaderPtr reader(readers[i]); + SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(reader)); + if (segmentReader) { + bool same = true; + FieldInfosPtr segmentFieldInfos(segmentReader->fieldInfos()); + int32_t numFieldInfos = segmentFieldInfos->size(); + for (int32_t j = 0; same && j < numFieldInfos; ++j) { + same = (fieldInfos->fieldName(j) == segmentFieldInfos->fieldName(j)); + } + if (same) { + matchingSegmentReaders[i] = segmentReader; } } + } + + // Used for bulk-reading raw bytes for stored fields + rawDocLengths = Collection::newInstance(MAX_RAW_MERGE_DOCS); + rawDocLengths2 = Collection::newInstance(MAX_RAW_MERGE_DOCS); +} - // Used for bulk-reading raw bytes for stored fields - rawDocLengths = Collection::newInstance(MAX_RAW_MERGE_DOCS); - rawDocLengths2 = Collection::newInstance(MAX_RAW_MERGE_DOCS); +int32_t SegmentMerger::mergeFields() { + if (!mergeDocStores) { + // When we are not merging by doc stores, their field name -> number mapping are the same. + // So, we start with the fieldInfos of the last segment in this case, to keep that numbering + fieldInfos = boost::dynamic_pointer_cast(boost::dynamic_pointer_cast(readers[readers.size() - 1])->core->fieldInfos->clone()); + } else { + fieldInfos = newLucene(); // merge field names } - int32_t SegmentMerger::mergeFields() - { - if (!mergeDocStores) - { - // When we are not merging by doc stores, their field name -> number mapping are the same. - // So, we start with the fieldInfos of the last segment in this case, to keep that numbering - fieldInfos = boost::dynamic_pointer_cast(boost::dynamic_pointer_cast(readers[readers.size() - 1])->core->fieldInfos->clone()); - } - else - fieldInfos = newLucene(); // merge field names - - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(*reader)); - if (segmentReader) - { - FieldInfosPtr readerFieldInfos(segmentReader->fieldInfos()); - int32_t numReaderFieldInfos = readerFieldInfos->size(); - for (int32_t j = 0; j < numReaderFieldInfos; ++j) - { - FieldInfoPtr fi(readerFieldInfos->fieldInfo(j)); - fieldInfos->add(fi->name, fi->isIndexed, fi->storeTermVector, fi->storePositionWithTermVector, - fi->storeOffsetWithTermVector, !(*reader)->hasNorms(fi->name), fi->storePayloads, - fi->omitTermFreqAndPositions); - } - } - else - { - addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET), true, true, true, false, false); - addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_POSITION), true, true, false, false, false); - addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_OFFSET), true, false, true, false, false); - addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR), true, false, false, false, false); - addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_OMIT_TERM_FREQ_AND_POSITIONS), false, false, false, false, true); - addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_STORES_PAYLOADS), false, false, false, true, false); - addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_INDEXED), false, false, false, false, false); - fieldInfos->add((*reader)->getFieldNames(IndexReader::FIELD_OPTION_UNINDEXED), false); + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(*reader)); + if (segmentReader) { + FieldInfosPtr readerFieldInfos(segmentReader->fieldInfos()); + int32_t numReaderFieldInfos = readerFieldInfos->size(); + for (int32_t j = 0; j < numReaderFieldInfos; ++j) { + FieldInfoPtr fi(readerFieldInfos->fieldInfo(j)); + fieldInfos->add(fi->name, fi->isIndexed, fi->storeTermVector, fi->storePositionWithTermVector, + fi->storeOffsetWithTermVector, !(*reader)->hasNorms(fi->name), fi->storePayloads, + fi->omitTermFreqAndPositions); } + } else { + addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET), true, true, true, false, false); + addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_POSITION), true, true, false, false, false); + addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR_WITH_OFFSET), true, false, true, false, false); + addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_TERMVECTOR), true, false, false, false, false); + addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_OMIT_TERM_FREQ_AND_POSITIONS), false, false, false, false, true); + addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_STORES_PAYLOADS), false, false, false, true, false); + addIndexed(*reader, fieldInfos, (*reader)->getFieldNames(IndexReader::FIELD_OPTION_INDEXED), false, false, false, false, false); + fieldInfos->add((*reader)->getFieldNames(IndexReader::FIELD_OPTION_UNINDEXED), false); } - fieldInfos->write(directory, segment + L".fnm"); + } + fieldInfos->write(directory, segment + L".fnm"); - int32_t docCount = 0; + int32_t docCount = 0; + + setMatchingSegmentReaders(); + + if (mergeDocStores) { + // merge field values + FieldsWriterPtr fieldsWriter(newLucene(directory, segment, fieldInfos)); - setMatchingSegmentReaders(); - - if (mergeDocStores) - { - // merge field values - FieldsWriterPtr fieldsWriter(newLucene(directory, segment, fieldInfos)); - - LuceneException finally; - try - { - int32_t idx = 0; - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - SegmentReaderPtr matchingSegmentReader(matchingSegmentReaders[idx++]); - FieldsReaderPtr matchingFieldsReader; - if (matchingSegmentReader) - { - FieldsReaderPtr fieldsReader(matchingSegmentReader->getFieldsReader()); - if (fieldsReader && fieldsReader->canReadRawDocs()) - matchingFieldsReader = fieldsReader; + LuceneException finally; + try { + int32_t idx = 0; + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + SegmentReaderPtr matchingSegmentReader(matchingSegmentReaders[idx++]); + FieldsReaderPtr matchingFieldsReader; + if (matchingSegmentReader) { + FieldsReaderPtr fieldsReader(matchingSegmentReader->getFieldsReader()); + if (fieldsReader && fieldsReader->canReadRawDocs()) { + matchingFieldsReader = fieldsReader; } - if ((*reader)->hasDeletions()) - docCount += copyFieldsWithDeletions(fieldsWriter, *reader, matchingFieldsReader); - else - docCount += copyFieldsNoDeletions(fieldsWriter, *reader, matchingFieldsReader); + } + if ((*reader)->hasDeletions()) { + docCount += copyFieldsWithDeletions(fieldsWriter, *reader, matchingFieldsReader); + } else { + docCount += copyFieldsNoDeletions(fieldsWriter, *reader, matchingFieldsReader); } } - catch (LuceneException& e) - { - finally = e; - } - fieldsWriter->close(); - finally.throwException(); - - String fileName(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - int64_t fdxFileLength = directory->fileLength(fileName); - - if (4 + ((int64_t)docCount) * 8 != fdxFileLength) - { - boost::throw_exception(RuntimeException(L"mergeFields produced an invalid result: docCount is " + - StringUtils::toString(docCount) + L" but fdx file size is " + - StringUtils::toString(fdxFileLength) + L" file=" + fileName + - L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + - L"; now aborting this merge to prevent index corruption")); - } - } - else - { - // If we are skipping the doc stores, that means there are no deletions in any of these segments, - // so we just sum numDocs() of each segment to get total docCount - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - docCount += (*reader)->numDocs(); + } catch (LuceneException& e) { + finally = e; } + fieldsWriter->close(); + finally.throwException(); + + String fileName(segment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); + int64_t fdxFileLength = directory->fileLength(fileName); - return docCount; + if (4 + ((int64_t)docCount) * 8 != fdxFileLength) { + boost::throw_exception(RuntimeException(L"mergeFields produced an invalid result: docCount is " + + StringUtils::toString(docCount) + L" but fdx file size is " + + StringUtils::toString(fdxFileLength) + L" file=" + fileName + + L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + + L"; now aborting this merge to prevent index corruption")); + } + } else { + // If we are skipping the doc stores, that means there are no deletions in any of these segments, + // so we just sum numDocs() of each segment to get total docCount + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + docCount += (*reader)->numDocs(); + } } - int32_t SegmentMerger::copyFieldsWithDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader) - { - int32_t docCount = 0; - int32_t maxDoc = reader->maxDoc(); - if (matchingFieldsReader) - { - // We can bulk-copy because the fieldInfos are "congruent" - for (int32_t j = 0; j < maxDoc;) - { - if (reader->isDeleted(j)) - { - // skip deleted docs - ++j; - continue; + return docCount; +} + +int32_t SegmentMerger::copyFieldsWithDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader) { + int32_t docCount = 0; + int32_t maxDoc = reader->maxDoc(); + if (matchingFieldsReader) { + // We can bulk-copy because the fieldInfos are "congruent" + for (int32_t j = 0; j < maxDoc;) { + if (reader->isDeleted(j)) { + // skip deleted docs + ++j; + continue; + } + // We can optimize this case (doing a bulk byte copy) since the field numbers are identical + int32_t start = j; + int32_t numDocs = 0; + do { + ++j; + ++numDocs; + if (j >= maxDoc) { + break; } - // We can optimize this case (doing a bulk byte copy) since the field numbers are identical - int32_t start = j; - int32_t numDocs = 0; - do - { + if (reader->isDeleted(j)) { ++j; - ++numDocs; - if (j >= maxDoc) - break; - if (reader->isDeleted(j)) - { - ++j; - break; - } + break; } - while (numDocs < MAX_RAW_MERGE_DOCS); + } while (numDocs < MAX_RAW_MERGE_DOCS); - IndexInputPtr stream(matchingFieldsReader->rawDocs(rawDocLengths, start, numDocs)); - fieldsWriter->addRawDocuments(stream, rawDocLengths, numDocs); - docCount += numDocs; - checkAbort->work(300 * numDocs); - } + IndexInputPtr stream(matchingFieldsReader->rawDocs(rawDocLengths, start, numDocs)); + fieldsWriter->addRawDocuments(stream, rawDocLengths, numDocs); + docCount += numDocs; + checkAbort->work(300 * numDocs); } - else - { - for (int32_t j = 0; j < maxDoc; ++j) - { - if (reader->isDeleted(j)) - { - // skip deleted docs - continue; - } - - // NOTE: it's very important to first assign to doc then pass it to termVectorsWriter.addAllDocVectors - fieldsWriter->addDocument(reader->document(j)); - ++docCount; - checkAbort->work(300); + } else { + for (int32_t j = 0; j < maxDoc; ++j) { + if (reader->isDeleted(j)) { + // skip deleted docs + continue; } + + // NOTE: it's very important to first assign to doc then pass it to termVectorsWriter.addAllDocVectors + fieldsWriter->addDocument(reader->document(j)); + ++docCount; + checkAbort->work(300); } - return docCount; } + return docCount; +} - int32_t SegmentMerger::copyFieldsNoDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader) - { - int32_t docCount = 0; - int32_t maxDoc = reader->maxDoc(); - if (matchingFieldsReader) - { - // We can bulk-copy because the fieldInfos are "congruent" - while (docCount < maxDoc) - { - int32_t len = std::min(MAX_RAW_MERGE_DOCS, maxDoc - docCount); - IndexInputPtr stream(matchingFieldsReader->rawDocs(rawDocLengths, docCount, len)); - fieldsWriter->addRawDocuments(stream, rawDocLengths, len); - docCount += len; - checkAbort->work(300 * len); - } +int32_t SegmentMerger::copyFieldsNoDeletions(const FieldsWriterPtr& fieldsWriter, const IndexReaderPtr& reader, const FieldsReaderPtr& matchingFieldsReader) { + int32_t docCount = 0; + int32_t maxDoc = reader->maxDoc(); + if (matchingFieldsReader) { + // We can bulk-copy because the fieldInfos are "congruent" + while (docCount < maxDoc) { + int32_t len = std::min(MAX_RAW_MERGE_DOCS, maxDoc - docCount); + IndexInputPtr stream(matchingFieldsReader->rawDocs(rawDocLengths, docCount, len)); + fieldsWriter->addRawDocuments(stream, rawDocLengths, len); + docCount += len; + checkAbort->work(300 * len); } - else - { - for (; docCount < maxDoc; ++docCount) - { - // NOTE: it's very important to first assign to doc then pass it to termVectorsWriter.addAllDocVectors - fieldsWriter->addDocument(reader->document(docCount)); - checkAbort->work(300); - } + } else { + for (; docCount < maxDoc; ++docCount) { + // NOTE: it's very important to first assign to doc then pass it to termVectorsWriter.addAllDocVectors + fieldsWriter->addDocument(reader->document(docCount)); + checkAbort->work(300); } - return docCount; } + return docCount; +} - void SegmentMerger::mergeVectors() - { - TermVectorsWriterPtr termVectorsWriter(newLucene(directory, segment, fieldInfos)); - - LuceneException finally; - try - { - int32_t idx = 0; - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - SegmentReaderPtr matchingSegmentReader(matchingSegmentReaders[idx++]); - TermVectorsReaderPtr matchingVectorsReader; - if (matchingSegmentReader) - { - TermVectorsReaderPtr vectorsReader(matchingSegmentReader->getTermVectorsReaderOrig()); - - // If the TV* files are an older format then they cannot read raw docs - if (vectorsReader && vectorsReader->canReadRawDocs()) - matchingVectorsReader = vectorsReader; +void SegmentMerger::mergeVectors() { + TermVectorsWriterPtr termVectorsWriter(newLucene(directory, segment, fieldInfos)); + + LuceneException finally; + try { + int32_t idx = 0; + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + SegmentReaderPtr matchingSegmentReader(matchingSegmentReaders[idx++]); + TermVectorsReaderPtr matchingVectorsReader; + if (matchingSegmentReader) { + TermVectorsReaderPtr vectorsReader(matchingSegmentReader->getTermVectorsReaderOrig()); + + // If the TV* files are an older format then they cannot read raw docs + if (vectorsReader && vectorsReader->canReadRawDocs()) { + matchingVectorsReader = vectorsReader; } - if ((*reader)->hasDeletions()) - copyVectorsWithDeletions(termVectorsWriter, matchingVectorsReader, *reader); - else - copyVectorsNoDeletions(termVectorsWriter, matchingVectorsReader, *reader); + } + if ((*reader)->hasDeletions()) { + copyVectorsWithDeletions(termVectorsWriter, matchingVectorsReader, *reader); + } else { + copyVectorsNoDeletions(termVectorsWriter, matchingVectorsReader, *reader); } } - catch (LuceneException& e) - { - finally = e; - } - termVectorsWriter->close(); - finally.throwException(); - - String fileName(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); - int64_t tvxSize = directory->fileLength(fileName); - - if (4 + ((int64_t)mergedDocs) * 16 != tvxSize) - { - boost::throw_exception(RuntimeException(L"mergeVectors produced an invalid result: mergedDocs is " + - StringUtils::toString(mergedDocs) + L" but tvx size is " + - StringUtils::toString(tvxSize) + L" file=" + fileName + - L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + - L"; now aborting this merge to prevent index corruption")); - } + } catch (LuceneException& e) { + finally = e; + } + termVectorsWriter->close(); + finally.throwException(); + + String fileName(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); + int64_t tvxSize = directory->fileLength(fileName); + + if (4 + ((int64_t)mergedDocs) * 16 != tvxSize) { + boost::throw_exception(RuntimeException(L"mergeVectors produced an invalid result: mergedDocs is " + + StringUtils::toString(mergedDocs) + L" but tvx size is " + + StringUtils::toString(tvxSize) + L" file=" + fileName + + L" file exists?=" + StringUtils::toString(directory->fileExists(fileName)) + + L"; now aborting this merge to prevent index corruption")); } +} - void SegmentMerger::copyVectorsWithDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader) - { - int32_t maxDoc = reader->maxDoc(); - if (matchingVectorsReader) - { - // We can bulk-copy because the fieldInfos are "congruent" - for (int32_t docNum = 0; docNum < maxDoc;) - { - if (reader->isDeleted(docNum)) - { - // skip deleted docs - ++docNum; - continue; +void SegmentMerger::copyVectorsWithDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader) { + int32_t maxDoc = reader->maxDoc(); + if (matchingVectorsReader) { + // We can bulk-copy because the fieldInfos are "congruent" + for (int32_t docNum = 0; docNum < maxDoc;) { + if (reader->isDeleted(docNum)) { + // skip deleted docs + ++docNum; + continue; + } + // We can optimize this case (doing a bulk byte copy) since the field numbers are identical + int32_t start = docNum; + int32_t numDocs = 0; + do { + ++docNum; + ++numDocs; + if (docNum >= maxDoc) { + break; } - // We can optimize this case (doing a bulk byte copy) since the field numbers are identical - int32_t start = docNum; - int32_t numDocs = 0; - do - { + if (reader->isDeleted(docNum)) { ++docNum; - ++numDocs; - if (docNum >= maxDoc) - break; - if (reader->isDeleted(docNum)) - { - ++docNum; - break; - } + break; } - while (numDocs < MAX_RAW_MERGE_DOCS); + } while (numDocs < MAX_RAW_MERGE_DOCS); - matchingVectorsReader->rawDocs(rawDocLengths, rawDocLengths2, start, numDocs); - termVectorsWriter->addRawDocuments(matchingVectorsReader, rawDocLengths, rawDocLengths2, numDocs); - checkAbort->work(300 * numDocs); - } + matchingVectorsReader->rawDocs(rawDocLengths, rawDocLengths2, start, numDocs); + termVectorsWriter->addRawDocuments(matchingVectorsReader, rawDocLengths, rawDocLengths2, numDocs); + checkAbort->work(300 * numDocs); } - else - { - for (int32_t docNum = 0; docNum < maxDoc; ++docNum) - { - if (reader->isDeleted(docNum)) - { - // skip deleted docs - continue; - } - - // NOTE: it's very important to first assign to vectors then pass it to termVectorsWriter.addAllDocVectors - termVectorsWriter->addAllDocVectors(reader->getTermFreqVectors(docNum)); - checkAbort->work(300); + } else { + for (int32_t docNum = 0; docNum < maxDoc; ++docNum) { + if (reader->isDeleted(docNum)) { + // skip deleted docs + continue; } + + // NOTE: it's very important to first assign to vectors then pass it to termVectorsWriter.addAllDocVectors + termVectorsWriter->addAllDocVectors(reader->getTermFreqVectors(docNum)); + checkAbort->work(300); } } +} - void SegmentMerger::copyVectorsNoDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader) - { - int32_t maxDoc = reader->maxDoc(); - if (matchingVectorsReader) - { - // We can bulk-copy because the fieldInfos are "congruent" - int32_t docCount = 0; - while (docCount < maxDoc) - { - int32_t len = std::min(MAX_RAW_MERGE_DOCS, maxDoc - docCount); - matchingVectorsReader->rawDocs(rawDocLengths, rawDocLengths2, docCount, len); - termVectorsWriter->addRawDocuments(matchingVectorsReader, rawDocLengths, rawDocLengths2, len); - docCount += len; - checkAbort->work(300 * len); - } +void SegmentMerger::copyVectorsNoDeletions(const TermVectorsWriterPtr& termVectorsWriter, const TermVectorsReaderPtr& matchingVectorsReader, const IndexReaderPtr& reader) { + int32_t maxDoc = reader->maxDoc(); + if (matchingVectorsReader) { + // We can bulk-copy because the fieldInfos are "congruent" + int32_t docCount = 0; + while (docCount < maxDoc) { + int32_t len = std::min(MAX_RAW_MERGE_DOCS, maxDoc - docCount); + matchingVectorsReader->rawDocs(rawDocLengths, rawDocLengths2, docCount, len); + termVectorsWriter->addRawDocuments(matchingVectorsReader, rawDocLengths, rawDocLengths2, len); + docCount += len; + checkAbort->work(300 * len); } - else - { - for (int32_t docNum = 0; docNum < maxDoc; ++docNum) - { - // NOTE: it's very important to first assign to vectors then pass it to termVectorsWriter.addAllDocVectors - termVectorsWriter->addAllDocVectors(reader->getTermFreqVectors(docNum)); - checkAbort->work(300); - } + } else { + for (int32_t docNum = 0; docNum < maxDoc; ++docNum) { + // NOTE: it's very important to first assign to vectors then pass it to termVectorsWriter.addAllDocVectors + termVectorsWriter->addAllDocVectors(reader->getTermFreqVectors(docNum)); + checkAbort->work(300); } } +} - void SegmentMerger::mergeTerms() - { - TestScope testScope(L"SegmentMerger", L"mergeTerms"); +void SegmentMerger::mergeTerms() { + TestScope testScope(L"SegmentMerger", L"mergeTerms"); - SegmentWriteStatePtr state(newLucene(DocumentsWriterPtr(), directory, segment, L"", mergedDocs, 0, termIndexInterval)); + SegmentWriteStatePtr state(newLucene(DocumentsWriterPtr(), directory, segment, L"", mergedDocs, 0, termIndexInterval)); - FormatPostingsFieldsConsumerPtr consumer(newLucene(state, fieldInfos)); + FormatPostingsFieldsConsumerPtr consumer(newLucene(state, fieldInfos)); - LuceneException finally; - try - { - queue = newLucene(readers.size()); - mergeTermInfos(consumer); - } - catch (LuceneException& e) - { - finally = e; - } - consumer->finish(); - if (queue) - queue->close(); - finally.throwException(); + LuceneException finally; + try { + queue = newLucene(readers.size()); + mergeTermInfos(consumer); + } catch (LuceneException& e) { + finally = e; } + consumer->finish(); + if (queue) { + queue->close(); + } + finally.throwException(); +} - void SegmentMerger::mergeTermInfos(const FormatPostingsFieldsConsumerPtr& consumer) - { - int32_t base = 0; - int32_t readerCount = readers.size(); - for (int32_t i = 0; i < readerCount; ++i) - { - IndexReaderPtr reader(readers[i]); - TermEnumPtr termEnum(reader->terms()); - SegmentMergeInfoPtr smi(newLucene(base, termEnum, reader)); - Collection docMap(smi->getDocMap()); - if (docMap) - { - if (!docMaps) - { - docMaps = Collection< Collection >::newInstance(readerCount); - delCounts = Collection::newInstance(readerCount); - } - docMaps[i] = docMap; - IndexReaderPtr segmentMergeReader(smi->_reader); - delCounts[i] = segmentMergeReader->maxDoc() - segmentMergeReader->numDocs(); +void SegmentMerger::mergeTermInfos(const FormatPostingsFieldsConsumerPtr& consumer) { + int32_t base = 0; + int32_t readerCount = readers.size(); + for (int32_t i = 0; i < readerCount; ++i) { + IndexReaderPtr reader(readers[i]); + TermEnumPtr termEnum(reader->terms()); + SegmentMergeInfoPtr smi(newLucene(base, termEnum, reader)); + Collection docMap(smi->getDocMap()); + if (docMap) { + if (!docMaps) { + docMaps = Collection< Collection >::newInstance(readerCount); + delCounts = Collection::newInstance(readerCount); } + docMaps[i] = docMap; + IndexReaderPtr segmentMergeReader(smi->_reader); + delCounts[i] = segmentMergeReader->maxDoc() - segmentMergeReader->numDocs(); + } - base += reader->numDocs(); + base += reader->numDocs(); - BOOST_ASSERT(reader->numDocs() == reader->maxDoc() - smi->delCount); + BOOST_ASSERT(reader->numDocs() == reader->maxDoc() - smi->delCount); - if (smi->next()) - queue->add(smi); // initialize queue - else - smi->close(); + if (smi->next()) { + queue->add(smi); // initialize queue + } else { + smi->close(); } + } - Collection match(Collection::newInstance(readers.size())); + Collection match(Collection::newInstance(readers.size())); - String currentField; - FormatPostingsTermsConsumerPtr termsConsumer; + String currentField; + FormatPostingsTermsConsumerPtr termsConsumer; - while (!queue->empty()) - { - int32_t matchSize = 0; // pop matching terms - match[matchSize++] = queue->pop(); - TermPtr term(match[0]->term); - SegmentMergeInfoPtr top(queue->empty() ? SegmentMergeInfoPtr() : queue->top()); + while (!queue->empty()) { + int32_t matchSize = 0; // pop matching terms + match[matchSize++] = queue->pop(); + TermPtr term(match[0]->term); + SegmentMergeInfoPtr top(queue->empty() ? SegmentMergeInfoPtr() : queue->top()); - while (top && term->compareTo(top->term) == 0) - { - match[matchSize++] = queue->pop(); - top = queue->top(); - } + while (top && term->compareTo(top->term) == 0) { + match[matchSize++] = queue->pop(); + top = queue->top(); + } - if (currentField != term->_field) - { - currentField = term->_field; - if (termsConsumer) - termsConsumer->finish(); - FieldInfoPtr fieldInfo(fieldInfos->fieldInfo(currentField)); - termsConsumer = consumer->addField(fieldInfo); - omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; + if (currentField != term->_field) { + currentField = term->_field; + if (termsConsumer) { + termsConsumer->finish(); } + FieldInfoPtr fieldInfo(fieldInfos->fieldInfo(currentField)); + termsConsumer = consumer->addField(fieldInfo); + omitTermFreqAndPositions = fieldInfo->omitTermFreqAndPositions; + } - int32_t df = appendPostings(termsConsumer, match, matchSize); // add new TermInfo + int32_t df = appendPostings(termsConsumer, match, matchSize); // add new TermInfo - checkAbort->work(df / 3.0); + checkAbort->work(df / 3.0); - while (matchSize > 0) - { - SegmentMergeInfoPtr smi(match[--matchSize]); - if (smi->next()) - queue->add(smi); // restore queue - else - smi->close(); // done with a segment + while (matchSize > 0) { + SegmentMergeInfoPtr smi(match[--matchSize]); + if (smi->next()) { + queue->add(smi); // restore queue + } else { + smi->close(); // done with a segment } } } +} - Collection< Collection > SegmentMerger::getDocMaps() - { - return docMaps; - } +Collection< Collection > SegmentMerger::getDocMaps() { + return docMaps; +} - Collection SegmentMerger::getDelCounts() - { - return delCounts; - } +Collection SegmentMerger::getDelCounts() { + return delCounts; +} - int32_t SegmentMerger::appendPostings(const FormatPostingsTermsConsumerPtr& termsConsumer, Collection smis, int32_t n) - { - FormatPostingsDocsConsumerPtr docConsumer(termsConsumer->addTerm(smis[0]->term->_text)); - int32_t df = 0; - for (int32_t i = 0; i < n; ++i) - { - SegmentMergeInfoPtr smi(smis[i]); - TermPositionsPtr postings(smi->getPositions()); - BOOST_ASSERT(postings); - int32_t base = smi->base; - Collection docMap(smi->getDocMap()); - postings->seek(smi->termEnum); - - while (postings->next()) - { - ++df; - int32_t doc = postings->doc(); - if (docMap) - doc = docMap[doc]; // map around deletions - doc += base; // convert to merged space - - int32_t freq = postings->freq(); - FormatPostingsPositionsConsumerPtr posConsumer(docConsumer->addDoc(doc, freq)); - - if (!omitTermFreqAndPositions) - { - for (int32_t j = 0; j < freq; ++j) - { - int32_t position = postings->nextPosition(); - int32_t payloadLength = postings->getPayloadLength(); - if (payloadLength > 0) - { - if (!payloadBuffer) - payloadBuffer = ByteArray::newInstance(payloadLength); - if (payloadBuffer.size() < payloadLength) - payloadBuffer.resize(payloadLength); - postings->getPayload(payloadBuffer, 0); +int32_t SegmentMerger::appendPostings(const FormatPostingsTermsConsumerPtr& termsConsumer, Collection smis, int32_t n) { + FormatPostingsDocsConsumerPtr docConsumer(termsConsumer->addTerm(smis[0]->term->_text)); + int32_t df = 0; + for (int32_t i = 0; i < n; ++i) { + SegmentMergeInfoPtr smi(smis[i]); + TermPositionsPtr postings(smi->getPositions()); + BOOST_ASSERT(postings); + int32_t base = smi->base; + Collection docMap(smi->getDocMap()); + postings->seek(smi->termEnum); + + while (postings->next()) { + ++df; + int32_t doc = postings->doc(); + if (docMap) { + doc = docMap[doc]; // map around deletions + } + doc += base; // convert to merged space + + int32_t freq = postings->freq(); + FormatPostingsPositionsConsumerPtr posConsumer(docConsumer->addDoc(doc, freq)); + + if (!omitTermFreqAndPositions) { + for (int32_t j = 0; j < freq; ++j) { + int32_t position = postings->nextPosition(); + int32_t payloadLength = postings->getPayloadLength(); + if (payloadLength > 0) { + if (!payloadBuffer) { + payloadBuffer = ByteArray::newInstance(payloadLength); + } + if (payloadBuffer.size() < payloadLength) { + payloadBuffer.resize(payloadLength); } - posConsumer->addPosition(position, payloadBuffer, 0, payloadLength); + postings->getPayload(payloadBuffer, 0); } - posConsumer->finish(); + posConsumer->addPosition(position, payloadBuffer, 0, payloadLength); } + posConsumer->finish(); } } - docConsumer->finish(); - - return df; } + docConsumer->finish(); - void SegmentMerger::mergeNorms() - { - ByteArray normBuffer; - IndexOutputPtr output; - LuceneException finally; - try - { - int32_t numFieldInfos = fieldInfos->size(); - for (int32_t i = 0; i < numFieldInfos; ++i) - { - FieldInfoPtr fi(fieldInfos->fieldInfo(i)); - if (fi->isIndexed && !fi->omitNorms) - { - if (!output) - { - output = directory->createOutput(segment + L"." + IndexFileNames::NORMS_EXTENSION()); - output->writeBytes(NORMS_HEADER, SIZEOF_ARRAY(NORMS_HEADER)); + return df; +} + +void SegmentMerger::mergeNorms() { + ByteArray normBuffer; + IndexOutputPtr output; + LuceneException finally; + try { + int32_t numFieldInfos = fieldInfos->size(); + for (int32_t i = 0; i < numFieldInfos; ++i) { + FieldInfoPtr fi(fieldInfos->fieldInfo(i)); + if (fi->isIndexed && !fi->omitNorms) { + if (!output) { + output = directory->createOutput(segment + L"." + IndexFileNames::NORMS_EXTENSION()); + output->writeBytes(NORMS_HEADER, SIZEOF_ARRAY(NORMS_HEADER)); + } + for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) { + int32_t maxDoc = (*reader)->maxDoc(); + + if (!normBuffer) { + normBuffer = ByteArray::newInstance(maxDoc); } - for (Collection::iterator reader = readers.begin(); reader != readers.end(); ++reader) - { - int32_t maxDoc = (*reader)->maxDoc(); - - if (!normBuffer) - normBuffer = ByteArray::newInstance(maxDoc); - if (normBuffer.size() < maxDoc) // the buffer is too small for the current segment - normBuffer.resize(maxDoc); - MiscUtils::arrayFill(normBuffer.get(), 0, normBuffer.size(), 0); - (*reader)->norms(fi->name, normBuffer, 0); - if (!(*reader)->hasDeletions()) - { - // optimized case for segments without deleted docs - output->writeBytes(normBuffer.get(), maxDoc); - } - else - { - // this segment has deleted docs, so we have to check for every doc if it is deleted or not - for (int32_t k = 0; k < maxDoc; ++k) - { - if (!(*reader)->isDeleted(k)) - output->writeByte(normBuffer[k]); + if (normBuffer.size() < maxDoc) { // the buffer is too small for the current segment + normBuffer.resize(maxDoc); + } + MiscUtils::arrayFill(normBuffer.get(), 0, normBuffer.size(), 0); + (*reader)->norms(fi->name, normBuffer, 0); + if (!(*reader)->hasDeletions()) { + // optimized case for segments without deleted docs + output->writeBytes(normBuffer.get(), maxDoc); + } else { + // this segment has deleted docs, so we have to check for every doc if it is deleted or not + for (int32_t k = 0; k < maxDoc; ++k) { + if (!(*reader)->isDeleted(k)) { + output->writeByte(normBuffer[k]); } } - checkAbort->work(maxDoc); } + checkAbort->work(maxDoc); } } } - catch (LuceneException& e) - { - finally = e; - } - if (output) - output->close(); - finally.throwException(); + } catch (LuceneException& e) { + finally = e; } - - CheckAbort::CheckAbort(const OneMergePtr& merge, const DirectoryPtr& dir) - { - workCount = 0; - this->merge = merge; - this->_dir = dir; + if (output) { + output->close(); } + finally.throwException(); +} - CheckAbort::~CheckAbort() - { - } +CheckAbort::CheckAbort(const OneMergePtr& merge, const DirectoryPtr& dir) { + workCount = 0; + this->merge = merge; + this->_dir = dir; +} - void CheckAbort::work(double units) - { - workCount += units; - if (workCount >= 10000.0) - { - merge->checkAborted(DirectoryPtr(_dir)); - workCount = 0; - } - } +CheckAbort::~CheckAbort() { +} - CheckAbortNull::CheckAbortNull() : CheckAbort(OneMergePtr(), DirectoryPtr()) - { +void CheckAbort::work(double units) { + workCount += units; + if (workCount >= 10000.0) { + merge->checkAborted(DirectoryPtr(_dir)); + workCount = 0; } +} - CheckAbortNull::~CheckAbortNull() - { - } +CheckAbortNull::CheckAbortNull() : CheckAbort(OneMergePtr(), DirectoryPtr()) { +} + +CheckAbortNull::~CheckAbortNull() { +} + +void CheckAbortNull::work(double units) { + // do nothing +} - void CheckAbortNull::work(double units) - { - // do nothing - } } diff --git a/src/core/index/SegmentReader.cpp b/src/core/index/SegmentReader.cpp index ed080daf..201da19e 100644 --- a/src/core/index/SegmentReader.cpp +++ b/src/core/index/SegmentReader.cpp @@ -30,1328 +30,1160 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - SegmentReader::SegmentReader() - { - _norms = MapStringNorm::newInstance(); - readOnly = false; - deletedDocsDirty = false; - normsDirty = false; - rollbackHasChanges = false; - rollbackDeletedDocsDirty = false; - rollbackNormsDirty = false; - - readBufferSize = 0; - pendingDeleteCount = 0; - rollbackPendingDeleteCount = 0; - } - - SegmentReader::~SegmentReader() - { - } +namespace Lucene { + +SegmentReader::SegmentReader() { + _norms = MapStringNorm::newInstance(); + readOnly = false; + deletedDocsDirty = false; + normsDirty = false; + rollbackHasChanges = false; + rollbackDeletedDocsDirty = false; + rollbackNormsDirty = false; + + readBufferSize = 0; + pendingDeleteCount = 0; + rollbackPendingDeleteCount = 0; +} - void SegmentReader::initialize() - { - fieldsReaderLocal = newLucene(shared_from_this()); - } +SegmentReader::~SegmentReader() { +} - SegmentReaderPtr SegmentReader::get(bool readOnly, const SegmentInfoPtr& si, int32_t termInfosIndexDivisor) - { - return get(readOnly, si->dir, si, BufferedIndexInput::BUFFER_SIZE, true, termInfosIndexDivisor); - } +void SegmentReader::initialize() { + fieldsReaderLocal = newLucene(shared_from_this()); +} - SegmentReaderPtr SegmentReader::get(bool readOnly, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor) - { - SegmentReaderPtr instance(readOnly ? newLucene() : newLucene()); - instance->readOnly = readOnly; - instance->si = si; - instance->readBufferSize = readBufferSize; +SegmentReaderPtr SegmentReader::get(bool readOnly, const SegmentInfoPtr& si, int32_t termInfosIndexDivisor) { + return get(readOnly, si->dir, si, BufferedIndexInput::BUFFER_SIZE, true, termInfosIndexDivisor); +} - bool success = false; - LuceneException finally; - try - { - instance->core = newLucene(instance, dir, si, readBufferSize, termInfosIndexDivisor); - if (doOpenStores) - instance->core->openDocStores(si); - instance->loadDeletedDocs(); - instance->openNorms(instance->core->cfsDir, readBufferSize); - success = true; - } - catch (LuceneException& e) - { - finally = e; +SegmentReaderPtr SegmentReader::get(bool readOnly, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, bool doOpenStores, int32_t termInfosIndexDivisor) { + SegmentReaderPtr instance(readOnly ? newLucene() : newLucene()); + instance->readOnly = readOnly; + instance->si = si; + instance->readBufferSize = readBufferSize; + + bool success = false; + LuceneException finally; + try { + instance->core = newLucene(instance, dir, si, readBufferSize, termInfosIndexDivisor); + if (doOpenStores) { + instance->core->openDocStores(si); } - - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. - // In this case, we want to explicitly close any subset of things that were opened - if (!success) - instance->doClose(); - finally.throwException(); - return instance; + instance->loadDeletedDocs(); + instance->openNorms(instance->core->cfsDir, readBufferSize); + success = true; + } catch (LuceneException& e) { + finally = e; } - void SegmentReader::openDocStores() - { - core->openDocStores(si); + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. + // In this case, we want to explicitly close any subset of things that were opened + if (!success) { + instance->doClose(); } + finally.throwException(); + return instance; +} - bool SegmentReader::checkDeletedCounts() - { - int32_t recomputedCount = deletedDocs->getRecomputedCount(); +void SegmentReader::openDocStores() { + core->openDocStores(si); +} - BOOST_ASSERT(deletedDocs->count() == recomputedCount); +bool SegmentReader::checkDeletedCounts() { + int32_t recomputedCount = deletedDocs->getRecomputedCount(); - BOOST_ASSERT(si->getDelCount() == recomputedCount); + BOOST_ASSERT(deletedDocs->count() == recomputedCount); - // Verify # deletes does not exceed maxDoc for this segment - BOOST_ASSERT(si->getDelCount() <= maxDoc()); + BOOST_ASSERT(si->getDelCount() == recomputedCount); - return true; - } + // Verify # deletes does not exceed maxDoc for this segment + BOOST_ASSERT(si->getDelCount() <= maxDoc()); - void SegmentReader::loadDeletedDocs() - { - // NOTE: the bitvector is stored using the regular directory, not cfs - if (hasDeletions(si)) - { - deletedDocs = newLucene(directory(), si->getDelFileName()); - deletedDocsRef = newLucene(); - BOOST_ASSERT(checkDeletedCounts()); - } - else - BOOST_ASSERT(si->getDelCount() == 0); - } + return true; +} - ByteArray SegmentReader::cloneNormBytes(ByteArray bytes) - { - ByteArray cloneBytes(ByteArray::newInstance(bytes.size())); - MiscUtils::arrayCopy(bytes.get(), 0, cloneBytes.get(), 0, bytes.size()); - return cloneBytes; +void SegmentReader::loadDeletedDocs() { + // NOTE: the bitvector is stored using the regular directory, not cfs + if (hasDeletions(si)) { + deletedDocs = newLucene(directory(), si->getDelFileName()); + deletedDocsRef = newLucene(); + BOOST_ASSERT(checkDeletedCounts()); + } else { + BOOST_ASSERT(si->getDelCount() == 0); } +} - BitVectorPtr SegmentReader::cloneDeletedDocs(const BitVectorPtr& bv) - { - return boost::dynamic_pointer_cast(bv->clone()); - } +ByteArray SegmentReader::cloneNormBytes(ByteArray bytes) { + ByteArray cloneBytes(ByteArray::newInstance(bytes.size())); + MiscUtils::arrayCopy(bytes.get(), 0, cloneBytes.get(), 0, bytes.size()); + return cloneBytes; +} - LuceneObjectPtr SegmentReader::clone(const LuceneObjectPtr& other) - { - try - { - return SegmentReader::clone(readOnly, other); // Preserve current readOnly - } - catch (...) - { - boost::throw_exception(RuntimeException()); - } - return LuceneObjectPtr(); - } +BitVectorPtr SegmentReader::cloneDeletedDocs(const BitVectorPtr& bv) { + return boost::dynamic_pointer_cast(bv->clone()); +} - LuceneObjectPtr SegmentReader::clone(bool openReadOnly, const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - return reopenSegment(si, true, openReadOnly); +LuceneObjectPtr SegmentReader::clone(const LuceneObjectPtr& other) { + try { + return SegmentReader::clone(readOnly, other); // Preserve current readOnly + } catch (...) { + boost::throw_exception(RuntimeException()); } + return LuceneObjectPtr(); +} - SegmentReaderPtr SegmentReader::reopenSegment(const SegmentInfoPtr& si, bool doClone, bool openReadOnly) - { - SyncLock syncLock(this); +LuceneObjectPtr SegmentReader::clone(bool openReadOnly, const LuceneObjectPtr& other) { + SyncLock syncLock(this); + return reopenSegment(si, true, openReadOnly); +} - bool deletionsUpToDate = (this->si->hasDeletions() == si->hasDeletions() && - (!si->hasDeletions() || this->si->getDelFileName() == si->getDelFileName())); - bool normsUpToDate = true; - int32_t fieldCount = core->fieldInfos->size(); - Collection fieldNormsChanged(Collection::newInstance(fieldCount)); +SegmentReaderPtr SegmentReader::reopenSegment(const SegmentInfoPtr& si, bool doClone, bool openReadOnly) { + SyncLock syncLock(this); - for (int32_t i = 0; i < fieldCount; ++i) - { - if (this->si->getNormFileName(i) != si->getNormFileName(i)) - { - normsUpToDate = false; - fieldNormsChanged[i] = true; - } + bool deletionsUpToDate = (this->si->hasDeletions() == si->hasDeletions() && + (!si->hasDeletions() || this->si->getDelFileName() == si->getDelFileName())); + bool normsUpToDate = true; + int32_t fieldCount = core->fieldInfos->size(); + Collection fieldNormsChanged(Collection::newInstance(fieldCount)); + + for (int32_t i = 0; i < fieldCount; ++i) { + if (this->si->getNormFileName(i) != si->getNormFileName(i)) { + normsUpToDate = false; + fieldNormsChanged[i] = true; } + } - // if we're cloning we need to run through the reopenSegment logic also if both old and new readers - // aren't readonly, we clone to avoid sharing modifications - if (normsUpToDate && deletionsUpToDate && !doClone && openReadOnly && readOnly) - return shared_from_this(); + // if we're cloning we need to run through the reopenSegment logic also if both old and new readers + // aren't readonly, we clone to avoid sharing modifications + if (normsUpToDate && deletionsUpToDate && !doClone && openReadOnly && readOnly) { + return shared_from_this(); + } - // When cloning, the incoming SegmentInfos should not have any changes in it - BOOST_ASSERT(!doClone || (normsUpToDate && deletionsUpToDate)); + // When cloning, the incoming SegmentInfos should not have any changes in it + BOOST_ASSERT(!doClone || (normsUpToDate && deletionsUpToDate)); - // clone reader - SegmentReaderPtr clone(openReadOnly ? newLucene() : newLucene()); + // clone reader + SegmentReaderPtr clone(openReadOnly ? newLucene() : newLucene()); - bool success = false; - LuceneException finally; - try - { - core->incRef(); - clone->core = core; - clone->readOnly = openReadOnly; - clone->si = si; - clone->readBufferSize = readBufferSize; - - if (!openReadOnly && _hasChanges) - { - // My pending changes transfer to the new reader - clone->pendingDeleteCount = pendingDeleteCount; - clone->deletedDocsDirty = deletedDocsDirty; - clone->normsDirty = normsDirty; - clone->_hasChanges = _hasChanges; - _hasChanges = false; - } + bool success = false; + LuceneException finally; + try { + core->incRef(); + clone->core = core; + clone->readOnly = openReadOnly; + clone->si = si; + clone->readBufferSize = readBufferSize; - if (doClone) - { - if (deletedDocs) - { - deletedDocsRef->incRef(); - clone->deletedDocs = deletedDocs; - clone->deletedDocsRef = deletedDocsRef; - } + if (!openReadOnly && _hasChanges) { + // My pending changes transfer to the new reader + clone->pendingDeleteCount = pendingDeleteCount; + clone->deletedDocsDirty = deletedDocsDirty; + clone->normsDirty = normsDirty; + clone->_hasChanges = _hasChanges; + _hasChanges = false; + } + + if (doClone) { + if (deletedDocs) { + deletedDocsRef->incRef(); + clone->deletedDocs = deletedDocs; + clone->deletedDocsRef = deletedDocsRef; } - else - { - if (!deletionsUpToDate) - { - // load deleted docs - BOOST_ASSERT(!clone->deletedDocs); - clone->loadDeletedDocs(); - } - else if (deletedDocs) - { - deletedDocsRef->incRef(); - clone->deletedDocs = deletedDocs; - clone->deletedDocsRef = deletedDocsRef; - } + } else { + if (!deletionsUpToDate) { + // load deleted docs + BOOST_ASSERT(!clone->deletedDocs); + clone->loadDeletedDocs(); + } else if (deletedDocs) { + deletedDocsRef->incRef(); + clone->deletedDocs = deletedDocs; + clone->deletedDocsRef = deletedDocsRef; } + } - clone->_norms = MapStringNorm::newInstance(); - - // Clone norms - for (int32_t i = 0; i < fieldNormsChanged.size(); ++i) - { - // Clone unchanged norms to the cloned reader - if (doClone || !fieldNormsChanged[i]) - { - String curField(core->fieldInfos->fieldInfo(i)->name); - NormPtr norm(this->_norms.get(curField)); - if (norm) - { - NormPtr cloneNorm(boost::dynamic_pointer_cast(norm->clone())); - cloneNorm->_reader = clone; - clone->_norms.put(curField, cloneNorm); - } + clone->_norms = MapStringNorm::newInstance(); + + // Clone norms + for (int32_t i = 0; i < fieldNormsChanged.size(); ++i) { + // Clone unchanged norms to the cloned reader + if (doClone || !fieldNormsChanged[i]) { + String curField(core->fieldInfos->fieldInfo(i)->name); + NormPtr norm(this->_norms.get(curField)); + if (norm) { + NormPtr cloneNorm(boost::dynamic_pointer_cast(norm->clone())); + cloneNorm->_reader = clone; + clone->_norms.put(curField, cloneNorm); } } + } + + // If we are not cloning, then this will open anew any norms that have changed + clone->openNorms(si->getUseCompoundFile() ? core->getCFSReader() : directory(), readBufferSize); - // If we are not cloning, then this will open anew any norms that have changed - clone->openNorms(si->getUseCompoundFile() ? core->getCFSReader() : directory(), readBufferSize); + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + // An exception occurred during reopen, we have to decRef the norms that we incRef'ed already + // and close singleNormsStream and FieldsReader + clone->decRef(); + } + finally.throwException(); + return clone; +} +void SegmentReader::doCommit(MapStringString commitUserData) { + if (_hasChanges) { + startCommit(); + bool success = false; + LuceneException finally; + try { + commitChanges(commitUserData); success = true; - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } - if (!success) - { - // An exception occurred during reopen, we have to decRef the norms that we incRef'ed already - // and close singleNormsStream and FieldsReader - clone->decRef(); + if (!success) { + rollbackCommit(); } finally.throwException(); - return clone; - } - - void SegmentReader::doCommit(MapStringString commitUserData) - { - if (_hasChanges) - { - startCommit(); - bool success = false; - LuceneException finally; - try - { - commitChanges(commitUserData); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - rollbackCommit(); - finally.throwException(); - } } +} - void SegmentReader::commitChanges(MapStringString commitUserData) - { - if (deletedDocsDirty) // re-write deleted - { - si->advanceDelGen(); +void SegmentReader::commitChanges(MapStringString commitUserData) { + if (deletedDocsDirty) { // re-write deleted + si->advanceDelGen(); - // We can write directly to the actual name (vs to a .tmp & renaming it) because the file - // is not live until segments file is written - String delFileName(si->getDelFileName()); + // We can write directly to the actual name (vs to a .tmp & renaming it) because the file + // is not live until segments file is written + String delFileName(si->getDelFileName()); - bool success = false; - LuceneException finally; - try - { - deletedDocs->write(directory(), delFileName); - success = true; - } - catch (LuceneException& e) - { - finally = e; - } - if (!success) - { - try - { - directory()->deleteFile(delFileName); - } - catch (...) - { - // suppress this so we keep throwing the original exception - } - } - finally.throwException(); - - si->setDelCount(si->getDelCount() + pendingDeleteCount); - pendingDeleteCount = 0; - BOOST_ASSERT(deletedDocs->count() == si->getDelCount()); // delete count mismatch during commit? - } - else - { - BOOST_ASSERT(pendingDeleteCount == 0); + bool success = false; + LuceneException finally; + try { + deletedDocs->write(directory(), delFileName); + success = true; + } catch (LuceneException& e) { + finally = e; } - - if (normsDirty) // re-write norms - { - si->setNumFields(core->fieldInfos->size()); - for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) - { - if (norm->second->dirty) - norm->second->reWrite(si); + if (!success) { + try { + directory()->deleteFile(delFileName); + } catch (...) { + // suppress this so we keep throwing the original exception } } - deletedDocsDirty = false; - normsDirty = false; - _hasChanges = false; - } + finally.throwException(); - FieldsReaderPtr SegmentReader::getFieldsReader() - { - return fieldsReaderLocal->get(); + si->setDelCount(si->getDelCount() + pendingDeleteCount); + pendingDeleteCount = 0; + BOOST_ASSERT(deletedDocs->count() == si->getDelCount()); // delete count mismatch during commit? + } else { + BOOST_ASSERT(pendingDeleteCount == 0); } - void SegmentReader::doClose() - { - termVectorsLocal.close(); - fieldsReaderLocal->close(); - if (deletedDocs) - { - deletedDocsRef->decRef(); - deletedDocs.reset(); // null so if an app hangs on to us we still free most ram + if (normsDirty) { // re-write norms + si->setNumFields(core->fieldInfos->size()); + for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) { + if (norm->second->dirty) { + norm->second->reWrite(si); + } } - for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) - norm->second->decRef(); - if (core) - core->decRef(); } + deletedDocsDirty = false; + normsDirty = false; + _hasChanges = false; +} - bool SegmentReader::hasDeletions(const SegmentInfoPtr& si) - { - // Don't call ensureOpen() here (it could affect performance) - return si->hasDeletions(); - } +FieldsReaderPtr SegmentReader::getFieldsReader() { + return fieldsReaderLocal->get(); +} - bool SegmentReader::hasDeletions() - { - // Don't call ensureOpen() here (it could affect performance) - return deletedDocs.get() != NULL; +void SegmentReader::doClose() { + termVectorsLocal.close(); + fieldsReaderLocal->close(); + if (deletedDocs) { + deletedDocsRef->decRef(); + deletedDocs.reset(); // null so if an app hangs on to us we still free most ram } - - bool SegmentReader::usesCompoundFile(const SegmentInfoPtr& si) - { - return si->getUseCompoundFile(); + for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) { + norm->second->decRef(); } - - bool SegmentReader::hasSeparateNorms(const SegmentInfoPtr& si) - { - return si->hasSeparateNorms(); + if (core) { + core->decRef(); } +} - void SegmentReader::doDelete(int32_t docNum) - { - if (!deletedDocs) - { - deletedDocs = newLucene(maxDoc()); - deletedDocsRef = newLucene(); - } - // there is more than 1 SegmentReader with a reference to this deletedDocs BitVector so decRef - // the current deletedDocsRef, clone the BitVector, create a new deletedDocsRef - if (deletedDocsRef->refCount() > 1) - { - SegmentReaderRefPtr oldRef(deletedDocsRef); - deletedDocs = cloneDeletedDocs(deletedDocs); - deletedDocsRef = newLucene(); - oldRef->decRef(); - } - deletedDocsDirty = true; - if (!deletedDocs->getAndSet(docNum)) - ++pendingDeleteCount; - } +bool SegmentReader::hasDeletions(const SegmentInfoPtr& si) { + // Don't call ensureOpen() here (it could affect performance) + return si->hasDeletions(); +} - void SegmentReader::doUndeleteAll() - { - deletedDocsDirty = false; - if (deletedDocs) - { - BOOST_ASSERT(deletedDocsRef); - deletedDocsRef->decRef(); - deletedDocs.reset(); - deletedDocsRef.reset(); - pendingDeleteCount = 0; - si->clearDelGen(); - si->setDelCount(0); - } - else - { - BOOST_ASSERT(!deletedDocsRef); - BOOST_ASSERT(pendingDeleteCount == 0); - } - } +bool SegmentReader::hasDeletions() { + // Don't call ensureOpen() here (it could affect performance) + return deletedDocs.get() != NULL; +} - HashSet SegmentReader::files() - { - return si->files(); - } +bool SegmentReader::usesCompoundFile(const SegmentInfoPtr& si) { + return si->getUseCompoundFile(); +} - TermEnumPtr SegmentReader::terms() - { - ensureOpen(); - return core->getTermsReader()->terms(); - } +bool SegmentReader::hasSeparateNorms(const SegmentInfoPtr& si) { + return si->hasSeparateNorms(); +} - TermEnumPtr SegmentReader::terms(const TermPtr& t) - { - ensureOpen(); - return core->getTermsReader()->terms(t); +void SegmentReader::doDelete(int32_t docNum) { + if (!deletedDocs) { + deletedDocs = newLucene(maxDoc()); + deletedDocsRef = newLucene(); } - - FieldInfosPtr SegmentReader::fieldInfos() - { - return core->fieldInfos; + // there is more than 1 SegmentReader with a reference to this deletedDocs BitVector so decRef + // the current deletedDocsRef, clone the BitVector, create a new deletedDocsRef + if (deletedDocsRef->refCount() > 1) { + SegmentReaderRefPtr oldRef(deletedDocsRef); + deletedDocs = cloneDeletedDocs(deletedDocs); + deletedDocsRef = newLucene(); + oldRef->decRef(); } - - DocumentPtr SegmentReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) - { - ensureOpen(); - return getFieldsReader()->doc(n, fieldSelector); + deletedDocsDirty = true; + if (!deletedDocs->getAndSet(docNum)) { + ++pendingDeleteCount; } +} - bool SegmentReader::isDeleted(int32_t n) - { - SyncLock syncLock(this); - return (deletedDocs && deletedDocs->get(n)); +void SegmentReader::doUndeleteAll() { + deletedDocsDirty = false; + if (deletedDocs) { + BOOST_ASSERT(deletedDocsRef); + deletedDocsRef->decRef(); + deletedDocs.reset(); + deletedDocsRef.reset(); + pendingDeleteCount = 0; + si->clearDelGen(); + si->setDelCount(0); + } else { + BOOST_ASSERT(!deletedDocsRef); + BOOST_ASSERT(pendingDeleteCount == 0); } +} - TermDocsPtr SegmentReader::termDocs(const TermPtr& term) - { - if (!term) - return newLucene(shared_from_this()); - else - return IndexReader::termDocs(term); - } +HashSet SegmentReader::files() { + return si->files(); +} - TermDocsPtr SegmentReader::termDocs() - { - ensureOpen(); - return newLucene(shared_from_this()); - } +TermEnumPtr SegmentReader::terms() { + ensureOpen(); + return core->getTermsReader()->terms(); +} - TermPositionsPtr SegmentReader::termPositions() - { - ensureOpen(); - return newLucene(shared_from_this()); - } +TermEnumPtr SegmentReader::terms(const TermPtr& t) { + ensureOpen(); + return core->getTermsReader()->terms(t); +} - int32_t SegmentReader::docFreq(const TermPtr& t) - { - ensureOpen(); - TermInfoPtr ti(core->getTermsReader()->get(t)); - return ti ? ti->docFreq : 0; - } +FieldInfosPtr SegmentReader::fieldInfos() { + return core->fieldInfos; +} - int32_t SegmentReader::numDocs() - { - // Don't call ensureOpen() here (it could affect performance) - int32_t n = maxDoc(); - if (deletedDocs) - n -= deletedDocs->count(); - return n; +DocumentPtr SegmentReader::document(int32_t n, const FieldSelectorPtr& fieldSelector) { + ensureOpen(); + return getFieldsReader()->doc(n, fieldSelector); +} + +bool SegmentReader::isDeleted(int32_t n) { + SyncLock syncLock(this); + return (deletedDocs && deletedDocs->get(n)); +} + +TermDocsPtr SegmentReader::termDocs(const TermPtr& term) { + if (!term) { + return newLucene(shared_from_this()); + } else { + return IndexReader::termDocs(term); } +} + +TermDocsPtr SegmentReader::termDocs() { + ensureOpen(); + return newLucene(shared_from_this()); +} + +TermPositionsPtr SegmentReader::termPositions() { + ensureOpen(); + return newLucene(shared_from_this()); +} + +int32_t SegmentReader::docFreq(const TermPtr& t) { + ensureOpen(); + TermInfoPtr ti(core->getTermsReader()->get(t)); + return ti ? ti->docFreq : 0; +} - int32_t SegmentReader::maxDoc() - { - // Don't call ensureOpen() here (it could affect performance) - return si->docCount; +int32_t SegmentReader::numDocs() { + // Don't call ensureOpen() here (it could affect performance) + int32_t n = maxDoc(); + if (deletedDocs) { + n -= deletedDocs->count(); } + return n; +} + +int32_t SegmentReader::maxDoc() { + // Don't call ensureOpen() here (it could affect performance) + return si->docCount; +} - HashSet SegmentReader::getFieldNames(FieldOption fieldOption) - { - ensureOpen(); - HashSet fieldSet(HashSet::newInstance()); - for (int32_t i = 0; i < core->fieldInfos->size(); ++i) - { - FieldInfoPtr fi(core->fieldInfos->fieldInfo(i)); - if (fieldOption == FIELD_OPTION_ALL) - fieldSet.add(fi->name); - else if (!fi->isIndexed && fieldOption == FIELD_OPTION_UNINDEXED) - fieldSet.add(fi->name); - else if (fi->omitTermFreqAndPositions && fieldOption == FIELD_OPTION_OMIT_TERM_FREQ_AND_POSITIONS) - fieldSet.add(fi->name); - else if (fi->storePayloads && fieldOption == FIELD_OPTION_STORES_PAYLOADS) - fieldSet.add(fi->name); - else if (fi->isIndexed && fieldOption == FIELD_OPTION_INDEXED) - fieldSet.add(fi->name); - else if (fi->isIndexed && !fi->storeTermVector && fieldOption == FIELD_OPTION_INDEXED_NO_TERMVECTOR) - fieldSet.add(fi->name); - else if (fi->storeTermVector && !fi->storePositionWithTermVector && !fi->storeOffsetWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR) - fieldSet.add(fi->name); - else if (fi->isIndexed && fi->storeTermVector && fieldOption == FIELD_OPTION_INDEXED_WITH_TERMVECTOR) - fieldSet.add(fi->name); - else if (fi->storePositionWithTermVector && !fi->storeOffsetWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR_WITH_POSITION) - fieldSet.add(fi->name); - else if (fi->storeOffsetWithTermVector && !fi->storePositionWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR_WITH_OFFSET) - fieldSet.add(fi->name); - else if (fi->storeOffsetWithTermVector && fi->storePositionWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET) - fieldSet.add(fi->name); +HashSet SegmentReader::getFieldNames(FieldOption fieldOption) { + ensureOpen(); + HashSet fieldSet(HashSet::newInstance()); + for (int32_t i = 0; i < core->fieldInfos->size(); ++i) { + FieldInfoPtr fi(core->fieldInfos->fieldInfo(i)); + if (fieldOption == FIELD_OPTION_ALL) { + fieldSet.add(fi->name); + } else if (!fi->isIndexed && fieldOption == FIELD_OPTION_UNINDEXED) { + fieldSet.add(fi->name); + } else if (fi->omitTermFreqAndPositions && fieldOption == FIELD_OPTION_OMIT_TERM_FREQ_AND_POSITIONS) { + fieldSet.add(fi->name); + } else if (fi->storePayloads && fieldOption == FIELD_OPTION_STORES_PAYLOADS) { + fieldSet.add(fi->name); + } else if (fi->isIndexed && fieldOption == FIELD_OPTION_INDEXED) { + fieldSet.add(fi->name); + } else if (fi->isIndexed && !fi->storeTermVector && fieldOption == FIELD_OPTION_INDEXED_NO_TERMVECTOR) { + fieldSet.add(fi->name); + } else if (fi->storeTermVector && !fi->storePositionWithTermVector && !fi->storeOffsetWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR) { + fieldSet.add(fi->name); + } else if (fi->isIndexed && fi->storeTermVector && fieldOption == FIELD_OPTION_INDEXED_WITH_TERMVECTOR) { + fieldSet.add(fi->name); + } else if (fi->storePositionWithTermVector && !fi->storeOffsetWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR_WITH_POSITION) { + fieldSet.add(fi->name); + } else if (fi->storeOffsetWithTermVector && !fi->storePositionWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR_WITH_OFFSET) { + fieldSet.add(fi->name); + } else if (fi->storeOffsetWithTermVector && fi->storePositionWithTermVector && fieldOption == FIELD_OPTION_TERMVECTOR_WITH_POSITION_OFFSET) { + fieldSet.add(fi->name); } - return fieldSet; } + return fieldSet; +} - bool SegmentReader::hasNorms(const String& field) - { - SyncLock syncLock(this); - ensureOpen(); - return _norms.contains(field); - } +bool SegmentReader::hasNorms(const String& field) { + SyncLock syncLock(this); + ensureOpen(); + return _norms.contains(field); +} - ByteArray SegmentReader::getNorms(const String& field) - { - SyncLock syncLock(this); - NormPtr norm(_norms.get(field)); - return norm ? norm->bytes() : ByteArray(); - } +ByteArray SegmentReader::getNorms(const String& field) { + SyncLock syncLock(this); + NormPtr norm(_norms.get(field)); + return norm ? norm->bytes() : ByteArray(); +} - ByteArray SegmentReader::norms(const String& field) - { - SyncLock syncLock(this); - ensureOpen(); - return getNorms(field); - } +ByteArray SegmentReader::norms(const String& field) { + SyncLock syncLock(this); + ensureOpen(); + return getNorms(field); +} - void SegmentReader::doSetNorm(int32_t doc, const String& field, uint8_t value) - { - NormPtr norm(_norms.get(field)); - if (!norm) // not an indexed field - return; - - normsDirty = true; - ByteArray bytes(norm->copyOnWrite()); - if (doc < 0 || doc >= bytes.size()) - boost::throw_exception(IndexOutOfBoundsException()); - bytes[doc] = value; // set the value +void SegmentReader::doSetNorm(int32_t doc, const String& field, uint8_t value) { + NormPtr norm(_norms.get(field)); + if (!norm) { // not an indexed field + return; } - void SegmentReader::norms(const String& field, ByteArray norms, int32_t offset) - { - SyncLock syncLock(this); - ensureOpen(); - NormPtr norm(_norms.get(field)); - if (!norm) - { - MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); - return; - } + normsDirty = true; + ByteArray bytes(norm->copyOnWrite()); + if (doc < 0 || doc >= bytes.size()) { + boost::throw_exception(IndexOutOfBoundsException()); + } + bytes[doc] = value; // set the value +} - norm->bytes(norms.get(), offset, maxDoc()); +void SegmentReader::norms(const String& field, ByteArray norms, int32_t offset) { + SyncLock syncLock(this); + ensureOpen(); + NormPtr norm(_norms.get(field)); + if (!norm) { + MiscUtils::arrayFill(norms.get(), offset, norms.size(), DefaultSimilarity::encodeNorm(1.0)); + return; } - void SegmentReader::openNorms(const DirectoryPtr& cfsDir, int32_t readBufferSize) - { - int64_t nextNormSeek = SegmentMerger::NORMS_HEADER_LENGTH; // skip header (header unused for now) - int32_t _maxDoc = maxDoc(); - for (int32_t i = 0; i < core->fieldInfos->size(); ++i) - { - FieldInfoPtr fi(core->fieldInfos->fieldInfo(i)); - if (_norms.contains(fi->name)) - { - // in case this SegmentReader is being re-opened, we might be able to reuse some norm - // instances and skip loading them here - continue; + norm->bytes(norms.get(), offset, maxDoc()); +} + +void SegmentReader::openNorms(const DirectoryPtr& cfsDir, int32_t readBufferSize) { + int64_t nextNormSeek = SegmentMerger::NORMS_HEADER_LENGTH; // skip header (header unused for now) + int32_t _maxDoc = maxDoc(); + for (int32_t i = 0; i < core->fieldInfos->size(); ++i) { + FieldInfoPtr fi(core->fieldInfos->fieldInfo(i)); + if (_norms.contains(fi->name)) { + // in case this SegmentReader is being re-opened, we might be able to reuse some norm + // instances and skip loading them here + continue; + } + if (fi->isIndexed && !fi->omitNorms) { + DirectoryPtr d(directory()); + String fileName(si->getNormFileName(fi->number)); + if (!si->hasSeparateNorms(fi->number)) { + d = cfsDir; } - if (fi->isIndexed && !fi->omitNorms) - { - DirectoryPtr d(directory()); - String fileName(si->getNormFileName(fi->number)); - if (!si->hasSeparateNorms(fi->number)) - d = cfsDir; - - // singleNormFile means multiple norms share this file - bool singleNormFile = boost::ends_with(fileName, String(L".") + IndexFileNames::NORMS_EXTENSION()); - IndexInputPtr normInput; - int64_t normSeek; - - if (singleNormFile) - { - normSeek = nextNormSeek; - if (!singleNormStream) - { - singleNormStream = d->openInput(fileName, readBufferSize); - singleNormRef = newLucene(); - } - else - singleNormRef->incRef(); - - // All norms in the .nrm file can share a single IndexInput since they are only used in - // a synchronized context. If this were to change in the future, a clone could be done here. - normInput = singleNormStream; - } - else - { - normSeek = 0; - normInput = d->openInput(fileName); + + // singleNormFile means multiple norms share this file + bool singleNormFile = boost::ends_with(fileName, String(L".") + IndexFileNames::NORMS_EXTENSION()); + IndexInputPtr normInput; + int64_t normSeek; + + if (singleNormFile) { + normSeek = nextNormSeek; + if (!singleNormStream) { + singleNormStream = d->openInput(fileName, readBufferSize); + singleNormRef = newLucene(); + } else { + singleNormRef->incRef(); } - _norms.put(fi->name, newLucene(shared_from_this(), normInput, fi->number, normSeek)); - nextNormSeek += _maxDoc; // increment also if some norms are separate + // All norms in the .nrm file can share a single IndexInput since they are only used in + // a synchronized context. If this were to change in the future, a clone could be done here. + normInput = singleNormStream; + } else { + normSeek = 0; + normInput = d->openInput(fileName); } + + _norms.put(fi->name, newLucene(shared_from_this(), normInput, fi->number, normSeek)); + nextNormSeek += _maxDoc; // increment also if some norms are separate } } +} - bool SegmentReader::termsIndexLoaded() - { - return core->termsIndexIsLoaded(); - } +bool SegmentReader::termsIndexLoaded() { + return core->termsIndexIsLoaded(); +} - void SegmentReader::loadTermsIndex(int32_t termsIndexDivisor) - { - core->loadTermsIndex(si, termsIndexDivisor); - } +void SegmentReader::loadTermsIndex(int32_t termsIndexDivisor) { + core->loadTermsIndex(si, termsIndexDivisor); +} - bool SegmentReader::normsClosed() - { - if (singleNormStream) +bool SegmentReader::normsClosed() { + if (singleNormStream) { + return false; + } + for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) { + if (norm->second->refCount > 0) { return false; - for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) - { - if (norm->second->refCount > 0) - return false; } - return true; } + return true; +} - bool SegmentReader::normsClosed(const String& field) - { - return (_norms.get(field)->refCount == 0); - } +bool SegmentReader::normsClosed(const String& field) { + return (_norms.get(field)->refCount == 0); +} - TermVectorsReaderPtr SegmentReader::getTermVectorsReader() - { - TermVectorsReaderPtr tvReader(termVectorsLocal.get()); - if (!tvReader) - { - TermVectorsReaderPtr orig(core->getTermVectorsReaderOrig()); - if (!orig) +TermVectorsReaderPtr SegmentReader::getTermVectorsReader() { + TermVectorsReaderPtr tvReader(termVectorsLocal.get()); + if (!tvReader) { + TermVectorsReaderPtr orig(core->getTermVectorsReaderOrig()); + if (!orig) { + return TermVectorsReaderPtr(); + } else { + try { + tvReader = boost::dynamic_pointer_cast(orig->clone()); + } catch (...) { return TermVectorsReaderPtr(); - else - { - try - { - tvReader = boost::dynamic_pointer_cast(orig->clone()); - } - catch (...) - { - return TermVectorsReaderPtr(); - } } - termVectorsLocal.set(tvReader); } - return tvReader; - } - - TermVectorsReaderPtr SegmentReader::getTermVectorsReaderOrig() - { - return core->getTermVectorsReaderOrig(); + termVectorsLocal.set(tvReader); } + return tvReader; +} - TermFreqVectorPtr SegmentReader::getTermFreqVector(int32_t docNumber, const String& field) - { - // Check if this field is invalid or has no stored term vector - ensureOpen(); - FieldInfoPtr fi(core->fieldInfos->fieldInfo(field)); - if (!fi || !fi->storeTermVector) - return TermFreqVectorPtr(); +TermVectorsReaderPtr SegmentReader::getTermVectorsReaderOrig() { + return core->getTermVectorsReaderOrig(); +} - TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); - if (!termVectorsReader) - return TermFreqVectorPtr(); +TermFreqVectorPtr SegmentReader::getTermFreqVector(int32_t docNumber, const String& field) { + // Check if this field is invalid or has no stored term vector + ensureOpen(); + FieldInfoPtr fi(core->fieldInfos->fieldInfo(field)); + if (!fi || !fi->storeTermVector) { + return TermFreqVectorPtr(); + } - return termVectorsReader->get(docNumber, field); + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); + if (!termVectorsReader) { + return TermFreqVectorPtr(); } - void SegmentReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) - { - ensureOpen(); - FieldInfoPtr fi(core->fieldInfos->fieldInfo(field)); - if (!fi || !fi->storeTermVector) - return; + return termVectorsReader->get(docNumber, field); +} - TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); - if (!termVectorsReader) - return; +void SegmentReader::getTermFreqVector(int32_t docNumber, const String& field, const TermVectorMapperPtr& mapper) { + ensureOpen(); + FieldInfoPtr fi(core->fieldInfos->fieldInfo(field)); + if (!fi || !fi->storeTermVector) { + return; + } - termVectorsReader->get(docNumber, field, mapper); + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); + if (!termVectorsReader) { + return; } - void SegmentReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) - { - ensureOpen(); + termVectorsReader->get(docNumber, field, mapper); +} - TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); - if (!termVectorsReader) - return; +void SegmentReader::getTermFreqVector(int32_t docNumber, const TermVectorMapperPtr& mapper) { + ensureOpen(); - termVectorsReader->get(docNumber, mapper); + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); + if (!termVectorsReader) { + return; } - Collection SegmentReader::getTermFreqVectors(int32_t docNumber) - { - ensureOpen(); + termVectorsReader->get(docNumber, mapper); +} - TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); - if (!termVectorsReader) - return Collection(); +Collection SegmentReader::getTermFreqVectors(int32_t docNumber) { + ensureOpen(); - return termVectorsReader->get(docNumber); + TermVectorsReaderPtr termVectorsReader(getTermVectorsReader()); + if (!termVectorsReader) { + return Collection(); } - String SegmentReader::getSegmentName() - { - return core->segment; - } - - SegmentInfoPtr SegmentReader::getSegmentInfo() - { - return si; - } + return termVectorsReader->get(docNumber); +} - void SegmentReader::setSegmentInfo(const SegmentInfoPtr& info) - { - si = info; - } +String SegmentReader::getSegmentName() { + return core->segment; +} - void SegmentReader::startCommit() - { - rollbackSegmentInfo = boost::dynamic_pointer_cast(si->clone()); - rollbackHasChanges = _hasChanges; - rollbackDeletedDocsDirty = deletedDocsDirty; - rollbackNormsDirty = normsDirty; - rollbackPendingDeleteCount = pendingDeleteCount; - for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) - norm->second->rollbackDirty = norm->second->dirty; - } +SegmentInfoPtr SegmentReader::getSegmentInfo() { + return si; +} - void SegmentReader::rollbackCommit() - { - si->reset(rollbackSegmentInfo); - _hasChanges = rollbackHasChanges; - deletedDocsDirty = rollbackDeletedDocsDirty; - normsDirty = rollbackNormsDirty; - pendingDeleteCount = rollbackPendingDeleteCount; - for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) - norm->second->dirty = norm->second->rollbackDirty; - } +void SegmentReader::setSegmentInfo(const SegmentInfoPtr& info) { + si = info; +} - DirectoryPtr SegmentReader::directory() - { - // Don't ensureOpen here - in certain cases, when a cloned/reopened reader needs to commit, - // it may call this method on the closed original reader - return core->dir; +void SegmentReader::startCommit() { + rollbackSegmentInfo = boost::dynamic_pointer_cast(si->clone()); + rollbackHasChanges = _hasChanges; + rollbackDeletedDocsDirty = deletedDocsDirty; + rollbackNormsDirty = normsDirty; + rollbackPendingDeleteCount = pendingDeleteCount; + for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) { + norm->second->rollbackDirty = norm->second->dirty; } +} - LuceneObjectPtr SegmentReader::getFieldCacheKey() - { - return core->freqStream; +void SegmentReader::rollbackCommit() { + si->reset(rollbackSegmentInfo); + _hasChanges = rollbackHasChanges; + deletedDocsDirty = rollbackDeletedDocsDirty; + normsDirty = rollbackNormsDirty; + pendingDeleteCount = rollbackPendingDeleteCount; + for (MapStringNorm::iterator norm = _norms.begin(); norm != _norms.end(); ++norm) { + norm->second->dirty = norm->second->rollbackDirty; } +} - LuceneObjectPtr SegmentReader::getDeletesCacheKey() - { - return deletedDocs; - } +DirectoryPtr SegmentReader::directory() { + // Don't ensureOpen here - in certain cases, when a cloned/reopened reader needs to commit, + // it may call this method on the closed original reader + return core->dir; +} - int64_t SegmentReader::getUniqueTermCount() - { - return core->getTermsReader()->size(); - } +LuceneObjectPtr SegmentReader::getFieldCacheKey() { + return core->freqStream; +} - SegmentReaderPtr SegmentReader::getOnlySegmentReader(const DirectoryPtr& dir) - { - return getOnlySegmentReader(IndexReader::open(dir, false)); - } +LuceneObjectPtr SegmentReader::getDeletesCacheKey() { + return deletedDocs; +} - SegmentReaderPtr SegmentReader::getOnlySegmentReader(const IndexReaderPtr& reader) - { - SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(reader)); - if (segmentReader) - return segmentReader; - - DirectoryReaderPtr directoryReader(boost::dynamic_pointer_cast(reader)); - if (directoryReader) - { - Collection subReaders(directoryReader->getSequentialSubReaders()); - if (subReaders.size() != 1) - boost::throw_exception(IllegalArgumentException(L"reader has " + StringUtils::toString(subReaders.size()) + L" segments instead of exactly one")); - return boost::dynamic_pointer_cast(subReaders[0]); - } +int64_t SegmentReader::getUniqueTermCount() { + return core->getTermsReader()->size(); +} - boost::throw_exception(IllegalArgumentException(L"reader is not a SegmentReader or a single-segment DirectoryReader")); +SegmentReaderPtr SegmentReader::getOnlySegmentReader(const DirectoryPtr& dir) { + return getOnlySegmentReader(IndexReader::open(dir, false)); +} - return SegmentReaderPtr(); +SegmentReaderPtr SegmentReader::getOnlySegmentReader(const IndexReaderPtr& reader) { + SegmentReaderPtr segmentReader(boost::dynamic_pointer_cast(reader)); + if (segmentReader) { + return segmentReader; } - int32_t SegmentReader::getTermInfosIndexDivisor() - { - return core->termsIndexDivisor; + DirectoryReaderPtr directoryReader(boost::dynamic_pointer_cast(reader)); + if (directoryReader) { + Collection subReaders(directoryReader->getSequentialSubReaders()); + if (subReaders.size() != 1) { + boost::throw_exception(IllegalArgumentException(L"reader has " + StringUtils::toString(subReaders.size()) + L" segments instead of exactly one")); + } + return boost::dynamic_pointer_cast(subReaders[0]); } - CoreReaders::CoreReaders(const SegmentReaderPtr& origInstance, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, int32_t termsIndexDivisor) - { - ref = newLucene(); + boost::throw_exception(IllegalArgumentException(L"reader is not a SegmentReader or a single-segment DirectoryReader")); - segment = si->name; - this->readBufferSize = readBufferSize; - this->dir = dir; + return SegmentReaderPtr(); +} - bool success = false; - LuceneException finally; - try - { - DirectoryPtr dir0(dir); - if (si->getUseCompoundFile()) - { - cfsReader = newLucene(dir, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION(), readBufferSize); - dir0 = cfsReader; - } - cfsDir = dir0; +int32_t SegmentReader::getTermInfosIndexDivisor() { + return core->termsIndexDivisor; +} - fieldInfos = newLucene(cfsDir, segment + L"." + IndexFileNames::FIELD_INFOS_EXTENSION()); +CoreReaders::CoreReaders(const SegmentReaderPtr& origInstance, const DirectoryPtr& dir, const SegmentInfoPtr& si, int32_t readBufferSize, int32_t termsIndexDivisor) { + ref = newLucene(); - this->termsIndexDivisor = termsIndexDivisor; - TermInfosReaderPtr reader(newLucene(cfsDir, segment, fieldInfos, readBufferSize, termsIndexDivisor)); - if (termsIndexDivisor == -1) - tisNoIndex = reader; - else - tis = reader; + segment = si->name; + this->readBufferSize = readBufferSize; + this->dir = dir; - // make sure that all index files have been read or are kept open so that if an index - // update removes them we'll still have them - freqStream = cfsDir->openInput(segment + L"." + IndexFileNames::FREQ_EXTENSION(), readBufferSize); + bool success = false; + LuceneException finally; + try { + DirectoryPtr dir0(dir); + if (si->getUseCompoundFile()) { + cfsReader = newLucene(dir, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION(), readBufferSize); + dir0 = cfsReader; + } + cfsDir = dir0; - if (fieldInfos->hasProx()) - proxStream = cfsDir->openInput(segment + L"." + IndexFileNames::PROX_EXTENSION(), readBufferSize); + fieldInfos = newLucene(cfsDir, segment + L"." + IndexFileNames::FIELD_INFOS_EXTENSION()); - success = true; + this->termsIndexDivisor = termsIndexDivisor; + TermInfosReaderPtr reader(newLucene(cfsDir, segment, fieldInfos, readBufferSize, termsIndexDivisor)); + if (termsIndexDivisor == -1) { + tisNoIndex = reader; + } else { + tis = reader; } - catch (LuceneException& e) - { - finally = e; + + // make sure that all index files have been read or are kept open so that if an index + // update removes them we'll still have them + freqStream = cfsDir->openInput(segment + L"." + IndexFileNames::FREQ_EXTENSION(), readBufferSize); + + if (fieldInfos->hasProx()) { + proxStream = cfsDir->openInput(segment + L"." + IndexFileNames::PROX_EXTENSION(), readBufferSize); } - if (!success) - decRef(); - finally.throwException(); - // Must assign this at the end -- if we hit an exception above core, we don't want to attempt to - // purge the FieldCache (will hit NPE because core is not assigned yet). - _origInstance = origInstance; + success = true; + } catch (LuceneException& e) { + finally = e; } - - CoreReaders::~CoreReaders() - { + if (!success) { + decRef(); } + finally.throwException(); - TermVectorsReaderPtr CoreReaders::getTermVectorsReaderOrig() - { - SyncLock syncLock(this); - return termVectorsReaderOrig; - } + // Must assign this at the end -- if we hit an exception above core, we don't want to attempt to + // purge the FieldCache (will hit NPE because core is not assigned yet). + _origInstance = origInstance; +} - FieldsReaderPtr CoreReaders::getFieldsReaderOrig() - { - SyncLock syncLock(this); - return fieldsReaderOrig; - } +CoreReaders::~CoreReaders() { +} - void CoreReaders::incRef() - { - SyncLock syncLock(this); - ref->incRef(); - } +TermVectorsReaderPtr CoreReaders::getTermVectorsReaderOrig() { + SyncLock syncLock(this); + return termVectorsReaderOrig; +} - DirectoryPtr CoreReaders::getCFSReader() - { - SyncLock syncLock(this); - return cfsReader; - } +FieldsReaderPtr CoreReaders::getFieldsReaderOrig() { + SyncLock syncLock(this); + return fieldsReaderOrig; +} - TermInfosReaderPtr CoreReaders::getTermsReader() - { - SyncLock syncLock(this); - return tis ? tis : tisNoIndex; - } +void CoreReaders::incRef() { + SyncLock syncLock(this); + ref->incRef(); +} - bool CoreReaders::termsIndexIsLoaded() - { - SyncLock syncLock(this); - return tis.get() != NULL; - } +DirectoryPtr CoreReaders::getCFSReader() { + SyncLock syncLock(this); + return cfsReader; +} - void CoreReaders::loadTermsIndex(const SegmentInfoPtr& si, int32_t termsIndexDivisor) - { - SyncLock syncLock(this); - if (!tis) - { - DirectoryPtr dir0; - if (si->getUseCompoundFile()) - { - // In some cases, we were originally opened when CFS was not used, but then we are asked - // to open the terms reader with index, the segment has switched to CFS - if (!cfsReader) - cfsReader = newLucene(dir, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION(), readBufferSize); +TermInfosReaderPtr CoreReaders::getTermsReader() { + SyncLock syncLock(this); + return tis ? tis : tisNoIndex; +} - dir0 = cfsReader; +bool CoreReaders::termsIndexIsLoaded() { + SyncLock syncLock(this); + return tis.get() != NULL; +} + +void CoreReaders::loadTermsIndex(const SegmentInfoPtr& si, int32_t termsIndexDivisor) { + SyncLock syncLock(this); + if (!tis) { + DirectoryPtr dir0; + if (si->getUseCompoundFile()) { + // In some cases, we were originally opened when CFS was not used, but then we are asked + // to open the terms reader with index, the segment has switched to CFS + if (!cfsReader) { + cfsReader = newLucene(dir, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION(), readBufferSize); } - else - dir0 = dir; - tis = newLucene(dir0, segment, fieldInfos, readBufferSize, termsIndexDivisor); + dir0 = cfsReader; + } else { + dir0 = dir; } + + tis = newLucene(dir0, segment, fieldInfos, readBufferSize, termsIndexDivisor); } +} - void CoreReaders::decRef() - { - SyncLock syncLock(this); - if (ref->decRef() == 0) - { - // close everything, nothing is shared anymore with other readers - if (tis) - { - tis->close(); - tis.reset(); // null so if an app hangs on to us we still free most ram - } - if (tisNoIndex) - tisNoIndex->close(); - if (freqStream) - freqStream->close(); - if (proxStream) - proxStream->close(); - if (termVectorsReaderOrig) - termVectorsReaderOrig->close(); - if (fieldsReaderOrig) - fieldsReaderOrig->close(); - if (cfsReader) - cfsReader->close(); - if (storeCFSReader) - storeCFSReader->close(); - - // Force FieldCache to evict our entries at this point - SegmentReaderPtr origInstance(_origInstance.lock()); - if (origInstance) - FieldCache::DEFAULT()->purge(origInstance); +void CoreReaders::decRef() { + SyncLock syncLock(this); + if (ref->decRef() == 0) { + // close everything, nothing is shared anymore with other readers + if (tis) { + tis->close(); + tis.reset(); // null so if an app hangs on to us we still free most ram + } + if (tisNoIndex) { + tisNoIndex->close(); + } + if (freqStream) { + freqStream->close(); + } + if (proxStream) { + proxStream->close(); + } + if (termVectorsReaderOrig) { + termVectorsReaderOrig->close(); + } + if (fieldsReaderOrig) { + fieldsReaderOrig->close(); + } + if (cfsReader) { + cfsReader->close(); + } + if (storeCFSReader) { + storeCFSReader->close(); } - } - void CoreReaders::openDocStores(const SegmentInfoPtr& si) - { - SyncLock syncLock(this); - BOOST_ASSERT(si->name == segment); + // Force FieldCache to evict our entries at this point + SegmentReaderPtr origInstance(_origInstance.lock()); + if (origInstance) { + FieldCache::DEFAULT()->purge(origInstance); + } + } +} - if (!fieldsReaderOrig) - { - DirectoryPtr storeDir; - if (si->getDocStoreOffset() != -1) - { - if (si->getDocStoreIsCompoundFile()) - { - BOOST_ASSERT(!storeCFSReader); - storeCFSReader = newLucene(dir, si->getDocStoreSegment() + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION(), readBufferSize); - storeDir = storeCFSReader; - BOOST_ASSERT(storeDir); - } - else - { - storeDir = dir; - BOOST_ASSERT(storeDir); - } - } - else if (si->getUseCompoundFile()) - { - // In some cases, we were originally opened when CFS was not used, but then we are asked to open doc - // stores after the segment has switched to CFS - if (!cfsReader) - cfsReader = newLucene(dir, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION(), readBufferSize); - storeDir = cfsReader; +void CoreReaders::openDocStores(const SegmentInfoPtr& si) { + SyncLock syncLock(this); + BOOST_ASSERT(si->name == segment); + + if (!fieldsReaderOrig) { + DirectoryPtr storeDir; + if (si->getDocStoreOffset() != -1) { + if (si->getDocStoreIsCompoundFile()) { + BOOST_ASSERT(!storeCFSReader); + storeCFSReader = newLucene(dir, si->getDocStoreSegment() + L"." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION(), readBufferSize); + storeDir = storeCFSReader; BOOST_ASSERT(storeDir); - } - else - { + } else { storeDir = dir; BOOST_ASSERT(storeDir); } + } else if (si->getUseCompoundFile()) { + // In some cases, we were originally opened when CFS was not used, but then we are asked to open doc + // stores after the segment has switched to CFS + if (!cfsReader) { + cfsReader = newLucene(dir, segment + L"." + IndexFileNames::COMPOUND_FILE_EXTENSION(), readBufferSize); + } + storeDir = cfsReader; + BOOST_ASSERT(storeDir); + } else { + storeDir = dir; + BOOST_ASSERT(storeDir); + } - String storesSegment(si->getDocStoreOffset() != -1 ? si->getDocStoreSegment() : segment); + String storesSegment(si->getDocStoreOffset() != -1 ? si->getDocStoreSegment() : segment); - fieldsReaderOrig = newLucene(storeDir, storesSegment, fieldInfos, readBufferSize, si->getDocStoreOffset(), si->docCount); + fieldsReaderOrig = newLucene(storeDir, storesSegment, fieldInfos, readBufferSize, si->getDocStoreOffset(), si->docCount); - // Verify two sources of "maxDoc" agree - if (si->getDocStoreOffset() == -1 && fieldsReaderOrig->size() != si->docCount) - { - boost::throw_exception(CorruptIndexException(L"doc counts differ for segment " + segment + - L": fieldsReader shows " + StringUtils::toString(fieldsReaderOrig->size()) + - L" but segmentInfo shows " + StringUtils::toString(si->docCount))); - } + // Verify two sources of "maxDoc" agree + if (si->getDocStoreOffset() == -1 && fieldsReaderOrig->size() != si->docCount) { + boost::throw_exception(CorruptIndexException(L"doc counts differ for segment " + segment + + L": fieldsReader shows " + StringUtils::toString(fieldsReaderOrig->size()) + + L" but segmentInfo shows " + StringUtils::toString(si->docCount))); + } - if (fieldInfos->hasVectors()) // open term vector files only as needed - termVectorsReaderOrig = newLucene(storeDir, storesSegment, fieldInfos, readBufferSize, si->getDocStoreOffset(), si->docCount); + if (fieldInfos->hasVectors()) { // open term vector files only as needed + termVectorsReaderOrig = newLucene(storeDir, storesSegment, fieldInfos, readBufferSize, si->getDocStoreOffset(), si->docCount); } } +} - FieldsReaderLocal::FieldsReaderLocal(const SegmentReaderPtr& reader) - { - this->_reader = reader; - } +FieldsReaderLocal::FieldsReaderLocal(const SegmentReaderPtr& reader) { + this->_reader = reader; +} - FieldsReaderPtr FieldsReaderLocal::initialValue() - { - return boost::dynamic_pointer_cast(SegmentReaderPtr(_reader)->core->getFieldsReaderOrig()->clone()); - } +FieldsReaderPtr FieldsReaderLocal::initialValue() { + return boost::dynamic_pointer_cast(SegmentReaderPtr(_reader)->core->getFieldsReaderOrig()->clone()); +} - SegmentReaderRef::SegmentReaderRef() - { - _refCount = 1; - } +SegmentReaderRef::SegmentReaderRef() { + _refCount = 1; +} - SegmentReaderRef::~SegmentReaderRef() - { - } +SegmentReaderRef::~SegmentReaderRef() { +} - String SegmentReaderRef::toString() - { - StringStream buffer; - buffer << L"refcount: " << _refCount; - return buffer.str(); - } +String SegmentReaderRef::toString() { + StringStream buffer; + buffer << L"refcount: " << _refCount; + return buffer.str(); +} - int32_t SegmentReaderRef::refCount() - { - SyncLock syncLock(this); - return _refCount; - } +int32_t SegmentReaderRef::refCount() { + SyncLock syncLock(this); + return _refCount; +} - int32_t SegmentReaderRef::incRef() - { - SyncLock syncLock(this); - BOOST_ASSERT(_refCount > 0); - return ++_refCount; - } +int32_t SegmentReaderRef::incRef() { + SyncLock syncLock(this); + BOOST_ASSERT(_refCount > 0); + return ++_refCount; +} - int32_t SegmentReaderRef::decRef() - { - SyncLock syncLock(this); - BOOST_ASSERT(_refCount > 0); - return --_refCount; - } +int32_t SegmentReaderRef::decRef() { + SyncLock syncLock(this); + BOOST_ASSERT(_refCount > 0); + return --_refCount; +} - Norm::Norm() - { - this->refCount = 1; - this->normSeek = 0; - this->dirty = false; - this->rollbackDirty = false; - this->number = 0; - } +Norm::Norm() { + this->refCount = 1; + this->normSeek = 0; + this->dirty = false; + this->rollbackDirty = false; + this->number = 0; +} - Norm::Norm(const SegmentReaderPtr& reader, const IndexInputPtr& in, int32_t number, int64_t normSeek) - { - this->_reader = reader; - this->refCount = 1; - this->dirty = false; - this->rollbackDirty = false; - this->in = in; - this->number = number; - this->normSeek = normSeek; - } +Norm::Norm(const SegmentReaderPtr& reader, const IndexInputPtr& in, int32_t number, int64_t normSeek) { + this->_reader = reader; + this->refCount = 1; + this->dirty = false; + this->rollbackDirty = false; + this->in = in; + this->number = number; + this->normSeek = normSeek; +} - Norm::~Norm() - { - } +Norm::~Norm() { +} - void Norm::incRef() - { - SyncLock syncLock(this); - BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - ++refCount; - } +void Norm::incRef() { + SyncLock syncLock(this); + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); + ++refCount; +} - void Norm::closeInput() - { - SegmentReaderPtr reader(_reader.lock()); - if (in && reader) - { - if (in != reader->singleNormStream) - { - // It's private to us -- just close it - in->close(); +void Norm::closeInput() { + SegmentReaderPtr reader(_reader.lock()); + if (in && reader) { + if (in != reader->singleNormStream) { + // It's private to us -- just close it + in->close(); + } else { + // We are sharing this with others -- decRef and maybe close the shared norm stream + if (reader->singleNormRef->decRef() == 0) { + reader->singleNormStream->close(); + reader->singleNormStream.reset(); } - else - { - // We are sharing this with others -- decRef and maybe close the shared norm stream - if (reader->singleNormRef->decRef() == 0) - { - reader->singleNormStream->close(); - reader->singleNormStream.reset(); - } - } - - in.reset(); } + + in.reset(); } +} - void Norm::decRef() - { - SyncLock syncLock(this); - BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); +void Norm::decRef() { + SyncLock syncLock(this); + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - if (--refCount == 0) - { - if (origNorm) - { - origNorm->decRef(); - origNorm.reset(); - } - else - closeInput(); + if (--refCount == 0) { + if (origNorm) { + origNorm->decRef(); + origNorm.reset(); + } else { + closeInput(); + } - if (origReader) - origReader.reset(); + if (origReader) { + origReader.reset(); + } - if (_bytes) - { - BOOST_ASSERT(_bytesRef); - _bytesRef->decRef(); - _bytes.reset(); - _bytesRef.reset(); - } - else - { - BOOST_ASSERT(!_bytesRef); - } + if (_bytes) { + BOOST_ASSERT(_bytesRef); + _bytesRef->decRef(); + _bytes.reset(); + _bytesRef.reset(); + } else { + BOOST_ASSERT(!_bytesRef); } } +} - void Norm::bytes(uint8_t* bytesOut, int32_t offset, int32_t length) - { - SyncLock syncLock(this); - BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - if (_bytes) - { - // Already cached - copy from cache - BOOST_ASSERT(length <= SegmentReaderPtr(_reader)->maxDoc()); - MiscUtils::arrayCopy(_bytes.get(), 0, bytesOut, offset, length); +void Norm::bytes(uint8_t* bytesOut, int32_t offset, int32_t length) { + SyncLock syncLock(this); + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); + if (_bytes) { + // Already cached - copy from cache + BOOST_ASSERT(length <= SegmentReaderPtr(_reader)->maxDoc()); + MiscUtils::arrayCopy(_bytes.get(), 0, bytesOut, offset, length); + } else { + // Not cached + if (origNorm) { + // Ask origNorm to load + origNorm->bytes(bytesOut, offset, length); + } else { + // We are orig - read ourselves from disk + SyncLock instancesLock(in); + in->seek(normSeek); + in->readBytes(bytesOut, offset, length, false); } - else - { - // Not cached - if (origNorm) - { - // Ask origNorm to load - origNorm->bytes(bytesOut, offset, length); - } - else + } +} + +ByteArray Norm::bytes() { + SyncLock syncLock(this); + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); + if (!_bytes) { // value not yet read + BOOST_ASSERT(!_bytesRef); + if (origNorm) { + // Ask origNorm to load so that for a series of reopened readers we share a single read-only byte[] + _bytes = origNorm->bytes(); + _bytesRef = origNorm->_bytesRef; + _bytesRef->incRef(); + + // Once we've loaded the bytes we no longer need origNorm + origNorm->decRef(); + origNorm.reset(); + origReader.reset(); + } else { + // We are the origNorm, so load the bytes for real ourself + int32_t count = SegmentReaderPtr(_reader)->maxDoc(); + _bytes = ByteArray::newInstance(count); + + // Since we are orig, in must not be null + BOOST_ASSERT(in); + + // Read from disk. { - // We are orig - read ourselves from disk SyncLock instancesLock(in); in->seek(normSeek); - in->readBytes(bytesOut, offset, length, false); + in->readBytes(_bytes.get(), 0, count, false); } + + _bytesRef = newLucene(); + closeInput(); } } - ByteArray Norm::bytes() - { - SyncLock syncLock(this); - BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - if (!_bytes) // value not yet read - { - BOOST_ASSERT(!_bytesRef); - if (origNorm) - { - // Ask origNorm to load so that for a series of reopened readers we share a single read-only byte[] - _bytes = origNorm->bytes(); - _bytesRef = origNorm->_bytesRef; - _bytesRef->incRef(); - - // Once we've loaded the bytes we no longer need origNorm - origNorm->decRef(); - origNorm.reset(); - origReader.reset(); - } - else - { - // We are the origNorm, so load the bytes for real ourself - int32_t count = SegmentReaderPtr(_reader)->maxDoc(); - _bytes = ByteArray::newInstance(count); - - // Since we are orig, in must not be null - BOOST_ASSERT(in); - - // Read from disk. - { - SyncLock instancesLock(in); - in->seek(normSeek); - in->readBytes(_bytes.get(), 0, count, false); - } - - _bytesRef = newLucene(); - closeInput(); - } - } + return _bytes; +} - return _bytes; - } +SegmentReaderRefPtr Norm::bytesRef() { + return _bytesRef; +} - SegmentReaderRefPtr Norm::bytesRef() - { - return _bytesRef; - } +ByteArray Norm::copyOnWrite() { + SyncLock syncLock(this); + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); + bytes(); + BOOST_ASSERT(_bytes); + BOOST_ASSERT(_bytesRef); + if (_bytesRef->refCount() > 1) { + // I cannot be the origNorm for another norm instance if I'm being changed. + // ie, only the "head Norm" can be changed + BOOST_ASSERT(refCount == 1); + SegmentReaderRefPtr oldRef(_bytesRef); + _bytes = SegmentReaderPtr(_reader)->cloneNormBytes(_bytes); + _bytesRef = newLucene(); + oldRef->decRef(); + } + dirty = true; + return _bytes; +} - ByteArray Norm::copyOnWrite() - { - SyncLock syncLock(this); - BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - bytes(); - BOOST_ASSERT(_bytes); +LuceneObjectPtr Norm::clone(const LuceneObjectPtr& other) { + SyncLock syncLock(this); + + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); + LuceneObjectPtr clone = other ? other : newLucene(); + NormPtr cloneNorm(boost::dynamic_pointer_cast(clone)); + cloneNorm->_reader = _reader; + cloneNorm->origNorm = origNorm; + cloneNorm->origReader = origReader; + cloneNorm->normSeek = normSeek; + cloneNorm->_bytesRef = _bytesRef; + cloneNorm->_bytes = _bytes; + cloneNorm->dirty = dirty; + cloneNorm->number = number; + cloneNorm->rollbackDirty = rollbackDirty; + + cloneNorm->refCount = 1; + + if (_bytes) { BOOST_ASSERT(_bytesRef); - if (_bytesRef->refCount() > 1) - { - // I cannot be the origNorm for another norm instance if I'm being changed. - // ie, only the "head Norm" can be changed - BOOST_ASSERT(refCount == 1); - SegmentReaderRefPtr oldRef(_bytesRef); - _bytes = SegmentReaderPtr(_reader)->cloneNormBytes(_bytes); - _bytesRef = newLucene(); - oldRef->decRef(); + BOOST_ASSERT(!origNorm); + + // Clone holds a reference to my bytes + cloneNorm->_bytesRef->incRef(); + } else { + BOOST_ASSERT(!_bytesRef); + if (!origNorm) { + // I become the origNorm for the clone + cloneNorm->origNorm = shared_from_this(); + cloneNorm->origReader = SegmentReaderPtr(_reader); } - dirty = true; - return _bytes; + cloneNorm->origNorm->incRef(); } - LuceneObjectPtr Norm::clone(const LuceneObjectPtr& other) - { - SyncLock syncLock(this); - - BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); - LuceneObjectPtr clone = other ? other : newLucene(); - NormPtr cloneNorm(boost::dynamic_pointer_cast(clone)); - cloneNorm->_reader = _reader; - cloneNorm->origNorm = origNorm; - cloneNorm->origReader = origReader; - cloneNorm->normSeek = normSeek; - cloneNorm->_bytesRef = _bytesRef; - cloneNorm->_bytes = _bytes; - cloneNorm->dirty = dirty; - cloneNorm->number = number; - cloneNorm->rollbackDirty = rollbackDirty; - - cloneNorm->refCount = 1; - - if (_bytes) - { - BOOST_ASSERT(_bytesRef); - BOOST_ASSERT(!origNorm); - - // Clone holds a reference to my bytes - cloneNorm->_bytesRef->incRef(); - } - else - { - BOOST_ASSERT(!_bytesRef); - if (!origNorm) - { - // I become the origNorm for the clone - cloneNorm->origNorm = shared_from_this(); - cloneNorm->origReader = SegmentReaderPtr(_reader); - } - cloneNorm->origNorm->incRef(); - } + // Only the origNorm will actually readBytes from in + cloneNorm->in.reset(); - // Only the origNorm will actually readBytes from in - cloneNorm->in.reset(); - - return cloneNorm; - } - - void Norm::reWrite(const SegmentInfoPtr& si) - { - BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); + return cloneNorm; +} - // NOTE: norms are re-written in regular directory, not cfs - si->advanceNormGen(this->number); - String normFileName(si->getNormFileName(this->number)); - SegmentReaderPtr reader(_reader); - IndexOutputPtr out(reader->directory()->createOutput(normFileName)); - bool success = false; - LuceneException finally; - try - { - try - { - out->writeBytes(_bytes.get(), reader->maxDoc()); - } - catch (LuceneException& e) - { - finally = e; - } - out->close(); - finally.throwException(); - success = true; - } - catch (LuceneException& e) - { +void Norm::reWrite(const SegmentInfoPtr& si) { + BOOST_ASSERT(refCount > 0 && (!origNorm || origNorm->refCount > 0)); + + // NOTE: norms are re-written in regular directory, not cfs + si->advanceNormGen(this->number); + String normFileName(si->getNormFileName(this->number)); + SegmentReaderPtr reader(_reader); + IndexOutputPtr out(reader->directory()->createOutput(normFileName)); + bool success = false; + LuceneException finally; + try { + try { + out->writeBytes(_bytes.get(), reader->maxDoc()); + } catch (LuceneException& e) { finally = e; } - if (!success) - { - try - { - reader->directory()->deleteFile(normFileName); - } - catch (...) - { - // suppress this so we keep throwing the original exception - } - } + out->close(); finally.throwException(); - this->dirty = false; + success = true; + } catch (LuceneException& e) { + finally = e; + } + if (!success) { + try { + reader->directory()->deleteFile(normFileName); + } catch (...) { + // suppress this so we keep throwing the original exception + } } + finally.throwException(); + this->dirty = false; +} + } diff --git a/src/core/index/SegmentTermDocs.cpp b/src/core/index/SegmentTermDocs.cpp index 6e60c3f1..9e49ec8c 100644 --- a/src/core/index/SegmentTermDocs.cpp +++ b/src/core/index/SegmentTermDocs.cpp @@ -19,232 +19,206 @@ #include "BitVector.h" #include "MiscUtils.h" -namespace Lucene -{ - SegmentTermDocs::SegmentTermDocs(const SegmentReaderPtr& parent) - { - this->_parent = parent; - this->count = 0; - this->df = 0; - this->_doc = 0; - this->_freq = 0; - this->freqBasePointer = 0; - this->proxBasePointer = 0; - this->skipPointer = 0; - this->haveSkipped = false; - this->currentFieldStoresPayloads = false; - this->currentFieldOmitTermFreqAndPositions = false; - - this->_freqStream = boost::dynamic_pointer_cast(parent->core->freqStream->clone()); - { - SyncLock parentLock(parent); - this->deletedDocs = parent->deletedDocs; - } - this->skipInterval = parent->core->getTermsReader()->getSkipInterval(); - this->maxSkipLevels = parent->core->getTermsReader()->getMaxSkipLevels(); - } - - SegmentTermDocs::~SegmentTermDocs() - { - } +namespace Lucene { + +SegmentTermDocs::SegmentTermDocs(const SegmentReaderPtr& parent) { + this->_parent = parent; + this->count = 0; + this->df = 0; + this->_doc = 0; + this->_freq = 0; + this->freqBasePointer = 0; + this->proxBasePointer = 0; + this->skipPointer = 0; + this->haveSkipped = false; + this->currentFieldStoresPayloads = false; + this->currentFieldOmitTermFreqAndPositions = false; + + this->_freqStream = boost::dynamic_pointer_cast(parent->core->freqStream->clone()); + { + SyncLock parentLock(parent); + this->deletedDocs = parent->deletedDocs; + } + this->skipInterval = parent->core->getTermsReader()->getSkipInterval(); + this->maxSkipLevels = parent->core->getTermsReader()->getMaxSkipLevels(); +} - void SegmentTermDocs::seek(const TermPtr& term) - { - TermInfoPtr ti(SegmentReaderPtr(_parent)->core->getTermsReader()->get(term)); - seek(ti, term); - } +SegmentTermDocs::~SegmentTermDocs() { +} - void SegmentTermDocs::seek(const TermEnumPtr& termEnum) - { - TermInfoPtr ti; - TermPtr term; +void SegmentTermDocs::seek(const TermPtr& term) { + TermInfoPtr ti(SegmentReaderPtr(_parent)->core->getTermsReader()->get(term)); + seek(ti, term); +} - SegmentTermEnumPtr segmentTermEnum(boost::dynamic_pointer_cast(termEnum)); - SegmentReaderPtr parent(_parent); +void SegmentTermDocs::seek(const TermEnumPtr& termEnum) { + TermInfoPtr ti; + TermPtr term; - // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs - if (segmentTermEnum && segmentTermEnum->fieldInfos == parent->core->fieldInfos) // optimized case - { - term = segmentTermEnum->term(); - ti = segmentTermEnum->termInfo(); - } - else // punt case - { - term = termEnum->term(); - ti = parent->core->getTermsReader()->get(term); - } + SegmentTermEnumPtr segmentTermEnum(boost::dynamic_pointer_cast(termEnum)); + SegmentReaderPtr parent(_parent); - seek(ti, term); + // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs + if (segmentTermEnum && segmentTermEnum->fieldInfos == parent->core->fieldInfos) { // optimized case + term = segmentTermEnum->term(); + ti = segmentTermEnum->termInfo(); + } else { // punt case + term = termEnum->term(); + ti = parent->core->getTermsReader()->get(term); } - void SegmentTermDocs::seek(const TermInfoPtr& ti, const TermPtr& term) - { - count = 0; - FieldInfoPtr fi(SegmentReaderPtr(_parent)->core->fieldInfos->fieldInfo(term->_field)); - currentFieldOmitTermFreqAndPositions = fi ? fi->omitTermFreqAndPositions : false; - currentFieldStoresPayloads = fi ? fi->storePayloads : false; - if (!ti) - df = 0; - else - { - df = ti->docFreq; - _doc = 0; - freqBasePointer = ti->freqPointer; - proxBasePointer = ti->proxPointer; - skipPointer = freqBasePointer + ti->skipOffset; - _freqStream->seek(freqBasePointer); - haveSkipped = false; - } - } + seek(ti, term); +} - void SegmentTermDocs::close() - { - _freqStream->close(); - if (skipListReader) - skipListReader->close(); +void SegmentTermDocs::seek(const TermInfoPtr& ti, const TermPtr& term) { + count = 0; + FieldInfoPtr fi(SegmentReaderPtr(_parent)->core->fieldInfos->fieldInfo(term->_field)); + currentFieldOmitTermFreqAndPositions = fi ? fi->omitTermFreqAndPositions : false; + currentFieldStoresPayloads = fi ? fi->storePayloads : false; + if (!ti) { + df = 0; + } else { + df = ti->docFreq; + _doc = 0; + freqBasePointer = ti->freqPointer; + proxBasePointer = ti->proxPointer; + skipPointer = freqBasePointer + ti->skipOffset; + _freqStream->seek(freqBasePointer); + haveSkipped = false; } +} - int32_t SegmentTermDocs::doc() - { - return _doc; +void SegmentTermDocs::close() { + _freqStream->close(); + if (skipListReader) { + skipListReader->close(); } +} - int32_t SegmentTermDocs::freq() - { - return _freq; - } +int32_t SegmentTermDocs::doc() { + return _doc; +} - void SegmentTermDocs::skippingDoc() - { - } +int32_t SegmentTermDocs::freq() { + return _freq; +} - bool SegmentTermDocs::next() - { - while (true) - { - if (count == df) - return false; - int32_t docCode = _freqStream->readVInt(); +void SegmentTermDocs::skippingDoc() { +} - if (currentFieldOmitTermFreqAndPositions) - { - _doc += docCode; - _freq = 1; - } - else - { - _doc += MiscUtils::unsignedShift(docCode, 1); // shift off low bit - if ((docCode & 1) != 0) // if low bit is set - _freq = 1; // freq is one - else - _freq = _freqStream->readVInt(); // else read freq +bool SegmentTermDocs::next() { + while (true) { + if (count == df) { + return false; + } + int32_t docCode = _freqStream->readVInt(); + + if (currentFieldOmitTermFreqAndPositions) { + _doc += docCode; + _freq = 1; + } else { + _doc += MiscUtils::unsignedShift(docCode, 1); // shift off low bit + if ((docCode & 1) != 0) { // if low bit is set + _freq = 1; // freq is one + } else { + _freq = _freqStream->readVInt(); // else read freq } - - ++count; - - if (!deletedDocs || !deletedDocs->get(_doc)) - break; - skippingDoc(); } - return true; - } - int32_t SegmentTermDocs::read(Collection docs, Collection freqs) - { - int32_t length = docs.size(); - if (currentFieldOmitTermFreqAndPositions) - return readNoTf(docs, freqs, length); - else - { - int32_t i = 0; - while (i < length && count < df) - { - // manually inlined call to next() for speed - int32_t docCode = _freqStream->readVInt(); - _doc += MiscUtils::unsignedShift(docCode, 1); // shift off low bit - if ((docCode & 1) != 0) // if low bit is set - _freq = 1; // freq is one - else - _freq = _freqStream->readVInt(); // else read freq - ++count; - - if (!deletedDocs || !deletedDocs->get(_doc)) - { - docs[i] = _doc; - freqs[i] = _freq; - ++i; - } - } - return i; + ++count; + + if (!deletedDocs || !deletedDocs->get(_doc)) { + break; } + skippingDoc(); } + return true; +} - int32_t SegmentTermDocs::readNoTf(Collection docs, Collection freqs, int32_t length) - { +int32_t SegmentTermDocs::read(Collection docs, Collection freqs) { + int32_t length = docs.size(); + if (currentFieldOmitTermFreqAndPositions) { + return readNoTf(docs, freqs, length); + } else { int32_t i = 0; - while (i < length && count < df) - { + while (i < length && count < df) { // manually inlined call to next() for speed - _doc += _freqStream->readVInt(); + int32_t docCode = _freqStream->readVInt(); + _doc += MiscUtils::unsignedShift(docCode, 1); // shift off low bit + if ((docCode & 1) != 0) { // if low bit is set + _freq = 1; // freq is one + } else { + _freq = _freqStream->readVInt(); // else read freq + } ++count; - if (!deletedDocs || !deletedDocs->get(_doc)) - { + if (!deletedDocs || !deletedDocs->get(_doc)) { docs[i] = _doc; - - // Hardware freq to 1 when term freqs were not stored in the index - freqs[i] = 1; + freqs[i] = _freq; ++i; } } return i; } +} - void SegmentTermDocs::skipProx(int64_t proxPointer, int32_t payloadLength) - { +int32_t SegmentTermDocs::readNoTf(Collection docs, Collection freqs, int32_t length) { + int32_t i = 0; + while (i < length && count < df) { + // manually inlined call to next() for speed + _doc += _freqStream->readVInt(); + ++count; + + if (!deletedDocs || !deletedDocs->get(_doc)) { + docs[i] = _doc; + + // Hardware freq to 1 when term freqs were not stored in the index + freqs[i] = 1; + ++i; + } } + return i; +} - bool SegmentTermDocs::skipTo(int32_t target) - { - if (df >= skipInterval) // optimized case - { - if (!skipListReader) - skipListReader = newLucene(boost::dynamic_pointer_cast(_freqStream->clone()), maxSkipLevels, skipInterval); // lazily clone - - if (!haveSkipped) // lazily initialize skip stream - { - skipListReader->init(skipPointer, freqBasePointer, proxBasePointer, df, currentFieldStoresPayloads); - haveSkipped = true; - } +void SegmentTermDocs::skipProx(int64_t proxPointer, int32_t payloadLength) { +} - int32_t newCount = skipListReader->skipTo(target); - if (newCount > count) - { - _freqStream->seek(skipListReader->getFreqPointer()); - skipProx(skipListReader->getProxPointer(), skipListReader->getPayloadLength()); +bool SegmentTermDocs::skipTo(int32_t target) { + if (df >= skipInterval) { // optimized case + if (!skipListReader) { + skipListReader = newLucene(boost::dynamic_pointer_cast(_freqStream->clone()), maxSkipLevels, skipInterval); // lazily clone + } - _doc = skipListReader->getDoc(); - count = newCount; - } + if (!haveSkipped) { // lazily initialize skip stream + skipListReader->init(skipPointer, freqBasePointer, proxBasePointer, df, currentFieldStoresPayloads); + haveSkipped = true; } - // done skipping, now just scan - do - { - if (!next()) - return false; + int32_t newCount = skipListReader->skipTo(target); + if (newCount > count) { + _freqStream->seek(skipListReader->getFreqPointer()); + skipProx(skipListReader->getProxPointer(), skipListReader->getPayloadLength()); + + _doc = skipListReader->getDoc(); + count = newCount; } - while (target > _doc); - return true; } - IndexInputPtr SegmentTermDocs::freqStream() - { - return _freqStream; - } + // done skipping, now just scan + do { + if (!next()) { + return false; + } + } while (target > _doc); + return true; +} + +IndexInputPtr SegmentTermDocs::freqStream() { + return _freqStream; +} + +void SegmentTermDocs::freqStream(const IndexInputPtr& freqStream) { + _freqStream = freqStream; +} - void SegmentTermDocs::freqStream(const IndexInputPtr& freqStream) - { - _freqStream = freqStream; - } } diff --git a/src/core/index/SegmentTermEnum.cpp b/src/core/index/SegmentTermEnum.cpp index 8adae7e7..2a157b4a 100644 --- a/src/core/index/SegmentTermEnum.cpp +++ b/src/core/index/SegmentTermEnum.cpp @@ -12,217 +12,196 @@ #include "TermInfo.h" #include "StringUtils.h" -namespace Lucene -{ - SegmentTermEnum::SegmentTermEnum() - { - format = 0; - termBuffer = newLucene(); - prevBuffer = newLucene(); - scanBuffer = newLucene(); - _termInfo = newLucene(); - formatM1SkipInterval = 0; - size = 0; - position = -1; - indexPointer = 0; - indexInterval = 0; - skipInterval = 0; - maxSkipLevels = 0; - - isIndex = false; - maxSkipLevels = 0; - } +namespace Lucene { + +SegmentTermEnum::SegmentTermEnum() { + format = 0; + termBuffer = newLucene(); + prevBuffer = newLucene(); + scanBuffer = newLucene(); + _termInfo = newLucene(); + formatM1SkipInterval = 0; + size = 0; + position = -1; + indexPointer = 0; + indexInterval = 0; + skipInterval = 0; + maxSkipLevels = 0; + + isIndex = false; + maxSkipLevels = 0; +} - SegmentTermEnum::SegmentTermEnum(const IndexInputPtr& i, const FieldInfosPtr& fis, bool isi) - { +SegmentTermEnum::SegmentTermEnum(const IndexInputPtr& i, const FieldInfosPtr& fis, bool isi) { + format = 0; + termBuffer = newLucene(); + prevBuffer = newLucene(); + scanBuffer = newLucene(); + _termInfo = newLucene(); + formatM1SkipInterval = 0; + size = 0; + position = -1; + indexPointer = 0; + indexInterval = 0; + skipInterval = 0; + maxSkipLevels = 0; + + input = i; + fieldInfos = fis; + isIndex = isi; + maxSkipLevels = 1; // use single-level skip lists for formats > -3 + + int32_t firstInt = input->readInt(); + if (firstInt >= 0) { + // original-format file, without explicit format version number format = 0; - termBuffer = newLucene(); - prevBuffer = newLucene(); - scanBuffer = newLucene(); - _termInfo = newLucene(); - formatM1SkipInterval = 0; - size = 0; - position = -1; - indexPointer = 0; - indexInterval = 0; - skipInterval = 0; - maxSkipLevels = 0; - - input = i; - fieldInfos = fis; - isIndex = isi; - maxSkipLevels = 1; // use single-level skip lists for formats > -3 - - int32_t firstInt = input->readInt(); - if (firstInt >= 0) - { - // original-format file, without explicit format version number - format = 0; - size = firstInt; - - // back-compatible settings - indexInterval = 128; - skipInterval = INT_MAX; // switch off skipTo optimization + size = firstInt; + + // back-compatible settings + indexInterval = 128; + skipInterval = INT_MAX; // switch off skipTo optimization + } else { + // we have a format version number + format = firstInt; + + // check that it is a format we can understand + if (format < TermInfosWriter::FORMAT_CURRENT) { + boost::throw_exception(CorruptIndexException(L"Unknown format version:" + StringUtils::toString(format) + L" expected " + StringUtils::toString(TermInfosWriter::FORMAT_CURRENT) + L" or higher")); } - else - { - // we have a format version number - format = firstInt; - - // check that it is a format we can understand - if (format < TermInfosWriter::FORMAT_CURRENT) - boost::throw_exception(CorruptIndexException(L"Unknown format version:" + StringUtils::toString(format) + L" expected " + StringUtils::toString(TermInfosWriter::FORMAT_CURRENT) + L" or higher")); - - size = input->readLong(); // read the size - - if (format == -1) - { - if (!isIndex) - { - indexInterval = input->readInt(); - formatM1SkipInterval = input->readInt(); - } - // switch off skipTo optimization for file format prior to 1.4rc2 - skipInterval = INT_MAX; - } - else - { + + size = input->readLong(); // read the size + + if (format == -1) { + if (!isIndex) { indexInterval = input->readInt(); - skipInterval = input->readInt(); - if (format <= TermInfosWriter::FORMAT) - { - // this new format introduces multi-level skipping - maxSkipLevels = input->readInt(); - } + formatM1SkipInterval = input->readInt(); + } + // switch off skipTo optimization for file format prior to 1.4rc2 + skipInterval = INT_MAX; + } else { + indexInterval = input->readInt(); + skipInterval = input->readInt(); + if (format <= TermInfosWriter::FORMAT) { + // this new format introduces multi-level skipping + maxSkipLevels = input->readInt(); } - - BOOST_ASSERT(indexInterval > 0); // must not be negative - BOOST_ASSERT(skipInterval > 0); // must not be negative - } - if (format > TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) - { - termBuffer->setPreUTF8Strings(); - scanBuffer->setPreUTF8Strings(); - prevBuffer->setPreUTF8Strings(); } - } - SegmentTermEnum::~SegmentTermEnum() - { + BOOST_ASSERT(indexInterval > 0); // must not be negative + BOOST_ASSERT(skipInterval > 0); // must not be negative } - - LuceneObjectPtr SegmentTermEnum::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - SegmentTermEnumPtr cloneEnum(boost::dynamic_pointer_cast(TermEnum::clone(clone))); - cloneEnum->format = format; - cloneEnum->isIndex = isIndex; - cloneEnum->formatM1SkipInterval = formatM1SkipInterval; - cloneEnum->fieldInfos = fieldInfos; - cloneEnum->size = size; - cloneEnum->position = position; - cloneEnum->indexPointer = indexPointer; - cloneEnum->indexInterval = indexInterval; - cloneEnum->skipInterval = skipInterval; - cloneEnum->maxSkipLevels = maxSkipLevels; - - cloneEnum->input = boost::dynamic_pointer_cast(input->clone()); - cloneEnum->_termInfo = newLucene(_termInfo); - - cloneEnum->termBuffer = boost::dynamic_pointer_cast(termBuffer->clone()); - cloneEnum->prevBuffer = boost::dynamic_pointer_cast(prevBuffer->clone()); - cloneEnum->scanBuffer = newLucene(); - - return cloneEnum; + if (format > TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) { + termBuffer->setPreUTF8Strings(); + scanBuffer->setPreUTF8Strings(); + prevBuffer->setPreUTF8Strings(); } +} - void SegmentTermEnum::seek(int64_t pointer, int64_t p, const TermPtr& t, const TermInfoPtr& ti) - { - input->seek(pointer); - position = p; - termBuffer->set(t); - prevBuffer->reset(); - _termInfo->set(ti); - } +SegmentTermEnum::~SegmentTermEnum() { +} - bool SegmentTermEnum::next() - { - if (position++ >= size - 1) - { - prevBuffer->set(termBuffer); - termBuffer->reset(); - return false; - } +LuceneObjectPtr SegmentTermEnum::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + SegmentTermEnumPtr cloneEnum(boost::dynamic_pointer_cast(TermEnum::clone(clone))); + cloneEnum->format = format; + cloneEnum->isIndex = isIndex; + cloneEnum->formatM1SkipInterval = formatM1SkipInterval; + cloneEnum->fieldInfos = fieldInfos; + cloneEnum->size = size; + cloneEnum->position = position; + cloneEnum->indexPointer = indexPointer; + cloneEnum->indexInterval = indexInterval; + cloneEnum->skipInterval = skipInterval; + cloneEnum->maxSkipLevels = maxSkipLevels; + + cloneEnum->input = boost::dynamic_pointer_cast(input->clone()); + cloneEnum->_termInfo = newLucene(_termInfo); + + cloneEnum->termBuffer = boost::dynamic_pointer_cast(termBuffer->clone()); + cloneEnum->prevBuffer = boost::dynamic_pointer_cast(prevBuffer->clone()); + cloneEnum->scanBuffer = newLucene(); + + return cloneEnum; +} +void SegmentTermEnum::seek(int64_t pointer, int64_t p, const TermPtr& t, const TermInfoPtr& ti) { + input->seek(pointer); + position = p; + termBuffer->set(t); + prevBuffer->reset(); + _termInfo->set(ti); +} + +bool SegmentTermEnum::next() { + if (position++ >= size - 1) { prevBuffer->set(termBuffer); - termBuffer->read(input, fieldInfos); - - _termInfo->docFreq = input->readVInt(); // read doc freq - _termInfo->freqPointer += input->readVLong(); // read freq pointer - _termInfo->proxPointer += input->readVLong(); // read prox pointer - - if (format == -1) - { - // just read skipOffset in order to increment file pointer; value is never used - // since skipTo is switched off - if (!isIndex && _termInfo->docFreq > formatM1SkipInterval) - _termInfo->skipOffset = input->readVInt(); - } - else if (_termInfo->docFreq >= skipInterval) - _termInfo->skipOffset = input->readVInt(); + termBuffer->reset(); + return false; + } - if (isIndex) - indexPointer += input->readVLong(); // read index pointer + prevBuffer->set(termBuffer); + termBuffer->read(input, fieldInfos); - return true; - } + _termInfo->docFreq = input->readVInt(); // read doc freq + _termInfo->freqPointer += input->readVLong(); // read freq pointer + _termInfo->proxPointer += input->readVLong(); // read prox pointer - int32_t SegmentTermEnum::scanTo(const TermPtr& term) - { - scanBuffer->set(term); - int32_t count = 0; - while (scanBuffer->compareTo(termBuffer) > 0 && next()) - ++count; - return count; + if (format == -1) { + // just read skipOffset in order to increment file pointer; value is never used + // since skipTo is switched off + if (!isIndex && _termInfo->docFreq > formatM1SkipInterval) { + _termInfo->skipOffset = input->readVInt(); + } + } else if (_termInfo->docFreq >= skipInterval) { + _termInfo->skipOffset = input->readVInt(); } - TermPtr SegmentTermEnum::term() - { - return termBuffer->toTerm(); + if (isIndex) { + indexPointer += input->readVLong(); // read index pointer } - TermPtr SegmentTermEnum::prev() - { - return prevBuffer->toTerm(); - } + return true; +} - TermInfoPtr SegmentTermEnum::termInfo() - { - return newLucene(_termInfo); +int32_t SegmentTermEnum::scanTo(const TermPtr& term) { + scanBuffer->set(term); + int32_t count = 0; + while (scanBuffer->compareTo(termBuffer) > 0 && next()) { + ++count; } + return count; +} - void SegmentTermEnum::termInfo(const TermInfoPtr& ti) - { - ti->set(_termInfo); - } +TermPtr SegmentTermEnum::term() { + return termBuffer->toTerm(); +} - int32_t SegmentTermEnum::docFreq() - { - return _termInfo->docFreq; - } +TermPtr SegmentTermEnum::prev() { + return prevBuffer->toTerm(); +} - int64_t SegmentTermEnum::freqPointer() - { - return _termInfo->freqPointer; - } +TermInfoPtr SegmentTermEnum::termInfo() { + return newLucene(_termInfo); +} - int64_t SegmentTermEnum::proxPointer() - { - return _termInfo->proxPointer; - } +void SegmentTermEnum::termInfo(const TermInfoPtr& ti) { + ti->set(_termInfo); +} + +int32_t SegmentTermEnum::docFreq() { + return _termInfo->docFreq; +} + +int64_t SegmentTermEnum::freqPointer() { + return _termInfo->freqPointer; +} + +int64_t SegmentTermEnum::proxPointer() { + return _termInfo->proxPointer; +} + +void SegmentTermEnum::close() { + input->close(); +} - void SegmentTermEnum::close() - { - input->close(); - } } diff --git a/src/core/index/SegmentTermPositionVector.cpp b/src/core/index/SegmentTermPositionVector.cpp index c874109d..f6e57d8b 100644 --- a/src/core/index/SegmentTermPositionVector.cpp +++ b/src/core/index/SegmentTermPositionVector.cpp @@ -8,46 +8,47 @@ #include "SegmentTermPositionVector.h" #include "TermVectorOffsetInfo.h" -namespace Lucene -{ - SegmentTermPositionVector::SegmentTermPositionVector(const String& field, Collection terms, - Collection termFreqs, Collection< Collection > positions, - Collection< Collection > offsets) : - SegmentTermVector(field, terms, termFreqs) - { - this->offsets = offsets; - this->positions = positions; - } +namespace Lucene { - SegmentTermPositionVector::~SegmentTermPositionVector() - { - } +SegmentTermPositionVector::SegmentTermPositionVector(const String& field, Collection terms, + Collection termFreqs, Collection< Collection > positions, + Collection< Collection > offsets) : + SegmentTermVector(field, terms, termFreqs) { + this->offsets = offsets; + this->positions = positions; +} - const Collection SegmentTermPositionVector::EMPTY_TERM_POS() - { - static Collection _EMPTY_TERM_POS; - if (!_EMPTY_TERM_POS) - _EMPTY_TERM_POS = Collection::newInstance(); - return _EMPTY_TERM_POS; +SegmentTermPositionVector::~SegmentTermPositionVector() { +} + +const Collection SegmentTermPositionVector::EMPTY_TERM_POS() { + static Collection _EMPTY_TERM_POS; + if (!_EMPTY_TERM_POS) { + _EMPTY_TERM_POS = Collection::newInstance(); } + return _EMPTY_TERM_POS; +} - Collection SegmentTermPositionVector::getOffsets(int32_t index) - { - Collection result(TermVectorOffsetInfo::EMPTY_OFFSET_INFO()); - if (!offsets) - return Collection(); - if (index >=0 && index < offsets.size()) - result = offsets[index]; - return result; +Collection SegmentTermPositionVector::getOffsets(int32_t index) { + Collection result(TermVectorOffsetInfo::EMPTY_OFFSET_INFO()); + if (!offsets) { + return Collection(); } + if (index >=0 && index < offsets.size()) { + result = offsets[index]; + } + return result; +} - Collection SegmentTermPositionVector::getTermPositions(int32_t index) - { - Collection result(EMPTY_TERM_POS()); - if (!positions) - return Collection(); - if (index >= 0 && index < positions.size()) - result = positions[index]; - return result; +Collection SegmentTermPositionVector::getTermPositions(int32_t index) { + Collection result(EMPTY_TERM_POS()); + if (!positions) { + return Collection(); + } + if (index >= 0 && index < positions.size()) { + result = positions[index]; } + return result; +} + } diff --git a/src/core/index/SegmentTermPositions.cpp b/src/core/index/SegmentTermPositions.cpp index 5f2f6e9b..8d1296c8 100644 --- a/src/core/index/SegmentTermPositions.cpp +++ b/src/core/index/SegmentTermPositions.cpp @@ -12,178 +12,158 @@ #include "IndexInput.h" #include "MiscUtils.h" -namespace Lucene -{ - SegmentTermPositions::SegmentTermPositions(const SegmentReaderPtr& parent) : SegmentTermDocs(parent) - { - this->proxCount = 0; - this->position = 0; - this->payloadLength = 0; - this->needToLoadPayload = false; - this->lazySkipPointer = -1; - this->lazySkipProxCount = 0; - } +namespace Lucene { + +SegmentTermPositions::SegmentTermPositions(const SegmentReaderPtr& parent) : SegmentTermDocs(parent) { + this->proxCount = 0; + this->position = 0; + this->payloadLength = 0; + this->needToLoadPayload = false; + this->lazySkipPointer = -1; + this->lazySkipProxCount = 0; +} - SegmentTermPositions::~SegmentTermPositions() - { - } +SegmentTermPositions::~SegmentTermPositions() { +} - void SegmentTermPositions::seek(const TermInfoPtr& ti, const TermPtr& term) - { - SegmentTermDocs::seek(ti, term); - if (ti) - lazySkipPointer = ti->proxPointer; - lazySkipProxCount = 0; - proxCount = 0; - payloadLength = 0; - needToLoadPayload = false; +void SegmentTermPositions::seek(const TermInfoPtr& ti, const TermPtr& term) { + SegmentTermDocs::seek(ti, term); + if (ti) { + lazySkipPointer = ti->proxPointer; } + lazySkipProxCount = 0; + proxCount = 0; + payloadLength = 0; + needToLoadPayload = false; +} - void SegmentTermPositions::close() - { - SegmentTermDocs::close(); - if (proxStream) - proxStream->close(); +void SegmentTermPositions::close() { + SegmentTermDocs::close(); + if (proxStream) { + proxStream->close(); } +} - int32_t SegmentTermPositions::nextPosition() - { - if (currentFieldOmitTermFreqAndPositions) - { - // This field does not store term freq, positions, payloads - return 0; - } - - // perform lazy skips if necessary - lazySkip(); - --proxCount; - position += readDeltaPosition(); - return position; +int32_t SegmentTermPositions::nextPosition() { + if (currentFieldOmitTermFreqAndPositions) { + // This field does not store term freq, positions, payloads + return 0; } - int32_t SegmentTermPositions::readDeltaPosition() - { - int32_t delta = proxStream->readVInt(); - if (currentFieldStoresPayloads) - { - // if the current field stores payloads then the position delta is shifted one bit to the left. - // if the LSB is set, then we have to read the current payload length - if ((delta & 1) != 0) - payloadLength = proxStream->readVInt(); - delta = MiscUtils::unsignedShift(delta, 1); - needToLoadPayload = true; + // perform lazy skips if necessary + lazySkip(); + --proxCount; + position += readDeltaPosition(); + return position; +} + +int32_t SegmentTermPositions::readDeltaPosition() { + int32_t delta = proxStream->readVInt(); + if (currentFieldStoresPayloads) { + // if the current field stores payloads then the position delta is shifted one bit to the left. + // if the LSB is set, then we have to read the current payload length + if ((delta & 1) != 0) { + payloadLength = proxStream->readVInt(); } - return delta; + delta = MiscUtils::unsignedShift(delta, 1); + needToLoadPayload = true; } + return delta; +} - void SegmentTermPositions::skippingDoc() - { - // we remember to skip a document lazily - lazySkipProxCount += _freq; - } +void SegmentTermPositions::skippingDoc() { + // we remember to skip a document lazily + lazySkipProxCount += _freq; +} - bool SegmentTermPositions::next() - { - // we remember to skip the remaining positions of the current document lazily - lazySkipProxCount += proxCount; +bool SegmentTermPositions::next() { + // we remember to skip the remaining positions of the current document lazily + lazySkipProxCount += proxCount; - if (SegmentTermDocs::next()) - { - proxCount = _freq; // note frequency - position = 0; // reset position - return true; - } - return false; + if (SegmentTermDocs::next()) { + proxCount = _freq; // note frequency + position = 0; // reset position + return true; } + return false; +} - int32_t SegmentTermPositions::read(Collection docs, Collection freqs) - { - boost::throw_exception(UnsupportedOperationException(L"TermPositions does not support processing multiple documents in one call. Use TermDocs instead.")); - return 0; - } +int32_t SegmentTermPositions::read(Collection docs, Collection freqs) { + boost::throw_exception(UnsupportedOperationException(L"TermPositions does not support processing multiple documents in one call. Use TermDocs instead.")); + return 0; +} - void SegmentTermPositions::skipProx(int64_t proxPointer, int32_t payloadLength) - { - // we save the pointer, we might have to skip there lazily - lazySkipPointer = proxPointer; - lazySkipProxCount = 0; - proxCount = 0; - this->payloadLength = payloadLength; - needToLoadPayload = false; - } +void SegmentTermPositions::skipProx(int64_t proxPointer, int32_t payloadLength) { + // we save the pointer, we might have to skip there lazily + lazySkipPointer = proxPointer; + lazySkipProxCount = 0; + proxCount = 0; + this->payloadLength = payloadLength; + needToLoadPayload = false; +} - void SegmentTermPositions::skipPositions(int32_t n) - { - BOOST_ASSERT(!currentFieldOmitTermFreqAndPositions); - for (int32_t i = n; i > 0; --i) // skip unread positions - { - readDeltaPosition(); - skipPayload(); - } +void SegmentTermPositions::skipPositions(int32_t n) { + BOOST_ASSERT(!currentFieldOmitTermFreqAndPositions); + for (int32_t i = n; i > 0; --i) { // skip unread positions + readDeltaPosition(); + skipPayload(); } +} - void SegmentTermPositions::skipPayload() - { - if (needToLoadPayload && payloadLength > 0) - proxStream->seek(proxStream->getFilePointer() + payloadLength); - needToLoadPayload = false; +void SegmentTermPositions::skipPayload() { + if (needToLoadPayload && payloadLength > 0) { + proxStream->seek(proxStream->getFilePointer() + payloadLength); } + needToLoadPayload = false; +} - void SegmentTermPositions::lazySkip() - { - if (!proxStream) - { - // clone lazily - proxStream = boost::dynamic_pointer_cast(SegmentReaderPtr(_parent)->core->proxStream->clone()); - } - - // we might have to skip the current payload if it was not read yet - skipPayload(); +void SegmentTermPositions::lazySkip() { + if (!proxStream) { + // clone lazily + proxStream = boost::dynamic_pointer_cast(SegmentReaderPtr(_parent)->core->proxStream->clone()); + } - if (lazySkipPointer != -1) - { - proxStream->seek(lazySkipPointer); - lazySkipPointer = -1; - } + // we might have to skip the current payload if it was not read yet + skipPayload(); - if (lazySkipProxCount != 0) - { - skipPositions(lazySkipProxCount); - lazySkipProxCount = 0; - } + if (lazySkipPointer != -1) { + proxStream->seek(lazySkipPointer); + lazySkipPointer = -1; } - int32_t SegmentTermPositions::getPayloadLength() - { - return payloadLength; + if (lazySkipProxCount != 0) { + skipPositions(lazySkipProxCount); + lazySkipProxCount = 0; } +} - ByteArray SegmentTermPositions::getPayload(ByteArray data, int32_t offset) - { - if (!needToLoadPayload) - boost::throw_exception(IOException(L"Either no payload exists at this term position or an attempt was made to load it more than once.")); - - // read payloads lazily - ByteArray retArray; - int32_t retOffset = 0; - if (!data || data.size() - offset < payloadLength) - { - // the array is too small to store the payload data, so we allocate a new one - retArray = ByteArray::newInstance(payloadLength); - retOffset = 0; - } - else - { - retArray = data; - retOffset = offset; - } - proxStream->readBytes(retArray.get(), retOffset, payloadLength); - needToLoadPayload = false; - return retArray; - } +int32_t SegmentTermPositions::getPayloadLength() { + return payloadLength; +} + +ByteArray SegmentTermPositions::getPayload(ByteArray data, int32_t offset) { + if (!needToLoadPayload) { + boost::throw_exception(IOException(L"Either no payload exists at this term position or an attempt was made to load it more than once.")); + } + + // read payloads lazily + ByteArray retArray; + int32_t retOffset = 0; + if (!data || data.size() - offset < payloadLength) { + // the array is too small to store the payload data, so we allocate a new one + retArray = ByteArray::newInstance(payloadLength); + retOffset = 0; + } else { + retArray = data; + retOffset = offset; + } + proxStream->readBytes(retArray.get(), retOffset, payloadLength); + needToLoadPayload = false; + return retArray; +} + +bool SegmentTermPositions::isPayloadAvailable() { + return (needToLoadPayload && payloadLength > 0); +} - bool SegmentTermPositions::isPayloadAvailable() - { - return (needToLoadPayload && payloadLength > 0); - } } diff --git a/src/core/index/SegmentTermVector.cpp b/src/core/index/SegmentTermVector.cpp index 09046986..959e3e8b 100644 --- a/src/core/index/SegmentTermVector.cpp +++ b/src/core/index/SegmentTermVector.cpp @@ -7,69 +7,62 @@ #include "LuceneInc.h" #include "SegmentTermVector.h" -namespace Lucene -{ - SegmentTermVector::SegmentTermVector(const String& field, Collection terms, Collection termFreqs) - { - this->field = field; - this->terms = terms; - this->termFreqs = termFreqs; - } +namespace Lucene { - SegmentTermVector::~SegmentTermVector() - { - } +SegmentTermVector::SegmentTermVector(const String& field, Collection terms, Collection termFreqs) { + this->field = field; + this->terms = terms; + this->termFreqs = termFreqs; +} - String SegmentTermVector::getField() - { - return field; - } +SegmentTermVector::~SegmentTermVector() { +} - String SegmentTermVector::toString() - { - StringStream segTermVector; - segTermVector << L"{" << field; - if (terms) - { - for (int32_t i = 0; i < terms.size(); ++i) - { - if (i > 0) - segTermVector << L", "; - segTermVector << terms[i] << L"/" << termFreqs[i]; +String SegmentTermVector::getField() { + return field; +} + +String SegmentTermVector::toString() { + StringStream segTermVector; + segTermVector << L"{" << field; + if (terms) { + for (int32_t i = 0; i < terms.size(); ++i) { + if (i > 0) { + segTermVector << L", "; } + segTermVector << terms[i] << L"/" << termFreqs[i]; } - segTermVector << L"}"; - return segTermVector.str(); } + segTermVector << L"}"; + return segTermVector.str(); +} - int32_t SegmentTermVector::size() - { - return terms ? terms.size() : 0; - } +int32_t SegmentTermVector::size() { + return terms ? terms.size() : 0; +} - Collection SegmentTermVector::getTerms() - { - return terms; - } +Collection SegmentTermVector::getTerms() { + return terms; +} - Collection SegmentTermVector::getTermFrequencies() - { - return termFreqs; - } +Collection SegmentTermVector::getTermFrequencies() { + return termFreqs; +} - int32_t SegmentTermVector::indexOf(const String& term) - { - if (!terms) - return -1; - Collection::iterator search = std::lower_bound(terms.begin(), terms.end(), term); - return (search == terms.end() || term < *search) ? -1 : std::distance(terms.begin(), search); +int32_t SegmentTermVector::indexOf(const String& term) { + if (!terms) { + return -1; } + Collection::iterator search = std::lower_bound(terms.begin(), terms.end(), term); + return (search == terms.end() || term < *search) ? -1 : std::distance(terms.begin(), search); +} - Collection SegmentTermVector::indexesOf(Collection termNumbers, int32_t start, int32_t length) - { - Collection res(Collection::newInstance(length)); - for (int32_t i = 0; i < length; ++i) - res[i] = indexOf(termNumbers[start + i]); - return res; +Collection SegmentTermVector::indexesOf(Collection termNumbers, int32_t start, int32_t length) { + Collection res(Collection::newInstance(length)); + for (int32_t i = 0; i < length; ++i) { + res[i] = indexOf(termNumbers[start + i]); } + return res; +} + } diff --git a/src/core/index/SegmentWriteState.cpp b/src/core/index/SegmentWriteState.cpp index 4158e12c..eb21811f 100644 --- a/src/core/index/SegmentWriteState.cpp +++ b/src/core/index/SegmentWriteState.cpp @@ -7,28 +7,26 @@ #include "LuceneInc.h" #include "SegmentWriteState.h" -namespace Lucene -{ - SegmentWriteState::SegmentWriteState(const DocumentsWriterPtr& docWriter, const DirectoryPtr& directory, const String& segmentName, - const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, - int32_t termIndexInterval) - { - this->_docWriter = docWriter; - this->directory = directory; - this->segmentName = segmentName; - this->docStoreSegmentName = docStoreSegmentName; - this->numDocs = numDocs; - this->numDocsInStore = numDocsInStore; - this->termIndexInterval = termIndexInterval; - this->flushedFiles = HashSet::newInstance(); - } +namespace Lucene { - SegmentWriteState::~SegmentWriteState() - { - } +SegmentWriteState::SegmentWriteState(const DocumentsWriterPtr& docWriter, const DirectoryPtr& directory, const String& segmentName, + const String& docStoreSegmentName, int32_t numDocs, int32_t numDocsInStore, + int32_t termIndexInterval) { + this->_docWriter = docWriter; + this->directory = directory; + this->segmentName = segmentName; + this->docStoreSegmentName = docStoreSegmentName; + this->numDocs = numDocs; + this->numDocsInStore = numDocsInStore; + this->termIndexInterval = termIndexInterval; + this->flushedFiles = HashSet::newInstance(); +} + +SegmentWriteState::~SegmentWriteState() { +} + +String SegmentWriteState::segmentFileName(const String& ext) { + return segmentName + L"." + ext; +} - String SegmentWriteState::segmentFileName(const String& ext) - { - return segmentName + L"." + ext; - } } diff --git a/src/core/index/SerialMergeScheduler.cpp b/src/core/index/SerialMergeScheduler.cpp index 758b0c8b..b3cf7c0d 100644 --- a/src/core/index/SerialMergeScheduler.cpp +++ b/src/core/index/SerialMergeScheduler.cpp @@ -8,25 +8,23 @@ #include "SerialMergeScheduler.h" #include "IndexWriter.h" -namespace Lucene -{ - SerialMergeScheduler::~SerialMergeScheduler() - { - } +namespace Lucene { + +SerialMergeScheduler::~SerialMergeScheduler() { +} - void SerialMergeScheduler::merge(const IndexWriterPtr& writer) - { - SyncLock syncLock(this); - while (true) - { - OneMergePtr merge(writer->getNextMerge()); - if (!merge) - break; - writer->merge(merge); +void SerialMergeScheduler::merge(const IndexWriterPtr& writer) { + SyncLock syncLock(this); + while (true) { + OneMergePtr merge(writer->getNextMerge()); + if (!merge) { + break; } + writer->merge(merge); } +} + +void SerialMergeScheduler::close() { +} - void SerialMergeScheduler::close() - { - } } diff --git a/src/core/index/SnapshotDeletionPolicy.cpp b/src/core/index/SnapshotDeletionPolicy.cpp index e1e8d5c2..7dee00db 100644 --- a/src/core/index/SnapshotDeletionPolicy.cpp +++ b/src/core/index/SnapshotDeletionPolicy.cpp @@ -8,121 +8,108 @@ #include "SnapshotDeletionPolicy.h" #include "_SnapshotDeletionPolicy.h" -namespace Lucene -{ - SnapshotDeletionPolicy::SnapshotDeletionPolicy(const IndexDeletionPolicyPtr& primary) - { - this->primary = primary; - } +namespace Lucene { - SnapshotDeletionPolicy::~SnapshotDeletionPolicy() - { - } +SnapshotDeletionPolicy::SnapshotDeletionPolicy(const IndexDeletionPolicyPtr& primary) { + this->primary = primary; +} - void SnapshotDeletionPolicy::onInit(Collection commits) - { - SyncLock syncLock(this); - primary->onInit(wrapCommits(commits)); - lastCommit = commits[commits.size() - 1]; - } +SnapshotDeletionPolicy::~SnapshotDeletionPolicy() { +} - void SnapshotDeletionPolicy::onCommit(Collection commits) - { - SyncLock syncLock(this); - primary->onCommit(wrapCommits(commits)); - lastCommit = commits[commits.size() - 1]; - } +void SnapshotDeletionPolicy::onInit(Collection commits) { + SyncLock syncLock(this); + primary->onInit(wrapCommits(commits)); + lastCommit = commits[commits.size() - 1]; +} - IndexCommitPtr SnapshotDeletionPolicy::snapshot() - { - SyncLock syncLock(this); - if (!lastCommit) - boost::throw_exception(IllegalStateException(L"no index commits to snapshot")); - if (_snapshot.empty()) - _snapshot = lastCommit->getSegmentsFileName(); - else - boost::throw_exception(IllegalStateException(L"snapshot is already set; please call release() first")); - return lastCommit; - } +void SnapshotDeletionPolicy::onCommit(Collection commits) { + SyncLock syncLock(this); + primary->onCommit(wrapCommits(commits)); + lastCommit = commits[commits.size() - 1]; +} - void SnapshotDeletionPolicy::release() - { - SyncLock syncLock(this); - if (!_snapshot.empty()) - _snapshot.clear(); - else - boost::throw_exception(IllegalStateException(L"snapshot was not set; please call snapshot() first")); +IndexCommitPtr SnapshotDeletionPolicy::snapshot() { + SyncLock syncLock(this); + if (!lastCommit) { + boost::throw_exception(IllegalStateException(L"no index commits to snapshot")); } - - Collection SnapshotDeletionPolicy::wrapCommits(Collection commits) - { - Collection myCommits(Collection::newInstance()); - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - myCommits.add(newLucene(shared_from_this(), *commit)); - return myCommits; + if (_snapshot.empty()) { + _snapshot = lastCommit->getSegmentsFileName(); + } else { + boost::throw_exception(IllegalStateException(L"snapshot is already set; please call release() first")); } + return lastCommit; +} - MyCommitPoint::MyCommitPoint(const SnapshotDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& cp) - { - this->_deletionPolicy = deletionPolicy; - this->cp = cp; +void SnapshotDeletionPolicy::release() { + SyncLock syncLock(this); + if (!_snapshot.empty()) { + _snapshot.clear(); + } else { + boost::throw_exception(IllegalStateException(L"snapshot was not set; please call snapshot() first")); } +} - MyCommitPoint::~MyCommitPoint() - { +Collection SnapshotDeletionPolicy::wrapCommits(Collection commits) { + Collection myCommits(Collection::newInstance()); + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { + myCommits.add(newLucene(shared_from_this(), *commit)); } + return myCommits; +} - String MyCommitPoint::toString() - { - return L"SnapshotDeletionPolicy.SnapshotCommitPoint(" + cp->toString() + L")"; - } +MyCommitPoint::MyCommitPoint(const SnapshotDeletionPolicyPtr& deletionPolicy, const IndexCommitPtr& cp) { + this->_deletionPolicy = deletionPolicy; + this->cp = cp; +} - String MyCommitPoint::getSegmentsFileName() - { - return cp->getSegmentsFileName(); - } +MyCommitPoint::~MyCommitPoint() { +} - HashSet MyCommitPoint::getFileNames() - { - return cp->getFileNames(); - } +String MyCommitPoint::toString() { + return L"SnapshotDeletionPolicy.SnapshotCommitPoint(" + cp->toString() + L")"; +} - DirectoryPtr MyCommitPoint::getDirectory() - { - return cp->getDirectory(); - } +String MyCommitPoint::getSegmentsFileName() { + return cp->getSegmentsFileName(); +} - void MyCommitPoint::deleteCommit() - { - SnapshotDeletionPolicyPtr deletionPolicy(_deletionPolicy); - SyncLock policyLock(deletionPolicy); - // Suppress the delete request if this commit point is our current snapshot. - if (deletionPolicy->_snapshot.empty() || deletionPolicy->_snapshot != getSegmentsFileName()) - cp->deleteCommit(); - } +HashSet MyCommitPoint::getFileNames() { + return cp->getFileNames(); +} - bool MyCommitPoint::isDeleted() - { - return cp->isDeleted(); - } +DirectoryPtr MyCommitPoint::getDirectory() { + return cp->getDirectory(); +} - int64_t MyCommitPoint::getVersion() - { - return cp->getVersion(); +void MyCommitPoint::deleteCommit() { + SnapshotDeletionPolicyPtr deletionPolicy(_deletionPolicy); + SyncLock policyLock(deletionPolicy); + // Suppress the delete request if this commit point is our current snapshot. + if (deletionPolicy->_snapshot.empty() || deletionPolicy->_snapshot != getSegmentsFileName()) { + cp->deleteCommit(); } +} - int64_t MyCommitPoint::getGeneration() - { - return cp->getGeneration(); - } +bool MyCommitPoint::isDeleted() { + return cp->isDeleted(); +} - MapStringString MyCommitPoint::getUserData() - { - return cp->getUserData(); - } +int64_t MyCommitPoint::getVersion() { + return cp->getVersion(); +} + +int64_t MyCommitPoint::getGeneration() { + return cp->getGeneration(); +} + +MapStringString MyCommitPoint::getUserData() { + return cp->getUserData(); +} + +bool MyCommitPoint::isOptimized() { + return cp->isOptimized(); +} - bool MyCommitPoint::isOptimized() - { - return cp->isOptimized(); - } } diff --git a/src/core/index/SortedTermVectorMapper.cpp b/src/core/index/SortedTermVectorMapper.cpp index 3e291b55..a573b448 100644 --- a/src/core/index/SortedTermVectorMapper.cpp +++ b/src/core/index/SortedTermVectorMapper.cpp @@ -8,87 +8,76 @@ #include "SortedTermVectorMapper.h" #include "TermVectorEntry.h" -namespace Lucene -{ - const wchar_t* SortedTermVectorMapper::ALL = L"_ALL_"; +namespace Lucene { - SortedTermVectorMapper::SortedTermVectorMapper(TermVectorEntryComparator comparator) : TermVectorMapper(false, false) - { - this->storeOffsets = false; - this->storePositions = false; - this->comparator = comparator; - this->currentSet = Collection::newInstance(); - this->termToTVE = MapStringTermVectorEntry::newInstance(); - } +const wchar_t* SortedTermVectorMapper::ALL = L"_ALL_"; - SortedTermVectorMapper::SortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator) - : TermVectorMapper(ignoringPositions, ignoringPositions) - { - this->storeOffsets = false; - this->storePositions = false; - this->comparator = comparator; - this->currentSet = Collection::newInstance(); - this->termToTVE = MapStringTermVectorEntry::newInstance(); - } +SortedTermVectorMapper::SortedTermVectorMapper(TermVectorEntryComparator comparator) : TermVectorMapper(false, false) { + this->storeOffsets = false; + this->storePositions = false; + this->comparator = comparator; + this->currentSet = Collection::newInstance(); + this->termToTVE = MapStringTermVectorEntry::newInstance(); +} - SortedTermVectorMapper::~SortedTermVectorMapper() - { - } +SortedTermVectorMapper::SortedTermVectorMapper(bool ignoringPositions, bool ignoringOffsets, TermVectorEntryComparator comparator) + : TermVectorMapper(ignoringPositions, ignoringPositions) { + this->storeOffsets = false; + this->storePositions = false; + this->comparator = comparator; + this->currentSet = Collection::newInstance(); + this->termToTVE = MapStringTermVectorEntry::newInstance(); +} + +SortedTermVectorMapper::~SortedTermVectorMapper() { +} - void SortedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) - { - // We need to combine any previous mentions of the term - TermVectorEntryPtr entry(termToTVE.get(term)); - if (!entry) - { - entry = newLucene(ALL, term, frequency, storeOffsets ? offsets : Collection(), storePositions ? positions : Collection()); - termToTVE.put(term, entry); +void SortedTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { + // We need to combine any previous mentions of the term + TermVectorEntryPtr entry(termToTVE.get(term)); + if (!entry) { + entry = newLucene(ALL, term, frequency, storeOffsets ? offsets : Collection(), storePositions ? positions : Collection()); + termToTVE.put(term, entry); - if (!currentSet.contains_if(luceneEqualTo(entry))) - currentSet.insert(std::upper_bound(currentSet.begin(), currentSet.end(), entry, comparator), entry); + if (!currentSet.contains_if(luceneEqualTo(entry))) { + currentSet.insert(std::upper_bound(currentSet.begin(), currentSet.end(), entry, comparator), entry); } - else - { - entry->setFrequency(entry->getFrequency() + frequency); - if (storeOffsets) - { - Collection existingOffsets(entry->getOffsets()); - // A few diff. cases here: offsets is null, existing offsets is null, both are null, same for positions - if (existingOffsets && offsets && !offsets.empty()) - { - // copy over the existing offsets - Collection newOffsets(Collection::newInstance(existingOffsets.begin(), existingOffsets.end())); - newOffsets.addAll(offsets.begin(), offsets.end()); - entry->setOffsets(newOffsets); - } - else if (!existingOffsets && offsets && !offsets.empty()) - entry->setOffsets(offsets); - // else leave it alone + } else { + entry->setFrequency(entry->getFrequency() + frequency); + if (storeOffsets) { + Collection existingOffsets(entry->getOffsets()); + // A few diff. cases here: offsets is null, existing offsets is null, both are null, same for positions + if (existingOffsets && offsets && !offsets.empty()) { + // copy over the existing offsets + Collection newOffsets(Collection::newInstance(existingOffsets.begin(), existingOffsets.end())); + newOffsets.addAll(offsets.begin(), offsets.end()); + entry->setOffsets(newOffsets); + } else if (!existingOffsets && offsets && !offsets.empty()) { + entry->setOffsets(offsets); } - if (storePositions) - { - Collection existingPositions(entry->getPositions()); - if (existingPositions && positions && !positions.empty()) - { - Collection newPositions(existingPositions); - newPositions.addAll(positions.begin(), positions.end()); - entry->setPositions(newPositions); - } - else if (!existingPositions && positions && !positions.empty()) - entry->setPositions(positions); - // else leave it alone + // else leave it alone + } + if (storePositions) { + Collection existingPositions(entry->getPositions()); + if (existingPositions && positions && !positions.empty()) { + Collection newPositions(existingPositions); + newPositions.addAll(positions.begin(), positions.end()); + entry->setPositions(newPositions); + } else if (!existingPositions && positions && !positions.empty()) { + entry->setPositions(positions); } + // else leave it alone } } +} - void SortedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) - { - this->storeOffsets = storeOffsets; - this->storePositions = storePositions; - } +void SortedTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { + this->storeOffsets = storeOffsets; + this->storePositions = storePositions; +} + +Collection SortedTermVectorMapper::getTermVectorEntrySet() { + return currentSet; +} - Collection SortedTermVectorMapper::getTermVectorEntrySet() - { - return currentSet; - } } diff --git a/src/core/index/StoredFieldsWriter.cpp b/src/core/index/StoredFieldsWriter.cpp index b1e8eb9d..06712ecf 100644 --- a/src/core/index/StoredFieldsWriter.cpp +++ b/src/core/index/StoredFieldsWriter.cpp @@ -16,210 +16,181 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - StoredFieldsWriter::StoredFieldsWriter(const DocumentsWriterPtr& docWriter, const FieldInfosPtr& fieldInfos) - { - lastDocID = 0; - docFreeList = Collection::newInstance(1); - freeCount = 0; - allocCount = 0; +namespace Lucene { - this->_docWriter = docWriter; - this->fieldInfos = fieldInfos; - } +StoredFieldsWriter::StoredFieldsWriter(const DocumentsWriterPtr& docWriter, const FieldInfosPtr& fieldInfos) { + lastDocID = 0; + docFreeList = Collection::newInstance(1); + freeCount = 0; + allocCount = 0; + + this->_docWriter = docWriter; + this->fieldInfos = fieldInfos; +} - StoredFieldsWriter::~StoredFieldsWriter() - { +StoredFieldsWriter::~StoredFieldsWriter() { +} + +StoredFieldsWriterPerThreadPtr StoredFieldsWriter::addThread(const DocStatePtr& docState) { + return newLucene(docState, shared_from_this()); +} + +void StoredFieldsWriter::flush(const SegmentWriteStatePtr& state) { + SyncLock syncLock(this); + if (state->numDocsInStore > 0) { + // It's possible that all documents seen in this segment hit non-aborting exceptions, + // in which case we will not have yet init'd the FieldsWriter + initFieldsWriter(); + + // Fill fdx file to include any final docs that we skipped because they hit non-aborting + // exceptions + fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); } - StoredFieldsWriterPerThreadPtr StoredFieldsWriter::addThread(const DocStatePtr& docState) - { - return newLucene(docState, shared_from_this()); + if (fieldsWriter) { + fieldsWriter->flush(); } +} - void StoredFieldsWriter::flush(const SegmentWriteStatePtr& state) - { - SyncLock syncLock(this); - if (state->numDocsInStore > 0) - { - // It's possible that all documents seen in this segment hit non-aborting exceptions, - // in which case we will not have yet init'd the FieldsWriter - initFieldsWriter(); - - // Fill fdx file to include any final docs that we skipped because they hit non-aborting - // exceptions - fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); +void StoredFieldsWriter::initFieldsWriter() { + if (!fieldsWriter) { + DocumentsWriterPtr docWriter(_docWriter); + String docStoreSegment(docWriter->getDocStoreSegment()); + if (!docStoreSegment.empty()) { + fieldsWriter = newLucene(docWriter->directory, docStoreSegment, fieldInfos); + docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::FIELDS_EXTENSION()); + docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); + lastDocID = 0; } - - if (fieldsWriter) - fieldsWriter->flush(); } +} - void StoredFieldsWriter::initFieldsWriter() - { - if (!fieldsWriter) - { - DocumentsWriterPtr docWriter(_docWriter); - String docStoreSegment(docWriter->getDocStoreSegment()); - if (!docStoreSegment.empty()) - { - fieldsWriter = newLucene(docWriter->directory, docStoreSegment, fieldInfos); - docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::FIELDS_EXTENSION()); - docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - lastDocID = 0; - } - } +void StoredFieldsWriter::closeDocStore(const SegmentWriteStatePtr& state) { + SyncLock syncLock(this); + int32_t inc = state->numDocsInStore - lastDocID; + if (inc > 0) { + initFieldsWriter(); + fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); } - void StoredFieldsWriter::closeDocStore(const SegmentWriteStatePtr& state) - { - SyncLock syncLock(this); - int32_t inc = state->numDocsInStore - lastDocID; - if (inc > 0) - { - initFieldsWriter(); - fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); - } + if (fieldsWriter) { + fieldsWriter->close(); + fieldsWriter.reset(); + lastDocID = 0; + BOOST_ASSERT(!state->docStoreSegmentName.empty()); + state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_EXTENSION()); + state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - if (fieldsWriter) - { - fieldsWriter->close(); - fieldsWriter.reset(); - lastDocID = 0; - BOOST_ASSERT(!state->docStoreSegmentName.empty()); - state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_EXTENSION()); - state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - - DocumentsWriterPtr docWriter(state->_docWriter); - docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_EXTENSION()); - docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - - String fileName(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); - - if (4 + ((int64_t)state->numDocsInStore) * 8 != state->directory->fileLength(fileName)) - { - boost::throw_exception(RuntimeException(L"after flush: fdx size mismatch: " + StringUtils::toString(state->numDocsInStore) + - L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + - L" length in bytes of " + fileName + L" file exists?=" + - StringUtils::toString(state->directory->fileExists(fileName)))); - } + DocumentsWriterPtr docWriter(state->_docWriter); + docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_EXTENSION()); + docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); + + String fileName(state->docStoreSegmentName + L"." + IndexFileNames::FIELDS_INDEX_EXTENSION()); + + if (4 + ((int64_t)state->numDocsInStore) * 8 != state->directory->fileLength(fileName)) { + boost::throw_exception(RuntimeException(L"after flush: fdx size mismatch: " + StringUtils::toString(state->numDocsInStore) + + L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + + L" length in bytes of " + fileName + L" file exists?=" + + StringUtils::toString(state->directory->fileExists(fileName)))); } } +} - StoredFieldsWriterPerDocPtr StoredFieldsWriter::getPerDoc() - { - SyncLock syncLock(this); - if (freeCount == 0) - { - ++allocCount; - if (allocCount > docFreeList.size()) - { - // Grow our free list up front to make sure we have enough space to recycle all - // outstanding StoredFieldsWriterPerDoc instances - BOOST_ASSERT(allocCount == docFreeList.size() + 1); - docFreeList.resize(MiscUtils::getNextSize(allocCount)); - } - return newLucene(shared_from_this()); +StoredFieldsWriterPerDocPtr StoredFieldsWriter::getPerDoc() { + SyncLock syncLock(this); + if (freeCount == 0) { + ++allocCount; + if (allocCount > docFreeList.size()) { + // Grow our free list up front to make sure we have enough space to recycle all + // outstanding StoredFieldsWriterPerDoc instances + BOOST_ASSERT(allocCount == docFreeList.size() + 1); + docFreeList.resize(MiscUtils::getNextSize(allocCount)); } - else - return docFreeList[--freeCount]; + return newLucene(shared_from_this()); + } else { + return docFreeList[--freeCount]; } +} - void StoredFieldsWriter::abort() - { - SyncLock syncLock(this); - if (fieldsWriter) - { - try - { - fieldsWriter->close(); - } - catch (...) - { - } - fieldsWriter.reset(); - lastDocID = 0; +void StoredFieldsWriter::abort() { + SyncLock syncLock(this); + if (fieldsWriter) { + try { + fieldsWriter->close(); + } catch (...) { } + fieldsWriter.reset(); + lastDocID = 0; } +} - void StoredFieldsWriter::fill(int32_t docID) - { - int32_t docStoreOffset = DocumentsWriterPtr(_docWriter)->getDocStoreOffset(); +void StoredFieldsWriter::fill(int32_t docID) { + int32_t docStoreOffset = DocumentsWriterPtr(_docWriter)->getDocStoreOffset(); - // We must "catch up" for all docs before us that had no stored fields - int32_t end = docID + docStoreOffset; - while (lastDocID < end) - { - fieldsWriter->skipDocument(); - ++lastDocID; - } + // We must "catch up" for all docs before us that had no stored fields + int32_t end = docID + docStoreOffset; + while (lastDocID < end) { + fieldsWriter->skipDocument(); + ++lastDocID; } +} - void StoredFieldsWriter::finishDocument(const StoredFieldsWriterPerDocPtr& perDoc) - { - SyncLock syncLock(this); - IndexWriterPtr writer(DocumentsWriterPtr(_docWriter)->_writer); - BOOST_ASSERT(writer->testPoint(L"StoredFieldsWriter.finishDocument start")); - initFieldsWriter(); +void StoredFieldsWriter::finishDocument(const StoredFieldsWriterPerDocPtr& perDoc) { + SyncLock syncLock(this); + IndexWriterPtr writer(DocumentsWriterPtr(_docWriter)->_writer); + BOOST_ASSERT(writer->testPoint(L"StoredFieldsWriter.finishDocument start")); + initFieldsWriter(); - fill(perDoc->docID); + fill(perDoc->docID); - // Append stored fields to the real FieldsWriter - fieldsWriter->flushDocument(perDoc->numStoredFields, perDoc->fdt); - ++lastDocID; - perDoc->reset(); - free(perDoc); - BOOST_ASSERT(writer->testPoint(L"StoredFieldsWriter.finishDocument end")); - } + // Append stored fields to the real FieldsWriter + fieldsWriter->flushDocument(perDoc->numStoredFields, perDoc->fdt); + ++lastDocID; + perDoc->reset(); + free(perDoc); + BOOST_ASSERT(writer->testPoint(L"StoredFieldsWriter.finishDocument end")); +} - bool StoredFieldsWriter::freeRAM() - { - return false; - } +bool StoredFieldsWriter::freeRAM() { + return false; +} - void StoredFieldsWriter::free(const StoredFieldsWriterPerDocPtr& perDoc) - { - SyncLock syncLock(this); - BOOST_ASSERT(freeCount < docFreeList.size()); - BOOST_ASSERT(perDoc->numStoredFields == 0); - BOOST_ASSERT(perDoc->fdt->length() == 0); - BOOST_ASSERT(perDoc->fdt->getFilePointer() == 0); - docFreeList[freeCount++] = perDoc; - } +void StoredFieldsWriter::free(const StoredFieldsWriterPerDocPtr& perDoc) { + SyncLock syncLock(this); + BOOST_ASSERT(freeCount < docFreeList.size()); + BOOST_ASSERT(perDoc->numStoredFields == 0); + BOOST_ASSERT(perDoc->fdt->length() == 0); + BOOST_ASSERT(perDoc->fdt->getFilePointer() == 0); + docFreeList[freeCount++] = perDoc; +} - StoredFieldsWriterPerDoc::StoredFieldsWriterPerDoc(const StoredFieldsWriterPtr& fieldsWriter) - { - this->_fieldsWriter = fieldsWriter; - buffer = DocumentsWriterPtr(fieldsWriter->_docWriter)->newPerDocBuffer(); - fdt = newLucene(buffer); - numStoredFields = 0; - } +StoredFieldsWriterPerDoc::StoredFieldsWriterPerDoc(const StoredFieldsWriterPtr& fieldsWriter) { + this->_fieldsWriter = fieldsWriter; + buffer = DocumentsWriterPtr(fieldsWriter->_docWriter)->newPerDocBuffer(); + fdt = newLucene(buffer); + numStoredFields = 0; +} - StoredFieldsWriterPerDoc::~StoredFieldsWriterPerDoc() - { - } +StoredFieldsWriterPerDoc::~StoredFieldsWriterPerDoc() { +} - void StoredFieldsWriterPerDoc::reset() - { - fdt->reset(); - buffer->recycle(); - numStoredFields = 0; - } +void StoredFieldsWriterPerDoc::reset() { + fdt->reset(); + buffer->recycle(); + numStoredFields = 0; +} - void StoredFieldsWriterPerDoc::abort() - { - reset(); - StoredFieldsWriterPtr(_fieldsWriter)->free(shared_from_this()); - } +void StoredFieldsWriterPerDoc::abort() { + reset(); + StoredFieldsWriterPtr(_fieldsWriter)->free(shared_from_this()); +} - int64_t StoredFieldsWriterPerDoc::sizeInBytes() - { - return buffer->getSizeInBytes(); - } +int64_t StoredFieldsWriterPerDoc::sizeInBytes() { + return buffer->getSizeInBytes(); +} + +void StoredFieldsWriterPerDoc::finish() { + StoredFieldsWriterPtr(_fieldsWriter)->finishDocument(shared_from_this()); +} - void StoredFieldsWriterPerDoc::finish() - { - StoredFieldsWriterPtr(_fieldsWriter)->finishDocument(shared_from_this()); - } } diff --git a/src/core/index/StoredFieldsWriterPerThread.cpp b/src/core/index/StoredFieldsWriterPerThread.cpp index e051f668..888c128e 100644 --- a/src/core/index/StoredFieldsWriterPerThread.cpp +++ b/src/core/index/StoredFieldsWriterPerThread.cpp @@ -10,61 +10,53 @@ #include "FieldsWriter.h" #include "RAMOutputStream.h" -namespace Lucene -{ - StoredFieldsWriterPerThread::StoredFieldsWriterPerThread(const DocStatePtr& docState, const StoredFieldsWriterPtr& storedFieldsWriter) - { - this->_storedFieldsWriter = storedFieldsWriter; - this->docState = docState; - localFieldsWriter = newLucene(IndexOutputPtr(), IndexOutputPtr(), storedFieldsWriter->fieldInfos); - } +namespace Lucene { + +StoredFieldsWriterPerThread::StoredFieldsWriterPerThread(const DocStatePtr& docState, const StoredFieldsWriterPtr& storedFieldsWriter) { + this->_storedFieldsWriter = storedFieldsWriter; + this->docState = docState; + localFieldsWriter = newLucene(IndexOutputPtr(), IndexOutputPtr(), storedFieldsWriter->fieldInfos); +} - StoredFieldsWriterPerThread::~StoredFieldsWriterPerThread() - { +StoredFieldsWriterPerThread::~StoredFieldsWriterPerThread() { +} + +void StoredFieldsWriterPerThread::startDocument() { + if (doc) { + // Only happens if previous document hit non-aborting exception while writing stored fields + // into localFieldsWriter + doc->reset(); + doc->docID = docState->docID; } +} - void StoredFieldsWriterPerThread::startDocument() - { - if (doc) - { - // Only happens if previous document hit non-aborting exception while writing stored fields - // into localFieldsWriter - doc->reset(); - doc->docID = docState->docID; - } +void StoredFieldsWriterPerThread::addField(const FieldablePtr& field, const FieldInfoPtr& fieldInfo) { + if (!doc) { + doc = StoredFieldsWriterPtr(_storedFieldsWriter)->getPerDoc(); + doc->docID = docState->docID; + localFieldsWriter->setFieldsStream(doc->fdt); + BOOST_ASSERT(doc->numStoredFields == 0); + BOOST_ASSERT(doc->fdt->length() == 0); + BOOST_ASSERT(doc->fdt->getFilePointer() == 0); } - void StoredFieldsWriterPerThread::addField(const FieldablePtr& field, const FieldInfoPtr& fieldInfo) - { - if (!doc) - { - doc = StoredFieldsWriterPtr(_storedFieldsWriter)->getPerDoc(); - doc->docID = docState->docID; - localFieldsWriter->setFieldsStream(doc->fdt); - BOOST_ASSERT(doc->numStoredFields == 0); - BOOST_ASSERT(doc->fdt->length() == 0); - BOOST_ASSERT(doc->fdt->getFilePointer() == 0); - } + localFieldsWriter->writeField(fieldInfo, field); + BOOST_ASSERT(docState->testPoint(L"StoredFieldsWriterPerThread.processFields.writeField")); + ++doc->numStoredFields; +} - localFieldsWriter->writeField(fieldInfo, field); - BOOST_ASSERT(docState->testPoint(L"StoredFieldsWriterPerThread.processFields.writeField")); - ++doc->numStoredFields; - } +DocWriterPtr StoredFieldsWriterPerThread::finishDocument() { + // If there were any stored fields in this doc, doc will be non-null; else it's null. + DocWriterPtr finishDoc(doc); + doc.reset(); + return finishDoc; +} - DocWriterPtr StoredFieldsWriterPerThread::finishDocument() - { - // If there were any stored fields in this doc, doc will be non-null; else it's null. - DocWriterPtr finishDoc(doc); +void StoredFieldsWriterPerThread::abort() { + if (doc) { + doc->abort(); doc.reset(); - return finishDoc; } +} - void StoredFieldsWriterPerThread::abort() - { - if (doc) - { - doc->abort(); - doc.reset(); - } - } } diff --git a/src/core/index/Term.cpp b/src/core/index/Term.cpp index 6ac2f113..d81b740b 100644 --- a/src/core/index/Term.cpp +++ b/src/core/index/Term.cpp @@ -9,71 +9,67 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - Term::Term(const String& fld, const String& txt) : _field(fld), _text(txt) - { - } +namespace Lucene { - Term::~Term() - { - } +Term::Term(const String& fld, const String& txt) : _field(fld), _text(txt) { +} - String Term::field() - { - return _field; - } +Term::~Term() { +} - String Term::text() - { - return _text; - } +String Term::field() { + return _field; +} - TermPtr Term::createTerm(const String& text) - { - return newLucene(_field, text); - } +String Term::text() { + return _text; +} - bool Term::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - TermPtr otherTerm(boost::dynamic_pointer_cast(other)); - if (!otherTerm) - return false; - return (_field == otherTerm->_field && _text == otherTerm->_text); - } +TermPtr Term::createTerm(const String& text) { + return newLucene(_field, text); +} - int32_t Term::hashCode() - { - int32_t prime = 31; - int32_t result = 1; - result = prime * result + (_field.empty() ? 0 : StringUtils::hashCode(_field)); - result = prime * result + (_text.empty() ? 0 : StringUtils::hashCode(_text)); - return result; +bool Term::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - - int32_t Term::compareTo(const LuceneObjectPtr& other) - { - TermPtr otherTerm(boost::static_pointer_cast(other)); - if (_field == otherTerm->_field) - return _text.compare(otherTerm->_text); - else - return _field.compare(otherTerm->_field); + if (!other) { + return false; } - - void Term::set(const String& fld, const String& txt) - { - _field = fld; - _text = txt; + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + TermPtr otherTerm(boost::dynamic_pointer_cast(other)); + if (!otherTerm) { + return false; } + return (_field == otherTerm->_field && _text == otherTerm->_text); +} - String Term::toString() - { - return _field + L":" + _text; +int32_t Term::hashCode() { + int32_t prime = 31; + int32_t result = 1; + result = prime * result + (_field.empty() ? 0 : StringUtils::hashCode(_field)); + result = prime * result + (_text.empty() ? 0 : StringUtils::hashCode(_text)); + return result; +} + +int32_t Term::compareTo(const LuceneObjectPtr& other) { + TermPtr otherTerm(boost::static_pointer_cast(other)); + if (_field == otherTerm->_field) { + return _text.compare(otherTerm->_text); + } else { + return _field.compare(otherTerm->_field); } } + +void Term::set(const String& fld, const String& txt) { + _field = fld; + _text = txt; +} + +String Term::toString() { + return _field + L":" + _text; +} + +} diff --git a/src/core/index/TermBuffer.cpp b/src/core/index/TermBuffer.cpp index 41f27398..0c3394a9 100644 --- a/src/core/index/TermBuffer.cpp +++ b/src/core/index/TermBuffer.cpp @@ -13,118 +13,107 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - TermBuffer::TermBuffer() - { - preUTF8Strings = false; - text = newLucene(); - bytes = newLucene(); - } +namespace Lucene { - TermBuffer::~TermBuffer() - { - } +TermBuffer::TermBuffer() { + preUTF8Strings = false; + text = newLucene(); + bytes = newLucene(); +} - int32_t TermBuffer::compareTo(const LuceneObjectPtr& other) - { - TermBufferPtr otherTermBuffer(boost::static_pointer_cast(other)); - if (field == otherTermBuffer->field) - return compareChars(text->result.get(), text->length, otherTermBuffer->text->result.get(), otherTermBuffer->text->length); - else - return field.compare(otherTermBuffer->field); +TermBuffer::~TermBuffer() { +} + +int32_t TermBuffer::compareTo(const LuceneObjectPtr& other) { + TermBufferPtr otherTermBuffer(boost::static_pointer_cast(other)); + if (field == otherTermBuffer->field) { + return compareChars(text->result.get(), text->length, otherTermBuffer->text->result.get(), otherTermBuffer->text->length); + } else { + return field.compare(otherTermBuffer->field); } +} - int32_t TermBuffer::compareChars(wchar_t* chars1, int32_t len1, wchar_t* chars2, int32_t len2) - { - int32_t end = len1 < len2 ? len1 : len2; - for (int32_t k = 0; k < end; ++k) - { - wchar_t c1 = chars1[k]; - wchar_t c2 = chars2[k]; - if (c1 != c2) - return c1 - c2; +int32_t TermBuffer::compareChars(wchar_t* chars1, int32_t len1, wchar_t* chars2, int32_t len2) { + int32_t end = len1 < len2 ? len1 : len2; + for (int32_t k = 0; k < end; ++k) { + wchar_t c1 = chars1[k]; + wchar_t c2 = chars2[k]; + if (c1 != c2) { + return c1 - c2; } - return len1 - len2; } + return len1 - len2; +} - void TermBuffer::setPreUTF8Strings() - { - preUTF8Strings = true; - } +void TermBuffer::setPreUTF8Strings() { + preUTF8Strings = true; +} - void TermBuffer::read(const IndexInputPtr& input, const FieldInfosPtr& fieldInfos) - { - this->term.reset(); // invalidate cache - int32_t start = input->readVInt(); - int32_t length = input->readVInt(); - int32_t totalLength = start + length; - if (preUTF8Strings) - { - text->setLength(totalLength); - text->setLength(start + input->readChars(text->result.get(), start, length)); - } - else - { - StringUtils::toUTF8(text->result.get(), text->length, bytes); - bytes->setLength(totalLength); - input->readBytes(bytes->result.get(), start, length); - StringUtils::toUnicode(bytes->result.get(), totalLength, text); - } - this->field = fieldInfos->fieldName(input->readVInt()); +void TermBuffer::read(const IndexInputPtr& input, const FieldInfosPtr& fieldInfos) { + this->term.reset(); // invalidate cache + int32_t start = input->readVInt(); + int32_t length = input->readVInt(); + int32_t totalLength = start + length; + if (preUTF8Strings) { + text->setLength(totalLength); + text->setLength(start + input->readChars(text->result.get(), start, length)); + } else { + StringUtils::toUTF8(text->result.get(), text->length, bytes); + bytes->setLength(totalLength); + input->readBytes(bytes->result.get(), start, length); + StringUtils::toUnicode(bytes->result.get(), totalLength, text); } + this->field = fieldInfos->fieldName(input->readVInt()); +} - void TermBuffer::set(const TermPtr& term) - { - if (!term) - { - reset(); - return; - } - String termText(term->text()); - int32_t termLen = termText.length(); - text->setLength(termLen); - MiscUtils::arrayCopy(termText.begin(), 0, text->result.get(), 0, termLen); - field = term->field(); - this->term = term; +void TermBuffer::set(const TermPtr& term) { + if (!term) { + reset(); + return; } + String termText(term->text()); + int32_t termLen = termText.length(); + text->setLength(termLen); + MiscUtils::arrayCopy(termText.begin(), 0, text->result.get(), 0, termLen); + field = term->field(); + this->term = term; +} - void TermBuffer::set(const TermBufferPtr& other) - { - text->copyText(other->text); - field = other->field; - term = other->term; +void TermBuffer::set(const TermBufferPtr& other) { + text->copyText(other->text); + field = other->field; + term = other->term; +} + +void TermBuffer::reset() { + field.clear(); + text->setLength(0); + term.reset(); +} + +TermPtr TermBuffer::toTerm() { + if (field.empty()) { // unset + return TermPtr(); } - void TermBuffer::reset() - { - field.clear(); - text->setLength(0); - term.reset(); + if (!term) { + term = newLucene(field, String(text->result.get(), text->length)); } - TermPtr TermBuffer::toTerm() - { - if (field.empty()) // unset - return TermPtr(); + return term; +} - if (!term) - term = newLucene(field, String(text->result.get(), text->length)); +LuceneObjectPtr TermBuffer::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + TermBufferPtr cloneBuffer(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); + cloneBuffer->field = field; + cloneBuffer->term = term; + cloneBuffer->preUTF8Strings = preUTF8Strings; - return term; - } + cloneBuffer->bytes = newLucene(); + cloneBuffer->text = newLucene(); + cloneBuffer->text->copyText(text); + return cloneBuffer; +} - LuceneObjectPtr TermBuffer::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - TermBufferPtr cloneBuffer(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); - cloneBuffer->field = field; - cloneBuffer->term = term; - cloneBuffer->preUTF8Strings = preUTF8Strings; - - cloneBuffer->bytes = newLucene(); - cloneBuffer->text = newLucene(); - cloneBuffer->text->copyText(text); - return cloneBuffer; - } } diff --git a/src/core/index/TermDocs.cpp b/src/core/index/TermDocs.cpp index 1a6b6097..8ce3c037 100644 --- a/src/core/index/TermDocs.cpp +++ b/src/core/index/TermDocs.cpp @@ -7,57 +7,49 @@ #include "LuceneInc.h" #include "TermDocs.h" -namespace Lucene -{ - TermDocs::TermDocs() - { - } - - void TermDocs::seek(const TermPtr& term) - { - BOOST_ASSERT(false); - // override - } - - void TermDocs::seek(const TermEnumPtr& termEnum) - { - BOOST_ASSERT(false); - // override - } - - int32_t TermDocs::doc() - { - BOOST_ASSERT(false); - return 0; // override - } - - int32_t TermDocs::freq() - { - BOOST_ASSERT(false); - return 0; // override - } - - bool TermDocs::next() - { - BOOST_ASSERT(false); - return false; // override - } - - int32_t TermDocs::read(Collection docs, Collection freqs) - { - BOOST_ASSERT(false); - return 0; // override - } - - bool TermDocs::skipTo(int32_t target) - { - BOOST_ASSERT(false); - return false; // override - } - - void TermDocs::close() - { - BOOST_ASSERT(false); - // override - } +namespace Lucene { + +TermDocs::TermDocs() { +} + +void TermDocs::seek(const TermPtr& term) { + BOOST_ASSERT(false); + // override +} + +void TermDocs::seek(const TermEnumPtr& termEnum) { + BOOST_ASSERT(false); + // override +} + +int32_t TermDocs::doc() { + BOOST_ASSERT(false); + return 0; // override +} + +int32_t TermDocs::freq() { + BOOST_ASSERT(false); + return 0; // override +} + +bool TermDocs::next() { + BOOST_ASSERT(false); + return false; // override +} + +int32_t TermDocs::read(Collection docs, Collection freqs) { + BOOST_ASSERT(false); + return 0; // override +} + +bool TermDocs::skipTo(int32_t target) { + BOOST_ASSERT(false); + return false; // override +} + +void TermDocs::close() { + BOOST_ASSERT(false); + // override +} + } diff --git a/src/core/index/TermEnum.cpp b/src/core/index/TermEnum.cpp index 3261c5d1..aa95bc7c 100644 --- a/src/core/index/TermEnum.cpp +++ b/src/core/index/TermEnum.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "TermEnum.h" -namespace Lucene -{ - TermEnum::~TermEnum() - { - } +namespace Lucene { + +TermEnum::~TermEnum() { +} + } diff --git a/src/core/index/TermFreqVector.cpp b/src/core/index/TermFreqVector.cpp index 0b16651e..3fe9e8a9 100644 --- a/src/core/index/TermFreqVector.cpp +++ b/src/core/index/TermFreqVector.cpp @@ -7,49 +7,42 @@ #include "LuceneInc.h" #include "TermFreqVector.h" -namespace Lucene -{ - TermFreqVector::TermFreqVector() - { - } - - TermFreqVector::~TermFreqVector() - { - } - - String TermFreqVector::getField() - { - BOOST_ASSERT(false); - return L""; // override - } - - int32_t TermFreqVector::size() - { - BOOST_ASSERT(false); - return 0; // override - } - - Collection TermFreqVector::getTerms() - { - BOOST_ASSERT(false); - return Collection(); // override - } - - Collection TermFreqVector::getTermFrequencies() - { - BOOST_ASSERT(false); - return Collection(); // override - } - - int32_t TermFreqVector::indexOf(const String& term) - { - BOOST_ASSERT(false); - return 0; // override - } - - Collection TermFreqVector::indexesOf(Collection terms, int32_t start, int32_t length) - { - BOOST_ASSERT(false); - return Collection(); // override - } +namespace Lucene { + +TermFreqVector::TermFreqVector() { +} + +TermFreqVector::~TermFreqVector() { +} + +String TermFreqVector::getField() { + BOOST_ASSERT(false); + return L""; // override +} + +int32_t TermFreqVector::size() { + BOOST_ASSERT(false); + return 0; // override +} + +Collection TermFreqVector::getTerms() { + BOOST_ASSERT(false); + return Collection(); // override +} + +Collection TermFreqVector::getTermFrequencies() { + BOOST_ASSERT(false); + return Collection(); // override +} + +int32_t TermFreqVector::indexOf(const String& term) { + BOOST_ASSERT(false); + return 0; // override +} + +Collection TermFreqVector::indexesOf(Collection terms, int32_t start, int32_t length) { + BOOST_ASSERT(false); + return Collection(); // override +} + } diff --git a/src/core/index/TermInfo.cpp b/src/core/index/TermInfo.cpp index af6f7dc0..f2cd186e 100644 --- a/src/core/index/TermInfo.cpp +++ b/src/core/index/TermInfo.cpp @@ -7,38 +7,34 @@ #include "LuceneInc.h" #include "TermInfo.h" -namespace Lucene -{ - TermInfo::TermInfo(const TermInfoPtr& ti) - { - set(ti); - } - - TermInfo::TermInfo(int32_t df, int64_t fp, int64_t pp) - { - docFreq = df; - freqPointer = fp; - proxPointer = pp; - skipOffset = 0; - } - - TermInfo::~TermInfo() - { - } - - void TermInfo::set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer, int32_t skipOffset) - { - this->docFreq = docFreq; - this->freqPointer = freqPointer; - this->proxPointer = proxPointer; - this->skipOffset = skipOffset; - } - - void TermInfo::set(const TermInfoPtr& ti) - { - docFreq = ti->docFreq; - freqPointer = ti->freqPointer; - proxPointer = ti->proxPointer; - skipOffset = ti->skipOffset; - } +namespace Lucene { + +TermInfo::TermInfo(const TermInfoPtr& ti) { + set(ti); +} + +TermInfo::TermInfo(int32_t df, int64_t fp, int64_t pp) { + docFreq = df; + freqPointer = fp; + proxPointer = pp; + skipOffset = 0; +} + +TermInfo::~TermInfo() { +} + +void TermInfo::set(int32_t docFreq, int64_t freqPointer, int64_t proxPointer, int32_t skipOffset) { + this->docFreq = docFreq; + this->freqPointer = freqPointer; + this->proxPointer = proxPointer; + this->skipOffset = skipOffset; +} + +void TermInfo::set(const TermInfoPtr& ti) { + docFreq = ti->docFreq; + freqPointer = ti->freqPointer; + proxPointer = ti->proxPointer; + skipOffset = ti->skipOffset; +} + } diff --git a/src/core/index/TermInfosReader.cpp b/src/core/index/TermInfosReader.cpp index d32b40ec..39e3db16 100644 --- a/src/core/index/TermInfosReader.cpp +++ b/src/core/index/TermInfosReader.cpp @@ -12,237 +12,212 @@ #include "Term.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t TermInfosReader::DEFAULT_CACHE_SIZE = 1024; - - TermInfosReader::TermInfosReader(const DirectoryPtr& dir, const String& seg, const FieldInfosPtr& fis, int32_t readBufferSize, int32_t indexDivisor) - { - bool success = false; - - if (indexDivisor < 1 && indexDivisor != -1) - boost::throw_exception(IllegalArgumentException(L"indexDivisor must be -1 (don't load terms index) or greater than 0: got " + StringUtils::toString(indexDivisor))); - - LuceneException finally; - try - { - directory = dir; - segment = seg; - fieldInfos = fis; - - origEnum = newLucene(directory->openInput(segment + L"." + IndexFileNames::TERMS_EXTENSION(), readBufferSize), fieldInfos, false); - _size = origEnum->size; - - if (indexDivisor != -1) - { - // Load terms index - totalIndexInterval = origEnum->indexInterval * indexDivisor; - SegmentTermEnumPtr indexEnum(newLucene(directory->openInput(segment + L"." + IndexFileNames::TERMS_INDEX_EXTENSION(), readBufferSize), fieldInfos, true)); - - try - { - int32_t indexSize = 1 + ((int32_t)indexEnum->size - 1) / indexDivisor; // otherwise read index - - indexTerms = Collection::newInstance(indexSize); - indexInfos = Collection::newInstance(indexSize); - indexPointers = Collection::newInstance(indexSize); - - for (int32_t i = 0; indexEnum->next(); ++i) - { - indexTerms[i] = indexEnum->term(); - indexInfos[i] = indexEnum->termInfo(); - indexPointers[i] = indexEnum->indexPointer; - - for (int32_t j = 1; j < indexDivisor; ++j) - { - if (!indexEnum->next()) - break; +namespace Lucene { + +const int32_t TermInfosReader::DEFAULT_CACHE_SIZE = 1024; + +TermInfosReader::TermInfosReader(const DirectoryPtr& dir, const String& seg, const FieldInfosPtr& fis, int32_t readBufferSize, int32_t indexDivisor) { + bool success = false; + + if (indexDivisor < 1 && indexDivisor != -1) { + boost::throw_exception(IllegalArgumentException(L"indexDivisor must be -1 (don't load terms index) or greater than 0: got " + StringUtils::toString(indexDivisor))); + } + + LuceneException finally; + try { + directory = dir; + segment = seg; + fieldInfos = fis; + + origEnum = newLucene(directory->openInput(segment + L"." + IndexFileNames::TERMS_EXTENSION(), readBufferSize), fieldInfos, false); + _size = origEnum->size; + + if (indexDivisor != -1) { + // Load terms index + totalIndexInterval = origEnum->indexInterval * indexDivisor; + SegmentTermEnumPtr indexEnum(newLucene(directory->openInput(segment + L"." + IndexFileNames::TERMS_INDEX_EXTENSION(), readBufferSize), fieldInfos, true)); + + try { + int32_t indexSize = 1 + ((int32_t)indexEnum->size - 1) / indexDivisor; // otherwise read index + + indexTerms = Collection::newInstance(indexSize); + indexInfos = Collection::newInstance(indexSize); + indexPointers = Collection::newInstance(indexSize); + + for (int32_t i = 0; indexEnum->next(); ++i) { + indexTerms[i] = indexEnum->term(); + indexInfos[i] = indexEnum->termInfo(); + indexPointers[i] = indexEnum->indexPointer; + + for (int32_t j = 1; j < indexDivisor; ++j) { + if (!indexEnum->next()) { + break; } } } - catch (LuceneException& e) - { - finally = e; - } - indexEnum->close(); - } - else - { - // Do not load terms index - totalIndexInterval = -1; + } catch (LuceneException& e) { + finally = e; } - success = true; + indexEnum->close(); + } else { + // Do not load terms index + totalIndexInterval = -1; } - catch (LuceneException& e) - { - finally = e; - } - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. - // In this case, we want to explicitly close any subset of things that were opened. - if (!success) - close(); - finally.throwException(); + success = true; + } catch (LuceneException& e) { + finally = e; } - - TermInfosReader::~TermInfosReader() - { + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception above. + // In this case, we want to explicitly close any subset of things that were opened. + if (!success) { + close(); } + finally.throwException(); +} - int32_t TermInfosReader::getMaxSkipLevels() - { - return origEnum->maxSkipLevels; - } +TermInfosReader::~TermInfosReader() { +} - int32_t TermInfosReader::getSkipInterval() - { - return origEnum->skipInterval; - } +int32_t TermInfosReader::getMaxSkipLevels() { + return origEnum->maxSkipLevels; +} - void TermInfosReader::close() - { - if (origEnum) - origEnum->close(); - threadResources.close(); - } +int32_t TermInfosReader::getSkipInterval() { + return origEnum->skipInterval; +} - int64_t TermInfosReader::size() - { - return _size; +void TermInfosReader::close() { + if (origEnum) { + origEnum->close(); } + threadResources.close(); +} - TermInfosReaderThreadResourcesPtr TermInfosReader::getThreadResources() - { - TermInfosReaderThreadResourcesPtr resources(threadResources.get()); - if (!resources) - { - resources = newLucene(); - resources->termEnum = terms(); - - // Cache does not have to be thread-safe, it is only used by one thread at the same time - resources->termInfoCache = newInstance(DEFAULT_CACHE_SIZE); - threadResources.set(resources); - } - return resources; - } +int64_t TermInfosReader::size() { + return _size; +} - int32_t TermInfosReader::getIndexOffset(const TermPtr& term) - { - // binary search indexTerms - Collection::iterator indexTerm = std::upper_bound(indexTerms.begin(), indexTerms.end(), term, luceneCompare()); - return (std::distance(indexTerms.begin(), indexTerm) - 1); - } +TermInfosReaderThreadResourcesPtr TermInfosReader::getThreadResources() { + TermInfosReaderThreadResourcesPtr resources(threadResources.get()); + if (!resources) { + resources = newLucene(); + resources->termEnum = terms(); - void TermInfosReader::seekEnum(const SegmentTermEnumPtr& enumerator, int32_t indexOffset) - { - enumerator->seek(indexPointers[indexOffset], ((int64_t)indexOffset * (int64_t)totalIndexInterval) - 1, indexTerms[indexOffset], indexInfos[indexOffset]); + // Cache does not have to be thread-safe, it is only used by one thread at the same time + resources->termInfoCache = newInstance(DEFAULT_CACHE_SIZE); + threadResources.set(resources); } + return resources; +} - TermInfoPtr TermInfosReader::get(const TermPtr& term) - { - return get(term, true); - } +int32_t TermInfosReader::getIndexOffset(const TermPtr& term) { + // binary search indexTerms + Collection::iterator indexTerm = std::upper_bound(indexTerms.begin(), indexTerms.end(), term, luceneCompare()); + return (std::distance(indexTerms.begin(), indexTerm) - 1); +} - TermInfoPtr TermInfosReader::get(const TermPtr& term, bool useCache) - { - if (_size == 0) - return TermInfoPtr(); +void TermInfosReader::seekEnum(const SegmentTermEnumPtr& enumerator, int32_t indexOffset) { + enumerator->seek(indexPointers[indexOffset], ((int64_t)indexOffset * (int64_t)totalIndexInterval) - 1, indexTerms[indexOffset], indexInfos[indexOffset]); +} - ensureIndexIsRead(); +TermInfoPtr TermInfosReader::get(const TermPtr& term) { + return get(term, true); +} - TermInfoPtr ti; - TermInfosReaderThreadResourcesPtr resources(getThreadResources()); - TermInfoCachePtr cache; +TermInfoPtr TermInfosReader::get(const TermPtr& term, bool useCache) { + if (_size == 0) { + return TermInfoPtr(); + } - if (useCache) - { - cache = resources->termInfoCache; - // check the cache first if the term was recently looked up - ti = cache->get(term); - if (ti) - return ti; + ensureIndexIsRead(); + + TermInfoPtr ti; + TermInfosReaderThreadResourcesPtr resources(getThreadResources()); + TermInfoCachePtr cache; + + if (useCache) { + cache = resources->termInfoCache; + // check the cache first if the term was recently looked up + ti = cache->get(term); + if (ti) { + return ti; } + } - // optimize sequential access: first try scanning cached enum without seeking - SegmentTermEnumPtr enumerator = resources->termEnum; + // optimize sequential access: first try scanning cached enum without seeking + SegmentTermEnumPtr enumerator = resources->termEnum; - if (enumerator->term() && // term is at or past current + if (enumerator->term() && // term is at or past current ((enumerator->prev() && term->compareTo(enumerator->prev()) > 0) || - term->compareTo(enumerator->term()) >= 0)) - { - int32_t enumOffset = (int32_t)(enumerator->position / totalIndexInterval ) + 1; - if (indexTerms.size() == enumOffset || // but before end of block - term->compareTo(indexTerms[enumOffset]) < 0) - { - // no need to seek - int32_t numScans = enumerator->scanTo(term); - if (enumerator->term() && term->compareTo(enumerator->term()) == 0) - { - ti = enumerator->termInfo(); - if (cache && numScans > 1) - { - // we only want to put this TermInfo into the cache if scanEnum skipped more - // than one dictionary entry. This prevents RangeQueries or WildcardQueries to - // wipe out the cache when they iterate over a large numbers of terms in order. - cache->put(term, ti); - } + term->compareTo(enumerator->term()) >= 0)) { + int32_t enumOffset = (int32_t)(enumerator->position / totalIndexInterval ) + 1; + if (indexTerms.size() == enumOffset || // but before end of block + term->compareTo(indexTerms[enumOffset]) < 0) { + // no need to seek + int32_t numScans = enumerator->scanTo(term); + if (enumerator->term() && term->compareTo(enumerator->term()) == 0) { + ti = enumerator->termInfo(); + if (cache && numScans > 1) { + // we only want to put this TermInfo into the cache if scanEnum skipped more + // than one dictionary entry. This prevents RangeQueries or WildcardQueries to + // wipe out the cache when they iterate over a large numbers of terms in order. + cache->put(term, ti); } - else - ti.reset(); - return ti; + } else { + ti.reset(); } + return ti; } + } - // random-access: must seek - seekEnum(enumerator, getIndexOffset(term)); - enumerator->scanTo(term); - if (enumerator->term() && term->compareTo(enumerator->term()) == 0) - { - ti = enumerator->termInfo(); - if (cache) - cache->put(term, ti); + // random-access: must seek + seekEnum(enumerator, getIndexOffset(term)); + enumerator->scanTo(term); + if (enumerator->term() && term->compareTo(enumerator->term()) == 0) { + ti = enumerator->termInfo(); + if (cache) { + cache->put(term, ti); } - else - ti.reset(); - return ti; + } else { + ti.reset(); + } + return ti; +} + +void TermInfosReader::ensureIndexIsRead() { + if (!indexTerms) { + boost::throw_exception(IllegalStateException(L"terms index was not loaded when this reader was created")); } +} - void TermInfosReader::ensureIndexIsRead() - { - if (!indexTerms) - boost::throw_exception(IllegalStateException(L"terms index was not loaded when this reader was created")); +int64_t TermInfosReader::getPosition(const TermPtr& term) { + if (_size == 0) { + return -1; } - int64_t TermInfosReader::getPosition(const TermPtr& term) - { - if (_size == 0) - return -1; + ensureIndexIsRead(); + int32_t indexOffset = getIndexOffset(term); - ensureIndexIsRead(); - int32_t indexOffset = getIndexOffset(term); + SegmentTermEnumPtr enumerator(getThreadResources()->termEnum); + seekEnum(enumerator, indexOffset); - SegmentTermEnumPtr enumerator(getThreadResources()->termEnum); - seekEnum(enumerator, indexOffset); + while (term->compareTo(enumerator->term()) > 0 && enumerator->next()) { + } - while (term->compareTo(enumerator->term()) > 0 && enumerator->next()) - { - } + return term->compareTo(enumerator->term()) == 0 ? enumerator->position : -1; +} - return term->compareTo(enumerator->term()) == 0 ? enumerator->position : -1; - } +SegmentTermEnumPtr TermInfosReader::terms() { + return boost::static_pointer_cast(origEnum->clone()); +} - SegmentTermEnumPtr TermInfosReader::terms() - { - return boost::static_pointer_cast(origEnum->clone()); - } +SegmentTermEnumPtr TermInfosReader::terms(const TermPtr& term) { + // don't use the cache in this call because we want to reposition the enumeration + get(term, false); + return boost::static_pointer_cast(getThreadResources()->termEnum->clone()); +} - SegmentTermEnumPtr TermInfosReader::terms(const TermPtr& term) - { - // don't use the cache in this call because we want to reposition the enumeration - get(term, false); - return boost::static_pointer_cast(getThreadResources()->termEnum->clone()); - } +TermInfosReaderThreadResources::~TermInfosReaderThreadResources() { +} - TermInfosReaderThreadResources::~TermInfosReaderThreadResources() - { - } } diff --git a/src/core/index/TermInfosWriter.cpp b/src/core/index/TermInfosWriter.cpp index 33e04551..02f7d901 100644 --- a/src/core/index/TermInfosWriter.cpp +++ b/src/core/index/TermInfosWriter.cpp @@ -15,166 +15,158 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// The file format version, a negative number. - const int32_t TermInfosWriter::FORMAT = -3; +namespace Lucene { - /// Changed strings to true utf8 with length-in-bytes not length-in-chars. - const int32_t TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES = -4; +/// The file format version, a negative number. +const int32_t TermInfosWriter::FORMAT = -3; - /// NOTE: always change this if you switch to a new format. - const int32_t TermInfosWriter::FORMAT_CURRENT = TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; +/// Changed strings to true utf8 with length-in-bytes not length-in-chars. +const int32_t TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES = -4; - TermInfosWriter::TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval) - { - initialize(directory, segment, fis, interval, false); - otherWriter = newLucene(directory, segment, fis, interval, true); - } +/// NOTE: always change this if you switch to a new format. +const int32_t TermInfosWriter::FORMAT_CURRENT = TermInfosWriter::FORMAT_VERSION_UTF8_LENGTH_IN_BYTES; - TermInfosWriter::TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isIndex) - { - initialize(directory, segment, fis, interval, isIndex); - } +TermInfosWriter::TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval) { + initialize(directory, segment, fis, interval, false); + otherWriter = newLucene(directory, segment, fis, interval, true); +} - TermInfosWriter::~TermInfosWriter() - { - } +TermInfosWriter::TermInfosWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isIndex) { + initialize(directory, segment, fis, interval, isIndex); +} - void TermInfosWriter::initialize() - { - if (otherWriter) - { - _other = otherWriter; - otherWriter->_other = shared_from_this(); - } - } +TermInfosWriter::~TermInfosWriter() { +} - void TermInfosWriter::initialize(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isi) - { - lastTi = newLucene(); - utf8Result = newLucene(); - lastTermBytes = ByteArray::newInstance(10); - lastTermBytesLength = 0; - lastFieldNumber = -1; - skipInterval = 16; - maxSkipLevels = 10; - size = 0; - lastIndexPointer = 0; - - indexInterval = interval; - fieldInfos = fis; - isIndex = isi; - output = directory->createOutput(segment + (isIndex ? L".tii" : L".tis")); - output->writeInt(FORMAT_CURRENT); // write format - output->writeLong(0); // leave space for size - output->writeInt(indexInterval); // write indexInterval - output->writeInt(skipInterval); // write skipInterval - output->writeInt(maxSkipLevels); // write maxSkipLevels - BOOST_ASSERT(initUnicodeResults()); +void TermInfosWriter::initialize() { + if (otherWriter) { + _other = otherWriter; + otherWriter->_other = shared_from_this(); } +} - void TermInfosWriter::add(const TermPtr& term, const TermInfoPtr& ti) - { - StringUtils::toUTF8(term->_text.c_str(), term->_text.size(), utf8Result); - add(fieldInfos->fieldNumber(term->_field), utf8Result->result, utf8Result->length, ti); - } +void TermInfosWriter::initialize(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fis, int32_t interval, bool isi) { + lastTi = newLucene(); + utf8Result = newLucene(); + lastTermBytes = ByteArray::newInstance(10); + lastTermBytesLength = 0; + lastFieldNumber = -1; + skipInterval = 16; + maxSkipLevels = 10; + size = 0; + lastIndexPointer = 0; + + indexInterval = interval; + fieldInfos = fis; + isIndex = isi; + output = directory->createOutput(segment + (isIndex ? L".tii" : L".tis")); + output->writeInt(FORMAT_CURRENT); // write format + output->writeLong(0); // leave space for size + output->writeInt(indexInterval); // write indexInterval + output->writeInt(skipInterval); // write skipInterval + output->writeInt(maxSkipLevels); // write maxSkipLevels + BOOST_ASSERT(initUnicodeResults()); +} - bool TermInfosWriter::initUnicodeResults() - { - unicodeResult1 = newLucene(); - unicodeResult2 = newLucene(); - return true; - } +void TermInfosWriter::add(const TermPtr& term, const TermInfoPtr& ti) { + StringUtils::toUTF8(term->_text.c_str(), term->_text.size(), utf8Result); + add(fieldInfos->fieldNumber(term->_field), utf8Result->result, utf8Result->length, ti); +} - int32_t TermInfosWriter::compareToLastTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength) - { - if (lastFieldNumber != fieldNumber) - { - int32_t cmp = fieldInfos->fieldName(lastFieldNumber).compare(fieldInfos->fieldName(fieldNumber)); - // If there is a field named "" (empty string) then we will get 0 on this comparison, yet, it's "OK". - // But it's not OK if two different field numbers map to the same name. - if (cmp != 0 || lastFieldNumber != -1) - return cmp; +bool TermInfosWriter::initUnicodeResults() { + unicodeResult1 = newLucene(); + unicodeResult2 = newLucene(); + return true; +} + +int32_t TermInfosWriter::compareToLastTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength) { + if (lastFieldNumber != fieldNumber) { + int32_t cmp = fieldInfos->fieldName(lastFieldNumber).compare(fieldInfos->fieldName(fieldNumber)); + // If there is a field named "" (empty string) then we will get 0 on this comparison, yet, it's "OK". + // But it's not OK if two different field numbers map to the same name. + if (cmp != 0 || lastFieldNumber != -1) { + return cmp; } + } - StringUtils::toUnicode(lastTermBytes.get(), lastTermBytesLength, unicodeResult1); - StringUtils::toUnicode(termBytes.get(), termBytesLength, unicodeResult2); - int32_t len = std::min(unicodeResult1->length, unicodeResult2->length); + StringUtils::toUnicode(lastTermBytes.get(), lastTermBytesLength, unicodeResult1); + StringUtils::toUnicode(termBytes.get(), termBytesLength, unicodeResult2); + int32_t len = std::min(unicodeResult1->length, unicodeResult2->length); - for (int32_t i = 0; i < len; ++i) - { - wchar_t ch1 = unicodeResult1->result[i]; - wchar_t ch2 = unicodeResult2->result[i]; - if (ch1 != ch2) - return (ch1 - ch2); + for (int32_t i = 0; i < len; ++i) { + wchar_t ch1 = unicodeResult1->result[i]; + wchar_t ch2 = unicodeResult2->result[i]; + if (ch1 != ch2) { + return (ch1 - ch2); } - return (unicodeResult1->length - unicodeResult2->length); } + return (unicodeResult1->length - unicodeResult2->length); +} - void TermInfosWriter::add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, const TermInfoPtr& ti) - { - // terms out of order? - BOOST_ASSERT(compareToLastTerm(fieldNumber, termBytes, termBytesLength) < 0 || (isIndex && termBytesLength == 0 && lastTermBytesLength == 0)); - - BOOST_ASSERT(ti->freqPointer >= lastTi->freqPointer); // freqPointer out of order? - BOOST_ASSERT(ti->proxPointer >= lastTi->proxPointer); // proxPointer out of order? +void TermInfosWriter::add(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength, const TermInfoPtr& ti) { + // terms out of order? + BOOST_ASSERT(compareToLastTerm(fieldNumber, termBytes, termBytesLength) < 0 || (isIndex && termBytesLength == 0 && lastTermBytesLength == 0)); - TermInfosWriterPtr other(_other); + BOOST_ASSERT(ti->freqPointer >= lastTi->freqPointer); // freqPointer out of order? + BOOST_ASSERT(ti->proxPointer >= lastTi->proxPointer); // proxPointer out of order? - if (!isIndex && size % indexInterval == 0) - other->add(lastFieldNumber, lastTermBytes, lastTermBytesLength, lastTi); // add an index term + TermInfosWriterPtr other(_other); - writeTerm(fieldNumber, termBytes, termBytesLength); // write term + if (!isIndex && size % indexInterval == 0) { + other->add(lastFieldNumber, lastTermBytes, lastTermBytesLength, lastTi); // add an index term + } - output->writeVInt(ti->docFreq); // write doc freq - output->writeVLong(ti->freqPointer - lastTi->freqPointer); // write pointers - output->writeVLong(ti->proxPointer - lastTi->proxPointer); + writeTerm(fieldNumber, termBytes, termBytesLength); // write term - if (ti->docFreq >= skipInterval) - output->writeVInt(ti->skipOffset); + output->writeVInt(ti->docFreq); // write doc freq + output->writeVLong(ti->freqPointer - lastTi->freqPointer); // write pointers + output->writeVLong(ti->proxPointer - lastTi->proxPointer); - if (isIndex) - { - output->writeVLong(other->output->getFilePointer() - lastIndexPointer); - lastIndexPointer = other->output->getFilePointer(); // write pointer - } + if (ti->docFreq >= skipInterval) { + output->writeVInt(ti->skipOffset); + } - lastFieldNumber = fieldNumber; - lastTi->set(ti); - ++size; + if (isIndex) { + output->writeVLong(other->output->getFilePointer() - lastIndexPointer); + lastIndexPointer = other->output->getFilePointer(); // write pointer } - void TermInfosWriter::writeTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength) - { - // Compute prefix in common with last term - int32_t start = 0; - int32_t limit = std::min(termBytesLength, lastTermBytesLength); - while (start < limit) - { - if (termBytes[start] != lastTermBytes[start]) - break; - ++start; + lastFieldNumber = fieldNumber; + lastTi->set(ti); + ++size; +} + +void TermInfosWriter::writeTerm(int32_t fieldNumber, ByteArray termBytes, int32_t termBytesLength) { + // Compute prefix in common with last term + int32_t start = 0; + int32_t limit = std::min(termBytesLength, lastTermBytesLength); + while (start < limit) { + if (termBytes[start] != lastTermBytes[start]) { + break; } + ++start; + } - int32_t length = termBytesLength - start; - output->writeVInt(start); // write shared prefix length - output->writeVInt(length); // write delta length - output->writeBytes(termBytes.get(), start, length); // write delta bytes - output->writeVInt(fieldNumber); // write field num - if (lastTermBytes.size() < termBytesLength) - lastTermBytes.resize((int32_t)((double)termBytesLength * 1.5)); - MiscUtils::arrayCopy(termBytes.get(), start, lastTermBytes.get(), start, length); - lastTermBytesLength = termBytesLength; + int32_t length = termBytesLength - start; + output->writeVInt(start); // write shared prefix length + output->writeVInt(length); // write delta length + output->writeBytes(termBytes.get(), start, length); // write delta bytes + output->writeVInt(fieldNumber); // write field num + if (lastTermBytes.size() < termBytesLength) { + lastTermBytes.resize((int32_t)((double)termBytesLength * 1.5)); } + MiscUtils::arrayCopy(termBytes.get(), start, lastTermBytes.get(), start, length); + lastTermBytesLength = termBytesLength; +} - void TermInfosWriter::close() - { - output->seek(4); // write size after format - output->writeLong(size); - output->close(); +void TermInfosWriter::close() { + output->seek(4); // write size after format + output->writeLong(size); + output->close(); - if (!isIndex) - TermInfosWriterPtr(_other)->close(); + if (!isIndex) { + TermInfosWriterPtr(_other)->close(); } } + +} diff --git a/src/core/index/TermPositionVector.cpp b/src/core/index/TermPositionVector.cpp index 6636dd51..8d7114f4 100644 --- a/src/core/index/TermPositionVector.cpp +++ b/src/core/index/TermPositionVector.cpp @@ -7,25 +7,22 @@ #include "LuceneInc.h" #include "TermPositionVector.h" -namespace Lucene -{ - TermPositionVector::TermPositionVector() - { - } +namespace Lucene { - TermPositionVector::~TermPositionVector() - { - } +TermPositionVector::TermPositionVector() { +} + +TermPositionVector::~TermPositionVector() { +} - Collection TermPositionVector::getTermPositions(int32_t index) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection TermPositionVector::getTermPositions(int32_t index) { + BOOST_ASSERT(false); + return Collection(); // override +} + +Collection TermPositionVector::getOffsets(int32_t index) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection TermPositionVector::getOffsets(int32_t index) - { - BOOST_ASSERT(false); - return Collection(); // override - } } diff --git a/src/core/index/TermPositions.cpp b/src/core/index/TermPositions.cpp index 3703996e..c0856ae1 100644 --- a/src/core/index/TermPositions.cpp +++ b/src/core/index/TermPositions.cpp @@ -7,37 +7,32 @@ #include "LuceneInc.h" #include "TermPositions.h" -namespace Lucene -{ - TermPositions::TermPositions() - { - } - - TermPositions::~TermPositions() - { - } - - int32_t TermPositions::nextPosition() - { - BOOST_ASSERT(false); - return 0; // override - } - - int32_t TermPositions::getPayloadLength() - { - BOOST_ASSERT(false); - return 0; // override - } - - ByteArray TermPositions::getPayload(ByteArray data, int32_t offset) - { - BOOST_ASSERT(false); - return ByteArray(); // override - } - - bool TermPositions::isPayloadAvailable() - { - BOOST_ASSERT(false); - return false; // override - } +namespace Lucene { + +TermPositions::TermPositions() { +} + +TermPositions::~TermPositions() { +} + +int32_t TermPositions::nextPosition() { + BOOST_ASSERT(false); + return 0; // override +} + +int32_t TermPositions::getPayloadLength() { + BOOST_ASSERT(false); + return 0; // override +} + +ByteArray TermPositions::getPayload(ByteArray data, int32_t offset) { + BOOST_ASSERT(false); + return ByteArray(); // override +} + +bool TermPositions::isPayloadAvailable() { + BOOST_ASSERT(false); + return false; // override +} + } diff --git a/src/core/index/TermVectorEntry.cpp b/src/core/index/TermVectorEntry.cpp index 8f6a7829..bea5b9cf 100644 --- a/src/core/index/TermVectorEntry.cpp +++ b/src/core/index/TermVectorEntry.cpp @@ -8,85 +8,75 @@ #include "TermVectorEntry.h" #include "StringUtils.h" -namespace Lucene -{ - TermVectorEntry::TermVectorEntry(const String& field, const String& term, int32_t frequency, - Collection offsets, Collection positions) - { - this->field = field; - this->term = term; - this->frequency = frequency; - this->offsets = offsets; - this->positions = positions; - } +namespace Lucene { + +TermVectorEntry::TermVectorEntry(const String& field, const String& term, int32_t frequency, + Collection offsets, Collection positions) { + this->field = field; + this->term = term; + this->frequency = frequency; + this->offsets = offsets; + this->positions = positions; +} - TermVectorEntry::~TermVectorEntry() - { - } +TermVectorEntry::~TermVectorEntry() { +} - String TermVectorEntry::getField() - { - return field; - } +String TermVectorEntry::getField() { + return field; +} - int32_t TermVectorEntry::getFrequency() - { - return frequency; - } +int32_t TermVectorEntry::getFrequency() { + return frequency; +} - Collection TermVectorEntry::getOffsets() - { - return offsets; - } +Collection TermVectorEntry::getOffsets() { + return offsets; +} - Collection TermVectorEntry::getPositions() - { - return positions; - } +Collection TermVectorEntry::getPositions() { + return positions; +} - String TermVectorEntry::getTerm() - { - return term; - } +String TermVectorEntry::getTerm() { + return term; +} - void TermVectorEntry::setFrequency(int32_t frequency) - { - this->frequency = frequency; - } +void TermVectorEntry::setFrequency(int32_t frequency) { + this->frequency = frequency; +} - void TermVectorEntry::setOffsets(Collection offsets) - { - this->offsets = offsets; - } +void TermVectorEntry::setOffsets(Collection offsets) { + this->offsets = offsets; +} - void TermVectorEntry::setPositions(Collection positions) - { - this->positions = positions; +void TermVectorEntry::setPositions(Collection positions) { + this->positions = positions; +} + +bool TermVectorEntry::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - bool TermVectorEntry::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; + TermVectorEntryPtr otherTermVectorEntry(boost::dynamic_pointer_cast(other)); + if (otherTermVectorEntry) { + return (term == otherTermVectorEntry->term); + } - TermVectorEntryPtr otherTermVectorEntry(boost::dynamic_pointer_cast(other)); - if (otherTermVectorEntry) - return (term == otherTermVectorEntry->term); + return false; +} - return false; - } +int32_t TermVectorEntry::hashCode() { + return StringUtils::hashCode(term); +} - int32_t TermVectorEntry::hashCode() - { - return StringUtils::hashCode(term); - } +String TermVectorEntry::toString() { + StringStream buffer; + buffer << L"TermVectorEntry{field='" << field; + buffer << L"\', term='" << term; + buffer << L"\', frequency=" << frequency << L"}"; + return buffer.str(); +} - String TermVectorEntry::toString() - { - StringStream buffer; - buffer << L"TermVectorEntry{field='" << field; - buffer << L"\', term='" << term; - buffer << L"\', frequency=" << frequency << L"}"; - return buffer.str(); - } } diff --git a/src/core/index/TermVectorEntryFreqSortedComparator.cpp b/src/core/index/TermVectorEntryFreqSortedComparator.cpp index 6ae03964..669a73cf 100644 --- a/src/core/index/TermVectorEntryFreqSortedComparator.cpp +++ b/src/core/index/TermVectorEntryFreqSortedComparator.cpp @@ -8,24 +8,27 @@ #include "TermVectorEntryFreqSortedComparator.h" #include "TermVectorEntry.h" -namespace Lucene -{ - TermVectorEntryFreqSortedComparator::~TermVectorEntryFreqSortedComparator() - { - } +namespace Lucene { + +TermVectorEntryFreqSortedComparator::~TermVectorEntryFreqSortedComparator() { +} - bool TermVectorEntryFreqSortedComparator::compare(const TermVectorEntryPtr& first, const TermVectorEntryPtr& second) - { - int32_t result = (second->getFrequency() - first->getFrequency()); - if (result < 0) - return true; - if (result > 0) - return false; - result = first->getTerm().compare(second->getTerm()); - if (result < 0) - return true; - if (result > 0) - return false; - return (first->getField().compare(second->getField()) < 0); +bool TermVectorEntryFreqSortedComparator::compare(const TermVectorEntryPtr& first, const TermVectorEntryPtr& second) { + int32_t result = (second->getFrequency() - first->getFrequency()); + if (result < 0) { + return true; + } + if (result > 0) { + return false; } + result = first->getTerm().compare(second->getTerm()); + if (result < 0) { + return true; + } + if (result > 0) { + return false; + } + return (first->getField().compare(second->getField()) < 0); +} + } diff --git a/src/core/index/TermVectorMapper.cpp b/src/core/index/TermVectorMapper.cpp index 70c7179f..ae18c019 100644 --- a/src/core/index/TermVectorMapper.cpp +++ b/src/core/index/TermVectorMapper.cpp @@ -7,30 +7,26 @@ #include "LuceneInc.h" #include "TermVectorMapper.h" -namespace Lucene -{ - TermVectorMapper::TermVectorMapper(bool ignoringPositions, bool ignoringOffsets) - { - this->ignoringPositions = ignoringPositions; - this->ignoringOffsets = ignoringOffsets; - } - - TermVectorMapper::~TermVectorMapper() - { - } - - bool TermVectorMapper::isIgnoringPositions() - { - return ignoringPositions; - } - - bool TermVectorMapper::isIgnoringOffsets() - { - return ignoringOffsets; - } - - void TermVectorMapper::setDocumentNumber(int32_t documentNumber) - { - // override - } +namespace Lucene { + +TermVectorMapper::TermVectorMapper(bool ignoringPositions, bool ignoringOffsets) { + this->ignoringPositions = ignoringPositions; + this->ignoringOffsets = ignoringOffsets; +} + +TermVectorMapper::~TermVectorMapper() { +} + +bool TermVectorMapper::isIgnoringPositions() { + return ignoringPositions; +} + +bool TermVectorMapper::isIgnoringOffsets() { + return ignoringOffsets; +} + +void TermVectorMapper::setDocumentNumber(int32_t documentNumber) { + // override +} + } diff --git a/src/core/index/TermVectorOffsetInfo.cpp b/src/core/index/TermVectorOffsetInfo.cpp index 36979a41..66d34652 100644 --- a/src/core/index/TermVectorOffsetInfo.cpp +++ b/src/core/index/TermVectorOffsetInfo.cpp @@ -7,59 +7,54 @@ #include "LuceneInc.h" #include "TermVectorOffsetInfo.h" -namespace Lucene -{ - TermVectorOffsetInfo::TermVectorOffsetInfo(int32_t startOffset, int32_t endOffset) - { - this->endOffset = endOffset; - this->startOffset = startOffset; - } +namespace Lucene { - TermVectorOffsetInfo::~TermVectorOffsetInfo() - { - } +TermVectorOffsetInfo::TermVectorOffsetInfo(int32_t startOffset, int32_t endOffset) { + this->endOffset = endOffset; + this->startOffset = startOffset; +} - const Collection TermVectorOffsetInfo::EMPTY_OFFSET_INFO() - { - static Collection _EMPTY_OFFSET_INFO; - if (!_EMPTY_OFFSET_INFO) - _EMPTY_OFFSET_INFO = Collection::newInstance(); - return _EMPTY_OFFSET_INFO; - } +TermVectorOffsetInfo::~TermVectorOffsetInfo() { +} - int32_t TermVectorOffsetInfo::getEndOffset() - { - return endOffset; +const Collection TermVectorOffsetInfo::EMPTY_OFFSET_INFO() { + static Collection _EMPTY_OFFSET_INFO; + if (!_EMPTY_OFFSET_INFO) { + _EMPTY_OFFSET_INFO = Collection::newInstance(); } + return _EMPTY_OFFSET_INFO; +} - void TermVectorOffsetInfo::setEndOffset(int32_t endOffset) - { - this->endOffset = endOffset; - } +int32_t TermVectorOffsetInfo::getEndOffset() { + return endOffset; +} - int32_t TermVectorOffsetInfo::getStartOffset() - { - return startOffset; - } +void TermVectorOffsetInfo::setEndOffset(int32_t endOffset) { + this->endOffset = endOffset; +} - void TermVectorOffsetInfo::setStartOffset(int32_t startOffset) - { - this->startOffset = startOffset; - } +int32_t TermVectorOffsetInfo::getStartOffset() { + return startOffset; +} - bool TermVectorOffsetInfo::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - TermVectorOffsetInfoPtr otherTermVector(boost::dynamic_pointer_cast(other)); - if (!otherTermVector) - return false; - return (endOffset == otherTermVector->endOffset && startOffset == otherTermVector->startOffset); - } +void TermVectorOffsetInfo::setStartOffset(int32_t startOffset) { + this->startOffset = startOffset; +} - int32_t TermVectorOffsetInfo::hashCode() - { - int32_t result = startOffset; - return (29 * result + endOffset); +bool TermVectorOffsetInfo::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + TermVectorOffsetInfoPtr otherTermVector(boost::dynamic_pointer_cast(other)); + if (!otherTermVector) { + return false; } + return (endOffset == otherTermVector->endOffset && startOffset == otherTermVector->startOffset); +} + +int32_t TermVectorOffsetInfo::hashCode() { + int32_t result = startOffset; + return (29 * result + endOffset); +} + } diff --git a/src/core/index/TermVectorsReader.cpp b/src/core/index/TermVectorsReader.cpp index 48d74861..488de775 100644 --- a/src/core/index/TermVectorsReader.cpp +++ b/src/core/index/TermVectorsReader.cpp @@ -15,599 +15,531 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// NOTE: if you make a new format, it must be larger than the current format - const int32_t TermVectorsReader::FORMAT_VERSION = 2; +namespace Lucene { - /// Changes to speed up bulk merging of term vectors - const int32_t TermVectorsReader::FORMAT_VERSION2 = 3; +/// NOTE: if you make a new format, it must be larger than the current format +const int32_t TermVectorsReader::FORMAT_VERSION = 2; - /// Changed strings to UTF8 with length-in-bytes not length-in-chars - const int32_t TermVectorsReader::FORMAT_UTF8_LENGTH_IN_BYTES = 4; +/// Changes to speed up bulk merging of term vectors +const int32_t TermVectorsReader::FORMAT_VERSION2 = 3; - /// NOTE: always change this if you switch to a new format - const int32_t TermVectorsReader::FORMAT_CURRENT = TermVectorsReader::FORMAT_UTF8_LENGTH_IN_BYTES; +/// Changed strings to UTF8 with length-in-bytes not length-in-chars +const int32_t TermVectorsReader::FORMAT_UTF8_LENGTH_IN_BYTES = 4; - /// The size in bytes that the FORMAT_VERSION will take up at the beginning of each file - const int32_t TermVectorsReader::FORMAT_SIZE = 4; +/// NOTE: always change this if you switch to a new format +const int32_t TermVectorsReader::FORMAT_CURRENT = TermVectorsReader::FORMAT_UTF8_LENGTH_IN_BYTES; - const uint8_t TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR = 0x1; - const uint8_t TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR = 0x2; +/// The size in bytes that the FORMAT_VERSION will take up at the beginning of each file +const int32_t TermVectorsReader::FORMAT_SIZE = 4; - TermVectorsReader::TermVectorsReader() - { - this->_size = 0; - this->numTotalDocs = 0; - this->docStoreOffset = 0; - this->format = 0; - } +const uint8_t TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR = 0x1; +const uint8_t TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR = 0x2; - TermVectorsReader::TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos) - { - ConstructReader(d, segment, fieldInfos, BufferedIndexInput::BUFFER_SIZE, -1, 0); - } +TermVectorsReader::TermVectorsReader() { + this->_size = 0; + this->numTotalDocs = 0; + this->docStoreOffset = 0; + this->format = 0; +} - TermVectorsReader::TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) - { - ConstructReader(d, segment, fieldInfos, readBufferSize, docStoreOffset, size); - } +TermVectorsReader::TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos) { + ConstructReader(d, segment, fieldInfos, BufferedIndexInput::BUFFER_SIZE, -1, 0); +} - TermVectorsReader::~TermVectorsReader() - { - } +TermVectorsReader::TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { + ConstructReader(d, segment, fieldInfos, readBufferSize, docStoreOffset, size); +} - void TermVectorsReader::ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) - { - this->_size = 0; - this->numTotalDocs = 0; - this->docStoreOffset = 0; - this->format = 0; - - bool success = false; - LuceneException finally; - try - { - if (d->fileExists(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION())) - { - tvx = d->openInput(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION(), readBufferSize); - format = checkValidFormat(tvx); - tvd = d->openInput(segment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION(), readBufferSize); - int32_t tvdFormat = checkValidFormat(tvd); - tvf = d->openInput(segment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION(), readBufferSize); - int32_t tvfFormat = checkValidFormat(tvf); - - BOOST_ASSERT(format == tvdFormat); - BOOST_ASSERT(format == tvfFormat); - - if (format >= FORMAT_VERSION2) - { - BOOST_ASSERT((tvx->length() - FORMAT_SIZE) % 16 == 0); - numTotalDocs = (int32_t)(tvx->length() >> 4); - } - else - { - BOOST_ASSERT((tvx->length() - FORMAT_SIZE) % 8 == 0); - numTotalDocs = (int32_t)(tvx->length() >> 3); - } +TermVectorsReader::~TermVectorsReader() { +} - if (docStoreOffset == -1) - { - this->docStoreOffset = 0; - this->_size = numTotalDocs; - BOOST_ASSERT(size == 0 || numTotalDocs == size); - } - else - { - this->docStoreOffset = docStoreOffset; - this->_size = size; - // Verify the file is long enough to hold all of our docs - BOOST_ASSERT(numTotalDocs >= size + docStoreOffset); - } - } - else - { - // If all documents flushed in a segment had hit non-aborting exceptions, it's possible that - // FieldInfos.hasVectors returns true yet the term vector files don't exist. - format = 0; +void TermVectorsReader::ConstructReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos, int32_t readBufferSize, int32_t docStoreOffset, int32_t size) { + this->_size = 0; + this->numTotalDocs = 0; + this->docStoreOffset = 0; + this->format = 0; + + bool success = false; + LuceneException finally; + try { + if (d->fileExists(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION())) { + tvx = d->openInput(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION(), readBufferSize); + format = checkValidFormat(tvx); + tvd = d->openInput(segment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION(), readBufferSize); + int32_t tvdFormat = checkValidFormat(tvd); + tvf = d->openInput(segment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION(), readBufferSize); + int32_t tvfFormat = checkValidFormat(tvf); + + BOOST_ASSERT(format == tvdFormat); + BOOST_ASSERT(format == tvfFormat); + + if (format >= FORMAT_VERSION2) { + BOOST_ASSERT((tvx->length() - FORMAT_SIZE) % 16 == 0); + numTotalDocs = (int32_t)(tvx->length() >> 4); + } else { + BOOST_ASSERT((tvx->length() - FORMAT_SIZE) % 8 == 0); + numTotalDocs = (int32_t)(tvx->length() >> 3); } - this->fieldInfos = fieldInfos; - success = true; - } - catch (LuceneException& e) - { - finally = e; + if (docStoreOffset == -1) { + this->docStoreOffset = 0; + this->_size = numTotalDocs; + BOOST_ASSERT(size == 0 || numTotalDocs == size); + } else { + this->docStoreOffset = docStoreOffset; + this->_size = size; + // Verify the file is long enough to hold all of our docs + BOOST_ASSERT(numTotalDocs >= size + docStoreOffset); + } + } else { + // If all documents flushed in a segment had hit non-aborting exceptions, it's possible that + // FieldInfos.hasVectors returns true yet the term vector files don't exist. + format = 0; } - // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception - // above. In this case, we want to explicitly close any subset of things that were opened. - if (!success) - close(); - finally.throwException(); + this->fieldInfos = fieldInfos; + success = true; + } catch (LuceneException& e) { + finally = e; } - IndexInputPtr TermVectorsReader::getTvdStream() - { - return tvd; + // With lock-less commits, it's entirely possible (and fine) to hit a FileNotFound exception + // above. In this case, we want to explicitly close any subset of things that were opened. + if (!success) { + close(); } + finally.throwException(); +} + +IndexInputPtr TermVectorsReader::getTvdStream() { + return tvd; +} - IndexInputPtr TermVectorsReader::getTvfStream() - { - return tvf; +IndexInputPtr TermVectorsReader::getTvfStream() { + return tvf; +} + +void TermVectorsReader::seekTvx(int32_t docNum) { + if (format < FORMAT_VERSION2) { + tvx->seek((docNum + docStoreOffset) * 8 + FORMAT_SIZE); + } else { + tvx->seek((docNum + docStoreOffset) * 16 + FORMAT_SIZE); } +} - void TermVectorsReader::seekTvx(int32_t docNum) - { - if (format < FORMAT_VERSION2) - tvx->seek((docNum + docStoreOffset) * 8 + FORMAT_SIZE); - else - tvx->seek((docNum + docStoreOffset) * 16 + FORMAT_SIZE); +bool TermVectorsReader::canReadRawDocs() { + return (format >= FORMAT_UTF8_LENGTH_IN_BYTES); +} + +void TermVectorsReader::rawDocs(Collection tvdLengths, Collection tvfLengths, int32_t startDocID, int32_t numDocs) { + if (!tvx) { + MiscUtils::arrayFill(tvdLengths.begin(), 0, tvdLengths.size(), 0); + MiscUtils::arrayFill(tvfLengths.begin(), 0, tvfLengths.size(), 0); + return; } - bool TermVectorsReader::canReadRawDocs() - { - return (format >= FORMAT_UTF8_LENGTH_IN_BYTES); + // SegmentMerger calls canReadRawDocs() first and should not call us if that returns false. + if (format < FORMAT_VERSION2) { + boost::throw_exception(IllegalStateException(L"cannot read raw docs with older term vector formats")); } - void TermVectorsReader::rawDocs(Collection tvdLengths, Collection tvfLengths, int32_t startDocID, int32_t numDocs) - { - if (!tvx) - { - MiscUtils::arrayFill(tvdLengths.begin(), 0, tvdLengths.size(), 0); - MiscUtils::arrayFill(tvfLengths.begin(), 0, tvfLengths.size(), 0); - return; - } + seekTvx(startDocID); - // SegmentMerger calls canReadRawDocs() first and should not call us if that returns false. - if (format < FORMAT_VERSION2) - boost::throw_exception(IllegalStateException(L"cannot read raw docs with older term vector formats")); + int64_t tvdPosition = tvx->readLong(); + tvd->seek(tvdPosition); - seekTvx(startDocID); + int64_t tvfPosition = tvx->readLong(); + tvf->seek(tvfPosition); - int64_t tvdPosition = tvx->readLong(); - tvd->seek(tvdPosition); + int64_t lastTvdPosition = tvdPosition; + int64_t lastTvfPosition = tvfPosition; - int64_t tvfPosition = tvx->readLong(); - tvf->seek(tvfPosition); - - int64_t lastTvdPosition = tvdPosition; - int64_t lastTvfPosition = tvfPosition; - - int32_t count = 0; - while (count < numDocs) - { - int32_t docID = docStoreOffset + startDocID + count + 1; - BOOST_ASSERT(docID <= numTotalDocs); - if (docID < numTotalDocs) - { - tvdPosition = tvx->readLong(); - tvfPosition = tvx->readLong(); - } - else - { - tvdPosition = tvd->length(); - tvfPosition = tvf->length(); - BOOST_ASSERT(count == numDocs - 1); - } - tvdLengths[count] = (int32_t)(tvdPosition - lastTvdPosition); - tvfLengths[count] = (int32_t)(tvfPosition - lastTvfPosition); - ++count; - lastTvdPosition = tvdPosition; - lastTvfPosition = tvfPosition; + int32_t count = 0; + while (count < numDocs) { + int32_t docID = docStoreOffset + startDocID + count + 1; + BOOST_ASSERT(docID <= numTotalDocs); + if (docID < numTotalDocs) { + tvdPosition = tvx->readLong(); + tvfPosition = tvx->readLong(); + } else { + tvdPosition = tvd->length(); + tvfPosition = tvf->length(); + BOOST_ASSERT(count == numDocs - 1); } + tvdLengths[count] = (int32_t)(tvdPosition - lastTvdPosition); + tvfLengths[count] = (int32_t)(tvfPosition - lastTvfPosition); + ++count; + lastTvdPosition = tvdPosition; + lastTvfPosition = tvfPosition; } +} - int32_t TermVectorsReader::checkValidFormat(const IndexInputPtr& in) - { - int32_t format = in->readInt(); - if (format > FORMAT_CURRENT) - { - boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + - StringUtils::toString(format) + L" expected " + - StringUtils::toString(FORMAT_CURRENT) + L" or less")); - } - return format; +int32_t TermVectorsReader::checkValidFormat(const IndexInputPtr& in) { + int32_t format = in->readInt(); + if (format > FORMAT_CURRENT) { + boost::throw_exception(CorruptIndexException(L"Incompatible format version: " + + StringUtils::toString(format) + L" expected " + + StringUtils::toString(FORMAT_CURRENT) + L" or less")); } + return format; +} - void TermVectorsReader::close() - { - // make all effort to close up. Keep the first exception and throw it as a new one. - LuceneException keep; - if (tvx) - { - try - { - tvx->close(); - } - catch (LuceneException& e) - { - if (keep.isNull()) - keep = e; +void TermVectorsReader::close() { + // make all effort to close up. Keep the first exception and throw it as a new one. + LuceneException keep; + if (tvx) { + try { + tvx->close(); + } catch (LuceneException& e) { + if (keep.isNull()) { + keep = e; } } - if (tvd) - { - try - { - tvd->close(); - } - catch (LuceneException& e) - { - if (keep.isNull()) - keep = e; + } + if (tvd) { + try { + tvd->close(); + } catch (LuceneException& e) { + if (keep.isNull()) { + keep = e; } } - if (tvf) - { - try - { - tvf->close(); - } - catch (LuceneException& e) - { - if (keep.isNull()) - keep = e; + } + if (tvf) { + try { + tvf->close(); + } catch (LuceneException& e) { + if (keep.isNull()) { + keep = e; } } - keep.throwException(); } + keep.throwException(); +} - int32_t TermVectorsReader::size() - { - return _size; - } +int32_t TermVectorsReader::size() { + return _size; +} + +void TermVectorsReader::get(int32_t docNum, const String& field, const TermVectorMapperPtr& mapper) { + if (tvx) { + int32_t fieldNumber = fieldInfos->fieldNumber(field); - void TermVectorsReader::get(int32_t docNum, const String& field, const TermVectorMapperPtr& mapper) - { - if (tvx) - { - int32_t fieldNumber = fieldInfos->fieldNumber(field); - - // We need to account for the FORMAT_SIZE at when seeking in the tvx. We don't need to do - // this in other seeks because we already have the file pointer that was written in another file - seekTvx(docNum); - int64_t tvdPosition = tvx->readLong(); - - tvd->seek(tvdPosition); - int32_t fieldCount = tvd->readVInt(); - - // There are only a few fields per document. We opt for a full scan rather then requiring that they - // be ordered. We need to read through all of the fields anyway to get to the tvf pointers. - int32_t number = 0; - int32_t found = -1; - for (int32_t i = 0; i < fieldCount; ++i) - { - if (format >= FORMAT_VERSION) - number = tvd->readVInt(); - else - number += tvd->readVInt(); - - if (number == fieldNumber) - found = i; + // We need to account for the FORMAT_SIZE at when seeking in the tvx. We don't need to do + // this in other seeks because we already have the file pointer that was written in another file + seekTvx(docNum); + int64_t tvdPosition = tvx->readLong(); + + tvd->seek(tvdPosition); + int32_t fieldCount = tvd->readVInt(); + + // There are only a few fields per document. We opt for a full scan rather then requiring that they + // be ordered. We need to read through all of the fields anyway to get to the tvf pointers. + int32_t number = 0; + int32_t found = -1; + for (int32_t i = 0; i < fieldCount; ++i) { + if (format >= FORMAT_VERSION) { + number = tvd->readVInt(); + } else { + number += tvd->readVInt(); } - // This field, although valid in the segment, was not found in this document - if (found != -1) - { - // Compute position in the tvf file - int64_t position; - if (format >= FORMAT_VERSION2) - position = tvx->readLong(); - else - position = tvd->readVLong(); - for (int32_t i = 1; i <= found; ++i) - position += tvd->readVLong(); - - mapper->setDocumentNumber(docNum); - readTermVector(field, position, mapper); + if (number == fieldNumber) { + found = i; } } - } - TermFreqVectorPtr TermVectorsReader::get(int32_t docNum, const String& field) - { - // Check if no term vectors are available for this segment at all - ParallelArrayTermVectorMapperPtr mapper(newLucene()); - get(docNum, field, mapper); - return mapper->materializeVector(); + // This field, although valid in the segment, was not found in this document + if (found != -1) { + // Compute position in the tvf file + int64_t position; + if (format >= FORMAT_VERSION2) { + position = tvx->readLong(); + } else { + position = tvd->readVLong(); + } + for (int32_t i = 1; i <= found; ++i) { + position += tvd->readVLong(); + } + + mapper->setDocumentNumber(docNum); + readTermVector(field, position, mapper); + } } +} - Collection TermVectorsReader::readFields(int32_t fieldCount) - { - int32_t number = 0; - Collection fields(Collection::newInstance(fieldCount)); +TermFreqVectorPtr TermVectorsReader::get(int32_t docNum, const String& field) { + // Check if no term vectors are available for this segment at all + ParallelArrayTermVectorMapperPtr mapper(newLucene()); + get(docNum, field, mapper); + return mapper->materializeVector(); +} - for (int32_t i = 0; i < fieldCount; ++i) - { - if (format >= FORMAT_VERSION) - number = tvd->readVInt(); - else - number += tvd->readVInt(); - fields[i] = fieldInfos->fieldName(number); +Collection TermVectorsReader::readFields(int32_t fieldCount) { + int32_t number = 0; + Collection fields(Collection::newInstance(fieldCount)); + + for (int32_t i = 0; i < fieldCount; ++i) { + if (format >= FORMAT_VERSION) { + number = tvd->readVInt(); + } else { + number += tvd->readVInt(); } + fields[i] = fieldInfos->fieldName(number); + } - return fields; + return fields; +} + +Collection TermVectorsReader::readTvfPointers(int32_t fieldCount) { + // Compute position in the tvf file + int64_t position; + if (format >= FORMAT_VERSION2) { + position = tvx->readLong(); + } else { + position = tvd->readVLong(); } - Collection TermVectorsReader::readTvfPointers(int32_t fieldCount) - { - // Compute position in the tvf file - int64_t position; - if (format >= FORMAT_VERSION2) - position = tvx->readLong(); - else - position = tvd->readVLong(); - - Collection tvfPointers(Collection::newInstance(fieldCount)); - tvfPointers[0] = position; - - for (int32_t i = 1; i < fieldCount; ++i) - { - position += tvd->readVLong(); - tvfPointers[i] = position; - } + Collection tvfPointers(Collection::newInstance(fieldCount)); + tvfPointers[0] = position; - return tvfPointers; + for (int32_t i = 1; i < fieldCount; ++i) { + position += tvd->readVLong(); + tvfPointers[i] = position; } - Collection TermVectorsReader::get(int32_t docNum) - { - Collection result; - if (tvx) - { - // We need to offset by - seekTvx(docNum); - int64_t tvdPosition = tvx->readLong(); - - tvd->seek(tvdPosition); - int32_t fieldCount = tvd->readVInt(); - - // No fields are vectorized for this document - if (fieldCount != 0) - { - Collection fields(readFields(fieldCount)); - Collection tvfPointers(readTvfPointers(fieldCount)); - result = readTermVectors(docNum, fields, tvfPointers); - } + return tvfPointers; +} + +Collection TermVectorsReader::get(int32_t docNum) { + Collection result; + if (tvx) { + // We need to offset by + seekTvx(docNum); + int64_t tvdPosition = tvx->readLong(); + + tvd->seek(tvdPosition); + int32_t fieldCount = tvd->readVInt(); + + // No fields are vectorized for this document + if (fieldCount != 0) { + Collection fields(readFields(fieldCount)); + Collection tvfPointers(readTvfPointers(fieldCount)); + result = readTermVectors(docNum, fields, tvfPointers); } - return result; } + return result; +} - void TermVectorsReader::get(int32_t docNumber, const TermVectorMapperPtr& mapper) - { - // Check if no term vectors are available for this segment at all - if (tvx) - { - // We need to offset by - seekTvx(docNumber); - int64_t tvdPosition = tvx->readLong(); - - tvd->seek(tvdPosition); - int32_t fieldCount = tvd->readVInt(); - - // No fields are vectorized for this document - if (fieldCount != 0) - { - Collection fields(readFields(fieldCount)); - Collection tvfPointers(readTvfPointers(fieldCount)); - mapper->setDocumentNumber(docNumber); - readTermVectors(fields, tvfPointers, mapper); - } +void TermVectorsReader::get(int32_t docNumber, const TermVectorMapperPtr& mapper) { + // Check if no term vectors are available for this segment at all + if (tvx) { + // We need to offset by + seekTvx(docNumber); + int64_t tvdPosition = tvx->readLong(); + + tvd->seek(tvdPosition); + int32_t fieldCount = tvd->readVInt(); + + // No fields are vectorized for this document + if (fieldCount != 0) { + Collection fields(readFields(fieldCount)); + Collection tvfPointers(readTvfPointers(fieldCount)); + mapper->setDocumentNumber(docNumber); + readTermVectors(fields, tvfPointers, mapper); } } +} - Collection TermVectorsReader::readTermVectors(int32_t docNum, Collection fields, Collection tvfPointers) - { - Collection res(Collection::newInstance(fields.size())); - for (int32_t i = 0; i < fields.size(); ++i) - { - ParallelArrayTermVectorMapperPtr mapper(newLucene()); - mapper->setDocumentNumber(docNum); - readTermVector(fields[i], tvfPointers[i], mapper); - res[i] = mapper->materializeVector(); - } - return res; +Collection TermVectorsReader::readTermVectors(int32_t docNum, Collection fields, Collection tvfPointers) { + Collection res(Collection::newInstance(fields.size())); + for (int32_t i = 0; i < fields.size(); ++i) { + ParallelArrayTermVectorMapperPtr mapper(newLucene()); + mapper->setDocumentNumber(docNum); + readTermVector(fields[i], tvfPointers[i], mapper); + res[i] = mapper->materializeVector(); } + return res; +} - void TermVectorsReader::readTermVectors(Collection fields, Collection tvfPointers, const TermVectorMapperPtr& mapper) - { - for (int32_t i = 0; i < fields.size(); ++i) - readTermVector(fields[i], tvfPointers[i], mapper); +void TermVectorsReader::readTermVectors(Collection fields, Collection tvfPointers, const TermVectorMapperPtr& mapper) { + for (int32_t i = 0; i < fields.size(); ++i) { + readTermVector(fields[i], tvfPointers[i], mapper); } +} - void TermVectorsReader::readTermVector(const String& field, int64_t tvfPointer, const TermVectorMapperPtr& mapper) - { - // Now read the data from specified position. We don't need to offset by the FORMAT here since - // the pointer already includes the offset - tvf->seek(tvfPointer); +void TermVectorsReader::readTermVector(const String& field, int64_t tvfPointer, const TermVectorMapperPtr& mapper) { + // Now read the data from specified position. We don't need to offset by the FORMAT here since + // the pointer already includes the offset + tvf->seek(tvfPointer); - int32_t numTerms = tvf->readVInt(); + int32_t numTerms = tvf->readVInt(); - // If no terms - return a constant empty termvector. However, this should never occur! - if (numTerms == 0) - return; + // If no terms - return a constant empty termvector. However, this should never occur! + if (numTerms == 0) { + return; + } - bool storePositions; - bool storeOffsets; + bool storePositions; + bool storeOffsets; + + if (format >= FORMAT_VERSION) { + uint8_t bits = tvf->readByte(); + storePositions = ((bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0); + storeOffsets = ((bits & STORE_OFFSET_WITH_TERMVECTOR) != 0); + } else { + tvf->readVInt(); + storePositions = false; + storeOffsets = false; + } - if (format >= FORMAT_VERSION) - { - uint8_t bits = tvf->readByte(); - storePositions = ((bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0); - storeOffsets = ((bits & STORE_OFFSET_WITH_TERMVECTOR) != 0); - } - else - { - tvf->readVInt(); - storePositions = false; - storeOffsets = false; - } + mapper->setExpectations(field, numTerms, storeOffsets, storePositions); + int32_t start = 0; + int32_t deltaLength = 0; + int32_t totalLength = 0; + ByteArray byteBuffer; + CharArray charBuffer; + bool preUTF8 = (format < FORMAT_UTF8_LENGTH_IN_BYTES); + + // init the buffers + if (preUTF8) { + charBuffer = CharArray::newInstance(10); + byteBuffer.reset(); + } else { + charBuffer.reset(); + byteBuffer = ByteArray::newInstance(20); + } - mapper->setExpectations(field, numTerms, storeOffsets, storePositions); - int32_t start = 0; - int32_t deltaLength = 0; - int32_t totalLength = 0; - ByteArray byteBuffer; - CharArray charBuffer; - bool preUTF8 = (format < FORMAT_UTF8_LENGTH_IN_BYTES); - - // init the buffers - if (preUTF8) - { - charBuffer = CharArray::newInstance(10); - byteBuffer.reset(); - } - else - { - charBuffer.reset(); - byteBuffer = ByteArray::newInstance(20); - } + for (int32_t i = 0; i < numTerms; ++i) { + start = tvf->readVInt(); + deltaLength = tvf->readVInt(); + totalLength = start + deltaLength; + + String term; - for (int32_t i = 0; i < numTerms; ++i) - { - start = tvf->readVInt(); - deltaLength = tvf->readVInt(); - totalLength = start + deltaLength; - - String term; - - if (preUTF8) - { - // Term stored as "java chars" - if (charBuffer.size() < totalLength) - charBuffer.resize((int32_t)(1.5 * (double)totalLength)); - totalLength = start + tvf->readChars(charBuffer.get(), start, deltaLength); - term.append(charBuffer.get(), totalLength); + if (preUTF8) { + // Term stored as "java chars" + if (charBuffer.size() < totalLength) { + charBuffer.resize((int32_t)(1.5 * (double)totalLength)); } - else - { - // Term stored as utf8 bytes - if (byteBuffer.size() < totalLength) - byteBuffer.resize((int32_t)(1.5 * (double)totalLength)); - tvf->readBytes(byteBuffer.get(), start, deltaLength); - term = StringUtils::toUnicode(byteBuffer.get(), totalLength); + totalLength = start + tvf->readChars(charBuffer.get(), start, deltaLength); + term.append(charBuffer.get(), totalLength); + } else { + // Term stored as utf8 bytes + if (byteBuffer.size() < totalLength) { + byteBuffer.resize((int32_t)(1.5 * (double)totalLength)); } - int32_t freq = tvf->readVInt(); - Collection positions; - if (storePositions) // read in the positions - { - // does the mapper even care about positions? - if (!mapper->isIgnoringPositions()) - { - positions = Collection::newInstance(freq); - int32_t prevPosition = 0; - for (Collection::iterator position = positions.begin(); position != positions.end(); ++position) - { - *position = prevPosition + tvf->readVInt(); - prevPosition = *position; - } + tvf->readBytes(byteBuffer.get(), start, deltaLength); + term = StringUtils::toUnicode(byteBuffer.get(), totalLength); + } + int32_t freq = tvf->readVInt(); + Collection positions; + if (storePositions) { // read in the positions + // does the mapper even care about positions? + if (!mapper->isIgnoringPositions()) { + positions = Collection::newInstance(freq); + int32_t prevPosition = 0; + for (Collection::iterator position = positions.begin(); position != positions.end(); ++position) { + *position = prevPosition + tvf->readVInt(); + prevPosition = *position; } - else - { - // we need to skip over the positions. Since these are VInts, I don't believe there - // is anyway to know for sure how far to skip - for (int32_t j = 0; j < freq; ++j) - tvf->readVInt(); + } else { + // we need to skip over the positions. Since these are VInts, I don't believe there + // is anyway to know for sure how far to skip + for (int32_t j = 0; j < freq; ++j) { + tvf->readVInt(); } } + } - Collection offsets; - if (storeOffsets) - { - // does the mapper even care about offsets? - if (!mapper->isIgnoringOffsets()) - { - offsets = Collection::newInstance(freq); - int32_t prevOffset = 0; - for (Collection::iterator offset = offsets.begin(); offset != offsets.end(); ++offset) - { - int32_t startOffset = prevOffset + tvf->readVInt(); - int32_t endOffset = startOffset + tvf->readVInt(); - *offset = newLucene(startOffset, endOffset); - prevOffset = endOffset; - } + Collection offsets; + if (storeOffsets) { + // does the mapper even care about offsets? + if (!mapper->isIgnoringOffsets()) { + offsets = Collection::newInstance(freq); + int32_t prevOffset = 0; + for (Collection::iterator offset = offsets.begin(); offset != offsets.end(); ++offset) { + int32_t startOffset = prevOffset + tvf->readVInt(); + int32_t endOffset = startOffset + tvf->readVInt(); + *offset = newLucene(startOffset, endOffset); + prevOffset = endOffset; } - else - { - for (int32_t j = 0; j < freq; ++j) - { - tvf->readVInt(); - tvf->readVInt(); - } + } else { + for (int32_t j = 0; j < freq; ++j) { + tvf->readVInt(); + tvf->readVInt(); } } - mapper->map(term, freq, offsets, positions); } + mapper->map(term, freq, offsets, positions); } +} - LuceneObjectPtr TermVectorsReader::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - TermVectorsReaderPtr cloneReader(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); - cloneReader->fieldInfos = fieldInfos; - cloneReader->_size = _size; - cloneReader->numTotalDocs = numTotalDocs; - cloneReader->docStoreOffset = docStoreOffset; - cloneReader->format = format; - - // These are null when a TermVectorsReader was created on a segment that did not have term vectors saved - if (tvx && tvd && tvf) - { - cloneReader->tvx = boost::dynamic_pointer_cast(tvx->clone()); - cloneReader->tvd = boost::dynamic_pointer_cast(tvd->clone()); - cloneReader->tvf = boost::dynamic_pointer_cast(tvf->clone()); - } - - return cloneReader; +LuceneObjectPtr TermVectorsReader::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + TermVectorsReaderPtr cloneReader(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); + cloneReader->fieldInfos = fieldInfos; + cloneReader->_size = _size; + cloneReader->numTotalDocs = numTotalDocs; + cloneReader->docStoreOffset = docStoreOffset; + cloneReader->format = format; + + // These are null when a TermVectorsReader was created on a segment that did not have term vectors saved + if (tvx && tvd && tvf) { + cloneReader->tvx = boost::dynamic_pointer_cast(tvx->clone()); + cloneReader->tvd = boost::dynamic_pointer_cast(tvd->clone()); + cloneReader->tvf = boost::dynamic_pointer_cast(tvf->clone()); } - ParallelArrayTermVectorMapper::ParallelArrayTermVectorMapper() - { - currentPosition = 0; - storingOffsets = false; - storingPositions = false; - } + return cloneReader; +} - ParallelArrayTermVectorMapper::~ParallelArrayTermVectorMapper() - { - } +ParallelArrayTermVectorMapper::ParallelArrayTermVectorMapper() { + currentPosition = 0; + storingOffsets = false; + storingPositions = false; +} + +ParallelArrayTermVectorMapper::~ParallelArrayTermVectorMapper() { +} + +void ParallelArrayTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { + this->field = field; + terms = Collection::newInstance(numTerms); + termFreqs = Collection::newInstance(numTerms); + this->storingOffsets = storeOffsets; + this->storingPositions = storePositions; - void ParallelArrayTermVectorMapper::setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) - { - this->field = field; - terms = Collection::newInstance(numTerms); - termFreqs = Collection::newInstance(numTerms); - this->storingOffsets = storeOffsets; - this->storingPositions = storePositions; - - if (storePositions) - this->positions = Collection< Collection >::newInstance(numTerms); - if (storeOffsets) - this->offsets = Collection< Collection >::newInstance(numTerms); + if (storePositions) { + this->positions = Collection< Collection >::newInstance(numTerms); } + if (storeOffsets) { + this->offsets = Collection< Collection >::newInstance(numTerms); + } +} - void ParallelArrayTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) - { - terms[currentPosition] = term; - termFreqs[currentPosition] = frequency; - if (storingOffsets) - this->offsets[currentPosition] = offsets; - if (storingPositions) - this->positions[currentPosition] = positions; - ++currentPosition; +void ParallelArrayTermVectorMapper::map(const String& term, int32_t frequency, Collection offsets, Collection positions) { + terms[currentPosition] = term; + termFreqs[currentPosition] = frequency; + if (storingOffsets) { + this->offsets[currentPosition] = offsets; + } + if (storingPositions) { + this->positions[currentPosition] = positions; } + ++currentPosition; +} - TermFreqVectorPtr ParallelArrayTermVectorMapper::materializeVector() - { - SegmentTermVectorPtr tv; - if (!field.empty() && terms) - { - if (storingPositions || storingOffsets) - tv = newLucene(field, terms, termFreqs, positions, offsets); - else - tv = newLucene(field, terms, termFreqs); +TermFreqVectorPtr ParallelArrayTermVectorMapper::materializeVector() { + SegmentTermVectorPtr tv; + if (!field.empty() && terms) { + if (storingPositions || storingOffsets) { + tv = newLucene(field, terms, termFreqs, positions, offsets); + } else { + tv = newLucene(field, terms, termFreqs); } - return tv; } + return tv; +} + } diff --git a/src/core/index/TermVectorsTermsWriter.cpp b/src/core/index/TermVectorsTermsWriter.cpp index eff282e7..f7173cee 100644 --- a/src/core/index/TermVectorsTermsWriter.cpp +++ b/src/core/index/TermVectorsTermsWriter.cpp @@ -19,321 +19,276 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - TermVectorsTermsWriter::TermVectorsTermsWriter(const DocumentsWriterPtr& docWriter) - { - this->freeCount = 0; - this->lastDocID = 0; - this->allocCount = 0; - this->_docWriter = docWriter; - this->docFreeList = Collection::newInstance(1); - } +namespace Lucene { + +TermVectorsTermsWriter::TermVectorsTermsWriter(const DocumentsWriterPtr& docWriter) { + this->freeCount = 0; + this->lastDocID = 0; + this->allocCount = 0; + this->_docWriter = docWriter; + this->docFreeList = Collection::newInstance(1); +} - TermVectorsTermsWriter::~TermVectorsTermsWriter() - { - } +TermVectorsTermsWriter::~TermVectorsTermsWriter() { +} - TermsHashConsumerPerThreadPtr TermVectorsTermsWriter::addThread(const TermsHashPerThreadPtr& perThread) - { - return newLucene(perThread, shared_from_this()); - } +TermsHashConsumerPerThreadPtr TermVectorsTermsWriter::addThread(const TermsHashPerThreadPtr& perThread) { + return newLucene(perThread, shared_from_this()); +} - void TermVectorsTermsWriter::createPostings(Collection postings, int32_t start, int32_t count) - { - int32_t end = start + count; - for (int32_t i = start; i < end; ++i) - postings[i] = newLucene(); +void TermVectorsTermsWriter::createPostings(Collection postings, int32_t start, int32_t count) { + int32_t end = start + count; + for (int32_t i = start; i < end; ++i) { + postings[i] = newLucene(); } +} - void TermVectorsTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) - { - SyncLock syncLock(this); - - // NOTE: it's possible that all documents seen in this segment hit non-aborting exceptions, in which case we will - // not have yet init'd the TermVectorsWriter. This is actually OK (unlike in the stored fields case) because, - // although IieldInfos.hasVectors() will return true, the TermVectorsReader gracefully handles non-existence of - // the term vectors files. - if (tvx) - { - if (state->numDocsInStore > 0) - { - // In case there are some final documents that we didn't see (because they hit a non-aborting exception) - fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); - } - - tvx->flush(); - tvd->flush(); - tvf->flush(); +void TermVectorsTermsWriter::flush(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { + SyncLock syncLock(this); + + // NOTE: it's possible that all documents seen in this segment hit non-aborting exceptions, in which case we will + // not have yet init'd the TermVectorsWriter. This is actually OK (unlike in the stored fields case) because, + // although IieldInfos.hasVectors() will return true, the TermVectorsReader gracefully handles non-existence of + // the term vectors files. + if (tvx) { + if (state->numDocsInStore > 0) { + // In case there are some final documents that we didn't see (because they hit a non-aborting exception) + fill(state->numDocsInStore - DocumentsWriterPtr(_docWriter)->getDocStoreOffset()); } - for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) - { - for (Collection::iterator field = entry->second.begin(); field != entry->second.end(); ++field) - { - TermVectorsTermsWriterPerFieldPtr perField(boost::static_pointer_cast(*field)); - TermsHashPerFieldPtr(perField->_termsHashPerField)->reset(); - perField->shrinkHash(); - } - - TermVectorsTermsWriterPerThreadPtr perThread(boost::static_pointer_cast(entry->first)); - TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(true); + tvx->flush(); + tvd->flush(); + tvf->flush(); + } + + for (MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { + for (Collection::iterator field = entry->second.begin(); field != entry->second.end(); ++field) { + TermVectorsTermsWriterPerFieldPtr perField(boost::static_pointer_cast(*field)); + TermsHashPerFieldPtr(perField->_termsHashPerField)->reset(); + perField->shrinkHash(); } + + TermVectorsTermsWriterPerThreadPtr perThread(boost::static_pointer_cast(entry->first)); + TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(true); } +} - void TermVectorsTermsWriter::closeDocStore(const SegmentWriteStatePtr& state) - { - SyncLock syncLock(this); - if (tvx) - { - DocumentsWriterPtr docWriter(_docWriter); +void TermVectorsTermsWriter::closeDocStore(const SegmentWriteStatePtr& state) { + SyncLock syncLock(this); + if (tvx) { + DocumentsWriterPtr docWriter(_docWriter); - // At least one doc in this run had term vectors enabled - fill(state->numDocsInStore - docWriter->getDocStoreOffset()); - tvx->close(); - tvf->close(); - tvd->close(); - tvx.reset(); - BOOST_ASSERT(!state->docStoreSegmentName.empty()); - String fileName(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); - if (4 + ((int64_t)state->numDocsInStore) * 16 != state->directory->fileLength(fileName)) - { - boost::throw_exception(RuntimeException(L"after flush: tvx size mismatch: " + StringUtils::toString(state->numDocsInStore) + - L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + - L" length in bytes of " + fileName + L" file exists?=" + - StringUtils::toString(state->directory->fileExists(fileName)))); - } - - state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); - state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); - state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - - docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); - docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); - docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - - lastDocID = 0; + // At least one doc in this run had term vectors enabled + fill(state->numDocsInStore - docWriter->getDocStoreOffset()); + tvx->close(); + tvf->close(); + tvd->close(); + tvx.reset(); + BOOST_ASSERT(!state->docStoreSegmentName.empty()); + String fileName(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); + if (4 + ((int64_t)state->numDocsInStore) * 16 != state->directory->fileLength(fileName)) { + boost::throw_exception(RuntimeException(L"after flush: tvx size mismatch: " + StringUtils::toString(state->numDocsInStore) + + L" docs vs " + StringUtils::toString(state->directory->fileLength(fileName)) + + L" length in bytes of " + fileName + L" file exists?=" + + StringUtils::toString(state->directory->fileExists(fileName)))); } + + state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); + state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); + state->flushedFiles.add(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); + + docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); + docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); + docWriter->removeOpenFile(state->docStoreSegmentName + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); + + lastDocID = 0; } +} - TermVectorsTermsWriterPerDocPtr TermVectorsTermsWriter::getPerDoc() - { - SyncLock syncLock(this); - if (freeCount == 0) - { - if (++allocCount > docFreeList.size()) - { - // Grow our free list up front to make sure we have enough space to recycle all outstanding - // PerDoc instances - BOOST_ASSERT(allocCount == 1 + docFreeList.size()); - docFreeList.resize(MiscUtils::getNextSize(allocCount)); - } - return newLucene(shared_from_this()); +TermVectorsTermsWriterPerDocPtr TermVectorsTermsWriter::getPerDoc() { + SyncLock syncLock(this); + if (freeCount == 0) { + if (++allocCount > docFreeList.size()) { + // Grow our free list up front to make sure we have enough space to recycle all outstanding + // PerDoc instances + BOOST_ASSERT(allocCount == 1 + docFreeList.size()); + docFreeList.resize(MiscUtils::getNextSize(allocCount)); } - else - return docFreeList[--freeCount]; + return newLucene(shared_from_this()); + } else { + return docFreeList[--freeCount]; } +} - void TermVectorsTermsWriter::fill(int32_t docID) - { - int32_t docStoreOffset = DocumentsWriterPtr(_docWriter)->getDocStoreOffset(); - int32_t end = docID + docStoreOffset; - if (lastDocID < end) - { - int64_t tvfPosition = tvf->getFilePointer(); - while (lastDocID < end) - { - tvx->writeLong(tvd->getFilePointer()); - tvd->writeVInt(0); - tvx->writeLong(tvfPosition); - ++lastDocID; - } +void TermVectorsTermsWriter::fill(int32_t docID) { + int32_t docStoreOffset = DocumentsWriterPtr(_docWriter)->getDocStoreOffset(); + int32_t end = docID + docStoreOffset; + if (lastDocID < end) { + int64_t tvfPosition = tvf->getFilePointer(); + while (lastDocID < end) { + tvx->writeLong(tvd->getFilePointer()); + tvd->writeVInt(0); + tvx->writeLong(tvfPosition); + ++lastDocID; } } +} - void TermVectorsTermsWriter::initTermVectorsWriter() - { - SyncLock syncLock(this); - if (!tvx) - { - DocumentsWriterPtr docWriter(_docWriter); +void TermVectorsTermsWriter::initTermVectorsWriter() { + SyncLock syncLock(this); + if (!tvx) { + DocumentsWriterPtr docWriter(_docWriter); - String docStoreSegment(docWriter->getDocStoreSegment()); - if (docStoreSegment.empty()) - return; + String docStoreSegment(docWriter->getDocStoreSegment()); + if (docStoreSegment.empty()) { + return; + } - // If we hit an exception while init'ing the term vector output files, we must abort this segment - // because those files will be in an unknown state - tvx = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); - tvd = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - tvf = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); + // If we hit an exception while init'ing the term vector output files, we must abort this segment + // because those files will be in an unknown state + tvx = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); + tvd = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); + tvf = docWriter->directory->createOutput(docStoreSegment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); - tvx->writeInt(TermVectorsReader::FORMAT_CURRENT); - tvd->writeInt(TermVectorsReader::FORMAT_CURRENT); - tvf->writeInt(TermVectorsReader::FORMAT_CURRENT); + tvx->writeInt(TermVectorsReader::FORMAT_CURRENT); + tvd->writeInt(TermVectorsReader::FORMAT_CURRENT); + tvf->writeInt(TermVectorsReader::FORMAT_CURRENT); - docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); - docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); - docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); + docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); + docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); + docWriter->addOpenFile(docStoreSegment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - lastDocID = 0; - } + lastDocID = 0; } +} - void TermVectorsTermsWriter::finishDocument(const TermVectorsTermsWriterPerDocPtr& perDoc) - { - SyncLock syncLock(this); - DocumentsWriterPtr docWriter(_docWriter); +void TermVectorsTermsWriter::finishDocument(const TermVectorsTermsWriterPerDocPtr& perDoc) { + SyncLock syncLock(this); + DocumentsWriterPtr docWriter(_docWriter); - BOOST_ASSERT(IndexWriterPtr(docWriter->_writer)->testPoint(L"TermVectorsTermsWriter.finishDocument start")); - - initTermVectorsWriter(); - - fill(perDoc->docID); - - // Append term vectors to the real outputs - tvx->writeLong(tvd->getFilePointer()); - tvx->writeLong(tvf->getFilePointer()); - tvd->writeVInt(perDoc->numVectorFields); - - if (perDoc->numVectorFields > 0) - { - for (int32_t i = 0; i < perDoc->numVectorFields; ++i) - tvd->writeVInt(perDoc->fieldNumbers[i]); - BOOST_ASSERT(perDoc->fieldPointers[0] == 0); - int64_t lastPos = perDoc->fieldPointers[0]; - for (int32_t i = 1; i < perDoc->numVectorFields; ++i) - { - int64_t pos = perDoc->fieldPointers[i]; - tvd->writeVLong(pos - lastPos); - lastPos = pos; - } - perDoc->perDocTvf->writeTo(tvf); - perDoc->numVectorFields = 0; - } + BOOST_ASSERT(IndexWriterPtr(docWriter->_writer)->testPoint(L"TermVectorsTermsWriter.finishDocument start")); - BOOST_ASSERT(lastDocID == perDoc->docID + docWriter->getDocStoreOffset()); + initTermVectorsWriter(); - ++lastDocID; + fill(perDoc->docID); - perDoc->reset(); - free(perDoc); - BOOST_ASSERT(IndexWriterPtr(docWriter->_writer)->testPoint(L"TermVectorsTermsWriter.finishDocument end")); - } + // Append term vectors to the real outputs + tvx->writeLong(tvd->getFilePointer()); + tvx->writeLong(tvf->getFilePointer()); + tvd->writeVInt(perDoc->numVectorFields); - bool TermVectorsTermsWriter::freeRAM() - { - // We don't hold any state beyond one doc, so we don't free persistent RAM here - return false; + if (perDoc->numVectorFields > 0) { + for (int32_t i = 0; i < perDoc->numVectorFields; ++i) { + tvd->writeVInt(perDoc->fieldNumbers[i]); + } + BOOST_ASSERT(perDoc->fieldPointers[0] == 0); + int64_t lastPos = perDoc->fieldPointers[0]; + for (int32_t i = 1; i < perDoc->numVectorFields; ++i) { + int64_t pos = perDoc->fieldPointers[i]; + tvd->writeVLong(pos - lastPos); + lastPos = pos; + } + perDoc->perDocTvf->writeTo(tvf); + perDoc->numVectorFields = 0; } - void TermVectorsTermsWriter::abort() - { - if (tvx) - { - try - { - tvx->close(); - } - catch (...) - { - } - tvx.reset(); + BOOST_ASSERT(lastDocID == perDoc->docID + docWriter->getDocStoreOffset()); + + ++lastDocID; + + perDoc->reset(); + free(perDoc); + BOOST_ASSERT(IndexWriterPtr(docWriter->_writer)->testPoint(L"TermVectorsTermsWriter.finishDocument end")); +} + +bool TermVectorsTermsWriter::freeRAM() { + // We don't hold any state beyond one doc, so we don't free persistent RAM here + return false; +} + +void TermVectorsTermsWriter::abort() { + if (tvx) { + try { + tvx->close(); + } catch (...) { } - if (tvd) - { - try - { - tvd->close(); - } - catch (...) - { - } - tvd.reset(); + tvx.reset(); + } + if (tvd) { + try { + tvd->close(); + } catch (...) { } - if (tvf) - { - try - { - tvf->close(); - } - catch (...) - { - } - tvf.reset(); + tvd.reset(); + } + if (tvf) { + try { + tvf->close(); + } catch (...) { } - lastDocID = 0; + tvf.reset(); } + lastDocID = 0; +} - void TermVectorsTermsWriter::free(const TermVectorsTermsWriterPerDocPtr& doc) - { - SyncLock syncLock(this); - BOOST_ASSERT(freeCount < docFreeList.size()); - docFreeList[freeCount++] = doc; - } +void TermVectorsTermsWriter::free(const TermVectorsTermsWriterPerDocPtr& doc) { + SyncLock syncLock(this); + BOOST_ASSERT(freeCount < docFreeList.size()); + docFreeList[freeCount++] = doc; +} - int32_t TermVectorsTermsWriter::bytesPerPosting() - { - return (RawPostingList::BYTES_SIZE + 3 * DocumentsWriter::INT_NUM_BYTE); - } +int32_t TermVectorsTermsWriter::bytesPerPosting() { + return (RawPostingList::BYTES_SIZE + 3 * DocumentsWriter::INT_NUM_BYTE); +} - TermVectorsTermsWriterPerDoc::TermVectorsTermsWriterPerDoc(const TermVectorsTermsWriterPtr& termsWriter) - { - this->_termsWriter = termsWriter; - buffer = DocumentsWriterPtr(termsWriter->_docWriter)->newPerDocBuffer(); - perDocTvf = newLucene(buffer); - numVectorFields = 0; - fieldNumbers = Collection::newInstance(1); - fieldPointers = Collection::newInstance(1); - } +TermVectorsTermsWriterPerDoc::TermVectorsTermsWriterPerDoc(const TermVectorsTermsWriterPtr& termsWriter) { + this->_termsWriter = termsWriter; + buffer = DocumentsWriterPtr(termsWriter->_docWriter)->newPerDocBuffer(); + perDocTvf = newLucene(buffer); + numVectorFields = 0; + fieldNumbers = Collection::newInstance(1); + fieldPointers = Collection::newInstance(1); +} - TermVectorsTermsWriterPerDoc::~TermVectorsTermsWriterPerDoc() - { - } +TermVectorsTermsWriterPerDoc::~TermVectorsTermsWriterPerDoc() { +} - void TermVectorsTermsWriterPerDoc::reset() - { - perDocTvf->reset(); - buffer->recycle(); - numVectorFields = 0; - } +void TermVectorsTermsWriterPerDoc::reset() { + perDocTvf->reset(); + buffer->recycle(); + numVectorFields = 0; +} - void TermVectorsTermsWriterPerDoc::abort() - { - reset(); - TermVectorsTermsWriterPtr(_termsWriter)->free(shared_from_this()); - } +void TermVectorsTermsWriterPerDoc::abort() { + reset(); + TermVectorsTermsWriterPtr(_termsWriter)->free(shared_from_this()); +} - void TermVectorsTermsWriterPerDoc::addField(int32_t fieldNumber) - { - if (numVectorFields == fieldNumbers.size()) - { - fieldNumbers.resize(MiscUtils::getNextSize(fieldNumbers.size())); - fieldPointers.resize(MiscUtils::getNextSize(fieldPointers.size())); - } - fieldNumbers[numVectorFields] = fieldNumber; - fieldPointers[numVectorFields] = perDocTvf->getFilePointer(); - ++numVectorFields; +void TermVectorsTermsWriterPerDoc::addField(int32_t fieldNumber) { + if (numVectorFields == fieldNumbers.size()) { + fieldNumbers.resize(MiscUtils::getNextSize(fieldNumbers.size())); + fieldPointers.resize(MiscUtils::getNextSize(fieldPointers.size())); } + fieldNumbers[numVectorFields] = fieldNumber; + fieldPointers[numVectorFields] = perDocTvf->getFilePointer(); + ++numVectorFields; +} - int64_t TermVectorsTermsWriterPerDoc::sizeInBytes() - { - return buffer->getSizeInBytes(); - } +int64_t TermVectorsTermsWriterPerDoc::sizeInBytes() { + return buffer->getSizeInBytes(); +} - void TermVectorsTermsWriterPerDoc::finish() - { - TermVectorsTermsWriterPtr(_termsWriter)->finishDocument(shared_from_this()); - } +void TermVectorsTermsWriterPerDoc::finish() { + TermVectorsTermsWriterPtr(_termsWriter)->finishDocument(shared_from_this()); +} - TermVectorsTermsWriterPostingList::TermVectorsTermsWriterPostingList() - { - freq = 0; - lastOffset = 0; - lastPosition = 0; - } +TermVectorsTermsWriterPostingList::TermVectorsTermsWriterPostingList() { + freq = 0; + lastOffset = 0; + lastPosition = 0; +} + +TermVectorsTermsWriterPostingList::~TermVectorsTermsWriterPostingList() { +} - TermVectorsTermsWriterPostingList::~TermVectorsTermsWriterPostingList() - { - } } diff --git a/src/core/index/TermVectorsTermsWriterPerField.cpp b/src/core/index/TermVectorsTermsWriterPerField.cpp index 97af0e29..85724964 100644 --- a/src/core/index/TermVectorsTermsWriterPerField.cpp +++ b/src/core/index/TermVectorsTermsWriterPerField.cpp @@ -23,254 +23,238 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - TermVectorsTermsWriterPerField::TermVectorsTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const TermVectorsTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) - { - this->doVectors = false; - this->doVectorPositions = false; - this->doVectorOffsets = false; - this->maxNumPostings = 0; - - this->_termsHashPerField = termsHashPerField; - this->_perThread = perThread; - this->_termsWriter = perThread->_termsWriter; - this->fieldInfo = fieldInfo; - _docState = termsHashPerField->docState; - _fieldState = termsHashPerField->fieldState; - } +namespace Lucene { + +TermVectorsTermsWriterPerField::TermVectorsTermsWriterPerField(const TermsHashPerFieldPtr& termsHashPerField, const TermVectorsTermsWriterPerThreadPtr& perThread, const FieldInfoPtr& fieldInfo) { + this->doVectors = false; + this->doVectorPositions = false; + this->doVectorOffsets = false; + this->maxNumPostings = 0; + + this->_termsHashPerField = termsHashPerField; + this->_perThread = perThread; + this->_termsWriter = perThread->_termsWriter; + this->fieldInfo = fieldInfo; + _docState = termsHashPerField->docState; + _fieldState = termsHashPerField->fieldState; +} - TermVectorsTermsWriterPerField::~TermVectorsTermsWriterPerField() - { - } +TermVectorsTermsWriterPerField::~TermVectorsTermsWriterPerField() { +} - int32_t TermVectorsTermsWriterPerField::getStreamCount() - { - return 2; - } +int32_t TermVectorsTermsWriterPerField::getStreamCount() { + return 2; +} - bool TermVectorsTermsWriterPerField::start(Collection fields, int32_t count) - { - doVectors = false; - doVectorPositions = false; - doVectorOffsets = false; - - for (int32_t i = 0; i < count; ++i) - { - FieldablePtr field(fields[i]); - if (field->isIndexed() && field->isTermVectorStored()) - { - doVectors = true; - if (field->isStorePositionWithTermVector()) - doVectorPositions = true; - if (field->isStoreOffsetWithTermVector()) - doVectorOffsets = true; +bool TermVectorsTermsWriterPerField::start(Collection fields, int32_t count) { + doVectors = false; + doVectorPositions = false; + doVectorOffsets = false; + + for (int32_t i = 0; i < count; ++i) { + FieldablePtr field(fields[i]); + if (field->isIndexed() && field->isTermVectorStored()) { + doVectors = true; + if (field->isStorePositionWithTermVector()) { + doVectorPositions = true; + } + if (field->isStoreOffsetWithTermVector()) { + doVectorOffsets = true; } } + } - if (doVectors) - { - TermVectorsTermsWriterPerThreadPtr perThread(_perThread); - DocStatePtr docState(_docState); - if (!perThread->doc) - { - perThread->doc = TermVectorsTermsWriterPtr(_termsWriter)->getPerDoc(); - perThread->doc->docID = docState->docID; - BOOST_ASSERT(perThread->doc->numVectorFields == 0); - BOOST_ASSERT(perThread->doc->perDocTvf->length() == 0); - BOOST_ASSERT(perThread->doc->perDocTvf->getFilePointer() == 0); - } + if (doVectors) { + TermVectorsTermsWriterPerThreadPtr perThread(_perThread); + DocStatePtr docState(_docState); + if (!perThread->doc) { + perThread->doc = TermVectorsTermsWriterPtr(_termsWriter)->getPerDoc(); + perThread->doc->docID = docState->docID; + BOOST_ASSERT(perThread->doc->numVectorFields == 0); + BOOST_ASSERT(perThread->doc->perDocTvf->length() == 0); + BOOST_ASSERT(perThread->doc->perDocTvf->getFilePointer() == 0); + } - BOOST_ASSERT(perThread->doc->docID == docState->docID); + BOOST_ASSERT(perThread->doc->docID == docState->docID); - TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - if (termsHashPerField->numPostings != 0) - { - // Only necessary if previous doc hit a non-aborting exception while writing vectors - // in this field - termsHashPerField->reset(); - TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(false); - } + if (termsHashPerField->numPostings != 0) { + // Only necessary if previous doc hit a non-aborting exception while writing vectors + // in this field + termsHashPerField->reset(); + TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(false); } - - return doVectors; } - void TermVectorsTermsWriterPerField::abort() - { - } + return doVectors; +} - void TermVectorsTermsWriterPerField::finish() - { - BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.finish start")); +void TermVectorsTermsWriterPerField::abort() { +} - TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - int32_t numPostings = termsHashPerField->numPostings; +void TermVectorsTermsWriterPerField::finish() { + BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.finish start")); - BOOST_ASSERT(numPostings >= 0); + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); + int32_t numPostings = termsHashPerField->numPostings; - if (!doVectors || numPostings == 0) - return; + BOOST_ASSERT(numPostings >= 0); - if (numPostings > maxNumPostings) - maxNumPostings = numPostings; + if (!doVectors || numPostings == 0) { + return; + } - TermVectorsTermsWriterPerThreadPtr perThread(_perThread); - IndexOutputPtr tvf(perThread->doc->perDocTvf); + if (numPostings > maxNumPostings) { + maxNumPostings = numPostings; + } - // This is called once, after inverting all occurrences of a given field in the doc. At this point we flush - // our hash into the DocWriter. + TermVectorsTermsWriterPerThreadPtr perThread(_perThread); + IndexOutputPtr tvf(perThread->doc->perDocTvf); - BOOST_ASSERT(fieldInfo->storeTermVector); - BOOST_ASSERT(perThread->vectorFieldsInOrder(fieldInfo)); + // This is called once, after inverting all occurrences of a given field in the doc. At this point we flush + // our hash into the DocWriter. - perThread->doc->addField(termsHashPerField->fieldInfo->number); + BOOST_ASSERT(fieldInfo->storeTermVector); + BOOST_ASSERT(perThread->vectorFieldsInOrder(fieldInfo)); - Collection postings(termsHashPerField->sortPostings()); + perThread->doc->addField(termsHashPerField->fieldInfo->number); - tvf->writeVInt(numPostings); - uint8_t bits = 0x0; - if (doVectorPositions) - bits |= TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR; - if (doVectorOffsets) - bits |= TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR; - tvf->writeByte(bits); + Collection postings(termsHashPerField->sortPostings()); + + tvf->writeVInt(numPostings); + uint8_t bits = 0x0; + if (doVectorPositions) { + bits |= TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR; + } + if (doVectorOffsets) { + bits |= TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR; + } + tvf->writeByte(bits); - int32_t encoderUpto = 0; - int32_t lastTermBytesCount = 0; + int32_t encoderUpto = 0; + int32_t lastTermBytesCount = 0; - ByteSliceReaderPtr reader(perThread->vectorSliceReader); - Collection charBuffers(TermsHashPerThreadPtr(perThread->_termsHashPerThread)->charPool->buffers); + ByteSliceReaderPtr reader(perThread->vectorSliceReader); + Collection charBuffers(TermsHashPerThreadPtr(perThread->_termsHashPerThread)->charPool->buffers); - for (int32_t j = 0; j < numPostings; ++j) - { - TermVectorsTermsWriterPostingListPtr posting(boost::static_pointer_cast(postings[j])); - int32_t freq = posting->freq; + for (int32_t j = 0; j < numPostings; ++j) { + TermVectorsTermsWriterPostingListPtr posting(boost::static_pointer_cast(postings[j])); + int32_t freq = posting->freq; - CharArray text2(charBuffers[posting->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]); - int32_t start2 = (posting->textStart & DocumentsWriter::CHAR_BLOCK_MASK); + CharArray text2(charBuffers[posting->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]); + int32_t start2 = (posting->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - // We swap between two encoders to save copying last Term's byte array - UTF8ResultPtr utf8Result(perThread->utf8Results[encoderUpto]); + // We swap between two encoders to save copying last Term's byte array + UTF8ResultPtr utf8Result(perThread->utf8Results[encoderUpto]); - StringUtils::toUTF8(text2.get() + start2, text2.size(), utf8Result); - int32_t termBytesCount = utf8Result->length; + StringUtils::toUTF8(text2.get() + start2, text2.size(), utf8Result); + int32_t termBytesCount = utf8Result->length; - // Compute common prefix between last term and this term - int32_t prefix = 0; - if (j > 0) - { - ByteArray lastTermBytes(perThread->utf8Results[1 - encoderUpto]->result); - ByteArray termBytes(perThread->utf8Results[encoderUpto]->result); - while (prefix < lastTermBytesCount && prefix < termBytesCount) - { - if (lastTermBytes[prefix] != termBytes[prefix]) - break; - ++prefix; + // Compute common prefix between last term and this term + int32_t prefix = 0; + if (j > 0) { + ByteArray lastTermBytes(perThread->utf8Results[1 - encoderUpto]->result); + ByteArray termBytes(perThread->utf8Results[encoderUpto]->result); + while (prefix < lastTermBytesCount && prefix < termBytesCount) { + if (lastTermBytes[prefix] != termBytes[prefix]) { + break; } + ++prefix; } - encoderUpto = 1 - encoderUpto; - lastTermBytesCount = termBytesCount; - - int32_t suffix = termBytesCount - prefix; - tvf->writeVInt(prefix); - tvf->writeVInt(suffix); - tvf->writeBytes(utf8Result->result.get(), prefix, suffix); - tvf->writeVInt(freq); - - if (doVectorPositions) - { - termsHashPerField->initReader(reader, posting, 0); - reader->writeTo(tvf); - } + } + encoderUpto = 1 - encoderUpto; + lastTermBytesCount = termBytesCount; + + int32_t suffix = termBytesCount - prefix; + tvf->writeVInt(prefix); + tvf->writeVInt(suffix); + tvf->writeBytes(utf8Result->result.get(), prefix, suffix); + tvf->writeVInt(freq); + + if (doVectorPositions) { + termsHashPerField->initReader(reader, posting, 0); + reader->writeTo(tvf); + } - if (doVectorOffsets) - { - termsHashPerField->initReader(reader, posting, 1); - reader->writeTo(tvf); - } + if (doVectorOffsets) { + termsHashPerField->initReader(reader, posting, 1); + reader->writeTo(tvf); } + } - termsHashPerField->reset(); + termsHashPerField->reset(); - // NOTE: we clear per-field at the thread level, because term vectors fully write themselves on each - // field; this saves RAM (eg if large doc has two large fields with term vectors on) because we - // recycle/reuse all RAM after each field - TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(false); - } + // NOTE: we clear per-field at the thread level, because term vectors fully write themselves on each + // field; this saves RAM (eg if large doc has two large fields with term vectors on) because we + // recycle/reuse all RAM after each field + TermsHashPerThreadPtr(perThread->_termsHashPerThread)->reset(false); +} - void TermVectorsTermsWriterPerField::shrinkHash() - { - TermsHashPerFieldPtr(_termsHashPerField)->shrinkHash(maxNumPostings); - maxNumPostings = 0; - } +void TermVectorsTermsWriterPerField::shrinkHash() { + TermsHashPerFieldPtr(_termsHashPerField)->shrinkHash(maxNumPostings); + maxNumPostings = 0; +} - void TermVectorsTermsWriterPerField::start(const FieldablePtr& field) - { - if (doVectorOffsets) - offsetAttribute = FieldInvertStatePtr(_fieldState)->attributeSource->addAttribute(); - else - offsetAttribute.reset(); +void TermVectorsTermsWriterPerField::start(const FieldablePtr& field) { + if (doVectorOffsets) { + offsetAttribute = FieldInvertStatePtr(_fieldState)->attributeSource->addAttribute(); + } else { + offsetAttribute.reset(); } +} - void TermVectorsTermsWriterPerField::newTerm(const RawPostingListPtr& p0) - { - BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); +void TermVectorsTermsWriterPerField::newTerm(const RawPostingListPtr& p0) { + BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); - TermVectorsTermsWriterPostingListPtr p(boost::static_pointer_cast(p0)); + TermVectorsTermsWriterPostingListPtr p(boost::static_pointer_cast(p0)); - p->freq = 1; + p->freq = 1; - FieldInvertStatePtr fieldState(_fieldState); - TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); + FieldInvertStatePtr fieldState(_fieldState); + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - if (doVectorOffsets) - { - int32_t startOffset = fieldState->offset + offsetAttribute->startOffset(); - int32_t endOffset = fieldState->offset + offsetAttribute->endOffset(); + if (doVectorOffsets) { + int32_t startOffset = fieldState->offset + offsetAttribute->startOffset(); + int32_t endOffset = fieldState->offset + offsetAttribute->endOffset(); - termsHashPerField->writeVInt(1, startOffset); - termsHashPerField->writeVInt(1, endOffset - startOffset); - p->lastOffset = endOffset; - } - - if (doVectorPositions) - { - termsHashPerField->writeVInt(0, fieldState->position); - p->lastPosition = fieldState->position; - } + termsHashPerField->writeVInt(1, startOffset); + termsHashPerField->writeVInt(1, endOffset - startOffset); + p->lastOffset = endOffset; } - void TermVectorsTermsWriterPerField::addTerm(const RawPostingListPtr& p0) - { - BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); + if (doVectorPositions) { + termsHashPerField->writeVInt(0, fieldState->position); + p->lastPosition = fieldState->position; + } +} - TermVectorsTermsWriterPostingListPtr p(boost::static_pointer_cast(p0)); +void TermVectorsTermsWriterPerField::addTerm(const RawPostingListPtr& p0) { + BOOST_ASSERT(DocStatePtr(_docState)->testPoint(L"TermVectorsTermsWriterPerField.newTerm start")); - ++p->freq; + TermVectorsTermsWriterPostingListPtr p(boost::static_pointer_cast(p0)); - FieldInvertStatePtr fieldState(_fieldState); - TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); + ++p->freq; - if (doVectorOffsets) - { - int32_t startOffset = fieldState->offset + offsetAttribute->startOffset(); - int32_t endOffset = fieldState->offset + offsetAttribute->endOffset(); + FieldInvertStatePtr fieldState(_fieldState); + TermsHashPerFieldPtr termsHashPerField(_termsHashPerField); - termsHashPerField->writeVInt(1, startOffset - p->lastOffset); - termsHashPerField->writeVInt(1, endOffset - startOffset); - p->lastOffset = endOffset; - } + if (doVectorOffsets) { + int32_t startOffset = fieldState->offset + offsetAttribute->startOffset(); + int32_t endOffset = fieldState->offset + offsetAttribute->endOffset(); - if (doVectorPositions) - { - termsHashPerField->writeVInt(0, fieldState->position - p->lastPosition); - p->lastPosition = fieldState->position; - } + termsHashPerField->writeVInt(1, startOffset - p->lastOffset); + termsHashPerField->writeVInt(1, endOffset - startOffset); + p->lastOffset = endOffset; } - void TermVectorsTermsWriterPerField::skippingLongTerm() - { + if (doVectorPositions) { + termsHashPerField->writeVInt(0, fieldState->position - p->lastPosition); + p->lastPosition = fieldState->position; } } + +void TermVectorsTermsWriterPerField::skippingLongTerm() { +} + +} diff --git a/src/core/index/TermVectorsTermsWriterPerThread.cpp b/src/core/index/TermVectorsTermsWriterPerThread.cpp index d07a0096..add3a270 100644 --- a/src/core/index/TermVectorsTermsWriterPerThread.cpp +++ b/src/core/index/TermVectorsTermsWriterPerThread.cpp @@ -14,62 +14,53 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - TermVectorsTermsWriterPerThread::TermVectorsTermsWriterPerThread(const TermsHashPerThreadPtr& termsHashPerThread, const TermVectorsTermsWriterPtr& termsWriter) - { - utf8Results = newCollection(newInstance(), newInstance()); - this->vectorSliceReader = newLucene(); - this->_termsWriter = termsWriter; - this->_termsHashPerThread = termsHashPerThread; - _docState = termsHashPerThread->docState; - } +namespace Lucene { - TermVectorsTermsWriterPerThread::~TermVectorsTermsWriterPerThread() - { - } +TermVectorsTermsWriterPerThread::TermVectorsTermsWriterPerThread(const TermsHashPerThreadPtr& termsHashPerThread, const TermVectorsTermsWriterPtr& termsWriter) { + utf8Results = newCollection(newInstance(), newInstance()); + this->vectorSliceReader = newLucene(); + this->_termsWriter = termsWriter; + this->_termsHashPerThread = termsHashPerThread; + _docState = termsHashPerThread->docState; +} - void TermVectorsTermsWriterPerThread::startDocument() - { - BOOST_ASSERT(clearLastVectorFieldName()); - if (doc) - { - doc->reset(); - doc->docID = DocStatePtr(_docState)->docID; - } - } +TermVectorsTermsWriterPerThread::~TermVectorsTermsWriterPerThread() { +} - DocWriterPtr TermVectorsTermsWriterPerThread::finishDocument() - { - DocWriterPtr returnDoc(doc); - doc.reset(); - return returnDoc; +void TermVectorsTermsWriterPerThread::startDocument() { + BOOST_ASSERT(clearLastVectorFieldName()); + if (doc) { + doc->reset(); + doc->docID = DocStatePtr(_docState)->docID; } +} - TermsHashConsumerPerFieldPtr TermVectorsTermsWriterPerThread::addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) - { - return newLucene(termsHashPerField, shared_from_this(), fieldInfo); - } +DocWriterPtr TermVectorsTermsWriterPerThread::finishDocument() { + DocWriterPtr returnDoc(doc); + doc.reset(); + return returnDoc; +} - void TermVectorsTermsWriterPerThread::abort() - { - if (doc) - { - doc->abort(); - doc.reset(); - } - } +TermsHashConsumerPerFieldPtr TermVectorsTermsWriterPerThread::addField(const TermsHashPerFieldPtr& termsHashPerField, const FieldInfoPtr& fieldInfo) { + return newLucene(termsHashPerField, shared_from_this(), fieldInfo); +} - bool TermVectorsTermsWriterPerThread::clearLastVectorFieldName() - { - lastVectorFieldName.clear(); - return true; +void TermVectorsTermsWriterPerThread::abort() { + if (doc) { + doc->abort(); + doc.reset(); } +} + +bool TermVectorsTermsWriterPerThread::clearLastVectorFieldName() { + lastVectorFieldName.clear(); + return true; +} + +bool TermVectorsTermsWriterPerThread::vectorFieldsInOrder(const FieldInfoPtr& fi) { + bool inOrder = lastVectorFieldName.empty() ? true : (lastVectorFieldName < fi->name); + lastVectorFieldName = fi->name; + return inOrder; +} - bool TermVectorsTermsWriterPerThread::vectorFieldsInOrder(const FieldInfoPtr& fi) - { - bool inOrder = lastVectorFieldName.empty() ? true : (lastVectorFieldName < fi->name); - lastVectorFieldName = fi->name; - return inOrder; - } } diff --git a/src/core/index/TermVectorsWriter.cpp b/src/core/index/TermVectorsWriter.cpp index 309677ec..2f553f4d 100644 --- a/src/core/index/TermVectorsWriter.cpp +++ b/src/core/index/TermVectorsWriter.cpp @@ -17,208 +17,184 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - TermVectorsWriter::TermVectorsWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fieldInfos) - { - utf8Results = newCollection(newInstance(), newInstance()); - - // Open files for TermVector storage - tvx = directory->createOutput(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); - tvx->writeInt(TermVectorsReader::FORMAT_CURRENT); - tvd = directory->createOutput(segment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); - tvd->writeInt(TermVectorsReader::FORMAT_CURRENT); - tvf = directory->createOutput(segment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); - tvf->writeInt(TermVectorsReader::FORMAT_CURRENT); - - this->fieldInfos = fieldInfos; - } +namespace Lucene { - TermVectorsWriter::~TermVectorsWriter() - { - } +TermVectorsWriter::TermVectorsWriter(const DirectoryPtr& directory, const String& segment, const FieldInfosPtr& fieldInfos) { + utf8Results = newCollection(newInstance(), newInstance()); + + // Open files for TermVector storage + tvx = directory->createOutput(segment + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION()); + tvx->writeInt(TermVectorsReader::FORMAT_CURRENT); + tvd = directory->createOutput(segment + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION()); + tvd->writeInt(TermVectorsReader::FORMAT_CURRENT); + tvf = directory->createOutput(segment + L"." + IndexFileNames::VECTORS_FIELDS_EXTENSION()); + tvf->writeInt(TermVectorsReader::FORMAT_CURRENT); + + this->fieldInfos = fieldInfos; +} - void TermVectorsWriter::addAllDocVectors(Collection vectors) - { - tvx->writeLong(tvd->getFilePointer()); - tvx->writeLong(tvf->getFilePointer()); +TermVectorsWriter::~TermVectorsWriter() { +} - if (vectors) - { - int32_t numFields = vectors.size(); - tvd->writeVInt(numFields); +void TermVectorsWriter::addAllDocVectors(Collection vectors) { + tvx->writeLong(tvd->getFilePointer()); + tvx->writeLong(tvf->getFilePointer()); - Collection fieldPointers(Collection::newInstance(numFields)); + if (vectors) { + int32_t numFields = vectors.size(); + tvd->writeVInt(numFields); - for (int32_t i = 0; i < numFields; ++i) - { - fieldPointers[i] = tvf->getFilePointer(); + Collection fieldPointers(Collection::newInstance(numFields)); - int32_t fieldNumber = fieldInfos->fieldNumber(vectors[i]->getField()); + for (int32_t i = 0; i < numFields; ++i) { + fieldPointers[i] = tvf->getFilePointer(); - // 1st pass: write field numbers to tvd - tvd->writeVInt(fieldNumber); + int32_t fieldNumber = fieldInfos->fieldNumber(vectors[i]->getField()); - int32_t numTerms = vectors[i]->size(); - tvf->writeVInt(numTerms); + // 1st pass: write field numbers to tvd + tvd->writeVInt(fieldNumber); - TermPositionVectorPtr tpVector(boost::dynamic_pointer_cast(vectors[i])); + int32_t numTerms = vectors[i]->size(); + tvf->writeVInt(numTerms); - uint8_t bits; - bool storePositions; - bool storeOffsets; + TermPositionVectorPtr tpVector(boost::dynamic_pointer_cast(vectors[i])); - if (tpVector) - { - // May have positions & offsets - storePositions = (tpVector->size() > 0 && !tpVector->getTermPositions(0)); - storeOffsets = (tpVector->size() > 0 && tpVector->getOffsets(0)); - bits = (uint8_t)((storePositions ? TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR : 0) + - (storeOffsets ? TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR : 0)); - } - else - { - bits = 0; - storePositions = false; - storeOffsets = false; - } + uint8_t bits; + bool storePositions; + bool storeOffsets; + + if (tpVector) { + // May have positions & offsets + storePositions = (tpVector->size() > 0 && !tpVector->getTermPositions(0)); + storeOffsets = (tpVector->size() > 0 && tpVector->getOffsets(0)); + bits = (uint8_t)((storePositions ? TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR : 0) + + (storeOffsets ? TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR : 0)); + } else { + bits = 0; + storePositions = false; + storeOffsets = false; + } + + tvf->writeVInt(bits); + Collection terms(vectors[i]->getTerms()); + Collection freqs(vectors[i]->getTermFrequencies()); + + int32_t utf8Upto = 0; + utf8Results[1]->length = 0; + + for (int32_t j = 0; j < numTerms; ++j) { + StringUtils::toUTF8(terms[j].c_str(), terms[j].length(), utf8Results[utf8Upto]); + + int32_t start = MiscUtils::bytesDifference(utf8Results[1 - utf8Upto]->result.get(), utf8Results[1 - utf8Upto]->length, + utf8Results[utf8Upto]->result.get(), utf8Results[utf8Upto]->length); + int32_t length = utf8Results[utf8Upto]->length - start; + tvf->writeVInt(start); // write shared prefix length + tvf->writeVInt(length); // write delta length + tvf->writeBytes(utf8Results[utf8Upto]->result.get(), start, length); // write delta bytes + utf8Upto = 1 - utf8Upto; + + int32_t termFreq = freqs[j]; + tvf->writeVInt(termFreq); - tvf->writeVInt(bits); - Collection terms(vectors[i]->getTerms()); - Collection freqs(vectors[i]->getTermFrequencies()); - - int32_t utf8Upto = 0; - utf8Results[1]->length = 0; - - for (int32_t j = 0; j < numTerms; ++j) - { - StringUtils::toUTF8(terms[j].c_str(), terms[j].length(), utf8Results[utf8Upto]); - - int32_t start = MiscUtils::bytesDifference(utf8Results[1 - utf8Upto]->result.get(), utf8Results[1 - utf8Upto]->length, - utf8Results[utf8Upto]->result.get(), utf8Results[utf8Upto]->length); - int32_t length = utf8Results[utf8Upto]->length - start; - tvf->writeVInt(start); // write shared prefix length - tvf->writeVInt(length); // write delta length - tvf->writeBytes(utf8Results[utf8Upto]->result.get(), start, length); // write delta bytes - utf8Upto = 1 - utf8Upto; - - int32_t termFreq = freqs[j]; - tvf->writeVInt(termFreq); - - if (storePositions) - { - Collection positions(tpVector->getTermPositions(j)); - if (!positions) - boost::throw_exception(IllegalStateException(L"Trying to write positions that are null!")); - BOOST_ASSERT(positions.size() == termFreq); - - // use delta encoding for positions - int32_t lastPosition = 0; - for (int32_t k = 0; k < positions.size(); ++k) - { - int32_t position = positions[k]; - tvf->writeVInt(position - lastPosition); - lastPosition = position; - } + if (storePositions) { + Collection positions(tpVector->getTermPositions(j)); + if (!positions) { + boost::throw_exception(IllegalStateException(L"Trying to write positions that are null!")); } + BOOST_ASSERT(positions.size() == termFreq); + + // use delta encoding for positions + int32_t lastPosition = 0; + for (int32_t k = 0; k < positions.size(); ++k) { + int32_t position = positions[k]; + tvf->writeVInt(position - lastPosition); + lastPosition = position; + } + } - if (storeOffsets) - { - Collection offsets(tpVector->getOffsets(j)); - if (!offsets) - boost::throw_exception(IllegalStateException(L"Trying to write offsets that are null!")); - BOOST_ASSERT(offsets.size() == termFreq); - - // use delta encoding for offsets - int32_t lastEndOffset = 0; - for (int32_t k = 0; k < offsets.size(); ++k) - { - int32_t startOffset = offsets[k]->getStartOffset(); - int32_t endOffset = offsets[k]->getEndOffset(); - tvf->writeVInt(startOffset - lastEndOffset); - tvf->writeVInt(endOffset - startOffset); - lastEndOffset = endOffset; - } + if (storeOffsets) { + Collection offsets(tpVector->getOffsets(j)); + if (!offsets) { + boost::throw_exception(IllegalStateException(L"Trying to write offsets that are null!")); + } + BOOST_ASSERT(offsets.size() == termFreq); + + // use delta encoding for offsets + int32_t lastEndOffset = 0; + for (int32_t k = 0; k < offsets.size(); ++k) { + int32_t startOffset = offsets[k]->getStartOffset(); + int32_t endOffset = offsets[k]->getEndOffset(); + tvf->writeVInt(startOffset - lastEndOffset); + tvf->writeVInt(endOffset - startOffset); + lastEndOffset = endOffset; } } } + } - // 2nd pass: write field pointers to tvd - if (numFields > 1) - { - int64_t lastFieldPointer = fieldPointers[0]; - for (int32_t i = 1; i < numFields; ++i) - { - int64_t fieldPointer = fieldPointers[i]; - tvd->writeVLong(fieldPointer - lastFieldPointer); - lastFieldPointer = fieldPointer; - } + // 2nd pass: write field pointers to tvd + if (numFields > 1) { + int64_t lastFieldPointer = fieldPointers[0]; + for (int32_t i = 1; i < numFields; ++i) { + int64_t fieldPointer = fieldPointers[i]; + tvd->writeVLong(fieldPointer - lastFieldPointer); + lastFieldPointer = fieldPointer; } } - else - tvd->writeVInt(0); + } else { + tvd->writeVInt(0); } +} - void TermVectorsWriter::addRawDocuments(const TermVectorsReaderPtr& reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs) - { - int64_t tvdPosition = tvd->getFilePointer(); - int64_t tvfPosition = tvf->getFilePointer(); - int64_t tvdStart = tvdPosition; - int64_t tvfStart = tvfPosition; - for (int32_t i = 0; i < numDocs; ++i) - { - tvx->writeLong(tvdPosition); - tvdPosition += tvdLengths[i]; - tvx->writeLong(tvfPosition); - tvfPosition += tvfLengths[i]; - } - tvd->copyBytes(reader->getTvdStream(), tvdPosition - tvdStart); - tvf->copyBytes(reader->getTvfStream(), tvfPosition - tvfStart); - BOOST_ASSERT(tvd->getFilePointer() == tvdPosition); - BOOST_ASSERT(tvf->getFilePointer() == tvfPosition); +void TermVectorsWriter::addRawDocuments(const TermVectorsReaderPtr& reader, Collection tvdLengths, Collection tvfLengths, int32_t numDocs) { + int64_t tvdPosition = tvd->getFilePointer(); + int64_t tvfPosition = tvf->getFilePointer(); + int64_t tvdStart = tvdPosition; + int64_t tvfStart = tvfPosition; + for (int32_t i = 0; i < numDocs; ++i) { + tvx->writeLong(tvdPosition); + tvdPosition += tvdLengths[i]; + tvx->writeLong(tvfPosition); + tvfPosition += tvfLengths[i]; } + tvd->copyBytes(reader->getTvdStream(), tvdPosition - tvdStart); + tvf->copyBytes(reader->getTvfStream(), tvfPosition - tvfStart); + BOOST_ASSERT(tvd->getFilePointer() == tvdPosition); + BOOST_ASSERT(tvf->getFilePointer() == tvfPosition); +} - void TermVectorsWriter::close() - { - // make an effort to close all streams we can but remember and re-throw the first exception - // encountered in this process - LuceneException keep; - if (tvx) - { - try - { - tvx->close(); - } - catch (LuceneException& e) - { - if (keep.isNull()) - keep = e; +void TermVectorsWriter::close() { + // make an effort to close all streams we can but remember and re-throw the first exception + // encountered in this process + LuceneException keep; + if (tvx) { + try { + tvx->close(); + } catch (LuceneException& e) { + if (keep.isNull()) { + keep = e; } } - if (tvd) - { - try - { - tvd->close(); - } - catch (LuceneException& e) - { - if (keep.isNull()) - keep = e; + } + if (tvd) { + try { + tvd->close(); + } catch (LuceneException& e) { + if (keep.isNull()) { + keep = e; } } - if (tvf) - { - try - { - tvf->close(); - } - catch (LuceneException& e) - { - if (keep.isNull()) - keep = e; + } + if (tvf) { + try { + tvf->close(); + } catch (LuceneException& e) { + if (keep.isNull()) { + keep = e; } } - keep.throwException(); } + keep.throwException(); +} + } diff --git a/src/core/index/TermsHash.cpp b/src/core/index/TermsHash.cpp index ccd441c1..ef10eb04 100644 --- a/src/core/index/TermsHash.cpp +++ b/src/core/index/TermsHash.cpp @@ -16,195 +16,190 @@ #include "IndexWriter.h" #include "MiscUtils.h" -namespace Lucene -{ - TermsHash::TermsHash(const DocumentsWriterPtr& docWriter, bool trackAllocations, const TermsHashConsumerPtr& consumer, const TermsHashPtr& nextTermsHash) - { - this->postingsFreeCount = 0; - this->postingsAllocCount = 0; - this->trackAllocations = false; - this->postingsFreeList = Collection::newInstance(1); - - this->_docWriter = docWriter; - this->consumer = consumer; - this->nextTermsHash = nextTermsHash; - this->trackAllocations = trackAllocations; - - bytesPerPosting = consumer->bytesPerPosting() + 4 * DocumentsWriter::POINTER_NUM_BYTE; - postingsFreeChunk = (int32_t)((double)DocumentsWriter::BYTE_BLOCK_SIZE / (double)bytesPerPosting); - } +namespace Lucene { - TermsHash::~TermsHash() - { - } +TermsHash::TermsHash(const DocumentsWriterPtr& docWriter, bool trackAllocations, const TermsHashConsumerPtr& consumer, const TermsHashPtr& nextTermsHash) { + this->postingsFreeCount = 0; + this->postingsAllocCount = 0; + this->trackAllocations = false; + this->postingsFreeList = Collection::newInstance(1); - InvertedDocConsumerPerThreadPtr TermsHash::addThread(const DocInverterPerThreadPtr& docInverterPerThread) - { - return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, TermsHashPerThreadPtr()); - } + this->_docWriter = docWriter; + this->consumer = consumer; + this->nextTermsHash = nextTermsHash; + this->trackAllocations = trackAllocations; - TermsHashPerThreadPtr TermsHash::addThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPerThreadPtr& primaryPerThread) - { - return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, primaryPerThread); - } + bytesPerPosting = consumer->bytesPerPosting() + 4 * DocumentsWriter::POINTER_NUM_BYTE; + postingsFreeChunk = (int32_t)((double)DocumentsWriter::BYTE_BLOCK_SIZE / (double)bytesPerPosting); +} - void TermsHash::setFieldInfos(const FieldInfosPtr& fieldInfos) - { - this->fieldInfos = fieldInfos; - consumer->setFieldInfos(fieldInfos); - } +TermsHash::~TermsHash() { +} - void TermsHash::abort() - { - consumer->abort(); - if (nextTermsHash) - nextTermsHash->abort(); +InvertedDocConsumerPerThreadPtr TermsHash::addThread(const DocInverterPerThreadPtr& docInverterPerThread) { + return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, TermsHashPerThreadPtr()); +} + +TermsHashPerThreadPtr TermsHash::addThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPerThreadPtr& primaryPerThread) { + return newLucene(docInverterPerThread, shared_from_this(), nextTermsHash, primaryPerThread); +} + +void TermsHash::setFieldInfos(const FieldInfosPtr& fieldInfos) { + this->fieldInfos = fieldInfos; + consumer->setFieldInfos(fieldInfos); +} + +void TermsHash::abort() { + consumer->abort(); + if (nextTermsHash) { + nextTermsHash->abort(); } +} - void TermsHash::shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) - { - BOOST_ASSERT(postingsFreeCount == postingsAllocCount); - - int32_t newSize = 1; - if (newSize != postingsFreeList.size()) - { - if (postingsFreeCount > newSize) - { - if (trackAllocations) - DocumentsWriterPtr(_docWriter)->bytesAllocated(-(postingsFreeCount - newSize) * bytesPerPosting); - postingsFreeCount = newSize; - postingsAllocCount = newSize; +void TermsHash::shrinkFreePostings(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { + BOOST_ASSERT(postingsFreeCount == postingsAllocCount); + + int32_t newSize = 1; + if (newSize != postingsFreeList.size()) { + if (postingsFreeCount > newSize) { + if (trackAllocations) { + DocumentsWriterPtr(_docWriter)->bytesAllocated(-(postingsFreeCount - newSize) * bytesPerPosting); } - postingsFreeList.resize(newSize); + postingsFreeCount = newSize; + postingsAllocCount = newSize; } + postingsFreeList.resize(newSize); } +} - void TermsHash::closeDocStore(const SegmentWriteStatePtr& state) - { - SyncLock syncLock(this); - consumer->closeDocStore(state); - if (nextTermsHash) - nextTermsHash->closeDocStore(state); +void TermsHash::closeDocStore(const SegmentWriteStatePtr& state) { + SyncLock syncLock(this); + consumer->closeDocStore(state); + if (nextTermsHash) { + nextTermsHash->closeDocStore(state); } +} - void TermsHash::flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) - { - SyncLock syncLock(this); - MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField childThreadsAndFields(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::newInstance()); - MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField nextThreadsAndFields; - if (nextTermsHash) - nextThreadsAndFields = MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::newInstance(); - - for (MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) - { - Collection childFields(Collection::newInstance()); - Collection nextChildFields; - if (nextTermsHash) - nextChildFields = Collection::newInstance(); - - for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) - { - childFields.add(boost::static_pointer_cast(*perField)->consumer); - if (nextTermsHash) - nextChildFields.add(boost::static_pointer_cast(*perField)->nextPerField); - } +void TermsHash::flush(MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField threadsAndFields, const SegmentWriteStatePtr& state) { + SyncLock syncLock(this); + MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField childThreadsAndFields(MapTermsHashConsumerPerThreadCollectionTermsHashConsumerPerField::newInstance()); + MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField nextThreadsAndFields; + if (nextTermsHash) { + nextThreadsAndFields = MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::newInstance(); + } - childThreadsAndFields.put(boost::static_pointer_cast(entry->first)->consumer, childFields); - if (nextTermsHash) - nextThreadsAndFields.put(boost::static_pointer_cast(entry->first)->nextPerThread, nextChildFields); + for (MapInvertedDocConsumerPerThreadCollectionInvertedDocConsumerPerField::iterator entry = threadsAndFields.begin(); entry != threadsAndFields.end(); ++entry) { + Collection childFields(Collection::newInstance()); + Collection nextChildFields; + if (nextTermsHash) { + nextChildFields = Collection::newInstance(); } - consumer->flush(childThreadsAndFields, state); - - shrinkFreePostings(threadsAndFields, state); + for (Collection::iterator perField = entry->second.begin(); perField != entry->second.end(); ++perField) { + childFields.add(boost::static_pointer_cast(*perField)->consumer); + if (nextTermsHash) { + nextChildFields.add(boost::static_pointer_cast(*perField)->nextPerField); + } + } - if (nextTermsHash) - nextTermsHash->flush(nextThreadsAndFields, state); + childThreadsAndFields.put(boost::static_pointer_cast(entry->first)->consumer, childFields); + if (nextTermsHash) { + nextThreadsAndFields.put(boost::static_pointer_cast(entry->first)->nextPerThread, nextChildFields); + } } - bool TermsHash::freeRAM() - { - if (!trackAllocations) - return false; - - bool any = false; - int64_t bytesFreed = 0; - { - SyncLock syncLock(this); - int32_t numToFree = postingsFreeCount >= postingsFreeChunk ? postingsFreeChunk : postingsFreeCount; - any = (numToFree > 0); - if (any) - { - MiscUtils::arrayFill(postingsFreeList.begin(), postingsFreeCount - numToFree, postingsFreeCount, RawPostingListPtr()); - postingsFreeCount -= numToFree; - postingsAllocCount -= numToFree; - bytesFreed = -numToFree * bytesPerPosting; - any = true; - } - } + consumer->flush(childThreadsAndFields, state); - if (any) - DocumentsWriterPtr(_docWriter)->bytesAllocated(bytesFreed); + shrinkFreePostings(threadsAndFields, state); - if (nextTermsHash && nextTermsHash->freeRAM()) - any = true; + if (nextTermsHash) { + nextTermsHash->flush(nextThreadsAndFields, state); + } +} - return any; +bool TermsHash::freeRAM() { + if (!trackAllocations) { + return false; } - void TermsHash::recyclePostings(Collection postings, int32_t numPostings) + bool any = false; + int64_t bytesFreed = 0; { SyncLock syncLock(this); - BOOST_ASSERT(postings.size() >= numPostings); + int32_t numToFree = postingsFreeCount >= postingsFreeChunk ? postingsFreeChunk : postingsFreeCount; + any = (numToFree > 0); + if (any) { + MiscUtils::arrayFill(postingsFreeList.begin(), postingsFreeCount - numToFree, postingsFreeCount, RawPostingListPtr()); + postingsFreeCount -= numToFree; + postingsAllocCount -= numToFree; + bytesFreed = -numToFree * bytesPerPosting; + any = true; + } + } - // Move all Postings from this ThreadState back to our free list. We pre-allocated this array while we - // were creating Postings to make sure it's large enough - BOOST_ASSERT(postingsFreeCount + numPostings <= postingsFreeList.size()); - MiscUtils::arrayCopy(postings.begin(), 0, postingsFreeList.begin(), postingsFreeCount, numPostings); - postingsFreeCount += numPostings; + if (any) { + DocumentsWriterPtr(_docWriter)->bytesAllocated(bytesFreed); } - void TermsHash::getPostings(Collection postings) - { - SyncLock syncLock(this); - DocumentsWriterPtr docWriter(_docWriter); - IndexWriterPtr writer(docWriter->_writer); - - BOOST_ASSERT(writer->testPoint(L"TermsHash.getPostings start")); - - BOOST_ASSERT(postingsFreeCount <= postingsFreeList.size()); - BOOST_ASSERT(postingsFreeCount <= postingsAllocCount); - - int32_t numToCopy = postingsFreeCount < postings.size() ? postingsFreeCount : postings.size(); - int32_t start = postingsFreeCount - numToCopy; - BOOST_ASSERT(start >= 0); - BOOST_ASSERT(start + numToCopy <= postingsFreeList.size()); - BOOST_ASSERT(numToCopy <= postings.size()); - MiscUtils::arrayCopy(postingsFreeList.begin(), start, postings.begin(), 0, numToCopy); - - // Directly allocate the remainder if any - if (numToCopy != postings.size()) - { - int32_t extra = postings.size() - numToCopy; - int32_t newPostingsAllocCount = postingsAllocCount + extra; - - consumer->createPostings(postings, numToCopy, extra); - BOOST_ASSERT(writer->testPoint(L"TermsHash.getPostings after create")); - postingsAllocCount += extra; - - if (trackAllocations) - docWriter->bytesAllocated(extra * bytesPerPosting); - - if (newPostingsAllocCount > postingsFreeList.size()) - { - // Pre-allocate the postingsFreeList so it's large enough to hold all postings we've given out - postingsFreeList = Collection::newInstance(MiscUtils::getNextSize(newPostingsAllocCount)); - } + if (nextTermsHash && nextTermsHash->freeRAM()) { + any = true; + } + + return any; +} + +void TermsHash::recyclePostings(Collection postings, int32_t numPostings) { + SyncLock syncLock(this); + BOOST_ASSERT(postings.size() >= numPostings); + + // Move all Postings from this ThreadState back to our free list. We pre-allocated this array while we + // were creating Postings to make sure it's large enough + BOOST_ASSERT(postingsFreeCount + numPostings <= postingsFreeList.size()); + MiscUtils::arrayCopy(postings.begin(), 0, postingsFreeList.begin(), postingsFreeCount, numPostings); + postingsFreeCount += numPostings; +} + +void TermsHash::getPostings(Collection postings) { + SyncLock syncLock(this); + DocumentsWriterPtr docWriter(_docWriter); + IndexWriterPtr writer(docWriter->_writer); + + BOOST_ASSERT(writer->testPoint(L"TermsHash.getPostings start")); + + BOOST_ASSERT(postingsFreeCount <= postingsFreeList.size()); + BOOST_ASSERT(postingsFreeCount <= postingsAllocCount); + + int32_t numToCopy = postingsFreeCount < postings.size() ? postingsFreeCount : postings.size(); + int32_t start = postingsFreeCount - numToCopy; + BOOST_ASSERT(start >= 0); + BOOST_ASSERT(start + numToCopy <= postingsFreeList.size()); + BOOST_ASSERT(numToCopy <= postings.size()); + MiscUtils::arrayCopy(postingsFreeList.begin(), start, postings.begin(), 0, numToCopy); + + // Directly allocate the remainder if any + if (numToCopy != postings.size()) { + int32_t extra = postings.size() - numToCopy; + int32_t newPostingsAllocCount = postingsAllocCount + extra; + + consumer->createPostings(postings, numToCopy, extra); + BOOST_ASSERT(writer->testPoint(L"TermsHash.getPostings after create")); + postingsAllocCount += extra; + + if (trackAllocations) { + docWriter->bytesAllocated(extra * bytesPerPosting); + } + + if (newPostingsAllocCount > postingsFreeList.size()) { + // Pre-allocate the postingsFreeList so it's large enough to hold all postings we've given out + postingsFreeList = Collection::newInstance(MiscUtils::getNextSize(newPostingsAllocCount)); } + } - postingsFreeCount -= numToCopy; + postingsFreeCount -= numToCopy; - if (trackAllocations) - docWriter->bytesUsed(postings.size() * bytesPerPosting); + if (trackAllocations) { + docWriter->bytesUsed(postings.size() * bytesPerPosting); } } + +} diff --git a/src/core/index/TermsHashConsumer.cpp b/src/core/index/TermsHashConsumer.cpp index 49ba2fb1..830127ca 100644 --- a/src/core/index/TermsHashConsumer.cpp +++ b/src/core/index/TermsHashConsumer.cpp @@ -7,14 +7,13 @@ #include "LuceneInc.h" #include "TermsHashConsumer.h" -namespace Lucene -{ - TermsHashConsumer::~TermsHashConsumer() - { - } +namespace Lucene { + +TermsHashConsumer::~TermsHashConsumer() { +} + +void TermsHashConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) { + this->fieldInfos = fieldInfos; +} - void TermsHashConsumer::setFieldInfos(const FieldInfosPtr& fieldInfos) - { - this->fieldInfos = fieldInfos; - } } diff --git a/src/core/index/TermsHashConsumerPerField.cpp b/src/core/index/TermsHashConsumerPerField.cpp index 9e5df4d9..02e9c4b9 100644 --- a/src/core/index/TermsHashConsumerPerField.cpp +++ b/src/core/index/TermsHashConsumerPerField.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "TermsHashConsumerPerField.h" -namespace Lucene -{ - TermsHashConsumerPerField::~TermsHashConsumerPerField() - { - } +namespace Lucene { + +TermsHashConsumerPerField::~TermsHashConsumerPerField() { +} + } diff --git a/src/core/index/TermsHashConsumerPerThread.cpp b/src/core/index/TermsHashConsumerPerThread.cpp index 295cb16f..a2538ace 100644 --- a/src/core/index/TermsHashConsumerPerThread.cpp +++ b/src/core/index/TermsHashConsumerPerThread.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "TermsHashConsumerPerThread.h" -namespace Lucene -{ - TermsHashConsumerPerThread::~TermsHashConsumerPerThread() - { - } +namespace Lucene { + +TermsHashConsumerPerThread::~TermsHashConsumerPerThread() { +} + } diff --git a/src/core/index/TermsHashPerField.cpp b/src/core/index/TermsHashPerField.cpp index 02212110..0a3fa062 100644 --- a/src/core/index/TermsHashPerField.cpp +++ b/src/core/index/TermsHashPerField.cpp @@ -22,519 +22,476 @@ #include "UTF8Stream.h" #include "MiscUtils.h" -namespace Lucene -{ - TermsHashPerField::TermsHashPerField(const DocInverterPerFieldPtr& docInverterPerField, const TermsHashPerThreadPtr& perThread, const TermsHashPerThreadPtr& nextPerThread, const FieldInfoPtr& fieldInfo) - { - this->_docInverterPerField = docInverterPerField; - this->_perThread = perThread; - this->nextPerThread = nextPerThread; - this->fieldInfo = fieldInfo; - } +namespace Lucene { - TermsHashPerField::~TermsHashPerField() - { - } +TermsHashPerField::TermsHashPerField(const DocInverterPerFieldPtr& docInverterPerField, const TermsHashPerThreadPtr& perThread, const TermsHashPerThreadPtr& nextPerThread, const FieldInfoPtr& fieldInfo) { + this->_docInverterPerField = docInverterPerField; + this->_perThread = perThread; + this->nextPerThread = nextPerThread; + this->fieldInfo = fieldInfo; +} - void TermsHashPerField::initialize() - { - this->postingsCompacted = false; - this->numPostings = 0; - this->postingsHashSize = 4; - this->postingsHashHalfSize = this->postingsHashSize / 2; - this->postingsHashMask = this->postingsHashSize - 1; - this->postingsHash = Collection::newInstance(postingsHashSize); - this->doCall = false; - this->doNextCall = false; - this->intUptoStart = 0; +TermsHashPerField::~TermsHashPerField() { +} - TermsHashPerThreadPtr perThread(_perThread); - intPool = perThread->intPool; - charPool = perThread->charPool; - bytePool = perThread->bytePool; - docState = perThread->docState; - DocInverterPerFieldPtr docInverterPerField(_docInverterPerField); - fieldState = docInverterPerField->fieldState; - this->consumer = perThread->consumer->addField(shared_from_this(), fieldInfo); - streamCount = consumer->getStreamCount(); - numPostingInt = 2 * streamCount; - if (nextPerThread) - nextPerField = boost::dynamic_pointer_cast(nextPerThread->addField(docInverterPerField, fieldInfo)); +void TermsHashPerField::initialize() { + this->postingsCompacted = false; + this->numPostings = 0; + this->postingsHashSize = 4; + this->postingsHashHalfSize = this->postingsHashSize / 2; + this->postingsHashMask = this->postingsHashSize - 1; + this->postingsHash = Collection::newInstance(postingsHashSize); + this->doCall = false; + this->doNextCall = false; + this->intUptoStart = 0; + + TermsHashPerThreadPtr perThread(_perThread); + intPool = perThread->intPool; + charPool = perThread->charPool; + bytePool = perThread->bytePool; + docState = perThread->docState; + DocInverterPerFieldPtr docInverterPerField(_docInverterPerField); + fieldState = docInverterPerField->fieldState; + this->consumer = perThread->consumer->addField(shared_from_this(), fieldInfo); + streamCount = consumer->getStreamCount(); + numPostingInt = 2 * streamCount; + if (nextPerThread) { + nextPerField = boost::dynamic_pointer_cast(nextPerThread->addField(docInverterPerField, fieldInfo)); } +} - void TermsHashPerField::shrinkHash(int32_t targetSize) - { - BOOST_ASSERT(postingsCompacted || numPostings == 0); - - int32_t newSize = 4; - if (newSize != postingsHash.size()) - { - postingsHash.resize(newSize); - postingsHashSize = newSize; - postingsHashHalfSize = newSize / 2; - postingsHashMask = newSize - 1; - } - MiscUtils::arrayFill(postingsHash.begin(), 0, postingsHash.size(), RawPostingListPtr()); - } +void TermsHashPerField::shrinkHash(int32_t targetSize) { + BOOST_ASSERT(postingsCompacted || numPostings == 0); - void TermsHashPerField::reset() - { - if (!postingsCompacted) - compactPostings(); - BOOST_ASSERT(numPostings <= postingsHash.size()); - if (numPostings > 0) - { - TermsHashPtr(TermsHashPerThreadPtr(_perThread)->_termsHash)->recyclePostings(postingsHash, numPostings); - MiscUtils::arrayFill(postingsHash.begin(), 0, numPostings, RawPostingListPtr()); - numPostings = 0; - } - postingsCompacted = false; - if (nextPerField) - nextPerField->reset(); + int32_t newSize = 4; + if (newSize != postingsHash.size()) { + postingsHash.resize(newSize); + postingsHashSize = newSize; + postingsHashHalfSize = newSize / 2; + postingsHashMask = newSize - 1; } + MiscUtils::arrayFill(postingsHash.begin(), 0, postingsHash.size(), RawPostingListPtr()); +} - void TermsHashPerField::abort() - { - SyncLock syncLock(this); - reset(); - if (nextPerField) - nextPerField->abort(); +void TermsHashPerField::reset() { + if (!postingsCompacted) { + compactPostings(); } + BOOST_ASSERT(numPostings <= postingsHash.size()); + if (numPostings > 0) { + TermsHashPtr(TermsHashPerThreadPtr(_perThread)->_termsHash)->recyclePostings(postingsHash, numPostings); + MiscUtils::arrayFill(postingsHash.begin(), 0, numPostings, RawPostingListPtr()); + numPostings = 0; + } + postingsCompacted = false; + if (nextPerField) { + nextPerField->reset(); + } +} - void TermsHashPerField::initReader(const ByteSliceReaderPtr& reader, const RawPostingListPtr& p, int32_t stream) - { - BOOST_ASSERT(stream < streamCount); - IntArray ints(intPool->buffers[p->intStart >> DocumentsWriter::INT_BLOCK_SHIFT]); - int32_t upto = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); - reader->init(bytePool, p->byteStart + stream * ByteBlockPool::FIRST_LEVEL_SIZE(), ints[upto + stream]); +void TermsHashPerField::abort() { + SyncLock syncLock(this); + reset(); + if (nextPerField) { + nextPerField->abort(); } +} - void TermsHashPerField::compactPostings() - { - SyncLock syncLock(this); - int32_t upto = 0; - for (int32_t i = 0; i < postingsHashSize; ++i) - { - if (postingsHash[i]) - { - if (upto < i) - { - postingsHash[upto] = postingsHash[i]; - postingsHash[i].reset(); - } - ++upto; +void TermsHashPerField::initReader(const ByteSliceReaderPtr& reader, const RawPostingListPtr& p, int32_t stream) { + BOOST_ASSERT(stream < streamCount); + IntArray ints(intPool->buffers[p->intStart >> DocumentsWriter::INT_BLOCK_SHIFT]); + int32_t upto = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); + reader->init(bytePool, p->byteStart + stream * ByteBlockPool::FIRST_LEVEL_SIZE(), ints[upto + stream]); +} + +void TermsHashPerField::compactPostings() { + SyncLock syncLock(this); + int32_t upto = 0; + for (int32_t i = 0; i < postingsHashSize; ++i) { + if (postingsHash[i]) { + if (upto < i) { + postingsHash[upto] = postingsHash[i]; + postingsHash[i].reset(); } + ++upto; } - - BOOST_ASSERT(upto == numPostings); - postingsCompacted = true; } - struct comparePostings - { - comparePostings(Collection buffers) - { - this->buffers = buffers; + BOOST_ASSERT(upto == numPostings); + postingsCompacted = true; +} + +struct comparePostings { + comparePostings(Collection buffers) { + this->buffers = buffers; } - /// Compares term text for two Posting instance - inline bool operator()(const RawPostingListPtr& first, const RawPostingListPtr& second) const - { - if (first == second) + /// Compares term text for two Posting instance + inline bool operator()(const RawPostingListPtr& first, const RawPostingListPtr& second) const { + if (first == second) { return false; + } - wchar_t* text1 = buffers[first->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); - int32_t pos1 = (first->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - wchar_t* text2 = buffers[second->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); - int32_t pos2 = (second->textStart & DocumentsWriter::CHAR_BLOCK_MASK); + wchar_t* text1 = buffers[first->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); + int32_t pos1 = (first->textStart & DocumentsWriter::CHAR_BLOCK_MASK); + wchar_t* text2 = buffers[second->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); + int32_t pos2 = (second->textStart & DocumentsWriter::CHAR_BLOCK_MASK); BOOST_ASSERT(text1 != text2 || pos1 != pos2); - while (true) - { + while (true) { wchar_t c1 = text1[pos1++]; wchar_t c2 = text2[pos2++]; - if (c1 != c2) - { - if (c2 == UTF8Base::UNICODE_TERMINATOR) + if (c1 != c2) { + if (c2 == UTF8Base::UNICODE_TERMINATOR) { return false; - else if (c1 == UTF8Base::UNICODE_TERMINATOR) + } else if (c1 == UTF8Base::UNICODE_TERMINATOR) { return true; - else + } else { return (c1 < c2); - } - else - { - // This method should never compare equal postings unless first == second + } + } else { + // This method should never compare equal postings unless first == second BOOST_ASSERT(c1 != UTF8Base::UNICODE_TERMINATOR); } } - } + } - Collection buffers; - }; + Collection buffers; +}; - Collection TermsHashPerField::sortPostings() - { - compactPostings(); - std::sort(postingsHash.begin(), postingsHash.begin() + numPostings, comparePostings(charPool->buffers)); - return postingsHash; - } +Collection TermsHashPerField::sortPostings() { + compactPostings(); + std::sort(postingsHash.begin(), postingsHash.begin() + numPostings, comparePostings(charPool->buffers)); + return postingsHash; +} - bool TermsHashPerField::postingEquals(const wchar_t* tokenText, int32_t tokenTextLen) - { - wchar_t* text = TermsHashPerThreadPtr(_perThread)->charPool->buffers[p->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); - BOOST_ASSERT(text); - int32_t pos = (p->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - int32_t tokenPos = 0; - for (; tokenPos < tokenTextLen; ++pos, ++tokenPos) - { - if (tokenText[tokenPos] != text[pos]) - return false; +bool TermsHashPerField::postingEquals(const wchar_t* tokenText, int32_t tokenTextLen) { + wchar_t* text = TermsHashPerThreadPtr(_perThread)->charPool->buffers[p->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT].get(); + BOOST_ASSERT(text); + int32_t pos = (p->textStart & DocumentsWriter::CHAR_BLOCK_MASK); + int32_t tokenPos = 0; + for (; tokenPos < tokenTextLen; ++pos, ++tokenPos) { + if (tokenText[tokenPos] != text[pos]) { + return false; } - return (text[pos] == UTF8Base::UNICODE_TERMINATOR); } + return (text[pos] == UTF8Base::UNICODE_TERMINATOR); +} - void TermsHashPerField::start(const FieldablePtr& field) - { - termAtt = fieldState->attributeSource->addAttribute(); - consumer->start(field); - if (nextPerField) - nextPerField->start(field); +void TermsHashPerField::start(const FieldablePtr& field) { + termAtt = fieldState->attributeSource->addAttribute(); + consumer->start(field); + if (nextPerField) { + nextPerField->start(field); } +} - bool TermsHashPerField::start(Collection fields, int32_t count) - { - doCall = consumer->start(fields, count); - if (nextPerField) - doNextCall = nextPerField->start(fields, count); - return (doCall || doNextCall); +bool TermsHashPerField::start(Collection fields, int32_t count) { + doCall = consumer->start(fields, count); + if (nextPerField) { + doNextCall = nextPerField->start(fields, count); } + return (doCall || doNextCall); +} - void TermsHashPerField::add(int32_t textStart) - { - // Secondary entry point (for 2nd and subsequent TermsHash), we hash by textStart - int32_t code = textStart; - - int32_t hashPos = (code & postingsHashMask); +void TermsHashPerField::add(int32_t textStart) { + // Secondary entry point (for 2nd and subsequent TermsHash), we hash by textStart + int32_t code = textStart; - BOOST_ASSERT(!postingsCompacted); + int32_t hashPos = (code & postingsHashMask); - // Locate RawPostingList in hash - p = postingsHash[hashPos]; + BOOST_ASSERT(!postingsCompacted); - if (p && p->textStart != textStart) - { - // Conflict: keep searching different locations in the hash table. - int32_t inc = (((code >> 8) + code) | 1); - do - { - code += inc; - hashPos = (code & postingsHashMask); - p = postingsHash[hashPos]; - } - while (p && p->textStart != textStart); - } + // Locate RawPostingList in hash + p = postingsHash[hashPos]; - if (!p) - { - // First time we are seeing this token since we last flushed the hash. - TermsHashPerThreadPtr perThread(_perThread); + if (p && p->textStart != textStart) { + // Conflict: keep searching different locations in the hash table. + int32_t inc = (((code >> 8) + code) | 1); + do { + code += inc; + hashPos = (code & postingsHashMask); + p = postingsHash[hashPos]; + } while (p && p->textStart != textStart); + } - // Refill? - if (perThread->freePostingsCount == 0) - perThread->morePostings(); + if (!p) { + // First time we are seeing this token since we last flushed the hash. + TermsHashPerThreadPtr perThread(_perThread); - // Pull next free RawPostingList from free list - p = perThread->freePostings[--perThread->freePostingsCount]; - BOOST_ASSERT(p); + // Refill? + if (perThread->freePostingsCount == 0) { + perThread->morePostings(); + } - p->textStart = textStart; + // Pull next free RawPostingList from free list + p = perThread->freePostings[--perThread->freePostingsCount]; + BOOST_ASSERT(p); - BOOST_ASSERT(!postingsHash[hashPos]); - postingsHash[hashPos] = p; - ++numPostings; + p->textStart = textStart; - if (numPostings == postingsHashHalfSize) - rehashPostings(2 * postingsHashSize); + BOOST_ASSERT(!postingsHash[hashPos]); + postingsHash[hashPos] = p; + ++numPostings; - // Init stream slices - if (numPostingInt + intPool->intUpto > DocumentsWriter::INT_BLOCK_SIZE) - intPool->nextBuffer(); + if (numPostings == postingsHashHalfSize) { + rehashPostings(2 * postingsHashSize); + } - if (DocumentsWriter::BYTE_BLOCK_SIZE - bytePool->byteUpto < numPostingInt * ByteBlockPool::FIRST_LEVEL_SIZE()) - bytePool->nextBuffer(); + // Init stream slices + if (numPostingInt + intPool->intUpto > DocumentsWriter::INT_BLOCK_SIZE) { + intPool->nextBuffer(); + } - intUptos = intPool->buffer; - intUptoStart = intPool->intUpto; - intPool->intUpto += streamCount; + if (DocumentsWriter::BYTE_BLOCK_SIZE - bytePool->byteUpto < numPostingInt * ByteBlockPool::FIRST_LEVEL_SIZE()) { + bytePool->nextBuffer(); + } - p->intStart = intUptoStart + intPool->intOffset; + intUptos = intPool->buffer; + intUptoStart = intPool->intUpto; + intPool->intUpto += streamCount; - for (int32_t i = 0; i < streamCount; ++i) - { - int32_t upto = bytePool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); - intUptos[intUptoStart + i] = upto + bytePool->byteOffset; - } - p->byteStart = intUptos[intUptoStart]; + p->intStart = intUptoStart + intPool->intOffset; - consumer->newTerm(p); - } - else - { - intUptos = intPool->buffers[p->intStart >> DocumentsWriter::INT_BLOCK_SHIFT]; - intUptoStart = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); - consumer->addTerm(p); + for (int32_t i = 0; i < streamCount; ++i) { + int32_t upto = bytePool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); + intUptos[intUptoStart + i] = upto + bytePool->byteOffset; } + p->byteStart = intUptos[intUptoStart]; + + consumer->newTerm(p); + } else { + intUptos = intPool->buffers[p->intStart >> DocumentsWriter::INT_BLOCK_SHIFT]; + intUptoStart = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); + consumer->addTerm(p); } +} - void TermsHashPerField::add() - { - BOOST_ASSERT(!postingsCompacted); +void TermsHashPerField::add() { + BOOST_ASSERT(!postingsCompacted); - // Get the text of this term. - wchar_t* tokenText = termAtt->termBufferArray(); - int32_t tokenTextLen = termAtt->termLength(); + // Get the text of this term. + wchar_t* tokenText = termAtt->termBufferArray(); + int32_t tokenTextLen = termAtt->termLength(); - // Compute hashcode and replace any invalid UTF16 sequences - int32_t downto = tokenTextLen; - int32_t code = 0; + // Compute hashcode and replace any invalid UTF16 sequences + int32_t downto = tokenTextLen; + int32_t code = 0; - while (downto > 0) - { - wchar_t ch = tokenText[--downto]; + while (downto > 0) { + wchar_t ch = tokenText[--downto]; - #ifdef LPP_UNICODE_CHAR_SIZE_2 - if (ch >= UTF8Base::TRAIL_SURROGATE_MIN && ch <= UTF8Base::TRAIL_SURROGATE_MAX) - { - if (downto == 0) - { +#ifdef LPP_UNICODE_CHAR_SIZE_2 + if (ch >= UTF8Base::TRAIL_SURROGATE_MIN && ch <= UTF8Base::TRAIL_SURROGATE_MAX) { + if (downto == 0) { + // Unpaired + ch = UTF8Base::UNICODE_REPLACEMENT_CHAR; + tokenText[downto] = ch; + } else { + wchar_t ch2 = tokenText[downto - 1]; + if (ch2 >= UTF8Base::LEAD_SURROGATE_MIN && ch2 <= UTF8Base::LEAD_SURROGATE_MAX) { + // OK: high followed by low. This is a valid surrogate pair. + code = ((code * 31) + ch) * 31 + ch2; + --downto; + continue; + } else { // Unpaired ch = UTF8Base::UNICODE_REPLACEMENT_CHAR; tokenText[downto] = ch; } - else - { - wchar_t ch2 = tokenText[downto - 1]; - if (ch2 >= UTF8Base::LEAD_SURROGATE_MIN && ch2 <= UTF8Base::LEAD_SURROGATE_MAX) - { - // OK: high followed by low. This is a valid surrogate pair. - code = ((code * 31) + ch) * 31 + ch2; - --downto; - continue; - } - else - { - // Unpaired - ch = UTF8Base::UNICODE_REPLACEMENT_CHAR; - tokenText[downto] = ch; - } - } - } - else if (ch >= UTF8Base::LEAD_SURROGATE_MIN && (ch <= UTF8Base::LEAD_SURROGATE_MAX || ch == UTF8Base::UNICODE_TERMINATOR)) - { - // Unpaired or UTF8Base::UNICODE_TERMINATOR - ch = UTF8Base::UNICODE_REPLACEMENT_CHAR; - tokenText[downto] = ch; - } - #else - if (ch == UTF8Base::UNICODE_TERMINATOR) - { - // Unpaired or UTF8Base::UNICODE_TERMINATOR - ch = UTF8Base::UNICODE_REPLACEMENT_CHAR; - tokenText[downto] = ch; } - #endif - - code = (code * 31) + ch; + } else if (ch >= UTF8Base::LEAD_SURROGATE_MIN && (ch <= UTF8Base::LEAD_SURROGATE_MAX || ch == UTF8Base::UNICODE_TERMINATOR)) { + // Unpaired or UTF8Base::UNICODE_TERMINATOR + ch = UTF8Base::UNICODE_REPLACEMENT_CHAR; + tokenText[downto] = ch; } +#else + if (ch == UTF8Base::UNICODE_TERMINATOR) { + // Unpaired or UTF8Base::UNICODE_TERMINATOR + ch = UTF8Base::UNICODE_REPLACEMENT_CHAR; + tokenText[downto] = ch; + } +#endif - int32_t hashPos = (code & postingsHashMask); + code = (code * 31) + ch; + } - // Locate RawPostingList in hash - p = postingsHash[hashPos]; + int32_t hashPos = (code & postingsHashMask); - if (p && !postingEquals(tokenText, tokenTextLen)) - { - // Conflict: keep searching different locations in the hash table. - int32_t inc = (((code >> 8) + code) | 1); - do - { - code += inc; - hashPos = (code & postingsHashMask); - p = postingsHash[hashPos]; - } - while (p && !postingEquals(tokenText, tokenTextLen)); - } + // Locate RawPostingList in hash + p = postingsHash[hashPos]; + + if (p && !postingEquals(tokenText, tokenTextLen)) { + // Conflict: keep searching different locations in the hash table. + int32_t inc = (((code >> 8) + code) | 1); + do { + code += inc; + hashPos = (code & postingsHashMask); + p = postingsHash[hashPos]; + } while (p && !postingEquals(tokenText, tokenTextLen)); + } - if (!p) - { - // First time we are seeing this token since we last flushed the hash. - int32_t textLen1 = 1 + tokenTextLen; - if (textLen1 + charPool->charUpto > DocumentsWriter::CHAR_BLOCK_SIZE) - { - if (textLen1 > DocumentsWriter::CHAR_BLOCK_SIZE) - { - // Just skip this term, to remain as robust as possible during indexing. A TokenFilter - // can be inserted into the analyzer chain if other behavior is wanted (pruning the term - // to a prefix, throwing an exception, etc). - - if (docState->maxTermPrefix.empty()) - docState->maxTermPrefix.append(tokenText, std::min((int32_t)30, tokenTextLen)); - - consumer->skippingLongTerm(); - return; + if (!p) { + // First time we are seeing this token since we last flushed the hash. + int32_t textLen1 = 1 + tokenTextLen; + if (textLen1 + charPool->charUpto > DocumentsWriter::CHAR_BLOCK_SIZE) { + if (textLen1 > DocumentsWriter::CHAR_BLOCK_SIZE) { + // Just skip this term, to remain as robust as possible during indexing. A TokenFilter + // can be inserted into the analyzer chain if other behavior is wanted (pruning the term + // to a prefix, throwing an exception, etc). + + if (docState->maxTermPrefix.empty()) { + docState->maxTermPrefix.append(tokenText, std::min((int32_t)30, tokenTextLen)); } - charPool->nextBuffer(); - } - TermsHashPerThreadPtr perThread(_perThread); + consumer->skippingLongTerm(); + return; + } + charPool->nextBuffer(); + } - // Refill? - if (perThread->freePostingsCount == 0) - perThread->morePostings(); + TermsHashPerThreadPtr perThread(_perThread); - // Pull next free RawPostingList from free list - p = perThread->freePostings[--perThread->freePostingsCount]; - BOOST_ASSERT(p); + // Refill? + if (perThread->freePostingsCount == 0) { + perThread->morePostings(); + } - wchar_t* text = charPool->buffer.get(); - int32_t textUpto = charPool->charUpto; + // Pull next free RawPostingList from free list + p = perThread->freePostings[--perThread->freePostingsCount]; + BOOST_ASSERT(p); - p->textStart = textUpto + charPool->charOffset; - charPool->charUpto += textLen1; + wchar_t* text = charPool->buffer.get(); + int32_t textUpto = charPool->charUpto; - MiscUtils::arrayCopy(tokenText, 0, text, textUpto, tokenTextLen); - text[textUpto + tokenTextLen] = UTF8Base::UNICODE_TERMINATOR; + p->textStart = textUpto + charPool->charOffset; + charPool->charUpto += textLen1; - BOOST_ASSERT(!postingsHash[hashPos]); - postingsHash[hashPos] = p; - ++numPostings; + MiscUtils::arrayCopy(tokenText, 0, text, textUpto, tokenTextLen); + text[textUpto + tokenTextLen] = UTF8Base::UNICODE_TERMINATOR; - if (numPostings == postingsHashHalfSize) - rehashPostings(2 * postingsHashSize); + BOOST_ASSERT(!postingsHash[hashPos]); + postingsHash[hashPos] = p; + ++numPostings; - // Init stream slices - if (numPostingInt + intPool->intUpto > DocumentsWriter::INT_BLOCK_SIZE) - intPool->nextBuffer(); + if (numPostings == postingsHashHalfSize) { + rehashPostings(2 * postingsHashSize); + } - if (DocumentsWriter::BYTE_BLOCK_SIZE - bytePool->byteUpto < numPostingInt * ByteBlockPool::FIRST_LEVEL_SIZE()) - bytePool->nextBuffer(); + // Init stream slices + if (numPostingInt + intPool->intUpto > DocumentsWriter::INT_BLOCK_SIZE) { + intPool->nextBuffer(); + } - intUptos = intPool->buffer; - intUptoStart = intPool->intUpto; - intPool->intUpto += streamCount; + if (DocumentsWriter::BYTE_BLOCK_SIZE - bytePool->byteUpto < numPostingInt * ByteBlockPool::FIRST_LEVEL_SIZE()) { + bytePool->nextBuffer(); + } - p->intStart = intUptoStart + intPool->intOffset; + intUptos = intPool->buffer; + intUptoStart = intPool->intUpto; + intPool->intUpto += streamCount; - for (int32_t i = 0; i < streamCount; ++i) - { - int32_t upto = bytePool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); - intUptos[intUptoStart + i] = upto + bytePool->byteOffset; - } - p->byteStart = intUptos[intUptoStart]; + p->intStart = intUptoStart + intPool->intOffset; - consumer->newTerm(p); - } - else - { - intUptos = intPool->buffers[p->intStart >> DocumentsWriter::INT_BLOCK_SHIFT]; - intUptoStart = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); - consumer->addTerm(p); + for (int32_t i = 0; i < streamCount; ++i) { + int32_t upto = bytePool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); + intUptos[intUptoStart + i] = upto + bytePool->byteOffset; } + p->byteStart = intUptos[intUptoStart]; - if (doNextCall) - nextPerField->add(p->textStart); + consumer->newTerm(p); + } else { + intUptos = intPool->buffers[p->intStart >> DocumentsWriter::INT_BLOCK_SHIFT]; + intUptoStart = (p->intStart & DocumentsWriter::INT_BLOCK_MASK); + consumer->addTerm(p); } - void TermsHashPerField::writeByte(int32_t stream, int8_t b) - { - int32_t upto = intUptos[intUptoStart + stream]; - ByteArray bytes(bytePool->buffers[upto >> DocumentsWriter::BYTE_BLOCK_SHIFT]); - BOOST_ASSERT(bytes); - int32_t offset = (upto & DocumentsWriter::BYTE_BLOCK_MASK); - if (bytes[offset] != 0) - { - // End of slice; allocate a new one - offset = bytePool->allocSlice(bytes, offset); - bytes = bytePool->buffer; - intUptos[intUptoStart + stream] = offset + bytePool->byteOffset; - } - bytes[offset] = b; - intUptos[intUptoStart + stream]++; + if (doNextCall) { + nextPerField->add(p->textStart); } +} - void TermsHashPerField::writeBytes(int32_t stream, const uint8_t* b, int32_t offset, int32_t length) - { - int32_t end = offset + length; - for (int32_t i = offset; i < end; ++i) - writeByte(stream, b[i]); +void TermsHashPerField::writeByte(int32_t stream, int8_t b) { + int32_t upto = intUptos[intUptoStart + stream]; + ByteArray bytes(bytePool->buffers[upto >> DocumentsWriter::BYTE_BLOCK_SHIFT]); + BOOST_ASSERT(bytes); + int32_t offset = (upto & DocumentsWriter::BYTE_BLOCK_MASK); + if (bytes[offset] != 0) { + // End of slice; allocate a new one + offset = bytePool->allocSlice(bytes, offset); + bytes = bytePool->buffer; + intUptos[intUptoStart + stream] = offset + bytePool->byteOffset; } + bytes[offset] = b; + intUptos[intUptoStart + stream]++; +} - void TermsHashPerField::writeVInt(int32_t stream, int32_t i) - { - BOOST_ASSERT(stream < streamCount); - while ((i & ~0x7f) != 0) - { - writeByte(stream, (uint8_t)((i & 0x7f) | 0x80)); - i = MiscUtils::unsignedShift(i, 7); - } - writeByte(stream, (uint8_t)i); +void TermsHashPerField::writeBytes(int32_t stream, const uint8_t* b, int32_t offset, int32_t length) { + int32_t end = offset + length; + for (int32_t i = offset; i < end; ++i) { + writeByte(stream, b[i]); } +} - void TermsHashPerField::finish() - { - consumer->finish(); - if (nextPerField) - nextPerField->finish(); +void TermsHashPerField::writeVInt(int32_t stream, int32_t i) { + BOOST_ASSERT(stream < streamCount); + while ((i & ~0x7f) != 0) { + writeByte(stream, (uint8_t)((i & 0x7f) | 0x80)); + i = MiscUtils::unsignedShift(i, 7); } + writeByte(stream, (uint8_t)i); +} - void TermsHashPerField::rehashPostings(int32_t newSize) - { - int32_t newMask = newSize - 1; - - Collection newHash(Collection::newInstance(newSize)); - TermsHashPerThreadPtr perThread(_perThread); +void TermsHashPerField::finish() { + consumer->finish(); + if (nextPerField) { + nextPerField->finish(); + } +} - for (int32_t i = 0; i < postingsHashSize; ++i) - { - RawPostingListPtr p0(postingsHash[i]); - if (p0) - { - int32_t code; - if (perThread->primary) - { - int32_t start = (p0->textStart & DocumentsWriter::CHAR_BLOCK_MASK); - CharArray text = charPool->buffers[p0->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]; - int32_t pos = start; - while (text[pos] != UTF8Base::UNICODE_TERMINATOR) - ++pos; - code = 0; - while (pos > start) - code = (code * 31) + text[--pos]; +void TermsHashPerField::rehashPostings(int32_t newSize) { + int32_t newMask = newSize - 1; + + Collection newHash(Collection::newInstance(newSize)); + TermsHashPerThreadPtr perThread(_perThread); + + for (int32_t i = 0; i < postingsHashSize; ++i) { + RawPostingListPtr p0(postingsHash[i]); + if (p0) { + int32_t code; + if (perThread->primary) { + int32_t start = (p0->textStart & DocumentsWriter::CHAR_BLOCK_MASK); + CharArray text = charPool->buffers[p0->textStart >> DocumentsWriter::CHAR_BLOCK_SHIFT]; + int32_t pos = start; + while (text[pos] != UTF8Base::UNICODE_TERMINATOR) { + ++pos; } - else - code = p0->textStart; - - int32_t hashPos = (code & newMask); - BOOST_ASSERT(hashPos >= 0); - if (newHash[hashPos]) - { - int32_t inc = (((code >> 8) + code) | 1); - do - { - code += inc; - hashPos = (code & newMask); - } - while (newHash[hashPos]); + code = 0; + while (pos > start) { + code = (code * 31) + text[--pos]; } - newHash[hashPos] = p0; + } else { + code = p0->textStart; } - } - postingsHashMask = newMask; - postingsHash = newHash; - postingsHashSize = newSize; - postingsHashHalfSize = (newSize >> 1); + int32_t hashPos = (code & newMask); + BOOST_ASSERT(hashPos >= 0); + if (newHash[hashPos]) { + int32_t inc = (((code >> 8) + code) | 1); + do { + code += inc; + hashPos = (code & newMask); + } while (newHash[hashPos]); + } + newHash[hashPos] = p0; + } } + + postingsHashMask = newMask; + postingsHash = newHash; + postingsHashSize = newSize; + postingsHashHalfSize = (newSize >> 1); +} + } diff --git a/src/core/index/TermsHashPerThread.cpp b/src/core/index/TermsHashPerThread.cpp index 22539b81..a68fa9dc 100644 --- a/src/core/index/TermsHashPerThread.cpp +++ b/src/core/index/TermsHashPerThread.cpp @@ -15,112 +15,101 @@ #include "IntBlockPool.h" #include "DocumentsWriter.h" -namespace Lucene -{ - TermsHashPerThread::TermsHashPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPtr& termsHash, const TermsHashPtr& nextTermsHash, const TermsHashPerThreadPtr& primaryPerThread) - { - this->freePostings = Collection::newInstance(256); - this->freePostingsCount = 0; - this->primary = false; - this->_docInverterPerThread = docInverterPerThread; - this->_termsHash = termsHash; - this->nextTermsHash = nextTermsHash; - this->_primaryPerThread = primaryPerThread; - } +namespace Lucene { + +TermsHashPerThread::TermsHashPerThread(const DocInverterPerThreadPtr& docInverterPerThread, const TermsHashPtr& termsHash, const TermsHashPtr& nextTermsHash, const TermsHashPerThreadPtr& primaryPerThread) { + this->freePostings = Collection::newInstance(256); + this->freePostingsCount = 0; + this->primary = false; + this->_docInverterPerThread = docInverterPerThread; + this->_termsHash = termsHash; + this->nextTermsHash = nextTermsHash; + this->_primaryPerThread = primaryPerThread; +} - TermsHashPerThread::~TermsHashPerThread() - { - } +TermsHashPerThread::~TermsHashPerThread() { +} - void TermsHashPerThread::initialize() - { - DocInverterPerThreadPtr docInverterPerThread(_docInverterPerThread); - TermsHashPtr termsHash(_termsHash); - docState = docInverterPerThread->docState; - consumer = termsHash->consumer->addThread(shared_from_this()); - - if (nextTermsHash) - { - // We are primary - charPool = newLucene(DocumentsWriterPtr(termsHash->_docWriter)); - primary = true; - } - else - { - charPool = TermsHashPerThreadPtr(_primaryPerThread)->charPool; - primary = false; - } - - intPool = newLucene(DocumentsWriterPtr(termsHash->_docWriter), termsHash->trackAllocations); - bytePool = newLucene(DocumentsWriterPtr(termsHash->_docWriter)->byteBlockAllocator, termsHash->trackAllocations); - - if (nextTermsHash) - nextPerThread = nextTermsHash->addThread(docInverterPerThread, shared_from_this()); +void TermsHashPerThread::initialize() { + DocInverterPerThreadPtr docInverterPerThread(_docInverterPerThread); + TermsHashPtr termsHash(_termsHash); + docState = docInverterPerThread->docState; + consumer = termsHash->consumer->addThread(shared_from_this()); + + if (nextTermsHash) { + // We are primary + charPool = newLucene(DocumentsWriterPtr(termsHash->_docWriter)); + primary = true; + } else { + charPool = TermsHashPerThreadPtr(_primaryPerThread)->charPool; + primary = false; } - InvertedDocConsumerPerFieldPtr TermsHashPerThread::addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) - { - return newLucene(docInverterPerField, shared_from_this(), nextPerThread, fieldInfo); - } + intPool = newLucene(DocumentsWriterPtr(termsHash->_docWriter), termsHash->trackAllocations); + bytePool = newLucene(DocumentsWriterPtr(termsHash->_docWriter)->byteBlockAllocator, termsHash->trackAllocations); - void TermsHashPerThread::abort() - { - SyncLock syncLock(this); - reset(true); - consumer->abort(); - if (nextPerThread) - nextPerThread->abort(); + if (nextTermsHash) { + nextPerThread = nextTermsHash->addThread(docInverterPerThread, shared_from_this()); } +} + +InvertedDocConsumerPerFieldPtr TermsHashPerThread::addField(const DocInverterPerFieldPtr& docInverterPerField, const FieldInfoPtr& fieldInfo) { + return newLucene(docInverterPerField, shared_from_this(), nextPerThread, fieldInfo); +} - void TermsHashPerThread::morePostings() - { - BOOST_ASSERT(freePostingsCount == 0); - TermsHashPtr(_termsHash)->getPostings(freePostings); - freePostingsCount = freePostings.size(); - BOOST_ASSERT(noNullPostings(freePostings, freePostingsCount, L"consumer=" + consumer->toString())); +void TermsHashPerThread::abort() { + SyncLock syncLock(this); + reset(true); + consumer->abort(); + if (nextPerThread) { + nextPerThread->abort(); } +} - bool TermsHashPerThread::noNullPostings(Collection postings, int32_t count, const String& details) - { - for (int32_t i = 0; i < count; ++i) - { - BOOST_ASSERT(postings[i]); - } - return true; +void TermsHashPerThread::morePostings() { + BOOST_ASSERT(freePostingsCount == 0); + TermsHashPtr(_termsHash)->getPostings(freePostings); + freePostingsCount = freePostings.size(); + BOOST_ASSERT(noNullPostings(freePostings, freePostingsCount, L"consumer=" + consumer->toString())); +} + +bool TermsHashPerThread::noNullPostings(Collection postings, int32_t count, const String& details) { + for (int32_t i = 0; i < count; ++i) { + BOOST_ASSERT(postings[i]); } + return true; +} - void TermsHashPerThread::startDocument() - { - consumer->startDocument(); - if (nextPerThread) - nextPerThread->consumer->startDocument(); +void TermsHashPerThread::startDocument() { + consumer->startDocument(); + if (nextPerThread) { + nextPerThread->consumer->startDocument(); } +} - DocWriterPtr TermsHashPerThread::finishDocument() - { - DocWriterPtr doc(consumer->finishDocument()); - DocWriterPtr doc2(nextPerThread ? nextPerThread->consumer->finishDocument() : DocWriterPtr()); - if (!doc) - return doc2; - else - { - doc->setNext(doc2); - return doc; - } +DocWriterPtr TermsHashPerThread::finishDocument() { + DocWriterPtr doc(consumer->finishDocument()); + DocWriterPtr doc2(nextPerThread ? nextPerThread->consumer->finishDocument() : DocWriterPtr()); + if (!doc) { + return doc2; + } else { + doc->setNext(doc2); + return doc; } +} - void TermsHashPerThread::reset(bool recyclePostings) - { - intPool->reset(); - bytePool->reset(); +void TermsHashPerThread::reset(bool recyclePostings) { + intPool->reset(); + bytePool->reset(); - if (primary) - charPool->reset(); + if (primary) { + charPool->reset(); + } - if (recyclePostings) - { - TermsHashPtr(_termsHash)->recyclePostings(freePostings, freePostingsCount); - freePostingsCount = 0; - } + if (recyclePostings) { + TermsHashPtr(_termsHash)->recyclePostings(freePostings, freePostingsCount); + freePostingsCount = 0; } } + +} diff --git a/src/core/msvc/dllmain.cpp b/src/core/msvc/dllmain.cpp index 02ab59e1..4c9bd0f4 100644 --- a/src/core/msvc/dllmain.cpp +++ b/src/core/msvc/dllmain.cpp @@ -8,15 +8,13 @@ #if defined(_WIN32) && defined(LPP_HAVE_DLL) -BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; +BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; } return TRUE; } diff --git a/src/core/queryparser/FastCharStream.cpp b/src/core/queryparser/FastCharStream.cpp index 77a8f7da..aca48889 100644 --- a/src/core/queryparser/FastCharStream.cpp +++ b/src/core/queryparser/FastCharStream.cpp @@ -9,116 +9,101 @@ #include "Reader.h" #include "MiscUtils.h" -namespace Lucene -{ - FastCharStream::FastCharStream(const ReaderPtr& reader) - { - input = reader; - bufferLength = 0; - bufferPosition = 0; - tokenStart = 0; - bufferStart = 0; - } +namespace Lucene { + +FastCharStream::FastCharStream(const ReaderPtr& reader) { + input = reader; + bufferLength = 0; + bufferPosition = 0; + tokenStart = 0; + bufferStart = 0; +} - FastCharStream::~FastCharStream() - { - } +FastCharStream::~FastCharStream() { +} - wchar_t FastCharStream::readChar() - { - if (bufferPosition >= bufferLength) - refill(); - return buffer[bufferPosition++]; +wchar_t FastCharStream::readChar() { + if (bufferPosition >= bufferLength) { + refill(); } + return buffer[bufferPosition++]; +} - void FastCharStream::refill() - { - int32_t newPosition = bufferLength - tokenStart; +void FastCharStream::refill() { + int32_t newPosition = bufferLength - tokenStart; - if (tokenStart == 0) // token won't fit in buffer - { - if (!buffer) - buffer = CharArray::newInstance(2048); - else if (bufferLength == buffer.size()) // grow buffer - buffer.resize(buffer.size() * 2); + if (tokenStart == 0) { // token won't fit in buffer + if (!buffer) { + buffer = CharArray::newInstance(2048); + } else if (bufferLength == buffer.size()) { // grow buffer + buffer.resize(buffer.size() * 2); } - else // shift token to front - MiscUtils::arrayCopy(buffer.get(), tokenStart, buffer.get(), 0, newPosition); - - bufferLength = newPosition; // update state - bufferPosition = newPosition; - bufferStart += tokenStart; - tokenStart = 0; - - int32_t charsRead = input->read(buffer.get(), newPosition, buffer.size() - newPosition); // fill space in buffer - if (charsRead == -1) - boost::throw_exception(IOException(L"read past eof")); - else - bufferLength += charsRead; + } else { // shift token to front + MiscUtils::arrayCopy(buffer.get(), tokenStart, buffer.get(), 0, newPosition); } - wchar_t FastCharStream::BeginToken() - { - tokenStart = bufferPosition; - return readChar(); - } + bufferLength = newPosition; // update state + bufferPosition = newPosition; + bufferStart += tokenStart; + tokenStart = 0; - void FastCharStream::backup(int32_t amount) - { - bufferPosition -= amount; + int32_t charsRead = input->read(buffer.get(), newPosition, buffer.size() - newPosition); // fill space in buffer + if (charsRead == -1) { + boost::throw_exception(IOException(L"read past eof")); + } else { + bufferLength += charsRead; } +} - String FastCharStream::GetImage() - { - return String(buffer.get() + tokenStart, bufferPosition - tokenStart); - } +wchar_t FastCharStream::BeginToken() { + tokenStart = bufferPosition; + return readChar(); +} - CharArray FastCharStream::GetSuffix(int32_t length) - { - CharArray value(CharArray::newInstance(length)); - MiscUtils::arrayCopy(buffer.get(), bufferPosition - length, value.get(), 0, length); - return value; - } +void FastCharStream::backup(int32_t amount) { + bufferPosition -= amount; +} - void FastCharStream::Done() - { - try - { - input->close(); - } - catch (IOException&) - { - // ignore IO exceptions - } - } +String FastCharStream::GetImage() { + return String(buffer.get() + tokenStart, bufferPosition - tokenStart); +} - int32_t FastCharStream::getColumn() - { - return bufferStart + bufferPosition; - } +CharArray FastCharStream::GetSuffix(int32_t length) { + CharArray value(CharArray::newInstance(length)); + MiscUtils::arrayCopy(buffer.get(), bufferPosition - length, value.get(), 0, length); + return value; +} - int32_t FastCharStream::getLine() - { - return 1; +void FastCharStream::Done() { + try { + input->close(); + } catch (IOException&) { + // ignore IO exceptions } +} - int32_t FastCharStream::getEndColumn() - { - return bufferStart + bufferPosition; - } +int32_t FastCharStream::getColumn() { + return bufferStart + bufferPosition; +} - int32_t FastCharStream::getEndLine() - { - return 1; - } +int32_t FastCharStream::getLine() { + return 1; +} - int32_t FastCharStream::getBeginColumn() - { - return bufferStart + tokenStart; - } +int32_t FastCharStream::getEndColumn() { + return bufferStart + bufferPosition; +} + +int32_t FastCharStream::getEndLine() { + return 1; +} + +int32_t FastCharStream::getBeginColumn() { + return bufferStart + tokenStart; +} + +int32_t FastCharStream::getBeginLine() { + return 1; +} - int32_t FastCharStream::getBeginLine() - { - return 1; - } } diff --git a/src/core/queryparser/MultiFieldQueryParser.cpp b/src/core/queryparser/MultiFieldQueryParser.cpp index e3353d31..05aa84b3 100644 --- a/src/core/queryparser/MultiFieldQueryParser.cpp +++ b/src/core/queryparser/MultiFieldQueryParser.cpp @@ -12,157 +12,148 @@ #include "MultiPhraseQuery.h" #include "MiscUtils.h" -namespace Lucene -{ - MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer, MapStringDouble boosts) : QueryParser(matchVersion, L"", analyzer) - { - this->boosts = boosts; - this->fields = fields; - } +namespace Lucene { - MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer) : QueryParser(matchVersion, L"", analyzer) - { - this->fields = fields; - } +MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer, MapStringDouble boosts) : QueryParser(matchVersion, L"", analyzer) { + this->boosts = boosts; + this->fields = fields; +} - MultiFieldQueryParser::~MultiFieldQueryParser() - { - } +MultiFieldQueryParser::MultiFieldQueryParser(LuceneVersion::Version matchVersion, Collection fields, const AnalyzerPtr& analyzer) : QueryParser(matchVersion, L"", analyzer) { + this->fields = fields; +} + +MultiFieldQueryParser::~MultiFieldQueryParser() { +} - QueryPtr MultiFieldQueryParser::getFieldQuery(const String& field, const String& queryText, int32_t slop) - { - if (field.empty()) - { - Collection clauses(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - QueryPtr query(QueryParser::getFieldQuery(*field, queryText)); - if (query) - { - // If the user passes a map of boosts - if (boosts) - { - // Get the boost from the map and apply them - MapStringDouble::iterator boost = boosts.find(*field); - if (boost != boosts.end()) - query->setBoost(boost->second); +QueryPtr MultiFieldQueryParser::getFieldQuery(const String& field, const String& queryText, int32_t slop) { + if (field.empty()) { + Collection clauses(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + QueryPtr query(QueryParser::getFieldQuery(*field, queryText)); + if (query) { + // If the user passes a map of boosts + if (boosts) { + // Get the boost from the map and apply them + MapStringDouble::iterator boost = boosts.find(*field); + if (boost != boosts.end()) { + query->setBoost(boost->second); } - applySlop(query, slop); - clauses.add(newLucene(query, BooleanClause::SHOULD)); } + applySlop(query, slop); + clauses.add(newLucene(query, BooleanClause::SHOULD)); } - if (clauses.empty()) // happens for stopwords - return QueryPtr(); - return getBooleanQuery(clauses, true); } - QueryPtr query(QueryParser::getFieldQuery(field, queryText)); - applySlop(query, slop); - return query; + if (clauses.empty()) { // happens for stopwords + return QueryPtr(); + } + return getBooleanQuery(clauses, true); } + QueryPtr query(QueryParser::getFieldQuery(field, queryText)); + applySlop(query, slop); + return query; +} - QueryPtr MultiFieldQueryParser::getFieldQuery(const String& field, const String& queryText) - { - return getFieldQuery(field, queryText, 0); - } +QueryPtr MultiFieldQueryParser::getFieldQuery(const String& field, const String& queryText) { + return getFieldQuery(field, queryText, 0); +} - void MultiFieldQueryParser::applySlop(const QueryPtr& query, int32_t slop) - { - if (MiscUtils::typeOf(query)) - boost::dynamic_pointer_cast(query)->setSlop(slop); - if (MiscUtils::typeOf(query)) - boost::dynamic_pointer_cast(query)->setSlop(slop); +void MultiFieldQueryParser::applySlop(const QueryPtr& query, int32_t slop) { + if (MiscUtils::typeOf(query)) { + boost::dynamic_pointer_cast(query)->setSlop(slop); + } + if (MiscUtils::typeOf(query)) { + boost::dynamic_pointer_cast(query)->setSlop(slop); } +} - QueryPtr MultiFieldQueryParser::getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) - { - if (field.empty()) - { - Collection clauses(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - clauses.add(newLucene(getFuzzyQuery(*field, termStr, minSimilarity), BooleanClause::SHOULD)); - return getBooleanQuery(clauses, true); +QueryPtr MultiFieldQueryParser::getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) { + if (field.empty()) { + Collection clauses(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + clauses.add(newLucene(getFuzzyQuery(*field, termStr, minSimilarity), BooleanClause::SHOULD)); } - return QueryParser::getFuzzyQuery(field, termStr, minSimilarity); + return getBooleanQuery(clauses, true); } + return QueryParser::getFuzzyQuery(field, termStr, minSimilarity); +} - QueryPtr MultiFieldQueryParser::getPrefixQuery(const String& field, const String& termStr) - { - if (field.empty()) - { - Collection clauses(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - clauses.add(newLucene(getPrefixQuery(*field, termStr), BooleanClause::SHOULD)); - return getBooleanQuery(clauses, true); +QueryPtr MultiFieldQueryParser::getPrefixQuery(const String& field, const String& termStr) { + if (field.empty()) { + Collection clauses(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + clauses.add(newLucene(getPrefixQuery(*field, termStr), BooleanClause::SHOULD)); } - return QueryParser::getPrefixQuery(field, termStr); + return getBooleanQuery(clauses, true); } + return QueryParser::getPrefixQuery(field, termStr); +} - QueryPtr MultiFieldQueryParser::getWildcardQuery(const String& field, const String& termStr) - { - if (field.empty()) - { - Collection clauses(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - clauses.add(newLucene(getWildcardQuery(*field, termStr), BooleanClause::SHOULD)); - return getBooleanQuery(clauses, true); +QueryPtr MultiFieldQueryParser::getWildcardQuery(const String& field, const String& termStr) { + if (field.empty()) { + Collection clauses(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + clauses.add(newLucene(getWildcardQuery(*field, termStr), BooleanClause::SHOULD)); } - return QueryParser::getWildcardQuery(field, termStr); + return getBooleanQuery(clauses, true); } + return QueryParser::getWildcardQuery(field, termStr); +} - QueryPtr MultiFieldQueryParser::getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) - { - if (field.empty()) - { - Collection clauses(Collection::newInstance()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - clauses.add(newLucene(getRangeQuery(*field, part1, part2, inclusive), BooleanClause::SHOULD)); - return getBooleanQuery(clauses, true); +QueryPtr MultiFieldQueryParser::getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) { + if (field.empty()) { + Collection clauses(Collection::newInstance()); + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + clauses.add(newLucene(getRangeQuery(*field, part1, part2, inclusive), BooleanClause::SHOULD)); } - return QueryParser::getRangeQuery(field, part1, part2, inclusive); + return getBooleanQuery(clauses, true); } + return QueryParser::getRangeQuery(field, part1, part2, inclusive); +} - QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, const AnalyzerPtr& analyzer) - { - if (queries.size() != fields.size()) - boost::throw_exception(IllegalArgumentException(L"queries.size() != fields.size()")); - BooleanQueryPtr booleanQuery(newLucene()); - for (int32_t i = 0; i < fields.size(); ++i) - { - QueryParserPtr queryParser(newLucene(matchVersion, fields[i], analyzer)); - QueryPtr query(queryParser->parse(queries[i])); - if (query && (!MiscUtils::typeOf(query) || !boost::dynamic_pointer_cast(query)->getClauses().empty())) - booleanQuery->add(query, BooleanClause::SHOULD); +QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, const AnalyzerPtr& analyzer) { + if (queries.size() != fields.size()) { + boost::throw_exception(IllegalArgumentException(L"queries.size() != fields.size()")); + } + BooleanQueryPtr booleanQuery(newLucene()); + for (int32_t i = 0; i < fields.size(); ++i) { + QueryParserPtr queryParser(newLucene(matchVersion, fields[i], analyzer)); + QueryPtr query(queryParser->parse(queries[i])); + if (query && (!MiscUtils::typeOf(query) || !boost::dynamic_pointer_cast(query)->getClauses().empty())) { + booleanQuery->add(query, BooleanClause::SHOULD); } - return booleanQuery; } + return booleanQuery; +} - QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, const AnalyzerPtr& analyzer) - { - if (fields.size() != flags.size()) - boost::throw_exception(IllegalArgumentException(L"fields.size() != flags.size()")); - BooleanQueryPtr booleanQuery(newLucene()); - for (int32_t i = 0; i < fields.size(); ++i) - { - QueryParserPtr queryParser(newLucene(matchVersion, fields[i], analyzer)); - QueryPtr q(queryParser->parse(query)); - if (q && (!MiscUtils::typeOf(q) || !boost::dynamic_pointer_cast(q)->getClauses().empty())) - booleanQuery->add(q, flags[i]); +QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, const String& query, Collection fields, Collection flags, const AnalyzerPtr& analyzer) { + if (fields.size() != flags.size()) { + boost::throw_exception(IllegalArgumentException(L"fields.size() != flags.size()")); + } + BooleanQueryPtr booleanQuery(newLucene()); + for (int32_t i = 0; i < fields.size(); ++i) { + QueryParserPtr queryParser(newLucene(matchVersion, fields[i], analyzer)); + QueryPtr q(queryParser->parse(query)); + if (q && (!MiscUtils::typeOf(q) || !boost::dynamic_pointer_cast(q)->getClauses().empty())) { + booleanQuery->add(q, flags[i]); } - return booleanQuery; } + return booleanQuery; +} - QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, const AnalyzerPtr& analyzer) - { - if (queries.size() != fields.size() || fields.size() != flags.size()) - boost::throw_exception(IllegalArgumentException(L"queries, fields, and flags array have have different length")); - BooleanQueryPtr booleanQuery(newLucene()); - for (int32_t i = 0; i < fields.size(); ++i) - { - QueryParserPtr queryParser(newLucene(matchVersion, fields[i], analyzer)); - QueryPtr query(queryParser->parse(queries[i])); - if (query && (!MiscUtils::typeOf(query) || !boost::dynamic_pointer_cast(query)->getClauses().empty())) - booleanQuery->add(query, flags[i]); +QueryPtr MultiFieldQueryParser::parse(LuceneVersion::Version matchVersion, Collection queries, Collection fields, Collection flags, const AnalyzerPtr& analyzer) { + if (queries.size() != fields.size() || fields.size() != flags.size()) { + boost::throw_exception(IllegalArgumentException(L"queries, fields, and flags array have have different length")); + } + BooleanQueryPtr booleanQuery(newLucene()); + for (int32_t i = 0; i < fields.size(); ++i) { + QueryParserPtr queryParser(newLucene(matchVersion, fields[i], analyzer)); + QueryPtr query(queryParser->parse(queries[i])); + if (query && (!MiscUtils::typeOf(query) || !boost::dynamic_pointer_cast(query)->getClauses().empty())) { + booleanQuery->add(query, flags[i]); } - return booleanQuery; } + return booleanQuery; +} + } diff --git a/src/core/queryparser/QueryParseError.cpp b/src/core/queryparser/QueryParseError.cpp index 5ea10c4b..5eec7525 100644 --- a/src/core/queryparser/QueryParseError.cpp +++ b/src/core/queryparser/QueryParseError.cpp @@ -9,109 +9,106 @@ #include "QueryParserToken.h" #include "StringUtils.h" -namespace Lucene -{ - QueryParseError::~QueryParseError() - { - } +namespace Lucene { + +QueryParseError::~QueryParseError() { +} - String QueryParseError::lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, - const String& errorAfter, wchar_t curChar) - { - StringStream buffer; - buffer << L"Lexical error at line " << errorLine << L", column " << errorColumn << L". Encountered:"; - if (EOFSeen) - buffer << L""; - else - buffer << L"\"" << addEscapes(String(1, curChar)) << L"\""; - buffer << L" (" << (int32_t)curChar << L"), after : \"" << addEscapes(errorAfter) + L"\""; - return buffer.str(); +String QueryParseError::lexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, + const String& errorAfter, wchar_t curChar) { + StringStream buffer; + buffer << L"Lexical error at line " << errorLine << L", column " << errorColumn << L". Encountered:"; + if (EOFSeen) { + buffer << L""; + } else { + buffer << L"\"" << addEscapes(String(1, curChar)) << L"\""; } + buffer << L" (" << (int32_t)curChar << L"), after : \"" << addEscapes(errorAfter) + L"\""; + return buffer.str(); +} - String QueryParseError::parseError(const QueryParserTokenPtr& currentToken, Collection< Collection > expectedTokenSequences, - Collection tokenImage) - { - StringStream expected; - int32_t maxSize = 0; - for (int32_t i = 0; i < expectedTokenSequences.size(); ++i) - { - if (maxSize < expectedTokenSequences[i].size()) - maxSize = expectedTokenSequences[i].size(); - for (int32_t j = 0; j < expectedTokenSequences[i].size(); ++j) - expected << tokenImage[expectedTokenSequences[i][j]] << L" "; - if (expectedTokenSequences[i][expectedTokenSequences[i].size() - 1] != 0) - expected << L"..."; - expected << L"\n "; +String QueryParseError::parseError(const QueryParserTokenPtr& currentToken, Collection< Collection > expectedTokenSequences, + Collection tokenImage) { + StringStream expected; + int32_t maxSize = 0; + for (int32_t i = 0; i < expectedTokenSequences.size(); ++i) { + if (maxSize < expectedTokenSequences[i].size()) { + maxSize = expectedTokenSequences[i].size(); } - StringStream retval; - retval << L"Encountered \""; - QueryParserTokenPtr token(currentToken->next); - for (int32_t i = 0; i < maxSize; ++i) - { - if (i != 0) - retval << L" "; - if (token->kind == 0) - { - retval << tokenImage[0]; - break; - } - retval << L" " << tokenImage[token->kind] << L" \"" << addEscapes(token->image) << L" \""; - token = token->next; + for (int32_t j = 0; j < expectedTokenSequences[i].size(); ++j) { + expected << tokenImage[expectedTokenSequences[i][j]] << L" "; + } + if (expectedTokenSequences[i][expectedTokenSequences[i].size() - 1] != 0) { + expected << L"..."; } - retval << L"\" at line " << currentToken->next->beginLine << L", column " << currentToken->next->beginColumn; - retval << L".\n"; - if (expectedTokenSequences.size() == 1) - retval << L"Was expecting:\n "; - else - retval << L"Was expecting one of:\n "; - retval << expected.str(); - return retval.str(); + expected << L"\n "; } + StringStream retval; + retval << L"Encountered \""; + QueryParserTokenPtr token(currentToken->next); + for (int32_t i = 0; i < maxSize; ++i) { + if (i != 0) { + retval << L" "; + } + if (token->kind == 0) { + retval << tokenImage[0]; + break; + } + retval << L" " << tokenImage[token->kind] << L" \"" << addEscapes(token->image) << L" \""; + token = token->next; + } + retval << L"\" at line " << currentToken->next->beginLine << L", column " << currentToken->next->beginColumn; + retval << L".\n"; + if (expectedTokenSequences.size() == 1) { + retval << L"Was expecting:\n "; + } else { + retval << L"Was expecting one of:\n "; + } + retval << expected.str(); + return retval.str(); +} - String QueryParseError::addEscapes(const String& str) - { - StringStream buffer; - for (String::const_iterator ch = str.begin(); ch != str.end(); ++ch) - { - switch (*ch) - { - case L'\0': - continue; - case L'\b': - buffer << L"\\b"; - continue; - case L'\t': - buffer << L"\\t"; - continue; - case L'\n': - buffer << L"\\n"; - continue; - case L'\f': - buffer << L"\\f"; - continue; - case L'\r': - buffer << L"\\r"; - continue; - case L'\"': - buffer << L"\\\""; - continue; - case L'\'': - buffer << L"\\\'"; - continue; - case L'\\': - buffer << L"\\\\"; - continue; - default: - if (*ch < 0x20 || *ch > 0x7e) - { - String hexChar(L"0000" + StringUtils::toString(*ch, 16)); - buffer << L"\\u" + hexChar.substr(hexChar.length() - 4); - } - else - buffer << *ch; - continue; +String QueryParseError::addEscapes(const String& str) { + StringStream buffer; + for (String::const_iterator ch = str.begin(); ch != str.end(); ++ch) { + switch (*ch) { + case L'\0': + continue; + case L'\b': + buffer << L"\\b"; + continue; + case L'\t': + buffer << L"\\t"; + continue; + case L'\n': + buffer << L"\\n"; + continue; + case L'\f': + buffer << L"\\f"; + continue; + case L'\r': + buffer << L"\\r"; + continue; + case L'\"': + buffer << L"\\\""; + continue; + case L'\'': + buffer << L"\\\'"; + continue; + case L'\\': + buffer << L"\\\\"; + continue; + default: + if (*ch < 0x20 || *ch > 0x7e) { + String hexChar(L"0000" + StringUtils::toString(*ch, 16)); + buffer << L"\\u" + hexChar.substr(hexChar.length() - 4); + } else { + buffer << *ch; } + continue; } - return buffer.str(); } + return buffer.str(); +} + } diff --git a/src/core/queryparser/QueryParser.cpp b/src/core/queryparser/QueryParser.cpp index bc3cf838..2f41c8a6 100644 --- a/src/core/queryparser/QueryParser.cpp +++ b/src/core/queryparser/QueryParser.cpp @@ -32,1540 +32,1358 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t QueryParser::CONJ_NONE = 0; - const int32_t QueryParser::CONJ_AND = 1; - const int32_t QueryParser::CONJ_OR = 2; - - const int32_t QueryParser::MOD_NONE = 0; - const int32_t QueryParser::MOD_NOT = 10; - const int32_t QueryParser::MOD_REQ = 11; - - const int32_t QueryParser::jj_la1_0[] = - { - 0x300, 0x300, 0x1c00, 0x1c00, 0x3ed3f00, 0x90000, 0x20000, 0x3ed2000, 0x2690000, 0x100000, 0x100000, 0x20000, - 0x30000000, 0x4000000, 0x30000000, 0x20000, 0x0, 0x40000000, 0x0, 0x20000, 0x100000, 0x20000, 0x3ed0000 - }; - - const int32_t QueryParser::jj_la1_1[] = - { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0 - }; - - QueryParser::QueryParser(LuceneVersion::Version matchVersion, const String& field, const AnalyzerPtr& analyzer) - { - ConstructParser(newLucene(newLucene(L"")), QueryParserTokenManagerPtr()); - this->analyzer = analyzer; - this->field = field; - this->enablePositionIncrements = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_29); - } - - QueryParser::QueryParser(const QueryParserCharStreamPtr& stream) - { - ConstructParser(stream, QueryParserTokenManagerPtr()); - } - - QueryParser::QueryParser(const QueryParserTokenManagerPtr& tokenMgr) - { - ConstructParser(QueryParserCharStreamPtr(), tokenMgr); - } - - QueryParser::~QueryParser() - { - } - - void QueryParser::ConstructParser(const QueryParserCharStreamPtr& stream, const QueryParserTokenManagerPtr& tokenMgr) - { - _operator = OR_OPERATOR; - lowercaseExpandedTerms = true; - multiTermRewriteMethod = MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(); - allowLeadingWildcard = false; - enablePositionIncrements = true; - phraseSlop = 0; - fuzzyMinSim = FuzzyQuery::defaultMinSimilarity(); - fuzzyPrefixLength = FuzzyQuery::defaultPrefixLength; - locale = std::locale(); - dateResolution = DateTools::RESOLUTION_NULL; - - token_source = tokenMgr ? tokenMgr : newLucene(stream); - token = newLucene(); - _jj_ntk = -1; - jj_la = 0; - jj_gen = 0; - jj_rescan = false; - jj_gc = 0; - jj_la1 = Collection::newInstance(23); - jj_2_rtns = Collection::newInstance(1); - for (int32_t i = 0; i < 23; ++i) - jj_la1[i] = -1; - for (int32_t i = 0; i < jj_2_rtns.size(); ++i) - jj_2_rtns[i] = newInstance(); - jj_expentries = Collection< Collection >::newInstance(); - jj_kind = -1; - jj_lasttokens = Collection::newInstance(100); - jj_endpos = 0; - } +namespace Lucene { + +const int32_t QueryParser::CONJ_NONE = 0; +const int32_t QueryParser::CONJ_AND = 1; +const int32_t QueryParser::CONJ_OR = 2; + +const int32_t QueryParser::MOD_NONE = 0; +const int32_t QueryParser::MOD_NOT = 10; +const int32_t QueryParser::MOD_REQ = 11; + +const int32_t QueryParser::jj_la1_0[] = { + 0x300, 0x300, 0x1c00, 0x1c00, 0x3ed3f00, 0x90000, 0x20000, 0x3ed2000, 0x2690000, 0x100000, 0x100000, 0x20000, + 0x30000000, 0x4000000, 0x30000000, 0x20000, 0x0, 0x40000000, 0x0, 0x20000, 0x100000, 0x20000, 0x3ed0000 +}; + +const int32_t QueryParser::jj_la1_1[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0 +}; + +QueryParser::QueryParser(LuceneVersion::Version matchVersion, const String& field, const AnalyzerPtr& analyzer) { + ConstructParser(newLucene(newLucene(L"")), QueryParserTokenManagerPtr()); + this->analyzer = analyzer; + this->field = field; + this->enablePositionIncrements = LuceneVersion::onOrAfter(matchVersion, LuceneVersion::LUCENE_29); +} - QueryPtr QueryParser::parse(const String& query) - { - ReInit(newLucene(newLucene(query))); - try - { - // TopLevelQuery is a Query followed by the end-of-input (EOF) - QueryPtr res(TopLevelQuery(field)); - return res ? res : newBooleanQuery(false); - } - catch (QueryParserError& e) - { - boost::throw_exception(QueryParserError(L"Cannot parse '" + query + L"': " + e.getError())); - } - catch (TooManyClausesException&) - { - boost::throw_exception(QueryParserError(L"Cannot parse '" + query + L"': too many boolean clauses")); - } - return QueryPtr(); - } +QueryParser::QueryParser(const QueryParserCharStreamPtr& stream) { + ConstructParser(stream, QueryParserTokenManagerPtr()); +} - AnalyzerPtr QueryParser::getAnalyzer() - { - return analyzer; - } +QueryParser::QueryParser(const QueryParserTokenManagerPtr& tokenMgr) { + ConstructParser(QueryParserCharStreamPtr(), tokenMgr); +} - String QueryParser::getField() - { - return field; - } +QueryParser::~QueryParser() { +} - double QueryParser::getFuzzyMinSim() - { - return fuzzyMinSim; - } +void QueryParser::ConstructParser(const QueryParserCharStreamPtr& stream, const QueryParserTokenManagerPtr& tokenMgr) { + _operator = OR_OPERATOR; + lowercaseExpandedTerms = true; + multiTermRewriteMethod = MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(); + allowLeadingWildcard = false; + enablePositionIncrements = true; + phraseSlop = 0; + fuzzyMinSim = FuzzyQuery::defaultMinSimilarity(); + fuzzyPrefixLength = FuzzyQuery::defaultPrefixLength; + locale = std::locale(); + dateResolution = DateTools::RESOLUTION_NULL; + + token_source = tokenMgr ? tokenMgr : newLucene(stream); + token = newLucene(); + _jj_ntk = -1; + jj_la = 0; + jj_gen = 0; + jj_rescan = false; + jj_gc = 0; + jj_la1 = Collection::newInstance(23); + jj_2_rtns = Collection::newInstance(1); + for (int32_t i = 0; i < 23; ++i) { + jj_la1[i] = -1; + } + for (int32_t i = 0; i < jj_2_rtns.size(); ++i) { + jj_2_rtns[i] = newInstance(); + } + jj_expentries = Collection< Collection >::newInstance(); + jj_kind = -1; + jj_lasttokens = Collection::newInstance(100); + jj_endpos = 0; +} - void QueryParser::setFuzzyMinSim(double fuzzyMinSim) - { - this->fuzzyMinSim = fuzzyMinSim; - } +QueryPtr QueryParser::parse(const String& query) { + ReInit(newLucene(newLucene(query))); + try { + // TopLevelQuery is a Query followed by the end-of-input (EOF) + QueryPtr res(TopLevelQuery(field)); + return res ? res : newBooleanQuery(false); + } catch (QueryParserError& e) { + boost::throw_exception(QueryParserError(L"Cannot parse '" + query + L"': " + e.getError())); + } catch (TooManyClausesException&) { + boost::throw_exception(QueryParserError(L"Cannot parse '" + query + L"': too many boolean clauses")); + } + return QueryPtr(); +} - int32_t QueryParser::getFuzzyPrefixLength() - { - return fuzzyPrefixLength; - } +AnalyzerPtr QueryParser::getAnalyzer() { + return analyzer; +} - void QueryParser::setFuzzyPrefixLength(int32_t fuzzyPrefixLength) - { - this->fuzzyPrefixLength = fuzzyPrefixLength; - } +String QueryParser::getField() { + return field; +} - void QueryParser::setPhraseSlop(int32_t phraseSlop) - { - this->phraseSlop = phraseSlop; - } +double QueryParser::getFuzzyMinSim() { + return fuzzyMinSim; +} - int32_t QueryParser::getPhraseSlop() - { - return phraseSlop; - } +void QueryParser::setFuzzyMinSim(double fuzzyMinSim) { + this->fuzzyMinSim = fuzzyMinSim; +} - void QueryParser::setAllowLeadingWildcard(bool allowLeadingWildcard) - { - this->allowLeadingWildcard = allowLeadingWildcard; - } +int32_t QueryParser::getFuzzyPrefixLength() { + return fuzzyPrefixLength; +} - bool QueryParser::getAllowLeadingWildcard() - { - return allowLeadingWildcard; - } +void QueryParser::setFuzzyPrefixLength(int32_t fuzzyPrefixLength) { + this->fuzzyPrefixLength = fuzzyPrefixLength; +} - void QueryParser::setEnablePositionIncrements(bool enable) - { - this->enablePositionIncrements = enable; - } +void QueryParser::setPhraseSlop(int32_t phraseSlop) { + this->phraseSlop = phraseSlop; +} - bool QueryParser::getEnablePositionIncrements() - { - return enablePositionIncrements; - } +int32_t QueryParser::getPhraseSlop() { + return phraseSlop; +} - void QueryParser::setDefaultOperator(Operator op) - { - this->_operator = op; - } +void QueryParser::setAllowLeadingWildcard(bool allowLeadingWildcard) { + this->allowLeadingWildcard = allowLeadingWildcard; +} - QueryParser::Operator QueryParser::getDefaultOperator() - { - return _operator; - } +bool QueryParser::getAllowLeadingWildcard() { + return allowLeadingWildcard; +} - void QueryParser::setLowercaseExpandedTerms(bool lowercaseExpandedTerms) - { - this->lowercaseExpandedTerms = lowercaseExpandedTerms; - } +void QueryParser::setEnablePositionIncrements(bool enable) { + this->enablePositionIncrements = enable; +} - bool QueryParser::getLowercaseExpandedTerms() - { - return lowercaseExpandedTerms; - } +bool QueryParser::getEnablePositionIncrements() { + return enablePositionIncrements; +} - void QueryParser::setMultiTermRewriteMethod(const RewriteMethodPtr& method) - { - multiTermRewriteMethod = method; - } +void QueryParser::setDefaultOperator(Operator op) { + this->_operator = op; +} - RewriteMethodPtr QueryParser::getMultiTermRewriteMethod() - { - return multiTermRewriteMethod; - } +QueryParser::Operator QueryParser::getDefaultOperator() { + return _operator; +} - void QueryParser::setLocale(std::locale locale) - { - this->locale = locale; - } +void QueryParser::setLowercaseExpandedTerms(bool lowercaseExpandedTerms) { + this->lowercaseExpandedTerms = lowercaseExpandedTerms; +} - std::locale QueryParser::getLocale() - { - return locale; - } +bool QueryParser::getLowercaseExpandedTerms() { + return lowercaseExpandedTerms; +} - void QueryParser::setDateResolution(DateTools::Resolution dateResolution) - { - this->dateResolution = dateResolution; - } +void QueryParser::setMultiTermRewriteMethod(const RewriteMethodPtr& method) { + multiTermRewriteMethod = method; +} - void QueryParser::setDateResolution(const String& fieldName, DateTools::Resolution dateResolution) - { - if (fieldName.empty()) - boost::throw_exception(IllegalArgumentException(L"Field cannot be empty.")); +RewriteMethodPtr QueryParser::getMultiTermRewriteMethod() { + return multiTermRewriteMethod; +} - if (!fieldToDateResolution) - { - // lazily initialize Map - fieldToDateResolution = MapStringResolution::newInstance(); - } +void QueryParser::setLocale(std::locale locale) { + this->locale = locale; +} - fieldToDateResolution.put(fieldName, dateResolution); - } +std::locale QueryParser::getLocale() { + return locale; +} - DateTools::Resolution QueryParser::getDateResolution(const String& fieldName) - { - if (fieldName.empty()) - boost::throw_exception(IllegalArgumentException(L"Field cannot be empty.")); +void QueryParser::setDateResolution(DateTools::Resolution dateResolution) { + this->dateResolution = dateResolution; +} - if (!fieldToDateResolution) - { - // no field specific date resolutions set; return default date resolution instead - return this->dateResolution; - } +void QueryParser::setDateResolution(const String& fieldName, DateTools::Resolution dateResolution) { + if (fieldName.empty()) { + boost::throw_exception(IllegalArgumentException(L"Field cannot be empty.")); + } - MapStringResolution::iterator resolution = fieldToDateResolution.find(fieldName); - if (resolution == fieldToDateResolution.end()) - { - // no date resolutions set for the given field; return default date resolution instead - return this->dateResolution; - } + if (!fieldToDateResolution) { + // lazily initialize Map + fieldToDateResolution = MapStringResolution::newInstance(); + } - return resolution->second; + fieldToDateResolution.put(fieldName, dateResolution); +} + +DateTools::Resolution QueryParser::getDateResolution(const String& fieldName) { + if (fieldName.empty()) { + boost::throw_exception(IllegalArgumentException(L"Field cannot be empty.")); } - void QueryParser::setRangeCollator(const CollatorPtr& rc) - { - rangeCollator = rc; + if (!fieldToDateResolution) { + // no field specific date resolutions set; return default date resolution instead + return this->dateResolution; } - CollatorPtr QueryParser::getRangeCollator() - { - return rangeCollator; + MapStringResolution::iterator resolution = fieldToDateResolution.find(fieldName); + if (resolution == fieldToDateResolution.end()) { + // no date resolutions set for the given field; return default date resolution instead + return this->dateResolution; } - void QueryParser::addClause(Collection clauses, int32_t conj, int32_t mods, const QueryPtr& q) - { - bool required = false; - bool prohibited = false; + return resolution->second; +} - // If this term is introduced by AND, make the preceding term required, unless it's already prohibited - if (!clauses.empty() && conj == CONJ_AND) - { - BooleanClausePtr c(clauses[clauses.size() - 1]); - if (!c->isProhibited()) - c->setOccur(BooleanClause::MUST); - } +void QueryParser::setRangeCollator(const CollatorPtr& rc) { + rangeCollator = rc; +} - if (!clauses.empty() && _operator == AND_OPERATOR && conj == CONJ_OR) - { - // If this term is introduced by OR, make the preceding term optional, unless it's prohibited (that - // means we leave -a OR b but +a OR b-->a OR b) notice if the input is a OR b, first term is parsed - // as required; without this modification a OR b would parsed as +a OR b - BooleanClausePtr c(clauses[clauses.size() - 1]); - if (!c->isProhibited()) - c->setOccur(BooleanClause::SHOULD); - } +CollatorPtr QueryParser::getRangeCollator() { + return rangeCollator; +} - // We might have been passed a null query; the term might have been filtered away by the analyzer. - if (!q) - return; +void QueryParser::addClause(Collection clauses, int32_t conj, int32_t mods, const QueryPtr& q) { + bool required = false; + bool prohibited = false; - if (_operator == OR_OPERATOR) - { - // We set REQUIRED if we're introduced by AND or +; PROHIBITED if introduced by NOT or -; make - // sure not to set both. - prohibited = (mods == MOD_NOT); - required = (mods == MOD_REQ); - if (conj == CONJ_AND && !prohibited) - required = true; + // If this term is introduced by AND, make the preceding term required, unless it's already prohibited + if (!clauses.empty() && conj == CONJ_AND) { + BooleanClausePtr c(clauses[clauses.size() - 1]); + if (!c->isProhibited()) { + c->setOccur(BooleanClause::MUST); } - else - { - // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED if not PROHIBITED and not - // introduced by OR - prohibited = (mods == MOD_NOT); - required = (!prohibited && conj != CONJ_OR); - } - if (required && !prohibited) - clauses.add(newBooleanClause(q, BooleanClause::MUST)); - else if (!required && !prohibited) - clauses.add(newBooleanClause(q, BooleanClause::SHOULD)); - else if (!required && prohibited) - clauses.add(newBooleanClause(q, BooleanClause::MUST_NOT)); - else - boost::throw_exception(RuntimeException(L"Clause cannot be both required and prohibited")); - } - - QueryPtr QueryParser::getFieldQuery(const String& field, const String& queryText) - { - TokenStreamPtr source; - try - { - source = analyzer->reusableTokenStream(field, newLucene(queryText)); - source->reset(); - } - catch (IOException&) - { - source = analyzer->tokenStream(field, newLucene(queryText)); + } + + if (!clauses.empty() && _operator == AND_OPERATOR && conj == CONJ_OR) { + // If this term is introduced by OR, make the preceding term optional, unless it's prohibited (that + // means we leave -a OR b but +a OR b-->a OR b) notice if the input is a OR b, first term is parsed + // as required; without this modification a OR b would parsed as +a OR b + BooleanClausePtr c(clauses[clauses.size() - 1]); + if (!c->isProhibited()) { + c->setOccur(BooleanClause::SHOULD); } + } - CachingTokenFilterPtr buffer(newLucene(source)); - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncrAtt; - int32_t numTokens = 0; + // We might have been passed a null query; the term might have been filtered away by the analyzer. + if (!q) { + return; + } - bool success = false; - try - { - buffer->reset(); - success = true; + if (_operator == OR_OPERATOR) { + // We set REQUIRED if we're introduced by AND or +; PROHIBITED if introduced by NOT or -; make + // sure not to set both. + prohibited = (mods == MOD_NOT); + required = (mods == MOD_REQ); + if (conj == CONJ_AND && !prohibited) { + required = true; } - catch (IOException&) - { - // success == false if we hit an exception + } else { + // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED if not PROHIBITED and not + // introduced by OR + prohibited = (mods == MOD_NOT); + required = (!prohibited && conj != CONJ_OR); + } + if (required && !prohibited) { + clauses.add(newBooleanClause(q, BooleanClause::MUST)); + } else if (!required && !prohibited) { + clauses.add(newBooleanClause(q, BooleanClause::SHOULD)); + } else if (!required && prohibited) { + clauses.add(newBooleanClause(q, BooleanClause::MUST_NOT)); + } else { + boost::throw_exception(RuntimeException(L"Clause cannot be both required and prohibited")); + } +} + +QueryPtr QueryParser::getFieldQuery(const String& field, const String& queryText) { + TokenStreamPtr source; + try { + source = analyzer->reusableTokenStream(field, newLucene(queryText)); + source->reset(); + } catch (IOException&) { + source = analyzer->tokenStream(field, newLucene(queryText)); + } + + CachingTokenFilterPtr buffer(newLucene(source)); + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncrAtt; + int32_t numTokens = 0; + + bool success = false; + try { + buffer->reset(); + success = true; + } catch (IOException&) { + // success == false if we hit an exception + } + if (success) { + if (buffer->hasAttribute()) { + termAtt = buffer->getAttribute(); } - if (success) - { - if (buffer->hasAttribute()) - termAtt = buffer->getAttribute(); - if (buffer->hasAttribute()) - posIncrAtt = buffer->getAttribute(); + if (buffer->hasAttribute()) { + posIncrAtt = buffer->getAttribute(); } + } - int32_t positionCount = 0; - bool severalTokensAtSamePosition = false; - - bool hasMoreTokens = false; - if (termAtt) - { - try - { - hasMoreTokens = buffer->incrementToken(); - while (hasMoreTokens) - { - ++numTokens; - int32_t positionIncrement = posIncrAtt ? posIncrAtt->getPositionIncrement() : 1; - if (positionIncrement != 0) - positionCount += positionIncrement; - else - severalTokensAtSamePosition = true; - hasMoreTokens = buffer->incrementToken(); + int32_t positionCount = 0; + bool severalTokensAtSamePosition = false; + + bool hasMoreTokens = false; + if (termAtt) { + try { + hasMoreTokens = buffer->incrementToken(); + while (hasMoreTokens) { + ++numTokens; + int32_t positionIncrement = posIncrAtt ? posIncrAtt->getPositionIncrement() : 1; + if (positionIncrement != 0) { + positionCount += positionIncrement; + } else { + severalTokensAtSamePosition = true; } + hasMoreTokens = buffer->incrementToken(); } - catch (IOException&) - { - // ignore - } - } - try - { - // rewind the buffer stream - buffer->reset(); - - // close original stream - all tokens buffered - source->close(); - } - catch (IOException&) - { + } catch (IOException&) { // ignore } + } + try { + // rewind the buffer stream + buffer->reset(); - if (numTokens == 0) - return QueryPtr(); - else if (numTokens == 1) - { - String term; - try - { - bool hasNext = buffer->incrementToken(); - BOOST_ASSERT(hasNext); - term = termAtt->term(); - } - catch (IOException&) - { - // safe to ignore, because we know the number of tokens - } - return newTermQuery(newLucene(field, term)); - } - else - { - if (severalTokensAtSamePosition) - { - if (positionCount == 1) - { - // no phrase query - BooleanQueryPtr q(newBooleanQuery(true)); - for (int32_t i = 0; i < numTokens; ++i) - { - String term; - try - { - bool hasNext = buffer->incrementToken(); - BOOST_ASSERT(hasNext); - term = termAtt->term(); - } - catch (IOException&) - { - // safe to ignore, because we know the number of tokens - } + // close original stream - all tokens buffered + source->close(); + } catch (IOException&) { + // ignore + } - QueryPtr currentQuery(newTermQuery(newLucene(field, term))); - q->add(currentQuery, BooleanClause::SHOULD); + if (numTokens == 0) { + return QueryPtr(); + } else if (numTokens == 1) { + String term; + try { + bool hasNext = buffer->incrementToken(); + BOOST_ASSERT(hasNext); + term = termAtt->term(); + } catch (IOException&) { + // safe to ignore, because we know the number of tokens + } + return newTermQuery(newLucene(field, term)); + } else { + if (severalTokensAtSamePosition) { + if (positionCount == 1) { + // no phrase query + BooleanQueryPtr q(newBooleanQuery(true)); + for (int32_t i = 0; i < numTokens; ++i) { + String term; + try { + bool hasNext = buffer->incrementToken(); + BOOST_ASSERT(hasNext); + term = termAtt->term(); + } catch (IOException&) { + // safe to ignore, because we know the number of tokens } - return q; - } - else - { - // phrase query - MultiPhraseQueryPtr mpq(newMultiPhraseQuery()); - mpq->setSlop(phraseSlop); - Collection multiTerms(Collection::newInstance()); - int32_t position = -1; - for (int32_t i = 0; i < numTokens; ++i) - { - String term; - int32_t positionIncrement = 1; - try - { - bool hasNext = buffer->incrementToken(); - BOOST_ASSERT(hasNext); - term = termAtt->term(); - if (posIncrAtt) - positionIncrement = posIncrAtt->getPositionIncrement(); - } - catch (IOException&) - { - // safe to ignore, because we know the number of tokens - } - if (positionIncrement > 0 && !multiTerms.empty()) - { - if (enablePositionIncrements) - mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end()), position); - else - mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end())); - multiTerms.clear(); - } - position += positionIncrement; - multiTerms.add(newLucene(field, term)); - } - if (enablePositionIncrements) - mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end()), position); - else - mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end())); - return mpq; + QueryPtr currentQuery(newTermQuery(newLucene(field, term))); + q->add(currentQuery, BooleanClause::SHOULD); } - } - else - { - PhraseQueryPtr pq(newPhraseQuery()); - pq->setSlop(phraseSlop); + return q; + } else { + // phrase query + MultiPhraseQueryPtr mpq(newMultiPhraseQuery()); + mpq->setSlop(phraseSlop); + Collection multiTerms(Collection::newInstance()); int32_t position = -1; - - for (int32_t i = 0; i < numTokens; ++i) - { + for (int32_t i = 0; i < numTokens; ++i) { String term; int32_t positionIncrement = 1; - - try - { + try { bool hasNext = buffer->incrementToken(); BOOST_ASSERT(hasNext); term = termAtt->term(); - if (posIncrAtt) + if (posIncrAtt) { positionIncrement = posIncrAtt->getPositionIncrement(); - } - catch (IOException&) - { + } + } catch (IOException&) { // safe to ignore, because we know the number of tokens } - if (enablePositionIncrements) - { - position += positionIncrement; - pq->add(newLucene(field, term), position); + if (positionIncrement > 0 && !multiTerms.empty()) { + if (enablePositionIncrements) { + mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end()), position); + } else { + mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end())); + } + multiTerms.clear(); } - else - pq->add(newLucene(field, term)); + position += positionIncrement; + multiTerms.add(newLucene(field, term)); } - return pq; + if (enablePositionIncrements) { + mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end()), position); + } else { + mpq->add(Collection::newInstance(multiTerms.begin(), multiTerms.end())); + } + return mpq; } + } else { + PhraseQueryPtr pq(newPhraseQuery()); + pq->setSlop(phraseSlop); + int32_t position = -1; + + for (int32_t i = 0; i < numTokens; ++i) { + String term; + int32_t positionIncrement = 1; + + try { + bool hasNext = buffer->incrementToken(); + BOOST_ASSERT(hasNext); + term = termAtt->term(); + if (posIncrAtt) { + positionIncrement = posIncrAtt->getPositionIncrement(); + } + } catch (IOException&) { + // safe to ignore, because we know the number of tokens + } + + if (enablePositionIncrements) { + position += positionIncrement; + pq->add(newLucene(field, term), position); + } else { + pq->add(newLucene(field, term)); + } + } + return pq; } } +} - QueryPtr QueryParser::getFieldQuery(const String& field, const String& queryText, int32_t slop) - { - QueryPtr query(getFieldQuery(field, queryText)); - if (MiscUtils::typeOf(query)) - boost::dynamic_pointer_cast(query)->setSlop(slop); - if (MiscUtils::typeOf(query)) - boost::dynamic_pointer_cast(query)->setSlop(slop); - return query; +QueryPtr QueryParser::getFieldQuery(const String& field, const String& queryText, int32_t slop) { + QueryPtr query(getFieldQuery(field, queryText)); + if (MiscUtils::typeOf(query)) { + boost::dynamic_pointer_cast(query)->setSlop(slop); + } + if (MiscUtils::typeOf(query)) { + boost::dynamic_pointer_cast(query)->setSlop(slop); } + return query; +} - QueryPtr QueryParser::getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) - { - String date1(part1); - String date2(part2); - if (lowercaseExpandedTerms) - { - StringUtils::toLower(date1); - StringUtils::toLower(date2); +QueryPtr QueryParser::getRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) { + String date1(part1); + String date2(part2); + if (lowercaseExpandedTerms) { + StringUtils::toLower(date1); + StringUtils::toLower(date2); + } + try { + boost::posix_time::ptime d1(DateTools::parseDate(date1, locale)); + boost::posix_time::ptime d2; + + // The user can only specify the date, not the time, so make sure the time is set to + // the latest possible time of that date to really include all documents + if (inclusive) { + d2 = boost::posix_time::ptime(DateTools::parseDate(date2, locale) + + boost::posix_time::hours(23) + + boost::posix_time::minutes(59) + + boost::posix_time::seconds(59) + + boost::posix_time::millisec(999)); + } else { + d2 = boost::posix_time::ptime(DateTools::parseDate(date2, locale)); } - try - { - boost::posix_time::ptime d1(DateTools::parseDate(date1, locale)); - boost::posix_time::ptime d2; - - // The user can only specify the date, not the time, so make sure the time is set to - // the latest possible time of that date to really include all documents - if (inclusive) - { - d2 = boost::posix_time::ptime(DateTools::parseDate(date2, locale) + - boost::posix_time::hours(23) + - boost::posix_time::minutes(59) + - boost::posix_time::seconds(59) + - boost::posix_time::millisec(999)); - } - else - d2 = boost::posix_time::ptime(DateTools::parseDate(date2, locale)); - DateTools::Resolution resolution = getDateResolution(field); - if (resolution == DateTools::RESOLUTION_NULL) - { - // no default or field specific date resolution has been set, use deprecated - // DateField to maintain compatibility with pre-1.9 Lucene versions. - date1 = DateField::dateToString(d1); - date2 = DateField::dateToString(d2); - } - else - { - date1 = DateTools::dateToString(d1, resolution); - date2 = DateTools::dateToString(d2, resolution); - } + DateTools::Resolution resolution = getDateResolution(field); + if (resolution == DateTools::RESOLUTION_NULL) { + // no default or field specific date resolution has been set, use deprecated + // DateField to maintain compatibility with pre-1.9 Lucene versions. + date1 = DateField::dateToString(d1); + date2 = DateField::dateToString(d2); + } else { + date1 = DateTools::dateToString(d1, resolution); + date2 = DateTools::dateToString(d2, resolution); } - catch (...) - { - } - return newRangeQuery(field, date1, date2, inclusive); + } catch (...) { } + return newRangeQuery(field, date1, date2, inclusive); +} - BooleanQueryPtr QueryParser::newBooleanQuery(bool disableCoord) - { - return newLucene(disableCoord); - } +BooleanQueryPtr QueryParser::newBooleanQuery(bool disableCoord) { + return newLucene(disableCoord); +} - BooleanClausePtr QueryParser::newBooleanClause(const QueryPtr& q, BooleanClause::Occur occur) - { - return newLucene(q, occur); - } +BooleanClausePtr QueryParser::newBooleanClause(const QueryPtr& q, BooleanClause::Occur occur) { + return newLucene(q, occur); +} - QueryPtr QueryParser::newTermQuery(const TermPtr& term) - { - return newLucene(term); - } +QueryPtr QueryParser::newTermQuery(const TermPtr& term) { + return newLucene(term); +} - PhraseQueryPtr QueryParser::newPhraseQuery() - { - return newLucene(); - } +PhraseQueryPtr QueryParser::newPhraseQuery() { + return newLucene(); +} - MultiPhraseQueryPtr QueryParser::newMultiPhraseQuery() - { - return newLucene(); - } +MultiPhraseQueryPtr QueryParser::newMultiPhraseQuery() { + return newLucene(); +} - QueryPtr QueryParser::newPrefixQuery(const TermPtr& prefix) - { - PrefixQueryPtr query(newLucene(prefix)); - query->setRewriteMethod(multiTermRewriteMethod); - return query; - } +QueryPtr QueryParser::newPrefixQuery(const TermPtr& prefix) { + PrefixQueryPtr query(newLucene(prefix)); + query->setRewriteMethod(multiTermRewriteMethod); + return query; +} - QueryPtr QueryParser::newFuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) - { - // FuzzyQuery doesn't yet allow constant score rewrite - return newLucene(term, minimumSimilarity, prefixLength); - } +QueryPtr QueryParser::newFuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) { + // FuzzyQuery doesn't yet allow constant score rewrite + return newLucene(term, minimumSimilarity, prefixLength); +} - QueryPtr QueryParser::newRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) - { - TermRangeQueryPtr query(newLucene(field, part1, part2, inclusive, inclusive, rangeCollator)); - query->setRewriteMethod(multiTermRewriteMethod); - return query; - } +QueryPtr QueryParser::newRangeQuery(const String& field, const String& part1, const String& part2, bool inclusive) { + TermRangeQueryPtr query(newLucene(field, part1, part2, inclusive, inclusive, rangeCollator)); + query->setRewriteMethod(multiTermRewriteMethod); + return query; +} - QueryPtr QueryParser::newMatchAllDocsQuery() - { - return newLucene(); - } +QueryPtr QueryParser::newMatchAllDocsQuery() { + return newLucene(); +} - QueryPtr QueryParser::newWildcardQuery(const TermPtr& term) - { - WildcardQueryPtr query(newLucene(term)); - query->setRewriteMethod(multiTermRewriteMethod); - return query; - } +QueryPtr QueryParser::newWildcardQuery(const TermPtr& term) { + WildcardQueryPtr query(newLucene(term)); + query->setRewriteMethod(multiTermRewriteMethod); + return query; +} - QueryPtr QueryParser::getBooleanQuery(Collection clauses) - { - return getBooleanQuery(clauses, false); - } +QueryPtr QueryParser::getBooleanQuery(Collection clauses) { + return getBooleanQuery(clauses, false); +} - QueryPtr QueryParser::getBooleanQuery(Collection clauses, bool disableCoord) - { - if (clauses.empty()) - return QueryPtr(); // all clause words were filtered away by the analyzer. - BooleanQueryPtr query(newBooleanQuery(disableCoord)); - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - query->add(*clause); - return query; +QueryPtr QueryParser::getBooleanQuery(Collection clauses, bool disableCoord) { + if (clauses.empty()) { + return QueryPtr(); // all clause words were filtered away by the analyzer. + } + BooleanQueryPtr query(newBooleanQuery(disableCoord)); + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + query->add(*clause); } + return query; +} - QueryPtr QueryParser::getWildcardQuery(const String& field, const String& termStr) - { - if (field == L"*" && termStr == L"*") - return newMatchAllDocsQuery(); - if (!allowLeadingWildcard && (boost::starts_with(termStr, L"*") || boost::starts_with(termStr, L"?"))) - boost::throw_exception(QueryParserError(L"'*' or '?' not allowed as first character in WildcardQuery")); - String queryTerm(termStr); - if (lowercaseExpandedTerms) - StringUtils::toLower(queryTerm); - TermPtr term(newLucene(field, queryTerm)); - return newWildcardQuery(term); +QueryPtr QueryParser::getWildcardQuery(const String& field, const String& termStr) { + if (field == L"*" && termStr == L"*") { + return newMatchAllDocsQuery(); + } + if (!allowLeadingWildcard && (boost::starts_with(termStr, L"*") || boost::starts_with(termStr, L"?"))) { + boost::throw_exception(QueryParserError(L"'*' or '?' not allowed as first character in WildcardQuery")); + } + String queryTerm(termStr); + if (lowercaseExpandedTerms) { + StringUtils::toLower(queryTerm); } + TermPtr term(newLucene(field, queryTerm)); + return newWildcardQuery(term); +} - QueryPtr QueryParser::getPrefixQuery(const String& field, const String& termStr) - { - if (!allowLeadingWildcard && boost::starts_with(termStr, L"*")) - boost::throw_exception(QueryParserError(L"'*' not allowed as first character in PrefixQuery")); - String queryTerm(termStr); - if (lowercaseExpandedTerms) - StringUtils::toLower(queryTerm); - TermPtr term(newLucene(field, queryTerm)); - return newPrefixQuery(term); +QueryPtr QueryParser::getPrefixQuery(const String& field, const String& termStr) { + if (!allowLeadingWildcard && boost::starts_with(termStr, L"*")) { + boost::throw_exception(QueryParserError(L"'*' not allowed as first character in PrefixQuery")); + } + String queryTerm(termStr); + if (lowercaseExpandedTerms) { + StringUtils::toLower(queryTerm); } + TermPtr term(newLucene(field, queryTerm)); + return newPrefixQuery(term); +} - QueryPtr QueryParser::getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) - { - String queryTerm(termStr); - if (lowercaseExpandedTerms) - StringUtils::toLower(queryTerm); - TermPtr term(newLucene(field, queryTerm)); - return newFuzzyQuery(term, minSimilarity, fuzzyPrefixLength); +QueryPtr QueryParser::getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) { + String queryTerm(termStr); + if (lowercaseExpandedTerms) { + StringUtils::toLower(queryTerm); } + TermPtr term(newLucene(field, queryTerm)); + return newFuzzyQuery(term, minSimilarity, fuzzyPrefixLength); +} - String QueryParser::discardEscapeChar(const String& input) - { - // Create char array to hold unescaped char sequence - CharArray output(CharArray::newInstance(input.length())); +String QueryParser::discardEscapeChar(const String& input) { + // Create char array to hold unescaped char sequence + CharArray output(CharArray::newInstance(input.length())); - // The length of the output can be less than the input due to discarded escape chars. - // This variable holds the actual length of the output - int32_t length = 0; + // The length of the output can be less than the input due to discarded escape chars. + // This variable holds the actual length of the output + int32_t length = 0; - // We remember whether the last processed character was an escape character - bool lastCharWasEscapeChar = false; + // We remember whether the last processed character was an escape character + bool lastCharWasEscapeChar = false; - // The multiplier the current unicode digit must be multiplied with. eg. the first digit must - // be multiplied with 16^3, the second with 16^2 - int32_t codePointMultiplier = 0; + // The multiplier the current unicode digit must be multiplied with. eg. the first digit must + // be multiplied with 16^3, the second with 16^2 + int32_t codePointMultiplier = 0; - // Used to calculate the codepoint of the escaped unicode character - int32_t codePoint = 0; + // Used to calculate the codepoint of the escaped unicode character + int32_t codePoint = 0; - for (int32_t i = 0; i < (int32_t)input.length(); ++i) - { - wchar_t curChar = input[i]; - if (codePointMultiplier > 0) - { - codePoint += hexToInt(curChar) * codePointMultiplier; - codePointMultiplier = MiscUtils::unsignedShift(codePointMultiplier, 4); - if (codePointMultiplier == 0) - { - output[length++] = (wchar_t)codePoint; - codePoint = 0; - } + for (int32_t i = 0; i < (int32_t)input.length(); ++i) { + wchar_t curChar = input[i]; + if (codePointMultiplier > 0) { + codePoint += hexToInt(curChar) * codePointMultiplier; + codePointMultiplier = MiscUtils::unsignedShift(codePointMultiplier, 4); + if (codePointMultiplier == 0) { + output[length++] = (wchar_t)codePoint; + codePoint = 0; } - else if (lastCharWasEscapeChar) - { - if (curChar == L'u') - { - // found an escaped unicode character - codePointMultiplier = 16 * 16 * 16; - } - else - { - // this character was escaped - output[length++] = curChar; - } - lastCharWasEscapeChar = false; + } else if (lastCharWasEscapeChar) { + if (curChar == L'u') { + // found an escaped unicode character + codePointMultiplier = 16 * 16 * 16; + } else { + // this character was escaped + output[length++] = curChar; } - else - { - if (curChar == L'\\') - lastCharWasEscapeChar = true; - else - output[length++] = curChar; + lastCharWasEscapeChar = false; + } else { + if (curChar == L'\\') { + lastCharWasEscapeChar = true; + } else { + output[length++] = curChar; } } + } - if (codePointMultiplier > 0) - boost::throw_exception(QueryParserError(L"Truncated unicode escape sequence.")); - if (lastCharWasEscapeChar) - boost::throw_exception(QueryParserError(L"Term can not end with escape character.")); - return String(output.get(), length); - } - - int32_t QueryParser::hexToInt(wchar_t c) - { - if (L'0' <= c && c <= L'9') - return c - L'0'; - else if (L'a' <= c && c <= L'f') - return c - L'a' + 10; - else if (L'A' <= c && c <= L'F') - return c - L'A' + 10; - else - { - boost::throw_exception(QueryParserError(L"None-hex character in unicode escape sequence: " + StringUtils::toString(c))); - return 0; - } + if (codePointMultiplier > 0) { + boost::throw_exception(QueryParserError(L"Truncated unicode escape sequence.")); + } + if (lastCharWasEscapeChar) { + boost::throw_exception(QueryParserError(L"Term can not end with escape character.")); } + return String(output.get(), length); +} - String QueryParser::escape(const String& s) - { - StringStream buffer; - for (int32_t i = 0; i < (int32_t)s.length(); ++i) - { - wchar_t c = s[i]; - // These characters are part of the query syntax and must be escaped - if (c == L'\\' || c == L'+' || c == L'-' || c == L'!' || c == L'(' || c == L')' || c == L':' || +int32_t QueryParser::hexToInt(wchar_t c) { + if (L'0' <= c && c <= L'9') { + return c - L'0'; + } else if (L'a' <= c && c <= L'f') { + return c - L'a' + 10; + } else if (L'A' <= c && c <= L'F') { + return c - L'A' + 10; + } else { + boost::throw_exception(QueryParserError(L"None-hex character in unicode escape sequence: " + StringUtils::toString(c))); + return 0; + } +} + +String QueryParser::escape(const String& s) { + StringStream buffer; + for (int32_t i = 0; i < (int32_t)s.length(); ++i) { + wchar_t c = s[i]; + // These characters are part of the query syntax and must be escaped + if (c == L'\\' || c == L'+' || c == L'-' || c == L'!' || c == L'(' || c == L')' || c == L':' || c == L'^' || c == L'[' || c == L']' || c == L'\"' || c == L'{' || c == L'}' || c == L'~' || - c == L'*' || c == L'?' || c == L'|' || c == L'&') - buffer << L"\\"; - buffer << c; + c == L'*' || c == L'?' || c == L'|' || c == L'&') { + buffer << L"\\"; } - return buffer.str(); + buffer << c; } + return buffer.str(); +} - int QueryParser::main(Collection args) - { - if (args.empty()) - { - std::wcout << L"Usage: QueryParser "; - return 1; +int QueryParser::main(Collection args) { + if (args.empty()) { + std::wcout << L"Usage: QueryParser "; + return 1; + } + QueryParserPtr qp(newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene())); + QueryPtr q(qp->parse(args[0])); + std::wcout << q->toString(L"field"); + return 0; +} + +int32_t QueryParser::Conjunction() { + int32_t ret = CONJ_NONE; + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case AND: + case OR: + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case AND: + jj_consume_token(AND); + ret = CONJ_AND; + break; + case OR: + jj_consume_token(OR); + ret = CONJ_OR; + break; + default: + jj_la1[0] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); } - QueryParserPtr qp(newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene())); - QueryPtr q(qp->parse(args[0])); - std::wcout << q->toString(L"field"); - return 0; + break; + default: + jj_la1[1] = jj_gen; } + return ret; +} - int32_t QueryParser::Conjunction() - { - int32_t ret = CONJ_NONE; - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case AND: - case OR: - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case AND: - jj_consume_token(AND); - ret = CONJ_AND; - break; - case OR: - jj_consume_token(OR); - ret = CONJ_OR; - break; - default: - jj_la1[0] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); - } - break; - default: - jj_la1[1] = jj_gen; +int32_t QueryParser::Modifiers() { + int32_t ret = MOD_NONE; + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case NOT: + case PLUS: + case MINUS: + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case PLUS: + jj_consume_token(PLUS); + ret = MOD_REQ; + break; + case MINUS: + jj_consume_token(MINUS); + ret = MOD_NOT; + break; + case NOT: + jj_consume_token(NOT); + ret = MOD_NOT; + break; + default: + jj_la1[2] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); } - return ret; + break; + default: + jj_la1[3] = jj_gen; } + return ret; +} - int32_t QueryParser::Modifiers() - { - int32_t ret = MOD_NONE; - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case NOT: - case PLUS: - case MINUS: - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case PLUS: - jj_consume_token(PLUS); - ret = MOD_REQ; - break; - case MINUS: - jj_consume_token(MINUS); - ret = MOD_NOT; - break; - case NOT: - jj_consume_token(NOT); - ret = MOD_NOT; - break; - default: - jj_la1[2] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); - } - break; - default: - jj_la1[3] = jj_gen; +QueryPtr QueryParser::TopLevelQuery(const String& field) { + QueryPtr q(ParseQuery(field)); + jj_consume_token(0); + return q; +} + +QueryPtr QueryParser::ParseQuery(const String& field) { + Collection clauses(Collection::newInstance()); + QueryPtr firstQuery; + int32_t mods = Modifiers(); + QueryPtr q(ParseClause(field)); + addClause(clauses, CONJ_NONE, mods, q); + if (mods == MOD_NONE) { + firstQuery = q; + } + for (bool more = true; more; ) { + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case AND: + case OR: + case NOT: + case PLUS: + case MINUS: + case LPAREN: + case STAR: + case QUOTED: + case TERM: + case PREFIXTERM: + case WILDTERM: + case RANGEIN_START: + case RANGEEX_START: + case NUMBER: + break; + default: + jj_la1[4] = jj_gen; + more = false; + continue; } - return ret; - } - - QueryPtr QueryParser::TopLevelQuery(const String& field) - { - QueryPtr q(ParseQuery(field)); - jj_consume_token(0); - return q; - } - - QueryPtr QueryParser::ParseQuery(const String& field) - { - Collection clauses(Collection::newInstance()); - QueryPtr firstQuery; - int32_t mods = Modifiers(); - QueryPtr q(ParseClause(field)); - addClause(clauses, CONJ_NONE, mods, q); - if (mods == MOD_NONE) - firstQuery = q; - for (bool more = true; more; ) - { - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case AND: - case OR: - case NOT: - case PLUS: - case MINUS: - case LPAREN: - case STAR: - case QUOTED: - case TERM: - case PREFIXTERM: - case WILDTERM: - case RANGEIN_START: - case RANGEEX_START: - case NUMBER: - break; - default: - jj_la1[4] = jj_gen; - more = false; - continue; - } - int32_t conj = Conjunction(); - mods = Modifiers(); - q = ParseClause(field); - addClause(clauses, conj, mods, q); + int32_t conj = Conjunction(); + mods = Modifiers(); + q = ParseClause(field); + addClause(clauses, conj, mods, q); + } + if (clauses.size() == 1 && firstQuery) { + return firstQuery; + } else { + return getBooleanQuery(clauses); + } +} + +QueryPtr QueryParser::ParseClause(const String& field) { + QueryPtr q; + QueryParserTokenPtr fieldToken; + QueryParserTokenPtr boost; + String fieldClause(field); + if (jj_2_1(2)) { + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case TERM: + fieldToken = jj_consume_token(TERM); + jj_consume_token(COLON); + fieldClause = discardEscapeChar(fieldToken->image); + break; + case STAR: + jj_consume_token(STAR); + jj_consume_token(COLON); + fieldClause = L"*"; + break; + default: + jj_la1[5] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); } - if (clauses.size() == 1 && firstQuery) - return firstQuery; - else - return getBooleanQuery(clauses); - } - - QueryPtr QueryParser::ParseClause(const String& field) - { - QueryPtr q; - QueryParserTokenPtr fieldToken; - QueryParserTokenPtr boost; - String fieldClause(field); - if (jj_2_1(2)) - { - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case TERM: - fieldToken = jj_consume_token(TERM); - jj_consume_token(COLON); - fieldClause = discardEscapeChar(fieldToken->image); - break; - case STAR: - jj_consume_token(STAR); - jj_consume_token(COLON); - fieldClause = L"*"; - break; - default: - jj_la1[5] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case STAR: + case QUOTED: + case TERM: + case PREFIXTERM: + case WILDTERM: + case RANGEIN_START: + case RANGEEX_START: + case NUMBER: + q = ParseTerm(fieldClause); + break; + case LPAREN: + jj_consume_token(LPAREN); + q = ParseQuery(fieldClause); + jj_consume_token(RPAREN); + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case CARAT: + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + break; + default: + jj_la1[6] = jj_gen; + } + break; + default: + jj_la1[7] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); + } + if (boost) { + double f = 1.0; + try { + if (q) { + f = StringUtils::toDouble(boost->image); + q->setBoost(f); } + } catch (...) { } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case STAR: - case QUOTED: - case TERM: - case PREFIXTERM: - case WILDTERM: - case RANGEIN_START: - case RANGEEX_START: - case NUMBER: - q = ParseTerm(fieldClause); - break; - case LPAREN: - jj_consume_token(LPAREN); - q = ParseQuery(fieldClause); - jj_consume_token(RPAREN); - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case CARAT: - jj_consume_token(CARAT); - boost = jj_consume_token(NUMBER); - break; - default: - jj_la1[6] = jj_gen; - } + } + return q; +} + +QueryPtr QueryParser::ParseTerm(const String& field) { + QueryParserTokenPtr term; + QueryParserTokenPtr boost; + QueryParserTokenPtr fuzzySlop; + QueryParserTokenPtr goop1; + QueryParserTokenPtr goop2; + bool prefix = false; + bool wildcard = false; + bool fuzzy = false; + QueryPtr q; + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case STAR: + case TERM: + case PREFIXTERM: + case WILDTERM: + case NUMBER: + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case TERM: + term = jj_consume_token(TERM); + break; + case STAR: + term = jj_consume_token(STAR); + wildcard = true; + break; + case PREFIXTERM: + term = jj_consume_token(PREFIXTERM); + prefix = true; + break; + case WILDTERM: + term = jj_consume_token(WILDTERM); + wildcard = true; + break; + case NUMBER: + term = jj_consume_token(NUMBER); + break; + default: + jj_la1[8] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case FUZZY_SLOP: + fuzzySlop = jj_consume_token(FUZZY_SLOP); + fuzzy = true; + break; + default: + jj_la1[9] = jj_gen; + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case CARAT: + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case FUZZY_SLOP: + fuzzySlop = jj_consume_token(FUZZY_SLOP); + fuzzy = true; break; default: - jj_la1[7] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); - } - if (boost) - { - double f = 1.0; - try - { - if (q) - { - f = StringUtils::toDouble(boost->image); - q->setBoost(f); - } - } - catch (...) - { + jj_la1[10] = jj_gen; } + break; + default: + jj_la1[11] = jj_gen; } - return q; - } - - QueryPtr QueryParser::ParseTerm(const String& field) - { - QueryParserTokenPtr term; - QueryParserTokenPtr boost; - QueryParserTokenPtr fuzzySlop; - QueryParserTokenPtr goop1; - QueryParserTokenPtr goop2; - bool prefix = false; - bool wildcard = false; - bool fuzzy = false; - QueryPtr q; - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { - case STAR: - case TERM: - case PREFIXTERM: - case WILDTERM: - case NUMBER: - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case TERM: - term = jj_consume_token(TERM); - break; - case STAR: - term = jj_consume_token(STAR); - wildcard = true; - break; - case PREFIXTERM: - term = jj_consume_token(PREFIXTERM); - prefix = true; - break; - case WILDTERM: - term = jj_consume_token(WILDTERM); - wildcard = true; - break; - case NUMBER: - term = jj_consume_token(NUMBER); - break; - default: - jj_la1[8] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); - } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case FUZZY_SLOP: - fuzzySlop = jj_consume_token(FUZZY_SLOP); - fuzzy = true; - break; - default: - jj_la1[9] = jj_gen; - } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case CARAT: - jj_consume_token(CARAT); - boost = jj_consume_token(NUMBER); - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case FUZZY_SLOP: - fuzzySlop = jj_consume_token(FUZZY_SLOP); - fuzzy = true; - break; - default: - jj_la1[10] = jj_gen; - } - break; - default: - jj_la1[11] = jj_gen; - } - { - String termImage(discardEscapeChar(term->image)); - if (wildcard) - q = getWildcardQuery(field, termImage); - else if (prefix) - q = getPrefixQuery(field, discardEscapeChar(term->image.substr(0, term->image.length() - 1))); - else if (fuzzy) - { - double fms = fuzzyMinSim; - try - { - fms = StringUtils::toDouble(fuzzySlop->image.substr(1)); - } - catch (...) - { - } - if (fms < 0.0 || fms > 1.0) - boost::throw_exception(QueryParserError(L"Minimum similarity for a FuzzyQuery has to be between 0.0 and 1.0")); - q = getFuzzyQuery(field, termImage, fms); - } - else - q = getFieldQuery(field, termImage); - } - break; - case RANGEIN_START: - jj_consume_token(RANGEIN_START); - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case RANGEIN_GOOP: - goop1 = jj_consume_token(RANGEIN_GOOP); - break; - case RANGEIN_QUOTED: - goop1 = jj_consume_token(RANGEIN_QUOTED); - break; - default: - jj_la1[12] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); - } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case RANGEIN_TO: - jj_consume_token(RANGEIN_TO); - break; - default: - jj_la1[13] = jj_gen; - } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case RANGEIN_GOOP: - goop2 = jj_consume_token(RANGEIN_GOOP); - break; - case RANGEIN_QUOTED: - goop2 = jj_consume_token(RANGEIN_QUOTED); - break; - default: - jj_la1[14] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); - } - jj_consume_token(RANGEIN_END); - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case CARAT: - jj_consume_token(CARAT); - boost = jj_consume_token(NUMBER); - break; - default: - jj_la1[15] = jj_gen; - } - if (goop1->kind == RANGEIN_QUOTED) - goop1->image = goop1->image.substr(1, std::max((int32_t)0, (int32_t)goop1->image.length() - 2)); - if (goop2->kind == RANGEIN_QUOTED) - goop2->image = goop2->image.substr(1, std::max((int32_t)0, (int32_t)goop2->image.length() - 2)); - q = getRangeQuery(field, discardEscapeChar(goop1->image), discardEscapeChar(goop2->image), true); - break; - case RANGEEX_START: - jj_consume_token(RANGEEX_START); - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case RANGEEX_GOOP: - goop1 = jj_consume_token(RANGEEX_GOOP); - break; - case RANGEEX_QUOTED: - goop1 = jj_consume_token(RANGEEX_QUOTED); - break; - default: - jj_la1[16] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); + String termImage(discardEscapeChar(term->image)); + if (wildcard) { + q = getWildcardQuery(field, termImage); + } else if (prefix) { + q = getPrefixQuery(field, discardEscapeChar(term->image.substr(0, term->image.length() - 1))); + } else if (fuzzy) { + double fms = fuzzyMinSim; + try { + fms = StringUtils::toDouble(fuzzySlop->image.substr(1)); + } catch (...) { } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case RANGEEX_TO: - jj_consume_token(RANGEEX_TO); - break; - default: - jj_la1[17] = jj_gen; - } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case RANGEEX_GOOP: - goop2 = jj_consume_token(RANGEEX_GOOP); - break; - case RANGEEX_QUOTED: - goop2 = jj_consume_token(RANGEEX_QUOTED); - break; - default: - jj_la1[18] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); + if (fms < 0.0 || fms > 1.0) { + boost::throw_exception(QueryParserError(L"Minimum similarity for a FuzzyQuery has to be between 0.0 and 1.0")); } - jj_consume_token(RANGEEX_END); - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case CARAT: - jj_consume_token(CARAT); - boost = jj_consume_token(NUMBER); - break; - default: - jj_la1[19] = jj_gen; - } - if (goop1->kind == RANGEEX_QUOTED) - goop1->image = goop1->image.substr(1, std::max((int32_t)0, (int32_t)goop1->image.length() - 2)); - if (goop2->kind == RANGEEX_QUOTED) - goop2->image = goop2->image.substr(1, std::max((int32_t)0, (int32_t)goop2->image.length() - 2)); - q = getRangeQuery(field, discardEscapeChar(goop1->image), discardEscapeChar(goop2->image), false); - break; - case QUOTED: - term = jj_consume_token(QUOTED); - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case FUZZY_SLOP: - fuzzySlop = jj_consume_token(FUZZY_SLOP); - break; - default: - jj_la1[20] = jj_gen; - } - switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) - { - case CARAT: - jj_consume_token(CARAT); - boost = jj_consume_token(NUMBER); - break; - default: - jj_la1[21] = jj_gen; - } - { - int32_t s = phraseSlop; - if (fuzzySlop) - { - try - { - s = StringUtils::toInt(fuzzySlop->image.substr(1)); - } - catch (...) - { - } - } - q = getFieldQuery(field, discardEscapeChar(term->image.substr(1, std::max((int32_t)0, (int32_t)term->image.length() - 2))), s); - } - break; - default: - jj_la1[22] = jj_gen; - jj_consume_token(-1); - boost::throw_exception(QueryParserError()); + q = getFuzzyQuery(field, termImage, fms); + } else { + q = getFieldQuery(field, termImage); + } + } + break; + case RANGEIN_START: + jj_consume_token(RANGEIN_START); + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case RANGEIN_GOOP: + goop1 = jj_consume_token(RANGEIN_GOOP); + break; + case RANGEIN_QUOTED: + goop1 = jj_consume_token(RANGEIN_QUOTED); + break; + default: + jj_la1[12] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case RANGEIN_TO: + jj_consume_token(RANGEIN_TO); + break; + default: + jj_la1[13] = jj_gen; + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case RANGEIN_GOOP: + goop2 = jj_consume_token(RANGEIN_GOOP); + break; + case RANGEIN_QUOTED: + goop2 = jj_consume_token(RANGEIN_QUOTED); + break; + default: + jj_la1[14] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); + } + jj_consume_token(RANGEIN_END); + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case CARAT: + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + break; + default: + jj_la1[15] = jj_gen; + } + if (goop1->kind == RANGEIN_QUOTED) { + goop1->image = goop1->image.substr(1, std::max((int32_t)0, (int32_t)goop1->image.length() - 2)); + } + if (goop2->kind == RANGEIN_QUOTED) { + goop2->image = goop2->image.substr(1, std::max((int32_t)0, (int32_t)goop2->image.length() - 2)); + } + q = getRangeQuery(field, discardEscapeChar(goop1->image), discardEscapeChar(goop2->image), true); + break; + case RANGEEX_START: + jj_consume_token(RANGEEX_START); + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case RANGEEX_GOOP: + goop1 = jj_consume_token(RANGEEX_GOOP); + break; + case RANGEEX_QUOTED: + goop1 = jj_consume_token(RANGEEX_QUOTED); + break; + default: + jj_la1[16] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case RANGEEX_TO: + jj_consume_token(RANGEEX_TO); + break; + default: + jj_la1[17] = jj_gen; + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case RANGEEX_GOOP: + goop2 = jj_consume_token(RANGEEX_GOOP); + break; + case RANGEEX_QUOTED: + goop2 = jj_consume_token(RANGEEX_QUOTED); + break; + default: + jj_la1[18] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); + } + jj_consume_token(RANGEEX_END); + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case CARAT: + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + break; + default: + jj_la1[19] = jj_gen; + } + if (goop1->kind == RANGEEX_QUOTED) { + goop1->image = goop1->image.substr(1, std::max((int32_t)0, (int32_t)goop1->image.length() - 2)); + } + if (goop2->kind == RANGEEX_QUOTED) { + goop2->image = goop2->image.substr(1, std::max((int32_t)0, (int32_t)goop2->image.length() - 2)); + } + q = getRangeQuery(field, discardEscapeChar(goop1->image), discardEscapeChar(goop2->image), false); + break; + case QUOTED: + term = jj_consume_token(QUOTED); + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case FUZZY_SLOP: + fuzzySlop = jj_consume_token(FUZZY_SLOP); + break; + default: + jj_la1[20] = jj_gen; + } + switch ((_jj_ntk == -1) ? jj_ntk() : _jj_ntk) { + case CARAT: + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + break; + default: + jj_la1[21] = jj_gen; } - if (boost) { - double f = 1.0; - try - { - f = StringUtils::toDouble(boost->image); - } - catch (...) - { + int32_t s = phraseSlop; + if (fuzzySlop) { + try { + s = StringUtils::toInt(fuzzySlop->image.substr(1)); + } catch (...) { + } } + q = getFieldQuery(field, discardEscapeChar(term->image.substr(1, std::max((int32_t)0, (int32_t)term->image.length() - 2))), s); + } + break; + default: + jj_la1[22] = jj_gen; + jj_consume_token(-1); + boost::throw_exception(QueryParserError()); + } + if (boost) { + double f = 1.0; + try { + f = StringUtils::toDouble(boost->image); + } catch (...) { + } - // avoid boosting null queries, such as those caused by stop words - if (q) - q->setBoost(f); + // avoid boosting null queries, such as those caused by stop words + if (q) { + q->setBoost(f); } - return q; } + return q; +} - bool QueryParser::jj_2_1(int32_t xla) - { - jj_la = xla; - jj_scanpos = token; - jj_lastpos = jj_scanpos; - bool _jj_2_1 = false; - LuceneException finally; - try - { - _jj_2_1 = !jj_3_1(); - } - catch (LookaheadSuccess&) - { - _jj_2_1 = true; - } - catch (LuceneException& e) - { - finally = e; - } - jj_save(0, xla); - finally.throwException(); - return _jj_2_1; +bool QueryParser::jj_2_1(int32_t xla) { + jj_la = xla; + jj_scanpos = token; + jj_lastpos = jj_scanpos; + bool _jj_2_1 = false; + LuceneException finally; + try { + _jj_2_1 = !jj_3_1(); + } catch (LookaheadSuccess&) { + _jj_2_1 = true; + } catch (LuceneException& e) { + finally = e; + } + jj_save(0, xla); + finally.throwException(); + return _jj_2_1; +} + +bool QueryParser::jj_3R_2() { + if (jj_scan_token(TERM)) { + return true; + } + if (jj_scan_token(COLON)) { + return true; } + return false; +} - bool QueryParser::jj_3R_2() - { - if (jj_scan_token(TERM)) - return true; - if (jj_scan_token(COLON)) +bool QueryParser::jj_3_1() { + QueryParserTokenPtr xsp(jj_scanpos); + if (jj_3R_2()) { + jj_scanpos = xsp; + if (jj_3R_3()) { return true; - return false; + } } + return false; +} - bool QueryParser::jj_3_1() - { - QueryParserTokenPtr xsp(jj_scanpos); - if (jj_3R_2()) - { - jj_scanpos = xsp; - if (jj_3R_3()) - return true; - } - return false; +bool QueryParser::jj_3R_3() { + if (jj_scan_token(STAR)) { + return true; + } + if (jj_scan_token(COLON)) { + return true; } + return false; +} - bool QueryParser::jj_3R_3() - { - if (jj_scan_token(STAR)) - return true; - if (jj_scan_token(COLON)) - return true; - return false; - } - - void QueryParser::ReInit(const QueryParserCharStreamPtr& stream) - { - token_source->ReInit(stream); - token = newLucene(); - _jj_ntk = -1; - jj_gen = 0; - for (int32_t i = 0; i < 23; ++i) - jj_la1[i] = -1; - for (int32_t i = 0; i < jj_2_rtns.size(); ++i) - jj_2_rtns[i] = newInstance(); - } - - void QueryParser::ReInit(const QueryParserTokenManagerPtr& tokenMgr) - { - token_source = tokenMgr; - token = newLucene(); - _jj_ntk = -1; - jj_gen = 0; - for (int32_t i = 0; i < 23; ++i) - jj_la1[i] = -1; - for (int32_t i = 0; i < jj_2_rtns.size(); ++i) - jj_2_rtns[i] = newInstance(); - } - - QueryParserTokenPtr QueryParser::jj_consume_token(int32_t kind) - { - QueryParserTokenPtr oldToken(token); - if (oldToken->next) - token = token->next; - else - { - token->next = token_source->getNextToken(); - token = token->next; - } - _jj_ntk = -1; - if (token->kind == kind) - { - ++jj_gen; - if (++jj_gc > 100) - { - jj_gc = 0; - for (int32_t i = 0; i < jj_2_rtns.size(); ++i) - { - JJCallsPtr c(jj_2_rtns[i]); - while (c) - { - if (c->gen < jj_gen) - c->first.reset(); - c = c->next; +void QueryParser::ReInit(const QueryParserCharStreamPtr& stream) { + token_source->ReInit(stream); + token = newLucene(); + _jj_ntk = -1; + jj_gen = 0; + for (int32_t i = 0; i < 23; ++i) { + jj_la1[i] = -1; + } + for (int32_t i = 0; i < jj_2_rtns.size(); ++i) { + jj_2_rtns[i] = newInstance(); + } +} + +void QueryParser::ReInit(const QueryParserTokenManagerPtr& tokenMgr) { + token_source = tokenMgr; + token = newLucene(); + _jj_ntk = -1; + jj_gen = 0; + for (int32_t i = 0; i < 23; ++i) { + jj_la1[i] = -1; + } + for (int32_t i = 0; i < jj_2_rtns.size(); ++i) { + jj_2_rtns[i] = newInstance(); + } +} + +QueryParserTokenPtr QueryParser::jj_consume_token(int32_t kind) { + QueryParserTokenPtr oldToken(token); + if (oldToken->next) { + token = token->next; + } else { + token->next = token_source->getNextToken(); + token = token->next; + } + _jj_ntk = -1; + if (token->kind == kind) { + ++jj_gen; + if (++jj_gc > 100) { + jj_gc = 0; + for (int32_t i = 0; i < jj_2_rtns.size(); ++i) { + JJCallsPtr c(jj_2_rtns[i]); + while (c) { + if (c->gen < jj_gen) { + c->first.reset(); } + c = c->next; } } - return token; } - token = oldToken; - jj_kind = kind; - generateParseException(); - return QueryParserTokenPtr(); + return token; } + token = oldToken; + jj_kind = kind; + generateParseException(); + return QueryParserTokenPtr(); +} - bool QueryParser::jj_scan_token(int32_t kind) - { - if (jj_scanpos == jj_lastpos) - { - --jj_la; - if (!jj_scanpos->next) - { - jj_scanpos->next = token_source->getNextToken(); - jj_scanpos = jj_scanpos->next; - jj_lastpos = jj_scanpos; - } - else - { - jj_scanpos = jj_scanpos->next; - jj_lastpos = jj_scanpos; - } - } - else +bool QueryParser::jj_scan_token(int32_t kind) { + if (jj_scanpos == jj_lastpos) { + --jj_la; + if (!jj_scanpos->next) { + jj_scanpos->next = token_source->getNextToken(); jj_scanpos = jj_scanpos->next; - if (jj_rescan) - { - int32_t i = 0; - QueryParserTokenPtr tok(token); - while (tok && tok != jj_scanpos) - { - ++i; - tok = tok->next; - } - if (tok) - jj_add_error_token(kind, i); + jj_lastpos = jj_scanpos; + } else { + jj_scanpos = jj_scanpos->next; + jj_lastpos = jj_scanpos; + } + } else { + jj_scanpos = jj_scanpos->next; + } + if (jj_rescan) { + int32_t i = 0; + QueryParserTokenPtr tok(token); + while (tok && tok != jj_scanpos) { + ++i; + tok = tok->next; + } + if (tok) { + jj_add_error_token(kind, i); } - if (jj_scanpos->kind != kind) - return true; - if (jj_la == 0 && jj_scanpos == jj_lastpos) - boost::throw_exception(LookaheadSuccess()); - return false; } + if (jj_scanpos->kind != kind) { + return true; + } + if (jj_la == 0 && jj_scanpos == jj_lastpos) { + boost::throw_exception(LookaheadSuccess()); + } + return false; +} - QueryParserTokenPtr QueryParser::getNextToken() - { - if (token->next) - token = token->next; - else - { - token->next = token_source->getNextToken(); - token = token->next; - } - _jj_ntk = -1; - ++jj_gen; - return token; +QueryParserTokenPtr QueryParser::getNextToken() { + if (token->next) { + token = token->next; + } else { + token->next = token_source->getNextToken(); + token = token->next; } + _jj_ntk = -1; + ++jj_gen; + return token; +} - QueryParserTokenPtr QueryParser::getToken(int32_t index) - { - QueryParserTokenPtr t(token); - for (int32_t i = 0; i < index; ++i) - { - if (t->next) - t = t->next; - else - { - t->next = token_source->getNextToken(); - t = t->next; - } +QueryParserTokenPtr QueryParser::getToken(int32_t index) { + QueryParserTokenPtr t(token); + for (int32_t i = 0; i < index; ++i) { + if (t->next) { + t = t->next; + } else { + t->next = token_source->getNextToken(); + t = t->next; } - return t; } + return t; +} - int32_t QueryParser::jj_ntk() - { - jj_nt = token->next; - if (!jj_nt) - { - token->next = token_source->getNextToken(); - _jj_ntk = token->next->kind; - return _jj_ntk; - } - else - { - _jj_ntk = jj_nt->kind; - return _jj_ntk; - } +int32_t QueryParser::jj_ntk() { + jj_nt = token->next; + if (!jj_nt) { + token->next = token_source->getNextToken(); + _jj_ntk = token->next->kind; + return _jj_ntk; + } else { + _jj_ntk = jj_nt->kind; + return _jj_ntk; } +} - void QueryParser::jj_add_error_token(int32_t kind, int32_t pos) - { - if (pos >= 100) - return; - if (pos == jj_endpos + 1) - jj_lasttokens[jj_endpos++] = kind; - else if (jj_endpos != 0) - { - jj_expentry = Collection::newInstance(jj_endpos); - for (int32_t i = 0; i < jj_endpos; ++i) - jj_expentry[i] = jj_lasttokens[i]; - for (Collection< Collection >::iterator oldentry = jj_expentries.begin(); oldentry != jj_expentries.end(); ++oldentry) - { - if (oldentry->size() == jj_expentry.size()) - { - bool jj_entries_loop = true; - for (int32_t i = 0; i < jj_expentry.size(); ++i) - { - if ((*oldentry)[i] != jj_expentry[i]) - { - jj_entries_loop = false; - break; - } +void QueryParser::jj_add_error_token(int32_t kind, int32_t pos) { + if (pos >= 100) { + return; + } + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + jj_expentry = Collection::newInstance(jj_endpos); + for (int32_t i = 0; i < jj_endpos; ++i) { + jj_expentry[i] = jj_lasttokens[i]; + } + for (Collection< Collection >::iterator oldentry = jj_expentries.begin(); oldentry != jj_expentries.end(); ++oldentry) { + if (oldentry->size() == jj_expentry.size()) { + bool jj_entries_loop = true; + for (int32_t i = 0; i < jj_expentry.size(); ++i) { + if ((*oldentry)[i] != jj_expentry[i]) { + jj_entries_loop = false; + break; } - if (!jj_entries_loop) - continue; - jj_expentries.add(jj_expentry); - break; } + if (!jj_entries_loop) { + continue; + } + jj_expentries.add(jj_expentry); + break; } - if (pos != 0) - { - jj_endpos = pos; - jj_lasttokens[jj_endpos - 1] = kind; - } + } + if (pos != 0) { + jj_endpos = pos; + jj_lasttokens[jj_endpos - 1] = kind; } } +} - void QueryParser::generateParseException() - { - jj_expentries.clear(); - Collection la1tokens(Collection::newInstance(34)); - if (jj_kind >= 0) - { - la1tokens[jj_kind] = true; - jj_kind = -1; - } - for (int32_t i = 0; i < 23; ++i) - { - if (jj_la1[i] == jj_gen) - { - for (int32_t j = 0; j < 32; ++j) - { - if ((jj_la1_0[i] & (1 << j)) != 0) - la1tokens[j] = true; - if ((jj_la1_1[i] & (1 << j)) != 0) - la1tokens[32 + j] = true; +void QueryParser::generateParseException() { + jj_expentries.clear(); + Collection la1tokens(Collection::newInstance(34)); + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int32_t i = 0; i < 23; ++i) { + if (jj_la1[i] == jj_gen) { + for (int32_t j = 0; j < 32; ++j) { + if ((jj_la1_0[i] & (1 << j)) != 0) { + la1tokens[j] = true; + } + if ((jj_la1_1[i] & (1 << j)) != 0) { + la1tokens[32 + j] = true; } } } - for (int32_t i = 0; i < 34; ++i) - { - if (la1tokens[i]) - { - jj_expentry = Collection::newInstance(1); - jj_expentry[0] = i; - jj_expentries.add(jj_expentry); - } + } + for (int32_t i = 0; i < 34; ++i) { + if (la1tokens[i]) { + jj_expentry = Collection::newInstance(1); + jj_expentry[0] = i; + jj_expentries.add(jj_expentry); } - jj_endpos = 0; - jj_rescan_token(); - jj_add_error_token(0, 0); - Collection< Collection > exptokseq(Collection< Collection >::newInstance(jj_expentries.size())); - for (int32_t i = 0; i < jj_expentries.size(); ++i) - exptokseq[i] = jj_expentries[i]; - boost::throw_exception(QueryParserError(QueryParseError::parseError(token, exptokseq, tokenImage))); } - - void QueryParser::enable_tracing() - { + jj_endpos = 0; + jj_rescan_token(); + jj_add_error_token(0, 0); + Collection< Collection > exptokseq(Collection< Collection >::newInstance(jj_expentries.size())); + for (int32_t i = 0; i < jj_expentries.size(); ++i) { + exptokseq[i] = jj_expentries[i]; } + boost::throw_exception(QueryParserError(QueryParseError::parseError(token, exptokseq, tokenImage))); +} - void QueryParser::disable_tracing() - { - } +void QueryParser::enable_tracing() { +} - void QueryParser::jj_rescan_token() - { - jj_rescan = true; - for (int32_t i = 0; i < 1; ++i) - { - try - { - JJCallsPtr p(jj_2_rtns[i]); - do - { - if (p->gen > jj_gen) - { - jj_la = p->arg; - jj_scanpos = p->first; - jj_lastpos = jj_scanpos; - jj_3_1(); - } - p = p->next; +void QueryParser::disable_tracing() { +} + +void QueryParser::jj_rescan_token() { + jj_rescan = true; + for (int32_t i = 0; i < 1; ++i) { + try { + JJCallsPtr p(jj_2_rtns[i]); + do { + if (p->gen > jj_gen) { + jj_la = p->arg; + jj_scanpos = p->first; + jj_lastpos = jj_scanpos; + jj_3_1(); } - while (p); - } - catch (LookaheadSuccess&) - { - } + p = p->next; + } while (p); + } catch (LookaheadSuccess&) { } - jj_rescan = false; } + jj_rescan = false; +} - void QueryParser::jj_save(int32_t index, int32_t xla) - { - JJCallsPtr p(jj_2_rtns[index]); - while (p->gen > jj_gen) - { - if (!p->next) - { - p->next = newInstance(); - p = p->next; - break; - } +void QueryParser::jj_save(int32_t index, int32_t xla) { + JJCallsPtr p(jj_2_rtns[index]); + while (p->gen > jj_gen) { + if (!p->next) { + p->next = newInstance(); p = p->next; + break; } - p->gen = jj_gen + xla - jj_la; - p->first = token; - p->arg = xla; + p = p->next; } + p->gen = jj_gen + xla - jj_la; + p->first = token; + p->arg = xla; +} + } diff --git a/src/core/queryparser/QueryParserCharStream.cpp b/src/core/queryparser/QueryParserCharStream.cpp index d9c4d390..a5d7b76f 100644 --- a/src/core/queryparser/QueryParserCharStream.cpp +++ b/src/core/queryparser/QueryParserCharStream.cpp @@ -7,77 +7,66 @@ #include "LuceneInc.h" #include "QueryParserCharStream.h" -namespace Lucene -{ - wchar_t QueryParserCharStream::readChar() - { - BOOST_ASSERT(false); - return 0; // override - } +namespace Lucene { - int32_t QueryParserCharStream::getColumn() - { - BOOST_ASSERT(false); - return 0; // override - } +wchar_t QueryParserCharStream::readChar() { + BOOST_ASSERT(false); + return 0; // override +} + +int32_t QueryParserCharStream::getColumn() { + BOOST_ASSERT(false); + return 0; // override +} - int32_t QueryParserCharStream::getLine() - { - BOOST_ASSERT(false); - return 0; // override - } +int32_t QueryParserCharStream::getLine() { + BOOST_ASSERT(false); + return 0; // override +} - int32_t QueryParserCharStream::getEndColumn() - { - BOOST_ASSERT(false); - return 0; // override - } +int32_t QueryParserCharStream::getEndColumn() { + BOOST_ASSERT(false); + return 0; // override +} + +int32_t QueryParserCharStream::getEndLine() { + BOOST_ASSERT(false); + return 0; // override +} - int32_t QueryParserCharStream::getEndLine() - { - BOOST_ASSERT(false); - return 0; // override - } +int32_t QueryParserCharStream::getBeginColumn() { + BOOST_ASSERT(false); + return 0; // override +} - int32_t QueryParserCharStream::getBeginColumn() - { - BOOST_ASSERT(false); - return 0; // override - } +int32_t QueryParserCharStream::getBeginLine() { + BOOST_ASSERT(false); + return 0; // override +} - int32_t QueryParserCharStream::getBeginLine() - { - BOOST_ASSERT(false); - return 0; // override - } +void QueryParserCharStream::backup(int32_t amount) { + BOOST_ASSERT(false); + // override +} - void QueryParserCharStream::backup(int32_t amount) - { - BOOST_ASSERT(false); - // override - } +wchar_t QueryParserCharStream::BeginToken() { + BOOST_ASSERT(false); + return 0; // override +} - wchar_t QueryParserCharStream::BeginToken() - { - BOOST_ASSERT(false); - return 0; // override - } +String QueryParserCharStream::GetImage() { + BOOST_ASSERT(false); + return L""; // override +} - String QueryParserCharStream::GetImage() - { - BOOST_ASSERT(false); - return L""; // override - } +CharArray QueryParserCharStream::GetSuffix(int32_t length) { + BOOST_ASSERT(false); + return CharArray(); // override +} - CharArray QueryParserCharStream::GetSuffix(int32_t length) - { - BOOST_ASSERT(false); - return CharArray(); // override - } +void QueryParserCharStream::Done() { + BOOST_ASSERT(false); + // override +} - void QueryParserCharStream::Done() - { - BOOST_ASSERT(false); - // override - } } diff --git a/src/core/queryparser/QueryParserConstants.cpp b/src/core/queryparser/QueryParserConstants.cpp index 48109f29..89e0cb85 100644 --- a/src/core/queryparser/QueryParserConstants.cpp +++ b/src/core/queryparser/QueryParserConstants.cpp @@ -7,52 +7,50 @@ #include "LuceneInc.h" #include "QueryParserConstants.h" -namespace Lucene -{ - const wchar_t* QueryParserConstants::_tokenImage[] = - { - L"", - L"<_NUM_CHAR>", - L"<_ESCAPED_CHAR>", - L"<_TERM_START_CHAR>", - L"<_TERM_CHAR>", - L"<_WHITESPACE>", - L"<_QUOTED_CHAR>", - L"", - L"", - L"", - L"", - L"\"+\"", - L"\"-\"", - L"\"(\"", - L"\")\"", - L"\":\"", - L"\"*\"", - L"\"^\"", - L"", - L"", - L"", - L"", - L"", - L"\"[\"", - L"\"{\"", - L"", - L"\"TO\"", - L"\"]\"", - L"", - L"", - L"\"TO\"", - L"\"}\"", - L"", - L"" - }; - Collection QueryParserConstants::tokenImage = Collection::newInstance(_tokenImage, _tokenImage + SIZEOF_ARRAY(_tokenImage)); +namespace Lucene { - QueryParserConstants::QueryParserConstants() - { - } +const wchar_t* QueryParserConstants::_tokenImage[] = { + L"", + L"<_NUM_CHAR>", + L"<_ESCAPED_CHAR>", + L"<_TERM_START_CHAR>", + L"<_TERM_CHAR>", + L"<_WHITESPACE>", + L"<_QUOTED_CHAR>", + L"", + L"", + L"", + L"", + L"\"+\"", + L"\"-\"", + L"\"(\"", + L"\")\"", + L"\":\"", + L"\"*\"", + L"\"^\"", + L"", + L"", + L"", + L"", + L"", + L"\"[\"", + L"\"{\"", + L"", + L"\"TO\"", + L"\"]\"", + L"", + L"", + L"\"TO\"", + L"\"}\"", + L"", + L"" +}; +Collection QueryParserConstants::tokenImage = Collection::newInstance(_tokenImage, _tokenImage + SIZEOF_ARRAY(_tokenImage)); + +QueryParserConstants::QueryParserConstants() { +} + +QueryParserConstants::~QueryParserConstants() { +} - QueryParserConstants::~QueryParserConstants() - { - } } diff --git a/src/core/queryparser/QueryParserToken.cpp b/src/core/queryparser/QueryParserToken.cpp index 5bfa7290..973c331c 100644 --- a/src/core/queryparser/QueryParserToken.cpp +++ b/src/core/queryparser/QueryParserToken.cpp @@ -7,29 +7,26 @@ #include "LuceneInc.h" #include "QueryParserToken.h" -namespace Lucene -{ - QueryParserToken::QueryParserToken(int32_t kind, const String& image) - { - this->kind = kind; - this->image = image; - this->beginLine = 0; - this->beginColumn = 0; - this->endLine = 0; - this->endColumn = 0; - } +namespace Lucene { - QueryParserToken::~QueryParserToken() - { - } +QueryParserToken::QueryParserToken(int32_t kind, const String& image) { + this->kind = kind; + this->image = image; + this->beginLine = 0; + this->beginColumn = 0; + this->endLine = 0; + this->endColumn = 0; +} + +QueryParserToken::~QueryParserToken() { +} - String QueryParserToken::toString() - { - return image; - } +String QueryParserToken::toString() { + return image; +} + +QueryParserTokenPtr QueryParserToken::newToken(int32_t ofKind, const String& image) { + return newLucene(ofKind, image); +} - QueryParserTokenPtr QueryParserToken::newToken(int32_t ofKind, const String& image) - { - return newLucene(ofKind, image); - } } diff --git a/src/core/queryparser/QueryParserTokenManager.cpp b/src/core/queryparser/QueryParserTokenManager.cpp index 9c278763..cd43c7e8 100644 --- a/src/core/queryparser/QueryParserTokenManager.cpp +++ b/src/core/queryparser/QueryParserTokenManager.cpp @@ -12,1329 +12,1279 @@ #include "InfoStream.h" #include "StringUtils.h" -namespace Lucene -{ - const int64_t QueryParserTokenManager::jjbitVec0[] = {0x1LL, 0x0LL, 0x0LL, 0x0LL}; - const int64_t QueryParserTokenManager::jjbitVec1[] = {static_cast(0xfffffffffffffffeLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; - const int64_t QueryParserTokenManager::jjbitVec3[] = {0x0LL, 0x0LL, static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; - const int64_t QueryParserTokenManager::jjbitVec4[] = {static_cast(0xfffefffffffffffeLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; +namespace Lucene { - const int32_t QueryParserTokenManager::jjnextStates[] = {15, 16, 18, 29, 32, 23, 33, 30, 20, 21, 32, 23, 33, 31, 34, 27, 2, 4, 5, 0, 1}; +const int64_t QueryParserTokenManager::jjbitVec0[] = {0x1LL, 0x0LL, 0x0LL, 0x0LL}; +const int64_t QueryParserTokenManager::jjbitVec1[] = {static_cast(0xfffffffffffffffeLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; +const int64_t QueryParserTokenManager::jjbitVec3[] = {0x0LL, 0x0LL, static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; +const int64_t QueryParserTokenManager::jjbitVec4[] = {static_cast(0xfffefffffffffffeLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL), static_cast(0xffffffffffffffffLL)}; - /// Token literal values. - const wchar_t* QueryParserTokenManager::jjstrLiteralImages[] = - { - L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"\53", L"\55", - L"\50", L"\51", L"\72", L"\52", L"\136", L"", L"", L"", L"", L"", L"\133", - L"\173", L"", L"\124\117", L"\135", L"", L"", L"\124\117", L"\175", L"", L"" - }; +const int32_t QueryParserTokenManager::jjnextStates[] = {15, 16, 18, 29, 32, 23, 33, 30, 20, 21, 32, 23, 33, 31, 34, 27, 2, 4, 5, 0, 1}; - /// Lexer state names. - const wchar_t* QueryParserTokenManager::lexStateNames[] = - { - L"Boost", L"RangeEx", L"RangeIn", L"DEFAULT" - }; +/// Token literal values. +const wchar_t* QueryParserTokenManager::jjstrLiteralImages[] = { + L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"\53", L"\55", + L"\50", L"\51", L"\72", L"\52", L"\136", L"", L"", L"", L"", L"", L"\133", + L"\173", L"", L"\124\117", L"\135", L"", L"", L"\124\117", L"\175", L"", L"" +}; - /// Lex State array. - const int32_t QueryParserTokenManager::jjnewLexState[] = - { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, - -1, -1, -1, -1, -1, 2, 1, 3, -1, 3, -1, -1, -1, 3, -1, -1 - }; +/// Lexer state names. +const wchar_t* QueryParserTokenManager::lexStateNames[] = { + L"Boost", L"RangeEx", L"RangeIn", L"DEFAULT" +}; - const int64_t QueryParserTokenManager::jjtoToken[] = {0x3ffffff01LL}; - const int64_t QueryParserTokenManager::jjtoSkip[] = {0x80LL}; +/// Lex State array. +const int32_t QueryParserTokenManager::jjnewLexState[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, + -1, -1, -1, -1, -1, 2, 1, 3, -1, 3, -1, -1, -1, 3, -1, -1 +}; - QueryParserTokenManager::QueryParserTokenManager(const QueryParserCharStreamPtr& stream) - { - debugStream = newLucene(); - jjrounds = IntArray::newInstance(36); - jjstateSet = IntArray::newInstance(72); - curChar = 0; - curLexState = 3; - defaultLexState = 3; - jjnewStateCnt = 0; - jjround = 0; - jjmatchedPos = 0; - jjmatchedKind = 0; - input_stream = stream; - } +const int64_t QueryParserTokenManager::jjtoToken[] = {0x3ffffff01LL}; +const int64_t QueryParserTokenManager::jjtoSkip[] = {0x80LL}; - QueryParserTokenManager::QueryParserTokenManager(const QueryParserCharStreamPtr& stream, int32_t lexState) - { - debugStream = newLucene(); - jjrounds = IntArray::newInstance(36); - jjstateSet = IntArray::newInstance(72); - input_stream = stream; - curChar = 0; - curLexState = 3; - defaultLexState = 3; - jjnewStateCnt = 0; - jjround = 0; - jjmatchedPos = 0; - jjmatchedKind = 0; - SwitchTo(lexState); - } +QueryParserTokenManager::QueryParserTokenManager(const QueryParserCharStreamPtr& stream) { + debugStream = newLucene(); + jjrounds = IntArray::newInstance(36); + jjstateSet = IntArray::newInstance(72); + curChar = 0; + curLexState = 3; + defaultLexState = 3; + jjnewStateCnt = 0; + jjround = 0; + jjmatchedPos = 0; + jjmatchedKind = 0; + input_stream = stream; +} - QueryParserTokenManager::~QueryParserTokenManager() - { - } +QueryParserTokenManager::QueryParserTokenManager(const QueryParserCharStreamPtr& stream, int32_t lexState) { + debugStream = newLucene(); + jjrounds = IntArray::newInstance(36); + jjstateSet = IntArray::newInstance(72); + input_stream = stream; + curChar = 0; + curLexState = 3; + defaultLexState = 3; + jjnewStateCnt = 0; + jjround = 0; + jjmatchedPos = 0; + jjmatchedKind = 0; + SwitchTo(lexState); +} - void QueryParserTokenManager::setDebugStream(const InfoStreamPtr& debugStream) - { - this->debugStream = debugStream; - } +QueryParserTokenManager::~QueryParserTokenManager() { +} - int32_t QueryParserTokenManager::jjStopStringLiteralDfa_3(int32_t pos, int64_t active0) - { - return -1; - } +void QueryParserTokenManager::setDebugStream(const InfoStreamPtr& debugStream) { + this->debugStream = debugStream; +} - int32_t QueryParserTokenManager::jjStartNfa_3(int32_t pos, int64_t active0) - { - return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1); - } +int32_t QueryParserTokenManager::jjStopStringLiteralDfa_3(int32_t pos, int64_t active0) { + return -1; +} - int32_t QueryParserTokenManager::jjStopAtPos(int32_t pos, int32_t kind) - { - jjmatchedKind = kind; - jjmatchedPos = pos; - return pos + 1; - } +int32_t QueryParserTokenManager::jjStartNfa_3(int32_t pos, int64_t active0) { + return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1); +} - int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_3() - { - switch (curChar) - { - case 40: - return jjStopAtPos(0, 13); - case 41: - return jjStopAtPos(0, 14); - case 42: - return jjStartNfaWithStates_3(0, 16, 36); - case 43: - return jjStopAtPos(0, 11); - case 45: - return jjStopAtPos(0, 12); - case 58: - return jjStopAtPos(0, 15); - case 91: - return jjStopAtPos(0, 23); - case 94: - return jjStopAtPos(0, 17); - case 123: - return jjStopAtPos(0, 24); - default: - return jjMoveNfa_3(0, 0); - } +int32_t QueryParserTokenManager::jjStopAtPos(int32_t pos, int32_t kind) { + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} + +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_3() { + switch (curChar) { + case 40: + return jjStopAtPos(0, 13); + case 41: + return jjStopAtPos(0, 14); + case 42: + return jjStartNfaWithStates_3(0, 16, 36); + case 43: + return jjStopAtPos(0, 11); + case 45: + return jjStopAtPos(0, 12); + case 58: + return jjStopAtPos(0, 15); + case 91: + return jjStopAtPos(0, 23); + case 94: + return jjStopAtPos(0, 17); + case 123: + return jjStopAtPos(0, 24); + default: + return jjMoveNfa_3(0, 0); } +} - int32_t QueryParserTokenManager::jjStartNfaWithStates_3(int32_t pos, int32_t kind, int32_t state) - { - jjmatchedKind = kind; - jjmatchedPos = pos; - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - return pos + 1; - } - return jjMoveNfa_3(state, pos + 1); +int32_t QueryParserTokenManager::jjStartNfaWithStates_3(int32_t pos, int32_t kind, int32_t state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + return pos + 1; } + return jjMoveNfa_3(state, pos + 1); +} - int32_t QueryParserTokenManager::jjMoveNfa_3(int32_t startState, int32_t curPos) - { - int32_t startsAt = 0; - jjnewStateCnt = 36; - int32_t i = 1; - jjstateSet[0] = startState; - int32_t kind = 0x7fffffff; - while (true) - { - if (++jjround == 0x7fffffff) - ReInitRounds(); - if (curChar < 64) - { - int64_t l = (int64_t)1 << curChar; - do - { - switch (jjstateSet[--i]) - { - case 36: - case 25: - if ((0xfbfffcf8ffffd9ffLL & l) == 0) - break; - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 0: - if ((0xfbffd4f8ffffd9ffLL & l) != 0) - { - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - } - else if ((0x100002600LL & l) != 0) - { - if (kind > 7) - kind = 7; - } - else if (curChar == 34) - jjCheckNAddStates(0, 2); - else if (curChar == 33) - { - if (kind > 10) - kind = 10; - } - if ((0x7bffd0f8ffffd9ffLL & l) != 0) - { - if (kind > 19) - kind = 19; - jjCheckNAddStates(3, 7); - } - else if (curChar == 42) - { - if (kind > 21) - kind = 21; - } - if (curChar == 38) - jjstateSet[jjnewStateCnt++] = 4; - break; - case 4: - if (curChar == 38 && kind > 8) - kind = 8; - break; - case 5: - if (curChar == 38) - jjstateSet[jjnewStateCnt++] = 4; - break; - case 13: - if (curChar == 33 && kind > 10) - kind = 10; - break; - case 14: - if (curChar == 34) - jjCheckNAddStates(0, 2); - break; - case 15: - if ((0xfffffffbffffffffLL & l) != 0) - jjCheckNAddStates(0, 2); - break; - case 17: - jjCheckNAddStates(0, 2); - break; - case 18: - if (curChar == 34 && kind > 18) - kind = 18; - break; - case 20: - if ((0x3ff000000000000LL & l) == 0) - break; - if (kind > 20) - kind = 20; - jjAddStates(8, 9); - break; - case 21: - if (curChar == 46) - jjCheckNAdd(22); - break; - case 22: - if ((0x3ff000000000000LL & l) == 0) - break; - if (kind > 20) - kind = 20; - jjCheckNAdd(22); - break; - case 23: - if (curChar == 42 && kind > 21) - kind = 21; - break; - case 24: - if ((0xfbffd4f8ffffd9ffLL & l) == 0) - break; - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 27: - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 28: - if ((0x7bffd0f8ffffd9ffLL & l) == 0) - break; - if (kind > 19) - kind = 19; - jjCheckNAddStates(3, 7); - break; - case 29: - if ((0x7bfff8f8ffffd9ffLL & l) == 0) - break; - if (kind > 19) - kind = 19; - jjCheckNAddTwoStates(29, 30); - break; - case 31: - if (kind > 19) - kind = 19; - jjCheckNAddTwoStates(29, 30); - break; - case 32: - if ((0x7bfff8f8ffffd9ffLL & l) != 0) - jjCheckNAddStates(10, 12); - break; - case 34: - jjCheckNAddStates(10, 12); - break; - default: - break; +int32_t QueryParserTokenManager::jjMoveNfa_3(int32_t startState, int32_t curPos) { + int32_t startsAt = 0; + jjnewStateCnt = 36; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + while (true) { + if (++jjround == 0x7fffffff) { + ReInitRounds(); + } + if (curChar < 64) { + int64_t l = (int64_t)1 << curChar; + do { + switch (jjstateSet[--i]) { + case 36: + case 25: + if ((0xfbfffcf8ffffd9ffLL & l) == 0) { + break; } + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 0: + if ((0xfbffd4f8ffffd9ffLL & l) != 0) { + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + } else if ((0x100002600LL & l) != 0) { + if (kind > 7) { + kind = 7; + } + } else if (curChar == 34) { + jjCheckNAddStates(0, 2); + } else if (curChar == 33) { + if (kind > 10) { + kind = 10; + } + } + if ((0x7bffd0f8ffffd9ffLL & l) != 0) { + if (kind > 19) { + kind = 19; + } + jjCheckNAddStates(3, 7); + } else if (curChar == 42) { + if (kind > 21) { + kind = 21; + } + } + if (curChar == 38) { + jjstateSet[jjnewStateCnt++] = 4; + } + break; + case 4: + if (curChar == 38 && kind > 8) { + kind = 8; + } + break; + case 5: + if (curChar == 38) { + jjstateSet[jjnewStateCnt++] = 4; + } + break; + case 13: + if (curChar == 33 && kind > 10) { + kind = 10; + } + break; + case 14: + if (curChar == 34) { + jjCheckNAddStates(0, 2); + } + break; + case 15: + if ((0xfffffffbffffffffLL & l) != 0) { + jjCheckNAddStates(0, 2); + } + break; + case 17: + jjCheckNAddStates(0, 2); + break; + case 18: + if (curChar == 34 && kind > 18) { + kind = 18; + } + break; + case 20: + if ((0x3ff000000000000LL & l) == 0) { + break; + } + if (kind > 20) { + kind = 20; + } + jjAddStates(8, 9); + break; + case 21: + if (curChar == 46) { + jjCheckNAdd(22); + } + break; + case 22: + if ((0x3ff000000000000LL & l) == 0) { + break; + } + if (kind > 20) { + kind = 20; + } + jjCheckNAdd(22); + break; + case 23: + if (curChar == 42 && kind > 21) { + kind = 21; + } + break; + case 24: + if ((0xfbffd4f8ffffd9ffLL & l) == 0) { + break; + } + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 27: + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 28: + if ((0x7bffd0f8ffffd9ffLL & l) == 0) { + break; + } + if (kind > 19) { + kind = 19; + } + jjCheckNAddStates(3, 7); + break; + case 29: + if ((0x7bfff8f8ffffd9ffLL & l) == 0) { + break; + } + if (kind > 19) { + kind = 19; + } + jjCheckNAddTwoStates(29, 30); + break; + case 31: + if (kind > 19) { + kind = 19; + } + jjCheckNAddTwoStates(29, 30); + break; + case 32: + if ((0x7bfff8f8ffffd9ffLL & l) != 0) { + jjCheckNAddStates(10, 12); + } + break; + case 34: + jjCheckNAddStates(10, 12); + break; + default: + break; } - while (i != startsAt); - } - else if (curChar < 128) - { - int64_t l = (int64_t)1 << (curChar & 077); - do - { - switch (jjstateSet[--i]) - { - case 36: - if ((0x97ffffff87ffffffLL & l) != 0) - { - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - } - else if (curChar == 92) - jjCheckNAddTwoStates(27, 27); - break; - case 0: - if ((0x97ffffff87ffffffLL & l) != 0) - { - if (kind > 19) - kind = 19; - jjCheckNAddStates(3, 7); - } - else if (curChar == 92) - jjCheckNAddStates(13, 15); - else if (curChar == 126) - { - if (kind > 20) - kind = 20; - jjstateSet[jjnewStateCnt++] = 20; - } - if ((0x97ffffff87ffffffLL & l) != 0) - { - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - } - if (curChar == 78) - jjstateSet[jjnewStateCnt++] = 11; - else if (curChar == 124) - jjstateSet[jjnewStateCnt++] = 8; - else if (curChar == 79) - jjstateSet[jjnewStateCnt++] = 6; - else if (curChar == 65) - jjstateSet[jjnewStateCnt++] = 2; - break; - case 1: - if (curChar == 68 && kind > 8) - kind = 8; - break; - case 2: - if (curChar == 78) - jjstateSet[jjnewStateCnt++] = 1; - break; - case 3: - if (curChar == 65) - jjstateSet[jjnewStateCnt++] = 2; - break; - case 6: - if (curChar == 82 && kind > 9) - kind = 9; - break; - case 7: - if (curChar == 79) - jjstateSet[jjnewStateCnt++] = 6; - break; - case 8: - if (curChar == 124 && kind > 9) - kind = 9; - break; - case 9: - if (curChar == 124) - jjstateSet[jjnewStateCnt++] = 8; - break; - case 10: - if (curChar == 84 && kind > 10) - kind = 10; - break; - case 11: - if (curChar == 79) - jjstateSet[jjnewStateCnt++] = 10; - break; - case 12: - if (curChar == 78) - jjstateSet[jjnewStateCnt++] = 11; - break; - case 15: - if ((0xffffffffefffffffLL & l) != 0) - jjCheckNAddStates(0, 2); - break; - case 16: - if (curChar == 92) - jjstateSet[jjnewStateCnt++] = 17; - break; - case 17: - jjCheckNAddStates(0, 2); - break; - case 19: - if (curChar != 126) - break; - if (kind > 20) - kind = 20; - jjstateSet[jjnewStateCnt++] = 20; - break; - case 24: - if ((0x97ffffff87ffffffLL & l) == 0) - break; - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 25: - if ((0x97ffffff87ffffffLL & l) == 0) - break; - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 26: - if (curChar == 92) - jjCheckNAddTwoStates(27, 27); - break; - case 27: - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 28: - if ((0x97ffffff87ffffffLL & l) == 0) - break; - if (kind > 19) - kind = 19; - jjCheckNAddStates(3, 7); - break; - case 29: - if ((0x97ffffff87ffffffLL & l) == 0) - break; - if (kind > 19) - kind = 19; - jjCheckNAddTwoStates(29, 30); - break; - case 30: - if (curChar == 92) - jjCheckNAddTwoStates(31, 31); - break; - case 31: - if (kind > 19) - kind = 19; - jjCheckNAddTwoStates(29, 30); - break; - case 32: - if ((0x97ffffff87ffffffLL & l) != 0) - jjCheckNAddStates(10, 12); - break; - case 33: - if (curChar == 92) - jjCheckNAddTwoStates(34, 34); - break; - case 34: - jjCheckNAddStates(10, 12); - break; - case 35: - if (curChar == 92) - jjCheckNAddStates(13, 15); - break; - default: - break; + } while (i != startsAt); + } else if (curChar < 128) { + int64_t l = (int64_t)1 << (curChar & 077); + do { + switch (jjstateSet[--i]) { + case 36: + if ((0x97ffffff87ffffffLL & l) != 0) { + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + } else if (curChar == 92) { + jjCheckNAddTwoStates(27, 27); + } + break; + case 0: + if ((0x97ffffff87ffffffLL & l) != 0) { + if (kind > 19) { + kind = 19; + } + jjCheckNAddStates(3, 7); + } else if (curChar == 92) { + jjCheckNAddStates(13, 15); + } else if (curChar == 126) { + if (kind > 20) { + kind = 20; + } + jjstateSet[jjnewStateCnt++] = 20; + } + if ((0x97ffffff87ffffffLL & l) != 0) { + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + } + if (curChar == 78) { + jjstateSet[jjnewStateCnt++] = 11; + } else if (curChar == 124) { + jjstateSet[jjnewStateCnt++] = 8; + } else if (curChar == 79) { + jjstateSet[jjnewStateCnt++] = 6; + } else if (curChar == 65) { + jjstateSet[jjnewStateCnt++] = 2; + } + break; + case 1: + if (curChar == 68 && kind > 8) { + kind = 8; + } + break; + case 2: + if (curChar == 78) { + jjstateSet[jjnewStateCnt++] = 1; + } + break; + case 3: + if (curChar == 65) { + jjstateSet[jjnewStateCnt++] = 2; + } + break; + case 6: + if (curChar == 82 && kind > 9) { + kind = 9; + } + break; + case 7: + if (curChar == 79) { + jjstateSet[jjnewStateCnt++] = 6; + } + break; + case 8: + if (curChar == 124 && kind > 9) { + kind = 9; + } + break; + case 9: + if (curChar == 124) { + jjstateSet[jjnewStateCnt++] = 8; + } + break; + case 10: + if (curChar == 84 && kind > 10) { + kind = 10; } + break; + case 11: + if (curChar == 79) { + jjstateSet[jjnewStateCnt++] = 10; + } + break; + case 12: + if (curChar == 78) { + jjstateSet[jjnewStateCnt++] = 11; + } + break; + case 15: + if ((0xffffffffefffffffLL & l) != 0) { + jjCheckNAddStates(0, 2); + } + break; + case 16: + if (curChar == 92) { + jjstateSet[jjnewStateCnt++] = 17; + } + break; + case 17: + jjCheckNAddStates(0, 2); + break; + case 19: + if (curChar != 126) { + break; + } + if (kind > 20) { + kind = 20; + } + jjstateSet[jjnewStateCnt++] = 20; + break; + case 24: + if ((0x97ffffff87ffffffLL & l) == 0) { + break; + } + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 25: + if ((0x97ffffff87ffffffLL & l) == 0) { + break; + } + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 26: + if (curChar == 92) { + jjCheckNAddTwoStates(27, 27); + } + break; + case 27: + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 28: + if ((0x97ffffff87ffffffLL & l) == 0) { + break; + } + if (kind > 19) { + kind = 19; + } + jjCheckNAddStates(3, 7); + break; + case 29: + if ((0x97ffffff87ffffffLL & l) == 0) { + break; + } + if (kind > 19) { + kind = 19; + } + jjCheckNAddTwoStates(29, 30); + break; + case 30: + if (curChar == 92) { + jjCheckNAddTwoStates(31, 31); + } + break; + case 31: + if (kind > 19) { + kind = 19; + } + jjCheckNAddTwoStates(29, 30); + break; + case 32: + if ((0x97ffffff87ffffffLL & l) != 0) { + jjCheckNAddStates(10, 12); + } + break; + case 33: + if (curChar == 92) { + jjCheckNAddTwoStates(34, 34); + } + break; + case 34: + jjCheckNAddStates(10, 12); + break; + case 35: + if (curChar == 92) { + jjCheckNAddStates(13, 15); + } + break; + default: + break; } - while (i != startsAt); - } - else - { - int32_t hiByte = (int32_t)(curChar >> 8); - int32_t i1 = hiByte >> 6; - int64_t l1 = (int64_t)1 << (hiByte & 077); - int32_t i2 = (curChar & 0xff) >> 6; - int64_t l2 = (int64_t)1 << (curChar & 077); - do - { - switch (jjstateSet[--i]) - { - case 36: - case 25: - if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) - break; - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 0: - if (jjCanMove_0(hiByte, i1, i2, l1, l2)) - { - if (kind > 7) - kind = 7; - } - if (jjCanMove_2(hiByte, i1, i2, l1, l2)) - { - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - } - if (jjCanMove_2(hiByte, i1, i2, l1, l2)) - { - if (kind > 19) - kind = 19; - jjCheckNAddStates(3, 7); - } - break; - case 15: - case 17: - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - jjCheckNAddStates(0, 2); - break; - case 24: - if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) + } while (i != startsAt); + } else { + int32_t hiByte = (int32_t)(curChar >> 8); + int32_t i1 = hiByte >> 6; + int64_t l1 = (int64_t)1 << (hiByte & 077); + int32_t i2 = (curChar & 0xff) >> 6; + int64_t l2 = (int64_t)1 << (curChar & 077); + do { + switch (jjstateSet[--i]) { + case 36: + case 25: + if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) { + break; + } + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 0: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) { + if (kind > 7) { + kind = 7; + } + } + if (jjCanMove_2(hiByte, i1, i2, l1, l2)) { + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + } + if (jjCanMove_2(hiByte, i1, i2, l1, l2)) { + if (kind > 19) { + kind = 19; + } + jjCheckNAddStates(3, 7); + } + break; + case 15: + case 17: + if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { + jjCheckNAddStates(0, 2); + } + break; + case 24: + if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) { + break; + } + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 27: + if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) { + break; + } + if (kind > 22) { + kind = 22; + } + jjCheckNAddTwoStates(25, 26); + break; + case 28: + if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) { break; - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 27: - if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) - break; - if (kind > 22) - kind = 22; - jjCheckNAddTwoStates(25, 26); - break; - case 28: - if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) - break; - if (kind > 19) - kind = 19; - jjCheckNAddStates(3, 7); + } + if (kind > 19) { + kind = 19; + } + jjCheckNAddStates(3, 7); + break; + case 29: + if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) { break; - case 29: - if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) - break; - if (kind > 19) - kind = 19; - jjCheckNAddTwoStates(29, 30); - break; - case 31: - if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) - break; - if (kind > 19) - kind = 19; - jjCheckNAddTwoStates(29, 30); - break; - case 32: - if (jjCanMove_2(hiByte, i1, i2, l1, l2)) - jjCheckNAddStates(10, 12); - break; - case 34: - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - jjCheckNAddStates(10, 12); - break; - default: - break; } + if (kind > 19) { + kind = 19; + } + jjCheckNAddTwoStates(29, 30); + break; + case 31: + if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) { + break; + } + if (kind > 19) { + kind = 19; + } + jjCheckNAddTwoStates(29, 30); + break; + case 32: + if (jjCanMove_2(hiByte, i1, i2, l1, l2)) { + jjCheckNAddStates(10, 12); + } + break; + case 34: + if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { + jjCheckNAddStates(10, 12); + } + break; + default: + break; } - while (i != startsAt); - } - if (kind != 0x7fffffff) - { - jjmatchedKind = kind; - jjmatchedPos = curPos; - kind = 0x7fffffff; - } - ++curPos; - i = jjnewStateCnt; - jjnewStateCnt = startsAt; - if (i == (startsAt = 36 - jjnewStateCnt)) - return curPos; - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - return curPos; - } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 36 - jjnewStateCnt)) { + return curPos; + } + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + return curPos; } } +} - int32_t QueryParserTokenManager::jjStopStringLiteralDfa_1(int32_t pos, int64_t active0) - { - switch (pos) - { - case 0: - if ((active0 & 0x40000000LL) != 0) - { - jjmatchedKind = 33; - return 6; - } - return -1; - default: - return -1; +int32_t QueryParserTokenManager::jjStopStringLiteralDfa_1(int32_t pos, int64_t active0) { + switch (pos) { + case 0: + if ((active0 & 0x40000000LL) != 0) { + jjmatchedKind = 33; + return 6; } + return -1; + default: + return -1; } +} - int32_t QueryParserTokenManager::jjStartNfa_1(int32_t pos, int64_t active0) - { - return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); - } +int32_t QueryParserTokenManager::jjStartNfa_1(int32_t pos, int64_t active0) { + return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); +} - int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_1() - { - switch (curChar) - { - case 84: - return jjMoveStringLiteralDfa1_1(0x40000000LL); - case 125: - return jjStopAtPos(0, 31); - default: - return jjMoveNfa_1(0, 0); - } +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_1() { + switch (curChar) { + case 84: + return jjMoveStringLiteralDfa1_1(0x40000000LL); + case 125: + return jjStopAtPos(0, 31); + default: + return jjMoveNfa_1(0, 0); } +} - int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_1(int64_t active0) - { - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - jjStopStringLiteralDfa_1(0, active0); - return 1; - } - switch (curChar) - { - case 79: - if ((active0 & 0x40000000LL) != 0) - return jjStartNfaWithStates_1(1, 30, 6); - break; - default: - break; +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_1(int64_t active0) { + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + jjStopStringLiteralDfa_1(0, active0); + return 1; + } + switch (curChar) { + case 79: + if ((active0 & 0x40000000LL) != 0) { + return jjStartNfaWithStates_1(1, 30, 6); } - return jjStartNfa_1(0, active0); + break; + default: + break; } + return jjStartNfa_1(0, active0); +} - int32_t QueryParserTokenManager::jjStartNfaWithStates_1(int32_t pos, int32_t kind, int32_t state) - { - jjmatchedKind = kind; - jjmatchedPos = pos; - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - return pos + 1; - } - return jjMoveNfa_1(state, pos + 1); +int32_t QueryParserTokenManager::jjStartNfaWithStates_1(int32_t pos, int32_t kind, int32_t state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + return pos + 1; } + return jjMoveNfa_1(state, pos + 1); +} - int32_t QueryParserTokenManager::jjMoveNfa_1(int32_t startState, int32_t curPos) - { - int32_t startsAt = 0; - jjnewStateCnt = 7; - int32_t i = 1; - jjstateSet[0] = startState; - int32_t kind = 0x7fffffff; - while (true) - { - if (++jjround == 0x7fffffff) - ReInitRounds(); - if (curChar < 64) - { - int64_t l = (int64_t)1 << curChar; - do - { - switch (jjstateSet[--i]) - { - case 0: - if ((0xfffffffeffffffffLL & l) != 0) - { - if (kind > 33) - kind = 33; - jjCheckNAdd(6); - } - if ((0x100002600LL & l) != 0) - { - if (kind > 7) - kind = 7; - } - else if (curChar == 34) - jjCheckNAddTwoStates(2, 4); - break; - case 1: - if (curChar == 34) - jjCheckNAddTwoStates(2, 4); - break; - case 2: - if ((0xfffffffbffffffffLL & l) != 0) - jjCheckNAddStates(16, 18); - break; - case 3: - if (curChar == 34) - jjCheckNAddStates(16, 18); - break; - case 5: - if (curChar == 34 && kind > 32) - kind = 32; - break; - case 6: - if ((0xfffffffeffffffffLL & l) == 0) - break; - if (kind > 33) - kind = 33; - jjCheckNAdd(6); - break; - default: - break; +int32_t QueryParserTokenManager::jjMoveNfa_1(int32_t startState, int32_t curPos) { + int32_t startsAt = 0; + jjnewStateCnt = 7; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + while (true) { + if (++jjround == 0x7fffffff) { + ReInitRounds(); + } + if (curChar < 64) { + int64_t l = (int64_t)1 << curChar; + do { + switch (jjstateSet[--i]) { + case 0: + if ((0xfffffffeffffffffLL & l) != 0) { + if (kind > 33) { + kind = 33; + } + jjCheckNAdd(6); + } + if ((0x100002600LL & l) != 0) { + if (kind > 7) { + kind = 7; + } + } else if (curChar == 34) { + jjCheckNAddTwoStates(2, 4); + } + break; + case 1: + if (curChar == 34) { + jjCheckNAddTwoStates(2, 4); + } + break; + case 2: + if ((0xfffffffbffffffffLL & l) != 0) { + jjCheckNAddStates(16, 18); + } + break; + case 3: + if (curChar == 34) { + jjCheckNAddStates(16, 18); } + break; + case 5: + if (curChar == 34 && kind > 32) { + kind = 32; + } + break; + case 6: + if ((0xfffffffeffffffffLL & l) == 0) { + break; + } + if (kind > 33) { + kind = 33; + } + jjCheckNAdd(6); + break; + default: + break; } - while (i != startsAt); - } - else if (curChar < 128) - { - int64_t l = (int64_t)1 << (curChar & 077); - do - { - switch (jjstateSet[--i]) - { - case 0: - case 6: - if ((0xdfffffffffffffffLL & l) == 0) - break; - if (kind > 33) - kind = 33; - jjCheckNAdd(6); - break; - case 2: - jjAddStates(16, 18); - break; - case 4: - if (curChar == 92) - jjstateSet[jjnewStateCnt++] = 3; - break; - default: - break; + } while (i != startsAt); + } else if (curChar < 128) { + int64_t l = (int64_t)1 << (curChar & 077); + do { + switch (jjstateSet[--i]) { + case 0: + case 6: + if ((0xdfffffffffffffffLL & l) == 0) { + break; + } + if (kind > 33) { + kind = 33; + } + jjCheckNAdd(6); + break; + case 2: + jjAddStates(16, 18); + break; + case 4: + if (curChar == 92) { + jjstateSet[jjnewStateCnt++] = 3; } + break; + default: + break; } - while (i != startsAt); - } - else - { - int32_t hiByte = (int32_t)(curChar >> 8); - int32_t i1 = hiByte >> 6; - int64_t l1 = (int64_t)1 << (hiByte & 077); - int32_t i2 = (curChar & 0xff) >> 6; - int64_t l2 = (int64_t)1 << (curChar & 077); - do - { - switch (jjstateSet[--i]) - { - case 0: - if (jjCanMove_0(hiByte, i1, i2, l1, l2)) - { - if (kind > 7) - kind = 7; - } - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - { - if (kind > 33) - kind = 33; - jjCheckNAdd(6); - } - break; - case 2: - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - jjAddStates(16, 18); - break; - case 6: - if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) - break; - if (kind > 33) - kind = 33; - jjCheckNAdd(6); - break; - default: - break; + } while (i != startsAt); + } else { + int32_t hiByte = (int32_t)(curChar >> 8); + int32_t i1 = hiByte >> 6; + int64_t l1 = (int64_t)1 << (hiByte & 077); + int32_t i2 = (curChar & 0xff) >> 6; + int64_t l2 = (int64_t)1 << (curChar & 077); + do { + switch (jjstateSet[--i]) { + case 0: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) { + if (kind > 7) { + kind = 7; + } + } + if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { + if (kind > 33) { + kind = 33; + } + jjCheckNAdd(6); } + break; + case 2: + if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { + jjAddStates(16, 18); + } + break; + case 6: + if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) { + break; + } + if (kind > 33) { + kind = 33; + } + jjCheckNAdd(6); + break; + default: + break; } - while (i != startsAt); - } - if (kind != 0x7fffffff) - { - jjmatchedKind = kind; - jjmatchedPos = curPos; - kind = 0x7fffffff; - } - ++curPos; - i = jjnewStateCnt; - jjnewStateCnt = startsAt; - if (i == (startsAt = 7 - jjnewStateCnt)) - return curPos; - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - return curPos; - } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 7 - jjnewStateCnt)) { + return curPos; + } + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + return curPos; } } +} - int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_0() - { - return jjMoveNfa_0(0, 0); - } +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_0() { + return jjMoveNfa_0(0, 0); +} - int32_t QueryParserTokenManager::jjMoveNfa_0(int32_t startState, int32_t curPos) - { - int32_t startsAt = 0; - jjnewStateCnt = 3; - int32_t i = 1; - jjstateSet[0] = startState; - int32_t kind = 0x7fffffff; - while (true) - { - if (++jjround == 0x7fffffff) - ReInitRounds(); - if (curChar < 64) - { - int64_t l = (int64_t)1 << curChar; - do - { - switch (jjstateSet[--i]) - { - case 0: - if ((0x3ff000000000000LL & l) == 0) - break; - if (kind > 25) - kind = 25; - jjAddStates(19, 20); - break; - case 1: - if (curChar == 46) - jjCheckNAdd(2); - break; - case 2: - if ((0x3ff000000000000LL & l) == 0) - break; - if (kind > 25) - kind = 25; - jjCheckNAdd(2); - break; - default: - break; +int32_t QueryParserTokenManager::jjMoveNfa_0(int32_t startState, int32_t curPos) { + int32_t startsAt = 0; + jjnewStateCnt = 3; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + while (true) { + if (++jjround == 0x7fffffff) { + ReInitRounds(); + } + if (curChar < 64) { + int64_t l = (int64_t)1 << curChar; + do { + switch (jjstateSet[--i]) { + case 0: + if ((0x3ff000000000000LL & l) == 0) { + break; } + if (kind > 25) { + kind = 25; + } + jjAddStates(19, 20); + break; + case 1: + if (curChar == 46) { + jjCheckNAdd(2); + } + break; + case 2: + if ((0x3ff000000000000LL & l) == 0) { + break; + } + if (kind > 25) { + kind = 25; + } + jjCheckNAdd(2); + break; + default: + break; } - while (i != startsAt); - } - else if (curChar < 128) - { - int64_t l = (int64_t)1 << (curChar & 077); - do - { - jjstateSet[--i]; - } - while (i != startsAt); - } - else - { - int32_t hiByte = (int32_t)(curChar >> 8); - int32_t i1 = hiByte >> 6; - int64_t l1 = (int64_t)1 << (hiByte & 077); - int32_t i2 = (curChar & 0xff) >> 6; - int64_t l2 = (int64_t)1 << (curChar & 077); - do - { - jjstateSet[--i]; - } - while (i != startsAt); - } - if (kind != 0x7fffffff) - { - jjmatchedKind = kind; - jjmatchedPos = curPos; - kind = 0x7fffffff; - } - ++curPos; - i = jjnewStateCnt; - jjnewStateCnt = startsAt; - if (i == (startsAt = 3 - jjnewStateCnt)) - return curPos; - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - return curPos; - } + } while (i != startsAt); + } else if (curChar < 128) { + int64_t l = (int64_t)1 << (curChar & 077); + do { + jjstateSet[--i]; + } while (i != startsAt); + } else { + int32_t hiByte = (int32_t)(curChar >> 8); + int32_t i1 = hiByte >> 6; + int64_t l1 = (int64_t)1 << (hiByte & 077); + int32_t i2 = (curChar & 0xff) >> 6; + int64_t l2 = (int64_t)1 << (curChar & 077); + do { + jjstateSet[--i]; + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 3 - jjnewStateCnt)) { + return curPos; + } + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + return curPos; } } +} - int32_t QueryParserTokenManager::jjStopStringLiteralDfa_2(int32_t pos, int64_t active0) - { - switch (pos) - { - case 0: - if ((active0 & 0x4000000LL) != 0) - { - jjmatchedKind = 29; - return 6; - } - return -1; - default: - return -1; +int32_t QueryParserTokenManager::jjStopStringLiteralDfa_2(int32_t pos, int64_t active0) { + switch (pos) { + case 0: + if ((active0 & 0x4000000LL) != 0) { + jjmatchedKind = 29; + return 6; } + return -1; + default: + return -1; } +} - int32_t QueryParserTokenManager::jjStartNfa_2(int32_t pos, int64_t active0) - { - return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); - } +int32_t QueryParserTokenManager::jjStartNfa_2(int32_t pos, int64_t active0) { + return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); +} - int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_2() - { - switch (curChar) - { - case 84: - return jjMoveStringLiteralDfa1_2(0x4000000LL); - case 93: - return jjStopAtPos(0, 27); - default: - return jjMoveNfa_2(0, 0); - } +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_2() { + switch (curChar) { + case 84: + return jjMoveStringLiteralDfa1_2(0x4000000LL); + case 93: + return jjStopAtPos(0, 27); + default: + return jjMoveNfa_2(0, 0); } +} - int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_2(int64_t active0) - { - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - jjStopStringLiteralDfa_2(0, active0); - return 1; - } - switch (curChar) - { - case 79: - if ((active0 & 0x4000000LL) != 0) - return jjStartNfaWithStates_2(1, 26, 6); - break; - default: - break; +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_2(int64_t active0) { + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + jjStopStringLiteralDfa_2(0, active0); + return 1; + } + switch (curChar) { + case 79: + if ((active0 & 0x4000000LL) != 0) { + return jjStartNfaWithStates_2(1, 26, 6); } - return jjStartNfa_2(0, active0); + break; + default: + break; } + return jjStartNfa_2(0, active0); +} - int32_t QueryParserTokenManager::jjStartNfaWithStates_2(int32_t pos, int32_t kind, int32_t state) - { - jjmatchedKind = kind; - jjmatchedPos = pos; - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - return pos + 1; - } - return jjMoveNfa_2(state, pos + 1); +int32_t QueryParserTokenManager::jjStartNfaWithStates_2(int32_t pos, int32_t kind, int32_t state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + return pos + 1; } + return jjMoveNfa_2(state, pos + 1); +} - int32_t QueryParserTokenManager::jjMoveNfa_2(int32_t startState, int32_t curPos) - { - int32_t startsAt = 0; - jjnewStateCnt = 7; - int32_t i = 1; - jjstateSet[0] = startState; - int32_t kind = 0x7fffffff; - while (true) - { - if (++jjround == 0x7fffffff) - ReInitRounds(); - if (curChar < 64) - { - int64_t l = (int64_t)1 << curChar; - do - { - switch (jjstateSet[--i]) - { - case 0: - if ((0xfffffffeffffffffLL & l) != 0) - { - if (kind > 29) - kind = 29; - jjCheckNAdd(6); - } - if ((0x100002600LL & l) != 0) - { - if (kind > 7) - kind = 7; - } - else if (curChar == 34) - jjCheckNAddTwoStates(2, 4); - break; - case 1: - if (curChar == 34) - jjCheckNAddTwoStates(2, 4); - break; - case 2: - if ((0xfffffffbffffffffLL & l) != 0) - jjCheckNAddStates(16, 18); - break; - case 3: - if (curChar == 34) - jjCheckNAddStates(16, 18); - break; - case 5: - if (curChar == 34 && kind > 28) - kind = 28; - break; - case 6: - if ((0xfffffffeffffffffLL & l) == 0) - break; - if (kind > 29) - kind = 29; - jjCheckNAdd(6); - break; - default: - break; +int32_t QueryParserTokenManager::jjMoveNfa_2(int32_t startState, int32_t curPos) { + int32_t startsAt = 0; + jjnewStateCnt = 7; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + while (true) { + if (++jjround == 0x7fffffff) { + ReInitRounds(); + } + if (curChar < 64) { + int64_t l = (int64_t)1 << curChar; + do { + switch (jjstateSet[--i]) { + case 0: + if ((0xfffffffeffffffffLL & l) != 0) { + if (kind > 29) { + kind = 29; + } + jjCheckNAdd(6); + } + if ((0x100002600LL & l) != 0) { + if (kind > 7) { + kind = 7; + } + } else if (curChar == 34) { + jjCheckNAddTwoStates(2, 4); + } + break; + case 1: + if (curChar == 34) { + jjCheckNAddTwoStates(2, 4); + } + break; + case 2: + if ((0xfffffffbffffffffLL & l) != 0) { + jjCheckNAddStates(16, 18); + } + break; + case 3: + if (curChar == 34) { + jjCheckNAddStates(16, 18); } + break; + case 5: + if (curChar == 34 && kind > 28) { + kind = 28; + } + break; + case 6: + if ((0xfffffffeffffffffLL & l) == 0) { + break; + } + if (kind > 29) { + kind = 29; + } + jjCheckNAdd(6); + break; + default: + break; } - while (i != startsAt); - } - else if (curChar < 128) - { - int64_t l = (int64_t)1 << (curChar & 077); - do - { - switch (jjstateSet[--i]) - { - case 0: - case 6: - if ((0xffffffffdfffffffLL & l) == 0) - break; - if (kind > 29) - kind = 29; - jjCheckNAdd(6); - break; - case 2: - jjAddStates(16, 18); - break; - case 4: - if (curChar == 92) - jjstateSet[jjnewStateCnt++] = 3; - break; - default: - break; + } while (i != startsAt); + } else if (curChar < 128) { + int64_t l = (int64_t)1 << (curChar & 077); + do { + switch (jjstateSet[--i]) { + case 0: + case 6: + if ((0xffffffffdfffffffLL & l) == 0) { + break; + } + if (kind > 29) { + kind = 29; } + jjCheckNAdd(6); + break; + case 2: + jjAddStates(16, 18); + break; + case 4: + if (curChar == 92) { + jjstateSet[jjnewStateCnt++] = 3; + } + break; + default: + break; } - while (i != startsAt); - } - else - { - int32_t hiByte = (int32_t)(curChar >> 8); - int32_t i1 = hiByte >> 6; - int64_t l1 = (int64_t)1 << (hiByte & 077); - int32_t i2 = (curChar & 0xff) >> 6; - int64_t l2 = (int64_t)1 << (curChar & 077); - do - { - switch (jjstateSet[--i]) - { - case 0: - if (jjCanMove_0(hiByte, i1, i2, l1, l2)) - { - if (kind > 7) - kind = 7; - } - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - { - if (kind > 29) - kind = 29; - jjCheckNAdd(6); - } - break; - case 2: - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - jjAddStates(16, 18); - break; - case 6: - if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) - break; - if (kind > 29) - kind = 29; - jjCheckNAdd(6); - break; - default: - break; + } while (i != startsAt); + } else { + int32_t hiByte = (int32_t)(curChar >> 8); + int32_t i1 = hiByte >> 6; + int64_t l1 = (int64_t)1 << (hiByte & 077); + int32_t i2 = (curChar & 0xff) >> 6; + int64_t l2 = (int64_t)1 << (curChar & 077); + do { + switch (jjstateSet[--i]) { + case 0: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) { + if (kind > 7) { + kind = 7; + } } + if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { + if (kind > 29) { + kind = 29; + } + jjCheckNAdd(6); + } + break; + case 2: + if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { + jjAddStates(16, 18); + } + break; + case 6: + if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) { + break; + } + if (kind > 29) { + kind = 29; + } + jjCheckNAdd(6); + break; + default: + break; } - while (i != startsAt); - } - if (kind != 0x7fffffff) - { - jjmatchedKind = kind; - jjmatchedPos = curPos; - kind = 0x7fffffff; - } - ++curPos; - i = jjnewStateCnt; - jjnewStateCnt = startsAt; - if (i == (startsAt = 7 - jjnewStateCnt)) - return curPos; - try - { - curChar = input_stream->readChar(); - } - catch (IOException&) - { - return curPos; - } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + i = jjnewStateCnt; + jjnewStateCnt = startsAt; + if (i == (startsAt = 7 - jjnewStateCnt)) { + return curPos; + } + try { + curChar = input_stream->readChar(); + } catch (IOException&) { + return curPos; } } +} - bool QueryParserTokenManager::jjCanMove_0(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) - { - switch (hiByte) - { - case 48: - return ((jjbitVec0[i2] & l2) != 0); - default: - return false; - } +bool QueryParserTokenManager::jjCanMove_0(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) { + switch (hiByte) { + case 48: + return ((jjbitVec0[i2] & l2) != 0); + default: + return false; } +} - bool QueryParserTokenManager::jjCanMove_1(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) - { - switch (hiByte) - { - case 0: - return ((jjbitVec3[i2] & l2) != 0); - default: - if ((jjbitVec1[i1] & l1) != 0) - return true; - return false; +bool QueryParserTokenManager::jjCanMove_1(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) { + switch (hiByte) { + case 0: + return ((jjbitVec3[i2] & l2) != 0); + default: + if ((jjbitVec1[i1] & l1) != 0) { + return true; } + return false; } +} - bool QueryParserTokenManager::jjCanMove_2(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) - { - switch (hiByte) - { - case 0: - return ((jjbitVec3[i2] & l2) != 0); - case 48: - return ((jjbitVec1[i2] & l2) != 0); - default: - if ((jjbitVec4[i1] & l1) != 0) - return true; - return false; +bool QueryParserTokenManager::jjCanMove_2(int32_t hiByte, int32_t i1, int32_t i2, int64_t l1, int64_t l2) { + switch (hiByte) { + case 0: + return ((jjbitVec3[i2] & l2) != 0); + case 48: + return ((jjbitVec1[i2] & l2) != 0); + default: + if ((jjbitVec4[i1] & l1) != 0) { + return true; } + return false; } +} - void QueryParserTokenManager::ReInit(const QueryParserCharStreamPtr& stream) - { - jjmatchedPos = 0; - jjnewStateCnt = 0; - curLexState = defaultLexState; - input_stream = stream; - ReInitRounds(); - } +void QueryParserTokenManager::ReInit(const QueryParserCharStreamPtr& stream) { + jjmatchedPos = 0; + jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} - void QueryParserTokenManager::ReInitRounds() - { - jjround = 0x80000001; - for (int32_t i = 36; i-- > 0;) - jjrounds[i] = 0x80000000; +void QueryParserTokenManager::ReInitRounds() { + jjround = 0x80000001; + for (int32_t i = 36; i-- > 0;) { + jjrounds[i] = 0x80000000; } +} - void QueryParserTokenManager::ReInit(const QueryParserCharStreamPtr& stream, int32_t lexState) - { - ReInit(stream); - SwitchTo(lexState); - } +void QueryParserTokenManager::ReInit(const QueryParserCharStreamPtr& stream, int32_t lexState) { + ReInit(stream); + SwitchTo(lexState); +} - void QueryParserTokenManager::SwitchTo(int32_t lexState) - { - if (lexState >= 4 || lexState < 0) - { - boost::throw_exception(QueryParserError(L"Error: Ignoring invalid lexical state : " + - StringUtils::toString(lexState) + L". State unchanged.")); - } - else - curLexState = lexState; +void QueryParserTokenManager::SwitchTo(int32_t lexState) { + if (lexState >= 4 || lexState < 0) { + boost::throw_exception(QueryParserError(L"Error: Ignoring invalid lexical state : " + + StringUtils::toString(lexState) + L". State unchanged.")); + } else { + curLexState = lexState; } +} - QueryParserTokenPtr QueryParserTokenManager::jjFillToken() - { - String im(jjstrLiteralImages[jjmatchedKind]); - String curTokenImage(im.empty() ? input_stream->GetImage() : im); - int32_t beginLine = input_stream->getBeginLine(); - int32_t beginColumn = input_stream->getBeginColumn(); - int32_t endLine = input_stream->getEndLine(); - int32_t endColumn = input_stream->getEndColumn(); - QueryParserTokenPtr t(QueryParserToken::newToken(jjmatchedKind, curTokenImage)); +QueryParserTokenPtr QueryParserTokenManager::jjFillToken() { + String im(jjstrLiteralImages[jjmatchedKind]); + String curTokenImage(im.empty() ? input_stream->GetImage() : im); + int32_t beginLine = input_stream->getBeginLine(); + int32_t beginColumn = input_stream->getBeginColumn(); + int32_t endLine = input_stream->getEndLine(); + int32_t endColumn = input_stream->getEndColumn(); + QueryParserTokenPtr t(QueryParserToken::newToken(jjmatchedKind, curTokenImage)); - t->beginLine = beginLine; - t->endLine = endLine; - t->beginColumn = beginColumn; - t->endColumn = endColumn; + t->beginLine = beginLine; + t->endLine = endLine; + t->beginColumn = beginColumn; + t->endColumn = endColumn; - return t; - } + return t; +} - QueryParserTokenPtr QueryParserTokenManager::getNextToken() - { - QueryParserTokenPtr matchedToken; - int32_t curPos = 0; +QueryParserTokenPtr QueryParserTokenManager::getNextToken() { + QueryParserTokenPtr matchedToken; + int32_t curPos = 0; - while (true) - { - try - { - curChar = input_stream->BeginToken(); - } - catch (IOException&) - { - jjmatchedKind = 0; - matchedToken = jjFillToken(); - return matchedToken; - } + while (true) { + try { + curChar = input_stream->BeginToken(); + } catch (IOException&) { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } - switch (curLexState) - { - case 0: - jjmatchedKind = 0x7fffffff; - jjmatchedPos = 0; - curPos = jjMoveStringLiteralDfa0_0(); - break; - case 1: - jjmatchedKind = 0x7fffffff; - jjmatchedPos = 0; - curPos = jjMoveStringLiteralDfa0_1(); - break; - case 2: - jjmatchedKind = 0x7fffffff; - jjmatchedPos = 0; - curPos = jjMoveStringLiteralDfa0_2(); - break; - case 3: - jjmatchedKind = 0x7fffffff; - jjmatchedPos = 0; - curPos = jjMoveStringLiteralDfa0_3(); - break; - } + switch (curLexState) { + case 0: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + break; + case 1: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_1(); + break; + case 2: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_2(); + break; + case 3: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_3(); + break; + } - if (jjmatchedKind != 0x7fffffff) - { - if (jjmatchedPos + 1 < curPos) - input_stream->backup(curPos - jjmatchedPos - 1); - if ((jjtoToken[jjmatchedKind >> 6] & ((int64_t)1 << (jjmatchedKind & 077))) != 0) - { - matchedToken = jjFillToken(); - if (jjnewLexState[jjmatchedKind] != -1) - curLexState = jjnewLexState[jjmatchedKind]; - return matchedToken; - } - else - { - if (jjnewLexState[jjmatchedKind] != -1) - curLexState = jjnewLexState[jjmatchedKind]; - continue; - } - } - int32_t error_line = input_stream->getEndLine(); - int32_t error_column = input_stream->getEndColumn(); - String error_after; - bool EOFSeen = false; - try - { - input_stream->readChar(); - input_stream->backup(1); + if (jjmatchedKind != 0x7fffffff) { + if (jjmatchedPos + 1 < curPos) { + input_stream->backup(curPos - jjmatchedPos - 1); } - catch (IOException&) - { - EOFSeen = true; - error_after = curPos <= 1 ? L"" : input_stream->GetImage(); - if (curChar == L'\n' || curChar == L'\r') - { - ++error_line; - error_column = 0; + if ((jjtoToken[jjmatchedKind >> 6] & ((int64_t)1 << (jjmatchedKind & 077))) != 0) { + matchedToken = jjFillToken(); + if (jjnewLexState[jjmatchedKind] != -1) { + curLexState = jjnewLexState[jjmatchedKind]; } - else - ++error_column; + return matchedToken; + } else { + if (jjnewLexState[jjmatchedKind] != -1) { + curLexState = jjnewLexState[jjmatchedKind]; + } + continue; } - - if (!EOFSeen) - { - input_stream->backup(1); - error_after = curPos <= 1 ? L"" : input_stream->GetImage(); + } + int32_t error_line = input_stream->getEndLine(); + int32_t error_column = input_stream->getEndColumn(); + String error_after; + bool EOFSeen = false; + try { + input_stream->readChar(); + input_stream->backup(1); + } catch (IOException&) { + EOFSeen = true; + error_after = curPos <= 1 ? L"" : input_stream->GetImage(); + if (curChar == L'\n' || curChar == L'\r') { + ++error_line; + error_column = 0; + } else { + ++error_column; } - - boost::throw_exception(QueryParserError(QueryParseError::lexicalError(EOFSeen, curLexState, error_line, error_column, error_after, curChar))); } - } - void QueryParserTokenManager::jjCheckNAdd(int32_t state) - { - if (jjrounds[state] != jjround) - { - jjstateSet[jjnewStateCnt++] = state; - jjrounds[state] = jjround; + if (!EOFSeen) { + input_stream->backup(1); + error_after = curPos <= 1 ? L"" : input_stream->GetImage(); } - } - void QueryParserTokenManager::jjAddStates(int32_t start, int32_t end) - { - do - { - jjstateSet[jjnewStateCnt++] = jjnextStates[start]; - } - while (start++ != end); + boost::throw_exception(QueryParserError(QueryParseError::lexicalError(EOFSeen, curLexState, error_line, error_column, error_after, curChar))); } +} - void QueryParserTokenManager::jjCheckNAddTwoStates(int32_t state1, int32_t state2) - { - jjCheckNAdd(state1); - jjCheckNAdd(state2); +void QueryParserTokenManager::jjCheckNAdd(int32_t state) { + if (jjrounds[state] != jjround) { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; } +} + +void QueryParserTokenManager::jjAddStates(int32_t start, int32_t end) { + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} + +void QueryParserTokenManager::jjCheckNAddTwoStates(int32_t state1, int32_t state2) { + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +void QueryParserTokenManager::jjCheckNAddStates(int32_t start, int32_t end) { + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} - void QueryParserTokenManager::jjCheckNAddStates(int32_t start, int32_t end) - { - do - { - jjCheckNAdd(jjnextStates[start]); - } - while (start++ != end); - } } diff --git a/src/core/search/BooleanClause.cpp b/src/core/search/BooleanClause.cpp index 2f4a4703..e47c4a8b 100644 --- a/src/core/search/BooleanClause.cpp +++ b/src/core/search/BooleanClause.cpp @@ -8,71 +8,61 @@ #include "BooleanClause.h" #include "Query.h" -namespace Lucene -{ - BooleanClause::BooleanClause(const QueryPtr& query, Occur occur) - { - this->query = query; - this->occur = occur; - } +namespace Lucene { - BooleanClause::~BooleanClause() - { - } +BooleanClause::BooleanClause(const QueryPtr& query, Occur occur) { + this->query = query; + this->occur = occur; +} - BooleanClause::Occur BooleanClause::getOccur() - { - return occur; - } +BooleanClause::~BooleanClause() { +} - void BooleanClause::setOccur(BooleanClause::Occur occur) - { - this->occur = occur; - } +BooleanClause::Occur BooleanClause::getOccur() { + return occur; +} - QueryPtr BooleanClause::getQuery() - { - return query; - } +void BooleanClause::setOccur(BooleanClause::Occur occur) { + this->occur = occur; +} - void BooleanClause::setQuery(const QueryPtr& query) - { - this->query = query; - } +QueryPtr BooleanClause::getQuery() { + return query; +} - bool BooleanClause::isProhibited() - { - return (occur == MUST_NOT); - } +void BooleanClause::setQuery(const QueryPtr& query) { + this->query = query; +} - bool BooleanClause::isRequired() - { - return (occur == MUST); - } +bool BooleanClause::isProhibited() { + return (occur == MUST_NOT); +} - bool BooleanClause::equals(const LuceneObjectPtr& other) - { - BooleanClausePtr otherBooleanClause(boost::dynamic_pointer_cast(other)); - if (!otherBooleanClause) - return false; - return (this->query->equals(otherBooleanClause->query) && this->occur == otherBooleanClause->occur); - } +bool BooleanClause::isRequired() { + return (occur == MUST); +} - int32_t BooleanClause::hashCode() - { - return query->hashCode() ^ (occur == MUST ? 1 : 0) ^ (occur == MUST_NOT ? 2 : 0); +bool BooleanClause::equals(const LuceneObjectPtr& other) { + BooleanClausePtr otherBooleanClause(boost::dynamic_pointer_cast(other)); + if (!otherBooleanClause) { + return false; } + return (this->query->equals(otherBooleanClause->query) && this->occur == otherBooleanClause->occur); +} + +int32_t BooleanClause::hashCode() { + return query->hashCode() ^ (occur == MUST ? 1 : 0) ^ (occur == MUST_NOT ? 2 : 0); +} - String BooleanClause::toString() - { - switch (occur) - { - case MUST: - return L"+" + query->toString(); - case MUST_NOT: - return L"-" + query->toString(); - default: - return query->toString(); - } +String BooleanClause::toString() { + switch (occur) { + case MUST: + return L"+" + query->toString(); + case MUST_NOT: + return L"-" + query->toString(); + default: + return query->toString(); } } + +} diff --git a/src/core/search/BooleanQuery.cpp b/src/core/search/BooleanQuery.cpp index 6a59e9e9..1376d24b 100644 --- a/src/core/search/BooleanQuery.cpp +++ b/src/core/search/BooleanQuery.cpp @@ -13,403 +13,364 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - int32_t BooleanQuery::maxClauseCount = 1024; - - BooleanQuery::BooleanQuery(bool disableCoord) - { - this->disableCoord = disableCoord; - this->clauses = Collection::newInstance(); - this->minNrShouldMatch = 0; - } +namespace Lucene { - BooleanQuery::~BooleanQuery() - { - } +int32_t BooleanQuery::maxClauseCount = 1024; - int32_t BooleanQuery::getMaxClauseCount() - { - return maxClauseCount; - } +BooleanQuery::BooleanQuery(bool disableCoord) { + this->disableCoord = disableCoord; + this->clauses = Collection::newInstance(); + this->minNrShouldMatch = 0; +} - void BooleanQuery::setMaxClauseCount(int32_t maxClauseCount) - { - if (maxClauseCount < 1) - boost::throw_exception(IllegalArgumentException(L"maxClauseCount must be >= 1")); - BooleanQuery::maxClauseCount = maxClauseCount; - } +BooleanQuery::~BooleanQuery() { +} - bool BooleanQuery::isCoordDisabled() - { - return disableCoord; - } +int32_t BooleanQuery::getMaxClauseCount() { + return maxClauseCount; +} - SimilarityPtr BooleanQuery::getSimilarity(const SearcherPtr& searcher) - { - SimilarityPtr result(Query::getSimilarity(searcher)); - if (disableCoord) // disable coord as requested - result = newLucene(result); - return result; +void BooleanQuery::setMaxClauseCount(int32_t maxClauseCount) { + if (maxClauseCount < 1) { + boost::throw_exception(IllegalArgumentException(L"maxClauseCount must be >= 1")); } + BooleanQuery::maxClauseCount = maxClauseCount; +} - void BooleanQuery::setMinimumNumberShouldMatch(int32_t min) - { - this->minNrShouldMatch = min; - } +bool BooleanQuery::isCoordDisabled() { + return disableCoord; +} - int32_t BooleanQuery::getMinimumNumberShouldMatch() - { - return minNrShouldMatch; +SimilarityPtr BooleanQuery::getSimilarity(const SearcherPtr& searcher) { + SimilarityPtr result(Query::getSimilarity(searcher)); + if (disableCoord) { // disable coord as requested + result = newLucene(result); } + return result; +} - void BooleanQuery::add(const QueryPtr& query, BooleanClause::Occur occur) - { - add(newLucene(query, occur)); - } +void BooleanQuery::setMinimumNumberShouldMatch(int32_t min) { + this->minNrShouldMatch = min; +} - void BooleanQuery::add(const BooleanClausePtr& clause) - { - if (clauses.size() >= maxClauseCount) - boost::throw_exception(TooManyClausesException(L"maxClauseCount is set to " + StringUtils::toString(maxClauseCount))); - clauses.add(clause); - } +int32_t BooleanQuery::getMinimumNumberShouldMatch() { + return minNrShouldMatch; +} - Collection BooleanQuery::getClauses() - { - return clauses; - } +void BooleanQuery::add(const QueryPtr& query, BooleanClause::Occur occur) { + add(newLucene(query, occur)); +} - Collection::iterator BooleanQuery::begin() - { - return clauses.begin(); +void BooleanQuery::add(const BooleanClausePtr& clause) { + if (clauses.size() >= maxClauseCount) { + boost::throw_exception(TooManyClausesException(L"maxClauseCount is set to " + StringUtils::toString(maxClauseCount))); } + clauses.add(clause); +} - Collection::iterator BooleanQuery::end() - { - return clauses.end(); - } +Collection BooleanQuery::getClauses() { + return clauses; +} - WeightPtr BooleanQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +Collection::iterator BooleanQuery::begin() { + return clauses.begin(); +} - QueryPtr BooleanQuery::rewrite(const IndexReaderPtr& reader) - { - if (minNrShouldMatch == 0 && clauses.size() == 1) // optimize 1-clause queries - { - BooleanClausePtr c(clauses[0]); - if (!c->isProhibited()) // just return clause - { - QueryPtr query(c->getQuery()->rewrite(reader)); // rewrite first - - if (getBoost() != 1.0) // incorporate boost - { - if (query == c->getQuery()) // if rewrite was no-op - query = boost::dynamic_pointer_cast(query->clone()); // then clone before boost - query->setBoost(getBoost() * query->getBoost()); - } +Collection::iterator BooleanQuery::end() { + return clauses.end(); +} + +WeightPtr BooleanQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} + +QueryPtr BooleanQuery::rewrite(const IndexReaderPtr& reader) { + if (minNrShouldMatch == 0 && clauses.size() == 1) { // optimize 1-clause queries + BooleanClausePtr c(clauses[0]); + if (!c->isProhibited()) { // just return clause + QueryPtr query(c->getQuery()->rewrite(reader)); // rewrite first - return query; + if (getBoost() != 1.0) { // incorporate boost + if (query == c->getQuery()) { // if rewrite was no-op + query = boost::dynamic_pointer_cast(query->clone()); // then clone before boost + } + query->setBoost(getBoost() * query->getBoost()); } + + return query; } + } - BooleanQueryPtr clone; // recursively rewrite - for (int32_t i = 0; i < clauses.size(); ++i) - { - BooleanClausePtr c(clauses[i]); - QueryPtr query(c->getQuery()->rewrite(reader)); - if (query != c->getQuery()) // clause rewrote: must clone - { - if (!clone) - clone = boost::dynamic_pointer_cast(this->clone()); - clone->clauses[i] = newLucene(query, c->getOccur()); + BooleanQueryPtr clone; // recursively rewrite + for (int32_t i = 0; i < clauses.size(); ++i) { + BooleanClausePtr c(clauses[i]); + QueryPtr query(c->getQuery()->rewrite(reader)); + if (query != c->getQuery()) { // clause rewrote: must clone + if (!clone) { + clone = boost::dynamic_pointer_cast(this->clone()); } + clone->clauses[i] = newLucene(query, c->getOccur()); } - - if (clone) - return clone; // some clauses rewrote - else - return shared_from_this(); // no clauses rewrote } - void BooleanQuery::extractTerms(SetTerm terms) - { - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - (*clause)->getQuery()->extractTerms(terms); + if (clone) { + return clone; // some clauses rewrote + } else { + return shared_from_this(); // no clauses rewrote } +} - LuceneObjectPtr BooleanQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); - BooleanQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->disableCoord = disableCoord; - cloneQuery->minNrShouldMatch = minNrShouldMatch; - cloneQuery->clauses = Collection::newInstance(clauses.begin(), clauses.end()); - return cloneQuery; +void BooleanQuery::extractTerms(SetTerm terms) { + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + (*clause)->getQuery()->extractTerms(terms); } +} - String BooleanQuery::toString(const String& field) - { - String buffer; - bool needParens = (getBoost() != 1.0 || getMinimumNumberShouldMatch() > 0); - if (needParens) - buffer += L"("; - - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - { - if (clause != clauses.begin()) - buffer += L" "; - - if ((*clause)->isProhibited()) - buffer += L"-"; - else if ((*clause)->isRequired()) - buffer += L"+"; - - QueryPtr subQuery((*clause)->getQuery()); - if (subQuery) - { - if (boost::dynamic_pointer_cast(subQuery)) // wrap sub-bools in parens - { - buffer += L"("; - buffer += subQuery->toString(field); - buffer += L")"; - } - else - buffer += subQuery->toString(field); - } - else - buffer += L"null"; - } +LuceneObjectPtr BooleanQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); + BooleanQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->disableCoord = disableCoord; + cloneQuery->minNrShouldMatch = minNrShouldMatch; + cloneQuery->clauses = Collection::newInstance(clauses.begin(), clauses.end()); + return cloneQuery; +} - if (needParens) - buffer += L")"; +String BooleanQuery::toString(const String& field) { + String buffer; + bool needParens = (getBoost() != 1.0 || getMinimumNumberShouldMatch() > 0); + if (needParens) { + buffer += L"("; + } - if (getMinimumNumberShouldMatch() > 0) - { - buffer += L"~"; - buffer += StringUtils::toString(getMinimumNumberShouldMatch()); + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + if (clause != clauses.begin()) { + buffer += L" "; } - if (getBoost() != 1.0) - buffer += boostString(); + if ((*clause)->isProhibited()) { + buffer += L"-"; + } else if ((*clause)->isRequired()) { + buffer += L"+"; + } - return buffer; + QueryPtr subQuery((*clause)->getQuery()); + if (subQuery) { + if (boost::dynamic_pointer_cast(subQuery)) { // wrap sub-bools in parens + buffer += L"("; + buffer += subQuery->toString(field); + buffer += L")"; + } else { + buffer += subQuery->toString(field); + } + } else { + buffer += L"null"; + } } - bool BooleanQuery::equals(const LuceneObjectPtr& other) - { - BooleanQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - return (getBoost() == otherQuery->getBoost() && - clauses.equals(otherQuery->clauses, luceneEquals()) && - getMinimumNumberShouldMatch() == otherQuery->getMinimumNumberShouldMatch() && - disableCoord == otherQuery->disableCoord); + if (needParens) { + buffer += L")"; } - int32_t BooleanQuery::hashCode() - { - return MiscUtils::doubleToIntBits(getBoost()) ^ MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene) + - getMinimumNumberShouldMatch() + (disableCoord ? 17 : 0); + if (getMinimumNumberShouldMatch() > 0) { + buffer += L"~"; + buffer += StringUtils::toString(getMinimumNumberShouldMatch()); } - BooleanWeight::BooleanWeight(const BooleanQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = query->getSimilarity(searcher); - weights = Collection::newInstance(); - for (Collection::iterator clause = query->clauses.begin(); clause != query->clauses.end(); ++clause) - weights.add((*clause)->getQuery()->createWeight(searcher)); + if (getBoost() != 1.0) { + buffer += boostString(); } - BooleanWeight::~BooleanWeight() - { - } + return buffer; +} - QueryPtr BooleanWeight::getQuery() - { - return query; +bool BooleanQuery::equals(const LuceneObjectPtr& other) { + BooleanQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } + return (getBoost() == otherQuery->getBoost() && + clauses.equals(otherQuery->clauses, luceneEquals()) && + getMinimumNumberShouldMatch() == otherQuery->getMinimumNumberShouldMatch() && + disableCoord == otherQuery->disableCoord); +} - double BooleanWeight::getValue() - { - return query->getBoost(); +int32_t BooleanQuery::hashCode() { + return MiscUtils::doubleToIntBits(getBoost()) ^ MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene) + + getMinimumNumberShouldMatch() + (disableCoord ? 17 : 0); +} + +BooleanWeight::BooleanWeight(const BooleanQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = query->getSimilarity(searcher); + weights = Collection::newInstance(); + for (Collection::iterator clause = query->clauses.begin(); clause != query->clauses.end(); ++clause) { + weights.add((*clause)->getQuery()->createWeight(searcher)); } +} - double BooleanWeight::sumOfSquaredWeights() - { - double sum = 0.0; - for (int32_t i = 0; i < weights.size(); ++i) - { - // call sumOfSquaredWeights for all clauses in case of side effects - double s = weights[i]->sumOfSquaredWeights(); // sum sub weights - if (!query->clauses[i]->isProhibited()) - { - // only add to sum for non-prohibited clauses - sum += s; - } - } +BooleanWeight::~BooleanWeight() { +} - sum *= query->getBoost() * query->getBoost(); // boost each sub-weight +QueryPtr BooleanWeight::getQuery() { + return query; +} - return sum; - } +double BooleanWeight::getValue() { + return query->getBoost(); +} - void BooleanWeight::normalize(double norm) - { - norm *= query->getBoost(); // incorporate boost - for (Collection::iterator w = weights.begin(); w != weights.end(); ++w) - { - // normalize all clauses, (even if prohibited in case of side affects) - (*w)->normalize(norm); +double BooleanWeight::sumOfSquaredWeights() { + double sum = 0.0; + for (int32_t i = 0; i < weights.size(); ++i) { + // call sumOfSquaredWeights for all clauses in case of side effects + double s = weights[i]->sumOfSquaredWeights(); // sum sub weights + if (!query->clauses[i]->isProhibited()) { + // only add to sum for non-prohibited clauses + sum += s; } } - ExplanationPtr BooleanWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - int32_t minShouldMatch = query->getMinimumNumberShouldMatch(); - ComplexExplanationPtr sumExpl(newLucene()); - sumExpl->setDescription(L"sum of:"); - int32_t coord = 0; - int32_t maxCoord = 0; - double sum = 0.0; - bool fail = false; - int32_t shouldMatchCount = 0; - Collection::iterator c = query->clauses.begin(); - for (Collection::iterator w = weights.begin(); w != weights.end(); ++w, ++c) - { - if (!(*w)->scorer(reader, true, true)) - continue; - ExplanationPtr e((*w)->explain(reader, doc)); - if (!(*c)->isProhibited()) - ++maxCoord; - if (e->isMatch()) - { - if (!(*c)->isProhibited()) - { - sumExpl->addDetail(e); - sum += e->getValue(); - ++coord; - } - else - { - ExplanationPtr r(newLucene(0.0, L"match on prohibited clause (" + (*c)->getQuery()->toString() + L")")); - r->addDetail(e); - sumExpl->addDetail(r); - fail = true; - } - if ((*c)->getOccur() == BooleanClause::SHOULD) - ++shouldMatchCount; - } - else if ((*c)->isRequired()) - { - ExplanationPtr r(newLucene(0.0, L"no match on required clause (" + (*c)->getQuery()->toString() + L")")); + sum *= query->getBoost() * query->getBoost(); // boost each sub-weight + + return sum; +} + +void BooleanWeight::normalize(double norm) { + norm *= query->getBoost(); // incorporate boost + for (Collection::iterator w = weights.begin(); w != weights.end(); ++w) { + // normalize all clauses, (even if prohibited in case of side affects) + (*w)->normalize(norm); + } +} + +ExplanationPtr BooleanWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + int32_t minShouldMatch = query->getMinimumNumberShouldMatch(); + ComplexExplanationPtr sumExpl(newLucene()); + sumExpl->setDescription(L"sum of:"); + int32_t coord = 0; + int32_t maxCoord = 0; + double sum = 0.0; + bool fail = false; + int32_t shouldMatchCount = 0; + Collection::iterator c = query->clauses.begin(); + for (Collection::iterator w = weights.begin(); w != weights.end(); ++w, ++c) { + if (!(*w)->scorer(reader, true, true)) { + continue; + } + ExplanationPtr e((*w)->explain(reader, doc)); + if (!(*c)->isProhibited()) { + ++maxCoord; + } + if (e->isMatch()) { + if (!(*c)->isProhibited()) { + sumExpl->addDetail(e); + sum += e->getValue(); + ++coord; + } else { + ExplanationPtr r(newLucene(0.0, L"match on prohibited clause (" + (*c)->getQuery()->toString() + L")")); r->addDetail(e); sumExpl->addDetail(r); fail = true; } + if ((*c)->getOccur() == BooleanClause::SHOULD) { + ++shouldMatchCount; + } + } else if ((*c)->isRequired()) { + ExplanationPtr r(newLucene(0.0, L"no match on required clause (" + (*c)->getQuery()->toString() + L")")); + r->addDetail(e); + sumExpl->addDetail(r); + fail = true; } - if (fail) - { - sumExpl->setMatch(false); - sumExpl->setValue(0.0); - sumExpl->setDescription(L"Failure to meet condition(s) of required/prohibited clause(s)"); - return sumExpl; - } - else if (shouldMatchCount < minShouldMatch) - { - sumExpl->setMatch(false); - sumExpl->setValue(0.0); - sumExpl->setDescription(L"Failure to match minimum number of optional clauses: " + StringUtils::toString(minShouldMatch)); - return sumExpl; - } - - sumExpl->setMatch(0 < coord); - sumExpl->setValue(sum); - double coordFactor = similarity->coord(coord, maxCoord); - if (coordFactor == 1.0) // coord is no-op - return sumExpl; // eliminate wrapper - else - { - ComplexExplanationPtr result(newLucene(sumExpl->isMatch(), sum * coordFactor, L"product of:")); - result->addDetail(sumExpl); - result->addDetail(newLucene(coordFactor, L"coord(" + StringUtils::toString(coord) + L"/" + StringUtils::toString(maxCoord) + L")")); - return result; - } } + if (fail) { + sumExpl->setMatch(false); + sumExpl->setValue(0.0); + sumExpl->setDescription(L"Failure to meet condition(s) of required/prohibited clause(s)"); + return sumExpl; + } else if (shouldMatchCount < minShouldMatch) { + sumExpl->setMatch(false); + sumExpl->setValue(0.0); + sumExpl->setDescription(L"Failure to match minimum number of optional clauses: " + StringUtils::toString(minShouldMatch)); + return sumExpl; + } + + sumExpl->setMatch(0 < coord); + sumExpl->setValue(sum); + double coordFactor = similarity->coord(coord, maxCoord); + if (coordFactor == 1.0) { // coord is no-op + return sumExpl; // eliminate wrapper + } else { + ComplexExplanationPtr result(newLucene(sumExpl->isMatch(), sum * coordFactor, L"product of:")); + result->addDetail(sumExpl); + result->addDetail(newLucene(coordFactor, L"coord(" + StringUtils::toString(coord) + L"/" + StringUtils::toString(maxCoord) + L")")); + return result; + } +} - ScorerPtr BooleanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - Collection required(Collection::newInstance()); - Collection prohibited(Collection::newInstance()); - Collection optional(Collection::newInstance()); - Collection::iterator c = query->clauses.begin(); - for (Collection::iterator w = weights.begin(); w != weights.end(); ++w, ++c) - { - ScorerPtr subScorer((*w)->scorer(reader, true, false)); - if (!subScorer) - { - if ((*c)->isRequired()) - return ScorerPtr(); +ScorerPtr BooleanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + Collection required(Collection::newInstance()); + Collection prohibited(Collection::newInstance()); + Collection optional(Collection::newInstance()); + Collection::iterator c = query->clauses.begin(); + for (Collection::iterator w = weights.begin(); w != weights.end(); ++w, ++c) { + ScorerPtr subScorer((*w)->scorer(reader, true, false)); + if (!subScorer) { + if ((*c)->isRequired()) { + return ScorerPtr(); } - else if ((*c)->isRequired()) - required.add(subScorer); - else if ((*c)->isProhibited()) - prohibited.add(subScorer); - else - optional.add(subScorer); - } - - // Check if we can return a BooleanScorer - if (!scoreDocsInOrder && topScorer && required.empty() && prohibited.size() < 32) - return newLucene(similarity, query->minNrShouldMatch, optional, prohibited); - - if (required.empty() && optional.empty()) - { - // no required and optional clauses. - return ScorerPtr(); - } - else if (optional.size() < query->minNrShouldMatch) - { - // either >1 req scorer, or there are 0 req scorers and at least 1 optional scorer. Therefore if there - // are not enough optional scorers no documents will be matched by the query - return ScorerPtr(); + } else if ((*c)->isRequired()) { + required.add(subScorer); + } else if ((*c)->isProhibited()) { + prohibited.add(subScorer); + } else { + optional.add(subScorer); } + } - // Return a BooleanScorer2 - return newLucene(similarity, query->minNrShouldMatch, required, prohibited, optional); + // Check if we can return a BooleanScorer + if (!scoreDocsInOrder && topScorer && required.empty() && prohibited.size() < 32) { + return newLucene(similarity, query->minNrShouldMatch, optional, prohibited); } - bool BooleanWeight::scoresDocsOutOfOrder() - { - int32_t numProhibited = 0; - for (Collection::iterator c = query->clauses.begin(); c != query->clauses.end(); ++c) - { - if ((*c)->isRequired()) - return false; // BS2 (in-order) will be used by scorer() - else if ((*c)->isProhibited()) - ++numProhibited; - } + if (required.empty() && optional.empty()) { + // no required and optional clauses. + return ScorerPtr(); + } else if (optional.size() < query->minNrShouldMatch) { + // either >1 req scorer, or there are 0 req scorers and at least 1 optional scorer. Therefore if there + // are not enough optional scorers no documents will be matched by the query + return ScorerPtr(); + } - if (numProhibited > 32) // cannot use BS - return false; + // Return a BooleanScorer2 + return newLucene(similarity, query->minNrShouldMatch, required, prohibited, optional); +} - // scorer() will return an out-of-order scorer if requested. - return true; +bool BooleanWeight::scoresDocsOutOfOrder() { + int32_t numProhibited = 0; + for (Collection::iterator c = query->clauses.begin(); c != query->clauses.end(); ++c) { + if ((*c)->isRequired()) { + return false; // BS2 (in-order) will be used by scorer() + } else if ((*c)->isProhibited()) { + ++numProhibited; + } } - SimilarityDisableCoord::SimilarityDisableCoord(const SimilarityPtr& delegee) : SimilarityDelegator(delegee) - { + if (numProhibited > 32) { // cannot use BS + return false; } - SimilarityDisableCoord::~SimilarityDisableCoord() - { - } + // scorer() will return an out-of-order scorer if requested. + return true; +} + +SimilarityDisableCoord::SimilarityDisableCoord(const SimilarityPtr& delegee) : SimilarityDelegator(delegee) { +} + +SimilarityDisableCoord::~SimilarityDisableCoord() { +} + +double SimilarityDisableCoord::coord(int32_t overlap, int32_t maxOverlap) { + return 1.0; // disable coord +} - double SimilarityDisableCoord::coord(int32_t overlap, int32_t maxOverlap) - { - return 1.0; // disable coord - } } diff --git a/src/core/search/BooleanScorer.cpp b/src/core/search/BooleanScorer.cpp index f545c241..6dea82c2 100644 --- a/src/core/search/BooleanScorer.cpp +++ b/src/core/search/BooleanScorer.cpp @@ -8,315 +8,270 @@ #include "BooleanScorer.h" #include "Similarity.h" -namespace Lucene -{ - BooleanScorer::BooleanScorer(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers) : Scorer(similarity) - { - this->bucketTable = newLucene(); - this->maxCoord = 1; - this->requiredMask = 0; - this->prohibitedMask = 0; - this->nextMask = 1; - this->minNrShouldMatch = minNrShouldMatch; - this->end = 0; - this->doc = -1; - - if (optionalScorers && !optionalScorers.empty()) - { - for (Collection::iterator scorer = optionalScorers.begin(); scorer != optionalScorers.end(); ++scorer) - { - ++maxCoord; - if ((*scorer)->nextDoc() != NO_MORE_DOCS) - scorers = newLucene(*scorer, false, false, bucketTable->newCollector(0), scorers); +namespace Lucene { + +BooleanScorer::BooleanScorer(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers) : Scorer(similarity) { + this->bucketTable = newLucene(); + this->maxCoord = 1; + this->requiredMask = 0; + this->prohibitedMask = 0; + this->nextMask = 1; + this->minNrShouldMatch = minNrShouldMatch; + this->end = 0; + this->doc = -1; + + if (optionalScorers && !optionalScorers.empty()) { + for (Collection::iterator scorer = optionalScorers.begin(); scorer != optionalScorers.end(); ++scorer) { + ++maxCoord; + if ((*scorer)->nextDoc() != NO_MORE_DOCS) { + scorers = newLucene(*scorer, false, false, bucketTable->newCollector(0), scorers); } } + } - if (prohibitedScorers && !prohibitedScorers.empty()) - { - for (Collection::iterator scorer = prohibitedScorers.begin(); scorer != prohibitedScorers.end(); ++scorer) - { - int32_t mask = nextMask; - nextMask = nextMask << 1; - prohibitedMask |= mask; // update prohibited mask - if ((*scorer)->nextDoc() != NO_MORE_DOCS) - scorers = newLucene(*scorer, false, true, bucketTable->newCollector(mask), scorers); + if (prohibitedScorers && !prohibitedScorers.empty()) { + for (Collection::iterator scorer = prohibitedScorers.begin(); scorer != prohibitedScorers.end(); ++scorer) { + int32_t mask = nextMask; + nextMask = nextMask << 1; + prohibitedMask |= mask; // update prohibited mask + if ((*scorer)->nextDoc() != NO_MORE_DOCS) { + scorers = newLucene(*scorer, false, true, bucketTable->newCollector(mask), scorers); } } - - coordFactors = Collection::newInstance(maxCoord); - SimilarityPtr sim(getSimilarity()); - for (int32_t i = 0; i < maxCoord; ++i) - coordFactors[i] = sim->coord(i, maxCoord - 1); } - BooleanScorer::~BooleanScorer() - { + coordFactors = Collection::newInstance(maxCoord); + SimilarityPtr sim(getSimilarity()); + for (int32_t i = 0; i < maxCoord; ++i) { + coordFactors[i] = sim->coord(i, maxCoord - 1); } +} + +BooleanScorer::~BooleanScorer() { +} - bool BooleanScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) - { - bool more = false; - BucketPtr tmp; - BucketScorerPtr bs(newLucene()); - // The internal loop will set the score and doc before calling collect. - collector->setScorer(bs); - do - { - bucketTable->first.reset(); - - while (current) // more queued - { - // check prohibited & required - if ((current->bits & prohibitedMask) == 0 && (current->bits & requiredMask) == requiredMask) - { - if (current->doc >= max) - { - tmp = current; - current = current->_next.lock(); - tmp->_next = bucketTable->first; - bucketTable->first = tmp; - continue; - } - - if (current->coord >= minNrShouldMatch) - { - bs->_score = current->score * coordFactors[current->coord]; - bs->doc = current->doc; - collector->collect(current->doc); - } +bool BooleanScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { + bool more = false; + BucketPtr tmp; + BucketScorerPtr bs(newLucene()); + // The internal loop will set the score and doc before calling collect. + collector->setScorer(bs); + do { + bucketTable->first.reset(); + + while (current) { // more queued + // check prohibited & required + if ((current->bits & prohibitedMask) == 0 && (current->bits & requiredMask) == requiredMask) { + if (current->doc >= max) { + tmp = current; + current = current->_next.lock(); + tmp->_next = bucketTable->first; + bucketTable->first = tmp; + continue; } - current = current->_next.lock(); // pop the queue + if (current->coord >= minNrShouldMatch) { + bs->_score = current->score * coordFactors[current->coord]; + bs->doc = current->doc; + collector->collect(current->doc); + } } - if (bucketTable->first) - { - current = bucketTable->first; - bucketTable->first = current->_next.lock(); - return true; - } + current = current->_next.lock(); // pop the queue + } + + if (bucketTable->first) { + current = bucketTable->first; + bucketTable->first = current->_next.lock(); + return true; + } + + // refill the queue + more = false; + end += BucketTable::SIZE; - // refill the queue - more = false; - end += BucketTable::SIZE; - - for (SubScorerPtr sub(scorers); sub; sub = sub->next) - { - int32_t subScorerDocID = sub->scorer->docID(); - if (subScorerDocID != NO_MORE_DOCS) - { - if (sub->scorer->score(sub->collector, end, subScorerDocID)) - more = true; + for (SubScorerPtr sub(scorers); sub; sub = sub->next) { + int32_t subScorerDocID = sub->scorer->docID(); + if (subScorerDocID != NO_MORE_DOCS) { + if (sub->scorer->score(sub->collector, end, subScorerDocID)) { + more = true; } } - current = bucketTable->first; } - while (current || more); + current = bucketTable->first; + } while (current || more); - return false; - } + return false; +} - int32_t BooleanScorer::advance(int32_t target) - { - boost::throw_exception(UnsupportedOperationException()); - return 0; - } +int32_t BooleanScorer::advance(int32_t target) { + boost::throw_exception(UnsupportedOperationException()); + return 0; +} - int32_t BooleanScorer::docID() - { - return doc; - } +int32_t BooleanScorer::docID() { + return doc; +} - int32_t BooleanScorer::nextDoc() - { - bool more = false; - do - { - while (bucketTable->first) // more queued - { - current = bucketTable->first; - bucketTable->first = current->_next.lock(); // pop the queue - - // check prohibited & required and minNrShouldMatch - if ((current->bits & prohibitedMask) == 0 && (current->bits & requiredMask) == requiredMask && current->coord >= minNrShouldMatch) - { - doc = current->doc; - return doc; - } - } +int32_t BooleanScorer::nextDoc() { + bool more = false; + do { + while (bucketTable->first) { // more queued + current = bucketTable->first; + bucketTable->first = current->_next.lock(); // pop the queue - // refill the queue - more = false; - end += BucketTable::SIZE; - - for (SubScorerPtr sub(scorers); sub; sub = sub->next) - { - ScorerPtr scorer(sub->scorer); - sub->collector->setScorer(scorer); - int32_t doc = scorer->docID(); - while (doc < end) - { - sub->collector->collect(doc); - doc = scorer->nextDoc(); - } - if (doc != NO_MORE_DOCS) - more = true; + // check prohibited & required and minNrShouldMatch + if ((current->bits & prohibitedMask) == 0 && (current->bits & requiredMask) == requiredMask && current->coord >= minNrShouldMatch) { + doc = current->doc; + return doc; } } - while (bucketTable->first || more); - doc = NO_MORE_DOCS; - return doc; - } - - double BooleanScorer::score() - { - return current->score * coordFactors[current->coord]; - } + // refill the queue + more = false; + end += BucketTable::SIZE; + + for (SubScorerPtr sub(scorers); sub; sub = sub->next) { + ScorerPtr scorer(sub->scorer); + sub->collector->setScorer(scorer); + int32_t doc = scorer->docID(); + while (doc < end) { + sub->collector->collect(doc); + doc = scorer->nextDoc(); + } + if (doc != NO_MORE_DOCS) { + more = true; + } + } + } while (bucketTable->first || more); - void BooleanScorer::score(const CollectorPtr& collector) - { - score(collector, INT_MAX, nextDoc()); - } + doc = NO_MORE_DOCS; + return doc; +} - String BooleanScorer::toString() - { - StringStream buffer; - buffer << L"boolean("; - for (SubScorerPtr sub(scorers); sub; sub = sub->next) - buffer << sub->scorer->toString() << L" "; - buffer << L")"; - return buffer.str(); - } +double BooleanScorer::score() { + return current->score * coordFactors[current->coord]; +} - BooleanScorerCollector::BooleanScorerCollector(int32_t mask, const BucketTablePtr& bucketTable) - { - this->mask = mask; - this->_bucketTable = bucketTable; - } +void BooleanScorer::score(const CollectorPtr& collector) { + score(collector, INT_MAX, nextDoc()); +} - BooleanScorerCollector::~BooleanScorerCollector() - { +String BooleanScorer::toString() { + StringStream buffer; + buffer << L"boolean("; + for (SubScorerPtr sub(scorers); sub; sub = sub->next) { + buffer << sub->scorer->toString() << L" "; } + buffer << L")"; + return buffer.str(); +} - void BooleanScorerCollector::collect(int32_t doc) - { - BucketTablePtr table(_bucketTable); - int32_t i = doc & BucketTable::MASK; - BucketPtr bucket(table->buckets[i]); - if (!bucket) - { - bucket = newLucene(); - table->buckets[i] = bucket; - } +BooleanScorerCollector::BooleanScorerCollector(int32_t mask, const BucketTablePtr& bucketTable) { + this->mask = mask; + this->_bucketTable = bucketTable; +} - if (bucket->doc != doc) // invalid bucket - { - bucket->doc = doc; // set doc - bucket->score = ScorerPtr(_scorer)->score(); // initialize score - bucket->bits = mask; // initialize mask - bucket->coord = 1; // initialize coord +BooleanScorerCollector::~BooleanScorerCollector() { +} - bucket->_next = table->first; // push onto valid list - table->first = bucket; - } - else - { - bucket->score += ScorerPtr(_scorer)->score(); // increment score - bucket->bits |= mask; // add bits in mask - ++bucket->coord; // increment coord - } +void BooleanScorerCollector::collect(int32_t doc) { + BucketTablePtr table(_bucketTable); + int32_t i = doc & BucketTable::MASK; + BucketPtr bucket(table->buckets[i]); + if (!bucket) { + bucket = newLucene(); + table->buckets[i] = bucket; } - void BooleanScorerCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - // not needed by this implementation + if (bucket->doc != doc) { // invalid bucket + bucket->doc = doc; // set doc + bucket->score = ScorerPtr(_scorer)->score(); // initialize score + bucket->bits = mask; // initialize mask + bucket->coord = 1; // initialize coord + + bucket->_next = table->first; // push onto valid list + table->first = bucket; + } else { + bucket->score += ScorerPtr(_scorer)->score(); // increment score + bucket->bits |= mask; // add bits in mask + ++bucket->coord; // increment coord } +} - void BooleanScorerCollector::setScorer(const ScorerPtr& scorer) - { - this->_scorer = scorer; - } +void BooleanScorerCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + // not needed by this implementation +} - bool BooleanScorerCollector::acceptsDocsOutOfOrder() - { - return true; - } +void BooleanScorerCollector::setScorer(const ScorerPtr& scorer) { + this->_scorer = scorer; +} - BucketScorer::BucketScorer() : Scorer(SimilarityPtr()) - { - _score = 0; - doc = NO_MORE_DOCS; - } +bool BooleanScorerCollector::acceptsDocsOutOfOrder() { + return true; +} - BucketScorer::~BucketScorer() - { - } +BucketScorer::BucketScorer() : Scorer(SimilarityPtr()) { + _score = 0; + doc = NO_MORE_DOCS; +} - int32_t BucketScorer::advance(int32_t target) - { - return NO_MORE_DOCS; - } +BucketScorer::~BucketScorer() { +} - int32_t BucketScorer::docID() - { - return doc; - } +int32_t BucketScorer::advance(int32_t target) { + return NO_MORE_DOCS; +} - int32_t BucketScorer::nextDoc() - { - return NO_MORE_DOCS; - } +int32_t BucketScorer::docID() { + return doc; +} - double BucketScorer::score() - { - return _score; - } +int32_t BucketScorer::nextDoc() { + return NO_MORE_DOCS; +} - Bucket::Bucket() - { - doc = -1; - score = 0; - bits = 0; - coord = 0; - } +double BucketScorer::score() { + return _score; +} - Bucket::~Bucket() - { - } +Bucket::Bucket() { + doc = -1; + score = 0; + bits = 0; + coord = 0; +} - const int32_t BucketTable::SIZE = 1 << 11; - const int32_t BucketTable::MASK = BucketTable::SIZE - 1; +Bucket::~Bucket() { +} - BucketTable::BucketTable() - { - buckets = Collection::newInstance(SIZE); - } +const int32_t BucketTable::SIZE = 1 << 11; +const int32_t BucketTable::MASK = BucketTable::SIZE - 1; - BucketTable::~BucketTable() - { - } +BucketTable::BucketTable() { + buckets = Collection::newInstance(SIZE); +} - CollectorPtr BucketTable::newCollector(int32_t mask) - { - return newLucene(mask, shared_from_this()); - } +BucketTable::~BucketTable() { +} - int32_t BucketTable::size() - { - return SIZE; - } +CollectorPtr BucketTable::newCollector(int32_t mask) { + return newLucene(mask, shared_from_this()); +} - SubScorer::SubScorer(const ScorerPtr& scorer, bool required, bool prohibited, const CollectorPtr& collector, const SubScorerPtr& next) - { - this->scorer = scorer; - this->required = required; - this->prohibited = prohibited; - this->collector = collector; - this->next = next; - } +int32_t BucketTable::size() { + return SIZE; +} + +SubScorer::SubScorer(const ScorerPtr& scorer, bool required, bool prohibited, const CollectorPtr& collector, const SubScorerPtr& next) { + this->scorer = scorer; + this->required = required; + this->prohibited = prohibited; + this->collector = collector; + this->next = next; +} + +SubScorer::~SubScorer() { +} - SubScorer::~SubScorer() - { - } } diff --git a/src/core/search/BooleanScorer2.cpp b/src/core/search/BooleanScorer2.cpp index 79589654..81010f09 100644 --- a/src/core/search/BooleanScorer2.cpp +++ b/src/core/search/BooleanScorer2.cpp @@ -11,253 +11,218 @@ #include "Similarity.h" #include "Collector.h" -namespace Lucene -{ - BooleanScorer2::BooleanScorer2(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional) : Scorer(similarity) - { - this->minNrShouldMatch = minNrShouldMatch; - this->requiredScorers = required; - this->prohibitedScorers = prohibited; - this->optionalScorers = optional; - this->doc = -1; - } +namespace Lucene { + +BooleanScorer2::BooleanScorer2(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection required, Collection prohibited, Collection optional) : Scorer(similarity) { + this->minNrShouldMatch = minNrShouldMatch; + this->requiredScorers = required; + this->prohibitedScorers = prohibited; + this->optionalScorers = optional; + this->doc = -1; +} - BooleanScorer2::~BooleanScorer2() - { - } +BooleanScorer2::~BooleanScorer2() { +} - void BooleanScorer2::initialize() - { - if (minNrShouldMatch < 0) - boost::throw_exception(IllegalArgumentException(L"Minimum number of optional scorers should not be negative")); +void BooleanScorer2::initialize() { + if (minNrShouldMatch < 0) { + boost::throw_exception(IllegalArgumentException(L"Minimum number of optional scorers should not be negative")); + } - coordinator = newLucene(shared_from_this()); - coordinator->maxCoord += optionalScorers.size(); - coordinator->maxCoord += requiredScorers.size(); + coordinator = newLucene(shared_from_this()); + coordinator->maxCoord += optionalScorers.size(); + coordinator->maxCoord += requiredScorers.size(); - coordinator->init(); - countingSumScorer = makeCountingSumScorer(); - } + coordinator->init(); + countingSumScorer = makeCountingSumScorer(); +} - ScorerPtr BooleanScorer2::countingDisjunctionSumScorer(Collection scorers, int32_t minNrShouldMatch) - { - // each scorer from the list counted as a single matcher - return newLucene(shared_from_this(), scorers, minNrShouldMatch); - } +ScorerPtr BooleanScorer2::countingDisjunctionSumScorer(Collection scorers, int32_t minNrShouldMatch) { + // each scorer from the list counted as a single matcher + return newLucene(shared_from_this(), scorers, minNrShouldMatch); +} - ScorerPtr BooleanScorer2::countingConjunctionSumScorer(Collection requiredScorers) - { - // each scorer from the list counted as a single matcher - return newLucene(shared_from_this(), Similarity::getDefault(), requiredScorers); - } +ScorerPtr BooleanScorer2::countingConjunctionSumScorer(Collection requiredScorers) { + // each scorer from the list counted as a single matcher + return newLucene(shared_from_this(), Similarity::getDefault(), requiredScorers); +} - ScorerPtr BooleanScorer2::dualConjunctionSumScorer(const ScorerPtr& req1, const ScorerPtr& req2) - { - Collection scorers(newCollection(req1, req2)); +ScorerPtr BooleanScorer2::dualConjunctionSumScorer(const ScorerPtr& req1, const ScorerPtr& req2) { + Collection scorers(newCollection(req1, req2)); - // All scorers match, so Similarity::getDefault() always has 1 as the coordination factor. - // Therefore the sum of the scores of two scorers is used as score. - return newLucene(Similarity::getDefault(), scorers); - } + // All scorers match, so Similarity::getDefault() always has 1 as the coordination factor. + // Therefore the sum of the scores of two scorers is used as score. + return newLucene(Similarity::getDefault(), scorers); +} - ScorerPtr BooleanScorer2::makeCountingSumScorer() - { - return requiredScorers.empty() ? makeCountingSumScorerNoReq() : makeCountingSumScorerSomeReq(); - } +ScorerPtr BooleanScorer2::makeCountingSumScorer() { + return requiredScorers.empty() ? makeCountingSumScorerNoReq() : makeCountingSumScorerSomeReq(); +} - ScorerPtr BooleanScorer2::makeCountingSumScorerNoReq() - { - // minNrShouldMatch optional scorers are required, but at least 1 - int32_t nrOptRequired = minNrShouldMatch < 1 ? 1 : minNrShouldMatch; - ScorerPtr requiredCountingSumScorer; - if (optionalScorers.size() > nrOptRequired) - requiredCountingSumScorer = countingDisjunctionSumScorer(optionalScorers, nrOptRequired); - else if (optionalScorers.size() == 1) - requiredCountingSumScorer = newLucene(optionalScorers[0], coordinator); - else - requiredCountingSumScorer = countingConjunctionSumScorer(optionalScorers); - return addProhibitedScorers(requiredCountingSumScorer); - } +ScorerPtr BooleanScorer2::makeCountingSumScorerNoReq() { + // minNrShouldMatch optional scorers are required, but at least 1 + int32_t nrOptRequired = minNrShouldMatch < 1 ? 1 : minNrShouldMatch; + ScorerPtr requiredCountingSumScorer; + if (optionalScorers.size() > nrOptRequired) { + requiredCountingSumScorer = countingDisjunctionSumScorer(optionalScorers, nrOptRequired); + } else if (optionalScorers.size() == 1) { + requiredCountingSumScorer = newLucene(optionalScorers[0], coordinator); + } else { + requiredCountingSumScorer = countingConjunctionSumScorer(optionalScorers); + } + return addProhibitedScorers(requiredCountingSumScorer); +} - ScorerPtr BooleanScorer2::makeCountingSumScorerSomeReq() - { - if (optionalScorers.size() == minNrShouldMatch) // all optional scorers also required. - { - Collection allReq(Collection::newInstance(requiredScorers.begin(), requiredScorers.end())); - allReq.addAll(optionalScorers.begin(), optionalScorers.end()); - return addProhibitedScorers(countingConjunctionSumScorer(allReq)); - } - else // optionalScorers.size() > minNrShouldMatch, and at least one required scorer - { - ScorerPtr requiredCountingSumScorer = requiredScorers.size() == 1 ? newLucene(requiredScorers[0], coordinator) : countingConjunctionSumScorer(requiredScorers); - if (minNrShouldMatch > 0) // use a required disjunction scorer over the optional scorers - return addProhibitedScorers(dualConjunctionSumScorer(requiredCountingSumScorer, countingDisjunctionSumScorer(optionalScorers, minNrShouldMatch))); - else // minNrShouldMatch == 0 - return newLucene(addProhibitedScorers(requiredCountingSumScorer), optionalScorers.size() == 1 ? newLucene(optionalScorers[0], coordinator) : countingDisjunctionSumScorer(optionalScorers, 1)); +ScorerPtr BooleanScorer2::makeCountingSumScorerSomeReq() { + if (optionalScorers.size() == minNrShouldMatch) { // all optional scorers also required. + Collection allReq(Collection::newInstance(requiredScorers.begin(), requiredScorers.end())); + allReq.addAll(optionalScorers.begin(), optionalScorers.end()); + return addProhibitedScorers(countingConjunctionSumScorer(allReq)); + } else { // optionalScorers.size() > minNrShouldMatch, and at least one required scorer + ScorerPtr requiredCountingSumScorer = requiredScorers.size() == 1 ? newLucene(requiredScorers[0], coordinator) : countingConjunctionSumScorer(requiredScorers); + if (minNrShouldMatch > 0) { // use a required disjunction scorer over the optional scorers + return addProhibitedScorers(dualConjunctionSumScorer(requiredCountingSumScorer, countingDisjunctionSumScorer(optionalScorers, minNrShouldMatch))); + } else { // minNrShouldMatch == 0 + return newLucene(addProhibitedScorers(requiredCountingSumScorer), optionalScorers.size() == 1 ? newLucene(optionalScorers[0], coordinator) : countingDisjunctionSumScorer(optionalScorers, 1)); } } +} - ScorerPtr BooleanScorer2::addProhibitedScorers(const ScorerPtr& requiredCountingSumScorer) - { - return prohibitedScorers.empty() ? requiredCountingSumScorer : newLucene(requiredCountingSumScorer, (prohibitedScorers.size() == 1 ? prohibitedScorers[0] : newLucene(prohibitedScorers))); - } +ScorerPtr BooleanScorer2::addProhibitedScorers(const ScorerPtr& requiredCountingSumScorer) { + return prohibitedScorers.empty() ? requiredCountingSumScorer : newLucene(requiredCountingSumScorer, (prohibitedScorers.size() == 1 ? prohibitedScorers[0] : newLucene(prohibitedScorers))); +} - void BooleanScorer2::score(const CollectorPtr& collector) - { - collector->setScorer(shared_from_this()); - while ((doc = countingSumScorer->nextDoc()) != NO_MORE_DOCS) - collector->collect(doc); +void BooleanScorer2::score(const CollectorPtr& collector) { + collector->setScorer(shared_from_this()); + while ((doc = countingSumScorer->nextDoc()) != NO_MORE_DOCS) { + collector->collect(doc); } +} - bool BooleanScorer2::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) - { - doc = firstDocID; - collector->setScorer(shared_from_this()); - while (doc < max) - { - collector->collect(doc); - doc = countingSumScorer->nextDoc(); - } - return (doc != NO_MORE_DOCS); +bool BooleanScorer2::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { + doc = firstDocID; + collector->setScorer(shared_from_this()); + while (doc < max) { + collector->collect(doc); + doc = countingSumScorer->nextDoc(); } + return (doc != NO_MORE_DOCS); +} - int32_t BooleanScorer2::docID() - { - return doc; - } +int32_t BooleanScorer2::docID() { + return doc; +} - int32_t BooleanScorer2::nextDoc() - { - doc = countingSumScorer->nextDoc(); - return doc; - } +int32_t BooleanScorer2::nextDoc() { + doc = countingSumScorer->nextDoc(); + return doc; +} - double BooleanScorer2::score() - { - coordinator->nrMatchers = 0; - double sum = countingSumScorer->score(); - return sum * coordinator->coordFactors[coordinator->nrMatchers]; - } +double BooleanScorer2::score() { + coordinator->nrMatchers = 0; + double sum = countingSumScorer->score(); + return sum * coordinator->coordFactors[coordinator->nrMatchers]; +} - int32_t BooleanScorer2::advance(int32_t target) - { - doc = countingSumScorer->advance(target); - return doc; - } +int32_t BooleanScorer2::advance(int32_t target) { + doc = countingSumScorer->advance(target); + return doc; +} - Coordinator::Coordinator(const BooleanScorer2Ptr& scorer) - { - _scorer = scorer; - maxCoord = 0; - nrMatchers = 0; - } +Coordinator::Coordinator(const BooleanScorer2Ptr& scorer) { + _scorer = scorer; + maxCoord = 0; + nrMatchers = 0; +} - Coordinator::~Coordinator() - { - } +Coordinator::~Coordinator() { +} - void Coordinator::init() - { - coordFactors = Collection::newInstance(maxCoord + 1); - SimilarityPtr sim(BooleanScorer2Ptr(_scorer)->getSimilarity()); - for (int32_t i = 0; i <= maxCoord; ++i) - coordFactors[i] = sim->coord(i, maxCoord); +void Coordinator::init() { + coordFactors = Collection::newInstance(maxCoord + 1); + SimilarityPtr sim(BooleanScorer2Ptr(_scorer)->getSimilarity()); + for (int32_t i = 0; i <= maxCoord; ++i) { + coordFactors[i] = sim->coord(i, maxCoord); } +} - SingleMatchScorer::SingleMatchScorer(const ScorerPtr& scorer, const CoordinatorPtr& coordinator) : Scorer(scorer->getSimilarity()) - { - lastScoredDoc = -1; - lastDocScore = std::numeric_limits::quiet_NaN(); - this->scorer = scorer; - this->coordinator = coordinator; - } +SingleMatchScorer::SingleMatchScorer(const ScorerPtr& scorer, const CoordinatorPtr& coordinator) : Scorer(scorer->getSimilarity()) { + lastScoredDoc = -1; + lastDocScore = std::numeric_limits::quiet_NaN(); + this->scorer = scorer; + this->coordinator = coordinator; +} - SingleMatchScorer::~SingleMatchScorer() - { - } +SingleMatchScorer::~SingleMatchScorer() { +} - double SingleMatchScorer::score() - { - int32_t doc = docID(); - if (doc >= lastScoredDoc) - { - if (doc > lastScoredDoc) - { - lastDocScore = scorer->score(); - lastScoredDoc = doc; - } - ++coordinator->nrMatchers; +double SingleMatchScorer::score() { + int32_t doc = docID(); + if (doc >= lastScoredDoc) { + if (doc > lastScoredDoc) { + lastDocScore = scorer->score(); + lastScoredDoc = doc; } - return lastDocScore; + ++coordinator->nrMatchers; } + return lastDocScore; +} - int32_t SingleMatchScorer::docID() - { - return scorer->docID(); - } +int32_t SingleMatchScorer::docID() { + return scorer->docID(); +} - int32_t SingleMatchScorer::nextDoc() - { - return scorer->nextDoc(); - } +int32_t SingleMatchScorer::nextDoc() { + return scorer->nextDoc(); +} - int32_t SingleMatchScorer::advance(int32_t target) - { - return scorer->advance(target); - } +int32_t SingleMatchScorer::advance(int32_t target) { + return scorer->advance(target); +} - CountingDisjunctionSumScorer::CountingDisjunctionSumScorer(const BooleanScorer2Ptr& scorer, Collection subScorers, int32_t minimumNrMatchers) : DisjunctionSumScorer(subScorers, minimumNrMatchers) - { - _scorer = scorer; - lastScoredDoc = -1; - lastDocScore = std::numeric_limits::quiet_NaN(); - } +CountingDisjunctionSumScorer::CountingDisjunctionSumScorer(const BooleanScorer2Ptr& scorer, Collection subScorers, int32_t minimumNrMatchers) : DisjunctionSumScorer(subScorers, minimumNrMatchers) { + _scorer = scorer; + lastScoredDoc = -1; + lastDocScore = std::numeric_limits::quiet_NaN(); +} - CountingDisjunctionSumScorer::~CountingDisjunctionSumScorer() - { - } +CountingDisjunctionSumScorer::~CountingDisjunctionSumScorer() { +} - double CountingDisjunctionSumScorer::score() - { - int32_t doc = docID(); - if (doc >= lastScoredDoc) - { - if (doc > lastScoredDoc) - { - lastDocScore = DisjunctionSumScorer::score(); - lastScoredDoc = doc; - } - BooleanScorer2Ptr(_scorer)->coordinator->nrMatchers += DisjunctionSumScorer::_nrMatchers; +double CountingDisjunctionSumScorer::score() { + int32_t doc = docID(); + if (doc >= lastScoredDoc) { + if (doc > lastScoredDoc) { + lastDocScore = DisjunctionSumScorer::score(); + lastScoredDoc = doc; } - return lastDocScore; + BooleanScorer2Ptr(_scorer)->coordinator->nrMatchers += DisjunctionSumScorer::_nrMatchers; } + return lastDocScore; +} - CountingConjunctionSumScorer::CountingConjunctionSumScorer(const BooleanScorer2Ptr& scorer, const SimilarityPtr& similarity, Collection scorers) : ConjunctionScorer(similarity, scorers) - { - _scorer = scorer; - lastScoredDoc = -1; - requiredNrMatchers = scorers.size(); - lastDocScore = std::numeric_limits::quiet_NaN(); - } +CountingConjunctionSumScorer::CountingConjunctionSumScorer(const BooleanScorer2Ptr& scorer, const SimilarityPtr& similarity, Collection scorers) : ConjunctionScorer(similarity, scorers) { + _scorer = scorer; + lastScoredDoc = -1; + requiredNrMatchers = scorers.size(); + lastDocScore = std::numeric_limits::quiet_NaN(); +} - CountingConjunctionSumScorer::~CountingConjunctionSumScorer() - { - } +CountingConjunctionSumScorer::~CountingConjunctionSumScorer() { +} - double CountingConjunctionSumScorer::score() - { - int32_t doc = docID(); - if (doc >= lastScoredDoc) - { - if (doc > lastScoredDoc) - { - lastDocScore = ConjunctionScorer::score(); - lastScoredDoc = doc; - } - BooleanScorer2Ptr(_scorer)->coordinator->nrMatchers += requiredNrMatchers; +double CountingConjunctionSumScorer::score() { + int32_t doc = docID(); + if (doc >= lastScoredDoc) { + if (doc > lastScoredDoc) { + lastDocScore = ConjunctionScorer::score(); + lastScoredDoc = doc; } - // All scorers match, so Similarity::getDefault() ConjunctionScorer::score() always has 1 as the - /// coordination factor. Therefore the sum of the scores of the requiredScorers is used as score. - return lastDocScore; + BooleanScorer2Ptr(_scorer)->coordinator->nrMatchers += requiredNrMatchers; } + // All scorers match, so Similarity::getDefault() ConjunctionScorer::score() always has 1 as the + /// coordination factor. Therefore the sum of the scores of the requiredScorers is used as score. + return lastDocScore; +} + } diff --git a/src/core/search/CachingSpanFilter.cpp b/src/core/search/CachingSpanFilter.cpp index 912aef81..9a449342 100644 --- a/src/core/search/CachingSpanFilter.cpp +++ b/src/core/search/CachingSpanFilter.cpp @@ -10,86 +10,78 @@ #include "SpanFilterResult.h" #include "IndexReader.h" -namespace Lucene -{ - CachingSpanFilter::CachingSpanFilter(const SpanFilterPtr& filter, CachingWrapperFilter::DeletesMode deletesMode) - { - this->filter = filter; - if (deletesMode == CachingWrapperFilter::DELETES_DYNAMIC) - boost::throw_exception(IllegalArgumentException(L"DeletesMode::DYNAMIC is not supported")); - this->cache = newLucene(deletesMode); - this->hitCount = 0; - this->missCount = 0; - } - - CachingSpanFilter::~CachingSpanFilter() - { - } +namespace Lucene { - DocIdSetPtr CachingSpanFilter::getDocIdSet(const IndexReaderPtr& reader) - { - SpanFilterResultPtr result(getCachedResult(reader)); - return result ? result->getDocIdSet() : DocIdSetPtr(); +CachingSpanFilter::CachingSpanFilter(const SpanFilterPtr& filter, CachingWrapperFilter::DeletesMode deletesMode) { + this->filter = filter; + if (deletesMode == CachingWrapperFilter::DELETES_DYNAMIC) { + boost::throw_exception(IllegalArgumentException(L"DeletesMode::DYNAMIC is not supported")); } + this->cache = newLucene(deletesMode); + this->hitCount = 0; + this->missCount = 0; +} - SpanFilterResultPtr CachingSpanFilter::getCachedResult(const IndexReaderPtr& reader) - { - LuceneObjectPtr coreKey = reader->getFieldCacheKey(); - LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; - - SpanFilterResultPtr result(boost::dynamic_pointer_cast(cache->get(reader, coreKey, delCoreKey))); - if (result) - { - ++hitCount; - return result; - } +CachingSpanFilter::~CachingSpanFilter() { +} - ++missCount; - result = filter->bitSpans(reader); +DocIdSetPtr CachingSpanFilter::getDocIdSet(const IndexReaderPtr& reader) { + SpanFilterResultPtr result(getCachedResult(reader)); + return result ? result->getDocIdSet() : DocIdSetPtr(); +} - cache->put(coreKey, delCoreKey, result); +SpanFilterResultPtr CachingSpanFilter::getCachedResult(const IndexReaderPtr& reader) { + LuceneObjectPtr coreKey = reader->getFieldCacheKey(); + LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; + SpanFilterResultPtr result(boost::dynamic_pointer_cast(cache->get(reader, coreKey, delCoreKey))); + if (result) { + ++hitCount; return result; } - SpanFilterResultPtr CachingSpanFilter::bitSpans(const IndexReaderPtr& reader) - { - return getCachedResult(reader); - } + ++missCount; + result = filter->bitSpans(reader); - String CachingSpanFilter::toString() - { - return L"CachingSpanFilter(" + filter->toString() + L")"; - } + cache->put(coreKey, delCoreKey, result); - bool CachingSpanFilter::equals(const LuceneObjectPtr& other) - { - if (SpanFilter::equals(other)) - return true; + return result; +} - CachingSpanFilterPtr otherCachingSpanFilter(boost::dynamic_pointer_cast(other)); - if (!otherCachingSpanFilter) - return false; +SpanFilterResultPtr CachingSpanFilter::bitSpans(const IndexReaderPtr& reader) { + return getCachedResult(reader); +} - return this->filter->equals(otherCachingSpanFilter->filter); - } +String CachingSpanFilter::toString() { + return L"CachingSpanFilter(" + filter->toString() + L")"; +} - int32_t CachingSpanFilter::hashCode() - { - return filter->hashCode() ^ 0x1117bf25; +bool CachingSpanFilter::equals(const LuceneObjectPtr& other) { + if (SpanFilter::equals(other)) { + return true; } - FilterCacheSpanFilterResult::FilterCacheSpanFilterResult(CachingWrapperFilter::DeletesMode deletesMode) : FilterCache(deletesMode) - { + CachingSpanFilterPtr otherCachingSpanFilter(boost::dynamic_pointer_cast(other)); + if (!otherCachingSpanFilter) { + return false; } - FilterCacheSpanFilterResult::~FilterCacheSpanFilterResult() - { - } + return this->filter->equals(otherCachingSpanFilter->filter); +} + +int32_t CachingSpanFilter::hashCode() { + return filter->hashCode() ^ 0x1117bf25; +} + +FilterCacheSpanFilterResult::FilterCacheSpanFilterResult(CachingWrapperFilter::DeletesMode deletesMode) : FilterCache(deletesMode) { +} + +FilterCacheSpanFilterResult::~FilterCacheSpanFilterResult() { +} + +LuceneObjectPtr FilterCacheSpanFilterResult::mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) { + boost::throw_exception(IllegalStateException(L"DeletesMode::DYNAMIC is not supported")); + return LuceneObjectPtr(); +} - LuceneObjectPtr FilterCacheSpanFilterResult::mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) - { - boost::throw_exception(IllegalStateException(L"DeletesMode::DYNAMIC is not supported")); - return LuceneObjectPtr(); - } } diff --git a/src/core/search/CachingWrapperFilter.cpp b/src/core/search/CachingWrapperFilter.cpp index 7ac05bfa..c04f9650 100644 --- a/src/core/search/CachingWrapperFilter.cpp +++ b/src/core/search/CachingWrapperFilter.cpp @@ -10,168 +10,146 @@ #include "OpenBitSetDISI.h" #include "IndexReader.h" -namespace Lucene -{ - CachingWrapperFilter::CachingWrapperFilter(const FilterPtr& filter, DeletesMode deletesMode) - { - this->filter = filter; - this->cache = newLucene(deletesMode); - this->hitCount = 0; - this->missCount = 0; - } +namespace Lucene { + +CachingWrapperFilter::CachingWrapperFilter(const FilterPtr& filter, DeletesMode deletesMode) { + this->filter = filter; + this->cache = newLucene(deletesMode); + this->hitCount = 0; + this->missCount = 0; +} - CachingWrapperFilter::~CachingWrapperFilter() - { +CachingWrapperFilter::~CachingWrapperFilter() { +} + +DocIdSetPtr CachingWrapperFilter::docIdSetToCache(const DocIdSetPtr& docIdSet, const IndexReaderPtr& reader) { + if (!docIdSet) { + // this is better than returning null, as the nonnull result can be cached + return DocIdSet::EMPTY_DOCIDSET(); + } else if (docIdSet->isCacheable()) { + return docIdSet; + } else { + DocIdSetIteratorPtr it(docIdSet->iterator()); + // null is allowed to be returned by iterator(), in this case we wrap with the empty set, + // which is cacheable. + return !it ? DocIdSet::EMPTY_DOCIDSET() : newLucene(it, reader->maxDoc()); } +} - DocIdSetPtr CachingWrapperFilter::docIdSetToCache(const DocIdSetPtr& docIdSet, const IndexReaderPtr& reader) - { - if (!docIdSet) - { - // this is better than returning null, as the nonnull result can be cached - return DocIdSet::EMPTY_DOCIDSET(); - } - else if (docIdSet->isCacheable()) - return docIdSet; - else - { - DocIdSetIteratorPtr it(docIdSet->iterator()); - // null is allowed to be returned by iterator(), in this case we wrap with the empty set, - // which is cacheable. - return !it ? DocIdSet::EMPTY_DOCIDSET() : newLucene(it, reader->maxDoc()); - } +DocIdSetPtr CachingWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) { + LuceneObjectPtr coreKey = reader->getFieldCacheKey(); + LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; + + DocIdSetPtr docIdSet(boost::dynamic_pointer_cast(cache->get(reader, coreKey, delCoreKey))); + if (docIdSet) { + ++hitCount; + return docIdSet; } - DocIdSetPtr CachingWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) - { - LuceneObjectPtr coreKey = reader->getFieldCacheKey(); - LuceneObjectPtr delCoreKey = reader->hasDeletions() ? reader->getDeletesCacheKey() : coreKey; + ++missCount; - DocIdSetPtr docIdSet(boost::dynamic_pointer_cast(cache->get(reader, coreKey, delCoreKey))); - if (docIdSet) - { - ++hitCount; - return docIdSet; - } + // cache miss + docIdSet = docIdSetToCache(filter->getDocIdSet(reader), reader); - ++missCount; + if (docIdSet) { + cache->put(coreKey, delCoreKey, docIdSet); + } - // cache miss - docIdSet = docIdSetToCache(filter->getDocIdSet(reader), reader); + return docIdSet; +} - if (docIdSet) - cache->put(coreKey, delCoreKey, docIdSet); +String CachingWrapperFilter::toString() { + return L"CachingWrapperFilter(" + filter->toString() + L")"; +} - return docIdSet; +bool CachingWrapperFilter::equals(const LuceneObjectPtr& other) { + if (Filter::equals(other)) { + return true; } - String CachingWrapperFilter::toString() - { - return L"CachingWrapperFilter(" + filter->toString() + L")"; + CachingWrapperFilterPtr otherCachingWrapperFilter(boost::dynamic_pointer_cast(other)); + if (!otherCachingWrapperFilter) { + return false; } - bool CachingWrapperFilter::equals(const LuceneObjectPtr& other) - { - if (Filter::equals(other)) - return true; + return this->filter->equals(otherCachingWrapperFilter->filter); +} - CachingWrapperFilterPtr otherCachingWrapperFilter(boost::dynamic_pointer_cast(other)); - if (!otherCachingWrapperFilter) - return false; +int32_t CachingWrapperFilter::hashCode() { + return filter->hashCode() ^ 0x1117bf25; +} - return this->filter->equals(otherCachingWrapperFilter->filter); - } +FilterCache::FilterCache(CachingWrapperFilter::DeletesMode deletesMode) { + this->deletesMode = deletesMode; +} - int32_t CachingWrapperFilter::hashCode() - { - return filter->hashCode() ^ 0x1117bf25; - } +FilterCache::~FilterCache() { +} - FilterCache::FilterCache(CachingWrapperFilter::DeletesMode deletesMode) - { - this->deletesMode = deletesMode; - } +LuceneObjectPtr FilterCache::get(const IndexReaderPtr& reader, const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey) { + SyncLock syncLock(this); - FilterCache::~FilterCache() - { + if (!cache) { + cache = WeakMapObjectObject::newInstance(); } - LuceneObjectPtr FilterCache::get(const IndexReaderPtr& reader, const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey) - { - SyncLock syncLock(this); + LuceneObjectPtr value; + if (deletesMode == CachingWrapperFilter::DELETES_IGNORE) { + // key on core + value = cache.get(coreKey); + } else if (deletesMode == CachingWrapperFilter::DELETES_RECACHE) { + // key on deletes, if any, else core + value = cache.get(delCoreKey); + } else { + BOOST_ASSERT(deletesMode == CachingWrapperFilter::DELETES_DYNAMIC); - if (!cache) - cache = WeakMapObjectObject::newInstance(); + // first try for exact match + value = cache.get(delCoreKey); - LuceneObjectPtr value; - if (deletesMode == CachingWrapperFilter::DELETES_IGNORE) - { - // key on core + if (!value) { + // now for core match, but dynamically AND NOT deletions value = cache.get(coreKey); - } - else if (deletesMode == CachingWrapperFilter::DELETES_RECACHE) - { - // key on deletes, if any, else core - value = cache.get(delCoreKey); - } - else - { - BOOST_ASSERT(deletesMode == CachingWrapperFilter::DELETES_DYNAMIC); - - // first try for exact match - value = cache.get(delCoreKey); - - if (!value) - { - // now for core match, but dynamically AND NOT deletions - value = cache.get(coreKey); - if (value && reader->hasDeletions()) - value = mergeDeletes(reader, value); + if (value && reader->hasDeletions()) { + value = mergeDeletes(reader, value); } } - - return value; } - void FilterCache::put(const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey, const LuceneObjectPtr& value) - { - SyncLock syncLock(this); - - if (deletesMode == CachingWrapperFilter::DELETES_IGNORE) - cache.put(coreKey, value); - else if (deletesMode == CachingWrapperFilter::DELETES_RECACHE) - cache.put(delCoreKey, value); - else - { - cache.put(coreKey, value); - cache.put(delCoreKey, value); - } - } + return value; +} - FilterCacheDocIdSet::FilterCacheDocIdSet(CachingWrapperFilter::DeletesMode deletesMode) : FilterCache(deletesMode) - { - } +void FilterCache::put(const LuceneObjectPtr& coreKey, const LuceneObjectPtr& delCoreKey, const LuceneObjectPtr& value) { + SyncLock syncLock(this); - FilterCacheDocIdSet::~FilterCacheDocIdSet() - { + if (deletesMode == CachingWrapperFilter::DELETES_IGNORE) { + cache.put(coreKey, value); + } else if (deletesMode == CachingWrapperFilter::DELETES_RECACHE) { + cache.put(delCoreKey, value); + } else { + cache.put(coreKey, value); + cache.put(delCoreKey, value); } +} - LuceneObjectPtr FilterCacheDocIdSet::mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) - { - return newLucene(reader, boost::dynamic_pointer_cast(value)); - } +FilterCacheDocIdSet::FilterCacheDocIdSet(CachingWrapperFilter::DeletesMode deletesMode) : FilterCache(deletesMode) { +} - FilteredCacheDocIdSet::FilteredCacheDocIdSet(const IndexReaderPtr& reader, const DocIdSetPtr& innerSet) : FilteredDocIdSet(innerSet) - { - this->reader = reader; - } +FilterCacheDocIdSet::~FilterCacheDocIdSet() { +} - FilteredCacheDocIdSet::~FilteredCacheDocIdSet() - { - } +LuceneObjectPtr FilterCacheDocIdSet::mergeDeletes(const IndexReaderPtr& reader, const LuceneObjectPtr& value) { + return newLucene(reader, boost::dynamic_pointer_cast(value)); +} + +FilteredCacheDocIdSet::FilteredCacheDocIdSet(const IndexReaderPtr& reader, const DocIdSetPtr& innerSet) : FilteredDocIdSet(innerSet) { + this->reader = reader; +} + +FilteredCacheDocIdSet::~FilteredCacheDocIdSet() { +} + +bool FilteredCacheDocIdSet::match(int32_t docid) { + return !reader->isDeleted(docid); +} - bool FilteredCacheDocIdSet::match(int32_t docid) - { - return !reader->isDeleted(docid); - } } diff --git a/src/core/search/Collector.cpp b/src/core/search/Collector.cpp index 3a400dbb..a12f1445 100644 --- a/src/core/search/Collector.cpp +++ b/src/core/search/Collector.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "Collector.h" -namespace Lucene -{ - Collector::~Collector() - { - } +namespace Lucene { + +Collector::~Collector() { +} + } diff --git a/src/core/search/ComplexExplanation.cpp b/src/core/search/ComplexExplanation.cpp index 45742ff4..c9ce412f 100644 --- a/src/core/search/ComplexExplanation.cpp +++ b/src/core/search/ComplexExplanation.cpp @@ -8,34 +8,29 @@ #include "ComplexExplanation.h" #include "StringUtils.h" -namespace Lucene -{ - ComplexExplanation::ComplexExplanation(bool match, double value, const String& description) : Explanation(value, description) - { - this->match = match; - } - - ComplexExplanation::~ComplexExplanation() - { - } - - bool ComplexExplanation::getMatch() - { - return match; - } - - void ComplexExplanation::setMatch(bool match) - { - this->match = match; - } - - bool ComplexExplanation::isMatch() - { - return getMatch(); - } - - String ComplexExplanation::getSummary() - { - return StringUtils::toString(getValue()) + L" = " + (isMatch() ? L"(MATCH) " : L"(NON-MATCH) ") + getDescription(); - } +namespace Lucene { + +ComplexExplanation::ComplexExplanation(bool match, double value, const String& description) : Explanation(value, description) { + this->match = match; +} + +ComplexExplanation::~ComplexExplanation() { +} + +bool ComplexExplanation::getMatch() { + return match; +} + +void ComplexExplanation::setMatch(bool match) { + this->match = match; +} + +bool ComplexExplanation::isMatch() { + return getMatch(); +} + +String ComplexExplanation::getSummary() { + return StringUtils::toString(getValue()) + L" = " + (isMatch() ? L"(MATCH) " : L"(NON-MATCH) ") + getDescription(); +} + } diff --git a/src/core/search/ConjunctionScorer.cpp b/src/core/search/ConjunctionScorer.cpp index dd33d3bb..86d9f73d 100644 --- a/src/core/search/ConjunctionScorer.cpp +++ b/src/core/search/ConjunctionScorer.cpp @@ -8,117 +8,105 @@ #include "ConjunctionScorer.h" #include "Similarity.h" -namespace Lucene -{ - struct lessScorerDocId - { - inline bool operator()(const ScorerPtr& first, const ScorerPtr& second) const - { - return (first->docID() < second->docID()); - } - }; - - ConjunctionScorer::ConjunctionScorer(const SimilarityPtr& similarity, Collection scorers) : Scorer(similarity) - { - this->lastDoc = -1; - this->scorers = scorers; - this->coord = similarity->coord(scorers.size(), scorers.size()); +namespace Lucene { - for (Collection::iterator scorer = scorers.begin(); scorer != scorers.end(); ++scorer) - { - if ((*scorer)->nextDoc() == NO_MORE_DOCS) - { - // If even one of the sub-scorers does not have any documents, this scorer should not attempt - // to do any more work. - lastDoc = NO_MORE_DOCS; - return; - } - } +struct lessScorerDocId { + inline bool operator()(const ScorerPtr& first, const ScorerPtr& second) const { + return (first->docID() < second->docID()); + } +}; - // Sort the array the first time... - // We don't need to sort the array in any future calls because we know it will already start off - // sorted (all scorers on same doc). - std::sort(scorers.begin(), scorers.end(), lessScorerDocId()); +ConjunctionScorer::ConjunctionScorer(const SimilarityPtr& similarity, Collection scorers) : Scorer(similarity) { + this->lastDoc = -1; + this->scorers = scorers; + this->coord = similarity->coord(scorers.size(), scorers.size()); - // NOTE: doNext() must be called before the re-sorting of the array later on. The reason is this: - // assume there are 5 scorers, whose first docs are 1, 2, 3, 5, 5 respectively. Sorting (above) leaves - // the array as is. Calling doNext() here advances all the first scorers to 5 (or a larger doc ID - // they all agree on). - // However, if we re-sort before doNext() is called, the order will be 5, 3, 2, 1, 5 and then doNext() - // will stop immediately, since the first scorer's docs equals the last one. So the invariant that after - // calling doNext() all scorers are on the same doc ID is broken. - if (doNext() == NO_MORE_DOCS) - { - // The scorers did not agree on any document. + for (Collection::iterator scorer = scorers.begin(); scorer != scorers.end(); ++scorer) { + if ((*scorer)->nextDoc() == NO_MORE_DOCS) { + // If even one of the sub-scorers does not have any documents, this scorer should not attempt + // to do any more work. lastDoc = NO_MORE_DOCS; return; } - - // If first-time skip distance is any predictor of scorer sparseness, then we should always try to skip - // first on those scorers. Keep last scorer in it's last place (it will be the first to be skipped on), - // but reverse all of the others so that they will be skipped on in order of original high skip. - int32_t end = scorers.size() - 1; - int32_t max = end >> 1; - for (int32_t i = 0; i < max; ++i) - { - ScorerPtr tmp(scorers[i]); - int32_t idx = end - i - 1; - scorers[i] = scorers[idx]; - scorers[idx] = tmp; - } } - ConjunctionScorer::~ConjunctionScorer() - { + // Sort the array the first time... + // We don't need to sort the array in any future calls because we know it will already start off + // sorted (all scorers on same doc). + std::sort(scorers.begin(), scorers.end(), lessScorerDocId()); + + // NOTE: doNext() must be called before the re-sorting of the array later on. The reason is this: + // assume there are 5 scorers, whose first docs are 1, 2, 3, 5, 5 respectively. Sorting (above) leaves + // the array as is. Calling doNext() here advances all the first scorers to 5 (or a larger doc ID + // they all agree on). + // However, if we re-sort before doNext() is called, the order will be 5, 3, 2, 1, 5 and then doNext() + // will stop immediately, since the first scorer's docs equals the last one. So the invariant that after + // calling doNext() all scorers are on the same doc ID is broken. + if (doNext() == NO_MORE_DOCS) { + // The scorers did not agree on any document. + lastDoc = NO_MORE_DOCS; + return; } - int32_t ConjunctionScorer::doNext() - { - int32_t first = 0; - int32_t doc = scorers[scorers.size() - 1]->docID(); - ScorerPtr firstScorer; - while ((firstScorer = scorers[first])->docID() < doc) - { - doc = firstScorer->advance(doc); - first = first == scorers.size() - 1 ? 0 : first + 1; - } - return doc; + // If first-time skip distance is any predictor of scorer sparseness, then we should always try to skip + // first on those scorers. Keep last scorer in it's last place (it will be the first to be skipped on), + // but reverse all of the others so that they will be skipped on in order of original high skip. + int32_t end = scorers.size() - 1; + int32_t max = end >> 1; + for (int32_t i = 0; i < max; ++i) { + ScorerPtr tmp(scorers[i]); + int32_t idx = end - i - 1; + scorers[i] = scorers[idx]; + scorers[idx] = tmp; } +} - int32_t ConjunctionScorer::advance(int32_t target) - { - if (lastDoc == NO_MORE_DOCS) - return lastDoc; - else if (scorers[(scorers.size() - 1)]->docID() < target) - scorers[(scorers.size() - 1)]->advance(target); - lastDoc = doNext(); - return lastDoc; +ConjunctionScorer::~ConjunctionScorer() { +} + +int32_t ConjunctionScorer::doNext() { + int32_t first = 0; + int32_t doc = scorers[scorers.size() - 1]->docID(); + ScorerPtr firstScorer; + while ((firstScorer = scorers[first])->docID() < doc) { + doc = firstScorer->advance(doc); + first = first == scorers.size() - 1 ? 0 : first + 1; } + return doc; +} - int32_t ConjunctionScorer::docID() - { +int32_t ConjunctionScorer::advance(int32_t target) { + if (lastDoc == NO_MORE_DOCS) { return lastDoc; + } else if (scorers[(scorers.size() - 1)]->docID() < target) { + scorers[(scorers.size() - 1)]->advance(target); } + lastDoc = doNext(); + return lastDoc; +} - int32_t ConjunctionScorer::nextDoc() - { - if (lastDoc == NO_MORE_DOCS) - return lastDoc; - else if (lastDoc == -1) - { - lastDoc = scorers[scorers.size() - 1]->docID(); - return lastDoc; - } - scorers[(scorers.size() - 1)]->nextDoc(); - lastDoc = doNext(); +int32_t ConjunctionScorer::docID() { + return lastDoc; +} + +int32_t ConjunctionScorer::nextDoc() { + if (lastDoc == NO_MORE_DOCS) { + return lastDoc; + } else if (lastDoc == -1) { + lastDoc = scorers[scorers.size() - 1]->docID(); return lastDoc; } + scorers[(scorers.size() - 1)]->nextDoc(); + lastDoc = doNext(); + return lastDoc; +} - double ConjunctionScorer::score() - { - double sum = 0.0; - for (Collection::iterator scorer = scorers.begin(); scorer != scorers.end(); ++scorer) - sum += (*scorer)->score(); - return sum * coord; +double ConjunctionScorer::score() { + double sum = 0.0; + for (Collection::iterator scorer = scorers.begin(); scorer != scorers.end(); ++scorer) { + sum += (*scorer)->score(); } + return sum * coord; +} + } diff --git a/src/core/search/ConstantScoreQuery.cpp b/src/core/search/ConstantScoreQuery.cpp index 0a4429df..5cfd75b9 100644 --- a/src/core/search/ConstantScoreQuery.cpp +++ b/src/core/search/ConstantScoreQuery.cpp @@ -13,169 +13,145 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - ConstantScoreQuery::ConstantScoreQuery(const FilterPtr& filter) - { - this->filter = filter; - } - - ConstantScoreQuery::~ConstantScoreQuery() - { - } +namespace Lucene { - FilterPtr ConstantScoreQuery::getFilter() - { - return filter; - } +ConstantScoreQuery::ConstantScoreQuery(const FilterPtr& filter) { + this->filter = filter; +} - QueryPtr ConstantScoreQuery::rewrite(const IndexReaderPtr& reader) - { - return shared_from_this(); - } +ConstantScoreQuery::~ConstantScoreQuery() { +} - void ConstantScoreQuery::extractTerms(SetTerm terms) - { - // OK to not add any terms when used for MultiSearcher, but may not be OK for highlighting - } +FilterPtr ConstantScoreQuery::getFilter() { + return filter; +} - WeightPtr ConstantScoreQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +QueryPtr ConstantScoreQuery::rewrite(const IndexReaderPtr& reader) { + return shared_from_this(); +} - String ConstantScoreQuery::toString(const String& field) - { - return L"ConstantScore(" + filter->toString() + (getBoost() == 1.0 ? L")" : L"^" + StringUtils::toString(getBoost())); - } +void ConstantScoreQuery::extractTerms(SetTerm terms) { + // OK to not add any terms when used for MultiSearcher, but may not be OK for highlighting +} - bool ConstantScoreQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; +WeightPtr ConstantScoreQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - ConstantScoreQueryPtr otherConstantScoreQuery(boost::dynamic_pointer_cast(other)); - if (!otherConstantScoreQuery) - return false; +String ConstantScoreQuery::toString(const String& field) { + return L"ConstantScore(" + filter->toString() + (getBoost() == 1.0 ? L")" : L"^" + StringUtils::toString(getBoost())); +} - return (this->getBoost() == otherConstantScoreQuery->getBoost() && this->filter->equals(otherConstantScoreQuery->filter)); +bool ConstantScoreQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - int32_t ConstantScoreQuery::hashCode() - { - // Simple add is OK since no existing filter hashcode has a float component. - return filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); + ConstantScoreQueryPtr otherConstantScoreQuery(boost::dynamic_pointer_cast(other)); + if (!otherConstantScoreQuery) { + return false; } - LuceneObjectPtr ConstantScoreQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(filter); - ConstantScoreQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); - cloneQuery->filter = filter; - return cloneQuery; - } + return (this->getBoost() == otherConstantScoreQuery->getBoost() && this->filter->equals(otherConstantScoreQuery->filter)); +} - ConstantWeight::ConstantWeight(const ConstantScoreQueryPtr& constantScorer, const SearcherPtr& searcher) - { - this->constantScorer = constantScorer; - this->similarity = constantScorer->getSimilarity(searcher); - this->queryNorm = 0; - this->queryWeight = 0; - } +int32_t ConstantScoreQuery::hashCode() { + // Simple add is OK since no existing filter hashcode has a float component. + return filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); +} - ConstantWeight::~ConstantWeight() - { - } +LuceneObjectPtr ConstantScoreQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(filter); + ConstantScoreQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); + cloneQuery->filter = filter; + return cloneQuery; +} - QueryPtr ConstantWeight::getQuery() - { - return constantScorer; - } +ConstantWeight::ConstantWeight(const ConstantScoreQueryPtr& constantScorer, const SearcherPtr& searcher) { + this->constantScorer = constantScorer; + this->similarity = constantScorer->getSimilarity(searcher); + this->queryNorm = 0; + this->queryWeight = 0; +} - double ConstantWeight::getValue() - { - return queryWeight; - } +ConstantWeight::~ConstantWeight() { +} - double ConstantWeight::sumOfSquaredWeights() - { - queryWeight = constantScorer->getBoost(); - return queryWeight * queryWeight; - } +QueryPtr ConstantWeight::getQuery() { + return constantScorer; +} - void ConstantWeight::normalize(double norm) - { - this->queryNorm = norm; - queryWeight *= this->queryNorm; - } +double ConstantWeight::getValue() { + return queryWeight; +} - ScorerPtr ConstantWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - return newLucene(constantScorer, similarity, reader, shared_from_this()); - } +double ConstantWeight::sumOfSquaredWeights() { + queryWeight = constantScorer->getBoost(); + return queryWeight * queryWeight; +} - ExplanationPtr ConstantWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - ConstantScorerPtr cs(newLucene(constantScorer, similarity, reader, shared_from_this())); - bool exists = (cs->docIdSetIterator->advance(doc) == doc); +void ConstantWeight::normalize(double norm) { + this->queryNorm = norm; + queryWeight *= this->queryNorm; +} - ComplexExplanationPtr result(newLucene()); +ScorerPtr ConstantWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + return newLucene(constantScorer, similarity, reader, shared_from_this()); +} - if (exists) - { - result->setDescription(L"ConstantScoreQuery(" + constantScorer->filter->toString() + L"), product of:"); - result->setValue(queryWeight); - result->setMatch(true); - result->addDetail(newLucene(constantScorer->getBoost(), L"boost")); - result->addDetail(newLucene(queryNorm, L"queryNorm")); - } - else - { - result->setDescription(L"ConstantScoreQuery(" + constantScorer->filter->toString() + L") doesn't match id " + StringUtils::toString(doc)); - result->setValue(0); - result->setMatch(false); - } - return result; +ExplanationPtr ConstantWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + ConstantScorerPtr cs(newLucene(constantScorer, similarity, reader, shared_from_this())); + bool exists = (cs->docIdSetIterator->advance(doc) == doc); + + ComplexExplanationPtr result(newLucene()); + + if (exists) { + result->setDescription(L"ConstantScoreQuery(" + constantScorer->filter->toString() + L"), product of:"); + result->setValue(queryWeight); + result->setMatch(true); + result->addDetail(newLucene(constantScorer->getBoost(), L"boost")); + result->addDetail(newLucene(queryNorm, L"queryNorm")); + } else { + result->setDescription(L"ConstantScoreQuery(" + constantScorer->filter->toString() + L") doesn't match id " + StringUtils::toString(doc)); + result->setValue(0); + result->setMatch(false); } + return result; +} - ConstantScorer::ConstantScorer(const ConstantScoreQueryPtr& constantScorer, const SimilarityPtr& similarity, const IndexReaderPtr& reader, const WeightPtr& w) : Scorer(similarity) - { - doc = -1; - theScore = w->getValue(); - DocIdSetPtr docIdSet(constantScorer->filter->getDocIdSet(reader)); - if (!docIdSet) +ConstantScorer::ConstantScorer(const ConstantScoreQueryPtr& constantScorer, const SimilarityPtr& similarity, const IndexReaderPtr& reader, const WeightPtr& w) : Scorer(similarity) { + doc = -1; + theScore = w->getValue(); + DocIdSetPtr docIdSet(constantScorer->filter->getDocIdSet(reader)); + if (!docIdSet) { + docIdSetIterator = DocIdSet::EMPTY_DOCIDSET()->iterator(); + } else { + DocIdSetIteratorPtr iter(docIdSet->iterator()); + if (!iter) { docIdSetIterator = DocIdSet::EMPTY_DOCIDSET()->iterator(); - else - { - DocIdSetIteratorPtr iter(docIdSet->iterator()); - if (!iter) - docIdSetIterator = DocIdSet::EMPTY_DOCIDSET()->iterator(); - else - docIdSetIterator = iter; + } else { + docIdSetIterator = iter; } } +} - ConstantScorer::~ConstantScorer() - { - } +ConstantScorer::~ConstantScorer() { +} - int32_t ConstantScorer::nextDoc() - { - return docIdSetIterator->nextDoc(); - } +int32_t ConstantScorer::nextDoc() { + return docIdSetIterator->nextDoc(); +} - int32_t ConstantScorer::docID() - { - return docIdSetIterator->docID(); - } +int32_t ConstantScorer::docID() { + return docIdSetIterator->docID(); +} - double ConstantScorer::score() - { - return theScore; - } +double ConstantScorer::score() { + return theScore; +} + +int32_t ConstantScorer::advance(int32_t target) { + return docIdSetIterator->advance(target); +} - int32_t ConstantScorer::advance(int32_t target) - { - return docIdSetIterator->advance(target); - } } diff --git a/src/core/search/DefaultSimilarity.cpp b/src/core/search/DefaultSimilarity.cpp index e55a75ca..da4c3db2 100644 --- a/src/core/search/DefaultSimilarity.cpp +++ b/src/core/search/DefaultSimilarity.cpp @@ -8,64 +8,55 @@ #include "DefaultSimilarity.h" #include "FieldInvertState.h" -namespace Lucene -{ - DefaultSimilarity::DefaultSimilarity() - { - discountOverlaps = false; - } +namespace Lucene { - DefaultSimilarity::~DefaultSimilarity() - { - } +DefaultSimilarity::DefaultSimilarity() { + discountOverlaps = false; +} - double DefaultSimilarity::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) - { - int32_t numTerms; - if (discountOverlaps) - numTerms = state->getLength() - state->getNumOverlap(); - else - numTerms = state->getLength(); - return (state->getBoost() * lengthNorm(fieldName, numTerms)); - } +DefaultSimilarity::~DefaultSimilarity() { +} - double DefaultSimilarity::lengthNorm(const String& fieldName, int32_t numTokens) - { - return (double)(1.0 / std::sqrt((double)numTokens)); +double DefaultSimilarity::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) { + int32_t numTerms; + if (discountOverlaps) { + numTerms = state->getLength() - state->getNumOverlap(); + } else { + numTerms = state->getLength(); } + return (state->getBoost() * lengthNorm(fieldName, numTerms)); +} - double DefaultSimilarity::queryNorm(double sumOfSquaredWeights) - { - return (double)(1.0 / std::sqrt(sumOfSquaredWeights)); - } +double DefaultSimilarity::lengthNorm(const String& fieldName, int32_t numTokens) { + return (double)(1.0 / std::sqrt((double)numTokens)); +} - double DefaultSimilarity::tf(double freq) - { - return (double)std::sqrt(freq); - } +double DefaultSimilarity::queryNorm(double sumOfSquaredWeights) { + return (double)(1.0 / std::sqrt(sumOfSquaredWeights)); +} - double DefaultSimilarity::sloppyFreq(int32_t distance) - { - return (1.0 / (double)(distance + 1)); - } +double DefaultSimilarity::tf(double freq) { + return (double)std::sqrt(freq); +} - double DefaultSimilarity::idf(int32_t docFreq, int32_t numDocs) - { - return (double)(std::log((double)numDocs / (double)(docFreq + 1)) + 1.0); - } +double DefaultSimilarity::sloppyFreq(int32_t distance) { + return (1.0 / (double)(distance + 1)); +} - double DefaultSimilarity::coord(int32_t overlap, int32_t maxOverlap) - { - return (double)overlap / (double)maxOverlap; - } +double DefaultSimilarity::idf(int32_t docFreq, int32_t numDocs) { + return (double)(std::log((double)numDocs / (double)(docFreq + 1)) + 1.0); +} - void DefaultSimilarity::setDiscountOverlaps(bool v) - { - discountOverlaps = v; - } +double DefaultSimilarity::coord(int32_t overlap, int32_t maxOverlap) { + return (double)overlap / (double)maxOverlap; +} + +void DefaultSimilarity::setDiscountOverlaps(bool v) { + discountOverlaps = v; +} + +bool DefaultSimilarity::getDiscountOverlaps() { + return discountOverlaps; +} - bool DefaultSimilarity::getDiscountOverlaps() - { - return discountOverlaps; - } } diff --git a/src/core/search/DisjunctionMaxQuery.cpp b/src/core/search/DisjunctionMaxQuery.cpp index ce778508..b35f1fe0 100644 --- a/src/core/search/DisjunctionMaxQuery.cpp +++ b/src/core/search/DisjunctionMaxQuery.cpp @@ -15,212 +15,196 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - DisjunctionMaxQuery::DisjunctionMaxQuery(double tieBreakerMultiplier) - { - this->tieBreakerMultiplier = tieBreakerMultiplier; - this->disjuncts = Collection::newInstance(); - } +namespace Lucene { - DisjunctionMaxQuery::DisjunctionMaxQuery(Collection disjuncts, double tieBreakerMultiplier) - { - this->tieBreakerMultiplier = tieBreakerMultiplier; - this->disjuncts = Collection::newInstance(); - add(disjuncts); - } +DisjunctionMaxQuery::DisjunctionMaxQuery(double tieBreakerMultiplier) { + this->tieBreakerMultiplier = tieBreakerMultiplier; + this->disjuncts = Collection::newInstance(); +} - DisjunctionMaxQuery::~DisjunctionMaxQuery() - { - } +DisjunctionMaxQuery::DisjunctionMaxQuery(Collection disjuncts, double tieBreakerMultiplier) { + this->tieBreakerMultiplier = tieBreakerMultiplier; + this->disjuncts = Collection::newInstance(); + add(disjuncts); +} - void DisjunctionMaxQuery::add(const QueryPtr& query) - { - disjuncts.add(query); - } +DisjunctionMaxQuery::~DisjunctionMaxQuery() { +} - void DisjunctionMaxQuery::add(Collection disjuncts) - { - this->disjuncts.addAll(disjuncts.begin(), disjuncts.end()); - } +void DisjunctionMaxQuery::add(const QueryPtr& query) { + disjuncts.add(query); +} - Collection::iterator DisjunctionMaxQuery::begin() - { - return disjuncts.begin(); - } +void DisjunctionMaxQuery::add(Collection disjuncts) { + this->disjuncts.addAll(disjuncts.begin(), disjuncts.end()); +} - Collection::iterator DisjunctionMaxQuery::end() - { - return disjuncts.end(); - } +Collection::iterator DisjunctionMaxQuery::begin() { + return disjuncts.begin(); +} - WeightPtr DisjunctionMaxQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +Collection::iterator DisjunctionMaxQuery::end() { + return disjuncts.end(); +} + +WeightPtr DisjunctionMaxQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - QueryPtr DisjunctionMaxQuery::rewrite(const IndexReaderPtr& reader) - { - int32_t numDisjunctions = disjuncts.size(); - if (numDisjunctions == 1) - { - QueryPtr singleton(disjuncts[0]); - QueryPtr result(singleton->rewrite(reader)); - if (getBoost() != 1.0) - { - if (result == singleton) - result = boost::dynamic_pointer_cast(result->clone()); - result->setBoost(getBoost() * result->getBoost()); +QueryPtr DisjunctionMaxQuery::rewrite(const IndexReaderPtr& reader) { + int32_t numDisjunctions = disjuncts.size(); + if (numDisjunctions == 1) { + QueryPtr singleton(disjuncts[0]); + QueryPtr result(singleton->rewrite(reader)); + if (getBoost() != 1.0) { + if (result == singleton) { + result = boost::dynamic_pointer_cast(result->clone()); } - return result; + result->setBoost(getBoost() * result->getBoost()); } - DisjunctionMaxQueryPtr clone; - for (int32_t i = 0; i < numDisjunctions; ++i) - { - QueryPtr clause(disjuncts[i]); - QueryPtr rewrite(clause->rewrite(reader)); - if (rewrite != clause) - { - if (!clone) - clone = boost::dynamic_pointer_cast(this->clone()); - clone->disjuncts[i] = rewrite; + return result; + } + DisjunctionMaxQueryPtr clone; + for (int32_t i = 0; i < numDisjunctions; ++i) { + QueryPtr clause(disjuncts[i]); + QueryPtr rewrite(clause->rewrite(reader)); + if (rewrite != clause) { + if (!clone) { + clone = boost::dynamic_pointer_cast(this->clone()); } + clone->disjuncts[i] = rewrite; } - return clone ? clone : shared_from_this(); } + return clone ? clone : shared_from_this(); +} - LuceneObjectPtr DisjunctionMaxQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); - DisjunctionMaxQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->tieBreakerMultiplier = tieBreakerMultiplier; - cloneQuery->disjuncts = Collection::newInstance(disjuncts.begin(), disjuncts.end()); - return cloneQuery; - } +LuceneObjectPtr DisjunctionMaxQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = Query::clone(other ? other : newLucene()); + DisjunctionMaxQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->tieBreakerMultiplier = tieBreakerMultiplier; + cloneQuery->disjuncts = Collection::newInstance(disjuncts.begin(), disjuncts.end()); + return cloneQuery; +} - void DisjunctionMaxQuery::extractTerms(SetTerm terms) - { - for (Collection::iterator query = disjuncts.begin(); query != disjuncts.end(); ++query) - (*query)->extractTerms(terms); +void DisjunctionMaxQuery::extractTerms(SetTerm terms) { + for (Collection::iterator query = disjuncts.begin(); query != disjuncts.end(); ++query) { + (*query)->extractTerms(terms); } +} - String DisjunctionMaxQuery::toString(const String& field) - { - String buffer(L"("); - for (Collection::iterator query = disjuncts.begin(); query != disjuncts.end(); ++query) - { - if (query != disjuncts.begin()) - buffer += L" | "; - if (boost::dynamic_pointer_cast(*query)) // wrap sub-bools in parens - buffer += L"(" + (*query)->toString(field) + L")"; - else - buffer += (*query)->toString(field); +String DisjunctionMaxQuery::toString(const String& field) { + String buffer(L"("); + for (Collection::iterator query = disjuncts.begin(); query != disjuncts.end(); ++query) { + if (query != disjuncts.begin()) { + buffer += L" | "; + } + if (boost::dynamic_pointer_cast(*query)) { // wrap sub-bools in parens + buffer += L"(" + (*query)->toString(field) + L")"; + } else { + buffer += (*query)->toString(field); } - buffer += L")"; - if (tieBreakerMultiplier != 0.0) - buffer += L"~" + StringUtils::toString(tieBreakerMultiplier); - if (getBoost() != 1.0) - buffer += L"^" + StringUtils::toString(getBoost()); - return buffer; } - - bool DisjunctionMaxQuery::equals(const LuceneObjectPtr& other) - { - if (!Query::equals(other)) - return false; - - DisjunctionMaxQueryPtr otherDisjunctionMaxQuery(boost::dynamic_pointer_cast(other)); - if (!otherDisjunctionMaxQuery) - return false; - - return (tieBreakerMultiplier == otherDisjunctionMaxQuery->tieBreakerMultiplier && disjuncts.equals(otherDisjunctionMaxQuery->disjuncts, luceneEquals())); + buffer += L")"; + if (tieBreakerMultiplier != 0.0) { + buffer += L"~" + StringUtils::toString(tieBreakerMultiplier); } - - int32_t DisjunctionMaxQuery::hashCode() - { - return MiscUtils::doubleToIntBits(getBoost()) + MiscUtils::doubleToIntBits(tieBreakerMultiplier) + MiscUtils::hashCode(disjuncts.begin(), disjuncts.end(), MiscUtils::hashLucene); + if (getBoost() != 1.0) { + buffer += L"^" + StringUtils::toString(getBoost()); } + return buffer; +} - DisjunctionMaxWeight::DisjunctionMaxWeight(const DisjunctionMaxQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = searcher->getSimilarity(); - this->weights = Collection::newInstance(); - for (Collection::iterator disjunctQuery = query->disjuncts.begin(); disjunctQuery != query->disjuncts.end(); ++disjunctQuery) - this->weights.add((*disjunctQuery)->createWeight(searcher)); +bool DisjunctionMaxQuery::equals(const LuceneObjectPtr& other) { + if (!Query::equals(other)) { + return false; } - DisjunctionMaxWeight::~DisjunctionMaxWeight() - { + DisjunctionMaxQueryPtr otherDisjunctionMaxQuery(boost::dynamic_pointer_cast(other)); + if (!otherDisjunctionMaxQuery) { + return false; } - QueryPtr DisjunctionMaxWeight::getQuery() - { - return query; - } + return (tieBreakerMultiplier == otherDisjunctionMaxQuery->tieBreakerMultiplier && disjuncts.equals(otherDisjunctionMaxQuery->disjuncts, luceneEquals())); +} - double DisjunctionMaxWeight::getValue() - { - return query->getBoost(); +int32_t DisjunctionMaxQuery::hashCode() { + return MiscUtils::doubleToIntBits(getBoost()) + MiscUtils::doubleToIntBits(tieBreakerMultiplier) + MiscUtils::hashCode(disjuncts.begin(), disjuncts.end(), MiscUtils::hashLucene); +} + +DisjunctionMaxWeight::DisjunctionMaxWeight(const DisjunctionMaxQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = searcher->getSimilarity(); + this->weights = Collection::newInstance(); + for (Collection::iterator disjunctQuery = query->disjuncts.begin(); disjunctQuery != query->disjuncts.end(); ++disjunctQuery) { + this->weights.add((*disjunctQuery)->createWeight(searcher)); } +} - double DisjunctionMaxWeight::sumOfSquaredWeights() - { - double max = 0.0; - double sum = 0.0; - for (Collection::iterator currentWeight = weights.begin(); currentWeight != weights.end(); ++currentWeight) - { - double sub = (*currentWeight)->sumOfSquaredWeights(); - sum += sub; - max = std::max(max, sub); - } - double boost = query->getBoost(); - return (((sum - max) * query->tieBreakerMultiplier * query->tieBreakerMultiplier) + max) * boost * boost; +DisjunctionMaxWeight::~DisjunctionMaxWeight() { +} + +QueryPtr DisjunctionMaxWeight::getQuery() { + return query; +} + +double DisjunctionMaxWeight::getValue() { + return query->getBoost(); +} + +double DisjunctionMaxWeight::sumOfSquaredWeights() { + double max = 0.0; + double sum = 0.0; + for (Collection::iterator currentWeight = weights.begin(); currentWeight != weights.end(); ++currentWeight) { + double sub = (*currentWeight)->sumOfSquaredWeights(); + sum += sub; + max = std::max(max, sub); } + double boost = query->getBoost(); + return (((sum - max) * query->tieBreakerMultiplier * query->tieBreakerMultiplier) + max) * boost * boost; +} - void DisjunctionMaxWeight::normalize(double norm) - { - norm *= query->getBoost(); // Incorporate our boost - for (Collection::iterator wt = weights.begin(); wt != weights.end(); ++wt) - (*wt)->normalize(norm); +void DisjunctionMaxWeight::normalize(double norm) { + norm *= query->getBoost(); // Incorporate our boost + for (Collection::iterator wt = weights.begin(); wt != weights.end(); ++wt) { + (*wt)->normalize(norm); } +} - ScorerPtr DisjunctionMaxWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - Collection scorers(Collection::newInstance(weights.size())); - int32_t idx = 0; - for (Collection::iterator wt = weights.begin(); wt != weights.end(); ++wt) - { - ScorerPtr subScorer((*wt)->scorer(reader, true, false)); - if (subScorer && subScorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) - scorers[idx++] = subScorer; +ScorerPtr DisjunctionMaxWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + Collection scorers(Collection::newInstance(weights.size())); + int32_t idx = 0; + for (Collection::iterator wt = weights.begin(); wt != weights.end(); ++wt) { + ScorerPtr subScorer((*wt)->scorer(reader, true, false)); + if (subScorer && subScorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) { + scorers[idx++] = subScorer; } - if (idx == 0) - return ScorerPtr(); // all scorers did not have documents - DisjunctionMaxScorerPtr result(newLucene(query->tieBreakerMultiplier, similarity, scorers, idx)); - return result; } + if (idx == 0) { + return ScorerPtr(); // all scorers did not have documents + } + DisjunctionMaxScorerPtr result(newLucene(query->tieBreakerMultiplier, similarity, scorers, idx)); + return result; +} - ExplanationPtr DisjunctionMaxWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - if (query->disjuncts.size() == 1) - return weights[0]->explain(reader, doc); - ComplexExplanationPtr result(newLucene()); - double max = 0.0; - double sum = 0.0; - result->setDescription(query->tieBreakerMultiplier == 0.0 ? L"max of:" : (L"max plus " + StringUtils::toString(query->tieBreakerMultiplier) + L" times others of:")); - for (Collection::iterator wt = weights.begin(); wt != weights.end(); ++wt) - { - ExplanationPtr e = (*wt)->explain(reader, doc); - if (e->isMatch()) - { - result->setMatch(true); - result->addDetail(e); - sum += e->getValue(); - max = std::max(max, e->getValue()); - } +ExplanationPtr DisjunctionMaxWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + if (query->disjuncts.size() == 1) { + return weights[0]->explain(reader, doc); + } + ComplexExplanationPtr result(newLucene()); + double max = 0.0; + double sum = 0.0; + result->setDescription(query->tieBreakerMultiplier == 0.0 ? L"max of:" : (L"max plus " + StringUtils::toString(query->tieBreakerMultiplier) + L" times others of:")); + for (Collection::iterator wt = weights.begin(); wt != weights.end(); ++wt) { + ExplanationPtr e = (*wt)->explain(reader, doc); + if (e->isMatch()) { + result->setMatch(true); + result->addDetail(e); + sum += e->getValue(); + max = std::max(max, e->getValue()); } - result->setValue(max + (sum - max) * query->tieBreakerMultiplier); - return result; } + result->setValue(max + (sum - max) * query->tieBreakerMultiplier); + return result; +} + } diff --git a/src/core/search/DisjunctionMaxScorer.cpp b/src/core/search/DisjunctionMaxScorer.cpp index b2f2200d..753dfd76 100644 --- a/src/core/search/DisjunctionMaxScorer.cpp +++ b/src/core/search/DisjunctionMaxScorer.cpp @@ -7,167 +7,139 @@ #include "LuceneInc.h" #include "DisjunctionMaxScorer.h" -namespace Lucene -{ - DisjunctionMaxScorer::DisjunctionMaxScorer(double tieBreakerMultiplier, const SimilarityPtr& similarity, Collection subScorers, int32_t numScorers) : Scorer(similarity) - { - this->doc = -1; - this->tieBreakerMultiplier = tieBreakerMultiplier; - - // The passed subScorers array includes only scorers which have documents (DisjunctionMaxQuery takes care - // of that), and their nextDoc() was already called. - this->subScorers = subScorers; - this->numScorers = numScorers; - - heapify(); - } +namespace Lucene { - DisjunctionMaxScorer::~DisjunctionMaxScorer() - { - } +DisjunctionMaxScorer::DisjunctionMaxScorer(double tieBreakerMultiplier, const SimilarityPtr& similarity, Collection subScorers, int32_t numScorers) : Scorer(similarity) { + this->doc = -1; + this->tieBreakerMultiplier = tieBreakerMultiplier; - int32_t DisjunctionMaxScorer::nextDoc() - { - if (numScorers == 0) - { - doc = NO_MORE_DOCS; - return doc; - } - while (subScorers[0]->docID() == doc) - { - if (subScorers[0]->nextDoc() != NO_MORE_DOCS) - heapAdjust(0); - else - { - heapRemoveRoot(); - if (numScorers == 0) - { - doc = NO_MORE_DOCS; - return doc; - } - } - } + // The passed subScorers array includes only scorers which have documents (DisjunctionMaxQuery takes care + // of that), and their nextDoc() was already called. + this->subScorers = subScorers; + this->numScorers = numScorers; - doc = subScorers[0]->docID(); - return doc; - } + heapify(); +} + +DisjunctionMaxScorer::~DisjunctionMaxScorer() { +} - int32_t DisjunctionMaxScorer::docID() - { +int32_t DisjunctionMaxScorer::nextDoc() { + if (numScorers == 0) { + doc = NO_MORE_DOCS; return doc; } - - double DisjunctionMaxScorer::score() - { - int32_t doc = subScorers[0]->docID(); - Collection sum(newCollection(subScorers[0]->score())); - Collection max(Collection::newInstance(sum.begin(), sum.end())); - int32_t size = numScorers; - scoreAll(1, size, doc, sum, max); - scoreAll(2, size, doc, sum, max); - return max[0] + (sum[0] - max[0]) * tieBreakerMultiplier; + while (subScorers[0]->docID() == doc) { + if (subScorers[0]->nextDoc() != NO_MORE_DOCS) { + heapAdjust(0); + } else { + heapRemoveRoot(); + if (numScorers == 0) { + doc = NO_MORE_DOCS; + return doc; + } + } } - void DisjunctionMaxScorer::scoreAll(int32_t root, int32_t size, int32_t doc, Collection sum, Collection max) - { - if (root < size && subScorers[root]->docID() == doc) - { - double sub = subScorers[root]->score(); - sum[0] += sub; - max[0] = std::max(max[0], sub); - scoreAll((root << 1) + 1, size, doc, sum, max); - scoreAll((root << 1) + 2, size, doc, sum, max); - } + doc = subScorers[0]->docID(); + return doc; +} + +int32_t DisjunctionMaxScorer::docID() { + return doc; +} + +double DisjunctionMaxScorer::score() { + int32_t doc = subScorers[0]->docID(); + Collection sum(newCollection(subScorers[0]->score())); + Collection max(Collection::newInstance(sum.begin(), sum.end())); + int32_t size = numScorers; + scoreAll(1, size, doc, sum, max); + scoreAll(2, size, doc, sum, max); + return max[0] + (sum[0] - max[0]) * tieBreakerMultiplier; +} + +void DisjunctionMaxScorer::scoreAll(int32_t root, int32_t size, int32_t doc, Collection sum, Collection max) { + if (root < size && subScorers[root]->docID() == doc) { + double sub = subScorers[root]->score(); + sum[0] += sub; + max[0] = std::max(max[0], sub); + scoreAll((root << 1) + 1, size, doc, sum, max); + scoreAll((root << 1) + 2, size, doc, sum, max); } +} - int32_t DisjunctionMaxScorer::advance(int32_t target) - { - if (numScorers == 0) - { - doc = NO_MORE_DOCS; - return doc; - } - while (subScorers[0]->docID() < target) - { - if (subScorers[0]->advance(target) != NO_MORE_DOCS) - heapAdjust(0); - else - { - heapRemoveRoot(); - if (numScorers == 0) - { - doc = NO_MORE_DOCS; - return doc; - } +int32_t DisjunctionMaxScorer::advance(int32_t target) { + if (numScorers == 0) { + doc = NO_MORE_DOCS; + return doc; + } + while (subScorers[0]->docID() < target) { + if (subScorers[0]->advance(target) != NO_MORE_DOCS) { + heapAdjust(0); + } else { + heapRemoveRoot(); + if (numScorers == 0) { + doc = NO_MORE_DOCS; + return doc; } } - doc = subScorers[0]->docID(); - return doc; } + doc = subScorers[0]->docID(); + return doc; +} - void DisjunctionMaxScorer::heapify() - { - for (int32_t i = (numScorers >> 1) - 1; i >= 0; --i) - heapAdjust(i); +void DisjunctionMaxScorer::heapify() { + for (int32_t i = (numScorers >> 1) - 1; i >= 0; --i) { + heapAdjust(i); } +} - void DisjunctionMaxScorer::heapAdjust(int32_t root) - { - ScorerPtr scorer(subScorers[root]); - int32_t doc = scorer->docID(); - int32_t i = root; - while (i <= (numScorers >> 1) - 1) - { - int32_t lchild = (i << 1) + 1; - ScorerPtr lscorer(subScorers[lchild]); - int32_t ldoc = lscorer->docID(); - int32_t rdoc = INT_MAX; - int32_t rchild = (i << 1) + 2; - ScorerPtr rscorer; - if (rchild < numScorers) - { - rscorer = subScorers[rchild]; - rdoc = rscorer->docID(); - } - if (ldoc < doc) - { - if (rdoc < ldoc) - { - subScorers[i] = rscorer; - subScorers[rchild] = scorer; - i = rchild; - } - else - { - subScorers[i] = lscorer; - subScorers[lchild] = scorer; - i = lchild; - } - } - else if (rdoc < doc) - { +void DisjunctionMaxScorer::heapAdjust(int32_t root) { + ScorerPtr scorer(subScorers[root]); + int32_t doc = scorer->docID(); + int32_t i = root; + while (i <= (numScorers >> 1) - 1) { + int32_t lchild = (i << 1) + 1; + ScorerPtr lscorer(subScorers[lchild]); + int32_t ldoc = lscorer->docID(); + int32_t rdoc = INT_MAX; + int32_t rchild = (i << 1) + 2; + ScorerPtr rscorer; + if (rchild < numScorers) { + rscorer = subScorers[rchild]; + rdoc = rscorer->docID(); + } + if (ldoc < doc) { + if (rdoc < ldoc) { subScorers[i] = rscorer; subScorers[rchild] = scorer; i = rchild; + } else { + subScorers[i] = lscorer; + subScorers[lchild] = scorer; + i = lchild; } - else - return; + } else if (rdoc < doc) { + subScorers[i] = rscorer; + subScorers[rchild] = scorer; + i = rchild; + } else { + return; } } +} - void DisjunctionMaxScorer::heapRemoveRoot() - { - if (numScorers == 1) - { - subScorers[0].reset(); - numScorers = 0; - } - else - { - subScorers[0] = subScorers[numScorers - 1]; - subScorers[numScorers - 1].reset(); - --numScorers; - heapAdjust(0); - } +void DisjunctionMaxScorer::heapRemoveRoot() { + if (numScorers == 1) { + subScorers[0].reset(); + numScorers = 0; + } else { + subScorers[0] = subScorers[numScorers - 1]; + subScorers[numScorers - 1].reset(); + --numScorers; + heapAdjust(0); } } + +} diff --git a/src/core/search/DisjunctionSumScorer.cpp b/src/core/search/DisjunctionSumScorer.cpp index 0147c611..aa786bb9 100644 --- a/src/core/search/DisjunctionSumScorer.cpp +++ b/src/core/search/DisjunctionSumScorer.cpp @@ -9,141 +9,127 @@ #include "ScorerDocQueue.h" #include "Collector.h" -namespace Lucene -{ - DisjunctionSumScorer::DisjunctionSumScorer(Collection subScorers, int32_t minimumNrMatchers) : Scorer(SimilarityPtr()) - { - this->currentDoc = -1; - this->_nrMatchers = -1; - this->currentScore = std::numeric_limits::quiet_NaN(); - - this->nrScorers = subScorers.size(); - - if (minimumNrMatchers <= 0) - boost::throw_exception(IllegalArgumentException(L"Minimum nr of matchers must be positive")); - if (nrScorers <= 1) - boost::throw_exception(IllegalArgumentException(L"There must be at least 2 subScorers")); - - this->minimumNrMatchers = minimumNrMatchers; - this->subScorers = subScorers; - } +namespace Lucene { - DisjunctionSumScorer::~DisjunctionSumScorer() - { - } +DisjunctionSumScorer::DisjunctionSumScorer(Collection subScorers, int32_t minimumNrMatchers) : Scorer(SimilarityPtr()) { + this->currentDoc = -1; + this->_nrMatchers = -1; + this->currentScore = std::numeric_limits::quiet_NaN(); + + this->nrScorers = subScorers.size(); - void DisjunctionSumScorer::initialize() - { - initScorerDocQueue(); + if (minimumNrMatchers <= 0) { + boost::throw_exception(IllegalArgumentException(L"Minimum nr of matchers must be positive")); } + if (nrScorers <= 1) { + boost::throw_exception(IllegalArgumentException(L"There must be at least 2 subScorers")); + } + + this->minimumNrMatchers = minimumNrMatchers; + this->subScorers = subScorers; +} + +DisjunctionSumScorer::~DisjunctionSumScorer() { +} + +void DisjunctionSumScorer::initialize() { + initScorerDocQueue(); +} - void DisjunctionSumScorer::initScorerDocQueue() - { - scorerDocQueue = newLucene(nrScorers); - for (Collection::iterator se = subScorers.begin(); se != subScorers.end(); ++se) - { - if ((*se)->nextDoc() != NO_MORE_DOCS) - scorerDocQueue->insert(*se); +void DisjunctionSumScorer::initScorerDocQueue() { + scorerDocQueue = newLucene(nrScorers); + for (Collection::iterator se = subScorers.begin(); se != subScorers.end(); ++se) { + if ((*se)->nextDoc() != NO_MORE_DOCS) { + scorerDocQueue->insert(*se); } } +} - void DisjunctionSumScorer::score(const CollectorPtr& collector) - { - collector->setScorer(shared_from_this()); - while (nextDoc() != NO_MORE_DOCS) - collector->collect(currentDoc); +void DisjunctionSumScorer::score(const CollectorPtr& collector) { + collector->setScorer(shared_from_this()); + while (nextDoc() != NO_MORE_DOCS) { + collector->collect(currentDoc); } +} - bool DisjunctionSumScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) - { - // firstDocID is ignored since nextDoc() sets 'currentDoc' - collector->setScorer(shared_from_this()); - while (currentDoc < max) - { - collector->collect(currentDoc); - if (nextDoc() == NO_MORE_DOCS) - return false; +bool DisjunctionSumScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { + // firstDocID is ignored since nextDoc() sets 'currentDoc' + collector->setScorer(shared_from_this()); + while (currentDoc < max) { + collector->collect(currentDoc); + if (nextDoc() == NO_MORE_DOCS) { + return false; } - return true; } + return true; +} - int32_t DisjunctionSumScorer::nextDoc() - { - if (scorerDocQueue->size() < minimumNrMatchers || !advanceAfterCurrent()) - currentDoc = NO_MORE_DOCS; - return currentDoc; +int32_t DisjunctionSumScorer::nextDoc() { + if (scorerDocQueue->size() < minimumNrMatchers || !advanceAfterCurrent()) { + currentDoc = NO_MORE_DOCS; } + return currentDoc; +} - bool DisjunctionSumScorer::advanceAfterCurrent() - { - do // repeat until minimum nr of matchers - { - currentDoc = scorerDocQueue->topDoc(); - currentScore = scorerDocQueue->topScore(); - _nrMatchers = 1; - do // Until all subscorers are after currentDoc - { - if (!scorerDocQueue->topNextAndAdjustElsePop()) - { - if (scorerDocQueue->size() == 0) - break; // nothing more to advance, check for last match. +bool DisjunctionSumScorer::advanceAfterCurrent() { + do { // repeat until minimum nr of matchers + currentDoc = scorerDocQueue->topDoc(); + currentScore = scorerDocQueue->topScore(); + _nrMatchers = 1; + do { // Until all subscorers are after currentDoc + if (!scorerDocQueue->topNextAndAdjustElsePop()) { + if (scorerDocQueue->size() == 0) { + break; // nothing more to advance, check for last match. } - if (scorerDocQueue->topDoc() != currentDoc) - break; // All remaining subscorers are after currentDoc. - currentScore += scorerDocQueue->topScore(); - ++_nrMatchers; } - while (true); - - if (_nrMatchers >= minimumNrMatchers) - return true; - else if (scorerDocQueue->size() < minimumNrMatchers) - return false; + if (scorerDocQueue->topDoc() != currentDoc) { + break; // All remaining subscorers are after currentDoc. + } + currentScore += scorerDocQueue->topScore(); + ++_nrMatchers; + } while (true); + + if (_nrMatchers >= minimumNrMatchers) { + return true; + } else if (scorerDocQueue->size() < minimumNrMatchers) { + return false; } - while (true); - } + } while (true); +} - double DisjunctionSumScorer::score() - { - return currentScore; - } +double DisjunctionSumScorer::score() { + return currentScore; +} + +int32_t DisjunctionSumScorer::docID() { + return currentDoc; +} - int32_t DisjunctionSumScorer::docID() - { +int32_t DisjunctionSumScorer::nrMatchers() { + return _nrMatchers; +} + +int32_t DisjunctionSumScorer::advance(int32_t target) { + if (scorerDocQueue->size() < minimumNrMatchers) { + currentDoc = NO_MORE_DOCS; return currentDoc; } - - int32_t DisjunctionSumScorer::nrMatchers() - { - return _nrMatchers; + if (target <= currentDoc) { + return currentDoc; } - - int32_t DisjunctionSumScorer::advance(int32_t target) - { - if (scorerDocQueue->size() < minimumNrMatchers) - { - currentDoc = NO_MORE_DOCS; - return currentDoc; - } - if (target <= currentDoc) + do { + if (scorerDocQueue->topDoc() >= target) { + if (!advanceAfterCurrent()) { + currentDoc = NO_MORE_DOCS; + } return currentDoc; - do - { - if (scorerDocQueue->topDoc() >= target) - { - if (!advanceAfterCurrent()) - currentDoc = NO_MORE_DOCS; + } else if (!scorerDocQueue->topSkipToAndAdjustElsePop(target)) { + if (scorerDocQueue->size() < minimumNrMatchers) { + currentDoc = NO_MORE_DOCS; return currentDoc; } - else if (!scorerDocQueue->topSkipToAndAdjustElsePop(target)) - { - if (scorerDocQueue->size() < minimumNrMatchers) - { - currentDoc = NO_MORE_DOCS; - return currentDoc; - } - } } - while (true); - } + } while (true); +} + } diff --git a/src/core/search/DocIdSet.cpp b/src/core/search/DocIdSet.cpp index 5ea2c6b8..28d19a07 100644 --- a/src/core/search/DocIdSet.cpp +++ b/src/core/search/DocIdSet.cpp @@ -8,58 +8,48 @@ #include "DocIdSet.h" #include "_DocIdSet.h" -namespace Lucene -{ - DocIdSet::~DocIdSet() - { - } +namespace Lucene { - bool DocIdSet::isCacheable() - { - return false; - } +DocIdSet::~DocIdSet() { +} - DocIdSetPtr DocIdSet::EMPTY_DOCIDSET() - { - static DocIdSetPtr _EMPTY_DOCIDSET; - if (!_EMPTY_DOCIDSET) - { - _EMPTY_DOCIDSET = newLucene(); - CycleCheck::addStatic(_EMPTY_DOCIDSET); - } - return _EMPTY_DOCIDSET; - } +bool DocIdSet::isCacheable() { + return false; +} - EmptyDocIdSetIterator::~EmptyDocIdSetIterator() - { +DocIdSetPtr DocIdSet::EMPTY_DOCIDSET() { + static DocIdSetPtr _EMPTY_DOCIDSET; + if (!_EMPTY_DOCIDSET) { + _EMPTY_DOCIDSET = newLucene(); + CycleCheck::addStatic(_EMPTY_DOCIDSET); } + return _EMPTY_DOCIDSET; +} - int32_t EmptyDocIdSetIterator::advance(int32_t target) - { - return NO_MORE_DOCS; - } +EmptyDocIdSetIterator::~EmptyDocIdSetIterator() { +} - int32_t EmptyDocIdSetIterator::docID() - { - return NO_MORE_DOCS; - } +int32_t EmptyDocIdSetIterator::advance(int32_t target) { + return NO_MORE_DOCS; +} - int32_t EmptyDocIdSetIterator::nextDoc() - { - return NO_MORE_DOCS; - } +int32_t EmptyDocIdSetIterator::docID() { + return NO_MORE_DOCS; +} - EmptyDocIdSet::~EmptyDocIdSet() - { - } +int32_t EmptyDocIdSetIterator::nextDoc() { + return NO_MORE_DOCS; +} - DocIdSetIteratorPtr EmptyDocIdSet::iterator() - { - return newLucene(); - } +EmptyDocIdSet::~EmptyDocIdSet() { +} + +DocIdSetIteratorPtr EmptyDocIdSet::iterator() { + return newLucene(); +} + +bool EmptyDocIdSet::isCacheable() { + return true; +} - bool EmptyDocIdSet::isCacheable() - { - return true; - } } diff --git a/src/core/search/DocIdSetIterator.cpp b/src/core/search/DocIdSetIterator.cpp index 69702039..435d5164 100644 --- a/src/core/search/DocIdSetIterator.cpp +++ b/src/core/search/DocIdSetIterator.cpp @@ -7,13 +7,13 @@ #include "LuceneInc.h" #include "DocIdSetIterator.h" -namespace Lucene -{ - /// When returned by {@link #nextDoc()}, {@link #advance(int)} and {@link #docID()} it means there - /// docs in the iterator. - const int32_t DocIdSetIterator::NO_MORE_DOCS = INT_MAX; +namespace Lucene { + +/// When returned by {@link #nextDoc()}, {@link #advance(int)} and {@link #docID()} it means there +/// docs in the iterator. +const int32_t DocIdSetIterator::NO_MORE_DOCS = INT_MAX; + +DocIdSetIterator::~DocIdSetIterator() { +} - DocIdSetIterator::~DocIdSetIterator() - { - } } diff --git a/src/core/search/ExactPhraseScorer.cpp b/src/core/search/ExactPhraseScorer.cpp index f1f56255..2304d187 100644 --- a/src/core/search/ExactPhraseScorer.cpp +++ b/src/core/search/ExactPhraseScorer.cpp @@ -9,46 +9,39 @@ #include "PhrasePositions.h" #include "PhraseQueue.h" -namespace Lucene -{ - ExactPhraseScorer::ExactPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) - { - } +namespace Lucene { + +ExactPhraseScorer::ExactPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) { +} + +ExactPhraseScorer::~ExactPhraseScorer() { +} - ExactPhraseScorer::~ExactPhraseScorer() - { +double ExactPhraseScorer::phraseFreq() { + // sort list with pq + pq->clear(); + for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) { + pp->firstPosition(); + pq->add(pp); // build pq from list } + pqToList(); // rebuild list from pq - double ExactPhraseScorer::phraseFreq() - { - // sort list with pq - pq->clear(); - for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) - { - pp->firstPosition(); - pq->add(pp); // build pq from list - } - pqToList(); // rebuild list from pq - - // For counting how many times the exact phrase is found in current document, just count how many - // times all PhrasePosition's have exactly the same position. - int32_t freq = 0; - do - { - while (first->position < last->position) // scan forward in first - { - do - { - if (!first->nextPosition()) - return freq; + // For counting how many times the exact phrase is found in current document, just count how many + // times all PhrasePosition's have exactly the same position. + int32_t freq = 0; + do { + while (first->position < last->position) { // scan forward in first + do { + if (!first->nextPosition()) { + return freq; } - while (first->position < last->position); - firstToLast(); - } - ++freq; // all equal: a match + } while (first->position < last->position); + firstToLast(); } - while (last->nextPosition()); + ++freq; // all equal: a match + } while (last->nextPosition()); + + return freq; +} - return freq; - } } diff --git a/src/core/search/Explanation.cpp b/src/core/search/Explanation.cpp index f59cd816..3c64badb 100644 --- a/src/core/search/Explanation.cpp +++ b/src/core/search/Explanation.cpp @@ -8,94 +8,84 @@ #include "Explanation.h" #include "StringUtils.h" -namespace Lucene -{ - Explanation::Explanation(double value, const String& description) - { - this->value = value; - this->description = description; - } +namespace Lucene { - Explanation::~Explanation() - { - } +Explanation::Explanation(double value, const String& description) { + this->value = value; + this->description = description; +} - bool Explanation::isMatch() - { - return (0.0 < getValue()); - } +Explanation::~Explanation() { +} - double Explanation::getValue() - { - return value; - } +bool Explanation::isMatch() { + return (0.0 < getValue()); +} - void Explanation::setValue(double value) - { - this->value = value; - } +double Explanation::getValue() { + return value; +} - String Explanation::getDescription() - { - return description; - } +void Explanation::setValue(double value) { + this->value = value; +} - void Explanation::setDescription(const String& description) - { - this->description = description; - } +String Explanation::getDescription() { + return description; +} - String Explanation::getSummary() - { - return StringUtils::toString(getValue()) + L" = " + getDescription(); - } +void Explanation::setDescription(const String& description) { + this->description = description; +} - Collection Explanation::getDetails() - { - if (!details) - return Collection(); - return Collection::newInstance(this->details.begin(), this->details.end()); - } +String Explanation::getSummary() { + return StringUtils::toString(getValue()) + L" = " + getDescription(); +} - void Explanation::addDetail(const ExplanationPtr& detail) - { - if (!details) - details = Collection::newInstance(); - details.add(detail); +Collection Explanation::getDetails() { + if (!details) { + return Collection(); } + return Collection::newInstance(this->details.begin(), this->details.end()); +} - String Explanation::toString() - { - return toString(0); +void Explanation::addDetail(const ExplanationPtr& detail) { + if (!details) { + details = Collection::newInstance(); } + details.add(detail); +} + +String Explanation::toString() { + return toString(0); +} - String Explanation::toString(int32_t depth) - { - String buffer; - for (int32_t i = 0; i < depth; ++i) - buffer += L" "; - buffer += getSummary() + L"\n"; - if (details) - { - for (int32_t i = 0; i < details.size(); ++i) - buffer += details[i]->toString(depth + 1); +String Explanation::toString(int32_t depth) { + String buffer; + for (int32_t i = 0; i < depth; ++i) { + buffer += L" "; + } + buffer += getSummary() + L"\n"; + if (details) { + for (int32_t i = 0; i < details.size(); ++i) { + buffer += details[i]->toString(depth + 1); } - return buffer; } + return buffer; +} - String Explanation::toHtml() - { - String buffer(L"
        \n
      • " + getSummary() + L"
        \n"); - if (details) - { - for (int32_t i = 0; i < details.size(); ++i) - buffer += details[i]->toHtml(); +String Explanation::toHtml() { + String buffer(L"
          \n
        • " + getSummary() + L"
          \n"); + if (details) { + for (int32_t i = 0; i < details.size(); ++i) { + buffer += details[i]->toHtml(); } - buffer += L"
        • \n
        \n"; - return buffer; } + buffer += L"
      • \n
      \n"; + return buffer; +} + +IDFExplanation::~IDFExplanation() { +} - IDFExplanation::~IDFExplanation() - { - } } diff --git a/src/core/search/FieldCache.cpp b/src/core/search/FieldCache.cpp index d5f7e59e..fab08368 100644 --- a/src/core/search/FieldCache.cpp +++ b/src/core/search/FieldCache.cpp @@ -11,351 +11,290 @@ #include "NumericUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// Indicator for StringIndex values in the cache. - const int32_t FieldCache::STRING_INDEX = -1; +namespace Lucene { - FieldCache::~FieldCache() - { - } +/// Indicator for StringIndex values in the cache. +const int32_t FieldCache::STRING_INDEX = -1; - FieldCachePtr FieldCache::DEFAULT() - { - static FieldCacheImplPtr _DEFAULT; - if (!_DEFAULT) - { - _DEFAULT = newLucene(); - CycleCheck::addStatic(_DEFAULT); - } - return _DEFAULT; - } +FieldCache::~FieldCache() { +} - ByteParserPtr FieldCache::DEFAULT_BYTE_PARSER() - { - static DefaultByteParserPtr _DEFAULT_BYTE_PARSER; - if (!_DEFAULT_BYTE_PARSER) - { - _DEFAULT_BYTE_PARSER = newLucene(); - CycleCheck::addStatic(_DEFAULT_BYTE_PARSER); - } - return _DEFAULT_BYTE_PARSER; +FieldCachePtr FieldCache::DEFAULT() { + static FieldCacheImplPtr _DEFAULT; + if (!_DEFAULT) { + _DEFAULT = newLucene(); + CycleCheck::addStatic(_DEFAULT); } + return _DEFAULT; +} - IntParserPtr FieldCache::DEFAULT_INT_PARSER() - { - static DefaultIntParserPtr _DEFAULT_INT_PARSER; - if (!_DEFAULT_INT_PARSER) - { - _DEFAULT_INT_PARSER = newLucene(); - CycleCheck::addStatic(_DEFAULT_INT_PARSER); - } - return _DEFAULT_INT_PARSER; +ByteParserPtr FieldCache::DEFAULT_BYTE_PARSER() { + static DefaultByteParserPtr _DEFAULT_BYTE_PARSER; + if (!_DEFAULT_BYTE_PARSER) { + _DEFAULT_BYTE_PARSER = newLucene(); + CycleCheck::addStatic(_DEFAULT_BYTE_PARSER); } + return _DEFAULT_BYTE_PARSER; +} - LongParserPtr FieldCache::DEFAULT_LONG_PARSER() - { - static DefaultLongParserPtr _DEFAULT_LONG_PARSER; - if (!_DEFAULT_LONG_PARSER) - { - _DEFAULT_LONG_PARSER = newLucene(); - CycleCheck::addStatic(_DEFAULT_LONG_PARSER); - } - return _DEFAULT_LONG_PARSER; +IntParserPtr FieldCache::DEFAULT_INT_PARSER() { + static DefaultIntParserPtr _DEFAULT_INT_PARSER; + if (!_DEFAULT_INT_PARSER) { + _DEFAULT_INT_PARSER = newLucene(); + CycleCheck::addStatic(_DEFAULT_INT_PARSER); } + return _DEFAULT_INT_PARSER; +} - DoubleParserPtr FieldCache::DEFAULT_DOUBLE_PARSER() - { - static DefaultDoubleParserPtr _DEFAULT_DOUBLE_PARSER; - if (!_DEFAULT_DOUBLE_PARSER) - { - _DEFAULT_DOUBLE_PARSER = newLucene(); - CycleCheck::addStatic(_DEFAULT_DOUBLE_PARSER); - } - return _DEFAULT_DOUBLE_PARSER; +LongParserPtr FieldCache::DEFAULT_LONG_PARSER() { + static DefaultLongParserPtr _DEFAULT_LONG_PARSER; + if (!_DEFAULT_LONG_PARSER) { + _DEFAULT_LONG_PARSER = newLucene(); + CycleCheck::addStatic(_DEFAULT_LONG_PARSER); } + return _DEFAULT_LONG_PARSER; +} - IntParserPtr FieldCache::NUMERIC_UTILS_INT_PARSER() - { - static NumericUtilsIntParserPtr _NUMERIC_UTILS_INT_PARSER; - if (!_NUMERIC_UTILS_INT_PARSER) - { - _NUMERIC_UTILS_INT_PARSER = newLucene(); - CycleCheck::addStatic(_NUMERIC_UTILS_INT_PARSER); - } - return _NUMERIC_UTILS_INT_PARSER; +DoubleParserPtr FieldCache::DEFAULT_DOUBLE_PARSER() { + static DefaultDoubleParserPtr _DEFAULT_DOUBLE_PARSER; + if (!_DEFAULT_DOUBLE_PARSER) { + _DEFAULT_DOUBLE_PARSER = newLucene(); + CycleCheck::addStatic(_DEFAULT_DOUBLE_PARSER); } + return _DEFAULT_DOUBLE_PARSER; +} - LongParserPtr FieldCache::NUMERIC_UTILS_LONG_PARSER() - { - static NumericUtilsLongParserPtr _NUMERIC_UTILS_LONG_PARSER; - if (!_NUMERIC_UTILS_LONG_PARSER) - { - _NUMERIC_UTILS_LONG_PARSER = newLucene(); - CycleCheck::addStatic(_NUMERIC_UTILS_LONG_PARSER); - } - return _NUMERIC_UTILS_LONG_PARSER; +IntParserPtr FieldCache::NUMERIC_UTILS_INT_PARSER() { + static NumericUtilsIntParserPtr _NUMERIC_UTILS_INT_PARSER; + if (!_NUMERIC_UTILS_INT_PARSER) { + _NUMERIC_UTILS_INT_PARSER = newLucene(); + CycleCheck::addStatic(_NUMERIC_UTILS_INT_PARSER); } + return _NUMERIC_UTILS_INT_PARSER; +} - DoubleParserPtr FieldCache::NUMERIC_UTILS_DOUBLE_PARSER() - { - static NumericUtilsDoubleParserPtr _NUMERIC_UTILS_DOUBLE_PARSER; - if (!_NUMERIC_UTILS_DOUBLE_PARSER) - { - _NUMERIC_UTILS_DOUBLE_PARSER = newLucene(); - CycleCheck::addStatic(_NUMERIC_UTILS_DOUBLE_PARSER); - } - return _NUMERIC_UTILS_DOUBLE_PARSER; +LongParserPtr FieldCache::NUMERIC_UTILS_LONG_PARSER() { + static NumericUtilsLongParserPtr _NUMERIC_UTILS_LONG_PARSER; + if (!_NUMERIC_UTILS_LONG_PARSER) { + _NUMERIC_UTILS_LONG_PARSER = newLucene(); + CycleCheck::addStatic(_NUMERIC_UTILS_LONG_PARSER); } + return _NUMERIC_UTILS_LONG_PARSER; +} - Collection FieldCache::getBytes(const IndexReaderPtr& reader, const String& field) - { - BOOST_ASSERT(false); - return Collection(); // override +DoubleParserPtr FieldCache::NUMERIC_UTILS_DOUBLE_PARSER() { + static NumericUtilsDoubleParserPtr _NUMERIC_UTILS_DOUBLE_PARSER; + if (!_NUMERIC_UTILS_DOUBLE_PARSER) { + _NUMERIC_UTILS_DOUBLE_PARSER = newLucene(); + CycleCheck::addStatic(_NUMERIC_UTILS_DOUBLE_PARSER); } + return _NUMERIC_UTILS_DOUBLE_PARSER; +} - Collection FieldCache::getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getBytes(const IndexReaderPtr& reader, const String& field) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection FieldCache::getInts(const IndexReaderPtr& reader, const String& field) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection FieldCache::getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getInts(const IndexReaderPtr& reader, const String& field) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection FieldCache::getLongs(const IndexReaderPtr& reader, const String& field) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection FieldCache::getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getLongs(const IndexReaderPtr& reader, const String& field) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection FieldCache::getDoubles(const IndexReaderPtr& reader, const String& field) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection FieldCache::getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getDoubles(const IndexReaderPtr& reader, const String& field) { + BOOST_ASSERT(false); + return Collection(); // override +} - Collection FieldCache::getStrings(const IndexReaderPtr& reader, const String& field) - { - BOOST_ASSERT(false); - return Collection(); // override - } +Collection FieldCache::getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser) { + BOOST_ASSERT(false); + return Collection(); // override +} - StringIndexPtr FieldCache::getStringIndex(const IndexReaderPtr& reader, const String& field) - { - BOOST_ASSERT(false); - return StringIndexPtr(); // override - } +Collection FieldCache::getStrings(const IndexReaderPtr& reader, const String& field) { + BOOST_ASSERT(false); + return Collection(); // override +} - void FieldCache::setInfoStream(const InfoStreamPtr& stream) - { - BOOST_ASSERT(false); - // override - } +StringIndexPtr FieldCache::getStringIndex(const IndexReaderPtr& reader, const String& field) { + BOOST_ASSERT(false); + return StringIndexPtr(); // override +} - InfoStreamPtr FieldCache::getInfoStream() - { - BOOST_ASSERT(false); - return InfoStreamPtr(); // override - } +void FieldCache::setInfoStream(const InfoStreamPtr& stream) { + BOOST_ASSERT(false); + // override +} - CreationPlaceholder::~CreationPlaceholder() - { - } +InfoStreamPtr FieldCache::getInfoStream() { + BOOST_ASSERT(false); + return InfoStreamPtr(); // override +} - StringIndex::StringIndex(Collection values, Collection lookup) - { - this->order = values; - this->lookup = lookup; - } +CreationPlaceholder::~CreationPlaceholder() { +} - StringIndex::~StringIndex() - { - } +StringIndex::StringIndex(Collection values, Collection lookup) { + this->order = values; + this->lookup = lookup; +} - int32_t StringIndex::binarySearchLookup(const String& key) - { - Collection::iterator search = std::lower_bound(lookup.begin(), lookup.end(), key); - int32_t keyPos = std::distance(lookup.begin(), search); - return (search == lookup.end() || key < *search) ? -(keyPos + 1) : keyPos; - } +StringIndex::~StringIndex() { +} - Parser::~Parser() - { - } +int32_t StringIndex::binarySearchLookup(const String& key) { + Collection::iterator search = std::lower_bound(lookup.begin(), lookup.end(), key); + int32_t keyPos = std::distance(lookup.begin(), search); + return (search == lookup.end() || key < *search) ? -(keyPos + 1) : keyPos; +} - ByteParser::~ByteParser() - { - } +Parser::~Parser() { +} - uint8_t ByteParser::parseByte(const String& string) - { - return 0; // override - } +ByteParser::~ByteParser() { +} - DefaultByteParser::~DefaultByteParser() - { - } +uint8_t ByteParser::parseByte(const String& string) { + return 0; // override +} - uint8_t DefaultByteParser::parseByte(const String& string) - { - return (uint8_t)StringUtils::toInt(string); - } +DefaultByteParser::~DefaultByteParser() { +} - String DefaultByteParser::toString() - { - return FieldCache::_getClassName() + L".DEFAULT_BYTE_PARSER"; - } +uint8_t DefaultByteParser::parseByte(const String& string) { + return (uint8_t)StringUtils::toInt(string); +} - IntParser::~IntParser() - { - } +String DefaultByteParser::toString() { + return FieldCache::_getClassName() + L".DEFAULT_BYTE_PARSER"; +} - int32_t IntParser::parseInt(const String& string) - { - return 0; // override - } +IntParser::~IntParser() { +} - DefaultIntParser::~DefaultIntParser() - { - } +int32_t IntParser::parseInt(const String& string) { + return 0; // override +} - int32_t DefaultIntParser::parseInt(const String& string) - { - return StringUtils::toInt(string); - } +DefaultIntParser::~DefaultIntParser() { +} - String DefaultIntParser::toString() - { - return FieldCache::_getClassName() + L".DEFAULT_INT_PARSER"; - } +int32_t DefaultIntParser::parseInt(const String& string) { + return StringUtils::toInt(string); +} - NumericUtilsIntParser::~NumericUtilsIntParser() - { - } +String DefaultIntParser::toString() { + return FieldCache::_getClassName() + L".DEFAULT_INT_PARSER"; +} - int32_t NumericUtilsIntParser::parseInt(const String& string) - { - int32_t shift = string[0] - NumericUtils::SHIFT_START_INT; - if (shift > 0 && shift <= 31) - boost::throw_exception(StopFillCacheException()); - return NumericUtils::prefixCodedToInt(string); - } +NumericUtilsIntParser::~NumericUtilsIntParser() { +} - String NumericUtilsIntParser::toString() - { - return FieldCache::_getClassName() + L".NUMERIC_UTILS_INT_PARSER"; +int32_t NumericUtilsIntParser::parseInt(const String& string) { + int32_t shift = string[0] - NumericUtils::SHIFT_START_INT; + if (shift > 0 && shift <= 31) { + boost::throw_exception(StopFillCacheException()); } + return NumericUtils::prefixCodedToInt(string); +} - LongParser::~LongParser() - { - } +String NumericUtilsIntParser::toString() { + return FieldCache::_getClassName() + L".NUMERIC_UTILS_INT_PARSER"; +} - int64_t LongParser::parseLong(const String& string) - { - return 0; // override - } +LongParser::~LongParser() { +} - DefaultLongParser::~DefaultLongParser() - { - } +int64_t LongParser::parseLong(const String& string) { + return 0; // override +} - int64_t DefaultLongParser::parseLong(const String& string) - { - return StringUtils::toLong(string); - } +DefaultLongParser::~DefaultLongParser() { +} - String DefaultLongParser::toString() - { - return FieldCache::_getClassName() + L".DEFAULT_LONG_PARSER"; - } +int64_t DefaultLongParser::parseLong(const String& string) { + return StringUtils::toLong(string); +} - NumericUtilsLongParser::~NumericUtilsLongParser() - { - } +String DefaultLongParser::toString() { + return FieldCache::_getClassName() + L".DEFAULT_LONG_PARSER"; +} - int64_t NumericUtilsLongParser::parseLong(const String& string) - { - int32_t shift = string[0] - NumericUtils::SHIFT_START_LONG; - if (shift > 0 && shift <= 63) - boost::throw_exception(StopFillCacheException()); - return NumericUtils::prefixCodedToLong(string); - } +NumericUtilsLongParser::~NumericUtilsLongParser() { +} - String NumericUtilsLongParser::toString() - { - return FieldCache::_getClassName() + L".NUMERIC_UTILS_LONG_PARSER"; +int64_t NumericUtilsLongParser::parseLong(const String& string) { + int32_t shift = string[0] - NumericUtils::SHIFT_START_LONG; + if (shift > 0 && shift <= 63) { + boost::throw_exception(StopFillCacheException()); } + return NumericUtils::prefixCodedToLong(string); +} - DoubleParser::~DoubleParser() - { - } +String NumericUtilsLongParser::toString() { + return FieldCache::_getClassName() + L".NUMERIC_UTILS_LONG_PARSER"; +} - double DoubleParser::parseDouble(const String& string) - { - return 0; // override - } +DoubleParser::~DoubleParser() { +} - DefaultDoubleParser::~DefaultDoubleParser() - { - } +double DoubleParser::parseDouble(const String& string) { + return 0; // override +} - double DefaultDoubleParser::parseDouble(const String& string) - { - return StringUtils::toDouble(string); - } +DefaultDoubleParser::~DefaultDoubleParser() { +} - String DefaultDoubleParser::toString() - { - return FieldCache::_getClassName() + L".DEFAULT_DOUBLE_PARSER"; - } +double DefaultDoubleParser::parseDouble(const String& string) { + return StringUtils::toDouble(string); +} - NumericUtilsDoubleParser::~NumericUtilsDoubleParser() - { - } +String DefaultDoubleParser::toString() { + return FieldCache::_getClassName() + L".DEFAULT_DOUBLE_PARSER"; +} - double NumericUtilsDoubleParser::parseDouble(const String& string) - { - int32_t shift = string[0] - NumericUtils::SHIFT_START_LONG; - if (shift > 0 && shift <= 63) - boost::throw_exception(StopFillCacheException()); - return NumericUtils::sortableLongToDouble(NumericUtils::prefixCodedToLong(string)); - } +NumericUtilsDoubleParser::~NumericUtilsDoubleParser() { +} - String NumericUtilsDoubleParser::toString() - { - return FieldCache::_getClassName() + L".NUMERIC_UTILS_DOUBLE_PARSER"; +double NumericUtilsDoubleParser::parseDouble(const String& string) { + int32_t shift = string[0] - NumericUtils::SHIFT_START_LONG; + if (shift > 0 && shift <= 63) { + boost::throw_exception(StopFillCacheException()); } + return NumericUtils::sortableLongToDouble(NumericUtils::prefixCodedToLong(string)); +} - FieldCacheEntry::~FieldCacheEntry() - { - } +String NumericUtilsDoubleParser::toString() { + return FieldCache::_getClassName() + L".NUMERIC_UTILS_DOUBLE_PARSER"; +} + +FieldCacheEntry::~FieldCacheEntry() { +} + +String FieldCacheEntry::toString() { + StringStream buffer; + buffer << L"'" << getReaderKey()->toString() << L"'=>" << getFieldName() << L"'," << getCacheType(); + return buffer.str(); +} - String FieldCacheEntry::toString() - { - StringStream buffer; - buffer << L"'" << getReaderKey()->toString() << L"'=>" << getFieldName() << L"'," << getCacheType(); - return buffer.str(); - } } diff --git a/src/core/search/FieldCacheImpl.cpp b/src/core/search/FieldCacheImpl.cpp index 74477b0c..aabcbff9 100644 --- a/src/core/search/FieldCacheImpl.cpp +++ b/src/core/search/FieldCacheImpl.cpp @@ -15,603 +15,511 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - FieldCacheImpl::FieldCacheImpl() - { - } +namespace Lucene { - FieldCacheImpl::~FieldCacheImpl() - { - } +FieldCacheImpl::FieldCacheImpl() { +} - void FieldCacheImpl::initialize() - { - caches = MapStringCache::newInstance(); - caches.put(CACHE_BYTE, newLucene(shared_from_this())); - caches.put(CACHE_INT, newLucene(shared_from_this())); - caches.put(CACHE_LONG, newLucene(shared_from_this())); - caches.put(CACHE_DOUBLE, newLucene(shared_from_this())); - caches.put(CACHE_STRING, newLucene(shared_from_this())); - caches.put(CACHE_STRING_INDEX, newLucene(shared_from_this())); - } +FieldCacheImpl::~FieldCacheImpl() { +} - void FieldCacheImpl::purgeAllCaches() - { - initialize(); - } +void FieldCacheImpl::initialize() { + caches = MapStringCache::newInstance(); + caches.put(CACHE_BYTE, newLucene(shared_from_this())); + caches.put(CACHE_INT, newLucene(shared_from_this())); + caches.put(CACHE_LONG, newLucene(shared_from_this())); + caches.put(CACHE_DOUBLE, newLucene(shared_from_this())); + caches.put(CACHE_STRING, newLucene(shared_from_this())); + caches.put(CACHE_STRING_INDEX, newLucene(shared_from_this())); +} - void FieldCacheImpl::purge(const IndexReaderPtr& r) - { - for (MapStringCache::iterator cache = caches.begin(); cache != caches.end(); ++cache) - cache->second->purge(r); +void FieldCacheImpl::purgeAllCaches() { + initialize(); +} + +void FieldCacheImpl::purge(const IndexReaderPtr& r) { + for (MapStringCache::iterator cache = caches.begin(); cache != caches.end(); ++cache) { + cache->second->purge(r); } +} - Collection FieldCacheImpl::getCacheEntries() - { - Collection result(Collection::newInstance()); - for (MapStringCache::iterator cache = caches.begin(); cache != caches.end(); ++cache) - { - for (WeakMapLuceneObjectMapEntryAny::iterator key = cache->second->readerCache.begin(); key != cache->second->readerCache.end(); ++key) - { - LuceneObjectPtr readerKey(key->first.lock()); +Collection FieldCacheImpl::getCacheEntries() { + Collection result(Collection::newInstance()); + for (MapStringCache::iterator cache = caches.begin(); cache != caches.end(); ++cache) { + for (WeakMapLuceneObjectMapEntryAny::iterator key = cache->second->readerCache.begin(); key != cache->second->readerCache.end(); ++key) { + LuceneObjectPtr readerKey(key->first.lock()); - // we've now materialized a hard ref - if (readerKey) - { - for (MapEntryAny::iterator mapEntry = key->second.begin(); mapEntry != key->second.end(); ++mapEntry) - result.add(newLucene(readerKey, mapEntry->first->field, cache->first, mapEntry->first->custom, mapEntry->second)); + // we've now materialized a hard ref + if (readerKey) { + for (MapEntryAny::iterator mapEntry = key->second.begin(); mapEntry != key->second.end(); ++mapEntry) { + result.add(newLucene(readerKey, mapEntry->first->field, cache->first, mapEntry->first->custom, mapEntry->second)); } } } - return result; } + return result; +} - Collection FieldCacheImpl::getBytes(const IndexReaderPtr& reader, const String& field) - { - return getBytes(reader, field, ByteParserPtr()); - } +Collection FieldCacheImpl::getBytes(const IndexReaderPtr& reader, const String& field) { + return getBytes(reader, field, ByteParserPtr()); +} - Collection FieldCacheImpl::getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser) - { - return VariantUtils::get< Collection >(caches.get(CACHE_BYTE)->get(reader, newLucene(field, parser))); - } +Collection FieldCacheImpl::getBytes(const IndexReaderPtr& reader, const String& field, const ByteParserPtr& parser) { + return VariantUtils::get< Collection >(caches.get(CACHE_BYTE)->get(reader, newLucene(field, parser))); +} - Collection FieldCacheImpl::getInts(const IndexReaderPtr& reader, const String& field) - { - return getInts(reader, field, IntParserPtr()); - } +Collection FieldCacheImpl::getInts(const IndexReaderPtr& reader, const String& field) { + return getInts(reader, field, IntParserPtr()); +} - Collection FieldCacheImpl::getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser) - { - return VariantUtils::get< Collection >(caches.get(CACHE_INT)->get(reader, newLucene(field, parser))); - } +Collection FieldCacheImpl::getInts(const IndexReaderPtr& reader, const String& field, const IntParserPtr& parser) { + return VariantUtils::get< Collection >(caches.get(CACHE_INT)->get(reader, newLucene(field, parser))); +} - Collection FieldCacheImpl::getLongs(const IndexReaderPtr& reader, const String& field) - { - return getLongs(reader, field, LongParserPtr()); - } +Collection FieldCacheImpl::getLongs(const IndexReaderPtr& reader, const String& field) { + return getLongs(reader, field, LongParserPtr()); +} - Collection FieldCacheImpl::getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser) - { - return VariantUtils::get< Collection >(caches.get(CACHE_LONG)->get(reader, newLucene(field, parser))); - } +Collection FieldCacheImpl::getLongs(const IndexReaderPtr& reader, const String& field, const LongParserPtr& parser) { + return VariantUtils::get< Collection >(caches.get(CACHE_LONG)->get(reader, newLucene(field, parser))); +} - Collection FieldCacheImpl::getDoubles(const IndexReaderPtr& reader, const String& field) - { - return getDoubles(reader, field, DoubleParserPtr()); - } +Collection FieldCacheImpl::getDoubles(const IndexReaderPtr& reader, const String& field) { + return getDoubles(reader, field, DoubleParserPtr()); +} - Collection FieldCacheImpl::getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser) - { - return VariantUtils::get< Collection >(caches.get(CACHE_DOUBLE)->get(reader, newLucene(field, parser))); - } +Collection FieldCacheImpl::getDoubles(const IndexReaderPtr& reader, const String& field, const DoubleParserPtr& parser) { + return VariantUtils::get< Collection >(caches.get(CACHE_DOUBLE)->get(reader, newLucene(field, parser))); +} - Collection FieldCacheImpl::getStrings(const IndexReaderPtr& reader, const String& field) - { - return VariantUtils::get< Collection >(caches.get(CACHE_STRING)->get(reader, newLucene(field, ParserPtr()))); - } +Collection FieldCacheImpl::getStrings(const IndexReaderPtr& reader, const String& field) { + return VariantUtils::get< Collection >(caches.get(CACHE_STRING)->get(reader, newLucene(field, ParserPtr()))); +} - StringIndexPtr FieldCacheImpl::getStringIndex(const IndexReaderPtr& reader, const String& field) - { - return VariantUtils::get< StringIndexPtr >(caches.get(CACHE_STRING_INDEX)->get(reader, newLucene(field, ParserPtr()))); - } +StringIndexPtr FieldCacheImpl::getStringIndex(const IndexReaderPtr& reader, const String& field) { + return VariantUtils::get< StringIndexPtr >(caches.get(CACHE_STRING_INDEX)->get(reader, newLucene(field, ParserPtr()))); +} - void FieldCacheImpl::setInfoStream(const InfoStreamPtr& stream) - { - infoStream = stream; - } +void FieldCacheImpl::setInfoStream(const InfoStreamPtr& stream) { + infoStream = stream; +} - InfoStreamPtr FieldCacheImpl::getInfoStream() - { - return infoStream; - } +InfoStreamPtr FieldCacheImpl::getInfoStream() { + return infoStream; +} - Entry::Entry(const String& field, const boost::any& custom) - { - this->field = field; - this->custom = custom; - } +Entry::Entry(const String& field, const boost::any& custom) { + this->field = field; + this->custom = custom; +} - Entry::~Entry() - { +Entry::~Entry() { +} + +bool Entry::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - bool Entry::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - - EntryPtr otherEntry(boost::dynamic_pointer_cast(other)); - if (otherEntry) - { - if (otherEntry->field == field) - return VariantUtils::equalsType(custom, otherEntry->custom); + EntryPtr otherEntry(boost::dynamic_pointer_cast(other)); + if (otherEntry) { + if (otherEntry->field == field) { + return VariantUtils::equalsType(custom, otherEntry->custom); } - return false; } + return false; +} - int32_t Entry::hashCode() - { - return StringUtils::hashCode(field) ^ VariantUtils::hashCode(custom); - } +int32_t Entry::hashCode() { + return StringUtils::hashCode(field) ^ VariantUtils::hashCode(custom); +} - Cache::Cache(const FieldCachePtr& wrapper) - { - this->_wrapper = wrapper; - this->readerCache = WeakMapLuceneObjectMapEntryAny::newInstance(); - } +Cache::Cache(const FieldCachePtr& wrapper) { + this->_wrapper = wrapper; + this->readerCache = WeakMapLuceneObjectMapEntryAny::newInstance(); +} - Cache::~Cache() - { - } +Cache::~Cache() { +} - void Cache::purge(const IndexReaderPtr& r) +void Cache::purge(const IndexReaderPtr& r) { + LuceneObjectPtr readerKey(r->getFieldCacheKey()); + SyncLock cacheLock(&readerCache); + readerCache.remove(readerKey); +} + +boost::any Cache::get(const IndexReaderPtr& reader, const EntryPtr& key) { + MapEntryAny innerCache; + boost::any value; + LuceneObjectPtr readerKey(reader->getFieldCacheKey()); { - LuceneObjectPtr readerKey(r->getFieldCacheKey()); SyncLock cacheLock(&readerCache); - readerCache.remove(readerKey); + innerCache = readerCache.get(readerKey); + if (!innerCache) { + innerCache = MapEntryAny::newInstance(); + readerCache.put(readerKey, innerCache); + } else if (innerCache.contains(key)) { + value = innerCache[key]; + } + if (VariantUtils::isNull(value)) { + value = newLucene(); + innerCache.put(key, value); + } } - - boost::any Cache::get(const IndexReaderPtr& reader, const EntryPtr& key) - { - MapEntryAny innerCache; - boost::any value; - LuceneObjectPtr readerKey(reader->getFieldCacheKey()); - { - SyncLock cacheLock(&readerCache); - innerCache = readerCache.get(readerKey); - if (!innerCache) - { - innerCache = MapEntryAny::newInstance(); - readerCache.put(readerKey, innerCache); - } - else if (innerCache.contains(key)) - value = innerCache[key]; - if (VariantUtils::isNull(value)) + if (VariantUtils::typeOf(value)) { + CreationPlaceholderPtr progress(VariantUtils::get(value)); + SyncLock valueLock(progress); + if (VariantUtils::isNull(progress->value)) { + progress->value = createValue(reader, key); { - value = newLucene(); - innerCache.put(key, value); + SyncLock cacheLock(&readerCache); + innerCache.put(key, progress->value); } - } - if (VariantUtils::typeOf(value)) - { - CreationPlaceholderPtr progress(VariantUtils::get(value)); - SyncLock valueLock(progress); - if (VariantUtils::isNull(progress->value)) - { - progress->value = createValue(reader, key); - { - SyncLock cacheLock(&readerCache); - innerCache.put(key, progress->value); - } - FieldCachePtr wrapper(_wrapper); + FieldCachePtr wrapper(_wrapper); - // Only check if key.custom (the parser) is non-null; else, we check twice for a single - // call to FieldCache.getXXX - if (!VariantUtils::isNull(key->custom) && wrapper) - { - InfoStreamPtr infoStream(wrapper->getInfoStream()); - if (infoStream) - printNewInsanity(infoStream, progress->value); + // Only check if key.custom (the parser) is non-null; else, we check twice for a single + // call to FieldCache.getXXX + if (!VariantUtils::isNull(key->custom) && wrapper) { + InfoStreamPtr infoStream(wrapper->getInfoStream()); + if (infoStream) { + printNewInsanity(infoStream, progress->value); } } - return progress->value; } - return value; + return progress->value; } + return value; +} - void Cache::printNewInsanity(const InfoStreamPtr& infoStream, const boost::any& value) - { - Collection insanities(FieldCacheSanityChecker::checkSanity(FieldCachePtr(_wrapper))); - for (Collection::iterator insanity = insanities.begin(); insanity != insanities.end(); ++insanity) - { - Collection entries((*insanity)->getCacheEntries()); - for (Collection::iterator entry = entries.begin(); entry != entries.end(); ++entry) - { - if (VariantUtils::equalsType((*entry)->getValue(), value)) - { - // OK this insanity involves our entry - *infoStream << L"WARNING: new FieldCache insanity created\nDetails: " + (*insanity)->toString() << L"\n"; - break; - } +void Cache::printNewInsanity(const InfoStreamPtr& infoStream, const boost::any& value) { + Collection insanities(FieldCacheSanityChecker::checkSanity(FieldCachePtr(_wrapper))); + for (Collection::iterator insanity = insanities.begin(); insanity != insanities.end(); ++insanity) { + Collection entries((*insanity)->getCacheEntries()); + for (Collection::iterator entry = entries.begin(); entry != entries.end(); ++entry) { + if (VariantUtils::equalsType((*entry)->getValue(), value)) { + // OK this insanity involves our entry + *infoStream << L"WARNING: new FieldCache insanity created\nDetails: " + (*insanity)->toString() << L"\n"; + break; } } } +} - ByteCache::ByteCache(const FieldCachePtr& wrapper) : Cache(wrapper) - { - } +ByteCache::ByteCache(const FieldCachePtr& wrapper) : Cache(wrapper) { +} - ByteCache::~ByteCache() - { - } +ByteCache::~ByteCache() { +} - boost::any ByteCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) - { - EntryPtr entry(key); - String field(entry->field); - ByteParserPtr parser(VariantUtils::get(entry->custom)); - if (!parser) - return FieldCachePtr(_wrapper)->getBytes(reader, field, FieldCache::DEFAULT_BYTE_PARSER()); - Collection retArray(Collection::newInstance(reader->maxDoc())); - TermDocsPtr termDocs(reader->termDocs()); - TermEnumPtr termEnum(reader->terms(newLucene(field))); - LuceneException finally; - try - { - do - { - TermPtr term(termEnum->term()); - if (!term || term->field() != field) - break; - uint8_t termval = parser->parseByte(term->text()); - termDocs->seek(termEnum); - while (termDocs->next()) - retArray[termDocs->doc()] = termval; +boost::any ByteCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { + EntryPtr entry(key); + String field(entry->field); + ByteParserPtr parser(VariantUtils::get(entry->custom)); + if (!parser) { + return FieldCachePtr(_wrapper)->getBytes(reader, field, FieldCache::DEFAULT_BYTE_PARSER()); + } + Collection retArray(Collection::newInstance(reader->maxDoc())); + TermDocsPtr termDocs(reader->termDocs()); + TermEnumPtr termEnum(reader->terms(newLucene(field))); + LuceneException finally; + try { + do { + TermPtr term(termEnum->term()); + if (!term || term->field() != field) { + break; } - while (termEnum->next()); - } - catch (StopFillCacheException&) - { - } - catch (LuceneException& e) - { - finally = e; - } - termDocs->close(); - termEnum->close(); - finally.throwException(); - return retArray; - } + uint8_t termval = parser->parseByte(term->text()); + termDocs->seek(termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; + } + } while (termEnum->next()); + } catch (StopFillCacheException&) { + } catch (LuceneException& e) { + finally = e; + } + termDocs->close(); + termEnum->close(); + finally.throwException(); + return retArray; +} - IntCache::IntCache(const FieldCachePtr& wrapper) : Cache(wrapper) - { - } +IntCache::IntCache(const FieldCachePtr& wrapper) : Cache(wrapper) { +} - IntCache::~IntCache() - { - } +IntCache::~IntCache() { +} - boost::any IntCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) - { - EntryPtr entry(key); - String field(entry->field); - IntParserPtr parser(VariantUtils::get(entry->custom)); - if (!parser) - { - FieldCachePtr wrapper(_wrapper); - boost::any ints; - try - { - ints = wrapper->getInts(reader, field, FieldCache::DEFAULT_INT_PARSER()); +boost::any IntCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { + EntryPtr entry(key); + String field(entry->field); + IntParserPtr parser(VariantUtils::get(entry->custom)); + if (!parser) { + FieldCachePtr wrapper(_wrapper); + boost::any ints; + try { + ints = wrapper->getInts(reader, field, FieldCache::DEFAULT_INT_PARSER()); + } catch (NumberFormatException&) { + ints = wrapper->getInts(reader, field, FieldCache::NUMERIC_UTILS_INT_PARSER()); + } + return ints; + } + Collection retArray; + TermDocsPtr termDocs(reader->termDocs()); + TermEnumPtr termEnum(reader->terms(newLucene(field))); + LuceneException finally; + try { + do { + TermPtr term(termEnum->term()); + if (!term || term->field() != field) { + break; } - catch (NumberFormatException&) - { - ints = wrapper->getInts(reader, field, FieldCache::NUMERIC_UTILS_INT_PARSER()); + int32_t termval = parser->parseInt(term->text()); + if (!retArray) { // late init + retArray = Collection::newInstance(reader->maxDoc()); } - return ints; - } - Collection retArray; - TermDocsPtr termDocs(reader->termDocs()); - TermEnumPtr termEnum(reader->terms(newLucene(field))); - LuceneException finally; - try - { - do - { - TermPtr term(termEnum->term()); - if (!term || term->field() != field) - break; - int32_t termval = parser->parseInt(term->text()); - if (!retArray) // late init - retArray = Collection::newInstance(reader->maxDoc()); - termDocs->seek(termEnum); - while (termDocs->next()) - retArray[termDocs->doc()] = termval; + termDocs->seek(termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; } - while (termEnum->next()); - } - catch (StopFillCacheException&) - { - } - catch (LuceneException& e) - { - finally = e; - } - termDocs->close(); - termEnum->close(); - finally.throwException(); - if (!retArray) // no values - retArray = Collection::newInstance(reader->maxDoc()); - return retArray; - } + } while (termEnum->next()); + } catch (StopFillCacheException&) { + } catch (LuceneException& e) { + finally = e; + } + termDocs->close(); + termEnum->close(); + finally.throwException(); + if (!retArray) { // no values + retArray = Collection::newInstance(reader->maxDoc()); + } + return retArray; +} - LongCache::LongCache(const FieldCachePtr& wrapper) : Cache(wrapper) - { - } +LongCache::LongCache(const FieldCachePtr& wrapper) : Cache(wrapper) { +} - LongCache::~LongCache() - { - } +LongCache::~LongCache() { +} - boost::any LongCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) - { - EntryPtr entry(key); - String field(entry->field); - LongParserPtr parser(VariantUtils::get(entry->custom)); - if (!parser) - { - FieldCachePtr wrapper(_wrapper); - boost::any longs; - try - { - longs = wrapper->getLongs(reader, field, FieldCache::DEFAULT_LONG_PARSER()); +boost::any LongCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { + EntryPtr entry(key); + String field(entry->field); + LongParserPtr parser(VariantUtils::get(entry->custom)); + if (!parser) { + FieldCachePtr wrapper(_wrapper); + boost::any longs; + try { + longs = wrapper->getLongs(reader, field, FieldCache::DEFAULT_LONG_PARSER()); + } catch (NumberFormatException&) { + longs = wrapper->getLongs(reader, field, FieldCache::NUMERIC_UTILS_LONG_PARSER()); + } + return longs; + } + Collection retArray; + TermDocsPtr termDocs(reader->termDocs()); + TermEnumPtr termEnum(reader->terms(newLucene(field))); + LuceneException finally; + try { + do { + TermPtr term(termEnum->term()); + if (!term || term->field() != field) { + break; } - catch (NumberFormatException&) - { - longs = wrapper->getLongs(reader, field, FieldCache::NUMERIC_UTILS_LONG_PARSER()); + int64_t termval = parser->parseLong(term->text()); + if (!retArray) { // late init + retArray = Collection::newInstance(reader->maxDoc()); } - return longs; - } - Collection retArray; - TermDocsPtr termDocs(reader->termDocs()); - TermEnumPtr termEnum(reader->terms(newLucene(field))); - LuceneException finally; - try - { - do - { - TermPtr term(termEnum->term()); - if (!term || term->field() != field) - break; - int64_t termval = parser->parseLong(term->text()); - if (!retArray) // late init - retArray = Collection::newInstance(reader->maxDoc()); - termDocs->seek(termEnum); - while (termDocs->next()) - retArray[termDocs->doc()] = termval; + termDocs->seek(termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; } - while (termEnum->next()); - } - catch (StopFillCacheException&) - { - } - catch (LuceneException& e) - { - finally = e; - } - termDocs->close(); - termEnum->close(); - finally.throwException(); - if (!retArray) // no values - retArray = Collection::newInstance(reader->maxDoc()); - return retArray; - } + } while (termEnum->next()); + } catch (StopFillCacheException&) { + } catch (LuceneException& e) { + finally = e; + } + termDocs->close(); + termEnum->close(); + finally.throwException(); + if (!retArray) { // no values + retArray = Collection::newInstance(reader->maxDoc()); + } + return retArray; +} - DoubleCache::DoubleCache(const FieldCachePtr& wrapper) : Cache(wrapper) - { - } +DoubleCache::DoubleCache(const FieldCachePtr& wrapper) : Cache(wrapper) { +} - DoubleCache::~DoubleCache() - { - } +DoubleCache::~DoubleCache() { +} - boost::any DoubleCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) - { - EntryPtr entry(key); - String field(entry->field); - DoubleParserPtr parser(VariantUtils::get(entry->custom)); - if (!parser) - { - FieldCachePtr wrapper(_wrapper); - boost::any doubles; - try - { - doubles = wrapper->getDoubles(reader, field, FieldCache::DEFAULT_DOUBLE_PARSER()); +boost::any DoubleCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { + EntryPtr entry(key); + String field(entry->field); + DoubleParserPtr parser(VariantUtils::get(entry->custom)); + if (!parser) { + FieldCachePtr wrapper(_wrapper); + boost::any doubles; + try { + doubles = wrapper->getDoubles(reader, field, FieldCache::DEFAULT_DOUBLE_PARSER()); + } catch (NumberFormatException&) { + doubles = wrapper->getDoubles(reader, field, FieldCache::NUMERIC_UTILS_DOUBLE_PARSER()); + } + return doubles; + } + Collection retArray; + TermDocsPtr termDocs(reader->termDocs()); + TermEnumPtr termEnum(reader->terms(newLucene(field))); + LuceneException finally; + try { + do { + TermPtr term(termEnum->term()); + if (!term || term->field() != field) { + break; } - catch (NumberFormatException&) - { - doubles = wrapper->getDoubles(reader, field, FieldCache::NUMERIC_UTILS_DOUBLE_PARSER()); + double termval = parser->parseDouble(term->text()); + if (!retArray) { // late init + retArray = Collection::newInstance(reader->maxDoc()); } - return doubles; - } - Collection retArray; - TermDocsPtr termDocs(reader->termDocs()); - TermEnumPtr termEnum(reader->terms(newLucene(field))); - LuceneException finally; - try - { - do - { - TermPtr term(termEnum->term()); - if (!term || term->field() != field) - break; - double termval = parser->parseDouble(term->text()); - if (!retArray) // late init - retArray = Collection::newInstance(reader->maxDoc()); - termDocs->seek(termEnum); - while (termDocs->next()) - retArray[termDocs->doc()] = termval; + termDocs->seek(termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; } - while (termEnum->next()); - } - catch (StopFillCacheException&) - { - } - catch (LuceneException& e) - { - finally = e; - } - termDocs->close(); - termEnum->close(); - finally.throwException(); - if (!retArray) // no values - retArray = Collection::newInstance(reader->maxDoc()); - return retArray; - } + } while (termEnum->next()); + } catch (StopFillCacheException&) { + } catch (LuceneException& e) { + finally = e; + } + termDocs->close(); + termEnum->close(); + finally.throwException(); + if (!retArray) { // no values + retArray = Collection::newInstance(reader->maxDoc()); + } + return retArray; +} - StringCache::StringCache(const FieldCachePtr& wrapper) : Cache(wrapper) - { - } +StringCache::StringCache(const FieldCachePtr& wrapper) : Cache(wrapper) { +} - StringCache::~StringCache() - { - } +StringCache::~StringCache() { +} - boost::any StringCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) - { - EntryPtr entry(key); - String field(entry->field); - Collection retArray(Collection::newInstance(reader->maxDoc())); - TermDocsPtr termDocs(reader->termDocs()); - TermEnumPtr termEnum(reader->terms(newLucene(field))); - LuceneException finally; - try - { - do - { - TermPtr term(termEnum->term()); - if (!term || term->field() != field) - break; - String termval(term->text()); - termDocs->seek(termEnum); - while (termDocs->next()) - retArray[termDocs->doc()] = termval; +boost::any StringCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { + EntryPtr entry(key); + String field(entry->field); + Collection retArray(Collection::newInstance(reader->maxDoc())); + TermDocsPtr termDocs(reader->termDocs()); + TermEnumPtr termEnum(reader->terms(newLucene(field))); + LuceneException finally; + try { + do { + TermPtr term(termEnum->term()); + if (!term || term->field() != field) { + break; } - while (termEnum->next()); - } - catch (LuceneException& e) - { - finally = e; - } - termDocs->close(); - termEnum->close(); - finally.throwException(); - return retArray; - } - - StringIndexCache::StringIndexCache(const FieldCachePtr& wrapper) : Cache(wrapper) - { - } + String termval(term->text()); + termDocs->seek(termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; + } + } while (termEnum->next()); + } catch (LuceneException& e) { + finally = e; + } + termDocs->close(); + termEnum->close(); + finally.throwException(); + return retArray; +} - StringIndexCache::~StringIndexCache() - { - } +StringIndexCache::StringIndexCache(const FieldCachePtr& wrapper) : Cache(wrapper) { +} - boost::any StringIndexCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) - { - EntryPtr entry(key); - String field(entry->field); - Collection retArray(Collection::newInstance(reader->maxDoc())); - Collection mterms(Collection::newInstance(reader->maxDoc() + 1)); - TermDocsPtr termDocs(reader->termDocs()); - TermEnumPtr termEnum(reader->terms(newLucene(field))); - int32_t t = 0; // current term number - - // an entry for documents that have no terms in this field should a document with no terms be at - // top or bottom? This puts them at the top - if it is changed, FieldDocSortedHitQueue needs to - // change as well. - mterms[t++] = L""; - - LuceneException finally; - try - { - do - { - TermPtr term(termEnum->term()); - if (!term || term->field() != field || t >= mterms.size() ) - break; +StringIndexCache::~StringIndexCache() { +} - // store term text - mterms[t] = term->text(); +boost::any StringIndexCache::createValue(const IndexReaderPtr& reader, const EntryPtr& key) { + EntryPtr entry(key); + String field(entry->field); + Collection retArray(Collection::newInstance(reader->maxDoc())); + Collection mterms(Collection::newInstance(reader->maxDoc() + 1)); + TermDocsPtr termDocs(reader->termDocs()); + TermEnumPtr termEnum(reader->terms(newLucene(field))); + int32_t t = 0; // current term number + + // an entry for documents that have no terms in this field should a document with no terms be at + // top or bottom? This puts them at the top - if it is changed, FieldDocSortedHitQueue needs to + // change as well. + mterms[t++] = L""; + + LuceneException finally; + try { + do { + TermPtr term(termEnum->term()); + if (!term || term->field() != field || t >= mterms.size() ) { + break; + } - termDocs->seek(termEnum); - while (termDocs->next()) - retArray[termDocs->doc()] = t; + // store term text + mterms[t] = term->text(); - ++t; + termDocs->seek(termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = t; } - while (termEnum->next()); - } - catch (LuceneException& e) - { - finally = e; - } - termDocs->close(); - termEnum->close(); - finally.throwException(); - - if (t == 0) - { - // if there are no terms, make the term array have a single null entry - mterms = Collection::newInstance(1); - } - else if (t < mterms.size()) - { - // if there are less terms than documents, trim off the dead array space - mterms.resize(t); - } - return newLucene(retArray, mterms); + ++t; + } while (termEnum->next()); + } catch (LuceneException& e) { + finally = e; } + termDocs->close(); + termEnum->close(); + finally.throwException(); - FieldCacheEntryImpl::FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, const boost::any& custom, const boost::any& value) - { - this->readerKey = readerKey; - this->fieldName = fieldName; - this->cacheType = cacheType; - this->custom = custom; - this->value = value; + if (t == 0) { + // if there are no terms, make the term array have a single null entry + mterms = Collection::newInstance(1); + } else if (t < mterms.size()) { + // if there are less terms than documents, trim off the dead array space + mterms.resize(t); } - FieldCacheEntryImpl::~FieldCacheEntryImpl() - { - } + return newLucene(retArray, mterms); +} - LuceneObjectPtr FieldCacheEntryImpl::getReaderKey() - { - return readerKey; - } +FieldCacheEntryImpl::FieldCacheEntryImpl(const LuceneObjectPtr& readerKey, const String& fieldName, int32_t cacheType, const boost::any& custom, const boost::any& value) { + this->readerKey = readerKey; + this->fieldName = fieldName; + this->cacheType = cacheType; + this->custom = custom; + this->value = value; +} - String FieldCacheEntryImpl::getFieldName() - { - return fieldName; - } +FieldCacheEntryImpl::~FieldCacheEntryImpl() { +} - int32_t FieldCacheEntryImpl::getCacheType() - { - return cacheType; - } +LuceneObjectPtr FieldCacheEntryImpl::getReaderKey() { + return readerKey; +} - boost::any FieldCacheEntryImpl::getCustom() - { - return custom; - } +String FieldCacheEntryImpl::getFieldName() { + return fieldName; +} + +int32_t FieldCacheEntryImpl::getCacheType() { + return cacheType; +} + +boost::any FieldCacheEntryImpl::getCustom() { + return custom; +} + +boost::any FieldCacheEntryImpl::getValue() { + return value; +} - boost::any FieldCacheEntryImpl::getValue() - { - return value; - } } diff --git a/src/core/search/FieldCacheRangeFilter.cpp b/src/core/search/FieldCacheRangeFilter.cpp index 7b318c17..7a3e1ae8 100644 --- a/src/core/search/FieldCacheRangeFilter.cpp +++ b/src/core/search/FieldCacheRangeFilter.cpp @@ -14,407 +14,349 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - FieldCacheRangeFilter::FieldCacheRangeFilter(const String& field, const ParserPtr& parser, bool includeLower, bool includeUpper) - { - this->field = field; - this->parser = parser; - this->includeLower = includeLower; - this->includeUpper = includeUpper; - } +namespace Lucene { - FieldCacheRangeFilter::~FieldCacheRangeFilter() - { - } +FieldCacheRangeFilter::FieldCacheRangeFilter(const String& field, const ParserPtr& parser, bool includeLower, bool includeUpper) { + this->field = field; + this->parser = parser; + this->includeLower = includeLower; + this->includeUpper = includeUpper; +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newStringRange(const String& field, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) - { - return newLucene(field, ParserPtr(), lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilter::~FieldCacheRangeFilter() { +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) - { - return newByteRange(field, ByteParserPtr(), lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newStringRange(const String& field, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) { + return newLucene(field, ParserPtr(), lowerVal, upperVal, includeLower, includeUpper); +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, const ByteParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) - { - return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) { + return newByteRange(field, ByteParserPtr(), lowerVal, upperVal, includeLower, includeUpper); +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) - { - return newIntRange(field, IntParserPtr(), lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newByteRange(const String& field, const ByteParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) { + return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, const IntParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) - { - return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) { + return newIntRange(field, IntParserPtr(), lowerVal, upperVal, includeLower, includeUpper); +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) - { - return newLongRange(field, LongParserPtr(), lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newIntRange(const String& field, const IntParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) { + return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, const LongParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) - { - return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) { + return newLongRange(field, LongParserPtr(), lowerVal, upperVal, includeLower, includeUpper); +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, double lowerVal, double upperVal, bool includeLower, bool includeUpper) - { - return newDoubleRange(field, DoubleParserPtr(), lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newLongRange(const String& field, const LongParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) { + return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); +} - FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, const DoubleParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) - { - return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, double lowerVal, double upperVal, bool includeLower, bool includeUpper) { + return newDoubleRange(field, DoubleParserPtr(), lowerVal, upperVal, includeLower, includeUpper); +} - String FieldCacheRangeFilter::getField() - { - return field; - } +FieldCacheRangeFilterPtr FieldCacheRangeFilter::newDoubleRange(const String& field, const DoubleParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) { + return newLucene(field, parser, lowerVal, upperVal, includeLower, includeUpper); +} - bool FieldCacheRangeFilter::includesLower() - { - return includeLower; - } +String FieldCacheRangeFilter::getField() { + return field; +} - bool FieldCacheRangeFilter::includesUpper() - { - return includeUpper; - } +bool FieldCacheRangeFilter::includesLower() { + return includeLower; +} - ParserPtr FieldCacheRangeFilter::getParser() - { - return parser; - } +bool FieldCacheRangeFilter::includesUpper() { + return includeUpper; +} - FieldCacheRangeFilterString::FieldCacheRangeFilterString(const String& field, const ParserPtr& parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) - : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) - { - this->lowerVal = lowerVal; - this->upperVal = upperVal; - } +ParserPtr FieldCacheRangeFilter::getParser() { + return parser; +} - FieldCacheRangeFilterString::~FieldCacheRangeFilterString() - { - } +FieldCacheRangeFilterString::FieldCacheRangeFilterString(const String& field, const ParserPtr& parser, const String& lowerVal, const String& upperVal, bool includeLower, bool includeUpper) + : FieldCacheRangeFilter(field, parser, includeLower, includeUpper) { + this->lowerVal = lowerVal; + this->upperVal = upperVal; +} - DocIdSetPtr FieldCacheRangeFilterString::getDocIdSet(const IndexReaderPtr& reader) - { - StringIndexPtr fcsi(FieldCache::DEFAULT()->getStringIndex(reader, field)); - int32_t lowerPoint = fcsi->binarySearchLookup(lowerVal); - int32_t upperPoint = fcsi->binarySearchLookup(upperVal); - - int32_t inclusiveLowerPoint = 0; - int32_t inclusiveUpperPoint = 0; - - // Hints: - // * binarySearchLookup returns 0, if value was null. - // * the value is <0 if no exact hit was found, the returned value is (-(insertion point) - 1) - if (lowerPoint == 0) - { - BOOST_ASSERT(lowerVal.empty()); - inclusiveLowerPoint = 1; - } - else if (includeLower && lowerPoint > 0) - inclusiveLowerPoint = lowerPoint; - else if (lowerPoint > 0) - inclusiveLowerPoint = lowerPoint + 1; - else - inclusiveLowerPoint = std::max((int32_t)1, -lowerPoint - 1); - - if (upperPoint == 0) - { - BOOST_ASSERT(upperVal.empty()); - inclusiveUpperPoint = INT_MAX; - } - else if (includeUpper && upperPoint > 0) - inclusiveUpperPoint = upperPoint; - else if (upperPoint > 0) - inclusiveUpperPoint = upperPoint - 1; - else - inclusiveUpperPoint = -upperPoint - 2; +FieldCacheRangeFilterString::~FieldCacheRangeFilterString() { +} - if (inclusiveUpperPoint <= 0 || inclusiveLowerPoint > inclusiveUpperPoint) - return DocIdSet::EMPTY_DOCIDSET(); +DocIdSetPtr FieldCacheRangeFilterString::getDocIdSet(const IndexReaderPtr& reader) { + StringIndexPtr fcsi(FieldCache::DEFAULT()->getStringIndex(reader, field)); + int32_t lowerPoint = fcsi->binarySearchLookup(lowerVal); + int32_t upperPoint = fcsi->binarySearchLookup(upperVal); - BOOST_ASSERT(inclusiveLowerPoint > 0 && inclusiveUpperPoint > 0); + int32_t inclusiveLowerPoint = 0; + int32_t inclusiveUpperPoint = 0; - // for this DocIdSet, we never need to use TermDocs, because deleted docs have an order of 0 - // (null entry in StringIndex) - return newLucene(reader, false, fcsi, inclusiveLowerPoint, inclusiveUpperPoint); + // Hints: + // * binarySearchLookup returns 0, if value was null. + // * the value is <0 if no exact hit was found, the returned value is (-(insertion point) - 1) + if (lowerPoint == 0) { + BOOST_ASSERT(lowerVal.empty()); + inclusiveLowerPoint = 1; + } else if (includeLower && lowerPoint > 0) { + inclusiveLowerPoint = lowerPoint; + } else if (lowerPoint > 0) { + inclusiveLowerPoint = lowerPoint + 1; + } else { + inclusiveLowerPoint = std::max((int32_t)1, -lowerPoint - 1); } - String FieldCacheRangeFilterString::toString() - { - StringStream buffer; - buffer << field << L":" << (includeLower ? L"[" : L"{"); - buffer << lowerVal << L" TO " << lowerVal; - buffer << (includeLower ? L"]" : L"}"); - return buffer.str(); + if (upperPoint == 0) { + BOOST_ASSERT(upperVal.empty()); + inclusiveUpperPoint = INT_MAX; + } else if (includeUpper && upperPoint > 0) { + inclusiveUpperPoint = upperPoint; + } else if (upperPoint > 0) { + inclusiveUpperPoint = upperPoint - 1; + } else { + inclusiveUpperPoint = -upperPoint - 2; } - bool FieldCacheRangeFilterString::equals(const LuceneObjectPtr& other) - { - if (Filter::equals(other)) - return true; - FieldCacheRangeFilterStringPtr otherFilter(boost::dynamic_pointer_cast(other)); - if (!otherFilter) - return false; - if (field != otherFilter->field || includeLower != otherFilter->includeLower || includeUpper != otherFilter->includeUpper) - return false; - if (lowerVal != otherFilter->lowerVal || upperVal != otherFilter->upperVal) - return false; - if (parser.get() != NULL ? !parser->equals(otherFilter->parser) : otherFilter->parser.get() != NULL) - return false; - return true; + if (inclusiveUpperPoint <= 0 || inclusiveLowerPoint > inclusiveUpperPoint) { + return DocIdSet::EMPTY_DOCIDSET(); } - int32_t FieldCacheRangeFilterString::hashCode() - { - int32_t code = StringUtils::hashCode(field); - code ^= lowerVal.empty() ? 550356204 : StringUtils::hashCode(lowerVal); - code = (code << 1) | MiscUtils::unsignedShift(code, 31); // rotate to distinguish lower from upper - code ^= upperVal.empty() ? -1674416163 : StringUtils::hashCode(upperVal); - code ^= parser ? parser->hashCode() : -1572457324; - code ^= (includeLower ? 1549299360 : -365038026) ^ (includeUpper ? 1721088258 : 1948649653); - return code; - } + BOOST_ASSERT(inclusiveLowerPoint > 0 && inclusiveUpperPoint > 0); - FieldCacheRangeFilterByte::FieldCacheRangeFilterByte(const String& field, const ParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) - : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, UCHAR_MAX, includeLower, includeUpper) - { - } + // for this DocIdSet, we never need to use TermDocs, because deleted docs have an order of 0 + // (null entry in StringIndex) + return newLucene(reader, false, fcsi, inclusiveLowerPoint, inclusiveUpperPoint); +} - FieldCacheRangeFilterByte::~FieldCacheRangeFilterByte() - { - } +String FieldCacheRangeFilterString::toString() { + StringStream buffer; + buffer << field << L":" << (includeLower ? L"[" : L"{"); + buffer << lowerVal << L" TO " << lowerVal; + buffer << (includeLower ? L"]" : L"}"); + return buffer.str(); +} - Collection FieldCacheRangeFilterByte::getValues(const IndexReaderPtr& reader) - { - return FieldCache::DEFAULT()->getBytes(reader, field, boost::static_pointer_cast(parser)); +bool FieldCacheRangeFilterString::equals(const LuceneObjectPtr& other) { + if (Filter::equals(other)) { + return true; } - - FieldCacheRangeFilterInt::FieldCacheRangeFilterInt(const String& field, const ParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) - : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, INT_MAX, includeLower, includeUpper) - { + FieldCacheRangeFilterStringPtr otherFilter(boost::dynamic_pointer_cast(other)); + if (!otherFilter) { + return false; } - - FieldCacheRangeFilterInt::~FieldCacheRangeFilterInt() - { + if (field != otherFilter->field || includeLower != otherFilter->includeLower || includeUpper != otherFilter->includeUpper) { + return false; } - - Collection FieldCacheRangeFilterInt::getValues(const IndexReaderPtr& reader) - { - return FieldCache::DEFAULT()->getInts(reader, field, boost::static_pointer_cast(parser)); + if (lowerVal != otherFilter->lowerVal || upperVal != otherFilter->upperVal) { + return false; } - - FieldCacheRangeFilterLong::FieldCacheRangeFilterLong(const String& field, const ParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) - : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::max(), includeLower, includeUpper) - { + if (parser.get() != NULL ? !parser->equals(otherFilter->parser) : otherFilter->parser.get() != NULL) { + return false; } + return true; +} - FieldCacheRangeFilterLong::~FieldCacheRangeFilterLong() - { - } +int32_t FieldCacheRangeFilterString::hashCode() { + int32_t code = StringUtils::hashCode(field); + code ^= lowerVal.empty() ? 550356204 : StringUtils::hashCode(lowerVal); + code = (code << 1) | MiscUtils::unsignedShift(code, 31); // rotate to distinguish lower from upper + code ^= upperVal.empty() ? -1674416163 : StringUtils::hashCode(upperVal); + code ^= parser ? parser->hashCode() : -1572457324; + code ^= (includeLower ? 1549299360 : -365038026) ^ (includeUpper ? 1721088258 : 1948649653); + return code; +} - Collection FieldCacheRangeFilterLong::getValues(const IndexReaderPtr& reader) - { - return FieldCache::DEFAULT()->getLongs(reader, field, boost::static_pointer_cast(parser)); - } +FieldCacheRangeFilterByte::FieldCacheRangeFilterByte(const String& field, const ParserPtr& parser, uint8_t lowerVal, uint8_t upperVal, bool includeLower, bool includeUpper) + : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, UCHAR_MAX, includeLower, includeUpper) { +} - FieldCacheRangeFilterDouble::FieldCacheRangeFilterDouble(const String& field, const ParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) - : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::infinity(), includeLower, includeUpper) - { - } +FieldCacheRangeFilterByte::~FieldCacheRangeFilterByte() { +} - FieldCacheRangeFilterDouble::~FieldCacheRangeFilterDouble() - { - } +Collection FieldCacheRangeFilterByte::getValues(const IndexReaderPtr& reader) { + return FieldCache::DEFAULT()->getBytes(reader, field, boost::static_pointer_cast(parser)); +} - DocIdSetPtr FieldCacheRangeFilterDouble::getDocIdSet(const IndexReaderPtr& reader) - { - if (!includeLower && lowerVal > 0.0 && MiscUtils::isInfinite(lowerVal)) - return DocIdSet::EMPTY_DOCIDSET(); - int64_t lower = NumericUtils::doubleToSortableLong(lowerVal); - double inclusiveLowerPoint = NumericUtils::sortableLongToDouble(includeLower ? lower : (lower + 1)); +FieldCacheRangeFilterInt::FieldCacheRangeFilterInt(const String& field, const ParserPtr& parser, int32_t lowerVal, int32_t upperVal, bool includeLower, bool includeUpper) + : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, INT_MAX, includeLower, includeUpper) { +} - if (!includeUpper && upperVal < 0.0 && MiscUtils::isInfinite(upperVal)) - return DocIdSet::EMPTY_DOCIDSET(); - int64_t upper = NumericUtils::doubleToSortableLong(upperVal); - double inclusiveUpperPoint = NumericUtils::sortableLongToDouble(includeUpper ? upper : (upper - 1)); +FieldCacheRangeFilterInt::~FieldCacheRangeFilterInt() { +} - if (inclusiveLowerPoint > inclusiveUpperPoint) - return DocIdSet::EMPTY_DOCIDSET(); +Collection FieldCacheRangeFilterInt::getValues(const IndexReaderPtr& reader) { + return FieldCache::DEFAULT()->getInts(reader, field, boost::static_pointer_cast(parser)); +} - // we only request the usage of termDocs, if the range contains 0 - return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); - } +FieldCacheRangeFilterLong::FieldCacheRangeFilterLong(const String& field, const ParserPtr& parser, int64_t lowerVal, int64_t upperVal, bool includeLower, bool includeUpper) + : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::max(), includeLower, includeUpper) { +} - Collection FieldCacheRangeFilterDouble::getValues(const IndexReaderPtr& reader) - { - return FieldCache::DEFAULT()->getDoubles(reader, field, boost::static_pointer_cast(parser)); - } +FieldCacheRangeFilterLong::~FieldCacheRangeFilterLong() { +} - FieldCacheDocIdSet::FieldCacheDocIdSet(const IndexReaderPtr& reader, bool mayUseTermDocs) - { - this->reader = reader; - this->mayUseTermDocs = mayUseTermDocs; - } +Collection FieldCacheRangeFilterLong::getValues(const IndexReaderPtr& reader) { + return FieldCache::DEFAULT()->getLongs(reader, field, boost::static_pointer_cast(parser)); +} - FieldCacheDocIdSet::~FieldCacheDocIdSet() - { - } +FieldCacheRangeFilterDouble::FieldCacheRangeFilterDouble(const String& field, const ParserPtr& parser, double lowerVal, double upperVal, bool includeLower, bool includeUpper) + : FieldCacheRangeFilterNumeric(field, parser, lowerVal, upperVal, std::numeric_limits::infinity(), includeLower, includeUpper) { +} - bool FieldCacheDocIdSet::isCacheable() - { - return !(mayUseTermDocs && reader->hasDeletions()); - } +FieldCacheRangeFilterDouble::~FieldCacheRangeFilterDouble() { +} - DocIdSetIteratorPtr FieldCacheDocIdSet::iterator() - { - // Synchronization needed because deleted docs BitVector can change after call to hasDeletions until - // TermDocs creation. We only use an iterator with termDocs, when this was requested (eg. range - // contains 0) and the index has deletions - TermDocsPtr termDocs; - { - SyncLock instancesLock(reader); - termDocs = isCacheable() ? TermDocsPtr() : reader->termDocs(TermPtr()); - } - if (termDocs) - { - // a DocIdSetIterator using TermDocs to iterate valid docIds - return newLucene(shared_from_this(), termDocs); - } - else - { - // a DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there - // are no deletions are on the index - return newLucene(shared_from_this()); - } +DocIdSetPtr FieldCacheRangeFilterDouble::getDocIdSet(const IndexReaderPtr& reader) { + if (!includeLower && lowerVal > 0.0 && MiscUtils::isInfinite(lowerVal)) { + return DocIdSet::EMPTY_DOCIDSET(); } + int64_t lower = NumericUtils::doubleToSortableLong(lowerVal); + double inclusiveLowerPoint = NumericUtils::sortableLongToDouble(includeLower ? lower : (lower + 1)); - FieldCacheDocIdSetString::FieldCacheDocIdSetString(const IndexReaderPtr& reader, bool mayUseTermDocs, const StringIndexPtr& fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) - { - this->fcsi = fcsi; - this->inclusiveLowerPoint = inclusiveLowerPoint; - this->inclusiveUpperPoint = inclusiveUpperPoint; + if (!includeUpper && upperVal < 0.0 && MiscUtils::isInfinite(upperVal)) { + return DocIdSet::EMPTY_DOCIDSET(); } + int64_t upper = NumericUtils::doubleToSortableLong(upperVal); + double inclusiveUpperPoint = NumericUtils::sortableLongToDouble(includeUpper ? upper : (upper - 1)); - FieldCacheDocIdSetString::~FieldCacheDocIdSetString() - { + if (inclusiveLowerPoint > inclusiveUpperPoint) { + return DocIdSet::EMPTY_DOCIDSET(); } - bool FieldCacheDocIdSetString::matchDoc(int32_t doc) - { - if (doc < 0 || doc >= fcsi->order.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (fcsi->order[doc] >= inclusiveLowerPoint && fcsi->order[doc] <= inclusiveUpperPoint); - } + // we only request the usage of termDocs, if the range contains 0 + return newLucene< FieldCacheDocIdSetNumeric >(reader, (inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0), getValues(reader), inclusiveLowerPoint, inclusiveUpperPoint); +} - FieldDocIdSetIteratorTermDocs::FieldDocIdSetIteratorTermDocs(const FieldCacheDocIdSetPtr& cacheDocIdSet, const TermDocsPtr& termDocs) - { - this->_cacheDocIdSet = cacheDocIdSet; - this->termDocs = termDocs; - this->doc = -1; - } +Collection FieldCacheRangeFilterDouble::getValues(const IndexReaderPtr& reader) { + return FieldCache::DEFAULT()->getDoubles(reader, field, boost::static_pointer_cast(parser)); +} + +FieldCacheDocIdSet::FieldCacheDocIdSet(const IndexReaderPtr& reader, bool mayUseTermDocs) { + this->reader = reader; + this->mayUseTermDocs = mayUseTermDocs; +} + +FieldCacheDocIdSet::~FieldCacheDocIdSet() { +} + +bool FieldCacheDocIdSet::isCacheable() { + return !(mayUseTermDocs && reader->hasDeletions()); +} - FieldDocIdSetIteratorTermDocs::~FieldDocIdSetIteratorTermDocs() +DocIdSetIteratorPtr FieldCacheDocIdSet::iterator() { + // Synchronization needed because deleted docs BitVector can change after call to hasDeletions until + // TermDocs creation. We only use an iterator with termDocs, when this was requested (eg. range + // contains 0) and the index has deletions + TermDocsPtr termDocs; { + SyncLock instancesLock(reader); + termDocs = isCacheable() ? TermDocsPtr() : reader->termDocs(TermPtr()); } + if (termDocs) { + // a DocIdSetIterator using TermDocs to iterate valid docIds + return newLucene(shared_from_this(), termDocs); + } else { + // a DocIdSetIterator generating docIds by incrementing a variable - this one can be used if there + // are no deletions are on the index + return newLucene(shared_from_this()); + } +} - int32_t FieldDocIdSetIteratorTermDocs::docID() - { - return doc; +FieldCacheDocIdSetString::FieldCacheDocIdSetString(const IndexReaderPtr& reader, bool mayUseTermDocs, const StringIndexPtr& fcsi, int32_t inclusiveLowerPoint, int32_t inclusiveUpperPoint) : FieldCacheDocIdSet(reader, mayUseTermDocs) { + this->fcsi = fcsi; + this->inclusiveLowerPoint = inclusiveLowerPoint; + this->inclusiveUpperPoint = inclusiveUpperPoint; +} + +FieldCacheDocIdSetString::~FieldCacheDocIdSetString() { +} + +bool FieldCacheDocIdSetString::matchDoc(int32_t doc) { + if (doc < 0 || doc >= fcsi->order.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return (fcsi->order[doc] >= inclusiveLowerPoint && fcsi->order[doc] <= inclusiveUpperPoint); +} - int32_t FieldDocIdSetIteratorTermDocs::nextDoc() - { - FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); - do - { - if (!termDocs->next()) - { - doc = NO_MORE_DOCS; - return doc; - } +FieldDocIdSetIteratorTermDocs::FieldDocIdSetIteratorTermDocs(const FieldCacheDocIdSetPtr& cacheDocIdSet, const TermDocsPtr& termDocs) { + this->_cacheDocIdSet = cacheDocIdSet; + this->termDocs = termDocs; + this->doc = -1; +} + +FieldDocIdSetIteratorTermDocs::~FieldDocIdSetIteratorTermDocs() { +} + +int32_t FieldDocIdSetIteratorTermDocs::docID() { + return doc; +} + +int32_t FieldDocIdSetIteratorTermDocs::nextDoc() { + FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); + do { + if (!termDocs->next()) { + doc = NO_MORE_DOCS; + return doc; } - while (!cacheDocIdSet->matchDoc(doc = termDocs->doc())); + } while (!cacheDocIdSet->matchDoc(doc = termDocs->doc())); + return doc; +} + +int32_t FieldDocIdSetIteratorTermDocs::advance(int32_t target) { + FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); + if (!termDocs->skipTo(target)) { + doc = NO_MORE_DOCS; return doc; } - - int32_t FieldDocIdSetIteratorTermDocs::advance(int32_t target) - { - FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); - if (!termDocs->skipTo(target)) - { + while (!cacheDocIdSet->matchDoc(doc = termDocs->doc())) { + if (!termDocs->next()) { doc = NO_MORE_DOCS; return doc; } - while (!cacheDocIdSet->matchDoc(doc = termDocs->doc())) - { - if (!termDocs->next()) - { - doc = NO_MORE_DOCS; - return doc; - } - } - return doc; } + return doc; +} - FieldDocIdSetIteratorIncrement::FieldDocIdSetIteratorIncrement(const FieldCacheDocIdSetPtr& cacheDocIdSet) - { - this->_cacheDocIdSet = cacheDocIdSet; - this->doc = -1; - } +FieldDocIdSetIteratorIncrement::FieldDocIdSetIteratorIncrement(const FieldCacheDocIdSetPtr& cacheDocIdSet) { + this->_cacheDocIdSet = cacheDocIdSet; + this->doc = -1; +} - FieldDocIdSetIteratorIncrement::~FieldDocIdSetIteratorIncrement() - { - } +FieldDocIdSetIteratorIncrement::~FieldDocIdSetIteratorIncrement() { +} - int32_t FieldDocIdSetIteratorIncrement::docID() - { +int32_t FieldDocIdSetIteratorIncrement::docID() { + return doc; +} + +int32_t FieldDocIdSetIteratorIncrement::nextDoc() { + FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); + try { + do { + ++doc; + } while (!cacheDocIdSet->matchDoc(doc)); + return doc; + } catch (IndexOutOfBoundsException&) { + doc = NO_MORE_DOCS; return doc; } +} - int32_t FieldDocIdSetIteratorIncrement::nextDoc() - { - FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); - try - { - do - { - ++doc; - } - while (!cacheDocIdSet->matchDoc(doc)); - return doc; - } - catch (IndexOutOfBoundsException&) - { - doc = NO_MORE_DOCS; - return doc; +int32_t FieldDocIdSetIteratorIncrement::advance(int32_t target) { + FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); + try { + doc = target; + while (!cacheDocIdSet->matchDoc(doc)) { + ++doc; } + return doc; + } catch (IndexOutOfBoundsException&) { + doc = NO_MORE_DOCS; + return doc; } +} - int32_t FieldDocIdSetIteratorIncrement::advance(int32_t target) - { - FieldCacheDocIdSetPtr cacheDocIdSet(_cacheDocIdSet); - try - { - doc = target; - while (!cacheDocIdSet->matchDoc(doc)) - ++doc; - return doc; - } - catch (IndexOutOfBoundsException&) - { - doc = NO_MORE_DOCS; - return doc; - } - } } diff --git a/src/core/search/FieldCacheTermsFilter.cpp b/src/core/search/FieldCacheTermsFilter.cpp index 38229077..32ca0a44 100644 --- a/src/core/search/FieldCacheTermsFilter.cpp +++ b/src/core/search/FieldCacheTermsFilter.cpp @@ -10,106 +10,90 @@ #include "FieldCache.h" #include "OpenBitSet.h" -namespace Lucene -{ - FieldCacheTermsFilter::FieldCacheTermsFilter(const String& field, Collection terms) - { - this->field = field; - this->terms = terms; - } +namespace Lucene { - FieldCacheTermsFilter::~FieldCacheTermsFilter() - { - } +FieldCacheTermsFilter::FieldCacheTermsFilter(const String& field, Collection terms) { + this->field = field; + this->terms = terms; +} - FieldCachePtr FieldCacheTermsFilter::getFieldCache() - { - return FieldCache::DEFAULT(); - } +FieldCacheTermsFilter::~FieldCacheTermsFilter() { +} - DocIdSetPtr FieldCacheTermsFilter::getDocIdSet(const IndexReaderPtr& reader) - { - return newLucene(terms, getFieldCache()->getStringIndex(reader, field)); - } +FieldCachePtr FieldCacheTermsFilter::getFieldCache() { + return FieldCache::DEFAULT(); +} - FieldCacheTermsFilterDocIdSet::FieldCacheTermsFilterDocIdSet(Collection terms, const StringIndexPtr& fcsi) - { - this->fcsi = fcsi; - openBitSet = newLucene(this->fcsi->lookup.size()); - for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) - { - int32_t termNumber = this->fcsi->binarySearchLookup(*term); - if (termNumber > 0) - openBitSet->set(termNumber); +DocIdSetPtr FieldCacheTermsFilter::getDocIdSet(const IndexReaderPtr& reader) { + return newLucene(terms, getFieldCache()->getStringIndex(reader, field)); +} + +FieldCacheTermsFilterDocIdSet::FieldCacheTermsFilterDocIdSet(Collection terms, const StringIndexPtr& fcsi) { + this->fcsi = fcsi; + openBitSet = newLucene(this->fcsi->lookup.size()); + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) { + int32_t termNumber = this->fcsi->binarySearchLookup(*term); + if (termNumber > 0) { + openBitSet->set(termNumber); } } +} - FieldCacheTermsFilterDocIdSet::~FieldCacheTermsFilterDocIdSet() - { - } +FieldCacheTermsFilterDocIdSet::~FieldCacheTermsFilterDocIdSet() { +} - DocIdSetIteratorPtr FieldCacheTermsFilterDocIdSet::iterator() - { - return newLucene(fcsi, openBitSet); - } +DocIdSetIteratorPtr FieldCacheTermsFilterDocIdSet::iterator() { + return newLucene(fcsi, openBitSet); +} - bool FieldCacheTermsFilterDocIdSet::isCacheable() - { - return true; - } +bool FieldCacheTermsFilterDocIdSet::isCacheable() { + return true; +} - FieldCacheTermsFilterDocIdSetIterator::FieldCacheTermsFilterDocIdSetIterator(const StringIndexPtr& fcsi, const OpenBitSetPtr& openBitSet) - { - this->fcsi = fcsi; - this->openBitSet = openBitSet; - this->doc = -1; - } +FieldCacheTermsFilterDocIdSetIterator::FieldCacheTermsFilterDocIdSetIterator(const StringIndexPtr& fcsi, const OpenBitSetPtr& openBitSet) { + this->fcsi = fcsi; + this->openBitSet = openBitSet; + this->doc = -1; +} - FieldCacheTermsFilterDocIdSetIterator::~FieldCacheTermsFilterDocIdSetIterator() - { - } +FieldCacheTermsFilterDocIdSetIterator::~FieldCacheTermsFilterDocIdSetIterator() { +} - int32_t FieldCacheTermsFilterDocIdSetIterator::docID() - { - return doc; - } +int32_t FieldCacheTermsFilterDocIdSetIterator::docID() { + return doc; +} - int32_t FieldCacheTermsFilterDocIdSetIterator::nextDoc() - { - try - { - if (++doc >= fcsi->order.size()) +int32_t FieldCacheTermsFilterDocIdSetIterator::nextDoc() { + try { + if (++doc >= fcsi->order.size()) { + boost::throw_exception(IndexOutOfBoundsException()); + } + while (!openBitSet->fastGet(fcsi->order[doc])) { + if (++doc >= fcsi->order.size()) { boost::throw_exception(IndexOutOfBoundsException()); - while (!openBitSet->fastGet(fcsi->order[doc])) - { - if (++doc >= fcsi->order.size()) - boost::throw_exception(IndexOutOfBoundsException()); } } - catch (IndexOutOfBoundsException&) - { - doc = NO_MORE_DOCS; - } - return doc; + } catch (IndexOutOfBoundsException&) { + doc = NO_MORE_DOCS; } + return doc; +} - int32_t FieldCacheTermsFilterDocIdSetIterator::advance(int32_t target) - { - try - { - doc = target; - if (doc < 0 || doc >= fcsi->order.size()) +int32_t FieldCacheTermsFilterDocIdSetIterator::advance(int32_t target) { + try { + doc = target; + if (doc < 0 || doc >= fcsi->order.size()) { + boost::throw_exception(IndexOutOfBoundsException()); + } + while (!openBitSet->fastGet(fcsi->order[doc])) { + if (++doc >= fcsi->order.size()) { boost::throw_exception(IndexOutOfBoundsException()); - while (!openBitSet->fastGet(fcsi->order[doc])) - { - if (++doc >= fcsi->order.size()) - boost::throw_exception(IndexOutOfBoundsException()); } } - catch (IndexOutOfBoundsException&) - { - doc = NO_MORE_DOCS; - } - return doc; + } catch (IndexOutOfBoundsException&) { + doc = NO_MORE_DOCS; } + return doc; +} + } diff --git a/src/core/search/FieldComparator.cpp b/src/core/search/FieldComparator.cpp index 070042ef..e0c612e4 100644 --- a/src/core/search/FieldComparator.cpp +++ b/src/core/search/FieldComparator.cpp @@ -10,381 +10,320 @@ #include "ScoreCachingWrappingScorer.h" #include "Collator.h" -namespace Lucene -{ - FieldComparator::~FieldComparator() - { - } +namespace Lucene { - void FieldComparator::setScorer(const ScorerPtr& scorer) - { - // Empty implementation since most comparators don't need the score. - // This can be overridden by those that need it. - } +FieldComparator::~FieldComparator() { +} - ByteComparator::ByteComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) - { - this->parser = boost::static_pointer_cast(parser); - } +void FieldComparator::setScorer(const ScorerPtr& scorer) { + // Empty implementation since most comparators don't need the score. + // This can be overridden by those that need it. +} - ByteComparator::~ByteComparator() - { - } +ByteComparator::ByteComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { + this->parser = boost::static_pointer_cast(parser); +} - void ByteComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - currentReaderValues = FieldCache::DEFAULT()->getBytes(reader, field, parser); - } +ByteComparator::~ByteComparator() { +} - DocComparator::DocComparator(int32_t numHits) : NumericComparator(numHits) - { - this->docBase = 0; - } +void ByteComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + currentReaderValues = FieldCache::DEFAULT()->getBytes(reader, field, parser); +} - DocComparator::~DocComparator() - { - } +DocComparator::DocComparator(int32_t numHits) : NumericComparator(numHits) { + this->docBase = 0; +} - int32_t DocComparator::compareBottom(int32_t doc) - { - // No overflow risk because docIDs are non-negative - return (bottom - (docBase + doc)); - } +DocComparator::~DocComparator() { +} - void DocComparator::copy(int32_t slot, int32_t doc) - { - values[slot] = docBase + doc; - } +int32_t DocComparator::compareBottom(int32_t doc) { + // No overflow risk because docIDs are non-negative + return (bottom - (docBase + doc)); +} - void DocComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - this->docBase = docBase; - } +void DocComparator::copy(int32_t slot, int32_t doc) { + values[slot] = docBase + doc; +} - DoubleComparator::DoubleComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) - { - this->parser = boost::static_pointer_cast(parser); - } +void DocComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + this->docBase = docBase; +} - DoubleComparator::~DoubleComparator() - { - } +DoubleComparator::DoubleComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { + this->parser = boost::static_pointer_cast(parser); +} - int32_t DoubleComparator::compare(int32_t slot1, int32_t slot2) - { - double v1 = values[slot1]; - double v2 = values[slot2]; - return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); - } +DoubleComparator::~DoubleComparator() { +} - int32_t DoubleComparator::compareBottom(int32_t doc) - { - double v2 = currentReaderValues[doc]; - return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); - } +int32_t DoubleComparator::compare(int32_t slot1, int32_t slot2) { + double v1 = values[slot1]; + double v2 = values[slot2]; + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); +} - void DoubleComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - currentReaderValues = FieldCache::DEFAULT()->getDoubles(reader, field, parser); - } +int32_t DoubleComparator::compareBottom(int32_t doc) { + double v2 = currentReaderValues[doc]; + return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); +} - IntComparator::IntComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) - { - this->parser = boost::static_pointer_cast(parser); - } +void DoubleComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + currentReaderValues = FieldCache::DEFAULT()->getDoubles(reader, field, parser); +} - IntComparator::~IntComparator() - { - } +IntComparator::IntComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { + this->parser = boost::static_pointer_cast(parser); +} - int32_t IntComparator::compare(int32_t slot1, int32_t slot2) - { - int32_t v1 = values[slot1]; - int32_t v2 = values[slot2]; - return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); - } +IntComparator::~IntComparator() { +} - int32_t IntComparator::compareBottom(int32_t doc) - { - int32_t v2 = currentReaderValues[doc]; - return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); - } +int32_t IntComparator::compare(int32_t slot1, int32_t slot2) { + int32_t v1 = values[slot1]; + int32_t v2 = values[slot2]; + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); +} - void IntComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - currentReaderValues = FieldCache::DEFAULT()->getInts(reader, field, parser); - } +int32_t IntComparator::compareBottom(int32_t doc) { + int32_t v2 = currentReaderValues[doc]; + return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); +} - LongComparator::LongComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) - { - this->parser = boost::static_pointer_cast(parser); - } +void IntComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + currentReaderValues = FieldCache::DEFAULT()->getInts(reader, field, parser); +} - LongComparator::~LongComparator() - { - } +LongComparator::LongComparator(int32_t numHits, const String& field, const ParserPtr& parser) : NumericComparator(numHits, field) { + this->parser = boost::static_pointer_cast(parser); +} - int32_t LongComparator::compare(int32_t slot1, int32_t slot2) - { - int64_t v1 = values[slot1]; - int64_t v2 = values[slot2]; - return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); - } +LongComparator::~LongComparator() { +} - int32_t LongComparator::compareBottom(int32_t doc) - { - int64_t v2 = currentReaderValues[doc]; - return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); - } +int32_t LongComparator::compare(int32_t slot1, int32_t slot2) { + int64_t v1 = values[slot1]; + int64_t v2 = values[slot2]; + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); +} - void LongComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - currentReaderValues = FieldCache::DEFAULT()->getLongs(reader, field, parser); - } +int32_t LongComparator::compareBottom(int32_t doc) { + int64_t v2 = currentReaderValues[doc]; + return bottom > v2 ? 1 : (bottom < v2 ? -1 : 0); +} - RelevanceComparator::RelevanceComparator(int32_t numHits) : NumericComparator(numHits) - { - } +void LongComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + currentReaderValues = FieldCache::DEFAULT()->getLongs(reader, field, parser); +} - RelevanceComparator::~RelevanceComparator() - { - } +RelevanceComparator::RelevanceComparator(int32_t numHits) : NumericComparator(numHits) { +} - int32_t RelevanceComparator::compare(int32_t slot1, int32_t slot2) - { - double score1 = values[slot1]; - double score2 = values[slot2]; - return score1 > score2 ? -1 : (score1 < score2 ? 1 : 0); - } +RelevanceComparator::~RelevanceComparator() { +} - int32_t RelevanceComparator::compareBottom(int32_t doc) - { - double score = scorer->score(); - return bottom > score ? -1 : (bottom < score ? 1 : 0); - } +int32_t RelevanceComparator::compare(int32_t slot1, int32_t slot2) { + double score1 = values[slot1]; + double score2 = values[slot2]; + return score1 > score2 ? -1 : (score1 < score2 ? 1 : 0); +} - void RelevanceComparator::copy(int32_t slot, int32_t doc) - { - values[slot] = scorer->score(); - } +int32_t RelevanceComparator::compareBottom(int32_t doc) { + double score = scorer->score(); + return bottom > score ? -1 : (bottom < score ? 1 : 0); +} - void RelevanceComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - } +void RelevanceComparator::copy(int32_t slot, int32_t doc) { + values[slot] = scorer->score(); +} - void RelevanceComparator::setScorer(const ScorerPtr& scorer) - { - this->scorer = newLucene(scorer); - } +void RelevanceComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { +} - StringComparatorLocale::StringComparatorLocale(int32_t numHits, const String& field, const std::locale& locale) : collator(newLucene(locale)) - { - this->values = Collection::newInstance(numHits); - this->field = field; - } +void RelevanceComparator::setScorer(const ScorerPtr& scorer) { + this->scorer = newLucene(scorer); +} - StringComparatorLocale::~StringComparatorLocale() - { - } +StringComparatorLocale::StringComparatorLocale(int32_t numHits, const String& field, const std::locale& locale) : collator(newLucene(locale)) { + this->values = Collection::newInstance(numHits); + this->field = field; +} - int32_t StringComparatorLocale::compare(int32_t slot1, int32_t slot2) - { - return collator->compare(values[slot1], values[slot2]); - } +StringComparatorLocale::~StringComparatorLocale() { +} - int32_t StringComparatorLocale::compareBottom(int32_t doc) - { - return collator->compare(bottom, currentReaderValues[doc]); - } +int32_t StringComparatorLocale::compare(int32_t slot1, int32_t slot2) { + return collator->compare(values[slot1], values[slot2]); +} - void StringComparatorLocale::copy(int32_t slot, int32_t doc) - { - values[slot] = currentReaderValues[doc]; - } +int32_t StringComparatorLocale::compareBottom(int32_t doc) { + return collator->compare(bottom, currentReaderValues[doc]); +} - void StringComparatorLocale::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); - } +void StringComparatorLocale::copy(int32_t slot, int32_t doc) { + values[slot] = currentReaderValues[doc]; +} - void StringComparatorLocale::setBottom(int32_t slot) - { - bottom = values[slot]; - } +void StringComparatorLocale::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); +} - ComparableValue StringComparatorLocale::value(int32_t slot) - { - return values[slot]; - } +void StringComparatorLocale::setBottom(int32_t slot) { + bottom = values[slot]; +} - StringOrdValComparator::StringOrdValComparator(int32_t numHits, const String& field, int32_t sortPos, bool reversed) - { - this->ords = Collection::newInstance(numHits); - this->values = Collection::newInstance(numHits); - this->readerGen = Collection::newInstance(numHits); - this->sortPos = sortPos; - this->reversed = reversed; - this->field = field; - this->currentReaderGen = -1; - this->bottomSlot = -1; - this->bottomOrd = 0; - } +ComparableValue StringComparatorLocale::value(int32_t slot) { + return values[slot]; +} - StringOrdValComparator::~StringOrdValComparator() - { - } +StringOrdValComparator::StringOrdValComparator(int32_t numHits, const String& field, int32_t sortPos, bool reversed) { + this->ords = Collection::newInstance(numHits); + this->values = Collection::newInstance(numHits); + this->readerGen = Collection::newInstance(numHits); + this->sortPos = sortPos; + this->reversed = reversed; + this->field = field; + this->currentReaderGen = -1; + this->bottomSlot = -1; + this->bottomOrd = 0; +} - int32_t StringOrdValComparator::compare(int32_t slot1, int32_t slot2) - { - if (readerGen[slot1] == readerGen[slot2]) - { - int32_t cmp = ords[slot1] - ords[slot2]; - if (cmp != 0) - return cmp; - } - return values[slot1].compare(values[slot2]); - } +StringOrdValComparator::~StringOrdValComparator() { +} - int32_t StringOrdValComparator::compareBottom(int32_t doc) - { - BOOST_ASSERT(bottomSlot != -1); - int32_t order = this->order[doc]; - int32_t cmp = bottomOrd - order; - if (cmp != 0) +int32_t StringOrdValComparator::compare(int32_t slot1, int32_t slot2) { + if (readerGen[slot1] == readerGen[slot2]) { + int32_t cmp = ords[slot1] - ords[slot2]; + if (cmp != 0) { return cmp; - return bottomValue.compare(lookup[order]); - } - - void StringOrdValComparator::convert(int32_t slot) - { - readerGen[slot] = currentReaderGen; - int32_t index = 0; - String value(values[slot]); - if (value.empty()) - { - ords[slot] = 0; - return; - } - - if (sortPos == 0 && bottomSlot != -1 && bottomSlot != slot) - { - // Since we are the primary sort, the entries in the queue are bounded by bottomOrd - BOOST_ASSERT(bottomOrd < lookup.size()); - if (reversed) - index = binarySearch(lookup, value, bottomOrd, lookup.size() - 1); - else - index = binarySearch(lookup, value, 0, bottomOrd); } - else - { - // Full binary search - index = binarySearch(lookup, value, 0, lookup.size() - 1); - } - - if (index < 0) - index = -index - 2; - - ords[slot] = index; } + return values[slot1].compare(values[slot2]); +} - int32_t StringOrdValComparator::binarySearch(Collection lookup, const String& key, int32_t low, int32_t high) - { - Collection::iterator search = std::lower_bound(lookup.begin() + low, lookup.begin() + high, key); - int32_t keyPos = std::distance(lookup.begin(), search); - return (search == lookup.end() || key < *search) ? -(keyPos + 1) : keyPos; +int32_t StringOrdValComparator::compareBottom(int32_t doc) { + BOOST_ASSERT(bottomSlot != -1); + int32_t order = this->order[doc]; + int32_t cmp = bottomOrd - order; + if (cmp != 0) { + return cmp; } + return bottomValue.compare(lookup[order]); +} - void StringOrdValComparator::copy(int32_t slot, int32_t doc) - { - int32_t ord = order[doc]; - ords[slot] = ord; - BOOST_ASSERT(ord >= 0); - values[slot] = lookup[ord]; - readerGen[slot] = currentReaderGen; +void StringOrdValComparator::convert(int32_t slot) { + readerGen[slot] = currentReaderGen; + int32_t index = 0; + String value(values[slot]); + if (value.empty()) { + ords[slot] = 0; + return; } - void StringOrdValComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - StringIndexPtr currentReaderValues(FieldCache::DEFAULT()->getStringIndex(reader, field)); - ++currentReaderGen; - order = currentReaderValues->order; - lookup = currentReaderValues->lookup; - BOOST_ASSERT(!lookup.empty()); - if (bottomSlot != -1) - { - convert(bottomSlot); - bottomOrd = ords[bottomSlot]; + if (sortPos == 0 && bottomSlot != -1 && bottomSlot != slot) { + // Since we are the primary sort, the entries in the queue are bounded by bottomOrd + BOOST_ASSERT(bottomOrd < lookup.size()); + if (reversed) { + index = binarySearch(lookup, value, bottomOrd, lookup.size() - 1); + } else { + index = binarySearch(lookup, value, 0, bottomOrd); } + } else { + // Full binary search + index = binarySearch(lookup, value, 0, lookup.size() - 1); } - void StringOrdValComparator::setBottom(int32_t slot) - { - bottomSlot = slot; - if (readerGen[slot] != currentReaderGen) - convert(bottomSlot); - bottomOrd = ords[slot]; - BOOST_ASSERT(bottomOrd >= 0); - BOOST_ASSERT(bottomOrd < lookup.size()); - bottomValue = values[slot]; + if (index < 0) { + index = -index - 2; } - ComparableValue StringOrdValComparator::value(int32_t slot) - { - return values[slot]; - } + ords[slot] = index; +} - Collection StringOrdValComparator::getValues() - { - return values; - } +int32_t StringOrdValComparator::binarySearch(Collection lookup, const String& key, int32_t low, int32_t high) { + Collection::iterator search = std::lower_bound(lookup.begin() + low, lookup.begin() + high, key); + int32_t keyPos = std::distance(lookup.begin(), search); + return (search == lookup.end() || key < *search) ? -(keyPos + 1) : keyPos; +} - int32_t StringOrdValComparator::getBottomSlot() - { - return bottomSlot; - } +void StringOrdValComparator::copy(int32_t slot, int32_t doc) { + int32_t ord = order[doc]; + ords[slot] = ord; + BOOST_ASSERT(ord >= 0); + values[slot] = lookup[ord]; + readerGen[slot] = currentReaderGen; +} - String StringOrdValComparator::getField() - { - return field; +void StringOrdValComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + StringIndexPtr currentReaderValues(FieldCache::DEFAULT()->getStringIndex(reader, field)); + ++currentReaderGen; + order = currentReaderValues->order; + lookup = currentReaderValues->lookup; + BOOST_ASSERT(!lookup.empty()); + if (bottomSlot != -1) { + convert(bottomSlot); + bottomOrd = ords[bottomSlot]; } +} - StringValComparator::StringValComparator(int32_t numHits, const String& field) - { - this->values = Collection::newInstance(numHits); - this->field = field; +void StringOrdValComparator::setBottom(int32_t slot) { + bottomSlot = slot; + if (readerGen[slot] != currentReaderGen) { + convert(bottomSlot); } + bottomOrd = ords[slot]; + BOOST_ASSERT(bottomOrd >= 0); + BOOST_ASSERT(bottomOrd < lookup.size()); + bottomValue = values[slot]; +} - StringValComparator::~StringValComparator() - { - } +ComparableValue StringOrdValComparator::value(int32_t slot) { + return values[slot]; +} - int32_t StringValComparator::compare(int32_t slot1, int32_t slot2) - { - return values[slot1].compare(values[slot2]); - } +Collection StringOrdValComparator::getValues() { + return values; +} - int32_t StringValComparator::compareBottom(int32_t doc) - { - return bottom.compare(currentReaderValues[doc]); - } +int32_t StringOrdValComparator::getBottomSlot() { + return bottomSlot; +} - void StringValComparator::copy(int32_t slot, int32_t doc) - { - values[slot] = currentReaderValues[doc]; - } +String StringOrdValComparator::getField() { + return field; +} - void StringValComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); - } +StringValComparator::StringValComparator(int32_t numHits, const String& field) { + this->values = Collection::newInstance(numHits); + this->field = field; +} - void StringValComparator::setBottom(int32_t slot) - { - bottom = values[slot]; - } +StringValComparator::~StringValComparator() { +} + +int32_t StringValComparator::compare(int32_t slot1, int32_t slot2) { + return values[slot1].compare(values[slot2]); +} + +int32_t StringValComparator::compareBottom(int32_t doc) { + return bottom.compare(currentReaderValues[doc]); +} + +void StringValComparator::copy(int32_t slot, int32_t doc) { + values[slot] = currentReaderValues[doc]; +} + +void StringValComparator::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + currentReaderValues = FieldCache::DEFAULT()->getStrings(reader, field); +} + +void StringValComparator::setBottom(int32_t slot) { + bottom = values[slot]; +} + +ComparableValue StringValComparator::value(int32_t slot) { + return values[slot]; +} - ComparableValue StringValComparator::value(int32_t slot) - { - return values[slot]; - } } diff --git a/src/core/search/FieldComparatorSource.cpp b/src/core/search/FieldComparatorSource.cpp index edb76a91..fc00b814 100644 --- a/src/core/search/FieldComparatorSource.cpp +++ b/src/core/search/FieldComparatorSource.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "FieldComparatorSource.h" -namespace Lucene -{ - FieldComparatorSource::~FieldComparatorSource() - { - } +namespace Lucene { + +FieldComparatorSource::~FieldComparatorSource() { +} + } diff --git a/src/core/search/FieldDoc.cpp b/src/core/search/FieldDoc.cpp index cc25b5e0..e42ef6ed 100644 --- a/src/core/search/FieldDoc.cpp +++ b/src/core/search/FieldDoc.cpp @@ -7,28 +7,26 @@ #include "LuceneInc.h" #include "FieldDoc.h" -namespace Lucene -{ - FieldDoc::FieldDoc(int32_t doc, double score, Collection fields) : ScoreDoc(doc, score) - { - this->fields = fields; - } +namespace Lucene { - FieldDoc::~FieldDoc() - { - } +FieldDoc::FieldDoc(int32_t doc, double score, Collection fields) : ScoreDoc(doc, score) { + this->fields = fields; +} - String FieldDoc::toString() - { - StringStream buffer; - buffer << ScoreDoc::toString() << L"["; - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if (field != fields.begin()) - buffer << L", "; - buffer << *field; +FieldDoc::~FieldDoc() { +} + +String FieldDoc::toString() { + StringStream buffer; + buffer << ScoreDoc::toString() << L"["; + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if (field != fields.begin()) { + buffer << L", "; } - buffer << L"]"; - return buffer.str(); + buffer << *field; } + buffer << L"]"; + return buffer.str(); +} + } diff --git a/src/core/search/FieldDocSortedHitQueue.cpp b/src/core/search/FieldDocSortedHitQueue.cpp index 0ccf7a1f..8dc4d103 100644 --- a/src/core/search/FieldDocSortedHitQueue.cpp +++ b/src/core/search/FieldDocSortedHitQueue.cpp @@ -12,73 +12,69 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - FieldDocSortedHitQueue::FieldDocSortedHitQueue(int32_t size) : PriorityQueue(size) - { - } +namespace Lucene { - FieldDocSortedHitQueue::~FieldDocSortedHitQueue() - { - } +FieldDocSortedHitQueue::FieldDocSortedHitQueue(int32_t size) : PriorityQueue(size) { +} - void FieldDocSortedHitQueue::setFields(Collection fields) - { - this->fields = fields; - this->collators = hasCollators(fields); - } +FieldDocSortedHitQueue::~FieldDocSortedHitQueue() { +} - Collection FieldDocSortedHitQueue::getFields() - { - return fields; - } +void FieldDocSortedHitQueue::setFields(Collection fields) { + this->fields = fields; + this->collators = hasCollators(fields); +} - Collection FieldDocSortedHitQueue::hasCollators(Collection fields) - { - if (!fields) - return Collection(); - Collection ret(Collection::newInstance(fields.size())); - for (int32_t i = 0; i < fields.size(); ++i) - { - localePtr locale(fields[i]->getLocale()); - if (locale) - ret[i] = newInstance(*locale); +Collection FieldDocSortedHitQueue::getFields() { + return fields; +} + +Collection FieldDocSortedHitQueue::hasCollators(Collection fields) { + if (!fields) { + return Collection(); + } + Collection ret(Collection::newInstance(fields.size())); + for (int32_t i = 0; i < fields.size(); ++i) { + localePtr locale(fields[i]->getLocale()); + if (locale) { + ret[i] = newInstance(*locale); } - return ret; } + return ret; +} - bool FieldDocSortedHitQueue::lessThan(const FieldDocPtr& first, const FieldDocPtr& second) - { - int32_t n = fields.size(); - int32_t c = 0; - for (int32_t i = 0; i < n && c == 0; ++i) - { - int32_t type = fields[i]->getType(); - if (type == SortField::STRING) - { - String s1(VariantUtils::get(first->fields[i])); - String s2(VariantUtils::get(second->fields[i])); - if (!fields[i]->getLocale()) - c = s1.compare(s2); - else - c = collators[i]->compare(s1, s2); - } - else - { - c = VariantUtils::compareTo(first->fields[i], second->fields[i]); - if (type == SortField::SCORE) - c = -c; +bool FieldDocSortedHitQueue::lessThan(const FieldDocPtr& first, const FieldDocPtr& second) { + int32_t n = fields.size(); + int32_t c = 0; + for (int32_t i = 0; i < n && c == 0; ++i) { + int32_t type = fields[i]->getType(); + if (type == SortField::STRING) { + String s1(VariantUtils::get(first->fields[i])); + String s2(VariantUtils::get(second->fields[i])); + if (!fields[i]->getLocale()) { + c = s1.compare(s2); + } else { + c = collators[i]->compare(s1, s2); } - - // reverse sort - if (fields[i]->getReverse()) + } else { + c = VariantUtils::compareTo(first->fields[i], second->fields[i]); + if (type == SortField::SCORE) { c = -c; + } } - // avoid random sort order that could lead to duplicates - if (c == 0) - return (first->doc > second->doc); + // reverse sort + if (fields[i]->getReverse()) { + c = -c; + } + } - return (c > 0); + // avoid random sort order that could lead to duplicates + if (c == 0) { + return (first->doc > second->doc); } + + return (c > 0); +} + } diff --git a/src/core/search/FieldValueHitQueue.cpp b/src/core/search/FieldValueHitQueue.cpp index ee23a280..c589bbb3 100644 --- a/src/core/search/FieldValueHitQueue.cpp +++ b/src/core/search/FieldValueHitQueue.cpp @@ -11,138 +11,126 @@ #include "FieldDoc.h" #include "SortField.h" -namespace Lucene -{ - FieldValueHitQueue::FieldValueHitQueue(Collection fields, int32_t size) : HitQueueBase(size) - { - // When we get here, fields.size() is guaranteed to be > 0, therefore no need to check it again. - - // All these are required by this class's API - need to return arrays. Therefore even in the case - // of a single comparator, create an array anyway. - this->fields = fields; - int32_t numComparators = fields.size(); - comparators = Collection::newInstance(numComparators); - reverseMul = Collection::newInstance(numComparators); - } +namespace Lucene { - FieldValueHitQueue::~FieldValueHitQueue() - { - } +FieldValueHitQueue::FieldValueHitQueue(Collection fields, int32_t size) : HitQueueBase(size) { + // When we get here, fields.size() is guaranteed to be > 0, therefore no need to check it again. - FieldValueHitQueuePtr FieldValueHitQueue::create(Collection fields, int32_t size) - { - if (fields.empty()) - boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); + // All these are required by this class's API - need to return arrays. Therefore even in the case + // of a single comparator, create an array anyway. + this->fields = fields; + int32_t numComparators = fields.size(); + comparators = Collection::newInstance(numComparators); + reverseMul = Collection::newInstance(numComparators); +} - if (fields.size() == 1) - return newLucene(fields, size); - else - return newLucene(fields, size); - } +FieldValueHitQueue::~FieldValueHitQueue() { +} - Collection FieldValueHitQueue::getComparators() - { - return comparators; +FieldValueHitQueuePtr FieldValueHitQueue::create(Collection fields, int32_t size) { + if (fields.empty()) { + boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); } - Collection FieldValueHitQueue::getReverseMul() - { - return reverseMul; + if (fields.size() == 1) { + return newLucene(fields, size); + } else { + return newLucene(fields, size); } +} - FieldDocPtr FieldValueHitQueue::fillFields(const FieldValueHitQueueEntryPtr& entry) - { - int32_t n = comparators.size(); - Collection fields(Collection::newInstance(n)); - for (int32_t i = 0; i < n; ++i) - fields[i] = comparators[i]->value(entry->slot); - return newLucene(entry->doc, entry->score, fields); - } +Collection FieldValueHitQueue::getComparators() { + return comparators; +} - Collection FieldValueHitQueue::getFields() - { - return fields; - } +Collection FieldValueHitQueue::getReverseMul() { + return reverseMul; +} - FieldValueHitQueueEntry::FieldValueHitQueueEntry(int32_t slot, int32_t doc, double score) : ScoreDoc(doc, score) - { - this->slot = slot; +FieldDocPtr FieldValueHitQueue::fillFields(const FieldValueHitQueueEntryPtr& entry) { + int32_t n = comparators.size(); + Collection fields(Collection::newInstance(n)); + for (int32_t i = 0; i < n; ++i) { + fields[i] = comparators[i]->value(entry->slot); } + return newLucene(entry->doc, entry->score, fields); +} - FieldValueHitQueueEntry::~FieldValueHitQueueEntry() - { - } +Collection FieldValueHitQueue::getFields() { + return fields; +} - String FieldValueHitQueueEntry::toString() - { - StringStream buffer; - buffer << L"slot:" << slot << L" " << ScoreDoc::toString(); - return buffer.str(); - } +FieldValueHitQueueEntry::FieldValueHitQueueEntry(int32_t slot, int32_t doc, double score) : ScoreDoc(doc, score) { + this->slot = slot; +} - OneComparatorFieldValueHitQueue::OneComparatorFieldValueHitQueue(Collection fields, int32_t size) : FieldValueHitQueue(fields, size) - { - if (fields.empty()) - boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); +FieldValueHitQueueEntry::~FieldValueHitQueueEntry() { +} - SortFieldPtr field(fields[0]); - comparator = field->getComparator(size, 0); - oneReverseMul = field->reverse ? -1 : 1; +String FieldValueHitQueueEntry::toString() { + StringStream buffer; + buffer << L"slot:" << slot << L" " << ScoreDoc::toString(); + return buffer.str(); +} - comparators[0] = comparator; - reverseMul[0] = oneReverseMul; +OneComparatorFieldValueHitQueue::OneComparatorFieldValueHitQueue(Collection fields, int32_t size) : FieldValueHitQueue(fields, size) { + if (fields.empty()) { + boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); } - OneComparatorFieldValueHitQueue::~OneComparatorFieldValueHitQueue() - { - } + SortFieldPtr field(fields[0]); + comparator = field->getComparator(size, 0); + oneReverseMul = field->reverse ? -1 : 1; + + comparators[0] = comparator; + reverseMul[0] = oneReverseMul; +} - bool OneComparatorFieldValueHitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) - { - FieldValueHitQueueEntryPtr firstEntry(boost::static_pointer_cast(first)); - FieldValueHitQueueEntryPtr secondEntry(boost::static_pointer_cast(second)); +OneComparatorFieldValueHitQueue::~OneComparatorFieldValueHitQueue() { +} - BOOST_ASSERT(firstEntry != secondEntry); - BOOST_ASSERT(firstEntry->slot != secondEntry->slot); +bool OneComparatorFieldValueHitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { + FieldValueHitQueueEntryPtr firstEntry(boost::static_pointer_cast(first)); + FieldValueHitQueueEntryPtr secondEntry(boost::static_pointer_cast(second)); - int32_t c = oneReverseMul * comparator->compare(firstEntry->slot, secondEntry->slot); + BOOST_ASSERT(firstEntry != secondEntry); + BOOST_ASSERT(firstEntry->slot != secondEntry->slot); - // avoid random sort order that could lead to duplicates - return c != 0 ? (c > 0) : (firstEntry->doc > secondEntry->doc); - } + int32_t c = oneReverseMul * comparator->compare(firstEntry->slot, secondEntry->slot); - MultiComparatorsFieldValueHitQueue::MultiComparatorsFieldValueHitQueue(Collection fields, int32_t size) : FieldValueHitQueue(fields, size) - { - int32_t numComparators = comparators.size(); - for (int32_t i = 0; i < numComparators; ++i) - { - SortFieldPtr field(fields[i]); - reverseMul[i] = field->reverse ? -1 : 1; - comparators[i] = field->getComparator(size, i); - } - } + // avoid random sort order that could lead to duplicates + return c != 0 ? (c > 0) : (firstEntry->doc > secondEntry->doc); +} - MultiComparatorsFieldValueHitQueue::~MultiComparatorsFieldValueHitQueue() - { +MultiComparatorsFieldValueHitQueue::MultiComparatorsFieldValueHitQueue(Collection fields, int32_t size) : FieldValueHitQueue(fields, size) { + int32_t numComparators = comparators.size(); + for (int32_t i = 0; i < numComparators; ++i) { + SortFieldPtr field(fields[i]); + reverseMul[i] = field->reverse ? -1 : 1; + comparators[i] = field->getComparator(size, i); } +} - bool MultiComparatorsFieldValueHitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) - { - FieldValueHitQueueEntryPtr firstEntry(boost::static_pointer_cast(first)); - FieldValueHitQueueEntryPtr secondEntry(boost::static_pointer_cast(second)); +MultiComparatorsFieldValueHitQueue::~MultiComparatorsFieldValueHitQueue() { +} - BOOST_ASSERT(firstEntry != secondEntry); - BOOST_ASSERT(firstEntry->slot != secondEntry->slot); +bool MultiComparatorsFieldValueHitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { + FieldValueHitQueueEntryPtr firstEntry(boost::static_pointer_cast(first)); + FieldValueHitQueueEntryPtr secondEntry(boost::static_pointer_cast(second)); - int32_t numComparators = comparators.size(); - for (int32_t i = 0; i < numComparators; ++i) - { - int32_t c = reverseMul[i] * comparators[i]->compare(firstEntry->slot, secondEntry->slot); - if (c != 0) - return (c > 0); // Short circuit - } + BOOST_ASSERT(firstEntry != secondEntry); + BOOST_ASSERT(firstEntry->slot != secondEntry->slot); - // avoid random sort order that could lead to duplicates - return (firstEntry->doc > secondEntry->doc); + int32_t numComparators = comparators.size(); + for (int32_t i = 0; i < numComparators; ++i) { + int32_t c = reverseMul[i] * comparators[i]->compare(firstEntry->slot, secondEntry->slot); + if (c != 0) { + return (c > 0); // Short circuit + } } + + // avoid random sort order that could lead to duplicates + return (firstEntry->doc > secondEntry->doc); +} + } diff --git a/src/core/search/Filter.cpp b/src/core/search/Filter.cpp index dd4add26..8db26bf6 100644 --- a/src/core/search/Filter.cpp +++ b/src/core/search/Filter.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "Filter.h" -namespace Lucene -{ - Filter::~Filter() - { - } +namespace Lucene { + +Filter::~Filter() { +} + } diff --git a/src/core/search/FilterManager.cpp b/src/core/search/FilterManager.cpp index 04e95526..c5530135 100644 --- a/src/core/search/FilterManager.cpp +++ b/src/core/search/FilterManager.cpp @@ -10,115 +10,102 @@ #include "Filter.h" #include "MiscUtils.h" -namespace Lucene -{ - /// The default maximum number of Filters in the cache - const int32_t FilterManager::DEFAULT_CACHE_CLEAN_SIZE = 100; +namespace Lucene { - /// The default frequency of cache cleanup - const int64_t FilterManager::DEFAULT_CACHE_SLEEP_TIME = 1000 * 60 * 10; +/// The default maximum number of Filters in the cache +const int32_t FilterManager::DEFAULT_CACHE_CLEAN_SIZE = 100; - FilterManager::FilterManager() - { - } +/// The default frequency of cache cleanup +const int64_t FilterManager::DEFAULT_CACHE_SLEEP_TIME = 1000 * 60 * 10; - FilterManager::~FilterManager() - { - } +FilterManager::FilterManager() { +} - void FilterManager::initialize() - { - cache = MapIntFilterItem::newInstance(); - cacheCleanSize = DEFAULT_CACHE_CLEAN_SIZE; // Let the cache get to 100 items - cleanSleepTime = DEFAULT_CACHE_SLEEP_TIME; // 10 minutes between cleanings +FilterManager::~FilterManager() { +} - filterCleaner = newLucene(shared_from_this()); - filterCleaner->start(); - } +void FilterManager::initialize() { + cache = MapIntFilterItem::newInstance(); + cacheCleanSize = DEFAULT_CACHE_CLEAN_SIZE; // Let the cache get to 100 items + cleanSleepTime = DEFAULT_CACHE_SLEEP_TIME; // 10 minutes between cleanings - FilterManagerPtr FilterManager::getInstance() - { - static FilterManagerPtr manager; - if (!manager) - { - manager = newLucene(); - CycleCheck::addStatic(manager); - } - return manager; - } + filterCleaner = newLucene(shared_from_this()); + filterCleaner->start(); +} - void FilterManager::setCacheSize(int32_t cacheCleanSize) - { - this->cacheCleanSize = cacheCleanSize; +FilterManagerPtr FilterManager::getInstance() { + static FilterManagerPtr manager; + if (!manager) { + manager = newLucene(); + CycleCheck::addStatic(manager); } + return manager; +} - void FilterManager::setCleanThreadSleepTime(int64_t cleanSleepTime) - { - this->cleanSleepTime = cleanSleepTime; - } +void FilterManager::setCacheSize(int32_t cacheCleanSize) { + this->cacheCleanSize = cacheCleanSize; +} - FilterPtr FilterManager::getFilter(const FilterPtr& filter) - { - SyncLock parentLock(&cache); - FilterItemPtr fi(cache.get(filter->hashCode())); - if (fi) - { - fi->timestamp = MiscUtils::currentTimeMillis(); - return fi->filter; - } - cache.put(filter->hashCode(), newLucene(filter)); - return filter; - } +void FilterManager::setCleanThreadSleepTime(int64_t cleanSleepTime) { + this->cleanSleepTime = cleanSleepTime; +} - FilterItem::FilterItem(const FilterPtr& filter) - { - this->filter = filter; - this->timestamp = MiscUtils::currentTimeMillis(); +FilterPtr FilterManager::getFilter(const FilterPtr& filter) { + SyncLock parentLock(&cache); + FilterItemPtr fi(cache.get(filter->hashCode())); + if (fi) { + fi->timestamp = MiscUtils::currentTimeMillis(); + return fi->filter; } + cache.put(filter->hashCode(), newLucene(filter)); + return filter; +} - FilterItem::~FilterItem() - { - } +FilterItem::FilterItem(const FilterPtr& filter) { + this->filter = filter; + this->timestamp = MiscUtils::currentTimeMillis(); +} - FilterCleaner::FilterCleaner(const FilterManagerPtr& manager) - { - _manager = manager; - running = true; - } +FilterItem::~FilterItem() { +} - FilterCleaner::~FilterCleaner() - { - } +FilterCleaner::FilterCleaner(const FilterManagerPtr& manager) { + _manager = manager; + running = true; +} + +FilterCleaner::~FilterCleaner() { +} + +void FilterCleaner::run() { + while (running) { + FilterManagerPtr manager(_manager); - void FilterCleaner::run() - { - while (running) - { - FilterManagerPtr manager(_manager); + // sort items from oldest to newest we delete the oldest filters + if (manager->cache.size() > manager->cacheCleanSize) { + // empty the temporary set + sortedFilterItems.clear(); - // sort items from oldest to newest we delete the oldest filters - if (manager->cache.size() > manager->cacheCleanSize) { - // empty the temporary set - sortedFilterItems.clear(); - - { - SyncLock parentLock(&manager->cache); - for (MapIntFilterItem::iterator item = manager->cache.begin(); item != manager->cache.end(); ++item) - sortedFilterItems.put(item->second->timestamp, item->first); - int32_t numToDelete = (int32_t)((double)(sortedFilterItems.size() - manager->cacheCleanSize) * 1.5); - int32_t counter = 0; - // loop over the set and delete all of the cache entries not used in a while - for (MapLongInt::iterator item = sortedFilterItems.begin(); item != sortedFilterItems.end() && counter++ < numToDelete; ++item) - manager->cache.remove(item->second); + SyncLock parentLock(&manager->cache); + for (MapIntFilterItem::iterator item = manager->cache.begin(); item != manager->cache.end(); ++item) { + sortedFilterItems.put(item->second->timestamp, item->first); + } + int32_t numToDelete = (int32_t)((double)(sortedFilterItems.size() - manager->cacheCleanSize) * 1.5); + int32_t counter = 0; + // loop over the set and delete all of the cache entries not used in a while + for (MapLongInt::iterator item = sortedFilterItems.begin(); item != sortedFilterItems.end() && counter++ < numToDelete; ++item) { + manager->cache.remove(item->second); } - - // empty the set so we don't tie up the memory - sortedFilterItems.clear(); } - // take a nap - LuceneThread::threadSleep(manager->cleanSleepTime); + // empty the set so we don't tie up the memory + sortedFilterItems.clear(); } + + // take a nap + LuceneThread::threadSleep(manager->cleanSleepTime); } } + +} diff --git a/src/core/search/FilteredDocIdSet.cpp b/src/core/search/FilteredDocIdSet.cpp index a3a9d930..3daba8d7 100644 --- a/src/core/search/FilteredDocIdSet.cpp +++ b/src/core/search/FilteredDocIdSet.cpp @@ -8,38 +8,32 @@ #include "FilteredDocIdSet.h" #include "_FilteredDocIdSet.h" -namespace Lucene -{ - FilteredDocIdSet::FilteredDocIdSet(const DocIdSetPtr& innerSet) - { - this->innerSet = innerSet; - } - - FilteredDocIdSet::~FilteredDocIdSet() - { - } - - bool FilteredDocIdSet::isCacheable() - { - return innerSet->isCacheable(); - } - - DocIdSetIteratorPtr FilteredDocIdSet::iterator() - { - return newLucene(shared_from_this(), innerSet->iterator()); - } - - DefaultFilteredDocIdSetIterator::DefaultFilteredDocIdSetIterator(const FilteredDocIdSetPtr& filtered, const DocIdSetIteratorPtr& innerIter) : FilteredDocIdSetIterator(innerIter) - { - this->filtered = filtered; - } - - DefaultFilteredDocIdSetIterator::~DefaultFilteredDocIdSetIterator() - { - } - - bool DefaultFilteredDocIdSetIterator::match(int32_t docid) - { - return filtered->match(docid); - } +namespace Lucene { + +FilteredDocIdSet::FilteredDocIdSet(const DocIdSetPtr& innerSet) { + this->innerSet = innerSet; +} + +FilteredDocIdSet::~FilteredDocIdSet() { +} + +bool FilteredDocIdSet::isCacheable() { + return innerSet->isCacheable(); +} + +DocIdSetIteratorPtr FilteredDocIdSet::iterator() { + return newLucene(shared_from_this(), innerSet->iterator()); +} + +DefaultFilteredDocIdSetIterator::DefaultFilteredDocIdSetIterator(const FilteredDocIdSetPtr& filtered, const DocIdSetIteratorPtr& innerIter) : FilteredDocIdSetIterator(innerIter) { + this->filtered = filtered; +} + +DefaultFilteredDocIdSetIterator::~DefaultFilteredDocIdSetIterator() { +} + +bool DefaultFilteredDocIdSetIterator::match(int32_t docid) { + return filtered->match(docid); +} + } diff --git a/src/core/search/FilteredDocIdSetIterator.cpp b/src/core/search/FilteredDocIdSetIterator.cpp index f4c6921b..0d64ce76 100644 --- a/src/core/search/FilteredDocIdSetIterator.cpp +++ b/src/core/search/FilteredDocIdSetIterator.cpp @@ -7,52 +7,47 @@ #include "LuceneInc.h" #include "FilteredDocIdSetIterator.h" -namespace Lucene -{ - FilteredDocIdSetIterator::FilteredDocIdSetIterator(const DocIdSetIteratorPtr& innerIter) - { - if (!innerIter) - boost::throw_exception(IllegalArgumentException(L"null iterator")); - this->innerIter = innerIter; - this->doc = -1; - } +namespace Lucene { - FilteredDocIdSetIterator::~FilteredDocIdSetIterator() - { +FilteredDocIdSetIterator::FilteredDocIdSetIterator(const DocIdSetIteratorPtr& innerIter) { + if (!innerIter) { + boost::throw_exception(IllegalArgumentException(L"null iterator")); } + this->innerIter = innerIter; + this->doc = -1; +} - int32_t FilteredDocIdSetIterator::docID() - { - return doc; - } +FilteredDocIdSetIterator::~FilteredDocIdSetIterator() { +} - int32_t FilteredDocIdSetIterator::nextDoc() - { - while ((doc = innerIter->nextDoc()) != NO_MORE_DOCS) - { - if (match(doc)) - return doc; +int32_t FilteredDocIdSetIterator::docID() { + return doc; +} + +int32_t FilteredDocIdSetIterator::nextDoc() { + while ((doc = innerIter->nextDoc()) != NO_MORE_DOCS) { + if (match(doc)) { + return doc; } - return doc; } + return doc; +} - int32_t FilteredDocIdSetIterator::advance(int32_t target) - { - doc = innerIter->advance(target); - if (doc != NO_MORE_DOCS) - { - if (match(doc)) - return doc; - else - { - while ((doc = innerIter->nextDoc()) != NO_MORE_DOCS) - { - if (match(doc)) - return doc; +int32_t FilteredDocIdSetIterator::advance(int32_t target) { + doc = innerIter->advance(target); + if (doc != NO_MORE_DOCS) { + if (match(doc)) { + return doc; + } else { + while ((doc = innerIter->nextDoc()) != NO_MORE_DOCS) { + if (match(doc)) { + return doc; } - return doc; } + return doc; } - return doc; } + return doc; +} + } diff --git a/src/core/search/FilteredQuery.cpp b/src/core/search/FilteredQuery.cpp index cca924bd..a6dbaf78 100644 --- a/src/core/search/FilteredQuery.cpp +++ b/src/core/search/FilteredQuery.cpp @@ -12,201 +12,178 @@ #include "DocIdSet.h" #include "MiscUtils.h" -namespace Lucene -{ - FilteredQuery::FilteredQuery(const QueryPtr& query, const FilterPtr& filter) - { - this->query = query; - this->filter = filter; - } +namespace Lucene { - FilteredQuery::~FilteredQuery() - { - } +FilteredQuery::FilteredQuery(const QueryPtr& query, const FilterPtr& filter) { + this->query = query; + this->filter = filter; +} - WeightPtr FilteredQuery::createWeight(const SearcherPtr& searcher) - { - WeightPtr weight(query->createWeight(searcher)); - SimilarityPtr similarity(query->getSimilarity(searcher)); - return newLucene(shared_from_this(), weight, similarity); - } +FilteredQuery::~FilteredQuery() { +} - QueryPtr FilteredQuery::rewrite(const IndexReaderPtr& reader) - { - QueryPtr rewritten(query->rewrite(reader)); - if (rewritten != query) - { - FilteredQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone())); - cloneQuery->query = rewritten; - return cloneQuery; - } - else - return shared_from_this(); - } +WeightPtr FilteredQuery::createWeight(const SearcherPtr& searcher) { + WeightPtr weight(query->createWeight(searcher)); + SimilarityPtr similarity(query->getSimilarity(searcher)); + return newLucene(shared_from_this(), weight, similarity); +} - QueryPtr FilteredQuery::getQuery() - { - return query; +QueryPtr FilteredQuery::rewrite(const IndexReaderPtr& reader) { + QueryPtr rewritten(query->rewrite(reader)); + if (rewritten != query) { + FilteredQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone())); + cloneQuery->query = rewritten; + return cloneQuery; + } else { + return shared_from_this(); } +} - FilterPtr FilteredQuery::getFilter() - { - return filter; - } +QueryPtr FilteredQuery::getQuery() { + return query; +} - void FilteredQuery::extractTerms(SetTerm terms) - { - getQuery()->extractTerms(terms); - } +FilterPtr FilteredQuery::getFilter() { + return filter; +} - String FilteredQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"filtered(" << query->toString(field) << L")->" << filter->toString() << boostString(); - return buffer.str(); - } +void FilteredQuery::extractTerms(SetTerm terms) { + getQuery()->extractTerms(terms); +} - bool FilteredQuery::equals(const LuceneObjectPtr& other) - { - FilteredQueryPtr otherFilteredQuery(boost::dynamic_pointer_cast(other)); - if (!otherFilteredQuery) - return false; - return (Query::equals(other) && query->equals(otherFilteredQuery->query) && filter->equals(otherFilteredQuery->filter)); - } +String FilteredQuery::toString(const String& field) { + StringStream buffer; + buffer << L"filtered(" << query->toString(field) << L")->" << filter->toString() << boostString(); + return buffer.str(); +} - int32_t FilteredQuery::hashCode() - { - return query->hashCode() ^ filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); +bool FilteredQuery::equals(const LuceneObjectPtr& other) { + FilteredQueryPtr otherFilteredQuery(boost::dynamic_pointer_cast(other)); + if (!otherFilteredQuery) { + return false; } + return (Query::equals(other) && query->equals(otherFilteredQuery->query) && filter->equals(otherFilteredQuery->filter)); +} - LuceneObjectPtr FilteredQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(query, filter); - FilteredQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); - cloneQuery->query = query; - cloneQuery->filter = filter; - return cloneQuery; - } +int32_t FilteredQuery::hashCode() { + return query->hashCode() ^ filter->hashCode() + MiscUtils::doubleToIntBits(getBoost()); +} - FilteredQueryWeight::FilteredQueryWeight(const FilteredQueryPtr& query, const WeightPtr& weight, const SimilarityPtr& similarity) - { - this->query = query; - this->weight = weight; - this->similarity = similarity; - value = 0.0; - } +LuceneObjectPtr FilteredQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(query, filter); + FilteredQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); + cloneQuery->query = query; + cloneQuery->filter = filter; + return cloneQuery; +} - FilteredQueryWeight::~FilteredQueryWeight() - { - } +FilteredQueryWeight::FilteredQueryWeight(const FilteredQueryPtr& query, const WeightPtr& weight, const SimilarityPtr& similarity) { + this->query = query; + this->weight = weight; + this->similarity = similarity; + value = 0.0; +} - double FilteredQueryWeight::getValue() - { - return value; - } +FilteredQueryWeight::~FilteredQueryWeight() { +} - double FilteredQueryWeight::sumOfSquaredWeights() - { - return weight->sumOfSquaredWeights() * query->getBoost() * query->getBoost(); - } +double FilteredQueryWeight::getValue() { + return value; +} - void FilteredQueryWeight::normalize(double norm) - { - weight->normalize(norm); - value = weight->getValue() * query->getBoost(); - } +double FilteredQueryWeight::sumOfSquaredWeights() { + return weight->sumOfSquaredWeights() * query->getBoost() * query->getBoost(); +} - ExplanationPtr FilteredQueryWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - ExplanationPtr inner(weight->explain(reader, doc)); - if (query->getBoost() !=1) - { - ExplanationPtr preBoost(inner); - inner = newLucene(inner->getValue() * query->getBoost(), L"product of:"); - inner->addDetail(newLucene(query->getBoost(), L"boost")); - inner->addDetail(preBoost); - } - FilterPtr f(query->filter); - DocIdSetPtr docIdSet(f->getDocIdSet(reader)); - DocIdSetIteratorPtr docIdSetIterator(!docIdSet ? DocIdSet::EMPTY_DOCIDSET()->iterator() : docIdSet->iterator()); - if (!docIdSetIterator) - docIdSetIterator = DocIdSet::EMPTY_DOCIDSET()->iterator(); - if (docIdSetIterator->advance(doc) == doc) - return inner; - else - { - ExplanationPtr result(newLucene(0.0, L"failure to match filter: " + f->toString())); - result->addDetail(inner); - return result; - } - } +void FilteredQueryWeight::normalize(double norm) { + weight->normalize(norm); + value = weight->getValue() * query->getBoost(); +} - QueryPtr FilteredQueryWeight::getQuery() - { - return query; +ExplanationPtr FilteredQueryWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + ExplanationPtr inner(weight->explain(reader, doc)); + if (query->getBoost() !=1) { + ExplanationPtr preBoost(inner); + inner = newLucene(inner->getValue() * query->getBoost(), L"product of:"); + inner->addDetail(newLucene(query->getBoost(), L"boost")); + inner->addDetail(preBoost); + } + FilterPtr f(query->filter); + DocIdSetPtr docIdSet(f->getDocIdSet(reader)); + DocIdSetIteratorPtr docIdSetIterator(!docIdSet ? DocIdSet::EMPTY_DOCIDSET()->iterator() : docIdSet->iterator()); + if (!docIdSetIterator) { + docIdSetIterator = DocIdSet::EMPTY_DOCIDSET()->iterator(); + } + if (docIdSetIterator->advance(doc) == doc) { + return inner; + } else { + ExplanationPtr result(newLucene(0.0, L"failure to match filter: " + f->toString())); + result->addDetail(inner); + return result; } +} - ScorerPtr FilteredQueryWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - ScorerPtr scorer(weight->scorer(reader, true, false)); - if (!scorer) - return ScorerPtr(); - DocIdSetPtr docIdSet(query->filter->getDocIdSet(reader)); - if (!docIdSet) - return ScorerPtr(); - DocIdSetIteratorPtr docIdSetIterator(docIdSet->iterator()); - if (!docIdSetIterator) - return ScorerPtr(); - return newLucene(shared_from_this(), scorer, docIdSetIterator, similarity); - } +QueryPtr FilteredQueryWeight::getQuery() { + return query; +} - FilteredQueryWeightScorer::FilteredQueryWeightScorer(const FilteredQueryWeightPtr& weight, const ScorerPtr& scorer, const DocIdSetIteratorPtr& docIdSetIterator, const SimilarityPtr& similarity) : Scorer(similarity) - { - this->weight = weight; - this->scorer = scorer; - this->docIdSetIterator = docIdSetIterator; - doc = -1; +ScorerPtr FilteredQueryWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + ScorerPtr scorer(weight->scorer(reader, true, false)); + if (!scorer) { + return ScorerPtr(); } - - FilteredQueryWeightScorer::~FilteredQueryWeightScorer() - { + DocIdSetPtr docIdSet(query->filter->getDocIdSet(reader)); + if (!docIdSet) { + return ScorerPtr(); + } + DocIdSetIteratorPtr docIdSetIterator(docIdSet->iterator()); + if (!docIdSetIterator) { + return ScorerPtr(); } + return newLucene(shared_from_this(), scorer, docIdSetIterator, similarity); +} - int32_t FilteredQueryWeightScorer::advanceToCommon(int32_t scorerDoc, int32_t disiDoc) - { - while (scorerDoc != disiDoc) - { - if (scorerDoc < disiDoc) - scorerDoc = scorer->advance(disiDoc); - else - disiDoc = docIdSetIterator->advance(scorerDoc); +FilteredQueryWeightScorer::FilteredQueryWeightScorer(const FilteredQueryWeightPtr& weight, const ScorerPtr& scorer, const DocIdSetIteratorPtr& docIdSetIterator, const SimilarityPtr& similarity) : Scorer(similarity) { + this->weight = weight; + this->scorer = scorer; + this->docIdSetIterator = docIdSetIterator; + doc = -1; +} + +FilteredQueryWeightScorer::~FilteredQueryWeightScorer() { +} + +int32_t FilteredQueryWeightScorer::advanceToCommon(int32_t scorerDoc, int32_t disiDoc) { + while (scorerDoc != disiDoc) { + if (scorerDoc < disiDoc) { + scorerDoc = scorer->advance(disiDoc); + } else { + disiDoc = docIdSetIterator->advance(scorerDoc); } - return scorerDoc; } + return scorerDoc; +} - int32_t FilteredQueryWeightScorer::nextDoc() - { - int32_t disiDoc = docIdSetIterator->nextDoc(); - int32_t scorerDoc = scorer->nextDoc(); - doc = (scorerDoc != NO_MORE_DOCS && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS) ? scorer->docID() : NO_MORE_DOCS; - return doc; - } +int32_t FilteredQueryWeightScorer::nextDoc() { + int32_t disiDoc = docIdSetIterator->nextDoc(); + int32_t scorerDoc = scorer->nextDoc(); + doc = (scorerDoc != NO_MORE_DOCS && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS) ? scorer->docID() : NO_MORE_DOCS; + return doc; +} - int32_t FilteredQueryWeightScorer::docID() - { - return doc; - } +int32_t FilteredQueryWeightScorer::docID() { + return doc; +} - int32_t FilteredQueryWeightScorer::advance(int32_t target) - { - int32_t disiDoc = docIdSetIterator->advance(target); - int32_t scorerDoc = scorer->advance(target); - doc = (scorerDoc != NO_MORE_DOCS && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS) ? scorer->docID() : NO_MORE_DOCS; - return doc; - } +int32_t FilteredQueryWeightScorer::advance(int32_t target) { + int32_t disiDoc = docIdSetIterator->advance(target); + int32_t scorerDoc = scorer->advance(target); + doc = (scorerDoc != NO_MORE_DOCS && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS) ? scorer->docID() : NO_MORE_DOCS; + return doc; +} + +double FilteredQueryWeightScorer::score() { + return weight->query->getBoost() * scorer->score(); +} - double FilteredQueryWeightScorer::score() - { - return weight->query->getBoost() * scorer->score(); - } } diff --git a/src/core/search/FilteredTermEnum.cpp b/src/core/search/FilteredTermEnum.cpp index fb0d28c6..b4473ad8 100644 --- a/src/core/search/FilteredTermEnum.cpp +++ b/src/core/search/FilteredTermEnum.cpp @@ -7,66 +7,63 @@ #include "LuceneInc.h" #include "FilteredTermEnum.h" -namespace Lucene -{ - FilteredTermEnum::~FilteredTermEnum() - { - } +namespace Lucene { + +FilteredTermEnum::~FilteredTermEnum() { +} - void FilteredTermEnum::setEnum(const TermEnumPtr& actualEnum) - { - this->actualEnum = actualEnum; - // Find the first term that matches - TermPtr term(actualEnum->term()); - if (term && termCompare(term)) - currentTerm = term; - else - next(); +void FilteredTermEnum::setEnum(const TermEnumPtr& actualEnum) { + this->actualEnum = actualEnum; + // Find the first term that matches + TermPtr term(actualEnum->term()); + if (term && termCompare(term)) { + currentTerm = term; + } else { + next(); } +} - int32_t FilteredTermEnum::docFreq() - { - if (!currentTerm) - return -1; - BOOST_ASSERT(actualEnum); - return actualEnum->docFreq(); +int32_t FilteredTermEnum::docFreq() { + if (!currentTerm) { + return -1; } + BOOST_ASSERT(actualEnum); + return actualEnum->docFreq(); +} - bool FilteredTermEnum::next() - { - if (!actualEnum) - return false; // the actual enumerator is not initialized - currentTerm.reset(); - while (!currentTerm) - { - if (endEnum()) - return false; - if (actualEnum->next()) - { - TermPtr term(actualEnum->term()); - if (termCompare(term)) - { - currentTerm = term; - return true; - } +bool FilteredTermEnum::next() { + if (!actualEnum) { + return false; // the actual enumerator is not initialized + } + currentTerm.reset(); + while (!currentTerm) { + if (endEnum()) { + return false; + } + if (actualEnum->next()) { + TermPtr term(actualEnum->term()); + if (termCompare(term)) { + currentTerm = term; + return true; } - else - return false; + } else { + return false; } - currentTerm.reset(); - return false; } + currentTerm.reset(); + return false; +} - TermPtr FilteredTermEnum::term() - { - return currentTerm; - } +TermPtr FilteredTermEnum::term() { + return currentTerm; +} - void FilteredTermEnum::close() - { - if (actualEnum) - actualEnum->close(); - currentTerm.reset(); - actualEnum.reset(); +void FilteredTermEnum::close() { + if (actualEnum) { + actualEnum->close(); } + currentTerm.reset(); + actualEnum.reset(); +} + } diff --git a/src/core/search/FuzzyQuery.cpp b/src/core/search/FuzzyQuery.cpp index f39417d0..52919956 100644 --- a/src/core/search/FuzzyQuery.cpp +++ b/src/core/search/FuzzyQuery.cpp @@ -14,205 +14,192 @@ #include "BooleanClause.h" #include "MiscUtils.h" -namespace Lucene -{ - const int32_t FuzzyQuery::defaultPrefixLength = 0; +namespace Lucene { - FuzzyQuery::FuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) - { - ConstructQuery(term, minimumSimilarity, prefixLength); - } - - FuzzyQuery::FuzzyQuery(const TermPtr& term, double minimumSimilarity) - { - ConstructQuery(term, minimumSimilarity, defaultPrefixLength); - } +const int32_t FuzzyQuery::defaultPrefixLength = 0; - FuzzyQuery::FuzzyQuery(const TermPtr& term) - { - ConstructQuery(term, defaultMinSimilarity(), defaultPrefixLength); - } +FuzzyQuery::FuzzyQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) { + ConstructQuery(term, minimumSimilarity, prefixLength); +} - FuzzyQuery::~FuzzyQuery() - { - } +FuzzyQuery::FuzzyQuery(const TermPtr& term, double minimumSimilarity) { + ConstructQuery(term, minimumSimilarity, defaultPrefixLength); +} - void FuzzyQuery::ConstructQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) - { - this->term = term; +FuzzyQuery::FuzzyQuery(const TermPtr& term) { + ConstructQuery(term, defaultMinSimilarity(), defaultPrefixLength); +} - if (minimumSimilarity >= 1.0) - boost::throw_exception(IllegalArgumentException(L"minimumSimilarity >= 1")); - else if (minimumSimilarity < 0.0) - boost::throw_exception(IllegalArgumentException(L"minimumSimilarity < 0")); - if (prefixLength < 0) - boost::throw_exception(IllegalArgumentException(L"prefixLength < 0")); +FuzzyQuery::~FuzzyQuery() { +} - this->termLongEnough = ((int32_t)term->text().length() > (int32_t)(1.0 / (1.0 - minimumSimilarity))); +void FuzzyQuery::ConstructQuery(const TermPtr& term, double minimumSimilarity, int32_t prefixLength) { + this->term = term; - this->minimumSimilarity = minimumSimilarity; - this->prefixLength = prefixLength; - rewriteMethod = SCORING_BOOLEAN_QUERY_REWRITE(); + if (minimumSimilarity >= 1.0) { + boost::throw_exception(IllegalArgumentException(L"minimumSimilarity >= 1")); + } else if (minimumSimilarity < 0.0) { + boost::throw_exception(IllegalArgumentException(L"minimumSimilarity < 0")); } - - double FuzzyQuery::defaultMinSimilarity() - { - const double _defaultMinSimilarity = 0.5; - return _defaultMinSimilarity; + if (prefixLength < 0) { + boost::throw_exception(IllegalArgumentException(L"prefixLength < 0")); } - double FuzzyQuery::getMinSimilarity() - { - return minimumSimilarity; - } + this->termLongEnough = ((int32_t)term->text().length() > (int32_t)(1.0 / (1.0 - minimumSimilarity))); - int32_t FuzzyQuery::getPrefixLength() - { - return prefixLength; - } + this->minimumSimilarity = minimumSimilarity; + this->prefixLength = prefixLength; + rewriteMethod = SCORING_BOOLEAN_QUERY_REWRITE(); +} - FilteredTermEnumPtr FuzzyQuery::getEnum(const IndexReaderPtr& reader) - { - return newLucene(reader, getTerm(), minimumSimilarity, prefixLength); - } +double FuzzyQuery::defaultMinSimilarity() { + const double _defaultMinSimilarity = 0.5; + return _defaultMinSimilarity; +} - TermPtr FuzzyQuery::getTerm() - { - return term; - } +double FuzzyQuery::getMinSimilarity() { + return minimumSimilarity; +} - void FuzzyQuery::setRewriteMethod(const RewriteMethodPtr& method) - { - boost::throw_exception(UnsupportedOperationException(L"FuzzyQuery cannot change rewrite method")); - } +int32_t FuzzyQuery::getPrefixLength() { + return prefixLength; +} + +FilteredTermEnumPtr FuzzyQuery::getEnum(const IndexReaderPtr& reader) { + return newLucene(reader, getTerm(), minimumSimilarity, prefixLength); +} + +TermPtr FuzzyQuery::getTerm() { + return term; +} - QueryPtr FuzzyQuery::rewrite(const IndexReaderPtr& reader) - { - if (!termLongEnough) // can only match if it's exact - return newLucene(term); - - int32_t maxSize = BooleanQuery::getMaxClauseCount(); - ScoreTermQueuePtr stQueue(newLucene(1024)); - FilteredTermEnumPtr enumerator(getEnum(reader)); - LuceneException finally; - try - { - ScoreTermPtr st = newLucene(); - do - { - TermPtr t(enumerator->term()); - if (!t) - break; - double score = enumerator->difference(); - // ignore uncompetitive hits - if (stQueue->size() >= maxSize && score <= stQueue->top()->score) - continue; - // add new entry in PQ - st->term = t; - st->score = score; - stQueue->add(st); - // possibly drop entries from queue - st = (stQueue->size() > maxSize) ? stQueue->pop() : newLucene(); +void FuzzyQuery::setRewriteMethod(const RewriteMethodPtr& method) { + boost::throw_exception(UnsupportedOperationException(L"FuzzyQuery cannot change rewrite method")); +} + +QueryPtr FuzzyQuery::rewrite(const IndexReaderPtr& reader) { + if (!termLongEnough) { // can only match if it's exact + return newLucene(term); + } + + int32_t maxSize = BooleanQuery::getMaxClauseCount(); + ScoreTermQueuePtr stQueue(newLucene(1024)); + FilteredTermEnumPtr enumerator(getEnum(reader)); + LuceneException finally; + try { + ScoreTermPtr st = newLucene(); + do { + TermPtr t(enumerator->term()); + if (!t) { + break; } - while (enumerator->next()); - } - catch (LuceneException& e) - { - finally = e; - } - enumerator->close(); - finally.throwException(); - - BooleanQueryPtr query(newLucene(true)); - int32_t size = stQueue->size(); - for (int32_t i = 0; i < size; ++i) - { - ScoreTermPtr st(stQueue->pop()); - TermQueryPtr tq(newLucene(st->term)); // found a match - tq->setBoost(getBoost() * st->score); // set the boost - query->add(tq, BooleanClause::SHOULD); // add to query - } + double score = enumerator->difference(); + // ignore uncompetitive hits + if (stQueue->size() >= maxSize && score <= stQueue->top()->score) { + continue; + } + // add new entry in PQ + st->term = t; + st->score = score; + stQueue->add(st); + // possibly drop entries from queue + st = (stQueue->size() > maxSize) ? stQueue->pop() : newLucene(); + } while (enumerator->next()); + } catch (LuceneException& e) { + finally = e; + } + enumerator->close(); + finally.throwException(); + + BooleanQueryPtr query(newLucene(true)); + int32_t size = stQueue->size(); + for (int32_t i = 0; i < size; ++i) { + ScoreTermPtr st(stQueue->pop()); + TermQueryPtr tq(newLucene(st->term)); // found a match + tq->setBoost(getBoost() * st->score); // set the boost + query->add(tq, BooleanClause::SHOULD); // add to query + } + + return query; +} - return query; - } +LuceneObjectPtr FuzzyQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); + FuzzyQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->minimumSimilarity = minimumSimilarity; + cloneQuery->prefixLength = prefixLength; + cloneQuery->termLongEnough = termLongEnough; + cloneQuery->term = term; + return cloneQuery; +} - LuceneObjectPtr FuzzyQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); - FuzzyQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->minimumSimilarity = minimumSimilarity; - cloneQuery->prefixLength = prefixLength; - cloneQuery->termLongEnough = termLongEnough; - cloneQuery->term = term; - return cloneQuery; +String FuzzyQuery::toString(const String& field) { + StringStream buffer; + if (term->field() != field) { + buffer << term->field() << L":"; } + buffer << term->text() << L"~" << minimumSimilarity << boostString(); + return buffer.str(); +} - String FuzzyQuery::toString(const String& field) - { - StringStream buffer; - if (term->field() != field) - buffer << term->field() << L":"; - buffer << term->text() << L"~" << minimumSimilarity << boostString(); - return buffer.str(); - } +int32_t FuzzyQuery::hashCode() { + int32_t prime = 31; + int32_t result = MultiTermQuery::hashCode(); + result = prime * result + MiscUtils::doubleToIntBits(minimumSimilarity); + result = prime * result + prefixLength; + result = prime * result + (term ? term->hashCode() : 0); + return result; +} - int32_t FuzzyQuery::hashCode() - { - int32_t prime = 31; - int32_t result = MultiTermQuery::hashCode(); - result = prime * result + MiscUtils::doubleToIntBits(minimumSimilarity); - result = prime * result + prefixLength; - result = prime * result + (term ? term->hashCode() : 0); - return result; +bool FuzzyQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - - bool FuzzyQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!MultiTermQuery::equals(other)) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - FuzzyQueryPtr otherFuzzyQuery(boost::dynamic_pointer_cast(other)); - if (!otherFuzzyQuery) - return false; - if (MiscUtils::doubleToIntBits(minimumSimilarity) != MiscUtils::doubleToIntBits(otherFuzzyQuery->minimumSimilarity)) - return false; - if (prefixLength != otherFuzzyQuery->prefixLength) + if (!MultiTermQuery::equals(other)) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + FuzzyQueryPtr otherFuzzyQuery(boost::dynamic_pointer_cast(other)); + if (!otherFuzzyQuery) { + return false; + } + if (MiscUtils::doubleToIntBits(minimumSimilarity) != MiscUtils::doubleToIntBits(otherFuzzyQuery->minimumSimilarity)) { + return false; + } + if (prefixLength != otherFuzzyQuery->prefixLength) { + return false; + } + if (!term) { + if (otherFuzzyQuery->term) { return false; - if (!term) - { - if (otherFuzzyQuery->term) - return false; } - else if (!term->equals(otherFuzzyQuery->term)) - return false; - return true; + } else if (!term->equals(otherFuzzyQuery->term)) { + return false; } + return true; +} - ScoreTerm::~ScoreTerm() - { - } +ScoreTerm::~ScoreTerm() { +} - int32_t ScoreTerm::compareTo(const ScoreTermPtr& other) - { - if (this->score == other->score) - return other->term->compareTo(this->term); - else - return this->score < other->score ? -1 : (this->score > other->score ? 1 : 0); +int32_t ScoreTerm::compareTo(const ScoreTermPtr& other) { + if (this->score == other->score) { + return other->term->compareTo(this->term); + } else { + return this->score < other->score ? -1 : (this->score > other->score ? 1 : 0); } +} - ScoreTermQueue::ScoreTermQueue(int32_t size) : PriorityQueue(size) - { - } +ScoreTermQueue::ScoreTermQueue(int32_t size) : PriorityQueue(size) { +} - ScoreTermQueue::~ScoreTermQueue() - { - } +ScoreTermQueue::~ScoreTermQueue() { +} + +bool ScoreTermQueue::lessThan(const ScoreTermPtr& first, const ScoreTermPtr& second) { + return (first->compareTo(second) < 0); +} - bool ScoreTermQueue::lessThan(const ScoreTermPtr& first, const ScoreTermPtr& second) - { - return (first->compareTo(second) < 0); - } } diff --git a/src/core/search/FuzzyTermEnum.cpp b/src/core/search/FuzzyTermEnum.cpp index ead9e7fd..36e66aab 100644 --- a/src/core/search/FuzzyTermEnum.cpp +++ b/src/core/search/FuzzyTermEnum.cpp @@ -11,155 +11,144 @@ #include "Term.h" #include "IndexReader.h" -namespace Lucene -{ - FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength) - { - ConstructTermEnum(reader, term, minSimilarity, prefixLength); - } +namespace Lucene { - FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity) - { - ConstructTermEnum(reader, term, minSimilarity, FuzzyQuery::defaultPrefixLength); - } +FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength) { + ConstructTermEnum(reader, term, minSimilarity, prefixLength); +} - FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term) - { - ConstructTermEnum(reader, term, FuzzyQuery::defaultMinSimilarity(), FuzzyQuery::defaultPrefixLength); - } +FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity) { + ConstructTermEnum(reader, term, minSimilarity, FuzzyQuery::defaultPrefixLength); +} - FuzzyTermEnum::~FuzzyTermEnum() - { +FuzzyTermEnum::FuzzyTermEnum(const IndexReaderPtr& reader, const TermPtr& term) { + ConstructTermEnum(reader, term, FuzzyQuery::defaultMinSimilarity(), FuzzyQuery::defaultPrefixLength); +} + +FuzzyTermEnum::~FuzzyTermEnum() { +} + +void FuzzyTermEnum::ConstructTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength) { + if (minSimilarity >= 1.0) { + boost::throw_exception(IllegalArgumentException(L"minimumSimilarity cannot be greater than or equal to 1")); + } else if (minSimilarity < 0.0) { + boost::throw_exception(IllegalArgumentException(L"minimumSimilarity cannot be less than 0")); + } + if (prefixLength < 0) { + boost::throw_exception(IllegalArgumentException(L"prefixLength cannot be less than 0")); } - void FuzzyTermEnum::ConstructTermEnum(const IndexReaderPtr& reader, const TermPtr& term, double minSimilarity, int32_t prefixLength) - { - if (minSimilarity >= 1.0) - boost::throw_exception(IllegalArgumentException(L"minimumSimilarity cannot be greater than or equal to 1")); - else if (minSimilarity < 0.0) - boost::throw_exception(IllegalArgumentException(L"minimumSimilarity cannot be less than 0")); - if (prefixLength < 0) - boost::throw_exception(IllegalArgumentException(L"prefixLength cannot be less than 0")); - - this->minimumSimilarity = minSimilarity; - this->scale_factor = 1.0 / (1.0 - minimumSimilarity); - this->searchTerm = term; - this->field = searchTerm->field(); - this->_endEnum = false; - this->_similarity = 0.0; - - // The prefix could be longer than the word. - // It's kind of silly though. It means we must match the entire word. - int32_t fullSearchTermLength = searchTerm->text().length(); - int32_t realPrefixLength = prefixLength > fullSearchTermLength ? fullSearchTermLength : prefixLength; - - this->text = searchTerm->text().substr(realPrefixLength); - this->prefix = searchTerm->text().substr(0, realPrefixLength); - - this->p = Collection::newInstance(this->text.length() + 1); - this->d = Collection::newInstance(this->text.length() + 1); - - setEnum(reader->terms(newLucene(searchTerm->field(), prefix))); + this->minimumSimilarity = minSimilarity; + this->scale_factor = 1.0 / (1.0 - minimumSimilarity); + this->searchTerm = term; + this->field = searchTerm->field(); + this->_endEnum = false; + this->_similarity = 0.0; + + // The prefix could be longer than the word. + // It's kind of silly though. It means we must match the entire word. + int32_t fullSearchTermLength = searchTerm->text().length(); + int32_t realPrefixLength = prefixLength > fullSearchTermLength ? fullSearchTermLength : prefixLength; + + this->text = searchTerm->text().substr(realPrefixLength); + this->prefix = searchTerm->text().substr(0, realPrefixLength); + + this->p = Collection::newInstance(this->text.length() + 1); + this->d = Collection::newInstance(this->text.length() + 1); + + setEnum(reader->terms(newLucene(searchTerm->field(), prefix))); +} + +bool FuzzyTermEnum::termCompare(const TermPtr& term) { + if (field == term->field() && boost::starts_with(term->text(), prefix)) { + String target(term->text().substr(prefix.length())); + this->_similarity = similarity(target); + return (_similarity > minimumSimilarity); } + _endEnum = true; + return false; +} - bool FuzzyTermEnum::termCompare(const TermPtr& term) - { - if (field == term->field() && boost::starts_with(term->text(), prefix)) - { - String target(term->text().substr(prefix.length())); - this->_similarity = similarity(target); - return (_similarity > minimumSimilarity); - } - _endEnum = true; - return false; +double FuzzyTermEnum::difference() { + return (_similarity - minimumSimilarity) * scale_factor; +} + +bool FuzzyTermEnum::endEnum() { + return _endEnum; +} + +double FuzzyTermEnum::similarity(const String& target) { + int32_t m = target.length(); + int32_t n = text.length(); + if (n == 0) { + // We don't have anything to compare. That means if we just add the letters for m we get the new word + return prefix.empty() ? 0.0 : 1.0 - ((double)m / (double)prefix.length()); } + if (m == 0) { + return prefix.empty() ? 0.0 : 1.0 - ((double)n / (double)prefix.length()); + } + + int32_t maxDistance = calculateMaxDistance(m); - double FuzzyTermEnum::difference() - { - return (_similarity - minimumSimilarity) * scale_factor; + if (maxDistance < std::abs(m - n)) { + // Just adding the characters of m to n or vice-versa results in too many edits for example "pre" length + // is 3 and "prefixes" length is 8. We can see that given this optimal circumstance, the edit distance + // cannot be less than 5. which is 8-3 or more precisely std::abs(3 - 8). if our maximum edit distance + // is 4, then we can discard this word without looking at it. + return 0.0; } - bool FuzzyTermEnum::endEnum() - { - return _endEnum; + // init matrix d + for (int32_t i = 0; i <= n; ++i) { + p[i] = i; } - double FuzzyTermEnum::similarity(const String& target) - { - int32_t m = target.length(); - int32_t n = text.length(); - if (n == 0) - { - // We don't have anything to compare. That means if we just add the letters for m we get the new word - return prefix.empty() ? 0.0 : 1.0 - ((double)m / (double)prefix.length()); + // start computing edit distance + for (int32_t j = 1; j <= m; ++j) { // iterates through target + int32_t bestPossibleEditDistance = m; + wchar_t t_j = target[j - 1]; // jth character of t + d[0] = j; + + for (int32_t i = 1; i <= n; ++i) { // iterates through text + // minimum of cell to the left+1, to the top+1, diagonally left and up +(0|1) + if (t_j != text[i - 1]) { + d[i] = std::min(std::min(d[i - 1], p[i]), p[i - 1]) + 1; + } else { + d[i] = std::min(std::min(d[i - 1] + 1, p[i] + 1), p[i - 1]); + } + bestPossibleEditDistance = std::min(bestPossibleEditDistance, d[i]); } - if (m == 0) - return prefix.empty() ? 0.0 : 1.0 - ((double)n / (double)prefix.length()); - int32_t maxDistance = calculateMaxDistance(m); + // After calculating row i, the best possible edit distance can be found by found by finding the smallest + // value in a given column. If the bestPossibleEditDistance is greater than the max distance, abort. - if (maxDistance < std::abs(m - n)) - { - // Just adding the characters of m to n or vice-versa results in too many edits for example "pre" length - // is 3 and "prefixes" length is 8. We can see that given this optimal circumstance, the edit distance - // cannot be less than 5. which is 8-3 or more precisely std::abs(3 - 8). if our maximum edit distance - // is 4, then we can discard this word without looking at it. + if (j > maxDistance && bestPossibleEditDistance > maxDistance) { // equal is okay, but not greater + // The closest the target can be to the text is just too far away. + // This target is leaving the party early. return 0.0; } - // init matrix d - for (int32_t i = 0; i <= n; ++i) - p[i] = i; - - // start computing edit distance - for (int32_t j = 1; j <= m; ++j) // iterates through target - { - int32_t bestPossibleEditDistance = m; - wchar_t t_j = target[j - 1]; // jth character of t - d[0] = j; - - for (int32_t i = 1; i <= n; ++i) // iterates through text - { - // minimum of cell to the left+1, to the top+1, diagonally left and up +(0|1) - if (t_j != text[i - 1]) - d[i] = std::min(std::min(d[i - 1], p[i]), p[i - 1]) + 1; - else - d[i] = std::min(std::min(d[i - 1] + 1, p[i] + 1), p[i - 1]); - bestPossibleEditDistance = std::min(bestPossibleEditDistance, d[i]); - } - - // After calculating row i, the best possible edit distance can be found by found by finding the smallest - // value in a given column. If the bestPossibleEditDistance is greater than the max distance, abort. - - if (j > maxDistance && bestPossibleEditDistance > maxDistance) // equal is okay, but not greater - { - // The closest the target can be to the text is just too far away. - // This target is leaving the party early. - return 0.0; - } + // copy current distance counts to 'previous row' distance counts: swap p and d + std::swap(p, d); + } - // copy current distance counts to 'previous row' distance counts: swap p and d - std::swap(p, d); - } + // Our last action in the above loop was to switch d and p, so p now actually has the most recent cost counts - // Our last action in the above loop was to switch d and p, so p now actually has the most recent cost counts + // This will return less than 0.0 when the edit distance is greater than the number of characters in the shorter + // word. But this was the formula that was previously used in FuzzyTermEnum, so it has not been changed (even + // though minimumSimilarity must be greater than 0.0) + return 1.0 - ((double)p[n] / (double)(prefix.length() + std::min(n, m))); +} - // This will return less than 0.0 when the edit distance is greater than the number of characters in the shorter - // word. But this was the formula that was previously used in FuzzyTermEnum, so it has not been changed (even - // though minimumSimilarity must be greater than 0.0) - return 1.0 - ((double)p[n] / (double)(prefix.length() + std::min(n, m))); - } +int32_t FuzzyTermEnum::calculateMaxDistance(int32_t m) { + return (int32_t)((1.0 - minimumSimilarity) * (double)(std::min((int32_t)text.length(), m) + prefix.length())); +} - int32_t FuzzyTermEnum::calculateMaxDistance(int32_t m) - { - return (int32_t)((1.0 - minimumSimilarity) * (double)(std::min((int32_t)text.length(), m) + prefix.length())); - } +void FuzzyTermEnum::close() { + p.reset(); + d.reset(); + searchTerm.reset(); + FilteredTermEnum::close(); // call FilteredTermEnum::close() and let the garbage collector do its work. +} - void FuzzyTermEnum::close() - { - p.reset(); - d.reset(); - searchTerm.reset(); - FilteredTermEnum::close(); // call FilteredTermEnum::close() and let the garbage collector do its work. - } } diff --git a/src/core/search/HitQueue.cpp b/src/core/search/HitQueue.cpp index 91ebb3da..d215b93a 100644 --- a/src/core/search/HitQueue.cpp +++ b/src/core/search/HitQueue.cpp @@ -8,29 +8,27 @@ #include "HitQueue.h" #include "ScoreDoc.h" -namespace Lucene -{ - HitQueue::HitQueue(int32_t size, bool prePopulate) : HitQueueBase(size) - { - this->prePopulate = prePopulate; - } +namespace Lucene { - HitQueue::~HitQueue() - { - } +HitQueue::HitQueue(int32_t size, bool prePopulate) : HitQueueBase(size) { + this->prePopulate = prePopulate; +} - bool HitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) - { - if (first->score == second->score) - return (first->doc > second->doc); - else - return (first->score < second->score); - } +HitQueue::~HitQueue() { +} - ScoreDocPtr HitQueue::getSentinelObject() - { - // Always set the doc Id to MAX_VALUE so that it won't be favored by lessThan. This generally should - // not happen since if score is not NEG_INF, TopScoreDocCollector will always add the object to the queue. - return !prePopulate ? ScoreDocPtr() : newLucene(INT_MAX, -std::numeric_limits::infinity()); +bool HitQueue::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { + if (first->score == second->score) { + return (first->doc > second->doc); + } else { + return (first->score < second->score); } } + +ScoreDocPtr HitQueue::getSentinelObject() { + // Always set the doc Id to MAX_VALUE so that it won't be favored by lessThan. This generally should + // not happen since if score is not NEG_INF, TopScoreDocCollector will always add the object to the queue. + return !prePopulate ? ScoreDocPtr() : newLucene(INT_MAX, -std::numeric_limits::infinity()); +} + +} diff --git a/src/core/search/HitQueueBase.cpp b/src/core/search/HitQueueBase.cpp index 351aa1f0..4d6c1161 100644 --- a/src/core/search/HitQueueBase.cpp +++ b/src/core/search/HitQueueBase.cpp @@ -8,83 +8,68 @@ #include "HitQueueBase.h" #include "ScoreDoc.h" -namespace Lucene -{ - HitQueueBase::HitQueueBase(int32_t size) - { - queueSize = size; - } - - HitQueueBase::~HitQueueBase() - { - } - - void HitQueueBase::initialize() - { - queue = newLucene(shared_from_this(), queueSize); - } - - ScoreDocPtr HitQueueBase::add(const ScoreDocPtr& scoreDoc) - { - return queue->add(scoreDoc); - } - - ScoreDocPtr HitQueueBase::addOverflow(const ScoreDocPtr& scoreDoc) - { - return queue->addOverflow(scoreDoc); - } - - ScoreDocPtr HitQueueBase::top() - { - return queue->top(); - } - - ScoreDocPtr HitQueueBase::pop() - { - return queue->pop(); - } - - ScoreDocPtr HitQueueBase::updateTop() - { - return queue->updateTop(); - } - - int32_t HitQueueBase::size() - { - return queue->size(); - } - - bool HitQueueBase::empty() - { - return queue->empty(); - } - - void HitQueueBase::clear() - { - queue->clear(); - } - - ScoreDocPtr HitQueueBase::getSentinelObject() - { - return ScoreDocPtr(); - } - - PriorityQueueScoreDocs::PriorityQueueScoreDocs(const HitQueueBasePtr& hitQueue, int32_t size) : PriorityQueue(size) - { - _hitQueue = hitQueue; - } - - PriorityQueueScoreDocs::~PriorityQueueScoreDocs() - { - } - - bool PriorityQueueScoreDocs::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) - { - return HitQueueBasePtr(_hitQueue)->lessThan(first, second); - } - - ScoreDocPtr PriorityQueueScoreDocs::getSentinelObject() - { - return HitQueueBasePtr(_hitQueue)->getSentinelObject(); - } +namespace Lucene { + +HitQueueBase::HitQueueBase(int32_t size) { + queueSize = size; +} + +HitQueueBase::~HitQueueBase() { +} + +void HitQueueBase::initialize() { + queue = newLucene(shared_from_this(), queueSize); +} + +ScoreDocPtr HitQueueBase::add(const ScoreDocPtr& scoreDoc) { + return queue->add(scoreDoc); +} + +ScoreDocPtr HitQueueBase::addOverflow(const ScoreDocPtr& scoreDoc) { + return queue->addOverflow(scoreDoc); +} + +ScoreDocPtr HitQueueBase::top() { + return queue->top(); +} + +ScoreDocPtr HitQueueBase::pop() { + return queue->pop(); +} + +ScoreDocPtr HitQueueBase::updateTop() { + return queue->updateTop(); +} + +int32_t HitQueueBase::size() { + return queue->size(); +} + +bool HitQueueBase::empty() { + return queue->empty(); +} + +void HitQueueBase::clear() { + queue->clear(); +} + +ScoreDocPtr HitQueueBase::getSentinelObject() { + return ScoreDocPtr(); +} + +PriorityQueueScoreDocs::PriorityQueueScoreDocs(const HitQueueBasePtr& hitQueue, int32_t size) : PriorityQueue(size) { + _hitQueue = hitQueue; +} + +PriorityQueueScoreDocs::~PriorityQueueScoreDocs() { +} + +bool PriorityQueueScoreDocs::lessThan(const ScoreDocPtr& first, const ScoreDocPtr& second) { + return HitQueueBasePtr(_hitQueue)->lessThan(first, second); +} + +ScoreDocPtr PriorityQueueScoreDocs::getSentinelObject() { + return HitQueueBasePtr(_hitQueue)->getSentinelObject(); +} + } diff --git a/src/core/search/IndexSearcher.cpp b/src/core/search/IndexSearcher.cpp index f2d32f18..293b258d 100644 --- a/src/core/search/IndexSearcher.cpp +++ b/src/core/search/IndexSearcher.cpp @@ -17,195 +17,172 @@ #include "Query.h" #include "ReaderUtil.h" -namespace Lucene -{ - IndexSearcher::IndexSearcher(const DirectoryPtr& path, bool readOnly) - { - ConstructSearcher(IndexReader::open(path, readOnly), true); - } +namespace Lucene { - IndexSearcher::IndexSearcher(const IndexReaderPtr& reader) - { - ConstructSearcher(reader, false); - } +IndexSearcher::IndexSearcher(const DirectoryPtr& path, bool readOnly) { + ConstructSearcher(IndexReader::open(path, readOnly), true); +} - IndexSearcher::IndexSearcher(const IndexReaderPtr& reader, Collection subReaders, Collection docStarts) - { - this->fieldSortDoTrackScores = false; - this->fieldSortDoMaxScore = false; - this->reader = reader; - this->subReaders = subReaders; - this->docStarts = docStarts; - closeReader = false; - } +IndexSearcher::IndexSearcher(const IndexReaderPtr& reader) { + ConstructSearcher(reader, false); +} - IndexSearcher::~IndexSearcher() - { - } +IndexSearcher::IndexSearcher(const IndexReaderPtr& reader, Collection subReaders, Collection docStarts) { + this->fieldSortDoTrackScores = false; + this->fieldSortDoMaxScore = false; + this->reader = reader; + this->subReaders = subReaders; + this->docStarts = docStarts; + closeReader = false; +} - void IndexSearcher::ConstructSearcher(const IndexReaderPtr& reader, bool closeReader) - { - this->fieldSortDoTrackScores = false; - this->fieldSortDoMaxScore = false; - this->reader = reader; - this->closeReader = closeReader; - - Collection subReadersList(Collection::newInstance()); - gatherSubReaders(subReadersList, reader); - subReaders = subReadersList; - docStarts = Collection::newInstance(subReaders.size()); - int32_t maxDoc = 0; - for (int32_t i = 0; i < subReaders.size(); ++i) - { - docStarts[i] = maxDoc; - maxDoc += subReaders[i]->maxDoc(); - } - } +IndexSearcher::~IndexSearcher() { +} - void IndexSearcher::gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader) - { - ReaderUtil::gatherSubReaders(allSubReaders, reader); +void IndexSearcher::ConstructSearcher(const IndexReaderPtr& reader, bool closeReader) { + this->fieldSortDoTrackScores = false; + this->fieldSortDoMaxScore = false; + this->reader = reader; + this->closeReader = closeReader; + + Collection subReadersList(Collection::newInstance()); + gatherSubReaders(subReadersList, reader); + subReaders = subReadersList; + docStarts = Collection::newInstance(subReaders.size()); + int32_t maxDoc = 0; + for (int32_t i = 0; i < subReaders.size(); ++i) { + docStarts[i] = maxDoc; + maxDoc += subReaders[i]->maxDoc(); } +} - IndexReaderPtr IndexSearcher::getIndexReader() - { - return reader; - } +void IndexSearcher::gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader) { + ReaderUtil::gatherSubReaders(allSubReaders, reader); +} - void IndexSearcher::close() - { - if (closeReader) - reader->close(); - } +IndexReaderPtr IndexSearcher::getIndexReader() { + return reader; +} - int32_t IndexSearcher::docFreq(const TermPtr& term) - { - return reader->docFreq(term); +void IndexSearcher::close() { + if (closeReader) { + reader->close(); } +} - DocumentPtr IndexSearcher::doc(int32_t n) - { - return reader->document(n); - } +int32_t IndexSearcher::docFreq(const TermPtr& term) { + return reader->docFreq(term); +} - DocumentPtr IndexSearcher::doc(int32_t n, const FieldSelectorPtr& fieldSelector) - { - return reader->document(n, fieldSelector); - } +DocumentPtr IndexSearcher::doc(int32_t n) { + return reader->document(n); +} - int32_t IndexSearcher::maxDoc() - { - return reader->maxDoc(); - } +DocumentPtr IndexSearcher::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { + return reader->document(n, fieldSelector); +} - TopDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) - { - if (n <= 0) - boost::throw_exception(IllegalArgumentException(L"n must be > 0")); - TopScoreDocCollectorPtr collector(TopScoreDocCollector::create(std::min(n, reader->maxDoc()), !weight->scoresDocsOutOfOrder())); - search(weight, filter, collector); - return collector->topDocs(); - } +int32_t IndexSearcher::maxDoc() { + return reader->maxDoc(); +} - TopFieldDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) - { - return search(weight, filter, n, sort, true); +TopDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { + if (n <= 0) { + boost::throw_exception(IllegalArgumentException(L"n must be > 0")); } + TopScoreDocCollectorPtr collector(TopScoreDocCollector::create(std::min(n, reader->maxDoc()), !weight->scoresDocsOutOfOrder())); + search(weight, filter, collector); + return collector->topDocs(); +} - TopFieldDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort, bool fillFields) - { - TopFieldCollectorPtr collector(TopFieldCollector::create(sort, std::min(n, reader->maxDoc()), fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight->scoresDocsOutOfOrder())); - search(weight, filter, collector); - return boost::dynamic_pointer_cast(collector->topDocs()); - } +TopFieldDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { + return search(weight, filter, n, sort, true); +} - void IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) - { - if (!filter) - { - for (int32_t i = 0; i < subReaders.size(); ++i) // search each subreader - { - results->setNextReader(subReaders[i], docStarts[i]); - ScorerPtr scorer(weight->scorer(subReaders[i], !results->acceptsDocsOutOfOrder(), true)); - if (scorer) - scorer->score(results); +TopFieldDocsPtr IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort, bool fillFields) { + TopFieldCollectorPtr collector(TopFieldCollector::create(sort, std::min(n, reader->maxDoc()), fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight->scoresDocsOutOfOrder())); + search(weight, filter, collector); + return boost::dynamic_pointer_cast(collector->topDocs()); +} + +void IndexSearcher::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) { + if (!filter) { + for (int32_t i = 0; i < subReaders.size(); ++i) { // search each subreader + results->setNextReader(subReaders[i], docStarts[i]); + ScorerPtr scorer(weight->scorer(subReaders[i], !results->acceptsDocsOutOfOrder(), true)); + if (scorer) { + scorer->score(results); } } - else - { - for (int32_t i = 0; i < subReaders.size(); ++i) // search each subreader - { - results->setNextReader(subReaders[i], docStarts[i]); - searchWithFilter(subReaders[i], weight, filter, results); - } + } else { + for (int32_t i = 0; i < subReaders.size(); ++i) { // search each subreader + results->setNextReader(subReaders[i], docStarts[i]); + searchWithFilter(subReaders[i], weight, filter, results); } } +} - void IndexSearcher::searchWithFilter(const IndexReaderPtr& reader, const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) - { - BOOST_ASSERT(filter); +void IndexSearcher::searchWithFilter(const IndexReaderPtr& reader, const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) { + BOOST_ASSERT(filter); - ScorerPtr scorer(weight->scorer(reader, true, false)); - if (!scorer) - return; + ScorerPtr scorer(weight->scorer(reader, true, false)); + if (!scorer) { + return; + } - int32_t docID = scorer->docID(); - BOOST_ASSERT(docID == -1 || docID == DocIdSetIterator::NO_MORE_DOCS); + int32_t docID = scorer->docID(); + BOOST_ASSERT(docID == -1 || docID == DocIdSetIterator::NO_MORE_DOCS); - DocIdSetPtr filterDocIdSet(filter->getDocIdSet(reader)); - if (!filterDocIdSet) - { - // this means the filter does not accept any documents. - return; - } + DocIdSetPtr filterDocIdSet(filter->getDocIdSet(reader)); + if (!filterDocIdSet) { + // this means the filter does not accept any documents. + return; + } - DocIdSetIteratorPtr filterIter(filterDocIdSet->iterator()); - if (!filterIter) - { - // this means the filter does not accept any documents. - return; - } + DocIdSetIteratorPtr filterIter(filterDocIdSet->iterator()); + if (!filterIter) { + // this means the filter does not accept any documents. + return; + } - int32_t filterDoc = filterIter->nextDoc(); - int32_t scorerDoc = scorer->advance(filterDoc); - - collector->setScorer(scorer); - while (true) - { - if (scorerDoc == filterDoc) - { - // Check if scorer has exhausted, only before collecting. - if (scorerDoc == DocIdSetIterator::NO_MORE_DOCS) - break; - collector->collect(scorerDoc); - filterDoc = filterIter->nextDoc(); - scorerDoc = scorer->advance(filterDoc); + int32_t filterDoc = filterIter->nextDoc(); + int32_t scorerDoc = scorer->advance(filterDoc); + + collector->setScorer(scorer); + while (true) { + if (scorerDoc == filterDoc) { + // Check if scorer has exhausted, only before collecting. + if (scorerDoc == DocIdSetIterator::NO_MORE_DOCS) { + break; } - else if (scorerDoc > filterDoc) - filterDoc = filterIter->advance(scorerDoc); - else - scorerDoc = scorer->advance(filterDoc); + collector->collect(scorerDoc); + filterDoc = filterIter->nextDoc(); + scorerDoc = scorer->advance(filterDoc); + } else if (scorerDoc > filterDoc) { + filterDoc = filterIter->advance(scorerDoc); + } else { + scorerDoc = scorer->advance(filterDoc); } } +} - QueryPtr IndexSearcher::rewrite(const QueryPtr& original) - { - QueryPtr query(original); - for (QueryPtr rewrittenQuery(query->rewrite(reader)); rewrittenQuery != query; rewrittenQuery = query->rewrite(reader)) - query = rewrittenQuery; - return query; +QueryPtr IndexSearcher::rewrite(const QueryPtr& original) { + QueryPtr query(original); + for (QueryPtr rewrittenQuery(query->rewrite(reader)); rewrittenQuery != query; rewrittenQuery = query->rewrite(reader)) { + query = rewrittenQuery; } + return query; +} - ExplanationPtr IndexSearcher::explain(const WeightPtr& weight, int32_t doc) - { - int32_t n = ReaderUtil::subIndex(doc, docStarts); - int32_t deBasedDoc = doc - docStarts[n]; - return weight->explain(subReaders[n], deBasedDoc); - } +ExplanationPtr IndexSearcher::explain(const WeightPtr& weight, int32_t doc) { + int32_t n = ReaderUtil::subIndex(doc, docStarts); + int32_t deBasedDoc = doc - docStarts[n]; + return weight->explain(subReaders[n], deBasedDoc); +} + +void IndexSearcher::setDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore) { + fieldSortDoTrackScores = doTrackScores; + fieldSortDoMaxScore = doMaxScore; +} - void IndexSearcher::setDefaultFieldSortScoring(bool doTrackScores, bool doMaxScore) - { - fieldSortDoTrackScores = doTrackScores; - fieldSortDoMaxScore = doMaxScore; - } } diff --git a/src/core/search/MatchAllDocsQuery.cpp b/src/core/search/MatchAllDocsQuery.cpp index 3233ad8f..8b0364ce 100644 --- a/src/core/search/MatchAllDocsQuery.cpp +++ b/src/core/search/MatchAllDocsQuery.cpp @@ -14,139 +14,118 @@ #include "Searcher.h" #include "MiscUtils.h" -namespace Lucene -{ - MatchAllDocsQuery::MatchAllDocsQuery(const String& normsField) - { - this->normsField = normsField; - } +namespace Lucene { - MatchAllDocsQuery::~MatchAllDocsQuery() - { - } +MatchAllDocsQuery::MatchAllDocsQuery(const String& normsField) { + this->normsField = normsField; +} - WeightPtr MatchAllDocsQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +MatchAllDocsQuery::~MatchAllDocsQuery() { +} - void MatchAllDocsQuery::extractTerms(SetTerm terms) - { - } +WeightPtr MatchAllDocsQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - String MatchAllDocsQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"*:*" << boostString(); - return buffer.str(); - } +void MatchAllDocsQuery::extractTerms(SetTerm terms) { +} - bool MatchAllDocsQuery::equals(const LuceneObjectPtr& other) - { - return Query::equals(other); - } +String MatchAllDocsQuery::toString(const String& field) { + StringStream buffer; + buffer << L"*:*" << boostString(); + return buffer.str(); +} - int32_t MatchAllDocsQuery::hashCode() - { - return MiscUtils::doubleToIntBits(getBoost()) ^ 0x1aa71190; - } +bool MatchAllDocsQuery::equals(const LuceneObjectPtr& other) { + return Query::equals(other); +} - LuceneObjectPtr MatchAllDocsQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - MatchAllDocsQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); - cloneQuery->normsField = normsField; - return cloneQuery; - } +int32_t MatchAllDocsQuery::hashCode() { + return MiscUtils::doubleToIntBits(getBoost()) ^ 0x1aa71190; +} - MatchAllDocsWeight::MatchAllDocsWeight(const MatchAllDocsQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = searcher->getSimilarity(); - this->queryWeight = 0.0; - this->queryNorm = 0.0; - } +LuceneObjectPtr MatchAllDocsQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + MatchAllDocsQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); + cloneQuery->normsField = normsField; + return cloneQuery; +} - MatchAllDocsWeight::~MatchAllDocsWeight() - { - } +MatchAllDocsWeight::MatchAllDocsWeight(const MatchAllDocsQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = searcher->getSimilarity(); + this->queryWeight = 0.0; + this->queryNorm = 0.0; +} - String MatchAllDocsWeight::toString() - { - StringStream buffer; - buffer << L"weight(" << queryWeight << L", " << queryNorm << L")"; - return buffer.str(); - } +MatchAllDocsWeight::~MatchAllDocsWeight() { +} - QueryPtr MatchAllDocsWeight::getQuery() - { - return query; - } +String MatchAllDocsWeight::toString() { + StringStream buffer; + buffer << L"weight(" << queryWeight << L", " << queryNorm << L")"; + return buffer.str(); +} - double MatchAllDocsWeight::getValue() - { - return queryWeight; - } +QueryPtr MatchAllDocsWeight::getQuery() { + return query; +} - double MatchAllDocsWeight::sumOfSquaredWeights() - { - queryWeight = getQuery()->getBoost(); - return queryWeight * queryWeight; - } +double MatchAllDocsWeight::getValue() { + return queryWeight; +} - void MatchAllDocsWeight::normalize(double norm) - { - this->queryNorm = norm; - queryWeight *= this->queryNorm; - } +double MatchAllDocsWeight::sumOfSquaredWeights() { + queryWeight = getQuery()->getBoost(); + return queryWeight * queryWeight; +} - ScorerPtr MatchAllDocsWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - return newLucene(query, reader, similarity, shared_from_this(), !query->normsField.empty() ? reader->norms(query->normsField) : ByteArray()); - } +void MatchAllDocsWeight::normalize(double norm) { + this->queryNorm = norm; + queryWeight *= this->queryNorm; +} - ExplanationPtr MatchAllDocsWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - // explain query weight - ExplanationPtr queryExpl(newLucene(true, getValue(), L"MatchAllDocsQuery, product of:")); - if (getQuery()->getBoost() != 1.0) - queryExpl->addDetail(newLucene(getQuery()->getBoost(), L"boost")); - queryExpl->addDetail(newLucene(queryNorm, L"queryNorm")); - return queryExpl; - } +ScorerPtr MatchAllDocsWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + return newLucene(query, reader, similarity, shared_from_this(), !query->normsField.empty() ? reader->norms(query->normsField) : ByteArray()); +} - MatchAllScorer::MatchAllScorer(const MatchAllDocsQueryPtr& query, const IndexReaderPtr& reader, const SimilarityPtr& similarity, const WeightPtr& weight, ByteArray norms) : Scorer(similarity) - { - this->query = query; - this->termDocs = reader->termDocs(TermPtr()); - this->_score = weight->getValue(); - this->norms = norms; - this->doc = -1; +ExplanationPtr MatchAllDocsWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + // explain query weight + ExplanationPtr queryExpl(newLucene(true, getValue(), L"MatchAllDocsQuery, product of:")); + if (getQuery()->getBoost() != 1.0) { + queryExpl->addDetail(newLucene(getQuery()->getBoost(), L"boost")); } + queryExpl->addDetail(newLucene(queryNorm, L"queryNorm")); + return queryExpl; +} - MatchAllScorer::~MatchAllScorer() - { - } +MatchAllScorer::MatchAllScorer(const MatchAllDocsQueryPtr& query, const IndexReaderPtr& reader, const SimilarityPtr& similarity, const WeightPtr& weight, ByteArray norms) : Scorer(similarity) { + this->query = query; + this->termDocs = reader->termDocs(TermPtr()); + this->_score = weight->getValue(); + this->norms = norms; + this->doc = -1; +} - int32_t MatchAllScorer::docID() - { - return doc; - } +MatchAllScorer::~MatchAllScorer() { +} - int32_t MatchAllScorer::nextDoc() - { - doc = termDocs->next() ? termDocs->doc() : NO_MORE_DOCS; - return doc; - } +int32_t MatchAllScorer::docID() { + return doc; +} - double MatchAllScorer::score() - { - return norms ? _score * Similarity::decodeNorm(norms[docID()]) : _score; - } +int32_t MatchAllScorer::nextDoc() { + doc = termDocs->next() ? termDocs->doc() : NO_MORE_DOCS; + return doc; +} + +double MatchAllScorer::score() { + return norms ? _score * Similarity::decodeNorm(norms[docID()]) : _score; +} + +int32_t MatchAllScorer::advance(int32_t target) { + doc = termDocs->skipTo(target) ? termDocs->doc() : NO_MORE_DOCS; + return doc; +} - int32_t MatchAllScorer::advance(int32_t target) - { - doc = termDocs->skipTo(target) ? termDocs->doc() : NO_MORE_DOCS; - return doc; - } } diff --git a/src/core/search/MultiPhraseQuery.cpp b/src/core/search/MultiPhraseQuery.cpp index 04c938ff..e8968241 100644 --- a/src/core/search/MultiPhraseQuery.cpp +++ b/src/core/search/MultiPhraseQuery.cpp @@ -20,313 +20,299 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - MultiPhraseQuery::MultiPhraseQuery() - { - termArrays = Collection< Collection >::newInstance(); - positions = Collection::newInstance(); - slop = 0; - } +namespace Lucene { - MultiPhraseQuery::~MultiPhraseQuery() - { - } +MultiPhraseQuery::MultiPhraseQuery() { + termArrays = Collection< Collection >::newInstance(); + positions = Collection::newInstance(); + slop = 0; +} - void MultiPhraseQuery::setSlop(int32_t s) - { - slop = s; - } +MultiPhraseQuery::~MultiPhraseQuery() { +} - int32_t MultiPhraseQuery::getSlop() - { - return slop; - } +void MultiPhraseQuery::setSlop(int32_t s) { + slop = s; +} - void MultiPhraseQuery::add(const TermPtr& term) - { - add(newCollection(term)); - } +int32_t MultiPhraseQuery::getSlop() { + return slop; +} + +void MultiPhraseQuery::add(const TermPtr& term) { + add(newCollection(term)); +} - void MultiPhraseQuery::add(Collection terms) - { - int32_t position = 0; - if (!positions.empty()) - position = positions[positions.size() - 1] + 1; - add(terms, position); +void MultiPhraseQuery::add(Collection terms) { + int32_t position = 0; + if (!positions.empty()) { + position = positions[positions.size() - 1] + 1; } + add(terms, position); +} - void MultiPhraseQuery::add(Collection terms, int32_t position) - { - if (termArrays.empty()) - field = terms[0]->field(); - for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) - { - if ((*term)->field() != field) - boost::throw_exception(IllegalArgumentException(L"All phrase terms must be in the same field (" + field + L"): " + (*term)->toString())); +void MultiPhraseQuery::add(Collection terms, int32_t position) { + if (termArrays.empty()) { + field = terms[0]->field(); + } + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) { + if ((*term)->field() != field) { + boost::throw_exception(IllegalArgumentException(L"All phrase terms must be in the same field (" + field + L"): " + (*term)->toString())); } - termArrays.add(terms); - positions.add(position); } + termArrays.add(terms); + positions.add(position); +} - Collection< Collection > MultiPhraseQuery::getTermArrays() - { - return termArrays; - } +Collection< Collection > MultiPhraseQuery::getTermArrays() { + return termArrays; +} - Collection MultiPhraseQuery::getPositions() - { - return positions; - } +Collection MultiPhraseQuery::getPositions() { + return positions; +} - void MultiPhraseQuery::extractTerms(SetTerm terms) - { - for (Collection< Collection >::iterator arr = termArrays.begin(); arr != termArrays.end(); ++arr) - { - for (Collection::iterator term = arr->begin(); term != arr->end(); ++term) - terms.add(*term); +void MultiPhraseQuery::extractTerms(SetTerm terms) { + for (Collection< Collection >::iterator arr = termArrays.begin(); arr != termArrays.end(); ++arr) { + for (Collection::iterator term = arr->begin(); term != arr->end(); ++term) { + terms.add(*term); } } +} - QueryPtr MultiPhraseQuery::rewrite(const IndexReaderPtr& reader) - { - if (termArrays.size() == 1) // optimize one-term case - { - Collection terms(termArrays[0]); - BooleanQueryPtr boq(newLucene(true)); - for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) - boq->add(newLucene(*term), BooleanClause::SHOULD); - boq->setBoost(getBoost()); - return boq; +QueryPtr MultiPhraseQuery::rewrite(const IndexReaderPtr& reader) { + if (termArrays.size() == 1) { // optimize one-term case + Collection terms(termArrays[0]); + BooleanQueryPtr boq(newLucene(true)); + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) { + boq->add(newLucene(*term), BooleanClause::SHOULD); } - else - return shared_from_this(); + boq->setBoost(getBoost()); + return boq; + } else { + return shared_from_this(); } +} - WeightPtr MultiPhraseQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +WeightPtr MultiPhraseQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - String MultiPhraseQuery::toString(const String& field) - { - StringStream buffer; - if (this->field != field) - buffer << this->field << L":"; - buffer << L"\""; - for (Collection< Collection >::iterator arr = termArrays.begin(); arr != termArrays.end(); ++arr) - { - if (arr != termArrays.begin()) - buffer << L" "; - if (arr->size() > 1) - { - buffer << L"("; - for (Collection::iterator term = arr->begin(); term != arr->end(); ++term) - { - if (term != arr->begin()) - buffer << L" "; - buffer << (*term)->text(); +String MultiPhraseQuery::toString(const String& field) { + StringStream buffer; + if (this->field != field) { + buffer << this->field << L":"; + } + buffer << L"\""; + for (Collection< Collection >::iterator arr = termArrays.begin(); arr != termArrays.end(); ++arr) { + if (arr != termArrays.begin()) { + buffer << L" "; + } + if (arr->size() > 1) { + buffer << L"("; + for (Collection::iterator term = arr->begin(); term != arr->end(); ++term) { + if (term != arr->begin()) { + buffer << L" "; } - buffer << L")"; + buffer << (*term)->text(); } - else if (!arr->empty()) - buffer << (*arr)[0]->text(); + buffer << L")"; + } else if (!arr->empty()) { + buffer << (*arr)[0]->text(); } - buffer << L"\""; - - if (slop != 0) - buffer << L"~" << slop; - - buffer << boostString(); - - return buffer.str(); } + buffer << L"\""; - bool MultiPhraseQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; + if (slop != 0) { + buffer << L"~" << slop; + } - MultiPhraseQueryPtr otherMultiPhraseQuery(boost::dynamic_pointer_cast(other)); - if (!otherMultiPhraseQuery) - return false; + buffer << boostString(); - return (getBoost() == otherMultiPhraseQuery->getBoost() && slop == otherMultiPhraseQuery->slop && - termArraysEquals(termArrays, otherMultiPhraseQuery->termArrays) && - positions.equals(otherMultiPhraseQuery->positions)); - } + return buffer.str(); +} - int32_t MultiPhraseQuery::hashCode() - { - return MiscUtils::doubleToIntBits(getBoost()) ^ slop ^ termArraysHashCode() ^ MiscUtils::hashCode(positions.begin(), positions.end(), MiscUtils::hashNumeric) ^ 0x4ac65113; +bool MultiPhraseQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - int32_t MultiPhraseQuery::termArraysHashCode() - { - int32_t hashCode = 1; - for (Collection< Collection >::iterator arr = termArrays.begin(); arr != termArrays.end(); ++arr) - hashCode = 31 * hashCode + MiscUtils::hashCode(arr->begin(), arr->end(), MiscUtils::hashLucene); - return hashCode; + MultiPhraseQueryPtr otherMultiPhraseQuery(boost::dynamic_pointer_cast(other)); + if (!otherMultiPhraseQuery) { + return false; } - struct equalTermArrays - { - inline bool operator()(const Collection& first, const Collection& second) const - { - if (first.size() != second.size()) - return false; - return first.equals(second, luceneEquals()); - } - }; + return (getBoost() == otherMultiPhraseQuery->getBoost() && slop == otherMultiPhraseQuery->slop && + termArraysEquals(termArrays, otherMultiPhraseQuery->termArrays) && + positions.equals(otherMultiPhraseQuery->positions)); +} - bool MultiPhraseQuery::termArraysEquals(Collection< Collection > first, Collection< Collection > second) - { - return first.equals(second, equalTermArrays()); - } +int32_t MultiPhraseQuery::hashCode() { + return MiscUtils::doubleToIntBits(getBoost()) ^ slop ^ termArraysHashCode() ^ MiscUtils::hashCode(positions.begin(), positions.end(), MiscUtils::hashNumeric) ^ 0x4ac65113; +} - LuceneObjectPtr MultiPhraseQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - MultiPhraseQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); - cloneQuery->field = field; - cloneQuery->termArrays = termArrays; - cloneQuery->positions = positions; - cloneQuery->slop = slop; - return cloneQuery; +int32_t MultiPhraseQuery::termArraysHashCode() { + int32_t hashCode = 1; + for (Collection< Collection >::iterator arr = termArrays.begin(); arr != termArrays.end(); ++arr) { + hashCode = 31 * hashCode + MiscUtils::hashCode(arr->begin(), arr->end(), MiscUtils::hashLucene); } + return hashCode; +} - MultiPhraseWeight::MultiPhraseWeight(const MultiPhraseQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = query->getSimilarity(searcher); - this->value = 0.0; - this->idf = 0.0; - this->queryNorm = 0.0; - this->queryWeight = 0.0; - - // compute idf - int32_t maxDoc = searcher->maxDoc(); - for (Collection< Collection >::iterator arr = query->termArrays.begin(); arr != query->termArrays.end(); ++arr) - { - for (Collection::iterator term = arr->begin(); term != arr->end(); ++term) - idf += this->similarity->idf(searcher->docFreq(*term), maxDoc); +struct equalTermArrays { + inline bool operator()(const Collection& first, const Collection& second) const { + if (first.size() != second.size()) { + return false; } + return first.equals(second, luceneEquals()); } +}; - MultiPhraseWeight::~MultiPhraseWeight() - { - } +bool MultiPhraseQuery::termArraysEquals(Collection< Collection > first, Collection< Collection > second) { + return first.equals(second, equalTermArrays()); +} - QueryPtr MultiPhraseWeight::getQuery() - { - return query; - } +LuceneObjectPtr MultiPhraseQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + MultiPhraseQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); + cloneQuery->field = field; + cloneQuery->termArrays = termArrays; + cloneQuery->positions = positions; + cloneQuery->slop = slop; + return cloneQuery; +} - double MultiPhraseWeight::getValue() - { - return value; +MultiPhraseWeight::MultiPhraseWeight(const MultiPhraseQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = query->getSimilarity(searcher); + this->value = 0.0; + this->idf = 0.0; + this->queryNorm = 0.0; + this->queryWeight = 0.0; + + // compute idf + int32_t maxDoc = searcher->maxDoc(); + for (Collection< Collection >::iterator arr = query->termArrays.begin(); arr != query->termArrays.end(); ++arr) { + for (Collection::iterator term = arr->begin(); term != arr->end(); ++term) { + idf += this->similarity->idf(searcher->docFreq(*term), maxDoc); + } } +} - double MultiPhraseWeight::sumOfSquaredWeights() - { - queryWeight = idf * getQuery()->getBoost(); // compute query weight - return queryWeight * queryWeight; // square it - } +MultiPhraseWeight::~MultiPhraseWeight() { +} - void MultiPhraseWeight::normalize(double norm) - { - queryNorm = norm; - queryWeight *= queryNorm; // normalize query weight - value = queryWeight * idf; // idf for document - } +QueryPtr MultiPhraseWeight::getQuery() { + return query; +} - ScorerPtr MultiPhraseWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - if (query->termArrays.empty()) // optimize zero-term case - return ScorerPtr(); +double MultiPhraseWeight::getValue() { + return value; +} + +double MultiPhraseWeight::sumOfSquaredWeights() { + queryWeight = idf * getQuery()->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it +} + +void MultiPhraseWeight::normalize(double norm) { + queryNorm = norm; + queryWeight *= queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document +} - Collection tps(Collection::newInstance(query->termArrays.size())); - for (int32_t i = 0; i < tps.size(); ++i) - { - Collection terms(query->termArrays[i]); +ScorerPtr MultiPhraseWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + if (query->termArrays.empty()) { // optimize zero-term case + return ScorerPtr(); + } - TermPositionsPtr p; - if (terms.size() > 1) - p = newLucene(reader, terms); - else - p = reader->termPositions(terms[0]); + Collection tps(Collection::newInstance(query->termArrays.size())); + for (int32_t i = 0; i < tps.size(); ++i) { + Collection terms(query->termArrays[i]); - if (!p) - return ScorerPtr(); + TermPositionsPtr p; + if (terms.size() > 1) { + p = newLucene(reader, terms); + } else { + p = reader->termPositions(terms[0]); + } - tps[i] = p; + if (!p) { + return ScorerPtr(); } - if (query->slop == 0) // optimize exact case - return newLucene(shared_from_this(), tps, query->getPositions(), similarity, reader->norms(query->field)); - else - return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); + tps[i] = p; } - ExplanationPtr MultiPhraseWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - ComplexExplanationPtr result(newLucene()); - result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); + if (query->slop == 0) { // optimize exact case + return newLucene(shared_from_this(), tps, query->getPositions(), similarity, reader->norms(query->field)); + } else { + return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); + } +} - ExplanationPtr idfExpl(newLucene(idf, L"idf(" + query->toString() + L")")); +ExplanationPtr MultiPhraseWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + ComplexExplanationPtr result(newLucene()); + result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - // explain query weight - ExplanationPtr queryExpl(newLucene()); - queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); + ExplanationPtr idfExpl(newLucene(idf, L"idf(" + query->toString() + L")")); - ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); - if (query->getBoost() != 1.0) - queryExpl->addDetail(boostExpl); + // explain query weight + ExplanationPtr queryExpl(newLucene()); + queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - queryExpl->addDetail(idfExpl); + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); + if (query->getBoost() != 1.0) { + queryExpl->addDetail(boostExpl); + } - ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); - queryExpl->addDetail(queryNormExpl); + queryExpl->addDetail(idfExpl); - queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); - result->addDetail(queryExpl); + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); + queryExpl->addDetail(queryNormExpl); - // explain field weight - ComplexExplanationPtr fieldExpl(newLucene()); - fieldExpl->setDescription(L"fieldWeight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); + queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); + result->addDetail(queryExpl); - PhraseScorerPtr phraseScorer(boost::dynamic_pointer_cast(scorer(reader, true, false))); - if (!phraseScorer) - return newLucene(0.0, L"no matching docs"); + // explain field weight + ComplexExplanationPtr fieldExpl(newLucene()); + fieldExpl->setDescription(L"fieldWeight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - ExplanationPtr tfExplanation(newLucene()); - int32_t d = phraseScorer->advance(doc); - double phraseFreq = d == doc ? phraseScorer->currentFreq() : 0.0; - tfExplanation->setValue(similarity->tf(phraseFreq)); - tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); + PhraseScorerPtr phraseScorer(boost::dynamic_pointer_cast(scorer(reader, true, false))); + if (!phraseScorer) { + return newLucene(0.0, L"no matching docs"); + } - fieldExpl->addDetail(tfExplanation); - fieldExpl->addDetail(idfExpl); + ExplanationPtr tfExplanation(newLucene()); + int32_t d = phraseScorer->advance(doc); + double phraseFreq = d == doc ? phraseScorer->currentFreq() : 0.0; + tfExplanation->setValue(similarity->tf(phraseFreq)); + tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); - ExplanationPtr fieldNormExpl(newLucene()); - ByteArray fieldNorms(reader->norms(query->field)); - double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; - fieldNormExpl->setValue(fieldNorm); - fieldNormExpl->setDescription(L"fieldNorm(field=" + query->field + L", doc=" + StringUtils::toString(doc) + L")"); - fieldExpl->addDetail(fieldNormExpl); + fieldExpl->addDetail(tfExplanation); + fieldExpl->addDetail(idfExpl); - fieldExpl->setMatch(tfExplanation->isMatch()); - fieldExpl->setValue(tfExplanation->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); + ExplanationPtr fieldNormExpl(newLucene()); + ByteArray fieldNorms(reader->norms(query->field)); + double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; + fieldNormExpl->setValue(fieldNorm); + fieldNormExpl->setDescription(L"fieldNorm(field=" + query->field + L", doc=" + StringUtils::toString(doc) + L")"); + fieldExpl->addDetail(fieldNormExpl); - result->addDetail(fieldExpl); - result->setMatch(fieldExpl->getMatch()); + fieldExpl->setMatch(tfExplanation->isMatch()); + fieldExpl->setValue(tfExplanation->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); - // combine them - result->setValue(queryExpl->getValue() * fieldExpl->getValue()); + result->addDetail(fieldExpl); + result->setMatch(fieldExpl->getMatch()); - if (queryExpl->getValue() == 1.0) - return fieldExpl; + // combine them + result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - return result; + if (queryExpl->getValue() == 1.0) { + return fieldExpl; } + + return result; +} + } diff --git a/src/core/search/MultiSearcher.cpp b/src/core/search/MultiSearcher.cpp index 4825c51a..d3276902 100644 --- a/src/core/search/MultiSearcher.cpp +++ b/src/core/search/MultiSearcher.cpp @@ -20,369 +20,329 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - MultiSearcher::MultiSearcher(Collection searchables) - { - this->searchables = searchables; - this->_maxDoc = 0; - - this->starts = Collection::newInstance(searchables.size() + 1); // build starts array - for (int32_t i = 0; i < searchables.size(); ++i) - { - starts[i] = _maxDoc; - _maxDoc += searchables[i]->maxDoc(); // compute maxDocs - } - starts[searchables.size()] = _maxDoc; - } +namespace Lucene { - MultiSearcher::~MultiSearcher() - { - } +MultiSearcher::MultiSearcher(Collection searchables) { + this->searchables = searchables; + this->_maxDoc = 0; - Collection MultiSearcher::getSearchables() - { - return searchables; + this->starts = Collection::newInstance(searchables.size() + 1); // build starts array + for (int32_t i = 0; i < searchables.size(); ++i) { + starts[i] = _maxDoc; + _maxDoc += searchables[i]->maxDoc(); // compute maxDocs } + starts[searchables.size()] = _maxDoc; +} - Collection MultiSearcher::getStarts() - { - return starts; - } +MultiSearcher::~MultiSearcher() { +} - void MultiSearcher::close() - { - for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) - (*searchable)->close(); - } +Collection MultiSearcher::getSearchables() { + return searchables; +} - int32_t MultiSearcher::docFreq(const TermPtr& term) - { - int32_t docFreq = 0; - for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) - docFreq += (*searchable)->docFreq(term); - return docFreq; - } +Collection MultiSearcher::getStarts() { + return starts; +} - DocumentPtr MultiSearcher::doc(int32_t n) - { - int32_t i = subSearcher(n); // find searcher index - return searchables[i]->doc(n - starts[i]); // dispatch to searcher +void MultiSearcher::close() { + for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) { + (*searchable)->close(); } +} - DocumentPtr MultiSearcher::doc(int32_t n, const FieldSelectorPtr& fieldSelector) - { - int32_t i = subSearcher(n); // find searcher index - return searchables[i]->doc(n - starts[i], fieldSelector); // dispatch to searcher +int32_t MultiSearcher::docFreq(const TermPtr& term) { + int32_t docFreq = 0; + for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) { + docFreq += (*searchable)->docFreq(term); } + return docFreq; +} - int32_t MultiSearcher::subSearcher(int32_t n) - { - return ReaderUtil::subIndex(n, starts); - } +DocumentPtr MultiSearcher::doc(int32_t n) { + int32_t i = subSearcher(n); // find searcher index + return searchables[i]->doc(n - starts[i]); // dispatch to searcher +} - int32_t MultiSearcher::subDoc(int32_t n) - { - return n - starts[subSearcher(n)]; - } +DocumentPtr MultiSearcher::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { + int32_t i = subSearcher(n); // find searcher index + return searchables[i]->doc(n - starts[i], fieldSelector); // dispatch to searcher +} - int32_t MultiSearcher::maxDoc() - { - return _maxDoc; - } +int32_t MultiSearcher::subSearcher(int32_t n) { + return ReaderUtil::subIndex(n, starts); +} - TopDocsPtr MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) - { - HitQueuePtr hq(newLucene(n, false)); - int32_t totalHits = 0; +int32_t MultiSearcher::subDoc(int32_t n) { + return n - starts[subSearcher(n)]; +} - for (int32_t i = 0; i < searchables.size(); ++i) // search each searcher - { - TopDocsPtr docs(newLucene(SynchronizePtr(), searchables[i], weight, filter, n, hq, i, starts)->call()); - totalHits += docs->totalHits; // update totalHits - } +int32_t MultiSearcher::maxDoc() { + return _maxDoc; +} - Collection scoreDocs(Collection::newInstance(hq->size())); - for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array - scoreDocs[i] = hq->pop(); +TopDocsPtr MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { + HitQueuePtr hq(newLucene(n, false)); + int32_t totalHits = 0; - double maxScore = totalHits == 0 ? -std::numeric_limits::infinity() : scoreDocs[0]->score; + for (int32_t i = 0; i < searchables.size(); ++i) { // search each searcher + TopDocsPtr docs(newLucene(SynchronizePtr(), searchables[i], weight, filter, n, hq, i, starts)->call()); + totalHits += docs->totalHits; // update totalHits + } - return newLucene(totalHits, scoreDocs, maxScore); + Collection scoreDocs(Collection::newInstance(hq->size())); + for (int32_t i = hq->size() - 1; i >= 0; --i) { // put docs in array + scoreDocs[i] = hq->pop(); } - TopFieldDocsPtr MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) - { - FieldDocSortedHitQueuePtr hq(newLucene(n)); - int32_t totalHits = 0; + double maxScore = totalHits == 0 ? -std::numeric_limits::infinity() : scoreDocs[0]->score; - double maxScore = -std::numeric_limits::infinity(); + return newLucene(totalHits, scoreDocs, maxScore); +} - for (int32_t i = 0; i < searchables.size(); ++i) // search each searcher - { - TopFieldDocsPtr docs(newLucene(SynchronizePtr(), searchables[i], weight, filter, n, hq, sort, i, starts)->call()); - totalHits += docs->totalHits; // update totalHits - maxScore = std::max(maxScore, docs->maxScore); - } +TopFieldDocsPtr MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { + FieldDocSortedHitQueuePtr hq(newLucene(n)); + int32_t totalHits = 0; - Collection scoreDocs(Collection::newInstance(hq->size())); - for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array - scoreDocs[i] = hq->pop(); + double maxScore = -std::numeric_limits::infinity(); - return newLucene(totalHits, scoreDocs, hq->getFields(), maxScore); + for (int32_t i = 0; i < searchables.size(); ++i) { // search each searcher + TopFieldDocsPtr docs(newLucene(SynchronizePtr(), searchables[i], weight, filter, n, hq, sort, i, starts)->call()); + totalHits += docs->totalHits; // update totalHits + maxScore = std::max(maxScore, docs->maxScore); } - void MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) - { - for (int32_t i = 0; i < searchables.size(); ++i) - { - int32_t start = starts[i]; - CollectorPtr hc = newLucene(results, start); - searchables[i]->search(weight, filter, hc); - } + Collection scoreDocs(Collection::newInstance(hq->size())); + for (int32_t i = hq->size() - 1; i >= 0; --i) { // put docs in array + scoreDocs[i] = hq->pop(); } - QueryPtr MultiSearcher::rewrite(const QueryPtr& query) - { - Collection queries(Collection::newInstance(searchables.size())); - for (int32_t i = 0; i < searchables.size(); ++i) - queries[i] = searchables[i]->rewrite(query); - return queries[0]->combine(queries); + return newLucene(totalHits, scoreDocs, hq->getFields(), maxScore); +} + +void MultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) { + for (int32_t i = 0; i < searchables.size(); ++i) { + int32_t start = starts[i]; + CollectorPtr hc = newLucene(results, start); + searchables[i]->search(weight, filter, hc); } +} - ExplanationPtr MultiSearcher::explain(const WeightPtr& weight, int32_t doc) - { - int32_t i = subSearcher(doc); // find searcher index - return searchables[i]->explain(weight, doc - starts[i]); // dispatch to searcher +QueryPtr MultiSearcher::rewrite(const QueryPtr& query) { + Collection queries(Collection::newInstance(searchables.size())); + for (int32_t i = 0; i < searchables.size(); ++i) { + queries[i] = searchables[i]->rewrite(query); } + return queries[0]->combine(queries); +} - WeightPtr MultiSearcher::createWeight(const QueryPtr& query) - { - // step 1 - QueryPtr rewrittenQuery(rewrite(query)); - - // step 2 - SetTerm terms(SetTerm::newInstance()); - rewrittenQuery->extractTerms(terms); - - // step3 - Collection allTermsArray(Collection::newInstance(terms.begin(), terms.end())); - Collection aggregatedDfs(Collection::newInstance(terms.size())); - for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) - { - Collection dfs((*searchable)->docFreqs(allTermsArray)); - for (int32_t j = 0; j < aggregatedDfs.size(); ++j) - aggregatedDfs[j] += dfs[j]; +ExplanationPtr MultiSearcher::explain(const WeightPtr& weight, int32_t doc) { + int32_t i = subSearcher(doc); // find searcher index + return searchables[i]->explain(weight, doc - starts[i]); // dispatch to searcher +} + +WeightPtr MultiSearcher::createWeight(const QueryPtr& query) { + // step 1 + QueryPtr rewrittenQuery(rewrite(query)); + + // step 2 + SetTerm terms(SetTerm::newInstance()); + rewrittenQuery->extractTerms(terms); + + // step3 + Collection allTermsArray(Collection::newInstance(terms.begin(), terms.end())); + Collection aggregatedDfs(Collection::newInstance(terms.size())); + for (Collection::iterator searchable = searchables.begin(); searchable != searchables.end(); ++searchable) { + Collection dfs((*searchable)->docFreqs(allTermsArray)); + for (int32_t j = 0; j < aggregatedDfs.size(); ++j) { + aggregatedDfs[j] += dfs[j]; } + } - MapTermInt dfMap(MapTermInt::newInstance()); - for (int32_t i = 0; i < allTermsArray.size(); ++i) - dfMap.put(allTermsArray[i], aggregatedDfs[i]); + MapTermInt dfMap(MapTermInt::newInstance()); + for (int32_t i = 0; i < allTermsArray.size(); ++i) { + dfMap.put(allTermsArray[i], aggregatedDfs[i]); + } - // step4 - int32_t numDocs = maxDoc(); - CachedDfSourcePtr cacheSim(newLucene(dfMap, numDocs, getSimilarity())); + // step4 + int32_t numDocs = maxDoc(); + CachedDfSourcePtr cacheSim(newLucene(dfMap, numDocs, getSimilarity())); - return rewrittenQuery->weight(cacheSim); - } + return rewrittenQuery->weight(cacheSim); +} - CachedDfSource::CachedDfSource(MapTermInt dfMap, int32_t maxDoc, const SimilarityPtr& similarity) - { - this->dfMap = dfMap; - this->_maxDoc = maxDoc; - setSimilarity(similarity); - } +CachedDfSource::CachedDfSource(MapTermInt dfMap, int32_t maxDoc, const SimilarityPtr& similarity) { + this->dfMap = dfMap; + this->_maxDoc = maxDoc; + setSimilarity(similarity); +} - CachedDfSource::~CachedDfSource() - { - } +CachedDfSource::~CachedDfSource() { +} - int32_t CachedDfSource::docFreq(const TermPtr& term) - { - MapTermInt::iterator df = dfMap.find(term); - if (df == dfMap.end()) - boost::throw_exception(IllegalArgumentException(L"df for term " + term->text() + L" not available")); - return df->second; +int32_t CachedDfSource::docFreq(const TermPtr& term) { + MapTermInt::iterator df = dfMap.find(term); + if (df == dfMap.end()) { + boost::throw_exception(IllegalArgumentException(L"df for term " + term->text() + L" not available")); } + return df->second; +} - Collection CachedDfSource::docFreqs(Collection terms) - { - Collection result(Collection::newInstance(terms.size())); - for (int32_t i = 0; i < terms.size(); ++i) - result[i] = docFreq(terms[i]); - return result; +Collection CachedDfSource::docFreqs(Collection terms) { + Collection result(Collection::newInstance(terms.size())); + for (int32_t i = 0; i < terms.size(); ++i) { + result[i] = docFreq(terms[i]); } + return result; +} - int32_t CachedDfSource::maxDoc() - { - return _maxDoc; - } +int32_t CachedDfSource::maxDoc() { + return _maxDoc; +} - QueryPtr CachedDfSource::rewrite(const QueryPtr& query) - { - // This is a bit of a hack. We know that a query which creates a Weight based on this Dummy-Searcher is - // always already rewritten (see preparedWeight()). Therefore we just return the unmodified query here. - return query; - } +QueryPtr CachedDfSource::rewrite(const QueryPtr& query) { + // This is a bit of a hack. We know that a query which creates a Weight based on this Dummy-Searcher is + // always already rewritten (see preparedWeight()). Therefore we just return the unmodified query here. + return query; +} - void CachedDfSource::close() - { - boost::throw_exception(UnsupportedOperationException()); - } +void CachedDfSource::close() { + boost::throw_exception(UnsupportedOperationException()); +} - DocumentPtr CachedDfSource::doc(int32_t n) - { - boost::throw_exception(UnsupportedOperationException()); - return DocumentPtr(); - } +DocumentPtr CachedDfSource::doc(int32_t n) { + boost::throw_exception(UnsupportedOperationException()); + return DocumentPtr(); +} - DocumentPtr CachedDfSource::doc(int32_t n, const FieldSelectorPtr& fieldSelector) - { - boost::throw_exception(UnsupportedOperationException()); - return DocumentPtr(); - } +DocumentPtr CachedDfSource::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { + boost::throw_exception(UnsupportedOperationException()); + return DocumentPtr(); +} - ExplanationPtr CachedDfSource::explain(const WeightPtr& weight, int32_t doc) - { - boost::throw_exception(UnsupportedOperationException()); - return ExplanationPtr(); - } +ExplanationPtr CachedDfSource::explain(const WeightPtr& weight, int32_t doc) { + boost::throw_exception(UnsupportedOperationException()); + return ExplanationPtr(); +} - void CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) - { - boost::throw_exception(UnsupportedOperationException()); - } +void CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& results) { + boost::throw_exception(UnsupportedOperationException()); +} - TopDocsPtr CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) - { - boost::throw_exception(UnsupportedOperationException()); - return TopDocsPtr(); - } +TopDocsPtr CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { + boost::throw_exception(UnsupportedOperationException()); + return TopDocsPtr(); +} - TopFieldDocsPtr CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) - { - boost::throw_exception(UnsupportedOperationException()); - return TopFieldDocsPtr(); - } +TopFieldDocsPtr CachedDfSource::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { + boost::throw_exception(UnsupportedOperationException()); + return TopFieldDocsPtr(); +} - MultiSearcherCallableNoSort::MultiSearcherCallableNoSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, - const FilterPtr& filter, int32_t nDocs, const HitQueuePtr& hq, int32_t i, - Collection starts) - { - this->lock = lock; - this->searchable = searchable; - this->weight = weight; - this->filter = filter; - this->nDocs = nDocs; - this->hq = hq; - this->i = i; - this->starts = starts; - } +MultiSearcherCallableNoSort::MultiSearcherCallableNoSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, + const FilterPtr& filter, int32_t nDocs, const HitQueuePtr& hq, int32_t i, + Collection starts) { + this->lock = lock; + this->searchable = searchable; + this->weight = weight; + this->filter = filter; + this->nDocs = nDocs; + this->hq = hq; + this->i = i; + this->starts = starts; +} - MultiSearcherCallableNoSort::~MultiSearcherCallableNoSort() - { - } +MultiSearcherCallableNoSort::~MultiSearcherCallableNoSort() { +} - TopDocsPtr MultiSearcherCallableNoSort::call() - { - TopDocsPtr docs(searchable->search(weight, filter, nDocs)); - Collection scoreDocs(docs->scoreDocs); - for (int32_t j = 0; j < scoreDocs.size(); ++j) // merge scoreDocs into hq - { - ScoreDocPtr scoreDoc(scoreDocs[j]); - scoreDoc->doc += starts[i]; // convert doc - - SyncLock syncLock(lock); - if (scoreDoc == hq->addOverflow(scoreDoc)) - break; +TopDocsPtr MultiSearcherCallableNoSort::call() { + TopDocsPtr docs(searchable->search(weight, filter, nDocs)); + Collection scoreDocs(docs->scoreDocs); + for (int32_t j = 0; j < scoreDocs.size(); ++j) { // merge scoreDocs into hq + ScoreDocPtr scoreDoc(scoreDocs[j]); + scoreDoc->doc += starts[i]; // convert doc + + SyncLock syncLock(lock); + if (scoreDoc == hq->addOverflow(scoreDoc)) { + break; } - return docs; } + return docs; +} - MultiSearcherCallableWithSort::MultiSearcherCallableWithSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, - const FilterPtr& filter, int32_t nDocs, const FieldDocSortedHitQueuePtr& hq, - const SortPtr& sort, int32_t i, Collection starts) - { - this->lock = lock; - this->searchable = searchable; - this->weight = weight; - this->filter = filter; - this->nDocs = nDocs; - this->hq = hq; - this->i = i; - this->starts = starts; - this->sort = sort; - } +MultiSearcherCallableWithSort::MultiSearcherCallableWithSort(const SynchronizePtr& lock, const SearchablePtr& searchable, const WeightPtr& weight, + const FilterPtr& filter, int32_t nDocs, const FieldDocSortedHitQueuePtr& hq, + const SortPtr& sort, int32_t i, Collection starts) { + this->lock = lock; + this->searchable = searchable; + this->weight = weight; + this->filter = filter; + this->nDocs = nDocs; + this->hq = hq; + this->i = i; + this->starts = starts; + this->sort = sort; +} - MultiSearcherCallableWithSort::~MultiSearcherCallableWithSort() - { - } +MultiSearcherCallableWithSort::~MultiSearcherCallableWithSort() { +} - TopFieldDocsPtr MultiSearcherCallableWithSort::call() - { - TopFieldDocsPtr docs(searchable->search(weight, filter, nDocs, sort)); - // If one of the Sort fields is FIELD_DOC, need to fix its values, so that it will break ties by doc Id - // properly. Otherwise, it will compare to 'relative' doc Ids, that belong to two different searchables. - for (int32_t j = 0; j < docs->fields.size(); ++j) - { - if (docs->fields[j]->getType() == SortField::DOC) - { - // iterate over the score docs and change their fields value - for (int32_t j2 = 0; j2 < docs->scoreDocs.size(); ++j2) - { - FieldDocPtr fd(boost::dynamic_pointer_cast(docs->scoreDocs[j2])); - fd->fields[j] = VariantUtils::get(fd->fields[j]) + starts[i]; - } - break; +TopFieldDocsPtr MultiSearcherCallableWithSort::call() { + TopFieldDocsPtr docs(searchable->search(weight, filter, nDocs, sort)); + // If one of the Sort fields is FIELD_DOC, need to fix its values, so that it will break ties by doc Id + // properly. Otherwise, it will compare to 'relative' doc Ids, that belong to two different searchables. + for (int32_t j = 0; j < docs->fields.size(); ++j) { + if (docs->fields[j]->getType() == SortField::DOC) { + // iterate over the score docs and change their fields value + for (int32_t j2 = 0; j2 < docs->scoreDocs.size(); ++j2) { + FieldDocPtr fd(boost::dynamic_pointer_cast(docs->scoreDocs[j2])); + fd->fields[j] = VariantUtils::get(fd->fields[j]) + starts[i]; } + break; } + } - { - SyncLock syncLock(lock); - hq->setFields(docs->fields); - } + { + SyncLock syncLock(lock); + hq->setFields(docs->fields); + } - Collection scoreDocs(docs->scoreDocs); - for (int32_t j = 0; j < scoreDocs.size(); ++j) // merge scoreDocs into hq - { - FieldDocPtr fieldDoc(boost::dynamic_pointer_cast(scoreDocs[j])); - fieldDoc->doc += starts[i]; // convert doc + Collection scoreDocs(docs->scoreDocs); + for (int32_t j = 0; j < scoreDocs.size(); ++j) { // merge scoreDocs into hq + FieldDocPtr fieldDoc(boost::dynamic_pointer_cast(scoreDocs[j])); + fieldDoc->doc += starts[i]; // convert doc - SyncLock syncLock(lock); - if (fieldDoc == hq->addOverflow(fieldDoc)) - break; + SyncLock syncLock(lock); + if (fieldDoc == hq->addOverflow(fieldDoc)) { + break; } - - return docs; } - MultiSearcherCollector::MultiSearcherCollector(const CollectorPtr& collector, int32_t start) - { - this->collector = collector; - this->start = start; - } + return docs; +} - MultiSearcherCollector::~MultiSearcherCollector() - { - } +MultiSearcherCollector::MultiSearcherCollector(const CollectorPtr& collector, int32_t start) { + this->collector = collector; + this->start = start; +} - void MultiSearcherCollector::setScorer(const ScorerPtr& scorer) - { - collector->setScorer(scorer); - } +MultiSearcherCollector::~MultiSearcherCollector() { +} - void MultiSearcherCollector::collect(int32_t doc) - { - collector->collect(doc); - } +void MultiSearcherCollector::setScorer(const ScorerPtr& scorer) { + collector->setScorer(scorer); +} - void MultiSearcherCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - collector->setNextReader(reader, start + docBase); - } +void MultiSearcherCollector::collect(int32_t doc) { + collector->collect(doc); +} + +void MultiSearcherCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + collector->setNextReader(reader, start + docBase); +} + +bool MultiSearcherCollector::acceptsDocsOutOfOrder() { + return collector->acceptsDocsOutOfOrder(); +} - bool MultiSearcherCollector::acceptsDocsOutOfOrder() - { - return collector->acceptsDocsOutOfOrder(); - } } diff --git a/src/core/search/MultiTermQuery.cpp b/src/core/search/MultiTermQuery.cpp index f821222e..89a0e98c 100644 --- a/src/core/search/MultiTermQuery.cpp +++ b/src/core/search/MultiTermQuery.cpp @@ -18,326 +18,286 @@ #include "IndexReader.h" #include "MiscUtils.h" -namespace Lucene -{ - MultiTermQuery::MultiTermQuery() - { - numberOfTerms = 0; - rewriteMethod = CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(); - } +namespace Lucene { - MultiTermQuery::~MultiTermQuery() - { - } +MultiTermQuery::MultiTermQuery() { + numberOfTerms = 0; + rewriteMethod = CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(); +} - RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE() - { - static RewriteMethodPtr _CONSTANT_SCORE_FILTER_REWRITE; - if (!_CONSTANT_SCORE_FILTER_REWRITE) - { - _CONSTANT_SCORE_FILTER_REWRITE = newLucene(); - CycleCheck::addStatic(_CONSTANT_SCORE_FILTER_REWRITE); - } - return _CONSTANT_SCORE_FILTER_REWRITE; - } +MultiTermQuery::~MultiTermQuery() { +} - RewriteMethodPtr MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE() - { - static RewriteMethodPtr _SCORING_BOOLEAN_QUERY_REWRITE; - if (!_SCORING_BOOLEAN_QUERY_REWRITE) - { - _SCORING_BOOLEAN_QUERY_REWRITE = newLucene(); - CycleCheck::addStatic(_SCORING_BOOLEAN_QUERY_REWRITE); - } - return _SCORING_BOOLEAN_QUERY_REWRITE; +RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE() { + static RewriteMethodPtr _CONSTANT_SCORE_FILTER_REWRITE; + if (!_CONSTANT_SCORE_FILTER_REWRITE) { + _CONSTANT_SCORE_FILTER_REWRITE = newLucene(); + CycleCheck::addStatic(_CONSTANT_SCORE_FILTER_REWRITE); } + return _CONSTANT_SCORE_FILTER_REWRITE; +} - RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE() - { - static RewriteMethodPtr _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE; - if (!_CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE) - { - _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE = newLucene(); - CycleCheck::addStatic(_CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE); - } - return _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE; +RewriteMethodPtr MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE() { + static RewriteMethodPtr _SCORING_BOOLEAN_QUERY_REWRITE; + if (!_SCORING_BOOLEAN_QUERY_REWRITE) { + _SCORING_BOOLEAN_QUERY_REWRITE = newLucene(); + CycleCheck::addStatic(_SCORING_BOOLEAN_QUERY_REWRITE); } + return _SCORING_BOOLEAN_QUERY_REWRITE; +} - RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT() - { - static RewriteMethodPtr _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT; - if (!_CONSTANT_SCORE_AUTO_REWRITE_DEFAULT) - { - _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT = newLucene(); - CycleCheck::addStatic(_CONSTANT_SCORE_AUTO_REWRITE_DEFAULT); - } - return _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT; +RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE() { + static RewriteMethodPtr _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE; + if (!_CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE) { + _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE = newLucene(); + CycleCheck::addStatic(_CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE); } + return _CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE; +} - int32_t MultiTermQuery::getTotalNumberOfTerms() - { - return numberOfTerms; +RewriteMethodPtr MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT() { + static RewriteMethodPtr _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT; + if (!_CONSTANT_SCORE_AUTO_REWRITE_DEFAULT) { + _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT = newLucene(); + CycleCheck::addStatic(_CONSTANT_SCORE_AUTO_REWRITE_DEFAULT); } + return _CONSTANT_SCORE_AUTO_REWRITE_DEFAULT; +} - void MultiTermQuery::clearTotalNumberOfTerms() - { - numberOfTerms = 0; - } +int32_t MultiTermQuery::getTotalNumberOfTerms() { + return numberOfTerms; +} - void MultiTermQuery::incTotalNumberOfTerms(int32_t inc) - { - numberOfTerms += inc; - } +void MultiTermQuery::clearTotalNumberOfTerms() { + numberOfTerms = 0; +} - QueryPtr MultiTermQuery::rewrite(const IndexReaderPtr& reader) - { - return rewriteMethod->rewrite(reader, shared_from_this()); - } +void MultiTermQuery::incTotalNumberOfTerms(int32_t inc) { + numberOfTerms += inc; +} - RewriteMethodPtr MultiTermQuery::getRewriteMethod() - { - return rewriteMethod; - } +QueryPtr MultiTermQuery::rewrite(const IndexReaderPtr& reader) { + return rewriteMethod->rewrite(reader, shared_from_this()); +} - void MultiTermQuery::setRewriteMethod(const RewriteMethodPtr& method) - { - rewriteMethod = method; - } +RewriteMethodPtr MultiTermQuery::getRewriteMethod() { + return rewriteMethod; +} - LuceneObjectPtr MultiTermQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = Query::clone(other); - MultiTermQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->rewriteMethod = rewriteMethod; - cloneQuery->numberOfTerms = numberOfTerms; - return cloneQuery; - } +void MultiTermQuery::setRewriteMethod(const RewriteMethodPtr& method) { + rewriteMethod = method; +} - int32_t MultiTermQuery::hashCode() - { - int32_t prime = 31; - int32_t result = 1; - result = prime * result + MiscUtils::doubleToIntBits(getBoost()); - result = prime * result; - result += rewriteMethod->hashCode(); - return result; - } +LuceneObjectPtr MultiTermQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = Query::clone(other); + MultiTermQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->rewriteMethod = rewriteMethod; + cloneQuery->numberOfTerms = numberOfTerms; + return cloneQuery; +} - bool MultiTermQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - MultiTermQueryPtr otherMultiTermQuery(boost::dynamic_pointer_cast(other)); - if (!otherMultiTermQuery) - return false; - if (MiscUtils::doubleToIntBits(getBoost()) != MiscUtils::doubleToIntBits(otherMultiTermQuery->getBoost())) - return false; - if (!rewriteMethod->equals(otherMultiTermQuery->rewriteMethod)) - return false; +int32_t MultiTermQuery::hashCode() { + int32_t prime = 31; + int32_t result = 1; + result = prime * result + MiscUtils::doubleToIntBits(getBoost()); + result = prime * result; + result += rewriteMethod->hashCode(); + return result; +} + +bool MultiTermQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { return true; } - - RewriteMethod::~RewriteMethod() - { + if (!other) { + return false; } - - ConstantScoreFilterRewrite::~ConstantScoreFilterRewrite() - { + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } - - QueryPtr ConstantScoreFilterRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) - { - QueryPtr result(newLucene(newLucene(query))); - result->setBoost(query->getBoost()); - return result; + MultiTermQueryPtr otherMultiTermQuery(boost::dynamic_pointer_cast(other)); + if (!otherMultiTermQuery) { + return false; } - - ScoringBooleanQueryRewrite::~ScoringBooleanQueryRewrite() - { + if (MiscUtils::doubleToIntBits(getBoost()) != MiscUtils::doubleToIntBits(otherMultiTermQuery->getBoost())) { + return false; } + if (!rewriteMethod->equals(otherMultiTermQuery->rewriteMethod)) { + return false; + } + return true; +} - QueryPtr ScoringBooleanQueryRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) - { - FilteredTermEnumPtr enumerator(query->getEnum(reader)); - BooleanQueryPtr result(newLucene(true)); - int32_t count = 0; - LuceneException finally; - try - { - do - { - TermPtr t(enumerator->term()); - if (t) - { - TermQueryPtr tq(newLucene(t)); // found a match - tq->setBoost(query->getBoost() * enumerator->difference()); // set the boost - result->add(tq, BooleanClause::SHOULD); // add to query - ++count; - } +RewriteMethod::~RewriteMethod() { +} + +ConstantScoreFilterRewrite::~ConstantScoreFilterRewrite() { +} + +QueryPtr ConstantScoreFilterRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { + QueryPtr result(newLucene(newLucene(query))); + result->setBoost(query->getBoost()); + return result; +} + +ScoringBooleanQueryRewrite::~ScoringBooleanQueryRewrite() { +} + +QueryPtr ScoringBooleanQueryRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { + FilteredTermEnumPtr enumerator(query->getEnum(reader)); + BooleanQueryPtr result(newLucene(true)); + int32_t count = 0; + LuceneException finally; + try { + do { + TermPtr t(enumerator->term()); + if (t) { + TermQueryPtr tq(newLucene(t)); // found a match + tq->setBoost(query->getBoost() * enumerator->difference()); // set the boost + result->add(tq, BooleanClause::SHOULD); // add to query + ++count; } - while (enumerator->next()); - } - catch (LuceneException& e) - { - finally = e; - } - enumerator->close(); - finally.throwException(); - query->incTotalNumberOfTerms(count); - return result; - } + } while (enumerator->next()); + } catch (LuceneException& e) { + finally = e; + } + enumerator->close(); + finally.throwException(); + query->incTotalNumberOfTerms(count); + return result; +} - ConstantScoreBooleanQueryRewrite::~ConstantScoreBooleanQueryRewrite() - { - } +ConstantScoreBooleanQueryRewrite::~ConstantScoreBooleanQueryRewrite() { +} - QueryPtr ConstantScoreBooleanQueryRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) - { - // strip the scores off - QueryPtr result(newLucene(newLucene(ScoringBooleanQueryRewrite::rewrite(reader, query)))); - result->setBoost(query->getBoost()); - return result; - } +QueryPtr ConstantScoreBooleanQueryRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { + // strip the scores off + QueryPtr result(newLucene(newLucene(ScoringBooleanQueryRewrite::rewrite(reader, query)))); + result->setBoost(query->getBoost()); + return result; +} - // Defaults derived from rough tests with a 20.0 million doc Wikipedia index. With more than 350 terms - // in the query, the filter method is fastest - const int32_t ConstantScoreAutoRewrite::DEFAULT_TERM_COUNT_CUTOFF = 350; +// Defaults derived from rough tests with a 20.0 million doc Wikipedia index. With more than 350 terms +// in the query, the filter method is fastest +const int32_t ConstantScoreAutoRewrite::DEFAULT_TERM_COUNT_CUTOFF = 350; - // If the query will hit more than 1 in 1000 of the docs in the index (0.1%), the filter method is fastest - const double ConstantScoreAutoRewrite::DEFAULT_DOC_COUNT_PERCENT = 0.1; +// If the query will hit more than 1 in 1000 of the docs in the index (0.1%), the filter method is fastest +const double ConstantScoreAutoRewrite::DEFAULT_DOC_COUNT_PERCENT = 0.1; - ConstantScoreAutoRewrite::ConstantScoreAutoRewrite() - { - termCountCutoff = DEFAULT_TERM_COUNT_CUTOFF; - docCountPercent = DEFAULT_DOC_COUNT_PERCENT; - } +ConstantScoreAutoRewrite::ConstantScoreAutoRewrite() { + termCountCutoff = DEFAULT_TERM_COUNT_CUTOFF; + docCountPercent = DEFAULT_DOC_COUNT_PERCENT; +} - ConstantScoreAutoRewrite::~ConstantScoreAutoRewrite() - { - } +ConstantScoreAutoRewrite::~ConstantScoreAutoRewrite() { +} - void ConstantScoreAutoRewrite::setTermCountCutoff(int32_t count) - { - termCountCutoff = count; - } +void ConstantScoreAutoRewrite::setTermCountCutoff(int32_t count) { + termCountCutoff = count; +} - int32_t ConstantScoreAutoRewrite::getTermCountCutoff() - { - return termCountCutoff; - } +int32_t ConstantScoreAutoRewrite::getTermCountCutoff() { + return termCountCutoff; +} - void ConstantScoreAutoRewrite::setDocCountPercent(double percent) - { - docCountPercent = percent; - } +void ConstantScoreAutoRewrite::setDocCountPercent(double percent) { + docCountPercent = percent; +} - double ConstantScoreAutoRewrite::getDocCountPercent() - { - return docCountPercent; - } +double ConstantScoreAutoRewrite::getDocCountPercent() { + return docCountPercent; +} - QueryPtr ConstantScoreAutoRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) - { - // Get the enum and start visiting terms. If we exhaust the enum before hitting either of the - // cutoffs, we use ConstantBooleanQueryRewrite; else ConstantFilterRewrite - Collection pendingTerms(Collection::newInstance()); - int32_t docCountCutoff = (int32_t)((docCountPercent / 100.0) * (double)reader->maxDoc()); - int32_t termCountLimit = std::min(BooleanQuery::getMaxClauseCount(), termCountCutoff); - int32_t docVisitCount = 0; - - FilteredTermEnumPtr enumerator(query->getEnum(reader)); - QueryPtr result; - LuceneException finally; - try - { - while (true) - { - TermPtr t(enumerator->term()); - if (t) - { - pendingTerms.add(t); - // Loading the TermInfo from the terms dict here should not be costly, because 1) the - // query/filter will load the TermInfo when it runs, and 2) the terms dict has a cache - docVisitCount += reader->docFreq(t); - } +QueryPtr ConstantScoreAutoRewrite::rewrite(const IndexReaderPtr& reader, const MultiTermQueryPtr& query) { + // Get the enum and start visiting terms. If we exhaust the enum before hitting either of the + // cutoffs, we use ConstantBooleanQueryRewrite; else ConstantFilterRewrite + Collection pendingTerms(Collection::newInstance()); + int32_t docCountCutoff = (int32_t)((docCountPercent / 100.0) * (double)reader->maxDoc()); + int32_t termCountLimit = std::min(BooleanQuery::getMaxClauseCount(), termCountCutoff); + int32_t docVisitCount = 0; + + FilteredTermEnumPtr enumerator(query->getEnum(reader)); + QueryPtr result; + LuceneException finally; + try { + while (true) { + TermPtr t(enumerator->term()); + if (t) { + pendingTerms.add(t); + // Loading the TermInfo from the terms dict here should not be costly, because 1) the + // query/filter will load the TermInfo when it runs, and 2) the terms dict has a cache + docVisitCount += reader->docFreq(t); + } - if (pendingTerms.size() >= termCountLimit || docVisitCount >= docCountCutoff) - { - // Too many terms -- make a filter. - result = newLucene(newLucene(query)); - result->setBoost(query->getBoost()); - break; - } - else if (!enumerator->next()) - { - // Enumeration is done, and we hit a small enough number of terms and docs - - // just make a BooleanQuery, now - BooleanQueryPtr bq(newLucene(true)); - for (Collection::iterator term = pendingTerms.begin(); term != pendingTerms.end(); ++ term) - { - TermQueryPtr tq(newLucene(*term)); - bq->add(tq, BooleanClause::SHOULD); - } - // Strip scores - result = newLucene(newLucene(bq)); - result->setBoost(query->getBoost()); - query->incTotalNumberOfTerms(pendingTerms.size()); - break; + if (pendingTerms.size() >= termCountLimit || docVisitCount >= docCountCutoff) { + // Too many terms -- make a filter. + result = newLucene(newLucene(query)); + result->setBoost(query->getBoost()); + break; + } else if (!enumerator->next()) { + // Enumeration is done, and we hit a small enough number of terms and docs - + // just make a BooleanQuery, now + BooleanQueryPtr bq(newLucene(true)); + for (Collection::iterator term = pendingTerms.begin(); term != pendingTerms.end(); ++ term) { + TermQueryPtr tq(newLucene(*term)); + bq->add(tq, BooleanClause::SHOULD); } + // Strip scores + result = newLucene(newLucene(bq)); + result->setBoost(query->getBoost()); + query->incTotalNumberOfTerms(pendingTerms.size()); + break; } } - catch (LuceneException& e) - { - finally = e; - } - enumerator->close(); - finally.throwException(); - return result; + } catch (LuceneException& e) { + finally = e; } + enumerator->close(); + finally.throwException(); + return result; +} - int32_t ConstantScoreAutoRewrite::hashCode() - { - int32_t prime = 1279; - return (int32_t)(prime * termCountCutoff + MiscUtils::doubleToLongBits(docCountPercent)); - } - - bool ConstantScoreAutoRewrite::equals(const LuceneObjectPtr& other) - { - if (RewriteMethod::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - - ConstantScoreAutoRewritePtr otherConstantScoreAutoRewrite(boost::dynamic_pointer_cast(other)); - if (!otherConstantScoreAutoRewrite) - return false; - - if (termCountCutoff != otherConstantScoreAutoRewrite->termCountCutoff) - return false; - - if (MiscUtils::doubleToLongBits(docCountPercent) != MiscUtils::doubleToLongBits(otherConstantScoreAutoRewrite->docCountPercent)) - return false; +int32_t ConstantScoreAutoRewrite::hashCode() { + int32_t prime = 1279; + return (int32_t)(prime * termCountCutoff + MiscUtils::doubleToLongBits(docCountPercent)); +} +bool ConstantScoreAutoRewrite::equals(const LuceneObjectPtr& other) { + if (RewriteMethod::equals(other)) { return true; } + if (!other) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } - ConstantScoreAutoRewriteDefault::~ConstantScoreAutoRewriteDefault() - { + ConstantScoreAutoRewritePtr otherConstantScoreAutoRewrite(boost::dynamic_pointer_cast(other)); + if (!otherConstantScoreAutoRewrite) { + return false; } - void ConstantScoreAutoRewriteDefault::setTermCountCutoff(int32_t count) - { - boost::throw_exception(UnsupportedOperationException(L"Please create a private instance")); + if (termCountCutoff != otherConstantScoreAutoRewrite->termCountCutoff) { + return false; } - void ConstantScoreAutoRewriteDefault::setDocCountPercent(double percent) - { - boost::throw_exception(UnsupportedOperationException(L"Please create a private instance")); + if (MiscUtils::doubleToLongBits(docCountPercent) != MiscUtils::doubleToLongBits(otherConstantScoreAutoRewrite->docCountPercent)) { + return false; } + + return true; +} + +ConstantScoreAutoRewriteDefault::~ConstantScoreAutoRewriteDefault() { +} + +void ConstantScoreAutoRewriteDefault::setTermCountCutoff(int32_t count) { + boost::throw_exception(UnsupportedOperationException(L"Please create a private instance")); +} + +void ConstantScoreAutoRewriteDefault::setDocCountPercent(double percent) { + boost::throw_exception(UnsupportedOperationException(L"Please create a private instance")); +} + } diff --git a/src/core/search/MultiTermQueryWrapperFilter.cpp b/src/core/search/MultiTermQueryWrapperFilter.cpp index f23747a4..4b6c203f 100644 --- a/src/core/search/MultiTermQueryWrapperFilter.cpp +++ b/src/core/search/MultiTermQueryWrapperFilter.cpp @@ -16,105 +16,95 @@ #include "OpenBitSet.h" #include "MiscUtils.h" -namespace Lucene -{ - MultiTermQueryWrapperFilter::MultiTermQueryWrapperFilter(const MultiTermQueryPtr& query) - { - this->query = query; - } +namespace Lucene { - MultiTermQueryWrapperFilter::~MultiTermQueryWrapperFilter() - { - } +MultiTermQueryWrapperFilter::MultiTermQueryWrapperFilter(const MultiTermQueryPtr& query) { + this->query = query; +} - String MultiTermQueryWrapperFilter::toString() - { - // query->toString should be ok for the filter, too, if the query boost is 1.0 - return query->toString(); - } +MultiTermQueryWrapperFilter::~MultiTermQueryWrapperFilter() { +} + +String MultiTermQueryWrapperFilter::toString() { + // query->toString should be ok for the filter, too, if the query boost is 1.0 + return query->toString(); +} - bool MultiTermQueryWrapperFilter::equals(const LuceneObjectPtr& other) - { - if (Filter::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - MultiTermQueryWrapperFilterPtr otherMultiTermQueryWrapperFilter(boost::dynamic_pointer_cast(other)); - if (otherMultiTermQueryWrapperFilter) - return query->equals(otherMultiTermQueryWrapperFilter->query); +bool MultiTermQueryWrapperFilter::equals(const LuceneObjectPtr& other) { + if (Filter::equals(other)) { + return true; + } + if (!other) { return false; } - - int32_t MultiTermQueryWrapperFilter::hashCode() - { - return query->hashCode(); + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } - - int32_t MultiTermQueryWrapperFilter::getTotalNumberOfTerms() - { - return query->getTotalNumberOfTerms(); + MultiTermQueryWrapperFilterPtr otherMultiTermQueryWrapperFilter(boost::dynamic_pointer_cast(other)); + if (otherMultiTermQueryWrapperFilter) { + return query->equals(otherMultiTermQueryWrapperFilter->query); } + return false; +} - void MultiTermQueryWrapperFilter::clearTotalNumberOfTerms() - { - query->clearTotalNumberOfTerms(); - } +int32_t MultiTermQueryWrapperFilter::hashCode() { + return query->hashCode(); +} - DocIdSetPtr MultiTermQueryWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) - { - TermEnumPtr enumerator(query->getEnum(reader)); - OpenBitSetPtr bitSet; - LuceneException finally; - try - { - // if current term in enum is null, the enum is empty -> shortcut - if (!enumerator->term()) - return DocIdSet::EMPTY_DOCIDSET(); - // else fill into a OpenBitSet - bitSet = newLucene(reader->maxDoc()); - Collection docs(Collection::newInstance(32)); - Collection freqs(Collection::newInstance(32)); - TermDocsPtr termDocs(reader->termDocs()); - try - { - int32_t termCount = 0; - do - { - TermPtr term(enumerator->term()); - if (!term) - break; - ++termCount; - termDocs->seek(term); - while (true) - { - int32_t count = termDocs->read(docs, freqs); - if (count != 0) - { - for (int32_t i = 0; i < count; ++i) - bitSet->set(docs[i]); +int32_t MultiTermQueryWrapperFilter::getTotalNumberOfTerms() { + return query->getTotalNumberOfTerms(); +} + +void MultiTermQueryWrapperFilter::clearTotalNumberOfTerms() { + query->clearTotalNumberOfTerms(); +} + +DocIdSetPtr MultiTermQueryWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) { + TermEnumPtr enumerator(query->getEnum(reader)); + OpenBitSetPtr bitSet; + LuceneException finally; + try { + // if current term in enum is null, the enum is empty -> shortcut + if (!enumerator->term()) { + return DocIdSet::EMPTY_DOCIDSET(); + } + // else fill into a OpenBitSet + bitSet = newLucene(reader->maxDoc()); + Collection docs(Collection::newInstance(32)); + Collection freqs(Collection::newInstance(32)); + TermDocsPtr termDocs(reader->termDocs()); + try { + int32_t termCount = 0; + do { + TermPtr term(enumerator->term()); + if (!term) { + break; + } + ++termCount; + termDocs->seek(term); + while (true) { + int32_t count = termDocs->read(docs, freqs); + if (count != 0) { + for (int32_t i = 0; i < count; ++i) { + bitSet->set(docs[i]); } - else - break; + } else { + break; } } - while (enumerator->next()); + } while (enumerator->next()); - query->incTotalNumberOfTerms(termCount); - } - catch (LuceneException& e) - { - finally = e; - } - termDocs->close(); - } - catch (LuceneException& e) - { + query->incTotalNumberOfTerms(termCount); + } catch (LuceneException& e) { finally = e; } - enumerator->close(); - finally.throwException(); - return bitSet; + termDocs->close(); + } catch (LuceneException& e) { + finally = e; } + enumerator->close(); + finally.throwException(); + return bitSet; +} + } diff --git a/src/core/search/NumericRangeFilter.cpp b/src/core/search/NumericRangeFilter.cpp index b00333ca..562f8d1e 100644 --- a/src/core/search/NumericRangeFilter.cpp +++ b/src/core/search/NumericRangeFilter.cpp @@ -8,78 +8,64 @@ #include "NumericRangeFilter.h" #include "NumericRangeQuery.h" -namespace Lucene -{ - NumericRangeFilter::NumericRangeFilter(const NumericRangeQueryPtr& query) : MultiTermQueryWrapperFilter(query) - { - } - - NumericRangeFilter::~NumericRangeFilter() - { - } - - NumericRangeFilterPtr NumericRangeFilter::newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); - } - - NumericRangeFilterPtr NumericRangeFilter::newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, min, max, minInclusive, maxInclusive); - } - - NumericRangeFilterPtr NumericRangeFilter::newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); - } - - NumericRangeFilterPtr NumericRangeFilter::newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, min, max, minInclusive, maxInclusive); - } - - NumericRangeFilterPtr NumericRangeFilter::newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); - } - - NumericRangeFilterPtr NumericRangeFilter::newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, min, max, minInclusive, maxInclusive); - } - - NumericRangeFilterPtr NumericRangeFilter::newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) - { - return newLucene(NumericRangeQuery::newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive)); - } - - NumericRangeFilterPtr NumericRangeFilter::newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) - { - return newLucene(NumericRangeQuery::newNumericRange(field, min, max, minInclusive, maxInclusive)); - } - - String NumericRangeFilter::getField() - { - return boost::static_pointer_cast(query)->field; - } - - bool NumericRangeFilter::includesMin() - { - return boost::static_pointer_cast(query)->minInclusive; - } - - bool NumericRangeFilter::includesMax() - { - return boost::static_pointer_cast(query)->maxInclusive; - } - - NumericValue NumericRangeFilter::getMin() - { - return boost::static_pointer_cast(query)->min; - } - - NumericValue NumericRangeFilter::getMax() - { - return boost::static_pointer_cast(query)->min; - } +namespace Lucene { + +NumericRangeFilter::NumericRangeFilter(const NumericRangeQueryPtr& query) : MultiTermQueryWrapperFilter(query) { +} + +NumericRangeFilter::~NumericRangeFilter() { +} + +NumericRangeFilterPtr NumericRangeFilter::newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); +} + +NumericRangeFilterPtr NumericRangeFilter::newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, min, max, minInclusive, maxInclusive); +} + +NumericRangeFilterPtr NumericRangeFilter::newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); +} + +NumericRangeFilterPtr NumericRangeFilter::newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, min, max, minInclusive, maxInclusive); +} + +NumericRangeFilterPtr NumericRangeFilter::newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); +} + +NumericRangeFilterPtr NumericRangeFilter::newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, min, max, minInclusive, maxInclusive); +} + +NumericRangeFilterPtr NumericRangeFilter::newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { + return newLucene(NumericRangeQuery::newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive)); +} + +NumericRangeFilterPtr NumericRangeFilter::newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { + return newLucene(NumericRangeQuery::newNumericRange(field, min, max, minInclusive, maxInclusive)); +} + +String NumericRangeFilter::getField() { + return boost::static_pointer_cast(query)->field; +} + +bool NumericRangeFilter::includesMin() { + return boost::static_pointer_cast(query)->minInclusive; +} + +bool NumericRangeFilter::includesMax() { + return boost::static_pointer_cast(query)->maxInclusive; +} + +NumericValue NumericRangeFilter::getMin() { + return boost::static_pointer_cast(query)->min; +} + +NumericValue NumericRangeFilter::getMax() { + return boost::static_pointer_cast(query)->min; +} + } diff --git a/src/core/search/NumericRangeQuery.cpp b/src/core/search/NumericRangeQuery.cpp index ac55d27f..384abd27 100644 --- a/src/core/search/NumericRangeQuery.cpp +++ b/src/core/search/NumericRangeQuery.cpp @@ -13,364 +13,340 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - NumericRangeQuery::NumericRangeQuery(const String& field, int32_t precisionStep, int32_t valSize, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) - { - BOOST_ASSERT(valSize == 32 || valSize == 64); - if (precisionStep < 1) - boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); - this->field = field; - this->precisionStep = precisionStep; - this->valSize = valSize; - this->min = min; - this->max = max; - this->minInclusive = minInclusive; - this->maxInclusive = maxInclusive; - - // For bigger precisionSteps this query likely hits too many terms, so set to CONSTANT_SCORE_FILTER - // right off (especially as the FilteredTermEnum is costly if wasted only for AUTO tests because it - // creates new enums from IndexReader for each sub-range) - switch (valSize) - { - case 64: - setRewriteMethod(precisionStep > 6 ? CONSTANT_SCORE_FILTER_REWRITE() : CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()); - break; - case 32: - setRewriteMethod(precisionStep > 8 ? CONSTANT_SCORE_FILTER_REWRITE() : CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()); - break; - default: - // should never happen - boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); - } - - // shortcut if upper bound == lower bound - if (!VariantUtils::isNull(min) && min == max) - setRewriteMethod(CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); +namespace Lucene { + +NumericRangeQuery::NumericRangeQuery(const String& field, int32_t precisionStep, int32_t valSize, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { + BOOST_ASSERT(valSize == 32 || valSize == 64); + if (precisionStep < 1) { + boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); + } + this->field = field; + this->precisionStep = precisionStep; + this->valSize = valSize; + this->min = min; + this->max = max; + this->minInclusive = minInclusive; + this->maxInclusive = maxInclusive; + + // For bigger precisionSteps this query likely hits too many terms, so set to CONSTANT_SCORE_FILTER + // right off (especially as the FilteredTermEnum is costly if wasted only for AUTO tests because it + // creates new enums from IndexReader for each sub-range) + switch (valSize) { + case 64: + setRewriteMethod(precisionStep > 6 ? CONSTANT_SCORE_FILTER_REWRITE() : CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()); + break; + case 32: + setRewriteMethod(precisionStep > 8 ? CONSTANT_SCORE_FILTER_REWRITE() : CONSTANT_SCORE_AUTO_REWRITE_DEFAULT()); + break; + default: + // should never happen + boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); + } + + // shortcut if upper bound == lower bound + if (!VariantUtils::isNull(min) && min == max) { + setRewriteMethod(CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); } +} - NumericRangeQuery::~NumericRangeQuery() - { - } +NumericRangeQuery::~NumericRangeQuery() { +} - NumericRangeQueryPtr NumericRangeQuery::newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); - } +NumericRangeQueryPtr NumericRangeQuery::newLongRange(const String& field, int32_t precisionStep, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); +} - NumericRangeQueryPtr NumericRangeQuery::newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, min, max, minInclusive, maxInclusive); - } +NumericRangeQueryPtr NumericRangeQuery::newLongRange(const String& field, int64_t min, int64_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, min, max, minInclusive, maxInclusive); +} - NumericRangeQueryPtr NumericRangeQuery::newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); - } +NumericRangeQueryPtr NumericRangeQuery::newIntRange(const String& field, int32_t precisionStep, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); +} - NumericRangeQueryPtr NumericRangeQuery::newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, min, max, minInclusive, maxInclusive); - } +NumericRangeQueryPtr NumericRangeQuery::newIntRange(const String& field, int32_t min, int32_t max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, min, max, minInclusive, maxInclusive); +} - NumericRangeQueryPtr NumericRangeQuery::newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); - } +NumericRangeQueryPtr NumericRangeQuery::newDoubleRange(const String& field, int32_t precisionStep, double min, double max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, precisionStep, min, max, minInclusive, maxInclusive); +} - NumericRangeQueryPtr NumericRangeQuery::newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, min, max, minInclusive, maxInclusive); - } +NumericRangeQueryPtr NumericRangeQuery::newDoubleRange(const String& field, double min, double max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, min, max, minInclusive, maxInclusive); +} - NumericRangeQueryPtr NumericRangeQuery::newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) - { - if (!VariantUtils::equalsType(min, max)) - boost::throw_exception(IllegalArgumentException(L"min/max must be of the same type")); - int32_t valSize = VariantUtils::typeOf(min) ? 32 : 64; - return newLucene(field, precisionStep, valSize, min, max, minInclusive, maxInclusive); +NumericRangeQueryPtr NumericRangeQuery::newNumericRange(const String& field, int32_t precisionStep, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { + if (!VariantUtils::equalsType(min, max)) { + boost::throw_exception(IllegalArgumentException(L"min/max must be of the same type")); } + int32_t valSize = VariantUtils::typeOf(min) ? 32 : 64; + return newLucene(field, precisionStep, valSize, min, max, minInclusive, maxInclusive); +} - NumericRangeQueryPtr NumericRangeQuery::newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) - { - return newNumericRange(field, NumericUtils::PRECISION_STEP_DEFAULT, min, max, minInclusive, maxInclusive); - } +NumericRangeQueryPtr NumericRangeQuery::newNumericRange(const String& field, NumericValue min, NumericValue max, bool minInclusive, bool maxInclusive) { + return newNumericRange(field, NumericUtils::PRECISION_STEP_DEFAULT, min, max, minInclusive, maxInclusive); +} - FilteredTermEnumPtr NumericRangeQuery::getEnum(const IndexReaderPtr& reader) - { - return newLucene(shared_from_this(), reader); - } +FilteredTermEnumPtr NumericRangeQuery::getEnum(const IndexReaderPtr& reader) { + return newLucene(shared_from_this(), reader); +} - String NumericRangeQuery::getField() - { - return field; - } +String NumericRangeQuery::getField() { + return field; +} - bool NumericRangeQuery::includesMin() - { - return minInclusive; - } +bool NumericRangeQuery::includesMin() { + return minInclusive; +} - bool NumericRangeQuery::includesMax() - { - return maxInclusive; - } +bool NumericRangeQuery::includesMax() { + return maxInclusive; +} - NumericValue NumericRangeQuery::getMin() - { - return min; - } +NumericValue NumericRangeQuery::getMin() { + return min; +} - NumericValue NumericRangeQuery::getMax() - { - return min; - } +NumericValue NumericRangeQuery::getMax() { + return min; +} - LuceneObjectPtr NumericRangeQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, precisionStep, valSize, min, max, minInclusive, maxInclusive)); - NumericRangeQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->field = field; - cloneQuery->precisionStep = precisionStep; - cloneQuery->valSize = valSize; - cloneQuery->min = min; - cloneQuery->max = max; - cloneQuery->minInclusive = minInclusive; - cloneQuery->maxInclusive = maxInclusive; - return cloneQuery; - } +LuceneObjectPtr NumericRangeQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, precisionStep, valSize, min, max, minInclusive, maxInclusive)); + NumericRangeQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->field = field; + cloneQuery->precisionStep = precisionStep; + cloneQuery->valSize = valSize; + cloneQuery->min = min; + cloneQuery->max = max; + cloneQuery->minInclusive = minInclusive; + cloneQuery->maxInclusive = maxInclusive; + return cloneQuery; +} + +String NumericRangeQuery::toString(const String& field) { + StringStream buffer; + if (this->field != field) { + buffer << this->field << L":"; + } + buffer << (minInclusive ? L"[" : L"{"); + if (VariantUtils::isNull(min)) { + buffer << L"*"; + } else { + buffer << min; + } + buffer << L" TO "; + if (VariantUtils::isNull(max)) { + buffer << L"*"; + } else { + buffer << max; + } + buffer << (maxInclusive ? L"]" : L"}"); + buffer << boostString(); + return buffer.str(); +} - String NumericRangeQuery::toString(const String& field) - { - StringStream buffer; - if (this->field != field) - buffer << this->field << L":"; - buffer << (minInclusive ? L"[" : L"{"); - if (VariantUtils::isNull(min)) - buffer << L"*"; - else - buffer << min; - buffer << L" TO "; - if (VariantUtils::isNull(max)) - buffer << L"*"; - else - buffer << max; - buffer << (maxInclusive ? L"]" : L"}"); - buffer << boostString(); - return buffer.str(); +bool NumericRangeQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!MultiTermQuery::equals(other)) { + return false; } - bool NumericRangeQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!MultiTermQuery::equals(other)) - return false; - - NumericRangeQueryPtr otherNumericRangeQuery(boost::dynamic_pointer_cast(other)); - if (!otherNumericRangeQuery) - return false; - - return (field == otherNumericRangeQuery->field && - min == otherNumericRangeQuery->min && - max == otherNumericRangeQuery->max && - minInclusive == otherNumericRangeQuery->minInclusive && - maxInclusive == otherNumericRangeQuery->maxInclusive && - precisionStep == otherNumericRangeQuery->precisionStep); + NumericRangeQueryPtr otherNumericRangeQuery(boost::dynamic_pointer_cast(other)); + if (!otherNumericRangeQuery) { + return false; } - int32_t NumericRangeQuery::hashCode() - { - int32_t hash = MultiTermQuery::hashCode(); - hash += StringUtils::hashCode(field) ^ 0x4565fd66 + precisionStep ^ 0x64365465; - if (!VariantUtils::isNull(min)) - hash += VariantUtils::hashCode(min) ^ 0x14fa55fb; - if (!VariantUtils::isNull(max)) - hash += VariantUtils::hashCode(max) ^ 0x733fa5fe; - return hash + (MiscUtils::hashCode(minInclusive) ^ 0x14fa55fb) + (MiscUtils::hashCode(maxInclusive) ^ 0x733fa5fe); + return (field == otherNumericRangeQuery->field && + min == otherNumericRangeQuery->min && + max == otherNumericRangeQuery->max && + minInclusive == otherNumericRangeQuery->minInclusive && + maxInclusive == otherNumericRangeQuery->maxInclusive && + precisionStep == otherNumericRangeQuery->precisionStep); +} + +int32_t NumericRangeQuery::hashCode() { + int32_t hash = MultiTermQuery::hashCode(); + hash += StringUtils::hashCode(field) ^ 0x4565fd66 + precisionStep ^ 0x64365465; + if (!VariantUtils::isNull(min)) { + hash += VariantUtils::hashCode(min) ^ 0x14fa55fb; } + if (!VariantUtils::isNull(max)) { + hash += VariantUtils::hashCode(max) ^ 0x733fa5fe; + } + return hash + (MiscUtils::hashCode(minInclusive) ^ 0x14fa55fb) + (MiscUtils::hashCode(maxInclusive) ^ 0x733fa5fe); +} - NumericRangeTermEnum::NumericRangeTermEnum(const NumericRangeQueryPtr& query, const IndexReaderPtr& reader) - { - this->_query = query; - this->reader = reader; - this->rangeBounds = Collection::newInstance(); - this->termTemplate = newLucene(query->field); - - switch (query->valSize) - { - case 64: - { - // lower - int64_t minBound = std::numeric_limits::min(); - if (VariantUtils::typeOf(query->min)) - minBound = VariantUtils::get(query->min); - else if (VariantUtils::typeOf(query->min)) - minBound = NumericUtils::doubleToSortableLong(VariantUtils::get(query->min)); - if (!query->minInclusive && !VariantUtils::isNull(query->min)) - { - if (minBound == std::numeric_limits::max()) - break; - ++minBound; - } - - // upper - int64_t maxBound = std::numeric_limits::max(); - if (VariantUtils::typeOf(query->max)) - maxBound = VariantUtils::get(query->max); - else if (VariantUtils::typeOf(query->max)) - maxBound = NumericUtils::doubleToSortableLong(VariantUtils::get(query->max)); - if (!query->maxInclusive && !VariantUtils::isNull(query->max)) - { - if (maxBound == std::numeric_limits::min()) - break; - --maxBound; - } - - NumericUtils::splitLongRange(newLucene(rangeBounds), query->precisionStep, minBound, maxBound); +NumericRangeTermEnum::NumericRangeTermEnum(const NumericRangeQueryPtr& query, const IndexReaderPtr& reader) { + this->_query = query; + this->reader = reader; + this->rangeBounds = Collection::newInstance(); + this->termTemplate = newLucene(query->field); + + switch (query->valSize) { + case 64: { + // lower + int64_t minBound = std::numeric_limits::min(); + if (VariantUtils::typeOf(query->min)) { + minBound = VariantUtils::get(query->min); + } else if (VariantUtils::typeOf(query->min)) { + minBound = NumericUtils::doubleToSortableLong(VariantUtils::get(query->min)); + } + if (!query->minInclusive && !VariantUtils::isNull(query->min)) { + if (minBound == std::numeric_limits::max()) { + break; + } + ++minBound; + } + // upper + int64_t maxBound = std::numeric_limits::max(); + if (VariantUtils::typeOf(query->max)) { + maxBound = VariantUtils::get(query->max); + } else if (VariantUtils::typeOf(query->max)) { + maxBound = NumericUtils::doubleToSortableLong(VariantUtils::get(query->max)); + } + if (!query->maxInclusive && !VariantUtils::isNull(query->max)) { + if (maxBound == std::numeric_limits::min()) { break; } + --maxBound; + } - case 32: - { - // lower - int32_t minBound = INT_MIN; - if (VariantUtils::typeOf(query->min)) - minBound = VariantUtils::get(query->min); - if (!query->minInclusive && !VariantUtils::isNull(query->min)) - { - if (minBound == INT_MAX) - break; - ++minBound; - } - - // upper - int32_t maxBound = INT_MAX; - if (VariantUtils::typeOf(query->max)) - maxBound = VariantUtils::get(query->max); - if (!query->maxInclusive && !VariantUtils::isNull(query->max)) - { - if (maxBound == INT_MIN) - break; - --maxBound; - } - - NumericUtils::splitIntRange(newLucene(rangeBounds), query->precisionStep, minBound, maxBound); + NumericUtils::splitLongRange(newLucene(rangeBounds), query->precisionStep, minBound, maxBound); + + break; + } + case 32: { + // lower + int32_t minBound = INT_MIN; + if (VariantUtils::typeOf(query->min)) { + minBound = VariantUtils::get(query->min); + } + if (!query->minInclusive && !VariantUtils::isNull(query->min)) { + if (minBound == INT_MAX) { break; } + ++minBound; + } - default: - // should never happen - boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); + // upper + int32_t maxBound = INT_MAX; + if (VariantUtils::typeOf(query->max)) { + maxBound = VariantUtils::get(query->max); + } + if (!query->maxInclusive && !VariantUtils::isNull(query->max)) { + if (maxBound == INT_MIN) { + break; + } + --maxBound; } - // seek to first term - next(); - } + NumericUtils::splitIntRange(newLucene(rangeBounds), query->precisionStep, minBound, maxBound); - NumericRangeTermEnum::~NumericRangeTermEnum() - { + break; } - double NumericRangeTermEnum::difference() - { - return 1.0; + default: + // should never happen + boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64")); } - bool NumericRangeTermEnum::endEnum() - { - boost::throw_exception(UnsupportedOperationException(L"not implemented")); - return false; - } + // seek to first term + next(); +} - void NumericRangeTermEnum::setEnum(const TermEnumPtr& actualEnum) - { - boost::throw_exception(UnsupportedOperationException(L"not implemented")); - } +NumericRangeTermEnum::~NumericRangeTermEnum() { +} - bool NumericRangeTermEnum::termCompare(const TermPtr& term) - { - return (term->field() == NumericRangeQueryPtr(_query)->field && term->text().compare(currentUpperBound) <= 0); - } +double NumericRangeTermEnum::difference() { + return 1.0; +} - bool NumericRangeTermEnum::next() - { - // if a current term exists, the actual enum is initialized: try change to next term, if no - // such term exists, fall-through - if (currentTerm) - { - BOOST_ASSERT(actualEnum); - if (actualEnum->next()) - { - currentTerm = actualEnum->term(); - if (termCompare(currentTerm)) - return true; - } - } +bool NumericRangeTermEnum::endEnum() { + boost::throw_exception(UnsupportedOperationException(L"not implemented")); + return false; +} - // if all above fails, we go forward to the next enum, if one is available - currentTerm.reset(); - while (rangeBounds.size() >= 2) - { - BOOST_ASSERT(rangeBounds.size() % 2 == 0); - // close the current enum and read next bounds - if (actualEnum) - { - actualEnum->close(); - actualEnum.reset(); - } - String lowerBound(rangeBounds.removeFirst()); - currentUpperBound = rangeBounds.removeFirst(); - // create a new enum - actualEnum = reader->terms(termTemplate->createTerm(lowerBound)); +void NumericRangeTermEnum::setEnum(const TermEnumPtr& actualEnum) { + boost::throw_exception(UnsupportedOperationException(L"not implemented")); +} + +bool NumericRangeTermEnum::termCompare(const TermPtr& term) { + return (term->field() == NumericRangeQueryPtr(_query)->field && term->text().compare(currentUpperBound) <= 0); +} + +bool NumericRangeTermEnum::next() { + // if a current term exists, the actual enum is initialized: try change to next term, if no + // such term exists, fall-through + if (currentTerm) { + BOOST_ASSERT(actualEnum); + if (actualEnum->next()) { currentTerm = actualEnum->term(); - if (currentTerm && termCompare(currentTerm)) + if (termCompare(currentTerm)) { return true; - // clear the current term for next iteration - currentTerm.reset(); + } } - - // no more sub-range enums available - BOOST_ASSERT(rangeBounds.empty() && !currentTerm); - return false; } - void NumericRangeTermEnum::close() - { - rangeBounds.clear(); - currentUpperBound.clear(); - FilteredTermEnum::close(); + // if all above fails, we go forward to the next enum, if one is available + currentTerm.reset(); + while (rangeBounds.size() >= 2) { + BOOST_ASSERT(rangeBounds.size() % 2 == 0); + // close the current enum and read next bounds + if (actualEnum) { + actualEnum->close(); + actualEnum.reset(); + } + String lowerBound(rangeBounds.removeFirst()); + currentUpperBound = rangeBounds.removeFirst(); + // create a new enum + actualEnum = reader->terms(termTemplate->createTerm(lowerBound)); + currentTerm = actualEnum->term(); + if (currentTerm && termCompare(currentTerm)) { + return true; + } + // clear the current term for next iteration + currentTerm.reset(); } - NumericLongRangeBuilder::NumericLongRangeBuilder(Collection rangeBounds) - { - this->rangeBounds = rangeBounds; - } + // no more sub-range enums available + BOOST_ASSERT(rangeBounds.empty() && !currentTerm); + return false; +} - NumericLongRangeBuilder::~NumericLongRangeBuilder() - { - } +void NumericRangeTermEnum::close() { + rangeBounds.clear(); + currentUpperBound.clear(); + FilteredTermEnum::close(); +} - void NumericLongRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) - { - rangeBounds.add(minPrefixCoded); - rangeBounds.add(maxPrefixCoded); - } +NumericLongRangeBuilder::NumericLongRangeBuilder(Collection rangeBounds) { + this->rangeBounds = rangeBounds; +} - NumericIntRangeBuilder::NumericIntRangeBuilder(Collection rangeBounds) - { - this->rangeBounds = rangeBounds; - } +NumericLongRangeBuilder::~NumericLongRangeBuilder() { +} - NumericIntRangeBuilder::~NumericIntRangeBuilder() - { - } +void NumericLongRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { + rangeBounds.add(minPrefixCoded); + rangeBounds.add(maxPrefixCoded); +} + +NumericIntRangeBuilder::NumericIntRangeBuilder(Collection rangeBounds) { + this->rangeBounds = rangeBounds; +} + +NumericIntRangeBuilder::~NumericIntRangeBuilder() { +} + +void NumericIntRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { + rangeBounds.add(minPrefixCoded); + rangeBounds.add(maxPrefixCoded); +} - void NumericIntRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) - { - rangeBounds.add(minPrefixCoded); - rangeBounds.add(maxPrefixCoded); - } } diff --git a/src/core/search/ParallelMultiSearcher.cpp b/src/core/search/ParallelMultiSearcher.cpp index c22e3231..f3bf4af0 100644 --- a/src/core/search/ParallelMultiSearcher.cpp +++ b/src/core/search/ParallelMultiSearcher.cpp @@ -15,87 +15,84 @@ #include "TopFieldDocs.h" #include "ThreadPool.h" -namespace Lucene -{ - ParallelMultiSearcher::ParallelMultiSearcher(Collection searchables) : MultiSearcher(searchables) - { +namespace Lucene { + +ParallelMultiSearcher::ParallelMultiSearcher(Collection searchables) : MultiSearcher(searchables) { +} + +ParallelMultiSearcher::~ParallelMultiSearcher() { +} + +int32_t ParallelMultiSearcher::docFreq(const TermPtr& term) { + ThreadPoolPtr threadPool(ThreadPool::getInstance()); + Collection searchThreads(Collection::newInstance(searchables.size())); + for (int32_t i = 0; i < searchables.size(); ++i) { + searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&Searchable::docFreq), searchables[i], term))); } + int32_t docFreq = 0; + for (int32_t i = 0; i < searchThreads.size(); ++i) { + docFreq += searchThreads[i]->get(); + } + return docFreq; +} - ParallelMultiSearcher::~ParallelMultiSearcher() - { +TopDocsPtr ParallelMultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { + HitQueuePtr hq(newLucene(n, false)); + SynchronizePtr lock(newInstance()); + ThreadPoolPtr threadPool(ThreadPool::getInstance()); + Collection searchThreads(Collection::newInstance(searchables.size())); + Collection multiSearcher(Collection::newInstance(searchables.size())); + for (int32_t i = 0; i < searchables.size(); ++i) { // search each searchable + multiSearcher[i] = newLucene(lock, searchables[i], weight, filter, n, hq, i, starts); + searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&MultiSearcherCallableNoSort::call), multiSearcher[i]))); } - int32_t ParallelMultiSearcher::docFreq(const TermPtr& term) - { - ThreadPoolPtr threadPool(ThreadPool::getInstance()); - Collection searchThreads(Collection::newInstance(searchables.size())); - for (int32_t i = 0; i < searchables.size(); ++i) - searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&Searchable::docFreq), searchables[i], term))); - int32_t docFreq = 0; - for (int32_t i = 0; i < searchThreads.size(); ++i) - docFreq += searchThreads[i]->get(); - return docFreq; + int32_t totalHits = 0; + double maxScore = -std::numeric_limits::infinity(); + + for (int32_t i = 0; i < searchThreads.size(); ++i) { + TopDocsPtr topDocs(searchThreads[i]->get()); + totalHits += topDocs->totalHits; + maxScore = std::max(maxScore, topDocs->maxScore); } - TopDocsPtr ParallelMultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) - { - HitQueuePtr hq(newLucene(n, false)); - SynchronizePtr lock(newInstance()); - ThreadPoolPtr threadPool(ThreadPool::getInstance()); - Collection searchThreads(Collection::newInstance(searchables.size())); - Collection multiSearcher(Collection::newInstance(searchables.size())); - for (int32_t i = 0; i < searchables.size(); ++i) // search each searchable - { - multiSearcher[i] = newLucene(lock, searchables[i], weight, filter, n, hq, i, starts); - searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&MultiSearcherCallableNoSort::call), multiSearcher[i]))); - } - - int32_t totalHits = 0; - double maxScore = -std::numeric_limits::infinity(); - - for (int32_t i = 0; i < searchThreads.size(); ++i) - { - TopDocsPtr topDocs(searchThreads[i]->get()); - totalHits += topDocs->totalHits; - maxScore = std::max(maxScore, topDocs->maxScore); - } - - Collection scoreDocs(Collection::newInstance(hq->size())); - for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array - scoreDocs[i] = hq->pop(); - - return newLucene(totalHits, scoreDocs, maxScore); + Collection scoreDocs(Collection::newInstance(hq->size())); + for (int32_t i = hq->size() - 1; i >= 0; --i) { // put docs in array + scoreDocs[i] = hq->pop(); } - TopFieldDocsPtr ParallelMultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) - { - if (!sort) - boost::throw_exception(NullPointerException(L"sort must not be null")); - FieldDocSortedHitQueuePtr hq(newLucene(n)); - SynchronizePtr lock(newInstance()); - ThreadPoolPtr threadPool(ThreadPool::getInstance()); - Collection searchThreads(Collection::newInstance(searchables.size())); - Collection multiSearcher(Collection::newInstance(searchables.size())); - for (int32_t i = 0; i < searchables.size(); ++i) // search each searchable - { - multiSearcher[i] = newLucene(lock, searchables[i], weight, filter, n, hq, sort, i, starts); - searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&MultiSearcherCallableWithSort::call), multiSearcher[i]))); - } - - int32_t totalHits = 0; - double maxScore = -std::numeric_limits::infinity(); - - for (int32_t i = 0; i < searchThreads.size(); ++i) - { - TopFieldDocsPtr topDocs(searchThreads[i]->get()); - totalHits += topDocs->totalHits; - maxScore = std::max(maxScore, topDocs->maxScore); - } - - Collection scoreDocs(Collection::newInstance(hq->size())); - for (int32_t i = hq->size() - 1; i >= 0; --i) // put docs in array - scoreDocs[i] = hq->pop(); - - return newLucene(totalHits, scoreDocs, hq->getFields(), maxScore); + return newLucene(totalHits, scoreDocs, maxScore); +} + +TopFieldDocsPtr ParallelMultiSearcher::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { + if (!sort) { + boost::throw_exception(NullPointerException(L"sort must not be null")); } + FieldDocSortedHitQueuePtr hq(newLucene(n)); + SynchronizePtr lock(newInstance()); + ThreadPoolPtr threadPool(ThreadPool::getInstance()); + Collection searchThreads(Collection::newInstance(searchables.size())); + Collection multiSearcher(Collection::newInstance(searchables.size())); + for (int32_t i = 0; i < searchables.size(); ++i) { // search each searchable + multiSearcher[i] = newLucene(lock, searchables[i], weight, filter, n, hq, sort, i, starts); + searchThreads[i] = threadPool->scheduleTask(boost::protect(boost::bind(boost::mem_fn(&MultiSearcherCallableWithSort::call), multiSearcher[i]))); + } + + int32_t totalHits = 0; + double maxScore = -std::numeric_limits::infinity(); + + for (int32_t i = 0; i < searchThreads.size(); ++i) { + TopFieldDocsPtr topDocs(searchThreads[i]->get()); + totalHits += topDocs->totalHits; + maxScore = std::max(maxScore, topDocs->maxScore); + } + + Collection scoreDocs(Collection::newInstance(hq->size())); + for (int32_t i = hq->size() - 1; i >= 0; --i) { // put docs in array + scoreDocs[i] = hq->pop(); + } + + return newLucene(totalHits, scoreDocs, hq->getFields(), maxScore); +} + } diff --git a/src/core/search/PhrasePositions.cpp b/src/core/search/PhrasePositions.cpp index c0eeb66f..6415f770 100644 --- a/src/core/search/PhrasePositions.cpp +++ b/src/core/search/PhrasePositions.cpp @@ -8,63 +8,55 @@ #include "PhrasePositions.h" #include "TermPositions.h" -namespace Lucene -{ - PhrasePositions::PhrasePositions(const TermPositionsPtr& t, int32_t o) - { - doc = 0; - position = 0; - count = 0; - repeats = false; +namespace Lucene { - tp = t; - offset = o; - } +PhrasePositions::PhrasePositions(const TermPositionsPtr& t, int32_t o) { + doc = 0; + position = 0; + count = 0; + repeats = false; - PhrasePositions::~PhrasePositions() - { - } + tp = t; + offset = o; +} - bool PhrasePositions::next() - { - if (!tp->next()) - { - tp->close(); // close stream - doc = INT_MAX; // sentinel value - return false; - } - doc = tp->doc(); - position = 0; - return true; - } +PhrasePositions::~PhrasePositions() { +} - bool PhrasePositions::skipTo(int32_t target) - { - if (!tp->skipTo(target)) - { - tp->close(); // close stream - doc = INT_MAX; // sentinel value - return false; - } - doc = tp->doc(); - position = 0; - return true; +bool PhrasePositions::next() { + if (!tp->next()) { + tp->close(); // close stream + doc = INT_MAX; // sentinel value + return false; } + doc = tp->doc(); + position = 0; + return true; +} - void PhrasePositions::firstPosition() - { - count = tp->freq(); // read first pos - nextPosition(); +bool PhrasePositions::skipTo(int32_t target) { + if (!tp->skipTo(target)) { + tp->close(); // close stream + doc = INT_MAX; // sentinel value + return false; } + doc = tp->doc(); + position = 0; + return true; +} + +void PhrasePositions::firstPosition() { + count = tp->freq(); // read first pos + nextPosition(); +} - bool PhrasePositions::nextPosition() - { - if (count-- > 0) // read subsequent pos's - { - position = tp->nextPosition() - offset; - return true; - } - else - return false; +bool PhrasePositions::nextPosition() { + if (count-- > 0) { // read subsequent pos's + position = tp->nextPosition() - offset; + return true; + } else { + return false; } } + +} diff --git a/src/core/search/PhraseQuery.cpp b/src/core/search/PhraseQuery.cpp index bad96735..d31c02a1 100644 --- a/src/core/search/PhraseQuery.cpp +++ b/src/core/search/PhraseQuery.cpp @@ -18,275 +18,264 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - PhraseQuery::PhraseQuery() - { - terms = Collection::newInstance(); - positions = Collection::newInstance(); - maxPosition = 0; - slop = 0; - } +namespace Lucene { - PhraseQuery::~PhraseQuery() - { - } +PhraseQuery::PhraseQuery() { + terms = Collection::newInstance(); + positions = Collection::newInstance(); + maxPosition = 0; + slop = 0; +} - void PhraseQuery::setSlop(int32_t slop) - { - this->slop = slop; - } +PhraseQuery::~PhraseQuery() { +} - int32_t PhraseQuery::getSlop() - { - return slop; - } +void PhraseQuery::setSlop(int32_t slop) { + this->slop = slop; +} - void PhraseQuery::add(const TermPtr& term) - { - int32_t position = 0; - if (!positions.empty()) - position = positions[positions.size() - 1] + 1; - add(term, position); +int32_t PhraseQuery::getSlop() { + return slop; +} + +void PhraseQuery::add(const TermPtr& term) { + int32_t position = 0; + if (!positions.empty()) { + position = positions[positions.size() - 1] + 1; } + add(term, position); +} - void PhraseQuery::add(const TermPtr& term, int32_t position) - { - if (terms.empty()) - field = term->field(); - else if (term->field() != field) - boost::throw_exception(IllegalArgumentException(L"All phrase terms must be in the same field: " + term->toString())); - - terms.add(term); - positions.add(position); - if (position > maxPosition) - maxPosition = position; +void PhraseQuery::add(const TermPtr& term, int32_t position) { + if (terms.empty()) { + field = term->field(); + } else if (term->field() != field) { + boost::throw_exception(IllegalArgumentException(L"All phrase terms must be in the same field: " + term->toString())); } - Collection PhraseQuery::getTerms() - { - return terms; + terms.add(term); + positions.add(position); + if (position > maxPosition) { + maxPosition = position; } +} - Collection PhraseQuery::getPositions() - { - return positions; +Collection PhraseQuery::getTerms() { + return terms; +} + +Collection PhraseQuery::getPositions() { + return positions; +} + +WeightPtr PhraseQuery::createWeight(const SearcherPtr& searcher) { + if (terms.size() == 1) { // optimize one-term case + QueryPtr termQuery(newLucene(terms[0])); + termQuery->setBoost(getBoost()); + return termQuery->createWeight(searcher); } + return newLucene(shared_from_this(), searcher); +} + +void PhraseQuery::extractTerms(SetTerm terms) { + terms.addAll(this->terms.begin(), this->terms.end()); +} - WeightPtr PhraseQuery::createWeight(const SearcherPtr& searcher) - { - if (terms.size() == 1) // optimize one-term case - { - QueryPtr termQuery(newLucene(terms[0])); - termQuery->setBoost(getBoost()); - return termQuery->createWeight(searcher); +String PhraseQuery::toString(const String& field) { + StringStream buffer; + if (this->field != field) { + buffer << this->field << L":"; + } + buffer << L"\""; + Collection pieces(Collection::newInstance(maxPosition + 1)); + for (int32_t i = 0; i < terms.size(); ++i) { + int32_t pos = positions[i]; + String s(pieces[pos]); + if (!s.empty()) { + s += L"|"; + } + s += terms[i]->text(); + pieces[pos] = s; + } + for (int32_t i = 0; i < pieces.size(); ++i) { + if (i > 0) { + buffer << L" "; } - return newLucene(shared_from_this(), searcher); + String s(pieces[i]); + buffer << (s.empty() ? L"?" : s); } + buffer << L"\""; - void PhraseQuery::extractTerms(SetTerm terms) - { - terms.addAll(this->terms.begin(), this->terms.end()); + if (slop != 0) { + buffer << L"~" << slop; } - String PhraseQuery::toString(const String& field) - { - StringStream buffer; - if (this->field != field) - buffer << this->field << L":"; - buffer << L"\""; - Collection pieces(Collection::newInstance(maxPosition + 1)); - for (int32_t i = 0; i < terms.size(); ++i) - { - int32_t pos = positions[i]; - String s(pieces[pos]); - if (!s.empty()) - s += L"|"; - s += terms[i]->text(); - pieces[pos] = s; - } - for (int32_t i = 0; i < pieces.size(); ++i) - { - if (i > 0) - buffer << L" "; - String s(pieces[i]); - buffer << (s.empty() ? L"?" : s); - } - buffer << L"\""; + buffer << boostString(); - if (slop != 0) - buffer << L"~" << slop; + return buffer.str(); +} - buffer << boostString(); +bool PhraseQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } - return buffer.str(); + PhraseQueryPtr otherPhraseQuery(boost::dynamic_pointer_cast(other)); + if (!otherPhraseQuery) { + return false; } - bool PhraseQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; + return (getBoost() == otherPhraseQuery->getBoost() && slop == otherPhraseQuery->slop && + terms.equals(otherPhraseQuery->terms, luceneEquals()) && positions.equals(otherPhraseQuery->positions)); +} - PhraseQueryPtr otherPhraseQuery(boost::dynamic_pointer_cast(other)); - if (!otherPhraseQuery) - return false; +int32_t PhraseQuery::hashCode() { + return MiscUtils::doubleToIntBits(getBoost()) ^ slop ^ + MiscUtils::hashCode(terms.begin(), terms.end(), MiscUtils::hashLucene) ^ + MiscUtils::hashCode(positions.begin(), positions.end(), MiscUtils::hashNumeric); +} - return (getBoost() == otherPhraseQuery->getBoost() && slop == otherPhraseQuery->slop && - terms.equals(otherPhraseQuery->terms, luceneEquals()) && positions.equals(otherPhraseQuery->positions)); - } +LuceneObjectPtr PhraseQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + PhraseQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); + cloneQuery->field = field; + cloneQuery->terms = terms; + cloneQuery->positions = positions; + cloneQuery->maxPosition = maxPosition; + cloneQuery->slop = slop; + return cloneQuery; +} - int32_t PhraseQuery::hashCode() - { - return MiscUtils::doubleToIntBits(getBoost()) ^ slop ^ - MiscUtils::hashCode(terms.begin(), terms.end(), MiscUtils::hashLucene) ^ - MiscUtils::hashCode(positions.begin(), positions.end(), MiscUtils::hashNumeric); - } +PhraseWeight::PhraseWeight(const PhraseQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = query->getSimilarity(searcher); + this->value = 0.0; + this->idf = 0.0; + this->queryNorm = 0.0; + this->queryWeight = 0.0; - LuceneObjectPtr PhraseQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - PhraseQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); - cloneQuery->field = field; - cloneQuery->terms = terms; - cloneQuery->positions = positions; - cloneQuery->maxPosition = maxPosition; - cloneQuery->slop = slop; - return cloneQuery; - } + this->idfExp = similarity->idfExplain(query->terms, searcher); + idf = idfExp->getIdf(); +} - PhraseWeight::PhraseWeight(const PhraseQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = query->getSimilarity(searcher); - this->value = 0.0; - this->idf = 0.0; - this->queryNorm = 0.0; - this->queryWeight = 0.0; - - this->idfExp = similarity->idfExplain(query->terms, searcher); - idf = idfExp->getIdf(); - } +PhraseWeight::~PhraseWeight() { +} - PhraseWeight::~PhraseWeight() - { - } +String PhraseWeight::toString() { + return L"weight(" + query->toString() + L")"; +} - String PhraseWeight::toString() - { - return L"weight(" + query->toString() + L")"; - } +QueryPtr PhraseWeight::getQuery() { + return query; +} - QueryPtr PhraseWeight::getQuery() - { - return query; - } +double PhraseWeight::getValue() { + return value; +} - double PhraseWeight::getValue() - { - return value; - } +double PhraseWeight::sumOfSquaredWeights() { + queryWeight = idf * getQuery()->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it +} - double PhraseWeight::sumOfSquaredWeights() - { - queryWeight = idf * getQuery()->getBoost(); // compute query weight - return queryWeight * queryWeight; // square it - } +void PhraseWeight::normalize(double norm) { + queryNorm = norm; + queryWeight *= queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document +} - void PhraseWeight::normalize(double norm) - { - queryNorm = norm; - queryWeight *= queryNorm; // normalize query weight - value = queryWeight * idf; // idf for document +ScorerPtr PhraseWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + if (query->terms.empty()) { // optimize zero-term case + return ScorerPtr(); } - ScorerPtr PhraseWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - if (query->terms.empty()) // optimize zero-term case + Collection tps(Collection::newInstance(query->terms.size())); + for (int32_t i = 0; i < tps.size(); ++i) { + TermPositionsPtr p(reader->termPositions(query->terms[i])); + if (!p) { return ScorerPtr(); - - Collection tps(Collection::newInstance(query->terms.size())); - for (int32_t i = 0; i < tps.size(); ++i) - { - TermPositionsPtr p(reader->termPositions(query->terms[i])); - if (!p) - return ScorerPtr(); - tps[i] = p; } + tps[i] = p; + } - if (query->slop == 0) // optimize exact case - return newLucene(shared_from_this(), tps, query->getPositions(), similarity, reader->norms(query->field)); - else - return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); + if (query->slop == 0) { // optimize exact case + return newLucene(shared_from_this(), tps, query->getPositions(), similarity, reader->norms(query->field)); + } else { + return newLucene(shared_from_this(), tps, query->getPositions(), similarity, query->slop, reader->norms(query->field)); } +} - ExplanationPtr PhraseWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - ExplanationPtr result(newLucene()); - result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - - StringStream docFreqsBuffer; - StringStream queryBuffer; - queryBuffer << L"\""; - docFreqsBuffer << idfExp->explain(); - for (Collection::iterator term = query->terms.begin(); term != query->terms.end(); ++term) - { - if (term != query->terms.begin()) - queryBuffer << L" "; - queryBuffer << (*term)->text(); +ExplanationPtr PhraseWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + ExplanationPtr result(newLucene()); + result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); + + StringStream docFreqsBuffer; + StringStream queryBuffer; + queryBuffer << L"\""; + docFreqsBuffer << idfExp->explain(); + for (Collection::iterator term = query->terms.begin(); term != query->terms.end(); ++term) { + if (term != query->terms.begin()) { + queryBuffer << L" "; } - queryBuffer << L"\""; - - ExplanationPtr idfExpl(newLucene(idf, L"idf(" + query->field + L":" + docFreqsBuffer.str() + L")")); + queryBuffer << (*term)->text(); + } + queryBuffer << L"\""; - // explain query weight - ExplanationPtr queryExpl(newLucene()); - queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); + ExplanationPtr idfExpl(newLucene(idf, L"idf(" + query->field + L":" + docFreqsBuffer.str() + L")")); - ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); - if (query->getBoost() != 1.0) - queryExpl->addDetail(boostExpl); - queryExpl->addDetail(idfExpl); + // explain query weight + ExplanationPtr queryExpl(newLucene()); + queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); - queryExpl->addDetail(queryNormExpl); + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); + if (query->getBoost() != 1.0) { + queryExpl->addDetail(boostExpl); + } + queryExpl->addDetail(idfExpl); - queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); - result->addDetail(queryExpl); + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); + queryExpl->addDetail(queryNormExpl); - // explain field weight - ExplanationPtr fieldExpl(newLucene()); - fieldExpl->setDescription(L"fieldWeight(" + query->field + L":" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); + queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); + result->addDetail(queryExpl); - PhraseScorerPtr phraseScorer(boost::dynamic_pointer_cast(scorer(reader, true, false))); - if (!phraseScorer) - return newLucene(0.0, L"no matching docs"); + // explain field weight + ExplanationPtr fieldExpl(newLucene()); + fieldExpl->setDescription(L"fieldWeight(" + query->field + L":" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - ExplanationPtr tfExplanation(newLucene()); - int32_t d = phraseScorer->advance(doc); - double phraseFreq = d == doc ? phraseScorer->currentFreq() : 0.0; - tfExplanation->setValue(similarity->tf(phraseFreq)); - tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); + PhraseScorerPtr phraseScorer(boost::dynamic_pointer_cast(scorer(reader, true, false))); + if (!phraseScorer) { + return newLucene(0.0, L"no matching docs"); + } - fieldExpl->addDetail(tfExplanation); - fieldExpl->addDetail(idfExpl); + ExplanationPtr tfExplanation(newLucene()); + int32_t d = phraseScorer->advance(doc); + double phraseFreq = d == doc ? phraseScorer->currentFreq() : 0.0; + tfExplanation->setValue(similarity->tf(phraseFreq)); + tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); - ExplanationPtr fieldNormExpl(newLucene()); - ByteArray fieldNorms(reader->norms(query->field)); - double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; - fieldNormExpl->setValue(fieldNorm); - fieldNormExpl->setDescription(L"fieldNorm(field=" + query->field + L", doc=" + StringUtils::toString(doc) + L")"); - fieldExpl->addDetail(fieldNormExpl); + fieldExpl->addDetail(tfExplanation); + fieldExpl->addDetail(idfExpl); - fieldExpl->setValue(tfExplanation->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); + ExplanationPtr fieldNormExpl(newLucene()); + ByteArray fieldNorms(reader->norms(query->field)); + double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; + fieldNormExpl->setValue(fieldNorm); + fieldNormExpl->setDescription(L"fieldNorm(field=" + query->field + L", doc=" + StringUtils::toString(doc) + L")"); + fieldExpl->addDetail(fieldNormExpl); - result->addDetail(fieldExpl); + fieldExpl->setValue(tfExplanation->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); - // combine them - result->setValue(queryExpl->getValue() * fieldExpl->getValue()); + result->addDetail(fieldExpl); - if (queryExpl->getValue() == 1.0) - return fieldExpl; + // combine them + result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - return result; + if (queryExpl->getValue() == 1.0) { + return fieldExpl; } + + return result; +} + } diff --git a/src/core/search/PhraseQueue.cpp b/src/core/search/PhraseQueue.cpp index c13079a2..16fff6e5 100644 --- a/src/core/search/PhraseQueue.cpp +++ b/src/core/search/PhraseQueue.cpp @@ -8,30 +8,26 @@ #include "PhraseQueue.h" #include "PhrasePositions.h" -namespace Lucene -{ - PhraseQueue::PhraseQueue(int32_t size) : PriorityQueue(size) - { - } +namespace Lucene { - PhraseQueue::~PhraseQueue() - { - } +PhraseQueue::PhraseQueue(int32_t size) : PriorityQueue(size) { +} - bool PhraseQueue::lessThan(const PhrasePositionsPtr& first, const PhrasePositionsPtr& second) - { - if (first->doc == second->doc) - { - if (first->position == second->position) - { - // same doc and pp.position, so decide by actual term positions. - // rely on: pp.position == tp.position - offset. - return first->offset < second->offset; - } - else - return first->position < second->position; +PhraseQueue::~PhraseQueue() { +} + +bool PhraseQueue::lessThan(const PhrasePositionsPtr& first, const PhrasePositionsPtr& second) { + if (first->doc == second->doc) { + if (first->position == second->position) { + // same doc and pp.position, so decide by actual term positions. + // rely on: pp.position == tp.position - offset. + return first->offset < second->offset; + } else { + return first->position < second->position; } - else - return first->doc < second->doc; + } else { + return first->doc < second->doc; } } + +} diff --git a/src/core/search/PhraseScorer.cpp b/src/core/search/PhraseScorer.cpp index 750e9182..5211e9e2 100644 --- a/src/core/search/PhraseScorer.cpp +++ b/src/core/search/PhraseScorer.cpp @@ -11,146 +11,138 @@ #include "Weight.h" #include "Similarity.h" -namespace Lucene -{ - PhraseScorer::PhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) - { - this->firstTime = true; - this->more = true; - this->freq = 0.0; - - this->norms = norms; - this->weight = weight; - this->value = weight->getValue(); - - // convert tps to a list of phrase positions. - // Note: phrase-position differs from term-position in that its position reflects the phrase offset: pp.pos = tp.pos - offset. - // This allows to easily identify a matching (exact) phrase when all PhrasePositions have exactly the same position. - for (int32_t i = 0; i < tps.size(); ++i) - { - PhrasePositionsPtr pp(newLucene(tps[i], offsets[i])); - if (last) // add next to end of list - last->_next = pp; - else - first = pp; - last = pp; +namespace Lucene { + +PhraseScorer::PhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) { + this->firstTime = true; + this->more = true; + this->freq = 0.0; + + this->norms = norms; + this->weight = weight; + this->value = weight->getValue(); + + // convert tps to a list of phrase positions. + // Note: phrase-position differs from term-position in that its position reflects the phrase offset: pp.pos = tp.pos - offset. + // This allows to easily identify a matching (exact) phrase when all PhrasePositions have exactly the same position. + for (int32_t i = 0; i < tps.size(); ++i) { + PhrasePositionsPtr pp(newLucene(tps[i], offsets[i])); + if (last) { // add next to end of list + last->_next = pp; + } else { + first = pp; } - - pq = newLucene(tps.size()); // construct empty pq - first->doc = -1; + last = pp; } - PhraseScorer::~PhraseScorer() - { - } + pq = newLucene(tps.size()); // construct empty pq + first->doc = -1; +} - int32_t PhraseScorer::docID() - { - return first->doc; - } +PhraseScorer::~PhraseScorer() { +} - int32_t PhraseScorer::nextDoc() - { - if (firstTime) - { - init(); - firstTime = false; - } - else if (more) - more = last->next(); // trigger further scanning - if (!doNext()) - first->doc = NO_MORE_DOCS; - return first->doc; +int32_t PhraseScorer::docID() { + return first->doc; +} + +int32_t PhraseScorer::nextDoc() { + if (firstTime) { + init(); + firstTime = false; + } else if (more) { + more = last->next(); // trigger further scanning + } + if (!doNext()) { + first->doc = NO_MORE_DOCS; } + return first->doc; +} - bool PhraseScorer::doNext() - { - while (more) - { - while (more && first->doc < last->doc) // find doc with all the terms - { - more = first->skipTo(last->doc); // skip first upto last and move it to the end - firstToLast(); - } +bool PhraseScorer::doNext() { + while (more) { + while (more && first->doc < last->doc) { // find doc with all the terms + more = first->skipTo(last->doc); // skip first upto last and move it to the end + firstToLast(); + } - if (more) - { - // found a doc with all of the terms - freq = phraseFreq(); // check for phrase - if (freq == 0.0) // no match - more = last->next(); // trigger further scanning - else - return true; + if (more) { + // found a doc with all of the terms + freq = phraseFreq(); // check for phrase + if (freq == 0.0) { // no match + more = last->next(); // trigger further scanning + } else { + return true; } } - return false; // no more matches } + return false; // no more matches +} - double PhraseScorer::score() - { - double raw = getSimilarity()->tf(freq) * value; // raw score - return !norms ? raw : raw * Similarity::decodeNorm(norms[first->doc]); // normalize - } +double PhraseScorer::score() { + double raw = getSimilarity()->tf(freq) * value; // raw score + return !norms ? raw : raw * Similarity::decodeNorm(norms[first->doc]); // normalize +} - int32_t PhraseScorer::advance(int32_t target) - { - firstTime = false; - for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) - more = pp->skipTo(target); - if (more) - sort(); // re-sort - if (!doNext()) - first->doc = NO_MORE_DOCS; - return first->doc; +int32_t PhraseScorer::advance(int32_t target) { + firstTime = false; + for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) { + more = pp->skipTo(target); } - - double PhraseScorer::currentFreq() - { - return freq; + if (more) { + sort(); // re-sort } + if (!doNext()) { + first->doc = NO_MORE_DOCS; + } + return first->doc; +} - void PhraseScorer::init() - { - for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) - more = pp->next(); - if (more) - sort(); +double PhraseScorer::currentFreq() { + return freq; +} + +void PhraseScorer::init() { + for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) { + more = pp->next(); } + if (more) { + sort(); + } +} - void PhraseScorer::sort() - { - pq->clear(); - for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) - pq->add(pp); - pqToList(); +void PhraseScorer::sort() { + pq->clear(); + for (PhrasePositionsPtr pp(first); more && pp; pp = pp->_next) { + pq->add(pp); } + pqToList(); +} - void PhraseScorer::pqToList() - { - last.reset(); - first.reset(); - while (pq->top()) - { - PhrasePositionsPtr pp(pq->pop()); - if (last) // add next to end of list - last->_next = pp; - else - first = pp; - last = pp; - pp->_next.reset(); +void PhraseScorer::pqToList() { + last.reset(); + first.reset(); + while (pq->top()) { + PhrasePositionsPtr pp(pq->pop()); + if (last) { // add next to end of list + last->_next = pp; + } else { + first = pp; } + last = pp; + pp->_next.reset(); } +} - void PhraseScorer::firstToLast() - { - last->_next = first; // move first to end of list - last = first; - first = first->_next; - last->_next.reset(); - } +void PhraseScorer::firstToLast() { + last->_next = first; // move first to end of list + last = first; + first = first->_next; + last->_next.reset(); +} + +String PhraseScorer::toString() { + return L"scorer(" + weight->toString() + L")"; +} - String PhraseScorer::toString() - { - return L"scorer(" + weight->toString() + L")"; - } } diff --git a/src/core/search/PositiveScoresOnlyCollector.cpp b/src/core/search/PositiveScoresOnlyCollector.cpp index cfbaca4d..b9adbb46 100644 --- a/src/core/search/PositiveScoresOnlyCollector.cpp +++ b/src/core/search/PositiveScoresOnlyCollector.cpp @@ -8,37 +8,33 @@ #include "PositiveScoresOnlyCollector.h" #include "ScoreCachingWrappingScorer.h" -namespace Lucene -{ - PositiveScoresOnlyCollector::PositiveScoresOnlyCollector(const CollectorPtr& collector) - { - this->collector = collector; - } +namespace Lucene { - PositiveScoresOnlyCollector::~PositiveScoresOnlyCollector() - { - } +PositiveScoresOnlyCollector::PositiveScoresOnlyCollector(const CollectorPtr& collector) { + this->collector = collector; +} - void PositiveScoresOnlyCollector::collect(int32_t doc) - { - if (scorer->score() > 0) - collector->collect(doc); - } +PositiveScoresOnlyCollector::~PositiveScoresOnlyCollector() { +} - void PositiveScoresOnlyCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - collector->setNextReader(reader, docBase); +void PositiveScoresOnlyCollector::collect(int32_t doc) { + if (scorer->score() > 0) { + collector->collect(doc); } +} - void PositiveScoresOnlyCollector::setScorer(const ScorerPtr& scorer) - { - // Set a ScoreCachingWrappingScorer in case the wrapped Collector will call score() also. - this->scorer = newLucene(scorer); - collector->setScorer(this->scorer); - } +void PositiveScoresOnlyCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + collector->setNextReader(reader, docBase); +} + +void PositiveScoresOnlyCollector::setScorer(const ScorerPtr& scorer) { + // Set a ScoreCachingWrappingScorer in case the wrapped Collector will call score() also. + this->scorer = newLucene(scorer); + collector->setScorer(this->scorer); +} + +bool PositiveScoresOnlyCollector::acceptsDocsOutOfOrder() { + return collector->acceptsDocsOutOfOrder(); +} - bool PositiveScoresOnlyCollector::acceptsDocsOutOfOrder() - { - return collector->acceptsDocsOutOfOrder(); - } } diff --git a/src/core/search/PrefixFilter.cpp b/src/core/search/PrefixFilter.cpp index dff66b4b..72a31ae4 100644 --- a/src/core/search/PrefixFilter.cpp +++ b/src/core/search/PrefixFilter.cpp @@ -9,25 +9,22 @@ #include "PrefixQuery.h" #include "Term.h" -namespace Lucene -{ - PrefixFilter::PrefixFilter(const TermPtr& prefix) : MultiTermQueryWrapperFilter(newLucene(prefix)) - { - } +namespace Lucene { - PrefixFilter::~PrefixFilter() - { - } +PrefixFilter::PrefixFilter(const TermPtr& prefix) : MultiTermQueryWrapperFilter(newLucene(prefix)) { +} + +PrefixFilter::~PrefixFilter() { +} - TermPtr PrefixFilter::getPrefix() - { - return boost::static_pointer_cast(query)->getPrefix(); - } +TermPtr PrefixFilter::getPrefix() { + return boost::static_pointer_cast(query)->getPrefix(); +} + +String PrefixFilter::toString() { + StringStream buffer; + buffer << L"PrefixFilter(" << getPrefix()->toString() << L")"; + return buffer.str(); +} - String PrefixFilter::toString() - { - StringStream buffer; - buffer << L"PrefixFilter(" << getPrefix()->toString() << L")"; - return buffer.str(); - } } diff --git a/src/core/search/PrefixQuery.cpp b/src/core/search/PrefixQuery.cpp index a4dad417..430b57e9 100644 --- a/src/core/search/PrefixQuery.cpp +++ b/src/core/search/PrefixQuery.cpp @@ -10,70 +10,68 @@ #include "Term.h" #include "MiscUtils.h" -namespace Lucene -{ - PrefixQuery::PrefixQuery(const TermPtr& prefix) - { - this->prefix = prefix; - } +namespace Lucene { - PrefixQuery::~PrefixQuery() - { - } +PrefixQuery::PrefixQuery(const TermPtr& prefix) { + this->prefix = prefix; +} - TermPtr PrefixQuery::getPrefix() - { - return prefix; - } +PrefixQuery::~PrefixQuery() { +} - FilteredTermEnumPtr PrefixQuery::getEnum(const IndexReaderPtr& reader) - { - return newLucene(reader, prefix); - } +TermPtr PrefixQuery::getPrefix() { + return prefix; +} - String PrefixQuery::toString(const String& field) - { - StringStream buffer; - if (prefix->field() != field) - buffer << prefix->field() << L":"; - buffer << prefix->text() << L"*" << boostString(); - return buffer.str(); - } +FilteredTermEnumPtr PrefixQuery::getEnum(const IndexReaderPtr& reader) { + return newLucene(reader, prefix); +} - LuceneObjectPtr PrefixQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(prefix)); - PrefixQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->prefix = prefix; - return cloneQuery; +String PrefixQuery::toString(const String& field) { + StringStream buffer; + if (prefix->field() != field) { + buffer << prefix->field() << L":"; } + buffer << prefix->text() << L"*" << boostString(); + return buffer.str(); +} - int32_t PrefixQuery::hashCode() - { - int32_t prime = 31; - int32_t result = MultiTermQuery::hashCode(); - result = prime * result + (prefix ? prefix->hashCode() : 0); - return result; - } +LuceneObjectPtr PrefixQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(prefix)); + PrefixQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->prefix = prefix; + return cloneQuery; +} - bool PrefixQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!MultiTermQuery::equals(other)) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - PrefixQueryPtr otherPrefixQuery(boost::dynamic_pointer_cast(other)); - if (!otherPrefixQuery) +int32_t PrefixQuery::hashCode() { + int32_t prime = 31; + int32_t result = MultiTermQuery::hashCode(); + result = prime * result + (prefix ? prefix->hashCode() : 0); + return result; +} + +bool PrefixQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!MultiTermQuery::equals(other)) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + PrefixQueryPtr otherPrefixQuery(boost::dynamic_pointer_cast(other)); + if (!otherPrefixQuery) { + return false; + } + if (!prefix) { + if (otherPrefixQuery->prefix) { return false; - if (!prefix) - { - if (otherPrefixQuery->prefix) - return false; } - else if (!prefix->equals(otherPrefixQuery->prefix)) - return false; - return true; + } else if (!prefix->equals(otherPrefixQuery->prefix)) { + return false; } + return true; +} + } diff --git a/src/core/search/PrefixTermEnum.cpp b/src/core/search/PrefixTermEnum.cpp index 9665ea05..fa599f3f 100644 --- a/src/core/search/PrefixTermEnum.cpp +++ b/src/core/search/PrefixTermEnum.cpp @@ -10,40 +10,36 @@ #include "IndexReader.h" #include "Term.h" -namespace Lucene -{ - PrefixTermEnum::PrefixTermEnum(const IndexReaderPtr& reader, const TermPtr& prefix) - { - this->_endEnum = false; - this->prefix = prefix; - - setEnum(reader->terms(newLucene(prefix->field(), prefix->text()))); - } +namespace Lucene { - PrefixTermEnum::~PrefixTermEnum() - { - } +PrefixTermEnum::PrefixTermEnum(const IndexReaderPtr& reader, const TermPtr& prefix) { + this->_endEnum = false; + this->prefix = prefix; - double PrefixTermEnum::difference() - { - return 1.0; - } + setEnum(reader->terms(newLucene(prefix->field(), prefix->text()))); +} - bool PrefixTermEnum::endEnum() - { - return _endEnum; - } +PrefixTermEnum::~PrefixTermEnum() { +} - TermPtr PrefixTermEnum::getPrefixTerm() - { - return prefix; - } +double PrefixTermEnum::difference() { + return 1.0; +} + +bool PrefixTermEnum::endEnum() { + return _endEnum; +} - bool PrefixTermEnum::termCompare(const TermPtr& term) - { - if (term->field() == prefix->field() && boost::starts_with(term->text(), prefix->text())) - return true; - _endEnum = true; - return false; +TermPtr PrefixTermEnum::getPrefixTerm() { + return prefix; +} + +bool PrefixTermEnum::termCompare(const TermPtr& term) { + if (term->field() == prefix->field() && boost::starts_with(term->text(), prefix->text())) { + return true; } + _endEnum = true; + return false; +} + } diff --git a/src/core/search/Query.cpp b/src/core/search/Query.cpp index 04fb7ea1..e9d27145 100644 --- a/src/core/search/Query.cpp +++ b/src/core/search/Query.cpp @@ -11,159 +11,151 @@ #include "Similarity.h" #include "MiscUtils.h" -namespace Lucene -{ - Query::Query() - { - boost = 1.0; - } +namespace Lucene { - Query::~Query() - { - } +Query::Query() { + boost = 1.0; +} - void Query::setBoost(double boost) - { - this->boost = boost; - } +Query::~Query() { +} - double Query::getBoost() - { - return boost; - } +void Query::setBoost(double boost) { + this->boost = boost; +} - String Query::toString(const String& field) - { - return L""; // override - } +double Query::getBoost() { + return boost; +} - String Query::toString() - { - return toString(L""); - } +String Query::toString(const String& field) { + return L""; // override +} - WeightPtr Query::createWeight(const SearcherPtr& searcher) - { - boost::throw_exception(UnsupportedOperationException()); - return WeightPtr(); - } +String Query::toString() { + return toString(L""); +} - WeightPtr Query::weight(const SearcherPtr& searcher) - { - QueryPtr query(searcher->rewrite(shared_from_this())); - WeightPtr weight(query->createWeight(searcher)); - double sum = weight->sumOfSquaredWeights(); - double norm = getSimilarity(searcher)->queryNorm(sum); - if (MiscUtils::isInfinite(norm) || MiscUtils::isNaN(norm)) - norm = 1.0; - weight->normalize(norm); - return weight; - } +WeightPtr Query::createWeight(const SearcherPtr& searcher) { + boost::throw_exception(UnsupportedOperationException()); + return WeightPtr(); +} - QueryPtr Query::rewrite(const IndexReaderPtr& reader) - { - return shared_from_this(); +WeightPtr Query::weight(const SearcherPtr& searcher) { + QueryPtr query(searcher->rewrite(shared_from_this())); + WeightPtr weight(query->createWeight(searcher)); + double sum = weight->sumOfSquaredWeights(); + double norm = getSimilarity(searcher)->queryNorm(sum); + if (MiscUtils::isInfinite(norm) || MiscUtils::isNaN(norm)) { + norm = 1.0; } + weight->normalize(norm); + return weight; +} + +QueryPtr Query::rewrite(const IndexReaderPtr& reader) { + return shared_from_this(); +} - QueryPtr Query::combine(Collection queries) - { - SetQuery uniques(SetQuery::newInstance()); - for (Collection::iterator query = queries.begin(); query != queries.end(); ++query) - { - Collection clauses; - BooleanQueryPtr bq(boost::dynamic_pointer_cast(*query)); - // check if we can split the query into clauses - bool splittable = bq.get() != NULL; - if (splittable) - { - splittable = bq->isCoordDisabled(); - clauses = bq->getClauses(); - for (Collection::iterator clause = clauses.begin(); splittable && clause != clauses.end(); ++clause) - splittable = ((*clause)->getOccur() == BooleanClause::SHOULD); +QueryPtr Query::combine(Collection queries) { + SetQuery uniques(SetQuery::newInstance()); + for (Collection::iterator query = queries.begin(); query != queries.end(); ++query) { + Collection clauses; + BooleanQueryPtr bq(boost::dynamic_pointer_cast(*query)); + // check if we can split the query into clauses + bool splittable = bq.get() != NULL; + if (splittable) { + splittable = bq->isCoordDisabled(); + clauses = bq->getClauses(); + for (Collection::iterator clause = clauses.begin(); splittable && clause != clauses.end(); ++clause) { + splittable = ((*clause)->getOccur() == BooleanClause::SHOULD); } - if (splittable) - { - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - uniques.add((*clause)->getQuery()); + } + if (splittable) { + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + uniques.add((*clause)->getQuery()); } - else - uniques.add(*query); + } else { + uniques.add(*query); } - // optimization: if we have just one query, just return it - if (uniques.size() == 1) - return *uniques.begin(); - BooleanQueryPtr result(newLucene(true)); - for (SetQuery::iterator query = uniques.begin(); query != uniques.end(); ++query) - result->add(*query, BooleanClause::SHOULD); - return result; } - - void Query::extractTerms(SetTerm terms) - { - // needs to be implemented by query subclasses - boost::throw_exception(UnsupportedOperationException()); + // optimization: if we have just one query, just return it + if (uniques.size() == 1) { + return *uniques.begin(); + } + BooleanQueryPtr result(newLucene(true)); + for (SetQuery::iterator query = uniques.begin(); query != uniques.end(); ++query) { + result->add(*query, BooleanClause::SHOULD); } + return result; +} - QueryPtr Query::mergeBooleanQueries(Collection queries) - { - SetBooleanClause allClauses(SetBooleanClause::newInstance()); - for (Collection::iterator booleanQuery = queries.begin(); booleanQuery != queries.end(); ++booleanQuery) - { - for (Collection::iterator clause = (*booleanQuery)->begin(); clause != (*booleanQuery)->end(); ++clause) - allClauses.add(*clause); - } +void Query::extractTerms(SetTerm terms) { + // needs to be implemented by query subclasses + boost::throw_exception(UnsupportedOperationException()); +} - bool coordDisabled = queries.empty() ? false : queries[0]->isCoordDisabled(); - BooleanQueryPtr result(newLucene(coordDisabled)); - for (SetBooleanClause::iterator clause2 = allClauses.begin(); clause2 != allClauses.end(); ++clause2) - result->add(*clause2); - return result; +QueryPtr Query::mergeBooleanQueries(Collection queries) { + SetBooleanClause allClauses(SetBooleanClause::newInstance()); + for (Collection::iterator booleanQuery = queries.begin(); booleanQuery != queries.end(); ++booleanQuery) { + for (Collection::iterator clause = (*booleanQuery)->begin(); clause != (*booleanQuery)->end(); ++clause) { + allClauses.add(*clause); + } } - SimilarityPtr Query::getSimilarity(const SearcherPtr& searcher) - { - return searcher->getSimilarity(); + bool coordDisabled = queries.empty() ? false : queries[0]->isCoordDisabled(); + BooleanQueryPtr result(newLucene(coordDisabled)); + for (SetBooleanClause::iterator clause2 = allClauses.begin(); clause2 != allClauses.end(); ++clause2) { + result->add(*clause2); } + return result; +} - LuceneObjectPtr Query::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); - QueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->boost = boost; - return cloneQuery; - } +SimilarityPtr Query::getSimilarity(const SearcherPtr& searcher) { + return searcher->getSimilarity(); +} - int32_t Query::hashCode() - { - int32_t prime = 31; - int32_t result = 1; - result = prime * result + MiscUtils::doubleToIntBits(boost); - return result; - } +LuceneObjectPtr Query::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = LuceneObject::clone(other ? other : newLucene()); + QueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->boost = boost; + return cloneQuery; +} + +int32_t Query::hashCode() { + int32_t prime = 31; + int32_t result = 1; + result = prime * result + MiscUtils::doubleToIntBits(boost); + return result; +} - bool Query::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - QueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - return (boost == otherQuery->boost); +bool Query::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!other) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } + QueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; + } + return (boost == otherQuery->boost); +} - String Query::boostString() - { - double boost = getBoost(); - if (boost == 1.0) - return L""; - StringStream boostString; - boostString.precision(1); - boostString.setf(std::ios::fixed); - boostString << L"^" << boost; - return boostString.str(); +String Query::boostString() { + double boost = getBoost(); + if (boost == 1.0) { + return L""; } + StringStream boostString; + boostString.precision(1); + boostString.setf(std::ios::fixed); + boostString << L"^" << boost; + return boostString.str(); +} + } diff --git a/src/core/search/QueryTermVector.cpp b/src/core/search/QueryTermVector.cpp index fb69f59c..763d6a1c 100644 --- a/src/core/search/QueryTermVector.cpp +++ b/src/core/search/QueryTermVector.cpp @@ -11,126 +11,108 @@ #include "StringReader.h" #include "TermAttribute.h" -namespace Lucene -{ - QueryTermVector::QueryTermVector(Collection queryTerms) - { - terms = Collection::newInstance(); - termFreqs = Collection::newInstance(); - processTerms(queryTerms); - } +namespace Lucene { + +QueryTermVector::QueryTermVector(Collection queryTerms) { + terms = Collection::newInstance(); + termFreqs = Collection::newInstance(); + processTerms(queryTerms); +} - QueryTermVector::QueryTermVector(const String& queryString, const AnalyzerPtr& analyzer) - { - terms = Collection::newInstance(); - termFreqs = Collection::newInstance(); - if (analyzer) - { - TokenStreamPtr stream(analyzer->tokenStream(L"", newLucene(queryString))); - if (stream) - { - Collection terms = Collection::newInstance(); - try - { - bool hasMoreTokens = false; - - stream->reset(); - TermAttributePtr termAtt(stream->addAttribute()); +QueryTermVector::QueryTermVector(const String& queryString, const AnalyzerPtr& analyzer) { + terms = Collection::newInstance(); + termFreqs = Collection::newInstance(); + if (analyzer) { + TokenStreamPtr stream(analyzer->tokenStream(L"", newLucene(queryString))); + if (stream) { + Collection terms = Collection::newInstance(); + try { + bool hasMoreTokens = false; + stream->reset(); + TermAttributePtr termAtt(stream->addAttribute()); + + hasMoreTokens = stream->incrementToken(); + while (hasMoreTokens) { + terms.add(termAtt->term()); hasMoreTokens = stream->incrementToken(); - while (hasMoreTokens) - { - terms.add(termAtt->term()); - hasMoreTokens = stream->incrementToken(); - } - processTerms(terms); - } - catch (IOException&) - { } + processTerms(terms); + } catch (IOException&) { } } } +} - QueryTermVector::~QueryTermVector() - { - } +QueryTermVector::~QueryTermVector() { +} - void QueryTermVector::processTerms(Collection queryTerms) - { - if (queryTerms) - { - std::sort(queryTerms.begin(), queryTerms.end()); - MapStringInt tmpSet(MapStringInt::newInstance()); - - // filter out duplicates - Collection tmpList(Collection::newInstance()); - Collection tmpFreqs(Collection::newInstance()); - int32_t j = 0; - for (int32_t i = 0; i < queryTerms.size(); ++i) - { - String term(queryTerms[i]); - MapStringInt::iterator position = tmpSet.find(term); - if (position == tmpSet.end()) - { - tmpSet.put(term, j++); - tmpList.add(term); - tmpFreqs.add(1); - } - else - { - int32_t freq = tmpFreqs[position->second]; - tmpFreqs[position->second] = freq + 1; - } +void QueryTermVector::processTerms(Collection queryTerms) { + if (queryTerms) { + std::sort(queryTerms.begin(), queryTerms.end()); + MapStringInt tmpSet(MapStringInt::newInstance()); + + // filter out duplicates + Collection tmpList(Collection::newInstance()); + Collection tmpFreqs(Collection::newInstance()); + int32_t j = 0; + for (int32_t i = 0; i < queryTerms.size(); ++i) { + String term(queryTerms[i]); + MapStringInt::iterator position = tmpSet.find(term); + if (position == tmpSet.end()) { + tmpSet.put(term, j++); + tmpList.add(term); + tmpFreqs.add(1); + } else { + int32_t freq = tmpFreqs[position->second]; + tmpFreqs[position->second] = freq + 1; } - terms = tmpList; - termFreqs = Collection::newInstance(tmpFreqs.size()); - int32_t i = 0; - for (Collection::iterator freq = tmpFreqs.begin(); freq != tmpFreqs.end(); ++freq) - termFreqs[i++] = *freq; + } + terms = tmpList; + termFreqs = Collection::newInstance(tmpFreqs.size()); + int32_t i = 0; + for (Collection::iterator freq = tmpFreqs.begin(); freq != tmpFreqs.end(); ++freq) { + termFreqs[i++] = *freq; } } +} - String QueryTermVector::toString() - { - StringStream buffer; - buffer << L"{"; - for (int32_t i = 0; i < terms.size(); ++i) - { - if (i > 0) - buffer << L", "; - buffer << terms[i] << L'/' << termFreqs[i]; +String QueryTermVector::toString() { + StringStream buffer; + buffer << L"{"; + for (int32_t i = 0; i < terms.size(); ++i) { + if (i > 0) { + buffer << L", "; } - buffer << L"}"; - return buffer.str(); + buffer << terms[i] << L'/' << termFreqs[i]; } + buffer << L"}"; + return buffer.str(); +} - int32_t QueryTermVector::size() - { - return terms.size(); - } +int32_t QueryTermVector::size() { + return terms.size(); +} - Collection QueryTermVector::getTerms() - { - return terms; - } +Collection QueryTermVector::getTerms() { + return terms; +} - Collection QueryTermVector::getTermFrequencies() - { - return termFreqs; - } +Collection QueryTermVector::getTermFrequencies() { + return termFreqs; +} - int32_t QueryTermVector::indexOf(const String& term) - { - Collection::iterator search = std::lower_bound(terms.begin(), terms.end(), term); - return (search == terms.end() || term < *search) ? -1 : std::distance(terms.begin(), search); - } +int32_t QueryTermVector::indexOf(const String& term) { + Collection::iterator search = std::lower_bound(terms.begin(), terms.end(), term); + return (search == terms.end() || term < *search) ? -1 : std::distance(terms.begin(), search); +} - Collection QueryTermVector::indexesOf(Collection terms, int32_t start, int32_t length) - { - Collection res(Collection::newInstance(length)); - for (int32_t i = 0; i < length; ++i) - res[i] = indexOf(terms[i]); - return res; +Collection QueryTermVector::indexesOf(Collection terms, int32_t start, int32_t length) { + Collection res(Collection::newInstance(length)); + for (int32_t i = 0; i < length; ++i) { + res[i] = indexOf(terms[i]); } + return res; +} + } diff --git a/src/core/search/QueryWrapperFilter.cpp b/src/core/search/QueryWrapperFilter.cpp index 9ed68565..ef717a5b 100644 --- a/src/core/search/QueryWrapperFilter.cpp +++ b/src/core/search/QueryWrapperFilter.cpp @@ -12,58 +12,50 @@ #include "Scorer.h" #include "IndexSearcher.h" -namespace Lucene -{ - QueryWrapperFilter::QueryWrapperFilter(const QueryPtr& query) - { - this->query = query; - } +namespace Lucene { - QueryWrapperFilter::~QueryWrapperFilter() - { - } +QueryWrapperFilter::QueryWrapperFilter(const QueryPtr& query) { + this->query = query; +} - DocIdSetPtr QueryWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) - { - WeightPtr weight(query->weight(newLucene(reader))); - return newLucene(reader, weight); - } +QueryWrapperFilter::~QueryWrapperFilter() { +} - String QueryWrapperFilter::toString() - { - return L"QueryWrapperFilter(" + query->toString() + L")"; - } +DocIdSetPtr QueryWrapperFilter::getDocIdSet(const IndexReaderPtr& reader) { + WeightPtr weight(query->weight(newLucene(reader))); + return newLucene(reader, weight); +} - bool QueryWrapperFilter::equals(const LuceneObjectPtr& other) - { - QueryWrapperFilterPtr otherQueryWrapperFilter(boost::dynamic_pointer_cast(other)); - if (!otherQueryWrapperFilter) - return false; - return this->query->equals(otherQueryWrapperFilter->query); - } +String QueryWrapperFilter::toString() { + return L"QueryWrapperFilter(" + query->toString() + L")"; +} - int32_t QueryWrapperFilter::hashCode() - { - return query->hashCode() ^ 0x923F64B9; +bool QueryWrapperFilter::equals(const LuceneObjectPtr& other) { + QueryWrapperFilterPtr otherQueryWrapperFilter(boost::dynamic_pointer_cast(other)); + if (!otherQueryWrapperFilter) { + return false; } + return this->query->equals(otherQueryWrapperFilter->query); +} - QueryWrapperFilterDocIdSet::QueryWrapperFilterDocIdSet(const IndexReaderPtr& reader, const WeightPtr& weight) - { - this->reader = reader; - this->weight = weight; - } +int32_t QueryWrapperFilter::hashCode() { + return query->hashCode() ^ 0x923F64B9; +} - QueryWrapperFilterDocIdSet::~QueryWrapperFilterDocIdSet() - { - } +QueryWrapperFilterDocIdSet::QueryWrapperFilterDocIdSet(const IndexReaderPtr& reader, const WeightPtr& weight) { + this->reader = reader; + this->weight = weight; +} - DocIdSetIteratorPtr QueryWrapperFilterDocIdSet::iterator() - { - return weight->scorer(reader, true, false); - } +QueryWrapperFilterDocIdSet::~QueryWrapperFilterDocIdSet() { +} + +DocIdSetIteratorPtr QueryWrapperFilterDocIdSet::iterator() { + return weight->scorer(reader, true, false); +} + +bool QueryWrapperFilterDocIdSet::isCacheable() { + return false; +} - bool QueryWrapperFilterDocIdSet::isCacheable() - { - return false; - } } diff --git a/src/core/search/ReqExclScorer.cpp b/src/core/search/ReqExclScorer.cpp index 48696f91..04a2034e 100644 --- a/src/core/search/ReqExclScorer.cpp +++ b/src/core/search/ReqExclScorer.cpp @@ -7,89 +7,78 @@ #include "LuceneInc.h" #include "ReqExclScorer.h" -namespace Lucene -{ - ReqExclScorer::ReqExclScorer(const ScorerPtr& reqScorer, const DocIdSetIteratorPtr& exclDisi) : Scorer(SimilarityPtr()) // No similarity used. - { - this->reqScorer = reqScorer; - this->exclDisi = exclDisi; - this->doc = -1; - } +namespace Lucene { - ReqExclScorer::~ReqExclScorer() - { - } +ReqExclScorer::ReqExclScorer(const ScorerPtr& reqScorer, const DocIdSetIteratorPtr& exclDisi) : Scorer(SimilarityPtr()) { // No similarity used. + this->reqScorer = reqScorer; + this->exclDisi = exclDisi; + this->doc = -1; +} - int32_t ReqExclScorer::nextDoc() - { - if (!reqScorer) - return doc; - doc = reqScorer->nextDoc(); - if (doc == NO_MORE_DOCS) - { - reqScorer.reset(); // exhausted, nothing left - return doc; - } - if (!exclDisi) - return doc; - doc = toNonExcluded(); +ReqExclScorer::~ReqExclScorer() { +} + +int32_t ReqExclScorer::nextDoc() { + if (!reqScorer) { + return doc; + } + doc = reqScorer->nextDoc(); + if (doc == NO_MORE_DOCS) { + reqScorer.reset(); // exhausted, nothing left + return doc; + } + if (!exclDisi) { return doc; } + doc = toNonExcluded(); + return doc; +} - int32_t ReqExclScorer::toNonExcluded() - { - int32_t exclDoc = exclDisi->docID(); - int32_t reqDoc = reqScorer->docID(); // may be excluded - do - { - if (reqDoc < exclDoc) - return reqDoc; // reqScorer advanced to before exclScorer, ie. not excluded - else if (reqDoc > exclDoc) - { - exclDoc = exclDisi->advance(reqDoc); - if (exclDoc == NO_MORE_DOCS) - { - exclDisi.reset(); // exhausted, no more exclusions - return reqDoc; - } - if (exclDoc > reqDoc) - return reqDoc; // not excluded +int32_t ReqExclScorer::toNonExcluded() { + int32_t exclDoc = exclDisi->docID(); + int32_t reqDoc = reqScorer->docID(); // may be excluded + do { + if (reqDoc < exclDoc) { + return reqDoc; // reqScorer advanced to before exclScorer, ie. not excluded + } else if (reqDoc > exclDoc) { + exclDoc = exclDisi->advance(reqDoc); + if (exclDoc == NO_MORE_DOCS) { + exclDisi.reset(); // exhausted, no more exclusions + return reqDoc; + } + if (exclDoc > reqDoc) { + return reqDoc; // not excluded } } - while ((reqDoc = reqScorer->nextDoc()) != NO_MORE_DOCS); - reqScorer.reset(); // exhausted, nothing left - return NO_MORE_DOCS; - } + } while ((reqDoc = reqScorer->nextDoc()) != NO_MORE_DOCS); + reqScorer.reset(); // exhausted, nothing left + return NO_MORE_DOCS; +} + +int32_t ReqExclScorer::docID() { + return doc; +} - int32_t ReqExclScorer::docID() - { +double ReqExclScorer::score() { + return reqScorer->score(); // reqScorer may be null when next() or skipTo() already return false +} + +int32_t ReqExclScorer::advance(int32_t target) { + if (!reqScorer) { + doc = NO_MORE_DOCS; return doc; } - - double ReqExclScorer::score() - { - return reqScorer->score(); // reqScorer may be null when next() or skipTo() already return false + if (!exclDisi) { + doc = reqScorer->advance(target); + return doc; } - - int32_t ReqExclScorer::advance(int32_t target) - { - if (!reqScorer) - { - doc = NO_MORE_DOCS; - return doc; - } - if (!exclDisi) - { - doc = reqScorer->advance(target); - return doc; - } - if (reqScorer->advance(target) == NO_MORE_DOCS) - { - reqScorer.reset(); - doc = NO_MORE_DOCS; - return doc; - } - doc = toNonExcluded(); + if (reqScorer->advance(target) == NO_MORE_DOCS) { + reqScorer.reset(); + doc = NO_MORE_DOCS; return doc; } + doc = toNonExcluded(); + return doc; +} + } diff --git a/src/core/search/ReqOptSumScorer.cpp b/src/core/search/ReqOptSumScorer.cpp index b51b1bca..fb5c0a01 100644 --- a/src/core/search/ReqOptSumScorer.cpp +++ b/src/core/search/ReqOptSumScorer.cpp @@ -7,47 +7,42 @@ #include "LuceneInc.h" #include "ReqOptSumScorer.h" -namespace Lucene -{ - ReqOptSumScorer::ReqOptSumScorer(const ScorerPtr& reqScorer, const ScorerPtr& optScorer) : Scorer(SimilarityPtr()) // No similarity used. - { - this->reqScorer = reqScorer; - this->optScorer = optScorer; - } +namespace Lucene { - ReqOptSumScorer::~ReqOptSumScorer() - { - } +ReqOptSumScorer::ReqOptSumScorer(const ScorerPtr& reqScorer, const ScorerPtr& optScorer) : Scorer(SimilarityPtr()) { // No similarity used. + this->reqScorer = reqScorer; + this->optScorer = optScorer; +} - int32_t ReqOptSumScorer::nextDoc() - { - return reqScorer->nextDoc(); - } +ReqOptSumScorer::~ReqOptSumScorer() { +} - int32_t ReqOptSumScorer::advance(int32_t target) - { - return reqScorer->advance(target); - } +int32_t ReqOptSumScorer::nextDoc() { + return reqScorer->nextDoc(); +} - int32_t ReqOptSumScorer::docID() - { - return reqScorer->docID(); +int32_t ReqOptSumScorer::advance(int32_t target) { + return reqScorer->advance(target); +} + +int32_t ReqOptSumScorer::docID() { + return reqScorer->docID(); +} + +double ReqOptSumScorer::score() { + int32_t curDoc = reqScorer->docID(); + double reqScore = reqScorer->score(); + if (!optScorer) { + return reqScore; } - double ReqOptSumScorer::score() - { - int32_t curDoc = reqScorer->docID(); - double reqScore = reqScorer->score(); - if (!optScorer) - return reqScore; - - int32_t optScorerDoc = optScorer->docID(); - if (optScorerDoc < curDoc && (optScorerDoc = optScorer->advance(curDoc)) == NO_MORE_DOCS) - { - optScorer.reset(); - return reqScore; - } - - return optScorerDoc == curDoc ? reqScore + optScorer->score() : reqScore; + int32_t optScorerDoc = optScorer->docID(); + if (optScorerDoc < curDoc && (optScorerDoc = optScorer->advance(curDoc)) == NO_MORE_DOCS) { + optScorer.reset(); + return reqScore; } + + return optScorerDoc == curDoc ? reqScore + optScorer->score() : reqScore; +} + } diff --git a/src/core/search/ScoreCachingWrappingScorer.cpp b/src/core/search/ScoreCachingWrappingScorer.cpp index 34b726c5..a0d4dc2e 100644 --- a/src/core/search/ScoreCachingWrappingScorer.cpp +++ b/src/core/search/ScoreCachingWrappingScorer.cpp @@ -7,58 +7,49 @@ #include "LuceneInc.h" #include "ScoreCachingWrappingScorer.h" -namespace Lucene -{ - ScoreCachingWrappingScorer::ScoreCachingWrappingScorer(const ScorerPtr& scorer) : Scorer(scorer->getSimilarity()) - { - this->curDoc = -1; - this->curScore = 0.0; - this->_scorer = scorer; - } +namespace Lucene { - ScoreCachingWrappingScorer::~ScoreCachingWrappingScorer() - { - } +ScoreCachingWrappingScorer::ScoreCachingWrappingScorer(const ScorerPtr& scorer) : Scorer(scorer->getSimilarity()) { + this->curDoc = -1; + this->curScore = 0.0; + this->_scorer = scorer; +} - bool ScoreCachingWrappingScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) - { - return ScorerPtr(_scorer)->score(collector, max, firstDocID); - } +ScoreCachingWrappingScorer::~ScoreCachingWrappingScorer() { +} - SimilarityPtr ScoreCachingWrappingScorer::getSimilarity() - { - return ScorerPtr(_scorer)->getSimilarity(); - } +bool ScoreCachingWrappingScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { + return ScorerPtr(_scorer)->score(collector, max, firstDocID); +} - double ScoreCachingWrappingScorer::score() - { - ScorerPtr scorer(_scorer); - int32_t doc = scorer->docID(); - if (doc != curDoc) - { - curScore = scorer->score(); - curDoc = doc; - } - return curScore; - } +SimilarityPtr ScoreCachingWrappingScorer::getSimilarity() { + return ScorerPtr(_scorer)->getSimilarity(); +} - int32_t ScoreCachingWrappingScorer::docID() - { - return ScorerPtr(_scorer)->docID(); +double ScoreCachingWrappingScorer::score() { + ScorerPtr scorer(_scorer); + int32_t doc = scorer->docID(); + if (doc != curDoc) { + curScore = scorer->score(); + curDoc = doc; } + return curScore; +} - int32_t ScoreCachingWrappingScorer::nextDoc() - { - return ScorerPtr(_scorer)->nextDoc(); - } +int32_t ScoreCachingWrappingScorer::docID() { + return ScorerPtr(_scorer)->docID(); +} - void ScoreCachingWrappingScorer::score(const CollectorPtr& collector) - { - ScorerPtr(_scorer)->score(collector); - } +int32_t ScoreCachingWrappingScorer::nextDoc() { + return ScorerPtr(_scorer)->nextDoc(); +} + +void ScoreCachingWrappingScorer::score(const CollectorPtr& collector) { + ScorerPtr(_scorer)->score(collector); +} + +int32_t ScoreCachingWrappingScorer::advance(int32_t target) { + return ScorerPtr(_scorer)->advance(target); +} - int32_t ScoreCachingWrappingScorer::advance(int32_t target) - { - return ScorerPtr(_scorer)->advance(target); - } } diff --git a/src/core/search/ScoreDoc.cpp b/src/core/search/ScoreDoc.cpp index c461bd3d..ba19a7cd 100644 --- a/src/core/search/ScoreDoc.cpp +++ b/src/core/search/ScoreDoc.cpp @@ -7,22 +7,20 @@ #include "LuceneInc.h" #include "ScoreDoc.h" -namespace Lucene -{ - ScoreDoc::ScoreDoc(int32_t doc, double score) - { - this->doc = doc; - this->score = score; - } +namespace Lucene { - ScoreDoc::~ScoreDoc() - { - } +ScoreDoc::ScoreDoc(int32_t doc, double score) { + this->doc = doc; + this->score = score; +} + +ScoreDoc::~ScoreDoc() { +} + +String ScoreDoc::toString() { + StringStream buffer; + buffer << L"doc=" << doc << L" score=" << score; + return buffer.str(); +} - String ScoreDoc::toString() - { - StringStream buffer; - buffer << L"doc=" << doc << L" score=" << score; - return buffer.str(); - } } diff --git a/src/core/search/Scorer.cpp b/src/core/search/Scorer.cpp index b2780a8e..db649a95 100644 --- a/src/core/search/Scorer.cpp +++ b/src/core/search/Scorer.cpp @@ -8,39 +8,35 @@ #include "Scorer.h" #include "Collector.h" -namespace Lucene -{ - Scorer::Scorer(const SimilarityPtr& similarity) - { - this->similarity = similarity; - } +namespace Lucene { - Scorer::~Scorer() - { - } +Scorer::Scorer(const SimilarityPtr& similarity) { + this->similarity = similarity; +} - SimilarityPtr Scorer::getSimilarity() - { - return similarity; - } +Scorer::~Scorer() { +} - void Scorer::score(const CollectorPtr& collector) - { - collector->setScorer(shared_from_this()); - int32_t doc; - while ((doc = nextDoc()) != NO_MORE_DOCS) - collector->collect(doc); +SimilarityPtr Scorer::getSimilarity() { + return similarity; +} + +void Scorer::score(const CollectorPtr& collector) { + collector->setScorer(shared_from_this()); + int32_t doc; + while ((doc = nextDoc()) != NO_MORE_DOCS) { + collector->collect(doc); } +} - bool Scorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) - { - collector->setScorer(shared_from_this()); - int32_t doc = firstDocID; - while (doc < max) - { - collector->collect(doc); - doc = nextDoc(); - } - return (doc != NO_MORE_DOCS); +bool Scorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { + collector->setScorer(shared_from_this()); + int32_t doc = firstDocID; + while (doc < max) { + collector->collect(doc); + doc = nextDoc(); } + return (doc != NO_MORE_DOCS); +} + } diff --git a/src/core/search/Searchable.cpp b/src/core/search/Searchable.cpp index f6fffc0e..a62a45d6 100644 --- a/src/core/search/Searchable.cpp +++ b/src/core/search/Searchable.cpp @@ -7,71 +7,61 @@ #include "LuceneInc.h" #include "Searchable.h" -namespace Lucene -{ - void Searchable::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) - { - BOOST_ASSERT(false); - // override - } +namespace Lucene { - void Searchable::close() - { - BOOST_ASSERT(false); - // override - } +void Searchable::search(const WeightPtr& weight, const FilterPtr& filter, const CollectorPtr& collector) { + BOOST_ASSERT(false); + // override +} - int32_t Searchable::docFreq(const TermPtr& term) - { - BOOST_ASSERT(false); - return 0; // override - } +void Searchable::close() { + BOOST_ASSERT(false); + // override +} - Collection Searchable::docFreqs(Collection terms) - { - BOOST_ASSERT(false); - return Collection(); // override - } +int32_t Searchable::docFreq(const TermPtr& term) { + BOOST_ASSERT(false); + return 0; // override +} - int32_t Searchable::maxDoc() - { - BOOST_ASSERT(false); - return 0; // override - } +Collection Searchable::docFreqs(Collection terms) { + BOOST_ASSERT(false); + return Collection(); // override +} - TopDocsPtr Searchable::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) - { - BOOST_ASSERT(false); - return TopDocsPtr(); // override - } +int32_t Searchable::maxDoc() { + BOOST_ASSERT(false); + return 0; // override +} - DocumentPtr Searchable::doc(int32_t n) - { - BOOST_ASSERT(false); - return DocumentPtr(); // override - } +TopDocsPtr Searchable::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n) { + BOOST_ASSERT(false); + return TopDocsPtr(); // override +} - DocumentPtr Searchable::doc(int32_t n, const FieldSelectorPtr& fieldSelector) - { - BOOST_ASSERT(false); - return DocumentPtr(); // override - } +DocumentPtr Searchable::doc(int32_t n) { + BOOST_ASSERT(false); + return DocumentPtr(); // override +} - QueryPtr Searchable::rewrite(const QueryPtr& query) - { - BOOST_ASSERT(false); - return QueryPtr(); // override - } +DocumentPtr Searchable::doc(int32_t n, const FieldSelectorPtr& fieldSelector) { + BOOST_ASSERT(false); + return DocumentPtr(); // override +} + +QueryPtr Searchable::rewrite(const QueryPtr& query) { + BOOST_ASSERT(false); + return QueryPtr(); // override +} - ExplanationPtr Searchable::explain(const WeightPtr& weight, int32_t doc) - { - BOOST_ASSERT(false); - return ExplanationPtr(); // override - } +ExplanationPtr Searchable::explain(const WeightPtr& weight, int32_t doc) { + BOOST_ASSERT(false); + return ExplanationPtr(); // override +} + +TopFieldDocsPtr Searchable::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) { + BOOST_ASSERT(false); + return TopFieldDocsPtr(); // override +} - TopFieldDocsPtr Searchable::search(const WeightPtr& weight, const FilterPtr& filter, int32_t n, const SortPtr& sort) - { - BOOST_ASSERT(false); - return TopFieldDocsPtr(); // override - } } diff --git a/src/core/search/Searcher.cpp b/src/core/search/Searcher.cpp index 3d84b806..71c89050 100644 --- a/src/core/search/Searcher.cpp +++ b/src/core/search/Searcher.cpp @@ -10,67 +10,57 @@ #include "Query.h" #include "Collector.h" -namespace Lucene -{ - Searcher::Searcher() - { - similarity = Similarity::getDefault(); - } +namespace Lucene { - Searcher::~Searcher() - { - } +Searcher::Searcher() { + similarity = Similarity::getDefault(); +} - TopFieldDocsPtr Searcher::search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort) - { - return search(createWeight(query), filter, n, sort); - } +Searcher::~Searcher() { +} - void Searcher::search(const QueryPtr& query, const CollectorPtr& results) - { - search(createWeight(query), FilterPtr(), results); - } +TopFieldDocsPtr Searcher::search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort) { + return search(createWeight(query), filter, n, sort); +} - void Searcher::search(const QueryPtr& query, const FilterPtr& filter, const CollectorPtr& results) - { - search(createWeight(query), filter, results); - } +void Searcher::search(const QueryPtr& query, const CollectorPtr& results) { + search(createWeight(query), FilterPtr(), results); +} - TopDocsPtr Searcher::search(const QueryPtr& query, const FilterPtr& filter, int32_t n) - { - return search(createWeight(query), filter, n); - } +void Searcher::search(const QueryPtr& query, const FilterPtr& filter, const CollectorPtr& results) { + search(createWeight(query), filter, results); +} - TopDocsPtr Searcher::search(const QueryPtr& query, int32_t n) - { - return search(query, FilterPtr(), n); - } +TopDocsPtr Searcher::search(const QueryPtr& query, const FilterPtr& filter, int32_t n) { + return search(createWeight(query), filter, n); +} - ExplanationPtr Searcher::explain(const QueryPtr& query, int32_t doc) - { - return explain(createWeight(query), doc); - } +TopDocsPtr Searcher::search(const QueryPtr& query, int32_t n) { + return search(query, FilterPtr(), n); +} - void Searcher::setSimilarity(const SimilarityPtr& similarity) - { - this->similarity = similarity; - } +ExplanationPtr Searcher::explain(const QueryPtr& query, int32_t doc) { + return explain(createWeight(query), doc); +} - SimilarityPtr Searcher::getSimilarity() - { - return this->similarity; - } +void Searcher::setSimilarity(const SimilarityPtr& similarity) { + this->similarity = similarity; +} - WeightPtr Searcher::createWeight(const QueryPtr& query) - { - return query->weight(shared_from_this()); - } +SimilarityPtr Searcher::getSimilarity() { + return this->similarity; +} + +WeightPtr Searcher::createWeight(const QueryPtr& query) { + return query->weight(shared_from_this()); +} - Collection Searcher::docFreqs(Collection terms) - { - Collection result(Collection::newInstance(terms.size())); - for (int32_t i = 0; i < terms.size(); ++i) - result[i] = docFreq(terms[i]); - return result; +Collection Searcher::docFreqs(Collection terms) { + Collection result(Collection::newInstance(terms.size())); + for (int32_t i = 0; i < terms.size(); ++i) { + result[i] = docFreq(terms[i]); } + return result; +} + } diff --git a/src/core/search/Similarity.cpp b/src/core/search/Similarity.cpp index 96d1fde1..302f3fb8 100644 --- a/src/core/search/Similarity.cpp +++ b/src/core/search/Similarity.cpp @@ -14,117 +14,99 @@ #include "SmallDouble.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t Similarity::NO_DOC_ID_PROVIDED = -1; +namespace Lucene { - Similarity::Similarity() - { - } +const int32_t Similarity::NO_DOC_ID_PROVIDED = -1; - Similarity::~Similarity() - { - } +Similarity::Similarity() { +} - SimilarityPtr Similarity::getDefault() - { - static SimilarityPtr defaultImpl; - if (!defaultImpl) - { - defaultImpl = newLucene(); - CycleCheck::addStatic(defaultImpl); - } - return defaultImpl; +Similarity::~Similarity() { +} + +SimilarityPtr Similarity::getDefault() { + static SimilarityPtr defaultImpl; + if (!defaultImpl) { + defaultImpl = newLucene(); + CycleCheck::addStatic(defaultImpl); } + return defaultImpl; +} - const Collection Similarity::NORM_TABLE() - { - static Collection _NORM_TABLE; - if (!_NORM_TABLE) - { - _NORM_TABLE = Collection::newInstance(256); - for (int32_t i = 0; i < 256; ++i) - _NORM_TABLE[i] = SmallDouble::byteToDouble((uint8_t)i); +const Collection Similarity::NORM_TABLE() { + static Collection _NORM_TABLE; + if (!_NORM_TABLE) { + _NORM_TABLE = Collection::newInstance(256); + for (int32_t i = 0; i < 256; ++i) { + _NORM_TABLE[i] = SmallDouble::byteToDouble((uint8_t)i); } - return _NORM_TABLE; } + return _NORM_TABLE; +} - double Similarity::decodeNorm(uint8_t b) - { - return NORM_TABLE()[b & 0xff]; // & 0xff maps negative bytes to positive above 127 - } +double Similarity::decodeNorm(uint8_t b) { + return NORM_TABLE()[b & 0xff]; // & 0xff maps negative bytes to positive above 127 +} - const Collection Similarity::getNormDecoder() - { - return NORM_TABLE(); - } +const Collection Similarity::getNormDecoder() { + return NORM_TABLE(); +} - double Similarity::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) - { - return (double)(state->getBoost() * lengthNorm(fieldName, state->getLength())); - } +double Similarity::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) { + return (double)(state->getBoost() * lengthNorm(fieldName, state->getLength())); +} - uint8_t Similarity::encodeNorm(double f) - { - return SmallDouble::doubleToByte(f); - } +uint8_t Similarity::encodeNorm(double f) { + return SmallDouble::doubleToByte(f); +} - double Similarity::tf(int32_t freq) - { - return tf((double)freq); - } +double Similarity::tf(int32_t freq) { + return tf((double)freq); +} - IDFExplanationPtr Similarity::idfExplain(const TermPtr& term, const SearcherPtr& searcher) - { - int32_t df = searcher->docFreq(term); - int32_t max = searcher->maxDoc(); - double _idf = idf(df, max); - return newLucene(df, max, _idf); - } +IDFExplanationPtr Similarity::idfExplain(const TermPtr& term, const SearcherPtr& searcher) { + int32_t df = searcher->docFreq(term); + int32_t max = searcher->maxDoc(); + double _idf = idf(df, max); + return newLucene(df, max, _idf); +} - IDFExplanationPtr Similarity::idfExplain(Collection terms, const SearcherPtr& searcher) - { - int32_t max = searcher->maxDoc(); - double _idf = 0.0; - String exp; - for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) - { - int32_t df = searcher->docFreq(*term); - _idf += idf(df, max); - exp += L" " + (*term)->text() + L"=" + StringUtils::toString(df); - } - return newLucene(exp, _idf); +IDFExplanationPtr Similarity::idfExplain(Collection terms, const SearcherPtr& searcher) { + int32_t max = searcher->maxDoc(); + double _idf = 0.0; + String exp; + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) { + int32_t df = searcher->docFreq(*term); + _idf += idf(df, max); + exp += L" " + (*term)->text() + L"=" + StringUtils::toString(df); } + return newLucene(exp, _idf); +} - double Similarity::scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) - { - return 1.0; - } +double Similarity::scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) { + return 1.0; +} - SimilarityIDFExplanation::SimilarityIDFExplanation(int32_t df, int32_t max, double idf) - { - this->df = df; - this->max = max; - this->idf = idf; - } +SimilarityIDFExplanation::SimilarityIDFExplanation(int32_t df, int32_t max, double idf) { + this->df = df; + this->max = max; + this->idf = idf; +} - SimilarityIDFExplanation::SimilarityIDFExplanation(const String& exp, double idf) - { - this->exp = exp; - this->idf = idf; - } +SimilarityIDFExplanation::SimilarityIDFExplanation(const String& exp, double idf) { + this->exp = exp; + this->idf = idf; +} - SimilarityIDFExplanation::~SimilarityIDFExplanation() - { - } +SimilarityIDFExplanation::~SimilarityIDFExplanation() { +} - String SimilarityIDFExplanation::explain() - { - return !exp.empty() ? exp : L"idf(docFreq=" + StringUtils::toString(df) + L", maxDocs=" + StringUtils::toString(max) + L")"; - } +String SimilarityIDFExplanation::explain() { + return !exp.empty() ? exp : L"idf(docFreq=" + StringUtils::toString(df) + L", maxDocs=" + StringUtils::toString(max) + L")"; +} + +double SimilarityIDFExplanation::getIdf() { + return idf; +} - double SimilarityIDFExplanation::getIdf() - { - return idf; - } } diff --git a/src/core/search/SimilarityDelegator.cpp b/src/core/search/SimilarityDelegator.cpp index 4ee52be2..50aac0b9 100644 --- a/src/core/search/SimilarityDelegator.cpp +++ b/src/core/search/SimilarityDelegator.cpp @@ -7,54 +7,45 @@ #include "LuceneInc.h" #include "SimilarityDelegator.h" -namespace Lucene -{ - SimilarityDelegator::SimilarityDelegator(const SimilarityPtr& delegee) - { - this->delegee = delegee; - } - - SimilarityDelegator::~SimilarityDelegator() - { - } - - double SimilarityDelegator::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) - { - return delegee->computeNorm(fieldName, state); - } - - double SimilarityDelegator::lengthNorm(const String& fieldName, int32_t numTokens) - { - return delegee->lengthNorm(fieldName, numTokens); - } - - double SimilarityDelegator::queryNorm(double sumOfSquaredWeights) - { - return delegee->queryNorm(sumOfSquaredWeights); - } - - double SimilarityDelegator::tf(double freq) - { - return delegee->tf(freq); - } - - double SimilarityDelegator::sloppyFreq(int32_t distance) - { - return delegee->sloppyFreq(distance); - } - - double SimilarityDelegator::idf(int32_t docFreq, int32_t numDocs) - { - return delegee->idf(docFreq, numDocs); - } - - double SimilarityDelegator::coord(int32_t overlap, int32_t maxOverlap) - { - return delegee->coord(overlap, maxOverlap); - } - - double SimilarityDelegator::scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) - { - return delegee->scorePayload(docId, fieldName, start, end, payload, offset, length); - } +namespace Lucene { + +SimilarityDelegator::SimilarityDelegator(const SimilarityPtr& delegee) { + this->delegee = delegee; +} + +SimilarityDelegator::~SimilarityDelegator() { +} + +double SimilarityDelegator::computeNorm(const String& fieldName, const FieldInvertStatePtr& state) { + return delegee->computeNorm(fieldName, state); +} + +double SimilarityDelegator::lengthNorm(const String& fieldName, int32_t numTokens) { + return delegee->lengthNorm(fieldName, numTokens); +} + +double SimilarityDelegator::queryNorm(double sumOfSquaredWeights) { + return delegee->queryNorm(sumOfSquaredWeights); +} + +double SimilarityDelegator::tf(double freq) { + return delegee->tf(freq); +} + +double SimilarityDelegator::sloppyFreq(int32_t distance) { + return delegee->sloppyFreq(distance); +} + +double SimilarityDelegator::idf(int32_t docFreq, int32_t numDocs) { + return delegee->idf(docFreq, numDocs); +} + +double SimilarityDelegator::coord(int32_t overlap, int32_t maxOverlap) { + return delegee->coord(overlap, maxOverlap); +} + +double SimilarityDelegator::scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) { + return delegee->scorePayload(docId, fieldName, start, end, payload, offset, length); +} + } diff --git a/src/core/search/SingleTermEnum.cpp b/src/core/search/SingleTermEnum.cpp index 20754260..8db9be73 100644 --- a/src/core/search/SingleTermEnum.cpp +++ b/src/core/search/SingleTermEnum.cpp @@ -9,34 +9,31 @@ #include "IndexReader.h" #include "Term.h" -namespace Lucene -{ - SingleTermEnum::SingleTermEnum(const IndexReaderPtr& reader, const TermPtr& singleTerm) - { - this->_endEnum = false; - this->singleTerm = singleTerm; - setEnum(reader->terms(singleTerm)); - } +namespace Lucene { - SingleTermEnum::~SingleTermEnum() - { - } +SingleTermEnum::SingleTermEnum(const IndexReaderPtr& reader, const TermPtr& singleTerm) { + this->_endEnum = false; + this->singleTerm = singleTerm; + setEnum(reader->terms(singleTerm)); +} - double SingleTermEnum::difference() - { - return 1.0; - } +SingleTermEnum::~SingleTermEnum() { +} - bool SingleTermEnum::endEnum() - { - return _endEnum; - } +double SingleTermEnum::difference() { + return 1.0; +} + +bool SingleTermEnum::endEnum() { + return _endEnum; +} - bool SingleTermEnum::termCompare(const TermPtr& term) - { - if (term->equals(singleTerm)) - return true; - _endEnum = true; - return false; +bool SingleTermEnum::termCompare(const TermPtr& term) { + if (term->equals(singleTerm)) { + return true; } + _endEnum = true; + return false; +} + } diff --git a/src/core/search/SloppyPhraseScorer.cpp b/src/core/search/SloppyPhraseScorer.cpp index d21a48ab..7920c680 100644 --- a/src/core/search/SloppyPhraseScorer.cpp +++ b/src/core/search/SloppyPhraseScorer.cpp @@ -10,172 +10,167 @@ #include "PhraseQueue.h" #include "Similarity.h" -namespace Lucene -{ - SloppyPhraseScorer::SloppyPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, int32_t slop, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) - { - this->slop = slop; - this->checkedRepeats = false; - } +namespace Lucene { - SloppyPhraseScorer::~SloppyPhraseScorer() - { - } +SloppyPhraseScorer::SloppyPhraseScorer(const WeightPtr& weight, Collection tps, Collection offsets, const SimilarityPtr& similarity, int32_t slop, ByteArray norms) : PhraseScorer(weight, tps, offsets, similarity, norms) { + this->slop = slop; + this->checkedRepeats = false; +} - double SloppyPhraseScorer::phraseFreq() - { - int32_t end = initPhrasePositions(); - - double freq = 0.0; - bool done = (end < 0); - while (!done) - { - PhrasePositionsPtr pp(pq->pop()); - int32_t start = pp->position; - int32_t next = pq->top()->position; - - bool tpsDiffer = true; - for (int32_t pos = start; pos <= next || !tpsDiffer; pos = pp->position) - { - if (pos<=next && tpsDiffer) - start = pos; // advance pp to min window - if (!pp->nextPosition()) - { - done = true; // ran out of a term - done - break; - } +SloppyPhraseScorer::~SloppyPhraseScorer() { +} + +double SloppyPhraseScorer::phraseFreq() { + int32_t end = initPhrasePositions(); - PhrasePositionsPtr pp2; - tpsDiffer = (!pp->repeats || !(pp2 = termPositionsDiffer(pp))); - if (pp2 && pp2 != pp) - pp = flip(pp, pp2); // flip pp to pp2 + double freq = 0.0; + bool done = (end < 0); + while (!done) { + PhrasePositionsPtr pp(pq->pop()); + int32_t start = pp->position; + int32_t next = pq->top()->position; + + bool tpsDiffer = true; + for (int32_t pos = start; pos <= next || !tpsDiffer; pos = pp->position) { + if (pos<=next && tpsDiffer) { + start = pos; // advance pp to min window + } + if (!pp->nextPosition()) { + done = true; // ran out of a term - done + break; } - int32_t matchLength = end - start; - if (matchLength <= slop) - freq += getSimilarity()->sloppyFreq(matchLength); // score match + PhrasePositionsPtr pp2; + tpsDiffer = (!pp->repeats || !(pp2 = termPositionsDiffer(pp))); + if (pp2 && pp2 != pp) { + pp = flip(pp, pp2); // flip pp to pp2 + } + } - if (pp->position > end) - end = pp->position; - pq->add(pp); // restore pq + int32_t matchLength = end - start; + if (matchLength <= slop) { + freq += getSimilarity()->sloppyFreq(matchLength); // score match } - return freq; + if (pp->position > end) { + end = pp->position; + } + pq->add(pp); // restore pq } - PhrasePositionsPtr SloppyPhraseScorer::flip(const PhrasePositionsPtr& pp, const PhrasePositionsPtr& pp2) - { - int32_t n = 0; - PhrasePositionsPtr pp3; - // pop until finding pp2 - while ((pp3 = pq->pop()) != pp2) - tmpPos[n++] = pp3; - // insert back all but pp2 - for (n--; n >= 0; --n) - pq->addOverflow(tmpPos[n]); - // insert pp back - pq->add(pp); - return pp2; + return freq; +} + +PhrasePositionsPtr SloppyPhraseScorer::flip(const PhrasePositionsPtr& pp, const PhrasePositionsPtr& pp2) { + int32_t n = 0; + PhrasePositionsPtr pp3; + // pop until finding pp2 + while ((pp3 = pq->pop()) != pp2) { + tmpPos[n++] = pp3; } + // insert back all but pp2 + for (n--; n >= 0; --n) { + pq->addOverflow(tmpPos[n]); + } + // insert pp back + pq->add(pp); + return pp2; +} - int32_t SloppyPhraseScorer::initPhrasePositions() - { - int32_t end = 0; - - // no repeats at all (most common case is also the simplest one) - if (checkedRepeats && !repeats) - { - // build queue from list - pq->clear(); - for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) - { - pp->firstPosition(); - if (pp->position > end) - end = pp->position; - pq->add(pp); // build pq from list +int32_t SloppyPhraseScorer::initPhrasePositions() { + int32_t end = 0; + + // no repeats at all (most common case is also the simplest one) + if (checkedRepeats && !repeats) { + // build queue from list + pq->clear(); + for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) { + pp->firstPosition(); + if (pp->position > end) { + end = pp->position; } - return end; + pq->add(pp); // build pq from list } + return end; + } - // position the pp's - for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) - pp->firstPosition(); + // position the pp's + for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) { + pp->firstPosition(); + } - // one time initialization for this scorer - if (!checkedRepeats) - { - checkedRepeats = true; - // check for repeats - MapPhrasePositionsLuceneObject m; - for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) - { - int32_t tpPos = pp->position + pp->offset; - for (PhrasePositionsPtr pp2(pp->_next); pp2; pp2 = pp2->_next) - { - int32_t tpPos2 = pp2->position + pp2->offset; - if (tpPos2 == tpPos) - { - if (!m) - m = MapPhrasePositionsLuceneObject::newInstance(); - pp->repeats = true; - pp2->repeats = true; - m.put(pp, LuceneObjectPtr()); - m.put(pp2, LuceneObjectPtr()); + // one time initialization for this scorer + if (!checkedRepeats) { + checkedRepeats = true; + // check for repeats + MapPhrasePositionsLuceneObject m; + for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) { + int32_t tpPos = pp->position + pp->offset; + for (PhrasePositionsPtr pp2(pp->_next); pp2; pp2 = pp2->_next) { + int32_t tpPos2 = pp2->position + pp2->offset; + if (tpPos2 == tpPos) { + if (!m) { + m = MapPhrasePositionsLuceneObject::newInstance(); } + pp->repeats = true; + pp2->repeats = true; + m.put(pp, LuceneObjectPtr()); + m.put(pp2, LuceneObjectPtr()); } } - if (m) - { - repeats = Collection::newInstance(); - for (MapPhrasePositionsLuceneObject::iterator key = m.begin(); key != m.end(); ++key) - repeats.add(key->first); + } + if (m) { + repeats = Collection::newInstance(); + for (MapPhrasePositionsLuceneObject::iterator key = m.begin(); key != m.end(); ++key) { + repeats.add(key->first); } } + } - // with repeats must advance some repeating pp's so they all start with differing tp's - if (repeats) - { - for (Collection::iterator pp = repeats.begin(); pp != repeats.end(); ++pp) - { - PhrasePositionsPtr pp2; - while ((pp2 = termPositionsDiffer(*pp))) - { - if (!pp2->nextPosition()) // out of pps that do not differ, advance the pp with higher offset - return -1; // ran out of a term - done + // with repeats must advance some repeating pp's so they all start with differing tp's + if (repeats) { + for (Collection::iterator pp = repeats.begin(); pp != repeats.end(); ++pp) { + PhrasePositionsPtr pp2; + while ((pp2 = termPositionsDiffer(*pp))) { + if (!pp2->nextPosition()) { // out of pps that do not differ, advance the pp with higher offset + return -1; // ran out of a term - done } } } + } - // build queue from list - pq->clear(); - for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) - { - if (pp->position > end) - end = pp->position; - pq->add(pp); // build pq from list + // build queue from list + pq->clear(); + for (PhrasePositionsPtr pp(first); pp; pp = pp->_next) { + if (pp->position > end) { + end = pp->position; } + pq->add(pp); // build pq from list + } - if (repeats) - tmpPos = Collection::newInstance(pq->size()); - - return end; + if (repeats) { + tmpPos = Collection::newInstance(pq->size()); } - PhrasePositionsPtr SloppyPhraseScorer::termPositionsDiffer(const PhrasePositionsPtr& pp) - { - // Efficiency note: a more efficient implementation could keep a map between repeating pp's, so that if - // pp1a, pp1b, pp1c are repeats term1, and pp2a, pp2b are repeats of term2, pp2a would only be checked - // against pp2b but not against pp1a, pp1b, pp1c. However this would complicate code, for a rather rare - // case, so choice is to compromise here. - int32_t tpPos = pp->position + pp->offset; - for (Collection::iterator pp2 = repeats.begin(); pp2 != repeats.end(); ++pp2) - { - if (*pp2 == pp) - continue; - int32_t tpPos2 = (*pp2)->position + (*pp2)->offset; - if (tpPos2 == tpPos) - return pp->offset > (*pp2)->offset ? pp : *pp2; // do not differ: return the one with higher offset. + return end; +} + +PhrasePositionsPtr SloppyPhraseScorer::termPositionsDiffer(const PhrasePositionsPtr& pp) { + // Efficiency note: a more efficient implementation could keep a map between repeating pp's, so that if + // pp1a, pp1b, pp1c are repeats term1, and pp2a, pp2b are repeats of term2, pp2a would only be checked + // against pp2b but not against pp1a, pp1b, pp1c. However this would complicate code, for a rather rare + // case, so choice is to compromise here. + int32_t tpPos = pp->position + pp->offset; + for (Collection::iterator pp2 = repeats.begin(); pp2 != repeats.end(); ++pp2) { + if (*pp2 == pp) { + continue; + } + int32_t tpPos2 = (*pp2)->position + (*pp2)->offset; + if (tpPos2 == tpPos) { + return pp->offset > (*pp2)->offset ? pp : *pp2; // do not differ: return the one with higher offset. } - return PhrasePositionsPtr(); } + return PhrasePositionsPtr(); +} + } diff --git a/src/core/search/Sort.cpp b/src/core/search/Sort.cpp index 0fe4dab3..3d1b384e 100644 --- a/src/core/search/Sort.cpp +++ b/src/core/search/Sort.cpp @@ -9,89 +9,78 @@ #include "SortField.h" #include "MiscUtils.h" -namespace Lucene -{ - Sort::Sort() - { - setSort(SortField::FIELD_SCORE()); - } +namespace Lucene { - Sort::Sort(const SortFieldPtr& field) - { - setSort(field); - } +Sort::Sort() { + setSort(SortField::FIELD_SCORE()); +} - Sort::Sort(Collection fields) - { - setSort(fields); - } +Sort::Sort(const SortFieldPtr& field) { + setSort(field); +} - Sort::~Sort() - { - } +Sort::Sort(Collection fields) { + setSort(fields); +} - SortPtr Sort::RELEVANCE() - { - static SortPtr _RELEVANCE; - if (!_RELEVANCE) - { - _RELEVANCE = newLucene(); - CycleCheck::addStatic(_RELEVANCE); - } - return _RELEVANCE; - } +Sort::~Sort() { +} - SortPtr Sort::INDEXORDER() - { - static SortPtr _INDEXORDER; - if (!_INDEXORDER) - { - _INDEXORDER = newLucene(SortField::FIELD_DOC()); - CycleCheck::addStatic(_INDEXORDER); - } - return _INDEXORDER; +SortPtr Sort::RELEVANCE() { + static SortPtr _RELEVANCE; + if (!_RELEVANCE) { + _RELEVANCE = newLucene(); + CycleCheck::addStatic(_RELEVANCE); } + return _RELEVANCE; +} - void Sort::setSort(const SortFieldPtr& field) - { - this->fields = newCollection(field); +SortPtr Sort::INDEXORDER() { + static SortPtr _INDEXORDER; + if (!_INDEXORDER) { + _INDEXORDER = newLucene(SortField::FIELD_DOC()); + CycleCheck::addStatic(_INDEXORDER); } + return _INDEXORDER; +} - void Sort::setSort(Collection fields) - { - this->fields = fields; - } +void Sort::setSort(const SortFieldPtr& field) { + this->fields = newCollection(field); +} - Collection Sort::getSort() - { - return fields; - } +void Sort::setSort(Collection fields) { + this->fields = fields; +} + +Collection Sort::getSort() { + return fields; +} - String Sort::toString() - { - StringStream buffer; - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - if (field != fields.begin()) - buffer << L","; - buffer << (*field)->toString(); +String Sort::toString() { + StringStream buffer; + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + if (field != fields.begin()) { + buffer << L","; } - return buffer.str(); + buffer << (*field)->toString(); } + return buffer.str(); +} - bool Sort::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - - SortPtr otherSort(boost::dynamic_pointer_cast(other)); - if (!otherSort) - return false; - return fields.equals(otherSort->fields); +bool Sort::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - int32_t Sort::hashCode() - { - return 0x45aaf665 + MiscUtils::hashCode(fields.begin(), fields.end(), MiscUtils::hashLucene); + SortPtr otherSort(boost::dynamic_pointer_cast(other)); + if (!otherSort) { + return false; } + return fields.equals(otherSort->fields); +} + +int32_t Sort::hashCode() { + return 0x45aaf665 + MiscUtils::hashCode(fields.begin(), fields.end(), MiscUtils::hashLucene); +} + } diff --git a/src/core/search/SortField.cpp b/src/core/search/SortField.cpp index c20052e6..fa7d453f 100644 --- a/src/core/search/SortField.cpp +++ b/src/core/search/SortField.cpp @@ -11,254 +11,243 @@ #include "FieldComparatorSource.h" #include "StringUtils.h" -namespace Lucene -{ - /// Sort by document score (relevancy). Sort values are Double and higher values are at the front. - const int32_t SortField::SCORE = 0; +namespace Lucene { - /// Sort by document number (index order). Sort values are Integer and lower values are at the front. - const int32_t SortField::DOC = 1; +/// Sort by document score (relevancy). Sort values are Double and higher values are at the front. +const int32_t SortField::SCORE = 0; - /// Sort using term values as Strings. Sort values are String and lower values are at the front. - const int32_t SortField::STRING = 3; +/// Sort by document number (index order). Sort values are Integer and lower values are at the front. +const int32_t SortField::DOC = 1; - /// Sort using term values as Integers. Sort values are Integer and lower values are at the front. - const int32_t SortField::INT = 4; +/// Sort using term values as Strings. Sort values are String and lower values are at the front. +const int32_t SortField::STRING = 3; - /// Sort using term values as Floats. Sort values are Float and lower values are at the front. - const int32_t SortField::FLOAT = 5; +/// Sort using term values as Integers. Sort values are Integer and lower values are at the front. +const int32_t SortField::INT = 4; - /// Sort using term values as Longs. Sort values are Long and lower values are at the front. - const int32_t SortField::LONG = 6; +/// Sort using term values as Floats. Sort values are Float and lower values are at the front. +const int32_t SortField::FLOAT = 5; - /// Sort using term values as Doubles. Sort values are Double and lower values are at the front. - const int32_t SortField::DOUBLE = 7; +/// Sort using term values as Longs. Sort values are Long and lower values are at the front. +const int32_t SortField::LONG = 6; - /// Sort using term values as Shorts. Sort values are Short and lower values are at the front. - const int32_t SortField::SHORT = 8; +/// Sort using term values as Doubles. Sort values are Double and lower values are at the front. +const int32_t SortField::DOUBLE = 7; - /// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according - /// to natural order. - const int32_t SortField::CUSTOM = 9; +/// Sort using term values as Shorts. Sort values are Short and lower values are at the front. +const int32_t SortField::SHORT = 8; - /// Sort using term values as Bytes. Sort values are Byte and lower values are at the front. - const int32_t SortField::BYTE = 10; +/// Sort using a custom Comparator. Sort values are any ComparableValue and sorting is done according +/// to natural order. +const int32_t SortField::CUSTOM = 9; - /// Sort using term values as Strings, but comparing by value (using String::compare) for all comparisons. - /// This is typically slower than {@link #STRING}, which uses ordinals to do the sorting. - const int32_t SortField::STRING_VAL = 11; +/// Sort using term values as Bytes. Sort values are Byte and lower values are at the front. +const int32_t SortField::BYTE = 10; - SortField::SortField(const String& field, int32_t type, bool reverse) - { - initFieldType(field, type); - this->reverse = reverse; - } +/// Sort using term values as Strings, but comparing by value (using String::compare) for all comparisons. +/// This is typically slower than {@link #STRING}, which uses ordinals to do the sorting. +const int32_t SortField::STRING_VAL = 11; - SortField::SortField(const String& field, const ParserPtr& parser, bool reverse) - { - if (boost::dynamic_pointer_cast(parser)) - initFieldType(field, INT); - else if (boost::dynamic_pointer_cast(parser)) - initFieldType(field, BYTE); - else if (boost::dynamic_pointer_cast(parser)) - initFieldType(field, LONG); - else if (boost::dynamic_pointer_cast(parser)) - initFieldType(field, DOUBLE); - else - boost::throw_exception(IllegalArgumentException(L"Parser instance does not subclass existing numeric parser from FieldCache")); - this->reverse = reverse; - this->parser = parser; - } +SortField::SortField(const String& field, int32_t type, bool reverse) { + initFieldType(field, type); + this->reverse = reverse; +} - SortField::SortField(const String& field, const std::locale& locale, bool reverse) - { - initFieldType(field, STRING); - this->locale = newInstance(locale); - this->reverse = reverse; - } +SortField::SortField(const String& field, const ParserPtr& parser, bool reverse) { + if (boost::dynamic_pointer_cast(parser)) { + initFieldType(field, INT); + } else if (boost::dynamic_pointer_cast(parser)) { + initFieldType(field, BYTE); + } else if (boost::dynamic_pointer_cast(parser)) { + initFieldType(field, LONG); + } else if (boost::dynamic_pointer_cast(parser)) { + initFieldType(field, DOUBLE); + } else { + boost::throw_exception(IllegalArgumentException(L"Parser instance does not subclass existing numeric parser from FieldCache")); + } + this->reverse = reverse; + this->parser = parser; +} - SortField::SortField(const String& field, const FieldComparatorSourcePtr& comparator, bool reverse) - { - initFieldType(field, CUSTOM); - this->comparatorSource = comparator; - this->reverse = reverse; - } +SortField::SortField(const String& field, const std::locale& locale, bool reverse) { + initFieldType(field, STRING); + this->locale = newInstance(locale); + this->reverse = reverse; +} - SortField::~SortField() - { - } +SortField::SortField(const String& field, const FieldComparatorSourcePtr& comparator, bool reverse) { + initFieldType(field, CUSTOM); + this->comparatorSource = comparator; + this->reverse = reverse; +} - SortFieldPtr SortField::FIELD_SCORE() - { - static SortFieldPtr _FIELD_SCORE; - if (!_FIELD_SCORE) - { - _FIELD_SCORE = newLucene(L"", SCORE); - CycleCheck::addStatic(_FIELD_SCORE); - } - return _FIELD_SCORE; - } +SortField::~SortField() { +} - SortFieldPtr SortField::FIELD_DOC() - { - static SortFieldPtr _FIELD_DOC; - if (!_FIELD_DOC) - { - _FIELD_DOC = newLucene(L"", DOC); - CycleCheck::addStatic(_FIELD_DOC); - } - return _FIELD_DOC; +SortFieldPtr SortField::FIELD_SCORE() { + static SortFieldPtr _FIELD_SCORE; + if (!_FIELD_SCORE) { + _FIELD_SCORE = newLucene(L"", SCORE); + CycleCheck::addStatic(_FIELD_SCORE); } + return _FIELD_SCORE; +} - void SortField::initFieldType(const String& field, int32_t type) - { - this->type = type; - if (field.empty() && type != SCORE && type != DOC) - boost::throw_exception(IllegalArgumentException(L"Field can only be null when type is SCORE or DOC")); - this->field = field; +SortFieldPtr SortField::FIELD_DOC() { + static SortFieldPtr _FIELD_DOC; + if (!_FIELD_DOC) { + _FIELD_DOC = newLucene(L"", DOC); + CycleCheck::addStatic(_FIELD_DOC); } + return _FIELD_DOC; +} - String SortField::getField() - { - return field; +void SortField::initFieldType(const String& field, int32_t type) { + this->type = type; + if (field.empty() && type != SCORE && type != DOC) { + boost::throw_exception(IllegalArgumentException(L"Field can only be null when type is SCORE or DOC")); } + this->field = field; +} - int32_t SortField::getType() - { - return type; - } +String SortField::getField() { + return field; +} - localePtr SortField::getLocale() - { - return locale; - } +int32_t SortField::getType() { + return type; +} - ParserPtr SortField::getParser() - { - return parser; - } +localePtr SortField::getLocale() { + return locale; +} - bool SortField::getReverse() - { - return reverse; - } +ParserPtr SortField::getParser() { + return parser; +} - FieldComparatorSourcePtr SortField::getComparatorSource() - { - return comparatorSource; - } +bool SortField::getReverse() { + return reverse; +} - String SortField::toString() - { - StringStream buffer; - switch (type) - { - case SCORE: - buffer << L""; - break; - case DOC: - buffer << L""; - break; - case STRING: - buffer << L""; - break; - case STRING_VAL: - buffer << L""; - break; - case BYTE: - buffer << L""; - break; - case SHORT: - buffer << L""; - break; - case INT: - buffer << L""; - break; - case LONG: - buffer << L""; - break; - case FLOAT: - buffer << L""; - break; - case DOUBLE: - buffer << L""; - break; - case CUSTOM: - buffer << L"toString() << L">"; - break; - default: - buffer << L""; - break; - } - - if (parser) - buffer << L"(" << parser->toString() << L")"; - if (reverse) - buffer << L"!"; - - return buffer.str(); - } +FieldComparatorSourcePtr SortField::getComparatorSource() { + return comparatorSource; +} - bool SortField::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; +String SortField::toString() { + StringStream buffer; + switch (type) { + case SCORE: + buffer << L""; + break; + case DOC: + buffer << L""; + break; + case STRING: + buffer << L""; + break; + case STRING_VAL: + buffer << L""; + break; + case BYTE: + buffer << L""; + break; + case SHORT: + buffer << L""; + break; + case INT: + buffer << L""; + break; + case LONG: + buffer << L""; + break; + case FLOAT: + buffer << L""; + break; + case DOUBLE: + buffer << L""; + break; + case CUSTOM: + buffer << L"toString() << L">"; + break; + default: + buffer << L""; + break; + } + + if (parser) { + buffer << L"(" << parser->toString() << L")"; + } + if (reverse) { + buffer << L"!"; + } + + return buffer.str(); +} - SortFieldPtr otherSortField(boost::dynamic_pointer_cast(other)); - if (!otherSortField) - return false; +bool SortField::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } - return (field == otherSortField->field && type == otherSortField->type && - reverse == otherSortField->reverse && - ((locale && otherSortField->locale && *locale == *otherSortField->locale) || (!locale && !otherSortField->locale)) && - (comparatorSource ? comparatorSource->equals(otherSortField->comparatorSource) : !otherSortField->comparatorSource) && - (parser ? parser->equals(otherSortField->parser) : !otherSortField->parser)); + SortFieldPtr otherSortField(boost::dynamic_pointer_cast(other)); + if (!otherSortField) { + return false; } - int32_t SortField::hashCode() - { - int32_t hash = type ^ 0x346565dd + (reverse ? 1 : 0) ^ 0xaf5998bb; - hash += StringUtils::hashCode(field) ^ 0xff5685dd; - if (locale) - hash += StringUtils::hashCode(StringUtils::toUnicode(locale->name().c_str())) ^ 0xff5685dd; - if (comparatorSource) - hash += comparatorSource->hashCode(); - if (parser) - hash += parser->hashCode() ^ 0x3aaf56ff; - return hash; + return (field == otherSortField->field && type == otherSortField->type && + reverse == otherSortField->reverse && + ((locale && otherSortField->locale && *locale == *otherSortField->locale) || (!locale && !otherSortField->locale)) && + (comparatorSource ? comparatorSource->equals(otherSortField->comparatorSource) : !otherSortField->comparatorSource) && + (parser ? parser->equals(otherSortField->parser) : !otherSortField->parser)); +} + +int32_t SortField::hashCode() { + int32_t hash = type ^ 0x346565dd + (reverse ? 1 : 0) ^ 0xaf5998bb; + hash += StringUtils::hashCode(field) ^ 0xff5685dd; + if (locale) { + hash += StringUtils::hashCode(StringUtils::toUnicode(locale->name().c_str())) ^ 0xff5685dd; + } + if (comparatorSource) { + hash += comparatorSource->hashCode(); } + if (parser) { + hash += parser->hashCode() ^ 0x3aaf56ff; + } + return hash; +} - FieldComparatorPtr SortField::getComparator(int32_t numHits, int32_t sortPos) - { - if (locale) - return newLucene(numHits, field, *locale); - - switch (type) - { - case SCORE: - return newLucene(numHits); - case DOC: - return newLucene(numHits); - case SHORT: - case INT: - return newLucene(numHits, field, parser); - case FLOAT: - case DOUBLE: - return newLucene(numHits, field, parser); - case LONG: - return newLucene(numHits, field, parser); - case BYTE: - return newLucene(numHits, field, parser); - case CUSTOM: - BOOST_ASSERT(comparatorSource); - return comparatorSource->newComparator(field, numHits, sortPos, reverse); - case STRING: - return newLucene(numHits, field, sortPos, reverse); - case STRING_VAL: - return newLucene(numHits, field); - default: - boost::throw_exception(IllegalStateException(L"Illegal sort type: " + StringUtils::toString(type))); - return FieldComparatorPtr(); - } +FieldComparatorPtr SortField::getComparator(int32_t numHits, int32_t sortPos) { + if (locale) { + return newLucene(numHits, field, *locale); + } + + switch (type) { + case SCORE: + return newLucene(numHits); + case DOC: + return newLucene(numHits); + case SHORT: + case INT: + return newLucene(numHits, field, parser); + case FLOAT: + case DOUBLE: + return newLucene(numHits, field, parser); + case LONG: + return newLucene(numHits, field, parser); + case BYTE: + return newLucene(numHits, field, parser); + case CUSTOM: + BOOST_ASSERT(comparatorSource); + return comparatorSource->newComparator(field, numHits, sortPos, reverse); + case STRING: + return newLucene(numHits, field, sortPos, reverse); + case STRING_VAL: + return newLucene(numHits, field); + default: + boost::throw_exception(IllegalStateException(L"Illegal sort type: " + StringUtils::toString(type))); + return FieldComparatorPtr(); } } + +} diff --git a/src/core/search/SpanFilter.cpp b/src/core/search/SpanFilter.cpp index 61ad52e7..0a9771d5 100644 --- a/src/core/search/SpanFilter.cpp +++ b/src/core/search/SpanFilter.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "SpanFilter.h" -namespace Lucene -{ - SpanFilter::~SpanFilter() - { - } +namespace Lucene { + +SpanFilter::~SpanFilter() { +} + } diff --git a/src/core/search/SpanFilterResult.cpp b/src/core/search/SpanFilterResult.cpp index 253e7a5c..2603e161 100644 --- a/src/core/search/SpanFilterResult.cpp +++ b/src/core/search/SpanFilterResult.cpp @@ -7,70 +7,58 @@ #include "LuceneInc.h" #include "SpanFilterResult.h" -namespace Lucene -{ - SpanFilterResult::SpanFilterResult(const DocIdSetPtr& docIdSet, Collection positions) - { - this->docIdSet = docIdSet; - this->positions = positions; - } - - SpanFilterResult::~SpanFilterResult() - { - } - - Collection SpanFilterResult::getPositions() - { - return positions; - } - - DocIdSetPtr SpanFilterResult::getDocIdSet() - { - return docIdSet; - } - - PositionInfo::PositionInfo(int32_t doc) - { - this->doc = doc; - this->positions = Collection::newInstance(); - } - - PositionInfo::~PositionInfo() - { - } - - void PositionInfo::addPosition(int32_t start, int32_t end) - { - positions.add(newLucene(start, end)); - } - - int32_t PositionInfo::getDoc() - { - return doc; - } - - Collection PositionInfo::getPositions() - { - return positions; - } - - StartEnd::StartEnd(int32_t start, int32_t end) - { - this->start = start; - this->end = end; - } - - StartEnd::~StartEnd() - { - } - - int32_t StartEnd::getEnd() - { - return end; - } - - int32_t StartEnd::getStart() - { - return start; - } +namespace Lucene { + +SpanFilterResult::SpanFilterResult(const DocIdSetPtr& docIdSet, Collection positions) { + this->docIdSet = docIdSet; + this->positions = positions; +} + +SpanFilterResult::~SpanFilterResult() { +} + +Collection SpanFilterResult::getPositions() { + return positions; +} + +DocIdSetPtr SpanFilterResult::getDocIdSet() { + return docIdSet; +} + +PositionInfo::PositionInfo(int32_t doc) { + this->doc = doc; + this->positions = Collection::newInstance(); +} + +PositionInfo::~PositionInfo() { +} + +void PositionInfo::addPosition(int32_t start, int32_t end) { + positions.add(newLucene(start, end)); +} + +int32_t PositionInfo::getDoc() { + return doc; +} + +Collection PositionInfo::getPositions() { + return positions; +} + +StartEnd::StartEnd(int32_t start, int32_t end) { + this->start = start; + this->end = end; +} + +StartEnd::~StartEnd() { +} + +int32_t StartEnd::getEnd() { + return end; +} + +int32_t StartEnd::getStart() { + return start; +} + } diff --git a/src/core/search/SpanQueryFilter.cpp b/src/core/search/SpanQueryFilter.cpp index 392e00cb..f147f889 100644 --- a/src/core/search/SpanQueryFilter.cpp +++ b/src/core/search/SpanQueryFilter.cpp @@ -12,68 +12,61 @@ #include "OpenBitSet.h" #include "IndexReader.h" -namespace Lucene -{ - SpanQueryFilter::SpanQueryFilter(const SpanQueryPtr& query) - { - this->query = query; - } +namespace Lucene { - SpanQueryFilter::~SpanQueryFilter() - { - } +SpanQueryFilter::SpanQueryFilter(const SpanQueryPtr& query) { + this->query = query; +} - DocIdSetPtr SpanQueryFilter::getDocIdSet(const IndexReaderPtr& reader) - { - SpanFilterResultPtr result(bitSpans(reader)); - return result->getDocIdSet(); - } +SpanQueryFilter::~SpanQueryFilter() { +} - SpanFilterResultPtr SpanQueryFilter::bitSpans(const IndexReaderPtr& reader) - { - OpenBitSetPtr bits(newLucene(reader->maxDoc())); - SpansPtr spans(query->getSpans(reader)); - Collection tmp(Collection::newInstance()); - int32_t currentDoc = -1; - PositionInfoPtr currentInfo; - while (spans->next()) - { - int32_t doc = spans->doc(); - bits->set(doc); - if (currentDoc != doc) - { - currentInfo = newLucene(doc); - tmp.add(currentInfo); - currentDoc = doc; - } - currentInfo->addPosition(spans->start(), spans->end()); - } - return newLucene(bits, tmp); - } +DocIdSetPtr SpanQueryFilter::getDocIdSet(const IndexReaderPtr& reader) { + SpanFilterResultPtr result(bitSpans(reader)); + return result->getDocIdSet(); +} - SpanQueryPtr SpanQueryFilter::getQuery() - { - return query; +SpanFilterResultPtr SpanQueryFilter::bitSpans(const IndexReaderPtr& reader) { + OpenBitSetPtr bits(newLucene(reader->maxDoc())); + SpansPtr spans(query->getSpans(reader)); + Collection tmp(Collection::newInstance()); + int32_t currentDoc = -1; + PositionInfoPtr currentInfo; + while (spans->next()) { + int32_t doc = spans->doc(); + bits->set(doc); + if (currentDoc != doc) { + currentInfo = newLucene(doc); + tmp.add(currentInfo); + currentDoc = doc; + } + currentInfo->addPosition(spans->start(), spans->end()); } + return newLucene(bits, tmp); +} - String SpanQueryFilter::toString() - { - return L"SpanQueryFilter(" + query->toString() + L")"; - } +SpanQueryPtr SpanQueryFilter::getQuery() { + return query; +} - bool SpanQueryFilter::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; +String SpanQueryFilter::toString() { + return L"SpanQueryFilter(" + query->toString() + L")"; +} - SpanQueryFilterPtr otherSpanQueryFilter(boost::dynamic_pointer_cast(other)); - if (!otherSpanQueryFilter) - return false; - return query->equals(otherSpanQueryFilter->query); +bool SpanQueryFilter::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - int32_t SpanQueryFilter::hashCode() - { - return query->hashCode() ^ 0x923f64b9; + SpanQueryFilterPtr otherSpanQueryFilter(boost::dynamic_pointer_cast(other)); + if (!otherSpanQueryFilter) { + return false; } + return query->equals(otherSpanQueryFilter->query); +} + +int32_t SpanQueryFilter::hashCode() { + return query->hashCode() ^ 0x923f64b9; +} + } diff --git a/src/core/search/TermQuery.cpp b/src/core/search/TermQuery.cpp index ad6a022d..1d0d3138 100644 --- a/src/core/search/TermQuery.cpp +++ b/src/core/search/TermQuery.cpp @@ -16,192 +16,175 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - TermQuery::TermQuery(const TermPtr& term) - { - this->term = term; - } +namespace Lucene { - TermQuery::~TermQuery() - { - } +TermQuery::TermQuery(const TermPtr& term) { + this->term = term; +} - TermPtr TermQuery::getTerm() - { - return term; - } +TermQuery::~TermQuery() { +} + +TermPtr TermQuery::getTerm() { + return term; +} + +WeightPtr TermQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - WeightPtr TermQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); +void TermQuery::extractTerms(SetTerm terms) { + terms.add(getTerm()); +} + +String TermQuery::toString(const String& field) { + StringStream buffer; + if (term->field() != field) { + buffer << term->field() << L":"; } + buffer << term->text() << boostString(); + return buffer.str(); +} - void TermQuery::extractTerms(SetTerm terms) - { - terms.add(getTerm()); +bool TermQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - String TermQuery::toString(const String& field) - { - StringStream buffer; - if (term->field() != field) - buffer << term->field() << L":"; - buffer << term->text() << boostString(); - return buffer.str(); + TermQueryPtr otherTermQuery(boost::dynamic_pointer_cast(other)); + if (!otherTermQuery) { + return false; } - bool TermQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; + return (getBoost() == otherTermQuery->getBoost() && term->equals(otherTermQuery->term)); +} - TermQueryPtr otherTermQuery(boost::dynamic_pointer_cast(other)); - if (!otherTermQuery) - return false; +int32_t TermQuery::hashCode() { + return MiscUtils::doubleToIntBits(getBoost()) ^ term->hashCode(); +} - return (getBoost() == otherTermQuery->getBoost() && term->equals(otherTermQuery->term)); - } +LuceneObjectPtr TermQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(term); + TermQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); + cloneQuery->term = term; + return cloneQuery; +} - int32_t TermQuery::hashCode() - { - return MiscUtils::doubleToIntBits(getBoost()) ^ term->hashCode(); - } +TermWeight::TermWeight(const TermQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = query->getSimilarity(searcher); + this->value = 0.0; + this->idf = 0.0; + this->queryNorm = 0.0; + this->queryWeight = 0.0; - LuceneObjectPtr TermQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(term); - TermQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); - cloneQuery->term = term; - return cloneQuery; - } + this->idfExp = similarity->idfExplain(query->term, searcher); + idf = idfExp->getIdf(); +} - TermWeight::TermWeight(const TermQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = query->getSimilarity(searcher); - this->value = 0.0; - this->idf = 0.0; - this->queryNorm = 0.0; - this->queryWeight = 0.0; - - this->idfExp = similarity->idfExplain(query->term, searcher); - idf = idfExp->getIdf(); - } +TermWeight::~TermWeight() { +} - TermWeight::~TermWeight() - { - } +String TermWeight::toString() { + return L"weight(" + query->toString() + L")"; +} - String TermWeight::toString() - { - return L"weight(" + query->toString() + L")"; - } +QueryPtr TermWeight::getQuery() { + return query; +} - QueryPtr TermWeight::getQuery() - { - return query; - } +double TermWeight::getValue() { + return value; +} - double TermWeight::getValue() - { - return value; - } +double TermWeight::sumOfSquaredWeights() { + queryWeight = idf * getQuery()->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it +} - double TermWeight::sumOfSquaredWeights() - { - queryWeight = idf * getQuery()->getBoost(); // compute query weight - return queryWeight * queryWeight; // square it - } +void TermWeight::normalize(double norm) { + queryNorm = norm; + queryWeight *= queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document +} - void TermWeight::normalize(double norm) - { - queryNorm = norm; - queryWeight *= queryNorm; // normalize query weight - value = queryWeight * idf; // idf for document - } +ScorerPtr TermWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + TermDocsPtr termDocs(reader->termDocs(query->term)); + return termDocs ? newLucene(shared_from_this(), termDocs, similarity, reader->norms(query->term->field())) : ScorerPtr(); +} + +ExplanationPtr TermWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + ComplexExplanationPtr result(newLucene()); + result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); + + ExplanationPtr expl(newLucene(idf, idfExp->explain())); - ScorerPtr TermWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - TermDocsPtr termDocs(reader->termDocs(query->term)); - return termDocs ? newLucene(shared_from_this(), termDocs, similarity, reader->norms(query->term->field())) : ScorerPtr(); + // explain query weight + ExplanationPtr queryExpl(newLucene()); + queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); + + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); + if (query->getBoost() != 1.0) { + queryExpl->addDetail(boostExpl); } + queryExpl->addDetail(expl); - ExplanationPtr TermWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - ComplexExplanationPtr result(newLucene()); - result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - - ExplanationPtr expl(newLucene(idf, idfExp->explain())); - - // explain query weight - ExplanationPtr queryExpl(newLucene()); - queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - - ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); - if (query->getBoost() != 1.0) - queryExpl->addDetail(boostExpl); - queryExpl->addDetail(expl); - - ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); - queryExpl->addDetail(queryNormExpl); - - queryExpl->setValue(boostExpl->getValue() * expl->getValue() * queryNormExpl->getValue()); - result->addDetail(queryExpl); - - // explain field weight - String field(query->term->field()); - ComplexExplanationPtr fieldExpl(newLucene()); - fieldExpl->setDescription(L"fieldWeight(" + query->term->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - - ExplanationPtr tfExplanation(newLucene()); - int32_t tf = 0; - TermDocsPtr termDocs(reader->termDocs(query->term)); - if (termDocs) - { - LuceneException finally; - try - { - if (termDocs->skipTo(doc) && termDocs->doc() == doc) - tf = termDocs->freq(); - } - catch (LuceneException& e) - { - finally = e; + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); + queryExpl->addDetail(queryNormExpl); + + queryExpl->setValue(boostExpl->getValue() * expl->getValue() * queryNormExpl->getValue()); + result->addDetail(queryExpl); + + // explain field weight + String field(query->term->field()); + ComplexExplanationPtr fieldExpl(newLucene()); + fieldExpl->setDescription(L"fieldWeight(" + query->term->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); + + ExplanationPtr tfExplanation(newLucene()); + int32_t tf = 0; + TermDocsPtr termDocs(reader->termDocs(query->term)); + if (termDocs) { + LuceneException finally; + try { + if (termDocs->skipTo(doc) && termDocs->doc() == doc) { + tf = termDocs->freq(); } - termDocs->close(); - finally.throwException(); - tfExplanation->setValue(similarity->tf(tf)); - tfExplanation->setDescription(L"tf(termFreq(" + query->term->toString() + L")=" + StringUtils::toString(tf) + L")"); - } - else - { - tfExplanation->setValue(0.0); - tfExplanation->setDescription(L"no matching term"); + } catch (LuceneException& e) { + finally = e; } + termDocs->close(); + finally.throwException(); + tfExplanation->setValue(similarity->tf(tf)); + tfExplanation->setDescription(L"tf(termFreq(" + query->term->toString() + L")=" + StringUtils::toString(tf) + L")"); + } else { + tfExplanation->setValue(0.0); + tfExplanation->setDescription(L"no matching term"); + } - fieldExpl->addDetail(tfExplanation); - fieldExpl->addDetail(expl); - - ExplanationPtr fieldNormExpl(newLucene()); - ByteArray fieldNorms(reader->norms(field)); - double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; - fieldNormExpl->setValue(fieldNorm); - fieldNormExpl->setDescription(L"fieldNorm(field=" + field + L", doc=" + StringUtils::toString(doc) + L")"); - fieldExpl->addDetail(fieldNormExpl); + fieldExpl->addDetail(tfExplanation); + fieldExpl->addDetail(expl); - fieldExpl->setMatch(tfExplanation->isMatch()); - fieldExpl->setValue(tfExplanation->getValue() * expl->getValue() * fieldNormExpl->getValue()); + ExplanationPtr fieldNormExpl(newLucene()); + ByteArray fieldNorms(reader->norms(field)); + double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; + fieldNormExpl->setValue(fieldNorm); + fieldNormExpl->setDescription(L"fieldNorm(field=" + field + L", doc=" + StringUtils::toString(doc) + L")"); + fieldExpl->addDetail(fieldNormExpl); - result->addDetail(fieldExpl); - result->setMatch(fieldExpl->getMatch()); + fieldExpl->setMatch(tfExplanation->isMatch()); + fieldExpl->setValue(tfExplanation->getValue() * expl->getValue() * fieldNormExpl->getValue()); - // combine them - result->setValue(queryExpl->getValue() * fieldExpl->getValue()); + result->addDetail(fieldExpl); + result->setMatch(fieldExpl->getMatch()); - if (queryExpl->getValue() == 1.0) - return fieldExpl; + // combine them + result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - return result; + if (queryExpl->getValue() == 1.0) { + return fieldExpl; } + + return result; +} + } diff --git a/src/core/search/TermRangeFilter.cpp b/src/core/search/TermRangeFilter.cpp index e1fa9bd5..b214e9a5 100644 --- a/src/core/search/TermRangeFilter.cpp +++ b/src/core/search/TermRangeFilter.cpp @@ -10,56 +10,47 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - TermRangeFilter::TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, - bool includeUpper, CollatorPtr collator) : - MultiTermQueryWrapperFilter(newLucene(fieldName, lowerTerm, upperTerm, - includeLower, includeUpper, collator)) - { - } +namespace Lucene { - TermRangeFilter::~TermRangeFilter() - { - } +TermRangeFilter::TermRangeFilter(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + bool includeUpper, CollatorPtr collator) : + MultiTermQueryWrapperFilter(newLucene(fieldName, lowerTerm, upperTerm, + includeLower, includeUpper, collator)) { +} + +TermRangeFilter::~TermRangeFilter() { +} - TermRangeFilterPtr TermRangeFilter::Less(const String& fieldName, StringValue upperTerm) - { - return newLucene(fieldName, VariantUtils::null(), upperTerm, false, true); - } +TermRangeFilterPtr TermRangeFilter::Less(const String& fieldName, StringValue upperTerm) { + return newLucene(fieldName, VariantUtils::null(), upperTerm, false, true); +} + +TermRangeFilterPtr TermRangeFilter::More(const String& fieldName, StringValue lowerTerm) { + return newLucene(fieldName, lowerTerm, VariantUtils::null(), true, false); +} - TermRangeFilterPtr TermRangeFilter::More(const String& fieldName, StringValue lowerTerm) - { - return newLucene(fieldName, lowerTerm, VariantUtils::null(), true, false); - } +String TermRangeFilter::getField() { + return boost::static_pointer_cast(query)->getField(); +} - String TermRangeFilter::getField() - { - return boost::static_pointer_cast(query)->getField(); - } +String TermRangeFilter::getLowerTerm() { + return boost::static_pointer_cast(query)->getLowerTerm(); +} - String TermRangeFilter::getLowerTerm() - { - return boost::static_pointer_cast(query)->getLowerTerm(); - } +String TermRangeFilter::getUpperTerm() { + return boost::static_pointer_cast(query)->getUpperTerm(); +} - String TermRangeFilter::getUpperTerm() - { - return boost::static_pointer_cast(query)->getUpperTerm(); - } +bool TermRangeFilter::includesLower() { + return boost::static_pointer_cast(query)->includesLower(); +} - bool TermRangeFilter::includesLower() - { - return boost::static_pointer_cast(query)->includesLower(); - } +bool TermRangeFilter::includesUpper() { + return boost::static_pointer_cast(query)->includesUpper(); +} - bool TermRangeFilter::includesUpper() - { - return boost::static_pointer_cast(query)->includesUpper(); - } +CollatorPtr TermRangeFilter::getCollator() { + return boost::static_pointer_cast(query)->getCollator(); +} - CollatorPtr TermRangeFilter::getCollator() - { - return boost::static_pointer_cast(query)->getCollator(); - } } diff --git a/src/core/search/TermRangeQuery.cpp b/src/core/search/TermRangeQuery.cpp index f262bd89..14276cc5 100644 --- a/src/core/search/TermRangeQuery.cpp +++ b/src/core/search/TermRangeQuery.cpp @@ -11,142 +11,140 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - TermRangeQuery::TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, - bool includeUpper, CollatorPtr collator) - { - this->field = fieldName; - this->lowerTerm = lowerTerm; - this->upperTerm = upperTerm; - this->includeLower = includeLower; - this->includeUpper = includeUpper; - this->collator = collator; - } +namespace Lucene { - TermRangeQuery::~TermRangeQuery() - { - } +TermRangeQuery::TermRangeQuery(const String& fieldName, StringValue lowerTerm, StringValue upperTerm, bool includeLower, + bool includeUpper, CollatorPtr collator) { + this->field = fieldName; + this->lowerTerm = lowerTerm; + this->upperTerm = upperTerm; + this->includeLower = includeLower; + this->includeUpper = includeUpper; + this->collator = collator; +} - String TermRangeQuery::getField() - { - return field; - } +TermRangeQuery::~TermRangeQuery() { +} - String TermRangeQuery::getLowerTerm() - { - return VariantUtils::get(lowerTerm); - } +String TermRangeQuery::getField() { + return field; +} - String TermRangeQuery::getUpperTerm() - { - return VariantUtils::get(upperTerm); - } +String TermRangeQuery::getLowerTerm() { + return VariantUtils::get(lowerTerm); +} - bool TermRangeQuery::includesLower() - { - return includeLower; - } +String TermRangeQuery::getUpperTerm() { + return VariantUtils::get(upperTerm); +} - bool TermRangeQuery::includesUpper() - { - return includeUpper; - } +bool TermRangeQuery::includesLower() { + return includeLower; +} - CollatorPtr TermRangeQuery::getCollator() - { - return collator; - } +bool TermRangeQuery::includesUpper() { + return includeUpper; +} - FilteredTermEnumPtr TermRangeQuery::getEnum(const IndexReaderPtr& reader) - { - return newLucene(reader, field, lowerTerm, upperTerm, includeLower, includeUpper, collator); - } +CollatorPtr TermRangeQuery::getCollator() { + return collator; +} - LuceneObjectPtr TermRangeQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, lowerTerm, upperTerm, includeLower, includeUpper, collator)); - TermRangeQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->lowerTerm = lowerTerm; - cloneQuery->upperTerm = upperTerm; - cloneQuery->collator = collator; - cloneQuery->field = field; - cloneQuery->includeLower = includeLower; - cloneQuery->includeUpper = includeUpper; - return cloneQuery; - } +FilteredTermEnumPtr TermRangeQuery::getEnum(const IndexReaderPtr& reader) { + return newLucene(reader, field, lowerTerm, upperTerm, includeLower, includeUpper, collator); +} + +LuceneObjectPtr TermRangeQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(field, lowerTerm, upperTerm, includeLower, includeUpper, collator)); + TermRangeQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->lowerTerm = lowerTerm; + cloneQuery->upperTerm = upperTerm; + cloneQuery->collator = collator; + cloneQuery->field = field; + cloneQuery->includeLower = includeLower; + cloneQuery->includeUpper = includeUpper; + return cloneQuery; +} - String TermRangeQuery::toString(const String& field) - { - StringStream buffer; - if (getField() != field) - buffer << getField() << L":"; - buffer << (includeLower ? L"[" : L"{"); - if (VariantUtils::isNull(lowerTerm)) - buffer << L"*"; - else - buffer << lowerTerm; - buffer << L" TO "; - if (VariantUtils::isNull(upperTerm)) - buffer << L"*"; - else - buffer << upperTerm; - buffer << (includeUpper ? L"]" : L"}"); - buffer << boostString(); - return buffer.str(); +String TermRangeQuery::toString(const String& field) { + StringStream buffer; + if (getField() != field) { + buffer << getField() << L":"; + } + buffer << (includeLower ? L"[" : L"{"); + if (VariantUtils::isNull(lowerTerm)) { + buffer << L"*"; + } else { + buffer << lowerTerm; + } + buffer << L" TO "; + if (VariantUtils::isNull(upperTerm)) { + buffer << L"*"; + } else { + buffer << upperTerm; } + buffer << (includeUpper ? L"]" : L"}"); + buffer << boostString(); + return buffer.str(); +} - bool TermRangeQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!MultiTermQuery::equals(other)) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - TermRangeQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) +bool TermRangeQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!MultiTermQuery::equals(other)) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + TermRangeQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; + } + if (!collator) { + if (otherQuery->collator) { return false; - if (!collator) - { - if (otherQuery->collator) - return false; } - else if (!collator->equals(otherQuery->collator)) - return false; - if (field != otherQuery->field) - return false; - if (includeLower != otherQuery->includeLower) - return false; - if (includeUpper != otherQuery->includeUpper) + } else if (!collator->equals(otherQuery->collator)) { + return false; + } + if (field != otherQuery->field) { + return false; + } + if (includeLower != otherQuery->includeLower) { + return false; + } + if (includeUpper != otherQuery->includeUpper) { + return false; + } + if (VariantUtils::isNull(lowerTerm)) { + if (!VariantUtils::isNull(otherQuery->lowerTerm)) { return false; - if (VariantUtils::isNull(lowerTerm)) - { - if (!VariantUtils::isNull(otherQuery->lowerTerm)) - return false; } - else if (!VariantUtils::equals(lowerTerm, otherQuery->lowerTerm)) + } else if (!VariantUtils::equals(lowerTerm, otherQuery->lowerTerm)) { + return false; + } + if (VariantUtils::isNull(upperTerm)) { + if (!VariantUtils::isNull(otherQuery->upperTerm)) { return false; - if (VariantUtils::isNull(upperTerm)) - { - if (!VariantUtils::isNull(otherQuery->upperTerm)) - return false; } - else if (!VariantUtils::equals(upperTerm, otherQuery->upperTerm)) - return false; - return true; + } else if (!VariantUtils::equals(upperTerm, otherQuery->upperTerm)) { + return false; } + return true; +} + +int32_t TermRangeQuery::hashCode() { + int32_t prime = 31; + int32_t result = MultiTermQuery::hashCode(); + result = prime * result + (collator ? collator->hashCode() : 0); + result = prime * result + (field.empty() ? 0 : StringUtils::hashCode(field)); + result = prime * result + (includeLower ? 1231 : 1237); + result = prime * result + (includeUpper ? 1231 : 1237); + result = prime * result + (VariantUtils::isNull(lowerTerm) ? 0 : StringUtils::hashCode(VariantUtils::get(lowerTerm))); + result = prime * result + (VariantUtils::isNull(upperTerm) ? 0 : StringUtils::hashCode(VariantUtils::get(upperTerm))); + return result; +} - int32_t TermRangeQuery::hashCode() - { - int32_t prime = 31; - int32_t result = MultiTermQuery::hashCode(); - result = prime * result + (collator ? collator->hashCode() : 0); - result = prime * result + (field.empty() ? 0 : StringUtils::hashCode(field)); - result = prime * result + (includeLower ? 1231 : 1237); - result = prime * result + (includeUpper ? 1231 : 1237); - result = prime * result + (VariantUtils::isNull(lowerTerm) ? 0 : StringUtils::hashCode(VariantUtils::get(lowerTerm))); - result = prime * result + (VariantUtils::isNull(upperTerm) ? 0 : StringUtils::hashCode(VariantUtils::get(upperTerm))); - return result; - } } diff --git a/src/core/search/TermRangeTermEnum.cpp b/src/core/search/TermRangeTermEnum.cpp index 465c30fd..077f300a 100644 --- a/src/core/search/TermRangeTermEnum.cpp +++ b/src/core/search/TermRangeTermEnum.cpp @@ -12,93 +12,83 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - TermRangeTermEnum::TermRangeTermEnum(const IndexReaderPtr& reader, const String& field, StringValue lowerTermText, - StringValue upperTermText, bool includeLower, bool includeUpper, const CollatorPtr& collator) - { - this->collator = collator; - this->_endEnum = false; - this->upperTermText = upperTermText; - this->lowerTermText = lowerTermText; - this->includeLower = includeLower; - this->includeUpper = includeUpper; - this->field = field; +namespace Lucene { - // do a little bit of normalization: open ended range queries should always be inclusive. - if (VariantUtils::isNull(this->lowerTermText)) - this->includeLower = true; +TermRangeTermEnum::TermRangeTermEnum(const IndexReaderPtr& reader, const String& field, StringValue lowerTermText, + StringValue upperTermText, bool includeLower, bool includeUpper, const CollatorPtr& collator) { + this->collator = collator; + this->_endEnum = false; + this->upperTermText = upperTermText; + this->lowerTermText = lowerTermText; + this->includeLower = includeLower; + this->includeUpper = includeUpper; + this->field = field; - if (VariantUtils::isNull(this->upperTermText)) - this->includeUpper = true; - - String startTermText(collator ? L"" : VariantUtils::get(this->lowerTermText)); - setEnum(reader->terms(newLucene(this->field, startTermText))); + // do a little bit of normalization: open ended range queries should always be inclusive. + if (VariantUtils::isNull(this->lowerTermText)) { + this->includeLower = true; } - TermRangeTermEnum::~TermRangeTermEnum() - { + if (VariantUtils::isNull(this->upperTermText)) { + this->includeUpper = true; } - double TermRangeTermEnum::difference() - { - return 1.0; - } + String startTermText(collator ? L"" : VariantUtils::get(this->lowerTermText)); + setEnum(reader->terms(newLucene(this->field, startTermText))); +} - bool TermRangeTermEnum::endEnum() - { - return _endEnum; - } +TermRangeTermEnum::~TermRangeTermEnum() { +} + +double TermRangeTermEnum::difference() { + return 1.0; +} - bool TermRangeTermEnum::termCompare(const TermPtr& term) - { - if (!collator) - { - // Use Unicode code point ordering - bool checkLower = false; - if (!includeLower) // make adjustments to set to exclusive - checkLower = true; - if (term && term->field() == field) - { - if (!checkLower || VariantUtils::isNull(lowerTermText) || term->text().compare(VariantUtils::get(lowerTermText)) > 0) - { - checkLower = false; - if (!VariantUtils::isNull(upperTermText)) - { - int32_t compare = VariantUtils::get(upperTermText).compare(term->text()); - // if beyond the upper term, or is exclusive and this is equal to the upper term, break out - if (compare < 0 || (!includeUpper && compare == 0)) - { - _endEnum = true; - return false; - } +bool TermRangeTermEnum::endEnum() { + return _endEnum; +} + +bool TermRangeTermEnum::termCompare(const TermPtr& term) { + if (!collator) { + // Use Unicode code point ordering + bool checkLower = false; + if (!includeLower) { // make adjustments to set to exclusive + checkLower = true; + } + if (term && term->field() == field) { + if (!checkLower || VariantUtils::isNull(lowerTermText) || term->text().compare(VariantUtils::get(lowerTermText)) > 0) { + checkLower = false; + if (!VariantUtils::isNull(upperTermText)) { + int32_t compare = VariantUtils::get(upperTermText).compare(term->text()); + // if beyond the upper term, or is exclusive and this is equal to the upper term, break out + if (compare < 0 || (!includeUpper && compare == 0)) { + _endEnum = true; + return false; } - return true; } + return true; } - else - { - // break - _endEnum = true; - return false; - } + } else { + // break + _endEnum = true; return false; } - else - { - if (term && term->field() == field) - { - if ((VariantUtils::isNull(lowerTermText) || + return false; + } else { + if (term && term->field() == field) { + if ((VariantUtils::isNull(lowerTermText) || (includeLower ? collator->compare(term->text(), VariantUtils::get(lowerTermText)) >= 0 : - collator->compare(term->text(), VariantUtils::get(lowerTermText)) > 0)) && + collator->compare(term->text(), VariantUtils::get(lowerTermText)) > 0)) && (VariantUtils::isNull(upperTermText) || - (includeUpper ? collator->compare(term->text(), VariantUtils::get(upperTermText)) <= 0 : - collator->compare(term->text(), VariantUtils::get(upperTermText)) < 0))) - return true; - return false; + (includeUpper ? collator->compare(term->text(), VariantUtils::get(upperTermText)) <= 0 : + collator->compare(term->text(), VariantUtils::get(upperTermText)) < 0))) { + return true; } - _endEnum = true; return false; } + _endEnum = true; + return false; } } + +} diff --git a/src/core/search/TermScorer.cpp b/src/core/search/TermScorer.cpp index 03856e1a..678da9d6 100644 --- a/src/core/search/TermScorer.cpp +++ b/src/core/search/TermScorer.cpp @@ -11,127 +11,111 @@ #include "Weight.h" #include "Collector.h" -namespace Lucene -{ - const int32_t TermScorer::SCORE_CACHE_SIZE = 32; - - TermScorer::TermScorer(const WeightPtr& weight, const TermDocsPtr& td, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) - { - this->weight = weight; - this->termDocs = td; - this->norms = norms; - this->weightValue = weight->getValue(); - this->doc = -1; - this->docs = Collection::newInstance(32); - this->freqs = Collection::newInstance(32); - this->pointer = 0; - this->pointerMax = 0; - this->scoreCache = Collection::newInstance(SCORE_CACHE_SIZE); - - for (int32_t i = 0; i < SCORE_CACHE_SIZE; ++i) - scoreCache[i] = getSimilarity()->tf(i) * weightValue; - } +namespace Lucene { - TermScorer::~TermScorer() - { - } +const int32_t TermScorer::SCORE_CACHE_SIZE = 32; - const Collection TermScorer::SIM_NORM_DECODER() - { - return Similarity::getNormDecoder(); - } +TermScorer::TermScorer(const WeightPtr& weight, const TermDocsPtr& td, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) { + this->weight = weight; + this->termDocs = td; + this->norms = norms; + this->weightValue = weight->getValue(); + this->doc = -1; + this->docs = Collection::newInstance(32); + this->freqs = Collection::newInstance(32); + this->pointer = 0; + this->pointerMax = 0; + this->scoreCache = Collection::newInstance(SCORE_CACHE_SIZE); - void TermScorer::score(const CollectorPtr& collector) - { - score(collector, INT_MAX, nextDoc()); + for (int32_t i = 0; i < SCORE_CACHE_SIZE; ++i) { + scoreCache[i] = getSimilarity()->tf(i) * weightValue; } +} - bool TermScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) - { - // firstDocID is ignored since nextDoc() sets 'doc' - collector->setScorer(shared_from_this()); - while (doc < max) // for docs in window - { - collector->collect(doc); - - if (++pointer >= pointerMax) - { - pointerMax = termDocs->read(docs, freqs); // refill buffers - if (pointerMax != 0) - pointer = 0; - else - { - termDocs->close(); // close stream - doc = INT_MAX; // set to sentinel value - return false; - } - } - doc = docs[pointer]; - } - return true; - } +TermScorer::~TermScorer() { +} - int32_t TermScorer::docID() - { - return doc; - } +const Collection TermScorer::SIM_NORM_DECODER() { + return Similarity::getNormDecoder(); +} + +void TermScorer::score(const CollectorPtr& collector) { + score(collector, INT_MAX, nextDoc()); +} + +bool TermScorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { + // firstDocID is ignored since nextDoc() sets 'doc' + collector->setScorer(shared_from_this()); + while (doc < max) { // for docs in window + collector->collect(doc); - int32_t TermScorer::nextDoc() - { - ++pointer; - if (pointer >= pointerMax) - { - pointerMax = termDocs->read(docs, freqs); // refill buffer - if (pointerMax != 0) + if (++pointer >= pointerMax) { + pointerMax = termDocs->read(docs, freqs); // refill buffers + if (pointerMax != 0) { pointer = 0; - else - { + } else { termDocs->close(); // close stream - doc = NO_MORE_DOCS; - return doc; + doc = INT_MAX; // set to sentinel value + return false; } } doc = docs[pointer]; - return doc; } + return true; +} - double TermScorer::score() - { - BOOST_ASSERT(doc != -1); - int32_t f = freqs[pointer]; - double raw = f < SCORE_CACHE_SIZE ? scoreCache[f] : getSimilarity()->tf(f) * weightValue; // compute tf(f) * weight - return norms ? raw * SIM_NORM_DECODER()[norms[doc] & 0xff] : raw; // normalize for field - } +int32_t TermScorer::docID() { + return doc; +} - int32_t TermScorer::advance(int32_t target) - { - // first scan in cache - for (++pointer; pointer < pointerMax; ++pointer) - { - if (docs[pointer] >= target) - { - doc = docs[pointer]; - return doc; - } +int32_t TermScorer::nextDoc() { + ++pointer; + if (pointer >= pointerMax) { + pointerMax = termDocs->read(docs, freqs); // refill buffer + if (pointerMax != 0) { + pointer = 0; + } else { + termDocs->close(); // close stream + doc = NO_MORE_DOCS; + return doc; } + } + doc = docs[pointer]; + return doc; +} - // not found in cache, seek underlying stream - bool result = termDocs->skipTo(target); - if (result) - { - pointerMax = 1; - pointer = 0; - doc = termDocs->doc(); - docs[pointer] = doc; - freqs[pointer] = termDocs->freq(); +double TermScorer::score() { + BOOST_ASSERT(doc != -1); + int32_t f = freqs[pointer]; + double raw = f < SCORE_CACHE_SIZE ? scoreCache[f] : getSimilarity()->tf(f) * weightValue; // compute tf(f) * weight + return norms ? raw * SIM_NORM_DECODER()[norms[doc] & 0xff] : raw; // normalize for field +} + +int32_t TermScorer::advance(int32_t target) { + // first scan in cache + for (++pointer; pointer < pointerMax; ++pointer) { + if (docs[pointer] >= target) { + doc = docs[pointer]; + return doc; } - else - doc = NO_MORE_DOCS; - return doc; } - String TermScorer::toString() - { - return L"scorer(" + weight->toString() + L")"; + // not found in cache, seek underlying stream + bool result = termDocs->skipTo(target); + if (result) { + pointerMax = 1; + pointer = 0; + doc = termDocs->doc(); + docs[pointer] = doc; + freqs[pointer] = termDocs->freq(); + } else { + doc = NO_MORE_DOCS; } + return doc; +} + +String TermScorer::toString() { + return L"scorer(" + weight->toString() + L")"; +} + } diff --git a/src/core/search/TimeLimitingCollector.cpp b/src/core/search/TimeLimitingCollector.cpp index 02259255..56f07d47 100644 --- a/src/core/search/TimeLimitingCollector.cpp +++ b/src/core/search/TimeLimitingCollector.cpp @@ -9,137 +9,118 @@ #include "_TimeLimitingCollector.h" #include "StringUtils.h" -namespace Lucene -{ - /// Default timer resolution. - const int32_t TimeLimitingCollector::DEFAULT_RESOLUTION = 20; - - int64_t TimeLimitingCollector::resolution = TimeLimitingCollector::DEFAULT_RESOLUTION; - - TimeLimitingCollector::TimeLimitingCollector(const CollectorPtr& collector, int64_t timeAllowed) - { - this->DEFAULT_GREEDY = false; - this->greedy = DEFAULT_GREEDY; - this->collector = collector; - this->t0 = TIMER_THREAD()->getMilliseconds(); - this->timeout = t0 + timeAllowed; - this->docBase = 0; - } +namespace Lucene { - TimeLimitingCollector::~TimeLimitingCollector() - { - } +/// Default timer resolution. +const int32_t TimeLimitingCollector::DEFAULT_RESOLUTION = 20; - TimerThreadPtr TimeLimitingCollector::TIMER_THREAD() - { - static TimerThreadPtr _TIMER_THREAD; - if (!_TIMER_THREAD) - { - _TIMER_THREAD = newLucene(); - CycleCheck::addStatic(_TIMER_THREAD); - } - if (!_TIMER_THREAD->isAlive()) - _TIMER_THREAD->start(); // start single thread instance - return _TIMER_THREAD; - } +int64_t TimeLimitingCollector::resolution = TimeLimitingCollector::DEFAULT_RESOLUTION; - int64_t TimeLimitingCollector::getResolution() - { - return resolution; - } +TimeLimitingCollector::TimeLimitingCollector(const CollectorPtr& collector, int64_t timeAllowed) { + this->DEFAULT_GREEDY = false; + this->greedy = DEFAULT_GREEDY; + this->collector = collector; + this->t0 = TIMER_THREAD()->getMilliseconds(); + this->timeout = t0 + timeAllowed; + this->docBase = 0; +} - void TimeLimitingCollector::setResolution(int64_t newResolution) - { - resolution = std::max(newResolution, (int64_t)5); // 5 milliseconds is about the minimum reasonable time for a wait call. - } +TimeLimitingCollector::~TimeLimitingCollector() { +} - void TimeLimitingCollector::stopTimer() - { - if (TIMER_THREAD()->isAlive()) - { - TIMER_THREAD()->stopThread(); - TIMER_THREAD()->join(); - } +TimerThreadPtr TimeLimitingCollector::TIMER_THREAD() { + static TimerThreadPtr _TIMER_THREAD; + if (!_TIMER_THREAD) { + _TIMER_THREAD = newLucene(); + CycleCheck::addStatic(_TIMER_THREAD); } - - bool TimeLimitingCollector::isGreedy() - { - return greedy; + if (!_TIMER_THREAD->isAlive()) { + _TIMER_THREAD->start(); // start single thread instance } + return _TIMER_THREAD; +} + +int64_t TimeLimitingCollector::getResolution() { + return resolution; +} + +void TimeLimitingCollector::setResolution(int64_t newResolution) { + resolution = std::max(newResolution, (int64_t)5); // 5 milliseconds is about the minimum reasonable time for a wait call. +} - void TimeLimitingCollector::setGreedy(bool greedy) - { - this->greedy = greedy; +void TimeLimitingCollector::stopTimer() { + if (TIMER_THREAD()->isAlive()) { + TIMER_THREAD()->stopThread(); + TIMER_THREAD()->join(); } +} - void TimeLimitingCollector::collect(int32_t doc) - { - int64_t time = TIMER_THREAD()->getMilliseconds(); - if (timeout < time) - { - if (greedy) - collector->collect(doc); - boost::throw_exception(TimeExceededException(L"Elapsed time:" + StringUtils::toString(timeout - t0) + L" ms. " + - L"Exceeded allowed search time:" + StringUtils::toString(time - t0) + L" ms. " + - L"Last doc:" + StringUtils::toString(docBase + doc))); +bool TimeLimitingCollector::isGreedy() { + return greedy; +} + +void TimeLimitingCollector::setGreedy(bool greedy) { + this->greedy = greedy; +} + +void TimeLimitingCollector::collect(int32_t doc) { + int64_t time = TIMER_THREAD()->getMilliseconds(); + if (timeout < time) { + if (greedy) { + collector->collect(doc); } - collector->collect(doc); + boost::throw_exception(TimeExceededException(L"Elapsed time:" + StringUtils::toString(timeout - t0) + L" ms. " + + L"Exceeded allowed search time:" + StringUtils::toString(time - t0) + L" ms. " + + L"Last doc:" + StringUtils::toString(docBase + doc))); } + collector->collect(doc); +} - void TimeLimitingCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - collector->setNextReader(reader, docBase); - this->docBase = docBase; - } +void TimeLimitingCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + collector->setNextReader(reader, docBase); + this->docBase = docBase; +} - void TimeLimitingCollector::setScorer(const ScorerPtr& scorer) - { - collector->setScorer(scorer); - } +void TimeLimitingCollector::setScorer(const ScorerPtr& scorer) { + collector->setScorer(scorer); +} - bool TimeLimitingCollector::acceptsDocsOutOfOrder() - { - return collector->acceptsDocsOutOfOrder(); - } +bool TimeLimitingCollector::acceptsDocsOutOfOrder() { + return collector->acceptsDocsOutOfOrder(); +} - TimerThread::TimerThread() - { - time = 0; - _stopThread = false; - } +TimerThread::TimerThread() { + time = 0; + _stopThread = false; +} - TimerThread::~TimerThread() - { - } +TimerThread::~TimerThread() { +} - void TimerThread::start() - { - _stopThread = false; - LuceneThread::start(); - } +void TimerThread::start() { + _stopThread = false; + LuceneThread::start(); +} - void TimerThread::run() - { - while (!_stopThread) +void TimerThread::run() { + while (!_stopThread) { + int64_t resolution; { - int64_t resolution; - { - SyncLock syncLock(this); - resolution = TimeLimitingCollector::resolution; - time += resolution; - } - LuceneThread::threadSleep(resolution); + SyncLock syncLock(this); + resolution = TimeLimitingCollector::resolution; + time += resolution; } + LuceneThread::threadSleep(resolution); } +} - int64_t TimerThread::getMilliseconds() - { - SyncLock syncLock(this); - return time; - } +int64_t TimerThread::getMilliseconds() { + SyncLock syncLock(this); + return time; +} + +void TimerThread::stopThread() { + _stopThread = true; +} - void TimerThread::stopThread() - { - _stopThread = true; - } } diff --git a/src/core/search/TopDocs.cpp b/src/core/search/TopDocs.cpp index 83a88a75..75a3e4be 100644 --- a/src/core/search/TopDocs.cpp +++ b/src/core/search/TopDocs.cpp @@ -7,33 +7,29 @@ #include "LuceneInc.h" #include "TopDocs.h" -namespace Lucene -{ - TopDocs::TopDocs(int32_t totalHits, Collection scoreDocs) - { - this->totalHits = totalHits; - this->scoreDocs = scoreDocs; - this->maxScore = std::numeric_limits::quiet_NaN(); - } - - TopDocs::TopDocs(int32_t totalHits, Collection scoreDocs, double maxScore) - { - this->totalHits = totalHits; - this->scoreDocs = scoreDocs; - this->maxScore = maxScore; - } - - TopDocs::~TopDocs() - { - } - - double TopDocs::getMaxScore() - { - return maxScore; - } - - void TopDocs::setMaxScore(double maxScore) - { - this->maxScore = maxScore; - } +namespace Lucene { + +TopDocs::TopDocs(int32_t totalHits, Collection scoreDocs) { + this->totalHits = totalHits; + this->scoreDocs = scoreDocs; + this->maxScore = std::numeric_limits::quiet_NaN(); +} + +TopDocs::TopDocs(int32_t totalHits, Collection scoreDocs, double maxScore) { + this->totalHits = totalHits; + this->scoreDocs = scoreDocs; + this->maxScore = maxScore; +} + +TopDocs::~TopDocs() { +} + +double TopDocs::getMaxScore() { + return maxScore; +} + +void TopDocs::setMaxScore(double maxScore) { + this->maxScore = maxScore; +} + } diff --git a/src/core/search/TopDocsCollector.cpp b/src/core/search/TopDocsCollector.cpp index e519323a..6c95a096 100644 --- a/src/core/search/TopDocsCollector.cpp +++ b/src/core/search/TopDocsCollector.cpp @@ -9,84 +9,78 @@ #include "TopDocs.h" #include "HitQueueBase.h" -namespace Lucene -{ - TopDocsCollector::TopDocsCollector(const HitQueueBasePtr& pq) - { - this->pq = pq; - this->totalHits = 0; - } - - TopDocsCollector::~TopDocsCollector() - { - } +namespace Lucene { - TopDocsPtr TopDocsCollector::EMPTY_TOPDOCS() - { - static TopDocsPtr _EMPTY_TOPDOCS; - if (!_EMPTY_TOPDOCS) - { - _EMPTY_TOPDOCS = newLucene(0, Collection::newInstance(), std::numeric_limits::quiet_NaN()); - CycleCheck::addStatic(_EMPTY_TOPDOCS); - } - return _EMPTY_TOPDOCS; - } +TopDocsCollector::TopDocsCollector(const HitQueueBasePtr& pq) { + this->pq = pq; + this->totalHits = 0; +} - void TopDocsCollector::populateResults(Collection results, int32_t howMany) - { - for (int32_t i = howMany - 1; i >= 0; --i) - results[i] = pq->pop(); - } +TopDocsCollector::~TopDocsCollector() { +} - TopDocsPtr TopDocsCollector::newTopDocs(Collection results, int32_t start) - { - return results ? newLucene(totalHits, results) : EMPTY_TOPDOCS(); +TopDocsPtr TopDocsCollector::EMPTY_TOPDOCS() { + static TopDocsPtr _EMPTY_TOPDOCS; + if (!_EMPTY_TOPDOCS) { + _EMPTY_TOPDOCS = newLucene(0, Collection::newInstance(), std::numeric_limits::quiet_NaN()); + CycleCheck::addStatic(_EMPTY_TOPDOCS); } + return _EMPTY_TOPDOCS; +} - int32_t TopDocsCollector::getTotalHits() - { - return totalHits; +void TopDocsCollector::populateResults(Collection results, int32_t howMany) { + for (int32_t i = howMany - 1; i >= 0; --i) { + results[i] = pq->pop(); } +} - TopDocsPtr TopDocsCollector::topDocs() - { - // In case pq was populated with sentinel values, there might be less results than pq.size(). - // Therefore return all results until either pq.size() or totalHits. - return topDocs(0, totalHits < pq->size() ? totalHits : pq->size()); - } +TopDocsPtr TopDocsCollector::newTopDocs(Collection results, int32_t start) { + return results ? newLucene(totalHits, results) : EMPTY_TOPDOCS(); +} - TopDocsPtr TopDocsCollector::topDocs(int32_t start) - { - // In case pq was populated with sentinel values, there might be less results than pq.size(). - // Therefore return all results until either pq.size() or totalHits. - return topDocs(start, totalHits < pq->size() ? totalHits : pq->size()); - } +int32_t TopDocsCollector::getTotalHits() { + return totalHits; +} - TopDocsPtr TopDocsCollector::topDocs(int32_t start, int32_t howMany) - { - // In case pq was populated with sentinel values, there might be less results than pq.size(). - // Therefore return all results until either pq.size() or totalHits. - int32_t size = totalHits < pq->size() ? totalHits : pq->size(); +TopDocsPtr TopDocsCollector::topDocs() { + // In case pq was populated with sentinel values, there might be less results than pq.size(). + // Therefore return all results until either pq.size() or totalHits. + return topDocs(0, totalHits < pq->size() ? totalHits : pq->size()); +} - // Don't bother to throw an exception, just return an empty TopDocs in case the parameters are - // invalid or out of range. - if (start < 0 || start >= size || howMany <= 0) - return newTopDocs(Collection(), start); +TopDocsPtr TopDocsCollector::topDocs(int32_t start) { + // In case pq was populated with sentinel values, there might be less results than pq.size(). + // Therefore return all results until either pq.size() or totalHits. + return topDocs(start, totalHits < pq->size() ? totalHits : pq->size()); +} - // We know that start < pq.size, so just fix howMany. - howMany = std::min(size - start, howMany); - Collection results = Collection::newInstance(howMany); +TopDocsPtr TopDocsCollector::topDocs(int32_t start, int32_t howMany) { + // In case pq was populated with sentinel values, there might be less results than pq.size(). + // Therefore return all results until either pq.size() or totalHits. + int32_t size = totalHits < pq->size() ? totalHits : pq->size(); - // pq's pop() returns the 'least' element in the queue, therefore need to discard the first ones, - // until we reach the requested range. Note that this loop will usually not be executed, since the - // common usage should be that the caller asks for the last howMany results. However it's needed - // here for completeness. - for (int32_t i = pq->size() - start - howMany; i > 0; --i) - pq->pop(); + // Don't bother to throw an exception, just return an empty TopDocs in case the parameters are + // invalid or out of range. + if (start < 0 || start >= size || howMany <= 0) { + return newTopDocs(Collection(), start); + } - // Get the requested results from pq. - populateResults(results, howMany); + // We know that start < pq.size, so just fix howMany. + howMany = std::min(size - start, howMany); + Collection results = Collection::newInstance(howMany); - return newTopDocs(results, start); + // pq's pop() returns the 'least' element in the queue, therefore need to discard the first ones, + // until we reach the requested range. Note that this loop will usually not be executed, since the + // common usage should be that the caller asks for the last howMany results. However it's needed + // here for completeness. + for (int32_t i = pq->size() - start - howMany; i > 0; --i) { + pq->pop(); } + + // Get the requested results from pq. + populateResults(results, howMany); + + return newTopDocs(results, start); +} + } diff --git a/src/core/search/TopFieldCollector.cpp b/src/core/search/TopFieldCollector.cpp index a1b09330..cc7efc26 100644 --- a/src/core/search/TopFieldCollector.cpp +++ b/src/core/search/TopFieldCollector.cpp @@ -14,889 +14,773 @@ #include "Sort.h" #include "TopFieldDocs.h" -namespace Lucene -{ - TopFieldCollector::TopFieldCollector(const HitQueueBasePtr& pq, int32_t numHits, bool fillFields) : TopDocsCollector(pq) - { - this->numHits = numHits; - this->fillFields = fillFields; - this->maxScore = std::numeric_limits::quiet_NaN(); - this->queueFull = false; - this->docBase = 0; - } +namespace Lucene { + +TopFieldCollector::TopFieldCollector(const HitQueueBasePtr& pq, int32_t numHits, bool fillFields) : TopDocsCollector(pq) { + this->numHits = numHits; + this->fillFields = fillFields; + this->maxScore = std::numeric_limits::quiet_NaN(); + this->queueFull = false; + this->docBase = 0; +} + +TopFieldCollector::~TopFieldCollector() { +} - TopFieldCollector::~TopFieldCollector() - { +const Collection TopFieldCollector::EMPTY_SCOREDOCS() { + static Collection _EMPTY_SCOREDOCS; + if (!_EMPTY_SCOREDOCS) { + _EMPTY_SCOREDOCS = Collection::newInstance(); } + return _EMPTY_SCOREDOCS; +} - const Collection TopFieldCollector::EMPTY_SCOREDOCS() - { - static Collection _EMPTY_SCOREDOCS; - if (!_EMPTY_SCOREDOCS) - _EMPTY_SCOREDOCS = Collection::newInstance(); - return _EMPTY_SCOREDOCS; +TopFieldCollectorPtr TopFieldCollector::create(const SortPtr& sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder) { + if (sort->fields.empty()) { + boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); } - TopFieldCollectorPtr TopFieldCollector::create(const SortPtr& sort, int32_t numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder) - { - if (sort->fields.empty()) - boost::throw_exception(IllegalArgumentException(L"Sort must contain at least one field")); - - FieldValueHitQueuePtr queue(FieldValueHitQueue::create(sort->fields, numHits)); - if (queue->getComparators().size() == 1) - { - if (docsScoredInOrder) - { - if (trackMaxScore) - return newLucene(queue, numHits, fillFields); - else if (trackDocScores) - return newLucene(queue, numHits, fillFields); - else - return newLucene(queue, numHits, fillFields); + FieldValueHitQueuePtr queue(FieldValueHitQueue::create(sort->fields, numHits)); + if (queue->getComparators().size() == 1) { + if (docsScoredInOrder) { + if (trackMaxScore) { + return newLucene(queue, numHits, fillFields); + } else if (trackDocScores) { + return newLucene(queue, numHits, fillFields); + } else { + return newLucene(queue, numHits, fillFields); } - else - { - if (trackMaxScore) - return newLucene(queue, numHits, fillFields); - else if (trackDocScores) - return newLucene(queue, numHits, fillFields); - else - return newLucene(queue, numHits, fillFields); + } else { + if (trackMaxScore) { + return newLucene(queue, numHits, fillFields); + } else if (trackDocScores) { + return newLucene(queue, numHits, fillFields); + } else { + return newLucene(queue, numHits, fillFields); } } + } - // multiple comparators - if (docsScoredInOrder) - { - if (trackMaxScore) - return newLucene(queue, numHits, fillFields); - else if (trackDocScores) - return newLucene(queue, numHits, fillFields); - else - return newLucene(queue, numHits, fillFields); - } - else - { - if (trackMaxScore) - return newLucene(queue, numHits, fillFields); - else if (trackDocScores) - return newLucene(queue, numHits, fillFields); - else - return newLucene(queue, numHits, fillFields); + // multiple comparators + if (docsScoredInOrder) { + if (trackMaxScore) { + return newLucene(queue, numHits, fillFields); + } else if (trackDocScores) { + return newLucene(queue, numHits, fillFields); + } else { + return newLucene(queue, numHits, fillFields); + } + } else { + if (trackMaxScore) { + return newLucene(queue, numHits, fillFields); + } else if (trackDocScores) { + return newLucene(queue, numHits, fillFields); + } else { + return newLucene(queue, numHits, fillFields); } } +} - void TopFieldCollector::add(int32_t slot, int32_t doc, double score) - { - bottom = boost::static_pointer_cast(pq->add(newLucene(slot, docBase + doc, score))); - queueFull = (totalHits == numHits); - } +void TopFieldCollector::add(int32_t slot, int32_t doc, double score) { + bottom = boost::static_pointer_cast(pq->add(newLucene(slot, docBase + doc, score))); + queueFull = (totalHits == numHits); +} - void TopFieldCollector::populateResults(Collection results, int32_t howMany) - { - if (fillFields) - { - FieldValueHitQueuePtr queue(boost::static_pointer_cast(pq)); - for (int32_t i = howMany - 1; i >= 0; --i) - results[i] = queue->fillFields(boost::static_pointer_cast(queue->pop())); - } - else - { - for (int32_t i = howMany - 1; i >= 0; --i) - { - FieldValueHitQueueEntryPtr entry(boost::static_pointer_cast(pq->pop())); - results[i] = newLucene(entry->doc, entry->score); - } +void TopFieldCollector::populateResults(Collection results, int32_t howMany) { + if (fillFields) { + FieldValueHitQueuePtr queue(boost::static_pointer_cast(pq)); + for (int32_t i = howMany - 1; i >= 0; --i) { + results[i] = queue->fillFields(boost::static_pointer_cast(queue->pop())); } - } - - TopDocsPtr TopFieldCollector::newTopDocs(Collection results, int32_t start) - { - if (!results) - { - results = EMPTY_SCOREDOCS(); - // Set maxScore to NaN, in case this is a maxScore tracking collector - maxScore = std::numeric_limits::quiet_NaN(); + } else { + for (int32_t i = howMany - 1; i >= 0; --i) { + FieldValueHitQueueEntryPtr entry(boost::static_pointer_cast(pq->pop())); + results[i] = newLucene(entry->doc, entry->score); } - - // If this is a maxScoring tracking collector and there were no results - return newLucene(totalHits, results, boost::static_pointer_cast(pq)->getFields(), maxScore); } +} - bool TopFieldCollector::acceptsDocsOutOfOrder() - { - return false; +TopDocsPtr TopFieldCollector::newTopDocs(Collection results, int32_t start) { + if (!results) { + results = EMPTY_SCOREDOCS(); + // Set maxScore to NaN, in case this is a maxScore tracking collector + maxScore = std::numeric_limits::quiet_NaN(); } - OneComparatorNonScoringCollector::OneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) - { - } + // If this is a maxScoring tracking collector and there were no results + return newLucene(totalHits, results, boost::static_pointer_cast(pq)->getFields(), maxScore); +} - OneComparatorNonScoringCollector::~OneComparatorNonScoringCollector() - { - } +bool TopFieldCollector::acceptsDocsOutOfOrder() { + return false; +} - void OneComparatorNonScoringCollector::initialize() - { - TopFieldCollector::initialize(); - FieldValueHitQueuePtr queue(boost::static_pointer_cast(pq)); - comparator = queue->getComparators()[0]; - reverseMul = queue->getReverseMul()[0]; - } +OneComparatorNonScoringCollector::OneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) { +} - void OneComparatorNonScoringCollector::updateBottom(int32_t doc) - { - // bottom.score is already set to NaN in add(). - bottom->doc = docBase + doc; - bottom = boost::static_pointer_cast(pq->updateTop()); - } +OneComparatorNonScoringCollector::~OneComparatorNonScoringCollector() { +} - void OneComparatorNonScoringCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - if ((reverseMul * comparator->compareBottom(doc)) <= 0) - { - // since docs are visited in doc Id order, if compare is 0, it means this document is largest - // than anything else in the queue, and therefore not competitive. - return; - } +void OneComparatorNonScoringCollector::initialize() { + TopFieldCollector::initialize(); + FieldValueHitQueuePtr queue(boost::static_pointer_cast(pq)); + comparator = queue->getComparators()[0]; + reverseMul = queue->getReverseMul()[0]; +} - // This hit is competitive - replace bottom element in queue and adjustTop - comparator->copy(bottom->slot, doc); - updateBottom(doc); - comparator->setBottom(bottom->slot); +void OneComparatorNonScoringCollector::updateBottom(int32_t doc) { + // bottom.score is already set to NaN in add(). + bottom->doc = docBase + doc; + bottom = boost::static_pointer_cast(pq->updateTop()); +} + +void OneComparatorNonScoringCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + if ((reverseMul * comparator->compareBottom(doc)) <= 0) { + // since docs are visited in doc Id order, if compare is 0, it means this document is largest + // than anything else in the queue, and therefore not competitive. + return; } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - comparator->copy(slot, doc); - add(slot, doc, std::numeric_limits::quiet_NaN()); - if (queueFull) - comparator->setBottom(bottom->slot); + + // This hit is competitive - replace bottom element in queue and adjustTop + comparator->copy(bottom->slot, doc); + updateBottom(doc); + comparator->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + comparator->copy(slot, doc); + add(slot, doc, std::numeric_limits::quiet_NaN()); + if (queueFull) { + comparator->setBottom(bottom->slot); } } +} - void OneComparatorNonScoringCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - this->docBase = docBase; - comparator->setNextReader(reader, docBase); - } +void OneComparatorNonScoringCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + this->docBase = docBase; + comparator->setNextReader(reader, docBase); +} - void OneComparatorNonScoringCollector::setScorer(const ScorerPtr& scorer) - { - comparator->setScorer(scorer); - } +void OneComparatorNonScoringCollector::setScorer(const ScorerPtr& scorer) { + comparator->setScorer(scorer); +} - OutOfOrderOneComparatorNonScoringCollector::OutOfOrderOneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) - { - } +OutOfOrderOneComparatorNonScoringCollector::OutOfOrderOneComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { +} - OutOfOrderOneComparatorNonScoringCollector::~OutOfOrderOneComparatorNonScoringCollector() - { - } +OutOfOrderOneComparatorNonScoringCollector::~OutOfOrderOneComparatorNonScoringCollector() { +} - void OutOfOrderOneComparatorNonScoringCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - int32_t cmp = reverseMul * comparator->compareBottom(doc); - if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) - return; +void OutOfOrderOneComparatorNonScoringCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + int32_t cmp = reverseMul * comparator->compareBottom(doc); + if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) { + return; + } - // This hit is competitive - replace bottom element in queue and adjustTop - comparator->copy(bottom->slot, doc); - updateBottom(doc); + // This hit is competitive - replace bottom element in queue and adjustTop + comparator->copy(bottom->slot, doc); + updateBottom(doc); + comparator->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + comparator->copy(slot, doc); + add(slot, doc, std::numeric_limits::quiet_NaN()); + if (queueFull) { comparator->setBottom(bottom->slot); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - comparator->copy(slot, doc); - add(slot, doc, std::numeric_limits::quiet_NaN()); - if (queueFull) - comparator->setBottom(bottom->slot); - } } +} - bool OutOfOrderOneComparatorNonScoringCollector::acceptsDocsOutOfOrder() - { - return true; - } +bool OutOfOrderOneComparatorNonScoringCollector::acceptsDocsOutOfOrder() { + return true; +} - OneComparatorScoringNoMaxScoreCollector::OneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) - { - } +OneComparatorScoringNoMaxScoreCollector::OneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { +} - OneComparatorScoringNoMaxScoreCollector::~OneComparatorScoringNoMaxScoreCollector() - { - } +OneComparatorScoringNoMaxScoreCollector::~OneComparatorScoringNoMaxScoreCollector() { +} - void OneComparatorScoringNoMaxScoreCollector::updateBottom(int32_t doc, double score) - { - bottom->doc = docBase + doc; - bottom->score = score; - bottom = boost::static_pointer_cast(pq->updateTop()); - } +void OneComparatorScoringNoMaxScoreCollector::updateBottom(int32_t doc, double score) { + bottom->doc = docBase + doc; + bottom->score = score; + bottom = boost::static_pointer_cast(pq->updateTop()); +} - void OneComparatorScoringNoMaxScoreCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - if ((reverseMul * comparator->compareBottom(doc)) <= 0) - { - // since docs are visited in doc Id order, if compare is 0, it means this document is largest - // than anything else in the queue, and therefore not competitive. - return; - } +void OneComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + if ((reverseMul * comparator->compareBottom(doc)) <= 0) { + // since docs are visited in doc Id order, if compare is 0, it means this document is largest + // than anything else in the queue, and therefore not competitive. + return; + } - // Compute the score only if the hit is competitive. - double score = scorer->score(); + // Compute the score only if the hit is competitive. + double score = scorer->score(); - // This hit is competitive - replace bottom element in queue and adjustTop - comparator->copy(bottom->slot, doc); - updateBottom(doc, score); - comparator->setBottom(bottom->slot); - } - else - { - // Compute the score only if the hit is competitive. - double score = scorer->score(); + // This hit is competitive - replace bottom element in queue and adjustTop + comparator->copy(bottom->slot, doc); + updateBottom(doc, score); + comparator->setBottom(bottom->slot); + } else { + // Compute the score only if the hit is competitive. + double score = scorer->score(); - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - comparator->copy(slot, doc); - add(slot, doc, score); - if (queueFull) - comparator->setBottom(bottom->slot); + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + comparator->copy(slot, doc); + add(slot, doc, score); + if (queueFull) { + comparator->setBottom(bottom->slot); } } +} - void OneComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - comparator->setScorer(scorer); - } +void OneComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + comparator->setScorer(scorer); +} - OutOfOrderOneComparatorScoringNoMaxScoreCollector::OutOfOrderOneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) - { - } +OutOfOrderOneComparatorScoringNoMaxScoreCollector::OutOfOrderOneComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) { +} - OutOfOrderOneComparatorScoringNoMaxScoreCollector::~OutOfOrderOneComparatorScoringNoMaxScoreCollector() - { - } +OutOfOrderOneComparatorScoringNoMaxScoreCollector::~OutOfOrderOneComparatorScoringNoMaxScoreCollector() { +} - void OutOfOrderOneComparatorScoringNoMaxScoreCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - int32_t cmp = reverseMul * comparator->compareBottom(doc); - if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) - return; +void OutOfOrderOneComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + int32_t cmp = reverseMul * comparator->compareBottom(doc); + if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) { + return; + } - // Compute the score only if the hit is competitive. - double score = scorer->score(); + // Compute the score only if the hit is competitive. + double score = scorer->score(); - // This hit is competitive - replace bottom element in queue and adjustTop - comparator->copy(bottom->slot, doc); - updateBottom(doc, score); - comparator->setBottom(bottom->slot); - } - else - { - // Compute the score only if the hit is competitive. - double score = scorer->score(); + // This hit is competitive - replace bottom element in queue and adjustTop + comparator->copy(bottom->slot, doc); + updateBottom(doc, score); + comparator->setBottom(bottom->slot); + } else { + // Compute the score only if the hit is competitive. + double score = scorer->score(); - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - comparator->copy(slot, doc); - add(slot, doc, score); - if (queueFull) - comparator->setBottom(bottom->slot); + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + comparator->copy(slot, doc); + add(slot, doc, score); + if (queueFull) { + comparator->setBottom(bottom->slot); } } +} - bool OutOfOrderOneComparatorScoringNoMaxScoreCollector::acceptsDocsOutOfOrder() - { - return true; - } +bool OutOfOrderOneComparatorScoringNoMaxScoreCollector::acceptsDocsOutOfOrder() { + return true; +} - OneComparatorScoringMaxScoreCollector::OneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) - { - // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. - this->maxScore = -std::numeric_limits::infinity(); - } +OneComparatorScoringMaxScoreCollector::OneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorNonScoringCollector(queue, numHits, fillFields) { + // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. + this->maxScore = -std::numeric_limits::infinity(); +} - OneComparatorScoringMaxScoreCollector::~OneComparatorScoringMaxScoreCollector() - { - } +OneComparatorScoringMaxScoreCollector::~OneComparatorScoringMaxScoreCollector() { +} - void OneComparatorScoringMaxScoreCollector::updateBottom(int32_t doc, double score) - { - bottom->doc = docBase + doc; - bottom->score = score; - bottom = boost::static_pointer_cast(pq->updateTop()); - } +void OneComparatorScoringMaxScoreCollector::updateBottom(int32_t doc, double score) { + bottom->doc = docBase + doc; + bottom->score = score; + bottom = boost::static_pointer_cast(pq->updateTop()); +} - void OneComparatorScoringMaxScoreCollector::collect(int32_t doc) - { - double score = scorer->score(); - if (score > maxScore) - maxScore = score; - ++totalHits; - if (queueFull) - { - if ((reverseMul * comparator->compareBottom(doc)) <= 0) - { - // since docs are visited in doc Id order, if compare is 0, it means this document is largest - // than anything else in the queue, and therefore not competitive. - return; - } +void OneComparatorScoringMaxScoreCollector::collect(int32_t doc) { + double score = scorer->score(); + if (score > maxScore) { + maxScore = score; + } + ++totalHits; + if (queueFull) { + if ((reverseMul * comparator->compareBottom(doc)) <= 0) { + // since docs are visited in doc Id order, if compare is 0, it means this document is largest + // than anything else in the queue, and therefore not competitive. + return; + } - // This hit is competitive - replace bottom element in queue and adjustTop - comparator->copy(bottom->slot, doc); - updateBottom(doc, score); + // This hit is competitive - replace bottom element in queue and adjustTop + comparator->copy(bottom->slot, doc); + updateBottom(doc, score); + comparator->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + comparator->copy(slot, doc); + add(slot, doc, score); + if (queueFull) { comparator->setBottom(bottom->slot); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - comparator->copy(slot, doc); - add(slot, doc, score); - if (queueFull) - comparator->setBottom(bottom->slot); - } } +} - void OneComparatorScoringMaxScoreCollector::setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - OneComparatorNonScoringCollector::setScorer(scorer); - } +void OneComparatorScoringMaxScoreCollector::setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + OneComparatorNonScoringCollector::setScorer(scorer); +} - OutOfOrderOneComparatorScoringMaxScoreCollector::OutOfOrderOneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorScoringMaxScoreCollector(queue, numHits, fillFields) - { - } +OutOfOrderOneComparatorScoringMaxScoreCollector::OutOfOrderOneComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : OneComparatorScoringMaxScoreCollector(queue, numHits, fillFields) { +} - OutOfOrderOneComparatorScoringMaxScoreCollector::~OutOfOrderOneComparatorScoringMaxScoreCollector() - { - } +OutOfOrderOneComparatorScoringMaxScoreCollector::~OutOfOrderOneComparatorScoringMaxScoreCollector() { +} - void OutOfOrderOneComparatorScoringMaxScoreCollector::collect(int32_t doc) - { - double score = scorer->score(); - if (score > maxScore) - maxScore = score; - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - int32_t cmp = reverseMul * comparator->compareBottom(doc); - if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) - return; +void OutOfOrderOneComparatorScoringMaxScoreCollector::collect(int32_t doc) { + double score = scorer->score(); + if (score > maxScore) { + maxScore = score; + } + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + int32_t cmp = reverseMul * comparator->compareBottom(doc); + if (cmp < 0 || (cmp == 0 && doc + docBase > bottom->doc)) { + return; + } - // This hit is competitive - replace bottom element in queue and adjustTop - comparator->copy(bottom->slot, doc); - updateBottom(doc, score); + // This hit is competitive - replace bottom element in queue and adjustTop + comparator->copy(bottom->slot, doc); + updateBottom(doc, score); + comparator->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + comparator->copy(slot, doc); + add(slot, doc, score); + if (queueFull) { comparator->setBottom(bottom->slot); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - comparator->copy(slot, doc); - add(slot, doc, score); - if (queueFull) - comparator->setBottom(bottom->slot); - } } +} - bool OutOfOrderOneComparatorScoringMaxScoreCollector::acceptsDocsOutOfOrder() - { - return true; - } +bool OutOfOrderOneComparatorScoringMaxScoreCollector::acceptsDocsOutOfOrder() { + return true; +} - MultiComparatorNonScoringCollector::MultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) - { - } +MultiComparatorNonScoringCollector::MultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : TopFieldCollector(queue, numHits, fillFields) { +} - MultiComparatorNonScoringCollector::~MultiComparatorNonScoringCollector() - { - } +MultiComparatorNonScoringCollector::~MultiComparatorNonScoringCollector() { +} - void MultiComparatorNonScoringCollector::initialize() - { - TopFieldCollector::initialize(); - FieldValueHitQueuePtr queue(boost::static_pointer_cast(pq)); - comparators = queue->getComparators(); - reverseMul = queue->getReverseMul(); - } +void MultiComparatorNonScoringCollector::initialize() { + TopFieldCollector::initialize(); + FieldValueHitQueuePtr queue(boost::static_pointer_cast(pq)); + comparators = queue->getComparators(); + reverseMul = queue->getReverseMul(); +} - void MultiComparatorNonScoringCollector::updateBottom(int32_t doc) - { - // bottom.score is already set to NaN in add(). - bottom->doc = docBase + doc; - bottom = boost::static_pointer_cast(pq->updateTop()); - } +void MultiComparatorNonScoringCollector::updateBottom(int32_t doc) { + // bottom.score is already set to NaN in add(). + bottom->doc = docBase + doc; + bottom = boost::static_pointer_cast(pq->updateTop()); +} - void MultiComparatorNonScoringCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - for (int32_t i = 0; ; ++i) - { - int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); - if (c < 0) - { - // Definitely not competitive. - return; - } - else if (c > 0) - { - // Definitely competitive. - break; - } - else if (i == comparators.size() - 1) - { - // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are - // visited in doc Id order, which means this doc cannot compete with any other document - // in the queue. - return; - } +void MultiComparatorNonScoringCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + for (int32_t i = 0; ; ++i) { + int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); + if (c < 0) { + // Definitely not competitive. + return; + } else if (c > 0) { + // Definitely competitive. + break; + } else if (i == comparators.size() - 1) { + // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are + // visited in doc Id order, which means this doc cannot compete with any other document + // in the queue. + return; } + } - // This hit is competitive - replace bottom element in queue and adjustTop - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(bottom->slot, doc); + // This hit is competitive - replace bottom element in queue and adjustTop + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(bottom->slot, doc); + } - updateBottom(doc); + updateBottom(doc); - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(slot, doc); - add(slot, doc, std::numeric_limits::quiet_NaN()); - if (queueFull) - { - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(slot, doc); + } + add(slot, doc, std::numeric_limits::quiet_NaN()); + if (queueFull) { + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } } } +} - void MultiComparatorNonScoringCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - this->docBase = docBase; - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setNextReader(reader, docBase); +void MultiComparatorNonScoringCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + this->docBase = docBase; + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setNextReader(reader, docBase); } +} - void MultiComparatorNonScoringCollector::setScorer(const ScorerPtr& scorer) - { - // set the scorer on all comparators - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setScorer(scorer); +void MultiComparatorNonScoringCollector::setScorer(const ScorerPtr& scorer) { + // set the scorer on all comparators + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setScorer(scorer); } +} - OutOfOrderMultiComparatorNonScoringCollector::OutOfOrderMultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) - { - } +OutOfOrderMultiComparatorNonScoringCollector::OutOfOrderMultiComparatorNonScoringCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { +} - OutOfOrderMultiComparatorNonScoringCollector::~OutOfOrderMultiComparatorNonScoringCollector() - { - } +OutOfOrderMultiComparatorNonScoringCollector::~OutOfOrderMultiComparatorNonScoringCollector() { +} - void OutOfOrderMultiComparatorNonScoringCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - for (int32_t i = 0; ; ++i) - { - int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); - if (c < 0) - { - // Definitely not competitive. +void OutOfOrderMultiComparatorNonScoringCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + for (int32_t i = 0; ; ++i) { + int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); + if (c < 0) { + // Definitely not competitive. + return; + } else if (c > 0) { + // Definitely competitive. + break; + } else if (i == comparators.size() - 1) { + // This is the equals case. + if (doc + docBase > bottom->doc) { + // Definitely not competitive return; } - else if (c > 0) - { - // Definitely competitive. - break; - } - else if (i == comparators.size() - 1) - { - // This is the equals case. - if (doc + docBase > bottom->doc) - { - // Definitely not competitive - return; - } - break; - } + break; } + } - // This hit is competitive - replace bottom element in queue and adjustTop - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(bottom->slot, doc); + // This hit is competitive - replace bottom element in queue and adjustTop + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(bottom->slot, doc); + } - updateBottom(doc); + updateBottom(doc); - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); + } + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(slot, doc); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(slot, doc); - add(slot, doc, std::numeric_limits::quiet_NaN()); - if (queueFull) - { - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + add(slot, doc, std::numeric_limits::quiet_NaN()); + if (queueFull) { + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } } } +} - bool OutOfOrderMultiComparatorNonScoringCollector::acceptsDocsOutOfOrder() - { - return true; - } +bool OutOfOrderMultiComparatorNonScoringCollector::acceptsDocsOutOfOrder() { + return true; +} - MultiComparatorScoringMaxScoreCollector::MultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) - { - // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. - this->maxScore = -std::numeric_limits::infinity(); - } +MultiComparatorScoringMaxScoreCollector::MultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { + // Must set maxScore to NEG_INF, or otherwise std::max always returns NaN. + this->maxScore = -std::numeric_limits::infinity(); +} - MultiComparatorScoringMaxScoreCollector::~MultiComparatorScoringMaxScoreCollector() - { - } +MultiComparatorScoringMaxScoreCollector::~MultiComparatorScoringMaxScoreCollector() { +} - void MultiComparatorScoringMaxScoreCollector::updateBottom(int32_t doc, double score) - { - bottom->doc = docBase + doc; - bottom->score = score; - bottom = boost::static_pointer_cast(pq->updateTop()); - } +void MultiComparatorScoringMaxScoreCollector::updateBottom(int32_t doc, double score) { + bottom->doc = docBase + doc; + bottom->score = score; + bottom = boost::static_pointer_cast(pq->updateTop()); +} - void MultiComparatorScoringMaxScoreCollector::collect(int32_t doc) - { - double score = ScorerPtr(_scorer)->score(); - if (score > maxScore) - maxScore = score; - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - for (int32_t i = 0; ; ++i) - { - int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); - if (c < 0) - { - // Definitely not competitive. - return; - } - else if (c > 0) - { - // Definitely competitive. - break; - } - else if (i == comparators.size() - 1) - { - // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are - // visited in doc Id order, which means this doc cannot compete with any other document - // in the queue. - return; - } +void MultiComparatorScoringMaxScoreCollector::collect(int32_t doc) { + double score = ScorerPtr(_scorer)->score(); + if (score > maxScore) { + maxScore = score; + } + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + for (int32_t i = 0; ; ++i) { + int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); + if (c < 0) { + // Definitely not competitive. + return; + } else if (c > 0) { + // Definitely competitive. + break; + } else if (i == comparators.size() - 1) { + // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are + // visited in doc Id order, which means this doc cannot compete with any other document + // in the queue. + return; } + } - // This hit is competitive - replace bottom element in queue and adjustTop - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(bottom->slot, doc); + // This hit is competitive - replace bottom element in queue and adjustTop + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(bottom->slot, doc); + } - updateBottom(doc, score); + updateBottom(doc, score); - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(slot, doc); - add(slot, doc, score); - if (queueFull) - { - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(slot, doc); + } + add(slot, doc, score); + if (queueFull) { + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } } } +} - void MultiComparatorScoringMaxScoreCollector::setScorer(const ScorerPtr& scorer) - { - this->_scorer = scorer; - MultiComparatorNonScoringCollector::setScorer(scorer); - } +void MultiComparatorScoringMaxScoreCollector::setScorer(const ScorerPtr& scorer) { + this->_scorer = scorer; + MultiComparatorNonScoringCollector::setScorer(scorer); +} - OutOfOrderMultiComparatorScoringMaxScoreCollector::OutOfOrderMultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields) - { - } +OutOfOrderMultiComparatorScoringMaxScoreCollector::OutOfOrderMultiComparatorScoringMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields) { +} - OutOfOrderMultiComparatorScoringMaxScoreCollector::~OutOfOrderMultiComparatorScoringMaxScoreCollector() - { - } +OutOfOrderMultiComparatorScoringMaxScoreCollector::~OutOfOrderMultiComparatorScoringMaxScoreCollector() { +} - void OutOfOrderMultiComparatorScoringMaxScoreCollector::collect(int32_t doc) - { - double score = ScorerPtr(_scorer)->score(); - if (score > maxScore) - maxScore = score; - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - for (int32_t i = 0; ; ++i) - { - int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); - if (c < 0) - { - // Definitely not competitive. +void OutOfOrderMultiComparatorScoringMaxScoreCollector::collect(int32_t doc) { + double score = ScorerPtr(_scorer)->score(); + if (score > maxScore) { + maxScore = score; + } + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + for (int32_t i = 0; ; ++i) { + int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); + if (c < 0) { + // Definitely not competitive. + return; + } else if (c > 0) { + // Definitely competitive. + break; + } else if (i == comparators.size() - 1) { + // This is the equals case. + if (doc + docBase > bottom->doc) { + // Definitely not competitive return; } - else if (c > 0) - { - // Definitely competitive. - break; - } - else if (i == comparators.size() - 1) - { - // This is the equals case. - if (doc + docBase > bottom->doc) - { - // Definitely not competitive - return; - } - break; - } + break; } + } - // This hit is competitive - replace bottom element in queue and adjustTop - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(bottom->slot, doc); + // This hit is competitive - replace bottom element in queue and adjustTop + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(bottom->slot, doc); + } - updateBottom(doc, score); + updateBottom(doc, score); - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); + } + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(slot, doc); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(slot, doc); - add(slot, doc, score); - if (queueFull) - { - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + add(slot, doc, score); + if (queueFull) { + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } } } +} - bool OutOfOrderMultiComparatorScoringMaxScoreCollector::acceptsDocsOutOfOrder() - { - return true; - } +bool OutOfOrderMultiComparatorScoringMaxScoreCollector::acceptsDocsOutOfOrder() { + return true; +} - MultiComparatorScoringNoMaxScoreCollector::MultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) - { - } +MultiComparatorScoringNoMaxScoreCollector::MultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorNonScoringCollector(queue, numHits, fillFields) { +} - MultiComparatorScoringNoMaxScoreCollector::~MultiComparatorScoringNoMaxScoreCollector() - { - } +MultiComparatorScoringNoMaxScoreCollector::~MultiComparatorScoringNoMaxScoreCollector() { +} - void MultiComparatorScoringNoMaxScoreCollector::updateBottom(int32_t doc, double score) - { - bottom->doc = docBase + doc; - bottom->score = score; - bottom = boost::static_pointer_cast(pq->updateTop()); - } +void MultiComparatorScoringNoMaxScoreCollector::updateBottom(int32_t doc, double score) { + bottom->doc = docBase + doc; + bottom->score = score; + bottom = boost::static_pointer_cast(pq->updateTop()); +} - void MultiComparatorScoringNoMaxScoreCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - for (int32_t i = 0; ; ++i) - { - int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); - if (c < 0) - { - // Definitely not competitive. - return; - } - else if (c > 0) - { - // Definitely competitive. - break; - } - else if (i == comparators.size() - 1) - { - // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are - // visited in doc Id order, which means this doc cannot compete with any other document - // in the queue. - return; - } +void MultiComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + for (int32_t i = 0; ; ++i) { + int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); + if (c < 0) { + // Definitely not competitive. + return; + } else if (c > 0) { + // Definitely competitive. + break; + } else if (i == comparators.size() - 1) { + // Here c=0. If we're at the last comparator, this doc is not competitive, since docs are + // visited in doc Id order, which means this doc cannot compete with any other document + // in the queue. + return; } + } - // This hit is competitive - replace bottom element in queue and adjustTop - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(bottom->slot, doc); + // This hit is competitive - replace bottom element in queue and adjustTop + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(bottom->slot, doc); + } - // Compute score only if it is competitive. - double score = ScorerPtr(_scorer)->score(); - updateBottom(doc, score); + // Compute score only if it is competitive. + double score = ScorerPtr(_scorer)->score(); + updateBottom(doc, score); - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(slot, doc); - - // Compute score only if it is competitive. - double score = ScorerPtr(_scorer)->score(); - add(slot, doc, score); - if (queueFull) - { - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(slot, doc); + } + + // Compute score only if it is competitive. + double score = ScorerPtr(_scorer)->score(); + add(slot, doc, score); + if (queueFull) { + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } } } +} - void MultiComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) - { - this->_scorer = scorer; - MultiComparatorNonScoringCollector::setScorer(scorer); - } +void MultiComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) { + this->_scorer = scorer; + MultiComparatorNonScoringCollector::setScorer(scorer); +} - OutOfOrderMultiComparatorScoringNoMaxScoreCollector::OutOfOrderMultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) - { - } +OutOfOrderMultiComparatorScoringNoMaxScoreCollector::OutOfOrderMultiComparatorScoringNoMaxScoreCollector(const FieldValueHitQueuePtr& queue, int32_t numHits, bool fillFields) : MultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields) { +} - OutOfOrderMultiComparatorScoringNoMaxScoreCollector::~OutOfOrderMultiComparatorScoringNoMaxScoreCollector() - { - } +OutOfOrderMultiComparatorScoringNoMaxScoreCollector::~OutOfOrderMultiComparatorScoringNoMaxScoreCollector() { +} - void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::collect(int32_t doc) - { - ++totalHits; - if (queueFull) - { - // Fastmatch: return if this hit is not competitive - for (int32_t i = 0; ; ++i) - { - int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); - if (c < 0) - { - // Definitely not competitive. +void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::collect(int32_t doc) { + ++totalHits; + if (queueFull) { + // Fastmatch: return if this hit is not competitive + for (int32_t i = 0; ; ++i) { + int32_t c = reverseMul[i] * comparators[i]->compareBottom(doc); + if (c < 0) { + // Definitely not competitive. + return; + } else if (c > 0) { + // Definitely competitive. + break; + } else if (i == comparators.size() - 1) { + // This is the equals case. + if (doc + docBase > bottom->doc) { + // Definitely not competitive return; } - else if (c > 0) - { - // Definitely competitive. - break; - } - else if (i == comparators.size() - 1) - { - // This is the equals case. - if (doc + docBase > bottom->doc) - { - // Definitely not competitive - return; - } - break; - } + break; } + } - // This hit is competitive - replace bottom element in queue and adjustTop - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(bottom->slot, doc); + // This hit is competitive - replace bottom element in queue and adjustTop + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(bottom->slot, doc); + } - // Compute score only if it is competitive. - double score = ScorerPtr(_scorer)->score(); - updateBottom(doc, score); + // Compute score only if it is competitive. + double score = ScorerPtr(_scorer)->score(); + updateBottom(doc, score); - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } - else - { - // Startup transient: queue hasn't gathered numHits yet - int32_t slot = totalHits - 1; - // Copy hit into queue - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->copy(slot, doc); - - // Compute score only if it is competitive. - double score = ScorerPtr(_scorer)->score(); - add(slot, doc, score); - if (queueFull) - { - for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) - (*cmp)->setBottom(bottom->slot); + } else { + // Startup transient: queue hasn't gathered numHits yet + int32_t slot = totalHits - 1; + // Copy hit into queue + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->copy(slot, doc); + } + + // Compute score only if it is competitive. + double score = ScorerPtr(_scorer)->score(); + add(slot, doc, score); + if (queueFull) { + for (Collection::iterator cmp = comparators.begin(); cmp != comparators.end(); ++cmp) { + (*cmp)->setBottom(bottom->slot); } } } +} - void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) - { - this->_scorer = scorer; - MultiComparatorScoringNoMaxScoreCollector::setScorer(scorer); - } +void OutOfOrderMultiComparatorScoringNoMaxScoreCollector::setScorer(const ScorerPtr& scorer) { + this->_scorer = scorer; + MultiComparatorScoringNoMaxScoreCollector::setScorer(scorer); +} + +bool OutOfOrderMultiComparatorScoringNoMaxScoreCollector::acceptsDocsOutOfOrder() { + return true; +} - bool OutOfOrderMultiComparatorScoringNoMaxScoreCollector::acceptsDocsOutOfOrder() - { - return true; - } } diff --git a/src/core/search/TopFieldDocs.cpp b/src/core/search/TopFieldDocs.cpp index 4c3f9b44..674d2905 100644 --- a/src/core/search/TopFieldDocs.cpp +++ b/src/core/search/TopFieldDocs.cpp @@ -7,14 +7,13 @@ #include "LuceneInc.h" #include "TopFieldDocs.h" -namespace Lucene -{ - TopFieldDocs::TopFieldDocs(int32_t totalHits, Collection scoreDocs, Collection fields, double maxScore) : TopDocs(totalHits, scoreDocs, maxScore) - { - this->fields = fields; - } +namespace Lucene { + +TopFieldDocs::TopFieldDocs(int32_t totalHits, Collection scoreDocs, Collection fields, double maxScore) : TopDocs(totalHits, scoreDocs, maxScore) { + this->fields = fields; +} + +TopFieldDocs::~TopFieldDocs() { +} - TopFieldDocs::~TopFieldDocs() - { - } } diff --git a/src/core/search/TopScoreDocCollector.cpp b/src/core/search/TopScoreDocCollector.cpp index 3a04f76f..08a9499c 100644 --- a/src/core/search/TopScoreDocCollector.cpp +++ b/src/core/search/TopScoreDocCollector.cpp @@ -13,119 +13,108 @@ #include "TopDocs.h" #include "MiscUtils.h" -namespace Lucene -{ - TopScoreDocCollector::TopScoreDocCollector(int32_t numHits) : TopDocsCollector(newLucene(numHits, true)) - { - // HitQueue implements getSentinelObject to return a ScoreDoc, so we know that at this point top() - // is already initialized. - pqTop = pq->top(); - docBase = 0; - } +namespace Lucene { + +TopScoreDocCollector::TopScoreDocCollector(int32_t numHits) : TopDocsCollector(newLucene(numHits, true)) { + // HitQueue implements getSentinelObject to return a ScoreDoc, so we know that at this point top() + // is already initialized. + pqTop = pq->top(); + docBase = 0; +} + +TopScoreDocCollector::~TopScoreDocCollector() { +} - TopScoreDocCollector::~TopScoreDocCollector() - { +TopScoreDocCollectorPtr TopScoreDocCollector::create(int32_t numHits, bool docsScoredInOrder) { + if (docsScoredInOrder) { + return newLucene(numHits); + } else { + return newLucene(numHits); } +} - TopScoreDocCollectorPtr TopScoreDocCollector::create(int32_t numHits, bool docsScoredInOrder) - { - if (docsScoredInOrder) - return newLucene(numHits); - else - return newLucene(numHits); +TopDocsPtr TopScoreDocCollector::newTopDocs(Collection results, int32_t start) { + if (!results) { + return EMPTY_TOPDOCS(); } - TopDocsPtr TopScoreDocCollector::newTopDocs(Collection results, int32_t start) - { - if (!results) - return EMPTY_TOPDOCS(); - - // We need to compute maxScore in order to set it in TopDocs. If start == 0, it means the largest element - // is already in results, use its score as maxScore. Otherwise pop everything else, until the largest - // element is extracted and use its score as maxScore. - double maxScore = std::numeric_limits::quiet_NaN(); - if (start == 0) - maxScore = results[0]->score; - else - { - for (int32_t i = pq->size(); i > 1; --i) - pq->pop(); - maxScore = pq->pop()->score; + // We need to compute maxScore in order to set it in TopDocs. If start == 0, it means the largest element + // is already in results, use its score as maxScore. Otherwise pop everything else, until the largest + // element is extracted and use its score as maxScore. + double maxScore = std::numeric_limits::quiet_NaN(); + if (start == 0) { + maxScore = results[0]->score; + } else { + for (int32_t i = pq->size(); i > 1; --i) { + pq->pop(); } - - return newLucene(totalHits, results, maxScore); + maxScore = pq->pop()->score; } - void TopScoreDocCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - this->docBase = docBase; - } + return newLucene(totalHits, results, maxScore); +} - void TopScoreDocCollector::setScorer(const ScorerPtr& scorer) - { - this->_scorer = scorer; - } +void TopScoreDocCollector::setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + this->docBase = docBase; +} - InOrderTopScoreDocCollector::InOrderTopScoreDocCollector(int32_t numHits) : TopScoreDocCollector(numHits) - { - } +void TopScoreDocCollector::setScorer(const ScorerPtr& scorer) { + this->_scorer = scorer; +} - InOrderTopScoreDocCollector::~InOrderTopScoreDocCollector() - { - } +InOrderTopScoreDocCollector::InOrderTopScoreDocCollector(int32_t numHits) : TopScoreDocCollector(numHits) { +} - void InOrderTopScoreDocCollector::collect(int32_t doc) - { - double score = ScorerPtr(_scorer)->score(); - - // This collector cannot handle these scores - BOOST_ASSERT(score != -std::numeric_limits::infinity()); - BOOST_ASSERT(!MiscUtils::isNaN(score)); - - ++totalHits; - if (score <= pqTop->score) - { - // Since docs are returned in-order (ie., increasing doc Id), a document with equal score to - // pqTop.score cannot compete since HitQueue favours documents with lower doc Ids. Therefore - // reject those docs too. - return; - } - pqTop->doc = doc + docBase; - pqTop->score = score; - pqTop = pq->updateTop(); - } +InOrderTopScoreDocCollector::~InOrderTopScoreDocCollector() { +} - bool InOrderTopScoreDocCollector::acceptsDocsOutOfOrder() - { - return false; - } +void InOrderTopScoreDocCollector::collect(int32_t doc) { + double score = ScorerPtr(_scorer)->score(); - OutOfOrderTopScoreDocCollector::OutOfOrderTopScoreDocCollector(int32_t numHits) : TopScoreDocCollector(numHits) - { - } + // This collector cannot handle these scores + BOOST_ASSERT(score != -std::numeric_limits::infinity()); + BOOST_ASSERT(!MiscUtils::isNaN(score)); - OutOfOrderTopScoreDocCollector::~OutOfOrderTopScoreDocCollector() - { + ++totalHits; + if (score <= pqTop->score) { + // Since docs are returned in-order (ie., increasing doc Id), a document with equal score to + // pqTop.score cannot compete since HitQueue favours documents with lower doc Ids. Therefore + // reject those docs too. + return; } + pqTop->doc = doc + docBase; + pqTop->score = score; + pqTop = pq->updateTop(); +} - void OutOfOrderTopScoreDocCollector::collect(int32_t doc) - { - double score = ScorerPtr(_scorer)->score(); +bool InOrderTopScoreDocCollector::acceptsDocsOutOfOrder() { + return false; +} - // This collector cannot handle NaN - BOOST_ASSERT(!MiscUtils::isNaN(score)); +OutOfOrderTopScoreDocCollector::OutOfOrderTopScoreDocCollector(int32_t numHits) : TopScoreDocCollector(numHits) { +} - ++totalHits; - doc += docBase; - if (score < pqTop->score || (score == pqTop->score && doc > pqTop->doc)) - return; - pqTop->doc = doc; - pqTop->score = score; - pqTop = pq->updateTop(); - } +OutOfOrderTopScoreDocCollector::~OutOfOrderTopScoreDocCollector() { +} + +void OutOfOrderTopScoreDocCollector::collect(int32_t doc) { + double score = ScorerPtr(_scorer)->score(); - bool OutOfOrderTopScoreDocCollector::acceptsDocsOutOfOrder() - { - return true; + // This collector cannot handle NaN + BOOST_ASSERT(!MiscUtils::isNaN(score)); + + ++totalHits; + doc += docBase; + if (score < pqTop->score || (score == pqTop->score && doc > pqTop->doc)) { + return; } + pqTop->doc = doc; + pqTop->score = score; + pqTop = pq->updateTop(); +} + +bool OutOfOrderTopScoreDocCollector::acceptsDocsOutOfOrder() { + return true; +} + } diff --git a/src/core/search/Weight.cpp b/src/core/search/Weight.cpp index eb05969c..80126de3 100644 --- a/src/core/search/Weight.cpp +++ b/src/core/search/Weight.cpp @@ -7,14 +7,13 @@ #include "LuceneInc.h" #include "Weight.h" -namespace Lucene -{ - Weight::~Weight() - { - } +namespace Lucene { + +Weight::~Weight() { +} + +bool Weight::scoresDocsOutOfOrder() { + return false; +} - bool Weight::scoresDocsOutOfOrder() - { - return false; - } } diff --git a/src/core/search/WildcardQuery.cpp b/src/core/search/WildcardQuery.cpp index 5832b691..3fce507f 100644 --- a/src/core/search/WildcardQuery.cpp +++ b/src/core/search/WildcardQuery.cpp @@ -13,93 +13,90 @@ #include "SingleTermEnum.h" #include "MiscUtils.h" -namespace Lucene -{ - WildcardQuery::WildcardQuery(const TermPtr& term) - { - this->term = term; - String text(term->text()); - this->termContainsWildcard = boost::contains(text, L"*") || boost::contains(text, L"?"); - this->termIsPrefix = termContainsWildcard && - !boost::contains(text, L"?") && - text.find_first_of(L"*") == text.length() - 1; - } +namespace Lucene { - WildcardQuery::~WildcardQuery() - { - } +WildcardQuery::WildcardQuery(const TermPtr& term) { + this->term = term; + String text(term->text()); + this->termContainsWildcard = boost::contains(text, L"*") || boost::contains(text, L"?"); + this->termIsPrefix = termContainsWildcard && + !boost::contains(text, L"?") && + text.find_first_of(L"*") == text.length() - 1; +} - FilteredTermEnumPtr WildcardQuery::getEnum(const IndexReaderPtr& reader) - { - if (termContainsWildcard) - return newLucene(reader, getTerm()); - else - return newLucene(reader, getTerm()); - } +WildcardQuery::~WildcardQuery() { +} - TermPtr WildcardQuery::getTerm() - { - return term; +FilteredTermEnumPtr WildcardQuery::getEnum(const IndexReaderPtr& reader) { + if (termContainsWildcard) { + return newLucene(reader, getTerm()); + } else { + return newLucene(reader, getTerm()); } +} - QueryPtr WildcardQuery::rewrite(const IndexReaderPtr& reader) - { - if (termIsPrefix) - { - MultiTermQueryPtr rewritten(newLucene(term->createTerm(term->text().substr(0, term->text().find('*'))))); - rewritten->setBoost(getBoost()); - rewritten->setRewriteMethod(getRewriteMethod()); - return rewritten; - } - else - return MultiTermQuery::rewrite(reader); - } +TermPtr WildcardQuery::getTerm() { + return term; +} - String WildcardQuery::toString(const String& field) - { - StringStream buffer; - if (term->field() != field) - buffer << term->field() << L":"; - buffer << term->text() << boostString(); - return buffer.str(); +QueryPtr WildcardQuery::rewrite(const IndexReaderPtr& reader) { + if (termIsPrefix) { + MultiTermQueryPtr rewritten(newLucene(term->createTerm(term->text().substr(0, term->text().find('*'))))); + rewritten->setBoost(getBoost()); + rewritten->setRewriteMethod(getRewriteMethod()); + return rewritten; + } else { + return MultiTermQuery::rewrite(reader); } +} - LuceneObjectPtr WildcardQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); - WildcardQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->termContainsWildcard = termContainsWildcard; - cloneQuery->termIsPrefix = termIsPrefix; - cloneQuery->term = term; - return cloneQuery; +String WildcardQuery::toString(const String& field) { + StringStream buffer; + if (term->field() != field) { + buffer << term->field() << L":"; } + buffer << term->text() << boostString(); + return buffer.str(); +} - int32_t WildcardQuery::hashCode() - { - int32_t prime = 31; - int32_t result = MultiTermQuery::hashCode(); - result = prime * result + (term ? term->hashCode() : 0); - return result; - } +LuceneObjectPtr WildcardQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = MultiTermQuery::clone(other ? other : newLucene(term)); + WildcardQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->termContainsWildcard = termContainsWildcard; + cloneQuery->termIsPrefix = termIsPrefix; + cloneQuery->term = term; + return cloneQuery; +} - bool WildcardQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!MultiTermQuery::equals(other)) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - WildcardQueryPtr otherWildcardQuery(boost::dynamic_pointer_cast(other)); - if (!otherWildcardQuery) +int32_t WildcardQuery::hashCode() { + int32_t prime = 31; + int32_t result = MultiTermQuery::hashCode(); + result = prime * result + (term ? term->hashCode() : 0); + return result; +} + +bool WildcardQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!MultiTermQuery::equals(other)) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + WildcardQueryPtr otherWildcardQuery(boost::dynamic_pointer_cast(other)); + if (!otherWildcardQuery) { + return false; + } + if (!term) { + if (otherWildcardQuery->term) { return false; - if (!term) - { - if (otherWildcardQuery->term) - return false; } - else if (!term->equals(otherWildcardQuery->term)) - return false; - return true; + } else if (!term->equals(otherWildcardQuery->term)) { + return false; } + return true; +} + } diff --git a/src/core/search/WildcardTermEnum.cpp b/src/core/search/WildcardTermEnum.cpp index c34b5672..d8e7a88c 100644 --- a/src/core/search/WildcardTermEnum.cpp +++ b/src/core/search/WildcardTermEnum.cpp @@ -10,125 +10,122 @@ #include "Term.h" #include "IndexReader.h" -namespace Lucene -{ - const wchar_t WildcardTermEnum::WILDCARD_STRING = L'*'; - const wchar_t WildcardTermEnum::WILDCARD_CHAR = L'?'; - - WildcardTermEnum::WildcardTermEnum(const IndexReaderPtr& reader, const TermPtr& term) - { - _endEnum = false; - searchTerm = term; - field = searchTerm->field(); - String searchTermText(searchTerm->text()); - - String::size_type sidx = searchTermText.find(WILDCARD_STRING); - String::size_type cidx = searchTermText.find(WILDCARD_CHAR); - String::size_type idx = sidx; - if (idx == String::npos) - idx = cidx; - else if (cidx != String::npos) - idx = std::min(idx, cidx); - pre = idx != String::npos ? searchTerm->text().substr(0, idx) : L""; - - preLen = pre.length(); - text = searchTermText.substr(preLen); - setEnum(reader->terms(newLucene(searchTerm->field(), pre))); +namespace Lucene { + +const wchar_t WildcardTermEnum::WILDCARD_STRING = L'*'; +const wchar_t WildcardTermEnum::WILDCARD_CHAR = L'?'; + +WildcardTermEnum::WildcardTermEnum(const IndexReaderPtr& reader, const TermPtr& term) { + _endEnum = false; + searchTerm = term; + field = searchTerm->field(); + String searchTermText(searchTerm->text()); + + String::size_type sidx = searchTermText.find(WILDCARD_STRING); + String::size_type cidx = searchTermText.find(WILDCARD_CHAR); + String::size_type idx = sidx; + if (idx == String::npos) { + idx = cidx; + } else if (cidx != String::npos) { + idx = std::min(idx, cidx); } + pre = idx != String::npos ? searchTerm->text().substr(0, idx) : L""; - WildcardTermEnum::~WildcardTermEnum() - { - } + preLen = pre.length(); + text = searchTermText.substr(preLen); + setEnum(reader->terms(newLucene(searchTerm->field(), pre))); +} + +WildcardTermEnum::~WildcardTermEnum() { +} - bool WildcardTermEnum::termCompare(const TermPtr& term) - { - if (field == term->field()) - { - String searchText(term->text()); - if (boost::starts_with(searchText, pre)) - return wildcardEquals(text, 0, searchText, preLen); +bool WildcardTermEnum::termCompare(const TermPtr& term) { + if (field == term->field()) { + String searchText(term->text()); + if (boost::starts_with(searchText, pre)) { + return wildcardEquals(text, 0, searchText, preLen); } - _endEnum = true; - return false; } + _endEnum = true; + return false; +} - double WildcardTermEnum::difference() - { - return 1.0; - } +double WildcardTermEnum::difference() { + return 1.0; +} - bool WildcardTermEnum::endEnum() - { - return _endEnum; - } +bool WildcardTermEnum::endEnum() { + return _endEnum; +} - bool WildcardTermEnum::wildcardEquals(const String& pattern, int32_t patternIdx, const String& string, int32_t stringIdx) - { - int32_t p = patternIdx; - for (int32_t s = stringIdx; ; ++p, ++s) - { - // End of string yet? - bool sEnd = (s >= (int32_t)string.length()); - // End of pattern yet? - bool pEnd = (p >= (int32_t)pattern.length()); - - // If we're looking at the end of the string - if (sEnd) - { - // Assume the only thing left on the pattern is/are wildcards - bool justWildcardsLeft = true; - - // Current wildcard position - int32_t wildcardSearchPos = p; - - // While we haven't found the end of the pattern, and haven't encountered any non-wildcard characters - while (wildcardSearchPos < (int32_t)pattern.length() && justWildcardsLeft) - { - // Check the character at the current position - wchar_t wildchar = pattern[wildcardSearchPos]; - - // If it's not a wildcard character, then there is more pattern information after this/these wildcards. - if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING) - justWildcardsLeft = false; - else - { - // to prevent "cat" matches "ca??" - if (wildchar == WILDCARD_CHAR) - return false; - // Look at the next character - ++wildcardSearchPos; +bool WildcardTermEnum::wildcardEquals(const String& pattern, int32_t patternIdx, const String& string, int32_t stringIdx) { + int32_t p = patternIdx; + for (int32_t s = stringIdx; ; ++p, ++s) { + // End of string yet? + bool sEnd = (s >= (int32_t)string.length()); + // End of pattern yet? + bool pEnd = (p >= (int32_t)pattern.length()); + + // If we're looking at the end of the string + if (sEnd) { + // Assume the only thing left on the pattern is/are wildcards + bool justWildcardsLeft = true; + + // Current wildcard position + int32_t wildcardSearchPos = p; + + // While we haven't found the end of the pattern, and haven't encountered any non-wildcard characters + while (wildcardSearchPos < (int32_t)pattern.length() && justWildcardsLeft) { + // Check the character at the current position + wchar_t wildchar = pattern[wildcardSearchPos]; + + // If it's not a wildcard character, then there is more pattern information after this/these wildcards. + if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING) { + justWildcardsLeft = false; + } else { + // to prevent "cat" matches "ca??" + if (wildchar == WILDCARD_CHAR) { + return false; } + // Look at the next character + ++wildcardSearchPos; } + } - // This was a prefix wildcard search, and we've matched, so return true. - if (justWildcardsLeft) - return true; + // This was a prefix wildcard search, and we've matched, so return true. + if (justWildcardsLeft) { + return true; } + } + + // If we've gone past the end of the string, or the pattern, return false. + if (sEnd || pEnd) { + break; + } + + // Match a single character, so continue. + if (pattern[p] == WILDCARD_CHAR) { + continue; + } - // If we've gone past the end of the string, or the pattern, return false. - if (sEnd || pEnd) - break; - - // Match a single character, so continue. - if (pattern[p] == WILDCARD_CHAR) - continue; - - if (pattern[p] == WILDCARD_STRING) - { - // Look at the character beyond the '*' characters. - while (p < (int32_t)pattern.length() && pattern[p] == WILDCARD_STRING) - ++p; - // Examine the string, starting at the last character. - for (int32_t i = string.length(); i >= s; --i) - { - if (wildcardEquals(pattern, p, string, i)) - return true; + if (pattern[p] == WILDCARD_STRING) { + // Look at the character beyond the '*' characters. + while (p < (int32_t)pattern.length() && pattern[p] == WILDCARD_STRING) { + ++p; + } + // Examine the string, starting at the last character. + for (int32_t i = string.length(); i >= s; --i) { + if (wildcardEquals(pattern, p, string, i)) { + return true; } - break; } - if (pattern[p] != string[s]) - break; + break; + } + if (pattern[p] != string[s]) { + break; } - return false; } + return false; +} + } diff --git a/src/core/search/function/ByteFieldSource.cpp b/src/core/search/function/ByteFieldSource.cpp index 9c313488..f2b98651 100644 --- a/src/core/search/function/ByteFieldSource.cpp +++ b/src/core/search/function/ByteFieldSource.cpp @@ -11,74 +11,67 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - ByteFieldSource::ByteFieldSource(const String& field, const ByteParserPtr& parser) : FieldCacheSource(field) - { - this->parser = parser; - } +namespace Lucene { - ByteFieldSource::~ByteFieldSource() - { - } +ByteFieldSource::ByteFieldSource(const String& field, const ByteParserPtr& parser) : FieldCacheSource(field) { + this->parser = parser; +} - String ByteFieldSource::description() - { - return L"byte(" + FieldCacheSource::description() + L")"; - } +ByteFieldSource::~ByteFieldSource() { +} - DocValuesPtr ByteFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) - { - Collection arr(cache->getBytes(reader, field, parser)); - return newLucene(shared_from_this(), arr); - } +String ByteFieldSource::description() { + return L"byte(" + FieldCacheSource::description() + L")"; +} - bool ByteFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) - { - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - ByteFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); - if (!otherSource) - return false; - return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; - } +DocValuesPtr ByteFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) { + Collection arr(cache->getBytes(reader, field, parser)); + return newLucene(shared_from_this(), arr); +} - int32_t ByteFieldSource::cachedFieldSourceHashCode() - { - return StringUtils::hashCode(parser ? ByteParser::_getClassName() : ByteFieldSource::_getClassName()); +bool ByteFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) { + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } - - ByteDocValues::ByteDocValues(const ByteFieldSourcePtr& source, Collection arr) - { - this->_source = source; - this->arr = arr; + ByteFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); + if (!otherSource) { + return false; } + return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; +} - ByteDocValues::~ByteDocValues() - { - } +int32_t ByteFieldSource::cachedFieldSourceHashCode() { + return StringUtils::hashCode(parser ? ByteParser::_getClassName() : ByteFieldSource::_getClassName()); +} - double ByteDocValues::doubleVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (double)arr[doc]; - } +ByteDocValues::ByteDocValues(const ByteFieldSourcePtr& source, Collection arr) { + this->_source = source; + this->arr = arr; +} - int32_t ByteDocValues::intVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (int32_t)arr[doc]; - } +ByteDocValues::~ByteDocValues() { +} - String ByteDocValues::toString(int32_t doc) - { - return ByteFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); +double ByteDocValues::doubleVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return (double)arr[doc]; +} - CollectionValue ByteDocValues::getInnerArray() - { - return arr; +int32_t ByteDocValues::intVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return (int32_t)arr[doc]; +} + +String ByteDocValues::toString(int32_t doc) { + return ByteFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); +} + +CollectionValue ByteDocValues::getInnerArray() { + return arr; +} + } diff --git a/src/core/search/function/CustomScoreProvider.cpp b/src/core/search/function/CustomScoreProvider.cpp index d3f6b2c2..7f8805f9 100644 --- a/src/core/search/function/CustomScoreProvider.cpp +++ b/src/core/search/function/CustomScoreProvider.cpp @@ -8,58 +8,61 @@ #include "CustomScoreProvider.h" #include "Explanation.h" -namespace Lucene -{ - CustomScoreProvider::CustomScoreProvider(const IndexReaderPtr& reader) - { - this->reader = reader; - } +namespace Lucene { - CustomScoreProvider::~CustomScoreProvider() - { - } +CustomScoreProvider::CustomScoreProvider(const IndexReaderPtr& reader) { + this->reader = reader; +} - double CustomScoreProvider::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) - { - if (valSrcScores.size() == 1) - return customScore(doc, subQueryScore, valSrcScores[0]); - if (valSrcScores.empty()) - return customScore(doc, subQueryScore, 1); - double score = subQueryScore; - for (Collection::iterator srcScore = valSrcScores.begin(); srcScore != valSrcScores.end(); ++srcScore) - score *= *srcScore; - return score; - } +CustomScoreProvider::~CustomScoreProvider() { +} - double CustomScoreProvider::customScore(int32_t doc, double subQueryScore, double valSrcScore) - { - return subQueryScore * valSrcScore; +double CustomScoreProvider::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) { + if (valSrcScores.size() == 1) { + return customScore(doc, subQueryScore, valSrcScores[0]); + } + if (valSrcScores.empty()) { + return customScore(doc, subQueryScore, 1); } + double score = subQueryScore; + for (Collection::iterator srcScore = valSrcScores.begin(); srcScore != valSrcScores.end(); ++srcScore) { + score *= *srcScore; + } + return score; +} - ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) - { - if (valSrcExpls.size() == 1) - return customExplain(doc, subQueryExpl, valSrcExpls[0]); - if (valSrcExpls.empty()) - return subQueryExpl; - double valSrcScore = 1; - for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) - valSrcScore *= (*srcExpl)->getValue(); - ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); - exp->addDetail(subQueryExpl); - for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) - exp->addDetail(*srcExpl); - return exp; +double CustomScoreProvider::customScore(int32_t doc, double subQueryScore, double valSrcScore) { + return subQueryScore * valSrcScore; +} + +ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { + if (valSrcExpls.size() == 1) { + return customExplain(doc, subQueryExpl, valSrcExpls[0]); + } + if (valSrcExpls.empty()) { + return subQueryExpl; + } + double valSrcScore = 1; + for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) { + valSrcScore *= (*srcExpl)->getValue(); } + ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); + exp->addDetail(subQueryExpl); + for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) { + exp->addDetail(*srcExpl); + } + return exp; +} - ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) - { - double valSrcScore = 1; - if (valSrcExpl) - valSrcScore *= valSrcExpl->getValue(); - ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); - exp->addDetail(subQueryExpl); - exp->addDetail(valSrcExpl); - return exp; +ExplanationPtr CustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { + double valSrcScore = 1; + if (valSrcExpl) { + valSrcScore *= valSrcExpl->getValue(); } + ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); + exp->addDetail(subQueryExpl); + exp->addDetail(valSrcExpl); + return exp; +} + } diff --git a/src/core/search/function/CustomScoreQuery.cpp b/src/core/search/function/CustomScoreQuery.cpp index ed9ff94f..ff0869d5 100644 --- a/src/core/search/function/CustomScoreQuery.cpp +++ b/src/core/search/function/CustomScoreQuery.cpp @@ -12,348 +12,326 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery) - { - ConstructQuery(subQuery, Collection::newInstance()); - } +namespace Lucene { - CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery, const ValueSourceQueryPtr& valSrcQuery) - { - Collection valSrcQueries(Collection::newInstance()); - if (valSrcQuery) - valSrcQueries.add(valSrcQuery); - ConstructQuery(subQuery, valSrcQueries); - } +CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery) { + ConstructQuery(subQuery, Collection::newInstance()); +} - CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery, Collection valSrcQueries) - { - ConstructQuery(subQuery, valSrcQueries); +CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery, const ValueSourceQueryPtr& valSrcQuery) { + Collection valSrcQueries(Collection::newInstance()); + if (valSrcQuery) { + valSrcQueries.add(valSrcQuery); } + ConstructQuery(subQuery, valSrcQueries); +} - CustomScoreQuery::~CustomScoreQuery() - { - } +CustomScoreQuery::CustomScoreQuery(const QueryPtr& subQuery, Collection valSrcQueries) { + ConstructQuery(subQuery, valSrcQueries); +} - void CustomScoreQuery::ConstructQuery(const QueryPtr& subQuery, Collection valSrcQueries) - { - this->strict = false; - this->subQuery = subQuery; - this->valSrcQueries = valSrcQueries ? valSrcQueries : Collection::newInstance(); - if (!subQuery) - boost::throw_exception(IllegalArgumentException(L" must not be null!")); +CustomScoreQuery::~CustomScoreQuery() { +} + +void CustomScoreQuery::ConstructQuery(const QueryPtr& subQuery, Collection valSrcQueries) { + this->strict = false; + this->subQuery = subQuery; + this->valSrcQueries = valSrcQueries ? valSrcQueries : Collection::newInstance(); + if (!subQuery) { + boost::throw_exception(IllegalArgumentException(L" must not be null!")); } +} - QueryPtr CustomScoreQuery::rewrite(const IndexReaderPtr& reader) - { - CustomScoreQueryPtr cloneQuery; +QueryPtr CustomScoreQuery::rewrite(const IndexReaderPtr& reader) { + CustomScoreQueryPtr cloneQuery; - QueryPtr sq = subQuery->rewrite(reader); - if (sq != subQuery) - { - cloneQuery = boost::static_pointer_cast(clone()); - cloneQuery->subQuery = sq; - } + QueryPtr sq = subQuery->rewrite(reader); + if (sq != subQuery) { + cloneQuery = boost::static_pointer_cast(clone()); + cloneQuery->subQuery = sq; + } - for (int32_t i = 0; i < valSrcQueries.size(); ++i) - { - ValueSourceQueryPtr v = boost::dynamic_pointer_cast(valSrcQueries[i]->rewrite(reader)); - if (v != valSrcQueries[i]) - { - if (!cloneQuery) - cloneQuery = boost::static_pointer_cast(clone()); - cloneQuery->valSrcQueries[i] = v; + for (int32_t i = 0; i < valSrcQueries.size(); ++i) { + ValueSourceQueryPtr v = boost::dynamic_pointer_cast(valSrcQueries[i]->rewrite(reader)); + if (v != valSrcQueries[i]) { + if (!cloneQuery) { + cloneQuery = boost::static_pointer_cast(clone()); } + cloneQuery->valSrcQueries[i] = v; } - - return cloneQuery ? cloneQuery : shared_from_this(); } - void CustomScoreQuery::extractTerms(SetTerm terms) - { - subQuery->extractTerms(terms); - for (Collection::iterator srcQuery = valSrcQueries.begin(); srcQuery != valSrcQueries.end(); ++srcQuery) - (*srcQuery)->extractTerms(terms); - } + return cloneQuery ? cloneQuery : shared_from_this(); +} - LuceneObjectPtr CustomScoreQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = Query::clone(other ? other : newLucene(subQuery)); - CustomScoreQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->strict = strict; - cloneQuery->subQuery = boost::dynamic_pointer_cast(subQuery->clone()); - cloneQuery->valSrcQueries = Collection::newInstance(valSrcQueries.size()); - for (int32_t i = 0; i < valSrcQueries.size(); ++i) - cloneQuery->valSrcQueries[i] = boost::dynamic_pointer_cast(valSrcQueries[i]->clone()); - return cloneQuery; +void CustomScoreQuery::extractTerms(SetTerm terms) { + subQuery->extractTerms(terms); + for (Collection::iterator srcQuery = valSrcQueries.begin(); srcQuery != valSrcQueries.end(); ++srcQuery) { + (*srcQuery)->extractTerms(terms); } +} - String CustomScoreQuery::toString(const String& field) - { - StringStream buffer; - buffer << name() << L"(" << subQuery->toString(field); - for (Collection::iterator srcQuery = valSrcQueries.begin(); srcQuery != valSrcQueries.end(); ++srcQuery) - buffer << L", " << (*srcQuery)->toString(field); - buffer << L")" << (strict ? L" STRICT" : L"") << boostString(); - return buffer.str(); +LuceneObjectPtr CustomScoreQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = Query::clone(other ? other : newLucene(subQuery)); + CustomScoreQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->strict = strict; + cloneQuery->subQuery = boost::dynamic_pointer_cast(subQuery->clone()); + cloneQuery->valSrcQueries = Collection::newInstance(valSrcQueries.size()); + for (int32_t i = 0; i < valSrcQueries.size(); ++i) { + cloneQuery->valSrcQueries[i] = boost::dynamic_pointer_cast(valSrcQueries[i]->clone()); } + return cloneQuery; +} - bool CustomScoreQuery::equals(const LuceneObjectPtr& other) - { - CustomScoreQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - if (getBoost() != otherQuery->getBoost() || !subQuery->equals(otherQuery->subQuery) || strict != otherQuery->strict) - return false; - return valSrcQueries.equals(otherQuery->valSrcQueries, luceneEquals()); +String CustomScoreQuery::toString(const String& field) { + StringStream buffer; + buffer << name() << L"(" << subQuery->toString(field); + for (Collection::iterator srcQuery = valSrcQueries.begin(); srcQuery != valSrcQueries.end(); ++srcQuery) { + buffer << L", " << (*srcQuery)->toString(field); } + buffer << L")" << (strict ? L" STRICT" : L"") << boostString(); + return buffer.str(); +} - int32_t CustomScoreQuery::hashCode() - { - return (StringUtils::hashCode(CustomScoreQuery::_getClassName()) + StringUtils::hashCode(Query::_getClassName()) + - MiscUtils::hashCode(valSrcQueries.begin(), valSrcQueries.end(), MiscUtils::hashLucene)) ^ - MiscUtils::doubleToIntBits(getBoost()) ^ (strict ? 1234 : 4321); +bool CustomScoreQuery::equals(const LuceneObjectPtr& other) { + CustomScoreQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } - - CustomScoreProviderPtr CustomScoreQuery::getCustomScoreProvider(const IndexReaderPtr& reader) - { - // when deprecated methods are removed, do not extend class here, just return new default CustomScoreProvider - return newLucene(shared_from_this(), reader); + if (getBoost() != otherQuery->getBoost() || !subQuery->equals(otherQuery->subQuery) || strict != otherQuery->strict) { + return false; } + return valSrcQueries.equals(otherQuery->valSrcQueries, luceneEquals()); +} - double CustomScoreQuery::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) - { - if (valSrcScores.size() == 1) - return customScore(doc, subQueryScore, valSrcScores[0]); - if (valSrcScores.empty()) - return customScore(doc, subQueryScore, 1); - double score = subQueryScore; - for (Collection::iterator srcScore = valSrcScores.begin(); srcScore != valSrcScores.end(); ++srcScore) - score *= *srcScore; - return score; - } +int32_t CustomScoreQuery::hashCode() { + return (StringUtils::hashCode(CustomScoreQuery::_getClassName()) + StringUtils::hashCode(Query::_getClassName()) + + MiscUtils::hashCode(valSrcQueries.begin(), valSrcQueries.end(), MiscUtils::hashLucene)) ^ + MiscUtils::doubleToIntBits(getBoost()) ^ (strict ? 1234 : 4321); +} - double CustomScoreQuery::customScore(int32_t doc, double subQueryScore, double valSrcScore) - { - return subQueryScore * valSrcScore; - } +CustomScoreProviderPtr CustomScoreQuery::getCustomScoreProvider(const IndexReaderPtr& reader) { + // when deprecated methods are removed, do not extend class here, just return new default CustomScoreProvider + return newLucene(shared_from_this(), reader); +} - ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) - { - if (valSrcExpls.size() == 1) - return customExplain(doc, subQueryExpl, valSrcExpls[0]); - if (valSrcExpls.empty()) - return subQueryExpl; - double valSrcScore = 1; - for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) - valSrcScore *= (*srcExpl)->getValue(); - ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); - exp->addDetail(subQueryExpl); - for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) - exp->addDetail(*srcExpl); - return exp; +double CustomScoreQuery::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) { + if (valSrcScores.size() == 1) { + return customScore(doc, subQueryScore, valSrcScores[0]); } - - ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) - { - double valSrcScore = 1; - if (valSrcExpl) - valSrcScore *= valSrcExpl->getValue(); - ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); - exp->addDetail(subQueryExpl); - exp->addDetail(valSrcExpl); - return exp; + if (valSrcScores.empty()) { + return customScore(doc, subQueryScore, 1); } - - WeightPtr CustomScoreQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); + double score = subQueryScore; + for (Collection::iterator srcScore = valSrcScores.begin(); srcScore != valSrcScores.end(); ++srcScore) { + score *= *srcScore; } + return score; +} - bool CustomScoreQuery::isStrict() - { - return strict; - } +double CustomScoreQuery::customScore(int32_t doc, double subQueryScore, double valSrcScore) { + return subQueryScore * valSrcScore; +} - void CustomScoreQuery::setStrict(bool strict) - { - this->strict = strict; +ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { + if (valSrcExpls.size() == 1) { + return customExplain(doc, subQueryExpl, valSrcExpls[0]); } - - String CustomScoreQuery::name() - { - return L"custom"; + if (valSrcExpls.empty()) { + return subQueryExpl; } - - DefaultCustomScoreProvider::DefaultCustomScoreProvider(const CustomScoreQueryPtr& customQuery, const IndexReaderPtr& reader) : CustomScoreProvider(reader) - { - _customQuery = customQuery; + double valSrcScore = 1; + for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) { + valSrcScore *= (*srcExpl)->getValue(); } - - DefaultCustomScoreProvider::~DefaultCustomScoreProvider() - { + ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); + exp->addDetail(subQueryExpl); + for (Collection::iterator srcExpl = valSrcExpls.begin(); srcExpl != valSrcExpls.end(); ++srcExpl) { + exp->addDetail(*srcExpl); } + return exp; +} - double DefaultCustomScoreProvider::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) - { - return CustomScoreQueryPtr(_customQuery)->customScore(doc, subQueryScore, valSrcScores); +ExplanationPtr CustomScoreQuery::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { + double valSrcScore = 1; + if (valSrcExpl) { + valSrcScore *= valSrcExpl->getValue(); } + ExplanationPtr exp(newLucene(valSrcScore * subQueryExpl->getValue(), L"custom score: product of:")); + exp->addDetail(subQueryExpl); + exp->addDetail(valSrcExpl); + return exp; +} - double DefaultCustomScoreProvider::customScore(int32_t doc, double subQueryScore, double valSrcScore) - { - return CustomScoreQueryPtr(_customQuery)->customScore(doc, subQueryScore, valSrcScore); - } +WeightPtr CustomScoreQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) - { - return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpls); - } +bool CustomScoreQuery::isStrict() { + return strict; +} - ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) - { - return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpl); - } +void CustomScoreQuery::setStrict(bool strict) { + this->strict = strict; +} - CustomWeight::CustomWeight(const CustomScoreQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = query->getSimilarity(searcher); - this->subQueryWeight = query->subQuery->weight(searcher); - this->valSrcWeights = Collection::newInstance(query->valSrcQueries.size()); - for (int32_t i = 0; i < query->valSrcQueries.size(); ++i) - this->valSrcWeights[i] = query->valSrcQueries[i]->createWeight(searcher); - this->qStrict = query->strict; - } +String CustomScoreQuery::name() { + return L"custom"; +} - CustomWeight::~CustomWeight() - { - } +DefaultCustomScoreProvider::DefaultCustomScoreProvider(const CustomScoreQueryPtr& customQuery, const IndexReaderPtr& reader) : CustomScoreProvider(reader) { + _customQuery = customQuery; +} - QueryPtr CustomWeight::getQuery() - { - return query; - } +DefaultCustomScoreProvider::~DefaultCustomScoreProvider() { +} + +double DefaultCustomScoreProvider::customScore(int32_t doc, double subQueryScore, Collection valSrcScores) { + return CustomScoreQueryPtr(_customQuery)->customScore(doc, subQueryScore, valSrcScores); +} + +double DefaultCustomScoreProvider::customScore(int32_t doc, double subQueryScore, double valSrcScore) { + return CustomScoreQueryPtr(_customQuery)->customScore(doc, subQueryScore, valSrcScore); +} + +ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { + return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpls); +} - double CustomWeight::getValue() - { - return query->getBoost(); +ExplanationPtr DefaultCustomScoreProvider::customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { + return CustomScoreQueryPtr(_customQuery)->customExplain(doc, subQueryExpl, valSrcExpl); +} + +CustomWeight::CustomWeight(const CustomScoreQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = query->getSimilarity(searcher); + this->subQueryWeight = query->subQuery->weight(searcher); + this->valSrcWeights = Collection::newInstance(query->valSrcQueries.size()); + for (int32_t i = 0; i < query->valSrcQueries.size(); ++i) { + this->valSrcWeights[i] = query->valSrcQueries[i]->createWeight(searcher); } + this->qStrict = query->strict; +} + +CustomWeight::~CustomWeight() { +} - double CustomWeight::sumOfSquaredWeights() - { - double sum = subQueryWeight->sumOfSquaredWeights(); - for (int32_t i = 0; i < valSrcWeights.size(); ++i) - { - if (qStrict) - valSrcWeights[i]->sumOfSquaredWeights(); // do not include ValueSource part in the query normalization - else - sum += valSrcWeights[i]->sumOfSquaredWeights(); +QueryPtr CustomWeight::getQuery() { + return query; +} + +double CustomWeight::getValue() { + return query->getBoost(); +} + +double CustomWeight::sumOfSquaredWeights() { + double sum = subQueryWeight->sumOfSquaredWeights(); + for (int32_t i = 0; i < valSrcWeights.size(); ++i) { + if (qStrict) { + valSrcWeights[i]->sumOfSquaredWeights(); // do not include ValueSource part in the query normalization + } else { + sum += valSrcWeights[i]->sumOfSquaredWeights(); } - sum *= query->getBoost() * query->getBoost(); // boost each sub-weight - return sum; } + sum *= query->getBoost() * query->getBoost(); // boost each sub-weight + return sum; +} - void CustomWeight::normalize(double norm) - { - norm *= query->getBoost(); // incorporate boost - subQueryWeight->normalize(norm); - for (int32_t i = 0; i < valSrcWeights.size(); ++i) - { - if (qStrict) - valSrcWeights[i]->normalize(1.0); // do not normalize the ValueSource part - else - valSrcWeights[i]->normalize(norm); +void CustomWeight::normalize(double norm) { + norm *= query->getBoost(); // incorporate boost + subQueryWeight->normalize(norm); + for (int32_t i = 0; i < valSrcWeights.size(); ++i) { + if (qStrict) { + valSrcWeights[i]->normalize(1.0); // do not normalize the ValueSource part + } else { + valSrcWeights[i]->normalize(norm); } } +} - ScorerPtr CustomWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - // Pass true for "scoresDocsInOrder", because we require in-order scoring, even if caller does not, - // since we call advance on the valSrcScorers. Pass false for "topScorer" because we will not invoke - // score(Collector) on these scorers - ScorerPtr subQueryScorer(subQueryWeight->scorer(reader, true, false)); - if (!subQueryScorer) - return ScorerPtr(); - Collection valSrcScorers(Collection::newInstance(valSrcWeights.size())); - for (int32_t i = 0; i < valSrcScorers.size(); ++i) - valSrcScorers[i] = valSrcWeights[i]->scorer(reader, true, topScorer); - return newLucene(similarity, reader, shared_from_this(), subQueryScorer, valSrcScorers); +ScorerPtr CustomWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + // Pass true for "scoresDocsInOrder", because we require in-order scoring, even if caller does not, + // since we call advance on the valSrcScorers. Pass false for "topScorer" because we will not invoke + // score(Collector) on these scorers + ScorerPtr subQueryScorer(subQueryWeight->scorer(reader, true, false)); + if (!subQueryScorer) { + return ScorerPtr(); } - - ExplanationPtr CustomWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - ExplanationPtr explain(doExplain(reader, doc)); - return explain ? explain : newLucene(0.0, L"no matching docs"); + Collection valSrcScorers(Collection::newInstance(valSrcWeights.size())); + for (int32_t i = 0; i < valSrcScorers.size(); ++i) { + valSrcScorers[i] = valSrcWeights[i]->scorer(reader, true, topScorer); } + return newLucene(similarity, reader, shared_from_this(), subQueryScorer, valSrcScorers); +} - ExplanationPtr CustomWeight::doExplain(const IndexReaderPtr& reader, int32_t doc) - { - ExplanationPtr subQueryExpl(subQueryWeight->explain(reader, doc)); - if (!subQueryExpl->isMatch()) - return subQueryExpl; - // match - Collection valSrcExpls(Collection::newInstance(valSrcWeights.size())); - for (int32_t i = 0; i < valSrcWeights.size(); ++i) - valSrcExpls[i] = valSrcWeights[i]->explain(reader, doc); - ExplanationPtr customExp(query->getCustomScoreProvider(reader)->customExplain(doc, subQueryExpl, valSrcExpls)); - double sc = getValue() * customExp->getValue(); - ExplanationPtr res(newLucene(true, sc, query->toString() + L", product of:")); - res->addDetail(customExp); - res->addDetail(newLucene(getValue(), L"queryBoost")); // actually using the q boost as q weight (== weight value) - return res; - } +ExplanationPtr CustomWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + ExplanationPtr explain(doExplain(reader, doc)); + return explain ? explain : newLucene(0.0, L"no matching docs"); +} - bool CustomWeight::scoresDocsOutOfOrder() - { - return false; - } +ExplanationPtr CustomWeight::doExplain(const IndexReaderPtr& reader, int32_t doc) { + ExplanationPtr subQueryExpl(subQueryWeight->explain(reader, doc)); + if (!subQueryExpl->isMatch()) { + return subQueryExpl; + } + // match + Collection valSrcExpls(Collection::newInstance(valSrcWeights.size())); + for (int32_t i = 0; i < valSrcWeights.size(); ++i) { + valSrcExpls[i] = valSrcWeights[i]->explain(reader, doc); + } + ExplanationPtr customExp(query->getCustomScoreProvider(reader)->customExplain(doc, subQueryExpl, valSrcExpls)); + double sc = getValue() * customExp->getValue(); + ExplanationPtr res(newLucene(true, sc, query->toString() + L", product of:")); + res->addDetail(customExp); + res->addDetail(newLucene(getValue(), L"queryBoost")); // actually using the q boost as q weight (== weight value) + return res; +} - CustomScorer::CustomScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const CustomWeightPtr& weight, const ScorerPtr& subQueryScorer, Collection valSrcScorers) : Scorer(similarity) - { - this->qWeight = weight->getValue(); - this->subQueryScorer = subQueryScorer; - this->valSrcScorers = valSrcScorers; - this->reader = reader; - this->vScores = Collection::newInstance(valSrcScorers.size()); - this->provider = weight->query->getCustomScoreProvider(reader); - } +bool CustomWeight::scoresDocsOutOfOrder() { + return false; +} - CustomScorer::~CustomScorer() - { - } +CustomScorer::CustomScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const CustomWeightPtr& weight, const ScorerPtr& subQueryScorer, Collection valSrcScorers) : Scorer(similarity) { + this->qWeight = weight->getValue(); + this->subQueryScorer = subQueryScorer; + this->valSrcScorers = valSrcScorers; + this->reader = reader; + this->vScores = Collection::newInstance(valSrcScorers.size()); + this->provider = weight->query->getCustomScoreProvider(reader); +} - int32_t CustomScorer::nextDoc() - { - int32_t doc = subQueryScorer->nextDoc(); - if (doc != NO_MORE_DOCS) - { - for (int32_t i = 0; i < valSrcScorers.size(); ++i) - valSrcScorers[i]->advance(doc); +CustomScorer::~CustomScorer() { +} + +int32_t CustomScorer::nextDoc() { + int32_t doc = subQueryScorer->nextDoc(); + if (doc != NO_MORE_DOCS) { + for (int32_t i = 0; i < valSrcScorers.size(); ++i) { + valSrcScorers[i]->advance(doc); } - return doc; } + return doc; +} - int32_t CustomScorer::docID() - { - return subQueryScorer->docID(); - } +int32_t CustomScorer::docID() { + return subQueryScorer->docID(); +} - double CustomScorer::score() - { - for (int32_t i = 0; i < valSrcScorers.size(); ++i) - vScores[i] = valSrcScorers[i]->score(); - return qWeight * provider->customScore(subQueryScorer->docID(), subQueryScorer->score(), vScores); +double CustomScorer::score() { + for (int32_t i = 0; i < valSrcScorers.size(); ++i) { + vScores[i] = valSrcScorers[i]->score(); } + return qWeight * provider->customScore(subQueryScorer->docID(), subQueryScorer->score(), vScores); +} - int32_t CustomScorer::advance(int32_t target) - { - int32_t doc = subQueryScorer->advance(target); - if (doc != NO_MORE_DOCS) - { - for (int32_t i = 0; i < valSrcScorers.size(); ++i) - valSrcScorers[i]->advance(doc); +int32_t CustomScorer::advance(int32_t target) { + int32_t doc = subQueryScorer->advance(target); + if (doc != NO_MORE_DOCS) { + for (int32_t i = 0; i < valSrcScorers.size(); ++i) { + valSrcScorers[i]->advance(doc); } - return doc; } + return doc; +} + } diff --git a/src/core/search/function/DocValues.cpp b/src/core/search/function/DocValues.cpp index 1a798450..a95858b6 100644 --- a/src/core/search/function/DocValues.cpp +++ b/src/core/search/function/DocValues.cpp @@ -11,88 +11,75 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - DocValues::DocValues() - { - minVal = std::numeric_limits::quiet_NaN(); - maxVal = std::numeric_limits::quiet_NaN(); - avgVal = std::numeric_limits::quiet_NaN(); - computed = false; - } +namespace Lucene { - DocValues::~DocValues() - { - } +DocValues::DocValues() { + minVal = std::numeric_limits::quiet_NaN(); + maxVal = std::numeric_limits::quiet_NaN(); + avgVal = std::numeric_limits::quiet_NaN(); + computed = false; +} - int32_t DocValues::intVal(int32_t doc) - { - return (int32_t)doubleVal(doc); - } +DocValues::~DocValues() { +} - int64_t DocValues::longVal(int32_t doc) - { - return (int64_t)doubleVal(doc); - } +int32_t DocValues::intVal(int32_t doc) { + return (int32_t)doubleVal(doc); +} - String DocValues::strVal(int32_t doc) - { - return StringUtils::toString(doubleVal(doc)); - } +int64_t DocValues::longVal(int32_t doc) { + return (int64_t)doubleVal(doc); +} - ExplanationPtr DocValues::explain(int32_t doc) - { - return newLucene(doubleVal(doc), toString(doc)); - } +String DocValues::strVal(int32_t doc) { + return StringUtils::toString(doubleVal(doc)); +} - CollectionValue DocValues::getInnerArray() - { - boost::throw_exception(UnsupportedOperationException(L"This optional method is for test purposes only")); - return VariantUtils::null(); - } +ExplanationPtr DocValues::explain(int32_t doc) { + return newLucene(doubleVal(doc), toString(doc)); +} - void DocValues::compute() - { - if (computed) - return; - double sum = 0; - int32_t n = 0; - while (true) - { - double val; - try - { - val = doubleVal(n); - } - catch (IndexOutOfBoundsException&) - { - break; - } - sum += val; - minVal = MiscUtils::isNaN(minVal) ? val : std::min(minVal, val); - maxVal = MiscUtils::isNaN(maxVal) ? val : std::max(maxVal, val); - ++n; - } +CollectionValue DocValues::getInnerArray() { + boost::throw_exception(UnsupportedOperationException(L"This optional method is for test purposes only")); + return VariantUtils::null(); +} - avgVal = n == 0 ? std::numeric_limits::quiet_NaN() : sum / (double)n; - computed = true; +void DocValues::compute() { + if (computed) { + return; } - - double DocValues::getMinValue() - { - compute(); - return minVal; + double sum = 0; + int32_t n = 0; + while (true) { + double val; + try { + val = doubleVal(n); + } catch (IndexOutOfBoundsException&) { + break; + } + sum += val; + minVal = MiscUtils::isNaN(minVal) ? val : std::min(minVal, val); + maxVal = MiscUtils::isNaN(maxVal) ? val : std::max(maxVal, val); + ++n; } - double DocValues::getMaxValue() - { - compute(); - return maxVal; - } + avgVal = n == 0 ? std::numeric_limits::quiet_NaN() : sum / (double)n; + computed = true; +} + +double DocValues::getMinValue() { + compute(); + return minVal; +} + +double DocValues::getMaxValue() { + compute(); + return maxVal; +} + +double DocValues::getAverageValue() { + compute(); + return avgVal; +} - double DocValues::getAverageValue() - { - compute(); - return avgVal; - } } diff --git a/src/core/search/function/DoubleFieldSource.cpp b/src/core/search/function/DoubleFieldSource.cpp index 94311c02..39127345 100644 --- a/src/core/search/function/DoubleFieldSource.cpp +++ b/src/core/search/function/DoubleFieldSource.cpp @@ -10,67 +10,60 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - DoubleFieldSource::DoubleFieldSource(const String& field, const DoubleParserPtr& parser) : FieldCacheSource(field) - { - this->parser = parser; - } +namespace Lucene { - DoubleFieldSource::~DoubleFieldSource() - { - } +DoubleFieldSource::DoubleFieldSource(const String& field, const DoubleParserPtr& parser) : FieldCacheSource(field) { + this->parser = parser; +} - String DoubleFieldSource::description() - { - return L"double(" + FieldCacheSource::description() + L")"; - } +DoubleFieldSource::~DoubleFieldSource() { +} - DocValuesPtr DoubleFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) - { - Collection arr(cache->getDoubles(reader, field, parser)); - return newLucene(shared_from_this(), arr); - } +String DoubleFieldSource::description() { + return L"double(" + FieldCacheSource::description() + L")"; +} - bool DoubleFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) - { - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - DoubleFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); - if (!otherSource) - return false; - return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; - } +DocValuesPtr DoubleFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) { + Collection arr(cache->getDoubles(reader, field, parser)); + return newLucene(shared_from_this(), arr); +} - int32_t DoubleFieldSource::cachedFieldSourceHashCode() - { - return StringUtils::hashCode(parser ? DoubleParser::_getClassName() : DoubleFieldSource::_getClassName()); +bool DoubleFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) { + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } - - DoubleDocValues::DoubleDocValues(const DoubleFieldSourcePtr& source, Collection arr) - { - this->_source = source; - this->arr = arr; + DoubleFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); + if (!otherSource) { + return false; } + return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; +} - DoubleDocValues::~DoubleDocValues() - { - } +int32_t DoubleFieldSource::cachedFieldSourceHashCode() { + return StringUtils::hashCode(parser ? DoubleParser::_getClassName() : DoubleFieldSource::_getClassName()); +} - double DoubleDocValues::doubleVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return arr[doc]; - } +DoubleDocValues::DoubleDocValues(const DoubleFieldSourcePtr& source, Collection arr) { + this->_source = source; + this->arr = arr; +} - String DoubleDocValues::toString(int32_t doc) - { - return DoubleFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(doubleVal(doc)); - } +DoubleDocValues::~DoubleDocValues() { +} - CollectionValue DoubleDocValues::getInnerArray() - { - return arr; +double DoubleDocValues::doubleVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return arr[doc]; +} + +String DoubleDocValues::toString(int32_t doc) { + return DoubleFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(doubleVal(doc)); +} + +CollectionValue DoubleDocValues::getInnerArray() { + return arr; +} + } diff --git a/src/core/search/function/FieldCacheSource.cpp b/src/core/search/function/FieldCacheSource.cpp index 962f4e79..4350e1ec 100644 --- a/src/core/search/function/FieldCacheSource.cpp +++ b/src/core/search/function/FieldCacheSource.cpp @@ -9,37 +9,33 @@ #include "FieldCache.h" #include "StringUtils.h" -namespace Lucene -{ - FieldCacheSource::FieldCacheSource(const String& field) - { - this->field = field; - } +namespace Lucene { - FieldCacheSource::~FieldCacheSource() - { - } +FieldCacheSource::FieldCacheSource(const String& field) { + this->field = field; +} - DocValuesPtr FieldCacheSource::getValues(const IndexReaderPtr& reader) - { - return getCachedFieldValues(FieldCache::DEFAULT(), field, reader); - } +FieldCacheSource::~FieldCacheSource() { +} - String FieldCacheSource::description() - { - return field; - } +DocValuesPtr FieldCacheSource::getValues(const IndexReaderPtr& reader) { + return getCachedFieldValues(FieldCache::DEFAULT(), field, reader); +} - bool FieldCacheSource::equals(const LuceneObjectPtr& other) - { - FieldCacheSourcePtr otherSource(boost::dynamic_pointer_cast(other)); - if (!otherSource) - return false; - return field == otherSource->field && cachedFieldSourceEquals(otherSource); - } +String FieldCacheSource::description() { + return field; +} - int32_t FieldCacheSource::hashCode() - { - return StringUtils::hashCode(field) + cachedFieldSourceHashCode(); +bool FieldCacheSource::equals(const LuceneObjectPtr& other) { + FieldCacheSourcePtr otherSource(boost::dynamic_pointer_cast(other)); + if (!otherSource) { + return false; } + return field == otherSource->field && cachedFieldSourceEquals(otherSource); +} + +int32_t FieldCacheSource::hashCode() { + return StringUtils::hashCode(field) + cachedFieldSourceHashCode(); +} + } diff --git a/src/core/search/function/FieldScoreQuery.cpp b/src/core/search/function/FieldScoreQuery.cpp index a9c3f6e7..4a5d4acb 100644 --- a/src/core/search/function/FieldScoreQuery.cpp +++ b/src/core/search/function/FieldScoreQuery.cpp @@ -10,29 +10,26 @@ #include "IntFieldSource.h" #include "DoubleFieldSource.h" -namespace Lucene -{ - FieldScoreQuery::FieldScoreQuery(const String& field, Type type) : ValueSourceQuery(getValueSource(field,type)) - { - } +namespace Lucene { - FieldScoreQuery::~FieldScoreQuery() - { - } +FieldScoreQuery::FieldScoreQuery(const String& field, Type type) : ValueSourceQuery(getValueSource(field,type)) { +} - ValueSourcePtr FieldScoreQuery::getValueSource(const String& field, Type type) - { - switch (type) - { - case BYTE: - return newLucene(field); - case INT: - return newLucene(field); - case DOUBLE: - return newLucene(field); - default: - boost::throw_exception(IllegalArgumentException(L"not a known Field Score Query Type")); - return ValueSourcePtr(); - } +FieldScoreQuery::~FieldScoreQuery() { +} + +ValueSourcePtr FieldScoreQuery::getValueSource(const String& field, Type type) { + switch (type) { + case BYTE: + return newLucene(field); + case INT: + return newLucene(field); + case DOUBLE: + return newLucene(field); + default: + boost::throw_exception(IllegalArgumentException(L"not a known Field Score Query Type")); + return ValueSourcePtr(); } } + +} diff --git a/src/core/search/function/IntFieldSource.cpp b/src/core/search/function/IntFieldSource.cpp index f6a3ebe0..0af3425f 100644 --- a/src/core/search/function/IntFieldSource.cpp +++ b/src/core/search/function/IntFieldSource.cpp @@ -11,74 +11,67 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - IntFieldSource::IntFieldSource(const String& field, const IntParserPtr& parser) : FieldCacheSource(field) - { - this->parser = parser; - } +namespace Lucene { - IntFieldSource::~IntFieldSource() - { - } +IntFieldSource::IntFieldSource(const String& field, const IntParserPtr& parser) : FieldCacheSource(field) { + this->parser = parser; +} - String IntFieldSource::description() - { - return L"int(" + FieldCacheSource::description() + L")"; - } +IntFieldSource::~IntFieldSource() { +} - DocValuesPtr IntFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) - { - Collection arr(cache->getInts(reader, field, parser)); - return newLucene(shared_from_this(), arr); - } +String IntFieldSource::description() { + return L"int(" + FieldCacheSource::description() + L")"; +} - bool IntFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) - { - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - IntFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); - if (!otherSource) - return false; - return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; - } +DocValuesPtr IntFieldSource::getCachedFieldValues(const FieldCachePtr& cache, const String& field, const IndexReaderPtr& reader) { + Collection arr(cache->getInts(reader, field, parser)); + return newLucene(shared_from_this(), arr); +} - int32_t IntFieldSource::cachedFieldSourceHashCode() - { - return StringUtils::hashCode(parser ? IntParser::_getClassName() : IntFieldSource::_getClassName()); +bool IntFieldSource::cachedFieldSourceEquals(const FieldCacheSourcePtr& other) { + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } - - IntDocValues::IntDocValues(const IntFieldSourcePtr& source, Collection arr) - { - this->_source = source; - this->arr = arr; + IntFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); + if (!otherSource) { + return false; } + return parser ? MiscUtils::equalTypes(parser, otherSource->parser) : !otherSource->parser; +} - IntDocValues::~IntDocValues() - { - } +int32_t IntFieldSource::cachedFieldSourceHashCode() { + return StringUtils::hashCode(parser ? IntParser::_getClassName() : IntFieldSource::_getClassName()); +} - double IntDocValues::doubleVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (double)arr[doc]; - } +IntDocValues::IntDocValues(const IntFieldSourcePtr& source, Collection arr) { + this->_source = source; + this->arr = arr; +} - int32_t IntDocValues::intVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return arr[doc]; - } +IntDocValues::~IntDocValues() { +} - String IntDocValues::toString(int32_t doc) - { - return IntFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); +double IntDocValues::doubleVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return (double)arr[doc]; +} - CollectionValue IntDocValues::getInnerArray() - { - return arr; +int32_t IntDocValues::intVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return arr[doc]; +} + +String IntDocValues::toString(int32_t doc) { + return IntFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); +} + +CollectionValue IntDocValues::getInnerArray() { + return arr; +} + } diff --git a/src/core/search/function/OrdFieldSource.cpp b/src/core/search/function/OrdFieldSource.cpp index 011049bd..66332b78 100644 --- a/src/core/search/function/OrdFieldSource.cpp +++ b/src/core/search/function/OrdFieldSource.cpp @@ -11,75 +11,68 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - OrdFieldSource::OrdFieldSource(const String& field) - { - this->field = field; - } +namespace Lucene { - OrdFieldSource::~OrdFieldSource() - { - } +OrdFieldSource::OrdFieldSource(const String& field) { + this->field = field; +} - String OrdFieldSource::description() - { - return L"ord(" + field + L")"; - } +OrdFieldSource::~OrdFieldSource() { +} - DocValuesPtr OrdFieldSource::getValues(const IndexReaderPtr& reader) - { - Collection arr(FieldCache::DEFAULT()->getStringIndex(reader, field)->order); - return newLucene(shared_from_this(), arr); - } +String OrdFieldSource::description() { + return L"ord(" + field + L")"; +} - bool OrdFieldSource::equals(const LuceneObjectPtr& other) - { - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - OrdFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); - if (!otherSource) - return false; - return field == otherSource->field; - } +DocValuesPtr OrdFieldSource::getValues(const IndexReaderPtr& reader) { + Collection arr(FieldCache::DEFAULT()->getStringIndex(reader, field)->order); + return newLucene(shared_from_this(), arr); +} - int32_t OrdFieldSource::hashCode() - { - return StringUtils::hashCode(OrdFieldSource::_getClassName()) + StringUtils::hashCode(field); +bool OrdFieldSource::equals(const LuceneObjectPtr& other) { + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } - - OrdDocValues::OrdDocValues(const OrdFieldSourcePtr& source, Collection arr) - { - this->_source = source; - this->arr = arr; + OrdFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); + if (!otherSource) { + return false; } + return field == otherSource->field; +} - OrdDocValues::~OrdDocValues() - { - } +int32_t OrdFieldSource::hashCode() { + return StringUtils::hashCode(OrdFieldSource::_getClassName()) + StringUtils::hashCode(field); +} - double OrdDocValues::doubleVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (double)arr[doc]; - } +OrdDocValues::OrdDocValues(const OrdFieldSourcePtr& source, Collection arr) { + this->_source = source; + this->arr = arr; +} - String OrdDocValues::strVal(int32_t doc) - { - // the string value of the ordinal, not the string itself - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return StringUtils::toString(arr[doc]); - } +OrdDocValues::~OrdDocValues() { +} - String OrdDocValues::toString(int32_t doc) - { - return OrdFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); +double OrdDocValues::doubleVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return (double)arr[doc]; +} - CollectionValue OrdDocValues::getInnerArray() - { - return arr; +String OrdDocValues::strVal(int32_t doc) { + // the string value of the ordinal, not the string itself + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return StringUtils::toString(arr[doc]); +} + +String OrdDocValues::toString(int32_t doc) { + return OrdFieldSourcePtr(_source)->description() + L"=" + StringUtils::toString(intVal(doc)); +} + +CollectionValue OrdDocValues::getInnerArray() { + return arr; +} + } diff --git a/src/core/search/function/ReverseOrdFieldSource.cpp b/src/core/search/function/ReverseOrdFieldSource.cpp index 50c08dfb..e7f7f8dd 100644 --- a/src/core/search/function/ReverseOrdFieldSource.cpp +++ b/src/core/search/function/ReverseOrdFieldSource.cpp @@ -11,83 +11,75 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - ReverseOrdFieldSource::ReverseOrdFieldSource(const String& field) - { - this->field = field; - } +namespace Lucene { - ReverseOrdFieldSource::~ReverseOrdFieldSource() - { - } +ReverseOrdFieldSource::ReverseOrdFieldSource(const String& field) { + this->field = field; +} - String ReverseOrdFieldSource::description() - { - return L"rord(" + field + L")"; - } +ReverseOrdFieldSource::~ReverseOrdFieldSource() { +} - DocValuesPtr ReverseOrdFieldSource::getValues(const IndexReaderPtr& reader) - { - StringIndexPtr sindex(FieldCache::DEFAULT()->getStringIndex(reader, field)); - Collection arr(sindex->order); - int32_t end = sindex->lookup.size(); - return newLucene(shared_from_this(), arr, end); - } +String ReverseOrdFieldSource::description() { + return L"rord(" + field + L")"; +} - bool ReverseOrdFieldSource::equals(const LuceneObjectPtr& other) - { - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - ReverseOrdFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); - if (!otherSource) - return false; - return field == otherSource->field; - } +DocValuesPtr ReverseOrdFieldSource::getValues(const IndexReaderPtr& reader) { + StringIndexPtr sindex(FieldCache::DEFAULT()->getStringIndex(reader, field)); + Collection arr(sindex->order); + int32_t end = sindex->lookup.size(); + return newLucene(shared_from_this(), arr, end); +} - int32_t ReverseOrdFieldSource::hashCode() - { - return StringUtils::hashCode(ReverseOrdFieldSource::_getClassName()) + StringUtils::hashCode(field); +bool ReverseOrdFieldSource::equals(const LuceneObjectPtr& other) { + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; } - - ReverseOrdDocValues::ReverseOrdDocValues(const ReverseOrdFieldSourcePtr& source, Collection arr, int32_t end) - { - this->_source = source; - this->arr = arr; - this->end = end; + ReverseOrdFieldSourcePtr otherSource(boost::dynamic_pointer_cast(other)); + if (!otherSource) { + return false; } + return field == otherSource->field; +} - ReverseOrdDocValues::~ReverseOrdDocValues() - { - } +int32_t ReverseOrdFieldSource::hashCode() { + return StringUtils::hashCode(ReverseOrdFieldSource::_getClassName()) + StringUtils::hashCode(field); +} - double ReverseOrdDocValues::doubleVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (double)(end - arr[doc]); - } +ReverseOrdDocValues::ReverseOrdDocValues(const ReverseOrdFieldSourcePtr& source, Collection arr, int32_t end) { + this->_source = source; + this->arr = arr; + this->end = end; +} - int32_t ReverseOrdDocValues::intVal(int32_t doc) - { - if (doc < 0 || doc >= arr.size()) - boost::throw_exception(IndexOutOfBoundsException()); - return (end - arr[doc]); - } +ReverseOrdDocValues::~ReverseOrdDocValues() { +} - String ReverseOrdDocValues::strVal(int32_t doc) - { - // the string value of the ordinal, not the string itself - return StringUtils::toString(intVal(doc)); +double ReverseOrdDocValues::doubleVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return (double)(end - arr[doc]); +} - String ReverseOrdDocValues::toString(int32_t doc) - { - return ReverseOrdFieldSourcePtr(_source)->description() + L"=" + strVal(doc); +int32_t ReverseOrdDocValues::intVal(int32_t doc) { + if (doc < 0 || doc >= arr.size()) { + boost::throw_exception(IndexOutOfBoundsException()); } + return (end - arr[doc]); +} + +String ReverseOrdDocValues::strVal(int32_t doc) { + // the string value of the ordinal, not the string itself + return StringUtils::toString(intVal(doc)); +} + +String ReverseOrdDocValues::toString(int32_t doc) { + return ReverseOrdFieldSourcePtr(_source)->description() + L"=" + strVal(doc); +} + +CollectionValue ReverseOrdDocValues::getInnerArray() { + return arr; +} - CollectionValue ReverseOrdDocValues::getInnerArray() - { - return arr; - } } diff --git a/src/core/search/function/ValueSource.cpp b/src/core/search/function/ValueSource.cpp index b38f511f..fa4b30c7 100644 --- a/src/core/search/function/ValueSource.cpp +++ b/src/core/search/function/ValueSource.cpp @@ -7,14 +7,13 @@ #include "LuceneInc.h" #include "ValueSource.h" -namespace Lucene -{ - ValueSource::~ValueSource() - { - } +namespace Lucene { + +ValueSource::~ValueSource() { +} + +String ValueSource::toString() { + return description(); +} - String ValueSource::toString() - { - return description(); - } } diff --git a/src/core/search/function/ValueSourceQuery.cpp b/src/core/search/function/ValueSourceQuery.cpp index d86cbe09..07f6e3fb 100644 --- a/src/core/search/function/ValueSourceQuery.cpp +++ b/src/core/search/function/ValueSourceQuery.cpp @@ -15,141 +15,120 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - ValueSourceQuery::ValueSourceQuery(const ValueSourcePtr& valSrc) - { - this->valSrc = valSrc; - } +namespace Lucene { - ValueSourceQuery::~ValueSourceQuery() - { - } +ValueSourceQuery::ValueSourceQuery(const ValueSourcePtr& valSrc) { + this->valSrc = valSrc; +} - QueryPtr ValueSourceQuery::rewrite(const IndexReaderPtr& reader) - { - return shared_from_this(); - } +ValueSourceQuery::~ValueSourceQuery() { +} - void ValueSourceQuery::extractTerms(SetTerm terms) - { - // no terms involved here - } +QueryPtr ValueSourceQuery::rewrite(const IndexReaderPtr& reader) { + return shared_from_this(); +} - WeightPtr ValueSourceQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +void ValueSourceQuery::extractTerms(SetTerm terms) { + // no terms involved here +} - String ValueSourceQuery::toString(const String& field) - { - return valSrc->toString() + boostString(); - } +WeightPtr ValueSourceQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - bool ValueSourceQuery::equals(const LuceneObjectPtr& other) - { - ValueSourceQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - return (getBoost() == otherQuery->getBoost() && valSrc->equals(otherQuery->valSrc)); - } +String ValueSourceQuery::toString(const String& field) { + return valSrc->toString() + boostString(); +} - int32_t ValueSourceQuery::hashCode() - { - return (StringUtils::hashCode(ValueSourceQuery::_getClassName()) + valSrc->hashCode()) ^ MiscUtils::doubleToIntBits(getBoost()); +bool ValueSourceQuery::equals(const LuceneObjectPtr& other) { + ValueSourceQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } + return (getBoost() == otherQuery->getBoost() && valSrc->equals(otherQuery->valSrc)); +} - LuceneObjectPtr ValueSourceQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(valSrc); - ValueSourceQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); - cloneQuery->valSrc = valSrc; - return cloneQuery; - } +int32_t ValueSourceQuery::hashCode() { + return (StringUtils::hashCode(ValueSourceQuery::_getClassName()) + valSrc->hashCode()) ^ MiscUtils::doubleToIntBits(getBoost()); +} - ValueSourceWeight::ValueSourceWeight(const ValueSourceQueryPtr& query, const SearcherPtr& searcher) - { - this->query = query; - this->similarity = query->getSimilarity(searcher); - } +LuceneObjectPtr ValueSourceQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(valSrc); + ValueSourceQueryPtr cloneQuery(boost::dynamic_pointer_cast(Query::clone(clone))); + cloneQuery->valSrc = valSrc; + return cloneQuery; +} - ValueSourceWeight::~ValueSourceWeight() - { - } +ValueSourceWeight::ValueSourceWeight(const ValueSourceQueryPtr& query, const SearcherPtr& searcher) { + this->query = query; + this->similarity = query->getSimilarity(searcher); +} - QueryPtr ValueSourceWeight::getQuery() - { - return query; - } +ValueSourceWeight::~ValueSourceWeight() { +} - double ValueSourceWeight::getValue() - { - return queryWeight; - } +QueryPtr ValueSourceWeight::getQuery() { + return query; +} - double ValueSourceWeight::sumOfSquaredWeights() - { - queryWeight = query->getBoost(); - return queryWeight * queryWeight; - } +double ValueSourceWeight::getValue() { + return queryWeight; +} - void ValueSourceWeight::normalize(double norm) - { - queryNorm = norm; - queryWeight *= queryNorm; - } +double ValueSourceWeight::sumOfSquaredWeights() { + queryWeight = query->getBoost(); + return queryWeight * queryWeight; +} - ScorerPtr ValueSourceWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - return newLucene(similarity, reader, shared_from_this()); - } +void ValueSourceWeight::normalize(double norm) { + queryNorm = norm; + queryWeight *= queryNorm; +} - ExplanationPtr ValueSourceWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - DocValuesPtr vals(query->valSrc->getValues(reader)); - double sc = queryWeight * vals->doubleVal(doc); +ScorerPtr ValueSourceWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + return newLucene(similarity, reader, shared_from_this()); +} - ExplanationPtr result(newLucene(true, sc, query->toString() + L", product of:")); +ExplanationPtr ValueSourceWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + DocValuesPtr vals(query->valSrc->getValues(reader)); + double sc = queryWeight * vals->doubleVal(doc); - result->addDetail(vals->explain(doc)); - result->addDetail(newLucene(query->getBoost(), L"boost")); - result->addDetail(newLucene(queryNorm, L"queryNorm")); - return result; - } + ExplanationPtr result(newLucene(true, sc, query->toString() + L", product of:")); - ValueSourceScorer::ValueSourceScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const ValueSourceWeightPtr& weight) : Scorer(similarity) - { - this->weight = weight; - this->qWeight = weight->getValue(); - this->doc = -1; - // this is when/where the values are first created. - vals = weight->query->valSrc->getValues(reader); - termDocs = reader->termDocs(TermPtr()); - } + result->addDetail(vals->explain(doc)); + result->addDetail(newLucene(query->getBoost(), L"boost")); + result->addDetail(newLucene(queryNorm, L"queryNorm")); + return result; +} - ValueSourceScorer::~ValueSourceScorer() - { - } +ValueSourceScorer::ValueSourceScorer(const SimilarityPtr& similarity, const IndexReaderPtr& reader, const ValueSourceWeightPtr& weight) : Scorer(similarity) { + this->weight = weight; + this->qWeight = weight->getValue(); + this->doc = -1; + // this is when/where the values are first created. + vals = weight->query->valSrc->getValues(reader); + termDocs = reader->termDocs(TermPtr()); +} - int32_t ValueSourceScorer::nextDoc() - { - doc = termDocs->next() ? termDocs->doc() : NO_MORE_DOCS; - return doc; - } +ValueSourceScorer::~ValueSourceScorer() { +} - int32_t ValueSourceScorer::docID() - { - return doc; - } +int32_t ValueSourceScorer::nextDoc() { + doc = termDocs->next() ? termDocs->doc() : NO_MORE_DOCS; + return doc; +} - int32_t ValueSourceScorer::advance(int32_t target) - { - doc = termDocs->skipTo(target) ? termDocs->doc() : NO_MORE_DOCS; - return doc; - } +int32_t ValueSourceScorer::docID() { + return doc; +} + +int32_t ValueSourceScorer::advance(int32_t target) { + doc = termDocs->skipTo(target) ? termDocs->doc() : NO_MORE_DOCS; + return doc; +} + +double ValueSourceScorer::score() { + return qWeight * vals->doubleVal(termDocs->doc()); +} - double ValueSourceScorer::score() - { - return qWeight * vals->doubleVal(termDocs->doc()); - } } diff --git a/src/core/search/payloads/AveragePayloadFunction.cpp b/src/core/search/payloads/AveragePayloadFunction.cpp index 537051d7..f34ba229 100644 --- a/src/core/search/payloads/AveragePayloadFunction.cpp +++ b/src/core/search/payloads/AveragePayloadFunction.cpp @@ -9,39 +9,38 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - AveragePayloadFunction::~AveragePayloadFunction() - { - } +namespace Lucene { - double AveragePayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, - int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) - { - return currentPayloadScore + currentScore; - } +AveragePayloadFunction::~AveragePayloadFunction() { +} - double AveragePayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) - { - return numPayloadsSeen > 0 ? (payloadScore / (double)numPayloadsSeen) : 1.0; - } +double AveragePayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, + int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { + return currentPayloadScore + currentScore; +} - int32_t AveragePayloadFunction::hashCode() - { - int32_t prime = 31; - int32_t result = 1; - result = prime * result + StringUtils::hashCode(getClassName()); - return result; - } +double AveragePayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) { + return numPayloadsSeen > 0 ? (payloadScore / (double)numPayloadsSeen) : 1.0; +} - bool AveragePayloadFunction::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; +int32_t AveragePayloadFunction::hashCode() { + int32_t prime = 31; + int32_t result = 1; + result = prime * result + StringUtils::hashCode(getClassName()); + return result; +} + +bool AveragePayloadFunction::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { return true; } + if (!other) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + return true; +} + } diff --git a/src/core/search/payloads/MaxPayloadFunction.cpp b/src/core/search/payloads/MaxPayloadFunction.cpp index 0062f7f8..ff7db7ce 100644 --- a/src/core/search/payloads/MaxPayloadFunction.cpp +++ b/src/core/search/payloads/MaxPayloadFunction.cpp @@ -9,42 +9,42 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - MaxPayloadFunction::~MaxPayloadFunction() - { - } +namespace Lucene { - double MaxPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, - int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) - { - if (numPayloadsSeen == 0) - return currentPayloadScore; - else - return std::max(currentPayloadScore, currentScore); - } +MaxPayloadFunction::~MaxPayloadFunction() { +} - double MaxPayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) - { - return numPayloadsSeen > 0 ? payloadScore : 1.0; +double MaxPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, + int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { + if (numPayloadsSeen == 0) { + return currentPayloadScore; + } else { + return std::max(currentPayloadScore, currentScore); } +} - int32_t MaxPayloadFunction::hashCode() - { - int32_t prime = 31; - int32_t result = 1; - result = prime * result + StringUtils::hashCode(getClassName()); - return result; - } +double MaxPayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) { + return numPayloadsSeen > 0 ? payloadScore : 1.0; +} - bool MaxPayloadFunction::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; +int32_t MaxPayloadFunction::hashCode() { + int32_t prime = 31; + int32_t result = 1; + result = prime * result + StringUtils::hashCode(getClassName()); + return result; +} + +bool MaxPayloadFunction::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { return true; } + if (!other) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + return true; +} + } diff --git a/src/core/search/payloads/MinPayloadFunction.cpp b/src/core/search/payloads/MinPayloadFunction.cpp index a2d61dd3..4dec9aef 100644 --- a/src/core/search/payloads/MinPayloadFunction.cpp +++ b/src/core/search/payloads/MinPayloadFunction.cpp @@ -9,42 +9,42 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - MinPayloadFunction::~MinPayloadFunction() - { - } +namespace Lucene { - double MinPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, - int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) - { - if (numPayloadsSeen == 0) - return currentPayloadScore; - else - return std::min(currentPayloadScore, currentScore); - } +MinPayloadFunction::~MinPayloadFunction() { +} - double MinPayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) - { - return numPayloadsSeen > 0 ? payloadScore : 1.0; +double MinPayloadFunction::currentScore(int32_t docId, const String& field, int32_t start, int32_t end, + int32_t numPayloadsSeen, double currentScore, double currentPayloadScore) { + if (numPayloadsSeen == 0) { + return currentPayloadScore; + } else { + return std::min(currentPayloadScore, currentScore); } +} - int32_t MinPayloadFunction::hashCode() - { - int32_t prime = 31; - int32_t result = 1; - result = prime * result + StringUtils::hashCode(getClassName()); - return result; - } +double MinPayloadFunction::docScore(int32_t docId, const String& field, int32_t numPayloadsSeen, double payloadScore) { + return numPayloadsSeen > 0 ? payloadScore : 1.0; +} - bool MinPayloadFunction::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!other) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; +int32_t MinPayloadFunction::hashCode() { + int32_t prime = 31; + int32_t result = 1; + result = prime * result + StringUtils::hashCode(getClassName()); + return result; +} + +bool MinPayloadFunction::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { return true; } + if (!other) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + return true; +} + } diff --git a/src/core/search/payloads/PayloadFunction.cpp b/src/core/search/payloads/PayloadFunction.cpp index 7e458ab8..05aeec73 100644 --- a/src/core/search/payloads/PayloadFunction.cpp +++ b/src/core/search/payloads/PayloadFunction.cpp @@ -7,13 +7,12 @@ #include "LuceneInc.h" #include "PayloadFunction.h" -namespace Lucene -{ - PayloadFunction::PayloadFunction() - { - } +namespace Lucene { + +PayloadFunction::PayloadFunction() { +} + +PayloadFunction::~PayloadFunction() { +} - PayloadFunction::~PayloadFunction() - { - } } diff --git a/src/core/search/payloads/PayloadNearQuery.cpp b/src/core/search/payloads/PayloadNearQuery.cpp index 378b1f3e..7283a021 100644 --- a/src/core/search/payloads/PayloadNearQuery.cpp +++ b/src/core/search/payloads/PayloadNearQuery.cpp @@ -14,178 +14,165 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - PayloadNearQuery::PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder) : SpanNearQuery(clauses, slop, inOrder) - { - fieldName = clauses[0]->getField(); // all clauses must have same field - this->function = newLucene(); - } +namespace Lucene { - PayloadNearQuery::PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, const PayloadFunctionPtr& function) : SpanNearQuery(clauses, slop, inOrder) - { - fieldName = clauses[0]->getField(); // all clauses must have same field - this->function = function; - } +PayloadNearQuery::PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder) : SpanNearQuery(clauses, slop, inOrder) { + fieldName = clauses[0]->getField(); // all clauses must have same field + this->function = newLucene(); +} - PayloadNearQuery::~PayloadNearQuery() - { - } +PayloadNearQuery::PayloadNearQuery(Collection clauses, int32_t slop, bool inOrder, const PayloadFunctionPtr& function) : SpanNearQuery(clauses, slop, inOrder) { + fieldName = clauses[0]->getField(); // all clauses must have same field + this->function = function; +} - WeightPtr PayloadNearQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +PayloadNearQuery::~PayloadNearQuery() { +} - LuceneObjectPtr PayloadNearQuery::clone(const LuceneObjectPtr& other) - { - int32_t sz = clauses.size(); - Collection newClauses(Collection::newInstance(sz)); +WeightPtr PayloadNearQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - for (int32_t i = 0; i < sz; ++i) - newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); +LuceneObjectPtr PayloadNearQuery::clone(const LuceneObjectPtr& other) { + int32_t sz = clauses.size(); + Collection newClauses(Collection::newInstance(sz)); - PayloadNearQueryPtr payloadNearQuery(newLucene(newClauses, slop, inOrder)); - payloadNearQuery->setBoost(getBoost()); - return payloadNearQuery; + for (int32_t i = 0; i < sz; ++i) { + newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); } - String PayloadNearQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"payloadNear(["; - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - { - if (clause != clauses.begin()) - buffer << L", "; - buffer << (*clause)->toString(field); + PayloadNearQueryPtr payloadNearQuery(newLucene(newClauses, slop, inOrder)); + payloadNearQuery->setBoost(getBoost()); + return payloadNearQuery; +} + +String PayloadNearQuery::toString(const String& field) { + StringStream buffer; + buffer << L"payloadNear(["; + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + if (clause != clauses.begin()) { + buffer << L", "; } - buffer << L"], " << slop << L", " << inOrder << L")" << boostString(); - return buffer.str(); + buffer << (*clause)->toString(field); } + buffer << L"], " << slop << L", " << inOrder << L")" << boostString(); + return buffer.str(); +} - bool PayloadNearQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!SpanNearQuery::equals(other)) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - PayloadNearQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - if (fieldName != otherQuery->fieldName) +bool PayloadNearQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!SpanNearQuery::equals(other)) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + PayloadNearQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; + } + if (fieldName != otherQuery->fieldName) { + return false; + } + if (!function) { + if (otherQuery->function) { return false; - if (!function) - { - if (otherQuery->function) - return false; } - else if (!function->equals(otherQuery->function)) - return false; - return true; + } else if (!function->equals(otherQuery->function)) { + return false; } + return true; +} - int32_t PayloadNearQuery::hashCode() - { - int32_t prime = 31; - int32_t result = SpanNearQuery::hashCode(); - result = prime * result + (fieldName.empty() ? 0 : StringUtils::hashCode(fieldName)); - result = prime * result + (!function ? 0 : function->hashCode()); - return result; - } +int32_t PayloadNearQuery::hashCode() { + int32_t prime = 31; + int32_t result = SpanNearQuery::hashCode(); + result = prime * result + (fieldName.empty() ? 0 : StringUtils::hashCode(fieldName)); + result = prime * result + (!function ? 0 : function->hashCode()); + return result; +} - PayloadNearSpanWeight::PayloadNearSpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher) : SpanWeight(query, searcher) - { - } +PayloadNearSpanWeight::PayloadNearSpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher) : SpanWeight(query, searcher) { +} - PayloadNearSpanWeight::~PayloadNearSpanWeight() - { - } +PayloadNearSpanWeight::~PayloadNearSpanWeight() { +} - ScorerPtr PayloadNearSpanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); - } +ScorerPtr PayloadNearSpanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); +} - PayloadNearSpanScorer::PayloadNearSpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) - { - this->spans = spans; - this->payloadScore = 0.0; - this->payloadsSeen = 0; - this->similarity = getSimilarity(); - } +PayloadNearSpanScorer::PayloadNearSpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) { + this->spans = spans; + this->payloadScore = 0.0; + this->payloadsSeen = 0; + this->similarity = getSimilarity(); +} - PayloadNearSpanScorer::~PayloadNearSpanScorer() - { - } +PayloadNearSpanScorer::~PayloadNearSpanScorer() { +} - void PayloadNearSpanScorer::getPayloads(Collection subSpans) - { - for (Collection::iterator span = subSpans.begin(); span != subSpans.end(); ++span) - { - if (MiscUtils::typeOf(*span)) - { - NearSpansOrderedPtr ordered(boost::static_pointer_cast(*span)); - if (ordered->isPayloadAvailable()) - processPayloads(ordered->getPayload(), ordered->start(), ordered->end()); - getPayloads(ordered->getSubSpans()); +void PayloadNearSpanScorer::getPayloads(Collection subSpans) { + for (Collection::iterator span = subSpans.begin(); span != subSpans.end(); ++span) { + if (MiscUtils::typeOf(*span)) { + NearSpansOrderedPtr ordered(boost::static_pointer_cast(*span)); + if (ordered->isPayloadAvailable()) { + processPayloads(ordered->getPayload(), ordered->start(), ordered->end()); } - else if (MiscUtils::typeOf(*span)) - { - NearSpansUnorderedPtr unordered(boost::static_pointer_cast(*span)); - if (unordered->isPayloadAvailable()) - processPayloads(unordered->getPayload(), unordered->start(), unordered->end()); - getPayloads(unordered->getSubSpans()); + getPayloads(ordered->getSubSpans()); + } else if (MiscUtils::typeOf(*span)) { + NearSpansUnorderedPtr unordered(boost::static_pointer_cast(*span)); + if (unordered->isPayloadAvailable()) { + processPayloads(unordered->getPayload(), unordered->start(), unordered->end()); } + getPayloads(unordered->getSubSpans()); } } +} - void PayloadNearSpanScorer::processPayloads(Collection payLoads, int32_t start, int32_t end) - { - PayloadNearSpanWeightPtr spanWeight(boost::static_pointer_cast(weight)); - PayloadNearQueryPtr nearQuery(boost::static_pointer_cast(spanWeight->query)); - - for (Collection::iterator payload = payLoads.begin(); payload != payLoads.end(); ++payload) - { - payloadScore = nearQuery->function->currentScore(doc, nearQuery->fieldName, start, end, payloadsSeen, payloadScore, - similarity->scorePayload(doc, nearQuery->fieldName, spans->start(), - spans->end(), *payload, 0, payload->size())); - ++payloadsSeen; - } - } +void PayloadNearSpanScorer::processPayloads(Collection payLoads, int32_t start, int32_t end) { + PayloadNearSpanWeightPtr spanWeight(boost::static_pointer_cast(weight)); + PayloadNearQueryPtr nearQuery(boost::static_pointer_cast(spanWeight->query)); - bool PayloadNearSpanScorer::setFreqCurrentDoc() - { - if (!more) - return false; - Collection spansArr(newCollection(spans)); - payloadScore = 0.0; - payloadsSeen = 0; - getPayloads(spansArr); - return SpanScorer::setFreqCurrentDoc(); + for (Collection::iterator payload = payLoads.begin(); payload != payLoads.end(); ++payload) { + payloadScore = nearQuery->function->currentScore(doc, nearQuery->fieldName, start, end, payloadsSeen, payloadScore, + similarity->scorePayload(doc, nearQuery->fieldName, spans->start(), + spans->end(), *payload, 0, payload->size())); + ++payloadsSeen; } +} - double PayloadNearSpanScorer::score() - { - PayloadNearSpanWeightPtr spanWeight(boost::static_pointer_cast(weight)); - PayloadNearQueryPtr nearQuery(boost::static_pointer_cast(spanWeight->query)); - return SpanScorer::score() * nearQuery->function->docScore(doc, nearQuery->fieldName, payloadsSeen, payloadScore); +bool PayloadNearSpanScorer::setFreqCurrentDoc() { + if (!more) { + return false; } + Collection spansArr(newCollection(spans)); + payloadScore = 0.0; + payloadsSeen = 0; + getPayloads(spansArr); + return SpanScorer::setFreqCurrentDoc(); +} + +double PayloadNearSpanScorer::score() { + PayloadNearSpanWeightPtr spanWeight(boost::static_pointer_cast(weight)); + PayloadNearQueryPtr nearQuery(boost::static_pointer_cast(spanWeight->query)); + return SpanScorer::score() * nearQuery->function->docScore(doc, nearQuery->fieldName, payloadsSeen, payloadScore); +} + +ExplanationPtr PayloadNearSpanScorer::explain(int32_t doc) { + ExplanationPtr result(newLucene()); + ExplanationPtr nonPayloadExpl(SpanScorer::explain(doc)); + result->addDetail(nonPayloadExpl); + ExplanationPtr payloadBoost(newLucene()); + result->addDetail(payloadBoost); + double avgPayloadScore = (payloadsSeen > 0 ? (payloadScore / (double)payloadsSeen) : 1.0); + payloadBoost->setValue(avgPayloadScore); + payloadBoost->setDescription(L"scorePayload(...)"); + result->setValue(nonPayloadExpl->getValue() * avgPayloadScore); + result->setDescription(L"bnq, product of:"); + return result; +} - ExplanationPtr PayloadNearSpanScorer::explain(int32_t doc) - { - ExplanationPtr result(newLucene()); - ExplanationPtr nonPayloadExpl(SpanScorer::explain(doc)); - result->addDetail(nonPayloadExpl); - ExplanationPtr payloadBoost(newLucene()); - result->addDetail(payloadBoost); - double avgPayloadScore = (payloadsSeen > 0 ? (payloadScore / (double)payloadsSeen) : 1.0); - payloadBoost->setValue(avgPayloadScore); - payloadBoost->setDescription(L"scorePayload(...)"); - result->setValue(nonPayloadExpl->getValue() * avgPayloadScore); - result->setDescription(L"bnq, product of:"); - return result; - } } diff --git a/src/core/search/payloads/PayloadSpanUtil.cpp b/src/core/search/payloads/PayloadSpanUtil.cpp index 28b4f63f..751f3924 100644 --- a/src/core/search/payloads/PayloadSpanUtil.cpp +++ b/src/core/search/payloads/PayloadSpanUtil.cpp @@ -20,147 +20,129 @@ #include "Spans.h" #include "MiscUtils.h" -namespace Lucene -{ - PayloadSpanUtil::PayloadSpanUtil(const IndexReaderPtr& reader) - { - this->reader = reader; - } +namespace Lucene { - PayloadSpanUtil::~PayloadSpanUtil() - { - } +PayloadSpanUtil::PayloadSpanUtil(const IndexReaderPtr& reader) { + this->reader = reader; +} - Collection PayloadSpanUtil::getPayloadsForQuery(const QueryPtr& query) - { - Collection payloads(Collection::newInstance()); - queryToSpanQuery(query, payloads); - return payloads; - } +PayloadSpanUtil::~PayloadSpanUtil() { +} + +Collection PayloadSpanUtil::getPayloadsForQuery(const QueryPtr& query) { + Collection payloads(Collection::newInstance()); + queryToSpanQuery(query, payloads); + return payloads; +} - void PayloadSpanUtil::queryToSpanQuery(const QueryPtr& query, Collection payloads) - { - if (MiscUtils::typeOf(query)) - { - BooleanQueryPtr booleanQuery(boost::dynamic_pointer_cast(query)); - Collection queryClauses(booleanQuery->getClauses()); - for (Collection::iterator clause = queryClauses.begin(); clause != queryClauses.end(); ++clause) - { - if (!(*clause)->isProhibited()) - queryToSpanQuery((*clause)->getQuery(), payloads); +void PayloadSpanUtil::queryToSpanQuery(const QueryPtr& query, Collection payloads) { + if (MiscUtils::typeOf(query)) { + BooleanQueryPtr booleanQuery(boost::dynamic_pointer_cast(query)); + Collection queryClauses(booleanQuery->getClauses()); + for (Collection::iterator clause = queryClauses.begin(); clause != queryClauses.end(); ++clause) { + if (!(*clause)->isProhibited()) { + queryToSpanQuery((*clause)->getQuery(), payloads); } } - else if (MiscUtils::typeOf(query)) - { - PhraseQueryPtr phraseQuery(boost::dynamic_pointer_cast(query)); - Collection phraseQueryTerms(phraseQuery->getTerms()); - Collection clauses(Collection::newInstance(phraseQueryTerms.size())); - for (int32_t i = 0; i < phraseQueryTerms.size(); ++i) - clauses[i] = newLucene(phraseQueryTerms[i]); - - int32_t slop = phraseQuery->getSlop(); - bool inorder = false; + } else if (MiscUtils::typeOf(query)) { + PhraseQueryPtr phraseQuery(boost::dynamic_pointer_cast(query)); + Collection phraseQueryTerms(phraseQuery->getTerms()); + Collection clauses(Collection::newInstance(phraseQueryTerms.size())); + for (int32_t i = 0; i < phraseQueryTerms.size(); ++i) { + clauses[i] = newLucene(phraseQueryTerms[i]); + } - if (slop == 0) - inorder = true; + int32_t slop = phraseQuery->getSlop(); + bool inorder = false; - SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); - sp->setBoost(query->getBoost()); - getPayloads(payloads, sp); - } - else if (MiscUtils::typeOf(query)) - { - TermQueryPtr termQuery(boost::dynamic_pointer_cast(query)); - SpanTermQueryPtr stq(newLucene(termQuery->getTerm())); - stq->setBoost(query->getBoost()); - getPayloads(payloads, stq); - } - else if (MiscUtils::typeOf(query)) - { - SpanQueryPtr spanQuery(boost::dynamic_pointer_cast(query)); - getPayloads(payloads, spanQuery); - } - else if (MiscUtils::typeOf(query)) - { - FilteredQueryPtr filteredQuery(boost::dynamic_pointer_cast(query)); - queryToSpanQuery(filteredQuery->getQuery(), payloads); + if (slop == 0) { + inorder = true; } - else if (MiscUtils::typeOf(query)) - { - DisjunctionMaxQueryPtr maxQuery(boost::dynamic_pointer_cast(query)); - for (Collection::iterator disjunct = maxQuery->begin(); disjunct != maxQuery->end(); ++disjunct) - queryToSpanQuery(*disjunct, payloads); + + SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); + sp->setBoost(query->getBoost()); + getPayloads(payloads, sp); + } else if (MiscUtils::typeOf(query)) { + TermQueryPtr termQuery(boost::dynamic_pointer_cast(query)); + SpanTermQueryPtr stq(newLucene(termQuery->getTerm())); + stq->setBoost(query->getBoost()); + getPayloads(payloads, stq); + } else if (MiscUtils::typeOf(query)) { + SpanQueryPtr spanQuery(boost::dynamic_pointer_cast(query)); + getPayloads(payloads, spanQuery); + } else if (MiscUtils::typeOf(query)) { + FilteredQueryPtr filteredQuery(boost::dynamic_pointer_cast(query)); + queryToSpanQuery(filteredQuery->getQuery(), payloads); + } else if (MiscUtils::typeOf(query)) { + DisjunctionMaxQueryPtr maxQuery(boost::dynamic_pointer_cast(query)); + for (Collection::iterator disjunct = maxQuery->begin(); disjunct != maxQuery->end(); ++disjunct) { + queryToSpanQuery(*disjunct, payloads); } - else if (MiscUtils::typeOf(query)) - { - MultiPhraseQueryPtr multiphraseQuery(boost::dynamic_pointer_cast(query)); - Collection< Collection > termArrays(multiphraseQuery->getTermArrays()); - Collection positions(multiphraseQuery->getPositions()); - if (!positions.empty()) - { - int32_t maxPosition = positions[positions.size() - 1]; - for (int32_t i = 0; i < positions.size() - 1; ++i) - { - if (positions[i] > maxPosition) - maxPosition = positions[i]; + } else if (MiscUtils::typeOf(query)) { + MultiPhraseQueryPtr multiphraseQuery(boost::dynamic_pointer_cast(query)); + Collection< Collection > termArrays(multiphraseQuery->getTermArrays()); + Collection positions(multiphraseQuery->getPositions()); + if (!positions.empty()) { + int32_t maxPosition = positions[positions.size() - 1]; + for (int32_t i = 0; i < positions.size() - 1; ++i) { + if (positions[i] > maxPosition) { + maxPosition = positions[i]; } + } - Collection< Collection > disjunctLists(Collection< Collection >::newInstance(maxPosition + 1)); - int32_t distinctPositions = 0; - - for (int32_t i = 0; i < termArrays.size(); ++i) - { - Collection termArray(termArrays[i]); - Collection disjuncts(disjunctLists[positions[i]]); - if (!disjuncts) - { - disjuncts = Collection::newInstance(); - disjunctLists[positions[i]] = disjuncts; - ++distinctPositions; - } - for (Collection::iterator term = termArray.begin(); term != termArray.end(); ++term) - disjuncts.add(newLucene(*term)); + Collection< Collection > disjunctLists(Collection< Collection >::newInstance(maxPosition + 1)); + int32_t distinctPositions = 0; + + for (int32_t i = 0; i < termArrays.size(); ++i) { + Collection termArray(termArrays[i]); + Collection disjuncts(disjunctLists[positions[i]]); + if (!disjuncts) { + disjuncts = Collection::newInstance(); + disjunctLists[positions[i]] = disjuncts; + ++distinctPositions; } + for (Collection::iterator term = termArray.begin(); term != termArray.end(); ++term) { + disjuncts.add(newLucene(*term)); + } + } - int32_t positionGaps = 0; - int32_t position = 0; - Collection clauses(Collection::newInstance(distinctPositions)); - for (int32_t i = 0; i < disjunctLists.size(); ++i) - { - Collection disjuncts(disjunctLists[i]); - if (disjuncts) - { - Collection spanDisjuncts(Collection::newInstance(disjuncts.size())); - for (int32_t j = 0; j < disjuncts.size(); ++j) - spanDisjuncts[j] = boost::dynamic_pointer_cast(disjuncts[j]); - clauses[position++] = newLucene(spanDisjuncts); + int32_t positionGaps = 0; + int32_t position = 0; + Collection clauses(Collection::newInstance(distinctPositions)); + for (int32_t i = 0; i < disjunctLists.size(); ++i) { + Collection disjuncts(disjunctLists[i]); + if (disjuncts) { + Collection spanDisjuncts(Collection::newInstance(disjuncts.size())); + for (int32_t j = 0; j < disjuncts.size(); ++j) { + spanDisjuncts[j] = boost::dynamic_pointer_cast(disjuncts[j]); } - else - ++positionGaps; + clauses[position++] = newLucene(spanDisjuncts); + } else { + ++positionGaps; } + } - int32_t slop = multiphraseQuery->getSlop(); - bool inorder = (slop == 0); + int32_t slop = multiphraseQuery->getSlop(); + bool inorder = (slop == 0); - SpanNearQueryPtr sp(newLucene(clauses, slop + positionGaps, inorder)); - sp->setBoost(query->getBoost()); - getPayloads(payloads, sp); - } + SpanNearQueryPtr sp(newLucene(clauses, slop + positionGaps, inorder)); + sp->setBoost(query->getBoost()); + getPayloads(payloads, sp); } } +} - void PayloadSpanUtil::getPayloads(Collection payloads, const SpanQueryPtr& query) - { - SpansPtr spans(query->getSpans(reader)); - - while (spans->next()) - { - if (spans->isPayloadAvailable()) - { - Collection payload(spans->getPayload()); - for (Collection::iterator bytes = payload.begin(); bytes != payload.end(); ++bytes) - payloads.add(*bytes); +void PayloadSpanUtil::getPayloads(Collection payloads, const SpanQueryPtr& query) { + SpansPtr spans(query->getSpans(reader)); + + while (spans->next()) { + if (spans->isPayloadAvailable()) { + Collection payload(spans->getPayload()); + for (Collection::iterator bytes = payload.begin(); bytes != payload.end(); ++bytes) { + payloads.add(*bytes); } } } } + +} diff --git a/src/core/search/payloads/PayloadTermQuery.cpp b/src/core/search/payloads/PayloadTermQuery.cpp index 7638dc76..9d8e4af5 100644 --- a/src/core/search/payloads/PayloadTermQuery.cpp +++ b/src/core/search/payloads/PayloadTermQuery.cpp @@ -16,166 +16,152 @@ #include "PayloadFunction.h" #include "MiscUtils.h" -namespace Lucene -{ - PayloadTermQuery::PayloadTermQuery(const TermPtr& term, const PayloadFunctionPtr& function, bool includeSpanScore) : SpanTermQuery(term) - { - this->function = function; - this->includeSpanScore = includeSpanScore; - } +namespace Lucene { - PayloadTermQuery::~PayloadTermQuery() - { - } +PayloadTermQuery::PayloadTermQuery(const TermPtr& term, const PayloadFunctionPtr& function, bool includeSpanScore) : SpanTermQuery(term) { + this->function = function; + this->includeSpanScore = includeSpanScore; +} - WeightPtr PayloadTermQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } +PayloadTermQuery::~PayloadTermQuery() { +} - LuceneObjectPtr PayloadTermQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term, function, includeSpanScore)); - PayloadTermQueryPtr termQuery(boost::dynamic_pointer_cast(clone)); - termQuery->function = function; - termQuery->includeSpanScore = includeSpanScore; - return termQuery; - } +WeightPtr PayloadTermQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - bool PayloadTermQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!SpanTermQuery::equals(other)) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - PayloadTermQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) +LuceneObjectPtr PayloadTermQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term, function, includeSpanScore)); + PayloadTermQueryPtr termQuery(boost::dynamic_pointer_cast(clone)); + termQuery->function = function; + termQuery->includeSpanScore = includeSpanScore; + return termQuery; +} + +bool PayloadTermQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!SpanTermQuery::equals(other)) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + PayloadTermQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; + } + if (!function) { + if (otherQuery->function) { return false; - if (!function) - { - if (otherQuery->function) - return false; } - else if (!function->equals(otherQuery->function)) - return false; - if (includeSpanScore != otherQuery->includeSpanScore) - return false; - return true; + } else if (!function->equals(otherQuery->function)) { + return false; } - - int32_t PayloadTermQuery::hashCode() - { - int32_t prime = 31; - int32_t result = SpanTermQuery::hashCode(); - result = prime * result + (function ? function->hashCode() : 0); - result = prime * result + (includeSpanScore ? 1231 : 1237); - return result; + if (includeSpanScore != otherQuery->includeSpanScore) { + return false; } + return true; +} - PayloadTermWeight::PayloadTermWeight(const PayloadTermQueryPtr& query, const SearcherPtr& searcher) : SpanWeight(query, searcher) - { - } +int32_t PayloadTermQuery::hashCode() { + int32_t prime = 31; + int32_t result = SpanTermQuery::hashCode(); + result = prime * result + (function ? function->hashCode() : 0); + result = prime * result + (includeSpanScore ? 1231 : 1237); + return result; +} - PayloadTermWeight::~PayloadTermWeight() - { - } +PayloadTermWeight::PayloadTermWeight(const PayloadTermQueryPtr& query, const SearcherPtr& searcher) : SpanWeight(query, searcher) { +} - ScorerPtr PayloadTermWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - return newLucene(boost::dynamic_pointer_cast(query->getSpans(reader)), shared_from_this(), similarity, reader->norms(query->getField())); - } +PayloadTermWeight::~PayloadTermWeight() { +} - PayloadTermSpanScorer::PayloadTermSpanScorer(const TermSpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) - { - positions = spans->getPositions(); - payload = ByteArray::newInstance(256); - payloadScore = 0.0; - payloadsSeen = 0; - } +ScorerPtr PayloadTermWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + return newLucene(boost::dynamic_pointer_cast(query->getSpans(reader)), shared_from_this(), similarity, reader->norms(query->getField())); +} - PayloadTermSpanScorer::~PayloadTermSpanScorer() - { - } +PayloadTermSpanScorer::PayloadTermSpanScorer(const TermSpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : SpanScorer(spans, weight, similarity, norms) { + positions = spans->getPositions(); + payload = ByteArray::newInstance(256); + payloadScore = 0.0; + payloadsSeen = 0; +} - bool PayloadTermSpanScorer::setFreqCurrentDoc() - { - if (!more) - return false; - doc = spans->doc(); - freq = 0.0; - payloadScore = 0.0; - payloadsSeen = 0; - SimilarityPtr similarity1(getSimilarity()); - while (more && doc == spans->doc()) - { - int32_t matchLength = spans->end() - spans->start(); - - freq += similarity1->sloppyFreq(matchLength); - processPayload(similarity1); - - more = spans->next(); // this moves positions to the next match in this document - } - return more || (freq != 0); - } +PayloadTermSpanScorer::~PayloadTermSpanScorer() { +} - void PayloadTermSpanScorer::processPayload(const SimilarityPtr& similarity) - { - if (positions->isPayloadAvailable()) - { - PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); - PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); - - payload = positions->getPayload(payload, 0); - payloadScore = payloadQuery->function->currentScore(doc, payloadQuery->term->field(), spans->start(), spans->end(), - payloadsSeen, payloadScore, similarity->scorePayload(doc, - payloadQuery->term->field(), spans->start(), spans->end(), - payload, 0, positions->getPayloadLength())); - ++payloadsSeen; - } - else - { - // zero out the payload? - } +bool PayloadTermSpanScorer::setFreqCurrentDoc() { + if (!more) { + return false; } + doc = spans->doc(); + freq = 0.0; + payloadScore = 0.0; + payloadsSeen = 0; + SimilarityPtr similarity1(getSimilarity()); + while (more && doc == spans->doc()) { + int32_t matchLength = spans->end() - spans->start(); - double PayloadTermSpanScorer::score() - { - PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); - PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); - return payloadQuery->includeSpanScore ? getSpanScore() * getPayloadScore() : getPayloadScore(); - } + freq += similarity1->sloppyFreq(matchLength); + processPayload(similarity1); - double PayloadTermSpanScorer::getSpanScore() - { - return SpanScorer::score(); + more = spans->next(); // this moves positions to the next match in this document } + return more || (freq != 0); +} - double PayloadTermSpanScorer::getPayloadScore() - { +void PayloadTermSpanScorer::processPayload(const SimilarityPtr& similarity) { + if (positions->isPayloadAvailable()) { PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); - return payloadQuery->function->docScore(doc, payloadQuery->term->field(), payloadsSeen, payloadScore); + + payload = positions->getPayload(payload, 0); + payloadScore = payloadQuery->function->currentScore(doc, payloadQuery->term->field(), spans->start(), spans->end(), + payloadsSeen, payloadScore, similarity->scorePayload(doc, + payloadQuery->term->field(), spans->start(), spans->end(), + payload, 0, positions->getPayloadLength())); + ++payloadsSeen; + } else { + // zero out the payload? } +} - ExplanationPtr PayloadTermSpanScorer::explain(int32_t doc) - { - ComplexExplanationPtr result(newLucene()); - ExplanationPtr nonPayloadExpl(SpanScorer::explain(doc)); - result->addDetail(nonPayloadExpl); +double PayloadTermSpanScorer::score() { + PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); + PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); + return payloadQuery->includeSpanScore ? getSpanScore() * getPayloadScore() : getPayloadScore(); +} - ExplanationPtr payloadBoost(newLucene()); - result->addDetail(payloadBoost); +double PayloadTermSpanScorer::getSpanScore() { + return SpanScorer::score(); +} - double payloadScore = getPayloadScore(); - payloadBoost->setValue(payloadScore); - payloadBoost->setDescription(L"scorePayload(...)"); +double PayloadTermSpanScorer::getPayloadScore() { + PayloadTermWeightPtr payloadWeight(boost::static_pointer_cast(weight)); + PayloadTermQueryPtr payloadQuery(boost::static_pointer_cast(payloadWeight->query)); + return payloadQuery->function->docScore(doc, payloadQuery->term->field(), payloadsSeen, payloadScore); +} - result->setValue(nonPayloadExpl->getValue() * payloadScore); - result->setDescription(L"btq, product of:"); - result->setMatch(nonPayloadExpl->getValue() != 0.0); +ExplanationPtr PayloadTermSpanScorer::explain(int32_t doc) { + ComplexExplanationPtr result(newLucene()); + ExplanationPtr nonPayloadExpl(SpanScorer::explain(doc)); + result->addDetail(nonPayloadExpl); + + ExplanationPtr payloadBoost(newLucene()); + result->addDetail(payloadBoost); + + double payloadScore = getPayloadScore(); + payloadBoost->setValue(payloadScore); + payloadBoost->setDescription(L"scorePayload(...)"); + + result->setValue(nonPayloadExpl->getValue() * payloadScore); + result->setDescription(L"btq, product of:"); + result->setMatch(nonPayloadExpl->getValue() != 0.0); + + return result; +} - return result; - } } diff --git a/src/core/search/spans/FieldMaskingSpanQuery.cpp b/src/core/search/spans/FieldMaskingSpanQuery.cpp index 42a5b6b9..920dcccf 100644 --- a/src/core/search/spans/FieldMaskingSpanQuery.cpp +++ b/src/core/search/spans/FieldMaskingSpanQuery.cpp @@ -9,100 +9,90 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - FieldMaskingSpanQuery::FieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField) - { - this->maskedQuery = maskedQuery; - this->field = maskedField; - } +namespace Lucene { - FieldMaskingSpanQuery::~FieldMaskingSpanQuery() - { - } +FieldMaskingSpanQuery::FieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField) { + this->maskedQuery = maskedQuery; + this->field = maskedField; +} - String FieldMaskingSpanQuery::getField() - { - return field; - } +FieldMaskingSpanQuery::~FieldMaskingSpanQuery() { +} - SpanQueryPtr FieldMaskingSpanQuery::getMaskedQuery() - { - return maskedQuery; - } +String FieldMaskingSpanQuery::getField() { + return field; +} - // :NOTE: getBoost and setBoost are not proxied to the maskedQuery - // ...this is done to be more consistent with things like SpanFirstQuery +SpanQueryPtr FieldMaskingSpanQuery::getMaskedQuery() { + return maskedQuery; +} - SpansPtr FieldMaskingSpanQuery::getSpans(const IndexReaderPtr& reader) - { - return maskedQuery->getSpans(reader); - } +// :NOTE: getBoost and setBoost are not proxied to the maskedQuery +// ...this is done to be more consistent with things like SpanFirstQuery - void FieldMaskingSpanQuery::extractTerms(SetTerm terms) - { - maskedQuery->extractTerms(terms); - } +SpansPtr FieldMaskingSpanQuery::getSpans(const IndexReaderPtr& reader) { + return maskedQuery->getSpans(reader); +} - WeightPtr FieldMaskingSpanQuery::createWeight(const SearcherPtr& searcher) - { - return maskedQuery->createWeight(searcher); - } +void FieldMaskingSpanQuery::extractTerms(SetTerm terms) { + maskedQuery->extractTerms(terms); +} - SimilarityPtr FieldMaskingSpanQuery::getSimilarity(const SearcherPtr& searcher) - { - return maskedQuery->getSimilarity(searcher); - } +WeightPtr FieldMaskingSpanQuery::createWeight(const SearcherPtr& searcher) { + return maskedQuery->createWeight(searcher); +} - QueryPtr FieldMaskingSpanQuery::rewrite(const IndexReaderPtr& reader) - { - FieldMaskingSpanQueryPtr clone; - - SpanQueryPtr rewritten(boost::dynamic_pointer_cast(maskedQuery->rewrite(reader))); - if (rewritten != maskedQuery) - { - clone = boost::dynamic_pointer_cast(this->clone()); - clone->maskedQuery = rewritten; - } - - if (clone) - return clone; - else - return shared_from_this(); - } +SimilarityPtr FieldMaskingSpanQuery::getSimilarity(const SearcherPtr& searcher) { + return maskedQuery->getSimilarity(searcher); +} + +QueryPtr FieldMaskingSpanQuery::rewrite(const IndexReaderPtr& reader) { + FieldMaskingSpanQueryPtr clone; - String FieldMaskingSpanQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"mask(" << maskedQuery->toString(field) << L")"; - buffer << boostString() << L" as " << this->field; - return buffer.str(); + SpanQueryPtr rewritten(boost::dynamic_pointer_cast(maskedQuery->rewrite(reader))); + if (rewritten != maskedQuery) { + clone = boost::dynamic_pointer_cast(this->clone()); + clone->maskedQuery = rewritten; } - bool FieldMaskingSpanQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; + if (clone) { + return clone; + } else { + return shared_from_this(); + } +} - FieldMaskingSpanQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; +String FieldMaskingSpanQuery::toString(const String& field) { + StringStream buffer; + buffer << L"mask(" << maskedQuery->toString(field) << L")"; + buffer << boostString() << L" as " << this->field; + return buffer.str(); +} - return (getField() == otherQuery->getField() && getBoost() == otherQuery->getBoost() && - getMaskedQuery()->equals(otherQuery->getMaskedQuery())); +bool FieldMaskingSpanQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - int32_t FieldMaskingSpanQuery::hashCode() - { - return getMaskedQuery()->hashCode() ^ StringUtils::hashCode(getField()) ^ MiscUtils::doubleToRawIntBits(getBoost()); + FieldMaskingSpanQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } - LuceneObjectPtr FieldMaskingSpanQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(maskedQuery, field)); - FieldMaskingSpanQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); - cloneQuery->maskedQuery = maskedQuery; - cloneQuery->field = field; - return cloneQuery; - } + return (getField() == otherQuery->getField() && getBoost() == otherQuery->getBoost() && + getMaskedQuery()->equals(otherQuery->getMaskedQuery())); +} + +int32_t FieldMaskingSpanQuery::hashCode() { + return getMaskedQuery()->hashCode() ^ StringUtils::hashCode(getField()) ^ MiscUtils::doubleToRawIntBits(getBoost()); +} + +LuceneObjectPtr FieldMaskingSpanQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(maskedQuery, field)); + FieldMaskingSpanQueryPtr cloneQuery(boost::dynamic_pointer_cast(clone)); + cloneQuery->maskedQuery = maskedQuery; + cloneQuery->field = field; + return cloneQuery; +} + } diff --git a/src/core/search/spans/NearSpansOrdered.cpp b/src/core/search/spans/NearSpansOrdered.cpp index 945ccfd1..2e86e540 100644 --- a/src/core/search/spans/NearSpansOrdered.cpp +++ b/src/core/search/spans/NearSpansOrdered.cpp @@ -8,291 +8,251 @@ #include "NearSpansOrdered.h" #include "SpanNearQuery.h" -namespace Lucene -{ - NearSpansOrdered::NearSpansOrdered(const SpanNearQueryPtr& spanNearQuery, const IndexReaderPtr& reader, bool collectPayloads) - { - if (spanNearQuery->getClauses().size() < 2) - boost::throw_exception(IllegalArgumentException(L"Less than 2 clauses: " + spanNearQuery->toString())); - this->firstTime = true; - this->more = false; - this->inSameDoc = false; - this->matchDoc = -1; - this->matchStart = -1; - this->matchEnd = -1; - this->collectPayloads = collectPayloads; - this->allowedSlop = spanNearQuery->getSlop(); - Collection clauses(spanNearQuery->getClauses()); - this->subSpans = Collection::newInstance(clauses.size()); - this->matchPayload = Collection::newInstance(); - this->subSpansByDoc = Collection::newInstance(clauses.size()); - for (int32_t i = 0; i < clauses.size(); ++i) - { - subSpans[i] = clauses[i]->getSpans(reader); - subSpansByDoc[i] = subSpans[i]; // used in toSameDoc() - } - this->query = spanNearQuery; // kept for toString() only. - } +namespace Lucene { - NearSpansOrdered::~NearSpansOrdered() - { +NearSpansOrdered::NearSpansOrdered(const SpanNearQueryPtr& spanNearQuery, const IndexReaderPtr& reader, bool collectPayloads) { + if (spanNearQuery->getClauses().size() < 2) { + boost::throw_exception(IllegalArgumentException(L"Less than 2 clauses: " + spanNearQuery->toString())); } - - int32_t NearSpansOrdered::doc() - { - return matchDoc; + this->firstTime = true; + this->more = false; + this->inSameDoc = false; + this->matchDoc = -1; + this->matchStart = -1; + this->matchEnd = -1; + this->collectPayloads = collectPayloads; + this->allowedSlop = spanNearQuery->getSlop(); + Collection clauses(spanNearQuery->getClauses()); + this->subSpans = Collection::newInstance(clauses.size()); + this->matchPayload = Collection::newInstance(); + this->subSpansByDoc = Collection::newInstance(clauses.size()); + for (int32_t i = 0; i < clauses.size(); ++i) { + subSpans[i] = clauses[i]->getSpans(reader); + subSpansByDoc[i] = subSpans[i]; // used in toSameDoc() } + this->query = spanNearQuery; // kept for toString() only. +} - int32_t NearSpansOrdered::start() - { - return matchStart; - } +NearSpansOrdered::~NearSpansOrdered() { +} - int32_t NearSpansOrdered::end() - { - return matchEnd; - } +int32_t NearSpansOrdered::doc() { + return matchDoc; +} - Collection NearSpansOrdered::getSubSpans() - { - return subSpans; - } +int32_t NearSpansOrdered::start() { + return matchStart; +} - Collection NearSpansOrdered::getPayload() - { - return matchPayload; - } +int32_t NearSpansOrdered::end() { + return matchEnd; +} - bool NearSpansOrdered::isPayloadAvailable() - { - return !matchPayload.empty(); - } +Collection NearSpansOrdered::getSubSpans() { + return subSpans; +} - bool NearSpansOrdered::next() - { - if (firstTime) - { - firstTime = false; - for (int32_t i = 0; i < subSpans.size(); ++i) - { - if (!subSpans[i]->next()) - { - more = false; - return false; - } +Collection NearSpansOrdered::getPayload() { + return matchPayload; +} + +bool NearSpansOrdered::isPayloadAvailable() { + return !matchPayload.empty(); +} + +bool NearSpansOrdered::next() { + if (firstTime) { + firstTime = false; + for (int32_t i = 0; i < subSpans.size(); ++i) { + if (!subSpans[i]->next()) { + more = false; + return false; } - more = true; } - if (collectPayloads) - matchPayload.clear(); - return advanceAfterOrdered(); + more = true; } + if (collectPayloads) { + matchPayload.clear(); + } + return advanceAfterOrdered(); +} - bool NearSpansOrdered::skipTo(int32_t target) - { - if (firstTime) - { - firstTime = false; - for (int32_t i = 0; i < subSpans.size(); ++i) - { - if (!subSpans[i]->skipTo(target)) - { - more = false; - return false; - } - } - more = true; - } - else if (more && (subSpans[0]->doc() < target)) - { - if (subSpans[0]->skipTo(target)) - inSameDoc = false; - else - { +bool NearSpansOrdered::skipTo(int32_t target) { + if (firstTime) { + firstTime = false; + for (int32_t i = 0; i < subSpans.size(); ++i) { + if (!subSpans[i]->skipTo(target)) { more = false; return false; } } - if (collectPayloads) - matchPayload.clear(); - return advanceAfterOrdered(); + more = true; + } else if (more && (subSpans[0]->doc() < target)) { + if (subSpans[0]->skipTo(target)) { + inSameDoc = false; + } else { + more = false; + return false; + } + } + if (collectPayloads) { + matchPayload.clear(); } + return advanceAfterOrdered(); +} - bool NearSpansOrdered::advanceAfterOrdered() - { - while (more && (inSameDoc || toSameDoc())) - { - if (stretchToOrder() && shrinkToAfterShortestMatch()) - return true; +bool NearSpansOrdered::advanceAfterOrdered() { + while (more && (inSameDoc || toSameDoc())) { + if (stretchToOrder() && shrinkToAfterShortestMatch()) { + return true; } - return false; // no more matches } + return false; // no more matches +} - struct lessSpanDoc - { - inline bool operator()(const SpansPtr& first, const SpansPtr& second) const - { - return ((first->doc() - second->doc()) < 0); - } - }; +struct lessSpanDoc { + inline bool operator()(const SpansPtr& first, const SpansPtr& second) const { + return ((first->doc() - second->doc()) < 0); + } +}; - bool NearSpansOrdered::toSameDoc() - { - std::sort(subSpansByDoc.begin(), subSpansByDoc.end(), lessSpanDoc()); - int32_t firstIndex = 0; - int32_t maxDoc = subSpansByDoc[subSpansByDoc.size() - 1]->doc(); - while (subSpansByDoc[firstIndex]->doc() != maxDoc) - { - if (!subSpansByDoc[firstIndex]->skipTo(maxDoc)) - { - more = false; - inSameDoc = false; - return false; - } - maxDoc = subSpansByDoc[firstIndex]->doc(); - if (++firstIndex == subSpansByDoc.size()) - firstIndex = 0; +bool NearSpansOrdered::toSameDoc() { + std::sort(subSpansByDoc.begin(), subSpansByDoc.end(), lessSpanDoc()); + int32_t firstIndex = 0; + int32_t maxDoc = subSpansByDoc[subSpansByDoc.size() - 1]->doc(); + while (subSpansByDoc[firstIndex]->doc() != maxDoc) { + if (!subSpansByDoc[firstIndex]->skipTo(maxDoc)) { + more = false; + inSameDoc = false; + return false; } - for (int32_t i = 0; i < subSpansByDoc.size(); ++i) - { - BOOST_ASSERT(subSpansByDoc[i]->doc() == maxDoc); + maxDoc = subSpansByDoc[firstIndex]->doc(); + if (++firstIndex == subSpansByDoc.size()) { + firstIndex = 0; } - inSameDoc = true; - return true; } - - bool NearSpansOrdered::docSpansOrdered(const SpansPtr& spans1, const SpansPtr& spans2) - { - BOOST_ASSERT(spans1->doc() == spans2->doc()); - int32_t start1 = spans1->start(); - int32_t start2 = spans2->start(); - // Do not call docSpansOrdered(int,int,int,int) to avoid invoking .end() - return start1 == start2 ? (spans1->end() < spans2->end()) : (start1 < start2); + for (int32_t i = 0; i < subSpansByDoc.size(); ++i) { + BOOST_ASSERT(subSpansByDoc[i]->doc() == maxDoc); } + inSameDoc = true; + return true; +} - bool NearSpansOrdered::docSpansOrdered(int32_t start1, int32_t end1, int32_t start2, int32_t end2) - { - return start1 == start2 ? (end1 < end2) : (start1 < start2); - } +bool NearSpansOrdered::docSpansOrdered(const SpansPtr& spans1, const SpansPtr& spans2) { + BOOST_ASSERT(spans1->doc() == spans2->doc()); + int32_t start1 = spans1->start(); + int32_t start2 = spans2->start(); + // Do not call docSpansOrdered(int,int,int,int) to avoid invoking .end() + return start1 == start2 ? (spans1->end() < spans2->end()) : (start1 < start2); +} - bool NearSpansOrdered::stretchToOrder() - { - matchDoc = subSpans[0]->doc(); - for (int32_t i = 1; inSameDoc && (i < subSpans.size()); ++i) - { - while (!docSpansOrdered(subSpans[i - 1], subSpans[i])) - { - if (!subSpans[i]->next()) - { - inSameDoc = false; - more = false; - break; - } - else if (matchDoc != subSpans[i]->doc()) - { - inSameDoc = false; - break; - } +bool NearSpansOrdered::docSpansOrdered(int32_t start1, int32_t end1, int32_t start2, int32_t end2) { + return start1 == start2 ? (end1 < end2) : (start1 < start2); +} + +bool NearSpansOrdered::stretchToOrder() { + matchDoc = subSpans[0]->doc(); + for (int32_t i = 1; inSameDoc && (i < subSpans.size()); ++i) { + while (!docSpansOrdered(subSpans[i - 1], subSpans[i])) { + if (!subSpans[i]->next()) { + inSameDoc = false; + more = false; + break; + } else if (matchDoc != subSpans[i]->doc()) { + inSameDoc = false; + break; } } - return inSameDoc; } + return inSameDoc; +} - bool NearSpansOrdered::shrinkToAfterShortestMatch() - { - SpansPtr subSpan(subSpans[subSpans.size() - 1]); - matchStart = subSpan->start(); - matchEnd = subSpan->end(); - SetByteArray possibleMatchPayloads(SetByteArray::newInstance()); - if (subSpan->isPayloadAvailable()) - { - Collection payload(subSpan->getPayload()); - possibleMatchPayloads.addAll(payload.begin(), payload.end()); - } +bool NearSpansOrdered::shrinkToAfterShortestMatch() { + SpansPtr subSpan(subSpans[subSpans.size() - 1]); + matchStart = subSpan->start(); + matchEnd = subSpan->end(); + SetByteArray possibleMatchPayloads(SetByteArray::newInstance()); + if (subSpan->isPayloadAvailable()) { + Collection payload(subSpan->getPayload()); + possibleMatchPayloads.addAll(payload.begin(), payload.end()); + } - Collection possiblePayload; + Collection possiblePayload; - int32_t matchSlop = 0; - int32_t lastStart = matchStart; - int32_t lastEnd = matchEnd; - for (int32_t i = subSpans.size() - 2; i >= 0; --i) - { - SpansPtr prevSpans(subSpans[i]); - if (collectPayloads && prevSpans->isPayloadAvailable()) - { - Collection payload(prevSpans->getPayload()); - possiblePayload = Collection::newInstance(payload.begin(), payload.end()); - } + int32_t matchSlop = 0; + int32_t lastStart = matchStart; + int32_t lastEnd = matchEnd; + for (int32_t i = subSpans.size() - 2; i >= 0; --i) { + SpansPtr prevSpans(subSpans[i]); + if (collectPayloads && prevSpans->isPayloadAvailable()) { + Collection payload(prevSpans->getPayload()); + possiblePayload = Collection::newInstance(payload.begin(), payload.end()); + } - int32_t prevStart = prevSpans->start(); - int32_t prevEnd = prevSpans->end(); - while (true) // Advance prevSpans until after (lastStart, lastEnd) - { - if (!prevSpans->next()) - { - inSameDoc = false; - more = false; - break; // Check remaining subSpans for final match. - } - else if (matchDoc != prevSpans->doc()) - { - inSameDoc = false; // The last subSpans is not advanced here. - break; // Check remaining subSpans for last match in this document. - } - else - { - int32_t ppStart = prevSpans->start(); - int32_t ppEnd = prevSpans->end(); // Cannot avoid invoking .end() - if (!docSpansOrdered(ppStart, ppEnd, lastStart, lastEnd)) - break; // Check remaining subSpans. - else - { - prevStart = ppStart; - prevEnd = ppEnd; - if (collectPayloads && prevSpans->isPayloadAvailable()) - { - Collection payload(prevSpans->getPayload()); - possiblePayload = Collection::newInstance(payload.begin(), payload.end()); - } + int32_t prevStart = prevSpans->start(); + int32_t prevEnd = prevSpans->end(); + while (true) { // Advance prevSpans until after (lastStart, lastEnd) + if (!prevSpans->next()) { + inSameDoc = false; + more = false; + break; // Check remaining subSpans for final match. + } else if (matchDoc != prevSpans->doc()) { + inSameDoc = false; // The last subSpans is not advanced here. + break; // Check remaining subSpans for last match in this document. + } else { + int32_t ppStart = prevSpans->start(); + int32_t ppEnd = prevSpans->end(); // Cannot avoid invoking .end() + if (!docSpansOrdered(ppStart, ppEnd, lastStart, lastEnd)) { + break; // Check remaining subSpans. + } else { + prevStart = ppStart; + prevEnd = ppEnd; + if (collectPayloads && prevSpans->isPayloadAvailable()) { + Collection payload(prevSpans->getPayload()); + possiblePayload = Collection::newInstance(payload.begin(), payload.end()); } } } + } - if (collectPayloads && possiblePayload) - possibleMatchPayloads.addAll(possiblePayload.begin(), possiblePayload.end()); - - BOOST_ASSERT(prevStart <= matchStart); - if (matchStart > prevEnd) // Only non overlapping spans add to slop. - matchSlop += (matchStart - prevEnd); + if (collectPayloads && possiblePayload) { + possibleMatchPayloads.addAll(possiblePayload.begin(), possiblePayload.end()); + } - // Do not break on (matchSlop > allowedSlop) here to make sure that subSpans[0] is - // advanced after the match, if any. - matchStart = prevStart; - lastStart = prevStart; - lastEnd = prevEnd; + BOOST_ASSERT(prevStart <= matchStart); + if (matchStart > prevEnd) { // Only non overlapping spans add to slop. + matchSlop += (matchStart - prevEnd); } - bool match = (matchSlop <= allowedSlop); + // Do not break on (matchSlop > allowedSlop) here to make sure that subSpans[0] is + // advanced after the match, if any. + matchStart = prevStart; + lastStart = prevStart; + lastEnd = prevEnd; + } - if (collectPayloads && match && !possibleMatchPayloads.empty()) - matchPayload.addAll(possibleMatchPayloads.begin(), possibleMatchPayloads.end()); + bool match = (matchSlop <= allowedSlop); - return match; // ordered and allowed slop + if (collectPayloads && match && !possibleMatchPayloads.empty()) { + matchPayload.addAll(possibleMatchPayloads.begin(), possibleMatchPayloads.end()); } - String NearSpansOrdered::toString() - { - StringStream buffer; - buffer << getClassName() << L"(" << query->toString() << L")@"; - if (firstTime) - buffer << L"START"; - else - { - if (more) - buffer << doc() << L":" << start() << L"-" << end(); - else - buffer << L"END"; + return match; // ordered and allowed slop +} + +String NearSpansOrdered::toString() { + StringStream buffer; + buffer << getClassName() << L"(" << query->toString() << L")@"; + if (firstTime) { + buffer << L"START"; + } else { + if (more) { + buffer << doc() << L":" << start() << L"-" << end(); + } else { + buffer << L"END"; } - return buffer.str(); } + return buffer.str(); +} + } diff --git a/src/core/search/spans/NearSpansUnordered.cpp b/src/core/search/spans/NearSpansUnordered.cpp index 1aa5a506..0bb752ce 100644 --- a/src/core/search/spans/NearSpansUnordered.cpp +++ b/src/core/search/spans/NearSpansUnordered.cpp @@ -11,317 +11,284 @@ #include "SpanNearQuery.h" #include "StringUtils.h" -namespace Lucene -{ - NearSpansUnordered::NearSpansUnordered(const SpanNearQueryPtr& query, const IndexReaderPtr& reader) - { - this->query = query; - this->reader = reader; - } +namespace Lucene { - NearSpansUnordered::~NearSpansUnordered() - { - } +NearSpansUnordered::NearSpansUnordered(const SpanNearQueryPtr& query, const IndexReaderPtr& reader) { + this->query = query; + this->reader = reader; +} - void NearSpansUnordered::initialize() - { - this->slop = query->getSlop(); - this->totalLength = 0; - this->more = true; - this->firstTime = true; - - Collection clauses(query->getClauses()); - queue = newLucene(clauses.size()); - subSpans = Collection::newInstance(clauses.size()); - ordered = Collection::newInstance(); - - for (int32_t i = 0; i < clauses.size(); ++i) - { - SpansCellPtr cell(newLucene(shared_from_this(), clauses[i]->getSpans(reader), i)); - ordered.add(cell); - subSpans[i] = cell->spans; - } - } +NearSpansUnordered::~NearSpansUnordered() { +} + +void NearSpansUnordered::initialize() { + this->slop = query->getSlop(); + this->totalLength = 0; + this->more = true; + this->firstTime = true; + + Collection clauses(query->getClauses()); + queue = newLucene(clauses.size()); + subSpans = Collection::newInstance(clauses.size()); + ordered = Collection::newInstance(); - Collection NearSpansUnordered::getSubSpans() - { - return subSpans; + for (int32_t i = 0; i < clauses.size(); ++i) { + SpansCellPtr cell(newLucene(shared_from_this(), clauses[i]->getSpans(reader), i)); + ordered.add(cell); + subSpans[i] = cell->spans; } +} - bool NearSpansUnordered::next() - { - if (firstTime) - { - initList(true); - listToQueue(); // initialize queue - firstTime = false; - } - else if (more) - { - if (min()->next()) // trigger further scanning - queue->updateTop(); // maintain queue - else - more = false; +Collection NearSpansUnordered::getSubSpans() { + return subSpans; +} + +bool NearSpansUnordered::next() { + if (firstTime) { + initList(true); + listToQueue(); // initialize queue + firstTime = false; + } else if (more) { + if (min()->next()) { // trigger further scanning + queue->updateTop(); // maintain queue + } else { + more = false; } + } - while (more) - { - bool queueStale = false; + while (more) { + bool queueStale = false; - if (min()->doc() != max->doc()) // maintain list - { - queueToList(); - queueStale = true; - } + if (min()->doc() != max->doc()) { // maintain list + queueToList(); + queueStale = true; + } - // skip to doc with all clauses + // skip to doc with all clauses - while (more && first->doc() < last->doc()) - { - more = first->skipTo(last->doc()); // skip first upto last - firstToLast(); // and move it to the end - queueStale = true; - } + while (more && first->doc() < last->doc()) { + more = first->skipTo(last->doc()); // skip first upto last + firstToLast(); // and move it to the end + queueStale = true; + } - if (!more) - return false; + if (!more) { + return false; + } - // found doc with all clauses + // found doc with all clauses - if (queueStale) // maintain the queue - { - listToQueue(); - queueStale = false; - } + if (queueStale) { // maintain the queue + listToQueue(); + queueStale = false; + } - if (atMatch()) - return true; + if (atMatch()) { + return true; + } - more = min()->next(); - if (more) - queue->updateTop(); // maintain queue + more = min()->next(); + if (more) { + queue->updateTop(); // maintain queue } - return false; // no more matches } + return false; // no more matches +} - bool NearSpansUnordered::skipTo(int32_t target) - { - if (firstTime) // initialize - { - initList(false); - for (SpansCellPtr cell(first); more && cell; cell = cell->_next) - more = cell->skipTo(target); // skip all - if (more) - listToQueue(); - firstTime = false; +bool NearSpansUnordered::skipTo(int32_t target) { + if (firstTime) { // initialize + initList(false); + for (SpansCellPtr cell(first); more && cell; cell = cell->_next) { + more = cell->skipTo(target); // skip all + } + if (more) { + listToQueue(); } - else // normal case - { - while (more && min()->doc() < target) // skip as needed - { - if (min()->skipTo(target)) - queue->updateTop(); - else - more = false; + firstTime = false; + } else { // normal case + while (more && min()->doc() < target) { // skip as needed + if (min()->skipTo(target)) { + queue->updateTop(); + } else { + more = false; } } - return (more && (atMatch() || next())); } + return (more && (atMatch() || next())); +} - SpansCellPtr NearSpansUnordered::min() - { - return queue->top(); - } +SpansCellPtr NearSpansUnordered::min() { + return queue->top(); +} - int32_t NearSpansUnordered::doc() - { - return min()->doc(); - } +int32_t NearSpansUnordered::doc() { + return min()->doc(); +} - int32_t NearSpansUnordered::start() - { - return min()->start(); - } +int32_t NearSpansUnordered::start() { + return min()->start(); +} - int32_t NearSpansUnordered::end() - { - return max->end(); - } +int32_t NearSpansUnordered::end() { + return max->end(); +} - Collection NearSpansUnordered::getPayload() - { - SetByteArray matchPayload(SetByteArray::newInstance()); - for (SpansCellPtr cell(first); cell; cell = cell->_next) - { - if (cell->isPayloadAvailable()) - { - Collection payload(cell->getPayload()); - matchPayload.addAll(payload.begin(), payload.end()); - } +Collection NearSpansUnordered::getPayload() { + SetByteArray matchPayload(SetByteArray::newInstance()); + for (SpansCellPtr cell(first); cell; cell = cell->_next) { + if (cell->isPayloadAvailable()) { + Collection payload(cell->getPayload()); + matchPayload.addAll(payload.begin(), payload.end()); } - return Collection::newInstance(matchPayload.begin(), matchPayload.end()); } + return Collection::newInstance(matchPayload.begin(), matchPayload.end()); +} - bool NearSpansUnordered::isPayloadAvailable() - { - SpansCellPtr pointer(min()); - while (pointer) - { - if (pointer->isPayloadAvailable()) - return true; - pointer = pointer->_next; +bool NearSpansUnordered::isPayloadAvailable() { + SpansCellPtr pointer(min()); + while (pointer) { + if (pointer->isPayloadAvailable()) { + return true; } - return false; + pointer = pointer->_next; } + return false; +} - String NearSpansUnordered::toString() - { - StringStream buffer; - buffer << getClassName() << L"(" << query->toString() << L")@"; - if (firstTime) - buffer << L"START"; - else - { - if (more) - buffer << doc() << L":" << start() << L"-" << end(); - else - buffer << L"END"; +String NearSpansUnordered::toString() { + StringStream buffer; + buffer << getClassName() << L"(" << query->toString() << L")@"; + if (firstTime) { + buffer << L"START"; + } else { + if (more) { + buffer << doc() << L":" << start() << L"-" << end(); + } else { + buffer << L"END"; } - return buffer.str(); } + return buffer.str(); +} - void NearSpansUnordered::initList(bool next) - { - for (Collection::iterator cell = ordered.begin(); more && cell != ordered.end(); ++cell) - { - if (next) - more = (*cell)->next(); // move to first entry - if (more) - addToList(*cell); // add to list +void NearSpansUnordered::initList(bool next) { + for (Collection::iterator cell = ordered.begin(); more && cell != ordered.end(); ++cell) { + if (next) { + more = (*cell)->next(); // move to first entry + } + if (more) { + addToList(*cell); // add to list } } +} - void NearSpansUnordered::addToList(const SpansCellPtr& cell) - { - if (last) // add next to end of list - last->_next = cell; - else - first = cell; - last = cell; - cell->_next.reset(); +void NearSpansUnordered::addToList(const SpansCellPtr& cell) { + if (last) { // add next to end of list + last->_next = cell; + } else { + first = cell; } + last = cell; + cell->_next.reset(); +} - void NearSpansUnordered::firstToLast() - { - last->_next = first; // move first to end of list - last = first; - first = first->_next; - last->_next.reset(); - } +void NearSpansUnordered::firstToLast() { + last->_next = first; // move first to end of list + last = first; + first = first->_next; + last->_next.reset(); +} - void NearSpansUnordered::queueToList() - { - first.reset(); - last.reset(); - while (queue->top()) - addToList(queue->pop()); +void NearSpansUnordered::queueToList() { + first.reset(); + last.reset(); + while (queue->top()) { + addToList(queue->pop()); } +} - void NearSpansUnordered::listToQueue() - { - queue->clear(); // rebuild queue - for (SpansCellPtr cell(first); cell; cell = cell->_next) - queue->add(cell); // add to queue from list +void NearSpansUnordered::listToQueue() { + queue->clear(); // rebuild queue + for (SpansCellPtr cell(first); cell; cell = cell->_next) { + queue->add(cell); // add to queue from list } +} - bool NearSpansUnordered::atMatch() - { - return ((min()->doc() == max->doc()) && ((max->end() - min()->start() - totalLength) <= slop)); - } +bool NearSpansUnordered::atMatch() { + return ((min()->doc() == max->doc()) && ((max->end() - min()->start() - totalLength) <= slop)); +} - SpansCell::SpansCell(const NearSpansUnorderedPtr& unordered, const SpansPtr& spans, int32_t index) - { - this->_unordered = unordered; - this->spans = spans; - this->index = index; - this->length = -1; - } +SpansCell::SpansCell(const NearSpansUnorderedPtr& unordered, const SpansPtr& spans, int32_t index) { + this->_unordered = unordered; + this->spans = spans; + this->index = index; + this->length = -1; +} - SpansCell::~SpansCell() - { - } +SpansCell::~SpansCell() { +} - bool SpansCell::next() - { - return adjust(spans->next()); - } +bool SpansCell::next() { + return adjust(spans->next()); +} + +bool SpansCell::skipTo(int32_t target) { + return adjust(spans->skipTo(target)); +} - bool SpansCell::skipTo(int32_t target) - { - return adjust(spans->skipTo(target)); +bool SpansCell::adjust(bool condition) { + NearSpansUnorderedPtr unordered(_unordered); + if (length != -1) { + unordered->totalLength -= length; // subtract old length } + if (condition) { + length = end() - start(); + unordered->totalLength += length; // add new length - bool SpansCell::adjust(bool condition) - { - NearSpansUnorderedPtr unordered(_unordered); - if (length != -1) - unordered->totalLength -= length; // subtract old length - if (condition) - { - length = end() - start(); - unordered->totalLength += length; // add new length - - if (!unordered->max || doc() > unordered->max->doc() || ((doc() == unordered->max->doc()) && (end() > unordered->max->end()))) - unordered->max = shared_from_this(); + if (!unordered->max || doc() > unordered->max->doc() || ((doc() == unordered->max->doc()) && (end() > unordered->max->end()))) { + unordered->max = shared_from_this(); } - unordered->more = condition; - return condition; } + unordered->more = condition; + return condition; +} - int32_t SpansCell::doc() - { - return spans->doc(); - } +int32_t SpansCell::doc() { + return spans->doc(); +} - int32_t SpansCell::start() - { - return spans->start(); - } +int32_t SpansCell::start() { + return spans->start(); +} - int32_t SpansCell::end() - { - return spans->end(); - } +int32_t SpansCell::end() { + return spans->end(); +} - Collection SpansCell::getPayload() - { - Collection payload(spans->getPayload()); - return Collection::newInstance(payload.begin(), payload.end()); - } +Collection SpansCell::getPayload() { + Collection payload(spans->getPayload()); + return Collection::newInstance(payload.begin(), payload.end()); +} - bool SpansCell::isPayloadAvailable() - { - return spans->isPayloadAvailable(); - } +bool SpansCell::isPayloadAvailable() { + return spans->isPayloadAvailable(); +} - String SpansCell::toString() - { - return spans->toString() + L"#" + StringUtils::toString(index); - } +String SpansCell::toString() { + return spans->toString() + L"#" + StringUtils::toString(index); +} - CellQueue::CellQueue(int32_t size) : PriorityQueue(size) - { - } +CellQueue::CellQueue(int32_t size) : PriorityQueue(size) { +} - CellQueue::~CellQueue() - { - } +CellQueue::~CellQueue() { +} - bool CellQueue::lessThan(const SpansCellPtr& first, const SpansCellPtr& second) - { - if (first->doc() == second->doc()) - return NearSpansOrdered::docSpansOrdered(first, second); - else - return (first->doc() < second->doc()); +bool CellQueue::lessThan(const SpansCellPtr& first, const SpansCellPtr& second) { + if (first->doc() == second->doc()) { + return NearSpansOrdered::docSpansOrdered(first, second); + } else { + return (first->doc() < second->doc()); } } + +} diff --git a/src/core/search/spans/SpanFirstQuery.cpp b/src/core/search/spans/SpanFirstQuery.cpp index 0f84c35a..b195e634 100644 --- a/src/core/search/spans/SpanFirstQuery.cpp +++ b/src/core/search/spans/SpanFirstQuery.cpp @@ -10,151 +10,133 @@ #include "SpanQuery.h" #include "MiscUtils.h" -namespace Lucene -{ - SpanFirstQuery::SpanFirstQuery(const SpanQueryPtr& match, int32_t end) - { - this->match = match; - this->end = end; - } +namespace Lucene { - SpanFirstQuery::~SpanFirstQuery() - { - } +SpanFirstQuery::SpanFirstQuery(const SpanQueryPtr& match, int32_t end) { + this->match = match; + this->end = end; +} - SpanQueryPtr SpanFirstQuery::getMatch() - { - return match; - } +SpanFirstQuery::~SpanFirstQuery() { +} - int32_t SpanFirstQuery::getEnd() - { - return end; - } +SpanQueryPtr SpanFirstQuery::getMatch() { + return match; +} - String SpanFirstQuery::getField() - { - return match->getField(); - } +int32_t SpanFirstQuery::getEnd() { + return end; +} - String SpanFirstQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"spanFirst(" << match->toString(field) << L", " << end << L")" << boostString(); - return buffer.str(); - } +String SpanFirstQuery::getField() { + return match->getField(); +} - LuceneObjectPtr SpanFirstQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(boost::dynamic_pointer_cast(match->clone()), end)); - SpanFirstQueryPtr spanFirstQuery(boost::dynamic_pointer_cast(clone)); - spanFirstQuery->match = match; - spanFirstQuery->end = end; - spanFirstQuery->setBoost(getBoost()); - return spanFirstQuery; - } +String SpanFirstQuery::toString(const String& field) { + StringStream buffer; + buffer << L"spanFirst(" << match->toString(field) << L", " << end << L")" << boostString(); + return buffer.str(); +} - void SpanFirstQuery::extractTerms(SetTerm terms) - { - match->extractTerms(terms); - } +LuceneObjectPtr SpanFirstQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(boost::dynamic_pointer_cast(match->clone()), end)); + SpanFirstQueryPtr spanFirstQuery(boost::dynamic_pointer_cast(clone)); + spanFirstQuery->match = match; + spanFirstQuery->end = end; + spanFirstQuery->setBoost(getBoost()); + return spanFirstQuery; +} - SpansPtr SpanFirstQuery::getSpans(const IndexReaderPtr& reader) - { - return newLucene(shared_from_this(), match->getSpans(reader)); - } +void SpanFirstQuery::extractTerms(SetTerm terms) { + match->extractTerms(terms); +} - QueryPtr SpanFirstQuery::rewrite(const IndexReaderPtr& reader) - { - SpanFirstQueryPtr clone; - SpanQueryPtr rewritten(boost::dynamic_pointer_cast(match->rewrite(reader))); - if (rewritten != match) - { - clone = boost::dynamic_pointer_cast(this->clone()); - clone->match = rewritten; - } +SpansPtr SpanFirstQuery::getSpans(const IndexReaderPtr& reader) { + return newLucene(shared_from_this(), match->getSpans(reader)); +} - if (clone) - return clone; // some clauses rewrote - else - return shared_from_this(); // no clauses rewrote +QueryPtr SpanFirstQuery::rewrite(const IndexReaderPtr& reader) { + SpanFirstQueryPtr clone; + SpanQueryPtr rewritten(boost::dynamic_pointer_cast(match->rewrite(reader))); + if (rewritten != match) { + clone = boost::dynamic_pointer_cast(this->clone()); + clone->match = rewritten; } - bool SpanFirstQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - - SpanFirstQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - - return (end == otherQuery->end && match->equals(otherQuery->match) && getBoost() == otherQuery->getBoost()); + if (clone) { + return clone; // some clauses rewrote + } else { + return shared_from_this(); // no clauses rewrote } +} - int32_t SpanFirstQuery::hashCode() - { - int32_t result = match->hashCode(); - result ^= (result << 8) | MiscUtils::unsignedShift(result, 25); // reversible - result ^= MiscUtils::doubleToRawIntBits(getBoost()) ^ end; - return result; +bool SpanFirstQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - FirstSpans::FirstSpans(const SpanFirstQueryPtr& query, const SpansPtr& spans) - { - this->query = query; - this->spans = spans; + SpanFirstQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } - FirstSpans::~FirstSpans() - { - } + return (end == otherQuery->end && match->equals(otherQuery->match) && getBoost() == otherQuery->getBoost()); +} + +int32_t SpanFirstQuery::hashCode() { + int32_t result = match->hashCode(); + result ^= (result << 8) | MiscUtils::unsignedShift(result, 25); // reversible + result ^= MiscUtils::doubleToRawIntBits(getBoost()) ^ end; + return result; +} + +FirstSpans::FirstSpans(const SpanFirstQueryPtr& query, const SpansPtr& spans) { + this->query = query; + this->spans = spans; +} - bool FirstSpans::next() - { - while (spans->next()) // scan to next match - { - if (end() <= query->end) - return true; +FirstSpans::~FirstSpans() { +} + +bool FirstSpans::next() { + while (spans->next()) { // scan to next match + if (end() <= query->end) { + return true; } - return false; } + return false; +} - bool FirstSpans::skipTo(int32_t target) - { - if (!spans->skipTo(target)) - return false; - return (spans->end() <= query->end || next()); +bool FirstSpans::skipTo(int32_t target) { + if (!spans->skipTo(target)) { + return false; } + return (spans->end() <= query->end || next()); +} - int32_t FirstSpans::doc() - { - return spans->doc(); - } +int32_t FirstSpans::doc() { + return spans->doc(); +} - int32_t FirstSpans::start() - { - return spans->start(); - } +int32_t FirstSpans::start() { + return spans->start(); +} - int32_t FirstSpans::end() - { - return spans->end(); - } +int32_t FirstSpans::end() { + return spans->end(); +} - Collection FirstSpans::getPayload() - { - Collection result; - if (spans->isPayloadAvailable()) - { - Collection payload(spans->getPayload()); - result = Collection::newInstance(payload.begin(), payload.end()); - } - return result; +Collection FirstSpans::getPayload() { + Collection result; + if (spans->isPayloadAvailable()) { + Collection payload(spans->getPayload()); + result = Collection::newInstance(payload.begin(), payload.end()); } + return result; +} + +bool FirstSpans::isPayloadAvailable() { + return spans->isPayloadAvailable(); +} - bool FirstSpans::isPayloadAvailable() - { - return spans->isPayloadAvailable(); - } } diff --git a/src/core/search/spans/SpanNearQuery.cpp b/src/core/search/spans/SpanNearQuery.cpp index ccbe6662..0c95d8d1 100644 --- a/src/core/search/spans/SpanNearQuery.cpp +++ b/src/core/search/spans/SpanNearQuery.cpp @@ -12,143 +12,140 @@ #include "NearSpansUnordered.h" #include "MiscUtils.h" -namespace Lucene -{ - SpanNearQuery::SpanNearQuery(Collection clauses, int32_t slop, bool inOrder, bool collectPayloads) - { - this->clauses = Collection::newInstance(); - for (int32_t i = 0; i < clauses.size(); ++i) - { - SpanQueryPtr clause(clauses[i]); - if (i == 0) // check field - field = clause->getField(); - else if (clause->getField() != field) - boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); - this->clauses.add(clause); +namespace Lucene { + +SpanNearQuery::SpanNearQuery(Collection clauses, int32_t slop, bool inOrder, bool collectPayloads) { + this->clauses = Collection::newInstance(); + for (int32_t i = 0; i < clauses.size(); ++i) { + SpanQueryPtr clause(clauses[i]); + if (i == 0) { // check field + field = clause->getField(); + } else if (clause->getField() != field) { + boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); } - this->collectPayloads = collectPayloads; - this->slop = slop; - this->inOrder = inOrder; + this->clauses.add(clause); } + this->collectPayloads = collectPayloads; + this->slop = slop; + this->inOrder = inOrder; +} - SpanNearQuery::~SpanNearQuery() - { - } +SpanNearQuery::~SpanNearQuery() { +} - Collection SpanNearQuery::getClauses() - { - return clauses; - } +Collection SpanNearQuery::getClauses() { + return clauses; +} - int32_t SpanNearQuery::getSlop() - { - return slop; - } +int32_t SpanNearQuery::getSlop() { + return slop; +} - bool SpanNearQuery::isInOrder() - { - return inOrder; - } +bool SpanNearQuery::isInOrder() { + return inOrder; +} - String SpanNearQuery::getField() - { - return field; - } +String SpanNearQuery::getField() { + return field; +} - void SpanNearQuery::extractTerms(SetTerm terms) - { - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - (*clause)->extractTerms(terms); +void SpanNearQuery::extractTerms(SetTerm terms) { + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + (*clause)->extractTerms(terms); } +} - String SpanNearQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"spanNear(["; - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - { - if (clause != clauses.begin()) - buffer << L", "; - buffer << (*clause)->toString(field); +String SpanNearQuery::toString(const String& field) { + StringStream buffer; + buffer << L"spanNear(["; + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + if (clause != clauses.begin()) { + buffer << L", "; } - buffer << L"], " << slop << L", " << inOrder << L")" << boostString(); - return buffer.str(); + buffer << (*clause)->toString(field); } + buffer << L"], " << slop << L", " << inOrder << L")" << boostString(); + return buffer.str(); +} - SpansPtr SpanNearQuery::getSpans(const IndexReaderPtr& reader) - { - if (clauses.empty()) // optimize 0-clause case - return newLucene(getClauses())->getSpans(reader); - - if (clauses.size() == 1) // optimize 1-clause case - return clauses[0]->getSpans(reader); +SpansPtr SpanNearQuery::getSpans(const IndexReaderPtr& reader) { + if (clauses.empty()) { // optimize 0-clause case + return newLucene(getClauses())->getSpans(reader); + } - return inOrder - ? boost::static_pointer_cast(newLucene(shared_from_this(), reader, collectPayloads)) - : boost::static_pointer_cast(newLucene(shared_from_this(), reader)); + if (clauses.size() == 1) { // optimize 1-clause case + return clauses[0]->getSpans(reader); } - QueryPtr SpanNearQuery::rewrite(const IndexReaderPtr& reader) - { - SpanNearQueryPtr clone; - for (int32_t i = 0; i < clauses.size(); ++i) - { - SpanQueryPtr clause(clauses[i]); - SpanQueryPtr query(boost::dynamic_pointer_cast(clause->rewrite(reader))); - if (query != clause) // clause rewrote: must clone - { - if (!clone) - clone = boost::dynamic_pointer_cast(this->clone()); - clone->clauses[i] = query; + return inOrder + ? boost::static_pointer_cast(newLucene(shared_from_this(), reader, collectPayloads)) + : boost::static_pointer_cast(newLucene(shared_from_this(), reader)); +} + +QueryPtr SpanNearQuery::rewrite(const IndexReaderPtr& reader) { + SpanNearQueryPtr clone; + for (int32_t i = 0; i < clauses.size(); ++i) { + SpanQueryPtr clause(clauses[i]); + SpanQueryPtr query(boost::dynamic_pointer_cast(clause->rewrite(reader))); + if (query != clause) { // clause rewrote: must clone + if (!clone) { + clone = boost::dynamic_pointer_cast(this->clone()); } + clone->clauses[i] = query; } - if (clone) - return clone; // some clauses rewrote - else - return shared_from_this(); // no clauses rewrote } + if (clone) { + return clone; // some clauses rewrote + } else { + return shared_from_this(); // no clauses rewrote + } +} - LuceneObjectPtr SpanNearQuery::clone(const LuceneObjectPtr& other) - { - int32_t sz = clauses.size(); - Collection newClauses(Collection::newInstance(sz)); - - for (int32_t i = 0; i < sz; ++i) - newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); +LuceneObjectPtr SpanNearQuery::clone(const LuceneObjectPtr& other) { + int32_t sz = clauses.size(); + Collection newClauses(Collection::newInstance(sz)); - SpanNearQueryPtr spanNearQuery(newLucene(newClauses, slop, inOrder)); - spanNearQuery->setBoost(getBoost()); - return spanNearQuery; + for (int32_t i = 0; i < sz; ++i) { + newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); } - bool SpanNearQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - - SpanNearQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; + SpanNearQueryPtr spanNearQuery(newLucene(newClauses, slop, inOrder)); + spanNearQuery->setBoost(getBoost()); + return spanNearQuery; +} - if (inOrder != otherQuery->inOrder) - return false; - if (slop != otherQuery->slop) - return false; - if (!clauses.equals(otherQuery->clauses, luceneEquals())) - return false; +bool SpanNearQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } - return (getBoost() == otherQuery->getBoost()); + SpanNearQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } - int32_t SpanNearQuery::hashCode() - { - int32_t result = MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene); - // Mix bits before folding in things like boost, since it could cancel the last element of clauses. - // This particular mix also serves to differentiate SpanNearQuery hashcodes from others. - result ^= (result << 14) | MiscUtils::unsignedShift(result, 19); // reversible - result += MiscUtils::doubleToRawIntBits(getBoost()); - result += slop; - result ^= (inOrder ? 0x99afd3bd : 0); - return result; + if (inOrder != otherQuery->inOrder) { + return false; } + if (slop != otherQuery->slop) { + return false; + } + if (!clauses.equals(otherQuery->clauses, luceneEquals())) { + return false; + } + + return (getBoost() == otherQuery->getBoost()); +} + +int32_t SpanNearQuery::hashCode() { + int32_t result = MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene); + // Mix bits before folding in things like boost, since it could cancel the last element of clauses. + // This particular mix also serves to differentiate SpanNearQuery hashcodes from others. + result ^= (result << 14) | MiscUtils::unsignedShift(result, 19); // reversible + result += MiscUtils::doubleToRawIntBits(getBoost()); + result += slop; + result ^= (inOrder ? 0x99afd3bd : 0); + return result; +} + } diff --git a/src/core/search/spans/SpanNotQuery.cpp b/src/core/search/spans/SpanNotQuery.cpp index 81984ea1..064999f8 100644 --- a/src/core/search/spans/SpanNotQuery.cpp +++ b/src/core/search/spans/SpanNotQuery.cpp @@ -9,200 +9,189 @@ #include "_SpanNotQuery.h" #include "MiscUtils.h" -namespace Lucene -{ - SpanNotQuery::SpanNotQuery(const SpanQueryPtr& include, const SpanQueryPtr& exclude) - { - this->include = include; - this->exclude = exclude; - - if (include->getField() != exclude->getField()) - boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); - } +namespace Lucene { - SpanNotQuery::~SpanNotQuery() - { - } +SpanNotQuery::SpanNotQuery(const SpanQueryPtr& include, const SpanQueryPtr& exclude) { + this->include = include; + this->exclude = exclude; - SpanQueryPtr SpanNotQuery::getInclude() - { - return include; + if (include->getField() != exclude->getField()) { + boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); } +} - SpanQueryPtr SpanNotQuery::getExclude() - { - return exclude; - } +SpanNotQuery::~SpanNotQuery() { +} - String SpanNotQuery::getField() - { - return include->getField(); - } +SpanQueryPtr SpanNotQuery::getInclude() { + return include; +} - void SpanNotQuery::extractTerms(SetTerm terms) - { - include->extractTerms(terms); - } +SpanQueryPtr SpanNotQuery::getExclude() { + return exclude; +} - String SpanNotQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"spanNot(" << include->toString(field) << L", " << exclude->toString(field) << L")"; - buffer << boostString(); - return buffer.str(); - } +String SpanNotQuery::getField() { + return include->getField(); +} - LuceneObjectPtr SpanNotQuery::clone(const LuceneObjectPtr& other) - { - SpanNotQueryPtr spanNotQuery(newLucene(boost::dynamic_pointer_cast(include->clone()), - boost::dynamic_pointer_cast(exclude->clone()))); - spanNotQuery->setBoost(getBoost()); - return spanNotQuery; - } +void SpanNotQuery::extractTerms(SetTerm terms) { + include->extractTerms(terms); +} - SpansPtr SpanNotQuery::getSpans(const IndexReaderPtr& reader) - { - return newLucene(shared_from_this(), include->getSpans(reader), exclude->getSpans(reader)); - } +String SpanNotQuery::toString(const String& field) { + StringStream buffer; + buffer << L"spanNot(" << include->toString(field) << L", " << exclude->toString(field) << L")"; + buffer << boostString(); + return buffer.str(); +} - QueryPtr SpanNotQuery::rewrite(const IndexReaderPtr& reader) - { - SpanNotQueryPtr clone; - SpanQueryPtr rewrittenInclude(boost::dynamic_pointer_cast(include->rewrite(reader))); - if (rewrittenInclude != include) - { - clone = boost::dynamic_pointer_cast(this->clone()); - clone->include = rewrittenInclude; - } +LuceneObjectPtr SpanNotQuery::clone(const LuceneObjectPtr& other) { + SpanNotQueryPtr spanNotQuery(newLucene(boost::dynamic_pointer_cast(include->clone()), + boost::dynamic_pointer_cast(exclude->clone()))); + spanNotQuery->setBoost(getBoost()); + return spanNotQuery; +} - SpanQueryPtr rewrittenExclude(boost::dynamic_pointer_cast(exclude->rewrite(reader))); - if (rewrittenExclude != exclude) - { - if (!clone) - clone = boost::dynamic_pointer_cast(this->clone()); - clone->exclude = rewrittenExclude; - } +SpansPtr SpanNotQuery::getSpans(const IndexReaderPtr& reader) { + return newLucene(shared_from_this(), include->getSpans(reader), exclude->getSpans(reader)); +} - if (clone) - return clone; // some clauses rewrote - else - return shared_from_this(); // no clauses rewrote +QueryPtr SpanNotQuery::rewrite(const IndexReaderPtr& reader) { + SpanNotQueryPtr clone; + SpanQueryPtr rewrittenInclude(boost::dynamic_pointer_cast(include->rewrite(reader))); + if (rewrittenInclude != include) { + clone = boost::dynamic_pointer_cast(this->clone()); + clone->include = rewrittenInclude; } - bool SpanNotQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - - SpanNotQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - - return (include->equals(otherQuery->include) && exclude->equals(otherQuery->exclude) && getBoost() == otherQuery->getBoost()); + SpanQueryPtr rewrittenExclude(boost::dynamic_pointer_cast(exclude->rewrite(reader))); + if (rewrittenExclude != exclude) { + if (!clone) { + clone = boost::dynamic_pointer_cast(this->clone()); + } + clone->exclude = rewrittenExclude; } - int32_t SpanNotQuery::hashCode() - { - int32_t result = include->hashCode(); - result = (result << 1) | MiscUtils::unsignedShift(result, 31); // rotate left - result ^= exclude->hashCode(); - result = (result << 1) | MiscUtils::unsignedShift(result, 31); // rotate left - result ^= MiscUtils::doubleToRawIntBits(getBoost()); - return result; + if (clone) { + return clone; // some clauses rewrote + } else { + return shared_from_this(); // no clauses rewrote } +} - NotSpans::NotSpans(const SpanNotQueryPtr& query, const SpansPtr& includeSpans, const SpansPtr& excludeSpans) - { - this->query = query; - this->includeSpans = includeSpans; - this->moreInclude = true; - this->excludeSpans = excludeSpans; - this->moreExclude = excludeSpans->next(); +bool SpanNotQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - NotSpans::~NotSpans() - { + SpanNotQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } - bool NotSpans::next() - { - if (moreInclude) // move to next include - moreInclude = includeSpans->next(); + return (include->equals(otherQuery->include) && exclude->equals(otherQuery->exclude) && getBoost() == otherQuery->getBoost()); +} - while (moreInclude && moreExclude) - { - if (includeSpans->doc() > excludeSpans->doc()) // skip exclude - moreExclude = excludeSpans->skipTo(includeSpans->doc()); +int32_t SpanNotQuery::hashCode() { + int32_t result = include->hashCode(); + result = (result << 1) | MiscUtils::unsignedShift(result, 31); // rotate left + result ^= exclude->hashCode(); + result = (result << 1) | MiscUtils::unsignedShift(result, 31); // rotate left + result ^= MiscUtils::doubleToRawIntBits(getBoost()); + return result; +} - // while exclude is before - while (moreExclude && includeSpans->doc() == excludeSpans->doc() && excludeSpans->end() <= includeSpans->start()) - moreExclude = excludeSpans->next(); // increment exclude +NotSpans::NotSpans(const SpanNotQueryPtr& query, const SpansPtr& includeSpans, const SpansPtr& excludeSpans) { + this->query = query; + this->includeSpans = includeSpans; + this->moreInclude = true; + this->excludeSpans = excludeSpans; + this->moreExclude = excludeSpans->next(); +} - // if no intersection - if (!moreExclude || includeSpans->doc() != excludeSpans->doc() || includeSpans->end() <= excludeSpans->start()) - break; // we found a match +NotSpans::~NotSpans() { +} - moreInclude = includeSpans->next(); // intersected: keep scanning - } - return moreInclude; +bool NotSpans::next() { + if (moreInclude) { // move to next include + moreInclude = includeSpans->next(); } - bool NotSpans::skipTo(int32_t target) - { - if (moreInclude) // skip include - moreInclude = includeSpans->skipTo(target); - - if (!moreInclude) - return false; - - // skip exclude - if (moreExclude && includeSpans->doc() > excludeSpans->doc()) + while (moreInclude && moreExclude) { + if (includeSpans->doc() > excludeSpans->doc()) { // skip exclude moreExclude = excludeSpans->skipTo(includeSpans->doc()); + } // while exclude is before - while (moreExclude && includeSpans->doc() == excludeSpans->doc() && excludeSpans->end() <= includeSpans->start()) - moreExclude = excludeSpans->next(); // increment exclude + while (moreExclude && includeSpans->doc() == excludeSpans->doc() && excludeSpans->end() <= includeSpans->start()) { + moreExclude = excludeSpans->next(); // increment exclude + } // if no intersection - if (!moreExclude || includeSpans->doc() != excludeSpans->doc() || includeSpans->end() <= excludeSpans->start()) - return true; // we found a match + if (!moreExclude || includeSpans->doc() != excludeSpans->doc() || includeSpans->end() <= excludeSpans->start()) { + break; // we found a match + } - return next(); // scan to next match + moreInclude = includeSpans->next(); // intersected: keep scanning } + return moreInclude; +} - int32_t NotSpans::doc() - { - return includeSpans->doc(); +bool NotSpans::skipTo(int32_t target) { + if (moreInclude) { // skip include + moreInclude = includeSpans->skipTo(target); } - int32_t NotSpans::start() - { - return includeSpans->start(); + if (!moreInclude) { + return false; } - int32_t NotSpans::end() - { - return includeSpans->end(); + // skip exclude + if (moreExclude && includeSpans->doc() > excludeSpans->doc()) { + moreExclude = excludeSpans->skipTo(includeSpans->doc()); } - Collection NotSpans::getPayload() - { - Collection result; - if (includeSpans->isPayloadAvailable()) - { - Collection payload(includeSpans->getPayload()); - result = Collection::newInstance(payload.begin(), payload.end()); - } - return result; + // while exclude is before + while (moreExclude && includeSpans->doc() == excludeSpans->doc() && excludeSpans->end() <= includeSpans->start()) { + moreExclude = excludeSpans->next(); // increment exclude } - bool NotSpans::isPayloadAvailable() - { - return includeSpans->isPayloadAvailable(); + // if no intersection + if (!moreExclude || includeSpans->doc() != excludeSpans->doc() || includeSpans->end() <= excludeSpans->start()) { + return true; // we found a match } - String NotSpans::toString() - { - return L"spans(" + query->toString() + L")"; + return next(); // scan to next match +} + +int32_t NotSpans::doc() { + return includeSpans->doc(); +} + +int32_t NotSpans::start() { + return includeSpans->start(); +} + +int32_t NotSpans::end() { + return includeSpans->end(); +} + +Collection NotSpans::getPayload() { + Collection result; + if (includeSpans->isPayloadAvailable()) { + Collection payload(includeSpans->getPayload()); + result = Collection::newInstance(payload.begin(), payload.end()); } + return result; +} + +bool NotSpans::isPayloadAvailable() { + return includeSpans->isPayloadAvailable(); +} + +String NotSpans::toString() { + return L"spans(" + query->toString() + L")"; +} + } diff --git a/src/core/search/spans/SpanOrQuery.cpp b/src/core/search/spans/SpanOrQuery.cpp index 4e2c102c..26349b1b 100644 --- a/src/core/search/spans/SpanOrQuery.cpp +++ b/src/core/search/spans/SpanOrQuery.cpp @@ -9,254 +9,238 @@ #include "_SpanOrQuery.h" #include "MiscUtils.h" -namespace Lucene -{ - SpanOrQuery::SpanOrQuery(Collection clauses) - { - // copy clauses array into an ArrayList - this->clauses = Collection::newInstance(); - for (int32_t i = 0; i < clauses.size(); ++i) - { - SpanQueryPtr clause(clauses[i]); - if (i == 0) // check field - field = clause->getField(); - else if (clause->getField() != field) - boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); - this->clauses.add(clause); +namespace Lucene { + +SpanOrQuery::SpanOrQuery(Collection clauses) { + // copy clauses array into an ArrayList + this->clauses = Collection::newInstance(); + for (int32_t i = 0; i < clauses.size(); ++i) { + SpanQueryPtr clause(clauses[i]); + if (i == 0) { // check field + field = clause->getField(); + } else if (clause->getField() != field) { + boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); } + this->clauses.add(clause); } +} - SpanOrQuery::~SpanOrQuery() - { - } +SpanOrQuery::~SpanOrQuery() { +} - Collection SpanOrQuery::getClauses() - { - return clauses; - } +Collection SpanOrQuery::getClauses() { + return clauses; +} - String SpanOrQuery::getField() - { - return field; - } +String SpanOrQuery::getField() { + return field; +} - void SpanOrQuery::extractTerms(SetTerm terms) - { - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - (*clause)->extractTerms(terms); +void SpanOrQuery::extractTerms(SetTerm terms) { + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + (*clause)->extractTerms(terms); } +} - LuceneObjectPtr SpanOrQuery::clone(const LuceneObjectPtr& other) - { - int32_t sz = clauses.size(); - Collection newClauses(Collection::newInstance(sz)); - - for (int32_t i = 0; i < sz; ++i) - newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); +LuceneObjectPtr SpanOrQuery::clone(const LuceneObjectPtr& other) { + int32_t sz = clauses.size(); + Collection newClauses(Collection::newInstance(sz)); - SpanOrQueryPtr spanOrQuery(newLucene(newClauses)); - spanOrQuery->setBoost(getBoost()); - return spanOrQuery; + for (int32_t i = 0; i < sz; ++i) { + newClauses[i] = boost::dynamic_pointer_cast(clauses[i]->clone()); } - QueryPtr SpanOrQuery::rewrite(const IndexReaderPtr& reader) - { - SpanOrQueryPtr clone; - for (int32_t i = 0; i < clauses.size(); ++i) - { - SpanQueryPtr clause(clauses[i]); - SpanQueryPtr query(boost::dynamic_pointer_cast(clause->rewrite(reader))); - if (query != clause) // clause rewrote: must clone - { - if (!clone) - clone = boost::dynamic_pointer_cast(this->clone()); - clone->clauses[i] = query; + SpanOrQueryPtr spanOrQuery(newLucene(newClauses)); + spanOrQuery->setBoost(getBoost()); + return spanOrQuery; +} + +QueryPtr SpanOrQuery::rewrite(const IndexReaderPtr& reader) { + SpanOrQueryPtr clone; + for (int32_t i = 0; i < clauses.size(); ++i) { + SpanQueryPtr clause(clauses[i]); + SpanQueryPtr query(boost::dynamic_pointer_cast(clause->rewrite(reader))); + if (query != clause) { // clause rewrote: must clone + if (!clone) { + clone = boost::dynamic_pointer_cast(this->clone()); } + clone->clauses[i] = query; } - if (clone) - return clone; // some clauses rewrote - else - return shared_from_this(); // no clauses rewrote } + if (clone) { + return clone; // some clauses rewrote + } else { + return shared_from_this(); // no clauses rewrote + } +} - String SpanOrQuery::toString(const String& field) - { - StringStream buffer; - buffer << L"SpanOr(["; - for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) - { - if (clause != clauses.begin()) - buffer << L", "; - buffer << (*clause)->toString(field); +String SpanOrQuery::toString(const String& field) { + StringStream buffer; + buffer << L"SpanOr(["; + for (Collection::iterator clause = clauses.begin(); clause != clauses.end(); ++clause) { + if (clause != clauses.begin()) { + buffer << L", "; } - buffer << L"])" << boostString(); - return buffer.str(); + buffer << (*clause)->toString(field); } + buffer << L"])" << boostString(); + return buffer.str(); +} - bool SpanOrQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - - SpanOrQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) - return false; - - if (!clauses.equals(otherQuery->clauses, luceneEquals())) - return false; - if (!clauses.empty() && field != otherQuery->field) - return false; - - return (getBoost() == otherQuery->getBoost()); +bool SpanOrQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - int32_t SpanOrQuery::hashCode() - { - int32_t result = MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene); - result ^= (result << 10) | MiscUtils::unsignedShift(result, 23); - result ^= MiscUtils::doubleToRawIntBits(getBoost()); - return result; + SpanOrQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; } - SpansPtr SpanOrQuery::getSpans(const IndexReaderPtr& reader) - { - if (clauses.size() == 1) // optimize 1-clause case - return clauses[0]->getSpans(reader); - return newLucene(shared_from_this(), reader); + if (!clauses.equals(otherQuery->clauses, luceneEquals())) { + return false; } - - SpanQueue::SpanQueue(int32_t size) : PriorityQueue(size) - { + if (!clauses.empty() && field != otherQuery->field) { + return false; } - SpanQueue::~SpanQueue() - { - } + return (getBoost() == otherQuery->getBoost()); +} - bool SpanQueue::lessThan(const SpansPtr& first, const SpansPtr& second) - { - if (first->doc() == second->doc()) - { - if (first->start() == second->start()) - return (first->end() < second->end()); - else - return (first->start() < second->start()); - } - else - return (first->doc() < second->doc()); - } +int32_t SpanOrQuery::hashCode() { + int32_t result = MiscUtils::hashCode(clauses.begin(), clauses.end(), MiscUtils::hashLucene); + result ^= (result << 10) | MiscUtils::unsignedShift(result, 23); + result ^= MiscUtils::doubleToRawIntBits(getBoost()); + return result; +} - OrSpans::OrSpans(const SpanOrQueryPtr& query, const IndexReaderPtr& reader) - { - this->query = query; - this->reader = reader; +SpansPtr SpanOrQuery::getSpans(const IndexReaderPtr& reader) { + if (clauses.size() == 1) { // optimize 1-clause case + return clauses[0]->getSpans(reader); } + return newLucene(shared_from_this(), reader); +} - OrSpans::~OrSpans() - { - } +SpanQueue::SpanQueue(int32_t size) : PriorityQueue(size) { +} - bool OrSpans::initSpanQueue(int32_t target) - { - queue = newLucene(query->clauses.size()); - for (Collection::iterator clause = query->clauses.begin(); clause != query->clauses.end(); ++clause) - { - SpansPtr spans((*clause)->getSpans(reader)); - if ((target == -1 && spans->next()) || (target != -1 && spans->skipTo(target))) - queue->add(spans); +SpanQueue::~SpanQueue() { +} + +bool SpanQueue::lessThan(const SpansPtr& first, const SpansPtr& second) { + if (first->doc() == second->doc()) { + if (first->start() == second->start()) { + return (first->end() < second->end()); + } else { + return (first->start() < second->start()); } - return !queue->empty(); + } else { + return (first->doc() < second->doc()); } +} - bool OrSpans::next() - { - if (!queue) - return initSpanQueue(-1); +OrSpans::OrSpans(const SpanOrQueryPtr& query, const IndexReaderPtr& reader) { + this->query = query; + this->reader = reader; +} - if (queue->empty()) // all done - return false; +OrSpans::~OrSpans() { +} - if (top()->next()) // move to next - { - queue->updateTop(); - return true; +bool OrSpans::initSpanQueue(int32_t target) { + queue = newLucene(query->clauses.size()); + for (Collection::iterator clause = query->clauses.begin(); clause != query->clauses.end(); ++clause) { + SpansPtr spans((*clause)->getSpans(reader)); + if ((target == -1 && spans->next()) || (target != -1 && spans->skipTo(target))) { + queue->add(spans); } - - queue->pop(); // exhausted a clause - return !queue->empty(); } + return !queue->empty(); +} - SpansPtr OrSpans::top() - { - return queue->top(); +bool OrSpans::next() { + if (!queue) { + return initSpanQueue(-1); } - bool OrSpans::skipTo(int32_t target) - { - if (!queue) - return initSpanQueue(target); - - bool skipCalled = false; - while (!queue->empty() && top()->doc() < target) - { - if (top()->skipTo(target)) - queue->updateTop(); - else - queue->pop(); - skipCalled = true; - } - - if (skipCalled) - return !queue->empty(); - return next(); + if (queue->empty()) { // all done + return false; } - int32_t OrSpans::doc() - { - return top()->doc(); + if (top()->next()) { // move to next + queue->updateTop(); + return true; } - int32_t OrSpans::start() - { - return top()->start(); - } + queue->pop(); // exhausted a clause + return !queue->empty(); +} - int32_t OrSpans::end() - { - return top()->end(); +SpansPtr OrSpans::top() { + return queue->top(); +} + +bool OrSpans::skipTo(int32_t target) { + if (!queue) { + return initSpanQueue(target); } - Collection OrSpans::getPayload() - { - Collection result; - SpansPtr theTop(top()); - if (theTop && theTop->isPayloadAvailable()) - { - Collection payload(theTop->getPayload()); - result = Collection::newInstance(payload.begin(), payload.end()); + bool skipCalled = false; + while (!queue->empty() && top()->doc() < target) { + if (top()->skipTo(target)) { + queue->updateTop(); + } else { + queue->pop(); } - return result; + skipCalled = true; } - bool OrSpans::isPayloadAvailable() - { - SpansPtr theTop(top()); - return (theTop && theTop->isPayloadAvailable()); + if (skipCalled) { + return !queue->empty(); } + return next(); +} + +int32_t OrSpans::doc() { + return top()->doc(); +} + +int32_t OrSpans::start() { + return top()->start(); +} + +int32_t OrSpans::end() { + return top()->end(); +} - String OrSpans::toString() - { - StringStream buffer; - buffer << L"spans(" << query->toString() << L")@"; - if (!queue) - buffer << L"START"; - else - { - if (!queue->empty()) - buffer << doc() << L":" << start() << L"-" << end(); - else - buffer << L"END"; +Collection OrSpans::getPayload() { + Collection result; + SpansPtr theTop(top()); + if (theTop && theTop->isPayloadAvailable()) { + Collection payload(theTop->getPayload()); + result = Collection::newInstance(payload.begin(), payload.end()); + } + return result; +} + +bool OrSpans::isPayloadAvailable() { + SpansPtr theTop(top()); + return (theTop && theTop->isPayloadAvailable()); +} + +String OrSpans::toString() { + StringStream buffer; + buffer << L"spans(" << query->toString() << L")@"; + if (!queue) { + buffer << L"START"; + } else { + if (!queue->empty()) { + buffer << doc() << L":" << start() << L"-" << end(); + } else { + buffer << L"END"; } - return buffer.str(); } + return buffer.str(); +} + } diff --git a/src/core/search/spans/SpanQuery.cpp b/src/core/search/spans/SpanQuery.cpp index eaa80cd3..bef1fb72 100644 --- a/src/core/search/spans/SpanQuery.cpp +++ b/src/core/search/spans/SpanQuery.cpp @@ -8,14 +8,13 @@ #include "SpanQuery.h" #include "SpanWeight.h" -namespace Lucene -{ - SpanQuery::~SpanQuery() - { - } +namespace Lucene { + +SpanQuery::~SpanQuery() { +} + +WeightPtr SpanQuery::createWeight(const SearcherPtr& searcher) { + return newLucene(shared_from_this(), searcher); +} - WeightPtr SpanQuery::createWeight(const SearcherPtr& searcher) - { - return newLucene(shared_from_this(), searcher); - } } diff --git a/src/core/search/spans/SpanScorer.cpp b/src/core/search/spans/SpanScorer.cpp index 42a27351..0e39b957 100644 --- a/src/core/search/spans/SpanScorer.cpp +++ b/src/core/search/spans/SpanScorer.cpp @@ -12,89 +12,80 @@ #include "Spans.h" #include "StringUtils.h" -namespace Lucene -{ - SpanScorer::SpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) - { - this->spans = spans; - this->norms = norms; - this->weight = weight; - this->value = weight->getValue(); - this->freq = 0.0; - if (this->spans->next()) - { - doc = -1; - more = true; - } - else - { - doc = NO_MORE_DOCS; - more = false; - } - } +namespace Lucene { - SpanScorer::~SpanScorer() - { +SpanScorer::SpanScorer(const SpansPtr& spans, const WeightPtr& weight, const SimilarityPtr& similarity, ByteArray norms) : Scorer(similarity) { + this->spans = spans; + this->norms = norms; + this->weight = weight; + this->value = weight->getValue(); + this->freq = 0.0; + if (this->spans->next()) { + doc = -1; + more = true; + } else { + doc = NO_MORE_DOCS; + more = false; } +} - int32_t SpanScorer::nextDoc() - { - if (!setFreqCurrentDoc()) - doc = NO_MORE_DOCS; - return doc; +SpanScorer::~SpanScorer() { +} + +int32_t SpanScorer::nextDoc() { + if (!setFreqCurrentDoc()) { + doc = NO_MORE_DOCS; } + return doc; +} - int32_t SpanScorer::advance(int32_t target) - { - if (!more) - { - doc = NO_MORE_DOCS; - return doc; - } - if (spans->doc() < target) // setFreqCurrentDoc() leaves spans->doc() ahead - more = spans->skipTo(target); - if (!setFreqCurrentDoc()) - doc = NO_MORE_DOCS; +int32_t SpanScorer::advance(int32_t target) { + if (!more) { + doc = NO_MORE_DOCS; return doc; } - - bool SpanScorer::setFreqCurrentDoc() - { - if (!more) - return false; - doc = spans->doc(); - freq = 0.0; - do - { - int32_t matchLength = spans->end() - spans->start(); - freq += getSimilarity()->sloppyFreq(matchLength); - more = spans->next(); - } - while (more && (doc == spans->doc())); - return true; + if (spans->doc() < target) { // setFreqCurrentDoc() leaves spans->doc() ahead + more = spans->skipTo(target); } - - int32_t SpanScorer::docID() - { - return doc; + if (!setFreqCurrentDoc()) { + doc = NO_MORE_DOCS; } + return doc; +} - double SpanScorer::score() - { - double raw = getSimilarity()->tf(freq) * value; // raw score - return norms ? raw * Similarity::decodeNorm(norms[doc]) : raw; // normalize +bool SpanScorer::setFreqCurrentDoc() { + if (!more) { + return false; } + doc = spans->doc(); + freq = 0.0; + do { + int32_t matchLength = spans->end() - spans->start(); + freq += getSimilarity()->sloppyFreq(matchLength); + more = spans->next(); + } while (more && (doc == spans->doc())); + return true; +} - ExplanationPtr SpanScorer::explain(int32_t doc) - { - ExplanationPtr tfExplanation(newLucene()); +int32_t SpanScorer::docID() { + return doc; +} - int32_t expDoc = advance(doc); +double SpanScorer::score() { + double raw = getSimilarity()->tf(freq) * value; // raw score + return norms ? raw * Similarity::decodeNorm(norms[doc]) : raw; // normalize +} - double phraseFreq = expDoc == doc ? freq : 0.0; - tfExplanation->setValue(getSimilarity()->tf(phraseFreq)); - tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); +ExplanationPtr SpanScorer::explain(int32_t doc) { + ExplanationPtr tfExplanation(newLucene()); + + int32_t expDoc = advance(doc); + + double phraseFreq = expDoc == doc ? freq : 0.0; + tfExplanation->setValue(getSimilarity()->tf(phraseFreq)); + tfExplanation->setDescription(L"tf(phraseFreq=" + StringUtils::toString(phraseFreq) + L")"); + + return tfExplanation; +} - return tfExplanation; - } } diff --git a/src/core/search/spans/SpanTermQuery.cpp b/src/core/search/spans/SpanTermQuery.cpp index 9664b312..3510a05d 100644 --- a/src/core/search/spans/SpanTermQuery.cpp +++ b/src/core/search/spans/SpanTermQuery.cpp @@ -11,82 +11,78 @@ #include "IndexReader.h" #include "MiscUtils.h" -namespace Lucene -{ - SpanTermQuery::SpanTermQuery(const TermPtr& term) - { - this->term = term; - } +namespace Lucene { - SpanTermQuery::~SpanTermQuery() - { - } +SpanTermQuery::SpanTermQuery(const TermPtr& term) { + this->term = term; +} - TermPtr SpanTermQuery::getTerm() - { - return term; - } +SpanTermQuery::~SpanTermQuery() { +} - String SpanTermQuery::getField() - { - return term->field(); - } +TermPtr SpanTermQuery::getTerm() { + return term; +} - void SpanTermQuery::extractTerms(SetTerm terms) - { - terms.add(term); - } +String SpanTermQuery::getField() { + return term->field(); +} - String SpanTermQuery::toString(const String& field) - { - StringStream buffer; - if (term->field() == field) - buffer << term->text(); - else - buffer << term->toString(); - buffer << boostString(); - return buffer.str(); - } +void SpanTermQuery::extractTerms(SetTerm terms) { + terms.add(term); +} - int32_t SpanTermQuery::hashCode() - { - int32_t prime = 31; - int32_t result = SpanQuery::hashCode(); - result = prime * result + (term ? term->hashCode() : 0); - return result; +String SpanTermQuery::toString(const String& field) { + StringStream buffer; + if (term->field() == field) { + buffer << term->text(); + } else { + buffer << term->toString(); } + buffer << boostString(); + return buffer.str(); +} - bool SpanTermQuery::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - if (!SpanQuery::equals(other)) - return false; - if (!MiscUtils::equalTypes(shared_from_this(), other)) - return false; - SpanTermQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); - if (!otherQuery) +int32_t SpanTermQuery::hashCode() { + int32_t prime = 31; + int32_t result = SpanQuery::hashCode(); + result = prime * result + (term ? term->hashCode() : 0); + return result; +} + +bool SpanTermQuery::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + if (!SpanQuery::equals(other)) { + return false; + } + if (!MiscUtils::equalTypes(shared_from_this(), other)) { + return false; + } + SpanTermQueryPtr otherQuery(boost::dynamic_pointer_cast(other)); + if (!otherQuery) { + return false; + } + if (!term) { + if (otherQuery->term) { return false; - if (!term) - { - if (otherQuery->term) - return false; } - else if (!term->equals(otherQuery->term)) - return false; - return true; + } else if (!term->equals(otherQuery->term)) { + return false; } + return true; +} - LuceneObjectPtr SpanTermQuery::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term)); - SpanTermQueryPtr spanFirstQuery(boost::dynamic_pointer_cast(clone)); - spanFirstQuery->term = term; - return spanFirstQuery; - } +LuceneObjectPtr SpanTermQuery::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = SpanQuery::clone(other ? other : newLucene(term)); + SpanTermQueryPtr spanFirstQuery(boost::dynamic_pointer_cast(clone)); + spanFirstQuery->term = term; + return spanFirstQuery; +} + +SpansPtr SpanTermQuery::getSpans(const IndexReaderPtr& reader) { + return newLucene(reader->termPositions(term), term); +} - SpansPtr SpanTermQuery::getSpans(const IndexReaderPtr& reader) - { - return newLucene(reader->termPositions(term), term); - } } diff --git a/src/core/search/spans/SpanWeight.cpp b/src/core/search/spans/SpanWeight.cpp index f60f801a..e8374d0e 100644 --- a/src/core/search/spans/SpanWeight.cpp +++ b/src/core/search/spans/SpanWeight.cpp @@ -13,105 +13,100 @@ #include "Similarity.h" #include "StringUtils.h" -namespace Lucene -{ - SpanWeight::SpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher) - { - this->similarity = query->getSimilarity(searcher); - this->query = query; - - terms = SetTerm::newInstance(); - query->extractTerms(terms); - - idfExp = similarity->idfExplain(Collection::newInstance(terms.begin(), terms.end()), searcher); - idf = idfExp->getIdf(); - value = 0.0; - queryNorm = 0.0; - queryWeight = 0.0; - } +namespace Lucene { - SpanWeight::~SpanWeight() - { - } +SpanWeight::SpanWeight(const SpanQueryPtr& query, const SearcherPtr& searcher) { + this->similarity = query->getSimilarity(searcher); + this->query = query; - QueryPtr SpanWeight::getQuery() - { - return query; - } + terms = SetTerm::newInstance(); + query->extractTerms(terms); - double SpanWeight::getValue() - { - return value; - } + idfExp = similarity->idfExplain(Collection::newInstance(terms.begin(), terms.end()), searcher); + idf = idfExp->getIdf(); + value = 0.0; + queryNorm = 0.0; + queryWeight = 0.0; +} - double SpanWeight::sumOfSquaredWeights() - { - queryWeight = idf * getQuery()->getBoost(); // compute query weight - return queryWeight * queryWeight; // square it - } +SpanWeight::~SpanWeight() { +} - void SpanWeight::normalize(double norm) - { - queryNorm = norm; - queryWeight *= queryNorm; // normalize query weight - value = queryWeight * idf; // idf for document - } +QueryPtr SpanWeight::getQuery() { + return query; +} - ScorerPtr SpanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) - { - return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); - } +double SpanWeight::getValue() { + return value; +} + +double SpanWeight::sumOfSquaredWeights() { + queryWeight = idf * getQuery()->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it +} + +void SpanWeight::normalize(double norm) { + queryNorm = norm; + queryWeight *= queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document +} - ExplanationPtr SpanWeight::explain(const IndexReaderPtr& reader, int32_t doc) - { - ComplexExplanationPtr result(newLucene()); - result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); - String field(query->getField()); +ScorerPtr SpanWeight::scorer(const IndexReaderPtr& reader, bool scoreDocsInOrder, bool topScorer) { + return newLucene(query->getSpans(reader), shared_from_this(), similarity, reader->norms(query->getField())); +} - ExplanationPtr idfExpl(newLucene(idf, L"idf(" + field + L":" + idfExp->explain() + L")")); +ExplanationPtr SpanWeight::explain(const IndexReaderPtr& reader, int32_t doc) { + ComplexExplanationPtr result(newLucene()); + result->setDescription(L"weight(" + query->toString() + L" in " + StringUtils::toString(doc) + L"), product of:"); + String field(query->getField()); - // explain query weight - ExplanationPtr queryExpl(newLucene()); - queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); + ExplanationPtr idfExpl(newLucene(idf, L"idf(" + field + L":" + idfExp->explain() + L")")); - ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); - if (query->getBoost() != 1.0) - queryExpl->addDetail(boostExpl); - queryExpl->addDetail(idfExpl); + // explain query weight + ExplanationPtr queryExpl(newLucene()); + queryExpl->setDescription(L"queryWeight(" + query->toString() + L"), product of:"); - ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); - queryExpl->addDetail(queryNormExpl); + ExplanationPtr boostExpl(newLucene(query->getBoost(), L"boost")); + if (query->getBoost() != 1.0) { + queryExpl->addDetail(boostExpl); + } + queryExpl->addDetail(idfExpl); - queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); - result->addDetail(queryExpl); + ExplanationPtr queryNormExpl(newLucene(queryNorm, L"queryNorm")); + queryExpl->addDetail(queryNormExpl); - // explain field weight - ComplexExplanationPtr fieldExpl(newLucene()); - fieldExpl->setDescription(L"fieldWeight(" + field + L":" + query->toString(field) + L" in " + StringUtils::toString(doc) + L"), product of:"); + queryExpl->setValue(boostExpl->getValue() * idfExpl->getValue() * queryNormExpl->getValue()); + result->addDetail(queryExpl); - ExplanationPtr tfExpl(boost::dynamic_pointer_cast(scorer(reader, true, false))->explain(doc)); - fieldExpl->addDetail(tfExpl); - fieldExpl->addDetail(idfExpl); + // explain field weight + ComplexExplanationPtr fieldExpl(newLucene()); + fieldExpl->setDescription(L"fieldWeight(" + field + L":" + query->toString(field) + L" in " + StringUtils::toString(doc) + L"), product of:"); - ExplanationPtr fieldNormExpl(newLucene()); - ByteArray fieldNorms(reader->norms(field)); - double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; - fieldNormExpl->setValue(fieldNorm); - fieldNormExpl->setDescription(L"fieldNorm(field=" + field + L", doc=" + StringUtils::toString(doc) + L")"); - fieldExpl->addDetail(fieldNormExpl); + ExplanationPtr tfExpl(boost::dynamic_pointer_cast(scorer(reader, true, false))->explain(doc)); + fieldExpl->addDetail(tfExpl); + fieldExpl->addDetail(idfExpl); - fieldExpl->setMatch(tfExpl->isMatch()); - fieldExpl->setValue(tfExpl->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); + ExplanationPtr fieldNormExpl(newLucene()); + ByteArray fieldNorms(reader->norms(field)); + double fieldNorm = fieldNorms ? Similarity::decodeNorm(fieldNorms[doc]) : 1.0; + fieldNormExpl->setValue(fieldNorm); + fieldNormExpl->setDescription(L"fieldNorm(field=" + field + L", doc=" + StringUtils::toString(doc) + L")"); + fieldExpl->addDetail(fieldNormExpl); - result->addDetail(fieldExpl); - result->setMatch(fieldExpl->getMatch()); + fieldExpl->setMatch(tfExpl->isMatch()); + fieldExpl->setValue(tfExpl->getValue() * idfExpl->getValue() * fieldNormExpl->getValue()); - // combine them - result->setValue(queryExpl->getValue() * fieldExpl->getValue()); + result->addDetail(fieldExpl); + result->setMatch(fieldExpl->getMatch()); - if (queryExpl->getValue() == 1.0) - return fieldExpl; + // combine them + result->setValue(queryExpl->getValue() * fieldExpl->getValue()); - return result; + if (queryExpl->getValue() == 1.0) { + return fieldExpl; } + + return result; +} + } diff --git a/src/core/search/spans/Spans.cpp b/src/core/search/spans/Spans.cpp index 6a213fa2..7991d50a 100644 --- a/src/core/search/spans/Spans.cpp +++ b/src/core/search/spans/Spans.cpp @@ -7,9 +7,9 @@ #include "LuceneInc.h" #include "Spans.h" -namespace Lucene -{ - Spans::~Spans() - { - } +namespace Lucene { + +Spans::~Spans() { +} + } diff --git a/src/core/search/spans/TermSpans.cpp b/src/core/search/spans/TermSpans.cpp index 86340fb4..09a30842 100644 --- a/src/core/search/spans/TermSpans.cpp +++ b/src/core/search/spans/TermSpans.cpp @@ -9,100 +9,88 @@ #include "TermPositions.h" #include "Term.h" -namespace Lucene -{ - TermSpans::TermSpans(const TermPositionsPtr& positions, const TermPtr& term) - { - this->positions = positions; - this->term = term; - this->_doc = -1; - this->freq = 0; - this->count = 0; - this->position = 0; - } +namespace Lucene { - TermSpans::~TermSpans() - { - } +TermSpans::TermSpans(const TermPositionsPtr& positions, const TermPtr& term) { + this->positions = positions; + this->term = term; + this->_doc = -1; + this->freq = 0; + this->count = 0; + this->position = 0; +} - bool TermSpans::next() - { - if (count == freq) - { - if (!positions->next()) - { - _doc = INT_MAX; - return false; - } - _doc = positions->doc(); - freq = positions->freq(); - count = 0; - } - position = positions->nextPosition(); - ++count; - return true; - } +TermSpans::~TermSpans() { +} - bool TermSpans::skipTo(int32_t target) - { - if (!positions->skipTo(target)) - { +bool TermSpans::next() { + if (count == freq) { + if (!positions->next()) { _doc = INT_MAX; return false; } - _doc = positions->doc(); freq = positions->freq(); count = 0; - - position = positions->nextPosition(); - ++count; - - return true; } + position = positions->nextPosition(); + ++count; + return true; +} - int32_t TermSpans::doc() - { - return _doc; +bool TermSpans::skipTo(int32_t target) { + if (!positions->skipTo(target)) { + _doc = INT_MAX; + return false; } - int32_t TermSpans::start() - { - return position; - } + _doc = positions->doc(); + freq = positions->freq(); + count = 0; - int32_t TermSpans::end() - { - return position + 1; - } + position = positions->nextPosition(); + ++count; - Collection TermSpans::getPayload() - { - Collection payload(newCollection(ByteArray::newInstance(positions->getPayloadLength()))); - payload[0] = positions->getPayload(payload[0], 0); - return payload; - } + return true; +} - bool TermSpans::isPayloadAvailable() - { - return positions->isPayloadAvailable(); - } +int32_t TermSpans::doc() { + return _doc; +} - String TermSpans::toString() - { - StringStream buffer; - buffer << L"spans(" << term->toString() << L")@"; - if (_doc == -1) - buffer << L"START"; - else if (_doc == INT_MAX) - buffer << L"END"; - else - buffer << _doc << L"-" << position; - return buffer.str(); - } +int32_t TermSpans::start() { + return position; +} + +int32_t TermSpans::end() { + return position + 1; +} + +Collection TermSpans::getPayload() { + Collection payload(newCollection(ByteArray::newInstance(positions->getPayloadLength()))); + payload[0] = positions->getPayload(payload[0], 0); + return payload; +} + +bool TermSpans::isPayloadAvailable() { + return positions->isPayloadAvailable(); +} - TermPositionsPtr TermSpans::getPositions() - { - return positions; +String TermSpans::toString() { + StringStream buffer; + buffer << L"spans(" << term->toString() << L")@"; + if (_doc == -1) { + buffer << L"START"; + } else if (_doc == INT_MAX) { + buffer << L"END"; + } else { + buffer << _doc << L"-" << position; } + return buffer.str(); +} + +TermPositionsPtr TermSpans::getPositions() { + return positions; +} + } diff --git a/src/core/store/BufferedIndexInput.cpp b/src/core/store/BufferedIndexInput.cpp index 33292eaf..42bc0c2c 100644 --- a/src/core/store/BufferedIndexInput.cpp +++ b/src/core/store/BufferedIndexInput.cpp @@ -9,183 +9,162 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// Default buffer size. - const int32_t BufferedIndexInput::BUFFER_SIZE = 1024; - - BufferedIndexInput::BufferedIndexInput(int32_t bufferSize) - { - this->bufferSize = bufferSize; - bufferStart = 0; - bufferLength = 0; - bufferPosition = 0; - } +namespace Lucene { - BufferedIndexInput::~BufferedIndexInput() - { - } +/// Default buffer size. +const int32_t BufferedIndexInput::BUFFER_SIZE = 1024; - uint8_t BufferedIndexInput::readByte() - { - if (bufferPosition >= bufferLength) - refill(); - return buffer[bufferPosition++]; +BufferedIndexInput::BufferedIndexInput(int32_t bufferSize) { + this->bufferSize = bufferSize; + bufferStart = 0; + bufferLength = 0; + bufferPosition = 0; +} + +BufferedIndexInput::~BufferedIndexInput() { +} + +uint8_t BufferedIndexInput::readByte() { + if (bufferPosition >= bufferLength) { + refill(); } + return buffer[bufferPosition++]; +} - void BufferedIndexInput::setBufferSize(int32_t newSize) - { - if (newSize != bufferSize) - { - bufferSize = newSize; - if (buffer) - { - // Resize the existing buffer and carefully save as many bytes as possible starting from the current bufferPosition - ByteArray _newBuffer(ByteArray::newInstance(newSize)); - int32_t leftInBuffer = bufferLength - bufferPosition; - int32_t numToCopy = leftInBuffer > newSize ? newSize : leftInBuffer; - - MiscUtils::arrayCopy(buffer.get(), bufferPosition, _newBuffer.get(), 0, numToCopy); - bufferStart += bufferPosition; - bufferPosition = 0; - bufferLength = numToCopy; - newBuffer(_newBuffer); - } +void BufferedIndexInput::setBufferSize(int32_t newSize) { + if (newSize != bufferSize) { + bufferSize = newSize; + if (buffer) { + // Resize the existing buffer and carefully save as many bytes as possible starting from the current bufferPosition + ByteArray _newBuffer(ByteArray::newInstance(newSize)); + int32_t leftInBuffer = bufferLength - bufferPosition; + int32_t numToCopy = leftInBuffer > newSize ? newSize : leftInBuffer; + + MiscUtils::arrayCopy(buffer.get(), bufferPosition, _newBuffer.get(), 0, numToCopy); + bufferStart += bufferPosition; + bufferPosition = 0; + bufferLength = numToCopy; + newBuffer(_newBuffer); } } +} - void BufferedIndexInput::newBuffer(ByteArray newBuffer) - { - // Subclasses can do something here - buffer = newBuffer; - } +void BufferedIndexInput::newBuffer(ByteArray newBuffer) { + // Subclasses can do something here + buffer = newBuffer; +} - int32_t BufferedIndexInput::getBufferSize() - { - return bufferSize; - } +int32_t BufferedIndexInput::getBufferSize() { + return bufferSize; +} - void BufferedIndexInput::checkBufferSize(int32_t bufferSize) - { - if (bufferSize <= 0) - boost::throw_exception(IllegalArgumentException(L"bufferSize must be greater than 0 (got " + StringUtils::toString(bufferSize) + L")")); +void BufferedIndexInput::checkBufferSize(int32_t bufferSize) { + if (bufferSize <= 0) { + boost::throw_exception(IllegalArgumentException(L"bufferSize must be greater than 0 (got " + StringUtils::toString(bufferSize) + L")")); } +} - void BufferedIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) - { - readBytes(b, offset, length, true); - } +void BufferedIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) { + readBytes(b, offset, length, true); +} - void BufferedIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer) - { - if (length <= (bufferLength - bufferPosition)) - { - // the buffer contains enough data to satisfy this request - if (length > 0) // to allow b to be null if length is 0 - MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, length); - bufferPosition += length; +void BufferedIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer) { + if (length <= (bufferLength - bufferPosition)) { + // the buffer contains enough data to satisfy this request + if (length > 0) { // to allow b to be null if length is 0 + MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, length); + } + bufferPosition += length; + } else { + // the buffer does not have enough data, first serve all we've got + int32_t available = bufferLength - bufferPosition; + if (available > 0) { + MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, available); + offset += available; + length -= available; + bufferPosition += available; } - else - { - // the buffer does not have enough data, first serve all we've got - int32_t available = bufferLength - bufferPosition; - if (available > 0) - { - MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, available); - offset += available; - length -= available; - bufferPosition += available; - } - // and now, read the remaining 'length' bytes - if (useBuffer && length < bufferSize) - { - // If the amount left to read is small enough, and we are allowed to use our buffer, - // do it in the usual buffered way: fill the buffer and copy from it - refill(); - if (bufferLength < length) - { - // throw an exception when refill() could not read length bytes - MiscUtils::arrayCopy(buffer.get(), 0, b, offset, bufferLength); - boost::throw_exception(IOException(L"Read past EOF")); - } - else - { - MiscUtils::arrayCopy(buffer.get(), 0, b, offset, length); - bufferPosition = length; - } + // and now, read the remaining 'length' bytes + if (useBuffer && length < bufferSize) { + // If the amount left to read is small enough, and we are allowed to use our buffer, + // do it in the usual buffered way: fill the buffer and copy from it + refill(); + if (bufferLength < length) { + // throw an exception when refill() could not read length bytes + MiscUtils::arrayCopy(buffer.get(), 0, b, offset, bufferLength); + boost::throw_exception(IOException(L"Read past EOF")); + } else { + MiscUtils::arrayCopy(buffer.get(), 0, b, offset, length); + bufferPosition = length; } - else - { - // The amount left to read is larger than the buffer or we've been asked to not use - // our buffer - there's no performance reason not to read it all at once. - // Note that unlike the previous code of this function, there is no need to do a seek - // here, because there's no need to reread what we had in the buffer. - int64_t after = bufferStart + bufferPosition + length; - if (after > this->length()) - boost::throw_exception(IOException(L"Read past EOF")); - readInternal(b, offset, length); - bufferStart = after; - bufferPosition = 0; - bufferLength = 0; // trigger refill() on read + } else { + // The amount left to read is larger than the buffer or we've been asked to not use + // our buffer - there's no performance reason not to read it all at once. + // Note that unlike the previous code of this function, there is no need to do a seek + // here, because there's no need to reread what we had in the buffer. + int64_t after = bufferStart + bufferPosition + length; + if (after > this->length()) { + boost::throw_exception(IOException(L"Read past EOF")); } + readInternal(b, offset, length); + bufferStart = after; + bufferPosition = 0; + bufferLength = 0; // trigger refill() on read } } +} - void BufferedIndexInput::refill() - { - int64_t start = bufferStart + bufferPosition; - int64_t end = start + bufferSize; - if (end > length()) // don't read past EOF - end = length(); - int32_t newLength = (int32_t)(end - start); - if (newLength <= 0) - boost::throw_exception(IOException(L"Read past EOF")); - - if (!buffer) - { - newBuffer(ByteArray::newInstance(bufferSize)); // allocate buffer lazily - seekInternal(bufferStart); - } - readInternal(buffer.get(), 0, newLength); - bufferLength = newLength; - bufferStart = start; - bufferPosition = 0; +void BufferedIndexInput::refill() { + int64_t start = bufferStart + bufferPosition; + int64_t end = start + bufferSize; + if (end > length()) { // don't read past EOF + end = length(); } - - void BufferedIndexInput::close() - { - bufferStart = 0; - bufferLength = 0; - bufferPosition = 0; + int32_t newLength = (int32_t)(end - start); + if (newLength <= 0) { + boost::throw_exception(IOException(L"Read past EOF")); } - int64_t BufferedIndexInput::getFilePointer() - { - return bufferStart + bufferPosition; + if (!buffer) { + newBuffer(ByteArray::newInstance(bufferSize)); // allocate buffer lazily + seekInternal(bufferStart); } + readInternal(buffer.get(), 0, newLength); + bufferLength = newLength; + bufferStart = start; + bufferPosition = 0; +} - void BufferedIndexInput::seek(int64_t pos) - { - if (pos >= bufferStart && pos < (bufferStart + bufferLength)) - bufferPosition = (int32_t)(pos - bufferStart); // seek within buffer - else - { - bufferStart = pos; - bufferPosition = 0; - bufferLength = 0; // trigger refill() on read() - seekInternal(pos); - } - } +void BufferedIndexInput::close() { + bufferStart = 0; + bufferLength = 0; + bufferPosition = 0; +} + +int64_t BufferedIndexInput::getFilePointer() { + return bufferStart + bufferPosition; +} - LuceneObjectPtr BufferedIndexInput::clone(const LuceneObjectPtr& other) - { - BufferedIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(IndexInput::clone(other))); - cloneIndexInput->bufferSize = bufferSize; - cloneIndexInput->buffer.reset(); - cloneIndexInput->bufferLength = 0; - cloneIndexInput->bufferPosition = 0; - cloneIndexInput->bufferStart = getFilePointer(); - return cloneIndexInput; +void BufferedIndexInput::seek(int64_t pos) { + if (pos >= bufferStart && pos < (bufferStart + bufferLength)) { + bufferPosition = (int32_t)(pos - bufferStart); // seek within buffer + } else { + bufferStart = pos; + bufferPosition = 0; + bufferLength = 0; // trigger refill() on read() + seekInternal(pos); } } + +LuceneObjectPtr BufferedIndexInput::clone(const LuceneObjectPtr& other) { + BufferedIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(IndexInput::clone(other))); + cloneIndexInput->bufferSize = bufferSize; + cloneIndexInput->buffer.reset(); + cloneIndexInput->bufferLength = 0; + cloneIndexInput->bufferPosition = 0; + cloneIndexInput->bufferStart = getFilePointer(); + return cloneIndexInput; +} + +} diff --git a/src/core/store/BufferedIndexOutput.cpp b/src/core/store/BufferedIndexOutput.cpp index 2d3a84c5..b033b2fb 100644 --- a/src/core/store/BufferedIndexOutput.cpp +++ b/src/core/store/BufferedIndexOutput.cpp @@ -8,101 +8,88 @@ #include "BufferedIndexOutput.h" #include "MiscUtils.h" -namespace Lucene -{ - const int32_t BufferedIndexOutput::BUFFER_SIZE = 16384; +namespace Lucene { - BufferedIndexOutput::BufferedIndexOutput() - { - bufferStart = 0; - bufferPosition = 0; - buffer = ByteArray::newInstance(BUFFER_SIZE); - } +const int32_t BufferedIndexOutput::BUFFER_SIZE = 16384; - BufferedIndexOutput::~BufferedIndexOutput() - { - } +BufferedIndexOutput::BufferedIndexOutput() { + bufferStart = 0; + bufferPosition = 0; + buffer = ByteArray::newInstance(BUFFER_SIZE); +} - void BufferedIndexOutput::writeByte(uint8_t b) - { - if (bufferPosition >= BUFFER_SIZE) - flush(); - buffer[bufferPosition++] = b; +BufferedIndexOutput::~BufferedIndexOutput() { +} + +void BufferedIndexOutput::writeByte(uint8_t b) { + if (bufferPosition >= BUFFER_SIZE) { + flush(); } + buffer[bufferPosition++] = b; +} - void BufferedIndexOutput::writeBytes(const uint8_t* b, int32_t offset, int32_t length) - { - int32_t bytesLeft = BUFFER_SIZE - bufferPosition; - if (bytesLeft >= length) - { - // we add the data to the end of the buffer - MiscUtils::arrayCopy(b, offset, buffer.get(), bufferPosition, length); - bufferPosition += length; - // if the buffer is full, flush it - if (BUFFER_SIZE - bufferPosition == 0) - flush(); +void BufferedIndexOutput::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { + int32_t bytesLeft = BUFFER_SIZE - bufferPosition; + if (bytesLeft >= length) { + // we add the data to the end of the buffer + MiscUtils::arrayCopy(b, offset, buffer.get(), bufferPosition, length); + bufferPosition += length; + // if the buffer is full, flush it + if (BUFFER_SIZE - bufferPosition == 0) { + flush(); } - else if (length > BUFFER_SIZE) - { - // we flush the buffer - if (bufferPosition > 0) - flush(); - // and write data at once - flushBuffer(b, offset, length); - bufferStart += length; + } else if (length > BUFFER_SIZE) { + // we flush the buffer + if (bufferPosition > 0) { + flush(); } - else - { - // we fill/flush the buffer (until the input is written) - int32_t pos = 0; // position in the input data - int32_t pieceLength; - while (pos < length) - { - pieceLength = (length - pos < bytesLeft) ? length - pos : bytesLeft; - MiscUtils::arrayCopy(b, pos + offset, buffer.get(), bufferPosition, pieceLength); - pos += pieceLength; - bufferPosition += pieceLength; - // if the buffer is full, flush it - bytesLeft = BUFFER_SIZE - bufferPosition; - if (bytesLeft == 0) - { - flush(); - bytesLeft = BUFFER_SIZE; - } + // and write data at once + flushBuffer(b, offset, length); + bufferStart += length; + } else { + // we fill/flush the buffer (until the input is written) + int32_t pos = 0; // position in the input data + int32_t pieceLength; + while (pos < length) { + pieceLength = (length - pos < bytesLeft) ? length - pos : bytesLeft; + MiscUtils::arrayCopy(b, pos + offset, buffer.get(), bufferPosition, pieceLength); + pos += pieceLength; + bufferPosition += pieceLength; + // if the buffer is full, flush it + bytesLeft = BUFFER_SIZE - bufferPosition; + if (bytesLeft == 0) { + flush(); + bytesLeft = BUFFER_SIZE; } } } +} - void BufferedIndexOutput::flush() - { - flushBuffer(buffer.get(), bufferPosition); - bufferStart += bufferPosition; - bufferPosition = 0; - } +void BufferedIndexOutput::flush() { + flushBuffer(buffer.get(), bufferPosition); + bufferStart += bufferPosition; + bufferPosition = 0; +} - void BufferedIndexOutput::flushBuffer(const uint8_t* b, int32_t length) - { - flushBuffer(b, 0, length); - } +void BufferedIndexOutput::flushBuffer(const uint8_t* b, int32_t length) { + flushBuffer(b, 0, length); +} - void BufferedIndexOutput::flushBuffer(const uint8_t* b, int32_t offset, int32_t length) - { - // override - } +void BufferedIndexOutput::flushBuffer(const uint8_t* b, int32_t offset, int32_t length) { + // override +} - void BufferedIndexOutput::close() - { - flush(); - } +void BufferedIndexOutput::close() { + flush(); +} - int64_t BufferedIndexOutput::getFilePointer() - { - return bufferStart + bufferPosition; - } +int64_t BufferedIndexOutput::getFilePointer() { + return bufferStart + bufferPosition; +} + +void BufferedIndexOutput::seek(int64_t pos) { + flush(); + bufferStart = pos; +} - void BufferedIndexOutput::seek(int64_t pos) - { - flush(); - bufferStart = pos; - } } diff --git a/src/core/store/ChecksumIndexInput.cpp b/src/core/store/ChecksumIndexInput.cpp index 96f696e4..d01e2181 100644 --- a/src/core/store/ChecksumIndexInput.cpp +++ b/src/core/store/ChecksumIndexInput.cpp @@ -7,61 +7,52 @@ #include "LuceneInc.h" #include "ChecksumIndexInput.h" -namespace Lucene -{ - ChecksumIndexInput::ChecksumIndexInput(const IndexInputPtr& main) - { - this->main = main; - } +namespace Lucene { - ChecksumIndexInput::~ChecksumIndexInput() - { - } +ChecksumIndexInput::ChecksumIndexInput(const IndexInputPtr& main) { + this->main = main; +} + +ChecksumIndexInput::~ChecksumIndexInput() { +} - uint8_t ChecksumIndexInput::readByte() - { - uint8_t b = main->readByte(); - checksum.process_byte(b); - return b; - } +uint8_t ChecksumIndexInput::readByte() { + uint8_t b = main->readByte(); + checksum.process_byte(b); + return b; +} + +void ChecksumIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) { + main->readBytes(b, offset, length); + checksum.process_bytes(b + offset, length); +} - void ChecksumIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) - { - main->readBytes(b, offset, length); - checksum.process_bytes(b + offset, length); - } +int64_t ChecksumIndexInput::getChecksum() { + return checksum.checksum(); +} - int64_t ChecksumIndexInput::getChecksum() - { - return checksum.checksum(); - } +void ChecksumIndexInput::close() { + main->close(); +} - void ChecksumIndexInput::close() - { - main->close(); - } +int64_t ChecksumIndexInput::getFilePointer() { + return main->getFilePointer(); +} - int64_t ChecksumIndexInput::getFilePointer() - { - return main->getFilePointer(); - } +void ChecksumIndexInput::seek(int64_t pos) { + boost::throw_exception(RuntimeException(L"Seek not allowed")); +} - void ChecksumIndexInput::seek(int64_t pos) - { - boost::throw_exception(RuntimeException(L"Seek not allowed")); - } +int64_t ChecksumIndexInput::length() { + return main->length(); +} - int64_t ChecksumIndexInput::length() - { - return main->length(); - } +LuceneObjectPtr ChecksumIndexInput::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene(main)); + ChecksumIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); + cloneIndexInput->main = main; + cloneIndexInput->checksum = checksum; + return cloneIndexInput; +} - LuceneObjectPtr ChecksumIndexInput::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene(main)); - ChecksumIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); - cloneIndexInput->main = main; - cloneIndexInput->checksum = checksum; - return cloneIndexInput; - } } diff --git a/src/core/store/ChecksumIndexOutput.cpp b/src/core/store/ChecksumIndexOutput.cpp index 87d0d38c..62f4171a 100644 --- a/src/core/store/ChecksumIndexOutput.cpp +++ b/src/core/store/ChecksumIndexOutput.cpp @@ -7,74 +7,63 @@ #include "LuceneInc.h" #include "ChecksumIndexOutput.h" -namespace Lucene -{ - ChecksumIndexOutput::ChecksumIndexOutput(const IndexOutputPtr& main) - { - this->main = main; - } - - ChecksumIndexOutput::~ChecksumIndexOutput() - { - } - - void ChecksumIndexOutput::writeByte(uint8_t b) - { - checksum.process_byte(b); - main->writeByte(b); - } - - void ChecksumIndexOutput::writeBytes(const uint8_t* b, int32_t offset, int32_t length) - { - checksum.process_bytes(b + offset, length); - main->writeBytes(b, offset, length); - } - - int64_t ChecksumIndexOutput::getChecksum() - { - return checksum.checksum(); - } - - void ChecksumIndexOutput::flush() - { - main->flush(); - } - - void ChecksumIndexOutput::close() - { - main->close(); - } - - int64_t ChecksumIndexOutput::getFilePointer() - { - return main->getFilePointer(); - } - - void ChecksumIndexOutput::seek(int64_t pos) - { - boost::throw_exception(RuntimeException(L"Seek not allowed")); - } - - void ChecksumIndexOutput::prepareCommit() - { - int64_t checksum = getChecksum(); - - // Intentionally write a mismatched checksum. This is because we want to 1) test, as best we can, that we - // are able to write a long to the file, but 2) not actually "commit" the file yet. This (prepare commit) - // is phase 1 of a two-phase commit. - int64_t pos = main->getFilePointer(); - main->writeLong(checksum - 1); - main->flush(); - main->seek(pos); - } - - void ChecksumIndexOutput::finishCommit() - { - main->writeLong(getChecksum()); - } - - int64_t ChecksumIndexOutput::length() - { - return main->length(); - } +namespace Lucene { + +ChecksumIndexOutput::ChecksumIndexOutput(const IndexOutputPtr& main) { + this->main = main; +} + +ChecksumIndexOutput::~ChecksumIndexOutput() { +} + +void ChecksumIndexOutput::writeByte(uint8_t b) { + checksum.process_byte(b); + main->writeByte(b); +} + +void ChecksumIndexOutput::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { + checksum.process_bytes(b + offset, length); + main->writeBytes(b, offset, length); +} + +int64_t ChecksumIndexOutput::getChecksum() { + return checksum.checksum(); +} + +void ChecksumIndexOutput::flush() { + main->flush(); +} + +void ChecksumIndexOutput::close() { + main->close(); +} + +int64_t ChecksumIndexOutput::getFilePointer() { + return main->getFilePointer(); +} + +void ChecksumIndexOutput::seek(int64_t pos) { + boost::throw_exception(RuntimeException(L"Seek not allowed")); +} + +void ChecksumIndexOutput::prepareCommit() { + int64_t checksum = getChecksum(); + + // Intentionally write a mismatched checksum. This is because we want to 1) test, as best we can, that we + // are able to write a long to the file, but 2) not actually "commit" the file yet. This (prepare commit) + // is phase 1 of a two-phase commit. + int64_t pos = main->getFilePointer(); + main->writeLong(checksum - 1); + main->flush(); + main->seek(pos); +} + +void ChecksumIndexOutput::finishCommit() { + main->writeLong(getChecksum()); +} + +int64_t ChecksumIndexOutput::length() { + return main->length(); +} + } diff --git a/src/core/store/Directory.cpp b/src/core/store/Directory.cpp index bf93af23..f7a6c4b6 100644 --- a/src/core/store/Directory.cpp +++ b/src/core/store/Directory.cpp @@ -12,126 +12,109 @@ #include "IndexInput.h" #include "IndexOutput.h" -namespace Lucene -{ - Directory::Directory() - { - isOpen = true; - } +namespace Lucene { - Directory::~Directory() - { - } +Directory::Directory() { + isOpen = true; +} - void Directory::close() - { - // override - } +Directory::~Directory() { +} - void Directory::sync(const String& name) - { - } +void Directory::close() { + // override +} - IndexInputPtr Directory::openInput(const String& name, int32_t bufferSize) - { - return openInput(name); - } +void Directory::sync(const String& name) { +} - LockPtr Directory::makeLock(const String& name) - { - return lockFactory->makeLock(name); - } +IndexInputPtr Directory::openInput(const String& name, int32_t bufferSize) { + return openInput(name); +} - void Directory::clearLock(const String& name) - { - if (lockFactory) - lockFactory->clearLock(name); - } +LockPtr Directory::makeLock(const String& name) { + return lockFactory->makeLock(name); +} - void Directory::setLockFactory(const LockFactoryPtr& lockFactory) - { - BOOST_ASSERT(lockFactory); - this->lockFactory = lockFactory; - this->lockFactory->setLockPrefix(getLockID()); +void Directory::clearLock(const String& name) { + if (lockFactory) { + lockFactory->clearLock(name); } +} - LockFactoryPtr Directory::getLockFactory() - { - return lockFactory; - } +void Directory::setLockFactory(const LockFactoryPtr& lockFactory) { + BOOST_ASSERT(lockFactory); + this->lockFactory = lockFactory; + this->lockFactory->setLockPrefix(getLockID()); +} - String Directory::getLockID() - { - return toString(); - } +LockFactoryPtr Directory::getLockFactory() { + return lockFactory; +} - String Directory::toString() - { - return LuceneObject::toString() + L" lockFactory=" + getLockFactory()->toString(); - } +String Directory::getLockID() { + return toString(); +} - void Directory::copy(const DirectoryPtr& src, const DirectoryPtr& dest, bool closeDirSrc) - { - HashSet files(src->listAll()); - - ByteArray buf(ByteArray::newInstance(BufferedIndexOutput::BUFFER_SIZE)); - - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - { - if (!IndexFileNameFilter::accept(L"", *file)) - continue; - - IndexOutputPtr os; - IndexInputPtr is; - - LuceneException finally; - try - { - // create file in dest directory - os = dest->createOutput(*file); - // read current file - is = src->openInput(*file); - // and copy to dest directory - int64_t len = is->length(); - int64_t readCount = 0; - while (readCount < len) - { - int32_t toRead = readCount + BufferedIndexOutput::BUFFER_SIZE > len ? (int32_t)(len - readCount) : BufferedIndexOutput::BUFFER_SIZE; - is->readBytes(buf.get(), 0, toRead); - os->writeBytes(buf.get(), toRead); - readCount += toRead; - } - } - catch (LuceneException& e) - { - finally = e; - } - // graceful cleanup - try - { - if (os) - os->close(); - } - catch (...) - { +String Directory::toString() { + return LuceneObject::toString() + L" lockFactory=" + getLockFactory()->toString(); +} + +void Directory::copy(const DirectoryPtr& src, const DirectoryPtr& dest, bool closeDirSrc) { + HashSet files(src->listAll()); + + ByteArray buf(ByteArray::newInstance(BufferedIndexOutput::BUFFER_SIZE)); + + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { + if (!IndexFileNameFilter::accept(L"", *file)) { + continue; + } + + IndexOutputPtr os; + IndexInputPtr is; + + LuceneException finally; + try { + // create file in dest directory + os = dest->createOutput(*file); + // read current file + is = src->openInput(*file); + // and copy to dest directory + int64_t len = is->length(); + int64_t readCount = 0; + while (readCount < len) { + int32_t toRead = readCount + BufferedIndexOutput::BUFFER_SIZE > len ? (int32_t)(len - readCount) : BufferedIndexOutput::BUFFER_SIZE; + is->readBytes(buf.get(), 0, toRead); + os->writeBytes(buf.get(), toRead); + readCount += toRead; } - try - { - if (is) - is->close(); + } catch (LuceneException& e) { + finally = e; + } + // graceful cleanup + try { + if (os) { + os->close(); } - catch (...) - { + } catch (...) { + } + try { + if (is) { + is->close(); } - finally.throwException(); + } catch (...) { } - if (closeDirSrc) - src->close(); + finally.throwException(); } + if (closeDirSrc) { + src->close(); + } +} - void Directory::ensureOpen() - { - if (!isOpen) - boost::throw_exception(AlreadyClosedException(L"This directory is closed")); +void Directory::ensureOpen() { + if (!isOpen) { + boost::throw_exception(AlreadyClosedException(L"This directory is closed")); } } + +} diff --git a/src/core/store/FSDirectory.cpp b/src/core/store/FSDirectory.cpp index 81d5e089..82b57366 100644 --- a/src/core/store/FSDirectory.cpp +++ b/src/core/store/FSDirectory.cpp @@ -19,229 +19,206 @@ extern "C" #include "../util/md5/md5.h" } -namespace Lucene -{ - /// Default read chunk size. This is a conditional default based on operating system. - #ifdef LPP_BUILD_64 - const int32_t FSDirectory::DEFAULT_READ_CHUNK_SIZE = INT_MAX; - #else - const int32_t FSDirectory::DEFAULT_READ_CHUNK_SIZE = 100 * 1024 * 1024; // 100mb - #endif - - FSDirectory::FSDirectory(const String& path, const LockFactoryPtr& lockFactory) - { - checked = false; - chunkSize = DEFAULT_READ_CHUNK_SIZE; - - LockFactoryPtr _lockFactory(lockFactory); - - // new ctors use always NativeFSLockFactory as default - if (!_lockFactory) - _lockFactory = newLucene(); - directory = path; - - if (FileUtils::fileExists(directory) && !FileUtils::isDirectory(directory)) - boost::throw_exception(NoSuchDirectoryException(L"File '" + directory + L"' exists but is not a directory")); - - setLockFactory(_lockFactory); - - // for filesystem based LockFactory, delete the lockPrefix if the locks are placed - // in index dir. if no index dir is given, set ourselves - FSLockFactoryPtr lf(boost::dynamic_pointer_cast(_lockFactory)); - - if (lf) - { - if (lf->getLockDir().empty()) - { - lf->setLockDir(directory); - lf->setLockPrefix(L""); - } - else if (lf->getLockDir() == directory) - lf->setLockPrefix(L""); - } - } +namespace Lucene { - FSDirectory::~FSDirectory() - { - } +/// Default read chunk size. This is a conditional default based on operating system. +#ifdef LPP_BUILD_64 +const int32_t FSDirectory::DEFAULT_READ_CHUNK_SIZE = INT_MAX; +#else +const int32_t FSDirectory::DEFAULT_READ_CHUNK_SIZE = 100 * 1024 * 1024; // 100mb +#endif - FSDirectoryPtr FSDirectory::open(const String& path) - { - return open(path, LockFactoryPtr()); - } +FSDirectory::FSDirectory(const String& path, const LockFactoryPtr& lockFactory) { + checked = false; + chunkSize = DEFAULT_READ_CHUNK_SIZE; + + LockFactoryPtr _lockFactory(lockFactory); - FSDirectoryPtr FSDirectory::open(const String& path, const LockFactoryPtr& lockFactory) - { - return newLucene(path, lockFactory); + // new ctors use always NativeFSLockFactory as default + if (!_lockFactory) { + _lockFactory = newLucene(); } + directory = path; - void FSDirectory::createDir() - { - if (!checked) - { - if (!FileUtils::fileExists(directory) && !FileUtils::createDirectory(directory)) - boost::throw_exception(IOException(L"Cannot create directory: " + directory)); - checked = true; - } + if (FileUtils::fileExists(directory) && !FileUtils::isDirectory(directory)) { + boost::throw_exception(NoSuchDirectoryException(L"File '" + directory + L"' exists but is not a directory")); } - void FSDirectory::initOutput(const String& name) - { - ensureOpen(); - createDir(); - String path(FileUtils::joinPath(directory, name)); - if (FileUtils::fileExists(path) && !FileUtils::removeFile(path)) // delete existing, if any - boost::throw_exception(IOException(L"Cannot overwrite: " + name)); + setLockFactory(_lockFactory); + + // for filesystem based LockFactory, delete the lockPrefix if the locks are placed + // in index dir. if no index dir is given, set ourselves + FSLockFactoryPtr lf(boost::dynamic_pointer_cast(_lockFactory)); + + if (lf) { + if (lf->getLockDir().empty()) { + lf->setLockDir(directory); + lf->setLockPrefix(L""); + } else if (lf->getLockDir() == directory) { + lf->setLockPrefix(L""); + } } +} - HashSet FSDirectory::listAll(const String& dir) - { - if (!FileUtils::fileExists(dir)) - boost::throw_exception(NoSuchDirectoryException(L"Directory '" + dir + L"' does not exist")); - else if (!FileUtils::isDirectory(dir)) - boost::throw_exception(NoSuchDirectoryException(L"File '" + dir + L"' exists but is not a directory")); +FSDirectory::~FSDirectory() { +} - HashSet result(HashSet::newInstance()); +FSDirectoryPtr FSDirectory::open(const String& path) { + return open(path, LockFactoryPtr()); +} - // Exclude subdirs - if (!FileUtils::listDirectory(dir, true, result)) - boost::throw_exception(IOException(L"Directory '" + dir + L"' exists and is a directory, but cannot be listed")); +FSDirectoryPtr FSDirectory::open(const String& path, const LockFactoryPtr& lockFactory) { + return newLucene(path, lockFactory); +} - return result; +void FSDirectory::createDir() { + if (!checked) { + if (!FileUtils::fileExists(directory) && !FileUtils::createDirectory(directory)) { + boost::throw_exception(IOException(L"Cannot create directory: " + directory)); + } + checked = true; } +} - HashSet FSDirectory::listAll() - { - ensureOpen(); - return listAll(directory); +void FSDirectory::initOutput(const String& name) { + ensureOpen(); + createDir(); + String path(FileUtils::joinPath(directory, name)); + if (FileUtils::fileExists(path) && !FileUtils::removeFile(path)) { // delete existing, if any + boost::throw_exception(IOException(L"Cannot overwrite: " + name)); } +} - bool FSDirectory::fileExists(const String& name) - { - ensureOpen(); - return FileUtils::fileExists(FileUtils::joinPath(directory, name)); +HashSet FSDirectory::listAll(const String& dir) { + if (!FileUtils::fileExists(dir)) { + boost::throw_exception(NoSuchDirectoryException(L"Directory '" + dir + L"' does not exist")); + } else if (!FileUtils::isDirectory(dir)) { + boost::throw_exception(NoSuchDirectoryException(L"File '" + dir + L"' exists but is not a directory")); } - uint64_t FSDirectory::fileModified(const String& name) - { - ensureOpen(); - return FileUtils::fileModified(FileUtils::joinPath(directory, name)); - } + HashSet result(HashSet::newInstance()); - uint64_t FSDirectory::fileModified(const String& directory, const String& name) - { - return FileUtils::fileModified(FileUtils::joinPath(directory, name)); + // Exclude subdirs + if (!FileUtils::listDirectory(dir, true, result)) { + boost::throw_exception(IOException(L"Directory '" + dir + L"' exists and is a directory, but cannot be listed")); } - void FSDirectory::touchFile(const String& name) - { - ensureOpen(); - FileUtils::touchFile(FileUtils::joinPath(directory, name)); - } + return result; +} - void FSDirectory::deleteFile(const String& name) - { - ensureOpen(); - if (!FileUtils::removeFile(FileUtils::joinPath(directory, name))) - boost::throw_exception(IOException(L"Cannot delete: " + name)); - } +HashSet FSDirectory::listAll() { + ensureOpen(); + return listAll(directory); +} - int64_t FSDirectory::fileLength(const String& name) - { - ensureOpen(); - return FileUtils::fileLength(FileUtils::joinPath(directory, name)); - } +bool FSDirectory::fileExists(const String& name) { + ensureOpen(); + return FileUtils::fileExists(FileUtils::joinPath(directory, name)); +} - void FSDirectory::sync(const String& name) - { - ensureOpen(); - String path(FileUtils::joinPath(directory, name)); - bool success = false; - - for (int32_t retryCount = 0; retryCount < 5; ++retryCount) - { - boost::filesystem::ofstream syncFile; - try - { - syncFile.open(path, std::ios::binary | std::ios::in | std::ios::out); - } - catch (...) - { - } - - if (syncFile.is_open()) - { - syncFile.close(); - success = true; - break; - } - - LuceneThread::threadSleep(5); // pause 5 msec - } +uint64_t FSDirectory::fileModified(const String& name) { + ensureOpen(); + return FileUtils::fileModified(FileUtils::joinPath(directory, name)); +} - if (!success) - boost::throw_exception(IOException(L"Sync failure: " + path)); - } +uint64_t FSDirectory::fileModified(const String& directory, const String& name) { + return FileUtils::fileModified(FileUtils::joinPath(directory, name)); +} - IndexInputPtr FSDirectory::openInput(const String& name) - { - ensureOpen(); - return openInput(name, BufferedIndexInput::BUFFER_SIZE); - } +void FSDirectory::touchFile(const String& name) { + ensureOpen(); + FileUtils::touchFile(FileUtils::joinPath(directory, name)); +} - IndexInputPtr FSDirectory::openInput(const String& name, int32_t bufferSize) - { - return Directory::openInput(name, bufferSize); +void FSDirectory::deleteFile(const String& name) { + ensureOpen(); + if (!FileUtils::removeFile(FileUtils::joinPath(directory, name))) { + boost::throw_exception(IOException(L"Cannot delete: " + name)); } +} - String FSDirectory::getLockID() - { - ensureOpen(); - md5_state_t state; - md5_byte_t digest[16]; +int64_t FSDirectory::fileLength(const String& name) { + ensureOpen(); + return FileUtils::fileLength(FileUtils::joinPath(directory, name)); +} - md5_init(&state); - md5_append(&state, (const md5_byte_t *)StringUtils::toUTF8(directory).c_str(), directory.size()); - md5_finish(&state, digest); +void FSDirectory::sync(const String& name) { + ensureOpen(); + String path(FileUtils::joinPath(directory, name)); + bool success = false; - static const wchar_t* hexDigits = L"0123456789abcdef"; + for (int32_t retryCount = 0; retryCount < 5; ++retryCount) { + boost::filesystem::ofstream syncFile; + try { + syncFile.open(path, std::ios::binary | std::ios::in | std::ios::out); + } catch (...) { + } - String lockID(L"lucene-"); - for (int32_t i = 0; i < 16; ++i) - { - lockID += hexDigits[(digest[i] >> 4) & 0x0f]; - lockID += hexDigits[digest[i] & 0x0f]; + if (syncFile.is_open()) { + syncFile.close(); + success = true; + break; } - return lockID; + LuceneThread::threadSleep(5); // pause 5 msec } - void FSDirectory::close() - { - SyncLock syncLock(this); - isOpen = false; + if (!success) { + boost::throw_exception(IOException(L"Sync failure: " + path)); } +} - String FSDirectory::toString() - { - return getClassName() + L"@" + directory + L" lockFactory=" + getLockFactory()->toString(); - } +IndexInputPtr FSDirectory::openInput(const String& name) { + ensureOpen(); + return openInput(name, BufferedIndexInput::BUFFER_SIZE); +} - String FSDirectory::getFile() - { - ensureOpen(); - return directory; - } +IndexInputPtr FSDirectory::openInput(const String& name, int32_t bufferSize) { + return Directory::openInput(name, bufferSize); +} - void FSDirectory::setReadChunkSize(int32_t chunkSize) - { - #ifndef LPP_BUILD_64 - this->chunkSize = chunkSize; - #endif - } +String FSDirectory::getLockID() { + ensureOpen(); + md5_state_t state; + md5_byte_t digest[16]; + + md5_init(&state); + md5_append(&state, (const md5_byte_t*)StringUtils::toUTF8(directory).c_str(), directory.size()); + md5_finish(&state, digest); + + static const wchar_t* hexDigits = L"0123456789abcdef"; - int32_t FSDirectory::getReadChunkSize() - { - return chunkSize; + String lockID(L"lucene-"); + for (int32_t i = 0; i < 16; ++i) { + lockID += hexDigits[(digest[i] >> 4) & 0x0f]; + lockID += hexDigits[digest[i] & 0x0f]; } + + return lockID; +} + +void FSDirectory::close() { + SyncLock syncLock(this); + isOpen = false; +} + +String FSDirectory::toString() { + return getClassName() + L"@" + directory + L" lockFactory=" + getLockFactory()->toString(); +} + +String FSDirectory::getFile() { + ensureOpen(); + return directory; +} + +void FSDirectory::setReadChunkSize(int32_t chunkSize) { +#ifndef LPP_BUILD_64 + this->chunkSize = chunkSize; +#endif +} + +int32_t FSDirectory::getReadChunkSize() { + return chunkSize; +} + } diff --git a/src/core/store/FSLockFactory.cpp b/src/core/store/FSLockFactory.cpp index ab8107c2..ba40de16 100644 --- a/src/core/store/FSLockFactory.cpp +++ b/src/core/store/FSLockFactory.cpp @@ -7,25 +7,23 @@ #include "LuceneInc.h" #include "FSLockFactory.h" -namespace Lucene -{ - FSLockFactory::FSLockFactory() - { - } +namespace Lucene { - FSLockFactory::~FSLockFactory() - { - } +FSLockFactory::FSLockFactory() { +} - void FSLockFactory::setLockDir(const String& lockDir) - { - if (!this->lockDir.empty()) - boost::throw_exception(IllegalStateException(L"You can set the lock directory for this factory only once.")); - this->lockDir = lockDir; - } +FSLockFactory::~FSLockFactory() { +} - String FSLockFactory::getLockDir() - { - return lockDir; +void FSLockFactory::setLockDir(const String& lockDir) { + if (!this->lockDir.empty()) { + boost::throw_exception(IllegalStateException(L"You can set the lock directory for this factory only once.")); } + this->lockDir = lockDir; +} + +String FSLockFactory::getLockDir() { + return lockDir; +} + } diff --git a/src/core/store/FileSwitchDirectory.cpp b/src/core/store/FileSwitchDirectory.cpp index 2378c2f6..081ce450 100644 --- a/src/core/store/FileSwitchDirectory.cpp +++ b/src/core/store/FileSwitchDirectory.cpp @@ -7,107 +7,88 @@ #include "LuceneInc.h" #include "FileSwitchDirectory.h" -namespace Lucene -{ - FileSwitchDirectory::FileSwitchDirectory(HashSet primaryExtensions, const DirectoryPtr& primaryDir, const DirectoryPtr& secondaryDir, bool doClose) - { - this->primaryExtensions = primaryExtensions; - this->primaryDir = primaryDir; - this->secondaryDir = secondaryDir; - this->doClose = doClose; - this->lockFactory = primaryDir->getLockFactory(); - } +namespace Lucene { + +FileSwitchDirectory::FileSwitchDirectory(HashSet primaryExtensions, const DirectoryPtr& primaryDir, const DirectoryPtr& secondaryDir, bool doClose) { + this->primaryExtensions = primaryExtensions; + this->primaryDir = primaryDir; + this->secondaryDir = secondaryDir; + this->doClose = doClose; + this->lockFactory = primaryDir->getLockFactory(); +} - FileSwitchDirectory::~FileSwitchDirectory() - { - } +FileSwitchDirectory::~FileSwitchDirectory() { +} - DirectoryPtr FileSwitchDirectory::getPrimaryDir() - { - return primaryDir; - } +DirectoryPtr FileSwitchDirectory::getPrimaryDir() { + return primaryDir; +} - DirectoryPtr FileSwitchDirectory::getSecondaryDir() - { - return secondaryDir; - } +DirectoryPtr FileSwitchDirectory::getSecondaryDir() { + return secondaryDir; +} - void FileSwitchDirectory::close() - { - if (doClose) - { - LuceneException finally; - try - { - secondaryDir->close(); - } - catch (LuceneException& e) - { - finally = e; - } - doClose = false; - primaryDir->close(); - finally.throwException(); +void FileSwitchDirectory::close() { + if (doClose) { + LuceneException finally; + try { + secondaryDir->close(); + } catch (LuceneException& e) { + finally = e; } + doClose = false; + primaryDir->close(); + finally.throwException(); } +} - HashSet FileSwitchDirectory::listAll() - { - HashSet primaryFiles(primaryDir->listAll()); - HashSet secondaryFiles(secondaryDir->listAll()); - HashSet files(HashSet::newInstance(primaryFiles.begin(), primaryFiles.end())); - files.addAll(secondaryFiles.begin(), secondaryFiles.end()); - return files; - } +HashSet FileSwitchDirectory::listAll() { + HashSet primaryFiles(primaryDir->listAll()); + HashSet secondaryFiles(secondaryDir->listAll()); + HashSet files(HashSet::newInstance(primaryFiles.begin(), primaryFiles.end())); + files.addAll(secondaryFiles.begin(), secondaryFiles.end()); + return files; +} - String FileSwitchDirectory::getExtension(const String& name) - { - String::size_type i = name.find_last_of(L'.'); - return i == String::npos ? L"" : name.substr(i + 1); - } +String FileSwitchDirectory::getExtension(const String& name) { + String::size_type i = name.find_last_of(L'.'); + return i == String::npos ? L"" : name.substr(i + 1); +} - DirectoryPtr FileSwitchDirectory::getDirectory(const String& name) - { - return primaryExtensions.contains(getExtension(name)) ? primaryDir : secondaryDir; - } +DirectoryPtr FileSwitchDirectory::getDirectory(const String& name) { + return primaryExtensions.contains(getExtension(name)) ? primaryDir : secondaryDir; +} - bool FileSwitchDirectory::fileExists(const String& name) - { - return getDirectory(name)->fileExists(name); - } +bool FileSwitchDirectory::fileExists(const String& name) { + return getDirectory(name)->fileExists(name); +} - uint64_t FileSwitchDirectory::fileModified(const String& name) - { - return getDirectory(name)->fileModified(name); - } +uint64_t FileSwitchDirectory::fileModified(const String& name) { + return getDirectory(name)->fileModified(name); +} - void FileSwitchDirectory::touchFile(const String& name) - { - getDirectory(name)->touchFile(name); - } +void FileSwitchDirectory::touchFile(const String& name) { + getDirectory(name)->touchFile(name); +} - void FileSwitchDirectory::deleteFile(const String& name) - { - getDirectory(name)->deleteFile(name); - } +void FileSwitchDirectory::deleteFile(const String& name) { + getDirectory(name)->deleteFile(name); +} - int64_t FileSwitchDirectory::fileLength(const String& name) - { - return getDirectory(name)->fileLength(name); - } +int64_t FileSwitchDirectory::fileLength(const String& name) { + return getDirectory(name)->fileLength(name); +} - IndexOutputPtr FileSwitchDirectory::createOutput(const String& name) - { - return getDirectory(name)->createOutput(name); - } +IndexOutputPtr FileSwitchDirectory::createOutput(const String& name) { + return getDirectory(name)->createOutput(name); +} - void FileSwitchDirectory::sync(const String& name) - { - getDirectory(name)->sync(name); - } +void FileSwitchDirectory::sync(const String& name) { + getDirectory(name)->sync(name); +} + +IndexInputPtr FileSwitchDirectory::openInput(const String& name) { + return getDirectory(name)->openInput(name); +} - IndexInputPtr FileSwitchDirectory::openInput(const String& name) - { - return getDirectory(name)->openInput(name); - } } diff --git a/src/core/store/IndexInput.cpp b/src/core/store/IndexInput.cpp index 592eb02a..319f3161 100644 --- a/src/core/store/IndexInput.cpp +++ b/src/core/store/IndexInput.cpp @@ -10,146 +10,126 @@ #include "Reader.h" #include "StringUtils.h" -namespace Lucene -{ - IndexInput::IndexInput() - { - preUTF8Strings = false; - } +namespace Lucene { - IndexInput::~IndexInput() - { - } +IndexInput::IndexInput() { + preUTF8Strings = false; +} - void IndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer) - { - // default to ignoring useBuffer entirely - readBytes(b, offset, length); - } +IndexInput::~IndexInput() { +} - int32_t IndexInput::readInt() - { - int32_t i = (readByte() & 0xff) << 24; - i |= (readByte() & 0xff) << 16; - i |= (readByte() & 0xff) << 8; - i |= (readByte() & 0xff); - return i; - } +void IndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length, bool useBuffer) { + // default to ignoring useBuffer entirely + readBytes(b, offset, length); +} - int32_t IndexInput::readVInt() - { - uint8_t b = readByte(); - int32_t i = (b & 0x7f); +int32_t IndexInput::readInt() { + int32_t i = (readByte() & 0xff) << 24; + i |= (readByte() & 0xff) << 16; + i |= (readByte() & 0xff) << 8; + i |= (readByte() & 0xff); + return i; +} - for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) - { - b = readByte(); - i |= (b & 0x7f) << shift; - } - return i; - } +int32_t IndexInput::readVInt() { + uint8_t b = readByte(); + int32_t i = (b & 0x7f); - int64_t IndexInput::readLong() - { - int64_t i = (int64_t)readInt() << 32; - i |= (readInt() & 0xffffffffLL); - return i; + for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) { + b = readByte(); + i |= (b & 0x7f) << shift; } + return i; +} - int64_t IndexInput::readVLong() - { - uint8_t b = readByte(); - int64_t i = (b & 0x7f); +int64_t IndexInput::readLong() { + int64_t i = (int64_t)readInt() << 32; + i |= (readInt() & 0xffffffffLL); + return i; +} - for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) - { - b = readByte(); - i |= (int64_t)(b & 0x7f) << shift; - } - return i; - } +int64_t IndexInput::readVLong() { + uint8_t b = readByte(); + int64_t i = (b & 0x7f); - void IndexInput::setModifiedUTF8StringsMode() - { - preUTF8Strings = true; + for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) { + b = readByte(); + i |= (int64_t)(b & 0x7f) << shift; } + return i; +} - String IndexInput::readString() - { - if (preUTF8Strings) - return readModifiedUTF8String(); - int32_t length = readVInt(); - ByteArray bytes(ByteArray::newInstance(length)); - readBytes(bytes.get(), 0, length); - return StringUtils::toUnicode(bytes.get(), length); - } +void IndexInput::setModifiedUTF8StringsMode() { + preUTF8Strings = true; +} - String IndexInput::readModifiedUTF8String() - { - int32_t length = readVInt(); - CharArray chars(CharArray::newInstance(length)); - return String(chars.get(), readChars(chars.get(), 0, length)); +String IndexInput::readString() { + if (preUTF8Strings) { + return readModifiedUTF8String(); } + int32_t length = readVInt(); + ByteArray bytes(ByteArray::newInstance(length)); + readBytes(bytes.get(), 0, length); + return StringUtils::toUnicode(bytes.get(), length); +} - int32_t IndexInput::readChars(wchar_t* buffer, int32_t start, int32_t length) - { - Array chars(Array::newInstance(length)); - for (int32_t i = 0; i < length; ++i) - { - uint8_t b = readByte(); - if ((b & 0x80) == 0) - chars[i] = (uint16_t)(b & 0x7f); - else if ((b & 0xe0) != 0xe0) - chars[i] = (uint16_t)(((b & 0x1f) << 6) | (readByte() & 0x3f)); - else - { - uint32_t ch = ((b & 0x0f) << 12); - ch |= (readByte() & 0x3f) << 6; - ch |= (readByte() & 0x3f); - chars[i] = (uint16_t)ch; - } - } - UTF16DecoderPtr utf16Decoder(newLucene(chars.get(), chars.get() + length)); - int32_t decodeLength = utf16Decoder->decode(buffer + start, length); - return decodeLength == Reader::READER_EOF ? 0 : decodeLength; - } +String IndexInput::readModifiedUTF8String() { + int32_t length = readVInt(); + CharArray chars(CharArray::newInstance(length)); + return String(chars.get(), readChars(chars.get(), 0, length)); +} - void IndexInput::skipChars(int32_t length) - { - for (int32_t i = 0; i < length; ++i) - { - uint8_t b = readByte(); - if ((b & 0x80) == 0) - { // do nothing, we only need one byte - } - else if ((b & 0xe0) != 0xe0) - readByte(); // read an additional byte - else - { - // read two additional bytes - readByte(); - readByte(); - } +int32_t IndexInput::readChars(wchar_t* buffer, int32_t start, int32_t length) { + Array chars(Array::newInstance(length)); + for (int32_t i = 0; i < length; ++i) { + uint8_t b = readByte(); + if ((b & 0x80) == 0) { + chars[i] = (uint16_t)(b & 0x7f); + } else if ((b & 0xe0) != 0xe0) { + chars[i] = (uint16_t)(((b & 0x1f) << 6) | (readByte() & 0x3f)); + } else { + uint32_t ch = ((b & 0x0f) << 12); + ch |= (readByte() & 0x3f) << 6; + ch |= (readByte() & 0x3f); + chars[i] = (uint16_t)ch; } } + UTF16DecoderPtr utf16Decoder(newLucene(chars.get(), chars.get() + length)); + int32_t decodeLength = utf16Decoder->decode(buffer + start, length); + return decodeLength == Reader::READER_EOF ? 0 : decodeLength; +} - MapStringString IndexInput::readStringStringMap() - { - MapStringString map(MapStringString::newInstance()); - int32_t count = readInt(); - for (int32_t i = 0; i < count; ++i) - { - String key(readString()); - String val(readString()); - map.put(key, val); +void IndexInput::skipChars(int32_t length) { + for (int32_t i = 0; i < length; ++i) { + uint8_t b = readByte(); + if ((b & 0x80) == 0) { + // do nothing, we only need one byte + } else if ((b & 0xe0) != 0xe0) { + readByte(); // read an additional byte + } else { + // read two additional bytes + readByte(); + readByte(); } - return map; } +} - LuceneObjectPtr IndexInput::clone(const LuceneObjectPtr& other) - { - IndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(LuceneObject::clone(other))); - cloneIndexInput->preUTF8Strings = preUTF8Strings; - return cloneIndexInput; +MapStringString IndexInput::readStringStringMap() { + MapStringString map(MapStringString::newInstance()); + int32_t count = readInt(); + for (int32_t i = 0; i < count; ++i) { + String key(readString()); + String val(readString()); + map.put(key, val); } + return map; +} + +LuceneObjectPtr IndexInput::clone(const LuceneObjectPtr& other) { + IndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(LuceneObject::clone(other))); + cloneIndexInput->preUTF8Strings = preUTF8Strings; + return cloneIndexInput; +} + } diff --git a/src/core/store/IndexOutput.cpp b/src/core/store/IndexOutput.cpp index 90859ed3..5245da0e 100644 --- a/src/core/store/IndexOutput.cpp +++ b/src/core/store/IndexOutput.cpp @@ -11,114 +11,96 @@ #include "UnicodeUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t IndexOutput::COPY_BUFFER_SIZE = 16384; +namespace Lucene { - IndexOutput::~IndexOutput() - { - } +const int32_t IndexOutput::COPY_BUFFER_SIZE = 16384; - void IndexOutput::writeBytes(const uint8_t* b, int32_t length) - { - writeBytes(b, 0, length); - } +IndexOutput::~IndexOutput() { +} - void IndexOutput::writeInt(int32_t i) - { - writeByte((uint8_t)(i >> 24)); - writeByte((uint8_t)(i >> 16)); - writeByte((uint8_t)(i >> 8)); - writeByte((uint8_t)i); - } +void IndexOutput::writeBytes(const uint8_t* b, int32_t length) { + writeBytes(b, 0, length); +} - void IndexOutput::writeVInt(int32_t i) - { - while ((i & ~0x7f) != 0) - { - writeByte((uint8_t)((i & 0x7f) | 0x80)); - i = MiscUtils::unsignedShift(i, 7); - } - writeByte((uint8_t)i); - } +void IndexOutput::writeInt(int32_t i) { + writeByte((uint8_t)(i >> 24)); + writeByte((uint8_t)(i >> 16)); + writeByte((uint8_t)(i >> 8)); + writeByte((uint8_t)i); +} - void IndexOutput::writeLong(int64_t i) - { - writeInt((int32_t)(i >> 32)); - writeInt((int32_t)i); +void IndexOutput::writeVInt(int32_t i) { + while ((i & ~0x7f) != 0) { + writeByte((uint8_t)((i & 0x7f) | 0x80)); + i = MiscUtils::unsignedShift(i, 7); } + writeByte((uint8_t)i); +} - void IndexOutput::writeVLong(int64_t i) - { - while ((i & ~0x7f) != 0) - { - writeByte((uint8_t)((i & 0x7f) | 0x80)); - i = MiscUtils::unsignedShift(i, (int64_t)7); - } - writeByte((uint8_t)i); - } +void IndexOutput::writeLong(int64_t i) { + writeInt((int32_t)(i >> 32)); + writeInt((int32_t)i); +} - void IndexOutput::writeString(const String& s) - { - UTF8ResultPtr utf8Result(newLucene()); - StringUtils::toUTF8(s.c_str(), s.length(), utf8Result); - writeVInt(utf8Result->length); - writeBytes(utf8Result->result.get(), utf8Result->length); +void IndexOutput::writeVLong(int64_t i) { + while ((i & ~0x7f) != 0) { + writeByte((uint8_t)((i & 0x7f) | 0x80)); + i = MiscUtils::unsignedShift(i, (int64_t)7); } + writeByte((uint8_t)i); +} - void IndexOutput::writeChars(const String& s, int32_t start, int32_t length) - { - int32_t end = start + length; - for (int32_t i = start; i < end; ++i) - { - int32_t code = (int32_t)s[i]; - if (code >= 0x01 && code <= 0x7f) - writeByte((uint8_t)code); - else if (((code >= 0x80) && (code <= 0x7ff)) || code == 0) - { - writeByte((uint8_t)(0xc0 | (code >> 6))); - writeByte((uint8_t)(0x80 | (code & 0x3f))); - } - else - { - writeByte((uint8_t)(0xe0 | MiscUtils::unsignedShift(code, 12))); - writeByte((uint8_t)(0x80 | ((code >> 6) & 0x3f))); - writeByte((uint8_t)(0x80 | (code & 0x3f))); - } - } - } +void IndexOutput::writeString(const String& s) { + UTF8ResultPtr utf8Result(newLucene()); + StringUtils::toUTF8(s.c_str(), s.length(), utf8Result); + writeVInt(utf8Result->length); + writeBytes(utf8Result->result.get(), utf8Result->length); +} - void IndexOutput::copyBytes(const IndexInputPtr& input, int64_t numBytes) - { - BOOST_ASSERT(numBytes >= 0); - int64_t left = numBytes; - if (!copyBuffer) - copyBuffer = ByteArray::newInstance(COPY_BUFFER_SIZE); - while (left > 0) - { - int32_t toCopy = left > COPY_BUFFER_SIZE ? COPY_BUFFER_SIZE : (int32_t)left; - input->readBytes(copyBuffer.get(), 0, toCopy); - writeBytes(copyBuffer.get(), 0, toCopy); - left -= toCopy; +void IndexOutput::writeChars(const String& s, int32_t start, int32_t length) { + int32_t end = start + length; + for (int32_t i = start; i < end; ++i) { + int32_t code = (int32_t)s[i]; + if (code >= 0x01 && code <= 0x7f) { + writeByte((uint8_t)code); + } else if (((code >= 0x80) && (code <= 0x7ff)) || code == 0) { + writeByte((uint8_t)(0xc0 | (code >> 6))); + writeByte((uint8_t)(0x80 | (code & 0x3f))); + } else { + writeByte((uint8_t)(0xe0 | MiscUtils::unsignedShift(code, 12))); + writeByte((uint8_t)(0x80 | ((code >> 6) & 0x3f))); + writeByte((uint8_t)(0x80 | (code & 0x3f))); } } +} - void IndexOutput::setLength(int64_t length) - { +void IndexOutput::copyBytes(const IndexInputPtr& input, int64_t numBytes) { + BOOST_ASSERT(numBytes >= 0); + int64_t left = numBytes; + if (!copyBuffer) { + copyBuffer = ByteArray::newInstance(COPY_BUFFER_SIZE); + } + while (left > 0) { + int32_t toCopy = left > COPY_BUFFER_SIZE ? COPY_BUFFER_SIZE : (int32_t)left; + input->readBytes(copyBuffer.get(), 0, toCopy); + writeBytes(copyBuffer.get(), 0, toCopy); + left -= toCopy; } +} + +void IndexOutput::setLength(int64_t length) { +} - void IndexOutput::writeStringStringMap(MapStringString map) - { - if (!map) - writeInt(0); - else - { - writeInt(map.size()); - for (MapStringString::iterator entry = map.begin(); entry != map.end(); ++entry) - { - writeString(entry->first); - writeString(entry->second); - } +void IndexOutput::writeStringStringMap(MapStringString map) { + if (!map) { + writeInt(0); + } else { + writeInt(map.size()); + for (MapStringString::iterator entry = map.begin(); entry != map.end(); ++entry) { + writeString(entry->first); + writeString(entry->second); } } } + +} diff --git a/src/core/store/Lock.cpp b/src/core/store/Lock.cpp index 0b3fd37c..04874160 100644 --- a/src/core/store/Lock.cpp +++ b/src/core/store/Lock.cpp @@ -8,30 +8,29 @@ #include "Lock.h" #include "LuceneThread.h" -namespace Lucene -{ - /// How long {@link #obtain(int64_t)} waits, in milliseconds, in between attempts to acquire the lock. - const int32_t Lock::LOCK_OBTAIN_WAIT_FOREVER = -1; +namespace Lucene { - /// Pass this value to {@link #obtain(int64_t)} to try forever to obtain the lock. - const int32_t Lock::LOCK_POLL_INTERVAL = 1000; +/// How long {@link #obtain(int64_t)} waits, in milliseconds, in between attempts to acquire the lock. +const int32_t Lock::LOCK_OBTAIN_WAIT_FOREVER = -1; - Lock::~Lock() - { - } +/// Pass this value to {@link #obtain(int64_t)} to try forever to obtain the lock. +const int32_t Lock::LOCK_POLL_INTERVAL = 1000; + +Lock::~Lock() { +} - bool Lock::obtain(int32_t lockWaitTimeout) - { - bool locked = obtain(); - int32_t maxSleepCount = lockWaitTimeout / LOCK_POLL_INTERVAL; - int32_t sleepCount = 0; - while (!locked) - { - if (lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ >= maxSleepCount) - boost::throw_exception(LockObtainFailedException(L"Lock obtain timed out")); - LuceneThread::threadSleep(LOCK_POLL_INTERVAL); - locked = obtain(); +bool Lock::obtain(int32_t lockWaitTimeout) { + bool locked = obtain(); + int32_t maxSleepCount = lockWaitTimeout / LOCK_POLL_INTERVAL; + int32_t sleepCount = 0; + while (!locked) { + if (lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ >= maxSleepCount) { + boost::throw_exception(LockObtainFailedException(L"Lock obtain timed out")); } - return locked; + LuceneThread::threadSleep(LOCK_POLL_INTERVAL); + locked = obtain(); } + return locked; +} + } diff --git a/src/core/store/LockFactory.cpp b/src/core/store/LockFactory.cpp index fdf09314..2c03fe6f 100644 --- a/src/core/store/LockFactory.cpp +++ b/src/core/store/LockFactory.cpp @@ -7,19 +7,17 @@ #include "LuceneInc.h" #include "LockFactory.h" -namespace Lucene -{ - LockFactory::~LockFactory() - { - } +namespace Lucene { - void LockFactory::setLockPrefix(const String& lockPrefix) - { - this->lockPrefix = lockPrefix; - } +LockFactory::~LockFactory() { +} + +void LockFactory::setLockPrefix(const String& lockPrefix) { + this->lockPrefix = lockPrefix; +} + +String LockFactory::getLockPrefix() { + return lockPrefix; +} - String LockFactory::getLockPrefix() - { - return lockPrefix; - } } diff --git a/src/core/store/MMapDirectory.cpp b/src/core/store/MMapDirectory.cpp index b8a15812..beac7828 100644 --- a/src/core/store/MMapDirectory.cpp +++ b/src/core/store/MMapDirectory.cpp @@ -13,110 +13,90 @@ #include "FileUtils.h" #include "StringUtils.h" -namespace Lucene -{ - MMapDirectory::MMapDirectory(const String& path, const LockFactoryPtr& lockFactory) : FSDirectory(path, lockFactory) - { - } +namespace Lucene { - MMapDirectory::~MMapDirectory() - { - } +MMapDirectory::MMapDirectory(const String& path, const LockFactoryPtr& lockFactory) : FSDirectory(path, lockFactory) { +} - IndexInputPtr MMapDirectory::openInput(const String& name, int32_t bufferSize) - { - ensureOpen(); - return newLucene(FileUtils::joinPath(directory, name)); - } +MMapDirectory::~MMapDirectory() { +} - IndexOutputPtr MMapDirectory::createOutput(const String& name) - { - initOutput(name); - return newLucene(FileUtils::joinPath(directory, name)); - } +IndexInputPtr MMapDirectory::openInput(const String& name, int32_t bufferSize) { + ensureOpen(); + return newLucene(FileUtils::joinPath(directory, name)); +} - MMapIndexInput::MMapIndexInput(const String& path) - { - _length = path.empty() ? 0 : (int32_t)FileUtils::fileLength(path); - bufferPosition = 0; - if (!path.empty()) - { - try - { - file.open(boost::filesystem::wpath(path), _length); - } - catch (...) - { - boost::throw_exception(FileNotFoundException(path)); - } +IndexOutputPtr MMapDirectory::createOutput(const String& name) { + initOutput(name); + return newLucene(FileUtils::joinPath(directory, name)); +} + +MMapIndexInput::MMapIndexInput(const String& path) { + _length = path.empty() ? 0 : (int32_t)FileUtils::fileLength(path); + bufferPosition = 0; + if (!path.empty()) { + try { + file.open(boost::filesystem::wpath(path), _length); + } catch (...) { + boost::throw_exception(FileNotFoundException(path)); } - isClone = false; } + isClone = false; +} - MMapIndexInput::~MMapIndexInput() - { - } +MMapIndexInput::~MMapIndexInput() { +} - uint8_t MMapIndexInput::readByte() - { - try - { - return file.data()[bufferPosition++]; - } - catch (...) - { - boost::throw_exception(IOException(L"Read past EOF")); - return 0; - } +uint8_t MMapIndexInput::readByte() { + try { + return file.data()[bufferPosition++]; + } catch (...) { + boost::throw_exception(IOException(L"Read past EOF")); + return 0; } +} - void MMapIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) - { - try - { - MiscUtils::arrayCopy(file.data(), bufferPosition, b, offset, length); - bufferPosition += length; - } - catch (...) - { - boost::throw_exception(IOException(L"Read past EOF")); - } +void MMapIndexInput::readBytes(uint8_t* b, int32_t offset, int32_t length) { + try { + MiscUtils::arrayCopy(file.data(), bufferPosition, b, offset, length); + bufferPosition += length; + } catch (...) { + boost::throw_exception(IOException(L"Read past EOF")); } +} - int64_t MMapIndexInput::getFilePointer() - { - return bufferPosition; - } +int64_t MMapIndexInput::getFilePointer() { + return bufferPosition; +} - void MMapIndexInput::seek(int64_t pos) - { - bufferPosition = (int32_t)pos; - } +void MMapIndexInput::seek(int64_t pos) { + bufferPosition = (int32_t)pos; +} - int64_t MMapIndexInput::length() - { - return (int64_t)_length; - } +int64_t MMapIndexInput::length() { + return (int64_t)_length; +} - void MMapIndexInput::close() - { - if (isClone || !file.is_open()) - return; - _length = 0; - bufferPosition = 0; - file.close(); +void MMapIndexInput::close() { + if (isClone || !file.is_open()) { + return; } + _length = 0; + bufferPosition = 0; + file.close(); +} - LuceneObjectPtr MMapIndexInput::clone(const LuceneObjectPtr& other) - { - if (!file.is_open()) - boost::throw_exception(AlreadyClosedException(L"MMapIndexInput already closed")); - LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene()); - MMapIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); - cloneIndexInput->_length = _length; - cloneIndexInput->file = file; - cloneIndexInput->bufferPosition = bufferPosition; - cloneIndexInput->isClone = true; - return cloneIndexInput; +LuceneObjectPtr MMapIndexInput::clone(const LuceneObjectPtr& other) { + if (!file.is_open()) { + boost::throw_exception(AlreadyClosedException(L"MMapIndexInput already closed")); } + LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene()); + MMapIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); + cloneIndexInput->_length = _length; + cloneIndexInput->file = file; + cloneIndexInput->bufferPosition = bufferPosition; + cloneIndexInput->isClone = true; + return cloneIndexInput; +} + } diff --git a/src/core/store/NativeFSLockFactory.cpp b/src/core/store/NativeFSLockFactory.cpp index c3c1d0b5..3a3adbac 100644 --- a/src/core/store/NativeFSLockFactory.cpp +++ b/src/core/store/NativeFSLockFactory.cpp @@ -13,227 +13,202 @@ #include "FileUtils.h" #include "StringUtils.h" -namespace Lucene -{ - NativeFSLockFactory::NativeFSLockFactory(const String& lockDirName) - { - setLockDir(lockDirName); - } +namespace Lucene { - NativeFSLockFactory::~NativeFSLockFactory() - { - } +NativeFSLockFactory::NativeFSLockFactory(const String& lockDirName) { + setLockDir(lockDirName); +} - LockPtr NativeFSLockFactory::makeLock(const String& lockName) - { - SyncLock syncLock(this); - return newLucene(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName); - } +NativeFSLockFactory::~NativeFSLockFactory() { +} - void NativeFSLockFactory::clearLock(const String& lockName) - { - // note that this isn't strictly required anymore because the existence of these files does not mean - // they are locked, but still do this in case people really want to see the files go away +LockPtr NativeFSLockFactory::makeLock(const String& lockName) { + SyncLock syncLock(this); + return newLucene(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName); +} - if (FileUtils::isDirectory(lockDir)) - { - String lockPath(FileUtils::joinPath(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName)); - if (FileUtils::fileExists(lockPath) && !FileUtils::removeFile(lockPath)) - boost::throw_exception(IOException(L"Failed to delete: " + lockPath)); +void NativeFSLockFactory::clearLock(const String& lockName) { + // note that this isn't strictly required anymore because the existence of these files does not mean + // they are locked, but still do this in case people really want to see the files go away + + if (FileUtils::isDirectory(lockDir)) { + String lockPath(FileUtils::joinPath(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName)); + if (FileUtils::fileExists(lockPath) && !FileUtils::removeFile(lockPath)) { + boost::throw_exception(IOException(L"Failed to delete: " + lockPath)); } } +} - NativeFSLock::NativeFSLock(const String& lockDir, const String& lockFileName) - { - this->lockDir = lockDir; - path = FileUtils::joinPath(lockDir, lockFileName); - } +NativeFSLock::NativeFSLock(const String& lockDir, const String& lockFileName) { + this->lockDir = lockDir; + path = FileUtils::joinPath(lockDir, lockFileName); +} - NativeFSLock::~NativeFSLock() - { - try - { - release(); - } - catch (...) - { - } +NativeFSLock::~NativeFSLock() { + try { + release(); + } catch (...) { } +} - SynchronizePtr NativeFSLock::LOCK_HELD_LOCK() - { - static SynchronizePtr _LOCK_HELD_LOCK; - if (!_LOCK_HELD_LOCK) - _LOCK_HELD_LOCK = newInstance(); - return _LOCK_HELD_LOCK; +SynchronizePtr NativeFSLock::LOCK_HELD_LOCK() { + static SynchronizePtr _LOCK_HELD_LOCK; + if (!_LOCK_HELD_LOCK) { + _LOCK_HELD_LOCK = newInstance(); } + return _LOCK_HELD_LOCK; +} - HashSet NativeFSLock::LOCK_HELD() - { - static HashSet _LOCK_HELD; - if (!_LOCK_HELD) - _LOCK_HELD = HashSet::newInstance(); - return _LOCK_HELD; +HashSet NativeFSLock::LOCK_HELD() { + static HashSet _LOCK_HELD; + if (!_LOCK_HELD) { + _LOCK_HELD = HashSet::newInstance(); } + return _LOCK_HELD; +} - bool NativeFSLock::lockExists() - { - SyncLock syncLock(this); - return lock.get() != NULL; - } +bool NativeFSLock::lockExists() { + SyncLock syncLock(this); + return lock.get() != NULL; +} - bool NativeFSLock::obtain() - { - SyncLock syncLock(this); +bool NativeFSLock::obtain() { + SyncLock syncLock(this); - if (lockExists()) - // our instance is already locked - return false; + if (lockExists()) + // our instance is already locked + { + return false; + } - // ensure that lockdir exists and is a directory - if (!FileUtils::fileExists(lockDir)) - { - if (!FileUtils::createDirectory(lockDir)) - boost::throw_exception(IOException(L"Cannot create directory: " + lockDir)); + // ensure that lockdir exists and is a directory + if (!FileUtils::fileExists(lockDir)) { + if (!FileUtils::createDirectory(lockDir)) { + boost::throw_exception(IOException(L"Cannot create directory: " + lockDir)); } - else if (!FileUtils::isDirectory(lockDir)) - boost::throw_exception(IOException(L"Found regular file where directory expected: " + lockDir)); + } else if (!FileUtils::isDirectory(lockDir)) { + boost::throw_exception(IOException(L"Found regular file where directory expected: " + lockDir)); + } - bool markedHeld = false; + bool markedHeld = false; - // make sure nobody else in-process has this lock held already and mark it held if not + // make sure nobody else in-process has this lock held already and mark it held if not + { + SyncLock heldLock(LOCK_HELD_LOCK()); + if (LOCK_HELD().contains(path)) + // someone else already has the lock { - SyncLock heldLock(LOCK_HELD_LOCK()); - if (LOCK_HELD().contains(path)) - // someone else already has the lock - return false; - else - { - // this "reserves" the fact that we are the one thread trying to obtain this lock, so we own the - // only instance of a channel against this file - LOCK_HELD().add(path); - markedHeld = true; - } + return false; + } else { + // this "reserves" the fact that we are the one thread trying to obtain this lock, so we own the + // only instance of a channel against this file + LOCK_HELD().add(path); + markedHeld = true; } + } - try - { - // we can get intermittent "access denied" here, so we treat this as failure to acquire the lock - boost::filesystem::ofstream f(path, std::ios::binary | std::ios::out); + try { + // we can get intermittent "access denied" here, so we treat this as failure to acquire the lock + boost::filesystem::ofstream f(path, std::ios::binary | std::ios::out); - if (f.is_open()) - { - std::string lockpath; + if (f.is_open()) { + std::string lockpath; - // file_lock only accepts char* filenames and we cannot losslessly convert Unicode paths to - // char*. The usual way to work around this is to use 8.3 short names. + // file_lock only accepts char* filenames and we cannot losslessly convert Unicode paths to + // char*. The usual way to work around this is to use 8.3 short names. #if defined(_WIN32) || defined(_WIN64) - wchar_t pathOut[MAX_PATH+1]; - if (::GetShortPathNameW(path.c_str(), pathOut, MAX_PATH+1) != 0) - { - lockpath = boost::filesystem::path(pathOut).string(); - } - else + wchar_t pathOut[MAX_PATH+1]; + if (::GetShortPathNameW(path.c_str(), pathOut, MAX_PATH+1) != 0) { + lockpath = boost::filesystem::path(pathOut).string(); + } else #endif // Windows - { - lockpath = boost::filesystem::path(path).string(); - } - lock = newInstance(lockpath.c_str()); - lock->lock(); + { + lockpath = boost::filesystem::path(path).string(); } + lock = newInstance(lockpath.c_str()); + lock->lock(); } - catch (...) - { + } catch (...) { + lock.reset(); + } + + if (markedHeld && !lockExists()) { + SyncLock heldLock(LOCK_HELD_LOCK()); + LOCK_HELD().remove(path); + } + + return lockExists(); +} + +void NativeFSLock::release() { + SyncLock syncLock(this); + + if (lockExists()) { + try { + lock->unlock(); lock.reset(); + } catch (...) { } - if (markedHeld && !lockExists()) { SyncLock heldLock(LOCK_HELD_LOCK()); LOCK_HELD().remove(path); } - return lockExists(); - } - - void NativeFSLock::release() - { - SyncLock syncLock(this); - - if (lockExists()) - { - try - { - lock->unlock(); - lock.reset(); + // we don't care anymore if the file cannot be deleted because it's held up by another process + // (eg. AntiVirus). NativeFSLock does not depend on the existence/absence of the lock file + FileUtils::removeFile(path); + } else { + // if we don't hold the lock, and somebody still called release(), for example as a result of + // calling IndexWriter.unlock(), we should attempt to obtain the lock and release it. If the + // obtain fails, it means the lock cannot be released, and we should throw a proper exception + // rather than silently failing/not doing anything. + bool obtained = false; + LuceneException finally; + try { + obtained = obtain(); + if (!obtained) { + boost::throw_exception(LockReleaseFailedException(L"Cannot forcefully unlock a NativeFSLock which is held by another indexer component: " + path)); } - catch (...) - { - } - - { - SyncLock heldLock(LOCK_HELD_LOCK()); - LOCK_HELD().remove(path); - } - - // we don't care anymore if the file cannot be deleted because it's held up by another process - // (eg. AntiVirus). NativeFSLock does not depend on the existence/absence of the lock file - FileUtils::removeFile(path); + } catch (LuceneException& e) { + finally = e; } - else - { - // if we don't hold the lock, and somebody still called release(), for example as a result of - // calling IndexWriter.unlock(), we should attempt to obtain the lock and release it. If the - // obtain fails, it means the lock cannot be released, and we should throw a proper exception - // rather than silently failing/not doing anything. - bool obtained = false; - LuceneException finally; - try - { - obtained = obtain(); - if (!obtained) - boost::throw_exception(LockReleaseFailedException(L"Cannot forcefully unlock a NativeFSLock which is held by another indexer component: " + path)); - } - catch (LuceneException& e) - { - finally = e; - } - if (obtained) - release(); - finally.throwException(); + if (obtained) { + release(); } + finally.throwException(); } +} - bool NativeFSLock::isLocked() - { - SyncLock syncLock(this); +bool NativeFSLock::isLocked() { + SyncLock syncLock(this); - // the test for is islocked is not directly possible with native file locks + // the test for is islocked is not directly possible with native file locks - // first a shortcut, if a lock reference in this instance is available - if (lockExists()) - return true; + // first a shortcut, if a lock reference in this instance is available + if (lockExists()) { + return true; + } - // look if lock file is present; if not, there can definitely be no lock! - if (!FileUtils::fileExists(path)) - return false; + // look if lock file is present; if not, there can definitely be no lock! + if (!FileUtils::fileExists(path)) { + return false; + } - // try to obtain and release (if was locked) the lock - try - { - bool obtained = obtain(); - if (obtained) - release(); - return !obtained; - } - catch (LuceneException&) - { - return false; + // try to obtain and release (if was locked) the lock + try { + bool obtained = obtain(); + if (obtained) { + release(); } + return !obtained; + } catch (LuceneException&) { + return false; } +} + +String NativeFSLock::toString() { + return getClassName() + L"@" + path; +} - String NativeFSLock::toString() - { - return getClassName() + L"@" + path; - } } diff --git a/src/core/store/NoLockFactory.cpp b/src/core/store/NoLockFactory.cpp index 24bc2255..03c9b4aa 100644 --- a/src/core/store/NoLockFactory.cpp +++ b/src/core/store/NoLockFactory.cpp @@ -8,64 +8,53 @@ #include "NoLockFactory.h" #include "_NoLockFactory.h" -namespace Lucene -{ - NoLockFactory::~NoLockFactory() - { - } +namespace Lucene { - NoLockFactoryPtr NoLockFactory::getNoLockFactory() - { - static NoLockFactoryPtr singleton; - if (!singleton) - { - singleton = newLucene(); - CycleCheck::addStatic(singleton); - } - return singleton; - } +NoLockFactory::~NoLockFactory() { +} - NoLockPtr NoLockFactory::getSingletonLock() - { - // Single instance returned whenever makeLock is called. - static NoLockPtr singletonLock; - if (!singletonLock) - { - singletonLock = newLucene(); - CycleCheck::addStatic(singletonLock); - } - return singletonLock; +NoLockFactoryPtr NoLockFactory::getNoLockFactory() { + static NoLockFactoryPtr singleton; + if (!singleton) { + singleton = newLucene(); + CycleCheck::addStatic(singleton); } + return singleton; +} - LockPtr NoLockFactory::makeLock(const String& lockName) - { - return getSingletonLock(); +NoLockPtr NoLockFactory::getSingletonLock() { + // Single instance returned whenever makeLock is called. + static NoLockPtr singletonLock; + if (!singletonLock) { + singletonLock = newLucene(); + CycleCheck::addStatic(singletonLock); } + return singletonLock; +} - void NoLockFactory::clearLock(const String& lockName) - { - } +LockPtr NoLockFactory::makeLock(const String& lockName) { + return getSingletonLock(); +} - NoLock::~NoLock() - { - } +void NoLockFactory::clearLock(const String& lockName) { +} - bool NoLock::obtain() - { - return true; - } +NoLock::~NoLock() { +} - void NoLock::release() - { - } +bool NoLock::obtain() { + return true; +} - bool NoLock::isLocked() - { - return false; - } +void NoLock::release() { +} + +bool NoLock::isLocked() { + return false; +} + +String NoLock::toString() { + return getClassName(); +} - String NoLock::toString() - { - return getClassName(); - } } diff --git a/src/core/store/RAMDirectory.cpp b/src/core/store/RAMDirectory.cpp index 3973010c..dbff24bd 100644 --- a/src/core/store/RAMDirectory.cpp +++ b/src/core/store/RAMDirectory.cpp @@ -13,153 +13,146 @@ #include "LuceneThread.h" #include "MiscUtils.h" -namespace Lucene -{ - RAMDirectory::RAMDirectory() - { - this->fileMap = MapStringRAMFile::newInstance(); - this->_sizeInBytes = 0; - this->copyDirectory = false; - this->closeDir = false; - setLockFactory(newLucene()); - } +namespace Lucene { + +RAMDirectory::RAMDirectory() { + this->fileMap = MapStringRAMFile::newInstance(); + this->_sizeInBytes = 0; + this->copyDirectory = false; + this->closeDir = false; + setLockFactory(newLucene()); +} - RAMDirectory::RAMDirectory(const DirectoryPtr& dir) - { - this->fileMap = MapStringRAMFile::newInstance(); - this->_sizeInBytes = 0; - this->copyDirectory = true; - this->_dirSource = dir; - this->closeDir = false; - setLockFactory(newLucene()); - } +RAMDirectory::RAMDirectory(const DirectoryPtr& dir) { + this->fileMap = MapStringRAMFile::newInstance(); + this->_sizeInBytes = 0; + this->copyDirectory = true; + this->_dirSource = dir; + this->closeDir = false; + setLockFactory(newLucene()); +} - RAMDirectory::RAMDirectory(const DirectoryPtr& dir, bool closeDir) - { - this->fileMap = MapStringRAMFile::newInstance(); - this->_sizeInBytes = 0; - this->copyDirectory = true; - this->_dirSource = dir; - this->closeDir = closeDir; - setLockFactory(newLucene()); - } +RAMDirectory::RAMDirectory(const DirectoryPtr& dir, bool closeDir) { + this->fileMap = MapStringRAMFile::newInstance(); + this->_sizeInBytes = 0; + this->copyDirectory = true; + this->_dirSource = dir; + this->closeDir = closeDir; + setLockFactory(newLucene()); +} - RAMDirectory::~RAMDirectory() - { - } +RAMDirectory::~RAMDirectory() { +} - void RAMDirectory::initialize() - { - if (copyDirectory) - Directory::copy(DirectoryPtr(_dirSource), shared_from_this(), closeDir); +void RAMDirectory::initialize() { + if (copyDirectory) { + Directory::copy(DirectoryPtr(_dirSource), shared_from_this(), closeDir); } +} - HashSet RAMDirectory::listAll() - { - SyncLock syncLock(this); - ensureOpen(); - HashSet result(HashSet::newInstance()); - for (MapStringRAMFile::iterator fileName = fileMap.begin(); fileName != fileMap.end(); ++fileName) - result.add(fileName->first); - return result; +HashSet RAMDirectory::listAll() { + SyncLock syncLock(this); + ensureOpen(); + HashSet result(HashSet::newInstance()); + for (MapStringRAMFile::iterator fileName = fileMap.begin(); fileName != fileMap.end(); ++fileName) { + result.add(fileName->first); } + return result; +} - bool RAMDirectory::fileExists(const String& name) - { - ensureOpen(); - SyncLock syncLock(this); - return fileMap.contains(name); +bool RAMDirectory::fileExists(const String& name) { + ensureOpen(); + SyncLock syncLock(this); + return fileMap.contains(name); +} + +uint64_t RAMDirectory::fileModified(const String& name) { + ensureOpen(); + SyncLock syncLock(this); + MapStringRAMFile::iterator ramFile = fileMap.find(name); + if (ramFile == fileMap.end()) { + boost::throw_exception(FileNotFoundException(name)); } + return ramFile->second->getLastModified(); +} - uint64_t RAMDirectory::fileModified(const String& name) +void RAMDirectory::touchFile(const String& name) { + ensureOpen(); + RAMFilePtr file; { - ensureOpen(); SyncLock syncLock(this); MapStringRAMFile::iterator ramFile = fileMap.find(name); - if (ramFile == fileMap.end()) + if (ramFile == fileMap.end()) { boost::throw_exception(FileNotFoundException(name)); - return ramFile->second->getLastModified(); + } + file = ramFile->second; + } + int64_t ts1 = MiscUtils::currentTimeMillis(); + while (ts1 == MiscUtils::currentTimeMillis()) { + LuceneThread::threadSleep(1); } + file->setLastModified(MiscUtils::currentTimeMillis()); +} - void RAMDirectory::touchFile(const String& name) - { - ensureOpen(); - RAMFilePtr file; - { - SyncLock syncLock(this); - MapStringRAMFile::iterator ramFile = fileMap.find(name); - if (ramFile == fileMap.end()) - boost::throw_exception(FileNotFoundException(name)); - file = ramFile->second; - } - int64_t ts1 = MiscUtils::currentTimeMillis(); - while (ts1 == MiscUtils::currentTimeMillis()) - LuceneThread::threadSleep(1); - file->setLastModified(MiscUtils::currentTimeMillis()); +int64_t RAMDirectory::fileLength(const String& name) { + ensureOpen(); + SyncLock syncLock(this); + MapStringRAMFile::iterator ramFile = fileMap.find(name); + if (ramFile == fileMap.end()) { + boost::throw_exception(FileNotFoundException(name)); } + return ramFile->second->getLength(); +} - int64_t RAMDirectory::fileLength(const String& name) - { - ensureOpen(); - SyncLock syncLock(this); - MapStringRAMFile::iterator ramFile = fileMap.find(name); - if (ramFile == fileMap.end()) - boost::throw_exception(FileNotFoundException(name)); - return ramFile->second->getLength(); +int64_t RAMDirectory::sizeInBytes() { + SyncLock syncLock(this); + ensureOpen(); + return _sizeInBytes; +} + +void RAMDirectory::deleteFile(const String& name) { + SyncLock syncLock(this); + ensureOpen(); + MapStringRAMFile::iterator ramFile = fileMap.find(name); + if (ramFile == fileMap.end()) { + boost::throw_exception(FileNotFoundException(name)); } + _sizeInBytes -= ramFile->second->getSizeInBytes(); + fileMap.remove(name); +} - int64_t RAMDirectory::sizeInBytes() +IndexOutputPtr RAMDirectory::createOutput(const String& name) { + ensureOpen(); + RAMFilePtr file(newLucene(shared_from_this())); { SyncLock syncLock(this); - ensureOpen(); - return _sizeInBytes; + MapStringRAMFile::iterator existing = fileMap.find(name); + if (existing != fileMap.end()) { + _sizeInBytes -= existing->second->getSizeInBytes(); + existing->second->_directory.reset(); + } + fileMap.put(name, file); } + return newLucene(file); +} - void RAMDirectory::deleteFile(const String& name) +IndexInputPtr RAMDirectory::openInput(const String& name) { + ensureOpen(); + RAMFilePtr file; { SyncLock syncLock(this); - ensureOpen(); MapStringRAMFile::iterator ramFile = fileMap.find(name); - if (ramFile == fileMap.end()) + if (ramFile == fileMap.end()) { boost::throw_exception(FileNotFoundException(name)); - _sizeInBytes -= ramFile->second->getSizeInBytes(); - fileMap.remove(name); - } - - IndexOutputPtr RAMDirectory::createOutput(const String& name) - { - ensureOpen(); - RAMFilePtr file(newLucene(shared_from_this())); - { - SyncLock syncLock(this); - MapStringRAMFile::iterator existing = fileMap.find(name); - if (existing != fileMap.end()) - { - _sizeInBytes -= existing->second->getSizeInBytes(); - existing->second->_directory.reset(); - } - fileMap.put(name, file); } - return newLucene(file); + file = ramFile->second; } + return newLucene(file); +} - IndexInputPtr RAMDirectory::openInput(const String& name) - { - ensureOpen(); - RAMFilePtr file; - { - SyncLock syncLock(this); - MapStringRAMFile::iterator ramFile = fileMap.find(name); - if (ramFile == fileMap.end()) - boost::throw_exception(FileNotFoundException(name)); - file = ramFile->second; - } - return newLucene(file); - } +void RAMDirectory::close() { + isOpen = false; + fileMap.reset(); +} - void RAMDirectory::close() - { - isOpen = false; - fileMap.reset(); - } } diff --git a/src/core/store/RAMFile.cpp b/src/core/store/RAMFile.cpp index 54c599f6..01f9724c 100644 --- a/src/core/store/RAMFile.cpp +++ b/src/core/store/RAMFile.cpp @@ -9,91 +9,79 @@ #include "RAMDirectory.h" #include "MiscUtils.h" -namespace Lucene -{ - RAMFile::RAMFile() - { - this->buffers = Collection::newInstance(); - this->length = 0; - this->sizeInBytes = 0; - this->lastModified = MiscUtils::currentTimeMillis(); - } +namespace Lucene { - RAMFile::RAMFile(const RAMDirectoryPtr& directory) - { - this->buffers = Collection::newInstance(); - this->length = 0; - this->sizeInBytes = 0; - this->_directory = directory; - this->lastModified = MiscUtils::currentTimeMillis(); - } +RAMFile::RAMFile() { + this->buffers = Collection::newInstance(); + this->length = 0; + this->sizeInBytes = 0; + this->lastModified = MiscUtils::currentTimeMillis(); +} - RAMFile::~RAMFile() - { - } +RAMFile::RAMFile(const RAMDirectoryPtr& directory) { + this->buffers = Collection::newInstance(); + this->length = 0; + this->sizeInBytes = 0; + this->_directory = directory; + this->lastModified = MiscUtils::currentTimeMillis(); +} - int64_t RAMFile::getLength() - { - SyncLock syncLock(this); - return length; - } +RAMFile::~RAMFile() { +} - void RAMFile::setLength(int64_t length) - { - SyncLock syncLock(this); - this->length = length; - } +int64_t RAMFile::getLength() { + SyncLock syncLock(this); + return length; +} - int64_t RAMFile::getLastModified() - { - SyncLock syncLock(this); - return lastModified; - } +void RAMFile::setLength(int64_t length) { + SyncLock syncLock(this); + this->length = length; +} - void RAMFile::setLastModified(int64_t lastModified) - { - SyncLock syncLock(this); - this->lastModified = lastModified; - } +int64_t RAMFile::getLastModified() { + SyncLock syncLock(this); + return lastModified; +} - ByteArray RAMFile::addBuffer(int32_t size) - { - ByteArray buffer(newBuffer(size)); - { - SyncLock syncLock(this); - buffers.add(buffer); - sizeInBytes += size; - } - - RAMDirectoryPtr directory(_directory.lock()); - if (directory) - { - SyncLock dirLock(directory); - directory->_sizeInBytes += size; - } - return buffer; - } +void RAMFile::setLastModified(int64_t lastModified) { + SyncLock syncLock(this); + this->lastModified = lastModified; +} - ByteArray RAMFile::getBuffer(int32_t index) +ByteArray RAMFile::addBuffer(int32_t size) { + ByteArray buffer(newBuffer(size)); { SyncLock syncLock(this); - return buffers[index]; + buffers.add(buffer); + sizeInBytes += size; } - int32_t RAMFile::numBuffers() - { - SyncLock syncLock(this); - return buffers.size(); + RAMDirectoryPtr directory(_directory.lock()); + if (directory) { + SyncLock dirLock(directory); + directory->_sizeInBytes += size; } + return buffer; +} - ByteArray RAMFile::newBuffer(int32_t size) - { - return ByteArray::newInstance(size); - } +ByteArray RAMFile::getBuffer(int32_t index) { + SyncLock syncLock(this); + return buffers[index]; +} + +int32_t RAMFile::numBuffers() { + SyncLock syncLock(this); + return buffers.size(); +} + +ByteArray RAMFile::newBuffer(int32_t size) { + return ByteArray::newInstance(size); +} + +int64_t RAMFile::getSizeInBytes() { + SyncLock syncLock(this); + return sizeInBytes; +} - int64_t RAMFile::getSizeInBytes() - { - SyncLock syncLock(this); - return sizeInBytes; - } } diff --git a/src/core/store/RAMInputStream.cpp b/src/core/store/RAMInputStream.cpp index 7514bc62..0cf173e4 100644 --- a/src/core/store/RAMInputStream.cpp +++ b/src/core/store/RAMInputStream.cpp @@ -11,128 +11,111 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t RAMInputStream::BUFFER_SIZE = RAMOutputStream::BUFFER_SIZE; +namespace Lucene { - RAMInputStream::RAMInputStream() - { - _length = 0; +const int32_t RAMInputStream::BUFFER_SIZE = RAMOutputStream::BUFFER_SIZE; - // make sure that we switch to the first needed buffer lazily - currentBufferIndex = -1; - bufferPosition = 0; - bufferStart = 0; - bufferLength = 0; - } +RAMInputStream::RAMInputStream() { + _length = 0; - RAMInputStream::RAMInputStream(const RAMFilePtr& f) - { - file = f; - _length = file->length; - if (_length / BUFFER_SIZE >= INT_MAX) - boost::throw_exception(IOException(L"Too large RAMFile: " + StringUtils::toString(_length))); + // make sure that we switch to the first needed buffer lazily + currentBufferIndex = -1; + bufferPosition = 0; + bufferStart = 0; + bufferLength = 0; +} - // make sure that we switch to the first needed buffer lazily - currentBufferIndex = -1; - bufferPosition = 0; - bufferStart = 0; - bufferLength = 0; +RAMInputStream::RAMInputStream(const RAMFilePtr& f) { + file = f; + _length = file->length; + if (_length / BUFFER_SIZE >= INT_MAX) { + boost::throw_exception(IOException(L"Too large RAMFile: " + StringUtils::toString(_length))); } - RAMInputStream::~RAMInputStream() - { - } + // make sure that we switch to the first needed buffer lazily + currentBufferIndex = -1; + bufferPosition = 0; + bufferStart = 0; + bufferLength = 0; +} - void RAMInputStream::close() - { - // nothing to do here - } +RAMInputStream::~RAMInputStream() { +} + +void RAMInputStream::close() { + // nothing to do here +} - int64_t RAMInputStream::length() - { - return _length; +int64_t RAMInputStream::length() { + return _length; +} + +uint8_t RAMInputStream::readByte() { + if (bufferPosition >= bufferLength) { + ++currentBufferIndex; + switchCurrentBuffer(true); } + return currentBuffer[bufferPosition++]; +} - uint8_t RAMInputStream::readByte() - { - if (bufferPosition >= bufferLength) - { +void RAMInputStream::readBytes(uint8_t* b, int32_t offset, int32_t length) { + while (length > 0) { + if (bufferPosition >= bufferLength) { ++currentBufferIndex; switchCurrentBuffer(true); } - return currentBuffer[bufferPosition++]; - } - void RAMInputStream::readBytes(uint8_t* b, int32_t offset, int32_t length) - { - while (length > 0) - { - if (bufferPosition >= bufferLength) - { - ++currentBufferIndex; - switchCurrentBuffer(true); - } - - int32_t remainInBuffer = bufferLength - bufferPosition; - int32_t bytesToCopy = length < remainInBuffer ? length : remainInBuffer; - MiscUtils::arrayCopy(currentBuffer.get(), bufferPosition, b, offset, bytesToCopy); - offset += bytesToCopy; - length -= bytesToCopy; - bufferPosition += bytesToCopy; - } + int32_t remainInBuffer = bufferLength - bufferPosition; + int32_t bytesToCopy = length < remainInBuffer ? length : remainInBuffer; + MiscUtils::arrayCopy(currentBuffer.get(), bufferPosition, b, offset, bytesToCopy); + offset += bytesToCopy; + length -= bytesToCopy; + bufferPosition += bytesToCopy; } +} - void RAMInputStream::switchCurrentBuffer(bool enforceEOF) - { - if (currentBufferIndex >= file->numBuffers()) - { - // end of file reached, no more buffers left - if (enforceEOF) - boost::throw_exception(IOException(L"Read past EOF")); - else - { - // force eof if a read takes place at this position - --currentBufferIndex; - bufferPosition = BUFFER_SIZE; - } - } - else - { - currentBuffer = file->getBuffer(currentBufferIndex); - bufferPosition = 0; - bufferStart = (int64_t)BUFFER_SIZE * (int64_t)currentBufferIndex; - int64_t buflen = _length - bufferStart; - bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int32_t)buflen; +void RAMInputStream::switchCurrentBuffer(bool enforceEOF) { + if (currentBufferIndex >= file->numBuffers()) { + // end of file reached, no more buffers left + if (enforceEOF) { + boost::throw_exception(IOException(L"Read past EOF")); + } else { + // force eof if a read takes place at this position + --currentBufferIndex; + bufferPosition = BUFFER_SIZE; } + } else { + currentBuffer = file->getBuffer(currentBufferIndex); + bufferPosition = 0; + bufferStart = (int64_t)BUFFER_SIZE * (int64_t)currentBufferIndex; + int64_t buflen = _length - bufferStart; + bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int32_t)buflen; } +} - int64_t RAMInputStream::getFilePointer() - { - return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; - } +int64_t RAMInputStream::getFilePointer() { + return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; +} - void RAMInputStream::seek(int64_t pos) - { - if (!currentBuffer || (int32_t)pos < bufferStart || (int32_t)pos >= bufferStart + BUFFER_SIZE) - { - currentBufferIndex = (int32_t)(pos / BUFFER_SIZE); - switchCurrentBuffer(false); - } - bufferPosition = (int32_t)(pos % BUFFER_SIZE); +void RAMInputStream::seek(int64_t pos) { + if (!currentBuffer || (int32_t)pos < bufferStart || (int32_t)pos >= bufferStart + BUFFER_SIZE) { + currentBufferIndex = (int32_t)(pos / BUFFER_SIZE); + switchCurrentBuffer(false); } + bufferPosition = (int32_t)(pos % BUFFER_SIZE); +} + +LuceneObjectPtr RAMInputStream::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene()); + RAMInputStreamPtr cloneInputStream(boost::dynamic_pointer_cast(clone)); + cloneInputStream->file = file; + cloneInputStream->_length = _length; + cloneInputStream->currentBuffer = currentBuffer; + cloneInputStream->currentBufferIndex = currentBufferIndex; + cloneInputStream->bufferPosition = bufferPosition; + cloneInputStream->bufferStart = bufferStart; + cloneInputStream->bufferLength = bufferLength; + return cloneInputStream; +} - LuceneObjectPtr RAMInputStream::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = IndexInput::clone(other ? other : newLucene()); - RAMInputStreamPtr cloneInputStream(boost::dynamic_pointer_cast(clone)); - cloneInputStream->file = file; - cloneInputStream->_length = _length; - cloneInputStream->currentBuffer = currentBuffer; - cloneInputStream->currentBufferIndex = currentBufferIndex; - cloneInputStream->bufferPosition = bufferPosition; - cloneInputStream->bufferStart = bufferStart; - cloneInputStream->bufferLength = bufferLength; - return cloneInputStream; - } } diff --git a/src/core/store/RAMOutputStream.cpp b/src/core/store/RAMOutputStream.cpp index 5bca4a23..da52588b 100644 --- a/src/core/store/RAMOutputStream.cpp +++ b/src/core/store/RAMOutputStream.cpp @@ -10,146 +10,130 @@ #include "RAMDirectory.h" #include "MiscUtils.h" -namespace Lucene -{ - const int32_t RAMOutputStream::BUFFER_SIZE = 1024; - - RAMOutputStream::RAMOutputStream() - { - file = newLucene(RAMDirectoryPtr()); - - // make sure that we switch to the first needed buffer lazily - currentBufferIndex = -1; - bufferPosition = 0; - bufferStart = 0; - bufferLength = 0; - } +namespace Lucene { - RAMOutputStream::RAMOutputStream(const RAMFilePtr& f) - { - file = f; +const int32_t RAMOutputStream::BUFFER_SIZE = 1024; - // make sure that we switch to the first needed buffer lazily - currentBufferIndex = -1; - bufferPosition = 0; - bufferStart = 0; - bufferLength = 0; - } +RAMOutputStream::RAMOutputStream() { + file = newLucene(RAMDirectoryPtr()); - RAMOutputStream::~RAMOutputStream() - { - } + // make sure that we switch to the first needed buffer lazily + currentBufferIndex = -1; + bufferPosition = 0; + bufferStart = 0; + bufferLength = 0; +} + +RAMOutputStream::RAMOutputStream(const RAMFilePtr& f) { + file = f; + + // make sure that we switch to the first needed buffer lazily + currentBufferIndex = -1; + bufferPosition = 0; + bufferStart = 0; + bufferLength = 0; +} + +RAMOutputStream::~RAMOutputStream() { +} - void RAMOutputStream::writeTo(const IndexOutputPtr& out) - { - flush(); - int64_t end = file->length; - int64_t pos = 0; - int32_t buffer = 0; - while (pos < end) - { - int32_t length = BUFFER_SIZE; - int64_t nextPos = pos + length; - if (nextPos > end) // at the last buffer - length = (int32_t)(end - pos); - out->writeBytes(file->getBuffer(buffer++).get(), length); - pos = nextPos; +void RAMOutputStream::writeTo(const IndexOutputPtr& out) { + flush(); + int64_t end = file->length; + int64_t pos = 0; + int32_t buffer = 0; + while (pos < end) { + int32_t length = BUFFER_SIZE; + int64_t nextPos = pos + length; + if (nextPos > end) { // at the last buffer + length = (int32_t)(end - pos); } + out->writeBytes(file->getBuffer(buffer++).get(), length); + pos = nextPos; } +} - void RAMOutputStream::reset() - { - currentBuffer.reset(); - currentBufferIndex = -1; - bufferPosition = 0; - bufferStart = 0; - bufferLength = 0; - file->setLength(0); - } +void RAMOutputStream::reset() { + currentBuffer.reset(); + currentBufferIndex = -1; + bufferPosition = 0; + bufferStart = 0; + bufferLength = 0; + file->setLength(0); +} - void RAMOutputStream::close() - { - flush(); - } +void RAMOutputStream::close() { + flush(); +} - void RAMOutputStream::seek(int64_t pos) - { - // set the file length in case we seek back and flush() has not been called yet - setFileLength(); - if ((int64_t)pos < bufferStart || (int64_t)pos >= bufferStart + bufferLength) - { - currentBufferIndex = (int32_t)(pos / BUFFER_SIZE); - switchCurrentBuffer(); - } - bufferPosition = (int32_t)(pos % BUFFER_SIZE); +void RAMOutputStream::seek(int64_t pos) { + // set the file length in case we seek back and flush() has not been called yet + setFileLength(); + if ((int64_t)pos < bufferStart || (int64_t)pos >= bufferStart + bufferLength) { + currentBufferIndex = (int32_t)(pos / BUFFER_SIZE); + switchCurrentBuffer(); } + bufferPosition = (int32_t)(pos % BUFFER_SIZE); +} + +int64_t RAMOutputStream::length() { + return file->length; +} - int64_t RAMOutputStream::length() - { - return file->length; +void RAMOutputStream::writeByte(uint8_t b) { + if (bufferPosition == bufferLength) { + ++currentBufferIndex; + switchCurrentBuffer(); } + currentBuffer[bufferPosition++] = b; +} - void RAMOutputStream::writeByte(uint8_t b) - { - if (bufferPosition == bufferLength) - { +void RAMOutputStream::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { + while (length > 0) { + BOOST_ASSERT(b != NULL); + if (bufferPosition == bufferLength) { ++currentBufferIndex; switchCurrentBuffer(); } - currentBuffer[bufferPosition++] = b; - } - void RAMOutputStream::writeBytes(const uint8_t* b, int32_t offset, int32_t length) - { - while (length > 0) - { - BOOST_ASSERT(b != NULL); - if (bufferPosition == bufferLength) - { - ++currentBufferIndex; - switchCurrentBuffer(); - } - - int32_t remainInBuffer = currentBuffer.size() - bufferPosition; - int32_t bytesToCopy = length < remainInBuffer ? length : remainInBuffer; - MiscUtils::arrayCopy(b, offset, currentBuffer.get(), bufferPosition, bytesToCopy); - offset += bytesToCopy; - length -= bytesToCopy; - bufferPosition += bytesToCopy; - } + int32_t remainInBuffer = currentBuffer.size() - bufferPosition; + int32_t bytesToCopy = length < remainInBuffer ? length : remainInBuffer; + MiscUtils::arrayCopy(b, offset, currentBuffer.get(), bufferPosition, bytesToCopy); + offset += bytesToCopy; + length -= bytesToCopy; + bufferPosition += bytesToCopy; } +} - void RAMOutputStream::switchCurrentBuffer() - { - if (currentBufferIndex == file->numBuffers()) - currentBuffer = file->addBuffer(BUFFER_SIZE); - else - currentBuffer = file->getBuffer(currentBufferIndex); - bufferPosition = 0; - bufferStart = (int64_t)BUFFER_SIZE * (int64_t)currentBufferIndex; - bufferLength = currentBuffer.size(); +void RAMOutputStream::switchCurrentBuffer() { + if (currentBufferIndex == file->numBuffers()) { + currentBuffer = file->addBuffer(BUFFER_SIZE); + } else { + currentBuffer = file->getBuffer(currentBufferIndex); } + bufferPosition = 0; + bufferStart = (int64_t)BUFFER_SIZE * (int64_t)currentBufferIndex; + bufferLength = currentBuffer.size(); +} - void RAMOutputStream::setFileLength() - { - int64_t pointer = bufferStart + bufferPosition; - if (pointer > file->length) - file->setLength(pointer); +void RAMOutputStream::setFileLength() { + int64_t pointer = bufferStart + bufferPosition; + if (pointer > file->length) { + file->setLength(pointer); } +} - void RAMOutputStream::flush() - { - file->setLastModified(MiscUtils::currentTimeMillis()); - setFileLength(); - } +void RAMOutputStream::flush() { + file->setLastModified(MiscUtils::currentTimeMillis()); + setFileLength(); +} - int64_t RAMOutputStream::getFilePointer() - { - return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; - } +int64_t RAMOutputStream::getFilePointer() { + return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; +} + +int64_t RAMOutputStream::sizeInBytes() { + return file->numBuffers() * BUFFER_SIZE; +} - int64_t RAMOutputStream::sizeInBytes() - { - return file->numBuffers() * BUFFER_SIZE; - } } diff --git a/src/core/store/SimpleFSDirectory.cpp b/src/core/store/SimpleFSDirectory.cpp index b975a306..88d39498 100644 --- a/src/core/store/SimpleFSDirectory.cpp +++ b/src/core/store/SimpleFSDirectory.cpp @@ -13,262 +13,227 @@ #include "FileUtils.h" #include "StringUtils.h" -namespace Lucene -{ - SimpleFSDirectory::SimpleFSDirectory(const String& path, const LockFactoryPtr& lockFactory) : FSDirectory(path, lockFactory) - { - } +namespace Lucene { - SimpleFSDirectory::~SimpleFSDirectory() - { - } +SimpleFSDirectory::SimpleFSDirectory(const String& path, const LockFactoryPtr& lockFactory) : FSDirectory(path, lockFactory) { +} - IndexOutputPtr SimpleFSDirectory::createOutput(const String& name) - { - initOutput(name); - return newLucene(FileUtils::joinPath(directory, name)); - } +SimpleFSDirectory::~SimpleFSDirectory() { +} - IndexInputPtr SimpleFSDirectory::openInput(const String& name) - { - return FSDirectory::openInput(name); - } +IndexOutputPtr SimpleFSDirectory::createOutput(const String& name) { + initOutput(name); + return newLucene(FileUtils::joinPath(directory, name)); +} - IndexInputPtr SimpleFSDirectory::openInput(const String& name, int32_t bufferSize) - { - ensureOpen(); - return newLucene(FileUtils::joinPath(directory, name), bufferSize, getReadChunkSize()); - } +IndexInputPtr SimpleFSDirectory::openInput(const String& name) { + return FSDirectory::openInput(name); +} + +IndexInputPtr SimpleFSDirectory::openInput(const String& name, int32_t bufferSize) { + ensureOpen(); + return newLucene(FileUtils::joinPath(directory, name), bufferSize, getReadChunkSize()); +} - const int32_t InputFile::FILE_EOF = FileReader::FILE_EOF; - const int32_t InputFile::FILE_ERROR = FileReader::FILE_ERROR; +const int32_t InputFile::FILE_EOF = FileReader::FILE_EOF; +const int32_t InputFile::FILE_ERROR = FileReader::FILE_ERROR; - InputFile::InputFile(const String& path) - { - file = newInstance(path, std::ios::binary | std::ios::in); - if (!file->is_open()) - boost::throw_exception(FileNotFoundException(path)); - position = 0; - length = FileUtils::fileLength(path); +InputFile::InputFile(const String& path) { + file = newInstance(path, std::ios::binary | std::ios::in); + if (!file->is_open()) { + boost::throw_exception(FileNotFoundException(path)); } + position = 0; + length = FileUtils::fileLength(path); +} - InputFile::~InputFile() - { - } +InputFile::~InputFile() { +} - void InputFile::setPosition(int64_t position) - { - this->position = position; - file->seekg((std::streamoff)position); - if (!file->good()) - boost::throw_exception(IOException()); +void InputFile::setPosition(int64_t position) { + this->position = position; + file->seekg((std::streamoff)position); + if (!file->good()) { + boost::throw_exception(IOException()); } +} - int64_t InputFile::getPosition() - { - return position; - } +int64_t InputFile::getPosition() { + return position; +} - int64_t InputFile::getLength() - { - return length; - } +int64_t InputFile::getLength() { + return length; +} - int32_t InputFile::read(uint8_t* b, int32_t offset, int32_t length) - { - try - { - if (file->eof()) - return FILE_EOF; - file->read((char*)b + offset, length); - int32_t readCount = file->gcount(); - position += readCount; - return readCount; - } - catch (...) - { - return FILE_ERROR; +int32_t InputFile::read(uint8_t* b, int32_t offset, int32_t length) { + try { + if (file->eof()) { + return FILE_EOF; } + file->read((char*)b + offset, length); + int32_t readCount = file->gcount(); + position += readCount; + return readCount; + } catch (...) { + return FILE_ERROR; } +} - void InputFile::close() - { - if (file->is_open()) - file->close(); +void InputFile::close() { + if (file->is_open()) { + file->close(); } +} - bool InputFile::isValid() - { - return (file && file->is_open() && file->good()); - } +bool InputFile::isValid() { + return (file && file->is_open() && file->good()); +} - SimpleFSIndexInput::SimpleFSIndexInput() - { - this->chunkSize = 0; - this->isClone = false; - } +SimpleFSIndexInput::SimpleFSIndexInput() { + this->chunkSize = 0; + this->isClone = false; +} - SimpleFSIndexInput::SimpleFSIndexInput(const String& path, int32_t bufferSize, int32_t chunkSize) : BufferedIndexInput(bufferSize) - { - this->file = newLucene(path); - this->path = path; - this->chunkSize = chunkSize; - this->isClone = false; - } +SimpleFSIndexInput::SimpleFSIndexInput(const String& path, int32_t bufferSize, int32_t chunkSize) : BufferedIndexInput(bufferSize) { + this->file = newLucene(path); + this->path = path; + this->chunkSize = chunkSize; + this->isClone = false; +} - SimpleFSIndexInput::~SimpleFSIndexInput() - { - } +SimpleFSIndexInput::~SimpleFSIndexInput() { +} - void SimpleFSIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) - { - SyncLock fileLock(file); +void SimpleFSIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) { + SyncLock fileLock(file); - int64_t position = getFilePointer(); - if (position != file->getPosition()) - file->setPosition(position); + int64_t position = getFilePointer(); + if (position != file->getPosition()) { + file->setPosition(position); + } - int32_t total = 0; + int32_t total = 0; - while (total < length) - { - int32_t readLength = total + chunkSize > length ? length - total : chunkSize; + while (total < length) { + int32_t readLength = total + chunkSize > length ? length - total : chunkSize; - int32_t i = file->read(b, offset + total, readLength); - if (i == InputFile::FILE_EOF) - boost::throw_exception(IOException(L"Read past EOF")); - total += i; + int32_t i = file->read(b, offset + total, readLength); + if (i == InputFile::FILE_EOF) { + boost::throw_exception(IOException(L"Read past EOF")); } + total += i; } +} - void SimpleFSIndexInput::seekInternal(int64_t pos) - { - } +void SimpleFSIndexInput::seekInternal(int64_t pos) { +} - int64_t SimpleFSIndexInput::length() - { - return file->getLength(); - } +int64_t SimpleFSIndexInput::length() { + return file->getLength(); +} - void SimpleFSIndexInput::close() - { - if (!isClone) - file->close(); +void SimpleFSIndexInput::close() { + if (!isClone) { + file->close(); } +} - bool SimpleFSIndexInput::isValid() - { - return file->isValid(); - } +bool SimpleFSIndexInput::isValid() { + return file->isValid(); +} - LuceneObjectPtr SimpleFSIndexInput::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = BufferedIndexInput::clone(other ? other : newLucene()); - SimpleFSIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); - cloneIndexInput->path = path; - cloneIndexInput->file = file; - cloneIndexInput->chunkSize = chunkSize; - cloneIndexInput->isClone = true; - return cloneIndexInput; - } +LuceneObjectPtr SimpleFSIndexInput::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = BufferedIndexInput::clone(other ? other : newLucene()); + SimpleFSIndexInputPtr cloneIndexInput(boost::dynamic_pointer_cast(clone)); + cloneIndexInput->path = path; + cloneIndexInput->file = file; + cloneIndexInput->chunkSize = chunkSize; + cloneIndexInput->isClone = true; + return cloneIndexInput; +} - OutputFile::OutputFile(const String& path) - { - this->path = path; - file = newInstance(path, std::ios::binary | std::ios::out); - } +OutputFile::OutputFile(const String& path) { + this->path = path; + file = newInstance(path, std::ios::binary | std::ios::out); +} - OutputFile::~OutputFile() - { - } +OutputFile::~OutputFile() { +} - bool OutputFile::write(const uint8_t* b, int32_t offset, int32_t length) - { - if (!file->is_open()) - return false; - try - { - file->write((char*)b + offset, length); - return file->good(); - } - catch (...) - { - return false; - } +bool OutputFile::write(const uint8_t* b, int32_t offset, int32_t length) { + if (!file->is_open()) { + return false; } - - void OutputFile::close() - { - file.reset(); + try { + file->write((char*)b + offset, length); + return file->good(); + } catch (...) { + return false; } +} - void OutputFile::setPosition(int64_t position) - { - file->seekp((std::streamoff)position); - if (!file->good()) - boost::throw_exception(IOException()); - } +void OutputFile::close() { + file.reset(); +} - int64_t OutputFile::getLength() - { - return FileUtils::fileLength(path); +void OutputFile::setPosition(int64_t position) { + file->seekp((std::streamoff)position); + if (!file->good()) { + boost::throw_exception(IOException()); } +} - void OutputFile::setLength(int64_t length) - { - FileUtils::setFileLength(path, length); - } +int64_t OutputFile::getLength() { + return FileUtils::fileLength(path); +} - void OutputFile::flush() - { - if (file->is_open()) - file->flush(); - } +void OutputFile::setLength(int64_t length) { + FileUtils::setFileLength(path, length); +} - bool OutputFile::isValid() - { - return (file && file->is_open() && file->good()); +void OutputFile::flush() { + if (file->is_open()) { + file->flush(); } +} - SimpleFSIndexOutput::SimpleFSIndexOutput(const String& path) - { - file = newLucene(path); - isOpen = true; - } +bool OutputFile::isValid() { + return (file && file->is_open() && file->good()); +} - SimpleFSIndexOutput::~SimpleFSIndexOutput() - { - } +SimpleFSIndexOutput::SimpleFSIndexOutput(const String& path) { + file = newLucene(path); + isOpen = true; +} - void SimpleFSIndexOutput::flushBuffer(const uint8_t* b, int32_t offset, int32_t length) - { - file->write(b, offset, length); - file->flush(); - } +SimpleFSIndexOutput::~SimpleFSIndexOutput() { +} - void SimpleFSIndexOutput::close() - { - if (isOpen) - { - BufferedIndexOutput::close(); - file.reset(); - isOpen = false; - } - } +void SimpleFSIndexOutput::flushBuffer(const uint8_t* b, int32_t offset, int32_t length) { + file->write(b, offset, length); + file->flush(); +} - void SimpleFSIndexOutput::seek(int64_t pos) - { - BufferedIndexOutput::seek(pos); - file->setPosition(pos); +void SimpleFSIndexOutput::close() { + if (isOpen) { + BufferedIndexOutput::close(); + file.reset(); + isOpen = false; } +} - int64_t SimpleFSIndexOutput::length() - { - return file->getLength(); - } +void SimpleFSIndexOutput::seek(int64_t pos) { + BufferedIndexOutput::seek(pos); + file->setPosition(pos); +} + +int64_t SimpleFSIndexOutput::length() { + return file->getLength(); +} + +void SimpleFSIndexOutput::setLength(int64_t length) { + file->setLength(length); +} - void SimpleFSIndexOutput::setLength(int64_t length) - { - file->setLength(length); - } } diff --git a/src/core/store/SimpleFSLockFactory.cpp b/src/core/store/SimpleFSLockFactory.cpp index 8060a91d..76a75a42 100644 --- a/src/core/store/SimpleFSLockFactory.cpp +++ b/src/core/store/SimpleFSLockFactory.cpp @@ -11,81 +11,69 @@ #include "FileUtils.h" #include "StringUtils.h" -namespace Lucene -{ - SimpleFSLockFactory::SimpleFSLockFactory() - { - } +namespace Lucene { - SimpleFSLockFactory::SimpleFSLockFactory(const String& lockDir) - { - setLockDir(lockDir); - } +SimpleFSLockFactory::SimpleFSLockFactory() { +} - SimpleFSLockFactory::~SimpleFSLockFactory() - { - } +SimpleFSLockFactory::SimpleFSLockFactory(const String& lockDir) { + setLockDir(lockDir); +} - LockPtr SimpleFSLockFactory::makeLock(const String& lockName) - { - return newLucene(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName); - } +SimpleFSLockFactory::~SimpleFSLockFactory() { +} + +LockPtr SimpleFSLockFactory::makeLock(const String& lockName) { + return newLucene(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName); +} - void SimpleFSLockFactory::clearLock(const String& lockName) - { - if (FileUtils::isDirectory(lockDir)) - { - String lockPath(FileUtils::joinPath(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName)); - if (FileUtils::fileExists(lockPath) && !FileUtils::removeFile(lockPath)) - boost::throw_exception(IOException(L"Cannot delete " + lockPath)); +void SimpleFSLockFactory::clearLock(const String& lockName) { + if (FileUtils::isDirectory(lockDir)) { + String lockPath(FileUtils::joinPath(lockDir, lockPrefix.empty() ? lockName : lockPrefix + L"-" + lockName)); + if (FileUtils::fileExists(lockPath) && !FileUtils::removeFile(lockPath)) { + boost::throw_exception(IOException(L"Cannot delete " + lockPath)); } } +} - SimpleFSLock::SimpleFSLock(const String& lockDir, const String& lockFileName) - { - this->lockDir = lockDir; - this->lockFile = lockFile; - } +SimpleFSLock::SimpleFSLock(const String& lockDir, const String& lockFileName) { + this->lockDir = lockDir; + this->lockFile = lockFile; +} - SimpleFSLock::~SimpleFSLock() - { - } +SimpleFSLock::~SimpleFSLock() { +} - bool SimpleFSLock::obtain() - { - // Ensure that lockDir exists and is a directory - if (!FileUtils::fileExists(lockDir)) - { - if (!FileUtils::createDirectory(lockDir)) - boost::throw_exception(RuntimeException(L"Cannot create directory: " + lockDir)); - } - else if (!FileUtils::isDirectory(lockDir)) - boost::throw_exception(RuntimeException(L"Found regular file where directory expected: " + lockDir)); - boost::filesystem::ofstream f; - try - { - f.open(FileUtils::joinPath(lockDir, lockFile), std::ios::binary | std::ios::out); +bool SimpleFSLock::obtain() { + // Ensure that lockDir exists and is a directory + if (!FileUtils::fileExists(lockDir)) { + if (!FileUtils::createDirectory(lockDir)) { + boost::throw_exception(RuntimeException(L"Cannot create directory: " + lockDir)); } - catch (...) - { - } - return f.is_open(); + } else if (!FileUtils::isDirectory(lockDir)) { + boost::throw_exception(RuntimeException(L"Found regular file where directory expected: " + lockDir)); } - - void SimpleFSLock::release() - { - String path(FileUtils::joinPath(lockDir, lockFile)); - if (FileUtils::fileExists(path) && !FileUtils::removeFile(path)) - boost::throw_exception(LockReleaseFailedException(L"failed to delete " + path)); + boost::filesystem::ofstream f; + try { + f.open(FileUtils::joinPath(lockDir, lockFile), std::ios::binary | std::ios::out); + } catch (...) { } + return f.is_open(); +} - bool SimpleFSLock::isLocked() - { - return FileUtils::fileExists(FileUtils::joinPath(lockDir, lockFile)); +void SimpleFSLock::release() { + String path(FileUtils::joinPath(lockDir, lockFile)); + if (FileUtils::fileExists(path) && !FileUtils::removeFile(path)) { + boost::throw_exception(LockReleaseFailedException(L"failed to delete " + path)); } +} + +bool SimpleFSLock::isLocked() { + return FileUtils::fileExists(FileUtils::joinPath(lockDir, lockFile)); +} + +String SimpleFSLock::toString() { + return getClassName() + L"@" + FileUtils::joinPath(lockDir, lockFile); +} - String SimpleFSLock::toString() - { - return getClassName() + L"@" + FileUtils::joinPath(lockDir, lockFile); - } } diff --git a/src/core/store/SingleInstanceLockFactory.cpp b/src/core/store/SingleInstanceLockFactory.cpp index c997edf4..f3f398ba 100644 --- a/src/core/store/SingleInstanceLockFactory.cpp +++ b/src/core/store/SingleInstanceLockFactory.cpp @@ -8,60 +8,51 @@ #include "SingleInstanceLockFactory.h" #include "_SingleInstanceLockFactory.h" -namespace Lucene -{ - SingleInstanceLockFactory::SingleInstanceLockFactory() - { - locks = HashSet::newInstance(); - } +namespace Lucene { - SingleInstanceLockFactory::~SingleInstanceLockFactory() - { - } +SingleInstanceLockFactory::SingleInstanceLockFactory() { + locks = HashSet::newInstance(); +} + +SingleInstanceLockFactory::~SingleInstanceLockFactory() { +} - LockPtr SingleInstanceLockFactory::makeLock(const String& lockName) - { - // We do not use the LockPrefix at all, because the private HashSet instance - // effectively scopes the locking to this single Directory instance. - return newLucene(locks, lockName); - } +LockPtr SingleInstanceLockFactory::makeLock(const String& lockName) { + // We do not use the LockPrefix at all, because the private HashSet instance + // effectively scopes the locking to this single Directory instance. + return newLucene(locks, lockName); +} + +void SingleInstanceLockFactory::clearLock(const String& lockName) { + SyncLock syncLock(&locks); + locks.remove(lockName); +} - void SingleInstanceLockFactory::clearLock(const String& lockName) - { - SyncLock syncLock(&locks); - locks.remove(lockName); - } +SingleInstanceLock::SingleInstanceLock(HashSet locks, const String& lockName) { + this->locks = locks; + this->lockName = lockName; +} - SingleInstanceLock::SingleInstanceLock(HashSet locks, const String& lockName) - { - this->locks = locks; - this->lockName = lockName; - } +SingleInstanceLock::~SingleInstanceLock() { +} - SingleInstanceLock::~SingleInstanceLock() - { - } +bool SingleInstanceLock::obtain() { + SyncLock syncLock(&locks); + return locks.add(lockName); +} - bool SingleInstanceLock::obtain() - { - SyncLock syncLock(&locks); - return locks.add(lockName); - } +void SingleInstanceLock::release() { + SyncLock syncLock(&locks); + locks.remove(lockName); +} - void SingleInstanceLock::release() - { - SyncLock syncLock(&locks); - locks.remove(lockName); - } +bool SingleInstanceLock::isLocked() { + SyncLock syncLock(&locks); + return locks.contains(lockName); +} - bool SingleInstanceLock::isLocked() - { - SyncLock syncLock(&locks); - return locks.contains(lockName); - } +String SingleInstanceLock::toString() { + return lockName; +} - String SingleInstanceLock::toString() - { - return lockName; - } } diff --git a/src/core/util/Attribute.cpp b/src/core/util/Attribute.cpp index 87402103..ae45eadf 100644 --- a/src/core/util/Attribute.cpp +++ b/src/core/util/Attribute.cpp @@ -7,24 +7,21 @@ #include "LuceneInc.h" #include "Attribute.h" -namespace Lucene -{ - Attribute::~Attribute() - { - } +namespace Lucene { - int32_t Attribute::hashCode() - { - return LuceneObject::hashCode(); - } +Attribute::~Attribute() { +} + +int32_t Attribute::hashCode() { + return LuceneObject::hashCode(); +} - bool Attribute::equals(const LuceneObjectPtr& other) - { - return LuceneObject::equals(other); - } +bool Attribute::equals(const LuceneObjectPtr& other) { + return LuceneObject::equals(other); +} + +LuceneObjectPtr Attribute::clone(const LuceneObjectPtr& other) { + return LuceneObject::clone(other); +} - LuceneObjectPtr Attribute::clone(const LuceneObjectPtr& other) - { - return LuceneObject::clone(other); - } } diff --git a/src/core/util/AttributeSource.cpp b/src/core/util/AttributeSource.cpp index 6dd86955..c5fb392e 100644 --- a/src/core/util/AttributeSource.cpp +++ b/src/core/util/AttributeSource.cpp @@ -8,255 +8,239 @@ #include "AttributeSource.h" #include "Attribute.h" -namespace Lucene -{ - AttributeFactory::AttributeFactory() - { - } +namespace Lucene { - AttributeFactory::~AttributeFactory() - { - } +AttributeFactory::AttributeFactory() { +} - AttributePtr AttributeFactory::createAttributeInstance(const String& className) - { - return AttributePtr(); // override - } +AttributeFactory::~AttributeFactory() { +} - AttributeFactoryPtr AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY() - { - static AttributeFactoryPtr _DEFAULT_ATTRIBUTE_FACTORY; - if (!_DEFAULT_ATTRIBUTE_FACTORY) - { - _DEFAULT_ATTRIBUTE_FACTORY = newLucene(); - CycleCheck::addStatic(_DEFAULT_ATTRIBUTE_FACTORY); - } - return _DEFAULT_ATTRIBUTE_FACTORY; - } +AttributePtr AttributeFactory::createAttributeInstance(const String& className) { + return AttributePtr(); // override +} - AttributeSource::AttributeSource() - { - this->attributes = MapStringAttribute::newInstance(); - this->factory = AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY(); +AttributeFactoryPtr AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY() { + static AttributeFactoryPtr _DEFAULT_ATTRIBUTE_FACTORY; + if (!_DEFAULT_ATTRIBUTE_FACTORY) { + _DEFAULT_ATTRIBUTE_FACTORY = newLucene(); + CycleCheck::addStatic(_DEFAULT_ATTRIBUTE_FACTORY); } + return _DEFAULT_ATTRIBUTE_FACTORY; +} - AttributeSource::AttributeSource(const AttributeSourcePtr& input) - { - if (!input) - boost::throw_exception(IllegalArgumentException(L"input AttributeSource must not be null")); - this->attributes = input->attributes; - this->factory = input->factory; - } +AttributeSource::AttributeSource() { + this->attributes = MapStringAttribute::newInstance(); + this->factory = AttributeFactory::DEFAULT_ATTRIBUTE_FACTORY(); +} - AttributeSource::AttributeSource(const AttributeFactoryPtr& factory) - { - this->attributes = MapStringAttribute::newInstance(); - this->factory = factory; +AttributeSource::AttributeSource(const AttributeSourcePtr& input) { + if (!input) { + boost::throw_exception(IllegalArgumentException(L"input AttributeSource must not be null")); } + this->attributes = input->attributes; + this->factory = input->factory; +} - AttributeSource::~AttributeSource() - { - } +AttributeSource::AttributeSource(const AttributeFactoryPtr& factory) { + this->attributes = MapStringAttribute::newInstance(); + this->factory = factory; +} - AttributeFactoryPtr AttributeSource::getAttributeFactory() - { - return this->factory; - } +AttributeSource::~AttributeSource() { +} - void AttributeSource::addAttribute(const String& className, const AttributePtr& attrImpl) - { - // invalidate state to force recomputation in captureState() - currentState.reset(); - attributes.put(className, attrImpl); - } +AttributeFactoryPtr AttributeSource::getAttributeFactory() { + return this->factory; +} - bool AttributeSource::hasAttributes() - { - return !attributes.empty(); - } +void AttributeSource::addAttribute(const String& className, const AttributePtr& attrImpl) { + // invalidate state to force recomputation in captureState() + currentState.reset(); + attributes.put(className, attrImpl); +} - AttributePtr AttributeSource::getAttribute(const String& className) - { - return attributes.get(className); - } +bool AttributeSource::hasAttributes() { + return !attributes.empty(); +} - bool AttributeSource::hasAttribute(const String& className) - { - return attributes.contains(className); - } +AttributePtr AttributeSource::getAttribute(const String& className) { + return attributes.get(className); +} - void AttributeSource::computeCurrentState() - { - currentState = newLucene(); - AttributeSourceStatePtr c(currentState); - MapStringAttribute::iterator attrImpl = attributes.begin(); +bool AttributeSource::hasAttribute(const String& className) { + return attributes.contains(className); +} + +void AttributeSource::computeCurrentState() { + currentState = newLucene(); + AttributeSourceStatePtr c(currentState); + MapStringAttribute::iterator attrImpl = attributes.begin(); + c->attribute = attrImpl->second; + ++attrImpl; + while (attrImpl != attributes.end()) { + c->next = newLucene(); + c = c->next; c->attribute = attrImpl->second; ++attrImpl; - while (attrImpl != attributes.end()) - { - c->next = newLucene(); - c = c->next; - c->attribute = attrImpl->second; - ++attrImpl; - } } +} - void AttributeSource::clearAttributes() - { - if (hasAttributes()) - { - if (!currentState) - computeCurrentState(); - for (MapStringAttribute::iterator attrImpl = attributes.begin(); attrImpl != attributes.end(); ++attrImpl) - attrImpl->second->clear(); +void AttributeSource::clearAttributes() { + if (hasAttributes()) { + if (!currentState) { + computeCurrentState(); + } + for (MapStringAttribute::iterator attrImpl = attributes.begin(); attrImpl != attributes.end(); ++attrImpl) { + attrImpl->second->clear(); } } +} - AttributeSourceStatePtr AttributeSource::captureState() - { - if (!hasAttributes()) - return AttributeSourceStatePtr(); +AttributeSourceStatePtr AttributeSource::captureState() { + if (!hasAttributes()) { + return AttributeSourceStatePtr(); + } - if (!currentState) - computeCurrentState(); + if (!currentState) { + computeCurrentState(); + } + + return boost::dynamic_pointer_cast(currentState->clone()); +} - return boost::dynamic_pointer_cast(currentState->clone()); +void AttributeSource::restoreState(const AttributeSourceStatePtr& state) { + AttributeSourceStatePtr _state(state); + if (!_state) { + return; } - void AttributeSource::restoreState(const AttributeSourceStatePtr& state) - { - AttributeSourceStatePtr _state(state); - if (!_state) - return; - - do - { - MapStringAttribute::iterator attrImpl = attributes.find(_state->attribute->getClassName()); - if (attrImpl == attributes.end()) - boost::throw_exception(IllegalArgumentException(L"State contains an AttributeImpl that is not in this AttributeSource")); - _state->attribute->copyTo(attrImpl->second); - _state = _state->next; + do { + MapStringAttribute::iterator attrImpl = attributes.find(_state->attribute->getClassName()); + if (attrImpl == attributes.end()) { + boost::throw_exception(IllegalArgumentException(L"State contains an AttributeImpl that is not in this AttributeSource")); } - while (_state); + _state->attribute->copyTo(attrImpl->second); + _state = _state->next; + } while (_state); +} + +int32_t AttributeSource::hashCode() { + int32_t code = 0; + for (MapStringAttribute::iterator attrImpl = attributes.begin(); attrImpl != attributes.end(); ++attrImpl) { + code = code * 31 + attrImpl->second->hashCode(); } + return code; +} - int32_t AttributeSource::hashCode() - { - int32_t code = 0; - for (MapStringAttribute::iterator attrImpl = attributes.begin(); attrImpl != attributes.end(); ++attrImpl) - code = code * 31 + attrImpl->second->hashCode(); - return code; +bool AttributeSource::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; } - bool AttributeSource::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; + AttributeSourcePtr otherAttributeSource = boost::dynamic_pointer_cast(other); + if (otherAttributeSource) { + if (hasAttributes()) { + if (!otherAttributeSource->hasAttributes()) { + return false; + } - AttributeSourcePtr otherAttributeSource = boost::dynamic_pointer_cast(other); - if (otherAttributeSource) - { - if (hasAttributes()) - { - if (!otherAttributeSource->hasAttributes()) - return false; + if (attributes.size() != otherAttributeSource->attributes.size()) { + return false; + } - if (attributes.size() != otherAttributeSource->attributes.size()) - return false; + // it is only equal if all attribute impls are the same in the same order + if (!currentState) { + computeCurrentState(); + } - // it is only equal if all attribute impls are the same in the same order - if (!currentState) - computeCurrentState(); - - AttributeSourceStatePtr thisState(currentState); - if (!otherAttributeSource->currentState) - otherAttributeSource->computeCurrentState(); - - AttributeSourceStatePtr otherState(otherAttributeSource->currentState); - while (thisState && otherState) - { - if (otherState->attribute->getClassName() != thisState->attribute->getClassName() || !otherState->attribute->equals(thisState->attribute)) - return false; - thisState = thisState->next; - otherState = otherState->next; + AttributeSourceStatePtr thisState(currentState); + if (!otherAttributeSource->currentState) { + otherAttributeSource->computeCurrentState(); + } + + AttributeSourceStatePtr otherState(otherAttributeSource->currentState); + while (thisState && otherState) { + if (otherState->attribute->getClassName() != thisState->attribute->getClassName() || !otherState->attribute->equals(thisState->attribute)) { + return false; } - return true; + thisState = thisState->next; + otherState = otherState->next; } - else - return !otherAttributeSource->hasAttributes(); + return true; + } else { + return !otherAttributeSource->hasAttributes(); } - else - return false; + } else { + return false; } +} - String AttributeSource::toString() - { - StringStream buf; - buf << L"("; - if (hasAttributes()) - { - if (!currentState) - computeCurrentState(); - for (AttributeSourceStatePtr state(currentState); state; state = state->next) - { - if (state != currentState) - buf << L","; - buf << state->attribute->toString(); +String AttributeSource::toString() { + StringStream buf; + buf << L"("; + if (hasAttributes()) { + if (!currentState) { + computeCurrentState(); + } + for (AttributeSourceStatePtr state(currentState); state; state = state->next) { + if (state != currentState) { + buf << L","; } + buf << state->attribute->toString(); } - buf << ")"; - return buf.str(); } + buf << ")"; + return buf.str(); +} - AttributeSourcePtr AttributeSource::cloneAttributes() - { - AttributeSourcePtr clone(newLucene(this->factory)); +AttributeSourcePtr AttributeSource::cloneAttributes() { + AttributeSourcePtr clone(newLucene(this->factory)); - if (hasAttributes()) - { - if (!currentState) - computeCurrentState(); - for (AttributeSourceStatePtr state(currentState); state; state = state->next) - clone->attributes.put(state->attribute->getClassName(), boost::dynamic_pointer_cast(state->attribute->clone())); + if (hasAttributes()) { + if (!currentState) { + computeCurrentState(); } - - return clone; - } - - Collection AttributeSource::getAttributes() - { - Collection attrImpls(Collection::newInstance()); - if (hasAttributes()) - { - if (!currentState) - computeCurrentState(); - for (AttributeSourceStatePtr state(currentState); state; state = state->next) - attrImpls.add(state->attribute); + for (AttributeSourceStatePtr state(currentState); state; state = state->next) { + clone->attributes.put(state->attribute->getClassName(), boost::dynamic_pointer_cast(state->attribute->clone())); } - return attrImpls; } - DefaultAttributeFactory::~DefaultAttributeFactory() - { - } + return clone; +} - AttributePtr DefaultAttributeFactory::createAttributeInstance(const String& className) - { - return AttributePtr(); +Collection AttributeSource::getAttributes() { + Collection attrImpls(Collection::newInstance()); + if (hasAttributes()) { + if (!currentState) { + computeCurrentState(); + } + for (AttributeSourceStatePtr state(currentState); state; state = state->next) { + attrImpls.add(state->attribute); + } } + return attrImpls; +} - AttributeSourceState::~AttributeSourceState() - { - } +DefaultAttributeFactory::~DefaultAttributeFactory() { +} - LuceneObjectPtr AttributeSourceState::clone(const LuceneObjectPtr& other) - { - AttributeSourceStatePtr clone(newLucene()); - clone->attribute = boost::dynamic_pointer_cast(attribute->clone()); +AttributePtr DefaultAttributeFactory::createAttributeInstance(const String& className) { + return AttributePtr(); +} - if (next) - clone->next = boost::dynamic_pointer_cast(next->clone()); +AttributeSourceState::~AttributeSourceState() { +} - return clone; +LuceneObjectPtr AttributeSourceState::clone(const LuceneObjectPtr& other) { + AttributeSourceStatePtr clone(newLucene()); + clone->attribute = boost::dynamic_pointer_cast(attribute->clone()); + + if (next) { + clone->next = boost::dynamic_pointer_cast(next->clone()); } + + return clone; +} + } diff --git a/src/core/util/Base64.cpp b/src/core/util/Base64.cpp index cc399277..8262baa8 100644 --- a/src/core/util/Base64.cpp +++ b/src/core/util/Base64.cpp @@ -9,120 +9,117 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - const String Base64::BASE64_CHARS = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +namespace Lucene { - Base64::~Base64() - { - } +const String Base64::BASE64_CHARS = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - String Base64::encode(ByteArray bytes) - { - return encode(bytes.get(), bytes.size()); - } +Base64::~Base64() { +} - String Base64::encode(const uint8_t* bytes, int32_t length) - { - String result; - uint8_t byteArray3[3]; - uint8_t byteArray4[4]; - int32_t i = 0; - - while (length--) - { - byteArray3[i++] = *(bytes++); - if (i == 3) - { - byteArray4[0] = (byteArray3[0] & 0xfc) >> 2; - byteArray4[1] = ((byteArray3[0] & 0x03) << 4) + ((byteArray3[1] & 0xf0) >> 4); - byteArray4[2] = ((byteArray3[1] & 0x0f) << 2) + ((byteArray3[2] & 0xc0) >> 6); - byteArray4[3] = byteArray3[2] & 0x3f; - - for (i = 0; i < 4; ++i) - result += BASE64_CHARS[byteArray4[i]]; - i = 0; - } - } +String Base64::encode(ByteArray bytes) { + return encode(bytes.get(), bytes.size()); +} - if (i != 0) - { - for (int32_t j = i; j < 3; ++j) - byteArray3[j] = 0; +String Base64::encode(const uint8_t* bytes, int32_t length) { + String result; + uint8_t byteArray3[3]; + uint8_t byteArray4[4]; + int32_t i = 0; + while (length--) { + byteArray3[i++] = *(bytes++); + if (i == 3) { byteArray4[0] = (byteArray3[0] & 0xfc) >> 2; byteArray4[1] = ((byteArray3[0] & 0x03) << 4) + ((byteArray3[1] & 0xf0) >> 4); byteArray4[2] = ((byteArray3[1] & 0x0f) << 2) + ((byteArray3[2] & 0xc0) >> 6); byteArray4[3] = byteArray3[2] & 0x3f; - for (int32_t j = 0; j < i + 1; ++j) - result += BASE64_CHARS[byteArray4[j]]; - - while (i++ < 3) - result += L'='; + for (i = 0; i < 4; ++i) { + result += BASE64_CHARS[byteArray4[i]]; + } + i = 0; } - return result; } - ByteArray Base64::decode(const String& str) - { - int32_t length = str.length(); - uint8_t byteArray4[4]; - uint8_t byteArray3[3]; - - int32_t i = 0; - int32_t charIndex = 0; - - ByteArray result(ByteArray::newInstance(length / 2)); - int32_t resultIndex = 0; - - while (length-- && str[charIndex] != L'=' && isBase64(str[charIndex])) - { - byteArray4[i++] = (uint8_t)str[charIndex++]; - if (i == 4) - { - for (i = 0; i < 4; ++i) - byteArray4[i] = BASE64_CHARS.find(byteArray4[i]); - byteArray3[0] = (byteArray4[0] << 2) + ((byteArray4[1] & 0x30) >> 4); - byteArray3[1] = ((byteArray4[1] & 0xf) << 4) + ((byteArray4[2] & 0x3c) >> 2); - byteArray3[2] = ((byteArray4[2] & 0x3) << 6) + byteArray4[3]; - - for (i = 0; i < 3; ++i) - { - if (resultIndex >= result.size()) - result.resize((int32_t)((double)result.size() * 1.5)); - result[resultIndex++] = byteArray3[i]; - } + if (i != 0) { + for (int32_t j = i; j < 3; ++j) { + byteArray3[j] = 0; + } - i = 0; - } + byteArray4[0] = (byteArray3[0] & 0xfc) >> 2; + byteArray4[1] = ((byteArray3[0] & 0x03) << 4) + ((byteArray3[1] & 0xf0) >> 4); + byteArray4[2] = ((byteArray3[1] & 0x0f) << 2) + ((byteArray3[2] & 0xc0) >> 6); + byteArray4[3] = byteArray3[2] & 0x3f; + + for (int32_t j = 0; j < i + 1; ++j) { + result += BASE64_CHARS[byteArray4[j]]; + } + + while (i++ < 3) { + result += L'='; } + } + return result; +} + +ByteArray Base64::decode(const String& str) { + int32_t length = str.length(); + uint8_t byteArray4[4]; + uint8_t byteArray3[3]; - if (i != 0) - { - for (int32_t j = i; j < 4; ++j) - byteArray4[j] = 0; - for (int32_t j = 0; j < 4; ++j) - byteArray4[j] = BASE64_CHARS.find(byteArray4[j]); + int32_t i = 0; + int32_t charIndex = 0; + + ByteArray result(ByteArray::newInstance(length / 2)); + int32_t resultIndex = 0; + + while (length-- && str[charIndex] != L'=' && isBase64(str[charIndex])) { + byteArray4[i++] = (uint8_t)str[charIndex++]; + if (i == 4) { + for (i = 0; i < 4; ++i) { + byteArray4[i] = BASE64_CHARS.find(byteArray4[i]); + } byteArray3[0] = (byteArray4[0] << 2) + ((byteArray4[1] & 0x30) >> 4); byteArray3[1] = ((byteArray4[1] & 0xf) << 4) + ((byteArray4[2] & 0x3c) >> 2); byteArray3[2] = ((byteArray4[2] & 0x3) << 6) + byteArray4[3]; - for (int32_t j = 0; j < i - 1; ++j) - { - if (resultIndex >= result.size()) + for (i = 0; i < 3; ++i) { + if (resultIndex >= result.size()) { result.resize((int32_t)((double)result.size() * 1.5)); - result[resultIndex++] = byteArray3[j]; + } + result[resultIndex++] = byteArray3[i]; } + + i = 0; } + } - result.resize(resultIndex); + if (i != 0) { + for (int32_t j = i; j < 4; ++j) { + byteArray4[j] = 0; + } + for (int32_t j = 0; j < 4; ++j) { + byteArray4[j] = BASE64_CHARS.find(byteArray4[j]); + } + byteArray3[0] = (byteArray4[0] << 2) + ((byteArray4[1] & 0x30) >> 4); + byteArray3[1] = ((byteArray4[1] & 0xf) << 4) + ((byteArray4[2] & 0x3c) >> 2); + byteArray3[2] = ((byteArray4[2] & 0x3) << 6) + byteArray4[3]; - return result; + for (int32_t j = 0; j < i - 1; ++j) { + if (resultIndex >= result.size()) { + result.resize((int32_t)((double)result.size() * 1.5)); + } + result[resultIndex++] = byteArray3[j]; + } } - bool Base64::isBase64(wchar_t ch) - { - return (UnicodeUtil::isAlnum(ch) || ch == L'+' || ch == L'/'); - } + result.resize(resultIndex); + + return result; +} + +bool Base64::isBase64(wchar_t ch) { + return (UnicodeUtil::isAlnum(ch) || ch == L'+' || ch == L'/'); +} + } diff --git a/src/core/util/BitSet.cpp b/src/core/util/BitSet.cpp index a1142af9..6eb9d943 100644 --- a/src/core/util/BitSet.cpp +++ b/src/core/util/BitSet.cpp @@ -8,265 +8,257 @@ #include "BitSet.h" #include "BitUtil.h" -namespace Lucene -{ - BitSet::BitSet(uint32_t size) : bitSet(size) - { - } +namespace Lucene { - BitSet::~BitSet() - { - } +BitSet::BitSet(uint32_t size) : bitSet(size) { +} - const uint64_t* BitSet::getBits() - { - return bitSet.empty() ? NULL : static_cast(&bitSet.m_bits[0]); - } +BitSet::~BitSet() { +} - void BitSet::clear() - { - bitSet.clear(); - } +const uint64_t* BitSet::getBits() { + return bitSet.empty() ? NULL : static_cast(&bitSet.m_bits[0]); +} - void BitSet::clear(uint32_t bitIndex) - { - if (bitIndex <= bitSet.size()) - bitSet.set(bitIndex, false); - } +void BitSet::clear() { + bitSet.clear(); +} - void BitSet::fastClear(uint32_t bitIndex) - { +void BitSet::clear(uint32_t bitIndex) { + if (bitIndex <= bitSet.size()) { bitSet.set(bitIndex, false); } +} - void BitSet::clear(uint32_t fromIndex, uint32_t toIndex) - { - toIndex = std::min(toIndex, (uint32_t)bitSet.size()); - for (bitset_type::size_type i = std::min(fromIndex, (uint32_t)bitSet.size()); i < toIndex; ++i) - bitSet.set(i, false); - } +void BitSet::fastClear(uint32_t bitIndex) { + bitSet.set(bitIndex, false); +} - void BitSet::fastClear(uint32_t fromIndex, uint32_t toIndex) - { - for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) - bitSet.set(i, false); +void BitSet::clear(uint32_t fromIndex, uint32_t toIndex) { + toIndex = std::min(toIndex, (uint32_t)bitSet.size()); + for (bitset_type::size_type i = std::min(fromIndex, (uint32_t)bitSet.size()); i < toIndex; ++i) { + bitSet.set(i, false); } +} - void BitSet::set(uint32_t bitIndex) - { - if (bitIndex >= bitSet.size()) - resize(bitIndex + 1); - bitSet.set(bitIndex, true); +void BitSet::fastClear(uint32_t fromIndex, uint32_t toIndex) { + for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) { + bitSet.set(i, false); } +} - void BitSet::fastSet(uint32_t bitIndex) - { - bitSet.set(bitIndex, true); +void BitSet::set(uint32_t bitIndex) { + if (bitIndex >= bitSet.size()) { + resize(bitIndex + 1); } + bitSet.set(bitIndex, true); +} - void BitSet::set(uint32_t bitIndex, bool value) - { - if (bitIndex >= bitSet.size()) - resize(bitIndex + 1); - bitSet.set(bitIndex, value); - } +void BitSet::fastSet(uint32_t bitIndex) { + bitSet.set(bitIndex, true); +} - void BitSet::fastSet(uint32_t bitIndex, bool value) - { - bitSet.set(bitIndex, value); +void BitSet::set(uint32_t bitIndex, bool value) { + if (bitIndex >= bitSet.size()) { + resize(bitIndex + 1); } + bitSet.set(bitIndex, value); +} - void BitSet::set(uint32_t fromIndex, uint32_t toIndex) - { - if (toIndex >= bitSet.size()) - resize(toIndex + 1); - for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) - bitSet.set(i, true); - } +void BitSet::fastSet(uint32_t bitIndex, bool value) { + bitSet.set(bitIndex, value); +} - void BitSet::fastSet(uint32_t fromIndex, uint32_t toIndex) - { - for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) - bitSet.set(i, true); +void BitSet::set(uint32_t fromIndex, uint32_t toIndex) { + if (toIndex >= bitSet.size()) { + resize(toIndex + 1); } - - void BitSet::set(uint32_t fromIndex, uint32_t toIndex, bool value) - { - if (toIndex >= bitSet.size()) - resize(toIndex + 1); - for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) - bitSet.set(i, value); + for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) { + bitSet.set(i, true); } +} - void BitSet::fastSet(uint32_t fromIndex, uint32_t toIndex, bool value) - { - for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) - bitSet.set(i, value); +void BitSet::fastSet(uint32_t fromIndex, uint32_t toIndex) { + for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) { + bitSet.set(i, true); } +} - void BitSet::flip(uint32_t bitIndex) - { - if (bitIndex >= bitSet.size()) - resize(bitIndex + 1); - bitSet.flip(bitIndex); +void BitSet::set(uint32_t fromIndex, uint32_t toIndex, bool value) { + if (toIndex >= bitSet.size()) { + resize(toIndex + 1); } - - void BitSet::fastFlip(uint32_t bitIndex) - { - bitSet.flip(bitIndex); + for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) { + bitSet.set(i, value); } +} - void BitSet::flip(uint32_t fromIndex, uint32_t toIndex) - { - if (toIndex >= bitSet.size()) - resize(toIndex + 1); - for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) - bitSet.flip(i); +void BitSet::fastSet(uint32_t fromIndex, uint32_t toIndex, bool value) { + for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) { + bitSet.set(i, value); } +} - void BitSet::fastFlip(uint32_t fromIndex, uint32_t toIndex) - { - for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) - bitSet.flip(i); +void BitSet::flip(uint32_t bitIndex) { + if (bitIndex >= bitSet.size()) { + resize(bitIndex + 1); } + bitSet.flip(bitIndex); +} - uint32_t BitSet::size() const - { - return bitSet.num_blocks() * sizeof(bitset_type::block_type) * 8; - } +void BitSet::fastFlip(uint32_t bitIndex) { + bitSet.flip(bitIndex); +} - uint32_t BitSet::numBlocks() const - { - return bitSet.num_blocks(); +void BitSet::flip(uint32_t fromIndex, uint32_t toIndex) { + if (toIndex >= bitSet.size()) { + resize(toIndex + 1); } - - bool BitSet::isEmpty() const - { - return bitSet.none(); + for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) { + bitSet.flip(i); } +} - bool BitSet::get(uint32_t bitIndex) const - { - return bitIndex < bitSet.size() ? bitSet.test(bitIndex) : false; +void BitSet::fastFlip(uint32_t fromIndex, uint32_t toIndex) { + for (bitset_type::size_type i = fromIndex; i < toIndex; ++i) { + bitSet.flip(i); } +} - bool BitSet::fastGet(uint32_t bitIndex) const - { - return bitSet.test(bitIndex); - } +uint32_t BitSet::size() const { + return bitSet.num_blocks() * sizeof(bitset_type::block_type) * 8; +} - int32_t BitSet::nextSetBit(uint32_t fromIndex) const - { - bitset_type::size_type next = fromIndex == 0 ? bitSet.find_first() : bitSet.find_next(fromIndex - 1); - return next == bitset_type::npos ? -1 : next; - } +uint32_t BitSet::numBlocks() const { + return bitSet.num_blocks(); +} - void BitSet::_and(const BitSetPtr& set) - { - bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); - for (bitset_type::size_type i = 0; i < minBlocks; ++i) - bitSet.m_bits[i] &= set->bitSet.m_bits[i]; - if (bitSet.num_blocks() > minBlocks) - std::fill(bitSet.m_bits.begin() + minBlocks, bitSet.m_bits.end(), bitset_type::block_type(0)); - } +bool BitSet::isEmpty() const { + return bitSet.none(); +} - void BitSet::_or(const BitSetPtr& set) - { - bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); - if (set->bitSet.size() > bitSet.size()) - resize(set->bitSet.size()); - for (bitset_type::size_type i = 0; i < minBlocks; ++i) - bitSet.m_bits[i] |= set->bitSet.m_bits[i]; - if (bitSet.num_blocks() > minBlocks) - std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); - } +bool BitSet::get(uint32_t bitIndex) const { + return bitIndex < bitSet.size() ? bitSet.test(bitIndex) : false; +} - void BitSet::_xor(const BitSetPtr& set) - { - bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); - if (set->bitSet.size() > bitSet.size()) - resize(set->bitSet.size()); - for (bitset_type::size_type i = 0; i < minBlocks; ++i) - bitSet.m_bits[i] ^= set->bitSet.m_bits[i]; - if (bitSet.num_blocks() > minBlocks) - std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); +bool BitSet::fastGet(uint32_t bitIndex) const { + return bitSet.test(bitIndex); +} + +int32_t BitSet::nextSetBit(uint32_t fromIndex) const { + bitset_type::size_type next = fromIndex == 0 ? bitSet.find_first() : bitSet.find_next(fromIndex - 1); + return next == bitset_type::npos ? -1 : next; +} + +void BitSet::_and(const BitSetPtr& set) { + bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); + for (bitset_type::size_type i = 0; i < minBlocks; ++i) { + bitSet.m_bits[i] &= set->bitSet.m_bits[i]; + } + if (bitSet.num_blocks() > minBlocks) { + std::fill(bitSet.m_bits.begin() + minBlocks, bitSet.m_bits.end(), bitset_type::block_type(0)); } +} - void BitSet::andNot(const BitSetPtr& set) - { - bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); - for (bitset_type::size_type i = 0; i < minBlocks; ++i) - bitSet.m_bits[i] &= ~set->bitSet.m_bits[i]; +void BitSet::_or(const BitSetPtr& set) { + bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); + if (set->bitSet.size() > bitSet.size()) { + resize(set->bitSet.size()); + } + for (bitset_type::size_type i = 0; i < minBlocks; ++i) { + bitSet.m_bits[i] |= set->bitSet.m_bits[i]; + } + if (bitSet.num_blocks() > minBlocks) { + std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); } +} - bool BitSet::intersectsBitSet(const BitSetPtr& set) const - { - return bitSet.intersects(set->bitSet); +void BitSet::_xor(const BitSetPtr& set) { + bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); + if (set->bitSet.size() > bitSet.size()) { + resize(set->bitSet.size()); + } + for (bitset_type::size_type i = 0; i < minBlocks; ++i) { + bitSet.m_bits[i] ^= set->bitSet.m_bits[i]; } + if (bitSet.num_blocks() > minBlocks) { + std::copy(set->bitSet.m_bits.begin() + minBlocks, set->bitSet.m_bits.end(), bitSet.m_bits.begin() + minBlocks); + } +} - uint32_t BitSet::cardinality() - { - return bitSet.num_blocks() == 0 ? 0 : (uint32_t)BitUtil::pop_array((int64_t*)getBits(), 0, bitSet.num_blocks()); +void BitSet::andNot(const BitSetPtr& set) { + bitset_type::size_type minBlocks = std::min(bitSet.num_blocks(), set->bitSet.num_blocks()); + for (bitset_type::size_type i = 0; i < minBlocks; ++i) { + bitSet.m_bits[i] &= ~set->bitSet.m_bits[i]; } +} + +bool BitSet::intersectsBitSet(const BitSetPtr& set) const { + return bitSet.intersects(set->bitSet); +} + +uint32_t BitSet::cardinality() { + return bitSet.num_blocks() == 0 ? 0 : (uint32_t)BitUtil::pop_array((int64_t*)getBits(), 0, bitSet.num_blocks()); +} - void BitSet::resize(uint32_t size) - { - bitset_type::size_type old_num_blocks = bitSet.num_blocks(); - bitset_type::size_type required_blocks = bitSet.calc_num_blocks(size); - if (required_blocks != old_num_blocks) - bitSet.m_bits.resize(required_blocks, bitset_type::block_type(0)); - bitSet.m_num_bits = size; - uint64_t extra_bits = static_cast(bitSet.size() % bitSet.bits_per_block); - if (extra_bits != 0) - bitSet.m_bits.back() &= ~(~static_cast(0) << extra_bits); +void BitSet::resize(uint32_t size) { + bitset_type::size_type old_num_blocks = bitSet.num_blocks(); + bitset_type::size_type required_blocks = bitSet.calc_num_blocks(size); + if (required_blocks != old_num_blocks) { + bitSet.m_bits.resize(required_blocks, bitset_type::block_type(0)); } + bitSet.m_num_bits = size; + uint64_t extra_bits = static_cast(bitSet.size() % bitSet.bits_per_block); + if (extra_bits != 0) { + bitSet.m_bits.back() &= ~(~static_cast(0) << extra_bits); + } +} - bool BitSet::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - BitSetPtr otherBitSet(boost::dynamic_pointer_cast(other)); - if (!otherBitSet) +bool BitSet::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + BitSetPtr otherBitSet(boost::dynamic_pointer_cast(other)); + if (!otherBitSet) { + return false; + } + BitSetPtr first = bitSet.num_blocks() < otherBitSet->bitSet.num_blocks() ? otherBitSet : shared_from_this(); + BitSetPtr second = bitSet.num_blocks() < otherBitSet->bitSet.num_blocks() ? shared_from_this() : otherBitSet; + bitset_type::size_type firstLength = first->bitSet.num_blocks(); + bitset_type::size_type secondLength = second->bitSet.num_blocks(); + for (bitset_type::size_type i = secondLength; i < firstLength; ++i) { + if (first->bitSet.m_bits[i] != 0) { return false; - BitSetPtr first = bitSet.num_blocks() < otherBitSet->bitSet.num_blocks() ? otherBitSet : shared_from_this(); - BitSetPtr second = bitSet.num_blocks() < otherBitSet->bitSet.num_blocks() ? shared_from_this() : otherBitSet; - bitset_type::size_type firstLength = first->bitSet.num_blocks(); - bitset_type::size_type secondLength = second->bitSet.num_blocks(); - for (bitset_type::size_type i = secondLength; i < firstLength; ++i) - { - if (first->bitSet.m_bits[i] != 0) - return false; - } - for (bitset_type::size_type i = 0; i < secondLength; ++i) - { - if (first->bitSet.m_bits[i] != second->bitSet.m_bits[i]) - return false; } - return true; } - - int32_t BitSet::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. - int64_t hash = 0; - uint32_t maxSize = bitSet.num_blocks(); - const uint64_t* bits = getBits(); - for (uint32_t bit = 0; bit < maxSize; ++bit) - { - hash ^= bits[bit]; - hash = (hash << 1) | (hash >> 63); // rotate left + for (bitset_type::size_type i = 0; i < secondLength; ++i) { + if (first->bitSet.m_bits[i] != second->bitSet.m_bits[i]) { + return false; } - // Fold leftmost bits into right and add a constant to prevent empty sets from - // returning 0, which is too common. - return (int32_t)((hash >> 32) ^ hash) + 0x98761234; } + return true; +} + +int32_t BitSet::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. + int64_t hash = 0; + uint32_t maxSize = bitSet.num_blocks(); + const uint64_t* bits = getBits(); + for (uint32_t bit = 0; bit < maxSize; ++bit) { + hash ^= bits[bit]; + hash = (hash << 1) | (hash >> 63); // rotate left + } + // Fold leftmost bits into right and add a constant to prevent empty sets from + // returning 0, which is too common. + return (int32_t)((hash >> 32) ^ hash) + 0x98761234; +} + +LuceneObjectPtr BitSet::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + BitSetPtr cloneBitSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); + cloneBitSet->bitSet = bitSet; + return cloneBitSet; +} - LuceneObjectPtr BitSet::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - BitSetPtr cloneBitSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); - cloneBitSet->bitSet = bitSet; - return cloneBitSet; - } } diff --git a/src/core/util/BitUtil.cpp b/src/core/util/BitUtil.cpp index ebc86555..771e7b85 100644 --- a/src/core/util/BitUtil.cpp +++ b/src/core/util/BitUtil.cpp @@ -8,571 +8,543 @@ #include "BitUtil.h" #include "MiscUtils.h" -namespace Lucene -{ - const uint8_t BitUtil::ntzTable[] = - { - 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 - }; - - BitUtil::~BitUtil() - { - } - - int32_t BitUtil::pop(int64_t x) - { - x = x - (MiscUtils::unsignedShift(x, (int64_t)1) & 0x5555555555555555LL); - x = (x & 0x3333333333333333LL) + (MiscUtils::unsignedShift(x, (int64_t)2) & 0x3333333333333333LL); - x = (x + MiscUtils::unsignedShift(x, (int64_t)4)) & 0x0f0f0f0f0f0f0f0fLL; - x = x + MiscUtils::unsignedShift(x, (int64_t)8); - x = x + MiscUtils::unsignedShift(x, (int64_t)16); - x = x + MiscUtils::unsignedShift(x, (int64_t)32); - return (int32_t)x & 0x7f; - } - - int64_t BitUtil::pop_array(const int64_t* A, int32_t wordOffset, int32_t numWords) - { - int32_t n = wordOffset + numWords; - int64_t tot = 0; - int64_t tot8 = 0; - int64_t ones = 0; - int64_t twos = 0; - int64_t fours = 0; - - int32_t i = wordOffset; - for (; i <= n - 8; i += 8) - { - int64_t twosA; - CSA(twosA, ones, ones, A[i], A[i + 1]); - - int64_t twosB; - CSA(twosB, ones, ones, A[i + 2], A[i + 3]); - - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); - - CSA(twosA, ones, ones, A[i + 4], A[i + 5]); - - CSA(twosB, ones, ones, A[i + 6], A[i + 7]); - - int64_t foursB; - CSA(foursB, twos, twos, twosA, twosB); - - int64_t eights; - CSA(eights, fours, fours, foursA, foursB); - - tot8 += pop(eights); - } +namespace Lucene { + +const uint8_t BitUtil::ntzTable[] = { + 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +BitUtil::~BitUtil() { +} - // Handle trailing words in a binary-search manner. - // Derived from the loop above by setting specific elements to 0. +int32_t BitUtil::pop(int64_t x) { + x = x - (MiscUtils::unsignedShift(x, (int64_t)1) & 0x5555555555555555LL); + x = (x & 0x3333333333333333LL) + (MiscUtils::unsignedShift(x, (int64_t)2) & 0x3333333333333333LL); + x = (x + MiscUtils::unsignedShift(x, (int64_t)4)) & 0x0f0f0f0f0f0f0f0fLL; + x = x + MiscUtils::unsignedShift(x, (int64_t)8); + x = x + MiscUtils::unsignedShift(x, (int64_t)16); + x = x + MiscUtils::unsignedShift(x, (int64_t)32); + return (int32_t)x & 0x7f; +} - if (i <= n - 4) - { - int64_t twosA; - CSA(twosA, ones, ones, A[i], A[i + 1]); +int64_t BitUtil::pop_array(const int64_t* A, int32_t wordOffset, int32_t numWords) { + int32_t n = wordOffset + numWords; + int64_t tot = 0; + int64_t tot8 = 0; + int64_t ones = 0; + int64_t twos = 0; + int64_t fours = 0; - int64_t twosB; - CSA(twosB, ones, ones, A[i + 2], A[i + 3]); + int32_t i = wordOffset; + for (; i <= n - 8; i += 8) { + int64_t twosA; + CSA(twosA, ones, ones, A[i], A[i + 1]); - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + int64_t twosB; + CSA(twosB, ones, ones, A[i + 2], A[i + 3]); - int64_t eights = fours & foursA; - fours = fours ^ foursA; + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - tot8 += pop(eights); - i += 4; - } + CSA(twosA, ones, ones, A[i + 4], A[i + 5]); - if (i <= n - 2) - { - int64_t twosA; - CSA(twosA, ones, ones, A[i], A[i + 1]); + CSA(twosB, ones, ones, A[i + 6], A[i + 7]); - int64_t foursA = twos & twosA; - twos = twos ^ twosA; + int64_t foursB; + CSA(foursB, twos, twos, twosA, twosB); - int64_t eights = fours & foursA; - fours = fours ^ foursA; + int64_t eights; + CSA(eights, fours, fours, foursA, foursB); - tot8 += pop(eights); - i += 2; - } + tot8 += pop(eights); + } - if (i < n) - tot += pop(A[i]); + // Handle trailing words in a binary-search manner. + // Derived from the loop above by setting specific elements to 0. - tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); + if (i <= n - 4) { + int64_t twosA; + CSA(twosA, ones, ones, A[i], A[i + 1]); - return tot; + int64_t twosB; + CSA(twosB, ones, ones, A[i + 2], A[i + 3]); + + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); + + int64_t eights = fours & foursA; + fours = fours ^ foursA; + + tot8 += pop(eights); + i += 4; } - int64_t BitUtil::pop_intersect(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) - { - int32_t n = wordOffset + numWords; - int64_t tot = 0; - int64_t tot8 = 0; - int64_t ones = 0; - int64_t twos = 0; - int64_t fours = 0; + if (i <= n - 2) { + int64_t twosA; + CSA(twosA, ones, ones, A[i], A[i + 1]); - int32_t i = wordOffset; - for (; i <= n - 8; i += 8) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); + int64_t foursA = twos & twosA; + twos = twos ^ twosA; - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] & B[i + 2]), (A[i + 3] & B[i + 3])); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + tot8 += pop(eights); + i += 2; + } - CSA(twosA, ones, ones, (A[i + 4] & B[i + 4]), (A[i + 5] & B[i + 5])); + if (i < n) { + tot += pop(A[i]); + } - CSA(twosB, ones, ones, (A[i + 6] & B[i + 6]), (A[i + 7] & B[i + 7])); + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - int64_t foursB; - CSA(foursB, twos, twos, twosA, twosB); + return tot; +} - int64_t eights; - CSA(eights, fours, fours, foursA, foursB); +int64_t BitUtil::pop_intersect(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { + int32_t n = wordOffset + numWords; + int64_t tot = 0; + int64_t tot8 = 0; + int64_t ones = 0; + int64_t twos = 0; + int64_t fours = 0; - tot8 += pop(eights); - } + int32_t i = wordOffset; + for (; i <= n - 8; i += 8) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); - if (i <= n - 4) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] & B[i + 2]), (A[i + 3] & B[i + 3])); - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] & B[i + 2]), (A[i + 3] & B[i + 3])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + CSA(twosA, ones, ones, (A[i + 4] & B[i + 4]), (A[i + 5] & B[i + 5])); - int64_t eights = fours & foursA; - fours = fours ^ foursA; + CSA(twosB, ones, ones, (A[i + 6] & B[i + 6]), (A[i + 7] & B[i + 7])); - tot8 += pop(eights); - i += 4; - } + int64_t foursB; + CSA(foursB, twos, twos, twosA, twosB); - if (i <= n - 2) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); + int64_t eights; + CSA(eights, fours, fours, foursA, foursB); - int64_t foursA = twos & twosA; - twos = twos ^ twosA; + tot8 += pop(eights); + } - int64_t eights = fours & foursA; - fours = fours ^ foursA; + if (i <= n - 4) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); - tot8 += pop(eights); - i += 2; - } + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] & B[i + 2]), (A[i + 3] & B[i + 3])); - if (i < n) - tot += pop((A[i] & B[i])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - return tot; + tot8 += pop(eights); + i += 4; } - int64_t BitUtil::pop_union(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) - { - int32_t n = wordOffset + numWords; - int64_t tot = 0; - int64_t tot8 = 0; - int64_t ones = 0; - int64_t twos = 0; - int64_t fours = 0; + if (i <= n - 2) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] & B[i]), (A[i + 1] & B[i + 1])); - int32_t i = wordOffset; - for (; i <= n - 8; i += 8) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); + int64_t foursA = twos & twosA; + twos = twos ^ twosA; - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] | B[i + 2]), (A[i + 3] | B[i + 3])); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + tot8 += pop(eights); + i += 2; + } - CSA(twosA, ones, ones, (A[i + 4] | B[i + 4]), (A[i + 5] | B[i + 5])); + if (i < n) { + tot += pop((A[i] & B[i])); + } - CSA(twosB, ones, ones, (A[i + 6] | B[i + 6]), (A[i + 7] | B[i + 7])); + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - int64_t foursB; - CSA(foursB, twos, twos, twosA, twosB); + return tot; +} - int64_t eights; - CSA(eights, fours, fours, foursA, foursB); +int64_t BitUtil::pop_union(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { + int32_t n = wordOffset + numWords; + int64_t tot = 0; + int64_t tot8 = 0; + int64_t ones = 0; + int64_t twos = 0; + int64_t fours = 0; - tot8 += pop(eights); - } + int32_t i = wordOffset; + for (; i <= n - 8; i += 8) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); - if (i <= n - 4) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] | B[i + 2]), (A[i + 3] | B[i + 3])); - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] | B[i + 2]), (A[i + 3] | B[i + 3])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + CSA(twosA, ones, ones, (A[i + 4] | B[i + 4]), (A[i + 5] | B[i + 5])); - int64_t eights = fours & foursA; - fours = fours ^ foursA; + CSA(twosB, ones, ones, (A[i + 6] | B[i + 6]), (A[i + 7] | B[i + 7])); - tot8 += pop(eights); - i += 4; - } + int64_t foursB; + CSA(foursB, twos, twos, twosA, twosB); - if (i <= n - 2) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); + int64_t eights; + CSA(eights, fours, fours, foursA, foursB); - int64_t foursA = twos & twosA; - twos = twos ^ twosA; + tot8 += pop(eights); + } - int64_t eights = fours & foursA; - fours = fours ^ foursA; + if (i <= n - 4) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); - tot8 += pop(eights); - i += 2; - } + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] | B[i + 2]), (A[i + 3] | B[i + 3])); - if (i < n) - tot += pop((A[i] | B[i])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - return tot; + tot8 += pop(eights); + i += 4; } - int64_t BitUtil::pop_andnot(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) - { - int32_t n = wordOffset + numWords; - int64_t tot = 0; - int64_t tot8 = 0; - int64_t ones = 0; - int64_t twos = 0; - int64_t fours = 0; + if (i <= n - 2) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] | B[i]), (A[i + 1] | B[i + 1])); - int32_t i = wordOffset; - for (; i <= n - 8; i += 8) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); + int64_t foursA = twos & twosA; + twos = twos ^ twosA; - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] & ~B[i + 2]), (A[i + 3] & ~B[i + 3])); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + tot8 += pop(eights); + i += 2; + } - CSA(twosA, ones, ones, (A[i + 4] & ~B[i + 4]), (A[i + 5] & ~B[i + 5])); + if (i < n) { + tot += pop((A[i] | B[i])); + } - CSA(twosB, ones, ones, (A[i + 6] & ~B[i + 6]), (A[i + 7] & ~B[i + 7])); + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - int64_t foursB; - CSA(foursB, twos, twos, twosA, twosB); + return tot; +} - int64_t eights; - CSA(eights, fours, fours, foursA, foursB); +int64_t BitUtil::pop_andnot(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { + int32_t n = wordOffset + numWords; + int64_t tot = 0; + int64_t tot8 = 0; + int64_t ones = 0; + int64_t twos = 0; + int64_t fours = 0; - tot8 += pop(eights); - } + int32_t i = wordOffset; + for (; i <= n - 8; i += 8) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); - if (i <= n - 4) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] & ~B[i + 2]), (A[i + 3] & ~B[i + 3])); - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] & ~B[i + 2]), (A[i + 3] & ~B[i + 3])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + CSA(twosA, ones, ones, (A[i + 4] & ~B[i + 4]), (A[i + 5] & ~B[i + 5])); - int64_t eights = fours & foursA; - fours = fours ^ foursA; + CSA(twosB, ones, ones, (A[i + 6] & ~B[i + 6]), (A[i + 7] & ~B[i + 7])); - tot8 += pop(eights); - i += 4; - } + int64_t foursB; + CSA(foursB, twos, twos, twosA, twosB); - if (i <= n - 2) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); + int64_t eights; + CSA(eights, fours, fours, foursA, foursB); - int64_t foursA = twos & twosA; - twos = twos ^ twosA; + tot8 += pop(eights); + } - int64_t eights = fours & foursA; - fours = fours ^ foursA; + if (i <= n - 4) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); - tot8 += pop(eights); - i += 2; - } + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] & ~B[i + 2]), (A[i + 3] & ~B[i + 3])); - if (i < n) - tot += pop((A[i] & ~B[i])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - return tot; + tot8 += pop(eights); + i += 4; } - int64_t BitUtil::pop_xor(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) - { - int32_t n = wordOffset + numWords; - int64_t tot = 0; - int64_t tot8 = 0; - int64_t ones = 0; - int64_t twos = 0; - int64_t fours = 0; + if (i <= n - 2) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i + 1] & ~B[i + 1])); - int32_t i = wordOffset; - for (; i <= n - 8; i += 8) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); + int64_t foursA = twos & twosA; + twos = twos ^ twosA; - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] ^ B[i + 2]), (A[i + 3] ^ B[i + 3])); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + tot8 += pop(eights); + i += 2; + } - CSA(twosA, ones, ones, (A[i + 4] ^ B[i + 4]), (A[i + 5] ^ B[i + 5])); + if (i < n) { + tot += pop((A[i] & ~B[i])); + } - CSA(twosB, ones, ones, (A[i + 6] ^ B[i + 6]), (A[i + 7] ^ B[i + 7])); + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - int64_t foursB; - CSA(foursB, twos, twos, twosA, twosB); + return tot; +} - int64_t eights; - CSA(eights, fours, fours, foursA, foursB); +int64_t BitUtil::pop_xor(const int64_t* A, const int64_t* B, int32_t wordOffset, int32_t numWords) { + int32_t n = wordOffset + numWords; + int64_t tot = 0; + int64_t tot8 = 0; + int64_t ones = 0; + int64_t twos = 0; + int64_t fours = 0; - tot8 += pop(eights); - } + int32_t i = wordOffset; + for (; i <= n - 8; i += 8) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); - if (i <= n - 4) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] ^ B[i + 2]), (A[i + 3] ^ B[i + 3])); - int64_t twosB; - CSA(twosB, ones, ones, (A[i + 2] ^ B[i + 2]), (A[i + 3] ^ B[i + 3])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - int64_t foursA; - CSA(foursA, twos, twos, twosA, twosB); + CSA(twosA, ones, ones, (A[i + 4] ^ B[i + 4]), (A[i + 5] ^ B[i + 5])); - int64_t eights = fours & foursA; - fours = fours ^ foursA; + CSA(twosB, ones, ones, (A[i + 6] ^ B[i + 6]), (A[i + 7] ^ B[i + 7])); - tot8 += pop(eights); - i += 4; - } + int64_t foursB; + CSA(foursB, twos, twos, twosA, twosB); - if (i <= n - 2) - { - int64_t twosA; - CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); + int64_t eights; + CSA(eights, fours, fours, foursA, foursB); - int64_t foursA = twos & twosA; - twos = twos ^ twosA; + tot8 += pop(eights); + } - int64_t eights = fours & foursA; - fours = fours ^ foursA; + if (i <= n - 4) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); - tot8 += pop(eights); - i += 2; - } + int64_t twosB; + CSA(twosB, ones, ones, (A[i + 2] ^ B[i + 2]), (A[i + 3] ^ B[i + 3])); - if (i < n) - tot += pop((A[i] ^ B[i])); + int64_t foursA; + CSA(foursA, twos, twos, twosA, twosB); - tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); + int64_t eights = fours & foursA; + fours = fours ^ foursA; - return tot; + tot8 += pop(eights); + i += 4; } - void BitUtil::CSA(int64_t& h, int64_t& l, int64_t a, int64_t b, int64_t c) - { - int64_t u = a ^ b; - h = (a & b) | (u & c); - l = u ^ c; - } + if (i <= n - 2) { + int64_t twosA; + CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i + 1] ^ B[i + 1])); - int32_t BitUtil::ntz(int64_t val) - { - // A full binary search to determine the low byte was slower than a linear search for nextSetBit(). - // This is most likely because the implementation of nextSetBit() shifts bits to the right, increasing - // the probability that the first non-zero byte is in the rhs. + int64_t foursA = twos & twosA; + twos = twos ^ twosA; - // This implementation does a single binary search at the top level only so that all other bit shifting - // can be done on ints instead of longs to remain friendly to 32 bit architectures. In addition, the - // case of a non-zero first byte is checked for first because it is the most common in dense bit arrays. + int64_t eights = fours & foursA; + fours = fours ^ foursA; - int32_t lower = (int32_t)val; - int32_t lowByte = lower & 0xff; - if (lowByte != 0) - return ntzTable[lowByte]; + tot8 += pop(eights); + i += 2; + } - if (lower != 0) - { - lowByte = MiscUtils::unsignedShift(lower, 8) & 0xff; - if (lowByte != 0) - return ntzTable[lowByte] + 8; - lowByte = MiscUtils::unsignedShift(lower, 16) & 0xff; - if (lowByte != 0) - return ntzTable[lowByte] + 16; - // no need to mask off low byte for the last byte in the 32 bit word - // no need to check for zero on the last byte either. - return ntzTable[MiscUtils::unsignedShift(lower, 24)] + 24; - } - else - { - // grab upper 32 bits - int32_t upper = (int32_t)(val >> 32); - lowByte = upper & 0xff; - if (lowByte != 0) - return ntzTable[lowByte] + 32; - lowByte = MiscUtils::unsignedShift(upper, 8) & 0xff; - if (lowByte != 0) - return ntzTable[lowByte] + 40; - lowByte = MiscUtils::unsignedShift(upper, 16) & 0xff; - if (lowByte != 0) - return ntzTable[lowByte] + 48; - // no need to mask off low byte for the last byte in the 32 bit word - // no need to check for zero on the last byte either. - return ntzTable[MiscUtils::unsignedShift(upper, 24)] + 56; - } + if (i < n) { + tot += pop((A[i] ^ B[i])); } - int32_t BitUtil::ntz(int32_t val) - { - // This implementation does a single binary search at the top level only. In addition, the case - // of a non-zero first byte is checked for first because it is the most common in dense bit arrays. + tot += (pop(fours) << 2) + (pop(twos) << 1) + pop(ones) + (tot8 << 3); - int32_t lowByte = val & 0xff; - if (lowByte != 0) - return ntzTable[lowByte]; - lowByte = MiscUtils::unsignedShift(val, 8) & 0xff; - if (lowByte != 0) - return ntzTable[lowByte] + 8; - lowByte = MiscUtils::unsignedShift(val, 16) & 0xff; - if (lowByte != 0) - return ntzTable[lowByte] + 16; - // no need to mask off low byte for the last byte. - // no need to check for zero on the last byte either. - return ntzTable[MiscUtils::unsignedShift(val, 24)] + 24; - } + return tot; +} - int32_t BitUtil::ntz2(int64_t x) - { - int32_t n = 0; - int32_t y = (int32_t)x; - if (y == 0) // the only 64 bit shift necessary - { - n += 32; - y = (int32_t)MiscUtils::unsignedShift(x, (int64_t)32); - } - if ((y & 0x0000ffff) == 0) - { - n += 16; - y = MiscUtils::unsignedShift(y, 16); - } - if ((y & 0x000000ff) == 0) - { - n += 8; - y = MiscUtils::unsignedShift(y, 8); - } - return (ntzTable[y & 0xff]) + n; - } +void BitUtil::CSA(int64_t& h, int64_t& l, int64_t a, int64_t b, int64_t c) { + int64_t u = a ^ b; + h = (a & b) | (u & c); + l = u ^ c; +} - int32_t BitUtil::ntz3(int64_t x) - { - int32_t n = 1; +int32_t BitUtil::ntz(int64_t val) { + // A full binary search to determine the low byte was slower than a linear search for nextSetBit(). + // This is most likely because the implementation of nextSetBit() shifts bits to the right, increasing + // the probability that the first non-zero byte is in the rhs. - // do the first step as a long, all others as ints. - int32_t y = (int32_t)x; - if (y == 0) - { - n += 32; - y = (int32_t)MiscUtils::unsignedShift(x, (int64_t)32); + // This implementation does a single binary search at the top level only so that all other bit shifting + // can be done on ints instead of longs to remain friendly to 32 bit architectures. In addition, the + // case of a non-zero first byte is checked for first because it is the most common in dense bit arrays. + + int32_t lower = (int32_t)val; + int32_t lowByte = lower & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte]; + } + + if (lower != 0) { + lowByte = MiscUtils::unsignedShift(lower, 8) & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte] + 8; } - if ((y & 0x0000ffff) == 0) - { - n += 16; - y = MiscUtils::unsignedShift(y, 16); + lowByte = MiscUtils::unsignedShift(lower, 16) & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte] + 16; } - if ((y & 0x000000ff) == 0) - { - n += 8; - y = MiscUtils::unsignedShift(y, 8); + // no need to mask off low byte for the last byte in the 32 bit word + // no need to check for zero on the last byte either. + return ntzTable[MiscUtils::unsignedShift(lower, 24)] + 24; + } else { + // grab upper 32 bits + int32_t upper = (int32_t)(val >> 32); + lowByte = upper & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte] + 32; } - if ((y & 0x0000000f) == 0) - { - n += 4; - y = MiscUtils::unsignedShift(y, 4); + lowByte = MiscUtils::unsignedShift(upper, 8) & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte] + 40; } - if ((y & 0x00000003) == 0) - { - n += 2; - y = MiscUtils::unsignedShift(y, 2); + lowByte = MiscUtils::unsignedShift(upper, 16) & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte] + 48; } - return n - (y & 1); + // no need to mask off low byte for the last byte in the 32 bit word + // no need to check for zero on the last byte either. + return ntzTable[MiscUtils::unsignedShift(upper, 24)] + 56; } +} - bool BitUtil::isPowerOfTwo(int32_t v) - { - return ((v & (v - 1)) == 0); - } +int32_t BitUtil::ntz(int32_t val) { + // This implementation does a single binary search at the top level only. In addition, the case + // of a non-zero first byte is checked for first because it is the most common in dense bit arrays. - bool BitUtil::isPowerOfTwo(int64_t v) - { - return ((v & (v - 1)) == 0); + int32_t lowByte = val & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte]; + } + lowByte = MiscUtils::unsignedShift(val, 8) & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte] + 8; } + lowByte = MiscUtils::unsignedShift(val, 16) & 0xff; + if (lowByte != 0) { + return ntzTable[lowByte] + 16; + } + // no need to mask off low byte for the last byte. + // no need to check for zero on the last byte either. + return ntzTable[MiscUtils::unsignedShift(val, 24)] + 24; +} - int32_t BitUtil::nextHighestPowerOfTwo(int32_t v) - { - --v; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return ++v; +int32_t BitUtil::ntz2(int64_t x) { + int32_t n = 0; + int32_t y = (int32_t)x; + if (y == 0) { // the only 64 bit shift necessary + n += 32; + y = (int32_t)MiscUtils::unsignedShift(x, (int64_t)32); + } + if ((y & 0x0000ffff) == 0) { + n += 16; + y = MiscUtils::unsignedShift(y, 16); } + if ((y & 0x000000ff) == 0) { + n += 8; + y = MiscUtils::unsignedShift(y, 8); + } + return (ntzTable[y & 0xff]) + n; +} - int64_t BitUtil::nextHighestPowerOfTwo(int64_t v) - { - --v; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - return ++v; +int32_t BitUtil::ntz3(int64_t x) { + int32_t n = 1; + + // do the first step as a long, all others as ints. + int32_t y = (int32_t)x; + if (y == 0) { + n += 32; + y = (int32_t)MiscUtils::unsignedShift(x, (int64_t)32); + } + if ((y & 0x0000ffff) == 0) { + n += 16; + y = MiscUtils::unsignedShift(y, 16); + } + if ((y & 0x000000ff) == 0) { + n += 8; + y = MiscUtils::unsignedShift(y, 8); + } + if ((y & 0x0000000f) == 0) { + n += 4; + y = MiscUtils::unsignedShift(y, 4); + } + if ((y & 0x00000003) == 0) { + n += 2; + y = MiscUtils::unsignedShift(y, 2); } + return n - (y & 1); +} + +bool BitUtil::isPowerOfTwo(int32_t v) { + return ((v & (v - 1)) == 0); +} + +bool BitUtil::isPowerOfTwo(int64_t v) { + return ((v & (v - 1)) == 0); +} + +int32_t BitUtil::nextHighestPowerOfTwo(int32_t v) { + --v; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return ++v; +} + +int64_t BitUtil::nextHighestPowerOfTwo(int64_t v) { + --v; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + return ++v; +} + } diff --git a/src/core/util/BitVector.cpp b/src/core/util/BitVector.cpp index 683a4524..dbd59974 100644 --- a/src/core/util/BitVector.cpp +++ b/src/core/util/BitVector.cpp @@ -12,245 +12,228 @@ #include "TestPoint.h" #include "MiscUtils.h" -namespace Lucene -{ - const uint8_t BitVector::BYTE_COUNTS[] = - { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 - }; - - BitVector::BitVector(int32_t n) - { - _size = n; - bits = ByteArray::newInstance((_size >> 3) + 1); - MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); - _count = 0; - } +namespace Lucene { + +const uint8_t BitVector::BYTE_COUNTS[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +BitVector::BitVector(int32_t n) { + _size = n; + bits = ByteArray::newInstance((_size >> 3) + 1); + MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); + _count = 0; +} - BitVector::BitVector(ByteArray bits, int32_t size) - { - this->bits = bits; - this->_size = size; - this->_count = -1; - } +BitVector::BitVector(ByteArray bits, int32_t size) { + this->bits = bits; + this->_size = size; + this->_count = -1; +} - BitVector::BitVector(const DirectoryPtr& d, const String& name) - { - IndexInputPtr input(d->openInput(name)); - LuceneException finally; - try - { - _size = input->readInt(); // read size - if (_size == -1) - readDgaps(input); - else - readBits(input); - } - catch (LuceneException& e) - { - finally = e; +BitVector::BitVector(const DirectoryPtr& d, const String& name) { + IndexInputPtr input(d->openInput(name)); + LuceneException finally; + try { + _size = input->readInt(); // read size + if (_size == -1) { + readDgaps(input); + } else { + readBits(input); } - input->close(); - finally.throwException(); + } catch (LuceneException& e) { + finally = e; } + input->close(); + finally.throwException(); +} - BitVector::~BitVector() - { - } +BitVector::~BitVector() { +} - LuceneObjectPtr BitVector::clone(const LuceneObjectPtr& other) - { - ByteArray copyBits(ByteArray::newInstance(bits.size())); - MiscUtils::arrayCopy(bits.get(), 0, copyBits.get(), 0, bits.size()); - BitVectorPtr clone = newLucene(copyBits, _size); - clone->_count = _count; - return clone; - } +LuceneObjectPtr BitVector::clone(const LuceneObjectPtr& other) { + ByteArray copyBits(ByteArray::newInstance(bits.size())); + MiscUtils::arrayCopy(bits.get(), 0, copyBits.get(), 0, bits.size()); + BitVectorPtr clone = newLucene(copyBits, _size); + clone->_count = _count; + return clone; +} - void BitVector::set(int32_t bit) - { - if (bit >= _size) - boost::throw_exception(IndexOutOfBoundsException()); - bits[bit >> 3] |= 1 << (bit & 7); - _count = -1; +void BitVector::set(int32_t bit) { + if (bit >= _size) { + boost::throw_exception(IndexOutOfBoundsException()); } + bits[bit >> 3] |= 1 << (bit & 7); + _count = -1; +} - bool BitVector::getAndSet(int32_t bit) - { - if (bit >= _size) - boost::throw_exception(IndexOutOfBoundsException()); - int32_t pos = (bit >> 3); - int32_t v = bits[pos]; - int32_t flag = 1 << (bit & 7); - if ((flag & v) != 0) - return true; - else - { - bits[pos] = (uint8_t)(v | flag); - if (_count != -1) - ++_count; - return false; +bool BitVector::getAndSet(int32_t bit) { + if (bit >= _size) { + boost::throw_exception(IndexOutOfBoundsException()); + } + int32_t pos = (bit >> 3); + int32_t v = bits[pos]; + int32_t flag = 1 << (bit & 7); + if ((flag & v) != 0) { + return true; + } else { + bits[pos] = (uint8_t)(v | flag); + if (_count != -1) { + ++_count; } + return false; } +} - void BitVector::clear(int32_t bit) - { - if (bit >= _size) - boost::throw_exception(IndexOutOfBoundsException()); - bits[bit >> 3] &= ~(1 << (bit & 7)); - _count = -1; +void BitVector::clear(int32_t bit) { + if (bit >= _size) { + boost::throw_exception(IndexOutOfBoundsException()); } + bits[bit >> 3] &= ~(1 << (bit & 7)); + _count = -1; +} - bool BitVector::get(int32_t bit) - { - BOOST_ASSERT(bit >= 0 && bit < _size); - return (bits[bit >> 3] & (1 << (bit & 7))) != 0; - } +bool BitVector::get(int32_t bit) { + BOOST_ASSERT(bit >= 0 && bit < _size); + return (bits[bit >> 3] & (1 << (bit & 7))) != 0; +} - int32_t BitVector::size() - { - return _size; - } +int32_t BitVector::size() { + return _size; +} - int32_t BitVector::count() - { - // if the vector has been modified - if (_count == -1) - { - int32_t c = 0; - int32_t end = bits.size(); - for (int32_t i = 0; i < end; ++i) - c += BYTE_COUNTS[bits[i] & 0xff]; // sum bits per byte - _count = c; +int32_t BitVector::count() { + // if the vector has been modified + if (_count == -1) { + int32_t c = 0; + int32_t end = bits.size(); + for (int32_t i = 0; i < end; ++i) { + c += BYTE_COUNTS[bits[i] & 0xff]; // sum bits per byte } - return _count; + _count = c; } + return _count; +} - int32_t BitVector::getRecomputedCount() - { - int32_t c = 0; - int32_t end = bits.size(); - for (int32_t i = 0; i < end; ++i) - c += BYTE_COUNTS[bits[i] & 0xff]; // sum bits per byte - return c; +int32_t BitVector::getRecomputedCount() { + int32_t c = 0; + int32_t end = bits.size(); + for (int32_t i = 0; i < end; ++i) { + c += BYTE_COUNTS[bits[i] & 0xff]; // sum bits per byte } + return c; +} - void BitVector::write(const DirectoryPtr& d, const String& name) - { - TestScope testScope(L"BitVector", L"write"); - IndexOutputPtr output(d->createOutput(name)); - LuceneException finally; - try - { - if (isSparse()) - writeDgaps(output); // sparse bit-set more efficiently saved as d-gaps. - else - writeBits(output); +void BitVector::write(const DirectoryPtr& d, const String& name) { + TestScope testScope(L"BitVector", L"write"); + IndexOutputPtr output(d->createOutput(name)); + LuceneException finally; + try { + if (isSparse()) { + writeDgaps(output); // sparse bit-set more efficiently saved as d-gaps. + } else { + writeBits(output); } - catch (LuceneException& e) - { - finally = e; - } - output->close(); - finally.throwException(); + } catch (LuceneException& e) { + finally = e; } + output->close(); + finally.throwException(); +} - void BitVector::writeBits(const IndexOutputPtr& output) - { - output->writeInt(size()); // write size - output->writeInt(count()); // write count - output->writeBytes(bits.get(), bits.size()); - } +void BitVector::writeBits(const IndexOutputPtr& output) { + output->writeInt(size()); // write size + output->writeInt(count()); // write count + output->writeBytes(bits.get(), bits.size()); +} - void BitVector::writeDgaps(const IndexOutputPtr& output) - { - output->writeInt(-1); // mark using d-gaps - output->writeInt(size()); // write size - output->writeInt(count()); // write count - int32_t last = 0; - int32_t n = count(); - int32_t m = bits.size(); - for (int32_t i = 0; i < m && n > 0; ++i) - { - if (bits[i] != 0) - { - output->writeVInt(i-last); - output->writeByte(bits[i]); - last = i; - n -= BYTE_COUNTS[bits[i] & 0xff]; - } +void BitVector::writeDgaps(const IndexOutputPtr& output) { + output->writeInt(-1); // mark using d-gaps + output->writeInt(size()); // write size + output->writeInt(count()); // write count + int32_t last = 0; + int32_t n = count(); + int32_t m = bits.size(); + for (int32_t i = 0; i < m && n > 0; ++i) { + if (bits[i] != 0) { + output->writeVInt(i-last); + output->writeByte(bits[i]); + last = i; + n -= BYTE_COUNTS[bits[i] & 0xff]; } } +} - bool BitVector::isSparse() - { - // note: order of comparisons below set to favor smaller values (no binary range search.) - // note: adding 4 because we start with ((int) -1) to indicate d-gaps format. - // note: we write the d-gap for the byte number, and the byte (bits[i]) itself, therefore - // multiplying count by (8+8) or (8+16) or (8+24) etc.: - // - first 8 for writing bits[i] (1 byte vs. 1 bit), and - // - second part for writing the byte-number d-gap as vint. - // note: factor is for read/write of byte-arrays being faster than vints. - int32_t factor = 10; - if (bits.size() < (1 << 7)) - return factor * (4 + (8 + 8) * count()) < size(); - if (bits.size() < (1 << 14)) - return factor * (4 + (8 + 16) * count()) < size(); - if (bits.size() < (1 << 21)) - return factor * (4 + (8 + 24) * count()) < size(); - if (bits.size() < (1 << 28)) - return factor * (4 + (8 + 32) * count()) < size(); - return factor * (4 + (8 + 40) * count()) < size(); +bool BitVector::isSparse() { + // note: order of comparisons below set to favor smaller values (no binary range search.) + // note: adding 4 because we start with ((int) -1) to indicate d-gaps format. + // note: we write the d-gap for the byte number, and the byte (bits[i]) itself, therefore + // multiplying count by (8+8) or (8+16) or (8+24) etc.: + // - first 8 for writing bits[i] (1 byte vs. 1 bit), and + // - second part for writing the byte-number d-gap as vint. + // note: factor is for read/write of byte-arrays being faster than vints. + int32_t factor = 10; + if (bits.size() < (1 << 7)) { + return factor * (4 + (8 + 8) * count()) < size(); } - - void BitVector::readBits(const IndexInputPtr& input) - { - _count = input->readInt(); // read count - bits = ByteArray::newInstance((_size >> 3) + 1); // allocate bits - MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); - input->readBytes(bits.get(), 0, bits.size()); + if (bits.size() < (1 << 14)) { + return factor * (4 + (8 + 16) * count()) < size(); + } + if (bits.size() < (1 << 21)) { + return factor * (4 + (8 + 24) * count()) < size(); + } + if (bits.size() < (1 << 28)) { + return factor * (4 + (8 + 32) * count()) < size(); } + return factor * (4 + (8 + 40) * count()) < size(); +} - void BitVector::readDgaps(const IndexInputPtr& input) - { - _size = input->readInt(); // (re)read size - _count = input->readInt(); // read count - bits = ByteArray::newInstance((_size >> 3) + 1); // allocate bits - MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); - int32_t last = 0; - int32_t n = count(); - while (n > 0) - { - last += input->readVInt(); - bits[last] = input->readByte(); - n -= BYTE_COUNTS[bits[last] & 0xff]; - } +void BitVector::readBits(const IndexInputPtr& input) { + _count = input->readInt(); // read count + bits = ByteArray::newInstance((_size >> 3) + 1); // allocate bits + MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); + input->readBytes(bits.get(), 0, bits.size()); +} + +void BitVector::readDgaps(const IndexInputPtr& input) { + _size = input->readInt(); // (re)read size + _count = input->readInt(); // read count + bits = ByteArray::newInstance((_size >> 3) + 1); // allocate bits + MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0); + int32_t last = 0; + int32_t n = count(); + while (n > 0) { + last += input->readVInt(); + bits[last] = input->readByte(); + n -= BYTE_COUNTS[bits[last] & 0xff]; } +} - BitVectorPtr BitVector::subset(int32_t start, int32_t end) - { - if (start < 0 || end > size() || end < start) - boost::throw_exception(IndexOutOfBoundsException()); - // Special case -- return empty vector is start == end - if (end == start) - return newLucene(0); - ByteArray bits(ByteArray::newInstance(MiscUtils::unsignedShift(end - start - 1, 3) + 1)); - int32_t s = MiscUtils::unsignedShift(start, 3); - for (int32_t i = 0; i < bits.size(); ++i) - { - int32_t cur = 0xff & this->bits[i + s]; - int32_t next = i + s + 1 >= this->bits.size() ? 0 : 0xff & this->bits[i + s + 1]; - bits[i] = (uint8_t)(MiscUtils::unsignedShift(cur, (start & 7)) | ((next << (8 - (start & 7))))); - } - int32_t bitsToClear = (bits.size() * 8 - (end - start)) % 8; - bits[bits.size() - 1] &= ~(0xff << (8 - bitsToClear)); - return newLucene(bits, end - start); +BitVectorPtr BitVector::subset(int32_t start, int32_t end) { + if (start < 0 || end > size() || end < start) { + boost::throw_exception(IndexOutOfBoundsException()); + } + // Special case -- return empty vector is start == end + if (end == start) { + return newLucene(0); + } + ByteArray bits(ByteArray::newInstance(MiscUtils::unsignedShift(end - start - 1, 3) + 1)); + int32_t s = MiscUtils::unsignedShift(start, 3); + for (int32_t i = 0; i < bits.size(); ++i) { + int32_t cur = 0xff & this->bits[i + s]; + int32_t next = i + s + 1 >= this->bits.size() ? 0 : 0xff & this->bits[i + s + 1]; + bits[i] = (uint8_t)(MiscUtils::unsignedShift(cur, (start & 7)) | ((next << (8 - (start & 7))))); } + int32_t bitsToClear = (bits.size() * 8 - (end - start)) % 8; + bits[bits.size() - 1] &= ~(0xff << (8 - bitsToClear)); + return newLucene(bits, end - start); +} + } diff --git a/src/core/util/BufferedReader.cpp b/src/core/util/BufferedReader.cpp index 368954af..84aa130e 100644 --- a/src/core/util/BufferedReader.cpp +++ b/src/core/util/BufferedReader.cpp @@ -8,118 +8,105 @@ #include "BufferedReader.h" #include "MiscUtils.h" -namespace Lucene -{ - const int32_t BufferedReader::READER_BUFFER = 8192; - - BufferedReader::BufferedReader(const ReaderPtr& reader, int32_t size) - { - this->reader = reader; - this->bufferSize = size; - this->bufferLength = 0; - this->bufferPosition = 0; - } +namespace Lucene { - BufferedReader::~BufferedReader() - { - } +const int32_t BufferedReader::READER_BUFFER = 8192; - int32_t BufferedReader::read() - { - if (bufferPosition >= bufferLength) - { - if (refill() == READER_EOF) - return READER_EOF; - } - return buffer[bufferPosition++]; - } +BufferedReader::BufferedReader(const ReaderPtr& reader, int32_t size) { + this->reader = reader; + this->bufferSize = size; + this->bufferLength = 0; + this->bufferPosition = 0; +} - int32_t BufferedReader::peek() - { - if (bufferPosition >= bufferLength) - { - if (refill() == READER_EOF) - return READER_EOF; +BufferedReader::~BufferedReader() { +} + +int32_t BufferedReader::read() { + if (bufferPosition >= bufferLength) { + if (refill() == READER_EOF) { + return READER_EOF; } - return buffer[bufferPosition]; } + return buffer[bufferPosition++]; +} - int32_t BufferedReader::read(wchar_t* b, int32_t offset, int32_t length) - { - if (length == 0) - return 0; - - int32_t remaining = length; - - while (remaining > 0) - { - int32_t available = bufferLength - bufferPosition; - - if (remaining <= available) - { - // the buffer contains enough data to satisfy this request - MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, remaining); - bufferPosition += remaining; - remaining = 0; - } - else if (available > 0) - { - // the buffer does not have enough data, first serve all we've got - MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, available); - bufferPosition += available; - offset += available; - remaining -= available; - } - else if (refill() == READER_EOF) - { - length -= remaining; - break; - } +int32_t BufferedReader::peek() { + if (bufferPosition >= bufferLength) { + if (refill() == READER_EOF) { + return READER_EOF; } + } + return buffer[bufferPosition]; +} - return length == 0 ? READER_EOF : length; +int32_t BufferedReader::read(wchar_t* b, int32_t offset, int32_t length) { + if (length == 0) { + return 0; } - bool BufferedReader::readLine(String& line) - { - line.clear(); - wchar_t ch = (wchar_t)read(); - while (ch != (wchar_t)READER_EOF && ch != L'\r' && ch != L'\n') - { - line += ch; - ch = (wchar_t)read(); + int32_t remaining = length; + + while (remaining > 0) { + int32_t available = bufferLength - bufferPosition; + + if (remaining <= available) { + // the buffer contains enough data to satisfy this request + MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, remaining); + bufferPosition += remaining; + remaining = 0; + } else if (available > 0) { + // the buffer does not have enough data, first serve all we've got + MiscUtils::arrayCopy(buffer.get(), bufferPosition, b, offset, available); + bufferPosition += available; + offset += available; + remaining -= available; + } else if (refill() == READER_EOF) { + length -= remaining; + break; } - if (ch == '\r' && (wchar_t)peek() == L'\n') - read(); - return (!line.empty() || ch != (wchar_t)READER_EOF); } - int32_t BufferedReader::refill() - { - if (!buffer) - buffer = CharArray::newInstance(bufferSize); // allocate buffer lazily - int32_t readLength = reader->read(buffer.get(), 0, bufferSize); - bufferLength = readLength == READER_EOF ? 0 : readLength; - bufferPosition = 0; - return readLength; - } + return length == 0 ? READER_EOF : length; +} - void BufferedReader::close() - { - reader->close(); - bufferLength = 0; - bufferPosition = 0; +bool BufferedReader::readLine(String& line) { + line.clear(); + wchar_t ch = (wchar_t)read(); + while (ch != (wchar_t)READER_EOF && ch != L'\r' && ch != L'\n') { + line += ch; + ch = (wchar_t)read(); } - - bool BufferedReader::markSupported() - { - return false; + if (ch == '\r' && (wchar_t)peek() == L'\n') { + read(); } + return (!line.empty() || ch != (wchar_t)READER_EOF); +} - void BufferedReader::reset() - { - reader->reset(); - bufferLength = 0; - bufferPosition = 0; +int32_t BufferedReader::refill() { + if (!buffer) { + buffer = CharArray::newInstance(bufferSize); // allocate buffer lazily } + int32_t readLength = reader->read(buffer.get(), 0, bufferSize); + bufferLength = readLength == READER_EOF ? 0 : readLength; + bufferPosition = 0; + return readLength; +} + +void BufferedReader::close() { + reader->close(); + bufferLength = 0; + bufferPosition = 0; +} + +bool BufferedReader::markSupported() { + return false; +} + +void BufferedReader::reset() { + reader->reset(); + bufferLength = 0; + bufferPosition = 0; +} + } diff --git a/src/core/util/CharFolder.cpp b/src/core/util/CharFolder.cpp index f0b73e7b..933178f8 100644 --- a/src/core/util/CharFolder.cpp +++ b/src/core/util/CharFolder.cpp @@ -9,38 +9,36 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - bool CharFolder::lowerCache = CharFolder::fillLower(); - bool CharFolder::upperCache = CharFolder::fillUpper(); - wchar_t CharFolder::lowerChars[CHAR_MAX - CHAR_MIN + 1]; - wchar_t CharFolder::upperChars[CHAR_MAX - CHAR_MIN + 1]; - - CharFolder::~CharFolder() - { - } +namespace Lucene { - wchar_t CharFolder::toLower(wchar_t ch) - { - return (ch > CHAR_MIN && ch < CHAR_MAX) ? lowerChars[ch - CHAR_MIN] : UnicodeUtil::toLower(ch); - } +bool CharFolder::lowerCache = CharFolder::fillLower(); +bool CharFolder::upperCache = CharFolder::fillUpper(); +wchar_t CharFolder::lowerChars[CHAR_MAX - CHAR_MIN + 1]; +wchar_t CharFolder::upperChars[CHAR_MAX - CHAR_MIN + 1]; - wchar_t CharFolder::toUpper(wchar_t ch) - { - return (ch > CHAR_MIN && ch < CHAR_MAX) ? upperChars[ch - CHAR_MIN] : UnicodeUtil::toUpper(ch); - } +CharFolder::~CharFolder() { +} + +wchar_t CharFolder::toLower(wchar_t ch) { + return (ch > CHAR_MIN && ch < CHAR_MAX) ? lowerChars[ch - CHAR_MIN] : UnicodeUtil::toLower(ch); +} - bool CharFolder::fillLower() - { - for (int32_t index = CHAR_MIN; index < CHAR_MAX; ++index) - lowerChars[index - CHAR_MIN] = UnicodeUtil::toLower((wchar_t)index); - return true; +wchar_t CharFolder::toUpper(wchar_t ch) { + return (ch > CHAR_MIN && ch < CHAR_MAX) ? upperChars[ch - CHAR_MIN] : UnicodeUtil::toUpper(ch); +} + +bool CharFolder::fillLower() { + for (int32_t index = CHAR_MIN; index < CHAR_MAX; ++index) { + lowerChars[index - CHAR_MIN] = UnicodeUtil::toLower((wchar_t)index); } + return true; +} - bool CharFolder::fillUpper() - { - for (int32_t index = CHAR_MIN; index < CHAR_MAX; ++index) - upperChars[index - CHAR_MIN] = UnicodeUtil::toUpper((wchar_t)index); - return true; +bool CharFolder::fillUpper() { + for (int32_t index = CHAR_MIN; index < CHAR_MAX; ++index) { + upperChars[index - CHAR_MIN] = UnicodeUtil::toUpper((wchar_t)index); } + return true; +} + } diff --git a/src/core/util/Collator.cpp b/src/core/util/Collator.cpp index b46cdd34..e841b1e5 100644 --- a/src/core/util/Collator.cpp +++ b/src/core/util/Collator.cpp @@ -8,18 +8,16 @@ #include #include "Collator.h" -namespace Lucene -{ - Collator::Collator(std::locale locale) : collate(std::use_facet< std::collate >(locale)) - { - } +namespace Lucene { - Collator::~Collator() - { - } +Collator::Collator(std::locale locale) : collate(std::use_facet< std::collate >(locale)) { +} + +Collator::~Collator() { +} + +int32_t Collator::compare(const String& first, const String& second) { + return collate.compare(first.c_str(), first.c_str() + first.length(), second.c_str(), second.c_str() + second.length()); +} - int32_t Collator::compare(const String& first, const String& second) - { - return collate.compare(first.c_str(), first.c_str() + first.length(), second.c_str(), second.c_str() + second.length()); - } } diff --git a/src/core/util/Constants.cpp b/src/core/util/Constants.cpp index 9be563b3..07898160 100644 --- a/src/core/util/Constants.cpp +++ b/src/core/util/Constants.cpp @@ -7,43 +7,39 @@ #include "LuceneInc.h" #include "Constants.h" -namespace Lucene -{ - #if defined(linux) || defined(__linux) || defined(__linux__) - String Constants::OS_NAME = L"Linux"; - #elif defined(sun) || defined(__sun) - String Constants::OS_NAME = L"Sun"; - #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(_WIN64) || defined(__WIN64__) || defined(WIN64) - String Constants::OS_NAME = L"Windows"; - #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) - String Constants::OS_NAME = L"Mac"; - #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) - String Constants::OS_NAME = L"BSD"; - #endif - - String Constants::LUCENE_MAIN_VERSION = L"3.0.5"; - String Constants::LUCENE_VERSION = L"3.0.5"; - - Constants::Constants() - { - // private - } - - Constants::~Constants() - { - } - - LuceneVersion::LuceneVersion() - { - // private - } - - LuceneVersion::~LuceneVersion() - { - } - - bool LuceneVersion::onOrAfter(LuceneVersion::Version first, LuceneVersion::Version second) - { - return (first >= second); - } +namespace Lucene { + +#if defined(linux) || defined(__linux) || defined(__linux__) +String Constants::OS_NAME = L"Linux"; +#elif defined(sun) || defined(__sun) +String Constants::OS_NAME = L"Sun"; +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(_WIN64) || defined(__WIN64__) || defined(WIN64) +String Constants::OS_NAME = L"Windows"; +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +String Constants::OS_NAME = L"Mac"; +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +String Constants::OS_NAME = L"BSD"; +#endif + +String Constants::LUCENE_MAIN_VERSION = L"3.0.5"; +String Constants::LUCENE_VERSION = L"3.0.5"; + +Constants::Constants() { + // private +} + +Constants::~Constants() { +} + +LuceneVersion::LuceneVersion() { + // private +} + +LuceneVersion::~LuceneVersion() { +} + +bool LuceneVersion::onOrAfter(LuceneVersion::Version first, LuceneVersion::Version second) { + return (first >= second); +} + } diff --git a/src/core/util/CycleCheck.cpp b/src/core/util/CycleCheck.cpp index 63148e77..60349c2b 100644 --- a/src/core/util/CycleCheck.cpp +++ b/src/core/util/CycleCheck.cpp @@ -8,65 +8,60 @@ #include #include "CycleCheck.h" -namespace Lucene -{ - MapStringInt CycleCheck::cycleMap; - Set CycleCheck::staticRefs; +namespace Lucene { - CycleCheck::~CycleCheck() - { - } +MapStringInt CycleCheck::cycleMap; +Set CycleCheck::staticRefs; - void CycleCheck::addRef(const String& className, int32_t ref) - { - if (!cycleMap) - cycleMap = MapStringInt::newInstance(); - SyncLock lockRef(&cycleMap); - MapStringInt::iterator classRef = cycleMap.find(className); - if (classRef == cycleMap.end()) - cycleMap.put(className, 1); - else - { - classRef->second += ref; - if (classRef->second < 0) - boost::throw_exception(RuntimeException(L"invalid class reference")); +CycleCheck::~CycleCheck() { +} + +void CycleCheck::addRef(const String& className, int32_t ref) { + if (!cycleMap) { + cycleMap = MapStringInt::newInstance(); + } + SyncLock lockRef(&cycleMap); + MapStringInt::iterator classRef = cycleMap.find(className); + if (classRef == cycleMap.end()) { + cycleMap.put(className, 1); + } else { + classRef->second += ref; + if (classRef->second < 0) { + boost::throw_exception(RuntimeException(L"invalid class reference")); } } +} - void CycleCheck::addStatic(LuceneObjectPtr* staticRef) - { - #ifdef LPP_USE_CYCLIC_CHECK - if (!staticRefs) - staticRefs = Set::newInstance(); - staticRefs.add(staticRef); - #endif +void CycleCheck::addStatic(LuceneObjectPtr* staticRef) { +#ifdef LPP_USE_CYCLIC_CHECK + if (!staticRefs) { + staticRefs = Set::newInstance(); } + staticRefs.add(staticRef); +#endif +} - void CycleCheck::dumpRefs() - { - // destroy all registered statics - if (staticRefs) - { - for (Set::iterator staticRef = staticRefs.begin(); staticRef != staticRefs.end(); ++staticRef) - (*staticRef)->reset(); +void CycleCheck::dumpRefs() { + // destroy all registered statics + if (staticRefs) { + for (Set::iterator staticRef = staticRefs.begin(); staticRef != staticRefs.end(); ++staticRef) { + (*staticRef)->reset(); } + } - if (cycleMap) - { - SyncLock lockRef(&cycleMap); - bool reportCycles = true; - for (MapStringInt::iterator classRef = cycleMap.begin(); classRef != cycleMap.end(); ++classRef) - { - if (classRef->second > 0) - { - if (reportCycles) - { - std::wcout << L"Cyclic references detected!\n"; - reportCycles = false; - } - std::wcout << classRef->first << L": " << classRef->second << L"\n"; + if (cycleMap) { + SyncLock lockRef(&cycleMap); + bool reportCycles = true; + for (MapStringInt::iterator classRef = cycleMap.begin(); classRef != cycleMap.end(); ++classRef) { + if (classRef->second > 0) { + if (reportCycles) { + std::wcout << L"Cyclic references detected!\n"; + reportCycles = false; } + std::wcout << classRef->first << L": " << classRef->second << L"\n"; } } } } + +} diff --git a/src/core/util/DocIdBitSet.cpp b/src/core/util/DocIdBitSet.cpp index 63a0c005..5e7576ed 100644 --- a/src/core/util/DocIdBitSet.cpp +++ b/src/core/util/DocIdBitSet.cpp @@ -9,83 +9,71 @@ #include "_DocIdBitSet.h" #include "BitSet.h" -namespace Lucene -{ - DocIdBitSet::DocIdBitSet() - { - } +namespace Lucene { - DocIdBitSet::DocIdBitSet(const BitSetPtr& bitSet) - { - this->bitSet = bitSet; - } +DocIdBitSet::DocIdBitSet() { +} - DocIdBitSet::~DocIdBitSet() - { - } +DocIdBitSet::DocIdBitSet(const BitSetPtr& bitSet) { + this->bitSet = bitSet; +} - DocIdSetIteratorPtr DocIdBitSet::iterator() - { - return newLucene(bitSet); - } +DocIdBitSet::~DocIdBitSet() { +} - bool DocIdBitSet::isCacheable() - { - return true; - } +DocIdSetIteratorPtr DocIdBitSet::iterator() { + return newLucene(bitSet); +} - BitSetPtr DocIdBitSet::getBitSet() - { - return bitSet; - } +bool DocIdBitSet::isCacheable() { + return true; +} - bool DocIdBitSet::equals(const LuceneObjectPtr& other) - { - if (DocIdSet::equals(other)) - return true; - DocIdBitSetPtr otherBitSet(boost::dynamic_pointer_cast(other)); - return bitSet->equals(otherBitSet->bitSet); - } +BitSetPtr DocIdBitSet::getBitSet() { + return bitSet; +} - int32_t DocIdBitSet::hashCode() - { - return bitSet->hashCode(); +bool DocIdBitSet::equals(const LuceneObjectPtr& other) { + if (DocIdSet::equals(other)) { + return true; } + DocIdBitSetPtr otherBitSet(boost::dynamic_pointer_cast(other)); + return bitSet->equals(otherBitSet->bitSet); +} - LuceneObjectPtr DocIdBitSet::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - DocIdBitSetPtr cloneBitSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); - cloneBitSet->bitSet = boost::dynamic_pointer_cast(bitSet->clone()); - return cloneBitSet; - } +int32_t DocIdBitSet::hashCode() { + return bitSet->hashCode(); +} - DocIdBitSetIterator::DocIdBitSetIterator(const BitSetPtr& bitSet) - { - this->bitSet = bitSet; - this->docId = -1; - } +LuceneObjectPtr DocIdBitSet::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + DocIdBitSetPtr cloneBitSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); + cloneBitSet->bitSet = boost::dynamic_pointer_cast(bitSet->clone()); + return cloneBitSet; +} - DocIdBitSetIterator::~DocIdBitSetIterator() - { - } +DocIdBitSetIterator::DocIdBitSetIterator(const BitSetPtr& bitSet) { + this->bitSet = bitSet; + this->docId = -1; +} - int32_t DocIdBitSetIterator::docID() - { - return docId; - } +DocIdBitSetIterator::~DocIdBitSetIterator() { +} - int32_t DocIdBitSetIterator::nextDoc() - { - int32_t doc = bitSet->nextSetBit(docId + 1); - docId = doc == -1 ? NO_MORE_DOCS : doc; - return docId; - } +int32_t DocIdBitSetIterator::docID() { + return docId; +} + +int32_t DocIdBitSetIterator::nextDoc() { + int32_t doc = bitSet->nextSetBit(docId + 1); + docId = doc == -1 ? NO_MORE_DOCS : doc; + return docId; +} + +int32_t DocIdBitSetIterator::advance(int32_t target) { + int32_t doc = bitSet->nextSetBit(target); + docId = doc == -1 ? NO_MORE_DOCS : doc; + return docId; +} - int32_t DocIdBitSetIterator::advance(int32_t target) - { - int32_t doc = bitSet->nextSetBit(target); - docId = doc == -1 ? NO_MORE_DOCS : doc; - return docId; - } } diff --git a/src/core/util/FieldCacheSanityChecker.cpp b/src/core/util/FieldCacheSanityChecker.cpp index 2b0408f9..afc326c6 100644 --- a/src/core/util/FieldCacheSanityChecker.cpp +++ b/src/core/util/FieldCacheSanityChecker.cpp @@ -12,268 +12,243 @@ #include "StringUtils.h" #include "VariantUtils.h" -namespace Lucene -{ - FieldCacheSanityChecker::FieldCacheSanityChecker() - { - } +namespace Lucene { - FieldCacheSanityChecker::~FieldCacheSanityChecker() - { - } +FieldCacheSanityChecker::FieldCacheSanityChecker() { +} - Collection FieldCacheSanityChecker::checkSanity(const FieldCachePtr& cache) - { - return checkSanity(cache->getCacheEntries()); - } +FieldCacheSanityChecker::~FieldCacheSanityChecker() { +} - Collection FieldCacheSanityChecker::checkSanity(Collection cacheEntries) - { - FieldCacheSanityCheckerPtr sanityChecker(newLucene()); - return sanityChecker->check(cacheEntries); - } +Collection FieldCacheSanityChecker::checkSanity(const FieldCachePtr& cache) { + return checkSanity(cache->getCacheEntries()); +} + +Collection FieldCacheSanityChecker::checkSanity(Collection cacheEntries) { + FieldCacheSanityCheckerPtr sanityChecker(newLucene()); + return sanityChecker->check(cacheEntries); +} - Collection FieldCacheSanityChecker::check(Collection cacheEntries) - { - if (!cacheEntries || cacheEntries.empty()) - return Collection::newInstance(); +Collection FieldCacheSanityChecker::check(Collection cacheEntries) { + if (!cacheEntries || cacheEntries.empty()) { + return Collection::newInstance(); + } - // Maps the (valId) identityhashCode of cache values to sets of CacheEntry instances - MapSetIntFieldCacheEntry valIdToItems(MapSetIntFieldCacheEntry::map_type::newInstance()); + // Maps the (valId) identityhashCode of cache values to sets of CacheEntry instances + MapSetIntFieldCacheEntry valIdToItems(MapSetIntFieldCacheEntry::map_type::newInstance()); - // Maps ReaderField keys to Sets of ValueIds - MapSetReaderFieldInt readerFieldToValIds(MapSetReaderFieldInt::map_type::newInstance()); + // Maps ReaderField keys to Sets of ValueIds + MapSetReaderFieldInt readerFieldToValIds(MapSetReaderFieldInt::map_type::newInstance()); - // Any keys that we know result in more then one valId - SetReaderField valMismatchKeys(SetReaderField::newInstance()); + // Any keys that we know result in more then one valId + SetReaderField valMismatchKeys(SetReaderField::newInstance()); - // iterate over all the cacheEntries to get the mappings we'll need - for (int32_t i = 0; i < cacheEntries.size(); ++i) - { - FieldCacheEntryPtr item(cacheEntries[i]); - boost::any val(item->getValue()); + // iterate over all the cacheEntries to get the mappings we'll need + for (int32_t i = 0; i < cacheEntries.size(); ++i) { + FieldCacheEntryPtr item(cacheEntries[i]); + boost::any val(item->getValue()); - if (VariantUtils::typeOf(val)) - continue; + if (VariantUtils::typeOf(val)) { + continue; + } - ReaderFieldPtr rf(newLucene(item->getReaderKey(), item->getFieldName())); - int32_t valId = VariantUtils::hashCode(val); + ReaderFieldPtr rf(newLucene(item->getReaderKey(), item->getFieldName())); + int32_t valId = VariantUtils::hashCode(val); - // indirect mapping, so the MapOfSet will dedup identical valIds for us - valIdToItems.put(valId, item); - if (1 < readerFieldToValIds.put(rf, valId)) - valMismatchKeys.add(rf); + // indirect mapping, so the MapOfSet will dedup identical valIds for us + valIdToItems.put(valId, item); + if (1 < readerFieldToValIds.put(rf, valId)) { + valMismatchKeys.add(rf); } + } - Collection insanity(Collection::newInstance()); + Collection insanity(Collection::newInstance()); - Collection mismatch(checkValueMismatch(valIdToItems, readerFieldToValIds, valMismatchKeys)); - insanity.addAll(mismatch.begin(), mismatch.end()); + Collection mismatch(checkValueMismatch(valIdToItems, readerFieldToValIds, valMismatchKeys)); + insanity.addAll(mismatch.begin(), mismatch.end()); - Collection subreaders(checkSubreaders(valIdToItems, readerFieldToValIds)); - insanity.addAll(subreaders.begin(), subreaders.end()); + Collection subreaders(checkSubreaders(valIdToItems, readerFieldToValIds)); + insanity.addAll(subreaders.begin(), subreaders.end()); - return insanity; - } + return insanity; +} - Collection FieldCacheSanityChecker::checkValueMismatch(MapSetIntFieldCacheEntry valIdToItems, - MapSetReaderFieldInt readerFieldToValIds, - SetReaderField valMismatchKeys) - { - Collection insanity(Collection::newInstance()); - - if (!valMismatchKeys.empty()) - { - // we have multiple values for some ReaderFields - - MapSetReaderFieldInt::map_type rfMap = readerFieldToValIds.getMap(); - MapSetIntFieldCacheEntry::map_type valMap = valIdToItems.getMap(); - - for (SetReaderField::iterator rf = valMismatchKeys.begin(); rf != valMismatchKeys.end(); ++rf) - { - Collection badEntries(Collection::newInstance()); - - MapSetReaderFieldInt::set_type values(rfMap.get(*rf)); - for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) - { - MapSetIntFieldCacheEntry::set_type cacheEntries(valMap.get(*value)); - for (MapSetIntFieldCacheEntry::set_type::iterator cacheEntry = cacheEntries.begin(); cacheEntry != cacheEntries.end(); ++cacheEntry) - badEntries.add(*cacheEntry); - } +Collection FieldCacheSanityChecker::checkValueMismatch(MapSetIntFieldCacheEntry valIdToItems, + MapSetReaderFieldInt readerFieldToValIds, + SetReaderField valMismatchKeys) { + Collection insanity(Collection::newInstance()); + + if (!valMismatchKeys.empty()) { + // we have multiple values for some ReaderFields - insanity.add(newLucene(VALUEMISMATCH, L"Multiple distinct value objects for " + (*rf)->toString(), badEntries)); + MapSetReaderFieldInt::map_type rfMap = readerFieldToValIds.getMap(); + MapSetIntFieldCacheEntry::map_type valMap = valIdToItems.getMap(); + + for (SetReaderField::iterator rf = valMismatchKeys.begin(); rf != valMismatchKeys.end(); ++rf) { + Collection badEntries(Collection::newInstance()); + + MapSetReaderFieldInt::set_type values(rfMap.get(*rf)); + for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) { + MapSetIntFieldCacheEntry::set_type cacheEntries(valMap.get(*value)); + for (MapSetIntFieldCacheEntry::set_type::iterator cacheEntry = cacheEntries.begin(); cacheEntry != cacheEntries.end(); ++cacheEntry) { + badEntries.add(*cacheEntry); + } } + + insanity.add(newLucene(VALUEMISMATCH, L"Multiple distinct value objects for " + (*rf)->toString(), badEntries)); } - return insanity; } + return insanity; +} - Collection FieldCacheSanityChecker::checkSubreaders(MapSetIntFieldCacheEntry valIdToItems, - MapSetReaderFieldInt readerFieldToValIds) - { - Collection insanity(Collection::newInstance()); - - MapReaderFieldSetReaderField badChildren(MapReaderFieldSetReaderField::newInstance()); - MapSetReaderFieldReaderField badKids(badChildren); // wrapper +Collection FieldCacheSanityChecker::checkSubreaders(MapSetIntFieldCacheEntry valIdToItems, + MapSetReaderFieldInt readerFieldToValIds) { + Collection insanity(Collection::newInstance()); - MapSetIntFieldCacheEntry::map_type viToItemSets = valIdToItems.getMap(); - MapSetReaderFieldInt::map_type rfToValIdSets = readerFieldToValIds.getMap(); + MapReaderFieldSetReaderField badChildren(MapReaderFieldSetReaderField::newInstance()); + MapSetReaderFieldReaderField badKids(badChildren); // wrapper - SetReaderField seen(SetReaderField::newInstance()); + MapSetIntFieldCacheEntry::map_type viToItemSets = valIdToItems.getMap(); + MapSetReaderFieldInt::map_type rfToValIdSets = readerFieldToValIds.getMap(); - for (MapSetReaderFieldInt::map_type::iterator rf = rfToValIdSets.begin(); rf != rfToValIdSets.end(); ++rf) - { - if (seen.contains(rf->first)) - continue; + SetReaderField seen(SetReaderField::newInstance()); - Collection kids(getAllDecendentReaderKeys(rf->first->readerKey)); - for (Collection::iterator kidKey = kids.begin(); kidKey != kids.end(); ++kidKey) - { - ReaderFieldPtr kid(newLucene(*kidKey, rf->first->fieldName)); + for (MapSetReaderFieldInt::map_type::iterator rf = rfToValIdSets.begin(); rf != rfToValIdSets.end(); ++rf) { + if (seen.contains(rf->first)) { + continue; + } - if (badChildren.contains(kid)) - { - // we've already process this kid as RF and found other problems track those problems as our own - badKids.put(rf->first, kid); - badKids.putAll(rf->first, badChildren.get(kid)); - badChildren.remove(kid); - } - else if (rfToValIdSets.contains(kid)) - { - // we have cache entries for the kid - badKids.put(rf->first, kid); - } - seen.add(kid); + Collection kids(getAllDecendentReaderKeys(rf->first->readerKey)); + for (Collection::iterator kidKey = kids.begin(); kidKey != kids.end(); ++kidKey) { + ReaderFieldPtr kid(newLucene(*kidKey, rf->first->fieldName)); + + if (badChildren.contains(kid)) { + // we've already process this kid as RF and found other problems track those problems as our own + badKids.put(rf->first, kid); + badKids.putAll(rf->first, badChildren.get(kid)); + badChildren.remove(kid); + } else if (rfToValIdSets.contains(kid)) { + // we have cache entries for the kid + badKids.put(rf->first, kid); } - seen.add(rf->first); + seen.add(kid); } + seen.add(rf->first); + } - // every mapping in badKids represents an Insanity - for (MapReaderFieldSetReaderField::iterator parent = badChildren.begin(); parent != badChildren.end(); ++parent) - { - SetReaderField kids = parent->second; - Collection badEntries(Collection::newInstance()); + // every mapping in badKids represents an Insanity + for (MapReaderFieldSetReaderField::iterator parent = badChildren.begin(); parent != badChildren.end(); ++parent) { + SetReaderField kids = parent->second; + Collection badEntries(Collection::newInstance()); - // put parent entries in first - MapSetReaderFieldInt::set_type values(rfToValIdSets.get(parent->first)); - for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) - { + // put parent entries in first + MapSetReaderFieldInt::set_type values(rfToValIdSets.get(parent->first)); + for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) { + MapSetIntFieldCacheEntry::set_type cacheEntries(viToItemSets.get(*value)); + badEntries.addAll(cacheEntries.begin(), cacheEntries.end()); + } + + // now the entries for the descendants + for (SetReaderField::iterator kid = kids.begin(); kid != kids.end(); ++kid) { + MapSetReaderFieldInt::set_type values(rfToValIdSets.get(*kid)); + for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) { MapSetIntFieldCacheEntry::set_type cacheEntries(viToItemSets.get(*value)); badEntries.addAll(cacheEntries.begin(), cacheEntries.end()); } - - // now the entries for the descendants - for (SetReaderField::iterator kid = kids.begin(); kid != kids.end(); ++kid) - { - MapSetReaderFieldInt::set_type values(rfToValIdSets.get(*kid)); - for (MapSetReaderFieldInt::set_type::iterator value = values.begin(); value != values.end(); ++value) - { - MapSetIntFieldCacheEntry::set_type cacheEntries(viToItemSets.get(*value)); - badEntries.addAll(cacheEntries.begin(), cacheEntries.end()); - } - } - - insanity.add(newLucene(SUBREADER, L"Found caches for descendants of " + parent->first->toString(), badEntries)); } - return insanity; + insanity.add(newLucene(SUBREADER, L"Found caches for descendants of " + parent->first->toString(), badEntries)); } - Collection FieldCacheSanityChecker::getAllDecendentReaderKeys(const LuceneObjectPtr& seed) - { - Collection all(Collection::newInstance()); // will grow as we iter - all.add(seed); - for (int32_t i = 0; i < all.size(); ++i) - { - IndexReaderPtr indexReader(boost::dynamic_pointer_cast(all[i])); - if (indexReader) - { - Collection subs(indexReader->getSequentialSubReaders()); - for (int32_t j = 0; subs && j < subs.size(); ++j) - all.add(subs[j]->getFieldCacheKey()); + return insanity; +} + +Collection FieldCacheSanityChecker::getAllDecendentReaderKeys(const LuceneObjectPtr& seed) { + Collection all(Collection::newInstance()); // will grow as we iter + all.add(seed); + for (int32_t i = 0; i < all.size(); ++i) { + IndexReaderPtr indexReader(boost::dynamic_pointer_cast(all[i])); + if (indexReader) { + Collection subs(indexReader->getSequentialSubReaders()); + for (int32_t j = 0; subs && j < subs.size(); ++j) { + all.add(subs[j]->getFieldCacheKey()); } } - - // need to remove the first, because it was the seed - all.remove(all.begin()); - return all; } - ReaderField::ReaderField(const LuceneObjectPtr& readerKey, const String& fieldName) - { - this->readerKey = readerKey; - this->fieldName = fieldName; - } + // need to remove the first, because it was the seed + all.remove(all.begin()); + return all; +} - ReaderField::~ReaderField() - { - } +ReaderField::ReaderField(const LuceneObjectPtr& readerKey, const String& fieldName) { + this->readerKey = readerKey; + this->fieldName = fieldName; +} - int32_t ReaderField::hashCode() - { - return readerKey->hashCode() * StringUtils::hashCode(fieldName); - } +ReaderField::~ReaderField() { +} - bool ReaderField::equals(const LuceneObjectPtr& other) - { - ReaderFieldPtr otherReaderField(boost::dynamic_pointer_cast(other)); - if (!otherReaderField) - return false; - return (readerKey->equals(otherReaderField->readerKey) && fieldName == otherReaderField->fieldName); - } +int32_t ReaderField::hashCode() { + return readerKey->hashCode() * StringUtils::hashCode(fieldName); +} - String ReaderField::toString() - { - return readerKey->toString() + L"+" + fieldName; +bool ReaderField::equals(const LuceneObjectPtr& other) { + ReaderFieldPtr otherReaderField(boost::dynamic_pointer_cast(other)); + if (!otherReaderField) { + return false; } + return (readerKey->equals(otherReaderField->readerKey) && fieldName == otherReaderField->fieldName); +} - Insanity::Insanity(FieldCacheSanityChecker::InsanityType type, const String& msg, Collection entries) - { - if (!entries || entries.empty()) - boost::throw_exception(IllegalArgumentException(L"Insanity requires non-null/non-empty CacheEntry[]")); - this->type = type; - this->msg = msg; - this->entries = entries; - } +String ReaderField::toString() { + return readerKey->toString() + L"+" + fieldName; +} - Insanity::~Insanity() - { +Insanity::Insanity(FieldCacheSanityChecker::InsanityType type, const String& msg, Collection entries) { + if (!entries || entries.empty()) { + boost::throw_exception(IllegalArgumentException(L"Insanity requires non-null/non-empty CacheEntry[]")); } + this->type = type; + this->msg = msg; + this->entries = entries; +} - FieldCacheSanityChecker::InsanityType Insanity::getType() - { - return type; - } +Insanity::~Insanity() { +} - String Insanity::getMsg() - { - return msg; - } +FieldCacheSanityChecker::InsanityType Insanity::getType() { + return type; +} - Collection Insanity::getCacheEntries() - { - return entries; - } +String Insanity::getMsg() { + return msg; +} - String Insanity::toString() - { - StringStream buffer; - switch (type) - { - case FieldCacheSanityChecker::SUBREADER: - buffer << L"SUBREADER: "; - break; - case FieldCacheSanityChecker::VALUEMISMATCH: - buffer << L"VALUEMISMATCH: "; - break; - case FieldCacheSanityChecker::EXPECTED: - buffer << L"EXPECTED: "; - break; - } - buffer << msg << L"\n"; +Collection Insanity::getCacheEntries() { + return entries; +} - for (Collection::iterator ce = entries.begin(); ce != entries.end(); ++ce) - buffer << L"\t" << (*ce)->toString() << L"\n"; +String Insanity::toString() { + StringStream buffer; + switch (type) { + case FieldCacheSanityChecker::SUBREADER: + buffer << L"SUBREADER: "; + break; + case FieldCacheSanityChecker::VALUEMISMATCH: + buffer << L"VALUEMISMATCH: "; + break; + case FieldCacheSanityChecker::EXPECTED: + buffer << L"EXPECTED: "; + break; + } + buffer << msg << L"\n"; - return buffer.str(); + for (Collection::iterator ce = entries.begin(); ce != entries.end(); ++ce) { + buffer << L"\t" << (*ce)->toString() << L"\n"; } + + return buffer.str(); +} + } diff --git a/src/core/util/FileReader.cpp b/src/core/util/FileReader.cpp index 6975ad4a..18442188 100644 --- a/src/core/util/FileReader.cpp +++ b/src/core/util/FileReader.cpp @@ -11,68 +11,62 @@ #include "FileUtils.h" #include "StringUtils.h" -namespace Lucene -{ - const int32_t FileReader::FILE_EOF = Reader::READER_EOF; - const int32_t FileReader::FILE_ERROR = -1; +namespace Lucene { - FileReader::FileReader(const String& fileName) - { - this->file = newInstance(fileName, std::ios::binary | std::ios::in); - if (!file->is_open()) - boost::throw_exception(FileNotFoundException(fileName)); - _length = FileUtils::fileLength(fileName); - } +const int32_t FileReader::FILE_EOF = Reader::READER_EOF; +const int32_t FileReader::FILE_ERROR = -1; - FileReader::~FileReader() - { +FileReader::FileReader(const String& fileName) { + this->file = newInstance(fileName, std::ios::binary | std::ios::in); + if (!file->is_open()) { + boost::throw_exception(FileNotFoundException(fileName)); } + _length = FileUtils::fileLength(fileName); +} - int32_t FileReader::read() - { - wchar_t buffer; - return read(&buffer, 0, 1) == FILE_EOF ? FILE_EOF : buffer; - } +FileReader::~FileReader() { +} - int32_t FileReader::read(wchar_t* buffer, int32_t offset, int32_t length) - { - try - { - if (file->eof()) - return FILE_EOF; - if (!fileBuffer) - fileBuffer = ByteArray::newInstance(length); - if (length > fileBuffer.size()) - fileBuffer.resize(length); - file->read((char*)fileBuffer.get(), length); - int32_t readLength = file->gcount(); - MiscUtils::arrayCopy(fileBuffer.get(), 0, buffer, offset, readLength); - return readLength == 0 ? FILE_EOF : readLength; +int32_t FileReader::read() { + wchar_t buffer; + return read(&buffer, 0, 1) == FILE_EOF ? FILE_EOF : buffer; +} + +int32_t FileReader::read(wchar_t* buffer, int32_t offset, int32_t length) { + try { + if (file->eof()) { + return FILE_EOF; + } + if (!fileBuffer) { + fileBuffer = ByteArray::newInstance(length); } - catch (...) - { - return FILE_ERROR; + if (length > fileBuffer.size()) { + fileBuffer.resize(length); } + file->read((char*)fileBuffer.get(), length); + int32_t readLength = file->gcount(); + MiscUtils::arrayCopy(fileBuffer.get(), 0, buffer, offset, readLength); + return readLength == 0 ? FILE_EOF : readLength; + } catch (...) { + return FILE_ERROR; } +} - void FileReader::close() - { - file->close(); - } +void FileReader::close() { + file->close(); +} - bool FileReader::markSupported() - { - return false; - } +bool FileReader::markSupported() { + return false; +} - void FileReader::reset() - { - file->clear(); - file->seekg((std::streamoff)0); - } +void FileReader::reset() { + file->clear(); + file->seekg((std::streamoff)0); +} + +int64_t FileReader::length() { + return _length; +} - int64_t FileReader::length() - { - return _length; - } } diff --git a/src/core/util/FileUtils.cpp b/src/core/util/FileUtils.cpp index ee070619..d624efaf 100644 --- a/src/core/util/FileUtils.cpp +++ b/src/core/util/FileUtils.cpp @@ -20,222 +20,165 @@ #include #endif -namespace Lucene -{ - namespace FileUtils - { - bool fileExists(const String& path) - { - try - { - return boost::filesystem::exists(path.c_str()); - } - catch (...) - { - return false; - } - } - - uint64_t fileModified(const String& path) - { - try - { - return (uint64_t)boost::filesystem::last_write_time(path.c_str()); - } - catch (...) - { - return 0; - } - } - - bool touchFile(const String& path) - { - try - { - boost::filesystem::last_write_time(path.c_str(), time(NULL)); - return true; - } - catch (...) - { - return false; - } - } +namespace Lucene { - int64_t fileLength(const String& path) - { - try - { - int64_t fileSize = (int64_t)boost::filesystem::file_size(path.c_str()); - for (int32_t i = 0; fileSize == 0 && i < 100; ++i) - { - LuceneThread::threadYield(); - fileSize = (int64_t)boost::filesystem::file_size(path.c_str()); - } - return fileSize; - } - catch (...) - { - return 0; - } - } +namespace FileUtils { - bool setFileLength(const String& path, int64_t length) - { - try - { - if (!fileExists(path)) - return false; - #if defined(_WIN32) || defined(_WIN64) - int32_t fd = _wopen(path.c_str(), _O_WRONLY | _O_CREAT | _O_BINARY, _S_IWRITE); - return _chsize(fd, (long)length) == 0; - #else - return truncate(boost::filesystem::path(path).c_str(), (off_t)length) == 0; - #endif - } - catch (...) - { - return false; - } - } +bool fileExists(const String& path) { + try { + return boost::filesystem::exists(path.c_str()); + } catch (...) { + return false; + } +} - bool removeFile(const String& path) - { - try - { - return boost::filesystem::remove(path.c_str()); - } - catch (...) - { - return false; - } - } +uint64_t fileModified(const String& path) { + try { + return (uint64_t)boost::filesystem::last_write_time(path.c_str()); + } catch (...) { + return 0; + } +} - bool copyFile(const String& source, const String& dest) - { - try - { - boost::filesystem::copy_file(source.c_str(), dest.c_str()); - return true; - } - catch (...) - { - return false; - } - } +bool touchFile(const String& path) { + try { + boost::filesystem::last_write_time(path.c_str(), time(NULL)); + return true; + } catch (...) { + return false; + } +} - bool createDirectory(const String& path) - { - try - { - return boost::filesystem::create_directory(path.c_str()); - } - catch (...) - { - return false; - } +int64_t fileLength(const String& path) { + try { + int64_t fileSize = (int64_t)boost::filesystem::file_size(path.c_str()); + for (int32_t i = 0; fileSize == 0 && i < 100; ++i) { + LuceneThread::threadYield(); + fileSize = (int64_t)boost::filesystem::file_size(path.c_str()); } + return fileSize; + } catch (...) { + return 0; + } +} - bool removeDirectory(const String& path) - { - try - { - boost::filesystem::remove_all(path.c_str()); - return true; - } - catch (...) - { - return false; - } +bool setFileLength(const String& path, int64_t length) { + try { + if (!fileExists(path)) { + return false; } +#if defined(_WIN32) || defined(_WIN64) + int32_t fd = _wopen(path.c_str(), _O_WRONLY | _O_CREAT | _O_BINARY, _S_IWRITE); + return _chsize(fd, (long)length) == 0; +#else + return truncate(boost::filesystem::path(path).c_str(), (off_t)length) == 0; +#endif + } catch (...) { + return false; + } +} - bool isDirectory(const String& path) - { - try - { - return boost::filesystem::is_directory(path.c_str()); - } - catch (...) - { - return false; - } - } +bool removeFile(const String& path) { + try { + return boost::filesystem::remove(path.c_str()); + } catch (...) { + return false; + } +} - bool listDirectory(const String& path, bool filesOnly, HashSet dirList) - { - try - { - for (boost::filesystem::directory_iterator dir(path.c_str()); dir != boost::filesystem::directory_iterator(); ++dir) - { - if (!filesOnly || !boost::filesystem::is_directory(dir->status())) - dirList.add(dir->path().filename().wstring().c_str()); - } - return true; - } - catch (...) - { - return false; - } - } +bool copyFile(const String& source, const String& dest) { + try { + boost::filesystem::copy_file(source.c_str(), dest.c_str()); + return true; + } catch (...) { + return false; + } +} - bool copyDirectory(const String& source, const String& dest) - { - try - { - HashSet dirList(HashSet::newInstance()); - if (!listDirectory(source, true, dirList)) - return false; +bool createDirectory(const String& path) { + try { + return boost::filesystem::create_directory(path.c_str()); + } catch (...) { + return false; + } +} - createDirectory(dest); +bool removeDirectory(const String& path) { + try { + boost::filesystem::remove_all(path.c_str()); + return true; + } catch (...) { + return false; + } +} - for (HashSet::iterator file = dirList.begin(); file != dirList.end(); ++file) - copyFile(joinPath(source, *file), joinPath(dest, *file)); +bool isDirectory(const String& path) { + try { + return boost::filesystem::is_directory(path.c_str()); + } catch (...) { + return false; + } +} - return true; - } - catch (...) - { - return false; +bool listDirectory(const String& path, bool filesOnly, HashSet dirList) { + try { + for (boost::filesystem::directory_iterator dir(path.c_str()); dir != boost::filesystem::directory_iterator(); ++dir) { + if (!filesOnly || !boost::filesystem::is_directory(dir->status())) { + dirList.add(dir->path().filename().wstring().c_str()); } } + return true; + } catch (...) { + return false; + } +} - String joinPath(const String& path, const String& file) - { - try - { - boost::filesystem::path join(path.c_str()); - join /= file.c_str(); - return join.wstring().c_str(); - } - catch (...) - { - return path; - } +bool copyDirectory(const String& source, const String& dest) { + try { + HashSet dirList(HashSet::newInstance()); + if (!listDirectory(source, true, dirList)) { + return false; } - String extractPath(const String& path) - { - try - { - boost::filesystem::wpath parentPath(path.c_str()); - return parentPath.parent_path().wstring().c_str(); - } - catch (...) - { - return path; - } - } + createDirectory(dest); - String extractFile(const String& path) - { - try - { - boost::filesystem::wpath fileName(path.c_str()); - return fileName.filename().wstring().c_str(); - } - catch (...) - { - return path; - } + for (HashSet::iterator file = dirList.begin(); file != dirList.end(); ++file) { + copyFile(joinPath(source, *file), joinPath(dest, *file)); } + + return true; + } catch (...) { + return false; + } +} + +String joinPath(const String& path, const String& file) { + try { + boost::filesystem::path join(path.c_str()); + join /= file.c_str(); + return join.wstring().c_str(); + } catch (...) { + return path; } } + +String extractPath(const String& path) { + try { + boost::filesystem::wpath parentPath(path.c_str()); + return parentPath.parent_path().wstring().c_str(); + } catch (...) { + return path; + } +} + +String extractFile(const String& path) { + try { + boost::filesystem::wpath fileName(path.c_str()); + return fileName.filename().wstring().c_str(); + } catch (...) { + return path; + } +} + +} +} diff --git a/src/core/util/InfoStream.cpp b/src/core/util/InfoStream.cpp index 984b32ca..f0229bcc 100644 --- a/src/core/util/InfoStream.cpp +++ b/src/core/util/InfoStream.cpp @@ -9,46 +9,38 @@ #include "InfoStream.h" #include "StringUtils.h" -namespace Lucene -{ - InfoStream::InfoStream() - { - } - - InfoStream::~InfoStream() - { - } - - InfoStreamFile::InfoStreamFile(const String& path) : file(path) - { - } - - InfoStreamFile::~InfoStreamFile() - { - } - - InfoStreamFile& InfoStreamFile::operator<< (const String& t) - { - file << t; - return *this; - } - - InfoStreamOut::~InfoStreamOut() - { - } - - InfoStreamOut& InfoStreamOut::operator<< (const String& t) - { - std::wcout << t; - return *this; - } - - InfoStreamNull::~InfoStreamNull() - { - } - - InfoStreamNull& InfoStreamNull::operator<< (const String& t) - { - return *this; - } +namespace Lucene { + +InfoStream::InfoStream() { +} + +InfoStream::~InfoStream() { +} + +InfoStreamFile::InfoStreamFile(const String& path) : file(path) { +} + +InfoStreamFile::~InfoStreamFile() { +} + +InfoStreamFile& InfoStreamFile::operator<< (const String& t) { + file << t; + return *this; +} + +InfoStreamOut::~InfoStreamOut() { +} + +InfoStreamOut& InfoStreamOut::operator<< (const String& t) { + std::wcout << t; + return *this; +} + +InfoStreamNull::~InfoStreamNull() { +} + +InfoStreamNull& InfoStreamNull::operator<< (const String& t) { + return *this; +} + } diff --git a/src/core/util/InputStreamReader.cpp b/src/core/util/InputStreamReader.cpp index d257da04..ceefafd2 100644 --- a/src/core/util/InputStreamReader.cpp +++ b/src/core/util/InputStreamReader.cpp @@ -9,41 +9,35 @@ #include "BufferedReader.h" #include "UTF8Stream.h" -namespace Lucene -{ - InputStreamReader::InputStreamReader(const ReaderPtr& reader) - { - this->reader = reader; - this->decoder = newLucene(newLucene(reader, 1024)); - } - - InputStreamReader::~InputStreamReader() - { - } - - int32_t InputStreamReader::read() - { - int32_t buffer; - return read((wchar_t*)&buffer, 0, 1) == READER_EOF ? READER_EOF : buffer; - } - - int32_t InputStreamReader::read(wchar_t* b, int32_t offset, int32_t length) - { - return decoder->decode(b + offset, length); - } - - void InputStreamReader::close() - { - reader->close(); - } - - bool InputStreamReader::markSupported() - { - return false; - } - - void InputStreamReader::reset() - { - reader->reset(); - } +namespace Lucene { + +InputStreamReader::InputStreamReader(const ReaderPtr& reader) { + this->reader = reader; + this->decoder = newLucene(newLucene(reader, 1024)); +} + +InputStreamReader::~InputStreamReader() { +} + +int32_t InputStreamReader::read() { + int32_t buffer; + return read((wchar_t*)&buffer, 0, 1) == READER_EOF ? READER_EOF : buffer; +} + +int32_t InputStreamReader::read(wchar_t* b, int32_t offset, int32_t length) { + return decoder->decode(b + offset, length); +} + +void InputStreamReader::close() { + reader->close(); +} + +bool InputStreamReader::markSupported() { + return false; +} + +void InputStreamReader::reset() { + reader->reset(); +} + } diff --git a/src/core/util/LuceneAllocator.cpp b/src/core/util/LuceneAllocator.cpp index b9588d3e..92a7ccad 100644 --- a/src/core/util/LuceneAllocator.cpp +++ b/src/core/util/LuceneAllocator.cpp @@ -7,41 +7,40 @@ #include "LuceneInc.h" #include "LuceneAllocator.h" -namespace Lucene -{ - void* AllocMemory(size_t size) - { - #if (defined(_WIN32) || defined(_WIN64)) && !defined(NDEBUG) - return _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__); - #else - return malloc(size); - #endif - } +namespace Lucene { + +void* AllocMemory(size_t size) { +#if (defined(_WIN32) || defined(_WIN64)) && !defined(NDEBUG) + return _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__); +#else + return malloc(size); +#endif +} - void* ReallocMemory(void* memory, size_t size) - { - if (memory == NULL) - return AllocMemory(size); - if (size == 0) - { - FreeMemory(memory); - return NULL; - } - #if defined(_WIN32) && !defined(NDEBUG) - return _realloc_dbg(memory, size, _NORMAL_BLOCK, __FILE__, __LINE__); - #else - return realloc(memory, size); - #endif +void* ReallocMemory(void* memory, size_t size) { + if (memory == NULL) { + return AllocMemory(size); + } + if (size == 0) { + FreeMemory(memory); + return NULL; } +#if defined(_WIN32) && !defined(NDEBUG) + return _realloc_dbg(memory, size, _NORMAL_BLOCK, __FILE__, __LINE__); +#else + return realloc(memory, size); +#endif +} - void FreeMemory(void* memory) - { - if (memory == NULL) - return; - #if defined(_WIN32) && !defined(NDEBUG) - _free_dbg(memory, _NORMAL_BLOCK); - #else - free(memory); - #endif +void FreeMemory(void* memory) { + if (memory == NULL) { + return; } +#if defined(_WIN32) && !defined(NDEBUG) + _free_dbg(memory, _NORMAL_BLOCK); +#else + free(memory); +#endif +} + } diff --git a/src/core/util/LuceneException.cpp b/src/core/util/LuceneException.cpp index 7261d022..ab69d6d1 100644 --- a/src/core/util/LuceneException.cpp +++ b/src/core/util/LuceneException.cpp @@ -7,94 +7,88 @@ #include "LuceneInc.h" #include "LuceneException.h" -namespace Lucene -{ - LuceneException::LuceneException(const String& error, ExceptionType type) throw() - { - this->error = error; - this->type = type; - } +namespace Lucene { - LuceneException::~LuceneException() throw() - { - } +LuceneException::LuceneException(const String& error, ExceptionType type) throw() { + this->error = error; + this->type = type; +} - LuceneException::ExceptionType LuceneException::getType() const - { - return type; - } +LuceneException::~LuceneException() throw() { +} - String LuceneException::getError() const - { - return error; - } +LuceneException::ExceptionType LuceneException::getType() const { + return type; +} - bool LuceneException::isNull() const - { - return (type == Null); - } +String LuceneException::getError() const { + return error; +} + +bool LuceneException::isNull() const { + return (type == Null); +} - void LuceneException::throwException() - { - switch (type) - { - case LuceneException::AlreadyClosed: - boost::throw_exception(AlreadyClosedException(error, type)); - case LuceneException::Compression: - boost::throw_exception(CompressionException(error, type)); - case LuceneException::CorruptIndex: - boost::throw_exception(CorruptIndexException(error, type)); - case LuceneException::FieldReader: - boost::throw_exception(FieldReaderException(error, type)); - case LuceneException::FileNotFound: - boost::throw_exception(FileNotFoundException(error, type)); - case LuceneException::IllegalArgument: - boost::throw_exception(IllegalArgumentException(error, type)); - case LuceneException::IllegalState: - boost::throw_exception(IllegalStateException(error, type)); - case LuceneException::IndexOutOfBounds: - boost::throw_exception(IndexOutOfBoundsException(error, type)); - case LuceneException::IO: - boost::throw_exception(IOException(error, type)); - case LuceneException::LockObtainFailed: - boost::throw_exception(LockObtainFailedException(error, type)); - case LuceneException::LockReleaseFailed: - boost::throw_exception(LockReleaseFailedException(error, type)); - case LuceneException::Lookahead: - boost::throw_exception(LookaheadSuccess(error, type)); - case LuceneException::MergeAborted: - boost::throw_exception(MergeAbortedException(error, type)); - case LuceneException::Merge: - boost::throw_exception(MergeException(error, type)); - case LuceneException::NoSuchDirectory: - boost::throw_exception(NoSuchDirectoryException(error, type)); - case LuceneException::NullPointer: - boost::throw_exception(NullPointerException(error, type)); - case LuceneException::NumberFormat: - boost::throw_exception(NumberFormatException(error, type)); - case LuceneException::OutOfMemory: - boost::throw_exception(OutOfMemoryError(error, type)); - case LuceneException::Parse: - boost::throw_exception(ParseException(error, type)); - case LuceneException::QueryParser: - boost::throw_exception(QueryParserError(error, type)); - case LuceneException::Runtime: - boost::throw_exception(RuntimeException(error, type)); - case LuceneException::StaleReader: - boost::throw_exception(StaleReaderException(error, type)); - case LuceneException::StopFillCache: - boost::throw_exception(StopFillCacheException(error, type)); - case LuceneException::Temporary: - boost::throw_exception(TemporaryException(error, type)); - case LuceneException::TimeExceeded: - boost::throw_exception(TimeExceededException(error, type)); - case LuceneException::TooManyClauses: - boost::throw_exception(TooManyClausesException(error, type)); - case LuceneException::UnsupportedOperation: - boost::throw_exception(UnsupportedOperationException(error, type)); - case LuceneException::Null: - // silence static analyzer - break; - } +void LuceneException::throwException() { + switch (type) { + case LuceneException::AlreadyClosed: + boost::throw_exception(AlreadyClosedException(error, type)); + case LuceneException::Compression: + boost::throw_exception(CompressionException(error, type)); + case LuceneException::CorruptIndex: + boost::throw_exception(CorruptIndexException(error, type)); + case LuceneException::FieldReader: + boost::throw_exception(FieldReaderException(error, type)); + case LuceneException::FileNotFound: + boost::throw_exception(FileNotFoundException(error, type)); + case LuceneException::IllegalArgument: + boost::throw_exception(IllegalArgumentException(error, type)); + case LuceneException::IllegalState: + boost::throw_exception(IllegalStateException(error, type)); + case LuceneException::IndexOutOfBounds: + boost::throw_exception(IndexOutOfBoundsException(error, type)); + case LuceneException::IO: + boost::throw_exception(IOException(error, type)); + case LuceneException::LockObtainFailed: + boost::throw_exception(LockObtainFailedException(error, type)); + case LuceneException::LockReleaseFailed: + boost::throw_exception(LockReleaseFailedException(error, type)); + case LuceneException::Lookahead: + boost::throw_exception(LookaheadSuccess(error, type)); + case LuceneException::MergeAborted: + boost::throw_exception(MergeAbortedException(error, type)); + case LuceneException::Merge: + boost::throw_exception(MergeException(error, type)); + case LuceneException::NoSuchDirectory: + boost::throw_exception(NoSuchDirectoryException(error, type)); + case LuceneException::NullPointer: + boost::throw_exception(NullPointerException(error, type)); + case LuceneException::NumberFormat: + boost::throw_exception(NumberFormatException(error, type)); + case LuceneException::OutOfMemory: + boost::throw_exception(OutOfMemoryError(error, type)); + case LuceneException::Parse: + boost::throw_exception(ParseException(error, type)); + case LuceneException::QueryParser: + boost::throw_exception(QueryParserError(error, type)); + case LuceneException::Runtime: + boost::throw_exception(RuntimeException(error, type)); + case LuceneException::StaleReader: + boost::throw_exception(StaleReaderException(error, type)); + case LuceneException::StopFillCache: + boost::throw_exception(StopFillCacheException(error, type)); + case LuceneException::Temporary: + boost::throw_exception(TemporaryException(error, type)); + case LuceneException::TimeExceeded: + boost::throw_exception(TimeExceededException(error, type)); + case LuceneException::TooManyClauses: + boost::throw_exception(TooManyClausesException(error, type)); + case LuceneException::UnsupportedOperation: + boost::throw_exception(UnsupportedOperationException(error, type)); + case LuceneException::Null: + // silence static analyzer + break; } } + +} diff --git a/src/core/util/LuceneObject.cpp b/src/core/util/LuceneObject.cpp index bf83b42c..536aabdf 100644 --- a/src/core/util/LuceneObject.cpp +++ b/src/core/util/LuceneObject.cpp @@ -8,45 +8,39 @@ #include "LuceneObject.h" #include "StringUtils.h" -namespace Lucene -{ - LuceneObject::LuceneObject() - { - } +namespace Lucene { - LuceneObject::~LuceneObject() - { - } +LuceneObject::LuceneObject() { +} - void LuceneObject::initialize() - { - // override - } +LuceneObject::~LuceneObject() { +} - LuceneObjectPtr LuceneObject::clone(const LuceneObjectPtr& other) - { - if (!other) - boost::throw_exception(UnsupportedOperationException(L"clone must not be null")); - return other; - } +void LuceneObject::initialize() { + // override +} - int32_t LuceneObject::hashCode() - { - return (int32_t)(int64_t)this; +LuceneObjectPtr LuceneObject::clone(const LuceneObjectPtr& other) { + if (!other) { + boost::throw_exception(UnsupportedOperationException(L"clone must not be null")); } + return other; +} - bool LuceneObject::equals(const LuceneObjectPtr& other) - { - return (other && this == other.get()); - } +int32_t LuceneObject::hashCode() { + return (int32_t)(int64_t)this; +} - int32_t LuceneObject::compareTo(const LuceneObjectPtr& other) - { - return (int32_t)(this - other.get()); - } +bool LuceneObject::equals(const LuceneObjectPtr& other) { + return (other && this == other.get()); +} + +int32_t LuceneObject::compareTo(const LuceneObjectPtr& other) { + return (int32_t)(this - other.get()); +} + +String LuceneObject::toString() { + return StringUtils::toString(hashCode()); +} - String LuceneObject::toString() - { - return StringUtils::toString(hashCode()); - } } diff --git a/src/core/util/LuceneSignal.cpp b/src/core/util/LuceneSignal.cpp index 31a9fa32..e2aef404 100644 --- a/src/core/util/LuceneSignal.cpp +++ b/src/core/util/LuceneSignal.cpp @@ -8,40 +8,38 @@ #include "LuceneSignal.h" #include "Synchronize.h" -namespace Lucene -{ - LuceneSignal::LuceneSignal(const SynchronizePtr& objectLock) - { - this->objectLock = objectLock; - } +namespace Lucene { - LuceneSignal::~LuceneSignal() - { - } +LuceneSignal::LuceneSignal(const SynchronizePtr& objectLock) { + this->objectLock = objectLock; +} - void LuceneSignal::createSignal(LuceneSignalPtr& signal, const SynchronizePtr& objectLock) - { - static boost::mutex lockMutex; - boost::mutex::scoped_lock syncLock(lockMutex); - if (!signal) - signal = newInstance(objectLock); +LuceneSignal::~LuceneSignal() { +} + +void LuceneSignal::createSignal(LuceneSignalPtr& signal, const SynchronizePtr& objectLock) { + static boost::mutex lockMutex; + boost::mutex::scoped_lock syncLock(lockMutex); + if (!signal) { + signal = newInstance(objectLock); } +} - void LuceneSignal::wait(int32_t timeout) - { - int32_t relockCount = objectLock ? objectLock->unlockAll() : 0; - boost::mutex::scoped_lock waitLock(waitMutex); - while (!signalCondition.timed_wait(waitMutex, boost::posix_time::milliseconds(timeout))) - { - if (timeout != 0 || signalCondition.timed_wait(waitMutex, boost::posix_time::milliseconds(10))) - break; +void LuceneSignal::wait(int32_t timeout) { + int32_t relockCount = objectLock ? objectLock->unlockAll() : 0; + boost::mutex::scoped_lock waitLock(waitMutex); + while (!signalCondition.timed_wait(waitMutex, boost::posix_time::milliseconds(timeout))) { + if (timeout != 0 || signalCondition.timed_wait(waitMutex, boost::posix_time::milliseconds(10))) { + break; } - for (int32_t relock = 0; relock < relockCount; ++relock) - objectLock->lock(); } - - void LuceneSignal::notifyAll() - { - signalCondition.notify_all(); + for (int32_t relock = 0; relock < relockCount; ++relock) { + objectLock->lock(); } } + +void LuceneSignal::notifyAll() { + signalCondition.notify_all(); +} + +} diff --git a/src/core/util/LuceneSync.cpp b/src/core/util/LuceneSync.cpp index d2065d60..9c195a47 100644 --- a/src/core/util/LuceneSync.cpp +++ b/src/core/util/LuceneSync.cpp @@ -9,46 +9,39 @@ #include "Synchronize.h" #include "LuceneSignal.h" -namespace Lucene -{ - LuceneSync::~LuceneSync() - { - } - - SynchronizePtr LuceneSync::getSync() - { - Synchronize::createSync(objectLock); - return objectLock; - } - - LuceneSignalPtr LuceneSync::getSignal() - { - LuceneSignal::createSignal(objectSignal, getSync()); - return objectSignal; - } - - void LuceneSync::lock(int32_t timeout) - { - getSync()->lock(); - } - - void LuceneSync::unlock() - { - getSync()->unlock(); - } - - bool LuceneSync::holdsLock() - { - return getSync()->holdsLock(); - } - - void LuceneSync::wait(int32_t timeout) - { - getSignal()->wait(timeout); - } - - void LuceneSync::notifyAll() - { - getSignal()->notifyAll(); - } +namespace Lucene { + +LuceneSync::~LuceneSync() { +} + +SynchronizePtr LuceneSync::getSync() { + Synchronize::createSync(objectLock); + return objectLock; +} + +LuceneSignalPtr LuceneSync::getSignal() { + LuceneSignal::createSignal(objectSignal, getSync()); + return objectSignal; +} + +void LuceneSync::lock(int32_t timeout) { + getSync()->lock(); +} + +void LuceneSync::unlock() { + getSync()->unlock(); +} + +bool LuceneSync::holdsLock() { + return getSync()->holdsLock(); +} + +void LuceneSync::wait(int32_t timeout) { + getSignal()->wait(timeout); +} + +void LuceneSync::notifyAll() { + getSignal()->notifyAll(); +} + } diff --git a/src/core/util/LuceneThread.cpp b/src/core/util/LuceneThread.cpp index 977a15a6..383d0ae6 100644 --- a/src/core/util/LuceneThread.cpp +++ b/src/core/util/LuceneThread.cpp @@ -8,116 +8,103 @@ #include #include "LuceneThread.h" -namespace Lucene -{ - #if defined(_WIN32) || defined(_WIN64) - const int32_t LuceneThread::MAX_PRIORITY = THREAD_PRIORITY_HIGHEST; - const int32_t LuceneThread::NORM_PRIORITY = THREAD_PRIORITY_NORMAL; - const int32_t LuceneThread::MIN_PRIORITY = THREAD_PRIORITY_LOWEST; - #else - const int32_t LuceneThread::MAX_PRIORITY = 2; - const int32_t LuceneThread::NORM_PRIORITY = 0; - const int32_t LuceneThread::MIN_PRIORITY = -2; - #endif - - LuceneThread::LuceneThread() - { - running = false; - } +namespace Lucene { + +#if defined(_WIN32) || defined(_WIN64) +const int32_t LuceneThread::MAX_PRIORITY = THREAD_PRIORITY_HIGHEST; +const int32_t LuceneThread::NORM_PRIORITY = THREAD_PRIORITY_NORMAL; +const int32_t LuceneThread::MIN_PRIORITY = THREAD_PRIORITY_LOWEST; +#else +const int32_t LuceneThread::MAX_PRIORITY = 2; +const int32_t LuceneThread::NORM_PRIORITY = 0; +const int32_t LuceneThread::MIN_PRIORITY = -2; +#endif + +LuceneThread::LuceneThread() { + running = false; +} - LuceneThread::~LuceneThread() - { - } +LuceneThread::~LuceneThread() { +} - void LuceneThread::start() - { - setRunning(false); - thread = newInstance(LuceneThread::runThread, this); - setRunning(true); - } +void LuceneThread::start() { + setRunning(false); + thread = newInstance(LuceneThread::runThread, this); + setRunning(true); +} - void LuceneThread::runThread(LuceneThread* thread) - { - LuceneThreadPtr threadObject(thread->shared_from_this()); - try - { - threadObject->run(); - } - catch (...) - { - } - threadObject->setRunning(false); - threadObject.reset(); +void LuceneThread::runThread(LuceneThread* thread) { + LuceneThreadPtr threadObject(thread->shared_from_this()); + try { + threadObject->run(); + } catch (...) { } + threadObject->setRunning(false); + threadObject.reset(); +} - void LuceneThread::setRunning(bool running) - { - SyncLock syncLock(this); - this->running = running; - } +void LuceneThread::setRunning(bool running) { + SyncLock syncLock(this); + this->running = running; +} - bool LuceneThread::isRunning() - { - SyncLock syncLock(this); - return running; - } +bool LuceneThread::isRunning() { + SyncLock syncLock(this); + return running; +} - bool LuceneThread::isAlive() - { - return (thread && isRunning()); - } +bool LuceneThread::isAlive() { + return (thread && isRunning()); +} - void LuceneThread::setPriority(int32_t priority) - { - #if defined(_WIN32) || defined(_WIN64) - if (thread) - SetThreadPriority(thread->native_handle(), priority); - #endif +void LuceneThread::setPriority(int32_t priority) { +#if defined(_WIN32) || defined(_WIN64) + if (thread) { + SetThreadPriority(thread->native_handle(), priority); } +#endif +} - int32_t LuceneThread::getPriority() - { - #if defined(_WIN32) || defined(_WIN64) - return thread ? GetThreadPriority(thread->native_handle()) : NORM_PRIORITY; - #else - return NORM_PRIORITY; - #endif - } +int32_t LuceneThread::getPriority() { +#if defined(_WIN32) || defined(_WIN64) + return thread ? GetThreadPriority(thread->native_handle()) : NORM_PRIORITY; +#else + return NORM_PRIORITY; +#endif +} - void LuceneThread::yield() - { - if (thread) - thread->yield(); +void LuceneThread::yield() { + if (thread) { + thread->yield(); } +} - bool LuceneThread::join(int32_t timeout) - { - while (isAlive() && !thread->timed_join(boost::posix_time::milliseconds(timeout))) - { - if (timeout != 0) - return false; - if (thread->timed_join(boost::posix_time::milliseconds(10))) - return true; +bool LuceneThread::join(int32_t timeout) { + while (isAlive() && !thread->timed_join(boost::posix_time::milliseconds(timeout))) { + if (timeout != 0) { + return false; + } + if (thread->timed_join(boost::posix_time::milliseconds(10))) { + return true; } - return true; } + return true; +} - int64_t LuceneThread::currentId() - { - #if defined(_WIN32) || defined(_WIN64) - return (int64_t)GetCurrentThreadId(); - #else - return (int64_t)pthread_self(); - #endif - } +int64_t LuceneThread::currentId() { +#if defined(_WIN32) || defined(_WIN64) + return (int64_t)GetCurrentThreadId(); +#else + return (int64_t)pthread_self(); +#endif +} - void LuceneThread::threadSleep(int32_t time) - { - boost::this_thread::sleep(boost::posix_time::milliseconds(time)); - } +void LuceneThread::threadSleep(int32_t time) { + boost::this_thread::sleep(boost::posix_time::milliseconds(time)); +} + +void LuceneThread::threadYield() { + boost::this_thread::yield(); +} - void LuceneThread::threadYield() - { - boost::this_thread::yield(); - } } diff --git a/src/core/util/MiscUtils.cpp b/src/core/util/MiscUtils.cpp index 68c19fe1..5a88722d 100644 --- a/src/core/util/MiscUtils.cpp +++ b/src/core/util/MiscUtils.cpp @@ -8,144 +8,126 @@ #include "MiscUtils.h" #include "LuceneObject.h" -namespace Lucene -{ - const uint32_t MiscUtils::SINGLE_EXPONENT_MASK = 0x7f800000; - const uint32_t MiscUtils::SINGLE_MANTISSA_MASK = 0x007fffff; - const uint32_t MiscUtils::SINGLE_NAN_BITS = (MiscUtils::SINGLE_EXPONENT_MASK | 0x00400000); - - const uint64_t MiscUtils::DOUBLE_SIGN_MASK = 0x8000000000000000LL; - const uint64_t MiscUtils::DOUBLE_EXPONENT_MASK = 0x7ff0000000000000LL; - const uint64_t MiscUtils::DOUBLE_MANTISSA_MASK = 0x000fffffffffffffLL; - const uint64_t MiscUtils::DOUBLE_NAN_BITS = DOUBLE_EXPONENT_MASK | 0x0008000000000000LL; - - uint64_t MiscUtils::getTimeMillis(boost::posix_time::ptime time) - { - return boost::posix_time::time_duration(time - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_milliseconds(); - } +namespace Lucene { - uint64_t MiscUtils::currentTimeMillis() - { - return getTimeMillis(boost::posix_time::microsec_clock::universal_time()); - } +const uint32_t MiscUtils::SINGLE_EXPONENT_MASK = 0x7f800000; +const uint32_t MiscUtils::SINGLE_MANTISSA_MASK = 0x007fffff; +const uint32_t MiscUtils::SINGLE_NAN_BITS = (MiscUtils::SINGLE_EXPONENT_MASK | 0x00400000); - int32_t MiscUtils::getNextSize(int32_t targetSize) - { - return (targetSize >> 3) + (targetSize < 9 ? 3 : 6) + targetSize; - } +const uint64_t MiscUtils::DOUBLE_SIGN_MASK = 0x8000000000000000LL; +const uint64_t MiscUtils::DOUBLE_EXPONENT_MASK = 0x7ff0000000000000LL; +const uint64_t MiscUtils::DOUBLE_MANTISSA_MASK = 0x000fffffffffffffLL; +const uint64_t MiscUtils::DOUBLE_NAN_BITS = DOUBLE_EXPONENT_MASK | 0x0008000000000000LL; - int32_t MiscUtils::getShrinkSize(int32_t currentSize, int32_t targetSize) - { - int32_t newSize = getNextSize(targetSize); - return (newSize < currentSize / 2) ? newSize : currentSize; - } +uint64_t MiscUtils::getTimeMillis(boost::posix_time::ptime time) { + return boost::posix_time::time_duration(time - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_milliseconds(); +} + +uint64_t MiscUtils::currentTimeMillis() { + return getTimeMillis(boost::posix_time::microsec_clock::universal_time()); +} + +int32_t MiscUtils::getNextSize(int32_t targetSize) { + return (targetSize >> 3) + (targetSize < 9 ? 3 : 6) + targetSize; +} + +int32_t MiscUtils::getShrinkSize(int32_t currentSize, int32_t targetSize) { + int32_t newSize = getNextSize(targetSize); + return (newSize < currentSize / 2) ? newSize : currentSize; +} - int32_t MiscUtils::bytesDifference(uint8_t* bytes1, int32_t len1, uint8_t* bytes2, int32_t len2) - { - int32_t len = std::min(len1, len2); - for (int32_t i = 0; i < len; ++i) - { - if (bytes1[i] != bytes2[i]) - return i; +int32_t MiscUtils::bytesDifference(uint8_t* bytes1, int32_t len1, uint8_t* bytes2, int32_t len2) { + int32_t len = std::min(len1, len2); + for (int32_t i = 0; i < len; ++i) { + if (bytes1[i] != bytes2[i]) { + return i; } - return len; } + return len; +} - int32_t MiscUtils::hashCode(const wchar_t* array, int32_t start, int32_t end) - { - return hashCode(array + start, array + end, hashNumeric); - } +int32_t MiscUtils::hashCode(const wchar_t* array, int32_t start, int32_t end) { + return hashCode(array + start, array + end, hashNumeric); +} - int32_t MiscUtils::hashCode(const uint8_t* array, int32_t start, int32_t end) - { - return hashCode(array + start, array + end, hashNumeric); - } +int32_t MiscUtils::hashCode(const uint8_t* array, int32_t start, int32_t end) { + return hashCode(array + start, array + end, hashNumeric); +} - int32_t MiscUtils::hashCode(bool value) - { - return value ? 1231 : 1237; - } +int32_t MiscUtils::hashCode(bool value) { + return value ? 1231 : 1237; +} - int32_t MiscUtils::doubleToIntBits(double value) - { - int32_t intValue = 0; - float floatValue = (float)value; - std::memcpy(&intValue, &floatValue, sizeof(float)); +int32_t MiscUtils::doubleToIntBits(double value) { + int32_t intValue = 0; + float floatValue = (float)value; + std::memcpy(&intValue, &floatValue, sizeof(float)); - if ((intValue & SINGLE_EXPONENT_MASK) == SINGLE_EXPONENT_MASK) - { - if (intValue & SINGLE_MANTISSA_MASK) - return SINGLE_NAN_BITS; + if ((intValue & SINGLE_EXPONENT_MASK) == SINGLE_EXPONENT_MASK) { + if (intValue & SINGLE_MANTISSA_MASK) { + return SINGLE_NAN_BITS; } - - return intValue; } - int32_t MiscUtils::doubleToRawIntBits(double value) - { - int32_t intValue = 0; - float floatValue = (float)value; - std::memcpy(&intValue, &floatValue, sizeof(float)); - return intValue; - } + return intValue; +} - double MiscUtils::intBitsToDouble(int32_t bits) - { - float floatValue = 0; - std::memcpy(&floatValue, &bits, sizeof(int32_t)); - return (double)floatValue; - } +int32_t MiscUtils::doubleToRawIntBits(double value) { + int32_t intValue = 0; + float floatValue = (float)value; + std::memcpy(&intValue, &floatValue, sizeof(float)); + return intValue; +} - int64_t MiscUtils::doubleToLongBits(double value) - { - int64_t longValue = 0; - std::memcpy(&longValue, &value, sizeof(double)); +double MiscUtils::intBitsToDouble(int32_t bits) { + float floatValue = 0; + std::memcpy(&floatValue, &bits, sizeof(int32_t)); + return (double)floatValue; +} - if ((longValue & DOUBLE_EXPONENT_MASK) == DOUBLE_EXPONENT_MASK) - { - if (longValue & DOUBLE_MANTISSA_MASK) - return DOUBLE_NAN_BITS; - } +int64_t MiscUtils::doubleToLongBits(double value) { + int64_t longValue = 0; + std::memcpy(&longValue, &value, sizeof(double)); - return longValue; + if ((longValue & DOUBLE_EXPONENT_MASK) == DOUBLE_EXPONENT_MASK) { + if (longValue & DOUBLE_MANTISSA_MASK) { + return DOUBLE_NAN_BITS; + } } - int64_t MiscUtils::doubleToRawLongBits(double value) - { - int64_t longValue = 0; - std::memcpy(&longValue, &value, sizeof(double)); - return longValue; - } + return longValue; +} - double MiscUtils::longBitsToDouble(int64_t bits) - { - double doubleValue = 0; - std::memcpy(&doubleValue, &bits, sizeof(int64_t)); - return doubleValue; - } +int64_t MiscUtils::doubleToRawLongBits(double value) { + int64_t longValue = 0; + std::memcpy(&longValue, &value, sizeof(double)); + return longValue; +} - bool MiscUtils::isInfinite(double value) - { - return (value == std::numeric_limits::infinity() || value == -std::numeric_limits::infinity()); - } +double MiscUtils::longBitsToDouble(int64_t bits) { + double doubleValue = 0; + std::memcpy(&doubleValue, &bits, sizeof(int64_t)); + return doubleValue; +} - bool MiscUtils::isNaN(double value) - { - return (value != value); - } +bool MiscUtils::isInfinite(double value) { + return (value == std::numeric_limits::infinity() || value == -std::numeric_limits::infinity()); +} - bool MiscUtils::equalTypes(const LuceneObjectPtr& first, const LuceneObjectPtr& second) - { - return (typeid(*first) == typeid(*second)); - } +bool MiscUtils::isNaN(double value) { + return (value != value); +} - int64_t MiscUtils::unsignedShift(int64_t num, int64_t shift) - { - return (shift & 0x3f) == 0 ? num : (((uint64_t)num >> 1) & 0x7fffffffffffffffLL) >> ((shift & 0x3f) - 1); - } +bool MiscUtils::equalTypes(const LuceneObjectPtr& first, const LuceneObjectPtr& second) { + return (typeid(*first) == typeid(*second)); +} + +int64_t MiscUtils::unsignedShift(int64_t num, int64_t shift) { + return (shift & 0x3f) == 0 ? num : (((uint64_t)num >> 1) & 0x7fffffffffffffffLL) >> ((shift & 0x3f) - 1); +} + +int32_t MiscUtils::unsignedShift(int32_t num, int32_t shift) { + return (shift & 0x1f) == 0 ? num : (((uint32_t)num >> 1) & 0x7fffffff) >> ((shift & 0x1f) - 1); +} - int32_t MiscUtils::unsignedShift(int32_t num, int32_t shift) - { - return (shift & 0x1f) == 0 ? num : (((uint32_t)num >> 1) & 0x7fffffff) >> ((shift & 0x1f) - 1); - } } diff --git a/src/core/util/NumericUtils.cpp b/src/core/util/NumericUtils.cpp index 4165390f..3f3f4f64 100644 --- a/src/core/util/NumericUtils.cpp +++ b/src/core/util/NumericUtils.cpp @@ -9,250 +9,229 @@ #include "MiscUtils.h" #include "StringUtils.h" -namespace Lucene -{ - /// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, - /// and {@link NumericRangeFilter} as default. - const int32_t NumericUtils::PRECISION_STEP_DEFAULT = 4; - - /// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + - /// shift in the first character. - const wchar_t NumericUtils::SHIFT_START_LONG = (wchar_t)0x20; - - /// The maximum term length (used for char[] buffer size) for encoding long values. - /// @see #longToPrefixCoded(long,int,char[]) - const int32_t NumericUtils::BUF_SIZE_LONG = 63 / 7 + 2; - - /// Integers are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_INT + - /// shift in the first character. - const wchar_t NumericUtils::SHIFT_START_INT = (wchar_t)0x60; - - /// The maximum term length (used for char[] buffer size) for encoding int values. - /// @see #intToPrefixCoded(int,int,char[]) - const int32_t NumericUtils::BUF_SIZE_INT = 31 / 7 + 2; - - NumericUtils::~NumericUtils() - { - } +namespace Lucene { - int32_t NumericUtils::longToPrefixCoded(int64_t val, int32_t shift, CharArray buffer) - { - if (shift > 63 || shift < 0) - boost::throw_exception(IllegalArgumentException(L"Illegal shift value, must be 0..63")); - int32_t nChars = (63 - shift) / 7 + 1; - int32_t len = nChars + 1; - buffer[0] = (wchar_t)(SHIFT_START_LONG + shift); - int64_t sortableBits = val ^ 0x8000000000000000LL; - sortableBits = MiscUtils::unsignedShift(sortableBits, (int64_t)shift); - while (nChars >= 1) - { - // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is - // right-justified so that lucene can prefix-encode the terms more efficiently. - buffer[nChars--] = (wchar_t)(sortableBits & 0x7f); - sortableBits = MiscUtils::unsignedShift(sortableBits, (int64_t)7); - } - return len; - } +/// The default precision step used by {@link NumericField}, {@link NumericTokenStream}, {@link NumericRangeQuery}, +/// and {@link NumericRangeFilter} as default. +const int32_t NumericUtils::PRECISION_STEP_DEFAULT = 4; - String NumericUtils::longToPrefixCoded(int64_t val, int32_t shift) - { - CharArray buffer(CharArray::newInstance(BUF_SIZE_LONG)); - int32_t len = longToPrefixCoded(val, shift, buffer); - return String(buffer.get(), len); - } +/// Longs are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_LONG + +/// shift in the first character. +const wchar_t NumericUtils::SHIFT_START_LONG = (wchar_t)0x20; - String NumericUtils::longToPrefixCoded(int64_t val) - { - return longToPrefixCoded(val, 0); - } +/// The maximum term length (used for char[] buffer size) for encoding long values. +/// @see #longToPrefixCoded(long,int,char[]) +const int32_t NumericUtils::BUF_SIZE_LONG = 63 / 7 + 2; - int32_t NumericUtils::intToPrefixCoded(int32_t val, int32_t shift, CharArray buffer) - { - if (shift > 31 || shift < 0) - boost::throw_exception(IllegalArgumentException(L"Illegal shift value, must be 0..31")); - int32_t nChars = (31 - shift) / 7 + 1; - int32_t len = nChars + 1; - buffer[0] = (wchar_t)(SHIFT_START_INT + shift); - int32_t sortableBits = val ^ 0x80000000; - sortableBits = MiscUtils::unsignedShift(sortableBits, shift); - while (nChars >= 1) - { - // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is - // right-justified so that lucene can prefix-encode the terms more efficiently. - buffer[nChars--] = (wchar_t)(sortableBits & 0x7f); - sortableBits = MiscUtils::unsignedShift(sortableBits, 7); - } - return len; - } +/// Integers are stored at lower precision by shifting off lower bits. The shift count is stored as SHIFT_START_INT + +/// shift in the first character. +const wchar_t NumericUtils::SHIFT_START_INT = (wchar_t)0x60; - String NumericUtils::intToPrefixCoded(int32_t val, int32_t shift) - { - CharArray buffer(CharArray::newInstance(BUF_SIZE_INT)); - int32_t len = intToPrefixCoded(val, shift, buffer); - return String(buffer.get(), len); - } +/// The maximum term length (used for char[] buffer size) for encoding int values. +/// @see #intToPrefixCoded(int,int,char[]) +const int32_t NumericUtils::BUF_SIZE_INT = 31 / 7 + 2; - String NumericUtils::intToPrefixCoded(int32_t val) - { - return intToPrefixCoded(val, 0); - } +NumericUtils::~NumericUtils() { +} + +int32_t NumericUtils::longToPrefixCoded(int64_t val, int32_t shift, CharArray buffer) { + if (shift > 63 || shift < 0) { + boost::throw_exception(IllegalArgumentException(L"Illegal shift value, must be 0..63")); + } + int32_t nChars = (63 - shift) / 7 + 1; + int32_t len = nChars + 1; + buffer[0] = (wchar_t)(SHIFT_START_LONG + shift); + int64_t sortableBits = val ^ 0x8000000000000000LL; + sortableBits = MiscUtils::unsignedShift(sortableBits, (int64_t)shift); + while (nChars >= 1) { + // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is + // right-justified so that lucene can prefix-encode the terms more efficiently. + buffer[nChars--] = (wchar_t)(sortableBits & 0x7f); + sortableBits = MiscUtils::unsignedShift(sortableBits, (int64_t)7); + } + return len; +} + +String NumericUtils::longToPrefixCoded(int64_t val, int32_t shift) { + CharArray buffer(CharArray::newInstance(BUF_SIZE_LONG)); + int32_t len = longToPrefixCoded(val, shift, buffer); + return String(buffer.get(), len); +} + +String NumericUtils::longToPrefixCoded(int64_t val) { + return longToPrefixCoded(val, 0); +} + +int32_t NumericUtils::intToPrefixCoded(int32_t val, int32_t shift, CharArray buffer) { + if (shift > 31 || shift < 0) { + boost::throw_exception(IllegalArgumentException(L"Illegal shift value, must be 0..31")); + } + int32_t nChars = (31 - shift) / 7 + 1; + int32_t len = nChars + 1; + buffer[0] = (wchar_t)(SHIFT_START_INT + shift); + int32_t sortableBits = val ^ 0x80000000; + sortableBits = MiscUtils::unsignedShift(sortableBits, shift); + while (nChars >= 1) { + // Store 7 bits per character for good efficiency when UTF-8 encoding. The whole number is + // right-justified so that lucene can prefix-encode the terms more efficiently. + buffer[nChars--] = (wchar_t)(sortableBits & 0x7f); + sortableBits = MiscUtils::unsignedShift(sortableBits, 7); + } + return len; +} + +String NumericUtils::intToPrefixCoded(int32_t val, int32_t shift) { + CharArray buffer(CharArray::newInstance(BUF_SIZE_INT)); + int32_t len = intToPrefixCoded(val, shift, buffer); + return String(buffer.get(), len); +} - int64_t NumericUtils::prefixCodedToLong(const String& prefixCoded) - { - int32_t shift = prefixCoded[0] - SHIFT_START_LONG; - if (shift > 63 || shift < 0) - boost::throw_exception(NumberFormatException(L"Invalid shift value in prefixCoded string (is encoded value really a LONG?)")); - int64_t sortableBits = 0; - for (int32_t i = 1, len = prefixCoded.length(); i < len; ++i) - { - sortableBits <<= 7; - wchar_t ch = prefixCoded[i]; - if (ch > 0x7f) - { - boost::throw_exception(NumberFormatException(L"Invalid prefixCoded numerical value representation (char " + StringUtils::toString(ch, 16) + - L" at position " + StringUtils::toString(i) + L" is invalid)")); - } - sortableBits |= (int64_t)ch; +String NumericUtils::intToPrefixCoded(int32_t val) { + return intToPrefixCoded(val, 0); +} + +int64_t NumericUtils::prefixCodedToLong(const String& prefixCoded) { + int32_t shift = prefixCoded[0] - SHIFT_START_LONG; + if (shift > 63 || shift < 0) { + boost::throw_exception(NumberFormatException(L"Invalid shift value in prefixCoded string (is encoded value really a LONG?)")); + } + int64_t sortableBits = 0; + for (int32_t i = 1, len = prefixCoded.length(); i < len; ++i) { + sortableBits <<= 7; + wchar_t ch = prefixCoded[i]; + if (ch > 0x7f) { + boost::throw_exception(NumberFormatException(L"Invalid prefixCoded numerical value representation (char " + StringUtils::toString(ch, 16) + + L" at position " + StringUtils::toString(i) + L" is invalid)")); } - return (sortableBits << shift) ^ 0x8000000000000000LL; + sortableBits |= (int64_t)ch; } + return (sortableBits << shift) ^ 0x8000000000000000LL; +} - int32_t NumericUtils::prefixCodedToInt(const String& prefixCoded) - { - int32_t shift = prefixCoded[0] - SHIFT_START_INT; - if (shift > 31 || shift < 0) - boost::throw_exception(NumberFormatException(L"Invalid shift value in prefixCoded string (is encoded value really a INT?)")); - int32_t sortableBits = 0; - for (int32_t i = 1, len = prefixCoded.length(); i < len; ++i) - { - sortableBits <<= 7; - wchar_t ch = prefixCoded[i]; - if (ch > 0x7f) - { - boost::throw_exception(NumberFormatException(L"Invalid prefixCoded numerical value representation (char " + StringUtils::toString(ch, 16) + - L" at position " + StringUtils::toString(i) + L" is invalid)")); - } - sortableBits |= (int32_t)ch; +int32_t NumericUtils::prefixCodedToInt(const String& prefixCoded) { + int32_t shift = prefixCoded[0] - SHIFT_START_INT; + if (shift > 31 || shift < 0) { + boost::throw_exception(NumberFormatException(L"Invalid shift value in prefixCoded string (is encoded value really a INT?)")); + } + int32_t sortableBits = 0; + for (int32_t i = 1, len = prefixCoded.length(); i < len; ++i) { + sortableBits <<= 7; + wchar_t ch = prefixCoded[i]; + if (ch > 0x7f) { + boost::throw_exception(NumberFormatException(L"Invalid prefixCoded numerical value representation (char " + StringUtils::toString(ch, 16) + + L" at position " + StringUtils::toString(i) + L" is invalid)")); } - return (sortableBits << shift) ^ 0x80000000; + sortableBits |= (int32_t)ch; } + return (sortableBits << shift) ^ 0x80000000; +} - int64_t NumericUtils::doubleToSortableLong(double val) - { - int64_t f = MiscUtils::doubleToRawLongBits(val); - if (f < 0) - f ^= 0x7fffffffffffffffLL; - return f; +int64_t NumericUtils::doubleToSortableLong(double val) { + int64_t f = MiscUtils::doubleToRawLongBits(val); + if (f < 0) { + f ^= 0x7fffffffffffffffLL; } + return f; +} - String NumericUtils::doubleToPrefixCoded(double val) - { - return longToPrefixCoded(doubleToSortableLong(val)); - } +String NumericUtils::doubleToPrefixCoded(double val) { + return longToPrefixCoded(doubleToSortableLong(val)); +} - double NumericUtils::sortableLongToDouble(int64_t val) - { - if (val < 0) - val ^= 0x7fffffffffffffffLL; - return MiscUtils::longBitsToDouble(val); +double NumericUtils::sortableLongToDouble(int64_t val) { + if (val < 0) { + val ^= 0x7fffffffffffffffLL; } + return MiscUtils::longBitsToDouble(val); +} - double NumericUtils::prefixCodedToDouble(const String& val) - { - return sortableLongToDouble(prefixCodedToLong(val)); - } +double NumericUtils::prefixCodedToDouble(const String& val) { + return sortableLongToDouble(prefixCodedToLong(val)); +} - void NumericUtils::splitLongRange(const LongRangeBuilderPtr& builder, int32_t precisionStep, int64_t minBound, int64_t maxBound) - { - splitRange(builder, 64, precisionStep, minBound, maxBound); - } +void NumericUtils::splitLongRange(const LongRangeBuilderPtr& builder, int32_t precisionStep, int64_t minBound, int64_t maxBound) { + splitRange(builder, 64, precisionStep, minBound, maxBound); +} - void NumericUtils::splitIntRange(const IntRangeBuilderPtr& builder, int32_t precisionStep, int32_t minBound, int32_t maxBound) - { - splitRange(builder, 32, precisionStep, (int64_t)minBound, (int64_t)maxBound); - } +void NumericUtils::splitIntRange(const IntRangeBuilderPtr& builder, int32_t precisionStep, int32_t minBound, int32_t maxBound) { + splitRange(builder, 32, precisionStep, (int64_t)minBound, (int64_t)maxBound); +} - void NumericUtils::splitRange(const LuceneObjectPtr& builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound) - { - if (precisionStep < 1) - boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); - if (minBound > maxBound) - return; - for (int32_t shift = 0; ; shift += precisionStep) - { - // calculate new bounds for inner precision - int64_t diff = (int64_t)1 << (shift + precisionStep); - int64_t mask = (((int64_t)1 << precisionStep) - (int64_t)1) << shift; - bool hasLower = ((minBound & mask) != 0); - bool hasUpper = ((maxBound & mask) != mask); - int64_t nextMinBound = ((hasLower ? (minBound + diff) : minBound) & ~mask); - int64_t nextMaxBound = ((hasUpper ? (maxBound - diff) : maxBound) & ~mask); - bool lowerWrapped = nextMinBound < minBound; - bool upperWrapped = nextMaxBound > maxBound; - - if (shift + precisionStep >= valSize || nextMinBound>nextMaxBound || lowerWrapped || upperWrapped) - { - // We are in the lowest precision or the next precision is not available. - addRange(builder, valSize, minBound, maxBound, shift); - break; // exit the split recursion loop - } - - if (hasLower) - addRange(builder, valSize, minBound, minBound | mask, shift); - if (hasUpper) - addRange(builder, valSize, maxBound & ~mask, maxBound, shift); - - // recurse to next precision - minBound = nextMinBound; - maxBound = nextMaxBound; +void NumericUtils::splitRange(const LuceneObjectPtr& builder, int32_t valSize, int32_t precisionStep, int64_t minBound, int64_t maxBound) { + if (precisionStep < 1) { + boost::throw_exception(IllegalArgumentException(L"precisionStep must be >=1")); + } + if (minBound > maxBound) { + return; + } + for (int32_t shift = 0; ; shift += precisionStep) { + // calculate new bounds for inner precision + int64_t diff = (int64_t)1 << (shift + precisionStep); + int64_t mask = (((int64_t)1 << precisionStep) - (int64_t)1) << shift; + bool hasLower = ((minBound & mask) != 0); + bool hasUpper = ((maxBound & mask) != mask); + int64_t nextMinBound = ((hasLower ? (minBound + diff) : minBound) & ~mask); + int64_t nextMaxBound = ((hasUpper ? (maxBound - diff) : maxBound) & ~mask); + bool lowerWrapped = nextMinBound < minBound; + bool upperWrapped = nextMaxBound > maxBound; + + if (shift + precisionStep >= valSize || nextMinBound>nextMaxBound || lowerWrapped || upperWrapped) { + // We are in the lowest precision or the next precision is not available. + addRange(builder, valSize, minBound, maxBound, shift); + break; // exit the split recursion loop } - } - void NumericUtils::addRange(const LuceneObjectPtr& builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift) - { - // for the max bound set all lower bits (that were shifted away): this is important for testing or other - // usages of the splitted range (eg. to reconstruct the full range). The prefixEncoding will remove the - // bits anyway, so they do not hurt! - maxBound |= ((int64_t)1 << shift) - (int64_t)1; - // delegate to correct range builder - switch (valSize) - { - case 64: - boost::dynamic_pointer_cast(builder)->addRange(minBound, maxBound, shift); - break; - case 32: - boost::dynamic_pointer_cast(builder)->addRange((int32_t)minBound, (int32_t)maxBound, shift); - break; - default: - boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64.")); + if (hasLower) { + addRange(builder, valSize, minBound, minBound | mask, shift); + } + if (hasUpper) { + addRange(builder, valSize, maxBound & ~mask, maxBound, shift); } - } - LongRangeBuilder::~LongRangeBuilder() - { + // recurse to next precision + minBound = nextMinBound; + maxBound = nextMaxBound; } +} - void LongRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) - { - boost::throw_exception(UnsupportedOperationException()); +void NumericUtils::addRange(const LuceneObjectPtr& builder, int32_t valSize, int64_t minBound, int64_t maxBound, int32_t shift) { + // for the max bound set all lower bits (that were shifted away): this is important for testing or other + // usages of the splitted range (eg. to reconstruct the full range). The prefixEncoding will remove the + // bits anyway, so they do not hurt! + maxBound |= ((int64_t)1 << shift) - (int64_t)1; + // delegate to correct range builder + switch (valSize) { + case 64: + boost::dynamic_pointer_cast(builder)->addRange(minBound, maxBound, shift); + break; + case 32: + boost::dynamic_pointer_cast(builder)->addRange((int32_t)minBound, (int32_t)maxBound, shift); + break; + default: + boost::throw_exception(IllegalArgumentException(L"valSize must be 32 or 64.")); } +} - void LongRangeBuilder::addRange(int64_t min, int64_t max, int32_t shift) - { - addRange(NumericUtils::longToPrefixCoded(min, shift), NumericUtils::longToPrefixCoded(max, shift)); - } +LongRangeBuilder::~LongRangeBuilder() { +} - IntRangeBuilder::~IntRangeBuilder() - { - } +void LongRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { + boost::throw_exception(UnsupportedOperationException()); +} - void IntRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) - { - boost::throw_exception(UnsupportedOperationException()); - } +void LongRangeBuilder::addRange(int64_t min, int64_t max, int32_t shift) { + addRange(NumericUtils::longToPrefixCoded(min, shift), NumericUtils::longToPrefixCoded(max, shift)); +} + +IntRangeBuilder::~IntRangeBuilder() { +} + +void IntRangeBuilder::addRange(const String& minPrefixCoded, const String& maxPrefixCoded) { + boost::throw_exception(UnsupportedOperationException()); +} + +void IntRangeBuilder::addRange(int32_t min, int32_t max, int32_t shift) { + addRange(NumericUtils::intToPrefixCoded(min, shift), NumericUtils::intToPrefixCoded(max, shift)); +} - void IntRangeBuilder::addRange(int32_t min, int32_t max, int32_t shift) - { - addRange(NumericUtils::intToPrefixCoded(min, shift), NumericUtils::intToPrefixCoded(max, shift)); - } } diff --git a/src/core/util/OpenBitSet.cpp b/src/core/util/OpenBitSet.cpp index 869f33ab..c5412a18 100644 --- a/src/core/util/OpenBitSet.cpp +++ b/src/core/util/OpenBitSet.cpp @@ -10,603 +10,566 @@ #include "BitUtil.h" #include "MiscUtils.h" -namespace Lucene -{ - OpenBitSet::OpenBitSet(int64_t numBits) - { - bits = LongArray::newInstance(bits2words(numBits)); - MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0LL); - wlen = bits.size(); - } +namespace Lucene { - OpenBitSet::OpenBitSet(LongArray bits, int32_t numWords) - { - this->bits = bits; - this->wlen = numWords; - } +OpenBitSet::OpenBitSet(int64_t numBits) { + bits = LongArray::newInstance(bits2words(numBits)); + MiscUtils::arrayFill(bits.get(), 0, bits.size(), 0LL); + wlen = bits.size(); +} - OpenBitSet::~OpenBitSet() - { - } +OpenBitSet::OpenBitSet(LongArray bits, int32_t numWords) { + this->bits = bits; + this->wlen = numWords; +} - DocIdSetIteratorPtr OpenBitSet::iterator() - { - return newLucene(bits, wlen); - } +OpenBitSet::~OpenBitSet() { +} - bool OpenBitSet::isCacheable() - { - return true; - } +DocIdSetIteratorPtr OpenBitSet::iterator() { + return newLucene(bits, wlen); +} - int64_t OpenBitSet::capacity() - { - return bits.size() << 6; - } +bool OpenBitSet::isCacheable() { + return true; +} - int64_t OpenBitSet::size() - { - return capacity(); - } +int64_t OpenBitSet::capacity() { + return bits.size() << 6; +} - bool OpenBitSet::isEmpty() - { - return (cardinality() == 0); - } +int64_t OpenBitSet::size() { + return capacity(); +} - LongArray OpenBitSet::getBits() - { - return bits; - } +bool OpenBitSet::isEmpty() { + return (cardinality() == 0); +} - void OpenBitSet::setBits(LongArray bits) - { - this->bits = bits; - } +LongArray OpenBitSet::getBits() { + return bits; +} - int32_t OpenBitSet::getNumWords() - { - return wlen; - } +void OpenBitSet::setBits(LongArray bits) { + this->bits = bits; +} - void OpenBitSet::setNumWords(int32_t numWords) - { - this->wlen = numWords; - } +int32_t OpenBitSet::getNumWords() { + return wlen; +} - bool OpenBitSet::get(int32_t index) - { - int32_t 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.size()) - return false; - int32_t bit = (index & 0x3f); // mod 64 - int64_t bitmask = 1LL << bit; - return ((bits[i] & bitmask) != 0); - } +void OpenBitSet::setNumWords(int32_t numWords) { + this->wlen = numWords; +} - bool OpenBitSet::fastGet(int32_t index) - { - int32_t 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. - int32_t bit = (index & 0x3f); // mod 64 - int64_t bitmask = 1LL << bit; - return ((bits[i] & bitmask) != 0); +bool OpenBitSet::get(int32_t index) { + int32_t 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.size()) { + return false; } + int32_t bit = (index & 0x3f); // mod 64 + int64_t bitmask = 1LL << bit; + return ((bits[i] & bitmask) != 0); +} - bool OpenBitSet::get(int64_t index) - { - int32_t i = (int32_t)(index >> 6); // div 64 - if (i >= bits.size()) - return false; - int32_t bit = ((int32_t)index & 0x3f); // mod 64 - int64_t bitmask = 1LL << bit; - return ((bits[i] & bitmask) != 0); - } +bool OpenBitSet::fastGet(int32_t index) { + int32_t 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. + int32_t bit = (index & 0x3f); // mod 64 + int64_t bitmask = 1LL << bit; + return ((bits[i] & bitmask) != 0); +} - bool OpenBitSet::fastGet(int64_t index) - { - int32_t i = (int32_t)(index >> 6); // div 64 - int32_t bit = ((int32_t)index & 0x3f); // mod 64 - int64_t bitmask = 1LL << bit; - return ((bits[i] & bitmask) != 0); +bool OpenBitSet::get(int64_t index) { + int32_t i = (int32_t)(index >> 6); // div 64 + if (i >= bits.size()) { + return false; } + int32_t bit = ((int32_t)index & 0x3f); // mod 64 + int64_t bitmask = 1LL << bit; + return ((bits[i] & bitmask) != 0); +} - int32_t OpenBitSet::getBit(int32_t index) - { - int32_t i = index >> 6; // div 64 - int32_t bit = (index & 0x3f); // mod 64 - return (int32_t)MiscUtils::unsignedShift(bits[i], (int64_t)bit) & 0x01; - } +bool OpenBitSet::fastGet(int64_t index) { + int32_t i = (int32_t)(index >> 6); // div 64 + int32_t bit = ((int32_t)index & 0x3f); // mod 64 + int64_t bitmask = 1LL << bit; + return ((bits[i] & bitmask) != 0); +} - void OpenBitSet::set(int64_t index) - { - int32_t wordNum = expandingWordNum(index); - int32_t bit = (int32_t)index & 0x3f; - int64_t bitmask = 1LL << bit; - bits[wordNum] |= bitmask; - } +int32_t OpenBitSet::getBit(int32_t index) { + int32_t i = index >> 6; // div 64 + int32_t bit = (index & 0x3f); // mod 64 + return (int32_t)MiscUtils::unsignedShift(bits[i], (int64_t)bit) & 0x01; +} - void OpenBitSet::fastSet(int32_t index) - { - int32_t wordNum = index >> 6; // div 64 - int32_t bit = index & 0x3f; - int64_t bitmask = 1LL << bit; - bits[wordNum] |= bitmask; - } +void OpenBitSet::set(int64_t index) { + int32_t wordNum = expandingWordNum(index); + int32_t bit = (int32_t)index & 0x3f; + int64_t bitmask = 1LL << bit; + bits[wordNum] |= bitmask; +} - void OpenBitSet::fastSet(int64_t index) - { - int32_t wordNum = (int32_t)(index >> 6); - int32_t bit = (int32_t)index & 0x3f; - int64_t bitmask = 1LL << bit; - bits[wordNum] |= bitmask; - } +void OpenBitSet::fastSet(int32_t index) { + int32_t wordNum = index >> 6; // div 64 + int32_t bit = index & 0x3f; + int64_t bitmask = 1LL << bit; + bits[wordNum] |= bitmask; +} - void OpenBitSet::set(int64_t startIndex, int64_t endIndex) - { - if (endIndex <= startIndex) - return; +void OpenBitSet::fastSet(int64_t index) { + int32_t wordNum = (int32_t)(index >> 6); + int32_t bit = (int32_t)index & 0x3f; + int64_t bitmask = 1LL << bit; + bits[wordNum] |= bitmask; +} - int32_t startWord = (int32_t)(startIndex >> 6); +void OpenBitSet::set(int64_t startIndex, int64_t endIndex) { + if (endIndex <= startIndex) { + return; + } - // since endIndex is one past the end, this is index of the last word to be changed - int32_t endWord = expandingWordNum(endIndex - 1); + int32_t startWord = (int32_t)(startIndex >> 6); - int64_t startmask = -1LL << (startIndex & 0x3f); - int64_t endmask = MiscUtils::unsignedShift(-1LL, -endIndex); + // since endIndex is one past the end, this is index of the last word to be changed + int32_t endWord = expandingWordNum(endIndex - 1); - if (startWord == endWord) - { - bits[startWord] |= (startmask & endmask); - return; - } + int64_t startmask = -1LL << (startIndex & 0x3f); + int64_t endmask = MiscUtils::unsignedShift(-1LL, -endIndex); - bits[startWord] |= startmask; - MiscUtils::arrayFill(bits.get(), startWord + 1, endWord, -1LL); - bits[endWord] |= endmask; + if (startWord == endWord) { + bits[startWord] |= (startmask & endmask); + return; } - int32_t OpenBitSet::expandingWordNum(int64_t index) - { - int32_t wordNum = (int32_t)(index >> 6); - if (wordNum >= wlen) - { - ensureCapacity(index + 1); - wlen = wordNum + 1; - } - return wordNum; + bits[startWord] |= startmask; + MiscUtils::arrayFill(bits.get(), startWord + 1, endWord, -1LL); + bits[endWord] |= endmask; +} + +int32_t OpenBitSet::expandingWordNum(int64_t index) { + int32_t wordNum = (int32_t)(index >> 6); + if (wordNum >= wlen) { + ensureCapacity(index + 1); + wlen = wordNum + 1; } + return wordNum; +} - void OpenBitSet::fastClear(int32_t index) - { - int32_t wordNum = index >> 6; - int32_t bit = (index & 0x03f); - int64_t bitmask = 1LL << bit; - bits[wordNum] &= ~bitmask; +void OpenBitSet::fastClear(int32_t index) { + int32_t wordNum = index >> 6; + int32_t bit = (index & 0x03f); + int64_t bitmask = 1LL << bit; + bits[wordNum] &= ~bitmask; +} + +void OpenBitSet::fastClear(int64_t index) { + int32_t wordNum = (int32_t)(index >> 6); + int32_t bit = (int32_t)index & 0x3f; + int64_t bitmask = 1LL << bit; + bits[wordNum] &= ~bitmask; +} + +void OpenBitSet::clear(int64_t index) { + int32_t wordNum = (int32_t)(index >> 6); + if (wordNum >= wlen) { + return; } + int32_t bit = (int32_t)index & 0x3f; + int64_t bitmask = 1LL << bit; + bits[wordNum] &= ~bitmask; +} - void OpenBitSet::fastClear(int64_t index) - { - int32_t wordNum = (int32_t)(index >> 6); - int32_t bit = (int32_t)index & 0x3f; - int64_t bitmask = 1LL << bit; - bits[wordNum] &= ~bitmask; +void OpenBitSet::clear(int32_t startIndex, int32_t endIndex) { + if (endIndex <= startIndex) { + return; } - void OpenBitSet::clear(int64_t index) - { - int32_t wordNum = (int32_t)(index >> 6); - if (wordNum >= wlen) - return; - int32_t bit = (int32_t)index & 0x3f; - int64_t bitmask = 1LL << bit; - bits[wordNum] &= ~bitmask; + int32_t startWord = (startIndex >> 6); + if (startWord >= wlen) { + return; } - void OpenBitSet::clear(int32_t startIndex, int32_t endIndex) - { - if (endIndex <= startIndex) - return; + // since endIndex is one past the end, this is index of the last word to be changed. + int32_t endWord = ((endIndex - 1) >> 6); - int32_t startWord = (startIndex >> 6); - if (startWord >= wlen) - return; + int64_t startmask = -1LL << (startIndex & 0x3f); + int64_t endmask = MiscUtils::unsignedShift(-1LL, (int64_t)-endIndex); - // since endIndex is one past the end, this is index of the last word to be changed. - int32_t endWord = ((endIndex - 1) >> 6); + // invert masks since we are clearing + startmask = ~startmask; + endmask = ~endmask; - int64_t startmask = -1LL << (startIndex & 0x3f); - int64_t endmask = MiscUtils::unsignedShift(-1LL, (int64_t)-endIndex); + if (startWord == endWord) { + bits[startWord] &= (startmask | endmask); + return; + } - // invert masks since we are clearing - startmask = ~startmask; - endmask = ~endmask; + bits[startWord] &= startmask; - if (startWord == endWord) - { - bits[startWord] &= (startmask | endmask); - return; - } + int32_t middle = std::min(wlen, endWord); + MiscUtils::arrayFill(bits.get(), startWord + 1, middle, 0LL); + if (endWord < wlen) { + bits[endWord] &= endmask; + } +} - bits[startWord] &= startmask; +void OpenBitSet::clear(int64_t startIndex, int64_t endIndex) { + if (endIndex <= startIndex) { + return; + } - int32_t middle = std::min(wlen, endWord); - MiscUtils::arrayFill(bits.get(), startWord + 1, middle, 0LL); - if (endWord < wlen) - bits[endWord] &= endmask; + int32_t startWord = (int32_t)(startIndex>>6); + if (startWord >= wlen) { + return; } - void OpenBitSet::clear(int64_t startIndex, int64_t endIndex) - { - if (endIndex <= startIndex) - return; + // since endIndex is one past the end, this is index of the last word to be changed. + int32_t endWord = (int32_t)((endIndex - 1) >> 6); - int32_t startWord = (int32_t)(startIndex>>6); - if (startWord >= wlen) - return; + int64_t startmask = -1LL << (startIndex & 0x3f); + int64_t endmask = MiscUtils::unsignedShift(-1LL, -endIndex); - // since endIndex is one past the end, this is index of the last word to be changed. - int32_t endWord = (int32_t)((endIndex - 1) >> 6); + // invert masks since we are clearing + startmask = ~startmask; + endmask = ~endmask; - int64_t startmask = -1LL << (startIndex & 0x3f); - int64_t endmask = MiscUtils::unsignedShift(-1LL, -endIndex); + if (startWord == endWord) { + bits[startWord] &= (startmask | endmask); + return; + } - // invert masks since we are clearing - startmask = ~startmask; - endmask = ~endmask; + bits[startWord] &= startmask; - if (startWord == endWord) - { - bits[startWord] &= (startmask | endmask); - return; - } + int32_t middle = std::min(wlen, endWord); + MiscUtils::arrayFill(bits.get(), startWord + 1, middle, 0LL); + if (endWord < wlen) { + bits[endWord] &= endmask; + } +} - bits[startWord] &= startmask; +bool OpenBitSet::getAndSet(int32_t index) { + int32_t wordNum = index >> 6; // div 64 + int32_t bit = (index & 0x3f); // mod 64 + int64_t bitmask = 1LL << bit; + bool val = ((bits[wordNum] & bitmask) != 0); + bits[wordNum] |= bitmask; + return val; +} - int32_t middle = std::min(wlen, endWord); - MiscUtils::arrayFill(bits.get(), startWord + 1, middle, 0LL); - if (endWord < wlen) - bits[endWord] &= endmask; - } +bool OpenBitSet::getAndSet(int64_t index) { + int32_t wordNum = (int32_t)(index >> 6); // div 64 + int32_t bit = (int32_t)index & 0x3f; // mod 64 + int64_t bitmask = 1LL << bit; + bool val = ((bits[wordNum] & bitmask) != 0); + bits[wordNum] |= bitmask; + return val; +} - bool OpenBitSet::getAndSet(int32_t index) - { - int32_t wordNum = index >> 6; // div 64 - int32_t bit = (index & 0x3f); // mod 64 - int64_t bitmask = 1LL << bit; - bool val = ((bits[wordNum] & bitmask) != 0); - bits[wordNum] |= bitmask; - return val; - } +void OpenBitSet::fastFlip(int32_t index) { + int32_t wordNum = index >> 6; // div 64 + int32_t bit = (index & 0x3f); // mod 64 + int64_t bitmask = 1LL << bit; + bits[wordNum] ^= bitmask; +} - bool OpenBitSet::getAndSet(int64_t index) - { - int32_t wordNum = (int32_t)(index >> 6); // div 64 - int32_t bit = (int32_t)index & 0x3f; // mod 64 - int64_t bitmask = 1LL << bit; - bool val = ((bits[wordNum] & bitmask) != 0); - bits[wordNum] |= bitmask; - return val; - } +void OpenBitSet::fastFlip(int64_t index) { + int32_t wordNum = (int32_t)(index >> 6); // div 64 + int32_t bit = (int32_t)index & 0x3f; // mod 64 + int64_t bitmask = 1LL << bit; + bits[wordNum] ^= bitmask; +} - void OpenBitSet::fastFlip(int32_t index) - { - int32_t wordNum = index >> 6; // div 64 - int32_t bit = (index & 0x3f); // mod 64 - int64_t bitmask = 1LL << bit; - bits[wordNum] ^= bitmask; - } +void OpenBitSet::flip(int64_t index) { + int32_t wordNum = expandingWordNum(index); + int32_t bit = (int32_t)index & 0x3f; // mod 64 + int64_t bitmask = 1LL << bit; + bits[wordNum] ^= bitmask; +} - void OpenBitSet::fastFlip(int64_t index) - { - int32_t wordNum = (int32_t)(index >> 6); // div 64 - int32_t bit = (int32_t)index & 0x3f; // mod 64 - int64_t bitmask = 1LL << bit; - bits[wordNum] ^= bitmask; - } +bool OpenBitSet::flipAndGet(int32_t index) { + int32_t wordNum = index >> 6; // div 64 + int32_t bit = (index & 0x3f); // mod 64 + int64_t bitmask = 1LL << bit; + bits[wordNum] ^= bitmask; + return ((bits[wordNum] & bitmask) != 0); +} - void OpenBitSet::flip(int64_t index) - { - int32_t wordNum = expandingWordNum(index); - int32_t bit = (int32_t)index & 0x3f; // mod 64 - int64_t bitmask = 1LL << bit; - bits[wordNum] ^= bitmask; - } +bool OpenBitSet::flipAndGet(int64_t index) { + int32_t wordNum = (int32_t)(index >> 6); // div 64 + int32_t bit = (int32_t)index & 0x3f; // mod 64 + int64_t bitmask = 1LL << bit; + bits[wordNum] ^= bitmask; + return ((bits[wordNum] & bitmask) != 0); +} - bool OpenBitSet::flipAndGet(int32_t index) - { - int32_t wordNum = index >> 6; // div 64 - int32_t bit = (index & 0x3f); // mod 64 - int64_t bitmask = 1LL << bit; - bits[wordNum] ^= bitmask; - return ((bits[wordNum] & bitmask) != 0); +void OpenBitSet::flip(int64_t startIndex, int64_t endIndex) { + if (endIndex <= startIndex) { + return; } + int32_t startWord = (int32_t)(startIndex >> 6); - bool OpenBitSet::flipAndGet(int64_t index) - { - int32_t wordNum = (int32_t)(index >> 6); // div 64 - int32_t bit = (int32_t)index & 0x3f; // mod 64 - int64_t bitmask = 1LL << bit; - bits[wordNum] ^= bitmask; - return ((bits[wordNum] & bitmask) != 0); - } + // since endIndex is one past the end, this is index of the last word to be changed. + int32_t endWord = expandingWordNum(endIndex - 1); - void OpenBitSet::flip(int64_t startIndex, int64_t endIndex) - { - if (endIndex <= startIndex) - return; - int32_t startWord = (int32_t)(startIndex >> 6); + int64_t startmask = -1LL << (startIndex & 0x3f); + int64_t endmask = MiscUtils::unsignedShift(-1LL, -endIndex); - // since endIndex is one past the end, this is index of the last word to be changed. - int32_t endWord = expandingWordNum(endIndex - 1); + if (startWord == endWord) { + bits[startWord] ^= (startmask & endmask); + return; + } - int64_t startmask = -1LL << (startIndex & 0x3f); - int64_t endmask = MiscUtils::unsignedShift(-1LL, -endIndex); + bits[startWord] ^= startmask; - if (startWord == endWord) - { - bits[startWord] ^= (startmask & endmask); - return; - } + for (int32_t i = startWord + 1; i < endWord; ++i) { + bits[i] = ~bits[i]; + } + bits[endWord] ^= endmask; +} - bits[startWord] ^= startmask; +int64_t OpenBitSet::cardinality() { + return BitUtil::pop_array(bits.get(), 0, wlen); +} - for (int32_t i = startWord + 1; i < endWord; ++i) - bits[i] = ~bits[i]; - bits[endWord] ^= endmask; - } +int64_t OpenBitSet::intersectionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { + return BitUtil::pop_intersect(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); +} - int64_t OpenBitSet::cardinality() - { - return BitUtil::pop_array(bits.get(), 0, wlen); +int64_t OpenBitSet::unionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { + int64_t tot = BitUtil::pop_union(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); + if (a->wlen < b->wlen) { + tot += BitUtil::pop_array(b->bits.get(), a->wlen, b->wlen - a->wlen); + } else if (a->wlen > b->wlen) { + tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); } + return tot; +} - int64_t OpenBitSet::intersectionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) - { - return BitUtil::pop_intersect(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); +int64_t OpenBitSet::andNotCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { + int64_t tot = BitUtil::pop_andnot(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); + if (a->wlen > b->wlen) { + tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); } + return tot; +} - int64_t OpenBitSet::unionCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) - { - int64_t tot = BitUtil::pop_union(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); - if (a->wlen < b->wlen) - tot += BitUtil::pop_array(b->bits.get(), a->wlen, b->wlen - a->wlen); - else if (a->wlen > b->wlen) - tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); - return tot; +int64_t OpenBitSet::xorCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) { + int64_t tot = BitUtil::pop_xor(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); + if (a->wlen < b->wlen) { + tot += BitUtil::pop_array(b->bits.get(), a->wlen, b->wlen - a->wlen); + } else if (a->wlen > b->wlen) { + tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); } + return tot; +} - int64_t OpenBitSet::andNotCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) - { - int64_t tot = BitUtil::pop_andnot(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); - if (a->wlen > b->wlen) - tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); - return tot; +int32_t OpenBitSet::nextSetBit(int32_t index) { + int32_t i = MiscUtils::unsignedShift(index, 6); + if (i >= wlen) { + return -1; } + int32_t subIndex = (index & 0x3f); // index within the word + int64_t word = MiscUtils::unsignedShift(bits[i], (int64_t)subIndex); // skip all the bits to the right of index - int64_t OpenBitSet::xorCount(const OpenBitSetPtr& a, const OpenBitSetPtr& b) - { - int64_t tot = BitUtil::pop_xor(a->bits.get(), b->bits.get(), 0, std::min(a->wlen, b->wlen)); - if (a->wlen < b->wlen) - tot += BitUtil::pop_array(b->bits.get(), a->wlen, b->wlen - a->wlen); - else if (a->wlen > b->wlen) - tot += BitUtil::pop_array(a->bits.get(), b->wlen, a->wlen - b->wlen); - return tot; + if (word != 0) { + return (i << 6) + subIndex + BitUtil::ntz(word); } - int32_t OpenBitSet::nextSetBit(int32_t index) - { - int32_t i = MiscUtils::unsignedShift(index, 6); - if (i >= wlen) - return -1; - int32_t subIndex = (index & 0x3f); // index within the word - int64_t word = MiscUtils::unsignedShift(bits[i], (int64_t)subIndex); // skip all the bits to the right of index - - if (word != 0) - return (i << 6) + subIndex + BitUtil::ntz(word); - - while (++i < wlen) - { - word = bits[i]; - if (word != 0) - return (i << 6) + BitUtil::ntz(word); + while (++i < wlen) { + word = bits[i]; + if (word != 0) { + return (i << 6) + BitUtil::ntz(word); } - - return -1; } - int64_t OpenBitSet::nextSetBit(int64_t index) - { - int32_t i = (int32_t)(index >> 6); - if (i >= wlen) - return -1; - int32_t subIndex = (int32_t)index & 0x3f; // index within the word - int64_t word = bits[i] >> subIndex; // skip all the bits to the right of index - - if (word != 0) - return ((int64_t)i << 6) + (subIndex + BitUtil::ntz(word)); - - while (++i < wlen) - { - word = bits[i]; - if (word != 0) - return ((int64_t)i << 6) + BitUtil::ntz(word); - } + return -1; +} +int64_t OpenBitSet::nextSetBit(int64_t index) { + int32_t i = (int32_t)(index >> 6); + if (i >= wlen) { return -1; } + int32_t subIndex = (int32_t)index & 0x3f; // index within the word + int64_t word = bits[i] >> subIndex; // skip all the bits to the right of index + + if (word != 0) { + return ((int64_t)i << 6) + (subIndex + BitUtil::ntz(word)); + } - LuceneObjectPtr OpenBitSet::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - OpenBitSetPtr cloneSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); - cloneSet->wlen = wlen; - cloneSet->bits = LongArray::newInstance(bits.size()); - MiscUtils::arrayCopy(bits.get(), 0, cloneSet->bits.get(), 0, bits.size()); - return cloneSet; - } - - void OpenBitSet::intersect(const OpenBitSetPtr& other) - { - int32_t newLen= std::min(this->wlen, other->wlen); - LongArray thisArr = this->bits; - LongArray otherArr = other->bits; - // testing against zero can be more efficient - int32_t pos = newLen; - while (--pos >= 0) - thisArr[pos] &= otherArr[pos]; - if (this->wlen > newLen) - { - // fill zeros from the new shorter length to the old length - MiscUtils::arrayFill(bits.get(), newLen, this->wlen, 0LL); + while (++i < wlen) { + word = bits[i]; + if (word != 0) { + return ((int64_t)i << 6) + BitUtil::ntz(word); } - this->wlen = newLen; } - void OpenBitSet::_union(const OpenBitSetPtr& other) - { - int32_t newLen = std::max(wlen, other->wlen); - ensureCapacityWords(newLen); + return -1; +} - LongArray thisArr = this->bits; - LongArray otherArr = other->bits; - int32_t pos = std::min(wlen, other->wlen); - while (--pos >= 0) - thisArr[pos] |= otherArr[pos]; - if (this->wlen < newLen) - MiscUtils::arrayCopy(otherArr.get(), this->wlen, thisArr.get(), this->wlen, newLen - this->wlen); - this->wlen = newLen; - } +LuceneObjectPtr OpenBitSet::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + OpenBitSetPtr cloneSet(boost::dynamic_pointer_cast(LuceneObject::clone(clone))); + cloneSet->wlen = wlen; + cloneSet->bits = LongArray::newInstance(bits.size()); + MiscUtils::arrayCopy(bits.get(), 0, cloneSet->bits.get(), 0, bits.size()); + return cloneSet; +} - void OpenBitSet::remove(const OpenBitSetPtr& other) - { - int32_t idx = std::min(wlen, other->wlen); - LongArray thisArr = this->bits; - LongArray otherArr = other->bits; - while (--idx >= 0) - thisArr[idx] &= ~otherArr[idx]; +void OpenBitSet::intersect(const OpenBitSetPtr& other) { + int32_t newLen= std::min(this->wlen, other->wlen); + LongArray thisArr = this->bits; + LongArray otherArr = other->bits; + // testing against zero can be more efficient + int32_t pos = newLen; + while (--pos >= 0) { + thisArr[pos] &= otherArr[pos]; + } + if (this->wlen > newLen) { + // fill zeros from the new shorter length to the old length + MiscUtils::arrayFill(bits.get(), newLen, this->wlen, 0LL); } + this->wlen = newLen; +} - void OpenBitSet::_xor(const OpenBitSetPtr& other) - { - int32_t newLen = std::max(wlen, other->wlen); - ensureCapacityWords(newLen); +void OpenBitSet::_union(const OpenBitSetPtr& other) { + int32_t newLen = std::max(wlen, other->wlen); + ensureCapacityWords(newLen); - LongArray thisArr = this->bits; - LongArray otherArr = other->bits; - int32_t pos = std::min(wlen, other->wlen); - while (--pos >= 0) - thisArr[pos] ^= otherArr[pos]; - if (this->wlen < newLen) - MiscUtils::arrayCopy(otherArr.get(), this->wlen, thisArr.get(), this->wlen, newLen - this->wlen); - this->wlen = newLen; + LongArray thisArr = this->bits; + LongArray otherArr = other->bits; + int32_t pos = std::min(wlen, other->wlen); + while (--pos >= 0) { + thisArr[pos] |= otherArr[pos]; } - - void OpenBitSet::_and(const OpenBitSetPtr& other) - { - intersect(other); + if (this->wlen < newLen) { + MiscUtils::arrayCopy(otherArr.get(), this->wlen, thisArr.get(), this->wlen, newLen - this->wlen); } + this->wlen = newLen; +} - void OpenBitSet::_or(const OpenBitSetPtr& other) - { - _union(other); +void OpenBitSet::remove(const OpenBitSetPtr& other) { + int32_t idx = std::min(wlen, other->wlen); + LongArray thisArr = this->bits; + LongArray otherArr = other->bits; + while (--idx >= 0) { + thisArr[idx] &= ~otherArr[idx]; } +} - void OpenBitSet::andNot(const OpenBitSetPtr& other) - { - remove(other); - } +void OpenBitSet::_xor(const OpenBitSetPtr& other) { + int32_t newLen = std::max(wlen, other->wlen); + ensureCapacityWords(newLen); - bool OpenBitSet::intersects(const OpenBitSetPtr& other) - { - int32_t pos = std::min(this->wlen, other->wlen); - LongArray thisArr = this->bits; - LongArray otherArr = other->bits; - while (--pos >= 0) - { - if ((thisArr[pos] & otherArr[pos]) !=0 ) - return true; - } - return false; + LongArray thisArr = this->bits; + LongArray otherArr = other->bits; + int32_t pos = std::min(wlen, other->wlen); + while (--pos >= 0) { + thisArr[pos] ^= otherArr[pos]; } + if (this->wlen < newLen) { + MiscUtils::arrayCopy(otherArr.get(), this->wlen, thisArr.get(), this->wlen, newLen - this->wlen); + } + this->wlen = newLen; +} + +void OpenBitSet::_and(const OpenBitSetPtr& other) { + intersect(other); +} + +void OpenBitSet::_or(const OpenBitSetPtr& other) { + _union(other); +} - void OpenBitSet::ensureCapacityWords(int32_t numWords) - { - int32_t length = bits.size(); - if (length < numWords) - { - bits.resize(MiscUtils::getNextSize(numWords)); - MiscUtils::arrayFill(bits.get(), length, bits.size(), 0LL); +void OpenBitSet::andNot(const OpenBitSetPtr& other) { + remove(other); +} + +bool OpenBitSet::intersects(const OpenBitSetPtr& other) { + int32_t pos = std::min(this->wlen, other->wlen); + LongArray thisArr = this->bits; + LongArray otherArr = other->bits; + while (--pos >= 0) { + if ((thisArr[pos] & otherArr[pos]) !=0 ) { + return true; } } + return false; +} - void OpenBitSet::ensureCapacity(int64_t numBits) - { - ensureCapacityWords(bits2words(numBits)); +void OpenBitSet::ensureCapacityWords(int32_t numWords) { + int32_t length = bits.size(); + if (length < numWords) { + bits.resize(MiscUtils::getNextSize(numWords)); + MiscUtils::arrayFill(bits.get(), length, bits.size(), 0LL); } +} - void OpenBitSet::trimTrailingZeros() - { - int32_t idx = wlen - 1; - while (idx >= 0 && bits[idx] == 0) - --idx; - wlen = idx + 1; +void OpenBitSet::ensureCapacity(int64_t numBits) { + ensureCapacityWords(bits2words(numBits)); +} + +void OpenBitSet::trimTrailingZeros() { + int32_t idx = wlen - 1; + while (idx >= 0 && bits[idx] == 0) { + --idx; } + wlen = idx + 1; +} - int32_t OpenBitSet::bits2words(int64_t numBits) - { - return (int32_t)(MiscUtils::unsignedShift(numBits - 1, (int64_t)6) + 1); +int32_t OpenBitSet::bits2words(int64_t numBits) { + return (int32_t)(MiscUtils::unsignedShift(numBits - 1, (int64_t)6) + 1); +} + +bool OpenBitSet::equals(const LuceneObjectPtr& other) { + if (LuceneObject::equals(other)) { + return true; + } + OpenBitSetPtr otherBitSet(boost::dynamic_pointer_cast(other)); + if (!otherBitSet) { + return false; + } + OpenBitSetPtr a; + OpenBitSetPtr b = otherBitSet; + // make a the larger set + if (b->wlen > this->wlen) { + a = b; + b = shared_from_this(); + } else { + a = shared_from_this(); } - bool OpenBitSet::equals(const LuceneObjectPtr& other) - { - if (LuceneObject::equals(other)) - return true; - OpenBitSetPtr otherBitSet(boost::dynamic_pointer_cast(other)); - if (!otherBitSet) + // check for any set bits out of the range of b + for (int32_t i = a->wlen - 1; i >= b->wlen; --i) { + if (a->bits[i] !=0 ) { return false; - OpenBitSetPtr a; - OpenBitSetPtr b = otherBitSet; - // make a the larger set - if (b->wlen > this->wlen) - { - a = b; - b = shared_from_this(); - } - else - a = shared_from_this(); - - // check for any set bits out of the range of b - for (int32_t i = a->wlen - 1; i >= b->wlen; --i) - { - if (a->bits[i] !=0 ) - return false; - } - - for (int32_t i = b->wlen - 1; i >= 0; --i) - { - if (a->bits[i] != b->bits[i]) - return false; } - - return true; } - int32_t OpenBitSet::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. - int64_t hash = 0; - for (int32_t i = bits.size(); --i >= 0;) - { - hash ^= bits[i]; - hash = (hash << 1) | MiscUtils::unsignedShift(hash, (int64_t)63); // rotate left + for (int32_t i = b->wlen - 1; i >= 0; --i) { + if (a->bits[i] != b->bits[i]) { + return false; } - // Fold leftmost bits into right and add a constant to prevent empty sets from - // returning 0, which is too common. - return (int32_t)((hash >> 32) ^ hash) + 0x98761234; } + + return true; +} + +int32_t OpenBitSet::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. + int64_t hash = 0; + for (int32_t i = bits.size(); --i >= 0;) { + hash ^= bits[i]; + hash = (hash << 1) | MiscUtils::unsignedShift(hash, (int64_t)63); // rotate left + } + // Fold leftmost bits into right and add a constant to prevent empty sets from + // returning 0, which is too common. + return (int32_t)((hash >> 32) ^ hash) + 0x98761234; +} + } diff --git a/src/core/util/OpenBitSetDISI.cpp b/src/core/util/OpenBitSetDISI.cpp index 0688c0be..43ec5867 100644 --- a/src/core/util/OpenBitSetDISI.cpp +++ b/src/core/util/OpenBitSetDISI.cpp @@ -7,55 +7,52 @@ #include "LuceneInc.h" #include "OpenBitSetDISI.h" -namespace Lucene -{ - OpenBitSetDISI::OpenBitSetDISI(const DocIdSetIteratorPtr& disi, int32_t maxSize) : OpenBitSet(maxSize) - { - inPlaceOr(disi); - } +namespace Lucene { - OpenBitSetDISI::OpenBitSetDISI(int32_t maxSize) : OpenBitSet(maxSize) - { - } +OpenBitSetDISI::OpenBitSetDISI(const DocIdSetIteratorPtr& disi, int32_t maxSize) : OpenBitSet(maxSize) { + inPlaceOr(disi); +} - OpenBitSetDISI::~OpenBitSetDISI() - { - } +OpenBitSetDISI::OpenBitSetDISI(int32_t maxSize) : OpenBitSet(maxSize) { +} + +OpenBitSetDISI::~OpenBitSetDISI() { +} - void OpenBitSetDISI::inPlaceOr(const DocIdSetIteratorPtr& disi) - { - int32_t doc; - int32_t _size = size(); - while ((doc = disi->nextDoc()) < _size) - set(doc); +void OpenBitSetDISI::inPlaceOr(const DocIdSetIteratorPtr& disi) { + int32_t doc; + int32_t _size = size(); + while ((doc = disi->nextDoc()) < _size) { + set(doc); } +} - void OpenBitSetDISI::inPlaceAnd(const DocIdSetIteratorPtr& disi) - { - int32_t bitSetDoc = nextSetBit((int32_t)0); - int32_t disiDoc; - while (bitSetDoc != -1 && (disiDoc = disi->advance(bitSetDoc)) != DocIdSetIterator::NO_MORE_DOCS) - { - clear(bitSetDoc, disiDoc); - bitSetDoc = nextSetBit(disiDoc + 1); - } - if (bitSetDoc != -1) - clear((int64_t)bitSetDoc, size()); +void OpenBitSetDISI::inPlaceAnd(const DocIdSetIteratorPtr& disi) { + int32_t bitSetDoc = nextSetBit((int32_t)0); + int32_t disiDoc; + while (bitSetDoc != -1 && (disiDoc = disi->advance(bitSetDoc)) != DocIdSetIterator::NO_MORE_DOCS) { + clear(bitSetDoc, disiDoc); + bitSetDoc = nextSetBit(disiDoc + 1); + } + if (bitSetDoc != -1) { + clear((int64_t)bitSetDoc, size()); } +} - void OpenBitSetDISI::inPlaceNot(const DocIdSetIteratorPtr& disi) - { - int32_t doc; - int32_t _size = size(); - while ((doc = disi->nextDoc()) < _size) - clear(doc); +void OpenBitSetDISI::inPlaceNot(const DocIdSetIteratorPtr& disi) { + int32_t doc; + int32_t _size = size(); + while ((doc = disi->nextDoc()) < _size) { + clear(doc); } +} - void OpenBitSetDISI::inPlaceXor(const DocIdSetIteratorPtr& disi) - { - int32_t doc; - int32_t _size = size(); - while ((doc = disi->nextDoc()) < _size) - flip(doc); +void OpenBitSetDISI::inPlaceXor(const DocIdSetIteratorPtr& disi) { + int32_t doc; + int32_t _size = size(); + while ((doc = disi->nextDoc()) < _size) { + flip(doc); } } + +} diff --git a/src/core/util/OpenBitSetIterator.cpp b/src/core/util/OpenBitSetIterator.cpp index 3a4e3d40..b6671fcf 100644 --- a/src/core/util/OpenBitSetIterator.cpp +++ b/src/core/util/OpenBitSetIterator.cpp @@ -9,158 +9,140 @@ #include "OpenBitSet.h" #include "MiscUtils.h" -namespace Lucene -{ - /// 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(int32_t))=1K - const int32_t OpenBitSetIterator::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, static_cast(0x87654321) - }; - - OpenBitSetIterator::OpenBitSetIterator(const OpenBitSetPtr& bitSet) - { - arr = bitSet->getBits(); - words = bitSet->getNumWords(); - i = -1; - word = 0; - wordShift = 0; - indexArray = 0; - curDocId = -1; - } +namespace Lucene { - OpenBitSetIterator::OpenBitSetIterator(LongArray bits, int32_t numWords) - { - arr = bits; - words = numWords; - i = -1; - word = 0; - wordShift = 0; - indexArray = 0; - curDocId = -1; - } +/// 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(int32_t))=1K +const int32_t OpenBitSetIterator::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, static_cast(0x87654321) +}; - OpenBitSetIterator::~OpenBitSetIterator() - { +OpenBitSetIterator::OpenBitSetIterator(const OpenBitSetPtr& bitSet) { + arr = bitSet->getBits(); + words = bitSet->getNumWords(); + i = -1; + word = 0; + wordShift = 0; + indexArray = 0; + curDocId = -1; +} + +OpenBitSetIterator::OpenBitSetIterator(LongArray bits, int32_t numWords) { + arr = bits; + words = numWords; + i = -1; + word = 0; + wordShift = 0; + indexArray = 0; + curDocId = -1; +} + +OpenBitSetIterator::~OpenBitSetIterator() { +} + +void OpenBitSetIterator::shift() { + if ((int32_t)word == 0) { + wordShift += 32; + word = MiscUtils::unsignedShift(word, (int64_t)32); + } + if ((word & 0x0000ffff) == 0) { + wordShift += 16; + word = MiscUtils::unsignedShift(word, (int64_t)16); } + if ((word & 0x000000ff) == 0) { + wordShift += 8; + word = MiscUtils::unsignedShift(word, (int64_t)8); + } + indexArray = bitlist[(int32_t)word & 0xff]; +} - void OpenBitSetIterator::shift() - { - if ((int32_t)word == 0) - { - wordShift += 32; - word = MiscUtils::unsignedShift(word, (int64_t)32); - } - if ((word & 0x0000ffff) == 0) - { - wordShift += 16; - word = MiscUtils::unsignedShift(word, (int64_t)16); - } - if ((word & 0x000000ff) == 0) - { - wordShift += 8; +int32_t OpenBitSetIterator::nextDoc() { + if (indexArray == 0) { + if (word != 0) { word = MiscUtils::unsignedShift(word, (int64_t)8); + wordShift += 8; } - indexArray = bitlist[(int32_t)word & 0xff]; - } - int32_t OpenBitSetIterator::nextDoc() - { - if (indexArray == 0) - { - if (word != 0) - { - word = MiscUtils::unsignedShift(word, (int64_t)8); - wordShift += 8; + while (word == 0) { + if (++i >= words) { + curDocId = NO_MORE_DOCS; + return curDocId; } + word = arr[i]; + wordShift = -1; // loop invariant code motion should move this + } - while (word == 0) - { - if (++i >= words) - { - curDocId = NO_MORE_DOCS; - return curDocId; - } - 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(); + } - // after the first time, should I go with a linear search, or stick with the binary search in shift? - shift(); - } + int32_t bitIndex = (indexArray & 0x0f) + wordShift; + indexArray = MiscUtils::unsignedShift(indexArray, 4); + curDocId = (i << 6) + bitIndex; + return curDocId; +} - int32_t bitIndex = (indexArray & 0x0f) + wordShift; - indexArray = MiscUtils::unsignedShift(indexArray, 4); - curDocId = (i << 6) + bitIndex; +int32_t OpenBitSetIterator::advance(int32_t target) { + indexArray = 0; + i = target >> 6; + if (i >= words) { + word = 0; // setup so next() will also return -1 + curDocId = NO_MORE_DOCS; return curDocId; } - - int32_t OpenBitSetIterator::advance(int32_t target) - { - indexArray = 0; - i = target >> 6; - if (i >= words) - { - word = 0; // setup so next() will also return -1 - curDocId = NO_MORE_DOCS; - return curDocId; - } - wordShift = target & 0x3f; - word = MiscUtils::unsignedShift(arr[i], (int64_t)wordShift); - if (word != 0) - --wordShift; // compensate for 1 based arrIndex - else - { - while (word == 0) - { - if (++i >= words) - { - curDocId = NO_MORE_DOCS; - return curDocId; - } - word = arr[i]; + wordShift = target & 0x3f; + word = MiscUtils::unsignedShift(arr[i], (int64_t)wordShift); + if (word != 0) { + --wordShift; // compensate for 1 based arrIndex + } else { + while (word == 0) { + if (++i >= words) { + curDocId = NO_MORE_DOCS; + return curDocId; } - wordShift = -1; + word = arr[i]; } + wordShift = -1; + } - shift(); + shift(); - int32_t bitIndex = (indexArray & 0x0f) + wordShift; - indexArray = MiscUtils::unsignedShift(indexArray, 4); - curDocId = (i << 6) + bitIndex; - return curDocId; - } + int32_t bitIndex = (indexArray & 0x0f) + wordShift; + indexArray = MiscUtils::unsignedShift(indexArray, 4); + curDocId = (i << 6) + bitIndex; + return curDocId; +} + +int32_t OpenBitSetIterator::docID() { + return curDocId; +} - int32_t OpenBitSetIterator::docID() - { - return curDocId; - } } diff --git a/src/core/util/Random.cpp b/src/core/util/Random.cpp index d28bf0ab..77919c24 100644 --- a/src/core/util/Random.cpp +++ b/src/core/util/Random.cpp @@ -8,53 +8,46 @@ #include "Random.h" #include "MiscUtils.h" -namespace Lucene -{ - Random::Random() - { - this->seed = (int64_t)MiscUtils::currentTimeMillis(); - } +namespace Lucene { - Random::Random(int64_t seed) - { - this->seed = seed; - } +Random::Random() { + this->seed = (int64_t)MiscUtils::currentTimeMillis(); +} - Random::~Random() - { - } +Random::Random(int64_t seed) { + this->seed = seed; +} + +Random::~Random() { +} - void Random::setSeed(int64_t seed) - { - this->seed = (seed ^ 0x5deece66dLL) & (((int64_t)1 << 48) - 1); +void Random::setSeed(int64_t seed) { + this->seed = (seed ^ 0x5deece66dLL) & (((int64_t)1 << 48) - 1); +} + +int32_t Random::nextInt(int32_t limit) { + if ((limit & -limit) == limit) { + return (int32_t)((limit * (int64_t)next(31)) >> 31); } - int32_t Random::nextInt(int32_t limit) - { - if ((limit & -limit) == limit) - return (int32_t)((limit * (int64_t)next(31)) >> 31); + int32_t bits = 0; + int32_t val = 0; - int32_t bits = 0; - int32_t val = 0; + do { + bits = next(31); + val = bits % limit; + } while (bits - val + (limit - 1) < 0); - do - { - bits = next(31); - val = bits % limit; - } - while (bits - val + (limit - 1) < 0); + return val; +} - return val; - } +double Random::nextDouble() { + return ((double)(((int64_t)next(26) << 27) + next(27)) / (double)((int64_t)1 << 53)); +} - double Random::nextDouble() - { - return ((double)(((int64_t)next(26) << 27) + next(27)) / (double)((int64_t)1 << 53)); - } +int32_t Random::next(int32_t bits) { + seed = (seed * 0x5deece66dLL + 0xb) & (((int64_t)1 << 48) - 1); + return (int32_t)(seed >> (48 - bits)); +} - int32_t Random::next(int32_t bits) - { - seed = (seed * 0x5deece66dLL + 0xb) & (((int64_t)1 << 48) - 1); - return (int32_t)(seed >> (48 - bits)); - } } diff --git a/src/core/util/Reader.cpp b/src/core/util/Reader.cpp index 320a7420..5e660996 100644 --- a/src/core/util/Reader.cpp +++ b/src/core/util/Reader.cpp @@ -7,46 +7,39 @@ #include "LuceneInc.h" #include "Reader.h" -namespace Lucene -{ - const int32_t Reader::READER_EOF = -1; - - Reader::Reader() - { - } - - Reader::~Reader() - { - } - - int32_t Reader::read() - { - wchar_t buffer; - return read(&buffer, 0, 1) == READER_EOF ? READER_EOF : buffer; - } - - int64_t Reader::skip(int64_t n) - { - return 0; // override - } - - bool Reader::markSupported() - { - return false; // override - } - - void Reader::mark(int32_t readAheadLimit) - { - // override - } - - void Reader::reset() - { - // override - } - - int64_t Reader::length() - { - return 0; // override - } +namespace Lucene { + +const int32_t Reader::READER_EOF = -1; + +Reader::Reader() { +} + +Reader::~Reader() { +} + +int32_t Reader::read() { + wchar_t buffer; + return read(&buffer, 0, 1) == READER_EOF ? READER_EOF : buffer; +} + +int64_t Reader::skip(int64_t n) { + return 0; // override +} + +bool Reader::markSupported() { + return false; // override +} + +void Reader::mark(int32_t readAheadLimit) { + // override +} + +void Reader::reset() { + // override +} + +int64_t Reader::length() { + return 0; // override +} + } diff --git a/src/core/util/ReaderUtil.cpp b/src/core/util/ReaderUtil.cpp index fc84d52b..0b000c1c 100644 --- a/src/core/util/ReaderUtil.cpp +++ b/src/core/util/ReaderUtil.cpp @@ -8,52 +8,45 @@ #include "ReaderUtil.h" #include "IndexReader.h" -namespace Lucene -{ - ReaderUtil::~ReaderUtil() - { - } +namespace Lucene { - void ReaderUtil::gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader) - { - Collection subReaders(reader->getSequentialSubReaders()); - if (!subReaders) - { - // Add the reader itself, and do not recurse - allSubReaders.add(reader); - } - else - { - for (Collection::iterator subReader = subReaders.begin(); subReader != subReaders.end(); ++subReader) - gatherSubReaders(allSubReaders, *subReader); - } - } +ReaderUtil::~ReaderUtil() { +} - IndexReaderPtr ReaderUtil::subReader(int32_t doc, const IndexReaderPtr& reader) - { - Collection subReaders(Collection::newInstance()); - ReaderUtil::gatherSubReaders(subReaders, reader); - Collection docStarts(Collection::newInstance(subReaders.size())); - int32_t maxDoc = 0; - for (int32_t i = 0; i < subReaders.size(); ++i) - { - docStarts[i] = maxDoc; - maxDoc += subReaders[i]->maxDoc(); +void ReaderUtil::gatherSubReaders(Collection allSubReaders, const IndexReaderPtr& reader) { + Collection subReaders(reader->getSequentialSubReaders()); + if (!subReaders) { + // Add the reader itself, and do not recurse + allSubReaders.add(reader); + } else { + for (Collection::iterator subReader = subReaders.begin(); subReader != subReaders.end(); ++subReader) { + gatherSubReaders(allSubReaders, *subReader); } - return subReaders[ReaderUtil::subIndex(doc, docStarts)]; } +} - IndexReaderPtr ReaderUtil::subReader(const IndexReaderPtr& reader, int32_t subIndex) - { - Collection subReaders(Collection::newInstance()); - ReaderUtil::gatherSubReaders(subReaders, reader); - return subReaders[subIndex]; +IndexReaderPtr ReaderUtil::subReader(int32_t doc, const IndexReaderPtr& reader) { + Collection subReaders(Collection::newInstance()); + ReaderUtil::gatherSubReaders(subReaders, reader); + Collection docStarts(Collection::newInstance(subReaders.size())); + int32_t maxDoc = 0; + for (int32_t i = 0; i < subReaders.size(); ++i) { + docStarts[i] = maxDoc; + maxDoc += subReaders[i]->maxDoc(); } + return subReaders[ReaderUtil::subIndex(doc, docStarts)]; +} + +IndexReaderPtr ReaderUtil::subReader(const IndexReaderPtr& reader, int32_t subIndex) { + Collection subReaders(Collection::newInstance()); + ReaderUtil::gatherSubReaders(subReaders, reader); + return subReaders[subIndex]; +} + +int32_t ReaderUtil::subIndex(int32_t n, Collection docStarts) { + // Binary search to locate reader + Collection::iterator index = std::upper_bound(docStarts.begin(), docStarts.end(), n); + return (std::distance(docStarts.begin(), index) - 1); +} - int32_t ReaderUtil::subIndex(int32_t n, Collection docStarts) - { - // Binary search to locate reader - Collection::iterator index = std::upper_bound(docStarts.begin(), docStarts.end(), n); - return (std::distance(docStarts.begin(), index) - 1); - } } diff --git a/src/core/util/ScorerDocQueue.cpp b/src/core/util/ScorerDocQueue.cpp index 8aabd9ee..cce4dd87 100644 --- a/src/core/util/ScorerDocQueue.cpp +++ b/src/core/util/ScorerDocQueue.cpp @@ -10,172 +10,148 @@ #include "Scorer.h" #include "MiscUtils.h" -namespace Lucene -{ - ScorerDocQueue::ScorerDocQueue(int32_t maxSize) - { - this->_size = 0; - int32_t heapSize = maxSize + 1; - heap = Collection::newInstance(heapSize); - this->maxSize = maxSize; - topHSD = heap[1]; // initially null - } +namespace Lucene { + +ScorerDocQueue::ScorerDocQueue(int32_t maxSize) { + this->_size = 0; + int32_t heapSize = maxSize + 1; + heap = Collection::newInstance(heapSize); + this->maxSize = maxSize; + topHSD = heap[1]; // initially null +} - ScorerDocQueue::~ScorerDocQueue() - { - } +ScorerDocQueue::~ScorerDocQueue() { +} - void ScorerDocQueue::put(const ScorerPtr& scorer) - { - heap[++_size] = newLucene(scorer); - upHeap(); - } +void ScorerDocQueue::put(const ScorerPtr& scorer) { + heap[++_size] = newLucene(scorer); + upHeap(); +} - bool ScorerDocQueue::insert(const ScorerPtr& scorer) - { - if (_size < maxSize) - { - put(scorer); +bool ScorerDocQueue::insert(const ScorerPtr& scorer) { + if (_size < maxSize) { + put(scorer); + return true; + } else { + int32_t docNr = scorer->docID(); + if ((_size > 0) && (!(docNr < topHSD->doc))) { // heap[1] is top() + heap[1] = newLucene(scorer, docNr); + downHeap(); return true; + } else { + return false; } - else - { - int32_t docNr = scorer->docID(); - if ((_size > 0) && (!(docNr < topHSD->doc))) // heap[1] is top() - { - heap[1] = newLucene(scorer, docNr); - downHeap(); - return true; - } - else - return false; - } - } - - ScorerPtr ScorerDocQueue::top() - { - return topHSD->scorer; - } - - int32_t ScorerDocQueue::topDoc() - { - return topHSD->doc; } +} - double ScorerDocQueue::topScore() - { - return topHSD->scorer->score(); - } +ScorerPtr ScorerDocQueue::top() { + return topHSD->scorer; +} - bool ScorerDocQueue::topNextAndAdjustElsePop() - { - return checkAdjustElsePop(topHSD->scorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); - } +int32_t ScorerDocQueue::topDoc() { + return topHSD->doc; +} - bool ScorerDocQueue::topSkipToAndAdjustElsePop(int32_t target) - { - return checkAdjustElsePop(topHSD->scorer->advance(target) != DocIdSetIterator::NO_MORE_DOCS); - } +double ScorerDocQueue::topScore() { + return topHSD->scorer->score(); +} - bool ScorerDocQueue::checkAdjustElsePop(bool cond) - { - if (cond) // see also adjustTop - topHSD->doc = topHSD->scorer->docID(); - else // see also popNoResult - { - heap[1] = heap[_size]; // move last to first - heap[_size--].reset(); - } - downHeap(); - return cond; - } +bool ScorerDocQueue::topNextAndAdjustElsePop() { + return checkAdjustElsePop(topHSD->scorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); +} - ScorerPtr ScorerDocQueue::pop() - { - ScorerPtr result(topHSD->scorer); - popNoResult(); - return result; - } +bool ScorerDocQueue::topSkipToAndAdjustElsePop(int32_t target) { + return checkAdjustElsePop(topHSD->scorer->advance(target) != DocIdSetIterator::NO_MORE_DOCS); +} - void ScorerDocQueue::popNoResult() - { +bool ScorerDocQueue::checkAdjustElsePop(bool cond) { + if (cond) { // see also adjustTop + topHSD->doc = topHSD->scorer->docID(); + } else { // see also popNoResult heap[1] = heap[_size]; // move last to first heap[_size--].reset(); - downHeap(); // adjust heap } + downHeap(); + return cond; +} - void ScorerDocQueue::adjustTop() - { - topHSD->adjust(); - downHeap(); - } +ScorerPtr ScorerDocQueue::pop() { + ScorerPtr result(topHSD->scorer); + popNoResult(); + return result; +} - int32_t ScorerDocQueue::size() - { - return _size; - } +void ScorerDocQueue::popNoResult() { + heap[1] = heap[_size]; // move last to first + heap[_size--].reset(); + downHeap(); // adjust heap +} - void ScorerDocQueue::clear() - { - for (int32_t i = 0; i <= _size; ++i) - heap[i].reset(); - _size = 0; - } +void ScorerDocQueue::adjustTop() { + topHSD->adjust(); + downHeap(); +} - void ScorerDocQueue::upHeap() - { - int32_t i = _size; - HeapedScorerDocPtr node(heap[i]); // save bottom node - int32_t j = MiscUtils::unsignedShift(i, 1); - while ((j > 0) && (node->doc < heap[j]->doc)) - { - heap[i] = heap[j]; // shift parents down - i = j; - j = MiscUtils::unsignedShift(j, 1); - } - heap[i] = node; // install saved node - topHSD = heap[1]; +int32_t ScorerDocQueue::size() { + return _size; +} + +void ScorerDocQueue::clear() { + for (int32_t i = 0; i <= _size; ++i) { + heap[i].reset(); } + _size = 0; +} - void ScorerDocQueue::downHeap() - { - int32_t i = 1; - HeapedScorerDocPtr node(heap[i]); // save top node - int32_t j = i << 1; // find smaller child - int32_t k = j + 1; - if ((k <= _size) && (heap[k]->doc < heap[j]->doc)) +void ScorerDocQueue::upHeap() { + int32_t i = _size; + HeapedScorerDocPtr node(heap[i]); // save bottom node + int32_t j = MiscUtils::unsignedShift(i, 1); + while ((j > 0) && (node->doc < heap[j]->doc)) { + heap[i] = heap[j]; // shift parents down + i = j; + j = MiscUtils::unsignedShift(j, 1); + } + heap[i] = node; // install saved node + topHSD = heap[1]; +} + +void ScorerDocQueue::downHeap() { + int32_t i = 1; + HeapedScorerDocPtr node(heap[i]); // save top node + int32_t j = i << 1; // find smaller child + int32_t k = j + 1; + if ((k <= _size) && (heap[k]->doc < heap[j]->doc)) { + j = k; + } + while ((j <= _size) && (heap[j]->doc < node->doc)) { + heap[i] = heap[j]; // shift up child + i = j; + j = i << 1; + k = j + 1; + if (k <= _size && (heap[k]->doc < heap[j]->doc)) { j = k; - while ((j <= _size) && (heap[j]->doc < node->doc)) - { - heap[i] = heap[j]; // shift up child - i = j; - j = i << 1; - k = j + 1; - if (k <= _size && (heap[k]->doc < heap[j]->doc)) - j = k; } - heap[i] = node; // install saved node - topHSD = heap[1]; } + heap[i] = node; // install saved node + topHSD = heap[1]; +} - HeapedScorerDoc::HeapedScorerDoc(const ScorerPtr& scorer) - { - this->scorer = scorer; - this->doc = scorer->docID(); - } +HeapedScorerDoc::HeapedScorerDoc(const ScorerPtr& scorer) { + this->scorer = scorer; + this->doc = scorer->docID(); +} - HeapedScorerDoc::HeapedScorerDoc(const ScorerPtr& scorer, int32_t doc) - { - this->scorer = scorer; - this->doc = doc; - } +HeapedScorerDoc::HeapedScorerDoc(const ScorerPtr& scorer, int32_t doc) { + this->scorer = scorer; + this->doc = doc; +} - HeapedScorerDoc::~HeapedScorerDoc() - { - } +HeapedScorerDoc::~HeapedScorerDoc() { +} + +void HeapedScorerDoc::adjust() { + doc = scorer->docID(); +} - void HeapedScorerDoc::adjust() - { - doc = scorer->docID(); - } } diff --git a/src/core/util/SmallDouble.cpp b/src/core/util/SmallDouble.cpp index 5f79d8c9..032611b5 100644 --- a/src/core/util/SmallDouble.cpp +++ b/src/core/util/SmallDouble.cpp @@ -8,44 +8,43 @@ #include "SmallDouble.h" #include "MiscUtils.h" -namespace Lucene -{ - SmallDouble::~SmallDouble() - { +namespace Lucene { + +SmallDouble::~SmallDouble() { +} + +uint8_t SmallDouble::doubleToByte(double f) { + if (f < 0.0) { // round negatives up to zero + f = 0.0; } + if (f == 0.0) { // zero is a special case + return 0; + } + + int32_t bits = MiscUtils::doubleToIntBits(f); + int32_t mantissa = (bits & 0xffffff) >> 21; + int32_t exponent = (((bits >> 24) & 0x7f) - 63) + 15; - uint8_t SmallDouble::doubleToByte(double f) - { - if (f < 0.0) // round negatives up to zero - f = 0.0; - if (f == 0.0) // zero is a special case - return 0; - - int32_t bits = MiscUtils::doubleToIntBits(f); - int32_t mantissa = (bits & 0xffffff) >> 21; - int32_t exponent = (((bits >> 24) & 0x7f) - 63) + 15; - - if (exponent > 31) // overflow: use max value - { - exponent = 31; - mantissa = 7; - } - if (exponent < 0) // underflow: use min value - { - exponent = 0; - mantissa = 1; - } - - return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t + if (exponent > 31) { // overflow: use max value + exponent = 31; + mantissa = 7; } + if (exponent < 0) { // underflow: use min value + exponent = 0; + mantissa = 1; + } + + return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t +} - double SmallDouble::byteToDouble(uint8_t b) - { - if (b == 0) // zero is a special case - return 0.0; - int32_t mantissa = b & 7; - int32_t exponent = (b >> 3) & 31; - int32_t bits = ((exponent + (63 - 15)) << 24) | (mantissa << 21); - return MiscUtils::intBitsToDouble(bits); +double SmallDouble::byteToDouble(uint8_t b) { + if (b == 0) { // zero is a special case + return 0.0; } + int32_t mantissa = b & 7; + int32_t exponent = (b >> 3) & 31; + int32_t bits = ((exponent + (63 - 15)) << 24) | (mantissa << 21); + return MiscUtils::intBitsToDouble(bits); +} + } diff --git a/src/core/util/SortedVIntList.cpp b/src/core/util/SortedVIntList.cpp index 0bd7259d..c5599ee6 100644 --- a/src/core/util/SortedVIntList.cpp +++ b/src/core/util/SortedVIntList.cpp @@ -12,181 +12,160 @@ #include "DocIdSetIterator.h" #include "MiscUtils.h" -namespace Lucene -{ - /// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the - /// index numbers of the set bits will be smaller than that BitSet. - const int32_t SortedVIntList::BITS2VINTLIST_SIZE = 8; - - const int32_t SortedVIntList::VB1 = 0x7f; - const int32_t SortedVIntList::BIT_SHIFT = 7; - const int32_t SortedVIntList::MAX_BYTES_PER_INT = (31 / SortedVIntList::BIT_SHIFT) + 1; - - SortedVIntList::SortedVIntList(Collection sortedInts) - { - lastInt = 0; - initBytes(); - for (int32_t i = 0; i < sortedInts.size(); ++i) - addInt(sortedInts[i]); - bytes.resize(lastBytePos); - } +namespace Lucene { - SortedVIntList::SortedVIntList(Collection sortedInts, int32_t inputSize) - { - lastInt = 0; - initBytes(); - for (int32_t i = 0; i < inputSize; ++i) - addInt(sortedInts[i]); - bytes.resize(lastBytePos); - } +/// When a BitSet has fewer than 1 in BITS2VINTLIST_SIZE bits set, a SortedVIntList representing the +/// index numbers of the set bits will be smaller than that BitSet. +const int32_t SortedVIntList::BITS2VINTLIST_SIZE = 8; - SortedVIntList::SortedVIntList(const BitSetPtr& bits) - { - lastInt = 0; - initBytes(); - int32_t nextInt = bits->nextSetBit(0); - while (nextInt != -1) - { - addInt(nextInt); - nextInt = bits->nextSetBit(nextInt + 1); - } - bytes.resize(lastBytePos); +const int32_t SortedVIntList::VB1 = 0x7f; +const int32_t SortedVIntList::BIT_SHIFT = 7; +const int32_t SortedVIntList::MAX_BYTES_PER_INT = (31 / SortedVIntList::BIT_SHIFT) + 1; + +SortedVIntList::SortedVIntList(Collection sortedInts) { + lastInt = 0; + initBytes(); + for (int32_t i = 0; i < sortedInts.size(); ++i) { + addInt(sortedInts[i]); } + bytes.resize(lastBytePos); +} - SortedVIntList::SortedVIntList(const OpenBitSetPtr& bits) - { - lastInt = 0; - initBytes(); - int32_t nextInt = bits->nextSetBit((int32_t)0); - while (nextInt != -1) - { - addInt(nextInt); - nextInt = bits->nextSetBit(nextInt + 1); - } - bytes.resize(lastBytePos); +SortedVIntList::SortedVIntList(Collection sortedInts, int32_t inputSize) { + lastInt = 0; + initBytes(); + for (int32_t i = 0; i < inputSize; ++i) { + addInt(sortedInts[i]); } + bytes.resize(lastBytePos); +} - SortedVIntList::SortedVIntList(const DocIdSetIteratorPtr& docIdSetIterator) - { - lastInt = 0; - initBytes(); - int32_t doc; - while ((doc = docIdSetIterator->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) - addInt(doc); - bytes.resize(lastBytePos); +SortedVIntList::SortedVIntList(const BitSetPtr& bits) { + lastInt = 0; + initBytes(); + int32_t nextInt = bits->nextSetBit(0); + while (nextInt != -1) { + addInt(nextInt); + nextInt = bits->nextSetBit(nextInt + 1); } + bytes.resize(lastBytePos); +} - SortedVIntList::~SortedVIntList() - { +SortedVIntList::SortedVIntList(const OpenBitSetPtr& bits) { + lastInt = 0; + initBytes(); + int32_t nextInt = bits->nextSetBit((int32_t)0); + while (nextInt != -1) { + addInt(nextInt); + nextInt = bits->nextSetBit(nextInt + 1); } + bytes.resize(lastBytePos); +} - void SortedVIntList::initBytes() - { - _size = 0; - bytes = ByteArray::newInstance(128); // initial byte size - lastBytePos = 0; +SortedVIntList::SortedVIntList(const DocIdSetIteratorPtr& docIdSetIterator) { + lastInt = 0; + initBytes(); + int32_t doc; + while ((doc = docIdSetIterator->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) { + addInt(doc); } + bytes.resize(lastBytePos); +} - void SortedVIntList::addInt(int32_t nextInt) - { - int32_t diff = nextInt - lastInt; - if (diff < 0) - boost::throw_exception(IllegalArgumentException(L"Input not sorted or first element negative.")); +SortedVIntList::~SortedVIntList() { +} - if (!bytes || (lastBytePos + MAX_BYTES_PER_INT) > bytes.size()) - { - // biggest possible int does not fit - bytes.resize((bytes.size() * 2) + MAX_BYTES_PER_INT); - } +void SortedVIntList::initBytes() { + _size = 0; + bytes = ByteArray::newInstance(128); // initial byte size + lastBytePos = 0; +} - // See IndexOutput.writeVInt() - while ((diff & ~VB1) != 0) // The high bit of the next byte needs to be set. - { - bytes[lastBytePos++] = (uint8_t)((diff & VB1) | ~VB1); - diff = MiscUtils::unsignedShift(diff, BIT_SHIFT); - } - bytes[lastBytePos++] = (uint8_t)diff; // Last byte, high bit not set. - ++_size; - lastInt = nextInt; +void SortedVIntList::addInt(int32_t nextInt) { + int32_t diff = nextInt - lastInt; + if (diff < 0) { + boost::throw_exception(IllegalArgumentException(L"Input not sorted or first element negative.")); } - int32_t SortedVIntList::size() - { - return _size; + if (!bytes || (lastBytePos + MAX_BYTES_PER_INT) > bytes.size()) { + // biggest possible int does not fit + bytes.resize((bytes.size() * 2) + MAX_BYTES_PER_INT); } - int32_t SortedVIntList::getByteSize() - { - return bytes ? bytes.size() : 0; + // See IndexOutput.writeVInt() + while ((diff & ~VB1) != 0) { // The high bit of the next byte needs to be set. + bytes[lastBytePos++] = (uint8_t)((diff & VB1) | ~VB1); + diff = MiscUtils::unsignedShift(diff, BIT_SHIFT); } + bytes[lastBytePos++] = (uint8_t)diff; // Last byte, high bit not set. + ++_size; + lastInt = nextInt; +} - bool SortedVIntList::isCacheable() - { - return true; - } +int32_t SortedVIntList::size() { + return _size; +} - DocIdSetIteratorPtr SortedVIntList::iterator() - { - return newLucene(shared_from_this()); - } +int32_t SortedVIntList::getByteSize() { + return bytes ? bytes.size() : 0; +} - SortedDocIdSetIterator::SortedDocIdSetIterator(const SortedVIntListPtr& list) - { - _list = list; - bytePos = 0; - lastInt = 0; - doc = -1; - } +bool SortedVIntList::isCacheable() { + return true; +} - SortedDocIdSetIterator::~SortedDocIdSetIterator() - { - } +DocIdSetIteratorPtr SortedVIntList::iterator() { + return newLucene(shared_from_this()); +} - void SortedDocIdSetIterator::advance() - { - SortedVIntListPtr list(_list); - - // See IndexInput.readVInt() - uint8_t b = list->bytes[bytePos++]; - lastInt += b & list->VB1; - for (int32_t s = list->BIT_SHIFT; (b & ~list->VB1) != 0; s += list->BIT_SHIFT) - { - b = list->bytes[bytePos++]; - lastInt += (b & list->VB1) << s; - } +SortedDocIdSetIterator::SortedDocIdSetIterator(const SortedVIntListPtr& list) { + _list = list; + bytePos = 0; + lastInt = 0; + doc = -1; +} + +SortedDocIdSetIterator::~SortedDocIdSetIterator() { +} + +void SortedDocIdSetIterator::advance() { + SortedVIntListPtr list(_list); + + // See IndexInput.readVInt() + uint8_t b = list->bytes[bytePos++]; + lastInt += b & list->VB1; + for (int32_t s = list->BIT_SHIFT; (b & ~list->VB1) != 0; s += list->BIT_SHIFT) { + b = list->bytes[bytePos++]; + lastInt += (b & list->VB1) << s; } +} + +int32_t SortedDocIdSetIterator::docID() { + return doc; +} - int32_t SortedDocIdSetIterator::docID() - { - return doc; +int32_t SortedDocIdSetIterator::nextDoc() { + SortedVIntListPtr list(_list); + if (bytePos >= list->lastBytePos) { + doc = NO_MORE_DOCS; + } else { + advance(); + doc = lastInt; } + return doc; +} - int32_t SortedDocIdSetIterator::nextDoc() - { - SortedVIntListPtr list(_list); - if (bytePos >= list->lastBytePos) - doc = NO_MORE_DOCS; - else - { - advance(); +int32_t SortedDocIdSetIterator::advance(int32_t target) { + SortedVIntListPtr list(_list); + while (bytePos < list->lastBytePos) { + advance(); + if (lastInt >= target) { doc = lastInt; + return doc; } - return doc; } + doc = NO_MORE_DOCS; + return doc; +} - int32_t SortedDocIdSetIterator::advance(int32_t target) - { - SortedVIntListPtr list(_list); - while (bytePos < list->lastBytePos) - { - advance(); - if (lastInt >= target) - { - doc = lastInt; - return doc; - } - } - doc = NO_MORE_DOCS; - return doc; - } } diff --git a/src/core/util/StringReader.cpp b/src/core/util/StringReader.cpp index 04fcef1f..81f83e1e 100644 --- a/src/core/util/StringReader.cpp +++ b/src/core/util/StringReader.cpp @@ -7,50 +7,44 @@ #include "LuceneInc.h" #include "StringReader.h" -namespace Lucene -{ - StringReader::StringReader(const String& str) - { - this->str = str; - this->position = 0; - } +namespace Lucene { - StringReader::~StringReader() - { - } +StringReader::StringReader(const String& str) { + this->str = str; + this->position = 0; +} - int32_t StringReader::read() - { - return position == (int32_t)str.length() ? READER_EOF : (int32_t)str[position++]; - } +StringReader::~StringReader() { +} - int32_t StringReader::read(wchar_t* buffer, int32_t offset, int32_t length) - { - if (position >= (int32_t)str.length()) - return READER_EOF; - int32_t readChars = std::min(length, (int32_t)str.length() - position); - std::wcsncpy(buffer + offset, str.c_str() + position, readChars); - position += readChars; - return readChars; - } +int32_t StringReader::read() { + return position == (int32_t)str.length() ? READER_EOF : (int32_t)str[position++]; +} - void StringReader::close() - { - str.clear(); +int32_t StringReader::read(wchar_t* buffer, int32_t offset, int32_t length) { + if (position >= (int32_t)str.length()) { + return READER_EOF; } + int32_t readChars = std::min(length, (int32_t)str.length() - position); + std::wcsncpy(buffer + offset, str.c_str() + position, readChars); + position += readChars; + return readChars; +} - bool StringReader::markSupported() - { - return false; - } +void StringReader::close() { + str.clear(); +} - void StringReader::reset() - { - position = 0; - } +bool StringReader::markSupported() { + return false; +} + +void StringReader::reset() { + position = 0; +} + +int64_t StringReader::length() { + return str.length(); +} - int64_t StringReader::length() - { - return str.length(); - } } diff --git a/src/core/util/StringUtils.cpp b/src/core/util/StringUtils.cpp index bc950f19..76474100 100644 --- a/src/core/util/StringUtils.cpp +++ b/src/core/util/StringUtils.cpp @@ -13,193 +13,187 @@ #include "Reader.h" #include "CharFolder.h" -namespace Lucene -{ - /// Maximum length of UTF encoding. - const int32_t StringUtils::MAX_ENCODING_UTF8_SIZE = 4; - - /// Default character radix. - const int32_t StringUtils::CHARACTER_MAX_RADIX = 36; - - int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, CharArray unicode) - { - if (length == 0) - return 0; - UTF8Decoder utf8Decoder(utf8, utf8 + length); - int32_t decodeLength = utf8Decoder.decode(unicode.get(), unicode.size()); - return decodeLength == Reader::READER_EOF ? 0 : decodeLength; - } - - int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, const UnicodeResultPtr& unicodeResult) - { - if (length == 0) - unicodeResult->length = 0; - else - { - if (length > unicodeResult->result.size()) - unicodeResult->result.resize(length); - unicodeResult->length = toUnicode(utf8, length, unicodeResult->result); - } - return unicodeResult->length; - } +namespace Lucene { - String StringUtils::toUnicode(const uint8_t* utf8, int32_t length) - { - if (length == 0) - return L""; - CharArray unicode(CharArray::newInstance(length)); - int32_t result = toUnicode(utf8, length, unicode); - return String(unicode.get(), result); - } +/// Maximum length of UTF encoding. +const int32_t StringUtils::MAX_ENCODING_UTF8_SIZE = 4; - String StringUtils::toUnicode(const SingleString& s) - { - return s.empty() ? L"" : toUnicode((uint8_t*)s.c_str(), s.length()); - } +/// Default character radix. +const int32_t StringUtils::CHARACTER_MAX_RADIX = 36; - int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, ByteArray utf8) - { - if (length == 0) - return 0; - UTF8Encoder utf8Encoder(unicode, unicode + length); - int32_t encodeLength = utf8Encoder.encode(utf8.get(), utf8.size()); - return encodeLength == Reader::READER_EOF ? 0 : encodeLength; +int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, CharArray unicode) { + if (length == 0) { + return 0; } + UTF8Decoder utf8Decoder(utf8, utf8 + length); + int32_t decodeLength = utf8Decoder.decode(unicode.get(), unicode.size()); + return decodeLength == Reader::READER_EOF ? 0 : decodeLength; +} - int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, const UTF8ResultPtr& utf8Result) - { - if (length == 0) - utf8Result->length = 0; - else - { - if (length * MAX_ENCODING_UTF8_SIZE > utf8Result->result.size()) - utf8Result->result.resize(length * MAX_ENCODING_UTF8_SIZE); - utf8Result->length = toUTF8(unicode, length, utf8Result->result); +int32_t StringUtils::toUnicode(const uint8_t* utf8, int32_t length, const UnicodeResultPtr& unicodeResult) { + if (length == 0) { + unicodeResult->length = 0; + } else { + if (length > unicodeResult->result.size()) { + unicodeResult->result.resize(length); } - return utf8Result->length; + unicodeResult->length = toUnicode(utf8, length, unicodeResult->result); } + return unicodeResult->length; +} - SingleString StringUtils::toUTF8(const wchar_t* unicode, int32_t length) - { - if (length == 0) - return ""; - ByteArray utf8(ByteArray::newInstance(length * MAX_ENCODING_UTF8_SIZE)); - int32_t result = toUTF8(unicode, length, utf8); - return SingleString((char*)utf8.get(), result); +String StringUtils::toUnicode(const uint8_t* utf8, int32_t length) { + if (length == 0) { + return L""; } + CharArray unicode(CharArray::newInstance(length)); + int32_t result = toUnicode(utf8, length, unicode); + return String(unicode.get(), result); +} - SingleString StringUtils::toUTF8(const String& s) - { - return s.empty() ? "" : toUTF8(s.c_str(), s.size()); - } +String StringUtils::toUnicode(const SingleString& s) { + return s.empty() ? L"" : toUnicode((uint8_t*)s.c_str(), s.length()); +} - void StringUtils::toLower(String& str) - { - CharFolder::toLower(str.begin(), str.end()); +int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, ByteArray utf8) { + if (length == 0) { + return 0; } + UTF8Encoder utf8Encoder(unicode, unicode + length); + int32_t encodeLength = utf8Encoder.encode(utf8.get(), utf8.size()); + return encodeLength == Reader::READER_EOF ? 0 : encodeLength; +} - String StringUtils::toLower(const String& str) - { - String lowerStr(str); - toLower(lowerStr); - return lowerStr; +int32_t StringUtils::toUTF8(const wchar_t* unicode, int32_t length, const UTF8ResultPtr& utf8Result) { + if (length == 0) { + utf8Result->length = 0; + } else { + if (length * MAX_ENCODING_UTF8_SIZE > utf8Result->result.size()) { + utf8Result->result.resize(length * MAX_ENCODING_UTF8_SIZE); + } + utf8Result->length = toUTF8(unicode, length, utf8Result->result); } + return utf8Result->length; +} - void StringUtils::toUpper(String& str) - { - CharFolder::toUpper(str.begin(), str.end()); +SingleString StringUtils::toUTF8(const wchar_t* unicode, int32_t length) { + if (length == 0) { + return ""; } + ByteArray utf8(ByteArray::newInstance(length * MAX_ENCODING_UTF8_SIZE)); + int32_t result = toUTF8(unicode, length, utf8); + return SingleString((char*)utf8.get(), result); +} - String StringUtils::toUpper(const String& str) - { - String upperStr(str); - toUpper(upperStr); - return upperStr; - } +SingleString StringUtils::toUTF8(const String& s) { + return s.empty() ? "" : toUTF8(s.c_str(), s.size()); +} - int32_t StringUtils::compareCase(const String& first, const String& second) - { - return (toLower(first) == toLower(second)); - } +void StringUtils::toLower(String& str) { + CharFolder::toLower(str.begin(), str.end()); +} - Collection StringUtils::split(const String& str, const String& delim) - { - std::vector tokens; - boost::split(tokens, str, boost::is_any_of(delim.c_str())); - return Collection::newInstance(tokens.begin(), tokens.end()); - } +String StringUtils::toLower(const String& str) { + String lowerStr(str); + toLower(lowerStr); + return lowerStr; +} + +void StringUtils::toUpper(String& str) { + CharFolder::toUpper(str.begin(), str.end()); +} - int32_t StringUtils::toInt(const String& value) - { - if (value.empty()) - boost::throw_exception(NumberFormatException()); - if (value.size() > 1 && value[0] == L'-' && !UnicodeUtil::isDigit(value[1])) - boost::throw_exception(NumberFormatException()); - if (value[0] != L'-' && !UnicodeUtil::isDigit(value[0])) - boost::throw_exception(NumberFormatException()); - return (int32_t)std::wcstol(value.c_str(), NULL, 10); +String StringUtils::toUpper(const String& str) { + String upperStr(str); + toUpper(upperStr); + return upperStr; +} + +int32_t StringUtils::compareCase(const String& first, const String& second) { + return (toLower(first) == toLower(second)); +} + +Collection StringUtils::split(const String& str, const String& delim) { + std::vector tokens; + boost::split(tokens, str, boost::is_any_of(delim.c_str())); + return Collection::newInstance(tokens.begin(), tokens.end()); +} + +int32_t StringUtils::toInt(const String& value) { + if (value.empty()) { + boost::throw_exception(NumberFormatException()); } + if (value.size() > 1 && value[0] == L'-' && !UnicodeUtil::isDigit(value[1])) { + boost::throw_exception(NumberFormatException()); + } + if (value[0] != L'-' && !UnicodeUtil::isDigit(value[0])) { + boost::throw_exception(NumberFormatException()); + } + return (int32_t)std::wcstol(value.c_str(), NULL, 10); +} - int64_t StringUtils::toLong(const String& value) - { - if (value.empty()) - boost::throw_exception(NumberFormatException()); - if (value.size() > 1 && value[0] == L'-' && !UnicodeUtil::isDigit(value[1])) - boost::throw_exception(NumberFormatException()); - if (value[0] != L'-' && !UnicodeUtil::isDigit(value[0])) - boost::throw_exception(NumberFormatException()); - #if defined(_WIN32) || defined(_WIN64) - return _wcstoi64(value.c_str(), 0, 10); - #else - return wcstoll(value.c_str(), 0, 10); - #endif +int64_t StringUtils::toLong(const String& value) { + if (value.empty()) { + boost::throw_exception(NumberFormatException()); + } + if (value.size() > 1 && value[0] == L'-' && !UnicodeUtil::isDigit(value[1])) { + boost::throw_exception(NumberFormatException()); + } + if (value[0] != L'-' && !UnicodeUtil::isDigit(value[0])) { + boost::throw_exception(NumberFormatException()); } +#if defined(_WIN32) || defined(_WIN64) + return _wcstoi64(value.c_str(), 0, 10); +#else + return wcstoll(value.c_str(), 0, 10); +#endif +} - int64_t StringUtils::toLong(const String& value, int32_t base) - { - int64_t longValue = 0; - for (String::const_iterator ptr = value.begin(); ptr != value.end(); ++ptr) - longValue = UnicodeUtil::isDigit(*ptr) ? (base * longValue) + (*ptr - L'0') : (base * longValue) + (*ptr - L'a' + 10); - return longValue; +int64_t StringUtils::toLong(const String& value, int32_t base) { + int64_t longValue = 0; + for (String::const_iterator ptr = value.begin(); ptr != value.end(); ++ptr) { + longValue = UnicodeUtil::isDigit(*ptr) ? (base * longValue) + (*ptr - L'0') : (base * longValue) + (*ptr - L'a' + 10); } + return longValue; +} - double StringUtils::toDouble(const String& value) - { - if (value.empty()) - boost::throw_exception(NumberFormatException()); - if (value.length() > 1 && (value[0] == L'-' || value[0] == L'.') && !UnicodeUtil::isDigit(value[1])) - boost::throw_exception(NumberFormatException()); - if (value[0] != L'-' && value[0] != L'.' && !UnicodeUtil::isDigit(value[0])) - boost::throw_exception(NumberFormatException()); - return std::wcstod(value.c_str(), NULL); +double StringUtils::toDouble(const String& value) { + if (value.empty()) { + boost::throw_exception(NumberFormatException()); + } + if (value.length() > 1 && (value[0] == L'-' || value[0] == L'.') && !UnicodeUtil::isDigit(value[1])) { + boost::throw_exception(NumberFormatException()); } + if (value[0] != L'-' && value[0] != L'.' && !UnicodeUtil::isDigit(value[0])) { + boost::throw_exception(NumberFormatException()); + } + return std::wcstod(value.c_str(), NULL); +} - int32_t StringUtils::hashCode(const String& value) - { - int32_t hashCode = 0; - for (String::const_iterator ptr = value.begin(); ptr != value.end(); ++ptr) - hashCode = hashCode * 31 + *ptr; - return hashCode; +int32_t StringUtils::hashCode(const String& value) { + int32_t hashCode = 0; + for (String::const_iterator ptr = value.begin(); ptr != value.end(); ++ptr) { + hashCode = hashCode * 31 + *ptr; } + return hashCode; +} - String StringUtils::toString(int64_t value, int32_t base) - { - static const wchar_t* digits = L"0123456789abcdefghijklmnopqrstuvwxyz"; +String StringUtils::toString(int64_t value, int32_t base) { + static const wchar_t* digits = L"0123456789abcdefghijklmnopqrstuvwxyz"; - int32_t bufferSize = (sizeof(int32_t) << 3) + 1; - CharArray baseOutput(CharArray::newInstance(bufferSize)); + int32_t bufferSize = (sizeof(int32_t) << 3) + 1; + CharArray baseOutput(CharArray::newInstance(bufferSize)); - wchar_t* ptr = baseOutput.get() + bufferSize - 1; - *ptr = L'\0'; + wchar_t* ptr = baseOutput.get() + bufferSize - 1; + *ptr = L'\0'; - do - { - *--ptr = digits[value % base]; - value /= base; - } - while (ptr > baseOutput.get() && value > 0); + do { + *--ptr = digits[value % base]; + value /= base; + } while (ptr > baseOutput.get() && value > 0); + + return String(ptr, (baseOutput.get() + bufferSize - 1) - ptr); +} - return String(ptr, (baseOutput.get() + bufferSize - 1) - ptr); - } } diff --git a/src/core/util/Synchronize.cpp b/src/core/util/Synchronize.cpp index 50b54fcf..47901076 100644 --- a/src/core/util/Synchronize.cpp +++ b/src/core/util/Synchronize.cpp @@ -9,71 +9,68 @@ #include "Synchronize.h" #include "LuceneThread.h" -namespace Lucene -{ - Synchronize::Synchronize() - { - lockThread = 0; - recursionCount = 0; - } +namespace Lucene { - Synchronize::~Synchronize() - { - } +Synchronize::Synchronize() { + lockThread = 0; + recursionCount = 0; +} - void Synchronize::createSync(SynchronizePtr& sync) - { - static boost::mutex lockMutex; - boost::mutex::scoped_lock syncLock(lockMutex); - if (!sync) - sync = newInstance(); - } +Synchronize::~Synchronize() { +} - void Synchronize::lock(int32_t timeout) - { - if (timeout > 0) - mutexSynchronize.timed_lock(boost::posix_time::milliseconds(timeout)); - else - mutexSynchronize.lock(); - lockThread = LuceneThread::currentId(); - ++recursionCount; +void Synchronize::createSync(SynchronizePtr& sync) { + static boost::mutex lockMutex; + boost::mutex::scoped_lock syncLock(lockMutex); + if (!sync) { + sync = newInstance(); } +} - void Synchronize::unlock() - { - if (--recursionCount == 0) - lockThread = 0; - mutexSynchronize.unlock(); +void Synchronize::lock(int32_t timeout) { + if (timeout > 0) { + mutexSynchronize.timed_lock(boost::posix_time::milliseconds(timeout)); + } else { + mutexSynchronize.lock(); } + lockThread = LuceneThread::currentId(); + ++recursionCount; +} - int32_t Synchronize::unlockAll() - { - int32_t count = recursionCount; - for (int32_t unlock = 0; unlock < count; ++unlock) - this->unlock(); - return count; +void Synchronize::unlock() { + if (--recursionCount == 0) { + lockThread = 0; } + mutexSynchronize.unlock(); +} - bool Synchronize::holdsLock() - { - return (lockThread == LuceneThread::currentId() && recursionCount > 0); +int32_t Synchronize::unlockAll() { + int32_t count = recursionCount; + for (int32_t unlock = 0; unlock < count; ++unlock) { + this->unlock(); } + return count; +} - SyncLock::SyncLock(const SynchronizePtr& sync, int32_t timeout) - { - this->sync = sync; - lock(timeout); - } +bool Synchronize::holdsLock() { + return (lockThread == LuceneThread::currentId() && recursionCount > 0); +} - SyncLock::~SyncLock() - { - if (sync) - sync->unlock(); +SyncLock::SyncLock(const SynchronizePtr& sync, int32_t timeout) { + this->sync = sync; + lock(timeout); +} + +SyncLock::~SyncLock() { + if (sync) { + sync->unlock(); } +} - void SyncLock::lock(int32_t timeout) - { - if (sync) - sync->lock(timeout); +void SyncLock::lock(int32_t timeout) { + if (sync) { + sync->lock(timeout); } } + +} diff --git a/src/core/util/TestPoint.cpp b/src/core/util/TestPoint.cpp index c0850b0e..1319037d 100644 --- a/src/core/util/TestPoint.cpp +++ b/src/core/util/TestPoint.cpp @@ -7,59 +7,51 @@ #include "LuceneInc.h" #include "TestPoint.h" -namespace Lucene -{ - MapStringInt TestPoint::testMethods = MapStringInt::newInstance(); - bool TestPoint::enable = false; +namespace Lucene { - TestPoint::~TestPoint() - { - } +MapStringInt TestPoint::testMethods = MapStringInt::newInstance(); +bool TestPoint::enable = false; - void TestPoint::enableTestPoints() - { - enable = true; - } +TestPoint::~TestPoint() { +} - void TestPoint::clear() - { - SyncLock syncLock(&testMethods); - testMethods.clear(); - } +void TestPoint::enableTestPoints() { + enable = true; +} - void TestPoint::setTestPoint(const String& object, const String& method, bool point) - { - if (enable) - { - SyncLock syncLock(&testMethods); - testMethods.put(object + L":" + method, point); - testMethods.put(method, point); - } - } +void TestPoint::clear() { + SyncLock syncLock(&testMethods); + testMethods.clear(); +} - bool TestPoint::getTestPoint(const String& object, const String& method) - { +void TestPoint::setTestPoint(const String& object, const String& method, bool point) { + if (enable) { SyncLock syncLock(&testMethods); - MapStringInt::iterator testMethod = testMethods.find(object + L":" + method); - return testMethod == testMethods.end() ? false : (testMethod->second != 0); + testMethods.put(object + L":" + method, point); + testMethods.put(method, point); } +} - bool TestPoint::getTestPoint(const String& method) - { - SyncLock syncLock(&testMethods); - MapStringInt::iterator testMethod = testMethods.find(method); - return testMethod == testMethods.end() ? false : (testMethod->second != 0); - } +bool TestPoint::getTestPoint(const String& object, const String& method) { + SyncLock syncLock(&testMethods); + MapStringInt::iterator testMethod = testMethods.find(object + L":" + method); + return testMethod == testMethods.end() ? false : (testMethod->second != 0); +} - TestScope::TestScope(const String& object, const String& method) - { - this->object = object; - this->method = method; - TestPoint::setTestPoint(object, method, true); - } +bool TestPoint::getTestPoint(const String& method) { + SyncLock syncLock(&testMethods); + MapStringInt::iterator testMethod = testMethods.find(method); + return testMethod == testMethods.end() ? false : (testMethod->second != 0); +} + +TestScope::TestScope(const String& object, const String& method) { + this->object = object; + this->method = method; + TestPoint::setTestPoint(object, method, true); +} + +TestScope::~TestScope() { + TestPoint::setTestPoint(object, method, false); +} - TestScope::~TestScope() - { - TestPoint::setTestPoint(object, method, false); - } } diff --git a/src/core/util/ThreadPool.cpp b/src/core/util/ThreadPool.cpp index 564620c2..c8dc10e0 100644 --- a/src/core/util/ThreadPool.cpp +++ b/src/core/util/ThreadPool.cpp @@ -7,35 +7,32 @@ #include "LuceneInc.h" #include "ThreadPool.h" -namespace Lucene -{ - Future::~Future() - { - } +namespace Lucene { - const int32_t ThreadPool::THREADPOOL_SIZE = 5; +Future::~Future() { +} - ThreadPool::ThreadPool() - { - work.reset(new boost::asio::io_service::work(io_service)); - for (int32_t i = 0; i < THREADPOOL_SIZE; ++i) - threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &io_service)); - } +const int32_t ThreadPool::THREADPOOL_SIZE = 5; - ThreadPool::~ThreadPool() - { - work.reset(); // stop all threads - threadGroup.join_all(); // wait for all competition +ThreadPool::ThreadPool() { + work.reset(new boost::asio::io_service::work(io_service)); + for (int32_t i = 0; i < THREADPOOL_SIZE; ++i) { + threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &io_service)); } +} - ThreadPoolPtr ThreadPool::getInstance() - { - static ThreadPoolPtr threadPool; - if (!threadPool) - { - threadPool = newLucene(); - CycleCheck::addStatic(threadPool); - } - return threadPool; +ThreadPool::~ThreadPool() { + work.reset(); // stop all threads + threadGroup.join_all(); // wait for all competition +} + +ThreadPoolPtr ThreadPool::getInstance() { + static ThreadPoolPtr threadPool; + if (!threadPool) { + threadPool = newLucene(); + CycleCheck::addStatic(threadPool); } + return threadPool; +} + } diff --git a/src/core/util/UTF8Stream.cpp b/src/core/util/UTF8Stream.cpp index ecc4c748..3762469b 100644 --- a/src/core/util/UTF8Stream.cpp +++ b/src/core/util/UTF8Stream.cpp @@ -8,415 +8,386 @@ #include "UTF8Stream.h" #include "Reader.h" -namespace Lucene -{ - const uint16_t UTF8Base::LEAD_SURROGATE_MIN = 0xd800u; - const uint16_t UTF8Base::LEAD_SURROGATE_MAX = 0xdbffu; - const uint16_t UTF8Base::TRAIL_SURROGATE_MIN = 0xdc00u; - const uint16_t UTF8Base::TRAIL_SURROGATE_MAX = 0xdfffu; - const uint16_t UTF8Base::LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); - const uint32_t UTF8Base::SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; - - // Maximum valid value for a Unicode code point - const uint32_t UTF8Base::CODE_POINT_MAX = 0x0010ffffu; - - #ifdef LPP_UNICODE_CHAR_SIZE_2 - const wchar_t UTF8Base::UNICODE_REPLACEMENT_CHAR = (wchar_t)0xfffd; - const wchar_t UTF8Base::UNICODE_TERMINATOR = (wchar_t)0xffff; - #else - const wchar_t UTF8Base::UNICODE_REPLACEMENT_CHAR = (wchar_t)0x0001fffd; - const wchar_t UTF8Base::UNICODE_TERMINATOR = (wchar_t)0x0001ffff; - #endif - - UTF8Base::~UTF8Base() - { - } +namespace Lucene { + +const uint16_t UTF8Base::LEAD_SURROGATE_MIN = 0xd800u; +const uint16_t UTF8Base::LEAD_SURROGATE_MAX = 0xdbffu; +const uint16_t UTF8Base::TRAIL_SURROGATE_MIN = 0xdc00u; +const uint16_t UTF8Base::TRAIL_SURROGATE_MAX = 0xdfffu; +const uint16_t UTF8Base::LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); +const uint32_t UTF8Base::SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; + +// Maximum valid value for a Unicode code point +const uint32_t UTF8Base::CODE_POINT_MAX = 0x0010ffffu; + +#ifdef LPP_UNICODE_CHAR_SIZE_2 +const wchar_t UTF8Base::UNICODE_REPLACEMENT_CHAR = (wchar_t)0xfffd; +const wchar_t UTF8Base::UNICODE_TERMINATOR = (wchar_t)0xffff; +#else +const wchar_t UTF8Base::UNICODE_REPLACEMENT_CHAR = (wchar_t)0x0001fffd; +const wchar_t UTF8Base::UNICODE_TERMINATOR = (wchar_t)0x0001ffff; +#endif + +UTF8Base::~UTF8Base() { +} - inline uint8_t UTF8Base::mask8(uint32_t b) - { - return static_cast(0xff & b); - } +inline uint8_t UTF8Base::mask8(uint32_t b) { + return static_cast(0xff & b); +} - inline uint16_t UTF8Base::mask16(uint32_t c) - { - return static_cast(0xffff & c); - } +inline uint16_t UTF8Base::mask16(uint32_t c) { + return static_cast(0xffff & c); +} - inline bool UTF8Base::isTrail(uint32_t b) - { - return ((mask8(b) >> 6) == 0x2); - } +inline bool UTF8Base::isTrail(uint32_t b) { + return ((mask8(b) >> 6) == 0x2); +} - inline bool UTF8Base::isSurrogate(uint32_t cp) - { - return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); - } +inline bool UTF8Base::isSurrogate(uint32_t cp) { + return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); +} - inline bool UTF8Base::isLeadSurrogate(uint32_t cp) - { - return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); - } +inline bool UTF8Base::isLeadSurrogate(uint32_t cp) { + return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); +} - inline bool UTF8Base::isTrailSurrogate(uint32_t cp) - { - return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); - } +inline bool UTF8Base::isTrailSurrogate(uint32_t cp) { + return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); +} - inline bool UTF8Base::isValidCodePoint(uint32_t cp) - { - return (cp <= CODE_POINT_MAX && !isSurrogate(cp) && cp != 0xfffe && cp != 0xffff); - } +inline bool UTF8Base::isValidCodePoint(uint32_t cp) { + return (cp <= CODE_POINT_MAX && !isSurrogate(cp) && cp != 0xfffe && cp != 0xffff); +} - inline bool UTF8Base::isOverlongSequence(uint32_t cp, int32_t length) - { - if (cp < 0x80) - { - if (length != 1) - return true; +inline bool UTF8Base::isOverlongSequence(uint32_t cp, int32_t length) { + if (cp < 0x80) { + if (length != 1) { + return true; } - else if (cp < 0x800) - { - if (length != 2) - return true; + } else if (cp < 0x800) { + if (length != 2) { + return true; } - else if (cp < 0x10000) - { - if (length != 3) - return true; + } else if (cp < 0x10000) { + if (length != 3) { + return true; } - return false; } + return false; +} - UTF8Encoder::UTF8Encoder(const wchar_t* unicodeBegin, const wchar_t* unicodeEnd) - { - this->unicodeBegin = unicodeBegin; - this->unicodeEnd = unicodeEnd; - } +UTF8Encoder::UTF8Encoder(const wchar_t* unicodeBegin, const wchar_t* unicodeEnd) { + this->unicodeBegin = unicodeBegin; + this->unicodeEnd = unicodeEnd; +} - UTF8Encoder::~UTF8Encoder() - { - } +UTF8Encoder::~UTF8Encoder() { +} - uint32_t UTF8Encoder::readNext() - { - return unicodeBegin == unicodeEnd ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*unicodeBegin++; - } +uint32_t UTF8Encoder::readNext() { + return unicodeBegin == unicodeEnd ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*unicodeBegin++; +} - inline uint8_t* UTF8Encoder::appendChar(uint8_t* utf8, uint32_t cp) - { - if (cp < 0x80) // one octet - *(utf8++) = static_cast(cp); - else if (cp < 0x800) // two octets - { - *(utf8++) = static_cast((cp >> 6) | 0xc0); - *(utf8++) = static_cast((cp & 0x3f) | 0x80); +inline uint8_t* UTF8Encoder::appendChar(uint8_t* utf8, uint32_t cp) { + if (cp < 0x80) { // one octet + *(utf8++) = static_cast(cp); + } else if (cp < 0x800) { // two octets + *(utf8++) = static_cast((cp >> 6) | 0xc0); + *(utf8++) = static_cast((cp & 0x3f) | 0x80); + } else if (cp < 0x10000) { // three octets + *(utf8++) = static_cast((cp >> 12) | 0xe0); + *(utf8++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(utf8++) = static_cast((cp & 0x3f) | 0x80); + } else { // four octets + *(utf8++) = static_cast((cp >> 18) | 0xf0); + *(utf8++) = static_cast(((cp >> 12) & 0x3f) | 0x80); + *(utf8++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(utf8++) = static_cast((cp & 0x3f) | 0x80); + } + return utf8; +} + +int32_t UTF8Encoder::utf16to8(uint8_t* utf8, int32_t length) { + uint8_t* start = utf8; + uint32_t next = readNext(); + + while (next != UNICODE_TERMINATOR) { + uint32_t cp = mask16(next); + if (isLeadSurrogate(cp)) { + next = readNext(); + if (next == UNICODE_TERMINATOR) { + return 0; + } + uint32_t trail_surrogate = mask16(next); + if (!isTrailSurrogate(trail_surrogate)) { + return 0; + } + cp = (cp << 10) + trail_surrogate + SURROGATE_OFFSET; + } else if (isTrailSurrogate(cp)) { + return 0; } - else if (cp < 0x10000) // three octets - { - *(utf8++) = static_cast((cp >> 12) | 0xe0); - *(utf8++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(utf8++) = static_cast((cp & 0x3f) | 0x80); + if (!isValidCodePoint(cp)) { + return 0; } - else // four octets - { - *(utf8++) = static_cast((cp >> 18) | 0xf0); - *(utf8++) = static_cast(((cp >> 12) & 0x3f) | 0x80); - *(utf8++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(utf8++) = static_cast((cp & 0x3f) | 0x80); + utf8 = appendChar(utf8, cp); + if ((utf8 - start) >= length) { + break; } - return utf8; + next = readNext(); } - int32_t UTF8Encoder::utf16to8(uint8_t* utf8, int32_t length) - { - uint8_t* start = utf8; - uint32_t next = readNext(); - - while (next != UNICODE_TERMINATOR) - { - uint32_t cp = mask16(next); - if (isLeadSurrogate(cp)) - { - next = readNext(); - if (next == UNICODE_TERMINATOR) - return 0; - uint32_t trail_surrogate = mask16(next); - if (!isTrailSurrogate(trail_surrogate)) - return 0; - cp = (cp << 10) + trail_surrogate + SURROGATE_OFFSET; - } - else if (isTrailSurrogate(cp)) - return 0; - if (!isValidCodePoint(cp)) - return 0; - utf8 = appendChar(utf8, cp); - if ((utf8 - start) >= length) - break; - next = readNext(); - } + return ((utf8 - start) == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : (utf8 - start); +} + +int32_t UTF8Encoder::utf32to8(uint8_t* utf8, int32_t length) { + uint8_t* start = utf8; + uint32_t next = readNext(); - return ((utf8 - start) == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : (utf8 - start); + while (next != UNICODE_TERMINATOR) { + if (!isValidCodePoint(next)) { + return 0; + } + utf8 = appendChar(utf8, next); + if ((utf8 - start) >= length) { + break; + } + next = readNext(); } - int32_t UTF8Encoder::utf32to8(uint8_t* utf8, int32_t length) - { - uint8_t* start = utf8; - uint32_t next = readNext(); + return ((utf8 - start) == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : (utf8 - start); +} - while (next != UNICODE_TERMINATOR) - { - if (!isValidCodePoint(next)) - return 0; - utf8 = appendChar(utf8, next); - if ((utf8 - start) >= length) - break; - next = readNext(); - } +int32_t UTF8Encoder::encode(uint8_t* utf8, int32_t length) { +#ifdef LPP_UNICODE_CHAR_SIZE_2 + return utf16to8(utf8, length); +#else + return utf32to8(utf8, length); +#endif +} - return ((utf8 - start) == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : (utf8 - start); - } +UTF8EncoderStream::UTF8EncoderStream(const ReaderPtr& reader) : UTF8Encoder(NULL, NULL) { + this->reader = reader; +} - int32_t UTF8Encoder::encode(uint8_t* utf8, int32_t length) - { - #ifdef LPP_UNICODE_CHAR_SIZE_2 - return utf16to8(utf8, length); - #else - return utf32to8(utf8, length); - #endif - } +UTF8EncoderStream::~UTF8EncoderStream() { +} - UTF8EncoderStream::UTF8EncoderStream(const ReaderPtr& reader) : UTF8Encoder(NULL, NULL) - { - this->reader = reader; - } +uint32_t UTF8EncoderStream::readNext() { + int32_t next = reader->read(); + return next == Reader::READER_EOF ? UNICODE_TERMINATOR : (uint32_t)next; +} - UTF8EncoderStream::~UTF8EncoderStream() - { - } +UTF8Decoder::UTF8Decoder(const uint8_t* utf8Begin, const uint8_t* utf8End) { + this->utf8Begin = utf8Begin; + this->utf8End = utf8End; +} - uint32_t UTF8EncoderStream::readNext() - { - int32_t next = reader->read(); - return next == Reader::READER_EOF ? UNICODE_TERMINATOR : (uint32_t)next; - } +UTF8Decoder::~UTF8Decoder() { +} - UTF8Decoder::UTF8Decoder(const uint8_t* utf8Begin, const uint8_t* utf8End) - { - this->utf8Begin = utf8Begin; - this->utf8End = utf8End; - } +uint32_t UTF8Decoder::readNext() { + return utf8Begin == utf8End ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*utf8Begin++; +} - UTF8Decoder::~UTF8Decoder() - { - } +inline int32_t UTF8Decoder::sequenceLength(uint32_t cp) { + uint8_t lead = mask8(cp); + if (lead < 0x80) { + return 1; + } else if ((lead >> 5) == 0x6) { + return 2; + } else if ((lead >> 4) == 0xe) { + return 3; + } else if ((lead >> 3) == 0x1e) { + return 4; + } + return 0; +} - uint32_t UTF8Decoder::readNext() - { - return utf8Begin == utf8End ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*utf8Begin++; +inline bool UTF8Decoder::getSequence(uint32_t& cp, int32_t length) { + cp = mask8(cp); + if (length == 1) { + return true; } - - inline int32_t UTF8Decoder::sequenceLength(uint32_t cp) - { - uint8_t lead = mask8(cp); - if (lead < 0x80) - return 1; - else if ((lead >> 5) == 0x6) - return 2; - else if ((lead >> 4) == 0xe) - return 3; - else if ((lead >> 3) == 0x1e) - return 4; - return 0; + uint32_t next = readNext(); + if (next == UNICODE_TERMINATOR) { + return false; } - - inline bool UTF8Decoder::getSequence(uint32_t& cp, int32_t length) - { - cp = mask8(cp); - if (length == 1) - return true; - uint32_t next = readNext(); - if (next == UNICODE_TERMINATOR) - return false; - if (!isTrail(next)) - return false; - if (length == 2) - { - cp = ((cp << 6) & 0x7ff) + (next & 0x3f); - return true; - } - if (length == 3) - cp = ((cp << 12) & 0xffff) + ((mask8(next) << 6) & 0xfff); - else - cp = ((cp << 18) & 0x1fffff) + ((mask8(next) << 12) & 0x3ffff); - next = readNext(); - if (next == UNICODE_TERMINATOR) - return false; - if (!isTrail(next)) - return false; - if (length == 3) - { - cp += next & 0x3f; - return true; - } - cp += (mask8(next) << 6) & 0xfff; - next = readNext(); - if (next == UNICODE_TERMINATOR) - return false; - if (!isTrail(next)) - return false; + if (!isTrail(next)) { + return false; + } + if (length == 2) { + cp = ((cp << 6) & 0x7ff) + (next & 0x3f); + return true; + } + if (length == 3) { + cp = ((cp << 12) & 0xffff) + ((mask8(next) << 6) & 0xfff); + } else { + cp = ((cp << 18) & 0x1fffff) + ((mask8(next) << 12) & 0x3ffff); + } + next = readNext(); + if (next == UNICODE_TERMINATOR) { + return false; + } + if (!isTrail(next)) { + return false; + } + if (length == 3) { cp += next & 0x3f; return true; } + cp += (mask8(next) << 6) & 0xfff; + next = readNext(); + if (next == UNICODE_TERMINATOR) { + return false; + } + if (!isTrail(next)) { + return false; + } + cp += next & 0x3f; + return true; +} - inline bool UTF8Decoder::isValidNext(uint32_t& cp) - { - // Determine the sequence length based on the lead octet - int32_t length = sequenceLength(cp); - if (length < 1 || length > 4) - return false; - - // Now that we have a valid sequence length, get trail octets and calculate the code point - if (!getSequence(cp, length)) - return false; +inline bool UTF8Decoder::isValidNext(uint32_t& cp) { + // Determine the sequence length based on the lead octet + int32_t length = sequenceLength(cp); + if (length < 1 || length > 4) { + return false; + } - // Decoding succeeded, now security checks - return (isValidCodePoint(cp) && !isOverlongSequence(cp, length)); + // Now that we have a valid sequence length, get trail octets and calculate the code point + if (!getSequence(cp, length)) { + return false; } - int32_t UTF8Decoder::utf8to16(wchar_t* unicode, int32_t length) - { - int32_t position = 0; - uint32_t next = readNext(); + // Decoding succeeded, now security checks + return (isValidCodePoint(cp) && !isOverlongSequence(cp, length)); +} - while (next != UNICODE_TERMINATOR) - { - if (!isValidNext(next)) - return 0; - if (next > 0xffff) // make a surrogate pair - { - unicode[position++] = static_cast((next >> 10) + LEAD_OFFSET); - unicode[position++] = static_cast((next & 0x3ff) + TRAIL_SURROGATE_MIN); - } - else - unicode[position++] = static_cast(next); - if (position >= length) - break; - next = readNext(); - } +int32_t UTF8Decoder::utf8to16(wchar_t* unicode, int32_t length) { + int32_t position = 0; + uint32_t next = readNext(); - return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; + while (next != UNICODE_TERMINATOR) { + if (!isValidNext(next)) { + return 0; + } + if (next > 0xffff) { // make a surrogate pair + unicode[position++] = static_cast((next >> 10) + LEAD_OFFSET); + unicode[position++] = static_cast((next & 0x3ff) + TRAIL_SURROGATE_MIN); + } else { + unicode[position++] = static_cast(next); + } + if (position >= length) { + break; + } + next = readNext(); } - int32_t UTF8Decoder::utf8to32(wchar_t* unicode, int32_t length) - { - int32_t position = 0; - uint32_t next = readNext(); + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; +} - while (next != UNICODE_TERMINATOR) - { - if (!isValidNext(next)) - return 0; - unicode[position++] = static_cast(next); - if (position >= length) - break; - next = readNext(); - } +int32_t UTF8Decoder::utf8to32(wchar_t* unicode, int32_t length) { + int32_t position = 0; + uint32_t next = readNext(); - return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; + while (next != UNICODE_TERMINATOR) { + if (!isValidNext(next)) { + return 0; + } + unicode[position++] = static_cast(next); + if (position >= length) { + break; + } + next = readNext(); } - int32_t UTF8Decoder::decode(wchar_t* unicode, int32_t length) - { - #ifdef LPP_UNICODE_CHAR_SIZE_2 - return utf8to16(unicode, length); - #else - return utf8to32(unicode, length); - #endif - } + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; +} - UTF8DecoderStream::UTF8DecoderStream(const ReaderPtr& reader) : UTF8Decoder(NULL, NULL) - { - this->reader = reader; - } +int32_t UTF8Decoder::decode(wchar_t* unicode, int32_t length) { +#ifdef LPP_UNICODE_CHAR_SIZE_2 + return utf8to16(unicode, length); +#else + return utf8to32(unicode, length); +#endif +} - UTF8DecoderStream::~UTF8DecoderStream() - { - } +UTF8DecoderStream::UTF8DecoderStream(const ReaderPtr& reader) : UTF8Decoder(NULL, NULL) { + this->reader = reader; +} - uint32_t UTF8DecoderStream::readNext() - { - int32_t next = reader->read(); - return next == Reader::READER_EOF ? UNICODE_TERMINATOR : (uint32_t)next; - } +UTF8DecoderStream::~UTF8DecoderStream() { +} - UTF16Decoder::UTF16Decoder(const uint16_t* utf16Begin, const uint16_t* utf16End) - { - this->utf16Begin = utf16Begin; - this->utf16End = utf16End; - } +uint32_t UTF8DecoderStream::readNext() { + int32_t next = reader->read(); + return next == Reader::READER_EOF ? UNICODE_TERMINATOR : (uint32_t)next; +} - UTF16Decoder::~UTF16Decoder() - { - } +UTF16Decoder::UTF16Decoder(const uint16_t* utf16Begin, const uint16_t* utf16End) { + this->utf16Begin = utf16Begin; + this->utf16End = utf16End; +} - uint32_t UTF16Decoder::readNext() - { - return utf16Begin == utf16End ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*utf16Begin++; - } +UTF16Decoder::~UTF16Decoder() { +} + +uint32_t UTF16Decoder::readNext() { + return utf16Begin == utf16End ? (uint32_t)UNICODE_TERMINATOR : (uint32_t)*utf16Begin++; +} - int32_t UTF16Decoder::utf16to32(wchar_t* unicode, int32_t length) - { - int32_t position = 0; - uint32_t next = readNext(); - - while (next != UNICODE_TERMINATOR) - { - uint32_t cp = mask16(next); - if (isLeadSurrogate(cp)) - { - next = readNext(); - if (next == UNICODE_TERMINATOR) - return 0; - uint32_t trail_surrogate = mask16(next); - if (!isTrailSurrogate(trail_surrogate)) - return 0; - unicode[position++] = static_cast(((cp - LEAD_SURROGATE_MIN) << 10) + (trail_surrogate - TRAIL_SURROGATE_MIN) + 0x0010000); +int32_t UTF16Decoder::utf16to32(wchar_t* unicode, int32_t length) { + int32_t position = 0; + uint32_t next = readNext(); + + while (next != UNICODE_TERMINATOR) { + uint32_t cp = mask16(next); + if (isLeadSurrogate(cp)) { + next = readNext(); + if (next == UNICODE_TERMINATOR) { + return 0; } - else if (isTrailSurrogate(cp)) + uint32_t trail_surrogate = mask16(next); + if (!isTrailSurrogate(trail_surrogate)) { return 0; - else - unicode[position++] = static_cast(cp); - if (position >= length) - break; - next = readNext(); + } + unicode[position++] = static_cast(((cp - LEAD_SURROGATE_MIN) << 10) + (trail_surrogate - TRAIL_SURROGATE_MIN) + 0x0010000); + } else if (isTrailSurrogate(cp)) { + return 0; + } else { + unicode[position++] = static_cast(cp); } - - return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; + if (position >= length) { + break; + } + next = readNext(); } - int32_t UTF16Decoder::utf16to16(wchar_t* unicode, int32_t length) - { - int32_t position = 0; - uint32_t next = readNext(); + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; +} + +int32_t UTF16Decoder::utf16to16(wchar_t* unicode, int32_t length) { + int32_t position = 0; + uint32_t next = readNext(); - while (next != UNICODE_TERMINATOR) - { - unicode[position++] = static_cast(next); - if (position >= length) - break; - next = readNext(); + while (next != UNICODE_TERMINATOR) { + unicode[position++] = static_cast(next); + if (position >= length) { + break; } - - return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; + next = readNext(); } - int32_t UTF16Decoder::decode(wchar_t* unicode, int32_t length) - { - #ifdef LPP_UNICODE_CHAR_SIZE_2 - return utf16to16(unicode, length); - #else - return utf16to32(unicode, length); - #endif - } + return (position == 0 && next == UNICODE_TERMINATOR) ? Reader::READER_EOF : position; +} + +int32_t UTF16Decoder::decode(wchar_t* unicode, int32_t length) { +#ifdef LPP_UNICODE_CHAR_SIZE_2 + return utf16to16(unicode, length); +#else + return utf16to32(unicode, length); +#endif +} + } diff --git a/src/core/util/UnicodeUtils.cpp b/src/core/util/UnicodeUtils.cpp index d66b8f83..f416ecf3 100644 --- a/src/core/util/UnicodeUtils.cpp +++ b/src/core/util/UnicodeUtils.cpp @@ -9,67 +9,55 @@ #include "UnicodeUtils.h" #include "unicode/guniprop.h" -namespace Lucene -{ - UnicodeUtil::~UnicodeUtil() - { - } - - bool UnicodeUtil::isAlnum(wchar_t c) - { - return g_unichar_isalnum(c); - } - - bool UnicodeUtil::isAlpha(wchar_t c) - { - return g_unichar_isalpha(c); - } - - bool UnicodeUtil::isDigit(wchar_t c) - { - return g_unichar_isdigit(c); - } - - bool UnicodeUtil::isSpace(wchar_t c) - { - return g_unichar_isspace(c); - } - - bool UnicodeUtil::isUpper(wchar_t c) - { - return g_unichar_isupper(c); - } - - bool UnicodeUtil::isLower(wchar_t c) - { - return g_unichar_islower(c); - } - - bool UnicodeUtil::isOther(wchar_t c) - { - return (g_unichar_type(c) == G_UNICODE_OTHER_LETTER); - } - - bool UnicodeUtil::isNonSpacing(wchar_t c) - { - return (g_unichar_type(c) == G_UNICODE_NON_SPACING_MARK); - } - - wchar_t UnicodeUtil::toUpper(wchar_t c) - { - return (wchar_t)g_unichar_toupper(c); - } - - wchar_t UnicodeUtil::toLower(wchar_t c) - { - return (wchar_t)g_unichar_tolower(c); - } - - UTF8Result::~UTF8Result() - { - } - - UnicodeResult::~UnicodeResult() - { - } +namespace Lucene { + +UnicodeUtil::~UnicodeUtil() { +} + +bool UnicodeUtil::isAlnum(wchar_t c) { + return g_unichar_isalnum(c); +} + +bool UnicodeUtil::isAlpha(wchar_t c) { + return g_unichar_isalpha(c); +} + +bool UnicodeUtil::isDigit(wchar_t c) { + return g_unichar_isdigit(c); +} + +bool UnicodeUtil::isSpace(wchar_t c) { + return g_unichar_isspace(c); +} + +bool UnicodeUtil::isUpper(wchar_t c) { + return g_unichar_isupper(c); +} + +bool UnicodeUtil::isLower(wchar_t c) { + return g_unichar_islower(c); +} + +bool UnicodeUtil::isOther(wchar_t c) { + return (g_unichar_type(c) == G_UNICODE_OTHER_LETTER); +} + +bool UnicodeUtil::isNonSpacing(wchar_t c) { + return (g_unichar_type(c) == G_UNICODE_NON_SPACING_MARK); +} + +wchar_t UnicodeUtil::toUpper(wchar_t c) { + return (wchar_t)g_unichar_toupper(c); +} + +wchar_t UnicodeUtil::toLower(wchar_t c) { + return (wchar_t)g_unichar_tolower(c); +} + +UTF8Result::~UTF8Result() { +} + +UnicodeResult::~UnicodeResult() { +} + } diff --git a/src/core/util/md5/md5.h b/src/core/util/md5/md5.h index 698c995d..fb751737 100644 --- a/src/core/util/md5/md5.h +++ b/src/core/util/md5/md5.h @@ -27,7 +27,7 @@ This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at - http://www.ietf.org/rfc/rfc1321.txt + http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being @@ -38,12 +38,12 @@ that follows (in reverse chronological order): 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . + added conditionalization for C++ compilation from Martin + Purschke . 1999-05-03 lpd Original version. */ @@ -65,24 +65,24 @@ typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; #ifdef __cplusplus -extern "C" +extern "C" { #endif /* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); +void md5_init(md5_state_t* pms); /* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); +void md5_append(md5_state_t* pms, const md5_byte_t* data, int nbytes); /* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); +void md5_finish(md5_state_t* pms, md5_byte_t digest[16]); #ifdef __cplusplus } /* end extern "C" */ diff --git a/src/core/util/unicode/gunichartables.h b/src/core/util/unicode/gunichartables.h index adc5a55d..cc5d00f9 100644 --- a/src/core/util/unicode/gunichartables.h +++ b/src/core/util/unicode/gunichartables.h @@ -15,13046 +15,13168 @@ #define G_UNICODE_LAST_PAGE_PART1 762 static const char type_data[][256] = { - { /* page 0, index 0 */ - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, - G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_FORMAT, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER - }, - { /* page 1, index 1 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER - }, - { /* page 2, index 2 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL - }, - { /* page 3, index 3 */ - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER - }, - { /* page 4, index 4 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER - }, - { /* page 5, index 5 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 6, index 6 */ - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_FORMAT, G_UNICODE_ENCLOSING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_LETTER - }, - { /* page 7, index 7 */ - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 9, index 8 */ - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 10, index 9 */ - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 11, index 10 */ - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 12, index 11 */ - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 13, index 12 */ - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 14, index 13 */ - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 15, index 14 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 16, index 15 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_COMBINING_MARK, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 17, index 16 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 18, index 17 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER - }, - { /* page 19, index 18 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 20, index 19 */ - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER - }, - { /* page 22, index 20 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 23, index 21 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 24, index 22 */ - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_UNASSIGNED, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 25, index 23 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL - }, - { /* page 26, index 24 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 27, index 25 */ - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 28, index 26 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 29, index 27 */ - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK - }, - { /* page 30, index 28 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER - }, - { /* page 31, index 29 */ - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED - }, - { /* page 32, index 30 */ - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_LINE_SEPARATOR, G_UNICODE_PARAGRAPH_SEPARATOR, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, - G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK, - G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 33, index 31 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL - }, - { /* page 35, index 32 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 36, index 33 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER - }, - { /* page 37, index 34 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL - }, - { /* page 38, index 35 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 39, index 36 */ - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL - }, - { /* page 41, index 37 */ - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL - }, - { /* page 43, index 38 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 44, index 39 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION - }, - { /* page 45, index 40 */ - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK - }, - { /* page 46, index 41 */ - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, - G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 47, index 42 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 48, index 43 */ - G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER - }, - { /* page 49, index 44 */ - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER - }, - { /* page 50, index 45 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED - }, - { /* page 77, index 46 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL - }, - { /* page 159, index 47 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 160, index 48 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER - }, - { /* page 164, index 49 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 166, index 50 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, - G_UNICODE_ENCLOSING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 167, index 51 */ - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER - }, - { /* page 168, index 52 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 169, index 53 */ - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 170, index 54 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 215, index 55 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 250, index 56 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 251, index 57 */ - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER - }, - { /* page 253, index 58 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 254, index 59 */ - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, - G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_DASH_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT - }, - { /* page 255, index 60 */ - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 256, index 61 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 257, index 62 */ - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 258, index 63 */ - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 259, index 64 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 260, index 65 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 264, index 66 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 265, index 67 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 266, index 68 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 291, index 69 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 292, index 70 */ - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, - G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 464, index 71 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 465, index 72 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, - G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 466, index 73 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 467, index 74 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 468, index 75 */ - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER - }, - { /* page 469, index 76 */ - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER - }, - { /* page 470, index 77 */ - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER - }, - { /* page 471, index 78 */ - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_DECIMAL_NUMBER - }, - { /* page 496, index 79 */ - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, - G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 678, index 80 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 762, index 81 */ - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 3584, index 82 */ - G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED - }, - { /* page 3585, index 83 */ - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 4095, index 84 */ - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - }, - { /* page 4351, index 85 */ - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, - G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, - G_UNICODE_UNASSIGNED - } + { + /* page 0, index 0 */ + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_FORMAT, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { + /* page 1, index 1 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { + /* page 2, index 2 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL + }, + { + /* page 3, index 3 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER + }, + { + /* page 4, index 4 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER + }, + { + /* page 5, index 5 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 6, index 6 */ + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_FORMAT, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_LETTER + }, + { + /* page 7, index 7 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 9, index 8 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 10, index 9 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 11, index 10 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 12, index 11 */ + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 13, index 12 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 14, index 13 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 15, index 14 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 16, index 15 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 17, index 16 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 18, index 17 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { + /* page 19, index 18 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 20, index 19 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { + /* page 22, index 20 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 23, index 21 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 24, index 22 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 25, index 23 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL + }, + { + /* page 26, index 24 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 27, index 25 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 28, index 26 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 29, index 27 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK + }, + { + /* page 30, index 28 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER + }, + { + /* page 31, index 29 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED + }, + { + /* page 32, index 30 */ + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_LINE_SEPARATOR, G_UNICODE_PARAGRAPH_SEPARATOR, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 33, index 31 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL + }, + { + /* page 35, index 32 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 36, index 33 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER + }, + { + /* page 37, index 34 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { + /* page 38, index 35 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 39, index 36 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { + /* page 41, index 37 */ + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { + /* page 43, index 38 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 44, index 39 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION + }, + { + /* page 45, index 40 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK + }, + { + /* page 46, index 41 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 47, index 42 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 48, index 43 */ + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { + /* page 49, index 44 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { + /* page 50, index 45 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED + }, + { + /* page 77, index 46 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL + }, + { + /* page 159, index 47 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 160, index 48 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { + /* page 164, index 49 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 166, index 50 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 167, index 51 */ + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { + /* page 168, index 52 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 169, index 53 */ + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 170, index 54 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 215, index 55 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 250, index 56 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 251, index 57 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { + /* page 253, index 58 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 254, index 59 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT + }, + { + /* page 255, index 60 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 256, index 61 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 257, index 62 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 258, index 63 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 259, index 64 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 260, index 65 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 264, index 66 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 265, index 67 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 266, index 68 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 291, index 69 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 292, index 70 */ + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 464, index 71 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 465, index 72 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 466, index 73 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 467, index 74 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 468, index 75 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { + /* page 469, index 76 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { + /* page 470, index 77 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { + /* page 471, index 78 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER + }, + { + /* page 496, index 79 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 678, index 80 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 762, index 81 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 3584, index 82 */ + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { + /* page 3585, index 83 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 4095, index 84 */ + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { + /* page 4351, index 85 */ + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + } }; /* U+0000 through U+2FAFF */ static const int16_t type_table_part1[763] = { - 0 /* page 0 */, - 1 /* page 1 */, - 2 /* page 2 */, - 3 /* page 3 */, - 4 /* page 4 */, - 5 /* page 5 */, - 6 /* page 6 */, - 7 /* page 7 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - 8 /* page 9 */, - 9 /* page 10 */, - 10 /* page 11 */, - 11 /* page 12 */, - 12 /* page 13 */, - 13 /* page 14 */, - 14 /* page 15 */, - 15 /* page 16 */, - 16 /* page 17 */, - 17 /* page 18 */, - 18 /* page 19 */, - 19 /* page 20 */, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 20 /* page 22 */, - 21 /* page 23 */, - 22 /* page 24 */, - 23 /* page 25 */, - 24 /* page 26 */, - 25 /* page 27 */, - 26 /* page 28 */, - 27 /* page 29 */, - 28 /* page 30 */, - 29 /* page 31 */, - 30 /* page 32 */, - 31 /* page 33 */, - G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, - 32 /* page 35 */, - 33 /* page 36 */, - 34 /* page 37 */, - 35 /* page 38 */, - 36 /* page 39 */, - G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, - 37 /* page 41 */, - G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, - 38 /* page 43 */, - 39 /* page 44 */, - 40 /* page 45 */, - 41 /* page 46 */, - 42 /* page 47 */, - 43 /* page 48 */, - 44 /* page 49 */, - 45 /* page 50 */, - G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 46 /* page 77 */, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 47 /* page 159 */, - 48 /* page 160 */, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 49 /* page 164 */, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 50 /* page 166 */, - 51 /* page 167 */, - 52 /* page 168 */, - 53 /* page 169 */, - 54 /* page 170 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 55 /* page 215 */, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 56 /* page 250 */, - 57 /* page 251 */, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 58 /* page 253 */, - 59 /* page 254 */, - 60 /* page 255 */, - 61 /* page 256 */, - 62 /* page 257 */, - 63 /* page 258 */, - 64 /* page 259 */, - 65 /* page 260 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - 66 /* page 264 */, - 67 /* page 265 */, - 68 /* page 266 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 69 /* page 291 */, - 70 /* page 292 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - 71 /* page 464 */, - 72 /* page 465 */, - 73 /* page 466 */, - 74 /* page 467 */, - 75 /* page 468 */, - 76 /* page 469 */, - 77 /* page 470 */, - 78 /* page 471 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - 79 /* page 496 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 80 /* page 678 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, - 81 /* page 762 */ + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 5 /* page 5 */, + 6 /* page 6 */, + 7 /* page 7 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 8 /* page 9 */, + 9 /* page 10 */, + 10 /* page 11 */, + 11 /* page 12 */, + 12 /* page 13 */, + 13 /* page 14 */, + 14 /* page 15 */, + 15 /* page 16 */, + 16 /* page 17 */, + 17 /* page 18 */, + 18 /* page 19 */, + 19 /* page 20 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 20 /* page 22 */, + 21 /* page 23 */, + 22 /* page 24 */, + 23 /* page 25 */, + 24 /* page 26 */, + 25 /* page 27 */, + 26 /* page 28 */, + 27 /* page 29 */, + 28 /* page 30 */, + 29 /* page 31 */, + 30 /* page 32 */, + 31 /* page 33 */, + G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 32 /* page 35 */, + 33 /* page 36 */, + 34 /* page 37 */, + 35 /* page 38 */, + 36 /* page 39 */, + G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 37 /* page 41 */, + G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 38 /* page 43 */, + 39 /* page 44 */, + 40 /* page 45 */, + 41 /* page 46 */, + 42 /* page 47 */, + 43 /* page 48 */, + 44 /* page 49 */, + 45 /* page 50 */, + G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 46 /* page 77 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 47 /* page 159 */, + 48 /* page 160 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 49 /* page 164 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 50 /* page 166 */, + 51 /* page 167 */, + 52 /* page 168 */, + 53 /* page 169 */, + 54 /* page 170 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 55 /* page 215 */, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 56 /* page 250 */, + 57 /* page 251 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 58 /* page 253 */, + 59 /* page 254 */, + 60 /* page 255 */, + 61 /* page 256 */, + 62 /* page 257 */, + 63 /* page 258 */, + 64 /* page 259 */, + 65 /* page 260 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 66 /* page 264 */, + 67 /* page 265 */, + 68 /* page 266 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 69 /* page 291 */, + 70 /* page 292 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 71 /* page 464 */, + 72 /* page 465 */, + 73 /* page 466 */, + 74 /* page 467 */, + 75 /* page 468 */, + 76 /* page 469 */, + 77 /* page 470 */, + 78 /* page 471 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 79 /* page 496 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 80 /* page 678 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 81 /* page 762 */ }; /* U+E0000 through U+10FFFF */ static const int16_t type_table_part2[768] = { - 82 /* page 3584 */, - 83 /* page 3585 */, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - 84 /* page 4095 */, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, - 85 /* page 4351 */ + 82 /* page 3584 */, + 83 /* page 3585 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + 84 /* page 4095 */, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + 85 /* page 4351 */ }; static const gunichar attr_data[][256] = { - { /* page 0, index 0 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, - 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, - 0x007a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0042, - 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, - 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, - 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x039c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, - 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, - 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0000, - 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x1000000, - 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, - 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, - 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0000, 0x00d8, 0x00d9, 0x00da, - 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178 - }, - { /* page 1, index 1 */ - 0x0101, 0x0100, 0x0103, 0x0102, 0x0105, 0x0104, 0x0107, 0x0106, 0x0109, - 0x0108, 0x010b, 0x010a, 0x010d, 0x010c, 0x010f, 0x010e, 0x0111, 0x0110, - 0x0113, 0x0112, 0x0115, 0x0114, 0x0117, 0x0116, 0x0119, 0x0118, 0x011b, - 0x011a, 0x011d, 0x011c, 0x011f, 0x011e, 0x0121, 0x0120, 0x0123, 0x0122, - 0x0125, 0x0124, 0x0127, 0x0126, 0x0129, 0x0128, 0x012b, 0x012a, 0x012d, - 0x012c, 0x012f, 0x012e, 0x1000007, 0x0049, 0x0133, 0x0132, 0x0135, - 0x0134, 0x0137, 0x0136, 0x0000, 0x013a, 0x0139, 0x013c, 0x013b, 0x013e, - 0x013d, 0x0140, 0x013f, 0x0142, 0x0141, 0x0144, 0x0143, 0x0146, 0x0145, - 0x0148, 0x0147, 0x1000086, 0x014b, 0x014a, 0x014d, 0x014c, 0x014f, - 0x014e, 0x0151, 0x0150, 0x0153, 0x0152, 0x0155, 0x0154, 0x0157, 0x0156, - 0x0159, 0x0158, 0x015b, 0x015a, 0x015d, 0x015c, 0x015f, 0x015e, 0x0161, - 0x0160, 0x0163, 0x0162, 0x0165, 0x0164, 0x0167, 0x0166, 0x0169, 0x0168, - 0x016b, 0x016a, 0x016d, 0x016c, 0x016f, 0x016e, 0x0171, 0x0170, 0x0173, - 0x0172, 0x0175, 0x0174, 0x0177, 0x0176, 0x00ff, 0x017a, 0x0179, 0x017c, - 0x017b, 0x017e, 0x017d, 0x0053, 0x0243, 0x0253, 0x0183, 0x0182, 0x0185, - 0x0184, 0x0254, 0x0188, 0x0187, 0x0256, 0x0257, 0x018c, 0x018b, 0x0000, - 0x01dd, 0x0259, 0x025b, 0x0192, 0x0191, 0x0260, 0x0263, 0x01f6, 0x0269, - 0x0268, 0x0199, 0x0198, 0x023d, 0x0000, 0x026f, 0x0272, 0x0220, 0x0275, - 0x01a1, 0x01a0, 0x01a3, 0x01a2, 0x01a5, 0x01a4, 0x0280, 0x01a8, 0x01a7, - 0x0283, 0x0000, 0x0000, 0x01ad, 0x01ac, 0x0288, 0x01b0, 0x01af, 0x028a, - 0x028b, 0x01b4, 0x01b3, 0x01b6, 0x01b5, 0x0292, 0x01b9, 0x01b8, 0x0000, - 0x0000, 0x01bd, 0x01bc, 0x0000, 0x01f7, 0x0000, 0x0000, 0x0000, 0x0000, - 0x01c6, 0x0000, 0x01c4, 0x01c9, 0x0000, 0x01c7, 0x01cc, 0x0000, 0x01ca, - 0x01ce, 0x01cd, 0x01d0, 0x01cf, 0x01d2, 0x01d1, 0x01d4, 0x01d3, 0x01d6, - 0x01d5, 0x01d8, 0x01d7, 0x01da, 0x01d9, 0x01dc, 0x01db, 0x018e, 0x01df, - 0x01de, 0x01e1, 0x01e0, 0x01e3, 0x01e2, 0x01e5, 0x01e4, 0x01e7, 0x01e6, - 0x01e9, 0x01e8, 0x01eb, 0x01ea, 0x01ed, 0x01ec, 0x01ef, 0x01ee, - 0x10000ad, 0x01f3, 0x0000, 0x01f1, 0x01f5, 0x01f4, 0x0195, 0x01bf, - 0x01f9, 0x01f8, 0x01fb, 0x01fa, 0x01fd, 0x01fc, 0x01ff, 0x01fe - }, - { /* page 2, index 2 */ - 0x0201, 0x0200, 0x0203, 0x0202, 0x0205, 0x0204, 0x0207, 0x0206, 0x0209, - 0x0208, 0x020b, 0x020a, 0x020d, 0x020c, 0x020f, 0x020e, 0x0211, 0x0210, - 0x0213, 0x0212, 0x0215, 0x0214, 0x0217, 0x0216, 0x0219, 0x0218, 0x021b, - 0x021a, 0x021d, 0x021c, 0x021f, 0x021e, 0x019e, 0x0000, 0x0223, 0x0222, - 0x0225, 0x0224, 0x0227, 0x0226, 0x0229, 0x0228, 0x022b, 0x022a, 0x022d, - 0x022c, 0x022f, 0x022e, 0x0231, 0x0230, 0x0233, 0x0232, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2c65, 0x023c, 0x023b, 0x019a, 0x2c66, - 0x0000, 0x0000, 0x0242, 0x0241, 0x0180, 0x0289, 0x028c, 0x0247, 0x0246, - 0x0249, 0x0248, 0x024b, 0x024a, 0x024d, 0x024c, 0x024f, 0x024e, 0x2c6f, - 0x2c6d, 0x0000, 0x0181, 0x0186, 0x0000, 0x0189, 0x018a, 0x0000, 0x018f, - 0x0000, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0193, 0x0000, 0x0000, - 0x0194, 0x0000, 0x0000, 0x0000, 0x0000, 0x0197, 0x0196, 0x0000, 0x2c62, - 0x0000, 0x0000, 0x0000, 0x019c, 0x0000, 0x2c6e, 0x019d, 0x0000, 0x0000, - 0x019f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2c64, - 0x0000, 0x0000, 0x01a6, 0x0000, 0x0000, 0x01a9, 0x0000, 0x0000, 0x0000, - 0x0000, 0x01ae, 0x0244, 0x01b1, 0x01b2, 0x0245, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x01b7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 3, index 3 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0371, 0x0370, 0x0373, 0x0372, 0x0000, - 0x0000, 0x0377, 0x0376, 0x0000, 0x0000, 0x0000, 0x03fd, 0x03fe, 0x03ff, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03ac, - 0x0000, 0x03ad, 0x03ae, 0x03af, 0x0000, 0x03cc, 0x0000, 0x03cd, 0x03ce, - 0x100008f, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, - 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, - 0x03c1, 0x0000, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, - 0x03ca, 0x03cb, 0x0386, 0x0388, 0x0389, 0x038a, 0x100009e, 0x0391, - 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, - 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a3, - 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x038c, - 0x038e, 0x038f, 0x03d7, 0x0392, 0x0398, 0x0000, 0x0000, 0x0000, 0x03a6, - 0x03a0, 0x03cf, 0x03d9, 0x03d8, 0x03db, 0x03da, 0x03dd, 0x03dc, 0x03df, - 0x03de, 0x03e1, 0x03e0, 0x03e3, 0x03e2, 0x03e5, 0x03e4, 0x03e7, 0x03e6, - 0x03e9, 0x03e8, 0x03eb, 0x03ea, 0x03ed, 0x03ec, 0x03ef, 0x03ee, 0x039a, - 0x03a1, 0x03f9, 0x0000, 0x03b8, 0x0395, 0x0000, 0x03f8, 0x03f7, 0x03f2, - 0x03fb, 0x03fa, 0x0000, 0x037b, 0x037c, 0x037d - }, - { /* page 4, index 4 */ - 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, - 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 0x0430, 0x0431, - 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, - 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, - 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, - 0x044d, 0x044e, 0x044f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, - 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, - 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, - 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0400, - 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, - 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, 0x0461, 0x0460, 0x0463, - 0x0462, 0x0465, 0x0464, 0x0467, 0x0466, 0x0469, 0x0468, 0x046b, 0x046a, - 0x046d, 0x046c, 0x046f, 0x046e, 0x0471, 0x0470, 0x0473, 0x0472, 0x0475, - 0x0474, 0x0477, 0x0476, 0x0479, 0x0478, 0x047b, 0x047a, 0x047d, 0x047c, - 0x047f, 0x047e, 0x0481, 0x0480, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x048b, 0x048a, 0x048d, 0x048c, 0x048f, 0x048e, - 0x0491, 0x0490, 0x0493, 0x0492, 0x0495, 0x0494, 0x0497, 0x0496, 0x0499, - 0x0498, 0x049b, 0x049a, 0x049d, 0x049c, 0x049f, 0x049e, 0x04a1, 0x04a0, - 0x04a3, 0x04a2, 0x04a5, 0x04a4, 0x04a7, 0x04a6, 0x04a9, 0x04a8, 0x04ab, - 0x04aa, 0x04ad, 0x04ac, 0x04af, 0x04ae, 0x04b1, 0x04b0, 0x04b3, 0x04b2, - 0x04b5, 0x04b4, 0x04b7, 0x04b6, 0x04b9, 0x04b8, 0x04bb, 0x04ba, 0x04bd, - 0x04bc, 0x04bf, 0x04be, 0x04cf, 0x04c2, 0x04c1, 0x04c4, 0x04c3, 0x04c6, - 0x04c5, 0x04c8, 0x04c7, 0x04ca, 0x04c9, 0x04cc, 0x04cb, 0x04ce, 0x04cd, - 0x04c0, 0x04d1, 0x04d0, 0x04d3, 0x04d2, 0x04d5, 0x04d4, 0x04d7, 0x04d6, - 0x04d9, 0x04d8, 0x04db, 0x04da, 0x04dd, 0x04dc, 0x04df, 0x04de, 0x04e1, - 0x04e0, 0x04e3, 0x04e2, 0x04e5, 0x04e4, 0x04e7, 0x04e6, 0x04e9, 0x04e8, - 0x04eb, 0x04ea, 0x04ed, 0x04ec, 0x04ef, 0x04ee, 0x04f1, 0x04f0, 0x04f3, - 0x04f2, 0x04f5, 0x04f4, 0x04f7, 0x04f6, 0x04f9, 0x04f8, 0x04fb, 0x04fa, - 0x04fd, 0x04fc, 0x04ff, 0x04fe - }, - { /* page 5, index 5 */ - 0x0501, 0x0500, 0x0503, 0x0502, 0x0505, 0x0504, 0x0507, 0x0506, 0x0509, - 0x0508, 0x050b, 0x050a, 0x050d, 0x050c, 0x050f, 0x050e, 0x0511, 0x0510, - 0x0513, 0x0512, 0x0515, 0x0514, 0x0517, 0x0516, 0x0519, 0x0518, 0x051b, - 0x051a, 0x051d, 0x051c, 0x051f, 0x051e, 0x0521, 0x0520, 0x0523, 0x0522, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, - 0x0566, 0x0567, 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, - 0x056f, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, - 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 0x0580, - 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0531, 0x0532, - 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 0x0538, 0x0539, 0x053a, 0x053b, - 0x053c, 0x053d, 0x053e, 0x053f, 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, - 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d, - 0x054e, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, - 0x1000044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 6, index 6 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 7, index 7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 9, index 8 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 10, index 9 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 11, index 10 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 12, index 11 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 13, index 12 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 14, index 13 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 15, index 14 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 16, index 15 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, - 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d00, 0x2d01, - 0x2d02, 0x2d03, 0x2d04, 0x2d05, 0x2d06, 0x2d07, 0x2d08, 0x2d09, 0x2d0a, - 0x2d0b, 0x2d0c, 0x2d0d, 0x2d0e, 0x2d0f, 0x2d10, 0x2d11, 0x2d12, 0x2d13, - 0x2d14, 0x2d15, 0x2d16, 0x2d17, 0x2d18, 0x2d19, 0x2d1a, 0x2d1b, 0x2d1c, - 0x2d1d, 0x2d1e, 0x2d1f, 0x2d20, 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 23, index 16 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 24, index 17 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, - 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 25, index 18 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, - 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 27, index 19 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 28, index 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 29, index 21 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xa77d, 0x0000, 0x0000, 0x0000, 0x2c63, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 30, index 22 */ - 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06, 0x1e09, - 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e, 0x1e11, 0x1e10, - 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16, 0x1e19, 0x1e18, 0x1e1b, - 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e, 0x1e21, 0x1e20, 0x1e23, 0x1e22, - 0x1e25, 0x1e24, 0x1e27, 0x1e26, 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, - 0x1e2c, 0x1e2f, 0x1e2e, 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, - 0x1e37, 0x1e36, 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, - 0x1e3e, 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46, - 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e, 0x1e51, - 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56, 0x1e59, 0x1e58, - 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e, 0x1e61, 0x1e60, 0x1e63, - 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66, 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, - 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e, 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, - 0x1e74, 0x1e77, 0x1e76, 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, - 0x1e7f, 0x1e7e, 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, - 0x1e86, 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e, - 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0x10000b6, 0x10000bf, - 0x10000c8, 0x10000d1, 0x10000da, 0x1e60, 0x0000, 0x0000, 0x00df, 0x0000, - 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6, 0x1ea9, - 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae, 0x1eb1, 0x1eb0, - 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6, 0x1eb9, 0x1eb8, 0x1ebb, - 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe, 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, - 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6, 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, - 0x1ecc, 0x1ecf, 0x1ece, 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, - 0x1ed7, 0x1ed6, 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, - 0x1ede, 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6, - 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee, 0x1ef1, - 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6, 0x1ef9, 0x1ef8, - 0x1efb, 0x1efa, 0x1efd, 0x1efc, 0x1eff, 0x1efe - }, - { /* page 31, index 23 */ - 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f00, - 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f18, 0x1f19, - 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x0000, 0x0000, 0x1f10, 0x1f11, 0x1f12, - 0x1f13, 0x1f14, 0x1f15, 0x0000, 0x0000, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, - 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, - 0x1f25, 0x1f26, 0x1f27, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, - 0x1f3e, 0x1f3f, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, - 0x1f37, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x0000, 0x0000, - 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x0000, 0x0000, - 0x10000e3, 0x1f59, 0x10000ee, 0x1f5b, 0x10000fd, 0x1f5d, 0x100010c, - 0x1f5f, 0x0000, 0x1f51, 0x0000, 0x1f53, 0x0000, 0x1f55, 0x0000, 0x1f57, - 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1f60, - 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1fba, 0x1fbb, - 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, - 0x1feb, 0x1ffa, 0x1ffb, 0x0000, 0x0000, 0x10001b7, 0x10001c4, 0x10001d1, - 0x10001de, 0x10001eb, 0x10001f8, 0x1000205, 0x1000212, 0x100021f, - 0x1000229, 0x1000233, 0x100023d, 0x1000247, 0x1000251, 0x100025b, - 0x1000265, 0x100026f, 0x100027c, 0x1000289, 0x1000296, 0x10002a3, - 0x10002b0, 0x10002bd, 0x10002ca, 0x10002d7, 0x10002e1, 0x10002eb, - 0x10002f5, 0x10002ff, 0x1000309, 0x1000313, 0x100031d, 0x1000327, - 0x1000334, 0x1000341, 0x100034e, 0x100035b, 0x1000368, 0x1000375, - 0x1000382, 0x100038f, 0x1000399, 0x10003a3, 0x10003ad, 0x10003b7, - 0x10003c1, 0x10003cb, 0x10003d5, 0x1fb8, 0x1fb9, 0x100041e, 0x10003df, - 0x100042b, 0x0000, 0x100011b, 0x1000466, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, - 0x10003eb, 0x0000, 0x0399, 0x0000, 0x0000, 0x0000, 0x1000436, 0x10003f4, - 0x1000443, 0x0000, 0x1000126, 0x1000475, 0x1f72, 0x1f73, 0x1f74, 0x1f75, - 0x1000400, 0x0000, 0x0000, 0x0000, 0x1fd8, 0x1fd9, 0x1000131, 0x1000140, - 0x0000, 0x0000, 0x100014f, 0x100015a, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, - 0x0000, 0x0000, 0x0000, 0x0000, 0x1fe8, 0x1fe9, 0x1000169, 0x1000178, - 0x1000187, 0x1fec, 0x1000192, 0x100019d, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, - 0x1fe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100044e, 0x1000409, - 0x100045b, 0x0000, 0x10001ac, 0x1000484, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, - 0x1000415, 0x0000, 0x0000, 0x0000 - }, - { /* page 33, index 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x03c9, 0x0000, 0x0000, 0x0000, 0x006b, 0x00e5, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x214e, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2132, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2184, 0x2183, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 44, index 25 */ - 0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, 0x2c38, - 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, 0x2c40, 0x2c41, - 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2c48, 0x2c49, 0x2c4a, - 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c50, 0x2c51, 0x2c52, 0x2c53, - 0x2c54, 0x2c55, 0x2c56, 0x2c57, 0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, - 0x2c5d, 0x2c5e, 0x0000, 0x2c00, 0x2c01, 0x2c02, 0x2c03, 0x2c04, 0x2c05, - 0x2c06, 0x2c07, 0x2c08, 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, - 0x2c0f, 0x2c10, 0x2c11, 0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16, 0x2c17, - 0x2c18, 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e, 0x2c1f, 0x2c20, - 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, 0x2c28, 0x2c29, - 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x0000, 0x2c61, 0x2c60, 0x026b, - 0x1d7d, 0x027d, 0x023a, 0x023e, 0x2c68, 0x2c67, 0x2c6a, 0x2c69, 0x2c6c, - 0x2c6b, 0x0251, 0x0271, 0x0250, 0x0000, 0x0000, 0x2c73, 0x2c72, 0x0000, - 0x2c76, 0x2c75, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2c81, 0x2c80, 0x2c83, 0x2c82, 0x2c85, 0x2c84, 0x2c87, - 0x2c86, 0x2c89, 0x2c88, 0x2c8b, 0x2c8a, 0x2c8d, 0x2c8c, 0x2c8f, 0x2c8e, - 0x2c91, 0x2c90, 0x2c93, 0x2c92, 0x2c95, 0x2c94, 0x2c97, 0x2c96, 0x2c99, - 0x2c98, 0x2c9b, 0x2c9a, 0x2c9d, 0x2c9c, 0x2c9f, 0x2c9e, 0x2ca1, 0x2ca0, - 0x2ca3, 0x2ca2, 0x2ca5, 0x2ca4, 0x2ca7, 0x2ca6, 0x2ca9, 0x2ca8, 0x2cab, - 0x2caa, 0x2cad, 0x2cac, 0x2caf, 0x2cae, 0x2cb1, 0x2cb0, 0x2cb3, 0x2cb2, - 0x2cb5, 0x2cb4, 0x2cb7, 0x2cb6, 0x2cb9, 0x2cb8, 0x2cbb, 0x2cba, 0x2cbd, - 0x2cbc, 0x2cbf, 0x2cbe, 0x2cc1, 0x2cc0, 0x2cc3, 0x2cc2, 0x2cc5, 0x2cc4, - 0x2cc7, 0x2cc6, 0x2cc9, 0x2cc8, 0x2ccb, 0x2cca, 0x2ccd, 0x2ccc, 0x2ccf, - 0x2cce, 0x2cd1, 0x2cd0, 0x2cd3, 0x2cd2, 0x2cd5, 0x2cd4, 0x2cd7, 0x2cd6, - 0x2cd9, 0x2cd8, 0x2cdb, 0x2cda, 0x2cdd, 0x2cdc, 0x2cdf, 0x2cde, 0x2ce1, - 0x2ce0, 0x2ce3, 0x2ce2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 45, index 26 */ - 0x10a0, 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, - 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, 0x10b1, - 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10ba, - 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 0x10c0, 0x10c1, 0x10c2, 0x10c3, - 0x10c4, 0x10c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 166, index 27 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xa641, 0xa640, 0xa643, 0xa642, 0xa645, 0xa644, 0xa647, 0xa646, - 0xa649, 0xa648, 0xa64b, 0xa64a, 0xa64d, 0xa64c, 0xa64f, 0xa64e, 0xa651, - 0xa650, 0xa653, 0xa652, 0xa655, 0xa654, 0xa657, 0xa656, 0xa659, 0xa658, - 0xa65b, 0xa65a, 0xa65d, 0xa65c, 0xa65f, 0xa65e, 0x0000, 0x0000, 0xa663, - 0xa662, 0xa665, 0xa664, 0xa667, 0xa666, 0xa669, 0xa668, 0xa66b, 0xa66a, - 0xa66d, 0xa66c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xa681, 0xa680, 0xa683, 0xa682, 0xa685, 0xa684, 0xa687, - 0xa686, 0xa689, 0xa688, 0xa68b, 0xa68a, 0xa68d, 0xa68c, 0xa68f, 0xa68e, - 0xa691, 0xa690, 0xa693, 0xa692, 0xa695, 0xa694, 0xa697, 0xa696, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 167, index 28 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa723, 0xa722, - 0xa725, 0xa724, 0xa727, 0xa726, 0xa729, 0xa728, 0xa72b, 0xa72a, 0xa72d, - 0xa72c, 0xa72f, 0xa72e, 0x0000, 0x0000, 0xa733, 0xa732, 0xa735, 0xa734, - 0xa737, 0xa736, 0xa739, 0xa738, 0xa73b, 0xa73a, 0xa73d, 0xa73c, 0xa73f, - 0xa73e, 0xa741, 0xa740, 0xa743, 0xa742, 0xa745, 0xa744, 0xa747, 0xa746, - 0xa749, 0xa748, 0xa74b, 0xa74a, 0xa74d, 0xa74c, 0xa74f, 0xa74e, 0xa751, - 0xa750, 0xa753, 0xa752, 0xa755, 0xa754, 0xa757, 0xa756, 0xa759, 0xa758, - 0xa75b, 0xa75a, 0xa75d, 0xa75c, 0xa75f, 0xa75e, 0xa761, 0xa760, 0xa763, - 0xa762, 0xa765, 0xa764, 0xa767, 0xa766, 0xa769, 0xa768, 0xa76b, 0xa76a, - 0xa76d, 0xa76c, 0xa76f, 0xa76e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xa77a, 0xa779, 0xa77c, 0xa77b, 0x1d79, - 0xa77f, 0xa77e, 0xa781, 0xa780, 0xa783, 0xa782, 0xa785, 0xa784, 0xa787, - 0xa786, 0x0000, 0x0000, 0x0000, 0xa78c, 0xa78b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 168, index 29 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 169, index 30 */ - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, - 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 170, index 31 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 251, index 32 */ - 0x100000f, 0x1000016, 0x100001d, 0x1000024, 0x100002d, 0x1000036, - 0x100003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100004f, 0x100005a, 0x1000065, - 0x1000070, 0x100007b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 - }, - { /* page 255, index 33 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, - 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff41, 0xff42, 0xff43, - 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, - 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, - 0xff56, 0xff57, 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, - 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, - 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, - 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 260, index 34 */ - 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, - 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, - 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, - 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, - 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, - 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, - 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, - 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, - 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, - 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - { /* page 471, index 35 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, - 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, - 0x0007, 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, - 0x0006, 0x0007, 0x0008, 0x0009 - } + { + /* page 0, index 0 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x039c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, + 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0000, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x1000000, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, + 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, + 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0000, 0x00d8, 0x00d9, 0x00da, + 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178 + }, + { + /* page 1, index 1 */ + 0x0101, 0x0100, 0x0103, 0x0102, 0x0105, 0x0104, 0x0107, 0x0106, 0x0109, + 0x0108, 0x010b, 0x010a, 0x010d, 0x010c, 0x010f, 0x010e, 0x0111, 0x0110, + 0x0113, 0x0112, 0x0115, 0x0114, 0x0117, 0x0116, 0x0119, 0x0118, 0x011b, + 0x011a, 0x011d, 0x011c, 0x011f, 0x011e, 0x0121, 0x0120, 0x0123, 0x0122, + 0x0125, 0x0124, 0x0127, 0x0126, 0x0129, 0x0128, 0x012b, 0x012a, 0x012d, + 0x012c, 0x012f, 0x012e, 0x1000007, 0x0049, 0x0133, 0x0132, 0x0135, + 0x0134, 0x0137, 0x0136, 0x0000, 0x013a, 0x0139, 0x013c, 0x013b, 0x013e, + 0x013d, 0x0140, 0x013f, 0x0142, 0x0141, 0x0144, 0x0143, 0x0146, 0x0145, + 0x0148, 0x0147, 0x1000086, 0x014b, 0x014a, 0x014d, 0x014c, 0x014f, + 0x014e, 0x0151, 0x0150, 0x0153, 0x0152, 0x0155, 0x0154, 0x0157, 0x0156, + 0x0159, 0x0158, 0x015b, 0x015a, 0x015d, 0x015c, 0x015f, 0x015e, 0x0161, + 0x0160, 0x0163, 0x0162, 0x0165, 0x0164, 0x0167, 0x0166, 0x0169, 0x0168, + 0x016b, 0x016a, 0x016d, 0x016c, 0x016f, 0x016e, 0x0171, 0x0170, 0x0173, + 0x0172, 0x0175, 0x0174, 0x0177, 0x0176, 0x00ff, 0x017a, 0x0179, 0x017c, + 0x017b, 0x017e, 0x017d, 0x0053, 0x0243, 0x0253, 0x0183, 0x0182, 0x0185, + 0x0184, 0x0254, 0x0188, 0x0187, 0x0256, 0x0257, 0x018c, 0x018b, 0x0000, + 0x01dd, 0x0259, 0x025b, 0x0192, 0x0191, 0x0260, 0x0263, 0x01f6, 0x0269, + 0x0268, 0x0199, 0x0198, 0x023d, 0x0000, 0x026f, 0x0272, 0x0220, 0x0275, + 0x01a1, 0x01a0, 0x01a3, 0x01a2, 0x01a5, 0x01a4, 0x0280, 0x01a8, 0x01a7, + 0x0283, 0x0000, 0x0000, 0x01ad, 0x01ac, 0x0288, 0x01b0, 0x01af, 0x028a, + 0x028b, 0x01b4, 0x01b3, 0x01b6, 0x01b5, 0x0292, 0x01b9, 0x01b8, 0x0000, + 0x0000, 0x01bd, 0x01bc, 0x0000, 0x01f7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x01c6, 0x0000, 0x01c4, 0x01c9, 0x0000, 0x01c7, 0x01cc, 0x0000, 0x01ca, + 0x01ce, 0x01cd, 0x01d0, 0x01cf, 0x01d2, 0x01d1, 0x01d4, 0x01d3, 0x01d6, + 0x01d5, 0x01d8, 0x01d7, 0x01da, 0x01d9, 0x01dc, 0x01db, 0x018e, 0x01df, + 0x01de, 0x01e1, 0x01e0, 0x01e3, 0x01e2, 0x01e5, 0x01e4, 0x01e7, 0x01e6, + 0x01e9, 0x01e8, 0x01eb, 0x01ea, 0x01ed, 0x01ec, 0x01ef, 0x01ee, + 0x10000ad, 0x01f3, 0x0000, 0x01f1, 0x01f5, 0x01f4, 0x0195, 0x01bf, + 0x01f9, 0x01f8, 0x01fb, 0x01fa, 0x01fd, 0x01fc, 0x01ff, 0x01fe + }, + { + /* page 2, index 2 */ + 0x0201, 0x0200, 0x0203, 0x0202, 0x0205, 0x0204, 0x0207, 0x0206, 0x0209, + 0x0208, 0x020b, 0x020a, 0x020d, 0x020c, 0x020f, 0x020e, 0x0211, 0x0210, + 0x0213, 0x0212, 0x0215, 0x0214, 0x0217, 0x0216, 0x0219, 0x0218, 0x021b, + 0x021a, 0x021d, 0x021c, 0x021f, 0x021e, 0x019e, 0x0000, 0x0223, 0x0222, + 0x0225, 0x0224, 0x0227, 0x0226, 0x0229, 0x0228, 0x022b, 0x022a, 0x022d, + 0x022c, 0x022f, 0x022e, 0x0231, 0x0230, 0x0233, 0x0232, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2c65, 0x023c, 0x023b, 0x019a, 0x2c66, + 0x0000, 0x0000, 0x0242, 0x0241, 0x0180, 0x0289, 0x028c, 0x0247, 0x0246, + 0x0249, 0x0248, 0x024b, 0x024a, 0x024d, 0x024c, 0x024f, 0x024e, 0x2c6f, + 0x2c6d, 0x0000, 0x0181, 0x0186, 0x0000, 0x0189, 0x018a, 0x0000, 0x018f, + 0x0000, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0193, 0x0000, 0x0000, + 0x0194, 0x0000, 0x0000, 0x0000, 0x0000, 0x0197, 0x0196, 0x0000, 0x2c62, + 0x0000, 0x0000, 0x0000, 0x019c, 0x0000, 0x2c6e, 0x019d, 0x0000, 0x0000, + 0x019f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2c64, + 0x0000, 0x0000, 0x01a6, 0x0000, 0x0000, 0x01a9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x01ae, 0x0244, 0x01b1, 0x01b2, 0x0245, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x01b7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 3, index 3 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0371, 0x0370, 0x0373, 0x0372, 0x0000, + 0x0000, 0x0377, 0x0376, 0x0000, 0x0000, 0x0000, 0x03fd, 0x03fe, 0x03ff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03ac, + 0x0000, 0x03ad, 0x03ae, 0x03af, 0x0000, 0x03cc, 0x0000, 0x03cd, 0x03ce, + 0x100008f, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x0000, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0x03ca, 0x03cb, 0x0386, 0x0388, 0x0389, 0x038a, 0x100009e, 0x0391, + 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, + 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x038c, + 0x038e, 0x038f, 0x03d7, 0x0392, 0x0398, 0x0000, 0x0000, 0x0000, 0x03a6, + 0x03a0, 0x03cf, 0x03d9, 0x03d8, 0x03db, 0x03da, 0x03dd, 0x03dc, 0x03df, + 0x03de, 0x03e1, 0x03e0, 0x03e3, 0x03e2, 0x03e5, 0x03e4, 0x03e7, 0x03e6, + 0x03e9, 0x03e8, 0x03eb, 0x03ea, 0x03ed, 0x03ec, 0x03ef, 0x03ee, 0x039a, + 0x03a1, 0x03f9, 0x0000, 0x03b8, 0x0395, 0x0000, 0x03f8, 0x03f7, 0x03f2, + 0x03fb, 0x03fa, 0x0000, 0x037b, 0x037c, 0x037d + }, + { + /* page 4, index 4 */ + 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, + 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, + 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, + 0x044d, 0x044e, 0x044f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, + 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0400, + 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, + 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, 0x0461, 0x0460, 0x0463, + 0x0462, 0x0465, 0x0464, 0x0467, 0x0466, 0x0469, 0x0468, 0x046b, 0x046a, + 0x046d, 0x046c, 0x046f, 0x046e, 0x0471, 0x0470, 0x0473, 0x0472, 0x0475, + 0x0474, 0x0477, 0x0476, 0x0479, 0x0478, 0x047b, 0x047a, 0x047d, 0x047c, + 0x047f, 0x047e, 0x0481, 0x0480, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x048b, 0x048a, 0x048d, 0x048c, 0x048f, 0x048e, + 0x0491, 0x0490, 0x0493, 0x0492, 0x0495, 0x0494, 0x0497, 0x0496, 0x0499, + 0x0498, 0x049b, 0x049a, 0x049d, 0x049c, 0x049f, 0x049e, 0x04a1, 0x04a0, + 0x04a3, 0x04a2, 0x04a5, 0x04a4, 0x04a7, 0x04a6, 0x04a9, 0x04a8, 0x04ab, + 0x04aa, 0x04ad, 0x04ac, 0x04af, 0x04ae, 0x04b1, 0x04b0, 0x04b3, 0x04b2, + 0x04b5, 0x04b4, 0x04b7, 0x04b6, 0x04b9, 0x04b8, 0x04bb, 0x04ba, 0x04bd, + 0x04bc, 0x04bf, 0x04be, 0x04cf, 0x04c2, 0x04c1, 0x04c4, 0x04c3, 0x04c6, + 0x04c5, 0x04c8, 0x04c7, 0x04ca, 0x04c9, 0x04cc, 0x04cb, 0x04ce, 0x04cd, + 0x04c0, 0x04d1, 0x04d0, 0x04d3, 0x04d2, 0x04d5, 0x04d4, 0x04d7, 0x04d6, + 0x04d9, 0x04d8, 0x04db, 0x04da, 0x04dd, 0x04dc, 0x04df, 0x04de, 0x04e1, + 0x04e0, 0x04e3, 0x04e2, 0x04e5, 0x04e4, 0x04e7, 0x04e6, 0x04e9, 0x04e8, + 0x04eb, 0x04ea, 0x04ed, 0x04ec, 0x04ef, 0x04ee, 0x04f1, 0x04f0, 0x04f3, + 0x04f2, 0x04f5, 0x04f4, 0x04f7, 0x04f6, 0x04f9, 0x04f8, 0x04fb, 0x04fa, + 0x04fd, 0x04fc, 0x04ff, 0x04fe + }, + { + /* page 5, index 5 */ + 0x0501, 0x0500, 0x0503, 0x0502, 0x0505, 0x0504, 0x0507, 0x0506, 0x0509, + 0x0508, 0x050b, 0x050a, 0x050d, 0x050c, 0x050f, 0x050e, 0x0511, 0x0510, + 0x0513, 0x0512, 0x0515, 0x0514, 0x0517, 0x0516, 0x0519, 0x0518, 0x051b, + 0x051a, 0x051d, 0x051c, 0x051f, 0x051e, 0x0521, 0x0520, 0x0523, 0x0522, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, + 0x0566, 0x0567, 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, + 0x056f, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, + 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 0x0580, + 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0531, 0x0532, + 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 0x0538, 0x0539, 0x053a, 0x053b, + 0x053c, 0x053d, 0x053e, 0x053f, 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, + 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d, + 0x054e, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, + 0x1000044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 6, index 6 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 7, index 7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 9, index 8 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 10, index 9 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 11, index 10 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 12, index 11 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 13, index 12 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 14, index 13 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 15, index 14 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 16, index 15 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d00, 0x2d01, + 0x2d02, 0x2d03, 0x2d04, 0x2d05, 0x2d06, 0x2d07, 0x2d08, 0x2d09, 0x2d0a, + 0x2d0b, 0x2d0c, 0x2d0d, 0x2d0e, 0x2d0f, 0x2d10, 0x2d11, 0x2d12, 0x2d13, + 0x2d14, 0x2d15, 0x2d16, 0x2d17, 0x2d18, 0x2d19, 0x2d1a, 0x2d1b, 0x2d1c, + 0x2d1d, 0x2d1e, 0x2d1f, 0x2d20, 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 23, index 16 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 24, index 17 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 25, index 18 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 27, index 19 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 28, index 20 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 29, index 21 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xa77d, 0x0000, 0x0000, 0x0000, 0x2c63, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 30, index 22 */ + 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06, 0x1e09, + 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e, 0x1e11, 0x1e10, + 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16, 0x1e19, 0x1e18, 0x1e1b, + 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e, 0x1e21, 0x1e20, 0x1e23, 0x1e22, + 0x1e25, 0x1e24, 0x1e27, 0x1e26, 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, + 0x1e2c, 0x1e2f, 0x1e2e, 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, + 0x1e37, 0x1e36, 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, + 0x1e3e, 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46, + 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e, 0x1e51, + 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56, 0x1e59, 0x1e58, + 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e, 0x1e61, 0x1e60, 0x1e63, + 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66, 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, + 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e, 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, + 0x1e74, 0x1e77, 0x1e76, 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, + 0x1e7f, 0x1e7e, 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, + 0x1e86, 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e, + 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0x10000b6, 0x10000bf, + 0x10000c8, 0x10000d1, 0x10000da, 0x1e60, 0x0000, 0x0000, 0x00df, 0x0000, + 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6, 0x1ea9, + 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae, 0x1eb1, 0x1eb0, + 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6, 0x1eb9, 0x1eb8, 0x1ebb, + 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe, 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, + 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6, 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, + 0x1ecc, 0x1ecf, 0x1ece, 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, + 0x1ed7, 0x1ed6, 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, + 0x1ede, 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6, + 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee, 0x1ef1, + 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6, 0x1ef9, 0x1ef8, + 0x1efb, 0x1efa, 0x1efd, 0x1efc, 0x1eff, 0x1efe + }, + { + /* page 31, index 23 */ + 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f00, + 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f18, 0x1f19, + 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x0000, 0x0000, 0x1f10, 0x1f11, 0x1f12, + 0x1f13, 0x1f14, 0x1f15, 0x0000, 0x0000, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, + 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, + 0x1f25, 0x1f26, 0x1f27, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, + 0x1f3e, 0x1f3f, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, + 0x1f37, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x0000, 0x0000, + 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x0000, 0x0000, + 0x10000e3, 0x1f59, 0x10000ee, 0x1f5b, 0x10000fd, 0x1f5d, 0x100010c, + 0x1f5f, 0x0000, 0x1f51, 0x0000, 0x1f53, 0x0000, 0x1f55, 0x0000, 0x1f57, + 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1f60, + 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1fba, 0x1fbb, + 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, + 0x1feb, 0x1ffa, 0x1ffb, 0x0000, 0x0000, 0x10001b7, 0x10001c4, 0x10001d1, + 0x10001de, 0x10001eb, 0x10001f8, 0x1000205, 0x1000212, 0x100021f, + 0x1000229, 0x1000233, 0x100023d, 0x1000247, 0x1000251, 0x100025b, + 0x1000265, 0x100026f, 0x100027c, 0x1000289, 0x1000296, 0x10002a3, + 0x10002b0, 0x10002bd, 0x10002ca, 0x10002d7, 0x10002e1, 0x10002eb, + 0x10002f5, 0x10002ff, 0x1000309, 0x1000313, 0x100031d, 0x1000327, + 0x1000334, 0x1000341, 0x100034e, 0x100035b, 0x1000368, 0x1000375, + 0x1000382, 0x100038f, 0x1000399, 0x10003a3, 0x10003ad, 0x10003b7, + 0x10003c1, 0x10003cb, 0x10003d5, 0x1fb8, 0x1fb9, 0x100041e, 0x10003df, + 0x100042b, 0x0000, 0x100011b, 0x1000466, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, + 0x10003eb, 0x0000, 0x0399, 0x0000, 0x0000, 0x0000, 0x1000436, 0x10003f4, + 0x1000443, 0x0000, 0x1000126, 0x1000475, 0x1f72, 0x1f73, 0x1f74, 0x1f75, + 0x1000400, 0x0000, 0x0000, 0x0000, 0x1fd8, 0x1fd9, 0x1000131, 0x1000140, + 0x0000, 0x0000, 0x100014f, 0x100015a, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1fe8, 0x1fe9, 0x1000169, 0x1000178, + 0x1000187, 0x1fec, 0x1000192, 0x100019d, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, + 0x1fe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100044e, 0x1000409, + 0x100045b, 0x0000, 0x10001ac, 0x1000484, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, + 0x1000415, 0x0000, 0x0000, 0x0000 + }, + { + /* page 33, index 24 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x03c9, 0x0000, 0x0000, 0x0000, 0x006b, 0x00e5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x214e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2132, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2184, 0x2183, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 44, index 25 */ + 0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, 0x2c38, + 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, 0x2c40, 0x2c41, + 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2c48, 0x2c49, 0x2c4a, + 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c50, 0x2c51, 0x2c52, 0x2c53, + 0x2c54, 0x2c55, 0x2c56, 0x2c57, 0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, + 0x2c5d, 0x2c5e, 0x0000, 0x2c00, 0x2c01, 0x2c02, 0x2c03, 0x2c04, 0x2c05, + 0x2c06, 0x2c07, 0x2c08, 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, + 0x2c0f, 0x2c10, 0x2c11, 0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16, 0x2c17, + 0x2c18, 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e, 0x2c1f, 0x2c20, + 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, 0x2c28, 0x2c29, + 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x0000, 0x2c61, 0x2c60, 0x026b, + 0x1d7d, 0x027d, 0x023a, 0x023e, 0x2c68, 0x2c67, 0x2c6a, 0x2c69, 0x2c6c, + 0x2c6b, 0x0251, 0x0271, 0x0250, 0x0000, 0x0000, 0x2c73, 0x2c72, 0x0000, + 0x2c76, 0x2c75, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2c81, 0x2c80, 0x2c83, 0x2c82, 0x2c85, 0x2c84, 0x2c87, + 0x2c86, 0x2c89, 0x2c88, 0x2c8b, 0x2c8a, 0x2c8d, 0x2c8c, 0x2c8f, 0x2c8e, + 0x2c91, 0x2c90, 0x2c93, 0x2c92, 0x2c95, 0x2c94, 0x2c97, 0x2c96, 0x2c99, + 0x2c98, 0x2c9b, 0x2c9a, 0x2c9d, 0x2c9c, 0x2c9f, 0x2c9e, 0x2ca1, 0x2ca0, + 0x2ca3, 0x2ca2, 0x2ca5, 0x2ca4, 0x2ca7, 0x2ca6, 0x2ca9, 0x2ca8, 0x2cab, + 0x2caa, 0x2cad, 0x2cac, 0x2caf, 0x2cae, 0x2cb1, 0x2cb0, 0x2cb3, 0x2cb2, + 0x2cb5, 0x2cb4, 0x2cb7, 0x2cb6, 0x2cb9, 0x2cb8, 0x2cbb, 0x2cba, 0x2cbd, + 0x2cbc, 0x2cbf, 0x2cbe, 0x2cc1, 0x2cc0, 0x2cc3, 0x2cc2, 0x2cc5, 0x2cc4, + 0x2cc7, 0x2cc6, 0x2cc9, 0x2cc8, 0x2ccb, 0x2cca, 0x2ccd, 0x2ccc, 0x2ccf, + 0x2cce, 0x2cd1, 0x2cd0, 0x2cd3, 0x2cd2, 0x2cd5, 0x2cd4, 0x2cd7, 0x2cd6, + 0x2cd9, 0x2cd8, 0x2cdb, 0x2cda, 0x2cdd, 0x2cdc, 0x2cdf, 0x2cde, 0x2ce1, + 0x2ce0, 0x2ce3, 0x2ce2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 45, index 26 */ + 0x10a0, 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, + 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, 0x10b1, + 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10ba, + 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 0x10c0, 0x10c1, 0x10c2, 0x10c3, + 0x10c4, 0x10c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 166, index 27 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa641, 0xa640, 0xa643, 0xa642, 0xa645, 0xa644, 0xa647, 0xa646, + 0xa649, 0xa648, 0xa64b, 0xa64a, 0xa64d, 0xa64c, 0xa64f, 0xa64e, 0xa651, + 0xa650, 0xa653, 0xa652, 0xa655, 0xa654, 0xa657, 0xa656, 0xa659, 0xa658, + 0xa65b, 0xa65a, 0xa65d, 0xa65c, 0xa65f, 0xa65e, 0x0000, 0x0000, 0xa663, + 0xa662, 0xa665, 0xa664, 0xa667, 0xa666, 0xa669, 0xa668, 0xa66b, 0xa66a, + 0xa66d, 0xa66c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xa681, 0xa680, 0xa683, 0xa682, 0xa685, 0xa684, 0xa687, + 0xa686, 0xa689, 0xa688, 0xa68b, 0xa68a, 0xa68d, 0xa68c, 0xa68f, 0xa68e, + 0xa691, 0xa690, 0xa693, 0xa692, 0xa695, 0xa694, 0xa697, 0xa696, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 167, index 28 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa723, 0xa722, + 0xa725, 0xa724, 0xa727, 0xa726, 0xa729, 0xa728, 0xa72b, 0xa72a, 0xa72d, + 0xa72c, 0xa72f, 0xa72e, 0x0000, 0x0000, 0xa733, 0xa732, 0xa735, 0xa734, + 0xa737, 0xa736, 0xa739, 0xa738, 0xa73b, 0xa73a, 0xa73d, 0xa73c, 0xa73f, + 0xa73e, 0xa741, 0xa740, 0xa743, 0xa742, 0xa745, 0xa744, 0xa747, 0xa746, + 0xa749, 0xa748, 0xa74b, 0xa74a, 0xa74d, 0xa74c, 0xa74f, 0xa74e, 0xa751, + 0xa750, 0xa753, 0xa752, 0xa755, 0xa754, 0xa757, 0xa756, 0xa759, 0xa758, + 0xa75b, 0xa75a, 0xa75d, 0xa75c, 0xa75f, 0xa75e, 0xa761, 0xa760, 0xa763, + 0xa762, 0xa765, 0xa764, 0xa767, 0xa766, 0xa769, 0xa768, 0xa76b, 0xa76a, + 0xa76d, 0xa76c, 0xa76f, 0xa76e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xa77a, 0xa779, 0xa77c, 0xa77b, 0x1d79, + 0xa77f, 0xa77e, 0xa781, 0xa780, 0xa783, 0xa782, 0xa785, 0xa784, 0xa787, + 0xa786, 0x0000, 0x0000, 0x0000, 0xa78c, 0xa78b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 168, index 29 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 169, index 30 */ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 170, index 31 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 251, index 32 */ + 0x100000f, 0x1000016, 0x100001d, 0x1000024, 0x100002d, 0x1000036, + 0x100003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100004f, 0x100005a, 0x1000065, + 0x1000070, 0x100007b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }, + { + /* page 255, index 33 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff41, 0xff42, 0xff43, + 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, + 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, + 0xff56, 0xff57, 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, + 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, + 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 260, index 34 */ + 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, + 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, + 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, + 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, + 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, + 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, + 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, + 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, + 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, + 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { + /* page 471, index 35 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, + 0x0007, 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009 + } }; /* U+0000 through U+2FAFF */ static const int16_t attr_table_part1[763] = { - 0 /* page 0 */, - 1 /* page 1 */, - 2 /* page 2 */, - 3 /* page 3 */, - 4 /* page 4 */, - 5 /* page 5 */, - 6 /* page 6 */, - 7 /* page 7 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 8 /* page 9 */, - 9 /* page 10 */, - 10 /* page 11 */, - 11 /* page 12 */, - 12 /* page 13 */, - 13 /* page 14 */, - 14 /* page 15 */, - 15 /* page 16 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 16 /* page 23 */, - 17 /* page 24 */, - 18 /* page 25 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 19 /* page 27 */, - 20 /* page 28 */, - 21 /* page 29 */, - 22 /* page 30 */, - 23 /* page 31 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 24 /* page 33 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 25 /* page 44 */, - 26 /* page 45 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 27 /* page 166 */, - 28 /* page 167 */, - 29 /* page 168 */, - 30 /* page 169 */, - 31 /* page 170 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 32 /* page 251 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 33 /* page 255 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 34 /* page 260 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 35 /* page 471 */, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 5 /* page 5 */, + 6 /* page 6 */, + 7 /* page 7 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 8 /* page 9 */, + 9 /* page 10 */, + 10 /* page 11 */, + 11 /* page 12 */, + 12 /* page 13 */, + 13 /* page 14 */, + 14 /* page 15 */, + 15 /* page 16 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 16 /* page 23 */, + 17 /* page 24 */, + 18 /* page 25 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 19 /* page 27 */, + 20 /* page 28 */, + 21 /* page 29 */, + 22 /* page 30 */, + 23 /* page 31 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 24 /* page 33 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 25 /* page 44 */, + 26 /* page 45 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 27 /* page 166 */, + 28 /* page 167 */, + 29 /* page 168 */, + 30 /* page 169 */, + 31 /* page 170 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 32 /* page 251 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 33 /* page 255 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 34 /* page 260 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 35 /* page 471 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX }; /* U+E0000 through U+10FFFF */ static const int16_t attr_table_part2[768] = { - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX, - 0x0000 + G_UNICODE_MAX_TABLE_INDEX + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX }; static const gunichar title_table[][3] = { - { 0x01c5, 0x01c4, 0x01c6 }, - { 0x01c8, 0x01c7, 0x01c9 }, - { 0x01cb, 0x01ca, 0x01cc }, - { 0x01f2, 0x01f1, 0x01f3 }, - { 0x1f88, 0x0000, 0x1f80 }, - { 0x1f89, 0x0000, 0x1f81 }, - { 0x1f8a, 0x0000, 0x1f82 }, - { 0x1f8b, 0x0000, 0x1f83 }, - { 0x1f8c, 0x0000, 0x1f84 }, - { 0x1f8d, 0x0000, 0x1f85 }, - { 0x1f8e, 0x0000, 0x1f86 }, - { 0x1f8f, 0x0000, 0x1f87 }, - { 0x1f98, 0x0000, 0x1f90 }, - { 0x1f99, 0x0000, 0x1f91 }, - { 0x1f9a, 0x0000, 0x1f92 }, - { 0x1f9b, 0x0000, 0x1f93 }, - { 0x1f9c, 0x0000, 0x1f94 }, - { 0x1f9d, 0x0000, 0x1f95 }, - { 0x1f9e, 0x0000, 0x1f96 }, - { 0x1f9f, 0x0000, 0x1f97 }, - { 0x1fa8, 0x0000, 0x1fa0 }, - { 0x1fa9, 0x0000, 0x1fa1 }, - { 0x1faa, 0x0000, 0x1fa2 }, - { 0x1fab, 0x0000, 0x1fa3 }, - { 0x1fac, 0x0000, 0x1fa4 }, - { 0x1fad, 0x0000, 0x1fa5 }, - { 0x1fae, 0x0000, 0x1fa6 }, - { 0x1faf, 0x0000, 0x1fa7 }, - { 0x1fbc, 0x0000, 0x1fb3 }, - { 0x1fcc, 0x0000, 0x1fc3 }, - { 0x1ffc, 0x0000, 0x1ff3 } + { 0x01c5, 0x01c4, 0x01c6 }, + { 0x01c8, 0x01c7, 0x01c9 }, + { 0x01cb, 0x01ca, 0x01cc }, + { 0x01f2, 0x01f1, 0x01f3 }, + { 0x1f88, 0x0000, 0x1f80 }, + { 0x1f89, 0x0000, 0x1f81 }, + { 0x1f8a, 0x0000, 0x1f82 }, + { 0x1f8b, 0x0000, 0x1f83 }, + { 0x1f8c, 0x0000, 0x1f84 }, + { 0x1f8d, 0x0000, 0x1f85 }, + { 0x1f8e, 0x0000, 0x1f86 }, + { 0x1f8f, 0x0000, 0x1f87 }, + { 0x1f98, 0x0000, 0x1f90 }, + { 0x1f99, 0x0000, 0x1f91 }, + { 0x1f9a, 0x0000, 0x1f92 }, + { 0x1f9b, 0x0000, 0x1f93 }, + { 0x1f9c, 0x0000, 0x1f94 }, + { 0x1f9d, 0x0000, 0x1f95 }, + { 0x1f9e, 0x0000, 0x1f96 }, + { 0x1f9f, 0x0000, 0x1f97 }, + { 0x1fa8, 0x0000, 0x1fa0 }, + { 0x1fa9, 0x0000, 0x1fa1 }, + { 0x1faa, 0x0000, 0x1fa2 }, + { 0x1fab, 0x0000, 0x1fa3 }, + { 0x1fac, 0x0000, 0x1fa4 }, + { 0x1fad, 0x0000, 0x1fa5 }, + { 0x1fae, 0x0000, 0x1fa6 }, + { 0x1faf, 0x0000, 0x1fa7 }, + { 0x1fbc, 0x0000, 0x1fb3 }, + { 0x1fcc, 0x0000, 0x1fc3 }, + { 0x1ffc, 0x0000, 0x1ff3 } }; /* Table of special cases for case conversion; each record contains - * First, the best single character mapping to lowercase if Lu, - * and to uppercase if Ll, followed by the output mapping for the two cases + * First, the best single character mapping to lowercase if Lu, + * and to uppercase if Ll, followed by the output mapping for the two cases * other than the case of the codepoint, in the order [Ll],[Lu],[Lt], * encoded in UTF-8, separated and terminated by a null character. */ static const char special_case_table[] = { - "\x00\x53\x53\x00\x53\x73\0" /* offset 0 */ - "\x69\x69\xcc\x87\x00\xc4\xb0\0" /* offset 7 */ - "\x00\x46\x46\x00\x46\x66\0" /* offset 15 */ - "\x00\x46\x49\x00\x46\x69\0" /* offset 22 */ - "\x00\x46\x4c\x00\x46\x6c\0" /* offset 29 */ - "\x00\x46\x46\x49\x00\x46\x66\x69\0" /* offset 36 */ - "\x00\x46\x46\x4c\x00\x46\x66\x6c\0" /* offset 45 */ - "\x00\x53\x54\x00\x53\x74\0" /* offset 54 */ - "\x00\x53\x54\x00\x53\x74\0" /* offset 61 */ - "\x00\xd4\xb5\xd5\x92\x00\xd4\xb5\xd6\x82\0" /* offset 68 */ - "\x00\xd5\x84\xd5\x86\x00\xd5\x84\xd5\xb6\0" /* offset 79 */ - "\x00\xd5\x84\xd4\xb5\x00\xd5\x84\xd5\xa5\0" /* offset 90 */ - "\x00\xd5\x84\xd4\xbb\x00\xd5\x84\xd5\xab\0" /* offset 101 */ - "\x00\xd5\x8e\xd5\x86\x00\xd5\x8e\xd5\xb6\0" /* offset 112 */ - "\x00\xd5\x84\xd4\xbd\x00\xd5\x84\xd5\xad\0" /* offset 123 */ - "\x00\xca\xbc\x4e\x00\xca\xbc\x4e\0" /* offset 134 */ - "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 143 */ - "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 158 */ - "\x00\x4a\xcc\x8c\x00\x4a\xcc\x8c\0" /* offset 173 */ - "\x00\x48\xcc\xb1\x00\x48\xcc\xb1\0" /* offset 182 */ - "\x00\x54\xcc\x88\x00\x54\xcc\x88\0" /* offset 191 */ - "\x00\x57\xcc\x8a\x00\x57\xcc\x8a\0" /* offset 200 */ - "\x00\x59\xcc\x8a\x00\x59\xcc\x8a\0" /* offset 209 */ - "\x00\x41\xca\xbe\x00\x41\xca\xbe\0" /* offset 218 */ - "\x00\xce\xa5\xcc\x93\x00\xce\xa5\xcc\x93\0" /* offset 227 */ - "\x00\xce\xa5\xcc\x93\xcc\x80\x00\xce\xa5\xcc\x93\xcc\x80\0" /* offset 238 */ - "\x00\xce\xa5\xcc\x93\xcc\x81\x00\xce\xa5\xcc\x93\xcc\x81\0" /* offset 253 */ - "\x00\xce\xa5\xcc\x93\xcd\x82\x00\xce\xa5\xcc\x93\xcd\x82\0" /* offset 268 */ - "\x00\xce\x91\xcd\x82\x00\xce\x91\xcd\x82\0" /* offset 283 */ - "\x00\xce\x97\xcd\x82\x00\xce\x97\xcd\x82\0" /* offset 294 */ - "\x00\xce\x99\xcc\x88\xcc\x80\x00\xce\x99\xcc\x88\xcc\x80\0" /* offset 305 */ - "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 320 */ - "\x00\xce\x99\xcd\x82\x00\xce\x99\xcd\x82\0" /* offset 335 */ - "\x00\xce\x99\xcc\x88\xcd\x82\x00\xce\x99\xcc\x88\xcd\x82\0" /* offset 346 */ - "\x00\xce\xa5\xcc\x88\xcc\x80\x00\xce\xa5\xcc\x88\xcc\x80\0" /* offset 361 */ - "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 376 */ - "\x00\xce\xa1\xcc\x93\x00\xce\xa1\xcc\x93\0" /* offset 391 */ - "\x00\xce\xa5\xcd\x82\x00\xce\xa5\xcd\x82\0" /* offset 402 */ - "\x00\xce\xa5\xcc\x88\xcd\x82\x00\xce\xa5\xcc\x88\xcd\x82\0" /* offset 413 */ - "\x00\xce\xa9\xcd\x82\x00\xce\xa9\xcd\x82\0" /* offset 428 */ - "\xe1\xbe\x88\xe1\xbc\x88\xce\x99\x00\xe1\xbe\x88\0" /* offset 439 */ - "\xe1\xbe\x89\xe1\xbc\x89\xce\x99\x00\xe1\xbe\x89\0" /* offset 452 */ - "\xe1\xbe\x8a\xe1\xbc\x8a\xce\x99\x00\xe1\xbe\x8a\0" /* offset 465 */ - "\xe1\xbe\x8b\xe1\xbc\x8b\xce\x99\x00\xe1\xbe\x8b\0" /* offset 478 */ - "\xe1\xbe\x8c\xe1\xbc\x8c\xce\x99\x00\xe1\xbe\x8c\0" /* offset 491 */ - "\xe1\xbe\x8d\xe1\xbc\x8d\xce\x99\x00\xe1\xbe\x8d\0" /* offset 504 */ - "\xe1\xbe\x8e\xe1\xbc\x8e\xce\x99\x00\xe1\xbe\x8e\0" /* offset 517 */ - "\xe1\xbe\x8f\xe1\xbc\x8f\xce\x99\x00\xe1\xbe\x8f\0" /* offset 530 */ - "\xe1\xbe\x80\x00\xe1\xbc\x88\xce\x99\0" /* offset 543 */ - "\xe1\xbe\x81\x00\xe1\xbc\x89\xce\x99\0" /* offset 553 */ - "\xe1\xbe\x82\x00\xe1\xbc\x8a\xce\x99\0" /* offset 563 */ - "\xe1\xbe\x83\x00\xe1\xbc\x8b\xce\x99\0" /* offset 573 */ - "\xe1\xbe\x84\x00\xe1\xbc\x8c\xce\x99\0" /* offset 583 */ - "\xe1\xbe\x85\x00\xe1\xbc\x8d\xce\x99\0" /* offset 593 */ - "\xe1\xbe\x86\x00\xe1\xbc\x8e\xce\x99\0" /* offset 603 */ - "\xe1\xbe\x87\x00\xe1\xbc\x8f\xce\x99\0" /* offset 613 */ - "\xe1\xbe\x98\xe1\xbc\xa8\xce\x99\x00\xe1\xbe\x98\0" /* offset 623 */ - "\xe1\xbe\x99\xe1\xbc\xa9\xce\x99\x00\xe1\xbe\x99\0" /* offset 636 */ - "\xe1\xbe\x9a\xe1\xbc\xaa\xce\x99\x00\xe1\xbe\x9a\0" /* offset 649 */ - "\xe1\xbe\x9b\xe1\xbc\xab\xce\x99\x00\xe1\xbe\x9b\0" /* offset 662 */ - "\xe1\xbe\x9c\xe1\xbc\xac\xce\x99\x00\xe1\xbe\x9c\0" /* offset 675 */ - "\xe1\xbe\x9d\xe1\xbc\xad\xce\x99\x00\xe1\xbe\x9d\0" /* offset 688 */ - "\xe1\xbe\x9e\xe1\xbc\xae\xce\x99\x00\xe1\xbe\x9e\0" /* offset 701 */ - "\xe1\xbe\x9f\xe1\xbc\xaf\xce\x99\x00\xe1\xbe\x9f\0" /* offset 714 */ - "\xe1\xbe\x90\x00\xe1\xbc\xa8\xce\x99\0" /* offset 727 */ - "\xe1\xbe\x91\x00\xe1\xbc\xa9\xce\x99\0" /* offset 737 */ - "\xe1\xbe\x92\x00\xe1\xbc\xaa\xce\x99\0" /* offset 747 */ - "\xe1\xbe\x93\x00\xe1\xbc\xab\xce\x99\0" /* offset 757 */ - "\xe1\xbe\x94\x00\xe1\xbc\xac\xce\x99\0" /* offset 767 */ - "\xe1\xbe\x95\x00\xe1\xbc\xad\xce\x99\0" /* offset 777 */ - "\xe1\xbe\x96\x00\xe1\xbc\xae\xce\x99\0" /* offset 787 */ - "\xe1\xbe\x97\x00\xe1\xbc\xaf\xce\x99\0" /* offset 797 */ - "\xe1\xbe\xa8\xe1\xbd\xa8\xce\x99\x00\xe1\xbe\xa8\0" /* offset 807 */ - "\xe1\xbe\xa9\xe1\xbd\xa9\xce\x99\x00\xe1\xbe\xa9\0" /* offset 820 */ - "\xe1\xbe\xaa\xe1\xbd\xaa\xce\x99\x00\xe1\xbe\xaa\0" /* offset 833 */ - "\xe1\xbe\xab\xe1\xbd\xab\xce\x99\x00\xe1\xbe\xab\0" /* offset 846 */ - "\xe1\xbe\xac\xe1\xbd\xac\xce\x99\x00\xe1\xbe\xac\0" /* offset 859 */ - "\xe1\xbe\xad\xe1\xbd\xad\xce\x99\x00\xe1\xbe\xad\0" /* offset 872 */ - "\xe1\xbe\xae\xe1\xbd\xae\xce\x99\x00\xe1\xbe\xae\0" /* offset 885 */ - "\xe1\xbe\xaf\xe1\xbd\xaf\xce\x99\x00\xe1\xbe\xaf\0" /* offset 898 */ - "\xe1\xbe\xa0\x00\xe1\xbd\xa8\xce\x99\0" /* offset 911 */ - "\xe1\xbe\xa1\x00\xe1\xbd\xa9\xce\x99\0" /* offset 921 */ - "\xe1\xbe\xa2\x00\xe1\xbd\xaa\xce\x99\0" /* offset 931 */ - "\xe1\xbe\xa3\x00\xe1\xbd\xab\xce\x99\0" /* offset 941 */ - "\xe1\xbe\xa4\x00\xe1\xbd\xac\xce\x99\0" /* offset 951 */ - "\xe1\xbe\xa5\x00\xe1\xbd\xad\xce\x99\0" /* offset 961 */ - "\xe1\xbe\xa6\x00\xe1\xbd\xae\xce\x99\0" /* offset 971 */ - "\xe1\xbe\xa7\x00\xe1\xbd\xaf\xce\x99\0" /* offset 981 */ - "\xe1\xbe\xbc\xce\x91\xce\x99\x00\xe1\xbe\xbc\0" /* offset 991 */ - "\xe1\xbe\xb3\x00\xce\x91\xce\x99\0" /* offset 1003 */ - "\xe1\xbf\x8c\xce\x97\xce\x99\x00\xe1\xbf\x8c\0" /* offset 1012 */ - "\xe1\xbf\x83\x00\xce\x97\xce\x99\0" /* offset 1024 */ - "\xe1\xbf\xbc\xce\xa9\xce\x99\x00\xe1\xbf\xbc\0" /* offset 1033 */ - "\xe1\xbf\xb3\x00\xce\xa9\xce\x99\0" /* offset 1045 */ - "\x00\xe1\xbe\xba\xce\x99\x00\xe1\xbe\xba\xcd\x85\0" /* offset 1054 */ - "\x00\xce\x86\xce\x99\x00\xce\x86\xcd\x85\0" /* offset 1067 */ - "\x00\xe1\xbf\x8a\xce\x99\x00\xe1\xbf\x8a\xcd\x85\0" /* offset 1078 */ - "\x00\xce\x89\xce\x99\x00\xce\x89\xcd\x85\0" /* offset 1091 */ - "\x00\xe1\xbf\xba\xce\x99\x00\xe1\xbf\xba\xcd\x85\0" /* offset 1102 */ - "\x00\xce\x8f\xce\x99\x00\xce\x8f\xcd\x85\0" /* offset 1115 */ - "\x00\xce\x91\xcd\x82\xce\x99\x00\xce\x91\xcd\x82\xcd\x85\0" /* offset 1126 */ - "\x00\xce\x97\xcd\x82\xce\x99\x00\xce\x97\xcd\x82\xcd\x85\0" /* offset 1141 */ - "\x00\xce\xa9\xcd\x82\xce\x99\x00\xce\xa9\xcd\x82\xcd\x85\0" /* offset 1156 */ + "\x00\x53\x53\x00\x53\x73\0" /* offset 0 */ + "\x69\x69\xcc\x87\x00\xc4\xb0\0" /* offset 7 */ + "\x00\x46\x46\x00\x46\x66\0" /* offset 15 */ + "\x00\x46\x49\x00\x46\x69\0" /* offset 22 */ + "\x00\x46\x4c\x00\x46\x6c\0" /* offset 29 */ + "\x00\x46\x46\x49\x00\x46\x66\x69\0" /* offset 36 */ + "\x00\x46\x46\x4c\x00\x46\x66\x6c\0" /* offset 45 */ + "\x00\x53\x54\x00\x53\x74\0" /* offset 54 */ + "\x00\x53\x54\x00\x53\x74\0" /* offset 61 */ + "\x00\xd4\xb5\xd5\x92\x00\xd4\xb5\xd6\x82\0" /* offset 68 */ + "\x00\xd5\x84\xd5\x86\x00\xd5\x84\xd5\xb6\0" /* offset 79 */ + "\x00\xd5\x84\xd4\xb5\x00\xd5\x84\xd5\xa5\0" /* offset 90 */ + "\x00\xd5\x84\xd4\xbb\x00\xd5\x84\xd5\xab\0" /* offset 101 */ + "\x00\xd5\x8e\xd5\x86\x00\xd5\x8e\xd5\xb6\0" /* offset 112 */ + "\x00\xd5\x84\xd4\xbd\x00\xd5\x84\xd5\xad\0" /* offset 123 */ + "\x00\xca\xbc\x4e\x00\xca\xbc\x4e\0" /* offset 134 */ + "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 143 */ + "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 158 */ + "\x00\x4a\xcc\x8c\x00\x4a\xcc\x8c\0" /* offset 173 */ + "\x00\x48\xcc\xb1\x00\x48\xcc\xb1\0" /* offset 182 */ + "\x00\x54\xcc\x88\x00\x54\xcc\x88\0" /* offset 191 */ + "\x00\x57\xcc\x8a\x00\x57\xcc\x8a\0" /* offset 200 */ + "\x00\x59\xcc\x8a\x00\x59\xcc\x8a\0" /* offset 209 */ + "\x00\x41\xca\xbe\x00\x41\xca\xbe\0" /* offset 218 */ + "\x00\xce\xa5\xcc\x93\x00\xce\xa5\xcc\x93\0" /* offset 227 */ + "\x00\xce\xa5\xcc\x93\xcc\x80\x00\xce\xa5\xcc\x93\xcc\x80\0" /* offset 238 */ + "\x00\xce\xa5\xcc\x93\xcc\x81\x00\xce\xa5\xcc\x93\xcc\x81\0" /* offset 253 */ + "\x00\xce\xa5\xcc\x93\xcd\x82\x00\xce\xa5\xcc\x93\xcd\x82\0" /* offset 268 */ + "\x00\xce\x91\xcd\x82\x00\xce\x91\xcd\x82\0" /* offset 283 */ + "\x00\xce\x97\xcd\x82\x00\xce\x97\xcd\x82\0" /* offset 294 */ + "\x00\xce\x99\xcc\x88\xcc\x80\x00\xce\x99\xcc\x88\xcc\x80\0" /* offset 305 */ + "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 320 */ + "\x00\xce\x99\xcd\x82\x00\xce\x99\xcd\x82\0" /* offset 335 */ + "\x00\xce\x99\xcc\x88\xcd\x82\x00\xce\x99\xcc\x88\xcd\x82\0" /* offset 346 */ + "\x00\xce\xa5\xcc\x88\xcc\x80\x00\xce\xa5\xcc\x88\xcc\x80\0" /* offset 361 */ + "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 376 */ + "\x00\xce\xa1\xcc\x93\x00\xce\xa1\xcc\x93\0" /* offset 391 */ + "\x00\xce\xa5\xcd\x82\x00\xce\xa5\xcd\x82\0" /* offset 402 */ + "\x00\xce\xa5\xcc\x88\xcd\x82\x00\xce\xa5\xcc\x88\xcd\x82\0" /* offset 413 */ + "\x00\xce\xa9\xcd\x82\x00\xce\xa9\xcd\x82\0" /* offset 428 */ + "\xe1\xbe\x88\xe1\xbc\x88\xce\x99\x00\xe1\xbe\x88\0" /* offset 439 */ + "\xe1\xbe\x89\xe1\xbc\x89\xce\x99\x00\xe1\xbe\x89\0" /* offset 452 */ + "\xe1\xbe\x8a\xe1\xbc\x8a\xce\x99\x00\xe1\xbe\x8a\0" /* offset 465 */ + "\xe1\xbe\x8b\xe1\xbc\x8b\xce\x99\x00\xe1\xbe\x8b\0" /* offset 478 */ + "\xe1\xbe\x8c\xe1\xbc\x8c\xce\x99\x00\xe1\xbe\x8c\0" /* offset 491 */ + "\xe1\xbe\x8d\xe1\xbc\x8d\xce\x99\x00\xe1\xbe\x8d\0" /* offset 504 */ + "\xe1\xbe\x8e\xe1\xbc\x8e\xce\x99\x00\xe1\xbe\x8e\0" /* offset 517 */ + "\xe1\xbe\x8f\xe1\xbc\x8f\xce\x99\x00\xe1\xbe\x8f\0" /* offset 530 */ + "\xe1\xbe\x80\x00\xe1\xbc\x88\xce\x99\0" /* offset 543 */ + "\xe1\xbe\x81\x00\xe1\xbc\x89\xce\x99\0" /* offset 553 */ + "\xe1\xbe\x82\x00\xe1\xbc\x8a\xce\x99\0" /* offset 563 */ + "\xe1\xbe\x83\x00\xe1\xbc\x8b\xce\x99\0" /* offset 573 */ + "\xe1\xbe\x84\x00\xe1\xbc\x8c\xce\x99\0" /* offset 583 */ + "\xe1\xbe\x85\x00\xe1\xbc\x8d\xce\x99\0" /* offset 593 */ + "\xe1\xbe\x86\x00\xe1\xbc\x8e\xce\x99\0" /* offset 603 */ + "\xe1\xbe\x87\x00\xe1\xbc\x8f\xce\x99\0" /* offset 613 */ + "\xe1\xbe\x98\xe1\xbc\xa8\xce\x99\x00\xe1\xbe\x98\0" /* offset 623 */ + "\xe1\xbe\x99\xe1\xbc\xa9\xce\x99\x00\xe1\xbe\x99\0" /* offset 636 */ + "\xe1\xbe\x9a\xe1\xbc\xaa\xce\x99\x00\xe1\xbe\x9a\0" /* offset 649 */ + "\xe1\xbe\x9b\xe1\xbc\xab\xce\x99\x00\xe1\xbe\x9b\0" /* offset 662 */ + "\xe1\xbe\x9c\xe1\xbc\xac\xce\x99\x00\xe1\xbe\x9c\0" /* offset 675 */ + "\xe1\xbe\x9d\xe1\xbc\xad\xce\x99\x00\xe1\xbe\x9d\0" /* offset 688 */ + "\xe1\xbe\x9e\xe1\xbc\xae\xce\x99\x00\xe1\xbe\x9e\0" /* offset 701 */ + "\xe1\xbe\x9f\xe1\xbc\xaf\xce\x99\x00\xe1\xbe\x9f\0" /* offset 714 */ + "\xe1\xbe\x90\x00\xe1\xbc\xa8\xce\x99\0" /* offset 727 */ + "\xe1\xbe\x91\x00\xe1\xbc\xa9\xce\x99\0" /* offset 737 */ + "\xe1\xbe\x92\x00\xe1\xbc\xaa\xce\x99\0" /* offset 747 */ + "\xe1\xbe\x93\x00\xe1\xbc\xab\xce\x99\0" /* offset 757 */ + "\xe1\xbe\x94\x00\xe1\xbc\xac\xce\x99\0" /* offset 767 */ + "\xe1\xbe\x95\x00\xe1\xbc\xad\xce\x99\0" /* offset 777 */ + "\xe1\xbe\x96\x00\xe1\xbc\xae\xce\x99\0" /* offset 787 */ + "\xe1\xbe\x97\x00\xe1\xbc\xaf\xce\x99\0" /* offset 797 */ + "\xe1\xbe\xa8\xe1\xbd\xa8\xce\x99\x00\xe1\xbe\xa8\0" /* offset 807 */ + "\xe1\xbe\xa9\xe1\xbd\xa9\xce\x99\x00\xe1\xbe\xa9\0" /* offset 820 */ + "\xe1\xbe\xaa\xe1\xbd\xaa\xce\x99\x00\xe1\xbe\xaa\0" /* offset 833 */ + "\xe1\xbe\xab\xe1\xbd\xab\xce\x99\x00\xe1\xbe\xab\0" /* offset 846 */ + "\xe1\xbe\xac\xe1\xbd\xac\xce\x99\x00\xe1\xbe\xac\0" /* offset 859 */ + "\xe1\xbe\xad\xe1\xbd\xad\xce\x99\x00\xe1\xbe\xad\0" /* offset 872 */ + "\xe1\xbe\xae\xe1\xbd\xae\xce\x99\x00\xe1\xbe\xae\0" /* offset 885 */ + "\xe1\xbe\xaf\xe1\xbd\xaf\xce\x99\x00\xe1\xbe\xaf\0" /* offset 898 */ + "\xe1\xbe\xa0\x00\xe1\xbd\xa8\xce\x99\0" /* offset 911 */ + "\xe1\xbe\xa1\x00\xe1\xbd\xa9\xce\x99\0" /* offset 921 */ + "\xe1\xbe\xa2\x00\xe1\xbd\xaa\xce\x99\0" /* offset 931 */ + "\xe1\xbe\xa3\x00\xe1\xbd\xab\xce\x99\0" /* offset 941 */ + "\xe1\xbe\xa4\x00\xe1\xbd\xac\xce\x99\0" /* offset 951 */ + "\xe1\xbe\xa5\x00\xe1\xbd\xad\xce\x99\0" /* offset 961 */ + "\xe1\xbe\xa6\x00\xe1\xbd\xae\xce\x99\0" /* offset 971 */ + "\xe1\xbe\xa7\x00\xe1\xbd\xaf\xce\x99\0" /* offset 981 */ + "\xe1\xbe\xbc\xce\x91\xce\x99\x00\xe1\xbe\xbc\0" /* offset 991 */ + "\xe1\xbe\xb3\x00\xce\x91\xce\x99\0" /* offset 1003 */ + "\xe1\xbf\x8c\xce\x97\xce\x99\x00\xe1\xbf\x8c\0" /* offset 1012 */ + "\xe1\xbf\x83\x00\xce\x97\xce\x99\0" /* offset 1024 */ + "\xe1\xbf\xbc\xce\xa9\xce\x99\x00\xe1\xbf\xbc\0" /* offset 1033 */ + "\xe1\xbf\xb3\x00\xce\xa9\xce\x99\0" /* offset 1045 */ + "\x00\xe1\xbe\xba\xce\x99\x00\xe1\xbe\xba\xcd\x85\0" /* offset 1054 */ + "\x00\xce\x86\xce\x99\x00\xce\x86\xcd\x85\0" /* offset 1067 */ + "\x00\xe1\xbf\x8a\xce\x99\x00\xe1\xbf\x8a\xcd\x85\0" /* offset 1078 */ + "\x00\xce\x89\xce\x99\x00\xce\x89\xcd\x85\0" /* offset 1091 */ + "\x00\xe1\xbf\xba\xce\x99\x00\xe1\xbf\xba\xcd\x85\0" /* offset 1102 */ + "\x00\xce\x8f\xce\x99\x00\xce\x8f\xcd\x85\0" /* offset 1115 */ + "\x00\xce\x91\xcd\x82\xce\x99\x00\xce\x91\xcd\x82\xcd\x85\0" /* offset 1126 */ + "\x00\xce\x97\xcd\x82\xce\x99\x00\xce\x97\xcd\x82\xcd\x85\0" /* offset 1141 */ + "\x00\xce\xa9\xcd\x82\xce\x99\x00\xce\xa9\xcd\x82\xcd\x85\0" /* offset 1156 */ }; /* Table of casefolding cases that can't be derived by lowercasing */ static const struct { - uint16_t ch; - char data[7]; + uint16_t ch; + char data[7]; } casefold_table[] = { - { 0x00b5, "\xce\xbc" }, - { 0x00df, "\x73\x73" }, - { 0x0130, "\x69\xcc\x87" }, - { 0x0149, "\xca\xbc\x6e" }, - { 0x017f, "\x73" }, - { 0x01f0, "\x6a\xcc\x8c" }, - { 0x0345, "\xce\xb9" }, - { 0x0390, "\xce\xb9\xcc\x88\xcc\x81" }, - { 0x03b0, "\xcf\x85\xcc\x88\xcc\x81" }, - { 0x03c2, "\xcf\x83" }, - { 0x03d0, "\xce\xb2" }, - { 0x03d1, "\xce\xb8" }, - { 0x03d5, "\xcf\x86" }, - { 0x03d6, "\xcf\x80" }, - { 0x03f0, "\xce\xba" }, - { 0x03f1, "\xcf\x81" }, - { 0x03f5, "\xce\xb5" }, - { 0x0587, "\xd5\xa5\xd6\x82" }, - { 0x1e96, "\x68\xcc\xb1" }, - { 0x1e97, "\x74\xcc\x88" }, - { 0x1e98, "\x77\xcc\x8a" }, - { 0x1e99, "\x79\xcc\x8a" }, - { 0x1e9a, "\x61\xca\xbe" }, - { 0x1e9b, "\xe1\xb9\xa1" }, - { 0x1e9e, "\x73\x73" }, - { 0x1f50, "\xcf\x85\xcc\x93" }, - { 0x1f52, "\xcf\x85\xcc\x93\xcc\x80" }, - { 0x1f54, "\xcf\x85\xcc\x93\xcc\x81" }, - { 0x1f56, "\xcf\x85\xcc\x93\xcd\x82" }, - { 0x1f80, "\xe1\xbc\x80\xce\xb9" }, - { 0x1f81, "\xe1\xbc\x81\xce\xb9" }, - { 0x1f82, "\xe1\xbc\x82\xce\xb9" }, - { 0x1f83, "\xe1\xbc\x83\xce\xb9" }, - { 0x1f84, "\xe1\xbc\x84\xce\xb9" }, - { 0x1f85, "\xe1\xbc\x85\xce\xb9" }, - { 0x1f86, "\xe1\xbc\x86\xce\xb9" }, - { 0x1f87, "\xe1\xbc\x87\xce\xb9" }, - { 0x1f88, "\xe1\xbc\x80\xce\xb9" }, - { 0x1f89, "\xe1\xbc\x81\xce\xb9" }, - { 0x1f8a, "\xe1\xbc\x82\xce\xb9" }, - { 0x1f8b, "\xe1\xbc\x83\xce\xb9" }, - { 0x1f8c, "\xe1\xbc\x84\xce\xb9" }, - { 0x1f8d, "\xe1\xbc\x85\xce\xb9" }, - { 0x1f8e, "\xe1\xbc\x86\xce\xb9" }, - { 0x1f8f, "\xe1\xbc\x87\xce\xb9" }, - { 0x1f90, "\xe1\xbc\xa0\xce\xb9" }, - { 0x1f91, "\xe1\xbc\xa1\xce\xb9" }, - { 0x1f92, "\xe1\xbc\xa2\xce\xb9" }, - { 0x1f93, "\xe1\xbc\xa3\xce\xb9" }, - { 0x1f94, "\xe1\xbc\xa4\xce\xb9" }, - { 0x1f95, "\xe1\xbc\xa5\xce\xb9" }, - { 0x1f96, "\xe1\xbc\xa6\xce\xb9" }, - { 0x1f97, "\xe1\xbc\xa7\xce\xb9" }, - { 0x1f98, "\xe1\xbc\xa0\xce\xb9" }, - { 0x1f99, "\xe1\xbc\xa1\xce\xb9" }, - { 0x1f9a, "\xe1\xbc\xa2\xce\xb9" }, - { 0x1f9b, "\xe1\xbc\xa3\xce\xb9" }, - { 0x1f9c, "\xe1\xbc\xa4\xce\xb9" }, - { 0x1f9d, "\xe1\xbc\xa5\xce\xb9" }, - { 0x1f9e, "\xe1\xbc\xa6\xce\xb9" }, - { 0x1f9f, "\xe1\xbc\xa7\xce\xb9" }, - { 0x1fa0, "\xe1\xbd\xa0\xce\xb9" }, - { 0x1fa1, "\xe1\xbd\xa1\xce\xb9" }, - { 0x1fa2, "\xe1\xbd\xa2\xce\xb9" }, - { 0x1fa3, "\xe1\xbd\xa3\xce\xb9" }, - { 0x1fa4, "\xe1\xbd\xa4\xce\xb9" }, - { 0x1fa5, "\xe1\xbd\xa5\xce\xb9" }, - { 0x1fa6, "\xe1\xbd\xa6\xce\xb9" }, - { 0x1fa7, "\xe1\xbd\xa7\xce\xb9" }, - { 0x1fa8, "\xe1\xbd\xa0\xce\xb9" }, - { 0x1fa9, "\xe1\xbd\xa1\xce\xb9" }, - { 0x1faa, "\xe1\xbd\xa2\xce\xb9" }, - { 0x1fab, "\xe1\xbd\xa3\xce\xb9" }, - { 0x1fac, "\xe1\xbd\xa4\xce\xb9" }, - { 0x1fad, "\xe1\xbd\xa5\xce\xb9" }, - { 0x1fae, "\xe1\xbd\xa6\xce\xb9" }, - { 0x1faf, "\xe1\xbd\xa7\xce\xb9" }, - { 0x1fb2, "\xe1\xbd\xb0\xce\xb9" }, - { 0x1fb3, "\xce\xb1\xce\xb9" }, - { 0x1fb4, "\xce\xac\xce\xb9" }, - { 0x1fb6, "\xce\xb1\xcd\x82" }, - { 0x1fb7, "\xce\xb1\xcd\x82\xce\xb9" }, - { 0x1fbc, "\xce\xb1\xce\xb9" }, - { 0x1fbe, "\xce\xb9" }, - { 0x1fc2, "\xe1\xbd\xb4\xce\xb9" }, - { 0x1fc3, "\xce\xb7\xce\xb9" }, - { 0x1fc4, "\xce\xae\xce\xb9" }, - { 0x1fc6, "\xce\xb7\xcd\x82" }, - { 0x1fc7, "\xce\xb7\xcd\x82\xce\xb9" }, - { 0x1fcc, "\xce\xb7\xce\xb9" }, - { 0x1fd2, "\xce\xb9\xcc\x88\xcc\x80" }, - { 0x1fd3, "\xce\xb9\xcc\x88\xcc\x81" }, - { 0x1fd6, "\xce\xb9\xcd\x82" }, - { 0x1fd7, "\xce\xb9\xcc\x88\xcd\x82" }, - { 0x1fe2, "\xcf\x85\xcc\x88\xcc\x80" }, - { 0x1fe3, "\xcf\x85\xcc\x88\xcc\x81" }, - { 0x1fe4, "\xcf\x81\xcc\x93" }, - { 0x1fe6, "\xcf\x85\xcd\x82" }, - { 0x1fe7, "\xcf\x85\xcc\x88\xcd\x82" }, - { 0x1ff2, "\xe1\xbd\xbc\xce\xb9" }, - { 0x1ff3, "\xcf\x89\xce\xb9" }, - { 0x1ff4, "\xcf\x8e\xce\xb9" }, - { 0x1ff6, "\xcf\x89\xcd\x82" }, - { 0x1ff7, "\xcf\x89\xcd\x82\xce\xb9" }, - { 0x1ffc, "\xcf\x89\xce\xb9" }, - { 0x2160, "\xe2\x85\xb0" }, - { 0x2161, "\xe2\x85\xb1" }, - { 0x2162, "\xe2\x85\xb2" }, - { 0x2163, "\xe2\x85\xb3" }, - { 0x2164, "\xe2\x85\xb4" }, - { 0x2165, "\xe2\x85\xb5" }, - { 0x2166, "\xe2\x85\xb6" }, - { 0x2167, "\xe2\x85\xb7" }, - { 0x2168, "\xe2\x85\xb8" }, - { 0x2169, "\xe2\x85\xb9" }, - { 0x216a, "\xe2\x85\xba" }, - { 0x216b, "\xe2\x85\xbb" }, - { 0x216c, "\xe2\x85\xbc" }, - { 0x216d, "\xe2\x85\xbd" }, - { 0x216e, "\xe2\x85\xbe" }, - { 0x216f, "\xe2\x85\xbf" }, - { 0x24b6, "\xe2\x93\x90" }, - { 0x24b7, "\xe2\x93\x91" }, - { 0x24b8, "\xe2\x93\x92" }, - { 0x24b9, "\xe2\x93\x93" }, - { 0x24ba, "\xe2\x93\x94" }, - { 0x24bb, "\xe2\x93\x95" }, - { 0x24bc, "\xe2\x93\x96" }, - { 0x24bd, "\xe2\x93\x97" }, - { 0x24be, "\xe2\x93\x98" }, - { 0x24bf, "\xe2\x93\x99" }, - { 0x24c0, "\xe2\x93\x9a" }, - { 0x24c1, "\xe2\x93\x9b" }, - { 0x24c2, "\xe2\x93\x9c" }, - { 0x24c3, "\xe2\x93\x9d" }, - { 0x24c4, "\xe2\x93\x9e" }, - { 0x24c5, "\xe2\x93\x9f" }, - { 0x24c6, "\xe2\x93\xa0" }, - { 0x24c7, "\xe2\x93\xa1" }, - { 0x24c8, "\xe2\x93\xa2" }, - { 0x24c9, "\xe2\x93\xa3" }, - { 0x24ca, "\xe2\x93\xa4" }, - { 0x24cb, "\xe2\x93\xa5" }, - { 0x24cc, "\xe2\x93\xa6" }, - { 0x24cd, "\xe2\x93\xa7" }, - { 0x24ce, "\xe2\x93\xa8" }, - { 0x24cf, "\xe2\x93\xa9" }, - { 0xfb00, "\x66\x66" }, - { 0xfb01, "\x66\x69" }, - { 0xfb02, "\x66\x6c" }, - { 0xfb03, "\x66\x66\x69" }, - { 0xfb04, "\x66\x66\x6c" }, - { 0xfb05, "\x73\x74" }, - { 0xfb06, "\x73\x74" }, - { 0xfb13, "\xd5\xb4\xd5\xb6" }, - { 0xfb14, "\xd5\xb4\xd5\xa5" }, - { 0xfb15, "\xd5\xb4\xd5\xab" }, - { 0xfb16, "\xd5\xbe\xd5\xb6" }, - { 0xfb17, "\xd5\xb4\xd5\xad" }, + { 0x00b5, "\xce\xbc" }, + { 0x00df, "\x73\x73" }, + { 0x0130, "\x69\xcc\x87" }, + { 0x0149, "\xca\xbc\x6e" }, + { 0x017f, "\x73" }, + { 0x01f0, "\x6a\xcc\x8c" }, + { 0x0345, "\xce\xb9" }, + { 0x0390, "\xce\xb9\xcc\x88\xcc\x81" }, + { 0x03b0, "\xcf\x85\xcc\x88\xcc\x81" }, + { 0x03c2, "\xcf\x83" }, + { 0x03d0, "\xce\xb2" }, + { 0x03d1, "\xce\xb8" }, + { 0x03d5, "\xcf\x86" }, + { 0x03d6, "\xcf\x80" }, + { 0x03f0, "\xce\xba" }, + { 0x03f1, "\xcf\x81" }, + { 0x03f5, "\xce\xb5" }, + { 0x0587, "\xd5\xa5\xd6\x82" }, + { 0x1e96, "\x68\xcc\xb1" }, + { 0x1e97, "\x74\xcc\x88" }, + { 0x1e98, "\x77\xcc\x8a" }, + { 0x1e99, "\x79\xcc\x8a" }, + { 0x1e9a, "\x61\xca\xbe" }, + { 0x1e9b, "\xe1\xb9\xa1" }, + { 0x1e9e, "\x73\x73" }, + { 0x1f50, "\xcf\x85\xcc\x93" }, + { 0x1f52, "\xcf\x85\xcc\x93\xcc\x80" }, + { 0x1f54, "\xcf\x85\xcc\x93\xcc\x81" }, + { 0x1f56, "\xcf\x85\xcc\x93\xcd\x82" }, + { 0x1f80, "\xe1\xbc\x80\xce\xb9" }, + { 0x1f81, "\xe1\xbc\x81\xce\xb9" }, + { 0x1f82, "\xe1\xbc\x82\xce\xb9" }, + { 0x1f83, "\xe1\xbc\x83\xce\xb9" }, + { 0x1f84, "\xe1\xbc\x84\xce\xb9" }, + { 0x1f85, "\xe1\xbc\x85\xce\xb9" }, + { 0x1f86, "\xe1\xbc\x86\xce\xb9" }, + { 0x1f87, "\xe1\xbc\x87\xce\xb9" }, + { 0x1f88, "\xe1\xbc\x80\xce\xb9" }, + { 0x1f89, "\xe1\xbc\x81\xce\xb9" }, + { 0x1f8a, "\xe1\xbc\x82\xce\xb9" }, + { 0x1f8b, "\xe1\xbc\x83\xce\xb9" }, + { 0x1f8c, "\xe1\xbc\x84\xce\xb9" }, + { 0x1f8d, "\xe1\xbc\x85\xce\xb9" }, + { 0x1f8e, "\xe1\xbc\x86\xce\xb9" }, + { 0x1f8f, "\xe1\xbc\x87\xce\xb9" }, + { 0x1f90, "\xe1\xbc\xa0\xce\xb9" }, + { 0x1f91, "\xe1\xbc\xa1\xce\xb9" }, + { 0x1f92, "\xe1\xbc\xa2\xce\xb9" }, + { 0x1f93, "\xe1\xbc\xa3\xce\xb9" }, + { 0x1f94, "\xe1\xbc\xa4\xce\xb9" }, + { 0x1f95, "\xe1\xbc\xa5\xce\xb9" }, + { 0x1f96, "\xe1\xbc\xa6\xce\xb9" }, + { 0x1f97, "\xe1\xbc\xa7\xce\xb9" }, + { 0x1f98, "\xe1\xbc\xa0\xce\xb9" }, + { 0x1f99, "\xe1\xbc\xa1\xce\xb9" }, + { 0x1f9a, "\xe1\xbc\xa2\xce\xb9" }, + { 0x1f9b, "\xe1\xbc\xa3\xce\xb9" }, + { 0x1f9c, "\xe1\xbc\xa4\xce\xb9" }, + { 0x1f9d, "\xe1\xbc\xa5\xce\xb9" }, + { 0x1f9e, "\xe1\xbc\xa6\xce\xb9" }, + { 0x1f9f, "\xe1\xbc\xa7\xce\xb9" }, + { 0x1fa0, "\xe1\xbd\xa0\xce\xb9" }, + { 0x1fa1, "\xe1\xbd\xa1\xce\xb9" }, + { 0x1fa2, "\xe1\xbd\xa2\xce\xb9" }, + { 0x1fa3, "\xe1\xbd\xa3\xce\xb9" }, + { 0x1fa4, "\xe1\xbd\xa4\xce\xb9" }, + { 0x1fa5, "\xe1\xbd\xa5\xce\xb9" }, + { 0x1fa6, "\xe1\xbd\xa6\xce\xb9" }, + { 0x1fa7, "\xe1\xbd\xa7\xce\xb9" }, + { 0x1fa8, "\xe1\xbd\xa0\xce\xb9" }, + { 0x1fa9, "\xe1\xbd\xa1\xce\xb9" }, + { 0x1faa, "\xe1\xbd\xa2\xce\xb9" }, + { 0x1fab, "\xe1\xbd\xa3\xce\xb9" }, + { 0x1fac, "\xe1\xbd\xa4\xce\xb9" }, + { 0x1fad, "\xe1\xbd\xa5\xce\xb9" }, + { 0x1fae, "\xe1\xbd\xa6\xce\xb9" }, + { 0x1faf, "\xe1\xbd\xa7\xce\xb9" }, + { 0x1fb2, "\xe1\xbd\xb0\xce\xb9" }, + { 0x1fb3, "\xce\xb1\xce\xb9" }, + { 0x1fb4, "\xce\xac\xce\xb9" }, + { 0x1fb6, "\xce\xb1\xcd\x82" }, + { 0x1fb7, "\xce\xb1\xcd\x82\xce\xb9" }, + { 0x1fbc, "\xce\xb1\xce\xb9" }, + { 0x1fbe, "\xce\xb9" }, + { 0x1fc2, "\xe1\xbd\xb4\xce\xb9" }, + { 0x1fc3, "\xce\xb7\xce\xb9" }, + { 0x1fc4, "\xce\xae\xce\xb9" }, + { 0x1fc6, "\xce\xb7\xcd\x82" }, + { 0x1fc7, "\xce\xb7\xcd\x82\xce\xb9" }, + { 0x1fcc, "\xce\xb7\xce\xb9" }, + { 0x1fd2, "\xce\xb9\xcc\x88\xcc\x80" }, + { 0x1fd3, "\xce\xb9\xcc\x88\xcc\x81" }, + { 0x1fd6, "\xce\xb9\xcd\x82" }, + { 0x1fd7, "\xce\xb9\xcc\x88\xcd\x82" }, + { 0x1fe2, "\xcf\x85\xcc\x88\xcc\x80" }, + { 0x1fe3, "\xcf\x85\xcc\x88\xcc\x81" }, + { 0x1fe4, "\xcf\x81\xcc\x93" }, + { 0x1fe6, "\xcf\x85\xcd\x82" }, + { 0x1fe7, "\xcf\x85\xcc\x88\xcd\x82" }, + { 0x1ff2, "\xe1\xbd\xbc\xce\xb9" }, + { 0x1ff3, "\xcf\x89\xce\xb9" }, + { 0x1ff4, "\xcf\x8e\xce\xb9" }, + { 0x1ff6, "\xcf\x89\xcd\x82" }, + { 0x1ff7, "\xcf\x89\xcd\x82\xce\xb9" }, + { 0x1ffc, "\xcf\x89\xce\xb9" }, + { 0x2160, "\xe2\x85\xb0" }, + { 0x2161, "\xe2\x85\xb1" }, + { 0x2162, "\xe2\x85\xb2" }, + { 0x2163, "\xe2\x85\xb3" }, + { 0x2164, "\xe2\x85\xb4" }, + { 0x2165, "\xe2\x85\xb5" }, + { 0x2166, "\xe2\x85\xb6" }, + { 0x2167, "\xe2\x85\xb7" }, + { 0x2168, "\xe2\x85\xb8" }, + { 0x2169, "\xe2\x85\xb9" }, + { 0x216a, "\xe2\x85\xba" }, + { 0x216b, "\xe2\x85\xbb" }, + { 0x216c, "\xe2\x85\xbc" }, + { 0x216d, "\xe2\x85\xbd" }, + { 0x216e, "\xe2\x85\xbe" }, + { 0x216f, "\xe2\x85\xbf" }, + { 0x24b6, "\xe2\x93\x90" }, + { 0x24b7, "\xe2\x93\x91" }, + { 0x24b8, "\xe2\x93\x92" }, + { 0x24b9, "\xe2\x93\x93" }, + { 0x24ba, "\xe2\x93\x94" }, + { 0x24bb, "\xe2\x93\x95" }, + { 0x24bc, "\xe2\x93\x96" }, + { 0x24bd, "\xe2\x93\x97" }, + { 0x24be, "\xe2\x93\x98" }, + { 0x24bf, "\xe2\x93\x99" }, + { 0x24c0, "\xe2\x93\x9a" }, + { 0x24c1, "\xe2\x93\x9b" }, + { 0x24c2, "\xe2\x93\x9c" }, + { 0x24c3, "\xe2\x93\x9d" }, + { 0x24c4, "\xe2\x93\x9e" }, + { 0x24c5, "\xe2\x93\x9f" }, + { 0x24c6, "\xe2\x93\xa0" }, + { 0x24c7, "\xe2\x93\xa1" }, + { 0x24c8, "\xe2\x93\xa2" }, + { 0x24c9, "\xe2\x93\xa3" }, + { 0x24ca, "\xe2\x93\xa4" }, + { 0x24cb, "\xe2\x93\xa5" }, + { 0x24cc, "\xe2\x93\xa6" }, + { 0x24cd, "\xe2\x93\xa7" }, + { 0x24ce, "\xe2\x93\xa8" }, + { 0x24cf, "\xe2\x93\xa9" }, + { 0xfb00, "\x66\x66" }, + { 0xfb01, "\x66\x69" }, + { 0xfb02, "\x66\x6c" }, + { 0xfb03, "\x66\x66\x69" }, + { 0xfb04, "\x66\x66\x6c" }, + { 0xfb05, "\x73\x74" }, + { 0xfb06, "\x73\x74" }, + { 0xfb13, "\xd5\xb4\xd5\xb6" }, + { 0xfb14, "\xd5\xb4\xd5\xa5" }, + { 0xfb15, "\xd5\xb4\xd5\xab" }, + { 0xfb16, "\xd5\xbe\xd5\xb6" }, + { 0xfb17, "\xd5\xb4\xd5\xad" }, }; #endif /* CHARTABLES_H */ diff --git a/src/core/util/unicode/guniprop.cpp b/src/core/util/unicode/guniprop.cpp index fa6287b7..03e60e15 100644 --- a/src/core/util/unicode/guniprop.cpp +++ b/src/core/util/unicode/guniprop.cpp @@ -16,7 +16,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public @@ -53,8 +53,8 @@ : G_UNICODE_UNASSIGNED)) -#define IS(Type, Class) (((guint)1 << (Type)) & (Class)) -#define OR(Type, Rest) (((guint)1 << (Type)) | (Rest)) +#define IS(Type, Class) (((guint)1 << (Type)) & (Class)) +#define OR(Type, Rest) (((guint)1 << (Type)) | (Rest)) /* Count the number of elements in an array. The array must be defined * as such; using this with a dynamically allocated array will give @@ -62,78 +62,78 @@ */ #define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) -#define ISALPHA(Type) IS ((Type), \ - OR (G_UNICODE_LOWERCASE_LETTER, \ - OR (G_UNICODE_UPPERCASE_LETTER, \ - OR (G_UNICODE_TITLECASE_LETTER, \ - OR (G_UNICODE_MODIFIER_LETTER, \ - OR (G_UNICODE_OTHER_LETTER, 0)))))) - -#define ISALDIGIT(Type) IS ((Type), \ - OR (G_UNICODE_DECIMAL_NUMBER, \ - OR (G_UNICODE_LETTER_NUMBER, \ - OR (G_UNICODE_OTHER_NUMBER, \ - OR (G_UNICODE_LOWERCASE_LETTER, \ - OR (G_UNICODE_UPPERCASE_LETTER, \ - OR (G_UNICODE_TITLECASE_LETTER, \ - OR (G_UNICODE_MODIFIER_LETTER, \ - OR (G_UNICODE_OTHER_LETTER, 0))))))))) - -#define ISMARK(Type) IS ((Type), \ - OR (G_UNICODE_NON_SPACING_MARK, \ - OR (G_UNICODE_COMBINING_MARK, \ - OR (G_UNICODE_ENCLOSING_MARK, 0)))) - -#define ISZEROWIDTHTYPE(Type) IS ((Type), \ - OR (G_UNICODE_NON_SPACING_MARK, \ - OR (G_UNICODE_ENCLOSING_MARK, \ - OR (G_UNICODE_FORMAT, 0)))) - -#define UTF8_COMPUTE(Char, Mask, Len) \ - if (Char < 128) \ - { \ - Len = 1; \ - Mask = 0x7f; \ - } \ - else if ((Char & 0xe0) == 0xc0) \ - { \ - Len = 2; \ - Mask = 0x1f; \ - } \ - else if ((Char & 0xf0) == 0xe0) \ - { \ - Len = 3; \ - Mask = 0x0f; \ - } \ - else if ((Char & 0xf8) == 0xf0) \ - { \ - Len = 4; \ - Mask = 0x07; \ - } \ - else if ((Char & 0xfc) == 0xf8) \ - { \ - Len = 5; \ - Mask = 0x03; \ - } \ - else if ((Char & 0xfe) == 0xfc) \ - { \ - Len = 6; \ - Mask = 0x01; \ - } \ - else \ +#define ISALPHA(Type) IS ((Type), \ + OR (G_UNICODE_LOWERCASE_LETTER, \ + OR (G_UNICODE_UPPERCASE_LETTER, \ + OR (G_UNICODE_TITLECASE_LETTER, \ + OR (G_UNICODE_MODIFIER_LETTER, \ + OR (G_UNICODE_OTHER_LETTER, 0)))))) + +#define ISALDIGIT(Type) IS ((Type), \ + OR (G_UNICODE_DECIMAL_NUMBER, \ + OR (G_UNICODE_LETTER_NUMBER, \ + OR (G_UNICODE_OTHER_NUMBER, \ + OR (G_UNICODE_LOWERCASE_LETTER, \ + OR (G_UNICODE_UPPERCASE_LETTER, \ + OR (G_UNICODE_TITLECASE_LETTER, \ + OR (G_UNICODE_MODIFIER_LETTER, \ + OR (G_UNICODE_OTHER_LETTER, 0))))))))) + +#define ISMARK(Type) IS ((Type), \ + OR (G_UNICODE_NON_SPACING_MARK, \ + OR (G_UNICODE_COMBINING_MARK, \ + OR (G_UNICODE_ENCLOSING_MARK, 0)))) + +#define ISZEROWIDTHTYPE(Type) IS ((Type), \ + OR (G_UNICODE_NON_SPACING_MARK, \ + OR (G_UNICODE_ENCLOSING_MARK, \ + OR (G_UNICODE_FORMAT, 0)))) + +#define UTF8_COMPUTE(Char, Mask, Len) \ + if (Char < 128) \ + { \ + Len = 1; \ + Mask = 0x7f; \ + } \ + else if ((Char & 0xe0) == 0xc0) \ + { \ + Len = 2; \ + Mask = 0x1f; \ + } \ + else if ((Char & 0xf0) == 0xe0) \ + { \ + Len = 3; \ + Mask = 0x0f; \ + } \ + else if ((Char & 0xf8) == 0xf0) \ + { \ + Len = 4; \ + Mask = 0x07; \ + } \ + else if ((Char & 0xfc) == 0xf8) \ + { \ + Len = 5; \ + Mask = 0x03; \ + } \ + else if ((Char & 0xfe) == 0xfc) \ + { \ + Len = 6; \ + Mask = 0x01; \ + } \ + else \ Len = -1; #define UTF8_GET(Result, Chars, Count, Mask, Len) \ - (Result) = (Chars)[0] & (Mask); \ - for ((Count) = 1; (Count) < (Len); ++(Count)) \ - { \ - if (((Chars)[(Count)] & 0xc0) != 0x80) \ - { \ - (Result) = -1; \ - break; \ - } \ - (Result) <<= 6; \ - (Result) |= ((Chars)[(Count)] & 0x3f); \ + (Result) = (Chars)[0] & (Mask); \ + for ((Count) = 1; (Count) < (Len); ++(Count)) \ + { \ + if (((Chars)[(Count)] & 0xc0) != 0x80) \ + { \ + (Result) = -1; \ + break; \ + } \ + (Result) <<= 6; \ + (Result) |= ((Chars)[(Count)] & 0x3f); \ } /** @@ -149,18 +149,18 @@ * Return value: the resulting character **/ gunichar -g_utf8_get_char (const gchar *p) -{ - int i, mask = 0, len; - gunichar result; - unsigned char c = (unsigned char) *p; - - UTF8_COMPUTE (c, mask, len); - if (len == -1) - return (gunichar)-1; - UTF8_GET (result, p, i, mask, len); - - return result; +g_utf8_get_char (const gchar* p) { + int i, mask = 0, len; + gunichar result; + unsigned char c = (unsigned char) *p; + + UTF8_COMPUTE (c, mask, len); + if (len == -1) { + return (gunichar)-1; + } + UTF8_GET (result, p, i, mask, len); + + return result; } /** @@ -174,9 +174,8 @@ g_utf8_get_char (const gchar *p) * Return value: %TRUE if @c is an alphanumeric character **/ gboolean -g_unichar_isalnum (gunichar c) -{ - return ISALDIGIT (TYPE (c)) ? true : false; +g_unichar_isalnum (gunichar c) { + return ISALDIGIT (TYPE (c)) ? true : false; } /** @@ -190,9 +189,8 @@ g_unichar_isalnum (gunichar c) * Return value: %TRUE if @c is an alphabetic character **/ gboolean -g_unichar_isalpha (gunichar c) -{ - return ISALPHA (TYPE (c)) ? true : false; +g_unichar_isalpha (gunichar c) { + return ISALPHA (TYPE (c)) ? true : false; } @@ -207,9 +205,8 @@ g_unichar_isalpha (gunichar c) * Return value: %TRUE if @c is a control character **/ gboolean -g_unichar_iscntrl (gunichar c) -{ - return TYPE (c) == G_UNICODE_CONTROL; +g_unichar_iscntrl (gunichar c) { + return TYPE (c) == G_UNICODE_CONTROL; } /** @@ -223,9 +220,8 @@ g_unichar_iscntrl (gunichar c) * Return value: %TRUE if @c is a digit **/ gboolean -g_unichar_isdigit (gunichar c) -{ - return TYPE (c) == G_UNICODE_DECIMAL_NUMBER; +g_unichar_isdigit (gunichar c) { + return TYPE (c) == G_UNICODE_DECIMAL_NUMBER; } @@ -242,15 +238,14 @@ g_unichar_isdigit (gunichar c) * Return value: %TRUE if @c is printable unless it's a space **/ gboolean -g_unichar_isgraph (gunichar c) -{ - return !IS (TYPE(c), - OR (G_UNICODE_CONTROL, - OR (G_UNICODE_FORMAT, - OR (G_UNICODE_UNASSIGNED, - OR (G_UNICODE_SURROGATE, - OR (G_UNICODE_SPACE_SEPARATOR, - 0)))))); +g_unichar_isgraph (gunichar c) { + return !IS (TYPE(c), + OR (G_UNICODE_CONTROL, + OR (G_UNICODE_FORMAT, + OR (G_UNICODE_UNASSIGNED, + OR (G_UNICODE_SURROGATE, + OR (G_UNICODE_SPACE_SEPARATOR, + 0)))))); } /** @@ -264,9 +259,8 @@ g_unichar_isgraph (gunichar c) * Return value: %TRUE if @c is a lowercase letter **/ gboolean -g_unichar_islower (gunichar c) -{ - return TYPE (c) == G_UNICODE_LOWERCASE_LETTER; +g_unichar_islower (gunichar c) { + return TYPE (c) == G_UNICODE_LOWERCASE_LETTER; } @@ -282,14 +276,13 @@ g_unichar_islower (gunichar c) * Return value: %TRUE if @c is printable **/ gboolean -g_unichar_isprint (gunichar c) -{ - return !IS (TYPE(c), - OR (G_UNICODE_CONTROL, - OR (G_UNICODE_FORMAT, - OR (G_UNICODE_UNASSIGNED, - OR (G_UNICODE_SURROGATE, - 0))))); +g_unichar_isprint (gunichar c) { + return !IS (TYPE(c), + OR (G_UNICODE_CONTROL, + OR (G_UNICODE_FORMAT, + OR (G_UNICODE_UNASSIGNED, + OR (G_UNICODE_SURROGATE, + 0))))); } /** @@ -303,21 +296,20 @@ g_unichar_isprint (gunichar c) * Return value: %TRUE if @c is a punctuation or symbol character **/ gboolean -g_unichar_ispunct (gunichar c) -{ - return IS (TYPE(c), - OR (G_UNICODE_CONNECT_PUNCTUATION, - OR (G_UNICODE_DASH_PUNCTUATION, - OR (G_UNICODE_CLOSE_PUNCTUATION, - OR (G_UNICODE_FINAL_PUNCTUATION, - OR (G_UNICODE_INITIAL_PUNCTUATION, - OR (G_UNICODE_OTHER_PUNCTUATION, - OR (G_UNICODE_OPEN_PUNCTUATION, - OR (G_UNICODE_CURRENCY_SYMBOL, - OR (G_UNICODE_MODIFIER_SYMBOL, - OR (G_UNICODE_MATH_SYMBOL, - OR (G_UNICODE_OTHER_SYMBOL, - 0)))))))))))) ? true : false; +g_unichar_ispunct (gunichar c) { + return IS (TYPE(c), + OR (G_UNICODE_CONNECT_PUNCTUATION, + OR (G_UNICODE_DASH_PUNCTUATION, + OR (G_UNICODE_CLOSE_PUNCTUATION, + OR (G_UNICODE_FINAL_PUNCTUATION, + OR (G_UNICODE_INITIAL_PUNCTUATION, + OR (G_UNICODE_OTHER_PUNCTUATION, + OR (G_UNICODE_OPEN_PUNCTUATION, + OR (G_UNICODE_CURRENCY_SYMBOL, + OR (G_UNICODE_MODIFIER_SYMBOL, + OR (G_UNICODE_MATH_SYMBOL, + OR (G_UNICODE_OTHER_SYMBOL, + 0)))))))))))) ? true : false; } /** @@ -335,27 +327,24 @@ g_unichar_ispunct (gunichar c) * Return value: %TRUE if @c is a space character **/ gboolean -g_unichar_isspace (gunichar c) -{ - switch (c) - { - /* special-case these since Unicode thinks they are not spaces */ +g_unichar_isspace (gunichar c) { + switch (c) { + /* special-case these since Unicode thinks they are not spaces */ case '\t': case '\n': case '\r': case '\f': - return true; - break; - - default: - { - return IS (TYPE(c), - OR (G_UNICODE_SPACE_SEPARATOR, - OR (G_UNICODE_LINE_SEPARATOR, - OR (G_UNICODE_PARAGRAPH_SEPARATOR, - 0)))) ? true : false; - } - break; + return true; + break; + + default: { + return IS (TYPE(c), + OR (G_UNICODE_SPACE_SEPARATOR, + OR (G_UNICODE_LINE_SEPARATOR, + OR (G_UNICODE_PARAGRAPH_SEPARATOR, + 0)))) ? true : false; + } + break; } } @@ -378,9 +367,8 @@ g_unichar_isspace (gunichar c) * Since: 2.14 **/ gboolean -g_unichar_ismark (gunichar c) -{ - return ISMARK (TYPE (c)) ? true : false; +g_unichar_ismark (gunichar c) { + return ISMARK (TYPE (c)) ? true : false; } /** @@ -392,9 +380,8 @@ g_unichar_ismark (gunichar c) * Return value: %TRUE if @c is an uppercase character **/ gboolean -g_unichar_isupper (gunichar c) -{ - return TYPE (c) == G_UNICODE_UPPERCASE_LETTER; +g_unichar_isupper (gunichar c) { + return TYPE (c) == G_UNICODE_UPPERCASE_LETTER; } /** @@ -411,13 +398,13 @@ g_unichar_isupper (gunichar c) * Return value: %TRUE if the character is titlecase **/ gboolean -g_unichar_istitle (gunichar c) -{ - unsigned int i; - for (i = 0; i < G_N_ELEMENTS (title_table); ++i) - if (title_table[i][0] == c) - return true; - return false; +g_unichar_istitle (gunichar c) { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + if (title_table[i][0] == c) { + return true; + } + return false; } /** @@ -429,11 +416,10 @@ g_unichar_istitle (gunichar c) * Return value: %TRUE if the character is a hexadecimal digit **/ gboolean -g_unichar_isxdigit (gunichar c) -{ - return ((c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F') - || (TYPE (c) == G_UNICODE_DECIMAL_NUMBER)); +g_unichar_isxdigit (gunichar c) { + return ((c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F') + || (TYPE (c) == G_UNICODE_DECIMAL_NUMBER)); } /** @@ -446,12 +432,11 @@ g_unichar_isxdigit (gunichar c) * Return value: %TRUE if the character has an assigned value **/ gboolean -g_unichar_isdefined (gunichar c) -{ - return !IS (TYPE(c), - OR (G_UNICODE_UNASSIGNED, - OR (G_UNICODE_SURROGATE, - 0))); +g_unichar_isdefined (gunichar c) { + return !IS (TYPE(c), + OR (G_UNICODE_UNASSIGNED, + OR (G_UNICODE_SURROGATE, + 0))); } /** @@ -465,33 +450,28 @@ g_unichar_isdefined (gunichar c) * or has no upper case equivalent @c is returned unchanged. **/ gunichar -g_unichar_toupper (gunichar c) -{ - int t = TYPE (c); - if (t == G_UNICODE_LOWERCASE_LETTER) - { - gunichar val = ATTTABLE (c >> 8, c & 0xff); - if (val >= 0x1000000) - { - const gchar *p = special_case_table + val - 0x1000000; - val = g_utf8_get_char (p); - } - /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR, - * do not have an uppercase equivalent, in which case val will be - * zero. - */ - return val ? val : c; +g_unichar_toupper (gunichar c) { + int t = TYPE (c); + if (t == G_UNICODE_LOWERCASE_LETTER) { + gunichar val = ATTTABLE (c >> 8, c & 0xff); + if (val >= 0x1000000) { + const gchar* p = special_case_table + val - 0x1000000; + val = g_utf8_get_char (p); + } + /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR, + * do not have an uppercase equivalent, in which case val will be + * zero. + */ + return val ? val : c; + } else if (t == G_UNICODE_TITLECASE_LETTER) { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) { + if (title_table[i][0] == c) { + return title_table[i][1]; + } + } } - else if (t == G_UNICODE_TITLECASE_LETTER) - { - unsigned int i; - for (i = 0; i < G_N_ELEMENTS (title_table); ++i) - { - if (title_table[i][0] == c) - return title_table[i][1]; - } - } - return c; + return c; } /** @@ -505,34 +485,27 @@ g_unichar_toupper (gunichar c) * or has no lowercase equivalent @c is returned unchanged. **/ gunichar -g_unichar_tolower (gunichar c) -{ - int t = TYPE (c); - if (t == G_UNICODE_UPPERCASE_LETTER) - { - gunichar val = ATTTABLE (c >> 8, c & 0xff); - if (val >= 0x1000000) - { - const gchar *p = special_case_table + val - 0x1000000; - return g_utf8_get_char (p); - } - else - { - /* Not all uppercase letters are guaranteed to have a lowercase - * equivalent. If this is the case, val will be zero. */ - return val ? val : c; - } - } - else if (t == G_UNICODE_TITLECASE_LETTER) - { - unsigned int i; - for (i = 0; i < G_N_ELEMENTS (title_table); ++i) - { - if (title_table[i][0] == c) - return title_table[i][2]; - } +g_unichar_tolower (gunichar c) { + int t = TYPE (c); + if (t == G_UNICODE_UPPERCASE_LETTER) { + gunichar val = ATTTABLE (c >> 8, c & 0xff); + if (val >= 0x1000000) { + const gchar* p = special_case_table + val - 0x1000000; + return g_utf8_get_char (p); + } else { + /* Not all uppercase letters are guaranteed to have a lowercase + * equivalent. If this is the case, val will be zero. */ + return val ? val : c; + } + } else if (t == G_UNICODE_TITLECASE_LETTER) { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) { + if (title_table[i][0] == c) { + return title_table[i][2]; + } + } } - return c; + return c; } /** @@ -546,20 +519,20 @@ g_unichar_tolower (gunichar c) * @c is returned unchanged. **/ gunichar -g_unichar_totitle (gunichar c) -{ - unsigned int i; - for (i = 0; i < G_N_ELEMENTS (title_table); ++i) - { - if (title_table[i][0] == c || title_table[i][1] == c - || title_table[i][2] == c) - return title_table[i][0]; +g_unichar_totitle (gunichar c) { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) { + if (title_table[i][0] == c || title_table[i][1] == c + || title_table[i][2] == c) { + return title_table[i][0]; + } } - if (TYPE (c) == G_UNICODE_LOWERCASE_LETTER) - return g_unichar_toupper (c); + if (TYPE (c) == G_UNICODE_LOWERCASE_LETTER) { + return g_unichar_toupper (c); + } - return c; + return c; } /** @@ -573,11 +546,11 @@ g_unichar_totitle (gunichar c) * g_unichar_isdigit()), its numeric value. Otherwise, -1. **/ int -g_unichar_digit_value (gunichar c) -{ - if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER) - return ATTTABLE (c >> 8, c & 0xff); - return -1; +g_unichar_digit_value (gunichar c) { + if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER) { + return ATTTABLE (c >> 8, c & 0xff); + } + return -1; } /** @@ -591,15 +564,17 @@ g_unichar_digit_value (gunichar c) * g_unichar_isxdigit()), its numeric value. Otherwise, -1. **/ int -g_unichar_xdigit_value (gunichar c) -{ - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER) - return ATTTABLE (c >> 8, c & 0xff); - return -1; +g_unichar_xdigit_value (gunichar c) { + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER) { + return ATTTABLE (c >> 8, c & 0xff); + } + return -1; } /** @@ -611,7 +586,6 @@ g_unichar_xdigit_value (gunichar c) * Return value: the type of the character. **/ GUnicodeType -g_unichar_type (gunichar c) -{ - return (GUnicodeType)TYPE (c); +g_unichar_type (gunichar c) { + return (GUnicodeType)TYPE (c); } diff --git a/src/core/util/unicode/guniprop.h b/src/core/util/unicode/guniprop.h index 51b5559e..9bf164bd 100644 --- a/src/core/util/unicode/guniprop.h +++ b/src/core/util/unicode/guniprop.h @@ -16,7 +16,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public @@ -40,38 +40,37 @@ typedef size_t gssize; /* These are the possible character classifications. * See http://www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values */ -typedef enum -{ - G_UNICODE_CONTROL, - G_UNICODE_FORMAT, - G_UNICODE_UNASSIGNED, - G_UNICODE_PRIVATE_USE, - G_UNICODE_SURROGATE, - G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER, - G_UNICODE_TITLECASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_COMBINING_MARK, - G_UNICODE_ENCLOSING_MARK, - G_UNICODE_NON_SPACING_MARK, - G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_LETTER_NUMBER, - G_UNICODE_OTHER_NUMBER, - G_UNICODE_CONNECT_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, - G_UNICODE_LINE_SEPARATOR, - G_UNICODE_PARAGRAPH_SEPARATOR, - G_UNICODE_SPACE_SEPARATOR +typedef enum { + G_UNICODE_CONTROL, + G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, + G_UNICODE_PRIVATE_USE, + G_UNICODE_SURROGATE, + G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, + G_UNICODE_TITLECASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_COMBINING_MARK, + G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, + G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_LETTER_NUMBER, + G_UNICODE_OTHER_NUMBER, + G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, + G_UNICODE_LINE_SEPARATOR, + G_UNICODE_PARAGRAPH_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR } GUnicodeType; /* These are the possible line break classifications. @@ -79,135 +78,134 @@ typedef enum * Implementations may regard unknown values like G_UNICODE_BREAK_UNKNOWN * See http://www.unicode.org/unicode/reports/tr14/ */ -typedef enum -{ - G_UNICODE_BREAK_MANDATORY, - G_UNICODE_BREAK_CARRIAGE_RETURN, - G_UNICODE_BREAK_LINE_FEED, - G_UNICODE_BREAK_COMBINING_MARK, - G_UNICODE_BREAK_SURROGATE, - G_UNICODE_BREAK_ZERO_WIDTH_SPACE, - G_UNICODE_BREAK_INSEPARABLE, - G_UNICODE_BREAK_NON_BREAKING_GLUE, - G_UNICODE_BREAK_CONTINGENT, - G_UNICODE_BREAK_SPACE, - G_UNICODE_BREAK_AFTER, - G_UNICODE_BREAK_BEFORE, - G_UNICODE_BREAK_BEFORE_AND_AFTER, - G_UNICODE_BREAK_HYPHEN, - G_UNICODE_BREAK_NON_STARTER, - G_UNICODE_BREAK_OPEN_PUNCTUATION, - G_UNICODE_BREAK_CLOSE_PUNCTUATION, - G_UNICODE_BREAK_QUOTATION, - G_UNICODE_BREAK_EXCLAMATION, - G_UNICODE_BREAK_IDEOGRAPHIC, - G_UNICODE_BREAK_NUMERIC, - G_UNICODE_BREAK_INFIX_SEPARATOR, - G_UNICODE_BREAK_SYMBOL, - G_UNICODE_BREAK_ALPHABETIC, - G_UNICODE_BREAK_PREFIX, - G_UNICODE_BREAK_POSTFIX, - G_UNICODE_BREAK_COMPLEX_CONTEXT, - G_UNICODE_BREAK_AMBIGUOUS, - G_UNICODE_BREAK_UNKNOWN, - G_UNICODE_BREAK_NEXT_LINE, - G_UNICODE_BREAK_WORD_JOINER, - G_UNICODE_BREAK_HANGUL_L_JAMO, - G_UNICODE_BREAK_HANGUL_V_JAMO, - G_UNICODE_BREAK_HANGUL_T_JAMO, - G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, - G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE +typedef enum { + G_UNICODE_BREAK_MANDATORY, + G_UNICODE_BREAK_CARRIAGE_RETURN, + G_UNICODE_BREAK_LINE_FEED, + G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_SURROGATE, + G_UNICODE_BREAK_ZERO_WIDTH_SPACE, + G_UNICODE_BREAK_INSEPARABLE, + G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_CONTINGENT, + G_UNICODE_BREAK_SPACE, + G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_BEFORE_AND_AFTER, + G_UNICODE_BREAK_HYPHEN, + G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_SYMBOL, + G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NEXT_LINE, + G_UNICODE_BREAK_WORD_JOINER, + G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE } GUnicodeBreakType; -typedef enum -{ /* ISO 15924 code */ - G_UNICODE_SCRIPT_INVALID_CODE = -1, - G_UNICODE_SCRIPT_COMMON = 0, /* Zyyy */ - G_UNICODE_SCRIPT_INHERITED, /* Qaai */ - G_UNICODE_SCRIPT_ARABIC, /* Arab */ - G_UNICODE_SCRIPT_ARMENIAN, /* Armn */ - G_UNICODE_SCRIPT_BENGALI, /* Beng */ - G_UNICODE_SCRIPT_BOPOMOFO, /* Bopo */ - G_UNICODE_SCRIPT_CHEROKEE, /* Cher */ - G_UNICODE_SCRIPT_COPTIC, /* Qaac */ - G_UNICODE_SCRIPT_CYRILLIC, /* Cyrl (Cyrs) */ - G_UNICODE_SCRIPT_DESERET, /* Dsrt */ - G_UNICODE_SCRIPT_DEVANAGARI, /* Deva */ - G_UNICODE_SCRIPT_ETHIOPIC, /* Ethi */ - G_UNICODE_SCRIPT_GEORGIAN, /* Geor (Geon, Geoa) */ - G_UNICODE_SCRIPT_GOTHIC, /* Goth */ - G_UNICODE_SCRIPT_GREEK, /* Grek */ - G_UNICODE_SCRIPT_GUJARATI, /* Gujr */ - G_UNICODE_SCRIPT_GURMUKHI, /* Guru */ - G_UNICODE_SCRIPT_HAN, /* Hani */ - G_UNICODE_SCRIPT_HANGUL, /* Hang */ - G_UNICODE_SCRIPT_HEBREW, /* Hebr */ - G_UNICODE_SCRIPT_HIRAGANA, /* Hira */ - G_UNICODE_SCRIPT_KANNADA, /* Knda */ - G_UNICODE_SCRIPT_KATAKANA, /* Kana */ - G_UNICODE_SCRIPT_KHMER, /* Khmr */ - G_UNICODE_SCRIPT_LAO, /* Laoo */ - G_UNICODE_SCRIPT_LATIN, /* Latn (Latf, Latg) */ - G_UNICODE_SCRIPT_MALAYALAM, /* Mlym */ - G_UNICODE_SCRIPT_MONGOLIAN, /* Mong */ - G_UNICODE_SCRIPT_MYANMAR, /* Mymr */ - G_UNICODE_SCRIPT_OGHAM, /* Ogam */ - G_UNICODE_SCRIPT_OLD_ITALIC, /* Ital */ - G_UNICODE_SCRIPT_ORIYA, /* Orya */ - G_UNICODE_SCRIPT_RUNIC, /* Runr */ - G_UNICODE_SCRIPT_SINHALA, /* Sinh */ - G_UNICODE_SCRIPT_SYRIAC, /* Syrc (Syrj, Syrn, Syre) */ - G_UNICODE_SCRIPT_TAMIL, /* Taml */ - G_UNICODE_SCRIPT_TELUGU, /* Telu */ - G_UNICODE_SCRIPT_THAANA, /* Thaa */ - G_UNICODE_SCRIPT_THAI, /* Thai */ - G_UNICODE_SCRIPT_TIBETAN, /* Tibt */ - G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */ - G_UNICODE_SCRIPT_YI, /* Yiii */ - G_UNICODE_SCRIPT_TAGALOG, /* Tglg */ - G_UNICODE_SCRIPT_HANUNOO, /* Hano */ - G_UNICODE_SCRIPT_BUHID, /* Buhd */ - G_UNICODE_SCRIPT_TAGBANWA, /* Tagb */ +typedef enum { + /* ISO 15924 code */ + G_UNICODE_SCRIPT_INVALID_CODE = -1, + G_UNICODE_SCRIPT_COMMON = 0, /* Zyyy */ + G_UNICODE_SCRIPT_INHERITED, /* Qaai */ + G_UNICODE_SCRIPT_ARABIC, /* Arab */ + G_UNICODE_SCRIPT_ARMENIAN, /* Armn */ + G_UNICODE_SCRIPT_BENGALI, /* Beng */ + G_UNICODE_SCRIPT_BOPOMOFO, /* Bopo */ + G_UNICODE_SCRIPT_CHEROKEE, /* Cher */ + G_UNICODE_SCRIPT_COPTIC, /* Qaac */ + G_UNICODE_SCRIPT_CYRILLIC, /* Cyrl (Cyrs) */ + G_UNICODE_SCRIPT_DESERET, /* Dsrt */ + G_UNICODE_SCRIPT_DEVANAGARI, /* Deva */ + G_UNICODE_SCRIPT_ETHIOPIC, /* Ethi */ + G_UNICODE_SCRIPT_GEORGIAN, /* Geor (Geon, Geoa) */ + G_UNICODE_SCRIPT_GOTHIC, /* Goth */ + G_UNICODE_SCRIPT_GREEK, /* Grek */ + G_UNICODE_SCRIPT_GUJARATI, /* Gujr */ + G_UNICODE_SCRIPT_GURMUKHI, /* Guru */ + G_UNICODE_SCRIPT_HAN, /* Hani */ + G_UNICODE_SCRIPT_HANGUL, /* Hang */ + G_UNICODE_SCRIPT_HEBREW, /* Hebr */ + G_UNICODE_SCRIPT_HIRAGANA, /* Hira */ + G_UNICODE_SCRIPT_KANNADA, /* Knda */ + G_UNICODE_SCRIPT_KATAKANA, /* Kana */ + G_UNICODE_SCRIPT_KHMER, /* Khmr */ + G_UNICODE_SCRIPT_LAO, /* Laoo */ + G_UNICODE_SCRIPT_LATIN, /* Latn (Latf, Latg) */ + G_UNICODE_SCRIPT_MALAYALAM, /* Mlym */ + G_UNICODE_SCRIPT_MONGOLIAN, /* Mong */ + G_UNICODE_SCRIPT_MYANMAR, /* Mymr */ + G_UNICODE_SCRIPT_OGHAM, /* Ogam */ + G_UNICODE_SCRIPT_OLD_ITALIC, /* Ital */ + G_UNICODE_SCRIPT_ORIYA, /* Orya */ + G_UNICODE_SCRIPT_RUNIC, /* Runr */ + G_UNICODE_SCRIPT_SINHALA, /* Sinh */ + G_UNICODE_SCRIPT_SYRIAC, /* Syrc (Syrj, Syrn, Syre) */ + G_UNICODE_SCRIPT_TAMIL, /* Taml */ + G_UNICODE_SCRIPT_TELUGU, /* Telu */ + G_UNICODE_SCRIPT_THAANA, /* Thaa */ + G_UNICODE_SCRIPT_THAI, /* Thai */ + G_UNICODE_SCRIPT_TIBETAN, /* Tibt */ + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */ + G_UNICODE_SCRIPT_YI, /* Yiii */ + G_UNICODE_SCRIPT_TAGALOG, /* Tglg */ + G_UNICODE_SCRIPT_HANUNOO, /* Hano */ + G_UNICODE_SCRIPT_BUHID, /* Buhd */ + G_UNICODE_SCRIPT_TAGBANWA, /* Tagb */ - /* Unicode-4.0 additions */ - G_UNICODE_SCRIPT_BRAILLE, /* Brai */ - G_UNICODE_SCRIPT_CYPRIOT, /* Cprt */ - G_UNICODE_SCRIPT_LIMBU, /* Limb */ - G_UNICODE_SCRIPT_OSMANYA, /* Osma */ - G_UNICODE_SCRIPT_SHAVIAN, /* Shaw */ - G_UNICODE_SCRIPT_LINEAR_B, /* Linb */ - G_UNICODE_SCRIPT_TAI_LE, /* Tale */ - G_UNICODE_SCRIPT_UGARITIC, /* Ugar */ + /* Unicode-4.0 additions */ + G_UNICODE_SCRIPT_BRAILLE, /* Brai */ + G_UNICODE_SCRIPT_CYPRIOT, /* Cprt */ + G_UNICODE_SCRIPT_LIMBU, /* Limb */ + G_UNICODE_SCRIPT_OSMANYA, /* Osma */ + G_UNICODE_SCRIPT_SHAVIAN, /* Shaw */ + G_UNICODE_SCRIPT_LINEAR_B, /* Linb */ + G_UNICODE_SCRIPT_TAI_LE, /* Tale */ + G_UNICODE_SCRIPT_UGARITIC, /* Ugar */ - /* Unicode-4.1 additions */ - G_UNICODE_SCRIPT_NEW_TAI_LUE, /* Talu */ - G_UNICODE_SCRIPT_BUGINESE, /* Bugi */ - G_UNICODE_SCRIPT_GLAGOLITIC, /* Glag */ - G_UNICODE_SCRIPT_TIFINAGH, /* Tfng */ - G_UNICODE_SCRIPT_SYLOTI_NAGRI, /* Sylo */ - G_UNICODE_SCRIPT_OLD_PERSIAN, /* Xpeo */ - G_UNICODE_SCRIPT_KHAROSHTHI, /* Khar */ + /* Unicode-4.1 additions */ + G_UNICODE_SCRIPT_NEW_TAI_LUE, /* Talu */ + G_UNICODE_SCRIPT_BUGINESE, /* Bugi */ + G_UNICODE_SCRIPT_GLAGOLITIC, /* Glag */ + G_UNICODE_SCRIPT_TIFINAGH, /* Tfng */ + G_UNICODE_SCRIPT_SYLOTI_NAGRI, /* Sylo */ + G_UNICODE_SCRIPT_OLD_PERSIAN, /* Xpeo */ + G_UNICODE_SCRIPT_KHAROSHTHI, /* Khar */ - /* Unicode-5.0 additions */ - G_UNICODE_SCRIPT_UNKNOWN, /* Zzzz */ - G_UNICODE_SCRIPT_BALINESE, /* Bali */ - G_UNICODE_SCRIPT_CUNEIFORM, /* Xsux */ - G_UNICODE_SCRIPT_PHOENICIAN, /* Phnx */ - G_UNICODE_SCRIPT_PHAGS_PA, /* Phag */ - G_UNICODE_SCRIPT_NKO, /* Nkoo */ + /* Unicode-5.0 additions */ + G_UNICODE_SCRIPT_UNKNOWN, /* Zzzz */ + G_UNICODE_SCRIPT_BALINESE, /* Bali */ + G_UNICODE_SCRIPT_CUNEIFORM, /* Xsux */ + G_UNICODE_SCRIPT_PHOENICIAN, /* Phnx */ + G_UNICODE_SCRIPT_PHAGS_PA, /* Phag */ + G_UNICODE_SCRIPT_NKO, /* Nkoo */ - /* Unicode-5.1 additions */ - G_UNICODE_SCRIPT_KAYAH_LI, /* Kali */ - G_UNICODE_SCRIPT_LEPCHA, /* Lepc */ - G_UNICODE_SCRIPT_REJANG, /* Rjng */ - G_UNICODE_SCRIPT_SUNDANESE, /* Sund */ - G_UNICODE_SCRIPT_SAURASHTRA, /* Saur */ - G_UNICODE_SCRIPT_CHAM, /* Cham */ - G_UNICODE_SCRIPT_OL_CHIKI, /* Olck */ - G_UNICODE_SCRIPT_VAI, /* Vaii */ - G_UNICODE_SCRIPT_CARIAN, /* Cari */ - G_UNICODE_SCRIPT_LYCIAN, /* Lyci */ - G_UNICODE_SCRIPT_LYDIAN /* Lydi */ + /* Unicode-5.1 additions */ + G_UNICODE_SCRIPT_KAYAH_LI, /* Kali */ + G_UNICODE_SCRIPT_LEPCHA, /* Lepc */ + G_UNICODE_SCRIPT_REJANG, /* Rjng */ + G_UNICODE_SCRIPT_SUNDANESE, /* Sund */ + G_UNICODE_SCRIPT_SAURASHTRA, /* Saur */ + G_UNICODE_SCRIPT_CHAM, /* Cham */ + G_UNICODE_SCRIPT_OL_CHIKI, /* Olck */ + G_UNICODE_SCRIPT_VAI, /* Vaii */ + G_UNICODE_SCRIPT_CARIAN, /* Cari */ + G_UNICODE_SCRIPT_LYCIAN, /* Lyci */ + G_UNICODE_SCRIPT_LYDIAN /* Lydi */ } GUnicodeScript; #include "gunichartables.h" diff --git a/src/demo/deletefiles/main.cpp b/src/demo/deletefiles/main.cpp index ec91791c..eb42c984 100644 --- a/src/demo/deletefiles/main.cpp +++ b/src/demo/deletefiles/main.cpp @@ -13,16 +13,13 @@ using namespace Lucene; /// Deletes documents from an index that do not contain a term. -int main(int argc, char* argv[]) -{ - if (argc == 1) - { +int main(int argc, char* argv[]) { + if (argc == 1) { std::wcout << L"Usage: deletefiles.exe \n"; return 1; } - try - { + try { DirectoryPtr directory = FSDirectory::open(StringUtils::toUnicode(argv[1])); // we don't want read-only because we are about to delete @@ -35,9 +32,7 @@ int main(int argc, char* argv[]) reader->close(); directory->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { std::wcout << L"Exception: " << e.getError() << L"\n"; return 1; } diff --git a/src/demo/indexfiles/main.cpp b/src/demo/indexfiles/main.cpp index 80b72f7e..f3b77d18 100644 --- a/src/demo/indexfiles/main.cpp +++ b/src/demo/indexfiles/main.cpp @@ -16,8 +16,7 @@ using namespace Lucene; int32_t docNumber = 0; -DocumentPtr fileDocument(const String& docFile) -{ +DocumentPtr fileDocument(const String& docFile) { DocumentPtr doc = newLucene(); // Add the path of the file as a field named "path". Use a field that is indexed (ie. searchable), but @@ -37,37 +36,30 @@ DocumentPtr fileDocument(const String& docFile) return doc; } -void indexDocs(const IndexWriterPtr& writer, const String& sourceDir) -{ +void indexDocs(const IndexWriterPtr& writer, const String& sourceDir) { HashSet dirList(HashSet::newInstance()); - if (!FileUtils::listDirectory(sourceDir, false, dirList)) + if (!FileUtils::listDirectory(sourceDir, false, dirList)) { return; + } - for (HashSet::iterator dirFile = dirList.begin(); dirFile != dirList.end(); ++dirFile) - { + for (HashSet::iterator dirFile = dirList.begin(); dirFile != dirList.end(); ++dirFile) { String docFile(FileUtils::joinPath(sourceDir, *dirFile)); - if (FileUtils::isDirectory(docFile)) + if (FileUtils::isDirectory(docFile)) { indexDocs(writer, docFile); - else - { + } else { std::wcout << L"Adding [" << ++docNumber << L"]: " << *dirFile << L"\n"; - try - { + try { writer->addDocument(fileDocument(docFile)); - } - catch (FileNotFoundException&) - { + } catch (FileNotFoundException&) { } } } } /// Index all text files under a directory. -int main(int argc, char* argv[]) -{ - if (argc != 3) - { +int main(int argc, char* argv[]) { + if (argc != 3) { std::wcout << L"Usage: indexfiles.exe \n"; return 1; } @@ -75,16 +67,13 @@ int main(int argc, char* argv[]) String sourceDir(StringUtils::toUnicode(argv[1])); String indexDir(StringUtils::toUnicode(argv[2])); - if (!FileUtils::isDirectory(sourceDir)) - { + if (!FileUtils::isDirectory(sourceDir)) { std::wcout << L"Source directory doesn't exist: " << sourceDir << L"\n"; return 1; } - if (!FileUtils::isDirectory(indexDir)) - { - if (!FileUtils::createDirectory(indexDir)) - { + if (!FileUtils::isDirectory(indexDir)) { + if (!FileUtils::createDirectory(indexDir)) { std::wcout << L"Unable to create directory: " << indexDir << L"\n"; return 1; } @@ -92,8 +81,7 @@ int main(int argc, char* argv[]) uint64_t beginIndex = MiscUtils::currentTimeMillis(); - try - { + try { IndexWriterPtr writer = newLucene(FSDirectory::open(indexDir), newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); std::wcout << L"Indexing to directory: " << indexDir << L"...\n"; @@ -112,9 +100,7 @@ int main(int argc, char* argv[]) writer->close(); std::wcout << L"Total time: " << indexDuration + optimizeDuration << L" milliseconds\n"; - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { std::wcout << L"Exception: " << e.getError() << L"\n"; return 1; } diff --git a/src/demo/searchfiles/main.cpp b/src/demo/searchfiles/main.cpp index 9c8aba40..de4d303d 100644 --- a/src/demo/searchfiles/main.cpp +++ b/src/demo/searchfiles/main.cpp @@ -19,24 +19,20 @@ using namespace Lucene; /// per document per searched field. This can cause search of large collections with a large number /// of fields to run out of memory. If all of the fields contain only a single token, then the norms /// are all identical, then single norm vector may be shared. -class OneNormsReader : public FilterIndexReader -{ +class OneNormsReader : public FilterIndexReader { public: - OneNormsReader(const IndexReaderPtr& in, const String& field) : FilterIndexReader(in) - { + OneNormsReader(const IndexReaderPtr& in, const String& field) : FilterIndexReader(in) { this->field = field; } - virtual ~OneNormsReader() - { + virtual ~OneNormsReader() { } protected: String field; public: - virtual ByteArray norms(const String& field) - { + virtual ByteArray norms(const String& field) { return in->norms(this->field); } }; @@ -47,8 +43,7 @@ class OneNormsReader : public FilterIndexReader /// When the query is executed for the first time, then only enough results are collected to fill 5 result /// pages. If the user wants to page beyond this limit, then the query is executed another time and all /// hits are collected. -static void doPagingSearch(const SearcherPtr& searcher, const QueryPtr& query, int32_t hitsPerPage, bool raw, bool interactive) -{ +static void doPagingSearch(const SearcherPtr& searcher, const QueryPtr& query, int32_t hitsPerPage, bool raw, bool interactive) { // Collect enough docs to show 5 pages TopScoreDocCollectorPtr collector = TopScoreDocCollector::create(5 * hitsPerPage, false); searcher->search(query, collector); @@ -60,18 +55,17 @@ static void doPagingSearch(const SearcherPtr& searcher, const QueryPtr& query, i int32_t start = 0; int32_t end = std::min(numTotalHits, hitsPerPage); - while (true) - { - if (end > hits.size()) - { + while (true) { + if (end > hits.size()) { std::wcout << L"Only results 1 - " << hits.size() << L" of " << numTotalHits << L" total matching documents collected.\n"; std::wcout << L"Collect more (y/n) ?"; String line; std::wcin >> line; boost::trim(line); - if (line.empty() || boost::starts_with(line, L"n")) + if (line.empty() || boost::starts_with(line, L"n")) { break; + } collector = TopScoreDocCollector::create(numTotalHits, false); searcher->search(query, collector); @@ -80,98 +74,86 @@ static void doPagingSearch(const SearcherPtr& searcher, const QueryPtr& query, i end = std::min(hits.size(), start + hitsPerPage); - for (int32_t i = start; i < end; ++i) - { - if (raw) // output raw format - { + for (int32_t i = start; i < end; ++i) { + if (raw) { // output raw format std::wcout << L"doc=" << hits[i]->doc << L" score=" << hits[i]->score << L"\n"; continue; } DocumentPtr doc = searcher->doc(hits[i]->doc); String path = doc->get(L"path"); - if (!path.empty()) - { + if (!path.empty()) { std::wcout << StringUtils::toString(i + 1) + L". " << path << L"\n"; String title = doc->get(L"title"); - if (!title.empty()) + if (!title.empty()) { std::wcout << L" Title: " << doc->get(L"title") << L"\n"; - } - else + } + } else { std::wcout << StringUtils::toString(i + 1) + L". No path for this document\n"; + } } - if (!interactive) + if (!interactive) { break; + } - if (numTotalHits >= end) - { + if (numTotalHits >= end) { bool quit = false; - while (true) - { + while (true) { std::wcout << L"Press "; - if (start - hitsPerPage >= 0) + if (start - hitsPerPage >= 0) { std::wcout << L"(p)revious page, "; - if (start + hitsPerPage < numTotalHits) + } + if (start + hitsPerPage < numTotalHits) { std::wcout << L"(n)ext page, "; + } std::wcout << L"(q)uit or enter number to jump to a page: "; String line; std::wcin >> line; boost::trim(line); - if (line.empty() || boost::starts_with(line, L"q")) - { + if (line.empty() || boost::starts_with(line, L"q")) { quit = true; break; } - if (boost::starts_with(line, L"p")) - { + if (boost::starts_with(line, L"p")) { start = std::max((int32_t)0, start - hitsPerPage); break; - } - else if (boost::starts_with(line, L"n")) - { - if (start + hitsPerPage < numTotalHits) + } else if (boost::starts_with(line, L"n")) { + if (start + hitsPerPage < numTotalHits) { start += hitsPerPage; + } break; - } - else - { + } else { int32_t page = 0; - try - { + try { page = StringUtils::toInt(line); + } catch (NumberFormatException&) { } - catch (NumberFormatException&) - { - } - if ((page - 1) * hitsPerPage < numTotalHits) - { + if ((page - 1) * hitsPerPage < numTotalHits) { start = std::max((int32_t)0, (page - 1) * hitsPerPage); break; - } - else + } else { std::wcout << L"No such page\n"; + } } } - if (quit) + if (quit) { break; + } end = std::min(numTotalHits, start + hitsPerPage); } } } -class StreamingHitCollector : public Collector -{ +class StreamingHitCollector : public Collector { public: - StreamingHitCollector() - { + StreamingHitCollector() { docBase = 0; } - virtual ~StreamingHitCollector() - { + virtual ~StreamingHitCollector() { } protected: @@ -180,23 +162,19 @@ class StreamingHitCollector : public Collector public: /// simply print docId and score of every matching document - virtual void collect(int32_t doc) - { + virtual void collect(int32_t doc) { std::wcout << L"doc=" << (doc + docBase) << L" score=" << scorer->score(); } - virtual bool acceptsDocsOutOfOrder() - { + virtual bool acceptsDocsOutOfOrder() { return true; } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } - virtual void setScorer(const ScorerPtr& scorer) - { + virtual void setScorer(const ScorerPtr& scorer) { this->scorer = scorer; } }; @@ -206,24 +184,20 @@ class StreamingHitCollector : public Collector /// /// This simulates the streaming search use case, where all hits are supposed to be processed, regardless /// of their relevance. -static void doStreamingSearch(const SearcherPtr& searcher, const QueryPtr& query) -{ +static void doStreamingSearch(const SearcherPtr& searcher, const QueryPtr& query) { searcher->search(query, newLucene()); } /// Simple command-line based search demo. -int main(int argc, char* argv[]) -{ - if (argc == 1 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-help") == 0) - { +int main(int argc, char* argv[]) { + if (argc == 1 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-help") == 0) { std::wcout << L"Usage: searchfiles.exe [-index dir] [-field f] [-repeat n] [-queries file] [-raw] "; std::wcout << L"[-norms field] [-paging hitsPerPage]\n\n"; std::wcout << L"Specify 'false' for hitsPerPage to use streaming instead of paging search.\n"; return 1; } - try - { + try { String index = L"index"; String field = L"contents"; String queries; @@ -233,44 +207,32 @@ int main(int argc, char* argv[]) bool paging = true; int32_t hitsPerPage = 10; - for (int32_t i = 0; i < argc; ++i) - { - if (strcmp(argv[i], "-index") == 0) - { + for (int32_t i = 0; i < argc; ++i) { + if (strcmp(argv[i], "-index") == 0) { index = StringUtils::toUnicode(argv[i + 1]); ++i; - } - else if (strcmp(argv[i], "-field") == 0) - { + } else if (strcmp(argv[i], "-field") == 0) { field = StringUtils::toUnicode(argv[i + 1]); ++i; - } - else if (strcmp(argv[i], "-queries") == 0) - { + } else if (strcmp(argv[i], "-queries") == 0) { queries = StringUtils::toUnicode(argv[i + 1]); ++i; - } - else if (strcmp(argv[i], "-repeat") == 0) - { + } else if (strcmp(argv[i], "-repeat") == 0) { repeat = StringUtils::toInt(StringUtils::toUnicode(argv[i + 1])); ++i; - } - else if (strcmp(argv[i], "-raw") == 0) + } else if (strcmp(argv[i], "-raw") == 0) { raw = true; - else if (strcmp(argv[i], "-norms") == 0) - { + } else if (strcmp(argv[i], "-norms") == 0) { normsField = StringUtils::toUnicode(argv[i + 1]); ++i; - } - else if (strcmp(argv[i], "-paging") == 0) - { - if (strcmp(argv[i + 1], "false") == 0) + } else if (strcmp(argv[i], "-paging") == 0) { + if (strcmp(argv[i + 1], "false") == 0) { paging = false; - else - { + } else { hitsPerPage = StringUtils::toInt(StringUtils::toUnicode(argv[i + 1])); - if (hitsPerPage == 0) + if (hitsPerPage == 0) { paging = false; + } } ++i; } @@ -279,60 +241,57 @@ int main(int argc, char* argv[]) // only searching, so read-only=true IndexReaderPtr reader = IndexReader::open(FSDirectory::open(index), true); - if (!normsField.empty()) + if (!normsField.empty()) { reader = newLucene(reader, normsField); + } SearcherPtr searcher = newLucene(reader); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); QueryParserPtr parser = newLucene(LuceneVersion::LUCENE_CURRENT, field, analyzer); ReaderPtr in; - if (!queries.empty()) + if (!queries.empty()) { in = newLucene(queries); + } - while (true) - { + while (true) { String line; - if (!queries.empty()) - { + if (!queries.empty()) { wchar_t c = in->read(); - while (c != L'\n' && c != L'\r' && c != Reader::READER_EOF) - { + while (c != L'\n' && c != L'\r' && c != Reader::READER_EOF) { line += c; c = in->read(); } - } - else - { + } else { std::wcout << L"Enter query: "; std::wcin >> line; } boost::trim(line); - if (line.empty()) + if (line.empty()) { break; + } QueryPtr query = parser->parse(line); std::wcout << L"Searching for: " << query->toString(field) << L"\n"; - if (repeat > 0) // repeat and time as benchmark - { + if (repeat > 0) { // repeat and time as benchmark int64_t start = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < repeat; ++i) + for (int32_t i = 0; i < repeat; ++i) { searcher->search(query, FilterPtr(), 100); + } std::wcout << L"Time: " << (MiscUtils::currentTimeMillis() - start) << L"ms\n"; } - if (paging) + if (paging) { doPagingSearch(searcher, query, hitsPerPage, raw, queries.empty()); - else + } else { doStreamingSearch(searcher, query); + } } reader->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { std::wcout << L"Exception: " << e.getError() << L"\n"; return 1; } diff --git a/src/test/analysis/AnalyzersTest.cpp b/src/test/analysis/AnalyzersTest.cpp index bdc6d210..f5609a15 100644 --- a/src/test/analysis/AnalyzersTest.cpp +++ b/src/test/analysis/AnalyzersTest.cpp @@ -19,20 +19,18 @@ using namespace Lucene; typedef BaseTokenStreamFixture AnalyzersTest; -static void verifyPayload(const TokenStreamPtr& ts) -{ +static void verifyPayload(const TokenStreamPtr& ts) { PayloadAttributePtr payloadAtt = ts->getAttribute(); - for (uint8_t b = 1; ; ++b) - { + for (uint8_t b = 1; ; ++b) { bool hasNext = ts->incrementToken(); - if (!hasNext) + if (!hasNext) { break; + } EXPECT_EQ(b, payloadAtt->getPayload()->toByteArray()[0]); } } -TEST_F(AnalyzersTest, testSimple) -{ +TEST_F(AnalyzersTest, testSimple) { AnalyzerPtr a = newLucene(); checkAnalyzesTo(a, L"foo bar FOO BAR", newCollection(L"foo", L"bar", L"foo", L"bar")); checkAnalyzesTo(a, L"foo bar . FOO <> BAR", newCollection(L"foo", L"bar", L"foo", L"bar")); @@ -44,8 +42,7 @@ TEST_F(AnalyzersTest, testSimple) checkAnalyzesTo(a, L"\"QUOTED\" word", newCollection(L"quoted", L"word")); } -TEST_F(AnalyzersTest, testNull) -{ +TEST_F(AnalyzersTest, testNull) { AnalyzerPtr a = newLucene(); checkAnalyzesTo(a, L"foo bar FOO BAR", newCollection(L"foo", L"bar", L"FOO", L"BAR")); checkAnalyzesTo(a, L"foo bar . FOO <> BAR", newCollection(L"foo", L"bar", L".", L"FOO", L"<>", L"BAR")); @@ -57,53 +54,49 @@ TEST_F(AnalyzersTest, testNull) checkAnalyzesTo(a, L"\"QUOTED\" word", newCollection(L"\"QUOTED\"", L"word")); } -TEST_F(AnalyzersTest, testStop) -{ +TEST_F(AnalyzersTest, testStop) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(a, L"foo bar FOO BAR", newCollection(L"foo", L"bar", L"foo", L"bar")); checkAnalyzesTo(a, L"foo a bar such FOO THESE BAR", newCollection(L"foo", L"bar", L"foo", L"bar")); } -namespace TestPayloadCopy -{ - DECLARE_SHARED_PTR(PayloadSetter) - - class PayloadSetter : public TokenFilter - { - public: - PayloadSetter(const TokenStreamPtr& input) : TokenFilter(input) - { - payloadAtt = addAttribute(); - data = ByteArray::newInstance(1); - data[0] = 0; - p = newLucene(data, 0, 1); - } +namespace TestPayloadCopy { - virtual ~PayloadSetter() - { - } +DECLARE_SHARED_PTR(PayloadSetter) + +class PayloadSetter : public TokenFilter { +public: + PayloadSetter(const TokenStreamPtr& input) : TokenFilter(input) { + payloadAtt = addAttribute(); + data = ByteArray::newInstance(1); + data[0] = 0; + p = newLucene(data, 0, 1); + } - public: - PayloadAttributePtr payloadAtt; - ByteArray data; - PayloadPtr p; - - public: - virtual bool incrementToken() - { - bool hasNext = input->incrementToken(); - if (!hasNext) - return false; - payloadAtt->setPayload(p); // reuse the payload / byte[] - data[0]++; - return true; + virtual ~PayloadSetter() { + } + +public: + PayloadAttributePtr payloadAtt; + ByteArray data; + PayloadPtr p; + +public: + virtual bool incrementToken() { + bool hasNext = input->incrementToken(); + if (!hasNext) { + return false; } - }; + payloadAtt->setPayload(p); // reuse the payload / byte[] + data[0]++; + return true; + } +}; + } /// Make sure old style next() calls result in a new copy of payloads -TEST_F(AnalyzersTest, testPayloadCopy) -{ +TEST_F(AnalyzersTest, testPayloadCopy) { String s = L"how now brown cow"; TokenStreamPtr ts = newLucene(newLucene(s)); ts = newLucene(ts); diff --git a/src/test/analysis/BaseTokenStreamFixture.cpp b/src/test/analysis/BaseTokenStreamFixture.cpp index e7121976..1672c332 100644 --- a/src/test/analysis/BaseTokenStreamFixture.cpp +++ b/src/test/analysis/BaseTokenStreamFixture.cpp @@ -14,232 +14,208 @@ #include "Analyzer.h" #include "StringReader.h" -namespace Lucene -{ - CheckClearAttributesAttribute::CheckClearAttributesAttribute() - { - clearCalled = false; - } +namespace Lucene { - CheckClearAttributesAttribute::~CheckClearAttributesAttribute() - { - } +CheckClearAttributesAttribute::CheckClearAttributesAttribute() { + clearCalled = false; +} + +CheckClearAttributesAttribute::~CheckClearAttributesAttribute() { +} + +bool CheckClearAttributesAttribute::getAndResetClearCalled() { + bool _clearCalled = clearCalled; + clearCalled = false; + return _clearCalled; +} + +void CheckClearAttributesAttribute::clear() { + clearCalled = true; +} - bool CheckClearAttributesAttribute::getAndResetClearCalled() - { - bool _clearCalled = clearCalled; - clearCalled = false; - return _clearCalled; +bool CheckClearAttributesAttribute::equals(const LuceneObjectPtr& other) { + if (Attribute::equals(other)) { + return true; } - void CheckClearAttributesAttribute::clear() - { - clearCalled = true; + CheckClearAttributesAttributePtr otherAttribute(boost::dynamic_pointer_cast(other)); + if (otherAttribute) { + return (otherAttribute->clearCalled == clearCalled); } - bool CheckClearAttributesAttribute::equals(const LuceneObjectPtr& other) - { - if (Attribute::equals(other)) - return true; + return false; +} - CheckClearAttributesAttributePtr otherAttribute(boost::dynamic_pointer_cast(other)); - if (otherAttribute) - return (otherAttribute->clearCalled == clearCalled); +int32_t CheckClearAttributesAttribute::hashCode() { + return 76137213 ^ (clearCalled ? 1231 : 1237); +} - return false; - } +void CheckClearAttributesAttribute::copyTo(const AttributePtr& target) { + CheckClearAttributesAttributePtr clearAttribute(boost::dynamic_pointer_cast(target)); + clearAttribute->clear(); +} - int32_t CheckClearAttributesAttribute::hashCode() - { - return 76137213 ^ (clearCalled ? 1231 : 1237); - } +LuceneObjectPtr CheckClearAttributesAttribute::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = other ? other : newLucene(); + CheckClearAttributesAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); + cloneAttribute->clearCalled = clearCalled; + return cloneAttribute; +} + +BaseTokenStreamFixture::~BaseTokenStreamFixture() { +} + +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, + Collection types, Collection posIncrements, int32_t finalOffset) { + EXPECT_TRUE(output); + CheckClearAttributesAttributePtr checkClearAtt = ts->addAttribute(); - void CheckClearAttributesAttribute::copyTo(const AttributePtr& target) - { - CheckClearAttributesAttributePtr clearAttribute(boost::dynamic_pointer_cast(target)); - clearAttribute->clear(); + EXPECT_TRUE(ts->hasAttribute()); + TermAttributePtr termAtt = ts->getAttribute(); + + OffsetAttributePtr offsetAtt; + if (startOffsets || endOffsets || finalOffset != -1) { + EXPECT_TRUE(ts->hasAttribute()); + offsetAtt = ts->getAttribute(); } - LuceneObjectPtr CheckClearAttributesAttribute::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = other ? other : newLucene(); - CheckClearAttributesAttributePtr cloneAttribute(boost::dynamic_pointer_cast(Attribute::clone(clone))); - cloneAttribute->clearCalled = clearCalled; - return cloneAttribute; + TypeAttributePtr typeAtt; + if (types) { + EXPECT_TRUE(ts->hasAttribute()); + typeAtt = ts->getAttribute(); } - BaseTokenStreamFixture::~BaseTokenStreamFixture() - { + PositionIncrementAttributePtr posIncrAtt; + if (posIncrements) { + EXPECT_TRUE(ts->hasAttribute()); + posIncrAtt = ts->getAttribute(); } - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, - Collection types, Collection posIncrements, int32_t finalOffset) - { - EXPECT_TRUE(output); - CheckClearAttributesAttributePtr checkClearAtt = ts->addAttribute(); + ts->reset(); + for (int32_t i = 0; i < output.size(); ++i) { + // extra safety to enforce, that the state is not preserved and also assign bogus values + ts->clearAttributes(); + termAtt->setTermBuffer(L"bogusTerm"); + if (offsetAtt) { + offsetAtt->setOffset(14584724, 24683243); + } + if (typeAtt) { + typeAtt->setType(L"bogusType"); + } + if (posIncrAtt) { + posIncrAtt->setPositionIncrement(45987657); + } - EXPECT_TRUE(ts->hasAttribute()); - TermAttributePtr termAtt = ts->getAttribute(); + checkClearAtt->getAndResetClearCalled(); // reset it, because we called clearAttribute() before + EXPECT_TRUE(ts->incrementToken()); + EXPECT_TRUE(checkClearAtt->getAndResetClearCalled()); - OffsetAttributePtr offsetAtt; - if (startOffsets || endOffsets || finalOffset != -1) - { - EXPECT_TRUE(ts->hasAttribute()); - offsetAtt = ts->getAttribute(); + EXPECT_EQ(output[i], termAtt->term()); + if (startOffsets) { + EXPECT_EQ(startOffsets[i], offsetAtt->startOffset()); } - - TypeAttributePtr typeAtt; - if (types) - { - EXPECT_TRUE(ts->hasAttribute()); - typeAtt = ts->getAttribute(); + if (endOffsets) { + EXPECT_EQ(endOffsets[i], offsetAtt->endOffset()); } - - PositionIncrementAttributePtr posIncrAtt; - if (posIncrements) - { - EXPECT_TRUE(ts->hasAttribute()); - posIncrAtt = ts->getAttribute(); + if (types) { + EXPECT_EQ(types[i], typeAtt->type()); } - - ts->reset(); - for (int32_t i = 0; i < output.size(); ++i) - { - // extra safety to enforce, that the state is not preserved and also assign bogus values - ts->clearAttributes(); - termAtt->setTermBuffer(L"bogusTerm"); - if (offsetAtt) - offsetAtt->setOffset(14584724, 24683243); - if (typeAtt) - typeAtt->setType(L"bogusType"); - if (posIncrAtt) - posIncrAtt->setPositionIncrement(45987657); - - checkClearAtt->getAndResetClearCalled(); // reset it, because we called clearAttribute() before - EXPECT_TRUE(ts->incrementToken()); - EXPECT_TRUE(checkClearAtt->getAndResetClearCalled()); - - EXPECT_EQ(output[i], termAtt->term()); - if (startOffsets) - EXPECT_EQ(startOffsets[i], offsetAtt->startOffset()); - if (endOffsets) - EXPECT_EQ(endOffsets[i], offsetAtt->endOffset()); - if (types) - EXPECT_EQ(types[i], typeAtt->type()); - if (posIncrements) - EXPECT_EQ(posIncrements[i], posIncrAtt->getPositionIncrement()); + if (posIncrements) { + EXPECT_EQ(posIncrements[i], posIncrAtt->getPositionIncrement()); } - EXPECT_TRUE(!ts->incrementToken()); - ts->end(); - if (finalOffset != -1) - EXPECT_EQ(finalOffset, offsetAtt->endOffset()); - ts->close(); } - - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output) - { - checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), Collection(), -1); + EXPECT_TRUE(!ts->incrementToken()); + ts->end(); + if (finalOffset != -1) { + EXPECT_EQ(finalOffset, offsetAtt->endOffset()); } + ts->close(); +} - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection types) - { - checkTokenStreamContents(ts, output, Collection(), Collection(), types, Collection(), -1); - } +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output) { + checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), Collection(), -1); +} - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection posIncrements) - { - checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), posIncrements, -1); - } +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection types) { + checkTokenStreamContents(ts, output, Collection(), Collection(), types, Collection(), -1); +} - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets) - { - checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), -1); - } +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection posIncrements) { + checkTokenStreamContents(ts, output, Collection(), Collection(), Collection(), posIncrements, -1); +} - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset) - { - checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), finalOffset); - } +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets) { + checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), -1); +} - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) - { - checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, -1); - } +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset) { + checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), Collection(), finalOffset); +} - void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset) - { - checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, finalOffset); - } +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { + checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, -1); +} - void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, - Collection endOffsets, Collection types, Collection posIncrements) - { - checkTokenStreamContents(analyzer->tokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); - } +void BaseTokenStreamFixture::checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset) { + checkTokenStreamContents(ts, output, startOffsets, endOffsets, Collection(), posIncrements, finalOffset); +} - void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output) - { - checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); - } +void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, + Collection endOffsets, Collection types, Collection posIncrements) { + checkTokenStreamContents(analyzer->tokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); +} - void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types) - { - checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), types, Collection()); - } +void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output) { + checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); +} - void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements) - { - checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); - } +void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types) { + checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), types, Collection()); +} - void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) - { - checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); - } +void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements) { + checkAnalyzesTo(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); +} - void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) - { - checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); - } +void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) { + checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); +} - void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, - Collection endOffsets, Collection types, Collection posIncrements) - { - checkTokenStreamContents(analyzer->reusableTokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); - } +void BaseTokenStreamFixture::checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { + checkAnalyzesTo(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); +} - void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output) - { - checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); - } +void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, + Collection endOffsets, Collection types, Collection posIncrements) { + checkTokenStreamContents(analyzer->reusableTokenStream(L"dummy", newLucene(input)), output, startOffsets, endOffsets, types, posIncrements, (int32_t)input.length()); +} - void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types) - { - checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), types, Collection()); - } +void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output) { + checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), Collection()); +} - void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements) - { - checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); - } +void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types) { + checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), types, Collection()); +} - void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) - { - checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); - } +void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements) { + checkAnalyzesToReuse(analyzer, input, output, Collection(), Collection(), Collection(), posIncrements); +} - void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) - { - checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); - } +void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets) { + checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), Collection()); +} - void BaseTokenStreamFixture::checkOneTerm(const AnalyzerPtr& analyzer, const String& input, const String& expected) - { - checkAnalyzesTo(analyzer, input, newCollection(expected)); - } +void BaseTokenStreamFixture::checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements) { + checkAnalyzesToReuse(analyzer, input, output, startOffsets, endOffsets, Collection(), posIncrements); +} + +void BaseTokenStreamFixture::checkOneTerm(const AnalyzerPtr& analyzer, const String& input, const String& expected) { + checkAnalyzesTo(analyzer, input, newCollection(expected)); +} + +void BaseTokenStreamFixture::checkOneTermReuse(const AnalyzerPtr& analyzer, const String& input, const String& expected) { + checkAnalyzesToReuse(analyzer, input, newCollection(expected)); +} - void BaseTokenStreamFixture::checkOneTermReuse(const AnalyzerPtr& analyzer, const String& input, const String& expected) - { - checkAnalyzesToReuse(analyzer, input, newCollection(expected)); - } } diff --git a/src/test/analysis/CachingTokenFilterTest.cpp b/src/test/analysis/CachingTokenFilterTest.cpp index d7f8bc65..2db324b8 100644 --- a/src/test/analysis/CachingTokenFilterTest.cpp +++ b/src/test/analysis/CachingTokenFilterTest.cpp @@ -25,14 +25,12 @@ typedef BaseTokenStreamFixture CachingTokenFilterTest; static Collection tokens = newCollection(L"term1", L"term2", L"term3", L"term2"); -static void checkTokens(const TokenStreamPtr& stream) -{ +static void checkTokens(const TokenStreamPtr& stream) { int32_t count = 0; TermAttributePtr termAtt = stream->getAttribute(); EXPECT_TRUE(termAtt); - while (stream->incrementToken()) - { + while (stream->incrementToken()) { EXPECT_TRUE(count < tokens.size()); EXPECT_EQ(tokens[count], termAtt->term()); ++count; @@ -40,45 +38,40 @@ static void checkTokens(const TokenStreamPtr& stream) EXPECT_EQ(tokens.size(), count); } -namespace TestCaching -{ - class TestableTokenStream : public TokenStream - { - public: - TestableTokenStream() - { - index = 0; - termAtt = addAttribute(); - offsetAtt = addAttribute(); - } +namespace TestCaching { - virtual ~TestableTokenStream() - { - } +class TestableTokenStream : public TokenStream { +public: + TestableTokenStream() { + index = 0; + termAtt = addAttribute(); + offsetAtt = addAttribute(); + } - protected: - int32_t index; - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; - - public: - virtual bool incrementToken() - { - if (index == tokens.size()) - return false; - else - { - clearAttributes(); - termAtt->setTermBuffer(tokens[index++]); - offsetAtt->setOffset(0, 0); - return true; - } + virtual ~TestableTokenStream() { + } + +protected: + int32_t index; + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + +public: + virtual bool incrementToken() { + if (index == tokens.size()) { + return false; + } else { + clearAttributes(); + termAtt->setTermBuffer(tokens[index++]); + offsetAtt->setOffset(0, 0); + return true; } - }; + } +}; + } -TEST_F(CachingTokenFilterTest, testCaching) -{ +TEST_F(CachingTokenFilterTest, testCaching) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); diff --git a/src/test/analysis/CharFilterTest.cpp b/src/test/analysis/CharFilterTest.cpp index fb7488e4..24f0d8e8 100644 --- a/src/test/analysis/CharFilterTest.cpp +++ b/src/test/analysis/CharFilterTest.cpp @@ -14,62 +14,50 @@ using namespace Lucene; typedef LuceneTestFixture CharFilterTest; -class CharFilter1 : public CharFilter -{ +class CharFilter1 : public CharFilter { public: - CharFilter1(const CharStreamPtr& in) : CharFilter(in) - { + CharFilter1(const CharStreamPtr& in) : CharFilter(in) { } - virtual ~CharFilter1() - { + virtual ~CharFilter1() { } protected: - virtual int32_t correct(int32_t currentOff) - { + virtual int32_t correct(int32_t currentOff) { return currentOff + 1; } }; -class CharFilter2 : public CharFilter -{ +class CharFilter2 : public CharFilter { public: - CharFilter2(const CharStreamPtr& in) : CharFilter(in) - { + CharFilter2(const CharStreamPtr& in) : CharFilter(in) { } - virtual ~CharFilter2() - { + virtual ~CharFilter2() { } protected: - virtual int32_t correct(int32_t currentOff) - { + virtual int32_t correct(int32_t currentOff) { return currentOff + 2; } }; -TEST_F(CharFilterTest, testCharFilter1) -{ +TEST_F(CharFilterTest, testCharFilter1) { CharStreamPtr cs = newLucene(CharReader::get(newLucene(L""))); EXPECT_EQ(1, cs->correctOffset(0)); } -TEST_F(CharFilterTest, testCharFilter2) -{ +TEST_F(CharFilterTest, testCharFilter2) { CharStreamPtr cs = newLucene(CharReader::get(newLucene(L""))); EXPECT_EQ(2, cs->correctOffset(0)); } -TEST_F(CharFilterTest, testCharFilter12) -{ +TEST_F(CharFilterTest, testCharFilter12) { CharStreamPtr cs = newLucene(newLucene(CharReader::get(newLucene(L"")))); EXPECT_EQ(3, cs->correctOffset(0)); } -TEST_F(CharFilterTest, testCharFilter11) -{ +TEST_F(CharFilterTest, testCharFilter11) { CharStreamPtr cs = newLucene(newLucene(CharReader::get(newLucene(L"")))); EXPECT_EQ(2, cs->correctOffset(0)); } diff --git a/src/test/analysis/KeywordAnalyzerTest.cpp b/src/test/analysis/KeywordAnalyzerTest.cpp index 89c7761d..d9ffc3cb 100644 --- a/src/test/analysis/KeywordAnalyzerTest.cpp +++ b/src/test/analysis/KeywordAnalyzerTest.cpp @@ -27,11 +27,9 @@ using namespace Lucene; -class KeywordAnalyzerTest : public BaseTokenStreamFixture -{ +class KeywordAnalyzerTest : public BaseTokenStreamFixture { public: - KeywordAnalyzerTest() - { + KeywordAnalyzerTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -44,8 +42,7 @@ class KeywordAnalyzerTest : public BaseTokenStreamFixture searcher = newLucene(directory, true); } - virtual ~KeywordAnalyzerTest() - { + virtual ~KeywordAnalyzerTest() { } protected: @@ -53,8 +50,7 @@ class KeywordAnalyzerTest : public BaseTokenStreamFixture IndexSearcherPtr searcher; }; -TEST_F(KeywordAnalyzerTest, testPerFieldAnalyzer) -{ +TEST_F(KeywordAnalyzerTest, testPerFieldAnalyzer) { PerFieldAnalyzerWrapperPtr analyzer = newLucene(newLucene()); analyzer->addAnalyzer(L"partnum", newLucene()); @@ -66,8 +62,7 @@ TEST_F(KeywordAnalyzerTest, testPerFieldAnalyzer) EXPECT_EQ(1, hits.size()); } -TEST_F(KeywordAnalyzerTest, testMutipleDocument) -{ +TEST_F(KeywordAnalyzerTest, testMutipleDocument) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -85,8 +80,7 @@ TEST_F(KeywordAnalyzerTest, testMutipleDocument) EXPECT_TRUE(td->next()); } -TEST_F(KeywordAnalyzerTest, testOffsets) -{ +TEST_F(KeywordAnalyzerTest, testOffsets) { TokenStreamPtr stream = newLucene()->tokenStream(L"field", newLucene(L"abcd")); OffsetAttributePtr offsetAtt = stream->addAttribute(); EXPECT_TRUE(stream->incrementToken()); diff --git a/src/test/analysis/LengthFilterTest.cpp b/src/test/analysis/LengthFilterTest.cpp index 8928fc6d..7234c8e0 100644 --- a/src/test/analysis/LengthFilterTest.cpp +++ b/src/test/analysis/LengthFilterTest.cpp @@ -16,8 +16,7 @@ using namespace Lucene; typedef BaseTokenStreamFixture LengthFilterTest; -TEST_F(LengthFilterTest, testFilter) -{ +TEST_F(LengthFilterTest, testFilter) { TokenStreamPtr stream = newLucene(newLucene(L"short toolong evenmuchlongertext a ab toolong foo")); LengthFilterPtr filter = newLucene(stream, 2, 6); TermAttributePtr termAtt = filter->getAttribute(); diff --git a/src/test/analysis/MappingCharFilterTest.cpp b/src/test/analysis/MappingCharFilterTest.cpp index 502e4c27..47b4f97e 100644 --- a/src/test/analysis/MappingCharFilterTest.cpp +++ b/src/test/analysis/MappingCharFilterTest.cpp @@ -15,11 +15,9 @@ using namespace Lucene; -class MappingCharFilterTest : public BaseTokenStreamFixture -{ +class MappingCharFilterTest : public BaseTokenStreamFixture { public: - MappingCharFilterTest() - { + MappingCharFilterTest() { normMap = newLucene(); normMap->add(L"aa", L"a"); @@ -34,16 +32,14 @@ class MappingCharFilterTest : public BaseTokenStreamFixture normMap->add(L"empty", L""); } - virtual ~MappingCharFilterTest() - { + virtual ~MappingCharFilterTest() { } public: NormalizeCharMapPtr normMap; }; -TEST_F(MappingCharFilterTest, testReaderReset) -{ +TEST_F(MappingCharFilterTest, testReaderReset) { CharStreamPtr cs = newLucene(normMap, newLucene(L"x")); CharArray buf = CharArray::newInstance(10); int32_t len = cs->read(buf.get(), 0, 10); @@ -59,64 +55,55 @@ TEST_F(MappingCharFilterTest, testReaderReset) EXPECT_EQ(L'x', buf[0]) ; } -TEST_F(MappingCharFilterTest, testNothingChange) -{ +TEST_F(MappingCharFilterTest, testNothingChange) { CharStreamPtr cs = newLucene(normMap, newLucene(L"x")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"x"), newCollection(0), newCollection(1)); } -TEST_F(MappingCharFilterTest, test1to1) -{ +TEST_F(MappingCharFilterTest, test1to1) { CharStreamPtr cs = newLucene(normMap, newLucene(L"h")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"i"), newCollection(0), newCollection(1)); } -TEST_F(MappingCharFilterTest, test1to2) -{ +TEST_F(MappingCharFilterTest, test1to2) { CharStreamPtr cs = newLucene(normMap, newLucene(L"j")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"jj"), newCollection(0), newCollection(1)); } -TEST_F(MappingCharFilterTest, test1to3) -{ +TEST_F(MappingCharFilterTest, test1to3) { CharStreamPtr cs = newLucene(normMap, newLucene(L"k")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"kkk"), newCollection(0), newCollection(1)); } -TEST_F(MappingCharFilterTest, test2to4) -{ +TEST_F(MappingCharFilterTest, test2to4) { CharStreamPtr cs = newLucene(normMap, newLucene(L"ll")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"llll"), newCollection(0), newCollection(2)); } -TEST_F(MappingCharFilterTest, test2to1) -{ +TEST_F(MappingCharFilterTest, test2to1) { CharStreamPtr cs = newLucene(normMap, newLucene(L"aa")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"a"), newCollection(0), newCollection(2)); } -TEST_F(MappingCharFilterTest, test3to1) -{ +TEST_F(MappingCharFilterTest, test3to1) { CharStreamPtr cs = newLucene(normMap, newLucene(L"bbb")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"b"), newCollection(0), newCollection(3)); } -TEST_F(MappingCharFilterTest, test4to2) -{ +TEST_F(MappingCharFilterTest, test4to2) { CharStreamPtr cs = newLucene(normMap, newLucene(L"cccc")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"cc"), newCollection(0), newCollection(4)); } -TEST_F(MappingCharFilterTest, test5to0) -{ +TEST_F(MappingCharFilterTest, test5to0) { CharStreamPtr cs = newLucene(normMap, newLucene(L"empty")); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, Collection::newInstance()); @@ -139,8 +126,7 @@ TEST_F(MappingCharFilterTest, test5to0) // cccc,11,15 => cc,11,15 // bbb,16,19 => b,16,19 // aa,20,22 => a,20,22 -TEST_F(MappingCharFilterTest, testTokenStream) -{ +TEST_F(MappingCharFilterTest, testTokenStream) { CharStreamPtr cs = newLucene(normMap, CharReader::get(newLucene(L"h i j k ll cccc bbb aa"))); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"i", L"i", L"jj", L"kkk", L"llll", L"cc", L"b", L"a"), @@ -158,8 +144,7 @@ TEST_F(MappingCharFilterTest, testTokenStream) // aaaa,0,4 => a,0,4 // ll,5,7 => llllllll,5,7 // h,8,9 => i,8,9 -TEST_F(MappingCharFilterTest, testChained) -{ +TEST_F(MappingCharFilterTest, testChained) { CharStreamPtr cs = newLucene(normMap, (CharStreamPtr)newLucene(normMap, CharReader::get(newLucene(L"aaaa ll h")))); TokenStreamPtr ts = newLucene(cs); checkTokenStreamContents(ts, newCollection(L"a", L"llllllll", L"i"), newCollection(0, 5, 8), newCollection(4, 7, 9)); diff --git a/src/test/analysis/NumericTokenStreamTest.cpp b/src/test/analysis/NumericTokenStreamTest.cpp index 09d902cb..aba9cfb0 100644 --- a/src/test/analysis/NumericTokenStreamTest.cpp +++ b/src/test/analysis/NumericTokenStreamTest.cpp @@ -18,14 +18,12 @@ typedef BaseTokenStreamFixture NumericTokenStreamTest; static int64_t lvalue = 4573245871874382LL; static int32_t ivalue = 123456; -TEST_F(NumericTokenStreamTest, testLongStream) -{ +TEST_F(NumericTokenStreamTest, testLongStream) { NumericTokenStreamPtr stream = newLucene()->setLongValue(lvalue); // use getAttribute to test if attributes really exist, if not an IAE will be thrown TermAttributePtr termAtt = stream->getAttribute(); TypeAttributePtr typeAtt = stream->getAttribute(); - for (int32_t shift = 0; shift < 64; shift += NumericUtils::PRECISION_STEP_DEFAULT) - { + for (int32_t shift = 0; shift < 64; shift += NumericUtils::PRECISION_STEP_DEFAULT) { EXPECT_TRUE(stream->incrementToken()); EXPECT_EQ(NumericUtils::longToPrefixCoded(lvalue, shift), termAtt->term()); EXPECT_EQ(shift == 0 ? NumericTokenStream::TOKEN_TYPE_FULL_PREC() : NumericTokenStream::TOKEN_TYPE_LOWER_PREC(), typeAtt->type()); @@ -33,14 +31,12 @@ TEST_F(NumericTokenStreamTest, testLongStream) EXPECT_TRUE(!stream->incrementToken()); } -TEST_F(NumericTokenStreamTest, testIntStream) -{ +TEST_F(NumericTokenStreamTest, testIntStream) { NumericTokenStreamPtr stream = newLucene()->setIntValue(ivalue); // use getAttribute to test if attributes really exist, if not an IAE will be thrown TermAttributePtr termAtt = stream->getAttribute(); TypeAttributePtr typeAtt = stream->getAttribute(); - for (int32_t shift = 0; shift < 32; shift += NumericUtils::PRECISION_STEP_DEFAULT) - { + for (int32_t shift = 0; shift < 32; shift += NumericUtils::PRECISION_STEP_DEFAULT) { EXPECT_TRUE(stream->incrementToken()); EXPECT_EQ(NumericUtils::intToPrefixCoded(ivalue, shift), termAtt->term()); EXPECT_EQ(shift == 0 ? NumericTokenStream::TOKEN_TYPE_FULL_PREC() : NumericTokenStream::TOKEN_TYPE_LOWER_PREC(), typeAtt->type()); @@ -48,23 +44,16 @@ TEST_F(NumericTokenStreamTest, testIntStream) EXPECT_TRUE(!stream->incrementToken()); } -TEST_F(NumericTokenStreamTest, testNotInitialized) -{ +TEST_F(NumericTokenStreamTest, testNotInitialized) { NumericTokenStreamPtr stream = newLucene(); - try - { + try { stream->reset(); - } - catch (IllegalStateException& e) - { + } catch (IllegalStateException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); } - try - { + try { stream->incrementToken(); - } - catch (IllegalStateException& e) - { + } catch (IllegalStateException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); } } diff --git a/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp b/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp index 31f21e53..af9b9617 100644 --- a/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp +++ b/src/test/analysis/PerFieldAnalzyerWrapperTest.cpp @@ -17,8 +17,7 @@ using namespace Lucene; typedef BaseTokenStreamFixture PerFieldAnalzyerWrapperTest; -TEST_F(PerFieldAnalzyerWrapperTest, testPerField) -{ +TEST_F(PerFieldAnalzyerWrapperTest, testPerField) { String text = L"Qwerty"; PerFieldAnalyzerWrapperPtr analyzer = newLucene(newLucene()); analyzer->addAnalyzer(L"special", newLucene()); diff --git a/src/test/analysis/StopAnalyzerTest.cpp b/src/test/analysis/StopAnalyzerTest.cpp index 13daa9cf..e4e49c4f 100644 --- a/src/test/analysis/StopAnalyzerTest.cpp +++ b/src/test/analysis/StopAnalyzerTest.cpp @@ -14,19 +14,17 @@ using namespace Lucene; -class StopAnalyzerTest : public BaseTokenStreamFixture -{ +class StopAnalyzerTest : public BaseTokenStreamFixture { public: - StopAnalyzerTest() - { + StopAnalyzerTest() { stop = newLucene(LuceneVersion::LUCENE_CURRENT); inValidTokens = HashSet::newInstance(); - for (HashSet::iterator word = StopAnalyzer::ENGLISH_STOP_WORDS_SET().begin(); word != StopAnalyzer::ENGLISH_STOP_WORDS_SET().end(); ++word) + for (HashSet::iterator word = StopAnalyzer::ENGLISH_STOP_WORDS_SET().begin(); word != StopAnalyzer::ENGLISH_STOP_WORDS_SET().end(); ++word) { inValidTokens.add(*word); + } } - virtual ~StopAnalyzerTest() - { + virtual ~StopAnalyzerTest() { } protected: @@ -34,20 +32,19 @@ class StopAnalyzerTest : public BaseTokenStreamFixture HashSet inValidTokens; }; -TEST_F(StopAnalyzerTest, testDefaults) -{ +TEST_F(StopAnalyzerTest, testDefaults) { EXPECT_TRUE(stop); StringReaderPtr reader = newLucene(L"This is a test of the english stop analyzer"); TokenStreamPtr stream = stop->tokenStream(L"test", reader); EXPECT_TRUE(stream); TermAttributePtr termAtt = stream->getAttribute(); - while (stream->incrementToken()) + while (stream->incrementToken()) { EXPECT_TRUE(!inValidTokens.contains(termAtt->term())); + } } -TEST_F(StopAnalyzerTest, testStopList) -{ +TEST_F(StopAnalyzerTest, testStopList) { HashSet stopWordsSet = HashSet::newInstance(); stopWordsSet.add(L"good"); stopWordsSet.add(L"test"); @@ -59,16 +56,14 @@ TEST_F(StopAnalyzerTest, testStopList) TermAttributePtr termAtt = stream->getAttribute(); PositionIncrementAttributePtr posIncrAtt = stream->addAttribute(); - while (stream->incrementToken()) - { + while (stream->incrementToken()) { String text = termAtt->term(); EXPECT_TRUE(!stopWordsSet.contains(text)); EXPECT_EQ(1, posIncrAtt->getPositionIncrement()); // in 2.4 stop tokenizer does not apply increments. } } -TEST_F(StopAnalyzerTest, testStopListPositions) -{ +TEST_F(StopAnalyzerTest, testStopListPositions) { HashSet stopWordsSet = HashSet::newInstance(); stopWordsSet.add(L"good"); stopWordsSet.add(L"test"); @@ -82,8 +77,7 @@ TEST_F(StopAnalyzerTest, testStopListPositions) TermAttributePtr termAtt = stream->getAttribute(); PositionIncrementAttributePtr posIncrAtt = stream->addAttribute(); - while (stream->incrementToken()) - { + while (stream->incrementToken()) { String text = termAtt->term(); EXPECT_TRUE(!stopWordsSet.contains(text)); EXPECT_EQ(expectedIncr[i++], posIncrAtt->getPositionIncrement()); diff --git a/src/test/analysis/StopFilterTest.cpp b/src/test/analysis/StopFilterTest.cpp index c669a1e0..e725520f 100644 --- a/src/test/analysis/StopFilterTest.cpp +++ b/src/test/analysis/StopFilterTest.cpp @@ -18,13 +18,11 @@ using namespace Lucene; typedef BaseTokenStreamFixture StopFilterTest; -static void doTestStopPositons(const StopFilterPtr& stpf, bool enableIcrements) -{ +static void doTestStopPositons(const StopFilterPtr& stpf, bool enableIcrements) { stpf->setEnablePositionIncrements(enableIcrements); TermAttributePtr termAtt = stpf->getAttribute(); PositionIncrementAttributePtr posIncrAtt = stpf->getAttribute(); - for (int32_t i = 0; i < 20; i += 3) - { + for (int32_t i = 0; i < 20; i += 3) { EXPECT_TRUE(stpf->incrementToken()); String w = intToEnglish(i); EXPECT_EQ(w, termAtt->term()); @@ -33,8 +31,7 @@ static void doTestStopPositons(const StopFilterPtr& stpf, bool enableIcrements) EXPECT_TRUE(!stpf->incrementToken()); } -TEST_F(StopFilterTest, testExactCase) -{ +TEST_F(StopFilterTest, testExactCase) { StringReaderPtr reader = newLucene(L"Now is The Time"); HashSet stopWords = HashSet::newInstance(); stopWords.add(L"is"); @@ -49,8 +46,7 @@ TEST_F(StopFilterTest, testExactCase) EXPECT_TRUE(!stream->incrementToken()); } -TEST_F(StopFilterTest, testIgnoreCase) -{ +TEST_F(StopFilterTest, testIgnoreCase) { StringReaderPtr reader = newLucene(L"Now is The Time"); HashSet stopWords = HashSet::newInstance(); stopWords.add(L"is"); @@ -63,16 +59,15 @@ TEST_F(StopFilterTest, testIgnoreCase) EXPECT_TRUE(!stream->incrementToken()); } -TEST_F(StopFilterTest, testStopPositons) -{ +TEST_F(StopFilterTest, testStopPositons) { StringStream buf; Collection stopWords = Collection::newInstance(); - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { String w = intToEnglish(i); buf << w << L" "; - if (i % 3 != 0) + if (i % 3 != 0) { stopWords.add(w); + } } HashSet stopSet = HashSet::newInstance(stopWords.begin(), stopWords.end()); // with increments @@ -86,12 +81,12 @@ TEST_F(StopFilterTest, testStopPositons) // with increments, concatenating two stop filters Collection stopWords0 = Collection::newInstance(); Collection stopWords1 = Collection::newInstance(); - for (int32_t i = 0; i < stopWords.size(); ++i) - { - if (i % 2 == 0) + for (int32_t i = 0; i < stopWords.size(); ++i) { + if (i % 2 == 0) { stopWords0.add(stopWords[i]); - else + } else { stopWords1.add(stopWords[i]); + } } HashSet stopSet0 = HashSet::newInstance(stopWords0.begin(), stopWords0.end()); HashSet stopSet1 = HashSet::newInstance(stopWords1.begin(), stopWords1.end()); diff --git a/src/test/analysis/TeeSinkTokenFilterTest.cpp b/src/test/analysis/TeeSinkTokenFilterTest.cpp index ca27e297..df90b5f2 100644 --- a/src/test/analysis/TeeSinkTokenFilterTest.cpp +++ b/src/test/analysis/TeeSinkTokenFilterTest.cpp @@ -22,55 +22,48 @@ using namespace Lucene; -class TheSinkFilter : public SinkFilter -{ +class TheSinkFilter : public SinkFilter { public: - virtual ~TheSinkFilter() - { + virtual ~TheSinkFilter() { } public: - virtual bool accept(const AttributeSourcePtr& source) - { + virtual bool accept(const AttributeSourcePtr& source) { TermAttributePtr termAtt = source->getAttribute(); return boost::iequals(termAtt->term(), L"The"); } }; -class DogSinkFilter : public SinkFilter -{ +class DogSinkFilter : public SinkFilter { public: - virtual ~DogSinkFilter() - { + virtual ~DogSinkFilter() { } public: - virtual bool accept(const AttributeSourcePtr& source) - { + virtual bool accept(const AttributeSourcePtr& source) { TermAttributePtr termAtt = source->getAttribute(); return boost::iequals(termAtt->term(), L"Dogs"); } }; -class TeeSinkTokenFilterTest : public BaseTokenStreamFixture -{ +class TeeSinkTokenFilterTest : public BaseTokenStreamFixture { public: - TeeSinkTokenFilterTest() - { + TeeSinkTokenFilterTest() { tokens1 = newCollection(L"The", L"quick", L"Burgundy", L"Fox", L"jumped", L"over", L"the", L"lazy", L"Red", L"Dogs"); tokens2 = newCollection(L"The", L"Lazy", L"Dogs", L"should", L"stay", L"on", L"the", L"porch"); - for (int32_t i = 0; i < tokens1.size(); ++i) + for (int32_t i = 0; i < tokens1.size(); ++i) { buffer1 << tokens1[i] << L" "; - for (int32_t i = 0; i < tokens2.size(); ++i) + } + for (int32_t i = 0; i < tokens2.size(); ++i) { buffer2 << tokens2[i] << L" "; + } theFilter = newLucene(); dogFilter = newLucene(); } - virtual ~TeeSinkTokenFilterTest() - { + virtual ~TeeSinkTokenFilterTest() { } protected: @@ -83,8 +76,7 @@ class TeeSinkTokenFilterTest : public BaseTokenStreamFixture SinkFilterPtr dogFilter; }; -TEST_F(TeeSinkTokenFilterTest, testGeneral) -{ +TEST_F(TeeSinkTokenFilterTest, testGeneral) { TeeSinkTokenFilterPtr source = newLucene(newLucene(newLucene(buffer1.str()))); TokenStreamPtr sink1 = source->newSinkTokenStream(); TokenStreamPtr sink2 = source->newSinkTokenStream(theFilter); @@ -98,8 +90,7 @@ TEST_F(TeeSinkTokenFilterTest, testGeneral) checkTokenStreamContents(sink2, newCollection(L"The", L"the")); } -TEST_F(TeeSinkTokenFilterTest, testMultipleSources) -{ +TEST_F(TeeSinkTokenFilterTest, testMultipleSources) { TeeSinkTokenFilterPtr tee1 = newLucene(newLucene(newLucene(buffer1.str()))); SinkTokenStreamPtr dogDetector = tee1->newSinkTokenStream(dogFilter); SinkTokenStreamPtr theDetector = tee1->newSinkTokenStream(theFilter); @@ -123,80 +114,74 @@ TEST_F(TeeSinkTokenFilterTest, testMultipleSources) source1->reset(); TokenStreamPtr lowerCasing = newLucene(source1); Collection lowerCaseTokens = Collection::newInstance(tokens1.size()); - for (int32_t i = 0; i < tokens1.size(); ++i) + for (int32_t i = 0; i < tokens1.size(); ++i) { lowerCaseTokens[i] = StringUtils::toLower((const String&)tokens1[i]); + } checkTokenStreamContents(lowerCasing, lowerCaseTokens); } -namespace TestPerformance -{ - class ModuloTokenFilter : public TokenFilter - { - public: - ModuloTokenFilter(const TokenStreamPtr& input, int32_t mc) : TokenFilter(input) - { - modCount = mc; - count = 0; - } +namespace TestPerformance { - virtual ~ModuloTokenFilter() - { - } +class ModuloTokenFilter : public TokenFilter { +public: + ModuloTokenFilter(const TokenStreamPtr& input, int32_t mc) : TokenFilter(input) { + modCount = mc; + count = 0; + } - public: - int32_t modCount; - int32_t count; - - public: - // return every 100 tokens - virtual bool incrementToken() - { - bool hasNext = false; - for (hasNext = input->incrementToken(); hasNext && count % modCount != 0; hasNext = input->incrementToken()) - ++count; + virtual ~ModuloTokenFilter() { + } + +public: + int32_t modCount; + int32_t count; + +public: + // return every 100 tokens + virtual bool incrementToken() { + bool hasNext = false; + for (hasNext = input->incrementToken(); hasNext && count % modCount != 0; hasNext = input->incrementToken()) { ++count; - return hasNext; - } - }; - - class ModuloSinkFilter : public SinkFilter - { - public: - ModuloSinkFilter(int32_t mc) - { - modCount = mc; - count = 0; } + ++count; + return hasNext; + } +}; - virtual ~ModuloSinkFilter() - { - } +class ModuloSinkFilter : public SinkFilter { +public: + ModuloSinkFilter(int32_t mc) { + modCount = mc; + count = 0; + } - public: - int32_t modCount; - int32_t count; + virtual ~ModuloSinkFilter() { + } + +public: + int32_t modCount; + int32_t count; + +public: + virtual bool accept(const AttributeSourcePtr& source) { + bool b = (source && count % modCount == 0); + ++count; + return b; + } +}; - public: - virtual bool accept(const AttributeSourcePtr& source) - { - bool b = (source && count % modCount == 0); - ++count; - return b; - } - }; } /// Not an explicit test, just useful to print out some info on performance -TEST_F(TeeSinkTokenFilterTest, testPerformance) -{ +TEST_F(TeeSinkTokenFilterTest, testPerformance) { Collection tokCount = newCollection(100, 500, 1000, 2000, 5000, 10000); Collection modCounts = newCollection(1, 2, 5, 10, 20, 50, 100, 200, 500); - for (int32_t k = 0; k < tokCount.size(); ++k) - { + for (int32_t k = 0; k < tokCount.size(); ++k) { StringStream buffer; // std::cout << "-----Tokens: " << tokCount[k] << "-----"; - for (int32_t i = 0; i < tokCount[k]; ++i) + for (int32_t i = 0; i < tokCount[k]; ++i) { buffer << StringUtils::toUpper(intToEnglish(i)) << L" "; + } // make sure we produce the same tokens TeeSinkTokenFilterPtr teeStream = newLucene(newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, newLucene(buffer.str())))); TokenStreamPtr sink = teeStream->newSinkTokenStream(newLucene(100)); @@ -204,43 +189,43 @@ TEST_F(TeeSinkTokenFilterTest, testPerformance) TokenStreamPtr stream = newLucene(newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, newLucene(buffer.str()))), 100); TermAttributePtr tfTok = stream->addAttribute(); TermAttributePtr sinkTok = sink->addAttribute(); - for (int32_t i = 0; stream->incrementToken(); ++i) - { + for (int32_t i = 0; stream->incrementToken(); ++i) { EXPECT_TRUE(sink->incrementToken()); EXPECT_TRUE(tfTok->equals(sinkTok)); } // simulate two fields, each being analyzed once, for 20 documents - for (int32_t j = 0; j < modCounts.size(); ++j) - { + for (int32_t j = 0; j < modCounts.size(); ++j) { int32_t tfPos = 0; int64_t start = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { stream = newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, newLucene(buffer.str()))); PositionIncrementAttributePtr posIncrAtt = stream->getAttribute(); - while (stream->incrementToken()) + while (stream->incrementToken()) { tfPos += posIncrAtt->getPositionIncrement(); + } stream = newLucene(newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, newLucene(buffer.str()))), modCounts[j]); posIncrAtt = stream->getAttribute(); - while (stream->incrementToken()) + while (stream->incrementToken()) { tfPos += posIncrAtt->getPositionIncrement(); + } } int64_t finish = MiscUtils::currentTimeMillis(); // std::cout << "ModCount: " << modCounts[j] << " Two fields took " << (finish - start) << " ms"; int32_t sinkPos = 0; // simulate one field with one sink start = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { teeStream = newLucene(newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, newLucene(buffer.str())))); sink = teeStream->newSinkTokenStream(newLucene(modCounts[j])); PositionIncrementAttributePtr posIncrAtt = teeStream->getAttribute(); - while (teeStream->incrementToken()) + while (teeStream->incrementToken()) { sinkPos += posIncrAtt->getPositionIncrement(); + } posIncrAtt = sink->getAttribute(); - while (sink->incrementToken()) + while (sink->incrementToken()) { sinkPos += posIncrAtt->getPositionIncrement(); + } } finish = MiscUtils::currentTimeMillis(); // std::cout << "ModCount: " << modCounts[j] << " Tee fields took " << (finish - start) << " ms"; diff --git a/src/test/analysis/TokenTest.cpp b/src/test/analysis/TokenTest.cpp index e2495a24..96569659 100644 --- a/src/test/analysis/TokenTest.cpp +++ b/src/test/analysis/TokenTest.cpp @@ -13,8 +13,7 @@ using namespace Lucene; typedef LuceneTestFixture TokenTest; -static AttributePtr checkCloneIsEqual(const AttributePtr& att) -{ +static AttributePtr checkCloneIsEqual(const AttributePtr& att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); EXPECT_TRUE(att->equals(clone)); EXPECT_EQ(att->hashCode(), clone->hashCode()); @@ -22,8 +21,7 @@ static AttributePtr checkCloneIsEqual(const AttributePtr& att) } template -static AttributePtr checkCopyIsEqual(const AttributePtr& att) -{ +static AttributePtr checkCopyIsEqual(const AttributePtr& att) { AttributePtr copy = newLucene(); att->copyTo(copy); EXPECT_TRUE(att->equals(copy)); @@ -31,8 +29,7 @@ static AttributePtr checkCopyIsEqual(const AttributePtr& att) return copy; } -TEST_F(TokenTest, testCtor) -{ +TEST_F(TokenTest, testCtor) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); EXPECT_EQ(L"hello", t->term()); @@ -59,25 +56,21 @@ TEST_F(TokenTest, testCtor) EXPECT_EQ(0, t->getFlags()); } -TEST_F(TokenTest, testResize) -{ +TEST_F(TokenTest, testResize) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); - for (int32_t i = 0; i < 2000; ++i) - { + for (int32_t i = 0; i < 2000; ++i) { t->resizeTermBuffer(i); EXPECT_TRUE(i <= t->termBuffer().size()); EXPECT_EQ(L"hello", t->term()); } } -TEST_F(TokenTest, testGrow) -{ +TEST_F(TokenTest, testGrow) { TokenPtr t = newLucene(); StringStream buf; buf << L"ab"; - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { String content = buf.str(); t->setTermBuffer(content); EXPECT_EQ(content.length(), t->termLength()); @@ -91,8 +84,7 @@ TEST_F(TokenTest, testGrow) t = newLucene(); buf.str(L""); buf << L"a"; - for (int32_t i = 0; i < 20000; ++i) - { + for (int32_t i = 0; i < 20000; ++i) { String content = buf.str(); t->setTermBuffer(content); EXPECT_EQ(content.length(), t->termLength()); @@ -103,8 +95,7 @@ TEST_F(TokenTest, testGrow) EXPECT_EQ(20167, t->termBuffer().size()); } -TEST_F(TokenTest, testToString) -{ +TEST_F(TokenTest, testToString) { TokenPtr t = newLucene(L"", 0, 5); t->setTermBuffer(L"aloha"); EXPECT_EQ(L"(aloha,0,5)", t->toString()); @@ -113,8 +104,7 @@ TEST_F(TokenTest, testToString) EXPECT_EQ(L"(hi there,0,5)", t->toString()); } -TEST_F(TokenTest, testTermBufferEquals) -{ +TEST_F(TokenTest, testTermBufferEquals) { TokenPtr t1a = newLucene(); t1a->setTermBuffer(L"hello"); TokenPtr t1b = newLucene(); @@ -126,8 +116,7 @@ TEST_F(TokenTest, testTermBufferEquals) EXPECT_TRUE(!t2->equals(t1b)); } -TEST_F(TokenTest, testMixedStringArray) -{ +TEST_F(TokenTest, testMixedStringArray) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); EXPECT_EQ(t->termLength(), 5); @@ -152,8 +141,7 @@ TEST_F(TokenTest, testMixedStringArray) EXPECT_EQ(t->term(), L"hollo3"); } -TEST_F(TokenTest, testClone) -{ +TEST_F(TokenTest, testClone) { TokenPtr t = newLucene(); t->setTermBuffer(L"hello"); CharArray buf = t->termBuffer(); @@ -174,8 +162,7 @@ TEST_F(TokenTest, testClone) EXPECT_NE(pl, clone->getPayload()); } -TEST_F(TokenTest, testCopyTo) -{ +TEST_F(TokenTest, testCopyTo) { TokenPtr t = newLucene(); TokenPtr copy = boost::dynamic_pointer_cast(checkCopyIsEqual(t)); EXPECT_EQ(L"", t->term()); diff --git a/src/test/analysis/standard/StandardAnalyzerTest.cpp b/src/test/analysis/standard/StandardAnalyzerTest.cpp index 01175ef3..389474a9 100644 --- a/src/test/analysis/standard/StandardAnalyzerTest.cpp +++ b/src/test/analysis/standard/StandardAnalyzerTest.cpp @@ -12,15 +12,13 @@ using namespace Lucene; typedef BaseTokenStreamFixture StandardAnalyzerTest; -TEST_F(StandardAnalyzerTest, testMaxTermLength) -{ +TEST_F(StandardAnalyzerTest, testMaxTermLength) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); sa->setMaxTokenLength(5); checkAnalyzesTo(sa, L"ab cd toolong xy z", newCollection(L"ab", L"cd", L"xy", L"z")); } -TEST_F(StandardAnalyzerTest, testMaxTermLength2) -{ +TEST_F(StandardAnalyzerTest, testMaxTermLength2) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"ab cd toolong xy z", newCollection(L"ab", L"cd", L"toolong", L"xy", L"z")); @@ -28,32 +26,28 @@ TEST_F(StandardAnalyzerTest, testMaxTermLength2) checkAnalyzesTo(sa, L"ab cd toolong xy z", newCollection(L"ab", L"cd", L"xy", L"z"), newCollection(1, 1, 2, 1)); } -TEST_F(StandardAnalyzerTest, testMaxTermLength3) -{ +TEST_F(StandardAnalyzerTest, testMaxTermLength3) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); String longTerm(255, L'a'); checkAnalyzesTo(sa, L"ab cd " + longTerm + L" xy z", newCollection(L"ab", L"cd", longTerm, L"xy", L"z")); checkAnalyzesTo(sa, L"ab cd " + longTerm + L"a xy z", newCollection(L"ab", L"cd", L"xy", L"z")); } -TEST_F(StandardAnalyzerTest, testAlphanumeric) -{ +TEST_F(StandardAnalyzerTest, testAlphanumeric) { // alphanumeric tokens StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"B2B", newCollection(L"b2b")); checkAnalyzesTo(sa, L"2B", newCollection(L"2b")); } -TEST_F(StandardAnalyzerTest, testUnderscores) -{ +TEST_F(StandardAnalyzerTest, testUnderscores) { // underscores are delimiters, but not in email addresses (below) StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"word_having_underscore", newCollection(L"word", L"having", L"underscore")); checkAnalyzesTo(sa, L"word_with_underscore_and_stopwords", newCollection(L"word", L"underscore", L"stopwords")); } -TEST_F(StandardAnalyzerTest, testDelimiters) -{ +TEST_F(StandardAnalyzerTest, testDelimiters) { // other delimiters: "-", "/", "," StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"some-dashed-phrase", newCollection(L"some", L"dashed", L"phrase")); @@ -61,8 +55,7 @@ TEST_F(StandardAnalyzerTest, testDelimiters) checkAnalyzesTo(sa, L"ac/dc", newCollection(L"ac", L"dc")); } -TEST_F(StandardAnalyzerTest, testApostrophes) -{ +TEST_F(StandardAnalyzerTest, testApostrophes) { // internal apostrophes: O'Reilly, you're, O'Reilly's possessives are actually removed by StardardFilter, not the tokenizer StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -74,8 +67,7 @@ TEST_F(StandardAnalyzerTest, testApostrophes) checkAnalyzesTo(sa, L"O'Reilly's", newCollection(L"o'reilly")); } -TEST_F(StandardAnalyzerTest, testTSADash) -{ +TEST_F(StandardAnalyzerTest, testTSADash) { // t and s had been stopwords in Lucene <= 2.0, which made it impossible to correctly search for these terms StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"s-class", newCollection(L"s", L"class")); @@ -85,16 +77,14 @@ TEST_F(StandardAnalyzerTest, testTSADash) checkAnalyzesTo(sa, L"a-class", newCollection(L"class")); } -TEST_F(StandardAnalyzerTest, testCompanyNames) -{ +TEST_F(StandardAnalyzerTest, testCompanyNames) { // internal apostrophes: O'Reilly, you're, O'Reilly's possessives are actually removed by StardardFilter, not the tokenizer StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"AT&T", newCollection(L"at&t")); checkAnalyzesTo(sa, L"Excite@Home", newCollection(L"excite@home")); } -TEST_F(StandardAnalyzerTest, testDomainNames) -{ +TEST_F(StandardAnalyzerTest, testDomainNames) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); // domain names @@ -112,8 +102,7 @@ TEST_F(StandardAnalyzerTest, testDomainNames) EXPECT_NO_THROW(checkAnalyzesTo(sa, L"www.nutch.org.", newCollection(L"www.nutch.org"), newCollection(L""))); } -TEST_F(StandardAnalyzerTest, testEMailAddresses) -{ +TEST_F(StandardAnalyzerTest, testEMailAddresses) { // email addresses, possibly with underscores, periods, etc StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"test@example.com", newCollection(L"test@example.com")); @@ -121,8 +110,7 @@ TEST_F(StandardAnalyzerTest, testEMailAddresses) checkAnalyzesTo(sa, L"first_lastname@example.com", newCollection(L"first_lastname@example.com")); } -TEST_F(StandardAnalyzerTest, testNumeric) -{ +TEST_F(StandardAnalyzerTest, testNumeric) { // floating point, serial, model numbers, ip addresses, etc. // every other segment must have at least one digit StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); @@ -134,14 +122,12 @@ TEST_F(StandardAnalyzerTest, testNumeric) checkAnalyzesTo(sa, L"R2D2 C3PO", newCollection(L"r2d2", L"c3po")); } -TEST_F(StandardAnalyzerTest, testTextWithNumbers) -{ +TEST_F(StandardAnalyzerTest, testTextWithNumbers) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"David has 5000 bones", newCollection(L"david", L"has", L"5000", L"bones")); } -TEST_F(StandardAnalyzerTest, testVariousText) -{ +TEST_F(StandardAnalyzerTest, testVariousText) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"C embedded developers wanted", newCollection(L"c", L"embedded", L"developers", L"wanted")); checkAnalyzesTo(sa, L"foo bar FOO BAR", newCollection(L"foo", L"bar", L"foo", L"bar")); @@ -149,62 +135,53 @@ TEST_F(StandardAnalyzerTest, testVariousText) checkAnalyzesTo(sa, L"\"QUOTED\" word", newCollection(L"quoted", L"word")); } -TEST_F(StandardAnalyzerTest, testAcronyms) -{ +TEST_F(StandardAnalyzerTest, testAcronyms) { // acronyms have their dots stripped StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"U.S.A.", newCollection(L"usa")); } -TEST_F(StandardAnalyzerTest, testCPlusPlusHash) -{ +TEST_F(StandardAnalyzerTest, testCPlusPlusHash) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"C++", newCollection(L"c")); checkAnalyzesTo(sa, L"C#", newCollection(L"c")); } -TEST_F(StandardAnalyzerTest, testComplianceFileName) -{ +TEST_F(StandardAnalyzerTest, testComplianceFileName) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"2004.jpg", newCollection(L"2004.jpg"), newCollection(L"")); } -TEST_F(StandardAnalyzerTest, testComplianceNumericIncorrect) -{ +TEST_F(StandardAnalyzerTest, testComplianceNumericIncorrect) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"62.46", newCollection(L"62.46"), newCollection(L"")); } -TEST_F(StandardAnalyzerTest, testComplianceNumericLong) -{ +TEST_F(StandardAnalyzerTest, testComplianceNumericLong) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"978-0-94045043-1", newCollection(L"978-0-94045043-1"), newCollection(L"")); } -TEST_F(StandardAnalyzerTest, testComplianceNumericFile) -{ +TEST_F(StandardAnalyzerTest, testComplianceNumericFile) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"78academyawards/rules/rule02.html", newCollection(L"78academyawards/rules/rule02.html"), newCollection(L"")); } -TEST_F(StandardAnalyzerTest, testComplianceNumericWithUnderscores) -{ +TEST_F(StandardAnalyzerTest, testComplianceNumericWithUnderscores) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"2006-03-11t082958z_01_ban130523_rtridst_0_ozabs", newCollection(L"2006-03-11t082958z_01_ban130523_rtridst_0_ozabs"), newCollection(L"")); } -TEST_F(StandardAnalyzerTest, testComplianceNumericWithDash) -{ +TEST_F(StandardAnalyzerTest, testComplianceNumericWithDash) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"mid-20th", newCollection(L"mid-20th"), newCollection(L"")); } -TEST_F(StandardAnalyzerTest, testComplianceManyTokens) -{ +TEST_F(StandardAnalyzerTest, testComplianceManyTokens) { StandardAnalyzerPtr sa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(sa, L"/money.cnn.com/magazines/fortune/fortune_archive/2007/03/19/8402357/index.htm safari-0-sheikh-zayed-grand-mosque.jpg", newCollection(L"money.cnn.com", L"magazines", L"fortune", L"fortune", L"archive/2007/03/19/8402357", L"index.htm", L"safari-0-sheikh", L"zayed", L"grand", L"mosque.jpg"), newCollection(L"", L"", L"", L"", L"", L"", L"", - L"", L"", L"")); + L"", L"", L"")); } diff --git a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp index d303c5c7..d1ab837d 100644 --- a/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/SimpleAttributeTest.cpp @@ -18,8 +18,7 @@ using namespace Lucene; typedef LuceneTestFixture SimpleAttributeTest; -static AttributePtr checkCloneIsEqual(const AttributePtr& att) -{ +static AttributePtr checkCloneIsEqual(const AttributePtr& att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); EXPECT_TRUE(att->equals(clone)); EXPECT_EQ(att->hashCode(), clone->hashCode()); @@ -27,8 +26,7 @@ static AttributePtr checkCloneIsEqual(const AttributePtr& att) } template -static AttributePtr checkCopyIsEqual(const AttributePtr& att) -{ +static AttributePtr checkCopyIsEqual(const AttributePtr& att) { AttributePtr copy = newLucene(); att->copyTo(copy); EXPECT_TRUE(att->equals(copy)); @@ -36,8 +34,7 @@ static AttributePtr checkCopyIsEqual(const AttributePtr& att) return copy; } -TEST_F(SimpleAttributeTest, testFlagsAttribute) -{ +TEST_F(SimpleAttributeTest, testFlagsAttribute) { FlagsAttributePtr att = newLucene(); EXPECT_EQ(0, att->getFlags()); @@ -54,8 +51,7 @@ TEST_F(SimpleAttributeTest, testFlagsAttribute) EXPECT_EQ(0, att->getFlags()); } -TEST_F(SimpleAttributeTest, testPositionIncrementAttribute) -{ +TEST_F(SimpleAttributeTest, testPositionIncrementAttribute) { PositionIncrementAttributePtr att = newLucene(); EXPECT_EQ(1, att->getPositionIncrement()); @@ -72,24 +68,22 @@ TEST_F(SimpleAttributeTest, testPositionIncrementAttribute) EXPECT_EQ(1, att->getPositionIncrement()); } -namespace TestTypeAttribute -{ - class TestableTypeAttribute : public TypeAttribute - { - public: - virtual ~TestableTypeAttribute() - { - } +namespace TestTypeAttribute { - LUCENE_CLASS(TestableTypeAttribute); +class TestableTypeAttribute : public TypeAttribute { +public: + virtual ~TestableTypeAttribute() { + } + + LUCENE_CLASS(TestableTypeAttribute); + +public: + using TypeAttribute::DEFAULT_TYPE; +}; - public: - using TypeAttribute::DEFAULT_TYPE; - }; } -TEST_F(SimpleAttributeTest, testTypeAttribute) -{ +TEST_F(SimpleAttributeTest, testTypeAttribute) { TypeAttributePtr att = newLucene(); EXPECT_EQ(TestTypeAttribute::TestableTypeAttribute::DEFAULT_TYPE(), att->type()); @@ -106,8 +100,7 @@ TEST_F(SimpleAttributeTest, testTypeAttribute) EXPECT_EQ(TestTypeAttribute::TestableTypeAttribute::DEFAULT_TYPE(), att->type()); } -TEST_F(SimpleAttributeTest, testPayloadAttribute) -{ +TEST_F(SimpleAttributeTest, testPayloadAttribute) { PayloadAttributePtr att = newLucene(); EXPECT_TRUE(!att->getPayload()); @@ -132,8 +125,7 @@ TEST_F(SimpleAttributeTest, testPayloadAttribute) EXPECT_TRUE(!att->getPayload()); } -TEST_F(SimpleAttributeTest, testOffsetAttribute) -{ +TEST_F(SimpleAttributeTest, testOffsetAttribute) { OffsetAttributePtr att = newLucene(); EXPECT_EQ(0, att->startOffset()); EXPECT_EQ(0, att->endOffset()); diff --git a/src/test/analysis/tokenattributes/TermAttributeTest.cpp b/src/test/analysis/tokenattributes/TermAttributeTest.cpp index 40d4b999..d0a350de 100644 --- a/src/test/analysis/tokenattributes/TermAttributeTest.cpp +++ b/src/test/analysis/tokenattributes/TermAttributeTest.cpp @@ -13,8 +13,7 @@ using namespace Lucene; typedef LuceneTestFixture TermAttributeTest; -static AttributePtr checkCloneIsEqual(const AttributePtr& att) -{ +static AttributePtr checkCloneIsEqual(const AttributePtr& att) { AttributePtr clone = boost::dynamic_pointer_cast(att->clone()); EXPECT_TRUE(att->equals(clone)); EXPECT_EQ(att->hashCode(), clone->hashCode()); @@ -22,8 +21,7 @@ static AttributePtr checkCloneIsEqual(const AttributePtr& att) } template -static AttributePtr checkCopyIsEqual(const AttributePtr& att) -{ +static AttributePtr checkCopyIsEqual(const AttributePtr& att) { AttributePtr copy = newLucene(); att->copyTo(copy); EXPECT_TRUE(att->equals(copy)); @@ -31,25 +29,21 @@ static AttributePtr checkCopyIsEqual(const AttributePtr& att) return copy; } -TEST_F(TermAttributeTest, testResize) -{ +TEST_F(TermAttributeTest, testResize) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"hello"); - for (int32_t i = 0; i < 2000; ++i) - { + for (int32_t i = 0; i < 2000; ++i) { t->resizeTermBuffer(i); EXPECT_TRUE(i <= t->termBuffer().size()); EXPECT_EQ(L"hello", t->term()); } } -TEST_F(TermAttributeTest, testGrow) -{ +TEST_F(TermAttributeTest, testGrow) { TermAttributePtr t = newLucene(); StringStream buf; buf << L"ab"; - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { String content = buf.str(); t->setTermBuffer(content); EXPECT_EQ(content.length(), t->termLength()); @@ -63,8 +57,7 @@ TEST_F(TermAttributeTest, testGrow) t = newLucene(); buf.str(L""); buf << L"a"; - for (int32_t i = 0; i < 20000; ++i) - { + for (int32_t i = 0; i < 20000; ++i) { String content = buf.str(); t->setTermBuffer(content); EXPECT_EQ(content.length(), t->termLength()); @@ -75,8 +68,7 @@ TEST_F(TermAttributeTest, testGrow) EXPECT_EQ(20167, t->termBuffer().size()); } -TEST_F(TermAttributeTest, testToString) -{ +TEST_F(TermAttributeTest, testToString) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"aloha"); EXPECT_EQ(L"term=aloha", t->toString()); @@ -85,8 +77,7 @@ TEST_F(TermAttributeTest, testToString) EXPECT_EQ(L"term=hi there", t->toString()); } -TEST_F(TermAttributeTest, testMixedStringArray) -{ +TEST_F(TermAttributeTest, testMixedStringArray) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"hello"); EXPECT_EQ(t->termLength(), 5); @@ -112,8 +103,7 @@ TEST_F(TermAttributeTest, testMixedStringArray) EXPECT_EQ(t->term(), L"hollo3"); } -TEST_F(TermAttributeTest, testClone) -{ +TEST_F(TermAttributeTest, testClone) { TermAttributePtr t = newLucene(); t->setTermBuffer(L"hello"); CharArray buf = t->termBuffer(); @@ -122,8 +112,7 @@ TEST_F(TermAttributeTest, testClone) EXPECT_TRUE(buf != clone->termBuffer()); } -TEST_F(TermAttributeTest, testEquals) -{ +TEST_F(TermAttributeTest, testEquals) { TermAttributePtr t1a = newLucene(); t1a->setTermBuffer(L"hello"); TermAttributePtr t1b = newLucene(); @@ -135,8 +124,7 @@ TEST_F(TermAttributeTest, testEquals) EXPECT_TRUE(!t2->equals(t1b)); } -TEST_F(TermAttributeTest, testCopyTo) -{ +TEST_F(TermAttributeTest, testCopyTo) { TermAttributePtr t = newLucene(); TermAttributePtr copy = boost::dynamic_pointer_cast(checkCopyIsEqual(t)); EXPECT_EQ(L"", t->term()); diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp index cd0b4b9e..f1739c5b 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicAnalyzerTest.cpp @@ -14,72 +14,63 @@ typedef BaseTokenStreamFixture ArabicAnalyzerTest; /// Some simple tests showing some features of the analyzer, how some regular forms will conflate -TEST_F(ArabicAnalyzerTest, testBasicFeatures1) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures1) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures2) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures2) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa9}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures3) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures3) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8}; const uint8_t second[] = {0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures4) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures4) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xaa}; const uint8_t second[] = {0xd9, 0x85, 0xd8, 0xb4, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures5) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures5) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa3, 0xd9, 0x85, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a, 0xd9, 0x8a, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x83}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures6) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures6) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x83, 0xd9, 0x8a}; const uint8_t second[] = {0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb1, 0xd9, 0x8a, 0xd9, 0x83}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures7) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures7) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures8) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures8) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures9) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures9) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd8, 0xa7, 0x20, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0x20, 0xd8, 0xa3, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x85}; const uint8_t second[] = {0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa}; @@ -87,8 +78,7 @@ TEST_F(ArabicAnalyzerTest, testBasicFeatures9) checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second), UTF8_TO_STRING(third))); } -TEST_F(ArabicAnalyzerTest, testBasicFeatures10) -{ +TEST_F(ArabicAnalyzerTest, testBasicFeatures10) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xb0, 0xd9, 0x8a, 0xd9, 0x86, 0x20, 0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa, 0x20, 0xd8, 0xa3, 0xd9, 0x8a, 0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x86, 0xd9, 0x83, 0xd9, 0x85}; const uint8_t second[] = {0xd9, 0x85, 0xd9, 0x84, 0xd9, 0x83, 0xd8, 0xaa}; @@ -97,16 +87,14 @@ TEST_F(ArabicAnalyzerTest, testBasicFeatures10) } /// Simple tests to show things are getting reset correctly, etc. -TEST_F(ArabicAnalyzerTest, testReusableTokenStream1) -{ +TEST_F(ArabicAnalyzerTest, testReusableTokenStream1) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; checkAnalyzesToReuse(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(ArabicAnalyzerTest, testReusableTokenStream2) -{ +TEST_F(ArabicAnalyzerTest, testReusableTokenStream2) { ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1, 0xd8, 0xa9}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xa8, 0xd9, 0x8a, 0xd8, 0xb1}; @@ -114,14 +102,12 @@ TEST_F(ArabicAnalyzerTest, testReusableTokenStream2) } /// Non-arabic text gets treated in a similar way as SimpleAnalyzer. -TEST_F(ArabicAnalyzerTest, testEnglishInput) -{ +TEST_F(ArabicAnalyzerTest, testEnglishInput) { checkAnalyzesTo(newLucene(LuceneVersion::LUCENE_CURRENT), L"English text.", newCollection(L"english", L"text")); } /// Test that custom stopwords work, and are not case-sensitive. -TEST_F(ArabicAnalyzerTest, testCustomStopwords) -{ +TEST_F(ArabicAnalyzerTest, testCustomStopwords) { Collection stopWords = newCollection(L"the", L"and", L"a"); ArabicAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance(stopWords.begin(), stopWords.end())); checkAnalyzesTo(a, L"The quick brown fox.", newCollection(L"quick", L"brown", L"fox")); diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp index 85b649c1..86712d9d 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicNormalizationFilterTest.cpp @@ -12,115 +12,98 @@ using namespace Lucene; -class ArabicNormalizationFilterTest : public BaseTokenStreamFixture -{ +class ArabicNormalizationFilterTest : public BaseTokenStreamFixture { public: - virtual ~ArabicNormalizationFilterTest() - { + virtual ~ArabicNormalizationFilterTest() { } public: - void check(const String& input, const String& expected) - { + void check(const String& input, const String& expected) { ArabicLetterTokenizerPtr tokenStream = newLucene(newLucene(input)); ArabicNormalizationFilterPtr filter = newLucene(tokenStream); checkTokenStreamContents(filter, newCollection(expected)); } }; -TEST_F(ArabicNormalizationFilterTest, testAlifMadda) -{ +TEST_F(ArabicNormalizationFilterTest, testAlifMadda) { const uint8_t first[] = {0xd8, 0xa2, 0xd8, 0xac, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xac, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testAlifHamzaAbove) -{ +TEST_F(ArabicNormalizationFilterTest, testAlifHamzaAbove) { const uint8_t first[] = {0xd8, 0xa3, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xad, 0xd9, 0x85, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testAlifHamzaBelow) -{ +TEST_F(ArabicNormalizationFilterTest, testAlifHamzaBelow) { const uint8_t first[] = {0xd8, 0xa5, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xb0}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xb9, 0xd8, 0xa7, 0xd8, 0xb0}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testAlifMaksura) -{ +TEST_F(ArabicNormalizationFilterTest, testAlifMaksura) { const uint8_t first[] = {0xd8, 0xa8, 0xd9, 0x86, 0xd9, 0x89}; const uint8_t second[] = {0xd8, 0xa8, 0xd9, 0x86, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testTehMarbuta) -{ +TEST_F(ArabicNormalizationFilterTest, testTehMarbuta) { const uint8_t first[] = {0xd9, 0x81, 0xd8, 0xa7, 0xd8, 0xb7, 0xd9, 0x85, 0xd8, 0xa9}; const uint8_t second[] = {0xd9, 0x81, 0xd8, 0xa7, 0xd8, 0xb7, 0xd9, 0x85, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testTatweel) -{ +TEST_F(ArabicNormalizationFilterTest, testTatweel) { const uint8_t first[] = {0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xb1, 0xd9, 0x80, 0xd9, 0x80, 0xd9, 0x80, 0xd9, 0x80, 0xd9, 0x80, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xb1, 0xd8, 0xaa}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testFatha) -{ +TEST_F(ArabicNormalizationFilterTest, testFatha) { const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8e, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7}; const uint8_t second[] = {0xd9, 0x85, 0xd8, 0xa8, 0xd9, 0x86, 0xd8, 0xa7}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testKasra) -{ +TEST_F(ArabicNormalizationFilterTest, testKasra) { const uint8_t first[] = {0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x90, 0xd9, 0x8a}; const uint8_t second[] = {0xd8, 0xb9, 0xd9, 0x84, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testDamma) -{ +TEST_F(ArabicNormalizationFilterTest, testDamma) { const uint8_t first[] = {0xd8, 0xa8, 0xd9, 0x8f, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xa7, 0xd8, 0xaa}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testFathatan) -{ +TEST_F(ArabicNormalizationFilterTest, testFathatan) { const uint8_t first[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x8b}; const uint8_t second[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd8, 0xa7}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testKasratan) -{ +TEST_F(ArabicNormalizationFilterTest, testKasratan) { const uint8_t first[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8d}; const uint8_t second[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testDammatan) -{ +TEST_F(ArabicNormalizationFilterTest, testDammatan) { const uint8_t first[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf, 0xd9, 0x8c}; const uint8_t second[] = {0xd9, 0x88, 0xd9, 0x84, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testSukun) -{ +TEST_F(ArabicNormalizationFilterTest, testSukun) { const uint8_t first[] = {0xd9, 0x86, 0xd9, 0x84, 0xd9, 0x92, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x86}; const uint8_t second[] = {0xd9, 0x86, 0xd9, 0x84, 0xd8, 0xb3, 0xd9, 0x88, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicNormalizationFilterTest, testShaddah) -{ +TEST_F(ArabicNormalizationFilterTest, testShaddah) { const uint8_t first[] = {0xd9, 0x87, 0xd8, 0xaa, 0xd9, 0x85, 0xd9, 0x8a, 0xd9, 0x91}; const uint8_t second[] = {0xd9, 0x87, 0xd8, 0xaa, 0xd9, 0x85, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); diff --git a/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp index 00cb0534..a5c0b6a0 100644 --- a/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ar/ArabicStemFilterTest.cpp @@ -12,163 +12,139 @@ using namespace Lucene; -class ArabicStemFilterTest : public BaseTokenStreamFixture -{ +class ArabicStemFilterTest : public BaseTokenStreamFixture { public: - virtual ~ArabicStemFilterTest() - { + virtual ~ArabicStemFilterTest() { } public: - void check(const String& input, const String& expected) - { + void check(const String& input, const String& expected) { ArabicLetterTokenizerPtr tokenStream = newLucene(newLucene(input)); ArabicStemFilterPtr filter = newLucene(tokenStream); checkTokenStreamContents(filter, newCollection(expected)); } }; -TEST_F(ArabicStemFilterTest, testAlPrefix) -{ +TEST_F(ArabicStemFilterTest, testAlPrefix) { const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testWalPrefix) -{ +TEST_F(ArabicStemFilterTest, testWalPrefix) { const uint8_t first[] = {0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testBalPrefix) -{ +TEST_F(ArabicStemFilterTest, testBalPrefix) { const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testKalPrefix) -{ +TEST_F(ArabicStemFilterTest, testKalPrefix) { const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testFalPrefix) -{ +TEST_F(ArabicStemFilterTest, testFalPrefix) { const uint8_t first[] = {0xd9, 0x81, 0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testLlPrefix) -{ +TEST_F(ArabicStemFilterTest, testLlPrefix) { const uint8_t first[] = {0xd9, 0x84, 0xd9, 0x84, 0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xb1}; const uint8_t second[] = {0xd8, 0xa7, 0xd8, 0xae, 0xd8, 0xb1}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testWaPrefix) -{ +TEST_F(ArabicStemFilterTest, testWaPrefix) { const uint8_t first[] = {0xd9, 0x88, 0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xad, 0xd8, 0xb3, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testAhSuffix) -{ +TEST_F(ArabicStemFilterTest, testAhSuffix) { const uint8_t first[] = {0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xac, 0xd9, 0x87, 0xd8, 0xa7}; const uint8_t second[] = {0xd8, 0xb2, 0xd9, 0x88, 0xd8, 0xac}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testAnSuffix) -{ +TEST_F(ArabicStemFilterTest, testAnSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa7, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testAtSuffix) -{ +TEST_F(ArabicStemFilterTest, testAtSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testWnSuffix) -{ +TEST_F(ArabicStemFilterTest, testWnSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testYnSuffix) -{ +TEST_F(ArabicStemFilterTest, testYnSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testYhSuffix) -{ +TEST_F(ArabicStemFilterTest, testYhSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a, 0xd9, 0x87}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testYpSuffix) -{ +TEST_F(ArabicStemFilterTest, testYpSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa9}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testHSuffix) -{ +TEST_F(ArabicStemFilterTest, testHSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x87}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testPSuffix) -{ +TEST_F(ArabicStemFilterTest, testPSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd8, 0xa9}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testYSuffix) -{ +TEST_F(ArabicStemFilterTest, testYSuffix) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x8a}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testComboPrefSuf) -{ +TEST_F(ArabicStemFilterTest, testComboPrefSuf) { const uint8_t first[] = {0xd9, 0x88, 0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x88, 0xd9, 0x86}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testComboSuf) -{ +TEST_F(ArabicStemFilterTest, testComboSuf) { const uint8_t first[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0xd9, 0x87, 0xd8, 0xa7, 0xd8, 0xaa}; const uint8_t second[] = {0xd8, 0xb3, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testShouldntStem) -{ +TEST_F(ArabicStemFilterTest, testShouldntStem) { const uint8_t first[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x88}; const uint8_t second[] = {0xd8, 0xa7, 0xd9, 0x84, 0xd9, 0x88}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(ArabicStemFilterTest, testNonArabic) -{ +TEST_F(ArabicStemFilterTest, testNonArabic) { check(L"English", L"English"); } diff --git a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp index ec33363d..1fd6a2d8 100644 --- a/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/br/BrazilianStemmerTest.cpp @@ -10,21 +10,17 @@ using namespace Lucene; -class BrazilianStemmerTest : public BaseTokenStreamFixture -{ +class BrazilianStemmerTest : public BaseTokenStreamFixture { public: - virtual ~BrazilianStemmerTest() - { + virtual ~BrazilianStemmerTest() { } public: - void check(const String& input, const String& expected) - { + void check(const String& input, const String& expected) { checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) - { + void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } }; @@ -32,8 +28,7 @@ class BrazilianStemmerTest : public BaseTokenStreamFixture /// Test the Brazilian Stem Filter, which only modifies the term text. /// It is very similar to the snowball Portuguese algorithm but not exactly the same. -TEST_F(BrazilianStemmerTest, testWithSnowballExamples) -{ +TEST_F(BrazilianStemmerTest, testWithSnowballExamples) { check(L"boa", L"boa"); check(L"boainain", L"boainain"); check(L"boas", L"boas"); @@ -132,8 +127,7 @@ TEST_F(BrazilianStemmerTest, testWithSnowballExamples) check(L"quiosque", L"quiosqu"); } -TEST_F(BrazilianStemmerTest, testNormalization) -{ +TEST_F(BrazilianStemmerTest, testNormalization) { check(L"Brasil", L"brasil"); // lowercase by default const uint8_t brasil[] = {0x42, 0x72, 0x61, 0x73, 0xc3, 0xad, 0x6c, 0x69, 0x61}; check(UTF8_TO_STRING(brasil), L"brasil"); // remove diacritics @@ -145,8 +139,7 @@ TEST_F(BrazilianStemmerTest, testNormalization) check(UTF8_TO_STRING(aaa), L"aaa"); // normally, diacritics are removed } -TEST_F(BrazilianStemmerTest, testReusableTokenStream) -{ +TEST_F(BrazilianStemmerTest, testReusableTokenStream) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"boa", L"boa"); checkReuse(a, L"boainain", L"boainain"); @@ -155,8 +148,7 @@ TEST_F(BrazilianStemmerTest, testReusableTokenStream) checkReuse(a, UTF8_TO_STRING(boas), L"boas"); // removes diacritic: different from snowball Portuguese } -TEST_F(BrazilianStemmerTest, testStemExclusionTable) -{ +TEST_F(BrazilianStemmerTest, testStemExclusionTable) { BrazilianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); HashSet exclusions = HashSet::newInstance(); const uint8_t quintessencia[] = {0x71, 0x75, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x73, 0xc3, 0xaa, 0x6e, 0x63, 0x69, 0x61}; @@ -166,8 +158,7 @@ TEST_F(BrazilianStemmerTest, testStemExclusionTable) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -TEST_F(BrazilianStemmerTest, testExclusionTableReuse) -{ +TEST_F(BrazilianStemmerTest, testExclusionTableReuse) { BrazilianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t quintessencia[] = {0x71, 0x75, 0x69, 0x6e, 0x74, 0x65, 0x73, 0x73, 0xc3, 0xaa, 0x6e, 0x63, 0x69, 0x61}; checkReuse(a, UTF8_TO_STRING(quintessencia), L"quintessente"); diff --git a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp index 4ffa29f3..b4f325a6 100644 --- a/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cjk/CJKTokenizerTest.cpp @@ -11,18 +11,14 @@ using namespace Lucene; -class CJKTokenizerTest : public BaseTokenStreamFixture -{ +class CJKTokenizerTest : public BaseTokenStreamFixture { public: - virtual ~CJKTokenizerTest() - { + virtual ~CJKTokenizerTest() { } public: - struct TestToken - { - TestToken(const String& termText = L"", int32_t start = 0, int32_t end = 0, int32_t type = 0) - { + struct TestToken { + TestToken(const String& termText = L"", int32_t start = 0, int32_t end = 0, int32_t type = 0) { this->termText = termText; this->start = start; this->end = end; @@ -35,15 +31,13 @@ class CJKTokenizerTest : public BaseTokenStreamFixture String type; }; - void checkCJKToken(const String& str, Collection out_tokens) - { + void checkCJKToken(const String& str, Collection out_tokens) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); Collection terms = Collection::newInstance(out_tokens.size()); Collection startOffsets = Collection::newInstance(out_tokens.size()); Collection endOffsets = Collection::newInstance(out_tokens.size()); Collection types = Collection::newInstance(out_tokens.size()); - for (int32_t i = 0; i < out_tokens.size(); ++i) - { + for (int32_t i = 0; i < out_tokens.size(); ++i) { terms[i] = out_tokens[i].termText; startOffsets[i] = out_tokens[i].start; endOffsets[i] = out_tokens[i].end; @@ -52,14 +46,12 @@ class CJKTokenizerTest : public BaseTokenStreamFixture checkAnalyzesTo(analyzer, str, terms, startOffsets, endOffsets, types, Collection()); } - void checkCJKTokenReusable(const AnalyzerPtr& analyzer, const String& str, Collection out_tokens) - { + void checkCJKTokenReusable(const AnalyzerPtr& analyzer, const String& str, Collection out_tokens) { Collection terms = Collection::newInstance(out_tokens.size()); Collection startOffsets = Collection::newInstance(out_tokens.size()); Collection endOffsets = Collection::newInstance(out_tokens.size()); Collection types = Collection::newInstance(out_tokens.size()); - for (int32_t i = 0; i < out_tokens.size(); ++i) - { + for (int32_t i = 0; i < out_tokens.size(); ++i) { terms[i] = out_tokens[i].termText; startOffsets[i] = out_tokens[i].start; endOffsets[i] = out_tokens[i].end; @@ -69,11 +61,11 @@ class CJKTokenizerTest : public BaseTokenStreamFixture } }; -TEST_F(CJKTokenizerTest, testJa1) -{ +TEST_F(CJKTokenizerTest, testJa1) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0xe4, 0xba, 0x8c, 0xe4, 0xb8, 0x89, 0xe5, 0x9b, 0x9b, 0xe4, 0xba, 0x94, 0xe5, 0x85, 0xad, 0xe4, 0xb8, 0x83, 0xe5, 0x85, 0xab, - 0xe4, 0xb9, 0x9d, 0xe5, 0x8d, 0x81}; + 0xe4, 0xb9, 0x9d, 0xe5, 0x8d, 0x81 + }; const uint8_t token1[] = {0xe4, 0xb8, 0x80, 0xe4, 0xba, 0x8c}; const uint8_t token2[] = {0xe4, 0xba, 0x8c, 0xe4, 0xb8, 0x89}; @@ -86,24 +78,24 @@ TEST_F(CJKTokenizerTest, testJa1) const uint8_t token9[] = {0xe4, 0xb9, 0x9d, 0xe5, 0x8d, 0x81}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token5), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token7), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token8), 7, 9, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token9), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token5), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token7), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token8), 7, 9, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token9), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -TEST_F(CJKTokenizerTest, testJa2) -{ +TEST_F(CJKTokenizerTest, testJa2) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0x20, 0xe4, 0xba, 0x8c, 0xe4, 0xb8, 0x89, 0xe5, 0x9b, 0x9b, 0x20, 0xe4, 0xba, 0x94, 0xe5, 0x85, 0xad, 0xe4, 0xb8, - 0x83, 0xe5, 0x85, 0xab, 0xe4, 0xb9, 0x9d, 0x20, 0xe5, 0x8d, 0x81}; + 0x83, 0xe5, 0x85, 0xab, 0xe4, 0xb9, 0x9d, 0x20, 0xe5, 0x8d, 0x81 + }; const uint8_t token1[] = {0xe4, 0xb8, 0x80}; const uint8_t token2[] = {0xe4, 0xba, 0x8c, 0xe4, 0xb8, 0x89}; @@ -115,38 +107,37 @@ TEST_F(CJKTokenizerTest, testJa2) const uint8_t token8[] = {0xe5, 0x8d, 0x81}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token5), 7, 9, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token8), 12, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token5), 7, 9, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token8), 12, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -TEST_F(CJKTokenizerTest, testC) -{ +TEST_F(CJKTokenizerTest, testC) { String str = L"abc defgh ijklmn opqrstu vwxy z"; Collection out_tokens = newCollection( - TestToken(L"abc", 0, 3, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"defgh", 4, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"ijklmn", 10, 16, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"opqrstu", 17, 24, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"vwxy", 25, 29, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"z", 30, 31, CJKTokenizer::SINGLE_TOKEN_TYPE) - ); + TestToken(L"abc", 0, 3, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"defgh", 4, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"ijklmn", 10, 16, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"opqrstu", 17, 24, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"vwxy", 25, 29, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"z", 30, 31, CJKTokenizer::SINGLE_TOKEN_TYPE) + ); checkCJKToken(str, out_tokens); } -TEST_F(CJKTokenizerTest, testMix) -{ +TEST_F(CJKTokenizerTest, testMix) { const uint8_t str[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0x63, 0xe3, 0x81, 0x8b, 0xe3, - 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93}; + 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93 + }; const uint8_t token1[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84}; const uint8_t token2[] = {0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86}; @@ -158,24 +149,24 @@ TEST_F(CJKTokenizerTest, testMix) const uint8_t token9[] = {0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token9), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token9), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -TEST_F(CJKTokenizerTest, testMix2) -{ +TEST_F(CJKTokenizerTest, testMix2) { const uint8_t str[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0xe3, 0x82, 0x93, 0x63, 0xe3, - 0x81, 0x8b, 0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; + 0x81, 0x8b, 0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91 + }; const uint8_t token1[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84}; const uint8_t token2[] = {0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86}; @@ -187,48 +178,47 @@ TEST_F(CJKTokenizerTest, testMix2) const uint8_t token10[] = {0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token8), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token9), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token10), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token8), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token9), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token10), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -TEST_F(CJKTokenizerTest, testSingleChar) -{ +TEST_F(CJKTokenizerTest, testSingleChar) { const uint8_t str[] = {0xe4, 0xb8, 0x80}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(str), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(str), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } /// Full-width text is normalized to half-width -TEST_F(CJKTokenizerTest, testFullWidth) -{ +TEST_F(CJKTokenizerTest, testFullWidth) { const uint8_t str[] = {0xef, 0xbc, 0xb4, 0xef, 0xbd, 0x85, 0xef, 0xbd, 0x93, 0xef, 0xbd, 0x94, - 0x20, 0xef, 0xbc, 0x91, 0xef, 0xbc, 0x92, 0xef, 0xbc, 0x93, 0xef, 0xbc, 0x94}; + 0x20, 0xef, 0xbc, 0x91, 0xef, 0xbc, 0x92, 0xef, 0xbc, 0x93, 0xef, 0xbc, 0x94 + }; Collection out_tokens = newCollection( - TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(L"1234", 5, 9, CJKTokenizer::SINGLE_TOKEN_TYPE) - ); + TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(L"1234", 5, 9, CJKTokenizer::SINGLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } /// Non-english text (not just CJK) is treated the same as CJK: C1C2 C2C3 -TEST_F(CJKTokenizerTest, testNonIdeographic) -{ +TEST_F(CJKTokenizerTest, testNonIdeographic) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0x20, 0xd8, 0xb1, 0xd9, 0x88, 0xd8, 0xa8, 0xd8, 0xb1, - 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1}; + 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1 + }; const uint8_t token1[] = {0xe4, 0xb8, 0x80}; const uint8_t token2[] = {0xd8, 0xb1, 0xd9, 0x88}; @@ -240,24 +230,24 @@ TEST_F(CJKTokenizerTest, testNonIdeographic) const uint8_t token8[] = {0xd9, 0x8a, 0xd8, 0xb1}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token5), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token5), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } /// Non-english text with non-letters (non-spacing marks,etc) is treated as C1C2 C2C3, /// except for words are split around non-letters. -TEST_F(CJKTokenizerTest, testNonIdeographicNonLetter) -{ +TEST_F(CJKTokenizerTest, testNonIdeographicNonLetter) { const uint8_t str[] = {0xe4, 0xb8, 0x80, 0x20, 0xd8, 0xb1, 0xd9, 0x8f, 0xd9, 0x88, 0xd8, 0xa8, - 0xd8, 0xb1, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1}; + 0xd8, 0xb1, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x88, 0xd9, 0x8a, 0xd8, 0xb1 + }; const uint8_t token1[] = {0xe4, 0xb8, 0x80}; const uint8_t token2[] = {0xd8, 0xb1}; @@ -269,20 +259,19 @@ TEST_F(CJKTokenizerTest, testNonIdeographicNonLetter) const uint8_t token8[] = {0xd9, 0x8a, 0xd8, 0xb1}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token2), 2, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token3), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token4), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token5), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token6), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token7), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token8), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(token1), 0, 1, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token2), 2, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token3), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token4), 5, 7, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token5), 6, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token6), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token7), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token8), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKToken(UTF8_TO_STRING(str), out_tokens); } -TEST_F(CJKTokenizerTest, testTokenStream) -{ +TEST_F(CJKTokenizerTest, testTokenStream) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t token1[] = {0xe4, 0xb8, 0x80, 0xe4, 0xb8, 0x81, 0xe4, 0xb8, 0x82}; @@ -292,13 +281,13 @@ TEST_F(CJKTokenizerTest, testTokenStream) checkAnalyzesTo(analyzer, UTF8_TO_STRING(token1), newCollection(UTF8_TO_STRING(token2), UTF8_TO_STRING(token3))); } -TEST_F(CJKTokenizerTest, testReusableTokenStream) -{ +TEST_F(CJKTokenizerTest, testReusableTokenStream) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0x63, 0xe3, 0x81, 0x8b, 0xe3, 0x81, 0x8d, - 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93}; + 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93 + }; const uint8_t firstToken1[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84}; const uint8_t firstToken2[] = {0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86}; @@ -310,21 +299,22 @@ TEST_F(CJKTokenizerTest, testReusableTokenStream) const uint8_t firstToken9[] = {0xe3, 0x81, 0x91, 0xe3, 0x81, 0x93}; Collection out_tokens = newCollection( - TestToken(UTF8_TO_STRING(firstToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(firstToken9), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(firstToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"abc", 5, 8, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken6), 8, 10, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken7), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken8), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(firstToken9), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKTokenReusable(analyzer, UTF8_TO_STRING(first), out_tokens); const uint8_t second[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a, 0x61, 0x62, 0xe3, 0x82, 0x93, 0x63, 0xe3, 0x81, 0x8b, - 0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; + 0xe3, 0x81, 0x8d, 0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91 + }; const uint8_t secondToken1[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84}; const uint8_t secondToken2[] = {0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86}; @@ -336,22 +326,21 @@ TEST_F(CJKTokenizerTest, testReusableTokenStream) const uint8_t secondToken10[] = {0xe3, 0x81, 0x8f, 0xe3, 0x81, 0x91}; Collection out_tokens2 = newCollection( - TestToken(UTF8_TO_STRING(secondToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken8), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken9), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(secondToken10), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) - ); + TestToken(UTF8_TO_STRING(secondToken1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken2), 1, 3, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken3), 2, 4, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken4), 3, 5, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"ab", 5, 7, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken6), 7, 8, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"c", 8, 9, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken8), 9, 11, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken9), 10, 12, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(secondToken10), 11, 13, CJKTokenizer::DOUBLE_TOKEN_TYPE) + ); checkCJKTokenReusable(analyzer, UTF8_TO_STRING(second), out_tokens2); } -TEST_F(CJKTokenizerTest, testFinalOffset) -{ +TEST_F(CJKTokenizerTest, testFinalOffset) { const uint8_t token1[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84}; checkCJKToken(UTF8_TO_STRING(token1), newCollection(TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE))); @@ -363,11 +352,11 @@ TEST_F(CJKTokenizerTest, testFinalOffset) const uint8_t token3[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0x74, 0x65, 0x73, 0x74}; checkCJKToken(UTF8_TO_STRING(token3), newCollection( - TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), - TestToken(L"test", 2, 6, CJKTokenizer::SINGLE_TOKEN_TYPE))); + TestToken(UTF8_TO_STRING(token1), 0, 2, CJKTokenizer::DOUBLE_TOKEN_TYPE), + TestToken(L"test", 2, 6, CJKTokenizer::SINGLE_TOKEN_TYPE))); const uint8_t token4[] = {0x74, 0x65, 0x73, 0x74, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0x20, 0x20, 0x20, 0x20}; checkCJKToken(UTF8_TO_STRING(token4), newCollection( - TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE), - TestToken(UTF8_TO_STRING(token1), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE))); + TestToken(L"test", 0, 4, CJKTokenizer::SINGLE_TOKEN_TYPE), + TestToken(UTF8_TO_STRING(token1), 4, 6, CJKTokenizer::DOUBLE_TOKEN_TYPE))); } diff --git a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp index df1e6884..f81d707f 100644 --- a/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cn/ChineseTokenizerTest.cpp @@ -17,48 +17,40 @@ using namespace Lucene; /// Analyzer that just uses ChineseTokenizer, not ChineseFilter. /// Convenience to show the behaviour of the tokenizer -class JustChineseTokenizerAnalyzer : public Analyzer -{ +class JustChineseTokenizerAnalyzer : public Analyzer { public: - virtual ~JustChineseTokenizerAnalyzer() - { + virtual ~JustChineseTokenizerAnalyzer() { } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } }; /// Analyzer that just uses ChineseFilter, not ChineseTokenizer. /// Convenience to show the behavior of the filter. -class JustChineseFilterAnalyzer : public Analyzer -{ +class JustChineseFilterAnalyzer : public Analyzer { public: - virtual ~JustChineseFilterAnalyzer() - { + virtual ~JustChineseFilterAnalyzer() { } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } }; typedef BaseTokenStreamFixture ChineseTokenizerTest; -TEST_F(ChineseTokenizerTest, testOtherLetterOffset) -{ +TEST_F(ChineseTokenizerTest, testOtherLetterOffset) { const uint8_t token[] = {0x61, 0xe5, 0xa4, 0xa9, 0x62}; ChineseTokenizerPtr tokenizer = newLucene(newLucene(UTF8_TO_STRING(token))); int32_t correctStartOffset = 0; int32_t correctEndOffset = 1; OffsetAttributePtr offsetAtt = tokenizer->getAttribute(); - while (tokenizer->incrementToken()) - { + while (tokenizer->incrementToken()) { EXPECT_EQ(correctStartOffset, offsetAtt->startOffset()); EXPECT_EQ(correctEndOffset, offsetAtt->endOffset()); ++correctStartOffset; @@ -66,12 +58,12 @@ TEST_F(ChineseTokenizerTest, testOtherLetterOffset) } } -TEST_F(ChineseTokenizerTest, testReusableTokenStream1) -{ +TEST_F(ChineseTokenizerTest, testReusableTokenStream1) { AnalyzerPtr a = newLucene(); const uint8_t input[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, - 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd}; + 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd + }; const uint8_t token1[] = {0xe4, 0xb8, 0xad}; const uint8_t token2[] = {0xe5, 0x8d, 0x8e}; @@ -82,21 +74,20 @@ TEST_F(ChineseTokenizerTest, testReusableTokenStream1) const uint8_t token7[] = {0xe5, 0x9b, 0xbd}; checkAnalyzesToReuse(a, UTF8_TO_STRING(input), - newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3), - UTF8_TO_STRING(token4), - UTF8_TO_STRING(token5), - UTF8_TO_STRING(token6), - UTF8_TO_STRING(token7) - ), - newCollection(0, 1, 2, 3, 4, 5, 6), - newCollection(1, 2, 3, 4, 5, 6, 7)); + newCollection( + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3), + UTF8_TO_STRING(token4), + UTF8_TO_STRING(token5), + UTF8_TO_STRING(token6), + UTF8_TO_STRING(token7) + ), + newCollection(0, 1, 2, 3, 4, 5, 6), + newCollection(1, 2, 3, 4, 5, 6, 7)); } -TEST_F(ChineseTokenizerTest, testReusableTokenStream2) -{ +TEST_F(ChineseTokenizerTest, testReusableTokenStream2) { AnalyzerPtr a = newLucene(); const uint8_t input[] = {0xe5, 0x8c, 0x97, 0xe4, 0xba, 0xac, 0xe5, 0xb8, 0x82}; @@ -106,18 +97,17 @@ TEST_F(ChineseTokenizerTest, testReusableTokenStream2) const uint8_t token3[] = {0xe5, 0xb8, 0x82}; checkAnalyzesToReuse(a, UTF8_TO_STRING(input), - newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3) - ), - newCollection(0, 1, 2), - newCollection(1, 2, 3)); + newCollection( + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3) + ), + newCollection(0, 1, 2), + newCollection(1, 2, 3)); } /// ChineseTokenizer tokenizes numbers as one token, but they are filtered by ChineseFilter -TEST_F(ChineseTokenizerTest, testNumerics) -{ +TEST_F(ChineseTokenizerTest, testNumerics) { AnalyzerPtr justTokenizer = newLucene(); const uint8_t input[] = {0xe4, 0xb8, 0xad, 0x31, 0x32, 0x33, 0x34}; @@ -135,8 +125,7 @@ TEST_F(ChineseTokenizerTest, testNumerics) /// /// ChineseFilter has an english stopword list, it also removes any single character tokens. /// The stopword list is case-sensitive. -TEST_F(ChineseTokenizerTest, testEnglish) -{ +TEST_F(ChineseTokenizerTest, testEnglish) { AnalyzerPtr chinese = newLucene(); checkAnalyzesTo(chinese, L"This is a Test. b c d", newCollection(L"test")); diff --git a/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp index b8967727..20951d6f 100644 --- a/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/cz/CzechAnalyzerTest.cpp @@ -12,23 +12,21 @@ using namespace Lucene; typedef BaseTokenStreamFixture CzechAnalyzerTest; -TEST_F(CzechAnalyzerTest, testStopWord) -{ +TEST_F(CzechAnalyzerTest, testStopWord) { CzechAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(analyzer, L"Pokud mluvime o volnem", newCollection(L"mluvime", L"volnem")); } -TEST_F(CzechAnalyzerTest, testReusableTokenStream1) -{ +TEST_F(CzechAnalyzerTest, testReusableTokenStream1) { CzechAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesToReuse(analyzer, L"Pokud mluvime o volnem", newCollection(L"mluvime", L"volnem")); } -TEST_F(CzechAnalyzerTest, testReusableTokenStream2) -{ +TEST_F(CzechAnalyzerTest, testReusableTokenStream2) { CzechAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t input[] = {0xc4, 0x8c, 0x65, 0x73, 0x6b, 0xc3, 0xa1, 0x20, 0x52, - 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b, 0x61}; + 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b, 0x61 + }; const uint8_t token1[] = {0xc4, 0x8d, 0x65, 0x73, 0x6b, 0xc3, 0xa1}; const uint8_t token2[] = {0x72, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b, 0x61}; checkAnalyzesToReuse(analyzer, UTF8_TO_STRING(input), newCollection(UTF8_TO_STRING(token1), UTF8_TO_STRING(token2))); diff --git a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp index c867ba33..81fba752 100644 --- a/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/de/GermanStemFilterTest.cpp @@ -11,21 +11,17 @@ using namespace Lucene; -class GermanStemFilterTest : public BaseTokenStreamFixture -{ +class GermanStemFilterTest : public BaseTokenStreamFixture { public: - virtual ~GermanStemFilterTest() - { + virtual ~GermanStemFilterTest() { } public: - void check(const String& input, const String& expected) - { + void check(const String& input, const String& expected) { checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) - { + void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } }; @@ -33,8 +29,7 @@ class GermanStemFilterTest : public BaseTokenStreamFixture /// Test the German stemmer. The stemming algorithm is known to work less than perfect, as it doesn't /// use any word lists with exceptions. We also check some of the cases where the algorithm is wrong. -TEST_F(GermanStemFilterTest, testStemming) -{ +TEST_F(GermanStemFilterTest, testStemming) { const uint8_t haufig[] = {0x68, 0xc3, 0xa4, 0x75, 0x66, 0x69, 0x67}; check(UTF8_TO_STRING(haufig), L"haufig"); // German special characters are replaced @@ -97,8 +92,7 @@ TEST_F(GermanStemFilterTest, testStemming) check(L"xxxnd", L"xxxnd"); } -TEST_F(GermanStemFilterTest, testReusableTokenStream) -{ +TEST_F(GermanStemFilterTest, testReusableTokenStream) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"Tisch", L"tisch"); checkReuse(a, L"Tische", L"tisch"); @@ -106,8 +100,7 @@ TEST_F(GermanStemFilterTest, testReusableTokenStream) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -TEST_F(GermanStemFilterTest, testExclusionTableReuse) -{ +TEST_F(GermanStemFilterTest, testExclusionTableReuse) { GermanAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"tischen", L"tisch"); HashSet exclusions = HashSet::newInstance(); diff --git a/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp index 7354b87d..c89da0b1 100644 --- a/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/el/GreekAnalyzerTest.cpp @@ -12,12 +12,10 @@ using namespace Lucene; typedef BaseTokenStreamFixture GreekAnalyzerTest; -TEST_F(GreekAnalyzerTest, testAnalyzer1) -{ +TEST_F(GreekAnalyzerTest, testAnalyzer1) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xce, 0x9c, 0xce, 0xaf, 0xce, 0xb1, 0x20, 0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xae, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xcf, 0x80, 0xce, 0xbb, @@ -31,14 +29,17 @@ TEST_F(GreekAnalyzerTest, testAnalyzer1) const uint8_t token1[] = {0xce, 0xbc, 0xce, 0xb9, 0xce, 0xb1}; const uint8_t token2[] = {0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, - 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb1}; + 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb1 + }; const uint8_t token3[] = {0xce, 0xba, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xb7}; const uint8_t token4[] = {0xcf, 0x80, 0xce, 0xbb, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1}; const uint8_t token5[] = {0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb1}; const uint8_t token6[] = {0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, 0xcf, 0x84, - 0xce, 0xb7, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd}; + 0xce, 0xb7, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd + }; const uint8_t token7[] = {0xce, 0xb5, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, - 0xce, 0xb7, 0xcf, 0x83}; + 0xce, 0xb7, 0xcf, 0x83 + }; const uint8_t token8[] = {0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x89, 0xcf, 0x83, 0xcf, 0x83, 0xce, 0xb1, 0xcf, 0x83}; // Verify the correct analysis of capitals and small accented letters @@ -54,12 +55,10 @@ TEST_F(GreekAnalyzerTest, testAnalyzer1) )); } -TEST_F(GreekAnalyzerTest, testAnalyzer2) -{ +TEST_F(GreekAnalyzerTest, testAnalyzer2) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xce, 0xa0, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x8a, 0xcf, 0x8c, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1, 0x20, 0x28, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xad, 0xcf, @@ -68,11 +67,14 @@ TEST_F(GreekAnalyzerTest, testAnalyzer2) }; const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xce, 0xbd, - 0xcf, 0x84, 0xce, 0xb1}; + 0xcf, 0x84, 0xce, 0xb1 + }; const uint8_t token2[] = {0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, - 0xce, 0xbb, 0xce, 0xb5, 0xcf, 0x83}; + 0xce, 0xbb, 0xce, 0xb5, 0xcf, 0x83 + }; const uint8_t token3[] = {0xce, 0xb1, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb3, 0xce, 0xba, 0xce, 0xb5, - 0xcf, 0x83}; + 0xcf, 0x83 + }; // Verify the correct analysis of small letters with diaeresis and the elimination of punctuation marks checkAnalyzesTo(a, UTF8_TO_STRING(input), newCollection( @@ -82,12 +84,10 @@ TEST_F(GreekAnalyzerTest, testAnalyzer2) )); } -TEST_F(GreekAnalyzerTest, testAnalyzer3) -{ +TEST_F(GreekAnalyzerTest, testAnalyzer3) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xce, 0xa0, 0xce, 0xa1, 0xce, 0x9f, 0xce, 0xab, 0xce, 0xa0, 0xce, 0x9f, 0xce, 0x98, 0xce, 0x95, 0xce, 0xa3, 0xce, 0x95, 0xce, 0x99, 0xce, 0xa3, 0x20, 0x20, 0xce, 0x86, 0xcf, 0x88, 0xce, 0xbf, 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x82, 0x2c, 0x20, 0xce, 0xbf, 0x20, 0xce, 0xbc, 0xce, 0xb5, 0xcf, @@ -96,7 +96,8 @@ TEST_F(GreekAnalyzerTest, testAnalyzer3) }; const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x80, 0xce, 0xbf, - 0xce, 0xb8, 0xce, 0xb5, 0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83}; + 0xce, 0xb8, 0xce, 0xb5, 0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83 + }; const uint8_t token2[] = {0xce, 0xb1, 0xcf, 0x88, 0xce, 0xbf, 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token3[] = {0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token4[] = {0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xbf, 0xce, 0xb9}; @@ -111,12 +112,10 @@ TEST_F(GreekAnalyzerTest, testAnalyzer3) )); } -TEST_F(GreekAnalyzerTest, testReusableTokenStream1) -{ +TEST_F(GreekAnalyzerTest, testReusableTokenStream1) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xce, 0x9c, 0xce, 0xaf, 0xce, 0xb1, 0x20, 0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xac, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xae, 0x20, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x20, 0xcf, 0x80, 0xce, 0xbb, @@ -130,35 +129,36 @@ TEST_F(GreekAnalyzerTest, testReusableTokenStream1) const uint8_t token1[] = {0xce, 0xbc, 0xce, 0xb9, 0xce, 0xb1}; const uint8_t token2[] = {0xce, 0xb5, 0xce, 0xbe, 0xce, 0xb1, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb5, - 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb1}; + 0xcf, 0x84, 0xce, 0xb9, 0xce, 0xba, 0xce, 0xb1 + }; const uint8_t token3[] = {0xce, 0xba, 0xce, 0xb1, 0xce, 0xbb, 0xce, 0xb7}; const uint8_t token4[] = {0xcf, 0x80, 0xce, 0xbb, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x83, 0xce, 0xb9, 0xce, 0xb1}; const uint8_t token5[] = {0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x81, 0xce, 0xb1}; const uint8_t token6[] = {0xcf, 0x87, 0xce, 0xb1, 0xcf, 0x81, 0xce, 0xb1, 0xce, 0xba, 0xcf, 0x84, - 0xce, 0xb7, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd}; + 0xce, 0xb7, 0xcf, 0x81, 0xcf, 0x89, 0xce, 0xbd + }; const uint8_t token7[] = {0xce, 0xb5, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb7, 0xce, 0xbd, 0xce, 0xb9, 0xce, 0xba, - 0xce, 0xb7, 0xcf, 0x83}; + 0xce, 0xb7, 0xcf, 0x83 + }; const uint8_t token8[] = {0xce, 0xb3, 0xce, 0xbb, 0xcf, 0x89, 0xcf, 0x83, 0xcf, 0x83, 0xce, 0xb1, 0xcf, 0x83}; // Verify the correct analysis of capitals and small accented letters checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3), - UTF8_TO_STRING(token4), - UTF8_TO_STRING(token5), - UTF8_TO_STRING(token6), - UTF8_TO_STRING(token7), - UTF8_TO_STRING(token8) + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3), + UTF8_TO_STRING(token4), + UTF8_TO_STRING(token5), + UTF8_TO_STRING(token6), + UTF8_TO_STRING(token7), + UTF8_TO_STRING(token8) )); } -TEST_F(GreekAnalyzerTest, testReusableTokenStream2) -{ +TEST_F(GreekAnalyzerTest, testReusableTokenStream2) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xce, 0xa0, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x8a, 0xcf, 0x8c, 0xce, 0xbd, 0xcf, 0x84, 0xce, 0xb1, 0x20, 0x28, 0xce, 0xba, 0xce, 0xb1, 0xce, 0xb9, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, 0xce, 0xbb, 0xce, 0xad, 0xcf, @@ -167,26 +167,27 @@ TEST_F(GreekAnalyzerTest, testReusableTokenStream2) }; const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xce, 0xb9, 0xce, 0xbf, 0xce, 0xbd, - 0xcf, 0x84, 0xce, 0xb1}; + 0xcf, 0x84, 0xce, 0xb1 + }; const uint8_t token2[] = {0xcf, 0x80, 0xce, 0xbf, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xb1, 0xcf, 0x80, - 0xce, 0xbb, 0xce, 0xb5, 0xcf, 0x83}; + 0xce, 0xbb, 0xce, 0xb5, 0xcf, 0x83 + }; const uint8_t token3[] = {0xce, 0xb1, 0xce, 0xbd, 0xce, 0xb1, 0xce, 0xb3, 0xce, 0xba, 0xce, 0xb5, - 0xcf, 0x83}; + 0xcf, 0x83 + }; // Verify the correct analysis of small letters with diaeresis and the elimination of punctuation marks checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3) + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3) )); } -TEST_F(GreekAnalyzerTest, testReusableTokenStream3) -{ +TEST_F(GreekAnalyzerTest, testReusableTokenStream3) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xce, 0xa0, 0xce, 0xa1, 0xce, 0x9f, 0xce, 0xab, 0xce, 0xa0, 0xce, 0x9f, 0xce, 0x98, 0xce, 0x95, 0xce, 0xa3, 0xce, 0x95, 0xce, 0x99, 0xce, 0xa3, 0x20, 0x20, 0xce, 0x86, 0xcf, 0x88, 0xce, 0xbf, 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x82, 0x2c, 0x20, 0xce, 0xbf, 0x20, 0xce, 0xbc, 0xce, 0xb5, 0xcf, @@ -195,7 +196,8 @@ TEST_F(GreekAnalyzerTest, testReusableTokenStream3) }; const uint8_t token1[] = {0xcf, 0x80, 0xcf, 0x81, 0xce, 0xbf, 0xcf, 0x85, 0xcf, 0x80, 0xce, 0xbf, - 0xce, 0xb8, 0xce, 0xb5, 0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83}; + 0xce, 0xb8, 0xce, 0xb5, 0xcf, 0x83, 0xce, 0xb5, 0xce, 0xb9, 0xcf, 0x83 + }; const uint8_t token2[] = {0xce, 0xb1, 0xcf, 0x88, 0xce, 0xbf, 0xce, 0xb3, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token3[] = {0xce, 0xbc, 0xce, 0xb5, 0xcf, 0x83, 0xcf, 0x84, 0xce, 0xbf, 0xcf, 0x83}; const uint8_t token4[] = {0xce, 0xb1, 0xce, 0xbb, 0xce, 0xbb, 0xce, 0xbf, 0xce, 0xb9}; @@ -203,9 +205,9 @@ TEST_F(GreekAnalyzerTest, testReusableTokenStream3) // Verify the correct analysis of capital accented letters and capital letters with diaeresis, // as well as the elimination of stop words checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3), - UTF8_TO_STRING(token4) + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3), + UTF8_TO_STRING(token4) )); } diff --git a/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp index 61bd7ca4..e9d41fd0 100644 --- a/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fa/PersianAnalyzerTest.cpp @@ -19,8 +19,7 @@ typedef BaseTokenStreamFixture PersianAnalyzerTest; /// These verb forms are from http://en.wikipedia.org/wiki/Persian_grammar /// active present indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs1) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -28,8 +27,7 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbs1) } /// active preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs2) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -37,8 +35,7 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbs2) } /// active imperfective preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs3) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs3) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -46,129 +43,128 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbs3) } /// active future indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs4) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs4) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, - 0xd8, 0xb1, 0xd8, 0xaf}; + 0xd8, 0xb1, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs5) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs5) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, - 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; + 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs6) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs6) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, - 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; + 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs7) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs7) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, - 0xd8, 0xb3, 0xd8, 0xaa}; + 0xd8, 0xb3, 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs8) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs8) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, - 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; + 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs9) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs9) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, - 0xd8, 0xaf}; + 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs10) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs10) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs11) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs11) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, - 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs12) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs12) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs13) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs13) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, - 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs14) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs14) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, - 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs15) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs15) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, - 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; + 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs16) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs16) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; @@ -176,145 +172,144 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbs16) } /// passive imperfective preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs17) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs17) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, - 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs18) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs18) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; + 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs19) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs19) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0xe2, 0x80, 0x8c, 0xd8, 0xa7, 0xd8, - 0xb3, 0xd8, 0xaa}; + 0xb3, 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs20) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs20) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs21) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs21) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, - 0xaf}; + 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive future indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs22) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs22) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xae, 0xd9, 0x88, - 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs23) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs23) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd9, - 0x88, 0xd8, 0xaf}; + 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbs24) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs24) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, - 0xaf}; + 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs25) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs25) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd9, 0x88, - 0xd8, 0xaf}; + 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs26) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs26) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs27) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs27) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, - 0xb4, 0xd8, 0xaf}; + 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs28) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs28) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, - 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs29) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs29) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xdb, 0x8c, 0xe2, 0x80, 0x8c, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, - 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbs30) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbs30) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xa8, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -331,8 +326,7 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbs30) /// These verb forms are from http://en.wikipedia.org/wiki/Persian_grammar /// active present subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective1) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -340,8 +334,7 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective1) } /// active preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective2) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -349,8 +342,7 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective2) } /// active imperfective preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective3) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective3) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -358,129 +350,128 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective3) } /// active future indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective4) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective4) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, - 0xd8, 0xb1, 0xd8, 0xaf}; + 0xd8, 0xb1, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective5) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective5) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, - 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; + 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective6) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective6) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, - 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; + 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective7) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective7) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, - 0xd8, 0xaa}; + 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective8) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective8) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, - 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; + 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective9) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective9) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, - 0xd8, 0xaf}; + 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective10) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective10) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, - 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; + 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective11) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective11) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, - 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective12) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective12) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, - 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective13) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective13) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, - 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active imperfective pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective14) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective14) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, - 0xb4, 0xd8, 0xaf}; + 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective15) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective15) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, - 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf}; + 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective16) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective16) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; @@ -488,142 +479,141 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective16) } /// passive imperfective preterite indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective17) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective17) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, - 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; + 0x20, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective18) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective18) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; + 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective perfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective19) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective19) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, - 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa}; + 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa7, 0xd8, 0xb3, 0xd8, 0xaa + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective20) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective20) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective21) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective21) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, - 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf}; + 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive future indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective22) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective22) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xae, 0xd9, 0x88, - 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd8, 0xa7, 0xd9, 0x87, 0xd8, 0xaf, 0x20, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective23) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective23) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb1, 0xd8, 0xaf, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd9, 0x88, 0xd8, - 0xaf}; + 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite progressive indicative -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective24) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective24) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0x20, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, - 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive present subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective25) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective25) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd9, 0x88, - 0xd8, 0xaf}; + 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective26) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective26) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, - 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective preterite subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective27) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective27) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, - 0xaf}; + 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective28) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective28) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd8, - 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// passive imperfective pluperfect subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective29) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective29) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, - 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } /// active present subjunctive -TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective30) -{ +TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective30) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; const uint8_t second[] = {0xd8, 0xa8, 0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf}; @@ -634,16 +624,14 @@ TEST_F(PersianAnalyzerTest, testBehaviorVerbsDefective30) /// non-joiner or space) and stopwords creates a light-stemming effect for /// nouns, removing the plural -ha. -TEST_F(PersianAnalyzerTest, testBehaviorNouns1) -{ +TEST_F(PersianAnalyzerTest, testBehaviorNouns1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf, 0x20, 0xd9, 0x87, 0xd8, 0xa7}; const uint8_t second[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf}; checkAnalyzesTo(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(PersianAnalyzerTest, testBehaviorNouns2) -{ +TEST_F(PersianAnalyzerTest, testBehaviorNouns2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf, 0xe2, 0x80, 0x8c, 0xd9, 0x87, 0xd8, 0xa7}; const uint8_t second[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf}; @@ -651,24 +639,22 @@ TEST_F(PersianAnalyzerTest, testBehaviorNouns2) } /// Test showing that non-Persian text is treated very much like SimpleAnalyzer (lowercased, etc) -TEST_F(PersianAnalyzerTest, testBehaviorNonPersian) -{ +TEST_F(PersianAnalyzerTest, testBehaviorNonPersian) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(a, L"English test.", newCollection(L"english", L"test")); } -TEST_F(PersianAnalyzerTest, testReusableTokenStream1) -{ +TEST_F(PersianAnalyzerTest, testReusableTokenStream1) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd9, 0x85, 0xd9, 0x8a, 0x20, 0xd8, 0xb4, 0xd8, 0xaf, 0xd9, 0x87, 0x20, 0xd8, 0xa8, 0xd9, 0x88, 0xd8, 0xaf, 0xd9, - 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf}; + 0x87, 0x20, 0xd8, 0xa8, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaf + }; const uint8_t second[] = {0xd8, 0xae, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x87}; checkAnalyzesToReuse(a, UTF8_TO_STRING(first), newCollection(UTF8_TO_STRING(second))); } -TEST_F(PersianAnalyzerTest, testReusableTokenStream2) -{ +TEST_F(PersianAnalyzerTest, testReusableTokenStream2) { PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); const uint8_t first[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf, 0xe2, 0x80, 0x8c, 0xd9, 0x87, 0xd8, 0xa7}; const uint8_t second[] = {0xd8, 0xa8, 0xd8, 0xb1, 0xda, 0xaf}; @@ -676,8 +662,7 @@ TEST_F(PersianAnalyzerTest, testReusableTokenStream2) } /// Test that custom stopwords work, and are not case-sensitive. -TEST_F(PersianAnalyzerTest, testCustomStopwords) -{ +TEST_F(PersianAnalyzerTest, testCustomStopwords) { Collection stopWords = newCollection(L"the", L"and", L"a"); PersianAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance(stopWords.begin(), stopWords.end())); checkAnalyzesTo(a, L"The quick brown fox.", newCollection(L"quick", L"brown", L"fox")); diff --git a/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp index 6d99f33c..c86a8faa 100644 --- a/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fa/PersianNormalizationFilterTest.cpp @@ -12,59 +12,50 @@ using namespace Lucene; -class PersianNormalizationFilterTest : public BaseTokenStreamFixture -{ +class PersianNormalizationFilterTest : public BaseTokenStreamFixture { public: - virtual ~PersianNormalizationFilterTest() - { + virtual ~PersianNormalizationFilterTest() { } public: - void check(const String& input, const String& expected) - { + void check(const String& input, const String& expected) { ArabicLetterTokenizerPtr tokenStream = newLucene(newLucene(input)); PersianNormalizationFilterPtr filter = newLucene(tokenStream); checkTokenStreamContents(filter, newCollection(expected)); } }; -TEST_F(PersianNormalizationFilterTest, testFarsiYeh) -{ +TEST_F(PersianNormalizationFilterTest, testFarsiYeh) { const uint8_t first[] = {0xd9, 0x87, 0xd8, 0xa7, 0xdb, 0x8c}; const uint8_t second[] = {0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(PersianNormalizationFilterTest, testYehBarree) -{ +TEST_F(PersianNormalizationFilterTest, testYehBarree) { const uint8_t first[] = {0xd9, 0x87, 0xd8, 0xa7, 0xdb, 0x92}; const uint8_t second[] = {0xd9, 0x87, 0xd8, 0xa7, 0xd9, 0x8a}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(PersianNormalizationFilterTest, testKeheh) -{ +TEST_F(PersianNormalizationFilterTest, testKeheh) { const uint8_t first[] = {0xda, 0xa9, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x86}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xb4, 0xd8, 0xa7, 0xd9, 0x86, 0xd8, 0xaf, 0xd9, 0x86}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(PersianNormalizationFilterTest, testHehYeh) -{ +TEST_F(PersianNormalizationFilterTest, testHehYeh) { const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xdb, 0x80}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(PersianNormalizationFilterTest, testHehHamzaAbove) -{ +TEST_F(PersianNormalizationFilterTest, testHehHamzaAbove) { const uint8_t first[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x94}; const uint8_t second[] = {0xd9, 0x83, 0xd8, 0xaa, 0xd8, 0xa7, 0xd8, 0xa8, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); } -TEST_F(PersianNormalizationFilterTest, testHehGoal) -{ +TEST_F(PersianNormalizationFilterTest, testHehGoal) { const uint8_t first[] = {0xd8, 0xb2, 0xd8, 0xa7, 0xd8, 0xaf, 0xdb, 0x81}; const uint8_t second[] = {0xd8, 0xb2, 0xd8, 0xa7, 0xd8, 0xaf, 0xd9, 0x87}; check(UTF8_TO_STRING(first), UTF8_TO_STRING(second)); diff --git a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp index 2fc6e9a5..3338df6b 100644 --- a/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fr/ElisionTest.cpp @@ -13,26 +13,23 @@ using namespace Lucene; -class ElisionTest : public BaseTokenStreamFixture -{ +class ElisionTest : public BaseTokenStreamFixture { public: - virtual ~ElisionTest() - { + virtual ~ElisionTest() { } public: - Collection addTerms(const TokenFilterPtr& filter) - { + Collection addTerms(const TokenFilterPtr& filter) { Collection terms = Collection::newInstance(); TermAttributePtr termAtt = filter->getAttribute(); - while (filter->incrementToken()) + while (filter->incrementToken()) { terms.add(termAtt->term()); + } return terms; } }; -TEST_F(ElisionTest, testElision) -{ +TEST_F(ElisionTest, testElision) { String test = L"Plop, juste pour voir l'embrouille avec O'brian. M'enfin."; TokenizerPtr tokenizer = newLucene(LuceneVersion::LUCENE_CURRENT, newLucene(test)); HashSet articles = HashSet::newInstance(); diff --git a/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp index 011ef483..3908b325 100644 --- a/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/fr/FrenchAnalyzerTest.cpp @@ -12,8 +12,7 @@ using namespace Lucene; typedef BaseTokenStreamFixture FrenchAnalyzerTest; -TEST_F(FrenchAnalyzerTest, testAnalyzer) -{ +TEST_F(FrenchAnalyzerTest, testAnalyzer) { AnalyzerPtr fa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesTo(fa, L"", Collection::newInstance()); @@ -52,8 +51,7 @@ TEST_F(FrenchAnalyzerTest, testAnalyzer) newCollection(L"33bis", L"1940-1945", L"1940", L"1945", L"i")); } -TEST_F(FrenchAnalyzerTest, testReusableTokenStream) -{ +TEST_F(FrenchAnalyzerTest, testReusableTokenStream) { AnalyzerPtr fa = newLucene(LuceneVersion::LUCENE_CURRENT); // stopwords @@ -66,8 +64,7 @@ TEST_F(FrenchAnalyzerTest, testReusableTokenStream) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -TEST_F(FrenchAnalyzerTest, testExclusionTableReuse) -{ +TEST_F(FrenchAnalyzerTest, testExclusionTableReuse) { FrenchAnalyzerPtr fa = newLucene(LuceneVersion::LUCENE_CURRENT); checkAnalyzesToReuse(fa, L"habitable", newCollection(L"habit")); HashSet exclusions = HashSet::newInstance(); diff --git a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp index e2e0aecf..e58831ae 100644 --- a/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/nl/DutchStemmerTest.cpp @@ -11,21 +11,17 @@ using namespace Lucene; -class DutchStemmerTest : public BaseTokenStreamFixture -{ +class DutchStemmerTest : public BaseTokenStreamFixture { public: - virtual ~DutchStemmerTest() - { + virtual ~DutchStemmerTest() { } public: - void check(const String& input, const String& expected) - { + void check(const String& input, const String& expected) { checkOneTerm(newLucene(LuceneVersion::LUCENE_CURRENT), input, expected); } - void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) - { + void checkReuse(const AnalyzerPtr& a, const String& input, const String& expected) { checkOneTermReuse(a, input, expected); } }; @@ -33,8 +29,7 @@ class DutchStemmerTest : public BaseTokenStreamFixture /// Test the Dutch Stem Filter, which only modifies the term text. /// The code states that it uses the snowball algorithm, but tests reveal some differences. -TEST_F(DutchStemmerTest, testWithSnowballExamples) -{ +TEST_F(DutchStemmerTest, testWithSnowballExamples) { check(L"lichaamsziek", L"lichaamsziek"); check(L"lichamelijk", L"licham"); check(L"lichamelijke", L"licham"); @@ -117,8 +112,7 @@ TEST_F(DutchStemmerTest, testWithSnowballExamples) check(L"ophouden", L"ophoud"); } -TEST_F(DutchStemmerTest, testReusableTokenStream) -{ +TEST_F(DutchStemmerTest, testReusableTokenStream) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"lichaamsziek", L"lichaamsziek"); checkReuse(a, L"lichamelijk", L"licham"); @@ -127,8 +121,7 @@ TEST_F(DutchStemmerTest, testReusableTokenStream) } /// Test that changes to the exclusion table are applied immediately when using reusable token streams. -TEST_F(DutchStemmerTest, testExclusionTableReuse) -{ +TEST_F(DutchStemmerTest, testExclusionTableReuse) { DutchAnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); checkReuse(a, L"lichamelijk", L"licham"); HashSet exclusions = HashSet::newInstance(); diff --git a/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp b/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp index 9f1e507c..b436220c 100644 --- a/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/reverse/ReverseStringFilterTest.cpp @@ -15,8 +15,7 @@ using namespace Lucene; typedef BaseTokenStreamFixture ReverseStringFilterTest; -TEST_F(ReverseStringFilterTest, testFilter) -{ +TEST_F(ReverseStringFilterTest, testFilter) { TokenStreamPtr stream = newLucene(newLucene(L"Do have a nice day")); // 1-4 length string ReverseStringFilterPtr filter = newLucene(stream); TermAttributePtr text = filter->getAttribute(); @@ -33,8 +32,7 @@ TEST_F(ReverseStringFilterTest, testFilter) EXPECT_TRUE(!filter->incrementToken()); } -TEST_F(ReverseStringFilterTest, testFilterWithMark) -{ +TEST_F(ReverseStringFilterTest, testFilterWithMark) { TokenStreamPtr stream = newLucene(newLucene(L"Do have a nice day")); // 1-4 length string ReverseStringFilterPtr filter = newLucene(stream, (wchar_t)0x0001); TermAttributePtr text = filter->getAttribute(); diff --git a/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp b/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp index ab641269..3a11f076 100644 --- a/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ru/RussianAnalyzerTest.cpp @@ -19,8 +19,7 @@ using namespace Lucene; typedef BaseTokenStreamFixture RussianAnalyzerTest; -TEST_F(RussianAnalyzerTest, testUnicode) -{ +TEST_F(RussianAnalyzerTest, testUnicode) { RussianAnalyzerPtr ra = newLucene(LuceneVersion::LUCENE_CURRENT); String testFile(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"russian"), L"testUTF8.txt")); @@ -35,10 +34,10 @@ TEST_F(RussianAnalyzerTest, testUnicode) TermAttributePtr text = in->getAttribute(); TermAttributePtr sampleText = sample->getAttribute(); - while (true) - { - if (!in->incrementToken()) + while (true) { + if (!in->incrementToken()) { break; + } sample->incrementToken(); EXPECT_EQ(text->term(), sampleText->term()); } @@ -47,8 +46,7 @@ TEST_F(RussianAnalyzerTest, testUnicode) sampleUnicode->close(); } -TEST_F(RussianAnalyzerTest, testDigitsInRussianCharset) -{ +TEST_F(RussianAnalyzerTest, testDigitsInRussianCharset) { ReaderPtr reader = newLucene(L"text 1000"); RussianAnalyzerPtr ra = newLucene(LuceneVersion::LUCENE_CURRENT); TokenStreamPtr stream = ra->tokenStream(L"", reader); @@ -61,12 +59,10 @@ TEST_F(RussianAnalyzerTest, testDigitsInRussianCharset) EXPECT_TRUE(!stream->incrementToken()); } -TEST_F(RussianAnalyzerTest, testReusableTokenStream1) -{ +TEST_F(RussianAnalyzerTest, testReusableTokenStream1) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xd0, 0x92, 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xb5, 0x20, 0xd1, 0x81, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0xbc, 0x20, 0xd0, 0xbe, 0x20, 0xd1, 0x81, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xb5, 0x20, 0xd1, 0x8d, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xba, 0xd1, 0x82, 0xd1, 0x80, 0xd0, @@ -81,28 +77,28 @@ TEST_F(RussianAnalyzerTest, testReusableTokenStream1) const uint8_t token2[] = {0xd1, 0x81, 0xd0, 0xb8, 0xd0, 0xbb}; const uint8_t token3[] = {0xd1, 0x8d, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xba, 0xd1, 0x82, 0xd1, 0x80, 0xd0, 0xbe, 0xd0, 0xbc, 0xd0, 0xb0, 0xd0, 0xb3, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x82, - 0xd0, 0xbd}; + 0xd0, 0xbd + }; const uint8_t token4[] = {0xd1, 0x8d, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x80, 0xd0, 0xb3}; const uint8_t token5[] = {0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb5, 0xd0, 0xbb}; const uint8_t token6[] = {0xd0, 0xbf, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb4, 0xd1, 0x81, 0xd1, 0x82, 0xd0, - 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd}; + 0xb0, 0xd0, 0xb2, 0xd0, 0xbb, 0xd0, 0xb5, 0xd0, 0xbd + }; checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3), - UTF8_TO_STRING(token4), - UTF8_TO_STRING(token5), - UTF8_TO_STRING(token6) + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3), + UTF8_TO_STRING(token4), + UTF8_TO_STRING(token5), + UTF8_TO_STRING(token6) )); } -TEST_F(RussianAnalyzerTest, testReusableTokenStream2) -{ +TEST_F(RussianAnalyzerTest, testReusableTokenStream2) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); - const uint8_t input[] = - { + const uint8_t input[] = { 0xd0, 0x9d, 0xd0, 0xbe, 0x20, 0xd0, 0xb7, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xb5, 0x20, 0xd1, 0x8d, 0xd1, 0x82, 0xd0, 0xbe, 0x20, 0xd1, 0x85, 0xd1, 0x80, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xbe, 0xd1, 0x81, 0xd1, 0x8c, 0x20, 0xd0, 0xb2, 0x20, 0xd1, @@ -114,8 +110,8 @@ TEST_F(RussianAnalyzerTest, testReusableTokenStream2) const uint8_t token3[] = {0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xb9, 0xd0, 0xbd}; checkAnalyzesToReuse(a, UTF8_TO_STRING(input), newCollection( - UTF8_TO_STRING(token1), - UTF8_TO_STRING(token2), - UTF8_TO_STRING(token3) + UTF8_TO_STRING(token1), + UTF8_TO_STRING(token2), + UTF8_TO_STRING(token3) )); } diff --git a/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp b/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp index d03cd33a..27f77fb5 100644 --- a/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp +++ b/src/test/contrib/analyzers/common/analysis/ru/RussianStemTest.cpp @@ -15,11 +15,9 @@ using namespace Lucene; -class RussianStemmerTest : public BaseTokenStreamFixture -{ +class RussianStemmerTest : public BaseTokenStreamFixture { public: - RussianStemmerTest() - { + RussianStemmerTest() { words = Collection::newInstance(); stems = Collection::newInstance(); @@ -28,19 +26,20 @@ class RussianStemmerTest : public BaseTokenStreamFixture BufferedReaderPtr inWords = newLucene(newLucene(newLucene(wordsFile))); String word; - while (inWords->readLine(word)) + while (inWords->readLine(word)) { words.add(word); + } inWords->close(); BufferedReaderPtr inStems = newLucene(newLucene(newLucene(stemsFile))); String stem; - while (inStems->readLine(stem)) + while (inStems->readLine(stem)) { stems.add(stem); + } inStems->close(); } - virtual ~RussianStemmerTest() - { + virtual ~RussianStemmerTest() { } protected: @@ -48,11 +47,9 @@ class RussianStemmerTest : public BaseTokenStreamFixture Collection stems; }; -TEST_F(RussianStemmerTest, testStem) -{ +TEST_F(RussianStemmerTest, testStem) { EXPECT_EQ(words.size(), stems.size()); - for (int32_t i = 0; i < words.size(); ++i) - { + for (int32_t i = 0; i < words.size(); ++i) { String realStem = RussianStemmer::stemWord(words[i]); EXPECT_EQ(stems[i], realStem); } diff --git a/src/test/contrib/highlighter/HighlighterTest.cpp b/src/test/contrib/highlighter/HighlighterTest.cpp index c717a1c7..beaa9ea4 100644 --- a/src/test/contrib/highlighter/HighlighterTest.cpp +++ b/src/test/contrib/highlighter/HighlighterTest.cpp @@ -57,46 +57,45 @@ using namespace Lucene; class HighlighterTest; -namespace HighlighterTestNS -{ - class TestFormatter : public Formatter, public LuceneObject - { - public: - TestFormatter(HighlighterTest* fixture); - virtual ~TestFormatter(); +namespace HighlighterTestNS { - LUCENE_CLASS(TestFormatter); +class TestFormatter : public Formatter, public LuceneObject { +public: + TestFormatter(HighlighterTest* fixture); + virtual ~TestFormatter(); + + LUCENE_CLASS(TestFormatter); - protected: - HighlighterTest* fixture; +protected: + HighlighterTest* fixture; + +public: + virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); +}; - public: - virtual String highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup); - }; } -class HighlighterTest : public BaseTokenStreamFixture -{ +class HighlighterTest : public BaseTokenStreamFixture { public: - HighlighterTest() - { + HighlighterTest() { numHighlights = 0; analyzer = newLucene(TEST_VERSION); texts = newCollection( - L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot", - L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy", - L"JFK has been shot", - L"John Kennedy has been shot", - L"This text has a typo in referring to Keneddy", - L"wordx wordy wordz wordx wordy wordx worda wordb wordy wordc", - L"y z x y z a b", - L"lets is a the lets is a the lets is a the lets" - ); + L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot", + L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy", + L"JFK has been shot", + L"John Kennedy has been shot", + L"This text has a typo in referring to Keneddy", + L"wordx wordy wordz wordx wordy wordx worda wordb wordy wordc", + L"y z x y z a b", + L"lets is a the lets is a the lets is a the lets" + ); ramDir = newLucene(); IndexWriterPtr writer = newLucene(ramDir, newLucene(TEST_VERSION), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < texts.size(); ++i) + for (int32_t i = 0; i < texts.size(); ++i) { addDoc(writer, texts[i]); + } DocumentPtr doc = newLucene(); NumericFieldPtr nfield = newLucene(NUMERIC_FIELD_NAME, Field::STORE_YES, true); nfield->setIntValue(1); @@ -125,8 +124,7 @@ class HighlighterTest : public BaseTokenStreamFixture a = newLucene(); } - virtual ~HighlighterTest() - { + virtual ~HighlighterTest() { } public: @@ -150,16 +148,14 @@ class HighlighterTest : public BaseTokenStreamFixture static const String NUMERIC_FIELD_NAME; public: - void addDoc(const IndexWriterPtr& writer, const String& text) - { + void addDoc(const IndexWriterPtr& writer, const String& text) { DocumentPtr doc = newLucene(); FieldPtr field = newLucene(FIELD_NAME, text, Field::STORE_YES, Field::INDEX_ANALYZED); doc->add(field); writer->addDocument(doc); } - String highlightField(const QueryPtr& query, const String& fieldName, const String& text) - { + String highlightField(const QueryPtr& query, const String& fieldName, const String& text) { TokenStreamPtr tokenStream = newLucene(TEST_VERSION)->tokenStream(fieldName, newLucene(text)); // Assuming "", "" used to highlight SimpleHTMLFormatterPtr formatter = newLucene(); @@ -171,8 +167,7 @@ class HighlighterTest : public BaseTokenStreamFixture return rv.empty() ? text : rv; } - void doSearching(const String& queryString) - { + void doSearching(const String& queryString) { QueryParserPtr parser = newLucene(TEST_VERSION, FIELD_NAME, analyzer); parser->setEnablePositionIncrements(true); parser->setMultiTermRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); @@ -180,20 +175,17 @@ class HighlighterTest : public BaseTokenStreamFixture doSearching(query); } - void doSearching(const QueryPtr& unReWrittenQuery) - { + void doSearching(const QueryPtr& unReWrittenQuery) { searcher = newLucene(ramDir, true); // for any multi-term queries to work (prefix, wildcard, range,fuzzy etc) you must use a rewritten query query = unReWrittenQuery->rewrite(reader); hits = searcher->search(query, FilterPtr(), 1000); } - void checkExpectedHighlightCount(int32_t maxNumFragmentsRequired, int32_t expectedHighlights, Collection expected) - { + void checkExpectedHighlightCount(int32_t maxNumFragmentsRequired, int32_t expectedHighlights, Collection expected) { Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); QueryScorerPtr scorer = newLucene(query, FIELD_NAME); @@ -207,12 +199,12 @@ class HighlighterTest : public BaseTokenStreamFixture } EXPECT_EQ(results.size(), expected.size()); - for (int32_t i = 0; i < results.size(); ++i) + for (int32_t i = 0; i < results.size(); ++i) { EXPECT_EQ(results[i], expected[i]); + } } - void makeIndex() - { + void makeIndex() { IndexWriterPtr writer = newLucene(dir, a, IndexWriter::MaxFieldLengthLIMITED); writer->addDocument(doc(L"t_text1", L"random words for highlighting tests del")); writer->addDocument(doc(L"t_text1", L"more random words for second field del")); @@ -222,22 +214,19 @@ class HighlighterTest : public BaseTokenStreamFixture writer->close(); } - DocumentPtr doc(const String& f, const String& v) - { + DocumentPtr doc(const String& f, const String& v) { DocumentPtr doc = newLucene(); doc->add(newLucene(f, v, Field::STORE_YES, Field::INDEX_ANALYZED)); return doc; } - void deleteDocument() - { + void deleteDocument() { IndexWriterPtr writer = newLucene(dir, a, false, IndexWriter::MaxFieldLengthLIMITED); writer->deleteDocuments(newLucene(L"t_text1", L"del")); writer->close(); } - void searchIndex() - { + void searchIndex() { String q = L"t_text1:random"; QueryParserPtr parser = newLucene(TEST_VERSION, L"t_text1", a ); QueryPtr query = parser->parse(q); @@ -247,8 +236,7 @@ class HighlighterTest : public BaseTokenStreamFixture HighlighterPtr h = newLucene(scorer); TopDocsPtr hits = searcher->search(query, FilterPtr(), 10); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { DocumentPtr doc = searcher->doc(hits->scoreDocs[i]->doc); String result = h->getBestFragment(a, L"t_text1", doc->get(L"t_text1")); EXPECT_EQ(L"more random words for second field", result); @@ -261,133 +249,123 @@ const LuceneVersion::Version HighlighterTest::TEST_VERSION = LuceneVersion::LUCE const String HighlighterTest::FIELD_NAME = L"contents"; const String HighlighterTest::NUMERIC_FIELD_NAME = L"nfield"; -namespace HighlighterTestNS -{ - TestFormatter::TestFormatter(HighlighterTest* fixture) - { - this->fixture = fixture; - } +namespace HighlighterTestNS { - TestFormatter::~TestFormatter() - { - } +TestFormatter::TestFormatter(HighlighterTest* fixture) { + this->fixture = fixture; +} - String TestFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) - { - if (tokenGroup->getTotalScore() <= 0) - return originalText; - ++fixture->numHighlights; // update stats used in assertions - return L"" + originalText + L""; +TestFormatter::~TestFormatter() { +} + +String TestFormatter::highlightTerm(const String& originalText, const TokenGroupPtr& tokenGroup) { + if (tokenGroup->getTotalScore() <= 0) { + return originalText; } + ++fixture->numHighlights; // update stats used in assertions + return L"" + originalText + L""; +} - DECLARE_SHARED_PTR(TestHighlightRunner) +DECLARE_SHARED_PTR(TestHighlightRunner) - class TestHighlightRunner : public LuceneObject - { - public: - TestHighlightRunner(HighlighterTest* fixture) - { - this->fixture = fixture; - mode = QUERY; - frag = newLucene(20); - } +class TestHighlightRunner : public LuceneObject { +public: + TestHighlightRunner(HighlighterTest* fixture) { + this->fixture = fixture; + mode = QUERY; + frag = newLucene(20); + } - virtual ~TestHighlightRunner() - { - } + virtual ~TestHighlightRunner() { + } - LUCENE_CLASS(TestHighlightRunner); + LUCENE_CLASS(TestHighlightRunner); - protected: - HighlighterTest* fixture; +protected: + HighlighterTest* fixture; - static const int32_t QUERY; - static const int32_t QUERY_TERM; + static const int32_t QUERY; + static const int32_t QUERY_TERM; - public: - int32_t mode; - FragmenterPtr frag; +public: + int32_t mode; + FragmenterPtr frag; - public: - virtual HighlighterPtr getHighlighter(const QueryPtr& query, const String& fieldName, const TokenStreamPtr& stream, const FormatterPtr& formatter) - { - return getHighlighter(query, fieldName, stream, formatter, true); - } +public: + virtual HighlighterPtr getHighlighter(const QueryPtr& query, const String& fieldName, const TokenStreamPtr& stream, const FormatterPtr& formatter) { + return getHighlighter(query, fieldName, stream, formatter, true); + } - virtual HighlighterPtr getHighlighter(const QueryPtr& query, const String& fieldName, const TokenStreamPtr& stream, const FormatterPtr& formatter, bool expanMultiTerm) - { - HighlighterScorerPtr scorer; - if (mode == QUERY) - { - scorer = newLucene(query, fieldName); - if (!expanMultiTerm) - boost::dynamic_pointer_cast(scorer)->setExpandMultiTermQuery(false); + virtual HighlighterPtr getHighlighter(const QueryPtr& query, const String& fieldName, const TokenStreamPtr& stream, const FormatterPtr& formatter, bool expanMultiTerm) { + HighlighterScorerPtr scorer; + if (mode == QUERY) { + scorer = newLucene(query, fieldName); + if (!expanMultiTerm) { + boost::dynamic_pointer_cast(scorer)->setExpandMultiTermQuery(false); } - else if (mode == QUERY_TERM) - scorer = newLucene(query); - else - boost::throw_exception(IllegalArgumentException(L"Unknown highlight mode")); - - return newLucene(formatter, scorer); + } else if (mode == QUERY_TERM) { + scorer = newLucene(query); + } else { + boost::throw_exception(IllegalArgumentException(L"Unknown highlight mode")); } - virtual HighlighterPtr getHighlighter(Collection weightedTerms, const FormatterPtr& formatter) - { - if (mode == QUERY) - { - Collection weightedSpanTerms = Collection::newInstance(weightedTerms.size()); - for (int32_t i = 0; i < weightedTerms.size(); ++i) - weightedSpanTerms[i] = boost::dynamic_pointer_cast(weightedTerms[i]); - return newLucene(formatter, newLucene(weightedSpanTerms)); + return newLucene(formatter, scorer); + } + + virtual HighlighterPtr getHighlighter(Collection weightedTerms, const FormatterPtr& formatter) { + if (mode == QUERY) { + Collection weightedSpanTerms = Collection::newInstance(weightedTerms.size()); + for (int32_t i = 0; i < weightedTerms.size(); ++i) { + weightedSpanTerms[i] = boost::dynamic_pointer_cast(weightedTerms[i]); } - else if (mode == QUERY_TERM) - return newLucene(formatter, newLucene(weightedTerms)); - else - boost::throw_exception(IllegalArgumentException(L"Unknown highlight mode")); - return HighlighterPtr(); + return newLucene(formatter, newLucene(weightedSpanTerms)); + } else if (mode == QUERY_TERM) { + return newLucene(formatter, newLucene(weightedTerms)); + } else { + boost::throw_exception(IllegalArgumentException(L"Unknown highlight mode")); } + return HighlighterPtr(); + } + + virtual void doStandardHighlights(const AnalyzerPtr& analyzer, const IndexSearcherPtr& searcher, const TopDocsPtr& hits, const QueryPtr& query, const FormatterPtr& formatter, Collection expected, bool expandMT = false) { + Collection results = Collection::newInstance(); - virtual void doStandardHighlights(const AnalyzerPtr& analyzer, const IndexSearcherPtr& searcher, const TopDocsPtr& hits, const QueryPtr& query, const FormatterPtr& formatter, Collection expected, bool expandMT = false) - { - Collection results = Collection::newInstance(); - - for (int32_t i = 0; i < hits->totalHits; ++i) - { - String text = searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); - int32_t maxNumFragmentsRequired = 2; - String fragmentSeparator = L"..."; - HighlighterScorerPtr scorer; - TokenStreamPtr tokenStream = analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - if (mode == QUERY) - scorer = newLucene(query); - else if (mode == QUERY_TERM) - scorer = newLucene(query); - HighlighterPtr highlighter = newLucene(formatter, scorer); - highlighter->setTextFragmenter(frag); - results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, fragmentSeparator)); + for (int32_t i = 0; i < hits->totalHits; ++i) { + String text = searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + int32_t maxNumFragmentsRequired = 2; + String fragmentSeparator = L"..."; + HighlighterScorerPtr scorer; + TokenStreamPtr tokenStream = analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + if (mode == QUERY) { + scorer = newLucene(query); + } else if (mode == QUERY_TERM) { + scorer = newLucene(query); } + HighlighterPtr highlighter = newLucene(formatter, scorer); + highlighter->setTextFragmenter(frag); + results.add(highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, fragmentSeparator)); + } - EXPECT_EQ(results.size(), expected.size()); - for (int32_t i = 0; i < results.size(); ++i) - EXPECT_EQ(results[i], expected[i]); + EXPECT_EQ(results.size(), expected.size()); + for (int32_t i = 0; i < results.size(); ++i) { + EXPECT_EQ(results[i], expected[i]); } + } - virtual void run(Collection expected) = 0; + virtual void run(Collection expected) = 0; - virtual void start(Collection expected = Collection()) - { - run(expected); - mode = QUERY_TERM; - run(expected); - } - }; + virtual void start(Collection expected = Collection()) { + run(expected); + mode = QUERY_TERM; + run(expected); + } +}; - const int32_t TestHighlightRunner::QUERY = 0; - const int32_t TestHighlightRunner::QUERY_TERM = 1; +const int32_t TestHighlightRunner::QUERY = 0; +const int32_t TestHighlightRunner::QUERY_TERM = 1; } -TEST_F(HighlighterTest, testQueryScorerHits) -{ +TEST_F(HighlighterTest, testQueryScorerHits) { AnalyzerPtr analyzer = newLucene(); QueryParserPtr qp = newLucene(TEST_VERSION, FIELD_NAME, analyzer); query = qp->parse(L"\"very long\""); @@ -398,8 +376,7 @@ TEST_F(HighlighterTest, testQueryScorerHits) HighlighterPtr highlighter = newLucene(scorer); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) - { + for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) { DocumentPtr doc = searcher->doc(hits->scoreDocs[i]->doc); String storedField = doc->get(FIELD_NAME); @@ -416,8 +393,7 @@ TEST_F(HighlighterTest, testQueryScorerHits) EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); } -TEST_F(HighlighterTest, testHighlightingWithDefaultField) -{ +TEST_F(HighlighterTest, testHighlightingWithDefaultField) { String s1 = L"I call our world Flatland, not because we call it so,"; QueryParserPtr parser = newLucene(TEST_VERSION, FIELD_NAME, newLucene(TEST_VERSION)); @@ -437,8 +413,7 @@ TEST_F(HighlighterTest, testHighlightingWithDefaultField) EXPECT_EQ(s1, highlightField(q, FIELD_NAME, s1)); } -TEST_F(HighlighterTest, testSimpleSpanHighlighter) -{ +TEST_F(HighlighterTest, testSimpleSpanHighlighter) { doSearching(L"Kennedy"); int32_t maxNumFragmentsRequired = 2; @@ -447,8 +422,7 @@ TEST_F(HighlighterTest, testSimpleSpanHighlighter) HighlighterPtr highlighter = newLucene(scorer); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); highlighter->setTextFragmenter(newLucene(40)); @@ -462,8 +436,7 @@ TEST_F(HighlighterTest, testSimpleSpanHighlighter) EXPECT_EQ(results[2], L" kennedy has been shot"); } -TEST_F(HighlighterTest, testRepeatingTermsInMultBooleans) -{ +TEST_F(HighlighterTest, testRepeatingTermsInMultBooleans) { String content = L"x y z a b c d e f g b c g"; String ph1 = L"\"a b c d\""; String ph2 = L"\"b c g\""; @@ -486,8 +459,7 @@ TEST_F(HighlighterTest, testRepeatingTermsInMultBooleans) EXPECT_EQ(numHighlights, 7); } -TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting) -{ +TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting) { doSearching(L"\"very long and contains\""); int32_t maxNumFragmentsRequired = 2; @@ -496,8 +468,7 @@ TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting) HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -520,8 +491,7 @@ TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting) highlighter = newLucene(newLucene(this), scorer); results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -544,8 +514,7 @@ TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting) highlighter = newLucene(newLucene(this), scorer); results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -560,18 +529,15 @@ TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting) EXPECT_EQ(numHighlights, 4); } -TEST_F(HighlighterTest, testSpanRegexQuery) -{ +TEST_F(HighlighterTest, testSpanRegexQuery) { // todo } -TEST_F(HighlighterTest, testRegexQuery) -{ +TEST_F(HighlighterTest, testRegexQuery) { // todo } -TEST_F(HighlighterTest, testNumericRangeQuery) -{ +TEST_F(HighlighterTest, testNumericRangeQuery) { // doesn't currently highlight, but make sure it doesn't cause exception either query = NumericRangeQuery::newIntRange(NUMERIC_FIELD_NAME, 2, 6, true, true); searcher = newLucene(ramDir, true); @@ -582,8 +548,7 @@ TEST_F(HighlighterTest, testNumericRangeQuery) HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(NUMERIC_FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -599,8 +564,7 @@ TEST_F(HighlighterTest, testNumericRangeQuery) EXPECT_EQ(numHighlights, 0); } -TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting2) -{ +TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting2) { doSearching(L"\"text piece long\"~5"); int32_t maxNumFragmentsRequired = 2; @@ -610,8 +574,7 @@ TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting2) highlighter->setTextFragmenter(newLucene(40)); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -625,15 +588,13 @@ TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting2) EXPECT_EQ(numHighlights, 6); } -TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting3) -{ +TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting3) { doSearching(L"\"x y z\""); int32_t maxNumFragmentsRequired = 2; Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); QueryScorerPtr scorer = newLucene(query, FIELD_NAME); @@ -650,8 +611,7 @@ TEST_F(HighlighterTest, testSimpleQueryScorerPhraseHighlighting3) EXPECT_EQ(results[0], L"y z x y z a b"); } -TEST_F(HighlighterTest, testSimpleSpanFragmenter) -{ +TEST_F(HighlighterTest, testSimpleSpanFragmenter) { doSearching(L"\"piece of text that is very long\""); int32_t maxNumFragmentsRequired = 2; @@ -660,8 +620,7 @@ TEST_F(HighlighterTest, testSimpleSpanFragmenter) HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -682,8 +641,7 @@ TEST_F(HighlighterTest, testSimpleSpanFragmenter) highlighter = newLucene(newLucene(this), scorer); results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -701,8 +659,7 @@ TEST_F(HighlighterTest, testSimpleSpanFragmenter) } /// position sensitive query added after position insensitive query -TEST_F(HighlighterTest, testPosTermStdTerm) -{ +TEST_F(HighlighterTest, testPosTermStdTerm) { doSearching(L"y \"x y z\""); int32_t maxNumFragmentsRequired = 2; @@ -711,8 +668,7 @@ TEST_F(HighlighterTest, testPosTermStdTerm) HighlighterPtr highlighter = newLucene(newLucene(this), scorer); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -727,8 +683,7 @@ TEST_F(HighlighterTest, testPosTermStdTerm) EXPECT_EQ(results[0], L"y z x y z a b"); } -TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlighting) -{ +TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlighting) { MultiPhraseQueryPtr mpq = newLucene(); mpq->add(newCollection(newLucene(FIELD_NAME, L"wordx"), newLucene(FIELD_NAME, L"wordb"))); @@ -742,8 +697,7 @@ TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlighting) checkExpectedHighlightCount(maxNumFragmentsRequired, 6, expected); } -TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlightingWithGap) -{ +TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlightingWithGap) { MultiPhraseQueryPtr mpq = newLucene(); // The toString of MultiPhraseQuery doesn't work so well with these out-of-order additions, but the Query itself seems to match accurately. @@ -761,33 +715,29 @@ TEST_F(HighlighterTest, testQueryScorerMultiPhraseQueryHighlightingWithGap) checkExpectedHighlightCount(maxNumFragmentsRequired, expectedHighlights, expected); } -namespace TestNearSpanSimpleQuery -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestNearSpanSimpleQuery { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + mode = QUERY; + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + } +}; - public: - virtual void run(Collection expected) - { - mode = QUERY; - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - } - }; } -TEST_F(HighlighterTest, testNearSpanSimpleQuery) -{ +TEST_F(HighlighterTest, testNearSpanSimpleQuery) { doSearching(newLucene(newCollection( - newLucene(newLucene(FIELD_NAME, L"beginning")), - newLucene(newLucene(FIELD_NAME, L"kennedy"))), 3, false)); + newLucene(newLucene(FIELD_NAME, L"beginning")), + newLucene(newLucene(FIELD_NAME, L"kennedy"))), 3, false)); HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); @@ -797,8 +747,7 @@ TEST_F(HighlighterTest, testNearSpanSimpleQuery) EXPECT_EQ(numHighlights, 2); } -TEST_F(HighlighterTest, testSimpleQueryTermScorerHighlighter) -{ +TEST_F(HighlighterTest, testSimpleQueryTermScorerHighlighter) { doSearching(L"Kennedy"); HighlighterPtr highlighter = newLucene(newLucene(query)); highlighter->setTextFragmenter(newLucene(40)); @@ -806,8 +755,7 @@ TEST_F(HighlighterTest, testSimpleQueryTermScorerHighlighter) int32_t maxNumFragmentsRequired = 2; Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); @@ -820,36 +768,32 @@ TEST_F(HighlighterTest, testSimpleQueryTermScorerHighlighter) EXPECT_EQ(results[2], L" kennedy has been shot"); } -namespace TestSpanHighlighting -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestSpanHighlighting { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + mode = QUERY; + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + } +}; - public: - virtual void run(Collection expected) - { - mode = QUERY; - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - } - }; } -TEST_F(HighlighterTest, testSpanHighlighting) -{ +TEST_F(HighlighterTest, testSpanHighlighting) { QueryPtr query1 = newLucene(newCollection( - newLucene(newLucene(FIELD_NAME, L"wordx")), - newLucene(newLucene(FIELD_NAME, L"wordy"))), 1, false); + newLucene(newLucene(FIELD_NAME, L"wordx")), + newLucene(newLucene(FIELD_NAME, L"wordy"))), 1, false); QueryPtr query2 = newLucene(newCollection( - newLucene(newLucene(FIELD_NAME, L"wordy")), - newLucene(newLucene(FIELD_NAME, L"wordc"))), 1, false); + newLucene(newLucene(FIELD_NAME, L"wordy")), + newLucene(newLucene(FIELD_NAME, L"wordc"))), 1, false); BooleanQueryPtr bquery = newLucene(); bquery->add(query1, BooleanClause::SHOULD); bquery->add(query2, BooleanClause::SHOULD); @@ -863,72 +807,64 @@ TEST_F(HighlighterTest, testSpanHighlighting) EXPECT_EQ(numHighlights, 7); } -namespace TestNotSpanSimpleQuery -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestNotSpanSimpleQuery { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + mode = QUERY; + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + } +}; - public: - virtual void run(Collection expected) - { - mode = QUERY; - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - } - }; } -TEST_F(HighlighterTest, testNotSpanSimpleQuery) -{ +TEST_F(HighlighterTest, testNotSpanSimpleQuery) { doSearching(newLucene(newLucene(newCollection( - newLucene(newLucene(FIELD_NAME, L"shot")), - newLucene(newLucene(FIELD_NAME, L"kennedy"))), 3, false), - newLucene(newLucene(FIELD_NAME, L"john")))); + newLucene(newLucene(FIELD_NAME, L"shot")), + newLucene(newLucene(FIELD_NAME, L"kennedy"))), 3, false), + newLucene(newLucene(FIELD_NAME, L"john")))); HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); Collection expected = newCollection( - L"John Kennedy has been shot", - L" kennedy has been shot" - ); + L"John Kennedy has been shot", + L" kennedy has been shot" + ); helper->run(expected); EXPECT_EQ(numHighlights, 4); } -namespace TestGetBestFragmentsSimpleQuery -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestFragmentsSimpleQuery { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"Kennedy"); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 4); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"Kennedy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - EXPECT_EQ(fixture->numHighlights, 4); - } - }; } -TEST_F(HighlighterTest, testGetBestFragmentsSimpleQuery) -{ +TEST_F(HighlighterTest, testGetBestFragmentsSimpleQuery) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start( @@ -940,32 +876,28 @@ TEST_F(HighlighterTest, testGetBestFragmentsSimpleQuery) ); } -namespace TestGetFuzzyFragments -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetFuzzyFragments { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"Kinnedy~"); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected, true); + EXPECT_EQ(fixture->numHighlights, 5); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"Kinnedy~"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected, true); - EXPECT_EQ(fixture->numHighlights, 5); - } - }; } -TEST_F(HighlighterTest, testGetFuzzyFragments) -{ +TEST_F(HighlighterTest, testGetFuzzyFragments) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start( @@ -978,32 +910,28 @@ TEST_F(HighlighterTest, testGetFuzzyFragments) ); } -namespace TestGetWildCardFragments -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetWildCardFragments { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"K?nnedy"); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 4); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"K?nnedy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - EXPECT_EQ(fixture->numHighlights, 4); - } - }; } -TEST_F(HighlighterTest, testGetWildCardFragments) -{ +TEST_F(HighlighterTest, testGetWildCardFragments) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start( @@ -1015,32 +943,28 @@ TEST_F(HighlighterTest, testGetWildCardFragments) ); } -namespace TestGetMidWildCardFragments -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetMidWildCardFragments { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"K*dy"); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"K*dy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - EXPECT_EQ(fixture->numHighlights, 5); - } - }; } -TEST_F(HighlighterTest, testGetMidWildCardFragments) -{ +TEST_F(HighlighterTest, testGetMidWildCardFragments) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start( @@ -1053,39 +977,35 @@ TEST_F(HighlighterTest, testGetMidWildCardFragments) ); } -namespace TestGetRangeFragments -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetRangeFragments { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - String queryString = HighlighterTest::FIELD_NAME + L":[kannedy TO kznnedy]"; +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + String queryString = HighlighterTest::FIELD_NAME + L":[kannedy TO kznnedy]"; - // Need to explicitly set the QueryParser property to use TermRangeQuery rather than RangeFilters - QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, fixture->analyzer); - parser->setMultiTermRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); - fixture->query = parser->parse(queryString); - fixture->doSearching(fixture->query); + // Need to explicitly set the QueryParser property to use TermRangeQuery rather than RangeFilters + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, fixture->analyzer); + parser->setMultiTermRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); + fixture->query = parser->parse(queryString); + fixture->doSearching(fixture->query); + + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); + } +}; - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - EXPECT_EQ(fixture->numHighlights, 5); - } - }; } -TEST_F(HighlighterTest, testGetRangeFragments) -{ +TEST_F(HighlighterTest, testGetRangeFragments) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start( @@ -1098,8 +1018,7 @@ TEST_F(HighlighterTest, testGetRangeFragments) ); } -TEST_F(HighlighterTest, testConstantScoreMultiTermQuery) -{ +TEST_F(HighlighterTest, testConstantScoreMultiTermQuery) { numHighlights = 0; query = newLucene(newLucene(FIELD_NAME, L"ken*")); @@ -1111,8 +1030,7 @@ TEST_F(HighlighterTest, testConstantScoreMultiTermQuery) Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); int32_t maxNumFragmentsRequired = 2; String fragmentSeparator = L"..."; @@ -1143,8 +1061,7 @@ TEST_F(HighlighterTest, testConstantScoreMultiTermQuery) results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); int32_t maxNumFragmentsRequired = 2; String fragmentSeparator = L"..."; @@ -1175,8 +1092,7 @@ TEST_F(HighlighterTest, testConstantScoreMultiTermQuery) results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = searcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); int32_t maxNumFragmentsRequired = 2; String fragmentSeparator = L"..."; @@ -1200,212 +1116,188 @@ TEST_F(HighlighterTest, testConstantScoreMultiTermQuery) EXPECT_EQ(results[3], L" to Keneddy"); } -namespace TestGetBestFragmentsPhrase -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestFragmentsPhrase { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"\"John Kennedy\""); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"\"John Kennedy\""); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + + // Currently highlights "John" and "Kennedy" separately + EXPECT_EQ(fixture->numHighlights, 2); + } +}; - // Currently highlights "John" and "Kennedy" separately - EXPECT_EQ(fixture->numHighlights, 2); - } - }; } -TEST_F(HighlighterTest, testGetBestFragmentsPhrase) -{ +TEST_F(HighlighterTest, testGetBestFragmentsPhrase) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } -namespace TestGetBestFragmentsQueryScorer -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestFragmentsQueryScorer { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + Collection clauses = newCollection( + newLucene(newLucene(L"contents", L"john")), + newLucene(newLucene(L"contents", L"kennedy")) + ); + + SpanNearQueryPtr snq = newLucene(clauses, 1, true); + fixture->doSearching(snq); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + + // Currently highlights "John" and "Kennedy" separately + EXPECT_EQ(fixture->numHighlights, 2); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - Collection clauses = newCollection( - newLucene(newLucene(L"contents", L"john")), - newLucene(newLucene(L"contents", L"kennedy")) - ); - - SpanNearQueryPtr snq = newLucene(clauses, 1, true); - fixture->doSearching(snq); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - - // Currently highlights "John" and "Kennedy" separately - EXPECT_EQ(fixture->numHighlights, 2); - } - }; } -TEST_F(HighlighterTest, testGetBestFragmentsQueryScorer) -{ +TEST_F(HighlighterTest, testGetBestFragmentsQueryScorer) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } -namespace TestOffByOne -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestOffByOne { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - TermQueryPtr query = newLucene(newLucene(L"data", L"help")); - HighlighterPtr hg = newLucene(newLucene(), newLucene(query)); - hg->setTextFragmenter(newLucene()); + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + TermQueryPtr query = newLucene(newLucene(L"data", L"help")); + HighlighterPtr hg = newLucene(newLucene(), newLucene(query)); + hg->setTextFragmenter(newLucene()); + + String match = hg->getBestFragment(fixture->analyzer, L"data", L"help me [54-65]"); + EXPECT_EQ(L"help me [54-65]", match); + } +}; - String match = hg->getBestFragment(fixture->analyzer, L"data", L"help me [54-65]"); - EXPECT_EQ(L"help me [54-65]", match); - } - }; } -TEST_F(HighlighterTest, testOffByOne) -{ +TEST_F(HighlighterTest, testOffByOne) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestGetBestFragmentsFilteredQuery -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestFragmentsFilteredQuery { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + TermRangeFilterPtr rf = newLucene(L"contents", L"john", L"john", true, true); + Collection clauses = newCollection( + newLucene(newLucene(L"contents", L"john")), + newLucene(newLucene(L"contents", L"kennedy")) + ); + SpanNearQueryPtr snq = newLucene(clauses, 1, true); + FilteredQueryPtr fq = newLucene(snq, rf); + + fixture->doSearching(fq); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + + // Currently highlights "John" and "Kennedy" separately + EXPECT_EQ(fixture->numHighlights, 2); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - TermRangeFilterPtr rf = newLucene(L"contents", L"john", L"john", true, true); - Collection clauses = newCollection( - newLucene(newLucene(L"contents", L"john")), - newLucene(newLucene(L"contents", L"kennedy")) - ); - SpanNearQueryPtr snq = newLucene(clauses, 1, true); - FilteredQueryPtr fq = newLucene(snq, rf); - - fixture->doSearching(fq); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - - // Currently highlights "John" and "Kennedy" separately - EXPECT_EQ(fixture->numHighlights, 2); - } - }; } -TEST_F(HighlighterTest, testGetBestFragmentsFilteredQuery) -{ +TEST_F(HighlighterTest, testGetBestFragmentsFilteredQuery) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } -namespace TestGetBestFragmentsFilteredPhraseQuery -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestFragmentsFilteredPhraseQuery { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + TermRangeFilterPtr rf = newLucene(L"contents", L"john", L"john", true, true); + PhraseQueryPtr pq = newLucene(); + pq->add(newLucene(L"contents", L"john")); + pq->add(newLucene(L"contents", L"kennedy")); + FilteredQueryPtr fq = newLucene(pq, rf); + + fixture->doSearching(fq); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + + // Currently highlights "John" and "Kennedy" separately + EXPECT_EQ(fixture->numHighlights, 2); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - TermRangeFilterPtr rf = newLucene(L"contents", L"john", L"john", true, true); - PhraseQueryPtr pq = newLucene(); - pq->add(newLucene(L"contents", L"john")); - pq->add(newLucene(L"contents", L"kennedy")); - FilteredQueryPtr fq = newLucene(pq, rf); - - fixture->doSearching(fq); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - - // Currently highlights "John" and "Kennedy" separately - EXPECT_EQ(fixture->numHighlights, 2); - } - }; } -TEST_F(HighlighterTest, testGetBestFragmentsFilteredPhraseQuery) -{ +TEST_F(HighlighterTest, testGetBestFragmentsFilteredPhraseQuery) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(newCollection(L"John Kennedy has been shot")); } -namespace TestGetBestFragmentsMultiTerm -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestFragmentsMultiTerm { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"John Kenn*"); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"John Kenn*"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - EXPECT_EQ(fixture->numHighlights, 5); - } - }; } -TEST_F(HighlighterTest, testGetBestFragmentsMultiTerm) -{ +TEST_F(HighlighterTest, testGetBestFragmentsMultiTerm) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start( @@ -1417,32 +1309,28 @@ TEST_F(HighlighterTest, testGetBestFragmentsMultiTerm) ); } -namespace TestGetBestFragmentsWithOr -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestFragmentsWithOr { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"JFK OR Kennedy"); + doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); + EXPECT_EQ(fixture->numHighlights, 5); + } +}; - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"JFK OR Kennedy"); - doStandardHighlights(fixture->analyzer, fixture->searcher, fixture->hits, fixture->query, newLucene(fixture), expected); - EXPECT_EQ(fixture->numHighlights, 5); - } - }; } -TEST_F(HighlighterTest, testGetBestFragmentsWithOr) -{ +TEST_F(HighlighterTest, testGetBestFragmentsWithOr) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start( @@ -1455,628 +1343,564 @@ TEST_F(HighlighterTest, testGetBestFragmentsWithOr) ); } -namespace TestGetBestSingleFragment -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { +namespace TestGetBestSingleFragment { + +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->doSearching(L"Kennedy"); + fixture->numHighlights = 0; + Collection results = Collection::newInstance(); + + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + highlighter->setTextFragmenter(newLucene(40)); + results.add(highlighter->getBestFragment(tokenStream, text)); } + EXPECT_EQ(fixture->numHighlights, 4); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy"); + EXPECT_EQ(results[2], L" kennedy has been shot"); + + fixture->numHighlights = 0; + results = Collection::newInstance(); - virtual ~HelperHighlightRunner() - { + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + results.add(highlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, text)); } + EXPECT_EQ(fixture->numHighlights, 4); - public: - virtual void run(Collection expected) - { - fixture->doSearching(L"Kennedy"); - fixture->numHighlights = 0; - Collection results = Collection::newInstance(); - - for (int32_t i = 0; i < fixture->hits->totalHits; ++i) - { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); - highlighter->setTextFragmenter(newLucene(40)); - results.add(highlighter->getBestFragment(tokenStream, text)); - } - EXPECT_EQ(fixture->numHighlights, 4); - - EXPECT_EQ(results.size(), 3); - EXPECT_EQ(results[0], L"John Kennedy has been shot"); - EXPECT_EQ(results[1], L"This piece of text refers to Kennedy"); - EXPECT_EQ(results[2], L" kennedy has been shot"); - - fixture->numHighlights = 0; - results = Collection::newInstance(); - - for (int32_t i = 0; i < fixture->hits->totalHits; ++i) - { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); - results.add(highlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, text)); - } - EXPECT_EQ(fixture->numHighlights, 4); - - EXPECT_EQ(results.size(), 3); - EXPECT_EQ(results[0], L"John Kennedy has been shot"); - EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); - EXPECT_EQ(results[2], L" is really here which says kennedy has been shot"); - - fixture->numHighlights = 0; - results = Collection::newInstance(); - - for (int32_t i = 0; i < fixture->hits->totalHits; ++i) - { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); - highlighter->setTextFragmenter(newLucene(40)); - Collection result = highlighter->getBestFragments(fixture->analyzer, HighlighterTest::FIELD_NAME, text, 10); - results.addAll(result.begin(), result.end()); - } - EXPECT_EQ(fixture->numHighlights, 4); + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); + EXPECT_EQ(results[2], L" is really here which says kennedy has been shot"); - EXPECT_EQ(results.size(), 3); - EXPECT_EQ(results[0], L"John Kennedy has been shot"); - EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy"); - EXPECT_EQ(results[2], L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot"); + fixture->numHighlights = 0; + results = Collection::newInstance(); + + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + highlighter->setTextFragmenter(newLucene(40)); + Collection result = highlighter->getBestFragments(fixture->analyzer, HighlighterTest::FIELD_NAME, text, 10); + results.addAll(result.begin(), result.end()); } - }; + EXPECT_EQ(fixture->numHighlights, 4); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy"); + EXPECT_EQ(results[2], L"Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot"); + } +}; + } -TEST_F(HighlighterTest, testGetBestSingleFragment) -{ +TEST_F(HighlighterTest, testGetBestSingleFragment) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestGetBestSingleFragmentWithWeights -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetBestSingleFragmentWithWeights { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - Collection wTerms = Collection::newInstance(2); - wTerms[0] = newLucene(10.0, L"hello"); + virtual ~HelperHighlightRunner() { + } - Collection positionSpans = newCollection(newLucene(0, 0)); - boost::dynamic_pointer_cast(wTerms[0])->addPositionSpans(positionSpans); +public: + virtual void run(Collection expected) { + Collection wTerms = Collection::newInstance(2); + wTerms[0] = newLucene(10.0, L"hello"); - wTerms[1] = newLucene(1.0, L"kennedy"); - positionSpans = newCollection(newLucene(14, 14)); - boost::dynamic_pointer_cast(wTerms[1])->addPositionSpans(positionSpans); + Collection positionSpans = newCollection(newLucene(0, 0)); + boost::dynamic_pointer_cast(wTerms[0])->addPositionSpans(positionSpans); - HighlighterPtr highlighter = getHighlighter(wTerms, newLucene(fixture)); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); - highlighter->setTextFragmenter(newLucene(2)); + wTerms[1] = newLucene(1.0, L"kennedy"); + positionSpans = newCollection(newLucene(14, 14)); + boost::dynamic_pointer_cast(wTerms[1])->addPositionSpans(positionSpans); - String result = highlighter->getBestFragment(tokenStream, fixture->texts[0]); - boost::trim(result); + HighlighterPtr highlighter = getHighlighter(wTerms, newLucene(fixture)); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); + highlighter->setTextFragmenter(newLucene(2)); - EXPECT_EQ(L"Hello", result); + String result = highlighter->getBestFragment(tokenStream, fixture->texts[0]); + boost::trim(result); - wTerms[1]->setWeight(50.0); - tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); - highlighter = getHighlighter(wTerms, newLucene(fixture)); - highlighter->setTextFragmenter(newLucene(2)); + EXPECT_EQ(L"Hello", result); - result = highlighter->getBestFragment(tokenStream, fixture->texts[0]); - boost::trim(result); + wTerms[1]->setWeight(50.0); + tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); + highlighter = getHighlighter(wTerms, newLucene(fixture)); + highlighter->setTextFragmenter(newLucene(2)); + + result = highlighter->getBestFragment(tokenStream, fixture->texts[0]); + boost::trim(result); + + EXPECT_EQ(L"kennedy", result); + } +}; - EXPECT_EQ(L"kennedy", result); - } - }; } -TEST_F(HighlighterTest, testGetBestSingleFragmentWithWeights) -{ +TEST_F(HighlighterTest, testGetBestSingleFragmentWithWeights) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestOverlapAnalyzer -{ - class SynonymTokenizer : public TokenStream - { - public: - SynonymTokenizer(const TokenStreamPtr& realStream, MapStringString synonyms) - { - this->realStream = realStream; - this->synonyms = synonyms; - this->synonymToken = 0; - this->realTermAtt = realStream->addAttribute(); - this->realPosIncrAtt = realStream->addAttribute(); - this->realOffsetAtt = realStream->addAttribute(); - - this->termAtt = addAttribute(); - this->posIncrAtt = addAttribute(); - this->offsetAtt = addAttribute(); - } +namespace TestOverlapAnalyzer { - virtual ~SynonymTokenizer() - { - } +class SynonymTokenizer : public TokenStream { +public: + SynonymTokenizer(const TokenStreamPtr& realStream, MapStringString synonyms) { + this->realStream = realStream; + this->synonyms = synonyms; + this->synonymToken = 0; + this->realTermAtt = realStream->addAttribute(); + this->realPosIncrAtt = realStream->addAttribute(); + this->realOffsetAtt = realStream->addAttribute(); + + this->termAtt = addAttribute(); + this->posIncrAtt = addAttribute(); + this->offsetAtt = addAttribute(); + } - protected: - TokenStreamPtr realStream; - TokenPtr currentRealToken; - TokenPtr cRealToken; - MapStringString synonyms; - Collection synonymTokens; - int32_t synonymToken; - TermAttributePtr realTermAtt; - PositionIncrementAttributePtr realPosIncrAtt; - OffsetAttributePtr realOffsetAtt; - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncrAtt; - OffsetAttributePtr offsetAtt; - - public: - virtual bool incrementToken() - { - if (!currentRealToken) - { - bool next = realStream->incrementToken(); - if (!next) - return false; - clearAttributes(); - termAtt->setTermBuffer(realTermAtt->term()); - offsetAtt->setOffset(realOffsetAtt->startOffset(), realOffsetAtt->endOffset()); - posIncrAtt->setPositionIncrement(realPosIncrAtt->getPositionIncrement()); - - if (!synonyms.contains(realTermAtt->term())) - return true; - String expansions = synonyms.get(realTermAtt->term()); - synonymTokens = StringUtils::split(expansions, L","); - synonymToken = 0; - if (!synonymTokens.empty()) - { - currentRealToken = newLucene(realOffsetAtt->startOffset(), realOffsetAtt->endOffset()); - currentRealToken->setTermBuffer(realTermAtt->term()); - } - return true; + virtual ~SynonymTokenizer() { + } + +protected: + TokenStreamPtr realStream; + TokenPtr currentRealToken; + TokenPtr cRealToken; + MapStringString synonyms; + Collection synonymTokens; + int32_t synonymToken; + TermAttributePtr realTermAtt; + PositionIncrementAttributePtr realPosIncrAtt; + OffsetAttributePtr realOffsetAtt; + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncrAtt; + OffsetAttributePtr offsetAtt; + +public: + virtual bool incrementToken() { + if (!currentRealToken) { + bool next = realStream->incrementToken(); + if (!next) { + return false; } - else - { - String tok = synonymTokens[synonymToken++]; - clearAttributes(); - termAtt->setTermBuffer(tok); - offsetAtt->setOffset(currentRealToken->startOffset(), currentRealToken->endOffset()); - posIncrAtt->setPositionIncrement(0); - if (synonymToken == synonymTokens.size()) - { - currentRealToken.reset(); - synonymTokens.reset(); - synonymToken = 0; - } + clearAttributes(); + termAtt->setTermBuffer(realTermAtt->term()); + offsetAtt->setOffset(realOffsetAtt->startOffset(), realOffsetAtt->endOffset()); + posIncrAtt->setPositionIncrement(realPosIncrAtt->getPositionIncrement()); + + if (!synonyms.contains(realTermAtt->term())) { return true; } + String expansions = synonyms.get(realTermAtt->term()); + synonymTokens = StringUtils::split(expansions, L","); + synonymToken = 0; + if (!synonymTokens.empty()) { + currentRealToken = newLucene(realOffsetAtt->startOffset(), realOffsetAtt->endOffset()); + currentRealToken->setTermBuffer(realTermAtt->term()); + } + return true; + } else { + String tok = synonymTokens[synonymToken++]; + clearAttributes(); + termAtt->setTermBuffer(tok); + offsetAtt->setOffset(currentRealToken->startOffset(), currentRealToken->endOffset()); + posIncrAtt->setPositionIncrement(0); + if (synonymToken == synonymTokens.size()) { + currentRealToken.reset(); + synonymTokens.reset(); + synonymToken = 0; + } + return true; } - }; - - class SynonymAnalyzer : public Analyzer - { - public: - SynonymAnalyzer(MapStringString synonyms) - { - this->synonyms = synonyms; - } + } +}; - virtual ~SynonymAnalyzer() - { - } +class SynonymAnalyzer : public Analyzer { +public: + SynonymAnalyzer(MapStringString synonyms) { + this->synonyms = synonyms; + } - protected: - MapStringString synonyms; - - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - LowerCaseTokenizerPtr stream = newLucene(reader); - stream->addAttribute(); - stream->addAttribute(); - stream->addAttribute(); - return newLucene(stream, synonyms); - } - }; + virtual ~SynonymAnalyzer() { + } - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +protected: + MapStringString synonyms; - virtual ~HelperHighlightRunner() - { - } +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + LowerCaseTokenizerPtr stream = newLucene(reader); + stream->addAttribute(); + stream->addAttribute(); + stream->addAttribute(); + return newLucene(stream, synonyms); + } +}; - public: - virtual void run(Collection expected) - { - MapStringString synonyms = MapStringString::newInstance(); - synonyms.put(L"football", L"soccer,footie"); - AnalyzerPtr analyzer = newLucene(synonyms); - String srchkey = L"football"; +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } - String s = L"football-soccer in the euro 2004 footie competition"; - QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, L"bookid", analyzer); - QueryPtr query = parser->parse(srchkey); +public: + virtual void run(Collection expected) { + MapStringString synonyms = MapStringString::newInstance(); + synonyms.put(L"football", L"soccer,footie"); + AnalyzerPtr analyzer = newLucene(synonyms); + String srchkey = L"football"; - TokenStreamPtr tokenStream = analyzer->tokenStream(L"", newLucene(s)); + String s = L"football-soccer in the euro 2004 footie competition"; + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, L"bookid", analyzer); + QueryPtr query = parser->parse(srchkey); - HighlighterPtr highlighter = getHighlighter(query, L"", tokenStream, newLucene(fixture)); + TokenStreamPtr tokenStream = analyzer->tokenStream(L"", newLucene(s)); - // Get 3 best fragments and separate with a "..." - tokenStream = analyzer->tokenStream(L"", newLucene(s)); + HighlighterPtr highlighter = getHighlighter(query, L"", tokenStream, newLucene(fixture)); - String result = highlighter->getBestFragments(tokenStream, s, 3, L"..."); - String expectedResult = L"football-soccer in the euro 2004 footie competition"; + // Get 3 best fragments and separate with a "..." + tokenStream = analyzer->tokenStream(L"", newLucene(s)); + + String result = highlighter->getBestFragments(tokenStream, s, 3, L"..."); + String expectedResult = L"football-soccer in the euro 2004 footie competition"; + + EXPECT_EQ(expectedResult, result); + } +}; - EXPECT_EQ(expectedResult, result); - } - }; } /// tests a "complex" analyzer that produces multiple overlapping tokens -TEST_F(HighlighterTest, testOverlapAnalyzer) -{ +TEST_F(HighlighterTest, testOverlapAnalyzer) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestGetSimpleHighlight -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetSimpleHighlight { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"Kennedy"); + virtual ~HelperHighlightRunner() { + } - Collection results = Collection::newInstance(); +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"Kennedy"); - for (int32_t i = 0; i < fixture->hits->totalHits; ++i) - { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); - results.add(highlighter->getBestFragment(tokenStream, text)); - } - EXPECT_EQ(fixture->numHighlights, 4); + Collection results = Collection::newInstance(); - EXPECT_EQ(results.size(), 3); - EXPECT_EQ(results[0], L"John Kennedy has been shot"); - EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); - EXPECT_EQ(results[2], L" is really here which says kennedy has been shot"); + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + results.add(highlighter->getBestFragment(tokenStream, text)); } - }; + EXPECT_EQ(fixture->numHighlights, 4); + + EXPECT_EQ(results.size(), 3); + EXPECT_EQ(results[0], L"John Kennedy has been shot"); + EXPECT_EQ(results[1], L"This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very"); + EXPECT_EQ(results[2], L" is really here which says kennedy has been shot"); + } +}; + } -TEST_F(HighlighterTest, testGetSimpleHighlight) -{ +TEST_F(HighlighterTest, testGetSimpleHighlight) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestGetTextFragments -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestGetTextFragments { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - fixture->doSearching(L"Kennedy"); + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->doSearching(L"Kennedy"); - for (int32_t i = 0; i < fixture->hits->totalHits; ++i) - { - String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + for (int32_t i = 0; i < fixture->hits->totalHits; ++i) { + String text = fixture->searcher->doc(fixture->hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); - highlighter->setTextFragmenter(newLucene(20)); - Collection stringResults = highlighter->getBestFragments(tokenStream, text, 10); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + highlighter->setTextFragmenter(newLucene(20)); + Collection stringResults = highlighter->getBestFragments(tokenStream, text, 10); - tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - Collection fragmentResults = highlighter->getBestTextFragments(tokenStream, text, true, 10); + tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + Collection fragmentResults = highlighter->getBestTextFragments(tokenStream, text, true, 10); - EXPECT_EQ(fragmentResults.size(), stringResults.size()); - for (int32_t j = 0; j < stringResults.size(); ++j) - EXPECT_EQ(fragmentResults[j]->toString(), stringResults[j]); + EXPECT_EQ(fragmentResults.size(), stringResults.size()); + for (int32_t j = 0; j < stringResults.size(); ++j) { + EXPECT_EQ(fragmentResults[j]->toString(), stringResults[j]); } } - }; + } +}; + } -TEST_F(HighlighterTest, testGetTextFragments) -{ +TEST_F(HighlighterTest, testGetTextFragments) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestMaxSizeHighlight -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestMaxSizeHighlight { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - fixture->doSearching(L"meat"); + virtual ~HelperHighlightRunner() { + } - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); - highlighter->setMaxDocCharsToAnalyze(30); +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + fixture->doSearching(L"meat"); + + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(fixture->texts[0])); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + highlighter->setMaxDocCharsToAnalyze(30); + + highlighter->getBestFragment(tokenStream, fixture->texts[0]); + EXPECT_EQ(fixture->numHighlights, 0); + } +}; - highlighter->getBestFragment(tokenStream, fixture->texts[0]); - EXPECT_EQ(fixture->numHighlights, 0); - } - }; } -TEST_F(HighlighterTest, testMaxSizeHighlight) -{ +TEST_F(HighlighterTest, testMaxSizeHighlight) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestMaxSizeHighlightTruncates -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestMaxSizeHighlightTruncates { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - String goodWord = L"goodtoken"; - HashSet stopWords = HashSet::newInstance(); - stopWords.add(L"stoppedtoken"); + virtual ~HelperHighlightRunner() { + } - TermQueryPtr query = newLucene(newLucene(L"data", goodWord)); +public: + virtual void run(Collection expected) { + String goodWord = L"goodtoken"; + HashSet stopWords = HashSet::newInstance(); + stopWords.add(L"stoppedtoken"); - StringStream buffer; - buffer << goodWord; + TermQueryPtr query = newLucene(newLucene(L"data", goodWord)); - for (int32_t i = 0; i < 10000; ++i) - { - // only one stopword - buffer << L" " << *stopWords.begin(); - } - SimpleHTMLFormatterPtr fm = newLucene(); - HighlighterPtr hg = getHighlighter(query, L"data", newLucene(HighlighterTest::TEST_VERSION, stopWords)->tokenStream(L"data", newLucene(buffer.str())), fm); - - hg->setTextFragmenter(newLucene()); - hg->setMaxDocCharsToAnalyze(100); - String match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"data", buffer.str()); - EXPECT_TRUE((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); - - // add another tokenized word to the overall length - but set way beyond the length of text under consideration - // (after a large slug of stop words + whitespace) - buffer << L" " << goodWord; - match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"data", buffer.str()); - EXPECT_TRUE((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); + StringStream buffer; + buffer << goodWord; + + for (int32_t i = 0; i < 10000; ++i) { + // only one stopword + buffer << L" " << *stopWords.begin(); } - }; + SimpleHTMLFormatterPtr fm = newLucene(); + HighlighterPtr hg = getHighlighter(query, L"data", newLucene(HighlighterTest::TEST_VERSION, stopWords)->tokenStream(L"data", newLucene(buffer.str())), fm); + + hg->setTextFragmenter(newLucene()); + hg->setMaxDocCharsToAnalyze(100); + String match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"data", buffer.str()); + EXPECT_TRUE((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); + + // add another tokenized word to the overall length - but set way beyond the length of text under consideration + // (after a large slug of stop words + whitespace) + buffer << L" " << goodWord; + match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"data", buffer.str()); + EXPECT_TRUE((int32_t)match.length() < hg->getMaxDocCharsToAnalyze()); + } +}; + } -TEST_F(HighlighterTest, testMaxSizeHighlightTruncates) -{ +TEST_F(HighlighterTest, testMaxSizeHighlightTruncates) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestMaxSizeEndHighlight -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestMaxSizeEndHighlight { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - HashSet stopWords = HashSet::newInstance(); - stopWords.add(L"in"); - stopWords.add(L"it"); + virtual ~HelperHighlightRunner() { + } - TermQueryPtr query = newLucene(newLucene(L"text", L"searchterm")); +public: + virtual void run(Collection expected) { + HashSet stopWords = HashSet::newInstance(); + stopWords.add(L"in"); + stopWords.add(L"it"); - String text = L"this is a text with searchterm in it"; + TermQueryPtr query = newLucene(newLucene(L"text", L"searchterm")); - SimpleHTMLFormatterPtr fm = newLucene(); - HighlighterPtr hg = getHighlighter(query, L"text", newLucene(HighlighterTest::TEST_VERSION, stopWords)->tokenStream(L"text", newLucene(text)), fm); + String text = L"this is a text with searchterm in it"; + + SimpleHTMLFormatterPtr fm = newLucene(); + HighlighterPtr hg = getHighlighter(query, L"text", newLucene(HighlighterTest::TEST_VERSION, stopWords)->tokenStream(L"text", newLucene(text)), fm); + + hg->setTextFragmenter(newLucene()); + hg->setMaxDocCharsToAnalyze(36); + String match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"text", text); + EXPECT_TRUE(boost::ends_with(match, L"in it")); + } +}; - hg->setTextFragmenter(newLucene()); - hg->setMaxDocCharsToAnalyze(36); - String match = hg->getBestFragment(newLucene(HighlighterTest::TEST_VERSION, stopWords), L"text", text); - EXPECT_TRUE(boost::ends_with(match, L"in it")); - } - }; } -TEST_F(HighlighterTest, testMaxSizeEndHighlight) -{ +TEST_F(HighlighterTest, testMaxSizeEndHighlight) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestUnRewrittenQuery -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestUnRewrittenQuery { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - fixture->numHighlights = 0; - // test to show how rewritten query can still be used - fixture->searcher = newLucene(fixture->ramDir, true); - AnalyzerPtr analyzer = newLucene(HighlighterTest::TEST_VERSION); + virtual ~HelperHighlightRunner() { + } - QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, analyzer); - QueryPtr query = parser->parse(L"JF? or Kenned*"); - TopDocsPtr hits = fixture->searcher->search(query, FilterPtr(), 1000); +public: + virtual void run(Collection expected) { + fixture->numHighlights = 0; + // test to show how rewritten query can still be used + fixture->searcher = newLucene(fixture->ramDir, true); + AnalyzerPtr analyzer = newLucene(HighlighterTest::TEST_VERSION); - int32_t maxNumFragmentsRequired = 3; + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, analyzer); + QueryPtr query = parser->parse(L"JF? or Kenned*"); + TopDocsPtr hits = fixture->searcher->search(query, FilterPtr(), 1000); - for (int32_t i = 0; i < hits->totalHits; ++i) - { - String text = fixture->searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture), false); + int32_t maxNumFragmentsRequired = 3; - highlighter->setTextFragmenter(newLucene(40)); + for (int32_t i = 0; i < hits->totalHits; ++i) { + String text = fixture->searcher->doc(hits->scoreDocs[i]->doc)->get(HighlighterTest::FIELD_NAME); + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture), false); - highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"..."); - } + highlighter->setTextFragmenter(newLucene(40)); - // We expect to have zero highlights if the query is multi-terms and is not rewritten - EXPECT_EQ(fixture->numHighlights, 0); + highlighter->getBestFragments(tokenStream, text, maxNumFragmentsRequired, L"..."); } - }; + + // We expect to have zero highlights if the query is multi-terms and is not rewritten + EXPECT_EQ(fixture->numHighlights, 0); + } +}; + } -TEST_F(HighlighterTest, testUnRewrittenQuery) -{ +TEST_F(HighlighterTest, testUnRewrittenQuery) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestNoFragments -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestNoFragments { - virtual ~HelperHighlightRunner() - { - } +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - public: - virtual void run(Collection expected) - { - fixture->doSearching(L"AnInvalidQueryWhichShouldYieldNoResults"); - - for (int32_t i = 0; i < fixture->texts.size(); ++i) - { - String text = fixture->texts[i]; - TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); - HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); - String result = highlighter->getBestFragment(tokenStream, text); - EXPECT_TRUE(result.empty()); - } + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + fixture->doSearching(L"AnInvalidQueryWhichShouldYieldNoResults"); + + for (int32_t i = 0; i < fixture->texts.size(); ++i) { + String text = fixture->texts[i]; + TokenStreamPtr tokenStream = fixture->analyzer->tokenStream(HighlighterTest::FIELD_NAME, newLucene(text)); + HighlighterPtr highlighter = getHighlighter(fixture->query, HighlighterTest::FIELD_NAME, tokenStream, newLucene(fixture)); + String result = highlighter->getBestFragment(tokenStream, text); + EXPECT_TRUE(result.empty()); } - }; + } +}; + } -TEST_F(HighlighterTest, testNoFragments) -{ +TEST_F(HighlighterTest, testNoFragments) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestEncoding -{ - class NullScorer : public HighlighterScorer, public LuceneObject - { - public: - virtual ~NullScorer() - { - } +namespace TestEncoding { - public: - virtual void startFragment(const TextFragmentPtr& newFragment) - { - } +class NullScorer : public HighlighterScorer, public LuceneObject { +public: + virtual ~NullScorer() { + } - virtual double getTokenScore() - { - return 0.0; - } +public: + virtual void startFragment(const TextFragmentPtr& newFragment) { + } - virtual double getFragmentScore() - { - return 1.0; - } + virtual double getTokenScore() { + return 0.0; + } + + virtual double getFragmentScore() { + return 1.0; + } + + virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream) { + return TokenStreamPtr(); + } +}; - virtual TokenStreamPtr init(const TokenStreamPtr& tokenStream) - { - return TokenStreamPtr(); - } - }; } /// Demonstrates creation of an XHTML compliant doc using new encoding facilities. -TEST_F(HighlighterTest, testEncoding) -{ +TEST_F(HighlighterTest, testEncoding) { String rawDocContent = L"\"Smith & sons' prices < 3 and >4\" claims article"; // run the highlighter on the raw content (scorer does not score any tokens for @@ -2090,8 +1914,7 @@ TEST_F(HighlighterTest, testEncoding) EXPECT_EQ(encodedSnippet, L""Smith & sons' prices < 3 and >4" claims article"); } -TEST_F(HighlighterTest, testMultiSearcher) -{ +TEST_F(HighlighterTest, testMultiSearcher) { // setup index 1 RAMDirectoryPtr ramDir1 = newLucene(); IndexWriterPtr writer1 = newLucene(ramDir1, newLucene(TEST_VERSION), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -2115,9 +1938,9 @@ TEST_F(HighlighterTest, testMultiSearcher) IndexReaderPtr reader2 = IndexReader::open(ramDir2, true); Collection searchers = newCollection( - newLucene(ramDir1, true), - newLucene(ramDir2, true) - ); + newLucene(ramDir1, true), + newLucene(ramDir2, true) + ); MultiSearcherPtr multiSearcher = newLucene(searchers); QueryParserPtr parser = newLucene(TEST_VERSION, FIELD_NAME, newLucene(TEST_VERSION)); parser->setMultiTermRewriteMethod(MultiTermQuery::SCORING_BOOLEAN_QUERY_REWRITE()); @@ -2126,17 +1949,16 @@ TEST_F(HighlighterTest, testMultiSearcher) hits = multiSearcher->search(query, FilterPtr(), 1000); Collection expandedQueries = newCollection( - query->rewrite(reader1), - query->rewrite(reader2) - ); + query->rewrite(reader1), + query->rewrite(reader2) + ); query = query->combine(expandedQueries); // create an instance of the highlighter with the tags used to surround highlighted text HighlighterPtr highlighter = newLucene(newLucene(this), newLucene(query)); Collection results = Collection::newInstance(); - for (int32_t i = 0; i < hits->totalHits; ++i) - { + for (int32_t i = 0; i < hits->totalHits; ++i) { String text = multiSearcher->doc(hits->scoreDocs[i]->doc)->get(FIELD_NAME); TokenStreamPtr tokenStream = analyzer->tokenStream(FIELD_NAME, newLucene(text)); String highlightedText = highlighter->getBestFragment(tokenStream, text); @@ -2150,291 +1972,270 @@ TEST_F(HighlighterTest, testMultiSearcher) EXPECT_EQ(numHighlights, 2); } -namespace TestFieldSpecificHighlighting -{ - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } +namespace TestFieldSpecificHighlighting { + +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } - virtual ~HelperHighlightRunner() - { + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + String docMainText = L"fred is one of the people"; + QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, fixture->analyzer); + QueryPtr query = parser->parse(L"fred category:people"); + + // highlighting respects fieldnames used in query + + HighlighterScorerPtr fieldSpecificScorer; + if (mode == QUERY) { + fieldSpecificScorer = newLucene(query, HighlighterTest::FIELD_NAME); + } else if (mode == QUERY_TERM) { + fieldSpecificScorer = newLucene(query, L"contents"); } - public: - virtual void run(Collection expected) - { - String docMainText = L"fred is one of the people"; - QueryParserPtr parser = newLucene(HighlighterTest::TEST_VERSION, HighlighterTest::FIELD_NAME, fixture->analyzer); - QueryPtr query = parser->parse(L"fred category:people"); - - // highlighting respects fieldnames used in query - - HighlighterScorerPtr fieldSpecificScorer; - if (mode == QUERY) - fieldSpecificScorer = newLucene(query, HighlighterTest::FIELD_NAME); - else if (mode == QUERY_TERM) - fieldSpecificScorer = newLucene(query, L"contents"); - - HighlighterPtr fieldSpecificHighlighter = newLucene(newLucene(), fieldSpecificScorer); - fieldSpecificHighlighter->setTextFragmenter(newLucene()); - String result = fieldSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, docMainText); - EXPECT_EQ(result, L"fred is one of the people"); - - // highlighting does not respect fieldnames used in query - HighlighterScorerPtr fieldInSpecificScorer; - if (mode == QUERY) - fieldInSpecificScorer = newLucene(query, L""); - else if (mode == QUERY_TERM) - fieldInSpecificScorer = newLucene(query); - - HighlighterPtr fieldInSpecificHighlighter = newLucene(newLucene(), fieldInSpecificScorer); - fieldInSpecificHighlighter->setTextFragmenter(newLucene()); - result = fieldInSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, docMainText); - EXPECT_EQ(result, L"fred is one of the people"); - - fixture->reader->close(); + HighlighterPtr fieldSpecificHighlighter = newLucene(newLucene(), fieldSpecificScorer); + fieldSpecificHighlighter->setTextFragmenter(newLucene()); + String result = fieldSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, docMainText); + EXPECT_EQ(result, L"fred is one of the people"); + + // highlighting does not respect fieldnames used in query + HighlighterScorerPtr fieldInSpecificScorer; + if (mode == QUERY) { + fieldInSpecificScorer = newLucene(query, L""); + } else if (mode == QUERY_TERM) { + fieldInSpecificScorer = newLucene(query); } - }; + + HighlighterPtr fieldInSpecificHighlighter = newLucene(newLucene(), fieldInSpecificScorer); + fieldInSpecificHighlighter->setTextFragmenter(newLucene()); + result = fieldInSpecificHighlighter->getBestFragment(fixture->analyzer, HighlighterTest::FIELD_NAME, docMainText); + EXPECT_EQ(result, L"fred is one of the people"); + + fixture->reader->close(); + } +}; + } -TEST_F(HighlighterTest, testFieldSpecificHighlighting) -{ +TEST_F(HighlighterTest, testFieldSpecificHighlighting) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -namespace TestOverlapAnalyzer2 -{ - class TS2 : public TokenStream - { - public: - TS2() - { - termAtt = addAttribute(); - posIncrAtt = addAttribute(); - offsetAtt = addAttribute(); - lst = Collection::newInstance(); - TokenPtr t = createToken(L"hi", 0, 2); - t->setPositionIncrement(1); - lst.add(t); - t = createToken(L"hispeed", 0, 8); - t->setPositionIncrement(1); - lst.add(t); - t = createToken(L"speed", 3, 8); - t->setPositionIncrement(0); - lst.add(t); - t = createToken(L"10", 8, 10); - t->setPositionIncrement(1); - lst.add(t); - t = createToken(L"foo", 11, 14); - t->setPositionIncrement(1); - lst.add(t); - tokenPos = 0; - } +namespace TestOverlapAnalyzer2 { - virtual ~TS2() - { - } +class TS2 : public TokenStream { +public: + TS2() { + termAtt = addAttribute(); + posIncrAtt = addAttribute(); + offsetAtt = addAttribute(); + lst = Collection::newInstance(); + TokenPtr t = createToken(L"hi", 0, 2); + t->setPositionIncrement(1); + lst.add(t); + t = createToken(L"hispeed", 0, 8); + t->setPositionIncrement(1); + lst.add(t); + t = createToken(L"speed", 3, 8); + t->setPositionIncrement(0); + lst.add(t); + t = createToken(L"10", 8, 10); + t->setPositionIncrement(1); + lst.add(t); + t = createToken(L"foo", 11, 14); + t->setPositionIncrement(1); + lst.add(t); + tokenPos = 0; + } - protected: - Collection lst; - int32_t tokenPos; - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncrAtt; - OffsetAttributePtr offsetAtt; - - public: - virtual bool incrementToken() - { - if (tokenPos < (int32_t)lst.size()) - { - TokenPtr token = lst[tokenPos++]; - clearAttributes(); - termAtt->setTermBuffer(token->term()); - posIncrAtt->setPositionIncrement(token->getPositionIncrement()); - offsetAtt->setOffset(token->startOffset(), token->endOffset()); - return true; - } - return false; - } + virtual ~TS2() { + } - protected: - TokenPtr createToken(const String& term, int32_t start, int32_t offset) - { - TokenPtr token = newLucene(start, offset); - token->setTermBuffer(term); - return token; - } - }; - - /// same token-stream as above, but the bigger token comes first this time - class TS2a : public TokenStream - { - public: - TS2a() - { - termAtt = addAttribute(); - posIncrAtt = addAttribute(); - offsetAtt = addAttribute(); - lst = Collection::newInstance(); - TokenPtr t = createToken(L"hispeed", 0, 8); - t->setPositionIncrement(1); - lst.add(t); - t = createToken(L"hi", 0, 2); - t->setPositionIncrement(0); - lst.add(t); - t = createToken(L"speed", 3, 8); - t->setPositionIncrement(1); - lst.add(t); - t = createToken(L"10", 8, 10); - t->setPositionIncrement(1); - lst.add(t); - t = createToken(L"foo", 11, 14); - t->setPositionIncrement(1); - lst.add(t); - tokenPos = 0; - } +protected: + Collection lst; + int32_t tokenPos; + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncrAtt; + OffsetAttributePtr offsetAtt; - virtual ~TS2a() - { - } +public: + virtual bool incrementToken() { + if (tokenPos < (int32_t)lst.size()) { + TokenPtr token = lst[tokenPos++]; + clearAttributes(); + termAtt->setTermBuffer(token->term()); + posIncrAtt->setPositionIncrement(token->getPositionIncrement()); + offsetAtt->setOffset(token->startOffset(), token->endOffset()); + return true; + } + return false; + } - protected: - Collection lst; - int32_t tokenPos; - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncrAtt; - OffsetAttributePtr offsetAtt; - - public: - virtual bool incrementToken() - { - if (tokenPos < (int32_t)lst.size()) - { - TokenPtr token = lst[tokenPos++]; - clearAttributes(); - termAtt->setTermBuffer(token->term()); - posIncrAtt->setPositionIncrement(token->getPositionIncrement()); - offsetAtt->setOffset(token->startOffset(), token->endOffset()); - return true; - } - return false; - } +protected: + TokenPtr createToken(const String& term, int32_t start, int32_t offset) { + TokenPtr token = newLucene(start, offset); + token->setTermBuffer(term); + return token; + } +}; - protected: - TokenPtr createToken(const String& term, int32_t start, int32_t offset) - { - TokenPtr token = newLucene(start, offset); - token->setTermBuffer(term); - return token; - } - }; +/// same token-stream as above, but the bigger token comes first this time +class TS2a : public TokenStream { +public: + TS2a() { + termAtt = addAttribute(); + posIncrAtt = addAttribute(); + offsetAtt = addAttribute(); + lst = Collection::newInstance(); + TokenPtr t = createToken(L"hispeed", 0, 8); + t->setPositionIncrement(1); + lst.add(t); + t = createToken(L"hi", 0, 2); + t->setPositionIncrement(0); + lst.add(t); + t = createToken(L"speed", 3, 8); + t->setPositionIncrement(1); + lst.add(t); + t = createToken(L"10", 8, 10); + t->setPositionIncrement(1); + lst.add(t); + t = createToken(L"foo", 11, 14); + t->setPositionIncrement(1); + lst.add(t); + tokenPos = 0; + } - class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner - { - public: - HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) - { - } + virtual ~TS2a() { + } - virtual ~HelperHighlightRunner() - { - } +protected: + Collection lst; + int32_t tokenPos; + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncrAtt; + OffsetAttributePtr offsetAtt; - public: - virtual void run(Collection expected) - { - String s = L"Hi-Speed10 foo"; - - QueryPtr query; - HighlighterPtr highlighter; - String result; - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"foo"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"10"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"speed"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); - highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - // same tests, just put the bigger overlapping token first - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"foo"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"10"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"speed"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - - query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); - highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); - result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); - EXPECT_EQ(L"Hi-Speed10 foo", result); - } +public: + virtual bool incrementToken() { + if (tokenPos < (int32_t)lst.size()) { + TokenPtr token = lst[tokenPos++]; + clearAttributes(); + termAtt->setTermBuffer(token->term()); + posIncrAtt->setPositionIncrement(token->getPositionIncrement()); + offsetAtt->setOffset(token->startOffset(), token->endOffset()); + return true; + } + return false; + } - TokenStreamPtr getTS2() - { - return newLucene(); - } +protected: + TokenPtr createToken(const String& term, int32_t start, int32_t offset) { + TokenPtr token = newLucene(start, offset); + token->setTermBuffer(term); + return token; + } +}; + +class HelperHighlightRunner : public HighlighterTestNS::TestHighlightRunner { +public: + HelperHighlightRunner(HighlighterTest* fixture) : HighlighterTestNS::TestHighlightRunner(fixture) { + } + + virtual ~HelperHighlightRunner() { + } + +public: + virtual void run(Collection expected) { + String s = L"Hi-Speed10 foo"; + + QueryPtr query; + HighlighterPtr highlighter; + String result; + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"foo"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"10"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"speed"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); + highlighter = getHighlighter(query, L"text", getTS2(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + // same tests, just put the bigger overlapping token first + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"foo"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"10"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"speed"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hispeed"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + + query = newLucene(HighlighterTest::TEST_VERSION, L"text", newLucene())->parse(L"hi speed"); + highlighter = getHighlighter(query, L"text", getTS2a(), newLucene(fixture)); + result = highlighter->getBestFragments(getTS2a(), s, 3, L"..."); + EXPECT_EQ(L"Hi-Speed10 foo", result); + } + + TokenStreamPtr getTS2() { + return newLucene(); + } + + TokenStreamPtr getTS2a() { + return newLucene(); + } +}; - TokenStreamPtr getTS2a() - { - return newLucene(); - } - }; } -TEST_F(HighlighterTest, testOverlapAnalyzer2) -{ +TEST_F(HighlighterTest, testOverlapAnalyzer2) { HighlighterTestNS::TestHighlightRunnerPtr helper = newLucene(this); helper->start(); } -TEST_F(HighlighterTest, testWeightedTermsWithDeletes) -{ +TEST_F(HighlighterTest, testWeightedTermsWithDeletes) { makeIndex(); deleteDocument(); searchIndex(); diff --git a/src/test/contrib/memory/MemoryIndexTest.cpp b/src/test/contrib/memory/MemoryIndexTest.cpp index d2c4b229..9d4da606 100644 --- a/src/test/contrib/memory/MemoryIndexTest.cpp +++ b/src/test/contrib/memory/MemoryIndexTest.cpp @@ -29,11 +29,9 @@ using namespace Lucene; /// Verifies that Lucene MemoryIndex and RAMDirectory have the same behaviour, /// returning the same results for queries on some randomish indexes. -class MemoryIndexTest : public BaseTokenStreamFixture -{ +class MemoryIndexTest : public BaseTokenStreamFixture { public: - MemoryIndexTest() - { + MemoryIndexTest() { fileDir = FileUtils::joinPath(getTestDir(), L"memory"); queries = HashSet::newInstance(); HashSet test1 = readQueries(L"testqueries.txt"); @@ -70,8 +68,7 @@ class MemoryIndexTest : public BaseTokenStreamFixture TEST_TERMS.add(L"Copyright"); } - virtual ~MemoryIndexTest() - { + virtual ~MemoryIndexTest() { } protected: @@ -85,16 +82,15 @@ class MemoryIndexTest : public BaseTokenStreamFixture public: /// read a set of queries from a resource file - HashSet readQueries(const String& resource) - { + HashSet readQueries(const String& resource) { HashSet queries = HashSet::newInstance(); BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(fileDir, resource))); String line; - while (reader->readLine(line)) - { + while (reader->readLine(line)) { boost::trim(line); - if (!line.empty() && !boost::starts_with(line, L"#") && !boost::starts_with(line, L"//")) + if (!line.empty() && !boost::starts_with(line, L"#") && !boost::starts_with(line, L"//")) { queries.add(line); + } } reader->close(); @@ -102,20 +98,21 @@ class MemoryIndexTest : public BaseTokenStreamFixture } /// Build a randomish document for both RAMDirectory and MemoryIndex, and run all the queries against it. - void checkAgainstRAMDirectory() - { + void checkAgainstRAMDirectory() { StringStream fooField; StringStream termField; // add up to 250 terms to field "foo" int32_t fieldCount = random->nextInt(250) + 1; - for (int32_t i = 0; i < fieldCount; ++i) + for (int32_t i = 0; i < fieldCount; ++i) { fooField << L" " << randomTerm(); + } // add up to 250 terms to field "foo" int32_t termCount = random->nextInt(250) + 1; - for (int32_t i = 0; i < termCount; ++i) + for (int32_t i = 0; i < termCount; ++i) { termField << L" " << randomTerm(); + } RAMDirectoryPtr ramdir = newLucene(); AnalyzerPtr analyzer = randomAnalyzer(); @@ -134,85 +131,74 @@ class MemoryIndexTest : public BaseTokenStreamFixture checkAllQueries(memory, ramdir, analyzer); } - void checkAllQueries(const MemoryIndexPtr& memory, const RAMDirectoryPtr& ramdir, const AnalyzerPtr& analyzer) - { + void checkAllQueries(const MemoryIndexPtr& memory, const RAMDirectoryPtr& ramdir, const AnalyzerPtr& analyzer) { IndexSearcherPtr ram = newLucene(ramdir); IndexSearcherPtr mem = memory->createSearcher(); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"foo", analyzer); - for (HashSet::iterator query = queries.begin(); query != queries.end(); ++query) - { + for (HashSet::iterator query = queries.begin(); query != queries.end(); ++query) { TopDocsPtr ramDocs = ram->search(qp->parse(*query), 1); TopDocsPtr memDocs = mem->search(qp->parse(*query), 1); EXPECT_EQ(ramDocs->totalHits, memDocs->totalHits); } } - AnalyzerPtr randomAnalyzer() - { - switch (random->nextInt(3)) - { - case 0: - return newLucene(); - case 1: - return newLucene(LuceneVersion::LUCENE_CURRENT); - default: - return newLucene(LuceneVersion::LUCENE_CURRENT); + AnalyzerPtr randomAnalyzer() { + switch (random->nextInt(3)) { + case 0: + return newLucene(); + case 1: + return newLucene(LuceneVersion::LUCENE_CURRENT); + default: + return newLucene(LuceneVersion::LUCENE_CURRENT); } } /// half of the time, returns a random term from TEST_TERMS. /// the other half of the time, returns a random unicode string. - String randomTerm() - { - if (random->nextInt() % 2 == 1) - { + String randomTerm() { + if (random->nextInt() % 2 == 1) { // return a random TEST_TERM return TEST_TERMS[random->nextInt(TEST_TERMS.size())]; - } - else - { + } else { // return a random unicode term return randomString(); } } /// Return a random unicode term, like StressIndexingTest. - String randomString() - { + String randomString() { int32_t end = random->nextInt(20); - if (buffer.size() < 1 + end) + if (buffer.size() < 1 + end) { buffer.resize((int32_t)((double)(1 + end) * 1.25)); + } - for (int32_t i = 0; i < end; ++i) - { + for (int32_t i = 0; i < end; ++i) { int32_t t = random->nextInt(5); - if (t == 0 && i < end - 1) - { - #ifdef LPP_UNICODE_CHAR_SIZE_2 + if (t == 0 && i < end - 1) { +#ifdef LPP_UNICODE_CHAR_SIZE_2 // Make a surrogate pair // High surrogate buffer[i++] = (wchar_t)nextInt(0xd800, 0xdc00); // Low surrogate buffer[i] = (wchar_t)nextInt(0xdc00, 0xe000); - #else +#else buffer[i] = (wchar_t)nextInt(0xdc00, 0xe000); - #endif - } - else if (t <= 1) +#endif + } else if (t <= 1) { buffer[i] = (wchar_t)nextInt(0x01, 0x80); - else if (t == 2) + } else if (t == 2) { buffer[i] = (wchar_t)nextInt(0x80, 0x800); - else if (t == 3) + } else if (t == 3) { buffer[i] = (wchar_t)nextInt(0x800, 0xd800); - else if (t == 4) + } else if (t == 4) { buffer[i] = (wchar_t)nextInt(0xe000, 0xfff0); + } } return String(buffer.get(), end); } /// start is inclusive and end is exclusive - int32_t nextInt(int32_t start, int32_t end) - { + int32_t nextInt(int32_t start, int32_t end) { return start + random->nextInt(end - start); } }; @@ -220,8 +206,8 @@ class MemoryIndexTest : public BaseTokenStreamFixture const int32_t MemoryIndexTest::ITERATIONS = 100; /// runs random tests, up to ITERATIONS times. -TEST_F(MemoryIndexTest, testRandomQueries) -{ - for (int32_t i = 0; i < ITERATIONS; ++i) +TEST_F(MemoryIndexTest, testRandomQueries) { + for (int32_t i = 0; i < ITERATIONS; ++i) { checkAgainstRAMDirectory(); + } } diff --git a/src/test/contrib/snowball/SnowballTest.cpp b/src/test/contrib/snowball/SnowballTest.cpp index 0d5cd263..1a79f26b 100644 --- a/src/test/contrib/snowball/SnowballTest.cpp +++ b/src/test/contrib/snowball/SnowballTest.cpp @@ -13,20 +13,17 @@ using namespace Lucene; typedef BaseTokenStreamFixture SnowballTest; -TEST_F(SnowballTest, testEnglish) -{ +TEST_F(SnowballTest, testEnglish) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, L"english"); checkAnalyzesTo(a, L"he abhorred accents", newCollection(L"he", L"abhor", L"accent")); } -TEST_F(SnowballTest, testStopwords) -{ +TEST_F(SnowballTest, testStopwords) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, L"english", StopAnalyzer::ENGLISH_STOP_WORDS_SET()); checkAnalyzesTo(a, L"the quick brown fox jumped", newCollection(L"quick", L"brown", L"fox", L"jump")); } -TEST_F(SnowballTest, testReusableTokenStream) -{ +TEST_F(SnowballTest, testReusableTokenStream) { AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT, L"english"); checkAnalyzesToReuse(a, L"he abhorred accents", newCollection(L"he", L"abhor", L"accent")); diff --git a/src/test/document/BinaryDocumentTest.cpp b/src/test/document/BinaryDocumentTest.cpp index 66648dde..b5776e5f 100644 --- a/src/test/document/BinaryDocumentTest.cpp +++ b/src/test/document/BinaryDocumentTest.cpp @@ -21,8 +21,7 @@ typedef LuceneTestFixture BinaryDocumentTest; static String binaryValStored = L"this text will be stored as a byte array in the index"; static String binaryValCompressed = L"this text will be also stored and compressed as a byte array in the index"; -TEST_F(BinaryDocumentTest, testBinaryFieldInIndex) -{ +TEST_F(BinaryDocumentTest, testBinaryFieldInIndex) { ByteArray binaryStored = ByteArray::newInstance(binaryValStored.length() * sizeof(wchar_t)); std::wcsncpy((wchar_t*)binaryStored.get(), binaryValStored.c_str(), binaryValStored.length()); @@ -30,12 +29,9 @@ TEST_F(BinaryDocumentTest, testBinaryFieldInIndex) FieldablePtr stringFldStored = newLucene(L"stringStored", binaryValStored, Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_NO); // binary fields with store off are not allowed - try - { + try { newLucene(L"fail", binaryStored, Field::STORE_NO); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } @@ -75,8 +71,7 @@ TEST_F(BinaryDocumentTest, testBinaryFieldInIndex) dir->close(); } -TEST_F(BinaryDocumentTest, testCompressionTools) -{ +TEST_F(BinaryDocumentTest, testCompressionTools) { ByteArray binaryCompressed = ByteArray::newInstance(binaryValCompressed.length() * sizeof(wchar_t)); std::wcsncpy((wchar_t*)binaryCompressed.get(), binaryValCompressed.c_str(), binaryValCompressed.length()); diff --git a/src/test/document/DateFieldTest.cpp b/src/test/document/DateFieldTest.cpp index 663d289d..7c35f6e9 100644 --- a/src/test/document/DateFieldTest.cpp +++ b/src/test/document/DateFieldTest.cpp @@ -12,27 +12,22 @@ using namespace Lucene; typedef LuceneTestFixture DateFieldTest; -TEST_F(DateFieldTest, testMinDate) -{ +TEST_F(DateFieldTest, testMinDate) { EXPECT_EQ(DateField::MIN_DATE_STRING(), L"000000000"); } -TEST_F(DateFieldTest, testMaxDate) -{ +TEST_F(DateFieldTest, testMaxDate) { EXPECT_EQ(DateField::MAX_DATE_STRING(), L"zzzzzzzzz"); } -TEST_F(DateFieldTest, testDateToString) -{ +TEST_F(DateFieldTest, testDateToString) { EXPECT_EQ(DateField::dateToString(boost::posix_time::ptime(boost::gregorian::date(2010, boost::gregorian::Jan, 14))), L"0g4erxmo0"); } -TEST_F(DateFieldTest, testTimeToString) -{ +TEST_F(DateFieldTest, testTimeToString) { EXPECT_EQ(DateField::timeToString(1263427200000LL), L"0g4erxmo0"); } -TEST_F(DateFieldTest, testStringToTime) -{ +TEST_F(DateFieldTest, testStringToTime) { EXPECT_EQ(DateField::stringToTime(L"0g4erxmo0"), 1263427200000LL); } diff --git a/src/test/document/DateToolsTest.cpp b/src/test/document/DateToolsTest.cpp index cb6ccdab..59612ad3 100644 --- a/src/test/document/DateToolsTest.cpp +++ b/src/test/document/DateToolsTest.cpp @@ -16,8 +16,7 @@ using namespace boost::gregorian; typedef LuceneTestFixture DateToolsTest; -TEST_F(DateToolsTest, testDateToString) -{ +TEST_F(DateToolsTest, testDateToString) { EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_YEAR), L"2010"); EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_MONTH), L"201001"); EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14)), DateTools::RESOLUTION_DAY), L"20100114"); @@ -27,8 +26,7 @@ TEST_F(DateToolsTest, testDateToString) EXPECT_EQ(DateTools::dateToString(ptime(date(2010, Jan, 14), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MILLISECOND), L"20100114034105123"); } -TEST_F(DateToolsTest, testTimeToString) -{ +TEST_F(DateToolsTest, testTimeToString) { EXPECT_EQ(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_YEAR), L"2010"); EXPECT_EQ(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_MONTH), L"201001"); EXPECT_EQ(DateTools::timeToString(1263427200000LL, DateTools::RESOLUTION_DAY), L"20100114"); @@ -38,8 +36,7 @@ TEST_F(DateToolsTest, testTimeToString) EXPECT_EQ(DateTools::timeToString(1263440465123LL, DateTools::RESOLUTION_MILLISECOND), L"20100114034105123"); } -TEST_F(DateToolsTest, testStringToTime) -{ +TEST_F(DateToolsTest, testStringToTime) { EXPECT_EQ(DateTools::stringToTime(L"2010"), 1262304000000LL); EXPECT_EQ(DateTools::stringToTime(L"201001"), 1262304000000LL); EXPECT_EQ(DateTools::stringToTime(L"20100114"), 1263427200000LL); @@ -49,8 +46,7 @@ TEST_F(DateToolsTest, testStringToTime) EXPECT_EQ(DateTools::stringToTime(L"20100114034105123"), 1263440465123LL); } -TEST_F(DateToolsTest, testDateRound) -{ +TEST_F(DateToolsTest, testDateRound) { EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_YEAR), ptime(date(2010, Jan, 1))); EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MONTH), ptime(date(2010, Feb, 1))); EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_DAY), ptime(date(2010, Feb, 16))); @@ -60,8 +56,7 @@ TEST_F(DateToolsTest, testDateRound) EXPECT_EQ(DateTools::round(ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123)), DateTools::RESOLUTION_MILLISECOND), ptime(date(2010, Feb, 16), hours(3) + minutes(41) + seconds(5) + milliseconds(123))); } -TEST_F(DateToolsTest, testParseDateGB) -{ +TEST_F(DateToolsTest, testParseDateGB) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); EXPECT_EQ(DateTools::parseDate(L"01122005"), ptime(date(2005, 12, 01))); EXPECT_EQ(DateTools::parseDate(L"011205"), ptime(date(2005, 12, 01))); @@ -75,8 +70,7 @@ TEST_F(DateToolsTest, testParseDateGB) EXPECT_EQ(DateTools::parseDate(L"01/Jan/2005"), ptime(date(2005, 01, 01))); } -TEST_F(DateToolsTest, testParseDateUS) -{ +TEST_F(DateToolsTest, testParseDateUS) { DateTools::setDateOrder(DateTools::DATEORDER_MDY); EXPECT_EQ(DateTools::parseDate(L"12012005"), ptime(date(2005, 12, 01))); EXPECT_EQ(DateTools::parseDate(L"120105"), ptime(date(2005, 12, 01))); @@ -90,21 +84,16 @@ TEST_F(DateToolsTest, testParseDateUS) EXPECT_EQ(DateTools::parseDate(L"Jan/01/2005"), ptime(date(2005, 01, 01))); } -TEST_F(DateToolsTest, testParseDateLocale) -{ +TEST_F(DateToolsTest, testParseDateLocale) { bool hasThisLocale = false; - try - { + try { std::locale("en_GB.UTF-8"); hasThisLocale = true; - } - catch (...) - { + } catch (...) { } - if (hasThisLocale) - { + if (hasThisLocale) { DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); EXPECT_EQ(DateTools::parseDate(L"01122005", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); EXPECT_EQ(DateTools::parseDate(L"011205", std::locale("en_GB.UTF-8")), ptime(date(2005, 12, 01))); @@ -118,18 +107,14 @@ TEST_F(DateToolsTest, testParseDateLocale) EXPECT_EQ(DateTools::parseDate(L"01/Jan/2005", std::locale("en_GB.UTF-8")), ptime(date(2005, 01, 01))); } - try - { + try { std::locale("en_US.UTF-8"); hasThisLocale = true; - } - catch (...) - { + } catch (...) { hasThisLocale = false; } - if (hasThisLocale) - { + if (hasThisLocale) { DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); EXPECT_EQ(DateTools::parseDate(L"12012005", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); EXPECT_EQ(DateTools::parseDate(L"120105", std::locale("en_US.UTF-8")), ptime(date(2005, 12, 01))); @@ -144,8 +129,7 @@ TEST_F(DateToolsTest, testParseDateLocale) } } -TEST_F(DateToolsTest, testParseDateSeparator) -{ +TEST_F(DateToolsTest, testParseDateSeparator) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); EXPECT_EQ(DateTools::parseDate(L"01122005"), ptime(date(2005, 12, 01))); EXPECT_EQ(DateTools::parseDate(L"011205"), ptime(date(2005, 12, 01))); diff --git a/src/test/document/DocumentTest.cpp b/src/test/document/DocumentTest.cpp index b31b1d19..274ed72e 100644 --- a/src/test/document/DocumentTest.cpp +++ b/src/test/document/DocumentTest.cpp @@ -24,8 +24,7 @@ typedef LuceneTestFixture DocumentTest; static String binaryVal = L"this text will be stored as a byte array in the index"; static String binaryVal2 = L"this text will be also stored as a byte array in the index"; -static DocumentPtr makeDocumentWithFields() -{ +static DocumentPtr makeDocumentWithFields() { DocumentPtr doc = newLucene(); doc->add(newLucene(L"keyword", L"test1", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"keyword", L"test2", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -38,8 +37,7 @@ static DocumentPtr makeDocumentWithFields() return doc; } -static void checkDocument(const DocumentPtr& doc, bool fromIndex) -{ +static void checkDocument(const DocumentPtr& doc, bool fromIndex) { Collection keywordFieldValues = doc->getValues(L"keyword"); Collection textFieldValues = doc->getValues(L"text"); Collection unindexedFieldValues = doc->getValues(L"unindexed"); @@ -49,8 +47,9 @@ static void checkDocument(const DocumentPtr& doc, bool fromIndex) EXPECT_EQ(textFieldValues.size(), 2); EXPECT_EQ(unindexedFieldValues.size(), 2); // this test cannot work for documents retrieved from the index since unstored fields will obviously not be returned - if (!fromIndex) + if (!fromIndex) { EXPECT_EQ(unstoredFieldValues.size(), 2); + } EXPECT_EQ(keywordFieldValues[0], L"test1"); EXPECT_EQ(keywordFieldValues[1], L"test2"); @@ -59,15 +58,13 @@ static void checkDocument(const DocumentPtr& doc, bool fromIndex) EXPECT_EQ(unindexedFieldValues[0], L"test1"); EXPECT_EQ(unindexedFieldValues[1], L"test2"); // this test cannot work for documents retrieved from the index since unstored fields will obviously not be returned - if (!fromIndex) - { + if (!fromIndex) { EXPECT_EQ(unstoredFieldValues[0], L"test1"); EXPECT_EQ(unstoredFieldValues[1], L"test2"); } } -TEST_F(DocumentTest, testBinaryField) -{ +TEST_F(DocumentTest, testBinaryField) { DocumentPtr doc = newLucene(); FieldablePtr stringFld = newLucene(L"string", binaryVal, Field::STORE_YES, Field::INDEX_NO); @@ -123,8 +120,7 @@ TEST_F(DocumentTest, testBinaryField) } /// Tests {@link Document#removeField(String)} method for a brand new Document that has not been indexed yet. -TEST_F(DocumentTest, testRemoveForNewDocument) -{ +TEST_F(DocumentTest, testRemoveForNewDocument) { DocumentPtr doc = makeDocumentWithFields(); EXPECT_EQ(8, doc->getFields().size()); doc->removeFields(L"keyword"); @@ -148,41 +144,32 @@ TEST_F(DocumentTest, testRemoveForNewDocument) EXPECT_EQ(0, doc->getFields().size()); } -TEST_F(DocumentTest, testConstructorExceptions) -{ +TEST_F(DocumentTest, testConstructorExceptions) { newLucene(L"name", L"value", Field::STORE_YES, Field::INDEX_NO); // ok newLucene(L"name", L"value", Field::STORE_NO, Field::INDEX_NOT_ANALYZED); // ok - try - { + try { newLucene(L"name", L"value", Field::STORE_NO, Field::INDEX_NO); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } newLucene(L"name", L"value", Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_NO); // ok - try - { + try { newLucene(L"name", L"value", Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_YES); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } /// Tests {@link Document#getValues(String)} method for a brand new Document that has not been indexed yet. -TEST_F(DocumentTest, testGetValuesForNewDocument) -{ +TEST_F(DocumentTest, testGetValuesForNewDocument) { checkDocument(makeDocumentWithFields(), false); } /// Tests {@link Document#getValues(String)} method for a Document retrieved from an index. -TEST_F(DocumentTest, testGetValuesForIndexedDocument) -{ +TEST_F(DocumentTest, testGetValuesForIndexedDocument) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); writer->addDocument(makeDocumentWithFields()); @@ -201,8 +188,7 @@ TEST_F(DocumentTest, testGetValuesForIndexedDocument) searcher->close(); } -TEST_F(DocumentTest, testFieldSetValue) -{ +TEST_F(DocumentTest, testFieldSetValue) { FieldPtr field = newLucene(L"id", L"id1", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); DocumentPtr doc = newLucene(); doc->add(field); @@ -225,44 +211,37 @@ TEST_F(DocumentTest, testFieldSetValue) Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(3, hits.size()); int32_t result = 0; - for (int32_t i = 0; i < 3; ++i) - { + for (int32_t i = 0; i < 3; ++i) { DocumentPtr doc2 = searcher->doc(hits[i]->doc); FieldPtr f = doc2->getField(L"id"); - if (f->stringValue() == L"id1") + if (f->stringValue() == L"id1") { result |= 1; - else if (f->stringValue() == L"id2") + } else if (f->stringValue() == L"id2") { result |= 2; - else if (f->stringValue() == L"id3") + } else if (f->stringValue() == L"id3") { result |= 4; - else + } else { FAIL() << "unexpected id field"; + } } searcher->close(); dir->close(); EXPECT_EQ(7, result); } -TEST_F(DocumentTest, testFieldSetValueChangeBinary) -{ +TEST_F(DocumentTest, testFieldSetValueChangeBinary) { FieldPtr field1 = newLucene(L"field1", ByteArray::newInstance(0), Field::STORE_YES); FieldPtr field2 = newLucene(L"field2", L"", Field::STORE_YES, Field::INDEX_ANALYZED); - try - { + try { field1->setValue(L"abc"); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } - try - { + try { field2->setValue(ByteArray::newInstance(0)); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } diff --git a/src/test/document/NumberToolsTest.cpp b/src/test/document/NumberToolsTest.cpp index 901d0f38..c4190c12 100644 --- a/src/test/document/NumberToolsTest.cpp +++ b/src/test/document/NumberToolsTest.cpp @@ -12,23 +12,19 @@ using namespace Lucene; typedef LuceneTestFixture NumberToolsTest; -TEST_F(NumberToolsTest, testMinValue) -{ +TEST_F(NumberToolsTest, testMinValue) { EXPECT_EQ(NumberTools::MIN_STRING_VALUE(), L"-0000000000000"); } -TEST_F(NumberToolsTest, testMaxValue) -{ +TEST_F(NumberToolsTest, testMaxValue) { EXPECT_EQ(NumberTools::MAX_STRING_VALUE(), L"01y2p0ij32e8e7"); } -TEST_F(NumberToolsTest, testValueSize) -{ +TEST_F(NumberToolsTest, testValueSize) { EXPECT_EQ(NumberTools::STR_SIZE(), 14); } -TEST_F(NumberToolsTest, testLongToString) -{ +TEST_F(NumberToolsTest, testLongToString) { EXPECT_EQ(NumberTools::longToString(LLONG_MIN), L"-0000000000000"); EXPECT_EQ(NumberTools::longToString(LLONG_MAX), L"01y2p0ij32e8e7"); EXPECT_EQ(NumberTools::longToString(1LL), L"00000000000001"); @@ -39,8 +35,7 @@ TEST_F(NumberToolsTest, testLongToString) EXPECT_EQ(NumberTools::longToString(23232143543434234LL), L"0006cr3vell8my"); } -TEST_F(NumberToolsTest, testStringToLong) -{ +TEST_F(NumberToolsTest, testStringToLong) { EXPECT_EQ(NumberTools::stringToLong(L"-0000000000000"), LLONG_MIN); EXPECT_EQ(NumberTools::stringToLong(L"01y2p0ij32e8e7"), LLONG_MAX); EXPECT_EQ(NumberTools::stringToLong(L"00000000000001"), 1LL); @@ -50,21 +45,15 @@ TEST_F(NumberToolsTest, testStringToLong) EXPECT_EQ(NumberTools::stringToLong(L"00009ps7uuwdlz"), 986778657657575LL); EXPECT_EQ(NumberTools::stringToLong(L"0006cr3vell8my"), 23232143543434234LL); - try - { + try { NumberTools::stringToLong(L"32132"); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); // wrong length } - try - { + try { NumberTools::stringToLong(L"9006cr3vell8my"); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); // wrong prefix } } diff --git a/src/test/include/BaseTestRangeFilterFixture.h b/src/test/include/BaseTestRangeFilterFixture.h index fc0d0367..499b1a1d 100644 --- a/src/test/include/BaseTestRangeFilterFixture.h +++ b/src/test/include/BaseTestRangeFilterFixture.h @@ -10,49 +10,47 @@ #include "LuceneTestFixture.h" #include "LuceneObject.h" -namespace Lucene -{ - DECLARE_SHARED_PTR(TestIndex) - - /// Collation interacts badly with hyphens -- collation produces different ordering than Unicode code-point ordering, - /// so two indexes are created: - /// one which can't have negative random integers, for testing collated ranges, and the other which can have negative - /// random integers, for all other tests. - class TestIndex : public LuceneObject - { - public: - TestIndex(int32_t minR, int32_t maxR, bool allowNegativeRandomInts); - virtual ~TestIndex(); - - LUCENE_CLASS(TestIndex); - - public: - int32_t maxR; - int32_t minR; - bool allowNegativeRandomInts; - RAMDirectoryPtr index; - }; - - class BaseTestRangeFilterFixture : public LuceneTestFixture - { - public: - BaseTestRangeFilterFixture(); - virtual ~BaseTestRangeFilterFixture(); - - public: - TestIndexPtr signedIndex; - TestIndexPtr unsignedIndex; - - int32_t minId; - int32_t maxId; - int32_t intLength; - RandomPtr random; - - protected: - void build(const TestIndexPtr& index); - String pad(int32_t n); - }; -} +namespace Lucene { + +DECLARE_SHARED_PTR(TestIndex) + +/// Collation interacts badly with hyphens -- collation produces different ordering than Unicode code-point ordering, +/// so two indexes are created: +/// one which can't have negative random integers, for testing collated ranges, and the other which can have negative +/// random integers, for all other tests. +class TestIndex : public LuceneObject { +public: + TestIndex(int32_t minR, int32_t maxR, bool allowNegativeRandomInts); + virtual ~TestIndex(); + + LUCENE_CLASS(TestIndex); + +public: + int32_t maxR; + int32_t minR; + bool allowNegativeRandomInts; + RAMDirectoryPtr index; +}; + +class BaseTestRangeFilterFixture : public LuceneTestFixture { +public: + BaseTestRangeFilterFixture(); + virtual ~BaseTestRangeFilterFixture(); + +public: + TestIndexPtr signedIndex; + TestIndexPtr unsignedIndex; + + int32_t minId; + int32_t maxId; + int32_t intLength; + RandomPtr random; + +protected: + void build(const TestIndexPtr& index); + String pad(int32_t n); +}; +} #endif diff --git a/src/test/include/BaseTokenStreamFixture.h b/src/test/include/BaseTokenStreamFixture.h index ed4e0836..4c246df1 100644 --- a/src/test/include/BaseTokenStreamFixture.h +++ b/src/test/include/BaseTokenStreamFixture.h @@ -10,69 +10,67 @@ #include "LuceneTestFixture.h" #include "Attribute.h" -namespace Lucene -{ - DECLARE_SHARED_PTR(CheckClearAttributesAttribute) - - class CheckClearAttributesAttribute : public Attribute - { - public: - CheckClearAttributesAttribute(); - virtual ~CheckClearAttributesAttribute(); - - LUCENE_CLASS(CheckClearAttributesAttribute); - - protected: - bool clearCalled; - - public: - bool getAndResetClearCalled(); - - virtual void clear(); - virtual bool equals(const LuceneObjectPtr& other); - virtual int32_t hashCode(); - virtual void copyTo(const AttributePtr& target); - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; - - class BaseTokenStreamFixture : public LuceneTestFixture - { - public: - virtual ~BaseTokenStreamFixture(); - - public: - // some helpers to test Analyzers and TokenStreams - - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, - Collection types, Collection posIncrements, int32_t finalOffset = -1); - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output); - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection types); - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection posIncrements); - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets); - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset); - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset); - - static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, - Collection endOffsets, Collection types, Collection posIncrements); - static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output); - static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types); - static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements); - static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); - static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - - static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, - Collection endOffsets, Collection types, Collection posIncrements); - static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output); - static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types); - static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements); - static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); - static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); - - static void checkOneTerm(const AnalyzerPtr& analyzer, const String& input, const String& expected); - static void checkOneTermReuse(const AnalyzerPtr& analyzer, const String& input, const String& expected); - }; -} +namespace Lucene { + +DECLARE_SHARED_PTR(CheckClearAttributesAttribute) + +class CheckClearAttributesAttribute : public Attribute { +public: + CheckClearAttributesAttribute(); + virtual ~CheckClearAttributesAttribute(); + + LUCENE_CLASS(CheckClearAttributesAttribute); + +protected: + bool clearCalled; + +public: + bool getAndResetClearCalled(); + + virtual void clear(); + virtual bool equals(const LuceneObjectPtr& other); + virtual int32_t hashCode(); + virtual void copyTo(const AttributePtr& target); + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + +class BaseTokenStreamFixture : public LuceneTestFixture { +public: + virtual ~BaseTokenStreamFixture(); + +public: + // some helpers to test Analyzers and TokenStreams + + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, + Collection types, Collection posIncrements, int32_t finalOffset = -1); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection types); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection posIncrements); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, int32_t finalOffset); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); + static void checkTokenStreamContents(const TokenStreamPtr& ts, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements, int32_t finalOffset); + + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, + Collection endOffsets, Collection types, Collection posIncrements); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); + static void checkAnalyzesTo(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); + + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, + Collection endOffsets, Collection types, Collection posIncrements); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection types); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection posIncrements); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets); + static void checkAnalyzesToReuse(const AnalyzerPtr& analyzer, const String& input, Collection output, Collection startOffsets, Collection endOffsets, Collection posIncrements); + + static void checkOneTerm(const AnalyzerPtr& analyzer, const String& input, const String& expected); + static void checkOneTermReuse(const AnalyzerPtr& analyzer, const String& input, const String& expected); +}; +} #endif diff --git a/src/test/include/CheckHits.h b/src/test/include/CheckHits.h index ec9e2924..cc7ba569 100644 --- a/src/test/include/CheckHits.h +++ b/src/test/include/CheckHits.h @@ -9,50 +9,50 @@ #include "test_lucene.h" -namespace Lucene -{ - class CheckHits - { - public: - virtual ~CheckHits(); - - public: - /// Some explains methods calculate their values though a slightly different order of operations - /// from the actual scoring method - this allows for a small amount of variation - static const double EXPLAIN_SCORE_TOLERANCE_DELTA; - - /// Tests that all documents up to maxDoc which are *not* in the expected result set, have an - /// explanation which indicates no match (ie: Explanation value of 0.0) - static void checkNoMatchExplanations(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); - - /// Tests that a query matches the an expected set of documents using a HitCollector. - /// - /// Note that when using the HitCollector API, documents will be collected if they "match" - /// regardless of what their score is. - static void checkHitCollector(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); - - /// Tests that a query matches the an expected set of documents using Hits. - /// - /// Note that when using the Hits API, documents will only be returned if they have a - /// positive normalized score. - static void checkHits(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); - - /// Tests that a Hits has an expected order of documents - static void checkDocIds(Collection results, Collection hits); - - /// Tests that two queries have an expected order of documents, and that the two queries have - /// the same score values. - static void checkHitsQuery(const QueryPtr& query, Collection hits1, Collection hits2, Collection results); - static void checkEqual(const QueryPtr& query, Collection hits1, Collection hits2); - - /// Asserts that the explanation value for every document matching a query corresponds with the true score. - /// Optionally does "deep" testing of the explanation details. - static void checkExplanations(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, bool deep = false); - - /// Assert that an explanation has the expected score, and optionally that its sub-details max/sum/factor - /// match to that score. - static void verifyExplanation(const String& q, int32_t doc, double score, bool deep, const ExplanationPtr& expl); - }; +namespace Lucene { + +class CheckHits { +public: + virtual ~CheckHits(); + +public: + /// Some explains methods calculate their values though a slightly different order of operations + /// from the actual scoring method - this allows for a small amount of variation + static const double EXPLAIN_SCORE_TOLERANCE_DELTA; + + /// Tests that all documents up to maxDoc which are *not* in the expected result set, have an + /// explanation which indicates no match (ie: Explanation value of 0.0) + static void checkNoMatchExplanations(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); + + /// Tests that a query matches the an expected set of documents using a HitCollector. + /// + /// Note that when using the HitCollector API, documents will be collected if they "match" + /// regardless of what their score is. + static void checkHitCollector(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); + + /// Tests that a query matches the an expected set of documents using Hits. + /// + /// Note that when using the Hits API, documents will only be returned if they have a + /// positive normalized score. + static void checkHits(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results); + + /// Tests that a Hits has an expected order of documents + static void checkDocIds(Collection results, Collection hits); + + /// Tests that two queries have an expected order of documents, and that the two queries have + /// the same score values. + static void checkHitsQuery(const QueryPtr& query, Collection hits1, Collection hits2, Collection results); + static void checkEqual(const QueryPtr& query, Collection hits1, Collection hits2); + + /// Asserts that the explanation value for every document matching a query corresponds with the true score. + /// Optionally does "deep" testing of the explanation details. + static void checkExplanations(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, bool deep = false); + + /// Assert that an explanation has the expected score, and optionally that its sub-details max/sum/factor + /// match to that score. + static void verifyExplanation(const String& q, int32_t doc, double score, bool deep, const ExplanationPtr& expl); +}; + } #endif diff --git a/src/test/include/DocHelper.h b/src/test/include/DocHelper.h index fb95f063..7147f5d9 100644 --- a/src/test/include/DocHelper.h +++ b/src/test/include/DocHelper.h @@ -9,105 +9,105 @@ #include "test_lucene.h" -namespace Lucene -{ - class DocHelper - { - public: - DocHelper(); - virtual ~DocHelper(); - - public: - static const wchar_t* FIELD_1_TEXT; - static const wchar_t* TEXT_FIELD_1_KEY; - static FieldPtr textField1; - - static const wchar_t* FIELD_2_TEXT; - static const int32_t FIELD_2_FREQS[]; - static const wchar_t* TEXT_FIELD_2_KEY; - static FieldPtr textField2; - - static const wchar_t* FIELD_3_TEXT; - static const wchar_t* TEXT_FIELD_3_KEY; - static FieldPtr textField3; - - static const wchar_t* KEYWORD_TEXT; - static const wchar_t* KEYWORD_FIELD_KEY; - static FieldPtr keyField; - - static const wchar_t* NO_NORMS_TEXT; - static const wchar_t* NO_NORMS_KEY; - static FieldPtr noNormsField; - - static const wchar_t* NO_TF_TEXT; - static const wchar_t* NO_TF_KEY; - static FieldPtr noTFField; - - static const wchar_t* UNINDEXED_FIELD_TEXT; - static const wchar_t* UNINDEXED_FIELD_KEY; - static FieldPtr unIndField; - - static const wchar_t* UNSTORED_1_FIELD_TEXT; - static const wchar_t* UNSTORED_FIELD_1_KEY; - static FieldPtr unStoredField1; - - static const wchar_t* UNSTORED_2_FIELD_TEXT; - static const wchar_t* UNSTORED_FIELD_2_KEY; - static FieldPtr unStoredField2; - - static const wchar_t* LAZY_FIELD_BINARY_KEY; - static ByteArray LAZY_FIELD_BINARY_BYTES; - static FieldPtr lazyFieldBinary; - - static const wchar_t* LAZY_FIELD_KEY; - static const wchar_t* LAZY_FIELD_TEXT; - static FieldPtr lazyField; - - static const wchar_t* LARGE_LAZY_FIELD_KEY; - static String LARGE_LAZY_FIELD_TEXT; - static FieldPtr largeLazyField; - - static const uint8_t _FIELD_UTF1_TEXT[]; - static const String FIELD_UTF1_TEXT; - static const wchar_t* TEXT_FIELD_UTF1_KEY; - static FieldPtr textUtfField1; - - static const uint8_t _FIELD_UTF2_TEXT[]; - static const String FIELD_UTF2_TEXT; - static const int32_t FIELD_UTF2_FREQS[]; - static const wchar_t* TEXT_FIELD_UTF2_KEY; - static FieldPtr textUtfField2; - - static MapStringString nameValues; - - static Collection fields; - static MapStringField all; - static MapStringField indexed; - static MapStringField stored; - static MapStringField unstored; - static MapStringField unindexed; - static MapStringField termvector; - static MapStringField notermvector; - static MapStringField lazy; - static MapStringField noNorms; - static MapStringField noTf; - - public: - /// Adds the fields above to a document - void setupDoc(const DocumentPtr& doc); - - /// Writes the document to the directory using a segment named "test"; returns the SegmentInfo describing the new segment - SegmentInfoPtr writeDoc(const DirectoryPtr& dir, const DocumentPtr& doc); - - /// Writes the document to the directory using the analyzer and the similarity score; returns the SegmentInfo describing the new segment - SegmentInfoPtr writeDoc(const DirectoryPtr& dir, const AnalyzerPtr& analyzer, const SimilarityPtr& similarity, const DocumentPtr& doc); - - int32_t numFields(const DocumentPtr& doc); - - protected: - /// One-time setup to initialise static members - void setup(); - }; +namespace Lucene { + +class DocHelper { +public: + DocHelper(); + virtual ~DocHelper(); + +public: + static const wchar_t* FIELD_1_TEXT; + static const wchar_t* TEXT_FIELD_1_KEY; + static FieldPtr textField1; + + static const wchar_t* FIELD_2_TEXT; + static const int32_t FIELD_2_FREQS[]; + static const wchar_t* TEXT_FIELD_2_KEY; + static FieldPtr textField2; + + static const wchar_t* FIELD_3_TEXT; + static const wchar_t* TEXT_FIELD_3_KEY; + static FieldPtr textField3; + + static const wchar_t* KEYWORD_TEXT; + static const wchar_t* KEYWORD_FIELD_KEY; + static FieldPtr keyField; + + static const wchar_t* NO_NORMS_TEXT; + static const wchar_t* NO_NORMS_KEY; + static FieldPtr noNormsField; + + static const wchar_t* NO_TF_TEXT; + static const wchar_t* NO_TF_KEY; + static FieldPtr noTFField; + + static const wchar_t* UNINDEXED_FIELD_TEXT; + static const wchar_t* UNINDEXED_FIELD_KEY; + static FieldPtr unIndField; + + static const wchar_t* UNSTORED_1_FIELD_TEXT; + static const wchar_t* UNSTORED_FIELD_1_KEY; + static FieldPtr unStoredField1; + + static const wchar_t* UNSTORED_2_FIELD_TEXT; + static const wchar_t* UNSTORED_FIELD_2_KEY; + static FieldPtr unStoredField2; + + static const wchar_t* LAZY_FIELD_BINARY_KEY; + static ByteArray LAZY_FIELD_BINARY_BYTES; + static FieldPtr lazyFieldBinary; + + static const wchar_t* LAZY_FIELD_KEY; + static const wchar_t* LAZY_FIELD_TEXT; + static FieldPtr lazyField; + + static const wchar_t* LARGE_LAZY_FIELD_KEY; + static String LARGE_LAZY_FIELD_TEXT; + static FieldPtr largeLazyField; + + static const uint8_t _FIELD_UTF1_TEXT[]; + static const String FIELD_UTF1_TEXT; + static const wchar_t* TEXT_FIELD_UTF1_KEY; + static FieldPtr textUtfField1; + + static const uint8_t _FIELD_UTF2_TEXT[]; + static const String FIELD_UTF2_TEXT; + static const int32_t FIELD_UTF2_FREQS[]; + static const wchar_t* TEXT_FIELD_UTF2_KEY; + static FieldPtr textUtfField2; + + static MapStringString nameValues; + + static Collection fields; + static MapStringField all; + static MapStringField indexed; + static MapStringField stored; + static MapStringField unstored; + static MapStringField unindexed; + static MapStringField termvector; + static MapStringField notermvector; + static MapStringField lazy; + static MapStringField noNorms; + static MapStringField noTf; + +public: + /// Adds the fields above to a document + void setupDoc(const DocumentPtr& doc); + + /// Writes the document to the directory using a segment named "test"; returns the SegmentInfo describing the new segment + SegmentInfoPtr writeDoc(const DirectoryPtr& dir, const DocumentPtr& doc); + + /// Writes the document to the directory using the analyzer and the similarity score; returns the SegmentInfo describing the new segment + SegmentInfoPtr writeDoc(const DirectoryPtr& dir, const AnalyzerPtr& analyzer, const SimilarityPtr& similarity, const DocumentPtr& doc); + + int32_t numFields(const DocumentPtr& doc); + +protected: + /// One-time setup to initialise static members + void setup(); +}; + } #endif diff --git a/src/test/include/ExplanationsFixture.h b/src/test/include/ExplanationsFixture.h index 1ffb336b..1953c80b 100644 --- a/src/test/include/ExplanationsFixture.h +++ b/src/test/include/ExplanationsFixture.h @@ -9,52 +9,51 @@ #include "LuceneTestFixture.h" -namespace Lucene -{ - class ExplanationsFixture : public LuceneTestFixture - { - public: - ExplanationsFixture(); - virtual ~ExplanationsFixture(); - - public: - static const String KEY; - static const String FIELD; - - protected: - IndexSearcherPtr searcher; - QueryParserPtr qp; - Collection docFields; - - public: - virtual SpanTermQueryPtr st(const String& s); - virtual SpanFirstQueryPtr sf(const String& s, int32_t b); - virtual SpanNotQueryPtr snot(const SpanQueryPtr& i, const SpanQueryPtr& e); - virtual SpanOrQueryPtr sor(const String& s, const String& e); - virtual SpanOrQueryPtr sor(const SpanQueryPtr& s, const SpanQueryPtr& e); - virtual SpanOrQueryPtr sor(const String& s, const String& m, const String& e); - virtual SpanOrQueryPtr sor(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e); - virtual SpanNearQueryPtr snear(const String& s, const String& e, int32_t slop, bool inOrder); - virtual SpanNearQueryPtr snear(const SpanQueryPtr& s, const SpanQueryPtr& e, int32_t slop, bool inOrder); - virtual SpanNearQueryPtr snear(const String& s, const String& m, const String& e, int32_t slop, bool inOrder); - virtual SpanNearQueryPtr snear(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e, int32_t slop, bool inOrder); - virtual QueryPtr optB(const String& q); - virtual QueryPtr optB(const QueryPtr& q); - virtual QueryPtr reqB(const String& q); - virtual QueryPtr reqB(const QueryPtr& q); - virtual Collection ta(Collection s); - - /// Check the expDocNrs first, then check the query (and the explanations) - virtual void qtest(const String& queryText, Collection expDocNrs); - virtual void qtest(const QueryPtr& q, Collection expDocNrs); - - /// Tests a query using qtest after wrapping it with both optB and reqB - virtual void bqtest(const QueryPtr& q, Collection expDocNrs); - virtual void bqtest(const String& queryText, Collection expDocNrs); - - virtual QueryPtr makeQuery(const String& queryText); - }; -} +namespace Lucene { + +class ExplanationsFixture : public LuceneTestFixture { +public: + ExplanationsFixture(); + virtual ~ExplanationsFixture(); + +public: + static const String KEY; + static const String FIELD; + +protected: + IndexSearcherPtr searcher; + QueryParserPtr qp; + Collection docFields; + +public: + virtual SpanTermQueryPtr st(const String& s); + virtual SpanFirstQueryPtr sf(const String& s, int32_t b); + virtual SpanNotQueryPtr snot(const SpanQueryPtr& i, const SpanQueryPtr& e); + virtual SpanOrQueryPtr sor(const String& s, const String& e); + virtual SpanOrQueryPtr sor(const SpanQueryPtr& s, const SpanQueryPtr& e); + virtual SpanOrQueryPtr sor(const String& s, const String& m, const String& e); + virtual SpanOrQueryPtr sor(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e); + virtual SpanNearQueryPtr snear(const String& s, const String& e, int32_t slop, bool inOrder); + virtual SpanNearQueryPtr snear(const SpanQueryPtr& s, const SpanQueryPtr& e, int32_t slop, bool inOrder); + virtual SpanNearQueryPtr snear(const String& s, const String& m, const String& e, int32_t slop, bool inOrder); + virtual SpanNearQueryPtr snear(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e, int32_t slop, bool inOrder); + virtual QueryPtr optB(const String& q); + virtual QueryPtr optB(const QueryPtr& q); + virtual QueryPtr reqB(const String& q); + virtual QueryPtr reqB(const QueryPtr& q); + virtual Collection ta(Collection s); + + /// Check the expDocNrs first, then check the query (and the explanations) + virtual void qtest(const String& queryText, Collection expDocNrs); + virtual void qtest(const QueryPtr& q, Collection expDocNrs); + + /// Tests a query using qtest after wrapping it with both optB and reqB + virtual void bqtest(const QueryPtr& q, Collection expDocNrs); + virtual void bqtest(const String& queryText, Collection expDocNrs); + + virtual QueryPtr makeQuery(const String& queryText); +}; +} #endif diff --git a/src/test/include/FunctionFixture.h b/src/test/include/FunctionFixture.h index 0acfe623..fe32faea 100644 --- a/src/test/include/FunctionFixture.h +++ b/src/test/include/FunctionFixture.h @@ -9,41 +9,40 @@ #include "LuceneTestFixture.h" -namespace Lucene -{ - class FunctionFixture : public LuceneTestFixture - { - public: - FunctionFixture(bool doMultiSegment); - virtual ~FunctionFixture(); +namespace Lucene { - public: - static const double TEST_SCORE_TOLERANCE_DELTA; +class FunctionFixture : public LuceneTestFixture { +public: + FunctionFixture(bool doMultiSegment); + virtual ~FunctionFixture(); - public: - static const int32_t N_DOCS; +public: + static const double TEST_SCORE_TOLERANCE_DELTA; - static const String ID_FIELD; - static const String TEXT_FIELD; - static const String INT_FIELD; - static const String DOUBLE_FIELD; +public: + static const int32_t N_DOCS; - bool doMultiSegment; - DirectoryPtr dir; - AnalyzerPtr anlzr; + static const String ID_FIELD; + static const String TEXT_FIELD; + static const String INT_FIELD; + static const String DOUBLE_FIELD; - protected: - static const Collection DOC_TEXT_LINES(); + bool doMultiSegment; + DirectoryPtr dir; + AnalyzerPtr anlzr; - void addDoc(const IndexWriterPtr& iw, int32_t i); - String id2String(int32_t scoreAndID); - String textLine(int32_t docNum); +protected: + static const Collection DOC_TEXT_LINES(); - double expectedFieldScore(const String& docIDFieldVal); + void addDoc(const IndexWriterPtr& iw, int32_t i); + String id2String(int32_t scoreAndID); + String textLine(int32_t docNum); - bool equalCollectionValues(CollectionValue first, CollectionValue second); - }; -} + double expectedFieldScore(const String& docIDFieldVal); + + bool equalCollectionValues(CollectionValue first, CollectionValue second); +}; +} #endif diff --git a/src/test/include/LuceneGlobalFixture.h b/src/test/include/LuceneGlobalFixture.h index 73a7a40b..81f9cdda 100644 --- a/src/test/include/LuceneGlobalFixture.h +++ b/src/test/include/LuceneGlobalFixture.h @@ -6,16 +6,16 @@ #include "test_lucene.h" -namespace Lucene -{ - class LuceneGlobalFixture : public testing::Environment - { - public: - /// setup - LuceneGlobalFixture(); +namespace Lucene { + +class LuceneGlobalFixture : public testing::Environment { +public: + /// setup + LuceneGlobalFixture(); + + /// teardown + virtual ~LuceneGlobalFixture(); +}; - /// teardown - virtual ~LuceneGlobalFixture(); - }; } diff --git a/src/test/include/LuceneTestFixture.h b/src/test/include/LuceneTestFixture.h index a033d03a..fd7371a4 100644 --- a/src/test/include/LuceneTestFixture.h +++ b/src/test/include/LuceneTestFixture.h @@ -6,16 +6,16 @@ #include "test_lucene.h" -namespace Lucene -{ - class LuceneTestFixture : public testing::Test - { - public: - /// setup - LuceneTestFixture(); +namespace Lucene { + +class LuceneTestFixture : public testing::Test { +public: + /// setup + LuceneTestFixture(); + + /// teardown + virtual ~LuceneTestFixture(); +}; - /// teardown - virtual ~LuceneTestFixture(); - }; } diff --git a/src/test/include/MockFSDirectory.h b/src/test/include/MockFSDirectory.h index ec502484..795be9ec 100644 --- a/src/test/include/MockFSDirectory.h +++ b/src/test/include/MockFSDirectory.h @@ -10,38 +10,38 @@ #include "test_lucene.h" #include "Directory.h" -namespace Lucene -{ - class MockFSDirectory : public Directory - { - public: - MockFSDirectory(const String& path); - virtual ~MockFSDirectory(); - - LUCENE_CLASS(MockFSDirectory); - - public: - Collection allIndexInputs; - - protected: - DirectoryPtr dir; - RandomPtr rand; - - public: - virtual IndexInputPtr openInput(const String& name); - virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); - - void tweakBufferSizes(); - - virtual IndexOutputPtr createOutput(const String& name); - virtual void close(); - virtual void deleteFile(const String& name); - virtual void touchFile(const String& name); - virtual uint64_t fileModified(const String& name); - virtual bool fileExists(const String& name); - virtual HashSet listAll(); - virtual int64_t fileLength(const String& name); - }; +namespace Lucene { + +class MockFSDirectory : public Directory { +public: + MockFSDirectory(const String& path); + virtual ~MockFSDirectory(); + + LUCENE_CLASS(MockFSDirectory); + +public: + Collection allIndexInputs; + +protected: + DirectoryPtr dir; + RandomPtr rand; + +public: + virtual IndexInputPtr openInput(const String& name); + virtual IndexInputPtr openInput(const String& name, int32_t bufferSize); + + void tweakBufferSizes(); + + virtual IndexOutputPtr createOutput(const String& name); + virtual void close(); + virtual void deleteFile(const String& name); + virtual void touchFile(const String& name); + virtual uint64_t fileModified(const String& name); + virtual bool fileExists(const String& name); + virtual HashSet listAll(); + virtual int64_t fileLength(const String& name); +}; + } #endif diff --git a/src/test/include/MockFilter.h b/src/test/include/MockFilter.h index eb06e03f..72f5c575 100644 --- a/src/test/include/MockFilter.h +++ b/src/test/include/MockFilter.h @@ -10,25 +10,25 @@ #include "test_lucene.h" #include "Filter.h" -namespace Lucene -{ - class MockFilter : public Filter - { - public: - MockFilter(); - virtual ~MockFilter(); +namespace Lucene { - LUCENE_CLASS(MockFilter); +class MockFilter : public Filter { +public: + MockFilter(); + virtual ~MockFilter(); - protected: - bool _wasCalled; + LUCENE_CLASS(MockFilter); - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); +protected: + bool _wasCalled; + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader); + + void clear(); + bool wasCalled(); +}; - void clear(); - bool wasCalled(); - }; } #endif diff --git a/src/test/include/MockIndexInput.h b/src/test/include/MockIndexInput.h index 4a4984f2..71f84136 100644 --- a/src/test/include/MockIndexInput.h +++ b/src/test/include/MockIndexInput.h @@ -10,29 +10,29 @@ #include "test_lucene.h" #include "BufferedIndexInput.h" -namespace Lucene -{ - class MockIndexInput : public BufferedIndexInput - { - public: - MockIndexInput(ByteArray bytes); - virtual ~MockIndexInput(); - - LUCENE_CLASS(MockIndexInput); - - protected: - ByteArray buffer; - int32_t pointer; - int64_t _length; - - public: - virtual void close(); - virtual int64_t length(); - - protected: - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); - virtual void seekInternal(int64_t pos); - }; +namespace Lucene { + +class MockIndexInput : public BufferedIndexInput { +public: + MockIndexInput(ByteArray bytes); + virtual ~MockIndexInput(); + + LUCENE_CLASS(MockIndexInput); + +protected: + ByteArray buffer; + int32_t pointer; + int64_t _length; + +public: + virtual void close(); + virtual int64_t length(); + +protected: + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length); + virtual void seekInternal(int64_t pos); +}; + } #endif diff --git a/src/test/include/MockLock.h b/src/test/include/MockLock.h index c930f081..a245019b 100644 --- a/src/test/include/MockLock.h +++ b/src/test/include/MockLock.h @@ -10,25 +10,25 @@ #include "test_lucene.h" #include "Lock.h" -namespace Lucene -{ - class MockLock : public Lock - { - public: - MockLock(); - virtual ~MockLock(); - - LUCENE_CLASS(MockLock); - - public: - int32_t lockAttempts; - - public: - virtual bool obtain(); - virtual void release(); - virtual bool isLocked(); - virtual String toString(); - }; +namespace Lucene { + +class MockLock : public Lock { +public: + MockLock(); + virtual ~MockLock(); + + LUCENE_CLASS(MockLock); + +public: + int32_t lockAttempts; + +public: + virtual bool obtain(); + virtual void release(); + virtual bool isLocked(); + virtual String toString(); +}; + } #endif diff --git a/src/test/include/MockLockFactory.h b/src/test/include/MockLockFactory.h index ec7f9e8d..c1a370b9 100644 --- a/src/test/include/MockLockFactory.h +++ b/src/test/include/MockLockFactory.h @@ -10,26 +10,26 @@ #include "test_lucene.h" #include "LockFactory.h" -namespace Lucene -{ - class MockLockFactory : public LockFactory - { - public: - MockLockFactory(); - virtual ~MockLockFactory(); - - LUCENE_CLASS(MockLockFactory); - - public: - bool lockPrefixSet; - int32_t makeLockCount; - MapStringLock locksCreated; - - public: - virtual void setLockPrefix(const String& lockPrefix); - virtual LockPtr makeLock(const String& lockName); - virtual void clearLock(const String& lockName); - }; +namespace Lucene { + +class MockLockFactory : public LockFactory { +public: + MockLockFactory(); + virtual ~MockLockFactory(); + + LUCENE_CLASS(MockLockFactory); + +public: + bool lockPrefixSet; + int32_t makeLockCount; + MapStringLock locksCreated; + +public: + virtual void setLockPrefix(const String& lockPrefix); + virtual LockPtr makeLock(const String& lockName); + virtual void clearLock(const String& lockName); +}; + } #endif diff --git a/src/test/include/MockRAMDirectory.h b/src/test/include/MockRAMDirectory.h index c16eba1d..707ee020 100644 --- a/src/test/include/MockRAMDirectory.h +++ b/src/test/include/MockRAMDirectory.h @@ -10,123 +10,122 @@ #include "test_lucene.h" #include "RAMDirectory.h" -namespace Lucene -{ - /// This is a subclass of RAMDirectory that adds methods intended to be used only by unit tests. - class MockRAMDirectory : public RAMDirectory - { - public: - MockRAMDirectory(); - MockRAMDirectory(const DirectoryPtr& dir); - virtual ~MockRAMDirectory(); +namespace Lucene { - LUCENE_CLASS(MockRAMDirectory); +/// This is a subclass of RAMDirectory that adds methods intended to be used only by unit tests. +class MockRAMDirectory : public RAMDirectory { +public: + MockRAMDirectory(); + MockRAMDirectory(const DirectoryPtr& dir); + virtual ~MockRAMDirectory(); - public: - int64_t maxSize; - RandomPtr randomState; + LUCENE_CLASS(MockRAMDirectory); - // Max actual bytes used. This is set by MockRAMOutputStream - int64_t maxUsedSize; - double randomIOExceptionRate; - bool noDeleteOpenFile; - bool preventDoubleWrite; - bool crashed; +public: + int64_t maxSize; + RandomPtr randomState; - MapStringInt openFiles; + // Max actual bytes used. This is set by MockRAMOutputStream + int64_t maxUsedSize; + double randomIOExceptionRate; + bool noDeleteOpenFile; + bool preventDoubleWrite; + bool crashed; - // Only tracked if noDeleteOpenFile is true: if an attempt is made to delete an - // open file, we enroll it here. - HashSet openFilesDeleted; + MapStringInt openFiles; - Collection failures; + // Only tracked if noDeleteOpenFile is true: if an attempt is made to delete an + // open file, we enroll it here. + HashSet openFilesDeleted; - protected: - HashSet unSyncedFiles; - HashSet createdFiles; + Collection failures; - public: - /// If set to true, we throw an IO exception if the same file is opened by createOutput, ever. - void setPreventDoubleWrite(bool value); +protected: + HashSet unSyncedFiles; + HashSet createdFiles; - virtual void sync(const String& name); +public: + /// If set to true, we throw an IO exception if the same file is opened by createOutput, ever. + void setPreventDoubleWrite(bool value); - /// Simulates a crash of OS or machine by overwriting unsynced files. - void crash(); + virtual void sync(const String& name); - void clearCrash(); - void setMaxSizeInBytes(int64_t maxSize); - int64_t getMaxSizeInBytes(); + /// Simulates a crash of OS or machine by overwriting unsynced files. + void crash(); - /// Returns the peek actual storage used (bytes) in this directory. - int64_t getMaxUsedSizeInBytes(); - void resetMaxUsedSizeInBytes(); + void clearCrash(); + void setMaxSizeInBytes(int64_t maxSize); + int64_t getMaxSizeInBytes(); - /// Emulate windows whereby deleting an open file is not allowed (raise IO exception) - void setNoDeleteOpenFile(bool value); - bool getNoDeleteOpenFile(); + /// Returns the peek actual storage used (bytes) in this directory. + int64_t getMaxUsedSizeInBytes(); + void resetMaxUsedSizeInBytes(); - /// If 0.0, no exceptions will be thrown. Else this should be a double 0.0 - 1.0. We will randomly throw an - /// IO exception on the first write to an OutputStream based on this probability. - void setRandomIOExceptionRate(double rate, int64_t seed); - double getRandomIOExceptionRate(); + /// Emulate windows whereby deleting an open file is not allowed (raise IO exception) + void setNoDeleteOpenFile(bool value); + bool getNoDeleteOpenFile(); - void maybeThrowIOException(); + /// If 0.0, no exceptions will be thrown. Else this should be a double 0.0 - 1.0. We will randomly throw an + /// IO exception on the first write to an OutputStream based on this probability. + void setRandomIOExceptionRate(double rate, int64_t seed); + double getRandomIOExceptionRate(); - virtual void deleteFile(const String& name); + void maybeThrowIOException(); - virtual HashSet getOpenDeletedFiles(); + virtual void deleteFile(const String& name); - virtual IndexOutputPtr createOutput(const String& name); - virtual IndexInputPtr openInput(const String& name); + virtual HashSet getOpenDeletedFiles(); - /// Provided for testing purposes. Use sizeInBytes() instead. - int64_t getRecomputedSizeInBytes(); + virtual IndexOutputPtr createOutput(const String& name); + virtual IndexInputPtr openInput(const String& name); - /// Like getRecomputedSizeInBytes(), but, uses actual file lengths rather than buffer allocations (which are - /// quantized up to nearest RAMOutputStream::BUFFER_SIZE (now 1024) bytes. - int64_t getRecomputedActualSizeInBytes(); + /// Provided for testing purposes. Use sizeInBytes() instead. + int64_t getRecomputedSizeInBytes(); - virtual void close(); + /// Like getRecomputedSizeInBytes(), but, uses actual file lengths rather than buffer allocations (which are + /// quantized up to nearest RAMOutputStream::BUFFER_SIZE (now 1024) bytes. + int64_t getRecomputedActualSizeInBytes(); - /// Add a Failure object to the list of objects to be evaluated at every potential failure point - void failOn(const MockDirectoryFailurePtr& fail); + virtual void close(); - /// Iterate through the failures list, giving each object a chance to throw an IO exception. - void maybeThrowDeterministicException(); + /// Add a Failure object to the list of objects to be evaluated at every potential failure point + void failOn(const MockDirectoryFailurePtr& fail); - protected: - void init(); + /// Iterate through the failures list, giving each object a chance to throw an IO exception. + void maybeThrowDeterministicException(); - void deleteFile(const String& name, bool forced); - }; +protected: + void init(); - /// Objects that represent fail-able conditions. Objects of a derived class are created and registered with the - /// mock directory. After register, each object will be invoked once for each first write of a file, giving the - /// object a chance to throw an IO exception. - class MockDirectoryFailure : public LuceneObject - { - public: - MockDirectoryFailure(); - virtual ~MockDirectoryFailure(); + void deleteFile(const String& name, bool forced); +}; - LUCENE_CLASS(MockDirectoryFailure); +/// Objects that represent fail-able conditions. Objects of a derived class are created and registered with the +/// mock directory. After register, each object will be invoked once for each first write of a file, giving the +/// object a chance to throw an IO exception. +class MockDirectoryFailure : public LuceneObject { +public: + MockDirectoryFailure(); + virtual ~MockDirectoryFailure(); - public: - /// eval is called on the first write of every new file. - virtual void eval(const MockRAMDirectoryPtr& dir); + LUCENE_CLASS(MockDirectoryFailure); - /// reset should set the state of the failure to its default (freshly constructed) state. Reset is convenient - /// for tests that want to create one failure object and then reuse it in multiple cases. This, combined with - /// the fact that MockDirectoryFailure subclasses are often anonymous classes makes reset difficult to do otherwise. - virtual MockDirectoryFailurePtr reset(); +public: + /// eval is called on the first write of every new file. + virtual void eval(const MockRAMDirectoryPtr& dir); - virtual void setDoFail(); - virtual void clearDoFail(); + /// reset should set the state of the failure to its default (freshly constructed) state. Reset is convenient + /// for tests that want to create one failure object and then reuse it in multiple cases. This, combined with + /// the fact that MockDirectoryFailure subclasses are often anonymous classes makes reset difficult to do otherwise. + virtual MockDirectoryFailurePtr reset(); + + virtual void setDoFail(); + virtual void clearDoFail(); + +protected: + bool doFail; +}; - protected: - bool doFail; - }; } #endif diff --git a/src/test/include/MockRAMInputStream.h b/src/test/include/MockRAMInputStream.h index 742d2ab7..2dded88e 100644 --- a/src/test/include/MockRAMInputStream.h +++ b/src/test/include/MockRAMInputStream.h @@ -10,29 +10,29 @@ #include "test_lucene.h" #include "RAMInputStream.h" -namespace Lucene -{ - /// Used by MockRAMDirectory to create an input stream that keeps track of when it's been closed. - class MockRAMInputStream : public RAMInputStream - { - public: - /// Construct an empty output buffer. - MockRAMInputStream(); - MockRAMInputStream(const MockRAMDirectoryPtr& dir, const String& name, const RAMFilePtr& f); - virtual ~MockRAMInputStream(); - - LUCENE_CLASS(MockRAMInputStream); - - protected: - MockRAMDirectoryWeakPtr _dir; - String name; - bool isClone; - - public: - virtual void close(); - - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); - }; +namespace Lucene { + +/// Used by MockRAMDirectory to create an input stream that keeps track of when it's been closed. +class MockRAMInputStream : public RAMInputStream { +public: + /// Construct an empty output buffer. + MockRAMInputStream(); + MockRAMInputStream(const MockRAMDirectoryPtr& dir, const String& name, const RAMFilePtr& f); + virtual ~MockRAMInputStream(); + + LUCENE_CLASS(MockRAMInputStream); + +protected: + MockRAMDirectoryWeakPtr _dir; + String name; + bool isClone; + +public: + virtual void close(); + + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()); +}; + } #endif diff --git a/src/test/include/MockRAMOutputStream.h b/src/test/include/MockRAMOutputStream.h index 78933aee..dc0c7d42 100644 --- a/src/test/include/MockRAMOutputStream.h +++ b/src/test/include/MockRAMOutputStream.h @@ -10,33 +10,33 @@ #include "test_lucene.h" #include "RAMOutputStream.h" -namespace Lucene -{ - /// Used by MockRAMDirectory to create an output stream that will throw an IOException on fake disk full, track max - /// disk space actually used, and maybe throw random IOExceptions. - class MockRAMOutputStream : public RAMOutputStream - { - public: - /// Construct an empty output buffer. - MockRAMOutputStream(const MockRAMDirectoryPtr& dir, const RAMFilePtr& f, const String& name); - virtual ~MockRAMOutputStream(); - - LUCENE_CLASS(MockRAMOutputStream); - - protected: - MockRAMDirectoryWeakPtr _dir; - bool first; - String name; - - public: - ByteArray singleByte; - - public: - virtual void close(); - virtual void flush(); - virtual void writeByte(uint8_t b); - virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); - }; +namespace Lucene { + +/// Used by MockRAMDirectory to create an output stream that will throw an IOException on fake disk full, track max +/// disk space actually used, and maybe throw random IOExceptions. +class MockRAMOutputStream : public RAMOutputStream { +public: + /// Construct an empty output buffer. + MockRAMOutputStream(const MockRAMDirectoryPtr& dir, const RAMFilePtr& f, const String& name); + virtual ~MockRAMOutputStream(); + + LUCENE_CLASS(MockRAMOutputStream); + +protected: + MockRAMDirectoryWeakPtr _dir; + bool first; + String name; + +public: + ByteArray singleByte; + +public: + virtual void close(); + virtual void flush(); + virtual void writeByte(uint8_t b); + virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length); +}; + } #endif diff --git a/src/test/include/PayloadHelper.h b/src/test/include/PayloadHelper.h index f0638a41..d3baedb6 100644 --- a/src/test/include/PayloadHelper.h +++ b/src/test/include/PayloadHelper.h @@ -9,27 +9,27 @@ #include "test_lucene.h" -namespace Lucene -{ - class PayloadHelper - { - public: - virtual ~PayloadHelper(); - - public: - static const String NO_PAYLOAD_FIELD; - static const String MULTI_FIELD; - static const String FIELD; - - public: - static const ByteArray payloadField(); - static const ByteArray payloadMultiField1(); - static const ByteArray payloadMultiField2(); - - /// Sets up a RAMDirectory, and adds documents (using intToEnglish()) with two fields: field and multiField - /// and analyzes them using the PayloadHelperAnalyzer - static IndexSearcherPtr setUp(const SimilarityPtr& similarity, int32_t numDocs); - }; +namespace Lucene { + +class PayloadHelper { +public: + virtual ~PayloadHelper(); + +public: + static const String NO_PAYLOAD_FIELD; + static const String MULTI_FIELD; + static const String FIELD; + +public: + static const ByteArray payloadField(); + static const ByteArray payloadMultiField1(); + static const ByteArray payloadMultiField2(); + + /// Sets up a RAMDirectory, and adds documents (using intToEnglish()) with two fields: field and multiField + /// and analyzes them using the PayloadHelperAnalyzer + static IndexSearcherPtr setUp(const SimilarityPtr& similarity, int32_t numDocs); +}; + } #endif diff --git a/src/test/include/QueryUtils.h b/src/test/include/QueryUtils.h index 6869918e..d5ca4567 100644 --- a/src/test/include/QueryUtils.h +++ b/src/test/include/QueryUtils.h @@ -9,57 +9,57 @@ #include "test_lucene.h" -namespace Lucene -{ - class QueryUtils - { - public: - virtual ~QueryUtils(); - - public: - /// Check the types of things query objects should be able to do. - static void check(const QueryPtr& q); - - /// Check very basic hashCode and equals - static void checkHashEquals(const QueryPtr& q); - - static void checkEqual(const QueryPtr& q1, const QueryPtr& q2); - static void checkUnequal(const QueryPtr& q1, const QueryPtr& q2); - - /// Deep check that explanations of a query 'score' correctly - static void checkExplanations(const QueryPtr& q, const SearcherPtr& s); - - /// Various query sanity checks on a searcher, some checks are only done - /// for types of IndexSearcher. - static void check(const QueryPtr& q1, const SearcherPtr& s); - static void check(const QueryPtr& q1, const SearcherPtr& s, bool wrap); - - /// Given an IndexSearcher, returns a new IndexSearcher whose IndexReader is a MultiReader - /// containing the Reader of the original IndexSearcher, as well as several "empty" - /// IndexReaders - some of which will have deleted documents in them. This new IndexSearcher - /// should behave exactly the same as the original IndexSearcher. - /// @param s the searcher to wrap. - /// @param edge if negative, s will be the first sub; if 0, s will be in the middle, if - /// positive s will be the last sub - static IndexSearcherPtr wrapUnderlyingReader(const IndexSearcherPtr& s, int32_t edge); - - /// Given a Searcher, returns a new MultiSearcher wrapping the the original Searcher, as well - /// as several "empty" IndexSearchers - some of which will have deleted documents in them. - /// This new MultiSearcher should behave exactly the same as the original Searcher. - /// @param s the Searcher to wrap - /// @param edge if negative, s will be the first sub; if 0, s will be in hte middle, if positive - /// s will be the last sub - static MultiSearcherPtr wrapSearcher(const SearcherPtr& s, int32_t edge); - - static RAMDirectoryPtr makeEmptyIndex(int32_t numDeletedDocs); - - /// Alternate scorer skipTo(), skipTo(), next(), next(), skipTo(), skipTo(), etc and ensure - /// a hitcollector receives same docs and scores - static void checkSkipTo(const QueryPtr& q, const IndexSearcherPtr& s); - - /// Check that first skip on just created scorers always goes to the right doc - static void checkFirstSkipTo(const QueryPtr& q, const IndexSearcherPtr& s); - }; +namespace Lucene { + +class QueryUtils { +public: + virtual ~QueryUtils(); + +public: + /// Check the types of things query objects should be able to do. + static void check(const QueryPtr& q); + + /// Check very basic hashCode and equals + static void checkHashEquals(const QueryPtr& q); + + static void checkEqual(const QueryPtr& q1, const QueryPtr& q2); + static void checkUnequal(const QueryPtr& q1, const QueryPtr& q2); + + /// Deep check that explanations of a query 'score' correctly + static void checkExplanations(const QueryPtr& q, const SearcherPtr& s); + + /// Various query sanity checks on a searcher, some checks are only done + /// for types of IndexSearcher. + static void check(const QueryPtr& q1, const SearcherPtr& s); + static void check(const QueryPtr& q1, const SearcherPtr& s, bool wrap); + + /// Given an IndexSearcher, returns a new IndexSearcher whose IndexReader is a MultiReader + /// containing the Reader of the original IndexSearcher, as well as several "empty" + /// IndexReaders - some of which will have deleted documents in them. This new IndexSearcher + /// should behave exactly the same as the original IndexSearcher. + /// @param s the searcher to wrap. + /// @param edge if negative, s will be the first sub; if 0, s will be in the middle, if + /// positive s will be the last sub + static IndexSearcherPtr wrapUnderlyingReader(const IndexSearcherPtr& s, int32_t edge); + + /// Given a Searcher, returns a new MultiSearcher wrapping the the original Searcher, as well + /// as several "empty" IndexSearchers - some of which will have deleted documents in them. + /// This new MultiSearcher should behave exactly the same as the original Searcher. + /// @param s the Searcher to wrap + /// @param edge if negative, s will be the first sub; if 0, s will be in hte middle, if positive + /// s will be the last sub + static MultiSearcherPtr wrapSearcher(const SearcherPtr& s, int32_t edge); + + static RAMDirectoryPtr makeEmptyIndex(int32_t numDeletedDocs); + + /// Alternate scorer skipTo(), skipTo(), next(), next(), skipTo(), skipTo(), etc and ensure + /// a hitcollector receives same docs and scores + static void checkSkipTo(const QueryPtr& q, const IndexSearcherPtr& s); + + /// Check that first skip on just created scorers always goes to the right doc + static void checkFirstSkipTo(const QueryPtr& q, const IndexSearcherPtr& s); +}; + } #endif diff --git a/src/test/include/TestUtils.h b/src/test/include/TestUtils.h index 3d4dddf9..66e19226 100644 --- a/src/test/include/TestUtils.h +++ b/src/test/include/TestUtils.h @@ -9,35 +9,35 @@ #include "Lucene.h" -namespace Lucene -{ - /// Initialise unit test files directory - void setTestDir(const String& dir); +namespace Lucene { - /// Return unit test files directory - String getTestDir(); +/// Initialise unit test files directory +void setTestDir(const String& dir); - /// Return temporary directory - String getTempDir(); +/// Return unit test files directory +String getTestDir(); - /// Return temporary directory (randomly generated) - String getTempDir(const String& desc); +/// Return temporary directory +String getTempDir(); - /// Wait for concurrent merge to finish - void syncConcurrentMerges(const IndexWriterPtr& writer); +/// Return temporary directory (randomly generated) +String getTempDir(const String& desc); - /// Wait for concurrent merge to finish - void syncConcurrentMerges(const MergeSchedulerPtr& ms); +/// Wait for concurrent merge to finish +void syncConcurrentMerges(const IndexWriterPtr& writer); - /// Return English representation of given integer - String intToEnglish(int32_t i); +/// Wait for concurrent merge to finish +void syncConcurrentMerges(const MergeSchedulerPtr& ms); - /// Return English representation of given integer (recursive) - String _intToEnglish(int32_t i); +/// Return English representation of given integer +String intToEnglish(int32_t i); - /// This runs the CheckIndex tool on the index in. - /// If any issues are hit, a RuntimeException is thrown; else, true is returned. - bool checkIndex(const DirectoryPtr& dir); +/// Return English representation of given integer (recursive) +String _intToEnglish(int32_t i); + +/// This runs the CheckIndex tool on the index in. +/// If any issues are hit, a RuntimeException is thrown; else, true is returned. +bool checkIndex(const DirectoryPtr& dir); } #endif diff --git a/src/test/include/test_lucene.h b/src/test/include/test_lucene.h index 59c57319..68e1ec32 100644 --- a/src/test/include/test_lucene.h +++ b/src/test/include/test_lucene.h @@ -12,38 +12,36 @@ #include "StringUtils.h" #include -namespace std -{ - inline std::ostream& operator<< (std::ostream& out, const Lucene::String& s) - { - out << Lucene::StringUtils::toUTF8(s); - return out; - } +namespace std { + +inline std::ostream& operator<< (std::ostream& out, const Lucene::String& s) { + out << Lucene::StringUtils::toUTF8(s); + return out; } -namespace Lucene -{ - DECLARE_SHARED_PTR(MockDirectoryFailure) - DECLARE_SHARED_PTR(MockFSDirectory) - DECLARE_SHARED_PTR(MockLock) - DECLARE_SHARED_PTR(MockLockFactory) - DECLARE_SHARED_PTR(MockRAMDirectory) - DECLARE_SHARED_PTR(MockRAMInputStream) - DECLARE_SHARED_PTR(MockRAMOutputStream) - DECLARE_SHARED_PTR(MockFilter) - - typedef HashMap MapStringField; - - struct check_exception - { - check_exception(LuceneException::ExceptionType type) : checkType(type) {} - inline bool operator()(const LuceneException& e) - { - return (checkType == LuceneException::Null || e.getType() == checkType); - } - LuceneException::ExceptionType checkType; - }; } +namespace Lucene { + +DECLARE_SHARED_PTR(MockDirectoryFailure) +DECLARE_SHARED_PTR(MockFSDirectory) +DECLARE_SHARED_PTR(MockLock) +DECLARE_SHARED_PTR(MockLockFactory) +DECLARE_SHARED_PTR(MockRAMDirectory) +DECLARE_SHARED_PTR(MockRAMInputStream) +DECLARE_SHARED_PTR(MockRAMOutputStream) +DECLARE_SHARED_PTR(MockFilter) + +typedef HashMap MapStringField; + +struct check_exception { + check_exception(LuceneException::ExceptionType type) : checkType(type) {} + inline bool operator()(const LuceneException& e) { + return (checkType == LuceneException::Null || e.getType() == checkType); + } + LuceneException::ExceptionType checkType; +}; + +} #endif diff --git a/src/test/index/AddIndexesNoOptimizeTest.cpp b/src/test/index/AddIndexesNoOptimizeTest.cpp index 50fe6e6b..eb423b04 100644 --- a/src/test/index/AddIndexesNoOptimizeTest.cpp +++ b/src/test/index/AddIndexesNoOptimizeTest.cpp @@ -24,54 +24,47 @@ using namespace Lucene; typedef LuceneTestFixture AddIndexesNoOptimizeTest; -static IndexWriterPtr newWriter(const DirectoryPtr& dir, bool create) -{ +static IndexWriterPtr newWriter(const DirectoryPtr& dir, bool create) { IndexWriterPtr writer = newLucene(dir, newLucene(), create, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMergePolicy(newLucene(writer)); return writer; } -static void addDocs(const IndexWriterPtr& writer, int32_t numDocs) -{ - for (int32_t i = 0; i < numDocs; ++i) - { +static void addDocs(const IndexWriterPtr& writer, int32_t numDocs) { + for (int32_t i = 0; i < numDocs; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } } -static void addDocs2(const IndexWriterPtr& writer, int32_t numDocs) -{ - for (int32_t i = 0; i < numDocs; ++i) - { +static void addDocs2(const IndexWriterPtr& writer, int32_t numDocs) { + for (int32_t i = 0; i < numDocs; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"bbb", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } } -static void verifyNumDocs(const DirectoryPtr& dir, int32_t numDocs) -{ +static void verifyNumDocs(const DirectoryPtr& dir, int32_t numDocs) { IndexReaderPtr reader = IndexReader::open(dir, true); EXPECT_EQ(reader->maxDoc(), numDocs); EXPECT_EQ(reader->numDocs(), numDocs); reader->close(); } -static void verifyTermDocs(const DirectoryPtr& dir, const TermPtr& term, int32_t numDocs) -{ +static void verifyTermDocs(const DirectoryPtr& dir, const TermPtr& term, int32_t numDocs) { IndexReaderPtr reader = IndexReader::open(dir, true); TermDocsPtr termDocs = reader->termDocs(term); int32_t count = 0; - while (termDocs->next()) + while (termDocs->next()) { ++count; + } EXPECT_EQ(count, numDocs); reader->close(); } -static void setUpDirs(const DirectoryPtr& dir, const DirectoryPtr& aux) -{ +static void setUpDirs(const DirectoryPtr& dir, const DirectoryPtr& aux) { IndexWriterPtr writer; writer = newWriter(dir, true); @@ -87,8 +80,7 @@ static void setUpDirs(const DirectoryPtr& dir, const DirectoryPtr& aux) writer->setMaxBufferedDocs(100); writer->setMergeFactor(10); // add 30 documents in 3 segments - for (int32_t i = 0; i < 3; ++i) - { + for (int32_t i = 0; i < 3; ++i) { addDocs(writer, 10); writer->close(); writer = newWriter(aux, false); @@ -101,8 +93,7 @@ static void setUpDirs(const DirectoryPtr& dir, const DirectoryPtr& aux) writer->close(); } -TEST_F(AddIndexesNoOptimizeTest, testSimpleCase) -{ +TEST_F(AddIndexesNoOptimizeTest, testSimpleCase) { // main directory DirectoryPtr dir = newLucene(); // two auxiliary directories @@ -192,8 +183,7 @@ TEST_F(AddIndexesNoOptimizeTest, testSimpleCase) verifyTermDocs(dir, newLucene(L"content", L"bbb"), 51); } -TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes) -{ +TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -204,8 +194,7 @@ TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes) writer->addIndexesNoOptimize(newCollection(aux)); // Adds 10 docs, then replaces them with another 10 docs, so 10 pending deletes - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i % 10), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"content", L"bbb " + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -230,8 +219,7 @@ TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes2) -{ +TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes2) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -241,8 +229,7 @@ TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes2) IndexWriterPtr writer = newWriter(dir, false); // Adds 10 docs, then replaces them with another 10 docs, so 10 pending deletes - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i % 10), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"content", L"bbb " + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -269,8 +256,7 @@ TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes2) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes3) -{ +TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes3) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -280,8 +266,7 @@ TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes3) IndexWriterPtr writer = newWriter(dir, false); // Adds 10 docs, then replaces them with another 10 docs, so 10 pending deletes - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i % 10), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"content", L"bbb " + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -308,8 +293,7 @@ TEST_F(AddIndexesNoOptimizeTest, testWithPendingDeletes3) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testAddSelf) -{ +TEST_F(AddIndexesNoOptimizeTest, testAddSelf) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -334,12 +318,9 @@ TEST_F(AddIndexesNoOptimizeTest, testAddSelf) writer->close(); writer = newWriter(dir, false); - try - { + try { writer->addIndexesNoOptimize(newCollection(aux, dir)); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); // cannot add self } EXPECT_EQ(100, writer->maxDoc()); @@ -353,8 +334,7 @@ TEST_F(AddIndexesNoOptimizeTest, testAddSelf) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testNoTailSegments) -{ +TEST_F(AddIndexesNoOptimizeTest, testNoTailSegments) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -381,8 +361,7 @@ TEST_F(AddIndexesNoOptimizeTest, testNoTailSegments) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testNoCopySegments) -{ +TEST_F(AddIndexesNoOptimizeTest, testNoCopySegments) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -409,8 +388,7 @@ TEST_F(AddIndexesNoOptimizeTest, testNoCopySegments) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testNoMergeAfterCopy) -{ +TEST_F(AddIndexesNoOptimizeTest, testNoMergeAfterCopy) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -435,8 +413,7 @@ TEST_F(AddIndexesNoOptimizeTest, testNoMergeAfterCopy) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testMergeAfterCopy) -{ +TEST_F(AddIndexesNoOptimizeTest, testMergeAfterCopy) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -445,8 +422,9 @@ TEST_F(AddIndexesNoOptimizeTest, testMergeAfterCopy) setUpDirs(dir, aux); IndexReaderPtr reader = IndexReader::open(aux, false); - for (int32_t i = 0; i < 20; ++i) + for (int32_t i = 0; i < 20; ++i) { reader->deleteDocument(i); + } EXPECT_EQ(10, reader->numDocs()); reader->close(); @@ -467,8 +445,7 @@ TEST_F(AddIndexesNoOptimizeTest, testMergeAfterCopy) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testMoreMerges) -{ +TEST_F(AddIndexesNoOptimizeTest, testMoreMerges) { // main directory DirectoryPtr dir = newLucene(); // auxiliary directory @@ -488,14 +465,16 @@ TEST_F(AddIndexesNoOptimizeTest, testMoreMerges) writer->close(); IndexReaderPtr reader = IndexReader::open(aux, false); - for (int32_t i = 0; i < 27; ++i) + for (int32_t i = 0; i < 27; ++i) { reader->deleteDocument(i); + } EXPECT_EQ(3, reader->numDocs()); reader->close(); reader = IndexReader::open(aux2, false); - for (int32_t i = 0; i < 8; ++i) + for (int32_t i = 0; i < 8; ++i) { reader->deleteDocument(i); + } EXPECT_EQ(22, reader->numDocs()); reader->close(); @@ -516,8 +495,7 @@ TEST_F(AddIndexesNoOptimizeTest, testMoreMerges) aux->close(); } -TEST_F(AddIndexesNoOptimizeTest, testHangOnClose) -{ +TEST_F(AddIndexesNoOptimizeTest, testHangOnClose) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMergePolicy(newLucene(writer)); @@ -528,8 +506,9 @@ TEST_F(AddIndexesNoOptimizeTest, testHangOnClose) DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - for (int32_t i = 0; i < 60; ++i) + for (int32_t i = 0; i < 60; ++i) { writer->addDocument(doc); + } writer->setMaxBufferedDocs(200); DocumentPtr doc2 = newLucene(); @@ -538,8 +517,9 @@ TEST_F(AddIndexesNoOptimizeTest, testHangOnClose) doc2->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_NO)); doc2->add(newLucene(L"content", L"aaa bbb ccc ddd eee fff ggg hhh iii", Field::STORE_YES, Field::INDEX_NO)); - for (int32_t i = 0; i < 60; ++i) + for (int32_t i = 0; i < 60; ++i) { writer->addDocument(doc2); + } writer->close(); DirectoryPtr dir2 = newLucene(); @@ -556,8 +536,7 @@ TEST_F(AddIndexesNoOptimizeTest, testHangOnClose) dir2->close(); } -TEST_F(AddIndexesNoOptimizeTest, testTargetCFS) -{ +TEST_F(AddIndexesNoOptimizeTest, testTargetCFS) { // make sure CFS of destination indexwriter is respected when copying tail segments DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newWriter(dir, true); diff --git a/src/test/index/AtomicUpdateTest.cpp b/src/test/index/AtomicUpdateTest.cpp index 0a4200d0..0535ee0c 100644 --- a/src/test/index/AtomicUpdateTest.cpp +++ b/src/test/index/AtomicUpdateTest.cpp @@ -24,26 +24,23 @@ using namespace Lucene; typedef LuceneTestFixture AtomicUpdateTest; -class MockIndexWriter : public IndexWriter -{ +class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) - { + MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) { random = newLucene(); } - virtual ~MockIndexWriter() - { + virtual ~MockIndexWriter() { } protected: RandomPtr random; public: - virtual bool testPoint(const String& name) - { - if (random->nextInt(4) == 2) + virtual bool testPoint(const String& name) { + if (random->nextInt(4) == 2) { LuceneThread::threadYield(); + } return true; } }; @@ -52,16 +49,13 @@ DECLARE_SHARED_PTR(AtomicTimedThread) DECLARE_SHARED_PTR(AtomicIndexerThread) DECLARE_SHARED_PTR(AtomicSearcherThread) -class AtomicTimedThread : public LuceneThread -{ +class AtomicTimedThread : public LuceneThread { public: - AtomicTimedThread() - { + AtomicTimedThread() { this->failed = false; } - virtual ~AtomicTimedThread() - { + virtual ~AtomicTimedThread() { } LUCENE_CLASS(AtomicTimedThread); @@ -75,17 +69,14 @@ class AtomicTimedThread : public LuceneThread public: virtual void doWork() = 0; - virtual void run() - { + virtual void run() { int64_t stopTime = MiscUtils::currentTimeMillis() + 1000 * RUN_TIME_SEC; - try - { - while ((int64_t)MiscUtils::currentTimeMillis() < stopTime && !failed) + try { + while ((int64_t)MiscUtils::currentTimeMillis() < stopTime && !failed) { doWork(); - } - catch (LuceneException& e) - { + } + } catch (LuceneException& e) { failed = true; FAIL() << "Unexpected exception: " << e.getError(); } @@ -94,16 +85,13 @@ class AtomicTimedThread : public LuceneThread const int32_t AtomicTimedThread::RUN_TIME_SEC = 3; -class AtomicIndexerThread : public AtomicTimedThread -{ +class AtomicIndexerThread : public AtomicTimedThread { public: - AtomicIndexerThread(const IndexWriterPtr& writer) - { + AtomicIndexerThread(const IndexWriterPtr& writer) { this->writer = writer; } - virtual ~AtomicIndexerThread() - { + virtual ~AtomicIndexerThread() { } LUCENE_CLASS(AtomicIndexerThread); @@ -112,11 +100,9 @@ class AtomicIndexerThread : public AtomicTimedThread IndexWriterPtr writer; public: - virtual void doWork() - { + virtual void doWork() { // Update all 100 docs - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { DocumentPtr d = newLucene(); d->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); d->add(newLucene(L"contents", intToEnglish(i), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -125,16 +111,13 @@ class AtomicIndexerThread : public AtomicTimedThread } }; -class AtomicSearcherThread : public AtomicTimedThread -{ +class AtomicSearcherThread : public AtomicTimedThread { public: - AtomicSearcherThread(const DirectoryPtr& directory) - { + AtomicSearcherThread(const DirectoryPtr& directory) { this->directory = directory; } - virtual ~AtomicSearcherThread() - { + virtual ~AtomicSearcherThread() { } LUCENE_CLASS(AtomicSearcherThread); @@ -143,18 +126,17 @@ class AtomicSearcherThread : public AtomicTimedThread DirectoryPtr directory; public: - virtual void doWork() - { + virtual void doWork() { IndexReaderPtr r = IndexReader::open(directory, true); - if (r->numDocs() != 100) + if (r->numDocs() != 100) { FAIL() << "num docs failure"; + } r->close(); } }; // Run one indexer and 2 searchers against single index as stress test. -static void runTest(const DirectoryPtr& directory) -{ +static void runTest(const DirectoryPtr& directory) { Collection threads(Collection::newInstance(4)); AnalyzerPtr analyzer = newLucene(); @@ -164,13 +146,13 @@ static void runTest(const DirectoryPtr& directory) writer->setMergeFactor(3); // Establish a base index of 100 docs - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { DocumentPtr d = newLucene(); d->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); d->add(newLucene(L"contents", intToEnglish(i), Field::STORE_NO, Field::INDEX_ANALYZED)); - if ((i - 1) % 7 == 0) + if ((i - 1) % 7 == 0) { writer->commit(); + } writer->addDocument(d); } writer->commit(); @@ -209,16 +191,14 @@ static void runTest(const DirectoryPtr& directory) } /// Run above stress test against RAMDirectory. -TEST_F(AtomicUpdateTest, testAtomicUpdatesRAMDirectory) -{ +TEST_F(AtomicUpdateTest, testAtomicUpdatesRAMDirectory) { DirectoryPtr directory = newLucene(); runTest(directory); directory->close(); } /// Run above stress test against FSDirectory -TEST_F(AtomicUpdateTest, testAtomicUpdatesFSDirectory) -{ +TEST_F(AtomicUpdateTest, testAtomicUpdatesFSDirectory) { String dirPath(getTempDir(L"lucene.test.atomic")); DirectoryPtr directory = FSDirectory::open(dirPath); runTest(directory); diff --git a/src/test/index/BackwardsCompatibilityTest.cpp b/src/test/index/BackwardsCompatibilityTest.cpp index dfeff8ee..89630d44 100644 --- a/src/test/index/BackwardsCompatibilityTest.cpp +++ b/src/test/index/BackwardsCompatibilityTest.cpp @@ -35,24 +35,22 @@ typedef LuceneTestFixture BackwardsCompatibilityTest; /// Verify we can read the pre-2.1 file format, do searches against it, and add documents to it. -static String fullDir(const String& dirName) -{ +static String fullDir(const String& dirName) { return FileUtils::joinPath(getTempDir(), dirName); } -static void rmDir(const String& dirName) -{ +static void rmDir(const String& dirName) { FileUtils::removeDirectory(FileUtils::joinPath(getTempDir(), dirName)); } -static void addDoc(const IndexWriterPtr& writer, int32_t id) -{ +static void addDoc(const IndexWriterPtr& writer, int32_t id) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", StringUtils::toString(id), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); const uint8_t utf8Field[] = {0x4c, 0x75, 0xf0, 0x9d, 0x84, 0x9e, 0x63, 0x65, 0xf0, 0x9d, 0x85, 0xa0, 0x6e, 0x65, - 0x20, 0x00, 0x20, 0xe2, 0x98, 0xa0, 0x20, 0x61, 0x62, 0xf1, 0x95, 0xb0, 0x97, 0x63, 0x64}; + 0x20, 0x00, 0x20, 0xe2, 0x98, 0xa0, 0x20, 0x61, 0x62, 0xf1, 0x95, 0xb0, 0x97, 0x63, 0x64 + }; const uint8_t utf8Field2[] = {0x66, 0x69, 0x65, 0xe2, 0xb1, 0xb7, 0x6c, 0x64}; @@ -68,8 +66,7 @@ static void addDoc(const IndexWriterPtr& writer, int32_t id) writer->addDocument(doc); } -static void addNoProxDoc(const IndexWriterPtr& writer) -{ +static void addNoProxDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"content3", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED); f->setOmitTermFreqAndPositions(true); @@ -80,8 +77,7 @@ static void addNoProxDoc(const IndexWriterPtr& writer) writer->addDocument(doc); } -static void createIndex(const String& dirName, bool doCFS) -{ +static void createIndex(const String& dirName, bool doCFS) { FileUtils::removeDirectory(dirName); String fullName(fullDir(dirName)); @@ -90,8 +86,9 @@ static void createIndex(const String& dirName, bool doCFS) writer->setUseCompoundFile(doCFS); writer->setMaxBufferedDocs(10); - for (int32_t i = 0; i < 35; ++i) + for (int32_t i = 0; i < 35; ++i) { addDoc(writer, i); + } EXPECT_EQ(35, writer->maxDoc()); writer->close(); @@ -114,15 +111,13 @@ static void createIndex(const String& dirName, bool doCFS) reader->close(); } -static void copyIndex(const String& dirName) -{ +static void copyIndex(const String& dirName) { String dirSource(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"legacyindex"), dirName)); String dirDest(FileUtils::joinPath(getTempDir(), dirName)); FileUtils::copyDirectory(dirSource, dirDest); } -static const wchar_t* oldNames[] = -{ +static const wchar_t* oldNames[] = { L"19.cfs", L"19.nocfs", L"20.cfs", @@ -140,27 +135,24 @@ static const wchar_t* oldNames[] = }; static const int32_t oldNamesLength = SIZEOF_ARRAY(oldNames); -namespace CheckCompressedFields -{ - class CompressedFieldSelector : public FieldSelector - { - public: - virtual ~CompressedFieldSelector() - { - }; - - LUCENE_CLASS(CompressedFieldSelector); - - public: - virtual FieldSelectorResult accept(const String& fieldName) - { - return fieldName == L"compressed" ? FieldSelector::SELECTOR_SIZE : FieldSelector::SELECTOR_LOAD; - } +namespace CheckCompressedFields { + +class CompressedFieldSelector : public FieldSelector { +public: + virtual ~CompressedFieldSelector() { }; + + LUCENE_CLASS(CompressedFieldSelector); + +public: + virtual FieldSelectorResult accept(const String& fieldName) { + return fieldName == L"compressed" ? FieldSelector::SELECTOR_SIZE : FieldSelector::SELECTOR_LOAD; + } +}; + } -void checkCompressedFields29(const DirectoryPtr& dir, bool shouldStillBeCompressed) -{ +void checkCompressedFields29(const DirectoryPtr& dir, bool shouldStillBeCompressed) { int32_t count = 0; static String TEXT_TO_COMPRESS = L"this is a compressed field and should appear in 3.0 as an uncompressed field after merge"; int32_t TEXT_PLAIN_LENGTH = TEXT_TO_COMPRESS.length() * 2; @@ -171,36 +163,30 @@ void checkCompressedFields29(const DirectoryPtr& dir, bool shouldStillBeCompress IndexReaderPtr reader = IndexReader::open(dir, true); LuceneException finally; - try - { + try { // look into sub readers and check if raw merge is on/off Collection readers = Collection::newInstance(); ReaderUtil::gatherSubReaders(readers, reader); - for (Collection::iterator ir = readers.begin(); ir != readers.end(); ++ir) - { + for (Collection::iterator ir = readers.begin(); ir != readers.end(); ++ir) { FieldsReaderPtr fr = boost::dynamic_pointer_cast(*ir)->getFieldsReader(); // for a 2.9 index, FieldsReader.canReadRawDocs() must be false and other way round for a trunk index EXPECT_NE(shouldStillBeCompressed, fr->canReadRawDocs()); } // test that decompression works correctly - for (int32_t i = 0; i < reader->maxDoc(); ++i) - { - if (!reader->isDeleted(i)) - { + for (int32_t i = 0; i < reader->maxDoc(); ++i) { + if (!reader->isDeleted(i)) { DocumentPtr d = reader->document(i); - if (!d->get(L"content3").empty()) + if (!d->get(L"content3").empty()) { continue; + } ++count; FieldablePtr compressed = d->getFieldable(L"compressed"); - if (StringUtils::toInt(d->get(L"id")) % 2 == 0) - { + if (StringUtils::toInt(d->get(L"id")) % 2 == 0) { EXPECT_TRUE(!compressed->isBinary()); EXPECT_EQ(TEXT_TO_COMPRESS, compressed->stringValue()); // correctly decompressed string - } - else - { + } else { EXPECT_TRUE(compressed->isBinary()); EXPECT_TRUE(std::memcmp(BINARY_TO_COMPRESS, compressed->getBinaryValue().get(), BINARY_PLAIN_LENGTH) == 0); // correctly decompressed binary } @@ -208,13 +194,12 @@ void checkCompressedFields29(const DirectoryPtr& dir, bool shouldStillBeCompress } // check if field was decompressed after optimize - for (int32_t i = 0; i < reader->maxDoc(); ++i) - { - if (!reader->isDeleted(i)) - { + for (int32_t i = 0; i < reader->maxDoc(); ++i) { + if (!reader->isDeleted(i)) { DocumentPtr d = reader->document(i, newLucene()); - if (!d->get(L"content3").empty()) + if (!d->get(L"content3").empty()) { continue; + } ++count; // read the size from the binary value using DataInputStream (this prevents us from doing the shift ops ourselves) uint8_t* ds = d->getFieldable(L"compressed")->getBinaryValue().get(); @@ -223,34 +208,30 @@ void checkCompressedFields29(const DirectoryPtr& dir, bool shouldStillBeCompress bool binary = (StringUtils::toInt(d->get(L"id")) % 2 > 0); int32_t shouldSize = shouldStillBeCompressed ? compressedSize : (binary ? BINARY_PLAIN_LENGTH : TEXT_PLAIN_LENGTH); EXPECT_EQ(shouldSize, actualSize); - if (!shouldStillBeCompressed) + if (!shouldStillBeCompressed) { EXPECT_NE(compressedSize, actualSize); + } } } EXPECT_EQ(34 * 2, count); // correct number of tests - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } reader->close(); finally.throwException(); } -static void testHits(Collection hits, int32_t expectedCount, const IndexReaderPtr& reader) -{ +static void testHits(Collection hits, int32_t expectedCount, const IndexReaderPtr& reader) { int32_t hitCount = hits.size(); EXPECT_EQ(expectedCount, hitCount); - for (int32_t i = 0; i < hitCount; ++i) - { + for (int32_t i = 0; i < hitCount; ++i) { reader->document(hits[i]->doc); reader->getTermFreqVectors(hits[i]->doc); } } -static void searchIndex(const String& dirName, const String& oldName) -{ +static void searchIndex(const String& dirName, const String& oldName) { String dirPath = fullDir(dirName); DirectoryPtr dir = FSDirectory::open(dirPath); @@ -260,7 +241,8 @@ static void searchIndex(const String& dirName, const String& oldName) checkIndex(dir); const uint8_t utf8Field[] = {0x4c, 0x75, 0xf0, 0x9d, 0x84, 0x9e, 0x63, 0x65, 0xf0, 0x9d, 0x85, 0xa0, 0x6e, 0x65, - 0x20, 0x00, 0x20, 0xe2, 0x98, 0xa0, 0x20, 0x61, 0x62, 0xf1, 0x95, 0xb0, 0x97, 0x63, 0x64}; + 0x20, 0x00, 0x20, 0xe2, 0x98, 0xa0, 0x20, 0x61, 0x62, 0xf1, 0x95, 0xb0, 0x97, 0x63, 0x64 + }; const uint8_t utf8Field2[] = {0x66, 0x69, 0x65, 0xe2, 0xb1, 0xb7, 0x6c, 0x64}; @@ -271,17 +253,13 @@ static void searchIndex(const String& dirName, const String& oldName) const wchar_t _zeroField[] = {0x0000}; String zeroField(_zeroField, SIZEOF_ARRAY(_zeroField)); - for (int32_t i = 0; i < 35; ++i) - { - if (!reader->isDeleted(i)) - { + for (int32_t i = 0; i < 35; ++i) { + if (!reader->isDeleted(i)) { DocumentPtr d = reader->document(i); Collection fields = d->getFields(); if (!boost::starts_with(oldName, L"19.") && !boost::starts_with(oldName, L"20.") && - !boost::starts_with(oldName, L"21.") && !boost::starts_with(oldName, L"22.")) - { - if (!d->getField(L"content3")) - { + !boost::starts_with(oldName, L"21.") && !boost::starts_with(oldName, L"22.")) { + if (!d->getField(L"content3")) { int32_t numFields = boost::starts_with(oldName, L"29.") ? 7 : 5; EXPECT_EQ(numFields, fields.size()); @@ -301,9 +279,7 @@ static void searchIndex(const String& dirName, const String& oldName) EXPECT_EQ(L"field with non-ascii name", f->stringValue()); } } - } - else - { + } else { // Only ID 7 is deleted EXPECT_EQ(7, i); } @@ -318,8 +294,7 @@ static void searchIndex(const String& dirName, const String& oldName) testHits(hits, 34, searcher->getIndexReader()); if (!boost::starts_with(oldName, L"19.") && !boost::starts_with(oldName, L"20.") && - !boost::starts_with(oldName, L"21.") && !boost::starts_with(oldName, L"22.")) - { + !boost::starts_with(oldName, L"21.") && !boost::starts_with(oldName, L"22.")) { // Test on indices >= 2.3 hits = searcher->search(newLucene(newLucene(L"utf8", zeroField)), FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(34, hits.size()); @@ -334,8 +309,7 @@ static void searchIndex(const String& dirName, const String& oldName) } // Open pre-lockless index, add docs, do a delete and setNorm, and search -static void changeIndexNoAdds(const String& dirName) -{ +static void changeIndexNoAdds(const String& dirName) { String dirPath = fullDir(dirName); DirectoryPtr dir = FSDirectory::open(dirPath); @@ -382,8 +356,7 @@ static void changeIndexNoAdds(const String& dirName) } // Open pre-lockless index, add docs, do a delete and setNorm, and search -static void changeIndexWithAdds(const String& dirName) -{ +static void changeIndexWithAdds(const String& dirName) { String origDirName(dirName); String dirPath = fullDir(dirName); @@ -393,8 +366,9 @@ static void changeIndexWithAdds(const String& dirName) IndexWriterPtr writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthUNLIMITED); // add 10 docs - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { addDoc(writer, 35 + i); + } // make sure writer sees right total - writer seems not to know about deletes in .del? int32_t dirNumber = StringUtils::toInt(dirName.substr(0, 2)); @@ -444,32 +418,27 @@ static void changeIndexWithAdds(const String& dirName) dir->close(); } -TEST_F(BackwardsCompatibilityTest, testCreateCFS) -{ +TEST_F(BackwardsCompatibilityTest, testCreateCFS) { String dirName(L"testindex.cfs"); createIndex(dirName, true); rmDir(dirName); } -TEST_F(BackwardsCompatibilityTest, testCreateNoCFS) -{ +TEST_F(BackwardsCompatibilityTest, testCreateNoCFS) { String dirName(L"testindex.nocfs"); createIndex(dirName, true); rmDir(dirName); } -TEST_F(BackwardsCompatibilityTest, testOptimizeOldIndex) -{ +TEST_F(BackwardsCompatibilityTest, testOptimizeOldIndex) { int32_t hasTested29 = 0; - for (int32_t i = 0; i < oldNamesLength; ++i) - { + for (int32_t i = 0; i < oldNamesLength; ++i) { copyIndex(oldNames[i]); String dirName(fullDir(oldNames[i])); DirectoryPtr dir = FSDirectory::open(dirName); - if (boost::starts_with(oldNames[i], L"29.")) - { + if (boost::starts_with(oldNames[i], L"29.")) { checkCompressedFields29(dir, true); ++hasTested29; } @@ -480,8 +449,7 @@ TEST_F(BackwardsCompatibilityTest, testOptimizeOldIndex) checkIndex(dir); - if (boost::starts_with(oldNames[i], L"29.")) - { + if (boost::starts_with(oldNames[i], L"29.")) { checkCompressedFields29(dir, false); ++hasTested29; } @@ -493,10 +461,8 @@ TEST_F(BackwardsCompatibilityTest, testOptimizeOldIndex) EXPECT_EQ(4, hasTested29); // test for compressed field should have run 4 times } -TEST_F(BackwardsCompatibilityTest, testSearchOldIndex) -{ - for (int32_t i = 0; i < oldNamesLength; ++i) - { +TEST_F(BackwardsCompatibilityTest, testSearchOldIndex) { + for (int32_t i = 0; i < oldNamesLength; ++i) { copyIndex(oldNames[i]); String dirName(fullDir(oldNames[i])); searchIndex(oldNames[i], oldNames[i]); @@ -504,10 +470,8 @@ TEST_F(BackwardsCompatibilityTest, testSearchOldIndex) } } -TEST_F(BackwardsCompatibilityTest, testIndexOldIndexNoAdds) -{ - for (int32_t i = 0; i < oldNamesLength; ++i) - { +TEST_F(BackwardsCompatibilityTest, testIndexOldIndexNoAdds) { + for (int32_t i = 0; i < oldNamesLength; ++i) { copyIndex(oldNames[i]); String dirName(fullDir(oldNames[i])); changeIndexNoAdds(oldNames[i]); @@ -515,10 +479,8 @@ TEST_F(BackwardsCompatibilityTest, testIndexOldIndexNoAdds) } } -TEST_F(BackwardsCompatibilityTest, testIndexOldIndex) -{ - for (int32_t i = 0; i < oldNamesLength; ++i) - { +TEST_F(BackwardsCompatibilityTest, testIndexOldIndex) { + for (int32_t i = 0; i < oldNamesLength; ++i) { copyIndex(oldNames[i]); String dirName(fullDir(oldNames[i])); changeIndexWithAdds(oldNames[i]); @@ -527,21 +489,20 @@ TEST_F(BackwardsCompatibilityTest, testIndexOldIndex) } // Verifies that the expected file names were produced -TEST_F(BackwardsCompatibilityTest, testExactFileNames) -{ +TEST_F(BackwardsCompatibilityTest, testExactFileNames) { String outputDir = L"lucene.backwardscompat0.index"; rmDir(outputDir); LuceneException finally; - try - { + try { DirectoryPtr dir = FSDirectory::open(fullDir(outputDir)); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setRAMBufferSizeMB(16.0); - for (int32_t i = 0; i < 35; ++i) + for (int32_t i = 0; i < 35; ++i) { addDoc(writer, i); + } EXPECT_EQ(35, writer->maxDoc()); // doc count writer->close(); @@ -560,11 +521,9 @@ TEST_F(BackwardsCompatibilityTest, testExactFileNames) FieldInfosPtr fieldInfos = newLucene(cfsReader, L"_0.fnm"); int32_t contentFieldIndex = -1; - for (int32_t i = 0; i < fieldInfos->size(); ++i) - { + for (int32_t i = 0; i < fieldInfos->size(); ++i) { FieldInfoPtr fi = fieldInfos->fieldInfo(i); - if (fi->name == L"content") - { + if (fi->name == L"content") { contentFieldIndex = i; break; } @@ -586,9 +545,7 @@ TEST_F(BackwardsCompatibilityTest, testExactFileNames) EXPECT_EQ(expected, actual); dir->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } rmDir(outputDir); diff --git a/src/test/index/ByteSlicesTest.cpp b/src/test/index/ByteSlicesTest.cpp index 009f4721..9e4a0115 100644 --- a/src/test/index/ByteSlicesTest.cpp +++ b/src/test/index/ByteSlicesTest.cpp @@ -20,16 +20,13 @@ using namespace Lucene; DECLARE_SHARED_PTR(TestByteBlockAllocator) -class TestByteBlockAllocator : public ByteBlockPoolAllocatorBase -{ +class TestByteBlockAllocator : public ByteBlockPoolAllocatorBase { public: - TestByteBlockAllocator() - { + TestByteBlockAllocator() { this->freeByteBlocks = Collection::newInstance(); } - virtual ~TestByteBlockAllocator() - { + virtual ~TestByteBlockAllocator() { } LUCENE_CLASS(TestByteBlockAllocator); @@ -38,41 +35,38 @@ class TestByteBlockAllocator : public ByteBlockPoolAllocatorBase Collection freeByteBlocks; public: - virtual ByteArray getByteBlock(bool trackAllocations) - { + virtual ByteArray getByteBlock(bool trackAllocations) { SyncLock syncLock(this); int32_t size = freeByteBlocks.size(); ByteArray b; - if (size == 0) - { + if (size == 0) { b = ByteArray::newInstance(DocumentsWriter::BYTE_BLOCK_SIZE); MiscUtils::arrayFill(b.get(), 0, b.size(), 0); - } - else + } else { b = freeByteBlocks.removeLast(); + } return b; } - virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end) - { + virtual void recycleByteBlocks(Collection blocks, int32_t start, int32_t end) { SyncLock syncLock(this); - for (int32_t i = start; i < end; ++i) + for (int32_t i = start; i < end; ++i) { freeByteBlocks.add(blocks[i]); + } } - virtual void recycleByteBlocks(Collection blocks) - { + virtual void recycleByteBlocks(Collection blocks) { SyncLock syncLock(this); int32_t size = blocks.size(); - for (int32_t i = 0; i < size; ++i) + for (int32_t i = 0; i < size; ++i) { freeByteBlocks.add(blocks[i]); + } } }; typedef LuceneTestFixture ByteSlicesTest; -TEST_F(ByteSlicesTest, testBasic) -{ +TEST_F(ByteSlicesTest, testBasic) { ByteBlockPoolPtr pool = newLucene(newLucene(), false); int32_t NUM_STREAM = 25; @@ -86,55 +80,54 @@ TEST_F(ByteSlicesTest, testBasic) RandomPtr r = newLucene(); ByteSliceReaderPtr reader = newLucene(); - for (int32_t ti = 0; ti < 100; ++ti) - { - for (int32_t stream = 0; stream < NUM_STREAM; ++stream) - { + for (int32_t ti = 0; ti < 100; ++ti) { + for (int32_t stream = 0; stream < NUM_STREAM; ++stream) { starts[stream] = -1; counters[stream] = 0; } bool debug = false; - for (int32_t iter = 0; iter < 10000; ++iter) - { + for (int32_t iter = 0; iter < 10000; ++iter) { int32_t stream = r->nextInt(NUM_STREAM); - if (debug) + if (debug) { std::wcout << L"write stream=" << stream << L"\n"; + } - if (starts[stream] == -1) - { + if (starts[stream] == -1) { int32_t spot = pool->newSlice(ByteBlockPool::FIRST_LEVEL_SIZE()); uptos[stream] = spot + pool->byteOffset; starts[stream] = uptos[stream]; - if (debug) + if (debug) { std::wcout << L" init to " << starts[stream] << L"\n"; + } } writer->init(uptos[stream]); int32_t numValue = r->nextInt(20); - for (int32_t j = 0; j < numValue; ++j) - { - if (debug) + for (int32_t j = 0; j < numValue; ++j) { + if (debug) { std::wcout << L" write " << (counters[stream] + j) << L"\n"; + } writer->writeVInt(counters[stream] + j); } counters[stream] += numValue; uptos[stream] = writer->getAddress(); - if (debug) + if (debug) { std::wcout << L" addr now " << uptos[stream] << L"\n"; + } } - for (int32_t stream = 0; stream < NUM_STREAM; ++stream) - { - if (debug) + for (int32_t stream = 0; stream < NUM_STREAM; ++stream) { + if (debug) { std::wcout << L" stream=" << stream << L" count=" << counters[stream] << L"\n"; + } - if (starts[stream] != uptos[stream]) - { + if (starts[stream] != uptos[stream]) { reader->init(pool, starts[stream], uptos[stream]); - for (int32_t j = 0; j < counters[stream]; ++j) + for (int32_t j = 0; j < counters[stream]; ++j) { EXPECT_EQ(j, reader->readVInt()); + } } } diff --git a/src/test/index/CheckIndexTest.cpp b/src/test/index/CheckIndexTest.cpp index 11911d48..f7b3b4b3 100644 --- a/src/test/index/CheckIndexTest.cpp +++ b/src/test/index/CheckIndexTest.cpp @@ -19,15 +19,15 @@ using namespace Lucene; typedef LuceneTestFixture CheckIndexTest; -TEST_F(CheckIndexTest, testDeletedDocs) -{ +TEST_F(CheckIndexTest, testDeletedDocs) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - for (int32_t i = 0; i < 19; ++i) + for (int32_t i = 0; i < 19; ++i) { writer->addDocument(doc); + } writer->close(); IndexReaderPtr reader = IndexReader::open(dir, false); reader->deleteDocument(5); diff --git a/src/test/index/CompoundFileTest.cpp b/src/test/index/CompoundFileTest.cpp index fc383f9b..7addc2dd 100644 --- a/src/test/index/CompoundFileTest.cpp +++ b/src/test/index/CompoundFileTest.cpp @@ -19,11 +19,9 @@ using namespace Lucene; -class CompoundFileTest : public LuceneTestFixture -{ +class CompoundFileTest : public LuceneTestFixture { public: - CompoundFileTest() - { + CompoundFileTest() { indexDir = FileUtils::joinPath(getTempDir(), L"testIndex"); FileUtils::removeDirectory(indexDir); @@ -31,8 +29,7 @@ class CompoundFileTest : public LuceneTestFixture dir = newLucene(indexDir); } - virtual ~CompoundFileTest() - { + virtual ~CompoundFileTest() { dir->close(); FileUtils::removeDirectory(indexDir); } @@ -43,28 +40,25 @@ class CompoundFileTest : public LuceneTestFixture public: /// Creates a file of the specified size with random data. - void createRandomFile(const DirectoryPtr& dir, const String& name, int32_t size) - { + void createRandomFile(const DirectoryPtr& dir, const String& name, int32_t size) { IndexOutputPtr os = dir->createOutput(name); RandomPtr r = newLucene(); - for (int32_t i = 0; i < size; ++i) + for (int32_t i = 0; i < size; ++i) { os->writeByte((uint8_t)r->nextInt(256)); + } os->close(); } - void createSequenceFile(const DirectoryPtr& dir, const String& name, uint8_t start, int32_t size) - { + void createSequenceFile(const DirectoryPtr& dir, const String& name, uint8_t start, int32_t size) { IndexOutputPtr os = dir->createOutput(name); - for (int32_t i = 0; i < size; ++i) - { + for (int32_t i = 0; i < size; ++i) { os->writeByte(start); ++start; } os->close(); } - void checkSameStreams(const IndexInputPtr& expected, const IndexInputPtr& test) - { + void checkSameStreams(const IndexInputPtr& expected, const IndexInputPtr& test) { EXPECT_TRUE(expected); EXPECT_TRUE(test); EXPECT_EQ(expected->length(), test->length()); @@ -74,8 +68,7 @@ class CompoundFileTest : public LuceneTestFixture ByteArray testBuffer(ByteArray::newInstance(expectedBuffer.size())); int64_t remainder = expected->length() - expected->getFilePointer(); - while (remainder > 0) - { + while (remainder > 0) { int32_t readLen = std::min((int32_t)remainder, expectedBuffer.size()); expected->readBytes(expectedBuffer.get(), 0, readLen); test->readBytes(testBuffer.get(), 0, readLen); @@ -84,18 +77,15 @@ class CompoundFileTest : public LuceneTestFixture } } - void checkSameStreams(const IndexInputPtr& expected, const IndexInputPtr& actual, int64_t seekTo) - { - if (seekTo >= 0 && seekTo < (int64_t)expected->length()) - { + void checkSameStreams(const IndexInputPtr& expected, const IndexInputPtr& actual, int64_t seekTo) { + if (seekTo >= 0 && seekTo < (int64_t)expected->length()) { expected->seek(seekTo); actual->seek(seekTo); checkSameStreams(expected, actual); } } - void checkSameSeekBehavior(const IndexInputPtr& expected, const IndexInputPtr& actual) - { + void checkSameSeekBehavior(const IndexInputPtr& expected, const IndexInputPtr& actual) { // seek to 0 int64_t point = 0; checkSameStreams(expected, actual, point); @@ -121,61 +111,53 @@ class CompoundFileTest : public LuceneTestFixture checkSameStreams(expected, actual, point); } - void checkEqualArrays(ByteArray expected, ByteArray test, int32_t start, int32_t length) - { + void checkEqualArrays(ByteArray expected, ByteArray test, int32_t start, int32_t length) { EXPECT_TRUE(expected); EXPECT_TRUE(test); - for (int32_t i = start; i < length; ++i) + for (int32_t i = start; i < length; ++i) { EXPECT_EQ(expected[i], test[i]); + } } /// Setup a larger compound file with a number of components, each of which is a sequential file (so that we can /// easily tell that we are reading in the right byte). The methods sets up 20 files - f0 to f19, the size of each /// file is 1000 bytes. - void setUpLarger() - { + void setUpLarger() { CompoundFileWriterPtr cw = newLucene(dir, L"f.comp"); - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { createSequenceFile(dir, L"f" + StringUtils::toString(i), 0, 2000); cw->addFile(L"f" + StringUtils::toString(i)); } cw->close(); } - bool isCSIndexInputOpen(const IndexInputPtr& is) - { - if (MiscUtils::typeOf(is)) - { + bool isCSIndexInputOpen(const IndexInputPtr& is) { + if (MiscUtils::typeOf(is)) { CSIndexInputPtr cis = boost::dynamic_pointer_cast(is); return isSimpleFSIndexInputOpen(cis->base); - } - else + } else { return false; + } } - bool isSimpleFSIndexInputOpen(const IndexInputPtr& is) - { - if (MiscUtils::typeOf(is)) - { + bool isSimpleFSIndexInputOpen(const IndexInputPtr& is) { + if (MiscUtils::typeOf(is)) { SimpleFSIndexInputPtr fis = boost::dynamic_pointer_cast(is); return fis->isValid(); - } - else + } else { return false; + } } }; /// This test creates compound file based on a single file. Files of different sizes are tested: 0, 1, 10, 100 bytes. -TEST_F(CompoundFileTest, testSingleFile) -{ +TEST_F(CompoundFileTest, testSingleFile) { IntArray data(IntArray::newInstance(4)); data[0] = 0; data[1] = 1; data[2] = 10; data[3] = 100; - for (int32_t i = 0; i < data.size(); ++i) - { + for (int32_t i = 0; i < data.size(); ++i) { String name = L"t" + StringUtils::toString(data[i]); createSequenceFile(dir, name, 0, data[i]); CompoundFileWriterPtr csw = newLucene(dir, name + L".cfs"); @@ -194,8 +176,7 @@ TEST_F(CompoundFileTest, testSingleFile) } /// This test creates compound file based on two files. -TEST_F(CompoundFileTest, testTwoFiles) -{ +TEST_F(CompoundFileTest, testTwoFiles) { createSequenceFile(dir, L"d1", 0, 15); createSequenceFile(dir, L"d2", 0, 114); @@ -224,8 +205,7 @@ TEST_F(CompoundFileTest, testTwoFiles) /// This test creates a compound file based on a large number of files of various length. The file content is generated randomly. /// The sizes range from 0 to 1Mb. Some of the sizes are selected to test the buffering logic in the file reading code. /// For this the chunk variable is set to the length of the buffer used internally by the compound file logic. -TEST_F(CompoundFileTest, testRandomFiles) -{ +TEST_F(CompoundFileTest, testRandomFiles) { // Setup the test segment String segment = L"test"; int32_t chunk = 1024; // internal buffer size used by the stream @@ -250,18 +230,25 @@ TEST_F(CompoundFileTest, testRandomFiles) CompoundFileWriterPtr csw = newLucene(dir, L"test.cfs"); Collection data(Collection::newInstance()); - data.add(L".zero"); data.add(L".one"); data.add(L".ten"); - data.add(L".hundred"); data.add(L".big1"); data.add(L".big2"); - data.add(L".big3"); data.add(L".big4"); data.add(L".big5"); - data.add(L".big6"); data.add(L".big7"); - - for (Collection::iterator name = data.begin(); name != data.end(); ++name) + data.add(L".zero"); + data.add(L".one"); + data.add(L".ten"); + data.add(L".hundred"); + data.add(L".big1"); + data.add(L".big2"); + data.add(L".big3"); + data.add(L".big4"); + data.add(L".big5"); + data.add(L".big6"); + data.add(L".big7"); + + for (Collection::iterator name = data.begin(); name != data.end(); ++name) { csw->addFile(segment + *name); + } csw->close(); CompoundFileReaderPtr csr = newLucene(dir, L"test.cfs"); - for (Collection::iterator name = data.begin(); name != data.end(); ++name) - { + for (Collection::iterator name = data.begin(); name != data.end(); ++name) { IndexInputPtr check = dir->openInput(segment + *name); IndexInputPtr test = csr->openInput(segment + *name); checkSameStreams(check, test); @@ -272,12 +259,12 @@ TEST_F(CompoundFileTest, testRandomFiles) csr->close(); } -TEST_F(CompoundFileTest, testReadAfterClose) -{ +TEST_F(CompoundFileTest, testReadAfterClose) { // Setup the test file - we need more than 1024 bytes IndexOutputPtr os = dir->createOutput(L"test"); - for (int32_t i = 0; i < 2000; ++i) + for (int32_t i = 0; i < 2000; ++i) { os->writeByte((uint8_t)i); + } os->close(); IndexInputPtr in = dir->openInput(L"test"); @@ -294,18 +281,14 @@ TEST_F(CompoundFileTest, testReadAfterClose) // ERROR: this call should fail, but succeeds for some reason as well in->seek(1099); - try - { + try { in->readByte(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } } -TEST_F(CompoundFileTest, testClonedStreamsClosing) -{ +TEST_F(CompoundFileTest, testClonedStreamsClosing) { setUpLarger(); CompoundFileReaderPtr cr = newLucene(dir, L"f.comp"); @@ -355,8 +338,7 @@ TEST_F(CompoundFileTest, testClonedStreamsClosing) } /// This test opens two files from a compound stream and verifies that their file positions are independent of each other. -TEST_F(CompoundFileTest, testRandomAccess) -{ +TEST_F(CompoundFileTest, testRandomAccess) { setUpLarger(); CompoundFileReaderPtr cr = newLucene(dir, L"f.comp"); @@ -434,8 +416,7 @@ TEST_F(CompoundFileTest, testRandomAccess) } /// This test opens two files from a compound stream and verifies that their file positions are independent of each other. -TEST_F(CompoundFileTest, testRandomAccessClones) -{ +TEST_F(CompoundFileTest, testRandomAccessClones) { setUpLarger(); CompoundFileReaderPtr cr = newLucene(dir, L"f.comp"); @@ -512,28 +493,23 @@ TEST_F(CompoundFileTest, testRandomAccessClones) cr->close(); } -TEST_F(CompoundFileTest, testFileNotFound) -{ +TEST_F(CompoundFileTest, testFileNotFound) { setUpLarger(); CompoundFileReaderPtr cr = newLucene(dir, L"f.comp"); IndexInputPtr e1; // Open two files - try - { + try { e1 = cr->openInput(L"bogus"); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } cr->close(); } -TEST_F(CompoundFileTest, testReadPastEOF) -{ +TEST_F(CompoundFileTest, testReadPastEOF) { setUpLarger(); CompoundFileReaderPtr cr = newLucene(dir, L"f.comp"); @@ -543,23 +519,17 @@ TEST_F(CompoundFileTest, testReadPastEOF) is->readBytes(b.get(), 0, 10); uint8_t test = 0; - try - { + try { test = is->readByte(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } is->seek(is->length() - 10); - try - { + try { is->readBytes(b.get(), 0, 50); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } @@ -568,14 +538,14 @@ TEST_F(CompoundFileTest, testReadPastEOF) } /// This test that writes larger than the size of the buffer output will correctly increment the file pointer. -TEST_F(CompoundFileTest, testLargeWrites) -{ +TEST_F(CompoundFileTest, testLargeWrites) { IndexOutputPtr os = dir->createOutput(L"testBufferStart.txt"); RandomPtr r = newLucene(); ByteArray largeBuf(ByteArray::newInstance(2048)); - for (int32_t i = 0; i < largeBuf.size(); ++i) + for (int32_t i = 0; i < largeBuf.size(); ++i) { largeBuf[i] = (uint8_t)r->nextInt(256); + } int64_t currentPos = os->getFilePointer(); os->writeBytes(largeBuf.get(), largeBuf.size()); diff --git a/src/test/index/ConcurrentMergeSchedulerTest.cpp b/src/test/index/ConcurrentMergeSchedulerTest.cpp index fa726b58..beb074d4 100644 --- a/src/test/index/ConcurrentMergeSchedulerTest.cpp +++ b/src/test/index/ConcurrentMergeSchedulerTest.cpp @@ -31,8 +31,7 @@ static bool mergeCalled = false; static bool mergeThreadCreated = false; static bool excCalled = false; -static void checkNoUnreferencedFiles(const DirectoryPtr& dir) -{ +static void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); infos->read(dir); @@ -48,74 +47,64 @@ static void checkNoUnreferencedFiles(const DirectoryPtr& dir) EXPECT_TRUE(startFiles.equals(endFiles)); } -namespace TestFlushException -{ - DECLARE_SHARED_PTR(FailOnlyOnFlush) - - class FailOnlyOnFlush : public MockDirectoryFailure - { - public: - FailOnlyOnFlush() - { - hitExc = false; - mainThread = LuceneThread::currentId(); - TestPoint::clear(); - } +namespace TestFlushException { - virtual ~FailOnlyOnFlush() - { - } +DECLARE_SHARED_PTR(FailOnlyOnFlush) - public: - bool hitExc; - int64_t mainThread; +class FailOnlyOnFlush : public MockDirectoryFailure { +public: + FailOnlyOnFlush() { + hitExc = false; + mainThread = LuceneThread::currentId(); + TestPoint::clear(); + } - public: - virtual void setDoFail() - { - MockDirectoryFailure::setDoFail(); - hitExc = false; - } + virtual ~FailOnlyOnFlush() { + } - virtual void clearDoFail() - { - MockDirectoryFailure::clearDoFail(); - this->doFail = false; - } +public: + bool hitExc; + int64_t mainThread; - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (this->doFail && mainThread == LuceneThread::currentId() && TestPoint::getTestPoint(L"doFlush")) - { - hitExc = true; - boost::throw_exception(IOException(L"now failing during flush")); - } - } - }; +public: + virtual void setDoFail() { + MockDirectoryFailure::setDoFail(); + hitExc = false; + } - DECLARE_SHARED_PTR(TestableIndexWriter) + virtual void clearDoFail() { + MockDirectoryFailure::clearDoFail(); + this->doFail = false; + } - class TestableIndexWriter : public IndexWriter - { - public: - TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (this->doFail && mainThread == LuceneThread::currentId() && TestPoint::getTestPoint(L"doFlush")) { + hitExc = true; + boost::throw_exception(IOException(L"now failing during flush")); } + } +}; - virtual ~TestableIndexWriter() - { - } +DECLARE_SHARED_PTR(TestableIndexWriter) + +class TestableIndexWriter : public IndexWriter { +public: + TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + } + + virtual ~TestableIndexWriter() { + } + + LUCENE_CLASS(TestableIndexWriter); - LUCENE_CLASS(TestableIndexWriter); +public: + using IndexWriter::flush; +}; - public: - using IndexWriter::flush; - }; } /// Make sure running background merges still work fine even when we are hitting exceptions during flushing. -TEST_F(ConcurrentMergeSchedulerTest, testFlushExceptions) -{ +TEST_F(ConcurrentMergeSchedulerTest, testFlushExceptions) { MockRAMDirectoryPtr directory = newLucene(); TestFlushException::FailOnlyOnFlushPtr failure = newLucene(); directory->failOn(failure); @@ -129,28 +118,22 @@ TEST_F(ConcurrentMergeSchedulerTest, testFlushExceptions) doc->add(idField); int32_t extraCount = 0; - for (int32_t i = 0; i < 10; ++i) - { - for (int32_t j = 0; j < 20; ++j) - { + for (int32_t i = 0; i < 10; ++i) { + for (int32_t j = 0; j < 20; ++j) { idField->setValue(StringUtils::toString(i * 20 + j)); writer->addDocument(doc); } // must cycle here because sometimes the merge flushes the doc we just added and so there's nothing to // flush, and we don't hit the exception - while (true) - { - try - { + while (true) { + try { writer->addDocument(doc); failure->setDoFail(); writer->flush(true, false, true); EXPECT_TRUE(!failure->hitExc); ++extraCount; - } - catch (LuceneException&) - { + } catch (LuceneException&) { failure->clearDoFail(); break; } @@ -165,8 +148,7 @@ TEST_F(ConcurrentMergeSchedulerTest, testFlushExceptions) } /// Test that deletes committed after a merge started and before it finishes, are correctly merged back -TEST_F(ConcurrentMergeSchedulerTest, testDeleteMerging) -{ +TEST_F(ConcurrentMergeSchedulerTest, testDeleteMerging) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -182,17 +164,14 @@ TEST_F(ConcurrentMergeSchedulerTest, testDeleteMerging) DocumentPtr doc = newLucene(); FieldPtr idField = newLucene(L"id", L"", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); doc->add(idField); - for (int32_t i = 0; i < 10; ++i) - { - for (int32_t j = 0; j < 100; ++j) - { + for (int32_t i = 0; i < 10; ++i) { + for (int32_t j = 0; j < 100; ++j) { idField->setValue(StringUtils::toString(i * 100 + j)); writer->addDocument(doc); } int32_t delID = i; - while (delID < 100 * (1 + i)) - { + while (delID < 100 * (1 + i)) { writer->deleteDocuments(newLucene(L"id", StringUtils::toString(delID))); delID += 10; } @@ -208,20 +187,17 @@ TEST_F(ConcurrentMergeSchedulerTest, testDeleteMerging) directory->close(); } -TEST_F(ConcurrentMergeSchedulerTest, testNoExtraFiles) -{ +TEST_F(ConcurrentMergeSchedulerTest, testNoExtraFiles) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 7; ++i) - { + for (int32_t i = 0; i < 7; ++i) { ConcurrentMergeSchedulerPtr cms = newLucene(); writer->setMergeScheduler(cms); writer->setMaxBufferedDocs(2); - for (int32_t j = 0; j < 21; ++j) - { + for (int32_t j = 0; j < 21; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -238,8 +214,7 @@ TEST_F(ConcurrentMergeSchedulerTest, testNoExtraFiles) directory->close(); } -TEST_F(ConcurrentMergeSchedulerTest, testNoWaitClose) -{ +TEST_F(ConcurrentMergeSchedulerTest, testNoWaitClose) { RAMDirectoryPtr directory = newLucene(); DocumentPtr doc = newLucene(); @@ -248,22 +223,19 @@ TEST_F(ConcurrentMergeSchedulerTest, testNoWaitClose) IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { ConcurrentMergeSchedulerPtr cms = newLucene(); writer->setMergeScheduler(cms); writer->setMaxBufferedDocs(2); writer->setMergeFactor(100); - for (int32_t j = 0; j < 201; ++j) - { + for (int32_t j = 0; j < 201; ++j) { idField->setValue(StringUtils::toString(i * 201 + j)); writer->addDocument(doc); } int32_t delID = i * 201; - for (int32_t j = 0; j < 20; ++j) - { + for (int32_t j = 0; j < 20; ++j) { writer->deleteDocuments(newLucene(L"id", StringUtils::toString(delID))); delID += 5; } @@ -291,75 +263,64 @@ TEST_F(ConcurrentMergeSchedulerTest, testNoWaitClose) LuceneThread::threadSleep(1000); } -namespace TestSubclassConcurrentMergeScheduler -{ - DECLARE_SHARED_PTR(MyMergeScheduler) +namespace TestSubclassConcurrentMergeScheduler { - class FailOnlyOnMerge : public MockDirectoryFailure - { - public: - FailOnlyOnMerge() - { - TestPoint::clear(); - } +DECLARE_SHARED_PTR(MyMergeScheduler) - virtual ~FailOnlyOnMerge() - { - } +class FailOnlyOnMerge : public MockDirectoryFailure { +public: + FailOnlyOnMerge() { + TestPoint::clear(); + } - public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (TestPoint::getTestPoint(L"doMerge")) - boost::throw_exception(IOException(L"now failing during merge")); - } - }; - - class MyMergeThread : public MergeThread - { - public: - MyMergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge) : MergeThread(merger, writer, startMerge) - { - mergeThreadCreated = true; - } + virtual ~FailOnlyOnMerge() { + } - virtual ~MyMergeThread() - { +public: + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (TestPoint::getTestPoint(L"doMerge")) { + boost::throw_exception(IOException(L"now failing during merge")); } - }; + } +}; - class MyMergeScheduler : public ConcurrentMergeScheduler - { - public: - virtual ~MyMergeScheduler() - { - } +class MyMergeThread : public MergeThread { +public: + MyMergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge) : MergeThread(merger, writer, startMerge) { + mergeThreadCreated = true; + } - LUCENE_CLASS(MyMergeScheduler); + virtual ~MyMergeThread() { + } +}; - protected: - virtual MergeThreadPtr getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge) - { - MergeThreadPtr thread = newLucene(shared_from_this(), writer, merge); - thread->setThreadPriority(getMergeThreadPriority()); - return thread; - } +class MyMergeScheduler : public ConcurrentMergeScheduler { +public: + virtual ~MyMergeScheduler() { + } - virtual void handleMergeException(const LuceneException& exc) - { - excCalled = true; - } + LUCENE_CLASS(MyMergeScheduler); + +protected: + virtual MergeThreadPtr getMergeThread(const IndexWriterPtr& writer, const OneMergePtr& merge) { + MergeThreadPtr thread = newLucene(shared_from_this(), writer, merge); + thread->setThreadPriority(getMergeThreadPriority()); + return thread; + } + + virtual void handleMergeException(const LuceneException& exc) { + excCalled = true; + } + + virtual void doMerge(const OneMergePtr& merge) { + mergeCalled = true; + ConcurrentMergeScheduler::doMerge(merge); + } +}; - virtual void doMerge(const OneMergePtr& merge) - { - mergeCalled = true; - ConcurrentMergeScheduler::doMerge(merge); - } - }; } -TEST_F(ConcurrentMergeSchedulerTest, testSubclassConcurrentMergeScheduler) -{ +TEST_F(ConcurrentMergeSchedulerTest, testSubclassConcurrentMergeScheduler) { MockRAMDirectoryPtr dir = newLucene(); dir->failOn(newLucene()); @@ -372,8 +333,9 @@ TEST_F(ConcurrentMergeSchedulerTest, testSubclassConcurrentMergeScheduler) writer->setMergeScheduler(ms); writer->setMaxBufferedDocs(2); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - for (int32_t i = 0; i < 20; ++i) + for (int32_t i = 0; i < 20; ++i) { writer->addDocument(doc); + } ms->sync(); writer->close(); diff --git a/src/test/index/CrashTest.cpp b/src/test/index/CrashTest.cpp index 0ad262de..8a06a12f 100644 --- a/src/test/index/CrashTest.cpp +++ b/src/test/index/CrashTest.cpp @@ -20,8 +20,7 @@ using namespace Lucene; typedef LuceneTestFixture CrashTest; -static IndexWriterPtr initIndex(const MockRAMDirectoryPtr& dir) -{ +static IndexWriterPtr initIndex(const MockRAMDirectoryPtr& dir) { dir->setLockFactory(NoLockFactory::getNoLockFactory()); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -32,19 +31,18 @@ static IndexWriterPtr initIndex(const MockRAMDirectoryPtr& dir) DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", L"0", Field::STORE_YES, Field::INDEX_ANALYZED)); - for (int32_t i = 0; i < 157; ++i) + for (int32_t i = 0; i < 157; ++i) { writer->addDocument(doc); + } return writer; } -static IndexWriterPtr initIndex() -{ +static IndexWriterPtr initIndex() { return initIndex(newLucene()); } -static void crash(const IndexWriterPtr& writer) -{ +static void crash(const IndexWriterPtr& writer) { MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); ConcurrentMergeSchedulerPtr cms = boost::dynamic_pointer_cast(writer->getMergeScheduler()); dir->crash(); @@ -52,8 +50,7 @@ static void crash(const IndexWriterPtr& writer) dir->clearCrash(); } -TEST_F(CrashTest, testCrashWhileIndexing) -{ +TEST_F(CrashTest, testCrashWhileIndexing) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); crash(writer); @@ -61,8 +58,7 @@ TEST_F(CrashTest, testCrashWhileIndexing) EXPECT_TRUE(reader->numDocs() < 157); } -TEST_F(CrashTest, testWriterAfterCrash) -{ +TEST_F(CrashTest, testWriterAfterCrash) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); dir->setPreventDoubleWrite(false); @@ -74,8 +70,7 @@ TEST_F(CrashTest, testWriterAfterCrash) EXPECT_TRUE(reader->numDocs() < 314); } -TEST_F(CrashTest, testCrashAfterReopen) -{ +TEST_F(CrashTest, testCrashAfterReopen) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(); @@ -87,8 +82,7 @@ TEST_F(CrashTest, testCrashAfterReopen) EXPECT_TRUE(reader->numDocs() >= 157); } -TEST_F(CrashTest, testCrashAfterClose) -{ +TEST_F(CrashTest, testCrashAfterClose) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(); @@ -98,8 +92,7 @@ TEST_F(CrashTest, testCrashAfterClose) EXPECT_EQ(157, reader->numDocs()); } -TEST_F(CrashTest, testCrashAfterCloseNoWait) -{ +TEST_F(CrashTest, testCrashAfterCloseNoWait) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(false); @@ -109,8 +102,7 @@ TEST_F(CrashTest, testCrashAfterCloseNoWait) EXPECT_EQ(157, reader->numDocs()); } -TEST_F(CrashTest, testCrashReaderDeletes) -{ +TEST_F(CrashTest, testCrashReaderDeletes) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(false); @@ -124,8 +116,7 @@ TEST_F(CrashTest, testCrashReaderDeletes) EXPECT_EQ(157, reader->numDocs()); } -TEST_F(CrashTest, testCrashReaderDeletesAfterClose) -{ +TEST_F(CrashTest, testCrashReaderDeletesAfterClose) { IndexWriterPtr writer = initIndex(); MockRAMDirectoryPtr dir = boost::dynamic_pointer_cast(writer->getDirectory()); writer->close(false); diff --git a/src/test/index/DeletionPolicyTest.cpp b/src/test/index/DeletionPolicyTest.cpp index 4f4d1674..6553304e 100644 --- a/src/test/index/DeletionPolicyTest.cpp +++ b/src/test/index/DeletionPolicyTest.cpp @@ -30,15 +30,13 @@ using namespace Lucene; typedef LuceneTestFixture DeletionPolicyTest; -static void verifyCommitOrder(Collection commits) -{ +static void verifyCommitOrder(Collection commits) { IndexCommitPtr firstCommit = commits[0]; int64_t last = SegmentInfos::generationFromSegmentsFileName(firstCommit->getSegmentsFileName()); EXPECT_EQ(last, firstCommit->getGeneration()); int64_t lastVersion = firstCommit->getVersion(); int64_t lastTimestamp = firstCommit->getTimestamp(); - for (int32_t i = 1; i < commits.size(); ++i) - { + for (int32_t i = 1; i < commits.size(); ++i) { IndexCommitPtr commit = commits[i]; int64_t now = SegmentInfos::generationFromSegmentsFileName(commit->getSegmentsFileName()); int64_t nowVersion = commit->getVersion(); @@ -53,8 +51,7 @@ static void verifyCommitOrder(Collection commits) } } -static void addDoc(const IndexWriterPtr& writer) -{ +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -65,17 +62,14 @@ DECLARE_SHARED_PTR(KeepNoneOnInitDeletionPolicy) DECLARE_SHARED_PTR(KeepLastNDeletionPolicy) DECLARE_SHARED_PTR(ExpirationTimeDeletionPolicy) -class DeletionPolicyKeepAllDeletionPolicy : public IndexDeletionPolicy -{ +class DeletionPolicyKeepAllDeletionPolicy : public IndexDeletionPolicy { public: - DeletionPolicyKeepAllDeletionPolicy() - { + DeletionPolicyKeepAllDeletionPolicy() { numOnInit = 0; numOnCommit = 0; } - virtual ~DeletionPolicyKeepAllDeletionPolicy() - { + virtual ~DeletionPolicyKeepAllDeletionPolicy() { } LUCENE_CLASS(DeletionPolicyKeepAllDeletionPolicy); @@ -86,14 +80,12 @@ class DeletionPolicyKeepAllDeletionPolicy : public IndexDeletionPolicy DirectoryPtr dir; public: - virtual void onInit(Collection commits) - { + virtual void onInit(Collection commits) { verifyCommitOrder(commits); ++numOnInit; } - virtual void onCommit(Collection commits) - { + virtual void onCommit(Collection commits) { IndexCommitPtr lastCommit = commits[commits.size() - 1]; IndexReaderPtr r = IndexReader::open(dir, true); EXPECT_EQ(r->isOptimized(), lastCommit->isOptimized()); @@ -104,17 +96,14 @@ class DeletionPolicyKeepAllDeletionPolicy : public IndexDeletionPolicy }; /// This is useful for adding to a big index when you know readers are not using it. -class KeepNoneOnInitDeletionPolicy : public IndexDeletionPolicy -{ +class KeepNoneOnInitDeletionPolicy : public IndexDeletionPolicy { public: - KeepNoneOnInitDeletionPolicy() - { + KeepNoneOnInitDeletionPolicy() { numOnInit = 0; numOnCommit = 0; } - virtual ~KeepNoneOnInitDeletionPolicy() - { + virtual ~KeepNoneOnInitDeletionPolicy() { } LUCENE_CLASS(KeepNoneOnInitDeletionPolicy); @@ -124,34 +113,30 @@ class KeepNoneOnInitDeletionPolicy : public IndexDeletionPolicy int32_t numOnCommit; public: - virtual void onInit(Collection commits) - { + virtual void onInit(Collection commits) { verifyCommitOrder(commits); ++numOnInit; // On init, delete all commit points - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { (*commit)->deleteCommit(); EXPECT_TRUE((*commit)->isDeleted()); } } - virtual void onCommit(Collection commits) - { + virtual void onCommit(Collection commits) { verifyCommitOrder(commits); int32_t size = commits.size(); // Delete all but last one - for (int32_t i = 0; i < size - 1; ++i) + for (int32_t i = 0; i < size - 1; ++i) { commits[i]->deleteCommit(); + } ++numOnCommit; } }; -class KeepLastNDeletionPolicy : public IndexDeletionPolicy -{ +class KeepLastNDeletionPolicy : public IndexDeletionPolicy { public: - KeepLastNDeletionPolicy(int32_t numToKeep) - { + KeepLastNDeletionPolicy(int32_t numToKeep) { this->numOnInit = 0; this->numOnCommit = 0; this->numToKeep = numToKeep; @@ -159,8 +144,7 @@ class KeepLastNDeletionPolicy : public IndexDeletionPolicy this->seen = HashSet::newInstance(); } - virtual ~KeepLastNDeletionPolicy() - { + virtual ~KeepLastNDeletionPolicy() { } LUCENE_CLASS(KeepLastNDeletionPolicy); @@ -173,35 +157,31 @@ class KeepLastNDeletionPolicy : public IndexDeletionPolicy HashSet seen; public: - virtual void onInit(Collection commits) - { + virtual void onInit(Collection commits) { verifyCommitOrder(commits); ++numOnInit; // do no deletions on init doDeletes(commits, false); } - virtual void onCommit(Collection commits) - { + virtual void onCommit(Collection commits) { verifyCommitOrder(commits); doDeletes(commits, true); } protected: - void doDeletes(Collection commits, bool isCommit) - { + void doDeletes(Collection commits, bool isCommit) { // Assert that we really are only called for each new commit - if (isCommit) - { + if (isCommit) { String fileName = commits[commits.size() - 1]->getSegmentsFileName(); - if (seen.contains(fileName)) + if (seen.contains(fileName)) { FAIL() << "onCommit was called twice on the same commit point"; + } seen.add(fileName); ++numOnCommit; } int32_t size = commits.size(); - for (int32_t i = 0; i < size - numToKeep; ++i) - { + for (int32_t i = 0; i < size - numToKeep; ++i) { commits[i]->deleteCommit(); ++numDelete; } @@ -209,18 +189,15 @@ class KeepLastNDeletionPolicy : public IndexDeletionPolicy }; /// Delete a commit only when it has been obsoleted by N seconds -class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy -{ +class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy { public: - ExpirationTimeDeletionPolicy(const DirectoryPtr& dir, double seconds) - { + ExpirationTimeDeletionPolicy(const DirectoryPtr& dir, double seconds) { this->dir = dir; this->expirationTimeSeconds = seconds; this->numDelete = 0; } - virtual ~ExpirationTimeDeletionPolicy() - { + virtual ~ExpirationTimeDeletionPolicy() { } LUCENE_CLASS(ExpirationTimeDeletionPolicy); @@ -231,14 +208,12 @@ class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy int32_t numDelete; public: - virtual void onInit(Collection commits) - { + virtual void onInit(Collection commits) { verifyCommitOrder(commits); onCommit(commits); } - virtual void onCommit(Collection commits) - { + virtual void onCommit(Collection commits) { verifyCommitOrder(commits); IndexCommitPtr lastCommit = commits[commits.size() - 1]; @@ -246,11 +221,9 @@ class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy // Any commit older than expireTime should be deleted double expireTime = dir->fileModified(lastCommit->getSegmentsFileName()) / 1000.0 - expirationTimeSeconds; - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { double modTime = dir->fileModified((*commit)->getSegmentsFileName()) / 1000.0; - if (*commit != lastCommit && modTime < expireTime) - { + if (*commit != lastCommit && modTime < expireTime) { (*commit)->deleteCommit(); ++numDelete; } @@ -259,8 +232,7 @@ class ExpirationTimeDeletionPolicy : public IndexDeletionPolicy }; /// Test "by time expiration" deletion policy -TEST_F(DeletionPolicyTest, testExpirationTimeDeletionPolicy) -{ +TEST_F(DeletionPolicyTest, testExpirationTimeDeletionPolicy) { const double SECONDS = 2.0; bool useCompoundFile = true; @@ -272,14 +244,14 @@ TEST_F(DeletionPolicyTest, testExpirationTimeDeletionPolicy) writer->close(); int64_t lastDeleteTime = 0; - for (int32_t i = 0; i < 7; ++i) - { + for (int32_t i = 0; i < 7; ++i) { // Record last time when writer performed deletes of past commits lastDeleteTime = MiscUtils::currentTimeMillis(); writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthUNLIMITED); writer->setUseCompoundFile(useCompoundFile); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { addDoc(writer); + } writer->close(); // Make sure to sleep long enough so that some commit points will be deleted @@ -295,18 +267,14 @@ TEST_F(DeletionPolicyTest, testExpirationTimeDeletionPolicy) String fileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen); dir->deleteFile(IndexFileNames::SEGMENTS_GEN()); - while (gen > 0) - { - try - { + while (gen > 0) { + try { IndexReaderPtr reader = IndexReader::open(dir, true); reader->close(); fileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen); int64_t modTime = dir->fileModified(fileName); EXPECT_TRUE(lastDeleteTime - modTime <= (SECONDS * 1000)); - } - catch (IOException&) - { + } catch (IOException&) { // OK break; } @@ -319,10 +287,8 @@ TEST_F(DeletionPolicyTest, testExpirationTimeDeletionPolicy) } /// Test a silly deletion policy that keeps all commits around. -TEST_F(DeletionPolicyTest, testDeletionPolicyKeepAllDeletionPolicy) -{ - for (int32_t pass = 0; pass < 2; ++pass) - { +TEST_F(DeletionPolicyTest, testDeletionPolicyKeepAllDeletionPolicy) { + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); // Never deletes a commit @@ -335,8 +301,9 @@ TEST_F(DeletionPolicyTest, testDeletionPolicyKeepAllDeletionPolicy) writer->setMaxBufferedDocs(10); writer->setUseCompoundFile(useCompoundFile); writer->setMergeScheduler(newLucene()); - for (int32_t i = 0; i < 107; ++i) + for (int32_t i = 0; i < 107; ++i) { addDoc(writer); + } writer->close(); @@ -356,8 +323,7 @@ TEST_F(DeletionPolicyTest, testDeletionPolicyKeepAllDeletionPolicy) EXPECT_EQ(3, commits.size()); // Make sure we can open a reader on each commit - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { IndexReaderPtr r = IndexReader::open(*commit, IndexDeletionPolicyPtr(), false); r->close(); } @@ -365,15 +331,13 @@ TEST_F(DeletionPolicyTest, testDeletionPolicyKeepAllDeletionPolicy) // Simplistic check: just verify all segments_N's still exist, and, I can open a reader on each dir->deleteFile(IndexFileNames::SEGMENTS_GEN()); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); - while (gen > 0) - { + while (gen > 0) { IndexReaderPtr reader = IndexReader::open(dir, true); reader->close(); dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); --gen; - if (gen > 0) - { + if (gen > 0) { // Now that we've removed a commit point, which should have orphan'd at least one index file. // Open and close a writer and check that it actually removed something int32_t preCount = dir->listAll().size(); @@ -389,8 +353,7 @@ TEST_F(DeletionPolicyTest, testDeletionPolicyKeepAllDeletionPolicy) } /// Uses DeletionPolicyKeepAllDeletionPolicy to keep all commits around, then, opens a new IndexWriter on a previous commit point. -TEST_F(DeletionPolicyTest, testOpenPriorSnapshot) -{ +TEST_F(DeletionPolicyTest, testOpenPriorSnapshot) { // Never deletes a commit DeletionPolicyKeepAllDeletionPolicyPtr policy = newLucene(); @@ -399,21 +362,21 @@ TEST_F(DeletionPolicyTest, testOpenPriorSnapshot) IndexWriterPtr writer = newLucene(dir, newLucene(), (IndexDeletionPolicyPtr)policy, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { addDoc(writer); - if ((1 + i) % 2 == 0) + if ((1 + i) % 2 == 0) { writer->commit(); + } } writer->close(); Collection commits = IndexReader::listCommits(dir); EXPECT_EQ(6, commits.size()); IndexCommitPtr lastCommit; - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { - if (!lastCommit || (*commit)->getGeneration() > lastCommit->getGeneration()) + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { + if (!lastCommit || (*commit)->getGeneration() > lastCommit->getGeneration()) { lastCommit = *commit; + } } EXPECT_TRUE(lastCommit); @@ -485,10 +448,8 @@ TEST_F(DeletionPolicyTest, testOpenPriorSnapshot) } /// Test keeping NO commit points. This is a viable and useful case eg where you want to build a big index and you know there are no readers. -TEST_F(DeletionPolicyTest, testKeepNoneOnInitDeletionPolicy) -{ - for (int32_t pass = 0; pass < 2; ++pass) - { +TEST_F(DeletionPolicyTest, testKeepNoneOnInitDeletionPolicy) { + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); KeepNoneOnInitDeletionPolicyPtr policy = newLucene(); @@ -498,8 +459,9 @@ TEST_F(DeletionPolicyTest, testKeepNoneOnInitDeletionPolicy) IndexWriterPtr writer = newLucene(dir, newLucene(), true, policy, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(10); writer->setUseCompoundFile(useCompoundFile); - for (int32_t i = 0; i < 107; ++i) + for (int32_t i = 0; i < 107; ++i) { addDoc(writer); + } writer->close(); writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthUNLIMITED); @@ -521,25 +483,23 @@ TEST_F(DeletionPolicyTest, testKeepNoneOnInitDeletionPolicy) } /// Test a deletion policy that keeps last N commits. -TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicy) -{ +TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicy) { int32_t N = 5; - for (int32_t pass = 0; pass < 2; ++pass) - { + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); DirectoryPtr dir = newLucene(); KeepLastNDeletionPolicyPtr policy = newLucene(N); - for (int32_t j = 0; j < N + 1; ++j) - { + for (int32_t j = 0; j < N + 1; ++j) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, policy, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(10); writer->setUseCompoundFile(useCompoundFile); - for (int32_t i = 0; i < 17; ++i) + for (int32_t i = 0; i < 17; ++i) { addDoc(writer); + } writer->optimize(); writer->close(); } @@ -551,22 +511,21 @@ TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicy) // Simplistic check: just verify only the past N segments_N's still exist, and, I can open a reader on each dir->deleteFile(IndexFileNames::SEGMENTS_GEN()); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); - for (int32_t i = 0; i < N + 1; ++i) - { - try - { + for (int32_t i = 0; i < N + 1; ++i) { + try { IndexReaderPtr reader = IndexReader::open(dir, true); reader->close(); - if (i == N) + if (i == N) { FAIL() << "should have failed on commits prior to last"; - } - catch (IOException& e) - { - if (i != N) + } + } catch (IOException& e) { + if (i != N) { FAIL() << e.getError(); + } } - if (i < N) + if (i < N) { dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); + } --gen; } @@ -575,12 +534,10 @@ TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicy) } /// Test a deletion policy that keeps last N commits around, with reader doing deletes. -TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithReader) -{ +TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithReader) { int32_t N = 10; - for (int32_t pass = 0; pass < 2; ++pass) - { + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); KeepLastNDeletionPolicyPtr policy = newLucene(N); @@ -592,12 +549,12 @@ TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithReader) TermPtr searchTerm = newLucene(L"content", L"aaa"); QueryPtr query = newLucene(searchTerm); - for (int32_t i = 0; i < N + 1; ++i) - { + for (int32_t i = 0; i < N + 1; ++i) { writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthUNLIMITED); writer->setUseCompoundFile(useCompoundFile); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { addDoc(writer); + } // this is a commit writer->close(); IndexReaderPtr reader = IndexReader::open(dir, policy, false); @@ -630,34 +587,33 @@ TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithReader) dir->deleteFile(IndexFileNames::SEGMENTS_GEN()); int32_t expectedCount = 176; - for (int32_t i = 0; i < N + 1; ++i) - { - try - { + for (int32_t i = 0; i < N + 1; ++i) { + try { IndexReaderPtr reader = IndexReader::open(dir, true); // Work backwards in commits on what the expected count should be. searcher = newLucene(reader); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - if (i > 1) - { - if (i % 2 == 0) + if (i > 1) { + if (i % 2 == 0) { expectedCount += 1; - else + } else { expectedCount -= 17; + } } EXPECT_EQ(expectedCount, hits.size()); searcher->close(); reader->close(); - if (i == N) + if (i == N) { FAIL() << "should have failed on commits before last 5"; - } - catch (IOException& e) - { - if (i != N) + } + } catch (IOException& e) { + if (i != N) { FAIL() << e.getError(); + } } - if (i < N) + if (i < N) { dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); + } --gen; } @@ -666,12 +622,10 @@ TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithReader) } /// Test a deletion policy that keeps last N commits around, through creates. -TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithCreates) -{ +TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithCreates) { int32_t N = 10; - for (int32_t pass = 0; pass < 2; ++pass) - { + for (int32_t pass = 0; pass < 2; ++pass) { bool useCompoundFile = ((pass % 2) != 0); KeepLastNDeletionPolicyPtr policy = newLucene(N); @@ -684,13 +638,13 @@ TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithCreates) TermPtr searchTerm = newLucene(L"content", L"aaa"); QueryPtr query = newLucene(searchTerm); - for (int32_t i = 0; i < N + 1; ++i) - { + for (int32_t i = 0; i < N + 1; ++i) { writer = newLucene(dir, newLucene(), false, policy, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(10); writer->setUseCompoundFile(useCompoundFile); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { addDoc(writer); + } // this is a commit writer->close(); IndexReaderPtr reader = IndexReader::open(dir, policy, false); @@ -721,33 +675,33 @@ TEST_F(DeletionPolicyTest, testKeepLastNDeletionPolicyWithCreates) dir->deleteFile(IndexFileNames::SEGMENTS_GEN()); int32_t expectedCount = 0; - for (int32_t i = 0; i < N + 1; ++i) - { - try - { + for (int32_t i = 0; i < N + 1; ++i) { + try { IndexReaderPtr reader = IndexReader::open(dir, true); // Work backwards in commits on what the expected count should be. searcher = newLucene(reader); hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(expectedCount, hits.size()); searcher->close(); - if (expectedCount == 0) + if (expectedCount == 0) { expectedCount = 16; - else if (expectedCount == 16) + } else if (expectedCount == 16) { expectedCount = 17; - else if (expectedCount == 17) + } else if (expectedCount == 17) { expectedCount = 0; + } reader->close(); - if (i == N) + if (i == N) { FAIL() << "should have failed on commits before last"; - } - catch (IOException& e) - { - if (i != N) + } + } catch (IOException& e) { + if (i != N) { FAIL() << e.getError(); + } } - if (i < N) + if (i < N) { dir->deleteFile(IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS(), L"", gen)); + } --gen; } diff --git a/src/test/index/DirectoryReaderTest.cpp b/src/test/index/DirectoryReaderTest.cpp index 0bb6653a..0c247fa2 100644 --- a/src/test/index/DirectoryReaderTest.cpp +++ b/src/test/index/DirectoryReaderTest.cpp @@ -25,11 +25,9 @@ using namespace Lucene; -class DirectoryReaderTest : public LuceneTestFixture, public DocHelper -{ +class DirectoryReaderTest : public LuceneTestFixture, public DocHelper { public: - DirectoryReaderTest() - { + DirectoryReaderTest() { readers = Collection::newInstance(2); dir = newLucene(); doc1 = newLucene(); @@ -42,8 +40,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper sis->read(dir); } - virtual ~DirectoryReaderTest() - { + virtual ~DirectoryReaderTest() { } protected: @@ -54,8 +51,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper SegmentInfosPtr sis; public: - void doTestDocument() - { + void doTestDocument() { sis->read(dir); IndexReaderPtr reader = openReader(); EXPECT_TRUE(reader); @@ -70,8 +66,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper checkNorms(reader); } - void doTestUndeleteAll() - { + void doTestUndeleteAll() { sis->read(dir); IndexReaderPtr reader = openReader(); EXPECT_TRUE(reader); @@ -85,8 +80,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper reader->commit(MapStringString()); reader->close(); - if (boost::dynamic_pointer_cast(reader)) - { + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } @@ -100,8 +94,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper reader->commit(MapStringString()); reader->close(); - if (boost::dynamic_pointer_cast(reader)) - { + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } @@ -112,8 +105,7 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper } protected: - IndexReaderPtr openReader() - { + IndexReaderPtr openReader() { IndexReaderPtr reader = IndexReader::open(dir, false); EXPECT_TRUE(boost::dynamic_pointer_cast(reader)); EXPECT_TRUE(dir); @@ -122,31 +114,27 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper return reader; } - void checkNorms(const IndexReaderPtr& reader) - { - for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) - { - if ((*field)->isIndexed()) - { + void checkNorms(const IndexReaderPtr& reader) { + for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) { + if ((*field)->isIndexed()) { EXPECT_EQ(reader->hasNorms((*field)->name()), !(*field)->getOmitNorms()); EXPECT_EQ(reader->hasNorms((*field)->name()), !DocHelper::noNorms.contains((*field)->name())); - if (!reader->hasNorms((*field)->name())) - { + if (!reader->hasNorms((*field)->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms((*field)->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); EXPECT_TRUE(!norms); norms = ByteArray::newInstance(reader->maxDoc()); reader->norms((*field)->name(), norms, 0); - for (int32_t j = 0; j < reader->maxDoc(); ++j) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { EXPECT_EQ(norms[j], norm1); + } } } } } - void addDoc(const RAMDirectoryPtr& ramDir1, const String& s, bool create) - { + void addDoc(const RAMDirectoryPtr& ramDir1, const String& s, bool create) { IndexWriterPtr iw = newLucene(ramDir1, newLucene(LuceneVersion::LUCENE_CURRENT), create, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"body", s, Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -155,14 +143,12 @@ class DirectoryReaderTest : public LuceneTestFixture, public DocHelper } }; -TEST_F(DirectoryReaderTest, testDirectoryReader) -{ +TEST_F(DirectoryReaderTest, testDirectoryReader) { doTestDocument(); doTestUndeleteAll(); } -TEST_F(DirectoryReaderTest, testIsCurrent) -{ +TEST_F(DirectoryReaderTest, testIsCurrent) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); RAMDirectoryPtr ramDir2 = newLucene(); @@ -173,19 +159,15 @@ TEST_F(DirectoryReaderTest, testIsCurrent) EXPECT_TRUE(!mr->isCurrent()); // has been modified, not current anymore addDoc(ramDir2, L"even more text", false); EXPECT_TRUE(!mr->isCurrent()); // has been modified even more, not current anymore - try - { + try { mr->getVersion(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); } mr->close(); } -TEST_F(DirectoryReaderTest, testMultiTermDocs) -{ +TEST_F(DirectoryReaderTest, testMultiTermDocs) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); RAMDirectoryPtr ramDir2 = newLucene(); @@ -206,8 +188,9 @@ TEST_F(DirectoryReaderTest, testMultiTermDocs) int32_t ret = 0; // This should blow up if we forget to check that the TermEnum is from the same reader as the TermDocs. - while (td2->next()) + while (td2->next()) { ret += td2->doc(); + } td2->close(); te3->close(); @@ -215,13 +198,11 @@ TEST_F(DirectoryReaderTest, testMultiTermDocs) EXPECT_TRUE(ret > 0); } -TEST_F(DirectoryReaderTest, testAllTermDocs) -{ +TEST_F(DirectoryReaderTest, testAllTermDocs) { IndexReaderPtr reader = openReader(); int32_t NUM_DOCS = 2; TermDocsPtr td = reader->termDocs(TermPtr()); - for (int32_t i = 0; i < NUM_DOCS; ++i) - { + for (int32_t i = 0; i < NUM_DOCS; ++i) { EXPECT_TRUE(td->next()); EXPECT_EQ(i, td->doc()); EXPECT_EQ(1, td->freq()); diff --git a/src/test/index/DocHelper.cpp b/src/test/index/DocHelper.cpp index d37ad77c..7155fdeb 100644 --- a/src/test/index/DocHelper.cpp +++ b/src/test/index/DocHelper.cpp @@ -15,227 +15,229 @@ #include "MiscUtils.h" #include "UnicodeUtils.h" -namespace Lucene -{ - const wchar_t* DocHelper::FIELD_1_TEXT = L"field one text"; - const wchar_t* DocHelper::TEXT_FIELD_1_KEY = L"textField1"; - FieldPtr DocHelper::textField1; - - const wchar_t* DocHelper::FIELD_2_TEXT = L"field field field two text"; - // Fields will be lexicographically sorted. So, the order is: field, text, two - const int32_t DocHelper::FIELD_2_FREQS[] = {3, 1, 1}; - const wchar_t* DocHelper::TEXT_FIELD_2_KEY = L"textField2"; - FieldPtr DocHelper::textField2; - - const wchar_t* DocHelper::FIELD_3_TEXT = L"aaaNoNorms aaaNoNorms bbbNoNorms"; - const wchar_t* DocHelper::TEXT_FIELD_3_KEY = L"textField3"; - FieldPtr DocHelper::textField3; - - const wchar_t* DocHelper::KEYWORD_TEXT = L"Keyword"; - const wchar_t* DocHelper::KEYWORD_FIELD_KEY = L"keyField"; - FieldPtr DocHelper::keyField; - - const wchar_t* DocHelper::NO_NORMS_TEXT = L"omitNormsText"; - const wchar_t* DocHelper::NO_NORMS_KEY = L"omitNorms"; - FieldPtr DocHelper::noNormsField; - - const wchar_t* DocHelper::NO_TF_TEXT = L"analyzed with no tf and positions"; - const wchar_t* DocHelper::NO_TF_KEY = L"omitTermFreqAndPositions"; - FieldPtr DocHelper::noTFField; - - const wchar_t* DocHelper::UNINDEXED_FIELD_TEXT = L"unindexed field text"; - const wchar_t* DocHelper::UNINDEXED_FIELD_KEY = L"unIndField"; - FieldPtr DocHelper::unIndField; - - const wchar_t* DocHelper::UNSTORED_1_FIELD_TEXT = L"unstored field text"; - const wchar_t* DocHelper::UNSTORED_FIELD_1_KEY = L"unStoredField1"; - FieldPtr DocHelper::unStoredField1; - - const wchar_t* DocHelper::UNSTORED_2_FIELD_TEXT = L"unstored field text"; - const wchar_t* DocHelper::UNSTORED_FIELD_2_KEY = L"unStoredField2"; - FieldPtr DocHelper::unStoredField2; - - const wchar_t* DocHelper::LAZY_FIELD_BINARY_KEY = L"lazyFieldBinary"; - ByteArray DocHelper::LAZY_FIELD_BINARY_BYTES; - FieldPtr DocHelper::lazyFieldBinary; - - const wchar_t* DocHelper::LAZY_FIELD_KEY = L"lazyField"; - const wchar_t* DocHelper::LAZY_FIELD_TEXT = L"These are some field bytes"; - FieldPtr DocHelper::lazyField; - - const wchar_t* DocHelper::LARGE_LAZY_FIELD_KEY = L"largeLazyField"; - String DocHelper::LARGE_LAZY_FIELD_TEXT; - FieldPtr DocHelper::largeLazyField; - - const uint8_t DocHelper::_FIELD_UTF1_TEXT[] = {0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6f, 0x6e, - 0x65, 0x20, 0xe4, 0xb8, 0x80, 0x74, 0x65, 0x78, 0x74}; - const String DocHelper::FIELD_UTF1_TEXT = UTF8_TO_STRING(_FIELD_UTF1_TEXT); - const wchar_t* DocHelper::TEXT_FIELD_UTF1_KEY = L"textField1Utf8"; - FieldPtr DocHelper::textUtfField1; - - const uint8_t DocHelper::_FIELD_UTF2_TEXT[] = {0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, - 0xe4, 0xb8, 0x80, 0x74, 0x77, 0x6f, 0x20, 0x74, 0x65, - 0x78, 0x74}; - const String DocHelper::FIELD_UTF2_TEXT = UTF8_TO_STRING(_FIELD_UTF2_TEXT); - FieldPtr DocHelper::textUtfField2; - - // Fields will be lexicographically sorted. So, the order is: field, text, two - const int32_t DocHelper::FIELD_UTF2_FREQS[] = {3, 1, 1}; - const wchar_t* DocHelper::TEXT_FIELD_UTF2_KEY = L"textField2Utf8"; - - MapStringString DocHelper::nameValues; - Collection DocHelper::fields; - MapStringField DocHelper::all; - MapStringField DocHelper::indexed; - MapStringField DocHelper::stored; - MapStringField DocHelper::unstored; - MapStringField DocHelper::unindexed; - MapStringField DocHelper::termvector; - MapStringField DocHelper::notermvector; - MapStringField DocHelper::lazy; - MapStringField DocHelper::noNorms; - MapStringField DocHelper::noTf; - - DocHelper::DocHelper() - { - static bool setupRequired = true; - if (setupRequired) - { - setup(); - setupRequired = false; - } +namespace Lucene { + +const wchar_t* DocHelper::FIELD_1_TEXT = L"field one text"; +const wchar_t* DocHelper::TEXT_FIELD_1_KEY = L"textField1"; +FieldPtr DocHelper::textField1; + +const wchar_t* DocHelper::FIELD_2_TEXT = L"field field field two text"; +// Fields will be lexicographically sorted. So, the order is: field, text, two +const int32_t DocHelper::FIELD_2_FREQS[] = {3, 1, 1}; +const wchar_t* DocHelper::TEXT_FIELD_2_KEY = L"textField2"; +FieldPtr DocHelper::textField2; + +const wchar_t* DocHelper::FIELD_3_TEXT = L"aaaNoNorms aaaNoNorms bbbNoNorms"; +const wchar_t* DocHelper::TEXT_FIELD_3_KEY = L"textField3"; +FieldPtr DocHelper::textField3; + +const wchar_t* DocHelper::KEYWORD_TEXT = L"Keyword"; +const wchar_t* DocHelper::KEYWORD_FIELD_KEY = L"keyField"; +FieldPtr DocHelper::keyField; + +const wchar_t* DocHelper::NO_NORMS_TEXT = L"omitNormsText"; +const wchar_t* DocHelper::NO_NORMS_KEY = L"omitNorms"; +FieldPtr DocHelper::noNormsField; + +const wchar_t* DocHelper::NO_TF_TEXT = L"analyzed with no tf and positions"; +const wchar_t* DocHelper::NO_TF_KEY = L"omitTermFreqAndPositions"; +FieldPtr DocHelper::noTFField; + +const wchar_t* DocHelper::UNINDEXED_FIELD_TEXT = L"unindexed field text"; +const wchar_t* DocHelper::UNINDEXED_FIELD_KEY = L"unIndField"; +FieldPtr DocHelper::unIndField; + +const wchar_t* DocHelper::UNSTORED_1_FIELD_TEXT = L"unstored field text"; +const wchar_t* DocHelper::UNSTORED_FIELD_1_KEY = L"unStoredField1"; +FieldPtr DocHelper::unStoredField1; + +const wchar_t* DocHelper::UNSTORED_2_FIELD_TEXT = L"unstored field text"; +const wchar_t* DocHelper::UNSTORED_FIELD_2_KEY = L"unStoredField2"; +FieldPtr DocHelper::unStoredField2; + +const wchar_t* DocHelper::LAZY_FIELD_BINARY_KEY = L"lazyFieldBinary"; +ByteArray DocHelper::LAZY_FIELD_BINARY_BYTES; +FieldPtr DocHelper::lazyFieldBinary; + +const wchar_t* DocHelper::LAZY_FIELD_KEY = L"lazyField"; +const wchar_t* DocHelper::LAZY_FIELD_TEXT = L"These are some field bytes"; +FieldPtr DocHelper::lazyField; + +const wchar_t* DocHelper::LARGE_LAZY_FIELD_KEY = L"largeLazyField"; +String DocHelper::LARGE_LAZY_FIELD_TEXT; +FieldPtr DocHelper::largeLazyField; + +const uint8_t DocHelper::_FIELD_UTF1_TEXT[] = {0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6f, 0x6e, + 0x65, 0x20, 0xe4, 0xb8, 0x80, 0x74, 0x65, 0x78, 0x74 + }; +const String DocHelper::FIELD_UTF1_TEXT = UTF8_TO_STRING(_FIELD_UTF1_TEXT); +const wchar_t* DocHelper::TEXT_FIELD_UTF1_KEY = L"textField1Utf8"; +FieldPtr DocHelper::textUtfField1; + +const uint8_t DocHelper::_FIELD_UTF2_TEXT[] = {0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, + 0xe4, 0xb8, 0x80, 0x74, 0x77, 0x6f, 0x20, 0x74, 0x65, + 0x78, 0x74 + }; +const String DocHelper::FIELD_UTF2_TEXT = UTF8_TO_STRING(_FIELD_UTF2_TEXT); +FieldPtr DocHelper::textUtfField2; + +// Fields will be lexicographically sorted. So, the order is: field, text, two +const int32_t DocHelper::FIELD_UTF2_FREQS[] = {3, 1, 1}; +const wchar_t* DocHelper::TEXT_FIELD_UTF2_KEY = L"textField2Utf8"; + +MapStringString DocHelper::nameValues; +Collection DocHelper::fields; +MapStringField DocHelper::all; +MapStringField DocHelper::indexed; +MapStringField DocHelper::stored; +MapStringField DocHelper::unstored; +MapStringField DocHelper::unindexed; +MapStringField DocHelper::termvector; +MapStringField DocHelper::notermvector; +MapStringField DocHelper::lazy; +MapStringField DocHelper::noNorms; +MapStringField DocHelper::noTf; + +DocHelper::DocHelper() { + static bool setupRequired = true; + if (setupRequired) { + setup(); + setupRequired = false; } +} - DocHelper::~DocHelper() - { - } +DocHelper::~DocHelper() { +} - void DocHelper::setup() - { - textField1 = newLucene(TEXT_FIELD_1_KEY, FIELD_1_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); - textField2 = newLucene(TEXT_FIELD_2_KEY, FIELD_2_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); - textField3 = newLucene(TEXT_FIELD_3_KEY, FIELD_3_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); - textField3->setOmitNorms(true); - keyField = newLucene(KEYWORD_FIELD_KEY, KEYWORD_TEXT, Field::STORE_YES, Field::INDEX_NOT_ANALYZED); - noNormsField = newLucene(NO_NORMS_KEY, NO_NORMS_TEXT, Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS); - noTFField = newLucene(NO_TF_KEY, NO_TF_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); - noTFField->setOmitTermFreqAndPositions(true); - unIndField = newLucene(UNINDEXED_FIELD_KEY, UNINDEXED_FIELD_TEXT, Field::STORE_YES, Field::INDEX_NO); - unStoredField1 = newLucene(UNSTORED_FIELD_1_KEY, UNSTORED_1_FIELD_TEXT, Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); - unStoredField2 = newLucene(UNSTORED_FIELD_2_KEY, UNSTORED_2_FIELD_TEXT, Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES); - - String binary(L"These are some binary field bytes"); - UTF8ResultPtr utf8 = newInstance(); - StringUtils::toUTF8(binary.c_str(), binary.length(), utf8); - LAZY_FIELD_BINARY_BYTES = ByteArray::newInstance(utf8->length); - MiscUtils::arrayCopy(utf8->result.get(), 0, LAZY_FIELD_BINARY_BYTES.get(), 0, utf8->length); - - lazyFieldBinary = newLucene(LAZY_FIELD_BINARY_KEY, LAZY_FIELD_BINARY_BYTES, Field::STORE_YES); - lazyField = newLucene(LAZY_FIELD_KEY, LAZY_FIELD_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); - - if (LARGE_LAZY_FIELD_TEXT.empty()) - { - LARGE_LAZY_FIELD_TEXT.reserve(550000); - for (int32_t i = 0; i < 10000; ++i) - LARGE_LAZY_FIELD_TEXT += L"Lazily loading lengths of language in lieu of laughing "; +void DocHelper::setup() { + textField1 = newLucene(TEXT_FIELD_1_KEY, FIELD_1_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); + textField2 = newLucene(TEXT_FIELD_2_KEY, FIELD_2_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); + textField3 = newLucene(TEXT_FIELD_3_KEY, FIELD_3_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); + textField3->setOmitNorms(true); + keyField = newLucene(KEYWORD_FIELD_KEY, KEYWORD_TEXT, Field::STORE_YES, Field::INDEX_NOT_ANALYZED); + noNormsField = newLucene(NO_NORMS_KEY, NO_NORMS_TEXT, Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS); + noTFField = newLucene(NO_TF_KEY, NO_TF_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); + noTFField->setOmitTermFreqAndPositions(true); + unIndField = newLucene(UNINDEXED_FIELD_KEY, UNINDEXED_FIELD_TEXT, Field::STORE_YES, Field::INDEX_NO); + unStoredField1 = newLucene(UNSTORED_FIELD_1_KEY, UNSTORED_1_FIELD_TEXT, Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); + unStoredField2 = newLucene(UNSTORED_FIELD_2_KEY, UNSTORED_2_FIELD_TEXT, Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES); + + String binary(L"These are some binary field bytes"); + UTF8ResultPtr utf8 = newInstance(); + StringUtils::toUTF8(binary.c_str(), binary.length(), utf8); + LAZY_FIELD_BINARY_BYTES = ByteArray::newInstance(utf8->length); + MiscUtils::arrayCopy(utf8->result.get(), 0, LAZY_FIELD_BINARY_BYTES.get(), 0, utf8->length); + + lazyFieldBinary = newLucene(LAZY_FIELD_BINARY_KEY, LAZY_FIELD_BINARY_BYTES, Field::STORE_YES); + lazyField = newLucene(LAZY_FIELD_KEY, LAZY_FIELD_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); + + if (LARGE_LAZY_FIELD_TEXT.empty()) { + LARGE_LAZY_FIELD_TEXT.reserve(550000); + for (int32_t i = 0; i < 10000; ++i) { + LARGE_LAZY_FIELD_TEXT += L"Lazily loading lengths of language in lieu of laughing "; } + } - largeLazyField = newLucene(LARGE_LAZY_FIELD_KEY, LARGE_LAZY_FIELD_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); - textUtfField1 = newLucene(TEXT_FIELD_UTF1_KEY, FIELD_UTF1_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); - textUtfField2 = newLucene(TEXT_FIELD_UTF2_KEY, FIELD_UTF2_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); - - nameValues = MapStringString::newInstance(); - nameValues.put(TEXT_FIELD_1_KEY, FIELD_1_TEXT); - nameValues.put(TEXT_FIELD_2_KEY, FIELD_2_TEXT); - nameValues.put(TEXT_FIELD_3_KEY, FIELD_3_TEXT); - nameValues.put(KEYWORD_FIELD_KEY, KEYWORD_TEXT); - nameValues.put(NO_NORMS_KEY, NO_NORMS_TEXT); - nameValues.put(NO_TF_KEY, NO_TF_TEXT); - nameValues.put(UNINDEXED_FIELD_KEY, UNINDEXED_FIELD_TEXT); - nameValues.put(UNSTORED_FIELD_1_KEY, UNSTORED_1_FIELD_TEXT); - nameValues.put(UNSTORED_FIELD_2_KEY, UNSTORED_2_FIELD_TEXT); - nameValues.put(LAZY_FIELD_KEY, LAZY_FIELD_TEXT); - nameValues.put(LAZY_FIELD_BINARY_KEY, L""); - nameValues.put(LARGE_LAZY_FIELD_KEY, LARGE_LAZY_FIELD_TEXT); - nameValues.put(TEXT_FIELD_UTF1_KEY, FIELD_UTF1_TEXT); - nameValues.put(TEXT_FIELD_UTF2_KEY, FIELD_UTF2_TEXT); - - fields = Collection::newInstance(); - fields.add(textField1); - fields.add(textField2); - fields.add(textField3); - fields.add(keyField); - fields.add(noNormsField); - fields.add(noTFField); - fields.add(unIndField); - fields.add(unStoredField1); - fields.add(unStoredField2); - fields.add(textUtfField1); - fields.add(textUtfField2); - fields.add(lazyField); - fields.add(lazyFieldBinary); - fields.add(largeLazyField); - - all = MapStringField::newInstance(); - indexed = MapStringField::newInstance(); - stored = MapStringField::newInstance(); - unstored = MapStringField::newInstance(); - unindexed = MapStringField::newInstance(); - termvector = MapStringField::newInstance(); - notermvector = MapStringField::newInstance(); - lazy = MapStringField::newInstance(); - noNorms = MapStringField::newInstance(); - noTf = MapStringField::newInstance(); - - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - all.put((*field)->name(), *field); - if ((*field)->isIndexed()) - indexed.put((*field)->name(), *field); - else - unindexed.put((*field)->name(), *field); - if ((*field)->isStored()) - stored.put((*field)->name(), *field); - else - unstored.put((*field)->name(), *field); - if ((*field)->isTermVectorStored()) - termvector.put((*field)->name(), *field); - if ((*field)->isIndexed() && !(*field)->isTermVectorStored()) - notermvector.put((*field)->name(), *field); - if ((*field)->isLazy()) - lazy.put((*field)->name(), *field); - if ((*field)->getOmitNorms()) - noNorms.put((*field)->name(), *field); - if ((*field)->getOmitTermFreqAndPositions()) - noTf.put((*field)->name(), *field); + largeLazyField = newLucene(LARGE_LAZY_FIELD_KEY, LARGE_LAZY_FIELD_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED); + textUtfField1 = newLucene(TEXT_FIELD_UTF1_KEY, FIELD_UTF1_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO); + textUtfField2 = newLucene(TEXT_FIELD_UTF2_KEY, FIELD_UTF2_TEXT, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); + + nameValues = MapStringString::newInstance(); + nameValues.put(TEXT_FIELD_1_KEY, FIELD_1_TEXT); + nameValues.put(TEXT_FIELD_2_KEY, FIELD_2_TEXT); + nameValues.put(TEXT_FIELD_3_KEY, FIELD_3_TEXT); + nameValues.put(KEYWORD_FIELD_KEY, KEYWORD_TEXT); + nameValues.put(NO_NORMS_KEY, NO_NORMS_TEXT); + nameValues.put(NO_TF_KEY, NO_TF_TEXT); + nameValues.put(UNINDEXED_FIELD_KEY, UNINDEXED_FIELD_TEXT); + nameValues.put(UNSTORED_FIELD_1_KEY, UNSTORED_1_FIELD_TEXT); + nameValues.put(UNSTORED_FIELD_2_KEY, UNSTORED_2_FIELD_TEXT); + nameValues.put(LAZY_FIELD_KEY, LAZY_FIELD_TEXT); + nameValues.put(LAZY_FIELD_BINARY_KEY, L""); + nameValues.put(LARGE_LAZY_FIELD_KEY, LARGE_LAZY_FIELD_TEXT); + nameValues.put(TEXT_FIELD_UTF1_KEY, FIELD_UTF1_TEXT); + nameValues.put(TEXT_FIELD_UTF2_KEY, FIELD_UTF2_TEXT); + + fields = Collection::newInstance(); + fields.add(textField1); + fields.add(textField2); + fields.add(textField3); + fields.add(keyField); + fields.add(noNormsField); + fields.add(noTFField); + fields.add(unIndField); + fields.add(unStoredField1); + fields.add(unStoredField2); + fields.add(textUtfField1); + fields.add(textUtfField2); + fields.add(lazyField); + fields.add(lazyFieldBinary); + fields.add(largeLazyField); + + all = MapStringField::newInstance(); + indexed = MapStringField::newInstance(); + stored = MapStringField::newInstance(); + unstored = MapStringField::newInstance(); + unindexed = MapStringField::newInstance(); + termvector = MapStringField::newInstance(); + notermvector = MapStringField::newInstance(); + lazy = MapStringField::newInstance(); + noNorms = MapStringField::newInstance(); + noTf = MapStringField::newInstance(); + + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + all.put((*field)->name(), *field); + if ((*field)->isIndexed()) { + indexed.put((*field)->name(), *field); + } else { + unindexed.put((*field)->name(), *field); + } + if ((*field)->isStored()) { + stored.put((*field)->name(), *field); + } else { + unstored.put((*field)->name(), *field); + } + if ((*field)->isTermVectorStored()) { + termvector.put((*field)->name(), *field); + } + if ((*field)->isIndexed() && !(*field)->isTermVectorStored()) { + notermvector.put((*field)->name(), *field); + } + if ((*field)->isLazy()) { + lazy.put((*field)->name(), *field); + } + if ((*field)->getOmitNorms()) { + noNorms.put((*field)->name(), *field); + } + if ((*field)->getOmitTermFreqAndPositions()) { + noTf.put((*field)->name(), *field); } } +} - void DocHelper::setupDoc(const DocumentPtr& doc) - { - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - doc->add(*field); +void DocHelper::setupDoc(const DocumentPtr& doc) { + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + doc->add(*field); } +} - SegmentInfoPtr DocHelper::writeDoc(const DirectoryPtr& dir, const DocumentPtr& doc) - { - return writeDoc(dir, newLucene(), Similarity::getDefault(), doc); - } +SegmentInfoPtr DocHelper::writeDoc(const DirectoryPtr& dir, const DocumentPtr& doc) { + return writeDoc(dir, newLucene(), Similarity::getDefault(), doc); +} - SegmentInfoPtr DocHelper::writeDoc(const DirectoryPtr& dir, const AnalyzerPtr& analyzer, const SimilarityPtr& similarity, const DocumentPtr& doc) - { - IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); - writer->setSimilarity(similarity); - writer->addDocument(doc); - writer->commit(); - SegmentInfoPtr info = writer->newestSegment(); - writer->close(); - return info; - } +SegmentInfoPtr DocHelper::writeDoc(const DirectoryPtr& dir, const AnalyzerPtr& analyzer, const SimilarityPtr& similarity, const DocumentPtr& doc) { + IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); + writer->setSimilarity(similarity); + writer->addDocument(doc); + writer->commit(); + SegmentInfoPtr info = writer->newestSegment(); + writer->close(); + return info; +} + +int32_t DocHelper::numFields(const DocumentPtr& doc) { + return doc->getFields().size(); +} - int32_t DocHelper::numFields(const DocumentPtr& doc) - { - return doc->getFields().size(); - } } diff --git a/src/test/index/DocTest.cpp b/src/test/index/DocTest.cpp index dfb33cb3..cd39fc52 100644 --- a/src/test/index/DocTest.cpp +++ b/src/test/index/DocTest.cpp @@ -25,8 +25,7 @@ using namespace Lucene; typedef LuceneTestFixture DocTest; -static SegmentInfoPtr indexDoc(const IndexWriterPtr& writer, const String& fileName) -{ +static SegmentInfoPtr indexDoc(const IndexWriterPtr& writer, const String& fileName) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"contents", newLucene(FileUtils::joinPath(getTestDir(), fileName)))); writer->addDocument(doc); @@ -34,35 +33,31 @@ static SegmentInfoPtr indexDoc(const IndexWriterPtr& writer, const String& fileN return writer->newestSegment(); } -static void printSegment(StringStream& out, const SegmentInfoPtr& si) -{ +static void printSegment(StringStream& out, const SegmentInfoPtr& si) { SegmentReaderPtr reader = SegmentReader::get(true, si, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); - for (int32_t i = 0; i < reader->numDocs(); ++i) + for (int32_t i = 0; i < reader->numDocs(); ++i) { out << reader->document(i)->toString() << L"\n"; + } TermEnumPtr tis = reader->terms(); - while (tis->next()) - { + while (tis->next()) { out << tis->term()->toString(); out << L" DF=" << tis->docFreq() << L"\n"; TermPositionsPtr positions = reader->termPositions(tis->term()); LuceneException finally; - try - { - while (positions->next()) - { + try { + while (positions->next()) { out << L" doc=" << positions->doc(); out << L" TF=" << positions->freq(); out << L" pos="; out << positions->nextPosition() << L"\n"; - for (int32_t j = 1; j < positions->freq(); ++j) + for (int32_t j = 1; j < positions->freq(); ++j) { out << L"," << positions->nextPosition(); + } } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } positions->close(); @@ -72,8 +67,7 @@ static void printSegment(StringStream& out, const SegmentInfoPtr& si) reader->close(); } -static SegmentInfoPtr merge(const SegmentInfoPtr& si1, const SegmentInfoPtr& si2, const String& merged, bool useCompoundFile) -{ +static SegmentInfoPtr merge(const SegmentInfoPtr& si1, const SegmentInfoPtr& si2, const String& merged, bool useCompoundFile) { SegmentReaderPtr r1 = SegmentReader::get(true, si1, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); SegmentReaderPtr r2 = SegmentReader::get(true, si2, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); @@ -84,18 +78,17 @@ static SegmentInfoPtr merge(const SegmentInfoPtr& si1, const SegmentInfoPtr& si2 merger->merge(); merger->closeReaders(); - if (useCompoundFile) - { + if (useCompoundFile) { HashSet filesToDelete = merger->createCompoundFile(merged + L".cfs"); - for (HashSet::iterator file = filesToDelete.begin(); file != filesToDelete.end(); ++file) + for (HashSet::iterator file = filesToDelete.begin(); file != filesToDelete.end(); ++file) { si1->dir->deleteFile(*file); + } } return newLucene(merged, si1->docCount + si2->docCount, si1->dir, useCompoundFile, true); } -TEST_F(DocTest, testIndexAndMerge) -{ +TEST_F(DocTest, testIndexAndMerge) { String indexDir(FileUtils::joinPath(getTempDir(), L"testDoc")); DirectoryPtr directory = FSDirectory::open(indexDir); diff --git a/src/test/index/DocumentWriterTest.cpp b/src/test/index/DocumentWriterTest.cpp index 90c03315..a1aab03a 100644 --- a/src/test/index/DocumentWriterTest.cpp +++ b/src/test/index/DocumentWriterTest.cpp @@ -35,16 +35,13 @@ using namespace Lucene; -class DocumentWriterTest : public LuceneTestFixture, public DocHelper -{ +class DocumentWriterTest : public LuceneTestFixture, public DocHelper { public: - virtual ~DocumentWriterTest() - { + virtual ~DocumentWriterTest() { } }; -TEST_F(DocumentWriterTest, testAddDocument) -{ +TEST_F(DocumentWriterTest, testAddDocument) { RAMDirectoryPtr dir = newLucene(); DocumentPtr testDoc = newLucene(); @@ -84,42 +81,38 @@ TEST_F(DocumentWriterTest, testAddDocument) EXPECT_EQ(fields[0]->stringValue(), DocHelper::FIELD_3_TEXT); // test that the norms are not present in the segment if omitNorms is true - for (int32_t i = 0; i < reader->core->fieldInfos->size(); ++i) - { + for (int32_t i = 0; i < reader->core->fieldInfos->size(); ++i) { FieldInfoPtr fi = reader->core->fieldInfos->fieldInfo(i); - if (fi->isIndexed) + if (fi->isIndexed) { EXPECT_TRUE(fi->omitNorms == !reader->hasNorms(fi->name)); + } } } -namespace TestPositionIncrementGap -{ - DECLARE_SHARED_PTR(TestableAnalyzer) +namespace TestPositionIncrementGap { - class TestableAnalyzer : public Analyzer - { - public: - virtual ~TestableAnalyzer() - { - } +DECLARE_SHARED_PTR(TestableAnalyzer) - LUCENE_CLASS(TestableAnalyzer); +class TestableAnalyzer : public Analyzer { +public: + virtual ~TestableAnalyzer() { + } - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(reader); - } + LUCENE_CLASS(TestableAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(reader); + } + + virtual int32_t getPositionIncrementGap(const String& fieldName) { + return 500; + } +}; - virtual int32_t getPositionIncrementGap(const String& fieldName) - { - return 500; - } - }; } -TEST_F(DocumentWriterTest, testPositionIncrementGap) -{ +TEST_F(DocumentWriterTest, testPositionIncrementGap) { RAMDirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(); @@ -143,89 +136,82 @@ TEST_F(DocumentWriterTest, testPositionIncrementGap) EXPECT_EQ(502, termPositions->nextPosition()); } -namespace TestTokenReuse -{ - DECLARE_SHARED_PTR(TestableTokenFilter) - DECLARE_SHARED_PTR(TestableAnalyzer) - - class TestableTokenFilter : public TokenFilter - { - public: - TestableTokenFilter(const ReaderPtr& reader) : TokenFilter(newLucene(reader)) - { - first = true; - termAtt = addAttribute(); - payloadAtt = addAttribute(); - posIncrAtt = addAttribute(); - } +namespace TestTokenReuse { - virtual ~TestableTokenFilter() - { - } +DECLARE_SHARED_PTR(TestableTokenFilter) +DECLARE_SHARED_PTR(TestableAnalyzer) + +class TestableTokenFilter : public TokenFilter { +public: + TestableTokenFilter(const ReaderPtr& reader) : TokenFilter(newLucene(reader)) { + first = true; + termAtt = addAttribute(); + payloadAtt = addAttribute(); + posIncrAtt = addAttribute(); + } + + virtual ~TestableTokenFilter() { + } - LUCENE_CLASS(TestableTokenFilter); - - public: - bool first; - AttributeSourceStatePtr state; - TermAttributePtr termAtt; - PayloadAttributePtr payloadAtt; - PositionIncrementAttributePtr posIncrAtt; - - public: - virtual bool incrementToken() - { - if (state) - { - restoreState(state); - payloadAtt->setPayload(PayloadPtr()); - posIncrAtt->setPositionIncrement(0); - static const wchar_t buffer[] = L"b"; - - termAtt->setTermBuffer(buffer, 0, 1); - state.reset(); - return true; - } - - bool hasNext = input->incrementToken(); - if (!hasNext) - return false; - if (UnicodeUtil::isDigit(termAtt->termBufferArray()[0])) - posIncrAtt->setPositionIncrement(termAtt->termBufferArray()[0] - L'0'); - if (first) - { - ByteArray payload = ByteArray::newInstance(1); - payload.get()[0] = 100; - - // set payload on first position only - payloadAtt->setPayload(newLucene(payload)); - first = false; - } - // index a "synonym" for every token - state = captureState(); + LUCENE_CLASS(TestableTokenFilter); + +public: + bool first; + AttributeSourceStatePtr state; + TermAttributePtr termAtt; + PayloadAttributePtr payloadAtt; + PositionIncrementAttributePtr posIncrAtt; + +public: + virtual bool incrementToken() { + if (state) { + restoreState(state); + payloadAtt->setPayload(PayloadPtr()); + posIncrAtt->setPositionIncrement(0); + static const wchar_t buffer[] = L"b"; + + termAtt->setTermBuffer(buffer, 0, 1); + state.reset(); return true; } - }; - class TestableAnalyzer : public Analyzer - { - public: - virtual ~TestableAnalyzer() - { + bool hasNext = input->incrementToken(); + if (!hasNext) { + return false; } + if (UnicodeUtil::isDigit(termAtt->termBufferArray()[0])) { + posIncrAtt->setPositionIncrement(termAtt->termBufferArray()[0] - L'0'); + } + if (first) { + ByteArray payload = ByteArray::newInstance(1); + payload.get()[0] = 100; - LUCENE_CLASS(TestableAnalyzer); - - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(reader); + // set payload on first position only + payloadAtt->setPayload(newLucene(payload)); + first = false; } - }; + // index a "synonym" for every token + state = captureState(); + return true; + } +}; + +class TestableAnalyzer : public Analyzer { +public: + virtual ~TestableAnalyzer() { + } + + LUCENE_CLASS(TestableAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(reader); + } +}; + } -TEST_F(DocumentWriterTest, testTokenReuse) -{ +TEST_F(DocumentWriterTest, testTokenReuse) { RAMDirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(); @@ -252,48 +238,43 @@ TEST_F(DocumentWriterTest, testTokenReuse) EXPECT_EQ(false, termPositions->isPayloadAvailable()); } -namespace TestPreAnalyzedField -{ - DECLARE_SHARED_PTR(TestableTokenStream) - - class TestableTokenStream : public TokenStream - { - public: - TestableTokenStream() - { - tokens = newCollection(L"term1", L"term2", L"term3", L"term2"); - index = 0; - termAtt = addAttribute(); - } +namespace TestPreAnalyzedField { - virtual ~TestableTokenStream() - { - } +DECLARE_SHARED_PTR(TestableTokenStream) - LUCENE_CLASS(TestableTokenStream); - - protected: - Collection tokens; - int32_t index; - TermAttributePtr termAtt; - - public: - virtual bool incrementToken() - { - if (index == tokens.size()) - return false; - else - { - clearAttributes(); - termAtt->setTermBuffer(tokens[index++]); - return true; - } +class TestableTokenStream : public TokenStream { +public: + TestableTokenStream() { + tokens = newCollection(L"term1", L"term2", L"term3", L"term2"); + index = 0; + termAtt = addAttribute(); + } + + virtual ~TestableTokenStream() { + } + + LUCENE_CLASS(TestableTokenStream); + +protected: + Collection tokens; + int32_t index; + TermAttributePtr termAtt; + +public: + virtual bool incrementToken() { + if (index == tokens.size()) { + return false; + } else { + clearAttributes(); + termAtt->setTermBuffer(tokens[index++]); + return true; } - }; + } +}; + } -TEST_F(DocumentWriterTest, testPreAnalyzedField) -{ +TEST_F(DocumentWriterTest, testPreAnalyzedField) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -325,8 +306,7 @@ TEST_F(DocumentWriterTest, testPreAnalyzedField) } /// Test adding two fields with the same name, but with different term vector setting -TEST_F(DocumentWriterTest, testMixedTermVectorSettingsSameField) -{ +TEST_F(DocumentWriterTest, testMixedTermVectorSettingsSameField) { RAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); // f1 first without tv then with tv @@ -355,8 +335,7 @@ TEST_F(DocumentWriterTest, testMixedTermVectorSettingsSameField) /// Test adding two fields with the same name, one indexed the other stored only. The omitNorms and /// omitTermFreqAndPositions setting of the stored field should not affect the indexed one -TEST_F(DocumentWriterTest, testMixedTermVectorSettingsSameField2) -{ +TEST_F(DocumentWriterTest, testMixedTermVectorSettingsSameField2) { RAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); // f1 has no norms diff --git a/src/test/index/FieldInfosTest.cpp b/src/test/index/FieldInfosTest.cpp index 88bb0402..bc774bb2 100644 --- a/src/test/index/FieldInfosTest.cpp +++ b/src/test/index/FieldInfosTest.cpp @@ -16,16 +16,13 @@ using namespace Lucene; -class FieldInfosTest : public LuceneTestFixture, public DocHelper -{ +class FieldInfosTest : public LuceneTestFixture, public DocHelper { public: - virtual ~FieldInfosTest() - { + virtual ~FieldInfosTest() { } }; -TEST_F(FieldInfosTest, testFieldInfos) -{ +TEST_F(FieldInfosTest, testFieldInfos) { DocumentPtr testDoc = newLucene(); DocHelper::setupDoc(testDoc); diff --git a/src/test/index/FieldsReaderTest.cpp b/src/test/index/FieldsReaderTest.cpp index 24f46869..d7c4d4d4 100644 --- a/src/test/index/FieldsReaderTest.cpp +++ b/src/test/index/FieldsReaderTest.cpp @@ -25,11 +25,9 @@ using namespace Lucene; -class FieldsReaderTest : public LuceneTestFixture, public DocHelper -{ +class FieldsReaderTest : public LuceneTestFixture, public DocHelper { public: - FieldsReaderTest() - { + FieldsReaderTest() { dir = newLucene(); testDoc = newLucene(); fieldInfos = newLucene(); @@ -41,8 +39,7 @@ class FieldsReaderTest : public LuceneTestFixture, public DocHelper writer->close(); } - virtual ~FieldsReaderTest() - { + virtual ~FieldsReaderTest() { } protected: @@ -58,17 +55,14 @@ String FieldsReaderTest::TEST_SEGMENT_NAME = L"_0"; DECLARE_SHARED_PTR(FaultyFSDirectory) DECLARE_SHARED_PTR(FaultyIndexInput) -class FaultyIndexInput : public BufferedIndexInput -{ +class FaultyIndexInput : public BufferedIndexInput { public: - FaultyIndexInput(const IndexInputPtr& delegate) - { + FaultyIndexInput(const IndexInputPtr& delegate) { this->delegate = delegate; count = 0; } - virtual ~FaultyIndexInput() - { + virtual ~FaultyIndexInput() { } LUCENE_CLASS(FaultyIndexInput); @@ -79,53 +73,45 @@ class FaultyIndexInput : public BufferedIndexInput int32_t count; public: - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) - { + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) { simOutage(); delegate->readBytes(b, offset, length); } - virtual void seekInternal(int64_t pos) - { + virtual void seekInternal(int64_t pos) { delegate->seek(pos); } - virtual int64_t length() - { + virtual int64_t length() { return delegate->length(); } - virtual void close() - { + virtual void close() { delegate->close(); } - virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) - { + virtual LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(delegate->clone())); } protected: - void simOutage() - { - if (doFail && count++ % 2 == 1) + void simOutage() { + if (doFail && count++ % 2 == 1) { boost::throw_exception(IOException(L"Simulated network outage")); + } } }; bool FaultyIndexInput::doFail = false; -class FaultyFSDirectory : public Directory -{ +class FaultyFSDirectory : public Directory { public: - FaultyFSDirectory(const String& dir) - { + FaultyFSDirectory(const String& dir) { fsDir = FSDirectory::open(dir); lockFactory = fsDir->getLockFactory(); } - virtual ~FaultyFSDirectory() - { + virtual ~FaultyFSDirectory() { } LUCENE_CLASS(FaultyFSDirectory); @@ -134,62 +120,51 @@ class FaultyFSDirectory : public Directory FSDirectoryPtr fsDir; public: - virtual IndexInputPtr openInput(const String& name) - { + virtual IndexInputPtr openInput(const String& name) { return newLucene(fsDir->openInput(name)); } - virtual HashSet listAll() - { + virtual HashSet listAll() { return fsDir->listAll(); } - virtual bool fileExists(const String& name) - { + virtual bool fileExists(const String& name) { return fsDir->fileExists(name); } - virtual uint64_t fileModified(const String& name) - { + virtual uint64_t fileModified(const String& name) { return fsDir->fileModified(name); } - virtual void touchFile(const String& name) - { + virtual void touchFile(const String& name) { fsDir->touchFile(name); } - virtual void deleteFile(const String& name) - { + virtual void deleteFile(const String& name) { fsDir->deleteFile(name); } - virtual int64_t fileLength(const String& name) - { + virtual int64_t fileLength(const String& name) { return fsDir->fileLength(name); } - virtual IndexOutputPtr createOutput(const String& name) - { + virtual IndexOutputPtr createOutput(const String& name) { return fsDir->createOutput(name); } - virtual void close() - { + virtual void close() { fsDir->close(); } }; -static void checkSizeEquals(int32_t size, const uint8_t* sizebytes) -{ +static void checkSizeEquals(int32_t size, const uint8_t* sizebytes) { EXPECT_EQ((uint8_t)MiscUtils::unsignedShift(size, 24), sizebytes[0]); EXPECT_EQ((uint8_t)MiscUtils::unsignedShift(size, 16), sizebytes[1]); EXPECT_EQ((uint8_t)MiscUtils::unsignedShift(size, 8), sizebytes[2]); EXPECT_EQ((uint8_t)size, sizebytes[3]); } -TEST_F(FieldsReaderTest, testFieldsReader) -{ +TEST_F(FieldsReaderTest, testFieldsReader) { EXPECT_TRUE(dir); EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); @@ -226,8 +201,7 @@ TEST_F(FieldsReaderTest, testFieldsReader) reader->close(); } -TEST_F(FieldsReaderTest, testLazyFields) -{ +TEST_F(FieldsReaderTest, testLazyFields) { EXPECT_TRUE(dir); EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); @@ -274,8 +248,7 @@ TEST_F(FieldsReaderTest, testLazyFields) EXPECT_TRUE(bytes.equals(DocHelper::LAZY_FIELD_BINARY_BYTES)); } -TEST_F(FieldsReaderTest, testLazyFieldsAfterClose) -{ +TEST_F(FieldsReaderTest, testLazyFieldsAfterClose) { EXPECT_TRUE(dir); EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); @@ -296,18 +269,14 @@ TEST_F(FieldsReaderTest, testLazyFieldsAfterClose) EXPECT_TRUE(field); EXPECT_TRUE(field->isLazy()); reader->close(); - try - { + try { field->stringValue(); - } - catch (AlreadyClosedException& e) - { + } catch (AlreadyClosedException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } } -TEST_F(FieldsReaderTest, testLoadFirst) -{ +TEST_F(FieldsReaderTest, testLoadFirst) { EXPECT_TRUE(dir); EXPECT_TRUE(fieldInfos); FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); @@ -318,8 +287,7 @@ TEST_F(FieldsReaderTest, testLoadFirst) EXPECT_TRUE(doc); int32_t count = 0; Collection fields = doc->getFields(); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { EXPECT_TRUE(*field); String sv = (*field)->stringValue(); EXPECT_TRUE(!sv.empty()); @@ -330,8 +298,7 @@ TEST_F(FieldsReaderTest, testLoadFirst) /// Not really a test per se, but we should have some way of assessing whether this is worthwhile. /// Must test using a File based directory. -TEST_F(FieldsReaderTest, testLazyPerformance) -{ +TEST_F(FieldsReaderTest, testLazyPerformance) { String path(FileUtils::joinPath(getTempDir(), L"lazyDir")); FSDirectoryPtr tmpDir = FSDirectory::open(path); EXPECT_TRUE(tmpDir); @@ -350,8 +317,7 @@ TEST_F(FieldsReaderTest, testLazyPerformance) lazyFieldNames.add(DocHelper::LARGE_LAZY_FIELD_KEY); SetBasedFieldSelectorPtr fieldSelector = newLucene(HashSet::newInstance(), lazyFieldNames); - for (int32_t i = 0; i < length; ++i) - { + for (int32_t i = 0; i < length; ++i) { reader = newLucene(tmpDir, TEST_SEGMENT_NAME, fieldInfos); EXPECT_TRUE(reader); EXPECT_TRUE(reader->size() == 1); @@ -387,34 +353,32 @@ TEST_F(FieldsReaderTest, testLazyPerformance) FileUtils::removeDirectory(path); } -namespace TestLoadSize -{ - DECLARE_SHARED_PTR(TestableFieldSelector) +namespace TestLoadSize { - class TestableFieldSelector : public FieldSelector - { - public: - virtual ~TestableFieldSelector() - { - } +DECLARE_SHARED_PTR(TestableFieldSelector) + +class TestableFieldSelector : public FieldSelector { +public: + virtual ~TestableFieldSelector() { + } - LUCENE_CLASS(TestableFieldSelector); - - public: - virtual FieldSelectorResult accept(const String& fieldName) - { - if (fieldName == DocHelper::TEXT_FIELD_1_KEY || fieldName == DocHelper::LAZY_FIELD_BINARY_KEY) - return FieldSelector::SELECTOR_SIZE; - else if (fieldName == DocHelper::TEXT_FIELD_3_KEY) - return FieldSelector::SELECTOR_LOAD; - else - return FieldSelector::SELECTOR_NO_LOAD; + LUCENE_CLASS(TestableFieldSelector); + +public: + virtual FieldSelectorResult accept(const String& fieldName) { + if (fieldName == DocHelper::TEXT_FIELD_1_KEY || fieldName == DocHelper::LAZY_FIELD_BINARY_KEY) { + return FieldSelector::SELECTOR_SIZE; + } else if (fieldName == DocHelper::TEXT_FIELD_3_KEY) { + return FieldSelector::SELECTOR_LOAD; + } else { + return FieldSelector::SELECTOR_NO_LOAD; } - }; + } +}; + } -TEST_F(FieldsReaderTest, testLoadSize) -{ +TEST_F(FieldsReaderTest, testLoadSize) { FieldsReaderPtr reader = newLucene(dir, TEST_SEGMENT_NAME, fieldInfos); DocumentPtr doc = reader->doc(0, newLucene()); @@ -431,17 +395,16 @@ TEST_F(FieldsReaderTest, testLoadSize) reader->close(); } -TEST_F(FieldsReaderTest, testExceptions) -{ +TEST_F(FieldsReaderTest, testExceptions) { String indexDir(FileUtils::joinPath(getTempDir(), L"testfieldswriterexceptions")); LuceneException finally; - try - { + try { DirectoryPtr dir = newLucene(indexDir); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 2; ++i) + for (int32_t i = 0; i < 2; ++i) { writer->addDocument(testDoc); + } writer->optimize(); writer->close(); @@ -451,31 +414,22 @@ TEST_F(FieldsReaderTest, testExceptions) bool exc = false; - for (int32_t i = 0; i < 2; ++i) - { - try - { + for (int32_t i = 0; i < 2; ++i) { + try { reader->document(i); - } - catch (IOException&) - { + } catch (IOException&) { exc = true; // expected } - try - { + try { reader->document(i); - } - catch (IOException&) - { + } catch (IOException&) { exc = true; // expected } } EXPECT_TRUE(exc); reader->close(); dir->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } FileUtils::removeDirectory(indexDir); diff --git a/src/test/index/FilterIndexReaderTest.cpp b/src/test/index/FilterIndexReaderTest.cpp index 78c6e663..7da2a00e 100644 --- a/src/test/index/FilterIndexReaderTest.cpp +++ b/src/test/index/FilterIndexReaderTest.cpp @@ -24,80 +24,67 @@ DECLARE_SHARED_PTR(TestTermEnum) DECLARE_SHARED_PTR(TestTermPositions) /// Filter that only permits terms containing 'e' -class TestTermEnum : public FilterTermEnum -{ +class TestTermEnum : public FilterTermEnum { public: - TestTermEnum(const TermEnumPtr& termEnum) : FilterTermEnum(termEnum) - { + TestTermEnum(const TermEnumPtr& termEnum) : FilterTermEnum(termEnum) { } - virtual ~TestTermEnum() - { + virtual ~TestTermEnum() { } LUCENE_CLASS(TestTermEnum); public: - virtual bool next() - { - while (in->next()) - { - if (in->term()->text().find(L'e') != String::npos) + virtual bool next() { + while (in->next()) { + if (in->term()->text().find(L'e') != String::npos) { return true; + } } return false; } }; /// Filter that only returns odd numbered documents. -class TestTermPositions : public FilterTermPositions -{ +class TestTermPositions : public FilterTermPositions { public: - TestTermPositions(const TermPositionsPtr& in) : FilterTermPositions(in) - { + TestTermPositions(const TermPositionsPtr& in) : FilterTermPositions(in) { } - virtual ~TestTermPositions() - { + virtual ~TestTermPositions() { } LUCENE_CLASS(TestTermPositions); public: - virtual bool next() - { - while (in->next()) - { - if ((in->doc() % 2) == 1) + virtual bool next() { + while (in->next()) { + if ((in->doc() % 2) == 1) { return true; + } } return false; } }; -class TestReader : public FilterIndexReader -{ +class TestReader : public FilterIndexReader { public: - TestReader(const IndexReaderPtr& reader) : FilterIndexReader(reader) - { + TestReader(const IndexReaderPtr& reader) : FilterIndexReader(reader) { } - virtual ~TestReader() - { + virtual ~TestReader() { } LUCENE_CLASS(TestReader); public: /// Filter terms with TestTermEnum. - virtual TermEnumPtr terms() - { + virtual TermEnumPtr terms() { return newLucene(in->terms()); } /// Filter positions with TestTermPositions. - virtual TermPositionsPtr termPositions() - { + virtual TermPositionsPtr termPositions() { return newLucene(in->termPositions()); } }; @@ -105,8 +92,7 @@ class TestReader : public FilterIndexReader typedef LuceneTestFixture FilterIndexReaderTest; /// Tests the IndexReader::getFieldNames implementation -TEST_F(FilterIndexReaderTest, testFilterIndexReader) -{ +TEST_F(FilterIndexReaderTest, testFilterIndexReader) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -129,19 +115,20 @@ TEST_F(FilterIndexReaderTest, testFilterIndexReader) EXPECT_TRUE(reader->isOptimized()); TermEnumPtr terms = reader->terms(); - while (terms->next()) + while (terms->next()) { EXPECT_NE(terms->term()->text().find(L'e'), String::npos); + } terms->close(); TermPositionsPtr positions = reader->termPositions(newLucene(L"default", L"one")); - while (positions->next()) + while (positions->next()) { EXPECT_TRUE((positions->doc() % 2) == 1); + } int32_t NUM_DOCS = 3; TermDocsPtr td = reader->termDocs(TermPtr()); - for (int32_t i = 0; i < NUM_DOCS; ++i) - { + for (int32_t i = 0; i < NUM_DOCS; ++i) { EXPECT_TRUE(td->next()); EXPECT_EQ(i, td->doc()); EXPECT_EQ(1, td->freq()); diff --git a/src/test/index/IndexCommitTest.cpp b/src/test/index/IndexCommitTest.cpp index b38049b7..84d30d95 100644 --- a/src/test/index/IndexCommitTest.cpp +++ b/src/test/index/IndexCommitTest.cpp @@ -13,95 +13,78 @@ using namespace Lucene; typedef LuceneTestFixture IndexCommitTest; -namespace TestEqualsHashCode -{ - class TestIndexCommit1 : public IndexCommit - { - public: - TestIndexCommit1(const DirectoryPtr& dir) - { - this->dir = dir; - } - - virtual ~TestIndexCommit1() - { - } - - protected: - DirectoryPtr dir; - - public: - virtual String getSegmentsFileName() - { - return L"a"; - } - - virtual int64_t getVersion() - { - return 12; - } - - virtual DirectoryPtr getDirectory() - { - return dir; - } - - virtual HashSet getFileNames() - { - return HashSet(); - } - - virtual void deleteCommit() - { - } - - virtual int64_t getGeneration() - { - return 0; - } - - virtual int64_t getTimestamp() - { - return -1; - } - - virtual MapStringString getUserData() - { - return MapStringString(); - } - - virtual bool isDeleted() - { - return false; - } - - virtual bool isOptimized() - { - return false; - } - }; - - class TestIndexCommit2 : public TestIndexCommit1 - { - public: - TestIndexCommit2(const DirectoryPtr& dir) : TestIndexCommit1(dir) - { - } - - virtual ~TestIndexCommit2() - { - } - - public: - virtual String getSegmentsFileName() - { - return L"b"; - } - }; +namespace TestEqualsHashCode { + +class TestIndexCommit1 : public IndexCommit { +public: + TestIndexCommit1(const DirectoryPtr& dir) { + this->dir = dir; + } + + virtual ~TestIndexCommit1() { + } + +protected: + DirectoryPtr dir; + +public: + virtual String getSegmentsFileName() { + return L"a"; + } + + virtual int64_t getVersion() { + return 12; + } + + virtual DirectoryPtr getDirectory() { + return dir; + } + + virtual HashSet getFileNames() { + return HashSet(); + } + + virtual void deleteCommit() { + } + + virtual int64_t getGeneration() { + return 0; + } + + virtual int64_t getTimestamp() { + return -1; + } + + virtual MapStringString getUserData() { + return MapStringString(); + } + + virtual bool isDeleted() { + return false; + } + + virtual bool isOptimized() { + return false; + } +}; + +class TestIndexCommit2 : public TestIndexCommit1 { +public: + TestIndexCommit2(const DirectoryPtr& dir) : TestIndexCommit1(dir) { + } + + virtual ~TestIndexCommit2() { + } + +public: + virtual String getSegmentsFileName() { + return L"b"; + } +}; + } -TEST_F(IndexCommitTest, testEqualsHashCode) -{ +TEST_F(IndexCommitTest, testEqualsHashCode) { DirectoryPtr dir = newLucene(); IndexCommitPtr ic1 = newLucene(dir); diff --git a/src/test/index/IndexFileDeleterTest.cpp b/src/test/index/IndexFileDeleterTest.cpp index e2596454..0bf8d08d 100644 --- a/src/test/index/IndexFileDeleterTest.cpp +++ b/src/test/index/IndexFileDeleterTest.cpp @@ -25,22 +25,19 @@ using namespace Lucene; typedef LuceneTestFixture IndexFileDeleterTest; -static void addDoc(const IndexWriterPtr& writer, int32_t id) -{ +static void addDoc(const IndexWriterPtr& writer, int32_t id) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", StringUtils::toString(id), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } -static void copyFile(const DirectoryPtr& dir, const String& src, const String& dest) -{ +static void copyFile(const DirectoryPtr& dir, const String& src, const String& dest) { IndexInputPtr in = dir->openInput(src); IndexOutputPtr out = dir->createOutput(dest); ByteArray b = ByteArray::newInstance(1024); int64_t remainder = in->length(); - while (remainder > 0) - { + while (remainder > 0) { int32_t len = std::min(b.size(), (int32_t)remainder); in->readBytes(b.get(), 0, len); out->writeBytes(b.get(), len); @@ -50,40 +47,42 @@ static void copyFile(const DirectoryPtr& dir, const String& src, const String& d out->close(); } -static HashSet difFiles(Collection files1, Collection files2) -{ +static HashSet difFiles(Collection files1, Collection files2) { HashSet set1 = HashSet::newInstance(); HashSet set2 = HashSet::newInstance(); HashSet extra = HashSet::newInstance(); - for (Collection::iterator file = files1.begin(); file != files1.end(); ++file) + for (Collection::iterator file = files1.begin(); file != files1.end(); ++file) { set1.add(*file); - for (Collection::iterator file = files2.begin(); file != files2.end(); ++file) + } + for (Collection::iterator file = files2.begin(); file != files2.end(); ++file) { set2.add(*file); - for (HashSet::iterator file = set1.begin(); file != set1.end(); ++file) - { - if (!set2.contains(*file)) + } + for (HashSet::iterator file = set1.begin(); file != set1.end(); ++file) { + if (!set2.contains(*file)) { extra.add(*file); + } } - for (HashSet::iterator file = set2.begin(); file != set2.end(); ++file) - { - if (!set1.contains(*file)) + for (HashSet::iterator file = set2.begin(); file != set2.end(); ++file) { + if (!set1.contains(*file)) { extra.add(*file); + } } return extra; } -TEST_F(IndexFileDeleterTest, testDeleteLeftoverFiles) -{ +TEST_F(IndexFileDeleterTest, testDeleteLeftoverFiles) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); int32_t i = 0; - for (; i < 35; ++i) + for (; i < 35; ++i) { addDoc(writer, i); + } writer->setUseCompoundFile(false); - for (; i < 45; ++i) + for (; i < 45; ++i) { addDoc(writer, i); + } writer->close(); // Delete one doc so we get a .del file @@ -104,11 +103,9 @@ TEST_F(IndexFileDeleterTest, testDeleteLeftoverFiles) CompoundFileReaderPtr cfsReader = newLucene(dir, L"_2.cfs"); FieldInfosPtr fieldInfos = newLucene(cfsReader, L"_2.fnm"); int32_t contentFieldIndex = -1; - for (int32_t j = 0; j < fieldInfos->size(); ++j) - { + for (int32_t j = 0; j < fieldInfos->size(); ++j) { FieldInfoPtr fi = fieldInfos->fieldInfo(j); - if (fi->name == L"content") - { + if (fi->name == L"content") { contentFieldIndex = j; break; } diff --git a/src/test/index/IndexInputTest.cpp b/src/test/index/IndexInputTest.cpp index 47015461..322139e6 100644 --- a/src/test/index/IndexInputTest.cpp +++ b/src/test/index/IndexInputTest.cpp @@ -13,8 +13,7 @@ using namespace Lucene; typedef LuceneTestFixture IndexInputTest; -TEST_F(IndexInputTest, testReadInt) -{ +TEST_F(IndexInputTest, testReadInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 1, 2, 3, 4 }; std::memcpy(inputBytes.get(), input, 4); @@ -22,8 +21,7 @@ TEST_F(IndexInputTest, testReadInt) EXPECT_EQ(is->readInt(), 16909060); } -TEST_F(IndexInputTest, testReadVInt) -{ +TEST_F(IndexInputTest, testReadVInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 200, 201, 150, 96 }; std::memcpy(inputBytes.get(), input, 4); @@ -31,8 +29,7 @@ TEST_F(IndexInputTest, testReadVInt) EXPECT_EQ(is->readVInt(), 201696456); } -TEST_F(IndexInputTest, testReadLong) -{ +TEST_F(IndexInputTest, testReadLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 32, 43, 32, 96, 12, 54, 22, 96 }; std::memcpy(inputBytes.get(), input, 8); @@ -40,8 +37,7 @@ TEST_F(IndexInputTest, testReadLong) EXPECT_EQ(is->readLong(), 2317982030106072672LL); } -TEST_F(IndexInputTest, testReadVLong) -{ +TEST_F(IndexInputTest, testReadVLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 213, 143, 132, 196, 172, 154, 129, 96 }; std::memcpy(inputBytes.get(), input, 8); @@ -49,8 +45,7 @@ TEST_F(IndexInputTest, testReadVLong) EXPECT_EQ(is->readVLong(), 54048498881988565LL); } -TEST_F(IndexInputTest, testReadString) -{ +TEST_F(IndexInputTest, testReadString) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); @@ -58,8 +53,7 @@ TEST_F(IndexInputTest, testReadString) EXPECT_EQ(is->readString(), L"test string"); } -TEST_F(IndexInputTest, testReadModifiedUTF8String) -{ +TEST_F(IndexInputTest, testReadModifiedUTF8String) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); @@ -67,8 +61,7 @@ TEST_F(IndexInputTest, testReadModifiedUTF8String) EXPECT_EQ(is->readModifiedUTF8String(), L"test string"); } -TEST_F(IndexInputTest, testReadChars) -{ +TEST_F(IndexInputTest, testReadChars) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[11] = { 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 11); @@ -82,8 +75,7 @@ TEST_F(IndexInputTest, testReadChars) EXPECT_EQ(std::memcmp((wchar_t*)outputChars.get(), expected, 11 * sizeof(wchar_t)), 0); } -TEST_F(IndexInputTest, testSkipOneChar) -{ +TEST_F(IndexInputTest, testSkipOneChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -92,8 +84,7 @@ TEST_F(IndexInputTest, testSkipOneChar) EXPECT_EQ(is->getFilePointer(), 1); } -TEST_F(IndexInputTest, testSkipTwoChars) -{ +TEST_F(IndexInputTest, testSkipTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -102,8 +93,7 @@ TEST_F(IndexInputTest, testSkipTwoChars) EXPECT_EQ(is->getFilePointer(), 2); } -TEST_F(IndexInputTest, testSkipTwoCharsAdditionalChar) -{ +TEST_F(IndexInputTest, testSkipTwoCharsAdditionalChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 132, 132, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -112,8 +102,7 @@ TEST_F(IndexInputTest, testSkipTwoCharsAdditionalChar) EXPECT_EQ(is->getFilePointer(), 3); } -TEST_F(IndexInputTest, testSkipTwoCharsAdditionalTwoChars) -{ +TEST_F(IndexInputTest, testSkipTwoCharsAdditionalTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 232, 232, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -122,12 +111,11 @@ TEST_F(IndexInputTest, testSkipTwoCharsAdditionalTwoChars) EXPECT_EQ(is->getFilePointer(), 4); } -TEST_F(IndexInputTest, testRead) -{ +TEST_F(IndexInputTest, testRead) { ByteArray inputBytes(ByteArray::newInstance(100)); uint8_t input[88] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, - 'L', 'u', 'c', 'e', 'n', 'e', + 'L', 'u', 'c', 'e', 'n', 'e', // 2-byte UTF-8 (U+00BF "INVERTED QUESTION MARK") 0x02, 0xc2, 0xbf, 0x0a, 'L', 'u', 0xc2, 0xbf, 'c', 'e', 0xc2, 0xbf, 'n', 'e', @@ -142,7 +130,8 @@ TEST_F(IndexInputTest, testRead) 'L', 'u', 0xf0, 0x9d, 0x84, 0x9e, 'c', 'e', 0xf0, 0x9d, 0x85, 0xa0, 'n', 'e', // null bytes - 0x01, 0x00, 0x08, 'L', 'u', 0x00, 'c', 'e', 0x00, 'n', 'e'}; + 0x01, 0x00, 0x08, 'L', 'u', 0x00, 'c', 'e', 0x00, 'n', 'e' + }; std::memcpy(inputBytes.get(), input, 88); IndexInputPtr is = newLucene(inputBytes); @@ -163,26 +152,26 @@ TEST_F(IndexInputTest, testRead) EXPECT_EQ(is->readString(), UTF8_TO_STRING(eighthnote)); String readString(is->readString()); - #ifdef LPP_UNICODE_CHAR_SIZE_2 +#ifdef LPP_UNICODE_CHAR_SIZE_2 EXPECT_EQ(readString[0], 55348); EXPECT_EQ(readString[1], 56606); - #else +#else EXPECT_EQ(readString[0], 119070); - #endif +#endif readString = is->readString(); - #ifdef LPP_UNICODE_CHAR_SIZE_2 +#ifdef LPP_UNICODE_CHAR_SIZE_2 EXPECT_EQ(readString[0], 55348); EXPECT_EQ(readString[1], 56606); EXPECT_EQ(readString[2], 55348); EXPECT_EQ(readString[3], 56672); - #else +#else EXPECT_EQ(readString[0], 119070); EXPECT_EQ(readString[1], 119136); - #endif +#endif readString = is->readString(); - #ifdef LPP_UNICODE_CHAR_SIZE_2 +#ifdef LPP_UNICODE_CHAR_SIZE_2 EXPECT_EQ(readString[0], L'L'); EXPECT_EQ(readString[1], L'u'); EXPECT_EQ(readString[2], 55348); @@ -193,7 +182,7 @@ TEST_F(IndexInputTest, testRead) EXPECT_EQ(readString[7], 56672); EXPECT_EQ(readString[8], L'n'); EXPECT_EQ(readString[9], L'e'); - #else +#else EXPECT_EQ(readString[0], L'L'); EXPECT_EQ(readString[1], L'u'); EXPECT_EQ(readString[2], 119070); @@ -202,7 +191,7 @@ TEST_F(IndexInputTest, testRead) EXPECT_EQ(readString[5], 119136); EXPECT_EQ(readString[6], L'n'); EXPECT_EQ(readString[7], L'e'); - #endif +#endif readString = is->readString(); EXPECT_EQ(readString[0], 0); @@ -218,8 +207,7 @@ TEST_F(IndexInputTest, testRead) EXPECT_EQ(readString[7], L'e'); } -TEST_F(IndexInputTest, testSkipChars) -{ +TEST_F(IndexInputTest, testSkipChars) { ByteArray inputBytes(ByteArray::newInstance(100)); uint8_t input[17] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, 'L', 'u', 'c', 'e', 'n', 'e'}; std::memcpy(inputBytes.get(), input, 17); @@ -236,21 +224,19 @@ TEST_F(IndexInputTest, testSkipChars) EXPECT_EQ(String((wchar_t*)remainingBytes.get(), 3), L"ene"); } -struct lessKey -{ - inline bool operator()(const MapStringString::key_value& first, const MapStringString::key_value& second) const - { +struct lessKey { + inline bool operator()(const MapStringString::key_value& first, const MapStringString::key_value& second) const { return (first.first < second.first); } }; -TEST_F(IndexInputTest, testReadStringMap) -{ +TEST_F(IndexInputTest, testReadStringMap) { ByteArray inputBytes(ByteArray::newInstance(100)); uint8_t input[34] = { 0, 0, 0, 3, 4, 'k', 'e', 'y', '1', 4, 'v', 'a', 'l', '1', 4, 'k', 'e', 'y', '2', 4, 'v', 'a', 'l', '2', - 4, 'k', 'e', 'y', '3', 4, 'v', 'a', 'l', '3' }; + 4, 'k', 'e', 'y', '3', 4, 'v', 'a', 'l', '3' + }; std::memcpy(inputBytes.get(), input, 34); IndexInputPtr is = newLucene(inputBytes); @@ -263,8 +249,7 @@ TEST_F(IndexInputTest, testReadStringMap) std::sort(orderedMap.begin(), orderedMap.end(), lessKey()); int32_t count = 1; - for (Collection::iterator mapEntry = orderedMap.begin(); mapEntry != orderedMap.end(); ++mapEntry, ++count) - { + for (Collection::iterator mapEntry = orderedMap.begin(); mapEntry != orderedMap.end(); ++mapEntry, ++count) { EXPECT_EQ(mapEntry->first, L"key" + StringUtils::toString(count)); EXPECT_EQ(mapEntry->second, L"val" + StringUtils::toString(count)); } diff --git a/src/test/index/IndexReaderCloneNormsTest.cpp b/src/test/index/IndexReaderCloneNormsTest.cpp index 2a15996e..cdd213f6 100644 --- a/src/test/index/IndexReaderCloneNormsTest.cpp +++ b/src/test/index/IndexReaderCloneNormsTest.cpp @@ -22,25 +22,20 @@ using namespace Lucene; -class SimilarityOne : public DefaultSimilarity -{ +class SimilarityOne : public DefaultSimilarity { public: - virtual ~SimilarityOne() - { + virtual ~SimilarityOne() { } public: - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } }; -class IndexReaderCloneNormsTest : public LuceneTestFixture -{ +class IndexReaderCloneNormsTest : public LuceneTestFixture { public: - IndexReaderCloneNormsTest() - { + IndexReaderCloneNormsTest() { similarityOne = newLucene(); anlzr = newLucene(LuceneVersion::LUCENE_CURRENT); numDocNorms = 0; @@ -48,8 +43,7 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture normDelta = 0.001; } - virtual ~IndexReaderCloneNormsTest() - { + virtual ~IndexReaderCloneNormsTest() { } protected: @@ -64,8 +58,7 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture double normDelta; public: - void createIndex(const DirectoryPtr& dir) - { + void createIndex(const DirectoryPtr& dir) { IndexWriterPtr iw = newLucene(dir, anlzr, true, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); iw->setMergeFactor(3); @@ -74,35 +67,35 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture iw->close(); } - void createIndex(const DirectoryPtr& dir, bool multiSegment) - { + void createIndex(const DirectoryPtr& dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); w->setMergePolicy(newLucene(w)); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { w->addDocument(createDocument(i, 4)); - if (multiSegment && (i % 10) == 0) + if (multiSegment && (i % 10) == 0) { w->commit(); + } } - if (!multiSegment) + if (!multiSegment) { w->optimize(); + } w->close(); IndexReaderPtr r = IndexReader::open(dir, false); - if (multiSegment) + if (multiSegment) { EXPECT_TRUE(r->getSequentialSubReaders().size() > 1); - else + } else { EXPECT_EQ(r->getSequentialSubReaders().size(), 1); + } r->close(); } - DocumentPtr createDocument(int32_t n, int32_t numFields) - { + DocumentPtr createDocument(int32_t n, int32_t numFields) { StringStream sb; DocumentPtr doc = newLucene(); sb << L"a" << n; @@ -110,14 +103,14 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture doc->add(newLucene(L"fielda", sb.str(), Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS)); doc->add(newLucene(L"fieldb", sb.str(), Field::STORE_YES, Field::INDEX_NO)); sb << L" b" << n; - for (int32_t i = 1; i < numFields; ++i) + for (int32_t i = 1; i < numFields; ++i) { doc->add(newLucene(L"field" + StringUtils::toString(i + 1), sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED)); + } return doc; } /// try cloning and reopening the norms - void doTestNorms(const DirectoryPtr& dir) - { + void doTestNorms(const DirectoryPtr& dir) { addDocs(dir, 12, true); IndexReaderPtr ir = IndexReader::open(dir, false); verifyIndex(ir); @@ -135,17 +128,14 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture irc3->close(); } - void modifyNormsForF1(const DirectoryPtr& dir) - { + void modifyNormsForF1(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); modifyNormsForF1(ir); } - void modifyNormsForF1(const IndexReaderPtr& ir) - { + void modifyNormsForF1(const IndexReaderPtr& ir) { int32_t n = ir->maxDoc(); - for (int32_t i = 0; i < n; i += 3) // modify for every third doc - { + for (int32_t i = 0; i < n; i += 3) { // modify for every third doc int32_t k = (i * 3) % modifiedNorms.size(); double origNorm = modifiedNorms[i]; double newNorm = modifiedNorms[k]; @@ -156,24 +146,22 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture } } - void addDocs(const DirectoryPtr& dir, int32_t ndocs, bool compound) - { + void addDocs(const DirectoryPtr& dir, int32_t ndocs, bool compound) { IndexWriterPtr iw = newLucene(dir, anlzr, false, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); iw->setMergeFactor(3); iw->setSimilarity(similarityOne); iw->setUseCompoundFile(compound); - for (int32_t i = 0; i < ndocs; ++i) + for (int32_t i = 0; i < ndocs; ++i) { iw->addDocument(newDoc()); + } iw->close(); } - DocumentPtr newDoc() - { + DocumentPtr newDoc() { DocumentPtr d = newLucene(); double boost = nextNorm(); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { FieldPtr f = newLucene(L"f" + StringUtils::toString(i), L"v" + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_NOT_ANALYZED); f->setBoost(boost); d->add(f); @@ -181,20 +169,16 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture return d; } - double nextNorm() - { + double nextNorm() { double norm = lastNorm + normDelta; - do - { + do { double norm1 = Similarity::decodeNorm(Similarity::encodeNorm(norm)); - if (norm1 > lastNorm) - { + if (norm1 > lastNorm) { norm = norm1; break; } norm += normDelta; - } - while (true); + } while (true); norms.add(numDocNorms, norm); modifiedNorms.add(numDocNorms, norm); ++numDocNorms; @@ -203,23 +187,19 @@ class IndexReaderCloneNormsTest : public LuceneTestFixture return norm; } - void verifyIndex(const DirectoryPtr& dir) - { + void verifyIndex(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); verifyIndex(ir); ir->close(); } - void verifyIndex(const IndexReaderPtr& ir) - { - for (int32_t i = 0; i < NUM_FIELDS; ++i) - { + void verifyIndex(const IndexReaderPtr& ir) { + for (int32_t i = 0; i < NUM_FIELDS; ++i) { String field = L"f" + StringUtils::toString(i); ByteArray b = ir->norms(field); EXPECT_EQ(numDocNorms, b.size()); Collection storedNorms = (i == 1 ? modifiedNorms : norms); - for (int32_t j = 0; j < b.size(); ++j) - { + for (int32_t j = 0; j < b.size(); ++j) { double norm = Similarity::decodeNorm(b[j]); double norm1 = storedNorms[j]; EXPECT_EQ(norm, norm1); // 0.000001 ?? @@ -232,8 +212,7 @@ const int32_t IndexReaderCloneNormsTest::NUM_FIELDS = 10; /// Test that norms values are preserved as the index is maintained. Including separate norms. /// Including merging indexes with separate norms. Including optimize. -TEST_F(IndexReaderCloneNormsTest, testNorms) -{ +TEST_F(IndexReaderCloneNormsTest, testNorms) { // test with a single index: index1 String indexDir1(FileUtils::joinPath(getTempDir(), L"lucenetestindex1")); DirectoryPtr dir1 = FSDirectory::open(indexDir1); @@ -295,8 +274,7 @@ TEST_F(IndexReaderCloneNormsTest, testNorms) dir3->close(); } -TEST_F(IndexReaderCloneNormsTest, testNormsClose) -{ +TEST_F(IndexReaderCloneNormsTest, testNormsClose) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); SegmentReaderPtr reader1 = SegmentReader::getOnlySegmentReader(dir1); @@ -312,8 +290,7 @@ TEST_F(IndexReaderCloneNormsTest, testNormsClose) dir1->close(); } -TEST_F(IndexReaderCloneNormsTest, testNormsRefCounting) -{ +TEST_F(IndexReaderCloneNormsTest, testNormsRefCounting) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -337,12 +314,9 @@ TEST_F(IndexReaderCloneNormsTest, testNormsRefCounting) reader4C->setNorm(5, L"field1", 0.33); // generate a cannot update exception in reader1 - try - { + try { reader3C->setNorm(1, L"field1", 0.99); - } - catch (LockObtainFailedException& e) - { + } catch (LockObtainFailedException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } diff --git a/src/test/index/IndexReaderCloneTest.cpp b/src/test/index/IndexReaderCloneTest.cpp index 2b7c71e5..81df66b2 100644 --- a/src/test/index/IndexReaderCloneTest.cpp +++ b/src/test/index/IndexReaderCloneTest.cpp @@ -31,8 +31,7 @@ using namespace Lucene; /// of the deletedDocs and norms is implemented properly typedef LuceneTestFixture IndexReaderCloneTest; -static DocumentPtr createDocument(int32_t n, int32_t numFields) -{ +static DocumentPtr createDocument(int32_t n, int32_t numFields) { StringStream sb; DocumentPtr doc = newLucene(); sb << L"a" << n; @@ -40,53 +39,50 @@ static DocumentPtr createDocument(int32_t n, int32_t numFields) doc->add(newLucene(L"fielda", sb.str(), Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS)); doc->add(newLucene(L"fieldb", sb.str(), Field::STORE_YES, Field::INDEX_NO)); sb << L" b" << n; - for (int32_t i = 1; i < numFields; ++i) + for (int32_t i = 1; i < numFields; ++i) { doc->add(newLucene(L"field" + StringUtils::toString(i + 1), sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED)); + } return doc; } -static void createIndex(const DirectoryPtr& dir, bool multiSegment) -{ +static void createIndex(const DirectoryPtr& dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); w->setMergePolicy(newLucene(w)); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { w->addDocument(createDocument(i, 4)); - if (multiSegment && (i % 10) == 0) + if (multiSegment && (i % 10) == 0) { w->commit(); + } } - if (!multiSegment) + if (!multiSegment) { w->optimize(); + } w->close(); IndexReaderPtr r = IndexReader::open(dir, false); - if (multiSegment) + if (multiSegment) { EXPECT_TRUE(r->getSequentialSubReaders().size() > 1); - else + } else { EXPECT_EQ(r->getSequentialSubReaders().size(), 1); + } r->close(); } -static bool isReadOnly(const IndexReaderPtr& r) -{ +static bool isReadOnly(const IndexReaderPtr& r) { return (MiscUtils::typeOf(r) || MiscUtils::typeOf(r)); } -static bool deleteWorked(int32_t doc, const IndexReaderPtr& r) -{ +static bool deleteWorked(int32_t doc, const IndexReaderPtr& r) { bool exception = false; - try - { + try { // trying to delete from the original reader should throw an exception r->deleteDocument(doc); - } - catch (...) - { + } catch (...) { exception = true; } return !exception; @@ -98,8 +94,7 @@ static bool deleteWorked(int32_t doc, const IndexReaderPtr& r) /// 4. Verify the norms are not the same on each reader /// 5. Verify the doc deleted is only in the cloned reader /// 6. Try to delete a document in the original reader, an exception should be thrown -static void performDefaultTests(const IndexReaderPtr& r1) -{ +static void performDefaultTests(const IndexReaderPtr& r1) { double norm1 = Similarity::decodeNorm(r1->norms(L"field1")[4]); IndexReaderPtr pr1Clone = boost::dynamic_pointer_cast(r1->clone()); @@ -112,85 +107,71 @@ static void performDefaultTests(const IndexReaderPtr& r1) EXPECT_TRUE(pr1Clone->isDeleted(10)); // try to update the original reader, which should throw an exception - try - { + try { r1->deleteDocument(11); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::Null)(e)); } pr1Clone->close(); } -static void modifyIndex(int32_t i, const DirectoryPtr& dir) -{ - switch (i) - { - case 0: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->deleteDocuments(newLucene(L"field2", L"a11")); - w->deleteDocuments(newLucene(L"field2", L"b30")); - w->close(); - break; - } - case 1: - { - IndexReaderPtr reader = IndexReader::open(dir, false); - reader->setNorm(4, L"field1", (uint8_t)123); - reader->setNorm(44, L"field2", (uint8_t)222); - reader->setNorm(44, L"field4", (uint8_t)22); - reader->close(); - break; - } - case 2: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->optimize(); - w->close(); - break; - } - case 3: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->addDocument(createDocument(101, 4)); - w->optimize(); - w->addDocument(createDocument(102, 4)); - w->addDocument(createDocument(103, 4)); - w->close(); - break; - } - case 4: - { - IndexReaderPtr reader = IndexReader::open(dir, false); - reader->setNorm(5, L"field1", (uint8_t)123); - reader->setNorm(55, L"field2", (uint8_t)222); - reader->close(); - break; - } - case 5: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->addDocument(createDocument(101, 4)); - w->close(); - break; - } +static void modifyIndex(int32_t i, const DirectoryPtr& dir) { + switch (i) { + case 0: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->deleteDocuments(newLucene(L"field2", L"a11")); + w->deleteDocuments(newLucene(L"field2", L"b30")); + w->close(); + break; + } + case 1: { + IndexReaderPtr reader = IndexReader::open(dir, false); + reader->setNorm(4, L"field1", (uint8_t)123); + reader->setNorm(44, L"field2", (uint8_t)222); + reader->setNorm(44, L"field4", (uint8_t)22); + reader->close(); + break; + } + case 2: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->optimize(); + w->close(); + break; + } + case 3: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->addDocument(createDocument(101, 4)); + w->optimize(); + w->addDocument(createDocument(102, 4)); + w->addDocument(createDocument(103, 4)); + w->close(); + break; + } + case 4: { + IndexReaderPtr reader = IndexReader::open(dir, false); + reader->setNorm(5, L"field1", (uint8_t)123); + reader->setNorm(55, L"field2", (uint8_t)222); + reader->close(); + break; + } + case 5: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->addDocument(createDocument(101, 4)); + w->close(); + break; + } } } -static void checkDelDocsRefCountEquals(int32_t refCount, const SegmentReaderPtr& reader) -{ +static void checkDelDocsRefCountEquals(int32_t refCount, const SegmentReaderPtr& reader) { EXPECT_EQ(refCount, reader->deletedDocsRef->refCount()); } -static void checkDocDeleted(const SegmentReaderPtr& reader, const SegmentReaderPtr& reader2, int32_t doc) -{ +static void checkDocDeleted(const SegmentReaderPtr& reader, const SegmentReaderPtr& reader2, int32_t doc) { EXPECT_EQ(reader->isDeleted(doc), reader2->isDeleted(doc)); } -TEST_F(IndexReaderCloneTest, testCloneReadOnlySegmentReader) -{ +TEST_F(IndexReaderCloneTest, testCloneReadOnlySegmentReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr reader = IndexReader::open(dir1, false); @@ -203,8 +184,7 @@ TEST_F(IndexReaderCloneTest, testCloneReadOnlySegmentReader) } /// Open non-readOnly reader1, clone to non-readOnly reader2, make sure we can change reader2 -TEST_F(IndexReaderCloneTest, testCloneNoChangesStillReadOnly) -{ +TEST_F(IndexReaderCloneTest, testCloneNoChangesStillReadOnly) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr r1 = IndexReader::open(dir1, false); @@ -216,8 +196,7 @@ TEST_F(IndexReaderCloneTest, testCloneNoChangesStillReadOnly) } /// Open non-readOnly reader1, clone to non-readOnly reader2, make sure we can change reader1 -TEST_F(IndexReaderCloneTest, testCloneWriteToOrig) -{ +TEST_F(IndexReaderCloneTest, testCloneWriteToOrig) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr r1 = IndexReader::open(dir1, false); @@ -229,8 +208,7 @@ TEST_F(IndexReaderCloneTest, testCloneWriteToOrig) } /// Open non-readOnly reader1, clone to non-readOnly reader2, make sure we can change reader2 -TEST_F(IndexReaderCloneTest, testCloneWriteToClone) -{ +TEST_F(IndexReaderCloneTest, testCloneWriteToClone) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr r1 = IndexReader::open(dir1, false); @@ -247,8 +225,7 @@ TEST_F(IndexReaderCloneTest, testCloneWriteToClone) } /// Create single-segment index, open non-readOnly SegmentReader, add docs, reopen to multireader, then do delete -TEST_F(IndexReaderCloneTest, testReopenSegmentReaderToMultiReader) -{ +TEST_F(IndexReaderCloneTest, testReopenSegmentReaderToMultiReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr reader1 = IndexReader::open(dir1, false); @@ -265,8 +242,7 @@ TEST_F(IndexReaderCloneTest, testReopenSegmentReaderToMultiReader) } /// Open non-readOnly reader1, clone to readOnly reader2 -TEST_F(IndexReaderCloneTest, testCloneWriteableToReadOnly) -{ +TEST_F(IndexReaderCloneTest, testCloneWriteableToReadOnly) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader = IndexReader::open(dir1, false); @@ -282,8 +258,7 @@ TEST_F(IndexReaderCloneTest, testCloneWriteableToReadOnly) } /// Open non-readOnly reader1, reopen to readOnly reader2 -TEST_F(IndexReaderCloneTest, testReopenWriteableToReadOnly) -{ +TEST_F(IndexReaderCloneTest, testReopenWriteableToReadOnly) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader = IndexReader::open(dir1, false); @@ -301,8 +276,7 @@ TEST_F(IndexReaderCloneTest, testReopenWriteableToReadOnly) } /// Open readOnly reader1, clone to non-readOnly reader2 -TEST_F(IndexReaderCloneTest, testCloneReadOnlyToWriteable) -{ +TEST_F(IndexReaderCloneTest, testCloneReadOnlyToWriteable) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader1 = IndexReader::open(dir1, true); @@ -319,8 +293,7 @@ TEST_F(IndexReaderCloneTest, testCloneReadOnlyToWriteable) } /// Open non-readOnly reader1 on multi-segment index, then optimize the index, then clone to readOnly reader2 -TEST_F(IndexReaderCloneTest, testReadOnlyCloneAfterOptimize) -{ +TEST_F(IndexReaderCloneTest, testReadOnlyCloneAfterOptimize) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader1 = IndexReader::open(dir1, false); @@ -334,8 +307,7 @@ TEST_F(IndexReaderCloneTest, testReadOnlyCloneAfterOptimize) dir1->close(); } -TEST_F(IndexReaderCloneTest, testCloneReadOnlyDirectoryReader) -{ +TEST_F(IndexReaderCloneTest, testCloneReadOnlyDirectoryReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); IndexReaderPtr reader = IndexReader::open(dir1, false); @@ -346,8 +318,7 @@ TEST_F(IndexReaderCloneTest, testCloneReadOnlyDirectoryReader) dir1->close(); } -TEST_F(IndexReaderCloneTest, testParallelReader) -{ +TEST_F(IndexReaderCloneTest, testParallelReader) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); @@ -366,8 +337,7 @@ TEST_F(IndexReaderCloneTest, testParallelReader) dir2->close(); } -TEST_F(IndexReaderCloneTest, testMixedReaders) -{ +TEST_F(IndexReaderCloneTest, testMixedReaders) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); @@ -384,8 +354,7 @@ TEST_F(IndexReaderCloneTest, testMixedReaders) dir2->close(); } -TEST_F(IndexReaderCloneTest, testSegmentReaderUndeleteall) -{ +TEST_F(IndexReaderCloneTest, testSegmentReaderUndeleteall) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); SegmentReaderPtr origSegmentReader = SegmentReader::getOnlySegmentReader(dir1); @@ -398,8 +367,7 @@ TEST_F(IndexReaderCloneTest, testSegmentReaderUndeleteall) dir1->close(); } -TEST_F(IndexReaderCloneTest, testSegmentReaderCloseReferencing) -{ +TEST_F(IndexReaderCloneTest, testSegmentReaderCloseReferencing) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); SegmentReaderPtr origSegmentReader = SegmentReader::getOnlySegmentReader(dir1); @@ -417,8 +385,7 @@ TEST_F(IndexReaderCloneTest, testSegmentReaderCloseReferencing) dir1->close(); } -TEST_F(IndexReaderCloneTest, testSegmentReaderDelDocsReferenceCounting) -{ +TEST_F(IndexReaderCloneTest, testSegmentReaderDelDocsReferenceCounting) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr origReader = IndexReader::open(dir1, false); @@ -446,12 +413,9 @@ TEST_F(IndexReaderCloneTest, testSegmentReaderDelDocsReferenceCounting) EXPECT_TRUE(!origSegmentReader->isDeleted(2)); // doc 2 should not be deleted in original segmentreader EXPECT_TRUE(clonedSegmentReader->isDeleted(2)); // doc 2 should be deleted in cloned segmentreader - try - { + try { origReader->deleteDocument(4); - } - catch (LockObtainFailedException& e) - { + } catch (LockObtainFailedException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } @@ -473,8 +437,7 @@ TEST_F(IndexReaderCloneTest, testSegmentReaderDelDocsReferenceCounting) dir1->close(); } -TEST_F(IndexReaderCloneTest, testCloneWithDeletes) -{ +TEST_F(IndexReaderCloneTest, testCloneWithDeletes) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr origReader = IndexReader::open(dir1, false); @@ -490,8 +453,7 @@ TEST_F(IndexReaderCloneTest, testCloneWithDeletes) dir1->close(); } -TEST_F(IndexReaderCloneTest, testCloneWithSetNorm) -{ +TEST_F(IndexReaderCloneTest, testCloneWithSetNorm) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr orig = IndexReader::open(dir1, false); @@ -510,8 +472,7 @@ TEST_F(IndexReaderCloneTest, testCloneWithSetNorm) dir1->close(); } -TEST_F(IndexReaderCloneTest, testCloneSubreaders) -{ +TEST_F(IndexReaderCloneTest, testCloneSubreaders) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); @@ -521,16 +482,17 @@ TEST_F(IndexReaderCloneTest, testCloneSubreaders) EXPECT_TRUE(subs.size() > 1); Collection clones = Collection::newInstance(subs.size()); - for (int32_t x = 0; x < subs.size(); ++x) + for (int32_t x = 0; x < subs.size(); ++x) { clones[x] = boost::dynamic_pointer_cast(subs[x]->clone()); + } reader->close(); - for (int32_t x = 0; x < subs.size(); ++x) + for (int32_t x = 0; x < subs.size(); ++x) { clones[x]->close(); + } dir1->close(); } -TEST_F(IndexReaderCloneTest, testIncDecRef) -{ +TEST_F(IndexReaderCloneTest, testIncDecRef) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); IndexReaderPtr r1 = IndexReader::open(dir1, false); @@ -547,8 +509,7 @@ TEST_F(IndexReaderCloneTest, testIncDecRef) dir1->close(); } -TEST_F(IndexReaderCloneTest, testCloseStoredFields) -{ +TEST_F(IndexReaderCloneTest, testCloseStoredFields) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); w->setUseCompoundFile(false); diff --git a/src/test/index/IndexReaderReopenTest.cpp b/src/test/index/IndexReaderReopenTest.cpp index 5e9af7cf..ac22db41 100644 --- a/src/test/index/IndexReaderReopenTest.cpp +++ b/src/test/index/IndexReaderReopenTest.cpp @@ -41,108 +41,91 @@ using namespace Lucene; typedef LuceneTestFixture IndexReaderReopenTest; -namespace TestReopen -{ - DECLARE_SHARED_PTR(TestableReopen) - DECLARE_SHARED_PTR(ReaderCouple) - DECLARE_SHARED_PTR(ReaderThread) - DECLARE_SHARED_PTR(ReaderThreadTask) - - class TestableReopen - { - public: - virtual ~TestableReopen() - { - } +namespace TestReopen { - public: - virtual IndexReaderPtr openReader() = 0; - virtual void modifyIndex(int32_t i) = 0; - }; +DECLARE_SHARED_PTR(TestableReopen) +DECLARE_SHARED_PTR(ReaderCouple) +DECLARE_SHARED_PTR(ReaderThread) +DECLARE_SHARED_PTR(ReaderThreadTask) - class ReaderCouple - { - public: - ReaderCouple(const IndexReaderPtr& r1, const IndexReaderPtr& r2) - { - newReader = r1; - refreshedReader = r2; - } +class TestableReopen { +public: + virtual ~TestableReopen() { + } - virtual ~ReaderCouple() - { - } +public: + virtual IndexReaderPtr openReader() = 0; + virtual void modifyIndex(int32_t i) = 0; +}; - public: - IndexReaderPtr newReader; - IndexReaderPtr refreshedReader; - }; +class ReaderCouple { +public: + ReaderCouple(const IndexReaderPtr& r1, const IndexReaderPtr& r2) { + newReader = r1; + refreshedReader = r2; + } - class ReaderThreadTask : public LuceneObject - { - public: - ReaderThreadTask() - { - stopped = false; - } + virtual ~ReaderCouple() { + } - virtual ~ReaderThreadTask() - { - } +public: + IndexReaderPtr newReader; + IndexReaderPtr refreshedReader; +}; - LUCENE_CLASS(ReaderThreadTask); +class ReaderThreadTask : public LuceneObject { +public: + ReaderThreadTask() { + stopped = false; + } - protected: - bool stopped; + virtual ~ReaderThreadTask() { + } - public: - void stop() - { - stopped = true; - } + LUCENE_CLASS(ReaderThreadTask); - virtual void run() = 0; - }; +protected: + bool stopped; - class ReaderThread : public LuceneThread - { - public: - ReaderThread(const ReaderThreadTaskPtr& task) - { - this->task = task; - } +public: + void stop() { + stopped = true; + } - virtual ~ReaderThread() - { - } + virtual void run() = 0; +}; - LUCENE_CLASS(ReaderThread); +class ReaderThread : public LuceneThread { +public: + ReaderThread(const ReaderThreadTaskPtr& task) { + this->task = task; + } - protected: - ReaderThreadTaskPtr task; + virtual ~ReaderThread() { + } - public: - void stopThread() - { - task->stop(); - } + LUCENE_CLASS(ReaderThread); - virtual void run() - { - try - { - task->run(); - } - catch (LuceneException& e) - { - FAIL() << "Unexpected exception: " << e.getError(); - } +protected: + ReaderThreadTaskPtr task; + +public: + void stopThread() { + task->stop(); + } + + virtual void run() { + try { + task->run(); + } catch (LuceneException& e) { + FAIL() << "Unexpected exception: " << e.getError(); } - }; + } +}; + } -static DocumentPtr createDocument(int32_t n, int32_t numFields) -{ +static DocumentPtr createDocument(int32_t n, int32_t numFields) { StringStream sb; DocumentPtr doc = newLucene(); sb << L"a" << n; @@ -150,96 +133,89 @@ static DocumentPtr createDocument(int32_t n, int32_t numFields) doc->add(newLucene(L"fielda", sb.str(), Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS)); doc->add(newLucene(L"fieldb", sb.str(), Field::STORE_YES, Field::INDEX_NO)); sb << L" b" << n; - for (int32_t i = 1; i < numFields; ++i) + for (int32_t i = 1; i < numFields; ++i) { doc->add(newLucene(L"field" + StringUtils::toString(i + 1), sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED)); + } return doc; } -static void createIndex(const DirectoryPtr& dir, bool multiSegment) -{ +static void createIndex(const DirectoryPtr& dir, bool multiSegment) { IndexWriter::unlock(dir); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); w->setMergePolicy(newLucene(w)); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { w->addDocument(createDocument(i, 4)); - if (multiSegment && (i % 10) == 0) + if (multiSegment && (i % 10) == 0) { w->commit(); + } } - if (!multiSegment) + if (!multiSegment) { w->optimize(); + } w->close(); IndexReaderPtr r = IndexReader::open(dir, false); - if (multiSegment) + if (multiSegment) { EXPECT_TRUE(r->getSequentialSubReaders().size() > 1); - else + } else { EXPECT_EQ(r->getSequentialSubReaders().size(), 1); + } r->close(); } -static void _modifyIndex(int32_t i, const DirectoryPtr& dir) -{ - switch (i) - { - case 0: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->deleteDocuments(newLucene(L"field2", L"a11")); - w->deleteDocuments(newLucene(L"field2", L"b30")); - w->close(); - break; - } - case 1: - { - IndexReaderPtr reader = IndexReader::open(dir, false); - reader->setNorm(4, L"field1", (uint8_t)123); - reader->setNorm(44, L"field2", (uint8_t)222); - reader->setNorm(44, L"field4", (uint8_t)22); - reader->close(); - break; - } - case 2: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->optimize(); - w->close(); - break; - } - case 3: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->addDocument(createDocument(101, 4)); - w->optimize(); - w->addDocument(createDocument(102, 4)); - w->addDocument(createDocument(103, 4)); - w->close(); - break; - } - case 4: - { - IndexReaderPtr reader = IndexReader::open(dir, false); - reader->setNorm(5, L"field1", (uint8_t)123); - reader->setNorm(55, L"field2", (uint8_t)222); - reader->close(); - break; - } - case 5: - { - IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - w->addDocument(createDocument(101, 4)); - w->close(); - break; - } +static void _modifyIndex(int32_t i, const DirectoryPtr& dir) { + switch (i) { + case 0: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->deleteDocuments(newLucene(L"field2", L"a11")); + w->deleteDocuments(newLucene(L"field2", L"b30")); + w->close(); + break; + } + case 1: { + IndexReaderPtr reader = IndexReader::open(dir, false); + reader->setNorm(4, L"field1", (uint8_t)123); + reader->setNorm(44, L"field2", (uint8_t)222); + reader->setNorm(44, L"field4", (uint8_t)22); + reader->close(); + break; + } + case 2: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->optimize(); + w->close(); + break; + } + case 3: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->addDocument(createDocument(101, 4)); + w->optimize(); + w->addDocument(createDocument(102, 4)); + w->addDocument(createDocument(103, 4)); + w->close(); + break; + } + case 4: { + IndexReaderPtr reader = IndexReader::open(dir, false); + reader->setNorm(5, L"field1", (uint8_t)123); + reader->setNorm(55, L"field2", (uint8_t)222); + reader->close(); + break; + } + case 5: { + IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); + w->addDocument(createDocument(101, 4)); + w->close(); + break; + } } } -static void checkIndexEquals(const IndexReaderPtr& index1, const IndexReaderPtr& index2) -{ +static void checkIndexEquals(const IndexReaderPtr& index1, const IndexReaderPtr& index2) { EXPECT_EQ(index1->numDocs(), index2->numDocs()); EXPECT_EQ(index1->maxDoc(), index2->maxDoc()); EXPECT_EQ(index1->hasDeletions(), index2->hasDeletions()); @@ -254,39 +230,36 @@ static void checkIndexEquals(const IndexReaderPtr& index1, const IndexReaderPtr& std::sort(fields2.begin(), fields2.end()); EXPECT_EQ(fields1.size(), fields2.size()); - for (int32_t i = 0; i < fields1.size(); ++i) + for (int32_t i = 0; i < fields1.size(); ++i) { EXPECT_EQ(fields1[i], fields2[i]); + } // check norms - for (int32_t i = 0; i < fields1.size(); ++i) - { + for (int32_t i = 0; i < fields1.size(); ++i) { String curField = fields1[i]; ByteArray norms1 = index1->norms(curField); ByteArray norms2 = index2->norms(curField); - if (norms1 && norms2) - { + if (norms1 && norms2) { EXPECT_TRUE(norms1.equals(norms2)); - } - else + } else { EXPECT_TRUE(norms1 == norms2); + } } // check deletions - for (int32_t i = 0; i < index1->maxDoc(); ++i) + for (int32_t i = 0; i < index1->maxDoc(); ++i) { EXPECT_EQ(index1->isDeleted(i), index2->isDeleted(i)); + } // check stored fields - for (int32_t i = 0; i < index1->maxDoc(); ++i) - { - if (!index1->isDeleted(i)) - { + for (int32_t i = 0; i < index1->maxDoc(); ++i) { + if (!index1->isDeleted(i)) { DocumentPtr doc1 = index1->document(i); DocumentPtr doc2 = index2->document(i); Collection storedFields1 = doc1->getFields(); Collection storedFields2 = doc2->getFields(); EXPECT_EQ(storedFields1.size(), storedFields2.size()); - for (int32_t j = 0; j < storedFields1.size(); ++j) - { + for (int32_t j = 0; j < storedFields1.size(); ++j) { EXPECT_EQ(storedFields1[j]->name(), storedFields2[j]->name()); EXPECT_EQ(storedFields1[j]->stringValue(), storedFields2[j]->stringValue()); } @@ -299,104 +272,93 @@ static void checkIndexEquals(const IndexReaderPtr& index1, const IndexReaderPtr& TermPositionsPtr tp1 = index1->termPositions(); TermPositionsPtr tp2 = index2->termPositions(); - while (enum1->next()) - { + while (enum1->next()) { EXPECT_TRUE(enum2->next()); EXPECT_TRUE(enum1->term()->equals(enum2->term())); tp1->seek(enum1->term()); tp2->seek(enum1->term()); - while (tp1->next()) - { + while (tp1->next()) { EXPECT_TRUE(tp2->next()); EXPECT_EQ(tp1->doc(), tp2->doc()); EXPECT_EQ(tp1->freq(), tp2->freq()); - for (int32_t i = 0; i < tp1->freq(); ++i) + for (int32_t i = 0; i < tp1->freq(); ++i) { EXPECT_EQ(tp1->nextPosition(), tp2->nextPosition()); + } } } } -static void checkReaderClosed(const IndexReaderPtr& reader, bool checkSubReaders, bool checkNormsClosed) -{ +static void checkReaderClosed(const IndexReaderPtr& reader, bool checkSubReaders, bool checkNormsClosed) { EXPECT_EQ(0, reader->getRefCount()); - if (checkNormsClosed && MiscUtils::typeOf(reader)) + if (checkNormsClosed && MiscUtils::typeOf(reader)) { EXPECT_TRUE(boost::dynamic_pointer_cast(reader)->normsClosed()); + } - if (checkSubReaders) - { - if (MiscUtils::typeOf(reader)) - { + if (checkSubReaders) { + if (MiscUtils::typeOf(reader)) { Collection subReaders = reader->getSequentialSubReaders(); - for (int32_t i = 0; i < subReaders.size(); ++i) + for (int32_t i = 0; i < subReaders.size(); ++i) { checkReaderClosed(subReaders[i], checkSubReaders, checkNormsClosed); + } } - if (MiscUtils::typeOf(reader)) - { + if (MiscUtils::typeOf(reader)) { Collection subReaders = reader->getSequentialSubReaders(); - for (int32_t i = 0; i < subReaders.size(); ++i) + for (int32_t i = 0; i < subReaders.size(); ++i) { checkReaderClosed(subReaders[i], checkSubReaders, checkNormsClosed); + } } - if (MiscUtils::typeOf(reader)) - { + if (MiscUtils::typeOf(reader)) { Collection subReaders = boost::dynamic_pointer_cast(reader)->getSubReaders(); - for (int32_t i = 0; i < subReaders.size(); ++i) + for (int32_t i = 0; i < subReaders.size(); ++i) { checkReaderClosed(subReaders[i], checkSubReaders, checkNormsClosed); + } } } } -static TestReopen::ReaderCouplePtr refreshReader(const IndexReaderPtr& reader, const TestReopen::TestableReopenPtr& test, int32_t modify, bool hasChanges) -{ +static TestReopen::ReaderCouplePtr refreshReader(const IndexReaderPtr& reader, const TestReopen::TestableReopenPtr& test, int32_t modify, bool hasChanges) { static SynchronizePtr createReaderMutex = newInstance(); SyncLock readersLock(createReaderMutex); IndexReaderPtr r; - if (test) - { + if (test) { test->modifyIndex(modify); r = test->openReader(); } IndexReaderPtr refreshed; LuceneException finally; - try - { + try { refreshed = reader->reopen(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } - if (!refreshed && r) - { + if (!refreshed && r) { // Hit exception - close opened reader r->close(); } finally.throwException(); - if (hasChanges) - { - if (refreshed == reader) + if (hasChanges) { + if (refreshed == reader) { boost::throw_exception(IllegalArgumentException(L"No new IndexReader instance created during refresh.")); - } - else - { - if (refreshed != reader) + } + } else { + if (refreshed != reader) { boost::throw_exception(IllegalArgumentException(L"New IndexReader instance created during refresh even though index had no changes.")); + } } return newInstance(r, refreshed); } -static TestReopen::ReaderCouplePtr refreshReader(const IndexReaderPtr& reader, bool hasChanges) -{ +static TestReopen::ReaderCouplePtr refreshReader(const IndexReaderPtr& reader, bool hasChanges) { return refreshReader(reader, TestReopen::TestableReopenPtr(), -1, hasChanges); } -static void performDefaultTests(const TestReopen::TestableReopenPtr& test) -{ +static void performDefaultTests(const TestReopen::TestableReopenPtr& test) { IndexReaderPtr index1 = test->openReader(); IndexReaderPtr index2 = test->openReader(); @@ -422,8 +384,7 @@ static void performDefaultTests(const TestReopen::TestableReopenPtr& test) index2 = test->openReader(); - for (int32_t i = 1; i < 4; ++i) - { + for (int32_t i = 1; i < 4; ++i) { index1->close(); couple = refreshReader(index2, test, i, true); // refresh IndexReader @@ -440,19 +401,15 @@ static void performDefaultTests(const TestReopen::TestableReopenPtr& test) checkReaderClosed(index2, true, true); } -static void performTestsWithExceptionInReopen(const TestReopen::TestableReopenPtr& test) -{ +static void performTestsWithExceptionInReopen(const TestReopen::TestableReopenPtr& test) { IndexReaderPtr index1 = test->openReader(); IndexReaderPtr index2 = test->openReader(); checkIndexEquals(index1, index2); - try - { + try { refreshReader(index1, test, 0, true); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::Null)(e)); } @@ -463,43 +420,37 @@ static void performTestsWithExceptionInReopen(const TestReopen::TestableReopenPt index2->close(); } -static void checkRefCountEquals(int32_t refCount, const IndexReaderPtr& reader) -{ +static void checkRefCountEquals(int32_t refCount, const IndexReaderPtr& reader) { EXPECT_EQ(refCount, reader->getRefCount()); } -namespace TestReopen -{ - class BasicReopen : public TestableReopen - { - public: - BasicReopen(const DirectoryPtr& dir) - { - this->dir = dir; - } +namespace TestReopen { - virtual ~BasicReopen() - { - } +class BasicReopen : public TestableReopen { +public: + BasicReopen(const DirectoryPtr& dir) { + this->dir = dir; + } - protected: - DirectoryPtr dir; + virtual ~BasicReopen() { + } - public: - virtual IndexReaderPtr openReader() - { - return IndexReader::open(dir, false); - } +protected: + DirectoryPtr dir; + +public: + virtual IndexReaderPtr openReader() { + return IndexReader::open(dir, false); + } + + virtual void modifyIndex(int32_t i) { + _modifyIndex(i, dir); + } +}; - virtual void modifyIndex(int32_t i) - { - _modifyIndex(i, dir); - } - }; } -TEST_F(IndexReaderReopenTest, testReopen) -{ +TEST_F(IndexReaderReopenTest, testReopen) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); performDefaultTests(newInstance(dir1)); @@ -511,79 +462,69 @@ TEST_F(IndexReaderReopenTest, testReopen) dir2->close(); } -namespace TestParallelReaderReopen -{ - class FirstReopen : public TestReopen::TestableReopen - { - public: - FirstReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2) - { - this->dir1 = dir1; - this->dir2 = dir2; - } +namespace TestParallelReaderReopen { - virtual ~FirstReopen() - { - } +class FirstReopen : public TestReopen::TestableReopen { +public: + FirstReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2) { + this->dir1 = dir1; + this->dir2 = dir2; + } - protected: - DirectoryPtr dir1; - DirectoryPtr dir2; - - public: - virtual IndexReaderPtr openReader() - { - ParallelReaderPtr pr = newLucene(); - pr->add(IndexReader::open(dir1, false)); - pr->add(IndexReader::open(dir2, false)); - return pr; - } + virtual ~FirstReopen() { + } - virtual void modifyIndex(int32_t i) - { - _modifyIndex(i, dir1); - _modifyIndex(i, dir2); - } - }; +protected: + DirectoryPtr dir1; + DirectoryPtr dir2; - class SecondReopen : public TestReopen::TestableReopen - { - public: - SecondReopen(const DirectoryPtr& dir3, const DirectoryPtr& dir4) - { - this->dir3 = dir3; - this->dir4 = dir4; - } +public: + virtual IndexReaderPtr openReader() { + ParallelReaderPtr pr = newLucene(); + pr->add(IndexReader::open(dir1, false)); + pr->add(IndexReader::open(dir2, false)); + return pr; + } - virtual ~SecondReopen() - { - } + virtual void modifyIndex(int32_t i) { + _modifyIndex(i, dir1); + _modifyIndex(i, dir2); + } +}; - protected: - DirectoryPtr dir3; - DirectoryPtr dir4; - - public: - virtual IndexReaderPtr openReader() - { - ParallelReaderPtr pr = newLucene(); - pr->add(IndexReader::open(dir3, false)); - pr->add(IndexReader::open(dir4, false)); - // Does not implement reopen, so hits exception - pr->add(newLucene(IndexReader::open(dir3, false))); - return pr; - } +class SecondReopen : public TestReopen::TestableReopen { +public: + SecondReopen(const DirectoryPtr& dir3, const DirectoryPtr& dir4) { + this->dir3 = dir3; + this->dir4 = dir4; + } + + virtual ~SecondReopen() { + } + +protected: + DirectoryPtr dir3; + DirectoryPtr dir4; + +public: + virtual IndexReaderPtr openReader() { + ParallelReaderPtr pr = newLucene(); + pr->add(IndexReader::open(dir3, false)); + pr->add(IndexReader::open(dir4, false)); + // Does not implement reopen, so hits exception + pr->add(newLucene(IndexReader::open(dir3, false))); + return pr; + } + + virtual void modifyIndex(int32_t i) { + _modifyIndex(i, dir3); + _modifyIndex(i, dir4); + } +}; - virtual void modifyIndex(int32_t i) - { - _modifyIndex(i, dir3); - _modifyIndex(i, dir4); - } - }; } -TEST_F(IndexReaderReopenTest, testParallelReaderReopen) -{ +TEST_F(IndexReaderReopenTest, testParallelReaderReopen) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); @@ -605,27 +546,22 @@ TEST_F(IndexReaderReopenTest, testParallelReaderReopen) dir4->close(); } -static void doTestReopenWithCommit(const DirectoryPtr& dir, bool withReopen) -{ +static void doTestReopenWithCommit(const DirectoryPtr& dir, bool withReopen) { IndexWriterPtr iwriter = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); iwriter->setMergeScheduler(newLucene()); IndexReaderPtr reader = IndexReader::open(dir, false); LuceneException finally; - try - { + try { int32_t M = 3; - for (int32_t i = 0; i < 4; ++i) - { - for (int32_t j = 0; j < M; ++j) - { + for (int32_t i = 0; i < 4; ++i) { + for (int32_t j = 0; j < M; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i) + L"_" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"id2", StringUtils::toString(i) + L"_" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS)); doc->add(newLucene(L"id3", StringUtils::toString(i) + L"_" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_NO)); iwriter->addDocument(doc); - if (i > 0) - { + if (i > 0) { int32_t k = i - 1; int32_t n = j + k * M; DocumentPtr prevItereationDoc = reader->document(n); @@ -635,26 +571,20 @@ static void doTestReopenWithCommit(const DirectoryPtr& dir, bool withReopen) } } iwriter->commit(); - if (withReopen) - { + if (withReopen) { // reopen IndexReaderPtr r2 = reader->reopen(); - if (reader != r2) - { + if (reader != r2) { reader->close(); reader = r2; } - } - else - { + } else { // recreate reader->close(); reader = IndexReader::open(dir, false); } } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } iwriter->close(); @@ -666,92 +596,81 @@ static void doTestReopenWithCommit(const DirectoryPtr& dir, bool withReopen) /// At the end of every iteration, commit the index and reopen/recreate the reader. /// In each iteration verify the work of previous iteration. /// Try this once with reopen once recreate, on both RAMDir and FSDir. -TEST_F(IndexReaderReopenTest, testCommitReopenFS) -{ +TEST_F(IndexReaderReopenTest, testCommitReopenFS) { String indexDir(FileUtils::joinPath(getTempDir(), L"IndexReaderReopen")); DirectoryPtr dir = FSDirectory::open(indexDir); doTestReopenWithCommit(dir, true); dir->close(); } -TEST_F(IndexReaderReopenTest, testCommitRecreateFS) -{ +TEST_F(IndexReaderReopenTest, testCommitRecreateFS) { String indexDir(FileUtils::joinPath(getTempDir(), L"IndexReaderReopen")); DirectoryPtr dir = FSDirectory::open(indexDir); doTestReopenWithCommit(dir, false); dir->close(); } -TEST_F(IndexReaderReopenTest, testCommitRecreateRAM) -{ +TEST_F(IndexReaderReopenTest, testCommitRecreateRAM) { DirectoryPtr dir = newLucene(); doTestReopenWithCommit(dir, false); dir->close(); } -namespace TestMultiReaderReopen -{ - class FirstReopen : public TestReopen::TestableReopen - { - public: - FirstReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2) - { - this->dir1 = dir1; - this->dir2 = dir2; - } +namespace TestMultiReaderReopen { - protected: - DirectoryPtr dir1; - DirectoryPtr dir2; +class FirstReopen : public TestReopen::TestableReopen { +public: + FirstReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2) { + this->dir1 = dir1; + this->dir2 = dir2; + } - public: - virtual IndexReaderPtr openReader() - { - Collection readers = newCollection(IndexReader::open(dir1, false), IndexReader::open(dir2, false)); - return newLucene(readers); - } +protected: + DirectoryPtr dir1; + DirectoryPtr dir2; - virtual void modifyIndex(int32_t i) - { - _modifyIndex(i, dir1); - _modifyIndex(i, dir2); - } - }; +public: + virtual IndexReaderPtr openReader() { + Collection readers = newCollection(IndexReader::open(dir1, false), IndexReader::open(dir2, false)); + return newLucene(readers); + } - class SecondReopen : public TestReopen::TestableReopen - { - public: - SecondReopen(const DirectoryPtr& dir3, const DirectoryPtr& dir4) - { - this->dir3 = dir3; - this->dir4 = dir4; - } + virtual void modifyIndex(int32_t i) { + _modifyIndex(i, dir1); + _modifyIndex(i, dir2); + } +}; - protected: - DirectoryPtr dir3; - DirectoryPtr dir4; - - public: - virtual IndexReaderPtr openReader() - { - Collection readers = Collection::newInstance(3); - readers[0] = IndexReader::open(dir3, false); - readers[1] = IndexReader::open(dir4, false); - // Does not implement reopen, so hits exception - readers[2] = newLucene(IndexReader::open(dir3, false)); - return newLucene(readers); - } +class SecondReopen : public TestReopen::TestableReopen { +public: + SecondReopen(const DirectoryPtr& dir3, const DirectoryPtr& dir4) { + this->dir3 = dir3; + this->dir4 = dir4; + } + +protected: + DirectoryPtr dir3; + DirectoryPtr dir4; + +public: + virtual IndexReaderPtr openReader() { + Collection readers = Collection::newInstance(3); + readers[0] = IndexReader::open(dir3, false); + readers[1] = IndexReader::open(dir4, false); + // Does not implement reopen, so hits exception + readers[2] = newLucene(IndexReader::open(dir3, false)); + return newLucene(readers); + } + + virtual void modifyIndex(int32_t i) { + _modifyIndex(i, dir3); + _modifyIndex(i, dir4); + } +}; - virtual void modifyIndex(int32_t i) - { - _modifyIndex(i, dir3); - _modifyIndex(i, dir4); - } - }; } -TEST_F(IndexReaderReopenTest, testMultiReaderReopen) -{ +TEST_F(IndexReaderReopenTest, testMultiReaderReopen) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); @@ -773,55 +692,52 @@ TEST_F(IndexReaderReopenTest, testMultiReaderReopen) dir4->close(); } -namespace TestMixedReaders -{ - class MixedReopen : public TestReopen::TestableReopen - { - public: - MixedReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2, const DirectoryPtr& dir3, const DirectoryPtr& dir4, const DirectoryPtr& dir5) - { - this->dir1 = dir1; - this->dir2 = dir2; - this->dir3 = dir3; - this->dir4 = dir4; - this->dir5 = dir5; - } +namespace TestMixedReaders { - protected: - DirectoryPtr dir1; - DirectoryPtr dir2; - DirectoryPtr dir3; - DirectoryPtr dir4; - DirectoryPtr dir5; - - public: - virtual IndexReaderPtr openReader() - { - ParallelReaderPtr pr = newLucene(); - pr->add(IndexReader::open(dir1, false)); - pr->add(IndexReader::open(dir2, false)); - - Collection readers = newCollection(IndexReader::open(dir3, false), IndexReader::open(dir4, false)); - MultiReaderPtr mr = newLucene(readers); - - Collection mixedReaders = newCollection(pr, mr, IndexReader::open(dir5, false)); - return newLucene(mixedReaders); - } +class MixedReopen : public TestReopen::TestableReopen { +public: + MixedReopen(const DirectoryPtr& dir1, const DirectoryPtr& dir2, const DirectoryPtr& dir3, const DirectoryPtr& dir4, const DirectoryPtr& dir5) { + this->dir1 = dir1; + this->dir2 = dir2; + this->dir3 = dir3; + this->dir4 = dir4; + this->dir5 = dir5; + } + +protected: + DirectoryPtr dir1; + DirectoryPtr dir2; + DirectoryPtr dir3; + DirectoryPtr dir4; + DirectoryPtr dir5; + +public: + virtual IndexReaderPtr openReader() { + ParallelReaderPtr pr = newLucene(); + pr->add(IndexReader::open(dir1, false)); + pr->add(IndexReader::open(dir2, false)); + + Collection readers = newCollection(IndexReader::open(dir3, false), IndexReader::open(dir4, false)); + MultiReaderPtr mr = newLucene(readers); + + Collection mixedReaders = newCollection(pr, mr, IndexReader::open(dir5, false)); + return newLucene(mixedReaders); + } - virtual void modifyIndex(int32_t i) - { - // only change norms in this index to maintain the same number of docs - // for each of ParallelReader's subreaders - if (i == 1) - _modifyIndex(i, dir1); - _modifyIndex(i, dir4); - _modifyIndex(i, dir5); + virtual void modifyIndex(int32_t i) { + // only change norms in this index to maintain the same number of docs + // for each of ParallelReader's subreaders + if (i == 1) { + _modifyIndex(i, dir1); } - }; + _modifyIndex(i, dir4); + _modifyIndex(i, dir5); + } +}; + } -TEST_F(IndexReaderReopenTest, testMixedReaders) -{ +TEST_F(IndexReaderReopenTest, testMixedReaders) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); DirectoryPtr dir2 = newLucene(); @@ -842,10 +758,8 @@ TEST_F(IndexReaderReopenTest, testMixedReaders) dir5->close(); } -TEST_F(IndexReaderReopenTest, testReferenceCounting) -{ - for (int32_t mode = 0; mode < 4; ++mode) - { +TEST_F(IndexReaderReopenTest, testReferenceCounting) { + for (int32_t mode = 0; mode < 4; ++mode) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, true); @@ -855,8 +769,9 @@ TEST_F(IndexReaderReopenTest, testReferenceCounting) EXPECT_TRUE(MiscUtils::typeOf(reader0)); Collection subReaders0 = reader0->getSequentialSubReaders(); - for (int32_t i = 0; i < subReaders0.size(); ++i) + for (int32_t i = 0; i < subReaders0.size(); ++i) { checkRefCountEquals(1, subReaders0[i]); + } // delete first document, so that only one of the subReaders have to be re-opened IndexReaderPtr modifier = IndexReader::open(dir1, false); @@ -867,15 +782,13 @@ TEST_F(IndexReaderReopenTest, testReferenceCounting) EXPECT_TRUE(MiscUtils::typeOf(reader1)); Collection subReaders1 = reader1->getSequentialSubReaders(); EXPECT_EQ(subReaders0.size(), subReaders1.size()); - for (int32_t i = 0; i < subReaders0.size(); ++i) - { - if (subReaders0[i] != subReaders1[i]) - { + for (int32_t i = 0; i < subReaders0.size(); ++i) { + if (subReaders0[i] != subReaders1[i]) { checkRefCountEquals(1, subReaders0[i]); checkRefCountEquals(1, subReaders1[i]); - } - else + } else { checkRefCountEquals(2, subReaders0[i]); + } } // delete first document, so that only one of the subReaders have to be re-opened @@ -888,25 +801,19 @@ TEST_F(IndexReaderReopenTest, testReferenceCounting) Collection subReaders2 = reader2->getSequentialSubReaders(); EXPECT_EQ(subReaders1.size(), subReaders2.size()); - for (int32_t i = 0; i < subReaders2.size(); ++i) - { - if (subReaders2[i] == subReaders1[i]) - { - if (subReaders1[i] == subReaders0[i]) + for (int32_t i = 0; i < subReaders2.size(); ++i) { + if (subReaders2[i] == subReaders1[i]) { + if (subReaders1[i] == subReaders0[i]) { checkRefCountEquals(3, subReaders2[i]); - else + } else { checkRefCountEquals(2, subReaders2[i]); - } - else - { + } + } else { checkRefCountEquals(1, subReaders2[i]); - if (subReaders0[i] == subReaders1[i]) - { + if (subReaders0[i] == subReaders1[i]) { checkRefCountEquals(2, subReaders2[i]); checkRefCountEquals(2, subReaders0[i]); - } - else - { + } else { checkRefCountEquals(1, subReaders0[i]); checkRefCountEquals(1, subReaders1[i]); } @@ -919,32 +826,31 @@ TEST_F(IndexReaderReopenTest, testReferenceCounting) EXPECT_EQ(subReaders3.size(), subReaders0.size()); // try some permutations - switch (mode) - { - case 0: - reader0->close(); - reader1->close(); - reader2->close(); - reader3->close(); - break; - case 1: - reader3->close(); - reader2->close(); - reader1->close(); - reader0->close(); - break; - case 2: - reader2->close(); - reader3->close(); - reader0->close(); - reader1->close(); - break; - case 3: - reader1->close(); - reader3->close(); - reader2->close(); - reader0->close(); - break; + switch (mode) { + case 0: + reader0->close(); + reader1->close(); + reader2->close(); + reader3->close(); + break; + case 1: + reader3->close(); + reader2->close(); + reader1->close(); + reader0->close(); + break; + case 2: + reader2->close(); + reader3->close(); + reader0->close(); + reader1->close(); + break; + case 3: + reader1->close(); + reader3->close(); + reader2->close(); + reader0->close(); + break; } checkReaderClosed(reader0, true, true); @@ -956,10 +862,8 @@ TEST_F(IndexReaderReopenTest, testReferenceCounting) } } -TEST_F(IndexReaderReopenTest, testReferenceCountingMultiReader) -{ - for (int32_t mode = 0; mode <= 1; ++mode) - { +TEST_F(IndexReaderReopenTest, testReferenceCountingMultiReader) { + for (int32_t mode = 0; mode <= 1; ++mode) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); DirectoryPtr dir2 = newLucene(); @@ -982,8 +886,9 @@ TEST_F(IndexReaderReopenTest, testReferenceCountingMultiReader) IndexReaderPtr reader2 = reader1->reopen(); checkRefCountEquals(2 + mode, reader1); - if (mode == 1) + if (mode == 1) { initReader2->close(); + } _modifyIndex(1, dir1); IndexReaderPtr reader3 = reader2->reopen(); @@ -996,8 +901,9 @@ TEST_F(IndexReaderReopenTest, testReferenceCountingMultiReader) multiReader1->close(); checkRefCountEquals(1 + mode, reader1); - if (mode == 1) + if (mode == 1) { initReader2->close(); + } reader1->close(); checkRefCountEquals(1, reader1); @@ -1027,10 +933,8 @@ TEST_F(IndexReaderReopenTest, testReferenceCountingMultiReader) } } -TEST_F(IndexReaderReopenTest, testReferenceCountingParallelReader) -{ - for (int32_t mode = 0; mode <= 1; ++mode) - { +TEST_F(IndexReaderReopenTest, testReferenceCountingParallelReader) { + for (int32_t mode = 0; mode <= 1; ++mode) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); DirectoryPtr dir2 = newLucene(); @@ -1055,8 +959,9 @@ TEST_F(IndexReaderReopenTest, testReferenceCountingParallelReader) IndexReaderPtr reader2 = reader1->reopen(); checkRefCountEquals(2 + mode, reader1); - if (mode == 1) + if (mode == 1) { initReader2->close(); + } _modifyIndex(4, dir1); IndexReaderPtr reader3 = reader2->reopen(); @@ -1069,8 +974,9 @@ TEST_F(IndexReaderReopenTest, testReferenceCountingParallelReader) parallelReader1->close(); checkRefCountEquals(1 + mode, reader1); - if (mode == 1) + if (mode == 1) { initReader2->close(); + } reader1->close(); checkRefCountEquals(1, reader1); @@ -1100,8 +1006,7 @@ TEST_F(IndexReaderReopenTest, testReferenceCountingParallelReader) } } -TEST_F(IndexReaderReopenTest, testNormsRefCounting) -{ +TEST_F(IndexReaderReopenTest, testNormsRefCounting) { DirectoryPtr dir1 = newLucene(); createIndex(dir1, false); @@ -1170,180 +1075,161 @@ TEST_F(IndexReaderReopenTest, testNormsRefCounting) dir1->close(); } -namespace TestReopen -{ - class ThreadReopen : public TestableReopen - { - public: - ThreadReopen(const DirectoryPtr& dir, int32_t n) - { - this->dir = dir; - this->n = n; - } +namespace TestReopen { - protected: - DirectoryPtr dir; - int32_t n; +class ThreadReopen : public TestableReopen { +public: + ThreadReopen(const DirectoryPtr& dir, int32_t n) { + this->dir = dir; + this->n = n; + } - public: - virtual IndexReaderPtr openReader() - { - return IndexReader::open(dir, false); - } +protected: + DirectoryPtr dir; + int32_t n; - virtual void modifyIndex(int32_t i) - { - if (i % 3 == 0) - { - IndexReaderPtr modifier = IndexReader::open(dir, false); - modifier->setNorm(i, L"field1", (uint8_t)50); - modifier->close(); - } - else if (i % 3 == 1) - { - IndexReaderPtr modifier = IndexReader::open(dir, false); - modifier->deleteDocument(i % modifier->maxDoc()); - modifier->close(); - } - else - { - IndexWriterPtr modifier = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); - modifier->addDocument(createDocument(n + i, 6)); - modifier->close(); - } - } - }; +public: + virtual IndexReaderPtr openReader() { + return IndexReader::open(dir, false); + } - class FirstThreadTask : public ReaderThreadTask - { - public: - FirstThreadTask(const IndexReaderPtr& r, const TestableReopenPtr& test, int32_t index, HashSet readersToClose, Collection readers) - { - this->r = r; - this->test = test; - this->index = index; - this->readersToClose = readersToClose; - this->readers = readers; - this->rnd = newLucene(); + virtual void modifyIndex(int32_t i) { + if (i % 3 == 0) { + IndexReaderPtr modifier = IndexReader::open(dir, false); + modifier->setNorm(i, L"field1", (uint8_t)50); + modifier->close(); + } else if (i % 3 == 1) { + IndexReaderPtr modifier = IndexReader::open(dir, false); + modifier->deleteDocument(i % modifier->maxDoc()); + modifier->close(); + } else { + IndexWriterPtr modifier = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); + modifier->addDocument(createDocument(n + i, 6)); + modifier->close(); } + } +}; + +class FirstThreadTask : public ReaderThreadTask { +public: + FirstThreadTask(const IndexReaderPtr& r, const TestableReopenPtr& test, int32_t index, HashSet readersToClose, Collection readers) { + this->r = r; + this->test = test; + this->index = index; + this->readersToClose = readersToClose; + this->readers = readers; + this->rnd = newLucene(); + } - virtual ~FirstThreadTask() - { - } + virtual ~FirstThreadTask() { + } - protected: - IndexReaderPtr r; - TestableReopenPtr test; - int32_t index; - HashSet readersToClose; - Collection readers; - RandomPtr rnd; - - public: - virtual void run() - { - while (!stopped) - { - if (index % 2 == 0) +protected: + IndexReaderPtr r; + TestableReopenPtr test; + int32_t index; + HashSet readersToClose; + Collection readers; + RandomPtr rnd; + +public: + virtual void run() { + while (!stopped) { + if (index % 2 == 0) { + // refresh reader synchronized + ReaderCouplePtr c = refreshReader(r, test, index, true); { - // refresh reader synchronized - ReaderCouplePtr c = refreshReader(r, test, index, true); - { - SyncLock readersLock(&readersToClose); - readersToClose.add(c->newReader); - readersToClose.add(c->refreshedReader); - } - { - SyncLock readersLock(&readers); - readers.add(c); - } - // prevent too many readers - break; + SyncLock readersLock(&readersToClose); + readersToClose.add(c->newReader); + readersToClose.add(c->refreshedReader); } - else { - // not synchronized - IndexReaderPtr refreshed = r->reopen(); - - IndexSearcherPtr searcher = newLucene(refreshed); - Collection hits = searcher->search(newLucene(newLucene(L"field1", L"a" + StringUtils::toString(rnd->nextInt(refreshed->maxDoc())))), FilterPtr(), 1000)->scoreDocs; - if (!hits.empty()) - searcher->doc(hits[0]->doc); - - // r might have changed because this is not a synchronized method. However we don't want to make it synchronized to test - // thread-safety of IndexReader.close(). That's why we add refreshed also to readersToClose, because double closing is fine. - if (refreshed != r) - refreshed->close(); - - { - SyncLock readersLock(&readersToClose); - readersToClose.add(refreshed); - } + SyncLock readersLock(&readers); + readers.add(c); + } + // prevent too many readers + break; + } else { + // not synchronized + IndexReaderPtr refreshed = r->reopen(); + + IndexSearcherPtr searcher = newLucene(refreshed); + Collection hits = searcher->search(newLucene(newLucene(L"field1", L"a" + StringUtils::toString(rnd->nextInt(refreshed->maxDoc())))), FilterPtr(), 1000)->scoreDocs; + if (!hits.empty()) { + searcher->doc(hits[0]->doc); } - LuceneThread::threadSleep(1000); - } - } - }; - class SecondThreadTask : public ReaderThreadTask - { - public: - SecondThreadTask(const IndexReaderPtr& r, const TestableReopenPtr& test, int32_t index, HashSet readersToClose, Collection readers) - { - this->r = r; - this->test = test; - this->index = index; - this->readersToClose = readersToClose; - this->readers = readers; - this->rnd = newLucene(); - } + // r might have changed because this is not a synchronized method. However we don't want to make it synchronized to test + // thread-safety of IndexReader.close(). That's why we add refreshed also to readersToClose, because double closing is fine. + if (refreshed != r) { + refreshed->close(); + } - virtual ~SecondThreadTask() - { + { + SyncLock readersLock(&readersToClose); + readersToClose.add(refreshed); + } + } + LuceneThread::threadSleep(1000); } + } +}; + +class SecondThreadTask : public ReaderThreadTask { +public: + SecondThreadTask(const IndexReaderPtr& r, const TestableReopenPtr& test, int32_t index, HashSet readersToClose, Collection readers) { + this->r = r; + this->test = test; + this->index = index; + this->readersToClose = readersToClose; + this->readers = readers; + this->rnd = newLucene(); + } + + virtual ~SecondThreadTask() { + } - protected: - IndexReaderPtr r; - TestableReopenPtr test; - int32_t index; - HashSet readersToClose; - Collection readers; - RandomPtr rnd; - - public: - virtual void run() - { - while (!stopped) +protected: + IndexReaderPtr r; + TestableReopenPtr test; + int32_t index; + HashSet readersToClose; + Collection readers; + RandomPtr rnd; + +public: + virtual void run() { + while (!stopped) { + int32_t numReaders = 0; + ReaderCouplePtr c; { - int32_t numReaders = 0; - ReaderCouplePtr c; - { - SyncLock readersLock(&readers); - numReaders = readers.size(); - if (numReaders > 0) - c = readers[rnd->nextInt(numReaders)]; - } - if (c) - { - static SynchronizePtr checkIndexMutex = newInstance(); - SyncLock readersLock(checkIndexMutex); - checkIndexEquals(c->newReader, c->refreshedReader); + SyncLock readersLock(&readers); + numReaders = readers.size(); + if (numReaders > 0) { + c = readers[rnd->nextInt(numReaders)]; } - - LuceneThread::threadSleep(100); } + if (c) { + static SynchronizePtr checkIndexMutex = newInstance(); + SyncLock readersLock(checkIndexMutex); + checkIndexEquals(c->newReader, c->refreshedReader); + } + + LuceneThread::threadSleep(100); } - }; + } +}; + } -TEST_F(IndexReaderReopenTest, testThreadSafety) -{ +TEST_F(IndexReaderReopenTest, testThreadSafety) { DirectoryPtr dir = newLucene(); int32_t n = 150; IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < n; ++i) + for (int32_t i = 0; i < n; ++i) { writer->addDocument(createDocument(i, 3)); + } writer->optimize(); writer->close(); @@ -1357,13 +1243,10 @@ TEST_F(IndexReaderReopenTest, testThreadSafety) Collection threads = Collection::newInstance(n); HashSet readersToClose = HashSet::newInstance(); - for (int32_t i = 0; i < n; ++i) - { - if (i % 10 == 0) - { + for (int32_t i = 0; i < n; ++i) { + if (i % 10 == 0) { IndexReaderPtr refreshed = reader->reopen(); - if (refreshed != reader) - { + if (refreshed != reader) { SyncLock readersLock(&readersToClose); readersToClose.add(reader); } @@ -1375,10 +1258,11 @@ TEST_F(IndexReaderReopenTest, testThreadSafety) TestReopen::ReaderThreadTaskPtr task; - if (i < 20 ||( i >= 50 && i < 70) || i > 90) + if (i < 20 ||( i >= 50 && i < 70) || i > 90) { task = newLucene(r, test, index, readersToClose, readers); - else + } else { task = newLucene(r, test, index, readersToClose, readers); + } threads[i] = newLucene(task); threads[i]->start(); @@ -1386,22 +1270,23 @@ TEST_F(IndexReaderReopenTest, testThreadSafety) LuceneThread::threadSleep(15000); - for (int32_t i = 0; i < n; ++i) - { - if (threads[i]) + for (int32_t i = 0; i < n; ++i) { + if (threads[i]) { threads[i]->stopThread(); + } } - for (int32_t i = 0; i < n; ++i) - { - if (threads[i]) + for (int32_t i = 0; i < n; ++i) { + if (threads[i]) { threads[i]->join(); + } } { SyncLock readersLock(&readersToClose); - for (HashSet::iterator reader = readersToClose.begin(); reader != readersToClose.end(); ++reader) + for (HashSet::iterator reader = readersToClose.begin(); reader != readersToClose.end(); ++reader) { (*reader)->close(); + } } firstReader->close(); @@ -1409,8 +1294,9 @@ TEST_F(IndexReaderReopenTest, testThreadSafety) { SyncLock readersLock(&readersToClose); - for (HashSet::iterator reader = readersToClose.begin(); reader != readersToClose.end(); ++reader) + for (HashSet::iterator reader = readersToClose.begin(); reader != readersToClose.end(); ++reader) { checkReaderClosed(*reader, true, true); + } } checkReaderClosed(reader, true, true); @@ -1419,8 +1305,7 @@ TEST_F(IndexReaderReopenTest, testThreadSafety) dir->close(); } -TEST_F(IndexReaderReopenTest, testCloseOrig) -{ +TEST_F(IndexReaderReopenTest, testCloseOrig) { DirectoryPtr dir = newLucene(); createIndex(dir, false); IndexReaderPtr r1 = IndexReader::open(dir, false); @@ -1432,12 +1317,9 @@ TEST_F(IndexReaderReopenTest, testCloseOrig) EXPECT_NE(r1, r3); r1->close(); - try - { + try { r1->document(2); - } - catch (AlreadyClosedException& e) - { + } catch (AlreadyClosedException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } @@ -1445,8 +1327,7 @@ TEST_F(IndexReaderReopenTest, testCloseOrig) dir->close(); } -TEST_F(IndexReaderReopenTest, testDeletes) -{ +TEST_F(IndexReaderReopenTest, testDeletes) { DirectoryPtr dir = newLucene(); createIndex(dir, false); // Create an index with a bunch of docs (1 segment) @@ -1482,8 +1363,7 @@ TEST_F(IndexReaderReopenTest, testDeletes) dir->close(); } -TEST_F(IndexReaderReopenTest, testDeletes2) -{ +TEST_F(IndexReaderReopenTest, testDeletes2) { DirectoryPtr dir = newLucene(); createIndex(dir, false); @@ -1513,34 +1393,29 @@ TEST_F(IndexReaderReopenTest, testDeletes2) dir->close(); } -namespace TestReopen -{ - class KeepAllCommits : public IndexDeletionPolicy - { - public: - virtual ~KeepAllCommits() - { - } +namespace TestReopen { - LUCENE_CLASS(KeepAllCommits); +class KeepAllCommits : public IndexDeletionPolicy { +public: + virtual ~KeepAllCommits() { + } - public: - virtual void onInit(Collection commits) - { - } + LUCENE_CLASS(KeepAllCommits); + +public: + virtual void onInit(Collection commits) { + } + + virtual void onCommit(Collection commits) { + } +}; - virtual void onCommit(Collection commits) - { - } - }; } -TEST_F(IndexReaderReopenTest, testReopenOnCommit) -{ +TEST_F(IndexReaderReopenTest, testReopenOnCommit) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), (IndexDeletionPolicyPtr)newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 4; ++i) - { + for (int32_t i = 0; i < 4; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); @@ -1548,8 +1423,7 @@ TEST_F(IndexReaderReopenTest, testReopenOnCommit) data.put(L"index", StringUtils::toString(i)); writer->commit(data); } - for (int32_t i = 0; i < 4; ++i) - { + for (int32_t i = 0; i < 4; ++i) { writer->deleteDocuments(newLucene(L"id", StringUtils::toString(i))); MapStringString data = MapStringString::newInstance(); data.put(L"index", StringUtils::toString(4 + i)); @@ -1562,27 +1436,24 @@ TEST_F(IndexReaderReopenTest, testReopenOnCommit) EXPECT_EQ(4, r->maxDoc()); Collection commits = IndexReader::listCommits(dir); - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { IndexReaderPtr r2 = r->reopen(*commit); EXPECT_NE(r2, r); - try - { + try { r2->deleteDocument(0); - } - catch (UnsupportedOperationException& e) - { + } catch (UnsupportedOperationException& e) { EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); } MapStringString s = (*commit)->getUserData(); int32_t v = s.empty() ? -1 : StringUtils::toInt(s.get(L"index")); - if (v < 4) + if (v < 4) { EXPECT_EQ(1 + v, r2->numDocs()); - else + } else { EXPECT_EQ(7 - v, r2->numDocs()); + } r->close(); r = r2; diff --git a/src/test/index/IndexReaderTest.cpp b/src/test/index/IndexReaderTest.cpp index 9bd9367a..b174444a 100644 --- a/src/test/index/IndexReaderTest.cpp +++ b/src/test/index/IndexReaderTest.cpp @@ -41,8 +41,7 @@ using namespace Lucene; typedef LuceneTestFixture IndexReaderTest; -static void addDocumentWithFields(const IndexWriterPtr& writer) -{ +static void addDocumentWithFields(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"keyword", L"test1", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"text", L"test1", Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -51,8 +50,7 @@ static void addDocumentWithFields(const IndexWriterPtr& writer) writer->addDocument(doc); } -static void addDocumentWithDifferentFields(const IndexWriterPtr& writer) -{ +static void addDocumentWithDifferentFields(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"keyword2", L"test1", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"text2", L"test1", Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -61,8 +59,7 @@ static void addDocumentWithDifferentFields(const IndexWriterPtr& writer) writer->addDocument(doc); } -static void addDocumentWithTermVectorFields(const IndexWriterPtr& writer) -{ +static void addDocumentWithTermVectorFields(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"tvnot", L"tvnot", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO)); doc->add(newLucene(L"termvector", L"termvector", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); @@ -72,50 +69,44 @@ static void addDocumentWithTermVectorFields(const IndexWriterPtr& writer) writer->addDocument(doc); } -static void addDoc(const IndexWriterPtr& writer, const String& value) -{ +static void addDoc(const IndexWriterPtr& writer, const String& value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", value, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void checkTermDocsCount(const IndexReaderPtr& reader, const TermPtr& term, int32_t expected) -{ +static void checkTermDocsCount(const IndexReaderPtr& reader, const TermPtr& term, int32_t expected) { TermDocsPtr tdocs; LuceneException finally; - try - { + try { tdocs = reader->termDocs(term); EXPECT_TRUE(tdocs); int32_t count = 0; - while (tdocs->next()) + while (tdocs->next()) { ++count; + } EXPECT_EQ(expected, count); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } - if (tdocs) + if (tdocs) { tdocs->close(); + } finally.throwException(); } -static DirectoryPtr getDirectory() -{ +static DirectoryPtr getDirectory() { return FSDirectory::open(FileUtils::joinPath(getTempDir(), L"testIndex")); } -static DocumentPtr createDocument(const String& id) -{ +static DocumentPtr createDocument(const String& id) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS)); return doc; } -TEST_F(IndexReaderTest, testCommitUserData) -{ +TEST_F(IndexReaderTest, testCommitUserData) { RAMDirectoryPtr d = newLucene(); MapStringString commitUserData = MapStringString::newInstance(); @@ -124,8 +115,9 @@ TEST_F(IndexReaderTest, testCommitUserData) // set up writer IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < 27; ++i) + for (int32_t i = 0; i < 27; ++i) { addDocumentWithFields(writer); + } writer->close(); IndexReaderPtr r = IndexReader::open(d, false); @@ -140,10 +132,12 @@ TEST_F(IndexReaderTest, testCommitUserData) MapStringString expectedData = c->getUserData(); EXPECT_EQ(expectedData.size(), commitUserData.size()); - for (MapStringString::iterator expected = expectedData.begin(); expected != expectedData.end(); ++expected) + for (MapStringString::iterator expected = expectedData.begin(); expected != expectedData.end(); ++expected) { EXPECT_TRUE(commitUserData.find(expected->first) != commitUserData.end()); - for (MapStringString::iterator commit = commitUserData.begin(); commit != commitUserData.end(); ++commit) + } + for (MapStringString::iterator commit = commitUserData.begin(); commit != commitUserData.end(); ++commit) { EXPECT_TRUE(expectedData.find(commit->first) != expectedData.end()); + } EXPECT_EQ(sis->getCurrentSegmentFileName(), c->getSegmentsFileName()); @@ -152,8 +146,9 @@ TEST_F(IndexReaderTest, testCommitUserData) // Change the index writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < 7; ++i) + for (int32_t i = 0; i < 7; ++i) { addDocumentWithFields(writer); + } writer->close(); IndexReaderPtr r3 = r2->reopen(); @@ -172,8 +167,7 @@ TEST_F(IndexReaderTest, testCommitUserData) d->close(); } -TEST_F(IndexReaderTest, testIsCurrent) -{ +TEST_F(IndexReaderTest, testIsCurrent) { RAMDirectoryPtr d = newLucene(); IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); @@ -195,8 +189,7 @@ TEST_F(IndexReaderTest, testIsCurrent) d->close(); } -TEST_F(IndexReaderTest, testGetFieldNames) -{ +TEST_F(IndexReaderTest, testGetFieldNames) { RAMDirectoryPtr d = newLucene(); // set up writer IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -214,14 +207,17 @@ TEST_F(IndexReaderTest, testGetFieldNames) // add more documents writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); // want to get some more segments here - for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) + for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) { addDocumentWithFields(writer); + } // new fields are in some different segments (we hope) - for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) + for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) { addDocumentWithDifferentFields(writer); + } // new termvector fields - for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) + for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) { addDocumentWithTermVectorFields(writer); + } writer->close(); // verify fields again @@ -283,15 +279,13 @@ TEST_F(IndexReaderTest, testGetFieldNames) d->close(); } -TEST_F(IndexReaderTest, testTermVectors) -{ +TEST_F(IndexReaderTest, testTermVectors) { RAMDirectoryPtr d = newLucene(); // set up writer IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); // want to get some more segments here // new termvector fields - for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) - { + for (int32_t i = 0; i < 5 * writer->getMergeFactor(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"tvnot", L"one two two three three three", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO)); doc->add(newLucene(L"termvector", L"one two two three three three", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); @@ -308,19 +302,20 @@ TEST_F(IndexReaderTest, testTermVectors) EXPECT_TRUE(map); EXPECT_EQ(map.size(), 4); Collection set = map.get(L"termvector"); - for (Collection::iterator entry = set.begin(); entry != set.end(); ++entry) + for (Collection::iterator entry = set.begin(); entry != set.end(); ++entry) { EXPECT_TRUE(*entry); + } } -TEST_F(IndexReaderTest, testBasicDelete) -{ +TEST_F(IndexReaderTest, testBasicDelete) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); TermPtr searchTerm = newLucene(L"content", L"aaa"); // add 100 documents with term : aaa - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer, searchTerm->text()); + } writer->close(); // open reader at this point - this should fix the view of the @@ -352,16 +347,14 @@ TEST_F(IndexReaderTest, testBasicDelete) dir->close(); } -TEST_F(IndexReaderTest, testBinaryFields) -{ +TEST_F(IndexReaderTest, testBinaryFields) { DirectoryPtr dir = newLucene(); uint8_t _bin[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ByteArray bin(ByteArray::newInstance(10)); std::memcpy(bin.get(), _bin, 10); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { addDoc(writer, L"document number " + StringUtils::toString(i + 1)); addDocumentWithFields(writer); addDocumentWithDifferentFields(writer); @@ -417,15 +410,15 @@ TEST_F(IndexReaderTest, testBinaryFields) } /// Make sure attempts to make changes after reader is closed throws IOException -TEST_F(IndexReaderTest, testChangesAfterClose) -{ +TEST_F(IndexReaderTest, testChangesAfterClose) { DirectoryPtr dir = newLucene(); TermPtr searchTerm = newLucene(L"content", L"aaa"); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 11 documents with term : aaa - for (int32_t i = 0; i < 11; ++i) + for (int32_t i = 0; i < 11; ++i) { addDoc(writer, searchTerm->text()); + } writer->close(); IndexReaderPtr reader = IndexReader::open(dir, false); @@ -434,68 +427,50 @@ TEST_F(IndexReaderTest, testChangesAfterClose) reader->close(); // Then, try to make changes - try - { + try { reader->deleteDocument(4); - } - catch (AlreadyClosedException& e) - { + } catch (AlreadyClosedException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } - try - { + try { reader->setNorm(5, L"aaa", 2.0); - } - catch (AlreadyClosedException& e) - { + } catch (AlreadyClosedException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } - try - { + try { reader->undeleteAll(); - } - catch (AlreadyClosedException& e) - { + } catch (AlreadyClosedException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } } /// Make sure we get lock obtain failed exception with 2 writers -TEST_F(IndexReaderTest, testLockObtainFailed) -{ +TEST_F(IndexReaderTest, testLockObtainFailed) { DirectoryPtr dir = newLucene(); TermPtr searchTerm = newLucene(L"content", L"aaa"); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 11 documents with term : aaa - for (int32_t i = 0; i < 11; ++i) + for (int32_t i = 0; i < 11; ++i) { addDoc(writer, searchTerm->text()); + } IndexReaderPtr reader = IndexReader::open(dir, false); // Try to make changes - try - { + try { reader->deleteDocument(4); - } - catch (LockObtainFailedException& e) - { + } catch (LockObtainFailedException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } - try - { + try { reader->setNorm(5, L"aaa", 2.0); - } - catch (LockObtainFailedException& e) - { + } catch (LockObtainFailedException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } - try - { + try { reader->undeleteAll(); - } - catch (LockObtainFailedException& e) - { + } catch (LockObtainFailedException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } @@ -503,8 +478,7 @@ TEST_F(IndexReaderTest, testLockObtainFailed) reader->close(); } -TEST_F(IndexReaderTest, testWritingNorms) -{ +TEST_F(IndexReaderTest, testWritingNorms) { String indexDir(FileUtils::joinPath(getTempDir(), L"lucenetestnormwriter")); DirectoryPtr dir = FSDirectory::open(indexDir); TermPtr searchTerm = newLucene(L"content", L"aaa"); @@ -544,8 +518,7 @@ TEST_F(IndexReaderTest, testWritingNorms) } /// Make sure you can set norms and commit, and there are no extra norms files left -TEST_F(IndexReaderTest, testWritingNormsNoReader) -{ +TEST_F(IndexReaderTest, testWritingNormsNoReader) { RAMDirectoryPtr dir = newLucene(); // add 1 documents with term : aaa @@ -570,8 +543,7 @@ TEST_F(IndexReaderTest, testWritingNormsNoReader) dir->close(); } -static void deleteReaderWriterConflict(bool optimize) -{ +static void deleteReaderWriterConflict(bool optimize) { DirectoryPtr dir = getDirectory(); TermPtr searchTerm = newLucene(L"content", L"aaa"); @@ -579,8 +551,9 @@ static void deleteReaderWriterConflict(bool optimize) // add 100 documents with term : aaa IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer, searchTerm->text()); + } writer->close(); // open reader at this point - this should fix the view of the index at the point of @@ -593,16 +566,18 @@ static void deleteReaderWriterConflict(bool optimize) // add 100 documents with term : bbb writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer, searchTerm2->text()); + } // request optimization // This causes a new segment to become current for all subsequent // searchers. Because of this, deletions made via a previously open // reader, which would be applied to that reader's segment, are lost // for subsequent searchers/readers - if (optimize) + if (optimize) { writer->optimize(); + } writer->close(); // The reader should not see the new data @@ -614,12 +589,9 @@ static void deleteReaderWriterConflict(bool optimize) // delete documents containing term: aaa // NOTE: the reader was created when only "aaa" documents were in int32_t deleted = 0; - try - { + try { deleted = reader->deleteDocuments(searchTerm); - } - catch (StaleReaderException& e) - { + } catch (StaleReaderException& e) { EXPECT_TRUE(check_exception(LuceneException::StaleReader)(e)); } @@ -648,18 +620,15 @@ static void deleteReaderWriterConflict(bool optimize) reader->close(); } -TEST_F(IndexReaderTest, testDeleteReaderWriterConflictUnoptimized) -{ +TEST_F(IndexReaderTest, testDeleteReaderWriterConflictUnoptimized) { deleteReaderWriterConflict(false); } -TEST_F(IndexReaderTest, testDeleteReaderWriterConflictOptimized) -{ +TEST_F(IndexReaderTest, testDeleteReaderWriterConflictOptimized) { deleteReaderWriterConflict(true); } -TEST_F(IndexReaderTest, testFilesOpenClose) -{ +TEST_F(IndexReaderTest, testFilesOpenClose) { // Create initial data set String dirFile = FileUtils::joinPath(getTempDir(), L"testIndex"); DirectoryPtr dir = getDirectory(); @@ -688,14 +657,11 @@ TEST_F(IndexReaderTest, testFilesOpenClose) EXPECT_TRUE(FileUtils::removeDirectory(dirFile)); } -TEST_F(IndexReaderTest, testLastModified) -{ +TEST_F(IndexReaderTest, testLastModified) { String fileDir = FileUtils::joinPath(getTempDir(), L"testIndex"); - for (int32_t i = 0; i < 2; ++i) - { + for (int32_t i = 0; i < 2; ++i) { LuceneException finally; - try - { + try { DirectoryPtr dir = i == 0 ? newLucene() : getDirectory(); EXPECT_TRUE(!IndexReader::indexExists(dir)); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -706,8 +672,7 @@ TEST_F(IndexReaderTest, testLastModified) IndexReaderPtr reader = IndexReader::open(dir, false); EXPECT_TRUE(!IndexWriter::isLocked(dir)); // reader only, no lock int64_t version = IndexReader::lastModified(dir); - if (i == 1) - { + if (i == 1) { int64_t version2 = IndexReader::lastModified(dir); EXPECT_EQ(version, version2); } @@ -723,19 +688,17 @@ TEST_F(IndexReaderTest, testLastModified) EXPECT_TRUE(version <= IndexReader::lastModified(dir)); reader->close(); dir->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } - if (i == 1) + if (i == 1) { EXPECT_TRUE(FileUtils::removeDirectory(fileDir)); + } finally.throwException(); } } -TEST_F(IndexReaderTest, testVersion) -{ +TEST_F(IndexReaderTest, testVersion) { DirectoryPtr dir = newLucene(); EXPECT_TRUE(!IndexReader::indexExists(dir)); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -757,20 +720,16 @@ TEST_F(IndexReaderTest, testVersion) dir->close(); } -TEST_F(IndexReaderTest, testLock) -{ +TEST_F(IndexReaderTest, testLock) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); writer->close(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); IndexReaderPtr reader = IndexReader::open(dir, false); - try - { + try { reader->deleteDocument(0); - } - catch (LockObtainFailedException& e) - { + } catch (LockObtainFailedException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } IndexWriter::unlock(dir); // this should not be done in the real world! @@ -780,8 +739,7 @@ TEST_F(IndexReaderTest, testLock) dir->close(); } -TEST_F(IndexReaderTest, testUndeleteAll) -{ +TEST_F(IndexReaderTest, testUndeleteAll) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); @@ -798,8 +756,7 @@ TEST_F(IndexReaderTest, testUndeleteAll) dir->close(); } -TEST_F(IndexReaderTest, testUndeleteAllAfterClose) -{ +TEST_F(IndexReaderTest, testUndeleteAllAfterClose) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); @@ -816,8 +773,7 @@ TEST_F(IndexReaderTest, testUndeleteAllAfterClose) dir->close(); } -TEST_F(IndexReaderTest, testUndeleteAllAfterCloseThenReopen) -{ +TEST_F(IndexReaderTest, testUndeleteAllAfterCloseThenReopen) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); @@ -836,8 +792,7 @@ TEST_F(IndexReaderTest, testUndeleteAllAfterCloseThenReopen) dir->close(); } -static void deleteReaderReaderConflict(bool optimize) -{ +static void deleteReaderReaderConflict(bool optimize) { DirectoryPtr dir = getDirectory(); TermPtr searchTerm1 = newLucene(L"content", L"aaa"); @@ -848,14 +803,14 @@ static void deleteReaderReaderConflict(bool optimize) // add 100 documents with term : bbb // add 100 documents with term : ccc IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { addDoc(writer, searchTerm1->text()); addDoc(writer, searchTerm2->text()); addDoc(writer, searchTerm3->text()); } - if (optimize) + if (optimize) { writer->optimize(); + } writer->close(); // open two readers @@ -899,12 +854,9 @@ static void deleteReaderReaderConflict(bool optimize) // attempt to delete from stale reader // delete documents containing term: bbb - try - { + try { reader1->deleteDocuments(searchTerm2); - } - catch (StaleReaderException& e) - { + } catch (StaleReaderException& e) { EXPECT_TRUE(check_exception(LuceneException::StaleReader)(e)); } @@ -940,19 +892,16 @@ static void deleteReaderReaderConflict(bool optimize) dir->close(); } -TEST_F(IndexReaderTest, testDeleteReaderReaderConflictUnoptimized) -{ +TEST_F(IndexReaderTest, testDeleteReaderReaderConflictUnoptimized) { deleteReaderReaderConflict(false); } -TEST_F(IndexReaderTest, testDeleteReaderReaderConflictOptimized) -{ +TEST_F(IndexReaderTest, testDeleteReaderReaderConflictOptimized) { deleteReaderReaderConflict(true); } /// Make sure if reader tries to commit but hits disk full that reader remains consistent and usable. -TEST_F(IndexReaderTest, testDiskFull) -{ +TEST_F(IndexReaderTest, testDiskFull) { TermPtr searchTerm = newLucene(L"content", L"aaa"); int32_t START_COUNT = 157; int32_t END_COUNT = 144; @@ -960,8 +909,7 @@ TEST_F(IndexReaderTest, testDiskFull) // First build up a starting index RAMDirectoryPtr startDir = newLucene(); IndexWriterPtr writer = newLucene(startDir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 157; ++i) - { + for (int32_t i = 0; i < 157; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"content", L"aaa " + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -977,8 +925,7 @@ TEST_F(IndexReaderTest, testDiskFull) bool done = false; // Iterate with ever increasing free disk space - while (!done) - { + while (!done) { MockRAMDirectoryPtr dir = newLucene(startDir); // If IndexReader hits disk full, it can write to the same files again. @@ -991,26 +938,25 @@ TEST_F(IndexReaderTest, testDiskFull) // retry with same reader bool success = false; - for (int32_t x = 0; x < 2; ++x) - { + for (int32_t x = 0; x < 2; ++x) { double rate = 0.05; double diskRatio = ((double)diskFree) / (double)diskUsage; int64_t thisDiskFree = 0; String testName; - if (x == 0) - { + if (x == 0) { thisDiskFree = diskFree; - if (diskRatio >= 2.0) + if (diskRatio >= 2.0) { rate /= 2; - if (diskRatio >= 4.0) + } + if (diskRatio >= 4.0) { rate /= 2; - if (diskRatio >= 6.0) + } + if (diskRatio >= 6.0) { rate = 0.0; + } testName = L"disk full during reader.close() @ " + StringUtils::toString(thisDiskFree) + L" bytes"; - } - else - { + } else { thisDiskFree = 0; rate = 0.0; testName = L"reader re-use after disk full"; @@ -1019,13 +965,10 @@ TEST_F(IndexReaderTest, testDiskFull) dir->setMaxSizeInBytes(thisDiskFree); dir->setRandomIOExceptionRate(rate, diskFree); - try - { - if (x == 0) - { + try { + if (x == 0) { int32_t docId = 12; - for (int32_t i = 0; i < 13; ++i) - { + for (int32_t i = 0; i < 13; ++i) { reader->deleteDocument(docId); reader->setNorm(docId, L"contents", 2.0); docId += 12; @@ -1033,14 +976,14 @@ TEST_F(IndexReaderTest, testDiskFull) } reader->close(); success = true; - if (x == 0) + if (x == 0) { done = true; - } - catch (IOException& e) - { + } + } catch (IOException& e) { err = e; - if (x == 1) + if (x == 1) { FAIL() << testName << " hit IOException after disk space was freed up"; + } } // Whether we succeeded or failed, check that all un-referenced files were in fact deleted (ie, @@ -1058,8 +1001,7 @@ TEST_F(IndexReaderTest, testDiskFull) std::sort(startFiles.begin(), startFiles.end()); std::sort(endFiles.begin(), endFiles.end()); - if (!startFiles.equals(endFiles)) - { + if (!startFiles.equals(endFiles)) { String successStr = success ? L"success" : L"IOException"; FAIL() << "reader.close() failed to delete unreferenced files after " << successStr << " (" << diskFree << " bytes)"; } @@ -1073,23 +1015,23 @@ TEST_F(IndexReaderTest, testDiskFull) Collection hits; EXPECT_NO_THROW(hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs); int32_t result2 = hits.size(); - if (success) - { - if (result2 != END_COUNT) + if (success) { + if (result2 != END_COUNT) { FAIL() << testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT; - } - else - { + } + } else { // On hitting exception we still may have added all docs - if (result2 != START_COUNT && result2 != END_COUNT) + if (result2 != START_COUNT && result2 != END_COUNT) { FAIL() << testName << ": method did throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT; + } } searcher->close(); newReader->close(); - if (result2 == END_COUNT) + if (result2 == END_COUNT) { break; + } } dir->close(); @@ -1101,22 +1043,19 @@ TEST_F(IndexReaderTest, testDiskFull) startDir->close(); } -TEST_F(IndexReaderTest, testDocsOutOfOrder) -{ +TEST_F(IndexReaderTest, testDocsOutOfOrder) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 11; ++i) + for (int32_t i = 0; i < 11; ++i) { addDoc(writer, L"aaa"); + } writer->close(); IndexReaderPtr reader = IndexReader::open(dir, false); // Try to delete an invalid docId, yet, within range of the final bits of the BitVector - try - { + try { reader->deleteDocument(11); - } - catch (IndexOutOfBoundsException& e) - { + } catch (IndexOutOfBoundsException& e) { EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); } @@ -1125,16 +1064,16 @@ TEST_F(IndexReaderTest, testDocsOutOfOrder) writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); // We must add more docs to get a new segment written - for (int32_t i = 0; i < 11; ++i) + for (int32_t i = 0; i < 11; ++i) { addDoc(writer, L"aaa"); + } EXPECT_NO_THROW(writer->optimize()); writer->close(); dir->close(); } -TEST_F(IndexReaderTest, testExceptionReleaseWriteLock) -{ +TEST_F(IndexReaderTest, testExceptionReleaseWriteLock) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(writer, L"aaa"); @@ -1142,12 +1081,9 @@ TEST_F(IndexReaderTest, testExceptionReleaseWriteLock) IndexReaderPtr reader = IndexReader::open(dir, false); - try - { + try { reader->deleteDocument(1); - } - catch (IndexOutOfBoundsException& e) - { + } catch (IndexOutOfBoundsException& e) { EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); } @@ -1157,12 +1093,9 @@ TEST_F(IndexReaderTest, testExceptionReleaseWriteLock) reader = IndexReader::open(dir, false); - try - { + try { reader->setNorm(1, L"content", 2.0); - } - catch (IndexOutOfBoundsException& e) - { + } catch (IndexOutOfBoundsException& e) { EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); } @@ -1173,41 +1106,34 @@ TEST_F(IndexReaderTest, testExceptionReleaseWriteLock) dir->close(); } -TEST_F(IndexReaderTest, testOpenReaderAfterDelete) -{ +TEST_F(IndexReaderTest, testOpenReaderAfterDelete) { String indexDir(FileUtils::joinPath(getTempDir(), L"deletetest")); DirectoryPtr dir = FSDirectory::open(indexDir); - try - { + try { IndexReader::open(dir, false); - } - catch (NoSuchDirectoryException& e) - { + } catch (NoSuchDirectoryException& e) { EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); } FileUtils::removeDirectory(indexDir); - try - { + try { IndexReader::open(dir, false); - } - catch (NoSuchDirectoryException& e) - { + } catch (NoSuchDirectoryException& e) { EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); } dir->close(); } -TEST_F(IndexReaderTest, testGetIndexCommit) -{ +TEST_F(IndexReaderTest, testGetIndexCommit) { RAMDirectoryPtr d = newLucene(); // set up writer IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < 27; ++i) + for (int32_t i = 0; i < 27; ++i) { addDocumentWithFields(writer); + } writer->close(); SegmentInfosPtr sis = newLucene(); @@ -1222,8 +1148,9 @@ TEST_F(IndexReaderTest, testGetIndexCommit) // Change the index writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < 7; ++i) + for (int32_t i = 0; i < 7; ++i) { addDocumentWithFields(writer); + } writer->close(); IndexReaderPtr r2 = r->reopen(); @@ -1243,8 +1170,7 @@ TEST_F(IndexReaderTest, testGetIndexCommit) d->close(); } -TEST_F(IndexReaderTest, testReadOnly) -{ +TEST_F(IndexReaderTest, testReadOnly) { RAMDirectoryPtr d = newLucene(); IndexWriterPtr writer = newLucene(d, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); addDocumentWithFields(writer); @@ -1253,12 +1179,9 @@ TEST_F(IndexReaderTest, testReadOnly) writer->close(); IndexReaderPtr r = IndexReader::open(d, true); - try - { + try { r->deleteDocument(0); - } - catch (UnsupportedOperationException& e) - { + } catch (UnsupportedOperationException& e) { EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); } @@ -1271,12 +1194,9 @@ TEST_F(IndexReaderTest, testReadOnly) r->close(); EXPECT_NE(r, r2); - try - { + try { r2->deleteDocument(0); - } - catch (UnsupportedOperationException& e) - { + } catch (UnsupportedOperationException& e) { EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); } @@ -1289,12 +1209,9 @@ TEST_F(IndexReaderTest, testReadOnly) r2->close(); EXPECT_NE(r, r2); - try - { + try { r3->deleteDocument(0); - } - catch (UnsupportedOperationException& e) - { + } catch (UnsupportedOperationException& e) { EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); } @@ -1305,8 +1222,7 @@ TEST_F(IndexReaderTest, testReadOnly) r3->close(); } -TEST_F(IndexReaderTest, testIndexReader) -{ +TEST_F(IndexReaderTest, testIndexReader) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthUNLIMITED); writer->addDocument(createDocument(L"a")); @@ -1321,8 +1237,7 @@ TEST_F(IndexReaderTest, testIndexReader) IndexReader::open(dir, true)->close(); } -TEST_F(IndexReaderTest, testIndexReaderUnDeleteAll) -{ +TEST_F(IndexReaderTest, testIndexReaderUnDeleteAll) { MockRAMDirectoryPtr dir = newLucene(); dir->setPreventDoubleWrite(false); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthUNLIMITED); @@ -1342,23 +1257,18 @@ TEST_F(IndexReaderTest, testIndexReaderUnDeleteAll) } /// Make sure on attempting to open an IndexReader on a non-existent directory, you get a good exception -TEST_F(IndexReaderTest, testNoDir) -{ +TEST_F(IndexReaderTest, testNoDir) { String indexDir(FileUtils::joinPath(getTempDir(), L"doesnotexist")); DirectoryPtr dir = FSDirectory::open(indexDir); - try - { + try { IndexReader::open(dir, true); - } - catch (NoSuchDirectoryException& e) - { + } catch (NoSuchDirectoryException& e) { EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); } dir->close(); } -TEST_F(IndexReaderTest, testNoDupCommitFileNames) -{ +TEST_F(IndexReaderTest, testNoDupCommitFileNames) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); @@ -1368,12 +1278,10 @@ TEST_F(IndexReaderTest, testNoDupCommitFileNames) writer->close(); Collection commits = IndexReader::listCommits(dir); - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { HashSet files = (*commit)->getFileNames(); HashSet seen = HashSet::newInstance(); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { EXPECT_TRUE(!seen.contains(*fileName)); seen.add(*fileName); } @@ -1383,8 +1291,7 @@ TEST_F(IndexReaderTest, testNoDupCommitFileNames) } /// Ensure that on a cloned reader, segments reuse the doc values arrays in FieldCache -TEST_F(IndexReaderTest, testFieldCacheReuseAfterClone) -{ +TEST_F(IndexReaderTest, testFieldCacheReuseAfterClone) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -1413,8 +1320,7 @@ TEST_F(IndexReaderTest, testFieldCacheReuseAfterClone) } /// Ensure that on a reopened reader, that any shared segments reuse the doc values arrays in FieldCache -TEST_F(IndexReaderTest, testFieldCacheReuseAfterReopen) -{ +TEST_F(IndexReaderTest, testFieldCacheReuseAfterReopen) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -1445,8 +1351,7 @@ TEST_F(IndexReaderTest, testFieldCacheReuseAfterReopen) } /// Make sure all SegmentReaders are new when reopen switches readOnly -TEST_F(IndexReaderTest, testReopenChangeReadonly) -{ +TEST_F(IndexReaderTest, testReopenChangeReadonly) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -1486,8 +1391,7 @@ TEST_F(IndexReaderTest, testReopenChangeReadonly) dir->close(); } -TEST_F(IndexReaderTest, testUniqueTermCount) -{ +TEST_F(IndexReaderTest, testUniqueTermCount) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); @@ -1504,25 +1408,22 @@ TEST_F(IndexReaderTest, testUniqueTermCount) writer->commit(); IndexReaderPtr r2 = r->reopen(); r->close(); - try - { + try { r2->getUniqueTermCount(); - } - catch (UnsupportedOperationException& e) - { + } catch (UnsupportedOperationException& e) { EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); } Collection subs = r2->getSequentialSubReaders(); - for (Collection::iterator sub = subs.begin(); sub != subs.end(); ++sub) + for (Collection::iterator sub = subs.begin(); sub != subs.end(); ++sub) { EXPECT_EQ(36, (*sub)->getUniqueTermCount()); + } r2->close(); writer->close(); dir->close(); } /// don't load terms index -TEST_F(IndexReaderTest, testNoTermsIndex) -{ +TEST_F(IndexReaderTest, testNoTermsIndex) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); @@ -1533,12 +1434,9 @@ TEST_F(IndexReaderTest, testNoTermsIndex) writer->close(); IndexReaderPtr r = IndexReader::open(dir, IndexDeletionPolicyPtr(), true, -1); - try - { + try { r->docFreq(newLucene(L"field", L"f")); - } - catch (IllegalStateException& e) - { + } catch (IllegalStateException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); } EXPECT_TRUE(!boost::dynamic_pointer_cast(r->getSequentialSubReaders()[0])->termsIndexLoaded()); @@ -1552,8 +1450,7 @@ TEST_F(IndexReaderTest, testNoTermsIndex) r->close(); Collection subReaders = r2->getSequentialSubReaders(); EXPECT_EQ(2, subReaders.size()); - for (Collection::iterator sub = subReaders.begin(); sub != subReaders.end(); ++sub) - { + for (Collection::iterator sub = subReaders.begin(); sub != subReaders.end(); ++sub) { SegmentReaderPtr subReader = boost::dynamic_pointer_cast(*sub); EXPECT_TRUE(!subReader->termsIndexLoaded()); } @@ -1561,8 +1458,7 @@ TEST_F(IndexReaderTest, testNoTermsIndex) dir->close(); } -TEST_F(IndexReaderTest, testPrepareCommitIsCurrent) -{ +TEST_F(IndexReaderTest, testPrepareCommitIsCurrent) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); diff --git a/src/test/index/IndexWriterDeleteTest.cpp b/src/test/index/IndexWriterDeleteTest.cpp index a09de871..a7015335 100644 --- a/src/test/index/IndexWriterDeleteTest.cpp +++ b/src/test/index/IndexWriterDeleteTest.cpp @@ -27,17 +27,14 @@ typedef LuceneTestFixture IndexWriterDeleteTest; DECLARE_SHARED_PTR(FailOnlyOnDeleteFlush) -class FailOnlyOnDeleteFlush : public MockDirectoryFailure -{ +class FailOnlyOnDeleteFlush : public MockDirectoryFailure { public: - FailOnlyOnDeleteFlush() - { + FailOnlyOnDeleteFlush() { sawMaybe = false; failed = false; } - virtual ~FailOnlyOnDeleteFlush() - { + virtual ~FailOnlyOnDeleteFlush() { } public: @@ -45,76 +42,64 @@ class FailOnlyOnDeleteFlush : public MockDirectoryFailure bool failed; public: - virtual MockDirectoryFailurePtr reset() - { + virtual MockDirectoryFailurePtr reset() { sawMaybe = false; failed = false; return shared_from_this(); } - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (sawMaybe && !failed) - { - if (!TestPoint::getTestPoint(L"applyDeletes")) - { + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (sawMaybe && !failed) { + if (!TestPoint::getTestPoint(L"applyDeletes")) { // Only fail once we are no longer in applyDeletes failed = true; boost::throw_exception(IOException(L"fail after applyDeletes")); } } - if (!failed) - { - if (TestPoint::getTestPoint(L"applyDeletes")) + if (!failed) { + if (TestPoint::getTestPoint(L"applyDeletes")) { sawMaybe = true; + } } } }; DECLARE_SHARED_PTR(FailOnlyOnAdd) -class FailOnlyOnAdd : public MockDirectoryFailure -{ +class FailOnlyOnAdd : public MockDirectoryFailure { public: - FailOnlyOnAdd() - { + FailOnlyOnAdd() { failed = false; } - virtual ~FailOnlyOnAdd() - { + virtual ~FailOnlyOnAdd() { } public: bool failed; public: - virtual MockDirectoryFailurePtr reset() - { + virtual MockDirectoryFailurePtr reset() { failed = false; return shared_from_this(); } - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (!failed) - { + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (!failed) { failed = true; boost::throw_exception(IOException(L"fail in add doc")); } } }; -static int32_t getHitCount(const DirectoryPtr& dir, const TermPtr& term) -{ +static int32_t getHitCount(const DirectoryPtr& dir, const TermPtr& term) { IndexSearcherPtr searcher = newLucene(dir, true); int32_t hitCount = searcher->search(newLucene(term), FilterPtr(), 1000)->totalHits; searcher->close(); return hitCount; } -static void addDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) -{ +static void addDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", StringUtils::toString(id), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -122,8 +107,7 @@ static void addDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) modifier->addDocument(doc); } -static void updateDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) -{ +static void updateDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", StringUtils::toString(id), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -131,8 +115,7 @@ static void updateDoc(const IndexWriterPtr& modifier, int32_t id, int32_t value) modifier->updateDocument(newLucene(L"id", StringUtils::toString(id)), doc); } -static void checkNoUnreferencedFiles(const DirectoryPtr& dir) -{ +static void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); infos->read(dir); @@ -148,8 +131,7 @@ static void checkNoUnreferencedFiles(const DirectoryPtr& dir) EXPECT_TRUE(startFiles.equals(endFiles)); } -TEST_F(IndexWriterDeleteTest, testSimpleCase) -{ +TEST_F(IndexWriterDeleteTest, testSimpleCase) { Collection keywords = newCollection(L"1", L"2"); Collection unindexed = newCollection(L"Netherlands", L"Italy"); Collection unstored = newCollection(L"Amsterdam has lots of bridges", L"Venice has lots of canals"); @@ -161,8 +143,7 @@ TEST_F(IndexWriterDeleteTest, testSimpleCase) modifier->setUseCompoundFile(true); modifier->setMaxBufferedDeleteTerms(1); - for (int32_t i = 0; i < keywords.size(); ++i) - { + for (int32_t i = 0; i < keywords.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", keywords[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"country", unindexed[i], Field::STORE_YES, Field::INDEX_NO)); @@ -186,8 +167,7 @@ TEST_F(IndexWriterDeleteTest, testSimpleCase) } /// test when delete terms only apply to disk segments -TEST_F(IndexWriterDeleteTest, testNonRAMDelete) -{ +TEST_F(IndexWriterDeleteTest, testNonRAMDelete) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -197,8 +177,9 @@ TEST_F(IndexWriterDeleteTest, testNonRAMDelete) int32_t id = 0; int32_t value = 100; - for (int32_t i = 0; i < 7; ++i) + for (int32_t i = 0; i < 7; ++i) { addDoc(modifier, ++id, value); + } modifier->commit(); EXPECT_EQ(0, modifier->getNumBufferedDocuments()); @@ -221,8 +202,7 @@ TEST_F(IndexWriterDeleteTest, testNonRAMDelete) dir->close(); } -TEST_F(IndexWriterDeleteTest, testMaxBufferedDeletes) -{ +TEST_F(IndexWriterDeleteTest, testMaxBufferedDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDeleteTerms(1); @@ -235,10 +215,8 @@ TEST_F(IndexWriterDeleteTest, testMaxBufferedDeletes) } /// test when delete terms only apply to ram segments -TEST_F(IndexWriterDeleteTest, testRAMDeletes) -{ - for (int32_t t = 0; t < 2; ++t) - { +TEST_F(IndexWriterDeleteTest, testRAMDeletes) { + for (int32_t t = 0; t < 2; ++t) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -249,19 +227,19 @@ TEST_F(IndexWriterDeleteTest, testRAMDeletes) int32_t value = 100; addDoc(modifier, ++id, value); - if (t == 0) + if (t == 0) { modifier->deleteDocuments(newLucene(L"value", StringUtils::toString(value))); - else + } else { modifier->deleteDocuments(newLucene(newLucene(L"value", StringUtils::toString(value)))); + } addDoc(modifier, ++id, value); - if (t == 0) - { + if (t == 0) { modifier->deleteDocuments(newLucene(L"value", StringUtils::toString(value))); EXPECT_EQ(2, modifier->getNumBufferedDeleteTerms()); EXPECT_EQ(1, modifier->getBufferedDeleteTermsSize()); - } - else + } else { modifier->deleteDocuments(newLucene(newLucene(L"value", StringUtils::toString(value)))); + } addDoc(modifier, ++id, value); EXPECT_EQ(0, modifier->getSegmentCount()); @@ -281,8 +259,7 @@ TEST_F(IndexWriterDeleteTest, testRAMDeletes) } /// test when delete terms apply to both disk and ram segments -TEST_F(IndexWriterDeleteTest, testBothDeletes) -{ +TEST_F(IndexWriterDeleteTest, testBothDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -291,17 +268,20 @@ TEST_F(IndexWriterDeleteTest, testBothDeletes) int32_t id = 0; int32_t value = 100; - for (int32_t i = 0; i < 5; ++i) + for (int32_t i = 0; i < 5; ++i) { addDoc(modifier, ++id, value); + } value = 200; - for (int32_t i = 0; i < 5; ++i) + for (int32_t i = 0; i < 5; ++i) { addDoc(modifier, ++id, value); + } modifier->commit(); - for (int32_t i = 0; i < 5; ++i) + for (int32_t i = 0; i < 5; ++i) { addDoc(modifier, ++id, value); + } modifier->deleteDocuments(newLucene(L"value", StringUtils::toString(value))); @@ -314,8 +294,7 @@ TEST_F(IndexWriterDeleteTest, testBothDeletes) } /// test that batched delete terms are flushed together -TEST_F(IndexWriterDeleteTest, testBatchDeletes) -{ +TEST_F(IndexWriterDeleteTest, testBatchDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -324,8 +303,9 @@ TEST_F(IndexWriterDeleteTest, testBatchDeletes) int32_t id = 0; int32_t value = 100; - for (int32_t i = 0; i < 7; ++i) + for (int32_t i = 0; i < 7; ++i) { addDoc(modifier, ++id, value); + } modifier->commit(); IndexReaderPtr reader = IndexReader::open(dir, true); @@ -343,8 +323,9 @@ TEST_F(IndexWriterDeleteTest, testBatchDeletes) reader->close(); Collection terms = Collection::newInstance(3); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { terms[i] = newLucene(L"id", StringUtils::toString(++id)); + } modifier->deleteDocuments(terms); modifier->commit(); @@ -356,8 +337,7 @@ TEST_F(IndexWriterDeleteTest, testBatchDeletes) dir->close(); } -TEST_F(IndexWriterDeleteTest, testDeleteAll) -{ +TEST_F(IndexWriterDeleteTest, testDeleteAll) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -366,8 +346,9 @@ TEST_F(IndexWriterDeleteTest, testDeleteAll) int32_t id = 0; int32_t value = 100; - for (int32_t i = 0; i < 7; ++i) + for (int32_t i = 0; i < 7; ++i) { addDoc(modifier, ++id, value); + } modifier->commit(); IndexReaderPtr reader = IndexReader::open(dir, true); @@ -401,8 +382,7 @@ TEST_F(IndexWriterDeleteTest, testDeleteAll) dir->close(); } -TEST_F(IndexWriterDeleteTest, testDeleteAllRollback) -{ +TEST_F(IndexWriterDeleteTest, testDeleteAllRollback) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -411,8 +391,9 @@ TEST_F(IndexWriterDeleteTest, testDeleteAllRollback) int32_t id = 0; int32_t value = 100; - for (int32_t i = 0; i < 7; ++i) + for (int32_t i = 0; i < 7; ++i) { addDoc(modifier, ++id, value); + } modifier->commit(); addDoc(modifier, 99, value); @@ -437,8 +418,7 @@ TEST_F(IndexWriterDeleteTest, testDeleteAllRollback) } /// test deleteAll() with near real-time reader -TEST_F(IndexWriterDeleteTest, testDeleteAllNRT) -{ +TEST_F(IndexWriterDeleteTest, testDeleteAllNRT) { DirectoryPtr dir = newLucene(); IndexWriterPtr modifier = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -447,8 +427,9 @@ TEST_F(IndexWriterDeleteTest, testDeleteAllNRT) int32_t id = 0; int32_t value = 100; - for (int32_t i = 0; i < 7; ++i) + for (int32_t i = 0; i < 7; ++i) { addDoc(modifier, ++id, value); + } modifier->commit(); IndexReaderPtr reader = modifier->getReader(); @@ -479,8 +460,7 @@ TEST_F(IndexWriterDeleteTest, testDeleteAllNRT) /// Make sure if modifier tries to commit but hits disk full that modifier /// remains consistent and usable. -static void testOperationsOnDiskFull(bool updates) -{ +static void testOperationsOnDiskFull(bool updates) { TermPtr searchTerm = newLucene(L"content", L"aaa"); int32_t START_COUNT = 157; int32_t END_COUNT = 144; @@ -488,8 +468,7 @@ static void testOperationsOnDiskFull(bool updates) // First build up a starting index RAMDirectoryPtr startDir = newLucene(); IndexWriterPtr writer = newLucene(startDir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 157; ++i) - { + for (int32_t i = 0; i < 157; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"content", L"aaa " + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -505,8 +484,7 @@ static void testOperationsOnDiskFull(bool updates) bool done = false; // Iterate with ever increasing free disk space - while (!done) - { + while (!done) { MockRAMDirectoryPtr dir = newLucene(startDir); // If IndexReader hits disk full, it can write to the same files again. @@ -522,26 +500,25 @@ static void testOperationsOnDiskFull(bool updates) // retry with same reader bool success = false; - for (int32_t x = 0; x < 2; ++x) - { + for (int32_t x = 0; x < 2; ++x) { double rate = 0.1; double diskRatio = ((double)diskFree) / (double)diskUsage; int64_t thisDiskFree = 0; String testName; - if (x == 0) - { + if (x == 0) { thisDiskFree = diskFree; - if (diskRatio >= 2.0) + if (diskRatio >= 2.0) { rate /= 2; - if (diskRatio >= 4.0) + } + if (diskRatio >= 4.0) { rate /= 2; - if (diskRatio >= 6.0) + } + if (diskRatio >= 6.0) { rate = 0.0; + } testName = L"disk full during reader.close() @ " + StringUtils::toString(thisDiskFree) + L" bytes"; - } - else - { + } else { thisDiskFree = 0; rate = 0.0; testName = L"reader re-use after disk full"; @@ -550,40 +527,35 @@ static void testOperationsOnDiskFull(bool updates) dir->setMaxSizeInBytes(thisDiskFree); dir->setRandomIOExceptionRate(rate, diskFree); - try - { - if (x == 0) - { + try { + if (x == 0) { int32_t docId = 12; - for (int32_t i = 0; i < 13; ++i) - { - if (updates) - { + for (int32_t i = 0; i < 13; ++i) { + if (updates) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"content", L"bbb " + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_ANALYZED)); modifier->updateDocument(newLucene(L"id", StringUtils::toString(docId)), doc); - } - else // deletes + } else { // deletes modifier->deleteDocuments(newLucene(L"id", StringUtils::toString(docId))); + } docId += 12; } } modifier->close(); success = true; - if (x == 0) + if (x == 0) { done = true; - } - catch (IOException& e) - { + } + } catch (IOException& e) { err = e; - if (x == 1) + if (x == 1) { FAIL() << testName << " hit IOException after disk space was freed up"; + } } // If the close() succeeded, make sure there are no unreferenced files. - if (success) - { + if (success) { checkIndex(dir); checkNoUnreferencedFiles(dir); } @@ -592,12 +564,9 @@ static void testOperationsOnDiskFull(bool updates) // we failed, we see either all docs or no docs changed (transactional semantics): IndexReaderPtr newReader; - try - { + try { newReader = IndexReader::open(dir, true); - } - catch (IOException& e) - { + } catch (IOException& e) { FAIL() << testName << ":exception when creating IndexReader after disk full during close:" << e.getError(); } @@ -605,30 +574,28 @@ static void testOperationsOnDiskFull(bool updates) Collection hits; EXPECT_NO_THROW(hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs); int32_t result2 = hits.size(); - if (success) - { - if (x == 0 && result2 != END_COUNT) + if (success) { + if (x == 0 && result2 != END_COUNT) { FAIL() << testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << END_COUNT; - else if (x == 1 && result2 != START_COUNT && result2 != END_COUNT) - { + } else if (x == 1 && result2 != START_COUNT && result2 != END_COUNT) { // It's possible that the first exception was "recoverable" wrt pending deletes, in which // case the pending deletes are retained and then re-flushing (with plenty of disk space) // will succeed in flushing the deletes FAIL() << testName << ": method did not throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << START_COUNT << " or " << END_COUNT; } - } - else - { + } else { // On hitting exception we still may have added all docs - if (result2 != START_COUNT && result2 != END_COUNT) + if (result2 != START_COUNT && result2 != END_COUNT) { FAIL() << testName << ": method did throw exception but hits.size() for search on term 'aaa' is " << result2 << " instead of expected " << START_COUNT << " or " << END_COUNT; + } } searcher->close(); newReader->close(); - if (result2 == END_COUNT) + if (result2 == END_COUNT) { break; + } } dir->close(); @@ -640,19 +607,16 @@ static void testOperationsOnDiskFull(bool updates) startDir->close(); } -TEST_F(IndexWriterDeleteTest, testDeletesOnDiskFull) -{ +TEST_F(IndexWriterDeleteTest, testDeletesOnDiskFull) { testOperationsOnDiskFull(false); } -TEST_F(IndexWriterDeleteTest, testUpdatesOnDiskFull) -{ +TEST_F(IndexWriterDeleteTest, testUpdatesOnDiskFull) { testOperationsOnDiskFull(true); } /// This test tests that buffered deletes are cleared when an Exception is hit during flush. -TEST_F(IndexWriterDeleteTest, testErrorAfterApplyDeletes) -{ +TEST_F(IndexWriterDeleteTest, testErrorAfterApplyDeletes) { Collection keywords = newCollection(L"1", L"2"); Collection unindexed = newCollection(L"Netherlands", L"Italy"); Collection unstored = newCollection(L"Amsterdam has lots of bridges", L"Venice has lots of canals"); @@ -667,8 +631,7 @@ TEST_F(IndexWriterDeleteTest, testErrorAfterApplyDeletes) FailOnlyOnDeleteFlushPtr failure = newLucene(); dir->failOn(failure->reset()); - for (int32_t i = 0; i < keywords.size(); ++i) - { + for (int32_t i = 0; i < keywords.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", keywords[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"country", unindexed[i], Field::STORE_YES, Field::INDEX_NO)); @@ -699,12 +662,9 @@ TEST_F(IndexWriterDeleteTest, testErrorAfterApplyDeletes) // the cfs file happens next so we need the doc (to test that it's okay that we don't // lose deletes if failing while creating the cfs file) - try - { + try { modifier->commit(); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } @@ -723,8 +683,7 @@ TEST_F(IndexWriterDeleteTest, testErrorAfterApplyDeletes) /// This test tests that the files created by the docs writer before a segment is written are /// cleaned up if there's an i/o error -TEST_F(IndexWriterDeleteTest, testErrorInDocsWriterAdd) -{ +TEST_F(IndexWriterDeleteTest, testErrorInDocsWriterAdd) { Collection keywords = newCollection(L"1", L"2"); Collection unindexed = newCollection(L"Netherlands", L"Italy"); Collection unstored = newCollection(L"Amsterdam has lots of bridges", L"Venice has lots of canals"); @@ -736,20 +695,16 @@ TEST_F(IndexWriterDeleteTest, testErrorInDocsWriterAdd) FailOnlyOnAddPtr failure = newLucene(); dir->failOn(failure->reset()); - for (int32_t i = 0; i < keywords.size(); ++i) - { + for (int32_t i = 0; i < keywords.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", keywords[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"country", unindexed[i], Field::STORE_YES, Field::INDEX_NO)); doc->add(newLucene(L"contents", unstored[i], Field::STORE_NO, Field::INDEX_ANALYZED)); doc->add(newLucene(L"city", text[i], Field::STORE_YES, Field::INDEX_ANALYZED)); - try - { + try { modifier->addDocument(doc); - } - catch (IOException&) - { + } catch (IOException&) { break; } } diff --git a/src/test/index/IndexWriterExceptionsTest.cpp b/src/test/index/IndexWriterExceptionsTest.cpp index 4b7fe0be..ba05c4a9 100644 --- a/src/test/index/IndexWriterExceptionsTest.cpp +++ b/src/test/index/IndexWriterExceptionsTest.cpp @@ -22,20 +22,17 @@ using namespace Lucene; -class IndexWriterExceptionsTest : public LuceneTestFixture -{ +class IndexWriterExceptionsTest : public LuceneTestFixture { public: - IndexWriterExceptionsTest() - { + IndexWriterExceptionsTest() { random = newLucene(); tvSettings = newCollection( - Field::TERM_VECTOR_NO, Field::TERM_VECTOR_YES, Field::TERM_VECTOR_WITH_OFFSETS, - Field::TERM_VECTOR_WITH_POSITIONS, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS - ); + Field::TERM_VECTOR_NO, Field::TERM_VECTOR_YES, Field::TERM_VECTOR_WITH_OFFSETS, + Field::TERM_VECTOR_WITH_POSITIONS, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS + ); } - virtual ~IndexWriterExceptionsTest() - { + virtual ~IndexWriterExceptionsTest() { } protected: @@ -43,8 +40,7 @@ class IndexWriterExceptionsTest : public LuceneTestFixture Collection tvSettings; public: - Field::TermVector randomTVSetting() - { + Field::TermVector randomTVSetting() { return tvSettings[random->nextInt(tvSettings.size())]; } }; @@ -53,18 +49,15 @@ static CloseableThreadLocal doFail; DECLARE_SHARED_PTR(ExceptionsIndexerThread) -class ExceptionsIndexerThread : public LuceneThread -{ +class ExceptionsIndexerThread : public LuceneThread { public: - ExceptionsIndexerThread(const IndexWriterPtr& writer, IndexWriterExceptionsTest* fixture) - { + ExceptionsIndexerThread(const IndexWriterPtr& writer, IndexWriterExceptionsTest* fixture) { this->writer = writer; this->fixture = fixture; this->r = newLucene(47); } - virtual ~ExceptionsIndexerThread() - { + virtual ~ExceptionsIndexerThread() { } LUCENE_CLASS(ExceptionsIndexerThread); @@ -76,8 +69,7 @@ class ExceptionsIndexerThread : public LuceneThread RandomPtr r; public: - virtual void run() - { + virtual void run() { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content1", L"aaa bbb ccc ddd", Field::STORE_YES, Field::INDEX_ANALYZED, fixture->randomTVSetting())); doc->add(newLucene(L"content6", L"aaa bbb ccc ddd", Field::STORE_NO, Field::INDEX_ANALYZED, fixture->randomTVSetting())); @@ -94,30 +86,21 @@ class ExceptionsIndexerThread : public LuceneThread int64_t stopTime = MiscUtils::currentTimeMillis() + 3000; - while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) - { + while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) { doFail.set(shared_from_this()); String id = StringUtils::toString(r->nextInt(50)); idField->setValue(id); TermPtr idTerm = newLucene(L"id", id); - try - { + try { writer->updateDocument(idTerm, doc); - } - catch (RuntimeException&) - { - try - { + } catch (RuntimeException&) { + try { checkIndex(writer->getDirectory()); - } - catch (IOException& ioe) - { + } catch (IOException& ioe) { failure = ioe; break; } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { failure = e; break; } @@ -126,12 +109,9 @@ class ExceptionsIndexerThread : public LuceneThread // After a possible exception (above) I should be able to add a new document // without hitting an exception - try - { + try { writer->updateDocument(idTerm, doc); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { failure = e; break; } @@ -139,32 +119,28 @@ class ExceptionsIndexerThread : public LuceneThread } }; -class MockIndexWriter : public IndexWriter -{ +class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) - { + MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) { this->r = newLucene(17); } - virtual ~MockIndexWriter() - { + virtual ~MockIndexWriter() { } protected: RandomPtr r; public: - virtual bool testPoint(const String& name) - { - if (doFail.get() && name != L"startDoFlush" && r->nextInt(20) == 17) + virtual bool testPoint(const String& name) { + if (doFail.get() && name != L"startDoFlush" && r->nextInt(20) == 17) { boost::throw_exception(RuntimeException(L"intentionally failing at " + name)); + } return true; } }; -TEST_F(IndexWriterExceptionsTest, testRandomExceptions) -{ +TEST_F(IndexWriterExceptionsTest, testRandomExceptions) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); boost::dynamic_pointer_cast(writer->getMergeScheduler())->setSuppressExceptions(); @@ -174,17 +150,15 @@ TEST_F(IndexWriterExceptionsTest, testRandomExceptions) ExceptionsIndexerThreadPtr thread = newLucene(writer, this); thread->run(); - if (!thread->failure.isNull()) + if (!thread->failure.isNull()) { FAIL() << "thread hit unexpected failure"; + } writer->commit(); - try - { + try { writer->close(); - } - catch (LuceneException&) - { + } catch (LuceneException&) { writer->rollback(); } @@ -198,8 +172,7 @@ TEST_F(IndexWriterExceptionsTest, testRandomExceptions) checkIndex(dir); } -TEST_F(IndexWriterExceptionsTest, testRandomExceptionsThreads) -{ +TEST_F(IndexWriterExceptionsTest, testRandomExceptionsThreads) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); boost::dynamic_pointer_cast(writer->getMergeScheduler())->setSuppressExceptions(); @@ -209,29 +182,26 @@ TEST_F(IndexWriterExceptionsTest, testRandomExceptionsThreads) int32_t NUM_THREADS = 4; Collection threads = Collection::newInstance(NUM_THREADS); - for (int32_t i = 0; i < NUM_THREADS; ++i) - { + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i] = newLucene(writer, this); threads[i]->start(); } - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); + } - for (int32_t i = 0; i < NUM_THREADS; ++i) - { - if (!threads[i]->failure.isNull()) + for (int32_t i = 0; i < NUM_THREADS; ++i) { + if (!threads[i]->failure.isNull()) { FAIL() << "thread hit unexpected failure: " << threads[i]->failure.getError(); + } } writer->commit(); - try - { + try { writer->close(); - } - catch (LuceneException&) - { + } catch (LuceneException&) { writer->rollback(); } diff --git a/src/test/index/IndexWriterLockReleaseTest.cpp b/src/test/index/IndexWriterLockReleaseTest.cpp index 012bd86f..7f7f700e 100644 --- a/src/test/index/IndexWriterLockReleaseTest.cpp +++ b/src/test/index/IndexWriterLockReleaseTest.cpp @@ -16,29 +16,22 @@ using namespace Lucene; typedef LuceneTestFixture IndexWriterLockReleaseTest; -TEST_F(IndexWriterLockReleaseTest, testIndexWriterLockRelease) -{ +TEST_F(IndexWriterLockReleaseTest, testIndexWriterLockRelease) { String testDir(getTempDir(L"testIndexWriter")); FileUtils::createDirectory(testDir); DirectoryPtr dir = FSDirectory::open(testDir); IndexWriterPtr im; - try - { + try { im = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); - } - catch (FileNotFoundException& e) - { + } catch (FileNotFoundException& e) { EXPECT_TRUE(check_exception(LuceneException::FileNotFound)(e)); } - try - { + try { im = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); - } - catch (FileNotFoundException& e) - { + } catch (FileNotFoundException& e) { EXPECT_TRUE(check_exception(LuceneException::FileNotFound)(e)); } diff --git a/src/test/index/IndexWriterMergePolicyTest.cpp b/src/test/index/IndexWriterMergePolicyTest.cpp index c1d056fa..898d4378 100644 --- a/src/test/index/IndexWriterMergePolicyTest.cpp +++ b/src/test/index/IndexWriterMergePolicyTest.cpp @@ -21,15 +21,13 @@ using namespace Lucene; typedef LuceneTestFixture IndexWriterMergePolicyTest; -static void addDoc(const IndexWriterPtr& writer) -{ +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void checkInvariants(const IndexWriterPtr& writer) -{ +static void checkInvariants(const IndexWriterPtr& writer) { writer->waitForMerges(); int32_t maxBufferedDocs = writer->getMaxBufferedDocs(); int32_t mergeFactor = writer->getMergeFactor(); @@ -43,33 +41,30 @@ static void checkInvariants(const IndexWriterPtr& writer) int32_t numSegments = 0; int32_t segmentCount = writer->getSegmentCount(); - for (int32_t i = segmentCount - 1; i >= 0; --i) - { + for (int32_t i = segmentCount - 1; i >= 0; --i) { int32_t docCount = writer->getDocCount(i); EXPECT_TRUE(docCount > lowerBound); - if (docCount <= upperBound) + if (docCount <= upperBound) { ++numSegments; - else - { - if (upperBound * mergeFactor <= maxMergeDocs) + } else { + if (upperBound * mergeFactor <= maxMergeDocs) { EXPECT_TRUE(numSegments < mergeFactor); + } - do - { + do { lowerBound = upperBound; upperBound *= mergeFactor; - } - while (docCount > upperBound); + } while (docCount > upperBound); numSegments = 1; } } - if (upperBound * mergeFactor <= maxMergeDocs) + if (upperBound * mergeFactor <= maxMergeDocs) { EXPECT_TRUE(numSegments < mergeFactor); + } } -TEST_F(IndexWriterMergePolicyTest, testNormalCase) -{ +TEST_F(IndexWriterMergePolicyTest, testNormalCase) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -77,8 +72,7 @@ TEST_F(IndexWriterMergePolicyTest, testNormalCase) writer->setMergeFactor(10); writer->setMergePolicy(newLucene(writer)); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); checkInvariants(writer); } @@ -86,8 +80,7 @@ TEST_F(IndexWriterMergePolicyTest, testNormalCase) writer->close(); } -TEST_F(IndexWriterMergePolicyTest, testNoOverMerge) -{ +TEST_F(IndexWriterMergePolicyTest, testNoOverMerge) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -96,12 +89,12 @@ TEST_F(IndexWriterMergePolicyTest, testNoOverMerge) writer->setMergePolicy(newLucene(writer)); bool noOverMerge = false; - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); checkInvariants(writer); - if (writer->getNumBufferedDocuments() + writer->getSegmentCount() >= 18) + if (writer->getNumBufferedDocuments() + writer->getSegmentCount() >= 18) { noOverMerge = true; + } } EXPECT_TRUE(noOverMerge); @@ -110,8 +103,7 @@ TEST_F(IndexWriterMergePolicyTest, testNoOverMerge) } /// Test the case where flush is forced after every addDoc -TEST_F(IndexWriterMergePolicyTest, testForceFlush) -{ +TEST_F(IndexWriterMergePolicyTest, testForceFlush) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -121,8 +113,7 @@ TEST_F(IndexWriterMergePolicyTest, testForceFlush) mp->setMinMergeDocs(100); writer->setMergePolicy(mp); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); writer->close(); @@ -138,8 +129,7 @@ TEST_F(IndexWriterMergePolicyTest, testForceFlush) } /// Test the case where mergeFactor changes -TEST_F(IndexWriterMergePolicyTest, testMergeFactorChange) -{ +TEST_F(IndexWriterMergePolicyTest, testMergeFactorChange) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -147,8 +137,7 @@ TEST_F(IndexWriterMergePolicyTest, testMergeFactorChange) writer->setMergeFactor(100); writer->setMergePolicy(newLucene(writer)); - for (int32_t i = 0; i < 250; ++i) - { + for (int32_t i = 0; i < 250; ++i) { addDoc(writer); checkInvariants(writer); } @@ -156,16 +145,16 @@ TEST_F(IndexWriterMergePolicyTest, testMergeFactorChange) writer->setMergeFactor(5); // merge policy only fixes segments on levels where merges have been triggered, so check invariants after all adds - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { addDoc(writer); + } checkInvariants(writer); writer->close(); } /// Test the case where both mergeFactor and maxBufferedDocs change -TEST_F(IndexWriterMergePolicyTest, testMaxBufferedDocsChange) -{ +TEST_F(IndexWriterMergePolicyTest, testMaxBufferedDocsChange) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -175,10 +164,8 @@ TEST_F(IndexWriterMergePolicyTest, testMaxBufferedDocsChange) // leftmost* segment has 1 doc // rightmost* segment has 100 docs - for (int32_t i = 1; i <= 100; ++i) - { - for (int32_t j = 0; j < i; ++j) - { + for (int32_t i = 1; i <= 100; ++i) { + for (int32_t j = 0; j < i; ++j) { addDoc(writer); checkInvariants(writer); } @@ -194,12 +181,14 @@ TEST_F(IndexWriterMergePolicyTest, testMaxBufferedDocsChange) writer->setMergeFactor(10); // merge policy only fixes segments on levels where merges have been triggered, so check invariants after all adds - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } checkInvariants(writer); - for (int32_t i = 100; i < 1000; ++i) + for (int32_t i = 100; i < 1000; ++i) { addDoc(writer); + } writer->commit(); boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); writer->commit(); @@ -209,8 +198,7 @@ TEST_F(IndexWriterMergePolicyTest, testMaxBufferedDocsChange) } /// Test the case where a merge results in no doc at all -TEST_F(IndexWriterMergePolicyTest, testMergeDocCount0) -{ +TEST_F(IndexWriterMergePolicyTest, testMergeDocCount0) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -218,8 +206,7 @@ TEST_F(IndexWriterMergePolicyTest, testMergeDocCount0) writer->setMaxBufferedDocs(10); writer->setMergeFactor(100); - for (int32_t i = 0; i < 250; ++i) - { + for (int32_t i = 0; i < 250; ++i) { addDoc(writer); checkInvariants(writer); } @@ -235,8 +222,9 @@ TEST_F(IndexWriterMergePolicyTest, testMergeDocCount0) writer->setMergeFactor(5); // merge factor is changed, so check invariants after all adds - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { addDoc(writer); + } writer->commit(); boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); writer->commit(); diff --git a/src/test/index/IndexWriterMergingTest.cpp b/src/test/index/IndexWriterMergingTest.cpp index e7efaaf4..085d9b33 100644 --- a/src/test/index/IndexWriterMergingTest.cpp +++ b/src/test/index/IndexWriterMergingTest.cpp @@ -18,30 +18,27 @@ using namespace Lucene; typedef LuceneTestFixture IndexWriterMergingTest; -static bool verifyIndex(const DirectoryPtr& directory, int32_t startAt) -{ +static bool verifyIndex(const DirectoryPtr& directory, int32_t startAt) { bool fail = false; IndexReaderPtr reader = IndexReader::open(directory, true); int32_t max = reader->maxDoc(); - for (int32_t i = 0; i < max; ++i) - { + for (int32_t i = 0; i < max; ++i) { DocumentPtr temp = reader->document(i); - if (temp->getField(L"count")->stringValue() != StringUtils::toString(i + startAt)) + if (temp->getField(L"count")->stringValue() != StringUtils::toString(i + startAt)) { fail = true; + } } reader->close(); return fail; } -static void fillIndex(const DirectoryPtr& dir, int32_t start, int32_t numDocs) -{ +static void fillIndex(const DirectoryPtr& dir, int32_t start, int32_t numDocs) { IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMergeFactor(2); writer->setMaxBufferedDocs(2); - for (int32_t i = start; i < (start + numDocs); ++i) - { + for (int32_t i = start; i < (start + numDocs); ++i) { DocumentPtr temp = newLucene(); temp->add(newLucene(L"count", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(temp); @@ -50,8 +47,7 @@ static void fillIndex(const DirectoryPtr& dir, int32_t start, int32_t numDocs) } /// Tests that index merging (specifically addIndexesNoOptimize()) doesn't change the index order of documents. -TEST_F(IndexWriterMergingTest, testIndexWriterMerging) -{ +TEST_F(IndexWriterMergingTest, testIndexWriterMerging) { int32_t num = 100; DirectoryPtr indexA = newLucene(); diff --git a/src/test/index/IndexWriterReaderTest.cpp b/src/test/index/IndexWriterReaderTest.cpp index 89d4ab7b..1ecc9011 100644 --- a/src/test/index/IndexWriterReaderTest.cpp +++ b/src/test/index/IndexWriterReaderTest.cpp @@ -32,8 +32,7 @@ DECLARE_SHARED_PTR(AddDirectoriesThread) DECLARE_SHARED_PTR(AddDirectoriesThreads) DECLARE_SHARED_PTR(HeavyAtomicInt) -static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t numFields) -{ +static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t numFields) { StringStream sb; DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(n), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -41,25 +40,25 @@ static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t nu sb << L"a" << n; doc->add(newLucene(L"field1", sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); sb << L" b" << n; - for (int32_t i = 1; i < numFields; ++i) + for (int32_t i = 1; i < numFields; ++i) { doc->add(newLucene(L"field" + StringUtils::toString(i + 1), sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); + } return doc; } -static void createIndexNoClose(bool multiSegment, const String& indexName, const IndexWriterPtr& w) -{ - for (int32_t i = 0; i < 100; ++i) +static void createIndexNoClose(bool multiSegment, const String& indexName, const IndexWriterPtr& w) { + for (int32_t i = 0; i < 100; ++i) { w->addDocument(createDocument(i, indexName, 4)); - if (!multiSegment) + } + if (!multiSegment) { w->optimize(); + } } -static int32_t count(const TermPtr& t, const IndexReaderPtr& r) -{ +static int32_t count(const TermPtr& t, const IndexReaderPtr& r) { int32_t count = 0; TermDocsPtr td = r->termDocs(t); - while (td->next()) - { + while (td->next()) { td->doc(); ++count; } @@ -67,15 +66,12 @@ static int32_t count(const TermPtr& t, const IndexReaderPtr& r) return count; } -class TestableIndexWriter : public IndexWriter -{ +class TestableIndexWriter : public IndexWriter { public: - TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl) : IndexWriter(d, a, mfl) - { + TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, int32_t mfl) : IndexWriter(d, a, mfl) { } - virtual ~TestableIndexWriter() - { + virtual ~TestableIndexWriter() { } LUCENE_CLASS(TestableIndexWriter); @@ -84,16 +80,13 @@ class TestableIndexWriter : public IndexWriter using IndexWriter::flush; }; -class HeavyAtomicInt : public LuceneObject -{ +class HeavyAtomicInt : public LuceneObject { public: - HeavyAtomicInt(int32_t start) - { + HeavyAtomicInt(int32_t start) { value = start; } - virtual ~HeavyAtomicInt() - { + virtual ~HeavyAtomicInt() { } @@ -101,37 +94,31 @@ class HeavyAtomicInt : public LuceneObject int32_t value; public: - int32_t addAndGet(int32_t inc) - { + int32_t addAndGet(int32_t inc) { SyncLock syncLock(this); value += inc; return value; } - int32_t incrementAndGet() - { + int32_t incrementAndGet() { SyncLock syncLock(this); return ++value; } - int32_t intValue() - { + int32_t intValue() { SyncLock syncLock(this); return value; } }; -class AddDirectoriesThread : public LuceneThread -{ +class AddDirectoriesThread : public LuceneThread { public: - AddDirectoriesThread(const AddDirectoriesThreadsPtr& addDirectories, int32_t numIter) - { + AddDirectoriesThread(const AddDirectoriesThreadsPtr& addDirectories, int32_t numIter) { this->_addDirectories = addDirectories; this->numIter = numIter; } - virtual ~AddDirectoriesThread() - { + virtual ~AddDirectoriesThread() { } LUCENE_CLASS(AddDirectoriesThread); @@ -144,11 +131,9 @@ class AddDirectoriesThread : public LuceneThread virtual void run(); }; -class AddDirectoriesThreads : public LuceneObject -{ +class AddDirectoriesThreads : public LuceneObject { public: - AddDirectoriesThreads(int32_t numDirs, const IndexWriterPtr& mainWriter) - { + AddDirectoriesThreads(int32_t numDirs, const IndexWriterPtr& mainWriter) { this->numDirs = numDirs; this->mainWriter = mainWriter; threads = Collection::newInstance(NUM_THREADS); @@ -159,8 +144,7 @@ class AddDirectoriesThreads : public LuceneObject addDir = newLucene(); IndexWriterPtr writer = newLucene(addDir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < NUM_INIT_DOCS; ++i) - { + for (int32_t i = 0; i < NUM_INIT_DOCS; ++i) { DocumentPtr doc = createDocument(i, L"addindex", 4); writer->addDocument(doc); } @@ -168,12 +152,12 @@ class AddDirectoriesThreads : public LuceneObject writer->close(); readers = Collection::newInstance(numDirs); - for (int32_t i = 0; i < numDirs; ++i) + for (int32_t i = 0; i < numDirs; ++i) { readers[i] = IndexReader::open(addDir, false); + } } - virtual ~AddDirectoriesThreads() - { + virtual ~AddDirectoriesThreads() { } LUCENE_CLASS(AddDirectoriesThreads); @@ -193,58 +177,55 @@ class AddDirectoriesThreads : public LuceneObject HeavyAtomicIntPtr numAddIndexesNoOptimize; public: - void joinThreads() - { - for (int32_t i = 0; i < NUM_THREADS; ++i) + void joinThreads() { + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); + } } - void close(bool doWait) - { + void close(bool doWait) { didClose = true; mainWriter->close(doWait); } - void closeDir() - { - for (int32_t i = 0; i < numDirs; ++i) + void closeDir() { + for (int32_t i = 0; i < numDirs; ++i) { readers[i]->close(); + } addDir->close(); } - void handle(const LuceneException& t) - { + void handle(const LuceneException& t) { FAIL() << t.getError(); SyncLock syncLock(&failures); failures.add(t); } - void launchThreads(int32_t numIter) - { - for (int32_t i = 0; i < NUM_THREADS; ++i) + void launchThreads(int32_t numIter) { + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i] = newLucene(shared_from_this(), numIter); - for (int32_t i = 0; i < NUM_THREADS; ++i) + } + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->start(); + } } - void doBody(int32_t j, Collection dirs) - { - switch (j % 4) - { - case 0: - mainWriter->addIndexesNoOptimize(dirs); - mainWriter->optimize(); - break; - case 1: - mainWriter->addIndexesNoOptimize(dirs); - numAddIndexesNoOptimize->incrementAndGet(); - break; - case 2: - mainWriter->addIndexes(readers); - break; - case 3: - mainWriter->commit(); - break; + void doBody(int32_t j, Collection dirs) { + switch (j % 4) { + case 0: + mainWriter->addIndexesNoOptimize(dirs); + mainWriter->optimize(); + break; + case 1: + mainWriter->addIndexesNoOptimize(dirs); + numAddIndexesNoOptimize->incrementAndGet(); + break; + case 2: + mainWriter->addIndexes(readers); + break; + case 3: + mainWriter->commit(); + break; } count->addAndGet(dirs.size() * NUM_INIT_DOCS); } @@ -253,29 +234,24 @@ class AddDirectoriesThreads : public LuceneObject const int32_t AddDirectoriesThreads::NUM_THREADS = 5; const int32_t AddDirectoriesThreads::NUM_INIT_DOCS = 100; -void AddDirectoriesThread::run() -{ +void AddDirectoriesThread::run() { AddDirectoriesThreadsPtr addDirectories(_addDirectories); - try - { + try { Collection dirs = Collection::newInstance(addDirectories->numDirs); - for (int32_t k = 0; k < addDirectories->numDirs; ++k) + for (int32_t k = 0; k < addDirectories->numDirs; ++k) { dirs[k] = newLucene(addDirectories->addDir); - for (int32_t x = 0; x < numIter; ++x) - { + } + for (int32_t x = 0; x < numIter; ++x) { // only do addIndexesNoOptimize addDirectories->doBody(x, dirs); } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { addDirectories->handle(e); } } -TEST_F(IndexWriterReaderTest, testUpdateDocument) -{ +TEST_F(IndexWriterReaderTest, testUpdateDocument) { bool optimize = true; DirectoryPtr dir1 = newLucene(); @@ -329,8 +305,7 @@ TEST_F(IndexWriterReaderTest, testUpdateDocument) dir1->close(); } -TEST_F(IndexWriterReaderTest, testAddIndexes) -{ +TEST_F(IndexWriterReaderTest, testAddIndexes) { bool optimize = false; DirectoryPtr dir1 = newLucene(); @@ -375,8 +350,7 @@ TEST_F(IndexWriterReaderTest, testAddIndexes) dir1->close(); } -TEST_F(IndexWriterReaderTest, testAddIndexes2) -{ +TEST_F(IndexWriterReaderTest, testAddIndexes2) { bool optimize = false; DirectoryPtr dir1 = newLucene(); @@ -403,8 +377,7 @@ TEST_F(IndexWriterReaderTest, testAddIndexes2) dir1->close(); } -TEST_F(IndexWriterReaderTest, testDeleteFromIndexWriter) -{ +TEST_F(IndexWriterReaderTest, testDeleteFromIndexWriter) { bool optimize = true; DirectoryPtr dir1 = newLucene(); @@ -456,8 +429,7 @@ TEST_F(IndexWriterReaderTest, testDeleteFromIndexWriter) dir1->close(); } -TEST_F(IndexWriterReaderTest, testAddIndexesAndDoDeletesThreads) -{ +TEST_F(IndexWriterReaderTest, testAddIndexesAndDoDeletesThreads) { int32_t numIter = 5; int32_t numDirs = 3; @@ -484,8 +456,7 @@ TEST_F(IndexWriterReaderTest, testAddIndexesAndDoDeletesThreads) } /// Tests creating a segment, then check to insure the segment can be seen via IndexWriter.getReader -static void doTestIndexWriterReopenSegment(bool optimize) -{ +static void doTestIndexWriterReopenSegment(bool optimize) { DirectoryPtr dir1 = newLucene(); TestableIndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -501,8 +472,7 @@ static void doTestIndexWriterReopenSegment(bool optimize) EXPECT_EQ(100, r2->maxDoc()); // add 100 documents - for (int32_t x = 10000; x < 10000 + 100; ++x) - { + for (int32_t x = 10000; x < 10000 + 100; ++x) { DocumentPtr d = createDocument(x, L"index1", 5); writer->addDocument(d); } @@ -535,47 +505,41 @@ static void doTestIndexWriterReopenSegment(bool optimize) dir1->close(); } -TEST_F(IndexWriterReaderTest, testIndexWriterReopenSegmentOptimize) -{ +TEST_F(IndexWriterReaderTest, testIndexWriterReopenSegmentOptimize) { doTestIndexWriterReopenSegment(true); } -TEST_F(IndexWriterReaderTest, testIndexWriterReopenSegment) -{ +TEST_F(IndexWriterReaderTest, testIndexWriterReopenSegment) { doTestIndexWriterReopenSegment(false); } -namespace TestMergeWarmer -{ - DECLARE_SHARED_PTR(MyWarmer) +namespace TestMergeWarmer { - class MyWarmer : public IndexReaderWarmer - { - public: - MyWarmer() - { - warmCount = 0; - } +DECLARE_SHARED_PTR(MyWarmer) - virtual ~MyWarmer() - { - } +class MyWarmer : public IndexReaderWarmer { +public: + MyWarmer() { + warmCount = 0; + } - LUCENE_CLASS(MyWarmer); + virtual ~MyWarmer() { + } - public: - int32_t warmCount; + LUCENE_CLASS(MyWarmer); + +public: + int32_t warmCount; + +public: + virtual void warm(const IndexReaderPtr& reader) { + ++warmCount; + } +}; - public: - virtual void warm(const IndexReaderPtr& reader) - { - ++warmCount; - } - }; } -TEST_F(IndexWriterReaderTest, testMergeWarmer) -{ +TEST_F(IndexWriterReaderTest, testMergeWarmer) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -591,8 +555,9 @@ TEST_F(IndexWriterReaderTest, testMergeWarmer) writer->setMergeFactor(2); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { writer->addDocument(createDocument(i, L"test", 4)); + } boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); @@ -608,8 +573,7 @@ TEST_F(IndexWriterReaderTest, testMergeWarmer) dir1->close(); } -TEST_F(IndexWriterReaderTest, testAfterCommit) -{ +TEST_F(IndexWriterReaderTest, testAfterCommit) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -623,14 +587,14 @@ TEST_F(IndexWriterReaderTest, testAfterCommit) checkIndex(dir1); EXPECT_EQ(100, r1->numDocs()); - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { writer->addDocument(createDocument(i, L"test", 4)); + } boost::dynamic_pointer_cast(writer->getMergeScheduler())->sync(); IndexReaderPtr r2 = r1->reopen(); - if (r2 != r1) - { + if (r2 != r1) { r1->close(); r1 = r2; } @@ -642,8 +606,7 @@ TEST_F(IndexWriterReaderTest, testAfterCommit) } /// Make sure reader remains usable even if IndexWriter closes -TEST_F(IndexWriterReaderTest, testAfterClose) -{ +TEST_F(IndexWriterReaderTest, testAfterClose) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -660,12 +623,9 @@ TEST_F(IndexWriterReaderTest, testAfterClose) QueryPtr q = newLucene(newLucene(L"indexname", L"test")); EXPECT_EQ(100, newLucene(r)->search(q, 10)->totalHits); - try - { + try { r->reopen(); - } - catch (AlreadyClosedException& e) - { + } catch (AlreadyClosedException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } @@ -673,50 +633,42 @@ TEST_F(IndexWriterReaderTest, testAfterClose) dir1->close(); } -namespace TestDuringAddIndexes -{ - class AddIndexesThread : public LuceneThread - { - public: - AddIndexesThread(int64_t endTime, const IndexWriterPtr& writer, Collection dirs) - { - this->endTime = endTime; - this->writer = writer; - this->dirs = dirs; - } +namespace TestDuringAddIndexes { - virtual ~AddIndexesThread() - { - } +class AddIndexesThread : public LuceneThread { +public: + AddIndexesThread(int64_t endTime, const IndexWriterPtr& writer, Collection dirs) { + this->endTime = endTime; + this->writer = writer; + this->dirs = dirs; + } - LUCENE_CLASS(AddIndexesThread); - - protected: - int64_t endTime; - IndexWriterPtr writer; - Collection dirs; - - public: - virtual void run() - { - while ((int64_t)MiscUtils::currentTimeMillis() < endTime) - { - try - { - writer->addIndexesNoOptimize(dirs); - } - catch (LuceneException& e) - { - FAIL() << "Unexpected exception: " << e.getError(); - } + virtual ~AddIndexesThread() { + } + + LUCENE_CLASS(AddIndexesThread); + +protected: + int64_t endTime; + IndexWriterPtr writer; + Collection dirs; + +public: + virtual void run() { + while ((int64_t)MiscUtils::currentTimeMillis() < endTime) { + try { + writer->addIndexesNoOptimize(dirs); + } catch (LuceneException& e) { + FAIL() << "Unexpected exception: " << e.getError(); } } - }; + } +}; + } /// Stress test reopen during addIndexes -TEST_F(IndexWriterReaderTest, testDuringAddIndexes) -{ +TEST_F(IndexWriterReaderTest, testDuringAddIndexes) { MockRAMDirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMergeFactor(2); @@ -726,8 +678,9 @@ TEST_F(IndexWriterReaderTest, testDuringAddIndexes) writer->commit(); Collection dirs = Collection::newInstance(10); - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { dirs[i] = newLucene(dir1); + } IndexReaderPtr r = writer->getReader(); @@ -737,18 +690,15 @@ TEST_F(IndexWriterReaderTest, testDuringAddIndexes) int64_t endTime = MiscUtils::currentTimeMillis() + 1000 * SECONDS; Collection threads = Collection::newInstance(NUM_THREAD); - for (int32_t i = 0; i < NUM_THREAD; ++i) - { + for (int32_t i = 0; i < NUM_THREAD; ++i) { threads[i] = newLucene(endTime, writer, dirs); threads[i]->start(); } int32_t lastCount = 0; - while ((int64_t)MiscUtils::currentTimeMillis() < endTime) - { + while ((int64_t)MiscUtils::currentTimeMillis() < endTime) { IndexReaderPtr r2 = r->reopen(); - if (r2 != r) - { + if (r2 != r) { r->close(); r = r2; } @@ -758,8 +708,9 @@ TEST_F(IndexWriterReaderTest, testDuringAddIndexes) lastCount = count; } - for (int32_t i = 0; i < NUM_THREAD; ++i) + for (int32_t i = 0; i < NUM_THREAD; ++i) { threads[i]->join(); + } writer->close(); r->close(); @@ -769,59 +720,51 @@ TEST_F(IndexWriterReaderTest, testDuringAddIndexes) dir1->close(); } -namespace TestDuringAddDelete -{ - class AddDeleteThread : public LuceneThread - { - public: - AddDeleteThread(int64_t endTime, const IndexWriterPtr& writer) - { - this->endTime = endTime; - this->writer = writer; - this->random = newLucene(); - } +namespace TestDuringAddDelete { - virtual ~AddDeleteThread() - { - } +class AddDeleteThread : public LuceneThread { +public: + AddDeleteThread(int64_t endTime, const IndexWriterPtr& writer) { + this->endTime = endTime; + this->writer = writer; + this->random = newLucene(); + } - LUCENE_CLASS(AddDeleteThread); - - protected: - int64_t endTime; - IndexWriterPtr writer; - RandomPtr random; - - public: - virtual void run() - { - int32_t count = 0; - while ((int64_t)MiscUtils::currentTimeMillis() < endTime) - { - try - { - for (int32_t docUpto = 0; docUpto < 10; ++docUpto) - writer->addDocument(createDocument(10 * count + docUpto, L"test", 4)); - ++count; - int32_t limit = count * 10; - for (int32_t delUpto = 0; delUpto < 5;++delUpto) - { - int32_t x = random->nextInt(limit); - writer->deleteDocuments(newLucene(L"field3", L"b" + StringUtils::toString(x))); - } + virtual ~AddDeleteThread() { + } + + LUCENE_CLASS(AddDeleteThread); + +protected: + int64_t endTime; + IndexWriterPtr writer; + RandomPtr random; + +public: + virtual void run() { + int32_t count = 0; + while ((int64_t)MiscUtils::currentTimeMillis() < endTime) { + try { + for (int32_t docUpto = 0; docUpto < 10; ++docUpto) { + writer->addDocument(createDocument(10 * count + docUpto, L"test", 4)); } - catch (LuceneException& e) - { - FAIL() << "Unexpected exception: " << e.getError(); + ++count; + int32_t limit = count * 10; + for (int32_t delUpto = 0; delUpto < 5; ++delUpto) { + int32_t x = random->nextInt(limit); + writer->deleteDocuments(newLucene(L"field3", L"b" + StringUtils::toString(x))); } + } catch (LuceneException& e) { + FAIL() << "Unexpected exception: " << e.getError(); } } - }; + } +}; + } /// Stress test reopen during add/delete -TEST_F(IndexWriterReaderTest, testDuringAddDelete) -{ +TEST_F(IndexWriterReaderTest, testDuringAddDelete) { DirectoryPtr dir1 = newLucene(); IndexWriterPtr writer = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMergeFactor(2); @@ -838,18 +781,15 @@ TEST_F(IndexWriterReaderTest, testDuringAddDelete) int64_t endTime = MiscUtils::currentTimeMillis() + 1000 * SECONDS; Collection threads = Collection::newInstance(NUM_THREAD); - for (int32_t i = 0; i < NUM_THREAD; ++i) - { + for (int32_t i = 0; i < NUM_THREAD; ++i) { threads[i] = newLucene(endTime, writer); threads[i]->start(); } int32_t sum = 0; - while ((int64_t)MiscUtils::currentTimeMillis() < endTime) - { + while ((int64_t)MiscUtils::currentTimeMillis() < endTime) { IndexReaderPtr r2 = r->reopen(); - if (r2 != r) - { + if (r2 != r) { r->close(); r = r2; } @@ -857,8 +797,9 @@ TEST_F(IndexWriterReaderTest, testDuringAddDelete) sum += newLucene(r)->search(q, 10)->totalHits; } - for (int32_t i = 0; i < NUM_THREAD; ++i) + for (int32_t i = 0; i < NUM_THREAD; ++i) { threads[i]->join(); + } EXPECT_TRUE(sum > 0); @@ -869,8 +810,7 @@ TEST_F(IndexWriterReaderTest, testDuringAddDelete) dir1->close(); } -TEST_F(IndexWriterReaderTest, testExpungeDeletes) -{ +TEST_F(IndexWriterReaderTest, testExpungeDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -895,8 +835,7 @@ TEST_F(IndexWriterReaderTest, testExpungeDeletes) dir->close(); } -TEST_F(IndexWriterReaderTest, testDeletesNumDocs) -{ +TEST_F(IndexWriterReaderTest, testDeletesNumDocs) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -925,31 +864,28 @@ TEST_F(IndexWriterReaderTest, testDeletesNumDocs) dir->close(); } -namespace TestSegmentWarmer -{ - DECLARE_SHARED_PTR(SegmentWarmer) +namespace TestSegmentWarmer { - class SegmentWarmer : public IndexReaderWarmer - { - public: - virtual ~SegmentWarmer() - { - } +DECLARE_SHARED_PTR(SegmentWarmer) + +class SegmentWarmer : public IndexReaderWarmer { +public: + virtual ~SegmentWarmer() { + } - LUCENE_CLASS(SegmentWarmer); + LUCENE_CLASS(SegmentWarmer); + +public: + virtual void warm(const IndexReaderPtr& reader) { + IndexSearcherPtr s = newLucene(reader); + TopDocsPtr hits = s->search(newLucene(newLucene(L"foo", L"bar")), 10); + EXPECT_EQ(20, hits->totalHits); + } +}; - public: - virtual void warm(const IndexReaderPtr& reader) - { - IndexSearcherPtr s = newLucene(reader); - TopDocsPtr hits = s->search(newLucene(newLucene(L"foo", L"bar")), 10); - EXPECT_EQ(20, hits->totalHits); - } - }; } -TEST_F(IndexWriterReaderTest, testSegmentWarmer) -{ +TEST_F(IndexWriterReaderTest, testSegmentWarmer) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); w->setMaxBufferedDocs(2); @@ -959,8 +895,9 @@ TEST_F(IndexWriterReaderTest, testSegmentWarmer) DocumentPtr doc = newLucene(); doc->add(newLucene(L"foo", L"bar", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - for (int32_t i = 0; i < 20; ++i) + for (int32_t i = 0; i < 20; ++i) { w->addDocument(doc); + } w->waitForMerges(); w->close(); dir->close(); diff --git a/src/test/index/IndexWriterTest.cpp b/src/test/index/IndexWriterTest.cpp index 8779a0dd..6b6dacec 100644 --- a/src/test/index/IndexWriterTest.cpp +++ b/src/test/index/IndexWriterTest.cpp @@ -59,23 +59,20 @@ using namespace Lucene; typedef LuceneTestFixture IndexWriterTest; -static void addDoc(const IndexWriterPtr& writer) -{ +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void addDocWithIndex(const IndexWriterPtr& writer, int32_t index) -{ +static void addDocWithIndex(const IndexWriterPtr& writer, int32_t index) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa " + StringUtils::toString(index), Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", StringUtils::toString(index), Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void checkNoUnreferencedFiles(const DirectoryPtr& dir) -{ +static void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); infos->read(dir); @@ -98,30 +95,24 @@ DECLARE_SHARED_PTR(FailOnlyInWriteSegment) DECLARE_SHARED_PTR(FailOnlyInSync) DECLARE_SHARED_PTR(FailOnlyInCommit) -class FailOnlyOnFlush : public MockDirectoryFailure -{ +class FailOnlyOnFlush : public MockDirectoryFailure { public: - FailOnlyOnFlush() - { + FailOnlyOnFlush() { count = 0; TestPoint::clear(); } - virtual ~FailOnlyOnFlush() - { + virtual ~FailOnlyOnFlush() { } public: int32_t count; public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (this->doFail) - { + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (this->doFail) { if (TestPoint::getTestPoint(L"FreqProxTermsWriter", L"appendPostings") && - TestPoint::getTestPoint(L"doFlush") && count++ >= 30) - { + TestPoint::getTestPoint(L"doFlush") && count++ >= 30) { doFail = false; boost::throw_exception(IOException(L"now failing during flush")); } @@ -130,30 +121,25 @@ class FailOnlyOnFlush : public MockDirectoryFailure }; /// Throws IOException during FieldsWriter.flushDocument and during DocumentsWriter.abort -class FailOnlyOnAbortOrFlush : public MockDirectoryFailure -{ +class FailOnlyOnAbortOrFlush : public MockDirectoryFailure { public: - FailOnlyOnAbortOrFlush(bool onlyOnce) - { + FailOnlyOnAbortOrFlush(bool onlyOnce) { onlyOnce = false; } - virtual ~FailOnlyOnAbortOrFlush() - { + virtual ~FailOnlyOnAbortOrFlush() { } protected: bool onlyOnce; public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (doFail) - { - if (TestPoint::getTestPoint(L"abort") || TestPoint::getTestPoint(L"flushDocument")) - { - if (onlyOnce) + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (doFail) { + if (TestPoint::getTestPoint(L"abort") || TestPoint::getTestPoint(L"flushDocument")) { + if (onlyOnce) { doFail = false; + } boost::throw_exception(IOException(L"now failing on purpose")); } } @@ -161,30 +147,25 @@ class FailOnlyOnAbortOrFlush : public MockDirectoryFailure }; /// Throws IOException during DocumentsWriter.closeDocStore -class FailOnlyInCloseDocStore : public MockDirectoryFailure -{ +class FailOnlyInCloseDocStore : public MockDirectoryFailure { public: - FailOnlyInCloseDocStore(bool onlyOnce) - { + FailOnlyInCloseDocStore(bool onlyOnce) { onlyOnce = false; } - virtual ~FailOnlyInCloseDocStore() - { + virtual ~FailOnlyInCloseDocStore() { } protected: bool onlyOnce; public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (doFail) - { - if (TestPoint::getTestPoint(L"closeDocStore")) - { - if (onlyOnce) + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (doFail) { + if (TestPoint::getTestPoint(L"closeDocStore")) { + if (onlyOnce) { doFail = false; + } boost::throw_exception(IOException(L"now failing on purpose")); } } @@ -192,30 +173,25 @@ class FailOnlyInCloseDocStore : public MockDirectoryFailure }; /// Throws IOException during DocumentsWriter.writeSegment -class FailOnlyInWriteSegment : public MockDirectoryFailure -{ +class FailOnlyInWriteSegment : public MockDirectoryFailure { public: - FailOnlyInWriteSegment(bool onlyOnce) - { + FailOnlyInWriteSegment(bool onlyOnce) { onlyOnce = false; } - virtual ~FailOnlyInWriteSegment() - { + virtual ~FailOnlyInWriteSegment() { } protected: bool onlyOnce; public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (doFail) - { - if (TestPoint::getTestPoint(L"DocFieldProcessor", L"flush")) - { - if (onlyOnce) + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (doFail) { + if (TestPoint::getTestPoint(L"DocFieldProcessor", L"flush")) { + if (onlyOnce) { doFail = false; + } boost::throw_exception(IOException(L"now failing on purpose")); } } @@ -223,28 +199,22 @@ class FailOnlyInWriteSegment : public MockDirectoryFailure }; /// Throws IOException during MockRAMDirectory.sync -class FailOnlyInSync : public MockDirectoryFailure -{ +class FailOnlyInSync : public MockDirectoryFailure { public: - FailOnlyInSync() - { + FailOnlyInSync() { didFail = false; } - virtual ~FailOnlyInSync() - { + virtual ~FailOnlyInSync() { } public: bool didFail; public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (doFail) - { - if (TestPoint::getTestPoint(L"MockRAMDirectory", L"sync")) - { + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (doFail) { + if (TestPoint::getTestPoint(L"MockRAMDirectory", L"sync")) { didFail = true; boost::throw_exception(IOException(L"now failing on purpose during sync")); } @@ -252,17 +222,14 @@ class FailOnlyInSync : public MockDirectoryFailure } }; -class FailOnlyInCommit : public MockDirectoryFailure -{ +class FailOnlyInCommit : public MockDirectoryFailure { public: - FailOnlyInCommit() - { + FailOnlyInCommit() { fail1 = false; fail2 = false; } - virtual ~FailOnlyInCommit() - { + virtual ~FailOnlyInCommit() { } public: @@ -270,20 +237,15 @@ class FailOnlyInCommit : public MockDirectoryFailure bool fail2; public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { + virtual void eval(const MockRAMDirectoryPtr& dir) { bool isCommit = TestPoint::getTestPoint(L"SegmentInfos", L"prepareCommit"); bool isDelete = TestPoint::getTestPoint(L"MockRAMDirectory", L"deleteFile"); - if (isCommit) - { - if (!isDelete) - { + if (isCommit) { + if (!isDelete) { fail1 = true; boost::throw_exception(RuntimeException(L"now fail first")); - } - else - { + } else { fail2 = true; boost::throw_exception(IOException(L"now fail during delete")); } @@ -291,17 +253,14 @@ class FailOnlyInCommit : public MockDirectoryFailure } }; -class CrashingFilter : public TokenFilter -{ +class CrashingFilter : public TokenFilter { public: - CrashingFilter(const String& fieldName, const TokenStreamPtr& input) : TokenFilter(input) - { + CrashingFilter(const String& fieldName, const TokenStreamPtr& input) : TokenFilter(input) { this->count = 0; this->fieldName = fieldName; } - virtual ~CrashingFilter() - { + virtual ~CrashingFilter() { } LUCENE_CLASS(CrashingFilter); @@ -311,15 +270,14 @@ class CrashingFilter : public TokenFilter int32_t count; public: - virtual bool incrementToken() - { - if (fieldName == L"crash" && count++ >= 4) + virtual bool incrementToken() { + if (fieldName == L"crash" && count++ >= 4) { boost::throw_exception(IOException(L"now failing on purpose")); + } return input->incrementToken(); } - virtual void reset() - { + virtual void reset() { TokenFilter::reset(); count = 0; } @@ -327,18 +285,15 @@ class CrashingFilter : public TokenFilter DECLARE_SHARED_PTR(IndexerThread) -class IndexerThread : public LuceneThread -{ +class IndexerThread : public LuceneThread { public: - IndexerThread(const IndexWriterPtr& writer, bool noErrors) - { + IndexerThread(const IndexWriterPtr& writer, bool noErrors) { this->writer = writer; this->noErrors = noErrors; this->addCount = 0; } - virtual ~IndexerThread() - { + virtual ~IndexerThread() { } LUCENE_CLASS(IndexerThread); @@ -349,8 +304,7 @@ class IndexerThread : public LuceneThread int32_t addCount; public: - virtual void run() - { + virtual void run() { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa bbb ccc ddd eee fff ggg hhh iii jjj", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); @@ -358,32 +312,26 @@ class IndexerThread : public LuceneThread int32_t fullCount = 0; int64_t stopTime = MiscUtils::currentTimeMillis() + 500; - while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) - { - try - { + while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) { + try { writer->updateDocument(newLucene(L"id", StringUtils::toString(idUpto++)), doc); ++addCount; - } - catch (IOException& e) - { - if (boost::starts_with(e.getError(), L"fake disk full at") || e.getError() == L"now failing on purpose") - { + } catch (IOException& e) { + if (boost::starts_with(e.getError(), L"fake disk full at") || e.getError() == L"now failing on purpose") { LuceneThread::threadSleep(1); - if (fullCount++ >= 5) + if (fullCount++ >= 5) { break; - } - else - { - if (noErrors) + } + } else { + if (noErrors) { FAIL() << "Unexpected exception"; + } break; } - } - catch (...) - { - if (noErrors) + } catch (...) { + if (noErrors) { FAIL() << "Unexpected exception"; + } break; } } @@ -393,8 +341,7 @@ class IndexerThread : public LuceneThread DECLARE_SHARED_PTR(RunAddIndexesThreads) DECLARE_SHARED_PTR(RunAddThread) -class RunAddIndexesThreads : public LuceneObject -{ +class RunAddIndexesThreads : public LuceneObject { public: RunAddIndexesThreads(int32_t numCopy); virtual ~RunAddIndexesThreads(); @@ -428,19 +375,16 @@ class RunAddIndexesThreads : public LuceneObject const int32_t RunAddIndexesThreads::NUM_INIT_DOCS = 17; const int32_t RunAddIndexesThreads::NUM_THREADS = 5; -class RunAddThread : public LuceneThread -{ +class RunAddThread : public LuceneThread { public: - RunAddThread(const RunAddIndexesThreadsPtr& runAdd, int32_t numIter, int32_t numCopy, const DirectoryPtr& dir) - { + RunAddThread(const RunAddIndexesThreadsPtr& runAdd, int32_t numIter, int32_t numCopy, const DirectoryPtr& dir) { this->_runAdd = runAdd; this->numIter = numIter; this->numCopy = numCopy; this->dir = dir; } - virtual ~RunAddThread() - { + virtual ~RunAddThread() { } protected: @@ -450,32 +394,28 @@ class RunAddThread : public LuceneThread DirectoryPtr dir; public: - virtual void run() - { - try - { + virtual void run() { + try { Collection dirs = Collection::newInstance(numCopy); - for (int32_t k = 0; k < numCopy; ++k) + for (int32_t k = 0; k < numCopy; ++k) { dirs[k] = newLucene(dir); + } int32_t j = 0; - while (true) - { - if (numIter > 0 && j == numIter) + while (true) { + if (numIter > 0 && j == numIter) { break; + } RunAddIndexesThreadsPtr(_runAdd)->doBody(j++, dirs); } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { RunAddIndexesThreadsPtr(_runAdd)->handle(e); } } }; -RunAddIndexesThreads::RunAddIndexesThreads(int32_t numCopy) -{ +RunAddIndexesThreads::RunAddIndexesThreads(int32_t numCopy) { threads = Collection::newInstance(NUM_THREADS); didClose = false; NUM_COPY = numCopy; @@ -483,8 +423,9 @@ RunAddIndexesThreads::RunAddIndexesThreads(int32_t numCopy) IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t i = 0; i < NUM_INIT_DOCS; ++i) + for (int32_t i = 0; i < NUM_INIT_DOCS; ++i) { addDoc(writer); + } writer->close(); @@ -493,43 +434,42 @@ RunAddIndexesThreads::RunAddIndexesThreads(int32_t numCopy) cms = boost::dynamic_pointer_cast(writer2->getMergeScheduler()); readers = Collection::newInstance(NUM_COPY); - for (int32_t i = 0; i < NUM_COPY; ++i) + for (int32_t i = 0; i < NUM_COPY; ++i) { readers[i] = IndexReader::open(dir, true); + } } -RunAddIndexesThreads::~RunAddIndexesThreads() -{ +RunAddIndexesThreads::~RunAddIndexesThreads() { } -void RunAddIndexesThreads::launchThreads(int32_t numIter) -{ - for (int32_t i = 0; i < NUM_THREADS; ++i) +void RunAddIndexesThreads::launchThreads(int32_t numIter) { + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i] = newLucene(shared_from_this(), numIter, NUM_COPY, dir); - for (int32_t i = 0; i < NUM_THREADS; ++i) + } + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->start(); + } } -void RunAddIndexesThreads::joinThreads() -{ - for (int32_t i = 0; i < NUM_THREADS; ++i) +void RunAddIndexesThreads::joinThreads() { + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); + } } -void RunAddIndexesThreads::close(bool doWait) -{ +void RunAddIndexesThreads::close(bool doWait) { didClose = true; writer2->close(doWait); } -void RunAddIndexesThreads::closeDir() -{ - for (int32_t i = 0; i < NUM_COPY; ++i) +void RunAddIndexesThreads::closeDir() { + for (int32_t i = 0; i < NUM_COPY; ++i) { readers[i]->close(); + } dir2->close(); } -TEST_F(IndexWriterTest, testDocCount) -{ +TEST_F(IndexWriterTest, testDocCount) { DirectoryPtr dir = newLucene(); IndexWriter::setDefaultWriteLockTimeout(2000); @@ -540,15 +480,17 @@ TEST_F(IndexWriterTest, testDocCount) IndexWriter::setDefaultWriteLockTimeout(1000); // add 100 documents - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } EXPECT_EQ(100, writer->maxDoc()); writer->close(); // delete 40 documents IndexReaderPtr reader = IndexReader::open(dir, false); - for (int32_t i = 0; i < 40; ++i) + for (int32_t i = 0; i < 40; ++i) { reader->deleteDocument(i); + } reader->close(); // test doc count before segments are merged/index is optimized @@ -586,8 +528,7 @@ TEST_F(IndexWriterTest, testDocCount) /// Test: make sure when we run out of disk space or hit random IOExceptions in any of the addIndexesNoOptimize(*) calls /// that 1) index is not corrupt (searcher can open/search it) and 2) transactional semantics are followed: /// either all or none of the incoming documents were in fact added. -TEST_F(IndexWriterTest, testAddIndexOnDiskFull) -{ +TEST_F(IndexWriterTest, testAddIndexOnDiskFull) { int32_t START_COUNT = 57; int32_t NUM_DIR = 50; int32_t END_COUNT = START_COUNT + NUM_DIR * 25; @@ -595,23 +536,25 @@ TEST_F(IndexWriterTest, testAddIndexOnDiskFull) // Build up a bunch of dirs that have indexes which we will then merge together by calling addIndexesNoOptimize(*) Collection dirs = Collection::newInstance(NUM_DIR); int64_t inputDiskUsage = 0; - for (int32_t i = 0; i < NUM_DIR; ++i) - { + for (int32_t i = 0; i < NUM_DIR; ++i) { dirs[i] = newLucene(); IndexWriterPtr writer = newLucene(dirs[i], newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t j = 0; j < 25; ++j) + for (int32_t j = 0; j < 25; ++j) { addDocWithIndex(writer, 25 * i + j); + } writer->close(); HashSet files = dirs[i]->listAll(); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { inputDiskUsage += dirs[i]->fileLength(*file); + } } // Now, build a starting index that has START_COUNT docs. We will then try to addIndexesNoOptimize into a copy of this RAMDirectoryPtr startDir = newLucene(); IndexWriterPtr writer = newLucene(startDir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t j = 0; j < START_COUNT; ++j) + for (int32_t j = 0; j < START_COUNT; ++j) { addDocWithIndex(writer, j); + } writer->close(); // Make sure starting index seems to be working properly @@ -635,11 +578,11 @@ TEST_F(IndexWriterTest, testAddIndexOnDiskFull) int64_t startDiskUsage = 0; HashSet files = startDir->listAll(); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { startDiskUsage += startDir->fileLength(*file); + } - for (int32_t iter = 0; iter < 3; ++iter) - { + for (int32_t iter = 0; iter < 3; ++iter) { // std::cout << "TEST: iter=" << iter; // Start with 100 bytes more than we are currently using: @@ -650,30 +593,29 @@ TEST_F(IndexWriterTest, testAddIndexOnDiskFull) bool done = false; String methodName; - if (method == 0) + if (method == 0) { methodName = L"addIndexes(Directory[]) + optimize()"; - else if (method == 1) + } else if (method == 1) { methodName = L"addIndexes(IndexReader[])"; - else + } else { methodName = L"addIndexesNoOptimize(Directory[])"; + } - while (!done) - { + while (!done) { // Make a new dir that will enforce disk usage MockRAMDirectoryPtr dir = newLucene(startDir); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthUNLIMITED); MergeSchedulerPtr ms = writer->getMergeScheduler(); - for (int32_t x = 0; x < 2; ++x) - { - if (MiscUtils::typeOf(ms)) - { + for (int32_t x = 0; x < 2; ++x) { + if (MiscUtils::typeOf(ms)) { // This test intentionally produces exceptions in the threads that CMS launches; we don't // want to pollute test output with these. - if (x == 0) + if (x == 0) { boost::dynamic_pointer_cast(ms)->setSuppressExceptions(); - else + } else { boost::dynamic_pointer_cast(ms)->clearSuppressExceptions(); + } } // Two loops: first time, limit disk space and throw random IOExceptions; second time, no disk space limit @@ -683,19 +625,19 @@ TEST_F(IndexWriterTest, testAddIndexOnDiskFull) String testName; - if (x == 0) - { + if (x == 0) { thisDiskFree = diskFree; - if (diskRatio >= 2.0) + if (diskRatio >= 2.0) { rate /= 2; - if (diskRatio >= 4.0) + } + if (diskRatio >= 4.0) { rate /= 2; - if (diskRatio >= 6.0) + } + if (diskRatio >= 6.0) { rate = 0.0; + } testName = L"disk full test " + methodName + L" with disk full at " + StringUtils::toString(diskFree) + L" bytes"; - } - else - { + } else { thisDiskFree = 0; rate = 0.0; testName = L"disk full test " + methodName + L" with unlimited disk space"; @@ -706,47 +648,42 @@ TEST_F(IndexWriterTest, testAddIndexOnDiskFull) dir->setMaxSizeInBytes(thisDiskFree); dir->setRandomIOExceptionRate(rate, diskFree); - try - { - if (method == 0) - { + try { + if (method == 0) { writer->addIndexesNoOptimize(dirs); writer->optimize(); - } - else if (method == 1) - { + } else if (method == 1) { Collection readers = Collection::newInstance(dirs.size()); - for (int32_t i = 0; i < dirs.size(); ++i) + for (int32_t i = 0; i < dirs.size(); ++i) { readers[i] = IndexReader::open(dirs[i], true); + } LuceneException finally; - try - { + try { writer->addIndexes(readers); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } - for (int32_t i = 0; i < dirs.size(); ++i) + for (int32_t i = 0; i < dirs.size(); ++i) { readers[i]->close(); + } finally.throwException(); - } - else + } else { writer->addIndexesNoOptimize(dirs); + } success = true; // std::cout << " success!"; - if (x == 0) + if (x == 0) { done = true; - } - catch (IOException& e) - { + } + } catch (IOException& e) { success = false; // std::cout << " hit IOException: " << e.getError(); - if (x == 1) + if (x == 1) { FAIL() << methodName << " hit IOException after disk space was freed up"; + } } // Make sure all threads from ConcurrentMergeScheduler are done @@ -756,61 +693,53 @@ TEST_F(IndexWriterTest, testAddIndexOnDiskFull) // Finally, verify index is not corrupt, and, if we succeeded, we see all docs added, and if we // failed, we see either all docs or no docs added (transactional semantics) - try - { + try { reader = IndexReader::open(dir, true); - } - catch (IOException& e) - { + } catch (IOException& e) { FAIL() << testName << ": exception when creating IndexReader: " << e.getError(); } int32_t result = reader->docFreq(searchTerm); - if (success) - { - if (result != START_COUNT) + if (success) { + if (result != START_COUNT) { FAIL() << testName << ": method did not throw exception but docFreq('aaa') is " << result << " instead of expected " << START_COUNT; - } - else - { + } + } else { // On hitting exception we still may have added all docs - if (result != START_COUNT && result != END_COUNT) + if (result != START_COUNT && result != END_COUNT) { FAIL() << testName << ": method did throw exception but docFreq('aaa') is " << result << " instead of expected " << START_COUNT << " or " << END_COUNT; + } } searcher = newLucene(reader); - try - { + try { hits = searcher->search(newLucene(searchTerm), FilterPtr(), END_COUNT)->scoreDocs; - } - catch (IOException& e) - { + } catch (IOException& e) { FAIL() << testName << ": exception when searching: " << e.getError(); } int32_t result2 = hits.size(); - if (success) - { - if (result2 != result) + if (success) { + if (result2 != result) { FAIL() << testName << ": method did not throw exception but hits.length for search on term 'aaa' is " << result2 << " instead of expected " << result; - } - else - { + } + } else { // On hitting exception we still may have added all docs - if (result2 != result) + if (result2 != result) { FAIL() << testName << ": method did throw exception but hits.length for search on term 'aaa' is " << result2 << " instead of expected " << result; + } } searcher->close(); reader->close(); // std::cout << " count is " << result; - if (done || result == END_COUNT) + if (done || result == END_COUNT) { break; + } } // std::cout << " start disk = " << startDiskUsage << "; input disk = " << inputDiskUsage << "; max used = " << dir->getMaxUsedSizeInBytes(); - if (done) - { + if (done) { // Make sure that temp free Directory space required is at most 3X total input size of indices EXPECT_TRUE((dir->getMaxUsedSizeInBytes() - startDiskUsage) < 3 * (startDiskUsage + inputDiskUsage)); } @@ -835,48 +764,39 @@ TEST_F(IndexWriterTest, testAddIndexOnDiskFull) } /// Make sure IndexWriter cleans up on hitting a disk full exception in addDocument. -TEST_F(IndexWriterTest, testAddDocumentOnDiskFull) -{ - for (int32_t pass = 0; pass < 2; ++pass) - { +TEST_F(IndexWriterTest, testAddDocumentOnDiskFull) { + for (int32_t pass = 0; pass < 2; ++pass) { // std::cout << "TEST: pass=" << pass; bool doAbort = (pass == 1); int64_t diskFree = 200; - while (true) - { + while (true) { // std::cout << "TEST: cycle: diskFree=" << diskFree; MockRAMDirectoryPtr dir = newLucene(); dir->setMaxSizeInBytes(diskFree); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); MergeSchedulerPtr ms = writer->getMergeScheduler(); - if (MiscUtils::typeOf(ms)) + if (MiscUtils::typeOf(ms)) { boost::dynamic_pointer_cast(ms)->setSuppressExceptions(); + } bool hitError = false; - try - { - for (int32_t i = 0; i < 200; ++i) + try { + for (int32_t i = 0; i < 200; ++i) { addDoc(writer); - } - catch (IOException&) - { + } + } catch (IOException&) { // std::cout << "TEST: exception on addDoc"; hitError = true; } - if (hitError) - { - if (doAbort) + if (hitError) { + if (doAbort) { writer->rollback(); - else - { - try - { + } else { + try { writer->close(); - } - catch (IOException&) - { + } catch (IOException&) { // std::cout << "TEST: exception on close"; dir->setMaxSizeInBytes(0); writer->close(); @@ -894,9 +814,7 @@ TEST_F(IndexWriterTest, testAddDocumentOnDiskFull) // Now try again with more space diskFree += 500; - } - else - { + } else { syncConcurrentMerges(writer); dir->close(); break; @@ -906,8 +824,7 @@ TEST_F(IndexWriterTest, testAddDocumentOnDiskFull) } /// Make sure we skip wicked long terms. -TEST_F(IndexWriterTest, testWickedLongTerm) -{ +TEST_F(IndexWriterTest, testWickedLongTerm) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -959,23 +876,22 @@ TEST_F(IndexWriterTest, testWickedLongTerm) dir->close(); } -TEST_F(IndexWriterTest, testOptimizeMaxNumSegments) -{ +TEST_F(IndexWriterTest, testOptimizeMaxNumSegments) { MockRAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED)); - for (int32_t numDocs = 38; numDocs < 500; numDocs += 38) - { + for (int32_t numDocs = 38; numDocs < 500; numDocs += 38) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); LogDocMergePolicyPtr ldmp = newLucene(writer); ldmp->setMinMergeDocs(1); writer->setMergePolicy(ldmp); writer->setMergeFactor(5); writer->setMaxBufferedDocs(2); - for (int32_t j = 0; j addDocument(doc); + } writer->close(); SegmentInfosPtr sis = newLucene(); @@ -992,15 +908,15 @@ TEST_F(IndexWriterTest, testOptimizeMaxNumSegments) sis->read(dir); int32_t optSegCount = sis->size(); - if (segCount < 3) + if (segCount < 3) { EXPECT_EQ(segCount, optSegCount); - else + } else { EXPECT_EQ(3, optSegCount); + } } } -TEST_F(IndexWriterTest, testOptimizeMaxNumSegments2) -{ +TEST_F(IndexWriterTest, testOptimizeMaxNumSegments2) { MockRAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); @@ -1013,10 +929,10 @@ TEST_F(IndexWriterTest, testOptimizeMaxNumSegments2) writer->setMergeFactor(4); writer->setMaxBufferedDocs(2); - for (int32_t iter = 0; iter < 10; ++iter) - { - for (int32_t i = 0; i < 19; ++i) + for (int32_t iter = 0; iter < 10; ++iter) { + for (int32_t i = 0; i < 19; ++i) { writer->addDocument(doc); + } writer->commit(); writer->waitForMerges(); @@ -1035,20 +951,21 @@ TEST_F(IndexWriterTest, testOptimizeMaxNumSegments2) sis->read(dir); int32_t optSegCount = sis->size(); - if (segCount < 7) + if (segCount < 7) { EXPECT_EQ(segCount, optSegCount); - else + } else { EXPECT_EQ(7, optSegCount); + } } } /// Make sure optimize doesn't use any more than 1X starting index size as its temporary free space required. -TEST_F(IndexWriterTest, testOptimizeTempSpaceUsage) -{ +TEST_F(IndexWriterTest, testOptimizeTempSpaceUsage) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t j = 0; j < 500; ++j) + for (int32_t j = 0; j < 500; ++j) { addDocWithIndex(writer, j); + } // force one extra segment w/ different doc store so we see the doc stores get merged writer->commit(); @@ -1058,8 +975,9 @@ TEST_F(IndexWriterTest, testOptimizeTempSpaceUsage) int64_t startDiskUsage = 0; HashSet files = dir->listAll(); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { startDiskUsage += dir->fileLength(*file); + } dir->resetMaxUsedSizeInBytes(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); @@ -1073,13 +991,11 @@ TEST_F(IndexWriterTest, testOptimizeTempSpaceUsage) } /// Make sure we can open an index for create even when a reader holds it open (this fails pre lock-less commits on windows) -TEST_F(IndexWriterTest, testCreateWithReader) -{ +TEST_F(IndexWriterTest, testCreateWithReader) { String indexDir(FileUtils::joinPath(getTempDir(), L"lucenetestindexwriter")); LuceneException finally; - try - { + try { DirectoryPtr dir = FSDirectory::open(indexDir); // add one document and close writer @@ -1102,28 +1018,27 @@ TEST_F(IndexWriterTest, testCreateWithReader) EXPECT_EQ(reader2->numDocs(), 1); reader->close(); reader2->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } FileUtils::removeDirectory(indexDir); - if (!finally.isNull()) + if (!finally.isNull()) { FAIL() << finally.getError(); + } } /// Simulate a writer that crashed while writing segments file: make sure we can still open the index (ie, /// gracefully fallback to the previous segments file), and that we can add to the index -TEST_F(IndexWriterTest, testSimulatedCrashedWriter) -{ +TEST_F(IndexWriterTest, testSimulatedCrashedWriter) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 100 documents - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } writer->close(); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); @@ -1136,8 +1051,9 @@ TEST_F(IndexWriterTest, testSimulatedCrashedWriter) IndexInputPtr in = dir->openInput(fileNameIn); IndexOutputPtr out = dir->createOutput(fileNameOut); int64_t length = in->length(); - for (int32_t i = 0; i < length - 1; ++i) + for (int32_t i = 0; i < length - 1; ++i) { out->writeByte(in->readByte()); + } in->close(); out->close(); @@ -1148,22 +1064,23 @@ TEST_F(IndexWriterTest, testSimulatedCrashedWriter) EXPECT_NO_THROW(writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); // add 100 documents - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } writer->close(); } /// Simulate a corrupt index by removing last byte of latest segments file and make sure we get an /// IOException trying to open the index -TEST_F(IndexWriterTest, testSimulatedCorruptIndex1) -{ +TEST_F(IndexWriterTest, testSimulatedCorruptIndex1) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 100 documents - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } writer->close(); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); @@ -1174,28 +1091,26 @@ TEST_F(IndexWriterTest, testSimulatedCorruptIndex1) IndexInputPtr in = dir->openInput(fileNameIn); IndexOutputPtr out = dir->createOutput(fileNameOut); int64_t length = in->length(); - for (int32_t i = 0; i < length - 1; ++i) + for (int32_t i = 0; i < length - 1; ++i) { out->writeByte(in->readByte()); + } in->close(); out->close(); dir->deleteFile(fileNameIn); IndexReaderPtr reader; - try - { + try { reader = IndexReader::open(dir, true); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } - if (reader) + if (reader) { reader->close(); + } } -TEST_F(IndexWriterTest, testChangesAfterClose) -{ +TEST_F(IndexWriterTest, testChangesAfterClose) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1203,64 +1118,57 @@ TEST_F(IndexWriterTest, testChangesAfterClose) addDoc(writer); writer->close(); - try - { + try { addDoc(writer); - } - catch (AlreadyClosedException& e) - { + } catch (AlreadyClosedException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } } /// Simulate a corrupt index by removing one of the cfs files and make sure we get an IOException trying to open the index -TEST_F(IndexWriterTest, testSimulatedCorruptIndex2) -{ +TEST_F(IndexWriterTest, testSimulatedCorruptIndex2) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 100 documents - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } writer->close(); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); EXPECT_TRUE(gen > 1); HashSet files = dir->listAll(); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - { - if (boost::ends_with(*file, L".cfs")) - { + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { + if (boost::ends_with(*file, L".cfs")) { dir->deleteFile(*file); break; } } IndexReaderPtr reader; - try - { + try { reader = IndexReader::open(dir, true); - } - catch (FileNotFoundException& e) - { + } catch (FileNotFoundException& e) { EXPECT_TRUE(check_exception(LuceneException::FileNotFound)(e)); } - if (reader) + if (reader) { reader->close(); + } } /// Simple test for "commit on close": open writer then add a bunch of docs, making sure reader does /// not see these docs until writer is closed. -TEST_F(IndexWriterTest, testCommitOnClose) -{ +TEST_F(IndexWriterTest, testCommitOnClose) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 14; ++i) + for (int32_t i = 0; i < 14; ++i) { addDoc(writer); + } writer->close(); TermPtr searchTerm = newLucene(L"content", L"aaa"); @@ -1272,10 +1180,10 @@ TEST_F(IndexWriterTest, testCommitOnClose) IndexReaderPtr reader = IndexReader::open(dir, true); writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 3; ++i) - { - for (int32_t j = 0; j < 11; ++j) + for (int32_t i = 0; i < 3; ++i) { + for (int32_t j = 0; j < 11; ++j) { addDoc(writer); + } searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(14, hits.size()); @@ -1293,14 +1201,14 @@ TEST_F(IndexWriterTest, testCommitOnClose) searcher->close(); } -TEST_F(IndexWriterTest, testCommitOnCloseAbort) -{ +TEST_F(IndexWriterTest, testCommitOnCloseAbort) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - for (int32_t i = 0; i < 14; ++i) + for (int32_t i = 0; i < 14; ++i) { addDoc(writer); + } writer->close(); TermPtr searchTerm = newLucene(L"content", L"aaa"); @@ -1311,8 +1219,9 @@ TEST_F(IndexWriterTest, testCommitOnCloseAbort) writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - for (int32_t i = 0; i < 17; ++i) + for (int32_t i = 0; i < 17; ++i) { addDoc(writer); + } // Delete all docs writer->deleteDocuments(searchTerm); @@ -1339,10 +1248,10 @@ TEST_F(IndexWriterTest, testCommitOnCloseAbort) // On abort, writer in fact may write to the same segments_N file dir->setPreventDoubleWrite(false); - for (int32_t i = 0; i < 12; ++i) - { - for (int32_t j = 0; j < 17; ++j) + for (int32_t i = 0; i < 12; ++i) { + for (int32_t j = 0; j < 17; ++j) { addDoc(writer); + } searcher = newLucene(dir, false); hits = searcher->search(newLucene(searchTerm), FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(14, hits.size()); @@ -1361,14 +1270,14 @@ TEST_F(IndexWriterTest, testCommitOnCloseAbort) /// Verify that a writer with "commit on close" indeed cleans up the temp segments created after opening /// that are not referenced by the starting segments file. We check this by using MockRAMDirectory to /// measure max temp disk space used. -TEST_F(IndexWriterTest, testCommitOnCloseDiskUsage) -{ +TEST_F(IndexWriterTest, testCommitOnCloseDiskUsage) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - for (int32_t j = 0; j < 30; ++j) + for (int32_t j = 0; j < 30; ++j) { addDocWithIndex(writer, j); + } writer->close(); dir->resetMaxUsedSizeInBytes(); @@ -1376,8 +1285,9 @@ TEST_F(IndexWriterTest, testCommitOnCloseDiskUsage) writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); writer->setMergeScheduler(newLucene()); - for (int32_t j = 0; j < 1470; ++j) + for (int32_t j = 0; j < 1470; ++j) { addDocWithIndex(writer, j); + } int64_t midDiskUsage = dir->getMaxUsedSizeInBytes(); dir->resetMaxUsedSizeInBytes(); writer->optimize(); @@ -1396,13 +1306,13 @@ TEST_F(IndexWriterTest, testCommitOnCloseDiskUsage) /// Verify that calling optimize when writer is open for "commit on close" works correctly both for /// rollback() and close(). -TEST_F(IndexWriterTest, testCommitOnCloseOptimize) -{ +TEST_F(IndexWriterTest, testCommitOnCloseOptimize) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { addDocWithIndex(writer, j); + } writer->close(); writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); @@ -1439,8 +1349,7 @@ TEST_F(IndexWriterTest, testCommitOnCloseOptimize) reader->close(); } -TEST_F(IndexWriterTest, testIndexNoDocuments) -{ +TEST_F(IndexWriterTest, testIndexNoDocuments) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->commit(); @@ -1461,13 +1370,11 @@ TEST_F(IndexWriterTest, testIndexNoDocuments) reader->close(); } -TEST_F(IndexWriterTest, testManyFields) -{ +TEST_F(IndexWriterTest, testManyFields) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - for (int32_t j = 0; j < 100; ++j) - { + for (int32_t j = 0; j < 100; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"a" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(L"b" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -1483,8 +1390,7 @@ TEST_F(IndexWriterTest, testManyFields) EXPECT_EQ(100, reader->maxDoc()); EXPECT_EQ(100, reader->numDocs()); - for (int32_t j = 0; j < 100; ++j) - { + for (int32_t j = 0; j < 100; ++j) { EXPECT_EQ(1, reader->docFreq(newLucene(L"a" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); EXPECT_EQ(1, reader->docFreq(newLucene(L"b" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); EXPECT_EQ(1, reader->docFreq(newLucene(L"c" + StringUtils::toString(j), L"aaa" + StringUtils::toString(j)))); @@ -1496,14 +1402,12 @@ TEST_F(IndexWriterTest, testManyFields) dir->close(); } -TEST_F(IndexWriterTest, testSmallRAMBuffer) -{ +TEST_F(IndexWriterTest, testSmallRAMBuffer) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setRAMBufferSizeMB(0.000001); int32_t lastNumFile = dir->listAll().size(); - for (int32_t j = 0; j < 9; ++j) - { + for (int32_t j = 0; j < 9; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -1517,187 +1421,149 @@ TEST_F(IndexWriterTest, testSmallRAMBuffer) } /// Make sure it's OK to change RAM buffer size and maxBufferedDocs in a write session -TEST_F(IndexWriterTest, testChangingRAMBuffer) -{ +TEST_F(IndexWriterTest, testChangingRAMBuffer) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); int32_t lastFlushCount = -1; - for (int32_t j = 1; j < 52; ++j) - { + for (int32_t j = 1; j < 52; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); syncConcurrentMerges(writer); int32_t flushCount = writer->getFlushCount(); - if (j == 1) + if (j == 1) { lastFlushCount = flushCount; - else if (j < 10) - { + } else if (j < 10) { // No new files should be created EXPECT_EQ(flushCount, lastFlushCount); - } - else if (j == 10) - { + } else if (j == 10) { EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; writer->setRAMBufferSizeMB(0.000001); writer->setMaxBufferedDocs(IndexWriter::DISABLE_AUTO_FLUSH); - } - else if (j < 20) - { + } else if (j < 20) { EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; - } - else if (j == 20) - { + } else if (j == 20) { writer->setRAMBufferSizeMB(16); writer->setMaxBufferedDocs(IndexWriter::DISABLE_AUTO_FLUSH); lastFlushCount = flushCount; - } - else if (j < 30) + } else if (j < 30) { EXPECT_EQ(flushCount, lastFlushCount); - else if (j == 30) - { + } else if (j == 30) { writer->setRAMBufferSizeMB(0.000001); writer->setMaxBufferedDocs(IndexWriter::DISABLE_AUTO_FLUSH); - } - else if (j < 40) - { + } else if (j < 40) { EXPECT_TRUE(flushCount> lastFlushCount); lastFlushCount = flushCount; - } - else if (j == 40) - { + } else if (j == 40) { writer->setMaxBufferedDocs(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); lastFlushCount = flushCount; - } - else if (j < 50) - { + } else if (j < 50) { EXPECT_EQ(flushCount, lastFlushCount); writer->setMaxBufferedDocs(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - } - else if (j == 50) + } else if (j == 50) { EXPECT_TRUE(flushCount > lastFlushCount); + } } writer->close(); dir->close(); } -TEST_F(IndexWriterTest, testChangingRAMBuffer2) -{ +TEST_F(IndexWriterTest, testChangingRAMBuffer2) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); writer->setMaxBufferedDeleteTerms(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - for (int32_t j = 1; j < 52; ++j) - { + for (int32_t j = 1; j < 52; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa" + StringUtils::toString(j), Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } int32_t lastFlushCount = -1; - for (int32_t j = 1; j < 52; ++j) - { + for (int32_t j = 1; j < 52; ++j) { writer->deleteDocuments(newLucene(L"field", L"aaa" + StringUtils::toString(j))); syncConcurrentMerges(writer); int32_t flushCount = writer->getFlushCount(); - if (j == 1) + if (j == 1) { lastFlushCount = flushCount; - else if (j < 10) - { + } else if (j < 10) { // No new files should be created EXPECT_EQ(flushCount, lastFlushCount); - } - else if (j == 10) - { + } else if (j == 10) { EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; writer->setRAMBufferSizeMB(0.000001); writer->setMaxBufferedDeleteTerms(1); - } - else if (j < 20) - { + } else if (j < 20) { EXPECT_TRUE(flushCount > lastFlushCount); lastFlushCount = flushCount; - } - else if (j == 20) - { + } else if (j == 20) { writer->setRAMBufferSizeMB(16); writer->setMaxBufferedDeleteTerms(IndexWriter::DISABLE_AUTO_FLUSH); lastFlushCount = flushCount; - } - else if (j < 30) + } else if (j < 30) { EXPECT_EQ(flushCount, lastFlushCount); - else if (j == 30) - { + } else if (j == 30) { writer->setRAMBufferSizeMB(0.000001); writer->setMaxBufferedDeleteTerms(IndexWriter::DISABLE_AUTO_FLUSH); writer->setMaxBufferedDeleteTerms(1); - } - else if (j < 40) - { + } else if (j < 40) { EXPECT_TRUE(flushCount> lastFlushCount); lastFlushCount = flushCount; - } - else if (j == 40) - { + } else if (j == 40) { writer->setMaxBufferedDeleteTerms(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); lastFlushCount = flushCount; - } - else if (j < 50) - { + } else if (j < 50) { EXPECT_EQ(flushCount, lastFlushCount); writer->setMaxBufferedDeleteTerms(10); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); - } - else if (j == 50) + } else if (j == 50) { EXPECT_TRUE(flushCount > lastFlushCount); + } } writer->close(); dir->close(); } -TEST_F(IndexWriterTest, testDiverseDocs) -{ +TEST_F(IndexWriterTest, testDiverseDocs) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setRAMBufferSizeMB(0.5); RandomPtr rand = newLucene(); - for (int32_t i = 0; i < 3; ++i) - { + for (int32_t i = 0; i < 3; ++i) { // First, docs where every term is unique (heavy on Posting instances) - for (int32_t j = 0; j < 100; ++j) - { + for (int32_t j = 0; j < 100; ++j) { DocumentPtr doc = newLucene(); - for (int32_t k = 0; k < 100; ++k) + for (int32_t k = 0; k < 100; ++k) { doc->add(newLucene(L"field", StringUtils::toString(rand->nextInt()), Field::STORE_YES, Field::INDEX_ANALYZED)); + } writer->addDocument(doc); } // Next, many single term docs where only one term occurs (heavy on byte blocks) - for (int32_t j = 0; j < 100; ++j) - { + for (int32_t j = 0; j < 100; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } // Next, many single term docs where only one term occurs but the terms are very long (heavy on char[] arrays) - for (int32_t j = 0; j < 100; ++j) - { + for (int32_t j = 0; j < 100; ++j) { StringStream buffer; - for (int32_t k = 0; k < 1000; ++k) + for (int32_t k = 0; k < 1000; ++k) { buffer << j << L"."; + } String longTerm = buffer.str(); DocumentPtr doc = newLucene(); @@ -1715,19 +1581,18 @@ TEST_F(IndexWriterTest, testDiverseDocs) dir->close(); } -TEST_F(IndexWriterTest, testEnablingNorms) -{ +TEST_F(IndexWriterTest, testEnablingNorms) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); // Enable norms for only 1 doc, pre flush - for (int32_t j = 0; j < 10; ++j) - { + for (int32_t j = 0; j < 10; ++j) { DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"field", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED); - if (j != 8) + if (j != 8) { f->setOmitNorms(true); + } doc->add(f); writer->addDocument(doc); } @@ -1744,12 +1609,12 @@ TEST_F(IndexWriterTest, testEnablingNorms) writer->setMaxBufferedDocs(10); // Enable norms for only 1 doc, post flush - for (int32_t j = 0; j < 27; ++j) - { + for (int32_t j = 0; j < 27; ++j) { DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"field", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED); - if (j != 26) + if (j != 26) { f->setOmitNorms(true); + } doc->add(f); writer->addDocument(doc); } @@ -1767,15 +1632,13 @@ TEST_F(IndexWriterTest, testEnablingNorms) dir->close(); } -TEST_F(IndexWriterTest, testHighFreqTerm) -{ +TEST_F(IndexWriterTest, testHighFreqTerm) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, 100000000); writer->setRAMBufferSizeMB(0.01); // Massive doc that has 128 K a's StringStream buffer; - for (int32_t i = 0; i < 4096; ++i) - { + for (int32_t i = 0; i < 4096; ++i) { buffer << L" a a a a a a a a"; buffer << L" a a a a a a a a"; buffer << L" a a a a a a a a"; @@ -1798,42 +1661,39 @@ TEST_F(IndexWriterTest, testHighFreqTerm) dir->close(); } -namespace TestNullLockFactory -{ - class MyRAMDirectory : public RAMDirectory - { - public: - MyRAMDirectory() - { - lockFactory.reset(); - myLockFactory = newLucene(); - } +namespace TestNullLockFactory { - virtual ~MyRAMDirectory() - { - } +class MyRAMDirectory : public RAMDirectory { +public: + MyRAMDirectory() { + lockFactory.reset(); + myLockFactory = newLucene(); + } - LUCENE_CLASS(MyRAMDirectory); + virtual ~MyRAMDirectory() { + } - protected: - LockFactoryPtr myLockFactory; + LUCENE_CLASS(MyRAMDirectory); + +protected: + LockFactoryPtr myLockFactory; + +public: + virtual LockPtr makeLock(const String& name) { + return myLockFactory->makeLock(name); + } +}; - public: - virtual LockPtr makeLock(const String& name) - { - return myLockFactory->makeLock(name); - } - }; } /// Make sure that a Directory implementation that does not use LockFactory at all (ie overrides makeLock and /// implements its own private locking) works OK. This was raised on java-dev as loss of backwards compatibility. -TEST_F(IndexWriterTest, testNullLockFactory) -{ +TEST_F(IndexWriterTest, testNullLockFactory) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } writer->close(); TermPtr searchTerm = newLucene(L"content", L"aaa"); @@ -1848,37 +1708,35 @@ TEST_F(IndexWriterTest, testNullLockFactory) dir->close(); } -namespace TestFlushWithNoMerging -{ - DECLARE_SHARED_PTR(TestableIndexWriter) +namespace TestFlushWithNoMerging { - class TestableIndexWriter : public IndexWriter - { - public: - TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { - } +DECLARE_SHARED_PTR(TestableIndexWriter) - virtual ~TestableIndexWriter() - { - } +class TestableIndexWriter : public IndexWriter { +public: + TestableIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + } + + virtual ~TestableIndexWriter() { + } + + LUCENE_CLASS(TestableIndexWriter); - LUCENE_CLASS(TestableIndexWriter); +public: + using IndexWriter::flush; +}; - public: - using IndexWriter::flush; - }; } -TEST_F(IndexWriterTest, testFlushWithNoMerging) -{ +TEST_F(IndexWriterTest, testFlushWithNoMerging) { DirectoryPtr dir = newLucene(); TestFlushWithNoMerging::TestableIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - for (int32_t i = 0; i < 19; ++i) + for (int32_t i = 0; i < 19; ++i) { writer->addDocument(doc); + } writer->flush(false, true, true); writer->close(); SegmentInfosPtr sis = newLucene(); @@ -1888,8 +1746,7 @@ TEST_F(IndexWriterTest, testFlushWithNoMerging) } /// Make sure we can flush segment with norms, then add empty doc (no norms) and flush -TEST_F(IndexWriterTest, testEmptyDocAfterFlushingRealDoc) -{ +TEST_F(IndexWriterTest, testEmptyDocAfterFlushingRealDoc) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -1905,30 +1762,26 @@ TEST_F(IndexWriterTest, testEmptyDocAfterFlushingRealDoc) /// Test calling optimize(false) whereby optimize is kicked off but we don't wait for it to finish (but /// writer.close()) does wait -TEST_F(IndexWriterTest, testBackgroundOptimize) -{ +TEST_F(IndexWriterTest, testBackgroundOptimize) { DirectoryPtr dir = newLucene(); - for (int32_t pass = 0; pass < 2; ++pass) - { + for (int32_t pass = 0; pass < 2; ++pass) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMergeScheduler(newLucene()); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); writer->setMaxBufferedDocs(2); writer->setMergeFactor(101); - for (int32_t i = 0; i < 200; ++i) + for (int32_t i = 0; i < 200; ++i) { writer->addDocument(doc); + } writer->optimize(false); - if (pass == 0) - { + if (pass == 0) { writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); EXPECT_TRUE(reader->isOptimized()); reader->close(); - } - else - { + } else { // Get another segment to flush so we can verify it is NOT included in the optimization writer->addDocument(doc); writer->addDocument(doc); @@ -1951,8 +1804,7 @@ TEST_F(IndexWriterTest, testBackgroundOptimize) /// Test that no NullPointerException will be raised, when adding one document with a single, empty /// field and term vectors enabled. -TEST_F(IndexWriterTest, testBadSegment) -{ +TEST_F(IndexWriterTest, testBadSegment) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1963,8 +1815,7 @@ TEST_F(IndexWriterTest, testBadSegment) dir->close(); } -TEST_F(IndexWriterTest, testNoTermVectorAfterTermVector) -{ +TEST_F(IndexWriterTest, testNoTermVectorAfterTermVector) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -1988,8 +1839,7 @@ TEST_F(IndexWriterTest, testNoTermVectorAfterTermVector) dir->close(); } -TEST_F(IndexWriterTest, testNoTermVectorAfterTermVectorMerge) -{ +TEST_F(IndexWriterTest, testNoTermVectorAfterTermVectorMerge) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -2017,40 +1867,37 @@ TEST_F(IndexWriterTest, testNoTermVectorAfterTermVectorMerge) dir->close(); } -namespace TestMaxThreadPriority -{ - // Just intercepts all merges & verifies that we are never merging a segment with >= 20 (maxMergeDocs) docs - class MyMergeScheduler : public MergeScheduler - { - public: - virtual ~MyMergeScheduler() - { - } +namespace TestMaxThreadPriority { - LUCENE_CLASS(MyMergeScheduler); +// Just intercepts all merges & verifies that we are never merging a segment with >= 20 (maxMergeDocs) docs +class MyMergeScheduler : public MergeScheduler { +public: + virtual ~MyMergeScheduler() { + } - public: - virtual void merge(const IndexWriterPtr& writer) - { - while (true) - { - OneMergePtr merge = writer->getNextMerge(); - if (!merge) - break; - for (int32_t i = 0; i < merge->segments->size(); ++i) - EXPECT_TRUE(merge->segments->info(i)->docCount < 20); - writer->merge(merge); + LUCENE_CLASS(MyMergeScheduler); + +public: + virtual void merge(const IndexWriterPtr& writer) { + while (true) { + OneMergePtr merge = writer->getNextMerge(); + if (!merge) { + break; } + for (int32_t i = 0; i < merge->segments->size(); ++i) { + EXPECT_TRUE(merge->segments->info(i)->docCount < 20); + } + writer->merge(merge); } + } + + virtual void close() { + } +}; - virtual void close() - { - } - }; } -TEST_F(IndexWriterTest, testMaxThreadPriority) -{ +TEST_F(IndexWriterTest, testMaxThreadPriority) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -2060,71 +1907,63 @@ TEST_F(IndexWriterTest, testMaxThreadPriority) writer->setMergeFactor(2); DocumentPtr doc = newLucene(); doc->add(newLucene(L"tvtest", L"a b c", Field::STORE_NO, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); - for (int32_t i = 0; i < 177; ++i) + for (int32_t i = 0; i < 177; ++i) { writer->addDocument(doc); + } writer->close(); dir->close(); } -namespace TestExceptionFromTokenStream -{ - class ExceptionTokenFilter : public TokenFilter - { - public: - ExceptionTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) - { - count = 0; - } +namespace TestExceptionFromTokenStream { - virtual ~ExceptionTokenFilter() - { - } +class ExceptionTokenFilter : public TokenFilter { +public: + ExceptionTokenFilter(const TokenStreamPtr& input) : TokenFilter(input) { + count = 0; + } + + virtual ~ExceptionTokenFilter() { + } - LUCENE_CLASS(ExceptionTokenFilter); + LUCENE_CLASS(ExceptionTokenFilter); - protected: - int32_t count; +protected: + int32_t count; - public: - virtual bool incrementToken() - { - if (count++ == 5) - boost::throw_exception(IOException(L"now failing on purpose")); - return input->incrementToken(); +public: + virtual bool incrementToken() { + if (count++ == 5) { + boost::throw_exception(IOException(L"now failing on purpose")); } - }; + return input->incrementToken(); + } +}; - class ExceptionAnalyzer : public Analyzer - { - public: - virtual ~ExceptionAnalyzer() - { - } +class ExceptionAnalyzer : public Analyzer { +public: + virtual ~ExceptionAnalyzer() { + } - LUCENE_CLASS(ExceptionAnalyzer); + LUCENE_CLASS(ExceptionAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, reader)); + } +}; - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(newLucene(LuceneVersion::LUCENE_CURRENT, reader)); - } - }; } -TEST_F(IndexWriterTest, testExceptionFromTokenStream) -{ +TEST_F(IndexWriterTest, testExceptionFromTokenStream) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); String contents = L"aa bb cc dd ee ff gg hh ii jj kk"; doc->add(newLucene(L"content", contents, Field::STORE_NO, Field::INDEX_ANALYZED)); - try - { + try { writer->addDocument(doc); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } @@ -2146,8 +1985,9 @@ TEST_F(IndexWriterTest, testExceptionFromTokenStream) // Make sure the doc that hit the exception was marked as deleted TermDocsPtr tdocs = reader->termDocs(t); int32_t count = 0; - while (tdocs->next()) + while (tdocs->next()) { ++count; + } EXPECT_EQ(2, count); @@ -2156,8 +1996,7 @@ TEST_F(IndexWriterTest, testExceptionFromTokenStream) dir->close(); } -TEST_F(IndexWriterTest, testDocumentsWriterAbort) -{ +TEST_F(IndexWriterTest, testDocumentsWriterAbort) { MockRAMDirectoryPtr dir = newLucene(); FailOnlyOnFlushPtr failure = newLucene(); failure->setDoFail(); @@ -2169,14 +2008,10 @@ TEST_F(IndexWriterTest, testDocumentsWriterAbort) String contents = L"aa bb cc dd ee ff gg hh ii jj kk"; doc->add(newLucene(L"content", contents, Field::STORE_NO, Field::INDEX_ANALYZED)); bool hitError = false; - for (int32_t i = 0; i < 200; ++i) - { - try - { + for (int32_t i = 0; i < 200; ++i) { + try { writer->addDocument(doc); - } - catch (IOException&) - { + } catch (IOException&) { // only one flush should fail EXPECT_TRUE(!hitError); hitError = true; @@ -2189,31 +2024,27 @@ TEST_F(IndexWriterTest, testDocumentsWriterAbort) reader->close(); } -namespace TestDocumentsWriterExceptions -{ - class CrashAnalyzer : public Analyzer - { - public: - virtual ~CrashAnalyzer() - { - } +namespace TestDocumentsWriterExceptions { + +class CrashAnalyzer : public Analyzer { +public: + virtual ~CrashAnalyzer() { + } - LUCENE_CLASS(CrashAnalyzer); + LUCENE_CLASS(CrashAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(fieldName, newLucene(reader)); + } +}; - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(fieldName, newLucene(reader)); - } - }; } -TEST_F(IndexWriterTest, testDocumentsWriterExceptions) -{ +TEST_F(IndexWriterTest, testDocumentsWriterExceptions) { AnalyzerPtr analyzer = newLucene(); - for (int32_t i = 0; i < 2; ++i) - { + for (int32_t i = 0; i < 2; ++i) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -2223,17 +2054,13 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptions) doc->add(newLucene(L"crash", L"this should crash after 4 terms", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); doc->add(newLucene(L"other", L"this will not get indexed", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - try - { + try { writer->addDocument(doc); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } - if (i == 0) - { + if (i == 0) { doc = newLucene(); doc->add(newLucene(L"contents", L"here are some contents", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); writer->addDocument(doc); @@ -2246,12 +2073,10 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptions) EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); EXPECT_EQ(expected, reader->maxDoc()); int32_t numDel = 0; - for (int32_t j = 0; j < reader->maxDoc(); ++j) - { - if (reader->isDeleted(j)) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { + if (reader->isDeleted(j)) { ++numDel; - else - { + } else { reader->document(j); reader->getTermFreqVectors(j); } @@ -2264,8 +2089,9 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptions) writer->setMaxBufferedDocs(10); doc = newLucene(); doc->add(newLucene(L"contents", L"here are some contents", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { writer->addDocument(doc); + } writer->optimize(); writer->close(); @@ -2274,12 +2100,10 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptions) EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); EXPECT_EQ(expected, reader->maxDoc()); numDel = 0; - for (int32_t j = 0; j < reader->maxDoc(); ++j) - { - if (reader->isDeleted(j)) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { + if (reader->isDeleted(j)) { ++numDel; - else - { + } else { reader->document(j); reader->getTermFreqVectors(j); } @@ -2291,94 +2115,78 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptions) } } -namespace TestDocumentsWriterExceptionThreads -{ - class CrashAnalyzer : public Analyzer - { - public: - virtual ~CrashAnalyzer() - { - } +namespace TestDocumentsWriterExceptionThreads { - LUCENE_CLASS(CrashAnalyzer); +class CrashAnalyzer : public Analyzer { +public: + virtual ~CrashAnalyzer() { + } - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(fieldName, newLucene(reader)); - } - }; + LUCENE_CLASS(CrashAnalyzer); - class ExceptionThread : public LuceneThread - { - public: - ExceptionThread(const IndexWriterPtr& writer, int32_t numIter, int32_t finalI) - { - this->writer = writer; - this->numIter = numIter; - this->finalI = finalI; - } +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(fieldName, newLucene(reader)); + } +}; - virtual ~ExceptionThread() - { - } +class ExceptionThread : public LuceneThread { +public: + ExceptionThread(const IndexWriterPtr& writer, int32_t numIter, int32_t finalI) { + this->writer = writer; + this->numIter = numIter; + this->finalI = finalI; + } - LUCENE_CLASS(ExceptionThread); + virtual ~ExceptionThread() { + } - protected: - IndexWriterPtr writer; - int32_t numIter; - int32_t finalI; + LUCENE_CLASS(ExceptionThread); - public: - virtual void run() - { - try - { - for (int32_t iter = 0; iter < numIter; ++iter) - { - DocumentPtr doc = newLucene(); - doc->add(newLucene(L"contents", L"here are some contents", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - writer->addDocument(doc); - writer->addDocument(doc); - doc->add(newLucene(L"crash", L"this should crash after 4 terms", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - doc->add(newLucene(L"other", L"this will not get indexed", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); +protected: + IndexWriterPtr writer; + int32_t numIter; + int32_t finalI; - try - { - writer->addDocument(doc); - FAIL() << "did not hit expected exception"; - } - catch (IOException&) - { - } +public: + virtual void run() { + try { + for (int32_t iter = 0; iter < numIter; ++iter) { + DocumentPtr doc = newLucene(); + doc->add(newLucene(L"contents", L"here are some contents", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); + writer->addDocument(doc); + writer->addDocument(doc); + doc->add(newLucene(L"crash", L"this should crash after 4 terms", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); + doc->add(newLucene(L"other", L"this will not get indexed", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - if (finalI == 0) - { - doc = newLucene(); - doc->add(newLucene(L"contents", L"here are some contents", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - writer->addDocument(doc); - writer->addDocument(doc); - } + try { + writer->addDocument(doc); + FAIL() << "did not hit expected exception"; + } catch (IOException&) { + } + + if (finalI == 0) { + doc = newLucene(); + doc->add(newLucene(L"contents", L"here are some contents", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); + writer->addDocument(doc); + writer->addDocument(doc); } } - catch (LuceneException& e) - { - FAIL() << "Unexpected exception: " << e.getError(); - } + } catch (LuceneException& e) { + FAIL() << "Unexpected exception: " << e.getError(); } - }; + } +}; + } -TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) -{ +TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) { AnalyzerPtr analyzer = newLucene(); int32_t NUM_THREAD = 3; int32_t NUM_ITER = 100; - for (int32_t i = 0; i < 2; ++i) - { + for (int32_t i = 0; i < 2; ++i) { MockRAMDirectoryPtr dir = newLucene(); { @@ -2386,14 +2194,14 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) int32_t finalI = i; Collection threads = Collection::newInstance(NUM_THREAD); - for (int32_t t = 0; t < NUM_THREAD; ++t) - { + for (int32_t t = 0; t < NUM_THREAD; ++t) { threads[t] = newLucene(writer, NUM_ITER, finalI); threads[t]->start(); } - for (int32_t t = 0; t < NUM_THREAD; ++t) + for (int32_t t = 0; t < NUM_THREAD; ++t) { threads[t]->join(); + } writer->close(); } @@ -2403,12 +2211,10 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); EXPECT_EQ(expected, reader->maxDoc()); int32_t numDel = 0; - for (int32_t j = 0; j < reader->maxDoc(); ++j) - { - if (reader->isDeleted(j)) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { + if (reader->isDeleted(j)) { ++numDel; - else - { + } else { reader->document(j); reader->getTermFreqVectors(j); } @@ -2421,8 +2227,9 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) writer->setMaxBufferedDocs(10); DocumentPtr doc = newLucene(); doc->add(newLucene(L"contents", L"here are some contents", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { writer->addDocument(doc); + } writer->optimize(); writer->close(); @@ -2431,12 +2238,10 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) EXPECT_EQ(expected, reader->docFreq(newLucene(L"contents", L"here"))); EXPECT_EQ(expected, reader->maxDoc()); numDel = 0; - for (int32_t j = 0; j < reader->maxDoc(); ++j) - { - if (reader->isDeleted(j)) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { + if (reader->isDeleted(j)) { ++numDel; - else - { + } else { reader->document(j); reader->getTermFreqVectors(j); } @@ -2448,13 +2253,11 @@ TEST_F(IndexWriterTest, testDocumentsWriterExceptionThreads) } } -TEST_F(IndexWriterTest, testVariableSchema) -{ +TEST_F(IndexWriterTest, testVariableSchema) { MockRAMDirectoryPtr dir = newLucene(); int32_t delID = 0; - for (int32_t i = 0; i < 20; ++i) - { + for (int32_t i = 0; i < 20; ++i) { IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(2); @@ -2462,16 +2265,12 @@ TEST_F(IndexWriterTest, testVariableSchema) DocumentPtr doc = newLucene(); String contents = L"aa bb cc dd ee ff gg hh ii jj kk"; - if (i == 7) - { + if (i == 7) { // Add empty docs here doc->add(newLucene(L"content3", L"", Field::STORE_NO, Field::INDEX_ANALYZED)); - } - else - { + } else { Field::Store storeVal = Field::STORE_NO; - if (i % 2 == 0) - { + if (i % 2 == 0) { doc->add(newLucene(L"content4", contents, Field::STORE_YES, Field::INDEX_ANALYZED)); storeVal = Field::STORE_YES; } @@ -2481,16 +2280,16 @@ TEST_F(IndexWriterTest, testVariableSchema) doc->add(newLucene(L"content5", L"", storeVal, Field::INDEX_ANALYZED)); } - for (int32_t j = 0; j < 4; ++j) + for (int32_t j = 0; j < 4; ++j) { writer->addDocument(doc); + } writer->close(); IndexReaderPtr reader = IndexReader::open(dir, false); reader->deleteDocument(delID++); reader->close(); - if (i % 4 == 0) - { + if (i % 4 == 0) { writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(false); writer->optimize(); @@ -2499,95 +2298,79 @@ TEST_F(IndexWriterTest, testVariableSchema) } } -namespace TestNoWaitClose -{ - class NoWaitThread : public LuceneThread - { - public: - NoWaitThread(const IndexWriterPtr& finalWriter, const DocumentPtr& doc) - { - this->finalWriter = finalWriter; - this->doc = doc; - } +namespace TestNoWaitClose { - virtual ~NoWaitThread() - { - } +class NoWaitThread : public LuceneThread { +public: + NoWaitThread(const IndexWriterPtr& finalWriter, const DocumentPtr& doc) { + this->finalWriter = finalWriter; + this->doc = doc; + } - LUCENE_CLASS(NoWaitThread); + virtual ~NoWaitThread() { + } - protected: - IndexWriterPtr finalWriter; - DocumentPtr doc; + LUCENE_CLASS(NoWaitThread); - public: - virtual void run() - { - bool done = false; - while (!done) - { - for (int32_t i = 0; i < 100; ++i) - { - try - { - finalWriter->addDocument(doc); - } - catch (AlreadyClosedException&) - { - done = true; - break; - } - catch (NullPointerException&) - { - done = true; - break; - } - catch (...) - { - FAIL() << "Unexpected exception"; - done = true; - break; - } +protected: + IndexWriterPtr finalWriter; + DocumentPtr doc; + +public: + virtual void run() { + bool done = false; + while (!done) { + for (int32_t i = 0; i < 100; ++i) { + try { + finalWriter->addDocument(doc); + } catch (AlreadyClosedException&) { + done = true; + break; + } catch (NullPointerException&) { + done = true; + break; + } catch (...) { + FAIL() << "Unexpected exception"; + done = true; + break; } - LuceneThread::threadYield(); } + LuceneThread::threadYield(); } - }; + } +}; + } -TEST_F(IndexWriterTest, testNoWaitClose) -{ +TEST_F(IndexWriterTest, testNoWaitClose) { MockRAMDirectoryPtr dir = newLucene(); DocumentPtr doc = newLucene(); FieldPtr idField = newLucene(L"id", L"", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); doc->add(idField); - for (int32_t pass = 0; pass < 2; ++pass) - { + for (int32_t pass = 0; pass < 2; ++pass) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t iter = 0; iter < 10; ++iter) - { + for (int32_t iter = 0; iter < 10; ++iter) { MergeSchedulerPtr ms; - if (pass == 1) + if (pass == 1) { ms = newLucene(); - else + } else { ms = newLucene(); + } writer->setMergeScheduler(ms); writer->setMaxBufferedDocs(2); writer->setMergeFactor(100); - for (int32_t j = 0; j < 199; ++j) - { + for (int32_t j = 0; j < 199; ++j) { idField->setValue(StringUtils::toString(iter * 201 + j)); writer->addDocument(doc); } int32_t delID = iter * 199; - for (int32_t j = 0; j < 20; ++j) - { + for (int32_t j = 0; j < 20; ++j) { writer->deleteDocuments(newLucene(L"id", StringUtils::toString(delID))); delID += 5; } @@ -2616,12 +2399,10 @@ TEST_F(IndexWriterTest, testNoWaitClose) } /// Make sure we can close() even while threads are trying to add documents. -TEST_F(IndexWriterTest, testCloseWithThreads) -{ +TEST_F(IndexWriterTest, testCloseWithThreads) { int32_t NUM_THREADS = 3; - for (int32_t iter = 0; iter < 20; ++iter) - { + for (int32_t iter = 0; iter < 20; ++iter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); ConcurrentMergeSchedulerPtr cms = newLucene(); @@ -2635,21 +2416,20 @@ TEST_F(IndexWriterTest, testCloseWithThreads) Collection threads = Collection::newInstance(NUM_THREADS); - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i] = newLucene(writer, false); + } - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->start(); + } bool done = false; - while (!done) - { + while (!done) { LuceneThread::threadSleep(100); - for (int32_t i = 0; i < NUM_THREADS; ++i) - { + for (int32_t i = 0; i < NUM_THREADS; ++i) { // only stop when at least one thread has added a doc - if (threads[i]->addCount > 0) - { + if (threads[i]->addCount > 0) { done = true; break; } @@ -2659,19 +2439,20 @@ TEST_F(IndexWriterTest, testCloseWithThreads) writer->close(false); // Make sure threads that are adding docs are not hung - for (int32_t i = 0; i < NUM_THREADS; ++i) - { + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); - if (threads[i]->isAlive()) + if (threads[i]->isAlive()) { FAIL() << "thread seems to be hung"; + } } // Quick test to make sure index is not corrupt IndexReaderPtr reader = IndexReader::open(dir, true); TermDocsPtr tdocs = reader->termDocs(newLucene(L"field", L"aaa")); int32_t count = 0; - while (tdocs->next()) + while (tdocs->next()) { ++count; + } EXPECT_TRUE(count > 0); reader->close(); @@ -2680,48 +2461,36 @@ TEST_F(IndexWriterTest, testCloseWithThreads) } /// Make sure immediate disk full on creating an IndexWriter (hit during DW.ThreadState.init()) is OK -TEST_F(IndexWriterTest, testImmediateDiskFull) -{ +TEST_F(IndexWriterTest, testImmediateDiskFull) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); dir->setMaxSizeInBytes(dir->getRecomputedActualSizeInBytes()); writer->setMaxBufferedDocs(2); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa bbb ccc ddd eee fff ggg hhh iii jjj", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - try - { + try { writer->addDocument(doc); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } - try - { + try { writer->addDocument(doc); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } - try - { + try { writer->close(false); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } } /// Make sure immediate disk full on creating an IndexWriter (hit during DW.ThreadState.init()), /// with multiple threads, is OK -TEST_F(IndexWriterTest, testImmediateDiskFullWithThreads) -{ +TEST_F(IndexWriterTest, testImmediateDiskFullWithThreads) { int32_t NUM_THREADS = 3; - for (int32_t iter = 0; iter < 10; ++iter) - { + for (int32_t iter = 0; iter < 10; ++iter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); ConcurrentMergeSchedulerPtr cms = newLucene(); @@ -2736,21 +2505,21 @@ TEST_F(IndexWriterTest, testImmediateDiskFullWithThreads) Collection threads = Collection::newInstance(NUM_THREADS); - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i] = newLucene(writer, true); + } - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->start(); + } - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); + } - try - { + try { writer->close(false); - } - catch (IOException&) - { + } catch (IOException&) { } // allow time for merge threads to finish @@ -2760,40 +2529,35 @@ TEST_F(IndexWriterTest, testImmediateDiskFullWithThreads) } } -static void _testSingleThreadFailure(const MockDirectoryFailurePtr& failure) -{ +static void _testSingleThreadFailure(const MockDirectoryFailurePtr& failure) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"aaa bbb ccc ddd eee fff ggg hhh iii jjj", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - for (int32_t i = 0; i < 6; ++i) + for (int32_t i = 0; i < 6; ++i) { writer->addDocument(doc); + } dir->failOn(failure); failure->setDoFail(); - try - { + try { writer->addDocument(doc); writer->addDocument(doc); writer->commit(); FAIL() << "did not hit exception"; - } - catch (IOException&) - { + } catch (IOException&) { } failure->clearDoFail(); writer->addDocument(doc); writer->close(false); } -static void _testMultipleThreadsFailure(const MockDirectoryFailurePtr& failure) -{ +static void _testMultipleThreadsFailure(const MockDirectoryFailurePtr& failure) { int32_t NUM_THREADS = 3; - for (int32_t iter = 0; iter < 5; ++iter) - { + for (int32_t iter = 0; iter < 5; ++iter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); ConcurrentMergeSchedulerPtr cms = newLucene(); @@ -2807,40 +2571,37 @@ static void _testMultipleThreadsFailure(const MockDirectoryFailurePtr& failure) Collection threads = Collection::newInstance(NUM_THREADS); - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i] = newLucene(writer, true); + } - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->start(); + } LuceneThread::threadSleep(10); dir->failOn(failure); failure->setDoFail(); - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); + } bool success = false; - try - { + try { writer->close(false); success = true; - } - catch (IOException&) - { + } catch (IOException&) { failure->clearDoFail(); writer->close(false); } - if (success) - { + if (success) { IndexReaderPtr reader = IndexReader::open(dir, true); - for (int32_t j = 0; j < reader->maxDoc(); ++j) - { - if (!reader->isDeleted(j)) - { + for (int32_t j = 0; j < reader->maxDoc(); ++j) { + if (!reader->isDeleted(j)) { reader->document(j); reader->getTermFreqVectors(j); } @@ -2856,88 +2617,76 @@ static void _testMultipleThreadsFailure(const MockDirectoryFailurePtr& failure) } /// Make sure initial IOException, and then 2nd IOException during rollback(), is OK -TEST_F(IndexWriterTest, testIOExceptionDuringAbort) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringAbort) { _testSingleThreadFailure(newLucene(false)); } /// Make sure initial IOException, and then 2nd IOException during rollback(), is OK -TEST_F(IndexWriterTest, testIOExceptionDuringAbortOnlyOnce) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringAbortOnlyOnce) { _testSingleThreadFailure(newLucene(true)); } /// Make sure initial IOException, and then 2nd IOException during rollback(), with /// multiple threads, is OK -TEST_F(IndexWriterTest, testIOExceptionDuringAbortWithThreads) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringAbortWithThreads) { _testMultipleThreadsFailure(newLucene(false)); } /// Make sure initial IOException, and then 2nd IOException during rollback(), with /// multiple threads, is OK -TEST_F(IndexWriterTest, testIOExceptionDuringAbortWithThreadsOnlyOnce) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringAbortWithThreadsOnlyOnce) { _testMultipleThreadsFailure(newLucene(true)); } /// Test IOException in closeDocStore -TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStore) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStore) { _testSingleThreadFailure(newLucene(false)); } /// Test IOException in closeDocStore -TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreOnlyOnce) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreOnlyOnce) { _testSingleThreadFailure(newLucene(true)); } /// Test IOException in closeDocStore, with threads -TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreWithThreads) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreWithThreads) { _testMultipleThreadsFailure(newLucene(false)); } /// Test IOException in closeDocStore, with threads -TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreWithThreadsOnlyOnce) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringCloseDocStoreWithThreadsOnlyOnce) { _testMultipleThreadsFailure(newLucene(true)); } /// Test IOException in writeSegment -TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegment) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegment) { _testSingleThreadFailure(newLucene(false)); } /// Test IOException in writeSegment -TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentOnlyOnce) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentOnlyOnce) { _testSingleThreadFailure(newLucene(true)); } /// Test IOException in writeSegment, with threads -TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentWithThreads) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentWithThreads) { _testMultipleThreadsFailure(newLucene(false)); } /// Test IOException in writeSegment, with threads -TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentWithThreadsOnlyOnce) -{ +TEST_F(IndexWriterTest, testIOExceptionDuringWriteSegmentWithThreadsOnlyOnce) { _testMultipleThreadsFailure(newLucene(true)); } /// Test unlimited field length -TEST_F(IndexWriterTest, testUnlimitedMaxFieldLength) -{ +TEST_F(IndexWriterTest, testUnlimitedMaxFieldLength) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); StringStream buffer; - for (int32_t i = 0; i < 10000; ++i) + for (int32_t i = 0; i < 10000; ++i) { buffer << L" a"; + } buffer << L" x"; doc->add(newLucene(L"field", buffer.str(), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -2951,14 +2700,14 @@ TEST_F(IndexWriterTest, testUnlimitedMaxFieldLength) } /// Simulate checksum error in segments_N -TEST_F(IndexWriterTest, testSegmentsChecksumError) -{ +TEST_F(IndexWriterTest, testSegmentsChecksumError) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // add 100 documents - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } writer->close(); int64_t gen = SegmentInfos::getCurrentSegmentGeneration(dir); @@ -2979,15 +2728,15 @@ TEST_F(IndexWriterTest, testSegmentsChecksumError) } /// Test writer.commit() when ac=false -TEST_F(IndexWriterTest, testForceCommit) -{ +TEST_F(IndexWriterTest, testForceCommit) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(5); - for (int32_t i = 0; i < 23; ++i) + for (int32_t i = 0; i < 23; ++i) { addDoc(writer); + } IndexReaderPtr reader = IndexReader::open(dir, true); EXPECT_EQ(0, reader->numDocs()); writer->commit(); @@ -2996,8 +2745,9 @@ TEST_F(IndexWriterTest, testForceCommit) EXPECT_EQ(23, reader2->numDocs()); reader->close(); - for (int32_t i = 0; i < 17; ++i) + for (int32_t i = 0; i < 17; ++i) { addDoc(writer); + } EXPECT_EQ(23, reader2->numDocs()); reader2->close(); reader = IndexReader::open(dir, true); @@ -3013,8 +2763,7 @@ TEST_F(IndexWriterTest, testForceCommit) } /// Test exception during sync -TEST_F(IndexWriterTest, testExceptionDuringSync) -{ +TEST_F(IndexWriterTest, testExceptionDuringSync) { MockRAMDirectoryPtr dir = newLucene(); FailOnlyInSyncPtr failure = newLucene(); dir->failOn(failure); @@ -3029,17 +2778,12 @@ TEST_F(IndexWriterTest, testExceptionDuringSync) writer->setMaxBufferedDocs(2); writer->setMergeFactor(5); - for (int32_t i = 0; i < 23; ++i) - { + for (int32_t i = 0; i < 23; ++i) { addDoc(writer); - if ((i - 1) % 2 == 0) - { - try - { + if ((i - 1) % 2 == 0) { + try { writer->commit(); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } } @@ -3056,11 +2800,9 @@ TEST_F(IndexWriterTest, testExceptionDuringSync) dir->close(); } -TEST_F(IndexWriterTest, testTermVectorCorruption) -{ +TEST_F(IndexWriterTest, testTermVectorCorruption) { DirectoryPtr dir = newLucene(); - for (int32_t iter = 0; iter < 2; ++iter) - { + for (int32_t iter = 0; iter < 2; ++iter) { IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); @@ -3084,8 +2826,7 @@ TEST_F(IndexWriterTest, testTermVectorCorruption) writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - for (int32_t i = 0; i < reader->numDocs(); ++i) - { + for (int32_t i = 0; i < reader->numDocs(); ++i) { reader->document(i); reader->getTermFreqVectors(i); } @@ -3104,11 +2845,9 @@ TEST_F(IndexWriterTest, testTermVectorCorruption) dir->close(); } -TEST_F(IndexWriterTest, testTermVectorCorruption2) -{ +TEST_F(IndexWriterTest, testTermVectorCorruption2) { DirectoryPtr dir = newLucene(); - for (int32_t iter = 0; iter < 2; ++iter) - { + for (int32_t iter = 0; iter < 2; ++iter) { IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); @@ -3140,8 +2879,7 @@ TEST_F(IndexWriterTest, testTermVectorCorruption2) dir->close(); } -TEST_F(IndexWriterTest, testTermVectorCorruption3) -{ +TEST_F(IndexWriterTest, testTermVectorCorruption3) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); @@ -3157,8 +2895,9 @@ TEST_F(IndexWriterTest, testTermVectorCorruption3) FieldPtr termVectorField = newLucene(L"termVector", L"termVector", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); document->add(termVectorField); - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { writer->addDocument(document); + } writer->close(); writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); @@ -3166,15 +2905,15 @@ TEST_F(IndexWriterTest, testTermVectorCorruption3) writer->setRAMBufferSizeMB(IndexWriter::DISABLE_AUTO_FLUSH); writer->setMergeScheduler(newLucene()); writer->setMergePolicy(newLucene(writer)); - for (int32_t i = 0; i < 6; ++i) + for (int32_t i = 0; i < 6; ++i) { writer->addDocument(document); + } writer->optimize(); writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { reader->getTermFreqVectors(i); reader->document(i); } @@ -3183,15 +2922,15 @@ TEST_F(IndexWriterTest, testTermVectorCorruption3) } /// Test user-specified field length -TEST_F(IndexWriterTest, testUserSpecifiedMaxFieldLength) -{ +TEST_F(IndexWriterTest, testUserSpecifiedMaxFieldLength) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), 100000); DocumentPtr doc = newLucene(); StringStream buffer; - for (int32_t i = 0; i < 10000; ++i) + for (int32_t i = 0; i < 10000; ++i) { buffer << L" a"; + } buffer << L" x"; doc->add(newLucene(L"field", buffer.str(), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -3205,8 +2944,7 @@ TEST_F(IndexWriterTest, testUserSpecifiedMaxFieldLength) } /// Test expungeDeletes, when 2 singular merges are required -TEST_F(IndexWriterTest, testExpungeDeletes) -{ +TEST_F(IndexWriterTest, testExpungeDeletes) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); @@ -3220,8 +2958,9 @@ TEST_F(IndexWriterTest, testExpungeDeletes) FieldPtr termVectorField = newLucene(L"termVector", L"termVector", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); document->add(termVectorField); - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { writer->addDocument(document); + } writer->close(); IndexReaderPtr ir = IndexReader::open(dir, false); @@ -3247,8 +2986,7 @@ TEST_F(IndexWriterTest, testExpungeDeletes) } /// Test expungeDeletes, when many adjacent merges are required -TEST_F(IndexWriterTest, testExpungeDeletes2) -{ +TEST_F(IndexWriterTest, testExpungeDeletes2) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); @@ -3263,15 +3001,17 @@ TEST_F(IndexWriterTest, testExpungeDeletes2) FieldPtr termVectorField = newLucene(L"termVector", L"termVector", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); document->add(termVectorField); - for (int32_t i = 0; i < 98; ++i) + for (int32_t i = 0; i < 98; ++i) { writer->addDocument(document); + } writer->close(); IndexReaderPtr ir = IndexReader::open(dir, false); EXPECT_EQ(98, ir->maxDoc()); EXPECT_EQ(98, ir->numDocs()); - for (int32_t i = 0; i < 98; i += 2) + for (int32_t i = 0; i < 98; i += 2) { ir->deleteDocument(i); + } EXPECT_EQ(49, ir->numDocs()); ir->close(); @@ -3289,8 +3029,7 @@ TEST_F(IndexWriterTest, testExpungeDeletes2) } /// Test expungeDeletes without waiting, when many adjacent merges are required -TEST_F(IndexWriterTest, testExpungeDeletes3) -{ +TEST_F(IndexWriterTest, testExpungeDeletes3) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); @@ -3305,15 +3044,17 @@ TEST_F(IndexWriterTest, testExpungeDeletes3) FieldPtr termVectorField = newLucene(L"termVector", L"termVector", Field::STORE_NO, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS); document->add(termVectorField); - for (int32_t i = 0; i < 98; ++i) + for (int32_t i = 0; i < 98; ++i) { writer->addDocument(document); + } writer->close(); IndexReaderPtr ir = IndexReader::open(dir, false); EXPECT_EQ(98, ir->maxDoc()); EXPECT_EQ(98, ir->numDocs()); - for (int32_t i = 0; i < 98; i += 2) + for (int32_t i = 0; i < 98; i += 2) { ir->deleteDocument(i); + } EXPECT_EQ(49, ir->numDocs()); ir->close(); @@ -3329,8 +3070,7 @@ TEST_F(IndexWriterTest, testExpungeDeletes3) dir->close(); } -TEST_F(IndexWriterTest, testEmptyFieldName) -{ +TEST_F(IndexWriterTest, testEmptyFieldName) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -3340,51 +3080,45 @@ TEST_F(IndexWriterTest, testEmptyFieldName) writer->close(); } -namespace TestExceptionDocumentsWriterInit -{ - DECLARE_SHARED_PTR(MockIndexWriter) +namespace TestExceptionDocumentsWriterInit { - class MockIndexWriter : public IndexWriter - { - public: - MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { - doFail = false; - } +DECLARE_SHARED_PTR(MockIndexWriter) - virtual ~MockIndexWriter() - { - } +class MockIndexWriter : public IndexWriter { +public: + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + doFail = false; + } + + virtual ~MockIndexWriter() { + } - LUCENE_CLASS(MockIndexWriter); + LUCENE_CLASS(MockIndexWriter); - public: - bool doFail; +public: + bool doFail; - public: - virtual bool testPoint(const String& name) - { - if (doFail && name == L"DocumentsWriter.ThreadState.init start") - boost::throw_exception(RuntimeException(L"intentionally failing")); - return true; +public: + virtual bool testPoint(const String& name) { + if (doFail && name == L"DocumentsWriter.ThreadState.init start") { + boost::throw_exception(RuntimeException(L"intentionally failing")); } - }; + return true; + } +}; + } -TEST_F(IndexWriterTest, testExceptionDocumentsWriterInit) -{ +TEST_F(IndexWriterTest, testExceptionDocumentsWriterInit) { MockRAMDirectoryPtr dir = newLucene(); TestExceptionDocumentsWriterInit::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"a field", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); writer->doFail = true; - try - { + try { writer->addDocument(doc); - } - catch (RuntimeException& e) - { + } catch (RuntimeException& e) { EXPECT_TRUE(check_exception(LuceneException::Runtime)(e)); } writer->close(); @@ -3392,55 +3126,49 @@ TEST_F(IndexWriterTest, testExceptionDocumentsWriterInit) dir->close(); } -namespace TestExceptionJustBeforeFlush -{ - DECLARE_SHARED_PTR(MockIndexWriter) +namespace TestExceptionJustBeforeFlush { - class MockIndexWriter : public IndexWriter - { - public: - MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { - doFail = false; - } +DECLARE_SHARED_PTR(MockIndexWriter) - virtual ~MockIndexWriter() - { - } +class MockIndexWriter : public IndexWriter { +public: + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + doFail = false; + } - LUCENE_CLASS(MockIndexWriter); + virtual ~MockIndexWriter() { + } - public: - bool doFail; + LUCENE_CLASS(MockIndexWriter); - public: - virtual bool testPoint(const String& name) - { - if (doFail && name == L"DocumentsWriter.ThreadState.init start") - boost::throw_exception(RuntimeException(L"intentionally failing")); - return true; - } - }; +public: + bool doFail; - class CrashAnalyzer : public Analyzer - { - public: - virtual ~CrashAnalyzer() - { +public: + virtual bool testPoint(const String& name) { + if (doFail && name == L"DocumentsWriter.ThreadState.init start") { + boost::throw_exception(RuntimeException(L"intentionally failing")); } + return true; + } +}; - LUCENE_CLASS(CrashAnalyzer); +class CrashAnalyzer : public Analyzer { +public: + virtual ~CrashAnalyzer() { + } + + LUCENE_CLASS(CrashAnalyzer); + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(fieldName, newLucene(reader)); + } +}; - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(fieldName, newLucene(reader)); - } - }; } -TEST_F(IndexWriterTest, testExceptionJustBeforeFlush) -{ +TEST_F(IndexWriterTest, testExceptionJustBeforeFlush) { MockRAMDirectoryPtr dir = newLucene(); TestExceptionJustBeforeFlush::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); @@ -3453,12 +3181,9 @@ TEST_F(IndexWriterTest, testExceptionJustBeforeFlush) DocumentPtr crashDoc = newLucene(); crashDoc->add(newLucene(L"crash", L"do it on token 4", Field::STORE_YES, Field::INDEX_ANALYZED)); - try - { + try { writer->addDocument(crashDoc, analyzer); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } writer->addDocument(doc); @@ -3466,44 +3191,39 @@ TEST_F(IndexWriterTest, testExceptionJustBeforeFlush) dir->close(); } -namespace TestExceptionOnMergeInit -{ - DECLARE_SHARED_PTR(MockIndexWriter) +namespace TestExceptionOnMergeInit { - class MockIndexWriter : public IndexWriter - { - public: - MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { - doFail = false; - failed = false; - } +DECLARE_SHARED_PTR(MockIndexWriter) - virtual ~MockIndexWriter() - { - } +class MockIndexWriter : public IndexWriter { +public: + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + doFail = false; + failed = false; + } - LUCENE_CLASS(MockIndexWriter); + virtual ~MockIndexWriter() { + } - public: - bool doFail; - bool failed; + LUCENE_CLASS(MockIndexWriter); - public: - virtual bool testPoint(const String& name) - { - if (doFail && name == L"startMergeInit") - { - failed = true; - boost::throw_exception(RuntimeException(L"intentionally failing")); - } - return true; +public: + bool doFail; + bool failed; + +public: + virtual bool testPoint(const String& name) { + if (doFail && name == L"startMergeInit") { + failed = true; + boost::throw_exception(RuntimeException(L"intentionally failing")); } - }; + return true; + } +}; + } -TEST_F(IndexWriterTest, testExceptionOnMergeInit) -{ +TEST_F(IndexWriterTest, testExceptionOnMergeInit) { MockRAMDirectoryPtr dir = newLucene(); TestExceptionOnMergeInit::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); @@ -3512,14 +3232,10 @@ TEST_F(IndexWriterTest, testExceptionOnMergeInit) writer->setMergeScheduler(newLucene()); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"a field", Field::STORE_YES, Field::INDEX_ANALYZED)); - for (int32_t i = 0; i < 10; ++i) - { - try - { + for (int32_t i = 0; i < 10; ++i) { + try { writer->addDocument(doc); - } - catch (RuntimeException&) - { + } catch (RuntimeException&) { break; } } @@ -3529,44 +3245,39 @@ TEST_F(IndexWriterTest, testExceptionOnMergeInit) dir->close(); } -namespace TestDoBeforeAfterFlush -{ - DECLARE_SHARED_PTR(MockIndexWriter) +namespace TestDoBeforeAfterFlush { - class MockIndexWriter : public IndexWriter - { - public: - MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { - afterWasCalled = false; - beforeWasCalled = false; - } +DECLARE_SHARED_PTR(MockIndexWriter) - virtual ~MockIndexWriter() - { - } +class MockIndexWriter : public IndexWriter { +public: + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + afterWasCalled = false; + beforeWasCalled = false; + } - LUCENE_CLASS(MockIndexWriter); + virtual ~MockIndexWriter() { + } - public: - bool afterWasCalled; - bool beforeWasCalled; + LUCENE_CLASS(MockIndexWriter); - protected: - virtual void doAfterFlush() - { - afterWasCalled = true; - } +public: + bool afterWasCalled; + bool beforeWasCalled; + +protected: + virtual void doAfterFlush() { + afterWasCalled = true; + } + + virtual void doBeforeFlush() { + beforeWasCalled = true; + } +}; - virtual void doBeforeFlush() - { - beforeWasCalled = true; - } - }; } -TEST_F(IndexWriterTest, testDoBeforeAfterFlush) -{ +TEST_F(IndexWriterTest, testDoBeforeAfterFlush) { MockRAMDirectoryPtr dir = newLucene(); TestDoBeforeAfterFlush::MockIndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); @@ -3591,8 +3302,7 @@ TEST_F(IndexWriterTest, testDoBeforeAfterFlush) dir->close(); } -TEST_F(IndexWriterTest, testExceptionsDuringCommit) -{ +TEST_F(IndexWriterTest, testExceptionsDuringCommit) { MockRAMDirectoryPtr dir = newLucene(); FailOnlyInCommitPtr failure = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -3600,12 +3310,9 @@ TEST_F(IndexWriterTest, testExceptionsDuringCommit) doc->add(newLucene(L"field", L"a field", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); dir->failOn(failure); - try - { + try { writer->close(); - } - catch (RuntimeException& e) - { + } catch (RuntimeException& e) { EXPECT_TRUE(check_exception(LuceneException::Runtime)(e)); } EXPECT_TRUE(failure->fail1 && failure->fail2); @@ -3613,47 +3320,44 @@ TEST_F(IndexWriterTest, testExceptionsDuringCommit) dir->close(); } -namespace TestNegativePositions -{ - class NegativeTokenStream : public TokenStream - { - public: - NegativeTokenStream() - { - termAtt = addAttribute(); - posIncrAtt = addAttribute(); - tokens = newCollection(L"a", L"b", L"c" ); - tokenIter = tokens.begin(); - first = true; - } +namespace TestNegativePositions { - virtual ~NegativeTokenStream() - { - } +class NegativeTokenStream : public TokenStream { +public: + NegativeTokenStream() { + termAtt = addAttribute(); + posIncrAtt = addAttribute(); + tokens = newCollection(L"a", L"b", L"c" ); + tokenIter = tokens.begin(); + first = true; + } - public: - TermAttributePtr termAtt; - PositionIncrementAttributePtr posIncrAtt; - Collection tokens; - Collection::iterator tokenIter; - bool first; + virtual ~NegativeTokenStream() { + } + +public: + TermAttributePtr termAtt; + PositionIncrementAttributePtr posIncrAtt; + Collection tokens; + Collection::iterator tokenIter; + bool first; + +public: + virtual bool incrementToken() { + if (tokenIter == tokens.end()) { + return false; + } + clearAttributes(); + termAtt->setTermBuffer(*tokenIter++); + posIncrAtt->setPositionIncrement(first ? 0 : 1); + first = false; + return true; + } +}; - public: - virtual bool incrementToken() - { - if (tokenIter == tokens.end()) - return false; - clearAttributes(); - termAtt->setTermBuffer(*tokenIter++); - posIncrAtt->setPositionIncrement(first ? 0 : 1); - first = false; - return true; - } - }; } -TEST_F(IndexWriterTest, testNegativePositions) -{ +TEST_F(IndexWriterTest, testNegativePositions) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); @@ -3684,15 +3388,15 @@ TEST_F(IndexWriterTest, testNegativePositions) dir->close(); } -TEST_F(IndexWriterTest, testPrepareCommit) -{ +TEST_F(IndexWriterTest, testPrepareCommit) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(5); - for (int32_t i = 0; i < 23; ++i) + for (int32_t i = 0; i < 23; ++i) { addDoc(writer); + } IndexReaderPtr reader = IndexReader::open(dir, true); EXPECT_EQ(0, reader->numDocs()); @@ -3711,8 +3415,9 @@ TEST_F(IndexWriterTest, testPrepareCommit) reader->close(); reader2->close(); - for (int32_t i = 0; i < 17; ++i) + for (int32_t i = 0; i < 17; ++i) { addDoc(writer); + } EXPECT_EQ(23, reader3->numDocs()); reader3->close(); @@ -3734,8 +3439,7 @@ TEST_F(IndexWriterTest, testPrepareCommit) dir->close(); } -TEST_F(IndexWriterTest, testPrepareCommitRollback) -{ +TEST_F(IndexWriterTest, testPrepareCommitRollback) { MockRAMDirectoryPtr dir = newLucene(); dir->setPreventDoubleWrite(false); @@ -3743,8 +3447,9 @@ TEST_F(IndexWriterTest, testPrepareCommitRollback) writer->setMaxBufferedDocs(2); writer->setMergeFactor(5); - for (int32_t i = 0; i < 23; ++i) + for (int32_t i = 0; i < 23; ++i) { addDoc(writer); + } IndexReaderPtr reader = IndexReader::open(dir, true); EXPECT_EQ(0, reader->numDocs()); @@ -3764,8 +3469,9 @@ TEST_F(IndexWriterTest, testPrepareCommitRollback) reader2->close(); writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 17; ++i) + for (int32_t i = 0; i < 17; ++i) { addDoc(writer); + } EXPECT_EQ(0, reader3->numDocs()); reader3->close(); @@ -3787,8 +3493,7 @@ TEST_F(IndexWriterTest, testPrepareCommitRollback) dir->close(); } -TEST_F(IndexWriterTest, testPrepareCommitNoChanges) -{ +TEST_F(IndexWriterTest, testPrepareCommitNoChanges) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -3802,59 +3507,54 @@ TEST_F(IndexWriterTest, testPrepareCommitNoChanges) dir->close(); } -namespace TestAddIndexesWithThreads -{ - DECLARE_SHARED_PTR(CommitAndAddIndexes) +namespace TestAddIndexesWithThreads { - class CommitAndAddIndexes : public RunAddIndexesThreads - { - public: - CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) - { - } +DECLARE_SHARED_PTR(CommitAndAddIndexes) - virtual ~CommitAndAddIndexes() - { - } +class CommitAndAddIndexes : public RunAddIndexesThreads { +public: + CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { + } - public: - virtual void handle(LuceneException& e) - { - FAIL() << "Unexpected exception: " << e.getError(); - } + virtual ~CommitAndAddIndexes() { + } - virtual void doBody(int32_t j, Collection dirs) - { - switch (j % 4) - { - case 0: - writer2->addIndexesNoOptimize(dirs); - writer2->optimize(); - break; - case 1: - writer2->addIndexesNoOptimize(dirs); - break; - case 2: - writer2->addIndexes(readers); - break; - case 3: - writer2->commit(); - break; - } +public: + virtual void handle(LuceneException& e) { + FAIL() << "Unexpected exception: " << e.getError(); + } + + virtual void doBody(int32_t j, Collection dirs) { + switch (j % 4) { + case 0: + writer2->addIndexesNoOptimize(dirs); + writer2->optimize(); + break; + case 1: + writer2->addIndexesNoOptimize(dirs); + break; + case 2: + writer2->addIndexes(readers); + break; + case 3: + writer2->commit(); + break; } - }; + } +}; + } /// Test simultaneous addIndexes & commits from multiple threads -TEST_F(IndexWriterTest, testAddIndexesWithThreads) -{ +TEST_F(IndexWriterTest, testAddIndexesWithThreads) { static const int32_t NUM_ITER = 12; static const int32_t NUM_COPY = 3; TestAddIndexesWithThreads::CommitAndAddIndexesPtr c = newLucene(NUM_COPY); c->launchThreads(NUM_ITER); - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(c->writer2); + } c->joinThreads(); @@ -3871,53 +3571,48 @@ TEST_F(IndexWriterTest, testAddIndexesWithThreads) c->closeDir(); } -namespace TestAddIndexesWithClose -{ - DECLARE_SHARED_PTR(CommitAndAddIndexes) +namespace TestAddIndexesWithClose { - class CommitAndAddIndexes : public RunAddIndexesThreads - { - public: - CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) - { - } +DECLARE_SHARED_PTR(CommitAndAddIndexes) - virtual ~CommitAndAddIndexes() - { - } +class CommitAndAddIndexes : public RunAddIndexesThreads { +public: + CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { + } - public: - virtual void handle(LuceneException& e) - { - if (e.getType() != LuceneException::AlreadyClosed && e.getType() != LuceneException::NullPointer) - FAIL() << "Unexpected exception: " << e.getError(); + virtual ~CommitAndAddIndexes() { + } + +public: + virtual void handle(LuceneException& e) { + if (e.getType() != LuceneException::AlreadyClosed && e.getType() != LuceneException::NullPointer) { + FAIL() << "Unexpected exception: " << e.getError(); } + } - virtual void doBody(int32_t j, Collection dirs) - { - switch (j % 4) - { - case 0: - writer2->addIndexesNoOptimize(dirs); - writer2->optimize(); - break; - case 1: - writer2->addIndexesNoOptimize(dirs); - break; - case 2: - writer2->addIndexes(readers); - break; - case 3: - writer2->commit(); - break; - } + virtual void doBody(int32_t j, Collection dirs) { + switch (j % 4) { + case 0: + writer2->addIndexesNoOptimize(dirs); + writer2->optimize(); + break; + case 1: + writer2->addIndexesNoOptimize(dirs); + break; + case 2: + writer2->addIndexes(readers); + break; + case 3: + writer2->commit(); + break; } - }; + } +}; + } /// Test simultaneous addIndexes & close -TEST_F(IndexWriterTest, testAddIndexesWithClose) -{ +TEST_F(IndexWriterTest, testAddIndexesWithClose) { static const int32_t NUM_COPY = 3; TestAddIndexesWithClose::CommitAndAddIndexesPtr c = newLucene(NUM_COPY); c->launchThreads(-1); @@ -3932,60 +3627,56 @@ TEST_F(IndexWriterTest, testAddIndexesWithClose) c->closeDir(); } -namespace TestAddIndexesWithCloseNoWait -{ - DECLARE_SHARED_PTR(CommitAndAddIndexes) +namespace TestAddIndexesWithCloseNoWait { - class CommitAndAddIndexes : public RunAddIndexesThreads - { - public: - CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) - { - } +DECLARE_SHARED_PTR(CommitAndAddIndexes) - virtual ~CommitAndAddIndexes() - { - } +class CommitAndAddIndexes : public RunAddIndexesThreads { +public: + CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { + } - public: - virtual void handle(LuceneException& e) - { - bool report = true; - if (e.getType() == LuceneException::AlreadyClosed || e.getType() == LuceneException::MergeAborted || e.getType() == LuceneException::NullPointer) - report = !didClose; - else if (e.getType() == LuceneException::IO) - report = !didClose; - if (report) - FAIL() << "Unexpected exception: " << e.getError(); + virtual ~CommitAndAddIndexes() { + } + +public: + virtual void handle(LuceneException& e) { + bool report = true; + if (e.getType() == LuceneException::AlreadyClosed || e.getType() == LuceneException::MergeAborted || e.getType() == LuceneException::NullPointer) { + report = !didClose; + } else if (e.getType() == LuceneException::IO) { + report = !didClose; + } + if (report) { + FAIL() << "Unexpected exception: " << e.getError(); } + } - virtual void doBody(int32_t j, Collection dirs) - { - switch (j % 5) - { - case 0: - writer2->addIndexesNoOptimize(dirs); - writer2->optimize(); - break; - case 1: - writer2->addIndexesNoOptimize(dirs); - break; - case 2: - writer2->addIndexes(readers); - break; - case 3: - writer2->optimize(); - case 4: - writer2->commit(); - break; - } + virtual void doBody(int32_t j, Collection dirs) { + switch (j % 5) { + case 0: + writer2->addIndexesNoOptimize(dirs); + writer2->optimize(); + break; + case 1: + writer2->addIndexesNoOptimize(dirs); + break; + case 2: + writer2->addIndexes(readers); + break; + case 3: + writer2->optimize(); + case 4: + writer2->commit(); + break; } - }; + } +}; + } /// Test simultaneous addIndexes and close -TEST_F(IndexWriterTest, testAddIndexesWithCloseNoWait) -{ +TEST_F(IndexWriterTest, testAddIndexesWithCloseNoWait) { static const int32_t NUM_COPY = 50; TestAddIndexesWithCloseNoWait::CommitAndAddIndexesPtr c = newLucene(NUM_COPY); c->launchThreads(-1); @@ -4002,60 +3693,56 @@ TEST_F(IndexWriterTest, testAddIndexesWithCloseNoWait) c->closeDir(); } -namespace TestAddIndexesWithRollback -{ - DECLARE_SHARED_PTR(CommitAndAddIndexes) +namespace TestAddIndexesWithRollback { - class CommitAndAddIndexes : public RunAddIndexesThreads - { - public: - CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) - { - } +DECLARE_SHARED_PTR(CommitAndAddIndexes) - virtual ~CommitAndAddIndexes() - { - } +class CommitAndAddIndexes : public RunAddIndexesThreads { +public: + CommitAndAddIndexes(int32_t numCopy) : RunAddIndexesThreads(numCopy) { + } - public: - virtual void handle(LuceneException& e) - { - bool report = true; - if (e.getType() == LuceneException::AlreadyClosed || e.getType() == LuceneException::MergeAborted || e.getType() == LuceneException::NullPointer) - report = !didClose; - else if (e.getType() == LuceneException::IO) - report = !didClose; - if (report) - FAIL() << "Unexpected exception: " << e.getError(); + virtual ~CommitAndAddIndexes() { + } + +public: + virtual void handle(LuceneException& e) { + bool report = true; + if (e.getType() == LuceneException::AlreadyClosed || e.getType() == LuceneException::MergeAborted || e.getType() == LuceneException::NullPointer) { + report = !didClose; + } else if (e.getType() == LuceneException::IO) { + report = !didClose; + } + if (report) { + FAIL() << "Unexpected exception: " << e.getError(); } + } - virtual void doBody(int32_t j, Collection dirs) - { - switch (j % 5) - { - case 0: - writer2->addIndexesNoOptimize(dirs); - writer2->optimize(); - break; - case 1: - writer2->addIndexesNoOptimize(dirs); - break; - case 2: - writer2->addIndexes(readers); - break; - case 3: - writer2->optimize(); - case 4: - writer2->commit(); - break; - } + virtual void doBody(int32_t j, Collection dirs) { + switch (j % 5) { + case 0: + writer2->addIndexesNoOptimize(dirs); + writer2->optimize(); + break; + case 1: + writer2->addIndexesNoOptimize(dirs); + break; + case 2: + writer2->addIndexes(readers); + break; + case 3: + writer2->optimize(); + case 4: + writer2->commit(); + break; } - }; + } +}; + } /// Test simultaneous addIndexes and close -TEST_F(IndexWriterTest, testAddIndexesWithRollback) -{ +TEST_F(IndexWriterTest, testAddIndexesWithRollback) { static const int32_t NUM_COPY = 50; TestAddIndexesWithRollback::CommitAndAddIndexesPtr c = newLucene(NUM_COPY); c->launchThreads(-1); @@ -4073,50 +3760,44 @@ TEST_F(IndexWriterTest, testAddIndexesWithRollback) c->closeDir(); } -namespace TestRollbackExceptionHang -{ - DECLARE_SHARED_PTR(MockIndexWriter) +namespace TestRollbackExceptionHang { - class MockIndexWriter : public IndexWriter - { - public: - MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { - doFail = false; - } +DECLARE_SHARED_PTR(MockIndexWriter) - virtual ~MockIndexWriter() - { - } +class MockIndexWriter : public IndexWriter { +public: + MockIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + doFail = false; + } - LUCENE_CLASS(MockIndexWriter); + virtual ~MockIndexWriter() { + } - public: - bool doFail; + LUCENE_CLASS(MockIndexWriter); - public: - virtual bool testPoint(const String& name) - { - if (doFail && name == L"rollback before checkpoint") - boost::throw_exception(RuntimeException(L"intentionally failing")); - return true; +public: + bool doFail; + +public: + virtual bool testPoint(const String& name) { + if (doFail && name == L"rollback before checkpoint") { + boost::throw_exception(RuntimeException(L"intentionally failing")); } - }; + return true; + } +}; + } -TEST_F(IndexWriterTest, testRollbackExceptionHang) -{ +TEST_F(IndexWriterTest, testRollbackExceptionHang) { MockRAMDirectoryPtr dir = newLucene(); TestRollbackExceptionHang::MockIndexWriterPtr w = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(w); w->doFail = true; - try - { + try { w->rollback(); - } - catch (RuntimeException& e) - { + } catch (RuntimeException& e) { EXPECT_TRUE(check_exception(LuceneException::Runtime)(e)); } @@ -4124,13 +3805,13 @@ TEST_F(IndexWriterTest, testRollbackExceptionHang) w->rollback(); } -TEST_F(IndexWriterTest, testBinaryFieldOffsetLength) -{ +TEST_F(IndexWriterTest, testBinaryFieldOffsetLength) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); ByteArray b = ByteArray::newInstance(50); - for (int32_t i = 0; i < 50; ++i) + for (int32_t i = 0; i < 50; ++i) { b[i] = (uint8_t)(i + 77); + } DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"binary", b, 10, 17, Field::STORE_YES); @@ -4154,13 +3835,13 @@ TEST_F(IndexWriterTest, testBinaryFieldOffsetLength) dir->close(); } -TEST_F(IndexWriterTest, testCommitUserData) -{ +TEST_F(IndexWriterTest, testCommitUserData) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { addDoc(writer); + } writer->close(); EXPECT_EQ(0, IndexReader::getCommitUserData(dir).size()); @@ -4172,8 +3853,9 @@ TEST_F(IndexWriterTest, testCommitUserData) writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); - for (int32_t j = 0; j < 17; ++j) + for (int32_t j = 0; j < 17; ++j) { addDoc(writer); + } MapStringString data = MapStringString::newInstance(); data.put(L"label", L"test1"); writer->commit(data); @@ -4194,29 +3876,25 @@ TEST_F(IndexWriterTest, testCommitUserData) dir->close(); } -TEST_F(IndexWriterTest, testOptimizeExceptions) -{ +TEST_F(IndexWriterTest, testOptimizeExceptions) { MockRAMDirectoryPtr startDir = newLucene(); IndexWriterPtr writer = newLucene(startDir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(100); - for (int32_t i = 0; i < 27; ++i) + for (int32_t i = 0; i < 27; ++i) { addDoc(writer); + } writer->close(); - for (int32_t i = 0; i < 200; ++i) - { + for (int32_t i = 0; i < 200; ++i) { MockRAMDirectoryPtr dir = newLucene(startDir); writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); boost::dynamic_pointer_cast(writer->getMergeScheduler())->setSuppressExceptions(); dir->setRandomIOExceptionRate(0.5, 100); - try - { + try { writer->optimize(); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } @@ -4228,57 +3906,48 @@ TEST_F(IndexWriterTest, testOptimizeExceptions) } } -namespace TestOutOfMemoryErrorCausesCloseToFail -{ - class MemoryIndexWriter : public IndexWriter - { - public: - MemoryIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) - { - thrown = false; - } +namespace TestOutOfMemoryErrorCausesCloseToFail { - virtual ~MemoryIndexWriter() - { - } +class MemoryIndexWriter : public IndexWriter { +public: + MemoryIndexWriter(const DirectoryPtr& d, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(d, a, create, mfl) { + thrown = false; + } - LUCENE_CLASS(MemoryIndexWriter); + virtual ~MemoryIndexWriter() { + } - protected: - bool thrown; + LUCENE_CLASS(MemoryIndexWriter); - public: - virtual void message(const String& message) - { - if (boost::starts_with(message, L"now flush at close") && !thrown) - { - thrown = true; - boost::throw_exception(std::bad_alloc()); - } +protected: + bool thrown; + +public: + virtual void message(const String& message) { + if (boost::starts_with(message, L"now flush at close") && !thrown) { + thrown = true; + boost::throw_exception(std::bad_alloc()); } - }; + } +}; + } -TEST_F(IndexWriterTest, testOutOfMemoryErrorCausesCloseToFail) -{ +TEST_F(IndexWriterTest, testOutOfMemoryErrorCausesCloseToFail) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setInfoStream(newLucene()); - try - { + try { writer->close(); - } - catch (OutOfMemoryError& e) - { + } catch (OutOfMemoryError& e) { EXPECT_TRUE(check_exception(LuceneException::OutOfMemory)(e)); } writer->close(); } -TEST_F(IndexWriterTest, testDoubleOffsetCounting) -{ +TEST_F(IndexWriterTest, testDoubleOffsetCounting) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -4312,8 +3981,7 @@ TEST_F(IndexWriterTest, testDoubleOffsetCounting) dir->close(); } -TEST_F(IndexWriterTest, testDoubleOffsetCounting2) -{ +TEST_F(IndexWriterTest, testDoubleOffsetCounting2) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -4334,8 +4002,7 @@ TEST_F(IndexWriterTest, testDoubleOffsetCounting2) dir->close(); } -TEST_F(IndexWriterTest, testEndOffsetPositionCharAnalyzer) -{ +TEST_F(IndexWriterTest, testEndOffsetPositionCharAnalyzer) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -4357,8 +4024,7 @@ TEST_F(IndexWriterTest, testEndOffsetPositionCharAnalyzer) dir->close(); } -TEST_F(IndexWriterTest, testEndOffsetPositionWithCachingTokenFilter) -{ +TEST_F(IndexWriterTest, testEndOffsetPositionWithCachingTokenFilter) { MockRAMDirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); @@ -4382,8 +4048,7 @@ TEST_F(IndexWriterTest, testEndOffsetPositionWithCachingTokenFilter) dir->close(); } -TEST_F(IndexWriterTest, testEndOffsetPositionWithTeeSinkTokenFilter) -{ +TEST_F(IndexWriterTest, testEndOffsetPositionWithTeeSinkTokenFilter) { MockRAMDirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, IndexWriter::MaxFieldLengthLIMITED); @@ -4409,8 +4074,7 @@ TEST_F(IndexWriterTest, testEndOffsetPositionWithTeeSinkTokenFilter) dir->close(); } -TEST_F(IndexWriterTest, testEndOffsetPositionStopFilter) -{ +TEST_F(IndexWriterTest, testEndOffsetPositionStopFilter) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -4432,8 +4096,7 @@ TEST_F(IndexWriterTest, testEndOffsetPositionStopFilter) dir->close(); } -TEST_F(IndexWriterTest, testEndOffsetPositionStandard) -{ +TEST_F(IndexWriterTest, testEndOffsetPositionStandard) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -4461,8 +4124,7 @@ TEST_F(IndexWriterTest, testEndOffsetPositionStandard) dir->close(); } -TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField) -{ +TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -4487,8 +4149,7 @@ TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField) dir->close(); } -TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField2) -{ +TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField2) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -4515,14 +4176,12 @@ TEST_F(IndexWriterTest, testEndOffsetPositionStandardEmptyField2) } /// Make sure opening an IndexWriter with create=true does not remove non-index files -TEST_F(IndexWriterTest, testOtherFiles) -{ +TEST_F(IndexWriterTest, testOtherFiles) { String indexDir(FileUtils::joinPath(getTempDir(), L"otherfiles")); DirectoryPtr dir = FSDirectory::open(indexDir); LuceneException finally; - try - { + try { // Create my own random file IndexOutputPtr out = dir->createOutput(L"myrandomfile"); out->writeByte((uint8_t)42); @@ -4536,9 +4195,7 @@ TEST_F(IndexWriterTest, testOtherFiles) // Make sure this does not copy myrandomfile DirectoryPtr dir2 = newLucene(dir); EXPECT_TRUE(!dir2->fileExists(L"myrandomfile")); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } dir->close(); @@ -4546,8 +4203,7 @@ TEST_F(IndexWriterTest, testOtherFiles) finally.throwException(); } -TEST_F(IndexWriterTest, testDeadlock) -{ +TEST_F(IndexWriterTest, testDeadlock) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); @@ -4581,13 +4237,13 @@ TEST_F(IndexWriterTest, testDeadlock) dir->close(); } -TEST_F(IndexWriterTest, testIndexStoreCombos) -{ +TEST_F(IndexWriterTest, testIndexStoreCombos) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); ByteArray b = ByteArray::newInstance(50); - for (int32_t i = 0; i < 50; ++i) + for (int32_t i = 0; i < 50; ++i) { b[i] = (uint8_t)(i + 77); + } DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"binary", b, 10, 17, Field::STORE_YES); @@ -4642,8 +4298,7 @@ TEST_F(IndexWriterTest, testIndexStoreCombos) } /// Make sure doc fields are stored in order -TEST_F(IndexWriterTest, testStoredFieldsOrder) -{ +TEST_F(IndexWriterTest, testStoredFieldsOrder) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); @@ -4667,8 +4322,7 @@ TEST_F(IndexWriterTest, testStoredFieldsOrder) dir->close(); } -TEST_F(IndexWriterTest, testEmbeddedFFFF) -{ +TEST_F(IndexWriterTest, testEmbeddedFFFF) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); @@ -4688,8 +4342,7 @@ TEST_F(IndexWriterTest, testEmbeddedFFFF) dir->close(); } -TEST_F(IndexWriterTest, testNoDocsIndex) -{ +TEST_F(IndexWriterTest, testNoDocsIndex) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); writer->setUseCompoundFile(false); @@ -4700,69 +4353,60 @@ TEST_F(IndexWriterTest, testNoDocsIndex) dir->close(); } -namespace TestCommitThreadSafety -{ - class CommitThread : public LuceneThread - { - public: - CommitThread(int32_t finalI, const IndexWriterPtr& writer, const DirectoryPtr& dir, int64_t endTime) - { - this->finalI = finalI; - this->writer = writer; - this->dir = dir; - this->endTime = endTime; - } +namespace TestCommitThreadSafety { - virtual ~CommitThread() - { - } +class CommitThread : public LuceneThread { +public: + CommitThread(int32_t finalI, const IndexWriterPtr& writer, const DirectoryPtr& dir, int64_t endTime) { + this->finalI = finalI; + this->writer = writer; + this->dir = dir; + this->endTime = endTime; + } - LUCENE_CLASS(CommitThread); + virtual ~CommitThread() { + } - protected: - int32_t finalI; - IndexWriterPtr writer; - DirectoryPtr dir; - int64_t endTime; + LUCENE_CLASS(CommitThread); - public: - virtual void run() - { - try - { - DocumentPtr doc = newLucene(); - IndexReaderPtr reader = IndexReader::open(dir); - FieldPtr field = newLucene(L"f", L"", Field::STORE_NO, Field::INDEX_NOT_ANALYZED); - doc->add(field); - int32_t count = 0; - while ((int64_t)MiscUtils::currentTimeMillis() < endTime) - { - for (int32_t j = 0; j < 10; ++j) - { - String s = StringUtils::toString(finalI) + L"_" + StringUtils::toString(count++); - field->setValue(s); - writer->addDocument(doc); - writer->commit(); - IndexReaderPtr reader2 = reader->reopen(); - EXPECT_NE(reader2, reader); - reader->close(); - reader = reader2; - EXPECT_EQ(1, reader->docFreq(newLucene(L"f", s))); - } +protected: + int32_t finalI; + IndexWriterPtr writer; + DirectoryPtr dir; + int64_t endTime; + +public: + virtual void run() { + try { + DocumentPtr doc = newLucene(); + IndexReaderPtr reader = IndexReader::open(dir); + FieldPtr field = newLucene(L"f", L"", Field::STORE_NO, Field::INDEX_NOT_ANALYZED); + doc->add(field); + int32_t count = 0; + while ((int64_t)MiscUtils::currentTimeMillis() < endTime) { + for (int32_t j = 0; j < 10; ++j) { + String s = StringUtils::toString(finalI) + L"_" + StringUtils::toString(count++); + field->setValue(s); + writer->addDocument(doc); + writer->commit(); + IndexReaderPtr reader2 = reader->reopen(); + EXPECT_NE(reader2, reader); + reader->close(); + reader = reader2; + EXPECT_EQ(1, reader->docFreq(newLucene(L"f", s))); } - reader->close(); - } - catch (...) - { - FAIL() << "Unexpected exception"; } + reader->close(); + } catch (...) { + FAIL() << "Unexpected exception"; } - }; + } +}; + } /// make sure with multiple threads commit doesn't return until all changes are in fact in the index -TEST_F(IndexWriterTest, testCommitThreadSafety) -{ +TEST_F(IndexWriterTest, testCommitThreadSafety) { static const int32_t NUM_THREADS = 5; double RUN_SEC = 0.5; DirectoryPtr dir = newLucene(); @@ -4770,56 +4414,53 @@ TEST_F(IndexWriterTest, testCommitThreadSafety) writer->commit(); Collection threads = Collection::newInstance(NUM_THREADS); int64_t endTime = (int64_t)MiscUtils::currentTimeMillis() + (int64_t)(RUN_SEC * 1000.0); - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i] = newLucene(i, writer, dir, endTime); - for (int32_t i = 0; i < NUM_THREADS; ++i) + } + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); + } writer->close(); dir->close(); } -namespace TestCorruptionAfterDiskFullDuringMerge -{ - DECLARE_SHARED_PTR(FailTwiceDuringMerge) +namespace TestCorruptionAfterDiskFullDuringMerge { - class FailTwiceDuringMerge : public MockDirectoryFailure - { - public: - FailTwiceDuringMerge() - { - didFail1 = false; - didFail2 = false; - } +DECLARE_SHARED_PTR(FailTwiceDuringMerge) - virtual ~FailTwiceDuringMerge() - { - } +class FailTwiceDuringMerge : public MockDirectoryFailure { +public: + FailTwiceDuringMerge() { + didFail1 = false; + didFail2 = false; + } - public: - bool didFail1; - bool didFail2; + virtual ~FailTwiceDuringMerge() { + } - public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (!doFail) - return; - if (TestPoint::getTestPoint(L"SegmentMerger", L"mergeTerms") && !didFail1) - { - didFail1 = true; - boost::throw_exception(IOException(L"fake disk full during mergeTerms")); - } - if (TestPoint::getTestPoint(L"BitVector", L"write") && !didFail2) - { - didFail2 = true; - boost::throw_exception(IOException(L"fake disk full while writing BitVector")); - } +public: + bool didFail1; + bool didFail2; + +public: + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (!doFail) { + return; + } + if (TestPoint::getTestPoint(L"SegmentMerger", L"mergeTerms") && !didFail1) { + didFail1 = true; + boost::throw_exception(IOException(L"fake disk full during mergeTerms")); + } + if (TestPoint::getTestPoint(L"BitVector", L"write") && !didFail2) { + didFail2 = true; + boost::throw_exception(IOException(L"fake disk full while writing BitVector")); } - }; + } +}; + } -TEST_F(IndexWriterTest, testCorruptionAfterDiskFullDuringMerge) -{ +TEST_F(IndexWriterTest, testCorruptionAfterDiskFullDuringMerge) { MockRAMDirectoryPtr dir = newLucene(); dir->setPreventDoubleWrite(false); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -4841,13 +4482,10 @@ TEST_F(IndexWriterTest, testCorruptionAfterDiskFullDuringMerge) ftdm->setDoFail(); dir->failOn(ftdm); - try - { + try { w->commit(); FAIL() << "fake disk full IOExceptions not hit"; - } - catch (IOException&) - { + } catch (IOException&) { } EXPECT_TRUE(ftdm->didFail1 || ftdm->didFail2); @@ -4861,30 +4499,26 @@ TEST_F(IndexWriterTest, testCorruptionAfterDiskFullDuringMerge) dir->close(); } -namespace TestFutureCommit -{ - class NoDeletionPolicy : public IndexDeletionPolicy - { - public: - virtual ~NoDeletionPolicy() - { - } +namespace TestFutureCommit { - LUCENE_CLASS(NoDeletionPolicy); +class NoDeletionPolicy : public IndexDeletionPolicy { +public: + virtual ~NoDeletionPolicy() { + } - public: - virtual void onInit(Collection commits) - { - } + LUCENE_CLASS(NoDeletionPolicy); + +public: + virtual void onInit(Collection commits) { + } + + virtual void onCommit(Collection commits) { + } +}; - virtual void onCommit(Collection commits) - { - } - }; } -TEST_F(IndexWriterTest, testFutureCommit) -{ +TEST_F(IndexWriterTest, testFutureCommit) { MockRAMDirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), (IndexDeletionPolicyPtr)newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); @@ -4905,11 +4539,9 @@ TEST_F(IndexWriterTest, testFutureCommit) // open "first" with IndexWriter IndexCommitPtr commit; Collection commits = IndexReader::listCommits(dir); - for (Collection::iterator c = commits.begin(); c != commits.end(); ++c) - { + for (Collection::iterator c = commits.begin(); c != commits.end(); ++c) { String tag = (*c)->getUserData().get(L"tag"); - if (tag == L"first") - { + if (tag == L"first") { commit = *c; break; } @@ -4930,11 +4562,9 @@ TEST_F(IndexWriterTest, testFutureCommit) // make sure "second" commit is still there commit.reset(); commits = IndexReader::listCommits(dir); - for (Collection::iterator c = commits.begin(); c != commits.end(); ++c) - { + for (Collection::iterator c = commits.begin(); c != commits.end(); ++c) { String tag = (*c)->getUserData().get(L"tag"); - if (tag == L"second") - { + if (tag == L"second") { commit = *c; break; } @@ -4958,11 +4588,9 @@ TEST_F(IndexWriterTest, testFutureCommit) // make sure "third" commit is still there commit.reset(); commits = IndexReader::listCommits(dir); - for (Collection::iterator c = commits.begin(); c != commits.end(); ++c) - { + for (Collection::iterator c = commits.begin(); c != commits.end(); ++c) { String tag = (*c)->getUserData().get(L"tag"); - if (tag == L"third") - { + if (tag == L"third") { commit = *c; break; } @@ -4973,8 +4601,7 @@ TEST_F(IndexWriterTest, testFutureCommit) dir->close(); } -TEST_F(IndexWriterTest, testNoUnwantedTVFiles) -{ +TEST_F(IndexWriterTest, testNoUnwantedTVFiles) { DirectoryPtr dir = newLucene(); IndexWriterPtr indexWriter = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); indexWriter->setRAMBufferSizeMB(0.01); @@ -4983,8 +4610,7 @@ TEST_F(IndexWriterTest, testNoUnwantedTVFiles) String BIG = L"alskjhlaksjghlaksjfhalksvjepgjioefgjnsdfjgefgjhelkgjhqewlrkhgwlekgrhwelkgjhwelkgrhwlkejg"; BIG += BIG + BIG + BIG; - for (int32_t i = 0; i < 2; ++i) - { + for (int32_t i = 0; i < 2; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i) + BIG, Field::STORE_YES, Field::INDEX_NOT_ANALYZED_NO_NORMS)); doc->add(newLucene(L"str", StringUtils::toString(i) + BIG, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -4999,8 +4625,7 @@ TEST_F(IndexWriterTest, testNoUnwantedTVFiles) checkNoUnreferencedFiles(dir); HashSet files = dir->listAll(); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - { + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { EXPECT_TRUE(!boost::ends_with(*file, IndexFileNames::VECTORS_FIELDS_EXTENSION())); EXPECT_TRUE(!boost::ends_with(*file, IndexFileNames::VECTORS_INDEX_EXTENSION())); EXPECT_TRUE(!boost::ends_with(*file, IndexFileNames::VECTORS_DOCUMENTS_EXTENSION())); diff --git a/src/test/index/LazyBugTest.cpp b/src/test/index/LazyBugTest.cpp index 73f1d55b..fdedfbb9 100644 --- a/src/test/index/LazyBugTest.cpp +++ b/src/test/index/LazyBugTest.cpp @@ -18,11 +18,9 @@ using namespace Lucene; -class LazyBugTest : public LuceneTestFixture -{ +class LazyBugTest : public LuceneTestFixture { public: - virtual ~LazyBugTest() - { + virtual ~LazyBugTest() { } public: @@ -30,11 +28,9 @@ class LazyBugTest : public LuceneTestFixture static const int32_t NUM_FIELDS; public: - Collection data() - { + Collection data() { static Collection _data; - if (!_data) - { + if (!_data) { _data = Collection::newInstance(); _data.add(L"now"); _data.add(L"is the time"); @@ -47,34 +43,28 @@ class LazyBugTest : public LuceneTestFixture return _data; } - HashSet dataset() - { + HashSet dataset() { static HashSet _dataset; - if (!_dataset) - { + if (!_dataset) { Collection _data = data(); _dataset = HashSet::newInstance(_data.begin(), _data.end()); } return _dataset; } - String MAGIC_FIELD() - { + String MAGIC_FIELD() { return L"f" + StringUtils::toString((double)NUM_FIELDS / 3); } DECLARE_SHARED_PTR(LazyBugSelector) - class LazyBugSelector : public FieldSelector - { + class LazyBugSelector : public FieldSelector { public: - LazyBugSelector(const String& magicField) - { + LazyBugSelector(const String& magicField) { this->magicField = magicField; } - virtual ~LazyBugSelector() - { + virtual ~LazyBugSelector() { } LUCENE_CLASS(LazyBugSelector); @@ -83,76 +73,66 @@ class LazyBugTest : public LuceneTestFixture String magicField; public: - virtual FieldSelectorResult accept(const String& fieldName) - { - if (fieldName == magicField) + virtual FieldSelectorResult accept(const String& fieldName) { + if (fieldName == magicField) { return FieldSelector::SELECTOR_LOAD; - else + } else { return FieldSelector::SELECTOR_LAZY_LOAD; + } } }; - FieldSelectorPtr SELECTOR() - { + FieldSelectorPtr SELECTOR() { return newLucene(MAGIC_FIELD()); } - DirectoryPtr makeIndex() - { + DirectoryPtr makeIndex() { DirectoryPtr dir = newLucene(); RandomPtr rand = newLucene(); - try - { + try { AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(false); Collection _data = data(); - for (int32_t d = 1; d <= NUM_DOCS; ++d) - { + for (int32_t d = 1; d <= NUM_DOCS; ++d) { DocumentPtr doc = newLucene(); - for (int32_t f = 1; f <= NUM_FIELDS; ++f) + for (int32_t f = 1; f <= NUM_FIELDS; ++f) { doc->add(newLucene(L"f" + StringUtils::toString(f), _data[f % _data.size()] + L"#" + _data[rand->nextInt(_data.size())], Field::STORE_YES, Field::INDEX_ANALYZED)); + } writer->addDocument(doc); } writer->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { boost::throw_exception(RuntimeException(L"Unexpected exception: " + e.getError())); } return dir; } - void doTest(Collection docs) - { + void doTest(Collection docs) { DirectoryPtr dir = makeIndex(); IndexReaderPtr reader = IndexReader::open(dir, true); HashSet _dataset = dataset(); - for (int32_t i = 0; i < docs.size(); ++i) - { + for (int32_t i = 0; i < docs.size(); ++i) { DocumentPtr d = reader->document(docs[i], SELECTOR()); d->get(MAGIC_FIELD()); Collection fields = d->getFields(); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { - try - { + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { + try { String fname = (*field)->name(); String fval = (*field)->stringValue(); EXPECT_TRUE(!fval.empty()); Collection vals = StringUtils::split(fval, L"#"); EXPECT_EQ(vals.size(), 2); - if (!_dataset.contains(vals[0]) || !_dataset.contains(vals[1])) + if (!_dataset.contains(vals[0]) || !_dataset.contains(vals[1])) { FAIL() << "FIELD:" << fname << ",VAL:" << fval; - } - catch (LuceneException& e) - { + } + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } @@ -166,17 +146,14 @@ const int32_t LazyBugTest::NUM_FIELDS = 100; /// Test demonstrating EOF bug on the last field of the last doc if other docs have already been accessed. -TEST_F(LazyBugTest, testLazyWorks) -{ +TEST_F(LazyBugTest, testLazyWorks) { doTest(newCollection(399)); } -TEST_F(LazyBugTest, testLazyAlsoWorks) -{ +TEST_F(LazyBugTest, testLazyAlsoWorks) { doTest(newCollection(399, 150)); } -TEST_F(LazyBugTest, testLazyBroken) -{ +TEST_F(LazyBugTest, testLazyBroken) { doTest(newCollection(150, 399)); } diff --git a/src/test/index/LazyProxSkippingTest.cpp b/src/test/index/LazyProxSkippingTest.cpp index 294fc7dc..fe2f87a1 100644 --- a/src/test/index/LazyProxSkippingTest.cpp +++ b/src/test/index/LazyProxSkippingTest.cpp @@ -28,16 +28,13 @@ using namespace Lucene; DECLARE_SHARED_PTR(SeeksCountingStream) /// Simply extends IndexInput in a way that we are able to count the number of invocations of seek() -class SeeksCountingStream : public IndexInput -{ +class SeeksCountingStream : public IndexInput { public: - SeeksCountingStream(const IndexInputPtr& input) - { + SeeksCountingStream(const IndexInputPtr& input) { this->input = input; } - virtual ~SeeksCountingStream() - { + virtual ~SeeksCountingStream() { } LUCENE_CLASS(SeeksCountingStream); @@ -46,52 +43,42 @@ class SeeksCountingStream : public IndexInput IndexInputPtr input; public: - virtual uint8_t readByte() - { + virtual uint8_t readByte() { return input->readByte(); } - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) - { + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) { input->readBytes(b, offset, length); } - virtual void close() - { + virtual void close() { input->close(); } - virtual int64_t getFilePointer() - { + virtual int64_t getFilePointer() { return input->getFilePointer(); } virtual void seek(int64_t pos); // implemented below - virtual int64_t length() - { + virtual int64_t length() { return input->length(); } - LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) - { + LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(input->clone())); } }; -class SeekCountingDirectory : public RAMDirectory -{ +class SeekCountingDirectory : public RAMDirectory { public: - virtual ~SeekCountingDirectory() - { + virtual ~SeekCountingDirectory() { } public: - virtual IndexInputPtr openInput(const String& name) - { + virtual IndexInputPtr openInput(const String& name) { IndexInputPtr ii = RAMDirectory::openInput(name); - if (boost::ends_with(name, L".prx")) - { + if (boost::ends_with(name, L".prx")) { // we decorate the proxStream with a wrapper class that allows to count the number of calls of seek() ii = newLucene(ii); } @@ -99,11 +86,9 @@ class SeekCountingDirectory : public RAMDirectory } }; -class LazyProxSkippingTest : public LuceneTestFixture -{ +class LazyProxSkippingTest : public LuceneTestFixture { public: - LazyProxSkippingTest() - { + LazyProxSkippingTest() { seeksCounter = 0; field = L"tokens"; term1 = L"xx"; @@ -111,8 +96,7 @@ class LazyProxSkippingTest : public LuceneTestFixture term3 = L"zz"; } - virtual ~LazyProxSkippingTest() - { + virtual ~LazyProxSkippingTest() { } protected: @@ -127,30 +111,23 @@ class LazyProxSkippingTest : public LuceneTestFixture static int32_t seeksCounter; public: - void createIndex(int32_t numHits) - { + void createIndex(int32_t numHits) { int32_t numDocs = 500; DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(false); writer->setMaxBufferedDocs(10); - for (int32_t i = 0; i < numDocs; ++i) - { + for (int32_t i = 0; i < numDocs; ++i) { DocumentPtr doc = newLucene(); String content; - if (i % (numDocs / numHits) == 0) - { + if (i % (numDocs / numHits) == 0) { // add a document that matches the query "term1 term2" content = term1 + L" " + term2; - } - else if (i % 15 == 0) - { + } else if (i % 15 == 0) { // add a document that only contains term1 content = term1 + L" " + term1; - } - else - { + } else { // add a document that contains term2 but not term 1 content = term3 + L" " + term2; } @@ -167,8 +144,7 @@ class LazyProxSkippingTest : public LuceneTestFixture searcher = newLucene(reader); } - Collection search() - { + Collection search() { // create PhraseQuery "term1 term2" and search PhraseQueryPtr pq = newLucene(); pq->add(newLucene(field, term1)); @@ -176,8 +152,7 @@ class LazyProxSkippingTest : public LuceneTestFixture return searcher->search(pq, FilterPtr(), 1000)->scoreDocs; } - void performTest(int32_t numHits) - { + void performTest(int32_t numHits) { createIndex(numHits); seeksCounter = 0; Collection hits = search(); @@ -192,27 +167,23 @@ class LazyProxSkippingTest : public LuceneTestFixture int32_t LazyProxSkippingTest::seeksCounter = 0; -void SeeksCountingStream::seek(int64_t pos) -{ +void SeeksCountingStream::seek(int64_t pos) { ++LazyProxSkippingTest::seeksCounter; input->seek(pos); } /// Tests lazy skipping on the proximity file. -TEST_F(LazyProxSkippingTest, testLazySkipping) -{ +TEST_F(LazyProxSkippingTest, testLazySkipping) { // test whether only the minimum amount of seeks() are performed performTest(5); performTest(10); } -TEST_F(LazyProxSkippingTest, testSeek) -{ +TEST_F(LazyProxSkippingTest, testSeek) { DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(field, L"a b", Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -222,15 +193,13 @@ TEST_F(LazyProxSkippingTest, testSeek) IndexReaderPtr reader = IndexReader::open(directory, true); TermPositionsPtr tp = reader->termPositions(); tp->seek(newLucene(field, L"b")); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { tp->next(); EXPECT_EQ(tp->doc(), i); EXPECT_EQ(tp->nextPosition(), 1); } tp->seek(newLucene(field, L"a")); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { tp->next(); EXPECT_EQ(tp->doc(), i); EXPECT_EQ(tp->nextPosition(), 0); diff --git a/src/test/index/MockIndexInput.cpp b/src/test/index/MockIndexInput.cpp index 86de16d0..1851e2cd 100644 --- a/src/test/index/MockIndexInput.cpp +++ b/src/test/index/MockIndexInput.cpp @@ -8,48 +8,42 @@ #include "MockIndexInput.h" #include "MiscUtils.h" -namespace Lucene -{ - MockIndexInput::MockIndexInput(ByteArray bytes) - { - buffer = bytes; - _length = bytes.size(); - pointer = 0; - } +namespace Lucene { - MockIndexInput::~MockIndexInput() - { - } +MockIndexInput::MockIndexInput(ByteArray bytes) { + buffer = bytes; + _length = bytes.size(); + pointer = 0; +} - void MockIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) - { - int32_t remainder = length; - int32_t start = pointer; - while (remainder != 0) - { - int32_t bufferOffset = start % buffer.size(); - int32_t bytesInBuffer = buffer.size() - bufferOffset; - int32_t bytesToCopy = bytesInBuffer >= remainder ? remainder : bytesInBuffer; - MiscUtils::arrayCopy(buffer.get(), bufferOffset, b, offset, bytesToCopy); - offset += bytesToCopy; - start += bytesToCopy; - remainder -= bytesToCopy; - } - pointer += length; - } +MockIndexInput::~MockIndexInput() { +} - void MockIndexInput::close() - { - // ignore +void MockIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length) { + int32_t remainder = length; + int32_t start = pointer; + while (remainder != 0) { + int32_t bufferOffset = start % buffer.size(); + int32_t bytesInBuffer = buffer.size() - bufferOffset; + int32_t bytesToCopy = bytesInBuffer >= remainder ? remainder : bytesInBuffer; + MiscUtils::arrayCopy(buffer.get(), bufferOffset, b, offset, bytesToCopy); + offset += bytesToCopy; + start += bytesToCopy; + remainder -= bytesToCopy; } + pointer += length; +} - void MockIndexInput::seekInternal(int64_t pos) - { - pointer = (int32_t)pos; - } +void MockIndexInput::close() { + // ignore +} + +void MockIndexInput::seekInternal(int64_t pos) { + pointer = (int32_t)pos; +} + +int64_t MockIndexInput::length() { + return _length; +} - int64_t MockIndexInput::length() - { - return _length; - } } diff --git a/src/test/index/MultiLevelSkipListTest.cpp b/src/test/index/MultiLevelSkipListTest.cpp index 3dd216f5..d152a0e3 100644 --- a/src/test/index/MultiLevelSkipListTest.cpp +++ b/src/test/index/MultiLevelSkipListTest.cpp @@ -30,16 +30,13 @@ using namespace Lucene; /// several other testcases. typedef LuceneTestFixture MultiLevelSkipListTest; -class MultiLevelSkipListPayloadFilter : public TokenFilter -{ +class MultiLevelSkipListPayloadFilter : public TokenFilter { public: - MultiLevelSkipListPayloadFilter(const TokenStreamPtr& input) : TokenFilter(input) - { + MultiLevelSkipListPayloadFilter(const TokenStreamPtr& input) : TokenFilter(input) { payloadAtt = addAttribute(); } - virtual ~MultiLevelSkipListPayloadFilter() - { + virtual ~MultiLevelSkipListPayloadFilter() { } LUCENE_CLASS(MultiLevelSkipListPayloadFilter); @@ -49,16 +46,13 @@ class MultiLevelSkipListPayloadFilter : public TokenFilter PayloadAttributePtr payloadAtt; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } - virtual bool incrementToken() - { + virtual bool incrementToken() { bool hasNext = input->incrementToken(); - if (hasNext) - { + if (hasNext) { ByteArray data = ByteArray::newInstance(1); data[0] = (uint8_t)(count++); payloadAtt->setPayload(newLucene(data)); @@ -69,34 +63,28 @@ class MultiLevelSkipListPayloadFilter : public TokenFilter int32_t MultiLevelSkipListPayloadFilter::count = 0; -class MultiLevelSkipListPayloadAnalyzer : public Analyzer -{ +class MultiLevelSkipListPayloadAnalyzer : public Analyzer { public: - virtual ~MultiLevelSkipListPayloadAnalyzer() - { + virtual ~MultiLevelSkipListPayloadAnalyzer() { } LUCENE_CLASS(MultiLevelSkipListPayloadAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } }; static int32_t counter = 0; -class CountingStream : public IndexInput -{ +class CountingStream : public IndexInput { public: - CountingStream(const IndexInputPtr& input) - { + CountingStream(const IndexInputPtr& input) { this->input = input; } - virtual ~CountingStream() - { + virtual ~CountingStream() { } LUCENE_CLASS(CountingStream); @@ -105,49 +93,42 @@ class CountingStream : public IndexInput IndexInputPtr input; public: - virtual uint8_t readByte() - { + virtual uint8_t readByte() { ++counter; return input->readByte(); } - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) - { + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) { counter += length; input->readBytes(b, offset, length); } - virtual void close() - { + virtual void close() { input->close(); } - virtual int64_t getFilePointer() - { + virtual int64_t getFilePointer() { return input->getFilePointer(); } - virtual void seek(int64_t pos) - { + virtual void seek(int64_t pos) { input->seek(pos); } - virtual int64_t length() - { + virtual int64_t length() { return input->length(); } - LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) - { + LuceneObjectPtr clone(const LuceneObjectPtr& other = LuceneObjectPtr()) { return newLucene(boost::dynamic_pointer_cast(input->clone())); } }; -static void checkSkipTo(const TermPositionsPtr& tp, int32_t target, int32_t maxCounter) -{ +static void checkSkipTo(const TermPositionsPtr& tp, int32_t target, int32_t maxCounter) { tp->skipTo(target); - if (maxCounter < counter) + if (maxCounter < counter) { FAIL() << "Too many bytes read: " << counter; + } EXPECT_EQ(target, tp->doc()); EXPECT_EQ(1, tp->freq()); @@ -157,13 +138,11 @@ static void checkSkipTo(const TermPositionsPtr& tp, int32_t target, int32_t maxC EXPECT_EQ((uint8_t)target, b[0]); } -TEST_F(MultiLevelSkipListTest, testSimpleSkip) -{ +TEST_F(MultiLevelSkipListTest, testSimpleSkip) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); TermPtr term = newLucene(L"test", L"a"); - for (int32_t i = 0; i < 5000; ++i) - { + for (int32_t i = 0; i < 5000; ++i) { DocumentPtr d1 = newLucene(); d1->add(newLucene(term->field(), term->text(), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(d1); @@ -177,8 +156,7 @@ TEST_F(MultiLevelSkipListTest, testSimpleSkip) SegmentTermPositionsPtr tp = boost::dynamic_pointer_cast(reader->termPositions()); tp->freqStream(newLucene(tp->freqStream())); - for (int32_t i = 0; i < 2; ++i) - { + for (int32_t i = 0; i < 2; ++i) { counter = 0; tp->seek(term); diff --git a/src/test/index/MultiReaderTest.cpp b/src/test/index/MultiReaderTest.cpp index 860508ab..79aadddb 100644 --- a/src/test/index/MultiReaderTest.cpp +++ b/src/test/index/MultiReaderTest.cpp @@ -26,11 +26,9 @@ using namespace Lucene; -class MultiReaderTest : public LuceneTestFixture, public DocHelper -{ +class MultiReaderTest : public LuceneTestFixture, public DocHelper { public: - MultiReaderTest() - { + MultiReaderTest() { readers = Collection::newInstance(2); dir = newLucene(); doc1 = newLucene(); @@ -43,8 +41,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper sis->read(dir); } - virtual ~MultiReaderTest() - { + virtual ~MultiReaderTest() { } protected: @@ -55,8 +52,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper SegmentInfosPtr sis; public: - void doTestDocument() - { + void doTestDocument() { sis->read(dir); IndexReaderPtr reader = openReader(); EXPECT_TRUE(reader); @@ -71,8 +67,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper checkNorms(reader); } - void doTestUndeleteAll() - { + void doTestUndeleteAll() { sis->read(dir); IndexReaderPtr reader = openReader(); EXPECT_TRUE(reader); @@ -86,8 +81,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper reader->commit(MapStringString()); reader->close(); - if (boost::dynamic_pointer_cast(reader)) - { + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } @@ -101,8 +95,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper reader->commit(MapStringString()); reader->close(); - if (boost::dynamic_pointer_cast(reader)) - { + if (boost::dynamic_pointer_cast(reader)) { // MultiReader does not "own" the directory so it does not write the changes to sis on commit sis->commit(dir); } @@ -113,8 +106,7 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper } protected: - IndexReaderPtr openReader() - { + IndexReaderPtr openReader() { sis->read(dir); SegmentReaderPtr reader1 = SegmentReader::get(false, sis->info(0), IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); SegmentReaderPtr reader2 = SegmentReader::get(false, sis->info(1), IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); @@ -132,31 +124,27 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper return reader; } - void checkNorms(const IndexReaderPtr& reader) - { - for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) - { - if ((*field)->isIndexed()) - { + void checkNorms(const IndexReaderPtr& reader) { + for (Collection::iterator field = DocHelper::fields.begin(); field != DocHelper::fields.end(); ++field) { + if ((*field)->isIndexed()) { EXPECT_EQ(reader->hasNorms((*field)->name()), !(*field)->getOmitNorms()); EXPECT_EQ(reader->hasNorms((*field)->name()), !DocHelper::noNorms.contains((*field)->name())); - if (!reader->hasNorms((*field)->name())) - { + if (!reader->hasNorms((*field)->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms((*field)->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); EXPECT_TRUE(!norms); norms = ByteArray::newInstance(reader->maxDoc()); reader->norms((*field)->name(), norms, 0); - for (int32_t j = 0; j < reader->maxDoc(); ++j) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { EXPECT_EQ(norms[j], norm1); + } } } } } - void addDoc(const RAMDirectoryPtr& ramDir1, const String& s, bool create) - { + void addDoc(const RAMDirectoryPtr& ramDir1, const String& s, bool create) { IndexWriterPtr iw = newLucene(ramDir1, newLucene(LuceneVersion::LUCENE_CURRENT), create, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"body", s, Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -165,14 +153,12 @@ class MultiReaderTest : public LuceneTestFixture, public DocHelper } }; -TEST_F(MultiReaderTest, testTestMultiReader) -{ +TEST_F(MultiReaderTest, testTestMultiReader) { doTestDocument(); doTestUndeleteAll(); } -TEST_F(MultiReaderTest, testIsCurrent) -{ +TEST_F(MultiReaderTest, testIsCurrent) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); RAMDirectoryPtr ramDir2 = newLucene(); @@ -183,19 +169,15 @@ TEST_F(MultiReaderTest, testIsCurrent) EXPECT_TRUE(!mr->isCurrent()); // has been modified, not current anymore addDoc(ramDir2, L"even more text", false); EXPECT_TRUE(!mr->isCurrent()); // has been modified even more, not current anymore - try - { + try { mr->getVersion(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::UnsupportedOperation)(e)); } mr->close(); } -TEST_F(MultiReaderTest, testMultiTermDocs) -{ +TEST_F(MultiReaderTest, testMultiTermDocs) { RAMDirectoryPtr ramDir1 = newLucene(); addDoc(ramDir1, L"test foo", true); RAMDirectoryPtr ramDir2 = newLucene(); @@ -216,8 +198,9 @@ TEST_F(MultiReaderTest, testMultiTermDocs) int32_t ret = 0; // This should blow up if we forget to check that the TermEnum is from the same reader as the TermDocs. - while (td2->next()) + while (td2->next()) { ret += td2->doc(); + } td2->close(); te3->close(); @@ -225,13 +208,11 @@ TEST_F(MultiReaderTest, testMultiTermDocs) EXPECT_TRUE(ret > 0); } -TEST_F(MultiReaderTest, testAllTermDocs) -{ +TEST_F(MultiReaderTest, testAllTermDocs) { IndexReaderPtr reader = openReader(); int32_t NUM_DOCS = 2; TermDocsPtr td = reader->termDocs(TermPtr()); - for (int32_t i = 0; i < NUM_DOCS; ++i) - { + for (int32_t i = 0; i < NUM_DOCS; ++i) { EXPECT_TRUE(td->next()); EXPECT_EQ(i, td->doc()); EXPECT_EQ(1, td->freq()); diff --git a/src/test/index/NRTReaderWithThreadsTest.cpp b/src/test/index/NRTReaderWithThreadsTest.cpp index c550bbe5..8bf0742d 100644 --- a/src/test/index/NRTReaderWithThreadsTest.cpp +++ b/src/test/index/NRTReaderWithThreadsTest.cpp @@ -26,8 +26,7 @@ typedef LuceneTestFixture NRTReaderWithThreadsTest; DECLARE_SHARED_PTR(RunThread) DECLARE_SHARED_PTR(HeavyAtomicInt) -static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t numFields) -{ +static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t numFields) { StringStream sb; DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(n), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); @@ -35,17 +34,16 @@ static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t nu sb << L"a" << n; doc->add(newLucene(L"field1", sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); sb << L" b" << n; - for (int32_t i = 1; i < numFields; ++i) + for (int32_t i = 1; i < numFields; ++i) { doc->add(newLucene(L"field" + StringUtils::toString(i + 1), sb.str(), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); + } return doc; } -static int32_t count(const TermPtr& t, const IndexReaderPtr& r) -{ +static int32_t count(const TermPtr& t, const IndexReaderPtr& r) { int32_t count = 0; TermDocsPtr td = r->termDocs(t); - while (td->next()) - { + while (td->next()) { td->doc(); ++count; } @@ -53,16 +51,13 @@ static int32_t count(const TermPtr& t, const IndexReaderPtr& r) return count; } -class HeavyAtomicInt : public LuceneObject -{ +class HeavyAtomicInt : public LuceneObject { public: - HeavyAtomicInt(int32_t start) - { + HeavyAtomicInt(int32_t start) { value = start; } - virtual ~HeavyAtomicInt() - { + virtual ~HeavyAtomicInt() { } @@ -70,31 +65,26 @@ class HeavyAtomicInt : public LuceneObject int32_t value; public: - int32_t addAndGet(int32_t inc) - { + int32_t addAndGet(int32_t inc) { SyncLock syncLock(this); value += inc; return value; } - int32_t incrementAndGet() - { + int32_t incrementAndGet() { SyncLock syncLock(this); return ++value; } - int32_t intValue() - { + int32_t intValue() { SyncLock syncLock(this); return value; } }; -class RunThread : public LuceneThread -{ +class RunThread : public LuceneThread { public: - RunThread(int32_t type, const IndexWriterPtr& writer, const HeavyAtomicIntPtr& seq) - { + RunThread(int32_t type, const IndexWriterPtr& writer, const HeavyAtomicIntPtr& seq) { this->_run = true; this->delCount = 0; this->addCount = 0; @@ -104,8 +94,7 @@ class RunThread : public LuceneThread this->rand = newLucene(); } - virtual ~RunThread() - { + virtual ~RunThread() { } LUCENE_CLASS(RunThread); @@ -120,21 +109,15 @@ class RunThread : public LuceneThread RandomPtr rand; public: - virtual void run() - { - try - { - while (_run) - { - if (type == 0) - { + virtual void run() { + try { + while (_run) { + if (type == 0) { int32_t i = seq->addAndGet(1); DocumentPtr doc = createDocument(i, L"index1", 10); writer->addDocument(doc); ++addCount; - } - else - { + } else { // we may or may not delete because the term may not exist, // however we're opening and closing the reader rapidly IndexReaderPtr reader = writer->getReader(); @@ -146,17 +129,14 @@ class RunThread : public LuceneThread delCount += _count; } } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { _run = false; FAIL() << "Unexpected exception: " << e.getError(); } } }; -TEST_F(NRTReaderWithThreadsTest, testIndexing) -{ +TEST_F(NRTReaderWithThreadsTest, testIndexing) { HeavyAtomicIntPtr seq = newLucene(1); DirectoryPtr mainDir = newLucene(); IndexWriterPtr writer = newLucene(mainDir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); @@ -166,25 +146,25 @@ TEST_F(NRTReaderWithThreadsTest, testIndexing) writer->setMergeFactor(2); writer->setMaxBufferedDocs(10); Collection indexThreads = Collection::newInstance(4); - for (int32_t x = 0; x < indexThreads.size(); ++x) - { + for (int32_t x = 0; x < indexThreads.size(); ++x) { indexThreads[x] = newLucene(x % 2, writer, seq); indexThreads[x]->start(); } int64_t startTime = MiscUtils::currentTimeMillis(); int64_t duration = 5 * 1000; - while (((int64_t)MiscUtils::currentTimeMillis() - startTime) < duration) + while (((int64_t)MiscUtils::currentTimeMillis() - startTime) < duration) { LuceneThread::threadSleep(100); + } int32_t delCount = 0; int32_t addCount = 0; - for (int32_t x = 0; x < indexThreads.size(); ++x) - { + for (int32_t x = 0; x < indexThreads.size(); ++x) { indexThreads[x]->_run = false; addCount += indexThreads[x]->addCount; delCount += indexThreads[x]->delCount; } - for (int32_t x = 0; x < indexThreads.size(); ++x) + for (int32_t x = 0; x < indexThreads.size(); ++x) { indexThreads[x]->join(); + } writer->close(); mainDir->close(); } diff --git a/src/test/index/NormsTest.cpp b/src/test/index/NormsTest.cpp index c9614420..8212e3bc 100644 --- a/src/test/index/NormsTest.cpp +++ b/src/test/index/NormsTest.cpp @@ -18,36 +18,30 @@ using namespace Lucene; -class SimilarityOne : public DefaultSimilarity -{ +class SimilarityOne : public DefaultSimilarity { public: - virtual ~SimilarityOne() - { + virtual ~SimilarityOne() { } LUCENE_CLASS(SimilarityOne); public: - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } }; /// Test that norms info is preserved during index life - including separate norms, addDocument, addIndexesNoOptimize, optimize. -class NormsTest : public LuceneTestFixture -{ +class NormsTest : public LuceneTestFixture { public: - NormsTest() - { + NormsTest() { similarityOne = newLucene(); lastNorm = 0.0; normDelta = 0.001; numDocNorms = 0; } - virtual ~NormsTest() - { + virtual ~NormsTest() { } protected: @@ -63,20 +57,16 @@ class NormsTest : public LuceneTestFixture public: /// return unique norm values that are unchanged by encoding/decoding - double nextNorm() - { + double nextNorm() { double norm = lastNorm + normDelta; - do - { + do { double norm1 = Similarity::decodeNorm(Similarity::encodeNorm(norm)); - if (norm1 > lastNorm) - { + if (norm1 > lastNorm) { norm = norm1; break; } norm += normDelta; - } - while (true); + } while (true); norms.add(numDocNorms, norm); modifiedNorms.add(numDocNorms, norm); ++numDocNorms; @@ -85,12 +75,10 @@ class NormsTest : public LuceneTestFixture } /// create the next document - DocumentPtr newDoc() - { + DocumentPtr newDoc() { DocumentPtr d = newLucene(); double boost = nextNorm(); - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { FieldPtr f = newLucene(L"f" + StringUtils::toString(i), L"v" + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_NOT_ANALYZED); f->setBoost(boost); d->add(f); @@ -98,17 +86,14 @@ class NormsTest : public LuceneTestFixture return d; } - void verifyIndex(const DirectoryPtr& dir) - { + void verifyIndex(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); - for (int32_t i = 0; i < NUM_FIELDS; ++i) - { + for (int32_t i = 0; i < NUM_FIELDS; ++i) { String field = L"f" + StringUtils::toString(i); ByteArray b = ir->norms(field); EXPECT_EQ(numDocNorms, b.size()); Collection storedNorms = (i == 1 ? modifiedNorms : norms); - for (int32_t j = 0; j < b.size(); ++j) - { + for (int32_t j = 0; j < b.size(); ++j) { double norm = Similarity::decodeNorm(b[j]); double norm1 = storedNorms[j]; EXPECT_EQ(norm, norm1); // 0.000001 @@ -116,24 +101,22 @@ class NormsTest : public LuceneTestFixture } } - void addDocs(const DirectoryPtr& dir, int32_t ndocs, bool compound) - { + void addDocs(const DirectoryPtr& dir, int32_t ndocs, bool compound) { IndexWriterPtr iw = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), false, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); iw->setMergeFactor(3); iw->setSimilarity(similarityOne); iw->setUseCompoundFile(compound); - for (int32_t i = 0; i < ndocs; ++i) + for (int32_t i = 0; i < ndocs; ++i) { iw->addDocument(newDoc()); + } iw->close(); } - void modifyNormsForF1(const DirectoryPtr& dir) - { + void modifyNormsForF1(const DirectoryPtr& dir) { IndexReaderPtr ir = IndexReader::open(dir, false); int32_t n = ir->maxDoc(); - for (int32_t i = 0; i < n; i += 3) // modify for every third doc - { + for (int32_t i = 0; i < n; i += 3) { // modify for every third doc int32_t k = (i * 3) % modifiedNorms.size(); double origNorm = modifiedNorms[i]; double newNorm = modifiedNorms[k]; @@ -145,10 +128,8 @@ class NormsTest : public LuceneTestFixture ir->close(); } - void doTestNorms(const DirectoryPtr& dir) - { - for (int32_t i = 0; i < 5; ++i) - { + void doTestNorms(const DirectoryPtr& dir) { + for (int32_t i = 0; i < 5; ++i) { addDocs(dir, 12, true); verifyIndex(dir); modifyNormsForF1(dir); @@ -160,8 +141,7 @@ class NormsTest : public LuceneTestFixture } } - void createIndex(const DirectoryPtr& dir) - { + void createIndex(const DirectoryPtr& dir) { IndexWriterPtr iw = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); iw->setMaxBufferedDocs(5); iw->setMergeFactor(3); @@ -177,8 +157,7 @@ const int32_t NormsTest::NUM_FIELDS = 10; /// Including separate norms. /// Including merging indexes with separate norms. /// Including optimize. -TEST_F(NormsTest, testNorms) -{ +TEST_F(NormsTest, testNorms) { // test with a single index: index1 String indexDir1(FileUtils::joinPath(getTempDir(), L"lucenetestindex1")); DirectoryPtr dir1 = FSDirectory::open(indexDir1); diff --git a/src/test/index/OmitTfTest.cpp b/src/test/index/OmitTfTest.cpp index d8fddcbb..618c1dda 100644 --- a/src/test/index/OmitTfTest.cpp +++ b/src/test/index/OmitTfTest.cpp @@ -31,85 +31,69 @@ typedef LuceneTestFixture OmitTfTest; DECLARE_SHARED_PTR(CountingHitCollector) -class SimpleIDFExplanation : public IDFExplanation -{ +class SimpleIDFExplanation : public IDFExplanation { public: - virtual ~SimpleIDFExplanation() - { + virtual ~SimpleIDFExplanation() { } LUCENE_CLASS(SimpleIDFExplanation); public: - virtual double getIdf() - { + virtual double getIdf() { return 1.0; } - virtual String explain() - { + virtual String explain() { return L"Inexplicable"; } }; -class SimpleSimilarity : public Similarity -{ +class SimpleSimilarity : public Similarity { public: - virtual ~SimpleSimilarity() - { + virtual ~SimpleSimilarity() { } LUCENE_CLASS(SimpleSimilarity); public: - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - virtual double queryNorm(double sumOfSquaredWeights) - { + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - virtual double tf(double freq) - { + virtual double tf(double freq) { return freq; } - virtual double sloppyFreq(int32_t distance) - { + virtual double sloppyFreq(int32_t distance) { return 2.0; } - virtual double idf(int32_t docFreq, int32_t numDocs) - { + virtual double idf(int32_t docFreq, int32_t numDocs) { return 1.0; } - virtual double coord(int32_t overlap, int32_t maxOverlap) - { + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) - { + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) { return newLucene(); } }; -class CountingHitCollector : public Collector -{ +class CountingHitCollector : public Collector { public: - CountingHitCollector() - { + CountingHitCollector() { count = 0; sum = 0; docBase = -1; } - virtual ~CountingHitCollector() - { + virtual ~CountingHitCollector() { } LUCENE_CLASS(CountingHitCollector); @@ -122,37 +106,32 @@ class CountingHitCollector : public Collector int32_t docBase; public: - virtual void setScorer(const ScorerPtr& scorer) - { + virtual void setScorer(const ScorerPtr& scorer) { } - virtual void collect(int32_t doc) - { + virtual void collect(int32_t doc) { ++count; sum += doc + docBase; // use it to avoid any possibility of being optimized away } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } - virtual bool acceptsDocsOutOfOrder() - { + virtual bool acceptsDocsOutOfOrder() { return true; } }; -static void checkNoPrx(const DirectoryPtr& dir) -{ +static void checkNoPrx(const DirectoryPtr& dir) { HashSet files = dir->listAll(); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { EXPECT_TRUE(!boost::ends_with(*file, L".prx")); + } } /// Tests whether the DocumentWriter correctly enable the omitTermFreqAndPositions bit in the FieldInfo -TEST_F(OmitTfTest, testOmitTermFreqAndPositions) -{ +TEST_F(OmitTfTest, testOmitTermFreqAndPositions) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); IndexWriterPtr writer = newLucene(ram, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -196,8 +175,7 @@ TEST_F(OmitTfTest, testOmitTermFreqAndPositions) } /// Tests whether merging of docs that have different omitTermFreqAndPositions for the same field works -TEST_F(OmitTfTest, testMixedMerge) -{ +TEST_F(OmitTfTest, testMixedMerge) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); IndexWriterPtr writer = newLucene(ram, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -214,8 +192,9 @@ TEST_F(OmitTfTest, testMixedMerge) f2->setOmitTermFreqAndPositions(true); d->add(f2); - for (int32_t i = 0; i < 30; ++i) + for (int32_t i = 0; i < 30; ++i) { writer->addDocument(d); + } // now we add another document which has term freq for field f2 and not for f1 and verify if the SegmentMerger keep things constant d = newLucene(); @@ -227,8 +206,9 @@ TEST_F(OmitTfTest, testMixedMerge) f2->setOmitTermFreqAndPositions(false); d->add(f2); - for (int32_t i = 0; i < 30; ++i) + for (int32_t i = 0; i < 30; ++i) { writer->addDocument(d); + } // force merge writer->optimize(); @@ -248,8 +228,7 @@ TEST_F(OmitTfTest, testMixedMerge) /// Make sure first adding docs that do not omitTermFreqAndPositions for field X, then adding docs that do /// omitTermFreqAndPositions for that same field -TEST_F(OmitTfTest, testMixedRAM) -{ +TEST_F(OmitTfTest, testMixedRAM) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); IndexWriterPtr writer = newLucene(ram, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -265,13 +244,15 @@ TEST_F(OmitTfTest, testMixedRAM) FieldPtr f2 = newLucene(L"f2", L"This field has NO Tf in all docs", Field::STORE_NO, Field::INDEX_ANALYZED); d->add(f2); - for (int32_t i = 0; i < 5; ++i) + for (int32_t i = 0; i < 5; ++i) { writer->addDocument(d); + } f2->setOmitTermFreqAndPositions(true); - for (int32_t i = 0; i < 20; ++i) + for (int32_t i = 0; i < 20; ++i) { writer->addDocument(d); + } // force merge writer->optimize(); @@ -291,8 +272,7 @@ TEST_F(OmitTfTest, testMixedRAM) } /// Verifies no *.prx exists when all fields omit term freq -TEST_F(OmitTfTest, testNoPrxFile) -{ +TEST_F(OmitTfTest, testNoPrxFile) { DirectoryPtr ram = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); IndexWriterPtr writer = newLucene(ram, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -306,8 +286,9 @@ TEST_F(OmitTfTest, testNoPrxFile) f1->setOmitTermFreqAndPositions(true); d->add(f1); - for (int32_t i = 0; i < 30; ++i) + for (int32_t i = 0; i < 30; ++i) { writer->addDocument(d); + } writer->commit(); @@ -323,85 +304,73 @@ TEST_F(OmitTfTest, testNoPrxFile) ram->close(); } -namespace TestBasic -{ - class CountingHitCollectorQ1 : public CountingHitCollector - { - protected: - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - EXPECT_EQ(scorer->score(), 1.0); - CountingHitCollector::collect(doc); - } - }; - - class CountingHitCollectorQ2 : public CountingHitCollector - { - protected: - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - EXPECT_EQ(scorer->score(), 1.0 + (double)doc); - CountingHitCollector::collect(doc); - } - }; - - class CountingHitCollectorQ3 : public CountingHitCollector - { - protected: - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - EXPECT_EQ(scorer->score(), 1.0); - EXPECT_NE(doc % 2, 0); - CountingHitCollector::collect(doc); - } - }; - - class CountingHitCollectorQ4 : public CountingHitCollector - { - protected: - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - EXPECT_EQ(scorer->score(), 1.0); - EXPECT_EQ(doc % 2, 0); - CountingHitCollector::collect(doc); - } - }; +namespace TestBasic { + +class CountingHitCollectorQ1 : public CountingHitCollector { +protected: + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + EXPECT_EQ(scorer->score(), 1.0); + CountingHitCollector::collect(doc); + } +}; + +class CountingHitCollectorQ2 : public CountingHitCollector { +protected: + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + EXPECT_EQ(scorer->score(), 1.0 + (double)doc); + CountingHitCollector::collect(doc); + } +}; + +class CountingHitCollectorQ3 : public CountingHitCollector { +protected: + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + EXPECT_EQ(scorer->score(), 1.0); + EXPECT_NE(doc % 2, 0); + CountingHitCollector::collect(doc); + } +}; + +class CountingHitCollectorQ4 : public CountingHitCollector { +protected: + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + EXPECT_EQ(scorer->score(), 1.0); + EXPECT_EQ(doc % 2, 0); + CountingHitCollector::collect(doc); + } +}; + } -TEST_F(OmitTfTest, testBasic) -{ +TEST_F(OmitTfTest, testBasic) { DirectoryPtr dir = newLucene(); AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -411,8 +380,7 @@ TEST_F(OmitTfTest, testBasic) writer->setSimilarity(newLucene()); StringStream sb; - for (int32_t i = 0; i < 30; ++i) - { + for (int32_t i = 0; i < 30; ++i) { DocumentPtr d = newLucene(); sb << L"term "; String content = sb.str(); diff --git a/src/test/index/ParallelReaderEmptyIndexTest.cpp b/src/test/index/ParallelReaderEmptyIndexTest.cpp index ad196e3e..973a00d1 100644 --- a/src/test/index/ParallelReaderEmptyIndexTest.cpp +++ b/src/test/index/ParallelReaderEmptyIndexTest.cpp @@ -21,8 +21,7 @@ typedef LuceneTestFixture ParallelReaderEmptyIndexTest; /// Creates two empty indexes and wraps a ParallelReader around. /// Adding this reader to a new index should not throw any exception. -TEST_F(ParallelReaderEmptyIndexTest, testEmptyIndex) -{ +TEST_F(ParallelReaderEmptyIndexTest, testEmptyIndex) { RAMDirectoryPtr rd1 = newLucene(); IndexWriterPtr iw = newLucene(rd1, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); iw->close(); @@ -47,8 +46,7 @@ TEST_F(ParallelReaderEmptyIndexTest, testEmptyIndex) /// This method creates an empty index (numFields=0, numDocs=0) but is marked to have TermVectors. /// Adding this index to another index should not throw any exception. -TEST_F(ParallelReaderEmptyIndexTest, testEmptyIndexWithVectors) -{ +TEST_F(ParallelReaderEmptyIndexTest, testEmptyIndexWithVectors) { RAMDirectoryPtr rd1 = newLucene(); { IndexWriterPtr iw = newLucene(rd1, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); diff --git a/src/test/index/ParallelReaderTest.cpp b/src/test/index/ParallelReaderTest.cpp index 3733aba8..75e64395 100644 --- a/src/test/index/ParallelReaderTest.cpp +++ b/src/test/index/ParallelReaderTest.cpp @@ -25,17 +25,14 @@ using namespace Lucene; -class ParallelReaderTest : public LuceneTestFixture -{ +class ParallelReaderTest : public LuceneTestFixture { public: - ParallelReaderTest() - { + ParallelReaderTest() { single = createSingle(); parallel = createParallel(); } - virtual ~ParallelReaderTest() - { + virtual ~ParallelReaderTest() { } public: @@ -44,8 +41,7 @@ class ParallelReaderTest : public LuceneTestFixture public: /// Fields 1-4 indexed together - SearcherPtr createSingle() - { + SearcherPtr createSingle() { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr d1 = newLucene(); @@ -65,8 +61,7 @@ class ParallelReaderTest : public LuceneTestFixture } /// Fields 1 & 2 in one index, 3 & 4 in other, with ParallelReader - SearcherPtr createParallel() - { + SearcherPtr createParallel() { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); ParallelReaderPtr pr = newLucene(); @@ -75,8 +70,7 @@ class ParallelReaderTest : public LuceneTestFixture return newLucene(pr); } - DirectoryPtr getDir1() - { + DirectoryPtr getDir1() { DirectoryPtr dir1 = newLucene(); IndexWriterPtr w1 = newLucene(dir1, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr d1 = newLucene(); @@ -91,8 +85,7 @@ class ParallelReaderTest : public LuceneTestFixture return dir1; } - DirectoryPtr getDir2() - { + DirectoryPtr getDir2() { DirectoryPtr dir2 = newLucene(); IndexWriterPtr w2 = newLucene(dir2, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr d3 = newLucene(); @@ -107,13 +100,11 @@ class ParallelReaderTest : public LuceneTestFixture return dir2; } - void queryTest(const QueryPtr& query) - { + void queryTest(const QueryPtr& query) { Collection parallelHits = parallel->search(query, FilterPtr(), 1000)->scoreDocs; Collection singleHits = single->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(parallelHits.size(), singleHits.size()); - for (int32_t i = 0; i < parallelHits.size(); ++i) - { + for (int32_t i = 0; i < parallelHits.size(); ++i) { EXPECT_NEAR(parallelHits[i]->score, singleHits[i]->score, 0.001); DocumentPtr docParallel = parallel->doc(parallelHits[i]->doc); DocumentPtr docSingle = single->doc(singleHits[i]->doc); @@ -125,8 +116,7 @@ class ParallelReaderTest : public LuceneTestFixture } }; -TEST_F(ParallelReaderTest, testQueries) -{ +TEST_F(ParallelReaderTest, testQueries) { queryTest(newLucene(newLucene(L"f1", L"v1"))); queryTest(newLucene(newLucene(L"f2", L"v1"))); queryTest(newLucene(newLucene(L"f2", L"v2"))); @@ -141,8 +131,7 @@ TEST_F(ParallelReaderTest, testQueries) queryTest(bq1); } -TEST_F(ParallelReaderTest, testFieldNames) -{ +TEST_F(ParallelReaderTest, testFieldNames) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); ParallelReaderPtr pr = newLucene(); @@ -156,8 +145,7 @@ TEST_F(ParallelReaderTest, testFieldNames) EXPECT_TRUE(fieldNames.contains(L"f4")); } -TEST_F(ParallelReaderTest, testDocument) -{ +TEST_F(ParallelReaderTest, testDocument) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); ParallelReaderPtr pr = newLucene(); @@ -182,8 +170,7 @@ TEST_F(ParallelReaderTest, testDocument) EXPECT_EQ(L"v2", doc223->get(L"f3")); } -TEST_F(ParallelReaderTest, testIncompatibleIndexes) -{ +TEST_F(ParallelReaderTest, testIncompatibleIndexes) { // two documents DirectoryPtr dir1 = getDir1(); @@ -198,18 +185,14 @@ TEST_F(ParallelReaderTest, testIncompatibleIndexes) ParallelReaderPtr pr = newLucene(); pr->add(IndexReader::open(dir1, false)); - try - { + try { pr->add(IndexReader::open(dir2, false)); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } -TEST_F(ParallelReaderTest, testIsCurrent) -{ +TEST_F(ParallelReaderTest, testIsCurrent) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); ParallelReaderPtr pr = newLucene(); @@ -232,8 +215,7 @@ TEST_F(ParallelReaderTest, testIsCurrent) EXPECT_TRUE(!pr->isCurrent()); } -TEST_F(ParallelReaderTest, testIsOptimized) -{ +TEST_F(ParallelReaderTest, testIsOptimized) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); @@ -279,8 +261,7 @@ TEST_F(ParallelReaderTest, testIsOptimized) pr->close(); } -TEST_F(ParallelReaderTest, testAllTermDocs) -{ +TEST_F(ParallelReaderTest, testAllTermDocs) { DirectoryPtr dir1 = getDir1(); DirectoryPtr dir2 = getDir2(); @@ -289,8 +270,7 @@ TEST_F(ParallelReaderTest, testAllTermDocs) pr->add(IndexReader::open(dir2, false)); int32_t NUM_DOCS = 2; TermDocsPtr td = pr->termDocs(TermPtr()); - for (int32_t i = 0; i < NUM_DOCS; ++i) - { + for (int32_t i = 0; i < NUM_DOCS; ++i) { EXPECT_TRUE(td->next()); EXPECT_EQ(i, td->doc()); EXPECT_EQ(1, td->freq()); diff --git a/src/test/index/ParallelTermEnumTest.cpp b/src/test/index/ParallelTermEnumTest.cpp index e02f52c2..aabd337c 100644 --- a/src/test/index/ParallelTermEnumTest.cpp +++ b/src/test/index/ParallelTermEnumTest.cpp @@ -20,11 +20,9 @@ using namespace Lucene; -class ParallelTermEnumTest : public LuceneTestFixture -{ +class ParallelTermEnumTest : public LuceneTestFixture { public: - ParallelTermEnumTest() - { + ParallelTermEnumTest() { RAMDirectoryPtr rd1 = newLucene(); IndexWriterPtr iw1 = newLucene(rd1, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -50,8 +48,7 @@ class ParallelTermEnumTest : public LuceneTestFixture this->ir2 = IndexReader::open(rd2, true); } - virtual ~ParallelTermEnumTest() - { + virtual ~ParallelTermEnumTest() { ir1->close(); ir2->close(); } @@ -61,8 +58,7 @@ class ParallelTermEnumTest : public LuceneTestFixture IndexReaderPtr ir2; }; -TEST_F(ParallelTermEnumTest, testParallelTermEnum) -{ +TEST_F(ParallelTermEnumTest, testParallelTermEnum) { ParallelReaderPtr pr = newLucene(); pr->add(ir1); pr->add(ir2); diff --git a/src/test/index/PayloadsTest.cpp b/src/test/index/PayloadsTest.cpp index 1e1a0aef..979b80e6 100644 --- a/src/test/index/PayloadsTest.cpp +++ b/src/test/index/PayloadsTest.cpp @@ -39,19 +39,16 @@ DECLARE_SHARED_PTR(PayloadData) DECLARE_SHARED_PTR(PayloadFilter) DECLARE_SHARED_PTR(PayloadAnalyzer) -class PayloadData : public LuceneObject -{ +class PayloadData : public LuceneObject { public: - PayloadData(int32_t skip, ByteArray data, int32_t offset, int32_t length) - { + PayloadData(int32_t skip, ByteArray data, int32_t offset, int32_t length) { this->numFieldInstancesToSkip = skip; this->data = data; this->offset = offset; this->length = length; } - virtual ~PayloadData() - { + virtual ~PayloadData() { } LUCENE_CLASS(PayloadData); @@ -64,11 +61,9 @@ class PayloadData : public LuceneObject }; /// This Filter adds payloads to the tokens. -class PayloadFilter : public TokenFilter -{ +class PayloadFilter : public TokenFilter { public: - PayloadFilter(const TokenStreamPtr& in, ByteArray data, int32_t offset, int32_t length) : TokenFilter(in) - { + PayloadFilter(const TokenStreamPtr& in, ByteArray data, int32_t offset, int32_t length) : TokenFilter(in) { this->payload = newLucene(); this->data = data; this->length = length; @@ -76,8 +71,7 @@ class PayloadFilter : public TokenFilter this->payloadAtt = addAttribute(); } - virtual ~PayloadFilter() - { + virtual ~PayloadFilter() { } LUCENE_CLASS(PayloadFilter); @@ -90,36 +84,30 @@ class PayloadFilter : public TokenFilter PayloadAttributePtr payloadAtt; public: - virtual bool incrementToken() - { + virtual bool incrementToken() { bool hasNext = input->incrementToken(); - if (hasNext) - { - if (offset + length <= data.size()) - { + if (hasNext) { + if (offset + length <= data.size()) { PayloadPtr p = newLucene(); payloadAtt->setPayload(p); p->setData(data, offset, length); offset += length; - } - else + } else { payloadAtt->setPayload(PayloadPtr()); + } } return hasNext; } }; /// This Analyzer uses an WhitespaceTokenizer and PayloadFilter. -class PayloadAnalyzer : public Analyzer -{ +class PayloadAnalyzer : public Analyzer { public: - PayloadAnalyzer() - { + PayloadAnalyzer() { fieldToData = HashMap::newInstance(); } - virtual ~PayloadAnalyzer() - { + virtual ~PayloadAnalyzer() { } LUCENE_CLASS(PayloadAnalyzer); @@ -128,55 +116,49 @@ class PayloadAnalyzer : public Analyzer HashMap fieldToData; public: - void setPayloadData(const String& field, ByteArray data, int32_t offset, int32_t length) - { + void setPayloadData(const String& field, ByteArray data, int32_t offset, int32_t length) { fieldToData.put(field, newLucene(0, data, offset, length)); } - void setPayloadData(const String& field, int32_t numFieldInstancesToSkip, ByteArray data, int32_t offset, int32_t length) - { + void setPayloadData(const String& field, int32_t numFieldInstancesToSkip, ByteArray data, int32_t offset, int32_t length) { PayloadDataPtr payload = newLucene(numFieldInstancesToSkip, data, offset, length); fieldToData.put(field, payload); } - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { PayloadDataPtr payload = fieldToData.get(fieldName); TokenStreamPtr ts = newLucene(reader); - if (payload) - { - if (payload->numFieldInstancesToSkip == 0) + if (payload) { + if (payload->numFieldInstancesToSkip == 0) { ts = newLucene(ts, payload->data, payload->offset, payload->length); - else + } else { --payload->numFieldInstancesToSkip; + } } return ts; } }; -static void generateRandomData(ByteArray data) -{ +static void generateRandomData(ByteArray data) { std::generate(data.get(), data.get() + data.size(), rand); } -static ByteArray generateRandomData(int32_t n) -{ +static ByteArray generateRandomData(int32_t n) { ByteArray data(ByteArray::newInstance(n)); generateRandomData(data); return data; } -static Collection generateTerms(const String& fieldName, int32_t n) -{ +static Collection generateTerms(const String& fieldName, int32_t n) { int32_t maxDigits = (int32_t)(std::log((double)n) / std::log(10.0)); Collection terms = Collection::newInstance(n); - for (int32_t i = 0; i < n; ++i) - { + for (int32_t i = 0; i < n; ++i) { StringStream sb; sb << L"t"; int32_t zeros = maxDigits - (int32_t)(std::log((double)i) / std::log(10.0)); - for (int32_t j = 0; j < zeros; ++j) + for (int32_t j = 0; j < zeros; ++j) { sb << L"0"; + } sb << i; terms[i] = newLucene(fieldName, sb.str()); } @@ -184,8 +166,7 @@ static Collection generateTerms(const String& fieldName, int32_t n) } /// Simple tests to test the Payload class -TEST_F(PayloadsTest, testPayload) -{ +TEST_F(PayloadsTest, testPayload) { ByteArray testData(ByteArray::newInstance(15)); uint8_t input[15] = { 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '!' }; std::memcpy(testData.get(), input, 15); @@ -194,47 +175,43 @@ TEST_F(PayloadsTest, testPayload) // test copyTo() ByteArray target(ByteArray::newInstance(testData.size() - 1)); - try - { + try { payload->copyTo(target, 0); - } - catch (IndexOutOfBoundsException& e) - { + } catch (IndexOutOfBoundsException& e) { EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); } target.resize(testData.size() + 3); payload->copyTo(target, 3); - for (int32_t i = 0; i < testData.size(); ++i) + for (int32_t i = 0; i < testData.size(); ++i) { EXPECT_EQ(testData[i], target[i + 3]); + } // test toByteArray() target = payload->toByteArray(); EXPECT_TRUE(testData.equals(target)); // test byteAt() - for (int32_t i = 0; i < testData.size(); ++i) + for (int32_t i = 0; i < testData.size(); ++i) { EXPECT_EQ(payload->byteAt(i), testData[i]); + } - try - { + try { payload->byteAt(testData.size() + 1); - } - catch (IndexOutOfBoundsException& e) - { + } catch (IndexOutOfBoundsException& e) { EXPECT_TRUE(check_exception(LuceneException::IndexOutOfBounds)(e)); } PayloadPtr clone = boost::dynamic_pointer_cast(payload->clone()); EXPECT_EQ(payload->length(), clone->length()); - for (int32_t i = 0; i < payload->length(); ++i) + for (int32_t i = 0; i < payload->length(); ++i) { EXPECT_EQ(payload->byteAt(i), clone->byteAt(i)); + } } /// Tests whether the DocumentWriter and SegmentMerger correctly enable the payload bit in the FieldInfo -TEST_F(PayloadsTest, testPayloadFieldBit) -{ +TEST_F(PayloadsTest, testPayloadFieldBit) { DirectoryPtr ram = newLucene(); PayloadAnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(ram, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -295,8 +272,7 @@ TEST_F(PayloadsTest, testPayloadFieldBit) /// Builds an index with payloads in the given Directory and performs different /// tests to verify the payload encoding -static void encodingTest(const DirectoryPtr& dir) -{ +static void encodingTest(const DirectoryPtr& dir) { PayloadAnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -310,8 +286,9 @@ static void encodingTest(const DirectoryPtr& dir) // create content for the test documents with just a few terms Collection terms = generateTerms(fieldName, numTerms); StringStream sb; - for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) + for (Collection::iterator term = terms.begin(); term != terms.end(); ++term) { sb << (*term)->text() << L" "; + } String content = sb.str(); int32_t payloadDataLength = numTerms * numDocs * 2 + numTerms * numDocs * (numDocs - 1) / 2; @@ -323,8 +300,7 @@ static void encodingTest(const DirectoryPtr& dir) // add the same document multiple times to have the same payload lengths for all // occurrences within two consecutive skip intervals int32_t offset = 0; - for (int32_t i = 0; i < 2 * numDocs; ++i) - { + for (int32_t i = 0; i < 2 * numDocs; ++i) { analyzer->setPayloadData(fieldName, payloadData, offset, 1); offset += numTerms; writer->addDocument(d); @@ -333,8 +309,7 @@ static void encodingTest(const DirectoryPtr& dir) // make sure we create more than one segment to test merging writer->commit(); - for (int32_t i = 0; i < numDocs; ++i) - { + for (int32_t i = 0; i < numDocs; ++i) { analyzer->setPayloadData(fieldName, payloadData, offset, i); offset += i * numTerms; writer->addDocument(d); @@ -350,19 +325,18 @@ static void encodingTest(const DirectoryPtr& dir) ByteArray verifyPayloadData(ByteArray::newInstance(payloadDataLength)); offset = 0; Collection tps = Collection::newInstance(numTerms); - for (int32_t i = 0; i < numTerms; ++i) + for (int32_t i = 0; i < numTerms; ++i) { tps[i] = reader->termPositions(terms[i]); + } - while (tps[0]->next()) - { - for (int32_t i = 1; i < numTerms; ++i) + while (tps[0]->next()) { + for (int32_t i = 1; i < numTerms; ++i) { tps[i]->next(); + } int32_t freq = tps[0]->freq(); - for (int32_t i = 0; i < freq; ++i) - { - for (int32_t j = 0; j < numTerms; ++j) - { + for (int32_t i = 0; i < freq; ++i) { + for (int32_t j = 0; j < numTerms; ++j) { tps[j]->nextPosition(); tps[j]->getPayload(verifyPayloadData, offset); offset += tps[j]->getPayloadLength(); @@ -370,8 +344,9 @@ static void encodingTest(const DirectoryPtr& dir) } } - for (int32_t i = 0; i < numTerms; ++i) + for (int32_t i = 0; i < numTerms; ++i) { tps[i]->close(); + } EXPECT_TRUE(payloadData.equals(verifyPayloadData)); @@ -412,12 +387,9 @@ static void encodingTest(const DirectoryPtr& dir) tp->getPayload(ByteArray(), 0); // it is forbidden to call getPayload() more than once without calling nextPosition() - try - { + try { tp->getPayload(ByteArray(), 0); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } @@ -455,8 +427,7 @@ static void encodingTest(const DirectoryPtr& dir) } /// Tests if payloads are correctly stored and loaded using both RamDirectory and FSDirectory -TEST_F(PayloadsTest, testPayloadsEncoding) -{ +TEST_F(PayloadsTest, testPayloadsEncoding) { // first perform the test using a RAMDirectory DirectoryPtr dir = newLucene(); encodingTest(dir); @@ -468,145 +439,127 @@ TEST_F(PayloadsTest, testPayloadsEncoding) FileUtils::removeDirectory(dirName); } -namespace TestThreadSafety -{ - DECLARE_SHARED_PTR(ByteArrayPool) - - class ByteArrayPool : public LuceneObject - { - public: - ByteArrayPool(int32_t capacity, int32_t size) - { - pool = Collection::newInstance(); - for (int32_t i = 0; i < capacity; ++i) - pool.add(ByteArray::newInstance(size)); - } +namespace TestThreadSafety { + +DECLARE_SHARED_PTR(ByteArrayPool) - virtual ~ByteArrayPool() - { +class ByteArrayPool : public LuceneObject { +public: + ByteArrayPool(int32_t capacity, int32_t size) { + pool = Collection::newInstance(); + for (int32_t i = 0; i < capacity; ++i) { + pool.add(ByteArray::newInstance(size)); } + } - LUCENE_CLASS(ByteArrayPool); + virtual ~ByteArrayPool() { + } - public: - Collection pool; + LUCENE_CLASS(ByteArrayPool); - public: - String bytesToString(ByteArray bytes) - { - SyncLock syncLock(this); - return Base64::encode(bytes); - } +public: + Collection pool; - ByteArray get() - { - SyncLock syncLock(this); - return pool.removeFirst(); - } +public: + String bytesToString(ByteArray bytes) { + SyncLock syncLock(this); + return Base64::encode(bytes); + } - void release(ByteArray b) - { - SyncLock syncLock(this); - pool.add(b); - } + ByteArray get() { + SyncLock syncLock(this); + return pool.removeFirst(); + } - int32_t size() - { - SyncLock syncLock(this); - return pool.size(); - } - }; - - class PoolingPayloadTokenStream : public TokenStream - { - public: - PoolingPayloadTokenStream(const ByteArrayPoolPtr& pool) - { - this->pool = pool; - payload = pool->get(); - generateRandomData(payload); - term = pool->bytesToString(payload); - first = true; - payloadAtt = addAttribute(); - termAtt = addAttribute(); - } + void release(ByteArray b) { + SyncLock syncLock(this); + pool.add(b); + } - virtual ~PoolingPayloadTokenStream() - { - } + int32_t size() { + SyncLock syncLock(this); + return pool.size(); + } +}; - LUCENE_CLASS(PoolingPayloadTokenStream); - - public: - ByteArray payload; - bool first; - ByteArrayPoolPtr pool; - String term; - - TermAttributePtr termAtt; - PayloadAttributePtr payloadAtt; - - public: - virtual bool incrementToken() - { - if (!first) - return false; - first = false; - clearAttributes(); - termAtt->setTermBuffer(term); - payloadAtt->setPayload(newLucene(payload)); - return true; - } +class PoolingPayloadTokenStream : public TokenStream { +public: + PoolingPayloadTokenStream(const ByteArrayPoolPtr& pool) { + this->pool = pool; + payload = pool->get(); + generateRandomData(payload); + term = pool->bytesToString(payload); + first = true; + payloadAtt = addAttribute(); + termAtt = addAttribute(); + } - virtual void close() - { - pool->release(payload); - } - }; - - class IngesterThread : public LuceneThread - { - public: - IngesterThread(int32_t numDocs, const ByteArrayPoolPtr& pool, const IndexWriterPtr& writer) - { - this->numDocs = numDocs; - this->pool = pool; - this->writer = writer; - } + virtual ~PoolingPayloadTokenStream() { + } + + LUCENE_CLASS(PoolingPayloadTokenStream); - virtual ~IngesterThread() - { +public: + ByteArray payload; + bool first; + ByteArrayPoolPtr pool; + String term; + + TermAttributePtr termAtt; + PayloadAttributePtr payloadAtt; + +public: + virtual bool incrementToken() { + if (!first) { + return false; } + first = false; + clearAttributes(); + termAtt->setTermBuffer(term); + payloadAtt->setPayload(newLucene(payload)); + return true; + } - LUCENE_CLASS(IngesterThread); - - protected: - int32_t numDocs; - ByteArrayPoolPtr pool; - IndexWriterPtr writer; - - public: - virtual void run() - { - try - { - for (int32_t j = 0; j < numDocs; ++j) - { - DocumentPtr d = newLucene(); - d->add(newLucene(L"test", newLucene(pool))); - writer->addDocument(d); - } - } - catch (LuceneException& e) - { - FAIL() << "Unexpected exception: " << e.getError(); + virtual void close() { + pool->release(payload); + } +}; + +class IngesterThread : public LuceneThread { +public: + IngesterThread(int32_t numDocs, const ByteArrayPoolPtr& pool, const IndexWriterPtr& writer) { + this->numDocs = numDocs; + this->pool = pool; + this->writer = writer; + } + + virtual ~IngesterThread() { + } + + LUCENE_CLASS(IngesterThread); + +protected: + int32_t numDocs; + ByteArrayPoolPtr pool; + IndexWriterPtr writer; + +public: + virtual void run() { + try { + for (int32_t j = 0; j < numDocs; ++j) { + DocumentPtr d = newLucene(); + d->add(newLucene(L"test", newLucene(pool))); + writer->addDocument(d); } + } catch (LuceneException& e) { + FAIL() << "Unexpected exception: " << e.getError(); } - }; + } +}; + } -TEST_F(PayloadsTest, testThreadSafety) -{ +TEST_F(PayloadsTest, testThreadSafety) { int32_t numThreads = 5; int32_t numDocs = 50; TestThreadSafety::ByteArrayPoolPtr pool = newLucene(numThreads, 5); @@ -615,26 +568,23 @@ TEST_F(PayloadsTest, testThreadSafety) IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); Collection ingesters = Collection::newInstance(numThreads); - for (int32_t i = 0; i < numThreads; ++i) - { + for (int32_t i = 0; i < numThreads; ++i) { ingesters[i] = newLucene(numDocs, pool, writer); ingesters[i]->start(); } - for (int32_t i = 0; i < numThreads; ++i) + for (int32_t i = 0; i < numThreads; ++i) { ingesters[i]->join(); + } writer->close(); IndexReaderPtr reader = IndexReader::open(dir, true); TermEnumPtr terms = reader->terms(); - while (terms->next()) - { + while (terms->next()) { TermPositionsPtr tp = reader->termPositions(terms->term()); - while (tp->next()) - { + while (tp->next()) { int32_t freq = tp->freq(); - for (int32_t i = 0; i < freq; ++i) - { + for (int32_t i = 0; i < freq; ++i) { tp->nextPosition(); EXPECT_EQ(pool->bytesToString(tp->getPayload(ByteArray::newInstance(5), 0)), terms->term()->text()); } diff --git a/src/test/index/PositionBasedTermVectorMapperTest.cpp b/src/test/index/PositionBasedTermVectorMapperTest.cpp index 4e90c397..60cd01cd 100644 --- a/src/test/index/PositionBasedTermVectorMapperTest.cpp +++ b/src/test/index/PositionBasedTermVectorMapperTest.cpp @@ -15,23 +15,23 @@ using namespace Lucene; typedef LuceneTestFixture PositionBasedTermVectorMapperTest; -TEST_F(PositionBasedTermVectorMapperTest, testPayload) -{ +TEST_F(PositionBasedTermVectorMapperTest, testPayload) { Collection tokens = newCollection(L"here", L"is", L"some", L"text", L"to", L"test", L"extra"); Collection< Collection > thePositions = Collection< Collection >::newInstance(tokens.size()); Collection< Collection > offsets = Collection< Collection >::newInstance(tokens.size()); int32_t numPositions = 0; // save off the last one so we can add it with the same positions as some of the others, but in a predictable way - for (int32_t i = 0; i < tokens.size() - 1; ++i) - { + for (int32_t i = 0; i < tokens.size() - 1; ++i) { thePositions[i] = Collection::newInstance(2 * i + 1); // give 'em all some positions - for (int32_t j = 0; j < thePositions[i].size(); ++j) + for (int32_t j = 0; j < thePositions[i].size(); ++j) { thePositions[i][j] = numPositions++; + } offsets[i] = Collection::newInstance(thePositions[i].size()); - for (int32_t j = 0; j < offsets[i].size(); ++j) - offsets[i][j] = newLucene(j, j + 1); // the actual value here doesn't much matter + for (int32_t j = 0; j < offsets[i].size(); ++j) { + offsets[i][j] = newLucene(j, j + 1); // the actual value here doesn't much matter + } } thePositions[tokens.size() - 1] = Collection::newInstance(1); @@ -43,8 +43,7 @@ TEST_F(PositionBasedTermVectorMapperTest, testPayload) mapper->setExpectations(L"test", tokens.size(), true, true); // Test single position - for (int32_t i = 0; i < tokens.size(); ++i) - { + for (int32_t i = 0; i < tokens.size(); ++i) { String token = tokens[i]; mapper->map(token, 1, Collection(), thePositions[i]); } @@ -57,20 +56,16 @@ TEST_F(PositionBasedTermVectorMapperTest, testPayload) EXPECT_EQ(positions.size(), numPositions); BitSetPtr bits = newLucene(numPositions); - for (MapIntTermVectorsPositionInfo::iterator entry = positions.begin(); entry != positions.end(); ++entry) - { + for (MapIntTermVectorsPositionInfo::iterator entry = positions.begin(); entry != positions.end(); ++entry) { EXPECT_TRUE(entry->second); int32_t pos = entry->first; bits->set(pos); EXPECT_EQ(entry->second->getPosition(), pos); EXPECT_TRUE(entry->second->getOffsets()); - if (pos == 0) - { + if (pos == 0) { EXPECT_EQ(entry->second->getTerms().size(), 2); // need a test for multiple terms at one pos EXPECT_EQ(entry->second->getOffsets().size(), 2); - } - else - { + } else { EXPECT_EQ(entry->second->getTerms().size(), 1); // need a test for multiple terms at one pos EXPECT_EQ(entry->second->getOffsets().size(), 1); } diff --git a/src/test/index/SegmentMergerTest.cpp b/src/test/index/SegmentMergerTest.cpp index 07b9c0dc..b0c2d4bf 100644 --- a/src/test/index/SegmentMergerTest.cpp +++ b/src/test/index/SegmentMergerTest.cpp @@ -23,11 +23,9 @@ using namespace Lucene; -class SegmentMergerTest : public LuceneTestFixture, public DocHelper -{ +class SegmentMergerTest : public LuceneTestFixture, public DocHelper { public: - SegmentMergerTest() - { + SegmentMergerTest() { mergedDir = newLucene(); mergedSegment = L"test"; merge1Dir = newLucene(); @@ -43,8 +41,7 @@ class SegmentMergerTest : public LuceneTestFixture, public DocHelper reader2 = SegmentReader::get(true, info2, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); } - virtual ~SegmentMergerTest() - { + virtual ~SegmentMergerTest() { } protected: @@ -63,35 +60,31 @@ class SegmentMergerTest : public LuceneTestFixture, public DocHelper SegmentReaderPtr reader2; public: - void checkNorms(const IndexReaderPtr& reader) - { + void checkNorms(const IndexReaderPtr& reader) { // test omit norms - for (int32_t i = 0; i < DocHelper::fields.size(); ++i) - { + for (int32_t i = 0; i < DocHelper::fields.size(); ++i) { FieldPtr f = DocHelper::fields[i]; - if (f->isIndexed()) - { + if (f->isIndexed()) { EXPECT_EQ(reader->hasNorms(f->name()), !f->getOmitNorms()); EXPECT_EQ(reader->hasNorms(f->name()), !DocHelper::noNorms.contains(f->name())); - if (!reader->hasNorms(f->name())) - { + if (!reader->hasNorms(f->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms(f->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); EXPECT_TRUE(!norms); norms.resize(reader->maxDoc()); reader->norms(f->name(), norms, 0); - for (int32_t j = 0; j < reader->maxDoc(); ++j) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { EXPECT_EQ(norms[j], norm1); + } } } } } }; -TEST_F(SegmentMergerTest, testMerge) -{ +TEST_F(SegmentMergerTest, testMerge) { SegmentMergerPtr merger = newLucene(mergedDir, mergedSegment); merger->add(reader1); merger->add(reader2); @@ -132,8 +125,7 @@ TEST_F(SegmentMergerTest, testMerge) EXPECT_TRUE(boost::dynamic_pointer_cast(vector)); - for (int32_t i = 0; i < terms.size(); ++i) - { + for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; int32_t freq = freqs[i]; diff --git a/src/test/index/SegmentReaderTest.cpp b/src/test/index/SegmentReaderTest.cpp index 7f30ca49..5ddb4a12 100644 --- a/src/test/index/SegmentReaderTest.cpp +++ b/src/test/index/SegmentReaderTest.cpp @@ -22,11 +22,9 @@ using namespace Lucene; -class SegmentReaderTest : public LuceneTestFixture, public DocHelper -{ +class SegmentReaderTest : public LuceneTestFixture, public DocHelper { public: - SegmentReaderTest() - { + SegmentReaderTest() { dir = newLucene(); testDoc = newLucene(); DocHelper::setupDoc(testDoc); @@ -34,8 +32,7 @@ class SegmentReaderTest : public LuceneTestFixture, public DocHelper reader = SegmentReader::get(true, info, IndexReader::DEFAULT_TERMS_INDEX_DIVISOR); } - virtual ~SegmentReaderTest() - { + virtual ~SegmentReaderTest() { } protected: @@ -44,16 +41,14 @@ class SegmentReaderTest : public LuceneTestFixture, public DocHelper SegmentReaderPtr reader; }; -TEST_F(SegmentReaderTest, testSegmentReader) -{ +TEST_F(SegmentReaderTest, testSegmentReader) { EXPECT_TRUE(dir); EXPECT_TRUE(reader); EXPECT_TRUE(DocHelper::nameValues.size() > 0); EXPECT_EQ(DocHelper::numFields(testDoc), DocHelper::all.size()); } -TEST_F(SegmentReaderTest, testDocument) -{ +TEST_F(SegmentReaderTest, testDocument) { EXPECT_EQ(reader->numDocs(), 1); EXPECT_TRUE(reader->maxDoc() >= 1); DocumentPtr result = reader->document(0); @@ -63,15 +58,13 @@ TEST_F(SegmentReaderTest, testDocument) EXPECT_EQ(DocHelper::numFields(result), DocHelper::numFields(testDoc) - DocHelper::unstored.size()); Collection fields = result->getFields(); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) - { + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { EXPECT_TRUE(*field); EXPECT_TRUE(DocHelper::nameValues.contains((*field)->name())); } } -TEST_F(SegmentReaderTest, testDelete) -{ +TEST_F(SegmentReaderTest, testDelete) { DocumentPtr docToDelete = newLucene(); DocHelper::setupDoc(docToDelete); SegmentInfoPtr info = DocHelper::writeDoc(dir, docToDelete); @@ -84,18 +77,19 @@ TEST_F(SegmentReaderTest, testDelete) EXPECT_EQ(deleteReader->numDocs(), 0); } -TEST_F(SegmentReaderTest, testGetFieldNameVariations) -{ +TEST_F(SegmentReaderTest, testGetFieldNameVariations) { HashSet result = reader->getFieldNames(IndexReader::FIELD_OPTION_ALL); EXPECT_TRUE(result); EXPECT_EQ(result.size(), DocHelper::all.size()); - for (HashSet::iterator field = result.begin(); field != result.end(); ++field) + for (HashSet::iterator field = result.begin(); field != result.end(); ++field) { EXPECT_TRUE(DocHelper::nameValues.contains(*field) || field->empty()); + } result = reader->getFieldNames(IndexReader::FIELD_OPTION_INDEXED); EXPECT_TRUE(result); EXPECT_EQ(result.size(), DocHelper::indexed.size()); - for (HashSet::iterator field = result.begin(); field != result.end(); ++field) + for (HashSet::iterator field = result.begin(); field != result.end(); ++field) { EXPECT_TRUE(DocHelper::indexed.contains(*field) || field->empty()); + } result = reader->getFieldNames(IndexReader::FIELD_OPTION_UNINDEXED); EXPECT_TRUE(result); EXPECT_EQ(result.size(), DocHelper::unindexed.size()); @@ -110,12 +104,10 @@ TEST_F(SegmentReaderTest, testGetFieldNameVariations) EXPECT_EQ(result.size(), DocHelper::notermvector.size()); } -TEST_F(SegmentReaderTest, testTerms) -{ +TEST_F(SegmentReaderTest, testTerms) { TermEnumPtr terms = reader->terms(); EXPECT_TRUE(terms); - while (terms->next()) - { + while (terms->next()) { TermPtr term = terms->term(); EXPECT_TRUE(term); String fieldValue = DocHelper::nameValues.get(term->field()); @@ -137,37 +129,33 @@ TEST_F(SegmentReaderTest, testTerms) EXPECT_TRUE(positions->nextPosition() >= 0); } -TEST_F(SegmentReaderTest, testNorms) -{ +TEST_F(SegmentReaderTest, testNorms) { // test omit norms - for (int32_t i = 0; i < DocHelper::fields.size(); ++i) - { + for (int32_t i = 0; i < DocHelper::fields.size(); ++i) { FieldPtr f = DocHelper::fields[i]; - if (f->isIndexed()) - { + if (f->isIndexed()) { bool a = reader->hasNorms(f->name()); bool b = !f->getOmitNorms(); EXPECT_EQ(reader->hasNorms(f->name()), !f->getOmitNorms()); EXPECT_EQ(reader->hasNorms(f->name()), !DocHelper::noNorms.contains(f->name())); - if (!reader->hasNorms(f->name())) - { + if (!reader->hasNorms(f->name())) { // test for fake norms of 1.0 or null depending on the flag ByteArray norms = reader->norms(f->name()); uint8_t norm1 = DefaultSimilarity::encodeNorm(1.0); EXPECT_TRUE(!norms); norms.resize(reader->maxDoc()); reader->norms(f->name(), norms, 0); - for (int32_t j = 0; j < reader->maxDoc(); ++j) + for (int32_t j = 0; j < reader->maxDoc(); ++j) { EXPECT_EQ(norms[j], norm1); + } } } } } -TEST_F(SegmentReaderTest, testTermVectors) -{ +TEST_F(SegmentReaderTest, testTermVectors) { TermFreqVectorPtr result = reader->getTermFreqVector(0, DocHelper::TEXT_FIELD_2_KEY); EXPECT_TRUE(result); Collection terms = result->getTerms(); @@ -176,8 +164,7 @@ TEST_F(SegmentReaderTest, testTermVectors) EXPECT_EQ(terms.size(), 3); EXPECT_TRUE(freqs); EXPECT_EQ(freqs.size(), 3); - for (int32_t i = 0; i < terms.size(); ++i) - { + for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; int32_t freq = freqs[i]; EXPECT_NE(String(DocHelper::FIELD_2_TEXT).find(term), -1); diff --git a/src/test/index/SegmentTermDocsTest.cpp b/src/test/index/SegmentTermDocsTest.cpp index 38f66ad2..d46abffc 100644 --- a/src/test/index/SegmentTermDocsTest.cpp +++ b/src/test/index/SegmentTermDocsTest.cpp @@ -22,19 +22,16 @@ using namespace Lucene; -class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper -{ +class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper { public: - SegmentTermDocsTest() - { + SegmentTermDocsTest() { testDoc = newLucene(); dir = newLucene(); DocHelper::setupDoc(testDoc); info = DocHelper::writeDoc(dir, testDoc); } - virtual ~SegmentTermDocsTest() - { + virtual ~SegmentTermDocsTest() { } protected: @@ -43,8 +40,7 @@ class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper SegmentInfoPtr info; public: - void checkTermDocs(int32_t indexDivisor) - { + void checkTermDocs(int32_t indexDivisor) { // After adding the document, we should be able to read it back in SegmentReaderPtr reader = SegmentReader::get(true, info, indexDivisor); EXPECT_TRUE(reader); @@ -52,8 +48,7 @@ class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper SegmentTermDocsPtr segTermDocs = newLucene(reader); EXPECT_TRUE(segTermDocs); segTermDocs->seek(newLucene(DocHelper::TEXT_FIELD_2_KEY, L"field")); - if (segTermDocs->next()) - { + if (segTermDocs->next()) { int32_t docId = segTermDocs->doc(); EXPECT_EQ(docId, 0); int32_t freq = segTermDocs->freq(); @@ -62,8 +57,7 @@ class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper reader->close(); } - void checkBadSeek(int32_t indexDivisor) - { + void checkBadSeek(int32_t indexDivisor) { { // After adding the document, we should be able to read it back in SegmentReaderPtr reader = SegmentReader::get(true, info, indexDivisor); @@ -86,22 +80,24 @@ class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper } } - void checkSkipTo(int32_t indexDivisor) - { + void checkSkipTo(int32_t indexDivisor) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); TermPtr ta = newLucene(L"content", L"aaa"); - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { addDoc(writer, L"aaa aaa aaa aaa"); + } TermPtr tb = newLucene(L"content", L"bbb"); - for (int32_t i = 0; i < 16; ++i) + for (int32_t i = 0; i < 16; ++i) { addDoc(writer, L"bbb bbb bbb bbb"); + } TermPtr tc = newLucene(L"content", L"ccc"); - for (int32_t i = 0; i < 50; ++i) + for (int32_t i = 0; i < 50; ++i) { addDoc(writer, L"ccc ccc ccc ccc"); + } // assure that we deal with a single segment writer->optimize(); @@ -212,31 +208,26 @@ class SegmentTermDocsTest : public LuceneTestFixture, public DocHelper dir->close(); } - void addDoc(const IndexWriterPtr& writer, const String& value) - { + void addDoc(const IndexWriterPtr& writer, const String& value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", value, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } }; -TEST_F(SegmentTermDocsTest, testTermDocs) -{ +TEST_F(SegmentTermDocsTest, testTermDocs) { checkTermDocs(1); } -TEST_F(SegmentTermDocsTest, testBadSeek) -{ +TEST_F(SegmentTermDocsTest, testBadSeek) { checkBadSeek(1); } -TEST_F(SegmentTermDocsTest, testSkipTo) -{ +TEST_F(SegmentTermDocsTest, testSkipTo) { checkSkipTo(1); } -TEST_F(SegmentTermDocsTest, testIndexDivisor) -{ +TEST_F(SegmentTermDocsTest, testIndexDivisor) { dir = newLucene(); testDoc = newLucene(); DocHelper::setupDoc(testDoc); diff --git a/src/test/index/SegmentTermEnumTest.cpp b/src/test/index/SegmentTermEnumTest.cpp index e112d300..e62894de 100644 --- a/src/test/index/SegmentTermEnumTest.cpp +++ b/src/test/index/SegmentTermEnumTest.cpp @@ -22,15 +22,13 @@ using namespace Lucene; typedef LuceneTestFixture SegmentTermEnumTest; -static void addDoc(const IndexWriterPtr& writer, const String& value) -{ +static void addDoc(const IndexWriterPtr& writer, const String& value) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", value, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void verifyDocFreq(const DirectoryPtr& dir) -{ +static void verifyDocFreq(const DirectoryPtr& dir) { IndexReaderPtr reader = IndexReader::open(dir, true); // create enumeration of all terms @@ -62,16 +60,14 @@ static void verifyDocFreq(const DirectoryPtr& dir) termEnum->close(); } -TEST_F(SegmentTermEnumTest, testTermEnum) -{ +TEST_F(SegmentTermEnumTest, testTermEnum) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); // ADD 100 documents with term : aaa // add 100 documents with terms: aaa bbb // Therefore, term 'aaa' has document frequency of 200 and term 'bbb' 100 - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { addDoc(writer, L"aaa"); addDoc(writer, L"aaa bbb"); } @@ -90,8 +86,7 @@ TEST_F(SegmentTermEnumTest, testTermEnum) verifyDocFreq(dir); } -TEST_F(SegmentTermEnumTest, testPrevTermAtEnd) -{ +TEST_F(SegmentTermEnumTest, testPrevTermAtEnd) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(writer, L"aaa bbb"); diff --git a/src/test/index/SnapshotDeletionPolicyTest.cpp b/src/test/index/SnapshotDeletionPolicyTest.cpp index 50ff5fa6..00fbf09c 100644 --- a/src/test/index/SnapshotDeletionPolicyTest.cpp +++ b/src/test/index/SnapshotDeletionPolicyTest.cpp @@ -23,17 +23,14 @@ using namespace Lucene; -class SnapshotThread : public LuceneThread -{ +class SnapshotThread : public LuceneThread { public: - SnapshotThread(int64_t stopTime, const IndexWriterPtr& writer) - { + SnapshotThread(int64_t stopTime, const IndexWriterPtr& writer) { this->stopTime = stopTime; this->writer = writer; } - virtual ~SnapshotThread() - { + virtual ~SnapshotThread() { } LUCENE_CLASS(SnapshotThread); @@ -43,41 +40,32 @@ class SnapshotThread : public LuceneThread IndexWriterPtr writer; public: - virtual void run() - { - try - { + virtual void run() { + try { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); - do - { - for (int32_t i = 0; i < 27; ++i) - { + do { + for (int32_t i = 0; i < 27; ++i) { writer->addDocument(doc); - if (i % 2 == 0) + if (i % 2 == 0) { writer->commit(); + } } LuceneThread::threadSleep(1); - } - while ((int64_t)MiscUtils::currentTimeMillis() < stopTime); - } - catch (LuceneException& e) - { + } while ((int64_t)MiscUtils::currentTimeMillis() < stopTime); + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } }; -class SnapshotDeletionPolicyTest : public LuceneTestFixture -{ +class SnapshotDeletionPolicyTest : public LuceneTestFixture { public: - SnapshotDeletionPolicyTest() - { + SnapshotDeletionPolicyTest() { buffer = ByteArray::newInstance(4096); } - virtual ~SnapshotDeletionPolicyTest() - { + virtual ~SnapshotDeletionPolicyTest() { } public: @@ -85,8 +73,7 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture ByteArray buffer; public: - void runTest(const DirectoryPtr& dir) - { + void runTest(const DirectoryPtr& dir) { // Run for ~1 seconds int64_t stopTime = MiscUtils::currentTimeMillis() + 1000; @@ -100,14 +87,13 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture thread->start(); // While the above indexing thread is running, take many backups - do - { + do { backupIndex(dir, dp); LuceneThread::threadSleep(20); - if (!thread->isAlive()) + if (!thread->isAlive()) { break; - } - while ((int64_t)MiscUtils::currentTimeMillis() < stopTime); + } + } while ((int64_t)MiscUtils::currentTimeMillis() < stopTime); thread->join(); @@ -124,16 +110,12 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture /// Example showing how to use the SnapshotDeletionPolicy to take a backup. This method does not /// really do a backup; instead, it reads every byte of every file just to test that the files /// indeed exist and are readable even while the index is changing. - void backupIndex(const DirectoryPtr& dir, const SnapshotDeletionPolicyPtr& dp) - { + void backupIndex(const DirectoryPtr& dir, const SnapshotDeletionPolicyPtr& dp) { // To backup an index we first take a snapshot LuceneException finally; - try - { + try { copyFiles(dir, boost::dynamic_pointer_cast(dp->snapshot())); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } @@ -143,13 +125,11 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture finally.throwException(); } - void copyFiles(const DirectoryPtr& dir, const IndexCommitPtr& cp) - { + void copyFiles(const DirectoryPtr& dir, const IndexCommitPtr& cp) { // While we hold the snapshot, and nomatter how long we take to do the backup, the IndexWriter will // never delete the files in the snapshot HashSet files = cp->getFileNames(); - for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) - { + for (HashSet::iterator fileName = files.begin(); fileName != files.end(); ++fileName) { // NOTE: in a real backup you would not use readFile; you would need to use something else // that copies the file to a backup location. This could even be a spawned shell process // (eg "tar", "zip") that takes the list of files and builds a backup. @@ -157,17 +137,14 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture } } - void readFile(const DirectoryPtr& dir, const String& name) - { + void readFile(const DirectoryPtr& dir, const String& name) { IndexInputPtr input = dir->openInput(name); LuceneException finally; - try - { + try { int64_t size = dir->fileLength(name); int64_t bytesLeft = size; - while (bytesLeft > 0) - { + while (bytesLeft > 0) { int32_t numToRead = bytesLeft < buffer.size() ? (int32_t)bytesLeft : buffer.size(); input->readBytes(buffer.get(), 0, numToRead, false); bytesLeft -= numToRead; @@ -176,17 +153,14 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture // long time, to make sure we are exercising the fact that the IndexWriter should not delete // this file even when I take my time reading it. LuceneThread::threadSleep(1); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } input->close(); finally.throwException(); } - void checkNoUnreferencedFiles(const DirectoryPtr& dir) - { + void checkNoUnreferencedFiles(const DirectoryPtr& dir) { HashSet _startFiles = dir->listAll(); SegmentInfosPtr infos = newLucene(); infos->read(dir); @@ -205,19 +179,15 @@ class SnapshotDeletionPolicyTest : public LuceneTestFixture const String SnapshotDeletionPolicyTest::INDEX_PATH = L"test.snapshots"; -TEST_F(SnapshotDeletionPolicyTest, testSnapshotDeletionPolicy) -{ +TEST_F(SnapshotDeletionPolicyTest, testSnapshotDeletionPolicy) { String dir = getTempDir(INDEX_PATH); LuceneException finally; - try - { + try { DirectoryPtr fsDir = FSDirectory::open(dir); runTest(fsDir); fsDir->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } FileUtils::removeDirectory(dir); @@ -228,17 +198,13 @@ TEST_F(SnapshotDeletionPolicyTest, testSnapshotDeletionPolicy) dir2->close(); } -TEST_F(SnapshotDeletionPolicyTest, testNoCommits) -{ +TEST_F(SnapshotDeletionPolicyTest, testNoCommits) { // Tests that if there were no commits when snapshot() is called, then // IllegalStateException is thrown rather than NPE. SnapshotDeletionPolicyPtr sdp = newLucene(newLucene()); - try - { + try { sdp->snapshot(); - } - catch (IllegalStateException& e) - { + } catch (IllegalStateException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalState)(e)); } } diff --git a/src/test/index/StressIndexingTest.cpp b/src/test/index/StressIndexingTest.cpp index c110b78b..b324813b 100644 --- a/src/test/index/StressIndexingTest.cpp +++ b/src/test/index/StressIndexingTest.cpp @@ -36,11 +36,9 @@ typedef LuceneTestFixture StressIndexingTest; DECLARE_SHARED_PTR(DocsAndWriter) -class DocsAndWriter : public LuceneObject -{ +class DocsAndWriter : public LuceneObject { public: - virtual ~DocsAndWriter() - { + virtual ~DocsAndWriter() { } LUCENE_CLASS(DocsAndWriter); @@ -50,16 +48,13 @@ class DocsAndWriter : public LuceneObject IndexWriterPtr writer; }; -class MockIndexWriter : public IndexWriter -{ +class MockIndexWriter : public IndexWriter { public: - MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) - { + MockIndexWriter(const DirectoryPtr& dir, const AnalyzerPtr& a, bool create, int32_t mfl) : IndexWriter(dir, a, create, mfl) { rand = newLucene(); } - virtual ~MockIndexWriter() - { + virtual ~MockIndexWriter() { } LUCENE_CLASS(MockIndexWriter); @@ -68,10 +63,10 @@ class MockIndexWriter : public IndexWriter RandomPtr rand; public: - virtual bool testPoint(const String& name) - { - if (rand->nextInt(4) == 2) + virtual bool testPoint(const String& name) { + if (rand->nextInt(4) == 2) { LuceneThread::threadYield(); + } return true; } }; @@ -85,19 +80,15 @@ static int32_t seed = 0; DECLARE_SHARED_PTR(IndexingThread) -struct lessFieldName -{ - inline bool operator()(const FieldablePtr& first, const FieldablePtr& second) const - { +struct lessFieldName { + inline bool operator()(const FieldablePtr& first, const FieldablePtr& second) const { return (first->name() < second->name()); } }; -class IndexingThread : public LuceneThread -{ +class IndexingThread : public LuceneThread { public: - IndexingThread() - { + IndexingThread() { base = 0; range = 0; iterations = 0; @@ -106,8 +97,7 @@ class IndexingThread : public LuceneThread r = newLucene(); } - virtual ~IndexingThread() - { + virtual ~IndexingThread() { } LUCENE_CLASS(IndexingThread); @@ -122,85 +112,78 @@ class IndexingThread : public LuceneThread RandomPtr r; public: - int32_t nextInt(int32_t limit = INT_MAX) - { + int32_t nextInt(int32_t limit = INT_MAX) { return r->nextInt(limit); } /// start is inclusive and end is exclusive - int32_t nextInt(int32_t start, int32_t end) - { + int32_t nextInt(int32_t start, int32_t end) { return start + r->nextInt(end - start); } - int32_t addUTF8Token(int32_t start) - { + int32_t addUTF8Token(int32_t start) { int32_t end = start + nextInt(20); - if (buffer.size() < 1 + end) + if (buffer.size() < 1 + end) { buffer.resize((int32_t)((double)(1 + end) * 1.25)); + } - for (int32_t i = start; i < end; ++i) - { + for (int32_t i = start; i < end; ++i) { int32_t t = nextInt(5); - if (t == 0 && i < end - 1) - { - #ifdef LPP_UNICODE_CHAR_SIZE_2 + if (t == 0 && i < end - 1) { +#ifdef LPP_UNICODE_CHAR_SIZE_2 // Make a surrogate pair // High surrogate buffer[i++] = (wchar_t)nextInt(0xd800, 0xdc00); // Low surrogate buffer[i] = (wchar_t)nextInt(0xdc00, 0xe000); - #else +#else buffer[i] = (wchar_t)nextInt(0x10dc00, 0x10e000); - #endif - } - else if (t <= 1) +#endif + } else if (t <= 1) { buffer[i] = (wchar_t)nextInt(0x01, 0x80); - else if (t == 2) + } else if (t == 2) { buffer[i] = (wchar_t)nextInt(0x80, 0x800); - else if (t == 3) + } else if (t == 3) { buffer[i] = (wchar_t)nextInt(0x800, 0xd800); - else if (t == 4) + } else if (t == 4) { buffer[i] = (wchar_t)nextInt(0xe000, 0xfff0); + } } buffer[end] = L' '; return 1 + end; } - String getString(int32_t tokens) - { + String getString(int32_t tokens) { tokens = tokens != 0 ? tokens : r->nextInt(4) + 1; // Half the time make a random UTF8 string - if (nextInt() % 2 == 1) + if (nextInt() % 2 == 1) { return getUTF8String(tokens); + } CharArray arr(CharArray::newInstance(tokens * 2)); - for (int32_t i = 0; i < tokens; ++i) - { + for (int32_t i = 0; i < tokens; ++i) { arr[i * 2] = (wchar_t)(L'A' + r->nextInt(10)); arr[i * 2 + 1] = L' '; } return String(arr.get(), arr.size()); } - String getUTF8String(int32_t tokens) - { + String getUTF8String(int32_t tokens) { int32_t upto = 0; MiscUtils::arrayFill(buffer.get(), 0, buffer.size(), (wchar_t)0); - for (int32_t i = 0; i < tokens; ++i) + for (int32_t i = 0; i < tokens; ++i) { upto = addUTF8Token(upto); + } return String(buffer.get(), upto); } - String getIdString() - { + String getIdString() { return StringUtils::toString(base + nextInt(range)); } - void indexDoc() - { + void indexDoc() { DocumentPtr d = newLucene(); Collection fields = Collection::newInstance(); @@ -210,89 +193,80 @@ class IndexingThread : public LuceneThread fields.add(idField); int32_t numFields = nextInt(maxFields); - for (int32_t i = 0; i < numFields; ++i) - { + for (int32_t i = 0; i < numFields; ++i) { Field::TermVector tvVal = Field::TERM_VECTOR_NO; - switch (nextInt(4)) - { - case 0: - tvVal = Field::TERM_VECTOR_NO; - break; - case 1: - tvVal = Field::TERM_VECTOR_YES; - break; - case 2: - tvVal = Field::TERM_VECTOR_WITH_POSITIONS; - break; - case 3: - tvVal = Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS; - break; + switch (nextInt(4)) { + case 0: + tvVal = Field::TERM_VECTOR_NO; + break; + case 1: + tvVal = Field::TERM_VECTOR_YES; + break; + case 2: + tvVal = Field::TERM_VECTOR_WITH_POSITIONS; + break; + case 3: + tvVal = Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS; + break; } - switch (nextInt(4)) - { - case 0: - fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(1), Field::STORE_YES, Field::INDEX_ANALYZED_NO_NORMS, tvVal)); - break; - case 1: - fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(0), Field::STORE_NO, Field::INDEX_ANALYZED, tvVal)); - break; - case 2: - fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(0), Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_NO)); - break; - case 3: - fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(bigFieldSize), Field::STORE_YES, Field::INDEX_ANALYZED, tvVal)); - break; + switch (nextInt(4)) { + case 0: + fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(1), Field::STORE_YES, Field::INDEX_ANALYZED_NO_NORMS, tvVal)); + break; + case 1: + fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(0), Field::STORE_NO, Field::INDEX_ANALYZED, tvVal)); + break; + case 2: + fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(0), Field::STORE_YES, Field::INDEX_NO, Field::TERM_VECTOR_NO)); + break; + case 3: + fields.add(newLucene(L"f" + StringUtils::toString(nextInt(100)), getString(bigFieldSize), Field::STORE_YES, Field::INDEX_ANALYZED, tvVal)); + break; } } - if (sameFieldOrder) + if (sameFieldOrder) { std::sort(fields.begin(), fields.end(), lessFieldName()); - else - { + } else { // random placement of id field also std::swap(*fields.begin(), *(fields.begin() + nextInt(fields.size()))); } - for (int32_t i = 0; i < fields.size(); ++i) + for (int32_t i = 0; i < fields.size(); ++i) { d->add(fields[i]); + } w->updateDocument(newLucene(L"id", L"")->createTerm(idString), d); docs.put(idString, d); } - void deleteDoc() - { + void deleteDoc() { String idString = getIdString(); w->deleteDocuments(newLucene(L"id", L"")->createTerm(idString)); docs.remove(idString); } - void deleteByQuery() - { + void deleteByQuery() { String idString = getIdString(); w->deleteDocuments(newLucene(newLucene(L"id", L"")->createTerm(idString))); docs.remove(idString); } - virtual void run() - { - try - { + virtual void run() { + try { r->setSeed(base + range + seed); - for (int32_t i = 0; i < iterations; ++i) - { + for (int32_t i = 0; i < iterations; ++i) { int32_t what = nextInt(100); - if (what < 5) + if (what < 5) { deleteDoc(); - else if (what < 10) + } else if (what < 10) { deleteByQuery(); - else + } else { indexDoc(); + } } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } @@ -304,8 +278,7 @@ static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, con static void verifyEquals(const DocumentPtr& d1, const DocumentPtr& d2); static void verifyEquals(Collection d1, Collection d2); -static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iterations, int32_t range, const DirectoryPtr& dir) -{ +static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iterations, int32_t range, const DirectoryPtr& dir) { HashMap docs = HashMap::newInstance(); IndexWriterPtr w = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); w->setUseCompoundFile(false); @@ -316,8 +289,7 @@ static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iteratio w->setMaxBufferedDocs(maxBufferedDocs); Collection threads = Collection::newInstance(numThreads); - for (int32_t i = 0; i < threads.size(); ++i) - { + for (int32_t i = 0; i < threads.size(); ++i) { IndexingThreadPtr th = newLucene(); th->w = w; th->base = 1000000 * i; @@ -326,13 +298,14 @@ static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iteratio threads[i] = th; } - for (int32_t i = 0; i < threads.size(); ++i) + for (int32_t i = 0; i < threads.size(); ++i) { threads[i]->start(); - for (int32_t i = 0; i < threads.size(); ++i) + } + for (int32_t i = 0; i < threads.size(); ++i) { threads[i]->join(); + } - for (int32_t i = 0; i < threads.size(); ++i) - { + for (int32_t i = 0; i < threads.size(); ++i) { IndexingThreadPtr th = threads[i]; SyncLock syncLock(th); docs.putAll(th->docs.begin(), th->docs.end()); @@ -345,12 +318,10 @@ static DocsAndWriterPtr indexRandomIWReader(int32_t numThreads, int32_t iteratio return dw; } -static HashMap indexRandom(int32_t numThreads, int32_t iterations, int32_t range, const DirectoryPtr& dir) -{ +static HashMap indexRandom(int32_t numThreads, int32_t iterations, int32_t range, const DirectoryPtr& dir) { HashMap docs = HashMap::newInstance(); - for (int32_t iter = 0; iter < 3; ++iter) - { + for (int32_t iter = 0; iter < 3; ++iter) { IndexWriterPtr w = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); w->setUseCompoundFile(false); @@ -360,8 +331,7 @@ static HashMap indexRandom(int32_t numThreads, int32_t iter w->setMaxBufferedDocs(maxBufferedDocs); Collection threads = Collection::newInstance(numThreads); - for (int32_t i = 0; i < threads.size(); ++i) - { + for (int32_t i = 0; i < threads.size(); ++i) { IndexingThreadPtr th = newLucene(); th->w = w; th->base = 1000000 * i; @@ -370,15 +340,16 @@ static HashMap indexRandom(int32_t numThreads, int32_t iter threads[i] = th; } - for (int32_t i = 0; i < threads.size(); ++i) + for (int32_t i = 0; i < threads.size(); ++i) { threads[i]->start(); - for (int32_t i = 0; i < threads.size(); ++i) + } + for (int32_t i = 0; i < threads.size(); ++i) { threads[i]->join(); + } w->close(); - for (int32_t i = 0; i < threads.size(); ++i) - { + for (int32_t i = 0; i < threads.size(); ++i) { IndexingThreadPtr th = threads[i]; SyncLock syncLock(th); docs.putAll(th->docs.begin(), th->docs.end()); @@ -390,13 +361,11 @@ static HashMap indexRandom(int32_t numThreads, int32_t iter return docs; } -static void indexSerial(HashMap docs, const DirectoryPtr& dir) -{ +static void indexSerial(HashMap docs, const DirectoryPtr& dir) { IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); // index all docs in a single thread - for (HashMap::iterator iter = docs.begin(); iter != docs.end(); ++iter) - { + for (HashMap::iterator iter = docs.begin(); iter != docs.end(); ++iter) { DocumentPtr d = iter->second; Collection fields = d->getFields(); @@ -405,22 +374,21 @@ static void indexSerial(HashMap docs, const DirectoryPtr& d DocumentPtr d1 = newLucene(); d1->setBoost(d->getBoost()); - for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) + for (Collection::iterator field = fields.begin(); field != fields.end(); ++field) { d1->add(*field); + } w->addDocument(d1); } w->close(); } -static void verifyEquals(const IndexReaderPtr& r1, const DirectoryPtr& dir2, const String& idField) -{ +static void verifyEquals(const IndexReaderPtr& r1, const DirectoryPtr& dir2, const String& idField) { IndexReaderPtr r2 = IndexReader::open(dir2, true); verifyEquals(r1, r2, idField); r2->close(); } -static void verifyEquals(const DirectoryPtr& dir1, const DirectoryPtr& dir2, const String& idField) -{ +static void verifyEquals(const DirectoryPtr& dir1, const DirectoryPtr& dir2, const String& idField) { IndexReaderPtr r1 = IndexReader::open(dir1, true); IndexReaderPtr r2 = IndexReader::open(dir2, true); verifyEquals(r1, r2, idField); @@ -428,8 +396,7 @@ static void verifyEquals(const DirectoryPtr& dir1, const DirectoryPtr& dir2, con r2->close(); } -static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, const String& idField) -{ +static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, const String& idField) { EXPECT_EQ(r1->numDocs(), r2->numDocs()); bool hasDeletes = !(r1->maxDoc() == r2->maxDoc() && r1->numDocs() == r1->maxDoc()); @@ -441,15 +408,14 @@ static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, con // create mapping from id2 space to id2 based on idField TermEnumPtr termEnum = r1->terms(newLucene(idField, L"")); - do - { + do { TermPtr term = termEnum->term(); - if (!term || term->field() != idField) + if (!term || term->field() != idField) { break; + } termDocs1->seek(termEnum); - if (!termDocs1->next()) - { + if (!termDocs1->next()) { // This doc is deleted and wasn't replaced termDocs2->seek(termEnum); EXPECT_TRUE(!termDocs2->next()); @@ -471,8 +437,7 @@ static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, con // verify term vectors are equivalent EXPECT_NO_THROW(verifyEquals(r1->getTermFreqVectors(id1), r2->getTermFreqVectors(id2))); - } - while (termEnum->next()); + } while (termEnum->next()); termEnum->close(); @@ -484,61 +449,64 @@ static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, con Collection info1 = Collection::newInstance(r1->numDocs()); Collection info2 = Collection::newInstance(r2->numDocs()); - while (true) - { + while (true) { TermPtr term1; TermPtr term2; // iterate until we get some docs int32_t len1 = 0; - while (true) - { + while (true) { len1 = 0; term1 = termEnum1->term(); - if (!term1) + if (!term1) { break; + } termDocs1->seek(termEnum1); - while (termDocs1->next()) - { + while (termDocs1->next()) { int32_t d1 = termDocs1->doc(); int32_t f1 = termDocs1->freq(); info1[len1] = (((int64_t)d1) << 32) | f1; len1++; } - if (len1 > 0) + if (len1 > 0) { break; - if (!termEnum1->next()) + } + if (!termEnum1->next()) { break; + } } // iterate until we get some docs int32_t len2 = 0; - while (true) - { + while (true) { len2 = 0; term2 = termEnum2->term(); - if (!term2) + if (!term2) { break; + } termDocs2->seek(termEnum2); - while (termDocs2->next()) - { + while (termDocs2->next()) { int32_t d2 = termDocs2->doc(); int32_t f2 = termDocs2->freq(); info2[len2] = (((int64_t)r2r1[d2]) << 32) | f2; len2++; } - if (len2 > 0) + if (len2 > 0) { break; - if (!termEnum2->next()) + } + if (!termEnum2->next()) { break; + } } - if (!hasDeletes) + if (!hasDeletes) { EXPECT_EQ(termEnum1->docFreq(), termEnum2->docFreq()); + } EXPECT_EQ(len1, len2); - if (len1 == 0) - break; // no more terms + if (len1 == 0) { + break; // no more terms + } EXPECT_EQ(term1, term2); @@ -546,16 +514,16 @@ static void verifyEquals(const IndexReaderPtr& r1, const IndexReaderPtr& r2, con std::sort(info2.begin(), info2.begin() + len2); // now compare - for (int32_t i = 0; i < len1; ++i) + for (int32_t i = 0; i < len1; ++i) { EXPECT_EQ(info1[i], info2[i]); + } termEnum1->next(); termEnum2->next(); } } -static void verifyEquals(const DocumentPtr& d1, const DocumentPtr& d2) -{ +static void verifyEquals(const DocumentPtr& d1, const DocumentPtr& d2) { Collection ff1 = d1->getFields(); Collection ff2 = d2->getFields(); @@ -564,21 +532,19 @@ static void verifyEquals(const DocumentPtr& d1, const DocumentPtr& d2) EXPECT_EQ(ff1.size(), ff2.size()); - for (int32_t i = 0; i < ff1.size(); ++i) - { + for (int32_t i = 0; i < ff1.size(); ++i) { FieldablePtr f1 = ff1[i]; FieldablePtr f2 = ff2[i]; - if (f1->isBinary()) + if (f1->isBinary()) { EXPECT_TRUE(f2->isBinary()); - else + } else { EXPECT_EQ(f1->stringValue(), f2->stringValue()); + } } } -static void verifyEquals(Collection d1, Collection d2) -{ - if (!d1) - { +static void verifyEquals(Collection d1, Collection d2) { + if (!d1) { EXPECT_TRUE(!d2); return; } @@ -586,8 +552,7 @@ static void verifyEquals(Collection d1, Collectionsize(), v2->size()); @@ -596,32 +561,28 @@ static void verifyEquals(Collection d1, Collection terms2 = v2->getTerms(); Collection freq1 = v1->getTermFrequencies(); Collection freq2 = v2->getTermFrequencies(); - for (int32_t j = 0; j < numTerms; ++j) - { + for (int32_t j = 0; j < numTerms; ++j) { EXPECT_EQ(terms1[j], terms2[j]); EXPECT_EQ(freq1[j], freq2[j]); } - if (boost::dynamic_pointer_cast(v1)) - { + if (boost::dynamic_pointer_cast(v1)) { EXPECT_TRUE(boost::dynamic_pointer_cast(v2)); SegmentTermPositionVectorPtr tpv1 = boost::dynamic_pointer_cast(v1); SegmentTermPositionVectorPtr tpv2 = boost::dynamic_pointer_cast(v2); - for (int32_t j = 0; j < numTerms; ++j) - { + for (int32_t j = 0; j < numTerms; ++j) { Collection pos1 = tpv1->getTermPositions(j); Collection pos2 = tpv2->getTermPositions(j); EXPECT_EQ(pos1.size(), pos2.size()); Collection offsets1 = tpv1->getOffsets(j); Collection offsets2 = tpv2->getOffsets(j); - if (!offsets1) + if (!offsets1) { EXPECT_TRUE(!offsets2); - else + } else { EXPECT_TRUE(offsets2); - for (int32_t k = 0; k < pos1.size(); ++k) - { + } + for (int32_t k = 0; k < pos1.size(); ++k) { EXPECT_EQ(pos1[k], pos2[k]); - if (offsets1) - { + if (offsets1) { EXPECT_EQ(offsets1[k]->getStartOffset(), offsets2[k]->getStartOffset()); EXPECT_EQ(offsets1[k]->getEndOffset(), offsets2[k]->getEndOffset()); } @@ -631,125 +592,110 @@ static void verifyEquals(Collection d1, Collectionfailed = false; - this->RUN_TIME_SEC = 6; - this->rand = newLucene(); - } +namespace RunStressTest { - virtual ~StressTimedThread() - { - } +DECLARE_SHARED_PTR(StressTimedThread) +DECLARE_SHARED_PTR(StressIndexerThread) +DECLARE_SHARED_PTR(StressSearcherThread) - LUCENE_CLASS(StressTimedThread); +class StressTimedThread : public LuceneThread { +public: + StressTimedThread() { + this->failed = false; + this->RUN_TIME_SEC = 6; + this->rand = newLucene(); + } - public: - bool failed; + virtual ~StressTimedThread() { + } - protected: - int32_t RUN_TIME_SEC; - RandomPtr rand; + LUCENE_CLASS(StressTimedThread); - public: - virtual void doWork() = 0; +public: + bool failed; - virtual void run() - { - int64_t stopTime = MiscUtils::currentTimeMillis() + 1000 * RUN_TIME_SEC; +protected: + int32_t RUN_TIME_SEC; + RandomPtr rand; - try - { - while ((int64_t)MiscUtils::currentTimeMillis() < stopTime && !failed) - doWork(); - } - catch (LuceneException& e) - { - failed = true; - FAIL() << "Unexpected exception: " << e.getError(); +public: + virtual void doWork() = 0; + + virtual void run() { + int64_t stopTime = MiscUtils::currentTimeMillis() + 1000 * RUN_TIME_SEC; + + try { + while ((int64_t)MiscUtils::currentTimeMillis() < stopTime && !failed) { + doWork(); } + } catch (LuceneException& e) { + failed = true; + FAIL() << "Unexpected exception: " << e.getError(); } - }; - - class StressIndexerThread : public StressTimedThread - { - public: - StressIndexerThread(const IndexWriterPtr& writer) - { - this->writer = writer; - this->nextID = 0; - } + } +}; - virtual ~StressIndexerThread() - { - } +class StressIndexerThread : public StressTimedThread { +public: + StressIndexerThread(const IndexWriterPtr& writer) { + this->writer = writer; + this->nextID = 0; + } - LUCENE_CLASS(StressIndexerThread); - - public: - IndexWriterPtr writer; - int32_t nextID; - - public: - virtual void doWork() - { - // Add 10 docs - for (int32_t i = 0; i < 10; ++i) - { - DocumentPtr d = newLucene(); - d->add(newLucene(L"id", StringUtils::toString(nextID++), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - d->add(newLucene(L"contents", intToEnglish(rand->nextInt()), Field::STORE_NO, Field::INDEX_ANALYZED)); - writer->addDocument(d); - } + virtual ~StressIndexerThread() { + } - // Delete 5 docs - int32_t deleteID = nextID - 1; - for (int32_t i = 0; i < 5; ++i) - { - writer->deleteDocuments(newLucene(L"id", StringUtils::toString(deleteID))); - deleteID -= 2; - } - } - }; - - class StressSearcherThread : public StressTimedThread - { - public: - StressSearcherThread(const DirectoryPtr& directory) - { - this->directory = directory; + LUCENE_CLASS(StressIndexerThread); + +public: + IndexWriterPtr writer; + int32_t nextID; + +public: + virtual void doWork() { + // Add 10 docs + for (int32_t i = 0; i < 10; ++i) { + DocumentPtr d = newLucene(); + d->add(newLucene(L"id", StringUtils::toString(nextID++), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + d->add(newLucene(L"contents", intToEnglish(rand->nextInt()), Field::STORE_NO, Field::INDEX_ANALYZED)); + writer->addDocument(d); } - virtual ~StressSearcherThread() - { + // Delete 5 docs + int32_t deleteID = nextID - 1; + for (int32_t i = 0; i < 5; ++i) { + writer->deleteDocuments(newLucene(L"id", StringUtils::toString(deleteID))); + deleteID -= 2; } + } +}; - LUCENE_CLASS(StressSearcherThread); +class StressSearcherThread : public StressTimedThread { +public: + StressSearcherThread(const DirectoryPtr& directory) { + this->directory = directory; + } - protected: - DirectoryPtr directory; + virtual ~StressSearcherThread() { + } - public: - virtual void doWork() - { - for (int32_t i = 0; i < 100; ++i) - newLucene(directory, true)->close(); + LUCENE_CLASS(StressSearcherThread); + +protected: + DirectoryPtr directory; + +public: + virtual void doWork() { + for (int32_t i = 0; i < 100; ++i) { + newLucene(directory, true)->close(); } - }; + } +}; + } /// Run one indexer and 2 searchers against single index as stress test. -static void runStressTest(const DirectoryPtr& directory, const MergeSchedulerPtr& mergeScheduler) -{ +static void runStressTest(const DirectoryPtr& directory, const MergeSchedulerPtr& mergeScheduler) { AnalyzerPtr analyzer = newLucene(); IndexWriterPtr modifier = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -758,8 +704,9 @@ static void runStressTest(const DirectoryPtr& directory, const MergeSchedulerPtr Collection threads = Collection::newInstance(4); int32_t numThread = 0; - if (mergeScheduler) + if (mergeScheduler) { modifier->setMergeScheduler(mergeScheduler); + } // One modifier that writes 10 docs then removes 5, over and over RunStressTest::StressIndexerThreadPtr indexerThread1 = newLucene(modifier); @@ -779,8 +726,9 @@ static void runStressTest(const DirectoryPtr& directory, const MergeSchedulerPtr threads[numThread++] = searcherThread2; searcherThread2->start(); - for (int32_t i = 0; i < numThread; ++i) + for (int32_t i = 0; i < numThread; ++i) { threads[i]->join(); + } modifier->close(); @@ -790,8 +738,7 @@ static void runStressTest(const DirectoryPtr& directory, const MergeSchedulerPtr EXPECT_TRUE(!searcherThread2->failed); // hit unexpected exception in search2 } -TEST_F(StressIndexingTest, testStressIndexAndSearching) -{ +TEST_F(StressIndexingTest, testStressIndexAndSearching) { // With ConcurrentMergeScheduler, in RAMDir DirectoryPtr directory = newLucene(); runStressTest(directory, newLucene()); @@ -807,8 +754,7 @@ TEST_F(StressIndexingTest, testStressIndexAndSearching) FileUtils::removeDirectory(dirPath); } -TEST_F(StressIndexingTest, testRandomIWReader) -{ +TEST_F(StressIndexingTest, testRandomIWReader) { DirectoryPtr dir = newLucene(); DocsAndWriterPtr dw = indexRandomIWReader(10, 100, 100, dir); @@ -820,8 +766,7 @@ TEST_F(StressIndexingTest, testRandomIWReader) dir->close(); } -TEST_F(StressIndexingTest, testRandom) -{ +TEST_F(StressIndexingTest, testRandom) { DirectoryPtr dir1 = newLucene(); DirectoryPtr dir2 = newLucene(); @@ -831,12 +776,10 @@ TEST_F(StressIndexingTest, testRandom) verifyEquals(dir1, dir2, L"id"); } -TEST_F(StressIndexingTest, testMultiConfig) -{ +TEST_F(StressIndexingTest, testMultiConfig) { RandomPtr r = newLucene(); // test lots of smaller different params together - for (int32_t i = 0; i < 100; ++i) // increase iterations for better testing - { + for (int32_t i = 0; i < 100; ++i) { // increase iterations for better testing sameFieldOrder = (r->nextInt() % 2 == 1); mergeFactor = r->nextInt(3) + 2; maxBufferedDocs = r->nextInt(3) + 2; diff --git a/src/test/index/TermDocsPerfTest.cpp b/src/test/index/TermDocsPerfTest.cpp index 70149ad9..43b7c3c8 100644 --- a/src/test/index/TermDocsPerfTest.cpp +++ b/src/test/index/TermDocsPerfTest.cpp @@ -27,18 +27,15 @@ typedef LuceneTestFixture TermDocsPerfTest; DECLARE_SHARED_PTR(RepeatingTokenStream) -class RepeatingTokenStream : public TokenStream -{ +class RepeatingTokenStream : public TokenStream { public: - RepeatingTokenStream(const String& val) - { + RepeatingTokenStream(const String& val) { this->num = 0; this->value = val; this->termAtt = addAttribute(); } - virtual ~RepeatingTokenStream() - { + virtual ~RepeatingTokenStream() { } LUCENE_CLASS(RepeatingTokenStream); @@ -49,11 +46,9 @@ class RepeatingTokenStream : public TokenStream String value; public: - virtual bool incrementToken() - { + virtual bool incrementToken() { --num; - if (num >= 0) - { + if (num >= 0) { clearAttributes(); termAtt->setTermBuffer(value); return true; @@ -62,19 +57,16 @@ class RepeatingTokenStream : public TokenStream } }; -class TermDocsPerfTestAnalyzer : public Analyzer -{ +class TermDocsPerfTestAnalyzer : public Analyzer { public: - TermDocsPerfTestAnalyzer(const RepeatingTokenStreamPtr& ts, const RandomPtr& random, int32_t maxTF, double percentDocs) - { + TermDocsPerfTestAnalyzer(const RepeatingTokenStreamPtr& ts, const RandomPtr& random, int32_t maxTF, double percentDocs) { this->ts = ts; this->random = random; this->maxTF = maxTF; this->percentDocs = percentDocs; } - virtual ~TermDocsPerfTestAnalyzer() - { + virtual ~TermDocsPerfTestAnalyzer() { } LUCENE_CLASS(TermDocsPerfTestAnalyzer); @@ -86,18 +78,17 @@ class TermDocsPerfTestAnalyzer : public Analyzer double percentDocs; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - if (random->nextDouble() < percentDocs) + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + if (random->nextDouble() < percentDocs) { ts->num = random->nextInt(maxTF) + 1; - else + } else { ts->num = 0; + } return ts; } }; -static void addDocs(const DirectoryPtr& dir, int32_t numDocs, const String& field, const String& val, int32_t maxTF, double percentDocs) -{ +static void addDocs(const DirectoryPtr& dir, int32_t numDocs, const String& field, const String& val, int32_t maxTF, double percentDocs) { RepeatingTokenStreamPtr ts = newLucene(val); RandomPtr random = newLucene(); AnalyzerPtr analyzer = newLucene(ts, random, maxTF, percentDocs); @@ -108,15 +99,15 @@ static void addDocs(const DirectoryPtr& dir, int32_t numDocs, const String& fiel writer->setMaxBufferedDocs(100); writer->setMergeFactor(100); - for (int32_t i = 0; i < numDocs; ++i) + for (int32_t i = 0; i < numDocs; ++i) { writer->addDocument(doc); + } writer->optimize(); writer->close(); } -TEST_F(TermDocsPerfTest, testTermDocsPerf) -{ +TEST_F(TermDocsPerfTest, testTermDocsPerf) { static const int32_t iter = 100000; static const int32_t numDocs = 10000; static const int32_t maxTF = 3; @@ -136,11 +127,11 @@ TEST_F(TermDocsPerfTest, testTermDocsPerf) start = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < iter; ++i) - { + for (int32_t i = 0; i < iter; ++i) { termDocs->seek(termEnum); - while (termDocs->next()) + while (termDocs->next()) { termDocs->doc(); + } } end = MiscUtils::currentTimeMillis(); diff --git a/src/test/index/TermTest.cpp b/src/test/index/TermTest.cpp index 8cba2b84..ca69bc60 100644 --- a/src/test/index/TermTest.cpp +++ b/src/test/index/TermTest.cpp @@ -13,8 +13,7 @@ using namespace Lucene; typedef LuceneTestFixture TermTest; -TEST_F(TermTest, testEquals) -{ +TEST_F(TermTest, testEquals) { TermPtr base = newLucene(L"same", L"same"); TermPtr same = newLucene(L"same", L"same"); TermPtr differentField = newLucene(L"different", L"same"); diff --git a/src/test/index/TermVectorsReaderTest.cpp b/src/test/index/TermVectorsReaderTest.cpp index dfe12975..a9038edd 100644 --- a/src/test/index/TermVectorsReaderTest.cpp +++ b/src/test/index/TermVectorsReaderTest.cpp @@ -35,18 +35,15 @@ using namespace Lucene; DECLARE_SHARED_PTR(TestToken) -class TestToken : public LuceneObject -{ +class TestToken : public LuceneObject { public: - TestToken() - { + TestToken() { pos = 0; startOffset = 0; endOffset = 0; } - virtual ~TestToken() - { + virtual ~TestToken() { } LUCENE_CLASS(TestToken); @@ -58,17 +55,14 @@ class TestToken : public LuceneObject int32_t endOffset; public: - int32_t compareTo(const TestTokenPtr& other) - { + int32_t compareTo(const TestTokenPtr& other) { return (pos - other->pos); } }; -class MyTokenStream : public TokenStream -{ +class MyTokenStream : public TokenStream { public: - MyTokenStream(Collection tokens) - { + MyTokenStream(Collection tokens) { this->tokens = tokens; tokenUpto = 0; @@ -77,8 +71,7 @@ class MyTokenStream : public TokenStream offsetAtt = addAttribute(); } - virtual ~MyTokenStream() - { + virtual ~MyTokenStream() { } LUCENE_CLASS(MyTokenStream); @@ -94,35 +87,31 @@ class MyTokenStream : public TokenStream OffsetAttributePtr offsetAtt; public: - virtual bool incrementToken() - { - if (tokenUpto >= tokens.size()) + virtual bool incrementToken() { + if (tokenUpto >= tokens.size()) { return false; - else - { + } else { TestTokenPtr testToken = tokens[tokenUpto++]; clearAttributes(); termAtt->setTermBuffer(testToken->text); offsetAtt->setOffset(testToken->startOffset, testToken->endOffset); - if (tokenUpto > 1) + if (tokenUpto > 1) { posIncrAtt->setPositionIncrement(testToken->pos - tokens[tokenUpto - 2]->pos); - else + } else { posIncrAtt->setPositionIncrement(testToken->pos + 1); + } } return true; } }; -class MyAnalyzer : public Analyzer -{ +class MyAnalyzer : public Analyzer { public: - MyAnalyzer(Collection tokens) - { + MyAnalyzer(Collection tokens) { this->tokens = tokens; } - virtual ~MyAnalyzer() - { + virtual ~MyAnalyzer() { } LUCENE_CLASS(MyAnalyzer); @@ -131,24 +120,20 @@ class MyAnalyzer : public Analyzer Collection tokens; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(tokens); } }; DECLARE_SHARED_PTR(DocNumAwareMapper) -class DocNumAwareMapper : public TermVectorMapper -{ +class DocNumAwareMapper : public TermVectorMapper { public: - DocNumAwareMapper() - { + DocNumAwareMapper() { documentNumber = -1; } - virtual ~DocNumAwareMapper() - { + virtual ~DocNumAwareMapper() { } LUCENE_CLASS(DocNumAwareMapper); @@ -157,34 +142,30 @@ class DocNumAwareMapper : public TermVectorMapper int32_t documentNumber; public: - virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) - { - if (documentNumber == -1) + virtual void setExpectations(const String& field, int32_t numTerms, bool storeOffsets, bool storePositions) { + if (documentNumber == -1) { FAIL() << "Documentnumber should be set at this point!"; + } } - virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions) - { - if (documentNumber == -1) + virtual void map(const String& term, int32_t frequency, Collection offsets, Collection positions) { + if (documentNumber == -1) { FAIL() << "Documentnumber should be set at this point!"; + } } - virtual int32_t getDocumentNumber() - { + virtual int32_t getDocumentNumber() { return documentNumber; } - virtual void setDocumentNumber(int32_t documentNumber) - { + virtual void setDocumentNumber(int32_t documentNumber) { this->documentNumber = documentNumber; } }; -class TermVectorsReaderTest : public LuceneTestFixture -{ +class TermVectorsReaderTest : public LuceneTestFixture { public: - TermVectorsReaderTest() - { + TermVectorsReaderTest() { // Must be lexicographically sorted, will do in setup, versus trying to maintain here testFields = newCollection(L"f1", L"f2", L"f3", L"f4"); testFieldsStorePos = newCollection(true, false, true, false); @@ -199,13 +180,11 @@ class TermVectorsReaderTest : public LuceneTestFixture std::sort(testTerms.begin(), testTerms.end()); int32_t tokenUpto = 0; - for (int32_t i = 0; i < testTerms.size(); ++i) - { + for (int32_t i = 0; i < testTerms.size(); ++i) { positions[i] = Collection::newInstance(TERM_FREQ); offsets[i] = Collection::newInstance(TERM_FREQ); // first position must be 0 - for (int32_t j = 0; j < TERM_FREQ; ++j) - { + for (int32_t j = 0; j < TERM_FREQ; ++j) { // positions are always sorted in increasing order positions[i][j] = (int32_t)(j * 10 + (int32_t)((double)random->nextInt(100) / 100.0) * 10); // offsets are always sorted in increasing order @@ -223,21 +202,22 @@ class TermVectorsReaderTest : public LuceneTestFixture IndexWriterPtr writer = newLucene(dir, newLucene(tokens), true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(false); DocumentPtr doc = newLucene(); - for (int32_t i = 0; i < testFields.size(); ++i) - { + for (int32_t i = 0; i < testFields.size(); ++i) { Field::TermVector tv = Field::TERM_VECTOR_YES; - if (testFieldsStorePos[i] && testFieldsStoreOff[i]) + if (testFieldsStorePos[i] && testFieldsStoreOff[i]) { tv = Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS; - else if (testFieldsStorePos[i] && !testFieldsStoreOff[i]) + } else if (testFieldsStorePos[i] && !testFieldsStoreOff[i]) { tv = Field::TERM_VECTOR_WITH_POSITIONS; - else if (!testFieldsStorePos[i] && testFieldsStoreOff[i]) + } else if (!testFieldsStorePos[i] && testFieldsStoreOff[i]) { tv = Field::TERM_VECTOR_WITH_OFFSETS; + } doc->add(newLucene(testFields[i], L"", Field::STORE_NO, Field::INDEX_ANALYZED, tv)); } // Create 5 documents for testing, they all have the same terms - for (int32_t j = 0; j < 5; ++j) + for (int32_t j = 0; j < 5; ++j) { writer->addDocument(doc); + } writer->commit(); seg = writer->newestSegment()->name; @@ -246,8 +226,7 @@ class TermVectorsReaderTest : public LuceneTestFixture fieldInfos = newLucene(dir, seg + L"." + IndexFileNames::FIELD_INFOS_EXTENSION()); } - virtual ~TermVectorsReaderTest() - { + virtual ~TermVectorsReaderTest() { } protected: @@ -267,8 +246,7 @@ class TermVectorsReaderTest : public LuceneTestFixture const int32_t TermVectorsReaderTest::TERM_FREQ = 3; -TEST_F(TermVectorsReaderTest, testReader) -{ +TEST_F(TermVectorsReaderTest, testReader) { // Check to see the files were created properly in setup EXPECT_TRUE(dir->fileExists(seg + L"." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION())); EXPECT_TRUE(dir->fileExists(seg + L"." + IndexFileNames::VECTORS_INDEX_EXTENSION())); @@ -276,20 +254,19 @@ TEST_F(TermVectorsReaderTest, testReader) TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); EXPECT_TRUE(reader); - for (int32_t j = 0; j < 5; ++j) - { + for (int32_t j = 0; j < 5; ++j) { TermFreqVectorPtr vector = reader->get(j, testFields[0]); EXPECT_TRUE(vector); Collection terms = vector->getTerms(); EXPECT_TRUE(terms); EXPECT_EQ(terms.size(), testTerms.size()); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { EXPECT_EQ(terms[i], testTerms[i]); + } } } -TEST_F(TermVectorsReaderTest, testPositionReader) -{ +TEST_F(TermVectorsReaderTest, testPositionReader) { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); EXPECT_TRUE(reader); TermPositionVectorPtr vector = boost::dynamic_pointer_cast(reader->get(0, testFields[0])); @@ -297,20 +274,19 @@ TEST_F(TermVectorsReaderTest, testPositionReader) Collection terms = vector->getTerms(); EXPECT_TRUE(terms); EXPECT_EQ(terms.size(), testTerms.size()); - for (int32_t i = 0; i < terms.size(); ++i) - { + for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; EXPECT_EQ(term, testTerms[i]); Collection positions = vector->getTermPositions(i); EXPECT_TRUE(positions); EXPECT_EQ(positions.size(), this->positions[i].size()); - for (int32_t j = 0; j < positions.size(); ++j) + for (int32_t j = 0; j < positions.size(); ++j) { EXPECT_EQ(positions[j], this->positions[i][j]); + } Collection offset = vector->getOffsets(i); EXPECT_TRUE(offset); EXPECT_EQ(offset.size(), this->offsets[i].size()); - for (int32_t j = 0; j < offset.size(); ++j) - { + for (int32_t j = 0; j < offset.size(); ++j) { TermVectorOffsetInfoPtr termVectorOffsetInfo = offset[j]; EXPECT_TRUE(termVectorOffsetInfo->equals(offsets[i][j])); } @@ -322,12 +298,12 @@ TEST_F(TermVectorsReaderTest, testPositionReader) terms = freqVector->getTerms(); EXPECT_TRUE(terms); EXPECT_EQ(terms.size(), testTerms.size()); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { EXPECT_EQ(terms[i], testTerms[i]); + } } -TEST_F(TermVectorsReaderTest, testOffsetReader) -{ +TEST_F(TermVectorsReaderTest, testOffsetReader) { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); EXPECT_TRUE(reader); TermPositionVectorPtr vector = boost::dynamic_pointer_cast(reader->get(0, testFields[0])); @@ -335,28 +311,26 @@ TEST_F(TermVectorsReaderTest, testOffsetReader) Collection terms = vector->getTerms(); EXPECT_TRUE(terms); EXPECT_EQ(terms.size(), testTerms.size()); - for (int32_t i = 0; i < terms.size(); ++i) - { + for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; EXPECT_EQ(term, testTerms[i]); Collection positions = vector->getTermPositions(i); EXPECT_TRUE(positions); EXPECT_EQ(positions.size(), this->positions[i].size()); - for (int32_t j = 0; j < positions.size(); ++j) + for (int32_t j = 0; j < positions.size(); ++j) { EXPECT_EQ(positions[j], this->positions[i][j]); + } Collection offset = vector->getOffsets(i); EXPECT_TRUE(offset); EXPECT_EQ(offset.size(), this->offsets[i].size()); - for (int32_t j = 0; j < offset.size(); ++j) - { + for (int32_t j = 0; j < offset.size(); ++j) { TermVectorOffsetInfoPtr termVectorOffsetInfo = offset[j]; EXPECT_TRUE(termVectorOffsetInfo->equals(offsets[i][j])); } } } -TEST_F(TermVectorsReaderTest, testMapper) -{ +TEST_F(TermVectorsReaderTest, testMapper) { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); EXPECT_TRUE(reader); SortedTermVectorMapperPtr mapper = newLucene(TermVectorEntryFreqSortedComparator::compare); @@ -366,8 +340,7 @@ TEST_F(TermVectorsReaderTest, testMapper) // three fields, 4 terms, all terms are the same EXPECT_EQ(entrySet.size(), 4); // check offsets and positions - for (Collection::iterator tve = entrySet.begin(); tve != entrySet.end(); ++tve) - { + for (Collection::iterator tve = entrySet.begin(); tve != entrySet.end(); ++tve) { EXPECT_TRUE(*tve); EXPECT_TRUE((*tve)->getOffsets()); EXPECT_TRUE((*tve)->getPositions()); @@ -380,8 +353,7 @@ TEST_F(TermVectorsReaderTest, testMapper) // three fields, 4 terms, all terms are the same EXPECT_EQ(entrySet.size(), 4); // should have offsets and positions because we are munging all the fields together - for (Collection::iterator tve = entrySet.begin(); tve != entrySet.end(); ++tve) - { + for (Collection::iterator tve = entrySet.begin(); tve != entrySet.end(); ++tve) { EXPECT_TRUE(*tve); EXPECT_TRUE((*tve)->getOffsets()); EXPECT_TRUE((*tve)->getPositions()); @@ -391,23 +363,18 @@ TEST_F(TermVectorsReaderTest, testMapper) reader->get(0, fsMapper); MapStringCollectionTermVectorEntry map = fsMapper->getFieldToTerms(); EXPECT_EQ(map.size(), testFields.size()); - for (MapStringCollectionTermVectorEntry::iterator entry = map.begin(); entry != map.end(); ++entry) - { + for (MapStringCollectionTermVectorEntry::iterator entry = map.begin(); entry != map.end(); ++entry) { Collection termVectorEntries = entry->second; EXPECT_EQ(termVectorEntries.size(), 4); - for (Collection::iterator tve = termVectorEntries.begin(); tve != termVectorEntries.end(); ++tve) - { + for (Collection::iterator tve = termVectorEntries.begin(); tve != termVectorEntries.end(); ++tve) { EXPECT_TRUE(*tve); // Check offsets and positions. String field = (*tve)->getField(); - if (field == testFields[0]) - { + if (field == testFields[0]) { // should have offsets EXPECT_TRUE((*tve)->getOffsets()); EXPECT_TRUE((*tve)->getPositions()); - } - else if (field == testFields[1]) - { + } else if (field == testFields[1]) { // should not have offsets EXPECT_TRUE(!(*tve)->getOffsets()); EXPECT_TRUE(!(*tve)->getPositions()); @@ -420,23 +387,18 @@ TEST_F(TermVectorsReaderTest, testMapper) reader->get(0, fsMapper); map = fsMapper->getFieldToTerms(); EXPECT_EQ(map.size(), testFields.size()); - for (MapStringCollectionTermVectorEntry::iterator entry = map.begin(); entry != map.end(); ++entry) - { + for (MapStringCollectionTermVectorEntry::iterator entry = map.begin(); entry != map.end(); ++entry) { Collection termVectorEntries = entry->second; EXPECT_EQ(termVectorEntries.size(), 4); - for (Collection::iterator tve = termVectorEntries.begin(); tve != termVectorEntries.end(); ++tve) - { + for (Collection::iterator tve = termVectorEntries.begin(); tve != termVectorEntries.end(); ++tve) { EXPECT_TRUE(*tve); // Check offsets and positions. String field = (*tve)->getField(); - if (field == testFields[0]) - { + if (field == testFields[0]) { // should have offsets EXPECT_TRUE(!(*tve)->getOffsets()); EXPECT_TRUE(!(*tve)->getPositions()); - } - else if (field == testFields[1]) - { + } else if (field == testFields[1]) { // should not have offsets EXPECT_TRUE(!(*tve)->getOffsets()); EXPECT_TRUE(!(*tve)->getPositions()); @@ -472,18 +434,14 @@ TEST_F(TermVectorsReaderTest, testMapper) } /// Make sure exceptions and bad params are handled appropriately -TEST_F(TermVectorsReaderTest, testBadParams) -{ +TEST_F(TermVectorsReaderTest, testBadParams) { { TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); EXPECT_TRUE(reader); // Bad document number, good field number - try - { + try { reader->get(50, testFields[0]); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } } @@ -492,12 +450,9 @@ TEST_F(TermVectorsReaderTest, testBadParams) TermVectorsReaderPtr reader = newLucene(dir, seg, fieldInfos); EXPECT_TRUE(reader); // Bad document number, no field - try - { + try { reader->get(50); - } - catch (IOException& e) - { + } catch (IOException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } } diff --git a/src/test/index/ThreadedOptimizeTest.cpp b/src/test/index/ThreadedOptimizeTest.cpp index 4a02a17b..7222c90d 100644 --- a/src/test/index/ThreadedOptimizeTest.cpp +++ b/src/test/index/ThreadedOptimizeTest.cpp @@ -22,11 +22,9 @@ using namespace Lucene; -class OptimizeThread : public LuceneThread -{ +class OptimizeThread : public LuceneThread { public: - OptimizeThread(int32_t numIter, int32_t iterFinal, int32_t iFinal, const IndexWriterPtr& writer, const IndexWriterPtr& writerFinal) - { + OptimizeThread(int32_t numIter, int32_t iterFinal, int32_t iFinal, const IndexWriterPtr& writer, const IndexWriterPtr& writerFinal) { this->numIter = numIter; this->iterFinal = iterFinal; this->iFinal = iFinal; @@ -34,8 +32,7 @@ class OptimizeThread : public LuceneThread this->writerFinal = writerFinal; } - virtual ~OptimizeThread() - { + virtual ~OptimizeThread() { } LUCENE_CLASS(OptimizeThread); @@ -48,42 +45,34 @@ class OptimizeThread : public LuceneThread IndexWriterPtr writerFinal; public: - virtual void run() - { - try - { - for (int32_t j = 0; j < numIter; ++j) - { + virtual void run() { + try { + for (int32_t j = 0; j < numIter; ++j) { writerFinal->optimize(false); - for (int32_t k = 0; k < 17 * (1 + iFinal); ++k) - { + for (int32_t k = 0; k < 17 * (1 + iFinal); ++k) { DocumentPtr d = newLucene(); d->add(newLucene(L"id", StringUtils::toString(iterFinal) + L"_" + StringUtils::toString(iFinal) + L"_" + StringUtils::toString(j) + L"_" + StringUtils::toString(k), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); d->add(newLucene(L"contents", intToEnglish(iFinal + k), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(d); } - for (int32_t k = 0; k < 9 * (1 + iFinal); ++k) + for (int32_t k = 0; k < 9 * (1 + iFinal); ++k) { writerFinal->deleteDocuments(newLucene(L"id", StringUtils::toString(iterFinal) + L"_" + StringUtils::toString(iFinal) + L"_" + StringUtils::toString(j) + L"_" + StringUtils::toString(k))); + } writerFinal->optimize(); } - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } }; -class ThreadedOptimizeTest : public LuceneTestFixture -{ +class ThreadedOptimizeTest : public LuceneTestFixture { public: - ThreadedOptimizeTest() - { + ThreadedOptimizeTest() { analyzer = newLucene(); } - virtual ~ThreadedOptimizeTest() - { + virtual ~ThreadedOptimizeTest() { } protected: @@ -94,21 +83,19 @@ class ThreadedOptimizeTest : public LuceneTestFixture AnalyzerPtr analyzer; public: - void runTest(const DirectoryPtr& directory, const MergeSchedulerPtr& merger) - { + void runTest(const DirectoryPtr& directory, const MergeSchedulerPtr& merger) { IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setMaxBufferedDocs(2); - if (merger) + if (merger) { writer->setMergeScheduler(merger); + } - for (int32_t iter = 0; iter < NUM_ITER; ++iter) - { + for (int32_t iter = 0; iter < NUM_ITER; ++iter) { int32_t iterFinal = iter; writer->setMergeFactor(1000); - for (int32_t i = 0; i < 200; ++i) - { + for (int32_t i = 0; i < 200; ++i) { DocumentPtr d = newLucene(); d->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); d->add(newLucene(L"contents", intToEnglish(i), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -119,17 +106,18 @@ class ThreadedOptimizeTest : public LuceneTestFixture Collection threads = Collection::newInstance(NUM_THREADS); - for (int32_t i = 0; i < NUM_THREADS; ++i) - { + for (int32_t i = 0; i < NUM_THREADS; ++i) { int32_t iFinal = i; IndexWriterPtr writerFinal = writer; threads[i] = newLucene(NUM_ITER2, iterFinal, iFinal, writer, writerFinal); } - for (int32_t i = 0; i < NUM_THREADS; ++i) + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->start(); - for (int32_t i = 0; i < NUM_THREADS; ++i) + } + for (int32_t i = 0; i < NUM_THREADS; ++i) { threads[i]->join(); + } int32_t expectedDocCount = (int32_t)((1 + iter) * (200 + 8 * NUM_ITER2 * (int32_t)(((double)NUM_THREADS / 2.0) * (double)(1 + NUM_THREADS)))); @@ -152,8 +140,7 @@ const int32_t ThreadedOptimizeTest::NUM_THREADS = 3; const int32_t ThreadedOptimizeTest::NUM_ITER = 1; const int32_t ThreadedOptimizeTest::NUM_ITER2 = 1; -TEST_F(ThreadedOptimizeTest, testThreadedOptimize) -{ +TEST_F(ThreadedOptimizeTest, testThreadedOptimize) { DirectoryPtr directory = newLucene(); runTest(directory, newLucene()); runTest(directory, newLucene()); diff --git a/src/test/index/TransactionRollbackTest.cpp b/src/test/index/TransactionRollbackTest.cpp index 079cf368..a0fe3729 100644 --- a/src/test/index/TransactionRollbackTest.cpp +++ b/src/test/index/TransactionRollbackTest.cpp @@ -21,36 +21,29 @@ using namespace Lucene; /// Keeps all commit points (used to build index) -class TransactionRollbackKeepAllDeletionPolicy : public IndexDeletionPolicy -{ +class TransactionRollbackKeepAllDeletionPolicy : public IndexDeletionPolicy { public: - virtual ~TransactionRollbackKeepAllDeletionPolicy() - { + virtual ~TransactionRollbackKeepAllDeletionPolicy() { } LUCENE_CLASS(TransactionRollbackKeepAllDeletionPolicy); public: - virtual void onInit(Collection commits) - { + virtual void onInit(Collection commits) { } - virtual void onCommit(Collection commits) - { + virtual void onCommit(Collection commits) { } }; /// Rolls back to previous commit point -class RollbackDeletionPolicy : public IndexDeletionPolicy -{ +class RollbackDeletionPolicy : public IndexDeletionPolicy { public: - RollbackDeletionPolicy(int32_t rollbackPoint) - { + RollbackDeletionPolicy(int32_t rollbackPoint) { this->rollbackPoint = rollbackPoint; } - virtual ~RollbackDeletionPolicy() - { + virtual ~RollbackDeletionPolicy() { } LUCENE_CLASS(RollbackDeletionPolicy); @@ -59,46 +52,39 @@ class RollbackDeletionPolicy : public IndexDeletionPolicy int32_t rollbackPoint; public: - virtual void onInit(Collection commits) - { - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { + virtual void onInit(Collection commits) { + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { MapStringString userData = (*commit)->getUserData(); - if (!userData.empty()) - { + if (!userData.empty()) { // Label for a commit point is "Records 1-30" // This code reads the last id ("30" in this example) and deletes it if it is after the desired rollback point String x = userData.get(L"index"); String lastVal = x.substr(x.find_last_of(L"-") + 1); int32_t last = StringUtils::toInt(lastVal); - if (last > rollbackPoint) + if (last > rollbackPoint) { (*commit)->deleteCommit(); + } } } } - virtual void onCommit(Collection commits) - { + virtual void onCommit(Collection commits) { } }; -class DeleteLastCommitPolicy : public IndexDeletionPolicy -{ +class DeleteLastCommitPolicy : public IndexDeletionPolicy { public: - virtual ~DeleteLastCommitPolicy() - { + virtual ~DeleteLastCommitPolicy() { } LUCENE_CLASS(DeleteLastCommitPolicy); public: - virtual void onInit(Collection commits) - { + virtual void onInit(Collection commits) { commits[commits.size() - 1]->deleteCommit(); } - virtual void onCommit(Collection commits) - { + virtual void onCommit(Collection commits) { } }; @@ -106,24 +92,20 @@ class DeleteLastCommitPolicy : public IndexDeletionPolicy /// This test case creates an index of records 1 to 100, introducing a commit point every 10 records. /// /// A "keep all" deletion policy is used to ensure we keep all commit points for testing purposes -class TransactionRollbackTest : public LuceneTestFixture -{ +class TransactionRollbackTest : public LuceneTestFixture { public: - TransactionRollbackTest() - { + TransactionRollbackTest() { FIELD_RECORD_ID = L"record_id"; dir = newLucene(); // Build index, of records 1 to 100, committing after each batch of 10 IndexDeletionPolicyPtr sdp = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), sdp, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t currentRecordId = 1; currentRecordId <= 100; ++currentRecordId) - { + for (int32_t currentRecordId = 1; currentRecordId <= 100; ++currentRecordId) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD_RECORD_ID, StringUtils::toString(currentRecordId), Field::STORE_YES, Field::INDEX_ANALYZED)); w->addDocument(doc); - if (currentRecordId % 10 == 0) - { + if (currentRecordId % 10 == 0) { MapStringString data = MapStringString::newInstance(); data.put(L"index", L"records 1-" + StringUtils::toString(currentRecordId)); w->commit(data); @@ -133,8 +115,7 @@ class TransactionRollbackTest : public LuceneTestFixture w->close(); } - virtual ~TransactionRollbackTest() - { + virtual ~TransactionRollbackTest() { } protected: @@ -143,18 +124,16 @@ class TransactionRollbackTest : public LuceneTestFixture public: /// Rolls back index to a chosen ID - void rollBackLast(int32_t id) - { + void rollBackLast(int32_t id) { String ids = L"-" + StringUtils::toString(id); IndexCommitPtr last; Collection commits = IndexReader::listCommits(dir); - for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) - { + for (Collection::iterator commit = commits.begin(); commit != commits.end(); ++commit) { MapStringString ud = (*commit)->getUserData(); - if (!ud.empty()) - { - if (boost::ends_with(ud.get(L"index"), ids)) + if (!ud.empty()) { + if (boost::ends_with(ud.get(L"index"), ids)) { last = *commit; + } } } @@ -167,18 +146,14 @@ class TransactionRollbackTest : public LuceneTestFixture w->close(); } - void checkExpecteds(const BitSetPtr& expecteds) - { + void checkExpecteds(const BitSetPtr& expecteds) { IndexReaderPtr r = IndexReader::open(dir, true); // Perhaps not the most efficient approach but meets our needs here. - for (int32_t i = 0; i < r->maxDoc(); ++i) - { - if (!r->isDeleted(i)) - { + for (int32_t i = 0; i < r->maxDoc(); ++i) { + if (!r->isDeleted(i)) { String sval = r->document(i)->get(FIELD_RECORD_ID); - if (!sval.empty()) - { + if (!sval.empty()) { int32_t val = StringUtils::toInt(sval); EXPECT_TRUE(expecteds->get(val)); expecteds->set(val, false); @@ -190,11 +165,9 @@ class TransactionRollbackTest : public LuceneTestFixture } }; -TEST_F(TransactionRollbackTest, testRepeatedRollBacks) -{ +TEST_F(TransactionRollbackTest, testRepeatedRollBacks) { int32_t expectedLastRecordId = 100; - while (expectedLastRecordId > 10) - { + while (expectedLastRecordId > 10) { expectedLastRecordId -= 10; rollBackLast(expectedLastRecordId); @@ -204,10 +177,8 @@ TEST_F(TransactionRollbackTest, testRepeatedRollBacks) } } -TEST_F(TransactionRollbackTest, testRollbackDeletionPolicy) -{ - for (int32_t i = 0; i < 2; ++i) - { +TEST_F(TransactionRollbackTest, testRollbackDeletionPolicy) { + for (int32_t i = 0; i < 2; ++i) { // Unless you specify a prior commit point, rollback should not work newLucene(dir, newLucene(), (IndexDeletionPolicyPtr)newLucene(), IndexWriter::MaxFieldLengthUNLIMITED)->close(); IndexReaderPtr r = IndexReader::open(dir, true); diff --git a/src/test/index/TransactionsTest.cpp b/src/test/index/TransactionsTest.cpp index 946415f0..6c07b412 100644 --- a/src/test/index/TransactionsTest.cpp +++ b/src/test/index/TransactionsTest.cpp @@ -28,15 +28,12 @@ DECLARE_SHARED_PTR(TransactionsTimedThread) DECLARE_SHARED_PTR(TransactionsIndexerThread) DECLARE_SHARED_PTR(TransactionsSearcherThread) -class TransactionsTimedThread : public LuceneThread -{ +class TransactionsTimedThread : public LuceneThread { public: - TransactionsTimedThread() - { + TransactionsTimedThread() { } - virtual ~TransactionsTimedThread() - { + virtual ~TransactionsTimedThread() { } LUCENE_CLASS(TransactionsTimedThread); @@ -47,17 +44,14 @@ class TransactionsTimedThread : public LuceneThread public: virtual void doWork() = 0; - virtual void run() - { + virtual void run() { int64_t stopTime = MiscUtils::currentTimeMillis() + 1000 * RUN_TIME_SEC; - try - { - while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) + try { + while ((int64_t)MiscUtils::currentTimeMillis() < stopTime) { doWork(); - } - catch (LuceneException& e) - { + } + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } @@ -65,11 +59,9 @@ class TransactionsTimedThread : public LuceneThread const int32_t TransactionsTimedThread::RUN_TIME_SEC = 6; -class TransactionsIndexerThread : public TransactionsTimedThread -{ +class TransactionsIndexerThread : public TransactionsTimedThread { public: - TransactionsIndexerThread(const SynchronizePtr& lock, const DirectoryPtr& dir1, const DirectoryPtr& dir2) - { + TransactionsIndexerThread(const SynchronizePtr& lock, const DirectoryPtr& dir1, const DirectoryPtr& dir2) { this->lock = lock; this->dir1 = dir1; this->dir2 = dir2; @@ -77,8 +69,7 @@ class TransactionsIndexerThread : public TransactionsTimedThread this->random = newLucene(); } - virtual ~TransactionsIndexerThread() - { + virtual ~TransactionsIndexerThread() { } LUCENE_CLASS(TransactionsIndexerThread); @@ -91,8 +82,7 @@ class TransactionsIndexerThread : public TransactionsTimedThread RandomPtr random; public: - virtual void doWork() - { + virtual void doWork() { IndexWriterPtr writer1 = newLucene(dir1, newLucene(), IndexWriter::MaxFieldLengthLIMITED); writer1->setMaxBufferedDocs(3); writer1->setMergeFactor(2); @@ -111,51 +101,41 @@ class TransactionsIndexerThread : public TransactionsTimedThread bool continueWork = true; LuceneException finally; - try - { + try { SyncLock syncLock(lock); - try - { + try { writer1->prepareCommit(); - } - catch (...) - { + } catch (...) { writer1->rollback(); writer2->rollback(); continueWork = false; } - try - { + try { writer2->prepareCommit(); - } - catch (...) - { + } catch (...) { writer1->rollback(); writer2->rollback(); continueWork = false; } writer1->commit(); writer2->commit(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } doFail = false; finally.throwException(); - if (!continueWork) + if (!continueWork) { return; + } writer1->close(); writer2->close(); } - void update(const IndexWriterPtr& writer) - { + void update(const IndexWriterPtr& writer) { // Add 10 docs - for (int32_t j = 0; j < 10; ++j) - { + for (int32_t j = 0; j < 10; ++j) { DocumentPtr d = newLucene(); d->add(newLucene(L"id", StringUtils::toString(nextID++), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); d->add(newLucene(L"contents", intToEnglish(random->nextInt()), Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -164,26 +144,22 @@ class TransactionsIndexerThread : public TransactionsTimedThread // Delete 5 docs int32_t deleteID = nextID - 1; - for (int32_t j = 0; j < 5; ++j) - { + for (int32_t j = 0; j < 5; ++j) { writer->deleteDocuments(newLucene(L"id", StringUtils::toString(deleteID))); deleteID -= 2; } } }; -class TransactionsSearcherThread : public TransactionsTimedThread -{ +class TransactionsSearcherThread : public TransactionsTimedThread { public: - TransactionsSearcherThread(const SynchronizePtr& lock, const DirectoryPtr& dir1, const DirectoryPtr& dir2) - { + TransactionsSearcherThread(const SynchronizePtr& lock, const DirectoryPtr& dir1, const DirectoryPtr& dir2) { this->lock = lock; this->dir1 = dir1; this->dir2 = dir2; } - virtual ~TransactionsSearcherThread() - { + virtual ~TransactionsSearcherThread() { } LUCENE_CLASS(TransactionsSearcherThread); @@ -194,8 +170,7 @@ class TransactionsSearcherThread : public TransactionsTimedThread SynchronizePtr lock; public: - virtual void doWork() - { + virtual void doWork() { IndexReaderPtr r1; IndexReaderPtr r2; { @@ -203,8 +178,9 @@ class TransactionsSearcherThread : public TransactionsTimedThread r1 = IndexReader::open(dir1, true); r2 = IndexReader::open(dir2, true); } - if (r1->numDocs() != r2->numDocs()) + if (r1->numDocs() != r2->numDocs()) { FAIL() << "doc counts differ"; + } r1->close(); r2->close(); } @@ -212,35 +188,30 @@ class TransactionsSearcherThread : public TransactionsTimedThread DECLARE_SHARED_PTR(RandomFailure) -class RandomFailure : public MockDirectoryFailure -{ +class RandomFailure : public MockDirectoryFailure { public: - RandomFailure() - { + RandomFailure() { random = newLucene(); } - virtual ~RandomFailure() - { + virtual ~RandomFailure() { } protected: RandomPtr random; public: - virtual void eval(const MockRAMDirectoryPtr& dir) - { - if (doFail && random->nextInt() % 10 <= 3) + virtual void eval(const MockRAMDirectoryPtr& dir) { + if (doFail && random->nextInt() % 10 <= 3) { boost::throw_exception(IOException(L"now failing randomly but on purpose")); + } } }; -static void initIndex(const DirectoryPtr& dir) -{ +static void initIndex(const DirectoryPtr& dir) { IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); RandomPtr random = newLucene(); - for (int32_t j = 0; j < 7; ++j) - { + for (int32_t j = 0; j < 7; ++j) { DocumentPtr d = newLucene(); d->add(newLucene(L"contents", intToEnglish(random->nextInt()), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(d); @@ -248,8 +219,7 @@ static void initIndex(const DirectoryPtr& dir) writer->close(); } -TEST_F(TransactionsTest, testTransactions) -{ +TEST_F(TransactionsTest, testTransactions) { MockRAMDirectoryPtr dir1 = newLucene(); MockRAMDirectoryPtr dir2 = newLucene(); dir1->setPreventDoubleWrite(false); @@ -277,6 +247,7 @@ TEST_F(TransactionsTest, testTransactions) threads[numThread++] = searcherThread2; searcherThread2->start(); - for (int32_t i = 0; i < numThread; ++i) + for (int32_t i = 0; i < numThread; ++i) { threads[i]->join(); + } } diff --git a/src/test/index/WordlistLoaderTest.cpp b/src/test/index/WordlistLoaderTest.cpp index 44dc1370..7ce44fa4 100644 --- a/src/test/index/WordlistLoaderTest.cpp +++ b/src/test/index/WordlistLoaderTest.cpp @@ -15,8 +15,7 @@ using namespace Lucene; typedef LuceneTestFixture WordlistLoaderTest; -static void checkSet(HashSet wordset) -{ +static void checkSet(HashSet wordset) { EXPECT_EQ(3, wordset.size()); EXPECT_TRUE(wordset.contains(L"ONE")); // case is not modified EXPECT_TRUE(!wordset.contains(L"one")); // case is not modified @@ -25,8 +24,7 @@ static void checkSet(HashSet wordset) EXPECT_TRUE(!wordset.contains(L"four")); } -TEST_F(WordlistLoaderTest, testWordlistLoading) -{ +TEST_F(WordlistLoaderTest, testWordlistLoading) { String s = L"ONE\n two \nthree"; HashSet wordSet1 = WordlistLoader::getWordSet(newLucene(s)); checkSet(wordSet1); @@ -34,8 +32,7 @@ TEST_F(WordlistLoaderTest, testWordlistLoading) checkSet(wordSet2); } -TEST_F(WordlistLoaderTest, testComments) -{ +TEST_F(WordlistLoaderTest, testComments) { String s = L"ONE\n two \nthree\n#comment"; HashSet wordSet1 = WordlistLoader::getWordSet(newLucene(s), L"#"); checkSet(wordSet1); diff --git a/src/test/main/main.cpp b/src/test/main/main.cpp index cdf7f56d..8bf816e7 100644 --- a/src/test/main/main.cpp +++ b/src/test/main/main.cpp @@ -29,18 +29,14 @@ using namespace Lucene; -int main(int argc, char* argv[]) -{ +int main(int argc, char* argv[]) { String testDir; - for (int32_t i = 0; i < argc; ++i) - { - if (strncmp(argv[i], "--test_dir", 9) == 0) - { + for (int32_t i = 0; i < argc; ++i) { + if (strncmp(argv[i], "--test_dir", 9) == 0) { String testParam = StringUtils::toUnicode(argv[i]); Collection vals = StringUtils::split(testParam, L"="); - if (vals.size() == 2) - { + if (vals.size() == 2) { testDir = vals[1]; boost::replace_all(testDir, L"\"", L""); boost::trim(testDir); @@ -49,19 +45,17 @@ int main(int argc, char* argv[]) } } - if (testDir.empty()) - { + if (testDir.empty()) { testDir = L"../../src/test/testfiles"; - if (!FileUtils::isDirectory(testDir)) - { + if (!FileUtils::isDirectory(testDir)) { testDir = L"../src/test/testfiles"; - if (!FileUtils::isDirectory(testDir)) + if (!FileUtils::isDirectory(testDir)) { testDir = L"./src/test/testfiles"; + } } } - if (!FileUtils::isDirectory(testDir)) - { + if (!FileUtils::isDirectory(testDir)) { std::wcout << L"Test directory not found. (override default by using --test_dir=\"./src/test/testfiles\")\n"; return 1; } diff --git a/src/test/queryparser/MultiAnalyzerTest.cpp b/src/test/queryparser/MultiAnalyzerTest.cpp index 3e99cae5..24214504 100644 --- a/src/test/queryparser/MultiAnalyzerTest.cpp +++ b/src/test/queryparser/MultiAnalyzerTest.cpp @@ -31,11 +31,9 @@ DECLARE_SHARED_PTR(DumbQueryWrapper) DECLARE_SHARED_PTR(DumbQueryParser) DECLARE_SHARED_PTR(TestPosIncrementFilter) -class MultiAnalyzerTestFilter : public TokenFilter -{ +class MultiAnalyzerTestFilter : public TokenFilter { public: - MultiAnalyzerTestFilter(const TokenStreamPtr& in) : TokenFilter(in) - { + MultiAnalyzerTestFilter(const TokenStreamPtr& in) : TokenFilter(in) { prevStartOffset = 0; prevEndOffset = 0; termAtt = addAttribute(); @@ -44,8 +42,7 @@ class MultiAnalyzerTestFilter : public TokenFilter typeAtt = addAttribute(); } - virtual ~MultiAnalyzerTestFilter() - { + virtual ~MultiAnalyzerTestFilter() { } LUCENE_CLASS(MultiAnalyzerTestFilter); @@ -61,54 +58,45 @@ class MultiAnalyzerTestFilter : public TokenFilter TypeAttributePtr typeAtt; public: - virtual bool incrementToken() - { - if (multiToken > 0) - { + virtual bool incrementToken() { + if (multiToken > 0) { termAtt->setTermBuffer(L"multi" + StringUtils::toString(multiToken + 1)); offsetAtt->setOffset(prevStartOffset, prevEndOffset); typeAtt->setType(prevType); posIncrAtt->setPositionIncrement(0); --multiToken; return true; - } - else - { + } else { bool next = input->incrementToken(); - if (!next) + if (!next) { return false; + } prevType = typeAtt->type(); prevStartOffset = offsetAtt->startOffset(); prevEndOffset = offsetAtt->endOffset(); String text = termAtt->term(); - if (text == L"triplemulti") - { + if (text == L"triplemulti") { multiToken = 2; return true; - } - else if (text == L"multi") - { + } else if (text == L"multi") { multiToken = 1; return true; - } - else + } else { return true; + } } } }; -class MultiAnalyzer : public Analyzer -{ +class MultiAnalyzer : public Analyzer { public: - virtual ~MultiAnalyzer() - { + virtual ~MultiAnalyzer() { } LUCENE_CLASS(MultiAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(LuceneVersion::LUCENE_CURRENT, reader); result = newLucene(result); result = newLucene(result); @@ -117,16 +105,13 @@ class MultiAnalyzer : public Analyzer }; /// A very simple wrapper to prevent typeOf checks but uses the toString of the query it wraps. -class DumbQueryWrapper : public Query -{ +class DumbQueryWrapper : public Query { public: - DumbQueryWrapper(const QueryPtr& q) - { + DumbQueryWrapper(const QueryPtr& q) { this->q = q; } - virtual ~DumbQueryWrapper() - { + virtual ~DumbQueryWrapper() { } LUCENE_CLASS(DumbQueryWrapper); @@ -135,44 +120,36 @@ class DumbQueryWrapper : public Query QueryPtr q; public: - virtual String toString(const String& field) - { + virtual String toString(const String& field) { return q->toString(field); } }; /// A very simple subclass of QueryParser -class DumbQueryParser : public QueryParser -{ +class DumbQueryParser : public QueryParser { public: - DumbQueryParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) - { + DumbQueryParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { } - virtual ~DumbQueryParser() - { + virtual ~DumbQueryParser() { } LUCENE_CLASS(DumbQueryParser); public: - virtual QueryPtr getFieldQuery(const String& field, const String& queryText) - { + virtual QueryPtr getFieldQuery(const String& field, const String& queryText) { return newLucene(QueryParser::getFieldQuery(field, queryText)); } }; -class TestPosIncrementFilter : public TokenFilter -{ +class TestPosIncrementFilter : public TokenFilter { public: - TestPosIncrementFilter(const TokenStreamPtr& in) : TokenFilter(in) - { + TestPosIncrementFilter(const TokenStreamPtr& in) : TokenFilter(in) { termAtt = addAttribute(); posIncrAtt = addAttribute(); } - virtual ~TestPosIncrementFilter() - { + virtual ~TestPosIncrementFilter() { } LUCENE_CLASS(TestPosIncrementFilter); @@ -182,21 +159,14 @@ class TestPosIncrementFilter : public TokenFilter PositionIncrementAttributePtr posIncrAtt; public: - virtual bool incrementToken() - { - while (input->incrementToken()) - { - if (termAtt->term() == L"the") - { + virtual bool incrementToken() { + while (input->incrementToken()) { + if (termAtt->term() == L"the") { // stopword, do nothing - } - else if (termAtt->term() == L"quick") - { + } else if (termAtt->term() == L"quick") { posIncrAtt->setPositionIncrement(2); return true; - } - else - { + } else { posIncrAtt->setPositionIncrement(1); return true; } @@ -207,18 +177,15 @@ class TestPosIncrementFilter : public TokenFilter /// Analyzes "the quick brown" as: quick(incr=2) brown(incr=1). /// Does not work correctly for input other than "the quick brown ...". -class PosIncrementAnalyzer : public Analyzer -{ +class PosIncrementAnalyzer : public Analyzer { public: - virtual ~PosIncrementAnalyzer() - { + virtual ~PosIncrementAnalyzer() { } LUCENE_CLASS(PosIncrementAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(LuceneVersion::LUCENE_CURRENT, reader); result = newLucene(result); result = newLucene(result); @@ -226,8 +193,7 @@ class PosIncrementAnalyzer : public Analyzer } }; -TEST_F(MultiAnalyzerTest, testMultiAnalyzer) -{ +TEST_F(MultiAnalyzerTest, testMultiAnalyzer) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"", newLucene()); // trivial, no multiple tokens @@ -274,8 +240,7 @@ TEST_F(MultiAnalyzerTest, testMultiAnalyzer) EXPECT_EQ(L"+(multi multi2) +foo", qp->parse(L"multi foo")->toString()); } -TEST_F(MultiAnalyzerTest, testMultiAnalyzerWithSubclassOfQueryParser) -{ +TEST_F(MultiAnalyzerTest, testMultiAnalyzerWithSubclassOfQueryParser) { DumbQueryParserPtr qp = newLucene(L"", newLucene()); qp->setPhraseSlop(99); // modified default slop @@ -288,8 +253,7 @@ TEST_F(MultiAnalyzerTest, testMultiAnalyzerWithSubclassOfQueryParser) EXPECT_EQ(L"\"(multi multi2) foo\"~99 bar", qp->parse(L"\"multi foo\" bar")->toString()); } -TEST_F(MultiAnalyzerTest, testPosIncrementAnalyzer) -{ +TEST_F(MultiAnalyzerTest, testPosIncrementAnalyzer) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_24, L"", newLucene()); EXPECT_EQ(L"quick brown", qp->parse(L"the quick brown")->toString()); EXPECT_EQ(L"\"quick brown\"", qp->parse(L"\"the quick brown\"")->toString()); diff --git a/src/test/queryparser/MultiFieldQueryParserTest.cpp b/src/test/queryparser/MultiFieldQueryParserTest.cpp index 32bd2a06..a7ef35e8 100644 --- a/src/test/queryparser/MultiFieldQueryParserTest.cpp +++ b/src/test/queryparser/MultiFieldQueryParserTest.cpp @@ -30,11 +30,9 @@ DECLARE_SHARED_PTR(MultiFieldQueryParserTestAnalyzer) DECLARE_SHARED_PTR(MultiFieldQueryParserTestFilter) /// Filter which discards the token 'stop' and which expands the token 'phrase' into 'phrase1 phrase2' -class MultiFieldQueryParserTestFilter : public TokenFilter -{ +class MultiFieldQueryParserTestFilter : public TokenFilter { public: - MultiFieldQueryParserTestFilter(const TokenStreamPtr& in) : TokenFilter(in) - { + MultiFieldQueryParserTestFilter(const TokenStreamPtr& in) : TokenFilter(in) { termAtt = addAttribute(); offsetAtt = addAttribute(); inPhrase = false; @@ -42,8 +40,7 @@ class MultiFieldQueryParserTestFilter : public TokenFilter savedEnd = 0; } - virtual ~MultiFieldQueryParserTestFilter() - { + virtual ~MultiFieldQueryParserTestFilter() { } LUCENE_CLASS(MultiFieldQueryParserTestFilter); @@ -56,80 +53,65 @@ class MultiFieldQueryParserTestFilter : public TokenFilter OffsetAttributePtr offsetAtt; public: - virtual bool incrementToken() - { - if (inPhrase) - { + virtual bool incrementToken() { + if (inPhrase) { inPhrase = false; termAtt->setTermBuffer(L"phrase2"); offsetAtt->setOffset(savedStart, savedEnd); return true; - } - else - { - while (input->incrementToken()) - { - if (termAtt->term() == L"phrase") - { + } else { + while (input->incrementToken()) { + if (termAtt->term() == L"phrase") { inPhrase = true; savedStart = offsetAtt->startOffset(); savedEnd = offsetAtt->endOffset(); termAtt->setTermBuffer(L"phrase1"); offsetAtt->setOffset(savedStart, savedEnd); return true; - } - else if (termAtt->term() != L"stop") + } else if (termAtt->term() != L"stop") { return true; + } } } return false; } }; -class MultiFieldQueryParserTestAnalyzer : public Analyzer -{ +class MultiFieldQueryParserTestAnalyzer : public Analyzer { public: - virtual ~MultiFieldQueryParserTestAnalyzer() - { + virtual ~MultiFieldQueryParserTestAnalyzer() { } LUCENE_CLASS(MultiFieldQueryParserTestAnalyzer); public: // Filters LowerCaseTokenizer with StopFilter. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } }; -class EmptyTokenStream : public TokenStream -{ +class EmptyTokenStream : public TokenStream { public: - virtual ~EmptyTokenStream() - { + virtual ~EmptyTokenStream() { } LUCENE_CLASS(EmptyTokenStream); public: - virtual bool incrementToken() - { + virtual bool incrementToken() { return false; } }; /// Return empty tokens for field "f1". -class AnalyzerReturningNull : public Analyzer -{ +class AnalyzerReturningNull : public Analyzer { public: - AnalyzerReturningNull() - { + AnalyzerReturningNull() { standardAnalyzer = newLucene(LuceneVersion::LUCENE_CURRENT); } - virtual ~AnalyzerReturningNull() - { + virtual ~AnalyzerReturningNull() { } LUCENE_CLASS(AnalyzerReturningNull); @@ -138,18 +120,17 @@ class AnalyzerReturningNull : public Analyzer StandardAnalyzerPtr standardAnalyzer; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - if (fieldName == L"f1") + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + if (fieldName == L"f1") { return newLucene(); - else + } else { return standardAnalyzer->tokenStream(fieldName, reader); + } } }; /// verify parsing of query using a stopping analyzer -static void checkStopQueryEquals(const String& qtxt, const String& expectedRes) -{ +static void checkStopQueryEquals(const String& qtxt, const String& expectedRes) { Collection fields = newCollection(L"b", L"t"); Collection occur = newCollection(BooleanClause::SHOULD, BooleanClause::SHOULD); MultiFieldQueryParserTestAnalyzerPtr a = newLucene(); @@ -163,8 +144,7 @@ static void checkStopQueryEquals(const String& qtxt, const String& expectedRes) } /// test stop words arising for both the non static form, and for the corresponding static form (qtxt, fields[]). -TEST_F(MultiFieldQueryParserTest, testStopwordsParsing) -{ +TEST_F(MultiFieldQueryParserTest, testStopwordsParsing) { checkStopQueryEquals(L"one", L"b:one t:one"); checkStopQueryEquals(L"one stop", L"b:one t:one"); checkStopQueryEquals(L"one (stop)", L"b:one t:one"); @@ -174,8 +154,7 @@ TEST_F(MultiFieldQueryParserTest, testStopwordsParsing) checkStopQueryEquals(L"((stop))", L""); } -TEST_F(MultiFieldQueryParserTest, testSimple) -{ +TEST_F(MultiFieldQueryParserTest, testSimple) { Collection fields = newCollection(L"b", L"t"); MultiFieldQueryParserPtr mfqp = newLucene(LuceneVersion::LUCENE_CURRENT, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); @@ -233,8 +212,7 @@ TEST_F(MultiFieldQueryParserTest, testSimple) EXPECT_EQ(L"+(b:\"aa bb cc\" t:\"aa bb cc\") +(b:\"dd ee\" t:\"dd ee\")", q->toString()); } -TEST_F(MultiFieldQueryParserTest, testBoostsSimple) -{ +TEST_F(MultiFieldQueryParserTest, testBoostsSimple) { MapStringDouble boosts = MapStringDouble::newInstance(); boosts.put(L"b", 5.0); boosts.put(L"t", 10.0); @@ -261,8 +239,7 @@ TEST_F(MultiFieldQueryParserTest, testBoostsSimple) EXPECT_EQ(L"+((b:one^5.0 t:one^10.0)^3.0) +((b:two^5.0 t:two^10.0)^4.0)", q->toString()); } -TEST_F(MultiFieldQueryParserTest, testStaticMethod1) -{ +TEST_F(MultiFieldQueryParserTest, testStaticMethod1) { Collection fields = newCollection(L"b", L"t"); Collection queries = newCollection(L"one", L"two"); QueryPtr q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); @@ -283,12 +260,9 @@ TEST_F(MultiFieldQueryParserTest, testStaticMethod1) Collection queries5 = newCollection(L"blah"); // expected exception, array length differs - try - { + try { q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries5, fields, newLucene(LuceneVersion::LUCENE_CURRENT)); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } @@ -304,8 +278,7 @@ TEST_F(MultiFieldQueryParserTest, testStaticMethod1) EXPECT_EQ(L"(b:one +b:more) (+t:two)", q->toString()); } -TEST_F(MultiFieldQueryParserTest, testStaticMethod2) -{ +TEST_F(MultiFieldQueryParserTest, testStaticMethod2) { Collection fields = newCollection(L"b", L"t"); Collection flags = newCollection(BooleanClause::MUST, BooleanClause::MUST_NOT); QueryPtr q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, L"one", fields, flags, newLucene(LuceneVersion::LUCENE_CURRENT)); @@ -317,18 +290,14 @@ TEST_F(MultiFieldQueryParserTest, testStaticMethod2) Collection flags2 = newCollection(BooleanClause::MUST); // expected exception, array length differs - try - { + try { q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, L"blah", fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } -TEST_F(MultiFieldQueryParserTest, testStaticMethod3) -{ +TEST_F(MultiFieldQueryParserTest, testStaticMethod3) { Collection queries = newCollection(L"one", L"two", L"three"); Collection fields = newCollection(L"f1", L"f2", L"f3"); Collection flags = newCollection(BooleanClause::MUST, BooleanClause::MUST_NOT, BooleanClause::SHOULD); @@ -338,18 +307,14 @@ TEST_F(MultiFieldQueryParserTest, testStaticMethod3) Collection flags2 = newCollection(BooleanClause::MUST); // expected exception, array length differs - try - { + try { q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } -TEST_F(MultiFieldQueryParserTest, testStaticMethod3Old) -{ +TEST_F(MultiFieldQueryParserTest, testStaticMethod3Old) { Collection queries = newCollection(L"one", L"two"); Collection fields = newCollection(L"b", L"t"); Collection flags = newCollection(BooleanClause::MUST, BooleanClause::MUST_NOT); @@ -359,18 +324,14 @@ TEST_F(MultiFieldQueryParserTest, testStaticMethod3Old) Collection flags2 = newCollection(BooleanClause::MUST); // expected exception, array length differs - try - { + try { q = MultiFieldQueryParser::parse(LuceneVersion::LUCENE_CURRENT, queries, fields, flags2, newLucene(LuceneVersion::LUCENE_CURRENT)); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } -TEST_F(MultiFieldQueryParserTest, testAnalyzerReturningNull) -{ +TEST_F(MultiFieldQueryParserTest, testAnalyzerReturningNull) { Collection fields = newCollection(L"f1", L"f2", L"f3"); MultiFieldQueryParserPtr parser = newLucene(LuceneVersion::LUCENE_CURRENT, fields, newLucene()); QueryPtr q = parser->parse(L"bla AND blo"); @@ -385,8 +346,7 @@ TEST_F(MultiFieldQueryParserTest, testAnalyzerReturningNull) EXPECT_EQ(L"f1:[a TO c] f2:[a TO c] f3:[a TO c]", q->toString()); } -TEST_F(MultiFieldQueryParserTest, testStopWordSearching) -{ +TEST_F(MultiFieldQueryParserTest, testStopWordSearching) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); DirectoryPtr ramDir = newLucene(); IndexWriterPtr iw = newLucene(ramDir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); diff --git a/src/test/queryparser/QueryParserTest.cpp b/src/test/queryparser/QueryParserTest.cpp index f86be710..5f5d4f8f 100644 --- a/src/test/queryparser/QueryParserTest.cpp +++ b/src/test/queryparser/QueryParserTest.cpp @@ -48,11 +48,9 @@ DECLARE_SHARED_PTR(QueryParserTestFilter) DECLARE_SHARED_PTR(TestParser) /// Filter which discards the token 'stop' and which expands the token 'phrase' into 'phrase1 phrase2' -class QueryParserTestFilter : public TokenFilter -{ +class QueryParserTestFilter : public TokenFilter { public: - QueryParserTestFilter(const TokenStreamPtr& in) : TokenFilter(in) - { + QueryParserTestFilter(const TokenStreamPtr& in) : TokenFilter(in) { termAtt = addAttribute(); offsetAtt = addAttribute(); inPhrase = false; @@ -60,8 +58,7 @@ class QueryParserTestFilter : public TokenFilter savedEnd = 0; } - virtual ~QueryParserTestFilter() - { + virtual ~QueryParserTestFilter() { } LUCENE_CLASS(QueryParserTestFilter); @@ -74,202 +71,177 @@ class QueryParserTestFilter : public TokenFilter OffsetAttributePtr offsetAtt; public: - virtual bool incrementToken() - { - if (inPhrase) - { + virtual bool incrementToken() { + if (inPhrase) { inPhrase = false; clearAttributes(); termAtt->setTermBuffer(L"phrase2"); offsetAtt->setOffset(savedStart, savedEnd); return true; - } - else - { - while (input->incrementToken()) - { - if (termAtt->term() == L"phrase") - { + } else { + while (input->incrementToken()) { + if (termAtt->term() == L"phrase") { inPhrase = true; savedStart = offsetAtt->startOffset(); savedEnd = offsetAtt->endOffset(); termAtt->setTermBuffer(L"phrase1"); offsetAtt->setOffset(savedStart, savedEnd); return true; - } - else if (termAtt->term() != L"stop") + } else if (termAtt->term() != L"stop") { return true; + } } } return false; } }; -class QueryParserTestAnalyzer : public Analyzer -{ +class QueryParserTestAnalyzer : public Analyzer { public: - virtual ~QueryParserTestAnalyzer() - { + virtual ~QueryParserTestAnalyzer() { } LUCENE_CLASS(QueryParserTestAnalyzer); public: // Filters LowerCaseTokenizer with StopFilter. - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(newLucene(reader)); } }; -class TestParser : public QueryParser -{ +class TestParser : public QueryParser { public: - TestParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) - { + TestParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { } - virtual ~TestParser() - { + virtual ~TestParser() { } LUCENE_CLASS(TestParser); public: - virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) - { + virtual QueryPtr getFuzzyQuery(const String& field, const String& termStr, double minSimilarity) { boost::throw_exception(QueryParserError(L"Fuzzy queries not allowed")); return QueryPtr(); } - virtual QueryPtr getWildcardQuery(const String& field, const String& termStr) - { + virtual QueryPtr getWildcardQuery(const String& field, const String& termStr) { boost::throw_exception(QueryParserError(L"Wildcard queries not allowed")); return QueryPtr(); } }; -class QueryParserTest : public LuceneTestFixture -{ +class QueryParserTest : public LuceneTestFixture { public: - QueryParserTest() - { + QueryParserTest() { originalMaxClauses = BooleanQuery::getMaxClauseCount(); DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); } - virtual ~QueryParserTest() - { + virtual ~QueryParserTest() { BooleanQuery::setMaxClauseCount(originalMaxClauses); } protected: int32_t originalMaxClauses; - QueryParserPtr getParser(const AnalyzerPtr& a) - { + QueryParserPtr getParser(const AnalyzerPtr& a) { AnalyzerPtr _a(a); - if (!_a) + if (!_a) { _a = newLucene(); + } QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", _a); qp->setDefaultOperator(QueryParser::OR_OPERATOR); return qp; } - QueryPtr getQuery(const String& query, const AnalyzerPtr& a) - { + QueryPtr getQuery(const String& query, const AnalyzerPtr& a) { return getParser(a)->parse(query); } - void checkQueryEquals(const String& query, const AnalyzerPtr& a, const String& result) - { + void checkQueryEquals(const String& query, const AnalyzerPtr& a, const String& result) { QueryPtr q = getQuery(query, a); String s = q->toString(L"field"); - if (s != result) + if (s != result) { FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; + } } - void checkQueryEquals(const QueryParserPtr& qp, const String& field, const String& query, const String& result) - { + void checkQueryEquals(const QueryParserPtr& qp, const String& field, const String& query, const String& result) { QueryPtr q = qp->parse(query); String s = q->toString(field); - if (s != result) + if (s != result) { FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; + } } - void checkParseException(const String& queryString) - { - try - { + void checkParseException(const String& queryString) { + try { getQuery(queryString, AnalyzerPtr()); - } - catch (QueryParserError& e) - { + } catch (QueryParserError& e) { EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); } } - void checkWildcardQueryEquals(const String& query, bool lowercase, const String& result, bool allowLeadingWildcard = false) - { + void checkWildcardQueryEquals(const String& query, bool lowercase, const String& result, bool allowLeadingWildcard = false) { QueryParserPtr qp = getParser(AnalyzerPtr()); qp->setLowercaseExpandedTerms(lowercase); qp->setAllowLeadingWildcard(allowLeadingWildcard); QueryPtr q = qp->parse(query); String s = q->toString(L"field"); - if (s != result) + if (s != result) { FAIL() << "WildcardQuery \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; + } } - void checkWildcardQueryEquals(const String& query, const String& result) - { + void checkWildcardQueryEquals(const String& query, const String& result) { QueryParserPtr qp = getParser(AnalyzerPtr()); QueryPtr q = qp->parse(query); String s = q->toString(L"field"); - if (s != result) + if (s != result) { FAIL() << "WildcardQuery \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; + } } - void checkEscapedQueryEquals(const String& query, const AnalyzerPtr& a, const String& result) - { - class TestableQueryParser : public QueryParser - { + void checkEscapedQueryEquals(const String& query, const AnalyzerPtr& a, const String& result) { + class TestableQueryParser : public QueryParser { public: using QueryParser::escape; }; String escapedQuery = TestableQueryParser::escape(query); - if (escapedQuery != result) + if (escapedQuery != result) { FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(escapedQuery) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; + } } - QueryPtr getQueryDOA(const String& query, const AnalyzerPtr& a) - { + QueryPtr getQueryDOA(const String& query, const AnalyzerPtr& a) { AnalyzerPtr _a(a); - if (!_a) + if (!_a) { _a = newLucene(); + } QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", _a); qp->setDefaultOperator(QueryParser::AND_OPERATOR); return qp->parse(query); } - void checkQueryEqualsDOA(const String& query, const AnalyzerPtr& a, const String& result) - { + void checkQueryEqualsDOA(const String& query, const AnalyzerPtr& a, const String& result) { QueryPtr q = getQueryDOA(query, a); String s = q->toString(L"field"); - if (s != result) + if (s != result) { FAIL() << "Query \"" << StringUtils::toUTF8(query) << "\" yielded \"" << StringUtils::toUTF8(s) << "\", expecting \"" << StringUtils::toUTF8(result) << "\""; + } } - void addDateDoc(const String& content, boost::posix_time::ptime date, const IndexWriterPtr& iw) - { + void addDateDoc(const String& content, boost::posix_time::ptime date, const IndexWriterPtr& iw) { DocumentPtr d = newLucene(); d->add(newLucene(L"f", content, Field::STORE_YES, Field::INDEX_ANALYZED)); d->add(newLucene(L"date", DateField::dateToString(date), Field::STORE_YES, Field::INDEX_ANALYZED)); iw->addDocument(d); } - void checkHits(int32_t expected, const String& query, const IndexSearcherPtr& is) - { + void checkHits(int32_t expected, const String& query, const IndexSearcherPtr& is) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"date", newLucene()); qp->setLocale(std::locale()); QueryPtr q = qp->parse(query); @@ -278,8 +250,7 @@ class QueryParserTest : public LuceneTestFixture } }; -TEST_F(QueryParserTest, testSimple) -{ +TEST_F(QueryParserTest, testSimple) { checkQueryEquals(L"term term term", AnalyzerPtr(), L"term term term"); const uint8_t term[] = {0x74, 0xc3, 0xbc, 0x72, 0x6d, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x20, 0x74, 0x65, 0x72, 0x6d}; @@ -339,16 +310,14 @@ TEST_F(QueryParserTest, testSimple) EXPECT_EQ(QueryParser::OR_OPERATOR, qp->getDefaultOperator()); } -TEST_F(QueryParserTest, testPunct) -{ +TEST_F(QueryParserTest, testPunct) { AnalyzerPtr a = newLucene(); checkQueryEquals(L"a&b", a, L"a&b"); checkQueryEquals(L"a&&b", a, L"a&&b"); checkQueryEquals(L".NET", a, L".NET"); } -TEST_F(QueryParserTest, testSlop) -{ +TEST_F(QueryParserTest, testSlop) { checkQueryEquals(L"\"term germ\"~2", AnalyzerPtr(), L"\"term germ\"~2"); checkQueryEquals(L"\"term germ\"~2 flork", AnalyzerPtr(), L"\"term germ\"~2 flork"); checkQueryEquals(L"\"term\"~2", AnalyzerPtr(), L"term"); @@ -356,8 +325,7 @@ TEST_F(QueryParserTest, testSlop) checkQueryEquals(L"\"term germ\"~2^2", AnalyzerPtr(), L"\"term germ\"~2^2.0"); } -TEST_F(QueryParserTest, testNumber) -{ +TEST_F(QueryParserTest, testNumber) { // The numbers go away because SimpleAnalzyer ignores them checkQueryEquals(L"3", AnalyzerPtr(), L""); checkQueryEquals(L"term 1.0 1 2", AnalyzerPtr(), L"term"); @@ -369,8 +337,7 @@ TEST_F(QueryParserTest, testNumber) checkQueryEquals(L"term term1 term2", a, L"term term1 term2"); } -TEST_F(QueryParserTest, testWildcard) -{ +TEST_F(QueryParserTest, testWildcard) { checkQueryEquals(L"term*", AnalyzerPtr(), L"term*"); checkQueryEquals(L"term*^2", AnalyzerPtr(), L"term*^2.0"); checkQueryEquals(L"term~", AnalyzerPtr(), L"term~0.5"); @@ -430,20 +397,14 @@ TEST_F(QueryParserTest, testWildcard) checkWildcardQueryEquals(L"[A TO C]", true, L"[a TO c]"); checkWildcardQueryEquals(L"[A TO C]", false, L"[A TO C]"); // Test suffix queries: first disallow - try - { + try { checkWildcardQueryEquals(L"*Term", true, L"*term"); - } - catch (QueryParserError& e) - { + } catch (QueryParserError& e) { EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); } - try - { + try { checkWildcardQueryEquals(L"?Term", true, L"?term"); - } - catch (QueryParserError& e) - { + } catch (QueryParserError& e) { EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); } @@ -452,8 +413,7 @@ TEST_F(QueryParserTest, testWildcard) checkWildcardQueryEquals(L"?Term", true, L"?term", true); } -TEST_F(QueryParserTest, testLeadingWildcardType) -{ +TEST_F(QueryParserTest, testLeadingWildcardType) { QueryParserPtr qp = getParser(AnalyzerPtr()); qp->setAllowLeadingWildcard(true); EXPECT_TRUE(MiscUtils::typeOf(qp->parse(L"t*erm*"))); @@ -461,8 +421,7 @@ TEST_F(QueryParserTest, testLeadingWildcardType) EXPECT_TRUE(MiscUtils::typeOf(qp->parse(L"*term*"))); } -TEST_F(QueryParserTest, testQPA) -{ +TEST_F(QueryParserTest, testQPA) { AnalyzerPtr qpAnalyzer = newLucene(); checkQueryEquals(L"term term^3.0 term", qpAnalyzer, L"term term^3.0 term"); @@ -491,8 +450,7 @@ TEST_F(QueryParserTest, testQPA) EXPECT_TRUE(MiscUtils::typeOf(getQuery(L"term +stop", qpAnalyzer))); } -TEST_F(QueryParserTest, testRange) -{ +TEST_F(QueryParserTest, testRange) { checkQueryEquals(L"[ a TO z]", AnalyzerPtr(), L"[a TO z]"); EXPECT_EQ(MultiTermQuery::CONSTANT_SCORE_AUTO_REWRITE_DEFAULT(), boost::dynamic_pointer_cast(getQuery(L"[ a TO z]", AnalyzerPtr()))->getRewriteMethod()); @@ -510,15 +468,13 @@ TEST_F(QueryParserTest, testRange) checkQueryEquals(L"gack ( bar blar { a TO z}) ", AnalyzerPtr(), L"gack (bar blar {a TO z})"); } -TEST_F(QueryParserTest, testLegacyDateRange) -{ +TEST_F(QueryParserTest, testLegacyDateRange) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); checkQueryEquals(L"[01/02/02 TO 04/02/02]", AnalyzerPtr(), L"[0cx597uo0 TO 0cxayz9bz]"); checkQueryEquals(L"{01/02/02 04/02/02}", AnalyzerPtr(), L"{0cx597uo0 TO 0cx9jjeo0}"); } -TEST_F(QueryParserTest, testDateRange) -{ +TEST_F(QueryParserTest, testDateRange) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); @@ -551,8 +507,7 @@ TEST_F(QueryParserTest, testDateRange) checkQueryEquals(qp, L"hour", L"hour:{01/02/02 TO 04/02/02}", L"{2002020100 TO 2002020400}"); } -TEST_F(QueryParserTest, testEscaped) -{ +TEST_F(QueryParserTest, testEscaped) { AnalyzerPtr a = newLucene(); checkQueryEquals(L"\\a", a, L"a"); @@ -619,8 +574,7 @@ TEST_F(QueryParserTest, testEscaped) checkQueryEquals(L"(\"a\\\\\") or (\"b\")", a, L"a\\ or b"); } -TEST_F(QueryParserTest, testQueryStringEscaping) -{ +TEST_F(QueryParserTest, testQueryStringEscaping) { AnalyzerPtr a = newLucene(); checkEscapedQueryEquals(L"a-b:c", a, L"a\\-b\\:c"); @@ -658,8 +612,7 @@ TEST_F(QueryParserTest, testQueryStringEscaping) checkEscapedQueryEquals(L"&& abc &&", a, L"\\&\\& abc \\&\\&"); } -TEST_F(QueryParserTest, testTabNewlineCarriageReturn) -{ +TEST_F(QueryParserTest, testTabNewlineCarriageReturn) { checkQueryEqualsDOA(L"+weltbank +worlbank", AnalyzerPtr(), L"+weltbank +worlbank"); checkQueryEqualsDOA(L"+weltbank\n+worlbank", AnalyzerPtr(), L"+weltbank +worlbank"); @@ -680,8 +633,7 @@ TEST_F(QueryParserTest, testTabNewlineCarriageReturn) checkQueryEqualsDOA(L"weltbank \t +worlbank", AnalyzerPtr(), L"+weltbank +worlbank"); } -TEST_F(QueryParserTest, testSimpleDAO) -{ +TEST_F(QueryParserTest, testSimpleDAO) { checkQueryEqualsDOA(L"term term term", AnalyzerPtr(), L"+term +term +term"); checkQueryEqualsDOA(L"term +term term", AnalyzerPtr(), L"+term +term +term"); checkQueryEqualsDOA(L"term term +term", AnalyzerPtr(), L"+term +term +term"); @@ -689,8 +641,7 @@ TEST_F(QueryParserTest, testSimpleDAO) checkQueryEqualsDOA(L"-term term term", AnalyzerPtr(), L"-term +term +term"); } -TEST_F(QueryParserTest, testBoost) -{ +TEST_F(QueryParserTest, testBoost) { HashSet stopWords = HashSet::newInstance(); stopWords.add(L"on"); StandardAnalyzerPtr oneStopAnalyzer = newLucene(LuceneVersion::LUCENE_CURRENT, stopWords); @@ -715,8 +666,7 @@ TEST_F(QueryParserTest, testBoost) EXPECT_NEAR(1.0, q->getBoost(), 0.01); } -TEST_F(QueryParserTest, testException) -{ +TEST_F(QueryParserTest, testException) { checkParseException(L"\"some phrase"); checkParseException(L"(foo bar"); checkParseException(L"foo bar))"); @@ -725,56 +675,42 @@ TEST_F(QueryParserTest, testException) checkParseException(L"secret AND illegal) AND access:confidential"); } -TEST_F(QueryParserTest, testCustomQueryParserWildcard) -{ - try - { +TEST_F(QueryParserTest, testCustomQueryParserWildcard) { + try { newLucene(L"contents", newLucene())->parse(L"a?t"); - } - catch (QueryParserError& e) - { + } catch (QueryParserError& e) { EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); } } -TEST_F(QueryParserTest, testCustomQueryParserFuzzy) -{ - try - { +TEST_F(QueryParserTest, testCustomQueryParserFuzzy) { + try { newLucene(L"contents", newLucene())->parse(L"xunit~"); - } - catch (QueryParserError& e) - { + } catch (QueryParserError& e) { EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); } } -TEST_F(QueryParserTest, testBooleanQuery) -{ +TEST_F(QueryParserTest, testBooleanQuery) { BooleanQuery::setMaxClauseCount(2); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); // too many boolean clauses, so ParseException is expected - try - { + try { qp->parse(L"one two three"); - } - catch (QueryParserError& e) - { + } catch (QueryParserError& e) { EXPECT_TRUE(check_exception(LuceneException::QueryParser)(e)); } } -TEST_F(QueryParserTest, testPrecedence) -{ +TEST_F(QueryParserTest, testPrecedence) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); QueryPtr query1 = qp->parse(L"A AND B OR C AND D"); QueryPtr query2 = qp->parse(L"+A +B +C +D"); EXPECT_TRUE(query1->equals(query2)); } -TEST_F(QueryParserTest, testLocalDateFormat) -{ +TEST_F(QueryParserTest, testLocalDateFormat) { DateTools::setDateOrder(DateTools::DATEORDER_DMY); RAMDirectoryPtr ramDir = newLucene(); IndexWriterPtr iw = newLucene(ramDir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -791,52 +727,46 @@ TEST_F(QueryParserTest, testLocalDateFormat) is->close(); } -namespace TestStarParsing -{ - DECLARE_SHARED_PTR(StarParser) +namespace TestStarParsing { - class StarParser : public QueryParser - { - public: - StarParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) - { - type = Collection::newInstance(1); - } +DECLARE_SHARED_PTR(StarParser) - virtual ~StarParser() - { - } +class StarParser : public QueryParser { +public: + StarParser(const String& f, const AnalyzerPtr& a) : QueryParser(LuceneVersion::LUCENE_CURRENT, f, a) { + type = Collection::newInstance(1); + } - LUCENE_CLASS(StarParser); + virtual ~StarParser() { + } - public: - Collection type; + LUCENE_CLASS(StarParser); - public: - virtual QueryPtr getWildcardQuery(const String& field, const String& termStr) - { - // override error checking of superclass - type[0] = 1; - return newLucene(newLucene(field, termStr)); - } +public: + Collection type; - virtual QueryPtr getPrefixQuery(const String& field, const String& termStr) - { - // override error checking of superclass - type[0] = 2; - return newLucene(newLucene(field, termStr)); - } +public: + virtual QueryPtr getWildcardQuery(const String& field, const String& termStr) { + // override error checking of superclass + type[0] = 1; + return newLucene(newLucene(field, termStr)); + } + + virtual QueryPtr getPrefixQuery(const String& field, const String& termStr) { + // override error checking of superclass + type[0] = 2; + return newLucene(newLucene(field, termStr)); + } + + virtual QueryPtr getFieldQuery(const String& field, const String& queryText) { + type[0] = 3; + return QueryParser::getFieldQuery(field, queryText); + } +}; - virtual QueryPtr getFieldQuery(const String& field, const String& queryText) - { - type[0] = 3; - return QueryParser::getFieldQuery(field, queryText); - } - }; } -TEST_F(QueryParserTest, testStarParsing) -{ +TEST_F(QueryParserTest, testStarParsing) { TestStarParsing::StarParserPtr qp = newLucene(L"field", newLucene()); TermQueryPtr tq = boost::dynamic_pointer_cast(qp->parse(L"foo:zoo*")); @@ -873,8 +803,7 @@ TEST_F(QueryParserTest, testStarParsing) EXPECT_EQ(1, qp->type[0]); } -TEST_F(QueryParserTest, testStopwords) -{ +TEST_F(QueryParserTest, testStopwords) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"a", newLucene(LuceneVersion::LUCENE_CURRENT, StopFilter::makeStopSet(newCollection(L"the", L"foo")))); QueryPtr result = qp->parse(L"a:the OR a:foo"); EXPECT_TRUE(result); @@ -889,8 +818,7 @@ TEST_F(QueryParserTest, testStopwords) EXPECT_EQ(boost::dynamic_pointer_cast(result)->getClauses().size(), 2); } -TEST_F(QueryParserTest, testPositionIncrement) -{ +TEST_F(QueryParserTest, testPositionIncrement) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"a", newLucene(LuceneVersion::LUCENE_CURRENT, StopFilter::makeStopSet(newCollection(L"the", L"in", L"are", L"this")))); qp->setEnablePositionIncrements(true); String qtxt = L"\"the words in positions pos02578 are stopped in this phrasequery\""; @@ -899,12 +827,12 @@ TEST_F(QueryParserTest, testPositionIncrement) PhraseQueryPtr pq = boost::dynamic_pointer_cast(qp->parse(qtxt)); Collection t = pq->getTerms(); Collection pos = pq->getPositions(); - for (int32_t i = 0; i < t.size(); ++i) + for (int32_t i = 0; i < t.size(); ++i) { EXPECT_EQ(expectedPositions[i], pos[i]); + } } -TEST_F(QueryParserTest, testMatchAllDocs) -{ +TEST_F(QueryParserTest, testMatchAllDocs) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", newLucene()); EXPECT_TRUE(newLucene()->equals(qp->parse(L"*:*"))); EXPECT_TRUE(newLucene()->equals(qp->parse(L"(*:*)"))); @@ -913,8 +841,7 @@ TEST_F(QueryParserTest, testMatchAllDocs) EXPECT_TRUE(MiscUtils::typeOf(bq->getClauses()[1]->getQuery())); } -TEST_F(QueryParserTest, testPositionIncrements) -{ +TEST_F(QueryParserTest, testPositionIncrements) { DirectoryPtr dir = newLucene(); AnalyzerPtr a = newLucene(LuceneVersion::LUCENE_CURRENT); IndexWriterPtr w = newLucene(dir, a, IndexWriter::MaxFieldLengthUNLIMITED); diff --git a/src/test/search/BaseTestRangeFilterFixture.cpp b/src/test/search/BaseTestRangeFilterFixture.cpp index d9ea2904..149137f1 100644 --- a/src/test/search/BaseTestRangeFilterFixture.cpp +++ b/src/test/search/BaseTestRangeFilterFixture.cpp @@ -13,70 +13,64 @@ #include "Field.h" #include "Random.h" -namespace Lucene -{ - TestIndex::TestIndex(int32_t minR, int32_t maxR, bool allowNegativeRandomInts) - { - this->minR = minR; - this->maxR = maxR; - this->allowNegativeRandomInts = allowNegativeRandomInts; - this->index = newLucene(); - } +namespace Lucene { - TestIndex::~TestIndex() - { - } +TestIndex::TestIndex(int32_t minR, int32_t maxR, bool allowNegativeRandomInts) { + this->minR = minR; + this->maxR = maxR; + this->allowNegativeRandomInts = allowNegativeRandomInts; + this->index = newLucene(); +} - BaseTestRangeFilterFixture::BaseTestRangeFilterFixture() - { - signedIndex = newLucene(INT_MAX, INT_MIN, true); - unsignedIndex = newLucene(INT_MAX, 0, false); - minId = 0; - maxId = 10000; - intLength = StringUtils::toString(INT_MAX).length(); - random = newLucene(); +TestIndex::~TestIndex() { +} - build(signedIndex); - build(unsignedIndex); - } +BaseTestRangeFilterFixture::BaseTestRangeFilterFixture() { + signedIndex = newLucene(INT_MAX, INT_MIN, true); + unsignedIndex = newLucene(INT_MAX, 0, false); + minId = 0; + maxId = 10000; + intLength = StringUtils::toString(INT_MAX).length(); + random = newLucene(); - BaseTestRangeFilterFixture::~BaseTestRangeFilterFixture() - { - } + build(signedIndex); + build(unsignedIndex); +} - void BaseTestRangeFilterFixture::build(const TestIndexPtr& index) - { - IndexWriterPtr writer = newLucene(index->index, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t d = minId; d <= maxId; ++d) - { - DocumentPtr doc = newLucene(); - doc->add(newLucene(L"id", pad(d), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - int32_t r = index->allowNegativeRandomInts ? random->nextInt() : random->nextInt(INT_MAX); - index->maxR = std::max(index->maxR, r); - index->minR = std::min(index->minR, r); - doc->add(newLucene(L"rand", pad(r), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - doc->add(newLucene(L"body", L"body", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - writer->addDocument(doc); - } +BaseTestRangeFilterFixture::~BaseTestRangeFilterFixture() { +} - writer->optimize(); - writer->close(); +void BaseTestRangeFilterFixture::build(const TestIndexPtr& index) { + IndexWriterPtr writer = newLucene(index->index, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); + for (int32_t d = minId; d <= maxId; ++d) { + DocumentPtr doc = newLucene(); + doc->add(newLucene(L"id", pad(d), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + int32_t r = index->allowNegativeRandomInts ? random->nextInt() : random->nextInt(INT_MAX); + index->maxR = std::max(index->maxR, r); + index->minR = std::min(index->minR, r); + doc->add(newLucene(L"rand", pad(r), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + doc->add(newLucene(L"body", L"body", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + writer->addDocument(doc); } - String BaseTestRangeFilterFixture::pad(int32_t n) - { - StringStream buf; - String p = L"0"; - if (n < 0) - { - p = L"-"; - n = INT_MAX + n + 1; - } - buf << p; - String s = StringUtils::toString(n); - for (int32_t i = s.length(); i <= intLength; ++i) - buf << L"0"; - buf << s; - return buf.str(); + writer->optimize(); + writer->close(); +} + +String BaseTestRangeFilterFixture::pad(int32_t n) { + StringStream buf; + String p = L"0"; + if (n < 0) { + p = L"-"; + n = INT_MAX + n + 1; } + buf << p; + String s = StringUtils::toString(n); + for (int32_t i = s.length(); i <= intLength; ++i) { + buf << L"0"; + } + buf << s; + return buf.str(); +} + } diff --git a/src/test/search/BaseTestRangeFilterTest.cpp b/src/test/search/BaseTestRangeFilterTest.cpp index ec31673b..4e1c51a8 100644 --- a/src/test/search/BaseTestRangeFilterTest.cpp +++ b/src/test/search/BaseTestRangeFilterTest.cpp @@ -11,11 +11,9 @@ using namespace Lucene; typedef BaseTestRangeFilterFixture BaseTestRangeFilterTest; -TEST_F(BaseTestRangeFilterTest, testPad) -{ +TEST_F(BaseTestRangeFilterTest, testPad) { Collection tests = newCollection(-9999999, -99560, -100, -1, 0, 3, 9, 10, 1000, 999999999); - for (int32_t i = 0; i < tests.size() - 1; ++i) - { + for (int32_t i = 0; i < tests.size() - 1; ++i) { int32_t a = tests[i]; int32_t b = tests[i + 1]; String aa = pad(a); diff --git a/src/test/search/Boolean2Test.cpp b/src/test/search/Boolean2Test.cpp index bc00c101..e9f45227 100644 --- a/src/test/search/Boolean2Test.cpp +++ b/src/test/search/Boolean2Test.cpp @@ -34,16 +34,13 @@ using namespace Lucene; /// Test BooleanQuery2 against BooleanQuery by overriding the standard query parser. /// This also tests the scoring order of BooleanQuery. -class Boolean2Test : public LuceneTestFixture -{ +class Boolean2Test : public LuceneTestFixture { public: - Boolean2Test() - { + Boolean2Test() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); docFields = newCollection(L"w1 w2 w3 w4 w5", L"w1 w3 w2 w3", L"w1 xx w2 yy w3", L"w1 w3 xx w2 yy w3"); - for (int32_t i = 0; i < docFields.size(); ++i) - { + for (int32_t i = 0; i < docFields.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(field, docFields[i], Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -58,26 +55,26 @@ class Boolean2Test : public LuceneTestFixture // First multiply small test index mulFactor = 1; int32_t docCount = 0; - do - { + do { DirectoryPtr copy = newLucene(dir2); IndexWriterPtr w = newLucene(dir2, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); w->addIndexesNoOptimize(newCollection(copy)); docCount = w->maxDoc(); w->close(); mulFactor *= 2; - } - while (docCount < 3000); + } while (docCount < 3000); IndexWriterPtr w = newLucene(dir2, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field2", L"xxx", Field::STORE_NO, Field::INDEX_ANALYZED)); - for (int32_t i = 0; i addDocument(doc); + } doc = newLucene(); doc->add(newLucene(L"field2", L"big bad bug", Field::STORE_NO, Field::INDEX_ANALYZED)); - for (int32_t i = 0; i addDocument(doc); + } // optimize to 1 segment w->optimize(); reader = w->getReader(); @@ -85,8 +82,7 @@ class Boolean2Test : public LuceneTestFixture bigSearcher = newLucene(reader); } - virtual ~Boolean2Test() - { + virtual ~Boolean2Test() { reader->close(); dir2->close(); } @@ -104,13 +100,11 @@ class Boolean2Test : public LuceneTestFixture static const String field; public: - QueryPtr makeQuery(const String& queryText) - { + QueryPtr makeQuery(const String& queryText) { return newLucene(LuceneVersion::LUCENE_CURRENT, field, newLucene())->parse(queryText); } - void queriesTest(const String& queryText, Collection expDocNrs) - { + void queriesTest(const String& queryText, Collection expDocNrs) { QueryPtr query1 = makeQuery(queryText); TopScoreDocCollectorPtr collector = TopScoreDocCollector::create(1000, false); searcher->search(query1, FilterPtr(), collector); @@ -127,32 +121,32 @@ class Boolean2Test : public LuceneTestFixture } /// Random rnd is passed in so that the exact same random query may be created more than once. - BooleanQueryPtr randBoolQuery(const RandomPtr& rnd, bool allowMust, int32_t level, const String& field, Collection vals) - { + BooleanQueryPtr randBoolQuery(const RandomPtr& rnd, bool allowMust, int32_t level, const String& field, Collection vals) { BooleanQueryPtr current = newLucene(rnd->nextInt() < 0); - for (int32_t i = 0; i < rnd->nextInt(vals.size()) + 1; ++i) - { + for (int32_t i = 0; i < rnd->nextInt(vals.size()) + 1; ++i) { int32_t qType = 0; // term query - if (level > 0) + if (level > 0) { qType = rnd->nextInt(10); + } QueryPtr q; - if (qType < 3) + if (qType < 3) { q = newLucene(newLucene(field, vals[rnd->nextInt(vals.size())])); - else if (qType < 7) + } else if (qType < 7) { q = newLucene(newLucene(field, L"w*")); - else + } else { q = randBoolQuery(rnd, allowMust, level - 1, field, vals); + } int32_t r = rnd->nextInt(10); BooleanClause::Occur occur = BooleanClause::SHOULD; - if (r < 2) + if (r < 2) { occur = BooleanClause::MUST_NOT; - else if (r < 5) - { - if (allowMust) + } else if (r < 5) { + if (allowMust) { occur = BooleanClause::MUST; - else + } else { occur = BooleanClause::SHOULD; + } } current->add(q, occur); @@ -164,88 +158,76 @@ class Boolean2Test : public LuceneTestFixture const String Boolean2Test::field = L"field"; const int32_t Boolean2Test::NUM_EXTRA_DOCS = 6000; -TEST_F(Boolean2Test, testQueries01) -{ +TEST_F(Boolean2Test, testQueries01) { String queryText = L"+w3 +xx"; Collection expDocNrs = newCollection(2, 3); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries02) -{ +TEST_F(Boolean2Test, testQueries02) { String queryText = L"+w3 xx"; Collection expDocNrs = newCollection(2, 3, 1, 0); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries03) -{ +TEST_F(Boolean2Test, testQueries03) { String queryText = L"w3 xx"; Collection expDocNrs = newCollection(2, 3, 1, 0); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries04) -{ +TEST_F(Boolean2Test, testQueries04) { String queryText = L"w3 -xx"; Collection expDocNrs = newCollection(1, 0); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries05) -{ +TEST_F(Boolean2Test, testQueries05) { String queryText = L"+w3 -xx"; Collection expDocNrs = newCollection(1, 0); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries06) -{ +TEST_F(Boolean2Test, testQueries06) { String queryText = L"+w3 -xx -w5"; Collection expDocNrs = newCollection(1); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries07) -{ +TEST_F(Boolean2Test, testQueries07) { String queryText = L"-w3 -xx -w5"; Collection expDocNrs = Collection::newInstance(); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries08) -{ +TEST_F(Boolean2Test, testQueries08) { String queryText = L"+w3 xx -w5"; Collection expDocNrs = newCollection(2, 3, 1); queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testQueries09) -{ +TEST_F(Boolean2Test, testQueries09) { String queryText = L"+w3 +xx +w2 zz"; Collection expDocNrs = newCollection(2, 3); queriesTest(queryText, expDocNrs); } -namespace TestQueries10 -{ - class OverlapSimilarity : public DefaultSimilarity - { - public: - virtual ~OverlapSimilarity() - { - } +namespace TestQueries10 { + +class OverlapSimilarity : public DefaultSimilarity { +public: + virtual ~OverlapSimilarity() { + } + +public: + virtual double coord(int32_t overlap, int32_t maxOverlap) { + return (double)overlap / ((double)maxOverlap - 1.0); + } +}; - public: - virtual double coord(int32_t overlap, int32_t maxOverlap) - { - return (double)overlap / ((double)maxOverlap - 1.0); - } - }; } -TEST_F(Boolean2Test, testQueries10) -{ +TEST_F(Boolean2Test, testQueries10) { String queryText = L"+w3 +xx +w2 zz"; Collection expDocNrs = newCollection(2, 3); searcher->setSimilarity(newLucene()); @@ -253,14 +235,12 @@ TEST_F(Boolean2Test, testQueries10) queriesTest(queryText, expDocNrs); } -TEST_F(Boolean2Test, testRandomQueries) -{ +TEST_F(Boolean2Test, testRandomQueries) { RandomPtr rnd = newLucene(17); Collection vals = newCollection(L"w1", L"w2", L"w3", L"w4", L"w5", L"xx", L"yy", L"zzz"); int32_t tot = 0; // increase number of iterations for more complete testing - for (int32_t i = 0; i < 1000; ++i) - { + for (int32_t i = 0; i < 1000; ++i) { int32_t level = rnd->nextInt(3); BooleanQueryPtr q1 = randBoolQuery(rnd, rnd->nextInt() % 2 == 0, level, field, vals); diff --git a/src/test/search/BooleanMinShouldMatchTest.cpp b/src/test/search/BooleanMinShouldMatchTest.cpp index 96eb3a01..e67143fe 100644 --- a/src/test/search/BooleanMinShouldMatchTest.cpp +++ b/src/test/search/BooleanMinShouldMatchTest.cpp @@ -25,31 +25,29 @@ using namespace Lucene; -class BooleanMinShouldMatchTest : public LuceneTestFixture -{ +class BooleanMinShouldMatchTest : public LuceneTestFixture { public: - BooleanMinShouldMatchTest() - { + BooleanMinShouldMatchTest() { Collection data = newCollection( - L"A 1 2 3 4 5 6", - L"Z 4 5 6", - L"", - L"B 2 4 5 6", - L"Y 3 5 6", - L"", - L"C 3 6", - L"X 4 5 6" - ); + L"A 1 2 3 4 5 6", + L"Z 4 5 6", + L"", + L"B 2 4 5 6", + L"Y 3 5 6", + L"", + L"C 3 6", + L"X 4 5 6" + ); index = newLucene(); IndexWriterPtr writer = newLucene(index, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < data.size(); ++i) - { + for (int32_t i = 0; i < data.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"all", L"all", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - if (!data[i].empty()) + if (!data[i].empty()) { doc->add(newLucene(L"data", data[i], Field::STORE_YES, Field::INDEX_ANALYZED)); + } writer->addDocument(doc); } @@ -60,8 +58,7 @@ class BooleanMinShouldMatchTest : public LuceneTestFixture s = newLucene(r); } - virtual ~BooleanMinShouldMatchTest() - { + virtual ~BooleanMinShouldMatchTest() { } public: @@ -70,40 +67,39 @@ class BooleanMinShouldMatchTest : public LuceneTestFixture IndexSearcherPtr s; public: - void verifyNrHits(const QueryPtr& q, int32_t expected) - { + void verifyNrHits(const QueryPtr& q, int32_t expected) { Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(expected, h.size()); QueryUtils::check(q, s); } /// Random rnd is passed in so that the exact same random query may be created more than once. - BooleanQueryPtr randBoolQuery(const RandomPtr& rnd, bool allowMust, int32_t level, const String& field, Collection vals) - { + BooleanQueryPtr randBoolQuery(const RandomPtr& rnd, bool allowMust, int32_t level, const String& field, Collection vals) { BooleanQueryPtr current = newLucene(rnd->nextInt() < 0); - for (int32_t i = 0; i < rnd->nextInt(vals.size()) + 1; ++i) - { + for (int32_t i = 0; i < rnd->nextInt(vals.size()) + 1; ++i) { int32_t qType = 0; // term query - if (level > 0) + if (level > 0) { qType = rnd->nextInt(10); + } QueryPtr q; - if (qType < 3) + if (qType < 3) { q = newLucene(newLucene(field, vals[rnd->nextInt(vals.size())])); - else if (qType < 7) + } else if (qType < 7) { q = newLucene(newLucene(field, L"w*")); - else + } else { q = randBoolQuery(rnd, allowMust, level - 1, field, vals); + } int32_t r = rnd->nextInt(10); BooleanClause::Occur occur = BooleanClause::SHOULD; - if (r < 2) + if (r < 2) { occur = BooleanClause::MUST_NOT; - else if (r < 5) - { - if (allowMust) + } else if (r < 5) { + if (allowMust) { occur = BooleanClause::MUST; - else + } else { occur = BooleanClause::SHOULD; + } } current->add(q, occur); @@ -111,30 +107,28 @@ class BooleanMinShouldMatchTest : public LuceneTestFixture return current; } - void minNrCB(const RandomPtr& rnd, const BooleanQueryPtr& q) - { + void minNrCB(const RandomPtr& rnd, const BooleanQueryPtr& q) { Collection c = q->getClauses(); int32_t opt = 0; - for (int32_t i = 0; i < c.size(); ++i) - { - if (c[i]->getOccur() == BooleanClause::SHOULD) + for (int32_t i = 0; i < c.size(); ++i) { + if (c[i]->getOccur() == BooleanClause::SHOULD) { ++opt; + } } q->setMinimumNumberShouldMatch(rnd->nextInt(opt + 2)); } }; -TEST_F(BooleanMinShouldMatchTest, testAllOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testAllOptional) { BooleanQueryPtr q = newLucene(); - for (int32_t i = 1; i <= 4; ++i) + for (int32_t i = 1; i <= 4; ++i) { q->add(newLucene(newLucene(L"data", StringUtils::toString(i))), BooleanClause::SHOULD); + } q->setMinimumNumberShouldMatch(2); // match at least two of 4 verifyNrHits(q, 2); } -TEST_F(BooleanMinShouldMatchTest, testOneReqAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testOneReqAndSomeOptional) { // one required, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -147,8 +141,7 @@ TEST_F(BooleanMinShouldMatchTest, testOneReqAndSomeOptional) verifyNrHits(q, 5); } -TEST_F(BooleanMinShouldMatchTest, testSomeReqAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testSomeReqAndSomeOptional) { // two required, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -162,8 +155,7 @@ TEST_F(BooleanMinShouldMatchTest, testSomeReqAndSomeOptional) verifyNrHits(q, 5); } -TEST_F(BooleanMinShouldMatchTest, testOneProhibAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testOneProhibAndSomeOptional) { // one prohibited, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"data", L"1")), BooleanClause::SHOULD); @@ -176,8 +168,7 @@ TEST_F(BooleanMinShouldMatchTest, testOneProhibAndSomeOptional) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testSomeProhibAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testSomeProhibAndSomeOptional) { // two prohibited, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"data", L"1")), BooleanClause::SHOULD); @@ -191,8 +182,7 @@ TEST_F(BooleanMinShouldMatchTest, testSomeProhibAndSomeOptional) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testOneReqOneProhibAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testOneReqOneProhibAndSomeOptional) { // one required, one prohibited, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"data", L"6")), BooleanClause::MUST); @@ -207,8 +197,7 @@ TEST_F(BooleanMinShouldMatchTest, testOneReqOneProhibAndSomeOptional) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testSomeReqOneProhibAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testSomeReqOneProhibAndSomeOptional) { // two required, one prohibited, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -224,8 +213,7 @@ TEST_F(BooleanMinShouldMatchTest, testSomeReqOneProhibAndSomeOptional) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testOneReqSomeProhibAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testOneReqSomeProhibAndSomeOptional) { // one required, two prohibited, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"data", L"6")), BooleanClause::MUST); @@ -241,8 +229,7 @@ TEST_F(BooleanMinShouldMatchTest, testOneReqSomeProhibAndSomeOptional) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testSomeReqSomeProhibAndSomeOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testSomeReqSomeProhibAndSomeOptional) { // two required, two prohibited, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -259,8 +246,7 @@ TEST_F(BooleanMinShouldMatchTest, testSomeReqSomeProhibAndSomeOptional) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testMinHigherThenNumOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testMinHigherThenNumOptional) { // two required, two prohibited, some optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -277,8 +263,7 @@ TEST_F(BooleanMinShouldMatchTest, testMinHigherThenNumOptional) verifyNrHits(q, 0); } -TEST_F(BooleanMinShouldMatchTest, testMinEqualToNumOptional) -{ +TEST_F(BooleanMinShouldMatchTest, testMinEqualToNumOptional) { // two required, two optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::SHOULD); @@ -291,8 +276,7 @@ TEST_F(BooleanMinShouldMatchTest, testMinEqualToNumOptional) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testOneOptionalEqualToMin) -{ +TEST_F(BooleanMinShouldMatchTest, testOneOptionalEqualToMin) { // two required, one optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -304,8 +288,7 @@ TEST_F(BooleanMinShouldMatchTest, testOneOptionalEqualToMin) verifyNrHits(q, 1); } -TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin) -{ +TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin) { // two required, no optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -316,8 +299,7 @@ TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin) verifyNrHits(q, 0); } -TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin2) -{ +TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin2) { // one required, no optional BooleanQueryPtr q = newLucene(); q->add(newLucene(newLucene(L"all", L"all")), BooleanClause::MUST); @@ -327,8 +309,7 @@ TEST_F(BooleanMinShouldMatchTest, testNoOptionalButMin2) verifyNrHits(q, 0); } -TEST_F(BooleanMinShouldMatchTest, testRandomQueries) -{ +TEST_F(BooleanMinShouldMatchTest, testRandomQueries) { RandomPtr rnd = newLucene(17); String field = L"data"; @@ -349,8 +330,7 @@ TEST_F(BooleanMinShouldMatchTest, testRandomQueries) int32_t maxLev = 4; // increase number of iterations for more complete testing - for (int32_t i = 0; i < 1000; ++i) - { + for (int32_t i = 0; i < 1000; ++i) { int32_t lev = rnd->nextInt(maxLev); int32_t seed = rnd->nextInt(); @@ -374,16 +354,13 @@ TEST_F(BooleanMinShouldMatchTest, testRandomQueries) // The constrained query should be a superset to the unconstrained query. EXPECT_TRUE(top2->totalHits <= top1->totalHits); - for (int32_t hit = 0; hit < top2->totalHits; ++hit) - { + for (int32_t hit = 0; hit < top2->totalHits; ++hit) { int32_t id = top2->scoreDocs[hit]->doc; double score = top2->scoreDocs[hit]->score; bool found = false; // find this doc in other hits - for (int32_t other = 0; other < top1->totalHits; ++other) - { - if (top1->scoreDocs[other]->doc == id) - { + for (int32_t other = 0; other < top1->totalHits; ++other) { + if (top1->scoreDocs[other]->doc == id) { found = true; double otherScore = top1->scoreDocs[other]->score; // check if scores match diff --git a/src/test/search/BooleanOrTest.cpp b/src/test/search/BooleanOrTest.cpp index 773252e6..f9685c29 100644 --- a/src/test/search/BooleanOrTest.cpp +++ b/src/test/search/BooleanOrTest.cpp @@ -20,11 +20,9 @@ using namespace Lucene; -class BooleanOrTest : public LuceneTestFixture -{ +class BooleanOrTest : public LuceneTestFixture { public: - BooleanOrTest() - { + BooleanOrTest() { t1 = newLucene(newLucene(FIELD_T, L"files")); t2 = newLucene(newLucene(FIELD_T, L"deleting")); c1 = newLucene(newLucene(FIELD_C, L"production")); @@ -42,8 +40,7 @@ class BooleanOrTest : public LuceneTestFixture searcher = newLucene(rd, true); } - virtual ~BooleanOrTest() - { + virtual ~BooleanOrTest() { } protected: @@ -58,8 +55,7 @@ class BooleanOrTest : public LuceneTestFixture IndexSearcherPtr searcher; public: - int32_t search(const QueryPtr& q) - { + int32_t search(const QueryPtr& q) { QueryUtils::check(q, searcher); return searcher->search(q, FilterPtr(), 1000)->totalHits; } @@ -68,16 +64,14 @@ class BooleanOrTest : public LuceneTestFixture const String BooleanOrTest::FIELD_T = L"T"; const String BooleanOrTest::FIELD_C = L"C"; -TEST_F(BooleanOrTest, testElements) -{ +TEST_F(BooleanOrTest, testElements) { EXPECT_EQ(1, search(t1)); EXPECT_EQ(1, search(t2)); EXPECT_EQ(1, search(c1)); EXPECT_EQ(1, search(c2)); } -TEST_F(BooleanOrTest, testFlat) -{ +TEST_F(BooleanOrTest, testFlat) { BooleanQueryPtr q = newLucene(); q->add(newLucene(t1, BooleanClause::SHOULD)); q->add(newLucene(t2, BooleanClause::SHOULD)); @@ -86,8 +80,7 @@ TEST_F(BooleanOrTest, testFlat) EXPECT_EQ(1, search(q)); } -TEST_F(BooleanOrTest, testParenthesisMust) -{ +TEST_F(BooleanOrTest, testParenthesisMust) { BooleanQueryPtr q3 = newLucene(); q3->add(newLucene(t1, BooleanClause::SHOULD)); q3->add(newLucene(t2, BooleanClause::SHOULD)); @@ -100,8 +93,7 @@ TEST_F(BooleanOrTest, testParenthesisMust) EXPECT_EQ(1, search(q2)); } -TEST_F(BooleanOrTest, testParenthesisMust2) -{ +TEST_F(BooleanOrTest, testParenthesisMust2) { BooleanQueryPtr q3 = newLucene(); q3->add(newLucene(t1, BooleanClause::SHOULD)); q3->add(newLucene(t2, BooleanClause::SHOULD)); @@ -114,8 +106,7 @@ TEST_F(BooleanOrTest, testParenthesisMust2) EXPECT_EQ(1, search(q2)); } -TEST_F(BooleanOrTest, testParenthesisShould) -{ +TEST_F(BooleanOrTest, testParenthesisShould) { BooleanQueryPtr q3 = newLucene(); q3->add(newLucene(t1, BooleanClause::SHOULD)); q3->add(newLucene(t2, BooleanClause::SHOULD)); diff --git a/src/test/search/BooleanPrefixQueryTest.cpp b/src/test/search/BooleanPrefixQueryTest.cpp index 3ab106ed..6cc97c93 100644 --- a/src/test/search/BooleanPrefixQueryTest.cpp +++ b/src/test/search/BooleanPrefixQueryTest.cpp @@ -25,34 +25,29 @@ using namespace Lucene; typedef LuceneTestFixture BooleanPrefixQueryTest; -static int32_t getCount(const IndexReaderPtr& r, const QueryPtr& q) -{ - if (MiscUtils::typeOf(q)) +static int32_t getCount(const IndexReaderPtr& r, const QueryPtr& q) { + if (MiscUtils::typeOf(q)) { return boost::dynamic_pointer_cast(q)->getClauses().size(); - else if (MiscUtils::typeOf(q)) - { + } else if (MiscUtils::typeOf(q)) { DocIdSetIteratorPtr iter = boost::dynamic_pointer_cast(q)->getFilter()->getDocIdSet(r)->iterator(); int32_t count = 0; - while (iter->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) + while (iter->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) { ++count; + } return count; - } - else - { + } else { boost::throw_exception(RuntimeException(L"unexpected query")); return 0; } } -TEST_F(BooleanPrefixQueryTest, testMethod) -{ +TEST_F(BooleanPrefixQueryTest, testMethod) { RAMDirectoryPtr directory = newLucene(); Collection categories = newCollection(L"food", L"foodanddrink", L"foodanddrinkandgoodtimes", L"food and drink"); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < categories.size(); ++i) - { + for (int32_t i = 0; i < categories.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"category", categories[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); diff --git a/src/test/search/BooleanQueryTest.cpp b/src/test/search/BooleanQueryTest.cpp index 2411f91e..f8a1e270 100644 --- a/src/test/search/BooleanQueryTest.cpp +++ b/src/test/search/BooleanQueryTest.cpp @@ -24,8 +24,7 @@ using namespace Lucene; typedef LuceneTestFixture BooleanQueryTest; -TEST_F(BooleanQueryTest, testEquality) -{ +TEST_F(BooleanQueryTest, testEquality) { BooleanQueryPtr bq1 = newLucene(); bq1->add(newLucene(newLucene(L"field", L"value1")), BooleanClause::SHOULD); bq1->add(newLucene(newLucene(L"field", L"value2")), BooleanClause::SHOULD); @@ -45,20 +44,15 @@ TEST_F(BooleanQueryTest, testEquality) EXPECT_TRUE(bq1->equals(bq2)); } -TEST_F(BooleanQueryTest, testException) -{ - try - { +TEST_F(BooleanQueryTest, testException) { + try { BooleanQuery::setMaxClauseCount(0); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } -TEST_F(BooleanQueryTest, testNullOrSubScorer) -{ +TEST_F(BooleanQueryTest, testNullOrSubScorer) { DirectoryPtr dir = newLucene(); IndexWriterPtr w = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); diff --git a/src/test/search/BooleanScorerTest.cpp b/src/test/search/BooleanScorerTest.cpp index a3eb9a97..86b38e45 100644 --- a/src/test/search/BooleanScorerTest.cpp +++ b/src/test/search/BooleanScorerTest.cpp @@ -24,16 +24,14 @@ using namespace Lucene; typedef LuceneTestFixture BooleanScorerTest; -TEST_F(BooleanScorerTest, testMethod) -{ +TEST_F(BooleanScorerTest, testMethod) { static const String FIELD = L"category"; RAMDirectoryPtr directory = newLucene(); Collection values = newCollection(L"1", L"2", L"3", L"4"); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < values.size(); ++i) - { + for (int32_t i = 0; i < values.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD, values[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); @@ -53,50 +51,43 @@ TEST_F(BooleanScorerTest, testMethod) EXPECT_EQ(2, hits.size()); } -namespace TestEmptyBucketWithMoreDocs -{ - class EmptyScorer : public Scorer - { - public: - EmptyScorer(const SimilarityPtr& similarity) : Scorer(similarity) - { - doc = -1; - } - - virtual ~EmptyScorer() - { - } - - protected: - int32_t doc; - - public: - virtual double score() - { - return 0.0; - } - - virtual int32_t docID() - { - return doc; - } - - virtual int32_t nextDoc() - { - doc = doc == -1 ? 3000 : NO_MORE_DOCS; - return doc; - } - - virtual int32_t advance(int32_t target) - { - doc = target <= 3000 ? 3000 : NO_MORE_DOCS; - return doc; - } - }; +namespace TestEmptyBucketWithMoreDocs { + +class EmptyScorer : public Scorer { +public: + EmptyScorer(const SimilarityPtr& similarity) : Scorer(similarity) { + doc = -1; + } + + virtual ~EmptyScorer() { + } + +protected: + int32_t doc; + +public: + virtual double score() { + return 0.0; + } + + virtual int32_t docID() { + return doc; + } + + virtual int32_t nextDoc() { + doc = doc == -1 ? 3000 : NO_MORE_DOCS; + return doc; + } + + virtual int32_t advance(int32_t target) { + doc = target <= 3000 ? 3000 : NO_MORE_DOCS; + return doc; + } +}; + } -TEST_F(BooleanScorerTest, testEmptyBucketWithMoreDocs) -{ +TEST_F(BooleanScorerTest, testEmptyBucketWithMoreDocs) { // This test checks the logic of nextDoc() when all sub scorers have docs beyond the first bucket // (for example). Currently, the code relies on the 'more' variable to work properly, and this // test ensures that if the logic changes, we have a test to back it up. diff --git a/src/test/search/CachingSpanFilterTest.cpp b/src/test/search/CachingSpanFilterTest.cpp index 0c6a6106..09d2bad1 100644 --- a/src/test/search/CachingSpanFilterTest.cpp +++ b/src/test/search/CachingSpanFilterTest.cpp @@ -29,18 +29,17 @@ using namespace Lucene; typedef LuceneTestFixture CachingSpanFilterTest; -static IndexReaderPtr refreshReader(const IndexReaderPtr& reader) -{ +static IndexReaderPtr refreshReader(const IndexReaderPtr& reader) { IndexReaderPtr _reader(reader); IndexReaderPtr oldReader = _reader; _reader = _reader->reopen(); - if (_reader != oldReader) + if (_reader != oldReader) { oldReader->close(); + } return _reader; } -TEST_F(CachingSpanFilterTest, testEnforceDeletions) -{ +TEST_F(CachingSpanFilterTest, testEnforceDeletions) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); IndexReaderPtr reader = writer->getReader(); diff --git a/src/test/search/CachingWrapperFilterTest.cpp b/src/test/search/CachingWrapperFilterTest.cpp index 6716e46f..39d3e92f 100644 --- a/src/test/search/CachingWrapperFilterTest.cpp +++ b/src/test/search/CachingWrapperFilterTest.cpp @@ -34,31 +34,30 @@ using namespace Lucene; typedef LuceneTestFixture CachingWrapperFilterTest; -static void checkDocIdSetCacheable(const IndexReaderPtr& reader, const FilterPtr& filter, bool shouldCacheable) -{ +static void checkDocIdSetCacheable(const IndexReaderPtr& reader, const FilterPtr& filter, bool shouldCacheable) { CachingWrapperFilterPtr cacher = newLucene(filter); DocIdSetPtr originalSet = filter->getDocIdSet(reader); DocIdSetPtr cachedSet = cacher->getDocIdSet(reader); EXPECT_TRUE(cachedSet->isCacheable()); EXPECT_EQ(shouldCacheable, originalSet->isCacheable()); - if (originalSet->isCacheable()) + if (originalSet->isCacheable()) { EXPECT_TRUE(MiscUtils::equalTypes(originalSet, cachedSet)); - else + } else { EXPECT_TRUE(MiscUtils::typeOf(cachedSet)); + } } -static IndexReaderPtr refreshReader(const IndexReaderPtr& reader) -{ +static IndexReaderPtr refreshReader(const IndexReaderPtr& reader) { IndexReaderPtr _reader(reader); IndexReaderPtr oldReader = _reader; _reader = _reader->reopen(); - if (_reader != oldReader) + if (_reader != oldReader) { oldReader->close(); + } return _reader; } -TEST_F(CachingWrapperFilterTest, testCachingWorks) -{ +TEST_F(CachingWrapperFilterTest, testCachingWorks) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->close(); @@ -83,25 +82,22 @@ TEST_F(CachingWrapperFilterTest, testCachingWorks) reader->close(); } -namespace TestNullDocIdSet -{ - class NullDocIdSetFilter : public Filter - { - public: - virtual ~NullDocIdSetFilter() - { - } - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { - return DocIdSetPtr(); - } - }; +namespace TestNullDocIdSet { + +class NullDocIdSetFilter : public Filter { +public: + virtual ~NullDocIdSetFilter() { + } + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { + return DocIdSetPtr(); + } +}; + } -TEST_F(CachingWrapperFilterTest, testNullDocIdSet) -{ +TEST_F(CachingWrapperFilterTest, testNullDocIdSet) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->close(); @@ -116,39 +112,33 @@ TEST_F(CachingWrapperFilterTest, testNullDocIdSet) reader->close(); } -namespace TestNullDocIdSetIterator -{ - class NullDocIdSetIterator : public DocIdSet - { - public: - virtual ~NullDocIdSetIterator() - { - } - - public: - virtual DocIdSetIteratorPtr iterator() - { - return DocIdSetIteratorPtr(); - } - }; - - class NullDocIdSetIteratorFilter : public Filter - { - public: - virtual ~NullDocIdSetIteratorFilter() - { - } - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { - return newLucene(); - } - }; +namespace TestNullDocIdSetIterator { + +class NullDocIdSetIterator : public DocIdSet { +public: + virtual ~NullDocIdSetIterator() { + } + +public: + virtual DocIdSetIteratorPtr iterator() { + return DocIdSetIteratorPtr(); + } +}; + +class NullDocIdSetIteratorFilter : public Filter { +public: + virtual ~NullDocIdSetIteratorFilter() { + } + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { + return newLucene(); + } +}; + } -TEST_F(CachingWrapperFilterTest, testNullDocIdSetIterator) -{ +TEST_F(CachingWrapperFilterTest, testNullDocIdSetIterator) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->close(); @@ -163,25 +153,22 @@ TEST_F(CachingWrapperFilterTest, testNullDocIdSetIterator) reader->close(); } -namespace TestIsCacheable -{ - class OpenBitSetFilter : public Filter - { - public: - virtual ~OpenBitSetFilter() - { - } - - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { - return newLucene(); - } - }; +namespace TestIsCacheable { + +class OpenBitSetFilter : public Filter { +public: + virtual ~OpenBitSetFilter() { + } + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { + return newLucene(); + } +}; + } -TEST_F(CachingWrapperFilterTest, testIsCacheable) -{ +TEST_F(CachingWrapperFilterTest, testIsCacheable) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->close(); @@ -201,8 +188,7 @@ TEST_F(CachingWrapperFilterTest, testIsCacheable) checkDocIdSetCacheable(reader, newLucene(), true); } -TEST_F(CachingWrapperFilterTest, testEnforceDeletions) -{ +TEST_F(CachingWrapperFilterTest, testEnforceDeletions) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); IndexReaderPtr reader = writer->getReader(); diff --git a/src/test/search/CheckHits.cpp b/src/test/search/CheckHits.cpp index 72e53d1e..9d8ea30f 100644 --- a/src/test/search/CheckHits.cpp +++ b/src/test/search/CheckHits.cpp @@ -19,278 +19,256 @@ #include "Scorer.h" #include "MiscUtils.h" -namespace Lucene -{ - /// Some explains methods calculate their values though a slightly different order of operations - /// from the actual scoring method - this allows for a small amount of variation - const double CheckHits::EXPLAIN_SCORE_TOLERANCE_DELTA = 0.00005; - - class SetCollector : public Collector - { - public: - SetCollector(Set bag) - { - this->bag = bag; - this->base = 0; - } - - virtual ~SetCollector() - { - } +namespace Lucene { - public: - Set bag; +/// Some explains methods calculate their values though a slightly different order of operations +/// from the actual scoring method - this allows for a small amount of variation +const double CheckHits::EXPLAIN_SCORE_TOLERANCE_DELTA = 0.00005; - protected: - int32_t base; +class SetCollector : public Collector { +public: + SetCollector(Set bag) { + this->bag = bag; + this->base = 0; + } - public: - virtual void setScorer(const ScorerPtr& scorer) - { - } + virtual ~SetCollector() { + } - virtual void collect(int32_t doc) - { - bag.add(doc + base); - } +public: + Set bag; - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - base = docBase; - } +protected: + int32_t base; - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; - - /// Asserts that the score explanation for every document matching a query corresponds with the true score. - /// - /// NOTE: this HitCollector should only be used with the Query and Searcher specified at when it is constructed. - class ExplanationAsserter : public Collector - { - public: - ExplanationAsserter(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& s, bool deep = false) - { - this->q=q; - this->s=s; - this->d = q->toString(defaultFieldName); - this->deep=deep; - this->base = 0; - } +public: + virtual void setScorer(const ScorerPtr& scorer) { + } - virtual ~ExplanationAsserter() - { - } + virtual void collect(int32_t doc) { + bag.add(doc + base); + } - public: - QueryPtr q; - SearcherPtr s; - String d; - bool deep; - ScorerPtr scorer; + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + base = docBase; + } - protected: - int32_t base; + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; + +/// Asserts that the score explanation for every document matching a query corresponds with the true score. +/// +/// NOTE: this HitCollector should only be used with the Query and Searcher specified at when it is constructed. +class ExplanationAsserter : public Collector { +public: + ExplanationAsserter(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& s, bool deep = false) { + this->q=q; + this->s=s; + this->d = q->toString(defaultFieldName); + this->deep=deep; + this->base = 0; + } - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } + virtual ~ExplanationAsserter() { + } - virtual void collect(int32_t doc) - { - doc = doc + base; - ExplanationPtr exp = s->explain(q, doc); +public: + QueryPtr q; + SearcherPtr s; + String d; + bool deep; + ScorerPtr scorer; - EXPECT_TRUE(exp); - CheckHits::verifyExplanation(d, doc, scorer->score(), deep, exp); - } +protected: + int32_t base; - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - base = docBase; - } +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; + virtual void collect(int32_t doc) { + doc = doc + base; + ExplanationPtr exp = s->explain(q, doc); - CheckHits::~CheckHits() - { + EXPECT_TRUE(exp); + CheckHits::verifyExplanation(d, doc, scorer->score(), deep, exp); } - void CheckHits::checkNoMatchExplanations(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) - { - String d = q->toString(defaultFieldName); - Set ignore = Set::newInstance(); - for (int32_t i = 0; i < results.size(); ++i) - ignore.add(results[i]); - - int32_t maxDoc = searcher->maxDoc(); - for (int32_t doc = 0; doc < maxDoc; ++doc) - { - if (ignore.contains(doc)) - continue; - - ExplanationPtr exp = searcher->explain(q, doc); - EXPECT_TRUE(exp); - EXPECT_EQ(0.0, exp->getValue()); - } + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + base = docBase; } - void CheckHits::checkHitCollector(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) - { - QueryUtils::check(query, searcher); - Set correct = Set::newInstance(); - for (int32_t i = 0; i < results.size(); ++i) - correct.add(results[i]); + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; - Set actual = Set::newInstance(); - CollectorPtr c = newLucene(actual); +CheckHits::~CheckHits() { +} - searcher->search(query, c); - EXPECT_TRUE(correct.equals(actual)); +void CheckHits::checkNoMatchExplanations(const QueryPtr& q, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) { + String d = q->toString(defaultFieldName); + Set ignore = Set::newInstance(); + for (int32_t i = 0; i < results.size(); ++i) { + ignore.add(results[i]); + } - for (int32_t i = -1; i < 2; ++i) - { - actual.clear(); - QueryUtils::wrapSearcher(searcher, i)->search(query, c); - EXPECT_TRUE(correct.equals(actual)); + int32_t maxDoc = searcher->maxDoc(); + for (int32_t doc = 0; doc < maxDoc; ++doc) { + if (ignore.contains(doc)) { + continue; } - if (!MiscUtils::typeOf(searcher)) - return; + ExplanationPtr exp = searcher->explain(q, doc); + EXPECT_TRUE(exp); + EXPECT_EQ(0.0, exp->getValue()); + } +} - for (int32_t i = -1; i < 2; ++i) - { - actual.clear(); - QueryUtils::wrapUnderlyingReader(boost::dynamic_pointer_cast(searcher), i)->search(query, c); - EXPECT_TRUE(correct.equals(actual)); - } +void CheckHits::checkHitCollector(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) { + QueryUtils::check(query, searcher); + Set correct = Set::newInstance(); + for (int32_t i = 0; i < results.size(); ++i) { + correct.add(results[i]); } - void CheckHits::checkHits(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) - { - if (!MiscUtils::typeOf(searcher)) - QueryUtils::check(query, searcher); + Set actual = Set::newInstance(); + CollectorPtr c = newLucene(actual); - Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - Set correct = Set::newInstance(); - for (int32_t i = 0; i < results.size(); ++i) - correct.add(results[i]); + searcher->search(query, c); + EXPECT_TRUE(correct.equals(actual)); - Set actual = Set::newInstance(); - for (int32_t i = 0; i < hits.size(); ++i) - actual.add(hits[i]->doc); + for (int32_t i = -1; i < 2; ++i) { + actual.clear(); + QueryUtils::wrapSearcher(searcher, i)->search(query, c); + EXPECT_TRUE(correct.equals(actual)); + } + if (!MiscUtils::typeOf(searcher)) { + return; + } + + for (int32_t i = -1; i < 2; ++i) { + actual.clear(); + QueryUtils::wrapUnderlyingReader(boost::dynamic_pointer_cast(searcher), i)->search(query, c); EXPECT_TRUE(correct.equals(actual)); + } +} +void CheckHits::checkHits(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, Collection results) { + if (!MiscUtils::typeOf(searcher)) { QueryUtils::check(query, searcher); } - void CheckHits::checkDocIds(Collection results, Collection hits) - { - EXPECT_EQ(hits.size(), results.size()); - for (int32_t i = 0; i < results.size(); ++i) - EXPECT_EQ(results[i], hits[i]->doc); + Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; + Set correct = Set::newInstance(); + for (int32_t i = 0; i < results.size(); ++i) { + correct.add(results[i]); } - void CheckHits::checkHitsQuery(const QueryPtr& query, Collection hits1, Collection hits2, Collection results) - { - checkDocIds(results, hits1); - checkDocIds(results, hits2); - checkEqual(query, hits1, hits2); + Set actual = Set::newInstance(); + for (int32_t i = 0; i < hits.size(); ++i) { + actual.add(hits[i]->doc); } - void CheckHits::checkEqual(const QueryPtr& query, Collection hits1, Collection hits2) - { - double scoreTolerance = 1.0e-6; - EXPECT_EQ(hits1.size(), hits2.size()); - for (int32_t i = 0; i < hits1.size(); ++i) - { - EXPECT_EQ(hits1[i]->doc, hits2[i]->doc); - EXPECT_NEAR(hits1[i]->score, hits2[i]->score, scoreTolerance); - } + EXPECT_TRUE(correct.equals(actual)); + + QueryUtils::check(query, searcher); +} + +void CheckHits::checkDocIds(Collection results, Collection hits) { + EXPECT_EQ(hits.size(), results.size()); + for (int32_t i = 0; i < results.size(); ++i) { + EXPECT_EQ(results[i], hits[i]->doc); + } +} + +void CheckHits::checkHitsQuery(const QueryPtr& query, Collection hits1, Collection hits2, Collection results) { + checkDocIds(results, hits1); + checkDocIds(results, hits2); + checkEqual(query, hits1, hits2); +} + +void CheckHits::checkEqual(const QueryPtr& query, Collection hits1, Collection hits2) { + double scoreTolerance = 1.0e-6; + EXPECT_EQ(hits1.size(), hits2.size()); + for (int32_t i = 0; i < hits1.size(); ++i) { + EXPECT_EQ(hits1[i]->doc, hits2[i]->doc); + EXPECT_NEAR(hits1[i]->score, hits2[i]->score, scoreTolerance); } +} + +void CheckHits::checkExplanations(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, bool deep) { + searcher->search(query, newLucene(query, defaultFieldName, searcher, deep)); +} + +void CheckHits::verifyExplanation(const String& q, int32_t doc, double score, bool deep, const ExplanationPtr& expl) { + double value = expl->getValue(); + EXPECT_NEAR(score, value, EXPLAIN_SCORE_TOLERANCE_DELTA); - void CheckHits::checkExplanations(const QueryPtr& query, const String& defaultFieldName, const SearcherPtr& searcher, bool deep) - { - searcher->search(query, newLucene(query, defaultFieldName, searcher, deep)); + if (!deep) { + return; } - void CheckHits::verifyExplanation(const String& q, int32_t doc, double score, bool deep, const ExplanationPtr& expl) - { - double value = expl->getValue(); - EXPECT_NEAR(score, value, EXPLAIN_SCORE_TOLERANCE_DELTA); - - if (!deep) - return; - - Collection detail = expl->getDetails(); - if (detail) - { - if (detail.size() == 1) - { - // simple containment, no matter what the description says, just verify contained expl has same score - verifyExplanation(q, doc, score, deep, detail[0]); - } - else - { - // explanation must either: - // - end with one of: "product of:", "sum of:", "max of:", or - // - have "max plus times others" (where is float). - double x = 0; - String descr = StringUtils::toLower(expl->getDescription()); - bool productOf = boost::ends_with(descr, L"product of:"); - bool sumOf = boost::ends_with(descr, L"sum of:"); - bool maxOf = boost::ends_with(descr, L"max of:"); - bool maxTimesOthers = false; - if (!(productOf || sumOf || maxOf)) - { - // maybe 'max plus x times others' - String::size_type k1 = descr.find(L"max plus "); - if (k1 != String::npos) - { - k1 += String(L"max plus ").length(); - String::size_type k2 = descr.find(L" ", k1); - x = StringUtils::toDouble(descr.substr(k1)); - String max(descr.substr(k2)); - boost::trim(max); - if (max == L"times others of:") - maxTimesOthers = true; + Collection detail = expl->getDetails(); + if (detail) { + if (detail.size() == 1) { + // simple containment, no matter what the description says, just verify contained expl has same score + verifyExplanation(q, doc, score, deep, detail[0]); + } else { + // explanation must either: + // - end with one of: "product of:", "sum of:", "max of:", or + // - have "max plus times others" (where is float). + double x = 0; + String descr = StringUtils::toLower(expl->getDescription()); + bool productOf = boost::ends_with(descr, L"product of:"); + bool sumOf = boost::ends_with(descr, L"sum of:"); + bool maxOf = boost::ends_with(descr, L"max of:"); + bool maxTimesOthers = false; + if (!(productOf || sumOf || maxOf)) { + // maybe 'max plus x times others' + String::size_type k1 = descr.find(L"max plus "); + if (k1 != String::npos) { + k1 += String(L"max plus ").length(); + String::size_type k2 = descr.find(L" ", k1); + x = StringUtils::toDouble(descr.substr(k1)); + String max(descr.substr(k2)); + boost::trim(max); + if (max == L"times others of:") { + maxTimesOthers = true; } } - EXPECT_TRUE(productOf || sumOf || maxOf || maxTimesOthers); - double sum = 0.0; - double product = 1.0; - double max = 0.0; - for (int32_t i = 0; i < detail.size(); ++i) - { - double dval = detail[i]->getValue(); - verifyExplanation(q, doc, dval, deep, detail[i]); - product *= dval; - sum += dval; - max = std::max(max, dval); - } - double combined = 0.0; - if (productOf) - combined = product; - else if (sumOf) - combined = sum; - else if (maxOf) - combined = max; - else if (maxTimesOthers) - combined = max + x * (sum - max); - else - FAIL() << "should never get here!"; - - EXPECT_NEAR(combined, value, EXPLAIN_SCORE_TOLERANCE_DELTA); } + EXPECT_TRUE(productOf || sumOf || maxOf || maxTimesOthers); + double sum = 0.0; + double product = 1.0; + double max = 0.0; + for (int32_t i = 0; i < detail.size(); ++i) { + double dval = detail[i]->getValue(); + verifyExplanation(q, doc, dval, deep, detail[i]); + product *= dval; + sum += dval; + max = std::max(max, dval); + } + double combined = 0.0; + if (productOf) { + combined = product; + } else if (sumOf) { + combined = sum; + } else if (maxOf) { + combined = max; + } else if (maxTimesOthers) { + combined = max + x * (sum - max); + } else { + FAIL() << "should never get here!"; + } + + EXPECT_NEAR(combined, value, EXPLAIN_SCORE_TOLERANCE_DELTA); } } } + +} diff --git a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp index d9132a8a..9da220f7 100644 --- a/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/ComplexExplanationsOfNonMatchesTest.cpp @@ -25,62 +25,51 @@ using namespace Lucene; -class Qnorm1Similarity : public DefaultSimilarity -{ +class Qnorm1Similarity : public DefaultSimilarity { public: - virtual ~Qnorm1Similarity() - { + virtual ~Qnorm1Similarity() { } public: - virtual double queryNorm(double sumOfSquaredWeights) - { + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } }; -class ItemizedFilter : public FieldCacheTermsFilter -{ +class ItemizedFilter : public FieldCacheTermsFilter { public: - ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) - { + ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) - { + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - virtual ~ItemizedFilter() - { + virtual ~ItemizedFilter() { } public: - Collection int2str(Collection terms) - { + Collection int2str(Collection terms) { Collection out = Collection::newInstance(terms.size()); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { out[i] = StringUtils::toString(terms[i]); + } return out; } }; /// TestExplanations subclass that builds up super crazy complex queries on the assumption that /// if the explanations work out right for them, they should work for anything. -class ComplexExplanationsOfNonMatchesTest : public ExplanationsFixture -{ +class ComplexExplanationsOfNonMatchesTest : public ExplanationsFixture { public: - ComplexExplanationsOfNonMatchesTest() - { + ComplexExplanationsOfNonMatchesTest() { searcher->setSimilarity(createQnorm1Similarity()); } - virtual ~ComplexExplanationsOfNonMatchesTest() - { + virtual ~ComplexExplanationsOfNonMatchesTest() { } protected: - DefaultSimilarityPtr createQnorm1Similarity() - { + DefaultSimilarityPtr createQnorm1Similarity() { return newLucene(); } @@ -88,14 +77,12 @@ class ComplexExplanationsOfNonMatchesTest : public ExplanationsFixture using ExplanationsFixture::qtest; /// ignore matches and focus on non-matches - virtual void qtest(const QueryPtr& q, Collection expDocNrs) - { + virtual void qtest(const QueryPtr& q, Collection expDocNrs) { CheckHits::checkNoMatchExplanations(q, FIELD, searcher, expDocNrs); } }; -TEST_F(ComplexExplanationsOfNonMatchesTest, test1) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, test1) { BooleanQueryPtr q = newLucene(); q->add(qp->parse(L"\"w1 w2\"~1"), BooleanClause::MUST); @@ -135,8 +122,7 @@ TEST_F(ComplexExplanationsOfNonMatchesTest, test1) qtest(q, newCollection(0, 1, 2)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, test2) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, test2) { BooleanQueryPtr q = newLucene(); q->add(qp->parse(L"\"w1 w2\"~1"), BooleanClause::MUST); @@ -177,32 +163,27 @@ TEST_F(ComplexExplanationsOfNonMatchesTest, test2) qtest(q, newCollection(0, 1, 2)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testT3) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testT3) { bqtest(L"w1^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testMA3) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testMA3) { QueryPtr q = newLucene(); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testFQ5) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testFQ5) { bqtest(newLucene(qp->parse(L"xx^0"), newLucene(newCollection(1, 3))), newCollection(3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testCSQ4) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testCSQ4) { QueryPtr q = newLucene(newLucene(newCollection(3))); q->setBoost(0); bqtest(q, newCollection(3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testDMQ10) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testDMQ10) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); q->add(qp->parse(L"xx^0")); @@ -210,8 +191,7 @@ TEST_F(ComplexExplanationsOfNonMatchesTest, testDMQ10) bqtest(q, newCollection(0, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testMPQ7) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testMPQ7) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2"))); @@ -220,83 +200,70 @@ TEST_F(ComplexExplanationsOfNonMatchesTest, testMPQ7) bqtest(q, newCollection(0, 1, 2)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ12) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ12) { qtest(L"w1 w2^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ13) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ13) { qtest(L"w1 -w5^0.0", newCollection(1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ18) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ18) { qtest(L"+w1^0.0 w2", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ21) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ21) { bqtest(L"(+w1 w2)^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ22) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testBQ22) { bqtest(L"(+w1^0.0 w2)^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testST3) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testST3) { SpanQueryPtr q = st(L"w1"); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testST6) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testST6) { SpanQueryPtr q = st(L"xx"); q->setBoost(0); qtest(q, newCollection(2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testSF3) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testSF3) { SpanQueryPtr q = sf(L"w1", 1); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testSF7) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testSF7) { SpanQueryPtr q = sf(L"xx", 3); q->setBoost(0); bqtest(q, newCollection(2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot3) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot3) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot6) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot6) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot8) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot8) { SpanQueryPtr f = snear(L"w1", L"w3", 10, true); f->setBoost(0); SpanQueryPtr q = snot(f, st(L"xx")); qtest(q, newCollection(0, 1, 3)); } -TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot9) -{ +TEST_F(ComplexExplanationsOfNonMatchesTest, testSNot9) { SpanQueryPtr t = st(L"xx"); t->setBoost(0); SpanQueryPtr q = snot(snear(L"w1", L"w3", 10, true), t); diff --git a/src/test/search/ComplexExplanationsTest.cpp b/src/test/search/ComplexExplanationsTest.cpp index 924ba600..261a95b1 100644 --- a/src/test/search/ComplexExplanationsTest.cpp +++ b/src/test/search/ComplexExplanationsTest.cpp @@ -24,68 +24,56 @@ using namespace Lucene; -class Qnorm1Similarity : public DefaultSimilarity -{ +class Qnorm1Similarity : public DefaultSimilarity { public: - virtual ~Qnorm1Similarity() - { + virtual ~Qnorm1Similarity() { } public: - virtual double queryNorm(double sumOfSquaredWeights) - { + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } }; -class ItemizedFilter : public FieldCacheTermsFilter -{ +class ItemizedFilter : public FieldCacheTermsFilter { public: - ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) - { + ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) - { + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - virtual ~ItemizedFilter() - { + virtual ~ItemizedFilter() { } public: - Collection int2str(Collection terms) - { + Collection int2str(Collection terms) { Collection out = Collection::newInstance(terms.size()); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { out[i] = StringUtils::toString(terms[i]); + } return out; } }; /// TestExplanations subclass that builds up super crazy complex queries on the assumption that /// if the explanations work out right for them, they should work for anything. -class ComplexExplanationsTest : public ExplanationsFixture -{ +class ComplexExplanationsTest : public ExplanationsFixture { public: - ComplexExplanationsTest() - { + ComplexExplanationsTest() { searcher->setSimilarity(createQnorm1Similarity()); } - virtual ~ComplexExplanationsTest() - { + virtual ~ComplexExplanationsTest() { } protected: - DefaultSimilarityPtr createQnorm1Similarity() - { + DefaultSimilarityPtr createQnorm1Similarity() { return newLucene(); } }; -TEST_F(ComplexExplanationsTest, test1) -{ +TEST_F(ComplexExplanationsTest, test1) { BooleanQueryPtr q = newLucene(); q->add(qp->parse(L"\"w1 w2\"~1"), BooleanClause::MUST); @@ -125,8 +113,7 @@ TEST_F(ComplexExplanationsTest, test1) qtest(q, newCollection(0, 1, 2)); } -TEST_F(ComplexExplanationsTest, test2) -{ +TEST_F(ComplexExplanationsTest, test2) { BooleanQueryPtr q = newLucene(); q->add(qp->parse(L"\"w1 w2\"~1"), BooleanClause::MUST); @@ -167,32 +154,27 @@ TEST_F(ComplexExplanationsTest, test2) qtest(q, newCollection(0, 1, 2)); } -TEST_F(ComplexExplanationsTest, testT3) -{ +TEST_F(ComplexExplanationsTest, testT3) { bqtest(L"w1^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testMA3) -{ +TEST_F(ComplexExplanationsTest, testMA3) { QueryPtr q = newLucene(); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testFQ5) -{ +TEST_F(ComplexExplanationsTest, testFQ5) { bqtest(newLucene(qp->parse(L"xx^0"), newLucene(newCollection(1, 3))), newCollection(3)); } -TEST_F(ComplexExplanationsTest, testCSQ4) -{ +TEST_F(ComplexExplanationsTest, testCSQ4) { QueryPtr q = newLucene(newLucene(newCollection(3))); q->setBoost(0); bqtest(q, newCollection(3)); } -TEST_F(ComplexExplanationsTest, testDMQ10) -{ +TEST_F(ComplexExplanationsTest, testDMQ10) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); q->add(qp->parse(L"xx^0")); @@ -200,8 +182,7 @@ TEST_F(ComplexExplanationsTest, testDMQ10) bqtest(q, newCollection(0, 2, 3)); } -TEST_F(ComplexExplanationsTest, testMPQ7) -{ +TEST_F(ComplexExplanationsTest, testMPQ7) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2"))); @@ -210,83 +191,70 @@ TEST_F(ComplexExplanationsTest, testMPQ7) bqtest(q, newCollection(0, 1, 2)); } -TEST_F(ComplexExplanationsTest, testBQ12) -{ +TEST_F(ComplexExplanationsTest, testBQ12) { qtest(L"w1 w2^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testBQ13) -{ +TEST_F(ComplexExplanationsTest, testBQ13) { qtest(L"w1 -w5^0.0", newCollection(1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testBQ18) -{ +TEST_F(ComplexExplanationsTest, testBQ18) { qtest(L"+w1^0.0 w2", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testBQ21) -{ +TEST_F(ComplexExplanationsTest, testBQ21) { bqtest(L"(+w1 w2)^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testBQ22) -{ +TEST_F(ComplexExplanationsTest, testBQ22) { bqtest(L"(+w1^0.0 w2)^0.0", newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testST3) -{ +TEST_F(ComplexExplanationsTest, testST3) { SpanQueryPtr q = st(L"w1"); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testST6) -{ +TEST_F(ComplexExplanationsTest, testST6) { SpanQueryPtr q = st(L"xx"); q->setBoost(0); qtest(q, newCollection(2, 3)); } -TEST_F(ComplexExplanationsTest, testSF3) -{ +TEST_F(ComplexExplanationsTest, testSF3) { SpanQueryPtr q = sf(L"w1", 1); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testSF7) -{ +TEST_F(ComplexExplanationsTest, testSF7) { SpanQueryPtr q = sf(L"xx", 3); q->setBoost(0); bqtest(q, newCollection(2, 3)); } -TEST_F(ComplexExplanationsTest, testSNot3) -{ +TEST_F(ComplexExplanationsTest, testSNot3) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testSNot6) -{ +TEST_F(ComplexExplanationsTest, testSNot6) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); q->setBoost(0); bqtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(ComplexExplanationsTest, testSNot8) -{ +TEST_F(ComplexExplanationsTest, testSNot8) { SpanQueryPtr f = snear(L"w1", L"w3", 10, true); f->setBoost(0); SpanQueryPtr q = snot(f, st(L"xx")); qtest(q, newCollection(0, 1, 3)); } -TEST_F(ComplexExplanationsTest, testSNot9) -{ +TEST_F(ComplexExplanationsTest, testSNot9) { SpanQueryPtr t = st(L"xx"); t->setBoost(0); SpanQueryPtr q = snot(snear(L"w1", L"w3", 10, true), t); diff --git a/src/test/search/CustomSearcherSortTest.cpp b/src/test/search/CustomSearcherSortTest.cpp index 1f7038c8..9d8d8ef1 100644 --- a/src/test/search/CustomSearcherSortTest.cpp +++ b/src/test/search/CustomSearcherSortTest.cpp @@ -28,37 +28,31 @@ using namespace Lucene; -class CustomSearcher : public IndexSearcher -{ +class CustomSearcher : public IndexSearcher { public: - CustomSearcher(const DirectoryPtr& directory, int32_t switcher) : IndexSearcher(directory, true) - { + CustomSearcher(const DirectoryPtr& directory, int32_t switcher) : IndexSearcher(directory, true) { this->switcher = switcher; } - CustomSearcher(const IndexReaderPtr& r, int32_t switcher) : IndexSearcher(r) - { + CustomSearcher(const IndexReaderPtr& r, int32_t switcher) : IndexSearcher(r) { this->switcher = switcher; } - virtual ~CustomSearcher() - { + virtual ~CustomSearcher() { } protected: int32_t switcher; public: - virtual TopFieldDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort) - { + virtual TopFieldDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n, const SortPtr& sort) { BooleanQueryPtr bq = newLucene(); bq->add(query, BooleanClause::MUST); bq->add(newLucene(newLucene(L"mandant", StringUtils::toString(switcher))), BooleanClause::MUST); return IndexSearcher::search(bq, filter, n, sort); } - virtual TopDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n) - { + virtual TopDocsPtr search(const QueryPtr& query, const FilterPtr& filter, int32_t n) { BooleanQueryPtr bq = newLucene(); bq->add(query, BooleanClause::MUST); bq->add(newLucene(newLucene(L"mandant", StringUtils::toString(switcher))), BooleanClause::MUST); @@ -66,18 +60,15 @@ class CustomSearcher : public IndexSearcher } }; -class CustomSearcherSortTest : public LuceneTestFixture -{ +class CustomSearcherSortTest : public LuceneTestFixture { public: - CustomSearcherSortTest() - { + CustomSearcherSortTest() { random = newLucene(); index = getIndex(); query = newLucene(newLucene(L"content", L"test")); } - virtual ~CustomSearcherSortTest() - { + virtual ~CustomSearcherSortTest() { } protected: @@ -88,17 +79,17 @@ class CustomSearcherSortTest : public LuceneTestFixture static const int32_t INDEX_SIZE; public: - DirectoryPtr getIndex() - { + DirectoryPtr getIndex() { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < INDEX_SIZE; ++i) - { + for (int32_t i = 0; i < INDEX_SIZE; ++i) { DocumentPtr doc = newLucene(); - if ((i % 5) != 0) + if ((i % 5) != 0) { doc->add(newLucene(L"publicationDate_", getLuceneDate(), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - if ((i % 7) == 0) + } + if ((i % 7) == 0) { doc->add(newLucene(L"content", L"test", Field::STORE_YES, Field::INDEX_ANALYZED)); + } // every document has a defined 'mandant' field doc->add(newLucene(L"mandant", StringUtils::toString(i % 3), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); @@ -108,31 +99,29 @@ class CustomSearcherSortTest : public LuceneTestFixture return indexStore; } - String getLuceneDate() - { + String getLuceneDate() { DateTools::setDateOrder(DateTools::DATEORDER_DMY); boost::posix_time::ptime base = DateTools::parseDate(L"01/01/1980"); return DateTools::timeToString(MiscUtils::getTimeMillis(base) + random->nextInt() - INT_MIN, DateTools::RESOLUTION_DAY); } /// make sure the documents returned by the search match the expected list - void matchHits(const SearcherPtr& searcher, const SortPtr& sort) - { + void matchHits(const SearcherPtr& searcher, const SortPtr& sort) { // make a query without sorting first Collection hitsByRank = searcher->search(query, FilterPtr(), 1000)->scoreDocs; checkHits(hitsByRank); // check for duplicates Map resultMap = Map::newInstance(); // store hits in Map - Map does not allow duplicates; existing entries are silently overwritten - for (int32_t hitid = 0; hitid < hitsByRank.size(); ++hitid) + for (int32_t hitid = 0; hitid < hitsByRank.size(); ++hitid) { resultMap.put(hitsByRank[hitid]->doc, hitid); + } // now make a query using the sort criteria Collection resultSort = searcher->search (query, FilterPtr(), 1000, sort)->scoreDocs; checkHits(resultSort); // check for duplicates // besides the sorting both sets of hits must be identical - for (int32_t hitid = 0; hitid < resultSort.size(); ++hitid) - { + for (int32_t hitid = 0; hitid < resultSort.size(); ++hitid) { int32_t idHitDate = resultSort[hitid]->doc; // document ID from sorted search EXPECT_TRUE(resultMap.contains(idHitDate)); // same ID must be in the Map from the rank-sorted search // every hit must appear once in both result sets --> remove it from the Map. @@ -142,13 +131,10 @@ class CustomSearcherSortTest : public LuceneTestFixture EXPECT_TRUE(resultMap.empty()); } - void checkHits(Collection hits) - { - if (hits) - { + void checkHits(Collection hits) { + if (hits) { Map idMap = Map::newInstance(); - for (int32_t docnum = 0; docnum < hits.size(); ++docnum) - { + for (int32_t docnum = 0; docnum < hits.size(); ++docnum) { int32_t luceneId = hits[docnum]->doc; EXPECT_TRUE(!idMap.contains(luceneId)); idMap.put(luceneId, docnum); @@ -160,8 +146,7 @@ class CustomSearcherSortTest : public LuceneTestFixture const int32_t CustomSearcherSortTest::INDEX_SIZE = 2000; /// Run the test using two CustomSearcher instances. -TEST_F(CustomSearcherSortTest, testFieldSortCustomSearcher) -{ +TEST_F(CustomSearcherSortTest, testFieldSortCustomSearcher) { SortPtr custSort = newLucene(newCollection(newLucene(L"publicationDate_", SortField::STRING), SortField::FIELD_SCORE())); SearcherPtr searcher = newLucene(index, 2); // search and check hits @@ -169,8 +154,7 @@ TEST_F(CustomSearcherSortTest, testFieldSortCustomSearcher) } /// Run the test using one CustomSearcher wrapped by a MultiSearcher. -TEST_F(CustomSearcherSortTest, testFieldSortSingleSearcher) -{ +TEST_F(CustomSearcherSortTest, testFieldSortSingleSearcher) { SortPtr custSort = newLucene(newCollection(newLucene(L"publicationDate_", SortField::STRING), SortField::FIELD_SCORE())); SearcherPtr searcher = newLucene(newCollection(newLucene(index, 2))); // search and check hits @@ -178,8 +162,7 @@ TEST_F(CustomSearcherSortTest, testFieldSortSingleSearcher) } /// Run the test using two CustomSearcher instances. -TEST_F(CustomSearcherSortTest, testFieldSortMultiCustomSearcher) -{ +TEST_F(CustomSearcherSortTest, testFieldSortMultiCustomSearcher) { SortPtr custSort = newLucene(newCollection(newLucene(L"publicationDate_", SortField::STRING), SortField::FIELD_SCORE())); SearcherPtr searcher = newLucene(newCollection(newLucene(index, 0), newLucene(index, 2))); // search and check hits diff --git a/src/test/search/DateFilterTest.cpp b/src/test/search/DateFilterTest.cpp index 139c066f..64a40043 100644 --- a/src/test/search/DateFilterTest.cpp +++ b/src/test/search/DateFilterTest.cpp @@ -24,8 +24,7 @@ using namespace Lucene; typedef LuceneTestFixture DateFilterTest; -TEST_F(DateFilterTest, testBefore) -{ +TEST_F(DateFilterTest, testBefore) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -43,10 +42,10 @@ TEST_F(DateFilterTest, testBefore) // filter that should preserve matches TermRangeFilterPtr df1 = newLucene(L"datefield", DateTools::timeToString(now - 2000, DateTools::RESOLUTION_MILLISECOND), - DateTools::timeToString(now, DateTools::RESOLUTION_MILLISECOND), false, true); + DateTools::timeToString(now, DateTools::RESOLUTION_MILLISECOND), false, true); // filter that should discard matches TermRangeFilterPtr df2 = newLucene(L"datefield", DateTools::timeToString(0, DateTools::RESOLUTION_MILLISECOND), - DateTools::timeToString(now - 2000, DateTools::RESOLUTION_MILLISECOND), true, false); + DateTools::timeToString(now - 2000, DateTools::RESOLUTION_MILLISECOND), true, false); // search something that doesn't exist with DateFilter QueryPtr query1 = newLucene(newLucene(L"body", L"NoMatchForThis")); @@ -75,8 +74,7 @@ TEST_F(DateFilterTest, testBefore) EXPECT_EQ(0, result.size()); } -TEST_F(DateFilterTest, testAfter) -{ +TEST_F(DateFilterTest, testAfter) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -94,10 +92,10 @@ TEST_F(DateFilterTest, testAfter) // filter that should preserve matches TermRangeFilterPtr df1 = newLucene(L"datefield", DateTools::timeToString(now, DateTools::RESOLUTION_MILLISECOND), - DateTools::timeToString(now + 999999, DateTools::RESOLUTION_MILLISECOND), true, false); + DateTools::timeToString(now + 999999, DateTools::RESOLUTION_MILLISECOND), true, false); // filter that should discard matches TermRangeFilterPtr df2 = newLucene(L"datefield", DateTools::timeToString(now + 999999, DateTools::RESOLUTION_MILLISECOND), - DateTools::timeToString(now + 999999999, DateTools::RESOLUTION_MILLISECOND), false, true); + DateTools::timeToString(now + 999999999, DateTools::RESOLUTION_MILLISECOND), false, true); // search something that doesn't exist with DateFilter QueryPtr query1 = newLucene(newLucene(L"body", L"NoMatchForThis")); diff --git a/src/test/search/DateSortTest.cpp b/src/test/search/DateSortTest.cpp index 5346c4e1..0c0094dd 100644 --- a/src/test/search/DateSortTest.cpp +++ b/src/test/search/DateSortTest.cpp @@ -22,11 +22,9 @@ using namespace Lucene; -class DateSortTest : public LuceneTestFixture -{ +class DateSortTest : public LuceneTestFixture { public: - DateSortTest() - { + DateSortTest() { // Create an index writer. directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -48,8 +46,7 @@ class DateSortTest : public LuceneTestFixture writer->close(); } - virtual ~DateSortTest() - { + virtual ~DateSortTest() { } protected: @@ -59,8 +56,7 @@ class DateSortTest : public LuceneTestFixture DirectoryPtr directory; public: - DocumentPtr createDocument(const String& text, int64_t time) - { + DocumentPtr createDocument(const String& text, int64_t time) { DocumentPtr document = newLucene(); // Add the text field. @@ -79,8 +75,7 @@ class DateSortTest : public LuceneTestFixture const String DateSortTest::TEXT_FIELD = L"text"; const String DateSortTest::DATE_TIME_FIELD = L"dateTime"; -TEST_F(DateSortTest, testReverseDateSort) -{ +TEST_F(DateSortTest, testReverseDateSort) { IndexSearcherPtr searcher = newLucene(directory, true); SortPtr sort = newLucene(newLucene(DATE_TIME_FIELD, SortField::STRING, true)); @@ -91,8 +86,7 @@ TEST_F(DateSortTest, testReverseDateSort) // Execute the search and process the search results. Collection actualOrder = Collection::newInstance(5); Collectionhits = searcher->search(query, FilterPtr(), 1000, sort)->scoreDocs; - for (int32_t i = 0; i < hits.size(); ++i) - { + for (int32_t i = 0; i < hits.size(); ++i) { DocumentPtr document = searcher->doc(hits[i]->doc); String text = document->get(TEXT_FIELD); actualOrder[i] = text; diff --git a/src/test/search/DisjunctionMaxQueryTest.cpp b/src/test/search/DisjunctionMaxQueryTest.cpp index a781a754..c0310ffd 100644 --- a/src/test/search/DisjunctionMaxQueryTest.cpp +++ b/src/test/search/DisjunctionMaxQueryTest.cpp @@ -28,38 +28,32 @@ using namespace Lucene; /// Similarity to eliminate tf, idf and lengthNorm effects to isolate test case. -class DisjunctionMaxSimilarity : public DefaultSimilarity -{ +class DisjunctionMaxSimilarity : public DefaultSimilarity { public: - virtual ~DisjunctionMaxSimilarity() - { + virtual ~DisjunctionMaxSimilarity() { } public: - virtual double tf(double freq) - { - if (freq > 0.0) + virtual double tf(double freq) { + if (freq > 0.0) { return 1.0; - else + } else { return 0.0; + } } - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - virtual double idf(int32_t docFreq, int32_t numDocs) - { + virtual double idf(int32_t docFreq, int32_t numDocs) { return 1.0; } }; -class DisjunctionMaxQueryTest : public LuceneTestFixture -{ +class DisjunctionMaxQueryTest : public LuceneTestFixture { public: - DisjunctionMaxQueryTest() - { + DisjunctionMaxQueryTest() { sim = newLucene(); index = newLucene(); @@ -113,8 +107,7 @@ class DisjunctionMaxQueryTest : public LuceneTestFixture s->setSimilarity(sim); } - virtual ~DisjunctionMaxQueryTest() - { + virtual ~DisjunctionMaxQueryTest() { } public: @@ -126,13 +119,11 @@ class DisjunctionMaxQueryTest : public LuceneTestFixture static const double SCORE_COMP_THRESH; protected: - QueryPtr tq(const String& f, const String& t) - { + QueryPtr tq(const String& f, const String& t) { return newLucene(newLucene(f, t)); } - QueryPtr tq(const String& f, const String& t, double b) - { + QueryPtr tq(const String& f, const String& t, double b) { QueryPtr q = tq(f, t); q->setBoost(b); return q; @@ -141,8 +132,7 @@ class DisjunctionMaxQueryTest : public LuceneTestFixture const double DisjunctionMaxQueryTest::SCORE_COMP_THRESH = 0.00001; -TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeMiss) -{ +TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeMiss) { DisjunctionMaxQueryPtr dq = newLucene(0.0); dq->add(tq(L"id", L"d1")); dq->add(tq(L"dek", L"DOES_NOT_EXIST")); @@ -154,8 +144,7 @@ TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeMiss) EXPECT_EQ(ds->advance(3), DocIdSetIterator::NO_MORE_DOCS); } -TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeHit) -{ +TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeHit) { DisjunctionMaxQueryPtr dq = newLucene(0.0); dq->add(tq(L"dek", L"albino")); dq->add(tq(L"dek", L"DOES_NOT_EXIST")); @@ -168,8 +157,7 @@ TEST_F(DisjunctionMaxQueryTest, testSkipToFirsttimeHit) EXPECT_EQ(L"d4", r->document(ds->docID())->get(L"id")); } -TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores1) -{ +TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores1) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(tq(L"hed", L"albino")); q->add(tq(L"hed", L"elephant")); @@ -180,12 +168,12 @@ TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores1) EXPECT_EQ(4, h.size()); double score = h[0]->score; - for (int32_t i = 1; i < h.size(); ++i) + for (int32_t i = 1; i < h.size(); ++i) { EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); + } } -TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores2) -{ +TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores2) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(tq(L"dek", L"albino")); q->add(tq(L"dek", L"elephant")); @@ -196,12 +184,12 @@ TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores2) EXPECT_EQ(3, h.size()); double score = h[0]->score; - for (int32_t i = 1; i < h.size(); ++i) + for (int32_t i = 1; i < h.size(); ++i) { EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); + } } -TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores3) -{ +TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores3) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(tq(L"hed", L"albino")); q->add(tq(L"hed", L"elephant")); @@ -214,12 +202,12 @@ TEST_F(DisjunctionMaxQueryTest, testSimpleEqualScores3) EXPECT_EQ(4, h.size()); double score = h[0]->score; - for (int32_t i = 1; i < h.size(); ++i) + for (int32_t i = 1; i < h.size(); ++i) { EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); + } } -TEST_F(DisjunctionMaxQueryTest, testSimpleTiebreaker) -{ +TEST_F(DisjunctionMaxQueryTest, testSimpleTiebreaker) { DisjunctionMaxQueryPtr q = newLucene(0.01); q->add(tq(L"dek", L"albino")); q->add(tq(L"dek", L"elephant")); @@ -236,8 +224,7 @@ TEST_F(DisjunctionMaxQueryTest, testSimpleTiebreaker) EXPECT_NEAR(score1, score2, SCORE_COMP_THRESH); } -TEST_F(DisjunctionMaxQueryTest, testBooleanRequiredEqualScores) -{ +TEST_F(DisjunctionMaxQueryTest, testBooleanRequiredEqualScores) { BooleanQueryPtr q = newLucene(); { DisjunctionMaxQueryPtr q1 = newLucene(0.0); @@ -259,12 +246,12 @@ TEST_F(DisjunctionMaxQueryTest, testBooleanRequiredEqualScores) Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(3, h.size()); double score = h[0]->score; - for (int32_t i = 1; i < h.size(); ++i) + for (int32_t i = 1; i < h.size(); ++i) { EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); + } } -TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalNoTiebreaker) -{ +TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalNoTiebreaker) { BooleanQueryPtr q = newLucene(); { DisjunctionMaxQueryPtr q1 = newLucene(0.0); @@ -284,15 +271,15 @@ TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalNoTiebreaker) Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(4, h.size()); double score = h[0]->score; - for (int32_t i = 1; i < h.size() - 1; ++i) + for (int32_t i = 1; i < h.size() - 1; ++i) { EXPECT_NEAR(score, h[i]->score, SCORE_COMP_THRESH); + } EXPECT_EQ(L"d1", s->doc(h[h.size() - 1]->doc)->get(L"id")); double score1 = h[h.size() - 1]->score; EXPECT_TRUE(score > score1); } -TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalWithTiebreaker) -{ +TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalWithTiebreaker) { BooleanQueryPtr q = newLucene(); { DisjunctionMaxQueryPtr q1 = newLucene(0.01); @@ -332,8 +319,7 @@ TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalWithTiebreaker) EXPECT_TRUE(score2 > score3); } -TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalWithTiebreakerAndBoost) -{ +TEST_F(DisjunctionMaxQueryTest, testBooleanOptionalWithTiebreakerAndBoost) { BooleanQueryPtr q = newLucene(); { DisjunctionMaxQueryPtr q1 = newLucene(0.01); diff --git a/src/test/search/DocBoostTest.cpp b/src/test/search/DocBoostTest.cpp index 6833dc04..b3bf4774 100644 --- a/src/test/search/DocBoostTest.cpp +++ b/src/test/search/DocBoostTest.cpp @@ -21,51 +21,44 @@ using namespace Lucene; typedef LuceneTestFixture DocBoostTest; -namespace TestDocBoost -{ - class BoostCollector : public Collector - { - public: - BoostCollector(Collection scores) - { - this->scores = scores; - this->base = 0; - } - - virtual ~BoostCollector() - { - } - - public: - Collection scores; - int32_t base; - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - scores[doc + base] = scorer->score(); - } - - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - base = docBase; - } - - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; +namespace TestDocBoost { + +class BoostCollector : public Collector { +public: + BoostCollector(Collection scores) { + this->scores = scores; + this->base = 0; + } + + virtual ~BoostCollector() { + } + +public: + Collection scores; + int32_t base; + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + scores[doc + base] = scorer->score(); + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + base = docBase; + } + + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; + } -TEST_F(DocBoostTest, testDocBoost) -{ +TEST_F(DocBoostTest, testDocBoost) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -97,8 +90,7 @@ TEST_F(DocBoostTest, testDocBoost) searcher->search(newLucene(newLucene(L"field", L"word")), newLucene(scores)); double lastScore = 0.0; - for (int32_t i = 0; i < 4; ++i) - { + for (int32_t i = 0; i < 4; ++i) { EXPECT_TRUE(scores[i] > lastScore); lastScore = scores[i]; } diff --git a/src/test/search/DocIdSetTest.cpp b/src/test/search/DocIdSetTest.cpp index 10766ee4..27b423ac 100644 --- a/src/test/search/DocIdSetTest.cpp +++ b/src/test/search/DocIdSetTest.cpp @@ -25,115 +25,98 @@ typedef LuceneTestFixture DocIdSetTest; static const int32_t maxdoc = 10; -namespace TestFilteredDocIdSet -{ - class TestDocIdSetIterator : public DocIdSetIterator - { - public: - TestDocIdSetIterator() - { - docid = -1; - } +namespace TestFilteredDocIdSet { - virtual ~TestDocIdSetIterator() - { - } +class TestDocIdSetIterator : public DocIdSetIterator { +public: + TestDocIdSetIterator() { + docid = -1; + } - public: - int32_t docid; + virtual ~TestDocIdSetIterator() { + } - public: - virtual int32_t docID() - { - return docid; - } +public: + int32_t docid; - virtual int32_t nextDoc() - { - return ++docid < maxdoc ? docid : (docid = NO_MORE_DOCS); - } +public: + virtual int32_t docID() { + return docid; + } - virtual int32_t advance(int32_t target) - { - while (nextDoc() < target) - { - } - return docid; - } - }; + virtual int32_t nextDoc() { + return ++docid < maxdoc ? docid : (docid = NO_MORE_DOCS); + } - class TestDocIdSet : public DocIdSet - { - public: - virtual ~TestDocIdSet() - { + virtual int32_t advance(int32_t target) { + while (nextDoc() < target) { } + return docid; + } +}; - public: - virtual DocIdSetIteratorPtr iterator() - { - return newLucene(); - } - }; +class TestDocIdSet : public DocIdSet { +public: + virtual ~TestDocIdSet() { + } - class TestFilteredDocIdSet : public FilteredDocIdSet - { - public: - TestFilteredDocIdSet(const DocIdSetPtr& innerSet) : FilteredDocIdSet(innerSet) - { - } +public: + virtual DocIdSetIteratorPtr iterator() { + return newLucene(); + } +}; - virtual ~TestFilteredDocIdSet() - { - } +class TestFilteredDocIdSet : public FilteredDocIdSet { +public: + TestFilteredDocIdSet(const DocIdSetPtr& innerSet) : FilteredDocIdSet(innerSet) { + } + + virtual ~TestFilteredDocIdSet() { + } + +protected: + virtual bool match(int32_t docid) { + return (docid % 2 == 0); // validate only even docids + } +}; - protected: - virtual bool match(int32_t docid) - { - return (docid % 2 == 0); // validate only even docids - } - }; } -TEST_F(DocIdSetTest, testFilteredDocIdSet) -{ +TEST_F(DocIdSetTest, testFilteredDocIdSet) { DocIdSetPtr innerSet = newLucene(); DocIdSetPtr filteredSet = newLucene(innerSet); DocIdSetIteratorPtr iter = filteredSet->iterator(); Collection docs = Collection::newInstance(); int32_t doc = iter->advance(3); - if (doc != DocIdSetIterator::NO_MORE_DOCS) - { + if (doc != DocIdSetIterator::NO_MORE_DOCS) { docs.add(doc); - while((doc = iter->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) + while ((doc = iter->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) { docs.add(doc); + } } Collection answer = newCollection(4, 6, 8); EXPECT_TRUE(docs.equals(answer)); } -namespace TestNullDocIdSet -{ - class TestFilter : public Filter - { - public: - virtual ~TestFilter() - { - } +namespace TestNullDocIdSet { + +class TestFilter : public Filter { +public: + virtual ~TestFilter() { + } + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { + return DocIdSetPtr(); + } +}; - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { - return DocIdSetPtr(); - } - }; } /// Tests that if a Filter produces a null DocIdSet, which is given to IndexSearcher, everything works fine -TEST_F(DocIdSetTest, testNullDocIdSet) -{ +TEST_F(DocIdSetTest, testNullDocIdSet) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); DocumentPtr doc = newLucene(); diff --git a/src/test/search/ElevationComparatorTest.cpp b/src/test/search/ElevationComparatorTest.cpp index 04894356..4279fd40 100644 --- a/src/test/search/ElevationComparatorTest.cpp +++ b/src/test/search/ElevationComparatorTest.cpp @@ -28,19 +28,16 @@ using namespace Lucene; -class ElevationFieldComparator : public FieldComparator -{ +class ElevationFieldComparator : public FieldComparator { public: - ElevationFieldComparator(MapStringInt priority, const String& fieldname, int32_t numHits) - { + ElevationFieldComparator(MapStringInt priority, const String& fieldname, int32_t numHits) { this->priority = priority; this->fieldname = fieldname; this->values = Collection::newInstance(numHits); this->bottomVal = 0; } - virtual ~ElevationFieldComparator() - { + virtual ~ElevationFieldComparator() { } public: @@ -51,92 +48,77 @@ class ElevationFieldComparator : public FieldComparator int32_t bottomVal; public: - virtual int32_t compare(int32_t slot1, int32_t slot2) - { + virtual int32_t compare(int32_t slot1, int32_t slot2) { return values[slot2] - values[slot1]; // values will be small enough that there is no overflow concern } - virtual void setBottom(int32_t slot) - { + virtual void setBottom(int32_t slot) { bottomVal = values[slot]; } - virtual int32_t compareBottom(int32_t doc) - { + virtual int32_t compareBottom(int32_t doc) { return docVal(doc) - bottomVal; } - virtual void copy(int32_t slot, int32_t doc) - { + virtual void copy(int32_t slot, int32_t doc) { values[slot] = docVal(doc); } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { idIndex = FieldCache::DEFAULT()->getStringIndex(reader, fieldname); } - virtual ComparableValue value(int32_t slot) - { + virtual ComparableValue value(int32_t slot) { return values[slot]; } protected: - int32_t docVal(int32_t doc) - { + int32_t docVal(int32_t doc) { String id = idIndex->lookup[idIndex->order[doc]]; return priority.contains(id) ? priority.get(id) : 0; } }; -class ElevationComparatorSource : public FieldComparatorSource -{ +class ElevationComparatorSource : public FieldComparatorSource { public: - ElevationComparatorSource(MapStringInt priority) - { + ElevationComparatorSource(MapStringInt priority) { this->priority = priority; } - virtual ~ElevationComparatorSource() - { + virtual ~ElevationComparatorSource() { } protected: MapStringInt priority; public: - virtual FieldComparatorPtr newComparator(const String& fieldname, int32_t numHits, int32_t sortPos, bool reversed) - { + virtual FieldComparatorPtr newComparator(const String& fieldname, int32_t numHits, int32_t sortPos, bool reversed) { return newLucene(priority, fieldname, numHits); } }; -class ElevationComparatorTest : public LuceneTestFixture -{ +class ElevationComparatorTest : public LuceneTestFixture { public: - ElevationComparatorTest() - { + ElevationComparatorTest() { priority = MapStringInt::newInstance(); } - virtual ~ElevationComparatorTest() - { + virtual ~ElevationComparatorTest() { } public: MapStringInt priority; public: - DocumentPtr adoc(Collection vals) - { + DocumentPtr adoc(Collection vals) { DocumentPtr doc = newLucene(); - for (int32_t i = 0; i < vals.size() - 2; i += 2) + for (int32_t i = 0; i < vals.size() - 2; i += 2) { doc->add(newLucene(vals[i], vals[i + 1], Field::STORE_YES, Field::INDEX_ANALYZED)); + } return doc; } - void runTest(const IndexSearcherPtr& searcher, bool reversed) - { + void runTest(const IndexSearcherPtr& searcher, bool reversed) { BooleanQueryPtr newq = newLucene(false); TermQueryPtr query = newLucene(newLucene(L"title", L"ipod")); @@ -144,9 +126,9 @@ class ElevationComparatorTest : public LuceneTestFixture newq->add(getElevatedQuery(newCollection(L"id", L"a", L"id", L"x")), BooleanClause::SHOULD); SortPtr sort = newLucene(newCollection( - newLucene(L"id", newLucene(priority), false), - newLucene(L"", SortField::SCORE, reversed) - )); + newLucene(L"id", newLucene(priority), false), + newLucene(L"", SortField::SCORE, reversed) + )); TopDocsCollectorPtr topCollector = TopFieldCollector::create(sort, 50, false, true, true, true); searcher->search(newq, FilterPtr(), topCollector); @@ -160,25 +142,20 @@ class ElevationComparatorTest : public LuceneTestFixture EXPECT_EQ(0, topDocs->scoreDocs[0]->doc); EXPECT_EQ(3, topDocs->scoreDocs[1]->doc); - if (reversed) - { + if (reversed) { EXPECT_EQ(2, topDocs->scoreDocs[2]->doc); EXPECT_EQ(1, topDocs->scoreDocs[3]->doc); - } - else - { + } else { EXPECT_EQ(1, topDocs->scoreDocs[2]->doc); EXPECT_EQ(2, topDocs->scoreDocs[3]->doc); } } - QueryPtr getElevatedQuery(Collection vals) - { + QueryPtr getElevatedQuery(Collection vals) { BooleanQueryPtr q = newLucene(false); q->setBoost(0); int32_t max = (vals.size() / 2) + 5; - for (int32_t i = 0; i < vals.size() - 1; i += 2) - { + for (int32_t i = 0; i < vals.size() - 1; i += 2) { q->add(newLucene(newLucene(vals[i], vals[i + 1])), BooleanClause::SHOULD); priority.put(vals[i + 1], max--); } @@ -186,8 +163,7 @@ class ElevationComparatorTest : public LuceneTestFixture } }; -TEST_F(ElevationComparatorTest, testSorting) -{ +TEST_F(ElevationComparatorTest, testSorting) { DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); diff --git a/src/test/search/ExplanationsFixture.cpp b/src/test/search/ExplanationsFixture.cpp index 64b98450..28238a48 100644 --- a/src/test/search/ExplanationsFixture.cpp +++ b/src/test/search/ExplanationsFixture.cpp @@ -23,147 +23,125 @@ #include "BooleanQuery.h" #include "TermQuery.h" -namespace Lucene -{ - const String ExplanationsFixture::KEY = L"KEY"; - const String ExplanationsFixture::FIELD = L"field"; - - ExplanationsFixture::ExplanationsFixture() - { - qp = newLucene(LuceneVersion::LUCENE_CURRENT, FIELD, newLucene()); - docFields = newCollection(L"w1 w2 w3 w4 w5", L"w1 w3 w2 w3 zz", L"w1 xx w2 yy w3", L"w1 w3 xx w2 yy w3 zz"); - - RAMDirectoryPtr directory = newLucene(); - IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - - for (int32_t i = 0; i < docFields.size(); ++i) - { - DocumentPtr doc = newLucene(); - doc->add(newLucene(KEY, StringUtils::toString(i), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - doc->add(newLucene(FIELD, docFields[i], Field::STORE_NO, Field::INDEX_ANALYZED)); - writer->addDocument(doc); - } - writer->close(); - searcher = newLucene(directory, true); - } +namespace Lucene { - ExplanationsFixture::~ExplanationsFixture() - { - searcher->close(); - } +const String ExplanationsFixture::KEY = L"KEY"; +const String ExplanationsFixture::FIELD = L"field"; - SpanTermQueryPtr ExplanationsFixture::st(const String& s) - { - return newLucene(newLucene(FIELD, s)); - } +ExplanationsFixture::ExplanationsFixture() { + qp = newLucene(LuceneVersion::LUCENE_CURRENT, FIELD, newLucene()); + docFields = newCollection(L"w1 w2 w3 w4 w5", L"w1 w3 w2 w3 zz", L"w1 xx w2 yy w3", L"w1 w3 xx w2 yy w3 zz"); - SpanFirstQueryPtr ExplanationsFixture::sf(const String& s, int32_t b) - { - return newLucene(st(s), b); - } + RAMDirectoryPtr directory = newLucene(); + IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - SpanNotQueryPtr ExplanationsFixture::snot(const SpanQueryPtr& i, const SpanQueryPtr& e) - { - return newLucene(i, e); + for (int32_t i = 0; i < docFields.size(); ++i) { + DocumentPtr doc = newLucene(); + doc->add(newLucene(KEY, StringUtils::toString(i), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); + doc->add(newLucene(FIELD, docFields[i], Field::STORE_NO, Field::INDEX_ANALYZED)); + writer->addDocument(doc); } + writer->close(); + searcher = newLucene(directory, true); +} - SpanOrQueryPtr ExplanationsFixture::sor(const String& s, const String& e) - { - return sor(st(s), st(e)); - } +ExplanationsFixture::~ExplanationsFixture() { + searcher->close(); +} - SpanOrQueryPtr ExplanationsFixture::sor(const SpanQueryPtr& s, const SpanQueryPtr& e) - { - return newLucene(newCollection(s, e)); - } +SpanTermQueryPtr ExplanationsFixture::st(const String& s) { + return newLucene(newLucene(FIELD, s)); +} - SpanOrQueryPtr ExplanationsFixture::sor(const String& s, const String& m, const String& e) - { - return sor(st(s), st(m), st(e)); - } +SpanFirstQueryPtr ExplanationsFixture::sf(const String& s, int32_t b) { + return newLucene(st(s), b); +} - SpanOrQueryPtr ExplanationsFixture::sor(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e) - { - return newLucene(newCollection(s, m, e)); - } +SpanNotQueryPtr ExplanationsFixture::snot(const SpanQueryPtr& i, const SpanQueryPtr& e) { + return newLucene(i, e); +} - SpanNearQueryPtr ExplanationsFixture::snear(const String& s, const String& e, int32_t slop, bool inOrder) - { - return snear(st(s), st(e), slop, inOrder); - } +SpanOrQueryPtr ExplanationsFixture::sor(const String& s, const String& e) { + return sor(st(s), st(e)); +} - SpanNearQueryPtr ExplanationsFixture::snear(const SpanQueryPtr& s, const SpanQueryPtr& e, int32_t slop, bool inOrder) - { - return newLucene(newCollection(s, e), slop, inOrder); - } +SpanOrQueryPtr ExplanationsFixture::sor(const SpanQueryPtr& s, const SpanQueryPtr& e) { + return newLucene(newCollection(s, e)); +} - SpanNearQueryPtr ExplanationsFixture::snear(const String& s, const String& m, const String& e, int32_t slop, bool inOrder) - { - return snear(st(s), st(m), st(e), slop, inOrder); - } +SpanOrQueryPtr ExplanationsFixture::sor(const String& s, const String& m, const String& e) { + return sor(st(s), st(m), st(e)); +} - SpanNearQueryPtr ExplanationsFixture::snear(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e, int32_t slop, bool inOrder) - { - return newLucene(newCollection(s, m, e), slop, inOrder); - } +SpanOrQueryPtr ExplanationsFixture::sor(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e) { + return newLucene(newCollection(s, m, e)); +} - QueryPtr ExplanationsFixture::optB(const String& q) - { - return optB(makeQuery(q)); - } +SpanNearQueryPtr ExplanationsFixture::snear(const String& s, const String& e, int32_t slop, bool inOrder) { + return snear(st(s), st(e), slop, inOrder); +} - QueryPtr ExplanationsFixture::optB(const QueryPtr& q) - { - BooleanQueryPtr bq = newLucene(true); - bq->add(q, BooleanClause::SHOULD); - bq->add(newLucene(newLucene(L"NEVER", L"MATCH")), BooleanClause::MUST_NOT); - return bq; - } +SpanNearQueryPtr ExplanationsFixture::snear(const SpanQueryPtr& s, const SpanQueryPtr& e, int32_t slop, bool inOrder) { + return newLucene(newCollection(s, e), slop, inOrder); +} - QueryPtr ExplanationsFixture::reqB(const String& q) - { - return reqB(makeQuery(q)); - } +SpanNearQueryPtr ExplanationsFixture::snear(const String& s, const String& m, const String& e, int32_t slop, bool inOrder) { + return snear(st(s), st(m), st(e), slop, inOrder); +} - QueryPtr ExplanationsFixture::reqB(const QueryPtr& q) - { - BooleanQueryPtr bq = newLucene(true); - bq->add(q, BooleanClause::MUST); - bq->add(newLucene(newLucene(FIELD, L"w1")), BooleanClause::SHOULD); - return bq; - } +SpanNearQueryPtr ExplanationsFixture::snear(const SpanQueryPtr& s, const SpanQueryPtr& m, const SpanQueryPtr& e, int32_t slop, bool inOrder) { + return newLucene(newCollection(s, m, e), slop, inOrder); +} - Collection ExplanationsFixture::ta(Collection s) - { - Collection t = Collection::newInstance(s.size()); - for (int32_t i = 0; i < s.size(); ++i) - t[i] = newLucene(FIELD, s[i]); - return t; - } +QueryPtr ExplanationsFixture::optB(const String& q) { + return optB(makeQuery(q)); +} - void ExplanationsFixture::qtest(const String& queryText, Collection expDocNrs) - { - qtest(makeQuery(queryText), expDocNrs); - } +QueryPtr ExplanationsFixture::optB(const QueryPtr& q) { + BooleanQueryPtr bq = newLucene(true); + bq->add(q, BooleanClause::SHOULD); + bq->add(newLucene(newLucene(L"NEVER", L"MATCH")), BooleanClause::MUST_NOT); + return bq; +} - void ExplanationsFixture::qtest(const QueryPtr& q, Collection expDocNrs) - { - CheckHits::checkHitCollector(q, FIELD, searcher, expDocNrs); - } +QueryPtr ExplanationsFixture::reqB(const String& q) { + return reqB(makeQuery(q)); +} - void ExplanationsFixture::bqtest(const QueryPtr& q, Collection expDocNrs) - { - qtest(reqB(q), expDocNrs); - qtest(optB(q), expDocNrs); - } +QueryPtr ExplanationsFixture::reqB(const QueryPtr& q) { + BooleanQueryPtr bq = newLucene(true); + bq->add(q, BooleanClause::MUST); + bq->add(newLucene(newLucene(FIELD, L"w1")), BooleanClause::SHOULD); + return bq; +} - void ExplanationsFixture::bqtest(const String& queryText, Collection expDocNrs) - { - bqtest(makeQuery(queryText), expDocNrs); +Collection ExplanationsFixture::ta(Collection s) { + Collection t = Collection::newInstance(s.size()); + for (int32_t i = 0; i < s.size(); ++i) { + t[i] = newLucene(FIELD, s[i]); } + return t; +} + +void ExplanationsFixture::qtest(const String& queryText, Collection expDocNrs) { + qtest(makeQuery(queryText), expDocNrs); +} + +void ExplanationsFixture::qtest(const QueryPtr& q, Collection expDocNrs) { + CheckHits::checkHitCollector(q, FIELD, searcher, expDocNrs); +} + +void ExplanationsFixture::bqtest(const QueryPtr& q, Collection expDocNrs) { + qtest(reqB(q), expDocNrs); + qtest(optB(q), expDocNrs); +} + +void ExplanationsFixture::bqtest(const String& queryText, Collection expDocNrs) { + bqtest(makeQuery(queryText), expDocNrs); +} + +QueryPtr ExplanationsFixture::makeQuery(const String& queryText) { + return qp->parse(queryText); +} - QueryPtr ExplanationsFixture::makeQuery(const String& queryText) - { - return qp->parse(queryText); - } } diff --git a/src/test/search/FieldCacheRangeFilterTest.cpp b/src/test/search/FieldCacheRangeFilterTest.cpp index 38233c36..d7fcd68c 100644 --- a/src/test/search/FieldCacheRangeFilterTest.cpp +++ b/src/test/search/FieldCacheRangeFilterTest.cpp @@ -26,8 +26,7 @@ using namespace Lucene; /// A basic 'positive' Unit test class for the FieldCacheRangeFilter class. typedef BaseTestRangeFilterFixture FieldCacheRangeFilterTest; -TEST_F(FieldCacheRangeFilterTest, testRangeFilterId) -{ +TEST_F(FieldCacheRangeFilterTest, testRangeFilterId) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -111,8 +110,7 @@ TEST_F(FieldCacheRangeFilterTest, testRangeFilterId) EXPECT_EQ(1, result.size()); } -TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterRand) -{ +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterRand) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -176,8 +174,7 @@ TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterRand) EXPECT_EQ(1, result.size()); } -TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterInts) -{ +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterInts) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -258,8 +255,7 @@ TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterInts) EXPECT_EQ(1, result.size()); } -TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterLongs) -{ +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterLongs) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -340,8 +336,7 @@ TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterLongs) EXPECT_EQ(1, result.size()); } -TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterDoubles) -{ +TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterDoubles) { IndexReaderPtr reader = IndexReader::open((DirectoryPtr)signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -366,13 +361,11 @@ TEST_F(FieldCacheRangeFilterTest, testFieldCacheRangeFilterDoubles) EXPECT_EQ(0, result.size()); } -TEST_F(FieldCacheRangeFilterTest, testSparseIndex) -{ +TEST_F(FieldCacheRangeFilterTest, testSparseIndex) { RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t d = -20; d <= 20; ++d) - { + for (int32_t d = -20; d <= 20; ++d) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(d), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"body", L"body", Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); diff --git a/src/test/search/FieldCacheTermsFilterTest.cpp b/src/test/search/FieldCacheTermsFilterTest.cpp index af793c98..8bd04f9d 100644 --- a/src/test/search/FieldCacheTermsFilterTest.cpp +++ b/src/test/search/FieldCacheTermsFilterTest.cpp @@ -22,13 +22,11 @@ using namespace Lucene; typedef LuceneTestFixture FieldCacheTermsFilterTest; -TEST_F(FieldCacheTermsFilterTest, testMissingTerms) -{ +TEST_F(FieldCacheTermsFilterTest, testMissingTerms) { String fieldName = L"field1"; MockRAMDirectoryPtr rd = newLucene(); IndexWriterPtr w = newLucene(rd, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { DocumentPtr doc = newLucene(); int32_t term = i * 10; // terms are units of 10 doc->add(newLucene(fieldName, StringUtils::toString(term), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); diff --git a/src/test/search/FieldCacheTest.cpp b/src/test/search/FieldCacheTest.cpp index 2418642c..2d1478e2 100644 --- a/src/test/search/FieldCacheTest.cpp +++ b/src/test/search/FieldCacheTest.cpp @@ -17,19 +17,16 @@ using namespace Lucene; -class FieldCacheTest : public LuceneTestFixture -{ +class FieldCacheTest : public LuceneTestFixture { public: - FieldCacheTest() - { + FieldCacheTest() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); int64_t theLong = LLONG_MAX; double theDouble = DBL_MAX; uint8_t theByte = UCHAR_MAX; int32_t theInt = INT_MAX; - for (int32_t i = 0; i < NUM_DOCS; ++i) - { + for (int32_t i = 0; i < NUM_DOCS; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"theLong", StringUtils::toString(theLong--), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"theDouble", StringUtils::toString(theDouble--), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); @@ -41,8 +38,7 @@ class FieldCacheTest : public LuceneTestFixture reader = IndexReader::open(directory, true); } - virtual ~FieldCacheTest() - { + virtual ~FieldCacheTest() { } protected: @@ -54,15 +50,13 @@ class FieldCacheTest : public LuceneTestFixture const int32_t FieldCacheTest::NUM_DOCS = 1000; -TEST_F(FieldCacheTest, testFieldCache) -{ +TEST_F(FieldCacheTest, testFieldCache) { FieldCachePtr cache = FieldCache::DEFAULT(); Collection doubles = cache->getDoubles(reader, L"theDouble"); EXPECT_EQ(doubles.hashCode(), cache->getDoubles(reader, L"theDouble").hashCode()); EXPECT_EQ(doubles.hashCode(), cache->getDoubles(reader, L"theDouble", FieldCache::DEFAULT_DOUBLE_PARSER()).hashCode()); EXPECT_EQ(doubles.size(), NUM_DOCS); - for (int32_t i = 0; i < doubles.size(); ++i) - { + for (int32_t i = 0; i < doubles.size(); ++i) { StringStream first; first.precision(5); first << doubles[i]; @@ -76,20 +70,23 @@ TEST_F(FieldCacheTest, testFieldCache) EXPECT_EQ(longs.hashCode(), cache->getLongs(reader, L"theLong").hashCode()); EXPECT_EQ(longs.hashCode(), cache->getLongs(reader, L"theLong", FieldCache::DEFAULT_LONG_PARSER()).hashCode()); EXPECT_EQ(longs.size(), NUM_DOCS); - for (int32_t i = 0; i < longs.size(); ++i) + for (int32_t i = 0; i < longs.size(); ++i) { EXPECT_EQ(longs[i], (LLONG_MAX - i)); + } Collection bytes = cache->getBytes(reader, L"theByte"); EXPECT_EQ(bytes.hashCode(), cache->getBytes(reader, L"theByte").hashCode()); EXPECT_EQ(bytes.hashCode(), cache->getBytes(reader, L"theByte", FieldCache::DEFAULT_BYTE_PARSER()).hashCode()); EXPECT_EQ(bytes.size(), NUM_DOCS); - for (int32_t i = 0; i < bytes.size(); ++i) + for (int32_t i = 0; i < bytes.size(); ++i) { EXPECT_EQ(bytes[i], (uint8_t)(UCHAR_MAX - i)); + } Collection ints = cache->getInts(reader, L"theInt"); EXPECT_EQ(ints.hashCode(), cache->getInts(reader, L"theInt").hashCode()); EXPECT_EQ(ints.hashCode(), cache->getInts(reader, L"theInt", FieldCache::DEFAULT_INT_PARSER()).hashCode()); EXPECT_EQ(ints.size(), NUM_DOCS); - for (int32_t i = 0; i < ints.size(); ++i) + for (int32_t i = 0; i < ints.size(); ++i) { EXPECT_EQ(ints[i], (INT_MAX - i)); + } } diff --git a/src/test/search/FilteredQueryTest.cpp b/src/test/search/FilteredQueryTest.cpp index a72108f1..d3808de8 100644 --- a/src/test/search/FilteredQueryTest.cpp +++ b/src/test/search/FilteredQueryTest.cpp @@ -31,32 +31,26 @@ using namespace Lucene; -class StaticFilterA : public Filter -{ +class StaticFilterA : public Filter { public: - virtual ~StaticFilterA() - { + virtual ~StaticFilterA() { } public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { BitSetPtr bitset = newLucene(5); bitset->set((uint32_t)0, (uint32_t)5); return newLucene(bitset); } }; -class StaticFilterB : public Filter -{ +class StaticFilterB : public Filter { public: - virtual ~StaticFilterB() - { + virtual ~StaticFilterB() { } public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { BitSetPtr bitset = newLucene(5); bitset->set(1); bitset->set(3); @@ -64,35 +58,29 @@ class StaticFilterB : public Filter } }; -class SingleDocTestFilter : public Filter -{ +class SingleDocTestFilter : public Filter { public: - SingleDocTestFilter(int32_t doc) - { + SingleDocTestFilter(int32_t doc) { this->doc = doc; } - virtual ~SingleDocTestFilter() - { + virtual ~SingleDocTestFilter() { } protected: int32_t doc; public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { BitSetPtr bits = newLucene(reader->maxDoc()); bits->set(doc); return newLucene(bits); } }; -class FilteredQueryTest : public LuceneTestFixture -{ +class FilteredQueryTest : public LuceneTestFixture { public: - FilteredQueryTest() - { + FilteredQueryTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -124,8 +112,7 @@ class FilteredQueryTest : public LuceneTestFixture filter = newStaticFilterB(); } - virtual ~FilteredQueryTest() - { + virtual ~FilteredQueryTest() { searcher->close(); directory->close(); } @@ -137,30 +124,27 @@ class FilteredQueryTest : public LuceneTestFixture FilterPtr filter; public: - FilterPtr newStaticFilterA() - { + FilterPtr newStaticFilterA() { return newLucene(); } - FilterPtr newStaticFilterB() - { + FilterPtr newStaticFilterB() { return newLucene(); } - void checkScoreEquals(const QueryPtr& q1, const QueryPtr& q2) - { + void checkScoreEquals(const QueryPtr& q1, const QueryPtr& q2) { Collection hits1 = searcher->search(q1, FilterPtr(), 1000)->scoreDocs; Collection hits2 = searcher->search (q2, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(hits1.size(), hits2.size()); - for (int32_t i = 0; i < hits1.size(); ++i) + for (int32_t i = 0; i < hits1.size(); ++i) { EXPECT_NEAR(hits1[i]->score, hits2[i]->score, 0.0000001); + } } }; -TEST_F(FilteredQueryTest, testFilteredQuery) -{ +TEST_F(FilteredQueryTest, testFilteredQuery) { QueryPtr filteredquery = newLucene(query, filter); Collection hits = searcher->search(filteredquery, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(1, hits.size()); @@ -209,8 +193,7 @@ TEST_F(FilteredQueryTest, testFilteredQuery) EXPECT_EQ(1.0, tq->getBoost()); // the boost value of the underlying query shouldn't have changed } -TEST_F(FilteredQueryTest, testRangeQuery) -{ +TEST_F(FilteredQueryTest, testRangeQuery) { TermRangeQueryPtr rq = newLucene(L"sorter", L"b", L"d", true, true); QueryPtr filteredquery = newLucene(rq, filter); @@ -219,8 +202,7 @@ TEST_F(FilteredQueryTest, testRangeQuery) QueryUtils::check(filteredquery, searcher); } -TEST_F(FilteredQueryTest, testBoolean) -{ +TEST_F(FilteredQueryTest, testBoolean) { BooleanQueryPtr bq = newLucene(); QueryPtr query = newLucene(newLucene(), newLucene(0)); bq->add(query, BooleanClause::MUST); @@ -232,8 +214,7 @@ TEST_F(FilteredQueryTest, testBoolean) } /// Make sure BooleanQuery, which does out-of-order scoring, inside FilteredQuery, works -TEST_F(FilteredQueryTest, testBoolean2) -{ +TEST_F(FilteredQueryTest, testBoolean2) { BooleanQueryPtr bq = newLucene(); QueryPtr query = newLucene(bq, newLucene(0)); bq->add(newLucene(newLucene(L"field", L"one")), BooleanClause::SHOULD); diff --git a/src/test/search/FilteredSearchTest.cpp b/src/test/search/FilteredSearchTest.cpp index abd6a6d6..62b62353 100644 --- a/src/test/search/FilteredSearchTest.cpp +++ b/src/test/search/FilteredSearchTest.cpp @@ -25,18 +25,15 @@ using namespace Lucene; DECLARE_SHARED_PTR(SimpleDocIdSetFilter) -class SimpleDocIdSetFilter : public Filter -{ +class SimpleDocIdSetFilter : public Filter { public: - SimpleDocIdSetFilter(Collection docs) - { + SimpleDocIdSetFilter(Collection docs) { this->docs = docs; this->docBase = 0; this->index = 0; } - virtual ~SimpleDocIdSetFilter() - { + virtual ~SimpleDocIdSetFilter() { } protected: @@ -45,23 +42,21 @@ class SimpleDocIdSetFilter : public Filter int32_t index; public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { OpenBitSetPtr set = newLucene(); int32_t limit = docBase + reader->maxDoc(); - for (; index < docs.size(); ++index) - { + for (; index < docs.size(); ++index) { int32_t docId = docs[index]; - if (docId > limit) + if (docId > limit) { break; + } set->set(docId - docBase); } docBase = limit; return set->isEmpty() ? DocIdSetPtr() : set; } - void reset() - { + void reset() { index = 0; docBase = 0; } @@ -69,17 +64,16 @@ class SimpleDocIdSetFilter : public Filter static const String FIELD = L"category"; -static void searchFiltered(const IndexWriterPtr& writer, const DirectoryPtr& directory, const FilterPtr& filter, bool optimize) -{ - for (int32_t i = 0; i < 60; ++i) - { +static void searchFiltered(const IndexWriterPtr& writer, const DirectoryPtr& directory, const FilterPtr& filter, bool optimize) { + for (int32_t i = 0; i < 60; ++i) { // Simple docs DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD, StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } - if (optimize) + if (optimize) { writer->optimize(); + } writer->close(); BooleanQueryPtr booleanQuery = newLucene(); @@ -92,8 +86,7 @@ static void searchFiltered(const IndexWriterPtr& writer, const DirectoryPtr& dir typedef LuceneTestFixture FilteredSearchTest; -TEST_F(FilteredSearchTest, testFilteredSearch) -{ +TEST_F(FilteredSearchTest, testFilteredSearch) { bool enforceSingleSegment = true; RAMDirectoryPtr directory = newLucene(); Collection filterBits = newCollection(1, 36); diff --git a/src/test/search/FuzzyQueryTest.cpp b/src/test/search/FuzzyQueryTest.cpp index 4e03c165..698fa277 100644 --- a/src/test/search/FuzzyQueryTest.cpp +++ b/src/test/search/FuzzyQueryTest.cpp @@ -25,15 +25,13 @@ using namespace Lucene; typedef LuceneTestFixture FuzzyQueryTest; -static void addDoc(const String& text, const IndexWriterPtr& writer) -{ +static void addDoc(const String& text, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", text, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -TEST_F(FuzzyQueryTest, testFuzziness) -{ +TEST_F(FuzzyQueryTest, testFuzziness) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(L"aaaaa", writer); @@ -76,8 +74,7 @@ TEST_F(FuzzyQueryTest, testFuzziness) hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(3, hits.size()); Collection order = newCollection(L"bbbbb", L"abbbb", L"aabbb"); - for (int32_t i = 0; i < hits.size(); ++i) - { + for (int32_t i = 0; i < hits.size(); ++i) { String term = searcher->doc(hits[i]->doc)->get(L"field"); EXPECT_EQ(order[i], term); } @@ -92,8 +89,7 @@ TEST_F(FuzzyQueryTest, testFuzziness) EXPECT_EQ(2, hits.size()); order = newCollection(L"bbbbb", L"abbbb"); - for (int32_t i = 0; i < hits.size(); ++i) - { + for (int32_t i = 0; i < hits.size(); ++i) { String term = searcher->doc(hits[i]->doc)->get(L"field"); EXPECT_EQ(order[i], term); } @@ -188,8 +184,7 @@ TEST_F(FuzzyQueryTest, testFuzziness) directory->close(); } -TEST_F(FuzzyQueryTest, testFuzzinessLong) -{ +TEST_F(FuzzyQueryTest, testFuzzinessLong) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(L"aaaaaaa", writer); @@ -259,20 +254,14 @@ TEST_F(FuzzyQueryTest, testFuzzinessLong) hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(0, hits.size()); - try - { + try { query = newLucene(newLucene(L"field", L"student"), 1.1); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } - try - { + try { query = newLucene(newLucene(L"field", L"student"), -0.1); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } @@ -280,8 +269,7 @@ TEST_F(FuzzyQueryTest, testFuzzinessLong) directory->close(); } -TEST_F(FuzzyQueryTest, testTokenLengthOpt) -{ +TEST_F(FuzzyQueryTest, testTokenLengthOpt) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); addDoc(L"12345678911", writer); @@ -311,8 +299,7 @@ TEST_F(FuzzyQueryTest, testTokenLengthOpt) EXPECT_EQ(0, hits.size()); } -TEST_F(FuzzyQueryTest, testGiga) -{ +TEST_F(FuzzyQueryTest, testGiga) { StandardAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); DirectoryPtr index = newLucene(); diff --git a/src/test/search/MatchAllDocsQueryTest.cpp b/src/test/search/MatchAllDocsQueryTest.cpp index a47257ac..89c61515 100644 --- a/src/test/search/MatchAllDocsQueryTest.cpp +++ b/src/test/search/MatchAllDocsQueryTest.cpp @@ -25,8 +25,7 @@ using namespace Lucene; typedef LuceneTestFixture MatchAllDocsQueryTest; -static void addDoc(const String& text, const IndexWriterPtr& iw, double boost) -{ +static void addDoc(const String& text, const IndexWriterPtr& iw, double boost) { DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"key", text, Field::STORE_YES, Field::INDEX_ANALYZED); f->setBoost(boost); @@ -34,8 +33,7 @@ static void addDoc(const String& text, const IndexWriterPtr& iw, double boost) iw->addDocument(doc); } -TEST_F(MatchAllDocsQueryTest, testQuery) -{ +TEST_F(MatchAllDocsQueryTest, testQuery) { AnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); RAMDirectoryPtr dir = newLucene(); IndexWriterPtr iw = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -109,8 +107,7 @@ TEST_F(MatchAllDocsQueryTest, testQuery) dir->close(); } -TEST_F(MatchAllDocsQueryTest, testEquals) -{ +TEST_F(MatchAllDocsQueryTest, testEquals) { QueryPtr q1 = newLucene(); QueryPtr q2 = newLucene(); EXPECT_TRUE(q1->equals(q2)); diff --git a/src/test/search/MockFilter.cpp b/src/test/search/MockFilter.cpp index 269843fe..5ba3795a 100644 --- a/src/test/search/MockFilter.cpp +++ b/src/test/search/MockFilter.cpp @@ -9,30 +9,26 @@ #include "DocIdBitSet.h" #include "BitSet.h" -namespace Lucene -{ - MockFilter::MockFilter() - { - _wasCalled = false; - } - - MockFilter::~MockFilter() - { - } - - DocIdSetPtr MockFilter::getDocIdSet(const IndexReaderPtr& reader) - { - _wasCalled = true; - return newLucene(newLucene()); - } - - void MockFilter::clear() - { - _wasCalled = false; - } - - bool MockFilter::wasCalled() - { - return _wasCalled; - } +namespace Lucene { + +MockFilter::MockFilter() { + _wasCalled = false; +} + +MockFilter::~MockFilter() { +} + +DocIdSetPtr MockFilter::getDocIdSet(const IndexReaderPtr& reader) { + _wasCalled = true; + return newLucene(newLucene()); +} + +void MockFilter::clear() { + _wasCalled = false; +} + +bool MockFilter::wasCalled() { + return _wasCalled; +} + } diff --git a/src/test/search/MultiPhraseQueryTest.cpp b/src/test/search/MultiPhraseQueryTest.cpp index 28999b5b..0242c18c 100644 --- a/src/test/search/MultiPhraseQueryTest.cpp +++ b/src/test/search/MultiPhraseQueryTest.cpp @@ -27,23 +27,20 @@ using namespace Lucene; typedef LuceneTestFixture MultiPhraseQueryTest; -static void add(const String& s, const IndexWriterPtr& writer) -{ +static void add(const String& s, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"body", s, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } -static void add(const String& s, const String& type, const IndexWriterPtr& writer) -{ +static void add(const String& s, const String& type, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"body", s, Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(L"type", type, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); } -TEST_F(MultiPhraseQueryTest, testPhrasePrefix) -{ +TEST_F(MultiPhraseQueryTest, testPhrasePrefix) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); add(L"blueberry pie", writer); @@ -71,12 +68,11 @@ TEST_F(MultiPhraseQueryTest, testPhrasePrefix) // this TermEnum gives "piccadilly", "pie" and "pizza". String prefix = L"pi"; TermEnumPtr te = ir->terms(newLucene(L"body", prefix)); - do - { - if (boost::starts_with(te->term()->text(), prefix)) + do { + if (boost::starts_with(te->term()->text(), prefix)) { termsWithPrefix.add(te->term()); - } - while (te->next()); + } + } while (te->next()); query1->add(termsWithPrefix); EXPECT_EQ(L"body:\"blueberry (piccadilly pie pizza)\"", query1->toString()); @@ -93,12 +89,11 @@ TEST_F(MultiPhraseQueryTest, testPhrasePrefix) termsWithPrefix.clear(); prefix = L"blue"; te = ir->terms(newLucene(L"body", prefix)); - do - { - if (boost::starts_with(te->term()->text(), prefix)) + do { + if (boost::starts_with(te->term()->text(), prefix)) { termsWithPrefix.add(te->term()); - } - while (te->next()); + } + } while (te->next()); query3->add(termsWithPrefix); query3->add(newLucene(L"body", L"pizza")); @@ -114,12 +109,9 @@ TEST_F(MultiPhraseQueryTest, testPhrasePrefix) MultiPhraseQueryPtr query4 = newLucene(); query4->add(newLucene(L"field1", L"foo")); - try - { + try { query4->add(newLucene(L"field2", L"foobar")); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } @@ -127,8 +119,7 @@ TEST_F(MultiPhraseQueryTest, testPhrasePrefix) indexStore->close(); } -TEST_F(MultiPhraseQueryTest, testBooleanQueryContainingSingleTermPrefixQuery) -{ +TEST_F(MultiPhraseQueryTest, testBooleanQueryContainingSingleTermPrefixQuery) { // In order to cause the bug, the outer query must have more than one term and all terms required. // The contained PhraseMultiQuery must contain exactly one term array. @@ -155,8 +146,7 @@ TEST_F(MultiPhraseQueryTest, testBooleanQueryContainingSingleTermPrefixQuery) searcher->close(); } -TEST_F(MultiPhraseQueryTest, testPhrasePrefixWithBooleanQuery) -{ +TEST_F(MultiPhraseQueryTest, testPhrasePrefixWithBooleanQuery) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance()), true, IndexWriter::MaxFieldLengthLIMITED); add(L"This is a test", L"object", writer); @@ -180,8 +170,7 @@ TEST_F(MultiPhraseQueryTest, testPhrasePrefixWithBooleanQuery) searcher->close(); } -TEST_F(MultiPhraseQueryTest, testHashCodeAndEquals) -{ +TEST_F(MultiPhraseQueryTest, testHashCodeAndEquals) { MultiPhraseQueryPtr query1 = newLucene(); MultiPhraseQueryPtr query2 = newLucene(); diff --git a/src/test/search/MultiSearcherRankingTest.cpp b/src/test/search/MultiSearcherRankingTest.cpp index 1c0db4d3..41476f15 100644 --- a/src/test/search/MultiSearcherRankingTest.cpp +++ b/src/test/search/MultiSearcherRankingTest.cpp @@ -20,11 +20,9 @@ using namespace Lucene; -class MultiSearcherRankingTest : public LuceneTestFixture -{ +class MultiSearcherRankingTest : public LuceneTestFixture { public: - MultiSearcherRankingTest() - { + MultiSearcherRankingTest() { // create MultiSearcher from two separate searchers DirectoryPtr d1 = newLucene(); IndexWriterPtr iw1 = newLucene(d1, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -47,8 +45,7 @@ class MultiSearcherRankingTest : public LuceneTestFixture singleSearcher = newLucene(d, true); } - virtual ~MultiSearcherRankingTest() - { + virtual ~MultiSearcherRankingTest() { } protected: @@ -57,8 +54,7 @@ class MultiSearcherRankingTest : public LuceneTestFixture SearcherPtr singleSearcher; public: - void addCollection1(const IndexWriterPtr& iw) - { + void addCollection1(const IndexWriterPtr& iw) { add(L"one blah three", iw); add(L"one foo three multiOne", iw); add(L"one foobar three multiThree", iw); @@ -67,8 +63,7 @@ class MultiSearcherRankingTest : public LuceneTestFixture add(L"blueberry pizza", iw); } - void addCollection2(const IndexWriterPtr& iw) - { + void addCollection2(const IndexWriterPtr& iw) { add(L"two blah three", iw); add(L"two foo xxx multiTwo", iw); add(L"two foobar xxx multiThreee", iw); @@ -78,8 +73,7 @@ class MultiSearcherRankingTest : public LuceneTestFixture add(L"piccadilly circus", iw); } - void add(const String& value, const IndexWriterPtr& iw) - { + void add(const String& value, const IndexWriterPtr& iw) { DocumentPtr d = newLucene(); d->add(newLucene(FIELD_NAME, value, Field::STORE_YES, Field::INDEX_ANALYZED)); iw->addDocument(d); @@ -88,15 +82,13 @@ class MultiSearcherRankingTest : public LuceneTestFixture /// checks if a query yields the same result when executed on a single IndexSearcher containing all /// documents and on MultiSearcher aggregating sub-searchers /// @param queryStr the query to check. - void checkQuery(const String& queryStr) - { + void checkQuery(const String& queryStr) { QueryParserPtr queryParser = newLucene(LuceneVersion::LUCENE_CURRENT, FIELD_NAME, newLucene(LuceneVersion::LUCENE_CURRENT)); QueryPtr query = queryParser->parse(queryStr); Collection multiSearcherHits = multiSearcher->search(query, FilterPtr(), 1000)->scoreDocs; Collection singleSearcherHits = singleSearcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(multiSearcherHits.size(), singleSearcherHits.size()); - for (int32_t i = 0; i < multiSearcherHits.size(); ++i) - { + for (int32_t i = 0; i < multiSearcherHits.size(); ++i) { DocumentPtr docMulti = multiSearcher->doc(multiSearcherHits[i]->doc); DocumentPtr docSingle = singleSearcher->doc(singleSearcherHits[i]->doc); EXPECT_NEAR(multiSearcherHits[i]->score, singleSearcherHits[i]->score, 0.001); @@ -107,37 +99,30 @@ class MultiSearcherRankingTest : public LuceneTestFixture const String MultiSearcherRankingTest::FIELD_NAME = L"body"; -TEST_F(MultiSearcherRankingTest, testOneTermQuery) -{ +TEST_F(MultiSearcherRankingTest, testOneTermQuery) { checkQuery(L"three"); } -TEST_F(MultiSearcherRankingTest, testTwoTermQuery) -{ +TEST_F(MultiSearcherRankingTest, testTwoTermQuery) { checkQuery(L"three foo"); } -TEST_F(MultiSearcherRankingTest, testPrefixQuery) -{ +TEST_F(MultiSearcherRankingTest, testPrefixQuery) { checkQuery(L"multi*"); } -TEST_F(MultiSearcherRankingTest, testFuzzyQuery) -{ +TEST_F(MultiSearcherRankingTest, testFuzzyQuery) { checkQuery(L"multiThree~"); } -TEST_F(MultiSearcherRankingTest, testRangeQuery) -{ +TEST_F(MultiSearcherRankingTest, testRangeQuery) { checkQuery(L"{multiA TO multiP}"); } -TEST_F(MultiSearcherRankingTest, testMultiPhraseQuery) -{ +TEST_F(MultiSearcherRankingTest, testMultiPhraseQuery) { checkQuery(L"\"blueberry pi*\""); } -TEST_F(MultiSearcherRankingTest, testNoMatchQuery) -{ +TEST_F(MultiSearcherRankingTest, testNoMatchQuery) { checkQuery(L"+three +nomatch"); } diff --git a/src/test/search/MultiSearcherTest.cpp b/src/test/search/MultiSearcherTest.cpp index dccf8ceb..f5122432 100644 --- a/src/test/search/MultiSearcherTest.cpp +++ b/src/test/search/MultiSearcherTest.cpp @@ -30,31 +30,29 @@ using namespace Lucene; typedef LuceneTestFixture MultiSearcherTest; -static MultiSearcherPtr getMultiSearcherInstance(Collection searchers) -{ +static MultiSearcherPtr getMultiSearcherInstance(Collection searchers) { return newLucene(searchers); } -static DocumentPtr createDocument(const String& contents1, const String& contents2) -{ +static DocumentPtr createDocument(const String& contents1, const String& contents2) { DocumentPtr document = newLucene(); document->add(newLucene(L"contents", contents1, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); document->add(newLucene(L"other", L"other contents", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - if (!contents2.empty()) + if (!contents2.empty()) { document->add(newLucene(L"contents", contents2, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + } return document; } -static void initIndex(const DirectoryPtr& directory, int32_t numDocs, bool create, const String& contents2) -{ +static void initIndex(const DirectoryPtr& directory, int32_t numDocs, bool create, const String& contents2) { IndexWriterPtr indexWriter = newLucene(directory, newLucene(), create, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < numDocs; ++i) + for (int32_t i = 0; i < numDocs; ++i) { indexWriter->addDocument(createDocument(L"doc" + StringUtils::toString(i), contents2)); + } indexWriter->close(); } -TEST_F(MultiSearcherTest, testEmptyIndex) -{ +TEST_F(MultiSearcherTest, testEmptyIndex) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); DirectoryPtr indexStoreB = newLucene(); @@ -110,8 +108,9 @@ TEST_F(MultiSearcherTest, testEmptyIndex) EXPECT_EQ(3, hits.size()); // iterating over the hit documents - for (int32_t i = 0; i < hits.size(); ++i) + for (int32_t i = 0; i < hits.size(); ++i) { mSearcher->doc(hits[i]->doc); + } mSearcher->close(); @@ -135,8 +134,9 @@ TEST_F(MultiSearcherTest, testEmptyIndex) EXPECT_EQ(4, hits2.size()); // iterating over the hit documents - for (int32_t i = 0; i < hits2.size(); ++i) + for (int32_t i = 0; i < hits2.size(); ++i) { mSearcher2->doc(hits2[i]->doc); + } // test the subSearcher() method QueryPtr subSearcherQuery = parser->parse(L"id:doc1"); @@ -176,16 +176,16 @@ TEST_F(MultiSearcherTest, testEmptyIndex) // iterating over the hit documents - for (int32_t i = 0; i < hits3.size(); ++i) + for (int32_t i = 0; i < hits3.size(); ++i) { mSearcher3->doc(hits3[i]->doc); + } mSearcher3->close(); indexStoreA->close(); indexStoreB->close(); } -TEST_F(MultiSearcherTest, testFieldSelector) -{ +TEST_F(MultiSearcherTest, testFieldSelector) { RAMDirectoryPtr ramDirectory1 = newLucene(); RAMDirectoryPtr ramDirectory2 = newLucene(); @@ -227,8 +227,7 @@ TEST_F(MultiSearcherTest, testFieldSelector) EXPECT_TRUE(value.empty()); } -TEST_F(MultiSearcherTest, testNormalization) -{ +TEST_F(MultiSearcherTest, testNormalization) { int32_t numDocs = 10; QueryPtr query = newLucene(newLucene(L"contents", L"doc0")); @@ -288,50 +287,42 @@ TEST_F(MultiSearcherTest, testNormalization) ramDirectory2->close(); } -namespace TestCustomSimilarity -{ - class CustomSimilarity : public DefaultSimilarity - { - public: - virtual ~CustomSimilarity() - { - } - - public: - virtual double idf(int32_t docFreq, int32_t numDocs) - { - return 100.0; - } - - virtual double coord(int32_t overlap, int32_t maxOverlap) - { - return 1.0; - } - - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { - return 1.0; - } - - virtual double queryNorm(double sumOfSquaredWeights) - { - return 1.0; - } - - virtual double sloppyFreq(int32_t distance) - { - return 1.0; - } - - virtual double tf(double freq) - { - return 1.0; - } - }; +namespace TestCustomSimilarity { + +class CustomSimilarity : public DefaultSimilarity { +public: + virtual ~CustomSimilarity() { + } + +public: + virtual double idf(int32_t docFreq, int32_t numDocs) { + return 100.0; + } + + virtual double coord(int32_t overlap, int32_t maxOverlap) { + return 1.0; + } + + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { + return 1.0; + } + + virtual double queryNorm(double sumOfSquaredWeights) { + return 1.0; + } + + virtual double sloppyFreq(int32_t distance) { + return 1.0; + } + + virtual double tf(double freq) { + return 1.0; + } +}; + } -TEST_F(MultiSearcherTest, testCustomSimilarity) -{ +TEST_F(MultiSearcherTest, testCustomSimilarity) { RAMDirectoryPtr dir = newLucene(); initIndex(dir, 10, true, L"x"); // documents with two tokens "doc0" and "x", "doc1" and x, etc... IndexSearcherPtr searcher = newLucene(dir, true); @@ -355,8 +346,7 @@ TEST_F(MultiSearcherTest, testCustomSimilarity) EXPECT_NEAR(score1, scoreN, 1e-6); } -TEST_F(MultiSearcherTest, testDocFreq) -{ +TEST_F(MultiSearcherTest, testDocFreq) { RAMDirectoryPtr dir1 = newLucene(); RAMDirectoryPtr dir2 = newLucene(); diff --git a/src/test/search/MultiTermConstantScoreTest.cpp b/src/test/search/MultiTermConstantScoreTest.cpp index 19deca5f..2bbbd15a 100644 --- a/src/test/search/MultiTermConstantScoreTest.cpp +++ b/src/test/search/MultiTermConstantScoreTest.cpp @@ -28,32 +28,30 @@ using namespace Lucene; -class MultiTermConstantScoreTest : public BaseTestRangeFilterFixture -{ +class MultiTermConstantScoreTest : public BaseTestRangeFilterFixture { public: - MultiTermConstantScoreTest() - { + MultiTermConstantScoreTest() { Collection data = newCollection( - L"A 1 2 3 4 5 6", - L"Z 4 5 6", - L"", - L"B 2 4 5 6", - L"Y 3 5 6", - L"", - L"C 3 6", - L"X 4 5 6" - ); + L"A 1 2 3 4 5 6", + L"Z 4 5 6", + L"", + L"B 2 4 5 6", + L"Y 3 5 6", + L"", + L"C 3 6", + L"X 4 5 6" + ); small = newLucene(); IndexWriterPtr writer = newLucene(small, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < data.size(); ++i) - { + for (int32_t i = 0; i < data.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"all", L"all", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - if (!data[i].empty()) + if (!data[i].empty()) { doc->add(newLucene(L"data", data[i], Field::STORE_YES, Field::INDEX_ANALYZED)); + } writer->addDocument(doc); } @@ -61,8 +59,7 @@ class MultiTermConstantScoreTest : public BaseTestRangeFilterFixture writer->close(); } - virtual ~MultiTermConstantScoreTest() - { + virtual ~MultiTermConstantScoreTest() { } public: @@ -71,36 +68,31 @@ class MultiTermConstantScoreTest : public BaseTestRangeFilterFixture DirectoryPtr small; public: - QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih) - { + QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih) { TermRangeQueryPtr query = newLucene(f, l, h, il, ih); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, const RewriteMethodPtr& method) - { + QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, const RewriteMethodPtr& method) { TermRangeQueryPtr query = newLucene(f, l, h, il, ih); query->setRewriteMethod(method); return query; } - QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, const CollatorPtr& c) - { + QueryPtr csrq(const String& f, const String& l, const String& h, bool il, bool ih, const CollatorPtr& c) { TermRangeQueryPtr query = newLucene(f, l, h, il, ih, c); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - QueryPtr cspq(const TermPtr& prefix) - { + QueryPtr cspq(const TermPtr& prefix) { PrefixQueryPtr query = newLucene(prefix); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; } - QueryPtr cswcq(const TermPtr& wild) - { + QueryPtr cswcq(const TermPtr& wild) { WildcardQueryPtr query = newLucene(wild); query->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); return query; @@ -110,8 +102,7 @@ class MultiTermConstantScoreTest : public BaseTestRangeFilterFixture /// threshold for comparing doubles const double MultiTermConstantScoreTest::SCORE_COMP_THRESH = 1e-6f; -TEST_F(MultiTermConstantScoreTest, testBasics) -{ +TEST_F(MultiTermConstantScoreTest, testBasics) { QueryUtils::check(csrq(L"data", L"1", L"6", true, true)); QueryUtils::check(csrq(L"data", L"A", L"Z", true, true)); QueryUtils::checkUnequal(csrq(L"data", L"1", L"6", true, true), csrq(L"data", L"A", L"Z", true, true)); @@ -123,16 +114,14 @@ TEST_F(MultiTermConstantScoreTest, testBasics) QueryUtils::checkUnequal(cswcq(newLucene(L"data", L"pre*n?t")), cswcq(newLucene(L"data", L"pr*t?j"))); } -TEST_F(MultiTermConstantScoreTest, testBasicsRngCollating) -{ +TEST_F(MultiTermConstantScoreTest, testBasicsRngCollating) { CollatorPtr c = newLucene(std::locale()); QueryUtils::check(csrq(L"data", L"1", L"6", true, true, c)); QueryUtils::check(csrq(L"data", L"A", L"Z", true, true, c)); QueryUtils::checkUnequal(csrq(L"data", L"1", L"6", true, true, c), csrq(L"data", L"A", L"Z", true, true, c)); } -TEST_F(MultiTermConstantScoreTest, testEqualScores) -{ +TEST_F(MultiTermConstantScoreTest, testEqualScores) { IndexReaderPtr reader = IndexReader::open(small, true); IndexSearcherPtr search = newLucene(reader); @@ -141,59 +130,54 @@ TEST_F(MultiTermConstantScoreTest, testEqualScores) int32_t numHits = result.size(); EXPECT_EQ(6, numHits); double score = result[0]->score; - for (int32_t i = 1; i < numHits; ++i) + for (int32_t i = 1; i < numHits; ++i) { EXPECT_EQ(score, result[i]->score); + } result = search->search(csrq(L"data", L"1", L"6", true, true, MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()), FilterPtr(), 1000)->scoreDocs; numHits = result.size(); EXPECT_EQ(6, numHits); - for (int32_t i = 0; i < numHits; ++i) + for (int32_t i = 0; i < numHits; ++i) { EXPECT_EQ(score, result[i]->score); + } } -namespace TestBoost -{ - class TestCollector : public Collector - { - public: - TestCollector() - { - base = 0; - } +namespace TestBoost { - virtual ~TestCollector() - { - } +class TestCollector : public Collector { +public: + TestCollector() { + base = 0; + } - protected: - int32_t base; - ScorerPtr scorer; + virtual ~TestCollector() { + } - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } +protected: + int32_t base; + ScorerPtr scorer; - virtual void collect(int32_t doc) - { - EXPECT_EQ(1.0, scorer->score()); - } +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - base = docBase; - } + virtual void collect(int32_t doc) { + EXPECT_EQ(1.0, scorer->score()); + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + base = docBase; + } + + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; } -TEST_F(MultiTermConstantScoreTest, testBoost) -{ +TEST_F(MultiTermConstantScoreTest, testBoost) { IndexReaderPtr reader = IndexReader::open(small, true); IndexSearcherPtr search = newLucene(reader); @@ -242,8 +226,7 @@ TEST_F(MultiTermConstantScoreTest, testBoost) EXPECT_TRUE(hits[0]->score > hits[1]->score); } -TEST_F(MultiTermConstantScoreTest, testBooleanOrderUnAffected) -{ +TEST_F(MultiTermConstantScoreTest, testBooleanOrderUnAffected) { IndexReaderPtr reader = IndexReader::open(small, true); IndexSearcherPtr search = newLucene(reader); @@ -262,12 +245,12 @@ TEST_F(MultiTermConstantScoreTest, testBooleanOrderUnAffected) Collection actual = search->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(numHits, actual.size()); - for (int32_t i = 0; i < numHits; ++i) + for (int32_t i = 0; i < numHits; ++i) { EXPECT_EQ(expected[i]->doc, actual[i]->doc); + } } -TEST_F(MultiTermConstantScoreTest, testRangeQueryId) -{ +TEST_F(MultiTermConstantScoreTest, testRangeQueryId) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -393,8 +376,7 @@ TEST_F(MultiTermConstantScoreTest, testRangeQueryId) EXPECT_EQ(1, result.size()); } -TEST_F(MultiTermConstantScoreTest, testRangeQueryIdCollating) -{ +TEST_F(MultiTermConstantScoreTest, testRangeQueryIdCollating) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -476,8 +458,7 @@ TEST_F(MultiTermConstantScoreTest, testRangeQueryIdCollating) EXPECT_EQ(1, result.size()); } -TEST_F(MultiTermConstantScoreTest, testRangeQueryRand) -{ +TEST_F(MultiTermConstantScoreTest, testRangeQueryRand) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -537,8 +518,7 @@ TEST_F(MultiTermConstantScoreTest, testRangeQueryRand) EXPECT_EQ(1, result.size()); } -TEST_F(MultiTermConstantScoreTest, testRangeQueryRandCollating) -{ +TEST_F(MultiTermConstantScoreTest, testRangeQueryRandCollating) { // using the unsigned index because collation seems to ignore hyphens IndexReaderPtr reader = IndexReader::open(unsignedIndex->index, true); IndexSearcherPtr search = newLucene(reader); diff --git a/src/test/search/MultiThreadTermVectorsTest.cpp b/src/test/search/MultiThreadTermVectorsTest.cpp index bcc1bb13..da88a98d 100644 --- a/src/test/search/MultiThreadTermVectorsTest.cpp +++ b/src/test/search/MultiThreadTermVectorsTest.cpp @@ -21,17 +21,14 @@ using namespace Lucene; DECLARE_SHARED_PTR(MultiThreadTermVectorsReader) -class MultiThreadTermVectorsReader : public LuceneThread -{ +class MultiThreadTermVectorsReader : public LuceneThread { public: - MultiThreadTermVectorsReader(const IndexReaderPtr& reader) - { + MultiThreadTermVectorsReader(const IndexReaderPtr& reader) { this->reader = reader; timeElapsed = 0; } - virtual ~MultiThreadTermVectorsReader() - { + virtual ~MultiThreadTermVectorsReader() { } LUCENE_CLASS(MultiThreadTermVectorsReader); @@ -43,26 +40,21 @@ class MultiThreadTermVectorsReader : public LuceneThread static const int32_t runsToDo; public: - virtual void run() - { - try - { - for (int32_t i = 0; i < runsToDo; ++i) + virtual void run() { + try { + for (int32_t i = 0; i < runsToDo; ++i) { testTermVectors(); - } - catch (LuceneException& e) - { + } + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } protected: - void testTermVectors() - { + void testTermVectors() { int32_t numDocs = reader->numDocs(); int64_t start = 0; - for (int32_t docId = 0; docId < numDocs; ++docId) - { + for (int32_t docId = 0; docId < numDocs; ++docId) { start = MiscUtils::currentTimeMillis(); Collection vectors = reader->getTermFreqVectors(docId); timeElapsed += MiscUtils::currentTimeMillis() - start; @@ -80,36 +72,33 @@ class MultiThreadTermVectorsReader : public LuceneThread } } - void verifyVectors(Collection vectors, int32_t num) - { + void verifyVectors(Collection vectors, int32_t num) { StringStream temp; Collection terms; - for (int32_t i = 0; i < vectors.size(); ++i) - { + for (int32_t i = 0; i < vectors.size(); ++i) { terms = vectors[i]->getTerms(); - for (int32_t z = 0; z < terms.size(); ++z) + for (int32_t z = 0; z < terms.size(); ++z) { temp << terms[z]; + } } - if (intToEnglish(num) != temp.str()) + if (intToEnglish(num) != temp.str()) { FAIL() << intToEnglish(num) << "!=" << temp.str(); + } } }; const int32_t MultiThreadTermVectorsReader::runsToDo = 100; -class MultiThreadTermVectorsTest : public LuceneTestFixture -{ +class MultiThreadTermVectorsTest : public LuceneTestFixture { public: - MultiThreadTermVectorsTest() - { + MultiThreadTermVectorsTest() { directory = newLucene(); numDocs = 100; numThreads = 3; IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < numDocs; ++i) - { + for (int32_t i = 0; i < numDocs; ++i) { DocumentPtr doc = newLucene(); FieldablePtr fld = newLucene(L"field", intToEnglish(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_YES); doc->add(fld); @@ -118,8 +107,7 @@ class MultiThreadTermVectorsTest : public LuceneTestFixture writer->close(); } - virtual ~MultiThreadTermVectorsTest() - { + virtual ~MultiThreadTermVectorsTest() { } protected: @@ -128,32 +116,28 @@ class MultiThreadTermVectorsTest : public LuceneTestFixture int32_t numThreads; public: - void testTermPositionVectors(const IndexReaderPtr& reader, int32_t threadCount) - { + void testTermPositionVectors(const IndexReaderPtr& reader, int32_t threadCount) { Collection mtr = Collection::newInstance(threadCount); - for (int32_t i = 0; i < threadCount; ++i) - { + for (int32_t i = 0; i < threadCount; ++i) { mtr[i] = newLucene(reader); mtr[i]->start(); } - for (int32_t i = 0; i < threadCount; ++i) + for (int32_t i = 0; i < threadCount; ++i) { mtr[i]->join(); + } } }; -TEST_F(MultiThreadTermVectorsTest, testMultiThreadTermVectors) -{ +TEST_F(MultiThreadTermVectorsTest, testMultiThreadTermVectors) { IndexReaderPtr reader; - try - { + try { reader = IndexReader::open(directory, true); - for (int32_t i = 1; i <= numThreads; ++i) + for (int32_t i = 1; i <= numThreads; ++i) { testTermPositionVectors(reader, i); - } - catch (LuceneException& e) - { + } + } catch (LuceneException& e) { FAIL() << e.getError(); } } diff --git a/src/test/search/MultiValuedNumericRangeQueryTest.cpp b/src/test/search/MultiValuedNumericRangeQueryTest.cpp index 8d7ac3ee..3de8c845 100644 --- a/src/test/search/MultiValuedNumericRangeQueryTest.cpp +++ b/src/test/search/MultiValuedNumericRangeQueryTest.cpp @@ -22,37 +22,33 @@ using namespace Lucene; typedef LuceneTestFixture MultiValuedNumericRangeQueryTest; -static String pad(int32_t n) -{ +static String pad(int32_t n) { int32_t intLength = String(L"00000000000").length(); StringStream buf; String p = L"0"; - if (n < 0) - { + if (n < 0) { p = L"-"; n = INT_MAX + n + 1; } buf << p; String s = StringUtils::toString(n); - for (int32_t i = s.length(); i <= intLength; ++i) + for (int32_t i = s.length(); i <= intLength; ++i) { buf << L"0"; + } buf << s; return buf.str(); } -TEST_F(MultiValuedNumericRangeQueryTest, testMultiValuedNRQ) -{ +TEST_F(MultiValuedNumericRangeQueryTest, testMultiValuedNRQ) { RandomPtr rnd = newLucene(); RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t l = 0; l < 5000; ++l) - { + for (int32_t l = 0; l < 5000; ++l) { DocumentPtr doc = newLucene(); - for (int32_t m = 0, c = rnd->nextInt(10); m <= c; ++m) - { + for (int32_t m = 0, c = rnd->nextInt(10); m <= c; ++m) { int32_t value = rnd->nextInt(INT_MAX); doc->add(newLucene(L"asc", pad(value), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"trie", Field::STORE_NO, true)->setIntValue(value)); @@ -62,12 +58,12 @@ TEST_F(MultiValuedNumericRangeQueryTest, testMultiValuedNRQ) writer->close(); SearcherPtr searcher = newLucene(directory, true); - for (int32_t i = 0; i < 50; ++i) - { + for (int32_t i = 0; i < 50; ++i) { int32_t lower = rnd->nextInt(INT_MAX); int32_t upper = rnd->nextInt(INT_MAX); - if (lower > upper) + if (lower > upper) { std::swap(lower, upper); + } TermRangeQueryPtr cq = newLucene(L"asc", pad(lower), pad(upper), true, true); NumericRangeQueryPtr tq = NumericRangeQuery::newIntRange(L"trie", lower, upper, true, true); TopDocsPtr trTopDocs = searcher->search(cq, 1); diff --git a/src/test/search/NotTest.cpp b/src/test/search/NotTest.cpp index 56879639..5734cc63 100644 --- a/src/test/search/NotTest.cpp +++ b/src/test/search/NotTest.cpp @@ -21,8 +21,7 @@ using namespace Lucene; typedef LuceneTestFixture NotTest; -TEST_F(NotTest, testNot) -{ +TEST_F(NotTest, testNot) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); diff --git a/src/test/search/NumericRangeQuery32Test.cpp b/src/test/search/NumericRangeQuery32Test.cpp index 08a8f372..4812ba06 100644 --- a/src/test/search/NumericRangeQuery32Test.cpp +++ b/src/test/search/NumericRangeQuery32Test.cpp @@ -33,21 +33,17 @@ using namespace Lucene; -class NumericRangeQuery32Test : public LuceneTestFixture -{ +class NumericRangeQuery32Test : public LuceneTestFixture { public: - NumericRangeQuery32Test() - { + NumericRangeQuery32Test() { static bool setupRequired = true; - if (setupRequired) - { + if (setupRequired) { setup(); setupRequired = false; } } - virtual ~NumericRangeQuery32Test() - { + virtual ~NumericRangeQuery32Test() { } protected: @@ -65,8 +61,7 @@ class NumericRangeQuery32Test : public LuceneTestFixture protected: /// One-time setup to initialise static members - void setup() - { + void setup() { // set the theoretical maximum term count for 8bit (see docs for the number) BooleanQuery::setMaxClauseCount(3 * 255 * 2 + 255); @@ -95,8 +90,7 @@ class NumericRangeQuery32Test : public LuceneTestFixture doc->add(ascfield2); // Add a series of noDocs docs with increasing int values - for (int32_t l = 0; l < noDocs; ++l) - { + for (int32_t l = 0; l < noDocs; ++l) { int32_t val = distance * l + startOffset; field8->setIntValue(val); field4->setIntValue(val); @@ -117,8 +111,7 @@ class NumericRangeQuery32Test : public LuceneTestFixture public: /// test for both constant score and boolean query, the other tests only use the constant score mode - void testRange(int32_t precisionStep) - { + void testRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); int32_t count = 3000; int32_t lower = (distance * 3 / 2) + startOffset; @@ -127,34 +120,32 @@ class NumericRangeQuery32Test : public LuceneTestFixture NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, true, true); NumericRangeFilterPtr f = NumericRangeFilter::newIntRange(field, precisionStep, lower, upper, true, true); int32_t lastTerms = 0; - for (uint8_t i = 0; i < 3; ++i) - { + for (uint8_t i = 0; i < 3; ++i) { TopDocsPtr topDocs; int32_t terms; String type; q->clearTotalNumberOfTerms(); f->clearTotalNumberOfTerms(); - switch (i) - { - case 0: - type = L" (constant score filter rewrite)"; - q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); - topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); - terms = q->getTotalNumberOfTerms(); - break; - case 1: - type = L" (constant score boolean rewrite)"; - q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); - topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); - terms = q->getTotalNumberOfTerms(); - break; - case 2: - type = L" (filter)"; - topDocs = searcher->search(newLucene(), f, noDocs, Sort::INDEXORDER()); - terms = f->getTotalNumberOfTerms(); - break; - default: - return; + switch (i) { + case 0: + type = L" (constant score filter rewrite)"; + q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); + topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); + terms = q->getTotalNumberOfTerms(); + break; + case 1: + type = L" (constant score boolean rewrite)"; + q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); + topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); + terms = q->getTotalNumberOfTerms(); + break; + case 2: + type = L" (filter)"; + topDocs = searcher->search(newLucene(), f, noDocs, Sort::INDEXORDER()); + terms = f->getTotalNumberOfTerms(); + break; + default: + return; } // std::cout << "Found " << terms << " distinct terms in range for field '" << field << "'" << type << "."; Collection sd = topDocs->scoreDocs; @@ -164,14 +155,14 @@ class NumericRangeQuery32Test : public LuceneTestFixture EXPECT_EQ(StringUtils::toString(2 * distance + startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); EXPECT_EQ(StringUtils::toString((1 + count) * distance + startOffset), doc->get(field)); - if (i > 0) + if (i > 0) { EXPECT_EQ(lastTerms, terms); + } lastTerms = terms; } } - void testLeftOpenRange(int32_t precisionStep) - { + void testLeftOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); int32_t count = 3000; int32_t upper = (count - 1) * distance + (distance / 3) + startOffset; @@ -186,8 +177,7 @@ class NumericRangeQuery32Test : public LuceneTestFixture EXPECT_EQ(StringUtils::toString((count - 1) * distance + startOffset), doc->get(field)); } - void testRightOpenRange(int32_t precisionStep) - { + void testRightOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); int32_t count = 3000; int32_t lower = (count - 1) * distance + (distance / 3) + startOffset; @@ -202,18 +192,17 @@ class NumericRangeQuery32Test : public LuceneTestFixture EXPECT_EQ(StringUtils::toString((noDocs - 1) * distance + startOffset), doc->get(field)); } - void testRandomTrieAndClassicRangeQuery(int32_t precisionStep) - { + void testRandomTrieAndClassicRangeQuery(int32_t precisionStep) { RandomPtr rnd = newLucene(); String field = L"field" + StringUtils::toString(precisionStep); int32_t termCountT = 0; int32_t termCountC = 0; - for (int32_t i = 0; i < 50; ++i) - { + for (int32_t i = 0; i < 50; ++i) { int32_t lower = (int32_t)(rnd->nextDouble() * noDocs * distance) + startOffset; int32_t upper = (int32_t)(rnd->nextDouble() * noDocs * distance) + startOffset; - if (lower > upper) + if (lower > upper) { std::swap(lower, upper); + } // test inclusive range NumericRangeQueryPtr tq = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, true, true); TermRangeQueryPtr cq = newLucene(field, NumericUtils::intToPrefixCoded(lower), NumericUtils::intToPrefixCoded(upper), true, true); @@ -247,21 +236,21 @@ class NumericRangeQuery32Test : public LuceneTestFixture termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); } - if (precisionStep == INT_MAX) + if (precisionStep == INT_MAX) { EXPECT_EQ(termCountT, termCountC); + } } - void testRangeSplit(int32_t precisionStep) - { + void testRangeSplit(int32_t precisionStep) { RandomPtr rnd = newLucene(); String field = L"ascfield" + StringUtils::toString(precisionStep); // 50 random tests - for (int32_t i = 0; i < 50; ++i) - { + for (int32_t i = 0; i < 50; ++i) { int32_t lower = (int32_t)(rnd->nextDouble() * noDocs - noDocs / 2.0); int32_t upper = (int32_t)(rnd->nextDouble() * noDocs - noDocs / 2.0); - if (lower > upper) + if (lower > upper) { std::swap(lower, upper); + } // test inclusive range QueryPtr tq = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, true, true); TopDocsPtr tTopDocs = searcher->search(tq, 1); @@ -281,26 +270,25 @@ class NumericRangeQuery32Test : public LuceneTestFixture } } - void testSorting(int32_t precisionStep) - { + void testSorting(int32_t precisionStep) { RandomPtr rnd = newLucene(); String field = L"field" + StringUtils::toString(precisionStep); // 10 random tests, the index order is ascending, so using a reverse sort field should return descending documents - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { int32_t lower = (int32_t)(rnd->nextDouble() * noDocs * distance) + startOffset; int32_t upper = (int32_t)(rnd->nextDouble() * noDocs * distance) + startOffset; - if (lower > upper) + if (lower > upper) { std::swap(lower, upper); + } QueryPtr tq = NumericRangeQuery::newIntRange(field, precisionStep, lower, upper, true, true); TopDocsPtr topDocs = searcher->search(tq, FilterPtr(), noDocs, newLucene(newLucene(field, SortField::INT, true))); - if (topDocs->totalHits == 0) + if (topDocs->totalHits == 0) { continue; + } Collection sd = topDocs->scoreDocs; EXPECT_TRUE(sd); int32_t last = StringUtils::toInt(searcher->doc(sd[0]->doc)->get(field)); - for (int32_t j = 1; j < sd.size(); ++j) - { + for (int32_t j = 1; j < sd.size(); ++j) { int32_t act = StringUtils::toInt(searcher->doc(sd[j]->doc)->get(field)); EXPECT_TRUE(last > act); last = act; @@ -308,22 +296,18 @@ class NumericRangeQuery32Test : public LuceneTestFixture } } - void testEnumRange(int32_t lower, int32_t upper) - { + void testEnumRange(int32_t lower, int32_t upper) { NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(L"field4", 4, lower, upper, true, true); FilteredTermEnumPtr termEnum = newLucene(q, searcher->getIndexReader()); - do - { + do { TermPtr t = termEnum->term(); - if (t) - { + if (t) { int32_t val = NumericUtils::prefixCodedToInt(t->text()); EXPECT_TRUE(val >= lower && val <= upper); - } - else + } else { break; - } - while (termEnum->next()); + } + } while (termEnum->next()); EXPECT_TRUE(!termEnum->next()); termEnum->close(); } @@ -341,23 +325,19 @@ const int32_t NumericRangeQuery32Test::noDocs = 10000; RAMDirectoryPtr NumericRangeQuery32Test::directory; IndexSearcherPtr NumericRangeQuery32Test::searcher; -TEST_F(NumericRangeQuery32Test, testRange_8bit) -{ +TEST_F(NumericRangeQuery32Test, testRange_8bit) { testRange(8); } -TEST_F(NumericRangeQuery32Test, testRange_4bit) -{ +TEST_F(NumericRangeQuery32Test, testRange_4bit) { testRange(4); } -TEST_F(NumericRangeQuery32Test, testRange_2bit) -{ +TEST_F(NumericRangeQuery32Test, testRange_2bit) { testRange(2); } -TEST_F(NumericRangeQuery32Test, testInverseRange) -{ +TEST_F(NumericRangeQuery32Test, testInverseRange) { NumericRangeFilterPtr f = NumericRangeFilter::newIntRange(L"field8", 8, 1000, -1000, true, true); EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); f = NumericRangeFilter::newIntRange(L"field8", 8, INT_MAX, INT_MIN, false, false); @@ -366,8 +346,7 @@ TEST_F(NumericRangeQuery32Test, testInverseRange) EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); } -TEST_F(NumericRangeQuery32Test, testOneMatchQuery) -{ +TEST_F(NumericRangeQuery32Test, testOneMatchQuery) { NumericRangeQueryPtr q = NumericRangeQuery::newIntRange(L"ascfield8", 8, 1000, 1000, true, true); EXPECT_EQ(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(), q->getRewriteMethod()); TopDocsPtr topDocs = searcher->search(q, noDocs); @@ -376,88 +355,71 @@ TEST_F(NumericRangeQuery32Test, testOneMatchQuery) EXPECT_EQ(1, sd.size()); } -TEST_F(NumericRangeQuery32Test, testLeftOpenRange_8bit) -{ +TEST_F(NumericRangeQuery32Test, testLeftOpenRange_8bit) { testLeftOpenRange(8); } -TEST_F(NumericRangeQuery32Test, testLeftOpenRange_4bit) -{ +TEST_F(NumericRangeQuery32Test, testLeftOpenRange_4bit) { testLeftOpenRange(4); } -TEST_F(NumericRangeQuery32Test, testLeftOpenRange_2bit) -{ +TEST_F(NumericRangeQuery32Test, testLeftOpenRange_2bit) { testLeftOpenRange(2); } -TEST_F(NumericRangeQuery32Test, testRightOpenRange_8bit) -{ +TEST_F(NumericRangeQuery32Test, testRightOpenRange_8bit) { testRightOpenRange(8); } -TEST_F(NumericRangeQuery32Test, testRightOpenRange_4bit) -{ +TEST_F(NumericRangeQuery32Test, testRightOpenRange_4bit) { testRightOpenRange(4); } -TEST_F(NumericRangeQuery32Test, testRightOpenRange_2bit) -{ +TEST_F(NumericRangeQuery32Test, testRightOpenRange_2bit) { testRightOpenRange(2); } -TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_8bit) -{ +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_8bit) { testRandomTrieAndClassicRangeQuery(8); } -TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_4bit) -{ +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_4bit) { testRandomTrieAndClassicRangeQuery(4); } -TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_2bit) -{ +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_2bit) { testRandomTrieAndClassicRangeQuery(2); } -TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_NoTrie) -{ +TEST_F(NumericRangeQuery32Test, testRandomTrieAndClassicRangeQuery_NoTrie) { testRandomTrieAndClassicRangeQuery(INT_MAX); } -TEST_F(NumericRangeQuery32Test, testRangeSplit_8bit) -{ +TEST_F(NumericRangeQuery32Test, testRangeSplit_8bit) { testRangeSplit(8); } -TEST_F(NumericRangeQuery32Test, testRangeSplit_4bit) -{ +TEST_F(NumericRangeQuery32Test, testRangeSplit_4bit) { testRangeSplit(4); } -TEST_F(NumericRangeQuery32Test, testRangeSplit_2bit) -{ +TEST_F(NumericRangeQuery32Test, testRangeSplit_2bit) { testRangeSplit(2); } -TEST_F(NumericRangeQuery32Test, testSorting_8bit) -{ +TEST_F(NumericRangeQuery32Test, testSorting_8bit) { testSorting(8); } -TEST_F(NumericRangeQuery32Test, testSorting_4bit) -{ +TEST_F(NumericRangeQuery32Test, testSorting_4bit) { testSorting(4); } -TEST_F(NumericRangeQuery32Test, testSorting_2bit) -{ +TEST_F(NumericRangeQuery32Test, testSorting_2bit) { testSorting(2); } -TEST_F(NumericRangeQuery32Test, testEqualsAndHash) -{ +TEST_F(NumericRangeQuery32Test, testEqualsAndHash) { QueryUtils::checkHashEquals(NumericRangeQuery::newIntRange(L"test1", 4, 10, 20, true, true)); QueryUtils::checkHashEquals(NumericRangeQuery::newIntRange(L"test2", 4, 10, 20, false, true)); QueryUtils::checkHashEquals(NumericRangeQuery::newIntRange(L"test3", 4, 10, 20, true, false)); @@ -479,8 +441,7 @@ TEST_F(NumericRangeQuery32Test, testEqualsAndHash) EXPECT_TRUE(!q2->equals(q1)); } -TEST_F(NumericRangeQuery32Test, testEnum) -{ +TEST_F(NumericRangeQuery32Test, testEnum) { int32_t count = 3000; int32_t lower= (distance * 3 / 2) + startOffset; int32_t upper = lower + count * distance + (distance / 3); diff --git a/src/test/search/NumericRangeQuery64Test.cpp b/src/test/search/NumericRangeQuery64Test.cpp index 8f5623e7..703853dc 100644 --- a/src/test/search/NumericRangeQuery64Test.cpp +++ b/src/test/search/NumericRangeQuery64Test.cpp @@ -32,21 +32,17 @@ using namespace Lucene; -class NumericRangeQuery64Test : public LuceneTestFixture -{ +class NumericRangeQuery64Test : public LuceneTestFixture { public: - NumericRangeQuery64Test() - { + NumericRangeQuery64Test() { static bool setupRequired = true; - if (setupRequired) - { + if (setupRequired) { setup(); setupRequired = false; } } - virtual ~NumericRangeQuery64Test() - { + virtual ~NumericRangeQuery64Test() { } protected: @@ -64,8 +60,7 @@ class NumericRangeQuery64Test : public LuceneTestFixture protected: /// One-time setup to initialise static members - void setup() - { + void setup() { // set the theoretical maximum term count for 8bit (see docs for the number) BooleanQuery::setMaxClauseCount(7 * 255 * 2 + 255); @@ -98,8 +93,7 @@ class NumericRangeQuery64Test : public LuceneTestFixture doc->add(ascfield2); // Add a series of noDocs docs with increasing int values - for (int32_t l = 0; l < noDocs; ++l) - { + for (int32_t l = 0; l < noDocs; ++l) { int64_t val = distance * l + startOffset; field8->setLongValue(val); field6->setLongValue(val); @@ -122,8 +116,7 @@ class NumericRangeQuery64Test : public LuceneTestFixture public: /// test for both constant score and boolean query, the other tests only use the constant score mode - void testRange(int32_t precisionStep) - { + void testRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); int32_t count = 3000; int64_t lower = (distance * 3 / 2) + startOffset; @@ -132,34 +125,32 @@ class NumericRangeQuery64Test : public LuceneTestFixture NumericRangeQueryPtr q = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, true, true); NumericRangeFilterPtr f = NumericRangeFilter::newLongRange(field, precisionStep, lower, upper, true, true); int32_t lastTerms = 0; - for (uint8_t i = 0; i < 3; ++i) - { + for (uint8_t i = 0; i < 3; ++i) { TopDocsPtr topDocs; int32_t terms; String type; q->clearTotalNumberOfTerms(); f->clearTotalNumberOfTerms(); - switch (i) - { - case 0: - type = L" (constant score filter rewrite)"; - q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); - topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); - terms = q->getTotalNumberOfTerms(); - break; - case 1: - type = L" (constant score boolean rewrite)"; - q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); - topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); - terms = q->getTotalNumberOfTerms(); - break; - case 2: - type = L" (filter)"; - topDocs = searcher->search(newLucene(), f, noDocs, Sort::INDEXORDER()); - terms = f->getTotalNumberOfTerms(); - break; - default: - return; + switch (i) { + case 0: + type = L" (constant score filter rewrite)"; + q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_FILTER_REWRITE()); + topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); + terms = q->getTotalNumberOfTerms(); + break; + case 1: + type = L" (constant score boolean rewrite)"; + q->setRewriteMethod(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE()); + topDocs = searcher->search(q, FilterPtr(), noDocs, Sort::INDEXORDER()); + terms = q->getTotalNumberOfTerms(); + break; + case 2: + type = L" (filter)"; + topDocs = searcher->search(newLucene(), f, noDocs, Sort::INDEXORDER()); + terms = f->getTotalNumberOfTerms(); + break; + default: + return; } // std::cout << "Found " << terms << " distinct terms in range for field '" << field << "'" << type << "."; Collection sd = topDocs->scoreDocs; @@ -169,14 +160,14 @@ class NumericRangeQuery64Test : public LuceneTestFixture EXPECT_EQ(StringUtils::toString(2 * distance + startOffset), doc->get(field)); doc = searcher->doc(sd[sd.size() - 1]->doc); EXPECT_EQ(StringUtils::toString((1 + count) * distance + startOffset), doc->get(field)); - if (i > 0) + if (i > 0) { EXPECT_EQ(lastTerms, terms); + } lastTerms = terms; } } - void testLeftOpenRange(int32_t precisionStep) - { + void testLeftOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); int32_t count = 3000; // int32_t count = 10; @@ -192,8 +183,7 @@ class NumericRangeQuery64Test : public LuceneTestFixture EXPECT_EQ(StringUtils::toString((count - 1) * distance + startOffset), doc->get(field)); } - void testRightOpenRange(int32_t precisionStep) - { + void testRightOpenRange(int32_t precisionStep) { String field = L"field" + StringUtils::toString(precisionStep); int32_t count = 3000; int64_t lower = (count - 1) * distance + (distance / 3) + startOffset; @@ -208,18 +198,17 @@ class NumericRangeQuery64Test : public LuceneTestFixture EXPECT_EQ(StringUtils::toString((noDocs - 1) * distance + startOffset), doc->get(field)); } - void testRandomTrieAndClassicRangeQuery(int32_t precisionStep) - { + void testRandomTrieAndClassicRangeQuery(int32_t precisionStep) { RandomPtr rnd = newLucene(); String field = L"field" + StringUtils::toString(precisionStep); int32_t termCountT = 0; int32_t termCountC = 0; - for (int32_t i = 0; i < 50; ++i) - { + for (int32_t i = 0; i < 50; ++i) { int64_t lower = (int64_t)(rnd->nextDouble() * noDocs * distance) + startOffset; int64_t upper = (int64_t)(rnd->nextDouble() * noDocs * distance) + startOffset; - if (lower > upper) + if (lower > upper) { std::swap(lower, upper); + } // test inclusive range NumericRangeQueryPtr tq = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, true, true); TermRangeQueryPtr cq = newLucene(field, NumericUtils::longToPrefixCoded(lower), NumericUtils::longToPrefixCoded(upper), true, true); @@ -253,21 +242,21 @@ class NumericRangeQuery64Test : public LuceneTestFixture termCountT += tq->getTotalNumberOfTerms(); termCountC += cq->getTotalNumberOfTerms(); } - if (precisionStep == INT_MAX) + if (precisionStep == INT_MAX) { EXPECT_EQ(termCountT, termCountC); + } } - void testRangeSplit(int32_t precisionStep) - { + void testRangeSplit(int32_t precisionStep) { RandomPtr rnd = newLucene(); String field = L"ascfield" + StringUtils::toString(precisionStep); // 50 random tests - for (int32_t i = 0; i < 50; ++i) - { + for (int32_t i = 0; i < 50; ++i) { int64_t lower = (int64_t)(rnd->nextDouble() * noDocs - noDocs / 2.0); int64_t upper = (int64_t)(rnd->nextDouble() * noDocs - noDocs / 2.0); - if (lower > upper) + if (lower > upper) { std::swap(lower, upper); + } // test inclusive range QueryPtr tq = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, true, true); TopDocsPtr tTopDocs = searcher->search(tq, 1); @@ -287,8 +276,7 @@ class NumericRangeQuery64Test : public LuceneTestFixture } } - void testDoubleRange(int32_t precisionStep) - { + void testDoubleRange(int32_t precisionStep) { String field = L"ascfield" + StringUtils::toString(precisionStep); int64_t lower = -1000; int64_t upper = +2000; @@ -302,26 +290,25 @@ class NumericRangeQuery64Test : public LuceneTestFixture EXPECT_EQ(upper - lower + 1, tTopDocs->totalHits); } - void testSorting(int32_t precisionStep) - { + void testSorting(int32_t precisionStep) { RandomPtr rnd = newLucene(); String field = L"field" + StringUtils::toString(precisionStep); // 10 random tests, the index order is ascending, so using a reverse sort field should return descending documents - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { int64_t lower = (int64_t)(rnd->nextDouble() * noDocs * distance) + startOffset; int64_t upper = (int64_t)(rnd->nextDouble() * noDocs * distance) + startOffset; - if (lower > upper) + if (lower > upper) { std::swap(lower, upper); + } QueryPtr tq = NumericRangeQuery::newLongRange(field, precisionStep, lower, upper, true, true); TopDocsPtr topDocs = searcher->search(tq, FilterPtr(), noDocs, newLucene(newLucene(field, SortField::LONG, true))); - if (topDocs->totalHits == 0) + if (topDocs->totalHits == 0) { continue; + } Collection sd = topDocs->scoreDocs; EXPECT_TRUE(sd); int64_t last = StringUtils::toInt(searcher->doc(sd[0]->doc)->get(field)); - for (int32_t j = 1; j < sd.size(); ++j) - { + for (int32_t j = 1; j < sd.size(); ++j) { int64_t act = StringUtils::toLong(searcher->doc(sd[j]->doc)->get(field)); EXPECT_TRUE(last > act); last = act; @@ -342,28 +329,23 @@ const int32_t NumericRangeQuery64Test::noDocs = 10000; RAMDirectoryPtr NumericRangeQuery64Test::directory; IndexSearcherPtr NumericRangeQuery64Test::searcher; -TEST_F(NumericRangeQuery64Test, testRange_8bit) -{ +TEST_F(NumericRangeQuery64Test, testRange_8bit) { testRange(8); } -TEST_F(NumericRangeQuery64Test, testRange_6bit) -{ +TEST_F(NumericRangeQuery64Test, testRange_6bit) { testRange(6); } -TEST_F(NumericRangeQuery64Test, testRange_4bit) -{ +TEST_F(NumericRangeQuery64Test, testRange_4bit) { testRange(4); } -TEST_F(NumericRangeQuery64Test, testRange_2bit) -{ +TEST_F(NumericRangeQuery64Test, testRange_2bit) { testRange(2); } -TEST_F(NumericRangeQuery64Test, testInverseRange) -{ +TEST_F(NumericRangeQuery64Test, testInverseRange) { NumericRangeFilterPtr f = NumericRangeFilter::newLongRange(L"field8", 8, 1000, -1000, true, true); EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); f = NumericRangeFilter::newLongRange(L"field8", 8, LLONG_MAX, LLONG_MIN, false, false); @@ -372,8 +354,7 @@ TEST_F(NumericRangeQuery64Test, testInverseRange) EXPECT_EQ(f->getDocIdSet(searcher->getIndexReader()), DocIdSet::EMPTY_DOCIDSET()); } -TEST_F(NumericRangeQuery64Test, testOneMatchQuery) -{ +TEST_F(NumericRangeQuery64Test, testOneMatchQuery) { NumericRangeQueryPtr q = NumericRangeQuery::newLongRange(L"ascfield8", 8, 1000, 1000, true, true); EXPECT_EQ(MultiTermQuery::CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE(), q->getRewriteMethod()); TopDocsPtr topDocs = searcher->search(q, noDocs); @@ -382,133 +363,107 @@ TEST_F(NumericRangeQuery64Test, testOneMatchQuery) EXPECT_EQ(1, sd.size()); } -TEST_F(NumericRangeQuery64Test, testLeftOpenRange_8bit) -{ +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_8bit) { testLeftOpenRange(8); } -TEST_F(NumericRangeQuery64Test, testLeftOpenRange_6bit) -{ +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_6bit) { testLeftOpenRange(6); } -TEST_F(NumericRangeQuery64Test, testLeftOpenRange_4bit) -{ +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_4bit) { testLeftOpenRange(4); } -TEST_F(NumericRangeQuery64Test, testLeftOpenRange_2bit) -{ +TEST_F(NumericRangeQuery64Test, testLeftOpenRange_2bit) { testLeftOpenRange(2); } -TEST_F(NumericRangeQuery64Test, testRightOpenRange_8bit) -{ +TEST_F(NumericRangeQuery64Test, testRightOpenRange_8bit) { testRightOpenRange(8); } -TEST_F(NumericRangeQuery64Test, testRightOpenRange_6bit) -{ +TEST_F(NumericRangeQuery64Test, testRightOpenRange_6bit) { testRightOpenRange(6); } -TEST_F(NumericRangeQuery64Test, testRightOpenRange_4bit) -{ +TEST_F(NumericRangeQuery64Test, testRightOpenRange_4bit) { testRightOpenRange(4); } -TEST_F(NumericRangeQuery64Test, testRightOpenRange_2bit) -{ +TEST_F(NumericRangeQuery64Test, testRightOpenRange_2bit) { testRightOpenRange(2); } -TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_8bit) -{ +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_8bit) { testRandomTrieAndClassicRangeQuery(8); } -TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_6bit) -{ +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_6bit) { testRandomTrieAndClassicRangeQuery(6); } -TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_4bit) -{ +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_4bit) { testRandomTrieAndClassicRangeQuery(4); } -TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_2bit) -{ +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_2bit) { testRandomTrieAndClassicRangeQuery(2); } -TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_NoTrie) -{ +TEST_F(NumericRangeQuery64Test, testRandomTrieAndClassicRangeQuery_NoTrie) { testRandomTrieAndClassicRangeQuery(INT_MAX); } -TEST_F(NumericRangeQuery64Test, testRangeSplit_8bit) -{ +TEST_F(NumericRangeQuery64Test, testRangeSplit_8bit) { testRangeSplit(8); } -TEST_F(NumericRangeQuery64Test, testRangeSplit_6bit) -{ +TEST_F(NumericRangeQuery64Test, testRangeSplit_6bit) { testRangeSplit(6); } -TEST_F(NumericRangeQuery64Test, testRangeSplit_4bit) -{ +TEST_F(NumericRangeQuery64Test, testRangeSplit_4bit) { testRangeSplit(4); } -TEST_F(NumericRangeQuery64Test, testRangeSplit_2bit) -{ +TEST_F(NumericRangeQuery64Test, testRangeSplit_2bit) { testRangeSplit(2); } -TEST_F(NumericRangeQuery64Test, testDoubleRange_8bit) -{ +TEST_F(NumericRangeQuery64Test, testDoubleRange_8bit) { testDoubleRange(8); } -TEST_F(NumericRangeQuery64Test, testDoubleRange_6bit) -{ +TEST_F(NumericRangeQuery64Test, testDoubleRange_6bit) { testDoubleRange(6); } -TEST_F(NumericRangeQuery64Test, testDoubleRange_4bit) -{ +TEST_F(NumericRangeQuery64Test, testDoubleRange_4bit) { testDoubleRange(4); } -TEST_F(NumericRangeQuery64Test, testDoubleRange_2bit) -{ +TEST_F(NumericRangeQuery64Test, testDoubleRange_2bit) { testDoubleRange(2); } -TEST_F(NumericRangeQuery64Test, testSorting_8bit) -{ +TEST_F(NumericRangeQuery64Test, testSorting_8bit) { testSorting(8); } -TEST_F(NumericRangeQuery64Test, testSorting_6bit) -{ +TEST_F(NumericRangeQuery64Test, testSorting_6bit) { testSorting(6); } -TEST_F(NumericRangeQuery64Test, testSorting_4bit) -{ +TEST_F(NumericRangeQuery64Test, testSorting_4bit) { testSorting(4); } -TEST_F(NumericRangeQuery64Test, testSorting_2bit) -{ +TEST_F(NumericRangeQuery64Test, testSorting_2bit) { testSorting(2); } -TEST_F(NumericRangeQuery64Test, testEqualsAndHash) -{ +TEST_F(NumericRangeQuery64Test, testEqualsAndHash) { QueryUtils::checkHashEquals(NumericRangeQuery::newLongRange(L"test1", 4, 10, 20, true, true)); QueryUtils::checkHashEquals(NumericRangeQuery::newLongRange(L"test2", 4, 10, 20, false, true)); QueryUtils::checkHashEquals(NumericRangeQuery::newLongRange(L"test3", 4, 10, 20, true, false)); diff --git a/src/test/search/ParallelMultiSearcherTest.cpp b/src/test/search/ParallelMultiSearcherTest.cpp index c497c483..eb52a7d1 100644 --- a/src/test/search/ParallelMultiSearcherTest.cpp +++ b/src/test/search/ParallelMultiSearcherTest.cpp @@ -30,31 +30,29 @@ using namespace Lucene; typedef LuceneTestFixture ParallelMultiSearcherTest; -static MultiSearcherPtr getMultiSearcherInstance(Collection searchers) -{ +static MultiSearcherPtr getMultiSearcherInstance(Collection searchers) { return newLucene(searchers); } -static DocumentPtr createDocument(const String& contents1, const String& contents2) -{ +static DocumentPtr createDocument(const String& contents1, const String& contents2) { DocumentPtr document = newLucene(); document->add(newLucene(L"contents", contents1, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); document->add(newLucene(L"other", L"other contents", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - if (!contents2.empty()) + if (!contents2.empty()) { document->add(newLucene(L"contents", contents2, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + } return document; } -static void initIndex(const DirectoryPtr& directory, int32_t numDocs, bool create, const String& contents2) -{ +static void initIndex(const DirectoryPtr& directory, int32_t numDocs, bool create, const String& contents2) { IndexWriterPtr indexWriter = newLucene(directory, newLucene(), create, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < numDocs; ++i) + for (int32_t i = 0; i < numDocs; ++i) { indexWriter->addDocument(createDocument(L"doc" + StringUtils::toString(i), contents2)); + } indexWriter->close(); } -TEST_F(ParallelMultiSearcherTest, testEmptyIndex) -{ +TEST_F(ParallelMultiSearcherTest, testEmptyIndex) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); DirectoryPtr indexStoreB = newLucene(); @@ -110,8 +108,9 @@ TEST_F(ParallelMultiSearcherTest, testEmptyIndex) EXPECT_EQ(3, hits.size()); // iterating over the hit documents - for (int32_t i = 0; i < hits.size(); ++i) + for (int32_t i = 0; i < hits.size(); ++i) { mSearcher->doc(hits[i]->doc); + } mSearcher->close(); @@ -135,8 +134,9 @@ TEST_F(ParallelMultiSearcherTest, testEmptyIndex) EXPECT_EQ(4, hits2.size()); // iterating over the hit documents - for (int32_t i = 0; i < hits2.size(); ++i) + for (int32_t i = 0; i < hits2.size(); ++i) { mSearcher2->doc(hits2[i]->doc); + } // test the subSearcher() method QueryPtr subSearcherQuery = parser->parse(L"id:doc1"); @@ -175,16 +175,16 @@ TEST_F(ParallelMultiSearcherTest, testEmptyIndex) EXPECT_EQ(3, hits3.size()); // iterating over the hit documents - for (int32_t i = 0; i < hits3.size(); ++i) + for (int32_t i = 0; i < hits3.size(); ++i) { mSearcher3->doc(hits3[i]->doc); + } mSearcher3->close(); indexStoreA->close(); indexStoreB->close(); } -TEST_F(ParallelMultiSearcherTest, testFieldSelector) -{ +TEST_F(ParallelMultiSearcherTest, testFieldSelector) { RAMDirectoryPtr ramDirectory1 = newLucene(); RAMDirectoryPtr ramDirectory2 = newLucene(); @@ -226,8 +226,7 @@ TEST_F(ParallelMultiSearcherTest, testFieldSelector) EXPECT_TRUE(value.empty()); } -TEST_F(ParallelMultiSearcherTest, testNormalization) -{ +TEST_F(ParallelMultiSearcherTest, testNormalization) { int32_t numDocs = 10; QueryPtr query = newLucene(newLucene(L"contents", L"doc0")); @@ -287,50 +286,42 @@ TEST_F(ParallelMultiSearcherTest, testNormalization) ramDirectory2->close(); } -namespace TestCustomSimilarity -{ - class CustomSimilarity : public DefaultSimilarity - { - public: - virtual ~CustomSimilarity() - { - } - - public: - virtual double idf(int32_t docFreq, int32_t numDocs) - { - return 100.0; - } - - virtual double coord(int32_t overlap, int32_t maxOverlap) - { - return 1.0; - } - - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { - return 1.0; - } - - virtual double queryNorm(double sumOfSquaredWeights) - { - return 1.0; - } - - virtual double sloppyFreq(int32_t distance) - { - return 1.0; - } - - virtual double tf(double freq) - { - return 1.0; - } - }; +namespace TestCustomSimilarity { + +class CustomSimilarity : public DefaultSimilarity { +public: + virtual ~CustomSimilarity() { + } + +public: + virtual double idf(int32_t docFreq, int32_t numDocs) { + return 100.0; + } + + virtual double coord(int32_t overlap, int32_t maxOverlap) { + return 1.0; + } + + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { + return 1.0; + } + + virtual double queryNorm(double sumOfSquaredWeights) { + return 1.0; + } + + virtual double sloppyFreq(int32_t distance) { + return 1.0; + } + + virtual double tf(double freq) { + return 1.0; + } +}; + } -TEST_F(ParallelMultiSearcherTest, testCustomSimilarity) -{ +TEST_F(ParallelMultiSearcherTest, testCustomSimilarity) { RAMDirectoryPtr dir = newLucene(); initIndex(dir, 10, true, L"x"); // documents with two tokens "doc0" and "x", "doc1" and x, etc... IndexSearcherPtr searcher = newLucene(dir, true); @@ -354,8 +345,7 @@ TEST_F(ParallelMultiSearcherTest, testCustomSimilarity) EXPECT_NEAR(score1, scoreN, 1e-6); } -TEST_F(ParallelMultiSearcherTest, testDocFreq) -{ +TEST_F(ParallelMultiSearcherTest, testDocFreq) { RAMDirectoryPtr dir1 = newLucene(); RAMDirectoryPtr dir2 = newLucene(); diff --git a/src/test/search/PhrasePrefixQueryTest.cpp b/src/test/search/PhrasePrefixQueryTest.cpp index 85195c80..e6d21deb 100644 --- a/src/test/search/PhrasePrefixQueryTest.cpp +++ b/src/test/search/PhrasePrefixQueryTest.cpp @@ -24,8 +24,7 @@ using namespace Lucene; typedef LuceneTestFixture PhrasePrefixQueryTest; -TEST_F(PhrasePrefixQueryTest, testPhrasePrefix) -{ +TEST_F(PhrasePrefixQueryTest, testPhrasePrefix) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc1 = newLucene(); @@ -59,12 +58,11 @@ TEST_F(PhrasePrefixQueryTest, testPhrasePrefix) // this TermEnum gives "piccadilly", "pie" and "pizza". String prefix = L"pi"; TermEnumPtr te = ir->terms(newLucene(L"body", prefix + L"*")); - do - { - if (boost::starts_with(te->term()->text(), prefix)) + do { + if (boost::starts_with(te->term()->text(), prefix)) { termsWithPrefix.add(te->term()); - } - while (te->next()); + } + } while (te->next()); query1->add(termsWithPrefix); query2->add(termsWithPrefix); diff --git a/src/test/search/PhraseQueryTest.cpp b/src/test/search/PhraseQueryTest.cpp index d3974233..648f0f20 100644 --- a/src/test/search/PhraseQueryTest.cpp +++ b/src/test/search/PhraseQueryTest.cpp @@ -26,30 +26,24 @@ using namespace Lucene; -class PhraseQueryAnalyzer : public Analyzer -{ +class PhraseQueryAnalyzer : public Analyzer { public: - virtual ~PhraseQueryAnalyzer() - { + virtual ~PhraseQueryAnalyzer() { } public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } - virtual int32_t getPositionIncrementGap(const String& fieldName) - { + virtual int32_t getPositionIncrementGap(const String& fieldName) { return 100; } }; -class PhraseQueryTest : public LuceneTestFixture -{ +class PhraseQueryTest : public LuceneTestFixture { public: - PhraseQueryTest() - { + PhraseQueryTest() { directory = newLucene(); AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -77,8 +71,7 @@ class PhraseQueryTest : public LuceneTestFixture query = newLucene(); } - virtual ~PhraseQueryTest() - { + virtual ~PhraseQueryTest() { searcher->close(); directory->close(); } @@ -95,8 +88,7 @@ class PhraseQueryTest : public LuceneTestFixture const double PhraseQueryTest::SCORE_COMP_THRESH = 1e-6f; -TEST_F(PhraseQueryTest, testNotCloseEnough) -{ +TEST_F(PhraseQueryTest, testNotCloseEnough) { query->setSlop(2); query->add(newLucene(L"field", L"one")); query->add(newLucene(L"field", L"five")); @@ -105,8 +97,7 @@ TEST_F(PhraseQueryTest, testNotCloseEnough) QueryUtils::check(query, searcher); } -TEST_F(PhraseQueryTest, testBarelyCloseEnough) -{ +TEST_F(PhraseQueryTest, testBarelyCloseEnough) { query->setSlop(3); query->add(newLucene(L"field", L"one")); query->add(newLucene(L"field", L"five")); @@ -116,8 +107,7 @@ TEST_F(PhraseQueryTest, testBarelyCloseEnough) } /// Ensures slop of 0 works for exact matches, but not reversed -TEST_F(PhraseQueryTest, testExact) -{ +TEST_F(PhraseQueryTest, testExact) { // slop is zero by default query->add(newLucene(L"field", L"four")); query->add(newLucene(L"field", L"five")); @@ -133,8 +123,7 @@ TEST_F(PhraseQueryTest, testExact) QueryUtils::check(query, searcher); } -TEST_F(PhraseQueryTest, testSlop1) -{ +TEST_F(PhraseQueryTest, testSlop1) { // Ensures slop of 1 works with terms in order. query->setSlop(1); query->add(newLucene(L"field", L"one")); @@ -154,8 +143,7 @@ TEST_F(PhraseQueryTest, testSlop1) } /// As long as slop is at least 2, terms can be reversed -TEST_F(PhraseQueryTest, testOrderDoesntMatter) -{ +TEST_F(PhraseQueryTest, testOrderDoesntMatter) { // must be at least two for reverse order match query->setSlop(2); query->add(newLucene(L"field", L"two")); @@ -174,8 +162,7 @@ TEST_F(PhraseQueryTest, testOrderDoesntMatter) } /// Slop is the total number of positional moves allowed to line up a phrase -TEST_F(PhraseQueryTest, testMulipleTerms) -{ +TEST_F(PhraseQueryTest, testMulipleTerms) { query->setSlop(2); query->add(newLucene(L"field", L"one")); query->add(newLucene(L"field", L"three")); @@ -199,8 +186,7 @@ TEST_F(PhraseQueryTest, testMulipleTerms) QueryUtils::check(query, searcher); } -TEST_F(PhraseQueryTest, testPhraseQueryWithStopAnalyzer) -{ +TEST_F(PhraseQueryTest, testPhraseQueryWithStopAnalyzer) { RAMDirectoryPtr directory = newLucene(); StopAnalyzerPtr stopAnalyzer = newLucene(LuceneVersion::LUCENE_24); IndexWriterPtr writer = newLucene(directory, stopAnalyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -230,8 +216,7 @@ TEST_F(PhraseQueryTest, testPhraseQueryWithStopAnalyzer) searcher->close(); } -TEST_F(PhraseQueryTest, testPhraseQueryInConjunctionScorer) -{ +TEST_F(PhraseQueryTest, testPhraseQueryInConjunctionScorer) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -311,8 +296,7 @@ TEST_F(PhraseQueryTest, testPhraseQueryInConjunctionScorer) directory->close(); } -TEST_F(PhraseQueryTest, testSlopScoring) -{ +TEST_F(PhraseQueryTest, testSlopScoring) { DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -348,8 +332,7 @@ TEST_F(PhraseQueryTest, testSlopScoring) QueryUtils::check(query, searcher); } -TEST_F(PhraseQueryTest, testToString) -{ +TEST_F(PhraseQueryTest, testToString) { StopAnalyzerPtr analyzer = newLucene(LuceneVersion::LUCENE_CURRENT); QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, L"field", analyzer); qp->setEnablePositionIncrements(true); @@ -359,8 +342,7 @@ TEST_F(PhraseQueryTest, testToString) EXPECT_EQ(L"field:\"? hi|hello ? ? ? test\"", q->toString()); } -TEST_F(PhraseQueryTest, testWrappedPhrase) -{ +TEST_F(PhraseQueryTest, testWrappedPhrase) { query->add(newLucene(L"repeated", L"first")); query->add(newLucene(L"repeated", L"part")); query->add(newLucene(L"repeated", L"second")); @@ -379,8 +361,7 @@ TEST_F(PhraseQueryTest, testWrappedPhrase) } /// work on two docs like this: "phrase exist notexist exist found" -TEST_F(PhraseQueryTest, testNonExistingPhrase) -{ +TEST_F(PhraseQueryTest, testNonExistingPhrase) { // phrase without repetitions that exists in 2 docs query->add(newLucene(L"nonexist", L"phrase")); query->add(newLucene(L"nonexist", L"notexist")); @@ -432,8 +413,7 @@ TEST_F(PhraseQueryTest, testNonExistingPhrase) /// Phrase of size 2 occurring twice, once in order and once in reverse, because doc is a palindrome, is counted twice. /// Also, in this case order in query does not matter. Also, when an exact match is found, both sloppy scorer and /// exact scorer scores the same. -TEST_F(PhraseQueryTest, testPalindrome2) -{ +TEST_F(PhraseQueryTest, testPalindrome2) { // search on non palindrome, find phrase with no slop, using exact phrase scorer query->setSlop(0); // to use exact phrase scorer query->add(newLucene(L"field", L"two")); @@ -476,8 +456,7 @@ TEST_F(PhraseQueryTest, testPalindrome2) /// Phrase of size 3 occurring twice, once in order and once in reverse, because doc is a palindrome, is counted twice. /// Also, in this case order in query does not matter. Also, when an exact match is found, both sloppy scorer and exact /// scorer scores the same. -TEST_F(PhraseQueryTest, testPalindrome3) -{ +TEST_F(PhraseQueryTest, testPalindrome3) { // search on non palindrome, find phrase with no slop, using exact phrase scorer query->setSlop(0); // to use exact phrase scorer query->add(newLucene(L"field", L"one")); @@ -517,8 +496,7 @@ TEST_F(PhraseQueryTest, testPalindrome3) QueryUtils::check(query, searcher); } -TEST_F(PhraseQueryTest, testEmptyPhraseQuery) -{ +TEST_F(PhraseQueryTest, testEmptyPhraseQuery) { BooleanQueryPtr q2 = newLucene(); q2->add(newLucene(), BooleanClause::MUST); EXPECT_EQ(q2->toString(), L"+\"?\""); diff --git a/src/test/search/PositionIncrementTest.cpp b/src/test/search/PositionIncrementTest.cpp index 21356b0a..b2dcd130 100644 --- a/src/test/search/PositionIncrementTest.cpp +++ b/src/test/search/PositionIncrementTest.cpp @@ -41,91 +41,81 @@ using namespace Lucene; typedef LuceneTestFixture PositionIncrementTest; -namespace TestSetPosition -{ - class SetPositionTokenStream : public TokenStream - { - public: - SetPositionTokenStream() - { - TOKENS = newCollection(L"1", L"2", L"3", L"4", L"5"); - INCREMENTS = newCollection(0, 2, 1, 0, 1); - i = 0; - - posIncrAtt = addAttribute(); - termAtt = addAttribute(); - offsetAtt = addAttribute(); - } +namespace TestSetPosition { + +class SetPositionTokenStream : public TokenStream { +public: + SetPositionTokenStream() { + TOKENS = newCollection(L"1", L"2", L"3", L"4", L"5"); + INCREMENTS = newCollection(0, 2, 1, 0, 1); + i = 0; + + posIncrAtt = addAttribute(); + termAtt = addAttribute(); + offsetAtt = addAttribute(); + } - virtual ~SetPositionTokenStream() - { - } + virtual ~SetPositionTokenStream() { + } - protected: - Collection TOKENS; - Collection INCREMENTS; - int32_t i; - - PositionIncrementAttributePtr posIncrAtt; - TermAttributePtr termAtt; - OffsetAttributePtr offsetAtt; - - public: - virtual bool incrementToken() - { - if (i == TOKENS.size()) - return false; - clearAttributes(); - termAtt->setTermBuffer(TOKENS[i]); - offsetAtt->setOffset(i, i); - posIncrAtt->setPositionIncrement(INCREMENTS[i]); - ++i; - return true; - } - }; +protected: + Collection TOKENS; + Collection INCREMENTS; + int32_t i; - class SetPositionAnalyzer : public Analyzer - { - public: - virtual ~SetPositionAnalyzer() - { - } + PositionIncrementAttributePtr posIncrAtt; + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - return newLucene(); - } - }; - - class StopWhitespaceAnalyzer : public Analyzer - { - public: - StopWhitespaceAnalyzer(bool enablePositionIncrements) - { - this->enablePositionIncrements = enablePositionIncrements; - this->a = newLucene(); +public: + virtual bool incrementToken() { + if (i == TOKENS.size()) { + return false; } + clearAttributes(); + termAtt->setTermBuffer(TOKENS[i]); + offsetAtt->setOffset(i, i); + posIncrAtt->setPositionIncrement(INCREMENTS[i]); + ++i; + return true; + } +}; - virtual ~StopWhitespaceAnalyzer() - { - } +class SetPositionAnalyzer : public Analyzer { +public: + virtual ~SetPositionAnalyzer() { + } - public: - bool enablePositionIncrements; - WhitespaceAnalyzerPtr a; +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + return newLucene(); + } +}; + +class StopWhitespaceAnalyzer : public Analyzer { +public: + StopWhitespaceAnalyzer(bool enablePositionIncrements) { + this->enablePositionIncrements = enablePositionIncrements; + this->a = newLucene(); + } + + virtual ~StopWhitespaceAnalyzer() { + } + +public: + bool enablePositionIncrements; + WhitespaceAnalyzerPtr a; + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr ts = a->tokenStream(fieldName, reader); + return newLucene(enablePositionIncrements, ts, newLucene(newCollection(L"stop"), true)); + } +}; - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr ts = a->tokenStream(fieldName, reader); - return newLucene(enablePositionIncrements, ts, newLucene(newCollection(L"stop"), true)); - } - }; } -TEST_F(PositionIncrementTest, testSetPosition) -{ +TEST_F(PositionIncrementTest, testSetPosition) { AnalyzerPtr analyzer = newLucene(); DirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -256,72 +246,64 @@ TEST_F(PositionIncrementTest, testSetPosition) EXPECT_EQ(1, hits.size()); } -namespace TestPayloadsPos0 -{ - class TestPayloadFilter : public TokenFilter - { - public: - TestPayloadFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) - { - this->fieldName = fieldName; - this->pos = 0; - this->i = 0; - this->posIncrAttr = input->addAttribute(); - this->payloadAttr = input->addAttribute(); - this->termAttr = input->addAttribute(); - } +namespace TestPayloadsPos0 { + +class TestPayloadFilter : public TokenFilter { +public: + TestPayloadFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { + this->fieldName = fieldName; + this->pos = 0; + this->i = 0; + this->posIncrAttr = input->addAttribute(); + this->payloadAttr = input->addAttribute(); + this->termAttr = input->addAttribute(); + } - virtual ~TestPayloadFilter() - { - } + virtual ~TestPayloadFilter() { + } - public: - String fieldName; - int32_t pos; - int32_t i; - - PositionIncrementAttributePtr posIncrAttr; - PayloadAttributePtr payloadAttr; - TermAttributePtr termAttr; - - public: - virtual bool incrementToken() - { - if (input->incrementToken()) - { - String payloadData = L"pos: " + StringUtils::toString(pos); - ByteArray data = ByteArray::newInstance(payloadData.length() * sizeof(wchar_t)); - std::wcsncpy((wchar_t*)data.get(), payloadData.c_str(), payloadData.length()); - payloadAttr->setPayload(newLucene(data)); - int32_t posIncr = i % 2 == 1 ? 1 : 0; - posIncrAttr->setPositionIncrement(posIncr); - pos += posIncr; - ++i; - return true; - } - else - return false; +public: + String fieldName; + int32_t pos; + int32_t i; + + PositionIncrementAttributePtr posIncrAttr; + PayloadAttributePtr payloadAttr; + TermAttributePtr termAttr; + +public: + virtual bool incrementToken() { + if (input->incrementToken()) { + String payloadData = L"pos: " + StringUtils::toString(pos); + ByteArray data = ByteArray::newInstance(payloadData.length() * sizeof(wchar_t)); + std::wcsncpy((wchar_t*)data.get(), payloadData.c_str(), payloadData.length()); + payloadAttr->setPayload(newLucene(data)); + int32_t posIncr = i % 2 == 1 ? 1 : 0; + posIncrAttr->setPositionIncrement(posIncr); + pos += posIncr; + ++i; + return true; + } else { + return false; } - }; + } +}; - class TestPayloadAnalyzer : public Analyzer - { - public: - virtual ~TestPayloadAnalyzer() - { - } +class TestPayloadAnalyzer : public Analyzer { +public: + virtual ~TestPayloadAnalyzer() { + } + +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(reader); + return newLucene(result, fieldName); + } +}; - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(reader); - return newLucene(result, fieldName); - } - }; } -TEST_F(PositionIncrementTest, testPayloadsPos0) -{ +TEST_F(PositionIncrementTest, testPayloadsPos0) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -355,11 +337,11 @@ TEST_F(PositionIncrementTest, testPayloadsPos0) count = 0; bool sawZero = false; SpansPtr pspans = snq->getSpans(is->getIndexReader()); - while (pspans->next()) - { + while (pspans->next()) { Collection payloads = pspans->getPayload(); - if (pspans->start() == 0) + if (pspans->start() == 0) { sawZero = true; + } count += payloads.size(); } @@ -369,11 +351,11 @@ TEST_F(PositionIncrementTest, testPayloadsPos0) SpansPtr spans = snq->getSpans(is->getIndexReader()); count = 0; sawZero = false; - while (spans->next()) - { + while (spans->next()) { ++count; - if (spans->start() == 0) + if (spans->start() == 0) { sawZero = true; + } } EXPECT_EQ(4, count); @@ -383,11 +365,11 @@ TEST_F(PositionIncrementTest, testPayloadsPos0) PayloadSpanUtilPtr psu = newLucene(is->getIndexReader()); Collection pls = psu->getPayloadsForQuery(snq); count = pls.size(); - for (Collection::iterator it = pls.begin(); it != pls.end(); ++it) - { + for (Collection::iterator it = pls.begin(); it != pls.end(); ++it) { String s = String((wchar_t*)it->get(), it->size() / sizeof(wchar_t)); - if (s == L"pos: 0") + if (s == L"pos: 0") { sawZero = true; + } } EXPECT_EQ(5, count); diff --git a/src/test/search/PositiveScoresOnlyCollectorTest.cpp b/src/test/search/PositiveScoresOnlyCollectorTest.cpp index 823d1101..b60b7d9c 100644 --- a/src/test/search/PositiveScoresOnlyCollectorTest.cpp +++ b/src/test/search/PositiveScoresOnlyCollectorTest.cpp @@ -16,51 +16,44 @@ using namespace Lucene; typedef LuceneTestFixture PositiveScoresOnlyCollectorTest; -namespace TestNegativeScores -{ - class SimpleScorer : public Scorer - { - public: - SimpleScorer(Collection scores) : Scorer(SimilarityPtr()) - { - this->scores = scores; - idx = -1; - } +namespace TestNegativeScores { - virtual ~SimpleScorer() - { - } +class SimpleScorer : public Scorer { +public: + SimpleScorer(Collection scores) : Scorer(SimilarityPtr()) { + this->scores = scores; + idx = -1; + } - public: - int32_t idx; - Collection scores; + virtual ~SimpleScorer() { + } - public: - virtual double score() - { - return idx == scores.size() ? std::numeric_limits::quiet_NaN() : scores[idx]; - } +public: + int32_t idx; + Collection scores; - virtual int32_t docID() - { - return idx; - } +public: + virtual double score() { + return idx == scores.size() ? std::numeric_limits::quiet_NaN() : scores[idx]; + } - virtual int32_t nextDoc() - { - return ++idx != scores.size() ? idx : DocIdSetIterator::NO_MORE_DOCS; - } + virtual int32_t docID() { + return idx; + } + + virtual int32_t nextDoc() { + return ++idx != scores.size() ? idx : DocIdSetIterator::NO_MORE_DOCS; + } + + virtual int32_t advance(int32_t target) { + idx = target; + return idx < scores.size() ? idx : DocIdSetIterator::NO_MORE_DOCS; + } +}; - virtual int32_t advance(int32_t target) - { - idx = target; - return idx < scores.size() ? idx : DocIdSetIterator::NO_MORE_DOCS; - } - }; } -TEST_F(PositiveScoresOnlyCollectorTest, testNegativeScores) -{ +TEST_F(PositiveScoresOnlyCollectorTest, testNegativeScores) { // The scores must have positive as well as negative values Collection scores = Collection::newInstance(); scores.add(0.7767749); @@ -82,22 +75,24 @@ TEST_F(PositiveScoresOnlyCollectorTest, testNegativeScores) // <= 0 scores are indeed filtered. int32_t numPositiveScores = 0; - for (int32_t i = 0; i < scores.size(); ++i) - { - if (scores[i] > 0) + for (int32_t i = 0; i < scores.size(); ++i) { + if (scores[i] > 0) { ++numPositiveScores; + } } ScorerPtr s = newLucene(scores); TopDocsCollectorPtr tdc = TopScoreDocCollector::create(scores.size(), true); CollectorPtr c = newLucene(tdc); c->setScorer(s); - while (s->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) + while (s->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) { c->collect(0); + } TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; EXPECT_EQ(numPositiveScores, td->totalHits); - for (int32_t i = 0; i < sd.size(); ++i) + for (int32_t i = 0; i < sd.size(); ++i) { EXPECT_TRUE(sd[i]->score > 0); + } } diff --git a/src/test/search/PrefixFilterTest.cpp b/src/test/search/PrefixFilterTest.cpp index 1adaeec7..309a229d 100644 --- a/src/test/search/PrefixFilterTest.cpp +++ b/src/test/search/PrefixFilterTest.cpp @@ -22,19 +22,17 @@ using namespace Lucene; typedef LuceneTestFixture PrefixFilterTest; -TEST_F(PrefixFilterTest, testPrefixFilter) -{ +TEST_F(PrefixFilterTest, testPrefixFilter) { RAMDirectoryPtr directory = newLucene(); Collection categories = newCollection( - L"/Computers/Linux", - L"/Computers/Mac/One", - L"/Computers/Mac/Two", - L"/Computers/Windows" - ); + L"/Computers/Linux", + L"/Computers/Mac/One", + L"/Computers/Mac/Two", + L"/Computers/Windows" + ); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < categories.size(); ++i) - { + for (int32_t i = 0; i < categories.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"category", categories[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); diff --git a/src/test/search/PrefixInBooleanQueryTest.cpp b/src/test/search/PrefixInBooleanQueryTest.cpp index 0781b631..5918d48e 100644 --- a/src/test/search/PrefixInBooleanQueryTest.cpp +++ b/src/test/search/PrefixInBooleanQueryTest.cpp @@ -20,16 +20,13 @@ using namespace Lucene; -class PrefixInBooleanQueryTest : public LuceneTestFixture -{ +class PrefixInBooleanQueryTest : public LuceneTestFixture { public: - PrefixInBooleanQueryTest() - { + PrefixInBooleanQueryTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 5137; ++i) - { + for (int32_t i = 0; i < 5137; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD, L"meaninglessnames", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); @@ -40,8 +37,7 @@ class PrefixInBooleanQueryTest : public LuceneTestFixture writer->addDocument(doc); } - for (int32_t i = 5138; i < 11377; ++i) - { + for (int32_t i = 5138; i < 11377; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD, L"meaninglessnames", Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); @@ -55,8 +51,7 @@ class PrefixInBooleanQueryTest : public LuceneTestFixture writer->close(); } - virtual ~PrefixInBooleanQueryTest() - { + virtual ~PrefixInBooleanQueryTest() { } protected: @@ -68,22 +63,19 @@ class PrefixInBooleanQueryTest : public LuceneTestFixture const String PrefixInBooleanQueryTest::FIELD = L"name"; -TEST_F(PrefixInBooleanQueryTest, testPrefixQuery) -{ +TEST_F(PrefixInBooleanQueryTest, testPrefixQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); QueryPtr query = newLucene(newLucene(FIELD, L"tang")); EXPECT_EQ(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); } -TEST_F(PrefixInBooleanQueryTest, testTermQuery) -{ +TEST_F(PrefixInBooleanQueryTest, testTermQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); QueryPtr query = newLucene(newLucene(FIELD, L"tangfulin")); EXPECT_EQ(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); } -TEST_F(PrefixInBooleanQueryTest, testTermBooleanQuery) -{ +TEST_F(PrefixInBooleanQueryTest, testTermBooleanQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(FIELD, L"tangfulin")), BooleanClause::SHOULD); @@ -91,8 +83,7 @@ TEST_F(PrefixInBooleanQueryTest, testTermBooleanQuery) EXPECT_EQ(2, indexSearcher->search(query, FilterPtr(), 1000)->totalHits); } -TEST_F(PrefixInBooleanQueryTest, testPrefixBooleanQuery) -{ +TEST_F(PrefixInBooleanQueryTest, testPrefixBooleanQuery) { IndexSearcherPtr indexSearcher = newLucene(directory, true); BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(FIELD, L"tang")), BooleanClause::SHOULD); diff --git a/src/test/search/PrefixQueryTest.cpp b/src/test/search/PrefixQueryTest.cpp index 2c2bff85..75507224 100644 --- a/src/test/search/PrefixQueryTest.cpp +++ b/src/test/search/PrefixQueryTest.cpp @@ -21,18 +21,16 @@ using namespace Lucene; typedef LuceneTestFixture PrefixQueryTest; -TEST_F(PrefixQueryTest, testPrefixQuery) -{ +TEST_F(PrefixQueryTest, testPrefixQuery) { RAMDirectoryPtr directory = newLucene(); Collection categories = newCollection( - L"/Computers/Linux", - L"/Computers/Mac", - L"/Computers/Windows" - ); + L"/Computers/Linux", + L"/Computers/Mac", + L"/Computers/Windows" + ); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < categories.size(); ++i) - { + for (int32_t i = 0; i < categories.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"category", categories[i], Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); diff --git a/src/test/search/QueryTermVectorTest.cpp b/src/test/search/QueryTermVectorTest.cpp index 76e92b8e..d9971da5 100644 --- a/src/test/search/QueryTermVectorTest.cpp +++ b/src/test/search/QueryTermVectorTest.cpp @@ -13,17 +13,14 @@ using namespace Lucene; typedef LuceneTestFixture QueryTermVectorTest; -static void checkGold(Collection terms, Collection gold, Collection freq, Collection goldFreqs) -{ - for (int32_t i = 0; i < terms.size(); ++i) - { +static void checkGold(Collection terms, Collection gold, Collection freq, Collection goldFreqs) { + for (int32_t i = 0; i < terms.size(); ++i) { EXPECT_EQ(terms[i], gold[i]); EXPECT_EQ(freq[i], goldFreqs[i]); } } -TEST_F(QueryTermVectorTest, testConstructor) -{ +TEST_F(QueryTermVectorTest, testConstructor) { Collection queryTerm = newCollection(L"foo", L"bar", L"foo", L"again", L"foo", L"bar", L"go", L"go", L"go"); // Items are sorted lexicographically diff --git a/src/test/search/QueryUtils.cpp b/src/test/search/QueryUtils.cpp index 5d2b0162..42e4d57c 100644 --- a/src/test/search/QueryUtils.cpp +++ b/src/test/search/QueryUtils.cpp @@ -23,426 +23,387 @@ #include "ReaderUtil.h" #include "MiscUtils.h" -namespace Lucene -{ - QueryUtils::~QueryUtils() - { - } +namespace Lucene { - void QueryUtils::check(const QueryPtr& q) - { - checkHashEquals(q); - } +QueryUtils::~QueryUtils() { +} - class WhackyQuery : public Query - { - public: - virtual ~WhackyQuery() - { - } +void QueryUtils::check(const QueryPtr& q) { + checkHashEquals(q); +} - public: - virtual String toString(const String& field) - { - return L"My Whacky Query"; - } +class WhackyQuery : public Query { +public: + virtual ~WhackyQuery() { + } + +public: + virtual String toString(const String& field) { + return L"My Whacky Query"; + } - virtual bool equals(const LuceneObjectPtr& other) - { - if (!MiscUtils::typeOf(other)) - return false; - return Query::equals(other); + virtual bool equals(const LuceneObjectPtr& other) { + if (!MiscUtils::typeOf(other)) { + return false; } - }; + return Query::equals(other); + } +}; - void QueryUtils::checkHashEquals(const QueryPtr& q) - { - QueryPtr q2 = boost::dynamic_pointer_cast(q->clone()); - checkEqual(q, q2); +void QueryUtils::checkHashEquals(const QueryPtr& q) { + QueryPtr q2 = boost::dynamic_pointer_cast(q->clone()); + checkEqual(q, q2); - QueryPtr q3 = boost::dynamic_pointer_cast(q->clone()); - q3->setBoost(7.21792348); - checkUnequal(q, q3); + QueryPtr q3 = boost::dynamic_pointer_cast(q->clone()); + q3->setBoost(7.21792348); + checkUnequal(q, q3); - // test that a class check is done so that no exception is thrown in the implementation of equals() - QueryPtr whacky = newLucene(); - whacky->setBoost(q->getBoost()); - checkUnequal(q, whacky); - } + // test that a class check is done so that no exception is thrown in the implementation of equals() + QueryPtr whacky = newLucene(); + whacky->setBoost(q->getBoost()); + checkUnequal(q, whacky); +} - void QueryUtils::checkEqual(const QueryPtr& q1, const QueryPtr& q2) - { - EXPECT_TRUE(q1->equals(q2)); - EXPECT_EQ(q1->hashCode(), q2->hashCode()); - } +void QueryUtils::checkEqual(const QueryPtr& q1, const QueryPtr& q2) { + EXPECT_TRUE(q1->equals(q2)); + EXPECT_EQ(q1->hashCode(), q2->hashCode()); +} - void QueryUtils::checkUnequal(const QueryPtr& q1, const QueryPtr& q2) - { - EXPECT_TRUE(!q1->equals(q2)); - EXPECT_TRUE(!q2->equals(q1)); +void QueryUtils::checkUnequal(const QueryPtr& q1, const QueryPtr& q2) { + EXPECT_TRUE(!q1->equals(q2)); + EXPECT_TRUE(!q2->equals(q1)); - // possible this test can fail on a hash collision... if that happens, please change - // test to use a different example. - EXPECT_NE(q1->hashCode(), q2->hashCode()); - } + // possible this test can fail on a hash collision... if that happens, please change + // test to use a different example. + EXPECT_NE(q1->hashCode(), q2->hashCode()); +} - void QueryUtils::checkExplanations(const QueryPtr& q, const SearcherPtr& s) - { - CheckHits::checkExplanations(q, L"", s, true); - } +void QueryUtils::checkExplanations(const QueryPtr& q, const SearcherPtr& s) { + CheckHits::checkExplanations(q, L"", s, true); +} - void QueryUtils::check(const QueryPtr& q1, const SearcherPtr& s) - { - check(q1, s, true); - } +void QueryUtils::check(const QueryPtr& q1, const SearcherPtr& s) { + check(q1, s, true); +} - void QueryUtils::check(const QueryPtr& q1, const SearcherPtr& s, bool wrap) - { - check(q1); - if (s) - { - IndexSearcherPtr is = boost::dynamic_pointer_cast(s); - if (is) - { - checkFirstSkipTo(q1, is); - checkSkipTo(q1, is); - if (wrap) - { - check(q1, wrapUnderlyingReader(is, -1), false); - check(q1, wrapUnderlyingReader(is, 0), false); - check(q1, wrapUnderlyingReader(is, +1), false); - } - } - if (wrap) - { - check(q1, wrapSearcher(s, -1), false); - check(q1, wrapSearcher(s, 0), false); - check(q1, wrapSearcher(s, +1), false); +void QueryUtils::check(const QueryPtr& q1, const SearcherPtr& s, bool wrap) { + check(q1); + if (s) { + IndexSearcherPtr is = boost::dynamic_pointer_cast(s); + if (is) { + checkFirstSkipTo(q1, is); + checkSkipTo(q1, is); + if (wrap) { + check(q1, wrapUnderlyingReader(is, -1), false); + check(q1, wrapUnderlyingReader(is, 0), false); + check(q1, wrapUnderlyingReader(is, +1), false); } - checkExplanations(q1, s); - - QueryPtr q2 = boost::dynamic_pointer_cast(q1->clone()); - checkEqual(s->rewrite(q1), s->rewrite(q2)); } + if (wrap) { + check(q1, wrapSearcher(s, -1), false); + check(q1, wrapSearcher(s, 0), false); + check(q1, wrapSearcher(s, +1), false); + } + checkExplanations(q1, s); + + QueryPtr q2 = boost::dynamic_pointer_cast(q1->clone()); + checkEqual(s->rewrite(q1), s->rewrite(q2)); } +} - IndexSearcherPtr QueryUtils::wrapUnderlyingReader(const IndexSearcherPtr& s, int32_t edge) - { - IndexReaderPtr r = s->getIndexReader(); +IndexSearcherPtr QueryUtils::wrapUnderlyingReader(const IndexSearcherPtr& s, int32_t edge) { + IndexReaderPtr r = s->getIndexReader(); - // we can't put deleted docs before the nested reader, because it will throw off the docIds - Collection readers = newCollection( + // we can't put deleted docs before the nested reader, because it will throw off the docIds + Collection readers = newCollection( edge < 0 ? r : IndexReader::open(makeEmptyIndex(0), true), IndexReader::open(makeEmptyIndex(0), true), newLucene(newCollection( - IndexReader::open(makeEmptyIndex(edge < 0 ? 4 : 0), true), - IndexReader::open(makeEmptyIndex(0), true), - 0 == edge ? r : IndexReader::open(makeEmptyIndex(0), true) - )), + IndexReader::open(makeEmptyIndex(edge < 0 ? 4 : 0), true), + IndexReader::open(makeEmptyIndex(0), true), + 0 == edge ? r : IndexReader::open(makeEmptyIndex(0), true) + )), IndexReader::open(makeEmptyIndex(0 < edge ? 0 : 7), true), IndexReader::open(makeEmptyIndex(0), true), newLucene(newCollection( - IndexReader::open(makeEmptyIndex(0 < edge ? 0 : 5), true), - IndexReader::open(makeEmptyIndex(0), true), - 0 < edge ? r : IndexReader::open(makeEmptyIndex(0), true) - )) - ); - IndexSearcherPtr out = newLucene(newLucene(readers)); - out->setSimilarity(s->getSimilarity()); - return out; - } + IndexReader::open(makeEmptyIndex(0 < edge ? 0 : 5), true), + IndexReader::open(makeEmptyIndex(0), true), + 0 < edge ? r : IndexReader::open(makeEmptyIndex(0), true) + )) + ); + IndexSearcherPtr out = newLucene(newLucene(readers)); + out->setSimilarity(s->getSimilarity()); + return out; +} - MultiSearcherPtr QueryUtils::wrapSearcher(const SearcherPtr& s, int32_t edge) - { - // we can't put deleted docs before the nested reader, because it will through off the docIds - Collection searchers = newCollection( +MultiSearcherPtr QueryUtils::wrapSearcher(const SearcherPtr& s, int32_t edge) { + // we can't put deleted docs before the nested reader, because it will through off the docIds + Collection searchers = newCollection( edge < 0 ? s : newLucene(makeEmptyIndex(0), true), newLucene(newCollection( - newLucene(makeEmptyIndex(edge < 0 ? 65 : 0), true), - newLucene(makeEmptyIndex(0), true), - 0 == edge ? s : newLucene(makeEmptyIndex(0), true) - )), + newLucene(makeEmptyIndex(edge < 0 ? 65 : 0), true), + newLucene(makeEmptyIndex(0), true), + 0 == edge ? s : newLucene(makeEmptyIndex(0), true) + )), newLucene(makeEmptyIndex(0 < edge ? 0 : 3), true), newLucene(makeEmptyIndex(0), true), newLucene(newCollection( - newLucene(makeEmptyIndex(0 < edge ? 0 : 5), true), - newLucene(makeEmptyIndex(0), true), - 0 < edge ? s : newLucene(makeEmptyIndex(0), true) - )) - ); - MultiSearcherPtr out = newLucene(searchers); - out->setSimilarity(s->getSimilarity()); - return out; - } + newLucene(makeEmptyIndex(0 < edge ? 0 : 5), true), + newLucene(makeEmptyIndex(0), true), + 0 < edge ? s : newLucene(makeEmptyIndex(0), true) + )) + ); + MultiSearcherPtr out = newLucene(searchers); + out->setSimilarity(s->getSimilarity()); + return out; +} - RAMDirectoryPtr QueryUtils::makeEmptyIndex(int32_t numDeletedDocs) - { - RAMDirectoryPtr d = newLucene(); - IndexWriterPtr w = newLucene(d, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < numDeletedDocs; ++i) - w->addDocument(newLucene()); - w->commit(); - w->deleteDocuments(newLucene()); - w->commit(); - - if (0 < numDeletedDocs) - EXPECT_TRUE(w->hasDeletions()); - - EXPECT_EQ(numDeletedDocs, w->maxDoc()); - EXPECT_EQ(0, w->numDocs()); - w->close(); - IndexReaderPtr r = IndexReader::open(d, true); - EXPECT_EQ(numDeletedDocs, r->numDeletedDocs()); - r->close(); - return d; +RAMDirectoryPtr QueryUtils::makeEmptyIndex(int32_t numDeletedDocs) { + RAMDirectoryPtr d = newLucene(); + IndexWriterPtr w = newLucene(d, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); + for (int32_t i = 0; i < numDeletedDocs; ++i) { + w->addDocument(newLucene()); } + w->commit(); + w->deleteDocuments(newLucene()); + w->commit(); - namespace CheckSkipTo - { - class SkipCollector : public Collector - { - public: - SkipCollector(const QueryPtr& q, const IndexSearcherPtr& s, Collection lastDoc, Collection order, Collection opidx, Collection lastReader) - { - this->q = q; - this->s = s; - this->lastDoc = lastDoc; - this->order = order; - this->opidx = opidx; - this->lastReader = lastReader; - } - - virtual ~SkipCollector() - { - } + if (0 < numDeletedDocs) { + EXPECT_TRUE(w->hasDeletions()); + } - protected: - QueryPtr q; - IndexSearcherPtr s; - Collection lastDoc; - Collection order; - Collection opidx; - - ScorerPtr sc; - IndexReaderPtr reader; - ScorerPtr scorer; - Collection lastReader; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->sc = scorer; - } + EXPECT_EQ(numDeletedDocs, w->maxDoc()); + EXPECT_EQ(0, w->numDocs()); + w->close(); + IndexReaderPtr r = IndexReader::open(d, true); + EXPECT_EQ(numDeletedDocs, r->numDeletedDocs()); + r->close(); + return d; +} - virtual void collect(int32_t doc) - { - double score = sc->score(); - lastDoc[0] = doc; - if (!scorer) - { - WeightPtr w = q->weight(s); - scorer = w->scorer(reader, true, false); - } - - int32_t skip_op = 0; - int32_t next_op = 1; - double maxDiff = 1e-5; - - int32_t op = order[(opidx[0]++) % order.size()]; - bool more = op == skip_op ? - (scorer->advance(scorer->docID() + 1) != DocIdSetIterator::NO_MORE_DOCS) : - (scorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); - int32_t scorerDoc = scorer->docID(); - double scorerScore = scorer->score(); - double scorerScore2 = scorer->score(); - double scoreDiff = std::abs(score - scorerScore); - double scorerDiff = std::abs(scorerScore2 - scorerScore); - if (!more || doc != scorerDoc || scoreDiff > maxDiff || scorerDiff > maxDiff) - { - StringStream sbord; - for (int32_t i = 0; i < order.size(); ++i) - sbord << (order[i] == skip_op ? L" skip()" : L" next()"); - StringStream message; - message << L"ERROR matching docs:\n\t" - << (doc != scorerDoc ? L"--> " : L"") - << L"doc=" << doc << L", scorerDoc=" << scorerDoc - << L"\n\t" << (!more ? L"--> " : L"") << L"tscorer.more=" - << more << L"\n\t" << (scoreDiff > maxDiff ? L"--> " : L"") - << L"scorerScore=" << scorerScore << L" scoreDiff=" - << scoreDiff << L" maxDiff=" << maxDiff << L"\n\t" - << (scorerDiff > maxDiff ? L"--> " : L"") << L"scorerScore2=" - << scorerScore2 << L" scorerDiff=" << scorerDiff - << L"\n\thitCollector.doc=" << doc << L" score=" - << score << L"\n\t Scorer=" << scorer << L"\n\t Query=" - << q->toString() + L" " << L"\n\t Searcher=" + s->toString() - << L"\n\t Order=" << sbord.str() << L"\n\t Op=" - << (op == skip_op ? L" skip()" : L" next()"); - FAIL() << StringUtils::toUTF8(message.str()); - } - } +namespace CheckSkipTo { + +class SkipCollector : public Collector { +public: + SkipCollector(const QueryPtr& q, const IndexSearcherPtr& s, Collection lastDoc, Collection order, Collection opidx, Collection lastReader) { + this->q = q; + this->s = s; + this->lastDoc = lastDoc; + this->order = order; + this->opidx = opidx; + this->lastReader = lastReader; + } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS - if (lastReader[0]) - { - IndexReaderPtr previousReader = lastReader[0]; - WeightPtr w = q->weight(newLucene(previousReader)); - ScorerPtr scorer = w->scorer(previousReader, true, false); - if (scorer) - { - bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); - EXPECT_TRUE(!more); - } - } - this->reader = reader; - this->scorer.reset(); - lastDoc[0] = -1; - } + virtual ~SkipCollector() { + } - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; +protected: + QueryPtr q; + IndexSearcherPtr s; + Collection lastDoc; + Collection order; + Collection opidx; + + ScorerPtr sc; + IndexReaderPtr reader; + ScorerPtr scorer; + Collection lastReader; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->sc = scorer; } - void QueryUtils::checkSkipTo(const QueryPtr& q, const IndexSearcherPtr& s) - { - if (q->weight(s)->scoresDocsOutOfOrder()) - return; // in this case order of skipTo() might differ from that of next(). + virtual void collect(int32_t doc) { + double score = sc->score(); + lastDoc[0] = doc; + if (!scorer) { + WeightPtr w = q->weight(s); + scorer = w->scorer(reader, true, false); + } int32_t skip_op = 0; int32_t next_op = 1; - Collection< Collection > orders = newCollection< Collection >( - newCollection(next_op), - newCollection(skip_op), - newCollection(skip_op, next_op), - newCollection(next_op, skip_op), - newCollection(skip_op, skip_op, next_op, next_op), - newCollection(next_op, next_op, skip_op, skip_op), - newCollection(skip_op, skip_op, skip_op, next_op, next_op) - ); - - Collection lastReader = Collection::newInstance(1); - - for (int32_t k = 0; k < orders.size(); ++k) - { - Collection order = orders[k]; - Collection opidx = newCollection(0); - Collection lastDoc = newCollection(-1); - - s->search(q, newLucene(q, s, lastDoc, order, opidx, lastReader)); - - if (lastReader[0]) - { - // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS - IndexReaderPtr previousReader = lastReader[0]; - WeightPtr w = q->weight(newLucene(previousReader)); - ScorerPtr scorer = w->scorer(previousReader, true, false); - if (scorer) - { - bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); - EXPECT_TRUE(!more); - } + double maxDiff = 1e-5; + + int32_t op = order[(opidx[0]++) % order.size()]; + bool more = op == skip_op ? + (scorer->advance(scorer->docID() + 1) != DocIdSetIterator::NO_MORE_DOCS) : + (scorer->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); + int32_t scorerDoc = scorer->docID(); + double scorerScore = scorer->score(); + double scorerScore2 = scorer->score(); + double scoreDiff = std::abs(score - scorerScore); + double scorerDiff = std::abs(scorerScore2 - scorerScore); + if (!more || doc != scorerDoc || scoreDiff > maxDiff || scorerDiff > maxDiff) { + StringStream sbord; + for (int32_t i = 0; i < order.size(); ++i) { + sbord << (order[i] == skip_op ? L" skip()" : L" next()"); } + StringStream message; + message << L"ERROR matching docs:\n\t" + << (doc != scorerDoc ? L"--> " : L"") + << L"doc=" << doc << L", scorerDoc=" << scorerDoc + << L"\n\t" << (!more ? L"--> " : L"") << L"tscorer.more=" + << more << L"\n\t" << (scoreDiff > maxDiff ? L"--> " : L"") + << L"scorerScore=" << scorerScore << L" scoreDiff=" + << scoreDiff << L" maxDiff=" << maxDiff << L"\n\t" + << (scorerDiff > maxDiff ? L"--> " : L"") << L"scorerScore2=" + << scorerScore2 << L" scorerDiff=" << scorerDiff + << L"\n\thitCollector.doc=" << doc << L" score=" + << score << L"\n\t Scorer=" << scorer << L"\n\t Query=" + << q->toString() + L" " << L"\n\t Searcher=" + s->toString() + << L"\n\t Order=" << sbord.str() << L"\n\t Op=" + << (op == skip_op ? L" skip()" : L" next()"); + FAIL() << StringUtils::toUTF8(message.str()); } } - namespace CheckFirstSkipTo - { - class SkipCollector : public Collector - { - public: - SkipCollector(const QueryPtr& q, const IndexSearcherPtr& s, Collection lastDoc, Collection lastReader) - { - this->q = q; - this->s = s; - this->lastDoc = lastDoc; - this->lastReader = lastReader; + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS + if (lastReader[0]) { + IndexReaderPtr previousReader = lastReader[0]; + WeightPtr w = q->weight(newLucene(previousReader)); + ScorerPtr scorer = w->scorer(previousReader, true, false); + if (scorer) { + bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); + EXPECT_TRUE(!more); } + } + this->reader = reader; + this->scorer.reset(); + lastDoc[0] = -1; + } - virtual ~SkipCollector() - { - } + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; - protected: - QueryPtr q; - IndexSearcherPtr s; - Collection lastDoc; - Collection lastReader; +} - ScorerPtr scorer; - IndexReaderPtr reader; +void QueryUtils::checkSkipTo(const QueryPtr& q, const IndexSearcherPtr& s) { + if (q->weight(s)->scoresDocsOutOfOrder()) { + return; // in this case order of skipTo() might differ from that of next(). + } - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } + int32_t skip_op = 0; + int32_t next_op = 1; + Collection< Collection > orders = newCollection< Collection >( + newCollection(next_op), + newCollection(skip_op), + newCollection(skip_op, next_op), + newCollection(next_op, skip_op), + newCollection(skip_op, skip_op, next_op, next_op), + newCollection(next_op, next_op, skip_op, skip_op), + newCollection(skip_op, skip_op, skip_op, next_op, next_op) + ); + + Collection lastReader = Collection::newInstance(1); + + for (int32_t k = 0; k < orders.size(); ++k) { + Collection order = orders[k]; + Collection opidx = newCollection(0); + Collection lastDoc = newCollection(-1); - virtual void collect(int32_t doc) - { - double score = scorer->score(); - lastDoc[0] = doc; - for (int32_t i = lastDoc[0] + 1; i <= doc; ++i) - { - WeightPtr w = q->weight(s); - ScorerPtr scorer = w->scorer(reader, true, false); - EXPECT_TRUE(scorer->advance(i) != DocIdSetIterator::NO_MORE_DOCS); - EXPECT_EQ(doc, scorer->docID()); - double skipToScore = scorer->score(); - EXPECT_NEAR(skipToScore, scorer->score(), 1e-5); - EXPECT_NEAR(score, skipToScore, 1e-5); - } - lastDoc[0] = doc; - } + s->search(q, newLucene(q, s, lastDoc, order, opidx, lastReader)); - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS - if (lastReader[0]) - { - IndexReaderPtr previousReader = lastReader[0]; - WeightPtr w = q->weight(newLucene(previousReader)); - ScorerPtr scorer = w->scorer(previousReader, true, false); - if (scorer) - { - bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); - EXPECT_TRUE(!more); - } - } - - lastReader[0] = reader; - this->reader = reader; - lastDoc[0] = -1; + if (lastReader[0]) { + // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS + IndexReaderPtr previousReader = lastReader[0]; + WeightPtr w = q->weight(newLucene(previousReader)); + ScorerPtr scorer = w->scorer(previousReader, true, false); + if (scorer) { + bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); + EXPECT_TRUE(!more); } + } + } +} - virtual bool acceptsDocsOutOfOrder() - { - return false; - } - }; +namespace CheckFirstSkipTo { + +class SkipCollector : public Collector { +public: + SkipCollector(const QueryPtr& q, const IndexSearcherPtr& s, Collection lastDoc, Collection lastReader) { + this->q = q; + this->s = s; + this->lastDoc = lastDoc; + this->lastReader = lastReader; } - void QueryUtils::checkFirstSkipTo(const QueryPtr& q, const IndexSearcherPtr& s) - { - Collection lastDoc = newCollection(-1); - Collection lastReader = Collection::newInstance(1); + virtual ~SkipCollector() { + } - s->search(q, newLucene(q, s, lastDoc, lastReader)); +protected: + QueryPtr q; + IndexSearcherPtr s; + Collection lastDoc; + Collection lastReader; - if (lastReader[0]) - { - // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS + ScorerPtr scorer; + IndexReaderPtr reader; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + double score = scorer->score(); + lastDoc[0] = doc; + for (int32_t i = lastDoc[0] + 1; i <= doc; ++i) { + WeightPtr w = q->weight(s); + ScorerPtr scorer = w->scorer(reader, true, false); + EXPECT_TRUE(scorer->advance(i) != DocIdSetIterator::NO_MORE_DOCS); + EXPECT_EQ(doc, scorer->docID()); + double skipToScore = scorer->score(); + EXPECT_NEAR(skipToScore, scorer->score(), 1e-5); + EXPECT_NEAR(score, skipToScore, 1e-5); + } + lastDoc[0] = doc; + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS + if (lastReader[0]) { IndexReaderPtr previousReader = lastReader[0]; WeightPtr w = q->weight(newLucene(previousReader)); ScorerPtr scorer = w->scorer(previousReader, true, false); - if (scorer) - { + if (scorer) { bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); EXPECT_TRUE(!more); } } + + lastReader[0] = reader; + this->reader = reader; + lastDoc[0] = -1; } + + virtual bool acceptsDocsOutOfOrder() { + return false; + } +}; + +} + +void QueryUtils::checkFirstSkipTo(const QueryPtr& q, const IndexSearcherPtr& s) { + Collection lastDoc = newCollection(-1); + Collection lastReader = Collection::newInstance(1); + + s->search(q, newLucene(q, s, lastDoc, lastReader)); + + if (lastReader[0]) { + // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS + IndexReaderPtr previousReader = lastReader[0]; + WeightPtr w = q->weight(newLucene(previousReader)); + ScorerPtr scorer = w->scorer(previousReader, true, false); + if (scorer) { + bool more = (scorer->advance(lastDoc[0] + 1) != DocIdSetIterator::NO_MORE_DOCS); + EXPECT_TRUE(!more); + } + } +} + } diff --git a/src/test/search/QueryWrapperFilterTest.cpp b/src/test/search/QueryWrapperFilterTest.cpp index 2d77ed87..38fff8c4 100644 --- a/src/test/search/QueryWrapperFilterTest.cpp +++ b/src/test/search/QueryWrapperFilterTest.cpp @@ -26,8 +26,7 @@ using namespace Lucene; typedef LuceneTestFixture QueryWrapperFilterTest; -TEST_F(QueryWrapperFilterTest, testBasic) -{ +TEST_F(QueryWrapperFilterTest, testBasic) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); diff --git a/src/test/search/ScoreCachingWrappingScorerTest.cpp b/src/test/search/ScoreCachingWrappingScorerTest.cpp index e724723b..1d3fc81d 100644 --- a/src/test/search/ScoreCachingWrappingScorerTest.cpp +++ b/src/test/search/ScoreCachingWrappingScorerTest.cpp @@ -16,105 +16,92 @@ using namespace Lucene; typedef LuceneTestFixture ScoreCachingWrappingScorerTest; -namespace TestGetScores -{ - class SimpleScorer : public Scorer - { - public: - SimpleScorer(Collection scores) : Scorer(SimilarityPtr()) - { - this->scores = scores; - idx = 0; - doc = -1; - } - - virtual ~SimpleScorer() - { - } - - public: - int32_t idx; - int32_t doc; - Collection scores; - - public: - virtual double score() - { - // Advance idx on purpose, so that consecutive calls to score will get different results. - // This is to emulate computation of a score. If ScoreCachingWrappingScorer is used, this - // should not be called more than once per document. - return idx == scores.size() ? std::numeric_limits::quiet_NaN() : scores[idx++]; - } - - virtual int32_t docID() - { - return doc; - } - - virtual int32_t nextDoc() - { - return ++doc < scores.size() ? doc : DocIdSetIterator::NO_MORE_DOCS; - } +namespace TestGetScores { - virtual int32_t advance(int32_t target) - { - doc = target; - return doc < scores.size() ? doc : DocIdSetIterator::NO_MORE_DOCS; - } - }; +class SimpleScorer : public Scorer { +public: + SimpleScorer(Collection scores) : Scorer(SimilarityPtr()) { + this->scores = scores; + idx = 0; + doc = -1; + } - DECLARE_SHARED_PTR(ScoreCachingCollector) + virtual ~SimpleScorer() { + } - class ScoreCachingCollector : public Collector - { - public: - ScoreCachingCollector(int32_t numToCollect) - { - idx = 0; - mscores = Collection::newInstance(numToCollect); +public: + int32_t idx; + int32_t doc; + Collection scores; + +public: + virtual double score() { + // Advance idx on purpose, so that consecutive calls to score will get different results. + // This is to emulate computation of a score. If ScoreCachingWrappingScorer is used, this + // should not be called more than once per document. + return idx == scores.size() ? std::numeric_limits::quiet_NaN() : scores[idx++]; + } + + virtual int32_t docID() { + return doc; + } + + virtual int32_t nextDoc() { + return ++doc < scores.size() ? doc : DocIdSetIterator::NO_MORE_DOCS; + } + + virtual int32_t advance(int32_t target) { + doc = target; + return doc < scores.size() ? doc : DocIdSetIterator::NO_MORE_DOCS; + } +}; + +DECLARE_SHARED_PTR(ScoreCachingCollector) + +class ScoreCachingCollector : public Collector { +public: + ScoreCachingCollector(int32_t numToCollect) { + idx = 0; + mscores = Collection::newInstance(numToCollect); + } + + virtual ~ScoreCachingCollector() { + } + +public: + int32_t idx; + ScorerPtr scorer; + Collection mscores; + +public: + virtual void collect(int32_t doc) { + // just a sanity check to avoid IOOB. + if (idx == mscores.size()) { + return; } - virtual ~ScoreCachingCollector() - { - } + // just call score() a couple of times and record the score. + mscores[idx] = scorer->score(); + mscores[idx] = scorer->score(); + mscores[idx] = scorer->score(); + ++idx; + } - public: - int32_t idx; - ScorerPtr scorer; - Collection mscores; - - public: - virtual void collect(int32_t doc) - { - // just a sanity check to avoid IOOB. - if (idx == mscores.size()) - return; - - // just call score() a couple of times and record the score. - mscores[idx] = scorer->score(); - mscores[idx] = scorer->score(); - mscores[idx] = scorer->score(); - ++idx; - } + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - } + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = newLucene(scorer); + } - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = newLucene(scorer); - } + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; } -TEST_F(ScoreCachingWrappingScorerTest, testGetScores) -{ +TEST_F(ScoreCachingWrappingScorerTest, testGetScores) { Collection scores = Collection::newInstance(); scores.add(0.7767749); scores.add(1.7839992); @@ -136,9 +123,11 @@ TEST_F(ScoreCachingWrappingScorerTest, testGetScores) // We need to iterate on the scorer so that its doc() advances. int32_t doc; - while ((doc = s->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) + while ((doc = s->nextDoc()) != DocIdSetIterator::NO_MORE_DOCS) { scc->collect(doc); + } - for (int32_t i = 0; i < scores.size(); ++i) + for (int32_t i = 0; i < scores.size(); ++i) { EXPECT_EQ(scores[i], scc->mscores[i]); + } } diff --git a/src/test/search/ScorerPerfTest.cpp b/src/test/search/ScorerPerfTest.cpp index 273c7df6..9612c31a 100644 --- a/src/test/search/ScorerPerfTest.cpp +++ b/src/test/search/ScorerPerfTest.cpp @@ -24,18 +24,15 @@ using namespace Lucene; DECLARE_SHARED_PTR(CountingHitCollector) DECLARE_SHARED_PTR(MatchingHitCollector) -class CountingHitCollector : public Collector -{ +class CountingHitCollector : public Collector { public: - CountingHitCollector() - { + CountingHitCollector() { count = 0; sum = 0; docBase = 0; } - virtual ~CountingHitCollector() - { + virtual ~CountingHitCollector() { } public: @@ -44,48 +41,39 @@ class CountingHitCollector : public Collector int32_t docBase; public: - virtual void setScorer(const ScorerPtr& scorer) - { + virtual void setScorer(const ScorerPtr& scorer) { } - virtual void collect(int32_t doc) - { + virtual void collect(int32_t doc) { ++count; sum += docBase + doc; // use it to avoid any possibility of being optimized away } - int32_t getCount() - { + int32_t getCount() { return count; } - int32_t getSum() - { + int32_t getSum() { return sum; } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } - virtual bool acceptsDocsOutOfOrder() - { + virtual bool acceptsDocsOutOfOrder() { return true; } }; -class MatchingHitCollector : public CountingHitCollector -{ +class MatchingHitCollector : public CountingHitCollector { public: - MatchingHitCollector(const BitSetPtr& answer) - { + MatchingHitCollector(const BitSetPtr& answer) { this->answer = answer; this->pos = -1; } - virtual ~MatchingHitCollector() - { + virtual ~MatchingHitCollector() { } public: @@ -93,48 +81,41 @@ class MatchingHitCollector : public CountingHitCollector int32_t pos; public: - virtual void collect(int32_t doc) - { + virtual void collect(int32_t doc) { pos = answer->nextSetBit(pos + 1); - if (pos != doc + docBase) + if (pos != doc + docBase) { boost::throw_exception(RuntimeException(L"Expected doc " + StringUtils::toString(pos) + L" but got " + StringUtils::toString(doc + docBase))); + } CountingHitCollector::collect(doc); } }; -class AddClauseFilter : public Filter -{ +class AddClauseFilter : public Filter { public: - AddClauseFilter(const BitSetPtr& rnd) - { + AddClauseFilter(const BitSetPtr& rnd) { this->rnd = rnd; } - virtual ~AddClauseFilter() - { + virtual ~AddClauseFilter() { } protected: BitSetPtr rnd; public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { return newLucene(rnd); } }; -class ScorerPerfTest : public LuceneTestFixture -{ +class ScorerPerfTest : public LuceneTestFixture { public: - ScorerPerfTest() - { + ScorerPerfTest() { r = newLucene(); createDummySearcher(); } - virtual ~ScorerPerfTest() - { + virtual ~ScorerPerfTest() { s->close(); } @@ -145,8 +126,7 @@ class ScorerPerfTest : public LuceneTestFixture IndexSearcherPtr s; public: - void createDummySearcher() - { + void createDummySearcher() { // Create a dummy index with nothing in it. RAMDirectoryPtr rd = newLucene(); IndexWriterPtr iw = newLucene(rd, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -155,31 +135,30 @@ class ScorerPerfTest : public LuceneTestFixture s = newLucene(rd, true); } - BitSetPtr randBitSet(int32_t sz, int32_t numBitsToSet) - { + BitSetPtr randBitSet(int32_t sz, int32_t numBitsToSet) { BitSetPtr set = newLucene(sz); - for (int32_t i = 0; i < numBitsToSet; ++i) + for (int32_t i = 0; i < numBitsToSet; ++i) { set->set(r->nextInt(sz)); + } return set; } - Collection randBitSets(int32_t numSets, int32_t setSize) - { + Collection randBitSets(int32_t numSets, int32_t setSize) { Collection sets = Collection::newInstance(numSets); - for (int32_t i = 0; i < sets.size(); ++i) + for (int32_t i = 0; i < sets.size(); ++i) { sets[i] = randBitSet(setSize, r->nextInt(setSize)); + } return sets; } - void doConjunctions(int32_t iter, int32_t maxClauses) - { - for (int32_t i = 0; i < iter; ++i) - { + void doConjunctions(int32_t iter, int32_t maxClauses) { + for (int32_t i = 0; i < iter; ++i) { int32_t numClauses = r->nextInt(maxClauses - 1) + 2; // min 2 clauses BooleanQueryPtr bq = newLucene(); BitSetPtr result; - for (int32_t j = 0; j < numClauses; ++j) + for (int32_t j = 0; j < numClauses; ++j) { result = addClause(bq, result); + } CountingHitCollectorPtr hc = newLucene(result); s->search(bq, hc); @@ -188,20 +167,18 @@ class ScorerPerfTest : public LuceneTestFixture } } - void doNestedConjunctions(int32_t iter, int32_t maxOuterClauses, int32_t maxClauses) - { - for (int32_t i = 0; i < iter; ++i) - { + void doNestedConjunctions(int32_t iter, int32_t maxOuterClauses, int32_t maxClauses) { + for (int32_t i = 0; i < iter; ++i) { int32_t oClauses = r->nextInt(maxOuterClauses - 1) + 2; BooleanQueryPtr oq = newLucene(); BitSetPtr result; - for (int32_t o = 0; o < oClauses; ++o) - { + for (int32_t o = 0; o < oClauses; ++o) { int32_t numClauses = r->nextInt(maxClauses - 1) + 2; // min 2 clauses BooleanQueryPtr bq = newLucene(); - for (int32_t j = 0; j < numClauses; ++j) + for (int32_t j = 0; j < numClauses; ++j) { result = addClause(bq, result); + } oq->add(bq, BooleanClause::MUST); } @@ -212,22 +189,21 @@ class ScorerPerfTest : public LuceneTestFixture } } - BitSetPtr addClause(const BooleanQueryPtr& bq, const BitSetPtr& result) - { + BitSetPtr addClause(const BooleanQueryPtr& bq, const BitSetPtr& result) { BitSetPtr rnd = sets[r->nextInt(sets.size())]; QueryPtr q = newLucene(newLucene(rnd)); bq->add(q, BooleanClause::MUST); BitSetPtr _result(result); - if (!_result) + if (!_result) { _result = boost::dynamic_pointer_cast(rnd->clone()); - else + } else { _result->_and(rnd); + } return _result; } }; -TEST_F(ScorerPerfTest, testConjunctions) -{ +TEST_F(ScorerPerfTest, testConjunctions) { // test many small sets... the bugs will be found on boundary conditions sets = randBitSets(1000, 10); doConjunctions(10000, 5); diff --git a/src/test/search/SearchForDuplicatesTest.cpp b/src/test/search/SearchForDuplicatesTest.cpp index 961ba63c..88cc9651 100644 --- a/src/test/search/SearchForDuplicatesTest.cpp +++ b/src/test/search/SearchForDuplicatesTest.cpp @@ -27,34 +27,27 @@ static const String HIGH_PRIORITY = L"high"; static const String MED_PRIORITY = L"medium"; static const String LOW_PRIORITY = L"low"; -static void printHits(StringStream& out, Collection hits, const SearcherPtr& searcher) -{ +static void printHits(StringStream& out, Collection hits, const SearcherPtr& searcher) { out << hits.size() << L" total results\n"; - for (int32_t i = 0; i < hits.size(); ++i) - { - if (i < 10 || (i > 94 && i < 105)) - { + for (int32_t i = 0; i < hits.size(); ++i) { + if (i < 10 || (i > 94 && i < 105)) { DocumentPtr doc = searcher->doc(hits[i]->doc); out << i << L" " << doc->get(ID_FIELD) << L"\n"; } } } -static void checkHits(Collection hits, int32_t expectedCount, const SearcherPtr& searcher) -{ +static void checkHits(Collection hits, int32_t expectedCount, const SearcherPtr& searcher) { EXPECT_EQ(expectedCount, hits.size()); - for (int32_t i = 0; i < hits.size(); ++i) - { - if (i < 10 || (i > 94 && i < 105)) - { + for (int32_t i = 0; i < hits.size(); ++i) { + if (i < 10 || (i > 94 && i < 105)) { DocumentPtr doc = searcher->doc(hits[i]->doc); EXPECT_EQ(StringUtils::toString(i), doc->get(ID_FIELD)); } } } -static void doTest(StringStream& out, bool useCompoundFile) -{ +static void doTest(StringStream& out, bool useCompoundFile) { DirectoryPtr directory = newLucene(); AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); @@ -63,8 +56,7 @@ static void doTest(StringStream& out, bool useCompoundFile) int32_t MAX_DOCS = 225; - for (int32_t j = 0; j < MAX_DOCS; ++j) - { + for (int32_t j = 0; j < MAX_DOCS; ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(PRIORITY_FIELD, HIGH_PRIORITY, Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(ID_FIELD, StringUtils::toString(j), Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -101,8 +93,7 @@ static void doTest(StringStream& out, bool useCompoundFile) searcher->close(); } -TEST_F(SearchForDuplicatesTest, testRun) -{ +TEST_F(SearchForDuplicatesTest, testRun) { StringStream multiFileOutput; doTest(multiFileOutput, false); diff --git a/src/test/search/SearchTest.cpp b/src/test/search/SearchTest.cpp index 6b8d7a5f..c13e2619 100644 --- a/src/test/search/SearchTest.cpp +++ b/src/test/search/SearchTest.cpp @@ -21,25 +21,23 @@ using namespace Lucene; typedef LuceneTestFixture SearchTest; -static void doTestSearch(StringStream& out, bool useCompoundFile) -{ +static void doTestSearch(StringStream& out, bool useCompoundFile) { DirectoryPtr directory = newLucene(); AnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(useCompoundFile); Collection docs = newCollection( - L"a b c d e", - L"a b c d e a b c d e", - L"a b c d e f g h i j", - L"a c e", - L"e c a", - L"a c e a c e", - L"a c e a b c" - ); + L"a b c d e", + L"a b c d e a b c d e", + L"a b c d e f g h i j", + L"a c e", + L"e c a", + L"a c e a c e", + L"a c e a b c" + ); - for (int32_t j = 0; j < docs.size(); ++j) - { + for (int32_t j = 0; j < docs.size(); ++j) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"contents", docs[j], Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -49,26 +47,24 @@ static void doTestSearch(StringStream& out, bool useCompoundFile) SearcherPtr searcher = newLucene(directory, true); Collection queries = newCollection( - L"a b", - L"\"a b\"", - L"\"a b c\"", - L"a c", - L"\"a c\"", - L"\"a c e\"" - ); + L"a b", + L"\"a b\"", + L"\"a b c\"", + L"a c", + L"\"a c\"", + L"\"a c e\"" + ); QueryParserPtr parser = newLucene(LuceneVersion::LUCENE_CURRENT, L"contents", analyzer); parser->setPhraseSlop(4); - for (int32_t j = 0; j < queries.size(); ++j) - { + for (int32_t j = 0; j < queries.size(); ++j) { QueryPtr query = parser->parse(queries[j]); out << L"Query: " << query->toString(L"contents") << L"\n"; Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; out << hits.size() << L" total results\n"; - for (int32_t i = 0; i < hits.size() && i < 10; ++i) - { + for (int32_t i = 0; i < hits.size() && i < 10; ++i) { DocumentPtr doc = searcher->doc(hits[i]->doc); out << i << L" " << hits[i]->score << L" " + doc->get(L"contents") << L"\n"; } @@ -76,8 +72,7 @@ static void doTestSearch(StringStream& out, bool useCompoundFile) searcher->close(); } -TEST_F(SearchTest, testSearch) -{ +TEST_F(SearchTest, testSearch) { StringStream multiFileOutput; doTestSearch(multiFileOutput, false); diff --git a/src/test/search/SetNormTest.cpp b/src/test/search/SetNormTest.cpp index e4c8014c..69b31428 100644 --- a/src/test/search/SetNormTest.cpp +++ b/src/test/search/SetNormTest.cpp @@ -22,51 +22,44 @@ using namespace Lucene; typedef LuceneTestFixture SetNormTest; -namespace TestSetNorm -{ - class SetNormCollector : public Collector - { - public: - SetNormCollector(Collection scores) - { - this->scores = scores; - this->base = 0; - } - - virtual ~SetNormCollector() - { - } - - protected: - int32_t base; - ScorerPtr scorer; - Collection scores; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - scores[doc + base] = scorer->score(); - } - - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - base = docBase; - } - - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; +namespace TestSetNorm { + +class SetNormCollector : public Collector { +public: + SetNormCollector(Collection scores) { + this->scores = scores; + this->base = 0; + } + + virtual ~SetNormCollector() { + } + +protected: + int32_t base; + ScorerPtr scorer; + Collection scores; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + scores[doc + base] = scorer->score(); + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + base = docBase; + } + + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; + } -TEST_F(SetNormTest, testSetNorm) -{ +TEST_F(SetNormTest, testSetNorm) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); @@ -95,8 +88,7 @@ TEST_F(SetNormTest, testSetNorm) searcher->search(newLucene(newLucene(L"field", L"word")), newLucene(scores)); double lastScore = 0.0; - for (int32_t i = 0; i < 4; ++i) - { + for (int32_t i = 0; i < 4; ++i) { EXPECT_TRUE(scores[i] > lastScore); lastScore = scores[i]; } diff --git a/src/test/search/SimilarityTest.cpp b/src/test/search/SimilarityTest.cpp index 40823ca3..b2551fb7 100644 --- a/src/test/search/SimilarityTest.cpp +++ b/src/test/search/SimilarityTest.cpp @@ -25,180 +25,147 @@ using namespace Lucene; typedef LuceneTestFixture SimilarityTest; -namespace TestSimilarity -{ - class SimpleIDFExplanation : public IDFExplanation - { - public: - virtual ~SimpleIDFExplanation() - { - } - - public: - virtual double getIdf() - { - return 1.0; - } - - virtual String explain() - { - return L"Inexplicable"; - } - }; - - class SimpleSimilarity : public Similarity - { - public: - virtual ~SimpleSimilarity() - { - } - - public: - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { - return 1.0; - } - - virtual double queryNorm(double sumOfSquaredWeights) - { - return 1.0; - } - - virtual double tf(double freq) - { - return freq; - } - - virtual double sloppyFreq(int32_t distance) - { - return 2.0; - } - - virtual double idf(int32_t docFreq, int32_t numDocs) - { - return 1.0; - } - - virtual double coord(int32_t overlap, int32_t maxOverlap) - { - return 1.0; - } - - virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) - { - return newLucene(); - } - }; - - class TermQueryCollector : public Collector - { - public: - virtual ~TermQueryCollector() - { - } - - protected: - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - EXPECT_EQ(1.0, scorer->score()); - } - - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - } - - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; - - class BooleanQueryCollector : public Collector - { - public: - BooleanQueryCollector() - { - this->base = 0; - } - - virtual ~BooleanQueryCollector() - { - } - - protected: - int32_t base; - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - EXPECT_EQ((double)doc + (double)base + 1.0, scorer->score()); - } - - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - base = docBase; - } - - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; - - class PhraseQueryCollector : public Collector - { - public: - PhraseQueryCollector(double expectedScore) - { - this->expectedScore = expectedScore; - } - - virtual ~PhraseQueryCollector() - { - } - - protected: - double expectedScore; - ScorerPtr scorer; - - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } - - virtual void collect(int32_t doc) - { - EXPECT_EQ(expectedScore, scorer->score()); - } - - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - } - - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; +namespace TestSimilarity { + +class SimpleIDFExplanation : public IDFExplanation { +public: + virtual ~SimpleIDFExplanation() { + } + +public: + virtual double getIdf() { + return 1.0; + } + + virtual String explain() { + return L"Inexplicable"; + } +}; + +class SimpleSimilarity : public Similarity { +public: + virtual ~SimpleSimilarity() { + } + +public: + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { + return 1.0; + } + + virtual double queryNorm(double sumOfSquaredWeights) { + return 1.0; + } + + virtual double tf(double freq) { + return freq; + } + + virtual double sloppyFreq(int32_t distance) { + return 2.0; + } + + virtual double idf(int32_t docFreq, int32_t numDocs) { + return 1.0; + } + + virtual double coord(int32_t overlap, int32_t maxOverlap) { + return 1.0; + } + + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) { + return newLucene(); + } +}; + +class TermQueryCollector : public Collector { +public: + virtual ~TermQueryCollector() { + } + +protected: + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + EXPECT_EQ(1.0, scorer->score()); + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + } + + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; + +class BooleanQueryCollector : public Collector { +public: + BooleanQueryCollector() { + this->base = 0; + } + + virtual ~BooleanQueryCollector() { + } + +protected: + int32_t base; + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + EXPECT_EQ((double)doc + (double)base + 1.0, scorer->score()); + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + base = docBase; + } + + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; + +class PhraseQueryCollector : public Collector { +public: + PhraseQueryCollector(double expectedScore) { + this->expectedScore = expectedScore; + } + + virtual ~PhraseQueryCollector() { + } + +protected: + double expectedScore; + ScorerPtr scorer; + +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } + + virtual void collect(int32_t doc) { + EXPECT_EQ(expectedScore, scorer->score()); + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + } + + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; + } -TEST_F(SimilarityTest, testSimilarity) -{ +TEST_F(SimilarityTest, testSimilarity) { RAMDirectoryPtr store = newLucene(); IndexWriterPtr writer = newLucene(store, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setSimilarity(newLucene()); diff --git a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp index b59f6725..513171ba 100644 --- a/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp +++ b/src/test/search/SimpleExplanationsOfNonMatchesTest.cpp @@ -32,262 +32,221 @@ using namespace Lucene; -class ItemizedFilter : public FieldCacheTermsFilter -{ +class ItemizedFilter : public FieldCacheTermsFilter { public: - ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) - { + ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) - { + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - virtual ~ItemizedFilter() - { + virtual ~ItemizedFilter() { } public: - Collection int2str(Collection terms) - { + Collection int2str(Collection terms) { Collection out = Collection::newInstance(terms.size()); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { out[i] = StringUtils::toString(terms[i]); + } return out; } }; /// TestExplanations subclass focusing on basic query types -class SimpleExplanationsOfNonMatchesTest : public ExplanationsFixture -{ +class SimpleExplanationsOfNonMatchesTest : public ExplanationsFixture { public: - SimpleExplanationsOfNonMatchesTest() - { + SimpleExplanationsOfNonMatchesTest() { } - virtual ~SimpleExplanationsOfNonMatchesTest() - { + virtual ~SimpleExplanationsOfNonMatchesTest() { } public: using ExplanationsFixture::qtest; /// ignore matches and focus on non-matches - virtual void qtest(const QueryPtr& q, Collection expDocNrs) - { + virtual void qtest(const QueryPtr& q, Collection expDocNrs) { CheckHits::checkNoMatchExplanations(q, FIELD, searcher, expDocNrs); } }; -TEST_F(SimpleExplanationsOfNonMatchesTest, testT1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testT1) { qtest(L"w1", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testT2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testT2) { qtest(L"w1^1000", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMA1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMA1) { qtest(newLucene(), newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMA2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMA2) { QueryPtr q = newLucene(); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testP1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testP1) { qtest(L"\"w1 w2\"", newCollection(0)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testP2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testP2) { qtest(L"\"w1 w3\"", newCollection(1, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testP3) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testP3) { qtest(L"\"w1 w2\"~1", newCollection(0, 1, 2)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testP4) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testP4) { qtest(L"\"w2 w3\"~1", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testP5) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testP5) { qtest(L"\"w3 w2\"~1", newCollection(1, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testP6) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testP6) { qtest(L"\"w3 w2\"~2", newCollection(0, 1, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testP7) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testP7) { qtest(L"\"w3 w2\"~3", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ1) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 1, 2, 3))), newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ2) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 2, 3))), newCollection(0, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ3) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ3) { qtest(newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))), newCollection(3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ4) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ4) { qtest(newLucene(qp->parse(L"xx^1000"), newLucene(newCollection(1, 3))), newCollection(3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ6) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testFQ6) { QueryPtr q = newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))); q->setBoost(1000); qtest(q, newCollection(3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ1) { QueryPtr q = newLucene(newLucene(newCollection(0, 1, 2, 3))); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ2) { QueryPtr q = newLucene(newLucene(newCollection(1, 3))); qtest(q, newCollection(1, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ3) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testCSQ3) { QueryPtr q = newLucene(newLucene(newCollection(0, 2))); q->setBoost(1000); qtest(q, newCollection(0, 2)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ1) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(qp->parse(L"w1")); q->add(qp->parse(L"w5")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ2) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"w1")); q->add(qp->parse(L"w5")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ3) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ3) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); q->add(qp->parse(L"w5")); qtest(q, newCollection(0)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ4) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ4) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); q->add(qp->parse(L"xx")); qtest(q, newCollection(2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ5) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ5) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy -QQ")); q->add(qp->parse(L"xx")); qtest(q, newCollection(2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ6) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ6) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); q->add(qp->parse(L"xx")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ7) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ7) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); q->add(qp->parse(L"w2")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ8) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ8) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); q->add(qp->parse(L"xx^100000")); qtest(q, newCollection(0, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ9) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testDMQ9) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); q->add(qp->parse(L"xx^0")); qtest(q, newCollection(0, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ1) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2", L"w3", L"xx"))); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ2) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2", L"w3"))); qtest(q, newCollection(0, 1, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ3) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ3) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"xx"))); q->add(ta(newCollection(L"w2", L"w3"))); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ4) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ4) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2"))); qtest(q, newCollection(0)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ5) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ5) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2"))); @@ -295,8 +254,7 @@ TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ5) qtest(q, newCollection(0, 1, 2)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ6) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ6) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"w3"))); q->add(ta(newCollection(L"w2"))); @@ -304,100 +262,83 @@ TEST_F(SimpleExplanationsOfNonMatchesTest, testMPQ6) qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ1) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ1) { qtest(L"+w1 +w2", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ2) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ2) { qtest(L"+yy +w3", newCollection(2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ3) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ3) { qtest(L"yy +w3", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ4) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ4) { qtest(L"w1 (-xx w2)", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ5) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ5) { qtest(L"w1 (+qq w2)", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ6) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ6) { qtest(L"w1 -(-qq w5)", newCollection(1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ7) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ7) { qtest(L"+w1 +(qq (xx -w2) (+w3 +w4))", newCollection(0)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ8) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ8) { qtest(L"+w1 (qq (xx -w2) (+w3 +w4))", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ9) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ9) { qtest(L"+w1 (qq (-xx w2) -(+w3 +w4))", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ10) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ10) { qtest(L"+w1 +(qq (-xx w2) -(+w3 +w4))", newCollection(1)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ11) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ11) { qtest(L"w1 w2^1000.0", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ14) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ14) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); q->add(qp->parse(L"w1"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ15) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ15) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::MUST_NOT); q->add(qp->parse(L"w1"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ16) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ16) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); q->add(qp->parse(L"w1 -xx"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ17) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ17) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"w2"), BooleanClause::SHOULD); q->add(qp->parse(L"w1 -xx"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ19) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ19) { qtest(L"-yy w3", newCollection(0, 1)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ20) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ20) { BooleanQueryPtr q = newLucene(); q->setMinimumNumberShouldMatch(2); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); @@ -408,8 +349,7 @@ TEST_F(SimpleExplanationsOfNonMatchesTest, testBQ20) qtest(q, newCollection(0, 3)); } -TEST_F(SimpleExplanationsOfNonMatchesTest, testTermQueryMultiSearcherExplain) -{ +TEST_F(SimpleExplanationsOfNonMatchesTest, testTermQueryMultiSearcherExplain) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); DirectoryPtr indexStoreB = newLucene(); @@ -436,9 +376,9 @@ TEST_F(SimpleExplanationsOfNonMatchesTest, testTermQueryMultiSearcherExplain) QueryPtr query = parser->parse(L"handle:1"); Collection searchers = newCollection( - newLucene(indexStoreB, true), - newLucene(indexStoreA, true) - ); + newLucene(indexStoreB, true), + newLucene(indexStoreA, true) + ); SearcherPtr mSearcher = newLucene(searchers); Collection hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; diff --git a/src/test/search/SimpleExplanationsTest.cpp b/src/test/search/SimpleExplanationsTest.cpp index 9cbd2be6..e75d3e3c 100644 --- a/src/test/search/SimpleExplanationsTest.cpp +++ b/src/test/search/SimpleExplanationsTest.cpp @@ -31,253 +31,213 @@ using namespace Lucene; -class ItemizedFilter : public FieldCacheTermsFilter -{ +class ItemizedFilter : public FieldCacheTermsFilter { public: - ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) - { + ItemizedFilter(const String& field, Collection terms) : FieldCacheTermsFilter(field, int2str(terms)) { } - ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) - { + ItemizedFilter(Collection terms) : FieldCacheTermsFilter(L"KEY", int2str(terms)) { } - virtual ~ItemizedFilter() - { + virtual ~ItemizedFilter() { } public: - Collection int2str(Collection terms) - { + Collection int2str(Collection terms) { Collection out = Collection::newInstance(terms.size()); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { out[i] = StringUtils::toString(terms[i]); + } return out; } }; /// TestExplanations subclass focusing on basic query types -class SimpleExplanationsTest : public ExplanationsFixture -{ +class SimpleExplanationsTest : public ExplanationsFixture { public: - SimpleExplanationsTest() - { + SimpleExplanationsTest() { } - virtual ~SimpleExplanationsTest() - { + virtual ~SimpleExplanationsTest() { } }; -TEST_F(SimpleExplanationsTest, testT1) -{ +TEST_F(SimpleExplanationsTest, testT1) { qtest(L"w1", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testT2) -{ +TEST_F(SimpleExplanationsTest, testT2) { qtest(L"w1^1000", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testMA1) -{ +TEST_F(SimpleExplanationsTest, testMA1) { qtest(newLucene(), newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testMA2) -{ +TEST_F(SimpleExplanationsTest, testMA2) { QueryPtr q = newLucene(); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testP1) -{ +TEST_F(SimpleExplanationsTest, testP1) { qtest(L"\"w1 w2\"", newCollection(0)); } -TEST_F(SimpleExplanationsTest, testP2) -{ +TEST_F(SimpleExplanationsTest, testP2) { qtest(L"\"w1 w3\"", newCollection(1, 3)); } -TEST_F(SimpleExplanationsTest, testP3) -{ +TEST_F(SimpleExplanationsTest, testP3) { qtest(L"\"w1 w2\"~1", newCollection(0, 1, 2)); } -TEST_F(SimpleExplanationsTest, testP4) -{ +TEST_F(SimpleExplanationsTest, testP4) { qtest(L"\"w2 w3\"~1", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testP5) -{ +TEST_F(SimpleExplanationsTest, testP5) { qtest(L"\"w3 w2\"~1", newCollection(1, 3)); } -TEST_F(SimpleExplanationsTest, testP6) -{ +TEST_F(SimpleExplanationsTest, testP6) { qtest(L"\"w3 w2\"~2", newCollection(0, 1, 3)); } -TEST_F(SimpleExplanationsTest, testP7) -{ +TEST_F(SimpleExplanationsTest, testP7) { qtest(L"\"w3 w2\"~3", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testFQ1) -{ +TEST_F(SimpleExplanationsTest, testFQ1) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 1, 2, 3))), newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testFQ2) -{ +TEST_F(SimpleExplanationsTest, testFQ2) { qtest(newLucene(qp->parse(L"w1"), newLucene(newCollection(0, 2, 3))), newCollection(0, 2, 3)); } -TEST_F(SimpleExplanationsTest, testFQ3) -{ +TEST_F(SimpleExplanationsTest, testFQ3) { qtest(newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))), newCollection(3)); } -TEST_F(SimpleExplanationsTest, testFQ4) -{ +TEST_F(SimpleExplanationsTest, testFQ4) { qtest(newLucene(qp->parse(L"xx^1000"), newLucene(newCollection(1, 3))), newCollection(3)); } -TEST_F(SimpleExplanationsTest, testFQ6) -{ +TEST_F(SimpleExplanationsTest, testFQ6) { QueryPtr q = newLucene(qp->parse(L"xx"), newLucene(newCollection(1, 3))); q->setBoost(1000); qtest(q, newCollection(3)); } -TEST_F(SimpleExplanationsTest, testCSQ1) -{ +TEST_F(SimpleExplanationsTest, testCSQ1) { QueryPtr q = newLucene(newLucene(newCollection(0, 1, 2, 3))); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testCSQ2) -{ +TEST_F(SimpleExplanationsTest, testCSQ2) { QueryPtr q = newLucene(newLucene(newCollection(1, 3))); qtest(q, newCollection(1, 3)); } -TEST_F(SimpleExplanationsTest, testCSQ3) -{ +TEST_F(SimpleExplanationsTest, testCSQ3) { QueryPtr q = newLucene(newLucene(newCollection(0, 2))); q->setBoost(1000); qtest(q, newCollection(0, 2)); } -TEST_F(SimpleExplanationsTest, testDMQ1) -{ +TEST_F(SimpleExplanationsTest, testDMQ1) { DisjunctionMaxQueryPtr q = newLucene(0.0); q->add(qp->parse(L"w1")); q->add(qp->parse(L"w5")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testDMQ2) -{ +TEST_F(SimpleExplanationsTest, testDMQ2) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"w1")); q->add(qp->parse(L"w5")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testDMQ3) -{ +TEST_F(SimpleExplanationsTest, testDMQ3) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); q->add(qp->parse(L"w5")); qtest(q, newCollection(0)); } -TEST_F(SimpleExplanationsTest, testDMQ4) -{ +TEST_F(SimpleExplanationsTest, testDMQ4) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"QQ")); q->add(qp->parse(L"xx")); qtest(q, newCollection(2, 3)); } -TEST_F(SimpleExplanationsTest, testDMQ5) -{ +TEST_F(SimpleExplanationsTest, testDMQ5) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy -QQ")); q->add(qp->parse(L"xx")); qtest(q, newCollection(2, 3)); } -TEST_F(SimpleExplanationsTest, testDMQ6) -{ +TEST_F(SimpleExplanationsTest, testDMQ6) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); q->add(qp->parse(L"xx")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testDMQ7) -{ +TEST_F(SimpleExplanationsTest, testDMQ7) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"-yy w3")); q->add(qp->parse(L"w2")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testDMQ8) -{ +TEST_F(SimpleExplanationsTest, testDMQ8) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); q->add(qp->parse(L"xx^100000")); qtest(q, newCollection(0, 2, 3)); } -TEST_F(SimpleExplanationsTest, testDMQ9) -{ +TEST_F(SimpleExplanationsTest, testDMQ9) { DisjunctionMaxQueryPtr q = newLucene(0.5); q->add(qp->parse(L"yy w5^100")); q->add(qp->parse(L"xx^0")); qtest(q, newCollection(0, 2, 3)); } -TEST_F(SimpleExplanationsTest, testMPQ1) -{ +TEST_F(SimpleExplanationsTest, testMPQ1) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2", L"w3", L"xx"))); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testMPQ2) -{ +TEST_F(SimpleExplanationsTest, testMPQ2) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2", L"w3"))); qtest(q, newCollection(0, 1, 3)); } -TEST_F(SimpleExplanationsTest, testMPQ3) -{ +TEST_F(SimpleExplanationsTest, testMPQ3) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"xx"))); q->add(ta(newCollection(L"w2", L"w3"))); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testMPQ4) -{ +TEST_F(SimpleExplanationsTest, testMPQ4) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2"))); qtest(q, newCollection(0)); } -TEST_F(SimpleExplanationsTest, testMPQ5) -{ +TEST_F(SimpleExplanationsTest, testMPQ5) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1"))); q->add(ta(newCollection(L"w2"))); @@ -285,8 +245,7 @@ TEST_F(SimpleExplanationsTest, testMPQ5) qtest(q, newCollection(0, 1, 2)); } -TEST_F(SimpleExplanationsTest, testMPQ6) -{ +TEST_F(SimpleExplanationsTest, testMPQ6) { MultiPhraseQueryPtr q = newLucene(); q->add(ta(newCollection(L"w1", L"w3"))); q->add(ta(newCollection(L"w2"))); @@ -294,100 +253,83 @@ TEST_F(SimpleExplanationsTest, testMPQ6) qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ1) -{ +TEST_F(SimpleExplanationsTest, testBQ1) { qtest(L"+w1 +w2", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ2) -{ +TEST_F(SimpleExplanationsTest, testBQ2) { qtest(L"+yy +w3", newCollection(2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ3) -{ +TEST_F(SimpleExplanationsTest, testBQ3) { qtest(L"yy +w3", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ4) -{ +TEST_F(SimpleExplanationsTest, testBQ4) { qtest(L"w1 (-xx w2)", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ5) -{ +TEST_F(SimpleExplanationsTest, testBQ5) { qtest(L"w1 (+qq w2)", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ6) -{ +TEST_F(SimpleExplanationsTest, testBQ6) { qtest(L"w1 -(-qq w5)", newCollection(1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ7) -{ +TEST_F(SimpleExplanationsTest, testBQ7) { qtest(L"+w1 +(qq (xx -w2) (+w3 +w4))", newCollection(0)); } -TEST_F(SimpleExplanationsTest, testBQ8) -{ +TEST_F(SimpleExplanationsTest, testBQ8) { qtest(L"+w1 (qq (xx -w2) (+w3 +w4))", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ9) -{ +TEST_F(SimpleExplanationsTest, testBQ9) { qtest(L"+w1 (qq (-xx w2) -(+w3 +w4))", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ10) -{ +TEST_F(SimpleExplanationsTest, testBQ10) { qtest(L"+w1 +(qq (-xx w2) -(+w3 +w4))", newCollection(1)); } -TEST_F(SimpleExplanationsTest, testBQ11) -{ +TEST_F(SimpleExplanationsTest, testBQ11) { qtest(L"w1 w2^1000.0", newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ14) -{ +TEST_F(SimpleExplanationsTest, testBQ14) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); q->add(qp->parse(L"w1"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ15) -{ +TEST_F(SimpleExplanationsTest, testBQ15) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::MUST_NOT); q->add(qp->parse(L"w1"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ16) -{ +TEST_F(SimpleExplanationsTest, testBQ16) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); q->add(qp->parse(L"w1 -xx"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1)); } -TEST_F(SimpleExplanationsTest, testBQ17) -{ +TEST_F(SimpleExplanationsTest, testBQ17) { BooleanQueryPtr q = newLucene(true); q->add(qp->parse(L"w2"), BooleanClause::SHOULD); q->add(qp->parse(L"w1 -xx"), BooleanClause::SHOULD); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SimpleExplanationsTest, testBQ19) -{ +TEST_F(SimpleExplanationsTest, testBQ19) { qtest(L"-yy w3", newCollection(0, 1)); } -TEST_F(SimpleExplanationsTest, testBQ20) -{ +TEST_F(SimpleExplanationsTest, testBQ20) { BooleanQueryPtr q = newLucene(); q->setMinimumNumberShouldMatch(2); q->add(qp->parse(L"QQQQQ"), BooleanClause::SHOULD); @@ -398,8 +340,7 @@ TEST_F(SimpleExplanationsTest, testBQ20) qtest(q, newCollection(0, 3)); } -TEST_F(SimpleExplanationsTest, testTermQueryMultiSearcherExplain) -{ +TEST_F(SimpleExplanationsTest, testTermQueryMultiSearcherExplain) { // creating two directories for indices DirectoryPtr indexStoreA = newLucene(); DirectoryPtr indexStoreB = newLucene(); @@ -426,9 +367,9 @@ TEST_F(SimpleExplanationsTest, testTermQueryMultiSearcherExplain) QueryPtr query = parser->parse(L"handle:1"); Collection searchers = newCollection( - newLucene(indexStoreB, true), - newLucene(indexStoreA, true) - ); + newLucene(indexStoreB, true), + newLucene(indexStoreA, true) + ); SearcherPtr mSearcher = newLucene(searchers); Collection hits = mSearcher->search(query, FilterPtr(), 1000)->scoreDocs; diff --git a/src/test/search/SloppyPhraseQueryTest.cpp b/src/test/search/SloppyPhraseQueryTest.cpp index 855dcd0a..82ba3f3c 100644 --- a/src/test/search/SloppyPhraseQueryTest.cpp +++ b/src/test/search/SloppyPhraseQueryTest.cpp @@ -18,11 +18,9 @@ using namespace Lucene; -class SloppyPhraseQueryTest : public LuceneTestFixture -{ +class SloppyPhraseQueryTest : public LuceneTestFixture { public: - SloppyPhraseQueryTest() - { + SloppyPhraseQueryTest() { S_1 = L"A A A"; S_2 = L"A 1 2 3 A 4 5 6 A"; @@ -39,8 +37,7 @@ class SloppyPhraseQueryTest : public LuceneTestFixture QUERY_4 = makePhraseQuery(L"X A A"); } - virtual ~SloppyPhraseQueryTest() - { + virtual ~SloppyPhraseQueryTest() { } protected: @@ -60,8 +57,7 @@ class SloppyPhraseQueryTest : public LuceneTestFixture PhraseQueryPtr QUERY_4; public: - DocumentPtr makeDocument(const String& docText) - { + DocumentPtr makeDocument(const String& docText) { DocumentPtr doc = newLucene(); FieldPtr f = newLucene(L"f", docText, Field::STORE_NO, Field::INDEX_ANALYZED); f->setOmitNorms(true); @@ -69,17 +65,16 @@ class SloppyPhraseQueryTest : public LuceneTestFixture return doc; } - PhraseQueryPtr makePhraseQuery(const String& terms) - { + PhraseQueryPtr makePhraseQuery(const String& terms) { PhraseQueryPtr query = newLucene(); Collection tokens = StringUtils::split(terms, L" +"); - for (int32_t i = 0; i < tokens.size(); ++i) + for (int32_t i = 0; i < tokens.size(); ++i) { query->add(newLucene(L"f", tokens[i])); + } return query; } - double checkPhraseQuery(const DocumentPtr& doc, const PhraseQueryPtr& query, int32_t slop, int32_t expectedNumResults) - { + double checkPhraseQuery(const DocumentPtr& doc, const PhraseQueryPtr& query, int32_t slop, int32_t expectedNumResults) { query->setSlop(slop); RAMDirectoryPtr ramDir = newLucene(); @@ -102,10 +97,8 @@ class SloppyPhraseQueryTest : public LuceneTestFixture /// Test DOC_4 and QUERY_4. /// QUERY_4 has a fuzzy (len=1) match to DOC_4, so all slop values > 0 should succeed. /// But only the 3rd sequence of A's in DOC_4 will do. -TEST_F(SloppyPhraseQueryTest, testDoc4Query4AllSlopsShouldMatch) -{ - for (int32_t slop = 0; slop < 30; ++slop) - { +TEST_F(SloppyPhraseQueryTest, testDoc4Query4AllSlopsShouldMatch) { + for (int32_t slop = 0; slop < 30; ++slop) { int32_t numResultsExpected = slop < 1 ? 0 : 1; checkPhraseQuery(DOC_4, QUERY_4, slop, numResultsExpected); } @@ -113,10 +106,8 @@ TEST_F(SloppyPhraseQueryTest, testDoc4Query4AllSlopsShouldMatch) /// Test DOC_1 and QUERY_1. /// QUERY_1 has an exact match to DOC_1, so all slop values should succeed. -TEST_F(SloppyPhraseQueryTest, testDoc1Query1AllSlopsShouldMatch) -{ - for (int32_t slop = 0; slop < 30; ++slop) - { +TEST_F(SloppyPhraseQueryTest, testDoc1Query1AllSlopsShouldMatch) { + for (int32_t slop = 0; slop < 30; ++slop) { double score1 = checkPhraseQuery(DOC_1, QUERY_1, slop, 1); double score2 = checkPhraseQuery(DOC_1_B, QUERY_1, slop, 1); EXPECT_TRUE(score2 > score1); @@ -125,14 +116,11 @@ TEST_F(SloppyPhraseQueryTest, testDoc1Query1AllSlopsShouldMatch) /// Test DOC_2 and QUERY_1. /// 6 should be the minimum slop to make QUERY_1 match DOC_2. -TEST_F(SloppyPhraseQueryTest, testDoc2Query1Slop6OrMoreShouldMatch) -{ - for (int32_t slop = 0; slop < 30; ++slop) - { +TEST_F(SloppyPhraseQueryTest, testDoc2Query1Slop6OrMoreShouldMatch) { + for (int32_t slop = 0; slop < 30; ++slop) { int32_t numResultsExpected = slop < 6 ? 0 : 1; double score1 = checkPhraseQuery(DOC_2, QUERY_1, slop, numResultsExpected); - if (numResultsExpected > 0) - { + if (numResultsExpected > 0) { double score2 = checkPhraseQuery(DOC_2_B, QUERY_1, slop, 1); EXPECT_TRUE(score2 > score1); } @@ -141,10 +129,8 @@ TEST_F(SloppyPhraseQueryTest, testDoc2Query1Slop6OrMoreShouldMatch) /// Test DOC_2 and QUERY_2. /// QUERY_2 has an exact match to DOC_2, so all slop values should succeed. -TEST_F(SloppyPhraseQueryTest, testDoc2Query2AllSlopsShouldMatch) -{ - for (int32_t slop = 0; slop < 30; ++slop) - { +TEST_F(SloppyPhraseQueryTest, testDoc2Query2AllSlopsShouldMatch) { + for (int32_t slop = 0; slop < 30; ++slop) { double score1 = checkPhraseQuery(DOC_2, QUERY_2, slop, 1); double score2 = checkPhraseQuery(DOC_2_B, QUERY_2, slop, 1); EXPECT_TRUE(score2 > score1); @@ -153,10 +139,8 @@ TEST_F(SloppyPhraseQueryTest, testDoc2Query2AllSlopsShouldMatch) /// Test DOC_3 and QUERY_1. /// QUERY_1 has an exact match to DOC_3, so all slop values should succeed. -TEST_F(SloppyPhraseQueryTest, testDoc3Query1AllSlopsShouldMatch) -{ - for (int32_t slop = 0; slop < 30; ++slop) - { +TEST_F(SloppyPhraseQueryTest, testDoc3Query1AllSlopsShouldMatch) { + for (int32_t slop = 0; slop < 30; ++slop) { double score1 = checkPhraseQuery(DOC_3, QUERY_1, slop, 1); double score2 = checkPhraseQuery(DOC_3_B, QUERY_1, slop, 1); EXPECT_TRUE(score2 > score1); diff --git a/src/test/search/SortTest.cpp b/src/test/search/SortTest.cpp index fa2176cf..a9367321 100644 --- a/src/test/search/SortTest.cpp +++ b/src/test/search/SortTest.cpp @@ -37,11 +37,9 @@ using namespace Lucene; -class SortTest : public LuceneTestFixture -{ +class SortTest : public LuceneTestFixture { public: - SortTest() - { + SortTest() { r = newLucene(); // document data: @@ -78,8 +76,7 @@ class SortTest : public LuceneTestFixture sort = newLucene(); } - virtual ~SortTest() - { + virtual ~SortTest() { } protected: @@ -100,55 +97,56 @@ class SortTest : public LuceneTestFixture Collection< Collection > data; protected: - SearcherPtr getFullIndex() - { + SearcherPtr getFullIndex() { return getIndex(true, true); } - SearcherPtr getXIndex() - { + SearcherPtr getXIndex() { return getIndex(true, false); } - SearcherPtr getYIndex() - { + SearcherPtr getYIndex() { return getIndex(false, true); } - SearcherPtr getEmptyIndex() - { + SearcherPtr getEmptyIndex() { return getIndex(false, false); } - SearcherPtr getIndex(bool even, bool odd) - { + SearcherPtr getIndex(bool even, bool odd) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(2); writer->setMergeFactor(1000); - for (int32_t i = 0; i < data.size(); ++i) - { - if (((i % 2) == 0 && even) || ((i % 2) == 1 && odd)) - { + for (int32_t i = 0; i < data.size(); ++i) { + if (((i % 2) == 0 && even) || ((i % 2) == 1 && odd)) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"tracer", data[i][0], Field::STORE_YES, Field::INDEX_NO)); doc->add(newLucene(L"contents", data[i][1], Field::STORE_NO, Field::INDEX_ANALYZED)); - if (!data[i][2].empty()) + if (!data[i][2].empty()) { doc->add(newLucene(L"int", data[i][2], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (!data[i][3].empty()) + } + if (!data[i][3].empty()) { doc->add(newLucene(L"double", data[i][3], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (!data[i][4].empty()) + } + if (!data[i][4].empty()) { doc->add(newLucene(L"string", data[i][4], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (!data[i][5].empty()) + } + if (!data[i][5].empty()) { doc->add(newLucene(L"custom", data[i][5], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (!data[i][6].empty()) + } + if (!data[i][6].empty()) { doc->add(newLucene(L"i18n", data[i][6], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (!data[i][7].empty()) + } + if (!data[i][7].empty()) { doc->add(newLucene(L"long", data[i][7], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (!data[i][8].empty()) + } + if (!data[i][8].empty()) { doc->add(newLucene(L"byte", data[i][8], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (!data[i][9].empty()) + } + if (!data[i][9].empty()) { doc->add(newLucene(L"parser", data[i][9], Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); + } doc->setBoost(2); // produce some scores above 1.0 writer->addDocument(doc); } @@ -159,12 +157,10 @@ class SortTest : public LuceneTestFixture return s; } - MapStringDouble getScores(Collection hits, const SearcherPtr& searcher) - { + MapStringDouble getScores(Collection hits, const SearcherPtr& searcher) { MapStringDouble scoreMap = MapStringDouble::newInstance(); int32_t n = hits.size(); - for (int32_t i = 0; i < n; ++i) - { + for (int32_t i = 0; i < n; ++i) { DocumentPtr doc = searcher->doc(hits[i]->doc); Collection v = doc->getValues(L"tracer"); EXPECT_EQ(v.size(), 1); @@ -173,13 +169,11 @@ class SortTest : public LuceneTestFixture return scoreMap; } - void checkSameValues(MapStringDouble m1, MapStringDouble m2) - { + void checkSameValues(MapStringDouble m1, MapStringDouble m2) { int32_t n = m1.size(); int32_t m = m2.size(); EXPECT_EQ(n, m); - for (MapStringDouble::iterator key = m1.begin(); key != m1.end(); ++key) - { + for (MapStringDouble::iterator key = m1.begin(); key != m1.end(); ++key) { double o1 = m1.get(key->first); double o2 = m2.get(key->first); EXPECT_NEAR(o1, o2, 1e-6); @@ -187,31 +181,28 @@ class SortTest : public LuceneTestFixture } /// make sure the documents returned by the search match the expected list - void checkMatches(const SearcherPtr& searcher, const QueryPtr& query, const SortPtr& sort, const String& expectedResult) - { + void checkMatches(const SearcherPtr& searcher, const QueryPtr& query, const SortPtr& sort, const String& expectedResult) { TopDocsPtr hits = searcher->search(query, FilterPtr(), expectedResult.length(), sort); Collection result = hits->scoreDocs; EXPECT_EQ(hits->totalHits, expectedResult.length()); StringStream buff; int32_t n = result.size(); - for (int32_t i = 0; i < n; ++i) - { + for (int32_t i = 0; i < n; ++i) { DocumentPtr doc = searcher->doc(result[i]->doc); Collection v = doc->getValues(L"tracer"); - for (int32_t j = 0; j < v.size(); ++j) + for (int32_t j = 0; j < v.size(); ++j) { buff << v[j]; + } } EXPECT_EQ(expectedResult, buff.str()); } - IndexSearcherPtr getFullStrings() - { + IndexSearcherPtr getFullStrings() { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(4); writer->setMergeFactor(97); - for (int32_t i = 0; i < NUM_STRINGS; ++i) - { + for (int32_t i = 0; i < NUM_STRINGS; ++i) { DocumentPtr doc = newLucene(); String num = getRandomCharString(getRandomNumber(2, 8), 48, 52); doc->add(newLucene(L"tracer", num, Field::STORE_YES, Field::INDEX_NO)); @@ -227,43 +218,39 @@ class SortTest : public LuceneTestFixture return newLucene(indexStore, true); } - String getRandomNumberString(int32_t num, int32_t low, int32_t high) - { + String getRandomNumberString(int32_t num, int32_t low, int32_t high) { StringStream buff; - for (int32_t i = 0; i < num; ++i) + for (int32_t i = 0; i < num; ++i) { buff << getRandomNumber(low, high); + } return buff.str(); } - String getRandomCharString(int32_t num) - { + String getRandomCharString(int32_t num) { return getRandomCharString(num, 48, 122); } - String getRandomCharString(int32_t num, int32_t start, int32_t end) - { + String getRandomCharString(int32_t num, int32_t start, int32_t end) { static const wchar_t* alphanum = L"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz"; StringStream buff; - for (int32_t i = 0; i < num; ++i) + for (int32_t i = 0; i < num; ++i) { buff << alphanum[getRandomNumber(start, end)]; + } return buff.str(); } - int32_t getRandomNumber(int32_t low, int32_t high) - { + int32_t getRandomNumber(int32_t low, int32_t high) { return (std::abs(r->nextInt()) % (high - low)) + low; } - void checkSaneFieldCaches() - { + void checkSaneFieldCaches() { Collection entries = FieldCache::DEFAULT()->getCacheEntries(); Collection insanity = FieldCacheSanityChecker::checkSanity(entries); EXPECT_EQ(0, insanity.size()); } /// runs a variety of sorts useful for multisearchers - void runMultiSorts(const SearcherPtr& multi, bool isFull) - { + void runMultiSorts(const SearcherPtr& multi, bool isFull) { sort->setSort(SortField::FIELD_DOC()); String expected = isFull ? L"ABCDEFGHIJ" : L"ACEGIBDFHJ"; checkMatches(multi, queryA, sort, expected); @@ -344,8 +331,7 @@ class SortTest : public LuceneTestFixture const int32_t SortTest::NUM_STRINGS = 6000; /// test the sorts by score and document number -TEST_F(SortTest, testBuiltInSorts) -{ +TEST_F(SortTest, testBuiltInSorts) { sort = newLucene(); checkMatches(full, queryX, sort, L"ACEGI"); checkMatches(full, queryY, sort, L"BDFHJ"); @@ -356,8 +342,7 @@ TEST_F(SortTest, testBuiltInSorts) } /// test sorts where the type of field is specified -TEST_F(SortTest, testTypedSort) -{ +TEST_F(SortTest, testTypedSort) { sort->setSort(newCollection(newLucene(L"int", SortField::INT), SortField::FIELD_DOC())); checkMatches(full, queryX, sort, L"IGAEC"); checkMatches(full, queryY, sort, L"DHFJB"); @@ -380,8 +365,7 @@ TEST_F(SortTest, testTypedSort) } /// Test String sorting: small queue to many matches, multi field sort, reverse sort -TEST_F(SortTest, testStringSort) -{ +TEST_F(SortTest, testStringSort) { IndexSearcherPtr searcher = getFullStrings(); sort->setSort(newCollection(newLucene(L"string", SortField::STRING), newLucene(L"string2", SortField::STRING, true), SortField::FIELD_DOC())); Collection result = searcher->search(newLucene(), FilterPtr(), 500, sort)->scoreDocs; @@ -391,27 +375,24 @@ TEST_F(SortTest, testStringSort) String last; String lastSub; int32_t lastDocId = 0; - for (int32_t x = 0; x < n; ++x) - { + for (int32_t x = 0; x < n; ++x) { DocumentPtr doc2 = searcher->doc(result[x]->doc); Collection v = doc2->getValues(L"tracer"); Collection v2 = doc2->getValues(L"tracer2"); - for (int32_t j = 0; j < v.size(); ++j) - { - if (!last.empty()) - { + for (int32_t j = 0; j < v.size(); ++j) { + if (!last.empty()) { int32_t cmp = v[j].compare(last); - if (cmp < 0) + if (cmp < 0) { FAIL() << "first field out of order"; - if (cmp == 0) // ensure second field is in reverse order - { + } + if (cmp == 0) { // ensure second field is in reverse order cmp = v2[j].compare(lastSub); - if (cmp > 0) + if (cmp > 0) { FAIL() << "second field out of order"; - else if (cmp == 0) // ensure docid is in order - { - if (result[x]->doc < lastDocId) + } else if (cmp == 0) { // ensure docid is in order + if (result[x]->doc < lastDocId) { FAIL() << "docid out of order"; + } } } @@ -424,70 +405,58 @@ TEST_F(SortTest, testStringSort) } } -namespace TestCustomFieldParserSort -{ - class CustomIntParser : public IntParser - { - public: - virtual ~CustomIntParser() - { - } +namespace TestCustomFieldParserSort { - public: - virtual int32_t parseInt(const String& string) - { - return (string[0] - L'A') * 123456; - } - }; +class CustomIntParser : public IntParser { +public: + virtual ~CustomIntParser() { + } - class CustomDoubleParser : public DoubleParser - { - public: - virtual ~CustomDoubleParser() - { - } +public: + virtual int32_t parseInt(const String& string) { + return (string[0] - L'A') * 123456; + } +}; - public: - virtual double parseDouble(const String& string) - { - return std::sqrt((double)string[0]); - } - }; +class CustomDoubleParser : public DoubleParser { +public: + virtual ~CustomDoubleParser() { + } - class CustomLongParser : public LongParser - { - public: - virtual ~CustomLongParser() - { - } +public: + virtual double parseDouble(const String& string) { + return std::sqrt((double)string[0]); + } +}; - public: - virtual int64_t parseLong(const String& string) - { - return (string[0] - L'A') * (int64_t)1234567890; - } - }; +class CustomLongParser : public LongParser { +public: + virtual ~CustomLongParser() { + } - class CustomByteParser : public ByteParser - { - public: - virtual ~CustomByteParser() - { - } +public: + virtual int64_t parseLong(const String& string) { + return (string[0] - L'A') * (int64_t)1234567890; + } +}; + +class CustomByteParser : public ByteParser { +public: + virtual ~CustomByteParser() { + } + +public: + virtual uint8_t parseByte(const String& string) { + return (uint8_t)(string[0] - L'A'); + } +}; - public: - virtual uint8_t parseByte(const String& string) - { - return (uint8_t)(string[0] - L'A'); - } - }; } /// Test sorts where the type of field is specified and a custom field parser is used, that uses a simple char encoding. /// The sorted string contains a character beginning from 'A' that is mapped to a numeric value using some "funny" /// algorithm to be different for each data type. -TEST_F(SortTest, testCustomFieldParserSort) -{ +TEST_F(SortTest, testCustomFieldParserSort) { // since tests explicitly uses different parsers on the same field name we explicitly check/purge the FieldCache between each assertMatch FieldCachePtr fc = FieldCache::DEFAULT(); @@ -513,8 +482,7 @@ TEST_F(SortTest, testCustomFieldParserSort) } /// test sorts when there's nothing in the index -TEST_F(SortTest, testEmptyIndex) -{ +TEST_F(SortTest, testEmptyIndex) { SearcherPtr empty = getEmptyIndex(); sort = newLucene(); @@ -533,97 +501,81 @@ TEST_F(SortTest, testEmptyIndex) checkMatches(empty, queryX, sort, L""); } -namespace TestNewCustomFieldParserSort -{ - class MyIntParser : public IntParser - { - public: - virtual ~MyIntParser() - { - } +namespace TestNewCustomFieldParserSort { - public: - virtual int32_t parseInt(const String& string) - { - return (string[0] - L'A') * 123456; - } - }; - - class MyFieldComparator : public FieldComparator - { - public: - MyFieldComparator(int32_t numHits) - { - slotValues = Collection::newInstance(numHits); - bottomValue = 0; - } +class MyIntParser : public IntParser { +public: + virtual ~MyIntParser() { + } - virtual ~MyFieldComparator() - { - } +public: + virtual int32_t parseInt(const String& string) { + return (string[0] - L'A') * 123456; + } +}; - public: - Collection docValues; - Collection slotValues; - int32_t bottomValue; +class MyFieldComparator : public FieldComparator { +public: + MyFieldComparator(int32_t numHits) { + slotValues = Collection::newInstance(numHits); + bottomValue = 0; + } - public: - virtual void copy(int32_t slot, int32_t doc) - { - slotValues[slot] = docValues[doc]; - } + virtual ~MyFieldComparator() { + } - virtual int32_t compare(int32_t slot1, int32_t slot2) - { - return slotValues[slot1] - slotValues[slot2]; - } +public: + Collection docValues; + Collection slotValues; + int32_t bottomValue; - virtual int32_t compareBottom(int32_t doc) - { - return bottomValue - docValues[doc]; - } +public: + virtual void copy(int32_t slot, int32_t doc) { + slotValues[slot] = docValues[doc]; + } - virtual void setBottom(int32_t slot) - { - bottomValue = slotValues[slot]; - } + virtual int32_t compare(int32_t slot1, int32_t slot2) { + return slotValues[slot1] - slotValues[slot2]; + } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - docValues = FieldCache::DEFAULT()->getInts(reader, L"parser", newLucene()); - } + virtual int32_t compareBottom(int32_t doc) { + return bottomValue - docValues[doc]; + } - virtual ComparableValue value(int32_t slot) - { - return slotValues[slot]; - } - }; + virtual void setBottom(int32_t slot) { + bottomValue = slotValues[slot]; + } - class MyFieldComparatorSource : public FieldComparatorSource - { - public: - virtual ~MyFieldComparatorSource() - { - } + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + docValues = FieldCache::DEFAULT()->getInts(reader, L"parser", newLucene()); + } + + virtual ComparableValue value(int32_t slot) { + return slotValues[slot]; + } +}; + +class MyFieldComparatorSource : public FieldComparatorSource { +public: + virtual ~MyFieldComparatorSource() { + } + +public: + virtual FieldComparatorPtr newComparator(const String& fieldname, int32_t numHits, int32_t sortPos, bool reversed) { + return newLucene(numHits); + } +}; - public: - virtual FieldComparatorPtr newComparator(const String& fieldname, int32_t numHits, int32_t sortPos, bool reversed) - { - return newLucene(numHits); - } - }; } // Test sorting with custom FieldComparator -TEST_F(SortTest, testNewCustomFieldParserSort) -{ +TEST_F(SortTest, testNewCustomFieldParserSort) { sort->setSort(newCollection(newLucene(L"parser", newLucene()))); checkMatches(full, queryA, sort, L"JIHGFEDCBA"); } /// test sorts in reverse -TEST_F(SortTest, testReverseSort) -{ +TEST_F(SortTest, testReverseSort) { sort->setSort(newCollection(newLucene(L"", SortField::SCORE, true), SortField::FIELD_DOC())); checkMatches(full, queryX, sort, L"IEGCA"); checkMatches(full, queryY, sort, L"JFHDB"); @@ -646,8 +598,7 @@ TEST_F(SortTest, testReverseSort) } /// test sorting when the sort field is empty (undefined) for some of the documents -TEST_F(SortTest, testEmptyFieldSort) -{ +TEST_F(SortTest, testEmptyFieldSort) { sort->setSort(newCollection(newLucene(L"string", SortField::STRING))); checkMatches(full, queryF, sort, L"ZJI"); @@ -706,8 +657,7 @@ TEST_F(SortTest, testEmptyFieldSort) } /// test sorts using a series of fields -TEST_F(SortTest, testSortCombos) -{ +TEST_F(SortTest, testSortCombos) { sort->setSort(newCollection(newLucene(L"int", SortField::INT), newLucene(L"double", SortField::DOUBLE))); checkMatches(full, queryX, sort, L"IGEAC"); @@ -719,8 +669,7 @@ TEST_F(SortTest, testSortCombos) } /// test using a Locale for sorting strings -TEST_F(SortTest, testLocaleSort) -{ +TEST_F(SortTest, testLocaleSort) { sort->setSort(newCollection(newLucene(L"string", std::locale()))); checkMatches(full, queryX, sort, L"AIGEC"); checkMatches(full, queryY, sort, L"DJHFB"); @@ -731,22 +680,19 @@ TEST_F(SortTest, testLocaleSort) } /// test a variety of sorts using more than one searcher -TEST_F(SortTest, testMultiSort) -{ +TEST_F(SortTest, testMultiSort) { MultiSearcherPtr searcher = newLucene(newCollection(searchX, searchY)); runMultiSorts(searcher, false); } /// test a variety of sorts using a parallel multisearcher -TEST_F(SortTest, testParallelMultiSort) -{ +TEST_F(SortTest, testParallelMultiSort) { MultiSearcherPtr searcher = newLucene(newCollection(searchX, searchY)); runMultiSorts(searcher, false); } // test that the relevancy scores are the same even if hits are sorted -TEST_F(SortTest, testNormalizedScores) -{ +TEST_F(SortTest, testNormalizedScores) { // capture relevancy scores MapStringDouble scoresX = getScores(full->search(queryX, FilterPtr(), 1000)->scoreDocs, full); MapStringDouble scoresY = getScores(full->search(queryY, FilterPtr(), 1000)->scoreDocs, full); @@ -823,36 +769,32 @@ TEST_F(SortTest, testNormalizedScores) checkSameValues(scoresA, getScores(multi->search(queryA, FilterPtr(), 1000, sort)->scoreDocs, multi)); } -namespace TestTopDocsScores -{ - class TopDocsFilter : public Filter - { - public: - TopDocsFilter(const TopDocsPtr& docs) - { - this->docs = docs; - } +namespace TestTopDocsScores { - virtual ~TopDocsFilter() - { - } +class TopDocsFilter : public Filter { +public: + TopDocsFilter(const TopDocsPtr& docs) { + this->docs = docs; + } - protected: - TopDocsPtr docs; + virtual ~TopDocsFilter() { + } + +protected: + TopDocsPtr docs; + +public: + virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) { + BitSetPtr bs = newLucene(reader->maxDoc()); + bs->set((uint32_t)0, (uint32_t)reader->maxDoc()); + bs->set(docs->scoreDocs[0]->doc); + return newLucene(bs); + } +}; - public: - virtual DocIdSetPtr getDocIdSet(const IndexReaderPtr& reader) - { - BitSetPtr bs = newLucene(reader->maxDoc()); - bs->set((uint32_t)0, (uint32_t)reader->maxDoc()); - bs->set(docs->scoreDocs[0]->doc); - return newLucene(bs); - } - }; } -TEST_F(SortTest, testTopDocsScores) -{ +TEST_F(SortTest, testTopDocsScores) { SortPtr sort = newLucene(); int32_t numDocs = 10; @@ -866,28 +808,25 @@ TEST_F(SortTest, testTopDocsScores) EXPECT_NEAR(docs1->scoreDocs[0]->score, docs2->scoreDocs[0]->score, 1e-6); } -TEST_F(SortTest, testSortWithoutFillFields) -{ +TEST_F(SortTest, testSortWithoutFillFields) { Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); - for (int32_t i = 0; i < sort.size(); ++i) - { + for (int32_t i = 0; i < sort.size(); ++i) { QueryPtr q = newLucene(); TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, false, false, false, true); full->search(q, tdc); Collection sd = tdc->topDocs()->scoreDocs; - for (int32_t j = 1; j < sd.size(); ++j) + for (int32_t j = 1; j < sd.size(); ++j) { EXPECT_NE(sd[j]->doc, sd[j - 1]->doc); + } } } -TEST_F(SortTest, testSortWithoutScoreTracking) -{ +TEST_F(SortTest, testSortWithoutScoreTracking) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); - for (int32_t i = 0; i < sort.size(); ++i) - { + for (int32_t i = 0; i < sort.size(); ++i) { QueryPtr q = newLucene(); TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, true, false, false, true); @@ -895,18 +834,17 @@ TEST_F(SortTest, testSortWithoutScoreTracking) TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; - for (int32_t j = 1; j < sd.size(); ++j) + for (int32_t j = 1; j < sd.size(); ++j) { EXPECT_TRUE(MiscUtils::isNaN(sd[j]->score)); + } EXPECT_TRUE(MiscUtils::isNaN(td->maxScore)); } } -TEST_F(SortTest, testSortWithScoreNoMaxScoreTracking) -{ +TEST_F(SortTest, testSortWithScoreNoMaxScoreTracking) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); - for (int32_t i = 0; i < sort.size(); ++i) - { + for (int32_t i = 0; i < sort.size(); ++i) { QueryPtr q = newLucene(); TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, true, true, false, true); @@ -914,18 +852,17 @@ TEST_F(SortTest, testSortWithScoreNoMaxScoreTracking) TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; - for (int32_t j = 1; j < sd.size(); ++j) + for (int32_t j = 1; j < sd.size(); ++j) { EXPECT_TRUE(!MiscUtils::isNaN(sd[j]->score)); + } EXPECT_TRUE(MiscUtils::isNaN(td->maxScore)); } } -TEST_F(SortTest, testSortWithScoreAndMaxScoreTracking) -{ +TEST_F(SortTest, testSortWithScoreAndMaxScoreTracking) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); - for (int32_t i = 0; i < sort.size(); ++i) - { + for (int32_t i = 0; i < sort.size(); ++i) { QueryPtr q = newLucene(); TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, true, true, true, true); @@ -933,36 +870,36 @@ TEST_F(SortTest, testSortWithScoreAndMaxScoreTracking) TopDocsPtr td = tdc->topDocs(); Collection sd = td->scoreDocs; - for (int32_t j = 1; j < sd.size(); ++j) + for (int32_t j = 1; j < sd.size(); ++j) { EXPECT_TRUE(!MiscUtils::isNaN(sd[j]->score)); + } EXPECT_TRUE(!MiscUtils::isNaN(td->maxScore)); } } -TEST_F(SortTest, testOutOfOrderDocsScoringSort) -{ +TEST_F(SortTest, testOutOfOrderDocsScoringSort) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); Collection< Collection > tfcOptions = newCollection< Collection >( - newCollection(false, false, false), - newCollection(false, false, true), - newCollection(false, true, false), - newCollection(false, true, true), - newCollection(true, false, false), - newCollection(true, false, true), - newCollection(true, true, false), - newCollection(true, true, true) - ); + newCollection(false, false, false), + newCollection(false, false, true), + newCollection(false, true, false), + newCollection(false, true, true), + newCollection(true, false, false), + newCollection(true, false, true), + newCollection(true, true, false), + newCollection(true, true, true) + ); Collection actualTFCClasses = newCollection( - L"OutOfOrderOneComparatorNonScoringCollector", - L"OutOfOrderOneComparatorScoringMaxScoreCollector", - L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", - L"OutOfOrderOneComparatorScoringMaxScoreCollector", - L"OutOfOrderOneComparatorNonScoringCollector", - L"OutOfOrderOneComparatorScoringMaxScoreCollector", - L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", - L"OutOfOrderOneComparatorScoringMaxScoreCollector" - ); + L"OutOfOrderOneComparatorNonScoringCollector", + L"OutOfOrderOneComparatorScoringMaxScoreCollector", + L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", + L"OutOfOrderOneComparatorScoringMaxScoreCollector", + L"OutOfOrderOneComparatorNonScoringCollector", + L"OutOfOrderOneComparatorScoringMaxScoreCollector", + L"OutOfOrderOneComparatorScoringNoMaxScoreCollector", + L"OutOfOrderOneComparatorScoringMaxScoreCollector" + ); BooleanQueryPtr bq = newLucene(); // Add a Query with SHOULD, since bw.scorer() returns BooleanScorer2 which delegates to @@ -971,10 +908,8 @@ TEST_F(SortTest, testOutOfOrderDocsScoringSort) // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return the clause // instead of BQ. bq->setMinimumNumberShouldMatch(1); - for (int32_t i = 0; i < sort.size(); ++i) - { - for (int32_t j = 0; j < tfcOptions.size(); ++j) - { + for (int32_t i = 0; i < sort.size(); ++i) { + for (int32_t j = 0; j < tfcOptions.size(); ++j) { TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, tfcOptions[j][0] == 1, tfcOptions[j][1] == 1, tfcOptions[j][2] == 1, false); EXPECT_EQ(tdc->getClassName(), actualTFCClasses[j]); @@ -988,12 +923,10 @@ TEST_F(SortTest, testOutOfOrderDocsScoringSort) } } -TEST_F(SortTest, testSortWithScoreAndMaxScoreTrackingNoResults) -{ +TEST_F(SortTest, testSortWithScoreAndMaxScoreTrackingNoResults) { // Two Sort criteria to instantiate the multi/single comparators. Collection sort = newCollection(newLucene(SortField::FIELD_DOC()), newLucene()); - for (int32_t i = 0; i < sort.size(); ++i) - { + for (int32_t i = 0; i < sort.size(); ++i) { TopDocsCollectorPtr tdc = TopFieldCollector::create(sort[i], 10, true, true, true, true); TopDocsPtr td = tdc->topDocs(); EXPECT_EQ(0, td->totalHits); @@ -1001,12 +934,10 @@ TEST_F(SortTest, testSortWithScoreAndMaxScoreTrackingNoResults) } } -TEST_F(SortTest, testSortWithStringNoException) -{ +TEST_F(SortTest, testSortWithStringNoException) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 5; ++i) - { + for (int32_t i = 0; i < 5; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"string", L"a" + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"string", L"b" + StringUtils::toString(i), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); diff --git a/src/test/search/SpanQueryFilterTest.cpp b/src/test/search/SpanQueryFilterTest.cpp index 5e7d9719..383cc4e0 100644 --- a/src/test/search/SpanQueryFilterTest.cpp +++ b/src/test/search/SpanQueryFilterTest.cpp @@ -24,28 +24,25 @@ using namespace Lucene; typedef LuceneTestFixture SpanQueryFilterTest; -static int32_t getDocIdSetSize(const DocIdSetPtr& docIdSet) -{ +static int32_t getDocIdSetSize(const DocIdSetPtr& docIdSet) { int32_t size = 0; DocIdSetIteratorPtr it = docIdSet->iterator(); - while (it->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) + while (it->nextDoc() != DocIdSetIterator::NO_MORE_DOCS) { ++size; + } return size; } -static void checkContainsDocId(const DocIdSetPtr& docIdSet, int32_t docId) -{ +static void checkContainsDocId(const DocIdSetPtr& docIdSet, int32_t docId) { DocIdSetIteratorPtr it = docIdSet->iterator(); EXPECT_NE(it->advance(docId), DocIdSetIterator::NO_MORE_DOCS); EXPECT_EQ(it->docID(), docId); } -TEST_F(SpanQueryFilterTest, testFilterWorks) -{ +TEST_F(SpanQueryFilterTest, testFilterWorks) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 500; ++i) - { + for (int32_t i = 0; i < 500; ++i) { DocumentPtr document = newLucene(); document->add(newLucene(L"field", intToEnglish(i) + L" equals " + intToEnglish(i), Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(document); @@ -65,8 +62,7 @@ TEST_F(SpanQueryFilterTest, testFilterWorks) EXPECT_TRUE(spans); int32_t size = getDocIdSetSize(docIdSet); EXPECT_EQ(spans.size(), size); - for (Collection::iterator info = spans.begin(); info != spans.end(); ++info) - { + for (Collection::iterator info = spans.begin(); info != spans.end(); ++info) { EXPECT_TRUE(*info); // The doc should indicate the bit is on checkContainsDocId(docIdSet, (*info)->getDoc()); diff --git a/src/test/search/TermRangeFilterTest.cpp b/src/test/search/TermRangeFilterTest.cpp index aab7f4d2..078ec3aa 100644 --- a/src/test/search/TermRangeFilterTest.cpp +++ b/src/test/search/TermRangeFilterTest.cpp @@ -19,16 +19,13 @@ using namespace Lucene; -class TermRangeFilterTest : public BaseTestRangeFilterFixture -{ +class TermRangeFilterTest : public BaseTestRangeFilterFixture { public: - virtual ~TermRangeFilterTest() - { + virtual ~TermRangeFilterTest() { } }; -TEST_F(TermRangeFilterTest, testRangeFilterId) -{ +TEST_F(TermRangeFilterTest, testRangeFilterId) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -107,8 +104,7 @@ TEST_F(TermRangeFilterTest, testRangeFilterId) EXPECT_EQ(1, result.size()); } -TEST_F(TermRangeFilterTest, testRangeFilterIdCollating) -{ +TEST_F(TermRangeFilterTest, testRangeFilterIdCollating) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -189,8 +185,7 @@ TEST_F(TermRangeFilterTest, testRangeFilterIdCollating) EXPECT_EQ(1, numHits); } -TEST_F(TermRangeFilterTest, testRangeFilterRand) -{ +TEST_F(TermRangeFilterTest, testRangeFilterRand) { IndexReaderPtr reader = IndexReader::open(signedIndex->index, true); IndexSearcherPtr search = newLucene(reader); @@ -249,8 +244,7 @@ TEST_F(TermRangeFilterTest, testRangeFilterRand) EXPECT_EQ(1, result.size()); } -TEST_F(TermRangeFilterTest, testRangeFilterRandCollating) -{ +TEST_F(TermRangeFilterTest, testRangeFilterRandCollating) { // using the unsigned index because collation seems to ignore hyphens IndexReaderPtr reader = IndexReader::open(unsignedIndex->index, true); IndexSearcherPtr search = newLucene(reader); diff --git a/src/test/search/TermRangeQueryTest.cpp b/src/test/search/TermRangeQueryTest.cpp index 7ad3f7b6..38bd5672 100644 --- a/src/test/search/TermRangeQueryTest.cpp +++ b/src/test/search/TermRangeQueryTest.cpp @@ -23,18 +23,15 @@ using namespace Lucene; -class SingleCharTokenizer : public Tokenizer -{ +class SingleCharTokenizer : public Tokenizer { public: - SingleCharTokenizer(const ReaderPtr& r) : Tokenizer(r) - { + SingleCharTokenizer(const ReaderPtr& r) : Tokenizer(r) { termAtt = addAttribute(); buffer = CharArray::newInstance(1); done = false; } - virtual ~SingleCharTokenizer() - { + virtual ~SingleCharTokenizer() { } public: @@ -43,71 +40,59 @@ class SingleCharTokenizer : public Tokenizer TermAttributePtr termAtt; public: - virtual bool incrementToken() - { + virtual bool incrementToken() { int32_t count = input->read(buffer.get(), 0, 1); - if (done) + if (done) { return false; - else - { + } else { clearAttributes(); done = true; - if (count == 1) - { + if (count == 1) { termAtt->termBuffer()[0] = buffer[0]; termAtt->setTermLength(1); - } - else + } else { termAtt->setTermLength(0); + } return true; } } - virtual void reset(const ReaderPtr& input) - { + virtual void reset(const ReaderPtr& input) { Tokenizer::reset(input); done = false; } }; -class SingleCharAnalyzer : public Analyzer -{ +class SingleCharAnalyzer : public Analyzer { public: - virtual ~SingleCharAnalyzer() - { + virtual ~SingleCharAnalyzer() { } public: - virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr reusableTokenStream(const String& fieldName, const ReaderPtr& reader) { TokenizerPtr tokenizer = boost::dynamic_pointer_cast(getPreviousTokenStream()); - if (!tokenizer) - { + if (!tokenizer) { tokenizer = newLucene(reader); setPreviousTokenStream(tokenizer); - } - else + } else { tokenizer->reset(reader); + } return tokenizer; } - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { return newLucene(reader); } }; -class TermRangeQueryTest : public LuceneTestFixture -{ +class TermRangeQueryTest : public LuceneTestFixture { public: - TermRangeQueryTest() - { + TermRangeQueryTest() { docCount = 0; dir = newLucene(); } - virtual ~TermRangeQueryTest() - { + virtual ~TermRangeQueryTest() { } protected: @@ -115,28 +100,25 @@ class TermRangeQueryTest : public LuceneTestFixture RAMDirectoryPtr dir; public: - void initializeIndex(Collection values) - { + void initializeIndex(Collection values) { initializeIndex(values, newLucene()); } - void initializeIndex(Collection values, const AnalyzerPtr& analyzer) - { + void initializeIndex(Collection values, const AnalyzerPtr& analyzer) { IndexWriterPtr writer = newLucene(dir, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < values.size(); ++i) + for (int32_t i = 0; i < values.size(); ++i) { insertDoc(writer, values[i]); + } writer->close(); } - void addDoc(const String& content) - { + void addDoc(const String& content) { IndexWriterPtr writer = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); insertDoc(writer, content); writer->close(); } - void insertDoc(const IndexWriterPtr& writer, const String& content) - { + void insertDoc(const IndexWriterPtr& writer, const String& content) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", L"id" + StringUtils::toString(docCount), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"content", content, Field::STORE_NO, Field::INDEX_ANALYZED)); @@ -145,8 +127,7 @@ class TermRangeQueryTest : public LuceneTestFixture } }; -TEST_F(TermRangeQueryTest, testExclusive) -{ +TEST_F(TermRangeQueryTest, testExclusive) { QueryPtr query = newLucene(L"content", L"A", L"C", false, false); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); IndexSearcherPtr searcher = newLucene(dir, true); @@ -167,8 +148,7 @@ TEST_F(TermRangeQueryTest, testExclusive) searcher->close(); } -TEST_F(TermRangeQueryTest, testInclusive) -{ +TEST_F(TermRangeQueryTest, testInclusive) { QueryPtr query = newLucene(L"content", L"A", L"C", true, true); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); @@ -190,8 +170,7 @@ TEST_F(TermRangeQueryTest, testInclusive) searcher->close(); } -TEST_F(TermRangeQueryTest, testEqualsHashcode) -{ +TEST_F(TermRangeQueryTest, testEqualsHashcode) { QueryPtr query = newLucene(L"content", L"A", L"C", true, true); query->setBoost(1.0); @@ -237,8 +216,7 @@ TEST_F(TermRangeQueryTest, testEqualsHashcode) EXPECT_TRUE(!query->equals(other)); } -TEST_F(TermRangeQueryTest, testExclusiveCollating) -{ +TEST_F(TermRangeQueryTest, testExclusiveCollating) { QueryPtr query = newLucene(L"content", L"A", L"C", false, false, newLucene(std::locale())); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); IndexSearcherPtr searcher = newLucene(dir, true); @@ -259,8 +237,7 @@ TEST_F(TermRangeQueryTest, testExclusiveCollating) searcher->close(); } -TEST_F(TermRangeQueryTest, testInclusiveCollating) -{ +TEST_F(TermRangeQueryTest, testInclusiveCollating) { QueryPtr query = newLucene(L"content", L"A", L"C", true, true, newLucene(std::locale())); initializeIndex(newCollection(L"A", L"B", L"C", L"D")); IndexSearcherPtr searcher = newLucene(dir, true); @@ -281,8 +258,7 @@ TEST_F(TermRangeQueryTest, testInclusiveCollating) searcher->close(); } -TEST_F(TermRangeQueryTest, testExclusiveLowerNull) -{ +TEST_F(TermRangeQueryTest, testExclusiveLowerNull) { AnalyzerPtr analyzer = newLucene(); QueryPtr query = newLucene(L"content", VariantUtils::null(), L"C", false, false); initializeIndex(newCollection(L"A", L"B", L"", L"C", L"D"), analyzer); @@ -304,8 +280,7 @@ TEST_F(TermRangeQueryTest, testExclusiveLowerNull) searcher->close(); } -TEST_F(TermRangeQueryTest, testInclusiveLowerNull) -{ +TEST_F(TermRangeQueryTest, testInclusiveLowerNull) { AnalyzerPtr analyzer = newLucene(); QueryPtr query = newLucene(L"content", VariantUtils::null(), L"C", true, true); initializeIndex(newCollection(L"A", L"B", L"", L"C", L"D"), analyzer); diff --git a/src/test/search/TermScorerTest.cpp b/src/test/search/TermScorerTest.cpp index 3a926c73..a0e9af38 100644 --- a/src/test/search/TermScorerTest.cpp +++ b/src/test/search/TermScorerTest.cpp @@ -24,17 +24,14 @@ using namespace Lucene; DECLARE_SHARED_PTR(TestHit) -class TestHit : public LuceneObject -{ +class TestHit : public LuceneObject { public: - TestHit(int32_t doc, double score) - { + TestHit(int32_t doc, double score) { this->doc = doc; this->score = score; } - virtual ~TestHit() - { + virtual ~TestHit() { } public: @@ -42,22 +39,18 @@ class TestHit : public LuceneObject double score; public: - virtual String toString() - { + virtual String toString() { return L"TestHit{doc=" + StringUtils::toString(doc) + L", score=" + StringUtils::toString(score) + L"}"; } }; -class TermScorerTest : public LuceneTestFixture -{ +class TermScorerTest : public LuceneTestFixture { public: - TermScorerTest() - { + TermScorerTest() { values = newCollection(L"all", L"dogs dogs", L"like", L"playing", L"fetch", L"all"); directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < values.size(); ++i) - { + for (int32_t i = 0; i < values.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD, values[i], Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -67,8 +60,7 @@ class TermScorerTest : public LuceneTestFixture indexReader = indexSearcher->getIndexReader(); } - virtual ~TermScorerTest() - { + virtual ~TermScorerTest() { } protected: @@ -82,55 +74,48 @@ class TermScorerTest : public LuceneTestFixture const String TermScorerTest::FIELD = L"field"; -namespace TestTermScorer -{ - class TestCollector : public Collector - { - public: - TestCollector(Collection docs) - { - this->docs = docs; - this->base = 0; - } +namespace TestTermScorer { - virtual ~TestCollector() - { - } +class TestCollector : public Collector { +public: + TestCollector(Collection docs) { + this->docs = docs; + this->base = 0; + } - protected: - int32_t base; - ScorerPtr scorer; - Collection docs; + virtual ~TestCollector() { + } - public: - virtual void setScorer(const ScorerPtr& scorer) - { - this->scorer = scorer; - } +protected: + int32_t base; + ScorerPtr scorer; + Collection docs; - virtual void collect(int32_t doc) - { - double score = scorer->score(); - doc = doc + base; - docs.add(newLucene(doc, score)); - EXPECT_TRUE(score > 0); - EXPECT_TRUE(doc == 0 || doc == 5); - } +public: + virtual void setScorer(const ScorerPtr& scorer) { + this->scorer = scorer; + } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { - base = docBase; - } + virtual void collect(int32_t doc) { + double score = scorer->score(); + doc = doc + base; + docs.add(newLucene(doc, score)); + EXPECT_TRUE(score > 0); + EXPECT_TRUE(doc == 0 || doc == 5); + } + + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { + base = docBase; + } + + virtual bool acceptsDocsOutOfOrder() { + return true; + } +}; - virtual bool acceptsDocsOutOfOrder() - { - return true; - } - }; } -TEST_F(TermScorerTest, testTermScorer) -{ +TEST_F(TermScorerTest, testTermScorer) { TermPtr allTerm = newLucene(FIELD, L"all"); TermQueryPtr termQuery = newLucene(allTerm); @@ -148,8 +133,7 @@ TEST_F(TermScorerTest, testTermScorer) EXPECT_NEAR(docs[0]->score, 1.6931472, 0.000001); } -TEST_F(TermScorerTest, testNext) -{ +TEST_F(TermScorerTest, testNext) { TermPtr allTerm = newLucene(FIELD, L"all"); TermQueryPtr termQuery = newLucene(allTerm); @@ -163,8 +147,7 @@ TEST_F(TermScorerTest, testNext) EXPECT_EQ(ts->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); } -TEST_F(TermScorerTest, testSkipTo) -{ +TEST_F(TermScorerTest, testSkipTo) { TermPtr allTerm = newLucene(FIELD, L"all"); TermQueryPtr termQuery = newLucene(allTerm); diff --git a/src/test/search/TermVectorsTest.cpp b/src/test/search/TermVectorsTest.cpp index 53d09bc4..f4d89482 100644 --- a/src/test/search/TermVectorsTest.cpp +++ b/src/test/search/TermVectorsTest.cpp @@ -31,27 +31,25 @@ using namespace Lucene; -class TermVectorsTest : public LuceneTestFixture -{ +class TermVectorsTest : public LuceneTestFixture { public: - TermVectorsTest() - { + TermVectorsTest() { directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 1000; ++i) - { + for (int32_t i = 0; i < 1000; ++i) { DocumentPtr doc = newLucene(); Field::TermVector termVector; int32_t mod3 = i % 3; int32_t mod2 = i % 2; - if (mod2 == 0 && mod3 == 0) + if (mod2 == 0 && mod3 == 0) { termVector = Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS; - else if (mod2 == 0) + } else if (mod2 == 0) { termVector = Field::TERM_VECTOR_WITH_POSITIONS; - else if (mod3 == 0) + } else if (mod3 == 0) { termVector = Field::TERM_VECTOR_WITH_OFFSETS; - else + } else { termVector = Field::TERM_VECTOR_YES; + } doc->add(newLucene(L"field", intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED, termVector)); writer->addDocument(doc); } @@ -59,8 +57,7 @@ class TermVectorsTest : public LuceneTestFixture searcher = newLucene(directory, true); } - virtual ~TermVectorsTest() - { + virtual ~TermVectorsTest() { } protected: @@ -68,28 +65,24 @@ class TermVectorsTest : public LuceneTestFixture DirectoryPtr directory; public: - void setupDoc(const DocumentPtr& doc, const String& text) - { + void setupDoc(const DocumentPtr& doc, const String& text) { doc->add(newLucene(L"field2", text, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); doc->add(newLucene(L"field", text, Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_YES)); } }; -TEST_F(TermVectorsTest, testTermVectors) -{ +TEST_F(TermVectorsTest, testTermVectors) { QueryPtr query = newLucene(newLucene(L"field", L"seventy")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(100, hits.size()); - for (int32_t i = 0; i < hits.size(); ++i) - { + for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); EXPECT_TRUE(vector); EXPECT_EQ(vector.size(), 1); } } -TEST_F(TermVectorsTest, testTermVectorsFieldOrder) -{ +TEST_F(TermVectorsTest, testTermVectorsFieldOrder) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -104,8 +97,7 @@ TEST_F(TermVectorsTest, testTermVectorsFieldOrder) EXPECT_EQ(4, v.size()); Collection expectedFields = newCollection(L"a", L"b", L"c", L"x"); Collection expectedPositions = newCollection(1, 2, 0); - for (int32_t i = 0; i < v.size(); ++i) - { + for (int32_t i = 0; i < v.size(); ++i) { TermPositionVectorPtr posVec = boost::dynamic_pointer_cast(v[i]); EXPECT_EQ(expectedFields[i], posVec->getField()); Collection terms = posVec->getTerms(); @@ -113,8 +105,7 @@ TEST_F(TermVectorsTest, testTermVectorsFieldOrder) EXPECT_EQ(L"content", terms[0]); EXPECT_EQ(L"here", terms[1]); EXPECT_EQ(L"some", terms[2]); - for (int32_t j = 0; j < 3; ++j) - { + for (int32_t j = 0; j < 3; ++j) { Collection positions = posVec->getTermPositions(j); EXPECT_EQ(1, positions.size()); EXPECT_EQ(expectedPositions[j], positions[0]); @@ -122,14 +113,12 @@ TEST_F(TermVectorsTest, testTermVectorsFieldOrder) } } -TEST_F(TermVectorsTest, testTermPositionVectors) -{ +TEST_F(TermVectorsTest, testTermPositionVectors) { QueryPtr query = newLucene(newLucene(L"field", L"zero")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(1, hits.size()); - for (int32_t i = 0; i < hits.size(); ++i) - { + for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); EXPECT_TRUE(vector); EXPECT_EQ(vector.size(), 1); @@ -140,36 +129,30 @@ TEST_F(TermVectorsTest, testTermPositionVectors) bool shouldBeOffVector = (hits[i]->doc % 3 == 0); EXPECT_TRUE(!shouldBeOffVector || (shouldBeOffVector && boost::dynamic_pointer_cast(vector[0]))); - if (shouldBePosVector || shouldBeOffVector) - { + if (shouldBePosVector || shouldBeOffVector) { TermPositionVectorPtr posVec = boost::dynamic_pointer_cast(vector[0]); Collection terms = posVec->getTerms(); EXPECT_TRUE(terms && !terms.empty()); - for (int32_t j = 0; j < terms.size(); ++j) - { + for (int32_t j = 0; j < terms.size(); ++j) { Collection positions = posVec->getTermPositions(j); Collection offsets = posVec->getOffsets(j); - if (shouldBePosVector) - { + if (shouldBePosVector) { EXPECT_TRUE(positions); EXPECT_TRUE(!positions.empty()); - } - else + } else { EXPECT_TRUE(!positions); + } - if (shouldBeOffVector) - { + if (shouldBeOffVector) { EXPECT_TRUE(offsets); EXPECT_TRUE(!offsets.empty()); - } - else + } else { EXPECT_TRUE(!offsets); + } } - } - else - { + } else { EXPECT_TRUE(!boost::dynamic_pointer_cast(vector[0])); TermFreqVectorPtr freqVec = boost::dynamic_pointer_cast(vector[0]); Collection terms = freqVec->getTerms(); @@ -178,22 +161,19 @@ TEST_F(TermVectorsTest, testTermPositionVectors) } } -TEST_F(TermVectorsTest, testTermOffsetVectors) -{ +TEST_F(TermVectorsTest, testTermOffsetVectors) { QueryPtr query = newLucene(newLucene(L"field", L"fifty")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(100, hits.size()); - for (int32_t i = 0; i < hits.size(); ++i) - { + for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); EXPECT_TRUE(vector); EXPECT_EQ(vector.size(), 1); } } -TEST_F(TermVectorsTest, testKnownSetOfDocuments) -{ +TEST_F(TermVectorsTest, testKnownSetOfDocuments) { String test1 = L"eating chocolate in a computer lab"; // 6 terms String test2 = L"computer in a computer lab"; // 5 terms String test3 = L"a chocolate lab grows old"; // 5 terms @@ -235,12 +215,10 @@ TEST_F(TermVectorsTest, testKnownSetOfDocuments) TermDocsPtr termDocs = knownSearcher->reader->termDocs(); SimilarityPtr sim = knownSearcher->getSimilarity(); - while (termEnum->next()) - { + while (termEnum->next()) { TermPtr term = termEnum->term(); termDocs->seek(term); - while (termDocs->next()) - { + while (termDocs->next()) { int32_t docId = termDocs->doc(); int32_t freq = termDocs->freq(); TermFreqVectorPtr vector = knownSearcher->reader->getTermFreqVector(docId, L"field"); @@ -251,10 +229,10 @@ TEST_F(TermVectorsTest, testKnownSetOfDocuments) EXPECT_TRUE(vector); Collection vTerms = vector->getTerms(); Collection freqs = vector->getTermFrequencies(); - for (int32_t i = 0; i < vTerms.size(); ++i) - { - if (term->text() == vTerms[i]) + for (int32_t i = 0; i < vTerms.size(); ++i) { + if (term->text() == vTerms[i]) { EXPECT_EQ(freqs[i], freq); + } } } } @@ -271,8 +249,7 @@ TEST_F(TermVectorsTest, testKnownSetOfDocuments) Collection terms = vector->getTerms(); Collection freqs = vector->getTermFrequencies(); EXPECT_TRUE(terms && terms.size() == 10); - for (int32_t i = 0; i < terms.size(); ++i) - { + for (int32_t i = 0; i < terms.size(); ++i) { String term = terms[i]; int32_t freq = freqs[i]; EXPECT_TRUE(test4.find(term) != String::npos); @@ -284,10 +261,8 @@ TEST_F(TermVectorsTest, testKnownSetOfDocuments) Collection vectorEntrySet = mapper->getTermVectorEntrySet(); EXPECT_EQ(vectorEntrySet.size(), 10); TermVectorEntryPtr last; - for (Collection::iterator tve = vectorEntrySet.begin(); tve != vectorEntrySet.end(); ++tve) - { - if (*tve && last) - { + for (Collection::iterator tve = vectorEntrySet.begin(); tve != vectorEntrySet.end(); ++tve) { + if (*tve && last) { EXPECT_TRUE(last->getFrequency() >= (*tve)->getFrequency()); int32_t expectedFreq = test4Map.get((*tve)->getTerm()); // we expect double the expectedFreq, since there are two fields with the exact same text and we are collapsing all fields @@ -306,19 +281,16 @@ TEST_F(TermVectorsTest, testKnownSetOfDocuments) } /// Test only a few docs having vectors -TEST_F(TermVectorsTest, testRareVectors) -{ +TEST_F(TermVectorsTest, testRareVectors) { IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO)); writer->addDocument(doc); } - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", intToEnglish(100 + i), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); writer->addDocument(doc); @@ -330,8 +302,7 @@ TEST_F(TermVectorsTest, testRareVectors) QueryPtr query = newLucene(newLucene(L"field", L"hundred")); Collection hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(10, hits.size()); - for (int32_t i = 0; i < hits.size(); ++i) - { + for (int32_t i = 0; i < hits.size(); ++i) { Collection vector = searcher->reader->getTermFreqVectors(hits[i]->doc); EXPECT_TRUE(vector); EXPECT_EQ(vector.size(), 1); @@ -339,8 +310,7 @@ TEST_F(TermVectorsTest, testRareVectors) } /// In a single doc, for the same field, mix the term vectors up -TEST_F(TermVectorsTest, testMixedVectrosVectors) -{ +TEST_F(TermVectorsTest, testMixedVectrosVectors) { IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", L"one", Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_NO)); @@ -369,12 +339,12 @@ TEST_F(TermVectorsTest, testMixedVectrosVectors) Collection positions = tfv->getTermPositions(0); EXPECT_EQ(5, positions.size()); - for (int32_t i = 0; i < 5; ++i) + for (int32_t i = 0; i < 5; ++i) { EXPECT_EQ(i, positions[i]); + } Collection offsets = tfv->getOffsets(0); EXPECT_EQ(5, offsets.size()); - for (int32_t i = 0; i < 5; ++i) - { + for (int32_t i = 0; i < 5; ++i) { EXPECT_EQ(4 * i, offsets[i]->getStartOffset()); EXPECT_EQ(4 * i + 3, offsets[i]->getEndOffset()); } diff --git a/src/test/search/ThreadSafeTest.cpp b/src/test/search/ThreadSafeTest.cpp index 06d1aca0..d4fa2a0c 100644 --- a/src/test/search/ThreadSafeTest.cpp +++ b/src/test/search/ThreadSafeTest.cpp @@ -19,48 +19,40 @@ using namespace Lucene; -class TestFieldSelector : public FieldSelector -{ +class TestFieldSelector : public FieldSelector { public: - TestFieldSelector(const RandomPtr& rand) - { + TestFieldSelector(const RandomPtr& rand) { this->rand = rand; } - virtual ~TestFieldSelector() - { + virtual ~TestFieldSelector() { } protected: RandomPtr rand; public: - virtual FieldSelectorResult accept(const String& fieldName) - { - switch (rand->nextInt(2)) - { - case 0: - return FieldSelector::SELECTOR_LAZY_LOAD; - case 1: - return FieldSelector::SELECTOR_LOAD; - default: - return FieldSelector::SELECTOR_LOAD; + virtual FieldSelectorResult accept(const String& fieldName) { + switch (rand->nextInt(2)) { + case 0: + return FieldSelector::SELECTOR_LAZY_LOAD; + case 1: + return FieldSelector::SELECTOR_LOAD; + default: + return FieldSelector::SELECTOR_LOAD; } } }; -class TestThread : public LuceneThread -{ +class TestThread : public LuceneThread { public: - TestThread(int32_t iter, const RandomPtr& rand, const IndexReaderPtr& reader) - { + TestThread(int32_t iter, const RandomPtr& rand, const IndexReaderPtr& reader) { this->iter = iter; this->rand = rand; this->reader = reader; } - virtual ~TestThread() - { + virtual ~TestThread() { } LUCENE_CLASS(TestThread); @@ -71,47 +63,41 @@ class TestThread : public LuceneThread RandomPtr rand; public: - virtual void run() - { - try - { - for (int32_t i = 0; i < iter; ++i) + virtual void run() { + try { + for (int32_t i = 0; i < iter; ++i) { loadDoc(); - } - catch (LuceneException& e) - { + } + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } - void loadDoc() - { + void loadDoc() { DocumentPtr doc = reader->document(rand->nextInt(reader->maxDoc()), newLucene(rand)); Collection fields = doc->getFields(); - for (int32_t i = 0; i < fields.size(); ++i) + for (int32_t i = 0; i < fields.size(); ++i) { validateField(fields[i]); + } } - void validateField(const FieldablePtr& f) - { + void validateField(const FieldablePtr& f) { String val = f->stringValue(); - if (!boost::starts_with(val, L"^") || !boost::ends_with(val, L"$")) + if (!boost::starts_with(val, L"^") || !boost::ends_with(val, L"$")) { FAIL() << "Invalid field"; + } } }; -class ThreadSafeTest : public LuceneTestFixture -{ +class ThreadSafeTest : public LuceneTestFixture { public: - ThreadSafeTest() - { + ThreadSafeTest() { r = newLucene(17); dir = newLucene(); words = StringUtils::split(L"now is the time for all good men to come to the aid of their country", L" "); } - virtual ~ThreadSafeTest() - { + virtual ~ThreadSafeTest() { } public: @@ -121,21 +107,19 @@ class ThreadSafeTest : public LuceneTestFixture Collection words; public: - void buildDir(const DirectoryPtr& dir, int32_t numDocs, int32_t maxFields, int32_t maxFieldLen) - { + void buildDir(const DirectoryPtr& dir, int32_t numDocs, int32_t maxFields, int32_t maxFieldLen) { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setMaxBufferedDocs(10); - for (int32_t j = 0; j < numDocs; ++j) - { + for (int32_t j = 0; j < numDocs; ++j) { DocumentPtr doc = newLucene(); int32_t numFields = r->nextInt(maxFields); - for (int32_t i = 0; i < numFields; ++i) - { + for (int32_t i = 0; i < numFields; ++i) { int32_t flen = r->nextInt(maxFieldLen); StringStream buf; buf << L"^ "; - while ((int32_t)buf.str().length() < flen) + while ((int32_t)buf.str().length() < flen) { buf << L" " << words[r->nextInt(words.size())]; + } buf << L" $"; doc->add(newLucene(L"f" + StringUtils::toString(i), buf.str(), Field::STORE_YES, Field::INDEX_ANALYZED)); } @@ -144,27 +128,24 @@ class ThreadSafeTest : public LuceneTestFixture writer->close(); } - void doTest(int32_t iter, int32_t numThreads) - { + void doTest(int32_t iter, int32_t numThreads) { Collection threads = Collection::newInstance(numThreads); - for (int32_t i = 0; i < numThreads; ++i) - { + for (int32_t i = 0; i < numThreads; ++i) { threads[i] = newLucene(iter, newLucene(r->nextInt()), reader); threads[i]->start(); } - for (int32_t i = 0; i < numThreads; ++i) + for (int32_t i = 0; i < numThreads; ++i) { threads[i]->join(); + } } }; -TEST_F(ThreadSafeTest, testLazyLoadThreadSafety) -{ +TEST_F(ThreadSafeTest, testLazyLoadThreadSafety) { // test with field sizes bigger than the buffer of an index input buildDir(dir, 15, 5, 2000); // do many small tests so the thread locals go away in between - for (int32_t i = 0; i < 100; ++i) - { + for (int32_t i = 0; i < 100; ++i) { reader = IndexReader::open(dir, false); doTest(10, 100); } diff --git a/src/test/search/TimeLimitingCollectorTest.cpp b/src/test/search/TimeLimitingCollectorTest.cpp index b0fe6d5b..9a041bdd 100644 --- a/src/test/search/TimeLimitingCollectorTest.cpp +++ b/src/test/search/TimeLimitingCollectorTest.cpp @@ -23,19 +23,16 @@ using namespace Lucene; DECLARE_SHARED_PTR(MyHitCollector) /// counting collector that can slow down at collect(). -class MyHitCollector : public Collector -{ +class MyHitCollector : public Collector { public: - MyHitCollector() - { + MyHitCollector() { bits = newLucene(); slowdown = 0; lastDocCollected = -1; docBase = 0; } - virtual ~MyHitCollector() - { + virtual ~MyHitCollector() { } protected: @@ -46,57 +43,50 @@ class MyHitCollector : public Collector public: /// amount of time to wait on each collect to simulate a long iteration - void setSlowDown(int32_t milliseconds) - { + void setSlowDown(int32_t milliseconds) { slowdown = milliseconds; } - int32_t hitCount() - { + int32_t hitCount() { return bits->cardinality(); } - int32_t getLastDocCollected() - { + int32_t getLastDocCollected() { return lastDocCollected; } - virtual void setScorer(const ScorerPtr& scorer) - { + virtual void setScorer(const ScorerPtr& scorer) { // scorer is not needed } - virtual void collect(int32_t doc) - { + virtual void collect(int32_t doc) { int32_t docId = doc + docBase; - if (slowdown > 0) + if (slowdown > 0) { LuceneThread::threadSleep(slowdown); - if (docId < 0) + } + if (docId < 0) { FAIL() << "Invalid doc"; + } bits->set(docId); lastDocCollected = docId; } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { this->docBase = docBase; } - virtual bool acceptsDocsOutOfOrder() - { + virtual bool acceptsDocsOutOfOrder() { return false; } }; class TimeLimitingCollectorTest; -class TimeLimitingThread : public LuceneThread -{ +class TimeLimitingThread : public LuceneThread { public: TimeLimitingThread(bool withTimeout, TimeLimitingCollectorTest* fixture); - virtual ~TimeLimitingThread() - { + virtual ~TimeLimitingThread() { } LUCENE_CLASS(TimeLimitingThread); @@ -111,34 +101,34 @@ class TimeLimitingThread : public LuceneThread /// Tests the {@link TimeLimitingCollector}. /// This test checks (1) search correctness (regardless of timeout), (2) expected timeout behaviour, and (3) a sanity test with multiple searching threads. -class TimeLimitingCollectorTest : public LuceneTestFixture -{ +class TimeLimitingCollectorTest : public LuceneTestFixture { public: - TimeLimitingCollectorTest() - { + TimeLimitingCollectorTest() { Collection docText = newCollection( - L"docThatNeverMatchesSoWeCanRequireLastDocCollectedToBeGreaterThanZero", - L"one blah three", - L"one foo three multiOne", - L"one foobar three multiThree", - L"blueberry pancakes", - L"blueberry pie", - L"blueberry strudel", - L"blueberry pizza" - ); + L"docThatNeverMatchesSoWeCanRequireLastDocCollectedToBeGreaterThanZero", + L"one blah three", + L"one foo three multiOne", + L"one foobar three multiThree", + L"blueberry pancakes", + L"blueberry pie", + L"blueberry strudel", + L"blueberry pizza" + ); DirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < N_DOCS; ++i) + for (int32_t i = 0; i < N_DOCS; ++i) { add(docText[i % docText.size()], writer); + } writer->close(); searcher = newLucene(directory, true); String qtxt = L"one"; // start from 1, so that the 0th doc never matches - for (int32_t i = 1; i < docText.size(); ++i) - qtxt += L" " + docText[i]; // large query so that search will be longer + for (int32_t i = 1; i < docText.size(); ++i) { + qtxt += L" " + docText[i]; // large query so that search will be longer + } QueryParserPtr queryParser = newLucene(LuceneVersion::LUCENE_CURRENT, FIELD_NAME, newLucene()); query = queryParser->parse(qtxt); @@ -146,8 +136,7 @@ class TimeLimitingCollectorTest : public LuceneTestFixture searcher->search(query, FilterPtr(), 1000); } - virtual ~TimeLimitingCollectorTest() - { + virtual ~TimeLimitingCollectorTest() { searcher->close(); TimeLimitingCollector::setResolution(TimeLimitingCollector::DEFAULT_RESOLUTION); TimeLimitingCollector::stopTimer(); @@ -171,15 +160,13 @@ class TimeLimitingCollectorTest : public LuceneTestFixture QueryPtr query; public: - void add(const String& value, const IndexWriterPtr& writer) - { + void add(const String& value, const IndexWriterPtr& writer) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD_NAME, value, Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - void doTestSearch() - { + void doTestSearch() { int32_t totalResults = 0; int32_t totalTLCResults = 0; @@ -193,12 +180,12 @@ class TimeLimitingCollectorTest : public LuceneTestFixture search(tlCollector); totalTLCResults = myHc->hitCount(); - if (totalResults != totalTLCResults) + if (totalResults != totalTLCResults) { EXPECT_EQ(totalResults, totalTLCResults); + } } - void doTestTimeout(bool multiThreaded, bool greedy) - { + void doTestTimeout(bool multiThreaded, bool greedy) { MyHitCollectorPtr myHc = newLucene(); myHc->setSlowDown(SLOW_DOWN); CollectorPtr tlCollector = createTimedCollector(myHc, TIME_ALLOWED, greedy); @@ -206,64 +193,66 @@ class TimeLimitingCollectorTest : public LuceneTestFixture TimeExceededException timoutException; // search - try - { + try { search(tlCollector); - } - catch (TimeExceededException& e) - { + } catch (TimeExceededException& e) { timoutException = e; - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } // must get exception - if (timoutException.isNull()) + if (timoutException.isNull()) { EXPECT_TRUE(!timoutException.isNull()); + } String message = timoutException.getError(); String::size_type last = message.find_last_of(L":"); - if (last == String::npos) + if (last == String::npos) { EXPECT_NE(last, String::npos); + } // greediness affect last doc collected int32_t exceptionDoc = StringUtils::toInt(message.substr(last + 1)); int32_t lastCollected = myHc->getLastDocCollected(); - if (exceptionDoc <= 0) + if (exceptionDoc <= 0) { EXPECT_TRUE(exceptionDoc > 0); - if (greedy) - { - if (exceptionDoc != lastCollected) + } + if (greedy) { + if (exceptionDoc != lastCollected) { EXPECT_EQ(exceptionDoc, lastCollected); - if (myHc->hitCount() <= 0) + } + if (myHc->hitCount() <= 0) { EXPECT_TRUE(myHc->hitCount() > 0); - } - else if (exceptionDoc <= lastCollected) + } + } else if (exceptionDoc <= lastCollected) { EXPECT_TRUE(exceptionDoc > lastCollected); + } String::size_type allowed = message.find_first_of(L":"); - if (allowed == String::npos) + if (allowed == String::npos) { EXPECT_NE(allowed, String::npos); + } int32_t timeAllowed = StringUtils::toInt(message.substr(allowed + 1)); String::size_type elapsed = message.find_first_of(L":", allowed + 1); - if (elapsed == String::npos) + if (elapsed == String::npos) { EXPECT_NE(elapsed, String::npos); + } int32_t timeElapsed = StringUtils::toInt(message.substr(elapsed + 1)); // verify that elapsed time at exception is within valid limits - if (timeAllowed != TIME_ALLOWED) + if (timeAllowed != TIME_ALLOWED) { EXPECT_EQ(timeAllowed, TIME_ALLOWED); + } // a) Not too early - if (timeElapsed <= TIME_ALLOWED - TimeLimitingCollector::getResolution()) + if (timeElapsed <= TIME_ALLOWED - TimeLimitingCollector::getResolution()) { EXPECT_TRUE(timeElapsed > TIME_ALLOWED - TimeLimitingCollector::getResolution()); + } // b) Not too late. // This part is problematic in a busy test system, so we just print a warning. // We already verified that a timeout occurred, we just can't be picky about how long it took. - if (timeElapsed > maxTime(multiThreaded)) - { + if (timeElapsed > maxTime(multiThreaded)) { // std::cout << "Informative: timeout exceeded (no action required: most probably just " << // "because the test machine is slower than usual): " << // "lastDoc = " << exceptionDoc << @@ -272,65 +261,58 @@ class TimeLimitingCollectorTest : public LuceneTestFixture } } - void doTestMultiThreads(bool withTimeout) - { + void doTestMultiThreads(bool withTimeout) { Collection threads = Collection::newInstance(N_THREADS); - for (int32_t i = 0; i < threads.size(); ++i) - { + for (int32_t i = 0; i < threads.size(); ++i) { threads[i] = newLucene(withTimeout, this); threads[i]->start(); } - for (int32_t i = 0; i < threads.size(); ++i) + for (int32_t i = 0; i < threads.size(); ++i) { threads[i]->join(); + } } - int64_t maxTime(bool multiThreaded) - { + int64_t maxTime(bool multiThreaded) { int64_t res = 2 * TimeLimitingCollector::getResolution() + TIME_ALLOWED + SLOW_DOWN; // some slack for less noise in this test - if (multiThreaded) - res *= (int64_t)MULTI_THREAD_SLACK; // larger slack + if (multiThreaded) { + res *= (int64_t)MULTI_THREAD_SLACK; // larger slack + } return res; } - String maxTimeStr(bool multiThreaded) - { + String maxTimeStr(bool multiThreaded) { StringStream buf; buf << L"( 2 * resolution + TIME_ALLOWED + SLOW_DOWN = 2 * " << TimeLimitingCollector::getResolution() << L" + " << TIME_ALLOWED << L" + " << SLOW_DOWN << L")"; - if (multiThreaded) + if (multiThreaded) { buf << L" * " << MULTI_THREAD_SLACK; + } return StringUtils::toString(maxTime(multiThreaded)) + L" = " + buf.str(); } - CollectorPtr createTimedCollector(const MyHitCollectorPtr& hc, int64_t timeAllowed, bool greedy) - { + CollectorPtr createTimedCollector(const MyHitCollectorPtr& hc, int64_t timeAllowed, bool greedy) { TimeLimitingCollectorPtr res = newLucene(hc, timeAllowed); res->setGreedy(greedy); // set to true to make sure at least one doc is collected. return res; } - void search(const CollectorPtr& collector) - { + void search(const CollectorPtr& collector) { searcher->search(query, collector); } }; -TimeLimitingThread::TimeLimitingThread(bool withTimeout, TimeLimitingCollectorTest* fixture) -{ +TimeLimitingThread::TimeLimitingThread(bool withTimeout, TimeLimitingCollectorTest* fixture) { this->withTimeout = withTimeout; this->fixture = fixture; } -void TimeLimitingThread::run() -{ - try - { - if (withTimeout) +void TimeLimitingThread::run() { + try { + if (withTimeout) { fixture->doTestTimeout(true, true); - else + } else { fixture->doTestSearch(); - } - catch (LuceneException& e) - { + } + } catch (LuceneException& e) { FAIL() << "Unexpected exception: " << e.getError(); } } @@ -349,26 +331,22 @@ const int32_t TimeLimitingCollectorTest::N_THREADS = 50; const String TimeLimitingCollectorTest::FIELD_NAME = L"body"; /// test search correctness with no timeout -TEST_F(TimeLimitingCollectorTest, testSearch) -{ +TEST_F(TimeLimitingCollectorTest, testSearch) { doTestSearch(); } /// Test that timeout is obtained, and soon enough -TEST_F(TimeLimitingCollectorTest, testTimeoutGreedy) -{ +TEST_F(TimeLimitingCollectorTest, testTimeoutGreedy) { doTestTimeout(false, true); } /// Test that timeout is obtained, and soon enough -TEST_F(TimeLimitingCollectorTest, testTimeoutNotGreedy) -{ +TEST_F(TimeLimitingCollectorTest, testTimeoutNotGreedy) { doTestTimeout(false, false); } /// Test timeout behavior when resolution is modified. -TEST_F(TimeLimitingCollectorTest, testModifyResolution) -{ +TEST_F(TimeLimitingCollectorTest, testModifyResolution) { // increase and test int64_t resolution = 20 * TimeLimitingCollector::DEFAULT_RESOLUTION; // 400 TimeLimitingCollector::setResolution(resolution); @@ -387,13 +365,11 @@ TEST_F(TimeLimitingCollectorTest, testModifyResolution) } /// Test correctness with multiple searching threads. -TEST_F(TimeLimitingCollectorTest, testSearchMultiThreaded) -{ +TEST_F(TimeLimitingCollectorTest, testSearchMultiThreaded) { doTestMultiThreads(false); } /// Test correctness with multiple searching threads. -TEST_F(TimeLimitingCollectorTest, testTimeoutMultiThreaded) -{ +TEST_F(TimeLimitingCollectorTest, testTimeoutMultiThreaded) { doTestMultiThreads(true); } diff --git a/src/test/search/TopDocsCollectorTest.cpp b/src/test/search/TopDocsCollectorTest.cpp index 498e49c3..e9bbda1c 100644 --- a/src/test/search/TopDocsCollectorTest.cpp +++ b/src/test/search/TopDocsCollectorTest.cpp @@ -19,18 +19,15 @@ using namespace Lucene; -class MyTopsDocCollector : public TopDocsCollector -{ +class MyTopsDocCollector : public TopDocsCollector { public: - MyTopsDocCollector(int32_t size, Collection scores) : TopDocsCollector(newLucene(size, false)) - { + MyTopsDocCollector(int32_t size, Collection scores) : TopDocsCollector(newLucene(size, false)) { this->scores = scores; this->idx = 0; this->base = 0; } - virtual ~MyTopsDocCollector() - { + virtual ~MyTopsDocCollector() { } protected: @@ -39,50 +36,44 @@ class MyTopsDocCollector : public TopDocsCollector Collection scores; protected: - virtual TopDocsPtr newTopDocs(Collection results, int32_t start) - { - if (!results) + virtual TopDocsPtr newTopDocs(Collection results, int32_t start) { + if (!results) { return EMPTY_TOPDOCS(); + } double maxScore = std::numeric_limits::quiet_NaN(); - if (start == 0) + if (start == 0) { maxScore = results[0]->score; - else - { - for (int32_t i = pq->size(); i > 1; --i) + } else { + for (int32_t i = pq->size(); i > 1; --i) { pq->pop(); + } maxScore = boost::dynamic_pointer_cast(pq->pop())->score; } return newLucene(totalHits, results, maxScore); } - virtual void collect(int32_t doc) - { + virtual void collect(int32_t doc) { ++totalHits; pq->addOverflow(newLucene(doc + base, scores[idx++])); } - virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) - { + virtual void setNextReader(const IndexReaderPtr& reader, int32_t docBase) { base = docBase; } - virtual void setScorer(const ScorerPtr& scorer) - { + virtual void setScorer(const ScorerPtr& scorer) { // Don't do anything. Assign scores in random } - virtual bool acceptsDocsOutOfOrder() - { + virtual bool acceptsDocsOutOfOrder() { return true; } }; -class TopDocsCollectorTest : public LuceneTestFixture -{ +class TopDocsCollectorTest : public LuceneTestFixture { public: - TopDocsCollectorTest() - { + TopDocsCollectorTest() { MAX_SCORE = 9.17561; // Scores array to be used by MyTopDocsCollector. If it is changed, MAX_SCORE must also change. @@ -100,13 +91,13 @@ class TopDocsCollectorTest : public LuceneTestFixture // populate an index with 30 documents, this should be enough for the test. // The documents have no content - the test uses MatchAllDocsQuery(). IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 30; ++i) + for (int32_t i = 0; i < 30; ++i) { writer->addDocument(newLucene()); + } writer->close(); } - virtual ~TopDocsCollectorTest() - { + virtual ~TopDocsCollectorTest() { dir->close(); } @@ -116,8 +107,7 @@ class TopDocsCollectorTest : public LuceneTestFixture double MAX_SCORE; public: - TopDocsCollectorPtr doSearch(int32_t numResults) - { + TopDocsCollectorPtr doSearch(int32_t numResults) { QueryPtr q = newLucene(); IndexSearcherPtr searcher = newLucene(dir, true); TopDocsCollectorPtr tdc = newLucene(numResults, scores); @@ -127,8 +117,7 @@ class TopDocsCollectorTest : public LuceneTestFixture } }; -TEST_F(TopDocsCollectorTest, testInvalidArguments) -{ +TEST_F(TopDocsCollectorTest, testInvalidArguments) { int32_t numResults = 5; TopDocsCollectorPtr tdc = doSearch(numResults); @@ -148,20 +137,17 @@ TEST_F(TopDocsCollectorTest, testInvalidArguments) EXPECT_EQ(0, tdc->topDocs(0, 0)->scoreDocs.size()); } -TEST_F(TopDocsCollectorTest, testZeroResults) -{ +TEST_F(TopDocsCollectorTest, testZeroResults) { TopDocsCollectorPtr tdc = newLucene(5, scores); EXPECT_EQ(0, tdc->topDocs(0, 1)->scoreDocs.size()); } -TEST_F(TopDocsCollectorTest, testFirstResultsPage) -{ +TEST_F(TopDocsCollectorTest, testFirstResultsPage) { TopDocsCollectorPtr tdc = doSearch(15); EXPECT_EQ(10, tdc->topDocs(0, 10)->scoreDocs.size()); } -TEST_F(TopDocsCollectorTest, testSecondResultsPages) -{ +TEST_F(TopDocsCollectorTest, testSecondResultsPages) { TopDocsCollectorPtr tdc = doSearch(15); // ask for more results than are available @@ -176,14 +162,12 @@ TEST_F(TopDocsCollectorTest, testSecondResultsPages) EXPECT_EQ(4, tdc->topDocs(10, 4)->scoreDocs.size()); } -TEST_F(TopDocsCollectorTest, testGetAllResults) -{ +TEST_F(TopDocsCollectorTest, testGetAllResults) { TopDocsCollectorPtr tdc = doSearch(15); EXPECT_EQ(15, tdc->topDocs()->scoreDocs.size()); } -TEST_F(TopDocsCollectorTest, testGetResultsFromStart) -{ +TEST_F(TopDocsCollectorTest, testGetResultsFromStart) { TopDocsCollectorPtr tdc = doSearch(15); // should bring all results EXPECT_EQ(15, tdc->topDocs(0)->scoreDocs.size()); @@ -193,8 +177,7 @@ TEST_F(TopDocsCollectorTest, testGetResultsFromStart) EXPECT_EQ(5, tdc->topDocs(10)->scoreDocs.size()); } -TEST_F(TopDocsCollectorTest, testMaxScore) -{ +TEST_F(TopDocsCollectorTest, testMaxScore) { // ask for all results TopDocsCollectorPtr tdc = doSearch(15); TopDocsPtr td = tdc->topDocs(); @@ -208,12 +191,12 @@ TEST_F(TopDocsCollectorTest, testMaxScore) /// This does not test the PQ's correctness, but whether topDocs() implementations /// return the results in decreasing score order. -TEST_F(TopDocsCollectorTest, testResultsOrder) -{ +TEST_F(TopDocsCollectorTest, testResultsOrder) { TopDocsCollectorPtr tdc = doSearch(15); Collection sd = tdc->topDocs()->scoreDocs; EXPECT_EQ(MAX_SCORE, sd[0]->score); - for (int32_t i = 1; i < sd.size(); ++i) + for (int32_t i = 1; i < sd.size(); ++i) { EXPECT_TRUE(sd[i - 1]->score >= sd[i]->score); + } } diff --git a/src/test/search/TopScoreDocCollectorTest.cpp b/src/test/search/TopScoreDocCollectorTest.cpp index 3b6b1bc8..db98d480 100644 --- a/src/test/search/TopScoreDocCollectorTest.cpp +++ b/src/test/search/TopScoreDocCollectorTest.cpp @@ -21,12 +21,12 @@ using namespace Lucene; typedef LuceneTestFixture TopScoreDocCollectorTest; -TEST_F(TopScoreDocCollectorTest, testOutOfOrderCollection) -{ +TEST_F(TopScoreDocCollectorTest, testOutOfOrderCollection) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, AnalyzerPtr(), IndexWriter::MaxFieldLengthUNLIMITED); - for (int32_t i = 0; i < 10; ++i) + for (int32_t i = 0; i < 10; ++i) { writer->addDocument(newLucene()); + } writer->commit(); writer->close(); @@ -42,8 +42,7 @@ TEST_F(TopScoreDocCollectorTest, testOutOfOrderCollection) // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return the clause instead of BQ. bq->setMinimumNumberShouldMatch(1); IndexSearcherPtr searcher = newLucene(dir, true); - for (int32_t i = 0; i < inOrder.size(); ++i) - { + for (int32_t i = 0; i < inOrder.size(); ++i) { TopDocsCollectorPtr tdc = TopScoreDocCollector::create(3, inOrder[i] == 1); EXPECT_EQ(actualTSDCClass[i], tdc->getClassName()); @@ -51,7 +50,8 @@ TEST_F(TopScoreDocCollectorTest, testOutOfOrderCollection) Collection sd = tdc->topDocs()->scoreDocs; EXPECT_EQ(3, sd.size()); - for (int32_t j = 0; j < sd.size(); ++j) + for (int32_t j = 0; j < sd.size(); ++j) { EXPECT_EQ(j, sd[j]->doc); + } } } diff --git a/src/test/search/WildcardTest.cpp b/src/test/search/WildcardTest.cpp index 7388776c..ee40c01a 100644 --- a/src/test/search/WildcardTest.cpp +++ b/src/test/search/WildcardTest.cpp @@ -29,12 +29,10 @@ using namespace Lucene; typedef LuceneTestFixture WildcardTest; -static RAMDirectoryPtr getIndexStore(const String& field, Collection contents) -{ +static RAMDirectoryPtr getIndexStore(const String& field, Collection contents) { RAMDirectoryPtr indexStore = newLucene(); IndexWriterPtr writer = newLucene(indexStore, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < contents.size(); ++i) - { + for (int32_t i = 0; i < contents.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(field, contents[i], Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -45,14 +43,12 @@ static RAMDirectoryPtr getIndexStore(const String& field, Collection con return indexStore; } -static void checkMatches(const IndexSearcherPtr& searcher, const QueryPtr& q, int32_t expectedMatches) -{ +static void checkMatches(const IndexSearcherPtr& searcher, const QueryPtr& q, int32_t expectedMatches) { Collection result = searcher->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(expectedMatches, result.size()); } -TEST_F(WildcardTest, testEquals) -{ +TEST_F(WildcardTest, testEquals) { WildcardQueryPtr wq1 = newLucene(newLucene(L"field", L"b*a")); WildcardQueryPtr wq2 = newLucene(newLucene(L"field", L"b*a")); WildcardQueryPtr wq3 = newLucene(newLucene(L"field", L"b*a")); @@ -75,8 +71,7 @@ TEST_F(WildcardTest, testEquals) /// Tests if a WildcardQuery that has no wildcard in the term is rewritten to a single TermQuery. /// The boost should be preserved, and the rewrite should return a ConstantScoreQuery if the /// WildcardQuery had a ConstantScore rewriteMethod. -TEST_F(WildcardTest, testTermWithoutWildcard) -{ +TEST_F(WildcardTest, testTermWithoutWildcard) { RAMDirectoryPtr indexStore = getIndexStore(L"field", newCollection(L"nowildcard", L"nowildcardx")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -109,8 +104,7 @@ TEST_F(WildcardTest, testTermWithoutWildcard) } /// Tests if a WildcardQuery with an empty term is rewritten to an empty BooleanQuery -TEST_F(WildcardTest, testEmptyTerm) -{ +TEST_F(WildcardTest, testEmptyTerm) { RAMDirectoryPtr indexStore = getIndexStore(L"field", newCollection(L"nowildcard", L"nowildcardx")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -123,8 +117,7 @@ TEST_F(WildcardTest, testEmptyTerm) /// Tests if a WildcardQuery that has only a trailing * in the term is rewritten to a /// single PrefixQuery. The boost and rewriteMethod should be preserved. -TEST_F(WildcardTest, testPrefixTerm) -{ +TEST_F(WildcardTest, testPrefixTerm) { RAMDirectoryPtr indexStore = getIndexStore(L"field", newCollection(L"prefix", L"prefixx")); IndexSearcherPtr searcher = newLucene(indexStore, true); @@ -157,8 +150,7 @@ TEST_F(WildcardTest, testPrefixTerm) EXPECT_TRUE(searcher->rewrite(expected)->equals(searcher->rewrite(wq))); } -TEST_F(WildcardTest, testAsterisk) -{ +TEST_F(WildcardTest, testAsterisk) { RAMDirectoryPtr indexStore = getIndexStore(L"body", newCollection(L"metal", L"metals")); IndexSearcherPtr searcher = newLucene(indexStore, true); QueryPtr query1 = newLucene(newLucene(L"body", L"metal")); @@ -190,14 +182,14 @@ TEST_F(WildcardTest, testAsterisk) checkMatches(searcher, newLucene(newLucene(L"body", L"*tal*")), 2); } -TEST_F(WildcardTest, testLotsOfAsterisks) -{ +TEST_F(WildcardTest, testLotsOfAsterisks) { RAMDirectoryPtr indexStore = getIndexStore(L"body", newCollection(L"metal", L"metals")); IndexSearcherPtr searcher = newLucene(indexStore, true); StringStream term; term << L"m"; - for (int32_t i = 0; i < 512; ++i) + for (int32_t i = 0; i < 512; ++i) { term << L"*"; + } term << L"tal"; QueryPtr query3 = newLucene(newLucene(L"body", term.str())); @@ -206,8 +198,7 @@ TEST_F(WildcardTest, testLotsOfAsterisks) indexStore->close(); } -TEST_F(WildcardTest, testQuestionmark) -{ +TEST_F(WildcardTest, testQuestionmark) { RAMDirectoryPtr indexStore = getIndexStore(L"body", newCollection(L"metal", L"metals", L"mXtals", L"mXtXls")); IndexSearcherPtr searcher = newLucene(indexStore, true); QueryPtr query1 = newLucene(newLucene(L"body", L"m?tal")); @@ -229,8 +220,7 @@ TEST_F(WildcardTest, testQuestionmark) /// This test looks at both parsing and execution of wildcard queries. Although placed /// here, it also tests prefix queries, verifying that prefix queries are not parsed into /// wild card queries, and vice-versa. -TEST_F(WildcardTest, testParsingAndSearching) -{ +TEST_F(WildcardTest, testParsingAndSearching) { String field = L"content"; QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, field, newLucene()); qp->setAllowLeadingWildcard(true); @@ -244,23 +234,22 @@ TEST_F(WildcardTest, testParsingAndSearching) // queries that should be parsed to prefix queries Collection< Collection > matchOneDocPrefix = newCollection< Collection >( - newCollection(L"a*", L"ab*", L"abc*"), // these should find only doc 0 - newCollection(L"h*", L"hi*", L"hij*", L"\\\\7*"), // these should find only doc 1 - newCollection(L"o*", L"op*", L"opq*", L"\\\\\\\\*") // these should find only doc 2 - ); + newCollection(L"a*", L"ab*", L"abc*"), // these should find only doc 0 + newCollection(L"h*", L"hi*", L"hij*", L"\\\\7*"), // these should find only doc 1 + newCollection(L"o*", L"op*", L"opq*", L"\\\\\\\\*") // these should find only doc 2 + ); // queries that should be parsed to wildcard queries Collection< Collection > matchOneDocWild = newCollection< Collection >( - newCollection(L"*a*", L"*ab*", L"*abc**", L"ab*e*", L"*g?", L"*f?1", L"abc**"), // these should find only doc 0 - newCollection(L"*h*", L"*hi*", L"*hij**", L"hi*k*", L"*n?", L"*m?1", L"hij**"), // these should find only doc 1 - newCollection(L"*o*", L"*op*", L"*opq**", L"op*q*", L"*u?", L"*t?1", L"opq**") // these should find only doc 2 - ); + newCollection(L"*a*", L"*ab*", L"*abc**", L"ab*e*", L"*g?", L"*f?1", L"abc**"), // these should find only doc 0 + newCollection(L"*h*", L"*hi*", L"*hij**", L"hi*k*", L"*n?", L"*m?1", L"hij**"), // these should find only doc 1 + newCollection(L"*o*", L"*op*", L"*opq**", L"op*q*", L"*u?", L"*t?1", L"opq**") // these should find only doc 2 + ); // prepare the index RAMDirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(), IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < docs.size(); ++i) - { + for (int32_t i = 0; i < docs.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(field, docs[i], Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -270,8 +259,7 @@ TEST_F(WildcardTest, testParsingAndSearching) IndexSearcherPtr searcher = newLucene(dir, true); // test queries that must find all - for (int32_t i = 0; i < matchAll.size(); ++i) - { + for (int32_t i = 0; i < matchAll.size(); ++i) { String qtxt = matchAll[i]; QueryPtr q = qp->parse(qtxt); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; @@ -279,8 +267,7 @@ TEST_F(WildcardTest, testParsingAndSearching) } // test queries that must find none - for (int32_t i = 0; i < matchNone.size(); ++i) - { + for (int32_t i = 0; i < matchNone.size(); ++i) { String qtxt = matchNone[i]; QueryPtr q = qp->parse(qtxt); Collection hits = searcher->search(q, FilterPtr(), 1000)->scoreDocs; @@ -288,10 +275,8 @@ TEST_F(WildcardTest, testParsingAndSearching) } // test queries that must be prefix queries and must find only one doc - for (int32_t i = 0; i < matchOneDocPrefix.size(); ++i) - { - for (int32_t j = 0; j < matchOneDocPrefix[i].size(); ++j) - { + for (int32_t i = 0; i < matchOneDocPrefix.size(); ++i) { + for (int32_t j = 0; j < matchOneDocPrefix[i].size(); ++j) { String qtxt = matchOneDocPrefix[i][j]; QueryPtr q = qp->parse(qtxt); EXPECT_TRUE(MiscUtils::typeOf(q)); @@ -302,10 +287,8 @@ TEST_F(WildcardTest, testParsingAndSearching) } // test queries that must be wildcard queries and must find only one doc - for (int32_t i = 0; i < matchOneDocPrefix.size(); ++i) - { - for (int32_t j = 0; j < matchOneDocWild[i].size(); ++j) - { + for (int32_t i = 0; i < matchOneDocPrefix.size(); ++i) { + for (int32_t j = 0; j < matchOneDocWild[i].size(); ++j) { String qtxt = matchOneDocWild[i][j]; QueryPtr q = qp->parse(qtxt); EXPECT_TRUE(MiscUtils::typeOf(q)); diff --git a/src/test/search/function/CustomScoreQueryTest.cpp b/src/test/search/function/CustomScoreQueryTest.cpp index 8cf4e060..ffc5885c 100644 --- a/src/test/search/function/CustomScoreQueryTest.cpp +++ b/src/test/search/function/CustomScoreQueryTest.cpp @@ -22,89 +22,77 @@ using namespace Lucene; -class CustomAddScoreProvider : public CustomScoreProvider -{ +class CustomAddScoreProvider : public CustomScoreProvider { public: - CustomAddScoreProvider(const IndexReaderPtr& reader) : CustomScoreProvider(reader) - { + CustomAddScoreProvider(const IndexReaderPtr& reader) : CustomScoreProvider(reader) { } - virtual ~CustomAddScoreProvider() - { + virtual ~CustomAddScoreProvider() { } public: - virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore) - { + virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore) { return subQueryScore + valSrcScore; } - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) - { + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, const ExplanationPtr& valSrcExpl) { double valSrcScore = valSrcExpl ? valSrcExpl->getValue() : 0.0; ExplanationPtr exp = newLucene(valSrcScore + subQueryExpl->getValue(), L"custom score: sum of:"); exp->addDetail(subQueryExpl); - if (valSrcExpl) + if (valSrcExpl) { exp->addDetail(valSrcExpl); + } return exp; } }; -class CustomAddQuery : public CustomScoreQuery -{ +class CustomAddQuery : public CustomScoreQuery { public: - CustomAddQuery(const QueryPtr& q, const ValueSourceQueryPtr& qValSrc) : CustomScoreQuery(q, qValSrc) - { + CustomAddQuery(const QueryPtr& q, const ValueSourceQueryPtr& qValSrc) : CustomScoreQuery(q, qValSrc) { } - virtual ~CustomAddQuery() - { + virtual ~CustomAddQuery() { } public: - virtual String name() - { + virtual String name() { return L"customAdd"; } protected: - virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) - { + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) { return newLucene(reader); } }; -class CustomMulAddScoreProvider : public CustomScoreProvider -{ +class CustomMulAddScoreProvider : public CustomScoreProvider { public: - CustomMulAddScoreProvider(const IndexReaderPtr& reader) : CustomScoreProvider(reader) - { + CustomMulAddScoreProvider(const IndexReaderPtr& reader) : CustomScoreProvider(reader) { } - virtual ~CustomMulAddScoreProvider() - { + virtual ~CustomMulAddScoreProvider() { } public: - virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores) - { - if (valSrcScores.empty()) + virtual double customScore(int32_t doc, double subQueryScore, Collection valSrcScores) { + if (valSrcScores.empty()) { return subQueryScore; - if (valSrcScores.size() == 1) + } + if (valSrcScores.size() == 1) { return subQueryScore + valSrcScores[0]; + } // confirm that skipping beyond the last doc, on the previous reader, hits NO_MORE_DOCS return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know there are two } - virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) - { - if (valSrcExpls.empty()) + virtual ExplanationPtr customExplain(int32_t doc, const ExplanationPtr& subQueryExpl, Collection valSrcExpls) { + if (valSrcExpls.empty()) { return subQueryExpl; + } ExplanationPtr exp = newLucene(valSrcExpls[0]->getValue() + subQueryExpl->getValue(), L"sum of:"); exp->addDetail(subQueryExpl); exp->addDetail(valSrcExpls[0]); - if (valSrcExpls.size() == 1) - { + if (valSrcExpls.size() == 1) { exp->setDescription(L"CustomMulAdd, sum of:"); return exp; } @@ -115,96 +103,79 @@ class CustomMulAddScoreProvider : public CustomScoreProvider } }; -class CustomMulAddQuery : public CustomScoreQuery -{ +class CustomMulAddQuery : public CustomScoreQuery { public: - CustomMulAddQuery(const QueryPtr& q, const ValueSourceQueryPtr& qValSrc1, const ValueSourceQueryPtr& qValSrc2) : CustomScoreQuery(q, newCollection(qValSrc1, qValSrc2)) - { + CustomMulAddQuery(const QueryPtr& q, const ValueSourceQueryPtr& qValSrc1, const ValueSourceQueryPtr& qValSrc2) : CustomScoreQuery(q, newCollection(qValSrc1, qValSrc2)) { } - virtual ~CustomMulAddQuery() - { + virtual ~CustomMulAddQuery() { } public: - virtual String name() - { + virtual String name() { return L"customMulAdd"; } protected: - virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) - { + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) { return newLucene(reader); } }; -class CustomExternalScoreProvider : public CustomScoreProvider -{ +class CustomExternalScoreProvider : public CustomScoreProvider { public: - CustomExternalScoreProvider(const IndexReaderPtr& reader, Collection values) : CustomScoreProvider(reader) - { + CustomExternalScoreProvider(const IndexReaderPtr& reader, Collection values) : CustomScoreProvider(reader) { this->values = values; } - virtual ~CustomExternalScoreProvider() - { + virtual ~CustomExternalScoreProvider() { } protected: Collection values; public: - virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore) - { + virtual double customScore(int32_t doc, double subQueryScore, double valSrcScore) { EXPECT_TRUE(doc <= reader->maxDoc()); return (double)values[doc]; } }; -class CustomExternalQuery : public CustomScoreQuery -{ +class CustomExternalQuery : public CustomScoreQuery { public: - CustomExternalQuery(const QueryPtr& q) : CustomScoreQuery(q) - { + CustomExternalQuery(const QueryPtr& q) : CustomScoreQuery(q) { } - virtual ~CustomExternalQuery() - { + virtual ~CustomExternalQuery() { } protected: - virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) - { + virtual CustomScoreProviderPtr getCustomScoreProvider(const IndexReaderPtr& reader) { Collection values = FieldCache::DEFAULT()->getInts(reader, FunctionFixture::INT_FIELD); return newLucene(reader, values); } }; -class CustomScoreQueryTest : public FunctionFixture -{ +class CustomScoreQueryTest : public FunctionFixture { public: - CustomScoreQueryTest() : FunctionFixture(true) - { + CustomScoreQueryTest() : FunctionFixture(true) { } - virtual ~CustomScoreQueryTest() - { + virtual ~CustomScoreQueryTest() { } public: /// since custom scoring modifies the order of docs, map results by doc ids so that we can later compare/verify them - MapIntDouble topDocsToMap(const TopDocsPtr& td) - { + MapIntDouble topDocsToMap(const TopDocsPtr& td) { MapIntDouble h = MapIntDouble::newInstance(); - for (int32_t i = 0; i < td->totalHits; ++i) + for (int32_t i = 0; i < td->totalHits; ++i) { h.put(td->scoreDocs[i]->doc, td->scoreDocs[i]->score); + } return h; } void verifyResults(double boost, IndexSearcherPtr s, MapIntDouble h1, MapIntDouble h2customNeutral, MapIntDouble h3CustomMul, - MapIntDouble h4CustomAdd, MapIntDouble h5CustomMulAdd, QueryPtr q1, QueryPtr q2, QueryPtr q3, QueryPtr q4, QueryPtr q5) - { + MapIntDouble h4CustomAdd, MapIntDouble h5CustomMulAdd, QueryPtr q1, QueryPtr q2, QueryPtr q3, QueryPtr q4, QueryPtr q5) { // verify numbers of matches EXPECT_EQ(h1.size(), h2customNeutral.size()); EXPECT_EQ(h1.size(), h3CustomMul.size()); @@ -212,8 +183,7 @@ class CustomScoreQueryTest : public FunctionFixture EXPECT_EQ(h1.size(), h5CustomMulAdd.size()); // verify scores ratios - for (MapIntDouble::iterator it = h1.begin(); it != h1.end(); ++it) - { + for (MapIntDouble::iterator it = h1.begin(); it != h1.end(); ++it) { int32_t doc = it->first; double fieldScore = expectedFieldScore(s->getIndexReader()->document(doc)->get(ID_FIELD)); EXPECT_TRUE(fieldScore > 0); @@ -235,8 +205,7 @@ class CustomScoreQueryTest : public FunctionFixture } /// Test that FieldScoreQuery returns docs with expected score. - void doTestCustomScore(const String& field, FieldScoreQuery::Type tp, double boost) - { + void doTestCustomScore(const String& field, FieldScoreQuery::Type tp, double boost) { IndexSearcherPtr s = newLucene(dir, true); FieldScoreQueryPtr qValSrc = newLucene(field, tp); // a query that would score by the field QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, TEXT_FIELD, anlzr); @@ -283,8 +252,7 @@ class CustomScoreQueryTest : public FunctionFixture } }; -TEST_F(CustomScoreQueryTest, testCustomExternalQuery) -{ +TEST_F(CustomScoreQueryTest, testCustomExternalQuery) { QueryParserPtr qp = newLucene(LuceneVersion::LUCENE_CURRENT, TEXT_FIELD, anlzr); String qtxt = L"first aid text"; // from the doc texts in FunctionFixture. QueryPtr q1 = qp->parse(qtxt); @@ -294,8 +262,7 @@ TEST_F(CustomScoreQueryTest, testCustomExternalQuery) IndexSearcherPtr s = newLucene(dir); TopDocsPtr hits = s->search(q, 1000); EXPECT_EQ(N_DOCS, hits->totalHits); - for (int32_t i = 0; i < N_DOCS; ++i) - { + for (int32_t i = 0; i < N_DOCS; ++i) { int32_t doc = hits->scoreDocs[i]->doc; double score = hits->scoreDocs[i]->score; EXPECT_NEAR((double)(1 + (4 * doc) % N_DOCS), score, 0.0001); @@ -304,24 +271,21 @@ TEST_F(CustomScoreQueryTest, testCustomExternalQuery) } /// Test that CustomScoreQuery of Type.BYTE returns the expected scores. -TEST_F(CustomScoreQueryTest, testCustomScoreByte) -{ +TEST_F(CustomScoreQueryTest, testCustomScoreByte) { // INT field values are small enough to be parsed as byte doTestCustomScore(INT_FIELD, FieldScoreQuery::BYTE, 1.0); doTestCustomScore(INT_FIELD, FieldScoreQuery::BYTE, 2.0); } /// Test that CustomScoreQuery of Type.INT returns the expected scores. -TEST_F(CustomScoreQueryTest, testCustomScoreInt) -{ +TEST_F(CustomScoreQueryTest, testCustomScoreInt) { // INT field values are small enough to be parsed as int doTestCustomScore(INT_FIELD, FieldScoreQuery::INT, 1.0); doTestCustomScore(INT_FIELD, FieldScoreQuery::INT, 2.0); } /// Test that CustomScoreQuery of Type.DOUBLE returns the expected scores. -TEST_F(CustomScoreQueryTest, testCustomScoreDouble) -{ +TEST_F(CustomScoreQueryTest, testCustomScoreDouble) { // INT field can be parsed as double doTestCustomScore(INT_FIELD, FieldScoreQuery::DOUBLE, 1.0); doTestCustomScore(INT_FIELD, FieldScoreQuery::DOUBLE, 5.0); diff --git a/src/test/search/function/DocValuesTest.cpp b/src/test/search/function/DocValuesTest.cpp index 113893f4..56a9e4fe 100644 --- a/src/test/search/function/DocValuesTest.cpp +++ b/src/test/search/function/DocValuesTest.cpp @@ -16,37 +16,32 @@ typedef LuceneTestFixture DocValuesTest; DECLARE_SHARED_PTR(TestableDocValues) -class TestableDocValues : public DocValues -{ +class TestableDocValues : public DocValues { public: - TestableDocValues(Collection innerArray) - { + TestableDocValues(Collection innerArray) { this->innerArray = innerArray; } - virtual ~TestableDocValues() - { + virtual ~TestableDocValues() { } public: Collection innerArray; public: - virtual double doubleVal(int32_t doc) - { - if (doc < 0 || doc >= innerArray.size()) + virtual double doubleVal(int32_t doc) { + if (doc < 0 || doc >= innerArray.size()) { boost::throw_exception(IndexOutOfBoundsException()); + } return innerArray[doc]; } - virtual String toString(int32_t doc) - { + virtual String toString(int32_t doc) { return StringUtils::toString(doc); } }; -TEST_F(DocValuesTest, testGetMinValue) -{ +TEST_F(DocValuesTest, testGetMinValue) { Collection innerArray = newCollection(1.0, 2.0, -1.0, 100.0); TestableDocValuesPtr docValues = newLucene(innerArray); EXPECT_EQ(-1.0, docValues->getMinValue()); @@ -57,8 +52,7 @@ TEST_F(DocValuesTest, testGetMinValue) EXPECT_TRUE(MiscUtils::isNaN(docValues->getMinValue())); } -TEST_F(DocValuesTest, testGetMaxValue) -{ +TEST_F(DocValuesTest, testGetMaxValue) { Collection innerArray = newCollection(1.0, 2.0, -1.0, 10.0); TestableDocValuesPtr docValues = newLucene(innerArray); EXPECT_EQ(10.0, docValues->getMaxValue()); @@ -77,8 +71,7 @@ TEST_F(DocValuesTest, testGetMaxValue) EXPECT_TRUE(MiscUtils::isNaN(docValues->getMaxValue())); } -TEST_F(DocValuesTest, testGetAverageValue) -{ +TEST_F(DocValuesTest, testGetAverageValue) { Collection innerArray = newCollection(1.0, 1.0, 1.0, 1.0); TestableDocValuesPtr docValues = newLucene(innerArray); EXPECT_EQ(1.0, docValues->getAverageValue()); diff --git a/src/test/search/function/FieldScoreQueryTest.cpp b/src/test/search/function/FieldScoreQueryTest.cpp index c36217e0..1d1b917e 100644 --- a/src/test/search/function/FieldScoreQueryTest.cpp +++ b/src/test/search/function/FieldScoreQueryTest.cpp @@ -26,21 +26,17 @@ using namespace Lucene; /// The rank tests use Hits to verify that docs are ordered (by score) as expected. /// /// The exact score tests use TopDocs top to verify the exact score. -class FieldScoreQueryTest : public FunctionFixture -{ +class FieldScoreQueryTest : public FunctionFixture { public: - FieldScoreQueryTest() : FunctionFixture(true) - { + FieldScoreQueryTest() : FunctionFixture(true) { } - virtual ~FieldScoreQueryTest() - { + virtual ~FieldScoreQueryTest() { } public: /// Test that FieldScoreQuery returns docs in expected order. - void doTestRank(const String& field, FieldScoreQuery::Type tp) - { + void doTestRank(const String& field, FieldScoreQuery::Type tp) { IndexSearcherPtr s = newLucene(dir, true); QueryPtr q = newLucene(field,tp); @@ -48,8 +44,7 @@ class FieldScoreQueryTest : public FunctionFixture Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(N_DOCS, h.size()); String prevID = L"ID" + StringUtils::toString(N_DOCS + 1); // greater than all ids of docs in this test - for (int32_t i = 0; i < h.size(); ++i) - { + for (int32_t i = 0; i < h.size(); ++i) { String resID = s->doc(h[i]->doc)->get(ID_FIELD); EXPECT_TRUE(resID.compare(prevID) < 0); prevID = resID; @@ -57,15 +52,13 @@ class FieldScoreQueryTest : public FunctionFixture } /// Test that FieldScoreQuery returns docs with expected score. - void doTestExactScore(const String& field, FieldScoreQuery::Type tp) - { + void doTestExactScore(const String& field, FieldScoreQuery::Type tp) { IndexSearcherPtr s = newLucene(dir, true); QueryPtr q = newLucene(field, tp); TopDocsPtr td = s->search(q, FilterPtr(), 1000); EXPECT_EQ(N_DOCS, td->totalHits); Collection sd = td->scoreDocs; - for (int32_t i = 0; i < sd.size(); ++i) - { + for (int32_t i = 0; i < sd.size(); ++i) { double score = sd[i]->score; String id = s->getIndexReader()->document(sd[i]->doc)->get(ID_FIELD); double expectedScore = expectedFieldScore(id); // "ID7" --> 7.0 @@ -75,8 +68,7 @@ class FieldScoreQueryTest : public FunctionFixture /// Test that values loaded for FieldScoreQuery are cached properly and consumes /// the proper RAM resources. - void doTestCaching(const String& field, FieldScoreQuery::Type tp) - { + void doTestCaching(const String& field, FieldScoreQuery::Type tp) { // prepare expected array types for comparison HashMap expectedArrayTypes = HashMap::newInstance(); expectedArrayTypes.put(FieldScoreQuery::BYTE, Collection::newInstance()); @@ -87,29 +79,22 @@ class FieldScoreQueryTest : public FunctionFixture Collection innerArray = Collection::newInstance(s->getIndexReader()->getSequentialSubReaders().size()); bool warned = false; // print warning once. - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { FieldScoreQueryPtr q = newLucene(field, tp); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); - for (int32_t j = 0; j < readers.size(); ++j) - { + for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; - try - { - if (i == 0) - { + try { + if (i == 0) { innerArray[j] = q->valSrc->getValues(reader)->getInnerArray(); EXPECT_TRUE(VariantUtils::equalsType(innerArray[j], expectedArrayTypes.get(tp))); - } - else + } else { EXPECT_TRUE(VariantUtils::equals(innerArray[j], q->valSrc->getValues(reader)->getInnerArray())); - } - catch (UnsupportedOperationException&) - { - if (!warned) - { + } + } catch (UnsupportedOperationException&) { + if (!warned) { // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } @@ -123,17 +108,12 @@ class FieldScoreQueryTest : public FunctionFixture Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); - for (int32_t j = 0; j < readers.size(); ++j) - { + for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; - try - { + try { EXPECT_TRUE(!equalCollectionValues(innerArray[j], q->valSrc->getValues(reader)->getInnerArray())); - } - catch (UnsupportedOperationException&) - { - if (!warned) - { + } catch (UnsupportedOperationException&) { + if (!warned) { // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } @@ -143,21 +123,18 @@ class FieldScoreQueryTest : public FunctionFixture }; /// Test that FieldScoreQuery of Type.BYTE returns docs in expected order. -TEST_F(FieldScoreQueryTest, testRankByte) -{ +TEST_F(FieldScoreQueryTest, testRankByte) { // INT field values are small enough to be parsed as byte doTestRank(INT_FIELD, FieldScoreQuery::BYTE); } /// Test that FieldScoreQuery of Type.INT returns docs in expected order. -TEST_F(FieldScoreQueryTest, testRankInt) -{ +TEST_F(FieldScoreQueryTest, testRankInt) { doTestRank(INT_FIELD, FieldScoreQuery::INT); } /// Test that FieldScoreQuery of Type.DOUBLE returns docs in expected order. -TEST_F(FieldScoreQueryTest, testRankDouble) -{ +TEST_F(FieldScoreQueryTest, testRankDouble) { // INT field can be parsed as double doTestRank(INT_FIELD, FieldScoreQuery::DOUBLE); // same values, but in double format @@ -165,22 +142,19 @@ TEST_F(FieldScoreQueryTest, testRankDouble) } /// Test that FieldScoreQuery of Type.BYTE returns the expected scores. -TEST_F(FieldScoreQueryTest, testExactScoreByte) -{ +TEST_F(FieldScoreQueryTest, testExactScoreByte) { // INT field values are small enough to be parsed as byte doTestExactScore(INT_FIELD, FieldScoreQuery::BYTE); } /// Test that FieldScoreQuery of Type.INT returns the expected scores. -TEST_F(FieldScoreQueryTest, testExactScoreInt) -{ +TEST_F(FieldScoreQueryTest, testExactScoreInt) { // INT field values are small enough to be parsed as byte doTestExactScore(INT_FIELD, FieldScoreQuery::INT); } /// Test that FieldScoreQuery of Type.DOUBLE returns the expected scores. -TEST_F(FieldScoreQueryTest, testExactScoreDouble) -{ +TEST_F(FieldScoreQueryTest, testExactScoreDouble) { // INT field can be parsed as double doTestExactScore(INT_FIELD, FieldScoreQuery::DOUBLE); // same values, but in double format @@ -189,24 +163,21 @@ TEST_F(FieldScoreQueryTest, testExactScoreDouble) /// Test that FieldScoreQuery of Type.BYTE caches/reuses loaded values and consumes /// the proper RAM resources. -TEST_F(FieldScoreQueryTest, testCachingByte) -{ +TEST_F(FieldScoreQueryTest, testCachingByte) { // INT field values are small enough to be parsed as byte doTestCaching(INT_FIELD, FieldScoreQuery::BYTE); } /// Test that FieldScoreQuery of Type.INT caches/reuses loaded values and consumes /// the proper RAM resources. -TEST_F(FieldScoreQueryTest, testCachingInt) -{ +TEST_F(FieldScoreQueryTest, testCachingInt) { // INT field values are small enough to be parsed as byte doTestCaching(INT_FIELD, FieldScoreQuery::INT); } /// Test that FieldScoreQuery of Type.DOUBLE caches/reuses loaded values and consumes /// the proper RAM resources. -TEST_F(FieldScoreQueryTest, testCachingDouble) -{ +TEST_F(FieldScoreQueryTest, testCachingDouble) { // INT field values can be parsed as float doTestCaching(INT_FIELD, FieldScoreQuery::DOUBLE); // same values, but in double format diff --git a/src/test/search/function/FunctionFixture.cpp b/src/test/search/function/FunctionFixture.cpp index d60fd34d..b86eca61 100644 --- a/src/test/search/function/FunctionFixture.cpp +++ b/src/test/search/function/FunctionFixture.cpp @@ -13,126 +13,123 @@ #include "Field.h" #include "VariantUtils.h" -namespace Lucene -{ - /// Actual score computation order is slightly different than assumptions this allows for a small amount of variation - const double FunctionFixture::TEST_SCORE_TOLERANCE_DELTA = 0.001; - - const int32_t FunctionFixture::N_DOCS = 17; - - const String FunctionFixture::ID_FIELD = L"id"; - const String FunctionFixture::TEXT_FIELD = L"text"; - const String FunctionFixture::INT_FIELD = L"iii"; - const String FunctionFixture::DOUBLE_FIELD = L"fff"; - - FunctionFixture::FunctionFixture(bool doMultiSegment) - { - this->doMultiSegment = doMultiSegment; - - // prepare a small index with just a few documents. - dir = newLucene(); - anlzr = newLucene(LuceneVersion::LUCENE_CURRENT); - IndexWriterPtr iw = newLucene(dir, anlzr, IndexWriter::MaxFieldLengthLIMITED); - // add docs not exactly in natural ID order, to verify we do check the order of docs by scores - int32_t remaining = N_DOCS; - Collection done = Collection::newInstance(N_DOCS); - int32_t i = 0; - while (remaining > 0) - { - if (done[i]) - boost::throw_exception(RuntimeException(L"to set this test correctly N_DOCS=" + StringUtils::toString(N_DOCS) + L" must be primary and greater than 2!")); - addDoc(iw, i); - done[i] = true; - i = (i + 4) % N_DOCS; - if (doMultiSegment && remaining % 3 == 0) - iw->commit(); - --remaining; +namespace Lucene { + +/// Actual score computation order is slightly different than assumptions this allows for a small amount of variation +const double FunctionFixture::TEST_SCORE_TOLERANCE_DELTA = 0.001; + +const int32_t FunctionFixture::N_DOCS = 17; + +const String FunctionFixture::ID_FIELD = L"id"; +const String FunctionFixture::TEXT_FIELD = L"text"; +const String FunctionFixture::INT_FIELD = L"iii"; +const String FunctionFixture::DOUBLE_FIELD = L"fff"; + +FunctionFixture::FunctionFixture(bool doMultiSegment) { + this->doMultiSegment = doMultiSegment; + + // prepare a small index with just a few documents. + dir = newLucene(); + anlzr = newLucene(LuceneVersion::LUCENE_CURRENT); + IndexWriterPtr iw = newLucene(dir, anlzr, IndexWriter::MaxFieldLengthLIMITED); + // add docs not exactly in natural ID order, to verify we do check the order of docs by scores + int32_t remaining = N_DOCS; + Collection done = Collection::newInstance(N_DOCS); + int32_t i = 0; + while (remaining > 0) { + if (done[i]) { + boost::throw_exception(RuntimeException(L"to set this test correctly N_DOCS=" + StringUtils::toString(N_DOCS) + L" must be primary and greater than 2!")); } - iw->close(); + addDoc(iw, i); + done[i] = true; + i = (i + 4) % N_DOCS; + if (doMultiSegment && remaining % 3 == 0) { + iw->commit(); + } + --remaining; } + iw->close(); +} - FunctionFixture::~FunctionFixture() - { - } +FunctionFixture::~FunctionFixture() { +} - const Collection FunctionFixture::DOC_TEXT_LINES() - { - static Collection _DOC_TEXT_LINES; - if (!_DOC_TEXT_LINES) - { - _DOC_TEXT_LINES = Collection::newInstance(); - _DOC_TEXT_LINES.add(L"Well, this is just some plain text we use for creating the "); - _DOC_TEXT_LINES.add(L"test documents. It used to be a text from an online collection "); - _DOC_TEXT_LINES.add(L"devoted to first aid, but if there was there an (online) lawyers "); - _DOC_TEXT_LINES.add(L"first aid collection with legal advices, \"it\" might have quite "); - _DOC_TEXT_LINES.add(L"probably advised one not to include \"it\"'s text or the text of "); - _DOC_TEXT_LINES.add(L"any other online collection in one's code, unless one has money "); - _DOC_TEXT_LINES.add(L"that one don't need and one is happy to donate for lawyers "); - _DOC_TEXT_LINES.add(L"charity. Anyhow at some point, rechecking the usage of this text, "); - _DOC_TEXT_LINES.add(L"it became uncertain that this text is free to use, because "); - _DOC_TEXT_LINES.add(L"the web site in the disclaimer of he eBook containing that text "); - _DOC_TEXT_LINES.add(L"was not responding anymore, and at the same time, in projGut, "); - _DOC_TEXT_LINES.add(L"searching for first aid no longer found that eBook as well. "); - _DOC_TEXT_LINES.add(L"So here we are, with a perhaps much less interesting "); - _DOC_TEXT_LINES.add(L"text for the test, but oh much much safer. "); - } - return _DOC_TEXT_LINES; +const Collection FunctionFixture::DOC_TEXT_LINES() { + static Collection _DOC_TEXT_LINES; + if (!_DOC_TEXT_LINES) { + _DOC_TEXT_LINES = Collection::newInstance(); + _DOC_TEXT_LINES.add(L"Well, this is just some plain text we use for creating the "); + _DOC_TEXT_LINES.add(L"test documents. It used to be a text from an online collection "); + _DOC_TEXT_LINES.add(L"devoted to first aid, but if there was there an (online) lawyers "); + _DOC_TEXT_LINES.add(L"first aid collection with legal advices, \"it\" might have quite "); + _DOC_TEXT_LINES.add(L"probably advised one not to include \"it\"'s text or the text of "); + _DOC_TEXT_LINES.add(L"any other online collection in one's code, unless one has money "); + _DOC_TEXT_LINES.add(L"that one don't need and one is happy to donate for lawyers "); + _DOC_TEXT_LINES.add(L"charity. Anyhow at some point, rechecking the usage of this text, "); + _DOC_TEXT_LINES.add(L"it became uncertain that this text is free to use, because "); + _DOC_TEXT_LINES.add(L"the web site in the disclaimer of he eBook containing that text "); + _DOC_TEXT_LINES.add(L"was not responding anymore, and at the same time, in projGut, "); + _DOC_TEXT_LINES.add(L"searching for first aid no longer found that eBook as well. "); + _DOC_TEXT_LINES.add(L"So here we are, with a perhaps much less interesting "); + _DOC_TEXT_LINES.add(L"text for the test, but oh much much safer. "); } + return _DOC_TEXT_LINES; +} - void FunctionFixture::addDoc(const IndexWriterPtr& iw, int32_t i) - { - DocumentPtr d = newLucene(); - int32_t scoreAndID = i + 1; +void FunctionFixture::addDoc(const IndexWriterPtr& iw, int32_t i) { + DocumentPtr d = newLucene(); + int32_t scoreAndID = i + 1; - FieldPtr f = newLucene(ID_FIELD, id2String(scoreAndID), Field::STORE_YES, Field::INDEX_NOT_ANALYZED); // for debug purposes - f->setOmitNorms(true); - d->add(f); + FieldPtr f = newLucene(ID_FIELD, id2String(scoreAndID), Field::STORE_YES, Field::INDEX_NOT_ANALYZED); // for debug purposes + f->setOmitNorms(true); + d->add(f); - f = newLucene(TEXT_FIELD, L"text of doc" + StringUtils::toString(scoreAndID) + textLine(i), Field::STORE_NO, Field::INDEX_ANALYZED); // for regular search - f->setOmitNorms(true); - d->add(f); + f = newLucene(TEXT_FIELD, L"text of doc" + StringUtils::toString(scoreAndID) + textLine(i), Field::STORE_NO, Field::INDEX_ANALYZED); // for regular search + f->setOmitNorms(true); + d->add(f); - f = newLucene(INT_FIELD, StringUtils::toString(scoreAndID), Field::STORE_YES, Field::INDEX_NOT_ANALYZED); // for function scoring - f->setOmitNorms(true); - d->add(f); + f = newLucene(INT_FIELD, StringUtils::toString(scoreAndID), Field::STORE_YES, Field::INDEX_NOT_ANALYZED); // for function scoring + f->setOmitNorms(true); + d->add(f); - f = newLucene(DOUBLE_FIELD, StringUtils::toString(scoreAndID) + L".000", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); // for function scoring - f->setOmitNorms(true); - d->add(f); + f = newLucene(DOUBLE_FIELD, StringUtils::toString(scoreAndID) + L".000", Field::STORE_YES, Field::INDEX_NOT_ANALYZED); // for function scoring + f->setOmitNorms(true); + d->add(f); - iw->addDocument(d); - } + iw->addDocument(d); +} - String FunctionFixture::id2String(int32_t scoreAndID) - { - String s = L"000000000" + StringUtils::toString(scoreAndID); // 17 --> ID00017 - int32_t n = StringUtils::toString(N_DOCS).length() + 3; - int32_t k = s.length() - n; - return L"ID" + s.substr(k); - } +String FunctionFixture::id2String(int32_t scoreAndID) { + String s = L"000000000" + StringUtils::toString(scoreAndID); // 17 --> ID00017 + int32_t n = StringUtils::toString(N_DOCS).length() + 3; + int32_t k = s.length() - n; + return L"ID" + s.substr(k); +} - String FunctionFixture::textLine(int32_t docNum) - { - // some text line for regular search - return DOC_TEXT_LINES()[docNum % DOC_TEXT_LINES().size()]; - } +String FunctionFixture::textLine(int32_t docNum) { + // some text line for regular search + return DOC_TEXT_LINES()[docNum % DOC_TEXT_LINES().size()]; +} - double FunctionFixture::expectedFieldScore(const String& docIDFieldVal) - { - // extract expected doc score from its ID Field: "ID7" --> 7.0 - return StringUtils::toDouble(docIDFieldVal.substr(2)); - } +double FunctionFixture::expectedFieldScore(const String& docIDFieldVal) { + // extract expected doc score from its ID Field: "ID7" --> 7.0 + return StringUtils::toDouble(docIDFieldVal.substr(2)); +} - bool FunctionFixture::equalCollectionValues(CollectionValue first, CollectionValue second) - { - if (!VariantUtils::equalsType(first, second)) - return false; - if (VariantUtils::typeOf< Collection >(first)) - return (VariantUtils::get< Collection >(first).hashCode() == VariantUtils::get< Collection >(second).hashCode()); - if (VariantUtils::typeOf< Collection >(first)) - return (VariantUtils::get< Collection >(first).hashCode() == VariantUtils::get< Collection >(second).hashCode()); - if (VariantUtils::typeOf< Collection >(first)) - return (VariantUtils::get< Collection >(first).hashCode() == VariantUtils::get< Collection >(second).hashCode()); +bool FunctionFixture::equalCollectionValues(CollectionValue first, CollectionValue second) { + if (!VariantUtils::equalsType(first, second)) { return false; } + if (VariantUtils::typeOf< Collection >(first)) { + return (VariantUtils::get< Collection >(first).hashCode() == VariantUtils::get< Collection >(second).hashCode()); + } + if (VariantUtils::typeOf< Collection >(first)) { + return (VariantUtils::get< Collection >(first).hashCode() == VariantUtils::get< Collection >(second).hashCode()); + } + if (VariantUtils::typeOf< Collection >(first)) { + return (VariantUtils::get< Collection >(first).hashCode() == VariantUtils::get< Collection >(second).hashCode()); + } + return false; +} + } diff --git a/src/test/search/function/OrdValuesTest.cpp b/src/test/search/function/OrdValuesTest.cpp index 0c9ed35e..596c0d3b 100644 --- a/src/test/search/function/OrdValuesTest.cpp +++ b/src/test/search/function/OrdValuesTest.cpp @@ -29,100 +29,91 @@ using namespace Lucene; /// The order tests use Hits to verify that docs are ordered as expected. /// /// The exact score tests use TopDocs top to verify the exact score. -class OrdValuesTest : public FunctionFixture -{ +class OrdValuesTest : public FunctionFixture { public: - OrdValuesTest() : FunctionFixture(false) - { + OrdValuesTest() : FunctionFixture(false) { } - virtual ~OrdValuesTest() - { + virtual ~OrdValuesTest() { } public: - void doTestRank(const String& field, bool inOrder) - { + void doTestRank(const String& field, bool inOrder) { IndexSearcherPtr s = newLucene(dir, true); ValueSourcePtr vs; - if (inOrder) + if (inOrder) { vs = newLucene(field); - else + } else { vs = newLucene(field); + } QueryPtr q = newLucene(vs); QueryUtils::check(q, s); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(N_DOCS, h.size()); String prevID = inOrder ? - L"IE" : // greater than all ids of docs in this test ("ID0001", etc.) - L"IC"; // smaller than all ids of docs in this test ("ID0001", etc.) - for (int32_t i = 0; i < h.size(); ++i) - { + L"IE" : // greater than all ids of docs in this test ("ID0001", etc.) + L"IC"; // smaller than all ids of docs in this test ("ID0001", etc.) + for (int32_t i = 0; i < h.size(); ++i) { String resID = s->doc(h[i]->doc)->get(ID_FIELD); - if (inOrder) + if (inOrder) { EXPECT_TRUE(resID.compare(prevID) < 0); - else + } else { EXPECT_TRUE(resID.compare(prevID) > 0); + } prevID = resID; } } - void doTestExactScore(const String& field, bool inOrder) - { + void doTestExactScore(const String& field, bool inOrder) { IndexSearcherPtr s = newLucene(dir, true); ValueSourcePtr vs; - if (inOrder) + if (inOrder) { vs = newLucene(field); - else + } else { vs = newLucene(field); + } QueryPtr q = newLucene(vs); TopDocsPtr td = s->search(q, FilterPtr(),1000); EXPECT_EQ(N_DOCS, td->totalHits); Collection sd = td->scoreDocs; - for (int32_t i = 0; i < sd.size(); ++i) - { + for (int32_t i = 0; i < sd.size(); ++i) { double score = sd[i]->score; String id = s->getIndexReader()->document(sd[i]->doc)->get(ID_FIELD); double expectedScore = N_DOCS - i; EXPECT_NEAR(expectedScore, score, TEST_SCORE_TOLERANCE_DELTA); String expectedId = inOrder ? - id2String(N_DOCS - i) : // in-order ==> larger values first - id2String(i + 1); // reverse ==> smaller values first + id2String(N_DOCS - i) : // in-order ==> larger values first + id2String(i + 1); // reverse ==> smaller values first EXPECT_EQ(expectedId, id); } } - void doTestCaching(const String& field, bool inOrder) - { + void doTestCaching(const String& field, bool inOrder) { IndexSearcherPtr s = newLucene(dir, true); CollectionValue innerArray = VariantUtils::null(); bool warned = false; // print warning once. - for (int32_t i = 0; i < 10; ++i) - { + for (int32_t i = 0; i < 10; ++i) { ValueSourcePtr vs; - if (inOrder) + if (inOrder) { vs = newLucene(field); - else + } else { vs = newLucene(field); + } ValueSourceQueryPtr q = newLucene(vs); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; - try - { + try { EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); - for (int32_t j = 0; j < readers.size(); ++j) - { + for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; - if (i == 0) + if (i == 0) { innerArray = q->valSrc->getValues(reader)->getInnerArray(); - else + } else { EXPECT_TRUE(equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); + } } - } - catch (UnsupportedOperationException&) - { - if (!warned) - { + } catch (UnsupportedOperationException&) { + if (!warned) { // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } @@ -133,25 +124,21 @@ class OrdValuesTest : public FunctionFixture String field2 = INT_FIELD; EXPECT_NE(field, field2); // otherwise this test is meaningless. ValueSourcePtr vs; - if (inOrder) + if (inOrder) { vs = newLucene(field2); - else + } else { vs = newLucene(field2); + } ValueSourceQueryPtr q = newLucene(vs); Collection h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(N_DOCS, h.size()); Collection readers = s->getIndexReader()->getSequentialSubReaders(); - for (int32_t j = 0; j < readers.size(); ++j) - { + for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; - try - { + try { EXPECT_TRUE(!equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); - } - catch (UnsupportedOperationException&) - { - if (!warned) - { + } catch (UnsupportedOperationException&) { + if (!warned) { // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } @@ -160,25 +147,21 @@ class OrdValuesTest : public FunctionFixture // verify new values are reloaded (not reused) for a new reader s = newLucene(dir, true); - if (inOrder) + if (inOrder) { vs = newLucene(field); - else + } else { vs = newLucene(field); + } q = newLucene(vs); h = s->search(q, FilterPtr(), 1000)->scoreDocs; EXPECT_EQ(N_DOCS, h.size()); readers = s->getIndexReader()->getSequentialSubReaders(); - for (int32_t j = 0; j < readers.size(); ++j) - { + for (int32_t j = 0; j < readers.size(); ++j) { IndexReaderPtr reader = readers[j]; - try - { + try { EXPECT_TRUE(!equalCollectionValues(innerArray, q->valSrc->getValues(reader)->getInnerArray())); - } - catch (UnsupportedOperationException&) - { - if (!warned) - { + } catch (UnsupportedOperationException&) { + if (!warned) { // std::cout << "WARNING: Cannot fully test values of " << StringUtils::toUTF8(q->toString()); warned = true; } @@ -187,32 +170,26 @@ class OrdValuesTest : public FunctionFixture } }; -TEST_F(OrdValuesTest, testOrdFieldRank) -{ +TEST_F(OrdValuesTest, testOrdFieldRank) { doTestRank(ID_FIELD, true); } -TEST_F(OrdValuesTest, testReverseOrdFieldRank) -{ +TEST_F(OrdValuesTest, testReverseOrdFieldRank) { doTestRank(ID_FIELD, false); } -TEST_F(OrdValuesTest, testOrdFieldExactScore) -{ +TEST_F(OrdValuesTest, testOrdFieldExactScore) { doTestExactScore(ID_FIELD, true); } -TEST_F(OrdValuesTest, testReverseOrdFieldExactScore) -{ +TEST_F(OrdValuesTest, testReverseOrdFieldExactScore) { doTestExactScore(ID_FIELD, false); } -TEST_F(OrdValuesTest, testCachingOrd) -{ +TEST_F(OrdValuesTest, testCachingOrd) { doTestCaching(ID_FIELD, true); } -TEST_F(OrdValuesTest, testCachingReverseOrd) -{ +TEST_F(OrdValuesTest, testCachingReverseOrd) { doTestCaching(ID_FIELD, false); } diff --git a/src/test/search/payloads/PayloadHelper.cpp b/src/test/search/payloads/PayloadHelper.cpp index a5ee28ab..a87b3ead 100644 --- a/src/test/search/payloads/PayloadHelper.cpp +++ b/src/test/search/payloads/PayloadHelper.cpp @@ -18,129 +18,113 @@ #include "LowerCaseTokenizer.h" #include "Analyzer.h" -namespace Lucene -{ - const String PayloadHelper::NO_PAYLOAD_FIELD = L"noPayloadField"; - const String PayloadHelper::MULTI_FIELD = L"multiField"; - const String PayloadHelper::FIELD = L"field"; - - DECLARE_SHARED_PTR(PayloadHelperAnalyzer) - - class PayloadHelperFilter : public TokenFilter - { - public: - PayloadHelperFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) - { - this->numSeen = 0; - this->fieldName = fieldName; - this->payloadAtt = addAttribute(); - } +namespace Lucene { - virtual ~PayloadHelperFilter() - { - } +const String PayloadHelper::NO_PAYLOAD_FIELD = L"noPayloadField"; +const String PayloadHelper::MULTI_FIELD = L"multiField"; +const String PayloadHelper::FIELD = L"field"; + +DECLARE_SHARED_PTR(PayloadHelperAnalyzer) + +class PayloadHelperFilter : public TokenFilter { +public: + PayloadHelperFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { + this->numSeen = 0; + this->fieldName = fieldName; + this->payloadAtt = addAttribute(); + } + + virtual ~PayloadHelperFilter() { + } - LUCENE_CLASS(PayloadHelperFilter); - - public: - String fieldName; - int32_t numSeen; - PayloadAttributePtr payloadAtt; - - public: - virtual bool incrementToken() - { - if (input->incrementToken()) - { - if (fieldName == PayloadHelper::FIELD) - payloadAtt->setPayload(newLucene(PayloadHelper::payloadField())); - else if (fieldName == PayloadHelper::MULTI_FIELD) - { - if (numSeen % 2 == 0) - payloadAtt->setPayload(newLucene(PayloadHelper::payloadMultiField1())); - else - payloadAtt->setPayload(newLucene(PayloadHelper::payloadMultiField2())); - ++numSeen; + LUCENE_CLASS(PayloadHelperFilter); + +public: + String fieldName; + int32_t numSeen; + PayloadAttributePtr payloadAtt; + +public: + virtual bool incrementToken() { + if (input->incrementToken()) { + if (fieldName == PayloadHelper::FIELD) { + payloadAtt->setPayload(newLucene(PayloadHelper::payloadField())); + } else if (fieldName == PayloadHelper::MULTI_FIELD) { + if (numSeen % 2 == 0) { + payloadAtt->setPayload(newLucene(PayloadHelper::payloadMultiField1())); + } else { + payloadAtt->setPayload(newLucene(PayloadHelper::payloadMultiField2())); } - return true; + ++numSeen; } - return false; + return true; } - }; + return false; + } +}; - class PayloadHelperAnalyzer : public Analyzer - { - public: - virtual ~PayloadHelperAnalyzer() - { - } +class PayloadHelperAnalyzer : public Analyzer { +public: + virtual ~PayloadHelperAnalyzer() { + } - LUCENE_CLASS(PayloadHelperAnalyzer); + LUCENE_CLASS(PayloadHelperAnalyzer); - public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { - TokenStreamPtr result = newLucene(reader); - result = newLucene(result, fieldName); - return result; - } - }; +public: + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { + TokenStreamPtr result = newLucene(reader); + result = newLucene(result, fieldName); + return result; + } +}; - PayloadHelper::~PayloadHelper() - { +PayloadHelper::~PayloadHelper() { +} + +const ByteArray PayloadHelper::payloadField() { + static ByteArray _payloadField; + if (!_payloadField) { + _payloadField = ByteArray::newInstance(1); + _payloadField[0] = 1; } + return _payloadField; +} - const ByteArray PayloadHelper::payloadField() - { - static ByteArray _payloadField; - if (!_payloadField) - { - _payloadField = ByteArray::newInstance(1); - _payloadField[0] = 1; - } - return _payloadField; +const ByteArray PayloadHelper::payloadMultiField1() { + static ByteArray _payloadMultiField1; + if (!_payloadMultiField1) { + _payloadMultiField1 = ByteArray::newInstance(1); + _payloadMultiField1[0] = 2; } + return _payloadMultiField1; +} - const ByteArray PayloadHelper::payloadMultiField1() - { - static ByteArray _payloadMultiField1; - if (!_payloadMultiField1) - { - _payloadMultiField1 = ByteArray::newInstance(1); - _payloadMultiField1[0] = 2; - } - return _payloadMultiField1; +const ByteArray PayloadHelper::payloadMultiField2() { + static ByteArray _payloadMultiField2; + if (!_payloadMultiField2) { + _payloadMultiField2 = ByteArray::newInstance(1); + _payloadMultiField2[0] = 4; } + return _payloadMultiField2; +} - const ByteArray PayloadHelper::payloadMultiField2() - { - static ByteArray _payloadMultiField2; - if (!_payloadMultiField2) - { - _payloadMultiField2 = ByteArray::newInstance(1); - _payloadMultiField2[0] = 4; - } - return _payloadMultiField2; +IndexSearcherPtr PayloadHelper::setUp(const SimilarityPtr& similarity, int32_t numDocs) { + RAMDirectoryPtr directory = newLucene(); + PayloadHelperAnalyzerPtr analyzer = newLucene(); + IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); + writer->setSimilarity(similarity); + for (int32_t i = 0; i < numDocs; ++i) { + DocumentPtr doc = newLucene(); + doc->add(newLucene(FIELD, intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); + doc->add(newLucene(MULTI_FIELD, intToEnglish(i) + L" " + intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); + doc->add(newLucene(NO_PAYLOAD_FIELD, intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); + writer->addDocument(doc); } + writer->close(); - IndexSearcherPtr PayloadHelper::setUp(const SimilarityPtr& similarity, int32_t numDocs) - { - RAMDirectoryPtr directory = newLucene(); - PayloadHelperAnalyzerPtr analyzer = newLucene(); - IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); - writer->setSimilarity(similarity); - for (int32_t i = 0; i < numDocs; ++i) - { - DocumentPtr doc = newLucene(); - doc->add(newLucene(FIELD, intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); - doc->add(newLucene(MULTI_FIELD, intToEnglish(i) + L" " + intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); - doc->add(newLucene(NO_PAYLOAD_FIELD, intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); - writer->addDocument(doc); - } - writer->close(); + IndexSearcherPtr searcher = newLucene(directory, true); + searcher->setSimilarity(similarity); + return searcher; +} - IndexSearcherPtr searcher = newLucene(directory, true); - searcher->setSimilarity(similarity); - return searcher; - } } diff --git a/src/test/search/payloads/PayloadNearQueryTest.cpp b/src/test/search/payloads/PayloadNearQueryTest.cpp index 117c6bb2..89d800a6 100644 --- a/src/test/search/payloads/PayloadNearQueryTest.cpp +++ b/src/test/search/payloads/PayloadNearQueryTest.cpp @@ -33,75 +33,60 @@ using namespace Lucene; DECLARE_SHARED_PTR(BoostingNearSimilarity) DECLARE_SHARED_PTR(PayloadNearAnalyzer) -class BoostingNearIDFExplanation : public IDFExplanation -{ +class BoostingNearIDFExplanation : public IDFExplanation { public: - virtual ~BoostingNearIDFExplanation() - { + virtual ~BoostingNearIDFExplanation() { } public: - virtual double getIdf() - { + virtual double getIdf() { return 1.0; } - virtual String explain() - { + virtual String explain() { return L"Inexplicable"; } }; -class BoostingNearSimilarity : public DefaultSimilarity -{ +class BoostingNearSimilarity : public DefaultSimilarity { public: - virtual ~BoostingNearSimilarity() - { + virtual ~BoostingNearSimilarity() { } public: - virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) - { + virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) { // we know it is size 4 here, so ignore the offset/length return (double)payload[0]; } - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - virtual double queryNorm(double sumOfSquaredWeights) - { + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - virtual double sloppyFreq(int32_t distance) - { + virtual double sloppyFreq(int32_t distance) { return 1.0; } - virtual double coord(int32_t overlap, int32_t maxOverlap) - { + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - virtual double tf(double freq) - { + virtual double tf(double freq) { return 1.0; } - virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) - { + virtual IDFExplanationPtr idfExplain(Collection terms, const SearcherPtr& searcher) { return newLucene(); } }; -class PayloadNearFilter : public TokenFilter -{ +class PayloadNearFilter : public TokenFilter { public: - PayloadNearFilter(ByteArray payload2, ByteArray payload4, const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) - { + PayloadNearFilter(ByteArray payload2, ByteArray payload4, const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->payload2 = payload2; this->payload4 = payload4; this->numSeen = 0; @@ -109,8 +94,7 @@ class PayloadNearFilter : public TokenFilter this->payAtt = addAttribute(); } - virtual ~PayloadNearFilter() - { + virtual ~PayloadNearFilter() { } LUCENE_CLASS(PayloadNearFilter); @@ -123,15 +107,14 @@ class PayloadNearFilter : public TokenFilter PayloadAttributePtr payAtt; public: - virtual bool incrementToken() - { + virtual bool incrementToken() { bool result = false; - if (input->incrementToken()) - { - if (numSeen % 2 == 0) + if (input->incrementToken()) { + if (numSeen % 2 == 0) { payAtt->setPayload(newLucene(payload2)); - else + } else { payAtt->setPayload(newLucene(payload4)); + } ++numSeen; result = true; } @@ -139,17 +122,14 @@ class PayloadNearFilter : public TokenFilter } }; -class PayloadNearAnalyzer : public Analyzer -{ +class PayloadNearAnalyzer : public Analyzer { public: - PayloadNearAnalyzer(ByteArray payload2, ByteArray payload4) - { + PayloadNearAnalyzer(ByteArray payload2, ByteArray payload4) { this->payload2 = payload2; this->payload4 = payload4; } - virtual ~PayloadNearAnalyzer() - { + virtual ~PayloadNearAnalyzer() { } LUCENE_CLASS(PayloadNearAnalyzer); @@ -159,19 +139,16 @@ class PayloadNearAnalyzer : public Analyzer ByteArray payload4; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(payload2, payload4, result, fieldName); return result; } }; -class PayloadNearQueryTest : public LuceneTestFixture -{ +class PayloadNearQueryTest : public LuceneTestFixture { public: - PayloadNearQueryTest() - { + PayloadNearQueryTest() { similarity = newLucene(); payload2 = ByteArray::newInstance(1); payload2[0] = 2; @@ -182,8 +159,7 @@ class PayloadNearQueryTest : public LuceneTestFixture PayloadNearAnalyzerPtr analyzer = newLucene(payload2, payload4); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); writer->setSimilarity(similarity); - for (int32_t i = 0; i < 1000; ++i) - { + for (int32_t i = 0; i < 1000; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); String txt = intToEnglish(i) + L" " + intToEnglish(i + 1); @@ -197,8 +173,7 @@ class PayloadNearQueryTest : public LuceneTestFixture searcher->setSimilarity(similarity); } - virtual ~PayloadNearQueryTest() - { + virtual ~PayloadNearQueryTest() { } protected: @@ -208,28 +183,24 @@ class PayloadNearQueryTest : public LuceneTestFixture ByteArray payload4; public: - PayloadNearQueryPtr newPhraseQuery(const String& fieldName, const String& phrase, bool inOrder) - { + PayloadNearQueryPtr newPhraseQuery(const String& fieldName, const String& phrase, bool inOrder) { std::wstring phraseClauses(phrase.c_str()); Collection clauses = Collection::newInstance(); boost::wsregex_token_iterator tokenIterator(phraseClauses.begin(), phraseClauses.end(), boost::wregex(L"[\\s]+"), -1); boost::wsregex_token_iterator endToken; - while (tokenIterator != endToken) - { + while (tokenIterator != endToken) { clauses.add(newLucene(newLucene(fieldName, *tokenIterator), newLucene())); ++tokenIterator; } return newLucene(clauses, 0, inOrder); } - SpanNearQueryPtr spanNearQuery(const String& fieldName, const String& words) - { + SpanNearQueryPtr spanNearQuery(const String& fieldName, const String& words) { std::wstring phraseClauses(words.c_str()); Collection clauses = Collection::newInstance(); boost::wsregex_token_iterator tokenIterator(phraseClauses.begin(), phraseClauses.end(), boost::wregex(L"[\\s]+"), -1); boost::wsregex_token_iterator endToken; - while (tokenIterator != endToken) - { + while (tokenIterator != endToken) { clauses.add(newLucene(newLucene(fieldName, *tokenIterator), newLucene())); ++tokenIterator; } @@ -237,8 +208,7 @@ class PayloadNearQueryTest : public LuceneTestFixture } }; -TEST_F(PayloadNearQueryTest, testSetup) -{ +TEST_F(PayloadNearQueryTest, testSetup) { PayloadNearQueryPtr query = newPhraseQuery(L"field", L"twenty two", true); QueryUtils::check(query); @@ -246,28 +216,24 @@ TEST_F(PayloadNearQueryTest, testSetup) TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); EXPECT_TRUE(hits); EXPECT_EQ(hits->totalHits, 10); - for (int32_t j = 0; j < hits->scoreDocs.size(); ++j) - { + for (int32_t j = 0; j < hits->scoreDocs.size(); ++j) { ScoreDocPtr doc = hits->scoreDocs[j]; EXPECT_EQ(doc->score, 3); } - for (int32_t i = 1; i < 10; ++i) - { + for (int32_t i = 1; i < 10; ++i) { query = newPhraseQuery(L"field", intToEnglish(i) + L" hundred", true); // all should have score = 3 because adjacent terms have payloads of 2, 4 and all the similarity factors are set to 1 hits = searcher->search(query, FilterPtr(), 100); EXPECT_TRUE(hits); EXPECT_EQ(hits->totalHits, 100); - for (int32_t j = 0; j < hits->scoreDocs.size(); ++j) - { + for (int32_t j = 0; j < hits->scoreDocs.size(); ++j) { ScoreDocPtr doc = hits->scoreDocs[j]; EXPECT_EQ(doc->score, 3); } } } -TEST_F(PayloadNearQueryTest, testPayloadNear) -{ +TEST_F(PayloadNearQueryTest, testPayloadNear) { SpanNearQueryPtr q1 = spanNearQuery(L"field2", L"twenty two"); SpanNearQueryPtr q2 = spanNearQuery(L"field2", L"twenty three"); Collection clauses = newCollection(q1, q2); @@ -275,8 +241,7 @@ TEST_F(PayloadNearQueryTest, testPayloadNear) EXPECT_EQ(12, searcher->search(query, FilterPtr(), 100)->totalHits); } -TEST_F(PayloadNearQueryTest, testLongerSpan) -{ +TEST_F(PayloadNearQueryTest, testLongerSpan) { SpanNearQueryPtr query = newPhraseQuery(L"field", L"nine hundred ninety nine", true); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); EXPECT_TRUE(hits); @@ -286,17 +251,16 @@ TEST_F(PayloadNearQueryTest, testLongerSpan) EXPECT_EQ(doc->score, 3); } -TEST_F(PayloadNearQueryTest, testComplexNested) -{ +TEST_F(PayloadNearQueryTest, testComplexNested) { // combine ordered and unordered spans with some nesting to make sure all payloads are counted SpanQueryPtr q1 = newPhraseQuery(L"field", L"nine hundred", true); SpanQueryPtr q2 = newPhraseQuery(L"field", L"ninety nine", true); SpanQueryPtr q3 = newPhraseQuery(L"field", L"nine ninety", false); SpanQueryPtr q4 = newPhraseQuery(L"field", L"hundred nine", false); Collection clauses = newCollection( - newLucene(newCollection(q1, q2), 0, true), - newLucene(newCollection(q3, q4), 0, false) - ); + newLucene(newCollection(q1, q2), 0, true), + newLucene(newCollection(q3, q4), 0, false) + ); PayloadNearQueryPtr query = newLucene(clauses, 0, false); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); EXPECT_TRUE(hits); diff --git a/src/test/search/payloads/PayloadTermQueryTest.cpp b/src/test/search/payloads/PayloadTermQueryTest.cpp index 3af8cc92..c60af9f0 100644 --- a/src/test/search/payloads/PayloadTermQueryTest.cpp +++ b/src/test/search/payloads/PayloadTermQueryTest.cpp @@ -38,71 +38,57 @@ using namespace Lucene; DECLARE_SHARED_PTR(BoostingTermSimilarity) DECLARE_SHARED_PTR(PayloadTermAnalyzer) -class BoostingTermSimilarity : public DefaultSimilarity -{ +class BoostingTermSimilarity : public DefaultSimilarity { public: - virtual ~BoostingTermSimilarity() - { + virtual ~BoostingTermSimilarity() { } public: - virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) - { + virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) { // we know it is size 4 here, so ignore the offset/length return (double)payload[0]; } - virtual double lengthNorm(const String& fieldName, int32_t numTokens) - { + virtual double lengthNorm(const String& fieldName, int32_t numTokens) { return 1.0; } - virtual double queryNorm(double sumOfSquaredWeights) - { + virtual double queryNorm(double sumOfSquaredWeights) { return 1.0; } - virtual double sloppyFreq(int32_t distance) - { + virtual double sloppyFreq(int32_t distance) { return 1.0; } - virtual double coord(int32_t overlap, int32_t maxOverlap) - { + virtual double coord(int32_t overlap, int32_t maxOverlap) { return 1.0; } - virtual double idf(int32_t docFreq, int32_t numDocs) - { + virtual double idf(int32_t docFreq, int32_t numDocs) { return 1.0; } - virtual double tf(double freq) - { + virtual double tf(double freq) { return freq == 0.0 ? 0.0 : 1.0; } }; -class FullSimilarity : public DefaultSimilarity -{ +class FullSimilarity : public DefaultSimilarity { public: - virtual ~FullSimilarity() - { + virtual ~FullSimilarity() { } public: - virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) - { + virtual double scorePayload(int32_t docId, const String& fieldName, int32_t start, int32_t end, ByteArray payload, int32_t offset, int32_t length) { // we know it is size 4 here, so ignore the offset/length return payload[0]; } }; -class PayloadTermFilter : public TokenFilter -{ +class PayloadTermFilter : public TokenFilter { public: - PayloadTermFilter(ByteArray payloadField, ByteArray payloadMultiField1, ByteArray payloadMultiField2, const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) - { + PayloadTermFilter(ByteArray payloadField, ByteArray payloadMultiField1, ByteArray payloadMultiField2, const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->payloadField = payloadField; this->payloadMultiField1 = payloadMultiField1; this->payloadMultiField2 = payloadMultiField2; @@ -111,8 +97,7 @@ class PayloadTermFilter : public TokenFilter this->payloadAtt = addAttribute(); } - virtual ~PayloadTermFilter() - { + virtual ~PayloadTermFilter() { } LUCENE_CLASS(PayloadTermFilter); @@ -126,40 +111,35 @@ class PayloadTermFilter : public TokenFilter PayloadAttributePtr payloadAtt; public: - virtual bool incrementToken() - { + virtual bool incrementToken() { bool hasNext = input->incrementToken(); - if (hasNext) - { - if (fieldName == L"field") + if (hasNext) { + if (fieldName == L"field") { payloadAtt->setPayload(newLucene(payloadField)); - else if (fieldName == L"multiField") - { - if (numSeen % 2 == 0) + } else if (fieldName == L"multiField") { + if (numSeen % 2 == 0) { payloadAtt->setPayload(newLucene(payloadMultiField1)); - else + } else { payloadAtt->setPayload(newLucene(payloadMultiField2)); + } ++numSeen; } return true; - } - else + } else { return false; + } } }; -class PayloadTermAnalyzer : public Analyzer -{ +class PayloadTermAnalyzer : public Analyzer { public: - PayloadTermAnalyzer(ByteArray payloadField, ByteArray payloadMultiField1, ByteArray payloadMultiField2) - { + PayloadTermAnalyzer(ByteArray payloadField, ByteArray payloadMultiField1, ByteArray payloadMultiField2) { this->payloadField = payloadField; this->payloadMultiField1 = payloadMultiField1; this->payloadMultiField2 = payloadMultiField2; } - virtual ~PayloadTermAnalyzer() - { + virtual ~PayloadTermAnalyzer() { } LUCENE_CLASS(PayloadTermAnalyzer); @@ -170,19 +150,16 @@ class PayloadTermAnalyzer : public Analyzer ByteArray payloadMultiField2; public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(payloadField, payloadMultiField1, payloadMultiField2, result, fieldName); return result; } }; -class PayloadTermQueryTest : public LuceneTestFixture -{ +class PayloadTermQueryTest : public LuceneTestFixture { public: - PayloadTermQueryTest() - { + PayloadTermQueryTest() { similarity = newLucene(); payloadField = ByteArray::newInstance(1); payloadField[0] = 1; @@ -195,8 +172,7 @@ class PayloadTermQueryTest : public LuceneTestFixture PayloadTermAnalyzerPtr analyzer = newLucene(payloadField, payloadMultiField1, payloadMultiField2); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); writer->setSimilarity(similarity); - for (int32_t i = 0; i < 1000; ++i) - { + for (int32_t i = 0; i < 1000; ++i) { DocumentPtr doc = newLucene(); FieldPtr noPayloadField = newLucene(PayloadHelper::NO_PAYLOAD_FIELD, intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED); doc->add(noPayloadField); @@ -211,8 +187,7 @@ class PayloadTermQueryTest : public LuceneTestFixture searcher->setSimilarity(similarity); } - virtual ~PayloadTermQueryTest() - { + virtual ~PayloadTermQueryTest() { } protected: @@ -224,8 +199,7 @@ class PayloadTermQueryTest : public LuceneTestFixture RAMDirectoryPtr directory; }; -TEST_F(PayloadTermQueryTest, testSetup) -{ +TEST_F(PayloadTermQueryTest, testSetup) { PayloadTermQueryPtr query = newLucene(newLucene(L"field", L"seventy"), newLucene()); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); EXPECT_TRUE(hits); @@ -233,8 +207,7 @@ TEST_F(PayloadTermQueryTest, testSetup) // they should all have the exact same score, because they all contain seventy once, and we set all the other similarity factors to be 1 EXPECT_EQ(hits->getMaxScore(), 1); - for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) - { + for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) { ScoreDocPtr doc = hits->scoreDocs[i]; EXPECT_EQ(doc->score, 1); } @@ -244,8 +217,7 @@ TEST_F(PayloadTermQueryTest, testSetup) EXPECT_TRUE(MiscUtils::typeOf(spans)); } -TEST_F(PayloadTermQueryTest, testQuery) -{ +TEST_F(PayloadTermQueryTest, testQuery) { PayloadTermQueryPtr BoostingTermFuncTermQuery = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy"), newLucene()); QueryUtils::check(BoostingTermFuncTermQuery); @@ -257,8 +229,7 @@ TEST_F(PayloadTermQueryTest, testQuery) QueryUtils::checkUnequal(BoostingTermFuncTermQuery, BoostingTermFuncTermQuery2); } -TEST_F(PayloadTermQueryTest, testMultipleMatchesPerDoc) -{ +TEST_F(PayloadTermQueryTest, testMultipleMatchesPerDoc) { PayloadTermQueryPtr query = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy"), newLucene()); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); EXPECT_TRUE(hits); @@ -270,16 +241,14 @@ TEST_F(PayloadTermQueryTest, testMultipleMatchesPerDoc) // there should be exactly 10 items that score a 4, all the rest should score a 2 // The 10 items are: 70 + i*100 where i in [0-9] int32_t numTens = 0; - for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) - { + for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) { ScoreDocPtr doc = hits->scoreDocs[i]; - if (doc->doc % 10 == 0) - { + if (doc->doc % 10 == 0) { ++numTens; EXPECT_EQ(doc->score, 4.0); - } - else + } else { EXPECT_EQ(doc->score, 2.0); + } } EXPECT_EQ(numTens, 10); CheckHits::checkExplanations(query, L"field", searcher, true); @@ -289,13 +258,13 @@ TEST_F(PayloadTermQueryTest, testMultipleMatchesPerDoc) // should be two matches per document int32_t count = 0; // 100 hits times 2 matches per hit, we should have 200 in count - while (spans->next()) + while (spans->next()) { ++count; + } EXPECT_EQ(count, 200); } -TEST_F(PayloadTermQueryTest, testIgnoreSpanScorer) -{ +TEST_F(PayloadTermQueryTest, testIgnoreSpanScorer) { PayloadTermQueryPtr query = newLucene(newLucene(PayloadHelper::MULTI_FIELD, L"seventy"), newLucene(), false); IndexSearcherPtr theSearcher = newLucene(directory, true); @@ -310,16 +279,14 @@ TEST_F(PayloadTermQueryTest, testIgnoreSpanScorer) // there should be exactly 10 items that score a 4, all the rest should score a 2 // The 10 items are: 70 + i*100 where i in [0-9] int32_t numTens = 0; - for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) - { + for (int32_t i = 0; i < hits->scoreDocs.size(); ++i) { ScoreDocPtr doc = hits->scoreDocs[i]; - if (doc->doc % 10 == 0) - { + if (doc->doc % 10 == 0) { ++numTens; EXPECT_EQ(doc->score, 4.0); - } - else + } else { EXPECT_EQ(doc->score, 2.0); + } } EXPECT_EQ(numTens, 10); CheckHits::checkExplanations(query, L"field", searcher, true); @@ -329,21 +296,20 @@ TEST_F(PayloadTermQueryTest, testIgnoreSpanScorer) // should be two matches per document int32_t count = 0; // 100 hits times 2 matches per hit, we should have 200 in count - while (spans->next()) + while (spans->next()) { ++count; + } EXPECT_EQ(count, 200); } -TEST_F(PayloadTermQueryTest, testNoMatch) -{ +TEST_F(PayloadTermQueryTest, testNoMatch) { PayloadTermQueryPtr query = newLucene(newLucene(PayloadHelper::FIELD, L"junk"), newLucene()); TopDocsPtr hits = searcher->search(query, FilterPtr(), 100); EXPECT_TRUE(hits); EXPECT_EQ(hits->totalHits, 0); } -TEST_F(PayloadTermQueryTest, testNoPayload) -{ +TEST_F(PayloadTermQueryTest, testNoPayload) { PayloadTermQueryPtr q1 = newLucene(newLucene(PayloadHelper::NO_PAYLOAD_FIELD, L"zero"), newLucene()); PayloadTermQueryPtr q2 = newLucene(newLucene(PayloadHelper::NO_PAYLOAD_FIELD, L"foo"), newLucene()); BooleanClausePtr c1 = newLucene(q1, BooleanClause::MUST); diff --git a/src/test/search/spans/BasicSpansTest.cpp b/src/test/search/spans/BasicSpansTest.cpp index e005f750..5a9983e3 100644 --- a/src/test/search/spans/BasicSpansTest.cpp +++ b/src/test/search/spans/BasicSpansTest.cpp @@ -36,15 +36,12 @@ using namespace Lucene; /// Tests are each a single query, and its hits are checked to ensure that all and only the /// correct documents are returned, thus providing end-to-end testing of the indexing and /// search code. -class BasicSpansTest : public LuceneTestFixture -{ +class BasicSpansTest : public LuceneTestFixture { public: - BasicSpansTest() - { + BasicSpansTest() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < 1000; ++i) - { + for (int32_t i = 0; i < 1000; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"field", intToEnglish(i), Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -54,37 +51,31 @@ class BasicSpansTest : public LuceneTestFixture searcher = newLucene(directory, true); } - virtual ~BasicSpansTest() - { + virtual ~BasicSpansTest() { } protected: IndexSearcherPtr searcher; public: - void checkHits(const QueryPtr& query, Collection results) - { + void checkHits(const QueryPtr& query, Collection results) { CheckHits::checkHits(query, L"field", searcher, results); } - bool skipTo(const SpansPtr& s, int32_t target) - { - do - { - if (!s->next()) + bool skipTo(const SpansPtr& s, int32_t target) { + do { + if (!s->next()) { return false; - } - while (target > s->doc()); + } + } while (target > s->doc()); return true; } }; -TEST_F(BasicSpansTest, testTerm) -{ +TEST_F(BasicSpansTest, testTerm) { QueryPtr query = newLucene(newLucene(L"field", L"seventy")); - static const int32_t results[] = - { + static const int32_t results[] = { 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 470, 471, 472, 473, @@ -96,14 +87,12 @@ TEST_F(BasicSpansTest, testTerm) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testTerm2) -{ +TEST_F(BasicSpansTest, testTerm2) { QueryPtr query = newLucene(newLucene(L"field", L"seventish")); checkHits(query, Collection::newInstance()); } -TEST_F(BasicSpansTest, testPhrase) -{ +TEST_F(BasicSpansTest, testPhrase) { PhraseQueryPtr query = newLucene(); query->add(newLucene(L"field", L"seventy")); query->add(newLucene(L"field", L"seven")); @@ -112,37 +101,32 @@ TEST_F(BasicSpansTest, testPhrase) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testPhrase2) -{ +TEST_F(BasicSpansTest, testPhrase2) { PhraseQueryPtr query = newLucene(); query->add(newLucene(L"field", L"seventish")); query->add(newLucene(L"field", L"sevenon")); checkHits(query, Collection::newInstance()); } -TEST_F(BasicSpansTest, testBoolean) -{ +TEST_F(BasicSpansTest, testBoolean) { BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(L"field", L"seventy")), BooleanClause::MUST); query->add(newLucene(newLucene(L"field", L"seven")), BooleanClause::MUST); - static const int32_t results[] = - { + static const int32_t results[] = { 77, 777, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775, 776, 778, 779, 877, 977 }; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testBoolean2) -{ +TEST_F(BasicSpansTest, testBoolean2) { BooleanQueryPtr query = newLucene(); query->add(newLucene(newLucene(L"field", L"sevento")), BooleanClause::MUST); query->add(newLucene(newLucene(L"field", L"sevenly")), BooleanClause::MUST); checkHits(query, Collection::newInstance()); } -TEST_F(BasicSpansTest, testSpanNearExact) -{ +TEST_F(BasicSpansTest, testSpanNearExact) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"seventy")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"seven")); SpanNearQueryPtr query = newLucene(newCollection(term1, term2), 0, true); @@ -158,8 +142,7 @@ TEST_F(BasicSpansTest, testSpanNearExact) QueryUtils::checkUnequal(term1, term2); } -TEST_F(BasicSpansTest, testSpanNearUnordered) -{ +TEST_F(BasicSpansTest, testSpanNearUnordered) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"nine")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"six")); SpanNearQueryPtr query = newLucene(newCollection(term1, term2), 4, false); @@ -168,8 +151,7 @@ TEST_F(BasicSpansTest, testSpanNearUnordered) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testSpanNearOrdered) -{ +TEST_F(BasicSpansTest, testSpanNearOrdered) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"nine")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"six")); SpanNearQueryPtr query = newLucene(newCollection(term1, term2), 4, true); @@ -178,8 +160,7 @@ TEST_F(BasicSpansTest, testSpanNearOrdered) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testSpanNot) -{ +TEST_F(BasicSpansTest, testSpanNot) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 4, true); @@ -194,8 +175,7 @@ TEST_F(BasicSpansTest, testSpanNot) EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -TEST_F(BasicSpansTest, testSpanWithMultipleNotSingle) -{ +TEST_F(BasicSpansTest, testSpanWithMultipleNotSingle) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 4, true); @@ -212,8 +192,7 @@ TEST_F(BasicSpansTest, testSpanWithMultipleNotSingle) EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -TEST_F(BasicSpansTest, testSpanWithMultipleNotMany) -{ +TEST_F(BasicSpansTest, testSpanWithMultipleNotMany) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 4, true); @@ -232,8 +211,7 @@ TEST_F(BasicSpansTest, testSpanWithMultipleNotMany) EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -TEST_F(BasicSpansTest, testNpeInSpanNearWithSpanNot) -{ +TEST_F(BasicSpansTest, testNpeInSpanNearWithSpanNot) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"eight")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"one")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 4, true); @@ -250,8 +228,7 @@ TEST_F(BasicSpansTest, testNpeInSpanNearWithSpanNot) EXPECT_TRUE(searcher->explain(query, 891)->getValue() > 0.0); } -TEST_F(BasicSpansTest, testNpeInSpanNearInSpanFirstInSpanNot) -{ +TEST_F(BasicSpansTest, testNpeInSpanNearInSpanFirstInSpanNot) { int32_t n = 5; SpanTermQueryPtr hun = newLucene(newLucene(L"field", L"hundred")); SpanTermQueryPtr term40 = newLucene(newLucene(L"field", L"forty")); @@ -266,13 +243,11 @@ TEST_F(BasicSpansTest, testNpeInSpanNearInSpanFirstInSpanNot) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testSpanFirst) -{ +TEST_F(BasicSpansTest, testSpanFirst) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"five")); SpanFirstQueryPtr query = newLucene(term1, 1); - static const int32_t results[] = - { + static const int32_t results[] = { 5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, @@ -288,8 +263,7 @@ TEST_F(BasicSpansTest, testSpanFirst) EXPECT_TRUE(searcher->explain(query, 599)->getValue() > 0.0); } -TEST_F(BasicSpansTest, testSpanOr) -{ +TEST_F(BasicSpansTest, testSpanOr) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"thirty")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"three")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 0, true); @@ -299,8 +273,7 @@ TEST_F(BasicSpansTest, testSpanOr) SpanOrQueryPtr query = newLucene(newCollection(near1, near2)); - static const int32_t results[] = - { + static const int32_t results[] = { 33, 47, 133, 147, 233, 247, 333, 347, 433, 447, 533, 547, 633, 647, 733, 747, 833, 847, 933, 947 }; checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); @@ -309,8 +282,7 @@ TEST_F(BasicSpansTest, testSpanOr) EXPECT_TRUE(searcher->explain(query, 947)->getValue() > 0.0); } -TEST_F(BasicSpansTest, testSpanExactNested) -{ +TEST_F(BasicSpansTest, testSpanExactNested) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"three")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"hundred")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 0, true); @@ -326,8 +298,7 @@ TEST_F(BasicSpansTest, testSpanExactNested) EXPECT_TRUE(searcher->explain(query, 333)->getValue() > 0.0); } -TEST_F(BasicSpansTest, testSpanNearOr) -{ +TEST_F(BasicSpansTest, testSpanNearOr) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"six")); SpanTermQueryPtr term3 = newLucene(newLucene(L"field", L"seven")); @@ -339,8 +310,7 @@ TEST_F(BasicSpansTest, testSpanNearOr) SpanNearQueryPtr query = newLucene(newCollection(to1, to2), 10, true); - static const int32_t results[] = - { + static const int32_t results[] = { 606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677, 686, 687, 696, 697, 706, 707, 726, 727, 736, 737, 746, 747, 756, @@ -349,8 +319,7 @@ TEST_F(BasicSpansTest, testSpanNearOr) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testSpanComplex1) -{ +TEST_F(BasicSpansTest, testSpanComplex1) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"six")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"hundred")); SpanNearQueryPtr near1 = newLucene(newCollection(term1, term2), 0, true); @@ -367,8 +336,7 @@ TEST_F(BasicSpansTest, testSpanComplex1) SpanNearQueryPtr query = newLucene(newCollection(to1, to2), 100, true); - static const int32_t results[] = - { + static const int32_t results[] = { 606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677, 686, 687, 696, 697, 706, 707, 726, 727, 736, 737, 746, 747, 756, @@ -377,8 +345,7 @@ TEST_F(BasicSpansTest, testSpanComplex1) checkHits(query, Collection::newInstance(results, results + SIZEOF_ARRAY(results))); } -TEST_F(BasicSpansTest, testSpansSkipTo) -{ +TEST_F(BasicSpansTest, testSpansSkipTo) { SpanTermQueryPtr term1 = newLucene(newLucene(L"field", L"seventy")); SpanTermQueryPtr term2 = newLucene(newLucene(L"field", L"seventy")); SpansPtr spans1 = term1->getSpans(searcher->getIndexReader()); @@ -388,11 +355,9 @@ TEST_F(BasicSpansTest, testSpansSkipTo) EXPECT_TRUE(spans2->next()); bool hasMore = true; - do - { + do { hasMore = skipTo(spans1, spans2->doc()); EXPECT_EQ(hasMore, spans2->skipTo(spans2->doc())); EXPECT_EQ(spans1->doc(), spans2->doc()); - } - while (hasMore); + } while (hasMore); } diff --git a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp index 1bc9c542..59daa629 100644 --- a/src/test/search/spans/FieldMaskingSpanQueryTest.cpp +++ b/src/test/search/spans/FieldMaskingSpanQueryTest.cpp @@ -23,73 +23,70 @@ using namespace Lucene; -class FieldMaskingSpanQueryTest : public LuceneTestFixture -{ +class FieldMaskingSpanQueryTest : public LuceneTestFixture { public: - FieldMaskingSpanQueryTest() - { + FieldMaskingSpanQueryTest() { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->addDocument(doc(newCollection( - field(L"id", L"0"), - field(L"gender", L"male"), - field(L"first", L"james"), - field(L"last", L"jones"))) - ); + field(L"id", L"0"), + field(L"gender", L"male"), + field(L"first", L"james"), + field(L"last", L"jones"))) + ); writer->addDocument(doc(newCollection( - field(L"id", L"1"), - field(L"gender", L"male"), - field(L"first", L"james"), - field(L"last", L"smith"), - field(L"gender", L"female"), - field(L"first", L"sally"), - field(L"last", L"jones"))) - ); + field(L"id", L"1"), + field(L"gender", L"male"), + field(L"first", L"james"), + field(L"last", L"smith"), + field(L"gender", L"female"), + field(L"first", L"sally"), + field(L"last", L"jones"))) + ); writer->addDocument(doc(newCollection( - field(L"id", L"2"), - field(L"gender", L"female"), - field(L"first", L"greta"), - field(L"last", L"jones"), - field(L"gender", L"female"), - field(L"first", L"sally"), - field(L"last", L"smith"), - field(L"gender", L"male"), - field(L"first", L"james"), - field(L"last", L"jones"))) - ); + field(L"id", L"2"), + field(L"gender", L"female"), + field(L"first", L"greta"), + field(L"last", L"jones"), + field(L"gender", L"female"), + field(L"first", L"sally"), + field(L"last", L"smith"), + field(L"gender", L"male"), + field(L"first", L"james"), + field(L"last", L"jones"))) + ); writer->addDocument(doc(newCollection( - field(L"id", L"3"), - field(L"gender", L"female"), - field(L"first", L"lisa"), - field(L"last", L"jones"), - field(L"gender", L"male"), - field(L"first", L"bob"), - field(L"last", L"costas"))) - ); + field(L"id", L"3"), + field(L"gender", L"female"), + field(L"first", L"lisa"), + field(L"last", L"jones"), + field(L"gender", L"male"), + field(L"first", L"bob"), + field(L"last", L"costas"))) + ); writer->addDocument(doc(newCollection( - field(L"id", L"4"), - field(L"gender", L"female"), - field(L"first", L"sally"), - field(L"last", L"smith"), - field(L"gender", L"female"), - field(L"first", L"linda"), - field(L"last", L"dixit"), - field(L"gender", L"male"), - field(L"first", L"bubba"), - field(L"last", L"jones"))) - ); + field(L"id", L"4"), + field(L"gender", L"female"), + field(L"first", L"sally"), + field(L"last", L"smith"), + field(L"gender", L"female"), + field(L"first", L"linda"), + field(L"last", L"dixit"), + field(L"gender", L"male"), + field(L"first", L"bubba"), + field(L"last", L"jones"))) + ); writer->close(); searcher = newLucene(directory, true); } - virtual ~FieldMaskingSpanQueryTest() - { + virtual ~FieldMaskingSpanQueryTest() { searcher->close(); } @@ -97,37 +94,32 @@ class FieldMaskingSpanQueryTest : public LuceneTestFixture IndexSearcherPtr searcher; public: - DocumentPtr doc(Collection fields) - { + DocumentPtr doc(Collection fields) { DocumentPtr doc = newLucene(); - for (int32_t i = 0; i < fields.size(); ++i) + for (int32_t i = 0; i < fields.size(); ++i) { doc->add(fields[i]); + } return doc; } - FieldPtr field(const String& name, const String& value) - { + FieldPtr field(const String& name, const String& value) { return newLucene(name, value, Field::STORE_NO, Field::INDEX_ANALYZED); } - void check(const SpanQueryPtr& q, Collection docs) - { + void check(const SpanQueryPtr& q, Collection docs) { CheckHits::checkHitCollector(q, L"", searcher, docs); } - String str(const SpansPtr& span) - { + String str(const SpansPtr& span) { return str(span->doc(), span->start(), span->end()); } - String str(int32_t doc, int32_t start, int32_t end) - { + String str(int32_t doc, int32_t start, int32_t end) { return L"s(" + StringUtils::toString(doc) + L"," + StringUtils::toString(start) + L"," + StringUtils::toString(end) + L")"; } }; -TEST_F(FieldMaskingSpanQueryTest, testRewrite0) -{ +TEST_F(FieldMaskingSpanQueryTest, testRewrite0) { SpanQueryPtr q = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); q->setBoost(8.7654321); SpanQueryPtr qr = boost::dynamic_pointer_cast(searcher->rewrite(q)); @@ -139,32 +131,28 @@ TEST_F(FieldMaskingSpanQueryTest, testRewrite0) EXPECT_EQ(1, terms.size()); } -namespace TestRewrite -{ - class TestableFieldMaskingSpanQuery : public FieldMaskingSpanQuery - { - public: - TestableFieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField) : FieldMaskingSpanQuery(maskedQuery, maskedField) - { - } +namespace TestRewrite { - virtual ~TestableFieldMaskingSpanQuery() - { - } +class TestableFieldMaskingSpanQuery : public FieldMaskingSpanQuery { +public: + TestableFieldMaskingSpanQuery(const SpanQueryPtr& maskedQuery, const String& maskedField) : FieldMaskingSpanQuery(maskedQuery, maskedField) { + } + + virtual ~TestableFieldMaskingSpanQuery() { + } + +public: + virtual QueryPtr rewrite(const IndexReaderPtr& reader) { + return newLucene(newCollection( + newLucene(newLucene(L"first", L"sally")), + newLucene(newLucene(L"first", L"james"))) + ); + } +}; - public: - virtual QueryPtr rewrite(const IndexReaderPtr& reader) - { - return newLucene(newCollection( - newLucene(newLucene(L"first", L"sally")), - newLucene(newLucene(L"first", L"james"))) - ); - } - }; } -TEST_F(FieldMaskingSpanQueryTest, testRewrite1) -{ +TEST_F(FieldMaskingSpanQueryTest, testRewrite1) { // mask an anon SpanQuery class that rewrites to something else. SpanQueryPtr q = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); SpanQueryPtr qr = boost::dynamic_pointer_cast(searcher->rewrite(q)); @@ -176,8 +164,7 @@ TEST_F(FieldMaskingSpanQueryTest, testRewrite1) EXPECT_EQ(2, terms.size()); } -TEST_F(FieldMaskingSpanQueryTest, testRewrite2) -{ +TEST_F(FieldMaskingSpanQueryTest, testRewrite2) { SpanQueryPtr q1 = newLucene(newLucene(L"last", L"smith")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"jones")); SpanQueryPtr q = newLucene(newCollection(q1, newLucene(q2, L"last")), 1, true); @@ -188,8 +175,7 @@ TEST_F(FieldMaskingSpanQueryTest, testRewrite2) EXPECT_EQ(2, terms.size()); } -TEST_F(FieldMaskingSpanQueryTest, testEquality1) -{ +TEST_F(FieldMaskingSpanQueryTest, testEquality1) { SpanQueryPtr q1 = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); SpanQueryPtr q2 = newLucene(newLucene(newLucene(L"last", L"sally")), L"first"); SpanQueryPtr q3 = newLucene(newLucene(newLucene(L"last", L"sally")), L"XXXXX"); @@ -208,15 +194,13 @@ TEST_F(FieldMaskingSpanQueryTest, testEquality1) QueryUtils::checkEqual(qA, qB); } -TEST_F(FieldMaskingSpanQueryTest, testNoop0) -{ +TEST_F(FieldMaskingSpanQueryTest, testNoop0) { SpanQueryPtr q1 = newLucene(newLucene(L"last", L"sally")); SpanQueryPtr q = newLucene(q1, L"first"); check(q, Collection::newInstance()); } -TEST_F(FieldMaskingSpanQueryTest, testNoop1) -{ +TEST_F(FieldMaskingSpanQueryTest, testNoop1) { SpanQueryPtr q1 = newLucene(newLucene(L"last", L"smith")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"jones")); SpanQueryPtr q = newLucene(newCollection(q1, newLucene(q2, L"last")), 0, true); @@ -225,8 +209,7 @@ TEST_F(FieldMaskingSpanQueryTest, testNoop1) check(q, newCollection(1, 2)); } -TEST_F(FieldMaskingSpanQueryTest, testSimple1) -{ +TEST_F(FieldMaskingSpanQueryTest, testSimple1) { SpanQueryPtr q1 = newLucene(newLucene(L"first", L"james")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"jones")); SpanQueryPtr q = newLucene(newCollection(q1, newLucene(q2, L"first")), -1, false); @@ -239,8 +222,7 @@ TEST_F(FieldMaskingSpanQueryTest, testSimple1) check(q, newCollection(0, 2)); } -TEST_F(FieldMaskingSpanQueryTest, testSimple2) -{ +TEST_F(FieldMaskingSpanQueryTest, testSimple2) { SpanQueryPtr q1 = newLucene(newLucene(L"gender", L"female")); SpanQueryPtr q2 = newLucene(newLucene(L"last", L"smith")); SpanQueryPtr q = newLucene(newCollection(q1, newLucene(q2, L"gender")), -1, false); @@ -249,8 +231,7 @@ TEST_F(FieldMaskingSpanQueryTest, testSimple2) check(q, newCollection(2, 4)); } -TEST_F(FieldMaskingSpanQueryTest, testSpans0) -{ +TEST_F(FieldMaskingSpanQueryTest, testSpans0) { SpanQueryPtr q1 = newLucene(newLucene(L"gender", L"female")); SpanQueryPtr q2 = newLucene(newLucene(L"first", L"james")); SpanQueryPtr q = newLucene(newCollection(q1, newLucene(q2, L"gender"))); @@ -288,8 +269,7 @@ TEST_F(FieldMaskingSpanQueryTest, testSpans0) EXPECT_TRUE(!span->next()); } -TEST_F(FieldMaskingSpanQueryTest, testSpans1) -{ +TEST_F(FieldMaskingSpanQueryTest, testSpans1) { SpanQueryPtr q1 = newLucene(newLucene(L"first", L"sally")); SpanQueryPtr q2 = newLucene(newLucene(L"first", L"james")); SpanQueryPtr qA = newLucene(newCollection(q1, q2)); @@ -301,16 +281,14 @@ TEST_F(FieldMaskingSpanQueryTest, testSpans1) SpansPtr spanA = qA->getSpans(searcher->getIndexReader()); SpansPtr spanB = qB->getSpans(searcher->getIndexReader()); - while (spanA->next()) - { + while (spanA->next()) { EXPECT_TRUE(spanB->next()); EXPECT_EQ(str(spanA), str(spanB)); } EXPECT_TRUE(!(spanB->next())); } -TEST_F(FieldMaskingSpanQueryTest, testSpans2) -{ +TEST_F(FieldMaskingSpanQueryTest, testSpans2) { SpanQueryPtr qA1 = newLucene(newLucene(L"gender", L"female")); SpanQueryPtr qA2 = newLucene(newLucene(L"first", L"james")); SpanQueryPtr qA = newLucene(newCollection(qA1, newLucene(qA2, L"gender"))); diff --git a/src/test/search/spans/NearSpansOrderedTest.cpp b/src/test/search/spans/NearSpansOrderedTest.cpp index 89b68cc3..cb23eea8 100644 --- a/src/test/search/spans/NearSpansOrderedTest.cpp +++ b/src/test/search/spans/NearSpansOrderedTest.cpp @@ -24,17 +24,14 @@ using namespace Lucene; -class NearSpansOrderedTest : public LuceneTestFixture -{ +class NearSpansOrderedTest : public LuceneTestFixture { public: - NearSpansOrderedTest() - { + NearSpansOrderedTest() { qp = newLucene(LuceneVersion::LUCENE_CURRENT, FIELD, newLucene()); docFields = newCollection(L"w1 w2 w3 w4 w5", L"w1 w3 w2 w3 zz", L"w1 xx w2 yy w3", L"w1 w3 xx w2 yy w3 zz"); RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < docFields.size(); ++i) - { + for (int32_t i = 0; i < docFields.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(FIELD, docFields[i], Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -43,8 +40,7 @@ class NearSpansOrderedTest : public LuceneTestFixture searcher = newLucene(directory, true); } - virtual ~NearSpansOrderedTest() - { + virtual ~NearSpansOrderedTest() { searcher->close(); } @@ -57,41 +53,35 @@ class NearSpansOrderedTest : public LuceneTestFixture static const String FIELD; public: - SpanNearQueryPtr makeQuery(const String& s1, const String& s2, const String& s3, int32_t slop, bool inOrder) - { + SpanNearQueryPtr makeQuery(const String& s1, const String& s2, const String& s3, int32_t slop, bool inOrder) { return newLucene(newCollection( - newLucene(newLucene(FIELD, s1)), - newLucene(newLucene(FIELD, s2)), - newLucene(newLucene(FIELD, s3)) - ), slop, inOrder); + newLucene(newLucene(FIELD, s1)), + newLucene(newLucene(FIELD, s2)), + newLucene(newLucene(FIELD, s3)) + ), slop, inOrder); } - SpanNearQueryPtr makeQuery() - { + SpanNearQueryPtr makeQuery() { return makeQuery(L"w1", L"w2", L"w3", 1, true); } - String str(const SpansPtr& span) - { + String str(const SpansPtr& span) { return str(span->doc(), span->start(), span->end()); } - String str(int32_t doc, int32_t start, int32_t end) - { + String str(int32_t doc, int32_t start, int32_t end) { return L"s(" + StringUtils::toString(doc) + L"," + StringUtils::toString(start) + L"," + StringUtils::toString(end) + L")"; } }; const String NearSpansOrderedTest::FIELD = L"field"; -TEST_F(NearSpansOrderedTest, testSpanNearQuery) -{ +TEST_F(NearSpansOrderedTest, testSpanNearQuery) { SpanNearQueryPtr q = makeQuery(); CheckHits::checkHits(q, FIELD, searcher, newCollection(0, 1)); } -TEST_F(NearSpansOrderedTest, testNearSpansNext) -{ +TEST_F(NearSpansOrderedTest, testNearSpansNext) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); EXPECT_TRUE(span->next()); @@ -103,8 +93,7 @@ TEST_F(NearSpansOrderedTest, testNearSpansNext) /// test does not imply that skipTo(doc+1) should work exactly the same as next -- it's only applicable in this case /// since we know doc does not contain more than one span -TEST_F(NearSpansOrderedTest, testNearSpansSkipToLikeNext) -{ +TEST_F(NearSpansOrderedTest, testNearSpansSkipToLikeNext) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); EXPECT_TRUE(span->skipTo(0)); @@ -114,8 +103,7 @@ TEST_F(NearSpansOrderedTest, testNearSpansSkipToLikeNext) EXPECT_TRUE(!span->skipTo(2)); } -TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipTo) -{ +TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipTo) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); EXPECT_TRUE(span->next()); @@ -125,8 +113,7 @@ TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipTo) EXPECT_TRUE(!span->next()); } -TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipPast) -{ +TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipPast) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); EXPECT_TRUE(span->next()); @@ -134,39 +121,34 @@ TEST_F(NearSpansOrderedTest, testNearSpansNextThenSkipPast) EXPECT_TRUE(!span->skipTo(2)); } -TEST_F(NearSpansOrderedTest, testNearSpansSkipPast) -{ +TEST_F(NearSpansOrderedTest, testNearSpansSkipPast) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); EXPECT_TRUE(!span->skipTo(2)); } -TEST_F(NearSpansOrderedTest, testNearSpansSkipTo0) -{ +TEST_F(NearSpansOrderedTest, testNearSpansSkipTo0) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); EXPECT_TRUE(span->skipTo(0)); EXPECT_EQ(str(0, 0, 3), str(span)); } -TEST_F(NearSpansOrderedTest, testNearSpansSkipTo1) -{ +TEST_F(NearSpansOrderedTest, testNearSpansSkipTo1) { SpanNearQueryPtr q = makeQuery(); SpansPtr span = q->getSpans(searcher->getIndexReader()); EXPECT_TRUE(span->skipTo(1)); EXPECT_EQ(str(1, 0, 4), str(span)); } -TEST_F(NearSpansOrderedTest, testSpanNearScorerSkipTo1) -{ +TEST_F(NearSpansOrderedTest, testSpanNearScorerSkipTo1) { SpanNearQueryPtr q = makeQuery(); WeightPtr w = q->weight(searcher); ScorerPtr s = w->scorer(searcher->getIndexReader(), true, false); EXPECT_EQ(1, s->advance(1)); } -TEST_F(NearSpansOrderedTest, testSpanNearScorerExplain) -{ +TEST_F(NearSpansOrderedTest, testSpanNearScorerExplain) { SpanNearQueryPtr q = makeQuery(); ExplanationPtr e = q->weight(searcher)->explain(searcher->getIndexReader(), 1); EXPECT_TRUE(0.0 < e->getValue()); diff --git a/src/test/search/spans/PayloadSpansTest.cpp b/src/test/search/spans/PayloadSpansTest.cpp index 3c02ff3e..e1025f6f 100644 --- a/src/test/search/spans/PayloadSpansTest.cpp +++ b/src/test/search/spans/PayloadSpansTest.cpp @@ -36,11 +36,9 @@ using namespace Lucene; DECLARE_SHARED_PTR(PayloadSpansAnalyzer) -class PayloadSpansFilter : public TokenFilter -{ +class PayloadSpansFilter : public TokenFilter { public: - PayloadSpansFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) - { + PayloadSpansFilter(const TokenStreamPtr& input, const String& fieldName) : TokenFilter(input) { this->fieldName = fieldName; this->pos = 0; this->entities = HashSet::newInstance(); @@ -54,8 +52,7 @@ class PayloadSpansFilter : public TokenFilter this->payloadAtt = addAttribute(); } - virtual ~PayloadSpansFilter() - { + virtual ~PayloadSpansFilter() { } LUCENE_CLASS(PayloadSpansFilter); @@ -70,20 +67,18 @@ class PayloadSpansFilter : public TokenFilter PositionIncrementAttributePtr posIncrAtt; public: - virtual bool incrementToken() - { - if (input->incrementToken()) - { + virtual bool incrementToken() { + if (input->incrementToken()) { String token(termAtt->termBuffer().get(), termAtt->termLength()); - if (!nopayload.contains(token)) - { + if (!nopayload.contains(token)) { StringStream buf; buf << token; - if (entities.contains(token)) + if (entities.contains(token)) { buf << L":Entity:"; - else + } else { buf << L":Noise:"; + } buf << pos; ByteArray data = ByteArray::newInstance(buf.str().length() * sizeof(wchar_t)); std::wcsncpy((wchar_t*)data.get(), buf.str().c_str(), buf.str().length()); @@ -91,42 +86,36 @@ class PayloadSpansFilter : public TokenFilter } pos += posIncrAtt->getPositionIncrement(); return true; - } - else + } else { return false; + } } }; -class PayloadSpansAnalyzer : public Analyzer -{ +class PayloadSpansAnalyzer : public Analyzer { public: - virtual ~PayloadSpansAnalyzer() - { + virtual ~PayloadSpansAnalyzer() { } LUCENE_CLASS(PayloadSpansAnalyzer); public: - virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) - { + virtual TokenStreamPtr tokenStream(const String& fieldName, const ReaderPtr& reader) { TokenStreamPtr result = newLucene(reader); result = newLucene(result, fieldName); return result; } }; -class PayloadSpansTest : public LuceneTestFixture -{ +class PayloadSpansTest : public LuceneTestFixture { public: - PayloadSpansTest() - { + PayloadSpansTest() { similarity = newLucene(); searcher = PayloadHelper::setUp(similarity, 1000); indexReader = searcher->getIndexReader(); } - virtual ~PayloadSpansTest() - { + virtual ~PayloadSpansTest() { } protected: @@ -135,24 +124,21 @@ class PayloadSpansTest : public LuceneTestFixture IndexReaderPtr indexReader; public: - void checkSpans(const SpansPtr& spans, int32_t expectedNumSpans, int32_t expectedNumPayloads, int32_t expectedPayloadLength, int32_t expectedFirstByte) - { + void checkSpans(const SpansPtr& spans, int32_t expectedNumSpans, int32_t expectedNumPayloads, int32_t expectedPayloadLength, int32_t expectedFirstByte) { EXPECT_TRUE(spans); int32_t seen = 0; - while (spans->next()) - { + while (spans->next()) { // if we expect payloads, then isPayloadAvailable should be true - if (expectedNumPayloads > 0) + if (expectedNumPayloads > 0) { EXPECT_TRUE(spans->isPayloadAvailable()); - else + } else { EXPECT_TRUE(!spans->isPayloadAvailable()); + } // See payload helper, for the PayloadHelper::FIELD field, there is a single byte payload at every token - if (spans->isPayloadAvailable()) - { + if (spans->isPayloadAvailable()) { Collection payload = spans->getPayload(); EXPECT_EQ(payload.size(), expectedNumPayloads); - for (Collection::iterator thePayload = payload.begin(); thePayload != payload.end(); ++thePayload) - { + for (Collection::iterator thePayload = payload.begin(); thePayload != payload.end(); ++thePayload) { EXPECT_EQ(thePayload->size(), expectedPayloadLength); EXPECT_EQ((*thePayload)[0], expectedFirstByte); } @@ -162,24 +148,20 @@ class PayloadSpansTest : public LuceneTestFixture EXPECT_EQ(seen, expectedNumSpans); } - void checkSpans(const SpansPtr& spans, int32_t numSpans, Collection numPayloads) - { + void checkSpans(const SpansPtr& spans, int32_t numSpans, Collection numPayloads) { int32_t cnt = 0; - while (spans->next()) - { - if (spans->isPayloadAvailable()) - { + while (spans->next()) { + if (spans->isPayloadAvailable()) { Collection payload = spans->getPayload(); EXPECT_EQ(numPayloads[cnt], payload.size()); - } - else + } else { EXPECT_TRUE(numPayloads.size() <= 0 || numPayloads[cnt] <= 0); + } } ++cnt; } - IndexSearcherPtr getSpanNotSearcher() - { + IndexSearcherPtr getSpanNotSearcher() { RAMDirectoryPtr directory = newLucene(); PayloadSpansAnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); @@ -195,20 +177,18 @@ class PayloadSpansTest : public LuceneTestFixture return searcher; } - IndexSearcherPtr getSearcher() - { + IndexSearcherPtr getSearcher() { RAMDirectoryPtr directory = newLucene(); PayloadSpansAnalyzerPtr analyzer = newLucene(); Collection docs = newCollection( - L"xx rr yy mm pp", L"xx yy mm rr pp", L"nopayload qq ss pp np", - L"one two three four five six seven eight nine ten eleven", - L"nine one two three four five six seven eight eleven ten" - ); + L"xx rr yy mm pp", L"xx yy mm rr pp", L"nopayload qq ss pp np", + L"one two three four five six seven eight nine ten eleven", + L"nine one two three four five six seven eight eleven ten" + ); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); writer->setSimilarity(similarity); - for (int32_t i = 0; i < docs.size(); ++i) - { + for (int32_t i = 0; i < docs.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(PayloadHelper::FIELD, docs[i], Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -221,8 +201,7 @@ class PayloadSpansTest : public LuceneTestFixture } }; -TEST_F(PayloadSpansTest, testSpanTermQuery) -{ +TEST_F(PayloadSpansTest, testSpanTermQuery) { SpanTermQueryPtr stq = newLucene(newLucene(PayloadHelper::FIELD, L"seventy")); SpansPtr spans = stq->getSpans(indexReader); EXPECT_TRUE(spans); @@ -234,17 +213,16 @@ TEST_F(PayloadSpansTest, testSpanTermQuery) checkSpans(spans, 100, 0, 0, 0); } -TEST_F(PayloadSpansTest, testSpanFirst) -{ +TEST_F(PayloadSpansTest, testSpanFirst) { SpanQueryPtr match = newLucene(newLucene(PayloadHelper::FIELD, L"one")); SpanFirstQueryPtr sfq = newLucene(match, 2); SpansPtr spans = sfq->getSpans(indexReader); checkSpans(spans, 109, 1, 1, 1); // Test more complicated subclause Collection clauses = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"one")), - newLucene(newLucene(PayloadHelper::FIELD, L"hundred")) - ); + newLucene(newLucene(PayloadHelper::FIELD, L"one")), + newLucene(newLucene(PayloadHelper::FIELD, L"hundred")) + ); match = newLucene(clauses, 0, true); sfq = newLucene(match, 2); checkSpans(sfq->getSpans(indexReader), 100, 2, 1, 1); @@ -254,19 +232,17 @@ TEST_F(PayloadSpansTest, testSpanFirst) checkSpans(sfq->getSpans(indexReader), 100, 2, 1, 1); } -TEST_F(PayloadSpansTest, testSpanNot) -{ +TEST_F(PayloadSpansTest, testSpanNot) { Collection clauses = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"one")), - newLucene(newLucene(PayloadHelper::FIELD, L"three")) - ); + newLucene(newLucene(PayloadHelper::FIELD, L"one")), + newLucene(newLucene(PayloadHelper::FIELD, L"three")) + ); SpanQueryPtr spq = newLucene(clauses, 5, true); SpanNotQueryPtr snq = newLucene(spq, newLucene(newLucene(PayloadHelper::FIELD, L"two"))); checkSpans(snq->getSpans(getSpanNotSearcher()->getIndexReader()), 1, newCollection(2)); } -TEST_F(PayloadSpansTest, testNestedSpans) -{ +TEST_F(PayloadSpansTest, testNestedSpans) { IndexSearcherPtr searcher = getSearcher(); SpanTermQueryPtr stq = newLucene(newLucene(PayloadHelper::FIELD, L"mark")); SpansPtr spans = stq->getSpans(searcher->getIndexReader()); @@ -274,10 +250,10 @@ TEST_F(PayloadSpansTest, testNestedSpans) checkSpans(spans, 0, Collection()); Collection clauses = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"rr")), - newLucene(newLucene(PayloadHelper::FIELD, L"yy")), - newLucene(newLucene(PayloadHelper::FIELD, L"xx")) - ); + newLucene(newLucene(PayloadHelper::FIELD, L"rr")), + newLucene(newLucene(PayloadHelper::FIELD, L"yy")), + newLucene(newLucene(PayloadHelper::FIELD, L"xx")) + ); SpanNearQueryPtr spanNearQuery = newLucene(clauses, 12, false); spans = spanNearQuery->getSpans(searcher->getIndexReader()); @@ -295,17 +271,17 @@ TEST_F(PayloadSpansTest, testNestedSpans) checkSpans(spans, 1, newCollection(3)); clauses = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"xx")), - newLucene(newLucene(PayloadHelper::FIELD, L"rr")) - ); + newLucene(newLucene(PayloadHelper::FIELD, L"xx")), + newLucene(newLucene(PayloadHelper::FIELD, L"rr")) + ); spanNearQuery = newLucene(clauses, 6, true); // xx within 6 of rr Collection clauses2 = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"yy")), - spanNearQuery - ); + newLucene(newLucene(PayloadHelper::FIELD, L"yy")), + spanNearQuery + ); SpanNearQueryPtr nestedSpanNearQuery = newLucene(clauses2, 6, false); @@ -315,27 +291,26 @@ TEST_F(PayloadSpansTest, testNestedSpans) checkSpans(spans, 2, newCollection(3, 3)); } -TEST_F(PayloadSpansTest, testFirstClauseWithoutPayload) -{ +TEST_F(PayloadSpansTest, testFirstClauseWithoutPayload) { IndexSearcherPtr searcher = getSearcher(); Collection clauses = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"nopayload")), - newLucene(newLucene(PayloadHelper::FIELD, L"qq")), - newLucene(newLucene(PayloadHelper::FIELD, L"ss")) - ); + newLucene(newLucene(PayloadHelper::FIELD, L"nopayload")), + newLucene(newLucene(PayloadHelper::FIELD, L"qq")), + newLucene(newLucene(PayloadHelper::FIELD, L"ss")) + ); SpanNearQueryPtr spanNearQuery = newLucene(clauses, 6, true); Collection clauses2 = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"pp")), - spanNearQuery - ); + newLucene(newLucene(PayloadHelper::FIELD, L"pp")), + spanNearQuery + ); SpanNearQueryPtr snq = newLucene(clauses2, 6, false); Collection clauses3 = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"np")), - snq - ); + newLucene(newLucene(PayloadHelper::FIELD, L"np")), + snq + ); SpanNearQueryPtr nestedSpanNearQuery = newLucene(clauses3, 6, false); @@ -344,14 +319,13 @@ TEST_F(PayloadSpansTest, testFirstClauseWithoutPayload) checkSpans(spans, 1, newCollection(3)); } -TEST_F(PayloadSpansTest, testHeavilyNestedSpanQuery) -{ +TEST_F(PayloadSpansTest, testHeavilyNestedSpanQuery) { IndexSearcherPtr searcher = getSearcher(); Collection clauses = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"one")), - newLucene(newLucene(PayloadHelper::FIELD, L"two")), - newLucene(newLucene(PayloadHelper::FIELD, L"three")) - ); + newLucene(newLucene(PayloadHelper::FIELD, L"one")), + newLucene(newLucene(PayloadHelper::FIELD, L"two")), + newLucene(newLucene(PayloadHelper::FIELD, L"three")) + ); SpanNearQueryPtr spanNearQuery = newLucene(clauses, 5, true); clauses[0] = spanNearQuery; @@ -361,16 +335,16 @@ TEST_F(PayloadSpansTest, testHeavilyNestedSpanQuery) SpanNearQueryPtr spanNearQuery2 = newLucene(clauses, 6, true); Collection clauses2 = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"eleven")), - newLucene(newLucene(PayloadHelper::FIELD, L"ten")) - ); + newLucene(newLucene(PayloadHelper::FIELD, L"eleven")), + newLucene(newLucene(PayloadHelper::FIELD, L"ten")) + ); SpanNearQueryPtr spanNearQuery3 = newLucene(clauses2, 2, false); Collection clauses3 = newCollection( - newLucene(newLucene(PayloadHelper::FIELD, L"nine")), - spanNearQuery2, - spanNearQuery3 - ); + newLucene(newLucene(PayloadHelper::FIELD, L"nine")), + spanNearQuery2, + spanNearQuery3 + ); SpanNearQueryPtr nestedSpanNearQuery = newLucene(clauses3, 6, false); SpansPtr spans = nestedSpanNearQuery->getSpans(searcher->getIndexReader()); @@ -378,8 +352,7 @@ TEST_F(PayloadSpansTest, testHeavilyNestedSpanQuery) checkSpans(spans, 2, newCollection(8, 8)); } -TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch) -{ +TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -397,13 +370,12 @@ TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch) TopDocsPtr topDocs = is->search(snq, 1); HashSet payloadSet = HashSet::newInstance(); - for (int32_t i = 0; i < topDocs->scoreDocs.size(); ++i) - { - while (spans->next()) - { + for (int32_t i = 0; i < topDocs->scoreDocs.size(); ++i) { + while (spans->next()) { Collection payloads = spans->getPayload(); - for (Collection::iterator it = payloads.begin(); it != payloads.end(); ++it) + for (Collection::iterator it = payloads.begin(); it != payloads.end(); ++it) { payloadSet.add(String((wchar_t*)it->get(), it->size() / sizeof(wchar_t))); + } } } EXPECT_EQ(2, payloadSet.size()); @@ -411,8 +383,7 @@ TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch) EXPECT_TRUE(payloadSet.contains(L"k:Noise:11")); } -TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch2) -{ +TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch2) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -430,13 +401,12 @@ TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch2) TopDocsPtr topDocs = is->search(snq, 1); HashSet payloadSet = HashSet::newInstance(); - for (int32_t i = 0; i < topDocs->scoreDocs.size(); ++i) - { - while (spans->next()) - { + for (int32_t i = 0; i < topDocs->scoreDocs.size(); ++i) { + while (spans->next()) { Collection payloads = spans->getPayload(); - for (Collection::iterator it = payloads.begin(); it != payloads.end(); ++it) + for (Collection::iterator it = payloads.begin(); it != payloads.end(); ++it) { payloadSet.add(String((wchar_t*)it->get(), it->size() / sizeof(wchar_t))); + } } } EXPECT_EQ(2, payloadSet.size()); @@ -444,8 +414,7 @@ TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch2) EXPECT_TRUE(payloadSet.contains(L"k:Noise:11")); } -TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch3) -{ +TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch3) { RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(), IndexWriter::MaxFieldLengthLIMITED); DocumentPtr doc = newLucene(); @@ -463,13 +432,12 @@ TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch3) TopDocsPtr topDocs = is->search(snq, 1); HashSet payloadSet = HashSet::newInstance(); - for (int32_t i = 0; i < topDocs->scoreDocs.size(); ++i) - { - while (spans->next()) - { + for (int32_t i = 0; i < topDocs->scoreDocs.size(); ++i) { + while (spans->next()) { Collection payloads = spans->getPayload(); - for (Collection::iterator it = payloads.begin(); it != payloads.end(); ++it) + for (Collection::iterator it = payloads.begin(); it != payloads.end(); ++it) { payloadSet.add(String((wchar_t*)it->get(), it->size() / sizeof(wchar_t))); + } } } EXPECT_EQ(2, payloadSet.size()); @@ -477,8 +445,7 @@ TEST_F(PayloadSpansTest, testShrinkToAfterShortestMatch3) EXPECT_TRUE(payloadSet.contains(L"k:Noise:11")); } -TEST_F(PayloadSpansTest, testPayloadSpanUtil) -{ +TEST_F(PayloadSpansTest, testPayloadSpanUtil) { RAMDirectoryPtr directory = newLucene(); PayloadSpansAnalyzerPtr analyzer = newLucene(); IndexWriterPtr writer = newLucene(directory, analyzer, true, IndexWriter::MaxFieldLengthUNLIMITED); diff --git a/src/test/search/spans/SpanExplanationsTest.cpp b/src/test/search/spans/SpanExplanationsTest.cpp index cf714591..e464759c 100644 --- a/src/test/search/spans/SpanExplanationsTest.cpp +++ b/src/test/search/spans/SpanExplanationsTest.cpp @@ -17,190 +17,160 @@ using namespace Lucene; typedef ExplanationsFixture SpanExplanationsTest; -TEST_F(SpanExplanationsTest, testST1) -{ +TEST_F(SpanExplanationsTest, testST1) { SpanQueryPtr q = st(L"w1"); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testST2) -{ +TEST_F(SpanExplanationsTest, testST2) { SpanQueryPtr q = st(L"w1"); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testST4) -{ +TEST_F(SpanExplanationsTest, testST4) { SpanQueryPtr q = st(L"xx"); qtest(q, newCollection(2, 3)); } -TEST_F(SpanExplanationsTest, testST5) -{ +TEST_F(SpanExplanationsTest, testST5) { SpanQueryPtr q = st(L"xx"); q->setBoost(1000); qtest(q, newCollection(2, 3)); } -TEST_F(SpanExplanationsTest, testSF1) -{ +TEST_F(SpanExplanationsTest, testSF1) { SpanQueryPtr q = sf(L"w1", 1); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSF2) -{ +TEST_F(SpanExplanationsTest, testSF2) { SpanQueryPtr q = sf(L"w1", 1); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSF4) -{ +TEST_F(SpanExplanationsTest, testSF4) { SpanQueryPtr q = sf(L"xx", 2); qtest(q, newCollection(2)); } -TEST_F(SpanExplanationsTest, testSF5) -{ +TEST_F(SpanExplanationsTest, testSF5) { SpanQueryPtr q = sf(L"yy", 2); qtest(q, Collection::newInstance()); } -TEST_F(SpanExplanationsTest, testSF6) -{ +TEST_F(SpanExplanationsTest, testSF6) { SpanQueryPtr q = sf(L"yy", 4); q->setBoost(1000); qtest(q, newCollection(2)); } -TEST_F(SpanExplanationsTest, testSO1) -{ +TEST_F(SpanExplanationsTest, testSO1) { SpanQueryPtr q = sor(L"w1", L"QQ"); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSO2) -{ +TEST_F(SpanExplanationsTest, testSO2) { SpanQueryPtr q = sor(L"w1", L"w3", L"zz"); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSO3) -{ +TEST_F(SpanExplanationsTest, testSO3) { SpanQueryPtr q = sor(L"w5", L"QQ", L"yy"); qtest(q, newCollection(0, 2, 3)); } -TEST_F(SpanExplanationsTest, testSO4) -{ +TEST_F(SpanExplanationsTest, testSO4) { SpanQueryPtr q = sor(L"w5", L"QQ", L"yy"); qtest(q, newCollection(0, 2, 3)); } -TEST_F(SpanExplanationsTest, testSNear1) -{ +TEST_F(SpanExplanationsTest, testSNear1) { SpanQueryPtr q = snear(L"w1", L"QQ", 100, true); qtest(q, Collection::newInstance()); } -TEST_F(SpanExplanationsTest, testSNear2) -{ +TEST_F(SpanExplanationsTest, testSNear2) { SpanQueryPtr q = snear(L"w1", L"xx", 100, true); qtest(q, newCollection(2, 3)); } -TEST_F(SpanExplanationsTest, testSNear3) -{ +TEST_F(SpanExplanationsTest, testSNear3) { SpanQueryPtr q = snear(L"w1", L"xx", 0, true); qtest(q, newCollection(2)); } -TEST_F(SpanExplanationsTest, testSNear4) -{ +TEST_F(SpanExplanationsTest, testSNear4) { SpanQueryPtr q = snear(L"w1", L"xx", 1, true); qtest(q, newCollection(2, 3)); } -TEST_F(SpanExplanationsTest, testSNear5) -{ +TEST_F(SpanExplanationsTest, testSNear5) { SpanQueryPtr q = snear(L"xx", L"w1", 0, false); qtest(q, newCollection(2)); } -TEST_F(SpanExplanationsTest, testSNear6) -{ +TEST_F(SpanExplanationsTest, testSNear6) { SpanQueryPtr q = snear(L"w1", L"w2", L"QQ", 100, true); qtest(q, Collection::newInstance()); } -TEST_F(SpanExplanationsTest, testSNear7) -{ +TEST_F(SpanExplanationsTest, testSNear7) { SpanQueryPtr q = snear(L"w1", L"xx", L"w2", 100, true); qtest(q, newCollection(2, 3)); } -TEST_F(SpanExplanationsTest, testSNear8) -{ +TEST_F(SpanExplanationsTest, testSNear8) { SpanQueryPtr q = snear(L"w1", L"xx", L"w2", 0, true); qtest(q, newCollection(2)); } -TEST_F(SpanExplanationsTest, testSNear9) -{ +TEST_F(SpanExplanationsTest, testSNear9) { SpanQueryPtr q = snear(L"w1", L"xx", L"w2", 1, true); qtest(q, newCollection(2, 3)); } -TEST_F(SpanExplanationsTest, testSNear10) -{ +TEST_F(SpanExplanationsTest, testSNear10) { SpanQueryPtr q = snear(L"xx", L"w1", L"w2", 0, false); qtest(q, newCollection(2)); } -TEST_F(SpanExplanationsTest, testSNear11) -{ +TEST_F(SpanExplanationsTest, testSNear11) { SpanQueryPtr q = snear(L"w1", L"w2", L"w3", 1, true); qtest(q, newCollection(0, 1)); } -TEST_F(SpanExplanationsTest, testSNot1) -{ +TEST_F(SpanExplanationsTest, testSNot1) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSNot2) -{ +TEST_F(SpanExplanationsTest, testSNot2) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"QQ")); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSNot4) -{ +TEST_F(SpanExplanationsTest, testSNot4) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSNot5) -{ +TEST_F(SpanExplanationsTest, testSNot5) { SpanQueryPtr q = snot(sf(L"w1", 10), st(L"xx")); q->setBoost(1000); qtest(q, newCollection(0, 1, 2, 3)); } -TEST_F(SpanExplanationsTest, testSNot7) -{ +TEST_F(SpanExplanationsTest, testSNot7) { SpanQueryPtr f = snear(L"w1", L"w3", 10, true); f->setBoost(1000); SpanQueryPtr q = snot(f, st(L"xx")); qtest(q, newCollection(0, 1, 3)); } -TEST_F(SpanExplanationsTest, testSNot10) -{ +TEST_F(SpanExplanationsTest, testSNot10) { SpanQueryPtr t = st(L"xx"); t->setBoost(10000); SpanQueryPtr q = snot(snear(L"w1", L"w3", 10, true), t); diff --git a/src/test/search/spans/SpansAdvanced2Test.cpp b/src/test/search/spans/SpansAdvanced2Test.cpp index e9889542..34fb5349 100644 --- a/src/test/search/spans/SpansAdvanced2Test.cpp +++ b/src/test/search/spans/SpansAdvanced2Test.cpp @@ -23,11 +23,9 @@ using namespace Lucene; -class SpansAdvanced2Test : public LuceneTestFixture -{ +class SpansAdvanced2Test : public LuceneTestFixture { public: - SpansAdvanced2Test() - { + SpansAdvanced2Test() { // create test index directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -46,8 +44,7 @@ class SpansAdvanced2Test : public LuceneTestFixture searcher2 = newLucene(directory, true); } - virtual ~SpansAdvanced2Test() - { + virtual ~SpansAdvanced2Test() { searcher->close(); searcher2->close(); directory->close(); @@ -62,16 +59,14 @@ class SpansAdvanced2Test : public LuceneTestFixture IndexSearcherPtr searcher; IndexSearcherPtr searcher2; - void addDocument(const IndexWriterPtr& writer, const String& id, const String& text) - { + void addDocument(const IndexWriterPtr& writer, const String& id, const String& text) { DocumentPtr document = newLucene(); document->add(newLucene(FIELD_ID, id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); document->add(newLucene(FIELD_TEXT, text, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(document); } - void checkHits(const SearcherPtr& s, const QueryPtr& query, const String& description, Collection expectedIds, Collection expectedScores) - { + void checkHits(const SearcherPtr& s, const QueryPtr& query, const String& description, Collection expectedIds, Collection expectedScores) { QueryUtils::check(query, s); double tolerance = 1e-5f; @@ -82,15 +77,13 @@ class SpansAdvanced2Test : public LuceneTestFixture // did we get the hits we expected EXPECT_EQ(expectedIds.size(), topdocs->totalHits); - for (int32_t i = 0; i < topdocs->totalHits; ++i) - { + for (int32_t i = 0; i < topdocs->totalHits; ++i) { int32_t id = topdocs->scoreDocs[i]->doc; double score = topdocs->scoreDocs[i]->score; DocumentPtr doc = s->doc(id); EXPECT_EQ(expectedIds[i], doc->get(FIELD_ID)); bool scoreEq = (std::abs(expectedScores[i] - score) < tolerance); - if (scoreEq) - { + if (scoreEq) { EXPECT_NEAR(expectedScores[i], score, tolerance); EXPECT_NEAR(s->explain(query, id)->getValue(), score, tolerance); } @@ -101,23 +94,20 @@ class SpansAdvanced2Test : public LuceneTestFixture const String SpansAdvanced2Test::FIELD_ID = L"ID"; const String SpansAdvanced2Test::FIELD_TEXT = L"TEXT"; -TEST_F(SpansAdvanced2Test, testVerifyIndex) -{ +TEST_F(SpansAdvanced2Test, testVerifyIndex) { IndexReaderPtr reader = IndexReader::open(directory, true); EXPECT_EQ(8, reader->numDocs()); reader->close(); } -TEST_F(SpansAdvanced2Test, testSingleSpanQuery) -{ +TEST_F(SpansAdvanced2Test, testSingleSpanQuery) { QueryPtr spanQuery = newLucene(newLucene(FIELD_TEXT, L"should")); Collection expectedIds = newCollection(L"B", L"D", L"1", L"2", L"3", L"4", L"A"); Collection expectedScores = newCollection(0.625, 0.45927936, 0.35355338, 0.35355338, 0.35355338, 0.35355338, 0.26516503); checkHits(searcher2, spanQuery, L"single span query", expectedIds, expectedScores); } -TEST_F(SpansAdvanced2Test, testMultipleDifferentSpanQueries) -{ +TEST_F(SpansAdvanced2Test, testMultipleDifferentSpanQueries) { QueryPtr spanQuery1 = newLucene(newLucene(FIELD_TEXT, L"should")); QueryPtr spanQuery2 = newLucene(newLucene(FIELD_TEXT, L"we")); BooleanQueryPtr query = newLucene(); @@ -128,8 +118,7 @@ TEST_F(SpansAdvanced2Test, testMultipleDifferentSpanQueries) checkHits(searcher2, query, L"multiple different span queries", expectedIds, expectedScores); } -TEST_F(SpansAdvanced2Test, testBooleanQueryWithSpanQueries) -{ +TEST_F(SpansAdvanced2Test, testBooleanQueryWithSpanQueries) { double expectedScore = 0.73500174; QueryPtr spanQuery = newLucene(newLucene(FIELD_TEXT, L"work")); BooleanQueryPtr query = newLucene(); diff --git a/src/test/search/spans/SpansAdvancedTest.cpp b/src/test/search/spans/SpansAdvancedTest.cpp index 089a0810..5876e338 100644 --- a/src/test/search/spans/SpansAdvancedTest.cpp +++ b/src/test/search/spans/SpansAdvancedTest.cpp @@ -22,11 +22,9 @@ using namespace Lucene; -class SpansAdvancedTest : public LuceneTestFixture -{ +class SpansAdvancedTest : public LuceneTestFixture { public: - SpansAdvancedTest() - { + SpansAdvancedTest() { // create test index directory = newLucene(); IndexWriterPtr writer = newLucene(directory, newLucene(LuceneVersion::LUCENE_CURRENT), true, IndexWriter::MaxFieldLengthLIMITED); @@ -38,8 +36,7 @@ class SpansAdvancedTest : public LuceneTestFixture searcher = newLucene(directory, true); } - virtual ~SpansAdvancedTest() - { + virtual ~SpansAdvancedTest() { searcher->close(); directory->close(); } @@ -52,16 +49,14 @@ class SpansAdvancedTest : public LuceneTestFixture DirectoryPtr directory; IndexSearcherPtr searcher; - void addDocument(const IndexWriterPtr& writer, const String& id, const String& text) - { + void addDocument(const IndexWriterPtr& writer, const String& id, const String& text) { DocumentPtr document = newLucene(); document->add(newLucene(FIELD_ID, id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); document->add(newLucene(FIELD_TEXT, text, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(document); } - void checkHits(const SearcherPtr& s, const QueryPtr& query, const String& description, Collection expectedIds, Collection expectedScores) - { + void checkHits(const SearcherPtr& s, const QueryPtr& query, const String& description, Collection expectedIds, Collection expectedScores) { QueryUtils::check(query, s); double tolerance = 1e-5f; @@ -72,15 +67,13 @@ class SpansAdvancedTest : public LuceneTestFixture // did we get the hits we expected EXPECT_EQ(expectedIds.size(), topdocs->totalHits); - for (int32_t i = 0; i < topdocs->totalHits; ++i) - { + for (int32_t i = 0; i < topdocs->totalHits; ++i) { int32_t id = topdocs->scoreDocs[i]->doc; double score = topdocs->scoreDocs[i]->score; DocumentPtr doc = s->doc(id); EXPECT_EQ(expectedIds[i], doc->get(FIELD_ID)); bool scoreEq = (std::abs(expectedScores[i] - score) < tolerance); - if (scoreEq) - { + if (scoreEq) { EXPECT_NEAR(expectedScores[i], score, tolerance); EXPECT_NEAR(s->explain(query, id)->getValue(), score, tolerance); } @@ -91,8 +84,7 @@ class SpansAdvancedTest : public LuceneTestFixture const String SpansAdvancedTest::FIELD_ID = L"ID"; const String SpansAdvancedTest::FIELD_TEXT = L"TEXT"; -TEST_F(SpansAdvancedTest, testBooleanQueryWithSpanQueries) -{ +TEST_F(SpansAdvancedTest, testBooleanQueryWithSpanQueries) { double expectedScore = 0.3884282; QueryPtr spanQuery = newLucene(newLucene(FIELD_TEXT, L"work")); BooleanQueryPtr query = newLucene(); diff --git a/src/test/search/spans/SpansTest.cpp b/src/test/search/spans/SpansTest.cpp index dfc257b1..52400d44 100644 --- a/src/test/search/spans/SpansTest.cpp +++ b/src/test/search/spans/SpansTest.cpp @@ -30,11 +30,9 @@ using namespace Lucene; -class SpansTest : public LuceneTestFixture -{ +class SpansTest : public LuceneTestFixture { public: - SpansTest() - { + SpansTest() { docFields = Collection::newInstance(); docFields.add(L"w1 w2 w3 w4 w5"); docFields.add(L"w1 w3 w2 w3"); @@ -50,8 +48,7 @@ class SpansTest : public LuceneTestFixture docFields.add(L"t1 t2 t1 t3 t2 t3"); RAMDirectoryPtr directory = newLucene(); IndexWriterPtr writer= newLucene(directory, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); - for (int32_t i = 0; i < docFields.size(); ++i) - { + for (int32_t i = 0; i < docFields.size(); ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(field, docFields[i], Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -60,8 +57,7 @@ class SpansTest : public LuceneTestFixture searcher = newLucene(directory, true); } - virtual ~SpansTest() - { + virtual ~SpansTest() { searcher->close(); } @@ -73,157 +69,130 @@ class SpansTest : public LuceneTestFixture static const String field; public: - SpanTermQueryPtr makeSpanTermQuery(const String& text) - { + SpanTermQueryPtr makeSpanTermQuery(const String& text) { return newLucene(newLucene(field, text)); } - void checkHits(const QueryPtr& query, Collection results) - { + void checkHits(const QueryPtr& query, Collection results) { CheckHits::checkHits(query, field, searcher, results); } - void orderedSlopTest3SQ(const SpanQueryPtr& q1, const SpanQueryPtr& q2, const SpanQueryPtr& q3, int32_t slop, Collection expectedDocs) - { + void orderedSlopTest3SQ(const SpanQueryPtr& q1, const SpanQueryPtr& q2, const SpanQueryPtr& q3, int32_t slop, Collection expectedDocs) { bool ordered = true; SpanNearQueryPtr snq = newLucene(newCollection(q1, q2, q3), slop, ordered); checkHits(snq, expectedDocs); } - void orderedSlopTest3(int32_t slop, Collection expectedDocs) - { + void orderedSlopTest3(int32_t slop, Collection expectedDocs) { orderedSlopTest3SQ(makeSpanTermQuery(L"w1"), makeSpanTermQuery(L"w2"), makeSpanTermQuery(L"w3"), slop, expectedDocs); } - void orderedSlopTest3Equal(int32_t slop, Collection expectedDocs) - { + void orderedSlopTest3Equal(int32_t slop, Collection expectedDocs) { orderedSlopTest3SQ(makeSpanTermQuery(L"w1"), makeSpanTermQuery(L"w3"), makeSpanTermQuery(L"w3"), slop, expectedDocs); } - void orderedSlopTest1Equal(int32_t slop, Collection expectedDocs) - { + void orderedSlopTest1Equal(int32_t slop, Collection expectedDocs) { orderedSlopTest3SQ(makeSpanTermQuery(L"u2"), makeSpanTermQuery(L"u2"), makeSpanTermQuery(L"u1"), slop, expectedDocs); } - SpansPtr orSpans(Collection terms) - { + SpansPtr orSpans(Collection terms) { Collection sqa = Collection::newInstance(terms.size()); - for (int32_t i = 0; i < terms.size(); ++i) + for (int32_t i = 0; i < terms.size(); ++i) { sqa[i] = makeSpanTermQuery(terms[i]); + } return newLucene(sqa)->getSpans(searcher->getIndexReader()); } - void checkNextSpans(const SpansPtr& spans, int32_t doc, int32_t start, int32_t end) - { + void checkNextSpans(const SpansPtr& spans, int32_t doc, int32_t start, int32_t end) { EXPECT_TRUE(spans->next()); EXPECT_EQ(doc, spans->doc()); EXPECT_EQ(start, spans->start()); EXPECT_EQ(end, spans->end()); } - void addDoc(const IndexWriterPtr& writer, const String& id, const String& text) - { + void addDoc(const IndexWriterPtr& writer, const String& id, const String& text) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", id, Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"text", text, Field::STORE_YES, Field::INDEX_ANALYZED)); writer->addDocument(doc); } - int32_t hitCount(const SearcherPtr& searcher, const String& word) - { + int32_t hitCount(const SearcherPtr& searcher, const String& word) { return searcher->search(newLucene(newLucene(L"text", word)), 10)->totalHits; } - SpanQueryPtr createSpan(const String& value) - { + SpanQueryPtr createSpan(const String& value) { return newLucene(newLucene(L"text", value)); } - SpanQueryPtr createSpan(int32_t slop, bool ordered, Collection clauses) - { + SpanQueryPtr createSpan(int32_t slop, bool ordered, Collection clauses) { return newLucene(clauses, slop, ordered); } - SpanQueryPtr createSpan(int32_t slop, bool ordered, const String& term1, const String& term2) - { + SpanQueryPtr createSpan(int32_t slop, bool ordered, const String& term1, const String& term2) { return createSpan(slop, ordered, newCollection(createSpan(term1), createSpan(term2))); } }; const String SpansTest::field = L"field"; -TEST_F(SpansTest, testSpanNearOrdered01) -{ +TEST_F(SpansTest, testSpanNearOrdered01) { orderedSlopTest3(0, newCollection(0)); } -TEST_F(SpansTest, testSpanNearOrdered02) -{ +TEST_F(SpansTest, testSpanNearOrdered02) { orderedSlopTest3(1, newCollection(0, 1)); } -TEST_F(SpansTest, testSpanNearOrdered03) -{ +TEST_F(SpansTest, testSpanNearOrdered03) { orderedSlopTest3(2, newCollection(0, 1, 2)); } -TEST_F(SpansTest, testSpanNearOrdered04) -{ +TEST_F(SpansTest, testSpanNearOrdered04) { orderedSlopTest3(3, newCollection(0, 1, 2, 3)); } -TEST_F(SpansTest, testSpanNearOrdered05) -{ +TEST_F(SpansTest, testSpanNearOrdered05) { orderedSlopTest3(4, newCollection(0, 1, 2, 3)); } -TEST_F(SpansTest, testSpanNearOrderedEqual01) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual01) { orderedSlopTest3Equal(0, Collection::newInstance()); } -TEST_F(SpansTest, testSpanNearOrderedEqual02) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual02) { orderedSlopTest3Equal(1, newCollection(1)); } -TEST_F(SpansTest, testSpanNearOrderedEqual03) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual03) { orderedSlopTest3Equal(2, newCollection(1)); } -TEST_F(SpansTest, testSpanNearOrderedEqual04) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual04) { orderedSlopTest3Equal(3, newCollection(1, 3)); } -TEST_F(SpansTest, testSpanNearOrderedEqual11) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual11) { orderedSlopTest1Equal(0, newCollection(4)); } -TEST_F(SpansTest, testSpanNearOrderedEqual12) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual12) { orderedSlopTest1Equal(0, newCollection(4)); } -TEST_F(SpansTest, testSpanNearOrderedEqual13) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual13) { orderedSlopTest1Equal(1, newCollection(4, 5, 6)); } -TEST_F(SpansTest, testSpanNearOrderedEqual14) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual14) { orderedSlopTest1Equal(2, newCollection(4, 5, 6, 7)); } -TEST_F(SpansTest, testSpanNearOrderedEqual15) -{ +TEST_F(SpansTest, testSpanNearOrderedEqual15) { orderedSlopTest1Equal(3, newCollection(4, 5, 6, 7)); } -TEST_F(SpansTest, testSpanNearOrderedOverlap) -{ +TEST_F(SpansTest, testSpanNearOrderedOverlap) { bool ordered = true; int32_t slop = 1; SpanNearQueryPtr snq = newLucene(newCollection(makeSpanTermQuery(L"t1"), makeSpanTermQuery(L"t2"), makeSpanTermQuery(L"t3")), slop, ordered); @@ -242,8 +211,7 @@ TEST_F(SpansTest, testSpanNearOrderedOverlap) EXPECT_TRUE(!spans->next()); } -TEST_F(SpansTest, testSpanNearUnOrdered) -{ +TEST_F(SpansTest, testSpanNearUnOrdered) { SpanNearQueryPtr snq = newLucene(newCollection(makeSpanTermQuery(L"u1"), makeSpanTermQuery(L"u2")), 0, false); SpansPtr spans = snq->getSpans(searcher->getIndexReader()); @@ -325,8 +293,7 @@ TEST_F(SpansTest, testSpanNearUnOrdered) EXPECT_TRUE(!spans->next()); } -TEST_F(SpansTest, testSpanOrEmpty) -{ +TEST_F(SpansTest, testSpanOrEmpty) { SpansPtr spans = orSpans(Collection::newInstance()); EXPECT_TRUE(!spans->next()); @@ -335,15 +302,13 @@ TEST_F(SpansTest, testSpanOrEmpty) EXPECT_TRUE(a->equals(b)); } -TEST_F(SpansTest, testSpanOrSingle) -{ +TEST_F(SpansTest, testSpanOrSingle) { SpansPtr spans = orSpans(newCollection(L"w5")); checkNextSpans(spans, 0, 4, 5); EXPECT_TRUE(!spans->next()); } -TEST_F(SpansTest, testSpanOrMovesForward) -{ +TEST_F(SpansTest, testSpanOrMovesForward) { SpansPtr spans = orSpans(newCollection(L"w1", L"xx")); EXPECT_TRUE(spans->next()); @@ -356,8 +321,7 @@ TEST_F(SpansTest, testSpanOrMovesForward) EXPECT_EQ(1, doc); } -TEST_F(SpansTest, testSpanOrDouble) -{ +TEST_F(SpansTest, testSpanOrDouble) { SpansPtr spans = orSpans(newCollection(L"w5", L"yy")); checkNextSpans(spans, 0, 4, 5); checkNextSpans(spans, 2, 3, 4); @@ -366,8 +330,7 @@ TEST_F(SpansTest, testSpanOrDouble) EXPECT_TRUE(!spans->next()); } -TEST_F(SpansTest, testSpanOrDoubleSkip) -{ +TEST_F(SpansTest, testSpanOrDoubleSkip) { SpansPtr spans = orSpans(newCollection(L"w5", L"yy")); EXPECT_TRUE(spans->skipTo(3)); EXPECT_EQ(3, spans->doc()); @@ -377,8 +340,7 @@ TEST_F(SpansTest, testSpanOrDoubleSkip) EXPECT_TRUE(!spans->next()); } -TEST_F(SpansTest, testSpanOrUnused) -{ +TEST_F(SpansTest, testSpanOrUnused) { SpansPtr spans = orSpans(newCollection(L"w5", L"unusedTerm", L"yy")); checkNextSpans(spans, 0, 4, 5); checkNextSpans(spans, 2, 3, 4); @@ -387,8 +349,7 @@ TEST_F(SpansTest, testSpanOrUnused) EXPECT_TRUE(!spans->next()); } -TEST_F(SpansTest, testSpanOrTripleSameDoc) -{ +TEST_F(SpansTest, testSpanOrTripleSameDoc) { SpansPtr spans = orSpans(newCollection(L"t1", L"t2", L"t3")); checkNextSpans(spans, 11, 0, 1); checkNextSpans(spans, 11, 1, 2); @@ -399,47 +360,40 @@ TEST_F(SpansTest, testSpanOrTripleSameDoc) EXPECT_TRUE(!spans->next()); } -namespace TestSpanScorerZeroSloppyFreq -{ - class SloppyFreqSimilarity : public DefaultSimilarity - { - public: - virtual ~SloppyFreqSimilarity() - { - } +namespace TestSpanScorerZeroSloppyFreq { - public: - virtual double sloppyFreq(int32_t distance) - { - return 0.0; - } - }; - - class SloppyFreqSpanNearQuery : public SpanNearQuery - { - public: - SloppyFreqSpanNearQuery(const SimilarityPtr& sim, Collection clauses, int32_t slop, bool inOrder) : SpanNearQuery(clauses, slop, inOrder) - { - this->sim = sim; - } +class SloppyFreqSimilarity : public DefaultSimilarity { +public: + virtual ~SloppyFreqSimilarity() { + } - virtual ~SloppyFreqSpanNearQuery() - { - } +public: + virtual double sloppyFreq(int32_t distance) { + return 0.0; + } +}; - protected: - SimilarityPtr sim; +class SloppyFreqSpanNearQuery : public SpanNearQuery { +public: + SloppyFreqSpanNearQuery(const SimilarityPtr& sim, Collection clauses, int32_t slop, bool inOrder) : SpanNearQuery(clauses, slop, inOrder) { + this->sim = sim; + } + + virtual ~SloppyFreqSpanNearQuery() { + } + +protected: + SimilarityPtr sim; + +public: + virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher) { + return sim; + } +}; - public: - virtual SimilarityPtr getSimilarity(const SearcherPtr& searcher) - { - return sim; - } - }; } -TEST_F(SpansTest, testSpanScorerZeroSloppyFreq) -{ +TEST_F(SpansTest, testSpanScorerZeroSloppyFreq) { bool ordered = true; int32_t slop = 1; @@ -454,8 +408,7 @@ TEST_F(SpansTest, testSpanScorerZeroSloppyFreq) EXPECT_EQ(spanScorer->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); } -TEST_F(SpansTest, testNPESpanQuery) -{ +TEST_F(SpansTest, testNPESpanQuery) { DirectoryPtr dir = newLucene(); IndexWriterPtr writer = newLucene(dir, newLucene(LuceneVersion::LUCENE_CURRENT, HashSet::newInstance()), IndexWriter::MaxFieldLengthLIMITED); diff --git a/src/test/store/BufferedIndexInputTest.cpp b/src/test/store/BufferedIndexInputTest.cpp index c7715d5f..10274a5c 100644 --- a/src/test/store/BufferedIndexInputTest.cpp +++ b/src/test/store/BufferedIndexInputTest.cpp @@ -30,15 +30,12 @@ using namespace Lucene; typedef LuceneTestFixture BufferedIndexInputTest; -class TestableBufferedIndexInputRead : public BufferedIndexInput -{ +class TestableBufferedIndexInputRead : public BufferedIndexInput { public: - TestableBufferedIndexInputRead(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) - { + TestableBufferedIndexInputRead(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) { } - virtual ~TestableBufferedIndexInputRead() - { + virtual ~TestableBufferedIndexInputRead() { } protected: @@ -47,29 +44,24 @@ class TestableBufferedIndexInputRead : public BufferedIndexInput int32_t nextByte; public: - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) - { + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) { std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); nextByte += length; } - virtual void seekInternal(int64_t pos) - { + virtual void seekInternal(int64_t pos) { } - virtual int64_t length() - { + virtual int64_t length() { return inputLength; } - virtual IndexInputPtr clone() - { + virtual IndexInputPtr clone() { return IndexInputPtr(); } }; -TEST_F(BufferedIndexInputTest, testReadInt) -{ +TEST_F(BufferedIndexInputTest, testReadInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 1, 2, 3, 4 }; std::memcpy(inputBytes.get(), input, 4); @@ -77,8 +69,7 @@ TEST_F(BufferedIndexInputTest, testReadInt) EXPECT_EQ(indexInput.readInt(), 16909060); } -TEST_F(BufferedIndexInputTest, testReadVInt) -{ +TEST_F(BufferedIndexInputTest, testReadVInt) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[4] = { 200, 201, 150, 96 }; std::memcpy(inputBytes.get(), input, 4); @@ -86,8 +77,7 @@ TEST_F(BufferedIndexInputTest, testReadVInt) EXPECT_EQ(indexInput.readVInt(), 201696456); } -TEST_F(BufferedIndexInputTest, testReadLong) -{ +TEST_F(BufferedIndexInputTest, testReadLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 32, 43, 32, 96, 12, 54, 22, 96 }; std::memcpy(inputBytes.get(), input, 8); @@ -95,8 +85,7 @@ TEST_F(BufferedIndexInputTest, testReadLong) EXPECT_EQ(indexInput.readLong(), 2317982030106072672LL); } -TEST_F(BufferedIndexInputTest, testReadVLong) -{ +TEST_F(BufferedIndexInputTest, testReadVLong) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[8] = { 213, 143, 132, 196, 172, 154, 129, 96 }; std::memcpy(inputBytes.get(), input, 8); @@ -104,8 +93,7 @@ TEST_F(BufferedIndexInputTest, testReadVLong) EXPECT_EQ(indexInput.readVLong(), 54048498881988565LL); } -TEST_F(BufferedIndexInputTest, testReadString) -{ +TEST_F(BufferedIndexInputTest, testReadString) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); @@ -113,8 +101,7 @@ TEST_F(BufferedIndexInputTest, testReadString) EXPECT_EQ(indexInput.readString(), L"test string"); } -TEST_F(BufferedIndexInputTest, testReadModifiedUTF8String) -{ +TEST_F(BufferedIndexInputTest, testReadModifiedUTF8String) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[12] = { 11, 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 12); @@ -122,8 +109,7 @@ TEST_F(BufferedIndexInputTest, testReadModifiedUTF8String) EXPECT_EQ(indexInput.readModifiedUTF8String(), L"test string"); } -TEST_F(BufferedIndexInputTest, testReadChars) -{ +TEST_F(BufferedIndexInputTest, testReadChars) { ByteArray inputBytes(ByteArray::newInstance(30)); uint8_t input[11] = { 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g' }; std::memcpy(inputBytes.get(), input, 11); @@ -137,8 +123,7 @@ TEST_F(BufferedIndexInputTest, testReadChars) EXPECT_EQ(std::memcmp(outputChars.get(), expected, 11 * sizeof(wchar_t)), 0); } -TEST_F(BufferedIndexInputTest, testSkipOneChar) -{ +TEST_F(BufferedIndexInputTest, testSkipOneChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -147,8 +132,7 @@ TEST_F(BufferedIndexInputTest, testSkipOneChar) EXPECT_EQ(indexInput.getFilePointer(), 1); } -TEST_F(BufferedIndexInputTest, testSkipTwoChars) -{ +TEST_F(BufferedIndexInputTest, testSkipTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 2, 3, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -157,8 +141,7 @@ TEST_F(BufferedIndexInputTest, testSkipTwoChars) EXPECT_EQ(indexInput.getFilePointer(), 2); } -TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalChar) -{ +TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalChar) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 132, 132, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -167,8 +150,7 @@ TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalChar) EXPECT_EQ(indexInput.getFilePointer(), 3); } -TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalTwoChars) -{ +TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalTwoChars) { ByteArray inputBytes(ByteArray::newInstance(10)); uint8_t input[5] = { 1, 232, 232, 4, 5 }; std::memcpy(inputBytes.get(), input, 5); @@ -177,12 +159,11 @@ TEST_F(BufferedIndexInputTest, testSkipTwoCharsAdditionalTwoChars) EXPECT_EQ(indexInput.getFilePointer(), 4); } -TEST_F(BufferedIndexInputTest, testReadCollection) -{ +TEST_F(BufferedIndexInputTest, testReadCollection) { ByteArray inputBytes(ByteArray::newInstance(100)); uint8_t input[88] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, - 'L', 'u', 'c', 'e', 'n', 'e', + 'L', 'u', 'c', 'e', 'n', 'e', // 2-byte UTF-8 (U+00BF "INVERTED QUESTION MARK") 0x02, 0xc2, 0xbf, 0x0a, 'L', 'u', 0xc2, 0xbf, 'c', 'e', 0xc2, 0xbf, 'n', 'e', @@ -197,7 +178,8 @@ TEST_F(BufferedIndexInputTest, testReadCollection) 'L', 'u', 0xf0, 0x9d, 0x84, 0x9e, 'c', 'e', 0xf0, 0x9d, 0x85, 0xa0, 'n', 'e', // null bytes - 0x01, 0x00, 0x08, 'L', 'u', 0x00, 'c', 'e', 0x00, 'n', 'e'}; + 0x01, 0x00, 0x08, 'L', 'u', 0x00, 'c', 'e', 0x00, 'n', 'e' + }; std::memcpy(inputBytes.get(), input, 88); TestableBufferedIndexInputRead indexInput(inputBytes.get(), 88); @@ -220,27 +202,27 @@ TEST_F(BufferedIndexInputTest, testReadCollection) String readString(indexInput.readString()); - #ifdef LPP_UNICODE_CHAR_SIZE_2 +#ifdef LPP_UNICODE_CHAR_SIZE_2 EXPECT_EQ(readString[0], 55348); EXPECT_EQ(readString[1], 56606); - #else +#else EXPECT_EQ(readString[0], 119070); - #endif +#endif readString = indexInput.readString(); - #ifdef LPP_UNICODE_CHAR_SIZE_2 +#ifdef LPP_UNICODE_CHAR_SIZE_2 EXPECT_EQ(readString[0], 55348); EXPECT_EQ(readString[1], 56606); EXPECT_EQ(readString[2], 55348); EXPECT_EQ(readString[3], 56672); - #else +#else EXPECT_EQ(readString[0], 119070); EXPECT_EQ(readString[1], 119136); - #endif +#endif readString = indexInput.readString(); - #ifdef LPP_UNICODE_CHAR_SIZE_2 +#ifdef LPP_UNICODE_CHAR_SIZE_2 EXPECT_EQ(readString[0], L'L'); EXPECT_EQ(readString[1], L'u'); EXPECT_EQ(readString[2], 55348); @@ -251,7 +233,7 @@ TEST_F(BufferedIndexInputTest, testReadCollection) EXPECT_EQ(readString[7], 56672); EXPECT_EQ(readString[8], L'n'); EXPECT_EQ(readString[9], L'e'); - #else +#else EXPECT_EQ(readString[0], L'L'); EXPECT_EQ(readString[1], L'u'); EXPECT_EQ(readString[2], 119070); @@ -260,7 +242,7 @@ TEST_F(BufferedIndexInputTest, testReadCollection) EXPECT_EQ(readString[5], 119136); EXPECT_EQ(readString[6], L'n'); EXPECT_EQ(readString[7], L'e'); - #endif +#endif readString = indexInput.readString(); EXPECT_EQ(readString[0], 0); @@ -276,8 +258,7 @@ TEST_F(BufferedIndexInputTest, testReadCollection) EXPECT_EQ(readString[7], L'e'); } -TEST_F(BufferedIndexInputTest, testSkipCollection) -{ +TEST_F(BufferedIndexInputTest, testSkipCollection) { ByteArray inputBytes(ByteArray::newInstance(100)); uint8_t input[17] = {0x80, 0x01, 0xff, 0x7f, 0x80, 0x80, 0x01, 0x81, 0x80, 0x01, 0x06, 'L', 'u', 'c', 'e', 'n', 'e'}; std::memcpy(inputBytes.get(), input, 17); @@ -295,54 +276,47 @@ TEST_F(BufferedIndexInputTest, testSkipCollection) } // byten emulates a file - byten(n) returns the n'th byte in that file. -uint8_t byten(int64_t n) -{ +uint8_t byten(int64_t n) { return (uint8_t)(n * n % 256); } -void writeBytes(std::ofstream& file, int64_t size) -{ - for (int64_t i = 0; i < size; ++i) +void writeBytes(std::ofstream& file, int64_t size) { + for (int64_t i = 0; i < size; ++i) { file << byten(i); + } file.flush(); } static const int64_t TEST_FILE_LENGTH = 1024 * 1024; -class MyBufferedIndexInput : public BufferedIndexInput -{ +class MyBufferedIndexInput : public BufferedIndexInput { public: - MyBufferedIndexInput() - { + MyBufferedIndexInput() { this->len = LLONG_MAX; // an infinite file this->pos = 0; } - MyBufferedIndexInput(int64_t len) - { + MyBufferedIndexInput(int64_t len) { this->len = len; this->pos = 0; } protected: - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) - { - for (int32_t i = offset; i < (offset + length); ++i) + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) { + for (int32_t i = offset; i < (offset + length); ++i) { b[i] = byten(pos++); + } } - virtual void seekInternal(int64_t pos) - { + virtual void seekInternal(int64_t pos) { this->pos = pos; } public: - virtual void close() - { + virtual void close() { } - virtual int64_t length() - { + virtual int64_t length() { return len; } @@ -355,15 +329,14 @@ DECLARE_SHARED_PTR(MyBufferedIndexInput) // Call readByte() repeatedly, past the buffer boundary, and see that it is working as expected. // Our input comes from a dynamically generated/ "file" - see MyBufferedIndexInput. -TEST_F(BufferedIndexInputTest, testReadByte) -{ +TEST_F(BufferedIndexInputTest, testReadByte) { MyBufferedIndexInputPtr input(newLucene()); - for (int32_t i = 0; i < BufferedIndexInput::BUFFER_SIZE * 10; ++i) + for (int32_t i = 0; i < BufferedIndexInput::BUFFER_SIZE * 10; ++i) { EXPECT_EQ(input->readByte(), byten(i)); + } } -void checkReadBytes(const IndexInputPtr& input, int32_t size, int32_t pos) -{ +void checkReadBytes(const IndexInputPtr& input, int32_t size, int32_t pos) { // Just to see that "offset" is treated properly in readBytes(), we add an arbitrary offset at // the beginning of the array int32_t offset = size % 10; // arbitrary @@ -371,53 +344,48 @@ void checkReadBytes(const IndexInputPtr& input, int32_t size, int32_t pos) buffer.resize(MiscUtils::getNextSize(offset + size)); EXPECT_EQ(pos, input->getFilePointer()); int64_t left = TEST_FILE_LENGTH - input->getFilePointer(); - if (left <= 0) + if (left <= 0) { return; - else if (left < size) + } else if (left < size) { size = (int32_t)left; + } input->readBytes(buffer.get(), offset, size); EXPECT_EQ(pos + size, input->getFilePointer()); - for (int32_t i = 0; i < size; ++i) + for (int32_t i = 0; i < size; ++i) { EXPECT_EQ(byten(pos + i), buffer[offset + i]); + } } -void runReadBytes(const IndexInputPtr& input, int32_t bufferSize) -{ +void runReadBytes(const IndexInputPtr& input, int32_t bufferSize) { int32_t pos = 0; RandomPtr random = newLucene(); // gradually increasing size - for (int32_t size = 1; size < bufferSize * 10; size = size + size / 200 + 1) - { + for (int32_t size = 1; size < bufferSize * 10; size = size + size / 200 + 1) { checkReadBytes(input, size, pos); pos += size; - if (pos >= TEST_FILE_LENGTH) - { + if (pos >= TEST_FILE_LENGTH) { // wrap pos = 0; input->seek(0); } } // wildly fluctuating size - for (int64_t i = 0; i < 1000; ++i) - { + for (int64_t i = 0; i < 1000; ++i) { int32_t size = random->nextInt(10000); checkReadBytes(input, 1 + size, pos); pos += 1 + size; - if (pos >= TEST_FILE_LENGTH) - { + if (pos >= TEST_FILE_LENGTH) { // wrap pos = 0; input->seek(0); } } // constant small size (7 bytes) - for (int32_t i = 0; i < bufferSize; ++i) - { + for (int32_t i = 0; i < bufferSize; ++i) { checkReadBytes(input, 7, pos); pos += 7; - if (pos >= TEST_FILE_LENGTH) - { + if (pos >= TEST_FILE_LENGTH) { // wrap pos = 0; input->seek(0); @@ -425,15 +393,11 @@ void runReadBytes(const IndexInputPtr& input, int32_t bufferSize) } } -void runReadBytesAndClose(const IndexInputPtr& input, int32_t bufferSize) -{ +void runReadBytesAndClose(const IndexInputPtr& input, int32_t bufferSize) { LuceneException finally; - try - { + try { runReadBytes(input, bufferSize); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } input->close(); @@ -442,8 +406,7 @@ void runReadBytesAndClose(const IndexInputPtr& input, int32_t bufferSize) // Call readBytes() repeatedly, with various chunk sizes (from 1 byte to larger than the buffer size), and see // that it returns the bytes we expect. Our input comes from a dynamically generated "file" - see MyBufferedIndexInput. -TEST_F(BufferedIndexInputTest, testReadBytes) -{ +TEST_F(BufferedIndexInputTest, testReadBytes) { MyBufferedIndexInputPtr input(newLucene()); runReadBytes(input, BufferedIndexInput::BUFFER_SIZE); @@ -463,8 +426,7 @@ TEST_F(BufferedIndexInputTest, testReadBytes) // This tests that attempts to readBytes() past an EOF will fail, while reads up to the EOF will succeed. The // EOF is determined by the BufferedIndexInput's arbitrary length() value. -TEST_F(BufferedIndexInputTest, testEOF) -{ +TEST_F(BufferedIndexInputTest, testEOF) { MyBufferedIndexInputPtr input(newLucene(1024)); // see that we can read all the bytes at one go @@ -476,50 +438,38 @@ TEST_F(BufferedIndexInputTest, testEOF) checkReadBytes(input, 10, pos); input->seek(pos); - try - { + try { checkReadBytes(input, 11, pos); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } input->seek(pos); - try - { + try { checkReadBytes(input, 50, pos); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } input->seek(pos); - try - { + try { checkReadBytes(input, 100000, pos); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::IO)(e)); } } -TEST_F(BufferedIndexInputTest, testSetBufferSize) -{ +TEST_F(BufferedIndexInputTest, testSetBufferSize) { String indexDir(getTempDir(L"testSetBufferSize")); MockFSDirectoryPtr dir = newLucene(indexDir); LuceneException finally; - try - { + try { IndexWriterPtr writer = newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED); writer->setUseCompoundFile(false); - for (int32_t i = 0; i < 37; ++i) - { + for (int32_t i = 0; i < 37; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"content", L"aaa bbb ccc ddd" + StringUtils::toString(i), Field::STORE_YES, Field::INDEX_ANALYZED)); doc->add(newLucene(L"id", StringUtils::toString(i), Field::STORE_YES, Field::INDEX_ANALYZED)); @@ -554,9 +504,7 @@ TEST_F(BufferedIndexInputTest, testSetBufferSize) EXPECT_EQ(hits.size(), 35); searcher->close(); reader->close(); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { finally = e; } FileUtils::removeDirectory(indexDir); diff --git a/src/test/store/BufferedIndexOutputTest.cpp b/src/test/store/BufferedIndexOutputTest.cpp index 05d2f4d5..564a875b 100644 --- a/src/test/store/BufferedIndexOutputTest.cpp +++ b/src/test/store/BufferedIndexOutputTest.cpp @@ -13,23 +13,19 @@ using namespace Lucene; typedef LuceneTestFixture BufferedIndexOutputTest; -class TestableBufferedIndexOutput : public BufferedIndexOutput -{ +class TestableBufferedIndexOutput : public BufferedIndexOutput { public: using BufferedIndexOutput::writeBytes; - TestableBufferedIndexOutput(uint8_t* b, int32_t length) : outputBytes(b), outputLength(length), nextByte(0) - { + TestableBufferedIndexOutput(uint8_t* b, int32_t length) : outputBytes(b), outputLength(length), nextByte(0) { } - virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length) - { + virtual void flushBuffer(const uint8_t* b, int32_t offset, int32_t length) { std::copy(b + offset, b + offset + length, outputBytes + nextByte + offset); nextByte += length; } - virtual int64_t length() - { + virtual int64_t length() { return outputLength; } @@ -39,8 +35,7 @@ class TestableBufferedIndexOutput : public BufferedIndexOutput int32_t nextByte; }; -TEST_F(BufferedIndexOutputTest, testWriteInt) -{ +TEST_F(BufferedIndexOutputTest, testWriteInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeInt(1234); @@ -50,8 +45,7 @@ TEST_F(BufferedIndexOutputTest, testWriteInt) EXPECT_EQ(memcmp(outputBytes.get(), expected, 4), 0); } -TEST_F(BufferedIndexOutputTest, testWriteVInt) -{ +TEST_F(BufferedIndexOutputTest, testWriteVInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVInt(1234); @@ -61,8 +55,7 @@ TEST_F(BufferedIndexOutputTest, testWriteVInt) EXPECT_EQ(memcmp(outputBytes.get(), expected, 2), 0); } -TEST_F(BufferedIndexOutputTest, testWriteLong) -{ +TEST_F(BufferedIndexOutputTest, testWriteLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeLong(1234123412341234LL); @@ -72,8 +65,7 @@ TEST_F(BufferedIndexOutputTest, testWriteLong) EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -TEST_F(BufferedIndexOutputTest, testWriteVLong) -{ +TEST_F(BufferedIndexOutputTest, testWriteVLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVLong(1234123412341234LL); @@ -83,8 +75,7 @@ TEST_F(BufferedIndexOutputTest, testWriteVLong) EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -TEST_F(BufferedIndexOutputTest, testWriteString) -{ +TEST_F(BufferedIndexOutputTest, testWriteString) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeString(L"test string"); @@ -94,8 +85,7 @@ TEST_F(BufferedIndexOutputTest, testWriteString) EXPECT_EQ(memcmp(outputBytes.get(), expected, 12), 0); } -TEST_F(BufferedIndexOutputTest, testWriteChars) -{ +TEST_F(BufferedIndexOutputTest, testWriteChars) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableBufferedIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeChars(L"test string", 5, 6); @@ -105,44 +95,38 @@ TEST_F(BufferedIndexOutputTest, testWriteChars) EXPECT_EQ(memcmp(outputBytes.get(), expected, 6), 0); } -namespace TestCopyBytes -{ - class SourceIndexInput : public BufferedIndexInput - { - public: - SourceIndexInput(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) - { - } - - virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) - { - std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); - nextByte += length; - } - - virtual void seekInternal(int64_t pos) - { - } - - virtual int64_t length() - { - return inputLength; - } - - virtual IndexInputPtr clone() - { - return IndexInputPtr(); - } - - protected: - const uint8_t* inputBytes; - int32_t inputLength; - int32_t nextByte; - }; +namespace TestCopyBytes { + +class SourceIndexInput : public BufferedIndexInput { +public: + SourceIndexInput(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) { + } + + virtual void readInternal(uint8_t* b, int32_t offset, int32_t length) { + std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); + nextByte += length; + } + + virtual void seekInternal(int64_t pos) { + } + + virtual int64_t length() { + return inputLength; + } + + virtual IndexInputPtr clone() { + return IndexInputPtr(); + } + +protected: + const uint8_t* inputBytes; + int32_t inputLength; + int32_t nextByte; +}; + } -TEST_F(BufferedIndexOutputTest, testCopyBytes) -{ +TEST_F(BufferedIndexOutputTest, testCopyBytes) { ByteArray sourceBytes(ByteArray::newInstance(32768)); std::generate(sourceBytes.get(), sourceBytes.get() + 32768, rand); BufferedIndexInputPtr indexSource(newLucene(sourceBytes.get(), 32768)); diff --git a/src/test/store/DirectoryTest.cpp b/src/test/store/DirectoryTest.cpp index 0da450b5..a4f96179 100644 --- a/src/test/store/DirectoryTest.cpp +++ b/src/test/store/DirectoryTest.cpp @@ -21,37 +21,28 @@ using namespace Lucene; typedef LuceneTestFixture DirectoryTest; -TEST_F(DirectoryTest, testDetectDirectoryClose) -{ +TEST_F(DirectoryTest, testDetectDirectoryClose) { RAMDirectoryPtr dir(newLucene()); dir->close(); - try - { + try { dir->createOutput(L"test"); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } } -TEST_F(DirectoryTest, testDetectFSDirectoryClose) -{ +TEST_F(DirectoryTest, testDetectFSDirectoryClose) { DirectoryPtr dir = FSDirectory::open(getTempDir()); dir->close(); - try - { + try { dir->createOutput(L"test"); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::AlreadyClosed)(e)); } } template < class FSDirectory1, class FSDirectory2 > -void TestInstantiationPair(FSDirectory1& first, FSDirectory2& second, const String& fileName, const String& lockName) -{ +void TestInstantiationPair(FSDirectory1& first, FSDirectory2& second, const String& fileName, const String& lockName) { EXPECT_NO_THROW(first.ensureOpen()); IndexOutputPtr out = first.createOutput(fileName); @@ -63,8 +54,7 @@ void TestInstantiationPair(FSDirectory1& first, FSDirectory2& second, const Stri EXPECT_EQ(first.fileLength(fileName), 1); // don't test read on MMapDirectory, since it can't really be closed and will cause a failure to delete the file. - if (!first.isMMapDirectory()) - { + if (!first.isMMapDirectory()) { IndexInputPtr input = first.openInput(fileName); EXPECT_EQ(input->readByte(), 123); EXPECT_NO_THROW(input->close()); @@ -74,8 +64,7 @@ void TestInstantiationPair(FSDirectory1& first, FSDirectory2& second, const Stri EXPECT_TRUE(second.fileExists(fileName)); EXPECT_EQ(second.fileLength(fileName), 1); - if (!second.isMMapDirectory()) - { + if (!second.isMMapDirectory()) { IndexInputPtr input = second.openInput(fileName); EXPECT_EQ(input->readByte(), 123); EXPECT_NO_THROW(input->close()); @@ -91,12 +80,9 @@ void TestInstantiationPair(FSDirectory1& first, FSDirectory2& second, const Stri EXPECT_TRUE(lock->obtain()); LockPtr lock2 = first.makeLock(lockName); - try - { + try { lock2->obtain(1); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } @@ -107,31 +93,33 @@ void TestInstantiationPair(FSDirectory1& first, FSDirectory2& second, const Stri lock->release(); } -namespace TestDirectInstantiation -{ - class TestableSimpleFSDirectory : public SimpleFSDirectory - { - public: - TestableSimpleFSDirectory(const String& path) : SimpleFSDirectory(path) {} - virtual ~TestableSimpleFSDirectory() {} - using SimpleFSDirectory::ensureOpen; - bool isMMapDirectory() { return false; } - }; - - class TestableMMapDirectory : public MMapDirectory - { - public: - TestableMMapDirectory(const String& path) : MMapDirectory(path) {} - virtual ~TestableMMapDirectory() {} - using MMapDirectory::ensureOpen; - bool isMMapDirectory() { return true; } - }; +namespace TestDirectInstantiation { + +class TestableSimpleFSDirectory : public SimpleFSDirectory { +public: + TestableSimpleFSDirectory(const String& path) : SimpleFSDirectory(path) {} + virtual ~TestableSimpleFSDirectory() {} + using SimpleFSDirectory::ensureOpen; + bool isMMapDirectory() { + return false; + } +}; + +class TestableMMapDirectory : public MMapDirectory { +public: + TestableMMapDirectory(const String& path) : MMapDirectory(path) {} + virtual ~TestableMMapDirectory() {} + using MMapDirectory::ensureOpen; + bool isMMapDirectory() { + return true; + } +}; + } // Test that different instances of FSDirectory can coexist on the same // path, can read, write, and lock files. -TEST_F(DirectoryTest, testDirectInstantiation) -{ +TEST_F(DirectoryTest, testDirectInstantiation) { TestDirectInstantiation::TestableSimpleFSDirectory fsDir(getTempDir()); fsDir.ensureOpen(); @@ -142,23 +130,18 @@ TEST_F(DirectoryTest, testDirectInstantiation) TestInstantiationPair(mmapDir, fsDir, L"foo.1", L"foo1.lck"); } -TEST_F(DirectoryTest, testDontCreate) -{ +TEST_F(DirectoryTest, testDontCreate) { String path(FileUtils::joinPath(getTempDir(), L"doesnotexist")); - try - { + try { EXPECT_TRUE(!FileUtils::fileExists(path)); SimpleFSDirectoryPtr fsDir(newLucene(path)); EXPECT_TRUE(!FileUtils::fileExists(path)); - } - catch (...) - { + } catch (...) { } FileUtils::removeDirectory(path); } -void checkDirectoryFilter(const DirectoryPtr& dir) -{ +void checkDirectoryFilter(const DirectoryPtr& dir) { String name(L"file"); dir->createOutput(name)->close(); EXPECT_TRUE(dir->fileExists(name)); @@ -166,53 +149,40 @@ void checkDirectoryFilter(const DirectoryPtr& dir) EXPECT_TRUE(dirFiles.contains(name)); } -TEST_F(DirectoryTest, testRAMDirectoryFilter) -{ +TEST_F(DirectoryTest, testRAMDirectoryFilter) { checkDirectoryFilter(newLucene()); } -TEST_F(DirectoryTest, testFSDirectoryFilter) -{ +TEST_F(DirectoryTest, testFSDirectoryFilter) { checkDirectoryFilter(newLucene(getTempDir())); } -TEST_F(DirectoryTest, testCopySubdir) -{ +TEST_F(DirectoryTest, testCopySubdir) { String path(FileUtils::joinPath(getTempDir(), L"testsubdir")); - try - { + try { FileUtils::createDirectory(path); String subpath(FileUtils::joinPath(path, L"subdir")); FileUtils::createDirectory(subpath); SimpleFSDirectoryPtr fsDir(newLucene(path)); EXPECT_TRUE(newLucene(fsDir)->listAll().empty()); - } - catch (...) - { + } catch (...) { } FileUtils::removeDirectory(path); } -TEST_F(DirectoryTest, testNotDirectory) -{ +TEST_F(DirectoryTest, testNotDirectory) { String path(FileUtils::joinPath(getTempDir(), L"testnotdir")); SimpleFSDirectoryPtr fsDir(newLucene(path)); - try - { + try { IndexOutputPtr out = fsDir->createOutput(L"afile"); out->close(); EXPECT_TRUE(fsDir->fileExists(L"afile")); - try - { + try { newLucene(FileUtils::joinPath(path, L"afile")); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::NoSuchDirectory)(e)); } - } - catch (...) - { + } catch (...) { } FileUtils::removeDirectory(path); } diff --git a/src/test/store/FileSwitchDirectoryTest.cpp b/src/test/store/FileSwitchDirectoryTest.cpp index 57575987..7ed268b9 100644 --- a/src/test/store/FileSwitchDirectoryTest.cpp +++ b/src/test/store/FileSwitchDirectoryTest.cpp @@ -18,8 +18,7 @@ using namespace Lucene; typedef LuceneTestFixture FileSwitchDirectoryTest; -static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t numFields) -{ +static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t numFields) { StringStream buffer; DocumentPtr doc = newLucene(); doc->add(newLucene(L"id", StringUtils::toString(n), Field::STORE_YES, Field::INDEX_NOT_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); @@ -27,22 +26,23 @@ static DocumentPtr createDocument(int32_t n, const String& indexName, int32_t nu buffer << L"a" << n; doc->add(newLucene(L"field1", buffer.str(), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); buffer << L" b" << n; - for (int32_t i = 1; i < numFields; ++i) + for (int32_t i = 1; i < numFields; ++i) { doc->add(newLucene(L"field" + StringUtils::toString(i + 1), buffer.str(), Field::STORE_YES, Field::INDEX_ANALYZED, Field::TERM_VECTOR_WITH_POSITIONS_OFFSETS)); + } return doc; } -static void createIndexNoClose(bool multiSegment, const String& indexName, const IndexWriterPtr& writer) -{ - for (int32_t i = 0; i < 100; ++i) +static void createIndexNoClose(bool multiSegment, const String& indexName, const IndexWriterPtr& writer) { + for (int32_t i = 0; i < 100; ++i) { writer->addDocument(createDocument(i, indexName, 4)); - if (!multiSegment) + } + if (!multiSegment) { writer->optimize(); + } } // Test if writing doc stores to disk and everything else to ram works. -TEST_F(FileSwitchDirectoryTest, testBasic) -{ +TEST_F(FileSwitchDirectoryTest, testBasic) { HashSet fileExtensions(HashSet::newInstance()); fileExtensions.add(L"fdt"); fileExtensions.add(L"fdx"); @@ -60,16 +60,14 @@ TEST_F(FileSwitchDirectoryTest, testBasic) // we should see only fdx,fdt files here HashSet files = primaryDir->listAll(); EXPECT_TRUE(!files.empty()); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - { + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { String ext = FileSwitchDirectory::getExtension(*file); EXPECT_TRUE(fileExtensions.contains(ext)); } files = secondaryDir->listAll(); EXPECT_TRUE(!files.empty()); // we should not see fdx,fdt files here - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) - { + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { String ext = FileSwitchDirectory::getExtension(*file); EXPECT_TRUE(!fileExtensions.contains(ext)); } @@ -77,7 +75,8 @@ TEST_F(FileSwitchDirectoryTest, testBasic) writer->close(); files = fsd->listAll(); - for (HashSet::iterator file = files.begin(); file != files.end(); ++file) + for (HashSet::iterator file = files.begin(); file != files.end(); ++file) { EXPECT_TRUE(!file->empty()); + } fsd->close(); } diff --git a/src/test/store/IndexOutputTest.cpp b/src/test/store/IndexOutputTest.cpp index 238d7e9d..15ff86b1 100644 --- a/src/test/store/IndexOutputTest.cpp +++ b/src/test/store/IndexOutputTest.cpp @@ -13,54 +13,43 @@ using namespace Lucene; typedef LuceneTestFixture IndexOutputTest; -class TestableIndexOutput : public IndexOutput -{ +class TestableIndexOutput : public IndexOutput { public: using IndexOutput::writeBytes; - TestableIndexOutput(uint8_t* b, int32_t length) : outputBytes(b), outputLength(length), nextByte(0) - { + TestableIndexOutput(uint8_t* b, int32_t length) : outputBytes(b), outputLength(length), nextByte(0) { } - virtual ~TestableIndexOutput() - { + virtual ~TestableIndexOutput() { } - virtual void writeByte(uint8_t b) - { + virtual void writeByte(uint8_t b) { outputBytes[nextByte++] = b; } - virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length) - { + virtual void writeBytes(const uint8_t* b, int32_t offset, int32_t length) { std::copy(b + offset, b + offset + length, outputBytes + nextByte + offset); nextByte += length; } - virtual void flush() - { + virtual void flush() { } - virtual void close() - { + virtual void close() { } - virtual int64_t getFilePointer() - { + virtual int64_t getFilePointer() { return 0; } - virtual void seek(int64_t pos) - { + virtual void seek(int64_t pos) { } - virtual int64_t length() - { + virtual int64_t length() { return 0; } - int32_t getNextPosition() - { + int32_t getNextPosition() { return nextByte; } @@ -70,8 +59,7 @@ class TestableIndexOutput : public IndexOutput int32_t nextByte; }; -TEST_F(IndexOutputTest, testWriteInt) -{ +TEST_F(IndexOutputTest, testWriteInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeInt(1234); @@ -80,8 +68,7 @@ TEST_F(IndexOutputTest, testWriteInt) EXPECT_EQ(memcmp(outputBytes.get(), expected, 4), 0); } -TEST_F(IndexOutputTest, testWriteVInt) -{ +TEST_F(IndexOutputTest, testWriteVInt) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVInt(1234); @@ -90,8 +77,7 @@ TEST_F(IndexOutputTest, testWriteVInt) EXPECT_EQ(memcmp(outputBytes.get(), expected, 2), 0); } -TEST_F(IndexOutputTest, testWriteLong) -{ +TEST_F(IndexOutputTest, testWriteLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeLong(1234123412341234LL); @@ -100,8 +86,7 @@ TEST_F(IndexOutputTest, testWriteLong) EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -TEST_F(IndexOutputTest, testWriteVLong) -{ +TEST_F(IndexOutputTest, testWriteVLong) { ByteArray outputBytes(ByteArray::newInstance(10)); TestableIndexOutput indexOutput(outputBytes.get(), 10); indexOutput.writeVLong(1234123412341234LL); @@ -110,8 +95,7 @@ TEST_F(IndexOutputTest, testWriteVLong) EXPECT_EQ(memcmp(outputBytes.get(), expected, 8), 0); } -TEST_F(IndexOutputTest, testWriteString) -{ +TEST_F(IndexOutputTest, testWriteString) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeString(L"test string"); @@ -120,8 +104,7 @@ TEST_F(IndexOutputTest, testWriteString) EXPECT_EQ(memcmp(outputBytes.get(), expected, 12), 0); } -TEST_F(IndexOutputTest, testWriteChars) -{ +TEST_F(IndexOutputTest, testWriteChars) { ByteArray outputBytes(ByteArray::newInstance(30)); TestableIndexOutput indexOutput(outputBytes.get(), 30); indexOutput.writeChars(L"test string", 5, 6); @@ -130,58 +113,49 @@ TEST_F(IndexOutputTest, testWriteChars) EXPECT_EQ(memcmp(outputBytes.get(), expected, 6), 0); } -namespace TestCopyBytes -{ - class SourceIndexInput : public IndexInput - { - public: - SourceIndexInput(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) - { - } - - virtual uint8_t readByte() - { - return 0; - } - - virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) - { - std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); - nextByte += length; - } - - virtual void close() - { - } - - virtual int64_t getFilePointer() - { - return 0; - } - - virtual void seek(int64_t pos) - { - } - - virtual int64_t length() - { - return 0; - } - - virtual IndexInputPtr clone() - { - return IndexInputPtr(); - } - - protected: - const uint8_t* inputBytes; - int32_t inputLength; - int32_t nextByte; - }; +namespace TestCopyBytes { + +class SourceIndexInput : public IndexInput { +public: + SourceIndexInput(const uint8_t* b, int32_t length) : inputBytes(b), inputLength(length), nextByte(0) { + } + + virtual uint8_t readByte() { + return 0; + } + + virtual void readBytes(uint8_t* b, int32_t offset, int32_t length) { + std::copy(inputBytes + nextByte + offset, inputBytes + nextByte + offset + length, b + offset); + nextByte += length; + } + + virtual void close() { + } + + virtual int64_t getFilePointer() { + return 0; + } + + virtual void seek(int64_t pos) { + } + + virtual int64_t length() { + return 0; + } + + virtual IndexInputPtr clone() { + return IndexInputPtr(); + } + +protected: + const uint8_t* inputBytes; + int32_t inputLength; + int32_t nextByte; +}; + } -TEST_F(IndexOutputTest, testCopyBytes) -{ +TEST_F(IndexOutputTest, testCopyBytes) { ByteArray sourceBytes(ByteArray::newInstance(32768)); std::generate(sourceBytes.get(), sourceBytes.get() + 32768, rand); IndexInputPtr indexSource(newLucene(sourceBytes.get(), 32768)); diff --git a/src/test/store/LockFactoryTest.cpp b/src/test/store/LockFactoryTest.cpp index 95191015..88e128a6 100644 --- a/src/test/store/LockFactoryTest.cpp +++ b/src/test/store/LockFactoryTest.cpp @@ -32,8 +32,7 @@ using namespace Lucene; typedef LuceneTestFixture LockFactoryTest; -static void addDoc(const IndexWriterPtr& writer) -{ +static void addDoc(const IndexWriterPtr& writer) { DocumentPtr doc(newLucene()); doc->add(newLucene(L"content", L"aaa", Field::STORE_NO, Field::INDEX_ANALYZED)); writer->addDocument(doc); @@ -41,8 +40,7 @@ static void addDoc(const IndexWriterPtr& writer) // Verify: we can provide our own LockFactory implementation, the right // methods are called at the right time, locks are created, etc. -TEST_F(LockFactoryTest, testCustomLockFactory) -{ +TEST_F(LockFactoryTest, testCustomLockFactory) { DirectoryPtr dir(newLucene()); MockLockFactoryPtr lf(newLucene()); dir->setLockFactory(lf); @@ -53,15 +51,15 @@ TEST_F(LockFactoryTest, testCustomLockFactory) IndexWriterPtr writer(newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); // add 100 documents (so that commit lock is used) - for (int32_t i = 0; i < 100; ++i) + for (int32_t i = 0; i < 100; ++i) { addDoc(writer); + } // Both write lock and commit lock should have been created EXPECT_EQ(lf->locksCreated.size(), 1); // # of unique locks created (after instantiating IndexWriter) EXPECT_TRUE(lf->makeLockCount >= 1); // # calls to makeLock is 0 (after instantiating IndexWriter) - for (MapStringLock::iterator lockName = lf->locksCreated.begin(); lockName != lf->locksCreated.end(); ++lockName) - { + for (MapStringLock::iterator lockName = lf->locksCreated.begin(); lockName != lf->locksCreated.end(); ++lockName) { MockLockPtr lock(boost::dynamic_pointer_cast(lockName->second)); EXPECT_TRUE(lock->lockAttempts > 0); // # calls to Lock.obtain is 0 (after instantiating IndexWriter) } @@ -71,8 +69,7 @@ TEST_F(LockFactoryTest, testCustomLockFactory) // Verify: we can use the NoLockFactory with RAMDirectory with no exceptions raised // Verify: NoLockFactory allows two IndexWriters -TEST_F(LockFactoryTest, testRAMDirectoryNoLocking) -{ +TEST_F(LockFactoryTest, testRAMDirectoryNoLocking) { DirectoryPtr dir(newLucene()); dir->setLockFactory(NoLockFactory::getNoLockFactory()); @@ -86,14 +83,14 @@ TEST_F(LockFactoryTest, testRAMDirectoryNoLocking) EXPECT_NO_THROW(writer2 = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED)); writer->close(); - if (writer2) + if (writer2) { writer2->close(); + } } // Verify: SingleInstanceLockFactory is the default lock for RAMDirectory // Verify: RAMDirectory does basic locking correctly (can't create two IndexWriters) -TEST_F(LockFactoryTest, testDefaultRAMDirectory) -{ +TEST_F(LockFactoryTest, testDefaultRAMDirectory) { DirectoryPtr dir(newLucene()); LockFactoryPtr lockFactory(dir->getLockFactory()); EXPECT_TRUE(boost::dynamic_pointer_cast(lockFactory)); @@ -103,183 +100,145 @@ TEST_F(LockFactoryTest, testDefaultRAMDirectory) IndexWriterPtr writer2; // Create a 2nd IndexWriter - This should fail - try - { + try { writer2 = newLucene(dir, newLucene(), false, IndexWriter::MaxFieldLengthLIMITED); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { EXPECT_TRUE(check_exception(LuceneException::LockObtainFailed)(e)); } writer->close(); - if (writer2) + if (writer2) { writer2->close(); + } } // test string file instantiation -TEST_F(LockFactoryTest, testSimpleFSLockFactory) -{ +TEST_F(LockFactoryTest, testSimpleFSLockFactory) { EXPECT_NO_THROW(newLucene(L"test")); } -namespace LockFactoryTestNS -{ - DECLARE_SHARED_PTR(WriterThread) - DECLARE_SHARED_PTR(LockFactorySearcherThread) - - class WriterThread : public LuceneThread - { - public: - WriterThread(int32_t numIteration, const DirectoryPtr& dir) - { - this->numIteration = numIteration; - this->dir = dir; - this->hitException = false; - } +namespace LockFactoryTestNS { - virtual ~WriterThread() - { - } +DECLARE_SHARED_PTR(WriterThread) +DECLARE_SHARED_PTR(LockFactorySearcherThread) - LUCENE_CLASS(WriterThread); - - public: - bool hitException; - - protected: - DirectoryPtr dir; - int32_t numIteration; - - public: - virtual void run() - { - WhitespaceAnalyzerPtr analyzer = newLucene(); - IndexWriterPtr writer; - for (int32_t i = 0; i < numIteration; ++i) - { - try - { - writer = newLucene(dir, analyzer, false, IndexWriter::MaxFieldLengthLIMITED); - } - catch (IOException& e) - { - if (e.getError().find(L" timed out:") == String::npos) - { - hitException = true; - FAIL() << "Stress Test Index Writer: creation hit unexpected IO exception: " << e.getError(); - break; - } - else - { - // lock obtain timed out - } +class WriterThread : public LuceneThread { +public: + WriterThread(int32_t numIteration, const DirectoryPtr& dir) { + this->numIteration = numIteration; + this->dir = dir; + this->hitException = false; + } + + virtual ~WriterThread() { + } + + LUCENE_CLASS(WriterThread); + +public: + bool hitException; + +protected: + DirectoryPtr dir; + int32_t numIteration; + +public: + virtual void run() { + WhitespaceAnalyzerPtr analyzer = newLucene(); + IndexWriterPtr writer; + for (int32_t i = 0; i < numIteration; ++i) { + try { + writer = newLucene(dir, analyzer, false, IndexWriter::MaxFieldLengthLIMITED); + } catch (IOException& e) { + if (e.getError().find(L" timed out:") == String::npos) { + hitException = true; + FAIL() << "Stress Test Index Writer: creation hit unexpected IO exception: " << e.getError(); + break; + } else { + // lock obtain timed out } - catch (LuceneException& e) - { + } catch (LuceneException& e) { + hitException = true; + FAIL() << "Stress Test Index Writer: creation hit unexpected exception: " << e.getError(); + break; + } + if (writer) { + try { + addDoc(writer); + } catch (LuceneException& e) { hitException = true; - FAIL() << "Stress Test Index Writer: creation hit unexpected exception: " << e.getError(); + FAIL() << "Stress Test Index Writer: addDoc hit unexpected exception: " << e.getError(); break; } - if (writer) - { - try - { - addDoc(writer); - } - catch (LuceneException& e) - { - hitException = true; - FAIL() << "Stress Test Index Writer: addDoc hit unexpected exception: " << e.getError(); - break; - } - try - { - writer->close(); - } - catch (LuceneException& e) - { - hitException = true; - FAIL() << "Stress Test Index Writer: close hit unexpected exception: " << e.getError(); - break; - } + try { + writer->close(); + } catch (LuceneException& e) { + hitException = true; + FAIL() << "Stress Test Index Writer: close hit unexpected exception: " << e.getError(); + break; } } } - }; - - class LockFactorySearcherThread : public LuceneThread - { - public: - LockFactorySearcherThread(int32_t numIteration, const DirectoryPtr& dir) - { - this->numIteration = numIteration; - this->dir = dir; - this->hitException = false; - } + } +}; + +class LockFactorySearcherThread : public LuceneThread { +public: + LockFactorySearcherThread(int32_t numIteration, const DirectoryPtr& dir) { + this->numIteration = numIteration; + this->dir = dir; + this->hitException = false; + } - virtual ~LockFactorySearcherThread() - { - } + virtual ~LockFactorySearcherThread() { + } - LUCENE_CLASS(LockFactorySearcherThread); + LUCENE_CLASS(LockFactorySearcherThread); - public: - bool hitException; +public: + bool hitException; - protected: - DirectoryPtr dir; - int32_t numIteration; +protected: + DirectoryPtr dir; + int32_t numIteration; - public: - virtual void run() - { - IndexSearcherPtr searcher; - QueryPtr query = newLucene(newLucene(L"content", L"aaa")); - for (int32_t i = 0; i < numIteration; ++i) - { - try - { - searcher = newLucene(dir, false); - } - catch (LuceneException& e) - { +public: + virtual void run() { + IndexSearcherPtr searcher; + QueryPtr query = newLucene(newLucene(L"content", L"aaa")); + for (int32_t i = 0; i < numIteration; ++i) { + try { + searcher = newLucene(dir, false); + } catch (LuceneException& e) { + hitException = true; + FAIL() << "Stress Test Index Searcher: creation hit unexpected exception: " << e.getError(); + break; + } + if (searcher) { + Collection hits; + try { + hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; + } catch (LuceneException& e) { hitException = true; - FAIL() << "Stress Test Index Searcher: creation hit unexpected exception: " << e.getError(); + FAIL() << "Stress Test Index Searcher: search hit unexpected exception: " << e.getError(); break; } - if (searcher) - { - Collection hits; - try - { - hits = searcher->search(query, FilterPtr(), 1000)->scoreDocs; - } - catch (LuceneException& e) - { - hitException = true; - FAIL() << "Stress Test Index Searcher: search hit unexpected exception: " << e.getError(); - break; - } - try - { - searcher->close(); - } - catch (LuceneException& e) - { - hitException = true; - FAIL() << "Stress Test Index Searcher: close hit unexpected exception: " << e.getError(); - break; - } + try { + searcher->close(); + } catch (LuceneException& e) { + hitException = true; + FAIL() << "Stress Test Index Searcher: close hit unexpected exception: " << e.getError(); + break; } } } - }; + } +}; + } -static void _testStressLocks(const LockFactoryPtr& lockFactory, const String& indexDir) -{ +static void _testStressLocks(const LockFactoryPtr& lockFactory, const String& indexDir) { FSDirectoryPtr fs1 = FSDirectory::open(indexDir, lockFactory); // First create a 1 doc index @@ -303,22 +262,19 @@ static void _testStressLocks(const LockFactoryPtr& lockFactory, const String& in // Verify: do stress test, by opening IndexReaders and IndexWriters over and over in 2 threads and making sure // no unexpected exceptions are raised -TEST_F(LockFactoryTest, testStressLocks) -{ +TEST_F(LockFactoryTest, testStressLocks) { _testStressLocks(LockFactoryPtr(), getTempDir(L"index.TestLockFactory6")); } // Verify: do stress test, by opening IndexReaders and IndexWriters over and over in 2 threads and making sure // no unexpected exceptions are raised, but use NativeFSLockFactory -TEST_F(LockFactoryTest, testStressLocksNativeFSLockFactory) -{ +TEST_F(LockFactoryTest, testStressLocksNativeFSLockFactory) { String dir(getTempDir(L"index.TestLockFactory7")); _testStressLocks(newLucene(dir), dir); } // Verify: NativeFSLockFactory works correctly -TEST_F(LockFactoryTest, testNativeFSLockFactory) -{ +TEST_F(LockFactoryTest, testNativeFSLockFactory) { NativeFSLockFactoryPtr f(newLucene(getTempDir())); f->setLockPrefix(L"test"); @@ -342,8 +298,7 @@ TEST_F(LockFactoryTest, testNativeFSLockFactory) } // Verify: NativeFSLockFactory works correctly if the lock file exists -TEST_F(LockFactoryTest, testNativeFSLockFactoryLockExists) -{ +TEST_F(LockFactoryTest, testNativeFSLockFactoryLockExists) { String lockFile = getTempDir(L"test.lock"); std::ofstream lockStream; lockStream.open(StringUtils::toUTF8(lockFile).c_str(), std::ios::binary | std::ios::in | std::ios::out); @@ -353,12 +308,12 @@ TEST_F(LockFactoryTest, testNativeFSLockFactoryLockExists) EXPECT_TRUE(l->obtain()); l->release(); EXPECT_TRUE(!l->isLocked()); - if (FileUtils::fileExists(lockFile)) + if (FileUtils::fileExists(lockFile)) { FileUtils::removeFile(lockFile); + } } -TEST_F(LockFactoryTest, testNativeFSLockReleaseByOtherLock) -{ +TEST_F(LockFactoryTest, testNativeFSLockReleaseByOtherLock) { NativeFSLockFactoryPtr f = newLucene(getTempDir()); f->setLockPrefix(L"test"); @@ -368,12 +323,9 @@ TEST_F(LockFactoryTest, testNativeFSLockReleaseByOtherLock) EXPECT_TRUE(l->obtain()); EXPECT_TRUE(l2->isLocked()); - try - { + try { l2->release(); - } - catch (LockReleaseFailedException& e) - { + } catch (LockReleaseFailedException& e) { EXPECT_TRUE(check_exception(LuceneException::LockReleaseFailed)(e)); } @@ -381,8 +333,7 @@ TEST_F(LockFactoryTest, testNativeFSLockReleaseByOtherLock) } // Verify: NativeFSLockFactory assigns null as lockPrefix if the lockDir is inside directory -TEST_F(LockFactoryTest, testNativeFSLockFactoryPrefix) -{ +TEST_F(LockFactoryTest, testNativeFSLockFactoryPrefix) { String fdir1(getTempDir(L"TestLockFactory.8")); String fdir2(getTempDir(L"TestLockFactory.8.Lockdir")); @@ -402,8 +353,7 @@ TEST_F(LockFactoryTest, testNativeFSLockFactoryPrefix) } // Verify: default LockFactory has no prefix (ie write.lock is stored in index) -TEST_F(LockFactoryTest, testDefaultFSLockFactoryPrefix) -{ +TEST_F(LockFactoryTest, testDefaultFSLockFactoryPrefix) { // Make sure we get null prefix String dirName(getTempDir(L"TestLockFactory.10")); DirectoryPtr dir(FSDirectory::open(dirName)); diff --git a/src/test/store/MMapDirectoryTest.cpp b/src/test/store/MMapDirectoryTest.cpp index 05d8f803..afe8d696 100644 --- a/src/test/store/MMapDirectoryTest.cpp +++ b/src/test/store/MMapDirectoryTest.cpp @@ -23,27 +23,26 @@ typedef LuceneTestFixture MMapDirectoryTest; static RandomPtr rndToken = newLucene(); -String randomToken() -{ +String randomToken() { static const wchar_t* alphabet = L"abcdefghijklmnopqrstuvwxyz"; int32_t tl = 1 + rndToken->nextInt(7); StringStream sb; - for (int32_t cx = 0; cx < tl; ++cx) + for (int32_t cx = 0; cx < tl; ++cx) { sb << alphabet[rndToken->nextInt(25)]; + } return sb.str(); } -String randomField() -{ +String randomField() { int32_t fl = 1 + rndToken->nextInt(3); StringStream fb; - for (int32_t fx = 0; fx < fl; ++fx) + for (int32_t fx = 0; fx < fl; ++fx) { fb << randomToken() << L" "; + } return fb.str(); } -TEST_F(MMapDirectoryTest, testMmapIndex) -{ +TEST_F(MMapDirectoryTest, testMmapIndex) { String storePathname(FileUtils::joinPath(getTempDir(), L"testLuceneMmap")); FSDirectoryPtr storeDirectory(newLucene(storePathname)); @@ -54,8 +53,7 @@ TEST_F(MMapDirectoryTest, testMmapIndex) IndexWriterPtr writer = newLucene(storeDirectory, analyzer, true, IndexWriter::MaxFieldLengthLIMITED); IndexSearcherPtr searcher = newLucene(storeDirectory, true); - for (int32_t dx = 0; dx < 1000; ++dx) - { + for (int32_t dx = 0; dx < 1000; ++dx) { String f(randomField()); DocumentPtr doc = newLucene(); doc->add(newLucene(L"data", f, Field::STORE_YES, Field::INDEX_ANALYZED)); diff --git a/src/test/store/MockFSDirectory.cpp b/src/test/store/MockFSDirectory.cpp index ccb15638..99acaa86 100644 --- a/src/test/store/MockFSDirectory.cpp +++ b/src/test/store/MockFSDirectory.cpp @@ -11,81 +11,68 @@ #include "BufferedIndexInput.h" #include "Random.h" -namespace Lucene -{ - MockFSDirectory::MockFSDirectory(const String& path) - { - allIndexInputs = Collection::newInstance(); - lockFactory = newLucene(); - dir = newLucene(path); - rand = newLucene(); - } +namespace Lucene { - MockFSDirectory::~MockFSDirectory() - { - } +MockFSDirectory::MockFSDirectory(const String& path) { + allIndexInputs = Collection::newInstance(); + lockFactory = newLucene(); + dir = newLucene(path); + rand = newLucene(); +} - IndexInputPtr MockFSDirectory::openInput(const String& name) - { - return openInput(name, BufferedIndexInput::BUFFER_SIZE); - } +MockFSDirectory::~MockFSDirectory() { +} - void MockFSDirectory::tweakBufferSizes() - { - for (Collection::iterator ii = allIndexInputs.begin(); ii != allIndexInputs.end(); ++ii) - { - BufferedIndexInputPtr bii(boost::dynamic_pointer_cast(*ii)); - int32_t bufferSize = 1024 + (int32_t)std::abs(rand->nextInt() % 32768); - bii->setBufferSize(bufferSize); - } - } +IndexInputPtr MockFSDirectory::openInput(const String& name) { + return openInput(name, BufferedIndexInput::BUFFER_SIZE); +} - IndexInputPtr MockFSDirectory::openInput(const String& name, int32_t bufferSize) - { - // Make random changes to buffer size - bufferSize = 1 + (int32_t)std::abs(rand->nextInt() % 10); - IndexInputPtr f(dir->openInput(name, bufferSize)); - allIndexInputs.add(f); - return f; +void MockFSDirectory::tweakBufferSizes() { + for (Collection::iterator ii = allIndexInputs.begin(); ii != allIndexInputs.end(); ++ii) { + BufferedIndexInputPtr bii(boost::dynamic_pointer_cast(*ii)); + int32_t bufferSize = 1024 + (int32_t)std::abs(rand->nextInt() % 32768); + bii->setBufferSize(bufferSize); } +} - IndexOutputPtr MockFSDirectory::createOutput(const String& name) - { - return dir->createOutput(name); - } +IndexInputPtr MockFSDirectory::openInput(const String& name, int32_t bufferSize) { + // Make random changes to buffer size + bufferSize = 1 + (int32_t)std::abs(rand->nextInt() % 10); + IndexInputPtr f(dir->openInput(name, bufferSize)); + allIndexInputs.add(f); + return f; +} - void MockFSDirectory::close() - { - dir->close(); - } +IndexOutputPtr MockFSDirectory::createOutput(const String& name) { + return dir->createOutput(name); +} - void MockFSDirectory::deleteFile(const String& name) - { - dir->deleteFile(name); - } +void MockFSDirectory::close() { + dir->close(); +} - void MockFSDirectory::touchFile(const String& name) - { - dir->touchFile(name); - } +void MockFSDirectory::deleteFile(const String& name) { + dir->deleteFile(name); +} - uint64_t MockFSDirectory::fileModified(const String& name) - { - return dir->fileModified(name); - } +void MockFSDirectory::touchFile(const String& name) { + dir->touchFile(name); +} - bool MockFSDirectory::fileExists(const String& name) - { - return dir->fileExists(name); - } +uint64_t MockFSDirectory::fileModified(const String& name) { + return dir->fileModified(name); +} - HashSet MockFSDirectory::listAll() - { - return dir->listAll(); - } +bool MockFSDirectory::fileExists(const String& name) { + return dir->fileExists(name); +} + +HashSet MockFSDirectory::listAll() { + return dir->listAll(); +} + +int64_t MockFSDirectory::fileLength(const String& name) { + return dir->fileLength(name); +} - int64_t MockFSDirectory::fileLength(const String& name) - { - return dir->fileLength(name); - } } diff --git a/src/test/store/MockLock.cpp b/src/test/store/MockLock.cpp index 541b25cf..11bed435 100644 --- a/src/test/store/MockLock.cpp +++ b/src/test/store/MockLock.cpp @@ -7,35 +7,30 @@ #include "TestInc.h" #include "MockLock.h" -namespace Lucene -{ - MockLock::MockLock() - { - lockAttempts = 0; - } - - MockLock::~MockLock() - { - } - - bool MockLock::obtain() - { - ++lockAttempts; - return true; - } - - void MockLock::release() - { - // do nothing - } - - bool MockLock::isLocked() - { - return false; - } - - String MockLock::toString() - { - return L"MockLock"; - } +namespace Lucene { + +MockLock::MockLock() { + lockAttempts = 0; +} + +MockLock::~MockLock() { +} + +bool MockLock::obtain() { + ++lockAttempts; + return true; +} + +void MockLock::release() { + // do nothing +} + +bool MockLock::isLocked() { + return false; +} + +String MockLock::toString() { + return L"MockLock"; +} + } diff --git a/src/test/store/MockLockFactory.cpp b/src/test/store/MockLockFactory.cpp index 7e405001..0c58eb86 100644 --- a/src/test/store/MockLockFactory.cpp +++ b/src/test/store/MockLockFactory.cpp @@ -8,35 +8,31 @@ #include "MockLockFactory.h" #include "MockLock.h" -namespace Lucene -{ - MockLockFactory::MockLockFactory() - { - locksCreated = MapStringLock::newInstance(); - lockPrefixSet = false; - makeLockCount = 0; - } - - MockLockFactory::~MockLockFactory() - { - } - - void MockLockFactory::setLockPrefix(const String& lockPrefix) - { - LockFactory::setLockPrefix(lockPrefix); - lockPrefixSet = true; - } - - LockPtr MockLockFactory::makeLock(const String& lockName) - { - LockPtr lock(newLucene()); - SyncLock createdLock(&locksCreated); - locksCreated.put(lockName, lock); - ++makeLockCount; - return lock; - } - - void MockLockFactory::clearLock(const String& lockName) - { - } +namespace Lucene { + +MockLockFactory::MockLockFactory() { + locksCreated = MapStringLock::newInstance(); + lockPrefixSet = false; + makeLockCount = 0; +} + +MockLockFactory::~MockLockFactory() { +} + +void MockLockFactory::setLockPrefix(const String& lockPrefix) { + LockFactory::setLockPrefix(lockPrefix); + lockPrefixSet = true; +} + +LockPtr MockLockFactory::makeLock(const String& lockName) { + LockPtr lock(newLucene()); + SyncLock createdLock(&locksCreated); + locksCreated.put(lockName, lock); + ++makeLockCount; + return lock; +} + +void MockLockFactory::clearLock(const String& lockName) { +} + } diff --git a/src/test/store/MockRAMDirectory.cpp b/src/test/store/MockRAMDirectory.cpp index 0de025a6..e3509421 100644 --- a/src/test/store/MockRAMDirectory.cpp +++ b/src/test/store/MockRAMDirectory.cpp @@ -13,313 +13,282 @@ #include "Random.h" #include "MiscUtils.h" -namespace Lucene -{ - MockRAMDirectory::MockRAMDirectory() - { - maxSize = 0; - maxUsedSize = 0; - randomIOExceptionRate = 0; - noDeleteOpenFile = true; - preventDoubleWrite = true; - crashed = false; - init(); - } +namespace Lucene { + +MockRAMDirectory::MockRAMDirectory() { + maxSize = 0; + maxUsedSize = 0; + randomIOExceptionRate = 0; + noDeleteOpenFile = true; + preventDoubleWrite = true; + crashed = false; + init(); +} - MockRAMDirectory::MockRAMDirectory(const DirectoryPtr& dir) : RAMDirectory(dir) - { - maxSize = 0; - maxUsedSize = 0; - randomIOExceptionRate = 0; - noDeleteOpenFile = true; - preventDoubleWrite = true; - crashed = false; - init(); - } +MockRAMDirectory::MockRAMDirectory(const DirectoryPtr& dir) : RAMDirectory(dir) { + maxSize = 0; + maxUsedSize = 0; + randomIOExceptionRate = 0; + noDeleteOpenFile = true; + preventDoubleWrite = true; + crashed = false; + init(); +} - MockRAMDirectory::~MockRAMDirectory() - { - } +MockRAMDirectory::~MockRAMDirectory() { +} - void MockRAMDirectory::init() - { - SyncLock syncLock(this); - if (!openFiles) - { - openFiles = MapStringInt::newInstance(); - openFilesDeleted = HashSet::newInstance(); - } - if (!createdFiles) - createdFiles = HashSet::newInstance(); - if (!unSyncedFiles) - unSyncedFiles = HashSet::newInstance(); +void MockRAMDirectory::init() { + SyncLock syncLock(this); + if (!openFiles) { + openFiles = MapStringInt::newInstance(); + openFilesDeleted = HashSet::newInstance(); } - - void MockRAMDirectory::setPreventDoubleWrite(bool value) - { - preventDoubleWrite = value; + if (!createdFiles) { + createdFiles = HashSet::newInstance(); } + if (!unSyncedFiles) { + unSyncedFiles = HashSet::newInstance(); + } +} - void MockRAMDirectory::sync(const String& name) - { - TestScope testScope(L"MockRAMDirectory", L"sync"); - SyncLock syncLock(this); - maybeThrowDeterministicException(); - if (crashed) - boost::throw_exception(IOException(L"cannot sync after crash")); - unSyncedFiles.remove(name); +void MockRAMDirectory::setPreventDoubleWrite(bool value) { + preventDoubleWrite = value; +} + +void MockRAMDirectory::sync(const String& name) { + TestScope testScope(L"MockRAMDirectory", L"sync"); + SyncLock syncLock(this); + maybeThrowDeterministicException(); + if (crashed) { + boost::throw_exception(IOException(L"cannot sync after crash")); } + unSyncedFiles.remove(name); +} - void MockRAMDirectory::crash() - { - SyncLock syncLock(this); - crashed = true; - openFiles = MapStringInt::newInstance(); - openFilesDeleted = HashSet::newInstance(); - HashSet crashFiles(unSyncedFiles); - unSyncedFiles.clear(); - int32_t count = 0; - for (HashSet::iterator it = crashFiles.begin(); it != crashFiles.end(); ++it) - { - RAMFilePtr file(fileMap.get(*it)); - if (count % 3 == 0) - deleteFile(*it, true); - else if (count % 3 == 1) - { - // Zero out file entirely - int32_t numBuffers = file->numBuffers(); - for (int32_t i = 0; i < numBuffers; ++i) - MiscUtils::arrayFill(file->getBuffer(i).get(), 0, file->getBuffer(i).size(), 0); +void MockRAMDirectory::crash() { + SyncLock syncLock(this); + crashed = true; + openFiles = MapStringInt::newInstance(); + openFilesDeleted = HashSet::newInstance(); + HashSet crashFiles(unSyncedFiles); + unSyncedFiles.clear(); + int32_t count = 0; + for (HashSet::iterator it = crashFiles.begin(); it != crashFiles.end(); ++it) { + RAMFilePtr file(fileMap.get(*it)); + if (count % 3 == 0) { + deleteFile(*it, true); + } else if (count % 3 == 1) { + // Zero out file entirely + int32_t numBuffers = file->numBuffers(); + for (int32_t i = 0; i < numBuffers; ++i) { + MiscUtils::arrayFill(file->getBuffer(i).get(), 0, file->getBuffer(i).size(), 0); } - else if (count % 3 == 2) - { - // Truncate the file - file->setLength(file->getLength() / 2); - } - ++count; + } else if (count % 3 == 2) { + // Truncate the file + file->setLength(file->getLength() / 2); } + ++count; } +} - void MockRAMDirectory::clearCrash() - { - SyncLock syncLock(this); - crashed = false; - } +void MockRAMDirectory::clearCrash() { + SyncLock syncLock(this); + crashed = false; +} - void MockRAMDirectory::setMaxSizeInBytes(int64_t maxSize) - { - this->maxSize = maxSize; - } +void MockRAMDirectory::setMaxSizeInBytes(int64_t maxSize) { + this->maxSize = maxSize; +} - int64_t MockRAMDirectory::getMaxSizeInBytes() - { - return maxSize; - } +int64_t MockRAMDirectory::getMaxSizeInBytes() { + return maxSize; +} - int64_t MockRAMDirectory::getMaxUsedSizeInBytes() - { - return maxUsedSize; - } +int64_t MockRAMDirectory::getMaxUsedSizeInBytes() { + return maxUsedSize; +} - void MockRAMDirectory::resetMaxUsedSizeInBytes() - { - maxUsedSize = getRecomputedActualSizeInBytes(); - } +void MockRAMDirectory::resetMaxUsedSizeInBytes() { + maxUsedSize = getRecomputedActualSizeInBytes(); +} - void MockRAMDirectory::setNoDeleteOpenFile(bool value) - { - noDeleteOpenFile = value; - } +void MockRAMDirectory::setNoDeleteOpenFile(bool value) { + noDeleteOpenFile = value; +} - bool MockRAMDirectory::getNoDeleteOpenFile() - { - return noDeleteOpenFile; - } +bool MockRAMDirectory::getNoDeleteOpenFile() { + return noDeleteOpenFile; +} - void MockRAMDirectory::setRandomIOExceptionRate(double rate, int64_t seed) - { - randomIOExceptionRate = rate; - // seed so we have deterministic behaviour - randomState = newLucene(seed); - } +void MockRAMDirectory::setRandomIOExceptionRate(double rate, int64_t seed) { + randomIOExceptionRate = rate; + // seed so we have deterministic behaviour + randomState = newLucene(seed); +} - double MockRAMDirectory::getRandomIOExceptionRate() - { - return randomIOExceptionRate; - } +double MockRAMDirectory::getRandomIOExceptionRate() { + return randomIOExceptionRate; +} - void MockRAMDirectory::maybeThrowIOException() - { - if (randomIOExceptionRate > 0.0) - { - int32_t number = std::abs(randomState->nextInt() % 1000); - if (number < randomIOExceptionRate * 1000) - boost::throw_exception(IOException(L"a random IO exception")); +void MockRAMDirectory::maybeThrowIOException() { + if (randomIOExceptionRate > 0.0) { + int32_t number = std::abs(randomState->nextInt() % 1000); + if (number < randomIOExceptionRate * 1000) { + boost::throw_exception(IOException(L"a random IO exception")); } } +} - void MockRAMDirectory::deleteFile(const String& name) - { - deleteFile(name, false); - } +void MockRAMDirectory::deleteFile(const String& name) { + deleteFile(name, false); +} - void MockRAMDirectory::deleteFile(const String& name, bool forced) - { - TestScope testScope(L"MockRAMDirectory", L"deleteFile"); - SyncLock syncLock(this); - maybeThrowDeterministicException(); +void MockRAMDirectory::deleteFile(const String& name, bool forced) { + TestScope testScope(L"MockRAMDirectory", L"deleteFile"); + SyncLock syncLock(this); + maybeThrowDeterministicException(); - if (crashed && !forced) - boost::throw_exception(IOException(L"cannot delete after crash")); + if (crashed && !forced) { + boost::throw_exception(IOException(L"cannot delete after crash")); + } - unSyncedFiles.remove(name); + unSyncedFiles.remove(name); - if (!forced && noDeleteOpenFile) - { - if (openFiles.contains(name)) - { - openFilesDeleted.add(name); - boost::throw_exception(IOException(L"MockRAMDirectory: file \"" + name + L"\" is still open: cannot delete")); - } - else - openFilesDeleted.remove(name); + if (!forced && noDeleteOpenFile) { + if (openFiles.contains(name)) { + openFilesDeleted.add(name); + boost::throw_exception(IOException(L"MockRAMDirectory: file \"" + name + L"\" is still open: cannot delete")); + } else { + openFilesDeleted.remove(name); } - - RAMDirectory::deleteFile(name); } - HashSet MockRAMDirectory::getOpenDeletedFiles() - { - SyncLock syncLock(this); - HashSet openFilesDeleted = HashSet::newInstance(this->openFilesDeleted.begin(), this->openFilesDeleted.end()); - return openFilesDeleted; - } + RAMDirectory::deleteFile(name); +} - IndexOutputPtr MockRAMDirectory::createOutput(const String& name) - { - SyncLock syncLock(this); - if (crashed) - boost::throw_exception(IOException(L"cannot createOutput after crash")); - init(); - if (preventDoubleWrite && createdFiles.contains(name) && name != L"segments.gen") - boost::throw_exception(IOException(L"file \"" + name + L"\" was already written to")); - if (noDeleteOpenFile && openFiles.contains(name)) - boost::throw_exception(IOException(L"MockRAMDirectory: file \"" + name + L"\" is still open: cannot overwrite")); - RAMFilePtr file(newLucene(shared_from_this())); - if (crashed) - boost::throw_exception(IOException(L"cannot createOutput after crash")); - unSyncedFiles.add(name); - createdFiles.add(name); - RAMFilePtr existing(fileMap.get(name)); - // Enforce write once - if (existing && name != L"segments.gen" && preventDoubleWrite) - boost::throw_exception(IOException(L"file " + name + L" already exists")); - else - { - if (existing) - { - _sizeInBytes -= existing->getSizeInBytes(); - existing->_directory.reset(); - } - fileMap.put(name, file); - } +HashSet MockRAMDirectory::getOpenDeletedFiles() { + SyncLock syncLock(this); + HashSet openFilesDeleted = HashSet::newInstance(this->openFilesDeleted.begin(), this->openFilesDeleted.end()); + return openFilesDeleted; +} - return newLucene(shared_from_this(), file, name); +IndexOutputPtr MockRAMDirectory::createOutput(const String& name) { + SyncLock syncLock(this); + if (crashed) { + boost::throw_exception(IOException(L"cannot createOutput after crash")); + } + init(); + if (preventDoubleWrite && createdFiles.contains(name) && name != L"segments.gen") { + boost::throw_exception(IOException(L"file \"" + name + L"\" was already written to")); + } + if (noDeleteOpenFile && openFiles.contains(name)) { + boost::throw_exception(IOException(L"MockRAMDirectory: file \"" + name + L"\" is still open: cannot overwrite")); + } + RAMFilePtr file(newLucene(shared_from_this())); + if (crashed) { + boost::throw_exception(IOException(L"cannot createOutput after crash")); + } + unSyncedFiles.add(name); + createdFiles.add(name); + RAMFilePtr existing(fileMap.get(name)); + // Enforce write once + if (existing && name != L"segments.gen" && preventDoubleWrite) { + boost::throw_exception(IOException(L"file " + name + L" already exists")); + } else { + if (existing) { + _sizeInBytes -= existing->getSizeInBytes(); + existing->_directory.reset(); + } + fileMap.put(name, file); } - IndexInputPtr MockRAMDirectory::openInput(const String& name) - { - SyncLock syncLock(this); - MapStringRAMFile::iterator file = fileMap.find(name); - if (file == fileMap.end()) - boost::throw_exception(FileNotFoundException(name)); - else - { - MapStringInt::iterator openFile = openFiles.find(name); - if (openFile != openFiles.end()) - ++openFile->second; - else - openFiles.put(name, 1); + return newLucene(shared_from_this(), file, name); +} + +IndexInputPtr MockRAMDirectory::openInput(const String& name) { + SyncLock syncLock(this); + MapStringRAMFile::iterator file = fileMap.find(name); + if (file == fileMap.end()) { + boost::throw_exception(FileNotFoundException(name)); + } else { + MapStringInt::iterator openFile = openFiles.find(name); + if (openFile != openFiles.end()) { + ++openFile->second; + } else { + openFiles.put(name, 1); } - return newLucene(shared_from_this(), name, file->second); } + return newLucene(shared_from_this(), name, file->second); +} - int64_t MockRAMDirectory::getRecomputedSizeInBytes() - { - SyncLock syncLock(this); - int64_t size = 0; - for (MapStringRAMFile::iterator file = fileMap.begin(); file != fileMap.end(); ++file) - size += file->second->getSizeInBytes(); - return size; +int64_t MockRAMDirectory::getRecomputedSizeInBytes() { + SyncLock syncLock(this); + int64_t size = 0; + for (MapStringRAMFile::iterator file = fileMap.begin(); file != fileMap.end(); ++file) { + size += file->second->getSizeInBytes(); } + return size; +} - int64_t MockRAMDirectory::getRecomputedActualSizeInBytes() - { - SyncLock syncLock(this); - int64_t size = 0; - for (MapStringRAMFile::iterator file = fileMap.begin(); file != fileMap.end(); ++file) - size += file->second->length; - return size; +int64_t MockRAMDirectory::getRecomputedActualSizeInBytes() { + SyncLock syncLock(this); + int64_t size = 0; + for (MapStringRAMFile::iterator file = fileMap.begin(); file != fileMap.end(); ++file) { + size += file->second->length; } + return size; +} - void MockRAMDirectory::close() - { - SyncLock syncLock(this); - if (!openFiles) - { - openFiles = MapStringInt::newInstance(); - openFilesDeleted = HashSet::newInstance(); - } - if (noDeleteOpenFile && !openFiles.empty()) - { - // RuntimeException instead of IOException because RAMDirectory does not throw IOException currently - boost::throw_exception(RuntimeException(L"MockRAMDirectory: cannot close: there are still open files")); - } +void MockRAMDirectory::close() { + SyncLock syncLock(this); + if (!openFiles) { + openFiles = MapStringInt::newInstance(); + openFilesDeleted = HashSet::newInstance(); + } + if (noDeleteOpenFile && !openFiles.empty()) { + // RuntimeException instead of IOException because RAMDirectory does not throw IOException currently + boost::throw_exception(RuntimeException(L"MockRAMDirectory: cannot close: there are still open files")); } +} - void MockRAMDirectory::failOn(const MockDirectoryFailurePtr& fail) - { - SyncLock syncLock(this); - if (!failures) - failures = Collection::newInstance(); - failures.add(fail); +void MockRAMDirectory::failOn(const MockDirectoryFailurePtr& fail) { + SyncLock syncLock(this); + if (!failures) { + failures = Collection::newInstance(); } + failures.add(fail); +} - void MockRAMDirectory::maybeThrowDeterministicException() - { - SyncLock syncLock(this); - if (failures) - { - for (Collection::iterator failure = failures.begin(); failure != failures.end(); ++failure) - (*failure)->eval(shared_from_this()); +void MockRAMDirectory::maybeThrowDeterministicException() { + SyncLock syncLock(this); + if (failures) { + for (Collection::iterator failure = failures.begin(); failure != failures.end(); ++failure) { + (*failure)->eval(shared_from_this()); } } +} - MockDirectoryFailure::MockDirectoryFailure() - { - doFail = false; - } +MockDirectoryFailure::MockDirectoryFailure() { + doFail = false; +} - MockDirectoryFailure::~MockDirectoryFailure() - { - } +MockDirectoryFailure::~MockDirectoryFailure() { +} - void MockDirectoryFailure::eval(const MockRAMDirectoryPtr& dir) - { - } +void MockDirectoryFailure::eval(const MockRAMDirectoryPtr& dir) { +} - MockDirectoryFailurePtr MockDirectoryFailure::reset() - { - return shared_from_this(); - } +MockDirectoryFailurePtr MockDirectoryFailure::reset() { + return shared_from_this(); +} - void MockDirectoryFailure::setDoFail() - { - doFail = true; - } +void MockDirectoryFailure::setDoFail() { + doFail = true; +} + +void MockDirectoryFailure::clearDoFail() { + doFail = false; +} - void MockDirectoryFailure::clearDoFail() - { - doFail = false; - } } diff --git a/src/test/store/MockRAMInputStream.cpp b/src/test/store/MockRAMInputStream.cpp index 87a4bc62..67ebb037 100644 --- a/src/test/store/MockRAMInputStream.cpp +++ b/src/test/store/MockRAMInputStream.cpp @@ -8,53 +8,46 @@ #include "MockRAMInputStream.h" #include "MockRAMDirectory.h" -namespace Lucene -{ - MockRAMInputStream::MockRAMInputStream() - { - this->isClone = false; - } +namespace Lucene { - MockRAMInputStream::MockRAMInputStream(const MockRAMDirectoryPtr& dir, const String& name, const RAMFilePtr& f) : RAMInputStream(f) - { - this->isClone = false; - this->name = name; - this->_dir = dir; - } +MockRAMInputStream::MockRAMInputStream() { + this->isClone = false; +} - MockRAMInputStream::~MockRAMInputStream() - { - } +MockRAMInputStream::MockRAMInputStream(const MockRAMDirectoryPtr& dir, const String& name, const RAMFilePtr& f) : RAMInputStream(f) { + this->isClone = false; + this->name = name; + this->_dir = dir; +} - void MockRAMInputStream::close() - { - RAMInputStream::close(); - if (!isClone) - { - MockRAMDirectoryPtr dir(_dir); - SyncLock dirLock(dir); - MapStringInt::iterator openFile = dir->openFiles.find(name); - // Could be null when MockRAMDirectory.crash() was called - if (openFile != dir->openFiles.end()) - { - if (openFile->second == 1) - { - dir->openFiles.remove(name); - dir->openFilesDeleted.remove(name); - } - else - --openFile->second; +MockRAMInputStream::~MockRAMInputStream() { +} + +void MockRAMInputStream::close() { + RAMInputStream::close(); + if (!isClone) { + MockRAMDirectoryPtr dir(_dir); + SyncLock dirLock(dir); + MapStringInt::iterator openFile = dir->openFiles.find(name); + // Could be null when MockRAMDirectory.crash() was called + if (openFile != dir->openFiles.end()) { + if (openFile->second == 1) { + dir->openFiles.remove(name); + dir->openFilesDeleted.remove(name); + } else { + --openFile->second; } } } +} + +LuceneObjectPtr MockRAMInputStream::clone(const LuceneObjectPtr& other) { + LuceneObjectPtr clone = RAMInputStream::clone(other ? other : newLucene()); + MockRAMInputStreamPtr cloneInputStream(boost::dynamic_pointer_cast(clone)); + cloneInputStream->_dir = _dir; + cloneInputStream->name = name; + cloneInputStream->isClone = true; + return cloneInputStream; +} - LuceneObjectPtr MockRAMInputStream::clone(const LuceneObjectPtr& other) - { - LuceneObjectPtr clone = RAMInputStream::clone(other ? other : newLucene()); - MockRAMInputStreamPtr cloneInputStream(boost::dynamic_pointer_cast(clone)); - cloneInputStream->_dir = _dir; - cloneInputStream->name = name; - cloneInputStream->isClone = true; - return cloneInputStream; - } } diff --git a/src/test/store/MockRAMOutputStream.cpp b/src/test/store/MockRAMOutputStream.cpp index 46501db9..e18d549c 100644 --- a/src/test/store/MockRAMOutputStream.cpp +++ b/src/test/store/MockRAMOutputStream.cpp @@ -8,82 +8,76 @@ #include "MockRAMOutputStream.h" #include "MockRAMDirectory.h" -namespace Lucene -{ - MockRAMOutputStream::MockRAMOutputStream(const MockRAMDirectoryPtr& dir, const RAMFilePtr& f, const String& name) : RAMOutputStream(f) - { - this->first = true; - this->singleByte = ByteArray::newInstance(1); - this->_dir = dir; - this->name = name; - } +namespace Lucene { - MockRAMOutputStream::~MockRAMOutputStream() - { - } +MockRAMOutputStream::MockRAMOutputStream(const MockRAMDirectoryPtr& dir, const RAMFilePtr& f, const String& name) : RAMOutputStream(f) { + this->first = true; + this->singleByte = ByteArray::newInstance(1); + this->_dir = dir; + this->name = name; +} - void MockRAMOutputStream::close() - { - RAMOutputStream::close(); - MockRAMDirectoryPtr dir(_dir); +MockRAMOutputStream::~MockRAMOutputStream() { +} - // Now compute actual disk usage & track the maxUsedSize in the MockRAMDirectory - int64_t size = dir->getRecomputedActualSizeInBytes(); - if (size > dir->maxUsedSize) - dir->maxUsedSize = size; - } +void MockRAMOutputStream::close() { + RAMOutputStream::close(); + MockRAMDirectoryPtr dir(_dir); - void MockRAMOutputStream::flush() - { - MockRAMDirectoryPtr(_dir)->maybeThrowDeterministicException(); - RAMOutputStream::flush(); + // Now compute actual disk usage & track the maxUsedSize in the MockRAMDirectory + int64_t size = dir->getRecomputedActualSizeInBytes(); + if (size > dir->maxUsedSize) { + dir->maxUsedSize = size; } +} - void MockRAMOutputStream::writeByte(uint8_t b) - { - singleByte[0] = b; - writeBytes(singleByte.get(), 0, 1); - } +void MockRAMOutputStream::flush() { + MockRAMDirectoryPtr(_dir)->maybeThrowDeterministicException(); + RAMOutputStream::flush(); +} + +void MockRAMOutputStream::writeByte(uint8_t b) { + singleByte[0] = b; + writeBytes(singleByte.get(), 0, 1); +} - void MockRAMOutputStream::writeBytes(const uint8_t* b, int32_t offset, int32_t length) - { - MockRAMDirectoryPtr dir(_dir); - int64_t freeSpace = dir->maxSize - dir->sizeInBytes(); - int64_t realUsage = 0; +void MockRAMOutputStream::writeBytes(const uint8_t* b, int32_t offset, int32_t length) { + MockRAMDirectoryPtr dir(_dir); + int64_t freeSpace = dir->maxSize - dir->sizeInBytes(); + int64_t realUsage = 0; - // If MockRAMDir crashed since we were opened, then don't write anything - if (dir->crashed) - boost::throw_exception(IOException(L"MockRAMDirectory was crashed; cannot write to " + name)); + // If MockRAMDir crashed since we were opened, then don't write anything + if (dir->crashed) { + boost::throw_exception(IOException(L"MockRAMDirectory was crashed; cannot write to " + name)); + } - // Enforce disk full - if (dir->maxSize != 0 && freeSpace <= length) - { - // Compute the real disk free. This will greatly slow down our test but makes it more accurate - realUsage = dir->getRecomputedActualSizeInBytes(); - freeSpace = dir->maxSize - realUsage; - } + // Enforce disk full + if (dir->maxSize != 0 && freeSpace <= length) { + // Compute the real disk free. This will greatly slow down our test but makes it more accurate + realUsage = dir->getRecomputedActualSizeInBytes(); + freeSpace = dir->maxSize - realUsage; + } - if (dir->maxSize != 0 && freeSpace <= length) - { - if (freeSpace > 0 && freeSpace < length) - { - realUsage += freeSpace; - RAMOutputStream::writeBytes(b, offset, (int32_t)freeSpace); - } - if (realUsage > dir->maxUsedSize) - dir->maxUsedSize = realUsage; - boost::throw_exception(IOException(L"fake disk full at " + StringUtils::toString(dir->getRecomputedActualSizeInBytes()) + L" bytes when writing " + name)); + if (dir->maxSize != 0 && freeSpace <= length) { + if (freeSpace > 0 && freeSpace < length) { + realUsage += freeSpace; + RAMOutputStream::writeBytes(b, offset, (int32_t)freeSpace); + } + if (realUsage > dir->maxUsedSize) { + dir->maxUsedSize = realUsage; } - else - RAMOutputStream::writeBytes(b, offset, length); + boost::throw_exception(IOException(L"fake disk full at " + StringUtils::toString(dir->getRecomputedActualSizeInBytes()) + L" bytes when writing " + name)); + } else { + RAMOutputStream::writeBytes(b, offset, length); + } - dir->maybeThrowDeterministicException(); + dir->maybeThrowDeterministicException(); - if (first) - { - // Maybe throw random exception; only do this on first write to a new file - first = false; - dir->maybeThrowIOException(); - } + if (first) { + // Maybe throw random exception; only do this on first write to a new file + first = false; + dir->maybeThrowIOException(); } } + +} diff --git a/src/test/store/RAMDirectoryTest.cpp b/src/test/store/RAMDirectoryTest.cpp index f43e3a37..322a3f0c 100644 --- a/src/test/store/RAMDirectoryTest.cpp +++ b/src/test/store/RAMDirectoryTest.cpp @@ -25,11 +25,9 @@ using namespace Lucene; -class RAMDirectoryTest : public LuceneTestFixture -{ +class RAMDirectoryTest : public LuceneTestFixture { public: - RAMDirectoryTest() - { + RAMDirectoryTest() { indexDir = FileUtils::joinPath(getTempDir(), L"RAMDirIndex"); DirectoryPtr dir(FSDirectory::open(indexDir)); IndexWriterPtr writer(newLucene(dir, newLucene(), true, IndexWriter::MaxFieldLengthLIMITED)); @@ -38,8 +36,7 @@ class RAMDirectoryTest : public LuceneTestFixture docsToAdd = 500; // add some documents - for (int32_t i = 0; i < docsToAdd; ++i) - { + for (int32_t i = 0; i < docsToAdd; ++i) { DocumentPtr doc(newLucene()); doc->add(newLucene(L"content", intToEnglish(i), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); writer->addDocument(doc); @@ -50,8 +47,7 @@ class RAMDirectoryTest : public LuceneTestFixture dir->close(); } - virtual ~RAMDirectoryTest() - { + virtual ~RAMDirectoryTest() { FileUtils::removeDirectory(indexDir); } @@ -60,11 +56,9 @@ class RAMDirectoryTest : public LuceneTestFixture int32_t docsToAdd; }; -class TestRAMDirectoryThread : public LuceneThread -{ +class TestRAMDirectoryThread : public LuceneThread { public: - TestRAMDirectoryThread(const IndexWriterPtr& writer, int32_t num) - { + TestRAMDirectoryThread(const IndexWriterPtr& writer, int32_t num) { this->writer = writer; this->num = num; } @@ -80,18 +74,13 @@ class TestRAMDirectoryThread : public LuceneThread int32_t num; public: - virtual void run() - { - for (int32_t j = 1; j < docsPerThread; ++j) - { + virtual void run() { + for (int32_t j = 1; j < docsPerThread; ++j) { DocumentPtr doc(newLucene()); doc->add(newLucene(L"sizeContent", intToEnglish((num * docsPerThread) + j), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); - try - { + try { writer->addDocument(doc); - } - catch (LuceneException& e) - { + } catch (LuceneException& e) { boost::throw_exception(RuntimeException(e.getError())); } } @@ -104,11 +93,9 @@ const int32_t TestRAMDirectoryThread::docsPerThread = 40; typedef boost::shared_ptr TestRAMDirectoryThreadPtr; /// Fake a huge ram file by using the same byte buffer for all buffers under INT_MAX. -class DenseRAMFile : public RAMFile -{ +class DenseRAMFile : public RAMFile { public: - DenseRAMFile() - { + DenseRAMFile() { capacity = 0; singleBuffers = MapIntByteArray::newInstance(); } @@ -123,15 +110,12 @@ class DenseRAMFile : public RAMFile MapIntByteArray singleBuffers; protected: - virtual ByteArray newBuffer(int32_t size) - { + virtual ByteArray newBuffer(int32_t size) { capacity += size; - if (capacity <= MAX_VALUE) - { + if (capacity <= MAX_VALUE) { // below INT_MAX we reuse buffers ByteArray buf(singleBuffers.get(size)); - if (!buf) - { + if (!buf) { buf = ByteArray::newInstance(size); singleBuffers.put(size, buf); } @@ -145,8 +129,7 @@ const int64_t DenseRAMFile::MAX_VALUE = 2 * (int64_t)INT_MAX; typedef boost::shared_ptr DenseRAMFilePtr; -TEST_F(RAMDirectoryTest, testRAMDirectory) -{ +TEST_F(RAMDirectoryTest, testRAMDirectory) { DirectoryPtr dir(FSDirectory::open(indexDir)); MockRAMDirectoryPtr ramDir(newLucene(dir)); @@ -164,8 +147,7 @@ TEST_F(RAMDirectoryTest, testRAMDirectory) IndexSearcherPtr searcher = newLucene(reader); // search for all documents - for (int32_t i = 0; i < docsToAdd; ++i) - { + for (int32_t i = 0; i < docsToAdd; ++i) { DocumentPtr doc = searcher->doc(i); EXPECT_TRUE(doc->getField(L"content")); } @@ -175,8 +157,7 @@ TEST_F(RAMDirectoryTest, testRAMDirectory) searcher->close(); } -TEST_F(RAMDirectoryTest, testRAMDirectorySize) -{ +TEST_F(RAMDirectoryTest, testRAMDirectorySize) { DirectoryPtr dir(FSDirectory::open(indexDir)); MockRAMDirectoryPtr ramDir(newLucene(dir)); dir->close(); @@ -187,13 +168,16 @@ TEST_F(RAMDirectoryTest, testRAMDirectorySize) EXPECT_EQ(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); Collection threads(Collection::newInstance(TestRAMDirectoryThread::numThreads)); - for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) + for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) { threads[i] = newLucene(writer, i); + } - for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) + for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) { threads[i]->start(); - for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) + } + for (int32_t i = 0; i < TestRAMDirectoryThread::numThreads; ++i) { threads[i]->join(); + } writer->optimize(); EXPECT_EQ(ramDir->sizeInBytes(), ramDir->getRecomputedSizeInBytes()); @@ -201,8 +185,7 @@ TEST_F(RAMDirectoryTest, testRAMDirectorySize) writer->close(); } -TEST_F(RAMDirectoryTest, testIllegalEOF) -{ +TEST_F(RAMDirectoryTest, testIllegalEOF) { RAMDirectoryPtr dir(newLucene()); IndexOutputPtr o(dir->createOutput(L"out")); ByteArray b(ByteArray::newInstance(1024)); @@ -215,8 +198,7 @@ TEST_F(RAMDirectoryTest, testIllegalEOF) } /// Test huge RAMFile with more than INT_MAX bytes. -TEST_F(RAMDirectoryTest, testHugeFile) -{ +TEST_F(RAMDirectoryTest, testHugeFile) { DenseRAMFilePtr f(newLucene()); // output part @@ -224,14 +206,15 @@ TEST_F(RAMDirectoryTest, testHugeFile) ByteArray b1(ByteArray::newInstance(RAMOutputStream::BUFFER_SIZE)); ByteArray b2(ByteArray::newInstance(RAMOutputStream::BUFFER_SIZE / 3)); - for (int32_t i = 0; i < b1.size(); ++i) + for (int32_t i = 0; i < b1.size(); ++i) { b1[i] = (uint8_t)(i & 0x0007f); - for (int32_t i = 0; i < b2.size(); ++i) + } + for (int32_t i = 0; i < b2.size(); ++i) { b2[i] = (uint8_t)(i & 0x0003f); + } int64_t n = 0; EXPECT_EQ(n, out->length()); // output length must match - while (n <= DenseRAMFile::MAX_VALUE - b1.size()) - { + while (n <= DenseRAMFile::MAX_VALUE - b1.size()) { out->writeBytes(b1.get(), 0, b1.size()); out->flush(); n += b1.size(); @@ -239,10 +222,10 @@ TEST_F(RAMDirectoryTest, testHugeFile) } int32_t m = b2.size(); int64_t l = 12; - for (int32_t j = 0; j < l; ++j) - { - for (int32_t i = 0; i < b2.size(); ++i) + for (int32_t j = 0; j < l; ++j) { + for (int32_t i = 0; i < b2.size(); ++i) { b2[i]++; + } out->writeBytes(b2.get(), 0, m); out->flush(); @@ -253,13 +236,11 @@ TEST_F(RAMDirectoryTest, testHugeFile) // input part RAMInputStreamPtr in(newLucene(f)); EXPECT_EQ(n, in->length()); // input length must match - for (int32_t j = 0; j < l; ++j) - { + for (int32_t j = 0; j < l; ++j) { int64_t loc = n - (l - j) * m; in->seek(loc / 3); in->seek(loc); - for (int32_t i = 0; i < m; ++i) - { + for (int32_t i = 0; i < m; ++i) { uint8_t bt = in->readByte(); uint8_t expected = (uint8_t)(1 + j + (i & 0x0003f)); EXPECT_EQ(expected, bt); // must read same value that was written diff --git a/src/test/util/AttributeSourceTest.cpp b/src/test/util/AttributeSourceTest.cpp index 40e1ab8f..f375aaa9 100644 --- a/src/test/util/AttributeSourceTest.cpp +++ b/src/test/util/AttributeSourceTest.cpp @@ -19,8 +19,7 @@ using namespace Lucene; typedef LuceneTestFixture AttributeSourceTest; -TEST_F(AttributeSourceTest, testCaptureState) -{ +TEST_F(AttributeSourceTest, testCaptureState) { // init a first instance AttributeSourcePtr src = newLucene(); TermAttributePtr termAtt = src->addAttribute(); @@ -64,18 +63,14 @@ TEST_F(AttributeSourceTest, testCaptureState) // init a third instance missing one Attribute AttributeSourcePtr src3 = newLucene(); termAtt = src3->addAttribute(); - try - { + try { src3->restoreState(state); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } -TEST_F(AttributeSourceTest, testCloneAttributes) -{ +TEST_F(AttributeSourceTest, testCloneAttributes) { AttributeSourcePtr src = newLucene(); TermAttributePtr termAtt = src->addAttribute(); TypeAttributePtr typeAtt = src->addAttribute(); @@ -96,8 +91,7 @@ TEST_F(AttributeSourceTest, testCloneAttributes) EXPECT_TRUE(typeAtt2->equals(typeAtt)); } -TEST_F(AttributeSourceTest, testToStringAndMultiAttributeImplementations) -{ +TEST_F(AttributeSourceTest, testToStringAndMultiAttributeImplementations) { AttributeSourcePtr src = newLucene(); TermAttributePtr termAtt = src->addAttribute(); TypeAttributePtr typeAtt = src->addAttribute(); @@ -111,8 +105,7 @@ TEST_F(AttributeSourceTest, testToStringAndMultiAttributeImplementations) EXPECT_TRUE(attributes[1]->equals(typeAtt)); } -TEST_F(AttributeSourceTest, testDefaultAttributeFactory) -{ +TEST_F(AttributeSourceTest, testDefaultAttributeFactory) { AttributeSourcePtr src = newLucene(); EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); EXPECT_TRUE(MiscUtils::typeOf(src->addAttribute())); diff --git a/src/test/util/Base64Test.cpp b/src/test/util/Base64Test.cpp index 968850b1..861e85df 100644 --- a/src/test/util/Base64Test.cpp +++ b/src/test/util/Base64Test.cpp @@ -13,15 +13,13 @@ using namespace Lucene; typedef LuceneTestFixture Base64Test; -TEST_F(Base64Test, testEncodeSmall) -{ +TEST_F(Base64Test, testEncodeSmall) { SingleString testBinary = "this is test binary"; String encode = Base64::encode((uint8_t*)testBinary.c_str(), testBinary.length()); EXPECT_EQ(encode, L"dGhpcyBpcyB0ZXN0IGJpbmFyeQ=="); } -TEST_F(Base64Test, testEncodeLarge) -{ +TEST_F(Base64Test, testEncodeLarge) { SingleString testBinary = "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64 " "This is a larger test string that should convert into base64 " @@ -39,16 +37,14 @@ TEST_F(Base64Test, testEncodeLarge) EXPECT_EQ(encode, expected); } -TEST_F(Base64Test, testDecodeSmall) -{ +TEST_F(Base64Test, testDecodeSmall) { String testString = L"dGhpcyBpcyB0ZXN0IGJpbmFyeQ=="; ByteArray decode = Base64::decode(testString); SingleString decodeBinary((char*)decode.get(), decode.size()); EXPECT_EQ(decodeBinary, "this is test binary"); } -TEST_F(Base64Test, testDecodeLaarge) -{ +TEST_F(Base64Test, testDecodeLaarge) { String testString = L"VGhpcyBpcyBhIGxhcmdlciB0ZXN0IHN0cmluZyB0aGF0IHNob3VsZCBjb252ZXJ0IGludG8gYmFz" L"ZTY0IFRoaXMgaXMgYSBsYXJnZXIgdGVzdCBzdHJpbmcgdGhhdCBzaG91bGQgY29udmVydCBpbnRv" L"IGJhc2U2NCBUaGlzIGlzIGEgbGFyZ2VyIHRlc3Qgc3RyaW5nIHRoYXQgc2hvdWxkIGNvbnZlcnQg" diff --git a/src/test/util/BitVectorTest.cpp b/src/test/util/BitVectorTest.cpp index 0355ec84..68d3ef4a 100644 --- a/src/test/util/BitVectorTest.cpp +++ b/src/test/util/BitVectorTest.cpp @@ -15,37 +15,32 @@ typedef LuceneTestFixture BitVectorTest; static const int32_t subsetPattern[] = {1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1}; -static bool compareBitVectors(const BitVectorPtr& bv, const BitVectorPtr& compare) -{ - for (int32_t i = 0; i < bv->size(); ++i) - { +static bool compareBitVectors(const BitVectorPtr& bv, const BitVectorPtr& compare) { + for (int32_t i = 0; i < bv->size(); ++i) { // bits must be equal - if (bv->get(i) != compare->get(i)) + if (bv->get(i) != compare->get(i)) { return false; + } } return true; } -static void doTestConstructOfSize(int32_t n) -{ +static void doTestConstructOfSize(int32_t n) { BitVectorPtr bv = newLucene(n); EXPECT_EQ(n, bv->size()); } /// Test the default constructor on BitVectors of various sizes. -TEST_F(BitVectorTest, testConstructSize) -{ +TEST_F(BitVectorTest, testConstructSize) { doTestConstructOfSize(8); doTestConstructOfSize(20); doTestConstructOfSize(100); doTestConstructOfSize(1000); } -static void doTestGetSetVectorOfSize(int32_t n) -{ +static void doTestGetSetVectorOfSize(int32_t n) { BitVectorPtr bv = newLucene(n); - for (int32_t i = 0; i < bv->size(); ++i) - { + for (int32_t i = 0; i < bv->size(); ++i) { EXPECT_TRUE(!bv->get(i)); bv->set(i); EXPECT_TRUE(bv->get(i)); @@ -53,19 +48,16 @@ static void doTestGetSetVectorOfSize(int32_t n) } /// Test the get() and set() methods on BitVectors of various sizes. -TEST_F(BitVectorTest, testGetSet) -{ +TEST_F(BitVectorTest, testGetSet) { doTestGetSetVectorOfSize(8); doTestGetSetVectorOfSize(20); doTestGetSetVectorOfSize(100); doTestGetSetVectorOfSize(1000); } -static void doTestClearVectorOfSize(int32_t n) -{ +static void doTestClearVectorOfSize(int32_t n) { BitVectorPtr bv = newLucene(n); - for (int32_t i = 0; i < bv->size(); ++i) - { + for (int32_t i = 0; i < bv->size(); ++i) { EXPECT_TRUE(!bv->get(i)); bv->set(i); EXPECT_TRUE(bv->get(i)); @@ -75,20 +67,17 @@ static void doTestClearVectorOfSize(int32_t n) } /// Test the clear() method on BitVectors of various sizes. -TEST_F(BitVectorTest, testClear) -{ +TEST_F(BitVectorTest, testClear) { doTestClearVectorOfSize(8); doTestClearVectorOfSize(20); doTestClearVectorOfSize(100); doTestClearVectorOfSize(1000); } -static void doTestCountVectorOfSize(int32_t n) -{ +static void doTestCountVectorOfSize(int32_t n) { BitVectorPtr bv = newLucene(n); // test count when incrementally setting bits - for (int32_t i = 0; i < bv->size(); ++i) - { + for (int32_t i = 0; i < bv->size(); ++i) { EXPECT_TRUE(!bv->get(i)); EXPECT_EQ(i, bv->count()); bv->set(i); @@ -98,8 +87,7 @@ static void doTestCountVectorOfSize(int32_t n) bv = newLucene(n); // test count when setting then clearing bits - for (int32_t i = 0; i < bv->size(); ++i) - { + for (int32_t i = 0; i < bv->size(); ++i) { EXPECT_TRUE(!bv->get(i)); EXPECT_EQ(0, bv->count()); bv->set(i); @@ -112,21 +100,18 @@ static void doTestCountVectorOfSize(int32_t n) } /// Test the count() method on BitVectors of various sizes. -TEST_F(BitVectorTest, testCount) -{ +TEST_F(BitVectorTest, testCount) { doTestCountVectorOfSize(8); doTestCountVectorOfSize(20); doTestCountVectorOfSize(100); doTestCountVectorOfSize(1000); } -static void doTestWriteRead(int32_t n) -{ +static void doTestWriteRead(int32_t n) { DirectoryPtr d = newLucene(); BitVectorPtr bv = newLucene(n); // test count when incrementally setting bits - for (int32_t i = 0; i < bv->size(); ++i) - { + for (int32_t i = 0; i < bv->size(); ++i) { EXPECT_TRUE(!bv->get(i)); EXPECT_EQ(i, bv->count()); bv->set(i); @@ -140,27 +125,23 @@ static void doTestWriteRead(int32_t n) } /// Test writing and construction to/from Directory. -TEST_F(BitVectorTest, testWriteRead) -{ +TEST_F(BitVectorTest, testWriteRead) { doTestWriteRead(8); doTestWriteRead(20); doTestWriteRead(100); doTestWriteRead(1000); } -static void doTestDgaps(int32_t size, int32_t count1, int32_t count2) -{ +static void doTestDgaps(int32_t size, int32_t count1, int32_t count2) { DirectoryPtr d = newLucene(); BitVectorPtr bv = newLucene(size); - for (int32_t i = 0; i < count1; ++i) - { + for (int32_t i = 0; i < count1; ++i) { bv->set(i); EXPECT_EQ(i + 1, bv->count()); } bv->write(d, L"TESTBV"); // gradually increase number of set bits - for (int32_t i = count1; i < count2; ++i) - { + for (int32_t i = count1; i < count2; ++i) { BitVectorPtr bv2 = newLucene(d, L"TESTBV"); EXPECT_TRUE(compareBitVectors(bv, bv2)); bv = bv2; @@ -169,8 +150,7 @@ static void doTestDgaps(int32_t size, int32_t count1, int32_t count2) bv->write(d, L"TESTBV"); } // now start decreasing number of set bits - for (int32_t i = count2 - 1; i >= count1; --i) - { + for (int32_t i = count2 - 1; i >= count1; --i) { BitVectorPtr bv2 = newLucene(d, L"TESTBV"); EXPECT_TRUE(compareBitVectors(bv, bv2)); bv = bv2; @@ -181,8 +161,7 @@ static void doTestDgaps(int32_t size, int32_t count1, int32_t count2) } /// Test r/w when size/count cause switching between bit-set and d-gaps file formats. -TEST_F(BitVectorTest, testDgaps) -{ +TEST_F(BitVectorTest, testDgaps) { doTestDgaps(1, 0, 1); doTestDgaps(10, 0, 1); doTestDgaps(100, 0, 1); @@ -192,41 +171,36 @@ TEST_F(BitVectorTest, testDgaps) doTestDgaps(1000000, 3123, 3126); } -static BitVectorPtr createSubsetTestVector() -{ +static BitVectorPtr createSubsetTestVector() { int32_t length = SIZEOF_ARRAY(subsetPattern); BitVectorPtr bv = newLucene(length); - for (int32_t i = 0; i < length; ++i) - { - if (subsetPattern[i] == 1) + for (int32_t i = 0; i < length; ++i) { + if (subsetPattern[i] == 1) { bv->set(i); + } } return bv; } /// Compare a subset against the corresponding portion of the test pattern -static void doTestSubset(int32_t start, int32_t end) -{ +static void doTestSubset(int32_t start, int32_t end) { BitVectorPtr full = createSubsetTestVector(); BitVectorPtr subset = full->subset(start, end); EXPECT_EQ(end - start, subset->size()); int32_t count = 0; - for (int32_t i = start, j = 0; i < end; ++i, ++j) - { - if (subsetPattern[i] == 1) - { + for (int32_t i = start, j = 0; i < end; ++i, ++j) { + if (subsetPattern[i] == 1) { ++count; EXPECT_TRUE(subset->get(j)); - } - else + } else { EXPECT_TRUE(!subset->get(j)); + } } EXPECT_EQ(count, subset->count()); } /// Tests BitVector.subset() against a pattern -TEST_F(BitVectorTest, testSubset) -{ +TEST_F(BitVectorTest, testSubset) { doTestSubset(0, 0); doTestSubset(0, 20); doTestSubset(0, 7); diff --git a/src/test/util/BufferedReaderTest.cpp b/src/test/util/BufferedReaderTest.cpp index f70cc56c..0e262c28 100644 --- a/src/test/util/BufferedReaderTest.cpp +++ b/src/test/util/BufferedReaderTest.cpp @@ -16,8 +16,7 @@ using namespace Lucene; typedef LuceneTestFixture BufferedReaderTest; -TEST_F(BufferedReaderTest, testBufferedReaderChar) -{ +TEST_F(BufferedReaderTest, testBufferedReaderChar) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); EXPECT_EQ((wchar_t)reader->read(), L't'); EXPECT_EQ((wchar_t)reader->read(), L'e'); @@ -30,8 +29,7 @@ TEST_F(BufferedReaderTest, testBufferedReaderChar) EXPECT_EQ((wchar_t)reader->read(), L'e'); } -TEST_F(BufferedReaderTest, testBufferedReaderRead) -{ +TEST_F(BufferedReaderTest, testBufferedReaderRead) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); wchar_t buffer[80]; @@ -44,15 +42,15 @@ TEST_F(BufferedReaderTest, testBufferedReaderRead) EXPECT_EQ(reader->read(buffer, 0, 1), FileReader::FILE_EOF); } -TEST_F(BufferedReaderTest, testBufferedReaderReadLine) -{ +TEST_F(BufferedReaderTest, testBufferedReaderReadLine) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); Collection readLines = Collection::newInstance(); String line; - while (reader->readLine(line)) + while (reader->readLine(line)) { readLines.add(line); + } EXPECT_EQ(reader->read(), FileReader::FILE_EOF); EXPECT_EQ(readLines.size(), 6); @@ -64,8 +62,7 @@ TEST_F(BufferedReaderTest, testBufferedReaderReadLine) EXPECT_EQ(readLines[5], L"1 2 3 4"); } -TEST_F(BufferedReaderTest, testBufferedReaderReset) -{ +TEST_F(BufferedReaderTest, testBufferedReaderReset) { BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); wchar_t buffer[20]; @@ -76,8 +73,7 @@ TEST_F(BufferedReaderTest, testBufferedReaderReset) EXPECT_EQ(String(buffer, 9), L"test file"); } -TEST_F(BufferedReaderTest, testBufferedReaderCharsSmallBuffer) -{ +TEST_F(BufferedReaderTest, testBufferedReaderCharsSmallBuffer) { static const int32_t bufferSize = 5; BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); @@ -93,8 +89,7 @@ TEST_F(BufferedReaderTest, testBufferedReaderCharsSmallBuffer) EXPECT_EQ((wchar_t)reader->read(), L'e'); } -TEST_F(BufferedReaderTest, testBufferedReaderReadSmallBuffer) -{ +TEST_F(BufferedReaderTest, testBufferedReaderReadSmallBuffer) { static const int32_t bufferSize = 5; BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); @@ -109,8 +104,7 @@ TEST_F(BufferedReaderTest, testBufferedReaderReadSmallBuffer) EXPECT_EQ(reader->read(buffer, 0, 1), FileReader::FILE_EOF); } -TEST_F(BufferedReaderTest, testBufferedReaderResetSmallBuffer) -{ +TEST_F(BufferedReaderTest, testBufferedReaderResetSmallBuffer) { static const int32_t bufferSize = 5; BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); @@ -123,8 +117,7 @@ TEST_F(BufferedReaderTest, testBufferedReaderResetSmallBuffer) EXPECT_EQ(String(buffer, 9), L"test file"); } -TEST_F(BufferedReaderTest, testBufferedReaderReadLineSmallBuffer) -{ +TEST_F(BufferedReaderTest, testBufferedReaderReadLineSmallBuffer) { static const int32_t bufferSize = 5; BufferedReaderPtr reader = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")), bufferSize); @@ -132,8 +125,9 @@ TEST_F(BufferedReaderTest, testBufferedReaderReadLineSmallBuffer) Collection readLines = Collection::newInstance(); String line; - while (reader->readLine(line)) + while (reader->readLine(line)) { readLines.add(line); + } EXPECT_EQ(reader->read(), FileReader::FILE_EOF); EXPECT_EQ(readLines.size(), 6); diff --git a/src/test/util/CloseableThreadLocalTest.cpp b/src/test/util/CloseableThreadLocalTest.cpp index ea07acd7..0bd9e8d7 100644 --- a/src/test/util/CloseableThreadLocalTest.cpp +++ b/src/test/util/CloseableThreadLocalTest.cpp @@ -14,18 +14,14 @@ typedef LuceneTestFixture CloseableThreadLocalTest; static const String TEST_VALUE = L"initvaluetest"; -TEST_F(CloseableThreadLocalTest, testInitValue) -{ - class InitValueThreadLocal : public CloseableThreadLocal - { +TEST_F(CloseableThreadLocalTest, testInitValue) { + class InitValueThreadLocal : public CloseableThreadLocal { public: - virtual ~InitValueThreadLocal() - { + virtual ~InitValueThreadLocal() { } protected: - virtual boost::shared_ptr initialValue() - { + virtual boost::shared_ptr initialValue() { return newInstance(TEST_VALUE); } }; @@ -36,16 +32,14 @@ TEST_F(CloseableThreadLocalTest, testInitValue) } /// Tests that null can be set as a valid value. -TEST_F(CloseableThreadLocalTest, testNullValue) -{ +TEST_F(CloseableThreadLocalTest, testNullValue) { CloseableThreadLocal ctl; ctl.set(boost::shared_ptr()); EXPECT_TRUE(!ctl.get()); } /// Make sure default get returns null, twice in a row -TEST_F(CloseableThreadLocalTest, testDefaultValueWithoutSetting) -{ +TEST_F(CloseableThreadLocalTest, testDefaultValueWithoutSetting) { CloseableThreadLocal ctl; EXPECT_TRUE(!ctl.get()); EXPECT_TRUE(!ctl.get()); diff --git a/src/test/util/CompressionToolsTest.cpp b/src/test/util/CompressionToolsTest.cpp index a164f217..6de124c6 100644 --- a/src/test/util/CompressionToolsTest.cpp +++ b/src/test/util/CompressionToolsTest.cpp @@ -12,8 +12,7 @@ using namespace Lucene; typedef LuceneTestFixture CompressionToolsTest; -TEST_F(CompressionToolsTest, testCompressDecompress) -{ +TEST_F(CompressionToolsTest, testCompressDecompress) { ByteArray compress(CompressionTools::compressString(L"test compressed string")); EXPECT_TRUE(compress.size() > 0); diff --git a/src/test/util/FieldCacheSanityCheckerTest.cpp b/src/test/util/FieldCacheSanityCheckerTest.cpp index dc968a66..a0757e6c 100644 --- a/src/test/util/FieldCacheSanityCheckerTest.cpp +++ b/src/test/util/FieldCacheSanityCheckerTest.cpp @@ -19,11 +19,9 @@ using namespace Lucene; -class FieldCacheSanityCheckerTest : public LuceneTestFixture -{ +class FieldCacheSanityCheckerTest : public LuceneTestFixture { public: - FieldCacheSanityCheckerTest() - { + FieldCacheSanityCheckerTest() { RAMDirectoryPtr dirA = newLucene(); RAMDirectoryPtr dirB = newLucene(); @@ -34,17 +32,17 @@ class FieldCacheSanityCheckerTest : public LuceneTestFixture double theDouble = DBL_MAX; uint8_t theByte = UCHAR_MAX; int32_t theInt = INT_MAX; - for (int32_t i = 0; i < NUM_DOCS; ++i) - { + for (int32_t i = 0; i < NUM_DOCS; ++i) { DocumentPtr doc = newLucene(); doc->add(newLucene(L"theLong", StringUtils::toString(theLong--), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"theDouble", StringUtils::toString(theDouble--), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"theByte", StringUtils::toString(theByte--), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); doc->add(newLucene(L"theInt", StringUtils::toString(theInt--), Field::STORE_NO, Field::INDEX_NOT_ANALYZED)); - if (i % 3 == 0) + if (i % 3 == 0) { wA->addDocument(doc); - else + } else { wB->addDocument(doc); + } } wA->close(); wB->close(); @@ -53,8 +51,7 @@ class FieldCacheSanityCheckerTest : public LuceneTestFixture readerX = newLucene(newCollection(readerA, readerB)); } - virtual ~FieldCacheSanityCheckerTest() - { + virtual ~FieldCacheSanityCheckerTest() { readerA->close(); readerB->close(); readerX->close(); @@ -70,8 +67,7 @@ class FieldCacheSanityCheckerTest : public LuceneTestFixture const int32_t FieldCacheSanityCheckerTest::NUM_DOCS = 1000; -TEST_F(FieldCacheSanityCheckerTest, testSanity) -{ +TEST_F(FieldCacheSanityCheckerTest, testSanity) { FieldCachePtr cache = FieldCache::DEFAULT(); cache->purgeAllCaches(); @@ -88,8 +84,7 @@ TEST_F(FieldCacheSanityCheckerTest, testSanity) cache->purgeAllCaches(); } -TEST_F(FieldCacheSanityCheckerTest, testInsanity1) -{ +TEST_F(FieldCacheSanityCheckerTest, testInsanity1) { FieldCachePtr cache = FieldCache::DEFAULT(); cache->purgeAllCaches(); @@ -109,8 +104,7 @@ TEST_F(FieldCacheSanityCheckerTest, testInsanity1) cache->purgeAllCaches(); } -TEST_F(FieldCacheSanityCheckerTest, testInsanity2) -{ +TEST_F(FieldCacheSanityCheckerTest, testInsanity2) { FieldCachePtr cache = FieldCache::DEFAULT(); cache->purgeAllCaches(); diff --git a/src/test/util/FileReaderTest.cpp b/src/test/util/FileReaderTest.cpp index cc376418..fadf9cfa 100644 --- a/src/test/util/FileReaderTest.cpp +++ b/src/test/util/FileReaderTest.cpp @@ -15,8 +15,7 @@ using namespace Lucene; typedef LuceneTestFixture FileReaderTest; -TEST_F(FileReaderTest, testFileReaderChar) -{ +TEST_F(FileReaderTest, testFileReaderChar) { FileReaderPtr reader = newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")); EXPECT_EQ((wchar_t)reader->read(), L't'); EXPECT_EQ((wchar_t)reader->read(), L'e'); @@ -29,8 +28,7 @@ TEST_F(FileReaderTest, testFileReaderChar) EXPECT_EQ((wchar_t)reader->read(), L'e'); } -TEST_F(FileReaderTest, testFileReaderRead) -{ +TEST_F(FileReaderTest, testFileReaderRead) { FileReaderPtr reader = newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")); wchar_t buffer[80]; @@ -43,8 +41,7 @@ TEST_F(FileReaderTest, testFileReaderRead) EXPECT_EQ(reader->read(buffer, 0, 1), FileReader::FILE_EOF); } -TEST_F(FileReaderTest, testFileReaderReset) -{ +TEST_F(FileReaderTest, testFileReaderReset) { FileReaderPtr reader = newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")); wchar_t buffer[20]; diff --git a/src/test/util/FileUtilsTest.cpp b/src/test/util/FileUtilsTest.cpp index dda0d153..5e06d42e 100644 --- a/src/test/util/FileUtilsTest.cpp +++ b/src/test/util/FileUtilsTest.cpp @@ -14,31 +14,27 @@ using namespace Lucene; typedef LuceneTestFixture FileUtilsTest; -TEST_F(FileUtilsTest, testFileExists) -{ +TEST_F(FileUtilsTest, testFileExists) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); EXPECT_TRUE(FileUtils::fileExists(fileDir)); } -TEST_F(FileUtilsTest, testFileModified) -{ +TEST_F(FileUtilsTest, testFileModified) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); uint64_t fileModified = FileUtils::fileModified(fileDir); EXPECT_NE(fileModified, 0); - struct tm *fileTime = localtime((const time_t*)&fileModified); + struct tm* fileTime = localtime((const time_t*)&fileModified); EXPECT_TRUE(fileTime != NULL); } -TEST_F(FileUtilsTest, testInvalidFileModified) -{ +TEST_F(FileUtilsTest, testInvalidFileModified) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); EXPECT_EQ(FileUtils::fileModified(fileDir), 0); } -TEST_F(FileUtilsTest, testTouchFile) -{ +TEST_F(FileUtilsTest, testTouchFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); EXPECT_TRUE(FileUtils::touchFile(fileDir)); @@ -46,38 +42,34 @@ TEST_F(FileUtilsTest, testTouchFile) uint64_t fileModified = FileUtils::fileModified(fileDir); EXPECT_NE(fileModified, 0); - struct tm *fileTime = localtime((const time_t*)&fileModified); + struct tm* fileTime = localtime((const time_t*)&fileModified); EXPECT_TRUE(fileTime != NULL); time_t current = time(NULL); - struct tm *currentTime = localtime((const time_t*)¤t); + struct tm* currentTime = localtime((const time_t*)¤t); EXPECT_EQ(fileTime->tm_year, currentTime->tm_year); EXPECT_EQ(fileTime->tm_mon, currentTime->tm_mon); EXPECT_EQ(fileTime->tm_mday, currentTime->tm_mday); } -TEST_F(FileUtilsTest, testInvalidTouchFile) -{ +TEST_F(FileUtilsTest, testInvalidTouchFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); EXPECT_TRUE(!FileUtils::touchFile(fileDir)); } -TEST_F(FileUtilsTest, testFileLength) -{ +TEST_F(FileUtilsTest, testFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfilesize1.txt")); int64_t fileLength = FileUtils::fileLength(fileDir); EXPECT_EQ(fileLength, 29); } -TEST_F(FileUtilsTest, testInvalidFileLength) -{ +TEST_F(FileUtilsTest, testInvalidFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); EXPECT_EQ(FileUtils::fileLength(fileDir), 0); } -TEST_F(FileUtilsTest, testSetFileLength) -{ +TEST_F(FileUtilsTest, testSetFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfilesize2.txt")); EXPECT_TRUE(FileUtils::setFileLength(fileDir, 1234)); @@ -91,14 +83,12 @@ TEST_F(FileUtilsTest, testSetFileLength) EXPECT_EQ(fileLengthShrink, 29); } -TEST_F(FileUtilsTest, testInvalidSetFileLength) -{ +TEST_F(FileUtilsTest, testInvalidSetFileLength) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); EXPECT_TRUE(!FileUtils::setFileLength(fileDir, 1234)); } -TEST_F(FileUtilsTest, testRemoveFile) -{ +TEST_F(FileUtilsTest, testRemoveFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testdelete.txt")); std::ofstream f(StringUtils::toUTF8(fileDir).c_str(), std::ios::binary | std::ios::out); @@ -109,31 +99,26 @@ TEST_F(FileUtilsTest, testRemoveFile) EXPECT_TRUE(!FileUtils::fileExists(fileDir)); } -TEST_F(FileUtilsTest, testInvalidRemoveFile) -{ +TEST_F(FileUtilsTest, testInvalidRemoveFile) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"invalid")); EXPECT_TRUE(!FileUtils::removeFile(fileDir)); } -TEST_F(FileUtilsTest, testIsDirectory) -{ +TEST_F(FileUtilsTest, testIsDirectory) { String fileDir(FileUtils::joinPath(getTestDir(), L"testdirectory")); EXPECT_TRUE(FileUtils::isDirectory(fileDir)); } -TEST_F(FileUtilsTest, testNotDirectory) -{ +TEST_F(FileUtilsTest, testNotDirectory) { String fileDir(FileUtils::joinPath(FileUtils::joinPath(getTestDir(), L"testdirectory"), L"testfile1.txt")); EXPECT_TRUE(!FileUtils::isDirectory(fileDir)); } -TEST_F(FileUtilsTest, testNotDirectoryEmpty) -{ +TEST_F(FileUtilsTest, testNotDirectoryEmpty) { EXPECT_TRUE(!FileUtils::isDirectory(L"")); } -TEST_F(FileUtilsTest, testListDirectory) -{ +TEST_F(FileUtilsTest, testListDirectory) { String fileDir(FileUtils::joinPath(getTestDir(), L"testdirectory")); HashSet list(HashSet::newInstance()); @@ -151,8 +136,7 @@ TEST_F(FileUtilsTest, testListDirectory) EXPECT_EQ(expectedList[5], L"testfilesize2.txt"); } -TEST_F(FileUtilsTest, testListDirectoryFiles) -{ +TEST_F(FileUtilsTest, testListDirectoryFiles) { String fileDir(FileUtils::joinPath(getTestDir(), L"testdirectory")); HashSet list(HashSet::newInstance()); @@ -169,9 +153,8 @@ TEST_F(FileUtilsTest, testListDirectoryFiles) EXPECT_EQ(expectedList[4], L"testfilesize2.txt"); } -TEST_F(FileUtilsTest, testJoinPath) -{ - #if defined(_WIN32) || defined(_WIN64) +TEST_F(FileUtilsTest, testJoinPath) { +#if defined(_WIN32) || defined(_WIN64) EXPECT_EQ(FileUtils::joinPath(L"c:\\test", L"\\testfile.txt"), L"c:\\test\\testfile.txt"); EXPECT_EQ(FileUtils::joinPath(L"c:\\test", L"testfile.txt"), L"c:\\test\\testfile.txt"); EXPECT_EQ(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); @@ -180,40 +163,38 @@ TEST_F(FileUtilsTest, testJoinPath) EXPECT_EQ(FileUtils::joinPath(L"\\test", L"testfile.txt"), L"\\test\\testfile.txt"); EXPECT_EQ(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); EXPECT_EQ(FileUtils::joinPath(L"\\test", L""), L"\\test"); - #else +#else EXPECT_EQ(FileUtils::joinPath(L"/test", L"/testfile.txt"), L"/test/testfile.txt"); EXPECT_EQ(FileUtils::joinPath(L"/test", L"testfile.txt"), L"/test/testfile.txt"); EXPECT_EQ(FileUtils::joinPath(L"", L"testfile.txt"), L"testfile.txt"); EXPECT_EQ(FileUtils::joinPath(L"/test", L""), L"/test"); - #endif +#endif } -TEST_F(FileUtilsTest, testExtractPath) -{ - #if defined(_WIN32) || defined(_WIN64) +TEST_F(FileUtilsTest, testExtractPath) { +#if defined(_WIN32) || defined(_WIN64) EXPECT_EQ(FileUtils::extractPath(L"c:\\test"), L"c:\\"); EXPECT_EQ(FileUtils::extractPath(L"c:\\test\\testfile.txt"), L"c:\\test"); EXPECT_EQ(FileUtils::extractPath(L""), L""); EXPECT_EQ(FileUtils::extractPath(L"\\test"), L"\\"); EXPECT_EQ(FileUtils::extractPath(L"\\test\\testfile.txt"), L"\\test"); - #else +#else EXPECT_EQ(FileUtils::extractPath(L"/test"), L"/"); EXPECT_EQ(FileUtils::extractPath(L"/test/testfile.txt"), L"/test"); EXPECT_EQ(FileUtils::extractPath(L""), L""); - #endif +#endif } -TEST_F(FileUtilsTest, testExtractFile) -{ - #if defined(_WIN32) || defined(_WIN64) +TEST_F(FileUtilsTest, testExtractFile) { +#if defined(_WIN32) || defined(_WIN64) EXPECT_EQ(FileUtils::extractFile(L"c:\\test"), L"test"); EXPECT_EQ(FileUtils::extractFile(L"c:\\test\\testfile.txt"), L"testfile.txt"); EXPECT_EQ(FileUtils::extractFile(L""), L""); EXPECT_EQ(FileUtils::extractFile(L"\\test"), L"test"); EXPECT_EQ(FileUtils::extractFile(L"\\test\\testfile.txt"), L"testfile.txt"); - #else +#else EXPECT_EQ(FileUtils::extractFile(L"/test"), L"test"); EXPECT_EQ(FileUtils::extractFile(L"/test/testfile.txt"), L"testfile.txt"); EXPECT_EQ(FileUtils::extractFile(L""), L""); - #endif +#endif } diff --git a/src/test/util/InputStreamReaderTest.cpp b/src/test/util/InputStreamReaderTest.cpp index 3910757a..c7d1d4ae 100644 --- a/src/test/util/InputStreamReaderTest.cpp +++ b/src/test/util/InputStreamReaderTest.cpp @@ -16,8 +16,7 @@ using namespace Lucene; typedef LuceneTestFixture InputStreamReaderTest; -TEST_F(InputStreamReaderTest, testInputStreamReaderChar) -{ +TEST_F(InputStreamReaderTest, testInputStreamReaderChar) { InputStreamReaderPtr stream = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt"))); EXPECT_EQ((wchar_t)stream->read(), L't'); EXPECT_EQ((wchar_t)stream->read(), L'e'); @@ -30,12 +29,12 @@ TEST_F(InputStreamReaderTest, testInputStreamReaderChar) EXPECT_EQ((wchar_t)stream->read(), L'e'); } -TEST_F(InputStreamReaderTest, testInputStreamReaderCharUtf8) -{ +TEST_F(InputStreamReaderTest, testInputStreamReaderCharUtf8) { InputStreamReaderPtr stream = newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_uft8.txt"))); const uint8_t chinese[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, - 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd}; + 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd + }; String expectedChinese(UTF8_TO_STRING(chinese)); EXPECT_EQ((wchar_t)stream->read(), expectedChinese[0]); @@ -47,15 +46,15 @@ TEST_F(InputStreamReaderTest, testInputStreamReaderCharUtf8) EXPECT_EQ((wchar_t)stream->read(), expectedChinese[6]); } -TEST_F(InputStreamReaderTest, testInputStreamReaderReadLine) -{ +TEST_F(InputStreamReaderTest, testInputStreamReaderReadLine) { BufferedReaderPtr reader = newLucene(newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_text.txt")))); Collection readLines = Collection::newInstance(); String line; - while (reader->readLine(line)) + while (reader->readLine(line)) { readLines.add(line); + } EXPECT_EQ(reader->read(), FileReader::FILE_EOF); EXPECT_EQ(readLines.size(), 6); @@ -67,23 +66,25 @@ TEST_F(InputStreamReaderTest, testInputStreamReaderReadLine) EXPECT_EQ(readLines[5], L"1 2 3 4"); } -TEST_F(InputStreamReaderTest, testInputStreamReaderReadLineUtf8) -{ +TEST_F(InputStreamReaderTest, testInputStreamReaderReadLineUtf8) { BufferedReaderPtr reader = newLucene(newLucene(newLucene(FileUtils::joinPath(getTestDir(), L"testfile_uft8.txt")))); Collection readLines = Collection::newInstance(); String line; - while (reader->readLine(line)) + while (reader->readLine(line)) { readLines.add(line); + } const uint8_t chinese[] = {0xe4, 0xb8, 0xad, 0xe5, 0x8d, 0x8e, 0xe4, 0xba, 0xba, 0xe6, 0xb0, - 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd}; + 0x91, 0xe5, 0x85, 0xb1, 0xe5, 0x92, 0x8c, 0xe5, 0x9b, 0xbd + }; const uint8_t persian[] = {0xd9, 0x86, 0xd8, 0xaf, 0xd8, 0xa7, 0xd8, 0xb4, 0xd8, 0xaa, 0xd9, 0x87}; const uint8_t russian[] = {0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xb8, 0xd1, 0x81, 0xd1, 0x81, 0xd0, - 0xb8, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8e}; + 0xb8, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x8e + }; EXPECT_EQ(readLines.size(), 80); EXPECT_EQ(readLines[0], UTF8_TO_STRING(chinese)); diff --git a/src/test/util/LuceneGlobalFixture.cpp b/src/test/util/LuceneGlobalFixture.cpp index d86e7b18..c46e8acc 100644 --- a/src/test/util/LuceneGlobalFixture.cpp +++ b/src/test/util/LuceneGlobalFixture.cpp @@ -10,18 +10,17 @@ #include "TestPoint.h" #include "FileUtils.h" -namespace Lucene -{ - LuceneGlobalFixture::LuceneGlobalFixture() - { - FileUtils::removeDirectory(getTempDir()); - FileUtils::createDirectory(getTempDir()); - TestPoint::enableTestPoints(); - } +namespace Lucene { + +LuceneGlobalFixture::LuceneGlobalFixture() { + FileUtils::removeDirectory(getTempDir()); + FileUtils::createDirectory(getTempDir()); + TestPoint::enableTestPoints(); +} + +LuceneGlobalFixture::~LuceneGlobalFixture() { + FileUtils::removeDirectory(getTempDir()); + Lucene::CycleCheck::dumpRefs(); +} - LuceneGlobalFixture::~LuceneGlobalFixture() - { - FileUtils::removeDirectory(getTempDir()); - Lucene::CycleCheck::dumpRefs(); - } } diff --git a/src/test/util/LuceneTestFixture.cpp b/src/test/util/LuceneTestFixture.cpp index e1ce9388..27c61e08 100644 --- a/src/test/util/LuceneTestFixture.cpp +++ b/src/test/util/LuceneTestFixture.cpp @@ -9,22 +9,20 @@ #include "ConcurrentMergeScheduler.h" #include "DateTools.h" -namespace Lucene -{ - LuceneTestFixture::LuceneTestFixture() - { - DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); - ConcurrentMergeScheduler::setTestMode(); - } +namespace Lucene { + +LuceneTestFixture::LuceneTestFixture() { + DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); + ConcurrentMergeScheduler::setTestMode(); +} - LuceneTestFixture::~LuceneTestFixture() - { - DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); - if (ConcurrentMergeScheduler::anyUnhandledExceptions()) - { - // Clear the failure so that we don't just keep failing subsequent test cases - ConcurrentMergeScheduler::clearUnhandledExceptions(); - FAIL() << "ConcurrentMergeScheduler hit unhandled exceptions"; - } +LuceneTestFixture::~LuceneTestFixture() { + DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); + if (ConcurrentMergeScheduler::anyUnhandledExceptions()) { + // Clear the failure so that we don't just keep failing subsequent test cases + ConcurrentMergeScheduler::clearUnhandledExceptions(); + FAIL() << "ConcurrentMergeScheduler hit unhandled exceptions"; } } + +} diff --git a/src/test/util/NumericUtilsTest.cpp b/src/test/util/NumericUtilsTest.cpp index 5d7cb9c9..173f8f81 100644 --- a/src/test/util/NumericUtilsTest.cpp +++ b/src/test/util/NumericUtilsTest.cpp @@ -15,15 +15,13 @@ using namespace Lucene; typedef LuceneTestFixture NumericUtilsTest; -class CheckLongRangeBuilder : public LongRangeBuilder -{ +class CheckLongRangeBuilder : public LongRangeBuilder { public: CheckLongRangeBuilder(int64_t lower, int64_t upper, OpenBitSetPtr bits, Collection::iterator neededBoundsFirst, Collection::iterator neededBoundsLast, Collection::iterator neededShiftsFirst, - Collection::iterator neededShiftsLast) - { + Collection::iterator neededShiftsLast) { this->lower = lower; this->upper = upper; this->bits = bits; @@ -33,8 +31,7 @@ class CheckLongRangeBuilder : public LongRangeBuilder this->neededShiftsLast = neededShiftsLast; } - virtual ~CheckLongRangeBuilder() - { + virtual ~CheckLongRangeBuilder() { } protected: @@ -47,23 +44,23 @@ class CheckLongRangeBuilder : public LongRangeBuilder Collection::iterator neededShiftsLast; public: - virtual void addRange(int64_t min, int64_t max, int32_t shift) - { + virtual void addRange(int64_t min, int64_t max, int32_t shift) { EXPECT_TRUE(min >= lower && min <= upper && max >= lower && max <= upper); - if (bits) - { - for (int64_t l = min; l <= max; ++l) - { - if (bits->getAndSet((int64_t)(l - lower))) + if (bits) { + for (int64_t l = min; l <= max; ++l) { + if (bits->getAndSet((int64_t)(l - lower))) { FAIL() << "getAndSet failure"; + } // extra exit condition to prevent overflow on MAX_VALUE - if (l == max) + if (l == max) { break; + } } } - if (neededBoundsFirst == neededBoundsLast || neededShiftsFirst == neededShiftsLast) + if (neededBoundsFirst == neededBoundsLast || neededShiftsFirst == neededShiftsLast) { return; + } // make unsigned longs for easier display and understanding min ^= 0x8000000000000000LL; @@ -75,28 +72,24 @@ class CheckLongRangeBuilder : public LongRangeBuilder } }; -static void checkLongRangeSplit(int64_t lower, int64_t upper, int32_t precisionStep, bool useBitSet, Collection neededBounds, Collection neededShifts) -{ +static void checkLongRangeSplit(int64_t lower, int64_t upper, int32_t precisionStep, bool useBitSet, Collection neededBounds, Collection neededShifts) { OpenBitSetPtr bits = useBitSet ? newLucene((int64_t)(upper - lower + 1)) : OpenBitSetPtr(); NumericUtils::splitLongRange(newLucene(lower, upper, bits, neededBounds.begin(), neededBounds.end(), neededShifts.begin(), neededShifts.end()), precisionStep, lower, upper); - if (useBitSet) - { + if (useBitSet) { // after flipping all bits in the range, the cardinality should be zero bits->flip(0, (int64_t)(upper - lower + 1)); EXPECT_TRUE(bits->isEmpty()); } } -class CheckIntRangeBuilder : public IntRangeBuilder -{ +class CheckIntRangeBuilder : public IntRangeBuilder { public: CheckIntRangeBuilder(int32_t lower, int32_t upper, OpenBitSetPtr bits, Collection::iterator neededBoundsFirst, Collection::iterator neededBoundsLast, Collection::iterator neededShiftsFirst, - Collection::iterator neededShiftsLast) - { + Collection::iterator neededShiftsLast) { this->lower = lower; this->upper = upper; this->bits = bits; @@ -106,8 +99,7 @@ class CheckIntRangeBuilder : public IntRangeBuilder this->neededShiftsLast = neededShiftsLast; } - virtual ~CheckIntRangeBuilder() - { + virtual ~CheckIntRangeBuilder() { } protected: @@ -120,23 +112,23 @@ class CheckIntRangeBuilder : public IntRangeBuilder Collection::iterator neededShiftsLast; public: - virtual void addRange(int32_t min, int32_t max, int32_t shift) - { + virtual void addRange(int32_t min, int32_t max, int32_t shift) { EXPECT_TRUE(min >= lower && min <= upper && max >= lower && max <= upper); - if (bits) - { - for (int32_t l = min; l <= max; ++l) - { - if (bits->getAndSet((int32_t)(l - lower))) + if (bits) { + for (int32_t l = min; l <= max; ++l) { + if (bits->getAndSet((int32_t)(l - lower))) { FAIL() << "getAndSet failure"; + } // extra exit condition to prevent overflow on MAX_VALUE - if (l == max) + if (l == max) { break; + } } } - if (neededBoundsFirst == neededBoundsLast || neededShiftsFirst == neededShiftsLast) + if (neededBoundsFirst == neededBoundsLast || neededShiftsFirst == neededShiftsLast) { return; + } // make unsigned longs for easier display and understanding min ^= 0x80000000; @@ -148,31 +140,27 @@ class CheckIntRangeBuilder : public IntRangeBuilder } }; -static void checkIntRangeSplit(int32_t lower, int32_t upper, int32_t precisionStep, bool useBitSet, Collection neededBounds, Collection neededShifts) -{ +static void checkIntRangeSplit(int32_t lower, int32_t upper, int32_t precisionStep, bool useBitSet, Collection neededBounds, Collection neededShifts) { OpenBitSetPtr bits = useBitSet ? newLucene((int32_t)(upper - lower + 1)) : OpenBitSetPtr(); NumericUtils::splitIntRange(newLucene(lower, upper, bits, neededBounds.begin(), neededBounds.end(), neededShifts.begin(), neededShifts.end()), precisionStep, lower, upper); - if (useBitSet) - { + if (useBitSet) { // after flipping all bits in the range, the cardinality should be zero bits->flip(0, (int32_t)(upper - lower + 1)); EXPECT_TRUE(bits->isEmpty()); } } -TEST_F(NumericUtilsTest, testLongConversionAndOrdering) -{ +TEST_F(NumericUtilsTest, testLongConversionAndOrdering) { // generate a series of encoded longs, each numerical one bigger than the one before String last; - for (int64_t l = -100000; l < 100000; ++l) - { + for (int64_t l = -100000; l < 100000; ++l) { String act = NumericUtils::longToPrefixCoded(l); - if (!last.empty()) - { + if (!last.empty()) { // test if smaller - if (last.compare(act) >= 0) + if (last.compare(act) >= 0) { FAIL() << "compare failure"; + } } // test is back and forward conversion works EXPECT_EQ(l, NumericUtils::prefixCodedToLong(act)); @@ -181,18 +169,16 @@ TEST_F(NumericUtilsTest, testLongConversionAndOrdering) } } -TEST_F(NumericUtilsTest, testIntConversionAndOrdering) -{ +TEST_F(NumericUtilsTest, testIntConversionAndOrdering) { // generate a series of encoded ints, each numerical one bigger than the one before String last; - for (int32_t l = -100000; l < 100000; ++l) - { + for (int32_t l = -100000; l < 100000; ++l) { String act = NumericUtils::intToPrefixCoded(l); - if (!last.empty()) - { + if (!last.empty()) { // test if smaller - if (last.compare(act) >= 0) + if (last.compare(act) >= 0) { FAIL() << "compare failure"; + } } // test is back and forward conversion works EXPECT_EQ(l, NumericUtils::prefixCodedToInt(act)); @@ -201,41 +187,36 @@ TEST_F(NumericUtilsTest, testIntConversionAndOrdering) } } -TEST_F(NumericUtilsTest, testLongSpecialValues) -{ +TEST_F(NumericUtilsTest, testLongSpecialValues) { static const int64_t vals[] = {LLONG_MIN, LLONG_MIN + 1, LLONG_MIN + 2, -5003400000000LL, -4000LL, -3000LL, -2000LL, -1000LL, -1LL, 0LL, 1LL, 10LL, 300LL, 50006789999999999LL, - LLONG_MAX - 2, LLONG_MAX - 1, LLONG_MAX}; + LLONG_MAX - 2, LLONG_MAX - 1, LLONG_MAX + }; int32_t length = SIZEOF_ARRAY(vals); Collection prefixVals = Collection::newInstance(length); - for (int32_t i = 0; i < length; ++i) - { + for (int32_t i = 0; i < length; ++i) { prefixVals[i] = NumericUtils::longToPrefixCoded(vals[i]); // check forward and back conversion EXPECT_EQ(vals[i], NumericUtils::prefixCodedToLong(prefixVals[i])); // test if decoding values as long fails correctly - try - { + try { NumericUtils::prefixCodedToInt(prefixVals[i]); - } - catch (NumberFormatException& e) - { + } catch (NumberFormatException& e) { EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); } } // check sort order (prefixVals should be ascending) - for (int32_t i = 1; i < prefixVals.size(); ++i) + for (int32_t i = 1; i < prefixVals.size(); ++i) { EXPECT_TRUE(prefixVals[i - 1].compare(prefixVals[i]) < 0); + } // check the prefix encoding, lower precision should have the difference to original // value equal to the lower removed bits - for (int32_t i = 0; i < length; ++i) - { - for (int32_t j = 0; j < 32; ++j) - { + for (int32_t i = 0; i < length; ++i) { + for (int32_t j = 0; j < 32; ++j) { int64_t prefixVal = NumericUtils::prefixCodedToLong(NumericUtils::longToPrefixCoded(vals[i], j)); int64_t mask = ((int64_t)1 << j) - 1; EXPECT_EQ(vals[i] & mask, vals[i] - prefixVal); @@ -243,40 +224,35 @@ TEST_F(NumericUtilsTest, testLongSpecialValues) } } -TEST_F(NumericUtilsTest, testIntSpecialValues) -{ +TEST_F(NumericUtilsTest, testIntSpecialValues) { static const int32_t vals[] = {INT_MIN, INT_MIN + 1, INT_MIN + 2, -64765767, -4000, -3000, -2000, - -1000, -1, 0, 1, 10, 300, 765878989, INT_MAX - 2, INT_MAX- 1, INT_MAX}; + -1000, -1, 0, 1, 10, 300, 765878989, INT_MAX - 2, INT_MAX- 1, INT_MAX + }; int32_t length = SIZEOF_ARRAY(vals); Collection prefixVals = Collection::newInstance(length); - for (int32_t i = 0; i < length; ++i) - { + for (int32_t i = 0; i < length; ++i) { prefixVals[i] = NumericUtils::intToPrefixCoded(vals[i]); // check forward and back conversion EXPECT_EQ(vals[i], NumericUtils::prefixCodedToInt(prefixVals[i])); // test if decoding values as long fails correctly - try - { + try { NumericUtils::prefixCodedToLong(prefixVals[i]); - } - catch (NumberFormatException& e) - { + } catch (NumberFormatException& e) { EXPECT_TRUE(check_exception(LuceneException::NumberFormat)(e)); } } // check sort order (prefixVals should be ascending) - for (int32_t i = 1; i < prefixVals.size(); ++i) + for (int32_t i = 1; i < prefixVals.size(); ++i) { EXPECT_TRUE(prefixVals[i - 1].compare(prefixVals[i]) < 0); + } // check the prefix encoding, lower precision should have the difference to original // value equal to the lower removed bits - for (int32_t i = 0; i < length; ++i) - { - for (int32_t j = 0; j < 32; ++j) - { + for (int32_t i = 0; i < length; ++i) { + for (int32_t j = 0; j < 32; ++j) { int32_t prefixVal = NumericUtils::prefixCodedToInt(NumericUtils::intToPrefixCoded(vals[i], j)); int32_t mask = ((int32_t)1 << j) - 1; EXPECT_EQ(vals[i] & mask, vals[i] - prefixVal); @@ -284,150 +260,149 @@ TEST_F(NumericUtilsTest, testIntSpecialValues) } } -TEST_F(NumericUtilsTest, testDoubles) -{ +TEST_F(NumericUtilsTest, testDoubles) { static const double vals[] = {-std::numeric_limits::infinity(), -2.3E25, -1.0E15, -1.0, -1.0E-1, -1.0E-2, -0.0, +0.0, 1.0E-2, 1.0E-1, 1.0, 1.0E15, 2.3E25, - std::numeric_limits::infinity()}; + std::numeric_limits::infinity() + }; int32_t length = SIZEOF_ARRAY(vals); Collection longVals = Collection::newInstance(length); // check forward and back conversion - for (int32_t i = 0; i < length; ++i) - { + for (int32_t i = 0; i < length; ++i) { longVals[i] = NumericUtils::doubleToSortableLong(vals[i]); EXPECT_EQ(vals[i], NumericUtils::sortableLongToDouble(longVals[i])); } // check sort order (longVals should be ascending) - for (int32_t i = 1; i < longVals.size(); ++i) + for (int32_t i = 1; i < longVals.size(); ++i) { EXPECT_TRUE(longVals[i - 1] < longVals[i]); + } } /// NumericRangeQuery errors with endpoints near long min and max values -TEST_F(NumericUtilsTest, testLongExtremeValues) -{ +TEST_F(NumericUtilsTest, testLongExtremeValues) { // upper end extremes checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 1, true, - newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), - newCollection(0) - ); + newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 2, true, - newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), - newCollection(0) - ); + newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 4, true, - newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), - newCollection(0) - ); + newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 6, true, - newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), - newCollection(0) - ); + newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 8, true, - newCollection(0xffffffffffffffffLL ,0xffffffffffffffffLL), - newCollection(0) - ); + newCollection(0xffffffffffffffffLL ,0xffffffffffffffffLL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MAX, LLONG_MAX, 64, true, - newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), - newCollection(0) - ); + newCollection(0xffffffffffffffffLL, 0xffffffffffffffffLL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MAX - 0xfLL, LLONG_MAX, 4, true, - newCollection(0xfffffffffffffffLL, 0xfffffffffffffffLL), - newCollection(4) - ); + newCollection(0xfffffffffffffffLL, 0xfffffffffffffffLL), + newCollection(4) + ); checkLongRangeSplit(LLONG_MAX - 0x10LL, LLONG_MAX, 4, true, - newCollection(0xffffffffffffffefLL, 0xffffffffffffffefLL, 0xfffffffffffffffLL, 0xfffffffffffffffLL), - newCollection(0, 4) - ); + newCollection(0xffffffffffffffefLL, 0xffffffffffffffefLL, 0xfffffffffffffffLL, 0xfffffffffffffffLL), + newCollection(0, 4) + ); // lower end extremes checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 1, true, - newCollection(0x0000000000000000LL,0x0000000000000000LL), - newCollection(0) - ); + newCollection(0x0000000000000000LL,0x0000000000000000LL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 2, true, - newCollection(0x0000000000000000LL, 0x0000000000000000LL), - newCollection(0) - ); + newCollection(0x0000000000000000LL, 0x0000000000000000LL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 4, true, - newCollection(0x0000000000000000LL, 0x0000000000000000LL), - newCollection(0) - ); + newCollection(0x0000000000000000LL, 0x0000000000000000LL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 6, true, - newCollection(0x0000000000000000LL, 0x0000000000000000LL), - newCollection(0) - ); + newCollection(0x0000000000000000LL, 0x0000000000000000LL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 8, true, - newCollection(0x0000000000000000LL, 0x0000000000000000LL), - newCollection(0) - ); + newCollection(0x0000000000000000LL, 0x0000000000000000LL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MIN, LLONG_MIN, 64, true, - newCollection(0x0000000000000000LL, 0x0000000000000000LL), - newCollection(0) - ); + newCollection(0x0000000000000000LL, 0x0000000000000000LL), + newCollection(0) + ); checkLongRangeSplit(LLONG_MIN, LLONG_MIN + 0xfLL, 4, true, - newCollection(0x000000000000000LL, 0x000000000000000LL), - newCollection(4) - ); + newCollection(0x000000000000000LL, 0x000000000000000LL), + newCollection(4) + ); checkLongRangeSplit(LLONG_MIN, LLONG_MIN + 0x10LL, 4, true, - newCollection(0x0000000000000010LL, 0x0000000000000010LL, 0x000000000000000LL, 0x000000000000000LL), - newCollection(0, 4) - ); + newCollection(0x0000000000000010LL, 0x0000000000000010LL, 0x000000000000000LL, 0x000000000000000LL), + newCollection(0, 4) + ); } -static int64_t randomLong(const RandomPtr& random) -{ +static int64_t randomLong(const RandomPtr& random) { int64_t val; - switch (random->nextInt(4)) - { - case 0: - val = 1LL << (int64_t)random->nextInt(63); // patterns like 0x000000100000 (-1 yields patterns like 0x0000fff) - break; - case 1: - val = -1LL << (int64_t)random->nextInt(63); // patterns like 0xfffff00000 - break; - default: - val = (int64_t)random->nextInt(); + switch (random->nextInt(4)) { + case 0: + val = 1LL << (int64_t)random->nextInt(63); // patterns like 0x000000100000 (-1 yields patterns like 0x0000fff) + break; + case 1: + val = -1LL << (int64_t)random->nextInt(63); // patterns like 0xfffff00000 + break; + default: + val = (int64_t)random->nextInt(); } val += random->nextInt(5) - 2; - if (random->nextInt() % 2 == 1) - { - if (random->nextInt() % 2 == 1) + if (random->nextInt() % 2 == 1) { + if (random->nextInt() % 2 == 1) { val += random->nextInt(100) - 50; - if (random->nextInt() % 2 == 1) + } + if (random->nextInt() % 2 == 1) { val = ~val; - if (random->nextInt() % 2 == 1) + } + if (random->nextInt() % 2 == 1) { val = val << 1; - if (random->nextInt() % 2 == 1) + } + if (random->nextInt() % 2 == 1) { val = MiscUtils::unsignedShift(val, (int64_t)1); + } } return val; } -static void executeOneRandomSplit(const RandomPtr& random) -{ +static void executeOneRandomSplit(const RandomPtr& random) { int64_t lower = randomLong(random); int64_t len = (int64_t)random->nextInt(16384 * 1024); // not too large bitsets, else OOME! - while (lower + len < lower) // overflow + while (lower + len < lower) { // overflow lower >>= 1; + } checkLongRangeSplit(lower, lower + len, random->nextInt(64) + 1, true, Collection::newInstance(), Collection::newInstance()); } -TEST_F(NumericUtilsTest, testRandomSplit) -{ +TEST_F(NumericUtilsTest, testRandomSplit) { RandomPtr random = newLucene(123); - for (int32_t i = 0; i < 20; ++i) + for (int32_t i = 0; i < 20; ++i) { executeOneRandomSplit(random); + } } -TEST_F(NumericUtilsTest, testSplitLongRange) -{ +TEST_F(NumericUtilsTest, testSplitLongRange) { Collection neededBounds = Collection::newInstance(14); neededBounds[0] = 0x7fffffffffffec78LL; neededBounds[1] = 0x7fffffffffffec7fLL; @@ -449,54 +424,53 @@ TEST_F(NumericUtilsTest, testSplitLongRange) // the same with no range splitting checkLongRangeSplit(-5000, 9500, 64, true, - newCollection(0x7fffffffffffec78LL, 0x800000000000251cLL), - newCollection(0) - ); + newCollection(0x7fffffffffffec78LL, 0x800000000000251cLL), + newCollection(0) + ); // this tests optimized range splitting, if one of the inner bounds // is also the bound of the next lower precision, it should be used completely checkLongRangeSplit(0, 1024 + 63, 4, true, - newCollection(0x800000000000040LL, 0x800000000000043LL, 0x80000000000000LL, 0x80000000000003LL), - newCollection(4, 8) - ); + newCollection(0x800000000000040LL, 0x800000000000043LL, 0x80000000000000LL, 0x80000000000003LL), + newCollection(4, 8) + ); // the full long range should only consist of a lowest precision range; // no bitset testing here, as too much memory needed checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 8, false, - newCollection(0x00LL, 0xffLL), - newCollection(56) - ); + newCollection(0x00LL, 0xffLL), + newCollection(56) + ); // the same with precisionStep=4 checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 4, false, - newCollection(0x00LL, 0xfLL), - newCollection(60) - ); + newCollection(0x00LL, 0xfLL), + newCollection(60) + ); // the same with precisionStep=2 checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 2, false, - newCollection(0x00LL, 0x3LL), - newCollection(62) - ); + newCollection(0x00LL, 0x3LL), + newCollection(62) + ); // the same with precisionStep=1 checkLongRangeSplit(LLONG_MIN, LLONG_MAX, 1, false, - newCollection(0x00LL, 0x1LL), - newCollection(63) - ); + newCollection(0x00LL, 0x1LL), + newCollection(63) + ); // a inverse range should produce no sub-ranges checkLongRangeSplit(9500, -5000, 4, false, Collection::newInstance(), Collection::newInstance()); // a 0-length range should reproduce the range itself checkLongRangeSplit(9500, 9500, 4, false, - newCollection(0x800000000000251cLL, 0x800000000000251cLL), - newCollection(0) - ); + newCollection(0x800000000000251cLL, 0x800000000000251cLL), + newCollection(0) + ); } -TEST_F(NumericUtilsTest, testSplitIntRange) -{ +TEST_F(NumericUtilsTest, testSplitIntRange) { Collection neededBounds = Collection::newInstance(14); neededBounds[0] = 0x7fffec78; neededBounds[1] = 0x7fffec7f; @@ -518,48 +492,48 @@ TEST_F(NumericUtilsTest, testSplitIntRange) // the same with no range splitting checkIntRangeSplit(-5000, 9500, 32, true, - newCollection(0x7fffec78, 0x8000251c), - newCollection(0) - ); + newCollection(0x7fffec78, 0x8000251c), + newCollection(0) + ); // this tests optimized range splitting, if one of the inner bounds // is also the bound of the next lower precision, it should be used completely checkIntRangeSplit(0, 1024 + 63, 4, true, - newCollection(0x8000040, 0x8000043, 0x800000, 0x800003), - newCollection(4, 8) - ); + newCollection(0x8000040, 0x8000043, 0x800000, 0x800003), + newCollection(4, 8) + ); // the full int range should only consist of a lowest precision range; // no bitset testing here, as too much memory needed checkIntRangeSplit(INT_MIN, INT_MAX, 8, false, - newCollection(0x00, 0xff), - newCollection(24) - ); + newCollection(0x00, 0xff), + newCollection(24) + ); // the same with precisionStep=4 checkIntRangeSplit(INT_MIN, INT_MAX, 4, false, - newCollection(0x00, 0xf), - newCollection(28) - ); + newCollection(0x00, 0xf), + newCollection(28) + ); // the same with precisionStep=2 checkIntRangeSplit(INT_MIN, INT_MAX, 2, false, - newCollection(0x00, 0x3), - newCollection(30) - ); + newCollection(0x00, 0x3), + newCollection(30) + ); // the same with precisionStep=1 checkIntRangeSplit(INT_MIN, INT_MAX, 1, false, - newCollection(0x00, 0x1), - newCollection(31) - ); + newCollection(0x00, 0x1), + newCollection(31) + ); // a inverse range should produce no sub-ranges checkIntRangeSplit(9500, -5000, 4, false, Collection::newInstance(), Collection::newInstance()); // a 0-length range should reproduce the range itself checkIntRangeSplit(9500, 9500, 4, false, - newCollection(0x8000251c, 0x8000251c), - newCollection(0) - ); + newCollection(0x8000251c, 0x8000251c), + newCollection(0) + ); } diff --git a/src/test/util/OpenBitSetTest.cpp b/src/test/util/OpenBitSetTest.cpp index 4568254e..91cb5809 100644 --- a/src/test/util/OpenBitSetTest.cpp +++ b/src/test/util/OpenBitSetTest.cpp @@ -19,79 +19,66 @@ typedef LuceneTestFixture OpenBitSetTest; static RandomPtr randBitSet = newLucene(123); -static void doGet(const BitSetPtr& a, const OpenBitSetPtr& b) -{ +static void doGet(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t max = a->size(); - for (int32_t i = 0; i < max; ++i) + for (int32_t i = 0; i < max; ++i) { EXPECT_EQ(a->get(i), b->get(i)); + } } -static void doNextSetBit(const BitSetPtr& a, const OpenBitSetPtr& b) -{ +static void doNextSetBit(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t aa = -1; int32_t bb = -1; - do - { + do { aa = a->nextSetBit(aa + 1); bb = b->nextSetBit(bb + 1); EXPECT_EQ(aa, bb); - } - while (aa >= 0); + } while (aa >= 0); } -static void doIterate1(const BitSetPtr& a, const OpenBitSetPtr& b) -{ +static void doIterate1(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t aa = -1; int32_t bb = -1; OpenBitSetIteratorPtr iterator = newLucene(b); - do - { + do { aa = a->nextSetBit(aa + 1); bb = (randBitSet->nextInt() % 2 == 0) ? iterator->nextDoc() : iterator->advance(bb + 1); EXPECT_EQ(aa == -1 ? DocIdSetIterator::NO_MORE_DOCS : aa, bb); - } - while (aa >= 0); + } while (aa >= 0); } -static void doIterate2(const BitSetPtr& a, const OpenBitSetPtr& b) -{ +static void doIterate2(const BitSetPtr& a, const OpenBitSetPtr& b) { int32_t aa = -1; int32_t bb = -1; OpenBitSetIteratorPtr iterator = newLucene(b); - do - { + do { aa = a->nextSetBit(aa + 1); bb = (randBitSet->nextInt() % 2 == 0) ? iterator->nextDoc() : iterator->advance(bb + 1); EXPECT_EQ(aa == -1 ? DocIdSetIterator::NO_MORE_DOCS : aa, bb); - } - while (aa >= 0); + } while (aa >= 0); } -static void doIterate(const BitSetPtr& a, const OpenBitSetPtr& b, int32_t mode) -{ - if (mode == 1) +static void doIterate(const BitSetPtr& a, const OpenBitSetPtr& b, int32_t mode) { + if (mode == 1) { doIterate1(a, b); - else if (mode == 2) + } else if (mode == 2) { doIterate2(a, b); + } } -static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) -{ +static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) { BitSetPtr a0; OpenBitSetPtr b0; - for (int32_t i = 0; i < iter; ++i) - { + for (int32_t i = 0; i < iter; ++i) { int32_t sz = randBitSet->nextInt(maxSize); BitSetPtr a = newLucene(sz); OpenBitSetPtr b = newLucene(sz); // test the various ways of setting bits - if (sz > 0) - { + if (sz > 0) { int32_t nOper = randBitSet->nextInt(sz); - for (int32_t j = 0; j < nOper; ++j) - { + for (int32_t j = 0; j < nOper; ++j) { int32_t idx = randBitSet->nextInt(sz); a->set(idx); b->fastSet(idx); @@ -110,8 +97,9 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) EXPECT_EQ(val2, val); EXPECT_TRUE(b->get(idx)); - if (!val) + if (!val) { b->fastClear(idx); + } EXPECT_EQ(b->get(idx), val); } } @@ -147,8 +135,7 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) doNextSetBit(aa, bb); // a problem here is from set() or nextSetBit - if (a0) - { + if (a0) { EXPECT_EQ(a->equals(a0), b->equals(b0)); EXPECT_EQ(a->cardinality(), b->cardinality()); @@ -193,8 +180,7 @@ static void doRandomSets(int32_t maxSize, int32_t iter, int32_t mode) } } -TEST_F(OpenBitSetTest, testSmall) -{ +TEST_F(OpenBitSetTest, testSmall) { randBitSet->setSeed(17); doRandomSets(1200, 1000, 1); doRandomSets(1200, 1000, 2); @@ -209,8 +195,7 @@ TEST_F(OpenBitSetTest, testBig) } */ -TEST_F(OpenBitSetTest, testEquals) -{ +TEST_F(OpenBitSetTest, testEquals) { randBitSet->setSeed(17); OpenBitSetPtr b1 = newLucene(1111); OpenBitSetPtr b2 = newLucene(2222); @@ -230,8 +215,7 @@ TEST_F(OpenBitSetTest, testEquals) EXPECT_TRUE(b2->equals(b1)); } -TEST_F(OpenBitSetTest, testBitUtils) -{ +TEST_F(OpenBitSetTest, testBitUtils) { randBitSet->setSeed(17); int64_t num = 100000; EXPECT_EQ(5, BitUtil::ntz(num)); @@ -243,8 +227,7 @@ TEST_F(OpenBitSetTest, testBitUtils) EXPECT_EQ(1, BitUtil::ntz2(num)); EXPECT_EQ(1, BitUtil::ntz3(num)); - for (int32_t i = 0; i < 64; ++i) - { + for (int32_t i = 0; i < 64; ++i) { num = (int64_t)1 << i; EXPECT_EQ(i, BitUtil::ntz(num)); EXPECT_EQ(i, BitUtil::ntz2(num)); @@ -252,8 +235,7 @@ TEST_F(OpenBitSetTest, testBitUtils) } } -TEST_F(OpenBitSetTest, testHashCodeEquals) -{ +TEST_F(OpenBitSetTest, testHashCodeEquals) { OpenBitSetPtr bs1 = newLucene(200); OpenBitSetPtr bs2 = newLucene(64); bs1->set(3); diff --git a/src/test/util/PriorityQueueTest.cpp b/src/test/util/PriorityQueueTest.cpp index 14de02be..ff1ae999 100644 --- a/src/test/util/PriorityQueueTest.cpp +++ b/src/test/util/PriorityQueueTest.cpp @@ -15,47 +15,38 @@ typedef LuceneTestFixture PriorityQueueTest; DECLARE_SHARED_PTR(IntegerQueue) -class IntegerQueue : public PriorityQueue -{ +class IntegerQueue : public PriorityQueue { public: - IntegerQueue(int32_t maxSize) : PriorityQueue(maxSize) - { + IntegerQueue(int32_t maxSize) : PriorityQueue(maxSize) { } - virtual ~IntegerQueue() - { + virtual ~IntegerQueue() { } }; DECLARE_SHARED_PTR(IntegerPtrQueue) typedef boost::shared_ptr IntPtr; -class IntegerPtrQueue : public PriorityQueue -{ +class IntegerPtrQueue : public PriorityQueue { public: - IntegerPtrQueue(int32_t maxSize) : PriorityQueue(maxSize) - { + IntegerPtrQueue(int32_t maxSize) : PriorityQueue(maxSize) { } - virtual ~IntegerPtrQueue() - { + virtual ~IntegerPtrQueue() { } protected: - virtual bool lessThan(const IntPtr& first, const IntPtr& second) - { + virtual bool lessThan(const IntPtr& first, const IntPtr& second) { return (*first < *second); } }; -TEST_F(PriorityQueueTest, testPriorityQueue) -{ +TEST_F(PriorityQueueTest, testPriorityQueue) { IntegerQueuePtr testQueue = newLucene(10000); int64_t sum = 0; RandomPtr random = newLucene(); - for (int32_t i = 0; i < 10000; ++i) - { + for (int32_t i = 0; i < 10000; ++i) { int32_t next = random->nextInt(); sum += next; testQueue->add(next); @@ -64,8 +55,7 @@ TEST_F(PriorityQueueTest, testPriorityQueue) int32_t last = INT_MIN; int64_t sum2 = 0; - for (int32_t i = 0; i < 10000; ++i) - { + for (int32_t i = 0; i < 10000; ++i) { int32_t next = testQueue->pop(); EXPECT_TRUE(next >= last); last = next; @@ -75,8 +65,7 @@ TEST_F(PriorityQueueTest, testPriorityQueue) EXPECT_EQ(sum, sum2); } -TEST_F(PriorityQueueTest, testPriorityQueueOverflow) -{ +TEST_F(PriorityQueueTest, testPriorityQueueOverflow) { IntegerQueuePtr testQueue = newLucene(3); testQueue->addOverflow(2); testQueue->addOverflow(3); @@ -88,8 +77,7 @@ TEST_F(PriorityQueueTest, testPriorityQueueOverflow) EXPECT_EQ(3, testQueue->top()); } -TEST_F(PriorityQueueTest, testPriorityQueueClear) -{ +TEST_F(PriorityQueueTest, testPriorityQueueClear) { IntegerQueuePtr testQueue = newLucene(3); testQueue->add(2); testQueue->add(3); @@ -99,8 +87,7 @@ TEST_F(PriorityQueueTest, testPriorityQueueClear) EXPECT_TRUE(testQueue->empty()); } -TEST_F(PriorityQueueTest, testPriorityQueueUpdate) -{ +TEST_F(PriorityQueueTest, testPriorityQueueUpdate) { IntegerPtrQueuePtr testQueue = newLucene(1024); testQueue->add(newInstance(2)); testQueue->add(newInstance(3)); diff --git a/src/test/util/SimpleLRUCacheTest.cpp b/src/test/util/SimpleLRUCacheTest.cpp index 5c8c66e9..3a408d96 100644 --- a/src/test/util/SimpleLRUCacheTest.cpp +++ b/src/test/util/SimpleLRUCacheTest.cpp @@ -16,8 +16,7 @@ typedef SimpleLRUCache< TermPtr, int32_t, luceneHash, luceneEqualsfirst, expectedKey--); + } } -TEST_F(SimpleLRUCacheTest, testCacheGet) -{ +TEST_F(SimpleLRUCacheTest, testCacheGet) { TestLRUSimpleCache testCache(5); testCache.put(1, L"test 1"); @@ -51,8 +50,7 @@ TEST_F(SimpleLRUCacheTest, testCacheGet) EXPECT_EQ(testCache.get(3), L"test 3"); } -TEST_F(SimpleLRUCacheTest, testCacheExists) -{ +TEST_F(SimpleLRUCacheTest, testCacheExists) { TestLRUSimpleCache testCache(5); testCache.put(1, L"test 1"); @@ -65,8 +63,7 @@ TEST_F(SimpleLRUCacheTest, testCacheExists) EXPECT_TRUE(!testCache.contains(7)); } -TEST_F(SimpleLRUCacheTest, testCachePutGet) -{ +TEST_F(SimpleLRUCacheTest, testCachePutGet) { TestLRUSimpleCache testCache(5); testCache.put(1, L"test 1"); @@ -85,8 +82,9 @@ TEST_F(SimpleLRUCacheTest, testCachePutGet) testCache.put(8, L"test 8"); Collection expectedLRU = Collection::newInstance(); - for (TestLRUSimpleCache::const_iterator cache = testCache.begin(); cache != testCache.end(); ++cache) + for (TestLRUSimpleCache::const_iterator cache = testCache.begin(); cache != testCache.end(); ++cache) { expectedLRU.add(cache->first); + } EXPECT_EQ(expectedLRU.size(), 5); @@ -98,38 +96,42 @@ TEST_F(SimpleLRUCacheTest, testCachePutGet) EXPECT_EQ(expectedLRU[4], 2); } -TEST_F(SimpleLRUCacheTest, testRandomAccess) -{ +TEST_F(SimpleLRUCacheTest, testRandomAccess) { const int32_t n = 100; TestLRUSimpleCache cache(n); String value = L"test"; - for (int32_t i = 0; i < n; ++i) + for (int32_t i = 0; i < n; ++i) { cache.put(i, value); + } // access every 2nd item in cache - for (int32_t i = 0; i < n; i += 2) + for (int32_t i = 0; i < n; i += 2) { EXPECT_NE(cache.get(i), L""); + } // add n/2 elements to cache, the ones that weren't touched in the previous loop should now be thrown away - for (int32_t i = n; i < n + (n / 2); ++i) + for (int32_t i = n; i < n + (n / 2); ++i) { cache.put(i, value); + } // access every 4th item in cache - for (int32_t i = 0; i < n; i += 4) + for (int32_t i = 0; i < n; i += 4) { EXPECT_NE(cache.get(i), L""); + } // add 3/4n elements to cache, the ones that weren't touched in the previous loops should now be thrown away - for (int32_t i = n; i < n + (n * 3 / 4); ++i) + for (int32_t i = n; i < n + (n * 3 / 4); ++i) { cache.put(i, value); + } // access every 4th item in cache - for (int32_t i = 0; i < n; i += 4) + for (int32_t i = 0; i < n; i += 4) { EXPECT_NE(cache.get(i), L""); + } } -TEST_F(SimpleLRUCacheTest, testTermCache) -{ +TEST_F(SimpleLRUCacheTest, testTermCache) { TestLRUTermCache testCache(5); testCache.put(newLucene(L"field1", L"text1"), 1); @@ -148,8 +150,9 @@ TEST_F(SimpleLRUCacheTest, testTermCache) testCache.put(newLucene(L"field8", L"text8"), 8); Collection expectedLRU = Collection::newInstance(); - for (TestLRUTermCache::const_iterator cache = testCache.begin(); cache != testCache.end(); ++cache) + for (TestLRUTermCache::const_iterator cache = testCache.begin(); cache != testCache.end(); ++cache) { expectedLRU.add(cache->first); + } EXPECT_EQ(expectedLRU.size(), 5); diff --git a/src/test/util/SortedVIntListTest.cpp b/src/test/util/SortedVIntListTest.cpp index b8ded48b..7e7900a3 100644 --- a/src/test/util/SortedVIntListTest.cpp +++ b/src/test/util/SortedVIntListTest.cpp @@ -20,65 +20,63 @@ static const int32_t VB2 = (VB1 << BIT_SHIFT) | VB1; static const int32_t VB3 = (VB2 << BIT_SHIFT) | VB1; static const int32_t VB4 = (VB3 << BIT_SHIFT) | VB1; -static int32_t vIntByteSize(int32_t i) -{ +static int32_t vIntByteSize(int32_t i) { EXPECT_TRUE(i >= 0); - if (i <= VB1) + if (i <= VB1) { return 1; - if (i <= VB2) + } + if (i <= VB2) { return 2; - if (i <= VB3) + } + if (i <= VB3) { return 3; - if (i <= VB4) + } + if (i <= VB4) { return 4; + } return 5; } -static int32_t vIntListByteSize(Collection ints) -{ +static int32_t vIntListByteSize(Collection ints) { int32_t byteSize = 0; int32_t last = 0; - for (int32_t i = 0; i < ints.size(); ++i) - { + for (int32_t i = 0; i < ints.size(); ++i) { byteSize += vIntByteSize(ints[i] - last); last = ints[i]; } return byteSize; } -static void tstIterator(const SortedVIntListPtr& vintList, Collection ints) -{ - for (int32_t i = 0; i < ints.size(); ++i) - { - if ((i > 0) && (ints[i - 1] == ints[i])) - return; // DocNrSkipper should not skip to same document. +static void tstIterator(const SortedVIntListPtr& vintList, Collection ints) { + for (int32_t i = 0; i < ints.size(); ++i) { + if ((i > 0) && (ints[i - 1] == ints[i])) { + return; // DocNrSkipper should not skip to same document. + } } DocIdSetIteratorPtr m = vintList->iterator(); - for (int32_t i = 0; i < ints.size(); ++i) - { + for (int32_t i = 0; i < ints.size(); ++i) { EXPECT_TRUE(m->nextDoc() != DocIdSetIterator::NO_MORE_DOCS); EXPECT_EQ(ints[i], m->docID()); } EXPECT_EQ(m->nextDoc(), DocIdSetIterator::NO_MORE_DOCS); } -static void tstVIntList(const SortedVIntListPtr& vintList, Collection ints, int32_t expectedByteSize) -{ +static void tstVIntList(const SortedVIntListPtr& vintList, Collection ints, int32_t expectedByteSize) { EXPECT_EQ(ints.size(), vintList->size()); EXPECT_EQ(expectedByteSize, vintList->getByteSize()); tstIterator(vintList, ints); } -static void tstViaBitSet(Collection ints, int32_t expectedByteSize) -{ +static void tstViaBitSet(Collection ints, int32_t expectedByteSize) { int32_t MAX_INT_FOR_BITSET = 1024 * 1024; BitSetPtr bs = newLucene(); - for (int32_t i = 0; i < ints.size(); ++i) - { - if (ints[i] > MAX_INT_FOR_BITSET) - return; // BitSet takes too much memory - if ((i > 0) && (ints[i - 1] == ints[i])) - return; // BitSet cannot store duplicate. + for (int32_t i = 0; i < ints.size(); ++i) { + if (ints[i] > MAX_INT_FOR_BITSET) { + return; // BitSet takes too much memory + } + if ((i > 0) && (ints[i - 1] == ints[i])) { + return; // BitSet cannot store duplicate. + } bs->set(ints[i]); } SortedVIntListPtr svil = newLucene(bs); @@ -86,130 +84,107 @@ static void tstViaBitSet(Collection ints, int32_t expectedByteSize) tstVIntList(newLucene(svil->iterator()), ints, expectedByteSize); } -static void tstInts(Collection ints) -{ +static void tstInts(Collection ints) { int32_t expectedByteSize = vIntListByteSize(ints); tstVIntList(newLucene(ints), ints, expectedByteSize); tstViaBitSet(ints, expectedByteSize); } -static Collection fibArray(int32_t a, int32_t b, int32_t size) -{ +static Collection fibArray(int32_t a, int32_t b, int32_t size) { Collection fib = Collection::newInstance(size); fib[0] = a; fib[1] = b; - for (int32_t i = 2; i < size; ++i) + for (int32_t i = 2; i < size; ++i) { fib[i] = fib[i - 1] + fib[i - 2]; + } return fib; } /// reverse the order of the successive differences -static Collection reverseDiffs(Collection ints) -{ +static Collection reverseDiffs(Collection ints) { Collection res = Collection::newInstance(ints.size()); - for (int32_t i = 0; i < ints.size(); ++i) + for (int32_t i = 0; i < ints.size(); ++i) { res[i] = ints[ints.size() - 1] + (ints[0] - ints[ints.size() - 1 - i]); + } return res; } -static void tstIllegalArgExc(Collection ints) -{ - try - { +static void tstIllegalArgExc(Collection ints) { + try { newLucene(ints); - } - catch (IllegalArgumentException& e) - { + } catch (IllegalArgumentException& e) { EXPECT_TRUE(check_exception(LuceneException::IllegalArgument)(e)); } } -TEST_F(SortedVIntListTest, test01) -{ +TEST_F(SortedVIntListTest, test01) { tstInts(Collection::newInstance()); } -TEST_F(SortedVIntListTest, test02) -{ +TEST_F(SortedVIntListTest, test02) { tstInts(newCollection(0)); } -TEST_F(SortedVIntListTest, test04a) -{ +TEST_F(SortedVIntListTest, test04a) { tstInts(newCollection(0, VB2 - 1)); } -TEST_F(SortedVIntListTest, test04b) -{ +TEST_F(SortedVIntListTest, test04b) { tstInts(newCollection(0, VB2)); } -TEST_F(SortedVIntListTest, test04c) -{ +TEST_F(SortedVIntListTest, test04c) { tstInts(newCollection(0, VB2 + 1)); } -TEST_F(SortedVIntListTest, test05) -{ +TEST_F(SortedVIntListTest, test05) { tstInts(fibArray(0, 1, 7)); // includes duplicate value 1 } -TEST_F(SortedVIntListTest, test05b) -{ +TEST_F(SortedVIntListTest, test05b) { tstInts(reverseDiffs(fibArray(0, 1, 7))); // includes duplicate value 1 } -TEST_F(SortedVIntListTest, test06) -{ +TEST_F(SortedVIntListTest, test06) { tstInts(fibArray(1, 2, 45)); // no duplicates, size 46 exceeds max int. } -TEST_F(SortedVIntListTest, test06b) -{ +TEST_F(SortedVIntListTest, test06b) { tstInts(reverseDiffs(fibArray(1, 2, 45))); // includes duplicate value 1 } -TEST_F(SortedVIntListTest, test07a) -{ +TEST_F(SortedVIntListTest, test07a) { tstInts(newCollection(0, VB3)); } -TEST_F(SortedVIntListTest, test07b) -{ +TEST_F(SortedVIntListTest, test07b) { tstInts(newCollection(1, VB3 + 2)); } -TEST_F(SortedVIntListTest, test07c) -{ +TEST_F(SortedVIntListTest, test07c) { tstInts(newCollection(2, VB3 + 4)); } -TEST_F(SortedVIntListTest, test08a) -{ +TEST_F(SortedVIntListTest, test08a) { tstInts(newCollection(0, VB4 + 1)); } -TEST_F(SortedVIntListTest, test08b) -{ +TEST_F(SortedVIntListTest, test08b) { tstInts(newCollection(1, VB4 + 1)); } -TEST_F(SortedVIntListTest, test08c) -{ +TEST_F(SortedVIntListTest, test08c) { tstInts(newCollection(2, VB4 + 1)); } -TEST_F(SortedVIntListTest, test10) -{ +TEST_F(SortedVIntListTest, test10) { tstIllegalArgExc(newCollection(-1)); } -TEST_F(SortedVIntListTest, test11) -{ +TEST_F(SortedVIntListTest, test11) { tstIllegalArgExc(newCollection(1, 0)); } -TEST_F(SortedVIntListTest, test12) -{ +TEST_F(SortedVIntListTest, test12) { tstIllegalArgExc(newCollection(0, 1, 1, 2, 3, 5, 8, 0)); } diff --git a/src/test/util/StringReaderTest.cpp b/src/test/util/StringReaderTest.cpp index e928f49b..328e37a6 100644 --- a/src/test/util/StringReaderTest.cpp +++ b/src/test/util/StringReaderTest.cpp @@ -12,8 +12,7 @@ using namespace Lucene; typedef LuceneTestFixture StringReaderTest; -TEST_F(StringReaderTest, testStringReaderChar) -{ +TEST_F(StringReaderTest, testStringReaderChar) { StringReader reader(L"Test string"); EXPECT_EQ((wchar_t)reader.read(), L'T'); EXPECT_EQ((wchar_t)reader.read(), L'e'); @@ -29,8 +28,7 @@ TEST_F(StringReaderTest, testStringReaderChar) EXPECT_EQ(reader.read(), StringReader::READER_EOF); } -TEST_F(StringReaderTest, testStringReaderBuffer) -{ +TEST_F(StringReaderTest, testStringReaderBuffer) { StringReader reader(L"Longer test string"); wchar_t buffer[50]; @@ -48,8 +46,7 @@ TEST_F(StringReaderTest, testStringReaderBuffer) EXPECT_EQ(reader.read(buffer, 0, 1), StringReader::READER_EOF); } -TEST_F(StringReaderTest, testStringReaderReset) -{ +TEST_F(StringReaderTest, testStringReaderReset) { StringReader reader(L"Longer test string"); wchar_t buffer[50]; @@ -61,8 +58,7 @@ TEST_F(StringReaderTest, testStringReaderReset) EXPECT_EQ(String(buffer, 6), L"Longer"); } -TEST_F(StringReaderTest, testStringReaderPastEOF) -{ +TEST_F(StringReaderTest, testStringReaderPastEOF) { StringReader reader(L"Short string"); wchar_t buffer[50]; diff --git a/src/test/util/StringUtilsTest.cpp b/src/test/util/StringUtilsTest.cpp index a32e911f..2e7089bb 100644 --- a/src/test/util/StringUtilsTest.cpp +++ b/src/test/util/StringUtilsTest.cpp @@ -14,14 +14,12 @@ using namespace Lucene; typedef LuceneTestFixture StringUtilsTest; -TEST_F(StringUtilsTest, testToUtf8) -{ +TEST_F(StringUtilsTest, testToUtf8) { String testString(L"this is a ascii string"); EXPECT_EQ(StringUtils::toUTF8(testString), "this is a ascii string"); } -TEST_F(StringUtilsTest, testToUtf8CharArray) -{ +TEST_F(StringUtilsTest, testToUtf8CharArray) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(testString.length())); std::copy(testString.begin(), testString.end(), testArray.get()); @@ -30,8 +28,7 @@ TEST_F(StringUtilsTest, testToUtf8CharArray) EXPECT_EQ(SingleString((char*)expectedUft8.get(), 22), "this is a ascii string"); } -TEST_F(StringUtilsTest, testToUtf8ArrayWithOffset) -{ +TEST_F(StringUtilsTest, testToUtf8ArrayWithOffset) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(testString.size())); std::copy(testString.begin(), testString.end(), testArray.get()); @@ -41,8 +38,7 @@ TEST_F(StringUtilsTest, testToUtf8ArrayWithOffset) EXPECT_EQ(SingleString((char*)expectedUft8.get(), 12), "ascii string"); } -TEST_F(StringUtilsTest, testToUtf8Result) -{ +TEST_F(StringUtilsTest, testToUtf8Result) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(testString.size())); std::copy(testString.begin(), testString.end(), testArray.get()); @@ -52,8 +48,7 @@ TEST_F(StringUtilsTest, testToUtf8Result) EXPECT_EQ(SingleString((char*)utf8Result->result.get(), 22), "this is a ascii string"); } -TEST_F(StringUtilsTest, testToUtf8ArrayWithTerminator) -{ +TEST_F(StringUtilsTest, testToUtf8ArrayWithTerminator) { String testString(L"this is a ascii string"); CharArray testArray(CharArray::newInstance(50)); std::copy(testString.begin(), testString.end(), testArray.get()); @@ -63,14 +58,12 @@ TEST_F(StringUtilsTest, testToUtf8ArrayWithTerminator) EXPECT_EQ(SingleString((char*)expectedUft8.get(), 22), "this is a ascii string"); } -TEST_F(StringUtilsTest, testToUnicode) -{ +TEST_F(StringUtilsTest, testToUnicode) { SingleString testString("this is a unicode string"); EXPECT_EQ(StringUtils::toUnicode(testString), L"this is a unicode string"); } -TEST_F(StringUtilsTest, testToUnicodeResult) -{ +TEST_F(StringUtilsTest, testToUnicodeResult) { SingleString testString("this is a unicode string"); ByteArray testArray(ByteArray::newInstance(testString.length())); std::copy(testString.begin(), testString.end(), testArray.get()); @@ -81,34 +74,29 @@ TEST_F(StringUtilsTest, testToUnicodeResult) } -TEST_F(StringUtilsTest, testToStringInteger) -{ +TEST_F(StringUtilsTest, testToStringInteger) { EXPECT_EQ(StringUtils::toString((int32_t)1234), L"1234"); } -TEST_F(StringUtilsTest, testToStringLong) -{ +TEST_F(StringUtilsTest, testToStringLong) { EXPECT_EQ(StringUtils::toString((int64_t)1234), L"1234"); } -TEST_F(StringUtilsTest, testToStringBase) -{ +TEST_F(StringUtilsTest, testToStringBase) { EXPECT_EQ(StringUtils::toString(1234, 4), L"103102"); EXPECT_EQ(StringUtils::toString(1234, 10), L"1234"); EXPECT_EQ(StringUtils::toString(1234, 16), L"4d2"); EXPECT_EQ(StringUtils::toString(1234, StringUtils::CHARACTER_MAX_RADIX), L"ya"); } -TEST_F(StringUtilsTest, testToLongBase) -{ +TEST_F(StringUtilsTest, testToLongBase) { EXPECT_EQ(StringUtils::toLong(L"1234", 4), 112); EXPECT_EQ(StringUtils::toLong(L"1234", 10), 1234); EXPECT_EQ(StringUtils::toLong(L"1234", 16), 4660); EXPECT_EQ(StringUtils::toLong(L"1234", StringUtils::CHARACTER_MAX_RADIX), 49360); } -TEST_F(StringUtilsTest, testToStringLongBase) -{ +TEST_F(StringUtilsTest, testToStringLongBase) { EXPECT_EQ(StringUtils::toString(1234, 4), L"103102"); EXPECT_EQ(StringUtils::toLong(L"103102", 4), 1234); @@ -122,21 +110,20 @@ TEST_F(StringUtilsTest, testToStringLongBase) EXPECT_EQ(StringUtils::toLong(L"ya", StringUtils::CHARACTER_MAX_RADIX), 1234); } -TEST_F(StringUtilsTest, testToHash) -{ +TEST_F(StringUtilsTest, testToHash) { EXPECT_EQ(StringUtils::hashCode(L"test"), 3556498); EXPECT_EQ(StringUtils::hashCode(L"string"), -891985903); } -TEST_F(StringUtilsTest, testUTF8Performance) -{ +TEST_F(StringUtilsTest, testUTF8Performance) { uint64_t startTime = MiscUtils::currentTimeMillis(); static const int32_t maxIter = 1000000; String unicode = L"this is a unicode string"; - for (int32_t i = 0; i < maxIter; ++i) + for (int32_t i = 0; i < maxIter; ++i) { StringUtils::toUTF8(unicode); + } // std::cout << "Encode utf8 (string): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; @@ -145,8 +132,9 @@ TEST_F(StringUtilsTest, testUTF8Performance) startTime = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < maxIter; ++i) + for (int32_t i = 0; i < maxIter; ++i) { StringUtils::toUTF8(unicodeChar, unicodeLength); + } // std::cout << "Encode utf8 (pointer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; @@ -154,21 +142,22 @@ TEST_F(StringUtilsTest, testUTF8Performance) startTime = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < maxIter; ++i) + for (int32_t i = 0; i < maxIter; ++i) { StringUtils::toUTF8(unicodeChar, unicodeLength, utf8); + } // std::cout << "Encode utf8 (buffer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; } -TEST_F(StringUtilsTest, testUnicodePerformance) -{ +TEST_F(StringUtilsTest, testUnicodePerformance) { uint64_t startTime = MiscUtils::currentTimeMillis(); static const int32_t maxIter = 1000000; SingleString utf8 = "this is a utf8 string"; - for (int32_t i = 0; i < maxIter; ++i) + for (int32_t i = 0; i < maxIter; ++i) { StringUtils::toUnicode(utf8); + } // std::cout << "Decode utf8 (string): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; @@ -177,8 +166,9 @@ TEST_F(StringUtilsTest, testUnicodePerformance) startTime = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < maxIter; ++i) + for (int32_t i = 0; i < maxIter; ++i) { StringUtils::toUnicode(utf8Char, utf8Length); + } // std::cout << "Decode utf8 (pointer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; @@ -186,8 +176,9 @@ TEST_F(StringUtilsTest, testUnicodePerformance) startTime = MiscUtils::currentTimeMillis(); - for (int32_t i = 0; i < maxIter; ++i) + for (int32_t i = 0; i < maxIter; ++i) { StringUtils::toUnicode(utf8Char, utf8Length, unicode); + } // std::cout << "Decode utf8 (buffer): " << (MiscUtils::currentTimeMillis() - startTime) << "ms"; } diff --git a/src/test/util/TestUtils.cpp b/src/test/util/TestUtils.cpp index 0261b947..c479bff8 100644 --- a/src/test/util/TestUtils.cpp +++ b/src/test/util/TestUtils.cpp @@ -15,170 +15,182 @@ #include "MiscUtils.h" #include "FileUtils.h" -namespace Lucene -{ - static RandomPtr randomTest = newLucene(); - static String testDir; +namespace Lucene { - void setTestDir(const String& dir) - { - testDir = dir; +static RandomPtr randomTest = newLucene(); +static String testDir; + +void setTestDir(const String& dir) { + testDir = dir; +} + +String getTestDir() { + if (testDir.empty()) { + boost::throw_exception(RuntimeException(L"test directory not set")); } + return testDir; +} - String getTestDir() - { - if (testDir.empty()) - boost::throw_exception(RuntimeException(L"test directory not set")); - return testDir; +String getTempDir() { + static String tempDir; + + if (tempDir.empty()) { + tempDir = FileUtils::joinPath(getTestDir(), L"temp"); + FileUtils::createDirectory(tempDir); } - String getTempDir() - { - static String tempDir; + return tempDir; +} - if (tempDir.empty()) - { - tempDir = FileUtils::joinPath(getTestDir(), L"temp"); - FileUtils::createDirectory(tempDir); - } +String getTempDir(const String& desc) { + return FileUtils::joinPath(getTempDir(), desc + L"." + StringUtils::toString(randomTest->nextInt())); +} - return tempDir; - } +void syncConcurrentMerges(const IndexWriterPtr& writer) { + syncConcurrentMerges(writer->getMergeScheduler()); +} - String getTempDir(const String& desc) - { - return FileUtils::joinPath(getTempDir(), desc + L"." + StringUtils::toString(randomTest->nextInt())); +void syncConcurrentMerges(const MergeSchedulerPtr& ms) { + if (MiscUtils::typeOf(ms)) { + boost::dynamic_pointer_cast(ms)->sync(); } +} - void syncConcurrentMerges(const IndexWriterPtr& writer) - { - syncConcurrentMerges(writer->getMergeScheduler()); - } +String intToEnglish(int32_t i) { + String english(_intToEnglish(i)); + boost::trim(english); + return english; +} - void syncConcurrentMerges(const MergeSchedulerPtr& ms) - { - if (MiscUtils::typeOf(ms)) - boost::dynamic_pointer_cast(ms)->sync(); +String _intToEnglish(int32_t i) { + String english; + if (i == 0) { + return L"zero"; } - - String intToEnglish(int32_t i) - { - String english(_intToEnglish(i)); - boost::trim(english); - return english; + if (i < 0) { + english += L"minus "; + i = -i; } - - String _intToEnglish(int32_t i) - { - String english; - if (i == 0) - return L"zero"; - if (i < 0) - { - english += L"minus "; - i = -i; - } - if (i >= 1000000000) // billions - { - english += _intToEnglish(i / 1000000000); - english += L"billion, "; - i = i % 1000000000; - } - if (i >= 1000000) // millions - { - english += _intToEnglish(i / 1000000); - english += L"million, "; - i = i % 1000000; - } - if (i >= 1000) // thousands - { - english += _intToEnglish(i / 1000); - english += L"thousand, "; - i = i % 1000; - } - if (i >= 100) // hundreds - { - english += _intToEnglish(i / 100); - english += L"hundred "; - i = i % 100; - } - if (i >= 20) - { - switch (i/10) - { - case 9: english += L"ninety"; - break; - case 8: english += L"eighty"; - break; - case 7: english += L"seventy"; - break; - case 6: english += L"sixty"; - break; - case 5: english += L"fifty"; - break; - case 4: english += L"forty"; - break; - case 3: english += L"thirty"; - break; - case 2: english += L"twenty"; - break; - } - i = i % 10; - english += i == 0 ? L" " : L"-"; - } - switch (i) - { - case 19: english += L"nineteen "; - break; - case 18: english += L"eighteen "; - break; - case 17: english += L"seventeen "; - break; - case 16: english += L"sixteen "; - break; - case 15: english += L"fifteen "; - break; - case 14: english += L"fourteen "; - break; - case 13: english += L"thirteen "; - break; - case 12: english += L"twelve "; - break; - case 11: english += L"eleven "; - break; - case 10: english += L"ten "; - break; - case 9: english += L"nine "; - break; - case 8: english += L"eight "; - break; - case 7: english += L"seven "; - break; - case 6: english += L"six "; - break; - case 5: english += L"five "; - break; - case 4: english += L"four "; - break; - case 3: english += L"three "; - break; - case 2: english += L"two "; - break; - case 1: english += L"one "; - break; + if (i >= 1000000000) { // billions + english += _intToEnglish(i / 1000000000); + english += L"billion, "; + i = i % 1000000000; + } + if (i >= 1000000) { // millions + english += _intToEnglish(i / 1000000); + english += L"million, "; + i = i % 1000000; + } + if (i >= 1000) { // thousands + english += _intToEnglish(i / 1000); + english += L"thousand, "; + i = i % 1000; + } + if (i >= 100) { // hundreds + english += _intToEnglish(i / 100); + english += L"hundred "; + i = i % 100; + } + if (i >= 20) { + switch (i/10) { + case 9: + english += L"ninety"; + break; + case 8: + english += L"eighty"; + break; + case 7: + english += L"seventy"; + break; + case 6: + english += L"sixty"; + break; + case 5: + english += L"fifty"; + break; + case 4: + english += L"forty"; + break; + case 3: + english += L"thirty"; + break; + case 2: + english += L"twenty"; + break; } - return english; + i = i % 10; + english += i == 0 ? L" " : L"-"; } + switch (i) { + case 19: + english += L"nineteen "; + break; + case 18: + english += L"eighteen "; + break; + case 17: + english += L"seventeen "; + break; + case 16: + english += L"sixteen "; + break; + case 15: + english += L"fifteen "; + break; + case 14: + english += L"fourteen "; + break; + case 13: + english += L"thirteen "; + break; + case 12: + english += L"twelve "; + break; + case 11: + english += L"eleven "; + break; + case 10: + english += L"ten "; + break; + case 9: + english += L"nine "; + break; + case 8: + english += L"eight "; + break; + case 7: + english += L"seven "; + break; + case 6: + english += L"six "; + break; + case 5: + english += L"five "; + break; + case 4: + english += L"four "; + break; + case 3: + english += L"three "; + break; + case 2: + english += L"two "; + break; + case 1: + english += L"one "; + break; + } + return english; +} - bool checkIndex(const DirectoryPtr& dir) - { - CheckIndexPtr checker = newLucene(dir); - IndexStatusPtr indexStatus = checker->checkIndex(); - if (!indexStatus || !indexStatus->clean) - { - boost::throw_exception(RuntimeException(L"CheckIndex failed")); - return false; - } - return true; +bool checkIndex(const DirectoryPtr& dir) { + CheckIndexPtr checker = newLucene(dir); + IndexStatusPtr indexStatus = checker->checkIndex(); + if (!indexStatus || !indexStatus->clean) { + boost::throw_exception(RuntimeException(L"CheckIndex failed")); + return false; } + return true; +} + } diff --git a/src/test/util/VersionTest.cpp b/src/test/util/VersionTest.cpp index 3236bd2b..d2d53967 100644 --- a/src/test/util/VersionTest.cpp +++ b/src/test/util/VersionTest.cpp @@ -11,10 +11,10 @@ using namespace Lucene; typedef LuceneTestFixture VersionTest; -TEST_F(VersionTest, testVersion) -{ - for (int32_t version = (int32_t)LuceneVersion::LUCENE_20; version <= (int32_t)LuceneVersion::LUCENE_CURRENT; ++version) +TEST_F(VersionTest, testVersion) { + for (int32_t version = (int32_t)LuceneVersion::LUCENE_20; version <= (int32_t)LuceneVersion::LUCENE_CURRENT; ++version) { EXPECT_TRUE(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_CURRENT, (LuceneVersion::Version)version)); + } EXPECT_TRUE(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_30, LuceneVersion::LUCENE_29)); EXPECT_TRUE(LuceneVersion::onOrAfter(LuceneVersion::LUCENE_30, LuceneVersion::LUCENE_30)); EXPECT_TRUE(!LuceneVersion::onOrAfter(LuceneVersion::LUCENE_29, LuceneVersion::LUCENE_30)); From c9c09bcf06c52db7bf0d7f04041aa492f7c9f08b Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sat, 19 Apr 2014 19:26:40 +0100 Subject: [PATCH 057/157] Release version 3.0.6. --- CMakeLists.txt | 2 +- README.rst | 2 +- doxygen/lucene++ | 2 +- src/core/util/Constants.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a15d7cf..9217c21f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 2.8.6) set(lucene++_VERSION_MAJOR 3) set(lucene++_VERSION_MINOR 0) -set(lucene++_VERSION_PATCH 5) +set(lucene++_VERSION_PATCH 6) set(lucene++_SOVERSION "0") diff --git a/README.rst b/README.rst index be73647e..da956322 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Lucene++ ========== -Welcome to lucene++ version **3.0.5**. +Welcome to lucene++ version **3.0.6**. Lucene++ is an up to date C++ port of the popular Java `Lucene `_ library, a high-performance, full-featured text search engine. diff --git a/doxygen/lucene++ b/doxygen/lucene++ index 3ddd69c7..f2faab46 100644 --- a/doxygen/lucene++ +++ b/doxygen/lucene++ @@ -31,7 +31,7 @@ PROJECT_NAME = Lucene++ # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 3.0.5 +PROJECT_NUMBER = 3.0.6 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/src/core/util/Constants.cpp b/src/core/util/Constants.cpp index 07898160..81724b9c 100644 --- a/src/core/util/Constants.cpp +++ b/src/core/util/Constants.cpp @@ -21,8 +21,8 @@ String Constants::OS_NAME = L"Mac"; String Constants::OS_NAME = L"BSD"; #endif -String Constants::LUCENE_MAIN_VERSION = L"3.0.5"; -String Constants::LUCENE_VERSION = L"3.0.5"; +String Constants::LUCENE_MAIN_VERSION = L"3.0.6"; +String Constants::LUCENE_VERSION = L"3.0.6"; Constants::Constants() { // private From b07d6ae3bd914f044610c577765d9bd9ff4a5248 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Wed, 23 Apr 2014 09:44:25 +0200 Subject: [PATCH 058/157] Rename MAX/MIN_PRIORITY to avoid conflicts on windows platform. --- include/LuceneThread.h | 6 +++--- src/core/index/ConcurrentMergeScheduler.cpp | 8 ++++---- src/core/util/LuceneThread.cpp | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/LuceneThread.h b/include/LuceneThread.h index 8f99bc93..2a5c33a2 100644 --- a/include/LuceneThread.h +++ b/include/LuceneThread.h @@ -28,9 +28,9 @@ class LPPAPI LuceneThread : public LuceneObject { LUCENE_CLASS(LuceneThread); public: - static const int32_t MAX_PRIORITY; - static const int32_t NORM_PRIORITY; - static const int32_t MIN_PRIORITY; + static const int32_t MAX_THREAD_PRIORITY; + static const int32_t NORM_THREAD_PRIORITY; + static const int32_t MIN_THREAD_PRIORITY; protected: threadPtr thread; diff --git a/src/core/index/ConcurrentMergeScheduler.cpp b/src/core/index/ConcurrentMergeScheduler.cpp index a24a261e..61c1ab15 100644 --- a/src/core/index/ConcurrentMergeScheduler.cpp +++ b/src/core/index/ConcurrentMergeScheduler.cpp @@ -53,9 +53,9 @@ int32_t ConcurrentMergeScheduler::getMergeThreadPriority() { void ConcurrentMergeScheduler::setMergeThreadPriority(int32_t pri) { SyncLock syncLock(this); - if (pri > LuceneThread::MAX_PRIORITY || pri < LuceneThread::MIN_PRIORITY) { - boost::throw_exception(IllegalArgumentException(L"priority must be in range " + StringUtils::toString(LuceneThread::MIN_PRIORITY) + - L" .. " + StringUtils::toString(LuceneThread::MAX_PRIORITY) + L" inclusive")); + if (pri > LuceneThread::MAX_THREAD_PRIORITY || pri < LuceneThread::MIN_THREAD_PRIORITY) { + boost::throw_exception(IllegalArgumentException(L"priority must be in range " + StringUtils::toString(LuceneThread::MIN_THREAD_PRIORITY) + + L" .. " + StringUtils::toString(LuceneThread::MAX_THREAD_PRIORITY) + L" inclusive")); } mergeThreadPriority = pri; @@ -78,7 +78,7 @@ void ConcurrentMergeScheduler::initMergeThreadPriority() { SyncLock syncLock(this); if (mergeThreadPriority == -1) { // Default to slightly higher priority than our calling thread - mergeThreadPriority = std::min(LuceneThread::NORM_PRIORITY + 1, LuceneThread::MAX_PRIORITY); + mergeThreadPriority = std::min(LuceneThread::NORM_THREAD_PRIORITY + 1, LuceneThread::MAX_THREAD_PRIORITY); } } diff --git a/src/core/util/LuceneThread.cpp b/src/core/util/LuceneThread.cpp index 383d0ae6..591caa02 100644 --- a/src/core/util/LuceneThread.cpp +++ b/src/core/util/LuceneThread.cpp @@ -11,13 +11,13 @@ namespace Lucene { #if defined(_WIN32) || defined(_WIN64) -const int32_t LuceneThread::MAX_PRIORITY = THREAD_PRIORITY_HIGHEST; -const int32_t LuceneThread::NORM_PRIORITY = THREAD_PRIORITY_NORMAL; -const int32_t LuceneThread::MIN_PRIORITY = THREAD_PRIORITY_LOWEST; +const int32_t LuceneThread::MAX_THREAD_PRIORITY = THREAD_PRIORITY_HIGHEST; +const int32_t LuceneThread::NORM_THREAD_PRIORITY = THREAD_PRIORITY_NORMAL; +const int32_t LuceneThread::MIN_THREAD_PRIORITY = THREAD_PRIORITY_LOWEST; #else -const int32_t LuceneThread::MAX_PRIORITY = 2; -const int32_t LuceneThread::NORM_PRIORITY = 0; -const int32_t LuceneThread::MIN_PRIORITY = -2; +const int32_t LuceneThread::MAX_THREAD_PRIORITY = 2; +const int32_t LuceneThread::NORM_THREAD_PRIORITY = 0; +const int32_t LuceneThread::MIN_THREAD_PRIORITY = -2; #endif LuceneThread::LuceneThread() { @@ -67,9 +67,9 @@ void LuceneThread::setPriority(int32_t priority) { int32_t LuceneThread::getPriority() { #if defined(_WIN32) || defined(_WIN64) - return thread ? GetThreadPriority(thread->native_handle()) : NORM_PRIORITY; + return thread ? GetThreadPriority(thread->native_handle()) : NORM_THREAD_PRIORITY; #else - return NORM_PRIORITY; + return NORM_THREAD_PRIORITY; #endif } From 23416f748caaada7bd81ce48416b2ca0c0c6da06 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 24 Apr 2014 15:10:31 +0200 Subject: [PATCH 059/157] Bug #53: Completed quoting for parameters of some CMake commands A wiki article pointed out that whitespace will only be preserved for parameters in CMake commands if passed strings will be appropriately quoted or escaped. http://cmake.org/Wiki/CMake/Language_Syntax#CMake_splits_arguments_unless_you_use_quotation_marks_or_escapes. Quoting was added so that more places should also handle file names correctly which contain space characters or semicolons eventually. Signed-off-by: Markus Elfring --- CMakeLists.txt | 21 +++++++++++---------- cmake/CreateLucene++Packages.cmake | 6 +++--- cmake/Lucene++Docs.cmake | 22 ++++++++++++---------- src/contrib/CMakeLists.txt | 12 ++++++------ src/core/CMakeLists.txt | 8 ++++---- src/demo/CMakeLists.txt | 10 +++++----- src/test/CMakeLists.txt | 16 ++++++++-------- 7 files changed, 49 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9217c21f..b0f3f208 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,12 +105,12 @@ endif() # generate Config.h ################################# configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/include/Config.h.cmake - ${CMAKE_CURRENT_BINARY_DIR}/include/Config.h @ONLY + "${CMAKE_CURRENT_SOURCE_DIR}/include/Config.h.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/include/Config.h" @ONLY ) include_directories( - ${CMAKE_CURRENT_BINARY_DIR}/include + "${CMAKE_CURRENT_BINARY_DIR}/include" ) include(CMakeExternal.txt) @@ -126,16 +126,16 @@ add_subdirectory(src/test) ################################# if(NOT WIN32) configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/liblucene++.pc.cmake - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc @ONLY) + "${CMAKE_CURRENT_SOURCE_DIR}/liblucene++.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc" @ONLY) configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/liblucene++-contrib.pc.cmake - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc @ONLY) + "${CMAKE_CURRENT_SOURCE_DIR}/liblucene++-contrib.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc" @ONLY) install( FILES - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc - ${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc - DESTINATION ${LIB_DESTINATION}/pkgconfig) + "${CMAKE_CURRENT_BINARY_DIR}/liblucene++.pc" + "${CMAKE_CURRENT_BINARY_DIR}/liblucene++-contrib.pc" + DESTINATION "${LIB_DESTINATION}/pkgconfig") endif() #################################### @@ -150,6 +150,7 @@ configure_file( add_custom_target( uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + VERBATIM ) if(ENABLE_PACKAGING) diff --git a/cmake/CreateLucene++Packages.cmake b/cmake/CreateLucene++Packages.cmake index 4c11f99e..2c3e98b6 100644 --- a/cmake/CreateLucene++Packages.cmake +++ b/cmake/CreateLucene++Packages.cmake @@ -39,7 +39,7 @@ set(CPACK_RPM_PACKAGE_GROUP "libs") set(CPACK_RPM_PACKAGE_REQUIRES "libboost-date-time1.42.0, libboost-filesystem1.42.0, libboost-regex1.42.0, libboost-thread1.42.0, libboost-iostreams1.42.0") #don't include the current binary dir. -get_filename_component(lucene++_BINARY_DIR_name ${lucene++_BINARY_DIR} NAME) +get_filename_component(lucene++_BINARY_DIR_name "${lucene++_BINARY_DIR}" NAME) set(CPACK_SOURCE_IGNORE_FILES "/\\\\.svn/" "/\\\\.git/" @@ -70,11 +70,11 @@ endif() add_custom_target(dist-package - COMMAND rsync -avP -e ssh ${CPACK_PACKAGE_FILE_NAME}.* ustramooner@frs.sourceforge.net:uploads/ + COMMAND rsync -avP -e ssh "${CPACK_PACKAGE_FILE_NAME}.*" ustramooner@frs.sourceforge.net:uploads/ # DEPENDS package ) add_custom_target(dist-package_source - COMMAND rsync -avP -e ssh ${CPACK_SOURCE_PACKAGE_FILE_NAME}.* ustramooner@frs.sourceforge.net:uploads/ + COMMAND rsync -avP -e ssh "${CPACK_SOURCE_PACKAGE_FILE_NAME}.*" ustramooner@frs.sourceforge.net:uploads/ # DEPENDS package_source ) diff --git a/cmake/Lucene++Docs.cmake b/cmake/Lucene++Docs.cmake index da0f4b23..476f984d 100644 --- a/cmake/Lucene++Docs.cmake +++ b/cmake/Lucene++Docs.cmake @@ -62,7 +62,8 @@ IF (ENABLE_DOCS) # It runs the final generated Doxyfile against it. # The DOT_PATH is substituted into the Doxyfile. ADD_CUSTOM_TARGET(doc - ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/doc/doxyfile + "${DOXYGEN_EXECUTABLE}" "${PROJECT_BINARY_DIR}/doc/doxyfile" + VERBATIM ) IF ( DOCS_HTML_HELP ) @@ -78,11 +79,11 @@ IF (ENABLE_DOCS) IF ( CYGWIN ) EXECUTE_PROCESS ( COMMAND cygpath "${HTML_HELP_COMPILER}" OUTPUT_VARIABLE HTML_HELP_COMPILER_EX ) - STRING ( REPLACE "\n" "" HTML_HELP_COMPILER_EX ${HTML_HELP_COMPILER_EX} ) - STRING ( REPLACE "\r" "" HTML_HELP_COMPILER_EX ${HTML_HELP_COMPILER_EX} ) + STRING ( REPLACE "\n" "" HTML_HELP_COMPILER_EX "${HTML_HELP_COMPILER_EX}" ) + STRING ( REPLACE "\r" "" HTML_HELP_COMPILER_EX "${HTML_HELP_COMPILER_EX}" ) SET ( HTML_HELP_COMPILER_EX "\"${HTML_HELP_COMPILER_EX}\"" ) ELSE ( CYGWIN ) - SET ( HTML_HELP_COMPILER_EX ${HTML_HELP_COMPILER} ) + SET ( HTML_HELP_COMPILER_EX "${HTML_HELP_COMPILER}" ) ENDIF ( CYGWIN ) ENDIF ( DOCS_HTML_HELP ) @@ -123,10 +124,10 @@ IF (ENABLE_DOCS) ENDIF ( DOCS_TAGFILE ) # This processes our Doxyfile.cmake and substitutes paths to generate a final Doxyfile - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/Doxyfile.cmake ${PROJECT_BINARY_DIR}/doc/doxyfile ) - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/helpheader.htm.cmake ${PROJECT_BINARY_DIR}/doc/helpheader.htm ) - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/helpfooter.htm.cmake ${PROJECT_BINARY_DIR}/doc/helpfooter.htm ) - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/doxygen.css.cmake ${PROJECT_BINARY_DIR}/doc/html/doxygen.css ) + CONFIGURE_FILE("${PROJECT_SOURCE_DIR}/doc/Doxyfile.cmake" "${PROJECT_BINARY_DIR}/doc/doxyfile") + CONFIGURE_FILE("${PROJECT_SOURCE_DIR}/doc/helpheader.htm.cmake" "${PROJECT_BINARY_DIR}/doc/helpheader.htm") + CONFIGURE_FILE("${PROJECT_SOURCE_DIR}/doc/helpfooter.htm.cmake" "${PROJECT_BINARY_DIR}/doc/helpfooter.htm") + CONFIGURE_FILE("${PROJECT_SOURCE_DIR}/doc/doxygen.css.cmake" "${PROJECT_BINARY_DIR}/doc/html/doxygen.css") #create a target for tar.gz html help FIND_PACKAGE(UnixCommands) @@ -135,17 +136,18 @@ IF (ENABLE_DOCS) COMMAND "${TAR}" "-czf" "${PROJECT_BINARY_DIR}/doc/lucene++-doc.tar.gz" ./ WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/doc/html/" #DEPENDS doc + VERBATIM ) ENDIF ( TAR AND GZIP ) #install HTML pages if they were built IF ( DOCS_HTML AND NOT WIN32 ) - INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/html/ DESTINATION share/doc/lucene++-${lucene++_VERSION}) + INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/doc/html/" DESTINATION share/doc/lucene++-${lucene++_VERSION}) ENDIF ( DOCS_HTML AND NOT WIN32 ) #install man pages if they were built IF ( DOCS_MAN ) - INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/man/ DESTINATION man) + INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/doc/man/" DESTINATION man) ENDIF ( DOCS_MAN ) ELSE ( DOXYGEN_FOUND ) diff --git a/src/contrib/CMakeLists.txt b/src/contrib/CMakeLists.txt index 41501c50..76f81e31 100644 --- a/src/contrib/CMakeLists.txt +++ b/src/contrib/CMakeLists.txt @@ -11,16 +11,16 @@ file(GLOB_RECURSE contrib_sources ) file(GLOB_RECURSE contrib_headers - ${lucene++-contrib_SOURCE_DIR}/include/*.h + "${lucene++-contrib_SOURCE_DIR}/include/*.h" ) add_definitions(-DLPP_BUILDING_LIB) include_directories( - ${lucene++_SOURCE_DIR}/include - ${lucene++-lib_SOURCE_DIR}/include - ${lucene++-contrib_SOURCE_DIR}/include - ${lucene++-contrib_SOURCE_DIR}/snowball/libstemmer_c/include + "${lucene++_SOURCE_DIR}/include" + "${lucene++-lib_SOURCE_DIR}/include" + "${lucene++-contrib_SOURCE_DIR}/include" + "${lucene++-contrib_SOURCE_DIR}/snowball/libstemmer_c/include" ${Boost_INCLUDE_DIRS} ) @@ -53,6 +53,6 @@ target_link_libraries(lucene++-contrib cotire(lucene++-contrib) install(TARGETS lucene++-contrib - DESTINATION ${LIB_DESTINATION} + DESTINATION "${LIB_DESTINATION}" COMPONENT runtime ) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 17ed352a..73157d0a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,8 +1,8 @@ project(lucene++-lib) include_directories( - ${lucene++_SOURCE_DIR}/include - ${lucene++-lib_SOURCE_DIR}/include + "${lucene++_SOURCE_DIR}/include" + "${lucene++-lib_SOURCE_DIR}/include" ${Boost_INCLUDE_DIRS} ) @@ -16,7 +16,7 @@ file(GLOB_RECURSE lucene_sources util/*.c*) file(GLOB_RECURSE lucene_internal_headers - ${lucene++-lib_SOURCE_DIR}/include/*.h + "${lucene++-lib_SOURCE_DIR}/include/*.h" ) file(GLOB_RECURSE lucene_headers @@ -49,6 +49,6 @@ install(FILES ${lucene_headers} ) install(TARGETS lucene++ - DESTINATION ${LIB_DESTINATION} + DESTINATION "${LIB_DESTINATION}" COMPONENT runtime ) diff --git a/src/demo/CMakeLists.txt b/src/demo/CMakeLists.txt index 642df8e6..fd1e0eea 100644 --- a/src/demo/CMakeLists.txt +++ b/src/demo/CMakeLists.txt @@ -2,7 +2,7 @@ project(lucene++-demo) file(GLOB_RECURSE demo_headers - ${lucene++-demo_SOURCE_DIR}/../include/*.h + "${lucene++-demo_SOURCE_DIR}/../include/*.h" ) add_definitions(-DLPP_HAVE_DLL) @@ -11,11 +11,11 @@ include_directories( ${Boost_INCLUDE_DIRS} ) include_directories( - ${lucene++_SOURCE_DIR}/include + "${lucene++_SOURCE_DIR}/include" ) add_executable(indexfiles - ${lucene++-demo_SOURCE_DIR}/indexfiles/main.cpp + "${lucene++-demo_SOURCE_DIR}/indexfiles/main.cpp" ${demo_headers} ) target_link_libraries(indexfiles @@ -23,7 +23,7 @@ target_link_libraries(indexfiles ) add_executable(searchfiles - ${lucene++-demo_SOURCE_DIR}/searchfiles/main.cpp + "${lucene++-demo_SOURCE_DIR}/searchfiles/main.cpp" ${demo_headers} ) target_link_libraries(searchfiles @@ -31,7 +31,7 @@ target_link_libraries(searchfiles ) add_executable(deletefiles - ${lucene++-demo_SOURCE_DIR}/deletefiles/main.cpp + "${lucene++-demo_SOURCE_DIR}/deletefiles/main.cpp" ${demo_headers} ) target_link_libraries(deletefiles diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 9400d37c..31bb850e 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,11 +1,11 @@ project(lucene++-tester) include_directories( - ${GTEST_INCLUDE_DIR} - ${lucene++_SOURCE_DIR}/include - ${lucene++-lib_SOURCE_DIR}/include - ${lucene++-contrib_SOURCE_DIR}/include - ${lucene++-tester_SOURCE_DIR}/include + "${GTEST_INCLUDE_DIR}" + "${lucene++_SOURCE_DIR}/include" + "${lucene++-lib_SOURCE_DIR}/include" + "${lucene++-contrib_SOURCE_DIR}/include" + "${lucene++-tester_SOURCE_DIR}/include" ${Boost_INCLUDE_DIRS} ) @@ -22,14 +22,14 @@ file(GLOB_RECURSE tester_sources ) file(GLOB_RECURSE test_headers - ${lucene++-tester_SOURCE_DIR}/../include/*.h - ${lucene++-tester_SOURCE_DIR}/include/*.h + "${lucene++-tester_SOURCE_DIR}/../include/*.h" + "${lucene++-tester_SOURCE_DIR}/include/*.h" ) add_definitions(-DLPP_EXPOSE_INTERNAL) link_directories( - ${GTEST_LIB_DIR} + "${GTEST_LIB_DIR}" ) add_executable(lucene++-tester From 4c1f1371e98c387cb07043c26b99beff5b5111a8 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Mon, 28 Apr 2014 13:53:48 +0100 Subject: [PATCH 060/157] Throw exception in fixture destructor instead of FAIL(). --- src/test/util/LuceneTestFixture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/util/LuceneTestFixture.cpp b/src/test/util/LuceneTestFixture.cpp index 27c61e08..e737bdb1 100644 --- a/src/test/util/LuceneTestFixture.cpp +++ b/src/test/util/LuceneTestFixture.cpp @@ -21,7 +21,7 @@ LuceneTestFixture::~LuceneTestFixture() { if (ConcurrentMergeScheduler::anyUnhandledExceptions()) { // Clear the failure so that we don't just keep failing subsequent test cases ConcurrentMergeScheduler::clearUnhandledExceptions(); - FAIL() << "ConcurrentMergeScheduler hit unhandled exceptions"; + boost::throw_exception(RuntimeException(L"ConcurrentMergeScheduler hit unhandled exceptions")); } } From a8bac06c4c4997310633c8ff13952d28b1c67593 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Mon, 28 Apr 2014 16:56:25 +0100 Subject: [PATCH 061/157] Fix compiler warnings. --- cmake/cotire.cmake | 73 +++++++++++++++++++++------ src/core/CMakeLists.txt | 1 - src/test/index/DocumentWriterTest.cpp | 6 +-- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/cmake/cotire.cmake b/cmake/cotire.cmake index 1661cbb3..ddfe4bfd 100644 --- a/cmake/cotire.cmake +++ b/cmake/cotire.cmake @@ -45,7 +45,7 @@ if (NOT CMAKE_SCRIPT_MODE_FILE) endif() set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.5.2") +set (COTIRE_CMAKE_MODULE_VERSION "1.6.1") include(CMakeParseArguments) include(ProcessorCount) @@ -856,7 +856,7 @@ function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honore # remove duplicate lines to speed up parsing list (REMOVE_DUPLICATES _scanOutput) list (LENGTH _scanOutput _uniqueLen) - if (COTIRE_VERBOSE) + if (COTIRE_VERBOSE OR COTIRE_DEBUG) message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") if (_ignoredExtensions) message (STATUS "Ignored extensions: ${_ignoredExtensions}") @@ -1146,8 +1146,16 @@ function (cotire_generate_prefix_header _prefixFile) return() endif() endif() + set (_prologue "") set (_epilogue "") - if (_option_COMPILER_ID MATCHES "Intel") + if (_option_COMPILER_ID MATCHES "Clang") + set (_prologue "#pragma clang system_header") + elseif (_option_COMPILER_ID MATCHES "GNU") + set (_prologue "#pragma GCC system_header") + elseif (_option_COMPILER_ID MATCHES "MSVC") + set (_prologue "#pragma warning(push, 0)") + set (_epilogue "#pragma warning(pop)") + elseif (_option_COMPILER_ID MATCHES "Intel") # Intel compiler requires hdrstop pragma to stop generating PCH file set (_epilogue "#pragma hdrstop") endif() @@ -1164,7 +1172,8 @@ function (cotire_generate_prefix_header _prefixFile) INCLUDE_PATH ${_option_INCLUDE_PATH} IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} UNPARSED_LINES _unparsedLines) - cotire_generate_unity_source("${_prefixFile}" EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) + cotire_generate_unity_source("${_prefixFile}" + PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) set (_unparsedLinesFile "${_prefixFile}.log") if (_unparsedLines) if (COTIRE_VERBOSE OR NOT _selectedHeaders) @@ -1291,6 +1300,7 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio endif() elseif (_compilerID MATCHES "GNU|Clang") # GCC / Clang options used + # -w disable all warnings # -x specify the source language # -c compile but do not link # -o place output in file @@ -1298,10 +1308,10 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio set (_xLanguage_CXX "c++-header") if (_flags) # append to list - list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + list (APPEND _flags "-w" "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") else() # return as a flag string - set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + set (_flags "-w -x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1400,21 +1410,34 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # -Winvalid-pch warns if precompiled header is found but cannot be used if (_flags) # append to list - list (APPEND _flags "-include" "${_prefixFile}" "-Winvalid-pch") + list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") else() # return as a flag string - set (_flags "-include \"${_prefixFile}\" -Winvalid-pch") + set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") endif() elseif (_compilerID MATCHES "Clang") # Clang options used # -include process include file as the first line of the primary source file + # -include-pch include precompiled header file # -Qunused-arguments don't emit warning for unused driver arguments - if (_flags) - # append to list - list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") + if (_pchFile AND NOT CMAKE_${_language}_COMPILER MATCHES "ccache") + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include-pch" "${_pchFile}") + else() + # return as a flag string + set (_flags "-Qunused-arguments -include-pch \"${_pchFile}\"") + endif() else() - # return as a flag string - set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") + # no precompiled header, force inclusion of prefix header + # ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") + endif() endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1554,6 +1577,13 @@ function (cotire_check_precompiled_header_support _language _targetSourceDir _ta else() set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) endif() + if (CMAKE_${_language}_COMPILER MATCHES "ccache") + if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros") + set (${_msgVar} + "ccache requires the environment variable CCACHE_SLOPPINESS to be set to time_macros." + PARENT_SCOPE) + endif() + endif() if (APPLE) # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) if (CMAKE_CONFIGURATION_TYPES) @@ -1705,8 +1735,11 @@ function (cotire_make_pch_file_path _language _targetSourceDir _target _pchFileV if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") # MSVC uses the extension .pch added to the prefix header base name set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # GCC / Clang look for a precompiled header corresponding to the prefix header with the extension .gch appended + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") # Intel uses the extension .pchi added to the prefix header base name @@ -1768,6 +1801,14 @@ function (cotire_get_prefix_header_dependencies _language _target _dependencySou # depend on target source files marked with custom COTIRE_DEPENDENCY property set (_dependencySources "") cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # Clang raises a fatal error if a file is not found during preprocessing + # thus we depend on target's generated source files for prefix header generation + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN}) + if (_generatedSources) + list (APPEND _dependencySources ${_generatedSources}) + endif() + endif() if (COTIRE_DEBUG AND _dependencySources) message (STATUS "${_language} ${_target} prefix header DEPENDS ${_dependencySources}") endif() @@ -2214,7 +2255,7 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag set (${_targetLanguagesVar} "" PARENT_SCOPE) return() endif() - if (_targetUsePCH AND "${_language}" STREQUAL "C" OR "${_language}" STREQUAL "CXX") + if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$") cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _disableMsg) if (_disableMsg) set (_targetUsePCH FALSE) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 73157d0a..83eb5789 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -40,7 +40,6 @@ cotire(lucene++) set_target_properties(lucene++ PROPERTIES VERSION ${lucene++_VERSION} SOVERSION ${lucene++_SOVERSION} - COMPILE_FLAGS -DLPP_HAVE_DLL ) install(FILES ${lucene_headers} diff --git a/src/test/index/DocumentWriterTest.cpp b/src/test/index/DocumentWriterTest.cpp index a1aab03a..5c48ad8e 100644 --- a/src/test/index/DocumentWriterTest.cpp +++ b/src/test/index/DocumentWriterTest.cpp @@ -231,11 +231,11 @@ TEST_F(DocumentWriterTest, testTokenReuse) { int32_t freq = termPositions->freq(); EXPECT_EQ(3, freq); EXPECT_EQ(0, termPositions->nextPosition()); - EXPECT_EQ(true, termPositions->isPayloadAvailable()); + EXPECT_TRUE(termPositions->isPayloadAvailable()); EXPECT_EQ(6, termPositions->nextPosition()); - EXPECT_EQ(false, termPositions->isPayloadAvailable()); + EXPECT_FALSE(termPositions->isPayloadAvailable()); EXPECT_EQ(7, termPositions->nextPosition()); - EXPECT_EQ(false, termPositions->isPayloadAvailable()); + EXPECT_FALSE(termPositions->isPayloadAvailable()); } namespace TestPreAnalyzedField { From f27e602f1f4a408b26a7db3ae039f2ff89a53ff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Sun, 18 May 2014 19:58:34 +0200 Subject: [PATCH 062/157] Fix various compiler warnings. Fix various warnings produced by Clang: Array.h:32:25: Declaration shadows a field of 'ArrayData' SegmentInfoCollection.h:32:10: 'Lucene::SegmentInfoCollection::equals' hides overloaded virtual function Searchable.h:24:14: 'Lucene::Searchable' has virtual functions but non-virtual destructor Fieldable.h:20:14: 'Lucene::Fieldable' has virtual functions but non-virtual destructor --- include/Array.h | 14 +++++++------- include/Fieldable.h | 1 + include/Searchable.h | 1 + include/SegmentInfoCollection.h | 2 +- src/core/index/SegmentInfoCollection.cpp | 10 ++++++++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/Array.h b/include/Array.h index ada8fec1..7dc30234 100644 --- a/include/Array.h +++ b/include/Array.h @@ -15,9 +15,9 @@ namespace Lucene { template class ArrayData { public: - ArrayData(int32_t size) { + ArrayData(int32_t size_) { data = NULL; - resize(size); + resize(size_); } ~ArrayData() { @@ -29,16 +29,16 @@ class ArrayData { int32_t size; public: - void resize(int32_t size) { - if (size == 0) { + void resize(int32_t size_) { + if (size_ == 0) { FreeMemory(data); data = NULL; } else if (data == NULL) { - data = (TYPE*)AllocMemory(size * sizeof(TYPE)); + data = (TYPE*)AllocMemory(size_ * sizeof(TYPE)); } else { - data = (TYPE*)ReallocMemory(data, size * sizeof(TYPE)); + data = (TYPE*)ReallocMemory(data, size_ * sizeof(TYPE)); } - this->size = size; + this->size = size_; } }; diff --git a/include/Fieldable.h b/include/Fieldable.h index 4846f009..93f7fd5d 100644 --- a/include/Fieldable.h +++ b/include/Fieldable.h @@ -20,6 +20,7 @@ namespace Lucene { class LPPAPI Fieldable { public: LUCENE_INTERFACE(Fieldable); + virtual ~Fieldable() {} public: /// Sets the boost factor hits on this field. This value will be multiplied into the score of all diff --git a/include/Searchable.h b/include/Searchable.h index 856e94d4..7035a76b 100644 --- a/include/Searchable.h +++ b/include/Searchable.h @@ -24,6 +24,7 @@ namespace Lucene { class LPPAPI Searchable { public: LUCENE_INTERFACE(Searchable); + virtual ~Searchable() {} public: /// Lower-level search API. diff --git a/include/SegmentInfoCollection.h b/include/SegmentInfoCollection.h index f05656e7..58819d07 100644 --- a/include/SegmentInfoCollection.h +++ b/include/SegmentInfoCollection.h @@ -29,7 +29,7 @@ class LPPAPI SegmentInfoCollection : public LuceneObject { void add(const SegmentInfoPtr& info); void add(int32_t pos, const SegmentInfoPtr& info); void addAll(const SegmentInfoCollectionPtr& segmentInfos); - bool equals(const SegmentInfoCollectionPtr& other); + bool equals(const LuceneObjectPtr& other); int32_t find(const SegmentInfoPtr& info); bool contains(const SegmentInfoPtr& info); void remove(int32_t pos); diff --git a/src/core/index/SegmentInfoCollection.cpp b/src/core/index/SegmentInfoCollection.cpp index 7e5fa7ce..21273594 100644 --- a/src/core/index/SegmentInfoCollection.cpp +++ b/src/core/index/SegmentInfoCollection.cpp @@ -41,11 +41,17 @@ void SegmentInfoCollection::addAll(const SegmentInfoCollectionPtr& segmentInfos) this->segmentInfos.addAll(segmentInfos->segmentInfos.begin(), segmentInfos->segmentInfos.end()); } -bool SegmentInfoCollection::equals(const SegmentInfoCollectionPtr& other) { +bool SegmentInfoCollection::equals(const LuceneObjectPtr& other) { if (LuceneObject::equals(other)) { return true; } - return segmentInfos.equals(other->segmentInfos, luceneEquals()); + + SegmentInfoCollectionPtr otherColl(boost::dynamic_pointer_cast(other)); + if (!otherColl) { + return false; + } + + return segmentInfos.equals(otherColl->segmentInfos, luceneEquals()); } int32_t SegmentInfoCollection::find(const SegmentInfoPtr& info) { From 994f03cf736229044a168835ae7387696041658f Mon Sep 17 00:00:00 2001 From: rezso Date: Mon, 19 May 2014 09:20:40 +0100 Subject: [PATCH 063/157] fix installing lucene++ headers in 3.0.6 --- CMakeLists.txt | 8 ++++++++ src/core/CMakeLists.txt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0f3f208..6ae96b77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,14 @@ if(NOT WIN32) DESTINATION "${LIB_DESTINATION}/pkgconfig") endif() +################################# +# install Config.h +################################# +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/include/Config.h" + DESTINATION include/lucene++) + #################################### # custom targets #################################### diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 83eb5789..7d6153d1 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -20,7 +20,7 @@ file(GLOB_RECURSE lucene_internal_headers ) file(GLOB_RECURSE lucene_headers - include/*.h + "${lucene++_SOURCE_DIR}/include/*.h" ) add_definitions(-DLPP_BUILDING_LIB) From c5ed014df578f2be4c48ac8e6f09d6450d1a2a03 Mon Sep 17 00:00:00 2001 From: rezso Date: Mon, 19 May 2014 09:23:35 +0100 Subject: [PATCH 064/157] lucene++ .pc files fix --- liblucene++-contrib.pc.cmake | 7 +++---- liblucene++.pc.cmake | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/liblucene++-contrib.pc.cmake b/liblucene++-contrib.pc.cmake index 3ebf9f98..98b63818 100644 --- a/liblucene++-contrib.pc.cmake +++ b/liblucene++-contrib.pc.cmake @@ -1,14 +1,13 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix}/bin -libdir=@LIB_DESTINATION@ +libdir=${prefix}/@LIB_DESTINATION@ includedir=${prefix}/include/lucene++ lib=lucene++-contrib Name: liblucene++-contrib Description: Contributions for Lucene++ - a C++ search engine, ported from the popular Apache Lucene Version: @lucene++_VERSION@ -Libs: -L@LIB_DESTINATION@/ -l${lib} +Libs: -L${prefix}/@LIB_DESTINATION@ -l${lib} Cflags: -I${includedir} -Requires: liblucene++=@lucene++_VERSION@ -~ +Requires: liblucene++ = @lucene++_VERSION@ diff --git a/liblucene++.pc.cmake b/liblucene++.pc.cmake index d238e51a..c526d4ab 100644 --- a/liblucene++.pc.cmake +++ b/liblucene++.pc.cmake @@ -1,13 +1,12 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix}/bin -libdir=@LIB_DESTINATION@ +libdir=${prefix}/@LIB_DESTINATION@ includedir=${prefix}/include/lucene++ lib=lucene++ Name: liblucene++ Description: Lucene++ - a C++ search engine, ported from the popular Apache Lucene Version: @lucene++_VERSION@ -Libs: -L@LIB_DESTINATION@ -l${lib} +Libs: -L${prefix}/@LIB_DESTINATION@ -l${lib} Cflags: -I${includedir} -~ From 0803bded9b087695e5897531bab23964e9fedbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Fri, 23 May 2014 13:26:17 +0200 Subject: [PATCH 065/157] Fix NumericTokenStream::setDoubleValue() to use correct encoding. The code used a simple cast to int64_t, which truncated the value and made searching with decimal precision impossible. Moreover, the encoding was different from what NumericRangeQuery expected and search results were wrong in other situations as well. Fix by using NumericUtils::doubleToSortableLong(), as both NumericRangeQuery and the original Java code do. --- src/core/analysis/NumericTokenStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/analysis/NumericTokenStream.cpp b/src/core/analysis/NumericTokenStream.cpp index 06aacf01..407f4761 100644 --- a/src/core/analysis/NumericTokenStream.cpp +++ b/src/core/analysis/NumericTokenStream.cpp @@ -87,7 +87,7 @@ NumericTokenStreamPtr NumericTokenStream::setIntValue(int32_t value) { } NumericTokenStreamPtr NumericTokenStream::setDoubleValue(double value) { - this->value = (int64_t)value; + this->value = NumericUtils::doubleToSortableLong(value); valSize = 64; shift = 0; return shared_from_this(); From fcdcf1945f0325c8dfdcdfa03ae8af5247602e6e Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Wed, 2 Jul 2014 17:20:57 +0200 Subject: [PATCH 066/157] enable multiarch lib location Cherry picked from ubuntu lucene++ package --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ae96b77..4b744273 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,9 +75,10 @@ set(lucene_boost_libs include(Lucene++Docs) include(TestCXXAcceptsFlag) +include(GNUInstallDirs) set(LIB_DESTINATION - "lib" CACHE STRING "Define lib output directory name" + "${CMAKE_INSTALL_FULL_LIBDIR}" CACHE STRING "Define lib output directory name" ) if(ENABLE_CYCLIC_CHECK) From 474d308600aecabfa88c27e691fa13e815e4649f Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Wed, 2 Jul 2014 17:23:27 +0200 Subject: [PATCH 067/157] Update LuceneTestFixture.cpp --- src/test/util/LuceneTestFixture.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/util/LuceneTestFixture.cpp b/src/test/util/LuceneTestFixture.cpp index e737bdb1..71e16cfa 100644 --- a/src/test/util/LuceneTestFixture.cpp +++ b/src/test/util/LuceneTestFixture.cpp @@ -17,6 +17,10 @@ LuceneTestFixture::LuceneTestFixture() { } LuceneTestFixture::~LuceneTestFixture() { + // Moved out to a separate function since GTEST_FAIL cannot be used in destructors + destructorBody(); +} +void LuceneTestFixture::destructorBody() { DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); if (ConcurrentMergeScheduler::anyUnhandledExceptions()) { // Clear the failure so that we don't just keep failing subsequent test cases From e349e74f59d4358dad899cdbc355edd6734b51f1 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Wed, 2 Jul 2014 17:25:37 +0200 Subject: [PATCH 068/157] Update LuceneTestFixture.h --- src/test/include/LuceneTestFixture.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/include/LuceneTestFixture.h b/src/test/include/LuceneTestFixture.h index fd7371a4..56136582 100644 --- a/src/test/include/LuceneTestFixture.h +++ b/src/test/include/LuceneTestFixture.h @@ -13,6 +13,7 @@ class LuceneTestFixture : public testing::Test { /// setup LuceneTestFixture(); + void destructorBody(); /// teardown virtual ~LuceneTestFixture(); }; From ab10671fb28b6b8ebf6813f9f6e609bacff6a5c3 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Thu, 3 Jul 2014 10:45:28 +0200 Subject: [PATCH 069/157] Moved Subversion requirement outside CMakeLists --- CMakeExternal.txt | 1 + CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeExternal.txt b/CMakeExternal.txt index 6ad53dc3..c7c1c1b1 100644 --- a/CMakeExternal.txt +++ b/CMakeExternal.txt @@ -1,5 +1,6 @@ # Enable ExternalProject CMake module include(ExternalProject) +find_package(Subversion REQUIRED) # main directory for external projects set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ThirdParty) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b744273..8a7e7255 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,6 @@ option(ENABLE_CYCLIC_CHECK # bootstrap #################################### -find_package(Subversion REQUIRED) find_package(Threads REQUIRED) find_package(Boost COMPONENTS date_time From 83356d9681fb52a4c190d2cf033279006c1bf57d Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 10 Jul 2014 10:45:45 +0100 Subject: [PATCH 070/157] Embed gtest in source tree instead of fetching from subversion. --- CMakeExternal.txt | 29 - CMakeLists.txt | 1 - src/test/CMakeLists.txt | 4 +- src/test/gtest/CHANGES | 157 + src/test/gtest/CMakeLists.txt | 260 + src/test/gtest/CONTRIBUTORS | 37 + src/test/gtest/LICENSE | 28 + src/test/gtest/Makefile.am | 306 + src/test/gtest/README | 435 + src/test/gtest/build-aux/.keep | 0 src/test/gtest/cmake/internal_utils.cmake | 242 + src/test/gtest/codegear/gtest.cbproj | 138 + src/test/gtest/codegear/gtest.groupproj | 54 + src/test/gtest/codegear/gtest_all.cc | 38 + src/test/gtest/codegear/gtest_link.cc | 40 + src/test/gtest/codegear/gtest_main.cbproj | 82 + src/test/gtest/codegear/gtest_unittest.cbproj | 88 + src/test/gtest/configure.ac | 68 + .../gtest/include/gtest/gtest-death-test.h | 294 + src/test/gtest/include/gtest/gtest-message.h | 250 + .../gtest/include/gtest/gtest-param-test.h | 1421 ++++ .../include/gtest/gtest-param-test.h.pump | 487 ++ src/test/gtest/include/gtest/gtest-printers.h | 891 ++ src/test/gtest/include/gtest/gtest-spi.h | 232 + .../gtest/include/gtest/gtest-test-part.h | 179 + .../gtest/include/gtest/gtest-typed-test.h | 259 + src/test/gtest/include/gtest/gtest.h | 2307 +++++ .../gtest/include/gtest/gtest_pred_impl.h | 358 + src/test/gtest/include/gtest/gtest_prod.h | 58 + .../internal/gtest-death-test-internal.h | 319 + .../include/gtest/internal/gtest-filepath.h | 206 + .../include/gtest/internal/gtest-internal.h | 1161 +++ .../include/gtest/internal/gtest-linked_ptr.h | 233 + .../internal/gtest-param-util-generated.h | 5143 ++++++++++++ .../gtest-param-util-generated.h.pump | 301 + .../include/gtest/internal/gtest-param-util.h | 619 ++ .../gtest/include/gtest/internal/gtest-port.h | 2432 ++++++ .../include/gtest/internal/gtest-string.h | 167 + .../include/gtest/internal/gtest-tuple.h | 1020 +++ .../include/gtest/internal/gtest-tuple.h.pump | 347 + .../include/gtest/internal/gtest-type-util.h | 3331 ++++++++ .../gtest/internal/gtest-type-util.h.pump | 297 + src/test/gtest/m4/acx_pthread.m4 | 363 + src/test/gtest/m4/gtest.m4 | 74 + src/test/gtest/msvc/gtest-md.sln | 45 + src/test/gtest/msvc/gtest-md.vcproj | 126 + src/test/gtest/msvc/gtest.sln | 45 + src/test/gtest/msvc/gtest.vcproj | 126 + src/test/gtest/msvc/gtest_main-md.vcproj | 129 + src/test/gtest/msvc/gtest_main.vcproj | 129 + src/test/gtest/msvc/gtest_prod_test-md.vcproj | 164 + src/test/gtest/msvc/gtest_prod_test.vcproj | 164 + src/test/gtest/msvc/gtest_unittest-md.vcproj | 147 + src/test/gtest/msvc/gtest_unittest.vcproj | 147 + src/test/gtest/samples/prime_tables.h | 123 + src/test/gtest/samples/sample1.cc | 68 + src/test/gtest/samples/sample1.h | 43 + src/test/gtest/samples/sample10_unittest.cc | 144 + src/test/gtest/samples/sample1_unittest.cc | 153 + src/test/gtest/samples/sample2.cc | 56 + src/test/gtest/samples/sample2.h | 85 + src/test/gtest/samples/sample2_unittest.cc | 109 + src/test/gtest/samples/sample3-inl.h | 172 + src/test/gtest/samples/sample3_unittest.cc | 151 + src/test/gtest/samples/sample4.cc | 46 + src/test/gtest/samples/sample4.h | 53 + src/test/gtest/samples/sample4_unittest.cc | 45 + src/test/gtest/samples/sample5_unittest.cc | 199 + src/test/gtest/samples/sample6_unittest.cc | 224 + src/test/gtest/samples/sample7_unittest.cc | 130 + src/test/gtest/samples/sample8_unittest.cc | 173 + src/test/gtest/samples/sample9_unittest.cc | 160 + src/test/gtest/scripts/common.py | 83 + src/test/gtest/scripts/fuse_gtest_files.py | 250 + src/test/gtest/scripts/gen_gtest_pred_impl.py | 730 ++ src/test/gtest/scripts/gtest-config.in | 274 + src/test/gtest/scripts/pump.py | 855 ++ src/test/gtest/scripts/release_docs.py | 158 + src/test/gtest/scripts/upload.py | 1387 +++ src/test/gtest/scripts/upload_gtest.py | 78 + src/test/gtest/src/gtest-all.cc | 48 + src/test/gtest/src/gtest-death-test.cc | 1346 +++ src/test/gtest/src/gtest-filepath.cc | 380 + src/test/gtest/src/gtest-internal-inl.h | 1192 +++ src/test/gtest/src/gtest-port.cc | 1184 +++ src/test/gtest/src/gtest-printers.cc | 373 + src/test/gtest/src/gtest-test-part.cc | 110 + src/test/gtest/src/gtest-typed-test.cc | 110 + src/test/gtest/src/gtest.cc | 5006 +++++++++++ src/test/gtest/src/gtest_main.cc | 38 + .../gtest/test/gtest-death-test_ex_test.cc | 93 + src/test/gtest/test/gtest-death-test_test.cc | 1423 ++++ src/test/gtest/test/gtest-filepath_test.cc | 680 ++ src/test/gtest/test/gtest-linked_ptr_test.cc | 154 + src/test/gtest/test/gtest-listener_test.cc | 310 + src/test/gtest/test/gtest-message_test.cc | 159 + src/test/gtest/test/gtest-options_test.cc | 215 + src/test/gtest/test/gtest-param-test2_test.cc | 65 + src/test/gtest/test/gtest-param-test_test.cc | 904 ++ src/test/gtest/test/gtest-param-test_test.h | 57 + src/test/gtest/test/gtest-port_test.cc | 1323 +++ src/test/gtest/test/gtest-printers_test.cc | 1651 ++++ src/test/gtest/test/gtest-test-part_test.cc | 208 + src/test/gtest/test/gtest-tuple_test.cc | 320 + src/test/gtest/test/gtest-typed-test2_test.cc | 45 + src/test/gtest/test/gtest-typed-test_test.cc | 361 + src/test/gtest/test/gtest-typed-test_test.h | 66 + .../gtest/test/gtest-unittest-api_test.cc | 341 + src/test/gtest/test/gtest_all_test.cc | 47 + .../test/gtest_break_on_failure_unittest.py | 212 + .../test/gtest_break_on_failure_unittest_.cc | 88 + .../gtest/test/gtest_catch_exceptions_test.py | 237 + .../test/gtest_catch_exceptions_test_.cc | 311 + src/test/gtest/test/gtest_color_test.py | 130 + src/test/gtest/test/gtest_color_test_.cc | 71 + src/test/gtest/test/gtest_env_var_test.py | 103 + src/test/gtest/test/gtest_env_var_test_.cc | 126 + src/test/gtest/test/gtest_environment_test.cc | 192 + src/test/gtest/test/gtest_filter_unittest.py | 633 ++ src/test/gtest/test/gtest_filter_unittest_.cc | 140 + src/test/gtest/test/gtest_help_test.py | 172 + src/test/gtest/test/gtest_help_test_.cc | 46 + .../gtest/test/gtest_list_tests_unittest.py | 207 + .../gtest/test/gtest_list_tests_unittest_.cc | 157 + src/test/gtest/test/gtest_main_unittest.cc | 45 + src/test/gtest/test/gtest_no_test_unittest.cc | 56 + src/test/gtest/test/gtest_output_test.py | 335 + src/test/gtest/test/gtest_output_test_.cc | 1034 +++ .../test/gtest_output_test_golden_lin.txt | 720 ++ .../gtest/test/gtest_pred_impl_unittest.cc | 2427 ++++++ .../gtest/test/gtest_premature_exit_test.cc | 143 + src/test/gtest/test/gtest_prod_test.cc | 57 + src/test/gtest/test/gtest_repeat_test.cc | 253 + src/test/gtest/test/gtest_shuffle_test.py | 325 + src/test/gtest/test/gtest_shuffle_test_.cc | 103 + src/test/gtest/test/gtest_sole_header_test.cc | 57 + src/test/gtest/test/gtest_stress_test.cc | 256 + src/test/gtest/test/gtest_test_utils.py | 320 + .../test/gtest_throw_on_failure_ex_test.cc | 92 + .../gtest/test/gtest_throw_on_failure_test.py | 171 + .../test/gtest_throw_on_failure_test_.cc | 72 + .../gtest/test/gtest_uninitialized_test.py | 70 + .../gtest/test/gtest_uninitialized_test_.cc | 43 + src/test/gtest/test/gtest_unittest.cc | 7431 +++++++++++++++++ .../gtest/test/gtest_xml_outfile1_test_.cc | 49 + .../gtest/test/gtest_xml_outfile2_test_.cc | 49 + .../gtest/test/gtest_xml_outfiles_test.py | 132 + .../gtest/test/gtest_xml_output_unittest.py | 307 + .../gtest/test/gtest_xml_output_unittest_.cc | 181 + src/test/gtest/test/gtest_xml_test_utils.py | 194 + src/test/gtest/test/production.cc | 36 + src/test/gtest/test/production.h | 55 + .../gtest/xcode/Config/DebugProject.xcconfig | 30 + .../xcode/Config/FrameworkTarget.xcconfig | 17 + src/test/gtest/xcode/Config/General.xcconfig | 41 + .../xcode/Config/ReleaseProject.xcconfig | 32 + .../xcode/Config/StaticLibraryTarget.xcconfig | 18 + .../gtest/xcode/Config/TestTarget.xcconfig | 8 + src/test/gtest/xcode/Resources/Info.plist | 30 + .../xcode/Samples/FrameworkSample/Info.plist | 28 + .../WidgetFramework.xcodeproj/project.pbxproj | 457 + .../xcode/Samples/FrameworkSample/runtests.sh | 62 + .../xcode/Samples/FrameworkSample/widget.cc | 63 + .../xcode/Samples/FrameworkSample/widget.h | 59 + .../Samples/FrameworkSample/widget_test.cc | 68 + src/test/gtest/xcode/Scripts/runtests.sh | 65 + .../gtest/xcode/Scripts/versiongenerate.py | 100 + .../xcode/gtest.xcodeproj/project.pbxproj | 1135 +++ 168 files changed, 70156 insertions(+), 31 deletions(-) delete mode 100644 CMakeExternal.txt create mode 100644 src/test/gtest/CHANGES create mode 100644 src/test/gtest/CMakeLists.txt create mode 100644 src/test/gtest/CONTRIBUTORS create mode 100644 src/test/gtest/LICENSE create mode 100644 src/test/gtest/Makefile.am create mode 100644 src/test/gtest/README create mode 100644 src/test/gtest/build-aux/.keep create mode 100644 src/test/gtest/cmake/internal_utils.cmake create mode 100644 src/test/gtest/codegear/gtest.cbproj create mode 100644 src/test/gtest/codegear/gtest.groupproj create mode 100644 src/test/gtest/codegear/gtest_all.cc create mode 100644 src/test/gtest/codegear/gtest_link.cc create mode 100644 src/test/gtest/codegear/gtest_main.cbproj create mode 100644 src/test/gtest/codegear/gtest_unittest.cbproj create mode 100644 src/test/gtest/configure.ac create mode 100644 src/test/gtest/include/gtest/gtest-death-test.h create mode 100644 src/test/gtest/include/gtest/gtest-message.h create mode 100644 src/test/gtest/include/gtest/gtest-param-test.h create mode 100644 src/test/gtest/include/gtest/gtest-param-test.h.pump create mode 100644 src/test/gtest/include/gtest/gtest-printers.h create mode 100644 src/test/gtest/include/gtest/gtest-spi.h create mode 100644 src/test/gtest/include/gtest/gtest-test-part.h create mode 100644 src/test/gtest/include/gtest/gtest-typed-test.h create mode 100644 src/test/gtest/include/gtest/gtest.h create mode 100644 src/test/gtest/include/gtest/gtest_pred_impl.h create mode 100644 src/test/gtest/include/gtest/gtest_prod.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-death-test-internal.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-filepath.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-internal.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-linked_ptr.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-param-util-generated.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump create mode 100644 src/test/gtest/include/gtest/internal/gtest-param-util.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-port.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-string.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-tuple.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-tuple.h.pump create mode 100644 src/test/gtest/include/gtest/internal/gtest-type-util.h create mode 100644 src/test/gtest/include/gtest/internal/gtest-type-util.h.pump create mode 100644 src/test/gtest/m4/acx_pthread.m4 create mode 100644 src/test/gtest/m4/gtest.m4 create mode 100644 src/test/gtest/msvc/gtest-md.sln create mode 100644 src/test/gtest/msvc/gtest-md.vcproj create mode 100644 src/test/gtest/msvc/gtest.sln create mode 100644 src/test/gtest/msvc/gtest.vcproj create mode 100644 src/test/gtest/msvc/gtest_main-md.vcproj create mode 100644 src/test/gtest/msvc/gtest_main.vcproj create mode 100644 src/test/gtest/msvc/gtest_prod_test-md.vcproj create mode 100644 src/test/gtest/msvc/gtest_prod_test.vcproj create mode 100644 src/test/gtest/msvc/gtest_unittest-md.vcproj create mode 100644 src/test/gtest/msvc/gtest_unittest.vcproj create mode 100644 src/test/gtest/samples/prime_tables.h create mode 100644 src/test/gtest/samples/sample1.cc create mode 100644 src/test/gtest/samples/sample1.h create mode 100644 src/test/gtest/samples/sample10_unittest.cc create mode 100644 src/test/gtest/samples/sample1_unittest.cc create mode 100644 src/test/gtest/samples/sample2.cc create mode 100644 src/test/gtest/samples/sample2.h create mode 100644 src/test/gtest/samples/sample2_unittest.cc create mode 100644 src/test/gtest/samples/sample3-inl.h create mode 100644 src/test/gtest/samples/sample3_unittest.cc create mode 100644 src/test/gtest/samples/sample4.cc create mode 100644 src/test/gtest/samples/sample4.h create mode 100644 src/test/gtest/samples/sample4_unittest.cc create mode 100644 src/test/gtest/samples/sample5_unittest.cc create mode 100644 src/test/gtest/samples/sample6_unittest.cc create mode 100644 src/test/gtest/samples/sample7_unittest.cc create mode 100644 src/test/gtest/samples/sample8_unittest.cc create mode 100644 src/test/gtest/samples/sample9_unittest.cc create mode 100644 src/test/gtest/scripts/common.py create mode 100755 src/test/gtest/scripts/fuse_gtest_files.py create mode 100755 src/test/gtest/scripts/gen_gtest_pred_impl.py create mode 100755 src/test/gtest/scripts/gtest-config.in create mode 100755 src/test/gtest/scripts/pump.py create mode 100755 src/test/gtest/scripts/release_docs.py create mode 100755 src/test/gtest/scripts/upload.py create mode 100755 src/test/gtest/scripts/upload_gtest.py create mode 100644 src/test/gtest/src/gtest-all.cc create mode 100644 src/test/gtest/src/gtest-death-test.cc create mode 100644 src/test/gtest/src/gtest-filepath.cc create mode 100644 src/test/gtest/src/gtest-internal-inl.h create mode 100644 src/test/gtest/src/gtest-port.cc create mode 100644 src/test/gtest/src/gtest-printers.cc create mode 100644 src/test/gtest/src/gtest-test-part.cc create mode 100644 src/test/gtest/src/gtest-typed-test.cc create mode 100644 src/test/gtest/src/gtest.cc create mode 100644 src/test/gtest/src/gtest_main.cc create mode 100644 src/test/gtest/test/gtest-death-test_ex_test.cc create mode 100644 src/test/gtest/test/gtest-death-test_test.cc create mode 100644 src/test/gtest/test/gtest-filepath_test.cc create mode 100644 src/test/gtest/test/gtest-linked_ptr_test.cc create mode 100644 src/test/gtest/test/gtest-listener_test.cc create mode 100644 src/test/gtest/test/gtest-message_test.cc create mode 100644 src/test/gtest/test/gtest-options_test.cc create mode 100644 src/test/gtest/test/gtest-param-test2_test.cc create mode 100644 src/test/gtest/test/gtest-param-test_test.cc create mode 100644 src/test/gtest/test/gtest-param-test_test.h create mode 100644 src/test/gtest/test/gtest-port_test.cc create mode 100644 src/test/gtest/test/gtest-printers_test.cc create mode 100644 src/test/gtest/test/gtest-test-part_test.cc create mode 100644 src/test/gtest/test/gtest-tuple_test.cc create mode 100644 src/test/gtest/test/gtest-typed-test2_test.cc create mode 100644 src/test/gtest/test/gtest-typed-test_test.cc create mode 100644 src/test/gtest/test/gtest-typed-test_test.h create mode 100644 src/test/gtest/test/gtest-unittest-api_test.cc create mode 100644 src/test/gtest/test/gtest_all_test.cc create mode 100755 src/test/gtest/test/gtest_break_on_failure_unittest.py create mode 100644 src/test/gtest/test/gtest_break_on_failure_unittest_.cc create mode 100755 src/test/gtest/test/gtest_catch_exceptions_test.py create mode 100644 src/test/gtest/test/gtest_catch_exceptions_test_.cc create mode 100755 src/test/gtest/test/gtest_color_test.py create mode 100644 src/test/gtest/test/gtest_color_test_.cc create mode 100755 src/test/gtest/test/gtest_env_var_test.py create mode 100644 src/test/gtest/test/gtest_env_var_test_.cc create mode 100644 src/test/gtest/test/gtest_environment_test.cc create mode 100755 src/test/gtest/test/gtest_filter_unittest.py create mode 100644 src/test/gtest/test/gtest_filter_unittest_.cc create mode 100755 src/test/gtest/test/gtest_help_test.py create mode 100644 src/test/gtest/test/gtest_help_test_.cc create mode 100755 src/test/gtest/test/gtest_list_tests_unittest.py create mode 100644 src/test/gtest/test/gtest_list_tests_unittest_.cc create mode 100644 src/test/gtest/test/gtest_main_unittest.cc create mode 100644 src/test/gtest/test/gtest_no_test_unittest.cc create mode 100755 src/test/gtest/test/gtest_output_test.py create mode 100644 src/test/gtest/test/gtest_output_test_.cc create mode 100644 src/test/gtest/test/gtest_output_test_golden_lin.txt create mode 100644 src/test/gtest/test/gtest_pred_impl_unittest.cc create mode 100644 src/test/gtest/test/gtest_premature_exit_test.cc create mode 100644 src/test/gtest/test/gtest_prod_test.cc create mode 100644 src/test/gtest/test/gtest_repeat_test.cc create mode 100755 src/test/gtest/test/gtest_shuffle_test.py create mode 100644 src/test/gtest/test/gtest_shuffle_test_.cc create mode 100644 src/test/gtest/test/gtest_sole_header_test.cc create mode 100644 src/test/gtest/test/gtest_stress_test.cc create mode 100755 src/test/gtest/test/gtest_test_utils.py create mode 100644 src/test/gtest/test/gtest_throw_on_failure_ex_test.cc create mode 100755 src/test/gtest/test/gtest_throw_on_failure_test.py create mode 100644 src/test/gtest/test/gtest_throw_on_failure_test_.cc create mode 100755 src/test/gtest/test/gtest_uninitialized_test.py create mode 100644 src/test/gtest/test/gtest_uninitialized_test_.cc create mode 100644 src/test/gtest/test/gtest_unittest.cc create mode 100644 src/test/gtest/test/gtest_xml_outfile1_test_.cc create mode 100644 src/test/gtest/test/gtest_xml_outfile2_test_.cc create mode 100755 src/test/gtest/test/gtest_xml_outfiles_test.py create mode 100755 src/test/gtest/test/gtest_xml_output_unittest.py create mode 100644 src/test/gtest/test/gtest_xml_output_unittest_.cc create mode 100755 src/test/gtest/test/gtest_xml_test_utils.py create mode 100644 src/test/gtest/test/production.cc create mode 100644 src/test/gtest/test/production.h create mode 100644 src/test/gtest/xcode/Config/DebugProject.xcconfig create mode 100644 src/test/gtest/xcode/Config/FrameworkTarget.xcconfig create mode 100644 src/test/gtest/xcode/Config/General.xcconfig create mode 100644 src/test/gtest/xcode/Config/ReleaseProject.xcconfig create mode 100644 src/test/gtest/xcode/Config/StaticLibraryTarget.xcconfig create mode 100644 src/test/gtest/xcode/Config/TestTarget.xcconfig create mode 100644 src/test/gtest/xcode/Resources/Info.plist create mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/Info.plist create mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj create mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/runtests.sh create mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/widget.cc create mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/widget.h create mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/widget_test.cc create mode 100644 src/test/gtest/xcode/Scripts/runtests.sh create mode 100644 src/test/gtest/xcode/Scripts/versiongenerate.py create mode 100644 src/test/gtest/xcode/gtest.xcodeproj/project.pbxproj diff --git a/CMakeExternal.txt b/CMakeExternal.txt deleted file mode 100644 index c7c1c1b1..00000000 --- a/CMakeExternal.txt +++ /dev/null @@ -1,29 +0,0 @@ -# Enable ExternalProject CMake module -include(ExternalProject) -find_package(Subversion REQUIRED) - -# main directory for external projects -set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ThirdParty) - -# GTest external project -ExternalProject_Add( - googletest - SVN_REPOSITORY http://googletest.googlecode.com/svn/tags/release-1.7.0/ - TIMEOUT 10 - CMAKE_ARGS -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} - -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} - -Dgtest_force_shared_crt=ON - # Disable update - UPDATE_COMMAND "" - # Disable install step - INSTALL_COMMAND "" - # Wrap download, configure and build steps in a script to log output - LOG_DOWNLOAD ON - LOG_CONFIGURE ON - LOG_BUILD ON) - -ExternalProject_Get_Property(googletest source_dir) -set(GTEST_DIR ${source_dir}) -set(GTEST_INCLUDE_DIR ${source_dir}/include) -ExternalProject_Get_Property(googletest binary_dir) -set(GTEST_LIB_DIR ${binary_dir}) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a7e7255..96183e38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,6 @@ include_directories( "${CMAKE_CURRENT_BINARY_DIR}/include" ) -include(CMakeExternal.txt) enable_testing() add_subdirectory(src/core) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 31bb850e..aad8f1c1 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,7 +1,9 @@ project(lucene++-tester) +add_subdirectory(gtest) + include_directories( - "${GTEST_INCLUDE_DIR}" + "${gtest_SOURCE_DIR}/include" "${lucene++_SOURCE_DIR}/include" "${lucene++-lib_SOURCE_DIR}/include" "${lucene++-contrib_SOURCE_DIR}/include" diff --git a/src/test/gtest/CHANGES b/src/test/gtest/CHANGES new file mode 100644 index 00000000..05521324 --- /dev/null +++ b/src/test/gtest/CHANGES @@ -0,0 +1,157 @@ +Changes for 1.7.0: + +* New feature: death tests are supported on OpenBSD and in iOS + simulator now. +* New feature: Google Test now implements a protocol to allow + a test runner to detect that a test program has exited + prematurely and report it as a failure (before it would be + falsely reported as a success if the exit code is 0). +* New feature: Test::RecordProperty() can now be used outside of the + lifespan of a test method, in which case it will be attributed to + the current test case or the test program in the XML report. +* New feature (potentially breaking): --gtest_list_tests now prints + the type parameters and value parameters for each test. +* Improvement: char pointers and char arrays are now escaped properly + in failure messages. +* Improvement: failure summary in XML reports now includes file and + line information. +* Improvement: the XML element now has a timestamp attribute. +* Improvement: When --gtest_filter is specified, XML report now doesn't + contain information about tests that are filtered out. +* Fixed the bug where long --gtest_filter flag values are truncated in + death tests. +* Potentially breaking change: RUN_ALL_TESTS() is now implemented as a + function instead of a macro in order to work better with Clang. +* Compatibility fixes with C++ 11 and various platforms. +* Bug/warning fixes. + +Changes for 1.6.0: + +* New feature: ADD_FAILURE_AT() for reporting a test failure at the + given source location -- useful for writing testing utilities. +* New feature: the universal value printer is moved from Google Mock + to Google Test. +* New feature: type parameters and value parameters are reported in + the XML report now. +* A gtest_disable_pthreads CMake option. +* Colored output works in GNU Screen sessions now. +* Parameters of value-parameterized tests are now printed in the + textual output. +* Failures from ad hoc test assertions run before RUN_ALL_TESTS() are + now correctly reported. +* Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to + ostream. +* More complete handling of exceptions. +* GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter + name is already used by another library. +* --gtest_catch_exceptions is now true by default, allowing a test + program to continue after an exception is thrown. +* Value-parameterized test fixtures can now derive from Test and + WithParamInterface separately, easing conversion of legacy tests. +* Death test messages are clearly marked to make them more + distinguishable from other messages. +* Compatibility fixes for Android, Google Native Client, MinGW, HP UX, + PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear), + IBM XL C++ (Visual Age C++), and C++0x. +* Bug fixes and implementation clean-ups. +* Potentially incompatible changes: disables the harmful 'make install' + command in autotools. + +Changes for 1.5.0: + + * New feature: assertions can be safely called in multiple threads + where the pthreads library is available. + * New feature: predicates used inside EXPECT_TRUE() and friends + can now generate custom failure messages. + * New feature: Google Test can now be compiled as a DLL. + * New feature: fused source files are included. + * New feature: prints help when encountering unrecognized Google Test flags. + * Experimental feature: CMake build script (requires CMake 2.6.4+). + * Experimental feature: the Pump script for meta programming. + * double values streamed to an assertion are printed with enough precision + to differentiate any two different values. + * Google Test now works on Solaris and AIX. + * Build and test script improvements. + * Bug fixes and implementation clean-ups. + + Potentially breaking changes: + + * Stopped supporting VC++ 7.1 with exceptions disabled. + * Dropped support for 'make install'. + +Changes for 1.4.0: + + * New feature: the event listener API + * New feature: test shuffling + * New feature: the XML report format is closer to junitreport and can + be parsed by Hudson now. + * New feature: when a test runs under Visual Studio, its failures are + integrated in the IDE. + * New feature: /MD(d) versions of VC++ projects. + * New feature: elapsed time for the tests is printed by default. + * New feature: comes with a TR1 tuple implementation such that Boost + is no longer needed for Combine(). + * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. + * New feature: the Xcode project can now produce static gtest + libraries in addition to a framework. + * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, + Symbian, gcc, and C++Builder. + * Bug fixes and implementation clean-ups. + +Changes for 1.3.0: + + * New feature: death tests on Windows, Cygwin, and Mac. + * New feature: ability to use Google Test assertions in other testing + frameworks. + * New feature: ability to run disabled test via + --gtest_also_run_disabled_tests. + * New feature: the --help flag for printing the usage. + * New feature: access to Google Test flag values in user code. + * New feature: a script that packs Google Test into one .h and one + .cc file for easy deployment. + * New feature: support for distributing test functions to multiple + machines (requires support from the test runner). + * Bug fixes and implementation clean-ups. + +Changes for 1.2.1: + + * Compatibility fixes for Linux IA-64 and IBM z/OS. + * Added support for using Boost and other TR1 implementations. + * Changes to the build scripts to support upcoming release of Google C++ + Mocking Framework. + * Added Makefile to the distribution package. + * Improved build instructions in README. + +Changes for 1.2.0: + + * New feature: value-parameterized tests. + * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS) + macros. + * Changed the XML report format to match JUnit/Ant's. + * Added tests to the Xcode project. + * Added scons/SConscript for building with SCons. + * Added src/gtest-all.cc for building Google Test from a single file. + * Fixed compatibility with Solaris and z/OS. + * Enabled running Python tests on systems with python 2.3 installed, + e.g. Mac OS X 10.4. + * Bug fixes. + +Changes for 1.1.0: + + * New feature: type-parameterized tests. + * New feature: exception assertions. + * New feature: printing elapsed time of tests. + * Improved the robustness of death tests. + * Added an Xcode project and samples. + * Adjusted the output format on Windows to be understandable by Visual Studio. + * Minor bug fixes. + +Changes for 1.0.1: + + * Added project files for Visual Studio 7.1. + * Fixed issues with compiling on Mac OS X. + * Fixed issues with compiling on Cygwin. + +Changes for 1.0.0: + + * Initial Open Source release of Google Test diff --git a/src/test/gtest/CMakeLists.txt b/src/test/gtest/CMakeLists.txt new file mode 100644 index 00000000..bd78cfe6 --- /dev/null +++ b/src/test/gtest/CMakeLists.txt @@ -0,0 +1,260 @@ +######################################################################## +# CMake build script for Google Test. +# +# To run the tests for Google Test itself on Linux, use 'make test' or +# ctest. You can select which tests to run using 'ctest -R regex'. +# For more options, run 'ctest --help'. + +# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to +# make it prominent in the GUI. +option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) + +# When other libraries are using a shared version of runtime libraries, +# Google Test also has to use one. +option( + gtest_force_shared_crt + "Use shared (DLL) run-time lib even when Google Test is built as static lib." + OFF) + +option(gtest_build_tests "Build all of gtest's own tests." OFF) + +option(gtest_build_samples "Build gtest's sample programs." OFF) + +option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF) + +# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). +include(cmake/hermetic_build.cmake OPTIONAL) + +if (COMMAND pre_project_set_up_hermetic_build) + pre_project_set_up_hermetic_build() +endif() + +######################################################################## +# +# Project-wide settings + +# Name of the project. +# +# CMake files in this project can refer to the root source directory +# as ${gtest_SOURCE_DIR} and to the root binary directory as +# ${gtest_BINARY_DIR}. +# Language "C" is required for find_package(Threads). +project(gtest CXX C) +cmake_minimum_required(VERSION 2.6.2) + +if (COMMAND set_up_hermetic_build) + set_up_hermetic_build() +endif() + +# Define helper functions and macros used by Google Test. +include(cmake/internal_utils.cmake) + +config_compiler_and_linker() # Defined in internal_utils.cmake. + +# Where Google Test's .h files can be found. +include_directories( + ${gtest_SOURCE_DIR}/include + ${gtest_SOURCE_DIR}) + +# Where Google Test's libraries can be found. +link_directories(${gtest_BINARY_DIR}/src) + +# Summary of tuple support for Microsoft Visual Studio: +# Compiler version(MS) version(cmake) Support +# ---------- ----------- -------------- ----------------------------- +# <= VS 2010 <= 10 <= 1600 Use Google Tests's own tuple. +# VS 2012 11 1700 std::tr1::tuple + _VARIADIC_MAX=10 +# VS 2013 12 1800 std::tr1::tuple +if (MSVC AND MSVC_VERSION EQUAL 1700) + add_definitions(/D _VARIADIC_MAX=10) +endif() + +######################################################################## +# +# Defines the gtest & gtest_main libraries. User tests should link +# with one of them. + +# Google Test libraries. We build them using more strict warnings than what +# are used for other targets, to ensure that gtest can be compiled by a user +# aggressive about warnings. +cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) +cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) +target_link_libraries(gtest_main gtest) + +######################################################################## +# +# Samples on how to link user tests with gtest or gtest_main. +# +# They are not built by default. To build them, set the +# gtest_build_samples option to ON. You can do it by running ccmake +# or specifying the -Dgtest_build_samples=ON flag when running cmake. + +if (gtest_build_samples) + cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc) + cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc) + cxx_executable(sample3_unittest samples gtest_main) + cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc) + cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc) + cxx_executable(sample6_unittest samples gtest_main) + cxx_executable(sample7_unittest samples gtest_main) + cxx_executable(sample8_unittest samples gtest_main) + cxx_executable(sample9_unittest samples gtest) + cxx_executable(sample10_unittest samples gtest) +endif() + +######################################################################## +# +# Google Test's own tests. +# +# You can skip this section if you aren't interested in testing +# Google Test itself. +# +# The tests are not built by default. To build them, set the +# gtest_build_tests option to ON. You can do it by running ccmake +# or specifying the -Dgtest_build_tests=ON flag when running cmake. + +if (gtest_build_tests) + # This must be set in the root directory for the tests to be run by + # 'make test' or ctest. + enable_testing() + + ############################################################ + # C++ tests built with standard compiler flags. + + cxx_test(gtest-death-test_test gtest_main) + cxx_test(gtest_environment_test gtest) + cxx_test(gtest-filepath_test gtest_main) + cxx_test(gtest-linked_ptr_test gtest_main) + cxx_test(gtest-listener_test gtest_main) + cxx_test(gtest_main_unittest gtest_main) + cxx_test(gtest-message_test gtest_main) + cxx_test(gtest_no_test_unittest gtest) + cxx_test(gtest-options_test gtest_main) + cxx_test(gtest-param-test_test gtest + test/gtest-param-test2_test.cc) + cxx_test(gtest-port_test gtest_main) + cxx_test(gtest_pred_impl_unittest gtest_main) + cxx_test(gtest_premature_exit_test gtest + test/gtest_premature_exit_test.cc) + cxx_test(gtest-printers_test gtest_main) + cxx_test(gtest_prod_test gtest_main + test/production.cc) + cxx_test(gtest_repeat_test gtest) + cxx_test(gtest_sole_header_test gtest_main) + cxx_test(gtest_stress_test gtest) + cxx_test(gtest-test-part_test gtest_main) + cxx_test(gtest_throw_on_failure_ex_test gtest) + cxx_test(gtest-typed-test_test gtest_main + test/gtest-typed-test2_test.cc) + cxx_test(gtest_unittest gtest_main) + cxx_test(gtest-unittest-api_test gtest) + + ############################################################ + # C++ tests built with non-standard compiler flags. + + # MSVC 7.1 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) + cxx_library(gtest_no_exception "${cxx_no_exception}" + src/gtest-all.cc) + cxx_library(gtest_main_no_exception "${cxx_no_exception}" + src/gtest-all.cc src/gtest_main.cc) + endif() + cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_test_with_flags(gtest-death-test_ex_nocatch_test + "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0" + gtest test/gtest-death-test_ex_test.cc) + cxx_test_with_flags(gtest-death-test_ex_catch_test + "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1" + gtest test/gtest-death-test_ex_test.cc) + + cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" + gtest_main_no_rtti test/gtest_unittest.cc) + + cxx_shared_library(gtest_dll "${cxx_default}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_executable_with_flags(gtest_dll_test_ "${cxx_default}" + gtest_dll test/gtest_all_test.cc) + set_target_properties(gtest_dll_test_ + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + + if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010. + # Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that + # conflict with our own definitions. Therefore using our own tuple does not + # work on those compilers. + cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}" + src/gtest-all.cc src/gtest_main.cc) + + cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}" + gtest_main_use_own_tuple test/gtest-tuple_test.cc) + + cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}" + gtest_main_use_own_tuple + test/gtest-param-test_test.cc test/gtest-param-test2_test.cc) + endif() + + ############################################################ + # Python tests. + + cxx_executable(gtest_break_on_failure_unittest_ test gtest) + py_test(gtest_break_on_failure_unittest) + + # Visual Studio .NET 2003 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003 + cxx_executable_with_flags( + gtest_catch_exceptions_no_ex_test_ + "${cxx_no_exception}" + gtest_main_no_exception + test/gtest_catch_exceptions_test_.cc) + endif() + + cxx_executable_with_flags( + gtest_catch_exceptions_ex_test_ + "${cxx_exception}" + gtest_main + test/gtest_catch_exceptions_test_.cc) + py_test(gtest_catch_exceptions_test) + + cxx_executable(gtest_color_test_ test gtest) + py_test(gtest_color_test) + + cxx_executable(gtest_env_var_test_ test gtest) + py_test(gtest_env_var_test) + + cxx_executable(gtest_filter_unittest_ test gtest) + py_test(gtest_filter_unittest) + + cxx_executable(gtest_help_test_ test gtest_main) + py_test(gtest_help_test) + + cxx_executable(gtest_list_tests_unittest_ test gtest) + py_test(gtest_list_tests_unittest) + + cxx_executable(gtest_output_test_ test gtest) + py_test(gtest_output_test) + + cxx_executable(gtest_shuffle_test_ test gtest) + py_test(gtest_shuffle_test) + + # MSVC 7.1 does not support STL with exceptions disabled. + if (NOT MSVC OR MSVC_VERSION GREATER 1310) + cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception) + set_target_properties(gtest_throw_on_failure_test_ + PROPERTIES + COMPILE_FLAGS "${cxx_no_exception}") + py_test(gtest_throw_on_failure_test) + endif() + + cxx_executable(gtest_uninitialized_test_ test gtest) + py_test(gtest_uninitialized_test) + + cxx_executable(gtest_xml_outfile1_test_ test gtest_main) + cxx_executable(gtest_xml_outfile2_test_ test gtest_main) + py_test(gtest_xml_outfiles_test) + + cxx_executable(gtest_xml_output_unittest_ test gtest) + py_test(gtest_xml_output_unittest) +endif() diff --git a/src/test/gtest/CONTRIBUTORS b/src/test/gtest/CONTRIBUTORS new file mode 100644 index 00000000..feae2fc0 --- /dev/null +++ b/src/test/gtest/CONTRIBUTORS @@ -0,0 +1,37 @@ +# This file contains a list of people who've made non-trivial +# contribution to the Google C++ Testing Framework project. People +# who commit code to the project are encouraged to add their names +# here. Please keep the list sorted by first names. + +Ajay Joshi +Balázs Dán +Bharat Mediratta +Chandler Carruth +Chris Prince +Chris Taylor +Dan Egnor +Eric Roman +Hady Zalek +Jeffrey Yasskin +Jói Sigurðsson +Keir Mierle +Keith Ray +Kenton Varda +Manuel Klimek +Markus Heule +Mika Raento +Miklós Fazekas +Pasi Valminen +Patrick Hanna +Patrick Riley +Peter Kaminski +Preston Jackson +Rainer Klaffenboeck +Russ Cox +Russ Rufer +Sean Mcafee +Sigurður Ãsgeirsson +Tracy Bialik +Vadim Berman +Vlad Losev +Zhanyong Wan diff --git a/src/test/gtest/LICENSE b/src/test/gtest/LICENSE new file mode 100644 index 00000000..1941a11f --- /dev/null +++ b/src/test/gtest/LICENSE @@ -0,0 +1,28 @@ +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 COPYRIGHT +OWNER OR CONTRIBUTORS 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. diff --git a/src/test/gtest/Makefile.am b/src/test/gtest/Makefile.am new file mode 100644 index 00000000..9c96b425 --- /dev/null +++ b/src/test/gtest/Makefile.am @@ -0,0 +1,306 @@ +# Automake file + +ACLOCAL_AMFLAGS = -I m4 + +# Nonstandard package files for distribution +EXTRA_DIST = \ + CHANGES \ + CONTRIBUTORS \ + LICENSE \ + include/gtest/gtest-param-test.h.pump \ + include/gtest/internal/gtest-param-util-generated.h.pump \ + include/gtest/internal/gtest-tuple.h.pump \ + include/gtest/internal/gtest-type-util.h.pump \ + make/Makefile \ + scripts/fuse_gtest_files.py \ + scripts/gen_gtest_pred_impl.py \ + scripts/pump.py \ + scripts/test/Makefile + +# gtest source files that we don't compile directly. They are +# #included by gtest-all.cc. +GTEST_SRC = \ + src/gtest-death-test.cc \ + src/gtest-filepath.cc \ + src/gtest-internal-inl.h \ + src/gtest-port.cc \ + src/gtest-printers.cc \ + src/gtest-test-part.cc \ + src/gtest-typed-test.cc \ + src/gtest.cc + +EXTRA_DIST += $(GTEST_SRC) + +# Sample files that we don't compile. +EXTRA_DIST += \ + samples/prime_tables.h \ + samples/sample2_unittest.cc \ + samples/sample3_unittest.cc \ + samples/sample4_unittest.cc \ + samples/sample5_unittest.cc \ + samples/sample6_unittest.cc \ + samples/sample7_unittest.cc \ + samples/sample8_unittest.cc \ + samples/sample9_unittest.cc + +# C++ test files that we don't compile directly. +EXTRA_DIST += \ + test/gtest-death-test_ex_test.cc \ + test/gtest-death-test_test.cc \ + test/gtest-filepath_test.cc \ + test/gtest-linked_ptr_test.cc \ + test/gtest-listener_test.cc \ + test/gtest-message_test.cc \ + test/gtest-options_test.cc \ + test/gtest-param-test2_test.cc \ + test/gtest-param-test2_test.cc \ + test/gtest-param-test_test.cc \ + test/gtest-param-test_test.cc \ + test/gtest-param-test_test.h \ + test/gtest-port_test.cc \ + test/gtest_premature_exit_test.cc \ + test/gtest-printers_test.cc \ + test/gtest-test-part_test.cc \ + test/gtest-tuple_test.cc \ + test/gtest-typed-test2_test.cc \ + test/gtest-typed-test_test.cc \ + test/gtest-typed-test_test.h \ + test/gtest-unittest-api_test.cc \ + test/gtest_break_on_failure_unittest_.cc \ + test/gtest_catch_exceptions_test_.cc \ + test/gtest_color_test_.cc \ + test/gtest_env_var_test_.cc \ + test/gtest_environment_test.cc \ + test/gtest_filter_unittest_.cc \ + test/gtest_help_test_.cc \ + test/gtest_list_tests_unittest_.cc \ + test/gtest_main_unittest.cc \ + test/gtest_no_test_unittest.cc \ + test/gtest_output_test_.cc \ + test/gtest_pred_impl_unittest.cc \ + test/gtest_prod_test.cc \ + test/gtest_repeat_test.cc \ + test/gtest_shuffle_test_.cc \ + test/gtest_sole_header_test.cc \ + test/gtest_stress_test.cc \ + test/gtest_throw_on_failure_ex_test.cc \ + test/gtest_throw_on_failure_test_.cc \ + test/gtest_uninitialized_test_.cc \ + test/gtest_unittest.cc \ + test/gtest_unittest.cc \ + test/gtest_xml_outfile1_test_.cc \ + test/gtest_xml_outfile2_test_.cc \ + test/gtest_xml_output_unittest_.cc \ + test/production.cc \ + test/production.h + +# Python tests that we don't run. +EXTRA_DIST += \ + test/gtest_break_on_failure_unittest.py \ + test/gtest_catch_exceptions_test.py \ + test/gtest_color_test.py \ + test/gtest_env_var_test.py \ + test/gtest_filter_unittest.py \ + test/gtest_help_test.py \ + test/gtest_list_tests_unittest.py \ + test/gtest_output_test.py \ + test/gtest_output_test_golden_lin.txt \ + test/gtest_shuffle_test.py \ + test/gtest_test_utils.py \ + test/gtest_throw_on_failure_test.py \ + test/gtest_uninitialized_test.py \ + test/gtest_xml_outfiles_test.py \ + test/gtest_xml_output_unittest.py \ + test/gtest_xml_test_utils.py + +# CMake script +EXTRA_DIST += \ + CMakeLists.txt \ + cmake/internal_utils.cmake + +# MSVC project files +EXTRA_DIST += \ + msvc/gtest-md.sln \ + msvc/gtest-md.vcproj \ + msvc/gtest.sln \ + msvc/gtest.vcproj \ + msvc/gtest_main-md.vcproj \ + msvc/gtest_main.vcproj \ + msvc/gtest_prod_test-md.vcproj \ + msvc/gtest_prod_test.vcproj \ + msvc/gtest_unittest-md.vcproj \ + msvc/gtest_unittest.vcproj + +# xcode project files +EXTRA_DIST += \ + xcode/Config/DebugProject.xcconfig \ + xcode/Config/FrameworkTarget.xcconfig \ + xcode/Config/General.xcconfig \ + xcode/Config/ReleaseProject.xcconfig \ + xcode/Config/StaticLibraryTarget.xcconfig \ + xcode/Config/TestTarget.xcconfig \ + xcode/Resources/Info.plist \ + xcode/Scripts/runtests.sh \ + xcode/Scripts/versiongenerate.py \ + xcode/gtest.xcodeproj/project.pbxproj + +# xcode sample files +EXTRA_DIST += \ + xcode/Samples/FrameworkSample/Info.plist \ + xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \ + xcode/Samples/FrameworkSample/runtests.sh \ + xcode/Samples/FrameworkSample/widget.cc \ + xcode/Samples/FrameworkSample/widget.h \ + xcode/Samples/FrameworkSample/widget_test.cc + +# C++Builder project files +EXTRA_DIST += \ + codegear/gtest.cbproj \ + codegear/gtest.groupproj \ + codegear/gtest_all.cc \ + codegear/gtest_link.cc \ + codegear/gtest_main.cbproj \ + codegear/gtest_unittest.cbproj + +# Distribute and install M4 macro +m4datadir = $(datadir)/aclocal +m4data_DATA = m4/gtest.m4 +EXTRA_DIST += $(m4data_DATA) + +# We define the global AM_CPPFLAGS as everything we compile includes from these +# directories. +AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include + +# Modifies compiler and linker flags for pthreads compatibility. +if HAVE_PTHREADS + AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 + AM_LIBS = @PTHREAD_LIBS@ +else + AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0 +endif + +# Build rules for libraries. +lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la + +lib_libgtest_la_SOURCES = src/gtest-all.cc + +pkginclude_HEADERS = \ + include/gtest/gtest-death-test.h \ + include/gtest/gtest-message.h \ + include/gtest/gtest-param-test.h \ + include/gtest/gtest-printers.h \ + include/gtest/gtest-spi.h \ + include/gtest/gtest-test-part.h \ + include/gtest/gtest-typed-test.h \ + include/gtest/gtest.h \ + include/gtest/gtest_pred_impl.h \ + include/gtest/gtest_prod.h + +pkginclude_internaldir = $(pkgincludedir)/internal +pkginclude_internal_HEADERS = \ + include/gtest/internal/gtest-death-test-internal.h \ + include/gtest/internal/gtest-filepath.h \ + include/gtest/internal/gtest-internal.h \ + include/gtest/internal/gtest-linked_ptr.h \ + include/gtest/internal/gtest-param-util-generated.h \ + include/gtest/internal/gtest-param-util.h \ + include/gtest/internal/gtest-port.h \ + include/gtest/internal/gtest-string.h \ + include/gtest/internal/gtest-tuple.h \ + include/gtest/internal/gtest-type-util.h + +lib_libgtest_main_la_SOURCES = src/gtest_main.cc +lib_libgtest_main_la_LIBADD = lib/libgtest.la + +# Bulid rules for samples and tests. Automake's naming for some of +# these variables isn't terribly obvious, so this is a brief +# reference: +# +# TESTS -- Programs run automatically by "make check" +# check_PROGRAMS -- Programs built by "make check" but not necessarily run + +noinst_LTLIBRARIES = samples/libsamples.la + +samples_libsamples_la_SOURCES = \ + samples/sample1.cc \ + samples/sample1.h \ + samples/sample2.cc \ + samples/sample2.h \ + samples/sample3-inl.h \ + samples/sample4.cc \ + samples/sample4.h + +TESTS= +TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \ + GTEST_BUILD_DIR="$(top_builddir)/test" +check_PROGRAMS= + +# A simple sample on using gtest. +TESTS += samples/sample1_unittest +check_PROGRAMS += samples/sample1_unittest +samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc +samples_sample1_unittest_LDADD = lib/libgtest_main.la \ + lib/libgtest.la \ + samples/libsamples.la + +# Another sample. It also verifies that libgtest works. +TESTS += samples/sample10_unittest +check_PROGRAMS += samples/sample10_unittest +samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc +samples_sample10_unittest_LDADD = lib/libgtest.la + +# This tests most constructs of gtest and verifies that libgtest_main +# and libgtest work. +TESTS += test/gtest_all_test +check_PROGRAMS += test/gtest_all_test +test_gtest_all_test_SOURCES = test/gtest_all_test.cc +test_gtest_all_test_LDADD = lib/libgtest_main.la \ + lib/libgtest.la + +# Tests that fused gtest files compile and work. +FUSED_GTEST_SRC = \ + fused-src/gtest/gtest-all.cc \ + fused-src/gtest/gtest.h \ + fused-src/gtest/gtest_main.cc + +if HAVE_PYTHON +TESTS += test/fused_gtest_test +check_PROGRAMS += test/fused_gtest_test +test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ + samples/sample1.cc samples/sample1_unittest.cc +test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src" + +# Build rules for putting fused Google Test files into the distribution +# package. The user can also create those files by manually running +# scripts/fuse_gtest_files.py. +$(test_fused_gtest_test_SOURCES): fused-gtest + +fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ + $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \ + scripts/fuse_gtest_files.py + mkdir -p "$(srcdir)/fused-src" + chmod -R u+w "$(srcdir)/fused-src" + rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc" + rm -f "$(srcdir)/fused-src/gtest/gtest.h" + "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src" + cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/" + +maintainer-clean-local: + rm -rf "$(srcdir)/fused-src" +endif + +# Death tests may produce core dumps in the build directory. In case +# this happens, clean them to keep distcleancheck happy. +CLEANFILES = core + +# Disables 'make install' as installing a compiled version of Google +# Test can lead to undefined behavior due to violation of the +# One-Definition Rule. + +install-exec-local: + echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." + false + +install-data-local: + echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." + false diff --git a/src/test/gtest/README b/src/test/gtest/README new file mode 100644 index 00000000..404bf3b8 --- /dev/null +++ b/src/test/gtest/README @@ -0,0 +1,435 @@ +Google C++ Testing Framework +============================ + +http://code.google.com/p/googletest/ + +Overview +-------- + +Google's framework for writing C++ tests on a variety of platforms +(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the +xUnit architecture. Supports automatic test discovery, a rich set of +assertions, user-defined assertions, death tests, fatal and non-fatal +failures, various options for running the tests, and XML test report +generation. + +Please see the project page above for more information as well as the +mailing list for questions, discussions, and development. There is +also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please +join us! + +Requirements for End Users +-------------------------- + +Google Test is designed to have fairly minimal requirements to build +and use with your projects, but there are some. Currently, we support +Linux, Windows, Mac OS X, and Cygwin. We will also make our best +effort to support other platforms (e.g. Solaris, AIX, and z/OS). +However, since core members of the Google Test project have no access +to these platforms, Google Test may have outstanding issues there. If +you notice any problems on your platform, please notify +googletestframework@googlegroups.com. Patches for fixing them are +even more welcome! + +### Linux Requirements ### + +These are the base requirements to build and use Google Test from a source +package (as described below): + * GNU-compatible Make or gmake + * POSIX-standard shell + * POSIX(-2) Regular Expressions (regex.h) + * A C++98-standard-compliant compiler + +### Windows Requirements ### + + * Microsoft Visual C++ 7.1 or newer + +### Cygwin Requirements ### + + * Cygwin 1.5.25-14 or newer + +### Mac OS X Requirements ### + + * Mac OS X 10.4 Tiger or newer + * Developer Tools Installed + +Also, you'll need CMake 2.6.4 or higher if you want to build the +samples using the provided CMake script, regardless of the platform. + +Requirements for Contributors +----------------------------- + +We welcome patches. If you plan to contribute a patch, you need to +build Google Test and its own tests from an SVN checkout (described +below), which has further requirements: + + * Python version 2.3 or newer (for running some of the tests and + re-generating certain source files from templates) + * CMake 2.6.4 or newer + +Getting the Source +------------------ + +There are two primary ways of getting Google Test's source code: you +can download a stable source release in your preferred archive format, +or directly check out the source from our Subversion (SVN) repository. +The SVN checkout requires a few extra steps and some extra software +packages on your system, but lets you track the latest development and +make patches much more easily, so we highly encourage it. + +### Source Package ### + +Google Test is released in versioned source packages which can be +downloaded from the download page [1]. Several different archive +formats are provided, but the only difference is the tools used to +manipulate them, and the size of the resulting file. Download +whichever you are most comfortable with. + + [1] http://code.google.com/p/googletest/downloads/list + +Once the package is downloaded, expand it using whichever tools you +prefer for that type. This will result in a new directory with the +name "gtest-X.Y.Z" which contains all of the source code. Here are +some examples on Linux: + + tar -xvzf gtest-X.Y.Z.tar.gz + tar -xvjf gtest-X.Y.Z.tar.bz2 + unzip gtest-X.Y.Z.zip + +### SVN Checkout ### + +To check out the main branch (also known as the "trunk") of Google +Test, run the following Subversion command: + + svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn + +Setting up the Build +-------------------- + +To build Google Test and your tests that use it, you need to tell your +build system where to find its headers and source files. The exact +way to do it depends on which build system you use, and is usually +straightforward. + +### Generic Build Instructions ### + +Suppose you put Google Test in directory ${GTEST_DIR}. To build it, +create a library build target (or a project as called by Visual Studio +and Xcode) to compile + + ${GTEST_DIR}/src/gtest-all.cc + +with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR} +in the normal header search path. Assuming a Linux-like system and gcc, +something like the following will do: + + g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ + -pthread -c ${GTEST_DIR}/src/gtest-all.cc + ar -rv libgtest.a gtest-all.o + +(We need -pthread as Google Test uses threads.) + +Next, you should compile your test source file with +${GTEST_DIR}/include in the system header search path, and link it +with gtest and any other necessary libraries: + + g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \ + -o your_test + +As an example, the make/ directory contains a Makefile that you can +use to build Google Test on systems where GNU make is available +(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google +Test's own tests. Instead, it just builds the Google Test library and +a sample test. You can use it as a starting point for your own build +script. + +If the default settings are correct for your environment, the +following commands should succeed: + + cd ${GTEST_DIR}/make + make + ./sample1_unittest + +If you see errors, try to tweak the contents of make/Makefile to make +them go away. There are instructions in make/Makefile on how to do +it. + +### Using CMake ### + +Google Test comes with a CMake build script (CMakeLists.txt) that can +be used on a wide range of platforms ("C" stands for cross-platform.). +If you don't have CMake installed already, you can download it for +free from http://www.cmake.org/. + +CMake works by generating native makefiles or build projects that can +be used in the compiler environment of your choice. The typical +workflow starts with: + + mkdir mybuild # Create a directory to hold the build output. + cd mybuild + cmake ${GTEST_DIR} # Generate native build scripts. + +If you want to build Google Test's samples, you should replace the +last command with + + cmake -Dgtest_build_samples=ON ${GTEST_DIR} + +If you are on a *nix system, you should now see a Makefile in the +current directory. Just type 'make' to build gtest. + +If you use Windows and have Visual Studio installed, a gtest.sln file +and several .vcproj files will be created. You can then build them +using Visual Studio. + +On Mac OS X with Xcode installed, a .xcodeproj file will be generated. + +### Legacy Build Scripts ### + +Before settling on CMake, we have been providing hand-maintained build +projects/scripts for Visual Studio, Xcode, and Autotools. While we +continue to provide them for convenience, they are not actively +maintained any more. We highly recommend that you follow the +instructions in the previous two sections to integrate Google Test +with your existing build system. + +If you still need to use the legacy build scripts, here's how: + +The msvc\ folder contains two solutions with Visual C++ projects. +Open the gtest.sln or gtest-md.sln file using Visual Studio, and you +are ready to build Google Test the same way you build any Visual +Studio project. Files that have names ending with -md use DLL +versions of Microsoft runtime libraries (the /MD or the /MDd compiler +option). Files without that suffix use static versions of the runtime +libraries (the /MT or the /MTd option). Please note that one must use +the same option to compile both gtest and the test code. If you use +Visual Studio 2005 or above, we recommend the -md version as /MD is +the default for new projects in these versions of Visual Studio. + +On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using +Xcode. Build the "gtest" target. The universal binary framework will +end up in your selected build directory (selected in the Xcode +"Preferences..." -> "Building" pane and defaults to xcode/build). +Alternatively, at the command line, enter: + + xcodebuild + +This will build the "Release" configuration of gtest.framework in your +default build location. See the "xcodebuild" man page for more +information about building different configurations and building in +different locations. + +If you wish to use the Google Test Xcode project with Xcode 4.x and +above, you need to either: + * update the SDK configuration options in xcode/Config/General.xconfig. + Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If + you choose this route you lose the ability to target earlier versions + of MacOS X. + * Install an SDK for an earlier version. This doesn't appear to be + supported by Apple, but has been reported to work + (http://stackoverflow.com/questions/5378518). + +Tweaking Google Test +-------------------- + +Google Test can be used in diverse environments. The default +configuration may not work (or may not work well) out of the box in +some environments. However, you can easily tweak Google Test by +defining control macros on the compiler command line. Generally, +these macros are named like GTEST_XYZ and you define them to either 1 +or 0 to enable or disable a certain feature. + +We list the most frequently used macros below. For a complete list, +see file include/gtest/internal/gtest-port.h. + +### Choosing a TR1 Tuple Library ### + +Some Google Test features require the C++ Technical Report 1 (TR1) +tuple library, which is not yet available with all compilers. The +good news is that Google Test implements a subset of TR1 tuple that's +enough for its own need, and will automatically use this when the +compiler doesn't provide TR1 tuple. + +Usually you don't need to care about which tuple library Google Test +uses. However, if your project already uses TR1 tuple, you need to +tell Google Test to use the same TR1 tuple library the rest of your +project uses, or the two tuple implementations will clash. To do +that, add + + -DGTEST_USE_OWN_TR1_TUPLE=0 + +to the compiler flags while compiling Google Test and your tests. If +you want to force Google Test to use its own tuple library, just add + + -DGTEST_USE_OWN_TR1_TUPLE=1 + +to the compiler flags instead. + +If you don't want Google Test to use tuple at all, add + + -DGTEST_HAS_TR1_TUPLE=0 + +and all features using tuple will be disabled. + +### Multi-threaded Tests ### + +Google Test is thread-safe where the pthread library is available. +After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE +macro to see whether this is the case (yes if the macro is #defined to +1, no if it's undefined.). + +If Google Test doesn't correctly detect whether pthread is available +in your environment, you can force it with + + -DGTEST_HAS_PTHREAD=1 + +or + + -DGTEST_HAS_PTHREAD=0 + +When Google Test uses pthread, you may need to add flags to your +compiler and/or linker to select the pthread library, or you'll get +link errors. If you use the CMake script or the deprecated Autotools +script, this is taken care of for you. If you use your own build +script, you'll need to read your compiler and linker's manual to +figure out what flags to add. + +### As a Shared Library (DLL) ### + +Google Test is compact, so most users can build and link it as a +static library for the simplicity. You can choose to use Google Test +as a shared library (known as a DLL on Windows) if you prefer. + +To compile *gtest* as a shared library, add + + -DGTEST_CREATE_SHARED_LIBRARY=1 + +to the compiler flags. You'll also need to tell the linker to produce +a shared library instead - consult your linker's manual for how to do +it. + +To compile your *tests* that use the gtest shared library, add + + -DGTEST_LINKED_AS_SHARED_LIBRARY=1 + +to the compiler flags. + +Note: while the above steps aren't technically necessary today when +using some compilers (e.g. GCC), they may become necessary in the +future, if we decide to improve the speed of loading the library (see +http://gcc.gnu.org/wiki/Visibility for details). Therefore you are +recommended to always add the above flags when using Google Test as a +shared library. Otherwise a future release of Google Test may break +your build script. + +### Avoiding Macro Name Clashes ### + +In C++, macros don't obey namespaces. Therefore two libraries that +both define a macro of the same name will clash if you #include both +definitions. In case a Google Test macro clashes with another +library, you can force Google Test to rename its macro to avoid the +conflict. + +Specifically, if both Google Test and some other code define macro +FOO, you can add + + -DGTEST_DONT_DEFINE_FOO=1 + +to the compiler flags to tell Google Test to change the macro's name +from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST. +For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write + + GTEST_TEST(SomeTest, DoesThis) { ... } + +instead of + + TEST(SomeTest, DoesThis) { ... } + +in order to define a test. + +Upgrating from an Earlier Version +--------------------------------- + +We strive to keep Google Test releases backward compatible. +Sometimes, though, we have to make some breaking changes for the +users' long-term benefits. This section describes what you'll need to +do if you are upgrading from an earlier version of Google Test. + +### Upgrading from 1.3.0 or Earlier ### + +You may need to explicitly enable or disable Google Test's own TR1 +tuple library. See the instructions in section "Choosing a TR1 Tuple +Library". + +### Upgrading from 1.4.0 or Earlier ### + +The Autotools build script (configure + make) is no longer officially +supportted. You are encouraged to migrate to your own build system or +use CMake. If you still need to use Autotools, you can find +instructions in the README file from Google Test 1.4.0. + +On platforms where the pthread library is available, Google Test uses +it in order to be thread-safe. See the "Multi-threaded Tests" section +for what this means to your build script. + +If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google +Test will no longer compile. This should affect very few people, as a +large portion of STL (including ) doesn't compile in this mode +anyway. We decided to stop supporting it in order to greatly simplify +Google Test's implementation. + +Developing Google Test +---------------------- + +This section discusses how to make your own changes to Google Test. + +### Testing Google Test Itself ### + +To make sure your changes work as intended and don't break existing +functionality, you'll want to compile and run Google Test's own tests. +For that you can use CMake: + + mkdir mybuild + cd mybuild + cmake -Dgtest_build_tests=ON ${GTEST_DIR} + +Make sure you have Python installed, as some of Google Test's tests +are written in Python. If the cmake command complains about not being +able to find Python ("Could NOT find PythonInterp (missing: +PYTHON_EXECUTABLE)"), try telling it explicitly where your Python +executable can be found: + + cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR} + +Next, you can build Google Test and all of its own tests. On *nix, +this is usually done by 'make'. To run the tests, do + + make test + +All tests should pass. + +### Regenerating Source Files ### + +Some of Google Test's source files are generated from templates (not +in the C++ sense) using a script. A template file is named FOO.pump, +where FOO is the name of the file it will generate. For example, the +file include/gtest/internal/gtest-type-util.h.pump is used to generate +gtest-type-util.h in the same directory. + +Normally you don't need to worry about regenerating the source files, +unless you need to modify them. In that case, you should modify the +corresponding .pump files instead and run the pump.py Python script to +regenerate them. You can find pump.py in the scripts/ directory. +Read the Pump manual [2] for how to use it. + + [2] http://code.google.com/p/googletest/wiki/PumpManual + +### Contributing a Patch ### + +We welcome patches. Please read the Google Test developer's guide [3] +for how you can contribute. In particular, make sure you have signed +the Contributor License Agreement, or we won't be able to accept the +patch. + + [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide + +Happy testing! diff --git a/src/test/gtest/build-aux/.keep b/src/test/gtest/build-aux/.keep new file mode 100644 index 00000000..e69de29b diff --git a/src/test/gtest/cmake/internal_utils.cmake b/src/test/gtest/cmake/internal_utils.cmake new file mode 100644 index 00000000..93e6dbb7 --- /dev/null +++ b/src/test/gtest/cmake/internal_utils.cmake @@ -0,0 +1,242 @@ +# Defines functions and macros useful for building Google Test and +# Google Mock. +# +# Note: +# +# - This file will be run twice when building Google Mock (once via +# Google Test's CMakeLists.txt, and once via Google Mock's). +# Therefore it shouldn't have any side effects other than defining +# the functions and macros. +# +# - The functions/macros defined in this file may depend on Google +# Test and Google Mock's option() definitions, and thus must be +# called *after* the options have been defined. + +# Tweaks CMake's default compiler/linker settings to suit Google Test's needs. +# +# This must be a macro(), as inside a function string() can only +# update variables in the function scope. +macro(fix_default_compiler_settings_) + if (MSVC) + # For MSVC, CMake sets certain flags to defaults we want to override. + # This replacement code is taken from sample in the CMake Wiki at + # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace. + foreach (flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt) + # When Google Test is built as a shared library, it should also use + # shared runtime libraries. Otherwise, it may end up with multiple + # copies of runtime library data in different modules, resulting in + # hard-to-find crashes. When it is built as a static library, it is + # preferable to use CRT as static libraries, as we don't have to rely + # on CRT DLLs being available. CMake always defaults to using shared + # CRT libraries, so we override that default here. + string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}") + endif() + + # We prefer more strict warning checking for building Google Test. + # Replaces /W3 with /W4 in defaults. + string(REPLACE "/W3" "/W4" ${flag_var} "${${flag_var}}") + endforeach() + endif() +endmacro() + +# Defines the compiler/linker flags used to build Google Test and +# Google Mock. You can tweak these definitions to suit your need. A +# variable's value is empty before it's explicitly assigned to. +macro(config_compiler_and_linker) + if (NOT gtest_disable_pthreads) + # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT. + find_package(Threads) + endif() + + fix_default_compiler_settings_() + if (MSVC) + # Newlines inside flags variables break CMake's NMake generator. + # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. + set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J -Zi") + if (MSVC_VERSION LESS 1400) # 1400 is Visual Studio 2005 + # Suppress spurious warnings MSVC 7.1 sometimes issues. + # Forcing value to bool. + set(cxx_base_flags "${cxx_base_flags} -wd4800") + # Copy constructor and assignment operator could not be generated. + set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512") + # Compatibility warnings not applicable to Google Test. + # Resolved overload was found by argument-dependent lookup. + set(cxx_base_flags "${cxx_base_flags} -wd4675") + endif() + if (MSVC_VERSION LESS 1500) # 1500 is Visual Studio 2008 + # Conditional expression is constant. + # When compiling with /W4, we get several instances of C4127 + # (Conditional expression is constant). In our code, we disable that + # warning on a case-by-case basis. However, on Visual Studio 2005, + # the warning fires on std::list. Therefore on that compiler and earlier, + # we disable the warning project-wide. + set(cxx_base_flags "${cxx_base_flags} -wd4127") + endif() + if (NOT (MSVC_VERSION LESS 1700)) # 1700 is Visual Studio 2012. + # Suppress "unreachable code" warning on VS 2012 and later. + # http://stackoverflow.com/questions/3232669 explains the issue. + set(cxx_base_flags "${cxx_base_flags} -wd4702") + endif() + + set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") + set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") + set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") + set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0") + set(cxx_no_rtti_flags "-GR-") + elseif (CMAKE_COMPILER_IS_GNUCXX) + set(cxx_base_flags "-Wall -Wshadow") + set(cxx_exception_flags "-fexceptions") + set(cxx_no_exception_flags "-fno-exceptions") + # Until version 4.3.2, GCC doesn't define a macro to indicate + # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI + # explicitly. + set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0") + set(cxx_strict_flags + "-Wextra -Wno-unused-parameter -Wno-missing-field-initializers") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + set(cxx_exception_flags "-features=except") + # Sun Pro doesn't provide macros to indicate whether exceptions and + # RTTI are enabled, so we define GTEST_HAS_* explicitly. + set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0") + set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR + CMAKE_CXX_COMPILER_ID STREQUAL "XL") + # CMake 2.8 changes Visual Age's compiler ID to "XL". + set(cxx_exception_flags "-qeh") + set(cxx_no_exception_flags "-qnoeh") + # Until version 9.0, Visual Age doesn't define a macro to indicate + # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI + # explicitly. + set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP") + set(cxx_base_flags "-AA -mt") + set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1") + set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0") + # RTTI can not be disabled in HP aCC compiler. + set(cxx_no_rtti_flags "") + endif() + + if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed. + set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1") + else() + set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0") + endif() + + # For building gtest's own tests and samples. + set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}") + set(cxx_no_exception + "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}") + set(cxx_default "${cxx_exception}") + set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}") + set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1") + + # For building the gtest libraries. + set(cxx_strict "${cxx_default} ${cxx_strict_flags}") +endmacro() + +# Defines the gtest & gtest_main libraries. User tests should link +# with one of them. +function(cxx_library_with_type name type cxx_flags) + # type can be either STATIC or SHARED to denote a static or shared library. + # ARGN refers to additional arguments after 'cxx_flags'. + add_library(${name} ${type} ${ARGN}) + set_target_properties(${name} + PROPERTIES + COMPILE_FLAGS "${cxx_flags}") + if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED") + set_target_properties(${name} + PROPERTIES + COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1") + endif() + if (CMAKE_USE_PTHREADS_INIT) + target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT}) + endif() +endfunction() + +######################################################################## +# +# Helper functions for creating build targets. + +function(cxx_shared_library name cxx_flags) + cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN}) +endfunction() + +function(cxx_library name cxx_flags) + cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN}) +endfunction() + +# cxx_executable_with_flags(name cxx_flags libs srcs...) +# +# creates a named C++ executable that depends on the given libraries and +# is built from the given source files with the given compiler flags. +function(cxx_executable_with_flags name cxx_flags libs) + add_executable(${name} ${ARGN}) + if (cxx_flags) + set_target_properties(${name} + PROPERTIES + COMPILE_FLAGS "${cxx_flags}") + endif() + if (BUILD_SHARED_LIBS) + set_target_properties(${name} + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + endif() + # To support mixing linking in static and dynamic libraries, link each + # library in with an extra call to target_link_libraries. + foreach (lib "${libs}") + target_link_libraries(${name} ${lib}) + endforeach() +endfunction() + +# cxx_executable(name dir lib srcs...) +# +# creates a named target that depends on the given libs and is built +# from the given source files. dir/name.cc is implicitly included in +# the source file list. +function(cxx_executable name dir libs) + cxx_executable_with_flags( + ${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN}) +endfunction() + +# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE. +find_package(PythonInterp) + +# cxx_test_with_flags(name cxx_flags libs srcs...) +# +# creates a named C++ test that depends on the given libs and is built +# from the given source files with the given compiler flags. +function(cxx_test_with_flags name cxx_flags libs) + cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN}) + add_test(${name} ${name}) +endfunction() + +# cxx_test(name libs srcs...) +# +# creates a named test target that depends on the given libs and is +# built from the given source files. Unlike cxx_test_with_flags, +# test/name.cc is already implicitly included in the source file list. +function(cxx_test name libs) + cxx_test_with_flags("${name}" "${cxx_default}" "${libs}" + "test/${name}.cc" ${ARGN}) +endfunction() + +# py_test(name) +# +# creates a Python test with the given name whose main module is in +# test/name.py. It does nothing if Python is not installed. +function(py_test name) + # We are not supporting Python tests on Linux yet as they consider + # all Linux environments to be google3 and try to use google3 features. + if (PYTHONINTERP_FOUND) + # ${CMAKE_BINARY_DIR} is known at configuration time, so we can + # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known + # only at ctest runtime (by calling ctest -c ), so + # we have to escape $ to delay variable substitution here. + add_test(${name} + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py + --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE}) + endif() +endfunction() diff --git a/src/test/gtest/codegear/gtest.cbproj b/src/test/gtest/codegear/gtest.cbproj new file mode 100644 index 00000000..95c3054b --- /dev/null +++ b/src/test/gtest/codegear/gtest.cbproj @@ -0,0 +1,138 @@ + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 0 + + + 1 + + + 2 + + + 9 + + + 10 + + + 11 + + + 12 + + + 14 + + + 13 + + + 15 + + + 16 + + + 17 + + + 18 + + + Cfg_1 + + + Cfg_2 + + + \ No newline at end of file diff --git a/src/test/gtest/codegear/gtest.groupproj b/src/test/gtest/codegear/gtest.groupproj new file mode 100644 index 00000000..faf31cab --- /dev/null +++ b/src/test/gtest/codegear/gtest.groupproj @@ -0,0 +1,54 @@ + + + {c1d923e0-6cba-4332-9b6f-3420acbf5091} + + + + + + + + + Default.Personality + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/gtest/codegear/gtest_all.cc b/src/test/gtest/codegear/gtest_all.cc new file mode 100644 index 00000000..121b2d80 --- /dev/null +++ b/src/test/gtest/codegear/gtest_all.cc @@ -0,0 +1,38 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// C++Builder's IDE cannot build a static library from files with hyphens +// in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 . +// This file serves as a workaround. + +#include "src/gtest-all.cc" diff --git a/src/test/gtest/codegear/gtest_link.cc b/src/test/gtest/codegear/gtest_link.cc new file mode 100644 index 00000000..918eccd1 --- /dev/null +++ b/src/test/gtest/codegear/gtest_link.cc @@ -0,0 +1,40 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// Links gtest.lib and gtest_main.lib into the current project in C++Builder. +// This means that these libraries can't be renamed, but it's the only way to +// ensure that Debug versus Release test builds are linked against the +// appropriate Debug or Release build of the libraries. + +#pragma link "gtest.lib" +#pragma link "gtest_main.lib" diff --git a/src/test/gtest/codegear/gtest_main.cbproj b/src/test/gtest/codegear/gtest_main.cbproj new file mode 100644 index 00000000..d76ce139 --- /dev/null +++ b/src/test/gtest/codegear/gtest_main.cbproj @@ -0,0 +1,82 @@ + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 0 + + + Cfg_1 + + + Cfg_2 + + + diff --git a/src/test/gtest/codegear/gtest_unittest.cbproj b/src/test/gtest/codegear/gtest_unittest.cbproj new file mode 100644 index 00000000..dc5db8e4 --- /dev/null +++ b/src/test/gtest/codegear/gtest_unittest.cbproj @@ -0,0 +1,88 @@ + + + + {eea63393-5ac5-4b9c-8909-d75fef2daa41} + Release + + + true + + + true + true + Base + + + true + true + Base + + + exe + true + NO_STRICT + JPHNE + true + ..\test + true + CppConsoleApplication + true + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;.. + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test + true + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppConsoleApplication + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test2NO_STRICTSTRICT + + + + + 0 + + + 1 + + + Cfg_1 + + + Cfg_2 + + + \ No newline at end of file diff --git a/src/test/gtest/configure.ac b/src/test/gtest/configure.ac new file mode 100644 index 00000000..cc592e15 --- /dev/null +++ b/src/test/gtest/configure.ac @@ -0,0 +1,68 @@ +m4_include(m4/acx_pthread.m4) + +# At this point, the Xcode project assumes the version string will be three +# integers separated by periods and surrounded by square brackets (e.g. +# "[1.0.1]"). It also asumes that there won't be any closing parenthesis +# between "AC_INIT(" and the closing ")" including comments and strings. +AC_INIT([Google C++ Testing Framework], + [1.7.0], + [googletestframework@googlegroups.com], + [gtest]) + +# Provide various options to initialize the Autoconf and configure processes. +AC_PREREQ([2.59]) +AC_CONFIG_SRCDIR([./LICENSE]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_HEADERS([build-aux/config.h]) +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([scripts/gtest-config], [chmod +x scripts/gtest-config]) + +# Initialize Automake with various options. We require at least v1.9, prevent +# pedantic complaints about package files, and enable various distribution +# targets. +AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects]) + +# Check for programs used in building Google Test. +AC_PROG_CC +AC_PROG_CXX +AC_LANG([C++]) +AC_PROG_LIBTOOL + +# TODO(chandlerc@google.com): Currently we aren't running the Python tests +# against the interpreter detected by AM_PATH_PYTHON, and so we condition +# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's +# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" +# hashbang. +PYTHON= # We *do not* allow the user to specify a python interpreter +AC_PATH_PROG([PYTHON],[python],[:]) +AS_IF([test "$PYTHON" != ":"], + [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) +AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) + +# Configure pthreads. +AC_ARG_WITH([pthreads], + [AS_HELP_STRING([--with-pthreads], + [use pthreads (default is yes)])], + [with_pthreads=$withval], + [with_pthreads=check]) + +have_pthreads=no +AS_IF([test "x$with_pthreads" != "xno"], + [ACX_PTHREAD( + [], + [AS_IF([test "x$with_pthreads" != "xcheck"], + [AC_MSG_FAILURE( + [--with-pthreads was specified, but unable to be used])])]) + have_pthreads="$acx_pthread_ok"]) +AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" = "xyes"]) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_LIBS) + +# TODO(chandlerc@google.com) Check for the necessary system headers. + +# TODO(chandlerc@google.com) Check the types, structures, and other compiler +# and architecture characteristics. + +# Output the generated files. No further autoconf macros may be used. +AC_OUTPUT diff --git a/src/test/gtest/include/gtest/gtest-death-test.h b/src/test/gtest/include/gtest/gtest-death-test.h new file mode 100644 index 00000000..957a69c6 --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-death-test.h @@ -0,0 +1,294 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +#include "gtest/internal/gtest-death-test-internal.h" + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +GTEST_API_ bool InDeathTestChild(); + +} // namespace internal + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i; +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +# define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +# define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +# define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +# define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +# if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +# endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +# ifdef NDEBUG + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# else + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/src/test/gtest/include/gtest/gtest-message.h b/src/test/gtest/include/gtest/gtest-message.h new file mode 100644 index 00000000..fe879bca --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-message.h @@ -0,0 +1,250 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include + +#include "gtest/internal/gtest-port.h" + +// Ensures that there is at least one operator<< in the global namespace. +// See Message& operator<<(...) below for why. +void operator<<(const testing::internal::Secret&, int); + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a stringstream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that stringstream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + Message(); + + // Copy constructor. + Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new ::std::stringstream) { + *ss_ << str; + } + +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template + inline Message& operator <<(const T& val) { + // Some libraries overload << for STL containers. These + // overloads are defined in the global namespace instead of ::std. + // + // C++'s symbol lookup rule (i.e. Koenig lookup) says that these + // overloads are visible in either the std namespace or the global + // namespace, but not other namespaces, including the testing + // namespace which Google Test's Message class is in. + // + // To allow STL containers (and other types that has a << operator + // defined in the global namespace) to be used in Google Test + // assertions, testing::Message must access the custom << operator + // from the global namespace. With this using declaration, + // overloads of << defined in the global namespace and those + // visible via Koenig lookup are both exposed in this function. + using ::operator <<; + *ss_ << val; + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + *ss_ << pointer; + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str); + Message& operator <<(wchar_t* wide_c_str); + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as an std::string. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + std::string GetString() const; + + private: + +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template + inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + *ss_ << pointer; + } + } + template + inline void StreamHelper(internal::false_type /*is_pointer*/, + const T& value) { + // See the comments in Message& operator <<(const T&) above for why + // we need this using statement. + using ::operator <<; + *ss_ << value; + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + const internal::scoped_ptr< ::std::stringstream> ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +namespace internal { + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +template +std::string StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ diff --git a/src/test/gtest/include/gtest/gtest-param-test.h b/src/test/gtest/include/gtest/gtest-param-test.h new file mode 100644 index 00000000..d6702c8f --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-param-test.h @@ -0,0 +1,1421 @@ +// This file was GENERATED by command: +// pump.py gtest-param-test.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + +#include "gtest/internal/gtest-port.h" + +#if !GTEST_OS_SYMBIAN +# include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-param-util-generated.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits + ::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template +internal::ValueArray1 Values(T1 v1) { + return internal::ValueArray1(v1); +} + +template +internal::ValueArray2 Values(T1 v1, T2 v2) { + return internal::ValueArray2(v1, v2); +} + +template +internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3(v1, v2, v3); +} + +template +internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4(v1, v2, v3, v4); +} + +template +internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5(v1, v2, v3, v4, v5); +} + +template +internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6(v1, v2, v3, v4, v5, v6); +} + +template +internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7(v1, v2, v3, v4, v5, + v6, v7); +} + +template +internal::ValueArray8 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template +internal::ValueArray9 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template +internal::ValueArray10 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template +internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template +internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template +internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template +internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template +internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template +internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template +internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template +internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template +internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template +internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template +internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template +internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template +internal::ValueArray23 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template +internal::ValueArray24 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template +internal::ValueArray25 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template +internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template +internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template +internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template +internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template +internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template +internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template +internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template +internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template +internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template +internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template +internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template +internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template +internal::ValueArray38 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template +internal::ValueArray39 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template +internal::ValueArray40 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template +internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template +internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template +internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template +internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template +internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template +internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template +internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template +internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template +internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template +internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template +internal::CartesianProductHolder2 Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2( + g1, g2); +} + +template +internal::CartesianProductHolder3 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3( + g1, g2, g3); +} + +template +internal::CartesianProductHolder4 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4( + g1, g2, g3, g4); +} + +template +internal::CartesianProductHolder5 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5( + g1, g2, g3, g4, g5); +} + +template +internal::CartesianProductHolder6 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6( + g1, g2, g3, g4, g5, g6); +} + +template +internal::CartesianProductHolder7 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7( + g1, g2, g3, g4, g5, g6, g7); +} + +template +internal::CartesianProductHolder8 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template +internal::CartesianProductHolder9 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template +internal::CartesianProductHolder10 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/src/test/gtest/include/gtest/gtest-param-test.h.pump b/src/test/gtest/include/gtest/gtest-param-test.h.pump new file mode 100644 index 00000000..2dc9303b --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-param-test.h.pump @@ -0,0 +1,487 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of Values arguments we want to support. +$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + +#include "gtest/internal/gtest-port.h" + +#if !GTEST_OS_SYMBIAN +# include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-param-util-generated.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits + ::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to $n parameters. +// +$range i 1..n +$for i [[ +$range j 1..i + +template <$for j, [[typename T$j]]> +internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) { + return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]); +} + +]] + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to $maxtuple arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +$range i 2..maxtuple +$for i [[ +$range j 1..i + +template <$for j, [[typename Generator$j]]> +internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( + $for j, [[const Generator$j& g$j]]) { + return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>( + $for j, [[g$j]]); +} + +]] +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/src/test/gtest/include/gtest/gtest-printers.h b/src/test/gtest/include/gtest/gtest-printers.h new file mode 100644 index 00000000..18ee7bc6 --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-printers.h @@ -0,0 +1,891 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// A user can teach this function how to print a class type T by +// defining either operator<<() or PrintTo() in the namespace that +// defines T. More specifically, the FIRST defined function in the +// following list will be used (assuming T is defined in namespace +// foo): +// +// 1. foo::PrintTo(const T&, ostream*) +// 2. operator<<(ostream&, const T&) defined in either foo or the +// global namespace. +// +// If none of the above is defined, it will print the debug string of +// the value if it is a protocol buffer, or print the raw bytes in the +// value otherwise. +// +// To aid debugging: when T is a reference type, the address of the +// value is also printed; when T is a (const) char pointer, both the +// pointer value and the NUL-terminated string it points to are +// printed. +// +// We also provide some convenient wrappers: +// +// // Prints a value to a string. For a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// std::string ::testing::PrintToString(const T& value); +// +// // Prints a value tersely: for a reference type, the referenced +// // value (but not the address) is printed; for a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); +// +// // Prints value using the type inferred by the compiler. The difference +// // from UniversalTersePrint() is that this function prints both the +// // pointer and the NUL-terminated string for a (const or not) char pointer. +// void ::testing::internal::UniversalPrint(const T& value, ostream*); +// +// // Prints the fields of a tuple tersely to a string vector, one +// // element for each field. Tuple support must be enabled in +// // gtest-port.h. +// std::vector UniversalTersePrintTupleFieldsToStrings( +// const Tuple& value); +// +// Known limitation: +// +// The print primitives print the elements of an STL-style container +// using the compiler-inferred type of *iter where iter is a +// const_iterator of the container. When const_iterator is an input +// iterator but not a forward iterator, this inferred type may not +// match value_type, and the print output may be incorrect. In +// practice, this is rarely a problem as for most containers +// const_iterator is a forward iterator. We'll fix this if there's an +// actual need for it. Note that this fix cannot rely on value_type +// being defined as many user-defined container types don't have +// value_type. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#include // NOLINT +#include +#include +#include +#include +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-internal.h" + +#if GTEST_HAS_STD_TUPLE_ +# include +#endif + +namespace testing { + +// Definitions in the 'internal' and 'internal2' name spaces are +// subject to change without notice. DO NOT USE THEM IN USER CODE! +namespace internal2 { + +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); + +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType // anything else +}; + +// TypeWithoutFormatter::PrintValue(value, os) is called +// by the universal printer to print a value of type T when neither +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template +class TypeWithoutFormatter { + public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo(reinterpret_cast(&value), + sizeof(value), os); + } +}; + +// We print a protobuf using its ShortDebugString() when the string +// doesn't exceed this many characters; otherwise we print it using +// DebugString() for better readability. +const size_t kProtobufOneLinerMaxLength = 50; + +template +class TypeWithoutFormatter { + public: + static void PrintValue(const T& value, ::std::ostream* os) { + const ::testing::internal::string short_str = value.ShortDebugString(); + const ::testing::internal::string pretty_str = + short_str.length() <= kProtobufOneLinerMaxLength ? + short_str : ("\n" + value.DebugString()); + *os << ("<" + pretty_str + ">"); + } +}; + +template +class TypeWithoutFormatter { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } +}; + +// Prints the given value to the given ostream. If the value is a +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). +// +// A user can override this behavior for a class type Foo by defining +// a << operator in the namespace where Foo is defined. +// +// We put this operator in namespace 'internal2' instead of 'internal' +// to simplify the implementation, as much code in 'internal' needs to +// use << in STL, which would conflict with our own << were it defined +// in 'internal'. +// +// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream, const Foo&) is more +// specific. +template +::std::basic_ostream& operator<<( + ::std::basic_ostream& os, const T& x) { + TypeWithoutFormatter::value ? kProtobuf : + internal::ImplicitlyConvertible::value ? + kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + return os; +} + +} // namespace internal2 +} // namespace testing + +// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up +// magic needed for implementing UniversalPrinter won't work. +namespace testing_internal { + +// Used to print a value that is not an STL-style container when the +// user doesn't define PrintTo() for it. +template +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT + + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; +} + +} // namespace testing_internal + +namespace testing { +namespace internal { + +// UniversalPrinter::Print(value, ostream_ptr) prints the given +// value to the given ostream. The caller must ensure that +// 'ostream_ptr' is not NULL, or the behavior is undefined. +// +// We define UniversalPrinter as a class template (as opposed to a +// function template), as we need to partially specialize it for +// reference types, which cannot be done with function templates. +template +class UniversalPrinter; + +template +void UniversalPrint(const T& value, ::std::ostream* os); + +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +template +void DefaultPrintTo(IsContainer /* dummy */, + false_type /* is not a pointer */, + const C& container, ::std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; +} + +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +template +void DefaultPrintTo(IsNotContainer /* dummy */, + true_type /* is a pointer */, + T* p, ::std::ostream* os) { + if (p == NULL) { + *os << "NULL"; + } else { + // C++ doesn't allow casting from a function pointer to any object + // pointer. + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible::value)) { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. However, we cannot cast it to const void* directly, + // even using reinterpret_cast, as earlier versions of gcc + // (e.g. 3.4.5) cannot compile the cast when p is a function + // pointer. Casting to UInt64 first solves the problem. + *os << reinterpret_cast( + reinterpret_cast(p)); + } + } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template +void DefaultPrintTo(IsNotContainer /* dummy */, + false_type /* is not a pointer */, + const T& value, ::std::ostream* os) { + ::testing_internal::DefaultPrintNonContainerTo(value, os); +} + +// Prints the given value using the << operator if it has one; +// otherwise prints the bytes in it. This is what +// UniversalPrinter::Print() does when PrintTo() is not specialized +// or overloaded for type T. +// +// A user can override this behavior for a class type Foo by defining +// an overload of PrintTo() in the namespace where Foo is defined. We +// give the user this option as sometimes defining a << operator for +// Foo is not desirable (e.g. the coding style may prevent doing it, +// or there is already a << operator but it doesn't do what the user +// wants). +template +void PrintTo(const T& value, ::std::ostream* os) { + // DefaultPrintTo() is overloaded. The type of its first two + // arguments determine which version will be picked. If T is an + // STL-style container, the version for container will be called; if + // T is a pointer, the pointer version will be called; otherwise the + // generic version will be called. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // The second argument of DefaultPrintTo() is needed to bypass a bug + // in Symbian's C++ compiler that prevents it from picking the right + // overload between: + // + // PrintTo(const T& x, ...); + // PrintTo(T* x, ...); + DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); +} + +// The following list of PrintTo() overloads tells +// UniversalPrinter::Print() how to print standard types (built-in +// types, strings, plain arrays, and pointers). + +// Overloads for various char types. +GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); +GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); +inline void PrintTo(char c, ::std::ostream* os) { + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast(c), os); +} + +// Overloads for other simple built-in types. +inline void PrintTo(bool x, ::std::ostream* os) { + *os << (x ? "true" : "false"); +} + +// Overload for wchar_t type. +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its decimal code (except for L'\0'). +// The L'\0' char is printed as "L'\\0'". The decimal code is printed +// as signed integer when wchar_t is implemented by the compiler +// as a signed type and is printed as an unsigned integer when wchar_t +// is implemented as an unsigned type. +GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); + +// Overloads for C strings. +GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); +inline void PrintTo(char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// signed/unsigned char is often used for representing binary data, so +// we print pointers to it as void* to be safe. +inline void PrintTo(const signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(const unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Overloads for wide C strings +GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +#endif + +// Overload for C arrays. Multi-dimensional arrays are printed +// properly. + +// Prints the given number of elements in an array, without printing +// the curly braces. +template +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) { + *os << ", "; + UniversalPrint(a[i], os); + } +} + +// Overloads for ::string and ::std::string. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); +inline void PrintTo(const ::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} + +// Overloads for ::wstring and ::std::wstring. +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os); +#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ + +#if GTEST_HAS_TR1_TUPLE +// Overload for ::std::tr1::tuple. Needed for printing function arguments, +// which are packed as tuples. + +// Overloaded PrintTo() for tuples of various arities. We support +// tuples of up-to 10 fields. The following implementation works +// regardless of whether tr1::tuple is implemented using the +// non-standard variadic template feature or not. + +inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo( + const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} +#endif // GTEST_HAS_TR1_TUPLE + +#if GTEST_HAS_STD_TUPLE_ +template +void PrintTo(const ::std::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} +#endif // GTEST_HAS_STD_TUPLE_ + +// Overload for std::pair. +template +void PrintTo(const ::std::pair& value, ::std::ostream* os) { + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter::Print(value.first, os); + *os << ", "; + UniversalPrinter::Print(value.second, os); + *os << ')'; +} + +// Implements printing a non-reference type T by letting the compiler +// pick the right overload of PrintTo() for T. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) + + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } + + GTEST_DISABLE_MSC_WARNINGS_POP_() +}; + +// UniversalPrintArray(begin, len, os) prints an array of 'len' +// elements, starting at address 'begin'. +template +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { + if (len == 0) { + *os << "{}"; + } else { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + // TODO(wan@google.com): let the user control the threshold using a flag. + if (len <= kThreshold) { + PrintRawArrayTo(begin, len, os); + } else { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } +} +// This overload prints a (const) char array compactly. +GTEST_API_ void UniversalPrintArray( + const char* begin, size_t len, ::std::ostream* os); + +// This overload prints a (const) wchar_t array compactly. +GTEST_API_ void UniversalPrintArray( + const wchar_t* begin, size_t len, ::std::ostream* os); + +// Implements printing an array type T[N]. +template +class UniversalPrinter { + public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) { + UniversalPrintArray(a, N, os); + } +}; + +// Implements printing a reference type T&. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) + + static void Print(const T& value, ::std::ostream* os) { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast(&value) << " "; + + // Then prints the value itself. + UniversalPrint(value, os); + } + + GTEST_DISABLE_MSC_WARNINGS_POP_() +}; + +// Prints a value tersely: for a reference type, the referenced value +// (but not the address) is printed; for a (const) char pointer, the +// NUL-terminated string (but not the pointer) is printed. + +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T (&value)[N], ::std::ostream* os) { + UniversalPrinter::Print(value, os); + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(const char* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(string(str), os); + } + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(char* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +#if GTEST_HAS_STD_WSTRING +template <> +class UniversalTersePrinter { + public: + static void Print(const wchar_t* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(::std::wstring(str), os); + } + } +}; +#endif + +template <> +class UniversalTersePrinter { + public: + static void Print(wchar_t* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +template +void UniversalTersePrint(const T& value, ::std::ostream* os) { + UniversalTersePrinter::Print(value, os); +} + +// Prints a value using the type inferred by the compiler. The +// difference between this and UniversalTersePrint() is that for a +// (const) char pointer, this prints both the pointer and the +// NUL-terminated string. +template +void UniversalPrint(const T& value, ::std::ostream* os) { + // A workarond for the bug in VC++ 7.1 that prevents us from instantiating + // UniversalPrinter with T directly. + typedef T T1; + UniversalPrinter::Print(value, os); +} + +typedef ::std::vector Strings; + +// TuplePolicy must provide: +// - tuple_size +// size of tuple TupleT. +// - get(const TupleT& t) +// static function extracting element I of tuple TupleT. +// - tuple_element::type +// type of element I of tuple TupleT. +template +struct TuplePolicy; + +#if GTEST_HAS_TR1_TUPLE +template +struct TuplePolicy { + typedef TupleT Tuple; + static const size_t tuple_size = ::std::tr1::tuple_size::value; + + template + struct tuple_element : ::std::tr1::tuple_element {}; + + template + static typename AddReference< + const typename ::std::tr1::tuple_element::type>::type get( + const Tuple& tuple) { + return ::std::tr1::get(tuple); + } +}; +template +const size_t TuplePolicy::tuple_size; +#endif // GTEST_HAS_TR1_TUPLE + +#if GTEST_HAS_STD_TUPLE_ +template +struct TuplePolicy< ::std::tuple > { + typedef ::std::tuple Tuple; + static const size_t tuple_size = ::std::tuple_size::value; + + template + struct tuple_element : ::std::tuple_element {}; + + template + static const typename ::std::tuple_element::type& get( + const Tuple& tuple) { + return ::std::get(tuple); + } +}; +template +const size_t TuplePolicy< ::std::tuple >::tuple_size; +#endif // GTEST_HAS_STD_TUPLE_ + +#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ +// This helper template allows PrintTo() for tuples and +// UniversalTersePrintTupleFieldsToStrings() to be defined by +// induction on the number of tuple fields. The idea is that +// TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N +// fields in tuple t, and can be defined in terms of +// TuplePrefixPrinter. +// +// The inductive case. +template +struct TuplePrefixPrinter { + // Prints the first N fields of a tuple. + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + TuplePrefixPrinter::PrintPrefixTo(t, os); + GTEST_INTENTIONAL_CONST_COND_PUSH_() + if (N > 1) { + GTEST_INTENTIONAL_CONST_COND_POP_() + *os << ", "; + } + UniversalPrinter< + typename TuplePolicy::template tuple_element::type> + ::Print(TuplePolicy::template get(t), os); + } + + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); + ::std::stringstream ss; + UniversalTersePrint(TuplePolicy::template get(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Base case. +template <> +struct TuplePrefixPrinter<0> { + template + static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} + + template + static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} +}; + +// Helper function for printing a tuple. +// Tuple must be either std::tr1::tuple or std::tuple type. +template +void PrintTupleTo(const Tuple& t, ::std::ostream* os) { + *os << "("; + TuplePrefixPrinter::tuple_size>::PrintPrefixTo(t, os); + *os << ")"; +} + +// Prints the fields of a tuple tersely to a string vector, one +// element for each field. See the comment before +// UniversalTersePrint() for how we define "tersely". +template +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { + Strings result; + TuplePrefixPrinter::tuple_size>:: + TersePrintPrefixToStrings(value, &result); + return result; +} +#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ + +} // namespace internal + +template +::std::string PrintToString(const T& value) { + ::std::stringstream ss; + internal::UniversalTersePrinter::Print(value, &ss); + return ss.str(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ diff --git a/src/test/gtest/include/gtest/gtest-spi.h b/src/test/gtest/include/gtest/gtest-spi.h new file mode 100644 index 00000000..f63fa9a1 --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-spi.h @@ -0,0 +1,232 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include "gtest/gtest.h" + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/src/test/gtest/include/gtest/gtest-test-part.h b/src/test/gtest/include/gtest/gtest-test-part.h new file mode 100644 index 00000000..77eb8448 --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-test-part.h @@ -0,0 +1,179 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include +#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name == NULL ? "" : a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { + return file_name_.empty() ? NULL : file_name_.c_str(); + } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static std::string ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // "" if the source file is unknown. + std::string file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + std::string summary_; // The test failure summary. + std::string message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ diff --git a/src/test/gtest/include/gtest/gtest-typed-test.h b/src/test/gtest/include/gtest/gtest-typed-test.h new file mode 100644 index 00000000..fe1e83b2 --- /dev/null +++ b/src/test/gtest/include/gtest/gtest-typed-test.h @@ -0,0 +1,259 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-type-util.h" + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +# define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +# define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +# define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +# define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template \ + class TestName : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() + +# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestCase::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ diff --git a/src/test/gtest/include/gtest/gtest.h b/src/test/gtest/include/gtest/gtest.h new file mode 100644 index 00000000..38ca3e97 --- /dev/null +++ b/src/test/gtest/include/gtest/gtest.h @@ -0,0 +1,2307 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include +#include +#include + +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" +#include "gtest/gtest-death-test.h" +#include "gtest/gtest-message.h" +#include "gtest/gtest-param-test.h" +#include "gtest/gtest-printers.h" +#include "gtest/gtest_prod.h" +#include "gtest/gtest-test-part.h" +#include "gtest/gtest-typed-test.h" + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// You can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If ::std::string and ::string are the same class on your platform +// due to aliasing, you should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If you do not define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// When this flag is set with a "host:port" string, on supported +// platforms test results are streamed to the specified port on +// the specified host machine. +GTEST_DECLARE_string_(stream_result_to); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class StreamingListenerTest; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class UnitTestRecordPropertyTestHelper; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message); + +} // namespace internal + +// The friend relationship of some of these classes is cyclic. +// If we don't forward declare them the compiler might confuse the classes +// in friendship clauses with same named classes on the scope. +class Test; +class TestCase; +class TestInfo; +class UnitTest; + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) + + // Used in the EXPECT_TRUE/FALSE(bool_expression). + // + // T must be contextually convertible to bool. + // + // The second parameter prevents this overload from being considered if + // the argument is implicitly convertible to AssertionResult. In that case + // we want AssertionResult's copy constructor to be used. + template + explicit AssertionResult( + const T& success, + typename internal::EnableIf< + !internal::ImplicitlyConvertible::value>::type* + /*enabler*/ = NULL) + : success_(success) {} + + GTEST_DISABLE_MSC_WARNINGS_POP_() + + // Assignment operator. + AssertionResult& operator=(AssertionResult other) { + swap(other); + return *this; + } + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL ? message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } + + private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == NULL) + message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } + + // Swap the contents of this AssertionResult with other. + void swap(AssertionResult& other); + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr< ::std::string> message_; +}; + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class TestInfo; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test, test case, or for the entire + // invocation of the test program when used outside of the context of a + // test case. Only the last value for a given key is remembered. These + // are public static so they can be called from utility functions that are + // not members of the test fixture. Calls to RecordProperty made during + // lifespan of the test (from the moment its constructor starts to the + // moment its destructor finishes) will be output in XML as attributes of + // the element. Properties recorded from fixture's + // SetUpTestCase or TearDownTestCase are logged as attributes of the + // corresponding element. Calls to RecordProperty made in the + // global context (before or after invocation of RUN_ALL_TESTS and from + // SetUp/TearDown method of Environment objects registered with Google + // Test) will be output as attributes of the element. + static void RecordProperty(const std::string& key, const std::string& value); + static void RecordProperty(const std::string& key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user misspells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if void Setup() is declared in the user's + // test fixture. + // + // - This method is private, so it will be another compiler error + // if the method is called from the user's test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const std::string& a_key, const std::string& a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const std::string& new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + std::string key_; + // The value supplied by the user. + std::string value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class TestCase; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. xml_element specifies the element for which the property is being + // recorded and is used for validation. + void RecordProperty(const std::string& xml_element, + const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const { + if (value_param_.get() != NULL) + return value_param_->c_str(); + return NULL; + } + + // Returns true if this test should run, that is if the test is not + // disabled (or it is disabled but the also_run_disabled_tests flag has + // been specified) and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const { return should_run_; } + + // Returns true iff this test will appear in the XML report. + bool is_reportable() const { + // For now, the XML report includes all tests matching the filter. + // In the future, we may trim tests that are excluded because of + // sharding. + return matches_filter_; + } + + // Returns the result of the test. + const TestResult* result() const { return &result_; } + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::UnitTestImpl; + friend class internal::StreamingListenerTest; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const std::string& test_case_name, + const std::string& name, + const char* a_type_param, // NULL if not a type-parameterized test + const char* a_value_param, // NULL if not a value-parameterized test + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const internal::scoped_ptr value_param_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test case. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + // Returns the TestResult that holds test properties recorded during + // execution of SetUpTestCase and TearDownTestCase. + const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } + + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } + + // Returns true iff test passed. + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } + + // Returns true iff test failed. + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } + + // Returns true iff the test is disabled and will be reported in the XML + // report. + static bool TestReportableDisabled(const TestInfo* test_info) { + return test_info->is_reportable() && test_info->is_disabled_; + } + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } + + // Returns true iff this test will appear in the XML report. + static bool TestReportable(const TestInfo* test_info) { + return test_info->is_reportable(); + } + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + std::string name_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + // Holds test properties recorded during execution of SetUpTestCase and + // TearDownTestCase. + TestResult ad_hoc_test_result_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. You should subclass this to define your own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class TestInfo; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the TestResult containing information on test failures and + // properties logged outside of individual test cases. + const TestResult& ad_hoc_test_result() const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Adds a TestProperty to the current TestResult object when invoked from + // inside a test, to current TestCase's ad_hoc_test_result_ when invoked + // from SetUpTestCase or TearDownTestCase, or to the global property set + // when invoked elsewhere. If the result already contains a property with + // the same key, the value will be updated. + void RecordProperty(const std::string& key, const std::string& value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend class internal::StreamingListenerTest; + friend class internal::UnitTestRecordPropertyTestHelper; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const std::string& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// FormatForComparison::Format(value) formats a +// value of type ToPrint that is an operand of a comparison assertion +// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in +// the comparison, and is used to help determine the best way to +// format the value. In particular, when the value is a C string +// (char pointer) and the other operand is an STL string object, we +// want to format the C string as a string, since we know it is +// compared by value with the string object. If the value is a char +// pointer but the other operand is not an STL string object, we don't +// know whether the pointer is supposed to point to a NUL-terminated +// string, and thus want to print it as a pointer to be safe. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// The default case. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint& value) { + return ::testing::PrintToString(value); + } +}; + +// Array. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint* value) { + return FormatForComparison::Format(value); + } +}; + +// By default, print C string as pointers to be safe, as we don't know +// whether they actually point to a NUL-terminated string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ + template \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(static_cast(value)); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ + +// If a C string is compared with an STL string object, we know it's meant +// to point to a NUL-terminated string, and thus can print it as a string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ + template <> \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(value); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); + +#if GTEST_HAS_GLOBAL_STRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); +#endif + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); +#endif + +#if GTEST_HAS_STD_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); +#endif + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char* or void*, and print it as a C string when it is compared +// against an std::string object, for example. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +std::string FormatForComparisonFailureMessage( + const T1& value, const T2& /* other_operand */) { + return FormatForComparison::Format(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */) + if (expected == actual) { + return AssertionSuccess(); + } +GTEST_DISABLE_MSC_WARNINGS_POP_() + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template +class EqHelper { + public: + // This templatized version is for the general case. + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal, like NULL, false, or 0. +template <> +class EqHelper { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual, + // The following line prevents this overload from being considered if T2 + // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) + // expands to Compare("", "", NULL, my_ptr), which requires a conversion + // to match the Secret* in the other overload, which would otherwise make + // this template match better. + typename EnableIf::value>::type* = 0) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to ASSERT_EQ() is a + // pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + // We used to have a second template parameter instead of Secret*. That + // template parameter would deduce to 'long', making this a better match + // than the first overload even without the first overload's EnableIf. + // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to + // non-pointer argument" (even a deduced integral argument), so the old + // implementation caused warnings in user code. + Secret* /* expected (NULL) */, + T* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template \ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, <); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, >); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + ::std::stringstream expected_ss; + expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << expected; + + ::std::stringstream actual_ss; + actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StringStreamToString(&expected_ss), + StringStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + std::string const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. +// +// This interface has support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template +class WithParamInterface { + public: + typedef T ParamType; + virtual ~WithParamInterface() {} + + // The current parameter value. Is also available in the test fixture's + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface::GetParam()' for a test that + // uses a fixture whose parameter type is int. + const ParamType& GetParam() const { + GTEST_CHECK_(parameter_ != NULL) + << "GetParam() can only be called inside a value-parameterized test " + << "-- did you intend to write TEST_P instead of TEST_F?"; + return *parameter_; + } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of WithParamInterface and Test. + template friend class internal::ParameterizedTestFactory; +}; + +template +const T* WithParamInterface::parameter_ = NULL; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template +class TestWithParam : public Test, public WithParamInterface { +}; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a nonfatal failure at the given source file location with +// a generic message. +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +# define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +# define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +#include "gtest/gtest_pred_impl.h" + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define GTEST_ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define GTEST_ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define GTEST_ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define GTEST_ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define GTEST_ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define GTEST_ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of +// ASSERT_XY(), which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_ASSERT_EQ +# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_NE +# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LE +# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LT +# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GE +# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GT +# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#endif + +// C-string Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +# define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +# define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +// Compile-time assertion for type equality. +// StaticAssertTypeEq() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq(); } +// }; +// +// the code: +// +// void Test1() { Foo foo; } +// +// will NOT generate a compiler error, as Foo::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo foo; foo.Bar(); } +// +// to cause a compiler error. +template +bool StaticAssertTypeEq() { + (void)internal::StaticAssertTypeEqHelper(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// Test code should appear between braces after an invocation of +// this macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) + +} // namespace testing + +// Use this function in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). +// +// This function was formerly a macro; thus, it is in the global +// namespace and has an all-caps name. +int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; + +inline int RUN_ALL_TESTS() { + return ::testing::UnitTest::GetInstance()->Run(); +} + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/src/test/gtest/include/gtest/gtest_pred_impl.h b/src/test/gtest/include/gtest/gtest_pred_impl.h new file mode 100644 index 00000000..30ae712f --- /dev/null +++ b/src/test/gtest/include/gtest/gtest_pred_impl.h @@ -0,0 +1,358 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/src/test/gtest/include/gtest/gtest_prod.h b/src/test/gtest/include/gtest/gtest_prod.h new file mode 100644 index 00000000..da80ddc6 --- /dev/null +++ b/src/test/gtest/include/gtest/gtest_prod.h @@ -0,0 +1,58 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-death-test-internal.h b/src/test/gtest/include/gtest/internal/gtest-death-test-internal.h new file mode 100644 index 00000000..2b3a78f5 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-death-test-internal.h @@ -0,0 +1,319 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +#include "gtest/internal/gtest-internal.h" + +#include + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const std::string& message); + + private: + // A string containing a description of the outcome of the last death test. + static std::string last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// Traps C++ exceptions escaping statement and reports them as test +// failures. Note that trapping SEH exceptions is not implemented here. +# if GTEST_HAS_EXCEPTIONS +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf(\ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } catch (...) { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } + +# else +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) + +# endif + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + default: \ + break; \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in +// NDEBUG mode. In this case we need the statements to be executed, the regex is +// ignored, and the macro must accept a streamed message even though the message +// is never printed. +# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } else \ + ::testing::Message() + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const std::string& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + const std::string& file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + std::string file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-filepath.h b/src/test/gtest/include/gtest/internal/gtest-filepath.h new file mode 100644 index 00000000..7a13b4b0 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-filepath.h @@ -0,0 +1,206 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in . +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + +#include "gtest/internal/gtest-string.h" + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const std::string& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + const std::string& string() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is "". + bool IsEmpty() const { return pathname_.empty(); } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + std::string pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-internal.h b/src/test/gtest/include/gtest/internal/gtest-internal.h new file mode 100644 index 00000000..ff8f6298 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-internal.h @@ -0,0 +1,1161 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_LINUX +# include +# include +# include +# include +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-type-util.h" + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +class ProtocolMessage; +namespace proto2 { class Message; } + +namespace testing { + +// Forward declarations. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +template +::std::string PrintToString(const T& value); + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +GTEST_API_ extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_IS_NULL_LITERAL_(x) false +#else +# define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ std::string AppendUserMessage( + const std::string& gtest_msg, const Message& user_msg); + +#if GTEST_HAS_EXCEPTIONS + +// This exception is thrown by (and only by) a failed Google Test +// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions +// are enabled). We derive it from std::runtime_error, which is for +// errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure); +}; + +#endif // GTEST_HAS_EXCEPTIONS + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Returns the maximum representable finite floating-point number. + static RawType Max(); + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// We cannot use std::numeric_limits::max() as it clashes with the max() +// macro defined by . +template <> +inline float FloatingPoint::Max() { return FLT_MAX; } +template <> +inline double FloatingPoint::Max() { return DBL_MAX; } + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint Float; +typedef FloatingPoint Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template +bool TypeIdHelper::dummy_ = false; + +// GetTypeId() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param text representation of the test's value parameter, +// or NULL if this is not a type-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (IsSpace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline std::string GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? str : std::string(str, comma); +} + +// TypeParameterizedTest::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + + StreamableToString(index)).c_str(), + GetPrefixUntilComma(test_names).c_str(), + GetTypeName().c_str(), + NULL, // No value parameter. + GetTypeId(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTest { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( + UnitTest* unit_test, int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; +}; + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +// Defining a variable of type CompileAssertTypesEqual will cause a +// compiler error iff T1 and T2 are different types. +template +struct CompileAssertTypesEqual; + +template +struct CompileAssertTypesEqual { +}; + +// Removes the reference from a type if it is a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::remove_reference, which is not widely available yet. +template +struct RemoveReference { typedef T type; }; // NOLINT +template +struct RemoveReference { typedef T type; }; // NOLINT + +// A handy wrapper around RemoveReference that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_REFERENCE_(T) \ + typename ::testing::internal::RemoveReference::type + +// Removes const from a type if it is a const type, otherwise leaves +// it unchanged. This is the same as tr1::remove_const, which is not +// widely available yet. +template +struct RemoveConst { typedef T type; }; // NOLINT +template +struct RemoveConst { typedef T type; }; // NOLINT + +// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above +// definition to fail to remove the const in 'const int[3]' and 'const +// char[3][4]'. The following specialization works around the bug. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; + +#if defined(_MSC_VER) && _MSC_VER < 1400 +// This is the only specialization that allows VC++ 7.1 to remove const in +// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC +// and thus needs to be conditionally compiled. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; +#endif + +// A handy wrapper around RemoveConst that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_CONST_(T) \ + typename ::testing::internal::RemoveConst::type + +// Turns const U&, U&, const U, and U all into U. +#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ + GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) + +// Adds reference to a type if it is not a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::add_reference, which is not widely available yet. +template +struct AddReference { typedef T& type; }; // NOLINT +template +struct AddReference { typedef T& type; }; // NOLINT + +// A handy wrapper around AddReference that works when the argument T +// depends on template parameters. +#define GTEST_ADD_REFERENCE_(T) \ + typename ::testing::internal::AddReference::type + +// Adds a reference to const on top of T as necessary. For example, +// it transforms +// +// char ==> const char& +// const char ==> const char& +// char& ==> const char& +// const char& ==> const char& +// +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) + +// ImplicitlyConvertible::value is a compile-time bool +// constant that's true iff type From can be implicitly converted to +// type To. +template +class ImplicitlyConvertible { + private: + // We need the following helper functions only for their types. + // They have no implementations. + + // MakeFrom() is an expression whose type is From. We cannot simply + // use From(), as the type From may not have a public default + // constructor. + static typename AddReference::type MakeFrom(); + + // These two functions are overloaded. Given an expression + // Helper(x), the compiler will pick the first version if x can be + // implicitly converted to type To; otherwise it will pick the + // second version. + // + // The first version returns a value of size 1, and the second + // version returns a value of size 2. Therefore, by checking the + // size of Helper(x), which can be done at compile time, we can tell + // which version of Helper() is used, and hence whether x can be + // implicitly converted to type To. + static char Helper(To); + static char (&Helper(...))[2]; // NOLINT + + // We have to put the 'public' section after the 'private' section, + // or MSVC refuses to compile the code. + public: +#if defined(__BORLANDC__) + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); +#else + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244) + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; + GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif // __BORLANDC__ +}; +template +const bool ImplicitlyConvertible::value; + +// IsAProtocolMessage::value is a compile-time bool constant that's +// true iff T is type ProtocolMessage, proto2::Message, or a subclass +// of those. +template +struct IsAProtocolMessage + : public bool_constant< + ImplicitlyConvertible::value || + ImplicitlyConvertible::value> { +}; + +// When the compiler sees expression IsContainerTest(0), if C is an +// STL-style container class, the first overload of IsContainerTest +// will be viable (since both C::iterator* and C::const_iterator* are +// valid types and NULL can be implicitly converted to them). It will +// be picked over the second overload as 'int' is a perfect match for +// the type of argument 0. If C::iterator or C::const_iterator is not +// a valid type, the first overload is not viable, and the second +// overload will be picked. Therefore, we can determine whether C is +// a container class by checking the type of IsContainerTest(0). +// The value of the expression is insignificant. +// +// Note that we look for both C::iterator and C::const_iterator. The +// reason is that C++ injects the name of a class as a member of the +// class itself (e.g. you can refer to class iterator as either +// 'iterator' or 'iterator::iterator'). If we look for C::iterator +// only, for example, we would mistakenly think that a class named +// iterator is an STL container. +// +// Also note that the simpler approach of overloading +// IsContainerTest(typename C::const_iterator*) and +// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. +typedef int IsContainer; +template +IsContainer IsContainerTest(int /* dummy */, + typename C::iterator* /* it */ = NULL, + typename C::const_iterator* /* const_it */ = NULL) { + return 0; +} + +typedef char IsNotContainer; +template +IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } + +// EnableIf::type is void when 'Cond' is true, and +// undefined when 'Cond' is false. To use SFINAE to make a function +// overload only apply when a particular expression is true, add +// "typename EnableIf::type* = 0" as the last parameter. +template struct EnableIf; +template<> struct EnableIf { typedef void type; }; // NOLINT + +// Utilities for native arrays. + +// ArrayEq() compares two k-dimensional native arrays using the +// elements' operator==, where k can be any integer >= 0. When k is +// 0, ArrayEq() degenerates into comparing a single pair of values. + +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs); + +// This generic version is used when k is 0. +template +inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } + +// This overload is used when k >= 1. +template +inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { + return internal::ArrayEq(lhs, N, rhs); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous ArrayEq() function, arrays with different sizes would +// lead to different copies of the template code. +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs) { + for (size_t i = 0; i != size; i++) { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; +} + +// Finds the first element in the iterator range [begin, end) that +// equals elem. Element may be a native array type itself. +template +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { + for (Iter it = begin; it != end; ++it) { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; +} + +// CopyArray() copies a k-dimensional native array using the elements' +// operator=, where k can be any integer >= 0. When k is 0, +// CopyArray() degenerates into copying a single value. + +template +void CopyArray(const T* from, size_t size, U* to); + +// This generic version is used when k is 0. +template +inline void CopyArray(const T& from, U* to) { *to = from; } + +// This overload is used when k >= 1. +template +inline void CopyArray(const T(&from)[N], U(*to)[N]) { + internal::CopyArray(from, N, *to); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous CopyArray() function, arrays with different sizes +// would lead to different copies of the template code. +template +void CopyArray(const T* from, size_t size, U* to) { + for (size_t i = 0; i != size; i++) { + internal::CopyArray(from[i], to + i); + } +} + +// The relation between an NativeArray object (see below) and the +// native array it represents. +// We use 2 different structs to allow non-copyable types to be used, as long +// as RelationToSourceReference() is passed. +struct RelationToSourceReference {}; +struct RelationToSourceCopy {}; + +// Adapts a native array to a read-only STL-style container. Instead +// of the complete STL container concept, this adaptor only implements +// members useful for Google Mock's container matchers. New members +// should be added as needed. To simplify the implementation, we only +// support Element being a raw type (i.e. having no top-level const or +// reference modifier). It's the client's responsibility to satisfy +// this requirement. Element can be an array type itself (hence +// multi-dimensional arrays are supported). +template +class NativeArray { + public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; + + // Constructs from a native array. References the source. + NativeArray(const Element* array, size_t count, RelationToSourceReference) { + InitRef(array, count); + } + + // Constructs from a native array. Copies the source. + NativeArray(const Element* array, size_t count, RelationToSourceCopy) { + InitCopy(array, count); + } + + // Copy constructor. + NativeArray(const NativeArray& rhs) { + (this->*rhs.clone_)(rhs.array_, rhs.size_); + } + + ~NativeArray() { + if (clone_ != &NativeArray::InitRef) + delete[] array_; + } + + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } + + private: + enum { + kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper< + Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value, + }; + + // Initializes this object with a copy of the input. + void InitCopy(const Element* array, size_t a_size) { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + size_ = a_size; + clone_ = &NativeArray::InitCopy; + } + + // Initializes this object with a reference of the input. + void InitRef(const Element* array, size_t a_size) { + array_ = array; + size_ = a_size; + clone_ = &NativeArray::InitRef; + } + + const Element* array_; + size_t size_; + void (NativeArray::*clone_)(const Element*, size_t); + + GTEST_DISALLOW_ASSIGN_(NativeArray); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) \ + = ::testing::Message() + +#define GTEST_MESSAGE_(message, result_type) \ + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg.value) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws.") + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail("Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't.") + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail("Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, NULL, NULL, \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + diff --git a/src/test/gtest/include/gtest/internal/gtest-linked_ptr.h b/src/test/gtest/include/gtest/internal/gtest-linked_ptr.h new file mode 100644 index 00000000..b1362cd0 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-linked_ptr.h @@ -0,0 +1,233 @@ +// Copyright 2003 Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include +#include + +#include "gtest/internal/gtest-port.h" + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr(obj) vs linked_ptr(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr, linked_ptr, and + // linked_ptr). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + void join(linked_ptr_internal const* ptr) + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + bool depart() + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template linked_ptr& operator=(linked_ptr const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template + bool operator==(linked_ptr const& ptr) const { + return value_ == ptr.get(); + } + template + bool operator!=(linked_ptr const& ptr) const { + return value_ != ptr.get(); + } + + private: + template + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template void copy(linked_ptr const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template inline +bool operator==(T* ptr, const linked_ptr& x) { + return ptr == x.get(); +} + +template inline +bool operator!=(T* ptr, const linked_ptr& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr +// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation +// for linked_ptr >(new FooBarBaz(arg)) +template +linked_ptr make_linked_ptr(T* ptr) { + return linked_ptr(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h b/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h new file mode 100644 index 00000000..6dbaf4b7 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h @@ -0,0 +1,5143 @@ +// This file was GENERATED by command: +// pump.py gtest-param-util-generated.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_), static_cast(v50_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator2(const ParamGenerator& g1, + const ParamGenerator& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; +}; // class CartesianProductGenerator2 + + +template +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator3(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; +}; // class CartesianProductGenerator3 + + +template +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator4(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; +}; // class CartesianProductGenerator4 + + +template +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator5(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; +}; // class CartesianProductGenerator5 + + +template +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator6(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; +}; // class CartesianProductGenerator6 + + +template +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator7(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; +}; // class CartesianProductGenerator7 + + +template +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator8(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; +}; // class CartesianProductGenerator8 + + +template +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator9(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; +}; // class CartesianProductGenerator9 + + +template +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::testing::tuple > { + public: + typedef ::testing::tuple ParamType; + + CartesianProductGenerator10(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9, + const ParamGenerator& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9, + const ParamGenerator& g10, + const typename ParamGenerator::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + const typename ParamGenerator::iterator begin10_; + const typename ParamGenerator::iterator end10_; + typename ParamGenerator::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; + const ParamGenerator g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +template +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator2( + static_cast >(g1_), + static_cast >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator3( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator4( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator5( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator6( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator7( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator8( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator9( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( + new CartesianProductGenerator10( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_), + static_cast >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump b/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump new file mode 100644 index 00000000..801a2fc7 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump @@ -0,0 +1,301 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of Values arguments we want to support. +$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most $n arguments in Values, +// and at most $maxtuple arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tuple which is +// currently set at $maxtuple. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +$range i 2..n +$for i [[ +$range j 1..i + +template <$for j, [[typename T$j]]> +class ValueArray$i { + public: + ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {} + + template + operator ParamGenerator() const { + const T array[] = {$for j, [[static_cast(v$(j)_)]]}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray$i& other); + +$for j [[ + + const T$j v$(j)_; +]] + +}; + +]] + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +$range i 2..maxtuple +$for i [[ +$range j 1..i +$range k 2..i + +template <$for j, [[typename T$j]]> +class CartesianProductGenerator$i + : public ParamGeneratorInterface< ::testing::tuple<$for j, [[T$j]]> > { + public: + typedef ::testing::tuple<$for j, [[T$j]]> ParamType; + + CartesianProductGenerator$i($for j, [[const ParamGenerator& g$j]]) + : $for j, [[g$(j)_(g$j)]] {} + virtual ~CartesianProductGenerator$i() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, $for j, [[ + + const ParamGenerator& g$j, + const typename ParamGenerator::iterator& current$(j)]]) + : base_(base), +$for j, [[ + + begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j) +]] { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current$(i)_; + +$for k [[ + if (current$(i+2-k)_ == end$(i+2-k)_) { + current$(i+2-k)_ = begin$(i+2-k)_; + ++current$(i+2-k-1)_; + } + +]] + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ($for j && [[ + + current$(j)_ == typed_other->current$(j)_ +]]); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), $for j, [[ + + begin$(j)_(other.begin$(j)_), + end$(j)_(other.end$(j)_), + current$(j)_(other.current$(j)_) +]] { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType($for j, [[*current$(j)_]]); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return +$for j || [[ + + current$(j)_ == end$(j)_ +]]; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. +$for j [[ + + const typename ParamGenerator::iterator begin$(j)_; + const typename ParamGenerator::iterator end$(j)_; + typename ParamGenerator::iterator current$(j)_; +]] + + ParamType current_value_; + }; // class CartesianProductGenerator$i::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator$i& other); + + +$for j [[ + const ParamGenerator g$(j)_; + +]] +}; // class CartesianProductGenerator$i + + +]] + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +$range i 2..maxtuple +$for i [[ +$range j 1..i + +template <$for j, [[class Generator$j]]> +class CartesianProductHolder$i { + public: +CartesianProductHolder$i($for j, [[const Generator$j& g$j]]) + : $for j, [[g$(j)_(g$j)]] {} + template <$for j, [[typename T$j]]> + operator ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >() const { + return ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >( + new CartesianProductGenerator$i<$for j, [[T$j]]>( +$for j,[[ + + static_cast >(g$(j)_) +]])); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder$i& other); + + +$for j [[ + const Generator$j g$(j)_; + +]] +}; // class CartesianProductHolder$i + +]] + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-param-util.h b/src/test/gtest/include/gtest/internal/gtest-param-util.h new file mode 100644 index 00000000..d5e1028b --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-param-util.h @@ -0,0 +1,619 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include +#include +#include + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-linked_ptr.h" +#include "gtest/internal/gtest-port.h" +#include "gtest/gtest-printers.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template class ParamGeneratorInterface; +template class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface. +template +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface. It wraps ParamIteratorInterface +// and implements the const forward iterator concept. +template +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + scoped_ptr > impl_; +}; + +// ParamGeneratorInterface is the binary interface to access generators +// defined in other translation units. +template +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; +}; + +// Wraps ParamGeneratorInterface and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template +class ParamGenerator { + public: + typedef ParamIterator iterator; + + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + linked_ptr > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template +class RangeGenerator : public ParamGeneratorInterface { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { + public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector ContainerType; + + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template +class TestMetaFactory + : public TestMetaFactoryBase { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const string& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const string& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase* meta_factory) { + tests_.push_back(linked_ptr(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const string& instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const string& instantiation_name = gen_it->first; + ParamGenerator generator((*gen_it->second)()); + + string test_case_name; + if ( !instantiation_name.empty() ) + test_case_name = instantiation_name + "/"; + test_case_name += test_info->test_case_base_name; + + int i = 0; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name << "/" << i; + MakeAndRegisterTestInfo( + test_case_name.c_str(), + test_name_stream.GetString().c_str(), + NULL, // No type parameter. + PrintToString(*param_it).c_str(), + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const string test_case_base_name; + const string test_base_name; + const scoped_ptr > test_meta_factory; + }; + typedef ::std::vector > TestInfoContainer; + // Keeps pairs of + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector > + InstantiationContainer; + + const string test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + posix::Abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-port.h b/src/test/gtest/include/gtest/internal/gtest-port.h new file mode 100644 index 00000000..f376dfa0 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-port.h @@ -0,0 +1,2432 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. All macros ending with _ and symbols defined in an +// internal namespace are subject to change without notice. Code +// outside Google Test MUST NOT USE THEM DIRECTLY. Macros that don't +// end with _ are part of Google Test's public API and can be used by +// code outside Google Test. +// +// This file is fundamental to Google Test. All other Google Test source +// files are expected to #include this. Therefore, it cannot #include +// any other Google Test header. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// Environment-describing macros +// ----------------------------- +// +// Google Test can be used in many different environments. Macros in +// this section tell Google Test what kind of environment it is being +// used in, such that Google Test can provide environment-specific +// features and implementations. +// +// Google Test tries to automatically detect the properties of its +// environment, so users usually don't need to worry about these +// macros. However, the automatic detection is not perfect. +// Sometimes it's necessary for a user to define some of the following +// macros in the build script to override Google Test's decisions. +// +// If the user doesn't define a macro in the list, Google Test will +// provide a default definition. After this header is #included, all +// macros in this list will be defined to either 1 or 0. +// +// Notes to maintainers: +// - Each macro here is a user-tweakable knob; do not grow the list +// lightly. +// - Use #if to key off these macros. Don't use #ifdef or "#if +// defined(...)", which will not work as these macros are ALWAYS +// defined. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular +// expressions are/aren't available. +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_HAS_STREAM_REDIRECTION +// - Define it to 1/0 to indicate whether the +// platform supports I/O stream redirection using +// dup() and dup2(). +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test +// is building in C++11/C++98 mode. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// Platform-indicating macros +// -------------------------- +// +// Macros indicating the platform on which Google Test is being used +// (a macro is defined to 1 if compiled on the given platform; +// otherwise UNDEFINED -- it's never defined to 0.). Google Test +// defines these macros automatically. Code outside Google Test MUST +// NOT define them. +// +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_HPUX - HP-UX +// GTEST_OS_LINUX - Linux +// GTEST_OS_LINUX_ANDROID - Google Android +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_IOS - iOS +// GTEST_OS_IOS_SIMULATOR - iOS simulator +// GTEST_OS_NACL - Google Native Client (NaCl) +// GTEST_OS_OPENBSD - OpenBSD +// GTEST_OS_QNX - QNX +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_WINDOWS_PHONE - Windows Phone +// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// It is possible that none of the GTEST_OS_* macros are defined. + +// Feature-indicating macros +// ------------------------- +// +// Macros indicating which Google Test features are available (a macro +// is defined to 1 if the corresponding feature is supported; +// otherwise UNDEFINED -- it's never defined to 0.). Google Test +// defines these macros automatically. Code outside Google Test MUST +// NOT define them. +// +// These macros are public so that portable tests can be written. +// Such tests typically surround code using a feature with an #if +// which controls that code. For example: +// +// #if GTEST_HAS_DEATH_TEST +// EXPECT_DEATH(DoSomethingDeadly()); +// #endif +// +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_IS_THREADSAFE - Google Test is thread-safe. +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with +// GTEST_HAS_POSIX_RE (see above) which users can +// define themselves. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). + +// Misc public macros +// ------------------ +// +// GTEST_FLAG(flag_name) - references the variable corresponding to +// the given Google Test flag. + +// Internal utilities +// ------------------ +// +// The following macros and utilities are for Google Test's INTERNAL +// use only. Code outside Google Test MUST NOT USE THEM DIRECTLY. +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is +// suppressed (constant conditional). +// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 +// is suppressed. +// +// C++11 feature wrappers: +// +// GTEST_MOVE_ - portability wrapper for std::move. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// IteratorTraits - partial implementation of std::iterator_traits, which +// is not available in libCstd when compiled with Sun C++. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax on UNIX-like +// platforms, or a reduced regular exception syntax on +// other platforms, including Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetInjectableArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include // for isspace, etc +#include // for ptrdiff_t +#include +#include +#include +#ifndef _WIN32_WCE +# include +# include +#endif // !_WIN32_WCE + +#if defined __APPLE__ +# include +# include +#endif + +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +# define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +# define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +# define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +# define GTEST_OS_WINDOWS 1 +# ifdef _WIN32_WCE +# define GTEST_OS_WINDOWS_MOBILE 1 +# elif defined(__MINGW__) || defined(__MINGW32__) +# define GTEST_OS_WINDOWS_MINGW 1 +# elif defined(WINAPI_FAMILY) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define GTEST_OS_WINDOWS_DESKTOP 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +# define GTEST_OS_WINDOWS_PHONE 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +# define GTEST_OS_WINDOWS_RT 1 +# else + // WINAPI_FAMILY defined but no known partition matched. + // Default to desktop. +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE +#elif defined __APPLE__ +# define GTEST_OS_MAC 1 +# if TARGET_OS_IPHONE +# define GTEST_OS_IOS 1 +# if TARGET_IPHONE_SIMULATOR +# define GTEST_OS_IOS_SIMULATOR 1 +# endif +# endif +#elif defined __linux__ +# define GTEST_OS_LINUX 1 +# if defined __ANDROID__ +# define GTEST_OS_LINUX_ANDROID 1 +# endif +#elif defined __MVS__ +# define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +# define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +# define GTEST_OS_AIX 1 +#elif defined(__hpux) +# define GTEST_OS_HPUX 1 +#elif defined __native_client__ +# define GTEST_OS_NACL 1 +#elif defined __OpenBSD__ +# define GTEST_OS_OPENBSD 1 +#elif defined __QNX__ +# define GTEST_OS_QNX 1 +#endif // __CYGWIN__ + +// Macros for disabling Microsoft Visual C++ warnings. +// +// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385) +// /* code that triggers warnings C4800 and C4385 */ +// GTEST_DISABLE_MSC_WARNINGS_POP_() +#if _MSC_VER >= 1500 +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ + __pragma(warning(push)) \ + __pragma(warning(disable: warnings)) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() \ + __pragma(warning(pop)) +#else +// Older versions of MSVC don't have __pragma. +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif + +#ifndef GTEST_LANG_CXX11 +// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when +// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a +// value for __cplusplus, and recent versions of clang, gcc, and +// probably other compilers set that too in C++11 mode. +# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L +// Compiling in at least C++11 mode. +# define GTEST_LANG_CXX11 1 +# else +# define GTEST_LANG_CXX11 0 +# endif +#endif + +// C++11 specifies that provides std::initializer_list. Use +// that if gtest is used in C++11 mode and libstdc++ isn't very old (binaries +// targeting OS X 10.6 can build with clang but need to use gcc4.2's +// libstdc++). +#if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +# define GTEST_HAS_STD_INITIALIZER_LIST_ 1 +#endif + +// C++11 specifies that provides std::tuple. +// Some platforms still might not have it, however. +#if GTEST_LANG_CXX11 +# define GTEST_HAS_STD_TUPLE_ 1 +# if defined(__clang__) +// Inspired by http://clang.llvm.org/docs/LanguageExtensions.html#__has_include +# if defined(__has_include) && !__has_include() +# undef GTEST_HAS_STD_TUPLE_ +# endif +# elif defined(_MSC_VER) +// Inspired by boost/config/stdlib/dinkumware.hpp +# if defined(_CPPLIB_VER) && _CPPLIB_VER < 520 +# undef GTEST_HAS_STD_TUPLE_ +# endif +# elif defined(__GLIBCXX__) +// Inspired by boost/config/stdlib/libstdcpp3.hpp, +// http://gcc.gnu.org/gcc-4.2/changes.html and +// http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01.html#manual.intro.status.standard.200x +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) +# undef GTEST_HAS_STD_TUPLE_ +# endif +# endif +#endif + +// Brings in definitions for functions used in the testing::internal::posix +// namespace (read, write, close, chdir, isatty, stat). We do not currently +// use them on Windows Mobile. +#if GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS_MOBILE +# include +# include +# endif +// In order to avoid having to include , use forward declaration +// assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION. +// This assumption is verified by +// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. +struct _RTL_CRITICAL_SECTION; +#else +// This assumes that non-Windows OSes provide unistd.h. For OSes where this +// is not the case, we need to include headers that provide the functions +// mentioned above. +# include +# include +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_LINUX_ANDROID +// Used to define __ANDROID_API__ matching the target NDK API level. +# include // NOLINT +#endif + +// Defines this to true iff Google Test can use POSIX regular expressions. +#ifndef GTEST_HAS_POSIX_RE +# if GTEST_OS_LINUX_ANDROID +// On Android, is only available starting with Gingerbread. +# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) +# else +# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +# endif +#endif + +#if GTEST_HAS_POSIX_RE + +// On some platforms, needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included , which is guaranteed to define size_t through +// . +# include // NOLINT + +# define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +// is not available on Windows. Use our own simple regex +// implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#else + +// may not be available on this platform. Use our own +// simple regex implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_HAS_POSIX_RE + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +# if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +# ifndef _HAS_EXCEPTIONS +# define _HAS_EXCEPTIONS 1 +# endif // _HAS_EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__HP_aCC) +// Exception handling is in effect by default in HP aCC compiler. It has to +// be turned of by +noeh compiler option if desired. +# define GTEST_HAS_EXCEPTIONS 1 +# else +// For other compilers, we assume exceptions are disabled to be +// conservative. +# define GTEST_HAS_EXCEPTIONS 0 +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +# define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +# error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +# define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.7 and below doesn't support ::std::wstring. +// Solaris' libc++ doesn't support it either. Android has +// no support for it at least as recent as Froyo (2.2). +# define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +# define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +# ifdef _MSC_VER + +# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +# ifdef __GXX_RTTI +// When building against STLport with the Android NDK and with +// -frtti -fno-exceptions, the build fails at link time with undefined +// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, +// so disable RTTI when detected. +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ + !defined(__EXCEPTIONS) +# define GTEST_HAS_RTTI 0 +# else +# define GTEST_HAS_RTTI 1 +# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS +# else +# define GTEST_HAS_RTTI 0 +# endif // __GXX_RTTI + +// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends +// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the +// first version with C++ support. +# elif defined(__clang__) + +# define GTEST_HAS_RTTI __has_feature(cxx_rtti) + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +# ifdef __RTTI_ALL__ +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +# else + +// For all other compilers, we assume RTTI is enabled. +# define GTEST_HAS_RTTI 1 + +# endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include when RTTI +// is enabled. +#if GTEST_HAS_RTTI +# include +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ + || GTEST_OS_QNX) +#endif // GTEST_HAS_PTHREAD + +#if GTEST_HAS_PTHREAD +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +# include // NOLINT + +// For timespec and nanosleep, used below. +# include // NOLINT +#endif + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) +// STLport, provided with the Android NDK, has neither or . +# define GTEST_HAS_TR1_TUPLE 0 +# else +// The user didn't tell us not to do it, so we assume it's OK. +# define GTEST_HAS_TR1_TUPLE 1 +# endif +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, libstdc++ 4.0.0+ and +// MSVC 2010 are the only mainstream standard libraries that come +// with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler +// pretends to be GCC by defining __GNUC__ and friends, but cannot +// compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 +// tuple in a 323 MB Feature Pack download, which we cannot assume the +// user has. QNX's QCC compiler is a modified GCC but it doesn't +// support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, +// and it can be used with some compilers that define __GNUC__. +# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ + && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 +# define GTEST_ENV_HAS_TR1_TUPLE_ 1 +# endif + +// C++11 specifies that provides std::tuple. Use that if gtest is used +// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 +// can build with clang but need to use gcc4.2's libstdc++). +# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +# define GTEST_ENV_HAS_STD_TUPLE_ 1 +# endif + +# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ +# define GTEST_USE_OWN_TR1_TUPLE 0 +# else +# define GTEST_USE_OWN_TR1_TUPLE 1 +# endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tuple. +#if GTEST_HAS_STD_TUPLE_ +# include // IWYU pragma: export +# define GTEST_TUPLE_NAMESPACE_ ::std +#endif // GTEST_HAS_STD_TUPLE_ + +// We include tr1::tuple even if std::tuple is available to define printers for +// them. +#if GTEST_HAS_TR1_TUPLE +# ifndef GTEST_TUPLE_NAMESPACE_ +# define GTEST_TUPLE_NAMESPACE_ ::std::tr1 +# endif // GTEST_TUPLE_NAMESPACE_ + +# if GTEST_USE_OWN_TR1_TUPLE +# include "gtest/internal/gtest-tuple.h" // IWYU pragma: export // NOLINT +# elif GTEST_ENV_HAS_STD_TUPLE_ +# include +// C++11 puts its tuple into the ::std namespace rather than +// ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. +// This causes undefined behavior, but supported compilers react in +// the way we intend. +namespace std { +namespace tr1 { +using ::std::get; +using ::std::make_tuple; +using ::std::tuple; +using ::std::tuple_element; +using ::std::tuple_size; +} +} + +# elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +# ifdef BOOST_HAS_TR1_TUPLE +# undef BOOST_HAS_TR1_TUPLE +# endif // BOOST_HAS_TR1_TUPLE + +// This prevents , which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's . +# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +# include // IWYU pragma: export // NOLINT + +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the header. This does +// not conform to the TR1 spec, which requires the header to be . + +# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes , +// which is #included by , to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// . Hence the following #define is a hack to prevent +// from being included. +# define _TR1_FUNCTIONAL 1 +# include +# undef _TR1_FUNCTIONAL // Allows the user to #include + // if he chooses to. +# else +# include // NOLINT +# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +# else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +# include // IWYU pragma: export // NOLINT +# endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +# if GTEST_OS_LINUX && !defined(__ia64__) +# if GTEST_OS_LINUX_ANDROID +// On Android, clone() is only available on ARM starting with Gingerbread. +# if defined(__arm__) && __ANDROID_API__ >= 9 +# define GTEST_HAS_CLONE 1 +# else +# define GTEST_HAS_CLONE 0 +# endif +# else +# define GTEST_HAS_CLONE 1 +# endif +# else +# define GTEST_HAS_CLONE 0 +# endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#ifndef GTEST_HAS_STREAM_REDIRECTION +// By default, we assume that stream redirection is supported on all +// platforms except known mobile ones. +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || \ + GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT +# define GTEST_HAS_STREAM_REDIRECTION 0 +# else +# define GTEST_HAS_STREAM_REDIRECTION 1 +# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ + GTEST_OS_OPENBSD || GTEST_OS_QNX) +# define GTEST_HAS_DEATH_TEST 1 +# include // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, IBM Visual Age, and HP aCC support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) || defined(__HP_aCC) +# define GTEST_HAS_TYPED_TEST 1 +# define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +# define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Determines whether test results can be streamed to a socket. +#if GTEST_OS_LINUX +# define GTEST_CAN_STREAM_RESULTS_ 1 +#endif + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +# define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +# define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +#if GTEST_LANG_CXX11 +# define GTEST_MOVE_(x) ::std::move(x) // NOLINT +#else +# define GTEST_MOVE_(x) x +#endif + +// MS C++ compiler emits warning when a conditional expression is compile time +// constant. In some contexts this warning is false positive and needs to be +// suppressed. Use the following two macros in such cases: +// +// GTEST_INTENTIONAL_CONST_COND_PUSH_() +// while (true) { +// GTEST_INTENTIONAL_CONST_COND_POP_() +// } +# define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) +# define GTEST_INTENTIONAL_CONST_COND_POP_() \ + GTEST_DISABLE_MSC_WARNINGS_POP_() + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +# if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +# define GTEST_HAS_SEH 1 +# else +// Assume no SEH. +# define GTEST_HAS_SEH 0 +# endif + +#define GTEST_IS_THREADSAFE \ + (0 \ + || (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \ + || GTEST_HAS_PTHREAD) + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +# if GTEST_LINKED_AS_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllimport) +# elif GTEST_CREATE_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllexport) +# endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +# define GTEST_API_ +#endif + +#ifdef __GNUC__ +// Ask the compiler to never inline a given function. +# define GTEST_NO_INLINE_ __attribute__((noinline)) +#else +# define GTEST_NO_INLINE_ +#endif + +// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. +#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) +# define GTEST_HAS_CXXABI_H_ 1 +#else +# define GTEST_HAS_CXXABI_H_ 0 +#endif + +// A function level attribute to disable checking for use of uninitialized +// memory when built with MemorySanitizer. +#if defined(__clang__) +# if __has_feature(memory_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ \ + __attribute__((no_sanitize_memory)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +# endif // __has_feature(memory_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +#endif // __clang__ + +// A function level attribute to disable AddressSanitizer instrumentation. +#if defined(__clang__) +# if __has_feature(address_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ + __attribute__((no_sanitize_address)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +# endif // __has_feature(address_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +#endif // __clang__ + +// A function level attribute to disable ThreadSanitizer instrumentation. +#if defined(__clang__) +# if __has_feature(thread_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \ + __attribute__((no_sanitize_thread)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +# endif // __has_feature(thread_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +#endif // __clang__ + +namespace testing { + +class Message; + +#if defined(GTEST_TUPLE_NAMESPACE_) +// Import tuple and friends into the ::testing namespace. +// It is part of our interface, having them in ::testing allows us to change +// their types as needed. +using GTEST_TUPLE_NAMESPACE_::get; +using GTEST_TUPLE_NAMESPACE_::make_tuple; +using GTEST_TUPLE_NAMESPACE_::tuple; +using GTEST_TUPLE_NAMESPACE_::tuple_size; +using GTEST_TUPLE_NAMESPACE_::tuple_element; +#endif // defined(GTEST_TUPLE_NAMESPACE_) + +namespace internal { + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES, +// names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +template +struct CompileAssert { +}; + +#define GTEST_COMPILE_ASSERT_(expr, msg) \ + typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ + msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ + +// Implementation details of GTEST_COMPILE_ASSERT_: +// +// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// GTEST_COMPILE_ASSERT_(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. +// +// This template is declared, but intentionally undefined. +template +struct StaticAssertTypeEqHelper; + +template +struct StaticAssertTypeEqHelper { + enum { value = true }; +}; + +// Evaluates to the number of elements in 'array'. +#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0])) + +#if GTEST_HAS_GLOBAL_STRING +typedef ::string string; +#else +typedef ::std::string string; +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +typedef ::wstring wstring; +#elif GTEST_HAS_STD_WSTRING +typedef ::std::wstring wstring; +#endif // GTEST_HAS_GLOBAL_WSTRING + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + + friend void swap(scoped_ptr& a, scoped_ptr& b) { + using std::swap; + swap(a.ptr_, b.ptr_); + } + + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for . It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT + +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of an std::string, as Google Test used to be + // used where std::string is not available. TODO(wan@google.com): change to + // std::string. + const char* pattern_; + bool is_valid_; + +#if GTEST_USES_POSIX_RE + + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). + +#else // GTEST_USES_SIMPLE_RE + + const char* full_pattern_; // For FullMatch(); + +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Use ImplicitCast_ as a safe version of static_cast for upcasting in +// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a +// const Foo*). When you use ImplicitCast_, the compiler checks that +// the cast is safe. Such explicit ImplicitCast_s are necessary in +// surprisingly many situations where C++ demands an exact type match +// instead of an argument type convertable to a target type. +// +// The syntax for using ImplicitCast_ is the same as for static_cast: +// +// ImplicitCast_(expr) +// +// ImplicitCast_ would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., implicit_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template +inline To ImplicitCast_(To x) { return x; } + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., down_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + GTEST_INTENTIONAL_CONST_COND_PUSH_() + if (false) { + GTEST_INTENTIONAL_CONST_COND_POP_() + const To to = NULL; + ::testing::internal::ImplicitCast_(to); + } + +#if GTEST_HAS_RTTI + // RTTI: debug mode only! + GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); +#endif + return static_cast(f); +} + +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast(base); // NOLINT +#else + return static_cast(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ std::string GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ std::string GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION + + +#if GTEST_HAS_DEATH_TEST + +const ::std::vector& GetInjectableArgvs(); +void SetInjectableArgvs(const ::std::vector* + new_argvs); + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector g_argvs; + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. +#if GTEST_IS_THREADSAFE +# if GTEST_HAS_PTHREAD +// Sleeps for (roughly) n milliseconds. This function is only for testing +// Google Test's own constructs. Don't use it in user tests, either +// directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} +# endif // GTEST_HAS_PTHREAD + +# if 0 // OS detection +# elif GTEST_HAS_PTHREAD +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + } + ~Notification() { + pthread_mutex_destroy(&mutex_); + } + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { + pthread_mutex_lock(&mutex_); + notified_ = true; + pthread_mutex_unlock(&mutex_); + } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + for (;;) { + pthread_mutex_lock(&mutex_); + const bool notified = notified_; + pthread_mutex_unlock(&mutex_); + if (notified) + break; + SleepMilliseconds(10); + } + } + + private: + pthread_mutex_t mutex_; + bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +GTEST_API_ void SleepMilliseconds(int n); + +// Provides leak-safe Windows kernel handle ownership. +// Used in death tests and in threading support. +class GTEST_API_ AutoHandle { + public: + // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to + // avoid including in this header file. Including is + // undesirable because it defines a lot of symbols and macros that tend to + // conflict with client code. This assumption is verified by + // WindowsTypesTest.HANDLEIsVoidStar. + typedef void* Handle; + AutoHandle(); + explicit AutoHandle(Handle handle); + + ~AutoHandle(); + + Handle Get() const; + void Reset(); + void Reset(Handle handle); + + private: + // Returns true iff the handle is a valid handle object that can be closed. + bool IsCloseable() const; + + Handle handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class GTEST_API_ Notification { + public: + Notification(); + void Notify(); + void WaitForNotification(); + + private: + AutoHandle event_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; +# endif // OS detection + +// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD +// defined, but we don't want to use MinGW's pthreads implementation, which +// has conformance problems with some versions of the POSIX standard. +# if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void UserThreadFunc(T); + + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + UserThreadFunc* const func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; +# endif // GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW + +# if 0 // OS detection +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +// Mutex implements mutex on Windows platforms. It is used in conjunction +// with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the +// // end of the current scope. +// +// A static Mutex *must* be defined or declared using one of the following +// macros: +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// (A non-static Mutex is defined/declared in the usual way). +class GTEST_API_ Mutex { + public: + enum MutexType { kStatic = 0, kDynamic = 1 }; + // We rely on kStaticMutex being 0 as it is to what the linker initializes + // type_ in static mutexes. critical_section_ will be initialized lazily + // in ThreadSafeLazyInit(). + enum StaticConstructorSelector { kStaticMutex = 0 }; + + // This constructor intentionally does nothing. It relies on type_ being + // statically initialized to 0 (effectively setting it to kStatic) and on + // ThreadSafeLazyInit() to lazily initialize the rest of the members. + explicit Mutex(StaticConstructorSelector /*dummy*/) {} + + Mutex(); + ~Mutex(); + + void Lock(); + + void Unlock(); + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld(); + + private: + // Initializes owner_thread_id_ and critical_section_ in static mutexes. + void ThreadSafeLazyInit(); + + // Per http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx, + // we assume that 0 is an invalid value for thread IDs. + unsigned int owner_thread_id_; + + // For static mutexes, we rely on these members being initialized to zeros + // by the linker. + MutexType type_; + long critical_section_init_phase_; // NOLINT + _RTL_CRITICAL_SECTION* critical_section_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + Mutex* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Base class for ValueHolder. Allows a caller to hold and delete a value +// without knowing its type. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Provides a way for a thread to send notifications to a ThreadLocal +// regardless of its parameter type. +class ThreadLocalBase { + public: + // Creates a new ValueHolder object holding a default value passed to + // this ThreadLocal's constructor and returns it. It is the caller's + // responsibility not to call this when the ThreadLocal instance already + // has a value on the current thread. + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0; + + protected: + ThreadLocalBase() {} + virtual ~ThreadLocalBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase); +}; + +// Maps a thread to a set of ThreadLocals that have values instantiated on that +// thread and notifies them when the thread exits. A ThreadLocal instance is +// expected to persist until all threads it has values on have terminated. +class GTEST_API_ ThreadLocalRegistry { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance); + + // Invoked when a ThreadLocal instance is destroyed. + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance); +}; + +class GTEST_API_ ThreadWithParamBase { + public: + void Join(); + + protected: + class Runnable { + public: + virtual ~Runnable() {} + virtual void Run() = 0; + }; + + ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start); + virtual ~ThreadWithParamBase(); + + private: + AutoHandle thread_; +}; + +// Helper class for testing Google Test's multi-threading constructs. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void UserThreadFunc(T); + + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) + : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) { + } + virtual ~ThreadWithParam() {} + + private: + class RunnableImpl : public Runnable { + public: + RunnableImpl(UserThreadFunc* func, T param) + : func_(func), + param_(param) { + } + virtual ~RunnableImpl() {} + virtual void Run() { + func_(param_); + } + + private: + UserThreadFunc* const func_; + const T param_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl); + }; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// Implements thread-local storage on Windows systems. +// +// // Thread 1 +// ThreadLocal tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// The users of a TheadLocal instance have to make sure that all but one +// threads (including the main one) using that instance have exited before +// destroying it. Otherwise, the per-thread objects managed for them by the +// ThreadLocal instance are not guaranteed to be destroyed on all platforms. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template +class ThreadLocal : public ThreadLocalBase { + public: + ThreadLocal() : default_() {} + explicit ThreadLocal(const T& value) : default_(value) {} + + ~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of T. Can be deleted via its base class without the caller + // knowing the type of T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + + T* GetOrCreateValue() const { + return static_cast( + ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer(); + } + + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const { + return new ValueHolder(default_); + } + + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# elif GTEST_HAS_PTHREAD + +// MutexBase and Mutex implement mutex on pthreads-based platforms. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + has_owner_ = true; + } + + // Releases this mutex. + void Unlock() { + // Since the lock is being released the owner_ field should no longer be + // considered valid. We don't protect writing to has_owner_ here, as it's + // the caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + has_owner_ = false; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + // has_owner_ indicates whether the owner_ field below contains a valid thread + // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All + // accesses to the owner_ field should be protected by a check of this field. + // An alternative might be to memset() owner_ to all zeros, but there's no + // guarantee that a zero'd pthread_t is necessarily invalid or even different + // from pthread_self(). + bool has_owner_; + pthread_t owner_; // The thread holding the mutex. +}; + +// Forward-declares a static mutex. +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +// The initialization list here does not explicitly initialize each field, +// instead relying on default initialization for the unspecified fields. In +// particular, the owner_ field (a pthread_t) is not explicitly initialized. +// This allows initialization to work whether pthread_t is a scalar or struct. +// The flag -Wmissing-field-initializers must not be specified for this to work. +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + has_owner_ = false; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +template +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# endif // OS detection + +#else // GTEST_IS_THREADSAFE + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void Lock() {} + void Unlock() {} + void AssertHeld() const {} +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +#endif // GTEST_IS_THREADSAFE + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +# define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +# define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template +struct bool_constant { + typedef bool_constant type; + static const bool value = bool_value; +}; +template const bool bool_constant::value; + +typedef bool_constant false_type; +typedef bool_constant true_type; + +template +struct is_pointer : public false_type {}; + +template +struct is_pointer : public true_type {}; + +template +struct IteratorTraits { + typedef typename Iterator::value_type value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_SEP_ "\\" +# define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +# define GTEST_PATH_SEP_ "/" +# define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// Utilities for char. + +// isspace(int ch) and friends accept an unsigned char or EOF. char +// may be signed, depending on the compiler (or compiler flags). +// Therefore we need to cast a char to unsigned char before calling +// isspace(), etc. + +inline bool IsAlpha(char ch) { + return isalpha(static_cast(ch)) != 0; +} +inline bool IsAlNum(char ch) { + return isalnum(static_cast(ch)) != 0; +} +inline bool IsDigit(char ch) { + return isdigit(static_cast(ch)) != 0; +} +inline bool IsLower(char ch) { + return islower(static_cast(ch)) != 0; +} +inline bool IsSpace(char ch) { + return isspace(static_cast(ch)) != 0; +} +inline bool IsUpper(char ch) { + return isupper(static_cast(ch)) != 0; +} +inline bool IsXDigit(char ch) { + return isxdigit(static_cast(ch)) != 0; +} +inline bool IsXDigit(wchar_t ch) { + const unsigned char low_byte = static_cast(ch); + return ch == low_byte && isxdigit(low_byte) != 0; +} + +inline char ToLower(char ch) { + return static_cast(tolower(static_cast(ch))); +} +inline char ToUpper(char ch) { + return static_cast(toupper(static_cast(ch))); +} + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +# ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +# else // !__BORLANDC__ +# if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +# else +inline int IsATTY(int fd) { return _isatty(fd); } +# endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +# endif // __BORLANDC__ + +# if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +# else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE | GTEST_OS_WINDOWS_RT + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +GTEST_DISABLE_MSC_WARNINGS_POP_() + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// MSVC "deprecates" snprintf and issues warnings wherever it is used. In +// order to avoid these warnings, we need to use _snprintf or _snprintf_s on +// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate +// function in order to achieve that. We use macro definition here because +// snprintf is a variadic function. +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE +// MSVC 2005 and above support variadic macros. +# define GTEST_SNPRINTF_(buffer, size, format, ...) \ + _snprintf_s(buffer, size, size, format, __VA_ARGS__) +#elif defined(_MSC_VER) +// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't +// complain about _snprintf. +# define GTEST_SNPRINTF_ _snprintf +#else +# define GTEST_SNPRINTF_ snprintf +#endif + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::std::string GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) + +// Thread annotations +#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +#define GTEST_LOCK_EXCLUDED_(locks) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + diff --git a/src/test/gtest/include/gtest/internal/gtest-string.h b/src/test/gtest/include/gtest/internal/gtest-string.h new file mode 100644 index 00000000..97f1a7fd --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-string.h @@ -0,0 +1,167 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by . +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +# include +#endif + +#include +#include + +#include "gtest/internal/gtest-port.h" + +namespace testing { +namespace internal { + +// String - an abstract class holding static string utilities. +class GTEST_API_ String { + public: + // Static utility methods + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static std::string ShowWideCString(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Returns true iff the given string ends with the given suffix, ignoring + // case. Any string is considered to end with an empty suffix. + static bool EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix); + + // Formats an int value as "%02d". + static std::string FormatIntWidth2(int value); // "%02d" for width == 2 + + // Formats an int value as "%X". + static std::string FormatHexInt(int value); + + // Formats a byte as "%02X". + static std::string FormatByte(unsigned char value); + + private: + String(); // Not meant to be instantiated. +}; // class String + +// Gets the content of the stringstream's buffer as an std::string. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-tuple.h b/src/test/gtest/include/gtest/internal/gtest-tuple.h new file mode 100644 index 00000000..e9b40534 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-tuple.h @@ -0,0 +1,1020 @@ +// This file was GENERATED by command: +// pump.py gtest-tuple.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + +// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict +// with our own definitions. Therefore using our own tuple does not work on +// those compilers. +#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */ +# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \ +GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers." +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple +#define GTEST_2_TUPLE_(T) tuple +#define GTEST_3_TUPLE_(T) tuple +#define GTEST_4_TUPLE_(T) tuple +#define GTEST_5_TUPLE_(T) tuple +#define GTEST_6_TUPLE_(T) tuple +#define GTEST_7_TUPLE_(T) tuple +#define GTEST_8_TUPLE_(T) tuple +#define GTEST_9_TUPLE_(T) tuple +#define GTEST_10_TUPLE_(T) tuple + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + +template +struct TupleElement { + typedef T0 type; +}; + +template +struct TupleElement { + typedef T1 type; +}; + +template +struct TupleElement { + typedef T2 type; +}; + +template +struct TupleElement { + typedef T3 type; +}; + +template +struct TupleElement { + typedef T4 type; +}; + +template +struct TupleElement { + typedef T5 type; +}; + +template +struct TupleElement { + typedef T6 type; +}; + +template +struct TupleElement { + typedef T7 type; +}; + +template +struct TupleElement { + typedef T8 type; +}; + +template +struct TupleElement { + typedef T9 type; +}; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template +class GTEST_1_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template +class GTEST_2_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template +class GTEST_3_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template +class GTEST_4_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template +class GTEST_5_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template +class GTEST_6_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template +class GTEST_7_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template +class GTEST_8_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template +class GTEST_9_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template +class tuple { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + +template +struct tuple_size { + static const int value = 0; +}; + +template +struct tuple_size { + static const int value = 1; +}; + +template +struct tuple_size { + static const int value = 2; +}; + +template +struct tuple_size { + static const int value = 3; +}; + +template +struct tuple_size { + static const int value = 4; +}; + +template +struct tuple_size { + static const int value = 5; +}; + +template +struct tuple_size { + static const int value = 6; +}; + +template +struct tuple_size { + static const int value = 7; +}; + +template +struct tuple_size { + static const int value = 8; +}; + +template +struct tuple_size { + static const int value = 9; +}; + +template +struct tuple_size { + static const int value = 10; +}; + +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-tuple.h.pump b/src/test/gtest/include/gtest/internal/gtest-tuple.h.pump new file mode 100644 index 00000000..429ddfee --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-tuple.h.pump @@ -0,0 +1,347 @@ +$$ -*- mode: c++; -*- +$var n = 10 $$ Maximum number of tuple fields we want to support. +$$ This meta comment fixes auto-indentation in Emacs. }} +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + +// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict +// with our own definitions. Therefore using our own tuple does not work on +// those compilers. +#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */ +# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \ +GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers." +#endif + + +$range i 0..n-1 +$range j 0..n +$range k 1..n +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> + +$for k [[ +$range m 0..k-1 +$range m2 k..n-1 +#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> + +]] + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. + +$for j [[ +$range m 0..j-1 +#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] + + +]] + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template <$for i, [[typename T$i = void]]> +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + + +$for i [[ +template +struct TupleElement { + typedef T$i type; +}; + + +]] +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + + +$for k [[ +$range m 0..k-1 +template +class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { + public: + template friend class gtest_internal::Get; + + tuple() : $for m, [[f$(m)_()]] {} + + explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] +$for m, [[f$(m)_(f$m)]] {} + + tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} + + template + tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} + +$if k == 2 [[ + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + +]] + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { + return CopyFrom(t); + } + +$if k == 2 [[ + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + +]] + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { + +$for m [[ + f$(m)_ = t.f$(m)_; + +]] + return *this; + } + + +$for m [[ + T$m f$(m)_; + +]] +}; + + +]] +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +$for k [[ +$range m 0..k-1 + +template +inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { + return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); +} + +]] + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + + +$for j [[ +template +struct tuple_size { + static const int value = $j; +}; + + +]] +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + + +$for i [[ +template <> +class Get<$i> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) + Field(Tuple& t) { return t.f$(i)_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) + ConstField(const Tuple& t) { return t.f$(i)_; } +}; + + +]] +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) +get(GTEST_$(n)_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) +get(const GTEST_$(n)_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, + const GTEST_$(n)_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, + const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + + +$for j [[ +#undef GTEST_$(j)_TUPLE_ + +]] + + +$for j [[ +#undef GTEST_$(j)_TYPENAMES_ + +]] + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-type-util.h b/src/test/gtest/include/gtest/internal/gtest-type-util.h new file mode 100644 index 00000000..e46f7cfc --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-type-util.h @@ -0,0 +1,3331 @@ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template +struct Types2 { + typedef T1 Head; + typedef Types1 Tail; +}; + +template +struct Types3 { + typedef T1 Head; + typedef Types2 Tail; +}; + +template +struct Types4 { + typedef T1 Head; + typedef Types3 Tail; +}; + +template +struct Types5 { + typedef T1 Head; + typedef Types4 Tail; +}; + +template +struct Types6 { + typedef T1 Head; + typedef Types5 Tail; +}; + +template +struct Types7 { + typedef T1 Head; + typedef Types6 Tail; +}; + +template +struct Types8 { + typedef T1 Head; + typedef Types7 Tail; +}; + +template +struct Types9 { + typedef T1 Head; + typedef Types8 Tail; +}; + +template +struct Types10 { + typedef T1 Head; + typedef Types9 Tail; +}; + +template +struct Types11 { + typedef T1 Head; + typedef Types10 Tail; +}; + +template +struct Types12 { + typedef T1 Head; + typedef Types11 Tail; +}; + +template +struct Types13 { + typedef T1 Head; + typedef Types12 Tail; +}; + +template +struct Types14 { + typedef T1 Head; + typedef Types13 Tail; +}; + +template +struct Types15 { + typedef T1 Head; + typedef Types14 Tail; +}; + +template +struct Types16 { + typedef T1 Head; + typedef Types15 Tail; +}; + +template +struct Types17 { + typedef T1 Head; + typedef Types16 Tail; +}; + +template +struct Types18 { + typedef T1 Head; + typedef Types17 Tail; +}; + +template +struct Types19 { + typedef T1 Head; + typedef Types18 Tail; +}; + +template +struct Types20 { + typedef T1 Head; + typedef Types19 Tail; +}; + +template +struct Types21 { + typedef T1 Head; + typedef Types20 Tail; +}; + +template +struct Types22 { + typedef T1 Head; + typedef Types21 Tail; +}; + +template +struct Types23 { + typedef T1 Head; + typedef Types22 Tail; +}; + +template +struct Types24 { + typedef T1 Head; + typedef Types23 Tail; +}; + +template +struct Types25 { + typedef T1 Head; + typedef Types24 Tail; +}; + +template +struct Types26 { + typedef T1 Head; + typedef Types25 Tail; +}; + +template +struct Types27 { + typedef T1 Head; + typedef Types26 Tail; +}; + +template +struct Types28 { + typedef T1 Head; + typedef Types27 Tail; +}; + +template +struct Types29 { + typedef T1 Head; + typedef Types28 Tail; +}; + +template +struct Types30 { + typedef T1 Head; + typedef Types29 Tail; +}; + +template +struct Types31 { + typedef T1 Head; + typedef Types30 Tail; +}; + +template +struct Types32 { + typedef T1 Head; + typedef Types31 Tail; +}; + +template +struct Types33 { + typedef T1 Head; + typedef Types32 Tail; +}; + +template +struct Types34 { + typedef T1 Head; + typedef Types33 Tail; +}; + +template +struct Types35 { + typedef T1 Head; + typedef Types34 Tail; +}; + +template +struct Types36 { + typedef T1 Head; + typedef Types35 Tail; +}; + +template +struct Types37 { + typedef T1 Head; + typedef Types36 Tail; +}; + +template +struct Types38 { + typedef T1 Head; + typedef Types37 Tail; +}; + +template +struct Types39 { + typedef T1 Head; + typedef Types38 Tail; +}; + +template +struct Types40 { + typedef T1 Head; + typedef Types39 Tail; +}; + +template +struct Types41 { + typedef T1 Head; + typedef Types40 Tail; +}; + +template +struct Types42 { + typedef T1 Head; + typedef Types41 Tail; +}; + +template +struct Types43 { + typedef T1 Head; + typedef Types42 Tail; +}; + +template +struct Types44 { + typedef T1 Head; + typedef Types43 Tail; +}; + +template +struct Types45 { + typedef T1 Head; + typedef Types44 Tail; +}; + +template +struct Types46 { + typedef T1 Head; + typedef Types45 Tail; +}; + +template +struct Types47 { + typedef T1 Head; + typedef Types46 Tail; +}; + +template +struct Types48 { + typedef T1 Head; + typedef Types47 Tail; +}; + +template +struct Types49 { + typedef T1 Head; + typedef Types48 Tail; +}; + +template +struct Types50 { + typedef T1 Head; + typedef Types49 Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template +struct Types { + typedef internal::Types50 type; +}; + +template <> +struct Types { + typedef internal::Types0 type; +}; +template +struct Types { + typedef internal::Types1 type; +}; +template +struct Types { + typedef internal::Types2 type; +}; +template +struct Types { + typedef internal::Types3 type; +}; +template +struct Types { + typedef internal::Types4 type; +}; +template +struct Types { + typedef internal::Types5 type; +}; +template +struct Types { + typedef internal::Types6 type; +}; +template +struct Types { + typedef internal::Types7 type; +}; +template +struct Types { + typedef internal::Types8 type; +}; +template +struct Types { + typedef internal::Types9 type; +}; +template +struct Types { + typedef internal::Types10 type; +}; +template +struct Types { + typedef internal::Types11 type; +}; +template +struct Types { + typedef internal::Types12 type; +}; +template +struct Types { + typedef internal::Types13 type; +}; +template +struct Types { + typedef internal::Types14 type; +}; +template +struct Types { + typedef internal::Types15 type; +}; +template +struct Types { + typedef internal::Types16 type; +}; +template +struct Types { + typedef internal::Types17 type; +}; +template +struct Types { + typedef internal::Types18 type; +}; +template +struct Types { + typedef internal::Types19 type; +}; +template +struct Types { + typedef internal::Types20 type; +}; +template +struct Types { + typedef internal::Types21 type; +}; +template +struct Types { + typedef internal::Types22 type; +}; +template +struct Types { + typedef internal::Types23 type; +}; +template +struct Types { + typedef internal::Types24 type; +}; +template +struct Types { + typedef internal::Types25 type; +}; +template +struct Types { + typedef internal::Types26 type; +}; +template +struct Types { + typedef internal::Types27 type; +}; +template +struct Types { + typedef internal::Types28 type; +}; +template +struct Types { + typedef internal::Types29 type; +}; +template +struct Types { + typedef internal::Types30 type; +}; +template +struct Types { + typedef internal::Types31 type; +}; +template +struct Types { + typedef internal::Types32 type; +}; +template +struct Types { + typedef internal::Types33 type; +}; +template +struct Types { + typedef internal::Types34 type; +}; +template +struct Types { + typedef internal::Types35 type; +}; +template +struct Types { + typedef internal::Types36 type; +}; +template +struct Types { + typedef internal::Types37 type; +}; +template +struct Types { + typedef internal::Types38 type; +}; +template +struct Types { + typedef internal::Types39 type; +}; +template +struct Types { + typedef internal::Types40 type; +}; +template +struct Types { + typedef internal::Types41 type; +}; +template +struct Types { + typedef internal::Types42 type; +}; +template +struct Types { + typedef internal::Types43 type; +}; +template +struct Types { + typedef internal::Types44 type; +}; +template +struct Types { + typedef internal::Types45 type; +}; +template +struct Types { + typedef internal::Types46 type; +}; +template +struct Types { + typedef internal::Types47 type; +}; +template +struct Types { + typedef internal::Types48 type; +}; +template +struct Types { + typedef internal::Types49 type; +}; + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; +template +struct Templates2 { + typedef TemplateSel Head; + typedef Templates1 Tail; +}; + +template +struct Templates3 { + typedef TemplateSel Head; + typedef Templates2 Tail; +}; + +template +struct Templates4 { + typedef TemplateSel Head; + typedef Templates3 Tail; +}; + +template +struct Templates5 { + typedef TemplateSel Head; + typedef Templates4 Tail; +}; + +template +struct Templates6 { + typedef TemplateSel Head; + typedef Templates5 Tail; +}; + +template +struct Templates7 { + typedef TemplateSel Head; + typedef Templates6 Tail; +}; + +template +struct Templates8 { + typedef TemplateSel Head; + typedef Templates7 Tail; +}; + +template +struct Templates9 { + typedef TemplateSel Head; + typedef Templates8 Tail; +}; + +template +struct Templates10 { + typedef TemplateSel Head; + typedef Templates9 Tail; +}; + +template +struct Templates11 { + typedef TemplateSel Head; + typedef Templates10 Tail; +}; + +template +struct Templates12 { + typedef TemplateSel Head; + typedef Templates11 Tail; +}; + +template +struct Templates13 { + typedef TemplateSel Head; + typedef Templates12 Tail; +}; + +template +struct Templates14 { + typedef TemplateSel Head; + typedef Templates13 Tail; +}; + +template +struct Templates15 { + typedef TemplateSel Head; + typedef Templates14 Tail; +}; + +template +struct Templates16 { + typedef TemplateSel Head; + typedef Templates15 Tail; +}; + +template +struct Templates17 { + typedef TemplateSel Head; + typedef Templates16 Tail; +}; + +template +struct Templates18 { + typedef TemplateSel Head; + typedef Templates17 Tail; +}; + +template +struct Templates19 { + typedef TemplateSel Head; + typedef Templates18 Tail; +}; + +template +struct Templates20 { + typedef TemplateSel Head; + typedef Templates19 Tail; +}; + +template +struct Templates21 { + typedef TemplateSel Head; + typedef Templates20 Tail; +}; + +template +struct Templates22 { + typedef TemplateSel Head; + typedef Templates21 Tail; +}; + +template +struct Templates23 { + typedef TemplateSel Head; + typedef Templates22 Tail; +}; + +template +struct Templates24 { + typedef TemplateSel Head; + typedef Templates23 Tail; +}; + +template +struct Templates25 { + typedef TemplateSel Head; + typedef Templates24 Tail; +}; + +template +struct Templates26 { + typedef TemplateSel Head; + typedef Templates25 Tail; +}; + +template +struct Templates27 { + typedef TemplateSel Head; + typedef Templates26 Tail; +}; + +template +struct Templates28 { + typedef TemplateSel Head; + typedef Templates27 Tail; +}; + +template +struct Templates29 { + typedef TemplateSel Head; + typedef Templates28 Tail; +}; + +template +struct Templates30 { + typedef TemplateSel Head; + typedef Templates29 Tail; +}; + +template +struct Templates31 { + typedef TemplateSel Head; + typedef Templates30 Tail; +}; + +template +struct Templates32 { + typedef TemplateSel Head; + typedef Templates31 Tail; +}; + +template +struct Templates33 { + typedef TemplateSel Head; + typedef Templates32 Tail; +}; + +template +struct Templates34 { + typedef TemplateSel Head; + typedef Templates33 Tail; +}; + +template +struct Templates35 { + typedef TemplateSel Head; + typedef Templates34 Tail; +}; + +template +struct Templates36 { + typedef TemplateSel Head; + typedef Templates35 Tail; +}; + +template +struct Templates37 { + typedef TemplateSel Head; + typedef Templates36 Tail; +}; + +template +struct Templates38 { + typedef TemplateSel Head; + typedef Templates37 Tail; +}; + +template +struct Templates39 { + typedef TemplateSel Head; + typedef Templates38 Tail; +}; + +template +struct Templates40 { + typedef TemplateSel Head; + typedef Templates39 Tail; +}; + +template +struct Templates41 { + typedef TemplateSel Head; + typedef Templates40 Tail; +}; + +template +struct Templates42 { + typedef TemplateSel Head; + typedef Templates41 Tail; +}; + +template +struct Templates43 { + typedef TemplateSel Head; + typedef Templates42 Tail; +}; + +template +struct Templates44 { + typedef TemplateSel Head; + typedef Templates43 Tail; +}; + +template +struct Templates45 { + typedef TemplateSel Head; + typedef Templates44 Tail; +}; + +template +struct Templates46 { + typedef TemplateSel Head; + typedef Templates45 Tail; +}; + +template +struct Templates47 { + typedef TemplateSel Head; + typedef Templates46 Tail; +}; + +template +struct Templates48 { + typedef TemplateSel Head; + typedef Templates47 Tail; +}; + +template +struct Templates49 { + typedef TemplateSel Head; + typedef Templates48 Tail; +}; + +template +struct Templates50 { + typedef TemplateSel Head; + typedef Templates49 Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template +struct Templates { + typedef Templates50 type; +}; + +template <> +struct Templates { + typedef Templates0 type; +}; +template +struct Templates { + typedef Templates1 type; +}; +template +struct Templates { + typedef Templates2 type; +}; +template +struct Templates { + typedef Templates3 type; +}; +template +struct Templates { + typedef Templates4 type; +}; +template +struct Templates { + typedef Templates5 type; +}; +template +struct Templates { + typedef Templates6 type; +}; +template +struct Templates { + typedef Templates7 type; +}; +template +struct Templates { + typedef Templates8 type; +}; +template +struct Templates { + typedef Templates9 type; +}; +template +struct Templates { + typedef Templates10 type; +}; +template +struct Templates { + typedef Templates11 type; +}; +template +struct Templates { + typedef Templates12 type; +}; +template +struct Templates { + typedef Templates13 type; +}; +template +struct Templates { + typedef Templates14 type; +}; +template +struct Templates { + typedef Templates15 type; +}; +template +struct Templates { + typedef Templates16 type; +}; +template +struct Templates { + typedef Templates17 type; +}; +template +struct Templates { + typedef Templates18 type; +}; +template +struct Templates { + typedef Templates19 type; +}; +template +struct Templates { + typedef Templates20 type; +}; +template +struct Templates { + typedef Templates21 type; +}; +template +struct Templates { + typedef Templates22 type; +}; +template +struct Templates { + typedef Templates23 type; +}; +template +struct Templates { + typedef Templates24 type; +}; +template +struct Templates { + typedef Templates25 type; +}; +template +struct Templates { + typedef Templates26 type; +}; +template +struct Templates { + typedef Templates27 type; +}; +template +struct Templates { + typedef Templates28 type; +}; +template +struct Templates { + typedef Templates29 type; +}; +template +struct Templates { + typedef Templates30 type; +}; +template +struct Templates { + typedef Templates31 type; +}; +template +struct Templates { + typedef Templates32 type; +}; +template +struct Templates { + typedef Templates33 type; +}; +template +struct Templates { + typedef Templates34 type; +}; +template +struct Templates { + typedef Templates35 type; +}; +template +struct Templates { + typedef Templates36 type; +}; +template +struct Templates { + typedef Templates37 type; +}; +template +struct Templates { + typedef Templates38 type; +}; +template +struct Templates { + typedef Templates39 type; +}; +template +struct Templates { + typedef Templates40 type; +}; +template +struct Templates { + typedef Templates41 type; +}; +template +struct Templates { + typedef Templates42 type; +}; +template +struct Templates { + typedef Templates43 type; +}; +template +struct Templates { + typedef Templates44 type; +}; +template +struct Templates { + typedef Templates45 type; +}; +template +struct Templates { + typedef Templates46 type; +}; +template +struct Templates { + typedef Templates47 type; +}; +template +struct Templates { + typedef Templates48 type; +}; +template +struct Templates { + typedef Templates49 type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + +template +struct TypeList > { + typedef typename Types::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/src/test/gtest/include/gtest/internal/gtest-type-util.h.pump b/src/test/gtest/include/gtest/internal/gtest-type-util.h.pump new file mode 100644 index 00000000..251fdf02 --- /dev/null +++ b/src/test/gtest/include/gtest/internal/gtest-type-util.h.pump @@ -0,0 +1,297 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of type lists we want to support. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most $n types in a list, and at most $n +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[typename T$j]]> +struct Types$i { + typedef T1 Head; + typedef Types$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. + +$range i 1..n +template <$for i, [[typename T$i = internal::None]]> +struct Types { + typedef internal::Types$n<$for i, [[T$i]]> type; +}; + +template <> +struct Types<$for i, [[internal::None]]> { + typedef internal::Types0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[typename T$j]]> +struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { + typedef internal::Types$i<$for j, [[T$j]]> type; +}; + +]] + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates$i { + typedef TemplateSel Head; + typedef Templates$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. + +$range i 1..n +template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> +struct Templates { + typedef Templates$n<$for i, [[T$i]]> type; +}; + +template <> +struct Templates<$for i, [[NoneT]]> { + typedef Templates0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { + typedef Templates$i<$for j, [[T$j]]> type; +}; + +]] + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + + +$range i 1..n +template <$for i, [[typename T$i]]> +struct TypeList > { + typedef typename Types<$for i, [[T$i]]>::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/src/test/gtest/m4/acx_pthread.m4 b/src/test/gtest/m4/acx_pthread.m4 new file mode 100644 index 00000000..2cf20de1 --- /dev/null +++ b/src/test/gtest/m4/acx_pthread.m4 @@ -0,0 +1,363 @@ +# This was retrieved from +# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi +# See also (perhaps for new versions?) +# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi +# +# We've rewritten the inconsistency check code (from avahi), to work +# more broadly. In particular, it no longer assumes ld accepts -zdefs. +# This caused a restructing of the code, but the functionality has only +# changed a little. + +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +dnl +dnl @summary figure out how to build C programs using POSIX threads +dnl +dnl This macro figures out how to build C programs using POSIX threads. +dnl It sets the PTHREAD_LIBS output variable to the threads library and +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special +dnl C compiler flags that are needed. (The user can also force certain +dnl compiler flags/libs to be tested by setting these environment +dnl variables.) +dnl +dnl Also sets PTHREAD_CC to any special C compiler that is needed for +dnl multi-threaded programs (defaults to the value of CC otherwise). +dnl (This is necessary on AIX to use the special cc_r compiler alias.) +dnl +dnl NOTE: You are assumed to not only compile your program with these +dnl flags, but also link it with them as well. e.g. you should link +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS +dnl $LIBS +dnl +dnl If you are only building threads programs, you may wish to use +dnl these variables in your default LIBS, CFLAGS, and CC: +dnl +dnl LIBS="$PTHREAD_LIBS $LIBS" +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +dnl CC="$PTHREAD_CC" +dnl +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +dnl +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the +dnl default action will define HAVE_PTHREAD. +dnl +dnl Please let the authors know if this macro fails on any platform, or +dnl if you have any other suggestions or comments. This macro was based +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. +dnl We are also grateful for the helpful feedback of numerous users. +dnl +dnl @category InstalledPackages +dnl @author Steven G. Johnson +dnl @version 2006-05-29 +dnl @license GPLWithACException +dnl +dnl Checks for GCC shared/pthread inconsistency based on work by +dnl Marcin Owsiany + + +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi + + # The next part tries to detect GCC inconsistency with -shared on some + # architectures and systems. The problem is that in certain + # configurations, when -shared is specified, GCC "forgets" to + # internally use various flags which are still necessary. + + # + # Prepare the flags + # + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_CC="$CC" + + # Try with the flags determined by the earlier checks. + # + # -Wl,-z,defs forces link-time symbol resolution, so that the + # linking checks with -shared actually have any value + # + # FIXME: -fPIC is required for -shared on many architectures, + # so we specify it here, but the right way would probably be to + # properly detect whether it is actually required. + CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CC="$PTHREAD_CC" + + # In order not to create several levels of indentation, we test + # the value of "$done" until we find the cure or run out of ideas. + done="no" + + # First, make sure the CFLAGS we added are actually accepted by our + # compiler. If not (and OS X's ld, for instance, does not accept -z), + # then we can't do this test. + if test x"$done" = xno; then + AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies]) + AC_TRY_LINK(,, , [done=yes]) + + if test "x$done" = xyes ; then + AC_MSG_RESULT([no]) + else + AC_MSG_RESULT([yes]) + fi + fi + + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -pthread is sufficient with -shared]) + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi + + # + # Linux gcc on some architectures such as mips/mipsel forgets + # about -lpthread + # + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -lpthread fixes that]) + LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" + else + AC_MSG_RESULT([no]) + fi + fi + # + # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc + # + if test x"$done" = xno; then + AC_MSG_CHECKING([whether -lc_r fixes that]) + LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [done=yes]) + + if test "x$done" = xyes; then + AC_MSG_RESULT([yes]) + PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" + else + AC_MSG_RESULT([no]) + fi + fi + if test x"$done" = xno; then + # OK, we have run out of ideas + AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries]) + + # so it's not safe to assume that we may use pthreads + acx_pthread_ok=no + fi + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + CC="$save_CC" +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/src/test/gtest/m4/gtest.m4 b/src/test/gtest/m4/gtest.m4 new file mode 100644 index 00000000..6598ba75 --- /dev/null +++ b/src/test/gtest/m4/gtest.m4 @@ -0,0 +1,74 @@ +dnl GTEST_LIB_CHECK([minimum version [, +dnl action if found [,action if not found]]]) +dnl +dnl Check for the presence of the Google Test library, optionally at a minimum +dnl version, and indicate a viable version with the HAVE_GTEST flag. It defines +dnl standard variables for substitution including GTEST_CPPFLAGS, +dnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines +dnl GTEST_VERSION as the version of Google Test found. Finally, it provides +dnl optional custom action slots in the event GTEST is found or not. +AC_DEFUN([GTEST_LIB_CHECK], +[ +dnl Provide a flag to enable or disable Google Test usage. +AC_ARG_ENABLE([gtest], + [AS_HELP_STRING([--enable-gtest], + [Enable tests using the Google C++ Testing Framework. + (Default is enabled.)])], + [], + [enable_gtest=]) +AC_ARG_VAR([GTEST_CONFIG], + [The exact path of Google Test's 'gtest-config' script.]) +AC_ARG_VAR([GTEST_CPPFLAGS], + [C-like preprocessor flags for Google Test.]) +AC_ARG_VAR([GTEST_CXXFLAGS], + [C++ compile flags for Google Test.]) +AC_ARG_VAR([GTEST_LDFLAGS], + [Linker path and option flags for Google Test.]) +AC_ARG_VAR([GTEST_LIBS], + [Library linking flags for Google Test.]) +AC_ARG_VAR([GTEST_VERSION], + [The version of Google Test available.]) +HAVE_GTEST="no" +AS_IF([test "x${enable_gtest}" != "xno"], + [AC_MSG_CHECKING([for 'gtest-config']) + AS_IF([test "x${enable_gtest}" != "xyes"], + [AS_IF([test -x "${enable_gtest}/scripts/gtest-config"], + [GTEST_CONFIG="${enable_gtest}/scripts/gtest-config"], + [GTEST_CONFIG="${enable_gtest}/bin/gtest-config"]) + AS_IF([test -x "${GTEST_CONFIG}"], [], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([dnl +Unable to locate either a built or installed Google Test. +The specific location '${enable_gtest}' was provided for a built or installed +Google Test, but no 'gtest-config' script could be found at this location.]) + ])], + [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])]) + AS_IF([test -x "${GTEST_CONFIG}"], + [AC_MSG_RESULT([${GTEST_CONFIG}]) + m4_ifval([$1], + [_gtest_min_version="--min-version=$1" + AC_MSG_CHECKING([for Google Test at least version >= $1])], + [_gtest_min_version="--min-version=0" + AC_MSG_CHECKING([for Google Test])]) + AS_IF([${GTEST_CONFIG} ${_gtest_min_version}], + [AC_MSG_RESULT([yes]) + HAVE_GTEST='yes'], + [AC_MSG_RESULT([no])])], + [AC_MSG_RESULT([no])]) + AS_IF([test "x${HAVE_GTEST}" = "xyes"], + [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags` + GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags` + GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags` + GTEST_LIBS=`${GTEST_CONFIG} --libs` + GTEST_VERSION=`${GTEST_CONFIG} --version` + AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])], + [AS_IF([test "x${enable_gtest}" = "xyes"], + [AC_MSG_ERROR([dnl +Google Test was enabled, but no viable version could be found.]) + ])])]) +AC_SUBST([HAVE_GTEST]) +AM_CONDITIONAL([HAVE_GTEST],[test "x$HAVE_GTEST" = "xyes"]) +AS_IF([test "x$HAVE_GTEST" = "xyes"], + [m4_ifval([$2], [$2])], + [m4_ifval([$3], [$3])]) +]) diff --git a/src/test/gtest/msvc/gtest-md.sln b/src/test/gtest/msvc/gtest-md.sln new file mode 100644 index 00000000..f7908da1 --- /dev/null +++ b/src/test/gtest/msvc/gtest-md.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.Build.0 = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.ActiveCfg = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.Build.0 = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.ActiveCfg = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.Build.0 = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.ActiveCfg = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.Build.0 = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/test/gtest/msvc/gtest-md.vcproj b/src/test/gtest/msvc/gtest-md.vcproj new file mode 100644 index 00000000..1c35c3a5 --- /dev/null +++ b/src/test/gtest/msvc/gtest-md.vcproj @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/msvc/gtest.sln b/src/test/gtest/msvc/gtest.sln new file mode 100644 index 00000000..ef4b057f --- /dev/null +++ b/src/test/gtest/msvc/gtest.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_unittest.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.ActiveCfg = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.Build.0 = Debug|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.ActiveCfg = Release|Win32 + {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.Build.0 = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.ActiveCfg = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.Build.0 = Debug|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.ActiveCfg = Release|Win32 + {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.Build.0 = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.ActiveCfg = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0 = Debug|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg = Release|Win32 + {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0 = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0 = Debug|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg = Release|Win32 + {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/test/gtest/msvc/gtest.vcproj b/src/test/gtest/msvc/gtest.vcproj new file mode 100644 index 00000000..a8373ce9 --- /dev/null +++ b/src/test/gtest/msvc/gtest.vcproj @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/msvc/gtest_main-md.vcproj b/src/test/gtest/msvc/gtest_main-md.vcproj new file mode 100644 index 00000000..b5379fe6 --- /dev/null +++ b/src/test/gtest/msvc/gtest_main-md.vcproj @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/msvc/gtest_main.vcproj b/src/test/gtest/msvc/gtest_main.vcproj new file mode 100644 index 00000000..e8b763c5 --- /dev/null +++ b/src/test/gtest/msvc/gtest_main.vcproj @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/msvc/gtest_prod_test-md.vcproj b/src/test/gtest/msvc/gtest_prod_test-md.vcproj new file mode 100644 index 00000000..05b05d9e --- /dev/null +++ b/src/test/gtest/msvc/gtest_prod_test-md.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/msvc/gtest_prod_test.vcproj b/src/test/gtest/msvc/gtest_prod_test.vcproj new file mode 100644 index 00000000..6d7a2f02 --- /dev/null +++ b/src/test/gtest/msvc/gtest_prod_test.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/msvc/gtest_unittest-md.vcproj b/src/test/gtest/msvc/gtest_unittest-md.vcproj new file mode 100644 index 00000000..38a5e566 --- /dev/null +++ b/src/test/gtest/msvc/gtest_unittest-md.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/msvc/gtest_unittest.vcproj b/src/test/gtest/msvc/gtest_unittest.vcproj new file mode 100644 index 00000000..cb1f52b1 --- /dev/null +++ b/src/test/gtest/msvc/gtest_unittest.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/gtest/samples/prime_tables.h b/src/test/gtest/samples/prime_tables.h new file mode 100644 index 00000000..92ce16a0 --- /dev/null +++ b/src/test/gtest/samples/prime_tables.h @@ -0,0 +1,123 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// Author: vladl@google.com (Vlad Losev) + +// This provides interface PrimeTable that determines whether a number is a +// prime and determines a next prime number. This interface is used +// in Google Test samples demonstrating use of parameterized tests. + +#ifndef GTEST_SAMPLES_PRIME_TABLES_H_ +#define GTEST_SAMPLES_PRIME_TABLES_H_ + +#include + +// The prime table interface. +class PrimeTable { + public: + virtual ~PrimeTable() {} + + // Returns true iff n is a prime number. + virtual bool IsPrime(int n) const = 0; + + // Returns the smallest prime number greater than p; or returns -1 + // if the next prime is beyond the capacity of the table. + virtual int GetNextPrime(int p) const = 0; +}; + +// Implementation #1 calculates the primes on-the-fly. +class OnTheFlyPrimeTable : public PrimeTable { + public: + virtual bool IsPrime(int n) const { + if (n <= 1) return false; + + for (int i = 2; i*i <= n; i++) { + // n is divisible by an integer other than 1 and itself. + if ((n % i) == 0) return false; + } + + return true; + } + + virtual int GetNextPrime(int p) const { + for (int n = p + 1; n > 0; n++) { + if (IsPrime(n)) return n; + } + + return -1; + } +}; + +// Implementation #2 pre-calculates the primes and stores the result +// in an array. +class PreCalculatedPrimeTable : public PrimeTable { + public: + // 'max' specifies the maximum number the prime table holds. + explicit PreCalculatedPrimeTable(int max) + : is_prime_size_(max + 1), is_prime_(new bool[max + 1]) { + CalculatePrimesUpTo(max); + } + virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; } + + virtual bool IsPrime(int n) const { + return 0 <= n && n < is_prime_size_ && is_prime_[n]; + } + + virtual int GetNextPrime(int p) const { + for (int n = p + 1; n < is_prime_size_; n++) { + if (is_prime_[n]) return n; + } + + return -1; + } + + private: + void CalculatePrimesUpTo(int max) { + ::std::fill(is_prime_, is_prime_ + is_prime_size_, true); + is_prime_[0] = is_prime_[1] = false; + + for (int i = 2; i <= max; i++) { + if (!is_prime_[i]) continue; + + // Marks all multiples of i (except i itself) as non-prime. + for (int j = 2*i; j <= max; j += i) { + is_prime_[j] = false; + } + } + } + + const int is_prime_size_; + bool* const is_prime_; + + // Disables compiler warning "assignment operator could not be generated." + void operator=(const PreCalculatedPrimeTable& rhs); +}; + +#endif // GTEST_SAMPLES_PRIME_TABLES_H_ diff --git a/src/test/gtest/samples/sample1.cc b/src/test/gtest/samples/sample1.cc new file mode 100644 index 00000000..f171e260 --- /dev/null +++ b/src/test/gtest/samples/sample1.cc @@ -0,0 +1,68 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "sample1.h" + +// Returns n! (the factorial of n). For negative n, n! is defined to be 1. +int Factorial(int n) { + int result = 1; + for (int i = 1; i <= n; i++) { + result *= i; + } + + return result; +} + +// Returns true iff n is a prime number. +bool IsPrime(int n) { + // Trivial case 1: small numbers + if (n <= 1) return false; + + // Trivial case 2: even numbers + if (n % 2 == 0) return n == 2; + + // Now, we have that n is odd and n >= 3. + + // Try to divide n by every odd number i, starting from 3 + for (int i = 3; ; i += 2) { + // We only have to try i up to the squre root of n + if (i > n/i) break; + + // Now, we have i <= n/i < n. + // If n is divisible by i, n is not prime. + if (n % i == 0) return false; + } + + // n has no integer factor in the range (1, n), and thus is prime. + return true; +} diff --git a/src/test/gtest/samples/sample1.h b/src/test/gtest/samples/sample1.h new file mode 100644 index 00000000..3dfeb98c --- /dev/null +++ b/src/test/gtest/samples/sample1.h @@ -0,0 +1,43 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE1_H_ +#define GTEST_SAMPLES_SAMPLE1_H_ + +// Returns n! (the factorial of n). For negative n, n! is defined to be 1. +int Factorial(int n); + +// Returns true iff n is a prime number. +bool IsPrime(int n); + +#endif // GTEST_SAMPLES_SAMPLE1_H_ diff --git a/src/test/gtest/samples/sample10_unittest.cc b/src/test/gtest/samples/sample10_unittest.cc new file mode 100644 index 00000000..0051cd5d --- /dev/null +++ b/src/test/gtest/samples/sample10_unittest.cc @@ -0,0 +1,144 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to use Google Test listener API to implement +// a primitive leak checker. + +#include +#include + +#include "gtest/gtest.h" + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +namespace { + +// We will track memory used by this class. +class Water { + public: + // Normal Water declarations go here. + + // operator new and operator delete help us control water allocation. + void* operator new(size_t allocation_size) { + allocated_++; + return malloc(allocation_size); + } + + void operator delete(void* block, size_t /* allocation_size */) { + allocated_--; + free(block); + } + + static int allocated() { return allocated_; } + + private: + static int allocated_; +}; + +int Water::allocated_ = 0; + +// This event listener monitors how many Water objects are created and +// destroyed by each test, and reports a failure if a test leaks some Water +// objects. It does this by comparing the number of live Water objects at +// the beginning of a test and at the end of a test. +class LeakChecker : public EmptyTestEventListener { + private: + // Called before a test starts. + virtual void OnTestStart(const TestInfo& /* test_info */) { + initially_allocated_ = Water::allocated(); + } + + // Called after a test ends. + virtual void OnTestEnd(const TestInfo& /* test_info */) { + int difference = Water::allocated() - initially_allocated_; + + // You can generate a failure in any event handler except + // OnTestPartResult. Just use an appropriate Google Test assertion to do + // it. + EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!"; + } + + int initially_allocated_; +}; + +TEST(ListenersTest, DoesNotLeak) { + Water* water = new Water; + delete water; +} + +// This should fail when the --check_for_leaks command line flag is +// specified. +TEST(ListenersTest, LeaksWater) { + Water* water = new Water; + EXPECT_TRUE(water != NULL); +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool check_for_leaks = false; + if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 ) + check_for_leaks = true; + else + printf("%s\n", "Run this program with --check_for_leaks to enable " + "custom leak checking in the tests."); + + // If we are given the --check_for_leaks command line flag, installs the + // leak checker. + if (check_for_leaks) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + + // Adds the leak checker to the end of the test event listener list, + // after the default text output printer and the default XML report + // generator. + // + // The order is important - it ensures that failures generated in the + // leak checker's OnTestEnd() method are processed by the text and XML + // printers *before* their OnTestEnd() methods are called, such that + // they are attributed to the right test. Remember that a listener + // receives an OnXyzStart event *after* listeners preceding it in the + // list received that event, and receives an OnXyzEnd event *before* + // listeners preceding it. + // + // We don't need to worry about deleting the new listener later, as + // Google Test will do it. + listeners.Append(new LeakChecker); + } + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/samples/sample1_unittest.cc b/src/test/gtest/samples/sample1_unittest.cc new file mode 100644 index 00000000..aefc4f1d --- /dev/null +++ b/src/test/gtest/samples/sample1_unittest.cc @@ -0,0 +1,153 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + + +// This sample shows how to write a simple unit test for a function, +// using Google C++ testing framework. +// +// Writing a unit test using Google C++ testing framework is easy as 1-2-3: + + +// Step 1. Include necessary header files such that the stuff your +// test logic needs is declared. +// +// Don't forget gtest.h, which declares the testing framework. + +#include +#include "sample1.h" +#include "gtest/gtest.h" + + +// Step 2. Use the TEST macro to define your tests. +// +// TEST has two parameters: the test case name and the test name. +// After using the macro, you should define your test logic between a +// pair of braces. You can use a bunch of macros to indicate the +// success or failure of a test. EXPECT_TRUE and EXPECT_EQ are +// examples of such macros. For a complete list, see gtest.h. +// +// +// +// In Google Test, tests are grouped into test cases. This is how we +// keep test code organized. You should put logically related tests +// into the same test case. +// +// The test case name and the test name should both be valid C++ +// identifiers. And you should not use underscore (_) in the names. +// +// Google Test guarantees that each test you define is run exactly +// once, but it makes no guarantee on the order the tests are +// executed. Therefore, you should write your tests in such a way +// that their results don't depend on their order. +// +// + + +// Tests Factorial(). + +// Tests factorial of negative numbers. +TEST(FactorialTest, Negative) { + // This test is named "Negative", and belongs to the "FactorialTest" + // test case. + EXPECT_EQ(1, Factorial(-5)); + EXPECT_EQ(1, Factorial(-1)); + EXPECT_GT(Factorial(-10), 0); + + // + // + // EXPECT_EQ(expected, actual) is the same as + // + // EXPECT_TRUE((expected) == (actual)) + // + // except that it will print both the expected value and the actual + // value when the assertion fails. This is very helpful for + // debugging. Therefore in this case EXPECT_EQ is preferred. + // + // On the other hand, EXPECT_TRUE accepts any Boolean expression, + // and is thus more general. + // + // +} + +// Tests factorial of 0. +TEST(FactorialTest, Zero) { + EXPECT_EQ(1, Factorial(0)); +} + +// Tests factorial of positive numbers. +TEST(FactorialTest, Positive) { + EXPECT_EQ(1, Factorial(1)); + EXPECT_EQ(2, Factorial(2)); + EXPECT_EQ(6, Factorial(3)); + EXPECT_EQ(40320, Factorial(8)); +} + + +// Tests IsPrime() + +// Tests negative input. +TEST(IsPrimeTest, Negative) { + // This test belongs to the IsPrimeTest test case. + + EXPECT_FALSE(IsPrime(-1)); + EXPECT_FALSE(IsPrime(-2)); + EXPECT_FALSE(IsPrime(INT_MIN)); +} + +// Tests some trivial cases. +TEST(IsPrimeTest, Trivial) { + EXPECT_FALSE(IsPrime(0)); + EXPECT_FALSE(IsPrime(1)); + EXPECT_TRUE(IsPrime(2)); + EXPECT_TRUE(IsPrime(3)); +} + +// Tests positive input. +TEST(IsPrimeTest, Positive) { + EXPECT_FALSE(IsPrime(4)); + EXPECT_TRUE(IsPrime(5)); + EXPECT_FALSE(IsPrime(6)); + EXPECT_TRUE(IsPrime(23)); +} + +// Step 3. Call RUN_ALL_TESTS() in main(). +// +// We do this by linking in src/gtest_main.cc file, which consists of +// a main() function which calls RUN_ALL_TESTS() for us. +// +// This runs all the tests you've defined, prints the result, and +// returns 0 if successful, or 1 otherwise. +// +// Did you notice that we didn't register the tests? The +// RUN_ALL_TESTS() macro magically knows about all the tests we +// defined. Isn't this convenient? diff --git a/src/test/gtest/samples/sample2.cc b/src/test/gtest/samples/sample2.cc new file mode 100644 index 00000000..5f763b9b --- /dev/null +++ b/src/test/gtest/samples/sample2.cc @@ -0,0 +1,56 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "sample2.h" + +#include + +// Clones a 0-terminated C string, allocating memory using new. +const char* MyString::CloneCString(const char* a_c_string) { + if (a_c_string == NULL) return NULL; + + const size_t len = strlen(a_c_string); + char* const clone = new char[ len + 1 ]; + memcpy(clone, a_c_string, len + 1); + + return clone; +} + +// Sets the 0-terminated C string this MyString object +// represents. +void MyString::Set(const char* a_c_string) { + // Makes sure this works when c_string == c_string_ + const char* const temp = MyString::CloneCString(a_c_string); + delete[] c_string_; + c_string_ = temp; +} diff --git a/src/test/gtest/samples/sample2.h b/src/test/gtest/samples/sample2.h new file mode 100644 index 00000000..cb485c70 --- /dev/null +++ b/src/test/gtest/samples/sample2.h @@ -0,0 +1,85 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE2_H_ +#define GTEST_SAMPLES_SAMPLE2_H_ + +#include + + +// A simple string class. +class MyString { + private: + const char* c_string_; + const MyString& operator=(const MyString& rhs); + + public: + // Clones a 0-terminated C string, allocating memory using new. + static const char* CloneCString(const char* a_c_string); + + //////////////////////////////////////////////////////////// + // + // C'tors + + // The default c'tor constructs a NULL string. + MyString() : c_string_(NULL) {} + + // Constructs a MyString by cloning a 0-terminated C string. + explicit MyString(const char* a_c_string) : c_string_(NULL) { + Set(a_c_string); + } + + // Copy c'tor + MyString(const MyString& string) : c_string_(NULL) { + Set(string.c_string_); + } + + //////////////////////////////////////////////////////////// + // + // D'tor. MyString is intended to be a final class, so the d'tor + // doesn't need to be virtual. + ~MyString() { delete[] c_string_; } + + // Gets the 0-terminated C string this MyString object represents. + const char* c_string() const { return c_string_; } + + size_t Length() const { + return c_string_ == NULL ? 0 : strlen(c_string_); + } + + // Sets the 0-terminated C string this MyString object represents. + void Set(const char* c_string); +}; + + +#endif // GTEST_SAMPLES_SAMPLE2_H_ diff --git a/src/test/gtest/samples/sample2_unittest.cc b/src/test/gtest/samples/sample2_unittest.cc new file mode 100644 index 00000000..4fa19b71 --- /dev/null +++ b/src/test/gtest/samples/sample2_unittest.cc @@ -0,0 +1,109 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + + +// This sample shows how to write a more complex unit test for a class +// that has multiple member functions. +// +// Usually, it's a good idea to have one test for each method in your +// class. You don't have to do that exactly, but it helps to keep +// your tests organized. You may also throw in additional tests as +// needed. + +#include "sample2.h" +#include "gtest/gtest.h" + +// In this example, we test the MyString class (a simple string). + +// Tests the default c'tor. +TEST(MyString, DefaultConstructor) { + const MyString s; + + // Asserts that s.c_string() returns NULL. + // + // + // + // If we write NULL instead of + // + // static_cast(NULL) + // + // in this assertion, it will generate a warning on gcc 3.4. The + // reason is that EXPECT_EQ needs to know the types of its + // arguments in order to print them when it fails. Since NULL is + // #defined as 0, the compiler will use the formatter function for + // int to print it. However, gcc thinks that NULL should be used as + // a pointer, not an int, and therefore complains. + // + // The root of the problem is C++'s lack of distinction between the + // integer number 0 and the null pointer constant. Unfortunately, + // we have to live with this fact. + // + // + EXPECT_STREQ(NULL, s.c_string()); + + EXPECT_EQ(0u, s.Length()); +} + +const char kHelloString[] = "Hello, world!"; + +// Tests the c'tor that accepts a C string. +TEST(MyString, ConstructorFromCString) { + const MyString s(kHelloString); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1, + s.Length()); +} + +// Tests the copy c'tor. +TEST(MyString, CopyConstructor) { + const MyString s1(kHelloString); + const MyString s2 = s1; + EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString)); +} + +// Tests the Set method. +TEST(MyString, Set) { + MyString s; + + s.Set(kHelloString); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + + // Set should work when the input pointer is the same as the one + // already in the MyString object. + s.Set(s.c_string()); + EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); + + // Can we set the MyString to NULL? + s.Set(NULL); + EXPECT_STREQ(NULL, s.c_string()); +} diff --git a/src/test/gtest/samples/sample3-inl.h b/src/test/gtest/samples/sample3-inl.h new file mode 100644 index 00000000..7e3084d6 --- /dev/null +++ b/src/test/gtest/samples/sample3-inl.h @@ -0,0 +1,172 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_ +#define GTEST_SAMPLES_SAMPLE3_INL_H_ + +#include + + +// Queue is a simple queue implemented as a singled-linked list. +// +// The element type must support copy constructor. +template // E is the element type +class Queue; + +// QueueNode is a node in a Queue, which consists of an element of +// type E and a pointer to the next node. +template // E is the element type +class QueueNode { + friend class Queue; + + public: + // Gets the element in this node. + const E& element() const { return element_; } + + // Gets the next node in the queue. + QueueNode* next() { return next_; } + const QueueNode* next() const { return next_; } + + private: + // Creates a node with a given element value. The next pointer is + // set to NULL. + explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} + + // We disable the default assignment operator and copy c'tor. + const QueueNode& operator = (const QueueNode&); + QueueNode(const QueueNode&); + + E element_; + QueueNode* next_; +}; + +template // E is the element type. +class Queue { + public: + // Creates an empty queue. + Queue() : head_(NULL), last_(NULL), size_(0) {} + + // D'tor. Clears the queue. + ~Queue() { Clear(); } + + // Clears the queue. + void Clear() { + if (size_ > 0) { + // 1. Deletes every node. + QueueNode* node = head_; + QueueNode* next = node->next(); + for (; ;) { + delete node; + node = next; + if (node == NULL) break; + next = node->next(); + } + + // 2. Resets the member variables. + head_ = last_ = NULL; + size_ = 0; + } + } + + // Gets the number of elements. + size_t Size() const { return size_; } + + // Gets the first element of the queue, or NULL if the queue is empty. + QueueNode* Head() { return head_; } + const QueueNode* Head() const { return head_; } + + // Gets the last element of the queue, or NULL if the queue is empty. + QueueNode* Last() { return last_; } + const QueueNode* Last() const { return last_; } + + // Adds an element to the end of the queue. A copy of the element is + // created using the copy constructor, and then stored in the queue. + // Changes made to the element in the queue doesn't affect the source + // object, and vice versa. + void Enqueue(const E& element) { + QueueNode* new_node = new QueueNode(element); + + if (size_ == 0) { + head_ = last_ = new_node; + size_ = 1; + } else { + last_->next_ = new_node; + last_ = new_node; + size_++; + } + } + + // Removes the head of the queue and returns it. Returns NULL if + // the queue is empty. + E* Dequeue() { + if (size_ == 0) { + return NULL; + } + + const QueueNode* const old_head = head_; + head_ = head_->next_; + size_--; + if (size_ == 0) { + last_ = NULL; + } + + E* element = new E(old_head->element()); + delete old_head; + + return element; + } + + // Applies a function/functor on each element of the queue, and + // returns the result in a new queue. The original queue is not + // affected. + template + Queue* Map(F function) const { + Queue* new_queue = new Queue(); + for (const QueueNode* node = head_; node != NULL; node = node->next_) { + new_queue->Enqueue(function(node->element())); + } + + return new_queue; + } + + private: + QueueNode* head_; // The first node of the queue. + QueueNode* last_; // The last node of the queue. + size_t size_; // The number of elements in the queue. + + // We disallow copying a queue. + Queue(const Queue&); + const Queue& operator = (const Queue&); +}; + +#endif // GTEST_SAMPLES_SAMPLE3_INL_H_ diff --git a/src/test/gtest/samples/sample3_unittest.cc b/src/test/gtest/samples/sample3_unittest.cc new file mode 100644 index 00000000..bf3877d0 --- /dev/null +++ b/src/test/gtest/samples/sample3_unittest.cc @@ -0,0 +1,151 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + + +// In this example, we use a more advanced feature of Google Test called +// test fixture. +// +// A test fixture is a place to hold objects and functions shared by +// all tests in a test case. Using a test fixture avoids duplicating +// the test code necessary to initialize and cleanup those common +// objects for each test. It is also useful for defining sub-routines +// that your tests need to invoke a lot. +// +// +// +// The tests share the test fixture in the sense of code sharing, not +// data sharing. Each test is given its own fresh copy of the +// fixture. You cannot expect the data modified by one test to be +// passed on to another test, which is a bad idea. +// +// The reason for this design is that tests should be independent and +// repeatable. In particular, a test should not fail as the result of +// another test's failure. If one test depends on info produced by +// another test, then the two tests should really be one big test. +// +// The macros for indicating the success/failure of a test +// (EXPECT_TRUE, FAIL, etc) need to know what the current test is +// (when Google Test prints the test result, it tells you which test +// each failure belongs to). Technically, these macros invoke a +// member function of the Test class. Therefore, you cannot use them +// in a global function. That's why you should put test sub-routines +// in a test fixture. +// +// + +#include "sample3-inl.h" +#include "gtest/gtest.h" + +// To use a test fixture, derive a class from testing::Test. +class QueueTest : public testing::Test { + protected: // You should make the members protected s.t. they can be + // accessed from sub-classes. + + // virtual void SetUp() will be called before each test is run. You + // should define it if you need to initialize the varaibles. + // Otherwise, this can be skipped. + virtual void SetUp() { + q1_.Enqueue(1); + q2_.Enqueue(2); + q2_.Enqueue(3); + } + + // virtual void TearDown() will be called after each test is run. + // You should define it if there is cleanup work to do. Otherwise, + // you don't have to provide it. + // + // virtual void TearDown() { + // } + + // A helper function that some test uses. + static int Double(int n) { + return 2*n; + } + + // A helper function for testing Queue::Map(). + void MapTester(const Queue * q) { + // Creates a new queue, where each element is twice as big as the + // corresponding one in q. + const Queue * const new_q = q->Map(Double); + + // Verifies that the new queue has the same size as q. + ASSERT_EQ(q->Size(), new_q->Size()); + + // Verifies the relationship between the elements of the two queues. + for ( const QueueNode * n1 = q->Head(), * n2 = new_q->Head(); + n1 != NULL; n1 = n1->next(), n2 = n2->next() ) { + EXPECT_EQ(2 * n1->element(), n2->element()); + } + + delete new_q; + } + + // Declares the variables your tests want to use. + Queue q0_; + Queue q1_; + Queue q2_; +}; + +// When you have a test fixture, you define a test using TEST_F +// instead of TEST. + +// Tests the default c'tor. +TEST_F(QueueTest, DefaultConstructor) { + // You can access data in the test fixture here. + EXPECT_EQ(0u, q0_.Size()); +} + +// Tests Dequeue(). +TEST_F(QueueTest, Dequeue) { + int * n = q0_.Dequeue(); + EXPECT_TRUE(n == NULL); + + n = q1_.Dequeue(); + ASSERT_TRUE(n != NULL); + EXPECT_EQ(1, *n); + EXPECT_EQ(0u, q1_.Size()); + delete n; + + n = q2_.Dequeue(); + ASSERT_TRUE(n != NULL); + EXPECT_EQ(2, *n); + EXPECT_EQ(1u, q2_.Size()); + delete n; +} + +// Tests the Queue::Map() function. +TEST_F(QueueTest, Map) { + MapTester(&q0_); + MapTester(&q1_); + MapTester(&q2_); +} diff --git a/src/test/gtest/samples/sample4.cc b/src/test/gtest/samples/sample4.cc new file mode 100644 index 00000000..ae44bda6 --- /dev/null +++ b/src/test/gtest/samples/sample4.cc @@ -0,0 +1,46 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#include + +#include "sample4.h" + +// Returns the current counter value, and increments it. +int Counter::Increment() { + return counter_++; +} + +// Prints the current counter value to STDOUT. +void Counter::Print() const { + printf("%d", counter_); +} diff --git a/src/test/gtest/samples/sample4.h b/src/test/gtest/samples/sample4.h new file mode 100644 index 00000000..cd60f0dd --- /dev/null +++ b/src/test/gtest/samples/sample4.h @@ -0,0 +1,53 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// A sample program demonstrating using Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_SAMPLES_SAMPLE4_H_ +#define GTEST_SAMPLES_SAMPLE4_H_ + +// A simple monotonic counter. +class Counter { + private: + int counter_; + + public: + // Creates a counter that starts at 0. + Counter() : counter_(0) {} + + // Returns the current counter value, and increments it. + int Increment(); + + // Prints the current counter value to STDOUT. + void Print() const; +}; + +#endif // GTEST_SAMPLES_SAMPLE4_H_ diff --git a/src/test/gtest/samples/sample4_unittest.cc b/src/test/gtest/samples/sample4_unittest.cc new file mode 100644 index 00000000..fa5afc7d --- /dev/null +++ b/src/test/gtest/samples/sample4_unittest.cc @@ -0,0 +1,45 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" +#include "sample4.h" + +// Tests the Increment() method. +TEST(Counter, Increment) { + Counter c; + + // EXPECT_EQ() evaluates its arguments exactly once, so they + // can have side effects. + + EXPECT_EQ(0, c.Increment()); + EXPECT_EQ(1, c.Increment()); + EXPECT_EQ(2, c.Increment()); +} diff --git a/src/test/gtest/samples/sample5_unittest.cc b/src/test/gtest/samples/sample5_unittest.cc new file mode 100644 index 00000000..43d8e577 --- /dev/null +++ b/src/test/gtest/samples/sample5_unittest.cc @@ -0,0 +1,199 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This sample teaches how to reuse a test fixture in multiple test +// cases by deriving sub-fixtures from it. +// +// When you define a test fixture, you specify the name of the test +// case that will use this fixture. Therefore, a test fixture can +// be used by only one test case. +// +// Sometimes, more than one test cases may want to use the same or +// slightly different test fixtures. For example, you may want to +// make sure that all tests for a GUI library don't leak important +// system resources like fonts and brushes. In Google Test, you do +// this by putting the shared logic in a super (as in "super class") +// test fixture, and then have each test case use a fixture derived +// from this super fixture. + +#include +#include +#include "sample3-inl.h" +#include "gtest/gtest.h" +#include "sample1.h" + +// In this sample, we want to ensure that every test finishes within +// ~5 seconds. If a test takes longer to run, we consider it a +// failure. +// +// We put the code for timing a test in a test fixture called +// "QuickTest". QuickTest is intended to be the super fixture that +// other fixtures derive from, therefore there is no test case with +// the name "QuickTest". This is OK. +// +// Later, we will derive multiple test fixtures from QuickTest. +class QuickTest : public testing::Test { + protected: + // Remember that SetUp() is run immediately before a test starts. + // This is a good place to record the start time. + virtual void SetUp() { + start_time_ = time(NULL); + } + + // TearDown() is invoked immediately after a test finishes. Here we + // check if the test was too slow. + virtual void TearDown() { + // Gets the time when the test finishes + const time_t end_time = time(NULL); + + // Asserts that the test took no more than ~5 seconds. Did you + // know that you can use assertions in SetUp() and TearDown() as + // well? + EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long."; + } + + // The UTC time (in seconds) when the test starts + time_t start_time_; +}; + + +// We derive a fixture named IntegerFunctionTest from the QuickTest +// fixture. All tests using this fixture will be automatically +// required to be quick. +class IntegerFunctionTest : public QuickTest { + // We don't need any more logic than already in the QuickTest fixture. + // Therefore the body is empty. +}; + + +// Now we can write tests in the IntegerFunctionTest test case. + +// Tests Factorial() +TEST_F(IntegerFunctionTest, Factorial) { + // Tests factorial of negative numbers. + EXPECT_EQ(1, Factorial(-5)); + EXPECT_EQ(1, Factorial(-1)); + EXPECT_GT(Factorial(-10), 0); + + // Tests factorial of 0. + EXPECT_EQ(1, Factorial(0)); + + // Tests factorial of positive numbers. + EXPECT_EQ(1, Factorial(1)); + EXPECT_EQ(2, Factorial(2)); + EXPECT_EQ(6, Factorial(3)); + EXPECT_EQ(40320, Factorial(8)); +} + + +// Tests IsPrime() +TEST_F(IntegerFunctionTest, IsPrime) { + // Tests negative input. + EXPECT_FALSE(IsPrime(-1)); + EXPECT_FALSE(IsPrime(-2)); + EXPECT_FALSE(IsPrime(INT_MIN)); + + // Tests some trivial cases. + EXPECT_FALSE(IsPrime(0)); + EXPECT_FALSE(IsPrime(1)); + EXPECT_TRUE(IsPrime(2)); + EXPECT_TRUE(IsPrime(3)); + + // Tests positive input. + EXPECT_FALSE(IsPrime(4)); + EXPECT_TRUE(IsPrime(5)); + EXPECT_FALSE(IsPrime(6)); + EXPECT_TRUE(IsPrime(23)); +} + + +// The next test case (named "QueueTest") also needs to be quick, so +// we derive another fixture from QuickTest. +// +// The QueueTest test fixture has some logic and shared objects in +// addition to what's in QuickTest already. We define the additional +// stuff inside the body of the test fixture, as usual. +class QueueTest : public QuickTest { + protected: + virtual void SetUp() { + // First, we need to set up the super fixture (QuickTest). + QuickTest::SetUp(); + + // Second, some additional setup for this fixture. + q1_.Enqueue(1); + q2_.Enqueue(2); + q2_.Enqueue(3); + } + + // By default, TearDown() inherits the behavior of + // QuickTest::TearDown(). As we have no additional cleaning work + // for QueueTest, we omit it here. + // + // virtual void TearDown() { + // QuickTest::TearDown(); + // } + + Queue q0_; + Queue q1_; + Queue q2_; +}; + + +// Now, let's write tests using the QueueTest fixture. + +// Tests the default constructor. +TEST_F(QueueTest, DefaultConstructor) { + EXPECT_EQ(0u, q0_.Size()); +} + +// Tests Dequeue(). +TEST_F(QueueTest, Dequeue) { + int* n = q0_.Dequeue(); + EXPECT_TRUE(n == NULL); + + n = q1_.Dequeue(); + EXPECT_TRUE(n != NULL); + EXPECT_EQ(1, *n); + EXPECT_EQ(0u, q1_.Size()); + delete n; + + n = q2_.Dequeue(); + EXPECT_TRUE(n != NULL); + EXPECT_EQ(2, *n); + EXPECT_EQ(1u, q2_.Size()); + delete n; +} + +// If necessary, you can derive further test fixtures from a derived +// fixture itself. For example, you can derive another fixture from +// QueueTest. Google Test imposes no limit on how deep the hierarchy +// can be. In practice, however, you probably don't want it to be too +// deep as to be confusing. diff --git a/src/test/gtest/samples/sample6_unittest.cc b/src/test/gtest/samples/sample6_unittest.cc new file mode 100644 index 00000000..8f2036a5 --- /dev/null +++ b/src/test/gtest/samples/sample6_unittest.cc @@ -0,0 +1,224 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This sample shows how to test common properties of multiple +// implementations of the same interface (aka interface tests). + +// The interface and its implementations are in this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" + +// First, we define some factory functions for creating instances of +// the implementations. You may be able to skip this step if all your +// implementations can be constructed the same way. + +template +PrimeTable* CreatePrimeTable(); + +template <> +PrimeTable* CreatePrimeTable() { + return new OnTheFlyPrimeTable; +} + +template <> +PrimeTable* CreatePrimeTable() { + return new PreCalculatedPrimeTable(10000); +} + +// Then we define a test fixture class template. +template +class PrimeTableTest : public testing::Test { + protected: + // The ctor calls the factory function to create a prime table + // implemented by T. + PrimeTableTest() : table_(CreatePrimeTable()) {} + + virtual ~PrimeTableTest() { delete table_; } + + // Note that we test an implementation via the base interface + // instead of the actual implementation class. This is important + // for keeping the tests close to the real world scenario, where the + // implementation is invoked via the base interface. It avoids + // got-yas where the implementation class has a method that shadows + // a method with the same name (but slightly different argument + // types) in the base interface, for example. + PrimeTable* const table_; +}; + +#if GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Google Test offers two ways for reusing tests for different types. +// The first is called "typed tests". You should use it if you +// already know *all* the types you are gonna exercise when you write +// the tests. + +// To write a typed test case, first use +// +// TYPED_TEST_CASE(TestCaseName, TypeList); +// +// to declare it and specify the type parameters. As with TEST_F, +// TestCaseName must match the test fixture name. + +// The list of types we want to test. +typedef Types Implementations; + +TYPED_TEST_CASE(PrimeTableTest, Implementations); + +// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test, +// similar to TEST_F. +TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) { + // Inside the test body, you can refer to the type parameter by + // TypeParam, and refer to the fixture class by TestFixture. We + // don't need them in this example. + + // Since we are in the template world, C++ requires explicitly + // writing 'this->' when referring to members of the fixture class. + // This is something you have to learn to live with. + EXPECT_FALSE(this->table_->IsPrime(-5)); + EXPECT_FALSE(this->table_->IsPrime(0)); + EXPECT_FALSE(this->table_->IsPrime(1)); + EXPECT_FALSE(this->table_->IsPrime(4)); + EXPECT_FALSE(this->table_->IsPrime(6)); + EXPECT_FALSE(this->table_->IsPrime(100)); +} + +TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(this->table_->IsPrime(2)); + EXPECT_TRUE(this->table_->IsPrime(3)); + EXPECT_TRUE(this->table_->IsPrime(5)); + EXPECT_TRUE(this->table_->IsPrime(7)); + EXPECT_TRUE(this->table_->IsPrime(11)); + EXPECT_TRUE(this->table_->IsPrime(131)); +} + +TYPED_TEST(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, this->table_->GetNextPrime(0)); + EXPECT_EQ(3, this->table_->GetNextPrime(2)); + EXPECT_EQ(5, this->table_->GetNextPrime(3)); + EXPECT_EQ(7, this->table_->GetNextPrime(5)); + EXPECT_EQ(11, this->table_->GetNextPrime(7)); + EXPECT_EQ(131, this->table_->GetNextPrime(128)); +} + +// That's it! Google Test will repeat each TYPED_TEST for each type +// in the type list specified in TYPED_TEST_CASE. Sit back and be +// happy that you don't have to define them multiple times. + +#endif // GTEST_HAS_TYPED_TEST + +#if GTEST_HAS_TYPED_TEST_P + +using testing::Types; + +// Sometimes, however, you don't yet know all the types that you want +// to test when you write the tests. For example, if you are the +// author of an interface and expect other people to implement it, you +// might want to write a set of tests to make sure each implementation +// conforms to some basic requirements, but you don't know what +// implementations will be written in the future. +// +// How can you write the tests without committing to the type +// parameters? That's what "type-parameterized tests" can do for you. +// It is a bit more involved than typed tests, but in return you get a +// test pattern that can be reused in many contexts, which is a big +// win. Here's how you do it: + +// First, define a test fixture class template. Here we just reuse +// the PrimeTableTest fixture defined earlier: + +template +class PrimeTableTest2 : public PrimeTableTest { +}; + +// Then, declare the test case. The argument is the name of the test +// fixture, and also the name of the test case (as usual). The _P +// suffix is for "parameterized" or "pattern". +TYPED_TEST_CASE_P(PrimeTableTest2); + +// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test, +// similar to what you do with TEST_F. +TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) { + EXPECT_FALSE(this->table_->IsPrime(-5)); + EXPECT_FALSE(this->table_->IsPrime(0)); + EXPECT_FALSE(this->table_->IsPrime(1)); + EXPECT_FALSE(this->table_->IsPrime(4)); + EXPECT_FALSE(this->table_->IsPrime(6)); + EXPECT_FALSE(this->table_->IsPrime(100)); +} + +TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) { + EXPECT_TRUE(this->table_->IsPrime(2)); + EXPECT_TRUE(this->table_->IsPrime(3)); + EXPECT_TRUE(this->table_->IsPrime(5)); + EXPECT_TRUE(this->table_->IsPrime(7)); + EXPECT_TRUE(this->table_->IsPrime(11)); + EXPECT_TRUE(this->table_->IsPrime(131)); +} + +TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) { + EXPECT_EQ(2, this->table_->GetNextPrime(0)); + EXPECT_EQ(3, this->table_->GetNextPrime(2)); + EXPECT_EQ(5, this->table_->GetNextPrime(3)); + EXPECT_EQ(7, this->table_->GetNextPrime(5)); + EXPECT_EQ(11, this->table_->GetNextPrime(7)); + EXPECT_EQ(131, this->table_->GetNextPrime(128)); +} + +// Type-parameterized tests involve one extra step: you have to +// enumerate the tests you defined: +REGISTER_TYPED_TEST_CASE_P( + PrimeTableTest2, // The first argument is the test case name. + // The rest of the arguments are the test names. + ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime); + +// At this point the test pattern is done. However, you don't have +// any real test yet as you haven't said which types you want to run +// the tests with. + +// To turn the abstract test pattern into real tests, you instantiate +// it with a list of types. Usually the test pattern will be defined +// in a .h file, and anyone can #include and instantiate it. You can +// even instantiate it more than once in the same program. To tell +// different instances apart, you give each of them a name, which will +// become part of the test case name and can be used in test filters. + +// The list of types we want to test. Note that it doesn't have to be +// defined at the time we write the TYPED_TEST_P()s. +typedef Types + PrimeTableImplementations; +INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated, // Instance name + PrimeTableTest2, // Test case name + PrimeTableImplementations); // Type list + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/src/test/gtest/samples/sample7_unittest.cc b/src/test/gtest/samples/sample7_unittest.cc new file mode 100644 index 00000000..1b651a21 --- /dev/null +++ b/src/test/gtest/samples/sample7_unittest.cc @@ -0,0 +1,130 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to test common properties of multiple +// implementations of an interface (aka interface tests) using +// value-parameterized tests. Each test in the test case has +// a parameter that is an interface pointer to an implementation +// tested. + +// The interface and its implementations are in this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +using ::testing::TestWithParam; +using ::testing::Values; + +// As a general rule, to prevent a test from affecting the tests that come +// after it, you should create and destroy the tested objects for each test +// instead of reusing them. In this sample we will define a simple factory +// function for PrimeTable objects. We will instantiate objects in test's +// SetUp() method and delete them in TearDown() method. +typedef PrimeTable* CreatePrimeTableFunc(); + +PrimeTable* CreateOnTheFlyPrimeTable() { + return new OnTheFlyPrimeTable(); +} + +template +PrimeTable* CreatePreCalculatedPrimeTable() { + return new PreCalculatedPrimeTable(max_precalculated); +} + +// Inside the test body, fixture constructor, SetUp(), and TearDown() you +// can refer to the test parameter by GetParam(). In this case, the test +// parameter is a factory function which we call in fixture's SetUp() to +// create and store an instance of PrimeTable. +class PrimeTableTest : public TestWithParam { + public: + virtual ~PrimeTableTest() { delete table_; } + virtual void SetUp() { table_ = (*GetParam())(); } + virtual void TearDown() { + delete table_; + table_ = NULL; + } + + protected: + PrimeTable* table_; +}; + +TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { + EXPECT_FALSE(table_->IsPrime(-5)); + EXPECT_FALSE(table_->IsPrime(0)); + EXPECT_FALSE(table_->IsPrime(1)); + EXPECT_FALSE(table_->IsPrime(4)); + EXPECT_FALSE(table_->IsPrime(6)); + EXPECT_FALSE(table_->IsPrime(100)); +} + +TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(table_->IsPrime(2)); + EXPECT_TRUE(table_->IsPrime(3)); + EXPECT_TRUE(table_->IsPrime(5)); + EXPECT_TRUE(table_->IsPrime(7)); + EXPECT_TRUE(table_->IsPrime(11)); + EXPECT_TRUE(table_->IsPrime(131)); +} + +TEST_P(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, table_->GetNextPrime(0)); + EXPECT_EQ(3, table_->GetNextPrime(2)); + EXPECT_EQ(5, table_->GetNextPrime(3)); + EXPECT_EQ(7, table_->GetNextPrime(5)); + EXPECT_EQ(11, table_->GetNextPrime(7)); + EXPECT_EQ(131, table_->GetNextPrime(128)); +} + +// In order to run value-parameterized tests, you need to instantiate them, +// or bind them to a list of values which will be used as test parameters. +// You can instantiate them in a different translation module, or even +// instantiate them several times. +// +// Here, we instantiate our tests with a list of two PrimeTable object +// factory functions: +INSTANTIATE_TEST_CASE_P( + OnTheFlyAndPreCalculated, + PrimeTableTest, + Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>)); + +#else + +// Google Test may not support value-parameterized tests with some +// compilers. If we use conditional compilation to compile out all +// code referring to the gtest_main library, MSVC linker will not link +// that library at all and consequently complain about missing entry +// point defined in that library (fatal error LNK1561: entry point +// must be defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {} + +#endif // GTEST_HAS_PARAM_TEST diff --git a/src/test/gtest/samples/sample8_unittest.cc b/src/test/gtest/samples/sample8_unittest.cc new file mode 100644 index 00000000..72743340 --- /dev/null +++ b/src/test/gtest/samples/sample8_unittest.cc @@ -0,0 +1,173 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to test code relying on some global flag variables. +// Combine() helps with generating all possible combinations of such flags, +// and each test is given one combination as a parameter. + +// Use class definitions to test from this header. +#include "prime_tables.h" + +#include "gtest/gtest.h" + +#if GTEST_HAS_COMBINE + +// Suppose we want to introduce a new, improved implementation of PrimeTable +// which combines speed of PrecalcPrimeTable and versatility of +// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both +// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more +// appropriate under the circumstances. But in low memory conditions, it can be +// told to instantiate without PrecalcPrimeTable instance at all and use only +// OnTheFlyPrimeTable. +class HybridPrimeTable : public PrimeTable { + public: + HybridPrimeTable(bool force_on_the_fly, int max_precalculated) + : on_the_fly_impl_(new OnTheFlyPrimeTable), + precalc_impl_(force_on_the_fly ? NULL : + new PreCalculatedPrimeTable(max_precalculated)), + max_precalculated_(max_precalculated) {} + virtual ~HybridPrimeTable() { + delete on_the_fly_impl_; + delete precalc_impl_; + } + + virtual bool IsPrime(int n) const { + if (precalc_impl_ != NULL && n < max_precalculated_) + return precalc_impl_->IsPrime(n); + else + return on_the_fly_impl_->IsPrime(n); + } + + virtual int GetNextPrime(int p) const { + int next_prime = -1; + if (precalc_impl_ != NULL && p < max_precalculated_) + next_prime = precalc_impl_->GetNextPrime(p); + + return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p); + } + + private: + OnTheFlyPrimeTable* on_the_fly_impl_; + PreCalculatedPrimeTable* precalc_impl_; + int max_precalculated_; +}; + +using ::testing::TestWithParam; +using ::testing::Bool; +using ::testing::Values; +using ::testing::Combine; + +// To test all code paths for HybridPrimeTable we must test it with numbers +// both within and outside PreCalculatedPrimeTable's capacity and also with +// PreCalculatedPrimeTable disabled. We do this by defining fixture which will +// accept different combinations of parameters for instantiating a +// HybridPrimeTable instance. +class PrimeTableTest : public TestWithParam< ::testing::tuple > { + protected: + virtual void SetUp() { + // This can be written as + // + // bool force_on_the_fly; + // int max_precalculated; + // tie(force_on_the_fly, max_precalculated) = GetParam(); + // + // once the Google C++ Style Guide allows use of ::std::tr1::tie. + // + bool force_on_the_fly = ::testing::get<0>(GetParam()); + int max_precalculated = ::testing::get<1>(GetParam()); + table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated); + } + virtual void TearDown() { + delete table_; + table_ = NULL; + } + HybridPrimeTable* table_; +}; + +TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { + // Inside the test body, you can refer to the test parameter by GetParam(). + // In this case, the test parameter is a PrimeTable interface pointer which + // we can use directly. + // Please note that you can also save it in the fixture's SetUp() method + // or constructor and use saved copy in the tests. + + EXPECT_FALSE(table_->IsPrime(-5)); + EXPECT_FALSE(table_->IsPrime(0)); + EXPECT_FALSE(table_->IsPrime(1)); + EXPECT_FALSE(table_->IsPrime(4)); + EXPECT_FALSE(table_->IsPrime(6)); + EXPECT_FALSE(table_->IsPrime(100)); +} + +TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { + EXPECT_TRUE(table_->IsPrime(2)); + EXPECT_TRUE(table_->IsPrime(3)); + EXPECT_TRUE(table_->IsPrime(5)); + EXPECT_TRUE(table_->IsPrime(7)); + EXPECT_TRUE(table_->IsPrime(11)); + EXPECT_TRUE(table_->IsPrime(131)); +} + +TEST_P(PrimeTableTest, CanGetNextPrime) { + EXPECT_EQ(2, table_->GetNextPrime(0)); + EXPECT_EQ(3, table_->GetNextPrime(2)); + EXPECT_EQ(5, table_->GetNextPrime(3)); + EXPECT_EQ(7, table_->GetNextPrime(5)); + EXPECT_EQ(11, table_->GetNextPrime(7)); + EXPECT_EQ(131, table_->GetNextPrime(128)); +} + +// In order to run value-parameterized tests, you need to instantiate them, +// or bind them to a list of values which will be used as test parameters. +// You can instantiate them in a different translation module, or even +// instantiate them several times. +// +// Here, we instantiate our tests with a list of parameters. We must combine +// all variations of the boolean flag suppressing PrecalcPrimeTable and some +// meaningful values for tests. We choose a small value (1), and a value that +// will put some of the tested numbers beyond the capability of the +// PrecalcPrimeTable instance and some inside it (10). Combine will produce all +// possible combinations. +INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters, + PrimeTableTest, + Combine(Bool(), Values(1, 10))); + +#else + +// Google Test may not support Combine() with some compilers. If we +// use conditional compilation to compile out all code referring to +// the gtest_main library, MSVC linker will not link that library at +// all and consequently complain about missing entry point defined in +// that library (fatal error LNK1561: entry point must be +// defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {} + +#endif // GTEST_HAS_COMBINE diff --git a/src/test/gtest/samples/sample9_unittest.cc b/src/test/gtest/samples/sample9_unittest.cc new file mode 100644 index 00000000..b2e2079b --- /dev/null +++ b/src/test/gtest/samples/sample9_unittest.cc @@ -0,0 +1,160 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to use Google Test listener API to implement +// an alternative console output and how to use the UnitTest reflection API +// to enumerate test cases and tests and to inspect their results. + +#include + +#include "gtest/gtest.h" + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +namespace { + +// Provides alternative output mode which produces minimal amount of +// information about tests. +class TersePrinter : public EmptyTestEventListener { + private: + // Called before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {} + + // Called after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) { + fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED"); + fflush(stdout); + } + + // Called before a test starts. + virtual void OnTestStart(const TestInfo& test_info) { + fprintf(stdout, + "*** Test %s.%s starting.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } + + // Called after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) { + fprintf(stdout, + "%s in %s:%d\n%s\n", + test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), + test_part_result.line_number(), + test_part_result.summary()); + fflush(stdout); + } + + // Called after a test ends. + virtual void OnTestEnd(const TestInfo& test_info) { + fprintf(stdout, + "*** Test %s.%s ending.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } +}; // class TersePrinter + +TEST(CustomOutputTest, PrintsMessage) { + printf("Printing something from the test body...\n"); +} + +TEST(CustomOutputTest, Succeeds) { + SUCCEED() << "SUCCEED() has been invoked from here"; +} + +TEST(CustomOutputTest, Fails) { + EXPECT_EQ(1, 2) + << "This test fails in order to demonstrate alternative failure messages"; +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool terse_output = false; + if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 ) + terse_output = true; + else + printf("%s\n", "Run this program with --terse_output to change the way " + "it prints its output."); + + UnitTest& unit_test = *UnitTest::GetInstance(); + + // If we are given the --terse_output command line flag, suppresses the + // standard output and attaches own result printer. + if (terse_output) { + TestEventListeners& listeners = unit_test.listeners(); + + // Removes the default console output listener from the list so it will + // not receive events from Google Test and won't print any output. Since + // this operation transfers ownership of the listener to the caller we + // have to delete it as well. + delete listeners.Release(listeners.default_result_printer()); + + // Adds the custom output listener to the list. It will now receive + // events from Google Test and print the alternative output. We don't + // have to worry about deleting it since Google Test assumes ownership + // over it after adding it to the list. + listeners.Append(new TersePrinter); + } + int ret_val = RUN_ALL_TESTS(); + + // This is an example of using the UnitTest reflection API to inspect test + // results. Here we discount failures from the tests we expected to fail. + int unexpectedly_failed_tests = 0; + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + // Counts failed tests that were not meant to fail (those without + // 'Fails' in the name). + if (test_info.result()->Failed() && + strcmp(test_info.name(), "Fails") != 0) { + unexpectedly_failed_tests++; + } + } + } + + // Test that were meant to fail should not affect the test program outcome. + if (unexpectedly_failed_tests == 0) + ret_val = 0; + + return ret_val; +} diff --git a/src/test/gtest/scripts/common.py b/src/test/gtest/scripts/common.py new file mode 100644 index 00000000..3c0347a7 --- /dev/null +++ b/src/test/gtest/scripts/common.py @@ -0,0 +1,83 @@ +# Copyright 2013 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Shared utilities for writing scripts for Google Test/Mock.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + + +import os +import re + + +# Matches the line from 'svn info .' output that describes what SVN +# path the current local directory corresponds to. For example, in +# a googletest SVN workspace's trunk/test directory, the output will be: +# +# URL: https://googletest.googlecode.com/svn/trunk/test +_SVN_INFO_URL_RE = re.compile(r'^URL: https://(\w+)\.googlecode\.com/svn(.*)') + + +def GetCommandOutput(command): + """Runs the shell command and returns its stdout as a list of lines.""" + + f = os.popen(command, 'r') + lines = [line.strip() for line in f.readlines()] + f.close() + return lines + + +def GetSvnInfo(): + """Returns the project name and the current SVN workspace's root path.""" + + for line in GetCommandOutput('svn info .'): + m = _SVN_INFO_URL_RE.match(line) + if m: + project = m.group(1) # googletest or googlemock + rel_path = m.group(2) + root = os.path.realpath(rel_path.count('/') * '../') + return project, root + + return None, None + + +def GetSvnTrunk(): + """Returns the current SVN workspace's trunk root path.""" + + _, root = GetSvnInfo() + return root + '/trunk' if root else None + + +def IsInGTestSvn(): + project, _ = GetSvnInfo() + return project == 'googletest' + + +def IsInGMockSvn(): + project, _ = GetSvnInfo() + return project == 'googlemock' diff --git a/src/test/gtest/scripts/fuse_gtest_files.py b/src/test/gtest/scripts/fuse_gtest_files.py new file mode 100755 index 00000000..57ef72f0 --- /dev/null +++ b/src/test/gtest/scripts/fuse_gtest_files.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""fuse_gtest_files.py v0.2.0 +Fuses Google Test source code into a .h file and a .cc file. + +SYNOPSIS + fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR + + Scans GTEST_ROOT_DIR for Google Test source code, and generates + two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc. + Then you can build your tests by adding OUTPUT_DIR to the include + search path and linking with OUTPUT_DIR/gtest/gtest-all.cc. These + two files contain everything you need to use Google Test. Hence + you can "install" Google Test by copying them to wherever you want. + + GTEST_ROOT_DIR can be omitted and defaults to the parent + directory of the directory holding this script. + +EXAMPLES + ./fuse_gtest_files.py fused_gtest + ./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest + +This tool is experimental. In particular, it assumes that there is no +conditional inclusion of Google Test headers. Please report any +problems to googletestframework@googlegroups.com. You can read +http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for +more information. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sets +import sys + +# We assume that this file is in the scripts/ directory in the Google +# Test root directory. +DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') + +# Regex for matching '#include "gtest/..."'. +INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"') + +# Regex for matching '#include "src/..."'. +INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"') + +# Where to find the source seed files. +GTEST_H_SEED = 'include/gtest/gtest.h' +GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h' +GTEST_ALL_CC_SEED = 'src/gtest-all.cc' + +# Where to put the generated files. +GTEST_H_OUTPUT = 'gtest/gtest.h' +GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc' + + +def VerifyFileExists(directory, relative_path): + """Verifies that the given file exists; aborts on failure. + + relative_path is the file path relative to the given directory. + """ + + if not os.path.isfile(os.path.join(directory, relative_path)): + print 'ERROR: Cannot find %s in directory %s.' % (relative_path, + directory) + print ('Please either specify a valid project root directory ' + 'or omit it on the command line.') + sys.exit(1) + + +def ValidateGTestRootDir(gtest_root): + """Makes sure gtest_root points to a valid gtest root directory. + + The function aborts the program on failure. + """ + + VerifyFileExists(gtest_root, GTEST_H_SEED) + VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED) + + +def VerifyOutputFile(output_dir, relative_path): + """Verifies that the given output file path is valid. + + relative_path is relative to the output_dir directory. + """ + + # Makes sure the output file either doesn't exist or can be overwritten. + output_file = os.path.join(output_dir, relative_path) + if os.path.exists(output_file): + # TODO(wan@google.com): The following user-interaction doesn't + # work with automated processes. We should provide a way for the + # Makefile to force overwriting the files. + print ('%s already exists in directory %s - overwrite it? (y/N) ' % + (relative_path, output_dir)) + answer = sys.stdin.readline().strip() + if answer not in ['y', 'Y']: + print 'ABORTED.' + sys.exit(1) + + # Makes sure the directory holding the output file exists; creates + # it and all its ancestors if necessary. + parent_directory = os.path.dirname(output_file) + if not os.path.isdir(parent_directory): + os.makedirs(parent_directory) + + +def ValidateOutputDir(output_dir): + """Makes sure output_dir points to a valid output directory. + + The function aborts the program on failure. + """ + + VerifyOutputFile(output_dir, GTEST_H_OUTPUT) + VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT) + + +def FuseGTestH(gtest_root, output_dir): + """Scans folder gtest_root to generate gtest/gtest.h in output_dir.""" + + output_file = file(os.path.join(output_dir, GTEST_H_OUTPUT), 'w') + processed_files = sets.Set() # Holds all gtest headers we've processed. + + def ProcessFile(gtest_header_path): + """Processes the given gtest header file.""" + + # We don't process the same header twice. + if gtest_header_path in processed_files: + return + + processed_files.add(gtest_header_path) + + # Reads each line in the given gtest header. + for line in file(os.path.join(gtest_root, gtest_header_path), 'r'): + m = INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + # It's '#include "gtest/..."' - let's process it recursively. + ProcessFile('include/' + m.group(1)) + else: + # Otherwise we copy the line unchanged to the output file. + output_file.write(line) + + ProcessFile(GTEST_H_SEED) + output_file.close() + + +def FuseGTestAllCcToFile(gtest_root, output_file): + """Scans folder gtest_root to generate gtest/gtest-all.cc in output_file.""" + + processed_files = sets.Set() + + def ProcessFile(gtest_source_file): + """Processes the given gtest source file.""" + + # We don't process the same #included file twice. + if gtest_source_file in processed_files: + return + + processed_files.add(gtest_source_file) + + # Reads each line in the given gtest source file. + for line in file(os.path.join(gtest_root, gtest_source_file), 'r'): + m = INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + if 'include/' + m.group(1) == GTEST_SPI_H_SEED: + # It's '#include "gtest/gtest-spi.h"'. This file is not + # #included by "gtest/gtest.h", so we need to process it. + ProcessFile(GTEST_SPI_H_SEED) + else: + # It's '#include "gtest/foo.h"' where foo is not gtest-spi. + # We treat it as '#include "gtest/gtest.h"', as all other + # gtest headers are being fused into gtest.h and cannot be + # #included directly. + + # There is no need to #include "gtest/gtest.h" more than once. + if not GTEST_H_SEED in processed_files: + processed_files.add(GTEST_H_SEED) + output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,)) + else: + m = INCLUDE_SRC_FILE_REGEX.match(line) + if m: + # It's '#include "src/foo"' - let's process it recursively. + ProcessFile(m.group(1)) + else: + output_file.write(line) + + ProcessFile(GTEST_ALL_CC_SEED) + + +def FuseGTestAllCc(gtest_root, output_dir): + """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir.""" + + output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w') + FuseGTestAllCcToFile(gtest_root, output_file) + output_file.close() + + +def FuseGTest(gtest_root, output_dir): + """Fuses gtest.h and gtest-all.cc.""" + + ValidateGTestRootDir(gtest_root) + ValidateOutputDir(output_dir) + + FuseGTestH(gtest_root, output_dir) + FuseGTestAllCc(gtest_root, output_dir) + + +def main(): + argc = len(sys.argv) + if argc == 2: + # fuse_gtest_files.py OUTPUT_DIR + FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1]) + elif argc == 3: + # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR + FuseGTest(sys.argv[1], sys.argv[2]) + else: + print __doc__ + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/src/test/gtest/scripts/gen_gtest_pred_impl.py b/src/test/gtest/scripts/gen_gtest_pred_impl.py new file mode 100755 index 00000000..3e7ab042 --- /dev/null +++ b/src/test/gtest/scripts/gen_gtest_pred_impl.py @@ -0,0 +1,730 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""gen_gtest_pred_impl.py v0.1 + +Generates the implementation of Google Test predicate assertions and +accompanying tests. + +Usage: + + gen_gtest_pred_impl.py MAX_ARITY + +where MAX_ARITY is a positive integer. + +The command generates the implementation of up-to MAX_ARITY-ary +predicate assertions, and writes it to file gtest_pred_impl.h in the +directory where the script is. It also generates the accompanying +unit test in file gtest_pred_impl_unittest.cc. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys +import time + +# Where this script is. +SCRIPT_DIR = os.path.dirname(sys.argv[0]) + +# Where to store the generated header. +HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h') + +# Where to store the generated unit test. +UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc') + + +def HeaderPreamble(n): + """Returns the preamble for the header file. + + Args: + n: the maximum arity of the predicate macros to be generated. + """ + + # A map that defines the values used in the preamble template. + DEFS = { + 'today' : time.strftime('%m/%d/%Y'), + 'year' : time.strftime('%Y'), + 'command' : '%s %s' % (os.path.basename(sys.argv[0]), n), + 'n' : n + } + + return ( +"""// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// This file is AUTOMATICALLY GENERATED on %(today)s by command +// '%(command)s'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most %(n)s. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \\ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\ + if (const ::testing::AssertionResult gtest_ar = (expression)) \\ + ; \\ + else \\ + on_failure(gtest_ar.failure_message()) +""" % DEFS) + + +def Arity(n): + """Returns the English name of the given arity.""" + + if n < 0: + return None + elif n <= 3: + return ['nullary', 'unary', 'binary', 'ternary'][n] + else: + return '%s-ary' % n + + +def Title(word): + """Returns the given word in title case. The difference between + this and string's title() method is that Title('4-ary') is '4-ary' + while '4-ary'.title() is '4-Ary'.""" + + return word[0].upper() + word[1:] + + +def OneTo(n): + """Returns the list [1, 2, 3, ..., n].""" + + return range(1, n + 1) + + +def Iter(n, format, sep=''): + """Given a positive integer n, a format string that contains 0 or + more '%s' format specs, and optionally a separator string, returns + the join of n strings, each formatted with the format string on an + iterator ranged from 1 to n. + + Example: + + Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'. + """ + + # How many '%s' specs are in format? + spec_count = len(format.split('%s')) - 1 + return sep.join([format % (spec_count * (i,)) for i in OneTo(n)]) + + +def ImplementationForArity(n): + """Returns the implementation of n-ary predicate assertions.""" + + # A map the defines the values used in the implementation template. + DEFS = { + 'n' : str(n), + 'vs' : Iter(n, 'v%s', sep=', '), + 'vts' : Iter(n, '#v%s', sep=', '), + 'arity' : Arity(n), + 'Arity' : Title(Arity(n)) + } + + impl = """ + +// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use +// this in your code. +template +AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS + + impl += Iter(n, """, + const char* e%s""") + + impl += """, + Pred pred""" + + impl += Iter(n, """, + const T%s& v%s""") + + impl += """) { + if (pred(%(vs)s)) return AssertionSuccess(); + +""" % DEFS + + impl += ' return AssertionFailure() << pred_text << "("' + + impl += Iter(n, """ + << e%s""", sep=' << ", "') + + impl += ' << ") evaluates to false, where"' + + impl += Iter(n, """ + << "\\n" << e%s << " evaluates to " << v%s""") + + impl += """; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s. +// Don't use this in your code. +#define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\ + GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use +// this in your code. +#define GTEST_PRED%(n)s_(pred, %(vs)s, on_failure)\\ + GTEST_ASSERT_(::testing::AssertPred%(n)sHelper(#pred""" % DEFS + + impl += Iter(n, """, \\ + #v%s""") + + impl += """, \\ + pred""" + + impl += Iter(n, """, \\ + v%s""") + + impl += """), on_failure) + +// %(Arity)s predicate assertion macros. +#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ + GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED%(n)s(pred, %(vs)s) \\ + GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ + GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED%(n)s(pred, %(vs)s) \\ + GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_FATAL_FAILURE_) + +""" % DEFS + + return impl + + +def HeaderPostamble(): + """Returns the postamble for the header file.""" + + return """ + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +""" + + +def GenerateFile(path, content): + """Given a file path and a content string, overwrites it with the + given content.""" + + print 'Updating file %s . . .' % path + + f = file(path, 'w+') + print >>f, content, + f.close() + + print 'File %s has been updated.' % path + + +def GenerateHeader(n): + """Given the maximum arity n, updates the header file that implements + the predicate assertions.""" + + GenerateFile(HEADER, + HeaderPreamble(n) + + ''.join([ImplementationForArity(i) for i in OneTo(n)]) + + HeaderPostamble()) + + +def UnitTestPreamble(): + """Returns the preamble for the unit test file.""" + + # A map that defines the values used in the preamble template. + DEFS = { + 'today' : time.strftime('%m/%d/%Y'), + 'year' : time.strftime('%Y'), + 'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]), + } + + return ( +"""// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// This file is AUTOMATICALLY GENERATED on %(today)s by command +// '%(command)s'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +""" % DEFS) + + +def TestsForArity(n): + """Returns the tests for n-ary predicate assertions.""" + + # A map that defines the values used in the template for the tests. + DEFS = { + 'n' : n, + 'es' : Iter(n, 'e%s', sep=', '), + 'vs' : Iter(n, 'v%s', sep=', '), + 'vts' : Iter(n, '#v%s', sep=', '), + 'tvs' : Iter(n, 'T%s v%s', sep=', '), + 'int_vs' : Iter(n, 'int v%s', sep=', '), + 'Bool_vs' : Iter(n, 'Bool v%s', sep=', '), + 'types' : Iter(n, 'typename T%s', sep=', '), + 'v_sum' : Iter(n, 'v%s', sep=' + '), + 'arity' : Arity(n), + 'Arity' : Title(Arity(n)), + } + + tests = ( +"""// Sample functions/functors for testing %(arity)s predicate assertions. + +// A %(arity)s predicate function. +template <%(types)s> +bool PredFunction%(n)s(%(tvs)s) { + return %(v_sum)s > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction%(n)sInt(%(int_vs)s) { + return %(v_sum)s > 0; +} +bool PredFunction%(n)sBool(%(Bool_vs)s) { + return %(v_sum)s > 0; +} +""" % DEFS) + + tests += """ +// A %(arity)s predicate functor. +struct PredFunctor%(n)s { + template <%(types)s> + bool operator()(""" % DEFS + + tests += Iter(n, 'const T%s& v%s', sep=""", + """) + + tests += """) { + return %(v_sum)s > 0; + } +}; +""" % DEFS + + tests += """ +// A %(arity)s predicate-formatter function. +template <%(types)s> +testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS + + tests += Iter(n, 'const char* e%s', sep=""", + """) + + tests += Iter(n, """, + const T%s& v%s""") + + tests += """) { + if (PredFunction%(n)s(%(vs)s)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << """ % DEFS + + tests += Iter(n, 'e%s', sep=' << " + " << ') + + tests += """ + << " is expected to be positive, but evaluates to " + << %(v_sum)s << "."; +} +""" % DEFS + + tests += """ +// A %(arity)s predicate-formatter functor. +struct PredFormatFunctor%(n)s { + template <%(types)s> + testing::AssertionResult operator()(""" % DEFS + + tests += Iter(n, 'const char* e%s', sep=""", + """) + + tests += Iter(n, """, + const T%s& v%s""") + + tests += """) const { + return PredFormatFunction%(n)s(%(es)s, %(vs)s); + } +}; +""" % DEFS + + tests += """ +// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s. + +class Predicate%(n)sTest : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false;""" % DEFS + + tests += """ + """ + Iter(n, 'n%s_ = ') + """0; + } +""" + + tests += """ + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once.""" + + tests += ''.join([""" + EXPECT_EQ(1, n%s_) << + "The predicate assertion didn't evaluate argument %s " + "exactly once.";""" % (i, i + 1) for i in OneTo(n)]) + + tests += """ + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; +""" % DEFS + + tests += Iter(n, """ + static int n%s_;""") + + tests += """ +}; + +bool Predicate%(n)sTest::expected_to_finish_; +bool Predicate%(n)sTest::finished_; +""" % DEFS + + tests += Iter(n, """int Predicate%%(n)sTest::n%s_; +""") % DEFS + + tests += """ +typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest; +typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest; +typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest; +typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest; +""" % DEFS + + def GenTest(use_format, use_assert, expect_failure, + use_functor, use_user_type): + """Returns the test for a predicate assertion macro. + + Args: + use_format: true iff the assertion is a *_PRED_FORMAT*. + use_assert: true iff the assertion is a ASSERT_*. + expect_failure: true iff the assertion is expected to fail. + use_functor: true iff the first argument of the assertion is + a functor (as opposed to a function) + use_user_type: true iff the predicate functor/function takes + argument(s) of a user-defined type. + + Example: + + GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior + of a successful EXPECT_PRED_FORMATn() that takes a functor + whose arguments have built-in types.""" + + if use_assert: + assrt = 'ASSERT' # 'assert' is reserved, so we cannot use + # that identifier here. + else: + assrt = 'EXPECT' + + assertion = assrt + '_PRED' + + if use_format: + pred_format = 'PredFormat' + assertion += '_FORMAT' + else: + pred_format = 'Pred' + + assertion += '%(n)s' % DEFS + + if use_functor: + pred_format_type = 'functor' + pred_format += 'Functor%(n)s()' + else: + pred_format_type = 'function' + pred_format += 'Function%(n)s' + if not use_format: + if use_user_type: + pred_format += 'Bool' + else: + pred_format += 'Int' + + test_name = pred_format_type.title() + + if use_user_type: + arg_type = 'user-defined type (Bool)' + test_name += 'OnUserType' + if expect_failure: + arg = 'Bool(n%s_++)' + else: + arg = 'Bool(++n%s_)' + else: + arg_type = 'built-in type (int)' + test_name += 'OnBuiltInType' + if expect_failure: + arg = 'n%s_++' + else: + arg = '++n%s_' + + if expect_failure: + successful_or_failed = 'failed' + expected_or_not = 'expected.' + test_name += 'Failure' + else: + successful_or_failed = 'successful' + expected_or_not = 'UNEXPECTED!' + test_name += 'Success' + + # A map that defines the values used in the test template. + defs = DEFS.copy() + defs.update({ + 'assert' : assrt, + 'assertion' : assertion, + 'test_name' : test_name, + 'pf_type' : pred_format_type, + 'pf' : pred_format, + 'arg_type' : arg_type, + 'arg' : arg, + 'successful' : successful_or_failed, + 'expected' : expected_or_not, + }) + + test = """ +// Tests a %(successful)s %(assertion)s where the +// predicate-formatter is a %(pf_type)s on a %(arg_type)s. +TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs + + indent = (len(assertion) + 3)*' ' + extra_indent = '' + + if expect_failure: + extra_indent = ' ' + if use_assert: + test += """ + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT""" + else: + test += """ + EXPECT_NONFATAL_FAILURE({ // NOLINT""" + + test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs + + test = test % defs + test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs) + test += ');\n' + extra_indent + ' finished_ = true;\n' + + if expect_failure: + test += ' }, "");\n' + + test += '}\n' + return test + + # Generates tests for all 2**6 = 64 combinations. + tests += ''.join([GenTest(use_format, use_assert, expect_failure, + use_functor, use_user_type) + for use_format in [0, 1] + for use_assert in [0, 1] + for expect_failure in [0, 1] + for use_functor in [0, 1] + for use_user_type in [0, 1] + ]) + + return tests + + +def UnitTestPostamble(): + """Returns the postamble for the tests.""" + + return '' + + +def GenerateUnitTest(n): + """Returns the tests for up-to n-ary predicate assertions.""" + + GenerateFile(UNIT_TEST, + UnitTestPreamble() + + ''.join([TestsForArity(i) for i in OneTo(n)]) + + UnitTestPostamble()) + + +def _Main(): + """The entry point of the script. Generates the header file and its + unit test.""" + + if len(sys.argv) != 2: + print __doc__ + print 'Author: ' + __author__ + sys.exit(1) + + n = int(sys.argv[1]) + GenerateHeader(n) + GenerateUnitTest(n) + + +if __name__ == '__main__': + _Main() diff --git a/src/test/gtest/scripts/gtest-config.in b/src/test/gtest/scripts/gtest-config.in new file mode 100755 index 00000000..780f8432 --- /dev/null +++ b/src/test/gtest/scripts/gtest-config.in @@ -0,0 +1,274 @@ +#!/bin/sh + +# These variables are automatically filled in by the configure script. +name="@PACKAGE_TARNAME@" +version="@PACKAGE_VERSION@" + +show_usage() +{ + echo "Usage: gtest-config [OPTIONS...]" +} + +show_help() +{ + show_usage + cat <<\EOF + +The `gtest-config' script provides access to the necessary compile and linking +flags to connect with Google C++ Testing Framework, both in a build prior to +installation, and on the system proper after installation. The installation +overrides may be issued in combination with any other queries, but will only +affect installation queries if called on a built but not installed gtest. The +installation queries may not be issued with any other types of queries, and +only one installation query may be made at a time. The version queries and +compiler flag queries may be combined as desired but not mixed. Different +version queries are always combined with logical "and" semantics, and only the +last of any particular query is used while all previous ones ignored. All +versions must be specified as a sequence of numbers separated by periods. +Compiler flag queries output the union of the sets of flags when combined. + + Examples: + gtest-config --min-version=1.0 || echo "Insufficient Google Test version." + + g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp + g++ $(gtest-config --ldflags --libs) -o foo foo.o + + # When using a built but not installed Google Test: + g++ $(../../my_gtest_build/scripts/gtest-config ...) ... + + # When using an installed Google Test, but with installation overrides: + export GTEST_PREFIX="/opt" + g++ $(gtest-config --libdir="/opt/lib64" ...) ... + + Help: + --usage brief usage information + --help display this help message + + Installation Overrides: + --prefix= overrides the installation prefix + --exec-prefix= overrides the executable installation prefix + --libdir= overrides the library installation prefix + --includedir= overrides the header file installation prefix + + Installation Queries: + --prefix installation prefix + --exec-prefix executable installation prefix + --libdir library installation directory + --includedir header file installation directory + --version the version of the Google Test installation + + Version Queries: + --min-version=VERSION return 0 if the version is at least VERSION + --exact-version=VERSION return 0 if the version is exactly VERSION + --max-version=VERSION return 0 if the version is at most VERSION + + Compilation Flag Queries: + --cppflags compile flags specific to the C-like preprocessors + --cxxflags compile flags appropriate for C++ programs + --ldflags linker flags + --libs libraries for linking + +EOF +} + +# This function bounds our version with a min and a max. It uses some clever +# POSIX-compliant variable expansion to portably do all the work in the shell +# and avoid any dependency on a particular "sed" or "awk" implementation. +# Notable is that it will only ever compare the first 3 components of versions. +# Further components will be cleanly stripped off. All versions must be +# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and +# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should +# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than +# continuing to maintain our own shell version. +check_versions() +{ + major_version=${version%%.*} + minor_version="0" + point_version="0" + if test "${version#*.}" != "${version}"; then + minor_version=${version#*.} + minor_version=${minor_version%%.*} + fi + if test "${version#*.*.}" != "${version}"; then + point_version=${version#*.*.} + point_version=${point_version%%.*} + fi + + min_version="$1" + min_major_version=${min_version%%.*} + min_minor_version="0" + min_point_version="0" + if test "${min_version#*.}" != "${min_version}"; then + min_minor_version=${min_version#*.} + min_minor_version=${min_minor_version%%.*} + fi + if test "${min_version#*.*.}" != "${min_version}"; then + min_point_version=${min_version#*.*.} + min_point_version=${min_point_version%%.*} + fi + + max_version="$2" + max_major_version=${max_version%%.*} + max_minor_version="0" + max_point_version="0" + if test "${max_version#*.}" != "${max_version}"; then + max_minor_version=${max_version#*.} + max_minor_version=${max_minor_version%%.*} + fi + if test "${max_version#*.*.}" != "${max_version}"; then + max_point_version=${max_version#*.*.} + max_point_version=${max_point_version%%.*} + fi + + test $(($major_version)) -lt $(($min_major_version)) && exit 1 + if test $(($major_version)) -eq $(($min_major_version)); then + test $(($minor_version)) -lt $(($min_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($min_minor_version)); then + test $(($point_version)) -lt $(($min_point_version)) && exit 1 + fi + fi + + test $(($major_version)) -gt $(($max_major_version)) && exit 1 + if test $(($major_version)) -eq $(($max_major_version)); then + test $(($minor_version)) -gt $(($max_minor_version)) && exit 1 + if test $(($minor_version)) -eq $(($max_minor_version)); then + test $(($point_version)) -gt $(($max_point_version)) && exit 1 + fi + fi + + exit 0 +} + +# Show the usage line when no arguments are specified. +if test $# -eq 0; then + show_usage + exit 1 +fi + +while test $# -gt 0; do + case $1 in + --usage) show_usage; exit 0;; + --help) show_help; exit 0;; + + # Installation overrides + --prefix=*) GTEST_PREFIX=${1#--prefix=};; + --exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};; + --libdir=*) GTEST_LIBDIR=${1#--libdir=};; + --includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};; + + # Installation queries + --prefix|--exec-prefix|--libdir|--includedir|--version) + if test -n "${do_query}"; then + show_usage + exit 1 + fi + do_query=${1#--} + ;; + + # Version checking + --min-version=*) + do_check_versions=yes + min_version=${1#--min-version=} + ;; + --max-version=*) + do_check_versions=yes + max_version=${1#--max-version=} + ;; + --exact-version=*) + do_check_versions=yes + exact_version=${1#--exact-version=} + ;; + + # Compiler flag output + --cppflags) echo_cppflags=yes;; + --cxxflags) echo_cxxflags=yes;; + --ldflags) echo_ldflags=yes;; + --libs) echo_libs=yes;; + + # Everything else is an error + *) show_usage; exit 1;; + esac + shift +done + +# These have defaults filled in by the configure script but can also be +# overridden by environment variables or command line parameters. +prefix="${GTEST_PREFIX:-@prefix@}" +exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}" +libdir="${GTEST_LIBDIR:-@libdir@}" +includedir="${GTEST_INCLUDEDIR:-@includedir@}" + +# We try and detect if our binary is not located at its installed location. If +# it's not, we provide variables pointing to the source and build tree rather +# than to the install tree. This allows building against a just-built gtest +# rather than an installed gtest. +bindir="@bindir@" +this_relative_bindir=`dirname $0` +this_bindir=`cd ${this_relative_bindir}; pwd -P` +if test "${this_bindir}" = "${this_bindir%${bindir}}"; then + # The path to the script doesn't end in the bindir sequence from Autoconf, + # assume that we are in a build tree. + build_dir=`dirname ${this_bindir}` + src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P` + + # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we + # should work to remove it, and/or remove libtool altogether, replacing it + # with direct references to the library and a link path. + gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_ldflags="" + + # We provide hooks to include from either the source or build dir, where the + # build dir is always preferred. This will potentially allow us to write + # build rules for generated headers and have them automatically be preferred + # over provided versions. + gtest_cppflags="-I${build_dir}/include -I${src_dir}/include" + gtest_cxxflags="@PTHREAD_CFLAGS@" +else + # We're using an installed gtest, although it may be staged under some + # prefix. Assume (as our own libraries do) that we can resolve the prefix, + # and are present in the dynamic link paths. + gtest_ldflags="-L${libdir}" + gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" + gtest_cppflags="-I${includedir}" + gtest_cxxflags="@PTHREAD_CFLAGS@" +fi + +# Do an installation query if requested. +if test -n "$do_query"; then + case $do_query in + prefix) echo $prefix; exit 0;; + exec-prefix) echo $exec_prefix; exit 0;; + libdir) echo $libdir; exit 0;; + includedir) echo $includedir; exit 0;; + version) echo $version; exit 0;; + *) show_usage; exit 1;; + esac +fi + +# Do a version check if requested. +if test "$do_check_versions" = "yes"; then + # Make sure we didn't receive a bad combination of parameters. + test "$echo_cppflags" = "yes" && show_usage && exit 1 + test "$echo_cxxflags" = "yes" && show_usage && exit 1 + test "$echo_ldflags" = "yes" && show_usage && exit 1 + test "$echo_libs" = "yes" && show_usage && exit 1 + + if test "$exact_version" != ""; then + check_versions $exact_version $exact_version + # unreachable + else + check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999} + # unreachable + fi +fi + +# Do the output in the correct order so that these can be used in-line of +# a compiler invocation. +output="" +test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags" +test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags" +test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags" +test "$echo_libs" = "yes" && output="$output $gtest_libs" +echo $output + +exit 0 diff --git a/src/test/gtest/scripts/pump.py b/src/test/gtest/scripts/pump.py new file mode 100755 index 00000000..5efb653c --- /dev/null +++ b/src/test/gtest/scripts/pump.py @@ -0,0 +1,855 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""pump v0.2.0 - Pretty Useful for Meta Programming. + +A tool for preprocessor meta programming. Useful for generating +repetitive boilerplate code. Especially useful for writing C++ +classes, functions, macros, and templates that need to work with +various number of arguments. + +USAGE: + pump.py SOURCE_FILE + +EXAMPLES: + pump.py foo.cc.pump + Converts foo.cc.pump to foo.cc. + +GRAMMAR: + CODE ::= ATOMIC_CODE* + ATOMIC_CODE ::= $var ID = EXPRESSION + | $var ID = [[ CODE ]] + | $range ID EXPRESSION..EXPRESSION + | $for ID SEPARATOR [[ CODE ]] + | $($) + | $ID + | $(EXPRESSION) + | $if EXPRESSION [[ CODE ]] ELSE_BRANCH + | [[ CODE ]] + | RAW_CODE + SEPARATOR ::= RAW_CODE | EMPTY + ELSE_BRANCH ::= $else [[ CODE ]] + | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH + | EMPTY + EXPRESSION has Python syntax. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys + + +TOKEN_TABLE = [ + (re.compile(r'\$var\s+'), '$var'), + (re.compile(r'\$elif\s+'), '$elif'), + (re.compile(r'\$else\s+'), '$else'), + (re.compile(r'\$for\s+'), '$for'), + (re.compile(r'\$if\s+'), '$if'), + (re.compile(r'\$range\s+'), '$range'), + (re.compile(r'\$[_A-Za-z]\w*'), '$id'), + (re.compile(r'\$\(\$\)'), '$($)'), + (re.compile(r'\$'), '$'), + (re.compile(r'\[\[\n?'), '[['), + (re.compile(r'\]\]\n?'), ']]'), + ] + + +class Cursor: + """Represents a position (line and column) in a text file.""" + + def __init__(self, line=-1, column=-1): + self.line = line + self.column = column + + def __eq__(self, rhs): + return self.line == rhs.line and self.column == rhs.column + + def __ne__(self, rhs): + return not self == rhs + + def __lt__(self, rhs): + return self.line < rhs.line or ( + self.line == rhs.line and self.column < rhs.column) + + def __le__(self, rhs): + return self < rhs or self == rhs + + def __gt__(self, rhs): + return rhs < self + + def __ge__(self, rhs): + return rhs <= self + + def __str__(self): + if self == Eof(): + return 'EOF' + else: + return '%s(%s)' % (self.line + 1, self.column) + + def __add__(self, offset): + return Cursor(self.line, self.column + offset) + + def __sub__(self, offset): + return Cursor(self.line, self.column - offset) + + def Clone(self): + """Returns a copy of self.""" + + return Cursor(self.line, self.column) + + +# Special cursor to indicate the end-of-file. +def Eof(): + """Returns the special cursor to denote the end-of-file.""" + return Cursor(-1, -1) + + +class Token: + """Represents a token in a Pump source file.""" + + def __init__(self, start=None, end=None, value=None, token_type=None): + if start is None: + self.start = Eof() + else: + self.start = start + if end is None: + self.end = Eof() + else: + self.end = end + self.value = value + self.token_type = token_type + + def __str__(self): + return 'Token @%s: \'%s\' type=%s' % ( + self.start, self.value, self.token_type) + + def Clone(self): + """Returns a copy of self.""" + + return Token(self.start.Clone(), self.end.Clone(), self.value, + self.token_type) + + +def StartsWith(lines, pos, string): + """Returns True iff the given position in lines starts with 'string'.""" + + return lines[pos.line][pos.column:].startswith(string) + + +def FindFirstInLine(line, token_table): + best_match_start = -1 + for (regex, token_type) in token_table: + m = regex.search(line) + if m: + # We found regex in lines + if best_match_start < 0 or m.start() < best_match_start: + best_match_start = m.start() + best_match_length = m.end() - m.start() + best_match_token_type = token_type + + if best_match_start < 0: + return None + + return (best_match_start, best_match_length, best_match_token_type) + + +def FindFirst(lines, token_table, cursor): + """Finds the first occurrence of any string in strings in lines.""" + + start = cursor.Clone() + cur_line_number = cursor.line + for line in lines[start.line:]: + if cur_line_number == start.line: + line = line[start.column:] + m = FindFirstInLine(line, token_table) + if m: + # We found a regex in line. + (start_column, length, token_type) = m + if cur_line_number == start.line: + start_column += start.column + found_start = Cursor(cur_line_number, start_column) + found_end = found_start + length + return MakeToken(lines, found_start, found_end, token_type) + cur_line_number += 1 + # We failed to find str in lines + return None + + +def SubString(lines, start, end): + """Returns a substring in lines.""" + + if end == Eof(): + end = Cursor(len(lines) - 1, len(lines[-1])) + + if start >= end: + return '' + + if start.line == end.line: + return lines[start.line][start.column:end.column] + + result_lines = ([lines[start.line][start.column:]] + + lines[start.line + 1:end.line] + + [lines[end.line][:end.column]]) + return ''.join(result_lines) + + +def StripMetaComments(str): + """Strip meta comments from each line in the given string.""" + + # First, completely remove lines containing nothing but a meta + # comment, including the trailing \n. + str = re.sub(r'^\s*\$\$.*\n', '', str) + + # Then, remove meta comments from contentful lines. + return re.sub(r'\s*\$\$.*', '', str) + + +def MakeToken(lines, start, end, token_type): + """Creates a new instance of Token.""" + + return Token(start, end, SubString(lines, start, end), token_type) + + +def ParseToken(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = regex.search(line) + if m and not m.start(): + return MakeToken(lines, pos, pos + m.end(), token_type) + else: + print 'ERROR: %s expected at %s.' % (token_type, pos) + sys.exit(1) + + +ID_REGEX = re.compile(r'[_A-Za-z]\w*') +EQ_REGEX = re.compile(r'=') +REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)') +OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*') +WHITE_SPACE_REGEX = re.compile(r'\s') +DOT_DOT_REGEX = re.compile(r'\.\.') + + +def Skip(lines, pos, regex): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m and not m.start(): + return pos + m.end() + else: + return pos + + +def SkipUntil(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m: + return pos + m.start() + else: + print ('ERROR: %s expected on line %s after column %s.' % + (token_type, pos.line + 1, pos.column)) + sys.exit(1) + + +def ParseExpTokenInParens(lines, pos): + def ParseInParens(pos): + pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX) + pos = Skip(lines, pos, r'\(') + pos = Parse(pos) + pos = Skip(lines, pos, r'\)') + return pos + + def Parse(pos): + pos = SkipUntil(lines, pos, r'\(|\)', ')') + if SubString(lines, pos, pos + 1) == '(': + pos = Parse(pos + 1) + pos = Skip(lines, pos, r'\)') + return Parse(pos) + else: + return pos + + start = pos.Clone() + pos = ParseInParens(pos) + return MakeToken(lines, start, pos, 'exp') + + +def RStripNewLineFromToken(token): + if token.value.endswith('\n'): + return Token(token.start, token.end, token.value[:-1], token.token_type) + else: + return token + + +def TokenizeLines(lines, pos): + while True: + found = FindFirst(lines, TOKEN_TABLE, pos) + if not found: + yield MakeToken(lines, pos, Eof(), 'code') + return + + if found.start == pos: + prev_token = None + prev_token_rstripped = None + else: + prev_token = MakeToken(lines, pos, found.start, 'code') + prev_token_rstripped = RStripNewLineFromToken(prev_token) + + if found.token_type == '$var': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + eq_token = ParseToken(lines, pos, EQ_REGEX, '=') + yield eq_token + pos = Skip(lines, eq_token.end, r'\s*') + + if SubString(lines, pos, pos + 2) != '[[': + exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp') + yield exp_token + pos = Cursor(exp_token.end.line + 1, 0) + elif found.token_type == '$for': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX) + elif found.token_type == '$range': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..') + yield MakeToken(lines, pos, dots_pos, 'exp') + yield MakeToken(lines, dots_pos, dots_pos + 2, '..') + pos = dots_pos + 2 + new_pos = Cursor(pos.line + 1, 0) + yield MakeToken(lines, pos, new_pos, 'exp') + pos = new_pos + elif found.token_type == '$': + if prev_token: + yield prev_token + yield found + exp_token = ParseExpTokenInParens(lines, found.end) + yield exp_token + pos = exp_token.end + elif (found.token_type == ']]' or found.token_type == '$if' or + found.token_type == '$elif' or found.token_type == '$else'): + if prev_token_rstripped: + yield prev_token_rstripped + yield found + pos = found.end + else: + if prev_token: + yield prev_token + yield found + pos = found.end + + +def Tokenize(s): + """A generator that yields the tokens in the given string.""" + if s != '': + lines = s.splitlines(True) + for token in TokenizeLines(lines, Cursor(0, 0)): + yield token + + +class CodeNode: + def __init__(self, atomic_code_list=None): + self.atomic_code = atomic_code_list + + +class VarNode: + def __init__(self, identifier=None, atomic_code=None): + self.identifier = identifier + self.atomic_code = atomic_code + + +class RangeNode: + def __init__(self, identifier=None, exp1=None, exp2=None): + self.identifier = identifier + self.exp1 = exp1 + self.exp2 = exp2 + + +class ForNode: + def __init__(self, identifier=None, sep=None, code=None): + self.identifier = identifier + self.sep = sep + self.code = code + + +class ElseNode: + def __init__(self, else_branch=None): + self.else_branch = else_branch + + +class IfNode: + def __init__(self, exp=None, then_branch=None, else_branch=None): + self.exp = exp + self.then_branch = then_branch + self.else_branch = else_branch + + +class RawCodeNode: + def __init__(self, token=None): + self.raw_code = token + + +class LiteralDollarNode: + def __init__(self, token): + self.token = token + + +class ExpNode: + def __init__(self, token, python_exp): + self.token = token + self.python_exp = python_exp + + +def PopFront(a_list): + head = a_list[0] + a_list[:1] = [] + return head + + +def PushFront(a_list, elem): + a_list[:0] = [elem] + + +def PopToken(a_list, token_type=None): + token = PopFront(a_list) + if token_type is not None and token.token_type != token_type: + print 'ERROR: %s expected at %s' % (token_type, token.start) + print 'ERROR: %s found instead' % (token,) + sys.exit(1) + + return token + + +def PeekToken(a_list): + if not a_list: + return None + + return a_list[0] + + +def ParseExpNode(token): + python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value) + return ExpNode(token, python_exp) + + +def ParseElseNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + next = PeekToken(tokens) + if not next: + return None + if next.token_type == '$else': + Pop('$else') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + elif next.token_type == '$elif': + Pop('$elif') + exp = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + inner_else_node = ParseElseNode(tokens) + return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)]) + elif not next.value.strip(): + Pop('code') + return ParseElseNode(tokens) + else: + return None + + +def ParseAtomicCodeNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + head = PopFront(tokens) + t = head.token_type + if t == 'code': + return RawCodeNode(head) + elif t == '$var': + id_token = Pop('id') + Pop('=') + next = PeekToken(tokens) + if next.token_type == 'exp': + exp_token = Pop() + return VarNode(id_token, ParseExpNode(exp_token)) + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return VarNode(id_token, code_node) + elif t == '$for': + id_token = Pop('id') + next_token = PeekToken(tokens) + if next_token.token_type == 'code': + sep_token = next_token + Pop('code') + else: + sep_token = None + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return ForNode(id_token, sep_token, code_node) + elif t == '$if': + exp_token = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + else_node = ParseElseNode(tokens) + return IfNode(ParseExpNode(exp_token), code_node, else_node) + elif t == '$range': + id_token = Pop('id') + exp1_token = Pop('exp') + Pop('..') + exp2_token = Pop('exp') + return RangeNode(id_token, ParseExpNode(exp1_token), + ParseExpNode(exp2_token)) + elif t == '$id': + return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id')) + elif t == '$($)': + return LiteralDollarNode(head) + elif t == '$': + exp_token = Pop('exp') + return ParseExpNode(exp_token) + elif t == '[[': + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + else: + PushFront(tokens, head) + return None + + +def ParseCodeNode(tokens): + atomic_code_list = [] + while True: + if not tokens: + break + atomic_code_node = ParseAtomicCodeNode(tokens) + if atomic_code_node: + atomic_code_list.append(atomic_code_node) + else: + break + return CodeNode(atomic_code_list) + + +def ParseToAST(pump_src_text): + """Convert the given Pump source text into an AST.""" + tokens = list(Tokenize(pump_src_text)) + code_node = ParseCodeNode(tokens) + return code_node + + +class Env: + def __init__(self): + self.variables = [] + self.ranges = [] + + def Clone(self): + clone = Env() + clone.variables = self.variables[:] + clone.ranges = self.ranges[:] + return clone + + def PushVariable(self, var, value): + # If value looks like an int, store it as an int. + try: + int_value = int(value) + if ('%s' % int_value) == value: + value = int_value + except Exception: + pass + self.variables[:0] = [(var, value)] + + def PopVariable(self): + self.variables[:1] = [] + + def PushRange(self, var, lower, upper): + self.ranges[:0] = [(var, lower, upper)] + + def PopRange(self): + self.ranges[:1] = [] + + def GetValue(self, identifier): + for (var, value) in self.variables: + if identifier == var: + return value + + print 'ERROR: meta variable %s is undefined.' % (identifier,) + sys.exit(1) + + def EvalExp(self, exp): + try: + result = eval(exp.python_exp) + except Exception, e: + print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e) + print ('ERROR: failed to evaluate meta expression %s at %s' % + (exp.python_exp, exp.token.start)) + sys.exit(1) + return result + + def GetRange(self, identifier): + for (var, lower, upper) in self.ranges: + if identifier == var: + return (lower, upper) + + print 'ERROR: range %s is undefined.' % (identifier,) + sys.exit(1) + + +class Output: + def __init__(self): + self.string = '' + + def GetLastLine(self): + index = self.string.rfind('\n') + if index < 0: + return '' + + return self.string[index + 1:] + + def Append(self, s): + self.string += s + + +def RunAtomicCode(env, node, output): + if isinstance(node, VarNode): + identifier = node.identifier.value.strip() + result = Output() + RunAtomicCode(env.Clone(), node.atomic_code, result) + value = result.string + env.PushVariable(identifier, value) + elif isinstance(node, RangeNode): + identifier = node.identifier.value.strip() + lower = int(env.EvalExp(node.exp1)) + upper = int(env.EvalExp(node.exp2)) + env.PushRange(identifier, lower, upper) + elif isinstance(node, ForNode): + identifier = node.identifier.value.strip() + if node.sep is None: + sep = '' + else: + sep = node.sep.value + (lower, upper) = env.GetRange(identifier) + for i in range(lower, upper + 1): + new_env = env.Clone() + new_env.PushVariable(identifier, i) + RunCode(new_env, node.code, output) + if i != upper: + output.Append(sep) + elif isinstance(node, RawCodeNode): + output.Append(node.raw_code.value) + elif isinstance(node, IfNode): + cond = env.EvalExp(node.exp) + if cond: + RunCode(env.Clone(), node.then_branch, output) + elif node.else_branch is not None: + RunCode(env.Clone(), node.else_branch, output) + elif isinstance(node, ExpNode): + value = env.EvalExp(node) + output.Append('%s' % (value,)) + elif isinstance(node, LiteralDollarNode): + output.Append('$') + elif isinstance(node, CodeNode): + RunCode(env.Clone(), node, output) + else: + print 'BAD' + print node + sys.exit(1) + + +def RunCode(env, code_node, output): + for atomic_code in code_node.atomic_code: + RunAtomicCode(env, atomic_code, output) + + +def IsSingleLineComment(cur_line): + return '//' in cur_line + + +def IsInPreprocessorDirective(prev_lines, cur_line): + if cur_line.lstrip().startswith('#'): + return True + return prev_lines and prev_lines[-1].endswith('\\') + + +def WrapComment(line, output): + loc = line.find('//') + before_comment = line[:loc].rstrip() + if before_comment == '': + indent = loc + else: + output.append(before_comment) + indent = len(before_comment) - len(before_comment.lstrip()) + prefix = indent*' ' + '// ' + max_len = 80 - len(prefix) + comment = line[loc + 2:].strip() + segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != ''] + cur_line = '' + for seg in segs: + if len((cur_line + seg).rstrip()) < max_len: + cur_line += seg + else: + if cur_line.strip() != '': + output.append(prefix + cur_line.rstrip()) + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapCode(line, line_concat, output): + indent = len(line) - len(line.lstrip()) + prefix = indent*' ' # Prefix of the current line + max_len = 80 - indent - len(line_concat) # Maximum length of the current line + new_prefix = prefix + 4*' ' # Prefix of a continuation line + new_max_len = max_len - 4 # Maximum length of a continuation line + # Prefers to wrap a line after a ',' or ';'. + segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != ''] + cur_line = '' # The current line without leading spaces. + for seg in segs: + # If the line is still too long, wrap at a space. + while cur_line == '' and len(seg.strip()) > max_len: + seg = seg.lstrip() + split_at = seg.rfind(' ', 0, max_len) + output.append(prefix + seg[:split_at].strip() + line_concat) + seg = seg[split_at + 1:] + prefix = new_prefix + max_len = new_max_len + + if len((cur_line + seg).rstrip()) < max_len: + cur_line = (cur_line + seg).lstrip() + else: + output.append(prefix + cur_line.rstrip() + line_concat) + prefix = new_prefix + max_len = new_max_len + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapPreprocessorDirective(line, output): + WrapCode(line, ' \\', output) + + +def WrapPlainCode(line, output): + WrapCode(line, '', output) + + +def IsMultiLineIWYUPragma(line): + return re.search(r'/\* IWYU pragma: ', line) + + +def IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or + re.match(r'^#include\s', line) or + # Don't break IWYU pragmas, either; that causes iwyu.py problems. + re.search(r'// IWYU pragma: ', line)) + + +def WrapLongLine(line, output): + line = line.rstrip() + if len(line) <= 80: + output.append(line) + elif IsSingleLineComment(line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapComment(line, output) + elif IsInPreprocessorDirective(output, line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapPreprocessorDirective(line, output) + elif IsMultiLineIWYUPragma(line): + output.append(line) + else: + WrapPlainCode(line, output) + + +def BeautifyCode(string): + lines = string.splitlines() + output = [] + for line in lines: + WrapLongLine(line, output) + output2 = [line.rstrip() for line in output] + return '\n'.join(output2) + '\n' + + +def ConvertFromPumpSource(src_text): + """Return the text generated from the given Pump source text.""" + ast = ParseToAST(StripMetaComments(src_text)) + output = Output() + RunCode(Env(), ast, output) + return BeautifyCode(output.string) + + +def main(argv): + if len(argv) == 1: + print __doc__ + sys.exit(1) + + file_path = argv[-1] + output_str = ConvertFromPumpSource(file(file_path, 'r').read()) + if file_path.endswith('.pump'): + output_file_path = file_path[:-5] + else: + output_file_path = '-' + if output_file_path == '-': + print output_str, + else: + output_file = file(output_file_path, 'w') + output_file.write('// This file was GENERATED by command:\n') + output_file.write('// %s %s\n' % + (os.path.basename(__file__), os.path.basename(file_path))) + output_file.write('// DO NOT EDIT BY HAND!!!\n\n') + output_file.write(output_str) + output_file.close() + + +if __name__ == '__main__': + main(sys.argv) diff --git a/src/test/gtest/scripts/release_docs.py b/src/test/gtest/scripts/release_docs.py new file mode 100755 index 00000000..1291347f --- /dev/null +++ b/src/test/gtest/scripts/release_docs.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +# +# Copyright 2013 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Script for branching Google Test/Mock wiki pages for a new version. + +SYNOPSIS + release_docs.py NEW_RELEASE_VERSION + + Google Test and Google Mock's external user documentation is in + interlinked wiki files. When we release a new version of + Google Test or Google Mock, we need to branch the wiki files + such that users of a specific version of Google Test/Mock can + look up documenation relevant for that version. This script + automates that process by: + + - branching the current wiki pages (which document the + behavior of the SVN trunk head) to pages for the specified + version (e.g. branching FAQ.wiki to V2_6_FAQ.wiki when + NEW_RELEASE_VERSION is 2.6); + - updating the links in the branched files to point to the branched + version (e.g. a link in V2_6_FAQ.wiki that pointed to + Primer.wiki#Anchor will now point to V2_6_Primer.wiki#Anchor). + + NOTE: NEW_RELEASE_VERSION must be a NEW version number for + which the wiki pages don't yet exist; otherwise you'll get SVN + errors like "svn: Path 'V1_7_PumpManual.wiki' is not a + directory" when running the script. + +EXAMPLE + $ cd PATH/TO/GTEST_SVN_WORKSPACE/trunk + $ scripts/release_docs.py 2.6 # create wiki pages for v2.6 + $ svn status # verify the file list + $ svn diff # verify the file contents + $ svn commit -m "release wiki pages for v2.6" +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys + +import common + + +# Wiki pages that shouldn't be branched for every gtest/gmock release. +GTEST_UNVERSIONED_WIKIS = ['DevGuide.wiki'] +GMOCK_UNVERSIONED_WIKIS = [ + 'DesignDoc.wiki', + 'DevGuide.wiki', + 'KnownIssues.wiki' + ] + + +def DropWikiSuffix(wiki_filename): + """Removes the .wiki suffix (if any) from the given filename.""" + + return (wiki_filename[:-len('.wiki')] if wiki_filename.endswith('.wiki') + else wiki_filename) + + +class WikiBrancher(object): + """Branches ...""" + + def __init__(self, dot_version): + self.project, svn_root_path = common.GetSvnInfo() + if self.project not in ('googletest', 'googlemock'): + sys.exit('This script must be run in a gtest or gmock SVN workspace.') + self.wiki_dir = svn_root_path + '/wiki' + # Turn '2.6' to 'V2_6_'. + self.version_prefix = 'V' + dot_version.replace('.', '_') + '_' + self.files_to_branch = self.GetFilesToBranch() + page_names = [DropWikiSuffix(f) for f in self.files_to_branch] + # A link to Foo.wiki is in one of the following forms: + # [Foo words] + # [Foo#Anchor words] + # [http://code.google.com/.../wiki/Foo words] + # [http://code.google.com/.../wiki/Foo#Anchor words] + # We want to replace 'Foo' with 'V2_6_Foo' in the above cases. + self.search_for_re = re.compile( + # This regex matches either + # [Foo + # or + # /wiki/Foo + # followed by a space or a #, where Foo is the name of an + # unversioned wiki page. + r'(\[|/wiki/)(%s)([ #])' % '|'.join(page_names)) + self.replace_with = r'\1%s\2\3' % (self.version_prefix,) + + def GetFilesToBranch(self): + """Returns a list of .wiki file names that need to be branched.""" + + unversioned_wikis = (GTEST_UNVERSIONED_WIKIS if self.project == 'googletest' + else GMOCK_UNVERSIONED_WIKIS) + return [f for f in os.listdir(self.wiki_dir) + if (f.endswith('.wiki') and + not re.match(r'^V\d', f) and # Excluded versioned .wiki files. + f not in unversioned_wikis)] + + def BranchFiles(self): + """Branches the .wiki files needed to be branched.""" + + print 'Branching %d .wiki files:' % (len(self.files_to_branch),) + os.chdir(self.wiki_dir) + for f in self.files_to_branch: + command = 'svn cp %s %s%s' % (f, self.version_prefix, f) + print command + os.system(command) + + def UpdateLinksInBranchedFiles(self): + + for f in self.files_to_branch: + source_file = os.path.join(self.wiki_dir, f) + versioned_file = os.path.join(self.wiki_dir, self.version_prefix + f) + print 'Updating links in %s.' % (versioned_file,) + text = file(source_file, 'r').read() + new_text = self.search_for_re.sub(self.replace_with, text) + file(versioned_file, 'w').write(new_text) + + +def main(): + if len(sys.argv) != 2: + sys.exit(__doc__) + + brancher = WikiBrancher(sys.argv[1]) + brancher.BranchFiles() + brancher.UpdateLinksInBranchedFiles() + + +if __name__ == '__main__': + main() diff --git a/src/test/gtest/scripts/upload.py b/src/test/gtest/scripts/upload.py new file mode 100755 index 00000000..6e6f9a14 --- /dev/null +++ b/src/test/gtest/scripts/upload.py @@ -0,0 +1,1387 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# 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. + +"""Tool for uploading diffs from a version control system to the codereview app. + +Usage summary: upload.py [options] [-- diff_options] + +Diff options are passed to the diff command of the underlying system. + +Supported version control systems: + Git + Mercurial + Subversion + +It is important for Git/Mercurial users to specify a tree/node/branch to diff +against by using the '--rev' option. +""" +# This code is derived from appcfg.py in the App Engine SDK (open source), +# and from ASPN recipe #146306. + +import cookielib +import getpass +import logging +import md5 +import mimetypes +import optparse +import os +import re +import socket +import subprocess +import sys +import urllib +import urllib2 +import urlparse + +try: + import readline +except ImportError: + pass + +# The logging verbosity: +# 0: Errors only. +# 1: Status messages. +# 2: Info logs. +# 3: Debug logs. +verbosity = 1 + +# Max size of patch or base file. +MAX_UPLOAD_SIZE = 900 * 1024 + + +def GetEmail(prompt): + """Prompts the user for their email address and returns it. + + The last used email address is saved to a file and offered up as a suggestion + to the user. If the user presses enter without typing in anything the last + used email address is used. If the user enters a new address, it is saved + for next time we prompt. + + """ + last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") + last_email = "" + if os.path.exists(last_email_file_name): + try: + last_email_file = open(last_email_file_name, "r") + last_email = last_email_file.readline().strip("\n") + last_email_file.close() + prompt += " [%s]" % last_email + except IOError, e: + pass + email = raw_input(prompt + ": ").strip() + if email: + try: + last_email_file = open(last_email_file_name, "w") + last_email_file.write(email) + last_email_file.close() + except IOError, e: + pass + else: + email = last_email + return email + + +def StatusUpdate(msg): + """Print a status message to stdout. + + If 'verbosity' is greater than 0, print the message. + + Args: + msg: The string to print. + """ + if verbosity > 0: + print msg + + +def ErrorExit(msg): + """Print an error message to stderr and exit.""" + print >>sys.stderr, msg + sys.exit(1) + + +class ClientLoginError(urllib2.HTTPError): + """Raised to indicate there was an error authenticating with ClientLogin.""" + + def __init__(self, url, code, msg, headers, args): + urllib2.HTTPError.__init__(self, url, code, msg, headers, None) + self.args = args + self.reason = args["Error"] + + +class AbstractRpcServer(object): + """Provides a common interface for a simple RPC server.""" + + def __init__(self, host, auth_function, host_override=None, extra_headers={}, + save_cookies=False): + """Creates a new HttpRpcServer. + + Args: + host: The host to send requests to. + auth_function: A function that takes no arguments and returns an + (email, password) tuple when called. Will be called if authentication + is required. + host_override: The host header to send to the server (defaults to host). + extra_headers: A dict of extra headers to append to every request. + save_cookies: If True, save the authentication cookies to local disk. + If False, use an in-memory cookiejar instead. Subclasses must + implement this functionality. Defaults to False. + """ + self.host = host + self.host_override = host_override + self.auth_function = auth_function + self.authenticated = False + self.extra_headers = extra_headers + self.save_cookies = save_cookies + self.opener = self._GetOpener() + if self.host_override: + logging.info("Server: %s; Host: %s", self.host, self.host_override) + else: + logging.info("Server: %s", self.host) + + def _GetOpener(self): + """Returns an OpenerDirector for making HTTP requests. + + Returns: + A urllib2.OpenerDirector object. + """ + raise NotImplementedError() + + def _CreateRequest(self, url, data=None): + """Creates a new urllib request.""" + logging.debug("Creating request for: '%s' with payload:\n%s", url, data) + req = urllib2.Request(url, data=data) + if self.host_override: + req.add_header("Host", self.host_override) + for key, value in self.extra_headers.iteritems(): + req.add_header(key, value) + return req + + def _GetAuthToken(self, email, password): + """Uses ClientLogin to authenticate the user, returning an auth token. + + Args: + email: The user's email address + password: The user's password + + Raises: + ClientLoginError: If there was an error authenticating with ClientLogin. + HTTPError: If there was some other form of HTTP error. + + Returns: + The authentication token returned by ClientLogin. + """ + account_type = "GOOGLE" + if self.host.endswith(".google.com"): + # Needed for use inside Google. + account_type = "HOSTED" + req = self._CreateRequest( + url="https://www.google.com/accounts/ClientLogin", + data=urllib.urlencode({ + "Email": email, + "Passwd": password, + "service": "ah", + "source": "rietveld-codereview-upload", + "accountType": account_type, + }), + ) + try: + response = self.opener.open(req) + response_body = response.read() + response_dict = dict(x.split("=") + for x in response_body.split("\n") if x) + return response_dict["Auth"] + except urllib2.HTTPError, e: + if e.code == 403: + body = e.read() + response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) + raise ClientLoginError(req.get_full_url(), e.code, e.msg, + e.headers, response_dict) + else: + raise + + def _GetAuthCookie(self, auth_token): + """Fetches authentication cookies for an authentication token. + + Args: + auth_token: The authentication token returned by ClientLogin. + + Raises: + HTTPError: If there was an error fetching the authentication cookies. + """ + # This is a dummy value to allow us to identify when we're successful. + continue_location = "http://localhost/" + args = {"continue": continue_location, "auth": auth_token} + req = self._CreateRequest("http://%s/_ah/login?%s" % + (self.host, urllib.urlencode(args))) + try: + response = self.opener.open(req) + except urllib2.HTTPError, e: + response = e + if (response.code != 302 or + response.info()["location"] != continue_location): + raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, + response.headers, response.fp) + self.authenticated = True + + def _Authenticate(self): + """Authenticates the user. + + The authentication process works as follows: + 1) We get a username and password from the user + 2) We use ClientLogin to obtain an AUTH token for the user + (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). + 3) We pass the auth token to /_ah/login on the server to obtain an + authentication cookie. If login was successful, it tries to redirect + us to the URL we provided. + + If we attempt to access the upload API without first obtaining an + authentication cookie, it returns a 401 response and directs us to + authenticate ourselves with ClientLogin. + """ + for i in range(3): + credentials = self.auth_function() + try: + auth_token = self._GetAuthToken(credentials[0], credentials[1]) + except ClientLoginError, e: + if e.reason == "BadAuthentication": + print >>sys.stderr, "Invalid username or password." + continue + if e.reason == "CaptchaRequired": + print >>sys.stderr, ( + "Please go to\n" + "https://www.google.com/accounts/DisplayUnlockCaptcha\n" + "and verify you are a human. Then try again.") + break + if e.reason == "NotVerified": + print >>sys.stderr, "Account not verified." + break + if e.reason == "TermsNotAgreed": + print >>sys.stderr, "User has not agreed to TOS." + break + if e.reason == "AccountDeleted": + print >>sys.stderr, "The user account has been deleted." + break + if e.reason == "AccountDisabled": + print >>sys.stderr, "The user account has been disabled." + break + if e.reason == "ServiceDisabled": + print >>sys.stderr, ("The user's access to the service has been " + "disabled.") + break + if e.reason == "ServiceUnavailable": + print >>sys.stderr, "The service is not available; try again later." + break + raise + self._GetAuthCookie(auth_token) + return + + def Send(self, request_path, payload=None, + content_type="application/octet-stream", + timeout=None, + **kwargs): + """Sends an RPC and returns the response. + + Args: + request_path: The path to send the request to, eg /api/appversion/create. + payload: The body of the request, or None to send an empty request. + content_type: The Content-Type header to use. + timeout: timeout in seconds; default None i.e. no timeout. + (Note: for large requests on OS X, the timeout doesn't work right.) + kwargs: Any keyword arguments are converted into query string parameters. + + Returns: + The response body, as a string. + """ + # TODO: Don't require authentication. Let the server say + # whether it is necessary. + if not self.authenticated: + self._Authenticate() + + old_timeout = socket.getdefaulttimeout() + socket.setdefaulttimeout(timeout) + try: + tries = 0 + while True: + tries += 1 + args = dict(kwargs) + url = "http://%s%s" % (self.host, request_path) + if args: + url += "?" + urllib.urlencode(args) + req = self._CreateRequest(url=url, data=payload) + req.add_header("Content-Type", content_type) + try: + f = self.opener.open(req) + response = f.read() + f.close() + return response + except urllib2.HTTPError, e: + if tries > 3: + raise + elif e.code == 401: + self._Authenticate() +## elif e.code >= 500 and e.code < 600: +## # Server Error - try again. +## continue + else: + raise + finally: + socket.setdefaulttimeout(old_timeout) + + +class HttpRpcServer(AbstractRpcServer): + """Provides a simplified RPC-style interface for HTTP requests.""" + + def _Authenticate(self): + """Save the cookie jar after authentication.""" + super(HttpRpcServer, self)._Authenticate() + if self.save_cookies: + StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) + self.cookie_jar.save() + + def _GetOpener(self): + """Returns an OpenerDirector that supports cookies and ignores redirects. + + Returns: + A urllib2.OpenerDirector object. + """ + opener = urllib2.OpenerDirector() + opener.add_handler(urllib2.ProxyHandler()) + opener.add_handler(urllib2.UnknownHandler()) + opener.add_handler(urllib2.HTTPHandler()) + opener.add_handler(urllib2.HTTPDefaultErrorHandler()) + opener.add_handler(urllib2.HTTPSHandler()) + opener.add_handler(urllib2.HTTPErrorProcessor()) + if self.save_cookies: + self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") + self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) + if os.path.exists(self.cookie_file): + try: + self.cookie_jar.load() + self.authenticated = True + StatusUpdate("Loaded authentication cookies from %s" % + self.cookie_file) + except (cookielib.LoadError, IOError): + # Failed to load cookies - just ignore them. + pass + else: + # Create an empty cookie file with mode 600 + fd = os.open(self.cookie_file, os.O_CREAT, 0600) + os.close(fd) + # Always chmod the cookie file + os.chmod(self.cookie_file, 0600) + else: + # Don't save cookies across runs of update.py. + self.cookie_jar = cookielib.CookieJar() + opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) + return opener + + +parser = optparse.OptionParser(usage="%prog [options] [-- diff_options]") +parser.add_option("-y", "--assume_yes", action="store_true", + dest="assume_yes", default=False, + help="Assume that the answer to yes/no questions is 'yes'.") +# Logging +group = parser.add_option_group("Logging options") +group.add_option("-q", "--quiet", action="store_const", const=0, + dest="verbose", help="Print errors only.") +group.add_option("-v", "--verbose", action="store_const", const=2, + dest="verbose", default=1, + help="Print info level logs (default).") +group.add_option("--noisy", action="store_const", const=3, + dest="verbose", help="Print all logs.") +# Review server +group = parser.add_option_group("Review server options") +group.add_option("-s", "--server", action="store", dest="server", + default="codereview.appspot.com", + metavar="SERVER", + help=("The server to upload to. The format is host[:port]. " + "Defaults to 'codereview.appspot.com'.")) +group.add_option("-e", "--email", action="store", dest="email", + metavar="EMAIL", default=None, + help="The username to use. Will prompt if omitted.") +group.add_option("-H", "--host", action="store", dest="host", + metavar="HOST", default=None, + help="Overrides the Host header sent with all RPCs.") +group.add_option("--no_cookies", action="store_false", + dest="save_cookies", default=True, + help="Do not save authentication cookies to local disk.") +# Issue +group = parser.add_option_group("Issue options") +group.add_option("-d", "--description", action="store", dest="description", + metavar="DESCRIPTION", default=None, + help="Optional description when creating an issue.") +group.add_option("-f", "--description_file", action="store", + dest="description_file", metavar="DESCRIPTION_FILE", + default=None, + help="Optional path of a file that contains " + "the description when creating an issue.") +group.add_option("-r", "--reviewers", action="store", dest="reviewers", + metavar="REVIEWERS", default=None, + help="Add reviewers (comma separated email addresses).") +group.add_option("--cc", action="store", dest="cc", + metavar="CC", default=None, + help="Add CC (comma separated email addresses).") +# Upload options +group = parser.add_option_group("Patch options") +group.add_option("-m", "--message", action="store", dest="message", + metavar="MESSAGE", default=None, + help="A message to identify the patch. " + "Will prompt if omitted.") +group.add_option("-i", "--issue", type="int", action="store", + metavar="ISSUE", default=None, + help="Issue number to which to add. Defaults to new issue.") +group.add_option("--download_base", action="store_true", + dest="download_base", default=False, + help="Base files will be downloaded by the server " + "(side-by-side diffs may not work on files with CRs).") +group.add_option("--rev", action="store", dest="revision", + metavar="REV", default=None, + help="Branch/tree/revision to diff against (used by DVCS).") +group.add_option("--send_mail", action="store_true", + dest="send_mail", default=False, + help="Send notification email to reviewers.") + + +def GetRpcServer(options): + """Returns an instance of an AbstractRpcServer. + + Returns: + A new AbstractRpcServer, on which RPC calls can be made. + """ + + rpc_server_class = HttpRpcServer + + def GetUserCredentials(): + """Prompts the user for a username and password.""" + email = options.email + if email is None: + email = GetEmail("Email (login for uploading to %s)" % options.server) + password = getpass.getpass("Password for %s: " % email) + return (email, password) + + # If this is the dev_appserver, use fake authentication. + host = (options.host or options.server).lower() + if host == "localhost" or host.startswith("localhost:"): + email = options.email + if email is None: + email = "test@example.com" + logging.info("Using debug user %s. Override with --email" % email) + server = rpc_server_class( + options.server, + lambda: (email, "password"), + host_override=options.host, + extra_headers={"Cookie": + 'dev_appserver_login="%s:False"' % email}, + save_cookies=options.save_cookies) + # Don't try to talk to ClientLogin. + server.authenticated = True + return server + + return rpc_server_class(options.server, GetUserCredentials, + host_override=options.host, + save_cookies=options.save_cookies) + + +def EncodeMultipartFormData(fields, files): + """Encode form fields for multipart/form-data. + + Args: + fields: A sequence of (name, value) elements for regular form fields. + files: A sequence of (name, filename, value) elements for data to be + uploaded as files. + Returns: + (content_type, body) ready for httplib.HTTP instance. + + Source: + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 + """ + BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' + CRLF = '\r\n' + lines = [] + for (key, value) in fields: + lines.append('--' + BOUNDARY) + lines.append('Content-Disposition: form-data; name="%s"' % key) + lines.append('') + lines.append(value) + for (key, filename, value) in files: + lines.append('--' + BOUNDARY) + lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)) + lines.append('Content-Type: %s' % GetContentType(filename)) + lines.append('') + lines.append(value) + lines.append('--' + BOUNDARY + '--') + lines.append('') + body = CRLF.join(lines) + content_type = 'multipart/form-data; boundary=%s' % BOUNDARY + return content_type, body + + +def GetContentType(filename): + """Helper to guess the content-type from the filename.""" + return mimetypes.guess_type(filename)[0] or 'application/octet-stream' + + +# Use a shell for subcommands on Windows to get a PATH search. +use_shell = sys.platform.startswith("win") + +def RunShellWithReturnCode(command, print_output=False, + universal_newlines=True): + """Executes a command and returns the output from stdout and the return code. + + Args: + command: Command to execute. + print_output: If True, the output is printed to stdout. + If False, both stdout and stderr are ignored. + universal_newlines: Use universal_newlines flag (default: True). + + Returns: + Tuple (output, return code) + """ + logging.info("Running %s", command) + p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=use_shell, universal_newlines=universal_newlines) + if print_output: + output_array = [] + while True: + line = p.stdout.readline() + if not line: + break + print line.strip("\n") + output_array.append(line) + output = "".join(output_array) + else: + output = p.stdout.read() + p.wait() + errout = p.stderr.read() + if print_output and errout: + print >>sys.stderr, errout + p.stdout.close() + p.stderr.close() + return output, p.returncode + + +def RunShell(command, silent_ok=False, universal_newlines=True, + print_output=False): + data, retcode = RunShellWithReturnCode(command, print_output, + universal_newlines) + if retcode: + ErrorExit("Got error status from %s:\n%s" % (command, data)) + if not silent_ok and not data: + ErrorExit("No output from %s" % command) + return data + + +class VersionControlSystem(object): + """Abstract base class providing an interface to the VCS.""" + + def __init__(self, options): + """Constructor. + + Args: + options: Command line options. + """ + self.options = options + + def GenerateDiff(self, args): + """Return the current diff as a string. + + Args: + args: Extra arguments to pass to the diff command. + """ + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + def GetUnknownFiles(self): + """Return a list of files unknown to the VCS.""" + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + def CheckForUnknownFiles(self): + """Show an "are you sure?" prompt if there are unknown files.""" + unknown_files = self.GetUnknownFiles() + if unknown_files: + print "The following files are not added to version control:" + for line in unknown_files: + print line + prompt = "Are you sure to continue?(y/N) " + answer = raw_input(prompt).strip() + if answer != "y": + ErrorExit("User aborted") + + def GetBaseFile(self, filename): + """Get the content of the upstream version of a file. + + Returns: + A tuple (base_content, new_content, is_binary, status) + base_content: The contents of the base file. + new_content: For text files, this is empty. For binary files, this is + the contents of the new file, since the diff output won't contain + information to reconstruct the current file. + is_binary: True iff the file is binary. + status: The status of the file. + """ + + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + + def GetBaseFiles(self, diff): + """Helper that calls GetBase file for each file in the patch. + + Returns: + A dictionary that maps from filename to GetBaseFile's tuple. Filenames + are retrieved based on lines that start with "Index:" or + "Property changes on:". + """ + files = {} + for line in diff.splitlines(True): + if line.startswith('Index:') or line.startswith('Property changes on:'): + unused, filename = line.split(':', 1) + # On Windows if a file has property changes its filename uses '\' + # instead of '/'. + filename = filename.strip().replace('\\', '/') + files[filename] = self.GetBaseFile(filename) + return files + + + def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, + files): + """Uploads the base files (and if necessary, the current ones as well).""" + + def UploadFile(filename, file_id, content, is_binary, status, is_base): + """Uploads a file to the server.""" + file_too_large = False + if is_base: + type = "base" + else: + type = "current" + if len(content) > MAX_UPLOAD_SIZE: + print ("Not uploading the %s file for %s because it's too large." % + (type, filename)) + file_too_large = True + content = "" + checksum = md5.new(content).hexdigest() + if options.verbose > 0 and not file_too_large: + print "Uploading %s file for %s" % (type, filename) + url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) + form_fields = [("filename", filename), + ("status", status), + ("checksum", checksum), + ("is_binary", str(is_binary)), + ("is_current", str(not is_base)), + ] + if file_too_large: + form_fields.append(("file_too_large", "1")) + if options.email: + form_fields.append(("user", options.email)) + ctype, body = EncodeMultipartFormData(form_fields, + [("data", filename, content)]) + response_body = rpc_server.Send(url, body, + content_type=ctype) + if not response_body.startswith("OK"): + StatusUpdate(" --> %s" % response_body) + sys.exit(1) + + patches = dict() + [patches.setdefault(v, k) for k, v in patch_list] + for filename in patches.keys(): + base_content, new_content, is_binary, status = files[filename] + file_id_str = patches.get(filename) + if file_id_str.find("nobase") != -1: + base_content = None + file_id_str = file_id_str[file_id_str.rfind("_") + 1:] + file_id = int(file_id_str) + if base_content != None: + UploadFile(filename, file_id, base_content, is_binary, status, True) + if new_content != None: + UploadFile(filename, file_id, new_content, is_binary, status, False) + + def IsImage(self, filename): + """Returns true if the filename has an image extension.""" + mimetype = mimetypes.guess_type(filename)[0] + if not mimetype: + return False + return mimetype.startswith("image/") + + +class SubversionVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Subversion.""" + + def __init__(self, options): + super(SubversionVCS, self).__init__(options) + if self.options.revision: + match = re.match(r"(\d+)(:(\d+))?", self.options.revision) + if not match: + ErrorExit("Invalid Subversion revision %s." % self.options.revision) + self.rev_start = match.group(1) + self.rev_end = match.group(3) + else: + self.rev_start = self.rev_end = None + # Cache output from "svn list -r REVNO dirname". + # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). + self.svnls_cache = {} + # SVN base URL is required to fetch files deleted in an older revision. + # Result is cached to not guess it over and over again in GetBaseFile(). + required = self.options.download_base or self.options.revision is not None + self.svn_base = self._GuessBase(required) + + def GuessBase(self, required): + """Wrapper for _GuessBase.""" + return self.svn_base + + def _GuessBase(self, required): + """Returns the SVN base URL. + + Args: + required: If true, exits if the url can't be guessed, otherwise None is + returned. + """ + info = RunShell(["svn", "info"]) + for line in info.splitlines(): + words = line.split() + if len(words) == 2 and words[0] == "URL:": + url = words[1] + scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) + username, netloc = urllib.splituser(netloc) + if username: + logging.info("Removed username from base URL") + if netloc.endswith("svn.python.org"): + if netloc == "svn.python.org": + if path.startswith("/projects/"): + path = path[9:] + elif netloc != "pythondev@svn.python.org": + ErrorExit("Unrecognized Python URL: %s" % url) + base = "http://svn.python.org/view/*checkout*%s/" % path + logging.info("Guessed Python base = %s", base) + elif netloc.endswith("svn.collab.net"): + if path.startswith("/repos/"): + path = path[6:] + base = "http://svn.collab.net/viewvc/*checkout*%s/" % path + logging.info("Guessed CollabNet base = %s", base) + elif netloc.endswith(".googlecode.com"): + path = path + "/" + base = urlparse.urlunparse(("http", netloc, path, params, + query, fragment)) + logging.info("Guessed Google Code base = %s", base) + else: + path = path + "/" + base = urlparse.urlunparse((scheme, netloc, path, params, + query, fragment)) + logging.info("Guessed base = %s", base) + return base + if required: + ErrorExit("Can't find URL in output from svn info") + return None + + def GenerateDiff(self, args): + cmd = ["svn", "diff"] + if self.options.revision: + cmd += ["-r", self.options.revision] + cmd.extend(args) + data = RunShell(cmd) + count = 0 + for line in data.splitlines(): + if line.startswith("Index:") or line.startswith("Property changes on:"): + count += 1 + logging.info(line) + if not count: + ErrorExit("No valid patches found in output from svn diff") + return data + + def _CollapseKeywords(self, content, keyword_str): + """Collapses SVN keywords.""" + # svn cat translates keywords but svn diff doesn't. As a result of this + # behavior patching.PatchChunks() fails with a chunk mismatch error. + # This part was originally written by the Review Board development team + # who had the same problem (http://reviews.review-board.org/r/276/). + # Mapping of keywords to known aliases + svn_keywords = { + # Standard keywords + 'Date': ['Date', 'LastChangedDate'], + 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], + 'Author': ['Author', 'LastChangedBy'], + 'HeadURL': ['HeadURL', 'URL'], + 'Id': ['Id'], + + # Aliases + 'LastChangedDate': ['LastChangedDate', 'Date'], + 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], + 'LastChangedBy': ['LastChangedBy', 'Author'], + 'URL': ['URL', 'HeadURL'], + } + + def repl(m): + if m.group(2): + return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) + return "$%s$" % m.group(1) + keywords = [keyword + for name in keyword_str.split(" ") + for keyword in svn_keywords.get(name, [])] + return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) + + def GetUnknownFiles(self): + status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) + unknown_files = [] + for line in status.split("\n"): + if line and line[0] == "?": + unknown_files.append(line) + return unknown_files + + def ReadFile(self, filename): + """Returns the contents of a file.""" + file = open(filename, 'rb') + result = "" + try: + result = file.read() + finally: + file.close() + return result + + def GetStatus(self, filename): + """Returns the status of a file.""" + if not self.options.revision: + status = RunShell(["svn", "status", "--ignore-externals", filename]) + if not status: + ErrorExit("svn status returned no output for %s" % filename) + status_lines = status.splitlines() + # If file is in a cl, the output will begin with + # "\n--- Changelist 'cl_name':\n". See + # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt + if (len(status_lines) == 3 and + not status_lines[0] and + status_lines[1].startswith("--- Changelist")): + status = status_lines[2] + else: + status = status_lines[0] + # If we have a revision to diff against we need to run "svn list" + # for the old and the new revision and compare the results to get + # the correct status for a file. + else: + dirname, relfilename = os.path.split(filename) + if dirname not in self.svnls_cache: + cmd = ["svn", "list", "-r", self.rev_start, dirname or "."] + out, returncode = RunShellWithReturnCode(cmd) + if returncode: + ErrorExit("Failed to get status for %s." % filename) + old_files = out.splitlines() + args = ["svn", "list"] + if self.rev_end: + args += ["-r", self.rev_end] + cmd = args + [dirname or "."] + out, returncode = RunShellWithReturnCode(cmd) + if returncode: + ErrorExit("Failed to run command %s" % cmd) + self.svnls_cache[dirname] = (old_files, out.splitlines()) + old_files, new_files = self.svnls_cache[dirname] + if relfilename in old_files and relfilename not in new_files: + status = "D " + elif relfilename in old_files and relfilename in new_files: + status = "M " + else: + status = "A " + return status + + def GetBaseFile(self, filename): + status = self.GetStatus(filename) + base_content = None + new_content = None + + # If a file is copied its status will be "A +", which signifies + # "addition-with-history". See "svn st" for more information. We need to + # upload the original file or else diff parsing will fail if the file was + # edited. + if status[0] == "A" and status[3] != "+": + # We'll need to upload the new content if we're adding a binary file + # since diff's output won't contain it. + mimetype = RunShell(["svn", "propget", "svn:mime-type", filename], + silent_ok=True) + base_content = "" + is_binary = mimetype and not mimetype.startswith("text/") + if is_binary and self.IsImage(filename): + new_content = self.ReadFile(filename) + elif (status[0] in ("M", "D", "R") or + (status[0] == "A" and status[3] == "+") or # Copied file. + (status[0] == " " and status[1] == "M")): # Property change. + args = [] + if self.options.revision: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + else: + # Don't change filename, it's needed later. + url = filename + args += ["-r", "BASE"] + cmd = ["svn"] + args + ["propget", "svn:mime-type", url] + mimetype, returncode = RunShellWithReturnCode(cmd) + if returncode: + # File does not exist in the requested revision. + # Reset mimetype, it contains an error message. + mimetype = "" + get_base = False + is_binary = mimetype and not mimetype.startswith("text/") + if status[0] == " ": + # Empty base content just to force an upload. + base_content = "" + elif is_binary: + if self.IsImage(filename): + get_base = True + if status[0] == "M": + if not self.rev_end: + new_content = self.ReadFile(filename) + else: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) + new_content = RunShell(["svn", "cat", url], + universal_newlines=True, silent_ok=True) + else: + base_content = "" + else: + get_base = True + + if get_base: + if is_binary: + universal_newlines = False + else: + universal_newlines = True + if self.rev_start: + # "svn cat -r REV delete_file.txt" doesn't work. cat requires + # the full URL with "@REV" appended instead of using "-r" option. + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + base_content = RunShell(["svn", "cat", url], + universal_newlines=universal_newlines, + silent_ok=True) + else: + base_content = RunShell(["svn", "cat", filename], + universal_newlines=universal_newlines, + silent_ok=True) + if not is_binary: + args = [] + if self.rev_start: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + else: + url = filename + args += ["-r", "BASE"] + cmd = ["svn"] + args + ["propget", "svn:keywords", url] + keywords, returncode = RunShellWithReturnCode(cmd) + if keywords and not returncode: + base_content = self._CollapseKeywords(base_content, keywords) + else: + StatusUpdate("svn status returned unexpected output: %s" % status) + sys.exit(1) + return base_content, new_content, is_binary, status[0:5] + + +class GitVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Git.""" + + def __init__(self, options): + super(GitVCS, self).__init__(options) + # Map of filename -> hash of base file. + self.base_hashes = {} + + def GenerateDiff(self, extra_args): + # This is more complicated than svn's GenerateDiff because we must convert + # the diff output to include an svn-style "Index:" line as well as record + # the hashes of the base files, so we can upload them along with our diff. + if self.options.revision: + extra_args = [self.options.revision] + extra_args + gitdiff = RunShell(["git", "diff", "--full-index"] + extra_args) + svndiff = [] + filecount = 0 + filename = None + for line in gitdiff.splitlines(): + match = re.match(r"diff --git a/(.*) b/.*$", line) + if match: + filecount += 1 + filename = match.group(1) + svndiff.append("Index: %s\n" % filename) + else: + # The "index" line in a git diff looks like this (long hashes elided): + # index 82c0d44..b2cee3f 100755 + # We want to save the left hash, as that identifies the base file. + match = re.match(r"index (\w+)\.\.", line) + if match: + self.base_hashes[filename] = match.group(1) + svndiff.append(line + "\n") + if not filecount: + ErrorExit("No valid patches found in output from git diff") + return "".join(svndiff) + + def GetUnknownFiles(self): + status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], + silent_ok=True) + return status.splitlines() + + def GetBaseFile(self, filename): + hash = self.base_hashes[filename] + base_content = None + new_content = None + is_binary = False + if hash == "0" * 40: # All-zero hash indicates no base file. + status = "A" + base_content = "" + else: + status = "M" + base_content, returncode = RunShellWithReturnCode(["git", "show", hash]) + if returncode: + ErrorExit("Got error status from 'git show %s'" % hash) + return (base_content, new_content, is_binary, status) + + +class MercurialVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Mercurial.""" + + def __init__(self, options, repo_dir): + super(MercurialVCS, self).__init__(options) + # Absolute path to repository (we can be in a subdir) + self.repo_dir = os.path.normpath(repo_dir) + # Compute the subdir + cwd = os.path.normpath(os.getcwd()) + assert cwd.startswith(self.repo_dir) + self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") + if self.options.revision: + self.base_rev = self.options.revision + else: + self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() + + def _GetRelPath(self, filename): + """Get relative path of a file according to the current directory, + given its logical path in the repo.""" + assert filename.startswith(self.subdir), filename + return filename[len(self.subdir):].lstrip(r"\/") + + def GenerateDiff(self, extra_args): + # If no file specified, restrict to the current subdir + extra_args = extra_args or ["."] + cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args + data = RunShell(cmd, silent_ok=True) + svndiff = [] + filecount = 0 + for line in data.splitlines(): + m = re.match("diff --git a/(\S+) b/(\S+)", line) + if m: + # Modify line to make it look like as it comes from svn diff. + # With this modification no changes on the server side are required + # to make upload.py work with Mercurial repos. + # NOTE: for proper handling of moved/copied files, we have to use + # the second filename. + filename = m.group(2) + svndiff.append("Index: %s" % filename) + svndiff.append("=" * 67) + filecount += 1 + logging.info(line) + else: + svndiff.append(line) + if not filecount: + ErrorExit("No valid patches found in output from hg diff") + return "\n".join(svndiff) + "\n" + + def GetUnknownFiles(self): + """Return a list of files unknown to the VCS.""" + args = [] + status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], + silent_ok=True) + unknown_files = [] + for line in status.splitlines(): + st, fn = line.split(" ", 1) + if st == "?": + unknown_files.append(fn) + return unknown_files + + def GetBaseFile(self, filename): + # "hg status" and "hg cat" both take a path relative to the current subdir + # rather than to the repo root, but "hg diff" has given us the full path + # to the repo root. + base_content = "" + new_content = None + is_binary = False + oldrelpath = relpath = self._GetRelPath(filename) + # "hg status -C" returns two lines for moved/copied files, one otherwise + out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) + out = out.splitlines() + # HACK: strip error message about missing file/directory if it isn't in + # the working copy + if out[0].startswith('%s: ' % relpath): + out = out[1:] + if len(out) > 1: + # Moved/copied => considered as modified, use old filename to + # retrieve base contents + oldrelpath = out[1].strip() + status = "M" + else: + status, _ = out[0].split(' ', 1) + if status != "A": + base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath], + silent_ok=True) + is_binary = "\0" in base_content # Mercurial's heuristic + if status != "R": + new_content = open(relpath, "rb").read() + is_binary = is_binary or "\0" in new_content + if is_binary and base_content: + # Fetch again without converting newlines + base_content = RunShell(["hg", "cat", "-r", self.base_rev, oldrelpath], + silent_ok=True, universal_newlines=False) + if not is_binary or not self.IsImage(relpath): + new_content = None + return base_content, new_content, is_binary, status + + +# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. +def SplitPatch(data): + """Splits a patch into separate pieces for each file. + + Args: + data: A string containing the output of svn diff. + + Returns: + A list of 2-tuple (filename, text) where text is the svn diff output + pertaining to filename. + """ + patches = [] + filename = None + diff = [] + for line in data.splitlines(True): + new_filename = None + if line.startswith('Index:'): + unused, new_filename = line.split(':', 1) + new_filename = new_filename.strip() + elif line.startswith('Property changes on:'): + unused, temp_filename = line.split(':', 1) + # When a file is modified, paths use '/' between directories, however + # when a property is modified '\' is used on Windows. Make them the same + # otherwise the file shows up twice. + temp_filename = temp_filename.strip().replace('\\', '/') + if temp_filename != filename: + # File has property changes but no modifications, create a new diff. + new_filename = temp_filename + if new_filename: + if filename and diff: + patches.append((filename, ''.join(diff))) + filename = new_filename + diff = [line] + continue + if diff is not None: + diff.append(line) + if filename and diff: + patches.append((filename, ''.join(diff))) + return patches + + +def UploadSeparatePatches(issue, rpc_server, patchset, data, options): + """Uploads a separate patch for each file in the diff output. + + Returns a list of [patch_key, filename] for each file. + """ + patches = SplitPatch(data) + rv = [] + for patch in patches: + if len(patch[1]) > MAX_UPLOAD_SIZE: + print ("Not uploading the patch for " + patch[0] + + " because the file is too large.") + continue + form_fields = [("filename", patch[0])] + if not options.download_base: + form_fields.append(("content_upload", "1")) + files = [("data", "data.diff", patch[1])] + ctype, body = EncodeMultipartFormData(form_fields, files) + url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) + print "Uploading patch for " + patch[0] + response_body = rpc_server.Send(url, body, content_type=ctype) + lines = response_body.splitlines() + if not lines or lines[0] != "OK": + StatusUpdate(" --> %s" % response_body) + sys.exit(1) + rv.append([lines[1], patch[0]]) + return rv + + +def GuessVCS(options): + """Helper to guess the version control system. + + This examines the current directory, guesses which VersionControlSystem + we're using, and returns an instance of the appropriate class. Exit with an + error if we can't figure it out. + + Returns: + A VersionControlSystem instance. Exits if the VCS can't be guessed. + """ + # Mercurial has a command to get the base directory of a repository + # Try running it, but don't die if we don't have hg installed. + # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. + try: + out, returncode = RunShellWithReturnCode(["hg", "root"]) + if returncode == 0: + return MercurialVCS(options, out.strip()) + except OSError, (errno, message): + if errno != 2: # ENOENT -- they don't have hg installed. + raise + + # Subversion has a .svn in all working directories. + if os.path.isdir('.svn'): + logging.info("Guessed VCS = Subversion") + return SubversionVCS(options) + + # Git has a command to test if you're in a git tree. + # Try running it, but don't die if we don't have git installed. + try: + out, returncode = RunShellWithReturnCode(["git", "rev-parse", + "--is-inside-work-tree"]) + if returncode == 0: + return GitVCS(options) + except OSError, (errno, message): + if errno != 2: # ENOENT -- they don't have git installed. + raise + + ErrorExit(("Could not guess version control system. " + "Are you in a working copy directory?")) + + +def RealMain(argv, data=None): + """The real main function. + + Args: + argv: Command line arguments. + data: Diff contents. If None (default) the diff is generated by + the VersionControlSystem implementation returned by GuessVCS(). + + Returns: + A 2-tuple (issue id, patchset id). + The patchset id is None if the base files are not uploaded by this + script (applies only to SVN checkouts). + """ + logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" + "%(lineno)s %(message)s ")) + os.environ['LC_ALL'] = 'C' + options, args = parser.parse_args(argv[1:]) + global verbosity + verbosity = options.verbose + if verbosity >= 3: + logging.getLogger().setLevel(logging.DEBUG) + elif verbosity >= 2: + logging.getLogger().setLevel(logging.INFO) + vcs = GuessVCS(options) + if isinstance(vcs, SubversionVCS): + # base field is only allowed for Subversion. + # Note: Fetching base files may become deprecated in future releases. + base = vcs.GuessBase(options.download_base) + else: + base = None + if not base and options.download_base: + options.download_base = True + logging.info("Enabled upload of base file") + if not options.assume_yes: + vcs.CheckForUnknownFiles() + if data is None: + data = vcs.GenerateDiff(args) + files = vcs.GetBaseFiles(data) + if verbosity >= 1: + print "Upload server:", options.server, "(change with -s/--server)" + if options.issue: + prompt = "Message describing this patch set: " + else: + prompt = "New issue subject: " + message = options.message or raw_input(prompt).strip() + if not message: + ErrorExit("A non-empty message is required") + rpc_server = GetRpcServer(options) + form_fields = [("subject", message)] + if base: + form_fields.append(("base", base)) + if options.issue: + form_fields.append(("issue", str(options.issue))) + if options.email: + form_fields.append(("user", options.email)) + if options.reviewers: + for reviewer in options.reviewers.split(','): + if "@" in reviewer and not reviewer.split("@")[1].count(".") == 1: + ErrorExit("Invalid email address: %s" % reviewer) + form_fields.append(("reviewers", options.reviewers)) + if options.cc: + for cc in options.cc.split(','): + if "@" in cc and not cc.split("@")[1].count(".") == 1: + ErrorExit("Invalid email address: %s" % cc) + form_fields.append(("cc", options.cc)) + description = options.description + if options.description_file: + if options.description: + ErrorExit("Can't specify description and description_file") + file = open(options.description_file, 'r') + description = file.read() + file.close() + if description: + form_fields.append(("description", description)) + # Send a hash of all the base file so the server can determine if a copy + # already exists in an earlier patchset. + base_hashes = "" + for file, info in files.iteritems(): + if not info[0] is None: + checksum = md5.new(info[0]).hexdigest() + if base_hashes: + base_hashes += "|" + base_hashes += checksum + ":" + file + form_fields.append(("base_hashes", base_hashes)) + # If we're uploading base files, don't send the email before the uploads, so + # that it contains the file status. + if options.send_mail and options.download_base: + form_fields.append(("send_mail", "1")) + if not options.download_base: + form_fields.append(("content_upload", "1")) + if len(data) > MAX_UPLOAD_SIZE: + print "Patch is large, so uploading file patches separately." + uploaded_diff_file = [] + form_fields.append(("separate_patches", "1")) + else: + uploaded_diff_file = [("data", "data.diff", data)] + ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) + response_body = rpc_server.Send("/upload", body, content_type=ctype) + patchset = None + if not options.download_base or not uploaded_diff_file: + lines = response_body.splitlines() + if len(lines) >= 2: + msg = lines[0] + patchset = lines[1].strip() + patches = [x.split(" ", 1) for x in lines[2:]] + else: + msg = response_body + else: + msg = response_body + StatusUpdate(msg) + if not response_body.startswith("Issue created.") and \ + not response_body.startswith("Issue updated."): + sys.exit(0) + issue = msg[msg.rfind("/")+1:] + + if not uploaded_diff_file: + result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) + if not options.download_base: + patches = result + + if not options.download_base: + vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) + if options.send_mail: + rpc_server.Send("/" + issue + "/mail", payload="") + return issue, patchset + + +def main(): + try: + RealMain(sys.argv) + except KeyboardInterrupt: + print + StatusUpdate("Interrupted.") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/src/test/gtest/scripts/upload_gtest.py b/src/test/gtest/scripts/upload_gtest.py new file mode 100755 index 00000000..be19ae80 --- /dev/null +++ b/src/test/gtest/scripts/upload_gtest.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""upload_gtest.py v0.1.0 -- uploads a Google Test patch for review. + +This simple wrapper passes all command line flags and +--cc=googletestframework@googlegroups.com to upload.py. + +USAGE: upload_gtest.py [options for upload.py] +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys + +CC_FLAG = '--cc=' +GTEST_GROUP = 'googletestframework@googlegroups.com' + + +def main(): + # Finds the path to upload.py, assuming it is in the same directory + # as this file. + my_dir = os.path.dirname(os.path.abspath(__file__)) + upload_py_path = os.path.join(my_dir, 'upload.py') + + # Adds Google Test discussion group to the cc line if it's not there + # already. + upload_py_argv = [upload_py_path] + found_cc_flag = False + for arg in sys.argv[1:]: + if arg.startswith(CC_FLAG): + found_cc_flag = True + cc_line = arg[len(CC_FLAG):] + cc_list = [addr for addr in cc_line.split(',') if addr] + if GTEST_GROUP not in cc_list: + cc_list.append(GTEST_GROUP) + upload_py_argv.append(CC_FLAG + ','.join(cc_list)) + else: + upload_py_argv.append(arg) + + if not found_cc_flag: + upload_py_argv.append(CC_FLAG + GTEST_GROUP) + + # Invokes upload.py with the modified command line flags. + os.execv(upload_py_path, upload_py_argv) + + +if __name__ == '__main__': + main() diff --git a/src/test/gtest/src/gtest-all.cc b/src/test/gtest/src/gtest-all.cc new file mode 100644 index 00000000..0a9cee52 --- /dev/null +++ b/src/test/gtest/src/gtest-all.cc @@ -0,0 +1,48 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +#include "src/gtest.cc" +#include "src/gtest-death-test.cc" +#include "src/gtest-filepath.cc" +#include "src/gtest-port.cc" +#include "src/gtest-printers.cc" +#include "src/gtest-test-part.cc" +#include "src/gtest-typed-test.cc" diff --git a/src/test/gtest/src/gtest-death-test.cc b/src/test/gtest/src/gtest-death-test.cc new file mode 100644 index 00000000..a0a8c7ba --- /dev/null +++ b/src/test/gtest/src/gtest-death-test.cc @@ -0,0 +1,1346 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include + +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_QNX +# include +# endif // GTEST_OS_QNX + +#endif // GTEST_HAS_DEATH_TEST + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +static bool g_in_fast_death_test_child = false; + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS + + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS +} + +# if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static std::string ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static std::string DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const std::string& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression + " != -1"); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +std::string GetLastErrnoDescription() { + return errno == 0 ? "" : posix::StrError(errno); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const std::string& message) { + last_death_test_message_ = message; +} + +std::string DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const std::string error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(static_cast(::GetCurrentProcessId())) + + // size_t has the same width as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + "|" + StreamableToString(reinterpret_cast(write_handle)) + + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +# else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + static ::std::vector + GetArgvsForDeathTestChildProcess() { + ::std::vector args = GetInjectableArgvs(); + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +# if !GTEST_OS_QNX +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; +} +# endif // !GTEST_OS_QNX + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; +void StackLowerThanAddress(const void* ptr, bool* result) { + int dummy; + *result = (&dummy < ptr); +} + +// Make sure AddressSanitizer does not tamper with the stack here. +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +bool StackGrowsDown() { + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; +} + +// Spawns a child process with the same executable as the current process in +// a thread-safe manner and instructs it to run the death test. The +// implementation uses fork(2) + exec. On systems where clone(2) is +// available, it is used instead, being slightly more thread-safe. On QNX, +// fork supports only single-threaded environments, so this function uses +// spawn(2) there instead. The function dies with an error message if +// anything goes wrong. +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + +# else // GTEST_OS_QNX +# if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +# endif // GTEST_OS_LINUX + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } +# endif // GTEST_OS_QNX +# if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, NULL)); +# endif // GTEST_OS_LINUX + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message( + "Death test count (" + StreamableToString(death_test_index) + + ") somehow exceeded expected maximum (" + + StreamableToString(flag->index()) + ")"); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message( + "Unknown death test style \"" + GTEST_FLAG(death_test_style) + + "\" encountered"); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort("Unable to open parent process " + + StreamableToString(parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the pipe handle " + + StreamableToString(write_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the event handle " + + StreamableToString(event_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort("Unable to convert pipe handle " + + StreamableToString(write_handle_as_size_t) + + " to a file descriptor"); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing diff --git a/src/test/gtest/src/gtest-filepath.cc b/src/test/gtest/src/gtest-filepath.cc new file mode 100644 index 00000000..219875cc --- /dev/null +++ b/src/test/gtest/src/gtest-filepath.cc @@ -0,0 +1,380 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-port.h" + +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +# include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +# include +#else +# include +# include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + +#include "gtest/internal/gtest-string.h" + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) { + dir = std::string(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + std::string file; + if (number == 0) { + file = base_name.string() + "." + extension; + } else { + file = base_name.string() + "_" + StreamableToString(number) + + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing diff --git a/src/test/gtest/src/gtest-internal-inl.h b/src/test/gtest/src/gtest-internal-inl.h new file mode 100644 index 00000000..0ac7a109 --- /dev/null +++ b/src/test/gtest/src/gtest-internal-inl.h @@ -0,0 +1,1192 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// If this file is included from the user's code, just say no. +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +# include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + +#include "gtest/internal/gtest-port.h" + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +#if GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS + +#include "gtest/gtest.h" // NOLINT +#include "gtest/gtest-spi.h" + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Converts the given time in milliseconds to a date string in the ISO 8601 +// format, without the timezone information. N.B.: due to the use the +// non-reentrant localtime() function, this function is not thread safe. Do +// not use it in any code that can be called from multiple threads. +GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return test_property.key() == key_; + } + + private: + std::string key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + + virtual string CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_); + + virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + std::string message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + // Adds a TestProperty to the current TestResult object when invoked in a + // context of a test or a test case, or to the global property set. If the + // result already contains a property with the same key, the value will be + // updated. + void RecordProperty(const TestProperty& test_property); + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ std::string GetLastErrnoDescription(); + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const std::string& xml_element, + const TestProperty& property) { + test_result->RecordProperty(xml_element, property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Abstract base class for writing strings to a socket. + class AbstractSocketWriter { + public: + virtual ~AbstractSocketWriter() {} + + // Sends a string to the socket. + virtual void Send(const string& message) = 0; + + // Closes the socket. + virtual void CloseConnection() {} + + // Sends a string and a newline to the socket. + void SendLn(const string& message) { + Send(message + "\n"); + } + }; + + // Concrete class for actually writing strings to a socket. + class SocketWriter : public AbstractSocketWriter { + public: + SocketWriter(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + } + + virtual ~SocketWriter() { + if (sockfd_ != -1) + CloseConnection(); + } + + // Sends a string to the socket. + virtual void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + }; // class SocketWriter + + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : socket_writer_(new SocketWriter(host, port)) { Start(); } + + explicit StreamingListener(AbstractSocketWriter* socket_writer) + : socket_writer_(socket_writer) { Start(); } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + SendLn("event=TestProgramStart"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); + + // Notify the streaming server to stop. + socket_writer_->CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + SendLn("event=TestIterationStart&iteration=" + + StreamableToString(iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + SendLn("event=TestIterationEnd&passed=" + + FormatBool(unit_test.Passed()) + "&elapsed_time=" + + StreamableToString(unit_test.elapsed_time()) + "ms"); + } + + void OnTestCaseStart(const TestCase& test_case) { + SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + } + + void OnTestCaseEnd(const TestCase& test_case) { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + + "ms"); + } + + void OnTestStart(const TestInfo& test_info) { + SendLn(std::string("event=TestStart&name=") + test_info.name()); + } + + void OnTestEnd(const TestInfo& test_info) { + SendLn("event=TestEnd&passed=" + + FormatBool((test_info.result())->Passed()) + + "&elapsed_time=" + + StreamableToString((test_info.result())->elapsed_time()) + "ms"); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + + "&line=" + StreamableToString(test_part_result.line_number()) + + "&message=" + UrlEncode(test_part_result.message())); + } + + private: + // Sends the given message and a newline to the socket. + void SendLn(const string& message) { socket_writer_->SendLn(message); } + + // Called at the start of streaming to notify the receiver what + // protocol we are using. + void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } + + string FormatBool(bool value) { return value ? "1" : "0"; } + + const scoped_ptr socket_writer_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +#endif // GTEST_CAN_STREAM_RESULTS_ + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/src/test/gtest/src/gtest-port.cc b/src/test/gtest/src/gtest-port.cc new file mode 100644 index 00000000..b032745b --- /dev/null +++ b/src/test/gtest/src/gtest-port.cc @@ -0,0 +1,1184 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/internal/gtest-port.h" + +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS +# include +# include +# include +# include // Used in ThreadLocal. +#else +# include +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_MAC +# include +# include +# include +#endif // GTEST_OS_MAC + +#if GTEST_OS_QNX +# include +# include +# include +#endif // GTEST_OS_QNX + +#include "gtest/gtest-spi.h" +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#elif GTEST_OS_QNX + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); + close(fd); + if (status == EOK) { + return static_cast(process_info.num_threads); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +void SleepMilliseconds(int n) { + ::Sleep(n); +} + +AutoHandle::AutoHandle() + : handle_(INVALID_HANDLE_VALUE) {} + +AutoHandle::AutoHandle(Handle handle) + : handle_(handle) {} + +AutoHandle::~AutoHandle() { + Reset(); +} + +AutoHandle::Handle AutoHandle::Get() const { + return handle_; +} + +void AutoHandle::Reset() { + Reset(INVALID_HANDLE_VALUE); +} + +void AutoHandle::Reset(HANDLE handle) { + // Resetting with the same handle we already own is invalid. + if (handle_ != handle) { + if (IsCloseable()) { + ::CloseHandle(handle_); + } + handle_ = handle; + } else { + GTEST_CHECK_(!IsCloseable()) + << "Resetting a valid handle to itself is likely a programmer error " + "and thus not allowed."; + } +} + +bool AutoHandle::IsCloseable() const { + // Different Windows APIs may use either of these values to represent an + // invalid handle. + return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE; +} + +Notification::Notification() + : event_(::CreateEvent(NULL, // Default security attributes. + TRUE, // Do not reset automatically. + FALSE, // Initially unset. + NULL)) { // Anonymous event. + GTEST_CHECK_(event_.Get() != NULL); +} + +void Notification::Notify() { + GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); +} + +void Notification::WaitForNotification() { + GTEST_CHECK_( + ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); +} + +Mutex::Mutex() + : type_(kDynamic), + owner_thread_id_(0), + critical_section_init_phase_(0), + critical_section_(new CRITICAL_SECTION) { + ::InitializeCriticalSection(critical_section_); +} + +Mutex::~Mutex() { + // Static mutexes are leaked intentionally. It is not thread-safe to try + // to clean them up. + // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires + // nothing to clean it up but is available only on Vista and later. + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx + if (type_ == kDynamic) { + ::DeleteCriticalSection(critical_section_); + delete critical_section_; + critical_section_ = NULL; + } +} + +void Mutex::Lock() { + ThreadSafeLazyInit(); + ::EnterCriticalSection(critical_section_); + owner_thread_id_ = ::GetCurrentThreadId(); +} + +void Mutex::Unlock() { + ThreadSafeLazyInit(); + // We don't protect writing to owner_thread_id_ here, as it's the + // caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_thread_id_ = 0; + ::LeaveCriticalSection(critical_section_); +} + +// Does nothing if the current thread holds the mutex. Otherwise, crashes +// with high probability. +void Mutex::AssertHeld() { + ThreadSafeLazyInit(); + GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) + << "The current thread is not holding the mutex @" << this; +} + +// Initializes owner_thread_id_ and critical_section_ in static mutexes. +void Mutex::ThreadSafeLazyInit() { + // Dynamic mutexes are initialized in the constructor. + if (type_ == kStatic) { + switch ( + ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { + case 0: + // If critical_section_init_phase_ was 0 before the exchange, we + // are the first to test it and need to perform the initialization. + owner_thread_id_ = 0; + critical_section_ = new CRITICAL_SECTION; + ::InitializeCriticalSection(critical_section_); + // Updates the critical_section_init_phase_ to 2 to signal + // initialization complete. + GTEST_CHECK_(::InterlockedCompareExchange( + &critical_section_init_phase_, 2L, 1L) == + 1L); + break; + case 1: + // Somebody else is already initializing the mutex; spin until they + // are done. + while (::InterlockedCompareExchange(&critical_section_init_phase_, + 2L, + 2L) != 2L) { + // Possibly yields the rest of the thread's time slice to other + // threads. + ::Sleep(0); + } + break; + + case 2: + break; // The mutex is already initialized and ready for use. + + default: + GTEST_CHECK_(false) + << "Unexpected value of critical_section_init_phase_ " + << "while initializing a static mutex."; + } + } +} + +namespace { + +class ThreadWithParamSupport : public ThreadWithParamBase { + public: + static HANDLE CreateThread(Runnable* runnable, + Notification* thread_can_start) { + ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); + DWORD thread_id; + // TODO(yukawa): Consider to use _beginthreadex instead. + HANDLE thread_handle = ::CreateThread( + NULL, // Default security. + 0, // Default stack size. + &ThreadWithParamSupport::ThreadMain, + param, // Parameter to ThreadMainStatic + 0x0, // Default creation flags. + &thread_id); // Need a valid pointer for the call to work under Win98. + GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error " + << ::GetLastError() << "."; + if (thread_handle == NULL) { + delete param; + } + return thread_handle; + } + + private: + struct ThreadMainParam { + ThreadMainParam(Runnable* runnable, Notification* thread_can_start) + : runnable_(runnable), + thread_can_start_(thread_can_start) { + } + scoped_ptr runnable_; + // Does not own. + Notification* thread_can_start_; + }; + + static DWORD WINAPI ThreadMain(void* ptr) { + // Transfers ownership. + scoped_ptr param(static_cast(ptr)); + if (param->thread_can_start_ != NULL) + param->thread_can_start_->WaitForNotification(); + param->runnable_->Run(); + return 0; + } + + // Prohibit instantiation. + ThreadWithParamSupport(); + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); +}; + +} // namespace + +ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, + Notification* thread_can_start) + : thread_(ThreadWithParamSupport::CreateThread(runnable, + thread_can_start)) { +} + +ThreadWithParamBase::~ThreadWithParamBase() { + Join(); +} + +void ThreadWithParamBase::Join() { + GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) + << "Failed to join the thread with error " << ::GetLastError() << "."; +} + +// Maps a thread to a set of ThreadIdToThreadLocals that have values +// instantiated on that thread and notifies them when the thread exits. A +// ThreadLocal instance is expected to persist until all threads it has +// values on have terminated. +class ThreadLocalRegistryImpl { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + DWORD current_thread = ::GetCurrentThreadId(); + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(current_thread); + if (thread_local_pos == thread_to_thread_locals->end()) { + thread_local_pos = thread_to_thread_locals->insert( + std::make_pair(current_thread, ThreadLocalValues())).first; + StartWatcherThreadFor(current_thread); + } + ThreadLocalValues& thread_local_values = thread_local_pos->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos == thread_local_values.end()) { + value_pos = + thread_local_values + .insert(std::make_pair( + thread_local_instance, + linked_ptr( + thread_local_instance->NewValueForCurrentThread()))) + .first; + } + return value_pos->second.get(); + } + + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + std::vector > value_holders; + // Clean up the ThreadLocalValues data structure while holding the lock, but + // defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + for (ThreadIdToThreadLocals::iterator it = + thread_to_thread_locals->begin(); + it != thread_to_thread_locals->end(); + ++it) { + ThreadLocalValues& thread_local_values = it->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos != thread_local_values.end()) { + value_holders.push_back(value_pos->second); + thread_local_values.erase(value_pos); + // This 'if' can only be successful at most once, so theoretically we + // could break out of the loop here, but we don't bother doing so. + } + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + static void OnThreadExit(DWORD thread_id) { + GTEST_CHECK_(thread_id != 0) << ::GetLastError(); + std::vector > value_holders; + // Clean up the ThreadIdToThreadLocals data structure while holding the + // lock, but defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(thread_id); + if (thread_local_pos != thread_to_thread_locals->end()) { + ThreadLocalValues& thread_local_values = thread_local_pos->second; + for (ThreadLocalValues::iterator value_pos = + thread_local_values.begin(); + value_pos != thread_local_values.end(); + ++value_pos) { + value_holders.push_back(value_pos->second); + } + thread_to_thread_locals->erase(thread_local_pos); + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + private: + // In a particular thread, maps a ThreadLocal object to its value. + typedef std::map > ThreadLocalValues; + // Stores all ThreadIdToThreadLocals having values in a thread, indexed by + // thread's ID. + typedef std::map ThreadIdToThreadLocals; + + // Holds the thread id and thread handle that we pass from + // StartWatcherThreadFor to WatcherThreadFunc. + typedef std::pair ThreadIdAndHandle; + + static void StartWatcherThreadFor(DWORD thread_id) { + // The returned handle will be kept in thread_map and closed by + // watcher_thread in WatcherThreadFunc. + HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, + FALSE, + thread_id); + GTEST_CHECK_(thread != NULL); + // We need to to pass a valid thread ID pointer into CreateThread for it + // to work correctly under Win98. + DWORD watcher_thread_id; + HANDLE watcher_thread = ::CreateThread( + NULL, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), + CREATE_SUSPENDED, + &watcher_thread_id); + GTEST_CHECK_(watcher_thread != NULL); + // Give the watcher thread the same priority as ours to avoid being + // blocked by it. + ::SetThreadPriority(watcher_thread, + ::GetThreadPriority(::GetCurrentThread())); + ::ResumeThread(watcher_thread); + ::CloseHandle(watcher_thread); + } + + // Monitors exit from a given thread and notifies those + // ThreadIdToThreadLocals about thread termination. + static DWORD WINAPI WatcherThreadFunc(LPVOID param) { + const ThreadIdAndHandle* tah = + reinterpret_cast(param); + GTEST_CHECK_( + ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); + OnThreadExit(tah->first); + ::CloseHandle(tah->second); + delete tah; + return 0; + } + + // Returns map of thread local instances. + static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { + mutex_.AssertHeld(); + static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; + return map; + } + + // Protects access to GetThreadLocalsMapLocked() and its return value. + static Mutex mutex_; + // Protects access to GetThreadMapLocked() and its return value. + static Mutex thread_map_mutex_; +}; + +Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); +Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); + +ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + return ThreadLocalRegistryImpl::GetValueOnCurrentThread( + thread_local_instance); +} + +void ThreadLocalRegistry::OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); +} + +#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +std::string FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) { + return file_name + ":"; + } +#ifdef _MSC_VER + return file_name + "(" + StreamableToString(line) + "):"; +#else + return file_name + ":" + StreamableToString(line) + ":"; +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) + return file_name; + else + return file_name + ":" + StreamableToString(line); +} + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +# if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /sdcard is directly accessible from native code + // and is the only location (unofficially) supported by the Android + // team. It's generally a symlink to the real SD Card mount point + // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or + // other OEM-customized locations. Never rely on these, and always + // use /sdcard. + char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; +# else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +# endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as an std::string. + static std::string ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +// Reads the entire content of a file as a string. +std::string CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +GTEST_DISABLE_MSC_WARNINGS_POP_() + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +static const ::std::vector* g_injected_test_argvs = + NULL; // Owned. + +void SetInjectableArgvs(const ::std::vector* argvs) { + if (g_injected_test_argvs != argvs) + delete g_injected_test_argvs; + g_injected_test_argvs = argvs; +} + +const ::std::vector& GetInjectableArgvs() { + if (g_injected_test_argvs != NULL) { + return *g_injected_test_argvs; + } + return g_argvs; +} +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing diff --git a/src/test/gtest/src/gtest-printers.cc b/src/test/gtest/src/gtest-printers.cc new file mode 100644 index 00000000..a2df412f --- /dev/null +++ b/src/test/gtest/src/gtest-printers.cc @@ -0,0 +1,373 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include "gtest/gtest-printers.h" +#include +#include +#include +#include // NOLINT +#include +#include "gtest/internal/gtest-port.h" + +namespace testing { + +namespace { + +using ::std::ostream; + +// Prints a segment of bytes in the given object. +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast(c); + return kAsIs; + } else { + *os << "\\x" + String::FormatHexInt(static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a wchar_t c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << static_cast(c); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << ", 0x" << String::FormatHexInt(static_cast(c)); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. CharType must be either +// char or wchar_t. +// The array starts at begin, the length is len, it may include '\0' characters +// and may not be NUL-terminated. +template +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +static void PrintCharsAsStringTo( + const CharType* begin, size_t len, ostream* os) { + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char/wchar_t array of 'len' elements, starting at address +// 'begin'. CharType must be either char or wchar_t. +template +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +static void UniversalPrintCharArray( + const CharType* begin, size_t len, ostream* os) { + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } + + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) wchar_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, std::wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing diff --git a/src/test/gtest/src/gtest-test-part.cc b/src/test/gtest/src/gtest-test-part.cc new file mode 100644 index 00000000..fb0e3542 --- /dev/null +++ b/src/test/gtest/src/gtest-test-part.cc @@ -0,0 +1,110 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest-test-part.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +std::string TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? message : + std::string(message, stack_trace); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing diff --git a/src/test/gtest/src/gtest-typed-test.cc b/src/test/gtest/src/gtest-typed-test.cc new file mode 100644 index 00000000..f0079f40 --- /dev/null +++ b/src/test/gtest/src/gtest-typed-test.cc @@ -0,0 +1,110 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest-typed-test.h" +#include "gtest/gtest.h" + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const std::string name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const std::string& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/src/test/gtest/src/gtest.cc b/src/test/gtest/src/gtest.cc new file mode 100644 index 00000000..ca3596eb --- /dev/null +++ b/src/test/gtest/src/gtest.cc @@ -0,0 +1,5006 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include // NOLINT +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include // NOLINT +# include // NOLINT +# include // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include + +#elif GTEST_OS_SYMBIAN +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +static const char* GetDefaultFilter() { + return kUniversalFilter; +} + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to a terminal type that supports colors."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", GetDefaultFilter()), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +GTEST_API_ int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +std::string g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +std::string UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return std::string(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + std::string(gtest_output_flag) : + std::string(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +std::string UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return ""; + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).string(); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.string(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter( + const std::string& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name) { + const std::string& full_name = test_case_name + "." + test_name.c_str(); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } else { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) { + const std::string expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTestImpl::reportable_disabled_test_count() const { + return SumOverTestCaseList(test_cases_, + &TestCase::reportable_disabled_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTestImpl::reportable_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return ""; +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) + _ftime64(&now); + GTEST_DISABLE_MSC_WARNINGS_POP_() + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String. + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +// Constructs an empty Message. +// We allocate the stringstream separately because otherwise each use of +// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's +// stack frame leading to huge stack frames in some cases; gcc does not reuse +// the stack space. +Message::Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); +} + +// These two overloads allow streaming a wide C string to a Message +// using the UTF-8 encoding. +Message& Message::operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} +Message& Message::operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Gets the text streamed to this object so far as an std::string. +// Each '\0' character in the buffer is replaced with "\\0". +std::string Message::GetString() const { + return internal::StringStreamToString(ss_.get()); +} + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { +} + +// Swaps two AssertionResults. +void AssertionResult::swap(AssertionResult& other) { + using std::swap; + swap(success_, other.success_); + swap(message_, other.message_); +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing CR-LF) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const std::string error_hex("0x" + String::FormatHexInt(hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << " " << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +std::string CodePointToUtf8(UInt32 code_point) { + if (code_point > kMaxCodePoint4) { + return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; + } + + char str[5]; // Big enough for the largest valid code point. + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else { // code_point <= kMaxCodePoint4 + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +std::string WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + stream << CodePointToUtf8(unicode_code_point); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to an std::string using the UTF-8 encoding. +// NULL will be converted to "(null)". +std::string String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return "(null)"; + + return internal::WideStringToUtf8(wide_c_str, -1); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Returns true iff str ends with the given suffix, ignoring case. +// Any string is considered to end with an empty suffix. +bool String::EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix) { + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); +} + +// Formats an int value as "%02d". +std::string String::FormatIntWidth2(int value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << value; + return ss.str(); +} + +// Formats an int value as "%X". +std::string String::FormatHexInt(int value) { + std::stringstream ss; + ss << std::hex << std::uppercase << value; + return ss.str(); +} + +// Formats a byte as "%02X". +std::string String::FormatByte(unsigned char value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase + << static_cast(value); + return ss.str(); +} + +// Converts the buffer in a stringstream to an std::string, converting NUL +// bytes to "\\0" along the way. +std::string StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + std::string result; + result.reserve(2 * (end - start)); + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + result += "\\0"; // Replaces NUL with "\\0"; + } else { + result += *ch; + } + } + + return result; +} + +// Appends the user-supplied message to the Google-Test-generated message. +std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + return gtest_msg + "\n" + user_msg_string; +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const std::string& xml_element, + const TestProperty& test_property) { + if (!ValidateTestProperty(xml_element, test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuitesAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "random_seed", + "tests", + "time", + "timestamp" +}; + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuiteAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "tests", + "time" +}; + +// The list of reserved attributes used in the element of XML output. +static const char* const kReservedTestCaseAttributes[] = { + "classname", + "name", + "status", + "time", + "type_param", + "value_param" +}; + +template +std::vector ArrayAsVector(const char* const (&array)[kSize]) { + return std::vector(array, array + kSize); +} + +static std::vector GetReservedAttributesForElement( + const std::string& xml_element) { + if (xml_element == "testsuites") { + return ArrayAsVector(kReservedTestSuitesAttributes); + } else if (xml_element == "testsuite") { + return ArrayAsVector(kReservedTestSuiteAttributes); + } else if (xml_element == "testcase") { + return ArrayAsVector(kReservedTestCaseAttributes); + } else { + GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; + } + // This code is unreachable but some compilers may not realizes that. + return std::vector(); +} + +static std::string FormatWordList(const std::vector& words) { + Message word_list; + for (size_t i = 0; i < words.size(); ++i) { + if (i > 0 && words.size() > 2) { + word_list << ", "; + } + if (i == words.size() - 1) { + word_list << "and "; + } + word_list << "'" << words[i] << "'"; + } + return word_list.GetString(); +} + +bool ValidateTestPropertyName(const std::string& property_name, + const std::vector& reserved_names) { + if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != + reserved_names.end()) { + ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name + << " (" << FormatWordList(reserved_names) + << " are reserved by " << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Adds a failure if the key is a reserved attribute of the element named +// xml_element. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property) { + return ValidateTestPropertyName(test_property.key(), + GetReservedAttributesForElement(xml_element)); +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, const std::string& value) { + UnitTest::GetInstance()->RecordProperty(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // Both TEST and TEST_F appear in same test case, which is incorrect. + // Tell the user how to fix this. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // Two fixture classes with the same name appear in two different + // namespaces, which is not allowed. Tell the user how to fix this. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static std::string* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new std::string(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +namespace internal { + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static std::string FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result); + +GoogleTestFailureException::GoogleTestFailureException( + const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} + +#endif // GTEST_HAS_EXCEPTIONS + +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const internal::GoogleTestFailureException&) { // NOLINT + // This exception type can only be thrown by a failed Google + // Test assertion with the intention of letting another testing + // framework catch it. Therefore we just re-throw it. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +TestInfo::TestInfo(const std::string& a_test_case_name, + const std::string& a_name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && test_info->name() == name_; + } + + private: + std::string name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int TestCase::reportable_disabled_test_count() const { + return CountIf(test_info_list_, TestReportableDisabled); +} + +// Gets the number of disabled tests in this test case. +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Gets the number of tests to be printed in the XML report. +int TestCase::reportable_test_count() const { + return CountIf(test_info_list_, TestReportable); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ad_hoc_test_result_.Clear(); + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static std::string FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::StreamableToString(count) + " " + + (count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static std::string FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static std::string FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +namespace internal { + +// Prints a TestPartResult to an std::string. +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \ + GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// Text printed in Google Test's text output and --gunit_list_tests +// output to label the type parameter and value parameter for a test. +static const char kTypeParamLabel[] = "TypeParam"; +static const char kValueParamLabel[] = "GetParam()"; + +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("%s = %s", kTypeParamLabel, type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("%s = %s", kValueParamLabel, value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == NULL) { + printf("\n"); + } else { + printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_case_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_case_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.reportable_disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const std::string& str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static std::string RemoveInvalidXmlCharacters(const std::string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const std::string& str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) { + return EscapeXml(str, false); + } + + // Verifies that the given attribute belongs to the given element and + // streams the attribute as XML. + static void OutputXmlAttribute(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value); + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(::std::ostream* stream, + const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(::std::ostream* stream, + const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::stringstream stream; + PrintXmlUnitTest(&stream, unit_test); + fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +std::string XmlUnitTestResultPrinter::EscapeXml( + const std::string& str, bool is_attribute) { + Message m; + + for (size_t i = 0; i < str.size(); ++i) { + const char ch = str[i]; + switch (ch) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(ch)) { + if (is_attribute && IsNormalizableWhitespace(ch)) + m << "&#x" << String::FormatByte(static_cast(ch)) + << ";"; + else + m << ch; + } + break; + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( + const std::string& str) { + std::string output; + output.reserve(str.size()); + for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Converts the given epoch time in milliseconds to a date string in the ISO +// 8601 format, without the timezone information. +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { + time_t seconds = static_cast(ms / 1000); + struct tm time_struct; +#ifdef _MSC_VER + if (localtime_s(&time_struct, &seconds) != 0) + return ""; // Invalid ms value +#else + if (localtime_r(&seconds, &time_struct) == NULL) + return ""; // Invalid ms value +#endif + + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct.tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +void XmlUnitTestResultPrinter::OutputXmlAttribute( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value) { + const std::vector& allowed_names = + GetReservedAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Attribute " << name << " is not allowed for element <" << element_name + << ">."; + + *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + const std::string kTestcase = "testcase"; + + *stream << " \n"; + } + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string summary = location + "\n" + part.summary(); + *stream << " "; + const string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, + const TestCase& test_case) { + const std::string kTestsuite = "testsuite"; + *stream << " <" << kTestsuite; + OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); + OutputXmlAttribute(stream, kTestsuite, "tests", + StreamableToString(test_case.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuite, "failures", + StreamableToString(test_case.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuite, "disabled", + StreamableToString(test_case.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuite, "errors", "0"); + OutputXmlAttribute(stream, kTestsuite, "time", + FormatTimeInMillisAsSeconds(test_case.elapsed_time())); + *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) + << ">\n"; + + for (int i = 0; i < test_case.total_test_count(); ++i) { + if (test_case.GetTestInfo(i)->is_reportable()) + OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); + } + *stream << " \n"; +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, + const UnitTest& unit_test) { + const std::string kTestsuites = "testsuites"; + + *stream << "\n"; + *stream << "<" << kTestsuites; + + OutputXmlAttribute(stream, kTestsuites, "tests", + StreamableToString(unit_test.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuites, "failures", + StreamableToString(unit_test.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuites, "disabled", + StreamableToString(unit_test.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuites, "errors", "0"); + OutputXmlAttribute( + stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); + OutputXmlAttribute(stream, kTestsuites, "time", + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + + if (GTEST_FLAG(shuffle)) { + OutputXmlAttribute(stream, kTestsuites, "random_seed", + StreamableToString(unit_test.random_seed())); + } + + *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); + + OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); + *stream << ">\n"; + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + if (unit_test.GetTestCase(i)->reportable_test_count() > 0) + PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); + } + *stream << "\n"; +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append("%" + String::FormatByte(static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::SocketWriter::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as an std::string. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, + int /* skip_count */) + GTEST_LOCK_EXCLUDED_(mutex_) { + return ""; +} + +void OsStackTraceGetter::UponLeavingGTest() + GTEST_LOCK_EXCLUDED_(mutex_) { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +// A helper class that creates the premature-exit file in its +// constructor and deletes the file in its destructor. +class ScopedPrematureExitFile { + public: + explicit ScopedPrematureExitFile(const char* premature_exit_filepath) + : premature_exit_filepath_(premature_exit_filepath) { + // If a path to the premature-exit file is specified... + if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { + // create the file with a single "0" character in it. I/O + // errors are ignored as there's nothing better we can do and we + // don't want to fail the test because of this. + FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); + fwrite("0", 1, 1, pfile); + fclose(pfile); + } + } + + ~ScopedPrematureExitFile() { + if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { + remove(premature_exit_filepath_); + } + } + + private: + const char* const premature_exit_filepath_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); +}; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest* UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTest::reportable_disabled_test_count() const { + return impl()->reportable_disabled_test_count(); +} + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTest::reportable_test_count() const { + return impl()->reportable_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the time of the test program start, in ms from the start of the +// UNIX epoch. +internal::TimeInMillis UnitTest::start_timestamp() const { + return impl()->start_timestamp(); +} + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Returns the TestResult containing information on test failures and +// properties logged outside of individual test cases. +const TestResult& UnitTest::ad_hoc_test_result() const { + return *impl()->ad_hoc_test_result(); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw internal::GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Adds a TestProperty to the current TestResult object when invoked from +// inside a test, to current TestCase's ad_hoc_test_result_ when invoked +// from SetUpTestCase or TearDownTestCase, or to the global property set +// when invoked elsewhere. If the result already contains a property with +// the same key, the value will be updated. +void UnitTest::RecordProperty(const std::string& key, + const std::string& value) { + impl_->RecordProperty(TestProperty(key, value)); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Google Test implements this protocol for catching that a test + // program exits before returning control to Google Test: + // + // 1. Upon start, Google Test creates a file whose absolute path + // is specified by the environment variable + // TEST_PREMATURE_EXIT_FILE. + // 2. When Google Test has finished its work, it deletes the file. + // + // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before + // running a Google-Test-based test program and check the existence + // of the file at the end of the test execution to see if it has + // exited prematurely. + + // If we are in the child process of a death test, don't + // create/delete the premature exit file, as doing so is unnecessary + // and will confuse the parent process. Otherwise, create/delete + // the file upon entering/leaving this function. If the program + // somehow exits before this function has a chance to return, the + // premature-exit file will be left undeleted, causing a test runner + // that understands the premature-exit-file protocol to report the + // test as having failed. + const internal::ScopedPrematureExitFile premature_exit_file( + in_death_test_child_process ? + NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); + + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_HAS_SEH + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { +# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + } +#endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */) + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), + GTEST_DISABLE_MSC_WARNINGS_POP_() + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +// Adds a TestProperty to the current TestResult object when invoked in a +// context of a test, to current test case's ad_hoc_test_result when invoke +// from SetUpTestCase/TearDownTestCase, or to the global property set +// otherwise. If the result already contains a property with the same key, +// the value will be updated. +void UnitTestImpl::RecordProperty(const TestProperty& test_property) { + std::string xml_element; + TestResult* test_result; // TestResult appropriate for property recording. + + if (current_test_info_ != NULL) { + xml_element = "testcase"; + test_result = &(current_test_info_->result_); + } else if (current_test_case_ != NULL) { + xml_element = "testsuite"; + test_result = &(current_test_case_->ad_hoc_test_result_); + } else { + xml_element = "testsuites"; + test_result = &ad_hoc_test_result_; + } + test_result->RecordProperty(xml_element, test_property); +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in string form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != std::string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const std::string& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + std::string name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(test_case_name, + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const std::string &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the given C-string on a single line by replacing all '\n' +// characters with string "\\n". If the output takes more than +// max_length characters, only prints the first max_length characters +// and "...". +static void PrintOnOneLine(const char* str, int max_length) { + if (str != NULL) { + for (int i = 0; *str != '\0'; ++str) { + if (i >= max_length) { + printf("..."); + break; + } + if (*str == '\n') { + printf("\\n"); + i += 2; + } else { + printf("%c", *str); + ++i; + } + } + } +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + // Print at most this many characters for each type/value parameter. + const int kMaxParamLength = 250; + + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.", test_case->name()); + if (test_case->type_param() != NULL) { + printf(" # %s = ", kTypeParamLabel); + // We print the type parameter on a single line to make + // the output easy to parse by a program. + PrintOnOneLine(test_case->type_param(), kMaxParamLength); + } + printf("\n"); + } + printf(" %s", test_info->name()); + if (test_info->value_param() != NULL) { + printf(" # %s = ", kValueParamLabel); + // We print the value parameter on a single line to make the + // output easy to parse by a program. + PrintOnOneLine(test_info->value_param(), kMaxParamLength); + } + printf("\n"); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + &(current_test_info_->result_) : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, std::string* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", std::string(str, p).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing diff --git a/src/test/gtest/src/gtest_main.cc b/src/test/gtest/src/gtest_main.cc new file mode 100644 index 00000000..f3028225 --- /dev/null +++ b/src/test/gtest/src/gtest_main.cc @@ -0,0 +1,38 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#include + +#include "gtest/gtest.h" + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from gtest_main.cc\n"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest-death-test_ex_test.cc b/src/test/gtest/test/gtest-death-test_ex_test.cc new file mode 100644 index 00000000..b50a13d5 --- /dev/null +++ b/src/test/gtest/test/gtest-death-test_ex_test.cc @@ -0,0 +1,93 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests that verify interaction of exceptions and death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_HAS_SEH +# include // For RaiseException(). +# endif + +# include "gtest/gtest-spi.h" + +# if GTEST_HAS_EXCEPTIONS + +# include // For std::exception. + +// Tests that death tests report thrown exceptions as failures and that the +// exceptions do not escape death test macros. +TEST(CxxExceptionDeathTest, ExceptionIsFailure) { + try { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception"); + } catch (...) { // NOLINT + FAIL() << "An exception escaped a death test macro invocation " + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); + } +} + +class TestException : public std::exception { + public: + virtual const char* what() const throw() { return "exceptional message"; } +}; + +TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) { + // Verifies that the exception message is quoted in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "exceptional message"); + // Verifies that the location is mentioned in the failure text. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), + "gtest-death-test_ex_test.cc"); +} +# endif // GTEST_HAS_EXCEPTIONS + +# if GTEST_HAS_SEH +// Tests that enabling interception of SEH exceptions with the +// catch_exceptions flag does not interfere with SEH exceptions being +// treated as death by death tests. +TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) { + EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "") + << "with catch_exceptions " + << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); +} +# endif + +#endif // GTEST_HAS_DEATH_TEST + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0; + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest-death-test_test.cc b/src/test/gtest/test/gtest-death-test_test.cc new file mode 100644 index 00000000..b25bc229 --- /dev/null +++ b/src/test/gtest/test/gtest-death-test_test.cc @@ -0,0 +1,1423 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/gtest.h" +#include "gtest/internal/gtest-filepath.h" + +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_WINDOWS +# include // For chdir(). +# else +# include +# include // For waitpid. +# endif // GTEST_OS_WINDOWS + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" +# undef GTEST_IMPLEMENTATION_ + +namespace posix = ::testing::internal::posix; + +using testing::Message; +using testing::internal::DeathTest; +using testing::internal::DeathTestFactory; +using testing::internal::FilePath; +using testing::internal::GetLastErrnoDescription; +using testing::internal::GetUnitTestImpl; +using testing::internal::InDeathTestChild; +using testing::internal::ParseNaturalNumber; + +namespace testing { +namespace internal { + +// A helper class whose objects replace the death test factory for a +// single UnitTest object during their lifetimes. +class ReplaceDeathTestFactory { + public: + explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory) + : unit_test_impl_(GetUnitTestImpl()) { + old_factory_ = unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(new_factory); + } + + ~ReplaceDeathTestFactory() { + unit_test_impl_->death_test_factory_.release(); + unit_test_impl_->death_test_factory_.reset(old_factory_); + } + private: + // Prevents copying ReplaceDeathTestFactory objects. + ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); + void operator=(const ReplaceDeathTestFactory&); + + UnitTestImpl* unit_test_impl_; + DeathTestFactory* old_factory_; +}; + +} // namespace internal +} // namespace testing + +void DieWithMessage(const ::std::string& message) { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); // Make sure the text is printed before the process exits. + + // We call _exit() instead of exit(), as the former is a direct + // system call and thus safer in the presence of threads. exit() + // will invoke user-defined exit-hooks, which may do dangerous + // things that conflict with death tests. + // + // Some compilers can recognize that _exit() never returns and issue the + // 'unreachable code' warning for code following this function, unless + // fooled by a fake condition. + if (AlwaysTrue()) + _exit(1); +} + +void DieInside(const ::std::string& function) { + DieWithMessage("death inside " + function + "()."); +} + +// Tests that death tests work. + +class TestForDeathTest : public testing::Test { + protected: + TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} + + virtual ~TestForDeathTest() { + posix::ChDir(original_dir_.c_str()); + } + + // A static member function that's expected to die. + static void StaticMemberFunction() { DieInside("StaticMemberFunction"); } + + // A method of the test fixture that may die. + void MemberFunction() { + if (should_die_) + DieInside("MemberFunction"); + } + + // True iff MemberFunction() should die. + bool should_die_; + const FilePath original_dir_; +}; + +// A class with a member function that may die. +class MayDie { + public: + explicit MayDie(bool should_die) : should_die_(should_die) {} + + // A member function that may die. + void MemberFunction() const { + if (should_die_) + DieInside("MayDie::MemberFunction"); + } + + private: + // True iff MemberFunction() should die. + bool should_die_; +}; + +// A global function that's expected to die. +void GlobalFunction() { DieInside("GlobalFunction"); } + +// A non-void function that's expected to die. +int NonVoidFunction() { + DieInside("NonVoidFunction"); + return 1; +} + +// A unary function that may die. +void DieIf(bool should_die) { + if (should_die) + DieInside("DieIf"); +} + +// A binary function that may die. +bool DieIfLessThan(int x, int y) { + if (x < y) { + DieInside("DieIfLessThan"); + } + return true; +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +void DeathTestSubroutine() { + EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction"); + ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction"); +} + +// Death in dbg, not opt. +int DieInDebugElse12(int* sideeffect) { + if (sideeffect) *sideeffect = 12; + +# ifndef NDEBUG + + DieInside("DieInDebugElse12"); + +# endif // NDEBUG + + return 12; +} + +# if GTEST_OS_WINDOWS + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + // On Windows, the process's exit code is the same as its exit status, + // so the predicate just compares the its input with its parameter. + EXPECT_TRUE(testing::ExitedWithCode(0)(0)); + EXPECT_TRUE(testing::ExitedWithCode(1)(1)); + EXPECT_TRUE(testing::ExitedWithCode(42)(42)); + EXPECT_FALSE(testing::ExitedWithCode(0)(1)); + EXPECT_FALSE(testing::ExitedWithCode(1)(0)); +} + +# else + +// Returns the exit status of a process that calls _exit(2) with a +// given exit code. This is a helper function for the +// ExitStatusPredicateTest test suite. +static int NormalExitStatus(int exit_code) { + pid_t child_pid = fork(); + if (child_pid == 0) { + _exit(exit_code); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Returns the exit status of a process that raises a given signal. +// If the signal does not cause the process to die, then it returns +// instead the exit status of a process that exits normally with exit +// code 1. This is a helper function for the ExitStatusPredicateTest +// test suite. +static int KilledExitStatus(int signum) { + pid_t child_pid = fork(); + if (child_pid == 0) { + raise(signum); + _exit(1); + } + int status; + waitpid(child_pid, &status, 0); + return status; +} + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + const int status0 = NormalExitStatus(0); + const int status1 = NormalExitStatus(1); + const int status42 = NormalExitStatus(42); + const testing::ExitedWithCode pred0(0); + const testing::ExitedWithCode pred1(1); + const testing::ExitedWithCode pred42(42); + EXPECT_PRED1(pred0, status0); + EXPECT_PRED1(pred1, status1); + EXPECT_PRED1(pred42, status42); + EXPECT_FALSE(pred0(status1)); + EXPECT_FALSE(pred42(status0)); + EXPECT_FALSE(pred1(status42)); +} + +// Tests the KilledBySignal predicate. +TEST(ExitStatusPredicateTest, KilledBySignal) { + const int status_segv = KilledExitStatus(SIGSEGV); + const int status_kill = KilledExitStatus(SIGKILL); + const testing::KilledBySignal pred_segv(SIGSEGV); + const testing::KilledBySignal pred_kill(SIGKILL); + EXPECT_PRED1(pred_segv, status_segv); + EXPECT_PRED1(pred_kill, status_kill); + EXPECT_FALSE(pred_segv(status_kill)); + EXPECT_FALSE(pred_kill(status_segv)); +} + +# endif // GTEST_OS_WINDOWS + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +TEST_F(TestForDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; + + if (AlwaysFalse()) + ASSERT_DEATH(return, "") << "did not die"; + + if (AlwaysFalse()) + ; + else + EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; +} + +void DieWithEmbeddedNul() { + fprintf(stderr, "Hello%cmy null world.\n", '\0'); + fflush(stderr); + _exit(1); +} + +# if GTEST_USES_PCRE +// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error +// message has a NUL character in it. +TEST_F(TestForDeathTest, EmbeddedNulInMessage) { + // TODO(wan@google.com): doesn't support matching strings + // with embedded NUL characters - find a way to workaround it. + EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); + ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); +} +# endif // GTEST_USES_PCRE + +// Tests that death test macros expand to code which interacts well with switch +// statements. +TEST_F(TestForDeathTest, SwitchStatement) { + // Microsoft compiler usually complains about switch statements without + // case labels. We suppress that warning for this test. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) + + switch (0) + default: + ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH(_exit(1), "") << "exit in switch case"; + + GTEST_DISABLE_MSC_WARNINGS_POP_() +} + +// Tests that a static member function can be used in a "fast" style +// death test. +TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +// Tests that a method of the test fixture can be used in a "fast" +// style death test. +TEST_F(TestForDeathTest, MemberFunctionFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); } + +// Tests that death tests work even if the current directory has been +// changed. +TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "fast"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +# if GTEST_OS_LINUX +void SigprofAction(int, siginfo_t*, void*) { /* no op */ } + +// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). +void SetSigprofActionAndTimer() { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_sigaction = SigprofAction; + signal_action.sa_flags = SA_RESTART | SA_SIGINFO; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL)); +} + +// Disables ITIMER_PROF timer and ignores SIGPROF signal. +void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); + struct sigaction signal_action; + memset(&signal_action, 0, sizeof(signal_action)); + sigemptyset(&signal_action.sa_mask); + signal_action.sa_handler = SIG_IGN; + ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action)); +} + +// Tests that death tests work when SIGPROF handler and timer are set. +TEST_F(TestForDeathTest, FastSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "fast"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} + +TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + SetSigprofActionAndTimer(); + EXPECT_DEATH(_exit(1), ""); + struct sigaction old_signal_action; + DisableSigprofActionAndTimer(&old_signal_action); + EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); +} +# endif // GTEST_OS_LINUX + +// Repeats a representative sample of death tests in the "threadsafe" style: + +TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); +} + +TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + should_die_ = true; + EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + for (int i = 0; i < 3; ++i) + EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; +} + +TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + + ChangeToRootDir(); + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + + ChangeToRootDir(); + ASSERT_DEATH(_exit(1), ""); +} + +TEST_F(TestForDeathTest, MixedStyles) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH(_exit(1), ""); + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(_exit(1), ""); +} + +# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +namespace { + +bool pthread_flag; + +void SetPthreadFlag() { + pthread_flag = true; +} + +} // namespace + +TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { + if (!testing::GTEST_FLAG(death_test_use_fork)) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + pthread_flag = false; + ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); + ASSERT_DEATH(_exit(1), ""); + ASSERT_FALSE(pthread_flag); + } +} + +# endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD + +// Tests that a method of another class can be used in a death test. +TEST_F(TestForDeathTest, MethodOfAnotherClass) { + const MayDie x(true); + ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction"); +} + +// Tests that a global function can be used in a death test. +TEST_F(TestForDeathTest, GlobalFunction) { + EXPECT_DEATH(GlobalFunction(), "GlobalFunction"); +} + +// Tests that any value convertible to an RE works as a second +// argument to EXPECT_DEATH. +TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { + static const char regex_c_str[] = "GlobalFunction"; + EXPECT_DEATH(GlobalFunction(), regex_c_str); + + const testing::internal::RE regex(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex); + +# if GTEST_HAS_GLOBAL_STRING + + const string regex_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_str); + +# endif // GTEST_HAS_GLOBAL_STRING + + const ::std::string regex_std_str(regex_c_str); + EXPECT_DEATH(GlobalFunction(), regex_std_str); +} + +// Tests that a non-void function can be used in a death test. +TEST_F(TestForDeathTest, NonVoidFunction) { + ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction"); +} + +// Tests that functions that take parameter(s) can be used in a death test. +TEST_F(TestForDeathTest, FunctionWithParameter) { + EXPECT_DEATH(DieIf(true), "DieIf\\(\\)"); + EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan"); +} + +// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. +TEST_F(TestForDeathTest, OutsideFixture) { + DeathTestSubroutine(); +} + +// Tests that death tests can be done inside a loop. +TEST_F(TestForDeathTest, InsideLoop) { + for (int i = 0; i < 5; i++) { + EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i; + } +} + +// Tests that a compound statement can be used in a death test. +TEST_F(TestForDeathTest, CompoundStatement) { + EXPECT_DEATH({ // NOLINT + const int x = 2; + const int y = x + 1; + DieIfLessThan(x, y); + }, + "DieIfLessThan"); +} + +// Tests that code that doesn't die causes a death test to fail. +TEST_F(TestForDeathTest, DoesNotDie) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"), + "failed to die"); +} + +// Tests that a death test fails when the error message isn't expected. +TEST_F(TestForDeathTest, ErrorMessageMismatch) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message."; + }, "died but not with expected error"); +} + +// On exit, *aborted will be true iff the EXPECT_DEATH() statement +// aborted the function. +void ExpectDeathTestHelper(bool* aborted) { + *aborted = true; + EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + *aborted = false; +} + +// Tests that EXPECT_DEATH doesn't abort the test on failure. +TEST_F(TestForDeathTest, EXPECT_DEATH) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted), + "failed to die"); + EXPECT_FALSE(aborted); +} + +// Tests that ASSERT_DEATH does abort the test on failure. +TEST_F(TestForDeathTest, ASSERT_DEATH) { + static bool aborted; + EXPECT_FATAL_FAILURE({ // NOLINT + aborted = true; + ASSERT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. + aborted = false; + }, "failed to die"); + EXPECT_TRUE(aborted); +} + +// Tests that EXPECT_DEATH evaluates the arguments exactly once. +TEST_F(TestForDeathTest, SingleEvaluation) { + int x = 3; + EXPECT_DEATH(DieIf((++x) == 4), "DieIf"); + + const char* regex = "DieIf"; + const char* regex_save = regex; + EXPECT_DEATH(DieIfLessThan(3, 4), regex++); + EXPECT_EQ(regex_save + 1, regex); +} + +// Tests that run-away death tests are reported as failures. +TEST_F(TestForDeathTest, RunawayIsFailure) { + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), + "failed to die."); +} + +// Tests that death tests report executing 'return' in the statement as +// failure. +TEST_F(TestForDeathTest, ReturnIsFailure) { + EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), + "illegal return in test statement."); +} + +// Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestExpectDebugDeath) { + int sideeffect = 0; + + EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +// Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a +// message to it, and in debug mode it: +// 1. Asserts on death. +// 2. Has no side effect. +// +// And in opt mode, it: +// 1. Has side effects but does not assert. +TEST_F(TestForDeathTest, TestAssertDebugDeath) { + int sideeffect = 0; + + ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + << "Must accept a streamed message"; + +# ifdef NDEBUG + + // Checks that the assignment occurs in opt mode (sideeffect). + EXPECT_EQ(12, sideeffect); + +# else + + // Checks that the assignment does not occur in dbg mode (no sideeffect). + EXPECT_EQ(0, sideeffect); + +# endif +} + +# ifndef NDEBUG + +void ExpectDebugDeathHelper(bool* aborted) { + *aborted = true; + EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail."; + *aborted = false; +} + +# if GTEST_OS_WINDOWS +TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + abort(); + }, ""); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEBUG_DEATH in debug mode does not abort +// the function. +TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), ""); + EXPECT_FALSE(aborted); +} + +void AssertDebugDeathHelper(bool* aborted) { + *aborted = true; + GTEST_LOG_(INFO) << "Before ASSERT_DEBUG_DEATH"; + ASSERT_DEBUG_DEATH(GTEST_LOG_(INFO) << "In ASSERT_DEBUG_DEATH"; return, "") + << "This is expected to fail."; + GTEST_LOG_(INFO) << "After ASSERT_DEBUG_DEATH"; + *aborted = false; +} + +// Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on +// failure. +TEST_F(TestForDeathTest, AssertDebugDeathAborts) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts2) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts3) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts4) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts5) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts6) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts7) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts8) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts9) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +TEST_F(TestForDeathTest, AssertDebugDeathAborts10) { + static bool aborted; + aborted = false; + EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); + EXPECT_TRUE(aborted); +} + +# endif // _NDEBUG + +// Tests the *_EXIT family of macros, using a variety of predicates. +static void TestExitMacros() { + EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); + ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); + +# if GTEST_OS_WINDOWS + + // Of all signals effects on the process exit code, only those of SIGABRT + // are documented on Windows. + // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. + EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar"; + +# else + + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; + ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") + << "This failure is expected, too."; + }, "This failure is expected, too."); + +# endif // GTEST_OS_WINDOWS + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") + << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, ExitMacros) { + TestExitMacros(); +} + +TEST_F(TestForDeathTest, ExitMacrosUsingFork) { + testing::GTEST_FLAG(death_test_use_fork) = true; + TestExitMacros(); +} + +TEST_F(TestForDeathTest, InvalidStyle) { + testing::GTEST_FLAG(death_test_style) = "rococo"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "This failure is expected."; + }, "This failure is expected."); +} + +TEST_F(TestForDeathTest, DeathTestFailedOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("death\n"), + "expected message"), + "Actual msg:\n" + "[ DEATH ] death\n"); +} + +TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH({ + fprintf(stderr, "returning\n"); + fflush(stderr); + return; + }, ""), + " Result: illegal return in test statement.\n" + " Error msg:\n" + "[ DEATH ] returning\n"); +} + +TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), + testing::ExitedWithCode(3), + "expected message"), + " Result: died but not with expected exit code:\n" + " Exited with exit status 1\n" + "Actual msg:\n" + "[ DEATH ] exiting with rc 1\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nxyz\nline 3\n"), + "Actual msg:\n" + "[ DEATH ] line 1\n" + "[ DEATH ] line 2\n" + "[ DEATH ] line 3\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nline 2\nline 3\n"); +} + +// A DeathTestFactory that returns MockDeathTests. +class MockDeathTestFactory : public DeathTestFactory { + public: + MockDeathTestFactory(); + virtual bool Create(const char* statement, + const ::testing::internal::RE* regex, + const char* file, int line, DeathTest** test); + + // Sets the parameters for subsequent calls to Create. + void SetParameters(bool create, DeathTest::TestRole role, + int status, bool passed); + + // Accessors. + int AssumeRoleCalls() const { return assume_role_calls_; } + int WaitCalls() const { return wait_calls_; } + int PassedCalls() const { return passed_args_.size(); } + bool PassedArgument(int n) const { return passed_args_[n]; } + int AbortCalls() const { return abort_args_.size(); } + DeathTest::AbortReason AbortArgument(int n) const { + return abort_args_[n]; + } + bool TestDeleted() const { return test_deleted_; } + + private: + friend class MockDeathTest; + // If true, Create will return a MockDeathTest; otherwise it returns + // NULL. + bool create_; + // The value a MockDeathTest will return from its AssumeRole method. + DeathTest::TestRole role_; + // The value a MockDeathTest will return from its Wait method. + int status_; + // The value a MockDeathTest will return from its Passed method. + bool passed_; + + // Number of times AssumeRole was called. + int assume_role_calls_; + // Number of times Wait was called. + int wait_calls_; + // The arguments to the calls to Passed since the last call to + // SetParameters. + std::vector passed_args_; + // The arguments to the calls to Abort since the last call to + // SetParameters. + std::vector abort_args_; + // True if the last MockDeathTest returned by Create has been + // deleted. + bool test_deleted_; +}; + + +// A DeathTest implementation useful in testing. It returns values set +// at its creation from its various inherited DeathTest methods, and +// reports calls to those methods to its parent MockDeathTestFactory +// object. +class MockDeathTest : public DeathTest { + public: + MockDeathTest(MockDeathTestFactory *parent, + TestRole role, int status, bool passed) : + parent_(parent), role_(role), status_(status), passed_(passed) { + } + virtual ~MockDeathTest() { + parent_->test_deleted_ = true; + } + virtual TestRole AssumeRole() { + ++parent_->assume_role_calls_; + return role_; + } + virtual int Wait() { + ++parent_->wait_calls_; + return status_; + } + virtual bool Passed(bool exit_status_ok) { + parent_->passed_args_.push_back(exit_status_ok); + return passed_; + } + virtual void Abort(AbortReason reason) { + parent_->abort_args_.push_back(reason); + } + + private: + MockDeathTestFactory* const parent_; + const TestRole role_; + const int status_; + const bool passed_; +}; + + +// MockDeathTestFactory constructor. +MockDeathTestFactory::MockDeathTestFactory() + : create_(true), + role_(DeathTest::OVERSEE_TEST), + status_(0), + passed_(true), + assume_role_calls_(0), + wait_calls_(0), + passed_args_(), + abort_args_() { +} + + +// Sets the parameters for subsequent calls to Create. +void MockDeathTestFactory::SetParameters(bool create, + DeathTest::TestRole role, + int status, bool passed) { + create_ = create; + role_ = role; + status_ = status; + passed_ = passed; + + assume_role_calls_ = 0; + wait_calls_ = 0; + passed_args_.clear(); + abort_args_.clear(); +} + + +// Sets test to NULL (if create_ is false) or to the address of a new +// MockDeathTest object with parameters taken from the last call +// to SetParameters (if create_ is true). Always returns true. +bool MockDeathTestFactory::Create(const char* /*statement*/, + const ::testing::internal::RE* /*regex*/, + const char* /*file*/, + int /*line*/, + DeathTest** test) { + test_deleted_ = false; + if (create_) { + *test = new MockDeathTest(this, role_, status_, passed_); + } else { + *test = NULL; + } + return true; +} + +// A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro. +// It installs a MockDeathTestFactory that is used for the duration +// of the test case. +class MacroLogicDeathTest : public testing::Test { + protected: + static testing::internal::ReplaceDeathTestFactory* replacer_; + static MockDeathTestFactory* factory_; + + static void SetUpTestCase() { + factory_ = new MockDeathTestFactory; + replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_); + } + + static void TearDownTestCase() { + delete replacer_; + replacer_ = NULL; + delete factory_; + factory_ = NULL; + } + + // Runs a death test that breaks the rules by returning. Such a death + // test cannot be run directly from a test routine that uses a + // MockDeathTest, or the remainder of the routine will not be executed. + static void RunReturningDeathTest(bool* flag) { + ASSERT_DEATH({ // NOLINT + *flag = true; + return; + }, ""); + } +}; + +testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_ + = NULL; +MockDeathTestFactory* MacroLogicDeathTest::factory_ = NULL; + + +// Test that nothing happens when the factory doesn't return a DeathTest: +TEST_F(MacroLogicDeathTest, NothingHappens) { + bool flag = false; + factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(0, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_FALSE(factory_->TestDeleted()); +} + +// Test that the parent process doesn't run the death test code, +// and that the Passed method returns false when the (simulated) +// child process exits with status 0: +TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_FALSE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the Passed method was given the argument "true" when +// the (simulated) child process exits with status 1: +TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { + bool flag = false; + factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_FALSE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(1, factory_->WaitCalls()); + ASSERT_EQ(1, factory_->PassedCalls()); + EXPECT_TRUE(factory_->PassedArgument(0)); + EXPECT_EQ(0, factory_->AbortCalls()); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process executes the death test +// code, and is aborted with the correct AbortReason if it +// executes a return statement. +TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + RunReturningDeathTest(&flag); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + EXPECT_EQ(1, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(0)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that the (simulated) child process is aborted with the +// correct AbortReason if it does not die. +TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { + bool flag = false; + factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); + EXPECT_DEATH(flag = true, ""); + EXPECT_TRUE(flag); + EXPECT_EQ(1, factory_->AssumeRoleCalls()); + EXPECT_EQ(0, factory_->WaitCalls()); + EXPECT_EQ(0, factory_->PassedCalls()); + // This time there are two calls to Abort: one since the test didn't + // die, and another from the ReturnSentinel when it's destroyed. The + // sentinel normally isn't destroyed if a test doesn't die, since + // _exit(2) is called in that case by ForkingDeathTest, but not by + // our MockDeathTest. + ASSERT_EQ(2, factory_->AbortCalls()); + EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, + factory_->AbortArgument(0)); + EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, + factory_->AbortArgument(1)); + EXPECT_TRUE(factory_->TestDeleted()); +} + +// Tests that a successful death test does not register a successful +// test part. +TEST(SuccessRegistrationDeathTest, NoSuccessPart) { + EXPECT_DEATH(_exit(1), ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +TEST(StreamingAssertionsDeathTest, DeathTest) { + EXPECT_DEATH(_exit(1), "") << "unexpected failure"; + ASSERT_DEATH(_exit(1), "") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DEATH(_exit(0), "") << "expected failure"; + }, "expected failure"); +} + +// Tests that GetLastErrnoDescription returns an empty string when the +// last error is 0 and non-empty string when it is non-zero. +TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { + errno = ENOENT; + EXPECT_STRNE("", GetLastErrnoDescription().c_str()); + errno = 0; + EXPECT_STREQ("", GetLastErrnoDescription().c_str()); +} + +# if GTEST_OS_WINDOWS +TEST(AutoHandleTest, AutoHandleWorks) { + HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + + // Tests that the AutoHandle is correctly initialized with a handle. + testing::internal::AutoHandle auto_handle(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that Reset assigns INVALID_HANDLE_VALUE. + // Note that this cannot verify whether the original handle is closed. + auto_handle.Reset(); + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); + + // Tests that Reset assigns the new handle. + // Note that this cannot verify whether the original handle is closed. + handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + auto_handle.Reset(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. + testing::internal::AutoHandle auto_handle2; + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); +} +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_WINDOWS +typedef unsigned __int64 BiggestParsable; +typedef signed __int64 BiggestSignedParsable; +# else +typedef unsigned long long BiggestParsable; +typedef signed long long BiggestSignedParsable; +# endif // GTEST_OS_WINDOWS + +// We cannot use std::numeric_limits::max() as it clashes with the +// max() macro defined by . +const BiggestParsable kBiggestParsableMax = ULLONG_MAX; +const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; + +TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { + BiggestParsable result = 0; + + // Rejects non-numbers. + EXPECT_FALSE(ParseNaturalNumber("non-number string", &result)); + + // Rejects numbers with whitespace prefix. + EXPECT_FALSE(ParseNaturalNumber(" 123", &result)); + + // Rejects negative numbers. + EXPECT_FALSE(ParseNaturalNumber("-123", &result)); + + // Rejects numbers starting with a plus sign. + EXPECT_FALSE(ParseNaturalNumber("+123", &result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { + BiggestParsable result = 0; + + EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result)); + + signed char char_result = 0; + EXPECT_FALSE(ParseNaturalNumber("200", &char_result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { + BiggestParsable result = 0; + + result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &result)); + EXPECT_EQ(123U, result); + + // Check 0 as an edge case. + result = 1; + ASSERT_TRUE(ParseNaturalNumber("0", &result)); + EXPECT_EQ(0U, result); + + result = 1; + ASSERT_TRUE(ParseNaturalNumber("00000", &result)); + EXPECT_EQ(0U, result); +} + +TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { + Message msg; + msg << kBiggestParsableMax; + + BiggestParsable result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); + EXPECT_EQ(kBiggestParsableMax, result); + + Message msg2; + msg2 << kBiggestSignedParsableMax; + + BiggestSignedParsable signed_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); + EXPECT_EQ(kBiggestSignedParsableMax, signed_result); + + Message msg3; + msg3 << INT_MAX; + + int int_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); + EXPECT_EQ(INT_MAX, int_result); + + Message msg4; + msg4 << UINT_MAX; + + unsigned int uint_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); + EXPECT_EQ(UINT_MAX, uint_result); +} + +TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { + short short_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &short_result)); + EXPECT_EQ(123, short_result); + + signed char char_result = 0; + ASSERT_TRUE(ParseNaturalNumber("123", &char_result)); + EXPECT_EQ(123, char_result); +} + +# if GTEST_OS_WINDOWS +TEST(EnvironmentTest, HandleFitsIntoSizeT) { + // TODO(vladl@google.com): Remove this test after this condition is verified + // in a static assertion in gtest-death-test.cc in the function + // GetStatusFileDescriptor. + ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); +} +# endif // GTEST_OS_WINDOWS + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger +// failures when death tests are available on the system. +TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { + EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"), + "death inside CondDeathTestExpectMacro"); + ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"), + "death inside CondDeathTestAssertMacro"); + + // Empty statement will not crash, which must trigger a failure. + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); + EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +#else // !GTEST_HAS_DEATH_TEST follows + +using testing::internal::CaptureStderr; +using testing::internal::GetCapturedStderr; + +// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still +// defined but do not trigger failures when death tests are not available on +// the system. +TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { + // Empty statement will not crash, but that should not trigger a failure + // when death tests are not supported. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, ""); + std::string output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + // The streamed message should not be printed as there is no test failure. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL != strstr(output.c_str(), + "Death tests are not supported on this platform")); + ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); +} + +void FuncWithAssert(int* n) { + ASSERT_DEATH_IF_SUPPORTED(return;, ""); + (*n)++; +} + +// Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current +// function (as ASSERT_DEATH does) if death tests are not supported. +TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { + int n = 0; + FuncWithAssert(&n); + EXPECT_EQ(1, n); +} + +#endif // !GTEST_HAS_DEATH_TEST + +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +// +// The syntax should work whether death tests are available or not. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH_IF_SUPPORTED(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; +} + +// Tests that conditional death test macros expand to code which interacts +// well with switch statements. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { + // Microsoft compiler usually complains about switch statements without + // case labels. We suppress that warning for this test. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) + + switch (0) + default: + ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") + << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; + + GTEST_DISABLE_MSC_WARNINGS_POP_() +} + +// Tests that a test case whose name ends with "DeathTest" works fine +// on Windows. +TEST(NotADeathTest, Test) { + SUCCEED(); +} diff --git a/src/test/gtest/test/gtest-filepath_test.cc b/src/test/gtest/test/gtest-filepath_test.cc new file mode 100644 index 00000000..ae9f55a0 --- /dev/null +++ b/src/test/gtest/test/gtest-filepath_test.cc @@ -0,0 +1,680 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest_unittest.cc, to avoid changing +// build or make-files for some existing Google Test clients. Do not +// #include this file anywhere else! + +#include "gtest/internal/gtest-filepath.h" +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS_MOBILE +# include // NOLINT +#elif GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS_MOBILE + +namespace testing { +namespace internal { +namespace { + +#if GTEST_OS_WINDOWS_MOBILE +// TODO(wan@google.com): Move these to the POSIX adapter section in +// gtest-port.h. + +// Windows CE doesn't have the remove C function. +int remove(const char* path) { + LPCWSTR wpath = String::AnsiToUtf16(path); + int ret = DeleteFile(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} +// Windows CE doesn't have the _rmdir C function. +int _rmdir(const char* path) { + FilePath filepath(path); + LPCWSTR wpath = String::AnsiToUtf16( + filepath.RemoveTrailingPathSeparator().c_str()); + int ret = RemoveDirectory(wpath) ? 0 : -1; + delete [] wpath; + return ret; +} + +#else + +TEST(GetCurrentDirTest, ReturnsCurrentDir) { + const FilePath original_dir = FilePath::GetCurrentDir(); + EXPECT_FALSE(original_dir.IsEmpty()); + + posix::ChDir(GTEST_PATH_SEP_); + const FilePath cwd = FilePath::GetCurrentDir(); + posix::ChDir(original_dir.c_str()); + +# if GTEST_OS_WINDOWS + + // Skips the ":". + const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); + ASSERT_TRUE(cwd_without_drive != NULL); + EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); + +# else + + EXPECT_EQ(GTEST_PATH_SEP_, cwd.string()); + +# endif +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { + EXPECT_TRUE(FilePath("").IsEmpty()); +} + +TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { + EXPECT_FALSE(FilePath("a").IsEmpty()); + EXPECT_FALSE(FilePath(".").IsEmpty()); + EXPECT_FALSE(FilePath("a/b").IsEmpty()); + EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); +} + +// RemoveDirectoryName "" -> "" +TEST(RemoveDirectoryNameTest, WhenEmptyName) { + EXPECT_EQ("", FilePath("").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "afile" -> "afile" +TEST(RemoveDirectoryNameTest, ButNoDirectory) { + EXPECT_EQ("afile", + FilePath("afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "/afile" -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/" -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { + EXPECT_EQ("", + FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName "adir/subdir/afile" -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { + EXPECT_EQ("afile", + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveDirectoryName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveDirectoryName() works with the alternate separator +// on Windows. + +// RemoveDirectoryName("/afile") -> "afile" +TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/") -> "" +TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { + EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string()); +} + +// RemoveDirectoryName("adir/subdir/afile") -> "afile" +TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { + EXPECT_EQ("afile", + FilePath("adir/subdir/afile").RemoveDirectoryName().string()); +} + +#endif + +// RemoveFileName "" -> "./" +TEST(RemoveFileNameTest, EmptyName) { +#if GTEST_OS_WINDOWS_MOBILE + // On Windows CE, we use the root as the current directory. + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#else + EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); +#endif +} + +// RemoveFileName "adir/" -> "adir/" +TEST(RemoveFileNameTest, ButNoFile) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string()); +} + +// RemoveFileName "adir/afile" -> "adir/" +TEST(RemoveFileNameTest, GivesDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +// RemoveFileName "adir/subdir/afile" -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirName) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") + .RemoveFileName().string()); +} + +// RemoveFileName "/afile" -> "/" +TEST(RemoveFileNameTest, GivesRootDir) { + EXPECT_EQ(GTEST_PATH_SEP_, + FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that RemoveFileName() works with the alternate separator on +// Windows. + +// RemoveFileName("adir/") -> "adir/" +TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/").RemoveFileName().string()); +} + +// RemoveFileName("adir/afile") -> "adir/" +TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_, + FilePath("adir/afile").RemoveFileName().string()); +} + +// RemoveFileName("adir/subdir/afile") -> "adir/subdir/" +TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { + EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, + FilePath("adir/subdir/afile").RemoveFileName().string()); +} + +// RemoveFileName("/afile") -> "\" +TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { + EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string()); +} + +#endif + +TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), + 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 0, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { + FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar"), 12, "xml"); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 0, "xml"); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { + FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), + 14, "xml"); + EXPECT_EQ("bar_14.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path1BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("bar.xml")); + EXPECT_EQ("bar.xml", actual.string()); +} + +TEST(ConcatPathsTest, Path2BeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("")); + EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string()); +} + +TEST(ConcatPathsTest, BothPathBeingEmpty) { + FilePath actual = FilePath::ConcatPaths(FilePath(""), + FilePath("")); + EXPECT_EQ("", actual.string()); +} + +TEST(ConcatPathsTest, Path1ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), + FilePath("foobar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2ContainsPathSep) { + FilePath actual = FilePath::ConcatPaths( + FilePath("foo" GTEST_PATH_SEP_), + FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", + actual.string()); +} + +TEST(ConcatPathsTest, Path2EndsWithPathSep) { + FilePath actual = FilePath::ConcatPaths(FilePath("foo"), + FilePath("bar" GTEST_PATH_SEP_)); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string()); +} + +// RemoveTrailingPathSeparator "" -> "" +TEST(RemoveTrailingPathSeparatorTest, EmptyString) { + EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { + EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/" -> "foo" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { + EXPECT_EQ("foo", + FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string()); +#endif +} + +// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" +TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) + .RemoveTrailingPathSeparator().string()); +} + +// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" +TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar") + .RemoveTrailingPathSeparator().string()); +} + +TEST(DirectoryTest, RootDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. + char current_drive[_MAX_PATH]; // NOLINT + current_drive[0] = static_cast(_getdrive() + 'A' - 1); + current_drive[1] = ':'; + current_drive[2] = '\\'; + current_drive[3] = '\0'; + EXPECT_TRUE(FilePath(current_drive).DirectoryExists()); +#else + EXPECT_TRUE(FilePath("/").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +#if GTEST_OS_WINDOWS +TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { + const int saved_drive_ = _getdrive(); + // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. + for (char drive = 'Z'; drive >= 'A'; drive--) + if (_chdrive(drive - 'A' + 1) == -1) { + char non_drive[_MAX_PATH]; // NOLINT + non_drive[0] = drive; + non_drive[1] = ':'; + non_drive[2] = '\\'; + non_drive[3] = '\0'; + EXPECT_FALSE(FilePath(non_drive).DirectoryExists()); + break; + } + _chdrive(saved_drive_); +} +#endif // GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +// Windows CE _does_ consider an empty directory to exist. +TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { + EXPECT_FALSE(FilePath("").DirectoryExists()); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(DirectoryTest, CurrentDirectoryExists) { +#if GTEST_OS_WINDOWS // We are on Windows. +# ifndef _WIN32_CE // Windows CE doesn't have a current directory. + + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath(".\\").DirectoryExists()); + +# endif // _WIN32_CE +#else + EXPECT_TRUE(FilePath(".").DirectoryExists()); + EXPECT_TRUE(FilePath("./").DirectoryExists()); +#endif // GTEST_OS_WINDOWS +} + +// "foo/bar" == foo//bar" == "foo///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ + GTEST_PATH_SEP_ "bar").string()); +} + +// "/bar" == //bar" == "///bar" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); + EXPECT_EQ(GTEST_PATH_SEP_ "bar", + FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); +} + +// "foo/" == foo//" == "foo///" +TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); +} + +#if GTEST_HAS_ALT_PATH_SEP_ + +// Tests that separators at the end of the string are normalized +// regardless of their combination (e.g. "foo\" =="foo/\" == +// "foo\\/"). +TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo" GTEST_PATH_SEP_ "/").string()); + EXPECT_EQ("foo" GTEST_PATH_SEP_, + FilePath("foo//" GTEST_PATH_SEP_).string()); +} + +#endif + +TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { + FilePath default_path; + FilePath non_default_path("path"); + non_default_path = default_path; + EXPECT_EQ("", non_default_path.string()); + EXPECT_EQ("", default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { + FilePath non_default_path("path"); + FilePath default_path; + default_path = non_default_path; + EXPECT_EQ("path", default_path.string()); + EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged. +} + +TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { + const FilePath const_default_path("const_path"); + FilePath non_default_path("path"); + non_default_path = const_default_path; + EXPECT_EQ("const_path", non_default_path.string()); +} + +class DirectoryCreationTest : public Test { + protected: + virtual void SetUp() { + testdata_path_.Set(FilePath( + TempDir() + GetCurrentExecutableName().string() + + "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_)); + testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); + + unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 0, "txt")); + unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), + 1, "txt")); + + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + virtual void TearDown() { + remove(testdata_file_.c_str()); + remove(unique_file0_.c_str()); + remove(unique_file1_.c_str()); + posix::RmDir(testdata_path_.c_str()); + } + + std::string TempDir() const { +#if GTEST_OS_WINDOWS_MOBILE + return "\\temp\\"; +#elif GTEST_OS_WINDOWS + const char* temp_dir = posix::GetEnv("TEMP"); + if (temp_dir == NULL || temp_dir[0] == '\0') + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; + else + return std::string(temp_dir) + "\\"; +#elif GTEST_OS_LINUX_ANDROID + return "/sdcard/"; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE + } + + void CreateTextFile(const char* filename) { + FILE* f = posix::FOpen(filename, "w"); + fprintf(f, "text\n"); + fclose(f); + } + + // Strings representing a directory and a file, with identical paths + // except for the trailing separator character that distinquishes + // a directory named 'test' from a file named 'test'. Example names: + FilePath testdata_path_; // "/tmp/directory_creation/test/" + FilePath testdata_file_; // "/tmp/directory_creation/test" + FilePath unique_file0_; // "/tmp/directory_creation/test/unique.txt" + FilePath unique_file1_; // "/tmp/directory_creation/test/unique_1.txt" +}; + +TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + EXPECT_TRUE(testdata_path_.DirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { + EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); + // Call 'create' again... should still succeed. + EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { + FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file0_.string(), file_path.string()); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there + + testdata_path_.CreateDirectoriesRecursively(); + EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file still not there + CreateTextFile(file_path.c_str()); + EXPECT_TRUE(file_path.FileOrDirectoryExists()); + + FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, + FilePath("unique"), "txt")); + EXPECT_EQ(unique_file1_.string(), file_path2.string()); + EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there + CreateTextFile(file_path2.c_str()); + EXPECT_TRUE(file_path2.FileOrDirectoryExists()); +} + +TEST_F(DirectoryCreationTest, CreateDirectoriesFail) { + // force a failure by putting a file where we will try to create a directory. + CreateTextFile(testdata_file_.c_str()); + EXPECT_TRUE(testdata_file_.FileOrDirectoryExists()); + EXPECT_FALSE(testdata_file_.DirectoryExists()); + EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively()); +} + +TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) { + const FilePath test_detail_xml("test_detail.xml"); + EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively()); +} + +TEST(FilePathTest, DefaultConstructor) { + FilePath fp; + EXPECT_EQ("", fp.string()); +} + +TEST(FilePathTest, CharAndCopyConstructors) { + const FilePath fp("spicy"); + EXPECT_EQ("spicy", fp.string()); + + const FilePath fp_copy(fp); + EXPECT_EQ("spicy", fp_copy.string()); +} + +TEST(FilePathTest, StringConstructor) { + const FilePath fp(std::string("cider")); + EXPECT_EQ("cider", fp.string()); +} + +TEST(FilePathTest, Set) { + const FilePath apple("apple"); + FilePath mac("mac"); + mac.Set(apple); // Implement Set() since overloading operator= is forbidden. + EXPECT_EQ("apple", mac.string()); + EXPECT_EQ("apple", apple.string()); +} + +TEST(FilePathTest, ToString) { + const FilePath file("drink"); + EXPECT_EQ("drink", file.string()); +} + +TEST(FilePathTest, RemoveExtension) { + EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string()); + EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string()); + EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { + EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string()); +} + +TEST(FilePathTest, IsDirectory) { + EXPECT_FALSE(FilePath("cola").IsDirectory()); + EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory()); +#if GTEST_HAS_ALT_PATH_SEP_ + EXPECT_TRUE(FilePath("koala/").IsDirectory()); +#endif +} + +TEST(FilePathTest, IsAbsolutePath) { + EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("").IsAbsolutePath()); +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); + EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath()); + EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not" + GTEST_PATH_SEP_ "relative").IsAbsolutePath()); +#else + EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") + .IsAbsolutePath()); +#endif // GTEST_OS_WINDOWS +} + +TEST(FilePathTest, IsRootDirectory) { +#if GTEST_OS_WINDOWS + EXPECT_TRUE(FilePath("a:\\").IsRootDirectory()); + EXPECT_TRUE(FilePath("Z:/").IsRootDirectory()); + EXPECT_TRUE(FilePath("e://").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:").IsRootDirectory()); + EXPECT_FALSE(FilePath("b:a").IsRootDirectory()); + EXPECT_FALSE(FilePath("8:/").IsRootDirectory()); + EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); +#else + EXPECT_TRUE(FilePath("/").IsRootDirectory()); + EXPECT_TRUE(FilePath("//").IsRootDirectory()); + EXPECT_FALSE(FilePath("").IsRootDirectory()); + EXPECT_FALSE(FilePath("\\").IsRootDirectory()); + EXPECT_FALSE(FilePath("/x").IsRootDirectory()); +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/src/test/gtest/test/gtest-linked_ptr_test.cc b/src/test/gtest/test/gtest-linked_ptr_test.cc new file mode 100644 index 00000000..6fcf5124 --- /dev/null +++ b/src/test/gtest/test/gtest-linked_ptr_test.cc @@ -0,0 +1,154 @@ +// Copyright 2003, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: Dan Egnor (egnor@google.com) +// Ported to Windows: Vadim Berman (vadimb@google.com) + +#include "gtest/internal/gtest-linked_ptr.h" + +#include +#include "gtest/gtest.h" + +namespace { + +using testing::Message; +using testing::internal::linked_ptr; + +int num; +Message* history = NULL; + +// Class which tracks allocation/deallocation +class A { + public: + A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; } + virtual ~A() { *history << "A" << mynum << " dtor\n"; } + virtual void Use() { *history << "A" << mynum << " use\n"; } + protected: + int mynum; +}; + +// Subclass +class B : public A { + public: + B() { *history << "B" << mynum << " ctor\n"; } + ~B() { *history << "B" << mynum << " dtor\n"; } + virtual void Use() { *history << "B" << mynum << " use\n"; } +}; + +class LinkedPtrTest : public testing::Test { + public: + LinkedPtrTest() { + num = 0; + history = new Message; + } + + virtual ~LinkedPtrTest() { + delete history; + history = NULL; + } +}; + +TEST_F(LinkedPtrTest, GeneralTest) { + { + linked_ptr a0, a1, a2; + // Use explicit function call notation here to suppress self-assign warning. + a0.operator=(a0); + a1 = a2; + ASSERT_EQ(a0.get(), static_cast(NULL)); + ASSERT_EQ(a1.get(), static_cast(NULL)); + ASSERT_EQ(a2.get(), static_cast(NULL)); + ASSERT_TRUE(a0 == NULL); + ASSERT_TRUE(a1 == NULL); + ASSERT_TRUE(a2 == NULL); + + { + linked_ptr a3(new A); + a0 = a3; + ASSERT_TRUE(a0 == a3); + ASSERT_TRUE(a0 != NULL); + ASSERT_TRUE(a0.get() == a3); + ASSERT_TRUE(a0 == a3.get()); + linked_ptr a4(a0); + a1 = a4; + linked_ptr a5(new A); + ASSERT_TRUE(a5.get() != a3); + ASSERT_TRUE(a5 != a3.get()); + a2 = a5; + linked_ptr b0(new B); + linked_ptr a6(b0); + ASSERT_TRUE(b0 == a6); + ASSERT_TRUE(a6 == b0); + ASSERT_TRUE(b0 != NULL); + a5 = b0; + a5 = b0; + a3->Use(); + a4->Use(); + a5->Use(); + a6->Use(); + b0->Use(); + (*b0).Use(); + b0.get()->Use(); + } + + a0->Use(); + a1->Use(); + a2->Use(); + + a1 = a2; + a2.reset(new A); + a0.reset(); + + linked_ptr a7; + } + + ASSERT_STREQ( + "A0 ctor\n" + "A1 ctor\n" + "A2 ctor\n" + "B2 ctor\n" + "A0 use\n" + "A0 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 use\n" + "B2 dtor\n" + "A2 dtor\n" + "A0 use\n" + "A0 use\n" + "A1 use\n" + "A3 ctor\n" + "A0 dtor\n" + "A3 dtor\n" + "A1 dtor\n", + history->GetString().c_str()); +} + +} // Unnamed namespace diff --git a/src/test/gtest/test/gtest-listener_test.cc b/src/test/gtest/test/gtest-listener_test.cc new file mode 100644 index 00000000..99662cff --- /dev/null +++ b/src/test/gtest/test/gtest-listener_test.cc @@ -0,0 +1,310 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file verifies Google Test event listeners receive events at the +// right times. + +#include "gtest/gtest.h" +#include + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListener; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +// Used by tests to register their events. +std::vector* g_events = NULL; + +namespace testing { +namespace internal { + +class EventRecordingListener : public TestEventListener { + public: + explicit EventRecordingListener(const char* name) : name_(name) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramStart")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationStart") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); + } + + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); + } + + virtual void OnTestCaseStart(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseStart")); + } + + virtual void OnTestStart(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestStart")); + } + + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { + g_events->push_back(GetFullMethodName("OnTestPartResult")); + } + + virtual void OnTestEnd(const TestInfo& /*test_info*/) { + g_events->push_back(GetFullMethodName("OnTestEnd")); + } + + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { + g_events->push_back(GetFullMethodName("OnTestCaseEnd")); + } + + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); + } + + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationEnd") + << "(" << iteration << ")"; + g_events->push_back(message.GetString()); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + g_events->push_back(GetFullMethodName("OnTestProgramEnd")); + } + + private: + std::string GetFullMethodName(const char* name) { + return name_ + "." + name; + } + + std::string name_; +}; + +class EnvironmentInvocationCatcher : public Environment { + protected: + virtual void SetUp() { + g_events->push_back("Environment::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("Environment::TearDown"); + } +}; + +class ListenerTest : public Test { + protected: + static void SetUpTestCase() { + g_events->push_back("ListenerTest::SetUpTestCase"); + } + + static void TearDownTestCase() { + g_events->push_back("ListenerTest::TearDownTestCase"); + } + + virtual void SetUp() { + g_events->push_back("ListenerTest::SetUp"); + } + + virtual void TearDown() { + g_events->push_back("ListenerTest::TearDown"); + } +}; + +TEST_F(ListenerTest, DoesFoo) { + // Test execution order within a test case is not guaranteed so we are not + // recording the test name. + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +TEST_F(ListenerTest, DoesBar) { + g_events->push_back("ListenerTest::* Test Body"); + SUCCEED(); // Triggers OnTestPartResult. +} + +} // namespace internal + +} // namespace testing + +using ::testing::internal::EnvironmentInvocationCatcher; +using ::testing::internal::EventRecordingListener; + +void VerifyResults(const std::vector& data, + const char* const* expected_data, + int expected_data_size) { + const int actual_size = data.size(); + // If the following assertion fails, a new entry will be appended to + // data. Hence we save data.size() first. + EXPECT_EQ(expected_data_size, actual_size); + + // Compares the common prefix. + const int shorter_size = expected_data_size <= actual_size ? + expected_data_size : actual_size; + int i = 0; + for (; i < shorter_size; ++i) { + ASSERT_STREQ(expected_data[i], data[i].c_str()) + << "at position " << i; + } + + // Prints extra elements in the actual data. + for (; i < actual_size; ++i) { + printf(" Actual event #%d: %s\n", i, data[i].c_str()); + } +} + +int main(int argc, char **argv) { + std::vector events; + g_events = &events; + InitGoogleTest(&argc, argv); + + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("1st")); + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("2nd")); + + AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); + + GTEST_CHECK_(events.size() == 0) + << "AddGlobalTestEnvironment should not generate any events itself."; + + ::testing::GTEST_FLAG(repeat) = 2; + int ret_val = RUN_ALL_TESTS(); + + const char* const expected_events[] = { + "1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd" + }; + VerifyResults(events, + expected_events, + sizeof(expected_events)/sizeof(expected_events[0])); + + // We need to check manually for ad hoc test failures that happen after + // RUN_ALL_TESTS finishes. + if (UnitTest::GetInstance()->Failed()) + ret_val = 1; + + return ret_val; +} diff --git a/src/test/gtest/test/gtest-message_test.cc b/src/test/gtest/test/gtest-message_test.cc new file mode 100644 index 00000000..175238ef --- /dev/null +++ b/src/test/gtest/test/gtest-message_test.cc @@ -0,0 +1,159 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for the Message class. + +#include "gtest/gtest-message.h" + +#include "gtest/gtest.h" + +namespace { + +using ::testing::Message; + +// Tests the testing::Message class + +// Tests the default constructor. +TEST(MessageTest, DefaultConstructor) { + const Message msg; + EXPECT_EQ("", msg.GetString()); +} + +// Tests the copy constructor. +TEST(MessageTest, CopyConstructor) { + const Message msg1("Hello"); + const Message msg2(msg1); + EXPECT_EQ("Hello", msg2.GetString()); +} + +// Tests constructing a Message from a C-string. +TEST(MessageTest, ConstructsFromCString) { + Message msg("Hello"); + EXPECT_EQ("Hello", msg.GetString()); +} + +// Tests streaming a float. +TEST(MessageTest, StreamsFloat) { + const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str()); +} + +// Tests streaming a double. +TEST(MessageTest, StreamsDouble) { + const std::string s = (Message() << 1260570880.4555497 << " " + << 1260572265.1954534).GetString(); + // Both numbers should be printed with enough precision. + EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str()); +} + +// Tests streaming a non-char pointer. +TEST(MessageTest, StreamsPointer) { + int n = 0; + int* p = &n; + EXPECT_NE("(null)", (Message() << p).GetString()); +} + +// Tests streaming a NULL non-char pointer. +TEST(MessageTest, StreamsNullPointer) { + int* p = NULL; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming a C string. +TEST(MessageTest, StreamsCString) { + EXPECT_EQ("Foo", (Message() << "Foo").GetString()); +} + +// Tests streaming a NULL C string. +TEST(MessageTest, StreamsNullCString) { + char* p = NULL; + EXPECT_EQ("(null)", (Message() << p).GetString()); +} + +// Tests streaming std::string. +TEST(MessageTest, StreamsString) { + const ::std::string str("Hello"); + EXPECT_EQ("Hello", (Message() << str).GetString()); +} + +// Tests that we can output strings containing embedded NULs. +TEST(MessageTest, StreamsStringWithEmbeddedNUL) { + const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + const ::std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) - 1); + EXPECT_EQ("Here's a NUL\\0 and some more string", + (Message() << string_with_nul).GetString()); +} + +// Tests streaming a NUL char. +TEST(MessageTest, StreamsNULChar) { + EXPECT_EQ("\\0", (Message() << '\0').GetString()); +} + +// Tests streaming int. +TEST(MessageTest, StreamsInt) { + EXPECT_EQ("123", (Message() << 123).GetString()); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to Message. +TEST(MessageTest, StreamsBasicIoManip) { + EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.", + (Message() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush + << " in line 2.").GetString()); +} + +// Tests Message::GetString() +TEST(MessageTest, GetString) { + Message msg; + msg << 1 << " lamb"; + EXPECT_EQ("1 lamb", msg.GetString()); +} + +// Tests streaming a Message object to an ostream. +TEST(MessageTest, StreamsToOStream) { + Message msg("Hello"); + ::std::stringstream ss; + ss << msg; + EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss)); +} + +// Tests that a Message object doesn't take up too much stack space. +TEST(MessageTest, DoesNotTakeUpMuchStackSpace) { + EXPECT_LE(sizeof(Message), 16U); +} + +} // namespace diff --git a/src/test/gtest/test/gtest-options_test.cc b/src/test/gtest/test/gtest-options_test.cc new file mode 100644 index 00000000..5586dc3b --- /dev/null +++ b/src/test/gtest/test/gtest-options_test.cc @@ -0,0 +1,215 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) +// +// Google Test UnitTestOptions tests +// +// This file tests classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included from gtest.cc, to avoid changing build or +// make-files on Windows and other platforms. Do not #include this file +// anywhere else! + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { +namespace { + +// Turns the given relative path into an absolute path. +FilePath GetAbsolutePathOf(const FilePath& relative_path) { + return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path); +} + +// Testing UnitTestOptions::GetOutputFormat/GetOutputFile. + +TEST(XmlOutputTest, GetOutputFormatDefault) { + GTEST_FLAG(output) = ""; + EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFormat) { + GTEST_FLAG(output) = "xml:filename"; + EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str()); +} + +TEST(XmlOutputTest, GetOutputFileDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileSingleFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + GetAbsolutePathOf( + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST(OutputFileHelpersTest, GetCurrentExecutableName) { + const std::string exe_str = GetCurrentExecutableName().string(); +#if GTEST_OS_WINDOWS + const bool success = + _strcmpi("gtest-options_test", exe_str.c_str()) == 0 || + _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_all_test", exe_str.c_str()) == 0 || + _strcmpi("gtest_dll_test", exe_str.c_str()) == 0; +#else + // TODO(wan@google.com): remove the hard-coded "lt-" prefix when + // Chandler Carruth's libtool replacement is ready. + const bool success = + exe_str == "gtest-options_test" || + exe_str == "gtest_all_test" || + exe_str == "lt-gtest_all_test" || + exe_str == "gtest_dll_test"; +#endif // GTEST_OS_WINDOWS + if (!success) + FAIL() << "GetCurrentExecutableName() returns " << exe_str; +} + +class XmlOutputChangeDirTest : public Test { + protected: + virtual void SetUp() { + original_working_dir_ = FilePath::GetCurrentDir(); + posix::ChDir(".."); + // This will make the test fail if run from the root directory. + EXPECT_NE(original_working_dir_.string(), + FilePath::GetCurrentDir().string()); + } + + virtual void TearDown() { + posix::ChDir(original_working_dir_.string().c_str()); + } + + FilePath original_working_dir_; +}; + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { + GTEST_FLAG(output) = ""; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { + GTEST_FLAG(output) = "xml"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("test_detail.xml")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { + GTEST_FLAG(output) = "xml:filename.abc"; + EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, + FilePath("filename.abc")).string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { + GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; + const std::string expected_output_file = + FilePath::ConcatPaths( + original_working_dir_, + FilePath(std::string("path") + GTEST_PATH_SEP_ + + GetCurrentExecutableName().string() + ".xml")).string(); + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { +#if GTEST_OS_WINDOWS + GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; + EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#else + GTEST_FLAG(output) ="xml:/tmp/filename.abc"; + EXPECT_EQ(FilePath("/tmp/filename.abc").string(), + UnitTestOptions::GetAbsolutePathToOutputFile()); +#endif +} + +TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { +#if GTEST_OS_WINDOWS + const std::string path = "c:\\tmp\\"; +#else + const std::string path = "/tmp/"; +#endif + + GTEST_FLAG(output) = "xml:" + path; + const std::string expected_output_file = + path + GetCurrentExecutableName().string() + ".xml"; + const std::string& output_file = + UnitTestOptions::GetAbsolutePathToOutputFile(); + +#if GTEST_OS_WINDOWS + EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); +#else + EXPECT_EQ(expected_output_file, output_file.c_str()); +#endif +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/src/test/gtest/test/gtest-param-test2_test.cc b/src/test/gtest/test/gtest-param-test2_test.cc new file mode 100644 index 00000000..4a782fe7 --- /dev/null +++ b/src/test/gtest/test/gtest-param-test2_test.cc @@ -0,0 +1,65 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" + +#include "test/gtest-param-test_test.h" + +#if GTEST_HAS_PARAM_TEST + +using ::testing::Values; +using ::testing::internal::ParamGenerator; + +// Tests that generators defined in a different translation unit +// are functional. The test using extern_gen is defined +// in gtest-param-test_test.cc. +ParamGenerator extern_gen = Values(33); + +// Tests that a parameterized test case can be defined in one translation unit +// and instantiated in another. The test is defined in gtest-param-test_test.cc +// and ExternalInstantiationTest fixture class is defined in +// gtest-param-test_test.h. +INSTANTIATE_TEST_CASE_P(MultiplesOf33, + ExternalInstantiationTest, + Values(33, 66)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. Another instantiation is defined +// in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest +// fixture is defined in gtest-param-test_test.h +INSTANTIATE_TEST_CASE_P(Sequence2, + InstantiationInMultipleTranslaionUnitsTest, + Values(42*3, 42*4, 42*5)); + +#endif // GTEST_HAS_PARAM_TEST diff --git a/src/test/gtest/test/gtest-param-test_test.cc b/src/test/gtest/test/gtest-param-test_test.cc new file mode 100644 index 00000000..cc1dc65f --- /dev/null +++ b/src/test/gtest/test/gtest-param-test_test.cc @@ -0,0 +1,904 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. This file verifies that the parameter +// generators objects produce correct parameter sequences and that +// Google Test runtime instantiates correct tests from those sequences. + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +# include +# include +# include +# include +# include +# include + +// To include gtest-internal-inl.h. +# define GTEST_IMPLEMENTATION_ 1 +# include "src/gtest-internal-inl.h" // for UnitTestOptions +# undef GTEST_IMPLEMENTATION_ + +# include "test/gtest-param-test_test.h" + +using ::std::vector; +using ::std::sort; + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Bool; +using ::testing::Message; +using ::testing::Range; +using ::testing::TestWithParam; +using ::testing::Values; +using ::testing::ValuesIn; + +# if GTEST_HAS_COMBINE +using ::testing::Combine; +using ::testing::get; +using ::testing::make_tuple; +using ::testing::tuple; +# endif // GTEST_HAS_COMBINE + +using ::testing::internal::ParamGenerator; +using ::testing::internal::UnitTestOptions; + +// Prints a value to a string. +// +// TODO(wan@google.com): remove PrintValue() when we move matchers and +// EXPECT_THAT() from Google Mock to Google Test. At that time, we +// can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as +// EXPECT_THAT() and the matchers know how to print tuples. +template +::std::string PrintValue(const T& value) { + ::std::stringstream stream; + stream << value; + return stream.str(); +} + +# if GTEST_HAS_COMBINE + +// These overloads allow printing tuples in our tests. We cannot +// define an operator<< for tuples, as that definition needs to be in +// the std namespace in order to be picked up by Google Test via +// Argument-Dependent Lookup, yet defining anything in the std +// namespace in non-STL code is undefined behavior. + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue(const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ")"; + return stream.str(); +} + +template +::std::string PrintValue( + const tuple& value) { + ::std::stringstream stream; + stream << "(" << get<0>(value) << ", " << get<1>(value) + << ", "<< get<2>(value) << ", " << get<3>(value) + << ", "<< get<4>(value) << ", " << get<5>(value) + << ", "<< get<6>(value) << ", " << get<7>(value) + << ", "<< get<8>(value) << ", " << get<9>(value) << ")"; + return stream.str(); +} + +# endif // GTEST_HAS_COMBINE + +// Verifies that a sequence generated by the generator and accessed +// via the iterator object matches the expected one using Google Test +// assertions. +template +void VerifyGenerator(const ParamGenerator& generator, + const T (&expected_values)[N]) { + typename ParamGenerator::iterator it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the copy constructor.\n"; + // We cannot use EXPECT_EQ() here as the values may be tuples, + // which don't support <<. + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the copy constructor.\n"; + + // Test the iterator assignment. The following lines verify that + // the sequence accessed via an iterator initialized via the + // assignment operator (as opposed to a copy constructor) matches + // just the same. + it = generator.begin(); + for (size_t i = 0; i < N; ++i) { + ASSERT_FALSE(it == generator.end()) + << "At element " << i << " when accessing via an iterator " + << "created with the assignment operator.\n"; + EXPECT_TRUE(expected_values[i] == *it) + << "where i is " << i + << ", expected_values[i] is " << PrintValue(expected_values[i]) + << ", *it is " << PrintValue(*it) + << ", and 'it' is an iterator created with the copy constructor.\n"; + it++; + } + EXPECT_TRUE(it == generator.end()) + << "At the presumed end of sequence when accessing via an iterator " + << "created with the assignment operator.\n"; +} + +template +void VerifyGeneratorIsEmpty(const ParamGenerator& generator) { + typename ParamGenerator::iterator it = generator.begin(); + EXPECT_TRUE(it == generator.end()); + + it = generator.begin(); + EXPECT_TRUE(it == generator.end()); +} + +// Generator tests. They test that each of the provided generator functions +// generates an expected sequence of values. The general test pattern +// instantiates a generator using one of the generator functions, +// checks the sequence produced by the generator using its iterator API, +// and then resets the iterator back to the beginning of the sequence +// and checks the sequence again. + +// Tests that iterators produced by generator functions conform to the +// ForwardIterator concept. +TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { + const ParamGenerator gen = Range(0, 10); + ParamGenerator::iterator it = gen.begin(); + + // Verifies that iterator initialization works as expected. + ParamGenerator::iterator it2 = it; + EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the " + << "element same as its source points to"; + + // Verifies that iterator assignment works as expected. + it++; + EXPECT_FALSE(*it == *it2); + it2 = it; + EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " + << "element same as its source points to"; + + // Verifies that prefix operator++() returns *this. + EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be " + << "refer to the original object"; + + // Verifies that the result of the postfix operator++ points to the value + // pointed to by the original iterator. + int original_value = *it; // Have to compute it outside of macro call to be + // unaffected by the parameter evaluation order. + EXPECT_EQ(original_value, *(it++)); + + // Verifies that prefix and postfix operator++() advance an iterator + // all the same. + it2 = it; + it++; + ++it2; + EXPECT_TRUE(*it == *it2); +} + +// Tests that Range() generates the expected sequence. +TEST(RangeTest, IntRangeWithDefaultStep) { + const ParamGenerator gen = Range(0, 3); + const int expected_values[] = {0, 1, 2}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() generates the single element sequence +// as expected when provided with range limits that are equal. +TEST(RangeTest, IntRangeSingleValue) { + const ParamGenerator gen = Range(0, 1); + const int expected_values[] = {0}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that Range() with generates empty sequence when +// supplied with an empty range. +TEST(RangeTest, IntRangeEmpty) { + const ParamGenerator gen = Range(0, 0); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence. +TEST(RangeTest, IntRangeWithCustomStep) { + const ParamGenerator gen = Range(0, 9, 3); + const int expected_values[] = {0, 3, 6}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Range() with custom step (greater then one) generates +// the expected sequence when the last element does not fall on the +// upper range limit. Sequences generated by Range() must not have +// elements beyond the range limits. +TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { + const ParamGenerator gen = Range(0, 4, 3); + const int expected_values[] = {0, 3}; + VerifyGenerator(gen, expected_values); +} + +// Verifies that Range works with user-defined types that define +// copy constructor, operator=(), operator+(), and operator<(). +class DogAdder { + public: + explicit DogAdder(const char* a_value) : value_(a_value) {} + DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} + + DogAdder operator=(const DogAdder& other) { + if (this != &other) + value_ = other.value_; + return *this; + } + DogAdder operator+(const DogAdder& other) const { + Message msg; + msg << value_.c_str() << other.value_.c_str(); + return DogAdder(msg.GetString().c_str()); + } + bool operator<(const DogAdder& other) const { + return value_ < other.value_; + } + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +TEST(RangeTest, WorksWithACustomType) { + const ParamGenerator gen = + Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog")); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_STREQ("cat", it->value().c_str()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_STREQ("catdog", it->value().c_str()); + + EXPECT_TRUE(++it == gen.end()); +} + +class IntWrapper { + public: + explicit IntWrapper(int a_value) : value_(a_value) {} + IntWrapper(const IntWrapper& other) : value_(other.value_) {} + + IntWrapper operator=(const IntWrapper& other) { + value_ = other.value_; + return *this; + } + // operator+() adds a different type. + IntWrapper operator+(int other) const { return IntWrapper(value_ + other); } + bool operator<(const IntWrapper& other) const { + return value_ < other.value_; + } + int value() const { return value_; } + + private: + int value_; +}; + +TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) { + const ParamGenerator gen = Range(IntWrapper(0), IntWrapper(2)); + ParamGenerator::iterator it = gen.begin(); + + ASSERT_FALSE(it == gen.end()); + EXPECT_EQ(0, it->value()); + + ASSERT_FALSE(++it == gen.end()); + EXPECT_EQ(1, it->value()); + + EXPECT_TRUE(++it == gen.end()); +} + +// Tests that ValuesIn() with an array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInArray) { + int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() with a const array parameter generates +// the expected sequence. +TEST(ValuesInTest, ValuesInConstArray) { + const int array[] = {3, 5, 8}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Edge case. Tests that ValuesIn() with an array parameter containing a +// single element generates the single element sequence. +TEST(ValuesInTest, ValuesInSingleElementArray) { + int array[] = {42}; + const ParamGenerator gen = ValuesIn(array); + VerifyGenerator(gen, array); +} + +// Tests that ValuesIn() generates the expected sequence for an STL +// container (vector). +TEST(ValuesInTest, ValuesInVector) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that ValuesIn() generates the expected sequence. +TEST(ValuesInTest, ValuesInIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(3); + values.push_back(5); + values.push_back(8); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an iterator range specifying a +// single value generates a single-element sequence. +TEST(ValuesInTest, ValuesInSingleElementIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + values.push_back(42); + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Edge case. Tests that ValuesIn() provided with an empty iterator range +// generates an empty sequence. +TEST(ValuesInTest, ValuesInEmptyIteratorRange) { + typedef ::std::vector ContainerType; + ContainerType values; + const ParamGenerator gen = ValuesIn(values.begin(), values.end()); + + VerifyGeneratorIsEmpty(gen); +} + +// Tests that the Values() generates the expected sequence. +TEST(ValuesTest, ValuesWorks) { + const ParamGenerator gen = Values(3, 5, 8); + + const int expected_values[] = {3, 5, 8}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Values() generates the expected sequences from elements of +// different types convertible to ParamGenerator's parameter type. +TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) { + const ParamGenerator gen = Values(3, 5.0f, 8.0); + + const double expected_values[] = {3.0, 5.0, 8.0}; + VerifyGenerator(gen, expected_values); +} + +TEST(ValuesTest, ValuesWorksForMaxLengthList) { + const ParamGenerator gen = Values( + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500); + + const int expected_values[] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, + 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, + 410, 420, 430, 440, 450, 460, 470, 480, 490, 500}; + VerifyGenerator(gen, expected_values); +} + +// Edge case test. Tests that single-parameter Values() generates the sequence +// with the single value. +TEST(ValuesTest, ValuesWithSingleParameter) { + const ParamGenerator gen = Values(42); + + const int expected_values[] = {42}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Bool() generates sequence (false, true). +TEST(BoolTest, BoolWorks) { + const ParamGenerator gen = Bool(); + + const bool expected_values[] = {false, true}; + VerifyGenerator(gen, expected_values); +} + +# if GTEST_HAS_COMBINE + +// Tests that Combine() with two parameters generates the expected sequence. +TEST(CombineTest, CombineWithTwoParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = + Combine(Values(foo, bar), Values(3, 4)); + + tuple expected_values[] = { + make_tuple(foo, 3), make_tuple(foo, 4), + make_tuple(bar, 3), make_tuple(bar, 4)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that Combine() with three parameters generates the expected sequence. +TEST(CombineTest, CombineWithThreeParameters) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(3, 4), + Values(5, 6)); + tuple expected_values[] = { + make_tuple(0, 3, 5), make_tuple(0, 3, 6), + make_tuple(0, 4, 5), make_tuple(0, 4, 6), + make_tuple(1, 3, 5), make_tuple(1, 3, 6), + make_tuple(1, 4, 5), make_tuple(1, 4, 6)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the first parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the second parameter. +TEST(CombineTest, CombineWithFirstParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(42), + Values(0, 1)); + + tuple expected_values[] = {make_tuple(42, 0), make_tuple(42, 1)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that the Combine() with the second parameter generating a single value +// sequence generates a sequence with the number of elements equal to the +// number of elements in the sequence generated by the first parameter. +TEST(CombineTest, CombineWithSecondParameterSingleValue) { + const ParamGenerator > gen = Combine(Values(0, 1), + Values(42)); + + tuple expected_values[] = {make_tuple(0, 42), make_tuple(1, 42)}; + VerifyGenerator(gen, expected_values); +} + +// Tests that when the first parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithFirstParameterEmptyRange) { + const ParamGenerator > gen = Combine(Range(0, 0), + Values(0, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Tests that when the second parameter produces an empty sequence, +// Combine() produces an empty sequence, too. +TEST(CombineTest, CombineWithSecondParameterEmptyRange) { + const ParamGenerator > gen = Combine(Values(0, 1), + Range(1, 1)); + VerifyGeneratorIsEmpty(gen); +} + +// Edge case. Tests that combine works with the maximum number +// of parameters supported by Google Test (currently 10). +TEST(CombineTest, CombineWithMaxNumberOfParameters) { + const char* foo = "foo"; + const char* bar = "bar"; + const ParamGenerator > gen = Combine(Values(foo, bar), + Values(1), Values(2), + Values(3), Values(4), + Values(5), Values(6), + Values(7), Values(8), + Values(9)); + + tuple + expected_values[] = {make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9), + make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)}; + VerifyGenerator(gen, expected_values); +} + +# endif // GTEST_HAS_COMBINE + +// Tests that an generator produces correct sequence after being +// assigned from another generator. +TEST(ParamGeneratorTest, AssignmentWorks) { + ParamGenerator gen = Values(1, 2); + const ParamGenerator gen2 = Values(3, 4); + gen = gen2; + + const int expected_values[] = {3, 4}; + VerifyGenerator(gen, expected_values); +} + +// This test verifies that the tests are expanded and run as specified: +// one test per element from the sequence produced by the generator +// specified in INSTANTIATE_TEST_CASE_P. It also verifies that the test's +// fixture constructor, SetUp(), and TearDown() have run and have been +// supplied with the correct parameters. + +// The use of environment object allows detection of the case where no test +// case functionality is run at all. In this case TestCaseTearDown will not +// be able to detect missing tests, naturally. +template +class TestGenerationEnvironment : public ::testing::Environment { + public: + static TestGenerationEnvironment* Instance() { + static TestGenerationEnvironment* instance = new TestGenerationEnvironment; + return instance; + } + + void FixtureConstructorExecuted() { fixture_constructor_count_++; } + void SetUpExecuted() { set_up_count_++; } + void TearDownExecuted() { tear_down_count_++; } + void TestBodyExecuted() { test_body_count_++; } + + virtual void TearDown() { + // If all MultipleTestGenerationTest tests have been de-selected + // by the filter flag, the following checks make no sense. + bool perform_check = false; + + for (int i = 0; i < kExpectedCalls; ++i) { + Message msg; + msg << "TestsExpandedAndRun/" << i; + if (UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + msg.GetString().c_str())) { + perform_check = true; + } + } + if (perform_check) { + EXPECT_EQ(kExpectedCalls, fixture_constructor_count_) + << "Fixture constructor of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, set_up_count_) + << "Fixture SetUp method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, tear_down_count_) + << "Fixture TearDown method of ParamTestGenerationTest test case " + << "has not been run as expected."; + EXPECT_EQ(kExpectedCalls, test_body_count_) + << "Test in ParamTestGenerationTest test case " + << "has not been run as expected."; + } + } + + private: + TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), + tear_down_count_(0), test_body_count_(0) {} + + int fixture_constructor_count_; + int set_up_count_; + int tear_down_count_; + int test_body_count_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment); +}; + +const int test_generation_params[] = {36, 42, 72}; + +class TestGenerationTest : public TestWithParam { + public: + enum { + PARAMETER_COUNT = + sizeof(test_generation_params)/sizeof(test_generation_params[0]) + }; + + typedef TestGenerationEnvironment Environment; + + TestGenerationTest() { + Environment::Instance()->FixtureConstructorExecuted(); + current_parameter_ = GetParam(); + } + virtual void SetUp() { + Environment::Instance()->SetUpExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + virtual void TearDown() { + Environment::Instance()->TearDownExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + } + + static void SetUpTestCase() { + bool all_tests_in_test_case_selected = true; + + for (int i = 0; i < PARAMETER_COUNT; ++i) { + Message test_name; + test_name << "TestsExpandedAndRun/" << i; + if ( !UnitTestOptions::FilterMatchesTest( + "TestExpansionModule/MultipleTestGenerationTest", + test_name.GetString())) { + all_tests_in_test_case_selected = false; + } + } + EXPECT_TRUE(all_tests_in_test_case_selected) + << "When running the TestGenerationTest test case all of its tests\n" + << "must be selected by the filter flag for the test case to pass.\n" + << "If not all of them are enabled, we can't reliably conclude\n" + << "that the correct number of tests have been generated."; + + collected_parameters_.clear(); + } + + static void TearDownTestCase() { + vector expected_values(test_generation_params, + test_generation_params + PARAMETER_COUNT); + // Test execution order is not guaranteed by Google Test, + // so the order of values in collected_parameters_ can be + // different and we have to sort to compare. + sort(expected_values.begin(), expected_values.end()); + sort(collected_parameters_.begin(), collected_parameters_.end()); + + EXPECT_TRUE(collected_parameters_ == expected_values); + } + + protected: + int current_parameter_; + static vector collected_parameters_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest); +}; +vector TestGenerationTest::collected_parameters_; + +TEST_P(TestGenerationTest, TestsExpandedAndRun) { + Environment::Instance()->TestBodyExecuted(); + EXPECT_EQ(current_parameter_, GetParam()); + collected_parameters_.push_back(GetParam()); +} +INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest, + ValuesIn(test_generation_params)); + +// This test verifies that the element sequence (third parameter of +// INSTANTIATE_TEST_CASE_P) is evaluated in InitGoogleTest() and neither at +// the call site of INSTANTIATE_TEST_CASE_P nor in RUN_ALL_TESTS(). For +// that, we declare param_value_ to be a static member of +// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in +// main(), just before invocation of InitGoogleTest(). After calling +// InitGoogleTest(), we set the value to 2. If the sequence is evaluated +// before or after InitGoogleTest, INSTANTIATE_TEST_CASE_P will create a +// test with parameter other than 1, and the test body will fail the +// assertion. +class GeneratorEvaluationTest : public TestWithParam { + public: + static int param_value() { return param_value_; } + static void set_param_value(int param_value) { param_value_ = param_value; } + + private: + static int param_value_; +}; +int GeneratorEvaluationTest::param_value_ = 0; + +TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) { + EXPECT_EQ(1, GetParam()); +} +INSTANTIATE_TEST_CASE_P(GenEvalModule, + GeneratorEvaluationTest, + Values(GeneratorEvaluationTest::param_value())); + +// Tests that generators defined in a different translation unit are +// functional. Generator extern_gen is defined in gtest-param-test_test2.cc. +extern ParamGenerator extern_gen; +class ExternalGeneratorTest : public TestWithParam {}; +TEST_P(ExternalGeneratorTest, ExternalGenerator) { + // Sequence produced by extern_gen contains only a single value + // which we verify here. + EXPECT_EQ(GetParam(), 33); +} +INSTANTIATE_TEST_CASE_P(ExternalGeneratorModule, + ExternalGeneratorTest, + extern_gen); + +// Tests that a parameterized test case can be defined in one translation +// unit and instantiated in another. This test will be instantiated in +// gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is +// defined in gtest-param-test_test.h. +TEST_P(ExternalInstantiationTest, IsMultipleOf33) { + EXPECT_EQ(0, GetParam() % 33); +} + +// Tests that a parameterized test case can be instantiated with multiple +// generators. +class MultipleInstantiationTest : public TestWithParam {}; +TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) { +} +INSTANTIATE_TEST_CASE_P(Sequence1, MultipleInstantiationTest, Values(1, 2)); +INSTANTIATE_TEST_CASE_P(Sequence2, MultipleInstantiationTest, Range(3, 5)); + +// Tests that a parameterized test case can be instantiated +// in multiple translation units. This test will be instantiated +// here and in gtest-param-test_test2.cc. +// InstantiationInMultipleTranslationUnitsTest fixture class +// is defined in gtest-param-test_test.h. +TEST_P(InstantiationInMultipleTranslaionUnitsTest, IsMultipleOf42) { + EXPECT_EQ(0, GetParam() % 42); +} +INSTANTIATE_TEST_CASE_P(Sequence1, + InstantiationInMultipleTranslaionUnitsTest, + Values(42, 42*2)); + +// Tests that each iteration of parameterized test runs in a separate test +// object. +class SeparateInstanceTest : public TestWithParam { + public: + SeparateInstanceTest() : count_(0) {} + + static void TearDownTestCase() { + EXPECT_GE(global_count_, 2) + << "If some (but not all) SeparateInstanceTest tests have been " + << "filtered out this test will fail. Make sure that all " + << "GeneratorEvaluationTest are selected or de-selected together " + << "by the test filter."; + } + + protected: + int count_; + static int global_count_; +}; +int SeparateInstanceTest::global_count_ = 0; + +TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) { + EXPECT_EQ(0, count_++); + global_count_++; +} +INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); + +// Tests that all instantiations of a test have named appropriately. Test +// defined with TEST_P(TestCaseName, TestName) and instantiated with +// INSTANTIATE_TEST_CASE_P(SequenceName, TestCaseName, generator) must be named +// SequenceName/TestCaseName.TestName/i, where i is the 0-based index of the +// sequence element used to instantiate the test. +class NamingTest : public TestWithParam {}; + +TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); + + Message index_stream; + index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam(); + EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); + +// Class that cannot be streamed into an ostream. It needs to be copyable +// (and, in case of MSVC, also assignable) in order to be a test parameter +// type. Its default copy constructor and assignment operator do exactly +// what we need. +class Unstreamable { + public: + explicit Unstreamable(int value) : value_(value) {} + + private: + int value_; +}; + +class CommentTest : public TestWithParam {}; + +TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); +} + +INSTANTIATE_TEST_CASE_P(InstantiationWithComments, + CommentTest, + Values(Unstreamable(1))); + +// Verify that we can create a hierarchy of test fixtures, where the base +// class fixture is not parameterized and the derived class is. In this case +// ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We +// perform simple tests on both. +class NonParameterizedBaseTest : public ::testing::Test { + public: + NonParameterizedBaseTest() : n_(17) { } + protected: + int n_; +}; + +class ParameterizedDerivedTest : public NonParameterizedBaseTest, + public ::testing::WithParamInterface { + protected: + ParameterizedDerivedTest() : count_(0) { } + int count_; + static int global_count_; +}; + +int ParameterizedDerivedTest::global_count_ = 0; + +TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { + EXPECT_EQ(17, n_); +} + +TEST_P(ParameterizedDerivedTest, SeesSequence) { + EXPECT_EQ(17, n_); + EXPECT_EQ(0, count_++); + EXPECT_EQ(GetParam(), global_count_++); +} + +class ParameterizedDeathTest : public ::testing::TestWithParam { }; + +TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { + EXPECT_DEATH_IF_SUPPORTED(GetParam(), + ".* value-parameterized test .*"); +} + +INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); + +#endif // GTEST_HAS_PARAM_TEST + +TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { +#if GTEST_HAS_COMBINE && !GTEST_HAS_PARAM_TEST + FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n" +#endif +} + +int main(int argc, char **argv) { +#if GTEST_HAS_PARAM_TEST + // Used in TestGenerationTest test case. + AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); + // Used in GeneratorEvaluationTest test case. Tests that the updated value + // will be picked up for instantiating tests in GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(1); +#endif // GTEST_HAS_PARAM_TEST + + ::testing::InitGoogleTest(&argc, argv); + +#if GTEST_HAS_PARAM_TEST + // Used in GeneratorEvaluationTest test case. Tests that value updated + // here will NOT be used for instantiating tests in + // GeneratorEvaluationTest. + GeneratorEvaluationTest::set_param_value(2); +#endif // GTEST_HAS_PARAM_TEST + + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest-param-test_test.h b/src/test/gtest/test/gtest-param-test_test.h new file mode 100644 index 00000000..26ea122b --- /dev/null +++ b/src/test/gtest/test/gtest-param-test_test.h @@ -0,0 +1,57 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file provides classes and functions used internally +// for testing Google Test itself. + +#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ +#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ + +#include "gtest/gtest.h" + +#if GTEST_HAS_PARAM_TEST + +// Test fixture for testing definition and instantiation of a test +// in separate translation units. +class ExternalInstantiationTest : public ::testing::TestWithParam { +}; + +// Test fixture for testing instantiation of a test in multiple +// translation units. +class InstantiationInMultipleTranslaionUnitsTest + : public ::testing::TestWithParam { +}; + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ diff --git a/src/test/gtest/test/gtest-port_test.cc b/src/test/gtest/test/gtest-port_test.cc new file mode 100644 index 00000000..370c952b --- /dev/null +++ b/src/test/gtest/test/gtest-port_test.cc @@ -0,0 +1,1323 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan) +// +// This file tests the internal cross-platform support utilities. + +#include "gtest/internal/gtest-port.h" + +#include + +#if GTEST_OS_MAC +# include +#endif // GTEST_OS_MAC + +#include +#include // For std::pair and std::make_pair. +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using std::make_pair; +using std::pair; + +namespace testing { +namespace internal { + +TEST(IsXDigitTest, WorksForNarrowAscii) { + EXPECT_TRUE(IsXDigit('0')); + EXPECT_TRUE(IsXDigit('9')); + EXPECT_TRUE(IsXDigit('A')); + EXPECT_TRUE(IsXDigit('F')); + EXPECT_TRUE(IsXDigit('a')); + EXPECT_TRUE(IsXDigit('f')); + + EXPECT_FALSE(IsXDigit('-')); + EXPECT_FALSE(IsXDigit('g')); + EXPECT_FALSE(IsXDigit('G')); +} + +TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast('0' | 0x80))); +} + +TEST(IsXDigitTest, WorksForWideAscii) { + EXPECT_TRUE(IsXDigit(L'0')); + EXPECT_TRUE(IsXDigit(L'9')); + EXPECT_TRUE(IsXDigit(L'A')); + EXPECT_TRUE(IsXDigit(L'F')); + EXPECT_TRUE(IsXDigit(L'a')); + EXPECT_TRUE(IsXDigit(L'f')); + + EXPECT_FALSE(IsXDigit(L'-')); + EXPECT_FALSE(IsXDigit(L'g')); + EXPECT_FALSE(IsXDigit(L'G')); +} + +TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { + EXPECT_FALSE(IsXDigit(static_cast(0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x80))); + EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x100))); +} + +class Base { + public: + // Copy constructor and assignment operator do exactly what we need, so we + // use them. + Base() : member_(0) {} + explicit Base(int n) : member_(n) {} + virtual ~Base() {} + int member() { return member_; } + + private: + int member_; +}; + +class Derived : public Base { + public: + explicit Derived(int n) : Base(n) {} +}; + +TEST(ImplicitCastTest, ConvertsPointers) { + Derived derived(0); + EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_(&derived)); +} + +TEST(ImplicitCastTest, CanUseInheritance) { + Derived derived(1); + Base base = ::testing::internal::ImplicitCast_(derived); + EXPECT_EQ(derived.member(), base.member()); +} + +class Castable { + public: + explicit Castable(bool* converted) : converted_(converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseNonConstCastOperator) { + bool converted = false; + Castable castable(&converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); +} + +class ConstCastable { + public: + explicit ConstCastable(bool* converted) : converted_(converted) {} + operator Base() const { + *converted_ = true; + return Base(); + } + + private: + bool* converted_; +}; + +TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { + bool converted = false; + const ConstCastable const_castable(&converted); + Base base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_TRUE(converted); +} + +class ConstAndNonConstCastable { + public: + ConstAndNonConstCastable(bool* converted, bool* const_converted) + : converted_(converted), const_converted_(const_converted) {} + operator Base() { + *converted_ = true; + return Base(); + } + operator Base() const { + *const_converted_ = true; + return Base(); + } + + private: + bool* converted_; + bool* const_converted_; +}; + +TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { + bool converted = false; + bool const_converted = false; + ConstAndNonConstCastable castable(&converted, &const_converted); + Base base = ::testing::internal::ImplicitCast_(castable); + EXPECT_TRUE(converted); + EXPECT_FALSE(const_converted); + + converted = false; + const_converted = false; + const ConstAndNonConstCastable const_castable(&converted, &const_converted); + base = ::testing::internal::ImplicitCast_(const_castable); + EXPECT_FALSE(converted); + EXPECT_TRUE(const_converted); +} + +class To { + public: + To(bool* converted) { *converted = true; } // NOLINT +}; + +TEST(ImplicitCastTest, CanUseImplicitConstructor) { + bool converted = false; + To to = ::testing::internal::ImplicitCast_(&converted); + (void)to; + EXPECT_TRUE(converted); +} + +TEST(IteratorTraitsTest, WorksForSTLContainerIterators) { + StaticAssertTypeEq::const_iterator>::value_type>(); + StaticAssertTypeEq::iterator>::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToNonConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +TEST(IteratorTraitsTest, WorksForPointerToConst) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +// Tests that the element_type typedef is available in scoped_ptr and refers +// to the parameter type. +TEST(ScopedPtrTest, DefinesElementType) { + StaticAssertTypeEq::element_type>(); +} + +// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests. + +TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { + if (AlwaysFalse()) + GTEST_CHECK_(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + GTEST_CHECK_(true); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + GTEST_CHECK_(true) << ""; +} + +TEST(GtestCheckSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + GTEST_CHECK_(true); + } + + switch (0) + case 0: + GTEST_CHECK_(true) << "Check failed in switch case"; +} + +// Verifies behavior of FormatFileLocation. +TEST(FormatFileLocationTest, FormatsFileLocation) { + EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); +} + +TEST(FormatFileLocationTest, FormatsUnknownFile) { + EXPECT_PRED_FORMAT2( + IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); +} + +TEST(FormatFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); +} + +TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); +} + +// Verifies behavior of FormatCompilerIndependentFileLocation. +TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { + EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { + EXPECT_EQ("unknown file:42", + FormatCompilerIndependentFileLocation(NULL, 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); +} + +#if GTEST_OS_MAC || GTEST_OS_QNX +void* ThreadFunc(void* data) { + pthread_mutex_t* mutex = static_cast(data); + pthread_mutex_lock(mutex); + pthread_mutex_unlock(mutex); + return NULL; +} + +TEST(GetThreadCountTest, ReturnsCorrectValue) { + EXPECT_EQ(1U, GetThreadCount()); + pthread_mutex_t mutex; + pthread_attr_t attr; + pthread_t thread_id; + + // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic + // destruction. + pthread_mutex_init(&mutex, NULL); + pthread_mutex_lock(&mutex); + ASSERT_EQ(0, pthread_attr_init(&attr)); + ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); + + const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); + ASSERT_EQ(0, pthread_attr_destroy(&attr)); + ASSERT_EQ(0, status); + EXPECT_EQ(2U, GetThreadCount()); + pthread_mutex_unlock(&mutex); + + void* dummy; + ASSERT_EQ(0, pthread_join(thread_id, &dummy)); + +# if GTEST_OS_MAC + + // MacOS X may not immediately report the updated thread count after + // joining a thread, causing flakiness in this test. To counter that, we + // wait for up to .5 seconds for the OS to report the correct value. + for (int i = 0; i < 5; ++i) { + if (GetThreadCount() == 1) + break; + + SleepMilliseconds(100); + } + +# endif // GTEST_OS_MAC + + EXPECT_EQ(1U, GetThreadCount()); + pthread_mutex_destroy(&mutex); +} +#else +TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { + EXPECT_EQ(0U, GetThreadCount()); +} +#endif // GTEST_OS_MAC || GTEST_OS_QNX + +TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { + const bool a_false_condition = false; + const char regex[] = +#ifdef _MSC_VER + "gtest-port_test\\.cc\\(\\d+\\):" +#elif GTEST_USES_POSIX_RE + "gtest-port_test\\.cc:[0-9]+" +#else + "gtest-port_test\\.cc:\\d+" +#endif // _MSC_VER + ".*a_false_condition.*Extra info.*"; + + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", + regex); +} + +#if GTEST_HAS_DEATH_TEST + +TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { + EXPECT_EXIT({ + GTEST_CHECK_(true) << "Extra info"; + ::std::cerr << "Success\n"; + exit(0); }, + ::testing::ExitedWithCode(0), "Success"); +} + +#endif // GTEST_HAS_DEATH_TEST + +// Verifies that Google Test choose regular expression engine appropriate to +// the platform. The test will produce compiler errors in case of failure. +// For simplicity, we only cover the most important platforms here. +TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { +#if GTEST_HAS_POSIX_RE + + EXPECT_TRUE(GTEST_USES_POSIX_RE); + +#else + + EXPECT_TRUE(GTEST_USES_SIMPLE_RE); + +#endif +} + +#if GTEST_USES_POSIX_RE + +# if GTEST_HAS_TYPED_TEST + +template +class RETest : public ::testing::Test {}; + +// Defines StringTypes as the list of all string types that class RE +// supports. +typedef testing::Types< + ::std::string, +# if GTEST_HAS_GLOBAL_STRING + ::string, +# endif // GTEST_HAS_GLOBAL_STRING + const char*> StringTypes; + +TYPED_TEST_CASE(RETest, StringTypes); + +// Tests RE's implicit constructors. +TYPED_TEST(RETest, ImplicitConstructorWorks) { + const RE empty(TypeParam("")); + EXPECT_STREQ("", empty.pattern()); + + const RE simple(TypeParam("hello")); + EXPECT_STREQ("hello", simple.pattern()); + + const RE normal(TypeParam(".*(\\w+)")); + EXPECT_STREQ(".*(\\w+)", normal.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TYPED_TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE invalid(TypeParam("?")); + }, "\"?\" is not a valid POSIX Extended regular expression."); +} + +// Tests RE::FullMatch(). +TYPED_TEST(RETest, FullMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); + EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); + EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); +} + +// Tests RE::PartialMatch(). +TYPED_TEST(RETest, PartialMatchWorks) { + const RE empty(TypeParam("")); + EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); + + const RE re(TypeParam("a.*z")); + EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); + EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); + EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); +} + +# endif // GTEST_HAS_TYPED_TEST + +#elif GTEST_USES_SIMPLE_RE + +TEST(IsInSetTest, NulCharIsNotInAnySet) { + EXPECT_FALSE(IsInSet('\0', "")); + EXPECT_FALSE(IsInSet('\0', "\0")); + EXPECT_FALSE(IsInSet('\0', "a")); +} + +TEST(IsInSetTest, WorksForNonNulChars) { + EXPECT_FALSE(IsInSet('a', "Ab")); + EXPECT_FALSE(IsInSet('c', "")); + + EXPECT_TRUE(IsInSet('b', "bcd")); + EXPECT_TRUE(IsInSet('b', "ab")); +} + +TEST(IsAsciiDigitTest, IsFalseForNonDigit) { + EXPECT_FALSE(IsAsciiDigit('\0')); + EXPECT_FALSE(IsAsciiDigit(' ')); + EXPECT_FALSE(IsAsciiDigit('+')); + EXPECT_FALSE(IsAsciiDigit('-')); + EXPECT_FALSE(IsAsciiDigit('.')); + EXPECT_FALSE(IsAsciiDigit('a')); +} + +TEST(IsAsciiDigitTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiDigit('0')); + EXPECT_TRUE(IsAsciiDigit('1')); + EXPECT_TRUE(IsAsciiDigit('5')); + EXPECT_TRUE(IsAsciiDigit('9')); +} + +TEST(IsAsciiPunctTest, IsFalseForNonPunct) { + EXPECT_FALSE(IsAsciiPunct('\0')); + EXPECT_FALSE(IsAsciiPunct(' ')); + EXPECT_FALSE(IsAsciiPunct('\n')); + EXPECT_FALSE(IsAsciiPunct('a')); + EXPECT_FALSE(IsAsciiPunct('0')); +} + +TEST(IsAsciiPunctTest, IsTrueForPunct) { + for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { + EXPECT_PRED1(IsAsciiPunct, *p); + } +} + +TEST(IsRepeatTest, IsFalseForNonRepeatChar) { + EXPECT_FALSE(IsRepeat('\0')); + EXPECT_FALSE(IsRepeat(' ')); + EXPECT_FALSE(IsRepeat('a')); + EXPECT_FALSE(IsRepeat('1')); + EXPECT_FALSE(IsRepeat('-')); +} + +TEST(IsRepeatTest, IsTrueForRepeatChar) { + EXPECT_TRUE(IsRepeat('?')); + EXPECT_TRUE(IsRepeat('*')); + EXPECT_TRUE(IsRepeat('+')); +} + +TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { + EXPECT_FALSE(IsAsciiWhiteSpace('\0')); + EXPECT_FALSE(IsAsciiWhiteSpace('a')); + EXPECT_FALSE(IsAsciiWhiteSpace('1')); + EXPECT_FALSE(IsAsciiWhiteSpace('+')); + EXPECT_FALSE(IsAsciiWhiteSpace('_')); +} + +TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { + EXPECT_TRUE(IsAsciiWhiteSpace(' ')); + EXPECT_TRUE(IsAsciiWhiteSpace('\n')); + EXPECT_TRUE(IsAsciiWhiteSpace('\r')); + EXPECT_TRUE(IsAsciiWhiteSpace('\t')); + EXPECT_TRUE(IsAsciiWhiteSpace('\v')); + EXPECT_TRUE(IsAsciiWhiteSpace('\f')); +} + +TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { + EXPECT_FALSE(IsAsciiWordChar('\0')); + EXPECT_FALSE(IsAsciiWordChar('+')); + EXPECT_FALSE(IsAsciiWordChar('.')); + EXPECT_FALSE(IsAsciiWordChar(' ')); + EXPECT_FALSE(IsAsciiWordChar('\n')); +} + +TEST(IsAsciiWordCharTest, IsTrueForLetter) { + EXPECT_TRUE(IsAsciiWordChar('a')); + EXPECT_TRUE(IsAsciiWordChar('b')); + EXPECT_TRUE(IsAsciiWordChar('A')); + EXPECT_TRUE(IsAsciiWordChar('Z')); +} + +TEST(IsAsciiWordCharTest, IsTrueForDigit) { + EXPECT_TRUE(IsAsciiWordChar('0')); + EXPECT_TRUE(IsAsciiWordChar('1')); + EXPECT_TRUE(IsAsciiWordChar('7')); + EXPECT_TRUE(IsAsciiWordChar('9')); +} + +TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { + EXPECT_TRUE(IsAsciiWordChar('_')); +} + +TEST(IsValidEscapeTest, IsFalseForNonPrintable) { + EXPECT_FALSE(IsValidEscape('\0')); + EXPECT_FALSE(IsValidEscape('\007')); +} + +TEST(IsValidEscapeTest, IsFalseForDigit) { + EXPECT_FALSE(IsValidEscape('0')); + EXPECT_FALSE(IsValidEscape('9')); +} + +TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { + EXPECT_FALSE(IsValidEscape(' ')); + EXPECT_FALSE(IsValidEscape('\n')); +} + +TEST(IsValidEscapeTest, IsFalseForSomeLetter) { + EXPECT_FALSE(IsValidEscape('a')); + EXPECT_FALSE(IsValidEscape('Z')); +} + +TEST(IsValidEscapeTest, IsTrueForPunct) { + EXPECT_TRUE(IsValidEscape('.')); + EXPECT_TRUE(IsValidEscape('-')); + EXPECT_TRUE(IsValidEscape('^')); + EXPECT_TRUE(IsValidEscape('$')); + EXPECT_TRUE(IsValidEscape('(')); + EXPECT_TRUE(IsValidEscape(']')); + EXPECT_TRUE(IsValidEscape('{')); + EXPECT_TRUE(IsValidEscape('|')); +} + +TEST(IsValidEscapeTest, IsTrueForSomeLetter) { + EXPECT_TRUE(IsValidEscape('d')); + EXPECT_TRUE(IsValidEscape('D')); + EXPECT_TRUE(IsValidEscape('s')); + EXPECT_TRUE(IsValidEscape('S')); + EXPECT_TRUE(IsValidEscape('w')); + EXPECT_TRUE(IsValidEscape('W')); +} + +TEST(AtomMatchesCharTest, EscapedPunct) { + EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); + EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); + + EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); + EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); + EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); + EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); +} + +TEST(AtomMatchesCharTest, Escaped_d) { + EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); + + EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_D) { + EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); + EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); +} + +TEST(AtomMatchesCharTest, Escaped_s) { + EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); + EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); + + EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); +} + +TEST(AtomMatchesCharTest, Escaped_S) { + EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); + + EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); + EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); +} + +TEST(AtomMatchesCharTest, Escaped_w) { + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); + EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); + + EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); + EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); +} + +TEST(AtomMatchesCharTest, Escaped_W) { + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); + EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); + + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); + EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); +} + +TEST(AtomMatchesCharTest, EscapedWhiteSpace) { + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); + EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); + EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); + + EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); + EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); + EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); + EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); + EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); +} + +TEST(AtomMatchesCharTest, UnescapedDot) { + EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); + + EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); + EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); + EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); + EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); +} + +TEST(AtomMatchesCharTest, UnescapedChar) { + EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); + EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); + EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); + + EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); + EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); + EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); +} + +TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), + "NULL is not a valid simple regular expression"); + EXPECT_NONFATAL_FAILURE( + ASSERT_FALSE(ValidateRegex("a\\")), + "Syntax error at index 1 in simple regular expression \"a\\\": "); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), + "'\\' cannot appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), + "invalid escape sequence \"\\h\""); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), + "'^' can only appear at the beginning"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), + "'$' can only appear at the end"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), + "'(' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), + "')' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), + "'[' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), + "'{' is unsupported"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), + "'?' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), + "'*' can only follow a repeatable token"); + EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), + "'+' can only follow a repeatable token"); +} + +TEST(ValidateRegexTest, ReturnsTrueForValid) { + EXPECT_TRUE(ValidateRegex("")); + EXPECT_TRUE(ValidateRegex("a")); + EXPECT_TRUE(ValidateRegex(".*")); + EXPECT_TRUE(ValidateRegex("^a_+")); + EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); + EXPECT_TRUE(ValidateRegex("09*$")); + EXPECT_TRUE(ValidateRegex("^Z$")); + EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); + // Repeating more than once. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); + + // Repeating zero times. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); +} + +TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); + // Repeating zero times. + EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); + + // Repeating once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); + // Repeating more than once. + EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); +} + +TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { + EXPECT_TRUE(MatchRegexAtHead("", "")); + EXPECT_TRUE(MatchRegexAtHead("", "ab")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { + EXPECT_FALSE(MatchRegexAtHead("$", "a")); + + EXPECT_TRUE(MatchRegexAtHead("$", "")); + EXPECT_TRUE(MatchRegexAtHead("a$", "a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); + EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); + + EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); + EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); +} + +TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { + EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); + + EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); +} + +TEST(MatchRegexAtHeadTest, + WorksWhenRegexStartsWithRepetionOfEscapeSequence) { + EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); + EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); + + EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); + EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); + EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); +} + +TEST(MatchRegexAtHeadTest, MatchesSequentially) { + EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); + + EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { + EXPECT_FALSE(MatchRegexAnywhere("", NULL)); +} + +TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { + EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); + EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); + + EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); + EXPECT_TRUE(MatchRegexAnywhere("^$", "")); +} + +TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { + EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); + EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); + EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); +} + +TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { + EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); + EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); +} + +// Tests RE's implicit constructors. +TEST(RETest, ImplicitConstructorWorks) { + const RE empty(""); + EXPECT_STREQ("", empty.pattern()); + + const RE simple("hello"); + EXPECT_STREQ("hello", simple.pattern()); +} + +// Tests that RE's constructors reject invalid regular expressions. +TEST(RETest, RejectsInvalidRegex) { + EXPECT_NONFATAL_FAILURE({ + const RE normal(NULL); + }, "NULL is not a valid simple regular expression"); + + EXPECT_NONFATAL_FAILURE({ + const RE normal(".*(\\w+"); + }, "'(' is unsupported"); + + EXPECT_NONFATAL_FAILURE({ + const RE invalid("^?"); + }, "'?' can only follow a repeatable token"); +} + +// Tests RE::FullMatch(). +TEST(RETest, FullMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::FullMatch("", empty)); + EXPECT_FALSE(RE::FullMatch("a", empty)); + + const RE re1("a"); + EXPECT_TRUE(RE::FullMatch("a", re1)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::FullMatch("az", re)); + EXPECT_TRUE(RE::FullMatch("axyz", re)); + EXPECT_FALSE(RE::FullMatch("baz", re)); + EXPECT_FALSE(RE::FullMatch("azy", re)); +} + +// Tests RE::PartialMatch(). +TEST(RETest, PartialMatchWorks) { + const RE empty(""); + EXPECT_TRUE(RE::PartialMatch("", empty)); + EXPECT_TRUE(RE::PartialMatch("a", empty)); + + const RE re("a.*z"); + EXPECT_TRUE(RE::PartialMatch("az", re)); + EXPECT_TRUE(RE::PartialMatch("axyz", re)); + EXPECT_TRUE(RE::PartialMatch("baz", re)); + EXPECT_TRUE(RE::PartialMatch("azy", re)); + EXPECT_FALSE(RE::PartialMatch("zza", re)); +} + +#endif // GTEST_USES_POSIX_RE + +#if !GTEST_OS_WINDOWS_MOBILE + +TEST(CaptureTest, CapturesStdout) { + CaptureStdout(); + fprintf(stdout, "abc"); + EXPECT_STREQ("abc", GetCapturedStdout().c_str()); + + CaptureStdout(); + fprintf(stdout, "def%cghi", '\0'); + EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); +} + +TEST(CaptureTest, CapturesStderr) { + CaptureStderr(); + fprintf(stderr, "jkl"); + EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); + + CaptureStderr(); + fprintf(stderr, "jkl%cmno", '\0'); + EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); +} + +// Tests that stdout and stderr capture don't interfere with each other. +TEST(CaptureTest, CapturesStdoutAndStderr) { + CaptureStdout(); + CaptureStderr(); + fprintf(stdout, "pqr"); + fprintf(stderr, "stu"); + EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); + EXPECT_STREQ("stu", GetCapturedStderr().c_str()); +} + +TEST(CaptureDeathTest, CannotReenterStdoutCapture) { + CaptureStdout(); + EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(), + "Only one stdout capturer can exist at a time"); + GetCapturedStdout(); + + // We cannot test stderr capturing using death tests as they use it + // themselves. +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { + ThreadLocal t1; + EXPECT_EQ(0, t1.get()); + + ThreadLocal t2; + EXPECT_TRUE(t2.get() == NULL); +} + +TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { + ThreadLocal t1(123); + EXPECT_EQ(123, t1.get()); + + int i = 0; + ThreadLocal t2(&i); + EXPECT_EQ(&i, t2.get()); +} + +class NoDefaultContructor { + public: + explicit NoDefaultContructor(const char*) {} + NoDefaultContructor(const NoDefaultContructor&) {} +}; + +TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { + ThreadLocal bar(NoDefaultContructor("foo")); + bar.pointer(); +} + +TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { + ThreadLocal thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); + + // Verifies the condition still holds after calling set. + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); +} + +TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { + ThreadLocal thread_local_string; + const ThreadLocal& const_thread_local_string = + thread_local_string; + + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); + + thread_local_string.set("foo"); + EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); +} + +#if GTEST_IS_THREADSAFE + +void AddTwo(int* param) { *param += 2; } + +TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { + int i = 40; + ThreadWithParam thread(&AddTwo, &i, NULL); + thread.Join(); + EXPECT_EQ(42, i); +} + +TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { + // AssertHeld() is flaky only in the presence of multiple threads accessing + // the lock. In this case, the test is robust. + EXPECT_DEATH_IF_SUPPORTED({ + Mutex m; + { MutexLock lock(&m); } + m.AssertHeld(); + }, + "thread .*hold"); +} + +TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { + Mutex m; + MutexLock lock(&m); + m.AssertHeld(); +} + +class AtomicCounterWithMutex { + public: + explicit AtomicCounterWithMutex(Mutex* mutex) : + value_(0), mutex_(mutex), random_(42) {} + + void Increment() { + MutexLock lock(mutex_); + int temp = value_; + { + // We need to put up a memory barrier to prevent reads and writes to + // value_ rearranged with the call to SleepMilliseconds when observed + // from other threads. +#if GTEST_HAS_PTHREAD + // On POSIX, locking a mutex puts up a memory barrier. We cannot use + // Mutex and MutexLock here or rely on their memory barrier + // functionality as we are testing them here. + pthread_mutex_t memory_barrier_mutex; + GTEST_CHECK_POSIX_SUCCESS_( + pthread_mutex_init(&memory_barrier_mutex, NULL)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); + + SleepMilliseconds(random_.Generate(30)); + + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); +#elif GTEST_OS_WINDOWS + // On Windows, performing an interlocked access puts up a memory barrier. + volatile LONG dummy = 0; + ::InterlockedIncrement(&dummy); + SleepMilliseconds(random_.Generate(30)); + ::InterlockedIncrement(&dummy); +#else +# error "Memory barrier not implemented on this platform." +#endif // GTEST_HAS_PTHREAD + } + value_ = temp + 1; + } + int value() const { return value_; } + + private: + volatile int value_; + Mutex* const mutex_; // Protects value_. + Random random_; +}; + +void CountingThreadFunc(pair param) { + for (int i = 0; i < param.second; ++i) + param.first->Increment(); +} + +// Tests that the mutex only lets one thread at a time to lock it. +TEST(MutexTest, OnlyOneThreadCanLockAtATime) { + Mutex mutex; + AtomicCounterWithMutex locked_counter(&mutex); + + typedef ThreadWithParam > ThreadType; + const int kCycleCount = 20; + const int kThreadCount = 7; + scoped_ptr counting_threads[kThreadCount]; + Notification threads_can_start; + // Creates and runs kThreadCount threads that increment locked_counter + // kCycleCount times each. + for (int i = 0; i < kThreadCount; ++i) { + counting_threads[i].reset(new ThreadType(&CountingThreadFunc, + make_pair(&locked_counter, + kCycleCount), + &threads_can_start)); + } + threads_can_start.Notify(); + for (int i = 0; i < kThreadCount; ++i) + counting_threads[i]->Join(); + + // If the mutex lets more than one thread to increment the counter at a + // time, they are likely to encounter a race condition and have some + // increments overwritten, resulting in the lower then expected counter + // value. + EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); +} + +template +void RunFromThread(void (func)(T), T param) { + ThreadWithParam thread(func, param, NULL); + thread.Join(); +} + +void RetrieveThreadLocalValue( + pair*, std::string*> param) { + *param.second = param.first->get(); +} + +TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { + ThreadLocal thread_local_string("foo"); + EXPECT_STREQ("foo", thread_local_string.get().c_str()); + + thread_local_string.set("bar"); + EXPECT_STREQ("bar", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_STREQ("foo", result.c_str()); +} + +// Keeps track of whether of destructors being called on instances of +// DestructorTracker. On Windows, waits for the destructor call reports. +class DestructorCall { + public: + DestructorCall() { + invoked_ = false; +#if GTEST_OS_WINDOWS + wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL)); + GTEST_CHECK_(wait_event_.Get() != NULL); +#endif + } + + bool CheckDestroyed() const { +#if GTEST_OS_WINDOWS + if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0) + return false; +#endif + return invoked_; + } + + void ReportDestroyed() { + invoked_ = true; +#if GTEST_OS_WINDOWS + ::SetEvent(wait_event_.Get()); +#endif + } + + static std::vector& List() { return *list_; } + + static void ResetList() { + for (size_t i = 0; i < list_->size(); ++i) { + delete list_->at(i); + } + list_->clear(); + } + + private: + bool invoked_; +#if GTEST_OS_WINDOWS + AutoHandle wait_event_; +#endif + static std::vector* const list_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall); +}; + +std::vector* const DestructorCall::list_ = + new std::vector; + +// DestructorTracker keeps track of whether its instances have been +// destroyed. +class DestructorTracker { + public: + DestructorTracker() : index_(GetNewIndex()) {} + DestructorTracker(const DestructorTracker& /* rhs */) + : index_(GetNewIndex()) {} + ~DestructorTracker() { + // We never access DestructorCall::List() concurrently, so we don't need + // to protect this acccess with a mutex. + DestructorCall::List()[index_]->ReportDestroyed(); + } + + private: + static int GetNewIndex() { + DestructorCall::List().push_back(new DestructorCall); + return DestructorCall::List().size() - 1; + } + const int index_; + + GTEST_DISALLOW_ASSIGN_(DestructorTracker); +}; + +typedef ThreadLocal* ThreadParam; + +void CallThreadLocalGet(ThreadParam thread_local_param) { + thread_local_param->get(); +} + +// Tests that when a ThreadLocal object dies in a thread, it destroys +// the managed object for that thread. +TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { + DestructorCall::ResetList(); + + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; + ASSERT_EQ(1U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + + // This creates another DestructorTracker object for the main thread. + thread_local_tracker.get(); + ASSERT_EQ(2U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + ASSERT_FALSE(DestructorCall::List()[1]->CheckDestroyed()); + } + + // Now thread_local_tracker has died. It should have destroyed both the + // default value shared by all threads and the value for the main + // thread. + ASSERT_EQ(2U, DestructorCall::List().size()); + EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); + EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed()); + + DestructorCall::ResetList(); +} + +// Tests that when a thread exits, the thread-local object for that +// thread is destroyed. +TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { + DestructorCall::ResetList(); + + { + // The next line default constructs a DestructorTracker object as + // the default value of objects managed by thread_local_tracker. + ThreadLocal thread_local_tracker; + ASSERT_EQ(1U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + + // This creates another DestructorTracker object in the new thread. + ThreadWithParam thread( + &CallThreadLocalGet, &thread_local_tracker, NULL); + thread.Join(); + + // The thread has exited, and we should have another DestroyedTracker + // instance created for it. But it may not have been destroyed yet. + // The instance for the main thread should still persist. + ASSERT_EQ(2U, DestructorCall::List().size()); + ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); + } + + // The thread has exited and thread_local_tracker has died. The default + // value should have been destroyed too. + ASSERT_EQ(2U, DestructorCall::List().size()); + EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); + EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed()); + + DestructorCall::ResetList(); +} + +TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { + ThreadLocal thread_local_string; + thread_local_string.set("Foo"); + EXPECT_STREQ("Foo", thread_local_string.get().c_str()); + + std::string result; + RunFromThread(&RetrieveThreadLocalValue, + make_pair(&thread_local_string, &result)); + EXPECT_TRUE(result.empty()); +} + +#endif // GTEST_IS_THREADSAFE + +#if GTEST_OS_WINDOWS +TEST(WindowsTypesTest, HANDLEIsVoidStar) { + StaticAssertTypeEq(); +} + +TEST(WindowsTypesTest, CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION) { + StaticAssertTypeEq(); +} +#endif // GTEST_OS_WINDOWS + +} // namespace internal +} // namespace testing diff --git a/src/test/gtest/test/gtest-printers_test.cc b/src/test/gtest/test/gtest-printers_test.cc new file mode 100644 index 00000000..7b07fd10 --- /dev/null +++ b/src/test/gtest/test/gtest-printers_test.cc @@ -0,0 +1,1651 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file tests the universal value printer. + +#include "gtest/gtest-printers.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" + +// hash_map and hash_set are available under Visual C++. +#if _MSC_VER +# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +# include // NOLINT +# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +# include // NOLINT +#endif // GTEST_OS_WINDOWS + +// Some user-defined types for testing the universal value printer. + +// An anonymous enum type. +enum AnonymousEnum { + kAE1 = -1, + kAE2 = 1 +}; + +// An enum without a user-defined printer. +enum EnumWithoutPrinter { + kEWP1 = -2, + kEWP2 = 42 +}; + +// An enum with a << operator. +enum EnumWithStreaming { + kEWS1 = 10 +}; + +std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { + return os << (e == kEWS1 ? "kEWS1" : "invalid"); +} + +// An enum with a PrintTo() function. +enum EnumWithPrintTo { + kEWPT1 = 1 +}; + +void PrintTo(EnumWithPrintTo e, std::ostream* os) { + *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); +} + +// A class implicitly convertible to BiggestInt. +class BiggestIntConvertible { + public: + operator ::testing::internal::BiggestInt() const { return 42; } +}; + +// A user-defined unprintable class template in the global namespace. +template +class UnprintableTemplateInGlobal { + public: + UnprintableTemplateInGlobal() : value_() {} + private: + T value_; +}; + +// A user-defined streamable type in the global namespace. +class StreamableInGlobal { + public: + virtual ~StreamableInGlobal() {} +}; + +inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { + os << "StreamableInGlobal"; +} + +void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { + os << "StreamableInGlobal*"; +} + +namespace foo { + +// A user-defined unprintable type in a user namespace. +class UnprintableInFoo { + public: + UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } + double z() const { return z_; } + private: + char xy_[8]; + double z_; +}; + +// A user-defined printable type in a user-chosen namespace. +struct PrintableViaPrintTo { + PrintableViaPrintTo() : value() {} + int value; +}; + +void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { + *os << "PrintableViaPrintTo: " << x.value; +} + +// A type with a user-defined << for printing its pointer. +struct PointerPrintable { +}; + +::std::ostream& operator<<(::std::ostream& os, + const PointerPrintable* /* x */) { + return os << "PointerPrintable*"; +} + +// A user-defined printable class template in a user-chosen namespace. +template +class PrintableViaPrintToTemplate { + public: + explicit PrintableViaPrintToTemplate(const T& a_value) : value_(a_value) {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +void PrintTo(const PrintableViaPrintToTemplate& x, ::std::ostream* os) { + *os << "PrintableViaPrintToTemplate: " << x.value(); +} + +// A user-defined streamable class template in a user namespace. +template +class StreamableTemplateInFoo { + public: + StreamableTemplateInFoo() : value_() {} + + const T& value() const { return value_; } + private: + T value_; +}; + +template +inline ::std::ostream& operator<<(::std::ostream& os, + const StreamableTemplateInFoo& x) { + return os << "StreamableTemplateInFoo: " << x.value(); +} + +} // namespace foo + +namespace testing { +namespace gtest_printers_test { + +using ::std::deque; +using ::std::list; +using ::std::make_pair; +using ::std::map; +using ::std::multimap; +using ::std::multiset; +using ::std::pair; +using ::std::set; +using ::std::vector; +using ::testing::PrintToString; +using ::testing::internal::FormatForComparisonFailureMessage; +using ::testing::internal::ImplicitCast_; +using ::testing::internal::NativeArray; +using ::testing::internal::RE; +using ::testing::internal::RelationToSourceReference; +using ::testing::internal::Strings; +using ::testing::internal::UniversalPrint; +using ::testing::internal::UniversalPrinter; +using ::testing::internal::UniversalTersePrint; +using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; +using ::testing::internal::string; + +// The hash_* classes are not part of the C++ standard. STLport +// defines them in namespace std. MSVC defines them in ::stdext. GCC +// defines them in ::. +#ifdef _STLP_HASH_MAP // We got from STLport. +using ::std::hash_map; +using ::std::hash_set; +using ::std::hash_multimap; +using ::std::hash_multiset; +#elif _MSC_VER +using ::stdext::hash_map; +using ::stdext::hash_set; +using ::stdext::hash_multimap; +using ::stdext::hash_multiset; +#endif + +// Prints a value to a string using the universal value printer. This +// is a helper for testing UniversalPrinter::Print() for various types. +template +string Print(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Prints a value passed by reference to a string, using the universal +// value printer. This is a helper for testing +// UniversalPrinter::Print() for various types. +template +string PrintByRef(const T& value) { + ::std::stringstream ss; + UniversalPrinter::Print(value, &ss); + return ss.str(); +} + +// Tests printing various enum types. + +TEST(PrintEnumTest, AnonymousEnum) { + EXPECT_EQ("-1", Print(kAE1)); + EXPECT_EQ("1", Print(kAE2)); +} + +TEST(PrintEnumTest, EnumWithoutPrinter) { + EXPECT_EQ("-2", Print(kEWP1)); + EXPECT_EQ("42", Print(kEWP2)); +} + +TEST(PrintEnumTest, EnumWithStreaming) { + EXPECT_EQ("kEWS1", Print(kEWS1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +TEST(PrintEnumTest, EnumWithPrintTo) { + EXPECT_EQ("kEWPT1", Print(kEWPT1)); + EXPECT_EQ("invalid", Print(static_cast(0))); +} + +// Tests printing a class implicitly convertible to BiggestInt. + +TEST(PrintClassTest, BiggestIntConvertible) { + EXPECT_EQ("42", Print(BiggestIntConvertible())); +} + +// Tests printing various char types. + +// char. +TEST(PrintCharTest, PlainChar) { + EXPECT_EQ("'\\0'", Print('\0')); + EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); + EXPECT_EQ("'\"' (34, 0x22)", Print('"')); + EXPECT_EQ("'?' (63, 0x3F)", Print('?')); + EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); + EXPECT_EQ("'\\a' (7)", Print('\a')); + EXPECT_EQ("'\\b' (8)", Print('\b')); + EXPECT_EQ("'\\f' (12, 0xC)", Print('\f')); + EXPECT_EQ("'\\n' (10, 0xA)", Print('\n')); + EXPECT_EQ("'\\r' (13, 0xD)", Print('\r')); + EXPECT_EQ("'\\t' (9)", Print('\t')); + EXPECT_EQ("'\\v' (11, 0xB)", Print('\v')); + EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); + EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); + EXPECT_EQ("' ' (32, 0x20)", Print(' ')); + EXPECT_EQ("'a' (97, 0x61)", Print('a')); +} + +// signed char. +TEST(PrintCharTest, SignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'\\xCE' (-50)", + Print(static_cast(-50))); +} + +// unsigned char. +TEST(PrintCharTest, UnsignedChar) { + EXPECT_EQ("'\\0'", Print(static_cast('\0'))); + EXPECT_EQ("'b' (98, 0x62)", + Print(static_cast('b'))); +} + +// Tests printing other simple, built-in types. + +// bool. +TEST(PrintBuiltInTypeTest, Bool) { + EXPECT_EQ("false", Print(false)); + EXPECT_EQ("true", Print(true)); +} + +// wchar_t. +TEST(PrintBuiltInTypeTest, Wchar_t) { + EXPECT_EQ("L'\\0'", Print(L'\0')); + EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); + EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); + EXPECT_EQ("L'?' (63, 0x3F)", Print(L'?')); + EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); + EXPECT_EQ("L'\\a' (7)", Print(L'\a')); + EXPECT_EQ("L'\\b' (8)", Print(L'\b')); + EXPECT_EQ("L'\\f' (12, 0xC)", Print(L'\f')); + EXPECT_EQ("L'\\n' (10, 0xA)", Print(L'\n')); + EXPECT_EQ("L'\\r' (13, 0xD)", Print(L'\r')); + EXPECT_EQ("L'\\t' (9)", Print(L'\t')); + EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); + EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); + EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); + EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); + EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); + EXPECT_EQ("L'\\x576' (1398)", Print(static_cast(0x576))); + EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast(0xC74D))); +} + +// Test that Int64 provides more storage than wchar_t. +TEST(PrintTypeSizeTest, Wchar_t) { + EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); +} + +// Various integer types. +TEST(PrintBuiltInTypeTest, Integer) { + EXPECT_EQ("'\\xFF' (255)", Print(static_cast(255))); // uint8 + EXPECT_EQ("'\\x80' (-128)", Print(static_cast(-128))); // int8 + EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 + EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 + EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 + EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 + EXPECT_EQ("18446744073709551615", + Print(static_cast(-1))); // uint64 + EXPECT_EQ("-9223372036854775808", + Print(static_cast(1) << 63)); // int64 +} + +// Size types. +TEST(PrintBuiltInTypeTest, Size_t) { + EXPECT_EQ("1", Print(sizeof('a'))); // size_t. +#if !GTEST_OS_WINDOWS + // Windows has no ssize_t type. + EXPECT_EQ("-2", Print(static_cast(-2))); // ssize_t. +#endif // !GTEST_OS_WINDOWS +} + +// Floating-points. +TEST(PrintBuiltInTypeTest, FloatingPoints) { + EXPECT_EQ("1.5", Print(1.5f)); // float + EXPECT_EQ("-2.5", Print(-2.5)); // double +} + +// Since ::std::stringstream::operator<<(const void *) formats the pointer +// output differently with different compilers, we have to create the expected +// output first and use it as our expectation. +static string PrintPointer(const void *p) { + ::std::stringstream expected_result_stream; + expected_result_stream << p; + return expected_result_stream.str(); +} + +// Tests printing C strings. + +// const char*. +TEST(PrintCStringTest, Const) { + const char* p = "World"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); +} + +// char*. +TEST(PrintCStringTest, NonConst) { + char p[] = "Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", + Print(static_cast(p))); +} + +// NULL C string. +TEST(PrintCStringTest, Null) { + const char* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that C strings are escaped properly. +TEST(PrintCStringTest, EscapesProperly) { + const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; + EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\x7F\\xFF a\"", + Print(p)); +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) + +// const wchar_t*. +TEST(PrintWideCStringTest, Const) { + const wchar_t* p = L"World"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); +} + +// wchar_t*. +TEST(PrintWideCStringTest, NonConst) { + wchar_t p[] = L"Hi"; + EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", + Print(static_cast(p))); +} + +// NULL wide C string. +TEST(PrintWideCStringTest, Null) { + const wchar_t* p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that wide C strings are escaped properly. +TEST(PrintWideCStringTest, EscapesProperly) { + const wchar_t s[] = {'\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', + '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; + EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"?\\\\\\a\\b\\f" + "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", + Print(static_cast(s))); +} +#endif // native wchar_t + +// Tests printing pointers to other char types. + +// signed char*. +TEST(PrintCharPointerTest, SignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const signed char*. +TEST(PrintCharPointerTest, ConstSignedChar) { + signed char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// unsigned char*. +TEST(PrintCharPointerTest, UnsignedChar) { + unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const unsigned char*. +TEST(PrintCharPointerTest, ConstUnsignedChar) { + const unsigned char* p = reinterpret_cast(0x1234); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to simple, built-in types. + +// bool*. +TEST(PrintPointerToBuiltInTypeTest, Bool) { + bool* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// void*. +TEST(PrintPointerToBuiltInTypeTest, Void) { + void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// const void*. +TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { + const void* p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to pointers. +TEST(PrintPointerToPointerTest, IntPointerPointer) { + int** p = reinterpret_cast(0xABCD); + EXPECT_EQ(PrintPointer(p), Print(p)); + p = NULL; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing (non-member) function pointers. + +void MyFunction(int /* n */) {} + +TEST(PrintPointerTest, NonMemberFunctionPointer) { + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + EXPECT_EQ( + PrintPointer(reinterpret_cast( + reinterpret_cast(&MyFunction))), + Print(&MyFunction)); + int (*p)(bool) = NULL; // NOLINT + EXPECT_EQ("NULL", Print(p)); +} + +// An assertion predicate determining whether a one string is a prefix for +// another. +template +AssertionResult HasPrefix(const StringType& str, const StringType& prefix) { + if (str.find(prefix, 0) == 0) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(prefix[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << begin_string_quote << prefix << "\" is not a prefix of " + << begin_string_quote << str << "\"\n"; +} + +// Tests printing member variable pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. + +struct Foo { + public: + virtual ~Foo() {} + int MyMethod(char x) { return x + 1; } + virtual char MyVirtualMethod(int /* n */) { return 'a'; } + + int value; +}; + +TEST(PrintPointerTest, MemberVariablePointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::value), + Print(sizeof(&Foo::value)) + "-byte object ")); + int (Foo::*p) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing member function pointers. Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined. Thus they will be +// printed as raw bytes. +TEST(PrintPointerTest, MemberFunctionPointer) { + EXPECT_TRUE(HasPrefix(Print(&Foo::MyMethod), + Print(sizeof(&Foo::MyMethod)) + "-byte object ")); + EXPECT_TRUE( + HasPrefix(Print(&Foo::MyVirtualMethod), + Print(sizeof((&Foo::MyVirtualMethod))) + "-byte object ")); + int (Foo::*p)(char) = NULL; // NOLINT + EXPECT_TRUE(HasPrefix(Print(p), + Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing C arrays. + +// The difference between this and Print() is that it ensures that the +// argument is a reference to an array. +template +string PrintArrayHelper(T (&a)[N]) { + return Print(a); +} + +// One-dimensional array. +TEST(PrintArrayTest, OneDimensionalArray) { + int a[5] = { 1, 2, 3, 4, 5 }; + EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a)); +} + +// Two-dimensional array. +TEST(PrintArrayTest, TwoDimensionalArray) { + int a[2][5] = { + { 1, 2, 3, 4, 5 }, + { 6, 7, 8, 9, 0 } + }; + EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a)); +} + +// Array of const elements. +TEST(PrintArrayTest, ConstArray) { + const bool a[1] = { false }; + EXPECT_EQ("{ false }", PrintArrayHelper(a)); +} + +// char array without terminating NUL. +TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + char a[] = { 'H', '\0', 'i' }; + EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// const char array with terminating NUL. +TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { + const char a[] = "\0Hi"; + EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); +} + +// const wchar_t array without terminating NUL. +TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const wchar_t a[] = { L'H', L'\0', L'i' }; + EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// wchar_t array with terminating NUL. +TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { + const wchar_t a[] = L"\0Hi"; + EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); +} + +// Array of objects. +TEST(PrintArrayTest, ObjectArray) { + string a[3] = { "Hi", "Hello", "Ni hao" }; + EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); +} + +// Array with many elements. +TEST(PrintArrayTest, BigArray) { + int a[100] = { 1, 2, 3 }; + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", + PrintArrayHelper(a)); +} + +// Tests printing ::string and ::std::string. + +#if GTEST_HAS_GLOBAL_STRING +// ::string. +TEST(PrintStringTest, StringInGlobalNamespace) { + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_STRING + +// ::std::string. +TEST(PrintStringTest, StringInStdNamespace) { + const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; + const ::std::string str(s, sizeof(s)); + EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", + Print(str)); +} + +TEST(PrintStringTest, StringAmbiguousHex) { + // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of: + // '\x6', '\x6B', or '\x6BA'. + + // a hex escaping sequence following by a decimal digit + EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3"))); + // a hex escaping sequence following by a hex digit (lower-case) + EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas"))); + // a hex escaping sequence following by a hex digit (upper-case) + EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA"))); + // a hex escaping sequence following by a non-xdigit + EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!"))); +} + +// Tests printing ::wstring and ::std::wstring. + +#if GTEST_HAS_GLOBAL_WSTRING +// ::wstring. +TEST(PrintWideStringTest, StringInGlobalNamespace) { + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +// ::std::wstring. +TEST(PrintWideStringTest, StringInStdNamespace) { + const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; + const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); + EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" + "\\xD3\\x576\\x8D3\\xC74D a\\0\"", + Print(str)); +} + +TEST(PrintWideStringTest, StringAmbiguousHex) { + // same for wide strings. + EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); + EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", + Print(::std::wstring(L"mm\x6" L"bananas"))); + EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", + Print(::std::wstring(L"NOM\x6" L"BANANA"))); + EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); +} +#endif // GTEST_HAS_STD_WSTRING + +// Tests printing types that support generic streaming (i.e. streaming +// to std::basic_ostream for any valid Char and +// CharTraits types). + +// Tests printing a non-template type that supports generic streaming. + +class AllowsGenericStreaming {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreaming& /* a */) { + return os << "AllowsGenericStreaming"; +} + +TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { + AllowsGenericStreaming a; + EXPECT_EQ("AllowsGenericStreaming", Print(a)); +} + +// Tests printing a template type that supports generic streaming. + +template +class AllowsGenericStreamingTemplate {}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingTemplate& /* a */) { + return os << "AllowsGenericStreamingTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TemplateType) { + AllowsGenericStreamingTemplate a; + EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); +} + +// Tests printing a type that supports generic streaming and can be +// implicitly converted to another printable type. + +template +class AllowsGenericStreamingAndImplicitConversionTemplate { + public: + operator bool() const { return false; } +}; + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const AllowsGenericStreamingAndImplicitConversionTemplate& /* a */) { + return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { + AllowsGenericStreamingAndImplicitConversionTemplate a; + EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); +} + +#if GTEST_HAS_STRING_PIECE_ + +// Tests printing StringPiece. + +TEST(PrintStringPieceTest, SimpleStringPiece) { + const StringPiece sp = "Hello"; + EXPECT_EQ("\"Hello\"", Print(sp)); +} + +TEST(PrintStringPieceTest, UnprintableCharacters) { + const char str[] = "NUL (\0) and \r\t"; + const StringPiece sp(str, sizeof(str) - 1); + EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); +} + +#endif // GTEST_HAS_STRING_PIECE_ + +// Tests printing STL containers. + +TEST(PrintStlContainerTest, EmptyDeque) { + deque empty; + EXPECT_EQ("{}", Print(empty)); +} + +TEST(PrintStlContainerTest, NonEmptyDeque) { + deque non_empty; + non_empty.push_back(1); + non_empty.push_back(3); + EXPECT_EQ("{ 1, 3 }", Print(non_empty)); +} + +#if GTEST_HAS_HASH_MAP_ + +TEST(PrintStlContainerTest, OneElementHashMap) { + hash_map map1; + map1[1] = 'a'; + EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); +} + +TEST(PrintStlContainerTest, HashMultiMap) { + hash_multimap map1; + map1.insert(make_pair(5, true)); + map1.insert(make_pair(5, false)); + + // Elements of hash_multimap can be printed in any order. + const string result = Print(map1); + EXPECT_TRUE(result == "{ (5, true), (5, false) }" || + result == "{ (5, false), (5, true) }") + << " where Print(map1) returns \"" << result << "\"."; +} + +#endif // GTEST_HAS_HASH_MAP_ + +#if GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, HashSet) { + hash_set set1; + set1.insert("hello"); + EXPECT_EQ("{ \"hello\" }", Print(set1)); +} + +TEST(PrintStlContainerTest, HashMultiSet) { + const int kSize = 5; + int a[kSize] = { 1, 1, 2, 5, 1 }; + hash_multiset set1(a, a + kSize); + + // Elements of hash_multiset can be printed in any order. + const string result = Print(set1); + const string expected_pattern = "{ d, d, d, d, d }"; // d means a digit. + + // Verifies the result matches the expected pattern; also extracts + // the numbers in the result. + ASSERT_EQ(expected_pattern.length(), result.length()); + std::vector numbers; + for (size_t i = 0; i != result.length(); i++) { + if (expected_pattern[i] == 'd') { + ASSERT_NE(isdigit(static_cast(result[i])), 0); + numbers.push_back(result[i] - '0'); + } else { + EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " + << result; + } + } + + // Makes sure the result contains the right numbers. + std::sort(numbers.begin(), numbers.end()); + std::sort(a, a + kSize); + EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); +} + +#endif // GTEST_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, List) { + const string a[] = { + "hello", + "world" + }; + const list strings(a, a + 2); + EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); +} + +TEST(PrintStlContainerTest, Map) { + map map1; + map1[1] = true; + map1[5] = false; + map1[3] = true; + EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); +} + +TEST(PrintStlContainerTest, MultiMap) { + multimap map1; + // The make_pair template function would deduce the type as + // pair here, and since the key part in a multimap has to + // be constant, without a templated ctor in the pair class (as in + // libCstd on Solaris), make_pair call would fail to compile as no + // implicit conversion is found. Thus explicit typename is used + // here instead. + map1.insert(pair(true, 0)); + map1.insert(pair(true, 1)); + map1.insert(pair(false, 2)); + EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); +} + +TEST(PrintStlContainerTest, Set) { + const unsigned int a[] = { 3, 0, 5 }; + set set1(a, a + 3); + EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, MultiSet) { + const int a[] = { 1, 1, 2, 5, 1 }; + multiset set1(a, a + 5); + EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, Pair) { + pair p(true, 5); + EXPECT_EQ("(true, 5)", Print(p)); +} + +TEST(PrintStlContainerTest, Vector) { + vector v; + v.push_back(1); + v.push_back(2); + EXPECT_EQ("{ 1, 2 }", Print(v)); +} + +TEST(PrintStlContainerTest, LongSequence) { + const int a[100] = { 1, 2, 3 }; + const vector v(a, a + 100); + EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " + "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); +} + +TEST(PrintStlContainerTest, NestedContainer) { + const int a1[] = { 1, 2 }; + const int a2[] = { 3, 4, 5 }; + const list l1(a1, a1 + 2); + const list l2(a2, a2 + 3); + + vector > v; + v.push_back(l1); + v.push_back(l2); + EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); +} + +TEST(PrintStlContainerTest, OneDimensionalNativeArray) { + const int a[3] = { 1, 2, 3 }; + NativeArray b(a, 3, RelationToSourceReference()); + EXPECT_EQ("{ 1, 2, 3 }", Print(b)); +} + +TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { + const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; + NativeArray b(a, 2, RelationToSourceReference()); + EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); +} + +// Tests that a class named iterator isn't treated as a container. + +struct iterator { + char x; +}; + +TEST(PrintStlContainerTest, Iterator) { + iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +// Tests that a class named const_iterator isn't treated as a container. + +struct const_iterator { + char x; +}; + +TEST(PrintStlContainerTest, ConstIterator) { + const_iterator it = {}; + EXPECT_EQ("1-byte object <00>", Print(it)); +} + +#if GTEST_HAS_TR1_TUPLE +// Tests printing ::std::tr1::tuples. + +// Tuples of various arities. +TEST(PrintTr1TupleTest, VariousSizes) { + ::std::tr1::tuple<> t0; + EXPECT_EQ("()", Print(t0)); + + ::std::tr1::tuple t1(5); + EXPECT_EQ("(5)", Print(t1)); + + ::std::tr1::tuple t2('a', true); + EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); + + ::std::tr1::tuple t3(false, 2, 3); + EXPECT_EQ("(false, 2, 3)", Print(t3)); + + ::std::tr1::tuple t4(false, 2, 3, 4); + EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); + + ::std::tr1::tuple t5(false, 2, 3, 4, true); + EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); + + ::std::tr1::tuple t6(false, 2, 3, 4, true, 6); + EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); + + ::std::tr1::tuple t7( + false, 2, 3, 4, true, 6, 7); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); + + ::std::tr1::tuple t8( + false, 2, 3, 4, true, 6, 7, true); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); + + ::std::tr1::tuple t9( + false, 2, 3, 4, true, 6, 7, true, 9); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); + + const char* const str = "8"; + // VC++ 2010's implementation of tuple of C++0x is deficient, requiring + // an explicit type cast of NULL to be used. + ::std::tr1::tuple + t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, + ImplicitCast_(NULL), "10"); + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + " pointing to \"8\", NULL, \"10\")", + Print(t10)); +} + +// Nested tuples. +TEST(PrintTr1TupleTest, NestedTuple) { + ::std::tr1::tuple< ::std::tr1::tuple, char> nested( + ::std::tr1::make_tuple(5, true), 'a'); + EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); +} + +#endif // GTEST_HAS_TR1_TUPLE + +#if GTEST_LANG_CXX11 +// Tests printing ::std::tuples. + +// Tuples of various arities. +TEST(PrintStdTupleTest, VariousSizes) { + ::std::tuple<> t0; + EXPECT_EQ("()", Print(t0)); + + ::std::tuple t1(5); + EXPECT_EQ("(5)", Print(t1)); + + ::std::tuple t2('a', true); + EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); + + ::std::tuple t3(false, 2, 3); + EXPECT_EQ("(false, 2, 3)", Print(t3)); + + ::std::tuple t4(false, 2, 3, 4); + EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); + + ::std::tuple t5(false, 2, 3, 4, true); + EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); + + ::std::tuple t6(false, 2, 3, 4, true, 6); + EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); + + ::std::tuple t7( + false, 2, 3, 4, true, 6, 7); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); + + ::std::tuple t8( + false, 2, 3, 4, true, 6, 7, true); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); + + ::std::tuple t9( + false, 2, 3, 4, true, 6, 7, true, 9); + EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); + + const char* const str = "8"; + // VC++ 2010's implementation of tuple of C++0x is deficient, requiring + // an explicit type cast of NULL to be used. + ::std::tuple + t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, + ImplicitCast_(NULL), "10"); + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + + " pointing to \"8\", NULL, \"10\")", + Print(t10)); +} + +// Nested tuples. +TEST(PrintStdTupleTest, NestedTuple) { + ::std::tuple< ::std::tuple, char> nested( + ::std::make_tuple(5, true), 'a'); + EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); +} + +#endif // GTEST_LANG_CXX11 + +// Tests printing user-defined unprintable types. + +// Unprintable types in the global namespace. +TEST(PrintUnprintableTypeTest, InGlobalNamespace) { + EXPECT_EQ("1-byte object <00>", + Print(UnprintableTemplateInGlobal())); +} + +// Unprintable types in a user namespace. +TEST(PrintUnprintableTypeTest, InUserNamespace) { + EXPECT_EQ("16-byte object ", + Print(::foo::UnprintableInFoo())); +} + +// Unprintable types are that too big to be printed completely. + +struct Big { + Big() { memset(array, 0, sizeof(array)); } + char array[257]; +}; + +TEST(PrintUnpritableTypeTest, BigObject) { + EXPECT_EQ("257-byte object <00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 ... 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " + "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00>", + Print(Big())); +} + +// Tests printing user-defined streamable types. + +// Streamable types in the global namespace. +TEST(PrintStreamableTypeTest, InGlobalNamespace) { + StreamableInGlobal x; + EXPECT_EQ("StreamableInGlobal", Print(x)); + EXPECT_EQ("StreamableInGlobal*", Print(&x)); +} + +// Printable template types in a user namespace. +TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { + EXPECT_EQ("StreamableTemplateInFoo: 0", + Print(::foo::StreamableTemplateInFoo())); +} + +// Tests printing user-defined types that have a PrintTo() function. +TEST(PrintPrintableTypeTest, InUserNamespace) { + EXPECT_EQ("PrintableViaPrintTo: 0", + Print(::foo::PrintableViaPrintTo())); +} + +// Tests printing a pointer to a user-defined type that has a << +// operator for its pointer. +TEST(PrintPrintableTypeTest, PointerInUserNamespace) { + ::foo::PointerPrintable x; + EXPECT_EQ("PointerPrintable*", Print(&x)); +} + +// Tests printing user-defined class template that have a PrintTo() function. +TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { + EXPECT_EQ("PrintableViaPrintToTemplate: 5", + Print(::foo::PrintableViaPrintToTemplate(5))); +} + +#if GTEST_HAS_PROTOBUF_ + +// Tests printing a short proto2 message. +TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + ""); +} + +// Tests printing a long proto2 message. +TEST(PrintProto2MessageTest, PrintsDebugStringWhenItIsLong) { + testing::internal::FooMessage msg; + msg.set_int_field(2); + msg.set_string_field("hello"); + msg.add_names("peter"); + msg.add_names("paul"); + msg.add_names("mary"); + EXPECT_PRED2(RE::FullMatch, Print(msg), + "<\n" + "int_field:\\s*2\n" + "string_field:\\s*\"hello\"\n" + "names:\\s*\"peter\"\n" + "names:\\s*\"paul\"\n" + "names:\\s*\"mary\"\n" + ">"); +} + +#endif // GTEST_HAS_PROTOBUF_ + +// Tests that the universal printer prints both the address and the +// value of a reference. +TEST(PrintReferenceTest, PrintsAddressAndValue) { + int n = 5; + EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); + + int a[2][3] = { + { 0, 1, 2 }, + { 3, 4, 5 } + }; + EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", + PrintByRef(a)); + + const ::foo::UnprintableInFoo x; + EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " + "", + PrintByRef(x)); +} + +// Tests that the universal printer prints a function pointer passed by +// reference. +TEST(PrintReferenceTest, HandlesFunctionPointer) { + void (*fp)(int n) = &MyFunction; + const string fp_pointer_string = + PrintPointer(reinterpret_cast(&fp)); + // We cannot directly cast &MyFunction to const void* because the + // standard disallows casting between pointers to functions and + // pointers to objects, and some compilers (e.g. GCC 3.4) enforce + // this limitation. + const string fp_string = PrintPointer(reinterpret_cast( + reinterpret_cast(fp))); + EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, + PrintByRef(fp)); +} + +// Tests that the universal printer prints a member function pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { + int (Foo::*p)(char ch) = &Foo::MyMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(reinterpret_cast(&p)) + " " + + Print(sizeof(p)) + "-byte object ")); + + char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; + EXPECT_TRUE(HasPrefix( + PrintByRef(p2), + "@" + PrintPointer(reinterpret_cast(&p2)) + " " + + Print(sizeof(p2)) + "-byte object ")); +} + +// Tests that the universal printer prints a member variable pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberVariablePointer) { + int (Foo::*p) = &Foo::value; // NOLINT + EXPECT_TRUE(HasPrefix( + PrintByRef(p), + "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); +} + +// Tests that FormatForComparisonFailureMessage(), which is used to print +// an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion +// fails, formats the operand in the desired way. + +// scalar +TEST(FormatForComparisonFailureMessageTest, WorksForScalar) { + EXPECT_STREQ("123", + FormatForComparisonFailureMessage(123, 124).c_str()); +} + +// non-char pointer +TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) { + int n = 0; + EXPECT_EQ(PrintPointer(&n), + FormatForComparisonFailureMessage(&n, &n).c_str()); +} + +// non-char array +TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { + // In expression 'array == x', 'array' is compared by pointer. + // Therefore we want to print an array operand as a pointer. + int n[] = { 1, 2, 3 }; + EXPECT_EQ(PrintPointer(n), + FormatForComparisonFailureMessage(n, n).c_str()); +} + +// Tests formatting a char pointer when it's compared with another pointer. +// In this case we want to print it as a raw pointer, as the comparision is by +// pointer. + +// char pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a C string (we don't + // even know if it's supposed to point to a valid C string). + + // const char* + const char* s = "hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // char* + char ch = 'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// wchar_t pointer vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) { + // In expression 'p == x', where 'p' and 'x' are (const or not) char + // pointers, the operands are compared by pointer. Therefore we + // want to print 'p' as a pointer instead of a wide C string (we don't + // even know if it's supposed to point to a valid wide C string). + + // const wchar_t* + const wchar_t* s = L"hello"; + EXPECT_EQ(PrintPointer(s), + FormatForComparisonFailureMessage(s, s).c_str()); + + // wchar_t* + wchar_t ch = L'a'; + EXPECT_EQ(PrintPointer(&ch), + FormatForComparisonFailureMessage(&ch, &ch).c_str()); +} + +// Tests formatting a char pointer when it's compared to a string object. +// In this case we want to print the char pointer as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char pointer vs ::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::string()).c_str()); +} +#endif + +// char pointer vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) { + const char* s = "hello \"world"; + EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::string()).c_str()); + + // char* + char str[] = "hi\1"; + char* p = str; + EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t pointer vs ::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t pointer vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) { + const wchar_t* s = L"hi \"world"; + EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. + FormatForComparisonFailureMessage(s, ::std::wstring()).c_str()); + + // wchar_t* + wchar_t str[] = L"hi\1"; + wchar_t* p = str; + EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. + FormatForComparisonFailureMessage(p, ::std::wstring()).c_str()); +} +#endif + +// Tests formatting a char array when it's compared with a pointer or array. +// In this case we want to print the array as a row pointer, as the comparison +// is by pointer. + +// char array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) { + char str[] = "hi \"world\""; + char* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// char array vs char array +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) { + const char str[] = "hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// wchar_t array vs pointer +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) { + wchar_t str[] = L"hi \"world\""; + wchar_t* p = NULL; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, p).c_str()); +} + +// wchar_t array vs wchar_t array +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_EQ(PrintPointer(str), + FormatForComparisonFailureMessage(str, str).c_str()); +} + +// Tests formatting a char array when it's compared with a string object. +// In this case we want to print the array as a C string. + +#if GTEST_HAS_GLOBAL_STRING +// char array vs string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsString) { + const char str[] = "hi \"w\0rld\""; + EXPECT_STREQ("\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::string()).c_str()); +} +#endif + +// char array vs std::string +TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) { + const char str[] = "hi \"world\""; + EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::std::string()).c_str()); +} + +#if GTEST_HAS_GLOBAL_WSTRING +// wchar_t array vs wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWString) { + const wchar_t str[] = L"hi \"world\""; + EXPECT_STREQ("L\"hi \\\"world\\\"\"", // The content should be escaped. + FormatForComparisonFailureMessage(str, ::wstring()).c_str()); +} +#endif + +#if GTEST_HAS_STD_WSTRING +// wchar_t array vs std::wstring +TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) { + const wchar_t str[] = L"hi \"w\0rld\""; + EXPECT_STREQ( + "L\"hi \\\"w\"", // The content should be escaped. + // Embedded NUL terminates the string. + FormatForComparisonFailureMessage(str, ::std::wstring()).c_str()); +} +#endif + +// Useful for testing PrintToString(). We cannot use EXPECT_EQ() +// there as its implementation uses PrintToString(). The caller must +// ensure that 'value' has no side effect. +#define EXPECT_PRINT_TO_STRING_(value, expected_string) \ + EXPECT_TRUE(PrintToString(value) == (expected_string)) \ + << " where " #value " prints as " << (PrintToString(value)) + +TEST(PrintToStringTest, WorksForScalar) { + EXPECT_PRINT_TO_STRING_(123, "123"); +} + +TEST(PrintToStringTest, WorksForPointerToConstChar) { + const char* p = "hello"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForPointerToNonConstChar) { + char s[] = "hello"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\""); +} + +TEST(PrintToStringTest, EscapesForPointerToConstChar) { + const char* p = "hello\n"; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\""); +} + +TEST(PrintToStringTest, EscapesForPointerToNonConstChar) { + char s[] = "hello\1"; + char* p = s; + EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\""); +} + +TEST(PrintToStringTest, WorksForArray) { + int n[3] = { 1, 2, 3 }; + EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); +} + +TEST(PrintToStringTest, WorksForCharArray) { + char s[] = "hello"; + EXPECT_PRINT_TO_STRING_(s, "\"hello\""); +} + +TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { + const char str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\""); + + char mutable_str_with_nul[] = "hello\0 world"; + EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); +} + +#undef EXPECT_PRINT_TO_STRING_ + +TEST(UniversalTersePrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalTersePrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalTersePrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalTersePrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalTersePrint(s1, &ss1); + EXPECT_EQ("\"abc\"", ss1.str()); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalTersePrint(s2, &ss2); + EXPECT_EQ("\"abc\"", ss2.str()); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalTersePrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForNonReference) { + ::std::stringstream ss; + UniversalPrint(123, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForReference) { + const int& n = 123; + ::std::stringstream ss; + UniversalPrint(n, &ss); + EXPECT_EQ("123", ss.str()); +} + +TEST(UniversalPrintTest, WorksForCString) { + const char* s1 = "abc"; + ::std::stringstream ss1; + UniversalPrint(s1, &ss1); + EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", string(ss1.str())); + + char* s2 = const_cast(s1); + ::std::stringstream ss2; + UniversalPrint(s2, &ss2); + EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", string(ss2.str())); + + const char* s3 = NULL; + ::std::stringstream ss3; + UniversalPrint(s3, &ss3); + EXPECT_EQ("NULL", ss3.str()); +} + +TEST(UniversalPrintTest, WorksForCharArray) { + const char str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss1; + UniversalPrint(str, &ss1); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); + + const char mutable_str[] = "\"Line\0 1\"\nLine 2"; + ::std::stringstream ss2; + UniversalPrint(mutable_str, &ss2); + EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); +} + +#if GTEST_HAS_TR1_TUPLE + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tr1::make_tuple()); + EXPECT_EQ(0u, result.size()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tr1::make_tuple(1)); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ("1", result[0]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tr1::make_tuple(1, 'a')); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("'a' (97, 0x61)", result[1]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsTersely) { + const int n = 1; + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tr1::tuple(n, "a")); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("\"a\"", result[1]); +} + +#endif // GTEST_HAS_TR1_TUPLE + +#if GTEST_HAS_STD_TUPLE_ + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); + EXPECT_EQ(0u, result.size()); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsOneTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::make_tuple(1)); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ("1", result[0]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTwoTuple) { + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::make_tuple(1, 'a')); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("'a' (97, 0x61)", result[1]); +} + +TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { + const int n = 1; + Strings result = UniversalTersePrintTupleFieldsToStrings( + ::std::tuple(n, "a")); + ASSERT_EQ(2u, result.size()); + EXPECT_EQ("1", result[0]); + EXPECT_EQ("\"a\"", result[1]); +} + +#endif // GTEST_HAS_STD_TUPLE_ + +} // namespace gtest_printers_test +} // namespace testing + diff --git a/src/test/gtest/test/gtest-test-part_test.cc b/src/test/gtest/test/gtest-test-part_test.cc new file mode 100644 index 00000000..ca8ba933 --- /dev/null +++ b/src/test/gtest/test/gtest-test-part_test.cc @@ -0,0 +1,208 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: mheule@google.com (Markus Heule) +// + +#include "gtest/gtest-test-part.h" + +#include "gtest/gtest.h" + +using testing::Message; +using testing::Test; +using testing::TestPartResult; +using testing::TestPartResultArray; + +namespace { + +// Tests the TestPartResult class. + +// The test fixture for testing TestPartResult. +class TestPartResultTest : public Test { + protected: + TestPartResultTest() + : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"), + r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"), + r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {} + + TestPartResult r1_, r2_, r3_; +}; + + +TEST_F(TestPartResultTest, ConstructorWorks) { + Message message; + message << "something is terribly wrong"; + message << static_cast(testing::internal::kStackTraceMarker); + message << "some unimportant stack trace"; + + const TestPartResult result(TestPartResult::kNonFatalFailure, + "some_file.cc", + 42, + message.GetString().c_str()); + + EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); + EXPECT_STREQ("some_file.cc", result.file_name()); + EXPECT_EQ(42, result.line_number()); + EXPECT_STREQ(message.GetString().c_str(), result.message()); + EXPECT_STREQ("something is terribly wrong", result.summary()); +} + +TEST_F(TestPartResultTest, ResultAccessorsWork) { + const TestPartResult success(TestPartResult::kSuccess, + "file.cc", + 42, + "message"); + EXPECT_TRUE(success.passed()); + EXPECT_FALSE(success.failed()); + EXPECT_FALSE(success.nonfatally_failed()); + EXPECT_FALSE(success.fatally_failed()); + + const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(nonfatal_failure.passed()); + EXPECT_TRUE(nonfatal_failure.failed()); + EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); + EXPECT_FALSE(nonfatal_failure.fatally_failed()); + + const TestPartResult fatal_failure(TestPartResult::kFatalFailure, + "file.cc", + 42, + "message"); + EXPECT_FALSE(fatal_failure.passed()); + EXPECT_TRUE(fatal_failure.failed()); + EXPECT_FALSE(fatal_failure.nonfatally_failed()); + EXPECT_TRUE(fatal_failure.fatally_failed()); +} + +// Tests TestPartResult::type(). +TEST_F(TestPartResultTest, type) { + EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type()); + EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type()); +} + +// Tests TestPartResult::file_name(). +TEST_F(TestPartResultTest, file_name) { + EXPECT_STREQ("foo/bar.cc", r1_.file_name()); + EXPECT_STREQ(NULL, r3_.file_name()); +} + +// Tests TestPartResult::line_number(). +TEST_F(TestPartResultTest, line_number) { + EXPECT_EQ(10, r1_.line_number()); + EXPECT_EQ(-1, r2_.line_number()); +} + +// Tests TestPartResult::message(). +TEST_F(TestPartResultTest, message) { + EXPECT_STREQ("Success!", r1_.message()); +} + +// Tests TestPartResult::passed(). +TEST_F(TestPartResultTest, Passed) { + EXPECT_TRUE(r1_.passed()); + EXPECT_FALSE(r2_.passed()); + EXPECT_FALSE(r3_.passed()); +} + +// Tests TestPartResult::failed(). +TEST_F(TestPartResultTest, Failed) { + EXPECT_FALSE(r1_.failed()); + EXPECT_TRUE(r2_.failed()); + EXPECT_TRUE(r3_.failed()); +} + +// Tests TestPartResult::fatally_failed(). +TEST_F(TestPartResultTest, FatallyFailed) { + EXPECT_FALSE(r1_.fatally_failed()); + EXPECT_FALSE(r2_.fatally_failed()); + EXPECT_TRUE(r3_.fatally_failed()); +} + +// Tests TestPartResult::nonfatally_failed(). +TEST_F(TestPartResultTest, NonfatallyFailed) { + EXPECT_FALSE(r1_.nonfatally_failed()); + EXPECT_TRUE(r2_.nonfatally_failed()); + EXPECT_FALSE(r3_.nonfatally_failed()); +} + +// Tests the TestPartResultArray class. + +class TestPartResultArrayTest : public Test { + protected: + TestPartResultArrayTest() + : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"), + r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {} + + const TestPartResult r1_, r2_; +}; + +// Tests that TestPartResultArray initially has size 0. +TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { + TestPartResultArray results; + EXPECT_EQ(0, results.size()); +} + +// Tests that TestPartResultArray contains the given TestPartResult +// after one Append() operation. +TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { + TestPartResultArray results; + results.Append(r1_); + EXPECT_EQ(1, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); +} + +// Tests that TestPartResultArray contains the given TestPartResults +// after two Append() operations. +TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { + TestPartResultArray results; + results.Append(r1_); + results.Append(r2_); + EXPECT_EQ(2, results.size()); + EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); + EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); +} + +typedef TestPartResultArrayTest TestPartResultArrayDeathTest; + +// Tests that the program dies when GetTestPartResult() is called with +// an invalid index. +TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { + TestPartResultArray results; + results.Append(r1_); + + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), ""); +} + +// TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper. + +} // namespace diff --git a/src/test/gtest/test/gtest-tuple_test.cc b/src/test/gtest/test/gtest-tuple_test.cc new file mode 100644 index 00000000..bfaa3e0a --- /dev/null +++ b/src/test/gtest/test/gtest-tuple_test.cc @@ -0,0 +1,320 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/internal/gtest-tuple.h" +#include +#include "gtest/gtest.h" + +namespace { + +using ::std::tr1::get; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +using ::std::tr1::tuple_element; +using ::std::tr1::tuple_size; +using ::testing::StaticAssertTypeEq; + +// Tests that tuple_element >::type returns TK. +TEST(tuple_element_Test, ReturnsElementType) { + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); + StaticAssertTypeEq >::type>(); +} + +// Tests that tuple_size::value gives the number of fields in tuple +// type T. +TEST(tuple_size_Test, ReturnsNumberOfFields) { + EXPECT_EQ(0, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +tuple_size >::value); + EXPECT_EQ(1, +(tuple_size > >::value)); + EXPECT_EQ(2, +(tuple_size >::value)); + EXPECT_EQ(3, +(tuple_size >::value)); +} + +// Tests comparing a tuple with itself. +TEST(ComparisonTest, ComparesWithSelf) { + const tuple a(5, 'a', false); + + EXPECT_TRUE(a == a); + EXPECT_FALSE(a != a); +} + +// Tests comparing two tuples with the same value. +TEST(ComparisonTest, ComparesEqualTuples) { + const tuple a(5, true), b(5, true); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +// Tests comparing two different tuples that have no reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) { + typedef tuple FooTuple; + + const FooTuple a(0, 'x'); + const FooTuple b(1, 'a'); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + const FooTuple c(1, 'b'); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests comparing two different tuples that have reference fields. +TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) { + typedef tuple FooTuple; + + int i = 5; + const char ch = 'a'; + const FooTuple a(i, ch); + + int j = 6; + const FooTuple b(j, ch); + + EXPECT_TRUE(a != b); + EXPECT_FALSE(a == b); + + j = 5; + const char ch2 = 'b'; + const FooTuple c(j, ch2); + + EXPECT_TRUE(b != c); + EXPECT_FALSE(b == c); +} + +// Tests that a tuple field with a reference type is an alias of the +// variable it's supposed to reference. +TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { + int n = 0; + tuple t(true, n); + + n = 1; + EXPECT_EQ(n, get<1>(t)) + << "Changing a underlying variable should update the reference field."; + + // Makes sure that the implementation doesn't do anything funny with + // the & operator for the return type of get<>(). + EXPECT_EQ(&n, &(get<1>(t))) + << "The address of a reference field should equal the address of " + << "the underlying variable."; + + get<1>(t) = 2; + EXPECT_EQ(2, n) + << "Changing a reference field should update the underlying variable."; +} + +// Tests that tuple's default constructor default initializes each field. +// This test needs to compile without generating warnings. +TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) { + // The TR1 report requires that tuple's default constructor default + // initializes each field, even if it's a primitive type. If the + // implementation forgets to do this, this test will catch it by + // generating warnings about using uninitialized variables (assuming + // a decent compiler). + + tuple<> empty; + + tuple a1, b1; + b1 = a1; + EXPECT_EQ(0, get<0>(b1)); + + tuple a2, b2; + b2 = a2; + EXPECT_EQ(0, get<0>(b2)); + EXPECT_EQ(0.0, get<1>(b2)); + + tuple a3, b3; + b3 = a3; + EXPECT_EQ(0.0, get<0>(b3)); + EXPECT_EQ('\0', get<1>(b3)); + EXPECT_TRUE(get<2>(b3) == NULL); + + tuple a10, b10; + b10 = a10; + EXPECT_EQ(0, get<0>(b10)); + EXPECT_EQ(0, get<1>(b10)); + EXPECT_EQ(0, get<2>(b10)); + EXPECT_EQ(0, get<3>(b10)); + EXPECT_EQ(0, get<4>(b10)); + EXPECT_EQ(0, get<5>(b10)); + EXPECT_EQ(0, get<6>(b10)); + EXPECT_EQ(0, get<7>(b10)); + EXPECT_EQ(0, get<8>(b10)); + EXPECT_EQ(0, get<9>(b10)); +} + +// Tests constructing a tuple from its fields. +TEST(TupleConstructorTest, ConstructsFromFields) { + int n = 1; + // Reference field. + tuple a(n); + EXPECT_EQ(&n, &(get<0>(a))); + + // Non-reference fields. + tuple b(5, 'a'); + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ('a', get<1>(b)); + + // Const reference field. + const int m = 2; + tuple c(true, m); + EXPECT_TRUE(get<0>(c)); + EXPECT_EQ(&m, &(get<1>(c))); +} + +// Tests tuple's copy constructor. +TEST(TupleConstructorTest, CopyConstructor) { + tuple a(0.0, true); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_TRUE(get<1>(b)); +} + +// Tests constructing a tuple from another tuple that has a compatible +// but different type. +TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) { + tuple a(0, 1, 'a'); + tuple b(a); + + EXPECT_DOUBLE_EQ(0.0, get<0>(b)); + EXPECT_EQ(1, get<1>(b)); + EXPECT_EQ('a', get<2>(b)); +} + +// Tests constructing a 2-tuple from an std::pair. +TEST(TupleConstructorTest, ConstructsFromPair) { + ::std::pair a(1, 'a'); + tuple b(a); + tuple c(a); +} + +// Tests assigning a tuple to another tuple with the same type. +TEST(TupleAssignmentTest, AssignsToSameTupleType) { + const tuple a(5, 7L); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_EQ(7L, get<1>(b)); +} + +// Tests assigning a tuple to another tuple with a different but +// compatible type. +TEST(TupleAssignmentTest, AssignsToDifferentTupleType) { + const tuple a(1, 7L, true); + tuple b; + b = a; + EXPECT_EQ(1L, get<0>(b)); + EXPECT_EQ(7, get<1>(b)); + EXPECT_TRUE(get<2>(b)); +} + +// Tests assigning an std::pair to a 2-tuple. +TEST(TupleAssignmentTest, AssignsFromPair) { + const ::std::pair a(5, true); + tuple b; + b = a; + EXPECT_EQ(5, get<0>(b)); + EXPECT_TRUE(get<1>(b)); + + tuple c; + c = a; + EXPECT_EQ(5L, get<0>(c)); + EXPECT_TRUE(get<1>(c)); +} + +// A fixture for testing big tuples. +class BigTupleTest : public testing::Test { + protected: + typedef tuple BigTuple; + + BigTupleTest() : + a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2), + b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {} + + BigTuple a_, b_; +}; + +// Tests constructing big tuples. +TEST_F(BigTupleTest, Construction) { + BigTuple a; + BigTuple b(b_); +} + +// Tests that get(t) returns the N-th (0-based) field of tuple t. +TEST_F(BigTupleTest, get) { + EXPECT_EQ(1, get<0>(a_)); + EXPECT_EQ(2, get<9>(a_)); + + // Tests that get() works on a const tuple too. + const BigTuple a(a_); + EXPECT_EQ(1, get<0>(a)); + EXPECT_EQ(2, get<9>(a)); +} + +// Tests comparing big tuples. +TEST_F(BigTupleTest, Comparisons) { + EXPECT_TRUE(a_ == a_); + EXPECT_FALSE(a_ != a_); + + EXPECT_TRUE(a_ != b_); + EXPECT_FALSE(a_ == b_); +} + +TEST(MakeTupleTest, WorksForScalarTypes) { + tuple a; + a = make_tuple(true, 5); + EXPECT_TRUE(get<0>(a)); + EXPECT_EQ(5, get<1>(a)); + + tuple b; + b = make_tuple('a', 'b', 5); + EXPECT_EQ('a', get<0>(b)); + EXPECT_EQ('b', get<1>(b)); + EXPECT_EQ(5, get<2>(b)); +} + +TEST(MakeTupleTest, WorksForPointers) { + int a[] = { 1, 2, 3, 4 }; + const char* const str = "hi"; + int* const p = a; + + tuple t; + t = make_tuple(str, p); + EXPECT_EQ(str, get<0>(t)); + EXPECT_EQ(p, get<1>(t)); +} + +} // namespace diff --git a/src/test/gtest/test/gtest-typed-test2_test.cc b/src/test/gtest/test/gtest-typed-test2_test.cc new file mode 100644 index 00000000..c284700b --- /dev/null +++ b/src/test/gtest/test/gtest-typed-test2_test.cc @@ -0,0 +1,45 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include + +#include "test/gtest-typed-test_test.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest, + testing::Types >); + +#endif // GTEST_HAS_TYPED_TEST_P diff --git a/src/test/gtest/test/gtest-typed-test_test.cc b/src/test/gtest/test/gtest-typed-test_test.cc new file mode 100644 index 00000000..c3e66c2d --- /dev/null +++ b/src/test/gtest/test/gtest-typed-test_test.cc @@ -0,0 +1,361 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "test/gtest-typed-test_test.h" + +#include +#include + +#include "gtest/gtest.h" + +using testing::Test; + +// Used for testing that SetUpTestCase()/TearDownTestCase(), fixture +// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and +// type-parameterized test. +template +class CommonTest : public Test { + // For some technical reason, SetUpTestCase() and TearDownTestCase() + // must be public. + public: + static void SetUpTestCase() { + shared_ = new T(5); + } + + static void TearDownTestCase() { + delete shared_; + shared_ = NULL; + } + + // This 'protected:' is optional. There's no harm in making all + // members of this fixture class template public. + protected: + // We used to use std::list here, but switched to std::vector since + // MSVC's doesn't compile cleanly with /W4. + typedef std::vector Vector; + typedef std::set IntSet; + + CommonTest() : value_(1) {} + + virtual ~CommonTest() { EXPECT_EQ(3, value_); } + + virtual void SetUp() { + EXPECT_EQ(1, value_); + value_++; + } + + virtual void TearDown() { + EXPECT_EQ(2, value_); + value_++; + } + + T value_; + static T* shared_; +}; + +template +T* CommonTest::shared_ = NULL; + +// This #ifdef block tests typed tests. +#if GTEST_HAS_TYPED_TEST + +using testing::Types; + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in typed tests + +typedef Types TwoTypes; +TYPED_TEST_CASE(CommonTest, TwoTypes); + +TYPED_TEST(CommonTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Typedefs in the fixture class template can be visited via the + // "typename TestFixture::" prefix. + typename TestFixture::Vector empty; + EXPECT_EQ(0U, empty.size()); + + typename TestFixture::IntSet empty2; + EXPECT_EQ(0U, empty2.size()); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST(CommonTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + + // TypeParam can be used to refer to the type parameter. + EXPECT_EQ(static_cast(2), this->value_); +} + +// Tests that multiple TYPED_TEST_CASE's can be defined in the same +// translation unit. + +template +class TypedTest1 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// single type. +TYPED_TEST_CASE(TypedTest1, int); +TYPED_TEST(TypedTest1, A) {} + +template +class TypedTest2 : public Test { +}; + +// Verifies that the second argument of TYPED_TEST_CASE can be a +// Types<...> type list. +TYPED_TEST_CASE(TypedTest2, Types); + +// This also verifies that tests from different typed test cases can +// share the same name. +TYPED_TEST(TypedTest2, A) {} + +// Tests that a typed test case can be defined in a namespace. + +namespace library1 { + +template +class NumericTest : public Test { +}; + +typedef Types NumericTypes; +TYPED_TEST_CASE(NumericTest, NumericTypes); + +TYPED_TEST(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +} // namespace library1 + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +using testing::Types; +using testing::internal::TypedTestCasePState; + +// Tests TypedTestCasePState. + +class TypedTestCasePStateTest : public Test { + protected: + virtual void SetUp() { + state_.AddTestName("foo.cc", 0, "FooTest", "A"); + state_.AddTestName("foo.cc", 0, "FooTest", "B"); + state_.AddTestName("foo.cc", 0, "FooTest", "C"); + } + + TypedTestCasePState state_; +}; + +TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) { + const char* tests = "A, B, C"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +// Makes sure that the order of the tests and spaces around the names +// don't matter. +TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { + const char* tests = "A,C, B"; + EXPECT_EQ(tests, + state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); +} + +typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; + +TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), + "foo\\.cc.1.?: Test A is listed more than once\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), + "foo\\.cc.1.?: No test named D can be found in this test case\\."); +} + +TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { + EXPECT_DEATH_IF_SUPPORTED( + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), + "foo\\.cc.1.?: You forgot to list test B\\."); +} + +// Tests that defining a test for a parameterized test case generates +// a run-time error if the test case has been registered. +TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { + state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); + EXPECT_DEATH_IF_SUPPORTED( + state_.AddTestName("foo.cc", 2, "FooTest", "D"), + "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" + "\\(FooTest, \\.\\.\\.\\)\\."); +} + +// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, +// and SetUp()/TearDown() work correctly in type-parameterized tests. + +template +class DerivedTest : public CommonTest { +}; + +TYPED_TEST_CASE_P(DerivedTest); + +TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { + // Static members of the fixture class template can be visited via + // the TestFixture:: prefix. + EXPECT_EQ(5, *TestFixture::shared_); + + // Non-static members of the fixture class must be visited via + // 'this', as required by C++ for class templates. + EXPECT_EQ(2, this->value_); +} + +// The second test makes sure shared_ is not deleted after the first +// test. +TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { + // Static members of the fixture class template can also be visited + // via 'this'. + ASSERT_TRUE(this->shared_ != NULL); + EXPECT_EQ(5, *this->shared_); + EXPECT_EQ(2, this->value_); +} + +REGISTER_TYPED_TEST_CASE_P(DerivedTest, + ValuesAreCorrect, ValuesAreStillCorrect); + +typedef Types MyTwoTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes); + +// Tests that multiple TYPED_TEST_CASE_P's can be defined in the same +// translation unit. + +template +class TypedTestP1 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP1); + +// For testing that the code between TYPED_TEST_CASE_P() and +// TYPED_TEST_P() is not enclosed in a namespace. +typedef int IntAfterTypedTestCaseP; + +TYPED_TEST_P(TypedTestP1, A) {} +TYPED_TEST_P(TypedTestP1, B) {} + +// For testing that the code between TYPED_TEST_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +typedef int IntBeforeRegisterTypedTestCaseP; + +REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B); + +template +class TypedTestP2 : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP2); + +// This also verifies that tests from different type-parameterized +// test cases can share the same name. +TYPED_TEST_P(TypedTestP2, A) {} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A); + +// Verifies that the code between TYPED_TEST_CASE_P() and +// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. +IntAfterTypedTestCaseP after = 0; +IntBeforeRegisterTypedTestCaseP before = 0; + +// Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P() +// can be either a single type or a Types<...> type list. +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int); +INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated more than once in the same translation unit. +INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types); + +// Tests that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// (ContainerTest is also instantiated in gtest-typed-test_test.cc.) +typedef Types, std::set > MyContainers; +INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); + +// Tests that a type-parameterized test case can be defined and +// instantiated in a namespace. + +namespace library2 { + +template +class NumericTest : public Test { +}; + +TYPED_TEST_CASE_P(NumericTest); + +TYPED_TEST_P(NumericTest, DefaultIsZero) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { + EXPECT_LT(TypeParam(0), TypeParam(1)); +} + +REGISTER_TYPED_TEST_CASE_P(NumericTest, + DefaultIsZero, ZeroIsLessThanOne); +typedef Types NumericTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); + +} // namespace library2 + +#endif // GTEST_HAS_TYPED_TEST_P + +#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) + +// Google Test may not support type-parameterized tests with some +// compilers. If we use conditional compilation to compile out all +// code referring to the gtest_main library, MSVC linker will not link +// that library at all and consequently complain about missing entry +// point defined in that library (fatal error LNK1561: entry point +// must be defined). This dummy test keeps gtest_main linked in. +TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} + +#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) diff --git a/src/test/gtest/test/gtest-typed-test_test.h b/src/test/gtest/test/gtest-typed-test_test.h new file mode 100644 index 00000000..41d75704 --- /dev/null +++ b/src/test/gtest/test/gtest-typed-test_test.h @@ -0,0 +1,66 @@ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ +#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ + +#include "gtest/gtest.h" + +#if GTEST_HAS_TYPED_TEST_P + +using testing::Test; + +// For testing that the same type-parameterized test case can be +// instantiated in different translation units linked together. +// ContainerTest will be instantiated in both gtest-typed-test_test.cc +// and gtest-typed-test2_test.cc. + +template +class ContainerTest : public Test { +}; + +TYPED_TEST_CASE_P(ContainerTest); + +TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { + TypeParam container; +} + +TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { + TypeParam container; + EXPECT_EQ(0U, container.size()); +} + +REGISTER_TYPED_TEST_CASE_P(ContainerTest, + CanBeDefaultConstructed, InitialSizeIsZero); + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ diff --git a/src/test/gtest/test/gtest-unittest-api_test.cc b/src/test/gtest/test/gtest-unittest-api_test.cc new file mode 100644 index 00000000..b1f51688 --- /dev/null +++ b/src/test/gtest/test/gtest-unittest-api_test.cc @@ -0,0 +1,341 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file contains tests verifying correctness of data provided via +// UnitTest's public methods. + +#include "gtest/gtest.h" + +#include // For strcmp. +#include + +using ::testing::InitGoogleTest; + +namespace testing { +namespace internal { + +template +struct LessByName { + bool operator()(const T* a, const T* b) { + return strcmp(a->name(), b->name()) < 0; + } +}; + +class UnitTestHelper { + public: + // Returns the array of pointers to all test cases sorted by the test case + // name. The caller is responsible for deleting the array. + static TestCase const** GetSortedTestCases() { + UnitTest& unit_test = *UnitTest::GetInstance(); + TestCase const** const test_cases = + new const TestCase*[unit_test.total_test_case_count()]; + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + test_cases[i] = unit_test.GetTestCase(i); + + std::sort(test_cases, + test_cases + unit_test.total_test_case_count(), + LessByName()); + return test_cases; + } + + // Returns the test case by its name. The caller doesn't own the returned + // pointer. + static const TestCase* FindTestCase(const char* name) { + UnitTest& unit_test = *UnitTest::GetInstance(); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase* test_case = unit_test.GetTestCase(i); + if (0 == strcmp(test_case->name(), name)) + return test_case; + } + return NULL; + } + + // Returns the array of pointers to all tests in a particular test case + // sorted by the test name. The caller is responsible for deleting the + // array. + static TestInfo const** GetSortedTests(const TestCase* test_case) { + TestInfo const** const tests = + new const TestInfo*[test_case->total_test_count()]; + + for (int i = 0; i < test_case->total_test_count(); ++i) + tests[i] = test_case->GetTestInfo(i); + + std::sort(tests, tests + test_case->total_test_count(), + LessByName()); + return tests; + } +}; + +#if GTEST_HAS_TYPED_TEST +template class TestCaseWithCommentTest : public Test {}; +TYPED_TEST_CASE(TestCaseWithCommentTest, Types); +TYPED_TEST(TestCaseWithCommentTest, Dummy) {} + +const int kTypedTestCases = 1; +const int kTypedTests = 1; +#else +const int kTypedTestCases = 0; +const int kTypedTests = 0; +#endif // GTEST_HAS_TYPED_TEST + +// We can only test the accessors that do not change value while tests run. +// Since tests can be run in any order, the values the accessors that track +// test execution (such as failed_test_count) can not be predicted. +TEST(ApiTest, UnitTestImmutableAccessorsWork) { + UnitTest* unit_test = UnitTest::GetInstance(); + + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + EXPECT_EQ(1 + kTypedTestCases, unit_test->test_case_to_run_count()); + EXPECT_EQ(2, unit_test->disabled_test_count()); + EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); + + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); +#endif // GTEST_HAS_TYPED_TEST + + delete[] test_cases; + + // The following lines initiate actions to verify certain methods in + // FinalSuccessChecker::TearDown. + + // Records a test property to verify TestResult::GetTestProperty(). + RecordProperty("key", "value"); +} + +AssertionResult IsNull(const char* str) { + if (str != NULL) { + return testing::AssertionFailure() << "argument is " << str; + } + return AssertionSuccess(); +} + +TEST(ApiTest, TestCaseImmutableAccessorsWork) { + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("ApiTest", test_case->name()); + EXPECT_TRUE(IsNull(test_case->type_param())); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(3, test_case->test_to_run_count()); + ASSERT_EQ(4, test_case->total_test_count()); + + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_TRUE(IsNull(tests[0]->type_param())); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + + delete[] tests; + tests = NULL; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_case->type_param()); + EXPECT_TRUE(test_case->should_run()); + EXPECT_EQ(0, test_case->disabled_test_count()); + EXPECT_EQ(1, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST +} + +TEST(ApiTest, TestCaseDisabledAccessorsWork) { + const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test"); + ASSERT_TRUE(test_case != NULL); + + EXPECT_STREQ("DISABLED_Test", test_case->name()); + EXPECT_TRUE(IsNull(test_case->type_param())); + EXPECT_FALSE(test_case->should_run()); + EXPECT_EQ(1, test_case->disabled_test_count()); + EXPECT_EQ(0, test_case->test_to_run_count()); + ASSERT_EQ(1, test_case->total_test_count()); + + const TestInfo* const test_info = test_case->GetTestInfo(0); + EXPECT_STREQ("Dummy2", test_info->name()); + EXPECT_STREQ("DISABLED_Test", test_info->test_case_name()); + EXPECT_TRUE(IsNull(test_info->value_param())); + EXPECT_TRUE(IsNull(test_info->type_param())); + EXPECT_FALSE(test_info->should_run()); +} + +// These two tests are here to provide support for testing +// test_case_to_run_count, disabled_test_count, and test_to_run_count. +TEST(ApiTest, DISABLED_Dummy1) {} +TEST(DISABLED_Test, Dummy2) {} + +class FinalSuccessChecker : public Environment { + protected: + virtual void TearDown() { + UnitTest* unit_test = UnitTest::GetInstance(); + + EXPECT_EQ(1 + kTypedTestCases, unit_test->successful_test_case_count()); + EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count()); + EXPECT_EQ(0, unit_test->failed_test_case_count()); + EXPECT_EQ(0, unit_test->failed_test_count()); + EXPECT_TRUE(unit_test->Passed()); + EXPECT_FALSE(unit_test->Failed()); + ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); + + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); + + EXPECT_STREQ("ApiTest", test_cases[0]->name()); + EXPECT_TRUE(IsNull(test_cases[0]->type_param())); + EXPECT_TRUE(test_cases[0]->should_run()); + EXPECT_EQ(1, test_cases[0]->disabled_test_count()); + ASSERT_EQ(4, test_cases[0]->total_test_count()); + EXPECT_EQ(3, test_cases[0]->successful_test_count()); + EXPECT_EQ(0, test_cases[0]->failed_test_count()); + EXPECT_TRUE(test_cases[0]->Passed()); + EXPECT_FALSE(test_cases[0]->Failed()); + + EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); + EXPECT_TRUE(IsNull(test_cases[1]->type_param())); + EXPECT_FALSE(test_cases[1]->should_run()); + EXPECT_EQ(1, test_cases[1]->disabled_test_count()); + ASSERT_EQ(1, test_cases[1]->total_test_count()); + EXPECT_EQ(0, test_cases[1]->successful_test_count()); + EXPECT_EQ(0, test_cases[1]->failed_test_count()); + +#if GTEST_HAS_TYPED_TEST + EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); + EXPECT_STREQ(GetTypeName().c_str(), test_cases[2]->type_param()); + EXPECT_TRUE(test_cases[2]->should_run()); + EXPECT_EQ(0, test_cases[2]->disabled_test_count()); + ASSERT_EQ(1, test_cases[2]->total_test_count()); + EXPECT_EQ(1, test_cases[2]->successful_test_count()); + EXPECT_EQ(0, test_cases[2]->failed_test_count()); + EXPECT_TRUE(test_cases[2]->Passed()); + EXPECT_FALSE(test_cases[2]->Failed()); +#endif // GTEST_HAS_TYPED_TEST + + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); + EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); + EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); + EXPECT_FALSE(tests[0]->should_run()); + + EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); + EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); + EXPECT_TRUE(IsNull(tests[1]->value_param())); + EXPECT_TRUE(IsNull(tests[1]->type_param())); + EXPECT_TRUE(tests[1]->should_run()); + EXPECT_TRUE(tests[1]->result()->Passed()); + EXPECT_EQ(0, tests[1]->result()->test_property_count()); + + EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); + EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); + EXPECT_TRUE(IsNull(tests[2]->value_param())); + EXPECT_TRUE(IsNull(tests[2]->type_param())); + EXPECT_TRUE(tests[2]->should_run()); + EXPECT_TRUE(tests[2]->result()->Passed()); + EXPECT_EQ(0, tests[2]->result()->test_property_count()); + + EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); + EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); + EXPECT_TRUE(IsNull(tests[3]->value_param())); + EXPECT_TRUE(IsNull(tests[3]->type_param())); + EXPECT_TRUE(tests[3]->should_run()); + EXPECT_TRUE(tests[3]->result()->Passed()); + EXPECT_EQ(1, tests[3]->result()->test_property_count()); + const TestProperty& property = tests[3]->result()->GetTestProperty(0); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); + + delete[] tests; + +#if GTEST_HAS_TYPED_TEST + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + tests = UnitTestHelper::GetSortedTests(test_case); + + EXPECT_STREQ("Dummy", tests[0]->name()); + EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); + EXPECT_TRUE(IsNull(tests[0]->value_param())); + EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); + EXPECT_TRUE(tests[0]->should_run()); + EXPECT_TRUE(tests[0]->result()->Passed()); + EXPECT_EQ(0, tests[0]->result()->test_property_count()); + + delete[] tests; +#endif // GTEST_HAS_TYPED_TEST + delete[] test_cases; + } +}; + +} // namespace internal +} // namespace testing + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker()); + + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_all_test.cc b/src/test/gtest/test/gtest_all_test.cc new file mode 100644 index 00000000..955aa628 --- /dev/null +++ b/src/test/gtest/test/gtest_all_test.cc @@ -0,0 +1,47 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build most of Google Test's own tests +// by compiling a single file. This file serves this purpose. +#include "test/gtest-filepath_test.cc" +#include "test/gtest-linked_ptr_test.cc" +#include "test/gtest-message_test.cc" +#include "test/gtest-options_test.cc" +#include "test/gtest-port_test.cc" +#include "test/gtest_pred_impl_unittest.cc" +#include "test/gtest_prod_test.cc" +#include "test/gtest-test-part_test.cc" +#include "test/gtest-typed-test_test.cc" +#include "test/gtest-typed-test2_test.cc" +#include "test/gtest_unittest.cc" +#include "test/production.cc" diff --git a/src/test/gtest/test/gtest_break_on_failure_unittest.py b/src/test/gtest/test/gtest_break_on_failure_unittest.py new file mode 100755 index 00000000..78f3e0f5 --- /dev/null +++ b/src/test/gtest/test/gtest_break_on_failure_unittest.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Unit test for Google Test's break-on-failure mode. + +A user can ask Google Test to seg-fault when an assertion fails, using +either the GTEST_BREAK_ON_FAILURE environment variable or the +--gtest_break_on_failure flag. This script tests such functionality +by invoking gtest_break_on_failure_unittest_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils +import os +import sys + + +# Constants. + +IS_WINDOWS = os.name == 'nt' + +# The environment variable for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' + +# The command line flag for enabling/disabling the break-on-failure mode. +BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' + +# The environment variable for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' + +# The environment variable for enabling/disabling the catch-exceptions mode. +CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS' + +# Path to the gtest_break_on_failure_unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_break_on_failure_unittest_') + + +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + + +def Run(command): + """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" + + p = gtest_test_utils.Subprocess(command, env=environ) + if p.terminated_by_signal: + return 1 + else: + return 0 + + +# The tests. + + +class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable or + the --gtest_break_on_failure flag to turn assertion failures into + segmentation faults. + """ + + def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault): + """Runs gtest_break_on_failure_unittest_ and verifies that it does + (or does not) have a seg-fault. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + expect_seg_fault: 1 if the program is expected to generate a seg-fault; + 0 otherwise. + """ + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % BREAK_ON_FAILURE_FLAG + else: + flag = '--%s' % BREAK_ON_FAILURE_FLAG + + command = [EXE_PATH] + if flag: + command.append(flag) + + if expect_seg_fault: + should_or_not = 'should' + else: + should_or_not = 'should not' + + has_seg_fault = Run(command) + + SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % + (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(has_seg_fault == expect_seg_fault, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, + flag_value=None, + expect_seg_fault=0) + + def testEnvVar(self): + """Tests using the GTEST_BREAK_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value=None, + expect_seg_fault=1) + + def testFlag(self): + """Tests using the --gtest_break_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + + def testFlagOverridesEnvVar(self): + """Tests that the flag overrides the environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='0', + flag_value='1', + expect_seg_fault=1) + self.RunAndVerify(env_var_value='1', + flag_value='0', + expect_seg_fault=0) + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + + def testBreakOnFailureOverridesThrowOnFailure(self): + """Tests that gtest_break_on_failure overrides gtest_throw_on_failure.""" + + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value=None, + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) + + if IS_WINDOWS: + def testCatchExceptionsDoesNotInterfere(self): + """Tests that gtest_catch_exceptions doesn't interfere.""" + + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1') + try: + self.RunAndVerify(env_var_value='1', + flag_value='1', + expect_seg_fault=1) + finally: + SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_break_on_failure_unittest_.cc b/src/test/gtest/test/gtest_break_on_failure_unittest_.cc new file mode 100644 index 00000000..dd07478c --- /dev/null +++ b/src/test/gtest/test/gtest_break_on_failure_unittest_.cc @@ -0,0 +1,88 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Unit test for Google Test's break-on-failure mode. +// +// A user can ask Google Test to seg-fault when an assertion fails, using +// either the GTEST_BREAK_ON_FAILURE environment variable or the +// --gtest_break_on_failure flag. This file is used for testing such +// functionality. +// +// This program will be invoked from a Python unit test. It is +// expected to fail. Don't run it directly. + +#include "gtest/gtest.h" + +#if GTEST_OS_WINDOWS +# include +# include +#endif + +namespace { + +// A test that's expected to fail. +TEST(Foo, Bar) { + EXPECT_EQ(2, 3); +} + +#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE +// On Windows Mobile global exception handlers are not supported. +LONG WINAPI ExitWithExceptionCode( + struct _EXCEPTION_POINTERS* exception_pointers) { + exit(exception_pointers->ExceptionRecord->ExceptionCode); +} +#endif + +} // namespace + +int main(int argc, char **argv) { +#if GTEST_OS_WINDOWS + // Suppresses display of the Windows error dialog upon encountering + // a general protection fault (segment violation). + SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); + +# if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE + + // The default unhandled exception filter does not always exit + // with the exception code as exit code - for example it exits with + // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT + // if the application is compiled in debug mode. Thus we use our own + // filter which always exits with the exception code for unhandled + // exceptions. + SetUnhandledExceptionFilter(ExitWithExceptionCode); + +# endif +#endif + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_catch_exceptions_test.py b/src/test/gtest/test/gtest_catch_exceptions_test.py new file mode 100755 index 00000000..e6fc22fd --- /dev/null +++ b/src/test/gtest/test/gtest_catch_exceptions_test.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python +# +# Copyright 2010 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Tests Google Test's exception catching behavior. + +This script invokes gtest_catch_exceptions_test_ and +gtest_catch_exceptions_ex_test_ (programs written with +Google Test) and verifies their output. +""" + +__author__ = 'vladl@google.com (Vlad Losev)' + +import os + +import gtest_test_utils + +# Constants. +FLAG_PREFIX = '--gtest_' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' +FILTER_FLAG = FLAG_PREFIX + 'filter' + +# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with +# exceptions enabled. +EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_ex_test_') + +# Path to the gtest_catch_exceptions_test_ binary, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_catch_exceptions_no_ex_test_') + +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + +TEST_LIST = gtest_test_utils.Subprocess( + [EXE_PATH, LIST_TESTS_FLAG], env=environ).output + +SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST + +if SUPPORTS_SEH_EXCEPTIONS: + BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output + +EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( + [EX_EXE_PATH], env=environ).output + + +# The tests. +if SUPPORTS_SEH_EXCEPTIONS: + # pylint:disable-msg=C6302 + class CatchSehExceptionsTest(gtest_test_utils.TestCase): + """Tests exception-catching behavior.""" + + + def TestSehExceptions(self, test_output): + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s constructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown ' + 'in the test fixture\'s destructor' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in SetUp()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in TearDown()' + in test_output) + self.assert_('SEH exception with code 0x2a thrown in the test body' + in test_output) + + def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): + self.TestSehExceptions(EX_BINARY_OUTPUT) + + def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): + self.TestSehExceptions(BINARY_OUTPUT) + + +class CatchCxxExceptionsTest(gtest_test_utils.TestCase): + """Tests C++ exception-catching behavior. + + Tests in this test case verify that: + * C++ exceptions are caught and logged as C++ (not SEH) exceptions + * Exception thrown affect the remainder of the test work flow in the + expected manner. + """ + + def testCatchesCxxExceptionsInFixtureConstructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s constructor' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInConstructorTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in + EX_BINARY_OUTPUT): + + def testCatchesCxxExceptionsInFixtureDestructor(self): + self.assert_('C++ exception with description ' + '"Standard C++ exception" thrown ' + 'in the test fixture\'s destructor' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUpTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUpTestCase()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTestCaseTest test body ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTearDownTestCase(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDownTestCase()' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInSetUp(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in SetUp()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInSetUpTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('unexpected' not in EX_BINARY_OUTPUT, + 'This failure belongs in this test only if ' + '"CxxExceptionInSetUpTest" (no quotes) ' + 'appears on the same line as words "called unexpectedly"') + + def testCatchesCxxExceptionsInTearDown(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in TearDown()' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTearDownTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesCxxExceptionsInTestBody(self): + self.assert_('C++ exception with description "Standard C++ exception"' + ' thrown in the test body' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest destructor ' + 'called as expected.' + in EX_BINARY_OUTPUT) + self.assert_('CxxExceptionInTestBodyTest::TearDown() ' + 'called as expected.' + in EX_BINARY_OUTPUT) + + def testCatchesNonStdCxxExceptions(self): + self.assert_('Unknown C++ exception thrown in the test body' + in EX_BINARY_OUTPUT) + + def testUnhandledCxxExceptionsAbortTheProgram(self): + # Filters out SEH exception tests on Windows. Unhandled SEH exceptions + # cause tests to show pop-up windows there. + FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' + # By default, Google Test doesn't catch the exceptions. + uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( + [EX_EXE_PATH, + NO_CATCH_EXCEPTIONS_FLAG, + FITLER_OUT_SEH_TESTS_FLAG], + env=environ).output + + self.assert_('Unhandled C++ exception terminating the program' + in uncaught_exceptions_ex_binary_output) + self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_catch_exceptions_test_.cc b/src/test/gtest/test/gtest_catch_exceptions_test_.cc new file mode 100644 index 00000000..d0fc82c9 --- /dev/null +++ b/src/test/gtest/test/gtest_catch_exceptions_test_.cc @@ -0,0 +1,311 @@ +// Copyright 2010, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: vladl@google.com (Vlad Losev) +// +// Tests for Google Test itself. Tests in this file throw C++ or SEH +// exceptions, and the output is verified by gtest_catch_exceptions_test.py. + +#include "gtest/gtest.h" + +#include // NOLINT +#include // For exit(). + +#if GTEST_HAS_SEH +# include +#endif + +#if GTEST_HAS_EXCEPTIONS +# include // For set_terminate(). +# include +#endif + +using testing::Test; + +#if GTEST_HAS_SEH + +class SehExceptionInConstructorTest : public Test { + public: + SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} + +class SehExceptionInDestructorTest : public Test { + public: + ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} + +class SehExceptionInSetUpTestCaseTest : public Test { + public: + static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {} + +class SehExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class SehExceptionInSetUpTest : public Test { + protected: + virtual void SetUp() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} + +class SehExceptionInTearDownTest : public Test { + protected: + virtual void TearDown() { RaiseException(42, 0, 0, NULL); } +}; + +TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +TEST(SehExceptionTest, ThrowsSehException) { + RaiseException(42, 0, 0, NULL); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +class CxxExceptionInConstructorTest : public Test { + public: + CxxExceptionInConstructorTest() { + // Without this macro VC++ complains about unreachable code at the end of + // the constructor. + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInConstructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInConstructorTest() { + ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " + << "called unexpectedly."; + } + + virtual void SetUp() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " + << "called unexpectedly."; + } + + virtual void TearDown() { + ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " + << "called unexpectedly."; + } +}; + +TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { + ADD_FAILURE() << "CxxExceptionInConstructorTest test body " + << "called unexpectedly."; +} + +// Exceptions in destructors are not supported in C++11. +#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L +class CxxExceptionInDestructorTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInDestructorTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInDestructorTest() { + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + throw std::runtime_error("Standard C++ exception")); + } +}; + +TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} +#endif // C++11 mode + +class CxxExceptionInSetUpTestCaseTest : public Test { + public: + CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest constructor " + "called as expected.\n"); + } + + static void SetUpTestCase() { + throw std::runtime_error("Standard C++ exception"); + } + + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTestCaseTest() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::SetUp() " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTestCaseTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) { + printf("%s", + "CxxExceptionInSetUpTestCaseTest test body " + "called as expected.\n"); +} + +class CxxExceptionInTearDownTestCaseTest : public Test { + public: + static void TearDownTestCase() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} + +class CxxExceptionInSetUpTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInSetUpTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInSetUpTest() { + printf("%s", + "CxxExceptionInSetUpTest destructor " + "called as expected.\n"); + } + + virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInSetUpTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { + ADD_FAILURE() << "CxxExceptionInSetUpTest test body " + << "called unexpectedly."; +} + +class CxxExceptionInTearDownTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTearDownTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTearDownTest() { + printf("%s", + "CxxExceptionInTearDownTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + throw std::runtime_error("Standard C++ exception"); + } +}; + +TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} + +class CxxExceptionInTestBodyTest : public Test { + public: + static void TearDownTestCase() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDownTestCase() " + "called as expected.\n"); + } + + protected: + ~CxxExceptionInTestBodyTest() { + printf("%s", + "CxxExceptionInTestBodyTest destructor " + "called as expected.\n"); + } + + virtual void TearDown() { + printf("%s", + "CxxExceptionInTestBodyTest::TearDown() " + "called as expected.\n"); + } +}; + +TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { + throw std::runtime_error("Standard C++ exception"); +} + +TEST(CxxExceptionTest, ThrowsNonStdCxxException) { + throw "C-string"; +} + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(3); +} + +#endif // GTEST_HAS_EXCEPTIONS + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_color_test.py b/src/test/gtest/test/gtest_color_test.py new file mode 100755 index 00000000..d02a53ed --- /dev/null +++ b/src/test/gtest/test/gtest_color_test.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Verifies that Google Test correctly determines whether to use colors.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +IS_WINDOWS = os.name = 'nt' + +COLOR_ENV_VAR = 'GTEST_COLOR' +COLOR_FLAG = 'gtest_color' +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_') + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def UsesColor(term, color_env_var, color_flag): + """Runs gtest_color_test_ and returns its exit code.""" + + SetEnvVar('TERM', term) + SetEnvVar(COLOR_ENV_VAR, color_env_var) + + if color_flag is None: + args = [] + else: + args = ['--%s=%s' % (COLOR_FLAG, color_flag)] + p = gtest_test_utils.Subprocess([COMMAND] + args) + return not p.exited or p.exit_code + + +class GTestColorTest(gtest_test_utils.TestCase): + def testNoEnvVarNoFlag(self): + """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" + + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', None, None)) + self.assert_(not UsesColor('emacs', None, None)) + self.assert_(not UsesColor('xterm-mono', None, None)) + self.assert_(not UsesColor('unknown', None, None)) + self.assert_(not UsesColor(None, None, None)) + self.assert_(UsesColor('linux', None, None)) + self.assert_(UsesColor('cygwin', None, None)) + self.assert_(UsesColor('xterm', None, None)) + self.assert_(UsesColor('xterm-color', None, None)) + self.assert_(UsesColor('xterm-256color', None, None)) + + def testFlagOnly(self): + """Tests the case when there's --gtest_color but not GTEST_COLOR.""" + + self.assert_(not UsesColor('dumb', None, 'no')) + self.assert_(not UsesColor('xterm-color', None, 'no')) + if not IS_WINDOWS: + self.assert_(not UsesColor('emacs', None, 'auto')) + self.assert_(UsesColor('xterm', None, 'auto')) + self.assert_(UsesColor('dumb', None, 'yes')) + self.assert_(UsesColor('xterm', None, 'yes')) + + def testEnvVarOnly(self): + """Tests the case when there's GTEST_COLOR but not --gtest_color.""" + + self.assert_(not UsesColor('dumb', 'no', None)) + self.assert_(not UsesColor('xterm-color', 'no', None)) + if not IS_WINDOWS: + self.assert_(not UsesColor('dumb', 'auto', None)) + self.assert_(UsesColor('xterm-color', 'auto', None)) + self.assert_(UsesColor('dumb', 'yes', None)) + self.assert_(UsesColor('xterm-color', 'yes', None)) + + def testEnvVarAndFlag(self): + """Tests the case when there are both GTEST_COLOR and --gtest_color.""" + + self.assert_(not UsesColor('xterm-color', 'no', 'no')) + self.assert_(UsesColor('dumb', 'no', 'yes')) + self.assert_(UsesColor('xterm-color', 'no', 'auto')) + + def testAliasesOfYesAndNo(self): + """Tests using aliases in specifying --gtest_color.""" + + self.assert_(UsesColor('dumb', None, 'true')) + self.assert_(UsesColor('dumb', None, 'YES')) + self.assert_(UsesColor('dumb', None, 'T')) + self.assert_(UsesColor('dumb', None, '1')) + + self.assert_(not UsesColor('xterm', None, 'f')) + self.assert_(not UsesColor('xterm', None, 'false')) + self.assert_(not UsesColor('xterm', None, '0')) + self.assert_(not UsesColor('xterm', None, 'unknown')) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_color_test_.cc b/src/test/gtest/test/gtest_color_test_.cc new file mode 100644 index 00000000..f61ebb89 --- /dev/null +++ b/src/test/gtest/test/gtest_color_test_.cc @@ -0,0 +1,71 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// A helper program for testing how Google Test determines whether to use +// colors in the output. It prints "YES" and returns 1 if Google Test +// decides to use colors, and prints "NO" and returns 0 otherwise. + +#include + +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using testing::internal::ShouldUseColor; + +// The purpose of this is to ensure that the UnitTest singleton is +// created before main() is entered, and thus that ShouldUseColor() +// works the same way as in a real Google-Test-based test. We don't actual +// run the TEST itself. +TEST(GTestColorTest, Dummy) { +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (ShouldUseColor(true)) { + // Google Test decides to use colors in the output (assuming it + // goes to a TTY). + printf("YES\n"); + return 1; + } else { + // Google Test decides not to use colors in the output. + printf("NO\n"); + return 0; + } +} diff --git a/src/test/gtest/test/gtest_env_var_test.py b/src/test/gtest/test/gtest_env_var_test.py new file mode 100755 index 00000000..ac24337f --- /dev/null +++ b/src/test/gtest/test/gtest_env_var_test.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Verifies that Google Test correctly parses environment variables.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +IS_WINDOWS = os.name == 'nt' +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' + +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_') + +environ = os.environ.copy() + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def GetFlag(flag): + """Runs gtest_env_var_test_ and returns its output.""" + + args = [COMMAND] + if flag is not None: + args += [flag] + return gtest_test_utils.Subprocess(args, env=environ).output + + +def TestFlag(flag, test_val, default_val): + """Verifies that the given flag is affected by the corresponding env var.""" + + env_var = 'GTEST_' + flag.upper() + SetEnvVar(env_var, test_val) + AssertEq(test_val, GetFlag(flag)) + SetEnvVar(env_var, None) + AssertEq(default_val, GetFlag(flag)) + + +class GTestEnvVarTest(gtest_test_utils.TestCase): + def testEnvVarAffectsFlag(self): + """Tests that environment variable should affect the corresponding flag.""" + + TestFlag('break_on_failure', '1', '0') + TestFlag('color', 'yes', 'auto') + TestFlag('filter', 'FooTest.Bar', '*') + TestFlag('output', 'xml:tmp/foo.xml', '') + TestFlag('print_time', '0', '1') + TestFlag('repeat', '999', '1') + TestFlag('throw_on_failure', '1', '0') + TestFlag('death_test_style', 'threadsafe', 'fast') + TestFlag('catch_exceptions', '0', '1') + + if IS_LINUX: + TestFlag('death_test_use_fork', '1', '0') + TestFlag('stack_trace_depth', '0', '100') + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_env_var_test_.cc b/src/test/gtest/test/gtest_env_var_test_.cc new file mode 100644 index 00000000..539afc96 --- /dev/null +++ b/src/test/gtest/test/gtest_env_var_test_.cc @@ -0,0 +1,126 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// A helper program for testing that Google Test parses the environment +// variables correctly. + +#include "gtest/gtest.h" + +#include + +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +using ::std::cout; + +namespace testing { + +// The purpose of this is to make the test more realistic by ensuring +// that the UnitTest singleton is created before main() is entered. +// We don't actual run the TEST itself. +TEST(GTestEnvVarTest, Dummy) { +} + +void PrintFlag(const char* flag) { + if (strcmp(flag, "break_on_failure") == 0) { + cout << GTEST_FLAG(break_on_failure); + return; + } + + if (strcmp(flag, "catch_exceptions") == 0) { + cout << GTEST_FLAG(catch_exceptions); + return; + } + + if (strcmp(flag, "color") == 0) { + cout << GTEST_FLAG(color); + return; + } + + if (strcmp(flag, "death_test_style") == 0) { + cout << GTEST_FLAG(death_test_style); + return; + } + + if (strcmp(flag, "death_test_use_fork") == 0) { + cout << GTEST_FLAG(death_test_use_fork); + return; + } + + if (strcmp(flag, "filter") == 0) { + cout << GTEST_FLAG(filter); + return; + } + + if (strcmp(flag, "output") == 0) { + cout << GTEST_FLAG(output); + return; + } + + if (strcmp(flag, "print_time") == 0) { + cout << GTEST_FLAG(print_time); + return; + } + + if (strcmp(flag, "repeat") == 0) { + cout << GTEST_FLAG(repeat); + return; + } + + if (strcmp(flag, "stack_trace_depth") == 0) { + cout << GTEST_FLAG(stack_trace_depth); + return; + } + + if (strcmp(flag, "throw_on_failure") == 0) { + cout << GTEST_FLAG(throw_on_failure); + return; + } + + cout << "Invalid flag name " << flag + << ". Valid names are break_on_failure, color, filter, etc.\n"; + exit(1); +} + +} // namespace testing + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + if (argc != 2) { + cout << "Usage: gtest_env_var_test_ NAME_OF_FLAG\n"; + return 1; + } + + testing::PrintFlag(argv[1]); + return 0; +} diff --git a/src/test/gtest/test/gtest_environment_test.cc b/src/test/gtest/test/gtest_environment_test.cc new file mode 100644 index 00000000..3cff19e7 --- /dev/null +++ b/src/test/gtest/test/gtest_environment_test.cc @@ -0,0 +1,192 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests using global test environments. + +#include +#include +#include "gtest/gtest.h" + +#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include. +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +GTEST_DECLARE_string_(filter); +} + +namespace { + +enum FailureType { + NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE +}; + +// For testing using global test environments. +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() { Reset(); } + + // Depending on the value of failure_in_set_up_, SetUp() will + // generate a non-fatal failure, generate a fatal failure, or + // succeed. + virtual void SetUp() { + set_up_was_run_ = true; + + switch (failure_in_set_up_) { + case NON_FATAL_FAILURE: + ADD_FAILURE() << "Expected non-fatal failure in global set-up."; + break; + case FATAL_FAILURE: + FAIL() << "Expected fatal failure in global set-up."; + break; + default: + break; + } + } + + // Generates a non-fatal failure. + virtual void TearDown() { + tear_down_was_run_ = true; + ADD_FAILURE() << "Expected non-fatal failure in global tear-down."; + } + + // Resets the state of the environment s.t. it can be reused. + void Reset() { + failure_in_set_up_ = NO_FAILURE; + set_up_was_run_ = false; + tear_down_was_run_ = false; + } + + // We call this function to set the type of failure SetUp() should + // generate. + void set_failure_in_set_up(FailureType type) { + failure_in_set_up_ = type; + } + + // Was SetUp() run? + bool set_up_was_run() const { return set_up_was_run_; } + + // Was TearDown() run? + bool tear_down_was_run() const { return tear_down_was_run_; } + + private: + FailureType failure_in_set_up_; + bool set_up_was_run_; + bool tear_down_was_run_; +}; + +// Was the TEST run? +bool test_was_run; + +// The sole purpose of this TEST is to enable us to check whether it +// was run. +TEST(FooTest, Bar) { + test_was_run = true; +} + +// Prints the message and aborts the program if condition is false. +void Check(bool condition, const char* msg) { + if (!condition) { + printf("FAILED: %s\n", msg); + testing::internal::posix::Abort(); + } +} + +// Runs the tests. Return true iff successful. +// +// The 'failure' parameter specifies the type of failure that should +// be generated by the global set-up. +int RunAllTests(MyEnvironment* env, FailureType failure) { + env->Reset(); + env->set_failure_in_set_up(failure); + test_was_run = false; + testing::internal::GetUnitTestImpl()->ClearAdHocTestResult(); + return RUN_ALL_TESTS(); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // Registers a global test environment, and verifies that the + // registration function returns its argument. + MyEnvironment* const env = new MyEnvironment; + Check(testing::AddGlobalTestEnvironment(env) == env, + "AddGlobalTestEnvironment() should return its argument."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up is successful. + Check(RunAllTests(env, NO_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global tear-down " + "should generate a failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "failure"); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs the tests when the global + // set-up generates no fatal failure. + Check(RunAllTests(env, NON_FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as both the global set-up " + "and the global tear-down should generate a non-fatal failure."); + Check(test_was_run, + "The tests should run, as the global set-up should generate no " + "fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() runs no test when the global set-up + // generates a fatal failure. + Check(RunAllTests(env, FATAL_FAILURE) != 0, + "RUN_ALL_TESTS() should return non-zero, as the global set-up " + "should generate a fatal failure."); + Check(!test_was_run, + "The tests should not run, as the global set-up should generate " + "a fatal failure."); + Check(env->tear_down_was_run(), + "The global tear-down should run, as the global set-up was run."); + + // Verifies that RUN_ALL_TESTS() doesn't do global set-up or + // tear-down when there is no test to run. + testing::GTEST_FLAG(filter) = "-*"; + Check(RunAllTests(env, NO_FAILURE) == 0, + "RUN_ALL_TESTS() should return zero, as there is no test to run."); + Check(!env->set_up_was_run(), + "The global set-up should not run, as there is no test to run."); + Check(!env->tear_down_was_run(), + "The global tear-down should not run, " + "as the global set-up was not run."); + + printf("PASS\n"); + return 0; +} diff --git a/src/test/gtest/test/gtest_filter_unittest.py b/src/test/gtest/test/gtest_filter_unittest.py new file mode 100755 index 00000000..0d1a7700 --- /dev/null +++ b/src/test/gtest/test/gtest_filter_unittest.py @@ -0,0 +1,633 @@ +#!/usr/bin/env python +# +# Copyright 2005 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Unit test for Google Test test filters. + +A user can specify which test(s) in a Google Test program to run via either +the GTEST_FILTER environment variable or the --gtest_filter flag. +This script tests such functionality by invoking +gtest_filter_unittest_ (a program written with Google Test) with different +environments and command line flags. + +Note that test sharding may also influence which tests are filtered. Therefore, +we test that here also. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sets +import sys + +import gtest_test_utils + +# Constants. + +# Checks if this platform can pass empty environment variables to child +# processes. We set an env variable to an empty string and invoke a python +# script in a subprocess to print whether the variable is STILL in +# os.environ. We then use 'eval' to parse the child's output so that an +# exception is thrown if the input is anything other than 'True' nor 'False'. +os.environ['EMPTY_VAR'] = '' +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ']) +CAN_PASS_EMPTY_ENV = eval(child.output) + + +# Check if this platform can unset environment variables in child processes. +# We set an env variable to a non-empty string, unset it, and invoke +# a python script in a subprocess to print whether the variable +# is NO LONGER in os.environ. +# We use 'eval' to parse the child's output so that an exception +# is thrown if the input is neither 'True' nor 'False'. +os.environ['UNSET_VAR'] = 'X' +del os.environ['UNSET_VAR'] +child = gtest_test_utils.Subprocess( + [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ']) +CAN_UNSET_ENV = eval(child.output) + + +# Checks if we should test with an empty filter. This doesn't +# make sense on platforms that cannot pass empty env variables (Win32) +# and on platforms that cannot unset variables (since we cannot tell +# the difference between "" and NULL -- Borland and Solaris < 5.10) +CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV) + + +# The environment variable for specifying the test filters. +FILTER_ENV_VAR = 'GTEST_FILTER' + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' +SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' + +# The command line flag for specifying the test filters. +FILTER_FLAG = 'gtest_filter' + +# The command line flag for including disabled tests. +ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' + +# Command to run the gtest_filter_unittest_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_') + +# Regex for determining whether parameterized tests are enabled in the binary. +PARAM_TEST_REGEX = re.compile(r'/ParamTest') + +# Regex for parsing test case names from Google Test's output. +TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)') + +# Regex for parsing test names from Google Test's output. +TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)') + +# The command line flag to tell Google Test to output the list of tests it +# will run. +LIST_TESTS_FLAG = '--gtest_list_tests' + +# Indicates whether Google Test supports death tests. +SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess( + [COMMAND, LIST_TESTS_FLAG]).output + +# Full names of all tests in gtest_filter_unittests_. +PARAM_TESTS = [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestX/1', + 'SeqQ/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestY/1', + ] + +DISABLED_TESTS = [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ] + +if SUPPORTS_DEATH_TESTS: + DEATH_TESTS = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + ] +else: + DEATH_TESTS = [] + +# All the non-disabled tests. +ACTIVE_TESTS = [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS + +param_tests_present = None + +# Utilities. + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets the env variable to 'value'; unsets it when 'value' is None.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +def RunAndReturnOutput(args = None): + """Runs the test program and returns its output.""" + + return gtest_test_utils.Subprocess([COMMAND] + (args or []), + env=environ).output + + +def RunAndExtractTestList(args = None): + """Runs the test program and returns its exit code and a list of tests run.""" + + p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ) + tests_run = [] + test_case = '' + test = '' + for line in p.output.split('\n'): + match = TEST_CASE_REGEX.match(line) + if match is not None: + test_case = match.group(1) + else: + match = TEST_REGEX.match(line) + if match is not None: + test = match.group(1) + tests_run.append(test_case + '.' + test) + return (tests_run, p.exit_code) + + +def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): + """Runs the given function and arguments in a modified environment.""" + try: + original_env = environ.copy() + environ.update(extra_env) + return function(*args, **kwargs) + finally: + environ.clear() + environ.update(original_env) + + +def RunWithSharding(total_shards, shard_index, command): + """Runs a test program shard and returns exit code and a list of tests run.""" + + extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), + TOTAL_SHARDS_ENV_VAR: str(total_shards)} + return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command) + +# The unit test. + + +class GTestFilterUnitTest(gtest_test_utils.TestCase): + """Tests the env variable or the command line flag to filter tests.""" + + # Utilities. + + def AssertSetEqual(self, lhs, rhs): + """Asserts that two sets are equal.""" + + for elem in lhs: + self.assert_(elem in rhs, '%s in %s' % (elem, rhs)) + + for elem in rhs: + self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) + + def AssertPartitionIsValid(self, set_var, list_of_sets): + """Asserts that list_of_sets is a valid partition of set_var.""" + + full_partition = [] + for slice_var in list_of_sets: + full_partition.extend(slice_var) + self.assertEqual(len(set_var), len(full_partition)) + self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) + + def AdjustForParameterizedTests(self, tests_to_run): + """Adjust tests_to_run in case value parameterized tests are disabled.""" + + global param_tests_present + if not param_tests_present: + return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) + else: + return tests_to_run + + def RunAndVerify(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for a given filter.""" + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # First, tests using the environment variable. + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + tests_run = RunAndExtractTestList()[0] + SetEnvVar(FILTER_ENV_VAR, None) + self.AssertSetEqual(tests_run, tests_to_run) + # pylint: enable-msg=C6403 + + # Next, tests using the command line flag. + + if gtest_filter is None: + args = [] + else: + args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)] + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, + args=None, check_exit_0=False): + """Checks that binary runs correct tests for the given filter and shard. + + Runs all shards of gtest_filter_unittest_ with the given filter, and + verifies that the right set of tests were run. The union of tests run + on each shard should be identical to tests_to_run, without duplicates. + + Args: + gtest_filter: A filter to apply to the tests. + total_shards: A total number of shards to split test run into. + tests_to_run: A set of tests expected to run. + args : Arguments to pass to the to the test binary. + check_exit_0: When set to a true value, make sure that all shards + return 0. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Windows removes empty variables from the environment when passing it + # to a new process. This means it is impossible to pass an empty filter + # into a process using the environment variable. However, we can still + # test the case when the variable is not supplied (i.e., gtest_filter is + # None). + # pylint: disable-msg=C6403 + if CAN_TEST_EMPTY_FILTER or gtest_filter != '': + SetEnvVar(FILTER_ENV_VAR, gtest_filter) + partition = [] + for i in range(0, total_shards): + (tests_run, exit_code) = RunWithSharding(total_shards, i, args) + if check_exit_0: + self.assertEqual(0, exit_code) + partition.append(tests_run) + + self.AssertPartitionIsValid(tests_to_run, partition) + SetEnvVar(FILTER_ENV_VAR, None) + # pylint: enable-msg=C6403 + + def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): + """Checks that the binary runs correct set of tests for the given filter. + + Runs gtest_filter_unittest_ with the given filter, and enables + disabled tests. Verifies that the right set of tests were run. + + Args: + gtest_filter: A filter to apply to the tests. + tests_to_run: A set of tests expected to run. + """ + + tests_to_run = self.AdjustForParameterizedTests(tests_to_run) + + # Construct the command line. + args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG] + if gtest_filter is not None: + args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) + + tests_run = RunAndExtractTestList(args)[0] + self.AssertSetEqual(tests_run, tests_to_run) + + def setUp(self): + """Sets up test case. + + Determines whether value-parameterized tests are enabled in the binary and + sets the flags accordingly. + """ + + global param_tests_present + if param_tests_present is None: + param_tests_present = PARAM_TEST_REGEX.search( + RunAndReturnOutput()) is not None + + def testDefaultBehavior(self): + """Tests the behavior of not specifying the filter.""" + + self.RunAndVerify(None, ACTIVE_TESTS) + + def testDefaultBehaviorWithShards(self): + """Tests the behavior without the filter, with sharding enabled.""" + + self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS) + self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS) + + def testEmptyFilter(self): + """Tests an empty filter.""" + + self.RunAndVerify('', []) + self.RunAndVerifyWithSharding('', 1, []) + self.RunAndVerifyWithSharding('', 2, []) + + def testBadFilter(self): + """Tests a filter that matches nothing.""" + + self.RunAndVerify('BadFilter', []) + self.RunAndVerifyAllowingDisabled('BadFilter', []) + + def testFullName(self): + """Tests filtering by full name.""" + + self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz']) + self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz']) + + def testUniversalFilters(self): + """Tests filters that match everything.""" + + self.RunAndVerify('*', ACTIVE_TESTS) + self.RunAndVerify('*.*', ACTIVE_TESTS) + self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS) + self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS) + self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS) + + def testFilterByTestCase(self): + """Tests filtering by test case name.""" + + self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz']) + + BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB'] + self.RunAndVerify('BazTest.*', BAZ_TESTS) + self.RunAndVerifyAllowingDisabled('BazTest.*', + BAZ_TESTS + ['BazTest.DISABLED_TestC']) + + def testFilterByTest(self): + """Tests filtering by test name.""" + + self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne']) + + def testFilterDisabledTests(self): + """Select only the disabled tests to run.""" + + self.RunAndVerify('DISABLED_FoobarTest.Test1', []) + self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1', + ['DISABLED_FoobarTest.Test1']) + + self.RunAndVerify('*DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS) + + self.RunAndVerify('*.DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [ + 'BarTest.DISABLED_TestFour', + 'BarTest.DISABLED_TestFive', + 'BazTest.DISABLED_TestC', + 'DISABLED_FoobarTest.DISABLED_Test2', + ]) + + self.RunAndVerify('DISABLED_*', []) + self.RunAndVerifyAllowingDisabled('DISABLED_*', [ + 'DISABLED_FoobarTest.Test1', + 'DISABLED_FoobarTest.DISABLED_Test2', + 'DISABLED_FoobarbazTest.TestA', + ]) + + def testWildcardInTestCaseName(self): + """Tests using wildcard in the test case name.""" + + self.RunAndVerify('*a*.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS) + + def testWildcardInTestName(self): + """Tests using wildcard in the test name.""" + + self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testFilterWithoutDot(self): + """Tests a filter that has no '.' in it.""" + + self.RunAndVerify('*z*', [ + 'FooTest.Xyz', + + 'BazTest.TestOne', + 'BazTest.TestA', + 'BazTest.TestB', + ]) + + def testTwoPatterns(self): + """Tests filters that consist of two patterns.""" + + self.RunAndVerify('Foo*.*:*A*', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BazTest.TestA', + ]) + + # An empty pattern + a non-empty one + self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA']) + + def testThreePatterns(self): + """Tests filters that consist of three patterns.""" + + self.RunAndVerify('*oo*:*A*:*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + 'BazTest.TestA', + ]) + + # The 2nd pattern is empty. + self.RunAndVerify('*oo*::*One', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + + 'BazTest.TestOne', + ]) + + # The last 2 patterns are empty. + self.RunAndVerify('*oo*::', [ + 'FooTest.Abc', + 'FooTest.Xyz', + ]) + + def testNegativeFilters(self): + self.RunAndVerify('*-BazTest.TestOne', [ + 'FooTest.Abc', + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + + 'BazTest.TestA', + 'BazTest.TestB', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ + 'FooTest.Xyz', + + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + self.RunAndVerify('BarTest.*-BarTest.TestOne', [ + 'BarTest.TestTwo', + 'BarTest.TestThree', + ]) + + # Tests without leading '*'. + self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [ + 'BarTest.TestOne', + 'BarTest.TestTwo', + 'BarTest.TestThree', + ] + DEATH_TESTS + PARAM_TESTS) + + # Value parameterized tests. + self.RunAndVerify('*/*', PARAM_TESTS) + + # Value parameterized tests filtering by the sequence name. + self.RunAndVerify('SeqP/*', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ]) + + # Value parameterized tests filtering by the test name. + self.RunAndVerify('*/0', [ + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestY/0', + 'SeqQ/ParamTest.TestX/0', + 'SeqQ/ParamTest.TestY/0', + ]) + + def testFlagOverridesEnvVar(self): + """Tests that the filter flag overrides the filtering env. variable.""" + + SetEnvVar(FILTER_ENV_VAR, 'Foo*') + args = ['--%s=%s' % (FILTER_FLAG, '*One')] + tests_run = RunAndExtractTestList(args)[0] + SetEnvVar(FILTER_ENV_VAR, None) + + self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) + + def testShardStatusFileIsCreated(self): + """Tests that the shard file is created if specified in the environment.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + InvokeWithModifiedEnv(extra_env, RunAndReturnOutput) + finally: + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + def testShardStatusFileIsCreatedWithListTests(self): + """Tests that the shard file is created with the "list_tests" flag.""" + + shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), + 'shard_status_file2') + self.assert_(not os.path.exists(shard_status_file)) + + extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} + try: + output = InvokeWithModifiedEnv(extra_env, + RunAndReturnOutput, + [LIST_TESTS_FLAG]) + finally: + # This assertion ensures that Google Test enumerated the tests as + # opposed to running them. + self.assert_('[==========]' not in output, + 'Unexpected output during test enumeration.\n' + 'Please ensure that LIST_TESTS_FLAG is assigned the\n' + 'correct flag value for listing Google Test tests.') + + self.assert_(os.path.exists(shard_status_file)) + os.remove(shard_status_file) + + if SUPPORTS_DEATH_TESTS: + def testShardingWorksWithDeathTests(self): + """Tests integration with death tests and sharding.""" + + gtest_filter = 'HasDeathTest.*:SeqP/*' + expected_tests = [ + 'HasDeathTest.Test1', + 'HasDeathTest.Test2', + + 'SeqP/ParamTest.TestX/0', + 'SeqP/ParamTest.TestX/1', + 'SeqP/ParamTest.TestY/0', + 'SeqP/ParamTest.TestY/1', + ] + + for flag in ['--gtest_death_test_style=threadsafe', + '--gtest_death_test_style=fast']: + self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, + check_exit_0=True, args=[flag]) + self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, + check_exit_0=True, args=[flag]) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_filter_unittest_.cc b/src/test/gtest/test/gtest_filter_unittest_.cc new file mode 100644 index 00000000..77deffc3 --- /dev/null +++ b/src/test/gtest/test/gtest_filter_unittest_.cc @@ -0,0 +1,140 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Unit test for Google Test test filters. +// +// A user can specify which test(s) in a Google Test program to run via +// either the GTEST_FILTER environment variable or the --gtest_filter +// flag. This is used for testing such functionality. +// +// The program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +namespace { + +// Test case FooTest. + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Abc) { +} + +TEST_F(FooTest, Xyz) { + FAIL() << "Expected failure."; +} + +// Test case BarTest. + +TEST(BarTest, TestOne) { +} + +TEST(BarTest, TestTwo) { +} + +TEST(BarTest, TestThree) { +} + +TEST(BarTest, DISABLED_TestFour) { + FAIL() << "Expected failure."; +} + +TEST(BarTest, DISABLED_TestFive) { + FAIL() << "Expected failure."; +} + +// Test case BazTest. + +TEST(BazTest, TestOne) { + FAIL() << "Expected failure."; +} + +TEST(BazTest, TestA) { +} + +TEST(BazTest, TestB) { +} + +TEST(BazTest, DISABLED_TestC) { + FAIL() << "Expected failure."; +} + +// Test case HasDeathTest + +TEST(HasDeathTest, Test1) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// We need at least two death tests to make sure that the all death tests +// aren't on the first shard. +TEST(HasDeathTest, Test2) { + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); +} + +// Test case FoobarTest + +TEST(DISABLED_FoobarTest, Test1) { + FAIL() << "Expected failure."; +} + +TEST(DISABLED_FoobarTest, DISABLED_Test2) { + FAIL() << "Expected failure."; +} + +// Test case FoobarbazTest + +TEST(DISABLED_FoobarbazTest, TestA) { + FAIL() << "Expected failure."; +} + +#if GTEST_HAS_PARAM_TEST +class ParamTest : public testing::TestWithParam { +}; + +TEST_P(ParamTest, TestX) { +} + +TEST_P(ParamTest, TestY) { +} + +INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2)); +INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6)); +#endif // GTEST_HAS_PARAM_TEST + +} // namespace + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_help_test.py b/src/test/gtest/test/gtest_help_test.py new file mode 100755 index 00000000..093c838d --- /dev/null +++ b/src/test/gtest/test/gtest_help_test.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Tests the --help flag of Google C++ Testing Framework. + +SYNOPSIS + gtest_help_test.py --build_dir=BUILD/DIR + # where BUILD/DIR contains the built gtest_help_test_ file. + gtest_help_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import gtest_test_utils + + +IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' +IS_WINDOWS = os.name == 'nt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') +FLAG_PREFIX = '--gtest_' +DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' +STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to' +UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' +LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' +INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG), + re.sub('^--', '/', LIST_TESTS_FLAG), + re.sub('_', '-', LIST_TESTS_FLAG)] +INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing' + +SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess( + [PROGRAM_PATH, LIST_TESTS_FLAG]).output + +# The help message must match this regex. +HELP_REGEX = re.compile( + FLAG_PREFIX + r'list_tests.*' + + FLAG_PREFIX + r'filter=.*' + + FLAG_PREFIX + r'also_run_disabled_tests.*' + + FLAG_PREFIX + r'repeat=.*' + + FLAG_PREFIX + r'shuffle.*' + + FLAG_PREFIX + r'random_seed=.*' + + FLAG_PREFIX + r'color=.*' + + FLAG_PREFIX + r'print_time.*' + + FLAG_PREFIX + r'output=.*' + + FLAG_PREFIX + r'break_on_failure.*' + + FLAG_PREFIX + r'throw_on_failure.*' + + FLAG_PREFIX + r'catch_exceptions=0.*', + re.DOTALL) + + +def RunWithFlag(flag): + """Runs gtest_help_test_ with the given flag. + + Returns: + the exit code and the text output as a tuple. + Args: + flag: the command-line flag to pass to gtest_help_test_, or None. + """ + + if flag is None: + command = [PROGRAM_PATH] + else: + command = [PROGRAM_PATH, flag] + child = gtest_test_utils.Subprocess(command) + return child.exit_code, child.output + + +class GTestHelpTest(gtest_test_utils.TestCase): + """Tests the --help flag and its equivalent forms.""" + + def TestHelpFlag(self, flag): + """Verifies correct behavior when help flag is specified. + + The right message must be printed and the tests must + skipped when the given flag is specified. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assertEquals(0, exit_code) + self.assert_(HELP_REGEX.search(output), output) + + if IS_LINUX: + self.assert_(STREAM_RESULT_TO_FLAG in output, output) + else: + self.assert_(STREAM_RESULT_TO_FLAG not in output, output) + + if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: + self.assert_(DEATH_TEST_STYLE_FLAG in output, output) + else: + self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) + + def TestNonHelpFlag(self, flag): + """Verifies correct behavior when no help flag is specified. + + Verifies that when no help flag is specified, the tests are run + and the help message is not printed. + + Args: + flag: A flag to pass to the binary or None. + """ + + exit_code, output = RunWithFlag(flag) + self.assert_(exit_code != 0) + self.assert_(not HELP_REGEX.search(output), output) + + def testPrintsHelpWithFullFlag(self): + self.TestHelpFlag('--help') + + def testPrintsHelpWithShortFlag(self): + self.TestHelpFlag('-h') + + def testPrintsHelpWithQuestionFlag(self): + self.TestHelpFlag('-?') + + def testPrintsHelpWithWindowsStyleQuestionFlag(self): + self.TestHelpFlag('/?') + + def testPrintsHelpWithUnrecognizedGoogleTestFlag(self): + self.TestHelpFlag(UNKNOWN_FLAG) + + def testPrintsHelpWithIncorrectFlagStyle(self): + for incorrect_flag in INCORRECT_FLAG_VARIANTS: + self.TestHelpFlag(incorrect_flag) + + def testRunsTestsWithoutHelpFlag(self): + """Verifies that when no help flag is specified, the tests are run + and the help message is not printed.""" + + self.TestNonHelpFlag(None) + + def testRunsTestsWithGtestInternalFlag(self): + """Verifies that the tests are run and no help message is printed when + a flag starting with Google Test prefix and 'internal_' is supplied.""" + + self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_help_test_.cc b/src/test/gtest/test/gtest_help_test_.cc new file mode 100644 index 00000000..31f78c24 --- /dev/null +++ b/src/test/gtest/test/gtest_help_test_.cc @@ -0,0 +1,46 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This program is meant to be run by gtest_help_test.py. Do not run +// it directly. + +#include "gtest/gtest.h" + +// When a help flag is specified, this program should skip the tests +// and exit with 0; otherwise the following test will be executed, +// causing this program to exit with a non-zero code. +TEST(HelpFlagTest, ShouldNotBeRun) { + ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified."; +} + +#if GTEST_HAS_DEATH_TEST +TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {} +#endif diff --git a/src/test/gtest/test/gtest_list_tests_unittest.py b/src/test/gtest/test/gtest_list_tests_unittest.py new file mode 100755 index 00000000..925b09d9 --- /dev/null +++ b/src/test/gtest/test/gtest_list_tests_unittest.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Unit test for Google Test's --gtest_list_tests flag. + +A user can ask Google Test to list all tests by specifying the +--gtest_list_tests flag. This script tests such functionality +by invoking gtest_list_tests_unittest_ (a program written with +Google Test) the command line flags. +""" + +__author__ = 'phanna@google.com (Patrick Hanna)' + +import gtest_test_utils +import re + + +# Constants. + +# The command line flag for enabling/disabling listing all tests. +LIST_TESTS_FLAG = 'gtest_list_tests' + +# Path to the gtest_list_tests_unittest_ program. +EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_') + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests +EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\. + Test1 +Foo\. + Bar1 + Bar2 + DISABLED_Bar3 +Abc\. + Xyz + Def +FooBar\. + Baz +FooTest\. + Test1 + DISABLED_Test2 + Test3 +TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +TypedTest/1\. # TypeParam = int\s*\* + TestA + TestB +TypedTest/2\. # TypeParam = .*MyArray + TestA + TestB +My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. + TestA + TestB +My/TypeParamTest/1\. # TypeParam = int\s*\* + TestA + TestB +My/TypeParamTest/2\. # TypeParam = .*MyArray + TestA + TestB +MyInstantiation/ValueParamTest\. + TestA/0 # GetParam\(\) = one line + TestA/1 # GetParam\(\) = two\\nlines + TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\. + TestB/0 # GetParam\(\) = one line + TestB/1 # GetParam\(\) = two\\nlines + TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\. +""") + +# The expected output when running gtest_list_tests_unittest_ with +# --gtest_list_tests and --gtest_filter=Foo*. +EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\. + Test1 +Foo\. + Bar1 + Bar2 + DISABLED_Bar3 +FooBar\. + Baz +FooTest\. + Test1 + DISABLED_Test2 + Test3 +""") + +# Utilities. + + +def Run(args): + """Runs gtest_list_tests_unittest_ and returns the list of tests printed.""" + + return gtest_test_utils.Subprocess([EXE_PATH] + args, + capture_stderr=False).output + + +# The unit test. + +class GTestListTestsUnitTest(gtest_test_utils.TestCase): + """Tests using the --gtest_list_tests flag to list all tests.""" + + def RunAndVerify(self, flag_value, expected_output_re, other_flag): + """Runs gtest_list_tests_unittest_ and verifies that it prints + the correct tests. + + Args: + flag_value: value of the --gtest_list_tests flag; + None if the flag should not be present. + expected_output_re: regular expression that matches the expected + output after running command; + other_flag: a different flag to be passed to command + along with gtest_list_tests; + None if the flag should not be present. + """ + + if flag_value is None: + flag = '' + flag_expression = 'not set' + elif flag_value == '0': + flag = '--%s=0' % LIST_TESTS_FLAG + flag_expression = '0' + else: + flag = '--%s' % LIST_TESTS_FLAG + flag_expression = '1' + + args = [flag] + + if other_flag is not None: + args += [other_flag] + + output = Run(args) + + if expected_output_re: + self.assert_( + expected_output_re.match(output), + ('when %s is %s, the output of "%s" is "%s",\n' + 'which does not match regex "%s"' % + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output, + expected_output_re.pattern))) + else: + self.assert_( + not EXPECTED_OUTPUT_NO_FILTER_RE.match(output), + ('when %s is %s, the output of "%s" is "%s"'% + (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(flag_value=None, + expected_output_re=None, + other_flag=None) + + def testFlag(self): + """Tests using the --gtest_list_tests flag.""" + + self.RunAndVerify(flag_value='0', + expected_output_re=None, + other_flag=None) + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, + other_flag=None) + + def testOverrideNonFilterFlags(self): + """Tests that --gtest_list_tests overrides the non-filter flags.""" + + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, + other_flag='--gtest_break_on_failure') + + def testWithFilterFlags(self): + """Tests that --gtest_list_tests takes into account the + --gtest_filter flag.""" + + self.RunAndVerify(flag_value='1', + expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE, + other_flag='--gtest_filter=Foo*') + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_list_tests_unittest_.cc b/src/test/gtest/test/gtest_list_tests_unittest_.cc new file mode 100644 index 00000000..907c176b --- /dev/null +++ b/src/test/gtest/test/gtest_list_tests_unittest_.cc @@ -0,0 +1,157 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: phanna@google.com (Patrick Hanna) + +// Unit test for Google Test's --gtest_list_tests flag. +// +// A user can ask Google Test to list all tests that will run +// so that when using a filter, a user will know what +// tests to look for. The tests will not be run after listing. +// +// This program will be invoked from a Python unit test. +// Don't run it directly. + +#include "gtest/gtest.h" + +// Several different test cases and tests that will be listed. +TEST(Foo, Bar1) { +} + +TEST(Foo, Bar2) { +} + +TEST(Foo, DISABLED_Bar3) { +} + +TEST(Abc, Xyz) { +} + +TEST(Abc, Def) { +} + +TEST(FooBar, Baz) { +} + +class FooTest : public testing::Test { +}; + +TEST_F(FooTest, Test1) { +} + +TEST_F(FooTest, DISABLED_Test2) { +} + +TEST_F(FooTest, Test3) { +} + +TEST(FooDeathTest, Test1) { +} + +// A group of value-parameterized tests. + +class MyType { + public: + explicit MyType(const std::string& a_value) : value_(a_value) {} + + const std::string& value() const { return value_; } + + private: + std::string value_; +}; + +// Teaches Google Test how to print a MyType. +void PrintTo(const MyType& x, std::ostream* os) { + *os << x.value(); +} + +class ValueParamTest : public testing::TestWithParam { +}; + +TEST_P(ValueParamTest, TestA) { +} + +TEST_P(ValueParamTest, TestB) { +} + +INSTANTIATE_TEST_CASE_P( + MyInstantiation, ValueParamTest, + testing::Values(MyType("one line"), + MyType("two\nlines"), + MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT + +// A group of typed tests. + +// A deliberately long type name for testing the line-truncating +// behavior when printing a type parameter. +class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT +}; + +template +class TypedTest : public testing::Test { +}; + +template +class MyArray { +}; + +typedef testing::Types > MyTypes; + +TYPED_TEST_CASE(TypedTest, MyTypes); + +TYPED_TEST(TypedTest, TestA) { +} + +TYPED_TEST(TypedTest, TestB) { +} + +// A group of type-parameterized tests. + +template +class TypeParamTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(TypeParamTest); + +TYPED_TEST_P(TypeParamTest, TestA) { +} + +TYPED_TEST_P(TypeParamTest, TestB) { +} + +REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB); + +INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes); + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_main_unittest.cc b/src/test/gtest/test/gtest_main_unittest.cc new file mode 100644 index 00000000..ecd9bb87 --- /dev/null +++ b/src/test/gtest/test/gtest_main_unittest.cc @@ -0,0 +1,45 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +// Tests that we don't have to define main() when we link to +// gtest_main instead of gtest. + +namespace { + +TEST(GTestMainTest, ShouldSucceed) { +} + +} // namespace + +// We are using the main() function defined in src/gtest_main.cc, so +// we don't define it here. diff --git a/src/test/gtest/test/gtest_no_test_unittest.cc b/src/test/gtest/test/gtest_no_test_unittest.cc new file mode 100644 index 00000000..292599af --- /dev/null +++ b/src/test/gtest/test/gtest_no_test_unittest.cc @@ -0,0 +1,56 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// Tests that a Google Test program that has no test defined can run +// successfully. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + // An ad-hoc assertion outside of all tests. + // + // This serves three purposes: + // + // 1. It verifies that an ad-hoc assertion can be executed even if + // no test is defined. + // 2. It verifies that a failed ad-hoc assertion causes the test + // program to fail. + // 3. We had a bug where the XML output won't be generated if an + // assertion is executed before RUN_ALL_TESTS() is called, even + // though --gtest_output=xml is specified. This makes sure the + // bug is fixed and doesn't regress. + EXPECT_EQ(1, 2); + + // The above EXPECT_EQ() should cause RUN_ALL_TESTS() to return non-zero. + return RUN_ALL_TESTS() ? 0 : 1; +} diff --git a/src/test/gtest/test/gtest_output_test.py b/src/test/gtest/test/gtest_output_test.py new file mode 100755 index 00000000..fa1a3117 --- /dev/null +++ b/src/test/gtest/test/gtest_output_test.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Tests the text output of Google C++ Testing Framework. + +SYNOPSIS + gtest_output_test.py --build_dir=BUILD/DIR --gengolden + # where BUILD/DIR contains the built gtest_output_test_ file. + gtest_output_test.py --gengolden + gtest_output_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import re +import sys +import gtest_test_utils + + +# The flag for generating the golden file +GENGOLDEN_FLAG = '--gengolden' +CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS' + +IS_WINDOWS = os.name == 'nt' + +# TODO(vladl@google.com): remove the _lin suffix. +GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' + +PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') + +# At least one command we exercise must not have the +# --gtest_internal_skip_environment_and_ad_hoc_tests flag. +COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests']) +COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes']) +COMMAND_WITH_TIME = ({}, [PROGRAM_PATH, + '--gtest_print_time', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=FatalFailureTest.*:LoggingTest.*']) +COMMAND_WITH_DISABLED = ( + {}, [PROGRAM_PATH, + '--gtest_also_run_disabled_tests', + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=*DISABLED_*']) +COMMAND_WITH_SHARDING = ( + {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, + [PROGRAM_PATH, + '--gtest_internal_skip_environment_and_ad_hoc_tests', + '--gtest_filter=PassingTest.*']) + +GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) + + +def ToUnixLineEnding(s): + """Changes all Windows/Mac line endings in s to UNIX line endings.""" + + return s.replace('\r\n', '\n').replace('\r', '\n') + + +def RemoveLocations(test_output): + """Removes all file location info from a Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with all file location info (in the form of + 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or + 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by + 'FILE_NAME:#: '. + """ + + return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output) + + +def RemoveStackTraceDetails(output): + """Removes all stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', + 'Stack trace: (omitted)\n\n', output) + + +def RemoveStackTraces(output): + """Removes all traces of stack traces from a Google Test program's output.""" + + # *? means "find the shortest string that matches". + return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output) + + +def RemoveTime(output): + """Removes all time information from a Google Test program's output.""" + + return re.sub(r'\(\d+ ms', '(? ms', output) + + +def RemoveTypeInfoDetails(test_output): + """Removes compiler-specific type info from Google Test program's output. + + Args: + test_output: the output of a Google Test program. + + Returns: + output with type information normalized to canonical form. + """ + + # some compilers output the name of type 'unsigned int' as 'unsigned' + return re.sub(r'unsigned int', 'unsigned', test_output) + + +def NormalizeToCurrentPlatform(test_output): + """Normalizes platform specific output details for easier comparison.""" + + if IS_WINDOWS: + # Removes the color information that is not present on Windows. + test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output) + # Changes failure message headers into the Windows format. + test_output = re.sub(r': Failure\n', r': error: ', test_output) + # Changes file(line_number) to file:line_number. + test_output = re.sub(r'((\w|\.)+)\((\d+)\):', r'\1:\3:', test_output) + + return test_output + + +def RemoveTestCounts(output): + """Removes test counts from a Google Test program's output.""" + + output = re.sub(r'\d+ tests?, listed below', + '? tests, listed below', output) + output = re.sub(r'\d+ FAILED TESTS', + '? FAILED TESTS', output) + output = re.sub(r'\d+ tests? from \d+ test cases?', + '? tests from ? test cases', output) + output = re.sub(r'\d+ tests? from ([a-zA-Z_])', + r'? tests from \1', output) + return re.sub(r'\d+ tests?\.', '? tests.', output) + + +def RemoveMatchingTests(test_output, pattern): + """Removes output of specified tests from a Google Test program's output. + + This function strips not only the beginning and the end of a test but also + all output in between. + + Args: + test_output: A string containing the test output. + pattern: A regex string that matches names of test cases or + tests to remove. + + Returns: + Contents of test_output with tests whose names match pattern removed. + """ + + test_output = re.sub( + r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( + pattern, pattern), + '', + test_output) + return re.sub(r'.*%s.*\n' % pattern, '', test_output) + + +def NormalizeOutput(output): + """Normalizes output (the output of gtest_output_test_.exe).""" + + output = ToUnixLineEnding(output) + output = RemoveLocations(output) + output = RemoveStackTraceDetails(output) + output = RemoveTime(output) + return output + + +def GetShellCommandOutput(env_cmd): + """Runs a command in a sub-process, and returns its output in a string. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + + Returns: + A string with the command's combined standard and diagnostic output. + """ + + # Spawns cmd in a sub-process, and gets its standard I/O file objects. + # Set and save the environment properly. + environ = os.environ.copy() + environ.update(env_cmd[0]) + p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) + + return p.output + + +def GetCommandOutput(env_cmd): + """Runs a command and returns its output with all file location + info stripped off. + + Args: + env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra + environment variables to set, and element 1 is a string with + the command and any flags. + """ + + # Disables exception pop-ups on Windows. + environ, cmdline = env_cmd + environ = dict(environ) # Ensures we are modifying a copy. + environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1' + return NormalizeOutput(GetShellCommandOutput((environ, cmdline))) + + +def GetOutputOfAllCommands(): + """Returns concatenated output from several representative commands.""" + + return (GetCommandOutput(COMMAND_WITH_COLOR) + + GetCommandOutput(COMMAND_WITH_TIME) + + GetCommandOutput(COMMAND_WITH_DISABLED) + + GetCommandOutput(COMMAND_WITH_SHARDING)) + + +test_list = GetShellCommandOutput(COMMAND_LIST_TESTS) +SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list +SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list +SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list +SUPPORTS_STACK_TRACES = False + +CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and + SUPPORTS_TYPED_TESTS and + SUPPORTS_THREADS and + not IS_WINDOWS) + +class GTestOutputTest(gtest_test_utils.TestCase): + def RemoveUnsupportedTests(self, test_output): + if not SUPPORTS_DEATH_TESTS: + test_output = RemoveMatchingTests(test_output, 'DeathTest') + if not SUPPORTS_TYPED_TESTS: + test_output = RemoveMatchingTests(test_output, 'TypedTest') + test_output = RemoveMatchingTests(test_output, 'TypedDeathTest') + test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest') + if not SUPPORTS_THREADS: + test_output = RemoveMatchingTests(test_output, + 'ExpectFailureWithThreadsTest') + test_output = RemoveMatchingTests(test_output, + 'ScopedFakeTestPartResultReporterTest') + test_output = RemoveMatchingTests(test_output, + 'WorksConcurrently') + if not SUPPORTS_STACK_TRACES: + test_output = RemoveStackTraces(test_output) + + return test_output + + def testOutput(self): + output = GetOutputOfAllCommands() + + golden_file = open(GOLDEN_PATH, 'rb') + # A mis-configured source control system can cause \r appear in EOL + # sequences when we read the golden file irrespective of an operating + # system used. Therefore, we need to strip those \r's from newlines + # unconditionally. + golden = ToUnixLineEnding(golden_file.read()) + golden_file.close() + + # We want the test to pass regardless of certain features being + # supported or not. + + # We still have to remove type name specifics in all cases. + normalized_actual = RemoveTypeInfoDetails(output) + normalized_golden = RemoveTypeInfoDetails(golden) + + if CAN_GENERATE_GOLDEN_FILE: + self.assertEqual(normalized_golden, normalized_actual) + else: + normalized_actual = NormalizeToCurrentPlatform( + RemoveTestCounts(normalized_actual)) + normalized_golden = NormalizeToCurrentPlatform( + RemoveTestCounts(self.RemoveUnsupportedTests(normalized_golden))) + + # This code is very handy when debugging golden file differences: + if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_actual.txt'), 'wb').write( + normalized_actual) + open(os.path.join( + gtest_test_utils.GetSourceDir(), + '_gtest_output_test_normalized_golden.txt'), 'wb').write( + normalized_golden) + + self.assertEqual(normalized_golden, normalized_actual) + + +if __name__ == '__main__': + if sys.argv[1:] == [GENGOLDEN_FLAG]: + if CAN_GENERATE_GOLDEN_FILE: + output = GetOutputOfAllCommands() + golden_file = open(GOLDEN_PATH, 'wb') + golden_file.write(output) + golden_file.close() + else: + message = ( + """Unable to write a golden file when compiled in an environment +that does not support all the required features (death tests, typed tests, +and multiple threads). Please generate the golden file using a binary built +with those features enabled.""") + + sys.stderr.write(message) + sys.exit(1) + else: + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_output_test_.cc b/src/test/gtest/test/gtest_output_test_.cc new file mode 100644 index 00000000..07ab633d --- /dev/null +++ b/src/test/gtest/test/gtest_output_test_.cc @@ -0,0 +1,1034 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// The purpose of this file is to generate Google Test output under +// various conditions. The output will then be verified by +// gtest_output_test.py to ensure that Google Test generates the +// desired messages. Therefore, most tests in this file are MEANT TO +// FAIL. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#include + +#if GTEST_IS_THREADSAFE +using testing::ScopedFakeTestPartResultReporter; +using testing::TestPartResultArray; + +using testing::internal::Notification; +using testing::internal::ThreadWithParam; +#endif + +namespace posix = ::testing::internal::posix; +using testing::internal::scoped_ptr; + +// Tests catching fatal failures. + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// This function calls a test subroutine, catches the fatal failure it +// generates, and then returns early. +void TryTestSubroutine() { + // Calls a subrountine that yields a fatal failure. + TestEq1(2); + + // Catches the fatal failure and aborts the test. + // + // The testing::Test:: prefix is necessary when calling + // HasFatalFailure() outside of a TEST, TEST_F, or test fixture. + if (testing::Test::HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +TEST(PassingTest, PassingTest1) { +} + +TEST(PassingTest, PassingTest2) { +} + +// Tests that parameters of failing parameterized tests are printed in the +// failing test summary. +class FailingParamTest : public testing::TestWithParam {}; + +TEST_P(FailingParamTest, Fails) { + EXPECT_EQ(1, GetParam()); +} + +// This generates a test which will fail. Google Test is expected to print +// its parameter when it outputs the list of all failed tests. +INSTANTIATE_TEST_CASE_P(PrintingFailingParams, + FailingParamTest, + testing::Values(2)); + +static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; + +TEST(NonfatalFailureTest, EscapesStringOperands) { + std::string actual = "actual \"string\""; + EXPECT_EQ(kGoldenString, actual); + + const char* golden = kGoldenString; + EXPECT_EQ(golden, actual); +} + +// Tests catching a fatal failure in a subroutine. +TEST(FatalFailureTest, FatalFailureInSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + TryTestSubroutine(); +} + +// Tests catching a fatal failure in a nested subroutine. +TEST(FatalFailureTest, FatalFailureInNestedSubroutine) { + printf("(expecting a failure that x should be 1)\n"); + + // Calls a subrountine that yields a fatal failure. + TryTestSubroutine(); + + // Catches the fatal failure and aborts the test. + // + // When calling HasFatalFailure() inside a TEST, TEST_F, or test + // fixture, the testing::Test:: prefix is not needed. + if (HasFatalFailure()) return; + + // If we get here, something is wrong. + FAIL() << "This should never be reached."; +} + +// Tests HasFatalFailure() after a failed EXPECT check. +TEST(FatalFailureTest, NonfatalFailureInSubroutine) { + printf("(expecting a failure on false)\n"); + EXPECT_TRUE(false); // Generates a nonfatal failure + ASSERT_FALSE(HasFatalFailure()); // This should succeed. +} + +// Tests interleaving user logging and Google Test assertions. +TEST(LoggingTest, InterleavingLoggingAndAssertions) { + static const int a[4] = { + 3, 9, 2, 6 + }; + + printf("(expecting 2 failures on (3) >= (a[i]))\n"); + for (int i = 0; i < static_cast(sizeof(a)/sizeof(*a)); i++) { + printf("i == %d\n", i); + EXPECT_GE(3, a[i]); + } +} + +// Tests the SCOPED_TRACE macro. + +// A helper function for testing SCOPED_TRACE. +void SubWithoutTrace(int n) { + EXPECT_EQ(1, n); + ASSERT_EQ(2, n); +} + +// Another helper function for testing SCOPED_TRACE. +void SubWithTrace(int n) { + SCOPED_TRACE(testing::Message() << "n = " << n); + + SubWithoutTrace(n); +} + +// Tests that SCOPED_TRACE() obeys lexical scopes. +TEST(SCOPED_TRACETest, ObeysScopes) { + printf("(expected to fail)\n"); + + // There should be no trace before SCOPED_TRACE() is invoked. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; + + { + SCOPED_TRACE("Expected trace"); + // After SCOPED_TRACE(), a failure in the current scope should contain + // the trace. + ADD_FAILURE() << "This failure is expected, and should have a trace."; + } + + // Once the control leaves the scope of the SCOPED_TRACE(), there + // should be no trace again. + ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; +} + +// Tests that SCOPED_TRACE works inside a loop. +TEST(SCOPED_TRACETest, WorksInLoop) { + printf("(expected to fail)\n"); + + for (int i = 1; i <= 2; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + + SubWithoutTrace(i); + } +} + +// Tests that SCOPED_TRACE works in a subroutine. +TEST(SCOPED_TRACETest, WorksInSubroutine) { + printf("(expected to fail)\n"); + + SubWithTrace(1); + SubWithTrace(2); +} + +// Tests that SCOPED_TRACE can be nested. +TEST(SCOPED_TRACETest, CanBeNested) { + printf("(expected to fail)\n"); + + SCOPED_TRACE(""); // A trace without a message. + + SubWithTrace(2); +} + +// Tests that multiple SCOPED_TRACEs can be used in the same scope. +TEST(SCOPED_TRACETest, CanBeRepeated) { + printf("(expected to fail)\n"); + + SCOPED_TRACE("A"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A."; + + SCOPED_TRACE("B"); + ADD_FAILURE() + << "This failure is expected, and should contain trace point A and B."; + + { + SCOPED_TRACE("C"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and C."; + } + + SCOPED_TRACE("D"); + ADD_FAILURE() << "This failure is expected, and should " + << "contain trace point A, B, and D."; +} + +#if GTEST_IS_THREADSAFE +// Tests that SCOPED_TRACE()s can be used concurrently from multiple +// threads. Namely, an assertion should be affected by +// SCOPED_TRACE()s in its own thread only. + +// Here's the sequence of actions that happen in the test: +// +// Thread A (main) | Thread B (spawned) +// ===============================|================================ +// spawns thread B | +// -------------------------------+-------------------------------- +// waits for n1 | SCOPED_TRACE("Trace B"); +// | generates failure #1 +// | notifies n1 +// -------------------------------+-------------------------------- +// SCOPED_TRACE("Trace A"); | waits for n2 +// generates failure #2 | +// notifies n2 | +// -------------------------------|-------------------------------- +// waits for n3 | generates failure #3 +// | trace B dies +// | generates failure #4 +// | notifies n3 +// -------------------------------|-------------------------------- +// generates failure #5 | finishes +// trace A dies | +// generates failure #6 | +// -------------------------------|-------------------------------- +// waits for thread B to finish | + +struct CheckPoints { + Notification n1; + Notification n2; + Notification n3; +}; + +static void ThreadWithScopedTrace(CheckPoints* check_points) { + { + SCOPED_TRACE("Trace B"); + ADD_FAILURE() + << "Expected failure #1 (in thread B, only trace B alive)."; + check_points->n1.Notify(); + check_points->n2.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #3 (in thread B, trace A & B both alive)."; + } // Trace B dies here. + ADD_FAILURE() + << "Expected failure #4 (in thread B, only trace A alive)."; + check_points->n3.Notify(); +} + +TEST(SCOPED_TRACETest, WorksConcurrently) { + printf("(expecting 6 failures)\n"); + + CheckPoints check_points; + ThreadWithParam thread(&ThreadWithScopedTrace, + &check_points, + NULL); + check_points.n1.WaitForNotification(); + + { + SCOPED_TRACE("Trace A"); + ADD_FAILURE() + << "Expected failure #2 (in thread A, trace A & B both alive)."; + check_points.n2.Notify(); + check_points.n3.WaitForNotification(); + + ADD_FAILURE() + << "Expected failure #5 (in thread A, only trace A alive)."; + } // Trace A dies here. + ADD_FAILURE() + << "Expected failure #6 (in thread A, no trace alive)."; + thread.Join(); +} +#endif // GTEST_IS_THREADSAFE + +TEST(DisabledTestsWarningTest, + DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) { + // This test body is intentionally empty. Its sole purpose is for + // verifying that the --gtest_also_run_disabled_tests flag + // suppresses the "YOU HAVE 12 DISABLED TESTS" warning at the end of + // the test output. +} + +// Tests using assertions outside of TEST and TEST_F. +// +// This function creates two failures intentionally. +void AdHocTest() { + printf("The non-test part of the code is expected to have 2 failures.\n\n"); + EXPECT_TRUE(false); + EXPECT_EQ(2, 3); +} + +// Runs all TESTs, all TEST_Fs, and the ad hoc test. +int RunAllTests() { + AdHocTest(); + return RUN_ALL_TESTS(); +} + +// Tests non-fatal failures in the fixture constructor. +class NonFatalFailureInFixtureConstructorTest : public testing::Test { + protected: + NonFatalFailureInFixtureConstructorTest() { + printf("(expecting 5 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in the test fixture c'tor."; + } + + ~NonFatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #5, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "Expected failure #2, in SetUp()."; + } + + virtual void TearDown() { + ADD_FAILURE() << "Expected failure #4, in TearDown."; + } +}; + +TEST_F(NonFatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "Expected failure #3, in the test body."; +} + +// Tests fatal failures in the fixture constructor. +class FatalFailureInFixtureConstructorTest : public testing::Test { + protected: + FatalFailureInFixtureConstructorTest() { + printf("(expecting 2 failures)\n"); + Init(); + } + + ~FatalFailureInFixtureConstructorTest() { + ADD_FAILURE() << "Expected failure #2, in the test fixture d'tor."; + } + + virtual void SetUp() { + ADD_FAILURE() << "UNEXPECTED failure in SetUp(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + virtual void TearDown() { + ADD_FAILURE() << "UNEXPECTED failure in TearDown(). " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; + } + + private: + void Init() { + FAIL() << "Expected failure #1, in the test fixture c'tor."; + } +}; + +TEST_F(FatalFailureInFixtureConstructorTest, FailureInConstructor) { + ADD_FAILURE() << "UNEXPECTED failure in the test body. " + << "We should never get here, as the test fixture c'tor " + << "had a fatal failure."; +} + +// Tests non-fatal failures in SetUp(). +class NonFatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~NonFatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 4 failures)\n"); + ADD_FAILURE() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #3, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #4, in the test fixture d'tor."; + } +}; + +TEST_F(NonFatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "Expected failure #2, in the test function."; +} + +// Tests fatal failures in SetUp(). +class FatalFailureInSetUpTest : public testing::Test { + protected: + virtual ~FatalFailureInSetUpTest() { + Deinit(); + } + + virtual void SetUp() { + printf("(expecting 3 failures)\n"); + FAIL() << "Expected failure #1, in SetUp()."; + } + + virtual void TearDown() { + FAIL() << "Expected failure #2, in TearDown()."; + } + private: + void Deinit() { + FAIL() << "Expected failure #3, in the test fixture d'tor."; + } +}; + +TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { + FAIL() << "UNEXPECTED failure in the test function. " + << "We should never get here, as SetUp() failed."; +} + +TEST(AddFailureAtTest, MessageContainsSpecifiedFileAndLineNumber) { + ADD_FAILURE_AT("foo.cc", 42) << "Expected failure in foo.cc"; +} + +#if GTEST_IS_THREADSAFE + +// A unary function that may die. +void DieIf(bool should_die) { + GTEST_CHECK_(!should_die) << " - death inside DieIf()."; +} + +// Tests running death tests in a multi-threaded context. + +// Used for coordination between the main and the spawn thread. +struct SpawnThreadNotifications { + SpawnThreadNotifications() {} + + Notification spawn_thread_started; + Notification spawn_thread_ok_to_terminate; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); +}; + +// The function to be executed in the thread spawn by the +// MultipleThreads test (below). +static void ThreadRoutine(SpawnThreadNotifications* notifications) { + // Signals the main thread that this thread has started. + notifications->spawn_thread_started.Notify(); + + // Waits for permission to finish from the main thread. + notifications->spawn_thread_ok_to_terminate.WaitForNotification(); +} + +// This is a death-test test, but it's not named with a DeathTest +// suffix. It starts threads which might interfere with later +// death tests, so it must run after all other death tests. +class DeathTestAndMultiThreadsTest : public testing::Test { + protected: + // Starts a thread and waits for it to begin. + virtual void SetUp() { + thread_.reset(new ThreadWithParam( + &ThreadRoutine, ¬ifications_, NULL)); + notifications_.spawn_thread_started.WaitForNotification(); + } + // Tells the thread to finish, and reaps it. + // Depending on the version of the thread library in use, + // a manager thread might still be left running that will interfere + // with later death tests. This is unfortunate, but this class + // cleans up after itself as best it can. + virtual void TearDown() { + notifications_.spawn_thread_ok_to_terminate.Notify(); + } + + private: + SpawnThreadNotifications notifications_; + scoped_ptr > thread_; +}; + +#endif // GTEST_IS_THREADSAFE + +// The MixedUpTestCaseTest test case verifies that Google Test will fail a +// test if it uses a different fixture class than what other tests in +// the same test case use. It deliberately contains two fixture +// classes with the same name but defined in different namespaces. + +// The MixedUpTestCaseWithSameTestNameTest test case verifies that +// when the user defines two tests with the same test case name AND +// same test name (but in different namespaces), the second test will +// fail. + +namespace foo { + +class MixedUpTestCaseTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseTest, FirstTestFromNamespaceFoo) {} +TEST_F(MixedUpTestCaseTest, SecondTestFromNamespaceFoo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace foo + +namespace bar { + +class MixedUpTestCaseTest : public testing::Test { +}; + +// The following two tests are expected to fail. We rely on the +// golden file to check that Google Test generates the right error message. +TEST_F(MixedUpTestCaseTest, ThisShouldFail) {} +TEST_F(MixedUpTestCaseTest, ThisShouldFailToo) {} + +class MixedUpTestCaseWithSameTestNameTest : public testing::Test { +}; + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(MixedUpTestCaseWithSameTestNameTest, + TheSecondTestWithThisNameShouldFail) {} + +} // namespace bar + +// The following two test cases verify that Google Test catches the user +// error of mixing TEST and TEST_F in the same test case. The first +// test case checks the scenario where TEST_F appears before TEST, and +// the second one checks where TEST appears before TEST_F. + +class TEST_F_before_TEST_in_same_test_case : public testing::Test { +}; + +TEST_F(TEST_F_before_TEST_in_same_test_case, DefinedUsingTEST_F) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST(TEST_F_before_TEST_in_same_test_case, DefinedUsingTESTAndShouldFail) {} + +class TEST_before_TEST_F_in_same_test_case : public testing::Test { +}; + +TEST(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST) {} + +// Expected to fail. We rely on the golden file to check that Google Test +// generates the right error message. +TEST_F(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST_FAndShouldFail) { +} + +// Used for testing EXPECT_NONFATAL_FAILURE() and EXPECT_FATAL_FAILURE(). +int global_integer = 0; + +// Tests that EXPECT_NONFATAL_FAILURE() can reference global variables. +TEST(ExpectNonfatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(1, global_integer) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() can reference local variables +// (static or not). +TEST(ExpectNonfatalFailureTest, CanReferenceLocalVariables) { + int m = 0; + static int n; + n = 1; + EXPECT_NONFATAL_FAILURE({ + EXPECT_EQ(m, n) << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() succeeds when there is exactly +// one non-fatal failure and no fatal failure. +TEST(ExpectNonfatalFailureTest, SucceedsWhenThereIsOneNonfatalFailure) { + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, "Expected non-fatal failure."); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is no +// non-fatal failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsNoNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there are two +// non-fatal failures. +TEST(ExpectNonfatalFailureTest, FailsWhenThereAreTwoNonfatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure 1."; + ADD_FAILURE() << "Expected non-fatal failure 2."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when there is one fatal +// failure. +TEST(ExpectNonfatalFailureTest, FailsWhenThereIsOneFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, ""); +} + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_NONFATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectNonfatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_NONFATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() can reference global variables. +TEST(ExpectFatalFailureTest, CanReferenceGlobalVariables) { + global_integer = 0; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(1, global_integer) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() can reference local static +// variables. +TEST(ExpectFatalFailureTest, CanReferenceLocalStaticVariables) { + static int n; + n = 1; + EXPECT_FATAL_FAILURE({ + ASSERT_EQ(0, n) << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() succeeds when there is exactly +// one fatal failure and no non-fatal failure. +TEST(ExpectFatalFailureTest, SucceedsWhenThereIsOneFatalFailure) { + EXPECT_FATAL_FAILURE({ + FAIL() << "Expected fatal failure."; + }, "Expected fatal failure."); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is no fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsNoFatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + }, ""); +} + +// A helper for generating a fatal failure. +void FatalFailure() { + FAIL() << "Expected fatal failure."; +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there are two +// fatal failures. +TEST(ExpectFatalFailureTest, FailsWhenThereAreTwoFatalFailures) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + FatalFailure(); + FatalFailure(); + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when there is one non-fatal +// failure. +TEST(ExpectFatalFailureTest, FailsWhenThereIsOneNonfatalFailure) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + ADD_FAILURE() << "Expected non-fatal failure."; + }, ""); +} + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested returns. +TEST(ExpectFatalFailureTest, FailsWhenStatementReturns) { + printf("(expecting a failure)\n"); + EXPECT_FATAL_FAILURE({ + return; + }, ""); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests that EXPECT_FATAL_FAILURE() fails when the statement being +// tested throws. +TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { + printf("(expecting a failure)\n"); + try { + EXPECT_FATAL_FAILURE({ + throw 0; + }, ""); + } catch(int) { // NOLINT + } +} + +#endif // GTEST_HAS_EXCEPTIONS + +// This #ifdef block tests the output of typed tests. +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public testing::Test { +}; + +TYPED_TEST_CASE(TypedTest, testing::Types); + +TYPED_TEST(TypedTest, Success) { + EXPECT_EQ(0, TypeParam()); +} + +TYPED_TEST(TypedTest, Failure) { + EXPECT_EQ(1, TypeParam()) << "Expected failure"; +} + +#endif // GTEST_HAS_TYPED_TEST + +// This #ifdef block tests the output of type-parameterized tests. +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public testing::Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, Success) { + EXPECT_EQ(0U, TypeParam()); +} + +TYPED_TEST_P(TypedTestP, Failure) { + EXPECT_EQ(1U, TypeParam()) << "Expected failure"; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure); + +typedef testing::Types UnsignedTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +#if GTEST_HAS_DEATH_TEST + +// We rely on the golden file to verify that tests whose test case +// name ends with DeathTest are run first. + +TEST(ADeathTest, ShouldRunFirst) { +} + +# if GTEST_HAS_TYPED_TEST + +// We rely on the golden file to verify that typed tests whose test +// case name ends with DeathTest are run first. + +template +class ATypedDeathTest : public testing::Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(ATypedDeathTest, NumericTypes); + +TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { +} + +# endif // GTEST_HAS_TYPED_TEST + +# if GTEST_HAS_TYPED_TEST_P + + +// We rely on the golden file to verify that type-parameterized tests +// whose test case name ends with DeathTest are run first. + +template +class ATypeParamDeathTest : public testing::Test { +}; + +TYPED_TEST_CASE_P(ATypeParamDeathTest); + +TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) { +} + +REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst); + +INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); + +# endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_HAS_DEATH_TEST + +// Tests various failure conditions of +// EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}. +class ExpectFailureTest : public testing::Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + FAIL() << "Expected fatal failure."; + } else { + ADD_FAILURE() << "Expected non-fatal failure."; + } + } +}; + +TEST_F(ExpectFailureTest, ExpectFatalFailure) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Expected non-fatal " + "failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Some other fatal failure " + "expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(SUCCEED(), "Expected non-fatal failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Some other non-fatal " + "failure."); +} + +#if GTEST_IS_THREADSAFE + +class ExpectFailureWithThreadsTest : public ExpectFailureTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); + } +}; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_FATAL_FAILURE(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailure) { + // We only intercept the current thread. + printf("(expecting 2 failures)\n"); + EXPECT_NONFATAL_FAILURE(AddFailureInOtherThread(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +typedef ExpectFailureWithThreadsTest ScopedFakeTestPartResultReporterTest; + +// Tests that the ScopedFakeTestPartResultReporter only catches failures from +// the current thread if it is instantiated with INTERCEPT_ONLY_CURRENT_THREAD. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) { + printf("(expecting 2 failures)\n"); + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailureInOtherThread(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + } + // The two failures should not have been intercepted. + EXPECT_EQ(0, results.size()) << "This shouldn't fail."; +} + +#endif // GTEST_IS_THREADSAFE + +TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { + // Expected fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected fatal failure."); + // Expected fatal failure, but got a non-fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Some other fatal failure expected."); +} + +TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { + // Expected non-fatal failure, but succeeds. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected non-fatal " + "failure."); + // Expected non-fatal failure, but got a fatal failure. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), + "Expected fatal failure."); + // Wrong message. + printf("(expecting 1 failure)\n"); + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Some other non-fatal failure."); +} + + +// Two test environments for testing testing::AddGlobalTestEnvironment(). + +class FooEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "FooEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "FooEnvironment::TearDown() called.\n"); + FAIL() << "Expected fatal failure."; + } +}; + +class BarEnvironment : public testing::Environment { + public: + virtual void SetUp() { + printf("%s", "BarEnvironment::SetUp() called.\n"); + } + + virtual void TearDown() { + printf("%s", "BarEnvironment::TearDown() called.\n"); + ADD_FAILURE() << "Expected non-fatal failure."; + } +}; + +bool GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = false; + +// The main function. +// +// The idea is to use Google Test to run all the tests we have defined (some +// of them are intended to fail), and then compare the test results +// with the "golden" file. +int main(int argc, char **argv) { + testing::GTEST_FLAG(print_time) = false; + + // We just run the tests, knowing some of them are intended to fail. + // We will use a separate Python script to compare the output of + // this program with the golden file. + + // It's hard to test InitGoogleTest() directly, as it has many + // global side effects. The following line serves as a sanity test + // for it. + testing::InitGoogleTest(&argc, argv); + if (argc >= 2 && + (std::string(argv[1]) == + "--gtest_internal_skip_environment_and_ad_hoc_tests")) + GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; + +#if GTEST_HAS_DEATH_TEST + if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { + // Skip the usual output capturing if we're running as the child + // process of an threadsafe-style death test. +# if GTEST_OS_WINDOWS + posix::FReopen("nul:", "w", stdout); +# else + posix::FReopen("/dev/null", "w", stdout); +# endif // GTEST_OS_WINDOWS + return RUN_ALL_TESTS(); + } +#endif // GTEST_HAS_DEATH_TEST + + if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests)) + return RUN_ALL_TESTS(); + + // Registers two global test environments. + // The golden file verifies that they are set up in the order they + // are registered, and torn down in the reverse order. + testing::AddGlobalTestEnvironment(new FooEnvironment); + testing::AddGlobalTestEnvironment(new BarEnvironment); + + return RunAllTests(); +} diff --git a/src/test/gtest/test/gtest_output_test_golden_lin.txt b/src/test/gtest/test/gtest_output_test_golden_lin.txt new file mode 100644 index 00000000..960eedce --- /dev/null +++ b/src/test/gtest/test/gtest_output_test_golden_lin.txt @@ -0,0 +1,720 @@ +The non-test part of the code is expected to have 2 failures. + +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +gtest_output_test_.cc:#: Failure +Value of: 3 +Expected: 2 +[==========] Running 63 tests from 28 test cases. +[----------] Global test environment set-up. +FooEnvironment::SetUp() called. +BarEnvironment::SetUp() called. +[----------] 1 test from ADeathTest +[ RUN ] ADeathTest.ShouldRunFirst +[ OK ] ADeathTest.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/0, where TypeParam = int +[ RUN ] ATypedDeathTest/0.ShouldRunFirst +[ OK ] ATypedDeathTest/0.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/1, where TypeParam = double +[ RUN ] ATypedDeathTest/1.ShouldRunFirst +[ OK ] ATypedDeathTest/1.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int +[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double +[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst +[----------] 2 tests from PassingTest +[ RUN ] PassingTest.PassingTest1 +[ OK ] PassingTest.PassingTest1 +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] 1 test from NonfatalFailureTest +[ RUN ] NonfatalFailureTest.EscapesStringOperands +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: kGoldenString +Which is: "\"Line" +gtest_output_test_.cc:#: Failure +Value of: actual + Actual: "actual \"string\"" +Expected: golden +Which is: "\"Line" +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[----------] 6 tests from SCOPED_TRACETest +[ RUN ] SCOPED_TRACETest.ObeysScopes +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should have a trace. +Google Test trace: +gtest_output_test_.cc:#: Expected trace +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and shouldn't have a trace. +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ RUN ] SCOPED_TRACETest.WorksInLoop +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: i = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: i = 2 +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ RUN ] SCOPED_TRACETest.WorksInSubroutine +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 1 +Expected: 2 +Google Test trace: +gtest_output_test_.cc:#: n = 1 +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ RUN ] SCOPED_TRACETest.CanBeNested +(expected to fail) +gtest_output_test_.cc:#: Failure +Value of: n + Actual: 2 +Expected: 1 +Google Test trace: +gtest_output_test_.cc:#: n = 2 +gtest_output_test_.cc:#: +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ RUN ] SCOPED_TRACETest.CanBeRepeated +(expected to fail) +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A. +Google Test trace: +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A and B. +Google Test trace: +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and C. +Google Test trace: +gtest_output_test_.cc:#: C +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +gtest_output_test_.cc:#: Failure +Failed +This failure is expected, and should contain trace point A, B, and D. +Google Test trace: +gtest_output_test_.cc:#: D +gtest_output_test_.cc:#: B +gtest_output_test_.cc:#: A +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ RUN ] SCOPED_TRACETest.WorksConcurrently +(expecting 6 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1 (in thread B, only trace B alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2 (in thread A, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3 (in thread B, trace A & B both alive). +Google Test trace: +gtest_output_test_.cc:#: Trace B +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4 (in thread B, only trace A alive). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5 (in thread A, only trace A alive). +Google Test trace: +gtest_output_test_.cc:#: Trace A +gtest_output_test_.cc:#: Failure +Failed +Expected failure #6 (in thread A, no trace alive). +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[----------] 1 test from NonFatalFailureInFixtureConstructorTest +[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 5 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test body. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in TearDown. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #5, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from FatalFailureInFixtureConstructorTest +[ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in the test fixture c'tor. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test fixture d'tor. +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[----------] 1 test from NonFatalFailureInSetUpTest +[ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp +(expecting 4 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in the test function. +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #4, in the test fixture d'tor. +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from FatalFailureInSetUpTest +[ RUN ] FatalFailureInSetUpTest.FailureInSetUp +(expecting 3 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected failure #1, in SetUp(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #2, in TearDown(). +gtest_output_test_.cc:#: Failure +Failed +Expected failure #3, in the test fixture d'tor. +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[----------] 1 test from AddFailureAtTest +[ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +foo.cc:42: Failure +Failed +Expected failure in foo.cc +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[----------] 4 tests from MixedUpTestCaseTest +[ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo +[ RUN ] MixedUpTestCaseTest.ThisShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ RUN ] MixedUpTestCaseTest.ThisShouldFailToo +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseTest, +you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class. However, in test case MixedUpTestCaseWithSameTestNameTest, +you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail +using two different test fixture classes. This can happen if +the two classes are from different namespaces or translation +units and have the same name. You should probably rename one +of the classes to put the tests into different test cases. +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[----------] 2 tests from TEST_F_before_TEST_in_same_test_case +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F +[ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_F_before_TEST_in_same_test_case, +test DefinedUsingTEST_F is defined using TEST_F but +test DefinedUsingTESTAndShouldFail is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[----------] 2 tests from TEST_before_TEST_F_in_same_test_case +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST +[ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +gtest.cc:#: Failure +Failed +All tests in the same test case must use the same test fixture +class, so mixing TEST_F and TEST in the same test case is +illegal. In test case TEST_before_TEST_F_in_same_test_case, +test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but +test DefinedUsingTEST is defined using TEST. You probably +want to change the TEST to TEST_F or move it to another test +case. +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[----------] 8 tests from ExpectNonfatalFailureTest +[ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables +[ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 1. + +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure 2. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[----------] 8 tests from ExpectFatalFailureTest +[ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables +[ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables +[ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 2 failures +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows +(expecting a failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[----------] 2 tests from TypedTest/0, where TypeParam = int +[ RUN ] TypedTest/0.Success +[ OK ] TypedTest/0.Success +[ RUN ] TypedTest/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1 +Expected failure +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char +[ RUN ] Unsigned/TypedTestP/0.Success +[ OK ] Unsigned/TypedTestP/0.Success +[ RUN ] Unsigned/TypedTestP/0.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: '\0' +Expected: 1U +Which is: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int +[ RUN ] Unsigned/TypedTestP/1.Success +[ OK ] Unsigned/TypedTestP/1.Success +[ RUN ] Unsigned/TypedTestP/1.Failure +gtest_output_test_.cc:#: Failure +Value of: TypeParam() + Actual: 0 +Expected: 1U +Which is: 1 +Expected failure +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[----------] 4 tests from ExpectFailureTest +[ RUN ] ExpectFailureTest.ExpectFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ RUN ] ExpectFailureTest.ExpectNonFatalFailure +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 fatal failure containing "Some other fatal failure expected." + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Success: +Succeeded + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: +gtest_output_test_.cc:#: Fatal failure: +Failed +Expected fatal failure. + +(expecting 1 failure) +gtest.cc:#: Failure +Expected: 1 non-fatal failure containing "Some other non-fatal failure." + Actual: +gtest_output_test_.cc:#: Non-fatal failure: +Failed +Expected non-fatal failure. + +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[----------] 2 tests from ExpectFailureWithThreadsTest +[ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest.cc:#: Failure +Expected: 1 fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +gtest.cc:#: Failure +Expected: 1 non-fatal failure + Actual: 0 failures +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[----------] 1 test from ScopedFakeTestPartResultReporterTest +[ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +(expecting 2 failures) +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[----------] 1 test from PrintingFailingParams/FailingParamTest +[ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 +gtest_output_test_.cc:#: Failure +Value of: GetParam() + Actual: 2 +Expected: 1 +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 +[----------] Global test environment tear-down +BarEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected non-fatal failure. +FooEnvironment::TearDown() called. +gtest_output_test_.cc:#: Failure +Failed +Expected fatal failure. +[==========] 63 tests from 28 test cases ran. +[ PASSED ] 21 tests. +[ FAILED ] 42 tests, listed below: +[ FAILED ] NonfatalFailureTest.EscapesStringOperands +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions +[ FAILED ] SCOPED_TRACETest.ObeysScopes +[ FAILED ] SCOPED_TRACETest.WorksInLoop +[ FAILED ] SCOPED_TRACETest.WorksInSubroutine +[ FAILED ] SCOPED_TRACETest.CanBeNested +[ FAILED ] SCOPED_TRACETest.CanBeRepeated +[ FAILED ] SCOPED_TRACETest.WorksConcurrently +[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor +[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] FatalFailureInSetUpTest.FailureInSetUp +[ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber +[ FAILED ] MixedUpTestCaseTest.ThisShouldFail +[ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo +[ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail +[ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail +[ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures +[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns +[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows +[ FAILED ] TypedTest/0.Failure, where TypeParam = int +[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char +[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int +[ FAILED ] ExpectFailureTest.ExpectFatalFailure +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure +[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads +[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads +[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure +[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure +[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread +[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 + +42 FAILED TESTS + YOU HAVE 1 DISABLED TEST + +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +[==========] Running 4 tests from 2 test cases. +[----------] Global test environment set-up. +[----------] 3 tests from FatalFailureTest +[ RUN ] FatalFailureTest.FatalFailureInSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) +[ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine +(expecting a failure that x should be 1) +gtest_output_test_.cc:#: Failure +Value of: x + Actual: 2 +Expected: 1 +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) +[ RUN ] FatalFailureTest.NonfatalFailureInSubroutine +(expecting a failure on false) +gtest_output_test_.cc:#: Failure +Value of: false + Actual: false +Expected: true +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) +[----------] 3 tests from FatalFailureTest (? ms total) + +[----------] 1 test from LoggingTest +[ RUN ] LoggingTest.InterleavingLoggingAndAssertions +(expecting 2 failures on (3) >= (a[i])) +i == 0 +i == 1 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 9 +i == 2 +i == 3 +gtest_output_test_.cc:#: Failure +Expected: (3) >= (a[i]), actual: 3 vs 6 +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) +[----------] 1 test from LoggingTest (? ms total) + +[----------] Global test environment tear-down +[==========] 4 tests from 2 test cases ran. (? ms total) +[ PASSED ] 0 tests. +[ FAILED ] 4 tests, listed below: +[ FAILED ] FatalFailureTest.FatalFailureInSubroutine +[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine +[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine +[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions + + 4 FAILED TESTS +Note: Google Test filter = *DISABLED_* +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from DisabledTestsWarningTest +[ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. +Note: Google Test filter = PassingTest.* +Note: This is test shard 2 of 2. +[==========] Running 1 test from 1 test case. +[----------] Global test environment set-up. +[----------] 1 test from PassingTest +[ RUN ] PassingTest.PassingTest2 +[ OK ] PassingTest.PassingTest2 +[----------] Global test environment tear-down +[==========] 1 test from 1 test case ran. +[ PASSED ] 1 test. diff --git a/src/test/gtest/test/gtest_pred_impl_unittest.cc b/src/test/gtest/test/gtest_pred_impl_unittest.cc new file mode 100644 index 00000000..a84eff86 --- /dev/null +++ b/src/test/gtest/test/gtest_pred_impl_unittest.cc @@ -0,0 +1,2427 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! + +// Regression test for gtest_pred_impl.h +// +// This file is generated by a script and quite long. If you intend to +// learn how Google Test works by reading its unit tests, read +// gtest_unittest.cc instead. +// +// This is intended as a regression test for the Google Test predicate +// assertions. We compile it as part of the gtest_unittest target +// only to keep the implementation tidy and compact, as it is quite +// involved to set up the stage for testing Google Test using Google +// Test itself. +// +// Currently, gtest_unittest takes ~11 seconds to run in the testing +// daemon. In the future, if it grows too large and needs much more +// time to finish, we should consider separating this file into a +// stand-alone regression test. + +#include + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +// A user-defined data type. +struct Bool { + explicit Bool(int val) : value(val != 0) {} + + bool operator>(int n) const { return value > Bool(n).value; } + + Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } + + bool operator==(const Bool& rhs) const { return value == rhs.value; } + + bool value; +}; + +// Enables Bool to be used in assertions. +std::ostream& operator<<(std::ostream& os, const Bool& x) { + return os << (x.value ? "true" : "false"); +} + +// Sample functions/functors for testing unary predicate assertions. + +// A unary predicate function. +template +bool PredFunction1(T1 v1) { + return v1 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction1Int(int v1) { + return v1 > 0; +} +bool PredFunction1Bool(Bool v1) { + return v1 > 0; +} + +// A unary predicate functor. +struct PredFunctor1 { + template + bool operator()(const T1& v1) { + return v1 > 0; + } +}; + +// A unary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction1(const char* e1, + const T1& v1) { + if (PredFunction1(v1)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 + << " is expected to be positive, but evaluates to " + << v1 << "."; +} + +// A unary predicate-formatter functor. +struct PredFormatFunctor1 { + template + testing::AssertionResult operator()(const char* e1, + const T1& v1) const { + return PredFormatFunction1(e1, v1); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT1. + +class Predicate1Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; +}; + +bool Predicate1Test::expected_to_finish_; +bool Predicate1Test::finished_; +int Predicate1Test::n1_; + +typedef Predicate1Test EXPECT_PRED_FORMAT1Test; +typedef Predicate1Test ASSERT_PRED_FORMAT1Test; +typedef Predicate1Test EXPECT_PRED1Test; +typedef Predicate1Test ASSERT_PRED1Test; + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunction1Int, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED1(PredFunction1Bool, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED1(PredFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Int, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunction1Bool, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED1(PredFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(++n1_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + ++n1_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(++n1_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunction1, + Bool(n1_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + n1_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT1 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(PredFormatFunctor1(), + Bool(n1_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing binary predicate assertions. + +// A binary predicate function. +template +bool PredFunction2(T1 v1, T2 v2) { + return v1 + v2 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction2Int(int v1, int v2) { + return v1 + v2 > 0; +} +bool PredFunction2Bool(Bool v1, Bool v2) { + return v1 + v2 > 0; +} + +// A binary predicate functor. +struct PredFunctor2 { + template + bool operator()(const T1& v1, + const T2& v2) { + return v1 + v2 > 0; + } +}; + +// A binary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction2(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) { + if (PredFunction2(v1, v2)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 + << " is expected to be positive, but evaluates to " + << v1 + v2 << "."; +} + +// A binary predicate-formatter functor. +struct PredFormatFunctor2 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const T1& v1, + const T2& v2) const { + return PredFormatFunction2(e1, e2, v1, v2); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT2. + +class Predicate2Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; +}; + +bool Predicate2Test::expected_to_finish_; +bool Predicate2Test::finished_; +int Predicate2Test::n1_; +int Predicate2Test::n2_; + +typedef Predicate2Test EXPECT_PRED_FORMAT2Test; +typedef Predicate2Test ASSERT_PRED_FORMAT2Test; +typedef Predicate2Test EXPECT_PRED2Test; +typedef Predicate2Test ASSERT_PRED2Test; + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunction2Int, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED2(PredFunction2Bool, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED2(PredFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Int, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunction2Bool, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED2(PredFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + ++n1_, + ++n2_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(++n1_), + Bool(++n2_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunction2, + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + n1_++, + n2_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT2 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(PredFormatFunctor2(), + Bool(n1_++), + Bool(n2_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing ternary predicate assertions. + +// A ternary predicate function. +template +bool PredFunction3(T1 v1, T2 v2, T3 v3) { + return v1 + v2 + v3 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction3Int(int v1, int v2, int v3) { + return v1 + v2 + v3 > 0; +} +bool PredFunction3Bool(Bool v1, Bool v2, Bool v3) { + return v1 + v2 + v3 > 0; +} + +// A ternary predicate functor. +struct PredFunctor3 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3) { + return v1 + v2 + v3 > 0; + } +}; + +// A ternary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction3(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) { + if (PredFunction3(v1, v2, v3)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 << "."; +} + +// A ternary predicate-formatter functor. +struct PredFormatFunctor3 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const T1& v1, + const T2& v2, + const T3& v3) const { + return PredFormatFunction3(e1, e2, e3, v1, v2, v3); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT3. + +class Predicate3Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; +}; + +bool Predicate3Test::expected_to_finish_; +bool Predicate3Test::finished_; +int Predicate3Test::n1_; +int Predicate3Test::n2_; +int Predicate3Test::n3_; + +typedef Predicate3Test EXPECT_PRED_FORMAT3Test; +typedef Predicate3Test ASSERT_PRED_FORMAT3Test; +typedef Predicate3Test EXPECT_PRED3Test; +typedef Predicate3Test ASSERT_PRED3Test; + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunction3Int, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED3(PredFunction3Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED3(PredFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Int, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunction3Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(PredFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + ++n1_, + ++n2_, + ++n3_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunction3, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + n1_++, + n2_++, + n3_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT3 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT3(PredFormatFunctor3(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 4-ary predicate assertions. + +// A 4-ary predicate function. +template +bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction4Int(int v1, int v2, int v3, int v4) { + return v1 + v2 + v3 + v4 > 0; +} +bool PredFunction4Bool(Bool v1, Bool v2, Bool v3, Bool v4) { + return v1 + v2 + v3 + v4 > 0; +} + +// A 4-ary predicate functor. +struct PredFunctor4 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + return v1 + v2 + v3 + v4 > 0; + } +}; + +// A 4-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction4(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (PredFunction4(v1, v2, v3, v4)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 << "."; +} + +// A 4-ary predicate-formatter functor. +struct PredFormatFunctor4 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) const { + return PredFormatFunction4(e1, e2, e3, e4, v1, v2, v3, v4); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT4. + +class Predicate4Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; +}; + +bool Predicate4Test::expected_to_finish_; +bool Predicate4Test::finished_; +int Predicate4Test::n1_; +int Predicate4Test::n2_; +int Predicate4Test::n3_; +int Predicate4Test::n4_; + +typedef Predicate4Test EXPECT_PRED_FORMAT4Test; +typedef Predicate4Test ASSERT_PRED_FORMAT4Test; +typedef Predicate4Test EXPECT_PRED4Test; +typedef Predicate4Test ASSERT_PRED4Test; + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunction4Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED4(PredFunction4Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED4(PredFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Int, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunction4Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED4(PredFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + ++n1_, + ++n2_, + ++n3_, + ++n4_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunction4, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + n1_++, + n2_++, + n3_++, + n4_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT4 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT4(PredFormatFunctor4(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++)); + finished_ = true; + }, ""); +} +// Sample functions/functors for testing 5-ary predicate assertions. + +// A 5-ary predicate function. +template +bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// The following two functions are needed to circumvent a bug in +// gcc 2.95.3, which sometimes has problem with the above template +// function. +bool PredFunction5Int(int v1, int v2, int v3, int v4, int v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} +bool PredFunction5Bool(Bool v1, Bool v2, Bool v3, Bool v4, Bool v5) { + return v1 + v2 + v3 + v4 + v5 > 0; +} + +// A 5-ary predicate functor. +struct PredFunctor5 { + template + bool operator()(const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + return v1 + v2 + v3 + v4 + v5 > 0; + } +}; + +// A 5-ary predicate-formatter function. +template +testing::AssertionResult PredFormatFunction5(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (PredFunction5(v1, v2, v3, v4, v5)) + return testing::AssertionSuccess(); + + return testing::AssertionFailure() + << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " is expected to be positive, but evaluates to " + << v1 + v2 + v3 + v4 + v5 << "."; +} + +// A 5-ary predicate-formatter functor. +struct PredFormatFunctor5 { + template + testing::AssertionResult operator()(const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) const { + return PredFormatFunction5(e1, e2, e3, e4, e5, v1, v2, v3, v4, v5); + } +}; + +// Tests for {EXPECT|ASSERT}_PRED_FORMAT5. + +class Predicate5Test : public testing::Test { + protected: + virtual void SetUp() { + expected_to_finish_ = true; + finished_ = false; + n1_ = n2_ = n3_ = n4_ = n5_ = 0; + } + + virtual void TearDown() { + // Verifies that each of the predicate's arguments was evaluated + // exactly once. + EXPECT_EQ(1, n1_) << + "The predicate assertion didn't evaluate argument 2 " + "exactly once."; + EXPECT_EQ(1, n2_) << + "The predicate assertion didn't evaluate argument 3 " + "exactly once."; + EXPECT_EQ(1, n3_) << + "The predicate assertion didn't evaluate argument 4 " + "exactly once."; + EXPECT_EQ(1, n4_) << + "The predicate assertion didn't evaluate argument 5 " + "exactly once."; + EXPECT_EQ(1, n5_) << + "The predicate assertion didn't evaluate argument 6 " + "exactly once."; + + // Verifies that the control flow in the test function is expected. + if (expected_to_finish_ && !finished_) { + FAIL() << "The predicate assertion unexpactedly aborted the test."; + } else if (!expected_to_finish_ && finished_) { + FAIL() << "The failed predicate assertion didn't abort the test " + "as expected."; + } + } + + // true iff the test function is expected to run to finish. + static bool expected_to_finish_; + + // true iff the test function did run to finish. + static bool finished_; + + static int n1_; + static int n2_; + static int n3_; + static int n4_; + static int n5_; +}; + +bool Predicate5Test::expected_to_finish_; +bool Predicate5Test::finished_; +int Predicate5Test::n1_; +int Predicate5Test::n2_; +int Predicate5Test::n3_; +int Predicate5Test::n4_; +int Predicate5Test::n5_; + +typedef Predicate5Test EXPECT_PRED_FORMAT5Test; +typedef Predicate5Test ASSERT_PRED_FORMAT5Test; +typedef Predicate5Test EXPECT_PRED5Test; +typedef Predicate5Test ASSERT_PRED5Test; + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunction5Int, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED5(PredFunction5Bool, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED5(PredFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Int, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunction5Bool, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED5(PredFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed EXPECT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + ++n1_, + ++n2_, + ++n3_, + ++n4_, + ++n5_); + finished_ = true; +} + +// Tests a successful ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(++n1_), + Bool(++n2_), + Bool(++n3_), + Bool(++n4_), + Bool(++n5_)); + finished_ = true; +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a function on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunction5, + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a built-in type (int). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + n1_++, + n2_++, + n3_++, + n4_++, + n5_++); + finished_ = true; + }, ""); +} + +// Tests a failed ASSERT_PRED_FORMAT5 where the +// predicate-formatter is a functor on a user-defined type (Bool). +TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { + expected_to_finish_ = false; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(PredFormatFunctor5(), + Bool(n1_++), + Bool(n2_++), + Bool(n3_++), + Bool(n4_++), + Bool(n5_++)); + finished_ = true; + }, ""); +} diff --git a/src/test/gtest/test/gtest_premature_exit_test.cc b/src/test/gtest/test/gtest_premature_exit_test.cc new file mode 100644 index 00000000..c1ed9686 --- /dev/null +++ b/src/test/gtest/test/gtest_premature_exit_test.cc @@ -0,0 +1,143 @@ +// Copyright 2013, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests that Google Test manipulates the premature-exit-detection +// file correctly. + +#include + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::internal::posix::GetEnv; +using ::testing::internal::posix::Stat; +using ::testing::internal::posix::StatStruct; + +namespace { + +// Is the TEST_PREMATURE_EXIT_FILE environment variable expected to be +// set? +const bool kTestPrematureExitFileEnvVarShouldBeSet = false; + +class PrematureExitTest : public Test { + public: + // Returns true iff the given file exists. + static bool FileExists(const char* filepath) { + StatStruct stat; + return Stat(filepath, &stat) == 0; + } + + protected: + PrematureExitTest() { + premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE"); + + // Normalize NULL to "" for ease of handling. + if (premature_exit_file_path_ == NULL) { + premature_exit_file_path_ = ""; + } + } + + // Returns true iff the premature-exit file exists. + bool PrematureExitFileExists() const { + return FileExists(premature_exit_file_path_); + } + + const char* premature_exit_file_path_; +}; + +typedef PrematureExitTest PrematureExitDeathTest; + +// Tests that: +// - the premature-exit file exists during the execution of a +// death test (EXPECT_DEATH*), and +// - a death test doesn't interfere with the main test process's +// handling of the premature-exit file. +TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_DEATH_IF_SUPPORTED({ + // If the file exists, crash the process such that the main test + // process will catch the (expected) crash and report a success; + // otherwise don't crash, which will cause the main test process + // to report that the death test has failed. + if (PrematureExitFileExists()) { + exit(1); + } + }, ""); +} + +// Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to +// be set. +TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { + GTEST_INTENTIONAL_CONST_COND_PUSH_() + if (kTestPrematureExitFileEnvVarShouldBeSet) { + GTEST_INTENTIONAL_CONST_COND_POP_() + const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); + ASSERT_TRUE(filepath != NULL); + ASSERT_NE(*filepath, '\0'); + } +} + +// Tests that the premature-exit file exists during the execution of a +// normal (non-death) test. +TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) { + if (*premature_exit_file_path_ == '\0') { + return; + } + + EXPECT_TRUE(PrematureExitFileExists()) + << " file " << premature_exit_file_path_ + << " should exist during test execution, but doesn't."; +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + const int exit_code = RUN_ALL_TESTS(); + + // Test that the premature-exit file is deleted upon return from + // RUN_ALL_TESTS(). + const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); + if (filepath != NULL && *filepath != '\0') { + if (PrematureExitTest::FileExists(filepath)) { + printf( + "File %s shouldn't exist after the test program finishes, but does.", + filepath); + return 1; + } + } + + return exit_code; +} diff --git a/src/test/gtest/test/gtest_prod_test.cc b/src/test/gtest/test/gtest_prod_test.cc new file mode 100644 index 00000000..060abce1 --- /dev/null +++ b/src/test/gtest/test/gtest_prod_test.cc @@ -0,0 +1,57 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Unit test for include/gtest/gtest_prod.h. + +#include "gtest/gtest.h" +#include "test/production.h" + +// Tests that private members can be accessed from a TEST declared as +// a friend of the class. +TEST(PrivateCodeTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(1); + EXPECT_EQ(1, a.x_); +} + +typedef testing::Test PrivateCodeFixtureTest; + +// Tests that private members can be accessed from a TEST_F declared +// as a friend of the class. +TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) { + PrivateCode a; + EXPECT_EQ(0, a.x_); + + a.set_x(2); + EXPECT_EQ(2, a.x_); +} diff --git a/src/test/gtest/test/gtest_repeat_test.cc b/src/test/gtest/test/gtest_repeat_test.cc new file mode 100644 index 00000000..481012ad --- /dev/null +++ b/src/test/gtest/test/gtest_repeat_test.cc @@ -0,0 +1,253 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests the --gtest_repeat=number flag. + +#include +#include +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +GTEST_DECLARE_string_(death_test_style); +GTEST_DECLARE_string_(filter); +GTEST_DECLARE_int32_(repeat); + +} // namespace testing + +using testing::GTEST_FLAG(death_test_style); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(repeat); + +namespace { + +// We need this when we are testing Google Test itself and therefore +// cannot use Google Test assertions. +#define GTEST_CHECK_INT_EQ_(expected, actual) \ + do {\ + const int expected_val = (expected);\ + const int actual_val = (actual);\ + if (::testing::internal::IsTrue(expected_val != actual_val)) {\ + ::std::cout << "Value of: " #actual "\n"\ + << " Actual: " << actual_val << "\n"\ + << "Expected: " #expected "\n"\ + << "Which is: " << expected_val << "\n";\ + ::testing::internal::posix::Abort();\ + }\ + } while (::testing::internal::AlwaysFalse()) + + +// Used for verifying that global environment set-up and tear-down are +// inside the gtest_repeat loop. + +int g_environment_set_up_count = 0; +int g_environment_tear_down_count = 0; + +class MyEnvironment : public testing::Environment { + public: + MyEnvironment() {} + virtual void SetUp() { g_environment_set_up_count++; } + virtual void TearDown() { g_environment_tear_down_count++; } +}; + +// A test that should fail. + +int g_should_fail_count = 0; + +TEST(FooTest, ShouldFail) { + g_should_fail_count++; + EXPECT_EQ(0, 1) << "Expected failure."; +} + +// A test that should pass. + +int g_should_pass_count = 0; + +TEST(FooTest, ShouldPass) { + g_should_pass_count++; +} + +// A test that contains a thread-safe death test and a fast death +// test. It should pass. + +int g_death_test_count = 0; + +TEST(BarDeathTest, ThreadSafeAndFast) { + g_death_test_count++; + + GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); + + GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); +} + +#if GTEST_HAS_PARAM_TEST +int g_param_test_count = 0; + +const int kNumberOfParamTests = 10; + +class MyParamTest : public testing::TestWithParam {}; + +TEST_P(MyParamTest, ShouldPass) { + // TODO(vladl@google.com): Make parameter value checking robust + // WRT order of tests. + GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam()); + g_param_test_count++; +} +INSTANTIATE_TEST_CASE_P(MyParamSequence, + MyParamTest, + testing::Range(0, kNumberOfParamTests)); +#endif // GTEST_HAS_PARAM_TEST + +// Resets the count for each test. +void ResetCounts() { + g_environment_set_up_count = 0; + g_environment_tear_down_count = 0; + g_should_fail_count = 0; + g_should_pass_count = 0; + g_death_test_count = 0; +#if GTEST_HAS_PARAM_TEST + g_param_test_count = 0; +#endif // GTEST_HAS_PARAM_TEST +} + +// Checks that the count for each test is expected. +void CheckCounts(int expected) { + GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); + GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); + GTEST_CHECK_INT_EQ_(expected, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +// Tests the behavior of Google Test when --gtest_repeat is not specified. +void TestRepeatUnspecified() { + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + CheckCounts(1); +} + +// Tests the behavior of Google Test when --gtest_repeat has the given value. +void TestRepeat(int repeat) { + GTEST_FLAG(repeat) = repeat; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS()); + CheckCounts(repeat); +} + +// Tests using --gtest_repeat when --gtest_filter specifies an empty +// set of tests. +void TestRepeatWithEmptyFilter(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "None"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + CheckCounts(0); +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// successful tests. +void TestRepeatWithFilterForSuccessfulTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*-*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(0, g_should_fail_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); + GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +// Tests using --gtest_repeat when --gtest_filter specifies a set of +// failed tests. +void TestRepeatWithFilterForFailedTests(int repeat) { + GTEST_FLAG(repeat) = repeat; + GTEST_FLAG(filter) = "*ShouldFail"; + + ResetCounts(); + GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); + GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); + GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); + GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); + GTEST_CHECK_INT_EQ_(0, g_should_pass_count); + GTEST_CHECK_INT_EQ_(0, g_death_test_count); +#if GTEST_HAS_PARAM_TEST + GTEST_CHECK_INT_EQ_(0, g_param_test_count); +#endif // GTEST_HAS_PARAM_TEST +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + testing::AddGlobalTestEnvironment(new MyEnvironment); + + TestRepeatUnspecified(); + TestRepeat(0); + TestRepeat(1); + TestRepeat(5); + + TestRepeatWithEmptyFilter(2); + TestRepeatWithEmptyFilter(3); + + TestRepeatWithFilterForSuccessfulTests(3); + + TestRepeatWithFilterForFailedTests(4); + + // It would be nice to verify that the tests indeed loop forever + // when GTEST_FLAG(repeat) is negative, but this test will be quite + // complicated to write. Since this flag is for interactive + // debugging only and doesn't affect the normal test result, such a + // test would be an overkill. + + printf("PASS\n"); + return 0; +} diff --git a/src/test/gtest/test/gtest_shuffle_test.py b/src/test/gtest/test/gtest_shuffle_test.py new file mode 100755 index 00000000..30d0303d --- /dev/null +++ b/src/test/gtest/test/gtest_shuffle_test.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# +# Copyright 2009 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Verifies that test shuffling works.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + +# Command to run the gtest_shuffle_test_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_') + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' + +TEST_FILTER = 'A*.A:A*.B:C*' + +ALL_TESTS = [] +ACTIVE_TESTS = [] +FILTERED_TESTS = [] +SHARDED_TESTS = [] + +SHUFFLED_ALL_TESTS = [] +SHUFFLED_ACTIVE_TESTS = [] +SHUFFLED_FILTERED_TESTS = [] +SHUFFLED_SHARDED_TESTS = [] + + +def AlsoRunDisabledTestsFlag(): + return '--gtest_also_run_disabled_tests' + + +def FilterFlag(test_filter): + return '--gtest_filter=%s' % (test_filter,) + + +def RepeatFlag(n): + return '--gtest_repeat=%s' % (n,) + + +def ShuffleFlag(): + return '--gtest_shuffle' + + +def RandomSeedFlag(n): + return '--gtest_random_seed=%s' % (n,) + + +def RunAndReturnOutput(extra_env, args): + """Runs the test program and returns its output.""" + + environ_copy = os.environ.copy() + environ_copy.update(extra_env) + + return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output + + +def GetTestsForAllIterations(extra_env, args): + """Runs the test program and returns a list of test lists. + + Args: + extra_env: a map from environment variables to their values + args: command line flags to pass to gtest_shuffle_test_ + + Returns: + A list where the i-th element is the list of tests run in the i-th + test iteration. + """ + + test_iterations = [] + for line in RunAndReturnOutput(extra_env, args).split('\n'): + if line.startswith('----'): + tests = [] + test_iterations.append(tests) + elif line.strip(): + tests.append(line.strip()) # 'TestCaseName.TestName' + + return test_iterations + + +def GetTestCases(tests): + """Returns a list of test cases in the given full test names. + + Args: + tests: a list of full test names + + Returns: + A list of test cases from 'tests', in their original order. + Consecutive duplicates are removed. + """ + + test_cases = [] + for test in tests: + test_case = test.split('.')[0] + if not test_case in test_cases: + test_cases.append(test_case) + + return test_cases + + +def CalculateTestLists(): + """Calculates the list of tests run under different flags.""" + + if not ALL_TESTS: + ALL_TESTS.extend( + GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) + + if not ACTIVE_TESTS: + ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) + + if not FILTERED_TESTS: + FILTERED_TESTS.extend( + GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) + + if not SHARDED_TESTS: + SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [])[0]) + + if not SHUFFLED_ALL_TESTS: + SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( + {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_ACTIVE_TESTS: + SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_FILTERED_TESTS: + SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) + + if not SHUFFLED_SHARDED_TESTS: + SHUFFLED_SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + +class GTestShuffleUnitTest(gtest_test_utils.TestCase): + """Tests test shuffling.""" + + def setUp(self): + CalculateTestLists() + + def testShufflePreservesNumberOfTests(self): + self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) + self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) + self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) + self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) + + def testShuffleChangesTestOrder(self): + self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + SHUFFLED_FILTERED_TESTS) + self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + SHUFFLED_SHARDED_TESTS) + + def testShuffleChangesTestCaseOrder(self): + self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + GetTestCases(SHUFFLED_ALL_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), + GetTestCases(SHUFFLED_ACTIVE_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), + GetTestCases(SHUFFLED_FILTERED_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), + GetTestCases(SHUFFLED_SHARDED_TESTS)) + + def testShuffleDoesNotRepeatTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), + '%s appears more than once' % (test,)) + + def testShuffleDoesNotCreateNewTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + + def testShuffleIncludesAllTests(self): + for test in ALL_TESTS: + self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + for test in ACTIVE_TESTS: + self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + for test in FILTERED_TESTS: + self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + for test in SHARDED_TESTS: + self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + + def testShuffleLeavesDeathTestsAtFront(self): + non_death_test_found = False + for test in SHUFFLED_ACTIVE_TESTS: + if 'DeathTest.' in test: + self.assert_(not non_death_test_found, + '%s appears after a non-death test' % (test,)) + else: + non_death_test_found = True + + def _VerifyTestCasesDoNotInterleave(self, tests): + test_cases = [] + for test in tests: + [test_case, _] = test.split('.') + if test_cases and test_cases[-1] != test_case: + test_cases.append(test_case) + self.assertEqual(1, test_cases.count(test_case), + 'Test case %s is not grouped together in %s' % + (test_case, tests)) + + def testShuffleDoesNotInterleaveTestCases(self): + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) + + def testShuffleRestoresOrderAfterEachIteration(self): + # Get the test lists in all 3 iterations, using random seed 1, 2, + # and 3 respectively. Google Test picks a different seed in each + # iteration, and this test depends on the current implementation + # picking successive numbers. This dependency is not ideal, but + # makes the test much easier to write. + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + # Make sure running the tests with random seed 1 gets the same + # order as in iteration 1 above. + [tests_with_seed1] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)]) + self.assertEqual(tests_in_iteration1, tests_with_seed1) + + # Make sure running the tests with random seed 2 gets the same + # order as in iteration 2 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 2. + [tests_with_seed2] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(2)]) + self.assertEqual(tests_in_iteration2, tests_with_seed2) + + # Make sure running the tests with random seed 3 gets the same + # order as in iteration 3 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 3. + [tests_with_seed3] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(3)]) + self.assertEqual(tests_in_iteration3, tests_with_seed3) + + def testShuffleGeneratesNewOrderInEachIteration(self): + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + self.assert_(tests_in_iteration1 != tests_in_iteration2, + tests_in_iteration1) + self.assert_(tests_in_iteration1 != tests_in_iteration3, + tests_in_iteration1) + self.assert_(tests_in_iteration2 != tests_in_iteration3, + tests_in_iteration2) + + def testShuffleShardedTestsPreservesPartition(self): + # If we run M tests on N shards, the same M tests should be run in + # total, regardless of the random seeds used by the shards. + [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '0'}, + [ShuffleFlag(), RandomSeedFlag(1)]) + [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(20)]) + [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '2'}, + [ShuffleFlag(), RandomSeedFlag(25)]) + sorted_sharded_tests = tests1 + tests2 + tests3 + sorted_sharded_tests.sort() + sorted_active_tests = [] + sorted_active_tests.extend(ACTIVE_TESTS) + sorted_active_tests.sort() + self.assertEqual(sorted_active_tests, sorted_sharded_tests) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_shuffle_test_.cc b/src/test/gtest/test/gtest_shuffle_test_.cc new file mode 100644 index 00000000..6fb441bd --- /dev/null +++ b/src/test/gtest/test/gtest_shuffle_test_.cc @@ -0,0 +1,103 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Verifies that test shuffling works. + +#include "gtest/gtest.h" + +namespace { + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::UnitTest; +using ::testing::internal::scoped_ptr; + +// The test methods are empty, as the sole purpose of this program is +// to print the test names before/after shuffling. + +class A : public Test {}; +TEST_F(A, A) {} +TEST_F(A, B) {} + +TEST(ADeathTest, A) {} +TEST(ADeathTest, B) {} +TEST(ADeathTest, C) {} + +TEST(B, A) {} +TEST(B, B) {} +TEST(B, C) {} +TEST(B, DISABLED_D) {} +TEST(B, DISABLED_E) {} + +TEST(BDeathTest, A) {} +TEST(BDeathTest, B) {} + +TEST(C, A) {} +TEST(C, B) {} +TEST(C, C) {} +TEST(C, DISABLED_D) {} + +TEST(CDeathTest, A) {} + +TEST(DISABLED_D, A) {} +TEST(DISABLED_D, DISABLED_B) {} + +// This printer prints the full test names only, starting each test +// iteration with a "----" marker. +class TestNamePrinter : public EmptyTestEventListener { + public: + virtual void OnTestIterationStart(const UnitTest& /* unit_test */, + int /* iteration */) { + printf("----\n"); + } + + virtual void OnTestStart(const TestInfo& test_info) { + printf("%s.%s\n", test_info.test_case_name(), test_info.name()); + } +}; + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + // Replaces the default printer with TestNamePrinter, which prints + // the test name only. + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new TestNamePrinter); + + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_sole_header_test.cc b/src/test/gtest/test/gtest_sole_header_test.cc new file mode 100644 index 00000000..ccd091a2 --- /dev/null +++ b/src/test/gtest/test/gtest_sole_header_test.cc @@ -0,0 +1,57 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: mheule@google.com (Markus Heule) +// +// This test verifies that it's possible to use Google Test by including +// the gtest.h header file alone. + +#include "gtest/gtest.h" + +namespace { + +void Subroutine() { + EXPECT_EQ(42, 42); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailure) { + EXPECT_NO_FATAL_FAILURE(;); + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + EXPECT_NO_FATAL_FAILURE(Subroutine()); + EXPECT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +TEST(NoFatalFailureTest, AssertNoFatalFailure) { + ASSERT_NO_FATAL_FAILURE(;); + ASSERT_NO_FATAL_FAILURE(SUCCEED()); + ASSERT_NO_FATAL_FAILURE(Subroutine()); + ASSERT_NO_FATAL_FAILURE({ SUCCEED(); }); +} + +} // namespace diff --git a/src/test/gtest/test/gtest_stress_test.cc b/src/test/gtest/test/gtest_stress_test.cc new file mode 100644 index 00000000..e7daa430 --- /dev/null +++ b/src/test/gtest/test/gtest_stress_test.cc @@ -0,0 +1,256 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests that SCOPED_TRACE() and various Google Test assertions can be +// used in a large number of threads concurrently. + +#include "gtest/gtest.h" + +#include +#include + +// We must define this macro in order to #include +// gtest-internal-inl.h. This is how Google Test prevents a user from +// accidentally depending on its internal implementation. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_IS_THREADSAFE + +namespace testing { +namespace { + +using internal::Notification; +using internal::TestPropertyKeyIs; +using internal::ThreadWithParam; +using internal::scoped_ptr; + +// In order to run tests in this file, for platforms where Google Test is +// thread safe, implement ThreadWithParam. See the description of its API +// in gtest-port.h, where it is defined for already supported platforms. + +// How many threads to create? +const int kThreadCount = 50; + +std::string IdToKey(int id, const char* suffix) { + Message key; + key << "key_" << id << "_" << suffix; + return key.GetString(); +} + +std::string IdToString(int id) { + Message id_message; + id_message << id; + return id_message.GetString(); +} + +void ExpectKeyAndValueWereRecordedForId( + const std::vector& properties, + int id, const char* suffix) { + TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); + const std::vector::const_iterator property = + std::find_if(properties.begin(), properties.end(), matches_key); + ASSERT_TRUE(property != properties.end()) + << "expecting " << suffix << " value for id " << id; + EXPECT_STREQ(IdToString(id).c_str(), property->value()); +} + +// Calls a large number of Google Test assertions, where exactly one of them +// will fail. +void ManyAsserts(int id) { + GTEST_LOG_(INFO) << "Thread #" << id << " running..."; + + SCOPED_TRACE(Message() << "Thread #" << id); + + for (int i = 0; i < kThreadCount; i++) { + SCOPED_TRACE(Message() << "Iteration #" << i); + + // A bunch of assertions that should succeed. + EXPECT_TRUE(true); + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_STREQ("a", "a"); + ASSERT_LE(5, 6); + EXPECT_EQ(i, i) << "This shouldn't fail."; + + // RecordProperty() should interact safely with other threads as well. + // The shared_key forces property updates. + Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str()); + Test::RecordProperty(IdToKey(id, "int").c_str(), id); + Test::RecordProperty("shared_key", IdToString(id).c_str()); + + // This assertion should fail kThreadCount times per thread. It + // is for testing whether Google Test can handle failed assertions in a + // multi-threaded context. + EXPECT_LT(i, 0) << "This should always fail."; + } +} + +void CheckTestFailureCount(int expected_failures) { + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + GTEST_CHECK_(expected_failures == result->total_part_count()) + << "Logged " << result->total_part_count() << " failures " + << " vs. " << expected_failures << " expected"; +} + +// Tests using SCOPED_TRACE() and Google Test assertions in many threads +// concurrently. +TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { + { + scoped_ptr > threads[kThreadCount]; + Notification threads_can_start; + for (int i = 0; i != kThreadCount; i++) + threads[i].reset(new ThreadWithParam(&ManyAsserts, + i, + &threads_can_start)); + + threads_can_start.Notify(); + + // Blocks until all the threads are done. + for (int i = 0; i != kThreadCount; i++) + threads[i]->Join(); + } + + // Ensures that kThreadCount*kThreadCount failures have been reported. + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult* const result = info->result(); + + std::vector properties; + // We have no access to the TestResult's list of properties but we can + // copy them one by one. + for (int i = 0; i < result->test_property_count(); ++i) + properties.push_back(result->GetTestProperty(i)); + + EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count()) + << "String and int values recorded on each thread, " + << "as well as one shared_key"; + for (int i = 0; i < kThreadCount; ++i) { + ExpectKeyAndValueWereRecordedForId(properties, i, "string"); + ExpectKeyAndValueWereRecordedForId(properties, i, "int"); + } + CheckTestFailureCount(kThreadCount*kThreadCount); +} + +void FailingThread(bool is_fatal) { + if (is_fatal) + FAIL() << "Fatal failure in some other thread. " + << "(This failure is expected.)"; + else + ADD_FAILURE() << "Non-fatal failure in some other thread. " + << "(This failure is expected.)"; +} + +void GenerateFatalFailureInAnotherThread(bool is_fatal) { + ThreadWithParam thread(&FailingThread, is_fatal, NULL); + thread.Join(); +} + +TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { + EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +void AssertNoFatalFailureIgnoresFailuresInOtherThreads() { + ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); +} +TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { + // Using a subroutine, to make sure, that the test continues. + AssertNoFatalFailureIgnoresFailuresInOtherThreads(); + // We should only have one failure (the one from + // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE + // should succeed. + CheckTestFailureCount(1); +} + +TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(2); +} + +TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(true), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures. + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { + // This statement should fail, since the current thread doesn't generate a + // fatal failure, only another one does. + EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false), + "expected"); + CheckTestFailureCount(2); +} + +TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { + // This statement should succeed, because failures in all threads are + // considered. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + GenerateFatalFailureInAnotherThread(false), "expected"); + CheckTestFailureCount(0); + // We need to add a failure, because main() checks that there are failures, + // But when only this test is run, we shouldn't have any failures. + ADD_FAILURE() << "This is an expected non-fatal failure."; +} + +} // namespace +} // namespace testing + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + const int result = RUN_ALL_TESTS(); // Expected to fail. + GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected"; + + printf("\nPASS\n"); + return 0; +} + +#else +TEST(StressTest, + DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) { +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif // GTEST_IS_THREADSAFE diff --git a/src/test/gtest/test/gtest_test_utils.py b/src/test/gtest/test/gtest_test_utils.py new file mode 100755 index 00000000..7e3cbcaf --- /dev/null +++ b/src/test/gtest/test/gtest_test_utils.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Unit test utilities for Google C++ Testing Framework.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import atexit +import os +import shutil +import sys +import tempfile +import unittest +_test_module = unittest + +# Suppresses the 'Import not at the top of the file' lint complaint. +# pylint: disable-msg=C6204 +try: + import subprocess + _SUBPROCESS_MODULE_AVAILABLE = True +except: + import popen2 + _SUBPROCESS_MODULE_AVAILABLE = False +# pylint: enable-msg=C6204 + +GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT' + +IS_WINDOWS = os.name == 'nt' +IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] + +# The environment variable for specifying the path to the premature-exit file. +PREMATURE_EXIT_FILE_ENV_VAR = 'TEST_PREMATURE_EXIT_FILE' + +environ = os.environ.copy() + + +def SetEnvVar(env_var, value): + """Sets/unsets an environment variable to a given value.""" + + if value is not None: + environ[env_var] = value + elif env_var in environ: + del environ[env_var] + + +# Here we expose a class from a particular module, depending on the +# environment. The comment suppresses the 'Invalid variable name' lint +# complaint. +TestCase = _test_module.TestCase # pylint: disable-msg=C6409 + +# Initially maps a flag to its default value. After +# _ParseAndStripGTestFlags() is called, maps a flag to its actual value. +_flag_map = {'source_dir': os.path.dirname(sys.argv[0]), + 'build_dir': os.path.dirname(sys.argv[0])} +_gtest_flags_are_parsed = False + + +def _ParseAndStripGTestFlags(argv): + """Parses and strips Google Test flags from argv. This is idempotent.""" + + # Suppresses the lint complaint about a global variable since we need it + # here to maintain module-wide state. + global _gtest_flags_are_parsed # pylint: disable-msg=W0603 + if _gtest_flags_are_parsed: + return + + _gtest_flags_are_parsed = True + for flag in _flag_map: + # The environment variable overrides the default value. + if flag.upper() in os.environ: + _flag_map[flag] = os.environ[flag.upper()] + + # The command line flag overrides the environment variable. + i = 1 # Skips the program name. + while i < len(argv): + prefix = '--' + flag + '=' + if argv[i].startswith(prefix): + _flag_map[flag] = argv[i][len(prefix):] + del argv[i] + break + else: + # We don't increment i in case we just found a --gtest_* flag + # and removed it from argv. + i += 1 + + +def GetFlag(flag): + """Returns the value of the given flag.""" + + # In case GetFlag() is called before Main(), we always call + # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags + # are parsed. + _ParseAndStripGTestFlags(sys.argv) + + return _flag_map[flag] + + +def GetSourceDir(): + """Returns the absolute path of the directory where the .py files are.""" + + return os.path.abspath(GetFlag('source_dir')) + + +def GetBuildDir(): + """Returns the absolute path of the directory where the test binaries are.""" + + return os.path.abspath(GetFlag('build_dir')) + + +_temp_dir = None + +def _RemoveTempDir(): + if _temp_dir: + shutil.rmtree(_temp_dir, ignore_errors=True) + +atexit.register(_RemoveTempDir) + + +def GetTempDir(): + """Returns a directory for temporary files.""" + + global _temp_dir + if not _temp_dir: + _temp_dir = tempfile.mkdtemp() + return _temp_dir + + +def GetTestExecutablePath(executable_name, build_dir=None): + """Returns the absolute path of the test binary given its name. + + The function will print a message and abort the program if the resulting file + doesn't exist. + + Args: + executable_name: name of the test binary that the test script runs. + build_dir: directory where to look for executables, by default + the result of GetBuildDir(). + + Returns: + The absolute path of the test binary. + """ + + path = os.path.abspath(os.path.join(build_dir or GetBuildDir(), + executable_name)) + if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'): + path += '.exe' + + if not os.path.exists(path): + message = ( + 'Unable to find the test binary "%s". Please make sure to provide\n' + 'a path to the binary via the --build_dir flag or the BUILD_DIR\n' + 'environment variable.' % path) + print >> sys.stderr, message + sys.exit(1) + + return path + + +def GetExitStatus(exit_code): + """Returns the argument to exit(), or -1 if exit() wasn't called. + + Args: + exit_code: the result value of os.system(command). + """ + + if os.name == 'nt': + # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns + # the argument to exit() directly. + return exit_code + else: + # On Unix, os.WEXITSTATUS() must be used to extract the exit status + # from the result of os.system(). + if os.WIFEXITED(exit_code): + return os.WEXITSTATUS(exit_code) + else: + return -1 + + +class Subprocess: + def __init__(self, command, working_dir=None, capture_stderr=True, env=None): + """Changes into a specified directory, if provided, and executes a command. + + Restores the old directory afterwards. + + Args: + command: The command to run, in the form of sys.argv. + working_dir: The directory to change into. + capture_stderr: Determines whether to capture stderr in the output member + or to discard it. + env: Dictionary with environment to pass to the subprocess. + + Returns: + An object that represents outcome of the executed process. It has the + following attributes: + terminated_by_signal True iff the child process has been terminated + by a signal. + signal Sygnal that terminated the child process. + exited True iff the child process exited normally. + exit_code The code with which the child process exited. + output Child process's stdout and stderr output + combined in a string. + """ + + # The subprocess module is the preferrable way of running programs + # since it is available and behaves consistently on all platforms, + # including Windows. But it is only available starting in python 2.4. + # In earlier python versions, we revert to the popen2 module, which is + # available in python 2.0 and later but doesn't provide required + # functionality (Popen4) under Windows. This allows us to support Mac + # OS X 10.4 Tiger, which has python 2.3 installed. + if _SUBPROCESS_MODULE_AVAILABLE: + if capture_stderr: + stderr = subprocess.STDOUT + else: + stderr = subprocess.PIPE + + p = subprocess.Popen(command, + stdout=subprocess.PIPE, stderr=stderr, + cwd=working_dir, universal_newlines=True, env=env) + # communicate returns a tuple with the file obect for the child's + # output. + self.output = p.communicate()[0] + self._return_code = p.returncode + else: + old_dir = os.getcwd() + + def _ReplaceEnvDict(dest, src): + # Changes made by os.environ.clear are not inheritable by child + # processes until Python 2.6. To produce inheritable changes we have + # to delete environment items with the del statement. + for key in dest.keys(): + del dest[key] + dest.update(src) + + # When 'env' is not None, backup the environment variables and replace + # them with the passed 'env'. When 'env' is None, we simply use the + # current 'os.environ' for compatibility with the subprocess.Popen + # semantics used above. + if env is not None: + old_environ = os.environ.copy() + _ReplaceEnvDict(os.environ, env) + + try: + if working_dir is not None: + os.chdir(working_dir) + if capture_stderr: + p = popen2.Popen4(command) + else: + p = popen2.Popen3(command) + p.tochild.close() + self.output = p.fromchild.read() + ret_code = p.wait() + finally: + os.chdir(old_dir) + + # Restore the old environment variables + # if they were replaced. + if env is not None: + _ReplaceEnvDict(os.environ, old_environ) + + # Converts ret_code to match the semantics of + # subprocess.Popen.returncode. + if os.WIFSIGNALED(ret_code): + self._return_code = -os.WTERMSIG(ret_code) + else: # os.WIFEXITED(ret_code) should return True here. + self._return_code = os.WEXITSTATUS(ret_code) + + if self._return_code < 0: + self.terminated_by_signal = True + self.exited = False + self.signal = -self._return_code + else: + self.terminated_by_signal = False + self.exited = True + self.exit_code = self._return_code + + +def Main(): + """Runs the unit test.""" + + # We must call _ParseAndStripGTestFlags() before calling + # unittest.main(). Otherwise the latter will be confused by the + # --gtest_* flags. + _ParseAndStripGTestFlags(sys.argv) + # The tested binaries should not be writing XML output files unless the + # script explicitly instructs them to. + # TODO(vladl@google.com): Move this into Subprocess when we implement + # passing environment into it as a parameter. + if GTEST_OUTPUT_VAR_NAME in os.environ: + del os.environ[GTEST_OUTPUT_VAR_NAME] + + _test_module.main() diff --git a/src/test/gtest/test/gtest_throw_on_failure_ex_test.cc b/src/test/gtest/test/gtest_throw_on_failure_ex_test.cc new file mode 100644 index 00000000..8d46c76f --- /dev/null +++ b/src/test/gtest/test/gtest_throw_on_failure_ex_test.cc @@ -0,0 +1,92 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Test's throw-on-failure mode with exceptions enabled. + +#include "gtest/gtest.h" + +#include +#include +#include +#include + +// Prints the given failure message and exits the program with +// non-zero. We use this instead of a Google Test assertion to +// indicate a failure, as the latter is been tested and cannot be +// relied on. +void Fail(const char* msg) { + printf("FAILURE: %s\n", msg); + fflush(stdout); + exit(1); +} + +// Tests that an assertion failure throws a subclass of +// std::runtime_error. +void TestFailureThrowsRuntimeError() { + testing::GTEST_FLAG(throw_on_failure) = true; + + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 3); + } catch(...) { + Fail("A successful assertion wrongfully threw."); + } + + // A failed assertion should throw a subclass of std::runtime_error. + try { + EXPECT_EQ(2, 3) << "Expected failure"; + } catch(const std::runtime_error& e) { + if (strstr(e.what(), "Expected failure") != NULL) + return; + + printf("%s", + "A failed assertion did throw an exception of the right type, " + "but the message is incorrect. Instead of containing \"Expected " + "failure\", it is:\n"); + Fail(e.what()); + } catch(...) { + Fail("A failed assertion threw the wrong type of exception."); + } + Fail("A failed assertion should've thrown but didn't."); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the thrown-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + TestFailureThrowsRuntimeError(); + return 0; +} diff --git a/src/test/gtest/test/gtest_throw_on_failure_test.py b/src/test/gtest/test/gtest_throw_on_failure_test.py new file mode 100755 index 00000000..5678ffea --- /dev/null +++ b/src/test/gtest/test/gtest_throw_on_failure_test.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# +# Copyright 2009, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Tests Google Test's throw-on-failure mode with exceptions disabled. + +This script invokes gtest_throw_on_failure_test_ (a program written with +Google Test) with different environments and command line flags. +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + + +# Constants. + +# The command line flag for enabling/disabling the throw-on-failure mode. +THROW_ON_FAILURE = 'gtest_throw_on_failure' + +# Path to the gtest_throw_on_failure_test_ program, compiled with +# exceptions disabled. +EXE_PATH = gtest_test_utils.GetTestExecutablePath( + 'gtest_throw_on_failure_test_') + + +# Utilities. + + +def SetEnvVar(env_var, value): + """Sets an environment variable to a given value; unsets it when the + given value is None. + """ + + env_var = env_var.upper() + if value is not None: + os.environ[env_var] = value + elif env_var in os.environ: + del os.environ[env_var] + + +def Run(command): + """Runs a command; returns True/False if its exit code is/isn't 0.""" + + print 'Running "%s". . .' % ' '.join(command) + p = gtest_test_utils.Subprocess(command) + return p.exited and p.exit_code == 0 + + +# The tests. TODO(wan@google.com): refactor the class to share common +# logic with code in gtest_break_on_failure_unittest.py. +class ThrowOnFailureTest(gtest_test_utils.TestCase): + """Tests the throw-on-failure mode.""" + + def RunAndVerify(self, env_var_value, flag_value, should_fail): + """Runs gtest_throw_on_failure_test_ and verifies that it does + (or does not) exit with a non-zero code. + + Args: + env_var_value: value of the GTEST_BREAK_ON_FAILURE environment + variable; None if the variable should be unset. + flag_value: value of the --gtest_break_on_failure flag; + None if the flag should not be present. + should_fail: True iff the program is expected to fail. + """ + + SetEnvVar(THROW_ON_FAILURE, env_var_value) + + if env_var_value is None: + env_var_value_msg = ' is not set' + else: + env_var_value_msg = '=' + env_var_value + + if flag_value is None: + flag = '' + elif flag_value == '0': + flag = '--%s=0' % THROW_ON_FAILURE + else: + flag = '--%s' % THROW_ON_FAILURE + + command = [EXE_PATH] + if flag: + command.append(flag) + + if should_fail: + should_or_not = 'should' + else: + should_or_not = 'should not' + + failed = not Run(command) + + SetEnvVar(THROW_ON_FAILURE, None) + + msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero ' + 'exit code.' % + (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command), + should_or_not)) + self.assert_(failed == should_fail, msg) + + def testDefaultBehavior(self): + """Tests the behavior of the default mode.""" + + self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False) + + def testThrowOnFailureEnvVar(self): + """Tests using the GTEST_THROW_ON_FAILURE environment variable.""" + + self.RunAndVerify(env_var_value='0', + flag_value=None, + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value=None, + should_fail=True) + + def testThrowOnFailureFlag(self): + """Tests using the --gtest_throw_on_failure flag.""" + + self.RunAndVerify(env_var_value=None, + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value=None, + flag_value='1', + should_fail=True) + + def testThrowOnFailureFlagOverridesEnvVar(self): + """Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE.""" + + self.RunAndVerify(env_var_value='0', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='0', + flag_value='1', + should_fail=True) + self.RunAndVerify(env_var_value='1', + flag_value='0', + should_fail=False) + self.RunAndVerify(env_var_value='1', + flag_value='1', + should_fail=True) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_throw_on_failure_test_.cc b/src/test/gtest/test/gtest_throw_on_failure_test_.cc new file mode 100644 index 00000000..2b88fe3d --- /dev/null +++ b/src/test/gtest/test/gtest_throw_on_failure_test_.cc @@ -0,0 +1,72 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Test's throw-on-failure mode with exceptions disabled. +// +// This program must be compiled with exceptions disabled. It will be +// invoked by gtest_throw_on_failure_test.py, and is expected to exit +// with non-zero in the throw-on-failure mode or 0 otherwise. + +#include "gtest/gtest.h" + +#include // for fflush, fprintf, NULL, etc. +#include // for exit +#include // for set_terminate + +// This terminate handler aborts the program using exit() rather than abort(). +// This avoids showing pop-ups on Windows systems and core dumps on Unix-like +// ones. +void TerminateHandler() { + fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); + fflush(NULL); + exit(1); +} + +int main(int argc, char** argv) { +#if GTEST_HAS_EXCEPTIONS + std::set_terminate(&TerminateHandler); +#endif + testing::InitGoogleTest(&argc, argv); + + // We want to ensure that people can use Google Test assertions in + // other testing frameworks, as long as they initialize Google Test + // properly and set the throw-on-failure mode. Therefore, we don't + // use Google Test's constructs for defining and running tests + // (e.g. TEST and RUN_ALL_TESTS) here. + + // In the throw-on-failure mode with exceptions disabled, this + // assertion will cause the program to exit with a non-zero code. + EXPECT_EQ(2, 3); + + // When not in the throw-on-failure mode, the control will reach + // here. + return 0; +} diff --git a/src/test/gtest/test/gtest_uninitialized_test.py b/src/test/gtest/test/gtest_uninitialized_test.py new file mode 100755 index 00000000..6ae57eee --- /dev/null +++ b/src/test/gtest/test/gtest_uninitialized_test.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Verifies that Google Test warns the user when not initialized properly.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gtest_test_utils + + +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') + + +def Assert(condition): + if not condition: + raise AssertionError + + +def AssertEq(expected, actual): + if expected != actual: + print 'Expected: %s' % (expected,) + print ' Actual: %s' % (actual,) + raise AssertionError + + +def TestExitCodeAndOutput(command): + """Runs the given command and verifies its exit code and output.""" + + # Verifies that 'command' exits with code 1. + p = gtest_test_utils.Subprocess(command) + Assert(p.exited) + AssertEq(1, p.exit_code) + Assert('InitGoogleTest' in p.output) + + +class GTestUninitializedTest(gtest_test_utils.TestCase): + def testExitCodeAndOutput(self): + TestExitCodeAndOutput(COMMAND) + + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_uninitialized_test_.cc b/src/test/gtest/test/gtest_uninitialized_test_.cc new file mode 100644 index 00000000..44316987 --- /dev/null +++ b/src/test/gtest/test/gtest_uninitialized_test_.cc @@ -0,0 +1,43 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest.h" + +TEST(DummyTest, Dummy) { + // This test doesn't verify anything. We just need it to create a + // realistic stage for testing the behavior of Google Test when + // RUN_ALL_TESTS() is called without testing::InitGoogleTest() being + // called first. +} + +int main() { + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_unittest.cc b/src/test/gtest/test/gtest_unittest.cc new file mode 100644 index 00000000..6cccd018 --- /dev/null +++ b/src/test/gtest/test/gtest_unittest.cc @@ -0,0 +1,7431 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Tests for Google Test itself. This verifies that the basic constructs of +// Google Test work. + +#include "gtest/gtest.h" + +// Verifies that the command line flag variables can be accessed +// in code once has been #included. +// Do not move it after other #includes. +TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { + bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) + || testing::GTEST_FLAG(break_on_failure) + || testing::GTEST_FLAG(catch_exceptions) + || testing::GTEST_FLAG(color) != "unknown" + || testing::GTEST_FLAG(filter) != "unknown" + || testing::GTEST_FLAG(list_tests) + || testing::GTEST_FLAG(output) != "unknown" + || testing::GTEST_FLAG(print_time) + || testing::GTEST_FLAG(random_seed) + || testing::GTEST_FLAG(repeat) > 0 + || testing::GTEST_FLAG(show_internal_stack_frames) + || testing::GTEST_FLAG(shuffle) + || testing::GTEST_FLAG(stack_trace_depth) > 0 + || testing::GTEST_FLAG(stream_result_to) != "unknown" + || testing::GTEST_FLAG(throw_on_failure); + EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. +} + +#include // For INT_MAX. +#include +#include +#include + +#include +#include +#include + +#include "gtest/gtest-spi.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if GTEST_CAN_STREAM_RESULTS_ + +class StreamingListenerTest : public Test { + public: + class FakeSocketWriter : public StreamingListener::AbstractSocketWriter { + public: + // Sends a string to the socket. + virtual void Send(const string& message) { output_ += message; } + + string output_; + }; + + StreamingListenerTest() + : fake_sock_writer_(new FakeSocketWriter), + streamer_(fake_sock_writer_), + test_info_obj_("FooTest", "Bar", NULL, NULL, 0, NULL) {} + + protected: + string* output() { return &(fake_sock_writer_->output_); } + + FakeSocketWriter* const fake_sock_writer_; + StreamingListener streamer_; + UnitTest unit_test_; + TestInfo test_info_obj_; // The name test_info_ was taken by testing::Test. +}; + +TEST_F(StreamingListenerTest, OnTestProgramEnd) { + *output() = ""; + streamer_.OnTestProgramEnd(unit_test_); + EXPECT_EQ("event=TestProgramEnd&passed=1\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestIterationEnd) { + *output() = ""; + streamer_.OnTestIterationEnd(unit_test_, 42); + EXPECT_EQ("event=TestIterationEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseStart) { + *output() = ""; + streamer_.OnTestCaseStart(TestCase("FooTest", "Bar", NULL, NULL)); + EXPECT_EQ("event=TestCaseStart&name=FooTest\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestCaseEnd) { + *output() = ""; + streamer_.OnTestCaseEnd(TestCase("FooTest", "Bar", NULL, NULL)); + EXPECT_EQ("event=TestCaseEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestStart) { + *output() = ""; + streamer_.OnTestStart(test_info_obj_); + EXPECT_EQ("event=TestStart&name=Bar\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestEnd) { + *output() = ""; + streamer_.OnTestEnd(test_info_obj_); + EXPECT_EQ("event=TestEnd&passed=1&elapsed_time=0ms\n", *output()); +} + +TEST_F(StreamingListenerTest, OnTestPartResult) { + *output() = ""; + streamer_.OnTestPartResult(TestPartResult( + TestPartResult::kFatalFailure, "foo.cc", 42, "failed=\n&%")); + + // Meta characters in the failure message should be properly escaped. + EXPECT_EQ( + "event=TestPartResult&file=foo.cc&line=42&message=failed%3D%0A%26%25\n", + *output()); +} + +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Provides access to otherwise private parts of the TestEventListeners class +// that are needed to test it. +class TestEventListenersAccessor { + public: + static TestEventListener* GetRepeater(TestEventListeners* listeners) { + return listeners->repeater(); + } + + static void SetDefaultResultPrinter(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultResultPrinter(listener); + } + static void SetDefaultXmlGenerator(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultXmlGenerator(listener); + } + + static bool EventForwardingEnabled(const TestEventListeners& listeners) { + return listeners.EventForwardingEnabled(); + } + + static void SuppressEventForwarding(TestEventListeners* listeners) { + listeners->SuppressEventForwarding(); + } +}; + +class UnitTestRecordPropertyTestHelper : public Test { + protected: + UnitTestRecordPropertyTestHelper() {} + + // Forwards to UnitTest::RecordProperty() to bypass access controls. + void UnitTestRecordProperty(const char* key, const std::string& value) { + unit_test_.RecordProperty(key, value); + } + + UnitTest unit_test_; +}; + +} // namespace internal +} // namespace testing + +using testing::AssertionFailure; +using testing::AssertionResult; +using testing::AssertionSuccess; +using testing::DoubleLE; +using testing::EmptyTestEventListener; +using testing::Environment; +using testing::FloatLE; +using testing::GTEST_FLAG(also_run_disabled_tests); +using testing::GTEST_FLAG(break_on_failure); +using testing::GTEST_FLAG(catch_exceptions); +using testing::GTEST_FLAG(color); +using testing::GTEST_FLAG(death_test_use_fork); +using testing::GTEST_FLAG(filter); +using testing::GTEST_FLAG(list_tests); +using testing::GTEST_FLAG(output); +using testing::GTEST_FLAG(print_time); +using testing::GTEST_FLAG(random_seed); +using testing::GTEST_FLAG(repeat); +using testing::GTEST_FLAG(show_internal_stack_frames); +using testing::GTEST_FLAG(shuffle); +using testing::GTEST_FLAG(stack_trace_depth); +using testing::GTEST_FLAG(stream_result_to); +using testing::GTEST_FLAG(throw_on_failure); +using testing::IsNotSubstring; +using testing::IsSubstring; +using testing::Message; +using testing::ScopedFakeTestPartResultReporter; +using testing::StaticAssertTypeEq; +using testing::Test; +using testing::TestCase; +using testing::TestEventListeners; +using testing::TestInfo; +using testing::TestPartResult; +using testing::TestPartResultArray; +using testing::TestProperty; +using testing::TestResult; +using testing::TimeInMillis; +using testing::UnitTest; +using testing::internal::AddReference; +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; +using testing::internal::AppendUserMessage; +using testing::internal::ArrayAwareFind; +using testing::internal::ArrayEq; +using testing::internal::CodePointToUtf8; +using testing::internal::CompileAssertTypesEqual; +using testing::internal::CopyArray; +using testing::internal::CountIf; +using testing::internal::EqFailure; +using testing::internal::FloatingPoint; +using testing::internal::ForEach; +using testing::internal::FormatEpochTimeInMillisAsIso8601; +using testing::internal::FormatTimeInMillisAsSeconds; +using testing::internal::GTestFlagSaver; +using testing::internal::GetCurrentOsStackTraceExceptTop; +using testing::internal::GetElementOr; +using testing::internal::GetNextRandomSeed; +using testing::internal::GetRandomSeedFromFlag; +using testing::internal::GetTestTypeId; +using testing::internal::GetTimeInMillis; +using testing::internal::GetTypeId; +using testing::internal::GetUnitTestImpl; +using testing::internal::ImplicitlyConvertible; +using testing::internal::Int32; +using testing::internal::Int32FromEnvOrDie; +using testing::internal::IsAProtocolMessage; +using testing::internal::IsContainer; +using testing::internal::IsContainerTest; +using testing::internal::IsNotContainer; +using testing::internal::NativeArray; +using testing::internal::ParseInt32Flag; +using testing::internal::RelationToSourceCopy; +using testing::internal::RelationToSourceReference; +using testing::internal::RemoveConst; +using testing::internal::RemoveReference; +using testing::internal::ShouldRunTestOnShard; +using testing::internal::ShouldShard; +using testing::internal::ShouldUseColor; +using testing::internal::Shuffle; +using testing::internal::ShuffleRange; +using testing::internal::SkipPrefix; +using testing::internal::StreamableToString; +using testing::internal::String; +using testing::internal::TestEventListenersAccessor; +using testing::internal::TestResultAccessor; +using testing::internal::UInt32; +using testing::internal::WideStringToUtf8; +using testing::internal::kMaxRandomSeed; +using testing::internal::kTestTypeIdInGoogleTest; +using testing::internal::scoped_ptr; +using testing::kMaxStackTraceDepth; + +#if GTEST_HAS_STREAM_REDIRECTION +using testing::internal::CaptureStdout; +using testing::internal::GetCapturedStdout; +#endif + +#if GTEST_IS_THREADSAFE +using testing::internal::ThreadWithParam; +#endif + +class TestingVector : public std::vector { +}; + +::std::ostream& operator<<(::std::ostream& os, + const TestingVector& vector) { + os << "{ "; + for (size_t i = 0; i < vector.size(); i++) { + os << vector[i] << " "; + } + os << "}"; + return os; +} + +// This line tests that we can define tests in an unnamed namespace. +namespace { + +TEST(GetRandomSeedFromFlagTest, HandlesZero) { + const int seed = GetRandomSeedFromFlag(0); + EXPECT_LE(1, seed); + EXPECT_LE(seed, static_cast(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, PreservesValidSeed) { + EXPECT_EQ(1, GetRandomSeedFromFlag(1)); + EXPECT_EQ(2, GetRandomSeedFromFlag(2)); + EXPECT_EQ(kMaxRandomSeed - 1, GetRandomSeedFromFlag(kMaxRandomSeed - 1)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetRandomSeedFromFlag(kMaxRandomSeed)); +} + +TEST(GetRandomSeedFromFlagTest, NormalizesInvalidSeed) { + const int seed1 = GetRandomSeedFromFlag(-1); + EXPECT_LE(1, seed1); + EXPECT_LE(seed1, static_cast(kMaxRandomSeed)); + + const int seed2 = GetRandomSeedFromFlag(kMaxRandomSeed + 1); + EXPECT_LE(1, seed2); + EXPECT_LE(seed2, static_cast(kMaxRandomSeed)); +} + +TEST(GetNextRandomSeedTest, WorksForValidInput) { + EXPECT_EQ(2, GetNextRandomSeed(1)); + EXPECT_EQ(3, GetNextRandomSeed(2)); + EXPECT_EQ(static_cast(kMaxRandomSeed), + GetNextRandomSeed(kMaxRandomSeed - 1)); + EXPECT_EQ(1, GetNextRandomSeed(kMaxRandomSeed)); + + // We deliberately don't test GetNextRandomSeed() with invalid + // inputs, as that requires death tests, which are expensive. This + // is fine as GetNextRandomSeed() is internal and has a + // straightforward definition. +} + +static void ClearCurrentTestPartResults() { + TestResultAccessor::ClearTestPartResults( + GetUnitTestImpl()->current_test_result()); +} + +// Tests GetTypeId. + +TEST(GetTypeIdTest, ReturnsSameValueForSameType) { + EXPECT_EQ(GetTypeId(), GetTypeId()); + EXPECT_EQ(GetTypeId(), GetTypeId()); +} + +class SubClassOfTest : public Test {}; +class AnotherSubClassOfTest : public Test {}; + +TEST(GetTypeIdTest, ReturnsDifferentValuesForDifferentTypes) { + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTestTypeId()); + EXPECT_NE(GetTypeId(), GetTypeId()); +} + +// Verifies that GetTestTypeId() returns the same value, no matter it +// is called from inside Google Test or outside of it. +TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { + EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId()); +} + +// Tests FormatTimeInMillisAsSeconds(). + +TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { + EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { + EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3)); + EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10)); + EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200)); + EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200)); + EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000)); +} + +TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { + EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3)); + EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10)); + EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200)); + EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); + EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); +} + +// Tests FormatEpochTimeInMillisAsIso8601(). The correctness of conversion +// for particular dates below was verified in Python using +// datetime.datetime.fromutctimestamp(/1000). + +// FormatEpochTimeInMillisAsIso8601 depends on the current timezone, so we +// have to set up a particular timezone to obtain predictable results. +class FormatEpochTimeInMillisAsIso8601Test : public Test { + public: + // On Cygwin, GCC doesn't allow unqualified integer literals to exceed + // 32 bits, even when 64-bit integer types are available. We have to + // force the constants to have a 64-bit type here. + static const TimeInMillis kMillisPerSec = 1000; + + private: + virtual void SetUp() { + saved_tz_ = NULL; + + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* getenv, strdup: deprecated */) + if (getenv("TZ")) + saved_tz_ = strdup(getenv("TZ")); + GTEST_DISABLE_MSC_WARNINGS_POP_() + + // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We + // cannot use the local time zone because the function's output depends + // on the time zone. + SetTimeZone("UTC+00"); + } + + virtual void TearDown() { + SetTimeZone(saved_tz_); + free(const_cast(saved_tz_)); + saved_tz_ = NULL; + } + + static void SetTimeZone(const char* time_zone) { + // tzset() distinguishes between the TZ variable being present and empty + // and not being present, so we have to consider the case of time_zone + // being NULL. +#if _MSC_VER + // ...Unless it's MSVC, whose standard library's _putenv doesn't + // distinguish between an empty and a missing variable. + const std::string env_var = + std::string("TZ=") + (time_zone ? time_zone : ""); + _putenv(env_var.c_str()); + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) + tzset(); + GTEST_DISABLE_MSC_WARNINGS_POP_() +#else + if (time_zone) { + setenv(("TZ"), time_zone, 1); + } else { + unsetenv("TZ"); + } + tzset(); +#endif + } + + const char* saved_tz_; +}; + +const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec; + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsTwoDigitSegments) { + EXPECT_EQ("2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, MillisecondsDoNotAffectResult) { + EXPECT_EQ( + "2011-10-31T18:52:42", + FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec + 234)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsLeadingZeroes) { + EXPECT_EQ("2011-09-03T05:07:02", + FormatEpochTimeInMillisAsIso8601(1315026422 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, Prints24HourTime) { + EXPECT_EQ("2011-09-28T17:08:22", + FormatEpochTimeInMillisAsIso8601(1317229702 * kMillisPerSec)); +} + +TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) { + EXPECT_EQ("1970-01-01T00:00:00", FormatEpochTimeInMillisAsIso8601(0)); +} + +#if GTEST_CAN_COMPARE_NULL + +# ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +# endif + +// Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null +// pointer literal. +TEST(NullLiteralTest, IsTrueForNullLiterals) { + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); + EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); +} + +// Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null +// pointer literal. +TEST(NullLiteralTest, IsFalseForNonNullLiterals) { + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(1)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(0.0)); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_('a')); + EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); +} + +# ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +# endif + +#endif // GTEST_CAN_COMPARE_NULL +// +// Tests CodePointToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeNul) { + EXPECT_EQ("", CodePointToUtf8(L'\0')); +} + +// Tests that ASCII characters are encoded correctly. +TEST(CodePointToUtf8Test, CanEncodeAscii) { + EXPECT_EQ("a", CodePointToUtf8(L'a')); + EXPECT_EQ("Z", CodePointToUtf8(L'Z')); + EXPECT_EQ("&", CodePointToUtf8(L'&')); + EXPECT_EQ("\x7F", CodePointToUtf8(L'\x7F')); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_EQ("\xC3\x93", CodePointToUtf8(L'\xD3')); + + // 101 0111 0110 => 110-10101 10-110110 + // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints + // in wide strings and wide chars. In order to accomodate them, we have to + // introduce such character constants as integers. + EXPECT_EQ("\xD5\xB6", + CodePointToUtf8(static_cast(0x576))); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + EXPECT_EQ("\xE0\xA3\x93", + CodePointToUtf8(static_cast(0x8D3))); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + EXPECT_EQ("\xEC\x9D\x8D", + CodePointToUtf8(static_cast(0xC74D))); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests in this group require a wchar_t to hold > 16 bits, and thus +// are skipped on Windows, Cygwin, and Symbian, where a wchar_t is +// 16-bit wide. This code may not compile on those systems. + +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. +TEST(CodePointToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_EQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3')); + + // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000 + EXPECT_EQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400')); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_EQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634')); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_EQ("(Invalid Unicode 0x1234ABCD)", CodePointToUtf8(L'\x1234ABCD')); +} + +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests WideStringToUtf8(). + +// Tests that the NUL character L'\0' is encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeNul) { + EXPECT_STREQ("", WideStringToUtf8(L"", 0).c_str()); + EXPECT_STREQ("", WideStringToUtf8(L"", -1).c_str()); +} + +// Tests that ASCII strings are encoded correctly. +TEST(WideStringToUtf8Test, CanEncodeAscii) { + EXPECT_STREQ("a", WideStringToUtf8(L"a", 1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", 2).c_str()); + EXPECT_STREQ("a", WideStringToUtf8(L"a", -1).c_str()); + EXPECT_STREQ("ab", WideStringToUtf8(L"ab", -1).c_str()); +} + +// Tests that Unicode code-points that have 8 to 11 bits are encoded +// as 110xxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode8To11Bits) { + // 000 1101 0011 => 110-00011 10-010011 + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", 1).c_str()); + EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str()); + + // 101 0111 0110 => 110-10101 10-110110 + const wchar_t s[] = { 0x576, '\0' }; + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, 1).c_str()); + EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that Unicode code-points that have 12 to 16 bits are encoded +// as 1110xxxx 10xxxxxx 10xxxxxx. +TEST(WideStringToUtf8Test, CanEncode12To16Bits) { + // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 + const wchar_t s1[] = { 0x8D3, '\0' }; + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, 1).c_str()); + EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, -1).c_str()); + + // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 + const wchar_t s2[] = { 0xC74D, '\0' }; + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, 1).c_str()); + EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, -1).c_str()); +} + +// Tests that the conversion stops when the function encounters \0 character. +TEST(WideStringToUtf8Test, StopsOnNulCharacter) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABC\0XYZ", 100).c_str()); +} + +// Tests that the conversion stops when the function reaches the limit +// specified by the 'length' parameter. +TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { + EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str()); +} + +#if !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that Unicode code-points that have 17 to 21 bits are encoded +// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile +// on the systems using UTF-16 encoding. +TEST(WideStringToUtf8Test, CanEncode17To21Bits) { + // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", 1).c_str()); + EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", -1).c_str()); + + // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", 1).c_str()); + EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", -1).c_str()); +} + +// Tests that encoding an invalid code-point generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { + EXPECT_STREQ("(Invalid Unicode 0xABCDFF)", + WideStringToUtf8(L"\xABCDFF", -1).c_str()); +} +#else // !GTEST_WIDE_STRING_USES_UTF16_ +// Tests that surrogate pairs are encoded correctly on the systems using +// UTF-16 encoding in the wide strings. +TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { + const wchar_t s[] = { 0xD801, 0xDC00, '\0' }; + EXPECT_STREQ("\xF0\x90\x90\x80", WideStringToUtf8(s, -1).c_str()); +} + +// Tests that encoding an invalid UTF-16 surrogate pair +// generates the expected result. +TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { + // Leading surrogate is at the end of the string. + const wchar_t s1[] = { 0xD800, '\0' }; + EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(s1, -1).c_str()); + // Leading surrogate is not followed by the trailing surrogate. + const wchar_t s2[] = { 0xD800, 'M', '\0' }; + EXPECT_STREQ("\xED\xA0\x80M", WideStringToUtf8(s2, -1).c_str()); + // Trailing surrogate appearas without a leading surrogate. + const wchar_t s3[] = { 0xDC00, 'P', 'Q', 'R', '\0' }; + EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(s3, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests that codepoint concatenation works correctly. +#if !GTEST_WIDE_STRING_USES_UTF16_ +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0x108634, 0xC74D, '\n', 0x576, 0x8D3, 0x108634, '\0'}; + EXPECT_STREQ( + "\xF4\x88\x98\xB4" + "\xEC\x9D\x8D" + "\n" + "\xD5\xB6" + "\xE0\xA3\x93" + "\xF4\x88\x98\xB4", + WideStringToUtf8(s, -1).c_str()); +} +#else +TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { + const wchar_t s[] = { 0xC74D, '\n', 0x576, 0x8D3, '\0'}; + EXPECT_STREQ( + "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", + WideStringToUtf8(s, -1).c_str()); +} +#endif // !GTEST_WIDE_STRING_USES_UTF16_ + +// Tests the Random class. + +TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { + testing::internal::Random random(42); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(0), + "Cannot generate a number in the range \\[0, 0\\)"); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(testing::internal::Random::kMaxRange + 1), + "Generation of a number in \\[0, 2147483649\\) was requested, " + "but this can only generate numbers in \\[0, 2147483648\\)"); +} + +TEST(RandomTest, GeneratesNumbersWithinRange) { + const UInt32 kRange = 10000; + testing::internal::Random random(12345); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; + } + + testing::internal::Random random2(testing::internal::Random::kMaxRange); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i; + } +} + +TEST(RandomTest, RepeatsWhenReseeded) { + const int kSeed = 123; + const int kArraySize = 10; + const UInt32 kRange = 10000; + UInt32 values[kArraySize]; + + testing::internal::Random random(kSeed); + for (int i = 0; i < kArraySize; i++) { + values[i] = random.Generate(kRange); + } + + random.Reseed(kSeed); + for (int i = 0; i < kArraySize; i++) { + EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i; + } +} + +// Tests STL container utilities. + +// Tests CountIf(). + +static bool IsPositive(int n) { return n > 0; } + +TEST(ContainerUtilityTest, CountIf) { + std::vector v; + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container. + + v.push_back(-1); + v.push_back(0); + EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies. + + v.push_back(2); + v.push_back(-10); + v.push_back(10); + EXPECT_EQ(2, CountIf(v, IsPositive)); +} + +// Tests ForEach(). + +static int g_sum = 0; +static void Accumulate(int n) { g_sum += n; } + +TEST(ContainerUtilityTest, ForEach) { + std::vector v; + g_sum = 0; + ForEach(v, Accumulate); + EXPECT_EQ(0, g_sum); // Works for an empty container; + + g_sum = 0; + v.push_back(1); + ForEach(v, Accumulate); + EXPECT_EQ(1, g_sum); // Works for a container with one element. + + g_sum = 0; + v.push_back(20); + v.push_back(300); + ForEach(v, Accumulate); + EXPECT_EQ(321, g_sum); +} + +// Tests GetElementOr(). +TEST(ContainerUtilityTest, GetElementOr) { + std::vector a; + EXPECT_EQ('x', GetElementOr(a, 0, 'x')); + + a.push_back('a'); + a.push_back('b'); + EXPECT_EQ('a', GetElementOr(a, 0, 'x')); + EXPECT_EQ('b', GetElementOr(a, 1, 'x')); + EXPECT_EQ('x', GetElementOr(a, -2, 'x')); + EXPECT_EQ('x', GetElementOr(a, 2, 'x')); +} + +TEST(ContainerUtilityDeathTest, ShuffleRange) { + std::vector a; + a.push_back(0); + a.push_back(1); + a.push_back(2); + testing::internal::Random random(1); + + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, -1, 1, &a), + "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 4, 4, &a), + "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 2, &a), + "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + ShuffleRange(&random, 3, 4, &a), + "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); +} + +class VectorShuffleTest : public Test { + protected: + static const int kVectorSize = 20; + + VectorShuffleTest() : random_(1) { + for (int i = 0; i < kVectorSize; i++) { + vector_.push_back(i); + } + } + + static bool VectorIsCorrupt(const TestingVector& vector) { + if (kVectorSize != static_cast(vector.size())) { + return true; + } + + bool found_in_vector[kVectorSize] = { false }; + for (size_t i = 0; i < vector.size(); i++) { + const int e = vector[i]; + if (e < 0 || e >= kVectorSize || found_in_vector[e]) { + return true; + } + found_in_vector[e] = true; + } + + // Vector size is correct, elements' range is correct, no + // duplicate elements. Therefore no corruption has occurred. + return false; + } + + static bool VectorIsNotCorrupt(const TestingVector& vector) { + return !VectorIsCorrupt(vector); + } + + static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { + for (int i = begin; i < end; i++) { + if (i != vector[i]) { + return true; + } + } + return false; + } + + static bool RangeIsUnshuffled( + const TestingVector& vector, int begin, int end) { + return !RangeIsShuffled(vector, begin, end); + } + + static bool VectorIsShuffled(const TestingVector& vector) { + return RangeIsShuffled(vector, 0, static_cast(vector.size())); + } + + static bool VectorIsUnshuffled(const TestingVector& vector) { + return !VectorIsShuffled(vector); + } + + testing::internal::Random random_; + TestingVector vector_; +}; // class VectorShuffleTest + +const int VectorShuffleTest::kVectorSize; + +TEST_F(VectorShuffleTest, HandlesEmptyRange) { + // Tests an empty range at the beginning... + ShuffleRange(&random_, 0, 0, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...at the end... + ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and past the end. + ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { + // Tests a size one range at the beginning... + ShuffleRange(&random_, 0, 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and at the end. + ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +// Because we use our own random number generator and a fixed seed, +// we can guarantee that the following "random" tests will succeed. + +TEST_F(VectorShuffleTest, ShufflesEntireVector) { + Shuffle(&random_, &vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; + + // Tests the first and last elements in particular to ensure that + // there are no off-by-one problems in our shuffle algorithm. + EXPECT_NE(0, vector_[0]); + EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]); +} + +TEST_F(VectorShuffleTest, ShufflesStartOfVector) { + const int kRangeSize = kVectorSize/2; + + ShuffleRange(&random_, 0, kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesEndOfVector) { + const int kRangeSize = kVectorSize / 2; + ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { + int kRangeSize = kVectorSize/3; + ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesRepeatably) { + TestingVector vector2; + for (int i = 0; i < kVectorSize; i++) { + vector2.push_back(i); + } + + random_.Reseed(1234); + Shuffle(&random_, &vector_); + random_.Reseed(1234); + Shuffle(&random_, &vector2); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector2); + + for (int i = 0; i < kVectorSize; i++) { + EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i; + } +} + +// Tests the size of the AssertHelper class. + +TEST(AssertHelperTest, AssertHelperIsSmall) { + // To avoid breaking clients that use lots of assertions in one + // function, we cannot grow the size of AssertHelper. + EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); +} + +// Tests String::EndsWithCaseInsensitive(). +TEST(StringTest, EndsWithCaseInsensitive) { + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "BAR")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobaR", "bar")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "")); + EXPECT_TRUE(String::EndsWithCaseInsensitive("", "")); + + EXPECT_FALSE(String::EndsWithCaseInsensitive("Foobar", "foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("foobar", "Foo")); + EXPECT_FALSE(String::EndsWithCaseInsensitive("", "foo")); +} + +// C++Builder's preprocessor is buggy; it fails to expand macros that +// appear in macro parameters after wide char literals. Provide an alias +// for NULL as a workaround. +static const wchar_t* const kNull = NULL; + +// Tests String::CaseInsensitiveWideCStringEquals +TEST(StringTest, CaseInsensitiveWideCStringEquals) { + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull)); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar")); + EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull)); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); + EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); +} + +#if GTEST_OS_WINDOWS + +// Tests String::ShowWideCString(). +TEST(StringTest, ShowWideCString) { + EXPECT_STREQ("(null)", + String::ShowWideCString(NULL).c_str()); + EXPECT_STREQ("", String::ShowWideCString(L"").c_str()); + EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); +} + +# if GTEST_OS_WINDOWS_MOBILE +TEST(StringTest, AnsiAndUtf16Null) { + EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); + EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); +} + +TEST(StringTest, AnsiAndUtf16ConvertBasic) { + const char* ansi = String::Utf16ToAnsi(L"str"); + EXPECT_STREQ("str", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16("str"); + EXPECT_EQ(0, wcsncmp(L"str", utf16, 3)); + delete [] utf16; +} + +TEST(StringTest, AnsiAndUtf16ConvertPathChars) { + const char* ansi = String::Utf16ToAnsi(L".:\\ \"*?"); + EXPECT_STREQ(".:\\ \"*?", ansi); + delete [] ansi; + const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?"); + EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); + delete [] utf16; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#endif // GTEST_OS_WINDOWS + +// Tests TestProperty construction. +TEST(TestPropertyTest, StringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("1", property.value()); +} + +// Tests TestProperty replacing a value. +TEST(TestPropertyTest, ReplaceStringValue) { + TestProperty property("key", "1"); + EXPECT_STREQ("1", property.value()); + property.SetValue("2"); + EXPECT_STREQ("2", property.value()); +} + +// AddFatalFailure() and AddNonfatalFailure() must be stand-alone +// functions (i.e. their definitions cannot be inlined at the call +// sites), or C++Builder won't compile the code. +static void AddFatalFailure() { + FAIL() << "Expected fatal failure."; +} + +static void AddNonfatalFailure() { + ADD_FAILURE() << "Expected non-fatal failure."; +} + +class ScopedFakeTestPartResultReporterTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + enum FailureMode { + FATAL_FAILURE, + NONFATAL_FAILURE + }; + static void AddFailure(FailureMode failure) { + if (failure == FATAL_FAILURE) { + AddFatalFailure(); + } else { + AddNonfatalFailure(); + } + } +}; + +// Tests that ScopedFakeTestPartResultReporter intercepts test +// failures. +TEST_F(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, + &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + } + + EXPECT_EQ(2, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); +} + +TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) { + TestPartResultArray results; + { + // Tests, that the deprecated constructor still works. + ScopedFakeTestPartResultReporter reporter(&results); + AddFailure(NONFATAL_FAILURE); + } + EXPECT_EQ(1, results.size()); +} + +#if GTEST_IS_THREADSAFE + +class ScopedFakeTestPartResultReporterWithThreadsTest + : public ScopedFakeTestPartResultReporterTest { + protected: + static void AddFailureInOtherThread(FailureMode failure) { + ThreadWithParam thread(&AddFailure, failure, NULL); + thread.Join(); + } +}; + +TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, + InterceptsTestFailuresInAllThreads) { + TestPartResultArray results; + { + ScopedFakeTestPartResultReporter reporter( + ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, &results); + AddFailure(NONFATAL_FAILURE); + AddFailure(FATAL_FAILURE); + AddFailureInOtherThread(NONFATAL_FAILURE); + AddFailureInOtherThread(FATAL_FAILURE); + } + + EXPECT_EQ(4, results.size()); + EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(2).nonfatally_failed()); + EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed()); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they +// work even if the failure is generated in a called function rather than +// the current context. + +typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; + +TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); +} + +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectFatalFailureTest, AcceptsStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), ::string("Expected fatal failure.")); +} +#endif + +TEST_F(ExpectFatalFailureTest, AcceptsStdStringObject) { + EXPECT_FATAL_FAILURE(AddFatalFailure(), + ::std::string("Expected fatal failure.")); +} + +TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches fatal + // failures generated on another thread. + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(), + "Expected fatal failure."); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true" +# pragma option push -w-ccc +#endif + +// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void +// function even when the statement in it contains ASSERT_*. + +int NonVoidFunction() { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + return 0; +} + +TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) { + NonVoidFunction(); +} + +// Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the +// current function even though 'statement' generates a fatal failure. + +void DoesNotAbortHelper(bool* aborted) { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + + *aborted = false; +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" suppressed them. +# pragma option pop +#endif + +TEST_F(ExpectFatalFailureTest, DoesNotAbort) { + bool aborted = true; + DoesNotAbortHelper(&aborted); + EXPECT_FALSE(aborted); +} + +// Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. + +static int global_var = 0; +#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ + +TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +#endif + + EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddFatalFailure(); + }, ""); +} + +// Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}. + +typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +#if GTEST_HAS_GLOBAL_STRING +TEST_F(ExpectNonfatalFailureTest, AcceptsStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::string("Expected non-fatal failure.")); +} +#endif + +TEST_F(ExpectNonfatalFailureTest, AcceptsStdStringObject) { + EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), + ::std::string("Expected non-fatal failure.")); +} + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches + // non-fatal failures generated on another thread. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(), + "Expected non-fatal failure."); +} + +// Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. +TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { + EXPECT_NONFATAL_FAILURE({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); + + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ + GTEST_USE_UNPROTECTED_COMMA_; + AddNonfatalFailure(); + }, ""); +} + +#if GTEST_IS_THREADSAFE + +typedef ScopedFakeTestPartResultReporterWithThreadsTest + ExpectFailureWithThreadsTest; + +TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailureOnAllThreads) { + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailureInOtherThread(FATAL_FAILURE), + "Expected fatal failure."); +} + +TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( + AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); +} + +#endif // GTEST_IS_THREADSAFE + +// Tests the TestProperty class. + +TEST(TestPropertyTest, ConstructorWorks) { + const TestProperty property("key", "value"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value", property.value()); +} + +TEST(TestPropertyTest, SetValue) { + TestProperty property("key", "value_1"); + EXPECT_STREQ("key", property.key()); + property.SetValue("value_2"); + EXPECT_STREQ("key", property.key()); + EXPECT_STREQ("value_2", property.value()); +} + +// Tests the TestResult class + +// The test fixture for testing TestResult. +class TestResultTest : public Test { + protected: + typedef std::vector TPRVector; + + // We make use of 2 TestPartResult objects, + TestPartResult * pr1, * pr2; + + // ... and 3 TestResult objects. + TestResult * r0, * r1, * r2; + + virtual void SetUp() { + // pr1 is for success. + pr1 = new TestPartResult(TestPartResult::kSuccess, + "foo/bar.cc", + 10, + "Success!"); + + // pr2 is for fatal failure. + pr2 = new TestPartResult(TestPartResult::kFatalFailure, + "foo/bar.cc", + -1, // This line number means "unknown" + "Failure!"); + + // Creates the TestResult objects. + r0 = new TestResult(); + r1 = new TestResult(); + r2 = new TestResult(); + + // In order to test TestResult, we need to modify its internal + // state, in particular the TestPartResult vector it holds. + // test_part_results() returns a const reference to this vector. + // We cast it to a non-const object s.t. it can be modified (yes, + // this is a hack). + TPRVector* results1 = const_cast( + &TestResultAccessor::test_part_results(*r1)); + TPRVector* results2 = const_cast( + &TestResultAccessor::test_part_results(*r2)); + + // r0 is an empty TestResult. + + // r1 contains a single SUCCESS TestPartResult. + results1->push_back(*pr1); + + // r2 contains a SUCCESS, and a FAILURE. + results2->push_back(*pr1); + results2->push_back(*pr2); + } + + virtual void TearDown() { + delete pr1; + delete pr2; + + delete r0; + delete r1; + delete r2; + } + + // Helper that compares two two TestPartResults. + static void CompareTestPartResult(const TestPartResult& expected, + const TestPartResult& actual) { + EXPECT_EQ(expected.type(), actual.type()); + EXPECT_STREQ(expected.file_name(), actual.file_name()); + EXPECT_EQ(expected.line_number(), actual.line_number()); + EXPECT_STREQ(expected.summary(), actual.summary()); + EXPECT_STREQ(expected.message(), actual.message()); + EXPECT_EQ(expected.passed(), actual.passed()); + EXPECT_EQ(expected.failed(), actual.failed()); + EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed()); + EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed()); + } +}; + +// Tests TestResult::total_part_count(). +TEST_F(TestResultTest, total_part_count) { + ASSERT_EQ(0, r0->total_part_count()); + ASSERT_EQ(1, r1->total_part_count()); + ASSERT_EQ(2, r2->total_part_count()); +} + +// Tests TestResult::Passed(). +TEST_F(TestResultTest, Passed) { + ASSERT_TRUE(r0->Passed()); + ASSERT_TRUE(r1->Passed()); + ASSERT_FALSE(r2->Passed()); +} + +// Tests TestResult::Failed(). +TEST_F(TestResultTest, Failed) { + ASSERT_FALSE(r0->Failed()); + ASSERT_FALSE(r1->Failed()); + ASSERT_TRUE(r2->Failed()); +} + +// Tests TestResult::GetTestPartResult(). + +typedef TestResultTest TestResultDeathTest; + +TEST_F(TestResultDeathTest, GetTestPartResult) { + CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); + CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), ""); + EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), ""); +} + +// Tests TestResult has no properties when none are added. +TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { + TestResult test_result; + ASSERT_EQ(0, test_result.test_property_count()); +} + +// Tests TestResult has the expected property when added. +TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { + TestResult test_result; + TestProperty property("key_1", "1"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property); + ASSERT_EQ(1, test_result.test_property_count()); + const TestProperty& actual_property = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property.key()); + EXPECT_STREQ("1", actual_property.value()); +} + +// Tests TestResult has multiple properties when added. +TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("1", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("2", actual_property_2.value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { + TestResult test_result; + TestProperty property_1_1("key_1", "1"); + TestProperty property_2_1("key_2", "2"); + TestProperty property_1_2("key_1", "12"); + TestProperty property_2_2("key_2", "22"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_2); + + ASSERT_EQ(2, test_result.test_property_count()); + const TestProperty& actual_property_1 = test_result.GetTestProperty(0); + EXPECT_STREQ("key_1", actual_property_1.key()); + EXPECT_STREQ("12", actual_property_1.value()); + + const TestProperty& actual_property_2 = test_result.GetTestProperty(1); + EXPECT_STREQ("key_2", actual_property_2.key()); + EXPECT_STREQ("22", actual_property_2.value()); +} + +// Tests TestResult::GetTestProperty(). +TEST(TestResultPropertyTest, GetTestProperty) { + TestResult test_result; + TestProperty property_1("key_1", "1"); + TestProperty property_2("key_2", "2"); + TestProperty property_3("key_3", "3"); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); + TestResultAccessor::RecordProperty(&test_result, "testcase", property_3); + + const TestProperty& fetched_property_1 = test_result.GetTestProperty(0); + const TestProperty& fetched_property_2 = test_result.GetTestProperty(1); + const TestProperty& fetched_property_3 = test_result.GetTestProperty(2); + + EXPECT_STREQ("key_1", fetched_property_1.key()); + EXPECT_STREQ("1", fetched_property_1.value()); + + EXPECT_STREQ("key_2", fetched_property_2.key()); + EXPECT_STREQ("2", fetched_property_2.value()); + + EXPECT_STREQ("key_3", fetched_property_3.key()); + EXPECT_STREQ("3", fetched_property_3.value()); + + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), ""); + EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); +} + +// Tests that GTestFlagSaver works on Windows and Mac. + +class GTestFlagSaverTest : public Test { + protected: + // Saves the Google Test flags such that we can restore them later, and + // then sets them to their default values. This will be called + // before the first test in this test case is run. + static void SetUpTestCase() { + saver_ = new GTestFlagSaver; + + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(color) = "auto"; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Restores the Google Test flags that the tests have modified. This will + // be called after the last test in this test case is run. + static void TearDownTestCase() { + delete saver_; + saver_ = NULL; + } + + // Verifies that the Google Test flags have their default values, and then + // modifies each of them. + void VerifyAndModifyFlags() { + EXPECT_FALSE(GTEST_FLAG(also_run_disabled_tests)); + EXPECT_FALSE(GTEST_FLAG(break_on_failure)); + EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); + EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); + EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); + EXPECT_FALSE(GTEST_FLAG(list_tests)); + EXPECT_STREQ("", GTEST_FLAG(output).c_str()); + EXPECT_TRUE(GTEST_FLAG(print_time)); + EXPECT_EQ(0, GTEST_FLAG(random_seed)); + EXPECT_EQ(1, GTEST_FLAG(repeat)); + EXPECT_FALSE(GTEST_FLAG(shuffle)); + EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ("", GTEST_FLAG(stream_result_to).c_str()); + EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); + + GTEST_FLAG(also_run_disabled_tests) = true; + GTEST_FLAG(break_on_failure) = true; + GTEST_FLAG(catch_exceptions) = true; + GTEST_FLAG(color) = "no"; + GTEST_FLAG(death_test_use_fork) = true; + GTEST_FLAG(filter) = "abc"; + GTEST_FLAG(list_tests) = true; + GTEST_FLAG(output) = "xml:foo.xml"; + GTEST_FLAG(print_time) = false; + GTEST_FLAG(random_seed) = 1; + GTEST_FLAG(repeat) = 100; + GTEST_FLAG(shuffle) = true; + GTEST_FLAG(stack_trace_depth) = 1; + GTEST_FLAG(stream_result_to) = "localhost:1234"; + GTEST_FLAG(throw_on_failure) = true; + } + + private: + // For saving Google Test flags during this test case. + static GTestFlagSaver* saver_; +}; + +GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL; + +// Google Test doesn't guarantee the order of tests. The following two +// tests are designed to work regardless of their order. + +// Modifies the Google Test flags in the test body. +TEST_F(GTestFlagSaverTest, ModifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Verifies that the Google Test flags in the body of the previous test were +// restored to their original values. +TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { + VerifyAndModifyFlags(); +} + +// Sets an environment variable with the given name to the given +// value. If the value argument is "", unsets the environment +// variable. The caller must ensure that both arguments are not NULL. +static void SetEnv(const char* name, const char* value) { +#if GTEST_OS_WINDOWS_MOBILE + // Environment variables are not supported on Windows CE. + return; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // C++Builder's putenv only stores a pointer to its parameter; we have to + // ensure that the string remains valid as long as it might be needed. + // We use an std::map to do so. + static std::map added_env; + + // Because putenv stores a pointer to the string buffer, we can't delete the + // previous string (if present) until after it's replaced. + std::string *prev_env = NULL; + if (added_env.find(name) != added_env.end()) { + prev_env = added_env[name]; + } + added_env[name] = new std::string( + (Message() << name << "=" << value).GetString()); + + // The standard signature of putenv accepts a 'char*' argument. Other + // implementations, like C++Builder's, accept a 'const char*'. + // We cast away the 'const' since that would work for both variants. + putenv(const_cast(added_env[name]->c_str())); + delete prev_env; +#elif GTEST_OS_WINDOWS // If we are on Windows proper. + _putenv((Message() << name << "=" << value).GetString().c_str()); +#else + if (*value == '\0') { + unsetenv(name); + } else { + setenv(name, value, 1); + } +#endif // GTEST_OS_WINDOWS_MOBILE +} + +#if !GTEST_OS_WINDOWS_MOBILE +// Environment variables are not supported on Windows CE. + +using testing::internal::Int32FromGTestEnv; + +// Tests Int32FromGTestEnv(). + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable is not set. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", ""); + EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable overflows as an Int32. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12345678987654321"); + EXPECT_EQ(20, Int32FromGTestEnv("temp", 20)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-12345678987654321"); + EXPECT_EQ(30, Int32FromGTestEnv("temp", 30)); +} + +// Tests that Int32FromGTestEnv() returns the default value when the +// environment variable does not represent a valid decimal integer. +TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "A1"); + EXPECT_EQ(40, Int32FromGTestEnv("temp", 40)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12X"); + EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); +} + +// Tests that Int32FromGTestEnv() parses and returns the value of the +// environment variable when it represents a valid decimal integer in +// the range of an Int32. +TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "123"); + EXPECT_EQ(123, Int32FromGTestEnv("temp", 0)); + + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); + EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests ParseInt32Flag(). + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag has wrong format +TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("a=100", "a", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag overflows as an Int32. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=-12345678987654321", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() returns false and doesn't change the +// output value when the flag does not represent a valid decimal +// integer. +TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { + printf("(expecting 2 warnings)\n"); + + Int32 value = 123; + EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value)); + EXPECT_EQ(123, value); + + EXPECT_FALSE(ParseInt32Flag("--abc=12X", "abc", &value)); + EXPECT_EQ(123, value); +} + +// Tests that ParseInt32Flag() parses the value of the flag and +// returns true when the flag represents a valid decimal integer in +// the range of an Int32. +TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { + Int32 value = 123; + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); + EXPECT_EQ(456, value); + + EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", + "abc", &value)); + EXPECT_EQ(-789, value); +} + +// Tests that Int32FromEnvOrDie() parses the value of the var or +// returns the correct default. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { + EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); + EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); + EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable is not an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that Int32FromEnvOrDie() aborts with an error message +// if the variable cannot be represnted by an Int32. +TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { + SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); + EXPECT_DEATH_IF_SUPPORTED( + Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), + ".*"); +} + +// Tests that ShouldRunTestOnShard() selects all tests +// where there is 1 shard. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 0)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 1)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 2)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 3)); + EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 4)); +} + +class ShouldShardTest : public testing::Test { + protected: + virtual void SetUp() { + index_var_ = GTEST_FLAG_PREFIX_UPPER_ "INDEX"; + total_var_ = GTEST_FLAG_PREFIX_UPPER_ "TOTAL"; + } + + virtual void TearDown() { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + } + + const char* index_var_; + const char* total_var_; +}; + +// Tests that sharding is disabled if neither of the environment variables +// are set. +TEST_F(ShouldShardTest, ReturnsFalseWhenNeitherEnvVarIsSet) { + SetEnv(index_var_, ""); + SetEnv(total_var_, ""); + + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is not enabled if total_shards == 1. +TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { + SetEnv(index_var_, "0"); + SetEnv(total_var_, "1"); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} + +// Tests that sharding is enabled if total_shards > 1 and +// we are not in a death test subprocess. +// Environment variables are not supported on Windows CE. +#if !GTEST_OS_WINDOWS_MOBILE +TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "22"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "8"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); + + SetEnv(index_var_, "0"); + SetEnv(total_var_, "9"); + EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); + EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); +} +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests that we exit in error if the sharding values are not valid. + +typedef ShouldShardTest ShouldShardDeathTest; + +TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { + SetEnv(index_var_, "4"); + SetEnv(total_var_, "4"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "4"); + SetEnv(total_var_, "-2"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, "5"); + SetEnv(total_var_, ""); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); + + SetEnv(index_var_, ""); + SetEnv(total_var_, "5"); + EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); +} + +// Tests that ShouldRunTestOnShard is a partition when 5 +// shards are used. +TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) { + // Choose an arbitrary number of tests and shards. + const int num_tests = 17; + const int num_shards = 5; + + // Check partitioning: each test should be on exactly 1 shard. + for (int test_id = 0; test_id < num_tests; test_id++) { + int prev_selected_shard_index = -1; + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + if (ShouldRunTestOnShard(num_shards, shard_index, test_id)) { + if (prev_selected_shard_index < 0) { + prev_selected_shard_index = shard_index; + } else { + ADD_FAILURE() << "Shard " << prev_selected_shard_index << " and " + << shard_index << " are both selected to run test " << test_id; + } + } + } + } + + // Check balance: This is not required by the sharding protocol, but is a + // desirable property for performance. + for (int shard_index = 0; shard_index < num_shards; shard_index++) { + int num_tests_on_shard = 0; + for (int test_id = 0; test_id < num_tests; test_id++) { + num_tests_on_shard += + ShouldRunTestOnShard(num_shards, shard_index, test_id); + } + EXPECT_GE(num_tests_on_shard, num_tests / num_shards); + } +} + +// For the same reason we are not explicitly testing everything in the +// Test class, there are no separate tests for the following classes +// (except for some trivial cases): +// +// TestCase, UnitTest, UnitTestResultPrinter. +// +// Similarly, there are no separate tests for the following macros: +// +// TEST, TEST_F, RUN_ALL_TESTS + +TEST(UnitTestTest, CanGetOriginalWorkingDir) { + ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != NULL); + EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), ""); +} + +TEST(UnitTestTest, ReturnsPlausibleTimestamp) { + EXPECT_LT(0, UnitTest::GetInstance()->start_timestamp()); + EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis()); +} + +// When a property using a reserved key is supplied to this function, it +// tests that a non-fatal failure is added, a fatal failure is not added, +// and that the property is not recorded. +void ExpectNonFatalFailureRecordingPropertyWithReservedKey( + const TestResult& test_result, const char* key) { + EXPECT_NONFATAL_FAILURE(Test::RecordProperty(key, "1"), "Reserved key"); + ASSERT_EQ(0, test_result.test_property_count()) << "Property for key '" << key + << "' recorded unexpectedly."; +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + const char* key) { + const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(test_info != NULL); + ExpectNonFatalFailureRecordingPropertyWithReservedKey(*test_info->result(), + key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + const char* key) { + const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); + ASSERT_TRUE(test_case != NULL); + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + test_case->ad_hoc_test_result(), key); +} + +void ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + const char* key) { + ExpectNonFatalFailureRecordingPropertyWithReservedKey( + UnitTest::GetInstance()->ad_hoc_test_result(), key); +} + +// Tests that property recording functions in UnitTest outside of tests +// functions correcly. Creating a separate instance of UnitTest ensures it +// is in a state similar to the UnitTest's singleton's between tests. +class UnitTestRecordPropertyTest : + public testing::internal::UnitTestRecordPropertyTestHelper { + public: + static void SetUpTestCase() { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( + "time"); + + Test::RecordProperty("test_case_key_1", "1"); + const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); + ASSERT_TRUE(test_case != NULL); + + ASSERT_EQ(1, test_case->ad_hoc_test_result().test_property_count()); + EXPECT_STREQ("test_case_key_1", + test_case->ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + test_case->ad_hoc_test_result().GetTestProperty(0).value()); + } +}; + +// Tests TestResult has the expected property when added. +TEST_F(UnitTestRecordPropertyTest, OnePropertyFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + + ASSERT_EQ(1, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); +} + +// Tests TestResult has multiple properties when added. +TEST_F(UnitTestRecordPropertyTest, MultiplePropertiesFoundWhenAdded) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("1", unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("2", unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +// Tests TestResult::RecordProperty() overrides values for duplicate keys. +TEST_F(UnitTestRecordPropertyTest, OverridesValuesForDuplicateKeys) { + UnitTestRecordProperty("key_1", "1"); + UnitTestRecordProperty("key_2", "2"); + UnitTestRecordProperty("key_1", "12"); + UnitTestRecordProperty("key_2", "22"); + + ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); + + EXPECT_STREQ("key_1", + unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); + EXPECT_STREQ("12", + unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); + + EXPECT_STREQ("key_2", + unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); + EXPECT_STREQ("22", + unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); +} + +TEST_F(UnitTestRecordPropertyTest, + AddFailureInsideTestsWhenUsingTestCaseReservedKeys) { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "value_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "type_param"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "status"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( + "classname"); +} + +TEST_F(UnitTestRecordPropertyTest, + AddRecordWithReservedKeysGeneratesCorrectPropertyList) { + EXPECT_NONFATAL_FAILURE( + Test::RecordProperty("name", "1"), + "'classname', 'name', 'status', 'time', 'type_param', and 'value_param'" + " are reserved"); +} + +class UnitTestRecordPropertyTestEnvironment : public Environment { + public: + virtual void TearDown() { + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "tests"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "failures"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "disabled"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "errors"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "name"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "timestamp"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "time"); + ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( + "random_seed"); + } +}; + +// This will test property recording outside of any test or test case. +static Environment* record_property_env = + AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment); + +// This group of tests is for predicate assertions (ASSERT_PRED*, etc) +// of various arities. They do not attempt to be exhaustive. Rather, +// view them as smoke tests that can be easily reviewed and verified. +// A more complete set of tests for predicate assertions can be found +// in gtest_pred_impl_unittest.cc. + +// First, some predicates and predicate-formatters needed by the tests. + +// Returns true iff the argument is an even number. +bool IsEven(int n) { + return (n % 2) == 0; +} + +// A functor that returns true iff the argument is an even number. +struct IsEvenFunctor { + bool operator()(int n) { return IsEven(n); } +}; + +// A predicate-formatter function that asserts the argument is an even +// number. +AssertionResult AssertIsEven(const char* expr, int n) { + if (IsEven(n)) { + return AssertionSuccess(); + } + + Message msg; + msg << expr << " evaluates to " << n << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate function that returns AssertionResult for use in +// EXPECT/ASSERT_TRUE/FALSE. +AssertionResult ResultIsEven(int n) { + if (IsEven(n)) + return AssertionSuccess() << n << " is even"; + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate function that returns AssertionResult but gives no +// explanation why it succeeds. Needed for testing that +// EXPECT/ASSERT_FALSE handles such functions correctly. +AssertionResult ResultIsEvenNoExplanation(int n) { + if (IsEven(n)) + return AssertionSuccess(); + else + return AssertionFailure() << n << " is odd"; +} + +// A predicate-formatter functor that asserts the argument is an even +// number. +struct AssertIsEvenFunctor { + AssertionResult operator()(const char* expr, int n) { + return AssertIsEven(expr, n); + } +}; + +// Returns true iff the sum of the arguments is an even number. +bool SumIsEven2(int n1, int n2) { + return IsEven(n1 + n2); +} + +// A functor that returns true iff the sum of the arguments is an even +// number. +struct SumIsEven3Functor { + bool operator()(int n1, int n2, int n3) { + return IsEven(n1 + n2 + n3); + } +}; + +// A predicate-formatter function that asserts the sum of the +// arguments is an even number. +AssertionResult AssertSumIsEven4( + const char* e1, const char* e2, const char* e3, const char* e4, + int n1, int n2, int n3, int n4) { + const int sum = n1 + n2 + n3 + n4; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 + << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); +} + +// A predicate-formatter functor that asserts the sum of the arguments +// is an even number. +struct AssertSumIsEven5Functor { + AssertionResult operator()( + const char* e1, const char* e2, const char* e3, const char* e4, + const char* e5, int n1, int n2, int n3, int n4, int n5) { + const int sum = n1 + n2 + n3 + n4 + n5; + if (IsEven(sum)) { + return AssertionSuccess(); + } + + Message msg; + msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 + << " (" + << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5 + << ") evaluates to " << sum << ", which is not even."; + return AssertionFailure(msg); + } +}; + + +// Tests unary predicate assertions. + +// Tests unary predicate assertions that don't use a custom formatter. +TEST(Pred1Test, WithoutFormat) { + // Success cases. + EXPECT_PRED1(IsEvenFunctor(), 2) << "This failure is UNEXPECTED!"; + ASSERT_PRED1(IsEven, 4); + + // Failure cases. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED1(IsEven, 5) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE(ASSERT_PRED1(IsEvenFunctor(), 5), + "evaluates to false"); +} + +// Tests unary predicate assertions that use a custom formatter. +TEST(Pred1Test, WithFormat) { + // Success cases. + EXPECT_PRED_FORMAT1(AssertIsEven, 2); + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), 4) + << "This failure is UNEXPECTED!"; + + // Failure cases. + const int n = 5; + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT1(AssertIsEvenFunctor(), n), + "n evaluates to 5, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEven, 5) << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that unary predicate assertions evaluates their arguments +// exactly once. +TEST(Pred1Test, SingleEvaluationOnFailure) { + // A success case. + static int n = 0; + EXPECT_PRED1(IsEven, n++); + EXPECT_EQ(1, n) << "The argument is not evaluated exactly once."; + + // A failure case. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), n++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(2, n) << "The argument is not evaluated exactly once."; +} + + +// Tests predicate assertions whose arity is >= 2. + +// Tests predicate assertions that don't use a custom formatter. +TEST(PredTest, WithoutFormat) { + // Success cases. + ASSERT_PRED2(SumIsEven2, 2, 4) << "This failure is UNEXPECTED!"; + EXPECT_PRED3(SumIsEven3Functor(), 4, 6, 8); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED2(SumIsEven2, n1, n2) << "This failure is expected."; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED3(SumIsEven3Functor(), 1, 2, 4); + }, "evaluates to false"); +} + +// Tests predicate assertions that use a custom formatter. +TEST(PredTest, WithFormat) { + // Success cases. + ASSERT_PRED_FORMAT4(AssertSumIsEven4, 4, 6, 8, 10) << + "This failure is UNEXPECTED!"; + EXPECT_PRED_FORMAT5(AssertSumIsEven5Functor(), 2, 4, 6, 8, 10); + + // Failure cases. + const int n1 = 1; + const int n2 = 2; + const int n3 = 4; + const int n4 = 6; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, n1, n2, n3, n4); + }, "evaluates to 13, which is not even."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), 1, 2, 4, 6, 8) + << "This failure is expected."; + }, "This failure is expected."); +} + +// Tests that predicate assertions evaluates their arguments +// exactly once. +TEST(PredTest, SingleEvaluationOnFailure) { + // A success case. + int n1 = 0; + int n2 = 0; + EXPECT_PRED2(SumIsEven2, n1++, n2++); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + + // Another success case. + n1 = n2 = 0; + int n3 = 0; + int n4 = 0; + int n5 = 0; + ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), + n1++, n2++, n3++, n4++, n5++) + << "This failure is UNEXPECTED!"; + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; + EXPECT_EQ(1, n5) << "Argument 5 is not evaluated exactly once."; + + // A failure case. + n1 = n2 = n3 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED3(SumIsEven3Functor(), ++n1, n2++, n3++) + << "This failure is expected."; + }, "This failure is expected."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + + // Another failure case. + n1 = n2 = n3 = n4 = 0; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT4(AssertSumIsEven4, ++n1, n2++, n3++, n4++); + }, "evaluates to 1, which is not even."); + EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; + EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; + EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; + EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PREDn and EXPECT_PREDn. + +bool IsPositive(double x) { + return x > 0; +} + +template +bool IsNegative(T x) { + return x < 0; +} + +template +bool GreaterThan(T1 x1, T2 x2) { + return x1 > x2; +} + +// Tests that overloaded functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { + // C++Builder requires C-style casts rather than static_cast. + EXPECT_PRED1((bool (*)(int))(IsPositive), 5); // NOLINT + ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0); // NOLINT +} + +// Tests that template functions can be used in *_PRED* as long as +// their types are explicitly specified. +TEST(PredicateAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED1(IsNegative, -5); + // Makes sure that we can handle templates with more than one + // parameter. + ASSERT_PRED2((GreaterThan), 5, 0); +} + + +// Some helper functions for testing using overloaded/template +// functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. + +AssertionResult IsPositiveFormat(const char* /* expr */, int n) { + return n > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +AssertionResult IsPositiveFormat(const char* /* expr */, double x) { + return x > 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult IsNegativeFormat(const char* /* expr */, T x) { + return x < 0 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +template +AssertionResult EqualsFormat(const char* /* expr1 */, const char* /* expr2 */, + const T1& x1, const T2& x2) { + return x1 == x2 ? AssertionSuccess() : + AssertionFailure(Message() << "Failure"); +} + +// Tests that overloaded functions can be used in *_PRED_FORMAT* +// without explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) { + EXPECT_PRED_FORMAT1(IsPositiveFormat, 5); + ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0); +} + +// Tests that template functions can be used in *_PRED_FORMAT* without +// explicitly specifying their types. +TEST(PredicateFormatAssertionTest, AcceptsTemplateFunction) { + EXPECT_PRED_FORMAT1(IsNegativeFormat, -5); + ASSERT_PRED_FORMAT2(EqualsFormat, 3, 3); +} + + +// Tests string assertions. + +// Tests ASSERT_STREQ with non-NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ) { + const char * const p1 = "good"; + ASSERT_STREQ(p1, p1); + + // Let p2 have the same content as p1, but be at a different address. + const char p2[] = "good"; + ASSERT_STREQ(p1, p2); + + EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"), + "Expected: \"bad\""); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null) { + ASSERT_STREQ(static_cast(NULL), NULL); + EXPECT_FATAL_FAILURE(ASSERT_STREQ(NULL, "non-null"), + "non-null"); +} + +// Tests ASSERT_STREQ with NULL arguments. +TEST(StringAssertionTest, ASSERT_STREQ_Null2) { + EXPECT_FATAL_FAILURE(ASSERT_STREQ("non-null", NULL), + "non-null"); +} + +// Tests ASSERT_STRNE. +TEST(StringAssertionTest, ASSERT_STRNE) { + ASSERT_STRNE("hi", "Hi"); + ASSERT_STRNE("Hi", NULL); + ASSERT_STRNE(NULL, "Hi"); + ASSERT_STRNE("", NULL); + ASSERT_STRNE(NULL, ""); + ASSERT_STRNE("", "Hi"); + ASSERT_STRNE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("Hi", "Hi"), + "\"Hi\" vs \"Hi\""); +} + +// Tests ASSERT_STRCASEEQ. +TEST(StringAssertionTest, ASSERT_STRCASEEQ) { + ASSERT_STRCASEEQ("hi", "Hi"); + ASSERT_STRCASEEQ(static_cast(NULL), NULL); + + ASSERT_STRCASEEQ("", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("Hi", "hi2"), + "(ignoring case)"); +} + +// Tests ASSERT_STRCASENE. +TEST(StringAssertionTest, ASSERT_STRCASENE) { + ASSERT_STRCASENE("hi1", "Hi2"); + ASSERT_STRCASENE("Hi", NULL); + ASSERT_STRCASENE(NULL, "Hi"); + ASSERT_STRCASENE("", NULL); + ASSERT_STRCASENE(NULL, ""); + ASSERT_STRCASENE("", "Hi"); + ASSERT_STRCASENE("Hi", ""); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), + "(ignoring case)"); +} + +// Tests *_STREQ on wide strings. +TEST(StringAssertionTest, STREQ_Wide) { + // NULL strings. + ASSERT_STREQ(static_cast(NULL), NULL); + + // Empty strings. + ASSERT_STREQ(L"", L""); + + // Non-null vs NULL. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"non-null", NULL), + "non-null"); + + // Equal strings. + EXPECT_STREQ(L"Hi", L"Hi"); + + // Unequal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc", L"Abc"), + "Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), + "abc"); + + // The streaming variation. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STREQ(L"abc\x8119", L"abc\x8121") << "Expected failure"; + }, "Expected failure"); +} + +// Tests *_STRNE on wide strings. +TEST(StringAssertionTest, STRNE_Wide) { + // NULL strings. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_STRNE(static_cast(NULL), NULL); + }, ""); + + // Empty strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"", L""), + "L\"\""); + + // Non-null vs NULL. + ASSERT_STRNE(L"non-null", NULL); + + // Equal strings. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"Hi", L"Hi"), + "L\"Hi\""); + + // Unequal strings. + EXPECT_STRNE(L"abc", L"Abc"); + + // Strings containing wide characters. + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), + "abc"); + + // The streaming variation. + ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen"; +} + +// Tests for ::testing::IsSubstring(). + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_FALSE(IsSubstring("", "", NULL, "a")); + EXPECT_FALSE(IsSubstring("", "", "b", NULL)); + EXPECT_FALSE(IsSubstring("", "", "needle", "haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", "needle", "two needles")); +} + +// Tests that IsSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_FALSE(IsSubstring("", "", kNull, L"a")); + EXPECT_FALSE(IsSubstring("", "", L"b", kNull)); + EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); + + EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); + EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is const char*. +TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: \"haystack\"", + IsSubstring("needle_expr", "haystack_expr", + "needle", "haystack").failure_message()); +} + +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); +} + +#if GTEST_HAS_STD_WSTRING +// Tests that IsSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +// Tests that IsSubstring() generates the correct message when the input +// argument type is ::std::wstring. +TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: a substring of haystack_expr\n" + "Which is: L\"haystack\"", + IsSubstring( + "needle_expr", "haystack_expr", + ::std::wstring(L"needle"), L"haystack").failure_message()); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests for ::testing::IsNotSubstring(). + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const char*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { + EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack")); + EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); +} + +// Tests that IsNotSubstring() returns the correct result when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) { + EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack")); + EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles")); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is const wchar_t*. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: L\"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: L\"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + L"needle", L"two needles").failure_message()); +} + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { + EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); + EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); +} + +// Tests that IsNotSubstring() generates the correct message when the input +// argument type is ::std::string. +TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { + EXPECT_STREQ("Value of: needle_expr\n" + " Actual: \"needle\"\n" + "Expected: not a substring of haystack_expr\n" + "Which is: \"two needles\"", + IsNotSubstring( + "needle_expr", "haystack_expr", + ::std::string("needle"), "two needles").failure_message()); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests that IsNotSubstring returns the correct result when the input +// argument type is ::std::wstring. +TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { + EXPECT_FALSE( + IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles")); + EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack"))); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Tests floating-point assertions. + +template +class FloatingPointTest : public Test { + protected: + // Pre-calculated numbers to be used by the tests. + struct TestValues { + RawType close_to_positive_zero; + RawType close_to_negative_zero; + RawType further_from_negative_zero; + + RawType close_to_one; + RawType further_from_one; + + RawType infinity; + RawType close_to_infinity; + RawType further_from_infinity; + + RawType nan1; + RawType nan2; + }; + + typedef typename testing::internal::FloatingPoint Floating; + typedef typename Floating::Bits Bits; + + virtual void SetUp() { + const size_t max_ulps = Floating::kMaxUlps; + + // The bits that represent 0.0. + const Bits zero_bits = Floating(0).bits(); + + // Makes some numbers close to 0.0. + values_.close_to_positive_zero = Floating::ReinterpretBits( + zero_bits + max_ulps/2); + values_.close_to_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps - max_ulps/2); + values_.further_from_negative_zero = -Floating::ReinterpretBits( + zero_bits + max_ulps + 1 - max_ulps/2); + + // The bits that represent 1.0. + const Bits one_bits = Floating(1).bits(); + + // Makes some numbers close to 1.0. + values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps); + values_.further_from_one = Floating::ReinterpretBits( + one_bits + max_ulps + 1); + + // +infinity. + values_.infinity = Floating::Infinity(); + + // The bits that represent +infinity. + const Bits infinity_bits = Floating(values_.infinity).bits(); + + // Makes some numbers close to infinity. + values_.close_to_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps); + values_.further_from_infinity = Floating::ReinterpretBits( + infinity_bits - max_ulps - 1); + + // Makes some NAN's. Sets the most significant bit of the fraction so that + // our NaN's are quiet; trying to process a signaling NaN would raise an + // exception if our environment enables floating point exceptions. + values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 1); + values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask + | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 200); + } + + void TestSize() { + EXPECT_EQ(sizeof(RawType), sizeof(Bits)); + } + + static TestValues values_; +}; + +template +typename FloatingPointTest::TestValues + FloatingPointTest::values_; + +// Instantiates FloatingPointTest for testing *_FLOAT_EQ. +typedef FloatingPointTest FloatTest; + +// Tests that the size of Float::Bits matches the size of float. +TEST_F(FloatTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(FloatTest, Zeros) { + EXPECT_FLOAT_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.5), + "1.5"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_FLOAT_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(FloatTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); + EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); + EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FLOAT_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(FloatTest, SmallDiff) { + EXPECT_FLOAT_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(FloatTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(2.5, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(FloatTest, Infinity) { + EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity and nan1 + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that comparing with NAN always returns false. +TEST_F(FloatTest, NaN) { +#if !GTEST_OS_SYMBIAN +// Nokia's STLport crashes if we try to output infinity or NaN. + + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const FloatTest::TestValues& v = this->values_; + + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), + "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), + "v.nan1"); + + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), + "v.infinity"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_FLOAT_EQ are reflexive. +TEST_F(FloatTest, Reflexive) { + EXPECT_FLOAT_EQ(0.0, 0.0); + EXPECT_FLOAT_EQ(1.0, 1.0); + ASSERT_FLOAT_EQ(values_.infinity, values_.infinity); +} + +// Tests that *_FLOAT_EQ are commutative. +TEST_F(FloatTest, Commutative) { + // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one). + EXPECT_FLOAT_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(FloatTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0f, -1.1f, 0.2f); + EXPECT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests ASSERT_NEAR. +TEST_F(FloatTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0f, -1.1f, 0.2f); + ASSERT_NEAR(2.0f, 3.0f, 1.0f); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT + "The difference between 1.0f and 1.5f is 0.5, " + "which exceeds 0.25f"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous line. +} + +// Tests the cases where FloatLE() should succeed. +TEST_F(FloatTest, FloatLESucceeds) { + EXPECT_PRED_FORMAT2(FloatLE, 1.0f, 2.0f); // When val1 < val2, + ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f); +} + +// Tests the cases where FloatLE() should fail. +TEST_F(FloatTest, FloatLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(FloatLE, 2.0f, 1.0f), + "(2.0f) <= (1.0f)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f); + }, "(values_.further_from_one) <= (1.0f)"); + +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) + // Nokia's STLport crashes if we try to output infinity or NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1); + }, "(-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) +} + +// Instantiates FloatingPointTest for testing *_DOUBLE_EQ. +typedef FloatingPointTest DoubleTest; + +// Tests that the size of Double::Bits matches the size of double. +TEST_F(DoubleTest, Size) { + TestSize(); +} + +// Tests comparing with +0 and -0. +TEST_F(DoubleTest, Zeros) { + EXPECT_DOUBLE_EQ(0.0, -0.0); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(-0.0, 1.0), + "1.0"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(0.0, 1.0), + "1.0"); +} + +// Tests comparing numbers close to 0. +// +// This ensures that *_DOUBLE_EQ handles the sign correctly and no +// overflow occurs when comparing numbers whose absolute value is very +// small. +TEST_F(DoubleTest, AlmostZeros) { + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; + + EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); + EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); + EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero); + + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_DOUBLE_EQ(v.close_to_positive_zero, + v.further_from_negative_zero); + }, "v.further_from_negative_zero"); +} + +// Tests comparing numbers close to each other. +TEST_F(DoubleTest, SmallDiff) { + EXPECT_DOUBLE_EQ(1.0, values_.close_to_one); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one), + "values_.further_from_one"); +} + +// Tests comparing numbers far apart. +TEST_F(DoubleTest, LargeDiff) { + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(2.0, 3.0), + "3.0"); +} + +// Tests comparing with infinity. +// +// This ensures that no overflow occurs when comparing numbers whose +// absolute value is very large. +TEST_F(DoubleTest, Infinity) { + EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); + EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), + "-values_.infinity"); + + // This is interesting as the representations of infinity_ and nan1_ + // are only 1 DLP apart. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1), + "values_.nan1"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that comparing with NAN always returns false. +TEST_F(DoubleTest, NaN) { +#if !GTEST_OS_SYMBIAN + // In C++Builder, names within local classes (such as used by + // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the + // scoping class. Use a static local alias as a workaround. + // We use the assignment syntax since some compilers, like Sun Studio, + // don't allow initializing references using construction syntax + // (parentheses). + static const DoubleTest::TestValues& v = this->values_; + + // Nokia's STLport crashes if we try to output infinity or NaN. + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), + "v.nan1"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); + EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), + "v.infinity"); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_DOUBLE_EQ are reflexive. +TEST_F(DoubleTest, Reflexive) { + EXPECT_DOUBLE_EQ(0.0, 0.0); + EXPECT_DOUBLE_EQ(1.0, 1.0); +#if !GTEST_OS_SYMBIAN + // Nokia's STLport crashes if we try to output infinity or NaN. + ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity); +#endif // !GTEST_OS_SYMBIAN +} + +// Tests that *_DOUBLE_EQ are commutative. +TEST_F(DoubleTest, Commutative) { + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one). + EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0); + + // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one). + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0), + "1.0"); +} + +// Tests EXPECT_NEAR. +TEST_F(DoubleTest, EXPECT_NEAR) { + EXPECT_NEAR(-1.0, -1.1, 0.2); + EXPECT_NEAR(2.0, 3.0, 1.0); + EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests ASSERT_NEAR. +TEST_F(DoubleTest, ASSERT_NEAR) { + ASSERT_NEAR(-1.0, -1.1, 0.2); + ASSERT_NEAR(2.0, 3.0, 1.0); + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT + "The difference between 1.0 and 1.5 is 0.5, " + "which exceeds 0.25"); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests the cases where DoubleLE() should succeed. +TEST_F(DoubleTest, DoubleLESucceeds) { + EXPECT_PRED_FORMAT2(DoubleLE, 1.0, 2.0); // When val1 < val2, + ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, + + // or when val1 is greater than, but almost equals to, val2. + EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0); +} + +// Tests the cases where DoubleLE() should fail. +TEST_F(DoubleTest, DoubleLEFails) { + // When val1 is greater than val2 by a large margin, + EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(DoubleLE, 2.0, 1.0), + "(2.0) <= (1.0)"); + + // or by a small yet non-negligible margin, + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0); + }, "(values_.further_from_one) <= (1.0)"); + +#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) + // Nokia's STLport crashes if we try to output infinity or NaN. + // C++Builder gives bad results for ordered comparisons involving NaNs + // due to compiler bugs. + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity); + }, "(values_.nan1) <= (values_.infinity)"); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1); + }, " (-values_.infinity) <= (values_.nan1)"); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1); + }, "(values_.nan1) <= (values_.nan1)"); +#endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) +} + + +// Verifies that a test or test case whose name starts with DISABLED_ is +// not run. + +// A test whose name starts with DISABLED_. +// Should not run. +TEST(DisabledTest, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// A test whose name does not start with DISABLED_. +// Should run. +TEST(DisabledTest, NotDISABLED_TestShouldRun) { + EXPECT_EQ(1, 1); +} + +// A test case whose name starts with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// A test case and test whose names start with DISABLED_. +// Should not run. +TEST(DISABLED_TestCase, DISABLED_TestShouldNotRun) { + FAIL() << "Unexpected failure: Test in disabled test case should not be run."; +} + +// Check that when all tests in a test case are disabled, SetupTestCase() and +// TearDownTestCase() are not called. +class DisabledTestsTest : public Test { + protected: + static void SetUpTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "SetupTestCase() should not be called."; + } + + static void TearDownTestCase() { + FAIL() << "Unexpected failure: All tests disabled in test case. " + "TearDownTestCase() should not be called."; + } +}; + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_1) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { + FAIL() << "Unexpected failure: Disabled test should not be run."; +} + +// Tests that disabled typed tests aren't run. + +#if GTEST_HAS_TYPED_TEST + +template +class TypedTest : public Test { +}; + +typedef testing::Types NumericTypes; +TYPED_TEST_CASE(TypedTest, NumericTypes); + +TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +template +class DISABLED_TypedTest : public Test { +}; + +TYPED_TEST_CASE(DISABLED_TypedTest, NumericTypes); + +TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) { + FAIL() << "Unexpected failure: Disabled typed test should not run."; +} + +#endif // GTEST_HAS_TYPED_TEST + +// Tests that disabled type-parameterized tests aren't run. + +#if GTEST_HAS_TYPED_TEST_P + +template +class TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(TypedTestP); + +TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(TypedTestP, DISABLED_ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, TypedTestP, NumericTypes); + +template +class DISABLED_TypedTestP : public Test { +}; + +TYPED_TEST_CASE_P(DISABLED_TypedTestP); + +TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) { + FAIL() << "Unexpected failure: " + << "Disabled type-parameterized test should not run."; +} + +REGISTER_TYPED_TEST_CASE_P(DISABLED_TypedTestP, ShouldNotRun); + +INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); + +#endif // GTEST_HAS_TYPED_TEST_P + +// Tests that assertion macros evaluate their arguments exactly once. + +class SingleEvaluationTest : public Test { + public: // Must be public and not protected due to a bug in g++ 3.4.2. + // This helper function is needed by the FailedASSERT_STREQ test + // below. It's public to work around C++Builder's bug with scoping local + // classes. + static void CompareAndIncrementCharPtrs() { + ASSERT_STREQ(p1_++, p2_++); + } + + // This helper function is needed by the FailedASSERT_NE test below. It's + // public to work around C++Builder's bug with scoping local classes. + static void CompareAndIncrementInts() { + ASSERT_NE(a_++, b_++); + } + + protected: + SingleEvaluationTest() { + p1_ = s1_; + p2_ = s2_; + a_ = 0; + b_ = 0; + } + + static const char* const s1_; + static const char* const s2_; + static const char* p1_; + static const char* p2_; + + static int a_; + static int b_; +}; + +const char* const SingleEvaluationTest::s1_ = "01234"; +const char* const SingleEvaluationTest::s2_ = "abcde"; +const char* SingleEvaluationTest::p1_; +const char* SingleEvaluationTest::p2_; +int SingleEvaluationTest::a_; +int SingleEvaluationTest::b_; + +// Tests that when ASSERT_STREQ fails, it evaluates its arguments +// exactly once. +TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(), + "p2_++"); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); +} + +// Tests that string assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ASSERT_STR) { + // successful EXPECT_STRNE + EXPECT_STRNE(p1_++, p2_++); + EXPECT_EQ(s1_ + 1, p1_); + EXPECT_EQ(s2_ + 1, p2_); + + // failed EXPECT_STRCASEEQ + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ(p1_++, p2_++), + "ignoring case"); + EXPECT_EQ(s1_ + 2, p1_); + EXPECT_EQ(s2_ + 2, p2_); +} + +// Tests that when ASSERT_NE fails, it evaluates its arguments exactly +// once. +TEST_F(SingleEvaluationTest, FailedASSERT_NE) { + EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(), + "(a_++) != (b_++)"); + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, OtherCases) { + // successful EXPECT_TRUE + EXPECT_TRUE(0 == a_++); // NOLINT + EXPECT_EQ(1, a_); + + // failed EXPECT_TRUE + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(-1 == a_++), "-1 == a_++"); + EXPECT_EQ(2, a_); + + // successful EXPECT_GT + EXPECT_GT(a_++, b_++); + EXPECT_EQ(3, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_LT + EXPECT_NONFATAL_FAILURE(EXPECT_LT(a_++, b_++), "(a_++) < (b_++)"); + EXPECT_EQ(4, a_); + EXPECT_EQ(2, b_); + + // successful ASSERT_TRUE + ASSERT_TRUE(0 < a_++); // NOLINT + EXPECT_EQ(5, a_); + + // successful ASSERT_GT + ASSERT_GT(a_++, b_++); + EXPECT_EQ(6, a_); + EXPECT_EQ(3, b_); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAnInteger() { + throw 1; +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ExceptionTests) { + // successful EXPECT_THROW + EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, int); + EXPECT_EQ(1, a_); + + // failed EXPECT_THROW, throws different + EXPECT_NONFATAL_FAILURE(EXPECT_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }, bool), "throws a different type"); + EXPECT_EQ(2, a_); + + // failed EXPECT_THROW, throws nothing + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing"); + EXPECT_EQ(3, a_); + + // successful EXPECT_NO_THROW + EXPECT_NO_THROW(a_++); + EXPECT_EQ(4, a_); + + // failed EXPECT_NO_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }), "it throws"); + EXPECT_EQ(5, a_); + + // successful EXPECT_ANY_THROW + EXPECT_ANY_THROW({ // NOLINT + a_++; + ThrowAnInteger(); + }); + EXPECT_EQ(6, a_); + + // failed EXPECT_ANY_THROW + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't"); + EXPECT_EQ(7, a_); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests {ASSERT|EXPECT}_NO_FATAL_FAILURE. +class NoFatalFailureTest : public Test { + protected: + void Succeeds() {} + void FailsNonFatal() { + ADD_FAILURE() << "some non-fatal failure"; + } + void Fails() { + FAIL() << "some fatal failure"; + } + + void DoAssertNoFatalFailureOnFails() { + ASSERT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "shold not reach here."; + } + + void DoExpectNoFatalFailureOnFails() { + EXPECT_NO_FATAL_FAILURE(Fails()); + ADD_FAILURE() << "other failure"; + } +}; + +TEST_F(NoFatalFailureTest, NoFailure) { + EXPECT_NO_FATAL_FAILURE(Succeeds()); + ASSERT_NO_FATAL_FAILURE(Succeeds()); +} + +TEST_F(NoFatalFailureTest, NonFatalIsNoFailure) { + EXPECT_NONFATAL_FAILURE( + EXPECT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); + EXPECT_NONFATAL_FAILURE( + ASSERT_NO_FATAL_FAILURE(FailsNonFatal()), + "some non-fatal failure"); +} + +TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoAssertNoFatalFailureOnFails(); + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); +} + +TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + DoExpectNoFatalFailureOnFails(); + } + ASSERT_EQ(3, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(2).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", + gtest_failures.GetTestPartResult(1).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "other failure", + gtest_failures.GetTestPartResult(2).message()); +} + +TEST_F(NoFatalFailureTest, MessageIsStreamable) { + TestPartResultArray gtest_failures; + { + ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); + EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; + } + ASSERT_EQ(2, gtest_failures.size()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(0).type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, + gtest_failures.GetTestPartResult(1).type()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", + gtest_failures.GetTestPartResult(0).message()); + EXPECT_PRED_FORMAT2(testing::IsSubstring, "my message", + gtest_failures.GetTestPartResult(1).message()); +} + +// Tests non-string assertions. + +// Tests EqFailure(), used for implementing *EQ* assertions. +TEST(AssertionTest, EqFailure) { + const std::string foo_val("5"), bar_val("6"); + const std::string msg1( + EqFailure("foo", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: foo\n" + "Which is: 5", + msg1.c_str()); + + const std::string msg2( + EqFailure("foo", "6", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: foo\n" + "Which is: 5", + msg2.c_str()); + + const std::string msg3( + EqFailure("5", "bar", foo_val, bar_val, false) + .failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: 6\n" + "Expected: 5", + msg3.c_str()); + + const std::string msg4( + EqFailure("5", "6", foo_val, bar_val, false).failure_message()); + EXPECT_STREQ( + "Value of: 6\n" + "Expected: 5", + msg4.c_str()); + + const std::string msg5( + EqFailure("foo", "bar", + std::string("\"x\""), std::string("\"y\""), + true).failure_message()); + EXPECT_STREQ( + "Value of: bar\n" + " Actual: \"y\"\n" + "Expected: foo (ignoring case)\n" + "Which is: \"x\"", + msg5.c_str()); +} + +// Tests AppendUserMessage(), used for implementing the *EQ* macros. +TEST(AssertionTest, AppendUserMessage) { + const std::string foo("foo"); + + Message msg; + EXPECT_STREQ("foo", + AppendUserMessage(foo, msg).c_str()); + + msg << "bar"; + EXPECT_STREQ("foo\nbar", + AppendUserMessage(foo, msg).c_str()); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests ASSERT_TRUE. +TEST(AssertionTest, ASSERT_TRUE) { + ASSERT_TRUE(2 > 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1), + "2 < 1"); +} + +// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertTrueWithAssertionResult) { + ASSERT_TRUE(ResultIsEven(2)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +#endif + ASSERT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests ASSERT_FALSE. +TEST(AssertionTest, ASSERT_FALSE) { + ASSERT_FALSE(2 < 1); // NOLINT + EXPECT_FATAL_FAILURE(ASSERT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); +} + +// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. +TEST(AssertionTest, AssertFalseWithAssertionResult) { + ASSERT_FALSE(ResultIsEven(3)); +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); +#endif + ASSERT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +// Tests using ASSERT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, ASSERT_EQ_Double) { + // A success. + ASSERT_EQ(5.6, 5.6); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(5.1, 5.2), + "5.1"); +} + +// Tests ASSERT_EQ. +TEST(AssertionTest, ASSERT_EQ) { + ASSERT_EQ(5, 2 + 3); + EXPECT_FATAL_FAILURE(ASSERT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); +} + +// Tests ASSERT_EQ(NULL, pointer). +#if GTEST_CAN_COMPARE_NULL +TEST(AssertionTest, ASSERT_EQ_NULL) { + // A success. + const char* p = NULL; + // Some older GCC versions may issue a spurious waring in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + ASSERT_EQ(NULL, p); + + // A failure. + static int n = 0; + EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // GTEST_CAN_COMPARE_NULL + +// Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that ASSERT_EQ(0, non_pointer) isn't interpreted by Google Test as +// ASSERT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, ASSERT_EQ_0) { + int n = 0; + + // A success. + ASSERT_EQ(0, n); + + // A failure. + EXPECT_FATAL_FAILURE(ASSERT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests ASSERT_NE. +TEST(AssertionTest, ASSERT_NE) { + ASSERT_NE(6, 7); + EXPECT_FATAL_FAILURE(ASSERT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); +} + +// Tests ASSERT_LE. +TEST(AssertionTest, ASSERT_LE) { + ASSERT_LE(2, 3); + ASSERT_LE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); +} + +// Tests ASSERT_LT. +TEST(AssertionTest, ASSERT_LT) { + ASSERT_LT(2, 3); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); +} + +// Tests ASSERT_GE. +TEST(AssertionTest, ASSERT_GE) { + ASSERT_GE(2, 1); + ASSERT_GE(2, 2); + EXPECT_FATAL_FAILURE(ASSERT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); +} + +// Tests ASSERT_GT. +TEST(AssertionTest, ASSERT_GT) { + ASSERT_GT(2, 1); + EXPECT_FATAL_FAILURE(ASSERT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowNothing() {} + +// Tests ASSERT_THROW. +TEST(AssertionTest, ASSERT_THROW) { + ASSERT_THROW(ThrowAnInteger(), int); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of type bool.\n" + " Actual: it throws a different type."); +# endif + + EXPECT_FATAL_FAILURE( + ASSERT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests ASSERT_NO_THROW. +TEST(AssertionTest, ASSERT_NO_THROW) { + ASSERT_NO_THROW(ThrowNothing()); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an exception." + "\n Actual: it throws."); +} + +// Tests ASSERT_ANY_THROW. +TEST(AssertionTest, ASSERT_ANY_THROW) { + ASSERT_ANY_THROW(ThrowAnInteger()); + EXPECT_FATAL_FAILURE( + ASSERT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Makes sure we deal with the precedence of <<. This test should +// compile. +TEST(AssertionTest, AssertPrecedence) { + ASSERT_EQ(1 < 2, true); + bool false_value = false; + ASSERT_EQ(true && false_value, false); +} + +// A subroutine used by the following test. +void TestEq1(int x) { + ASSERT_EQ(1, x); +} + +// Tests calling a test subroutine that's not part of a fixture. +TEST(AssertionTest, NonFixtureSubroutine) { + EXPECT_FATAL_FAILURE(TestEq1(2), + "Value of: x"); +} + +// An uncopyable class. +class Uncopyable { + public: + explicit Uncopyable(int a_value) : value_(a_value) {} + + int value() const { return value_; } + bool operator==(const Uncopyable& rhs) const { + return value() == rhs.value(); + } + private: + // This constructor deliberately has no implementation, as we don't + // want this class to be copyable. + Uncopyable(const Uncopyable&); // NOLINT + + int value_; +}; + +::std::ostream& operator<<(::std::ostream& os, const Uncopyable& value) { + return os << value.value(); +} + + +bool IsPositiveUncopyable(const Uncopyable& x) { + return x.value() > 0; +} + +// A subroutine used by the following test. +void TestAssertNonPositive() { + Uncopyable y(-1); + ASSERT_PRED1(IsPositiveUncopyable, y); +} +// A subroutine used by the following test. +void TestAssertEqualsUncopyable() { + Uncopyable x(5); + Uncopyable y(-1); + ASSERT_EQ(x, y); +} + +// Tests that uncopyable objects can be used in assertions. +TEST(AssertionTest, AssertWorksWithUncopyableObject) { + Uncopyable x(5); + ASSERT_PRED1(IsPositiveUncopyable, x); + ASSERT_EQ(x, x); + EXPECT_FATAL_FAILURE(TestAssertNonPositive(), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_FATAL_FAILURE(TestAssertEqualsUncopyable(), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + +// Tests that uncopyable objects can be used in expects. +TEST(AssertionTest, ExpectWorksWithUncopyableObject) { + Uncopyable x(5); + EXPECT_PRED1(IsPositiveUncopyable, x); + Uncopyable y(-1); + EXPECT_NONFATAL_FAILURE(EXPECT_PRED1(IsPositiveUncopyable, y), + "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); + EXPECT_EQ(x, x); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), + "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); +} + +enum NamedEnum { + kE1 = 0, + kE2 = 1 +}; + +TEST(AssertionTest, NamedEnum) { + EXPECT_EQ(kE1, kE1); + EXPECT_LT(kE1, kE2); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Actual: 1"); +} + +// The version of gcc used in XCode 2.2 has a bug and doesn't allow +// anonymous enums in assertions. Therefore the following test is not +// done on Mac. +// Sun Studio and HP aCC also reject this code. +#if !GTEST_OS_MAC && !defined(__SUNPRO_CC) && !defined(__HP_aCC) + +// Tests using assertions with anonymous enums. +enum { + kCaseA = -1, + +# if GTEST_OS_LINUX + + // We want to test the case where the size of the anonymous enum is + // larger than sizeof(int), to make sure our implementation of the + // assertions doesn't truncate the enums. However, MSVC + // (incorrectly) doesn't allow an enum value to exceed the range of + // an int, so this has to be conditionally compiled. + // + // On Linux, kCaseB and kCaseA have the same value when truncated to + // int size. We want to test whether this will confuse the + // assertions. + kCaseB = testing::internal::kMaxBiggestInt, + +# else + + kCaseB = INT_MAX, + +# endif // GTEST_OS_LINUX + + kCaseC = 42 +}; + +TEST(AssertionTest, AnonymousEnum) { +# if GTEST_OS_LINUX + + EXPECT_EQ(static_cast(kCaseA), static_cast(kCaseB)); + +# endif // GTEST_OS_LINUX + + EXPECT_EQ(kCaseA, kCaseA); + EXPECT_NE(kCaseA, kCaseB); + EXPECT_LT(kCaseA, kCaseB); + EXPECT_LE(kCaseA, kCaseB); + EXPECT_GT(kCaseB, kCaseA); + EXPECT_GE(kCaseA, kCaseA); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseB), + "(kCaseA) >= (kCaseB)"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseC), + "-1 vs 42"); + + ASSERT_EQ(kCaseA, kCaseA); + ASSERT_NE(kCaseA, kCaseB); + ASSERT_LT(kCaseA, kCaseB); + ASSERT_LE(kCaseA, kCaseB); + ASSERT_GT(kCaseB, kCaseA); + ASSERT_GE(kCaseA, kCaseA); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), + "Value of: kCaseB"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Actual: 42"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), + "Which is: -1"); +} + +#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) + +#if GTEST_OS_WINDOWS + +static HRESULT UnexpectedHRESULTFailure() { + return E_UNEXPECTED; +} + +static HRESULT OkHRESULTSuccess() { + return S_OK; +} + +static HRESULT FalseHRESULTSuccess() { + return S_FALSE; +} + +// HRESULT assertion tests test both zero and non-zero +// success codes as well as failure message for each. +// +// Windows CE doesn't support message texts. +TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) { + EXPECT_HRESULT_SUCCEEDED(S_OK); + EXPECT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) { + ASSERT_HRESULT_SUCCEEDED(S_OK); + ASSERT_HRESULT_SUCCEEDED(S_FALSE); + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), + "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" + " Actual: 0x8000FFFF"); +} + +TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { + EXPECT_HRESULT_FAILED(E_UNEXPECTED); + + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x0"); + EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x1"); +} + +TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { + ASSERT_HRESULT_FAILED(E_UNEXPECTED); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), + "Expected: (OkHRESULTSuccess()) fails.\n" + " Actual: 0x0"); +# endif + + EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), + "Expected: (FalseHRESULTSuccess()) fails.\n" + " Actual: 0x1"); +} + +// Tests that streaming to the HRESULT macros works. +TEST(HRESULTAssertionTest, Streaming) { + EXPECT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + ASSERT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; + EXPECT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + ASSERT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder 2007 and 2009. + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", + "expected failure"); +# endif + + EXPECT_NONFATAL_FAILURE( + EXPECT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); + + EXPECT_FATAL_FAILURE( + ASSERT_HRESULT_FAILED(S_OK) << "expected failure", + "expected failure"); +} + +#endif // GTEST_OS_WINDOWS + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +// Tests that the assertion macros behave like single statements. +TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + ASSERT_TRUE(false) << "This should never be executed; " + "It's a compilation test only."; + + if (AlwaysTrue()) + EXPECT_FALSE(false); + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_LT(1, 3); + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_GT(3, 2) << ""; +} + +#if GTEST_HAS_EXCEPTIONS +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros. +TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + + EXPECT_THROW(throw 1, int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), ""); + EXPECT_NO_THROW(n++); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), ""); + EXPECT_ANY_THROW(throw 1); + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), ""); +} + +TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_THROW(ThrowNothing(), bool); + + if (AlwaysTrue()) + EXPECT_THROW(ThrowAnInteger(), int); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_NO_THROW(ThrowAnInteger()); + + if (AlwaysTrue()) + EXPECT_NO_THROW(ThrowNothing()); + else + ; // NOLINT + + if (AlwaysFalse()) + EXPECT_ANY_THROW(ThrowNothing()); + + if (AlwaysTrue()) + EXPECT_ANY_THROW(ThrowAnInteger()); + else + ; // NOLINT +} +#endif // GTEST_HAS_EXCEPTIONS + +TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { + if (AlwaysFalse()) + EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " + << "It's a compilation test only."; + else + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; + else + ; // NOLINT + + if (AlwaysTrue()) + EXPECT_NO_FATAL_FAILURE(SUCCEED()); + else + ; // NOLINT + + if (AlwaysFalse()) + ; // NOLINT + else + ASSERT_NO_FATAL_FAILURE(SUCCEED()); +} + +// Tests that the assertion macros work well with switch statements. +TEST(AssertionSyntaxTest, WorksWithSwitch) { + switch (0) { + case 1: + break; + default: + ASSERT_TRUE(true); + } + + switch (0) + case 0: + EXPECT_FALSE(false) << "EXPECT_FALSE failed in switch case"; + + // Binary assertions are implemented using a different code path + // than the Boolean assertions. Hence we test them separately. + switch (0) { + case 1: + default: + ASSERT_EQ(1, 1) << "ASSERT_EQ failed in default switch handler"; + } + + switch (0) + case 0: + EXPECT_NE(1, 2); +} + +#if GTEST_HAS_EXCEPTIONS + +void ThrowAString() { + throw "std::string"; +} + +// Test that the exception assertion macros compile and work with const +// type qualifier. +TEST(AssertionSyntaxTest, WorksWithConst) { + ASSERT_THROW(ThrowAString(), const char*); + + EXPECT_THROW(ThrowAString(), const char*); +} + +#endif // GTEST_HAS_EXCEPTIONS + +} // namespace + +namespace testing { + +// Tests that Google Test tracks SUCCEED*. +TEST(SuccessfulAssertionTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "OK"; + EXPECT_EQ(2, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_*. +TEST(SuccessfulAssertionTest, EXPECT) { + EXPECT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful EXPECT_STR*. +TEST(SuccessfulAssertionTest, EXPECT_STR) { + EXPECT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_*. +TEST(SuccessfulAssertionTest, ASSERT) { + ASSERT_TRUE(true); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +// Tests that Google Test doesn't track successful ASSERT_STR*. +TEST(SuccessfulAssertionTest, ASSERT_STR) { + ASSERT_STREQ("", ""); + EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); +} + +} // namespace testing + +namespace { + +// Tests the message streaming variation of assertions. + +TEST(AssertionWithMessageTest, EXPECT) { + EXPECT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(1, 1) << "Expected failure #1.", + "Expected failure #1"); + EXPECT_LE(1, 2) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(1, 0) << "Expected failure #2.", + "Expected failure #2."); + EXPECT_GE(1, 0) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_GT(1, 2) << "Expected failure #3.", + "Expected failure #3."); + + EXPECT_STREQ("1", "1") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("1", "1") << "Expected failure #4.", + "Expected failure #4."); + EXPECT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("a", "A") << "Expected failure #5.", + "Expected failure #5."); + + EXPECT_FLOAT_EQ(1, 1) << "This should succeed."; + EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1, 1.2) << "Expected failure #6.", + "Expected failure #6."); + EXPECT_NEAR(1, 1.1, 0.2) << "This should succeed."; +} + +TEST(AssertionWithMessageTest, ASSERT) { + ASSERT_EQ(1, 1) << "This should succeed."; + ASSERT_NE(1, 2) << "This should succeed."; + ASSERT_LE(1, 2) << "This should succeed."; + ASSERT_LT(1, 2) << "This should succeed."; + ASSERT_GE(1, 0) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_GT(1, 2) << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_STR) { + ASSERT_STREQ("1", "1") << "This should succeed."; + ASSERT_STRNE("1", "2") << "This should succeed."; + ASSERT_STRCASEEQ("a", "A") << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("a", "A") << "Expected failure.", + "Expected failure."); +} + +TEST(AssertionWithMessageTest, ASSERT_FLOATING) { + ASSERT_FLOAT_EQ(1, 1) << "This should succeed."; + ASSERT_DOUBLE_EQ(1, 1) << "This should succeed."; + EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT + "Expect failure."); + // To work around a bug in gcc 2.95.0, there is intentionally no + // space after the first comma in the previous statement. +} + +// Tests using ASSERT_FALSE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_FALSE) { + ASSERT_FALSE(false) << "This shouldn't fail."; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_FALSE(true) << "Expected failure: " << 2 << " > " << 1 + << " evaluates to " << true; + }, "Expected failure"); +} + +// Tests using FAIL with a streamed message. +TEST(AssertionWithMessageTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL() << 0, + "0"); +} + +// Tests using SUCCEED with a streamed message. +TEST(AssertionWithMessageTest, SUCCEED) { + SUCCEED() << "Success == " << 1; +} + +// Tests using ASSERT_TRUE with a streamed message. +TEST(AssertionWithMessageTest, ASSERT_TRUE) { + ASSERT_TRUE(true) << "This should succeed."; + ASSERT_TRUE(true) << true; + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_TRUE(false) << static_cast(NULL) + << static_cast(NULL); + }, "(null)(null)"); +} + +#if GTEST_OS_WINDOWS +// Tests using wide strings in assertion messages. +TEST(AssertionWithMessageTest, WideStringMessage) { + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_TRUE(false) << L"This failure is expected.\x8119"; + }, "This failure is expected."); + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(1, 2) << "This failure is " + << L"expected too.\x8120"; + }, "This failure is expected too."); +} +#endif // GTEST_OS_WINDOWS + +// Tests EXPECT_TRUE. +TEST(ExpectTest, EXPECT_TRUE) { + EXPECT_TRUE(true) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_TRUE(2 > 1); // NOLINT + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), + "Value of: 2 < 1\n" + " Actual: false\n" + "Expected: true"); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3), + "2 > 3"); +} + +// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectTrueWithAssertionResult) { + EXPECT_TRUE(ResultIsEven(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)), + "Value of: ResultIsEven(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); + EXPECT_TRUE(ResultIsEvenNoExplanation(2)); + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)), + "Value of: ResultIsEvenNoExplanation(3)\n" + " Actual: false (3 is odd)\n" + "Expected: true"); +} + +// Tests EXPECT_FALSE with a streamed message. +TEST(ExpectTest, EXPECT_FALSE) { + EXPECT_FALSE(2 < 1); // NOLINT + EXPECT_FALSE(false) << "Intentional success"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #1.", + "Intentional failure #1."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #2.", + "Intentional failure #2."); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), + "Value of: 2 > 1\n" + " Actual: true\n" + "Expected: false"); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3), + "2 < 3"); +} + +// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult. +TEST(ExpectTest, ExpectFalseWithAssertionResult) { + EXPECT_FALSE(ResultIsEven(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)), + "Value of: ResultIsEven(2)\n" + " Actual: true (2 is even)\n" + "Expected: false"); + EXPECT_FALSE(ResultIsEvenNoExplanation(3)); + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)), + "Value of: ResultIsEvenNoExplanation(2)\n" + " Actual: true\n" + "Expected: false"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +// Tests EXPECT_EQ. +TEST(ExpectTest, EXPECT_EQ) { + EXPECT_EQ(5, 2 + 3); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2*3), + "Value of: 2*3\n" + " Actual: 6\n" + "Expected: 5"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2 - 3), + "2 - 3"); +} + +// Tests using EXPECT_EQ on double values. The purpose is to make +// sure that the specialization we did for integer and anonymous enums +// isn't used for double arguments. +TEST(ExpectTest, EXPECT_EQ_Double) { + // A success. + EXPECT_EQ(5.6, 5.6); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5.1, 5.2), + "5.1"); +} + +#if GTEST_CAN_COMPARE_NULL +// Tests EXPECT_EQ(NULL, pointer). +TEST(ExpectTest, EXPECT_EQ_NULL) { + // A success. + const char* p = NULL; + // Some older GCC versions may issue a spurious warning in this or the next + // assertion statement. This warning should not be suppressed with + // static_cast since the test verifies the ability to use bare NULL as the + // expected parameter to the macro. + EXPECT_EQ(NULL, p); + + // A failure. + int n = 0; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), + "Value of: &n\n"); +} +#endif // GTEST_CAN_COMPARE_NULL + +// Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be +// treated as a null pointer by the compiler, we need to make sure +// that EXPECT_EQ(0, non_pointer) isn't interpreted by Google Test as +// EXPECT_EQ(static_cast(NULL), non_pointer). +TEST(ExpectTest, EXPECT_EQ_0) { + int n = 0; + + // A success. + EXPECT_EQ(0, n); + + // A failure. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), + "Expected: 0"); +} + +// Tests EXPECT_NE. +TEST(ExpectTest, EXPECT_NE) { + EXPECT_NE(6, 7); + + EXPECT_NONFATAL_FAILURE(EXPECT_NE('a', 'a'), + "Expected: ('a') != ('a'), " + "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(2, 2), + "2"); + char* const p0 = NULL; + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p0, p0), + "p0"); + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + char* const p1 = reinterpret_cast(pv1); + EXPECT_NONFATAL_FAILURE(EXPECT_NE(p1, p1), + "p1"); +} + +// Tests EXPECT_LE. +TEST(ExpectTest, EXPECT_LE) { + EXPECT_LE(2, 3); + EXPECT_LE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(2, 0), + "Expected: (2) <= (0), actual: 2 vs 0"); + EXPECT_NONFATAL_FAILURE(EXPECT_LE(1.1, 0.9), + "(1.1) <= (0.9)"); +} + +// Tests EXPECT_LT. +TEST(ExpectTest, EXPECT_LT) { + EXPECT_LT(2, 3); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 2), + "Expected: (2) < (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1), + "(2) < (1)"); +} + +// Tests EXPECT_GE. +TEST(ExpectTest, EXPECT_GE) { + EXPECT_GE(2, 1); + EXPECT_GE(2, 2); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(2, 3), + "Expected: (2) >= (3), actual: 2 vs 3"); + EXPECT_NONFATAL_FAILURE(EXPECT_GE(0.9, 1.1), + "(0.9) >= (1.1)"); +} + +// Tests EXPECT_GT. +TEST(ExpectTest, EXPECT_GT) { + EXPECT_GT(2, 1); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 2), + "Expected: (2) > (2), actual: 2 vs 2"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 3), + "(2) > (3)"); +} + +#if GTEST_HAS_EXCEPTIONS + +// Tests EXPECT_THROW. +TEST(ExpectTest, EXPECT_THROW) { + EXPECT_THROW(ThrowAnInteger(), int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), + "Expected: ThrowAnInteger() throws an exception of " + "type bool.\n Actual: it throws a different type."); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW(ThrowNothing(), bool), + "Expected: ThrowNothing() throws an exception of type bool.\n" + " Actual: it throws nothing."); +} + +// Tests EXPECT_NO_THROW. +TEST(ExpectTest, EXPECT_NO_THROW) { + EXPECT_NO_THROW(ThrowNothing()); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()), + "Expected: ThrowAnInteger() doesn't throw an " + "exception.\n Actual: it throws."); +} + +// Tests EXPECT_ANY_THROW. +TEST(ExpectTest, EXPECT_ANY_THROW) { + EXPECT_ANY_THROW(ThrowAnInteger()); + EXPECT_NONFATAL_FAILURE( + EXPECT_ANY_THROW(ThrowNothing()), + "Expected: ThrowNothing() throws an exception.\n" + " Actual: it doesn't."); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Make sure we deal with the precedence of <<. +TEST(ExpectTest, ExpectPrecedence) { + EXPECT_EQ(1 < 2, true); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), + "Value of: true && false"); +} + + +// Tests the StreamableToString() function. + +// Tests using StreamableToString() on a scalar. +TEST(StreamableToStringTest, Scalar) { + EXPECT_STREQ("5", StreamableToString(5).c_str()); +} + +// Tests using StreamableToString() on a non-char pointer. +TEST(StreamableToStringTest, Pointer) { + int n = 0; + int* p = &n; + EXPECT_STRNE("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a NULL non-char pointer. +TEST(StreamableToStringTest, NullPointer) { + int* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using StreamableToString() on a C string. +TEST(StreamableToStringTest, CString) { + EXPECT_STREQ("Foo", StreamableToString("Foo").c_str()); +} + +// Tests using StreamableToString() on a NULL C string. +TEST(StreamableToStringTest, NullCString) { + char* p = NULL; + EXPECT_STREQ("(null)", StreamableToString(p).c_str()); +} + +// Tests using streamable values as assertion messages. + +// Tests using std::string as an assertion message. +TEST(StreamableTest, string) { + static const std::string str( + "This failure message is a std::string, and is expected."); + EXPECT_FATAL_FAILURE(FAIL() << str, + str.c_str()); +} + +// Tests that we can output strings containing embedded NULs. +// Limited to Linux because we can only do this with std::string's. +TEST(StreamableTest, stringWithEmbeddedNUL) { + static const char char_array_with_nul[] = + "Here's a NUL\0 and some more string"; + static const std::string string_with_nul(char_array_with_nul, + sizeof(char_array_with_nul) + - 1); // drops the trailing NUL + EXPECT_FATAL_FAILURE(FAIL() << string_with_nul, + "Here's a NUL\\0 and some more string"); +} + +// Tests that we can output a NUL char. +TEST(StreamableTest, NULChar) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "A NUL" << '\0' << " and some more string"; + }, "A NUL\\0 and some more string"); +} + +// Tests using int as an assertion message. +TEST(StreamableTest, int) { + EXPECT_FATAL_FAILURE(FAIL() << 900913, + "900913"); +} + +// Tests using NULL char pointer as an assertion message. +// +// In MSVC, streaming a NULL char * causes access violation. Google Test +// implemented a workaround (substituting "(null)" for NULL). This +// tests whether the workaround works. +TEST(StreamableTest, NullCharPtr) { + EXPECT_FATAL_FAILURE(FAIL() << static_cast(NULL), + "(null)"); +} + +// Tests that basic IO manipulators (endl, ends, and flush) can be +// streamed to testing::Message. +TEST(StreamableTest, BasicIoManip) { + EXPECT_FATAL_FAILURE({ // NOLINT + FAIL() << "Line 1." << std::endl + << "A NUL char " << std::ends << std::flush << " in line 2."; + }, "Line 1.\nA NUL char \\0 in line 2."); +} + +// Tests the macros that haven't been covered so far. + +void AddFailureHelper(bool* aborted) { + *aborted = true; + ADD_FAILURE() << "Intentional failure."; + *aborted = false; +} + +// Tests ADD_FAILURE. +TEST(MacroTest, ADD_FAILURE) { + bool aborted = true; + EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), + "Intentional failure."); + EXPECT_FALSE(aborted); +} + +// Tests ADD_FAILURE_AT. +TEST(MacroTest, ADD_FAILURE_AT) { + // Verifies that ADD_FAILURE_AT does generate a nonfatal failure and + // the failure message contains the user-streamed part. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42) << "Wrong!", "Wrong!"); + + // Verifies that the user-streamed part is optional. + EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42), "Failed"); + + // Unfortunately, we cannot verify that the failure message contains + // the right file path and line number the same way, as + // EXPECT_NONFATAL_FAILURE() doesn't get to see the file path and + // line number. Instead, we do that in gtest_output_test_.cc. +} + +// Tests FAIL. +TEST(MacroTest, FAIL) { + EXPECT_FATAL_FAILURE(FAIL(), + "Failed"); + EXPECT_FATAL_FAILURE(FAIL() << "Intentional failure.", + "Intentional failure."); +} + +// Tests SUCCEED +TEST(MacroTest, SUCCEED) { + SUCCEED(); + SUCCEED() << "Explicit success."; +} + +// Tests for EXPECT_EQ() and ASSERT_EQ(). +// +// These tests fail *intentionally*, s.t. the failure messages can be +// generated and tested. +// +// We have different tests for different argument types. + +// Tests using bool values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Bool) { + EXPECT_EQ(true, true); + EXPECT_FATAL_FAILURE({ + bool false_value = false; + ASSERT_EQ(false_value, true); + }, "Value of: true"); +} + +// Tests using int values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Int) { + ASSERT_EQ(32, 32); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), + "33"); +} + +// Tests using time_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Time_T) { + EXPECT_EQ(static_cast(0), + static_cast(0)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0), + static_cast(1234)), + "1234"); +} + +// Tests using char values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, Char) { + ASSERT_EQ('z', 'z'); + const char ch = 'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), + "ch"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), + "ch"); +} + +// Tests using wchar_t values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideChar) { + EXPECT_EQ(L'b', L'b'); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'\0', L'x'), + "Value of: L'x'\n" + " Actual: L'x' (120, 0x78)\n" + "Expected: L'\0'\n" + "Which is: L'\0' (0, 0x0)"); + + static wchar_t wchar; + wchar = L'b'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar), + "wchar"); + wchar = 0x8119; + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0x8120), wchar), + "Value of: wchar"); +} + +// Tests using ::std::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdString) { + // Compares a const char* to an std::string that has identical + // content. + ASSERT_EQ("Test", ::std::string("Test")); + + // Compares two identical std::strings. + static const ::std::string str1("A * in the middle"); + static const ::std::string str2(str1); + EXPECT_EQ(str1, str2); + + // Compares a const char* to an std::string that has different + // content + EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")), + "\"test\""); + + // Compares an std::string to a char* that has different content. + char* const p1 = const_cast("foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::std::string("bar"), p1), + "p1"); + + // Compares two std::strings that have different contents, one of + // which having a NUL character in the middle. This should fail. + static ::std::string str3(str1); + str3.at(2) = '\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), + "Value of: str3\n" + " Actual: \"A \\0 in the middle\""); +} + +#if GTEST_HAS_STD_WSTRING + +// Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, StdWideString) { + // Compares two identical std::wstrings. + const ::std::wstring wstr1(L"A * in the middle"); + const ::std::wstring wstr2(wstr1); + ASSERT_EQ(wstr1, wstr2); + + // Compares an std::wstring to a const wchar_t* that has identical + // content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8119); + + // Compares an std::wstring to a const wchar_t* that has different + // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(::std::wstring(kTestX8119), kTestX8120); + }, "kTestX8120"); + + // Compares two std::wstrings that have different contents, one of + // which having a NUL character in the middle. + ::std::wstring wstr3(wstr1); + wstr3.at(2) = L'\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(wstr1, wstr3), + "wstr3"); + + // Compares a wchar_t* to an std::wstring that has different + // content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(const_cast(L"foo"), ::std::wstring(L"bar")); + }, ""); +} + +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +// Tests using ::string values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalString) { + // Compares a const char* to a ::string that has identical content. + EXPECT_EQ("Test", ::string("Test")); + + // Compares two identical ::strings. + const ::string str1("A * in the middle"); + const ::string str2(str1); + ASSERT_EQ(str1, str2); + + // Compares a ::string to a const char* that has different content. + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::string("Test"), "test"), + "test"); + + // Compares two ::strings that have different contents, one of which + // having a NUL character in the middle. + ::string str3(str1); + str3.at(2) = '\0'; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(str1, str3), + "str3"); + + // Compares a ::string to a char* that has different content. + EXPECT_FATAL_FAILURE({ // NOLINT + ASSERT_EQ(::string("bar"), const_cast("foo")); + }, ""); +} + +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING + +// Tests using ::wstring values in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, GlobalWideString) { + // Compares two identical ::wstrings. + static const ::wstring wstr1(L"A * in the middle"); + static const ::wstring wstr2(wstr1); + EXPECT_EQ(wstr1, wstr2); + + // Compares a const wchar_t* to a ::wstring that has identical content. + const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; + ASSERT_EQ(kTestX8119, ::wstring(kTestX8119)); + + // Compares a const wchar_t* to a ::wstring that has different + // content. + const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EQ(kTestX8120, ::wstring(kTestX8119)); + }, "Test\\x8119"); + + // Compares a wchar_t* to a ::wstring that has different content. + wchar_t* const p1 = const_cast(L"foo"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, ::wstring(L"bar")), + "bar"); + + // Compares two ::wstrings that have different contents, one of which + // having a NUL character in the middle. + static ::wstring wstr3; + wstr3 = wstr1; + wstr3.at(2) = L'\0'; + EXPECT_FATAL_FAILURE(ASSERT_EQ(wstr1, wstr3), + "wstr3"); +} + +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Tests using char pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, CharPointer) { + char* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + char* const p1 = reinterpret_cast(pv1); + char* const p2 = reinterpret_cast(pv2); + ASSERT_EQ(p1, p1); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast(0x1234), + reinterpret_cast(0xABC0)), + "ABC0"); +} + +// Tests using wchar_t pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, WideCharPointer) { + wchar_t* const p0 = NULL; + // Only way to get the Nokia compiler to compile the cast + // is to have a separate void* variable first. Putting + // the two casts on the same line doesn't work, neither does + // a direct C-style to char*. + void* pv1 = (void*)0x1234; // NOLINT + void* pv2 = (void*)0xABC0; // NOLINT + wchar_t* const p1 = reinterpret_cast(pv1); + wchar_t* const p2 = reinterpret_cast(pv2); + EXPECT_EQ(p0, p0); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), + "Value of: p2"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), + "p2"); + void* pv3 = (void*)0x1234; // NOLINT + void* pv4 = (void*)0xABC0; // NOLINT + const wchar_t* p3 = reinterpret_cast(pv3); + const wchar_t* p4 = reinterpret_cast(pv4); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p3, p4), + "p4"); +} + +// Tests using other types of pointers in {EXPECT|ASSERT}_EQ. +TEST(EqAssertionTest, OtherPointer) { + ASSERT_EQ(static_cast(NULL), + static_cast(NULL)); + EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(NULL), + reinterpret_cast(0x1234)), + "0x1234"); +} + +// A class that supports binary comparison operators but not streaming. +class UnprintableChar { + public: + explicit UnprintableChar(char ch) : char_(ch) {} + + bool operator==(const UnprintableChar& rhs) const { + return char_ == rhs.char_; + } + bool operator!=(const UnprintableChar& rhs) const { + return char_ != rhs.char_; + } + bool operator<(const UnprintableChar& rhs) const { + return char_ < rhs.char_; + } + bool operator<=(const UnprintableChar& rhs) const { + return char_ <= rhs.char_; + } + bool operator>(const UnprintableChar& rhs) const { + return char_ > rhs.char_; + } + bool operator>=(const UnprintableChar& rhs) const { + return char_ >= rhs.char_; + } + + private: + char char_; +}; + +// Tests that ASSERT_EQ() and friends don't require the arguments to +// be printable. +TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { + const UnprintableChar x('x'), y('y'); + ASSERT_EQ(x, x); + EXPECT_NE(x, y); + ASSERT_LT(x, y); + EXPECT_LE(x, y); + ASSERT_GT(y, x); + EXPECT_GE(x, x); + + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_LT(y, y), "1-byte object <79>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <78>"); + EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <79>"); + + // Code tested by EXPECT_FATAL_FAILURE cannot reference local + // variables, so we have to write UnprintableChar('x') instead of x. +#ifndef __BORLANDC__ + // ICE's in C++Builder. + EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <78>"); +#endif + EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), + "1-byte object <79>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <78>"); + EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), + "1-byte object <79>"); +} + +// Tests the FRIEND_TEST macro. + +// This class has a private member we want to test. We will test it +// both in a TEST and in a TEST_F. +class Foo { + public: + Foo() {} + + private: + int Bar() const { return 1; } + + // Declares the friend tests that can access the private member + // Bar(). + FRIEND_TEST(FRIEND_TEST_Test, TEST); + FRIEND_TEST(FRIEND_TEST_Test2, TEST_F); +}; + +// Tests that the FRIEND_TEST declaration allows a TEST to access a +// class's private members. This should compile. +TEST(FRIEND_TEST_Test, TEST) { + ASSERT_EQ(1, Foo().Bar()); +} + +// The fixture needed to test using FRIEND_TEST with TEST_F. +class FRIEND_TEST_Test2 : public Test { + protected: + Foo foo; +}; + +// Tests that the FRIEND_TEST declaration allows a TEST_F to access a +// class's private members. This should compile. +TEST_F(FRIEND_TEST_Test2, TEST_F) { + ASSERT_EQ(1, foo.Bar()); +} + +// Tests the life cycle of Test objects. + +// The test fixture for testing the life cycle of Test objects. +// +// This class counts the number of live test objects that uses this +// fixture. +class TestLifeCycleTest : public Test { + protected: + // Constructor. Increments the number of test objects that uses + // this fixture. + TestLifeCycleTest() { count_++; } + + // Destructor. Decrements the number of test objects that uses this + // fixture. + ~TestLifeCycleTest() { count_--; } + + // Returns the number of live test objects that uses this fixture. + int count() const { return count_; } + + private: + static int count_; +}; + +int TestLifeCycleTest::count_ = 0; + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test1) { + // There should be only one test object in this test case that's + // currently alive. + ASSERT_EQ(1, count()); +} + +// Tests the life cycle of test objects. +TEST_F(TestLifeCycleTest, Test2) { + // After Test1 is done and Test2 is started, there should still be + // only one live test object, as the object for Test1 should've been + // deleted. + ASSERT_EQ(1, count()); +} + +} // namespace + +// Tests that the copy constructor works when it is NOT optimized away by +// the compiler. +TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) { + // Checks that the copy constructor doesn't try to dereference NULL pointers + // in the source object. + AssertionResult r1 = AssertionSuccess(); + AssertionResult r2 = r1; + // The following line is added to prevent the compiler from optimizing + // away the constructor call. + r1 << "abc"; + + AssertionResult r3 = r1; + EXPECT_EQ(static_cast(r3), static_cast(r1)); + EXPECT_STREQ("abc", r1.message()); +} + +// Tests that AssertionSuccess and AssertionFailure construct +// AssertionResult objects as expected. +TEST(AssertionResultTest, ConstructionWorks) { + AssertionResult r1 = AssertionSuccess(); + EXPECT_TRUE(r1); + EXPECT_STREQ("", r1.message()); + + AssertionResult r2 = AssertionSuccess() << "abc"; + EXPECT_TRUE(r2); + EXPECT_STREQ("abc", r2.message()); + + AssertionResult r3 = AssertionFailure(); + EXPECT_FALSE(r3); + EXPECT_STREQ("", r3.message()); + + AssertionResult r4 = AssertionFailure() << "def"; + EXPECT_FALSE(r4); + EXPECT_STREQ("def", r4.message()); + + AssertionResult r5 = AssertionFailure(Message() << "ghi"); + EXPECT_FALSE(r5); + EXPECT_STREQ("ghi", r5.message()); +} + +// Tests that the negation flips the predicate result but keeps the message. +TEST(AssertionResultTest, NegationWorks) { + AssertionResult r1 = AssertionSuccess() << "abc"; + EXPECT_FALSE(!r1); + EXPECT_STREQ("abc", (!r1).message()); + + AssertionResult r2 = AssertionFailure() << "def"; + EXPECT_TRUE(!r2); + EXPECT_STREQ("def", (!r2).message()); +} + +TEST(AssertionResultTest, StreamingWorks) { + AssertionResult r = AssertionSuccess(); + r << "abc" << 'd' << 0 << true; + EXPECT_STREQ("abcd0true", r.message()); +} + +TEST(AssertionResultTest, CanStreamOstreamManipulators) { + AssertionResult r = AssertionSuccess(); + r << "Data" << std::endl << std::flush << std::ends << "Will be visible"; + EXPECT_STREQ("Data\n\\0Will be visible", r.message()); +} + +// The next test uses explicit conversion operators -- a C++11 feature. +#if GTEST_LANG_CXX11 + +TEST(AssertionResultTest, ConstructibleFromContextuallyConvertibleToBool) { + struct ExplicitlyConvertibleToBool { + explicit operator bool() const { return value; } + bool value; + }; + ExplicitlyConvertibleToBool v1 = {false}; + ExplicitlyConvertibleToBool v2 = {true}; + EXPECT_FALSE(v1); + EXPECT_TRUE(v2); +} + +#endif // GTEST_LANG_CXX11 + +struct ConvertibleToAssertionResult { + operator AssertionResult() const { return AssertionResult(true); } +}; + +TEST(AssertionResultTest, ConstructibleFromImplicitlyConvertible) { + ConvertibleToAssertionResult obj; + EXPECT_TRUE(obj); +} + +// Tests streaming a user type whose definition and operator << are +// both in the global namespace. +class Base { + public: + explicit Base(int an_x) : x_(an_x) {} + int x() const { return x_; } + private: + int x_; +}; +std::ostream& operator<<(std::ostream& os, + const Base& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const Base* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { + Message msg; + Base a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in an unnamed namespace. +namespace { +class MyTypeInUnnamedNameSpace : public Base { + public: + explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInUnnamedNameSpace* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace + +TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { + Message msg; + MyTypeInUnnamedNameSpace a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition and operator<< are +// both in a user namespace. +namespace namespace1 { +class MyTypeInNameSpace1 : public Base { + public: + explicit MyTypeInNameSpace1(int an_x): Base(an_x) {} +}; +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const MyTypeInNameSpace1* pointer) { + return os << "(" << pointer->x() << ")"; +} +} // namespace namespace1 + +TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { + Message msg; + namespace1::MyTypeInNameSpace1 a(1); + + msg << a << &a; // Uses namespace1::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming a user type whose definition is in a user namespace +// but whose operator<< is in the global namespace. +namespace namespace2 { +class MyTypeInNameSpace2 : public ::Base { + public: + explicit MyTypeInNameSpace2(int an_x): Base(an_x) {} +}; +} // namespace namespace2 +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2& val) { + return os << val.x(); +} +std::ostream& operator<<(std::ostream& os, + const namespace2::MyTypeInNameSpace2* pointer) { + return os << "(" << pointer->x() << ")"; +} + +TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { + Message msg; + namespace2::MyTypeInNameSpace2 a(1); + + msg << a << &a; // Uses ::operator<<. + EXPECT_STREQ("1(1)", msg.GetString().c_str()); +} + +// Tests streaming NULL pointers to testing::Message. +TEST(MessageTest, NullPointers) { + Message msg; + char* const p1 = NULL; + unsigned char* const p2 = NULL; + int* p3 = NULL; + double* p4 = NULL; + bool* p5 = NULL; + Message* p6 = NULL; + + msg << p1 << p2 << p3 << p4 << p5 << p6; + ASSERT_STREQ("(null)(null)(null)(null)(null)(null)", + msg.GetString().c_str()); +} + +// Tests streaming wide strings to testing::Message. +TEST(MessageTest, WideStrings) { + // Streams a NULL of type const wchar_t*. + const wchar_t* const_wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << const_wstr).GetString().c_str()); + + // Streams a NULL of type wchar_t*. + wchar_t* wstr = NULL; + EXPECT_STREQ("(null)", + (Message() << wstr).GetString().c_str()); + + // Streams a non-NULL of type const wchar_t*. + const_wstr = L"abc\x8119"; + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << const_wstr).GetString().c_str()); + + // Streams a non-NULL of type wchar_t*. + wstr = const_cast(const_wstr); + EXPECT_STREQ("abc\xe8\x84\x99", + (Message() << wstr).GetString().c_str()); +} + + +// This line tests that we can define tests in the testing namespace. +namespace testing { + +// Tests the TestInfo class. + +class TestInfoTest : public Test { + protected: + static const TestInfo* GetTestInfo(const char* test_name) { + const TestCase* const test_case = GetUnitTestImpl()-> + GetTestCase("TestInfoTest", "", NULL, NULL); + + for (int i = 0; i < test_case->total_test_count(); ++i) { + const TestInfo* const test_info = test_case->GetTestInfo(i); + if (strcmp(test_name, test_info->name()) == 0) + return test_info; + } + return NULL; + } + + static const TestResult* GetTestResult( + const TestInfo* test_info) { + return test_info->result(); + } +}; + +// Tests TestInfo::test_case_name() and TestInfo::name(). +TEST_F(TestInfoTest, Names) { + const TestInfo* const test_info = GetTestInfo("Names"); + + ASSERT_STREQ("TestInfoTest", test_info->test_case_name()); + ASSERT_STREQ("Names", test_info->name()); +} + +// Tests TestInfo::result(). +TEST_F(TestInfoTest, result) { + const TestInfo* const test_info = GetTestInfo("result"); + + // Initially, there is no TestPartResult for this test. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); + + // After the previous assertion, there is still none. + ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); +} + +// Tests setting up and tearing down a test case. + +class SetUpTestCaseTest : public Test { + protected: + // This will be called once before the first test in this test case + // is run. + static void SetUpTestCase() { + printf("Setting up the test case . . .\n"); + + // Initializes some shared resource. In this simple example, we + // just create a C string. More complex stuff can be done if + // desired. + shared_resource_ = "123"; + + // Increments the number of test cases that have been set up. + counter_++; + + // SetUpTestCase() should be called only once. + EXPECT_EQ(1, counter_); + } + + // This will be called once after the last test in this test case is + // run. + static void TearDownTestCase() { + printf("Tearing down the test case . . .\n"); + + // Decrements the number of test cases that have been set up. + counter_--; + + // TearDownTestCase() should be called only once. + EXPECT_EQ(0, counter_); + + // Cleans up the shared resource. + shared_resource_ = NULL; + } + + // This will be called before each test in this test case. + virtual void SetUp() { + // SetUpTestCase() should be called only once, so counter_ should + // always be 1. + EXPECT_EQ(1, counter_); + } + + // Number of test cases that have been set up. + static int counter_; + + // Some resource to be shared by all tests in this test case. + static const char* shared_resource_; +}; + +int SetUpTestCaseTest::counter_ = 0; +const char* SetUpTestCaseTest::shared_resource_ = NULL; + +// A test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test1) { + EXPECT_STRNE(NULL, shared_resource_); +} + +// Another test that uses the shared resource. +TEST_F(SetUpTestCaseTest, Test2) { + EXPECT_STREQ("123", shared_resource_); +} + +// The InitGoogleTestTest test case tests testing::InitGoogleTest(). + +// The Flags struct stores a copy of all Google Test flags. +struct Flags { + // Constructs a Flags struct where each flag has its default value. + Flags() : also_run_disabled_tests(false), + break_on_failure(false), + catch_exceptions(false), + death_test_use_fork(false), + filter(""), + list_tests(false), + output(""), + print_time(true), + random_seed(0), + repeat(1), + shuffle(false), + stack_trace_depth(kMaxStackTraceDepth), + stream_result_to(""), + throw_on_failure(false) {} + + // Factory methods. + + // Creates a Flags struct where the gtest_also_run_disabled_tests flag has + // the given value. + static Flags AlsoRunDisabledTests(bool also_run_disabled_tests) { + Flags flags; + flags.also_run_disabled_tests = also_run_disabled_tests; + return flags; + } + + // Creates a Flags struct where the gtest_break_on_failure flag has + // the given value. + static Flags BreakOnFailure(bool break_on_failure) { + Flags flags; + flags.break_on_failure = break_on_failure; + return flags; + } + + // Creates a Flags struct where the gtest_catch_exceptions flag has + // the given value. + static Flags CatchExceptions(bool catch_exceptions) { + Flags flags; + flags.catch_exceptions = catch_exceptions; + return flags; + } + + // Creates a Flags struct where the gtest_death_test_use_fork flag has + // the given value. + static Flags DeathTestUseFork(bool death_test_use_fork) { + Flags flags; + flags.death_test_use_fork = death_test_use_fork; + return flags; + } + + // Creates a Flags struct where the gtest_filter flag has the given + // value. + static Flags Filter(const char* filter) { + Flags flags; + flags.filter = filter; + return flags; + } + + // Creates a Flags struct where the gtest_list_tests flag has the + // given value. + static Flags ListTests(bool list_tests) { + Flags flags; + flags.list_tests = list_tests; + return flags; + } + + // Creates a Flags struct where the gtest_output flag has the given + // value. + static Flags Output(const char* output) { + Flags flags; + flags.output = output; + return flags; + } + + // Creates a Flags struct where the gtest_print_time flag has the given + // value. + static Flags PrintTime(bool print_time) { + Flags flags; + flags.print_time = print_time; + return flags; + } + + // Creates a Flags struct where the gtest_random_seed flag has + // the given value. + static Flags RandomSeed(Int32 random_seed) { + Flags flags; + flags.random_seed = random_seed; + return flags; + } + + // Creates a Flags struct where the gtest_repeat flag has the given + // value. + static Flags Repeat(Int32 repeat) { + Flags flags; + flags.repeat = repeat; + return flags; + } + + // Creates a Flags struct where the gtest_shuffle flag has + // the given value. + static Flags Shuffle(bool shuffle) { + Flags flags; + flags.shuffle = shuffle; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has + // the given value. + static Flags StackTraceDepth(Int32 stack_trace_depth) { + Flags flags; + flags.stack_trace_depth = stack_trace_depth; + return flags; + } + + // Creates a Flags struct where the GTEST_FLAG(stream_result_to) flag has + // the given value. + static Flags StreamResultTo(const char* stream_result_to) { + Flags flags; + flags.stream_result_to = stream_result_to; + return flags; + } + + // Creates a Flags struct where the gtest_throw_on_failure flag has + // the given value. + static Flags ThrowOnFailure(bool throw_on_failure) { + Flags flags; + flags.throw_on_failure = throw_on_failure; + return flags; + } + + // These fields store the flag values. + bool also_run_disabled_tests; + bool break_on_failure; + bool catch_exceptions; + bool death_test_use_fork; + const char* filter; + bool list_tests; + const char* output; + bool print_time; + Int32 random_seed; + Int32 repeat; + bool shuffle; + Int32 stack_trace_depth; + const char* stream_result_to; + bool throw_on_failure; +}; + +// Fixture for testing InitGoogleTest(). +class InitGoogleTestTest : public Test { + protected: + // Clears the flags before each test. + virtual void SetUp() { + GTEST_FLAG(also_run_disabled_tests) = false; + GTEST_FLAG(break_on_failure) = false; + GTEST_FLAG(catch_exceptions) = false; + GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(filter) = ""; + GTEST_FLAG(list_tests) = false; + GTEST_FLAG(output) = ""; + GTEST_FLAG(print_time) = true; + GTEST_FLAG(random_seed) = 0; + GTEST_FLAG(repeat) = 1; + GTEST_FLAG(shuffle) = false; + GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; + GTEST_FLAG(stream_result_to) = ""; + GTEST_FLAG(throw_on_failure) = false; + } + + // Asserts that two narrow or wide string arrays are equal. + template + static void AssertStringArrayEq(size_t size1, CharType** array1, + size_t size2, CharType** array2) { + ASSERT_EQ(size1, size2) << " Array sizes different."; + + for (size_t i = 0; i != size1; i++) { + ASSERT_STREQ(array1[i], array2[i]) << " where i == " << i; + } + } + + // Verifies that the flag values match the expected values. + static void CheckFlags(const Flags& expected) { + EXPECT_EQ(expected.also_run_disabled_tests, + GTEST_FLAG(also_run_disabled_tests)); + EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); + EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); + EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); + EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); + EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); + EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); + EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); + EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed)); + EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); + EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); + EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth)); + EXPECT_STREQ(expected.stream_result_to, + GTEST_FLAG(stream_result_to).c_str()); + EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); + } + + // Parses a command line (specified by argc1 and argv1), then + // verifies that the flag values are expected and that the + // recognized flags are removed from the command line. + template + static void TestParsingFlags(int argc1, const CharType** argv1, + int argc2, const CharType** argv2, + const Flags& expected, bool should_print_help) { + const bool saved_help_flag = ::testing::internal::g_help_flag; + ::testing::internal::g_help_flag = false; + +#if GTEST_HAS_STREAM_REDIRECTION + CaptureStdout(); +#endif + + // Parses the command line. + internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); + +#if GTEST_HAS_STREAM_REDIRECTION + const std::string captured_stdout = GetCapturedStdout(); +#endif + + // Verifies the flag values. + CheckFlags(expected); + + // Verifies that the recognized flags are removed from the command + // line. + AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2); + + // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the + // help message for the flags it recognizes. + EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); + +#if GTEST_HAS_STREAM_REDIRECTION + const char* const expected_help_fragment = + "This program contains tests written using"; + if (should_print_help) { + EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout); + } else { + EXPECT_PRED_FORMAT2(IsNotSubstring, + expected_help_fragment, captured_stdout); + } +#endif // GTEST_HAS_STREAM_REDIRECTION + + ::testing::internal::g_help_flag = saved_help_flag; + } + + // This macro wraps TestParsingFlags s.t. the user doesn't need + // to specify the array sizes. + +#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ + TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ + sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ + expected, should_print_help) +}; + +// Tests parsing an empty command line. +TEST_F(InitGoogleTestTest, Empty) { + const char* argv[] = { + NULL + }; + + const char* argv2[] = { + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a command line that has no flag. +TEST_F(InitGoogleTestTest, NoFlag) { + const char* argv[] = { + "foo.exe", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); +} + +// Tests parsing a bad --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterBad) { + const char* argv[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_filter", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true); +} + +// Tests parsing an empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false); +} + +// Tests parsing a non-empty --gtest_filter flag. +TEST_F(InitGoogleTestTest, FilterNonEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=abc", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); +} + +// Tests parsing --gtest_break_on_failure. +TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_break_on_failure=0. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=f. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing --gtest_break_on_failure=F. +TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); +} + +// Tests parsing a --gtest_break_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); +} + +// Tests parsing --gtest_catch_exceptions. +TEST_F(InitGoogleTestTest, CatchExceptions) { + const char* argv[] = { + "foo.exe", + "--gtest_catch_exceptions", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false); +} + +// Tests parsing --gtest_death_test_use_fork. +TEST_F(InitGoogleTestTest, DeathTestUseFork) { + const char* argv[] = { + "foo.exe", + "--gtest_death_test_use_fork", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false); +} + +// Tests having the same flag twice with different values. The +// expected behavior is that the one coming last takes precedence. +TEST_F(InitGoogleTestTest, DuplicatedFlags) { + const char* argv[] = { + "foo.exe", + "--gtest_filter=a", + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false); +} + +// Tests having an unrecognized flag on the command line. +TEST_F(InitGoogleTestTest, UnrecognizedFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_break_on_failure", + "bar", // Unrecognized by Google Test. + "--gtest_filter=b", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "bar", + NULL + }; + + Flags flags; + flags.break_on_failure = true; + flags.filter = "b"; + GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false); +} + +// Tests having a --gtest_list_tests flag +TEST_F(InitGoogleTestTest, ListTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "true" value +TEST_F(InitGoogleTestTest, ListTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); +} + +// Tests having a --gtest_list_tests flag with a "false" value +TEST_F(InitGoogleTestTest, ListTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=f. +TEST_F(InitGoogleTestTest, ListTestsFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_list_tests=F. +TEST_F(InitGoogleTestTest, ListTestsFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_list_tests=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); +} + +// Tests parsing --gtest_output (invalid). +TEST_F(InitGoogleTestTest, OutputEmpty) { + const char* argv[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + const char* argv2[] = { + "foo.exe", + "--gtest_output", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true); +} + +// Tests parsing --gtest_output=xml +TEST_F(InitGoogleTestTest, OutputXml) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false); +} + +// Tests parsing --gtest_output=xml:file +TEST_F(InitGoogleTestTest, OutputXmlFile) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:file", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false); +} + +// Tests parsing --gtest_output=xml:directory/path/ +TEST_F(InitGoogleTestTest, OutputXmlDirectory) { + const char* argv[] = { + "foo.exe", + "--gtest_output=xml:directory/path/", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::Output("xml:directory/path/"), false); +} + +// Tests having a --gtest_print_time flag +TEST_F(InitGoogleTestTest, PrintTimeFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "true" value +TEST_F(InitGoogleTestTest, PrintTimeTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); +} + +// Tests having a --gtest_print_time flag with a "false" value +TEST_F(InitGoogleTestTest, PrintTimeFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=f. +TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=f", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_print_time=F. +TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { + const char* argv[] = { + "foo.exe", + "--gtest_print_time=F", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); +} + +// Tests parsing --gtest_random_seed=number +TEST_F(InitGoogleTestTest, RandomSeed) { + const char* argv[] = { + "foo.exe", + "--gtest_random_seed=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false); +} + +// Tests parsing --gtest_repeat=number +TEST_F(InitGoogleTestTest, Repeat) { + const char* argv[] = { + "foo.exe", + "--gtest_repeat=1000", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "true" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(true), false); +} + +// Tests having a --gtest_also_run_disabled_tests flag with a "false" value +TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { + const char* argv[] = { + "foo.exe", + "--gtest_also_run_disabled_tests=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, + Flags::AlsoRunDisabledTests(false), false); +} + +// Tests parsing --gtest_shuffle. +TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_shuffle=0. +TEST_F(InitGoogleTestTest, ShuffleFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); +} + +// Tests parsing a --gtest_shuffle flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ShuffleTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_shuffle=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); +} + +// Tests parsing --gtest_stack_trace_depth=number. +TEST_F(InitGoogleTestTest, StackTraceDepth) { + const char* argv[] = { + "foo.exe", + "--gtest_stack_trace_depth=5", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); +} + +TEST_F(InitGoogleTestTest, StreamResultTo) { + const char* argv[] = { + "foo.exe", + "--gtest_stream_result_to=localhost:1234", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_( + argv, argv2, Flags::StreamResultTo("localhost:1234"), false); +} + +// Tests parsing --gtest_throw_on_failure. +TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure", + NULL +}; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +// Tests parsing --gtest_throw_on_failure=0. +TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=0", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false); +} + +// Tests parsing a --gtest_throw_on_failure flag that has a "true" +// definition. +TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { + const char* argv[] = { + "foo.exe", + "--gtest_throw_on_failure=1", + NULL + }; + + const char* argv2[] = { + "foo.exe", + NULL + }; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); +} + +#if GTEST_OS_WINDOWS +// Tests parsing wide strings. +TEST_F(InitGoogleTestTest, WideStrings) { + const wchar_t* argv[] = { + L"foo.exe", + L"--gtest_filter=Foo*", + L"--gtest_list_tests=1", + L"--gtest_break_on_failure", + L"--non_gtest_flag", + NULL + }; + + const wchar_t* argv2[] = { + L"foo.exe", + L"--non_gtest_flag", + NULL + }; + + Flags expected_flags; + expected_flags.break_on_failure = true; + expected_flags.filter = "Foo*"; + expected_flags.list_tests = true; + + GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); +} +#endif // GTEST_OS_WINDOWS + +// Tests current_test_info() in UnitTest. +class CurrentTestInfoTest : public Test { + protected: + // Tests that current_test_info() returns NULL before the first test in + // the test case is run. + static void SetUpTestCase() { + // There should be no tests running at this point. + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == NULL) + << "There should be no tests running at this point."; + } + + // Tests that current_test_info() returns NULL after the last test in + // the test case has run. + static void TearDownTestCase() { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + EXPECT_TRUE(test_info == NULL) + << "There should be no tests running at this point."; + } +}; + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. +TEST_F(CurrentTestInfoTest, WorksForFirstTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForFirstTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +// Tests that current_test_info() returns TestInfo for currently running +// test by checking the expected test name against the actual one. We +// use this test to see that the TestInfo object actually changed from +// the previous invocation. +TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) { + const TestInfo* test_info = + UnitTest::GetInstance()->current_test_info(); + ASSERT_TRUE(NULL != test_info) + << "There is a test running so we should have a valid TestInfo."; + EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) + << "Expected the name of the currently running test case."; + EXPECT_STREQ("WorksForSecondTestInATestCase", test_info->name()) + << "Expected the name of the currently running test."; +} + +} // namespace testing + +// These two lines test that we can define tests in a namespace that +// has the name "testing" and is nested in another namespace. +namespace my_namespace { +namespace testing { + +// Makes sure that TEST knows to use ::testing::Test instead of +// ::my_namespace::testing::Test. +class Test {}; + +// Makes sure that an assertion knows to use ::testing::Message instead of +// ::my_namespace::testing::Message. +class Message {}; + +// Makes sure that an assertion knows to use +// ::testing::AssertionResult instead of +// ::my_namespace::testing::AssertionResult. +class AssertionResult {}; + +// Tests that an assertion that should succeed works as expected. +TEST(NestedTestingNamespaceTest, Success) { + EXPECT_EQ(1, 1) << "This shouldn't fail."; +} + +// Tests that an assertion that should fail works as expected. +TEST(NestedTestingNamespaceTest, Failure) { + EXPECT_FATAL_FAILURE(FAIL() << "This failure is expected.", + "This failure is expected."); +} + +} // namespace testing +} // namespace my_namespace + +// Tests that one can call superclass SetUp and TearDown methods-- +// that is, that they are not private. +// No tests are based on this fixture; the test "passes" if it compiles +// successfully. +class ProtectedFixtureMethodsTest : public Test { + protected: + virtual void SetUp() { + Test::SetUp(); + } + virtual void TearDown() { + Test::TearDown(); + } +}; + +// StreamingAssertionsTest tests the streaming versions of a representative +// sample of assertions. +TEST(StreamingAssertionsTest, Unconditional) { + SUCCEED() << "expected success"; + EXPECT_NONFATAL_FAILURE(ADD_FAILURE() << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(FAIL() << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Silences warnings: "Condition is always true", "Unreachable code" +# pragma option push -w-ccc -w-rch +#endif + +TEST(StreamingAssertionsTest, Truth) { + EXPECT_TRUE(true) << "unexpected failure"; + ASSERT_TRUE(true) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, Truth2) { + EXPECT_FALSE(false) << "unexpected failure"; + ASSERT_FALSE(false) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FALSE(true) << "expected failure", + "expected failure"); +} + +#ifdef __BORLANDC__ +// Restores warnings after previous "#pragma option push" supressed them +# pragma option pop +#endif + +TEST(StreamingAssertionsTest, IntegerEquals) { + EXPECT_EQ(1, 1) << "unexpected failure"; + ASSERT_EQ(1, 1) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_EQ(1, 2) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_EQ(1, 2) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, IntegerLessThan) { + EXPECT_LT(1, 2) << "unexpected failure"; + ASSERT_LT(1, 2) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_LT(2, 1) << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqual) { + EXPECT_STREQ("foo", "foo") << "unexpected failure"; + ASSERT_STREQ("foo", "foo") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STREQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STREQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsNotEqual) { + EXPECT_STRNE("foo", "bar") << "unexpected failure"; + ASSERT_STRNE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("foo", "foo") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRNE("foo", "foo") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringsEqualIgnoringCase) { + EXPECT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + ASSERT_STRCASEEQ("foo", "FOO") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("foo", "bar") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, StringNotEqualIgnoringCase) { + EXPECT_STRCASENE("foo", "bar") << "unexpected failure"; + ASSERT_STRCASENE("foo", "bar") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("foo", "FOO") << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("bar", "BAR") << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, FloatingPointEquals) { + EXPECT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + ASSERT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.0) << "expected failure", + "expected failure"); +} + +#if GTEST_HAS_EXCEPTIONS + +TEST(StreamingAssertionsTest, Throw) { + EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, NoThrow) { + EXPECT_NO_THROW(ThrowNothing()) << "unexpected failure"; + ASSERT_NO_THROW(ThrowNothing()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) << + "expected failure", "expected failure"); +} + +TEST(StreamingAssertionsTest, AnyThrow) { + EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); + EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(ThrowNothing()) << + "expected failure", "expected failure"); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// Tests that Google Test correctly decides whether to use colors in the output. + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) { + GTEST_FLAG(color) = "yes"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsAliasOfYes) { + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + + GTEST_FLAG(color) = "True"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "t"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. + + GTEST_FLAG(color) = "1"; + EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsNo) { + GTEST_FLAG(color) = "no"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. +} + +TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsInvalid) { + SetEnv("TERM", "xterm"); // TERM supports colors. + + GTEST_FLAG(color) = "F"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "0"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + GTEST_FLAG(color) = "unknown"; + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) { + GTEST_FLAG(color) = "auto"; + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +} + +TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { + GTEST_FLAG(color) = "auto"; + +#if GTEST_OS_WINDOWS + // On Windows, we ignore the TERM variable as it's usually not set. + + SetEnv("TERM", "dumb"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", ""); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#else + // On non-Windows platforms, we rely on TERM to determine if the + // terminal supports colors. + + SetEnv("TERM", "dumb"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "emacs"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "vt100"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-mono"); // TERM doesn't support colors. + EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "xterm-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "screen-256color"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "linux"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. + + SetEnv("TERM", "cygwin"); // TERM supports colors. + EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. +#endif // GTEST_OS_WINDOWS +} + +// Verifies that StaticAssertTypeEq works in a namespace scope. + +static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq(); +static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ = + StaticAssertTypeEq(); + +// Verifies that StaticAssertTypeEq works in a class. + +template +class StaticAssertTypeEqTestHelper { + public: + StaticAssertTypeEqTestHelper() { StaticAssertTypeEq(); } +}; + +TEST(StaticAssertTypeEqTest, WorksInClass) { + StaticAssertTypeEqTestHelper(); +} + +// Verifies that StaticAssertTypeEq works inside a function. + +typedef int IntAlias; + +TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { + StaticAssertTypeEq(); + StaticAssertTypeEq(); +} + +TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { + testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); + + // We don't have a stack walker in Google Test yet. + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); + EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); +} + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasNonfatalFailure()); +} + +static void FailFatally() { FAIL(); } + +TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) { + FailFatally(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_FALSE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +// A wrapper for calling HasNonfatalFailure outside of a test body. +static bool HasNonfatalFailureHelper() { + return testing::Test::HasNonfatalFailure(); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasNonfatalFailureHelper()); +} + +TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_nonfatal_failure = HasNonfatalFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_nonfatal_failure); +} + +TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) { + EXPECT_FALSE(HasFailure()); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) { + FailFatally(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { + FailFatally(); + ADD_FAILURE(); + const bool has_failure = HasFailure(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +// A wrapper for calling HasFailure outside of a test body. +static bool HasFailureHelper() { return testing::Test::HasFailure(); } + +TEST(HasFailureTest, WorksOutsideOfTestBody) { + EXPECT_FALSE(HasFailureHelper()); +} + +TEST(HasFailureTest, WorksOutsideOfTestBody2) { + ADD_FAILURE(); + const bool has_failure = HasFailureHelper(); + ClearCurrentTestPartResults(); + EXPECT_TRUE(has_failure); +} + +class TestListener : public EmptyTestEventListener { + public: + TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {} + TestListener(int* on_start_counter, bool* is_destroyed) + : on_start_counter_(on_start_counter), + is_destroyed_(is_destroyed) {} + + virtual ~TestListener() { + if (is_destroyed_) + *is_destroyed_ = true; + } + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + if (on_start_counter_ != NULL) + (*on_start_counter_)++; + } + + private: + int* on_start_counter_; + bool* is_destroyed_; +}; + +// Tests the constructor. +TEST(TestEventListenersTest, ConstructionWorks) { + TestEventListeners listeners; + + EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != NULL); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); +} + +// Tests that the TestEventListeners destructor deletes all the listeners it +// owns. +TEST(TestEventListenersTest, DestructionWorks) { + bool default_result_printer_is_destroyed = false; + bool default_xml_printer_is_destroyed = false; + bool extra_listener_is_destroyed = false; + TestListener* default_result_printer = new TestListener( + NULL, &default_result_printer_is_destroyed); + TestListener* default_xml_printer = new TestListener( + NULL, &default_xml_printer_is_destroyed); + TestListener* extra_listener = new TestListener( + NULL, &extra_listener_is_destroyed); + + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, + default_result_printer); + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, + default_xml_printer); + listeners.Append(extra_listener); + } + EXPECT_TRUE(default_result_printer_is_destroyed); + EXPECT_TRUE(default_xml_printer_is_destroyed); + EXPECT_TRUE(extra_listener_is_destroyed); +} + +// Tests that a listener Append'ed to a TestEventListeners list starts +// receiving events. +TEST(TestEventListenersTest, Append) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); + } + EXPECT_TRUE(is_destroyed); +} + +// Tests that listeners receive events in the order they were appended to +// the list, except for *End requests, which must be received in the reverse +// order. +class SequenceTestingListener : public EmptyTestEventListener { + public: + SequenceTestingListener(std::vector* vector, const char* id) + : vector_(vector), id_(id) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + vector_->push_back(GetEventDescription("OnTestProgramStart")); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + vector_->push_back(GetEventDescription("OnTestProgramEnd")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->push_back(GetEventDescription("OnTestIterationStart")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->push_back(GetEventDescription("OnTestIterationEnd")); + } + + private: + std::string GetEventDescription(const char* method) { + Message message; + message << id_ << "." << method; + return message.GetString(); + } + + std::vector* vector_; + const char* const id_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); +}; + +TEST(EventListenerTest, AppendKeepsOrder) { + std::vector vec; + TestEventListeners listeners; + listeners.Append(new SequenceTestingListener(&vec, "1st")); + listeners.Append(new SequenceTestingListener(&vec, "2nd")); + listeners.Append(new SequenceTestingListener(&vec, "3rd")); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( + *UnitTest::GetInstance()); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str()); + EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str()); + + vec.clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3U, vec.size()); + EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str()); + EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str()); + EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str()); +} + +// Tests that a listener removed from a TestEventListeners list stops receiving +// events and is not deleted when the list is destroyed. +TEST(TestEventListenersTest, Release) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + EXPECT_EQ(listener, listeners.Release(listener)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_TRUE(listeners.Release(listener) == NULL); + } + EXPECT_EQ(0, on_start_counter); + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that no events are forwarded when event forwarding is disabled. +TEST(EventListenerTest, SuppressEventForwarding) { + int on_start_counter = 0; + TestListener* listener = new TestListener(&on_start_counter, NULL); + + TestEventListeners listeners; + listeners.Append(listener); + ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::SuppressEventForwarding(&listeners); + ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); +} + +// Tests that events generated by Google Test are not forwarded in +// death test subprocesses. +TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { + EXPECT_DEATH_IF_SUPPORTED({ + GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled( + *GetUnitTestImpl()->listeners())) << "expected failure";}, + "expected failure"); +} + +// Tests that a listener installed via SetDefaultResultPrinter() starts +// receiving events and is returned via default_result_printer() and that +// the previous default_result_printer is removed from the list and deleted. +TEST(EventListenerTest, default_result_printer) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_result_printer()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_result_printer with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); + + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_result_printer listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_result_printer. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that a listener installed via SetDefaultXmlGenerator() starts +// receiving events and is returned via default_xml_generator() and that +// the previous default_xml_generator is removed from the list and deleted. +TEST(EventListenerTest, default_xml_generator) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_xml_generator()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_xml_generator with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); + + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_xml_generator listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_xml_generator. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Sanity tests to ensure that the alternative, verbose spellings of +// some of the macros work. We don't test them thoroughly as that +// would be quite involved. Since their implementations are +// straightforward, and they are rarely used, we'll just rely on the +// users to tell us when they are broken. +GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. + GTEST_SUCCEED() << "OK"; // GTEST_SUCCEED is the same as SUCCEED. + + // GTEST_FAIL is the same as FAIL. + EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", + "An expected failure"); + + // GTEST_ASSERT_XY is the same as ASSERT_XY. + + GTEST_ASSERT_EQ(0, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_NE(0, 1); + GTEST_ASSERT_NE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_NE(0, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LE(0, 0); + GTEST_ASSERT_LE(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LE(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_LT(0, 1); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(0, 0) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(1, 0) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GE(0, 0); + GTEST_ASSERT_GE(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GE(0, 1) << "An expected failure", + "An expected failure"); + + GTEST_ASSERT_GT(1, 0); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(0, 1) << "An expected failure", + "An expected failure"); + EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(1, 1) << "An expected failure", + "An expected failure"); +} + +// Tests for internal utilities necessary for implementation of the universal +// printing. +// TODO(vladl@google.com): Find a better home for them. + +class ConversionHelperBase {}; +class ConversionHelperDerived : public ConversionHelperBase {}; + +// Tests that IsAProtocolMessage::value is a compile-time constant. +TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_(IsAProtocolMessage::value, + const_true); + GTEST_COMPILE_ASSERT_(!IsAProtocolMessage::value, const_false); +} + +// Tests that IsAProtocolMessage::value is true when T is +// proto2::Message or a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { + EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); + EXPECT_TRUE(IsAProtocolMessage::value); +} + +// Tests that IsAProtocolMessage::value is false when T is neither +// ProtocolMessage nor a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { + EXPECT_FALSE(IsAProtocolMessage::value); + EXPECT_FALSE(IsAProtocolMessage::value); +} + +// Tests that CompileAssertTypesEqual compiles when the type arguments are +// equal. +TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) { + CompileAssertTypesEqual(); + CompileAssertTypesEqual(); +} + +// Tests that RemoveReference does not affect non-reference types. +TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveReference removes reference from reference types. +TEST(RemoveReferenceTest, RemovesReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_REFERENCE_. + +template +void TestGTestRemoveReference() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceTest, MacroVersion) { + TestGTestRemoveReference(); + TestGTestRemoveReference(); +} + + +// Tests that RemoveConst does not affect non-const types. +TEST(RemoveConstTest, DoesNotAffectNonConstType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that RemoveConst removes const from const types. +TEST(RemoveConstTest, RemovesConst) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_REMOVE_CONST_. + +template +void TestGTestRemoveConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveConstTest, MacroVersion) { + TestGTestRemoveConst(); + TestGTestRemoveConst(); + TestGTestRemoveConst(); +} + +// Tests GTEST_REMOVE_REFERENCE_AND_CONST_. + +template +void TestGTestRemoveReferenceAndConst() { + CompileAssertTypesEqual(); +} + +TEST(RemoveReferenceToConstTest, Works) { + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); + TestGTestRemoveReferenceAndConst(); +} + +// Tests that AddReference does not affect reference types. +TEST(AddReferenceTest, DoesNotAffectReferenceType) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests that AddReference adds reference to non-reference types. +TEST(AddReferenceTest, AddsReference) { + CompileAssertTypesEqual::type>(); + CompileAssertTypesEqual::type>(); +} + +// Tests GTEST_ADD_REFERENCE_. + +template +void TestGTestAddReference() { + CompileAssertTypesEqual(); +} + +TEST(AddReferenceTest, MacroVersion) { + TestGTestAddReference(); + TestGTestAddReference(); +} + +// Tests GTEST_REFERENCE_TO_CONST_. + +template +void TestGTestReferenceToConst() { + CompileAssertTypesEqual(); +} + +TEST(GTestReferenceToConstTest, Works) { + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); + TestGTestReferenceToConst(); +} + +// Tests that ImplicitlyConvertible::value is a compile-time constant. +TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) { + GTEST_COMPILE_ASSERT_((ImplicitlyConvertible::value), const_true); + GTEST_COMPILE_ASSERT_((!ImplicitlyConvertible::value), + const_false); +} + +// Tests that ImplicitlyConvertible::value is true when T1 can +// be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) { + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); + EXPECT_TRUE((ImplicitlyConvertible::value)); +} + +// Tests that ImplicitlyConvertible::value is false when T1 +// cannot be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) { + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); + EXPECT_FALSE((ImplicitlyConvertible::value)); +} + +// Tests IsContainerTest. + +class NonContainer {}; + +TEST(IsContainerTestTest, WorksForNonContainer) { + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); +} + +TEST(IsContainerTestTest, WorksForContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest >(0))); +} + +// Tests ArrayEq(). + +TEST(ArrayEqTest, WorksForDegeneratedArrays) { + EXPECT_TRUE(ArrayEq(5, 5L)); + EXPECT_FALSE(ArrayEq('a', 0)); +} + +TEST(ArrayEqTest, WorksForOneDimensionalArrays) { + // Note that a and b are distinct but compatible types. + const int a[] = { 0, 1 }; + long b[] = { 0, 1 }; + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + b[0] = 2; + EXPECT_FALSE(ArrayEq(a, b)); + EXPECT_FALSE(ArrayEq(a, 1, b)); +} + +TEST(ArrayEqTest, WorksForTwoDimensionalArrays) { + const char a[][3] = { "hi", "lo" }; + const char b[][3] = { "hi", "lo" }; + const char c[][3] = { "hi", "li" }; + + EXPECT_TRUE(ArrayEq(a, b)); + EXPECT_TRUE(ArrayEq(a, 2, b)); + + EXPECT_FALSE(ArrayEq(a, c)); + EXPECT_FALSE(ArrayEq(a, 2, c)); +} + +// Tests ArrayAwareFind(). + +TEST(ArrayAwareFindTest, WorksForOneDimensionalArray) { + const char a[] = "hello"; + EXPECT_EQ(a + 4, ArrayAwareFind(a, a + 5, 'o')); + EXPECT_EQ(a + 5, ArrayAwareFind(a, a + 5, 'x')); +} + +TEST(ArrayAwareFindTest, WorksForTwoDimensionalArray) { + int a[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } }; + const int b[2] = { 2, 3 }; + EXPECT_EQ(a + 1, ArrayAwareFind(a, a + 3, b)); + + const int c[2] = { 6, 7 }; + EXPECT_EQ(a + 3, ArrayAwareFind(a, a + 3, c)); +} + +// Tests CopyArray(). + +TEST(CopyArrayTest, WorksForDegeneratedArrays) { + int n = 0; + CopyArray('a', &n); + EXPECT_EQ('a', n); +} + +TEST(CopyArrayTest, WorksForOneDimensionalArrays) { + const char a[3] = "hi"; + int b[3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[3]; + CopyArray(a, 3, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { + const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; + int b[2][3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. + CopyArray(a, &b); + EXPECT_TRUE(ArrayEq(a, b)); +#endif + + int c[2][3]; + CopyArray(a, 2, c); + EXPECT_TRUE(ArrayEq(a, c)); +} + +// Tests NativeArray. + +TEST(NativeArrayTest, ConstructorFromArrayWorks) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, RelationToSourceReference()); + EXPECT_EQ(3U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) { + typedef int Array[2]; + Array* a = new Array[1]; + (*a)[0] = 0; + (*a)[1] = 1; + NativeArray na(*a, 2, RelationToSourceCopy()); + EXPECT_NE(*a, na.begin()); + delete[] a; + EXPECT_EQ(0, na.begin()[0]); + EXPECT_EQ(1, na.begin()[1]); + + // We rely on the heap checker to verify that na deletes the copy of + // array. +} + +TEST(NativeArrayTest, TypeMembersAreCorrect) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); + + StaticAssertTypeEq::const_iterator>(); + StaticAssertTypeEq::const_iterator>(); +} + +TEST(NativeArrayTest, MethodsWork) { + const int a[3] = { 0, 1, 2 }; + NativeArray na(a, 3, RelationToSourceCopy()); + ASSERT_EQ(3U, na.size()); + EXPECT_EQ(3, na.end() - na.begin()); + + NativeArray::const_iterator it = na.begin(); + EXPECT_EQ(0, *it); + ++it; + EXPECT_EQ(1, *it); + it++; + EXPECT_EQ(2, *it); + ++it; + EXPECT_EQ(na.end(), it); + + EXPECT_TRUE(na == na); + + NativeArray na2(a, 3, RelationToSourceReference()); + EXPECT_TRUE(na == na2); + + const int b1[3] = { 0, 1, 1 }; + const int b2[4] = { 0, 1, 2, 3 }; + EXPECT_FALSE(na == NativeArray(b1, 3, RelationToSourceReference())); + EXPECT_FALSE(na == NativeArray(b2, 4, RelationToSourceCopy())); +} + +TEST(NativeArrayTest, WorksForTwoDimensionalArray) { + const char a[2][3] = { "hi", "lo" }; + NativeArray na(a, 2, RelationToSourceReference()); + ASSERT_EQ(2U, na.size()); + EXPECT_EQ(a, na.begin()); +} + +// Tests SkipPrefix(). + +TEST(SkipPrefixTest, SkipsWhenPrefixMatches) { + const char* const str = "hello"; + + const char* p = str; + EXPECT_TRUE(SkipPrefix("", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_TRUE(SkipPrefix("hell", &p)); + EXPECT_EQ(str + 4, p); +} + +TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { + const char* const str = "world"; + + const char* p = str; + EXPECT_FALSE(SkipPrefix("W", &p)); + EXPECT_EQ(str, p); + + p = str; + EXPECT_FALSE(SkipPrefix("world!", &p)); + EXPECT_EQ(str, p); +} + diff --git a/src/test/gtest/test/gtest_xml_outfile1_test_.cc b/src/test/gtest/test/gtest_xml_outfile1_test_.cc new file mode 100644 index 00000000..531ced49 --- /dev/null +++ b/src/test/gtest/test/gtest_xml_outfile1_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile1_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyOne : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 1); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 1); + } +}; + +TEST_F(PropertyOne, TestSomeProperties) { + RecordProperty("TestSomeProperty", 1); +} diff --git a/src/test/gtest/test/gtest_xml_outfile2_test_.cc b/src/test/gtest/test/gtest_xml_outfile2_test_.cc new file mode 100644 index 00000000..7b400b27 --- /dev/null +++ b/src/test/gtest/test/gtest_xml_outfile2_test_.cc @@ -0,0 +1,49 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// gtest_xml_outfile2_test_ writes some xml via TestProperty used by +// gtest_xml_outfiles_test.py + +#include "gtest/gtest.h" + +class PropertyTwo : public testing::Test { + protected: + virtual void SetUp() { + RecordProperty("SetUpProp", 2); + } + virtual void TearDown() { + RecordProperty("TearDownProp", 2); + } +}; + +TEST_F(PropertyTwo, TestSomeProperties) { + RecordProperty("TestSomeProperty", 2); +} diff --git a/src/test/gtest/test/gtest_xml_outfiles_test.py b/src/test/gtest/test/gtest_xml_outfiles_test.py new file mode 100755 index 00000000..524e437e --- /dev/null +++ b/src/test/gtest/test/gtest_xml_outfiles_test.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Unit test for the gtest_xml_output module.""" + +__author__ = "keith.ray@gmail.com (Keith Ray)" + +import os +from xml.dom import minidom, Node + +import gtest_test_utils +import gtest_xml_test_utils + + +GTEST_OUTPUT_SUBDIR = "xml_outfiles" +GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" +GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" + +EXPECTED_XML_1 = """ + + + + + +""" + +EXPECTED_XML_2 = """ + + + + + +""" + + +class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): + """Unit test for Google Test's XML output functionality.""" + + def setUp(self): + # We want the trailing '/' that the last "" provides in os.path.join, for + # telling Google Test to create an output directory instead of a single file + # for xml output. + self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_OUTPUT_SUBDIR, "") + self.DeleteFilesAndDir() + + def tearDown(self): + self.DeleteFilesAndDir() + + def DeleteFilesAndDir(self): + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml")) + except os.error: + pass + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml")) + except os.error: + pass + try: + os.rmdir(self.output_dir_) + except os.error: + pass + + def testOutfile1(self): + self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_XML_1) + + def testOutfile2(self): + self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) + + def _TestOutFile(self, test_name, expected_xml): + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) + command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] + p = gtest_test_utils.Subprocess(command, + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + + # TODO(wan@google.com): libtool causes the built test binary to be + # named lt-gtest_xml_outfiles_test_ instead of + # gtest_xml_outfiles_test_. To account for this possibillity, we + # allow both names in the following code. We should remove this + # hack when Chandler Carruth's libtool replacement tool is ready. + output_file_name1 = test_name + ".xml" + output_file1 = os.path.join(self.output_dir_, output_file_name1) + output_file_name2 = 'lt-' + output_file_name1 + output_file2 = os.path.join(self.output_dir_, output_file_name2) + self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + output_file1) + + expected = minidom.parseString(expected_xml) + if os.path.isfile(output_file1): + actual = minidom.parse(output_file1) + else: + actual = minidom.parse(output_file2) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == "__main__": + os.environ["GTEST_STACK_TRACE_DEPTH"] = "0" + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_xml_output_unittest.py b/src/test/gtest/test/gtest_xml_output_unittest.py new file mode 100755 index 00000000..f605d4ee --- /dev/null +++ b/src/test/gtest/test/gtest_xml_output_unittest.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Unit test for the gtest_xml_output module""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import datetime +import errno +import os +import re +import sys +from xml.dom import minidom, Node + +import gtest_test_utils +import gtest_xml_test_utils + + +GTEST_FILTER_FLAG = '--gtest_filter' +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' +GTEST_OUTPUT_FLAG = "--gtest_output" +GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" + +SUPPORTS_STACK_TRACES = False + +if SUPPORTS_STACK_TRACES: + STACK_TRACE_TEMPLATE = '\nStack trace:\n*' +else: + STACK_TRACE_TEMPLATE = '' + +EXPECTED_NON_EMPTY_XML = """ + + + + + + + + + + + + + + + + + + + + ]]>%(stack)s]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" % {'stack': STACK_TRACE_TEMPLATE} + +EXPECTED_FILTERED_TEST_XML = """ + + + + +""" + +EXPECTED_EMPTY_XML = """ + +""" + +GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + +SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( + [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output + + +class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): + """ + Unit test for Google Test's XML output functionality. + """ + + # This test currently breaks on platforms that do not support typed and + # type-parameterized tests, so we don't run it under them. + if SUPPORTS_TYPED_TESTS: + def testNonEmptyXmlOutput(self): + """ + Runs a test program that generates a non-empty XML output, and + tests that the XML output is expected. + """ + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) + + def testEmptyXmlOutput(self): + """Verifies XML output for a Google Test binary without actual tests. + + Runs a test program that generates an empty XML output, and + tests that the XML output is expected. + """ + + self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) + + def testTimestampValue(self): + """Checks whether the timestamp attribute in the XML output is valid. + + Runs a test program that generates an empty XML output, and checks if + the timestamp attribute in the testsuites tag is valid. + """ + actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0) + date_time_str = actual.documentElement.getAttributeNode('timestamp').value + # datetime.strptime() is only available in Python 2.5+ so we have to + # parse the expected datetime manually. + match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) + self.assertTrue( + re.match, + 'XML datettime string %s has incorrect format' % date_time_str) + date_time_from_xml = datetime.datetime( + year=int(match.group(1)), month=int(match.group(2)), + day=int(match.group(3)), hour=int(match.group(4)), + minute=int(match.group(5)), second=int(match.group(6))) + + time_delta = abs(datetime.datetime.now() - date_time_from_xml) + # timestamp value should be near the current local time + self.assertTrue(time_delta < datetime.timedelta(seconds=600), + 'time_delta is %s' % time_delta) + actual.unlink() + + def testDefaultOutputFile(self): + """ + Confirms that Google Test produces an XML output file with the expected + default name if no name is explicitly specified. + """ + output_file = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + 'gtest_no_test_unittest') + try: + os.remove(output_file) + except OSError, e: + if e.errno != errno.ENOENT: + raise + + p = gtest_test_utils.Subprocess( + [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + self.assert_(os.path.isfile(output_file)) + + def testSuppressedXmlOutput(self): + """ + Tests that no XML file is generated if the default XML listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + 'out.xml') + if os.path.isfile(xml_path): + os.remove(xml_path) + + command = [GTEST_PROGRAM_PATH, + '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), + '--shut_down_xml'] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + # p.signal is avalable only if p.terminated_by_signal is True. + self.assertFalse( + p.terminated_by_signal, + '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(xml_path)) + + def testFilteredTestXmlOutput(self): + """Verifies XML output when a filter is applied. + + Runs a test program that executes only some tests and verifies that + non-selected tests do not show up in the XML output. + """ + + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0, + extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) + + def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code): + """ + Returns the xml output generated by running the program gtest_prog_name. + Furthermore, the program's exit code must be expected_exit_code. + """ + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + gtest_prog_name + 'out.xml') + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) + + command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + + extra_args) + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + self.assert_(False, + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(expected_exit_code, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, expected_exit_code)) + actual = minidom.parse(xml_path) + return actual + + def _TestXmlOutput(self, gtest_prog_name, expected_xml, + expected_exit_code, extra_args=None): + """ + Asserts that the XML document generated by running the program + gtest_prog_name matches expected_xml, a string containing another + XML document. Furthermore, the program's exit code must be + expected_exit_code. + """ + + actual = self._GetXmlOutput(gtest_prog_name, extra_args or [], + expected_exit_code) + expected = minidom.parseString(expected_xml) + self.NormalizeXml(actual.documentElement) + self.AssertEquivalentNodes(expected.documentElement, + actual.documentElement) + expected.unlink() + actual.unlink() + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' + gtest_test_utils.Main() diff --git a/src/test/gtest/test/gtest_xml_output_unittest_.cc b/src/test/gtest/test/gtest_xml_output_unittest_.cc new file mode 100644 index 00000000..48b8771b --- /dev/null +++ b/src/test/gtest/test/gtest_xml_output_unittest_.cc @@ -0,0 +1,181 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// Author: eefacm@gmail.com (Sean Mcafee) + +// Unit test for Google Test XML output. +// +// A user can specify XML output in a Google Test program to run via +// either the GTEST_OUTPUT environment variable or the --gtest_output +// flag. This is used for testing such functionality. +// +// This program will be invoked from a Python unit test. Don't run it +// directly. + +#include "gtest/gtest.h" + +using ::testing::InitGoogleTest; +using ::testing::TestEventListeners; +using ::testing::TestWithParam; +using ::testing::UnitTest; +using ::testing::Test; +using ::testing::Values; + +class SuccessfulTest : public Test { +}; + +TEST_F(SuccessfulTest, Succeeds) { + SUCCEED() << "This is a success."; + ASSERT_EQ(1, 1); +} + +class FailedTest : public Test { +}; + +TEST_F(FailedTest, Fails) { + ASSERT_EQ(1, 2); +} + +class DisabledTest : public Test { +}; + +TEST_F(DisabledTest, DISABLED_test_not_run) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(MixedResultTest, Succeeds) { + EXPECT_EQ(1, 1); + ASSERT_EQ(1, 1); +} + +TEST(MixedResultTest, Fails) { + EXPECT_EQ(1, 2); + ASSERT_EQ(2, 3); +} + +TEST(MixedResultTest, DISABLED_test) { + FAIL() << "Unexpected failure: Disabled test should not be run"; +} + +TEST(XmlQuotingTest, OutputsCData) { + FAIL() << "XML output: " + ""; +} + +// Helps to test that invalid characters produced by test code do not make +// it into the XML file. +TEST(InvalidCharactersTest, InvalidCharactersInMessage) { + FAIL() << "Invalid characters in brackets [\x1\x2]"; +} + +class PropertyRecordingTest : public Test { + public: + static void SetUpTestCase() { RecordProperty("SetUpTestCase", "yes"); } + static void TearDownTestCase() { RecordProperty("TearDownTestCase", "aye"); } +}; + +TEST_F(PropertyRecordingTest, OneProperty) { + RecordProperty("key_1", "1"); +} + +TEST_F(PropertyRecordingTest, IntValuedProperty) { + RecordProperty("key_int", 1); +} + +TEST_F(PropertyRecordingTest, ThreeProperties) { + RecordProperty("key_1", "1"); + RecordProperty("key_2", "2"); + RecordProperty("key_3", "3"); +} + +TEST_F(PropertyRecordingTest, TwoValuesForOneKeyUsesLastValue) { + RecordProperty("key_1", "1"); + RecordProperty("key_1", "2"); +} + +TEST(NoFixtureTest, RecordProperty) { + RecordProperty("key", "1"); +} + +void ExternalUtilityThatCallsRecordProperty(const std::string& key, int value) { + testing::Test::RecordProperty(key, value); +} + +void ExternalUtilityThatCallsRecordProperty(const std::string& key, + const std::string& value) { + testing::Test::RecordProperty(key, value); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_int", 1); +} + +TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { + ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); +} + +// Verifies that the test parameter value is output in the 'value_param' +// XML attribute for value-parameterized tests. +class ValueParamTest : public TestWithParam {}; +TEST_P(ValueParamTest, HasValueParamAttribute) {} +TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} +INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42)); + +#if GTEST_HAS_TYPED_TEST +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for typed tests. +template class TypedTest : public Test {}; +typedef testing::Types TypedTestTypes; +TYPED_TEST_CASE(TypedTest, TypedTestTypes); +TYPED_TEST(TypedTest, HasTypeParamAttribute) {} +#endif + +#if GTEST_HAS_TYPED_TEST_P +// Verifies that the type parameter name is output in the 'type_param' +// XML attribute for type-parameterized tests. +template class TypeParameterizedTestCase : public Test {}; +TYPED_TEST_CASE_P(TypeParameterizedTestCase); +TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {} +REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute); +typedef testing::Types TypeParameterizedTestCaseTypes; +INSTANTIATE_TYPED_TEST_CASE_P(Single, + TypeParameterizedTestCase, + TypeParameterizedTestCaseTypes); +#endif + +int main(int argc, char** argv) { + InitGoogleTest(&argc, argv); + + if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_xml_generator()); + } + testing::Test::RecordProperty("ad_hoc_property", "42"); + return RUN_ALL_TESTS(); +} diff --git a/src/test/gtest/test/gtest_xml_test_utils.py b/src/test/gtest/test/gtest_xml_test_utils.py new file mode 100755 index 00000000..3d0c3b2c --- /dev/null +++ b/src/test/gtest/test/gtest_xml_test_utils.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Unit test utilities for gtest_xml_output""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import re +from xml.dom import minidom, Node + +import gtest_test_utils + + +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' + +class GTestXMLTestCase(gtest_test_utils.TestCase): + """ + Base class for tests of Google Test's XML output functionality. + """ + + + def AssertEquivalentNodes(self, expected_node, actual_node): + """ + Asserts that actual_node (a DOM node object) is equivalent to + expected_node (another DOM node object), in that either both of + them are CDATA nodes and have the same value, or both are DOM + elements and actual_node meets all of the following conditions: + + * It has the same tag name as expected_node. + * It has the same set of attributes as expected_node, each with + the same value as the corresponding attribute of expected_node. + Exceptions are any attribute named "time", which needs only be + convertible to a floating-point number and any attribute named + "type_param" which only has to be non-empty. + * It has an equivalent set of child nodes (including elements and + CDATA sections) as expected_node. Note that we ignore the + order of the children as they are not guaranteed to be in any + particular order. + """ + + if expected_node.nodeType == Node.CDATA_SECTION_NODE: + self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) + self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) + return + + self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) + self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) + self.assertEquals(expected_node.tagName, actual_node.tagName) + + expected_attributes = expected_node.attributes + actual_attributes = actual_node .attributes + self.assertEquals( + expected_attributes.length, actual_attributes.length, + 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % ( + actual_node.tagName, expected_attributes.keys(), + actual_attributes.keys())) + for i in range(expected_attributes.length): + expected_attr = expected_attributes.item(i) + actual_attr = actual_attributes.get(expected_attr.name) + self.assert_( + actual_attr is not None, + 'expected attribute %s not found in element %s' % + (expected_attr.name, actual_node.tagName)) + self.assertEquals( + expected_attr.value, actual_attr.value, + ' values of attribute %s in element %s differ: %s vs %s' % + (expected_attr.name, actual_node.tagName, + expected_attr.value, actual_attr.value)) + + expected_children = self._GetChildren(expected_node) + actual_children = self._GetChildren(actual_node) + self.assertEquals( + len(expected_children), len(actual_children), + 'number of child elements differ in element ' + actual_node.tagName) + for child_id, child in expected_children.iteritems(): + self.assert_(child_id in actual_children, + '<%s> is not in <%s> (in element %s)' % + (child_id, actual_children, actual_node.tagName)) + self.AssertEquivalentNodes(child, actual_children[child_id]) + + identifying_attribute = { + 'testsuites': 'name', + 'testsuite': 'name', + 'testcase': 'name', + 'failure': 'message', + } + + def _GetChildren(self, element): + """ + Fetches all of the child nodes of element, a DOM Element object. + Returns them as the values of a dictionary keyed by the IDs of the + children. For , and elements, the ID + is the value of their "name" attribute; for elements, it is + the value of the "message" attribute; CDATA sections and non-whitespace + text nodes are concatenated into a single CDATA section with ID + "detail". An exception is raised if any element other than the above + four is encountered, if two child elements with the same identifying + attributes are encountered, or if any other type of node is encountered. + """ + + children = {} + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.assert_(child.tagName in self.identifying_attribute, + 'Encountered unknown element <%s>' % child.tagName) + childID = child.getAttribute(self.identifying_attribute[child.tagName]) + self.assert_(childID not in children) + children[childID] = child + elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: + if 'detail' not in children: + if (child.nodeType == Node.CDATA_SECTION_NODE or + not child.nodeValue.isspace()): + children['detail'] = child.ownerDocument.createCDATASection( + child.nodeValue) + else: + children['detail'].nodeValue += child.nodeValue + else: + self.fail('Encountered unexpected node type %d' % child.nodeType) + return children + + def NormalizeXml(self, element): + """ + Normalizes Google Test's XML output to eliminate references to transient + information that may change from run to run. + + * The "time" attribute of , and + elements is replaced with a single asterisk, if it contains + only digit characters. + * The "timestamp" attribute of elements is replaced with a + single asterisk, if it contains a valid ISO8601 datetime value. + * The "type_param" attribute of elements is replaced with a + single asterisk (if it sn non-empty) as it is the type name returned + by the compiler and is platform dependent. + * The line info reported in the first line of the "message" + attribute and CDATA section of elements is replaced with the + file's basename and a single asterisk for the line number. + * The directory names in file paths are removed. + * The stack traces are removed. + """ + + if element.tagName == 'testsuites': + timestamp = element.getAttributeNode('timestamp') + timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$', + '*', timestamp.value) + if element.tagName in ('testsuites', 'testsuite', 'testcase'): + time = element.getAttributeNode('time') + time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value) + type_param = element.getAttributeNode('type_param') + if type_param and type_param.value: + type_param.value = '*' + elif element.tagName == 'failure': + source_line_pat = r'^.*[/\\](.*:)\d+\n' + # Replaces the source line information with a normalized form. + message = element.getAttributeNode('message') + message.value = re.sub(source_line_pat, '\\1*\n', message.value) + for child in element.childNodes: + if child.nodeType == Node.CDATA_SECTION_NODE: + # Replaces the source line information with a normalized form. + cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) + # Removes the actual stack trace. + child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', + '', cdata) + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.NormalizeXml(child) diff --git a/src/test/gtest/test/production.cc b/src/test/gtest/test/production.cc new file mode 100644 index 00000000..8b8a40b4 --- /dev/null +++ b/src/test/gtest/test/production.cc @@ -0,0 +1,36 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#include "production.h" + +PrivateCode::PrivateCode() : x_(0) {} diff --git a/src/test/gtest/test/production.h b/src/test/gtest/test/production.h new file mode 100644 index 00000000..98fd5e47 --- /dev/null +++ b/src/test/gtest/test/production.h @@ -0,0 +1,55 @@ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This is part of the unit test for include/gtest/gtest_prod.h. + +#ifndef GTEST_TEST_PRODUCTION_H_ +#define GTEST_TEST_PRODUCTION_H_ + +#include "gtest/gtest_prod.h" + +class PrivateCode { + public: + // Declares a friend test that does not use a fixture. + FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers); + + // Declares a friend test that uses a fixture. + FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers); + + PrivateCode(); + + int x() const { return x_; } + private: + void set_x(int an_x) { x_ = an_x; } + int x_; +}; + +#endif // GTEST_TEST_PRODUCTION_H_ diff --git a/src/test/gtest/xcode/Config/DebugProject.xcconfig b/src/test/gtest/xcode/Config/DebugProject.xcconfig new file mode 100644 index 00000000..3d68157d --- /dev/null +++ b/src/test/gtest/xcode/Config/DebugProject.xcconfig @@ -0,0 +1,30 @@ +// +// DebugProject.xcconfig +// +// These are Debug Configuration project settings for the gtest framework and +// examples. It is set in the "Based On:" dropdown in the "Project" info +// dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +#include "General.xcconfig" + +// No optimization +GCC_OPTIMIZATION_LEVEL = 0 + +// Deployment postprocessing is what triggers Xcode to strip, turn it off +DEPLOYMENT_POSTPROCESSING = NO + +// Dead code stripping off +DEAD_CODE_STRIPPING = NO + +// Debug symbols should be on obviously +GCC_GENERATE_DEBUGGING_SYMBOLS = YES + +// Define the DEBUG macro in all debug builds +OTHER_CFLAGS = $(OTHER_CFLAGS) -DDEBUG=1 + +// These are turned off to avoid STL incompatibilities with client code +// // Turns on special C++ STL checks to "encourage" good STL use +// GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS) _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG _GLIBCPP_CONCEPT_CHECKS diff --git a/src/test/gtest/xcode/Config/FrameworkTarget.xcconfig b/src/test/gtest/xcode/Config/FrameworkTarget.xcconfig new file mode 100644 index 00000000..357b1c8f --- /dev/null +++ b/src/test/gtest/xcode/Config/FrameworkTarget.xcconfig @@ -0,0 +1,17 @@ +// +// FrameworkTarget.xcconfig +// +// These are Framework target settings for the gtest framework and examples. It +// is set in the "Based On:" dropdown in the "Target" info dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Dynamic libs need to be position independent +GCC_DYNAMIC_NO_PIC = NO + +// Dynamic libs should not have their external symbols stripped. +STRIP_STYLE = non-global + +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/src/test/gtest/xcode/Config/General.xcconfig b/src/test/gtest/xcode/Config/General.xcconfig new file mode 100644 index 00000000..f23e3222 --- /dev/null +++ b/src/test/gtest/xcode/Config/General.xcconfig @@ -0,0 +1,41 @@ +// +// General.xcconfig +// +// These are General configuration settings for the gtest framework and +// examples. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Build for PPC and Intel, 32- and 64-bit +ARCHS = i386 x86_64 ppc ppc64 + +// Zerolink prevents link warnings so turn it off +ZERO_LINK = NO + +// Prebinding considered unhelpful in 10.3 and later +PREBINDING = NO + +// Strictest warning policy +WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow + +// Work around Xcode bugs by using external strip. See: +// http://lists.apple.com/archives/Xcode-users/2006/Feb/msg00050.html +SEPARATE_STRIP = YES + +// Force C99 dialect +GCC_C_LANGUAGE_STANDARD = c99 + +// not sure why apple defaults this on, but it's pretty risky +ALWAYS_SEARCH_USER_PATHS = NO + +// Turn on position dependent code for most cases (overridden where appropriate) +GCC_DYNAMIC_NO_PIC = YES + +// Default SDK and minimum OS version is 10.4 +SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk +MACOSX_DEPLOYMENT_TARGET = 10.4 +GCC_VERSION = 4.0 + +// VERSIONING BUILD SETTINGS (used in Info.plist) +GTEST_VERSIONINFO_ABOUT = © 2008 Google Inc. diff --git a/src/test/gtest/xcode/Config/ReleaseProject.xcconfig b/src/test/gtest/xcode/Config/ReleaseProject.xcconfig new file mode 100644 index 00000000..5349f0a0 --- /dev/null +++ b/src/test/gtest/xcode/Config/ReleaseProject.xcconfig @@ -0,0 +1,32 @@ +// +// ReleaseProject.xcconfig +// +// These are Release Configuration project settings for the gtest framework +// and examples. It is set in the "Based On:" dropdown in the "Project" info +// dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +#include "General.xcconfig" + +// subconfig/Release.xcconfig + +// Optimize for space and size (Apple recommendation) +GCC_OPTIMIZATION_LEVEL = s + +// Deploment postprocessing is what triggers Xcode to strip +DEPLOYMENT_POSTPROCESSING = YES + +// No symbols +GCC_GENERATE_DEBUGGING_SYMBOLS = NO + +// Dead code strip does not affect ObjC code but can help for C +DEAD_CODE_STRIPPING = YES + +// NDEBUG is used by things like assert.h, so define it for general compat. +// ASSERT going away in release tends to create unused vars. +OTHER_CFLAGS = $(OTHER_CFLAGS) -DNDEBUG=1 -Wno-unused-variable + +// When we strip we want to strip all symbols in release, but save externals. +STRIP_STYLE = all diff --git a/src/test/gtest/xcode/Config/StaticLibraryTarget.xcconfig b/src/test/gtest/xcode/Config/StaticLibraryTarget.xcconfig new file mode 100644 index 00000000..3922fa51 --- /dev/null +++ b/src/test/gtest/xcode/Config/StaticLibraryTarget.xcconfig @@ -0,0 +1,18 @@ +// +// StaticLibraryTarget.xcconfig +// +// These are static library target settings for libgtest.a. It +// is set in the "Based On:" dropdown in the "Target" info dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Static libs can be included in bundles so make them position independent +GCC_DYNAMIC_NO_PIC = NO + +// Static libs should not have their internal globals or external symbols +// stripped. +STRIP_STYLE = debugging + +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/src/test/gtest/xcode/Config/TestTarget.xcconfig b/src/test/gtest/xcode/Config/TestTarget.xcconfig new file mode 100644 index 00000000..e6652ba8 --- /dev/null +++ b/src/test/gtest/xcode/Config/TestTarget.xcconfig @@ -0,0 +1,8 @@ +// +// TestTarget.xcconfig +// +// These are Test target settings for the gtest framework and examples. It +// is set in the "Based On:" dropdown in the "Target" info dialog. + +PRODUCT_NAME = $(TARGET_NAME) +HEADER_SEARCH_PATHS = ../include diff --git a/src/test/gtest/xcode/Resources/Info.plist b/src/test/gtest/xcode/Resources/Info.plist new file mode 100644 index 00000000..9dd28ea1 --- /dev/null +++ b/src/test/gtest/xcode/Resources/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.google.${PRODUCT_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + GTEST_VERSIONINFO_LONG + CFBundleShortVersionString + GTEST_VERSIONINFO_SHORT + CFBundleGetInfoString + ${PRODUCT_NAME} GTEST_VERSIONINFO_LONG, ${GTEST_VERSIONINFO_ABOUT} + NSHumanReadableCopyright + ${GTEST_VERSIONINFO_ABOUT} + CSResourcesFileMapped + + + diff --git a/src/test/gtest/xcode/Samples/FrameworkSample/Info.plist b/src/test/gtest/xcode/Samples/FrameworkSample/Info.plist new file mode 100644 index 00000000..f3852ede --- /dev/null +++ b/src/test/gtest/xcode/Samples/FrameworkSample/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.google.gtest.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + + + diff --git a/src/test/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/src/test/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj new file mode 100644 index 00000000..497617eb --- /dev/null +++ b/src/test/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj @@ -0,0 +1,457 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + 4024D162113D7D2400C7059E /* Test */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */; + buildPhases = ( + 4024D161113D7D2400C7059E /* ShellScript */, + ); + dependencies = ( + 4024D166113D7D3100C7059E /* PBXTargetDependency */, + ); + name = Test; + productName = TestAndBuild; + }; + 4024D1E9113D83FF00C7059E /* TestAndBuild */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */; + buildPhases = ( + ); + dependencies = ( + 4024D1ED113D840900C7059E /* PBXTargetDependency */, + 4024D1EF113D840D00C7059E /* PBXTargetDependency */, + ); + name = TestAndBuild; + productName = TestAndBuild; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1230E5AEE3500C7F239 /* widget.cc */; }; + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; }; + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; }; + 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D185113D7D5500C7059E /* libgtest.a */; }; + 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D183113D7D5500C7059E /* libgtest_main.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = gTestExample; + }; + 4024D165113D7D3100C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3B07BDE90E3F3F9E00647869; + remoteInfo = WidgetFrameworkTest; + }; + 4024D1EC113D840900C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = WidgetFramework; + }; + 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4024D162113D7D2400C7059E; + remoteInfo = Test; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WidgetFrameworkTest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = ""; }; + 3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = ""; }; + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = ""; }; + 4024D183113D7D5500C7059E /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /usr/local/lib/libgtest_main.a; sourceTree = ""; }; + 4024D185113D7D5500C7059E /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest.a; path = /usr/local/lib/libgtest.a; sourceTree = ""; }; + 4024D1E2113D838200C7059E /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; + 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3B07BDE80E3F3F9E00647869 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */, + 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */, + 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 8D07F2C80486CC7A007CD1D0 /* Widget.framework */, + 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gTestExample */ = { + isa = PBXGroup; + children = ( + 4024D1E1113D836C00C7059E /* Scripts */, + 08FB77ACFE841707C02AAC07 /* Source */, + 089C1665FE841158C02AAC07 /* Resources */, + 3B07BE350E4094E400647869 /* Test */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gTestExample; + sourceTree = ""; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 4024D183113D7D5500C7059E /* libgtest_main.a */, + 4024D185113D7D5500C7059E /* libgtest.a */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D07F2C70486CC7A007CD1D0 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 3B7EB1230E5AEE3500C7F239 /* widget.cc */, + 3B7EB1240E5AEE3500C7F239 /* widget.h */, + ); + name = Source; + sourceTree = ""; + }; + 3B07BE350E4094E400647869 /* Test */ = { + isa = PBXGroup; + children = ( + 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */, + ); + name = Test; + sourceTree = ""; + }; + 4024D1E1113D836C00C7059E /* Scripts */ = { + isa = PBXGroup; + children = ( + 4024D1E2113D838200C7059E /* runtests.sh */, + ); + name = Scripts; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */; + buildPhases = ( + 3B07BDE70E3F3F9E00647869 /* Sources */, + 3B07BDE80E3F3F9E00647869 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */, + ); + name = WidgetFrameworkTest; + productName = gTestExampleTest; + productReference = 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2C30486CC7A007CD1D0 /* Frameworks */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + 8D07F2C50486CC7A007CD1D0 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WidgetFramework; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gTestExample; + productReference = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* gTestExample */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */, + 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */, + 4024D162113D7D2400C7059E /* Test */, + 4024D1E9113D83FF00C7059E /* TestAndBuild */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D07F2C50486CC7A007CD1D0 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4024D161113D7D2400C7059E /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/bash $SRCROOT/runtests.sh $BUILT_PRODUCTS_DIR/WidgetFrameworkTest\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3B07BDE70E3F3F9E00647869 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; + targetProxy = 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */; + }; + 4024D166113D7D3100C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */; + targetProxy = 4024D165113D7D3100C7059E /* PBXContainerItemProxy */; + }; + 4024D1ED113D840900C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; + targetProxy = 4024D1EC113D840900C7059E /* PBXContainerItemProxy */; + }; + 4024D1EF113D840D00C7059E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4024D162113D7D2400C7059E /* Test */; + targetProxy = 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B07BDEC0E3F3F9F00647869 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Debug; + }; + 3B07BDED0E3F3F9F00647869 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = WidgetFrameworkTest; + }; + name = Release; + }; + 4024D163113D7D2400C7059E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Debug; + }; + 4024D164113D7D2400C7059E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Release; + }; + 4024D1EA113D83FF00C7059E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Debug; + }; + 4024D1EB113D83FF00C7059E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = TestAndBuild; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@loader_path/../Frameworks"; + PRODUCT_NAME = Widget; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B07BDEC0E3F3F9F00647869 /* Debug */, + 3B07BDED0E3F3F9F00647869 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4024D163113D7D2400C7059E /* Debug */, + 4024D164113D7D2400C7059E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4024D1EA113D83FF00C7059E /* Debug */, + 4024D1EB113D83FF00C7059E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/src/test/gtest/xcode/Samples/FrameworkSample/runtests.sh b/src/test/gtest/xcode/Samples/FrameworkSample/runtests.sh new file mode 100644 index 00000000..4a0d413e --- /dev/null +++ b/src/test/gtest/xcode/Samples/FrameworkSample/runtests.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +# Executes the samples and tests for the Google Test Framework. + +# Help the dynamic linker find the path to the libraries. +export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR +export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR + +# Create some executables. +test_executables=$@ + +# Now execute each one in turn keeping track of how many succeeded and failed. +succeeded=0 +failed=0 +failed_list=() +for test in ${test_executables[*]}; do + "$test" + result=$? + if [ $result -eq 0 ]; then + succeeded=$(( $succeeded + 1 )) + else + failed=$(( failed + 1 )) + failed_list="$failed_list $test" + fi +done + +# Report the successes and failures to the console. +echo "Tests complete with $succeeded successes and $failed failures." +if [ $failed -ne 0 ]; then + echo "The following tests failed:" + echo $failed_list +fi +exit $failed diff --git a/src/test/gtest/xcode/Samples/FrameworkSample/widget.cc b/src/test/gtest/xcode/Samples/FrameworkSample/widget.cc new file mode 100644 index 00000000..bfc4e7fc --- /dev/null +++ b/src/test/gtest/xcode/Samples/FrameworkSample/widget.cc @@ -0,0 +1,63 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget.cc +// + +// Widget is a very simple class used for demonstrating the use of gtest + +#include "widget.h" + +Widget::Widget(int number, const std::string& name) + : number_(number), + name_(name) {} + +Widget::~Widget() {} + +float Widget::GetFloatValue() const { + return number_; +} + +int Widget::GetIntValue() const { + return static_cast(number_); +} + +std::string Widget::GetStringValue() const { + return name_; +} + +void Widget::GetCharPtrValue(char* buffer, size_t max_size) const { + // Copy the char* representation of name_ into buffer, up to max_size. + strncpy(buffer, name_.c_str(), max_size-1); + buffer[max_size-1] = '\0'; + return; +} diff --git a/src/test/gtest/xcode/Samples/FrameworkSample/widget.h b/src/test/gtest/xcode/Samples/FrameworkSample/widget.h new file mode 100644 index 00000000..0c55cdc8 --- /dev/null +++ b/src/test/gtest/xcode/Samples/FrameworkSample/widget.h @@ -0,0 +1,59 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget.h +// + +// Widget is a very simple class used for demonstrating the use of gtest. It +// simply stores two values a string and an integer, which are returned via +// public accessors in multiple forms. + +#import + +class Widget { + public: + Widget(int number, const std::string& name); + ~Widget(); + + // Public accessors to number data + float GetFloatValue() const; + int GetIntValue() const; + + // Public accessors to the string data + std::string GetStringValue() const; + void GetCharPtrValue(char* buffer, size_t max_size) const; + + private: + // Data members + float number_; + std::string name_; +}; diff --git a/src/test/gtest/xcode/Samples/FrameworkSample/widget_test.cc b/src/test/gtest/xcode/Samples/FrameworkSample/widget_test.cc new file mode 100644 index 00000000..87259942 --- /dev/null +++ b/src/test/gtest/xcode/Samples/FrameworkSample/widget_test.cc @@ -0,0 +1,68 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +// +// Author: preston.a.jackson@gmail.com (Preston Jackson) +// +// Google Test - FrameworkSample +// widget_test.cc +// + +// This is a simple test file for the Widget class in the Widget.framework + +#include +#include "gtest/gtest.h" + +#include + +// This test verifies that the constructor sets the internal state of the +// Widget class correctly. +TEST(WidgetInitializerTest, TestConstructor) { + Widget widget(1.0f, "name"); + EXPECT_FLOAT_EQ(1.0f, widget.GetFloatValue()); + EXPECT_EQ(std::string("name"), widget.GetStringValue()); +} + +// This test verifies the conversion of the float and string values to int and +// char*, respectively. +TEST(WidgetInitializerTest, TestConversion) { + Widget widget(1.0f, "name"); + EXPECT_EQ(1, widget.GetIntValue()); + + size_t max_size = 128; + char buffer[max_size]; + widget.GetCharPtrValue(buffer, max_size); + EXPECT_STREQ("name", buffer); +} + +// Use the Google Test main that is linked into the framework. It does something +// like this: +// int main(int argc, char** argv) { +// testing::InitGoogleTest(&argc, argv); +// return RUN_ALL_TESTS(); +// } diff --git a/src/test/gtest/xcode/Scripts/runtests.sh b/src/test/gtest/xcode/Scripts/runtests.sh new file mode 100644 index 00000000..3fc229f1 --- /dev/null +++ b/src/test/gtest/xcode/Scripts/runtests.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +# Executes the samples and tests for the Google Test Framework. + +# Help the dynamic linker find the path to the libraries. +export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR +export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR + +# Create some executables. +test_executables=("$BUILT_PRODUCTS_DIR/gtest_unittest-framework" + "$BUILT_PRODUCTS_DIR/gtest_unittest" + "$BUILT_PRODUCTS_DIR/sample1_unittest-framework" + "$BUILT_PRODUCTS_DIR/sample1_unittest-static") + +# Now execute each one in turn keeping track of how many succeeded and failed. +succeeded=0 +failed=0 +failed_list=() +for test in ${test_executables[*]}; do + "$test" + result=$? + if [ $result -eq 0 ]; then + succeeded=$(( $succeeded + 1 )) + else + failed=$(( failed + 1 )) + failed_list="$failed_list $test" + fi +done + +# Report the successes and failures to the console. +echo "Tests complete with $succeeded successes and $failed failures." +if [ $failed -ne 0 ]; then + echo "The following tests failed:" + echo $failed_list +fi +exit $failed diff --git a/src/test/gtest/xcode/Scripts/versiongenerate.py b/src/test/gtest/xcode/Scripts/versiongenerate.py new file mode 100644 index 00000000..81de8c96 --- /dev/null +++ b/src/test/gtest/xcode/Scripts/versiongenerate.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# +# Copyright 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""A script to prepare version informtion for use the gtest Info.plist file. + + This script extracts the version information from the configure.ac file and + uses it to generate a header file containing the same information. The + #defines in this header file will be included in during the generation of + the Info.plist of the framework, giving the correct value to the version + shown in the Finder. + + This script makes the following assumptions (these are faults of the script, + not problems with the Autoconf): + 1. The AC_INIT macro will be contained within the first 1024 characters + of configure.ac + 2. The version string will be 3 integers separated by periods and will be + surrounded by squre brackets, "[" and "]" (e.g. [1.0.1]). The first + segment represents the major version, the second represents the minor + version and the third represents the fix version. + 3. No ")" character exists between the opening "(" and closing ")" of + AC_INIT, including in comments and character strings. +""" + +import sys +import re + +# Read the command line argument (the output directory for Version.h) +if (len(sys.argv) < 3): + print "Usage: versiongenerate.py input_dir output_dir" + sys.exit(1) +else: + input_dir = sys.argv[1] + output_dir = sys.argv[2] + +# Read the first 1024 characters of the configure.ac file +config_file = open("%s/configure.ac" % input_dir, 'r') +buffer_size = 1024 +opening_string = config_file.read(buffer_size) +config_file.close() + +# Extract the version string from the AC_INIT macro +# The following init_expression means: +# Extract three integers separated by periods and surrounded by squre +# brackets(e.g. "[1.0.1]") between "AC_INIT(" and ")". Do not be greedy +# (*? is the non-greedy flag) since that would pull in everything between +# the first "(" and the last ")" in the file. +version_expression = re.compile(r"AC_INIT\(.*?\[(\d+)\.(\d+)\.(\d+)\].*?\)", + re.DOTALL) +version_values = version_expression.search(opening_string) +major_version = version_values.group(1) +minor_version = version_values.group(2) +fix_version = version_values.group(3) + +# Write the version information to a header file to be included in the +# Info.plist file. +file_data = """// +// DO NOT MODIFY THIS FILE (but you can delete it) +// +// This file is autogenerated by the versiongenerate.py script. This script +// is executed in a "Run Script" build phase when creating gtest.framework. This +// header file is not used during compilation of C-source. Rather, it simply +// defines some version strings for substitution in the Info.plist. Because of +// this, we are not not restricted to C-syntax nor are we using include guards. +// + +#define GTEST_VERSIONINFO_SHORT %s.%s +#define GTEST_VERSIONINFO_LONG %s.%s.%s + +""" % (major_version, minor_version, major_version, minor_version, fix_version) +version_file = open("%s/Version.h" % output_dir, 'w') +version_file.write(file_data) +version_file.close() diff --git a/src/test/gtest/xcode/gtest.xcodeproj/project.pbxproj b/src/test/gtest/xcode/gtest.xcodeproj/project.pbxproj new file mode 100644 index 00000000..0452a63d --- /dev/null +++ b/src/test/gtest/xcode/gtest.xcodeproj/project.pbxproj @@ -0,0 +1,1135 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXAggregateTarget section */ + 3B238F5F0E828B5400846E11 /* Check */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */; + buildPhases = ( + 3B238F5E0E828B5400846E11 /* ShellScript */, + ); + dependencies = ( + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */, + 40C849F7101A43440083642A /* PBXTargetDependency */, + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */, + 40C849F9101A43490083642A /* PBXTargetDependency */, + ); + name = Check; + productName = Check; + }; + 40C44ADC0E3798F4008FCC51 /* Version Info */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */; + buildPhases = ( + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */, + ); + comments = "The generation of Version.h must be performed in its own target. Since the Info.plist is preprocessed before any of the other build phases in gtest, the Version.h file would not be ready if included as a build phase of that target."; + dependencies = ( + ); + name = "Version Info"; + productName = Version.h; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */ = {isa = PBXBuildFile; fileRef = 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */; }; + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DC0E2F799B00CF7658 /* gtest-message.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DD0E2F799B00CF7658 /* gtest-spi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DE0E2F799B00CF7658 /* gtest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883E00E2F799B00CF7658 /* gtest_prod.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 404884500E2F799B00CF7658 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 404883F60E2F799B00CF7658 /* README */; }; + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */; }; + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E30E2F799B00CF7658 /* gtest-filepath.h */; }; + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E40E2F799B00CF7658 /* gtest-internal.h */; }; + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E50E2F799B00CF7658 /* gtest-port.h */; }; + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; }; + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; }; + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; }; + 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* LICENSE */; }; + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; }; + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C848FF101A21150083642A /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; }; + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84978101A36540083642A /* libgtest_main.a in Resources */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 40C84982101A36850083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C8498F101A36A60083642A /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C84992101A36A60083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C849A2101A37050083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 40C849A4101A37150083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; }; + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; }; + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; }; + 4567C8181264FF71007740BE /* gtest-printers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4567C8171264FF71007740BE /* gtest-printers.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40899F420FFA7184000B29AE; + remoteInfo = gtest_unittest; + }; + 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4089A0120FFACEFC000B29AE; + remoteInfo = sample1_unittest; + }; + 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C44ADC0E3798F4008FCC51; + remoteInfo = Version.h; + }; + 40C8497C101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8497E101A36850083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8498B101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; + }; + 40C8498D101A36A60083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499B101A36DC0083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; + }; + 40C8499D101A36E50083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C8499F101A36F10083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; + remoteInfo = "gtest-framework"; + }; + 40C849F6101A43440083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C8497A101A36850083642A; + remoteInfo = "gtest_unittest-static"; + }; + 40C849F8101A43490083642A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40C84989101A36A60083642A; + remoteInfo = "sample1_unittest-static"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Headers/internal; + dstSubfolderSpec = 6; + files = ( + 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */, + 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */, + 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */, + 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */, + 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */, + 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */, + 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */, + 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */, + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */, + 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */, + ); + name = "Copy Headers Internal"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 224A12A10E9EADA700BD17FD /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = ""; }; + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "gtest-test-part.h"; sourceTree = ""; }; + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_unittest.cc; sourceTree = ""; }; + 3B87D2100E96B92E000D1852 /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-type-util.h"; sourceTree = ""; }; + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test.h"; sourceTree = ""; }; + 403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = ""; }; + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test.h"; sourceTree = ""; }; + 404883DC0E2F799B00CF7658 /* gtest-message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-message.h"; sourceTree = ""; }; + 404883DD0E2F799B00CF7658 /* gtest-spi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-spi.h"; sourceTree = ""; }; + 404883DE0E2F799B00CF7658 /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest.h; sourceTree = ""; }; + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_pred_impl.h; sourceTree = ""; }; + 404883E00E2F799B00CF7658 /* gtest_prod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_prod.h; sourceTree = ""; }; + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test-internal.h"; sourceTree = ""; }; + 404883E30E2F799B00CF7658 /* gtest-filepath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-filepath.h"; sourceTree = ""; }; + 404883E40E2F799B00CF7658 /* gtest-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-internal.h"; sourceTree = ""; }; + 404883E50E2F799B00CF7658 /* gtest-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-port.h"; sourceTree = ""; }; + 404883E60E2F799B00CF7658 /* gtest-string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-string.h"; sourceTree = ""; }; + 404883F60E2F799B00CF7658 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; }; + 4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = ""; }; + 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; + 404884AB0E2F7CD900CF7658 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = SOURCE_ROOT; }; + 40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = ""; }; + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = ""; }; + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4089A02C0FFACF7F000B29AE /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = ""; }; + 4089A02D0FFACF7F000B29AE /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = ""; }; + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = ""; }; + 40C848FA101A209C0083642A /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C8490B101A217E0083642A /* libgtest_main.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest_main.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84987101A36850083642A /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84997101A36A60083642A /* sample1_unittest-static */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-static"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = ""; }; + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = ""; }; + 40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = ""; }; + 40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = ""; }; + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = ""; }; + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = ""; }; + 4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = ""; }; + 4567C8171264FF71007740BE /* gtest-printers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-printers.h"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 40899F410FFA7184000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A4101A37150083642A /* gtest.framework in Frameworks */, + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0110FFACEFC000B29AE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C849A2101A37050083642A /* gtest.framework in Frameworks */, + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84981101A36850083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84982101A36850083642A /* libgtest.a in Frameworks */, + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84991101A36A60083642A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84992101A36A60083642A /* libgtest.a in Frameworks */, + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 4539C8FF0EC27F6400A70F4C /* gtest.framework */, + 40C848FA101A209C0083642A /* libgtest.a */, + 40C8490B101A217E0083642A /* libgtest_main.a */, + 40899F430FFA7184000B29AE /* gtest_unittest-framework */, + 40C84987101A36850083642A /* gtest_unittest */, + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84997101A36A60083642A /* sample1_unittest-static */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* gtest */ = { + isa = PBXGroup; + children = ( + 40D4CDF00E30E07400294801 /* Config */, + 08FB77ACFE841707C02AAC07 /* Source */, + 40D4CF4E0E30F5E200294801 /* Resources */, + 403EE37B0E377822004BD1E2 /* Scripts */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = gtest; + sourceTree = ""; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 404884A90E2F7CD900CF7658 /* CHANGES */, + 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */, + 404884AB0E2F7CD900CF7658 /* LICENSE */, + 404883F60E2F799B00CF7658 /* README */, + 404883D90E2F799B00CF7658 /* include */, + 4089A02F0FFACF84000B29AE /* samples */, + 404884070E2F799B00CF7658 /* src */, + 3B238BF00E7FE13B00846E11 /* test */, + ); + name = Source; + sourceTree = ""; + }; + 3B238BF00E7FE13B00846E11 /* test */ = { + isa = PBXGroup; + children = ( + 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */, + ); + name = test; + path = ../test; + sourceTree = SOURCE_ROOT; + }; + 403EE37B0E377822004BD1E2 /* Scripts */ = { + isa = PBXGroup; + children = ( + 403EE37C0E377822004BD1E2 /* versiongenerate.py */, + 3B87D2100E96B92E000D1852 /* runtests.sh */, + ); + path = Scripts; + sourceTree = ""; + }; + 404883D90E2F799B00CF7658 /* include */ = { + isa = PBXGroup; + children = ( + 404883DA0E2F799B00CF7658 /* gtest */, + ); + name = include; + path = ../include; + sourceTree = SOURCE_ROOT; + }; + 404883DA0E2F799B00CF7658 /* gtest */ = { + isa = PBXGroup; + children = ( + 404883E10E2F799B00CF7658 /* internal */, + 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */, + 404883DB0E2F799B00CF7658 /* gtest-death-test.h */, + 404883DC0E2F799B00CF7658 /* gtest-message.h */, + 4539C9330EC280AE00A70F4C /* gtest-param-test.h */, + 4567C8171264FF71007740BE /* gtest-printers.h */, + 404883DD0E2F799B00CF7658 /* gtest-spi.h */, + 404883DE0E2F799B00CF7658 /* gtest.h */, + 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */, + 404883E00E2F799B00CF7658 /* gtest_prod.h */, + 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */, + ); + path = gtest; + sourceTree = ""; + }; + 404883E10E2F799B00CF7658 /* internal */ = { + isa = PBXGroup; + children = ( + 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */, + 404883E30E2F799B00CF7658 /* gtest-filepath.h */, + 404883E40E2F799B00CF7658 /* gtest-internal.h */, + 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */, + 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */, + 4539C9370EC280E200A70F4C /* gtest-param-util.h */, + 404883E50E2F799B00CF7658 /* gtest-port.h */, + 404883E60E2F799B00CF7658 /* gtest-string.h */, + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */, + 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */, + ); + path = internal; + sourceTree = ""; + }; + 404884070E2F799B00CF7658 /* src */ = { + isa = PBXGroup; + children = ( + 224A12A10E9EADA700BD17FD /* gtest-all.cc */, + 4048840D0E2F799B00CF7658 /* gtest_main.cc */, + ); + name = src; + path = ../src; + sourceTree = SOURCE_ROOT; + }; + 4089A02F0FFACF84000B29AE /* samples */ = { + isa = PBXGroup; + children = ( + 4089A02C0FFACF7F000B29AE /* sample1.cc */, + 4089A02D0FFACF7F000B29AE /* sample1.h */, + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */, + ); + name = samples; + path = ../samples; + sourceTree = SOURCE_ROOT; + }; + 40D4CDF00E30E07400294801 /* Config */ = { + isa = PBXGroup; + children = ( + 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */, + 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */, + 40D4CDF30E30E07400294801 /* General.xcconfig */, + 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */, + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */, + ); + path = Config; + sourceTree = ""; + }; + 40D4CF4E0E30F5E200294801 /* Resources */ = { + isa = PBXGroup; + children = ( + 40D4CF510E30F5E200294801 /* Info.plist */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */, + 404884390E2F799B00CF7658 /* gtest-message.h in Headers */, + 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */, + 4567C8181264FF71007740BE /* gtest-printers.h in Headers */, + 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */, + 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */, + 4048843B0E2F799B00CF7658 /* gtest.h in Headers */, + 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */, + 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */, + 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 40899F420FFA7184000B29AE /* gtest_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */; + buildPhases = ( + 40899F400FFA7184000B29AE /* Sources */, + 40899F410FFA7184000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C849A0101A36F10083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-framework"; + productName = gtest_unittest; + productReference = 40899F430FFA7184000B29AE /* gtest_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */; + buildPhases = ( + 4089A0100FFACEFC000B29AE /* Sources */, + 4089A0110FFACEFC000B29AE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8499E101A36E50083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-framework"; + productName = sample1_unittest; + productReference = 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */; + productType = "com.apple.product-type.tool"; + }; + 40C848F9101A209C0083642A /* gtest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */; + buildPhases = ( + 40C848F7101A209C0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest-static"; + productName = "gtest-static"; + productReference = 40C848FA101A209C0083642A /* libgtest.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8490A101A217E0083642A /* gtest_main-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */; + buildPhases = ( + 40C84908101A217E0083642A /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gtest_main-static"; + productName = "gtest_main-static"; + productReference = 40C8490B101A217E0083642A /* libgtest_main.a */; + productType = "com.apple.product-type.library.static"; + }; + 40C8497A101A36850083642A /* gtest_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */; + buildPhases = ( + 40C8497F101A36850083642A /* Sources */, + 40C84981101A36850083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8497B101A36850083642A /* PBXTargetDependency */, + 40C8497D101A36850083642A /* PBXTargetDependency */, + ); + name = "gtest_unittest-static"; + productName = gtest_unittest; + productReference = 40C84987101A36850083642A /* gtest_unittest */; + productType = "com.apple.product-type.tool"; + }; + 40C84989101A36A60083642A /* sample1_unittest-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */; + buildPhases = ( + 40C8498E101A36A60083642A /* Sources */, + 40C84991101A36A60083642A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 40C8498A101A36A60083642A /* PBXTargetDependency */, + 40C8498C101A36A60083642A /* PBXTargetDependency */, + ); + name = "sample1_unittest-static"; + productName = sample1_unittest; + productReference = 40C84997101A36A60083642A /* sample1_unittest-static */; + productType = "com.apple.product-type.tool"; + }; + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */; + buildPhases = ( + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 404884A50E2F7C0400CF7658 /* Copy Headers Internal */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 40C44AE60E379922008FCC51 /* PBXTargetDependency */, + 408BEC101046CFE900DEF522 /* PBXTargetDependency */, + 40C8499C101A36DC0083642A /* PBXTargetDependency */, + ); + name = "gtest-framework"; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = gtest; + productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; + buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 0867D691FE84028FC02AAC07 /* gtest */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */, + 40C848F9101A209C0083642A /* gtest-static */, + 40C8490A101A217E0083642A /* gtest_main-static */, + 40899F420FFA7184000B29AE /* gtest_unittest-framework */, + 40C8497A101A36850083642A /* gtest_unittest-static */, + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84989101A36A60083642A /* sample1_unittest-static */, + 3B238F5F0E828B5400846E11 /* Check */, + 40C44ADC0E3798F4008FCC51 /* Version Info */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 404884500E2F799B00CF7658 /* README in Resources */, + 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */, + 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */, + 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */, + 40C84978101A36540083642A /* libgtest_main.a in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B238F5E0E828B5400846E11 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/bin/bash Scripts/runtests.sh"; + }; + 40C44ADB0E3798F4008FCC51 /* Generate Version.h */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/Scripts/versiongenerate.py", + "$(SRCROOT)/../configure.ac", + ); + name = "Generate Version.h"; + outputPaths = ( + "$(PROJECT_TEMP_DIR)/Version.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $PROJECT_TEMP_DIR"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 40899F400FFA7184000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4089A0100FFACEFC000B29AE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */, + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C848F7101A209C0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C848FF101A21150083642A /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C84908101A217E0083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8497F101A36850083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40C8498E101A36A60083642A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40C8498F101A36A60083642A /* sample1.cc in Sources */, + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40899F420FFA7184000B29AE /* gtest_unittest-framework */; + targetProxy = 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */; + }; + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */; + targetProxy = 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */; + }; + 408BEC101046CFE900DEF522 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */; + }; + 40C44AE60E379922008FCC51 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C44ADC0E3798F4008FCC51 /* Version Info */; + targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */; + }; + 40C8497B101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8497C101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8497D101A36850083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8497E101A36850083642A /* PBXContainerItemProxy */; + }; + 40C8498A101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8498B101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8498C101A36A60083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8498D101A36A60083642A /* PBXContainerItemProxy */; + }; + 40C8499C101A36DC0083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8499B101A36DC0083642A /* PBXContainerItemProxy */; + }; + 40C8499E101A36E50083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499D101A36E50083642A /* PBXContainerItemProxy */; + }; + 40C849A0101A36F10083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499F101A36F10083642A /* PBXContainerItemProxy */; + }; + 40C849F7101A43440083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C8497A101A36850083642A /* gtest_unittest-static */; + targetProxy = 40C849F6101A43440083642A /* PBXContainerItemProxy */; + }; + 40C849F9101A43490083642A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40C84989101A36A60083642A /* sample1_unittest-static */; + targetProxy = 40C849F8101A43490083642A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3B238F600E828B5400846E11 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = Check; + SDKROOT = macosx; + }; + name = Debug; + }; + 3B238F610E828B5400846E11 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = Check; + SDKROOT = macosx; + ZERO_LINK = NO; + }; + name = Release; + }; + 40899F450FFA7185000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + SDKROOT = macosx; + }; + name = Debug; + }; + 40899F460FFA7185000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; + SDKROOT = macosx; + }; + name = Release; + }; + 4089A0150FFACEFD000B29AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-framework"; + SDKROOT = macosx; + }; + name = Debug; + }; + 4089A0160FFACEFD000B29AE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-framework"; + SDKROOT = macosx; + }; + name = Release; + }; + 40C44ADF0E3798F4008FCC51 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + TARGET_NAME = gtest; + }; + name = Debug; + }; + 40C44AE00E3798F4008FCC51 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + TARGET_NAME = gtest; + }; + name = Release; + }; + 40C848FB101A209D0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C848FC101A209D0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest; + SDKROOT = macosx; + }; + name = Release; + }; + 40C8490E101A217F0083642A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C8490F101A217F0083642A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + PRODUCT_NAME = gtest_main; + SDKROOT = macosx; + }; + name = Release; + }; + 40C84985101A36850083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C84986101A36850083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; + SDKROOT = macosx; + }; + name = Release; + }; + 40C84995101A36A60083642A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-static"; + SDKROOT = macosx; + }; + name = Debug; + }; + 40C84996101A36A60083642A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + PRODUCT_NAME = "sample1_unittest-static"; + SDKROOT = macosx; + }; + name = Release; + }; + 4FADC24308B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 4FADC24408B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, + ); + INFOPLIST_FILE = Resources/Info.plist; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; + INFOPLIST_PREPROCESS = YES; + PRODUCT_NAME = gtest; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 4FADC24708B4156D00ABE55E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + 4FADC24808B4156D00ABE55E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B238F600E828B5400846E11 /* Debug */, + 3B238F610E828B5400846E11 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40899F450FFA7185000B29AE /* Debug */, + 40899F460FFA7185000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4089A0150FFACEFD000B29AE /* Debug */, + 4089A0160FFACEFD000B29AE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C44ADF0E3798F4008FCC51 /* Debug */, + 40C44AE00E3798F4008FCC51 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C848FB101A209D0083642A /* Debug */, + 40C848FC101A209D0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C8490E101A217F0083642A /* Debug */, + 40C8490F101A217F0083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84985101A36850083642A /* Debug */, + 40C84986101A36850083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40C84995101A36A60083642A /* Debug */, + 40C84996101A36A60083642A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24308B4156D00ABE55E /* Debug */, + 4FADC24408B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4FADC24708B4156D00ABE55E /* Debug */, + 4FADC24808B4156D00ABE55E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} From 93a2f6dc2cccd017f49fef87ff595c48d01190d1 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Thu, 10 Jul 2014 11:59:24 +0200 Subject: [PATCH 071/157] Update Lucene++Docs.cmake This is where debian installs the documentation stuff --- cmake/Lucene++Docs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Lucene++Docs.cmake b/cmake/Lucene++Docs.cmake index 476f984d..c7473049 100644 --- a/cmake/Lucene++Docs.cmake +++ b/cmake/Lucene++Docs.cmake @@ -142,7 +142,7 @@ IF (ENABLE_DOCS) #install HTML pages if they were built IF ( DOCS_HTML AND NOT WIN32 ) - INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/doc/html/" DESTINATION share/doc/lucene++-${lucene++_VERSION}) + INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/doc/html/" DESTINATION share/doc/lucene++/html) ENDIF ( DOCS_HTML AND NOT WIN32 ) #install man pages if they were built From 8f2bb907d119322e1615a5cc06effec24b9a7c76 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Thu, 10 Jul 2014 12:24:51 +0200 Subject: [PATCH 072/157] Moving into -doc directory, the best location for a doxygen documentation directory --- cmake/Lucene++Docs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Lucene++Docs.cmake b/cmake/Lucene++Docs.cmake index c7473049..becc13c4 100644 --- a/cmake/Lucene++Docs.cmake +++ b/cmake/Lucene++Docs.cmake @@ -142,7 +142,7 @@ IF (ENABLE_DOCS) #install HTML pages if they were built IF ( DOCS_HTML AND NOT WIN32 ) - INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/doc/html/" DESTINATION share/doc/lucene++/html) + INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/doc/html/" DESTINATION share/doc/lucene++-doc/html) ENDIF ( DOCS_HTML AND NOT WIN32 ) #install man pages if they were built From a385bcf745bd9e04f2404a3613e0a6b6fe041302 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 10 Jul 2014 14:20:03 +0100 Subject: [PATCH 073/157] Upgrade cotire to 1.6.3. --- cmake/cotire.cmake | 230 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 176 insertions(+), 54 deletions(-) diff --git a/cmake/cotire.cmake b/cmake/cotire.cmake index ddfe4bfd..990f2778 100644 --- a/cmake/cotire.cmake +++ b/cmake/cotire.cmake @@ -45,7 +45,7 @@ if (NOT CMAKE_SCRIPT_MODE_FILE) endif() set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.6.1") +set (COTIRE_CMAKE_MODULE_VERSION "1.6.3") include(CMakeParseArguments) include(ProcessorCount) @@ -59,13 +59,15 @@ function (cotire_determine_compiler_version _language _versionPrefix) # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) - execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} + execute_process ( + COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10) string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}") else() # assume GCC like command line interface string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) - execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion" + execute_process ( + COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion" OUTPUT_VARIABLE ${_versionPrefix}_VERSION RESULT_VARIABLE _result OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10) @@ -255,6 +257,26 @@ function (cotire_copy_set_properites _configurations _type _source _target) endforeach() endfunction() +function (cotire_get_target_link_libraries_for_usage_requirements _target _targetLinkLibrariesVar) + set (_targetLinkLibraries "") + get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) + while (_librariesToProcess) + # remove from head + list (GET _librariesToProcess 0 _library) + list (REMOVE_AT _librariesToProcess 0) + list (FIND _targetLinkLibraries ${_library} _index) + if (_index LESS 0) + list (APPEND _targetLinkLibraries ${_library}) + # process transitive libraries + get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) + if (_libraries) + list (APPEND _librariesToProcess ${_libraries}) + endif() + endif() + endwhile() + set (${_targetLinkLibrariesVar} ${_targetLinkLibraries} PARENT_SCOPE) +endfunction() + function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") set (_flagPrefix "[/-]") @@ -366,6 +388,14 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ if (_targetOptions) set (_compileFlags "${_compileFlags} ${_targetOptions}") endif() + # interface compile options from linked library targets + cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) + foreach (_library ${_linkLibraries}) + get_target_property(_targetOptions ${_library} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + set (_compileFlags "${_compileFlags} ${_targetOptions}") + endif() + endforeach() endif() if (UNIX) separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") @@ -404,8 +434,9 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) endfunction() -function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar) +function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar _systemIncludeDirsVar) set (_includeDirs "") + set (_systemIncludeDirs "") # default include dirs if (CMAKE_INCLUDE_CURRENT_DIR) list (APPEND _includeDirs "${_targetBinaryDir}") @@ -424,8 +455,27 @@ function (cotire_get_target_include_directories _config _language _targetSourceD get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) if (_targetDirs) list (APPEND _dirs ${_targetDirs}) - list (REMOVE_DUPLICATES _dirs) endif() + get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + + # interface include directories from linked library targets + cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) + foreach (_library ${_linkLibraries}) + get_target_property(_targetDirs ${_library} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_library} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endforeach() + endif() + if (dirs) + list (REMOVE_DUPLICATES _dirs) endif() list (LENGTH _includeDirs _projectInsertIndex) foreach (_dir ${_dirs}) @@ -447,6 +497,7 @@ function (cotire_get_target_include_directories _config _language _targetSourceD endif() endforeach() list (REMOVE_DUPLICATES _includeDirs) + list (REMOVE_DUPLICATES _systemIncludeDirs) if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) endif() @@ -454,6 +505,10 @@ function (cotire_get_target_include_directories _config _language _targetSourceD message (STATUS "Target ${_target} include dirs ${_includeDirs}") endif() set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) + if (COTIRE_DEBUG AND _systemIncludeDirs) + message (STATUS "Target ${_target} system include dirs ${_systemIncludeDirs}") + endif() + set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) endfunction() macro (cotire_make_C_identifier _identifierVar _str) @@ -513,6 +568,14 @@ function (cotire_get_target_compile_definitions _config _language _directory _ta if (_definitions) list (APPEND _configDefinitions ${_definitions}) endif() + # interface compile definitions from linked library targets + cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) + foreach (_library ${_linkLibraries}) + get_target_property(_definitions ${_library} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + endforeach() # parse additional compile definitions from target compile flags # and don't look at directory compile definitions, which we already handled set (_targetFlags "") @@ -678,13 +741,18 @@ macro (cotire_add_definitions_to_cmd _cmdVar _language) endforeach() endmacro() -macro (cotire_add_includes_to_cmd _cmdVar _language) - foreach (_include ${ARGN}) +macro (cotire_add_includes_to_cmd _cmdVar _language _includeSystemFlag _includesVar _systemIncludesVar) + foreach (_include ${${_includesVar}}) if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") file (TO_NATIVE_PATH "${_include}" _include) list (APPEND ${_cmdVar} "/I${_include}") else() - list (APPEND ${_cmdVar} "-I${_include}") + list(FIND ${_systemIncludesVar} ${_include} _index) + if(_index GREATER -1 AND NOT "${_includeSystemFlag}" STREQUAL "") + list (APPEND ${_cmdVar} "${_includeSystemFlag} ${_include}") + else() + list (APPEND ${_cmdVar} "-I${_include}") + endif() endif() endforeach() endmacro() @@ -945,8 +1013,8 @@ endfunction() function (cotire_scan_includes _includesVar) set(_options "") - set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION LANGUAGE UNPARSED_LINES) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE UNPARSED_LINES) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) if (NOT _option_LANGUAGE) @@ -959,7 +1027,7 @@ function (cotire_scan_includes _includesVar) cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) # only consider existing source files for scanning @@ -984,7 +1052,8 @@ function (cotire_scan_includes _includesVar) # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) endif() - execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + execute_process( + COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output) if (_result) message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") @@ -1136,13 +1205,15 @@ endfunction() function (cotire_generate_prefix_header _prefixFile) set(_options "") - set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION) + set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG) set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS - INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) if (_option_DEPENDS) cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) if (_prefixFileIsUpToDate) + set (_unparsedLinesFile "${_prefixFile}.log") + file (WRITE "${_unparsedLinesFile}" "") return() endif() endif() @@ -1168,6 +1239,8 @@ function (cotire_generate_prefix_header _prefixFile) COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} COMPILE_FLAGS ${_option_COMPILE_FLAGS} INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} + INCLUDE_SYSTEM_FLAG ${_option_INCLUDE_SYSTEM_FLAG} + SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} IGNORE_PATH ${_option_IGNORE_PATH} INCLUDE_PATH ${_option_INCLUDE_PATH} IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} @@ -1300,18 +1373,19 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio endif() elseif (_compilerID MATCHES "GNU|Clang") # GCC / Clang options used - # -w disable all warnings # -x specify the source language # -c compile but do not link # -o place output in file + # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may + # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) set (_xLanguage_C "c-header") set (_xLanguage_CXX "c++-header") if (_flags) # append to list - list (APPEND _flags "-w" "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") else() # return as a flag string - set (_flags "-w -x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1408,6 +1482,7 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # GCC options used # -include process include file as the first line of the primary source file # -Winvalid-pch warns if precompiled header is found but cannot be used + # note: ccache requires the -include flag to be used in order to process precompiled header correctly if (_flags) # append to list list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") @@ -1420,24 +1495,13 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # -include process include file as the first line of the primary source file # -include-pch include precompiled header file # -Qunused-arguments don't emit warning for unused driver arguments - if (_pchFile AND NOT CMAKE_${_language}_COMPILER MATCHES "ccache") - if (_flags) - # append to list - list (APPEND _flags "-Qunused-arguments" "-include-pch" "${_pchFile}") - else() - # return as a flag string - set (_flags "-Qunused-arguments -include-pch \"${_pchFile}\"") - endif() + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") else() - # no precompiled header, force inclusion of prefix header - # ccache requires the -include flag to be used in order to process precompiled header correctly - if (_flags) - # append to list - list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") - else() - # return as a flag string - set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") - endif() + # return as a flag string + set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1513,8 +1577,8 @@ endfunction() function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) set(_options "") - set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION LANGUAGE) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES) + set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) if (NOT _option_LANGUAGE) set (_option_LANGUAGE "CXX") @@ -1525,7 +1589,7 @@ function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) cotire_add_pch_compilation_flags( "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" @@ -1540,7 +1604,10 @@ function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) endif() - execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result) + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result) if (_result) message (FATAL_ERROR "Error ${_result} precompiling ${_prefixFile}.") endif() @@ -1618,6 +1685,8 @@ macro (cotire_setup_file_extension_variables) set (_unityFileExt_CXX ".cxx") set (_prefixFileExt_C ".h") set (_prefixFileExt_CXX ".hxx") + set (_prefixSourceFileExt_C ".c") + set (_prefixSourceFileExt_CXX ".cxx") endmacro() function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) @@ -1691,6 +1760,16 @@ function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixF set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) endfunction() +function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _prefixSourceFileExt_${_language}) + set (${_prefixSourceFileVar} "" PARENT_SCOPE) + return() + endif() + string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") + set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) +endfunction() + function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) cotire_setup_file_extension_variables() if (NOT _language) @@ -1833,11 +1912,12 @@ function (cotire_generate_target_script _language _configurations _targetSourceD get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES}) cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES}) + set (COTIRE_INCLUDE_SYSTEM_FLAG ${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}) set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") foreach (_config ${_configurations}) string (TOUPPER "${_config}" _upperConfig) cotire_get_target_include_directories( - "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}) + "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) cotire_get_target_compile_definitions( "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) cotire_get_target_compiler_flags( @@ -1895,7 +1975,8 @@ function (cotire_setup_pch_file_compilation _language _target _targetSourceDir _ message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") endif() set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) - add_custom_command(OUTPUT "${_pchFile}" + add_custom_command( + OUTPUT "${_pchFile}" COMMAND ${_cmds} DEPENDS "${_prefixFile}" IMPLICIT_DEPENDS ${_language} "${_prefixFile}" @@ -1996,11 +2077,16 @@ function (cotire_setup_combine_command _language _sourceDir _targetScript _joine endif() set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") - get_filename_component(_joinedFileName "${_joinedFileRelPath}" NAME_WE) - if (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) + get_filename_component(_joinedFileExt "${_joinedFile}" EXT) + if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}") - elseif (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") - set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}") + elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") + if (_joinedFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_joinedFileRelPath}") + else() + set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}") + endif() else() set (_comment "Generating ${_joinedFileRelPath}") endif() @@ -2104,7 +2190,7 @@ function (cotire_setup_unity_generation_commands _language _targetSourceDir _tar set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() -function (cotire_setup_single_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar) +function (cotire_setup_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar) set (_sourceFiles ${ARGN}) set (_dependencySources "") cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) @@ -2115,28 +2201,58 @@ function (cotire_setup_single_prefix_generation_command _language _target _targe message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_targetScript} ${_unityFile} ${_dependencySources}") endif() file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") + get_filename_component(_prefixFileExt "${_prefixFile}" EXT) + if (_prefixFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_prefixFileRelPath}") + else() + set (_comment "Generating ${_language} prefix header ${_prefixFileRelPath}") + endif() add_custom_command( OUTPUT "${_prefixFile}" "${_prefixFile}.log" COMMAND ${_prefixCmd} DEPENDS "${_targetScript}" "${_unityFile}" ${_dependencySources} - COMMENT "Generating ${_language} prefix header ${_prefixFileRelPath}" + COMMENT "${_comment}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() -function (cotire_setup_multi_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar) +function (cotire_setup_prefix_generation_from_unity_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar) set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() list (LENGTH _unityFiles _numberOfUnityFiles) if (_numberOfUnityFiles GREATER 1) cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) - cotire_setup_single_prefix_generation_command( + cotire_setup_prefix_generation_command( ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" - "${_prefixFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles}) + "${_prefixSourceFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles}) else() - cotire_setup_single_prefix_generation_command( + cotire_setup_prefix_generation_command( ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" - "${_prefixFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) + "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) + endif() + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" ${_cmdsVar} ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_provided_command _language _target _targetSourceDir _targetScript _prefixFile _cmdsVar) + set (_prefixHeaderFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) endif() set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() @@ -2381,9 +2497,10 @@ function (cotire_process_target_language _language _configurations _targetSource # check for user provided prefix header files get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) if (_prefixHeaderFiles) - cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + cotire_setup_prefix_generation_from_provided_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) else() - cotire_setup_multi_prefix_generation_command( + cotire_setup_prefix_generation_from_unity_command( ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles}) endif() get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) @@ -2699,7 +2816,7 @@ function (cotire_target _target) endif() endfunction(cotire_target) -function(cotire_target_link_libraries _target) +function (cotire_target_link_libraries _target) get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) if (TARGET "${_unityTargetName}") get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) @@ -2865,6 +2982,7 @@ if (CMAKE_SCRIPT_MODE_FILE) endif() string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}}) set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) # check if target has been cotired for actual build type COTIRE_BUILD_TYPE @@ -2917,7 +3035,9 @@ if (CMAKE_SCRIPT_MODE_FILE) IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" + INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}" INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} COMPILE_DEFINITIONS ${_compileDefinitions} COMPILE_FLAGS ${_compileFlags}) @@ -2937,7 +3057,9 @@ if (CMAKE_SCRIPT_MODE_FILE) COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}" INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} COMPILE_DEFINITIONS ${_compileDefinitions} COMPILE_FLAGS ${_compileFlags}) From 8c05fcd7a564888a485419d7e2fafa5e9f87e5c8 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Tue, 15 Jul 2014 15:39:53 +0100 Subject: [PATCH 074/157] Upgrade cotire to 1.6.4 to fix warnings when building on Ubuntu. --- cmake/cotire.cmake | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/cmake/cotire.cmake b/cmake/cotire.cmake index 990f2778..e72758cc 100644 --- a/cmake/cotire.cmake +++ b/cmake/cotire.cmake @@ -45,7 +45,7 @@ if (NOT CMAKE_SCRIPT_MODE_FILE) endif() set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.6.3") +set (COTIRE_CMAKE_MODULE_VERSION "1.6.4") include(CMakeParseArguments) include(ProcessorCount) @@ -268,9 +268,11 @@ function (cotire_get_target_link_libraries_for_usage_requirements _target _targe if (_index LESS 0) list (APPEND _targetLinkLibraries ${_library}) # process transitive libraries - get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) - if (_libraries) - list (APPEND _librariesToProcess ${_libraries}) + if (TARGET ${_library}) + get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) + if (_libraries) + list (APPEND _librariesToProcess ${_libraries}) + endif() endif() endif() endwhile() @@ -391,9 +393,11 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ # interface compile options from linked library targets cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) foreach (_library ${_linkLibraries}) - get_target_property(_targetOptions ${_library} INTERFACE_COMPILE_OPTIONS) - if (_targetOptions) - set (_compileFlags "${_compileFlags} ${_targetOptions}") + if (TARGET ${_library}) + get_target_property(_targetOptions ${_library} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + set (_compileFlags "${_compileFlags} ${_targetOptions}") + endif() endif() endforeach() endif() @@ -464,13 +468,15 @@ function (cotire_get_target_include_directories _config _language _targetSourceD # interface include directories from linked library targets cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) foreach (_library ${_linkLibraries}) - get_target_property(_targetDirs ${_library} INTERFACE_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - get_target_property(_targetDirs ${_library} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _systemIncludeDirs ${_targetDirs}) + if (TARGET ${_library}) + get_target_property(_targetDirs ${_library} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_library} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() endif() endforeach() endif() @@ -519,7 +525,7 @@ macro (cotire_make_C_identifier _identifierVar _str) endif() string (REGEX REPLACE "[^a-zA-Z0-9]" "_" ${_identifierVar} "${_str}") else() - string (MAKE_C_IDENTIFIER "${_identifierVar}" "${_str}") + string (MAKE_C_IDENTIFIER "${_str}" "${_identifierVar}") endif() endmacro() @@ -571,9 +577,11 @@ function (cotire_get_target_compile_definitions _config _language _directory _ta # interface compile definitions from linked library targets cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) foreach (_library ${_linkLibraries}) - get_target_property(_definitions ${_library} INTERFACE_COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) + if (TARGET ${_library}) + get_target_property(_definitions ${_library} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() endif() endforeach() # parse additional compile definitions from target compile flags From cd9a313ff306ff6471ad9314c306b3c4baf22f6e Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Tue, 16 Sep 2014 11:13:23 +0200 Subject: [PATCH 075/157] fix some warnings on mingw --- CMakeLists.txt | 2 +- src/core/include/LuceneInc.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96183e38..8ea0320e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,7 @@ if(WIN32 OR WIN64) set(CMAKE_DEBUG_POSTFIX "d") endif() -if(NOT MSVC AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") +if(NOT WIN32 AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") add_definitions(-fPIC) endif() diff --git a/src/core/include/LuceneInc.h b/src/core/include/LuceneInc.h index 1fbee3a2..a0999194 100644 --- a/src/core/include/LuceneInc.h +++ b/src/core/include/LuceneInc.h @@ -9,7 +9,9 @@ #include "targetver.h" #define WIN32_LEAN_AND_MEAN +#ifndef NOMINMAX #define NOMINMAX +#endif #include From 91905585a015a881bb6527ac43dee13a5a8d8e14 Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Tue, 16 Sep 2014 11:16:53 +0200 Subject: [PATCH 076/157] fixed build on mingw, the automatic linking of the boost dependencies using #pragma comment(lib, "ws2_32") doesn't work with mingw --- src/core/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7d6153d1..13ff0a60 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -34,6 +34,10 @@ target_link_libraries(lucene++ ${lucene_boost_libs} ) +if(WIN32) + target_link_libraries(lucene++ ws2_32) +endif() + set_target_properties(lucene++ PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "include/LuceneInc.h") cotire(lucene++) From de2318120e24719f89a1db467f04fc76208b3f0e Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Tue, 16 Sep 2014 11:33:39 +0200 Subject: [PATCH 077/157] make test optional --- CMakeLists.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96183e38..01f6e171 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,10 @@ option(ENABLE_CYCLIC_CHECK "Enable cyclic checking" OFF ) +option(ENABLE_TEST + "Enable the tests" + ON +) #################################### # bootstrap @@ -113,12 +117,15 @@ include_directories( "${CMAKE_CURRENT_BINARY_DIR}/include" ) -enable_testing() add_subdirectory(src/core) add_subdirectory(src/contrib) add_subdirectory(src/demo) -add_subdirectory(src/test) + +if(ENABLE_TEST) + enable_testing() + add_subdirectory(src/test) +endif() ################################# # install pkg-config file From b295c2f8ee4cb1ad6c91653f8f78906d71c9e1df Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Fri, 10 Oct 2014 18:48:53 +0200 Subject: [PATCH 078/157] Fix build failure with debian kfreebsd and hurd This should avoid the "../core/liblucene++.so.3.0.6: undefined reference to `Lucene::Constants::OS_NAME'" error, and fix issue #75 --- src/core/util/Constants.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/util/Constants.cpp b/src/core/util/Constants.cpp index 81724b9c..fd74c53b 100644 --- a/src/core/util/Constants.cpp +++ b/src/core/util/Constants.cpp @@ -17,8 +17,12 @@ String Constants::OS_NAME = L"Sun"; String Constants::OS_NAME = L"Windows"; #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) String Constants::OS_NAME = L"Mac"; -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) String Constants::OS_NAME = L"BSD"; +#elif defined(__GNU__) +String Constants::OS_NAME = L"HURD"; +#else +String Constants::OS_NAME = L"UNKNOWN"; #endif String Constants::LUCENE_MAIN_VERSION = L"3.0.6"; From c80d05a9ece6685b09b0ca865867a79a412acabc Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 7 Nov 2014 23:52:39 +0000 Subject: [PATCH 079/157] Fix cmake gtest. --- src/test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index aad8f1c1..7ce02fca 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -40,7 +40,7 @@ add_executable(lucene++-tester ) add_dependencies(lucene++-tester - googletest + gtest ) target_link_libraries(lucene++-tester From a564d107c7d50a8ad9726508cfe12a55f326132f Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sat, 8 Nov 2014 00:13:27 +0000 Subject: [PATCH 080/157] Make building demo applications optional. --- CMakeLists.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 768b208e..a56c5ffd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,10 @@ option(ENABLE_TEST "Enable the tests" ON ) +option(ENABLE_DEMO + "Enable building demo applications" + ON +) #################################### # bootstrap @@ -105,6 +109,18 @@ if(CYGWIN) add_definitions(-D__LARGE64_FILES) endif() +if(APPLE) + set(CMAKE_MACOSX_RPATH ON) + set(CMAKE_SKIP_BUILD_RPATH FALSE) + set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) + if("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + endif() +endif() + ################################# # generate Config.h ################################# @@ -120,7 +136,10 @@ include_directories( add_subdirectory(src/core) add_subdirectory(src/contrib) -add_subdirectory(src/demo) + +if(ENABLE_DEMO) + add_subdirectory(src/demo) +endif() if(ENABLE_TEST) enable_testing() From 1d5b6a4ea5d340617b56e3f1a9967b29e80856c7 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sat, 8 Nov 2014 00:14:00 +0000 Subject: [PATCH 081/157] Update cotire to 1.6.6. --- cmake/cotire.cmake | 141 +++++++++++++++++++++++++++------------------ 1 file changed, 85 insertions(+), 56 deletions(-) diff --git a/cmake/cotire.cmake b/cmake/cotire.cmake index e72758cc..d855c1d4 100644 --- a/cmake/cotire.cmake +++ b/cmake/cotire.cmake @@ -45,7 +45,7 @@ if (NOT CMAKE_SCRIPT_MODE_FILE) endif() set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.6.4") +set (COTIRE_CMAKE_MODULE_VERSION "1.6.6") include(CMakeParseArguments) include(ProcessorCount) @@ -414,9 +414,11 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ if (NOT _architectures) get_target_property(_architectures ${_target} OSX_ARCHITECTURES) endif() - foreach (_arch ${_architectures}) - list (APPEND _compileFlags "-arch" "${_arch}") - endforeach() + if (_architectures) + foreach (_arch ${_architectures}) + list (APPEND _compileFlags "-arch" "${_arch}") + endforeach() + endif() if (CMAKE_OSX_SYSROOT) if (CMAKE_${_language}_SYSROOT_FLAG) list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") @@ -755,9 +757,9 @@ macro (cotire_add_includes_to_cmd _cmdVar _language _includeSystemFlag _includes file (TO_NATIVE_PATH "${_include}" _include) list (APPEND ${_cmdVar} "/I${_include}") else() - list(FIND ${_systemIncludesVar} ${_include} _index) + list (FIND ${_systemIncludesVar} ${_include} _index) if(_index GREATER -1 AND NOT "${_includeSystemFlag}" STREQUAL "") - list (APPEND ${_cmdVar} "${_includeSystemFlag} ${_include}") + list (APPEND ${_cmdVar} "${_includeSystemFlag}${_include}") else() list (APPEND ${_cmdVar} "-I${_include}") endif() @@ -1351,7 +1353,7 @@ function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flags endif() endif() else() - message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") endif() set (${_flagsVar} ${_flags} PARENT_SCOPE) endfunction() @@ -1454,7 +1456,7 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio endif() endif() else() - message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") endif() set (${_flagsVar} ${_flags} PARENT_SCOPE) endfunction() @@ -1578,7 +1580,7 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV endif() endif() else() - message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") endif() set (${_flagsVar} ${_flags} PARENT_SCOPE) endfunction() @@ -1617,7 +1619,7 @@ function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result) if (_result) - message (FATAL_ERROR "Error ${_result} precompiling ${_prefixFile}.") + message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.") endif() endfunction() @@ -1888,8 +1890,8 @@ function (cotire_get_prefix_header_dependencies _language _target _dependencySou # depend on target source files marked with custom COTIRE_DEPENDENCY property set (_dependencySources "") cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") - # Clang raises a fatal error if a file is not found during preprocessing + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GCC and clang raise a fatal error if a file is not found during preprocessing # thus we depend on target's generated source files for prefix header generation cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN}) if (_generatedSources) @@ -1902,10 +1904,8 @@ function (cotire_get_prefix_header_dependencies _language _target _dependencySou set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) endfunction() -function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar) +function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar _targetConfigScriptVar) set (COTIRE_TARGET_SOURCES ${ARGN}) - get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) - set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${COTIRE_TARGET_SOURCES}) cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${COTIRE_TARGET_SOURCES}) # set up variables to be configured @@ -1920,7 +1920,7 @@ function (cotire_generate_target_script _language _configurations _targetSourceD get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES}) cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES}) - set (COTIRE_INCLUDE_SYSTEM_FLAG ${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" COTIRE_INCLUDE_SYSTEM_FLAG) set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") foreach (_config ${_configurations}) string (TOUPPER "${_config}" _upperConfig) @@ -1938,6 +1938,7 @@ function (cotire_generate_target_script _language _configurations _targetSourceD # remove COTIRE_VERBOSE which is passed as a CMake define on command line list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) set (_contents "") + set (_contentsHasGeneratorExpressions FALSE) foreach (_var IN LISTS _matchVars ITEMS MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 @@ -1945,10 +1946,32 @@ function (cotire_generate_target_script _language _configurations _targetSourceD if (DEFINED ${_var}) string (REPLACE "\"" "\\\"" _value "${${_var}}") set (_contents "${_contents}set (${_var} \"${_value}\")\n") + if (NOT _contentsHasGeneratorExpressions) + if ("${_value}" MATCHES "\\$<.*>") + set (_contentsHasGeneratorExpressions TRUE) + endif() + endif() endif() endforeach() + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) + if (_contentsHasGeneratorExpressions) + # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time + if (NOT CMAKE_VERSION VERSION_LESS "2.8.12") + # the file(GENERATE ...) command requires cmake 2.8.12 or later + set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") + set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") + file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") + else() + message (WARNING "cotire: generator expression used in target ${_target}. This requires CMake 2.8.12 or later.") + set (_targetCotireConfigScript "${_targetCotireScript}") + endif() + else() + set (_targetCotireConfigScript "${_targetCotireScript}") + endif() set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) + set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) endfunction() function (cotire_setup_pch_file_compilation _language _target _targetSourceDir _targetScript _prefixFile _pchFile) @@ -2158,7 +2181,7 @@ function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _who endif() endfunction() -function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _unityFiles _cmdsVar) +function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _targetConfigScript _unityFiles _cmdsVar) set (_dependencySources "") cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) foreach (_unityFile ${_unityFiles}) @@ -2177,7 +2200,7 @@ function (cotire_setup_unity_generation_commands _language _targetSourceDir _tar set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") endif() cotire_set_cmd_to_prologue(_unityCmd) - list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetScript}" "${_unityFile}") + list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") if (COTIRE_DEBUG) message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_targetScript}") endif() @@ -2193,7 +2216,7 @@ function (cotire_setup_unity_generation_commands _language _targetSourceDir _tar if (_numberOfUnityFiles GREATER 1) # create a joint unity file from all unity file segments cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) - cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles}) + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetConfigScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles}) endif() set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() @@ -2206,7 +2229,7 @@ function (cotire_setup_prefix_generation_command _language _target _targetSource list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" "${_unityFile}") set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_targetScript} ${_unityFile} ${_dependencySources}") + message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources}") endif() file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") get_filename_component(_prefixFileExt "${_prefixFile}" EXT) @@ -2218,7 +2241,7 @@ function (cotire_setup_prefix_generation_command _language _target _targetSource add_custom_command( OUTPUT "${_prefixFile}" "${_prefixFile}.log" COMMAND ${_prefixCmd} - DEPENDS "${_targetScript}" "${_unityFile}" ${_dependencySources} + DEPENDS "${_unityFile}" ${_dependencySources} COMMENT "${_comment}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) @@ -2375,7 +2398,7 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) if (_prefixHeader OR _unityBuildFile) - message (STATUS "Target ${_target} has already been cotired.") + message (STATUS "cotire: target ${_target} has already been cotired.") set (${_targetLanguagesVar} "" PARENT_SCOPE) return() endif() @@ -2492,31 +2515,31 @@ function (cotire_process_target_language _language _configurations _targetSource set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) endif() cotire_generate_target_script( - ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript ${_unitySourceFiles}) + ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) if (NOT _unityFiles) return() endif() cotire_setup_unity_generation_commands( - ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) if (_prefixFile) # check for user provided prefix header files get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) if (_prefixHeaderFiles) cotire_setup_prefix_generation_from_provided_command( - ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) else() cotire_setup_prefix_generation_from_unity_command( - ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles}) endif() get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) if (_targetUsePCH) cotire_make_pch_file_path(${_language} "${_targetSourceDir}" ${_target} _pchFile) if (_pchFile) cotire_setup_pch_file_compilation( - ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) if (_excludedSources) set (_wholeTarget FALSE) endif() @@ -2592,7 +2615,7 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") set (_unityTargetSubType "${CMAKE_MATCH_1}") else() - message (WARNING "Unknown target type ${_targetType}.") + message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") return() endif() # determine unity target sources @@ -2689,9 +2712,10 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN) # copy interface stuff cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_STRING + COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN COMPATIBLE_INTERFACE_STRING INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_OPTIONS INTERFACE_INCLUDE_DIRECTORIES - INTERFACE_LINK_LIBRARIES INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + INTERFACE_AUTOUIC_OPTIONS) # copy link stuff cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH @@ -2704,7 +2728,8 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour NO_SONAME SOVERSION VERSION) # copy Qt stuff cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - AUTOMOC AUTOMOC_MOC_OPTIONS) + AUTOMOC AUTOMOC_MOC_OPTIONS AUTOUIC AUTOUIC_OPTIONS AUTORCC AUTORCC_OPTIONS + AUTOGEN_TARGET_DEPENDS) # copy cmake stuff cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) @@ -2763,7 +2788,7 @@ function (cotire_target _target) # trivial checks get_target_property(_imported ${_target} IMPORTED) if (_imported) - message (WARNING "Imported target ${_target} cannot be cotired.") + message (WARNING "cotire: imported target ${_target} cannot be cotired.") return() endif() # resolve alias @@ -2824,6 +2849,24 @@ function (cotire_target _target) endif() endfunction(cotire_target) +function (cotire_map_libraries _strategy _mappedLibrariesVar) + set (_mappedLibraries "") + foreach (_library ${ARGN}) + if (TARGET "${_library}" AND "${_strategy}" MATCHES "COPY_UNITY") + get_target_property(_libraryUnityTargetName ${_library} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_libraryUnityTargetName}") + list (APPEND _mappedLibraries "${_libraryUnityTargetName}") + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + endforeach() + list (REMOVE_DUPLICATES _mappedLibraries) + set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE) +endfunction() + function (cotire_target_link_libraries _target) get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) if (TARGET "${_unityTargetName}") @@ -2833,30 +2876,16 @@ function (cotire_target_link_libraries _target) endif() if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") if (CMAKE_VERSION VERSION_LESS "2.8.11") - message (WARNING "Unity target link strategy ${_linkLibrariesStrategy} requires CMake 2.8.11 or later. Defaulting to NONE for ${_target}.") - return() - endif() - get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) - if (_linkLibraries) + message (WARNING "cotire: unity target link strategy ${_linkLibrariesStrategy} requires CMake 2.8.11 or later. Defaulting to NONE for ${_target}.") + else() + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries} ${_interfaceLinkLibraries}) if (COTIRE_DEBUG) - message (STATUS "target ${_target} link libraries: ${_linkLibraries}") + message (STATUS "unity target ${_unityTargetName} libraries: ${_unityLinkLibraries}") endif() - set (_unityTargetLibraries "") - foreach (_library ${_linkLibraries}) - if (TARGET "${_library}" AND "${_linkLibrariesStrategy}" MATCHES "COPY_UNITY") - get_target_property(_libraryUnityTargetName ${_library} COTIRE_UNITY_TARGET_NAME) - if (TARGET "${_libraryUnityTargetName}") - list (APPEND _unityTargetLibraries "${_libraryUnityTargetName}") - else() - list (APPEND _unityTargetLibraries "${_library}") - endif() - else() - list (APPEND _unityTargetLibraries "${_library}") - endif() - endforeach() - set_property(TARGET ${_unityTargetName} APPEND PROPERTY LINK_LIBRARIES ${_unityTargetLibraries}) - if (COTIRE_DEBUG) - message (STATUS "set unity target ${_unityTargetName} link libraries: ${_unityTargetLibraries}") + if (_unityLinkLibraries) + target_link_libraries(${_unityTargetName} ${_unityLinkLibraries}) endif() endif() endif() @@ -2943,7 +2972,7 @@ function (cotire) cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS} SOURCE_DIR "${_option_SOURCE_DIR}" BINARY_DIR "${_option_BINARY_DIR}") else() - message (WARNING "${_target} is not a target.") + message (WARNING "cotire: ${_target} is not a target.") endif() endforeach() foreach (_target ${_targets}) @@ -3095,7 +3124,7 @@ if (CMAKE_SCRIPT_MODE_FILE) cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") else() - message (FATAL_ERROR "Unknown cotire command \"${COTIRE_ARGV1}\".") + message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".") endif() else() From b89c5a990cb1982cdabd596f26d27ad4c8626f95 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Sat, 8 Nov 2014 00:26:33 +0000 Subject: [PATCH 082/157] Attempt to fix compile cstdint.hpp errors. --- include/Lucene.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/Lucene.h b/include/Lucene.h index c377f154..9427bffb 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -24,14 +24,25 @@ #include #include +#ifndef int8_t using boost::int8_t; using boost::uint8_t; +#endif + +#ifndef int16_t using boost::int16_t; using boost::uint16_t; +#endif + +#ifndef int32_t using boost::int32_t; using boost::uint32_t; +#endif + +#ifndef int64_t using boost::int64_t; using boost::uint64_t; +#endif #define SIZEOF_ARRAY(arr) (sizeof(arr) / sizeof((arr)[0])) From ab7b4e384033db5169b8461c98f6887bbae8eaa6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 28 Oct 2014 18:32:06 +0100 Subject: [PATCH 083/157] Don't throw exceptions in file operations just to ignore them. Use overloads of boost::filesystem functions taking a boost::system::error_code to avoid throwing exceptions which are simply immediately ignored. While this is also more efficient, the main rationale for this change is to avoid dozens if not hundreds of exceptions which can be thrown when updating the cached index and spam the debugger console. There should be no changes in behaviour. --- src/core/util/FileUtils.cpp | 161 +++++++++++++----------------------- 1 file changed, 59 insertions(+), 102 deletions(-) diff --git a/src/core/util/FileUtils.cpp b/src/core/util/FileUtils.cpp index d624efaf..51508b57 100644 --- a/src/core/util/FileUtils.cpp +++ b/src/core/util/FileUtils.cpp @@ -25,159 +25,116 @@ namespace Lucene { namespace FileUtils { bool fileExists(const String& path) { - try { - return boost::filesystem::exists(path.c_str()); - } catch (...) { - return false; - } + boost::system::error_code ec; + return boost::filesystem::exists(path.c_str(), ec); } uint64_t fileModified(const String& path) { - try { - return (uint64_t)boost::filesystem::last_write_time(path.c_str()); - } catch (...) { - return 0; - } + boost::system::error_code ec; + uint64_t t = (uint64_t)boost::filesystem::last_write_time(path.c_str(), ec); + return ec ? 0 : t; } bool touchFile(const String& path) { - try { - boost::filesystem::last_write_time(path.c_str(), time(NULL)); - return true; - } catch (...) { - return false; - } + boost::system::error_code ec; + boost::filesystem::last_write_time(path.c_str(), time(NULL), ec); + return !ec; } int64_t fileLength(const String& path) { - try { - int64_t fileSize = (int64_t)boost::filesystem::file_size(path.c_str()); - for (int32_t i = 0; fileSize == 0 && i < 100; ++i) { - LuceneThread::threadYield(); - fileSize = (int64_t)boost::filesystem::file_size(path.c_str()); - } - return fileSize; - } catch (...) { - return 0; + boost::system::error_code ec; + int64_t fileSize = (int64_t)boost::filesystem::file_size(path.c_str(), ec); + for (int32_t i = 0; !ec && fileSize == 0 && i < 100; ++i) { + LuceneThread::threadYield(); + fileSize = (int64_t)boost::filesystem::file_size(path.c_str(), ec); } + + return ec ? 0 : fileSize; } bool setFileLength(const String& path, int64_t length) { - try { - if (!fileExists(path)) { - return false; - } + if (!fileExists(path)) { + return false; + } #if defined(_WIN32) || defined(_WIN64) - int32_t fd = _wopen(path.c_str(), _O_WRONLY | _O_CREAT | _O_BINARY, _S_IWRITE); - return _chsize(fd, (long)length) == 0; + int32_t fd = _wopen(path.c_str(), _O_WRONLY | _O_CREAT | _O_BINARY, _S_IWRITE); + return _chsize(fd, (long)length) == 0; #else - return truncate(boost::filesystem::path(path).c_str(), (off_t)length) == 0; + return truncate(boost::filesystem::path(path).c_str(), (off_t)length) == 0; #endif - } catch (...) { - return false; - } } bool removeFile(const String& path) { - try { - return boost::filesystem::remove(path.c_str()); - } catch (...) { - return false; - } + boost::system::error_code ec; + return boost::filesystem::remove(path.c_str(), ec); } bool copyFile(const String& source, const String& dest) { - try { - boost::filesystem::copy_file(source.c_str(), dest.c_str()); - return true; - } catch (...) { - return false; - } + boost::system::error_code ec; + boost::filesystem::copy_file(source.c_str(), dest.c_str(), ec); + return !ec; } bool createDirectory(const String& path) { - try { - return boost::filesystem::create_directory(path.c_str()); - } catch (...) { - return false; - } + boost::system::error_code ec; + return boost::filesystem::create_directory(path.c_str(), ec) && !ec; } bool removeDirectory(const String& path) { - try { - boost::filesystem::remove_all(path.c_str()); - return true; - } catch (...) { - return false; - } + boost::system::error_code ec; + boost::filesystem::remove_all(path.c_str(), ec); + return !ec; } bool isDirectory(const String& path) { - try { - return boost::filesystem::is_directory(path.c_str()); - } catch (...) { - return false; - } + boost::system::error_code ec; + return boost::filesystem::is_directory(path.c_str(), ec); } bool listDirectory(const String& path, bool filesOnly, HashSet dirList) { - try { - for (boost::filesystem::directory_iterator dir(path.c_str()); dir != boost::filesystem::directory_iterator(); ++dir) { - if (!filesOnly || !boost::filesystem::is_directory(dir->status())) { - dirList.add(dir->path().filename().wstring().c_str()); - } - } - return true; - } catch (...) { + boost::system::error_code ec; + boost::filesystem::directory_iterator dir(path.c_str(), ec); + if (ec) { return false; } -} -bool copyDirectory(const String& source, const String& dest) { - try { - HashSet dirList(HashSet::newInstance()); - if (!listDirectory(source, true, dirList)) { - return false; + for (; dir != boost::filesystem::directory_iterator(); ++dir) { + if (!filesOnly || !boost::filesystem::is_directory(dir->status())) { + dirList.add(dir->path().filename().wstring().c_str()); } + } + return true; +} - createDirectory(dest); +bool copyDirectory(const String& source, const String& dest) { + HashSet dirList(HashSet::newInstance()); + if (!listDirectory(source, true, dirList)) { + return false; + } - for (HashSet::iterator file = dirList.begin(); file != dirList.end(); ++file) { - copyFile(joinPath(source, *file), joinPath(dest, *file)); - } + createDirectory(dest); - return true; - } catch (...) { - return false; + for (HashSet::iterator file = dirList.begin(); file != dirList.end(); ++file) { + copyFile(joinPath(source, *file), joinPath(dest, *file)); } + + return true; } String joinPath(const String& path, const String& file) { - try { - boost::filesystem::path join(path.c_str()); - join /= file.c_str(); - return join.wstring().c_str(); - } catch (...) { - return path; - } + boost::filesystem::path join(path.c_str()); + join /= file.c_str(); + return join.wstring().c_str(); } String extractPath(const String& path) { - try { - boost::filesystem::wpath parentPath(path.c_str()); - return parentPath.parent_path().wstring().c_str(); - } catch (...) { - return path; - } + boost::filesystem::wpath parentPath(path.c_str()); + return parentPath.parent_path().wstring().c_str(); } String extractFile(const String& path) { - try { - boost::filesystem::wpath fileName(path.c_str()); - return fileName.filename().wstring().c_str(); - } catch (...) { - return path; - } + boost::filesystem::wpath fileName(path.c_str()); + return fileName.filename().wstring().c_str(); } } From 74ef19235a2359497c043d200cc4826fa1a46a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Thu, 20 Nov 2014 14:12:24 +0100 Subject: [PATCH 084/157] Fix crash in StandardTokenizer if wchar_t is 32bit StandardTokenizerImpl::getNextToken() uses a map to classify characters; the map is 16bit, because this code was ported from Java and Java's strings use UTF-16. But Lucene++ uses wchar_t, which may be 32bit on some platforms (Unix, OS X), resulting in crashes when encountering characters above U+FFFF. Fix the crash by classifying anything outside of BMP as a character. This is hardly ideal, but it prevents the crash and gets the job done reasonably well (as StandardTokenizer is intended for European languages in the first place). A proper fix would rework the map to correspond to UTF-32 rather than UTF-16, or would port Unicode tokenizer from Lucene 3.1+. Fixes #57. --- .../analysis/standard/StandardTokenizerImpl.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index 8384d966..78930f64 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -420,6 +420,18 @@ int32_t StandardTokenizerImpl::getNextToken() { wchar_t* zzBufferL = zzBuffer.get(); const wchar_t* zzCMapL = ZZ_CMAP(); + // This code was originally written in Java, which uses UTF-16, and it can't + // correctly deal with 32bit wchar_t and characters outside of the Basic + // Multilingual Plane. As a workaround to prevent crashes, treat all + // characters above U+FFFF as letters in the tokenizer. + // See https://github.com/luceneplusplus/LucenePlusPlus/issues/57 +#ifdef LPP_UNICODE_CHAR_SIZE_4 + const wchar_t zzCMapFallback = zzCMapL['A']; + #define zzCMap_at(n) ((n) > 0xFFFF ? zzCMapFallback : zzCMapL[n]) +#else + #define zzCMap_at(n) (zzCMapL[n]) +#endif + const int32_t* zzTransL = ZZ_TRANS(); const int32_t* zzRowMapL = ZZ_ROWMAP(); const int32_t* zzAttrL = ZZ_ATTRIBUTE(); @@ -458,7 +470,7 @@ int32_t StandardTokenizerImpl::getNextToken() { } } - int32_t zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; + int32_t zzNext = zzTransL[zzRowMapL[zzState] + zzCMap_at(zzInput)]; if (zzNext == -1) { break; } From e096d4db9ef3ef84c6c0828314143fcb95ce9eb2 Mon Sep 17 00:00:00 2001 From: Zachary Sims Date: Tue, 13 Jan 2015 17:05:31 +1100 Subject: [PATCH 085/157] Disables boost auto linking when using the MSVC generator --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a56c5ffd..dde9d71d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,12 @@ option(ENABLE_DEMO #################################### find_package(Threads REQUIRED) + +if(MSVC) + # Disable automatic boost linking on Windows as libraries are added to the linker explicitly + add_definitions("/DBOOST_ALL_NO_LIB") +endif() + find_package(Boost COMPONENTS date_time filesystem From e516210384d8b80df9a6f308d937f4d5aabaf640 Mon Sep 17 00:00:00 2001 From: Zachary Sims Date: Tue, 13 Jan 2015 18:16:41 +1100 Subject: [PATCH 086/157] Updated style per rest of CMakeLists.txt --- CMakeLists.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dde9d71d..bebcbfb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,12 +58,6 @@ option(ENABLE_DEMO #################################### find_package(Threads REQUIRED) - -if(MSVC) - # Disable automatic boost linking on Windows as libraries are added to the linker explicitly - add_definitions("/DBOOST_ALL_NO_LIB") -endif() - find_package(Boost COMPONENTS date_time filesystem @@ -107,6 +101,11 @@ if(WIN32 OR WIN64) set(CMAKE_DEBUG_POSTFIX "d") endif() +if(MSVC) + # Disable automatic boost linking on Windows as libraries are added to the linker explicitly + add_definitions(-DBOOST_ALL_NO_LIB) +endif() + if(NOT WIN32 AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") add_definitions(-fPIC) endif() From dd56e9ddc216fe88c9dc024b7c484f8eeaf6f4d4 Mon Sep 17 00:00:00 2001 From: Zachary Sims Date: Tue, 13 Jan 2015 20:14:21 +1100 Subject: [PATCH 087/157] Enables C++ exceptions when generating VS projects --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bebcbfb7..78731de6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,9 @@ endif() if(MSVC) # Disable automatic boost linking on Windows as libraries are added to the linker explicitly add_definitions(-DBOOST_ALL_NO_LIB) + + # enable exceptions, see http://msdn.microsoft.com/en-us/library/1deeycx5.aspx + add_definitions(-EHsc) endif() if(NOT WIN32 AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") From b09f21934818a72fc3e3e5300456f565ec187439 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 30 Jan 2015 15:51:35 +0000 Subject: [PATCH 088/157] Added licensing clarification for glib code. closes #69 --- COPYING | 82 ++++++++++++++++++++++++++ src/core/util/unicode/gunichartables.h | 2 + src/core/util/unicode/guniprop.cpp | 2 + src/core/util/unicode/guniprop.h | 2 + 4 files changed, 88 insertions(+) diff --git a/COPYING b/COPYING index b2e8e49f..cb871c4a 100644 --- a/COPYING +++ b/COPYING @@ -14,3 +14,85 @@ Apache 2.0: you may not use this file except in compliance with the License. See the file APACHE.licence + + +Notes regarding licensing glib code. +==================================== + +Files: src/core/util/unicode/* + +Some portions of glib code have been used in Lucene++, a project +spawned from CLucene, with special permission from the author(s). +This is the email exchange that took place in 2006 between +Ben van Klinken, Owen Taylor and Tom Tromey: + +---------- Forwarded message ---------- +From: Owen Taylor +Date: 11 February 2006 04:48 +Subject: Re: Fwd: glib licensing +To: Ben van Klinken +Cc: tromey@redhat.com + + +On Fri, 2006-02-10 at 18:34 +0100, Ben van Klinken wrote: +> +> Hi Owen, +> +> I am the author and maintainer of CLucene (clucene.sourceforge.net). I +> was forwarded to you by Matthias Classen. We have an enquiry about +> licensing of glib: +> +> CLucene was licensed LGPL, but recently we changed our license to +> allow licensing under apache or LGPL. During the audit of the change, +> we made a mistake with some of the code (code in the +> gunichartables.cpp - various utf8<>wchar conversion functions) to be +> licensed apache, since some of the functions are from the glib +> library. The file in question contains various functions from the +> http://cvs.gnome.org/viewcvs/glib/glib/ directory. +> +> We are working on fixing this and are exploring several options. When +> discussing the issue on our mailing list, one suggestion was to +> enquire with you what the chances of re-licensing some of the glib +> unicode functions under +> the apache license would be? I believe you were the author of glib +> unicode support? + +I'd have to know more specifically what particular portions of +the GLib code are involved; can you be more specific about +particular functions and code portions? while I did much of the work, +there have been additions made later on by other people, and a good +portion of the code derives originally from libunicode by +Tom Tromey. (Cc'ed) + +For the portions that are actually my code I don't have any +objection to them also being licensed under the Apache license ... +it's pretty much straightforward implementations of algorithms from +the Unicode standard, and other implementations are widely available in +many forms. + +Regards, +Owen + +---------- Forwarded message ---------- +From: Tom Tromey +Date: 25 April 2006 02:42 +Subject: Re: Fwd: glib licensing +To: Ben van Klinken +Cc: Owen Taylor + +Ben> All the code has Tom Tromey's name at the top. Please let me know if +Ben> you need any other information. + +I was wondering ... if other people made substantial contributions +after this code was written, wouldn't they also be copyright holders? +You'd have to use the cvs history to see this. + +Ben> I don't think we need to do anything other for you to agree with this +Ben> licensing in this email correspondence. So unless you can shed any +Ben> more light on this process and if you agree to this licensing, i will +Ben> append the apache license to the top of our files with a note that it +Ben> has been licensed with your approval. + +It is fine by me. + +Tom diff --git a/src/core/util/unicode/gunichartables.h b/src/core/util/unicode/gunichartables.h index cc5d00f9..4b376d6f 100644 --- a/src/core/util/unicode/gunichartables.h +++ b/src/core/util/unicode/gunichartables.h @@ -1,6 +1,8 @@ /* This file is automatically generated. DO NOT EDIT! Instead, edit gen-unicode-tables.pl and re-run. */ +// See COPYING file for licensing information. + #ifndef CHARTABLES_H #define CHARTABLES_H diff --git a/src/core/util/unicode/guniprop.cpp b/src/core/util/unicode/guniprop.cpp index 03e60e15..97c05520 100644 --- a/src/core/util/unicode/guniprop.cpp +++ b/src/core/util/unicode/guniprop.cpp @@ -25,6 +25,8 @@ * Boston, MA 02111-1307, USA. */ +// See COPYING file for licensing information. + #include "LuceneInc.h" #include "guniprop.h" diff --git a/src/core/util/unicode/guniprop.h b/src/core/util/unicode/guniprop.h index 9bf164bd..74a00bfd 100644 --- a/src/core/util/unicode/guniprop.h +++ b/src/core/util/unicode/guniprop.h @@ -25,6 +25,8 @@ * Boston, MA 02111-1307, USA. */ +// See COPYING file for licensing information. + #include "Lucene.h" typedef uint32_t gunichar; From 35de024437f4b458c1a2574035d691c23894724f Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 30 Jan 2015 16:11:35 +0000 Subject: [PATCH 089/157] Whitespace. --- src/test/util/LuceneTestFixture.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/util/LuceneTestFixture.cpp b/src/test/util/LuceneTestFixture.cpp index 71e16cfa..80ea6a55 100644 --- a/src/test/util/LuceneTestFixture.cpp +++ b/src/test/util/LuceneTestFixture.cpp @@ -20,6 +20,7 @@ LuceneTestFixture::~LuceneTestFixture() { // Moved out to a separate function since GTEST_FAIL cannot be used in destructors destructorBody(); } + void LuceneTestFixture::destructorBody() { DateTools::setDateOrder(DateTools::DATEORDER_LOCALE); if (ConcurrentMergeScheduler::anyUnhandledExceptions()) { From 4d28f9f04f87fbd5d9e50e15d6d681c37d33addb Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 30 Jan 2015 16:14:22 +0000 Subject: [PATCH 090/157] Release version 3.0.7. --- CMakeLists.txt | 2 +- README.rst | 2 +- doxygen/lucene++ | 2 +- src/core/util/Constants.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78731de6..af3c078c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 2.8.6) set(lucene++_VERSION_MAJOR 3) set(lucene++_VERSION_MINOR 0) -set(lucene++_VERSION_PATCH 6) +set(lucene++_VERSION_PATCH 7) set(lucene++_SOVERSION "0") diff --git a/README.rst b/README.rst index da956322..2e847835 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Lucene++ ========== -Welcome to lucene++ version **3.0.6**. +Welcome to lucene++ version **3.0.7**. Lucene++ is an up to date C++ port of the popular Java `Lucene `_ library, a high-performance, full-featured text search engine. diff --git a/doxygen/lucene++ b/doxygen/lucene++ index f2faab46..f12bf91a 100644 --- a/doxygen/lucene++ +++ b/doxygen/lucene++ @@ -31,7 +31,7 @@ PROJECT_NAME = Lucene++ # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 3.0.6 +PROJECT_NUMBER = 3.0.7 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/src/core/util/Constants.cpp b/src/core/util/Constants.cpp index fd74c53b..d0ec6edc 100644 --- a/src/core/util/Constants.cpp +++ b/src/core/util/Constants.cpp @@ -25,8 +25,8 @@ String Constants::OS_NAME = L"HURD"; String Constants::OS_NAME = L"UNKNOWN"; #endif -String Constants::LUCENE_MAIN_VERSION = L"3.0.6"; -String Constants::LUCENE_VERSION = L"3.0.6"; +String Constants::LUCENE_MAIN_VERSION = L"3.0.7"; +String Constants::LUCENE_VERSION = L"3.0.7"; Constants::Constants() { // private From 972c9cb37457c70530610c22a5f3ff68adf3bd5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Tue, 3 Feb 2015 18:22:25 +0100 Subject: [PATCH 091/157] Fix FSDirectory::sync() to sync writes to disk Contrary to the documentation, FSDirectory::sync() conversion to C++ omitted the most important line of the Java original: actually fsyncing the file descriptor. As the result, its current code amounts to little more than a little nonsensical noop dance. Add the missing fsync() call. Use fsync() on Unix, its FlushFileBuffers() equivalent on Windows, and F_FULLFSYNC on OS X where fsync() is documented as not always sufficient. F_FULLFSYNC is more expensive than fsync(), but guarantees physical write; SQLite uses it too. --- src/core/store/FSDirectory.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/core/store/FSDirectory.cpp b/src/core/store/FSDirectory.cpp index 82b57366..2cb257ac 100644 --- a/src/core/store/FSDirectory.cpp +++ b/src/core/store/FSDirectory.cpp @@ -5,7 +5,6 @@ ///////////////////////////////////////////////////////////////////////////// #include "LuceneInc.h" -#include #include "FSDirectory.h" #include "NativeFSLockFactory.h" #include "SimpleFSDirectory.h" @@ -14,6 +13,15 @@ #include "FileUtils.h" #include "StringUtils.h" +#if defined(_WIN32) + #include +#elif defined(__APPLE__) + #include +#else + #include +#endif +#include + extern "C" { #include "../util/md5/md5.h" @@ -148,15 +156,24 @@ void FSDirectory::sync(const String& name) { bool success = false; for (int32_t retryCount = 0; retryCount < 5; ++retryCount) { - boost::filesystem::ofstream syncFile; + boost::iostreams::file_descriptor syncFile; try { - syncFile.open(path, std::ios::binary | std::ios::in | std::ios::out); + syncFile.open(boost::filesystem::path(path)); } catch (...) { } if (syncFile.is_open()) { + boost::iostreams::file_descriptor::handle_type fd = syncFile.handle(); +#if defined(_WIN32) + bool ok = ::FlushFileBuffers(fd) != 0; +#elif defined(__APPLE__) + bool ok = fcntl(fd, F_FULLFSYNC) == 0; +#else + bool ok = fsync(fd) == 0; +#endif syncFile.close(); - success = true; + if (ok) + success = true; break; } From a02e5b6d422191a3674b13f1becf9c2ec90e83a5 Mon Sep 17 00:00:00 2001 From: gbjbaanb Date: Tue, 24 Mar 2015 15:17:28 +0000 Subject: [PATCH 092/157] minor fix to allow full lines to be input to demo queries --- src/demo/searchfiles/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demo/searchfiles/main.cpp b/src/demo/searchfiles/main.cpp index de4d303d..748003c8 100644 --- a/src/demo/searchfiles/main.cpp +++ b/src/demo/searchfiles/main.cpp @@ -265,7 +265,7 @@ int main(int argc, char* argv[]) { } } else { std::wcout << L"Enter query: "; - std::wcin >> line; + getline(std::wcin, line); } boost::trim(line); From 126821fe1cbf824961f2dacfcefff5775fd66934 Mon Sep 17 00:00:00 2001 From: gbjbaanb Date: Tue, 24 Mar 2015 15:36:11 +0000 Subject: [PATCH 093/157] Modified build for VS2010 - added new style VS project files (.vcxproj) Updated instructions. --- README.rst | 33 +- src/contrib/msvc/lucene_contrib.vcxproj | 641 +++++ .../msvc/lucene_contrib.vcxproj.filters | 599 ++++ src/core/msvc/lucene++.vcxproj | 1056 +++++++ src/core/msvc/lucene++.vcxproj.filters | 2556 +++++++++++++++++ src/demo/deletefiles/msvc/deletefiles.vcxproj | 210 ++ .../msvc/deletefiles.vcxproj.filters | 14 + src/demo/indexfiles/msvc/indexfiles.vcxproj | 210 ++ .../msvc/indexfiles.vcxproj.filters | 14 + src/demo/searchfiles/msvc/searchfiles.vcxproj | 210 ++ .../msvc/searchfiles.vcxproj.filters | 14 + src/msvc/lucene++.sln | 181 +- src/test/msvc/lucene_tester.vcxproj | 471 +++ src/test/msvc/lucene_tester.vcxproj.filters | 848 ++++++ 14 files changed, 6946 insertions(+), 111 deletions(-) create mode 100644 src/contrib/msvc/lucene_contrib.vcxproj create mode 100644 src/contrib/msvc/lucene_contrib.vcxproj.filters create mode 100644 src/core/msvc/lucene++.vcxproj create mode 100644 src/core/msvc/lucene++.vcxproj.filters create mode 100644 src/demo/deletefiles/msvc/deletefiles.vcxproj create mode 100644 src/demo/deletefiles/msvc/deletefiles.vcxproj.filters create mode 100644 src/demo/indexfiles/msvc/indexfiles.vcxproj create mode 100644 src/demo/indexfiles/msvc/indexfiles.vcxproj.filters create mode 100644 src/demo/searchfiles/msvc/searchfiles.vcxproj create mode 100644 src/demo/searchfiles/msvc/searchfiles.vcxproj.filters create mode 100644 src/test/msvc/lucene_tester.vcxproj create mode 100644 src/test/msvc/lucene_tester.vcxproj.filters diff --git a/README.rst b/README.rst index 2e847835..9f35891e 100644 --- a/README.rst +++ b/README.rst @@ -48,20 +48,19 @@ To build the library the following commands should be issued:: Build Instructions for Windows systems -------------------------------------- -Open solution lucene++.sln located in the *msvc* folder into Visual Studio and build. +Open solution lucene++.sln located in the *msvc* folder into Visual Studio 2010+ and build. -**Note: "BOOST_ROOT" environment variable must be defined to point to the Boost library directory (eg. c:\\boost_1_51_0)** +**Note: you will need to edit the include\Config.h.cmake file. Make a copy, rename it to Config.h, and replace + @DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK + with + #define LPP_USE_CYCLIC_CHECK -You'll need Boost installed. +**Note: "BOOST_ROOT" environment variable must be defined to point to the Boost library directory (eg. c:\\boost_1_57_0)** +** Boost libs must be located in a subdirectory lib32-msvc-10.0 +** This is the default name of the install directory from the sf.net `boost-binaries http://sourceforge.net/projects/boost/files/boost-binaries/` project: + +You'll need Boost installed from http://boost.org. -`BoostPro `_ has some precompiled Windows packages. You'll need the following extras installed:: - -- boost::system -- boost::thread -- boost::filesystem -- boost::regex -- boost::date_time -- boost::iostreams To run unit test suite @@ -74,6 +73,18 @@ lucene_tester is built using the `Google Testing Framework + +Once the indexer has finished, you can query the index using searchfiles: + searchfiles.exe -index + + This uses an interactive command for you to enter queries, type a query to search the index press enter and you'll see the results. + + Acknowledgements ---------------- diff --git a/src/contrib/msvc/lucene_contrib.vcxproj b/src/contrib/msvc/lucene_contrib.vcxproj new file mode 100644 index 00000000..984af9b0 --- /dev/null +++ b/src/contrib/msvc/lucene_contrib.vcxproj @@ -0,0 +1,641 @@ + + + + + Debug DLL + Win32 + + + Debug Static + Win32 + + + Release DLL + Win32 + + + Release Static + Win32 + + + + {46A95AFD-95FD-4280-B22E-1B56F273144B} + lucene_contrib + Win32Proj + + + + StaticLibrary + Unicode + true + + + StaticLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + true + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + false + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + + + + /Zm120 %(AdditionalOptions) + Disabled + ..\include;..\..\..\include;..\snowball\libstemmer_c\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;LPP_HAVE_DLL;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + Use + ContribInc.h + Level3 + EditAndContinue + 4996;%(DisableSpecificWarnings) + false + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\lib32-msvc-10.0;..\..\..\lib;%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." +copy "$(OutDir)$(ProjectName).dll" "..\..\..\bin\." + + + + + + /Zm120 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\include;..\..\..\include;..\snowball\libstemmer_c\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LPP_HAVE_DLL;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + Use + ContribInc.h + Level3 + ProgramDatabase + 4996;%(DisableSpecificWarnings) + false + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\lib;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." +copy "$(OutDir)$(ProjectName).dll" "..\..\..\bin\." + + + + + + /Zm120 %(AdditionalOptions) + Disabled + ..\include;..\..\..\include;..\snowball\libstemmer_c\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + ContribInc.h + Level3 + EditAndContinue + 4996;%(DisableSpecificWarnings) + false + + + /IGNORE:4221 %(AdditionalOptions) + $(BOOST_ROOT)\stage\lib;%(AdditionalLibraryDirectories) + + + copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." + + + + + /Zm120 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\include;..\..\..\include;..\snowball\libstemmer_c\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Use + ContribInc.h + Level3 + ProgramDatabase + 4996;%(DisableSpecificWarnings) + false + + + /IGNORE:4221 %(AdditionalOptions) + $(BOOST_ROOT)\stage\lib;%(AdditionalLibraryDirectories) + + + copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." + + + + + + Create + Create + Create + Create + + + + + false + + + false + + + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + Config.h;%(ForcedIncludeFiles) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {46a95afd-95fd-4280-b22e-1b56f273144a} + false + + + + + + \ No newline at end of file diff --git a/src/contrib/msvc/lucene_contrib.vcxproj.filters b/src/contrib/msvc/lucene_contrib.vcxproj.filters new file mode 100644 index 00000000..cd070873 --- /dev/null +++ b/src/contrib/msvc/lucene_contrib.vcxproj.filters @@ -0,0 +1,599 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {ed281916-1385-43dd-ba49-d40e8504292f} + + + {cbc62969-9e1a-4ea1-8a5b-70dc05c54a74} + + + {af08d7d6-346f-4315-8a08-e5670d8ea661} + + + {5f664ed0-5376-4c1d-be74-9f437a8f28a0} + + + {25265c9f-fb03-4de0-af5b-1dc8a22b6a39} + + + {cbd88c58-498d-4cf6-a8b8-cab8ae9c1a33} + + + {f22aa0ca-0c74-4b24-8c13-ac4bf2eaeb62} + + + {9d6a5d6b-5270-4d71-bf47-e1fd628f0de5} + + + {de0f0dac-e3c9-4c68-9645-bd7facc23cad} + + + {b3fa72fe-e465-4c37-879c-ca78a4cdfa04} + + + {ff7c09cf-c9c4-48f1-b627-c4577cf04005} + + + {9a006a1c-6c67-4ad5-9a3a-1e73278296de} + + + {15af4be9-0258-4006-8d4a-e14efa2d23d2} + + + {897982c5-a448-4a64-a394-5b6621b73523} + + + {892af3ea-b061-4b0e-83ba-d221682d4d98} + + + {1f5a687a-5a25-4d1f-aff1-224dd446d1b4} + + + {65078152-1671-49dc-8eff-10daa009b07b} + + + {99f2b070-1b33-44cc-b645-c887144eb557} + + + {a5432a73-3546-49ee-9b10-974d0dfbd3a7} + + + {0df31b77-1d5d-42dc-839d-c77784ea81c4} + + + {72f1545b-b051-45f8-b0b3-bf0facf48e9b} + + + {2d2a742a-d676-42ee-be16-54d6ed3e42b0} + + + + + source files + + + source files + + + analyzers\common\analysis\reverse + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\br + + + analyzers\common\analysis\br + + + analyzers\common\analysis\br + + + analyzers\common\analysis\cjk + + + analyzers\common\analysis\cjk + + + analyzers\common\analysis\cn + + + analyzers\common\analysis\cn + + + analyzers\common\analysis\cn + + + analyzers\common\analysis\cz + + + analyzers\common\analysis\de + + + analyzers\common\analysis\de + + + analyzers\common\analysis\de + + + analyzers\common\analysis\el + + + analyzers\common\analysis\el + + + analyzers\common\analysis\fa + + + analyzers\common\analysis\fa + + + analyzers\common\analysis\fa + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\nl + + + analyzers\common\analysis\nl + + + analyzers\common\analysis\nl + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + snowball + + + snowball + + + snowball\libstemmer\runtime + + + snowball\libstemmer\runtime + + + snowball\libstemmer\libstemmer + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + memory + + + + + header files + + + header files + + + header files + + + header files + + + header files + + + header files + + + header files + + + analyzers\common\analysis\reverse + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\ar + + + analyzers\common\analysis\br + + + analyzers\common\analysis\br + + + analyzers\common\analysis\br + + + analyzers\common\analysis\cjk + + + analyzers\common\analysis\cjk + + + analyzers\common\analysis\cn + + + analyzers\common\analysis\cn + + + analyzers\common\analysis\cn + + + analyzers\common\analysis\cz + + + analyzers\common\analysis\de + + + analyzers\common\analysis\de + + + analyzers\common\analysis\de + + + analyzers\common\analysis\el + + + analyzers\common\analysis\el + + + analyzers\common\analysis\fa + + + analyzers\common\analysis\fa + + + analyzers\common\analysis\fa + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\fr + + + analyzers\common\analysis\nl + + + analyzers\common\analysis\nl + + + analyzers\common\analysis\nl + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + analyzers\common\analysis\ru + + + snowball + + + snowball + + + snowball\libstemmer\runtime + + + snowball\libstemmer\runtime + + + snowball\libstemmer\libstemmer + + + snowball\libstemmer\libstemmer + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + snowball\libstemmer\src + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + highlighter + + + memory + + + \ No newline at end of file diff --git a/src/core/msvc/lucene++.vcxproj b/src/core/msvc/lucene++.vcxproj new file mode 100644 index 00000000..cd811b5c --- /dev/null +++ b/src/core/msvc/lucene++.vcxproj @@ -0,0 +1,1056 @@ + + + + + Debug DLL + Win32 + + + Debug Static + Win32 + + + Release DLL + Win32 + + + Release Static + Win32 + + + + {46A95AFD-95FD-4280-B22E-1B56F273144A} + lucene++ + Win32Proj + + + + StaticLibrary + Unicode + true + + + StaticLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + + + Disabled + ..\..\..\include;..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;LPP_HAVE_DLL;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + Use + LuceneInc.h + Level3 + EditAndContinue + 4996;%(DisableSpecificWarnings) + false + + + $(BOOST_ROOT)\lib32-msvc-10.0;%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + if not exist "..\..\..\lib" mkdir "..\..\..\lib" +if not exist "..\..\..\bin" mkdir "..\..\..\bin" +copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." +copy "$(OutDir)$(ProjectName).dll" "..\..\..\bin\." + + + + + + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\include;..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LPP_HAVE_DLL;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + Use + LuceneInc.h + Level3 + ProgramDatabase + 4996;%(DisableSpecificWarnings) + false + + + $(BOOST_ROOT)\stage\lib;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + if not exist "..\..\..\lib" mkdir "..\..\..\lib" +if not exist "..\..\..\bin" mkdir "..\..\..\bin" +copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." +copy "$(OutDir)$(ProjectName).dll" "..\..\..\bin\." + + + + + + Disabled + ..\..\..\include;..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + LuceneInc.h + Level3 + EditAndContinue + 4996;%(DisableSpecificWarnings) + false + + + /IGNORE:4221 %(AdditionalOptions) + $(BOOST_ROOT)\stage\lib;%(AdditionalLibraryDirectories) + + + if not exist "..\..\..\lib" mkdir "..\..\..\lib" +copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." + + + + + + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\include;..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;LPP_BUILDING_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Use + LuceneInc.h + Level3 + ProgramDatabase + 4996;%(DisableSpecificWarnings) + false + + + /IGNORE:4221 %(AdditionalOptions) + $(BOOST_ROOT)\stage\lib;%(AdditionalLibraryDirectories) + + + if not exist "..\..\..\lib" mkdir "..\..\..\lib" +copy "$(OutDir)$(ProjectName).lib" "..\..\..\lib\." + + + + + + + + false + + + false + + + false + + + false + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/core/msvc/lucene++.vcxproj.filters b/src/core/msvc/lucene++.vcxproj.filters new file mode 100644 index 00000000..ae9ef5b2 --- /dev/null +++ b/src/core/msvc/lucene++.vcxproj.filters @@ -0,0 +1,2556 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {48502038-53e1-4765-991b-c97b4be11da4} + + + {a684d11c-6040-49c1-b5e5-0615984a8c2c} + + + {b61dc7e6-fb87-4b3f-ba4c-226a4361b847} + + + {c2e416ff-52fb-4d36-9be1-e8610beefd4d} + + + {88cac9c3-83c6-42df-a5eb-a1f0d741b627} + + + {3e5e8bae-b0a3-498d-89bb-c4d511c21f4f} + + + {9a837aa2-bfff-4729-b020-bece9d615183} + + + {174ad8b8-0c6c-4ff7-8a6f-84f5627420ea} + + + {f6b6a77f-cc4a-406e-9b54-cb4af439c1e1} + + + {d4777928-6836-4755-9087-b4025ec3fc78} + + + {88de8393-eac2-4c2b-b102-0aa83c3ff01b} + + + {eb586280-ac06-4447-a2f7-404725729407} + + + {cc88a9b9-9490-48e9-a2d2-c77a8e370f45} + + + {81e1de0d-e621-451a-94dd-97e69cff08e7} + + + {ce3c5a86-a7c4-4f59-9c67-92d38e9dc50a} + + + + + source files + + + source files + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\standard + + + analysis\standard + + + analysis\standard + + + analysis\standard + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform\md5 + + + platform\unicode + + + + + header files + + + header files + + + header files + + + header files + + + header files + + + header files + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\tokenattributes + + + analysis\standard + + + analysis\standard + + + analysis\standard + + + analysis\standard + + + analysis\standard + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\payloads + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + document + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + query parser + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform + + + platform\md5 + + + platform\unicode + + + platform\unicode + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + store + + + store + + + store + + + store + + + store + + + store + + + \ No newline at end of file diff --git a/src/demo/deletefiles/msvc/deletefiles.vcxproj b/src/demo/deletefiles/msvc/deletefiles.vcxproj new file mode 100644 index 00000000..e39c2261 --- /dev/null +++ b/src/demo/deletefiles/msvc/deletefiles.vcxproj @@ -0,0 +1,210 @@ + + + + + Debug DLL + Win32 + + + Debug Static + Win32 + + + Release DLL + Win32 + + + Release Static + Win32 + + + + {688A6720-739F-4EA3-AC5B-AA67A0965105} + deletefiles + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;LPP_HAVE_DLL;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + + + Level3 + EditAndContinue + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\lib32-msvc-10.0;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + + + Level3 + ProgramDatabase + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + + + Level3 + EditAndContinue + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;LPP_HAVE_DLL;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + + + Level3 + ProgramDatabase + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + + + + {46a95afd-95fd-4280-b22e-1b56f273144b} + false + + + {46a95afd-95fd-4280-b22e-1b56f273144a} + false + + + + + + \ No newline at end of file diff --git a/src/demo/deletefiles/msvc/deletefiles.vcxproj.filters b/src/demo/deletefiles/msvc/deletefiles.vcxproj.filters new file mode 100644 index 00000000..e37e4061 --- /dev/null +++ b/src/demo/deletefiles/msvc/deletefiles.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + source files + + + \ No newline at end of file diff --git a/src/demo/indexfiles/msvc/indexfiles.vcxproj b/src/demo/indexfiles/msvc/indexfiles.vcxproj new file mode 100644 index 00000000..94c8f34b --- /dev/null +++ b/src/demo/indexfiles/msvc/indexfiles.vcxproj @@ -0,0 +1,210 @@ + + + + + Debug DLL + Win32 + + + Debug Static + Win32 + + + Release DLL + Win32 + + + Release Static + Win32 + + + + {688A6720-739F-4EA3-AC5B-AA67A0965103} + indexfiles + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;LPP_HAVE_DLL;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + + + Level3 + EditAndContinue + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\lib32-msvc-10.0;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + + + Level3 + ProgramDatabase + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + + + Level3 + EditAndContinue + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;LPP_HAVE_DLL;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + + + Level3 + ProgramDatabase + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + + + + {46a95afd-95fd-4280-b22e-1b56f273144b} + false + + + {46a95afd-95fd-4280-b22e-1b56f273144a} + false + + + + + + \ No newline at end of file diff --git a/src/demo/indexfiles/msvc/indexfiles.vcxproj.filters b/src/demo/indexfiles/msvc/indexfiles.vcxproj.filters new file mode 100644 index 00000000..e37e4061 --- /dev/null +++ b/src/demo/indexfiles/msvc/indexfiles.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + source files + + + \ No newline at end of file diff --git a/src/demo/searchfiles/msvc/searchfiles.vcxproj b/src/demo/searchfiles/msvc/searchfiles.vcxproj new file mode 100644 index 00000000..59187932 --- /dev/null +++ b/src/demo/searchfiles/msvc/searchfiles.vcxproj @@ -0,0 +1,210 @@ + + + + + Debug DLL + Win32 + + + Debug Static + Win32 + + + Release DLL + Win32 + + + Release Static + Win32 + + + + {688A6720-739F-4EA3-AC5B-AA67A0965104} + searchfiles + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;LPP_HAVE_DLL;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + + + Level3 + EditAndContinue + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\lib32-msvc-10.0;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + + + Level3 + ProgramDatabase + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + + + Level3 + EditAndContinue + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\..\..\..\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;LPP_HAVE_DLL;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + + + Level3 + ProgramDatabase + + + lucene++.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\..\bin\." + + + + + + + + {46a95afd-95fd-4280-b22e-1b56f273144b} + false + + + {46a95afd-95fd-4280-b22e-1b56f273144a} + false + + + + + + \ No newline at end of file diff --git a/src/demo/searchfiles/msvc/searchfiles.vcxproj.filters b/src/demo/searchfiles/msvc/searchfiles.vcxproj.filters new file mode 100644 index 00000000..e37e4061 --- /dev/null +++ b/src/demo/searchfiles/msvc/searchfiles.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + source files + + + \ No newline at end of file diff --git a/src/msvc/lucene++.sln b/src/msvc/lucene++.sln index e183f153..a016ec99 100644 --- a/src/msvc/lucene++.sln +++ b/src/msvc/lucene++.sln @@ -1,100 +1,81 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lucene_tester", "..\test\msvc\lucene_tester.vcproj", "{6D684870-1124-49E1-8F96-7DE7B6114BEA}" - ProjectSection(ProjectDependencies) = postProject - {46A95AFD-95FD-4280-B22E-1B56F273144A} = {46A95AFD-95FD-4280-B22E-1B56F273144A} - {46A95AFD-95FD-4280-B22E-1B56F273144B} = {46A95AFD-95FD-4280-B22E-1B56F273144B} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demos", "demos", "{E9344A66-4CC8-4E5B-83BC-8061E8962B46}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "indexfiles", "..\demo\indexfiles\msvc\indexfiles.vcproj", "{688A6720-739F-4EA3-AC5B-AA67A0965103}" - ProjectSection(ProjectDependencies) = postProject - {46A95AFD-95FD-4280-B22E-1B56F273144A} = {46A95AFD-95FD-4280-B22E-1B56F273144A} - {46A95AFD-95FD-4280-B22E-1B56F273144B} = {46A95AFD-95FD-4280-B22E-1B56F273144B} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deletefiles", "..\demo\deletefiles\msvc\deletefiles.vcproj", "{688A6720-739F-4EA3-AC5B-AA67A0965105}" - ProjectSection(ProjectDependencies) = postProject - {46A95AFD-95FD-4280-B22E-1B56F273144A} = {46A95AFD-95FD-4280-B22E-1B56F273144A} - {46A95AFD-95FD-4280-B22E-1B56F273144B} = {46A95AFD-95FD-4280-B22E-1B56F273144B} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "searchfiles", "..\demo\searchfiles\msvc\searchfiles.vcproj", "{688A6720-739F-4EA3-AC5B-AA67A0965104}" - ProjectSection(ProjectDependencies) = postProject - {46A95AFD-95FD-4280-B22E-1B56F273144A} = {46A95AFD-95FD-4280-B22E-1B56F273144A} - {46A95AFD-95FD-4280-B22E-1B56F273144B} = {46A95AFD-95FD-4280-B22E-1B56F273144B} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lucene_contrib", "..\contrib\msvc\lucene_contrib.vcproj", "{46A95AFD-95FD-4280-B22E-1B56F273144B}" - ProjectSection(ProjectDependencies) = postProject - {46A95AFD-95FD-4280-B22E-1B56F273144A} = {46A95AFD-95FD-4280-B22E-1B56F273144A} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lucene++", "..\core\msvc\lucene++.vcproj", "{46A95AFD-95FD-4280-B22E-1B56F273144A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug DLL|Win32 = Debug DLL|Win32 - Debug Static|Win32 = Debug Static|Win32 - Release DLL|Win32 = Release DLL|Win32 - Release Static|Win32 = Release Static|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 - {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 - {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Debug Static|Win32.Build.0 = Debug Static|Win32 - {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 - {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Release Static|Win32.Build.0 = Release Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug Static|Win32.Build.0 = Debug Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release DLL|Win32.Build.0 = Release DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release Static|Win32.Build.0 = Release Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug Static|Win32.Build.0 = Debug Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release DLL|Win32.Build.0 = Release DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release Static|Win32.Build.0 = Release Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug Static|Win32.Build.0 = Debug Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release DLL|Win32.Build.0 = Release DLL|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release Static|Win32.Build.0 = Release Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug Static|Win32.Build.0 = Debug Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release DLL|Win32.Build.0 = Release DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release Static|Win32.Build.0 = Release Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug Static|Win32.Build.0 = Debug Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release DLL|Win32.Build.0 = Release DLL|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release Static|Win32.Build.0 = Release Static|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {688A6720-739F-4EA3-AC5B-AA67A0965103} = {E9344A66-4CC8-4E5B-83BC-8061E8962B46} - {688A6720-739F-4EA3-AC5B-AA67A0965105} = {E9344A66-4CC8-4E5B-83BC-8061E8962B46} - {688A6720-739F-4EA3-AC5B-AA67A0965104} = {E9344A66-4CC8-4E5B-83BC-8061E8962B46} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demos", "demos", "{E9344A66-4CC8-4E5B-83BC-8061E8962B46}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lucene_tester", "..\test\msvc\lucene_tester.vcxproj", "{6D684870-1124-49E1-8F96-7DE7B6114BEA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "indexfiles", "..\demo\indexfiles\msvc\indexfiles.vcxproj", "{688A6720-739F-4EA3-AC5B-AA67A0965103}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deletefiles", "..\demo\deletefiles\msvc\deletefiles.vcxproj", "{688A6720-739F-4EA3-AC5B-AA67A0965105}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "searchfiles", "..\demo\searchfiles\msvc\searchfiles.vcxproj", "{688A6720-739F-4EA3-AC5B-AA67A0965104}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lucene_contrib", "..\contrib\msvc\lucene_contrib.vcxproj", "{46A95AFD-95FD-4280-B22E-1B56F273144B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lucene++", "..\core\msvc\lucene++.vcxproj", "{46A95AFD-95FD-4280-B22E-1B56F273144A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug DLL|Win32 = Debug DLL|Win32 + Debug Static|Win32 = Debug Static|Win32 + Release DLL|Win32 = Release DLL|Win32 + Release Static|Win32 = Release Static|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 + {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 + {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Debug Static|Win32.Build.0 = Debug Static|Win32 + {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 + {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Release Static|Win32.ActiveCfg = Release Static|Win32 + {6D684870-1124-49E1-8F96-7DE7B6114BEA}.Release Static|Win32.Build.0 = Release Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Debug Static|Win32.Build.0 = Debug Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release DLL|Win32.Build.0 = Release DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release Static|Win32.ActiveCfg = Release Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965103}.Release Static|Win32.Build.0 = Release Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Debug Static|Win32.Build.0 = Debug Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release DLL|Win32.Build.0 = Release DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release Static|Win32.ActiveCfg = Release Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965105}.Release Static|Win32.Build.0 = Release Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Debug Static|Win32.Build.0 = Debug Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release DLL|Win32.Build.0 = Release DLL|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release Static|Win32.ActiveCfg = Release Static|Win32 + {688A6720-739F-4EA3-AC5B-AA67A0965104}.Release Static|Win32.Build.0 = Release Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Debug Static|Win32.Build.0 = Debug Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release DLL|Win32.Build.0 = Release DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release Static|Win32.ActiveCfg = Release Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144B}.Release Static|Win32.Build.0 = Release Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug Static|Win32.ActiveCfg = Debug Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Debug Static|Win32.Build.0 = Debug Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release DLL|Win32.Build.0 = Release DLL|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release Static|Win32.ActiveCfg = Release Static|Win32 + {46A95AFD-95FD-4280-B22E-1B56F273144A}.Release Static|Win32.Build.0 = Release Static|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {688A6720-739F-4EA3-AC5B-AA67A0965103} = {E9344A66-4CC8-4E5B-83BC-8061E8962B46} + {688A6720-739F-4EA3-AC5B-AA67A0965105} = {E9344A66-4CC8-4E5B-83BC-8061E8962B46} + {688A6720-739F-4EA3-AC5B-AA67A0965104} = {E9344A66-4CC8-4E5B-83BC-8061E8962B46} + EndGlobalSection +EndGlobal diff --git a/src/test/msvc/lucene_tester.vcxproj b/src/test/msvc/lucene_tester.vcxproj new file mode 100644 index 00000000..777c51cb --- /dev/null +++ b/src/test/msvc/lucene_tester.vcxproj @@ -0,0 +1,471 @@ + + + + + Debug DLL + Win32 + + + Debug Static + Win32 + + + Release DLL + Win32 + + + Release Static + Win32 + + + + {6D684870-1124-49E1-8F96-7DE7B6114BEA} + lucene_tester + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + true + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\include;..\..\..\include;..\..\core\include;..\..\contrib\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;LPP_HAVE_DLL;LPP_EXPOSE_INTERNAL;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + Use + TestInc.h + Level3 + EditAndContinue + + + lucene++.lib;lucene_contrib.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\lib32-msvc-10.0;..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\include;..\..\..\include;..\..\core\include;..\..\contrib\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;LPP_EXPOSE_INTERNAL;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + Use + TestInc.h + Level3 + ProgramDatabase + + + lucene++.lib;lucene_contrib.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + Disabled + ..\include;..\..\..\include;..\..\core\include;..\..\contrib\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;LPP_EXPOSE_INTERNAL;%(PreprocessorDefinitions) + true + Async + EnableFastChecks + MultiThreadedDebugDLL + false + Use + TestInc.h + Level3 + EditAndContinue + + + lucene++.lib;lucene_contrib.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\bin\." + + + + + /Zm180 %(AdditionalOptions) + MaxSpeed + AnySuitable + true + Speed + true + ..\include;..\..\..\include;..\..\core\include;..\..\contrib\include;$(BOOST_ROOT);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;LPP_HAVE_DLL;LPP_EXPOSE_INTERNAL;%(PreprocessorDefinitions) + Async + MultiThreadedDLL + true + false + Use + TestInc.h + Level3 + ProgramDatabase + + + lucene++.lib;lucene_contrib.lib;%(AdditionalDependencies) + $(BOOST_ROOT)\stage\lib;..\..\..\lib;%(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + copy "$(OutDir)$(ProjectName).exe" "..\..\..\bin\." + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {46a95afd-95fd-4280-b22e-1b56f273144b} + false + + + {46a95afd-95fd-4280-b22e-1b56f273144a} + false + + + + + + \ No newline at end of file diff --git a/src/test/msvc/lucene_tester.vcxproj.filters b/src/test/msvc/lucene_tester.vcxproj.filters new file mode 100644 index 00000000..b20839ae --- /dev/null +++ b/src/test/msvc/lucene_tester.vcxproj.filters @@ -0,0 +1,848 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {7333c43f-9e86-4988-a184-3b190d47dd66} + + + {cc6d76f1-6754-4733-812d-89af8999002f} + + + {4cff3fec-b356-4da6-a4fc-0501aa700b72} + + + {4378e8be-af9c-4221-92c2-0133df9db27d} + + + {027420f1-bdf4-4121-89f4-702b31ab05d4} + + + {0e80767f-dbcf-4405-8282-f33c1c025380} + + + {36c464b5-2a15-4060-ab8f-4b0549003407} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {31ab326e-55c7-4cd3-914e-04ad6f443103} + + + {a21c1a10-57e9-4ce8-bcfb-02228c404856} + + + {0868ef7a-70c1-4273-b893-1ce8b92f5675} + + + {0c8fb69f-b236-4c42-b42d-d2b70d8648b4} + + + {7f3b48dc-cc4a-4a89-8dfb-9e7c5c60d980} + + + {0d5e16aa-6874-4e57-a351-462a685c9c4c} + + + {987e5db6-a038-4d26-9917-47359346af48} + + + {31fd1660-a627-4627-9e63-0498b157ef99} + + + {68c9de7e-8c09-4e0a-a85b-534d2ebf6ea9} + + + {94f5ef13-7985-446f-afbb-a33542e2d1f0} + + + {8a5c6219-2c5b-4ac3-8728-1c4ba5e4a420} + + + {f42aacf4-3011-4755-be9a-c610a55aeb62} + + + {b568d9f7-380c-4679-a0f6-e9ac915f08b1} + + + {80ccc2ee-c801-4e82-8bcd-2529abbfa0cc} + + + {e81adcfc-0198-4fed-ad37-d53518e40ca6} + + + {d7464eec-abec-466a-abf4-0f1a81c9f3e8} + + + {a11af51d-bb86-49e4-9aef-3d59bf7c57f2} + + + {1a3ffcb1-fd23-4a42-bfb1-20c6ed8ea634} + + + {ca3743cd-f295-4139-b742-7535a91bed1a} + + + {c6435527-5f60-4991-962f-bfcd8c976728} + + + {0eb8d6c3-de36-484d-92d0-2a6683dfbbc8} + + + {963470db-0af1-4c90-b732-4a347cb41b5e} + + + {6f1adb3c-338e-4ae8-81c1-eb04895401a9} + + + {311b1fb8-b020-4342-b1e2-060b708bc6da} + + + + + header files + + + header files + + + header files + + + header files + + + header files + + + store + + + store + + + store + + + store + + + store + + + store + + + index + + + index + + + analysis + + + source files + + + source files + + + source files + + + search + + + search + + + search + + + search + + + search + + + search\function + + + search\payloads + + + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + store + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + util + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + index + + + document + + + document + + + document + + + document + + + document + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis + + + analysis\standard + + + analysis\tokenattributes + + + analysis\tokenattributes + + + source files + + + source files + + + source files + + + source files + + + source files + + + query parser + + + query parser + + + query parser + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search + + + search\function + + + search\function + + + search\function + + + search\function + + + search\function + + + search\payloads + + + search\payloads + + + search\payloads + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + search\spans + + + contrib\analyzers\common\analysis\reverse + + + contrib\analyzers\common\analysis\ar + + + contrib\analyzers\common\analysis\ar + + + contrib\analyzers\common\analysis\ar + + + contrib\analyzers\common\analysis\br + + + contrib\analyzers\common\analysis\cjk + + + contrib\analyzers\common\analysis\cn + + + contrib\analyzers\common\analysis\cz + + + contrib\analyzers\common\analysis\de + + + contrib\analyzers\common\analysis\el + + + contrib\analyzers\common\analysis\fa + + + contrib\analyzers\common\analysis\fa + + + contrib\analyzers\common\analysis\fr + + + contrib\analyzers\common\analysis\fr + + + contrib\analyzers\common\analysis\nl + + + contrib\analyzers\common\analysis\ru + + + contrib\analyzers\common\analysis\ru + + + contrib\snowball + + + contrib\highlighter + + + contrib\memory + + + \ No newline at end of file From f83f2db769f406f682be92eba1fe72936bae8568 Mon Sep 17 00:00:00 2001 From: gbjbaanb Date: Tue, 24 Mar 2015 15:45:25 +0000 Subject: [PATCH 094/157] better formatting --- README.rst | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 9f35891e..4c96d234 100644 --- a/README.rst +++ b/README.rst @@ -50,15 +50,19 @@ Build Instructions for Windows systems Open solution lucene++.sln located in the *msvc* folder into Visual Studio 2010+ and build. -**Note: you will need to edit the include\Config.h.cmake file. Make a copy, rename it to Config.h, and replace - @DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK - with - #define LPP_USE_CYCLIC_CHECK +**Note: you will need to edit the include\Config.h.cmake file. Make a copy, rename it to Config.h, and replace** + + #@DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK + +with + + #define LPP_USE_CYCLIC_CHECK **Note: "BOOST_ROOT" environment variable must be defined to point to the Boost library directory (eg. c:\\boost_1_57_0)** -** Boost libs must be located in a subdirectory lib32-msvc-10.0 -** This is the default name of the install directory from the sf.net `boost-binaries http://sourceforge.net/projects/boost/files/boost-binaries/` project: - + +Boost libs must be located in a subdirectory lib32-msvc-10.0 +This is the default name of the install directory from the sf.net `Boost-binaries `_ project. + You'll need Boost installed from http://boost.org. @@ -73,16 +77,20 @@ lucene_tester is built using the `Google Testing Framework -Once the indexer has finished, you can query the index using searchfiles: +Once the indexer has finished, you can query the index using searchfiles + searchfiles.exe -index - This uses an interactive command for you to enter queries, type a query to search the index press enter and you'll see the results. +This uses an interactive command for you to enter queries, type a query to search the index press enter and you'll see the results. Acknowledgements From 229f783749283d1ec2bed4593805f7a8458ab819 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Mon, 6 Apr 2015 16:48:16 +0200 Subject: [PATCH 095/157] Use maxSize of BooleanQuery as base for the queue size --- src/core/search/FuzzyQuery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/search/FuzzyQuery.cpp b/src/core/search/FuzzyQuery.cpp index 52919956..38e1bf25 100644 --- a/src/core/search/FuzzyQuery.cpp +++ b/src/core/search/FuzzyQuery.cpp @@ -83,7 +83,7 @@ QueryPtr FuzzyQuery::rewrite(const IndexReaderPtr& reader) { } int32_t maxSize = BooleanQuery::getMaxClauseCount(); - ScoreTermQueuePtr stQueue(newLucene(1024)); + ScoreTermQueuePtr stQueue(newLucene(maxSize + 1)); FilteredTermEnumPtr enumerator(getEnum(reader)); LuceneException finally; try { From dd6ba769ea8b411d6e09720dfe7f38d027d8f8fc Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Tue, 28 Apr 2015 09:31:35 +0200 Subject: [PATCH 096/157] Fix packageconfig path. Rationale: LIB_DESTINATION is set as CMAKE_INSTALL_FULL_LIBDIR. So repeating "{prefix}" results in a double usr/usr inclusion --- liblucene++-contrib.pc.cmake | 4 ++-- liblucene++.pc.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/liblucene++-contrib.pc.cmake b/liblucene++-contrib.pc.cmake index 98b63818..21026e0a 100644 --- a/liblucene++-contrib.pc.cmake +++ b/liblucene++-contrib.pc.cmake @@ -1,13 +1,13 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix}/bin -libdir=${prefix}/@LIB_DESTINATION@ +libdir=@LIB_DESTINATION@ includedir=${prefix}/include/lucene++ lib=lucene++-contrib Name: liblucene++-contrib Description: Contributions for Lucene++ - a C++ search engine, ported from the popular Apache Lucene Version: @lucene++_VERSION@ -Libs: -L${prefix}/@LIB_DESTINATION@ -l${lib} +Libs: -L@LIB_DESTINATION@ -l${lib} Cflags: -I${includedir} Requires: liblucene++ = @lucene++_VERSION@ diff --git a/liblucene++.pc.cmake b/liblucene++.pc.cmake index c526d4ab..32d16ad7 100644 --- a/liblucene++.pc.cmake +++ b/liblucene++.pc.cmake @@ -1,12 +1,12 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix}/bin -libdir=${prefix}/@LIB_DESTINATION@ +libdir=@LIB_DESTINATION@ includedir=${prefix}/include/lucene++ lib=lucene++ Name: liblucene++ Description: Lucene++ - a C++ search engine, ported from the popular Apache Lucene Version: @lucene++_VERSION@ -Libs: -L${prefix}/@LIB_DESTINATION@ -l${lib} +Libs: -L@LIB_DESTINATION@ -l${lib} Cflags: -I${includedir} From 1987082cf9278a639d772b4f35a8ae2d34944177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Mon, 4 May 2015 18:04:46 +0200 Subject: [PATCH 097/157] Fix compilation with Boost 1.58 1.58 introduces strict type checking in boost::get() and while that's good in theory, the VariantUtils code makes it impractical to use. Instead, use relaxed_get() to get the old behavior. relaxed_get() didn't exist in older versions of Boost, so the code must check BOOST_VERSION. Fixes #93. --- include/VariantUtils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/VariantUtils.h b/include/VariantUtils.h index 1e6c2436..5a72e592 100644 --- a/include/VariantUtils.h +++ b/include/VariantUtils.h @@ -8,6 +8,7 @@ #define VARIANTUTILS_H #include +#include #include "Lucene.h" #include "MiscUtils.h" @@ -22,7 +23,11 @@ class LPPAPI VariantUtils { template static TYPE get(VAR var) { +#if BOOST_VERSION < 105800 return var.type() == typeid(TYPE) ? boost::get(var) : TYPE(); +#else + return var.type() == typeid(TYPE) ? boost::relaxed_get(var) : TYPE(); +#endif } template From afd772ba14954c8785ce17a376759ba9525f3315 Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Thu, 16 Jul 2015 17:03:34 +0100 Subject: [PATCH 098/157] Fix segfault when unit tests are complete. closes #87 --- src/test/include/LuceneGlobalFixture.h | 7 ++----- src/test/util/LuceneGlobalFixture.cpp | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/include/LuceneGlobalFixture.h b/src/test/include/LuceneGlobalFixture.h index 81f9cdda..ff426d06 100644 --- a/src/test/include/LuceneGlobalFixture.h +++ b/src/test/include/LuceneGlobalFixture.h @@ -10,11 +10,8 @@ namespace Lucene { class LuceneGlobalFixture : public testing::Environment { public: - /// setup - LuceneGlobalFixture(); - - /// teardown - virtual ~LuceneGlobalFixture(); + virtual void SetUp(); + virtual void TearDown(); }; } diff --git a/src/test/util/LuceneGlobalFixture.cpp b/src/test/util/LuceneGlobalFixture.cpp index c46e8acc..c98f9e51 100644 --- a/src/test/util/LuceneGlobalFixture.cpp +++ b/src/test/util/LuceneGlobalFixture.cpp @@ -12,13 +12,13 @@ namespace Lucene { -LuceneGlobalFixture::LuceneGlobalFixture() { +void LuceneGlobalFixture::SetUp() { FileUtils::removeDirectory(getTempDir()); FileUtils::createDirectory(getTempDir()); TestPoint::enableTestPoints(); } -LuceneGlobalFixture::~LuceneGlobalFixture() { +void LuceneGlobalFixture::TearDown() { FileUtils::removeDirectory(getTempDir()); Lucene::CycleCheck::dumpRefs(); } From c32e5609b6bcf5591d5d510156fb82cc6c242fba Mon Sep 17 00:00:00 2001 From: Alan Wright Date: Fri, 14 Aug 2015 12:38:14 +0100 Subject: [PATCH 099/157] Make use of boost integer types optional. Closes #55. --- CMakeLists.txt | 10 ++++++++++ include/Config.h.cmake | 3 +++ include/Lucene.h | 14 ++++---------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af3c078c..e63c59d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,10 @@ option(LUCENE_USE_STATIC_BOOST_LIBS "Use static boost libraries" OFF ) +option(ENABLE_BOOST_INTEGER + "Enable boost integer types" + OFF +) option(ENABLE_CYCLIC_CHECK "Enable cyclic checking" OFF @@ -88,6 +92,12 @@ set(LIB_DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" CACHE STRING "Define lib output directory name" ) +if(ENABLE_BOOST_INTEGER) + set(DEFINE_USE_BOOST_INTEGER "define") +else() + set(DEFINE_USE_BOOST_INTEGER "undef") +endif() + if(ENABLE_CYCLIC_CHECK) set(DEFINE_USE_CYCLIC_CHECK "define") else() diff --git a/include/Config.h.cmake b/include/Config.h.cmake index f716a4ed..203fec3e 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -17,6 +17,9 @@ #endif #endif +// Define to enable boost integer types +#@DEFINE_USE_BOOST_INTEGER@ LPP_USE_BOOST_INTEGER + #if defined(_WIN32) || defined(_WIN64) #define LPP_IMPORT __declspec(dllimport) #define LPP_EXPORT __declspec(dllexport) diff --git a/include/Lucene.h b/include/Lucene.h index 9427bffb..358a5809 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -18,28 +18,22 @@ #include #include +#ifdef LPP_USE_BOOST_INTEGER #include +#endif + #include #include #include #include -#ifndef int8_t +#ifdef LPP_USE_BOOST_INTEGER using boost::int8_t; using boost::uint8_t; -#endif - -#ifndef int16_t using boost::int16_t; using boost::uint16_t; -#endif - -#ifndef int32_t using boost::int32_t; using boost::uint32_t; -#endif - -#ifndef int64_t using boost::int64_t; using boost::uint64_t; #endif From f93136ee98fcc618169c55d91ce253a0c37710a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20B=C3=B6hn=20/=20FI=24H2k?= Date: Fri, 14 Aug 2015 19:01:57 -0400 Subject: [PATCH 100/157] Link against `libboost_system` when building demo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Added `cmake_minimum_required()` statement at the top of CMakeLists.txt (as per verbose development output from `cmake`) • Added call to `find_package()` to find Boost • Specified `boost_system` in all calls to `target_link_libraries()` --- src/demo/CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/demo/CMakeLists.txt b/src/demo/CMakeLists.txt index fd1e0eea..ee7538ab 100644 --- a/src/demo/CMakeLists.txt +++ b/src/demo/CMakeLists.txt @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.0) project(lucene++-demo) file(GLOB_RECURSE @@ -6,6 +7,7 @@ file(GLOB_RECURSE ) add_definitions(-DLPP_HAVE_DLL) +find_package(Boost REQUIRED) include_directories( ${Boost_INCLUDE_DIRS} @@ -19,7 +21,7 @@ add_executable(indexfiles ${demo_headers} ) target_link_libraries(indexfiles - lucene++ + lucene++ boost_system ) add_executable(searchfiles @@ -27,7 +29,7 @@ add_executable(searchfiles ${demo_headers} ) target_link_libraries(searchfiles - lucene++ + lucene++ boost_system ) add_executable(deletefiles @@ -35,5 +37,5 @@ add_executable(deletefiles ${demo_headers} ) target_link_libraries(deletefiles - lucene++ + lucene++ boost_system ) From 7359e95c655fa112340ca61b84fa61e8b72046e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Sat, 10 Oct 2015 17:32:48 +0200 Subject: [PATCH 101/157] Work around clang warning about side effects inside typeid() This warning is harmless here, but warnings-free build is even more harmless. --- src/core/util/MiscUtils.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/util/MiscUtils.cpp b/src/core/util/MiscUtils.cpp index 5a88722d..a50ba51d 100644 --- a/src/core/util/MiscUtils.cpp +++ b/src/core/util/MiscUtils.cpp @@ -119,7 +119,9 @@ bool MiscUtils::isNaN(double value) { } bool MiscUtils::equalTypes(const LuceneObjectPtr& first, const LuceneObjectPtr& second) { - return (typeid(*first) == typeid(*second)); + const LuceneObject& firstRef(*first); + const LuceneObject& secondRef(*second); + return (typeid(firstRef) == typeid(secondRef)); } int64_t MiscUtils::unsignedShift(int64_t num, int64_t shift) { From 96e9cee10d70eb7d8bdcb3a00e09424af4d8995b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Wed, 23 Mar 2016 17:21:25 +0100 Subject: [PATCH 102/157] Fix Visual Studio 2015 warnings --- src/core/util/Base64.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/util/Base64.cpp b/src/core/util/Base64.cpp index 8262baa8..be00413b 100644 --- a/src/core/util/Base64.cpp +++ b/src/core/util/Base64.cpp @@ -77,7 +77,7 @@ ByteArray Base64::decode(const String& str) { byteArray4[i++] = (uint8_t)str[charIndex++]; if (i == 4) { for (i = 0; i < 4; ++i) { - byteArray4[i] = BASE64_CHARS.find(byteArray4[i]); + byteArray4[i] = static_cast(BASE64_CHARS.find(byteArray4[i])); } byteArray3[0] = (byteArray4[0] << 2) + ((byteArray4[1] & 0x30) >> 4); byteArray3[1] = ((byteArray4[1] & 0xf) << 4) + ((byteArray4[2] & 0x3c) >> 2); @@ -99,7 +99,7 @@ ByteArray Base64::decode(const String& str) { byteArray4[j] = 0; } for (int32_t j = 0; j < 4; ++j) { - byteArray4[j] = BASE64_CHARS.find(byteArray4[j]); + byteArray4[j] = static_cast(BASE64_CHARS.find(byteArray4[j])); } byteArray3[0] = (byteArray4[0] << 2) + ((byteArray4[1] & 0x30) >> 4); byteArray3[1] = ((byteArray4[1] & 0xf) << 4) + ((byteArray4[2] & 0x3c) >> 2); From 1cdc36dca819c8901516ab85293767c0efbfa593 Mon Sep 17 00:00:00 2001 From: sravan rekula Date: Fri, 18 Aug 2017 12:49:27 -0700 Subject: [PATCH 103/157] add scorer visitor interface --- include/Scorer.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/include/Scorer.h b/include/Scorer.h index bb9fd92b..456609cc 100644 --- a/include/Scorer.h +++ b/include/Scorer.h @@ -8,8 +8,19 @@ #define SCORER_H #include "DocIdSetIterator.h" +#include "BooleanClause.h" +#include "Weight.h" namespace Lucene { + + + class LPPAPI ScorerVisitor{ + public: + virtual void visitOptional(QueryPtr parent,QueryPtr child,ScorerPtr scorer)=0; + virtual void visitRequired(QueryPtr parent,QueryPtr child,ScorerPtr scorer)=0; + virtual void visitProhibited(QueryPtr parent,QueryPtr child,ScorerPtr scorer)=0; + + }; /// Common scoring functionality for different types of queries. /// @@ -24,9 +35,11 @@ class LPPAPI Scorer : public DocIdSetIterator { /// Constructs a Scorer. /// @param similarity The Similarity implementation used by this scorer. Scorer(const SimilarityPtr& similarity); + Scorer(const WeightPtr& weight); virtual ~Scorer(); LUCENE_CLASS(Scorer); + WeightPtr weight; protected: SimilarityPtr similarity; @@ -43,6 +56,15 @@ class LPPAPI Scorer : public DocIdSetIterator { /// #nextDoc()} or {@link #advance(int32_t)} is called the first time, or when called from within /// {@link Collector#collect}. virtual double score() = 0; + + void visitSubScorers(QueryPtr parent, BooleanClause::Occur relationship, + ScorerVisitor *visitor); + + void visitScorers(ScorerVisitor *visitor); + + virtual float term_freq(){ + boost::throw_exception(RuntimeException(L"Freq not implemented")); + } protected: /// Collects matching documents in a range. Hook for optimization. @@ -57,6 +79,7 @@ class LPPAPI Scorer : public DocIdSetIterator { friend class BooleanScorer; friend class ScoreCachingWrappingScorer; }; + } From 0e94cff7381de0fa63811ea3a69f21e1135d784c Mon Sep 17 00:00:00 2001 From: sravan rekula Date: Fri, 18 Aug 2017 12:50:26 -0700 Subject: [PATCH 104/157] implement scorer visitor --- src/core/search/Scorer.cpp | 86 +++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 29 deletions(-) diff --git a/src/core/search/Scorer.cpp b/src/core/search/Scorer.cpp index db649a95..20ea35d6 100644 --- a/src/core/search/Scorer.cpp +++ b/src/core/search/Scorer.cpp @@ -9,34 +9,62 @@ #include "Collector.h" namespace Lucene { - -Scorer::Scorer(const SimilarityPtr& similarity) { - this->similarity = similarity; -} - -Scorer::~Scorer() { -} - -SimilarityPtr Scorer::getSimilarity() { - return similarity; -} - -void Scorer::score(const CollectorPtr& collector) { - collector->setScorer(shared_from_this()); - int32_t doc; - while ((doc = nextDoc()) != NO_MORE_DOCS) { - collector->collect(doc); + + Scorer::Scorer(const SimilarityPtr& similarity) { + this->similarity = similarity; } -} - -bool Scorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { - collector->setScorer(shared_from_this()); - int32_t doc = firstDocID; - while (doc < max) { - collector->collect(doc); - doc = nextDoc(); - } - return (doc != NO_MORE_DOCS); -} - + + Scorer::Scorer(const WeightPtr& weight) { + this->weight = weight; + } + + Scorer::~Scorer() { + } + + SimilarityPtr Scorer::getSimilarity() { + return similarity; + } + + void Scorer::score(const CollectorPtr& collector) { + collector->setScorer(shared_from_this()); + int32_t doc; + while ((doc = nextDoc()) != NO_MORE_DOCS) { + collector->collect(doc); + } + } + + bool Scorer::score(const CollectorPtr& collector, int32_t max, int32_t firstDocID) { + collector->setScorer(shared_from_this()); + int32_t doc = firstDocID; + while (doc < max) { + collector->collect(doc); + doc = nextDoc(); + } + return (doc != NO_MORE_DOCS); + } + + void Scorer::visitSubScorers(QueryPtr parent, BooleanClause::Occur relationship, + ScorerVisitor *visitor){ + QueryPtr q = weight->getQuery(); + switch (relationship) { + case BooleanClause::MUST: + visitor->visitRequired(parent, q, shared_from_this()); + break; + case BooleanClause::MUST_NOT: + visitor->visitProhibited(parent, q, shared_from_this()); + break; + case BooleanClause::SHOULD: + visitor->visitOptional(parent, q, shared_from_this()); + break; + } + } + + void Scorer::visitScorers(ScorerVisitor *visitor) { + boost::shared_ptr s_obj; + + visitSubScorers(s_obj, BooleanClause::MUST/*must id default*/, visitor); + } + + + } From ed8643247325267eacc40ae56d13079eb7885b2b Mon Sep 17 00:00:00 2001 From: sravan rekula Date: Fri, 18 Aug 2017 12:51:18 -0700 Subject: [PATCH 105/157] add frequencies to scorers --- include/BooleanScorer.h | 8 ++++++++ include/PhraseScorer.h | 5 ++++- include/SpanScorer.h | 3 +++ include/TermScorer.h | 8 ++++++++ src/core/search/BooleanScorer.cpp | 1 + src/core/search/TermScorer.cpp | 11 +++++++---- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/include/BooleanScorer.h b/include/BooleanScorer.h index fa02a9d8..0fb454c9 100644 --- a/include/BooleanScorer.h +++ b/include/BooleanScorer.h @@ -33,6 +33,7 @@ class BooleanScorer : public Scorer { virtual ~BooleanScorer(); LUCENE_CLASS(BooleanScorer); + protected: SubScorerPtr scorers; @@ -58,6 +59,7 @@ class BooleanScorer : public Scorer { virtual double score(); virtual void score(const CollectorPtr& collector); virtual String toString(); + }; class BooleanScorerCollector : public Collector { @@ -87,7 +89,13 @@ class BucketScorer : public Scorer { BucketScorer(); virtual ~BucketScorer(); + + int32_t freq; LUCENE_CLASS(BucketScorer); + float term_freq(){ + return freq; + } + public: double _score; diff --git a/include/PhraseScorer.h b/include/PhraseScorer.h index 2b5c64f4..83be14b1 100644 --- a/include/PhraseScorer.h +++ b/include/PhraseScorer.h @@ -46,7 +46,10 @@ class PhraseScorer : public Scorer { /// Phrase frequency in current doc as computed by phraseFreq(). double currentFreq(); - + float term_freq(){ + return currentFreq(); + } + virtual String toString(); protected: diff --git a/include/SpanScorer.h b/include/SpanScorer.h index 69274aff..fc236ba6 100644 --- a/include/SpanScorer.h +++ b/include/SpanScorer.h @@ -33,6 +33,9 @@ class LPPAPI SpanScorer : public Scorer { virtual int32_t advance(int32_t target); virtual int32_t docID(); virtual double score(); + virtual float term_freq(){ + return freq; + } protected: virtual bool setFreqCurrentDoc(); diff --git a/include/TermScorer.h b/include/TermScorer.h index 5dbc2638..45fdb2d6 100644 --- a/include/TermScorer.h +++ b/include/TermScorer.h @@ -34,11 +34,15 @@ class TermScorer : public Scorer { Collection docs; // buffered doc numbers Collection freqs; // buffered term freqs + + int32_t freq; int32_t pointer; int32_t pointerMax; static const int32_t SCORE_CACHE_SIZE; Collection scoreCache; + + public: virtual void score(const CollectorPtr& collector); @@ -60,6 +64,10 @@ class TermScorer : public Scorer { /// Returns a string representation of this TermScorer. virtual String toString(); + + virtual float term_freq(){ + return freq; + } protected: static const Collection SIM_NORM_DECODER(); diff --git a/src/core/search/BooleanScorer.cpp b/src/core/search/BooleanScorer.cpp index 6dea82c2..8de17dd1 100644 --- a/src/core/search/BooleanScorer.cpp +++ b/src/core/search/BooleanScorer.cpp @@ -73,6 +73,7 @@ bool BooleanScorer::score(const CollectorPtr& collector, int32_t max, int32_t fi if (current->coord >= minNrShouldMatch) { bs->_score = current->score * coordFactors[current->coord]; bs->doc = current->doc; + bs->freq = current->coord; collector->collect(current->doc); } } diff --git a/src/core/search/TermScorer.cpp b/src/core/search/TermScorer.cpp index 678da9d6..310fe2a8 100644 --- a/src/core/search/TermScorer.cpp +++ b/src/core/search/TermScorer.cpp @@ -60,6 +60,7 @@ bool TermScorer::score(const CollectorPtr& collector, int32_t max, int32_t first } } doc = docs[pointer]; + freq = freqs[pointer]; } return true; } @@ -81,13 +82,14 @@ int32_t TermScorer::nextDoc() { } } doc = docs[pointer]; + freq = freqs[pointer]; + return doc; } double TermScorer::score() { BOOST_ASSERT(doc != -1); - int32_t f = freqs[pointer]; - double raw = f < SCORE_CACHE_SIZE ? scoreCache[f] : getSimilarity()->tf(f) * weightValue; // compute tf(f) * weight + double raw = freq < SCORE_CACHE_SIZE ? scoreCache[freq] : getSimilarity()->tf(freq) * weightValue; // compute tf(f) * weight return norms ? raw * SIM_NORM_DECODER()[norms[doc] & 0xff] : raw; // normalize for field } @@ -96,6 +98,7 @@ int32_t TermScorer::advance(int32_t target) { for (++pointer; pointer < pointerMax; ++pointer) { if (docs[pointer] >= target) { doc = docs[pointer]; + freq = freqs[pointer]; return doc; } } @@ -107,7 +110,7 @@ int32_t TermScorer::advance(int32_t target) { pointer = 0; doc = termDocs->doc(); docs[pointer] = doc; - freqs[pointer] = termDocs->freq(); + freqs[pointer] = freq = termDocs->freq(); } else { doc = NO_MORE_DOCS; } @@ -115,7 +118,7 @@ int32_t TermScorer::advance(int32_t target) { } String TermScorer::toString() { - return L"scorer(" + weight->toString() + L")"; + return L"term scorer(" + weight->toString() + L")"; } } From 763bddeb19711022eb9cb66fe9da452f3ce119c4 Mon Sep 17 00:00:00 2001 From: sravan rekula Date: Sat, 10 Feb 2018 14:51:27 -0800 Subject: [PATCH 106/157] rename term_freq -> termFreq --- include/BooleanScorer.h | 2 +- include/PhraseScorer.h | 2 +- include/Scorer.h | 2 +- include/SpanScorer.h | 2 +- include/TermScorer.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/BooleanScorer.h b/include/BooleanScorer.h index 0fb454c9..fd1e0d93 100644 --- a/include/BooleanScorer.h +++ b/include/BooleanScorer.h @@ -92,7 +92,7 @@ class BucketScorer : public Scorer { int32_t freq; LUCENE_CLASS(BucketScorer); - float term_freq(){ + float termFreq(){ return freq; } diff --git a/include/PhraseScorer.h b/include/PhraseScorer.h index 83be14b1..09a4938a 100644 --- a/include/PhraseScorer.h +++ b/include/PhraseScorer.h @@ -46,7 +46,7 @@ class PhraseScorer : public Scorer { /// Phrase frequency in current doc as computed by phraseFreq(). double currentFreq(); - float term_freq(){ + float termFreq(){ return currentFreq(); } diff --git a/include/Scorer.h b/include/Scorer.h index 456609cc..181ac392 100644 --- a/include/Scorer.h +++ b/include/Scorer.h @@ -62,7 +62,7 @@ class LPPAPI Scorer : public DocIdSetIterator { void visitScorers(ScorerVisitor *visitor); - virtual float term_freq(){ + virtual float termFreq(){ boost::throw_exception(RuntimeException(L"Freq not implemented")); } diff --git a/include/SpanScorer.h b/include/SpanScorer.h index fc236ba6..a8685645 100644 --- a/include/SpanScorer.h +++ b/include/SpanScorer.h @@ -33,7 +33,7 @@ class LPPAPI SpanScorer : public Scorer { virtual int32_t advance(int32_t target); virtual int32_t docID(); virtual double score(); - virtual float term_freq(){ + virtual float termFreq(){ return freq; } diff --git a/include/TermScorer.h b/include/TermScorer.h index 45fdb2d6..05866586 100644 --- a/include/TermScorer.h +++ b/include/TermScorer.h @@ -65,7 +65,7 @@ class TermScorer : public Scorer { /// Returns a string representation of this TermScorer. virtual String toString(); - virtual float term_freq(){ + virtual float termFreq(){ return freq; } From 885ba746858c86d588895d705002ff7a343403f3 Mon Sep 17 00:00:00 2001 From: Xiaolong Zheng Date: Mon, 12 Nov 2018 11:58:40 -0500 Subject: [PATCH 107/157] * update cotire.cmake \n * fix header includes \n * fix the boost linker error --- cmake/cotire.cmake | 1987 +++++++++++------ include/Lucene.h | 4 +- src/demo/CMakeLists.txt | 6 +- .../include/gtest/internal/gtest-internal.h | 6 +- 4 files changed, 1321 insertions(+), 682 deletions(-) diff --git a/cmake/cotire.cmake b/cmake/cotire.cmake index d855c1d4..9a4982d4 100644 --- a/cmake/cotire.cmake +++ b/cmake/cotire.cmake @@ -3,7 +3,7 @@ # See the cotire manual for usage hints. # #============================================================================= -# Copyright 2012-2014 Sascha Kratky +# Copyright 2012-2018 Sascha Kratky # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -37,51 +37,96 @@ set(__COTIRE_INCLUDED TRUE) if (NOT CMAKE_SCRIPT_MODE_FILE) cmake_policy(PUSH) endif() -# we need the CMake variables CMAKE_SCRIPT_MODE_FILE and CMAKE_ARGV available since 2.8.5 -# we need APPEND_STRING option for set_property available since 2.8.6 -cmake_minimum_required(VERSION 2.8.6) +cmake_minimum_required(VERSION 2.8.12) if (NOT CMAKE_SCRIPT_MODE_FILE) cmake_policy(POP) endif() set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.6.6") +set (COTIRE_CMAKE_MODULE_VERSION "1.8.0") + +# activate select policies +if (POLICY CMP0025) + # Compiler id for Apple Clang is now AppleClang + cmake_policy(SET CMP0025 NEW) +endif() + +if (POLICY CMP0026) + # disallow use of the LOCATION target property + cmake_policy(SET CMP0026 NEW) +endif() + +if (POLICY CMP0038) + # targets may not link directly to themselves + cmake_policy(SET CMP0038 NEW) +endif() + +if (POLICY CMP0039) + # utility targets may not have link dependencies + cmake_policy(SET CMP0039 NEW) +endif() + +if (POLICY CMP0040) + # target in the TARGET signature of add_custom_command() must exist + cmake_policy(SET CMP0040 NEW) +endif() + +if (POLICY CMP0045) + # error on non-existent target in get_target_property + cmake_policy(SET CMP0045 NEW) +endif() + +if (POLICY CMP0046) + # error on non-existent dependency in add_dependencies + cmake_policy(SET CMP0046 NEW) +endif() + +if (POLICY CMP0049) + # do not expand variables in target source entries + cmake_policy(SET CMP0049 NEW) +endif() + +if (POLICY CMP0050) + # disallow add_custom_command SOURCE signatures + cmake_policy(SET CMP0050 NEW) +endif() + +if (POLICY CMP0051) + # include TARGET_OBJECTS expressions in a target's SOURCES property + cmake_policy(SET CMP0051 NEW) +endif() + +if (POLICY CMP0053) + # simplify variable reference and escape sequence evaluation + cmake_policy(SET CMP0053 NEW) +endif() + +if (POLICY CMP0054) + # only interpret if() arguments as variables or keywords when unquoted + cmake_policy(SET CMP0054 NEW) +endif() + +if (POLICY CMP0055) + # strict checking for break() command + cmake_policy(SET CMP0055 NEW) +endif() include(CMakeParseArguments) include(ProcessorCount) -function (cotire_determine_compiler_version _language _versionPrefix) - if (NOT ${_versionPrefix}_VERSION) - # use CMake's predefined compiler version variable (available since CMake 2.8.8) - if (DEFINED CMAKE_${_language}_COMPILER_VERSION) - set (${_versionPrefix}_VERSION "${CMAKE_${_language}_COMPILER_VERSION}") - elseif (WIN32) - # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared - unset (ENV{VS_UNICODE_OUTPUT}) - string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) - execute_process ( - COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} - ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10) - string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}") - else() - # assume GCC like command line interface - string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) - execute_process ( - COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion" - OUTPUT_VARIABLE ${_versionPrefix}_VERSION - RESULT_VARIABLE _result - OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10) - if (_result) - set (${_versionPrefix}_VERSION "") - endif() - endif() - if (${_versionPrefix}_VERSION) - set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" CACHE INTERNAL "${_language} compiler version") - endif() - set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" PARENT_SCOPE) - if (COTIRE_DEBUG) - message (STATUS "${CMAKE_${_language}_COMPILER} version ${${_versionPrefix}_VERSION}") - endif() +function (cotire_get_configuration_types _configsVar) + set (_configs "") + if (CMAKE_CONFIGURATION_TYPES) + list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES}) + endif() + if (CMAKE_BUILD_TYPE) + list (APPEND _configs "${CMAKE_BUILD_TYPE}") + endif() + if (_configs) + list (REMOVE_DUPLICATES _configs) + set (${_configsVar} ${_configs} PARENT_SCOPE) + else() + set (${_configsVar} "None" PARENT_SCOPE) endif() endfunction() @@ -111,10 +156,7 @@ macro (cotire_check_is_path_relative_to _path _isRelativeVar) endif() endmacro() -function (cotire_filter_language_source_files _language _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) - set (_sourceFiles "") - set (_excludedSourceFiles "") - set (_cotiredSourceFiles "") +function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") else() @@ -130,17 +172,29 @@ function (cotire_filter_language_source_files _language _sourceFilesVar _exclude else() set (_excludeExtensions "") endif() - if (COTIRE_DEBUG) + if (COTIRE_DEBUG AND _languageExtensions) message (STATUS "${_language} source file extensions: ${_languageExtensions}") + endif() + if (COTIRE_DEBUG AND _ignoreExtensions) message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") + endif() + if (COTIRE_DEBUG AND _excludeExtensions) message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") endif() - foreach (_sourceFile ${ARGN}) + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_allSourceFiles ${ARGN}) + else() + # as of CMake 3.1 target sources may contain generator expressions + # since we cannot obtain required property information about source files added + # through generator expressions at configure time, we filter them out + string (GENEX_STRIP "${ARGN}" _allSourceFiles) + endif() + set (_filteredSourceFiles "") + set (_excludedSourceFiles "") + foreach (_sourceFile ${_allSourceFiles}) get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) - get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) - set (_sourceIsFiltered FALSE) if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) cotire_get_source_file_extension("${_sourceFile}" _sourceExt) if (_sourceExt) @@ -152,39 +206,59 @@ function (cotire_filter_language_source_files _language _sourceFilesVar _exclude else() list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) if (_sourceIndex GREATER -1) - set (_sourceIsFiltered TRUE) - elseif ("${_sourceLanguage}" STREQUAL "${_language}") - # add to excluded sources, if file is not ignored and has correct language without having the correct extension - list (APPEND _excludedSourceFiles "${_sourceFile}") + # consider source file unless it is excluded explicitly + get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) + if (_sourceIsExcluded) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _filteredSourceFiles "${_sourceFile}") + endif() + else() + get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) + if ("${_sourceLanguage}" STREQUAL "${_language}") + # add to excluded sources, if file is not ignored and has correct language without having the correct extension + list (APPEND _excludedSourceFiles "${_sourceFile}") + endif() endif() endif() endif() endif() endif() - if (COTIRE_DEBUG) - message (STATUS "${_sourceFile} filtered=${_sourceIsFiltered} language=${_sourceLanguage} header=${_sourceIsHeaderOnly}") - endif() - if (_sourceIsFiltered) - get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) - get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) + endforeach() + # separate filtered source files from already cotired ones + # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire + set (_sourceFiles "") + set (_cotiredSourceFiles "") + foreach (_sourceFile ${_filteredSourceFiles}) + get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) + if (_sourceIsCotired) + list (APPEND _cotiredSourceFiles "${_sourceFile}") + else() get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) - if (COTIRE_DEBUG) - message (STATUS "${_sourceFile} excluded=${_sourceIsExcluded} cotired=${_sourceIsCotired} compileFlags=${_sourceCompileFlags}") - endif() - if (_sourceIsCotired) - list (APPEND _cotiredSourceFiles "${_sourceFile}") - elseif (_sourceIsExcluded OR _sourceCompileFlags) + if (_sourceCompileFlags) + # add to excluded sources, if file has custom compile flags list (APPEND _excludedSourceFiles "${_sourceFile}") else() - list (APPEND _sourceFiles "${_sourceFile}") + get_source_file_property(_sourceCompileOptions "${_sourceFile}" COMPILE_OPTIONS) + if (_sourceCompileOptions) + # add to excluded sources, if file has list of custom compile options + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _sourceFiles "${_sourceFile}") + endif() endif() endif() endforeach() if (COTIRE_DEBUG) - message (STATUS "All: ${ARGN}") - message (STATUS "${_language}: ${_sourceFiles}") - message (STATUS "Excluded: ${_excludedSourceFiles}") - message (STATUS "Cotired: ${_cotiredSourceFiles}") + if (_sourceFiles) + message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}") + endif() + if (_excludedSourceFiles) + message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}") + endif() + if (_cotiredSourceFiles) + message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}") + endif() endif() set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) @@ -230,7 +304,7 @@ function (cotire_get_source_file_property_values _valuesVar _property) set (${_valuesVar} ${_values} PARENT_SCOPE) endfunction() -function (cotire_resolve_config_properites _configurations _propertiesVar) +function (cotire_resolve_config_properties _configurations _propertiesVar) set (_properties "") foreach (_property ${ARGN}) if ("${_property}" MATCHES "") @@ -246,8 +320,8 @@ function (cotire_resolve_config_properites _configurations _propertiesVar) set (${_propertiesVar} ${_properties} PARENT_SCOPE) endfunction() -function (cotire_copy_set_properites _configurations _type _source _target) - cotire_resolve_config_properites("${_configurations}" _properties ${ARGN}) +function (cotire_copy_set_properties _configurations _type _source _target) + cotire_resolve_config_properties("${_configurations}" _properties ${ARGN}) foreach (_property ${_properties}) get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) if (_isSet) @@ -257,26 +331,32 @@ function (cotire_copy_set_properites _configurations _type _source _target) endforeach() endfunction() -function (cotire_get_target_link_libraries_for_usage_requirements _target _targetLinkLibrariesVar) - set (_targetLinkLibraries "") +function (cotire_get_target_usage_requirements _target _config _targetRequirementsVar) + set (_targetRequirements "") get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) while (_librariesToProcess) # remove from head list (GET _librariesToProcess 0 _library) list (REMOVE_AT _librariesToProcess 0) - list (FIND _targetLinkLibraries ${_library} _index) - if (_index LESS 0) - list (APPEND _targetLinkLibraries ${_library}) - # process transitive libraries - if (TARGET ${_library}) + if (_library MATCHES "^\\$<\\$:([A-Za-z0-9_:-]+)>$") + set (_library "${CMAKE_MATCH_1}") + elseif (_config STREQUAL "None" AND _library MATCHES "^\\$<\\$:([A-Za-z0-9_:-]+)>$") + set (_library "${CMAKE_MATCH_1}") + endif() + if (TARGET ${_library}) + list (FIND _targetRequirements ${_library} _index) + if (_index LESS 0) + list (APPEND _targetRequirements ${_library}) + # BFS traversal of transitive libraries get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) if (_libraries) list (APPEND _librariesToProcess ${_libraries}) + list (REMOVE_DUPLICATES _librariesToProcess) endif() endif() endif() endwhile() - set (${_targetLinkLibrariesVar} ${_targetLinkLibraries} PARENT_SCOPE) + set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE) endfunction() function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) @@ -315,20 +395,35 @@ function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _ if (_optionFlag) list (APPEND _matchedOptions "${_optionFlag}") endif() - if (COTIRE_DEBUG) - message (STATUS "Filter ${_flagFilter}") - if (_matchedOptions) - message (STATUS "Matched ${_matchedOptions}") - endif() - if (_unmatchedOptions) - message (STATUS "Unmatched ${_unmatchedOptions}") - endif() + if (COTIRE_DEBUG AND _matchedOptions) + message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}") + endif() + if (COTIRE_DEBUG AND _unmatchedOptions) + message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}") endif() set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) endfunction() -function (cotire_get_target_compile_flags _config _language _directory _target _flagsVar) +function (cotire_is_target_supported _target _isSupportedVar) + if (NOT TARGET "${_target}") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_imported ${_target} IMPORTED) + if (_imported) + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_targetType ${_target} TYPE) + if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + set (${_isSupportedVar} TRUE PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_flags _config _language _target _flagsVar) string (TOUPPER "${_config}" _upperConfig) # collect options from CMake language variables set (_compileFlags "") @@ -339,67 +434,11 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") endif() if (_target) - # add option from CMake target type variable - get_target_property(_targetType ${_target} TYPE) - if (POLICY CMP0018) - # handle POSITION_INDEPENDENT_CODE property introduced with CMake 2.8.9 if policy CMP0018 is turned on - cmake_policy(GET CMP0018 _PIC_Policy) - else() - # default to old behavior - set (_PIC_Policy "OLD") - endif() - if (COTIRE_DEBUG) - message(STATUS "CMP0018=${_PIC_Policy}") - endif() - if (_PIC_Policy STREQUAL "NEW") - # NEW behavior: honor the POSITION_INDEPENDENT_CODE target property - get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) - if (_targetPIC) - if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) - set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") - elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) - set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") - endif() - endif() - else() - # OLD behavior or policy not set: use the value of CMAKE_SHARED_LIBRARY__FLAGS - if (_targetType STREQUAL "MODULE_LIBRARY") - # flags variable for module library uses different name SHARED_MODULE - # (e.g., CMAKE_SHARED_MODULE_C_FLAGS) - set (_targetType SHARED_MODULE) - endif() - if (CMAKE_${_targetType}_${_language}_FLAGS) - set (_compileFlags "${_compileFlags} ${CMAKE_${_targetType}_${_language}_FLAGS}") - endif() - endif() - endif() - if (_directory) - # add_definitions may have been used to add flags to the compiler command - get_directory_property(_dirDefinitions DIRECTORY "${_directory}" DEFINITIONS) - if (_dirDefinitions) - set (_compileFlags "${_compileFlags} ${_dirDefinitions}") - endif() - endif() - if (_target) - # add target compile options + # add target compile flags get_target_property(_targetflags ${_target} COMPILE_FLAGS) if (_targetflags) set (_compileFlags "${_compileFlags} ${_targetflags}") endif() - get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) - if (_targetOptions) - set (_compileFlags "${_compileFlags} ${_targetOptions}") - endif() - # interface compile options from linked library targets - cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) - foreach (_library ${_linkLibraries}) - if (TARGET ${_library}) - get_target_property(_targetOptions ${_library} INTERFACE_COMPILE_OPTIONS) - if (_targetOptions) - set (_compileFlags "${_compileFlags} ${_targetOptions}") - endif() - endif() - endforeach() endif() if (UNIX) separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") @@ -408,6 +447,67 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ else() separate_arguments(_compileFlags) endif() + # target compile options + if (_target) + get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endif() + # interface compile options from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endforeach() + endif() + # handle language standard properties + if (CMAKE_${_language}_STANDARD_DEFAULT) + # used compiler supports language standard levels + if (_target) + get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD) + if (_targetLanguageStandard) + set (_type "EXTENSION") + get_property(_isSet TARGET ${_target} PROPERTY ${_language}_EXTENSIONS SET) + if (_isSet) + get_target_property(_targetUseLanguageExtensions ${_target} ${_language}_EXTENSIONS) + if (NOT _targetUseLanguageExtensions) + set (_type "STANDARD") + endif() + endif() + if (CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION) + list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION}") + endif() + endif() + endif() + endif() + # handle the POSITION_INDEPENDENT_CODE target property + if (_target) + get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) + if (_targetPIC) + get_target_property(_targetType ${_target} TYPE) + if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") + elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") + endif() + endif() + endif() + # handle visibility target properties + if (_target) + get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET) + if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}") + endif() + get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN) + if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}") + endif() + endif() # platform specific flags if (APPLE) get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) @@ -435,28 +535,47 @@ function (cotire_get_target_compile_flags _config _language _directory _target _ endif() endif() if (COTIRE_DEBUG AND _compileFlags) - message (STATUS "Target ${_target} compile flags ${_compileFlags}") + message (STATUS "Target ${_target} compile flags: ${_compileFlags}") endif() set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) endfunction() -function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar _systemIncludeDirsVar) +function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar) set (_includeDirs "") set (_systemIncludeDirs "") # default include dirs if (CMAKE_INCLUDE_CURRENT_DIR) - list (APPEND _includeDirs "${_targetBinaryDir}") - list (APPEND _includeDirs "${_targetSourceDir}") + list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}") + list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}") endif() - # parse additional include directories from target compile flags set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags) - cotire_filter_compile_flags("${_language}" "I" _dirs _ignore ${_targetFlags}) - if (_dirs) - list (APPEND _includeDirs ${_dirs}) + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + # parse additional include directories from target compile flags + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _includeDirs ${_dirs}) + endif() + endif() + endif() + # parse additional system include directories from target compile flags + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _systemIncludeDirs ${_dirs}) + endif() + endif() endif() # target include directories - get_directory_property(_dirs DIRECTORY "${_targetSourceDir}" INCLUDE_DIRECTORIES) + get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES) if (_target) get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) if (_targetDirs) @@ -466,20 +585,35 @@ function (cotire_get_target_include_directories _config _language _targetSourceD if (_targetDirs) list (APPEND _systemIncludeDirs ${_targetDirs}) endif() - - # interface include directories from linked library targets - cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) - foreach (_library ${_linkLibraries}) - if (TARGET ${_library}) - get_target_property(_targetDirs ${_library} INTERFACE_INCLUDE_DIRECTORIES) + endif() + # interface include directories from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_linkedTargetType ${_linkedTarget} TYPE) + if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND + _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR + # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR + # which are only available with CMake 3.4 or later. + get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR) if (_targetDirs) list (APPEND _dirs ${_targetDirs}) endif() - get_target_property(_targetDirs ${_library} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR) if (_targetDirs) - list (APPEND _systemIncludeDirs ${_targetDirs}) + list (APPEND _dirs ${_targetDirs}) endif() endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() endforeach() endif() if (dirs) @@ -509,28 +643,35 @@ function (cotire_get_target_include_directories _config _language _targetSourceD if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) endif() + if (WIN32 AND NOT MINGW) + # convert Windows paths in include directories to CMake paths + if (_includeDirs) + set (_paths "") + foreach (_dir ${_includeDirs}) + file (TO_CMAKE_PATH "${_dir}" _path) + list (APPEND _paths "${_path}") + endforeach() + set (_includeDirs ${_paths}) + endif() + if (_systemIncludeDirs) + set (_paths "") + foreach (_dir ${_systemIncludeDirs}) + file (TO_CMAKE_PATH "${_dir}" _path) + list (APPEND _paths "${_path}") + endforeach() + set (_systemIncludeDirs ${_paths}) + endif() + endif() if (COTIRE_DEBUG AND _includeDirs) - message (STATUS "Target ${_target} include dirs ${_includeDirs}") + message (STATUS "Target ${_target} include dirs: ${_includeDirs}") endif() set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) if (COTIRE_DEBUG AND _systemIncludeDirs) - message (STATUS "Target ${_target} system include dirs ${_systemIncludeDirs}") + message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}") endif() set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) endfunction() -macro (cotire_make_C_identifier _identifierVar _str) - if (CMAKE_VERSION VERSION_LESS "2.8.12") - # mimic CMake SystemTools::MakeCindentifier behavior - if ("${_str}" MATCHES "^[0-9].+$") - set (_str "_${str}") - endif() - string (REGEX REPLACE "[^a-zA-Z0-9]" "_" ${_identifierVar} "${_str}") - else() - string (MAKE_C_IDENTIFIER "${_str}" "${_identifierVar}") - endif() -endmacro() - function (cotire_get_target_export_symbol _target _exportSymbolVar) set (_exportSymbol "") get_target_property(_targetType ${_target} TYPE) @@ -541,12 +682,12 @@ function (cotire_get_target_export_symbol _target _exportSymbolVar) if (NOT _exportSymbol) set (_exportSymbol "${_target}_EXPORTS") endif() - cotire_make_C_identifier(_exportSymbol "${_exportSymbol}") + string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol) endif() set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) endfunction() -function (cotire_get_target_compile_definitions _config _language _directory _target _definitionsVar) +function (cotire_get_target_compile_definitions _config _language _target _definitionsVar) string (TOUPPER "${_config}" _upperConfig) set (_configDefinitions "") # CMAKE_INTDIR for multi-configuration build systems @@ -559,11 +700,11 @@ function (cotire_get_target_compile_definitions _config _language _directory _ta list (APPEND _configDefinitions "${_defineSymbol}") endif() # directory compile definitions - get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS) + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS) if (_definitions) list (APPEND _configDefinitions ${_definitions}) endif() - get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS_${_upperConfig}) + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig}) if (_definitions) list (APPEND _configDefinitions ${_definitions}) endif() @@ -577,38 +718,52 @@ function (cotire_get_target_compile_definitions _config _language _directory _ta list (APPEND _configDefinitions ${_definitions}) endif() # interface compile definitions from linked library targets - cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) - foreach (_library ${_linkLibraries}) - if (TARGET ${_library}) - get_target_property(_definitions ${_library} INTERFACE_COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) endif() endforeach() # parse additional compile definitions from target compile flags - # and don't look at directory compile definitions, which we already handled + # and do not look at directory compile definitions, which we already handled set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "" "${_target}" _targetFlags) + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) if (_definitions) list (APPEND _configDefinitions ${_definitions}) endif() list (REMOVE_DUPLICATES _configDefinitions) if (COTIRE_DEBUG AND _configDefinitions) - message (STATUS "Target ${_target} compile definitions ${_configDefinitions}") + message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}") endif() set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) endfunction() -function (cotire_get_target_compiler_flags _config _language _directory _target _compilerFlagsVar) +function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar) # parse target compile flags omitting compile definitions and include directives set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_directory}" "${_target}" _targetFlags) + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + set (_flagFilter "D") + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() set (_compilerFlags "") - cotire_filter_compile_flags("${_language}" "[ID]" _ignore _compilerFlags ${_targetFlags}) + cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags}) if (COTIRE_DEBUG AND _compilerFlags) - message (STATUS "Target ${_target} compiler flags ${_compilerFlags}") + message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}") endif() set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) endfunction() @@ -627,9 +782,6 @@ function (cotire_add_sys_root_paths _pathsVar) endif() endif() set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) - if (COTIRE_DEBUG) - message (STATUS "${_pathsVar}=${${_pathsVar}}") - endif() endfunction() function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) @@ -672,7 +824,7 @@ function (cotire_get_source_compile_definitions _config _language _sourceFile _d list (APPEND _compileDefinitions ${_definitions}) endif() if (COTIRE_DEBUG AND _compileDefinitions) - message (STATUS "Source ${_sourceFile} compile definitions ${_compileDefinitions}") + message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}") endif() set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) endfunction() @@ -701,7 +853,7 @@ function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) list (APPEND _sourceUndefs ${_undefs}) endif() if (COTIRE_DEBUG AND _sourceUndefs) - message (STATUS "Source ${_sourceFile} ${_property} undefs ${_sourceUndefs}") + message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}") endif() set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) endfunction() @@ -723,6 +875,9 @@ macro (cotire_set_cmd_to_prologue _cmdVar) list (APPEND ${_cmdVar} "--warn-uninitialized") endif() list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$") + if (XCODE) + list (APPEND ${_cmdVar} "-DXCODE:BOOL=TRUE") + endif() if (COTIRE_VERBOSE) list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") @@ -730,15 +885,26 @@ macro (cotire_set_cmd_to_prologue _cmdVar) endif() endmacro() -function (cotire_init_compile_cmd _cmdVar _language _compilerExe _compilerArg1) +function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1) + if (NOT _compilerLauncher) + set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER}) + endif() if (NOT _compilerExe) set (_compilerExe "${CMAKE_${_language}_COMPILER}") endif() if (NOT _compilerArg1) set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) endif() + if (WIN32) + file (TO_NATIVE_PATH "${_compilerExe}" _compilerExe) + endif() string (STRIP "${_compilerArg1}" _compilerArg1) - set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # compiler launcher is only supported for Makefile and Ninja + set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + else() + set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + endif() endfunction() macro (cotire_add_definitions_to_cmd _cmdVar _language) @@ -751,39 +917,66 @@ macro (cotire_add_definitions_to_cmd _cmdVar _language) endforeach() endmacro() -macro (cotire_add_includes_to_cmd _cmdVar _language _includeSystemFlag _includesVar _systemIncludesVar) - foreach (_include ${${_includesVar}}) - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - file (TO_NATIVE_PATH "${_include}" _include) - list (APPEND ${_cmdVar} "/I${_include}") - else() - list (FIND ${_systemIncludesVar} ${_include} _index) - if(_index GREATER -1 AND NOT "${_includeSystemFlag}" STREQUAL "") - list (APPEND ${_cmdVar} "${_includeSystemFlag}${_include}") +function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar) + set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}}) + if (_includeDirs) + list (REMOVE_DUPLICATES _includeDirs) + foreach (_include ${_includeDirs}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + file (TO_NATIVE_PATH "${_include}" _include) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") else() - list (APPEND ${_cmdVar} "-I${_include}") + set (_index -1) + if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+") + list (FIND ${_systemIncludesVar} "${_include}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + else() + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + endif() endif() - endif() - endforeach() -endmacro() + endforeach() + endif() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() -macro (cotire_add_frameworks_to_cmd _cmdVar _language) +function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar) if (APPLE) - set (_frameWorkDirs "") - foreach (_include ${ARGN}) + set (_frameworkDirs "") + foreach (_include ${${_includesVar}}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _frameworkDirs "${_frameworkDir}") + endif() + endforeach() + set (_systemFrameworkDirs "") + foreach (_include ${${_systemIncludesVar}}) if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") - get_filename_component(_frameWorkDir "${_include}" PATH) - list (APPEND _frameWorkDirs "${_frameWorkDir}") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _systemFrameworkDirs "${_frameworkDir}") endif() endforeach() - if (_frameWorkDirs) - list (REMOVE_DUPLICATES _frameWorkDirs) - foreach (_frameWorkDir ${_frameWorkDirs}) - list (APPEND ${_cmdVar} "-F${_frameWorkDir}") + if (_systemFrameworkDirs) + list (APPEND _frameworkDirs ${_systemFrameworkDirs}) + endif() + if (_frameworkDirs) + list (REMOVE_DUPLICATES _frameworkDirs) + foreach (_frameworkDir ${_frameworkDirs}) + set (_index -1) + if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+") + list (FIND _systemFrameworkDirs "${_frameworkDir}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + else() + list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + endif() endforeach() endif() endif() -endmacro() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() macro (cotire_add_compile_flags_to_cmd _cmdVar) foreach (_flag ${ARGN}) @@ -792,30 +985,38 @@ macro (cotire_add_compile_flags_to_cmd _cmdVar) endmacro() function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) - set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) - set (_triggerFile "") - foreach (_dependencyFile ${ARGN}) - if (EXISTS "${_dependencyFile}" AND "${_dependencyFile}" IS_NEWER_THAN "${_file}") - set (_triggerFile "${_dependencyFile}") - break() - endif() - endforeach() - get_filename_component(_fileName "${_file}" NAME) if (EXISTS "${_file}") + set (_triggerFile "") + foreach (_dependencyFile ${ARGN}) + if (EXISTS "${_dependencyFile}") + # IS_NEWER_THAN returns TRUE if both files have the same timestamp + # thus we do the comparison in both directions to exclude ties + if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND + NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}") + set (_triggerFile "${_dependencyFile}") + break() + endif() + endif() + endforeach() if (_triggerFile) if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) else() if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) message (STATUS "${_fileName} is up-to-date.") endif() set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) endif() else() if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) message (STATUS "${_fileName} does not exist yet.") endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) endif() endfunction() @@ -839,12 +1040,12 @@ macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) endforeach() endmacro() -macro (cotire_check_header_file_location _headerFile _insideIncudeDirs _outsideIncudeDirs _headerIsInside) +macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside) # check header path against ignored and honored include directories - cotire_find_closest_relative_path("${_headerFile}" "${_insideIncudeDirs}" _insideRelPath) + cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath) if (_insideRelPath) # header is inside, but could be become outside if there is a shorter outside match - cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncudeDirs}" _outsideRelPath) + cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath) if (_outsideRelPath) string (LENGTH "${_insideRelPath}" _insideRelPathLen) string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) @@ -891,12 +1092,11 @@ endmacro() macro (cotire_parse_line _line _headerFileVar _headerDepthVar) if (MSVC) - # cl.exe /showIncludes output looks different depending on the language pack used, e.g.: + # cl.exe /showIncludes produces different output, depending on the language pack used, e.g.: # English: "Note: including file: C:\directory\file" # German: "Hinweis: Einlesen der Datei: C:\directory\file" # We use a very general regular expression, relying on the presence of the : characters - if (_line MATCHES ":( +)([^:]+:[^:]+)$") - # Visual Studio compiler output + if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$") string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) else() @@ -919,7 +1119,7 @@ macro (cotire_parse_line _line _headerFileVar _headerDepthVar) endif() endmacro() -function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honoredIncudeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) +function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) if (WIN32) # prevent CMake macro invocation errors due to backslash characters in Windows paths string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") @@ -939,11 +1139,11 @@ function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honore if (_ignoredExtensions) message (STATUS "Ignored extensions: ${_ignoredExtensions}") endif() - if (_ignoredIncudeDirs) - message (STATUS "Ignored paths: ${_ignoredIncudeDirs}") + if (_ignoredIncludeDirs) + message (STATUS "Ignored paths: ${_ignoredIncludeDirs}") endif() - if (_honoredIncudeDirs) - message (STATUS "Included paths: ${_honoredIncudeDirs}") + if (_honoredIncludeDirs) + message (STATUS "Included paths: ${_honoredIncludeDirs}") endif() endif() set (_sourceFiles ${ARGN}) @@ -955,7 +1155,7 @@ function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honore if (_line) cotire_parse_line("${_line}" _headerFile _headerDepth) if (_headerFile) - cotire_check_header_file_location("${_headerFile}" "${_ignoredIncudeDirs}" "${_honoredIncudeDirs}" _headerIsInside) + cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside) if (COTIRE_DEBUG) message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") endif() @@ -1023,8 +1223,9 @@ endfunction() function (cotire_scan_includes _includesVar) set(_options "") - set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE UNPARSED_LINES) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES SCAN_RESULT) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES + IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) if (NOT _option_LANGUAGE) @@ -1033,12 +1234,14 @@ function (cotire_scan_includes _includesVar) if (NOT _option_COMPILER_ID) set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") endif() - set (_cmd "${_option_COMPILER_EXECUTABLE}" ${_option_COMPILER_ARG1}) - cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) # only consider existing source files for scanning set (_existingSourceFiles "") @@ -1051,20 +1254,28 @@ function (cotire_scan_includes _includesVar) set (${_includesVar} "" PARENT_SCOPE) return() endif() - list (APPEND _cmd ${_existingSourceFiles}) + # add source files to be scanned + if (WIN32) + foreach (_sourceFile ${_existingSourceFiles}) + file (TO_NATIVE_PATH "${_sourceFile}" _sourceFileNative) + list (APPEND _cmd "${_sourceFileNative}") + endforeach() + else() + list (APPEND _cmd ${_existingSourceFiles}) + endif() if (COTIRE_VERBOSE) message (STATUS "execute_process: ${_cmd}") endif() - if (_option_COMPILER_ID MATCHES "MSVC") - if (COTIRE_DEBUG) - message (STATUS "clearing VS_UNICODE_OUTPUT") - endif() + if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC") # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) endif() execute_process( - COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output) + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result + OUTPUT_QUIET + ERROR_VARIABLE _output) if (_result) message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") endif() @@ -1074,10 +1285,28 @@ function (cotire_scan_includes _includesVar) "${_option_IGNORE_EXTENSIONS}" _includes _unparsedLines ${_sourceFiles}) + if (_option_INCLUDE_PRIORITY_PATH) + set (_sortedIncludes "") + foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH}) + foreach (_include ${_includes}) + string (FIND ${_include} ${_priorityPath} _position) + if (_position GREATER -1) + list (APPEND _sortedIncludes ${_include}) + endif() + endforeach() + endforeach() + if (_sortedIncludes) + list (INSERT _includes 0 ${_sortedIncludes}) + list (REMOVE_DUPLICATES _includes) + endif() + endif() set (${_includesVar} ${_includes} PARENT_SCOPE) if (_option_UNPARSED_LINES) set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) endif() + if (_option_SCAN_RESULT) + set (${_option_SCAN_RESULT} ${_result} PARENT_SCOPE) + endif() endfunction() macro (cotire_append_undefs _contentsVar) @@ -1189,11 +1418,12 @@ function (cotire_generate_unity_source _unityFile) list (INSERT _compileUndefinitions 0 "${_definition}") endif() endforeach() - get_filename_component(_sourceFile "${_sourceFile}" ABSOLUTE) + # use absolute path as source file location + get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE) if (WIN32) - file (TO_NATIVE_PATH "${_sourceFile}" _sourceFile) + file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation) endif() - list (APPEND _contents "#include \"${_sourceFile}\"") + list (APPEND _contents "#include \"${_sourceFileLocation}\"") endforeach() if (_compileUndefinitions) cotire_append_undefs(_contents ${_compileUndefinitions}) @@ -1215,13 +1445,21 @@ endfunction() function (cotire_generate_prefix_header _prefixFile) set(_options "") - set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG) + set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION) set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS - INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH + IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() if (_option_DEPENDS) cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) if (_prefixFileIsUpToDate) + # create empty log file set (_unparsedLinesFile "${_prefixFile}.log") file (WRITE "${_unparsedLinesFile}" "") return() @@ -1243,30 +1481,37 @@ function (cotire_generate_prefix_header _prefixFile) set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) cotire_scan_includes(_selectedHeaders ${_sourceFiles} LANGUAGE "${_option_LANGUAGE}" + COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}" COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" + COMPILER_ARG1 "${_option_COMPILER_ARG1}" COMPILER_ID "${_option_COMPILER_ID}" COMPILER_VERSION "${_option_COMPILER_VERSION}" COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} COMPILE_FLAGS ${_option_COMPILE_FLAGS} INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} - INCLUDE_SYSTEM_FLAG ${_option_INCLUDE_SYSTEM_FLAG} SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} IGNORE_PATH ${_option_IGNORE_PATH} INCLUDE_PATH ${_option_INCLUDE_PATH} IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} - UNPARSED_LINES _unparsedLines) + INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH} + UNPARSED_LINES _unparsedLines + SCAN_RESULT _scanResult) cotire_generate_unity_source("${_prefixFile}" PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) set (_unparsedLinesFile "${_prefixFile}.log") if (_unparsedLines) - if (COTIRE_VERBOSE OR NOT _selectedHeaders) + if (COTIRE_VERBOSE OR _scanResult OR NOT _selectedHeaders) list (LENGTH _unparsedLines _skippedLineCount) - file (RELATIVE_PATH _unparsedLinesFileRelPath "${CMAKE_BINARY_DIR}" "${_unparsedLinesFile}") - message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFileRelPath}") + if (WIN32) + file (TO_NATIVE_PATH "${_unparsedLinesFile}" _unparsedLinesLogPath) + else() + set (_unparsedLinesLogPath "${_unparsedLinesFile}") + endif() + message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesLogPath}") endif() string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") endif() - file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}") + file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}\n") endfunction() function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) @@ -1296,7 +1541,7 @@ function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flags # append to list list (APPEND _flags -H -E) if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") - list (APPEND _flags "-fdirectives-only") + list (APPEND _flags -fdirectives-only) endif() else() # return as a flag string @@ -1306,15 +1551,36 @@ function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flags endif() endif() elseif (_compilerID MATCHES "Clang") - # Clang options used - # -H print the name of each header file used - # -E invoke preprocessor - if (_flags) - # append to list - list (APPEND _flags -H -E) - else() - # return as a flag string - set (_flags "-H -E") + if (UNIX) + # Clang options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fno-color-diagnostics do not print diagnostics in color + # -Eonly just run preprocessor, no output + if (_flags) + # append to list + list (APPEND _flags -H -E -fno-color-diagnostics -Xclang -Eonly) + else() + # return as a flag string + set (_flags "-H -E -fno-color-diagnostics -Xclang -Eonly") + endif() + elseif (WIN32) + # Clang-cl.exe options used + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /EP preprocess to stdout without #line directives + # -H print the name of each header file used + # -fno-color-diagnostics do not print diagnostics in color + # -Eonly just run preprocessor, no output + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags "${_sourceFileType${_language}}" /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly") + endif() endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1371,18 +1637,25 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio # /TC treat all files named on the command line as C source files # /TP treat all files named on the command line as C++ source files # /Zs syntax check only + # /Zm precompiled header memory allocation scaling factor set (_sourceFileTypeC "/TC") set (_sourceFileTypeCXX "/TP") if (_flags) # append to list list (APPEND _flags /nologo "${_sourceFileType${_language}}" "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() else() # return as a flag string set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() endif() - elseif (_compilerID MATCHES "GNU|Clang") - # GCC / Clang options used + elseif (_compilerID MATCHES "GNU") + # GCC options used # -x specify the source language # -c compile but do not link # -o place output in file @@ -1392,11 +1665,52 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio set (_xLanguage_CXX "c++-header") if (_flags) # append to list - list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}") else() # return as a flag string set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") endif() + elseif (_compilerID MATCHES "Clang") + if (UNIX) + # Clang options used + # -x specify the source language + # -c compile but do not link + # -o place output in file + # -fno-pch-timestamp disable inclusion of timestamp in precompiled headers (clang 4.0.0+) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}") + if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0") + list (APPEND _flags -Xclang -fno-pch-timestamp) + endif() + else() + # return as a flag string + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0") + set (_flags "${_flags} -Xclang -fno-pch-timestamp") + endif() + endif() + elseif (WIN32) + # Clang-cl.exe options used + # /Yc creates a precompiled header file + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /Zs syntax check only + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags "${_sourceFileType${_language}}" + "/Yc${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}" /Zs "${_hostFile}") + else() + # return as a flag string + set (_flags "/Yc\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"") + endif() + endif() elseif (_compilerID MATCHES "Intel") if (WIN32) file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) @@ -1434,24 +1748,32 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio # -Kc++ process all source or unrecognized file types as C++ source files # -fsyntax-only check only for correct syntax # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - get_filename_component(_pchDir "${_pchFile}" PATH) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) get_filename_component(_pchName "${_pchFile}" NAME) set (_xLanguage_C "c-header") set (_xLanguage_CXX "c++-header") + set (_pchSuppressMessages FALSE) + if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") + set(_pchSuppressMessages TRUE) + endif() if (_flags) # append to list if ("${_language}" STREQUAL "CXX") list (APPEND _flags -Kc++) endif() - list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}") + list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-create "${_pchName}" -fsyntax-only "${_hostFile}") if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "-Wpch-messages") + if (NOT _pchSuppressMessages) + list (APPEND _flags -Wpch-messages) + endif() endif() else() # return as a flag string set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} -Wpch-messages") + if (NOT _pchSuppressMessages) + set (_flags "${_flags} -Wpch-messages") + endif() endif() endif() endif() @@ -1469,14 +1791,21 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # /Yu uses a precompiled header file during build # /Fp specifies precompiled header binary file name # /FI forces inclusion of file + # /Zm precompiled header memory allocation scaling factor if (_pchFile) file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) if (_flags) # append to list list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() else() # return as a flag string set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() endif() else() # no precompiled header, force inclusion of prefix header @@ -1495,23 +1824,46 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # note: ccache requires the -include flag to be used in order to process precompiled header correctly if (_flags) # append to list - list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") + list (APPEND _flags -Winvalid-pch -include "${_prefixFile}") else() # return as a flag string set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") endif() elseif (_compilerID MATCHES "Clang") - # Clang options used - # -include process include file as the first line of the primary source file - # -include-pch include precompiled header file - # -Qunused-arguments don't emit warning for unused driver arguments - # note: ccache requires the -include flag to be used in order to process precompiled header correctly - if (_flags) - # append to list - list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") - else() - # return as a flag string - set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") + if (UNIX) + # Clang options used + # -include process include file as the first line of the primary source file + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags -include "${_prefixFile}") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\"") + endif() + elseif (WIN32) + # Clang-cl.exe options used + # /Yu uses a precompiled header file during build + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + if (_pchFile) + if (_flags) + # append to list + list (APPEND _flags "/Yu${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}") + else() + # return as a flag string + set (_flags "/Yu\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"") + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFile}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFile}\"") + endif() + endif() endif() elseif (_compilerID MATCHES "Intel") if (WIN32) @@ -1553,26 +1905,34 @@ function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerV # -include process include file as the first line of the primary source file # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) if (_pchFile) - get_filename_component(_pchDir "${_pchFile}" PATH) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) get_filename_component(_pchName "${_pchFile}" NAME) + set (_pchSuppressMessages FALSE) + if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") + set(_pchSuppressMessages TRUE) + endif() if (_flags) # append to list - list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}") + list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-use "${_pchName}") if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "-Wpch-messages") + if (NOT _pchSuppressMessages) + list (APPEND _flags -Wpch-messages) + endif() endif() else() # return as a flag string set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} -Wpch-messages") + if (NOT _pchSuppressMessages) + set (_flags "${_flags} -Wpch-messages") + endif() endif() endif() else() # no precompiled header, force inclusion of prefix header if (_flags) # append to list - list (APPEND _flags "-include" "${_prefixFile}") + list (APPEND _flags -include "${_prefixFile}") else() # return as a flag string set (_flags "-include \"${_prefixFile}\"") @@ -1587,8 +1947,8 @@ endfunction() function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) set(_options "") - set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS) + set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) if (NOT _option_LANGUAGE) set (_option_LANGUAGE "CXX") @@ -1596,23 +1956,31 @@ function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) if (NOT _option_COMPILER_ID) set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") endif() - cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) cotire_add_pch_compilation_flags( "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) if (COTIRE_VERBOSE) message (STATUS "execute_process: ${_cmd}") endif() - if (_option_COMPILER_ID MATCHES "MSVC") - if (COTIRE_DEBUG) - message (STATUS "clearing VS_UNICODE_OUTPUT") - endif() + if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC") # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared unset (ENV{VS_UNICODE_OUTPUT}) + elseif (_option_COMPILER_ID MATCHES "Clang" AND _option_COMPILER_VERSION VERSION_LESS "4.0.0") + if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR + _option_COMPILER_EXECUTABLE MATCHES "ccache") + # Newer versions of Clang embed a compilation timestamp into the precompiled header binary, + # which results in "file has been modified since the precompiled header was built" errors if ccache is used. + # We work around the problem by disabling ccache upon pre-compiling the prefix header. + set (ENV{CCACHE_DISABLE} "true") + endif() endif() execute_process( COMMAND ${_cmd} @@ -1623,56 +1991,83 @@ function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) endif() endfunction() -function (cotire_check_precompiled_header_support _language _targetSourceDir _target _msgVar) +function (cotire_check_precompiled_header_support _language _target _msgVar) set (_unsupportedCompiler "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") - # supported since Visual Studio C++ 6.0 + # PCH supported since Visual Studio C++ 6.0 # and CMake does not support an earlier version set (${_msgVar} "" PARENT_SCOPE) elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") # GCC PCH support requires version >= 3.4 - cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) - if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND - "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") - set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) else() set (${_msgVar} "" PARENT_SCOPE) endif() elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") - # all Clang versions have PCH support - set (${_msgVar} "" PARENT_SCOPE) + if (UNIX) + # all Unix Clang versions have PCH support + set (${_msgVar} "" PARENT_SCOPE) + elseif (WIN32) + # only clang-cl is supported under Windows + get_filename_component(_compilerName "${CMAKE_${_language}_COMPILER}" NAME_WE) + if (NOT _compilerName MATCHES "cl$") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}. Use clang-cl instead." PARENT_SCOPE) + endif() + endif() elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") # Intel PCH support requires version >= 8.0.0 - cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) - if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND - "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") - set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) else() set (${_msgVar} "" PARENT_SCOPE) endif() else() set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) endif() - if (CMAKE_${_language}_COMPILER MATCHES "ccache") - if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros") - set (${_msgVar} - "ccache requires the environment variable CCACHE_SLOPPINESS to be set to time_macros." - PARENT_SCOPE) + # check if ccache is used as a compiler launcher + get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER) + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" REALPATH) + if (_realCompilerExe MATCHES "ccache" OR _launcher MATCHES "ccache") + # verify that ccache configuration is compatible with precompiled headers + # always check environment variable CCACHE_SLOPPINESS, because earlier versions of ccache + # do not report the "sloppiness" setting correctly upon printing ccache configuration + if (DEFINED ENV{CCACHE_SLOPPINESS}) + if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR + NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros") + set (${_msgVar} + "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() + else() + if (_realCompilerExe MATCHES "ccache") + set (_ccacheExe "${_realCompilerExe}") + else() + set (_ccacheExe "${_launcher}") + endif() + execute_process( + COMMAND "${_ccacheExe}" "--print-config" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if (_result) + set (${_msgVar} "ccache configuration cannot be determined." PARENT_SCOPE) + elseif (NOT _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR + NOT _ccacheConfig MATCHES "sloppiness.*=.*pch_defines") + set (${_msgVar} + "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() endif() endif() if (APPLE) # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) - if (CMAKE_CONFIGURATION_TYPES) - set (_configs ${CMAKE_CONFIGURATION_TYPES}) - elseif (CMAKE_BUILD_TYPE) - set (_configs ${CMAKE_BUILD_TYPE}) - else() - set (_configs "None") - endif() + cotire_get_configuration_types(_configs) foreach (_config ${_configs}) set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags) + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) list (LENGTH _architectures _numberOfArchitectures) if (_numberOfArchitectures GREATER 1) @@ -1687,6 +2082,7 @@ function (cotire_check_precompiled_header_support _language _targetSourceDir _ta endfunction() macro (cotire_get_intermediate_dir _cotireDir) + # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) endmacro() @@ -1710,9 +2106,6 @@ function (cotire_make_single_unity_source_file_path _language _target _unityFile cotire_get_intermediate_dir(_baseDir) set (_unityFile "${_baseDir}/${_unityFileName}") set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) - if (COTIRE_DEBUG) - message(STATUS "${_unityFile}") - endif() endfunction() function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) @@ -1752,8 +2145,8 @@ function (cotire_make_unity_source_file_paths _language _target _maxIncludes _un list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") endif() set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) - if (COTIRE_DEBUG) - message(STATUS "${_unityFiles}") + if (COTIRE_DEBUG AND _unityFiles) + message (STATUS "unity files: ${_unityFiles}") endif() endfunction() @@ -1803,18 +2196,18 @@ function (cotire_make_prefix_file_path _language _target _prefixFileVar) if (NOT _language) set (_language "C") endif() - if (MSVC OR CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel") + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC") cotire_get_intermediate_dir(_baseDir) set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) endif() endif() endfunction() -function (cotire_make_pch_file_path _language _targetSourceDir _target _pchFileVar) +function (cotire_make_pch_file_path _language _target _pchFileVar) cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) set (${_pchFileVar} "" PARENT_SCOPE) if (_prefixFileBaseName AND _prefixFileName) - cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _msg) + cotire_check_precompiled_header_support("${_language}" "${_target}" _msg) if (NOT _msg) if (XCODE) # For Xcode, we completely hand off the compilation of the prefix header to the IDE @@ -1864,7 +2257,8 @@ endfunction() function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) set (_dependencySources "") # depend on target's generated source files - cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN}) + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) if (_generatedSources) # but omit all generated source files that have the COTIRE_EXCLUDED property set to true cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) @@ -1881,36 +2275,28 @@ function (cotire_get_unity_source_dependencies _language _target _dependencySour endif() endif() if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_language} ${_target} unity source depends on ${_dependencySources}") + message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}") endif() set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) endfunction() function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) - # depend on target source files marked with custom COTIRE_DEPENDENCY property set (_dependencySources "") - cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # GCC and clang raise a fatal error if a file is not found during preprocessing - # thus we depend on target's generated source files for prefix header generation - cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN}) - if (_generatedSources) - list (APPEND _dependencySources ${_generatedSources}) - endif() - endif() + # depend on target source files marked with custom COTIRE_DEPENDENCY property + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles}) if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_language} ${_target} prefix header DEPENDS ${_dependencySources}") + message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}") endif() set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) endfunction() -function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar _targetConfigScriptVar) - set (COTIRE_TARGET_SOURCES ${ARGN}) - cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${COTIRE_TARGET_SOURCES}) - cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${COTIRE_TARGET_SOURCES}) +function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar) + set (_targetSources ${ARGN}) + cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources}) + cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources}) # set up variables to be configured set (COTIRE_TARGET_LANGUAGE "${_language}") - cotire_determine_compiler_version("${COTIRE_TARGET_LANGUAGE}" COTIRE_${_language}_COMPILER) get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) @@ -1918,30 +2304,54 @@ function (cotire_generate_target_script _language _configurations _targetSourceD get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) - cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES}) - cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES}) - string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" COTIRE_INCLUDE_SYSTEM_FLAG) + get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources}) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources}) set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") foreach (_config ${_configurations}) string (TOUPPER "${_config}" _upperConfig) cotire_get_target_include_directories( - "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) cotire_get_target_compile_definitions( - "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) cotire_get_target_compiler_flags( - "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) cotire_get_source_files_compile_definitions( - "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${COTIRE_TARGET_SOURCES}) + "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources}) + endforeach() + get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER) + # set up COTIRE_TARGET_SOURCES + set (COTIRE_TARGET_SOURCES "") + foreach (_sourceFile ${_targetSources}) + get_source_file_property(_generated "${_sourceFile}" GENERATED) + if (_generated) + # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}") + else() + list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}") + endif() endforeach() + # copy variable definitions to cotire target script get_cmake_property(_vars VARIABLES) string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") - # remove COTIRE_VERBOSE which is passed as a CMake define on command line + # omit COTIRE_*_INIT variables + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}") + if (_initVars) + list (REMOVE_ITEM _matchVars ${_initVars}) + endif() + # omit COTIRE_VERBOSE which is passed as a CMake define on command line list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) set (_contents "") set (_contentsHasGeneratorExpressions FALSE) foreach (_var IN LISTS _matchVars ITEMS - MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES - CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 + XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES + CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION + CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 + CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language} + CMAKE_INCLUDE_SYSTEM_FLAG_${_language} + CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG + CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) if (DEFINED ${_var}) string (REPLACE "\"" "\\\"" _value "${${_var}}") @@ -1953,20 +2363,15 @@ function (cotire_generate_target_script _language _configurations _targetSourceD endif() endif() endforeach() + # generate target script file get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) if (_contentsHasGeneratorExpressions) # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time - if (NOT CMAKE_VERSION VERSION_LESS "2.8.12") - # the file(GENERATE ...) command requires cmake 2.8.12 or later - set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") - set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") - file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") - else() - message (WARNING "cotire: generator expression used in target ${_target}. This requires CMake 2.8.12 or later.") - set (_targetCotireConfigScript "${_targetCotireScript}") - endif() + set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") + set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") + file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") else() set (_targetCotireConfigScript "${_targetCotireScript}") endif() @@ -1974,82 +2379,86 @@ function (cotire_generate_target_script _language _configurations _targetSourceD set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) endfunction() -function (cotire_setup_pch_file_compilation _language _target _targetSourceDir _targetScript _prefixFile _pchFile) +function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile) set (_sourceFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # for Visual Studio and Intel, we attach the precompiled header compilation to the first source file + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) + # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion if (_sourceFiles) - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - list (GET _sourceFiles 0 _hostFile) set (_flags "") - cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) cotire_add_pch_compilation_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") - # make first source file depend on prefix header + # make object file generated from host file depend on prefix header set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") - # mark first source file as cotired to prevent it from being used in another cotired target + # mark host file as cotired to prevent it from being used in another cotired target set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") endif() - elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") # for makefile based generator, we add a custom command to precompile the prefix header if (_targetScript) cotire_set_cmd_to_prologue(_cmds) - list (GET _sourceFiles 0 _hostFile) list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") - file (RELATIVE_PATH _pchFileRelPath "${CMAKE_BINARY_DIR}" "${_pchFile}") + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath) + else() + file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}") + endif() + # make precompiled header compilation depend on the actual compiler executable used to force + # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable" + # warnings when the precompiled header is included. + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") + message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") endif() set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) add_custom_command( OUTPUT "${_pchFile}" COMMAND ${_cmds} - DEPENDS "${_prefixFile}" + DEPENDS "${_prefixFile}" "${_realCompilerExe}" IMPLICIT_DEPENDS ${_language} "${_prefixFile}" - WORKING_DIRECTORY "${_targetSourceDir}" - COMMENT "Building ${_language} precompiled header ${_pchFileRelPath}" VERBATIM) + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}" + VERBATIM) endif() endif() endfunction() -function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile) - set (_sourceFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # for Visual Studio and Intel, we include the precompiled header in all but the first source file - # the first source file does the precompiled header compilation, see cotire_setup_pch_file_compilation +function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) + # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file + # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation + set (_sourceFiles ${ARGN}) list (LENGTH _sourceFiles _numberOfSourceFiles) - if (_numberOfSourceFiles GREATER 1) + if (_numberOfSourceFiles GREATER 0) # mark sources as cotired to prevent them from being used in another cotired target set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - list (REMOVE_AT _sourceFiles 0) set (_flags "") - cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" "${_prefixFile}" "${_pchFile}" _flags) set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - # make source files depend on precompiled header + # make object files generated from source files depend on precompiled header set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") endif() - elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + set (_sourceFiles ${_hostFile} ${ARGN}) if (NOT _wholeTarget) # for makefile based generator, we force the inclusion of the prefix header for a subset # of the source files, if this is a multi-language target or has excluded files set (_flags "") - cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" "${_prefixFile}" "${_pchFile}" _flags) set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") # mark sources as cotired to prevent them from being used in another cotired target set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") endif() - # make source files depend on precompiled header + # make object files generated from source files depend on precompiled header set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") endif() endfunction() @@ -2058,14 +2467,14 @@ function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) set (_sourceFiles ${ARGN}) # force the inclusion of the prefix header for the given source files set (_flags "") - cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + set (_pchFile "") cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "" _flags) + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") # mark sources as cotired to prevent them from being used in another cotired target set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - # make source files depend on prefix header + # make object files generated from source files depend on prefix header set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") endfunction() @@ -2081,21 +2490,12 @@ function (cotire_get_first_set_property_value _propertyValueVar _type _object) set (${_propertyValueVar} "" PARENT_SCOPE) endfunction() -function (cotire_setup_combine_command _language _sourceDir _targetScript _joinedFile _cmdsVar) +function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar) set (_files ${ARGN}) set (_filesPaths "") foreach (_file ${_files}) - if (IS_ABSOLUTE "${_file}") - set (_filePath "${_file}") - else() - get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE) - endif() - file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}") - if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.") - list (APPEND _filesPaths "${_fileRelPath}") - else() - list (APPEND _filesPaths "${_filePath}") - endif() + get_filename_component(_filePath "${_file}" ABSOLUTE) + list (APPEND _filesPaths "${_filePath}") endforeach() cotire_set_cmd_to_prologue(_prefixCmd) list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") @@ -2107,34 +2507,38 @@ function (cotire_setup_combine_command _language _sourceDir _targetScript _joine message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") endif() set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) - file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath) + else() + file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") + endif() get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) get_filename_component(_joinedFileExt "${_joinedFile}" EXT) if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") - set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}") + set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}") elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") if (_joinedFileExt MATCHES "^\\.c") - set (_comment "Generating ${_language} prefix source ${_joinedFileRelPath}") + set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}") else() - set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}") + set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}") endif() else() - set (_comment "Generating ${_joinedFileRelPath}") + set (_comment "Generating ${_joinedFileLogPath}") endif() add_custom_command( OUTPUT "${_joinedFile}" COMMAND ${_prefixCmd} DEPENDS ${_files} COMMENT "${_comment}" - WORKING_DIRECTORY "${_sourceDir}" VERBATIM) + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() -function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _wholeTarget) +function (cotire_setup_target_pch_usage _languages _target _wholeTarget) if (XCODE) # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers - # if necessary, we also generate a single prefix header which includes all language specific prefix headers set (_prefixFiles "") foreach (_language ${_languages}) get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) @@ -2145,110 +2549,156 @@ function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _who set (_cmds ${ARGN}) list (LENGTH _prefixFiles _numberOfPrefixFiles) if (_numberOfPrefixFiles GREATER 1) - cotire_make_prefix_file_path("" ${_target} _prefixHeader) - cotire_setup_combine_command("" "${_targetSourceDir}" "" "${_prefixHeader}" _cmds ${_prefixFiles}) + # we also generate a generic, single prefix header which includes all language specific prefix headers + set (_language "") + set (_targetScript "") + cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader) + cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles}) else() set (_prefixHeader "${_prefixFiles}") endif() if (COTIRE_DEBUG) message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") endif() - add_custom_command(TARGET "${_target}" + # because CMake PRE_BUILD command does not support dependencies, + # we check dependencies explicity in cotire script mode when the pre-build action is run + add_custom_command( + TARGET "${_target}" PRE_BUILD ${_cmds} - WORKING_DIRECTORY "${_targetSourceDir}" - COMMENT "Updating target ${_target} prefix headers" VERBATIM) + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Updating target ${_target} prefix headers" + VERBATIM) # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") - elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") # for makefile based generator, we force inclusion of the prefix header for all target source files # if this is a single-language target without any excluded files if (_wholeTarget) set (_language "${_languages}") - # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level + # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level # see cotire_setup_pch_file_inclusion - if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) - get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) - set (_flags "") - cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _flags) - set_property(TARGET ${_target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + if (_prefixFile) + get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) + set (_options COMPILE_OPTIONS) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _options) + set_property(TARGET ${_target} APPEND PROPERTY ${_options}) + endif() endif() endif() endif() endfunction() -function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _targetConfigScript _unityFiles _cmdsVar) +function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar) set (_dependencySources "") cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) foreach (_unityFile ${_unityFiles}) - file (RELATIVE_PATH _unityFileRelPath "${CMAKE_BINARY_DIR}" "${_unityFile}") set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) - # set up compiled unity source dependencies + # set up compiled unity source dependencies via OBJECT_DEPENDS # this ensures that missing source files are generated before the unity file is compiled if (COTIRE_DEBUG AND _dependencySources) message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") endif() if (_dependencySources) - set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_dependencySources}) + # the OBJECT_DEPENDS property requires a list of full paths + set (_objectDependsPaths "") + foreach (_sourceFile ${_dependencySources}) + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND _objectDependsPaths "${_sourceLocation}") + endforeach() + set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths}) endif() if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel + # unity file compilation results in potentially huge object file, + # thus use /bigobj by default unter cl.exe and Windows Intel set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") endif() cotire_set_cmd_to_prologue(_unityCmd) list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_unityCmdDepends "${_targetScript}") + else() + # CMake 3.1.0 supports generator expressions in arguments to DEPENDS + set (_unityCmdDepends "${_targetConfigScript}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath) + else() + file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}") + endif() if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_targetScript}") + message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}") endif() add_custom_command( OUTPUT "${_unityFile}" COMMAND ${_unityCmd} - DEPENDS "${_targetScript}" - COMMENT "Generating ${_language} unity source ${_unityFileRelPath}" - WORKING_DIRECTORY "${_targetSourceDir}" VERBATIM) + DEPENDS ${_unityCmdDepends} + COMMENT "Generating ${_language} unity source ${_unityFileLogPath}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) endforeach() - list (LENGTH _unityFiles _numberOfUnityFiles) - if (_numberOfUnityFiles GREATER 1) - # create a joint unity file from all unity file segments - cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) - cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetConfigScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles}) - endif() set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() -function (cotire_setup_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar) +function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) set (_sourceFiles ${ARGN}) set (_dependencySources "") cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) cotire_set_cmd_to_prologue(_prefixCmd) - list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" "${_unityFile}") + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles}) set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) + # make prefix header generation depend on the actual compiler executable used to force + # re-generation when the compiler executable is updated. This prevents "file not found" + # errors for compiler version specific system header files. + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources}") + message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath) + else() + file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") endif() - file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") get_filename_component(_prefixFileExt "${_prefixFile}" EXT) if (_prefixFileExt MATCHES "^\\.c") - set (_comment "Generating ${_language} prefix source ${_prefixFileRelPath}") + set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}") + else() + set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}") + endif() + # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist + # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence + # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files + set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre") + if (TARGET ${_preTargetName}) + # custom helper target has already been generated while processing a different language + list (APPEND _dependencySources ${_preTargetName}) else() - set (_comment "Generating ${_language} prefix header ${_prefixFileRelPath}") + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) + if (_generatedSources) + add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources}) + cotire_init_target("${_preTargetName}") + list (APPEND _dependencySources ${_preTargetName}) + endif() endif() add_custom_command( OUTPUT "${_prefixFile}" "${_prefixFile}.log" COMMAND ${_prefixCmd} - DEPENDS "${_unityFile}" ${_dependencySources} + DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}" COMMENT "${_comment}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() -function (cotire_setup_prefix_generation_from_unity_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar) +function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) set (_sourceFiles ${ARGN}) if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma @@ -2256,24 +2706,17 @@ function (cotire_setup_prefix_generation_from_unity_command _language _target _t else() set (_prefixSourceFile "${_prefixFile}") endif() - list (LENGTH _unityFiles _numberOfUnityFiles) - if (_numberOfUnityFiles GREATER 1) - cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) - cotire_setup_prefix_generation_command( - ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" - "${_prefixSourceFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles}) - else() - cotire_setup_prefix_generation_command( - ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" - "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) - endif() + cotire_setup_prefix_generation_command( + ${_language} ${_target} "${_targetScript}" + "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" ${_cmdsVar} ${_prefixSourceFile}) + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) endif() set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() -function (cotire_setup_prefix_generation_from_provided_command _language _target _targetSourceDir _targetScript _prefixFile _cmdsVar) +function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar) set (_prefixHeaderFiles ${ARGN}) if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma @@ -2281,9 +2724,10 @@ function (cotire_setup_prefix_generation_from_provided_command _language _target else() set (_prefixSourceFile "${_prefixFile}") endif() - cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) endif() set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) endfunction() @@ -2313,6 +2757,10 @@ function (cotire_init_cotire_target_properties _target) if (NOT _isSet) set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "") + endif() get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) if (NOT _isSet) set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") @@ -2323,7 +2771,7 @@ function (cotire_init_cotire_target_properties _target) endif() get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "") + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY") endif() get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) if (NOT _isSet) @@ -2373,6 +2821,9 @@ function (cotire_make_target_message _target _languages _disableMsg _targetMsgVa else() set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") endif() + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() else() if (_excludedStr) set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") @@ -2383,12 +2834,13 @@ function (cotire_make_target_message _target _languages _disableMsg _targetMsgVa set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) endfunction() -function (cotire_choose_target_languages _targetSourceDir _target _targetLanguagesVar) +function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar) set (_languages ${ARGN}) set (_allSourceFiles "") set (_allExcludedSourceFiles "") set (_allCotiredSourceFiles "") set (_targetLanguages "") + set (_pchEligibleTargetLanguages "") get_target_property(_targetType ${_target} TYPE) get_target_property(_targetSourceFiles ${_target} SOURCES) get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) @@ -2402,22 +2854,28 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag set (${_targetLanguagesVar} "" PARENT_SCOPE) return() endif() - if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$") - cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _disableMsg) - if (_disableMsg) - set (_targetUsePCH FALSE) + if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID) + if (CMAKE_${_language}_COMPILER_ID) + cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg) + if (_disableMsg) + set (_targetUsePCH FALSE) + endif() endif() endif() set (_sourceFiles "") set (_excludedSources "") set (_cotiredSources "") - cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) if (_sourceFiles OR _excludedSources OR _cotiredSources) list (APPEND _targetLanguages ${_language}) endif() if (_sourceFiles) list (APPEND _allSourceFiles ${_sourceFiles}) endif() + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + list (APPEND _pchEligibleTargetLanguages ${_language}) + endif() if (_excludedSources) list (APPEND _allExcludedSourceFiles ${_excludedSources}) endif() @@ -2433,11 +2891,7 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag set (_targetAddSCU FALSE) endif() if (_targetUsePCH) - list (LENGTH _allSourceFiles _numberOfSources) - if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) - set (_disableMsg "Too few applicable sources.") - set (_targetUsePCH FALSE) - elseif (_allCotiredSourceFiles) + if (_allCotiredSourceFiles) cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) list (REMOVE_DUPLICATES _cotireTargets) string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") @@ -2446,6 +2900,9 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") set (_targetMsgLevel SEND_ERROR) set (_targetUsePCH FALSE) + elseif (NOT _pchEligibleTargetLanguages) + set (_disableMsg "Too few applicable sources.") + set (_targetUsePCH FALSE) elseif (XCODE AND _allExcludedSourceFiles) # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target set (_disableMsg "Exclusion of source files not supported for generator Xcode.") @@ -2456,6 +2913,20 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag set (_targetUsePCH FALSE) endif() endif() + if (_targetAddSCU) + # disable unity builds if automatic Qt processing is used + get_target_property(_targetAutoMoc ${_target} AUTOMOC) + get_target_property(_targetAutoUic ${_target} AUTOUIC) + get_target_property(_targetAutoRcc ${_target} AUTORCC) + if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) + if (_disableMsg) + set (_disableMsg "${_disableMsg} Target uses automatic CMake Qt processing.") + else() + set (_disableMsg "Target uses automatic CMake Qt processing.") + endif() + set (_targetAddSCU FALSE) + endif() + endif() set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) @@ -2470,6 +2941,12 @@ function (cotire_choose_target_languages _targetSourceDir _target _targetLanguag message (${_targetMsgLevel} "${_targetMsg}") endif() endif() + list (LENGTH _targetLanguages _numberOfLanguages) + if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles) + set (${_wholeTargetVar} FALSE PARENT_SCOPE) + else() + set (${_wholeTargetVar} TRUE PARENT_SCOPE) + endif() set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) endfunction() @@ -2477,37 +2954,36 @@ function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) set (_sourceFiles ${ARGN}) get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") - set (_numberOfThreads "${CMAKE_MATCH_2}") + if (DEFINED CMAKE_MATCH_2) + set (_numberOfThreads "${CMAKE_MATCH_2}") + else() + set (_numberOfThreads "") + endif() if (NOT _numberOfThreads) # use all available cores ProcessorCount(_numberOfThreads) endif() list (LENGTH _sourceFiles _numberOfSources) math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") - # a unity source segment must not contain less than COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES files - if (_maxIncludes LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) - set (_maxIncludes ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) - endif() elseif (NOT _maxIncludes MATCHES "[0-9]+") set (_maxIncludes 0) endif() if (COTIRE_DEBUG) - message (STATUS "${_target} unity source max includes = ${_maxIncludes}") + message (STATUS "${_target} unity source max includes: ${_maxIncludes}") endif() set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) endfunction() -function (cotire_process_target_language _language _configurations _targetSourceDir _targetBinaryDir _target _wholeTargetVar _cmdsVar) +function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar) set (${_cmdsVar} "" PARENT_SCOPE) get_target_property(_targetSourceFiles ${_target} SOURCES) set (_sourceFiles "") set (_excludedSources "") set (_cotiredSources "") - cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) if (NOT _sourceFiles AND NOT _cotiredSources) return() endif() - set (_wholeTarget ${${_wholeTargetVar}}) set (_cmds "") # check for user provided unity source file list get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) @@ -2515,41 +2991,52 @@ function (cotire_process_target_language _language _configurations _targetSource set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) endif() cotire_generate_target_script( - ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) + ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) + # set up unity files for parallel compilation cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) - if (NOT _unityFiles) + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles EQUAL 0) return() + elseif (_numberOfUnityFiles GREATER 1) + cotire_setup_unity_generation_commands( + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) endif() + # set up single unity file for prefix header generation + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) cotire_setup_unity_generation_commands( - ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles}) cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) + # set up prefix header if (_prefixFile) # check for user provided prefix header files get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) if (_prefixHeaderFiles) cotire_setup_prefix_generation_from_provided_command( - ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) else() cotire_setup_prefix_generation_from_unity_command( - ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles}) + endif() + # check if selected language has enough sources at all + list (LENGTH _sourceFiles _numberOfSources) + if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_targetUsePCH FALSE) + else() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) endif() - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) if (_targetUsePCH) - cotire_make_pch_file_path(${_language} "${_targetSourceDir}" ${_target} _pchFile) + cotire_make_pch_file_path(${_language} ${_target} _pchFile) if (_pchFile) + # first file in _sourceFiles is passed as the host file cotire_setup_pch_file_compilation( - ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) - if (_excludedSources) - set (_wholeTarget FALSE) - endif() + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) cotire_setup_pch_file_inclusion( ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) endif() elseif (_prefixHeaderFiles) - # user provided prefix header must be included - cotire_setup_prefix_file_inclusion( - ${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) + # user provided prefix header must be included unconditionally + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) endif() endif() # mark target as cotired for language @@ -2560,7 +3047,6 @@ function (cotire_process_target_language _language _configurations _targetSource set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") endif() endif() - set (${_wholeTargetVar} ${_wholeTarget} PARENT_SCOPE) set (${_cmdsVar} ${_cmds} PARENT_SCOPE) endfunction() @@ -2570,20 +3056,24 @@ function (cotire_setup_clean_target _target) cotire_set_cmd_to_prologue(_cmds) get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") - add_custom_target(${_cleanTargetName} COMMAND ${_cmds} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - COMMENT "Cleaning up target ${_target} cotire generated files" VERBATIM) + add_custom_target(${_cleanTargetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up target ${_target} cotire generated files" + VERBATIM) cotire_init_target("${_cleanTargetName}") endif() endfunction() function (cotire_setup_pch_target _languages _configurations _target) - if ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") # for makefile based generators, we add a custom target to trigger the generation of the cotire related files set (_dependsFiles "") foreach (_language ${_languages}) set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) - if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # Visual Studio and Intel only create precompiled header as a side effect + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) + # MSVC, Intel and clang-cl only create precompiled header as a side effect list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) endif() cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) @@ -2603,22 +3093,17 @@ function (cotire_setup_pch_target _languages _configurations _target) endif() endfunction() -function (cotire_setup_unity_build_target _languages _configurations _targetSourceDir _target) - get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) - if (NOT _unityTargetName) - set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") - endif() - # determine unity target sub type - get_target_property(_targetType ${_target} TYPE) - if ("${_targetType}" STREQUAL "EXECUTABLE") - set (_unityTargetSubType "") - elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") - set (_unityTargetSubType "${CMAKE_MATCH_1}") - else() - message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") - return() - endif() - # determine unity target sources +function (cotire_filter_object_libraries _target _objectLibrariesVar) + set (_objectLibraries "") + foreach (_source ${ARGN}) + if (_source MATCHES "^\\$$") + list (APPEND _objectLibraries "${_source}") + endif() + endforeach() + set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar) get_target_property(_targetSourceFiles ${_target} SOURCES) set (_unityTargetSources ${_targetSourceFiles}) foreach (_language ${_languages}) @@ -2628,32 +3113,65 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour set (_sourceFiles "") set (_excludedSources "") set (_cotiredSources "") - cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) if (_sourceFiles OR _cotiredSources) list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) endif() - # if cotire is applied to a target which has not been added in the current source dir, - # non-existing files cannot be referenced from the unity build target (this is a CMake restriction) - if (NOT "${_targetSourceDir}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") - set (_nonExistingFiles "") - foreach (_file ${_unityTargetSources}) - if (NOT EXISTS "${_file}") - list (APPEND _nonExistingFiles "${_file}") - endif() - endforeach() - if (_nonExistingFiles) - if (COTIRE_VERBOSE) - message (STATUS "removing non-existing ${_nonExistingFiles} from ${_unityTargetName}") - endif() - list (REMOVE_ITEM _unityTargetSources ${_nonExistingFiles}) - endif() - endif() # add unity source files instead list (APPEND _unityTargetSources ${_unityFiles}) endif() endforeach() + # handle object libraries which are part of the target's sources + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$") + cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles}) + if (_objectLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries}) + list (REMOVE_ITEM _unityTargetSources ${_objectLibraries}) + list (APPEND _unityTargetSources ${_unityObjectLibraries}) + endif() + endif() + set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE) +endfunction() + +function (cotire_setup_unity_target_pch_usage _languages _target) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_userPrefixFile AND _prefixFile) + # user provided prefix header must be included unconditionally by unity sources + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles}) + endif() + endif() + endforeach() +endfunction() + +function (cotire_setup_unity_build_target _languages _configurations _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (NOT _unityTargetName) + set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") + endif() + # determine unity target sub type + get_target_property(_targetType ${_target} TYPE) + if ("${_targetType}" STREQUAL "EXECUTABLE") + set (_unityTargetSubType "") + elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (_unityTargetSubType "${CMAKE_MATCH_1}") + else() + message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") + return() + endif() + # determine unity target sources + set (_unityTargetSources "") + cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources) + # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created + set (CMAKE_AUTOMOC OFF) + set (CMAKE_AUTOUIC OFF) + set (CMAKE_AUTORCC OFF) if (COTIRE_DEBUG) - message (STATUS "add ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") + message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") endif() # generate unity target if ("${_targetType}" STREQUAL "EXECUTABLE") @@ -2661,18 +3179,19 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour else() add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) endif() + # copy output location properties set (_outputDirProperties ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_ LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_ RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_) - # copy output location properties if (COTIRE_UNITY_OUTPUT_DIRECTORY) set (_setDefaultOutputDir TRUE) if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") else() - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) - cotire_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties}) + # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties}) foreach (_property ${_properties}) get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) if (_outputDir) @@ -2692,58 +3211,91 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") endif() else() - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ${_outputDirProperties}) endif() # copy output name - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_ LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_ OUTPUT_NAME OUTPUT_NAME_ RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_ - PREFIX _POSTFIX SUFFIX) + PREFIX _POSTFIX SUFFIX + IMPORT_PREFIX IMPORT_SUFFIX) # copy compile stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} COMPILE_DEFINITIONS COMPILE_DEFINITIONS_ COMPILE_FLAGS COMPILE_OPTIONS Fortran_FORMAT Fortran_MODULE_DIRECTORY INCLUDE_DIRECTORIES INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_ POSITION_INDEPENDENT_CODE - C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN) + C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER + C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE + C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN + C_CLANG_TIDY CXX_CLANG_TIDY) + # copy compile features + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED + CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED + COMPILE_FEATURES) # copy interface stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN COMPATIBLE_INTERFACE_STRING - INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_OPTIONS INTERFACE_INCLUDE_DIRECTORIES + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN + COMPATIBLE_INTERFACE_STRING + INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS + INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES - INTERFACE_AUTOUIC_OPTIONS) + INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED) # copy link stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUILD_WITH_INSTALL_RPATH BUILD_WITH_INSTALL_NAME_DIR + INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED LINK_FLAGS LINK_FLAGS_ LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_ LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_ LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_ - NO_SONAME SOVERSION VERSION) - # copy Qt stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - AUTOMOC AUTOMOC_MOC_OPTIONS AUTOUIC AUTOUIC_OPTIONS AUTORCC AUTORCC_OPTIONS - AUTOGEN_TARGET_DEPENDS) + NO_SONAME SOVERSION VERSION + LINK_WHAT_YOU_USE BUILD_RPATH) # copy cmake stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) # copy Apple platform specific stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - BUNDLE BUNDLE_EXTENSION FRAMEWORK INSTALL_NAME_DIR MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST - MACOSX_RPATH OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE) + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR + MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH + OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST + IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE) # copy Windows platform specific stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} GNUtoMS + COMPILE_PDB_NAME COMPILE_PDB_NAME_ + COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_ PDB_NAME PDB_NAME_ PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_ - VS_DOTNET_REFERENCES VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE VS_KEYWORD + VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION + VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE + VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK + VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER - VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES WIN32_EXECUTABLE) + VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION + VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES + WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS + DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE + VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY) + # copy Android platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ANDROID_API ANDROID_API_MIN ANDROID_GUI + ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES + ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR + ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES + ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH + ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE) + # copy CUDA platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + CUDA_PTX_COMPILATION CUDA_SEPARABLE_COMPILATION CUDA_RESOLVE_DEVICE_SYMBOLS + CUDA_EXTENSIONS CUDA_STANDARD CUDA_STANDARD_REQUIRED) # use output name from original target get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) if (NOT _targetOutputName) @@ -2757,6 +3309,13 @@ function (cotire_setup_unity_build_target _languages _configurations _targetSour set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) endif() endif() + # enable parallel compilation for MSVC + if (MSVC AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio") + list (LENGTH _unityTargetSources _numberOfUnityTargetSources) + if (_numberOfUnityTargetSources GREATER 1) + set_property(TARGET ${_unityTargetName} APPEND PROPERTY COMPILE_OPTIONS "/MP") + endif() + endif() cotire_init_target(${_unityTargetName}) cotire_add_to_unity_all_target(${_unityTargetName}) set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") @@ -2764,31 +3323,25 @@ endfunction(cotire_setup_unity_build_target) function (cotire_target _target) set(_options "") - set(_oneValueArgs SOURCE_DIR BINARY_DIR) + set(_oneValueArgs "") set(_multiValueArgs LANGUAGES CONFIGURATIONS) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (NOT _option_SOURCE_DIR) - set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - endif() - if (NOT _option_BINARY_DIR) - set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") - endif() if (NOT _option_LANGUAGES) get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) endif() if (NOT _option_CONFIGURATIONS) - if (CMAKE_CONFIGURATION_TYPES) - set (_option_CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES}) - elseif (CMAKE_BUILD_TYPE) - set (_option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}") + cotire_get_configuration_types(_option_CONFIGURATIONS) + endif() + # check if cotire can be applied to target at all + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + get_target_property(_imported ${_target} IMPORTED) + get_target_property(_targetType ${_target} TYPE) + if (_imported) + message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.") else() - set (_option_CONFIGURATIONS "None") + message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.") endif() - endif() - # trivial checks - get_target_property(_imported ${_target} IMPORTED) - if (_imported) - message (WARNING "cotire: imported target ${_target} cannot be cotired.") return() endif() # resolve alias @@ -2815,33 +3368,34 @@ function (cotire_target _target) return() endif() endif() + # when not using configuration types, immediately create cotire intermediate dir + if (NOT CMAKE_CONFIGURATION_TYPES) + cotire_get_intermediate_dir(_baseDir) + file (MAKE_DIRECTORY "${_baseDir}") + endif() # choose languages that apply to the target - cotire_choose_target_languages("${_option_SOURCE_DIR}" "${_target}" _targetLanguages ${_option_LANGUAGES}) + cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES}) if (NOT _targetLanguages) return() endif() - list (LENGTH _targetLanguages _numberOfLanguages) - if (_numberOfLanguages GREATER 1) - set (_wholeTarget FALSE) - else() - set (_wholeTarget TRUE) - endif() set (_cmds "") foreach (_language ${_targetLanguages}) - cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" - "${_option_SOURCE_DIR}" "${_option_BINARY_DIR}" ${_target} _wholeTarget _cmd) + cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd) if (_cmd) list (APPEND _cmds ${_cmd}) endif() endforeach() get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) if (_targetAddSCU) - cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" "${_option_SOURCE_DIR}" ${_target}) + cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) endif() get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) if (_targetUsePCH) - cotire_setup_target_pch_usage("${_targetLanguages}" "${_option_SOURCE_DIR}" ${_target} ${_wholeTarget} ${_cmds}) + cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds}) cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + if (_targetAddSCU) + cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target}) + endif() endif() get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) if (_targetAddCleanTarget) @@ -2852,10 +3406,35 @@ endfunction(cotire_target) function (cotire_map_libraries _strategy _mappedLibrariesVar) set (_mappedLibraries "") foreach (_library ${ARGN}) - if (TARGET "${_library}" AND "${_strategy}" MATCHES "COPY_UNITY") - get_target_property(_libraryUnityTargetName ${_library} COTIRE_UNITY_TARGET_NAME) - if (TARGET "${_libraryUnityTargetName}") - list (APPEND _mappedLibraries "${_libraryUnityTargetName}") + if (_library MATCHES "^\\$$") + set (_libraryName "${CMAKE_MATCH_1}") + set (_linkOnly TRUE) + set (_objectLibrary FALSE) + elseif (_library MATCHES "^\\$$") + set (_libraryName "${CMAKE_MATCH_1}") + set (_linkOnly FALSE) + set (_objectLibrary TRUE) + else() + set (_libraryName "${_library}") + set (_linkOnly FALSE) + set (_objectLibrary FALSE) + endif() + if ("${_strategy}" MATCHES "COPY_UNITY") + cotire_is_target_supported(${_libraryName} _isSupported) + if (_isSupported) + # use target's corresponding unity target, if available + get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_libraryUnityTargetName}") + if (_linkOnly) + list (APPEND _mappedLibraries "$") + elseif (_objectLibrary) + list (APPEND _mappedLibraries "$") + else() + list (APPEND _mappedLibraries "${_libraryUnityTargetName}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() else() list (APPEND _mappedLibraries "${_library}") endif() @@ -2868,6 +3447,10 @@ function (cotire_map_libraries _strategy _mappedLibrariesVar) endfunction() function (cotire_target_link_libraries _target) + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + return() + endif() get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) if (TARGET "${_unityTargetName}") get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) @@ -2875,17 +3458,27 @@ function (cotire_target_link_libraries _target) message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") endif() if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") - if (CMAKE_VERSION VERSION_LESS "2.8.11") - message (WARNING "cotire: unity target link strategy ${_linkLibrariesStrategy} requires CMake 2.8.11 or later. Defaulting to NONE for ${_target}.") - else() - get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) - get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) - cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries} ${_interfaceLinkLibraries}) + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + if (_linkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}") + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}") + endif() + endif() + get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) + if (_interfaceLinkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}") if (COTIRE_DEBUG) - message (STATUS "unity target ${_unityTargetName} libraries: ${_unityLinkLibraries}") + message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}") endif() - if (_unityLinkLibraries) - target_link_libraries(${_unityTargetName} ${_unityLinkLibraries}) + endif() + get_target_property(_manualDependencies ${_target} MANUALLY_ADDED_DEPENDENCIES) + if (_manualDependencies) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityManualDependencies ${_manualDependencies}) + if (_unityManualDependencies) + add_dependencies("${_unityTargetName}" ${_unityManualDependencies}) endif() endif() endif() @@ -2901,7 +3494,7 @@ function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) # filter files in intermediate directory set (_filesToRemove "") foreach (_file ${_cotireFiles}) - get_filename_component(_dir "${_file}" PATH) + get_filename_component(_dir "${_file}" DIRECTORY) get_filename_component(_dirName "${_dir}" NAME) if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") list (APPEND _filesToRemove "${_file}") @@ -2909,7 +3502,7 @@ function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) endforeach() if (_filesToRemove) if (COTIRE_VERBOSE) - message (STATUS "removing ${_filesToRemove}") + message (STATUS "cleaning up ${_filesToRemove}") endif() file (REMOVE ${_filesToRemove}) endif() @@ -2919,6 +3512,7 @@ function (cotire_init_target _targetName) if (COTIRE_TARGETS_FOLDER) set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") endif() + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE) if (MSVC_IDE) set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) endif() @@ -2927,7 +3521,9 @@ endfunction() function (cotire_add_to_pch_all_target _pchTargetName) set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") if (NOT TARGET "${_targetName}") - add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) cotire_init_target("${_targetName}") endif() cotire_setup_clean_all_target() @@ -2937,7 +3533,9 @@ endfunction() function (cotire_add_to_unity_all_target _unityTargetName) set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") if (NOT TARGET "${_targetName}") - add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) cotire_init_target("${_targetName}") endif() cotire_setup_clean_all_target() @@ -2949,28 +3547,24 @@ function (cotire_setup_clean_all_target) if (NOT TARGET "${_targetName}") cotire_set_cmd_to_prologue(_cmds) list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") - add_custom_target(${_targetName} COMMAND ${_cmds} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Cleaning up all cotire generated files" VERBATIM) + add_custom_target(${_targetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up all cotire generated files" + VERBATIM) cotire_init_target("${_targetName}") endif() endfunction() function (cotire) set(_options "") - set(_oneValueArgs SOURCE_DIR BINARY_DIR) + set(_oneValueArgs "") set(_multiValueArgs LANGUAGES CONFIGURATIONS) cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) set (_targets ${_option_UNPARSED_ARGUMENTS}) - if (NOT _option_SOURCE_DIR) - set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - endif() - if (NOT _option_BINARY_DIR) - set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") - endif() foreach (_target ${_targets}) if (TARGET ${_target}) - cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS} - SOURCE_DIR "${_option_SOURCE_DIR}" BINARY_DIR "${_option_BINARY_DIR}") + cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}) else() message (WARNING "cotire: ${_target} is not a target.") endif() @@ -3006,14 +3600,6 @@ if (CMAKE_SCRIPT_MODE_FILE) message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") endif() - if (WIN32) - # for MSVC, compiler IDs may not always be set correctly - if (MSVC) - set (CMAKE_C_COMPILER_ID "MSVC") - set (CMAKE_CXX_COMPILER_ID "MSVC") - endif() - endif() - if (NOT COTIRE_BUILD_TYPE) set (COTIRE_BUILD_TYPE "None") endif() @@ -3041,19 +3627,36 @@ if (CMAKE_SCRIPT_MODE_FILE) if ("${COTIRE_ARGV1}" STREQUAL "unity") + if (XCODE) + # executing pre-build action under Xcode, check dependency on target script + set (_dependsOption DEPENDS "${COTIRE_ARGV2}") + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) + cotire_generate_unity_source( "${COTIRE_ARGV3}" ${_sources} LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV2}" SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} PRE_UNDEFS ${_targetPreUndefs} POST_UNDEFS ${_targetPostUndefs} SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} - SOURCES_POST_UNDEFS ${_sourcesPostUndefs}) + SOURCES_POST_UNDEFS ${_sourcesPostUndefs} + ${_dependsOption}) elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") + if (XCODE) + # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies + set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + set (_files "") foreach (_index RANGE 4 ${COTIRE_ARGC}) if (COTIRE_ARGV${_index}) @@ -3063,20 +3666,21 @@ if (CMAKE_SCRIPT_MODE_FILE) cotire_generate_prefix_header( "${COTIRE_ARGV3}" ${_files} + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" - COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS} IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" - INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}" + INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH} INCLUDE_DIRECTORIES ${_includeDirs} SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} COMPILE_DEFINITIONS ${_compileDefinitions} - COMPILE_FLAGS ${_compileFlags}) + COMPILE_FLAGS ${_compileFlags} + ${_dependsOption}) elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") @@ -3089,12 +3693,12 @@ if (CMAKE_SCRIPT_MODE_FILE) cotire_precompile_prefix_header( "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" - COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}" INCLUDE_DIRECTORIES ${_includeDirs} SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} COMPILE_DEFINITIONS ${_compileDefinitions} @@ -3103,9 +3707,11 @@ if (CMAKE_SCRIPT_MODE_FILE) elseif ("${COTIRE_ARGV1}" STREQUAL "combine") if (COTIRE_TARGET_LANGUAGE) - set (_startIndex 3) + set (_combinedFile "${COTIRE_ARGV3}") + set (_startIndex 4) else() - set (_startIndex 2) + set (_combinedFile "${COTIRE_ARGV2}") + set (_startIndex 3) endif() set (_files "") foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) @@ -3113,10 +3719,22 @@ if (CMAKE_SCRIPT_MODE_FILE) list (APPEND _files "${COTIRE_ARGV${_index}}") endif() endforeach() + + if (XCODE) + # executing pre-build action under Xcode, check dependency on files to be combined + set (_dependsOption DEPENDS ${_files}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + if (COTIRE_TARGET_LANGUAGE) - cotire_generate_unity_source(${_files} LANGUAGE "${COTIRE_TARGET_LANGUAGE}") + cotire_generate_unity_source( + "${_combinedFile}" ${_files} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + ${_dependsOption}) else() - cotire_generate_unity_source(${_files}) + cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption}) endif() elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") @@ -3132,9 +3750,6 @@ else() # cotire is being run in include mode # set up all variable and property definitions - unset (COTIRE_C_COMPILER_VERSION CACHE) - unset (COTIRE_CXX_COMPILER_VERSION CACHE) - if (NOT DEFINED COTIRE_DEBUG_INIT) if (DEFINED COTIRE_DEBUG) set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) @@ -3162,7 +3777,7 @@ else() set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING "Ignore sources with the listed file extensions from the generated unity source.") - set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING + set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "2" CACHE STRING "Minimum number of sources in target required to enable use of precompiled header.") if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) @@ -3202,6 +3817,13 @@ else() if (NOT COTIRE_PCH_TARGET_SUFFIX) set (COTIRE_PCH_TARGET_SUFFIX "_pch") endif() + if (MSVC) + # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code + # use a bigger default factor of 170 percent (128 MB) + if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170") + endif() + endif() if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") endif() @@ -3254,7 +3876,7 @@ else() FULL_DOCS "The variable can be set to an integer > 0." "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." - "If not defined, defaults to 3." + "If not defined, defaults to 2." ) define_property( @@ -3307,6 +3929,13 @@ else() "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." ) + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" + BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH." + ) + define_property( DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." @@ -3393,6 +4022,16 @@ else() "If not set, this property is initialized to the empty list." ) + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED + BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header." + "Header files are sorted according to the order of the directories in the property." + "If not set, this property is initialized to the empty list." + ) + define_property( TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." @@ -3448,7 +4087,7 @@ else() TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED BRIEF_DOCS "Define strategy for setting up unity target's link libraries." FULL_DOCS - "If this property is empty, the generated unity target's link libraries have to be set up manually." + "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually." "If this property is set to COPY, the unity target's link libraries will be copied from this target." "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." "Inherited from directory." @@ -3548,4 +4187,4 @@ else() message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") -endif() +endif() \ No newline at end of file diff --git a/include/Lucene.h b/include/Lucene.h index 358a5809..d7328e4e 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -9,8 +9,8 @@ #include "Config.h" -#include -#include +#include +#include #include #include #include diff --git a/src/demo/CMakeLists.txt b/src/demo/CMakeLists.txt index ee7538ab..d0d36020 100644 --- a/src/demo/CMakeLists.txt +++ b/src/demo/CMakeLists.txt @@ -21,7 +21,7 @@ add_executable(indexfiles ${demo_headers} ) target_link_libraries(indexfiles - lucene++ boost_system + lucene++ ${lucene_boost_libs} ) add_executable(searchfiles @@ -29,7 +29,7 @@ add_executable(searchfiles ${demo_headers} ) target_link_libraries(searchfiles - lucene++ boost_system + lucene++ ${lucene_boost_libs} ) add_executable(deletefiles @@ -37,5 +37,5 @@ add_executable(deletefiles ${demo_headers} ) target_link_libraries(deletefiles - lucene++ boost_system + lucene++ ${lucene_boost_libs} ) diff --git a/src/test/gtest/include/gtest/internal/gtest-internal.h b/src/test/gtest/include/gtest/internal/gtest-internal.h index ff8f6298..ba963156 100644 --- a/src/test/gtest/include/gtest/internal/gtest-internal.h +++ b/src/test/gtest/include/gtest/internal/gtest-internal.h @@ -50,9 +50,9 @@ # include #endif -#include -#include -#include +#include +#include +#include #include #include #include From f1169f6f3617871dc02e18e26cb4dd1b75a83aae Mon Sep 17 00:00:00 2001 From: Josh Stoddard Date: Wed, 6 Mar 2019 17:03:23 -0500 Subject: [PATCH 108/157] Handle all non-BMP chars as letters --- src/core/analysis/standard/StandardTokenizerImpl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/analysis/standard/StandardTokenizerImpl.cpp b/src/core/analysis/standard/StandardTokenizerImpl.cpp index 78930f64..3828dc76 100644 --- a/src/core/analysis/standard/StandardTokenizerImpl.cpp +++ b/src/core/analysis/standard/StandardTokenizerImpl.cpp @@ -425,11 +425,13 @@ int32_t StandardTokenizerImpl::getNextToken() { // Multilingual Plane. As a workaround to prevent crashes, treat all // characters above U+FFFF as letters in the tokenizer. // See https://github.com/luceneplusplus/LucenePlusPlus/issues/57 -#ifdef LPP_UNICODE_CHAR_SIZE_4 const wchar_t zzCMapFallback = zzCMapL['A']; +#ifdef LPP_UNICODE_CHAR_SIZE_4 #define zzCMap_at(n) ((n) > 0xFFFF ? zzCMapFallback : zzCMapL[n]) #else - #define zzCMap_at(n) (zzCMapL[n]) + // If the 16-bit value is in [0xD800, 0xDFFF], it is part of a multi-byte + // UTF-16 character and its UTF code point is > U+FFFF, so handle as above. + #define zzCMap_at(n) (((n) & 0xF800) == 0xD800 ? zzCMapFallback : zzCMapL[n]) #endif const int32_t* zzTransL = ZZ_TRANS(); From 9e7ea78eb3186584e524b78c58a0aa22effae396 Mon Sep 17 00:00:00 2001 From: Josh Stoddard Date: Thu, 7 Mar 2019 10:32:56 -0500 Subject: [PATCH 109/157] fix improper override --- include/PhraseScorer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/PhraseScorer.h b/include/PhraseScorer.h index 09a4938a..c36e3ce3 100644 --- a/include/PhraseScorer.h +++ b/include/PhraseScorer.h @@ -46,7 +46,7 @@ class PhraseScorer : public Scorer { /// Phrase frequency in current doc as computed by phraseFreq(). double currentFreq(); - float termFreq(){ + virtual float termFreq(){ return currentFreq(); } From 72dac36558390f39f368af699210e225b61015cb Mon Sep 17 00:00:00 2001 From: Josh Stoddard Date: Thu, 14 Mar 2019 15:10:34 -0400 Subject: [PATCH 110/157] fix query parse with no position increment --- src/core/queryparser/QueryParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/queryparser/QueryParser.cpp b/src/core/queryparser/QueryParser.cpp index 2f41c8a6..f05f7b67 100644 --- a/src/core/queryparser/QueryParser.cpp +++ b/src/core/queryparser/QueryParser.cpp @@ -368,7 +368,7 @@ QueryPtr QueryParser::getFieldQuery(const String& field, const String& queryText return newTermQuery(newLucene(field, term)); } else { if (severalTokensAtSamePosition) { - if (positionCount == 1) { + if (positionCount <= 1) { // no phrase query BooleanQueryPtr q(newBooleanQuery(true)); for (int32_t i = 0; i < numTokens; ++i) { From df37106adeac93fdbd16c08f48a32bdfc3f7c5d9 Mon Sep 17 00:00:00 2001 From: Josh Stoddard Date: Mon, 25 Mar 2019 10:01:32 -0400 Subject: [PATCH 111/157] fix stem filter --- src/core/analysis/PorterStemFilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/analysis/PorterStemFilter.cpp b/src/core/analysis/PorterStemFilter.cpp index 0ae5689f..55862d31 100644 --- a/src/core/analysis/PorterStemFilter.cpp +++ b/src/core/analysis/PorterStemFilter.cpp @@ -24,7 +24,7 @@ bool PorterStemFilter::incrementToken() { return false; } - if (stemmer->stem(termAtt->termBuffer())) { + if (stemmer->stem(termAtt->termBufferArray(), termAtt->termLength() - 1)) { termAtt->setTermBuffer(stemmer->getResultBuffer(), 0, stemmer->getResultLength()); } return true; From c3602b3230d46505f667c8e4bd64cb1d7f398b51 Mon Sep 17 00:00:00 2001 From: Josh Stoddard Date: Tue, 26 Mar 2019 14:41:46 -0400 Subject: [PATCH 112/157] port of LUCENE-5503 fix --- .../highlighter/WeightedSpanTermExtractor.cpp | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp index 774967ce..19ae902a 100644 --- a/src/contrib/highlighter/WeightedSpanTermExtractor.cpp +++ b/src/contrib/highlighter/WeightedSpanTermExtractor.cpp @@ -68,29 +68,19 @@ void WeightedSpanTermExtractor::extract(const QueryPtr& query, const MapWeighted for (int32_t i = 0; i < phraseQueryTerms.size(); ++i) { clauses[i] = newLucene(phraseQueryTerms[i]); } - int32_t slop = phraseQuery->getSlop(); + + // sum position increments beyond 1 + int32_t positionGaps = 0; Collection positions(phraseQuery->getPositions()); - // add largest position increment to slop - if (!positions.empty()) { - int32_t lastPos = positions[0]; - int32_t largestInc = 0; - int32_t sz = positions.size(); - for (int32_t i = 1; i < sz; ++i) { - int32_t pos = positions[i]; - int32_t inc = pos - lastPos; - if (inc > largestInc) { - largestInc = inc; - } - lastPos = pos; - } - if (largestInc > 1) { - slop += largestInc; - } + if (!positions.empty() && positions.size() > 1) { + // positions are in increasing order. max(0,...) is just a safeguard. + positionGaps = (std::max)(0, positions[positions.size() - 1] - positions[0] - positions.size() + 1 ); } - bool inorder = (slop == 0); + //if original slop is 0 then require inOrder + bool inorder = (phraseQuery->getSlop() == 0); - SpanNearQueryPtr sp(newLucene(clauses, slop, inorder)); + SpanNearQueryPtr sp(newLucene(clauses, phraseQuery->getSlop() + positionGaps, inorder)); sp->setBoost(_query->getBoost()); extractWeightedSpanTerms(terms, sp); } else if (MiscUtils::typeOf(_query)) { From afa8a41597143541880c1278f5bfe48e1e51a395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Sat, 20 Apr 2019 19:33:22 +0200 Subject: [PATCH 113/157] Assign lockFile value in SimpleFSLock constructor Due to a typo, the lockFile member was always empty - the constructor assigned it to itself. --- src/core/store/SimpleFSLockFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/store/SimpleFSLockFactory.cpp b/src/core/store/SimpleFSLockFactory.cpp index 76a75a42..fcbbc615 100644 --- a/src/core/store/SimpleFSLockFactory.cpp +++ b/src/core/store/SimpleFSLockFactory.cpp @@ -38,7 +38,7 @@ void SimpleFSLockFactory::clearLock(const String& lockName) { SimpleFSLock::SimpleFSLock(const String& lockDir, const String& lockFileName) { this->lockDir = lockDir; - this->lockFile = lockFile; + this->lockFile = lockFileName; } SimpleFSLock::~SimpleFSLock() { From ef8875441eb69bdf87bb38755295b7dd5a15a977 Mon Sep 17 00:00:00 2001 From: Matt Taylor Date: Tue, 13 Aug 2019 11:07:06 -0400 Subject: [PATCH 114/157] Fix unescaped backslash in path in README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 4c96d234..c348d9b9 100644 --- a/README.rst +++ b/README.rst @@ -50,7 +50,7 @@ Build Instructions for Windows systems Open solution lucene++.sln located in the *msvc* folder into Visual Studio 2010+ and build. -**Note: you will need to edit the include\Config.h.cmake file. Make a copy, rename it to Config.h, and replace** +**Note: you will need to edit the include\\Config.h.cmake file. Make a copy, rename it to Config.h, and replace** #@DEFINE_USE_CYCLIC_CHECK@ LPP_USE_CYCLIC_CHECK From 0b97cc39782efdc30eb126c828b80cff7b9b14ac Mon Sep 17 00:00:00 2001 From: josh-stoddard-tanium Date: Fri, 21 Jun 2019 09:39:36 -0400 Subject: [PATCH 115/157] Don't retain input file handles (#4) - Don't retain input file handles in the IndexReader between reads. This can lead to file handle exhaustion for highly segmented indices. - Throw immediately on failure to open or write to an output file. --- src/core/include/_SimpleFSDirectory.h | 2 +- src/core/store/SimpleFSDirectory.cpp | 52 ++++++++++++++++++--------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/core/include/_SimpleFSDirectory.h b/src/core/include/_SimpleFSDirectory.h index 379f3aaa..1818f847 100644 --- a/src/core/include/_SimpleFSDirectory.h +++ b/src/core/include/_SimpleFSDirectory.h @@ -24,7 +24,7 @@ class InputFile : public LuceneObject { static const int32_t FILE_ERROR; protected: - ifstreamPtr file; + String path; int64_t position; int64_t length; diff --git a/src/core/store/SimpleFSDirectory.cpp b/src/core/store/SimpleFSDirectory.cpp index 88d39498..bf142d4b 100644 --- a/src/core/store/SimpleFSDirectory.cpp +++ b/src/core/store/SimpleFSDirectory.cpp @@ -39,8 +39,9 @@ const int32_t InputFile::FILE_EOF = FileReader::FILE_EOF; const int32_t InputFile::FILE_ERROR = FileReader::FILE_ERROR; InputFile::InputFile(const String& path) { - file = newInstance(path, std::ios::binary | std::ios::in); - if (!file->is_open()) { + this->path = path; + if (!FileUtils::fileExists(path)) + { boost::throw_exception(FileNotFoundException(path)); } position = 0; @@ -52,8 +53,8 @@ InputFile::~InputFile() { void InputFile::setPosition(int64_t position) { this->position = position; - file->seekg((std::streamoff)position); - if (!file->good()) { + if (position < 0 || position > length) + { boost::throw_exception(IOException()); } } @@ -68,11 +69,17 @@ int64_t InputFile::getLength() { int32_t InputFile::read(uint8_t* b, int32_t offset, int32_t length) { try { - if (file->eof()) { + boost::filesystem::ifstream file(path, std::ios::binary | std::ios::in); + file.seekg((std::streamoff)position); + if (!file.is_open() || !file.good()) + { + return FILE_ERROR; + } + if (file.eof()) { return FILE_EOF; } - file->read((char*)b + offset, length); - int32_t readCount = file->gcount(); + file.read((char*)b + offset, length); + int32_t readCount = file.gcount(); position += readCount; return readCount; } catch (...) { @@ -81,13 +88,13 @@ int32_t InputFile::read(uint8_t* b, int32_t offset, int32_t length) { } void InputFile::close() { - if (file->is_open()) { - file->close(); - } + // NOOP } bool InputFile::isValid() { - return (file && file->is_open() && file->good()); + boost::filesystem::ifstream file(path, std::ios::binary | std::ios::in); + file.seekg((std::streamoff)position); + return (file.is_open() && file.good()); } SimpleFSIndexInput::SimpleFSIndexInput() { @@ -156,6 +163,12 @@ LuceneObjectPtr SimpleFSIndexInput::clone(const LuceneObjectPtr& other) { OutputFile::OutputFile(const String& path) { this->path = path; file = newInstance(path, std::ios::binary | std::ios::out); + if (!isValid()) + { + std::wostringstream msg; + msg << L"failed to open file for write: " << path; + boost::throw_exception(IOException(msg.str())); + } } OutputFile::~OutputFile() { @@ -163,14 +176,19 @@ OutputFile::~OutputFile() { bool OutputFile::write(const uint8_t* b, int32_t offset, int32_t length) { if (!file->is_open()) { - return false; + std::wostringstream msg; + msg << L"file is closed: " << path; + boost::throw_exception(IOException(msg.str())); } - try { - file->write((char*)b + offset, length); - return file->good(); - } catch (...) { - return false; + + file->write((char*)b + offset, length); + if( !file->good() ) + { + std::wostringstream msg; + msg << L"error writing file: " << path << L" bad=" << file->bad() << L" fail=" << file->fail() << L" eof=" << file->eof(); + boost::throw_exception(IOException(msg.str())); } + return true; } void OutputFile::close() { From cf444262c270f2bc424f408f4ca2698bbee06cd6 Mon Sep 17 00:00:00 2001 From: josh-stoddard-tanium Date: Wed, 10 Jul 2019 09:56:19 -0400 Subject: [PATCH 116/157] Propagate errors reading input files (#5) Also add a proper `what()` to `LuceneException` --- include/LuceneException.h | 4 ++++ src/core/store/SimpleFSDirectory.cpp | 5 +++++ src/core/util/LuceneException.cpp | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/include/LuceneException.h b/include/LuceneException.h index 91d09b07..b24701e7 100644 --- a/include/LuceneException.h +++ b/include/LuceneException.h @@ -52,11 +52,15 @@ class LPPAPI LuceneException : public std::exception { ExceptionType type; String error; + std::string _what; + public: ExceptionType getType() const; String getError() const; bool isNull() const; void throwException(); + + virtual const char* what() const throw(); }; template diff --git a/src/core/store/SimpleFSDirectory.cpp b/src/core/store/SimpleFSDirectory.cpp index 88d39498..ff80b694 100644 --- a/src/core/store/SimpleFSDirectory.cpp +++ b/src/core/store/SimpleFSDirectory.cpp @@ -122,6 +122,11 @@ void SimpleFSIndexInput::readInternal(uint8_t* b, int32_t offset, int32_t length if (i == InputFile::FILE_EOF) { boost::throw_exception(IOException(L"Read past EOF")); } + else if (i == InputFile::FILE_ERROR) { + std::wostringstream msg; + msg << L"Failed to read from file: " << path; + boost::throw_exception(IOException(msg.str())); + } total += i; } } diff --git a/src/core/util/LuceneException.cpp b/src/core/util/LuceneException.cpp index ab69d6d1..2d0bb35c 100644 --- a/src/core/util/LuceneException.cpp +++ b/src/core/util/LuceneException.cpp @@ -6,12 +6,16 @@ #include "LuceneInc.h" #include "LuceneException.h" +#include "StringUtils.h" namespace Lucene { LuceneException::LuceneException(const String& error, ExceptionType type) throw() { this->error = error; this->type = type; + SingleStringStream ss; + ss << "LuceneException[" << type << "]: " << StringUtils::toUTF8(error); + this->_what = ss.str(); } LuceneException::~LuceneException() throw() { @@ -91,4 +95,9 @@ void LuceneException::throwException() { } } +const char* LuceneException::what() const throw() +{ + return _what.c_str(); +} + } From ae9120a42fa5dc150451a541eca54cdd1bb72a8b Mon Sep 17 00:00:00 2001 From: Damon Revoe Date: Sat, 9 May 2020 12:07:51 -0400 Subject: [PATCH 117/157] Use CMAKE_CURRENT_SOURCE_DIR for CMAKE_MODULE_PATH The top-level CMakeLists.txt is setting CMAKE_MODULE_PATH based on CMAKE_SOURCE_DIR. This causes failure to find the CMake modules when Lucene++ is included as a submodule in another project. This commit fixes the definition of CMAKE_MODULE_PATH by using CMAKE_CURRENT_SOURCE_DIR instead. Note that everywhere else in CMakeLists.txt, the correct variable (CMAKE_CURRENT_SOURCE_DIR) is used already. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e63c59d1..d246d3da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ set(lucene++_VERSION ) # include specific modules -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") #################################### # pre-compiled headers support From 51751e5704c3f35ccba3fe916099ff86a24b24c4 Mon Sep 17 00:00:00 2001 From: Merwan Date: Fri, 12 Jun 2020 18:10:59 +0200 Subject: [PATCH 118/157] Add LUCENE_BUILD_STATIC option --- CMakeLists.txt | 4 ++++ src/contrib/CMakeLists.txt | 15 +++++++++++---- src/core/CMakeLists.txt | 12 +++++++++--- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d246d3da..67100131 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,10 @@ if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() +option(LUCENE_BUILD_STATIC + "Build a static library" + OFF +) option(ENABLE_PACKAGING "Create build scripts for creating lucene++ packages" OFF diff --git a/src/contrib/CMakeLists.txt b/src/contrib/CMakeLists.txt index 76f81e31..c58cff7f 100644 --- a/src/contrib/CMakeLists.txt +++ b/src/contrib/CMakeLists.txt @@ -34,10 +34,17 @@ install(FILES ${contrib_headers} COMPONENT development-contrib ) -add_library(lucene++-contrib SHARED - ${contrib_sources} - ${contrib_headers} -) +if (LUCENE_BUILD_STATIC) + add_library(lucene++-contrib STATIC + ${contrib_sources} + ${contrib_headers} + ) +else() + add_library(lucene++-contrib SHARED + ${contrib_sources} + ${contrib_headers} + ) +endif() set_target_properties(lucene++-contrib PROPERTIES VERSION ${lucene++_VERSION} diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 13ff0a60..ca7e37c4 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -25,9 +25,15 @@ file(GLOB_RECURSE lucene_headers add_definitions(-DLPP_BUILDING_LIB) -add_library(lucene++ SHARED - ${lucene_sources} -) +if (LUCENE_BUILD_STATIC) + add_library(lucene++ STATIC + ${lucene_sources} + ) +else() + add_library(lucene++ SHARED + ${lucene_sources} + ) +endif() target_link_libraries(lucene++ ${CMAKE_THREAD_LIBS_INIT} From 75a5fe25641c59fab2f1e11837d5592fee846f19 Mon Sep 17 00:00:00 2001 From: Merwan Date: Mon, 15 Jun 2020 10:56:11 +0200 Subject: [PATCH 119/157] Define WIN32_LEAN_AND_MEAN and NOMINMAX via CMake --- CMakeLists.txt | 6 ++++++ src/contrib/include/ContribInc.h | 5 +++++ src/core/include/LuceneInc.h | 3 +++ src/demo/deletefiles/main.cpp | 2 ++ src/demo/indexfiles/main.cpp | 2 ++ src/demo/searchfiles/main.cpp | 6 ++++++ src/test/include/TestInc.h | 5 +++++ src/test/main/main.cpp | 5 +++++ 8 files changed, 34 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d246d3da..c92f77af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,12 @@ if(MSVC) # enable exceptions, see http://msdn.microsoft.com/en-us/library/1deeycx5.aspx add_definitions(-EHsc) + + # Disable including too many Windows headers + add_definitions(-DWIN32_LEAN_AND_MEAN) + + # Disable the min/max macros that conflict with std::min/std::max + add_definitions(-DNOMINMAX) endif() if(NOT WIN32 AND NOT CMAKE_SYSTEM MATCHES "SunOS-5*.") diff --git a/src/contrib/include/ContribInc.h b/src/contrib/include/ContribInc.h index 777bd0e8..87d50b5c 100644 --- a/src/contrib/include/ContribInc.h +++ b/src/contrib/include/ContribInc.h @@ -8,8 +8,13 @@ #include "targetver.h" +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif + +#ifndef NOMINMAX #define NOMINMAX +#endif #include diff --git a/src/core/include/LuceneInc.h b/src/core/include/LuceneInc.h index a0999194..b3943bab 100644 --- a/src/core/include/LuceneInc.h +++ b/src/core/include/LuceneInc.h @@ -8,7 +8,10 @@ #include "targetver.h" +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif + #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/demo/deletefiles/main.cpp b/src/demo/deletefiles/main.cpp index eb42c984..0c31cb4c 100644 --- a/src/demo/deletefiles/main.cpp +++ b/src/demo/deletefiles/main.cpp @@ -4,7 +4,9 @@ // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// +#ifndef NOMINMAX #define NOMINMAX +#endif #include "targetver.h" #include diff --git a/src/demo/indexfiles/main.cpp b/src/demo/indexfiles/main.cpp index f3b77d18..15d5f512 100644 --- a/src/demo/indexfiles/main.cpp +++ b/src/demo/indexfiles/main.cpp @@ -4,7 +4,9 @@ // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// +#ifndef NOMINMAX #define NOMINMAX +#endif #include "targetver.h" #include diff --git a/src/demo/searchfiles/main.cpp b/src/demo/searchfiles/main.cpp index 748003c8..63686e2a 100644 --- a/src/demo/searchfiles/main.cpp +++ b/src/demo/searchfiles/main.cpp @@ -4,7 +4,13 @@ // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#ifndef NOMINMAX #define NOMINMAX +#endif #include "targetver.h" #include diff --git a/src/test/include/TestInc.h b/src/test/include/TestInc.h index a0056c7a..77026a7a 100644 --- a/src/test/include/TestInc.h +++ b/src/test/include/TestInc.h @@ -8,8 +8,13 @@ #include "targetver.h" +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif + +#ifndef NOMINMAX #define NOMINMAX +#endif #include diff --git a/src/test/main/main.cpp b/src/test/main/main.cpp index 8bf816e7..2e9525c9 100644 --- a/src/test/main/main.cpp +++ b/src/test/main/main.cpp @@ -10,8 +10,13 @@ #include "targetver.h" +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif + +#ifndef NOMINMAX #define NOMINMAX +#endif #include From f33553eb1116f5b1f051c234f13aacd1f519ae73 Mon Sep 17 00:00:00 2001 From: Merwan Date: Mon, 15 Jun 2020 14:29:43 +0200 Subject: [PATCH 120/157] Fix std::unary_function missing from C++17 --- include/Lucene.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Lucene.h b/include/Lucene.h index d7328e4e..ee2faff2 100644 --- a/include/Lucene.h +++ b/include/Lucene.h @@ -122,14 +122,14 @@ struct luceneWeakEquals { }; template -struct luceneHash : std::unary_function { +struct luceneHash { std::size_t operator()(const TYPE& type) const { return type ? type->hashCode() : 0; } }; template -struct luceneWeakHash : std::unary_function { +struct luceneWeakHash { std::size_t operator()(const TYPE& type) const { return type.expired() ? 0 : type.lock()->hashCode(); } From f6ba1f4c89f86629a08840674f100d7c7ea5cb7b Mon Sep 17 00:00:00 2001 From: p01arst0rm Date: Tue, 14 Jul 2020 09:30:03 +0100 Subject: [PATCH 121/157] added BOOST_USE_WINDOWS_H to config.h --- include/Config.h.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/Config.h.cmake b/include/Config.h.cmake index 203fec3e..9bbe5f8f 100644 --- a/include/Config.h.cmake +++ b/include/Config.h.cmake @@ -81,3 +81,8 @@ #define BOOST_FILESYSTEM_VERSION 3 #endif + +// Use windows definitions +#if defined(_WIN32) || defined(_WIN64) +#define BOOST_USE_WINDOWS_H +#endif From 8c626829ae9ac6a299f45a08b3de6a5427bc8679 Mon Sep 17 00:00:00 2001 From: p01arst0rm Date: Sun, 2 Aug 2020 04:09:47 +0100 Subject: [PATCH 122/157] added LPPAPI definitions missing in headers --- include/Base64.h | 2 +- include/InputStreamReader.h | 2 +- include/TestPoint.h | 2 +- include/UTF8Stream.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Base64.h b/include/Base64.h index 68db9e50..117e2af3 100644 --- a/include/Base64.h +++ b/include/Base64.h @@ -11,7 +11,7 @@ namespace Lucene { -class Base64 : public LuceneObject { +class LPPAPI Base64 : public LuceneObject { public: virtual ~Base64(); LUCENE_CLASS(Base64); diff --git a/include/InputStreamReader.h b/include/InputStreamReader.h index 1dd7730f..a26bbefd 100644 --- a/include/InputStreamReader.h +++ b/include/InputStreamReader.h @@ -12,7 +12,7 @@ namespace Lucene { /// An InputStreamReader is a bridge from byte streams to character streams. -class InputStreamReader : public Reader { +class LPPAPI InputStreamReader : public Reader { public: /// Create an InputStreamReader that uses the utf8 charset. InputStreamReader(const ReaderPtr& reader); diff --git a/include/TestPoint.h b/include/TestPoint.h index b387cd3d..439b6df1 100644 --- a/include/TestPoint.h +++ b/include/TestPoint.h @@ -12,7 +12,7 @@ namespace Lucene { /// Used for unit testing as a substitute for stack trace -class TestPoint { +class LPPAPI TestPoint { public: virtual ~TestPoint(); diff --git a/include/UTF8Stream.h b/include/UTF8Stream.h index 866b85b8..0a56f016 100644 --- a/include/UTF8Stream.h +++ b/include/UTF8Stream.h @@ -11,7 +11,7 @@ namespace Lucene { -class UTF8Base : public LuceneObject { +class LPPAPI UTF8Base : public LuceneObject { public: virtual ~UTF8Base(); LUCENE_CLASS(UTF8Base); From a8707970aa9d980c9a4f19216b536ca6992316c5 Mon Sep 17 00:00:00 2001 From: p01arst0rm Date: Fri, 7 Aug 2020 02:36:39 +0100 Subject: [PATCH 123/157] added missing WIN32_LEAN_AND_MEAN definition to demos --- src/demo/deletefiles/main.cpp | 4 ++++ src/demo/indexfiles/main.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/demo/deletefiles/main.cpp b/src/demo/deletefiles/main.cpp index 0c31cb4c..dc546618 100644 --- a/src/demo/deletefiles/main.cpp +++ b/src/demo/deletefiles/main.cpp @@ -4,6 +4,10 @@ // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/demo/indexfiles/main.cpp b/src/demo/indexfiles/main.cpp index 15d5f512..e6911f48 100644 --- a/src/demo/indexfiles/main.cpp +++ b/src/demo/indexfiles/main.cpp @@ -4,6 +4,10 @@ // or the GNU Lesser General Public License. ///////////////////////////////////////////////////////////////////////////// +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + #ifndef NOMINMAX #define NOMINMAX #endif From e5673eae5d89f37d44e7f1b614f20a7872f1f5a1 Mon Sep 17 00:00:00 2001 From: p01arst0rm Date: Sun, 9 Aug 2020 07:46:25 +0100 Subject: [PATCH 124/157] fixed missing LPPAPI definitions --- include/BooleanScorer.h | 2 +- include/ByteBlockPool.h | 4 ++-- include/ByteSliceReader.h | 2 +- include/ByteSliceWriter.h | 2 +- include/CompoundFileReader.h | 4 ++-- include/CompoundFileWriter.h | 2 +- include/DirectoryReader.h | 2 +- include/DocumentsWriter.h | 2 +- include/FieldInfos.h | 2 +- include/FieldsReader.h | 2 +- include/HitQueue.h | 2 +- include/IndexFileDeleter.h | 2 +- include/IndexFileNames.h | 2 +- include/RAMInputStream.h | 2 +- include/RAMOutputStream.h | 2 +- include/ReadOnlyDirectoryReader.h | 2 +- include/ReadOnlySegmentReader.h | 2 +- include/SegmentMerger.h | 2 +- include/SegmentTermDocs.h | 2 +- include/SegmentTermEnum.h | 2 +- include/SegmentTermPositionVector.h | 2 +- include/SegmentTermPositions.h | 2 +- include/SegmentTermVector.h | 2 +- include/TermScorer.h | 2 +- include/TermVectorsReader.h | 2 +- include/TestPoint.h | 2 +- src/core/include/_ConcurrentMergeScheduler.h | 2 +- src/core/include/_NumericRangeQuery.h | 2 +- src/core/include/_SegmentReader.h | 6 +++--- src/core/include/_SimpleFSDirectory.h | 4 ++-- src/test/include/MockRAMDirectory.h | 2 +- src/test/include/MockRAMOutputStream.h | 2 +- 32 files changed, 37 insertions(+), 37 deletions(-) diff --git a/include/BooleanScorer.h b/include/BooleanScorer.h index fd1e0d93..fab5adae 100644 --- a/include/BooleanScorer.h +++ b/include/BooleanScorer.h @@ -27,7 +27,7 @@ namespace Lucene { /// the last, then there's a hit. When some terms are required and some terms are optional, the conjunction can /// be evaluated first, then the optional terms can all skip to the match and be added to the score. Thus the /// conjunction can reduce the number of priority queue updates for the optional terms. -class BooleanScorer : public Scorer { +class LPPAPI BooleanScorer : public Scorer { public: BooleanScorer(const SimilarityPtr& similarity, int32_t minNrShouldMatch, Collection optionalScorers, Collection prohibitedScorers); virtual ~BooleanScorer(); diff --git a/include/ByteBlockPool.h b/include/ByteBlockPool.h index 7b084f2e..c0df8c63 100644 --- a/include/ByteBlockPool.h +++ b/include/ByteBlockPool.h @@ -20,7 +20,7 @@ namespace Lucene { /// Each slice is filled with 0's initially, and we mark the end with a non-zero byte. This way the methods /// that are writing into the slice don't need to record its length and instead allocate a new slice once /// they hit a non-zero byte. -class ByteBlockPool : public LuceneObject { +class LPPAPI ByteBlockPool : public LuceneObject { public: ByteBlockPool(const ByteBlockPoolAllocatorBasePtr& allocator, bool trackAllocations); virtual ~ByteBlockPool(); @@ -51,7 +51,7 @@ class ByteBlockPool : public LuceneObject { int32_t allocSlice(ByteArray slice, int32_t upto); }; -class ByteBlockPoolAllocatorBase : public LuceneObject { +class LPPAPI ByteBlockPoolAllocatorBase : public LuceneObject { public: virtual ~ByteBlockPoolAllocatorBase(); diff --git a/include/ByteSliceReader.h b/include/ByteSliceReader.h index 0a9234cf..1e0d2b1d 100644 --- a/include/ByteSliceReader.h +++ b/include/ByteSliceReader.h @@ -13,7 +13,7 @@ namespace Lucene { /// IndexInput that knows how to read the byte slices written by Posting and PostingVector. We read the bytes in each slice /// until we hit the end of that slice at which point we read the forwarding address of the next slice and then jump to it. -class ByteSliceReader : public IndexInput { +class LPPAPI ByteSliceReader : public IndexInput { public: ByteSliceReader(); virtual ~ByteSliceReader(); diff --git a/include/ByteSliceWriter.h b/include/ByteSliceWriter.h index f4c16e7f..85f3e661 100644 --- a/include/ByteSliceWriter.h +++ b/include/ByteSliceWriter.h @@ -13,7 +13,7 @@ namespace Lucene { /// Class to write byte streams into slices of shared byte[]. This is used by DocumentsWriter to hold /// the posting list for many terms in RAM. -class ByteSliceWriter : public LuceneObject { +class LPPAPI ByteSliceWriter : public LuceneObject { public: ByteSliceWriter(const ByteBlockPoolPtr& pool); virtual ~ByteSliceWriter(); diff --git a/include/CompoundFileReader.h b/include/CompoundFileReader.h index e82d7904..8de2adf3 100644 --- a/include/CompoundFileReader.h +++ b/include/CompoundFileReader.h @@ -15,7 +15,7 @@ namespace Lucene { /// Class for accessing a compound stream. /// This class implements a directory, but is limited to only read operations. /// Directory methods that would normally modify data throw an exception. -class CompoundFileReader : public Directory { +class LPPAPI CompoundFileReader : public Directory { public: CompoundFileReader(const DirectoryPtr& dir, const String& name); CompoundFileReader(const DirectoryPtr& dir, const String& name, int32_t readBufferSize); @@ -80,7 +80,7 @@ class CompoundFileReader : public Directory { }; /// Implementation of an IndexInput that reads from a portion of the compound file. -class CSIndexInput : public BufferedIndexInput { +class LPPAPI CSIndexInput : public BufferedIndexInput { public: CSIndexInput(); CSIndexInput(const IndexInputPtr& base, int64_t fileOffset, int64_t length); diff --git a/include/CompoundFileWriter.h b/include/CompoundFileWriter.h index e2d3f26f..804d0d71 100644 --- a/include/CompoundFileWriter.h +++ b/include/CompoundFileWriter.h @@ -24,7 +24,7 @@ namespace Lucene { /// The fileCount integer indicates how many files are contained in this compound file. The {directory} /// that follows has that many entries. Each directory entry contains a long pointer to the start of /// this file's data section, and a string with that file's name. -class CompoundFileWriter : public LuceneObject { +class LPPAPI CompoundFileWriter : public LuceneObject { public: CompoundFileWriter(const DirectoryPtr& dir, const String& name, const CheckAbortPtr& checkAbort = CheckAbortPtr()); virtual ~CompoundFileWriter(); diff --git a/include/DirectoryReader.h b/include/DirectoryReader.h index 0fa417d9..0dd2753c 100644 --- a/include/DirectoryReader.h +++ b/include/DirectoryReader.h @@ -16,7 +16,7 @@ namespace Lucene { /// An IndexReader which reads indexes with multiple segments. -class DirectoryReader : public IndexReader { +class LPPAPI DirectoryReader : public IndexReader { public: /// Construct reading the named set of readers. DirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, bool readOnly, int32_t termInfosIndexDivisor); diff --git a/include/DocumentsWriter.h b/include/DocumentsWriter.h index a3d8905f..a33a29ef 100644 --- a/include/DocumentsWriter.h +++ b/include/DocumentsWriter.h @@ -51,7 +51,7 @@ namespace Lucene { /// updates are consistent, but, they represent only a part of the document seen up until the exception was hit. /// When this happens, we immediately mark the document as deleted so that the document is always atomically /// ("all or none") added to the index. -class DocumentsWriter : public LuceneObject { +class LPPAPI DocumentsWriter : public LuceneObject { public: DocumentsWriter(const DirectoryPtr& directory, const IndexWriterPtr& writer, const IndexingChainPtr& indexingChain); virtual ~DocumentsWriter(); diff --git a/include/FieldInfos.h b/include/FieldInfos.h index 61dcfda0..310fc8ac 100644 --- a/include/FieldInfos.h +++ b/include/FieldInfos.h @@ -15,7 +15,7 @@ namespace Lucene { /// Each segment has a separate Fieldable Info file. Objects of this class are thread-safe for multiple /// readers, but only one thread can be adding documents at a time, with no other reader or writer threads /// accessing this object. -class FieldInfos : public LuceneObject { +class LPPAPI FieldInfos : public LuceneObject { public: FieldInfos(); diff --git a/include/FieldsReader.h b/include/FieldsReader.h index 3d4d4ed1..a524e0cc 100644 --- a/include/FieldsReader.h +++ b/include/FieldsReader.h @@ -13,7 +13,7 @@ namespace Lucene { /// Class responsible for access to stored document fields. It uses .fdt and .fdx; files. -class FieldsReader : public LuceneObject { +class LPPAPI FieldsReader : public LuceneObject { public: /// Used only by clone FieldsReader(const FieldInfosPtr& fieldInfos, int32_t numTotalDocs, int32_t size, int32_t format, int32_t formatSize, diff --git a/include/HitQueue.h b/include/HitQueue.h index a9f10681..db61e81a 100644 --- a/include/HitQueue.h +++ b/include/HitQueue.h @@ -11,7 +11,7 @@ namespace Lucene { -class HitQueue : public HitQueueBase { +class LPPAPI HitQueue : public HitQueueBase { public: /// Creates a new instance with size elements. HitQueue(int32_t size, bool prePopulate); diff --git a/include/IndexFileDeleter.h b/include/IndexFileDeleter.h index c774b0dc..474f5adb 100644 --- a/include/IndexFileDeleter.h +++ b/include/IndexFileDeleter.h @@ -31,7 +31,7 @@ namespace Lucene { /// /// Note that you must hold the write.lock before instantiating this class. It opens segments_N file(s) directly /// with no retry logic. -class IndexFileDeleter : public LuceneObject { +class LPPAPI IndexFileDeleter : public LuceneObject { public: /// Initialize the deleter: find all previous commits in the Directory, incref the files they reference, call /// the policy to let it delete commits. This will remove any files not referenced by any of the commits. diff --git a/include/IndexFileNames.h b/include/IndexFileNames.h index d157d78e..a62e6ef1 100644 --- a/include/IndexFileNames.h +++ b/include/IndexFileNames.h @@ -12,7 +12,7 @@ namespace Lucene { /// Constants representing filenames and extensions used by Lucene. -class IndexFileNames : public LuceneObject { +class LPPAPI IndexFileNames : public LuceneObject { public: virtual ~IndexFileNames(); LUCENE_CLASS(IndexFileNames); diff --git a/include/RAMInputStream.h b/include/RAMInputStream.h index a16342ab..142385b3 100644 --- a/include/RAMInputStream.h +++ b/include/RAMInputStream.h @@ -12,7 +12,7 @@ namespace Lucene { /// A memory-resident {@link IndexInput} implementation. -class RAMInputStream : public IndexInput { +class LPPAPI RAMInputStream : public IndexInput { public: RAMInputStream(); RAMInputStream(const RAMFilePtr& f); diff --git a/include/RAMOutputStream.h b/include/RAMOutputStream.h index 26d25ed4..23814aa9 100644 --- a/include/RAMOutputStream.h +++ b/include/RAMOutputStream.h @@ -12,7 +12,7 @@ namespace Lucene { /// A memory-resident {@link IndexOutput} implementation. -class RAMOutputStream : public IndexOutput { +class LPPAPI RAMOutputStream : public IndexOutput { public: /// Construct an empty output buffer. RAMOutputStream(); diff --git a/include/ReadOnlyDirectoryReader.h b/include/ReadOnlyDirectoryReader.h index 241a1f0f..eff9715d 100644 --- a/include/ReadOnlyDirectoryReader.h +++ b/include/ReadOnlyDirectoryReader.h @@ -11,7 +11,7 @@ namespace Lucene { -class ReadOnlyDirectoryReader : public DirectoryReader { +class LPPAPI ReadOnlyDirectoryReader : public DirectoryReader { public: ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& sis, const IndexDeletionPolicyPtr& deletionPolicy, int32_t termInfosIndexDivisor); ReadOnlyDirectoryReader(const DirectoryPtr& directory, const SegmentInfosPtr& infos, Collection oldReaders, diff --git a/include/ReadOnlySegmentReader.h b/include/ReadOnlySegmentReader.h index bd641e81..10a7dbd0 100644 --- a/include/ReadOnlySegmentReader.h +++ b/include/ReadOnlySegmentReader.h @@ -11,7 +11,7 @@ namespace Lucene { -class ReadOnlySegmentReader : public SegmentReader { +class LPPAPI ReadOnlySegmentReader : public SegmentReader { public: virtual ~ReadOnlySegmentReader(); diff --git a/include/SegmentMerger.h b/include/SegmentMerger.h index 859fab93..e6267800 100644 --- a/include/SegmentMerger.h +++ b/include/SegmentMerger.h @@ -17,7 +17,7 @@ namespace Lucene { /// If the compoundFile flag is set, then the segments will be merged into a compound file. /// @see #merge /// @see #add -class SegmentMerger : public LuceneObject { +class LPPAPI SegmentMerger : public LuceneObject { public: SegmentMerger(const DirectoryPtr& dir, const String& name); SegmentMerger(const IndexWriterPtr& writer, const String& name, const OneMergePtr& merge); diff --git a/include/SegmentTermDocs.h b/include/SegmentTermDocs.h index a3787b83..8bc20226 100644 --- a/include/SegmentTermDocs.h +++ b/include/SegmentTermDocs.h @@ -11,7 +11,7 @@ namespace Lucene { -class SegmentTermDocs : public TermPositions, public LuceneObject { +class LPPAPI SegmentTermDocs : public TermPositions, public LuceneObject { public: SegmentTermDocs(const SegmentReaderPtr& parent); virtual ~SegmentTermDocs(); diff --git a/include/SegmentTermEnum.h b/include/SegmentTermEnum.h index fa0672a0..e943697e 100644 --- a/include/SegmentTermEnum.h +++ b/include/SegmentTermEnum.h @@ -11,7 +11,7 @@ namespace Lucene { -class SegmentTermEnum : public TermEnum { +class LPPAPI SegmentTermEnum : public TermEnum { public: SegmentTermEnum(); SegmentTermEnum(const IndexInputPtr& i, const FieldInfosPtr& fis, bool isi); diff --git a/include/SegmentTermPositionVector.h b/include/SegmentTermPositionVector.h index 1ff31e5e..fb9cc6ab 100644 --- a/include/SegmentTermPositionVector.h +++ b/include/SegmentTermPositionVector.h @@ -11,7 +11,7 @@ namespace Lucene { -class SegmentTermPositionVector : public SegmentTermVector { +class LPPAPI SegmentTermPositionVector : public SegmentTermVector { public: SegmentTermPositionVector(const String& field, Collection terms, Collection termFreqs, Collection< Collection > positions, Collection< Collection > offsets); diff --git a/include/SegmentTermPositions.h b/include/SegmentTermPositions.h index 82904039..d62ddc67 100644 --- a/include/SegmentTermPositions.h +++ b/include/SegmentTermPositions.h @@ -11,7 +11,7 @@ namespace Lucene { -class SegmentTermPositions : public SegmentTermDocs { +class LPPAPI SegmentTermPositions : public SegmentTermDocs { public: SegmentTermPositions(const SegmentReaderPtr& parent); virtual ~SegmentTermPositions(); diff --git a/include/SegmentTermVector.h b/include/SegmentTermVector.h index cf534559..d50a603c 100644 --- a/include/SegmentTermVector.h +++ b/include/SegmentTermVector.h @@ -11,7 +11,7 @@ namespace Lucene { -class SegmentTermVector : public TermPositionVector, public LuceneObject { +class LPPAPI SegmentTermVector : public TermPositionVector, public LuceneObject { public: SegmentTermVector(const String& field, Collection terms, Collection termFreqs); virtual ~SegmentTermVector(); diff --git a/include/TermScorer.h b/include/TermScorer.h index 05866586..f76ebf18 100644 --- a/include/TermScorer.h +++ b/include/TermScorer.h @@ -12,7 +12,7 @@ namespace Lucene { /// A Scorer for documents matching a Term. -class TermScorer : public Scorer { +class LPPAPI TermScorer : public Scorer { public: /// Construct a TermScorer. /// @param weight The weight of the Term in the query. diff --git a/include/TermVectorsReader.h b/include/TermVectorsReader.h index 848f92ae..bd2ca2bc 100644 --- a/include/TermVectorsReader.h +++ b/include/TermVectorsReader.h @@ -11,7 +11,7 @@ namespace Lucene { -class TermVectorsReader : public LuceneObject { +class LPPAPI TermVectorsReader : public LuceneObject { public: TermVectorsReader(); TermVectorsReader(const DirectoryPtr& d, const String& segment, const FieldInfosPtr& fieldInfos); diff --git a/include/TestPoint.h b/include/TestPoint.h index 439b6df1..f4e626da 100644 --- a/include/TestPoint.h +++ b/include/TestPoint.h @@ -28,7 +28,7 @@ class LPPAPI TestPoint { static bool getTestPoint(const String& method); }; -class TestScope { +class LPPAPI TestScope { public: TestScope(const String& object, const String& method); virtual ~TestScope(); diff --git a/src/core/include/_ConcurrentMergeScheduler.h b/src/core/include/_ConcurrentMergeScheduler.h index 9aeb46d9..7fb46c56 100644 --- a/src/core/include/_ConcurrentMergeScheduler.h +++ b/src/core/include/_ConcurrentMergeScheduler.h @@ -11,7 +11,7 @@ namespace Lucene { -class MergeThread : public LuceneThread { +class LPPAPI MergeThread : public LuceneThread { public: MergeThread(const ConcurrentMergeSchedulerPtr& merger, const IndexWriterPtr& writer, const OneMergePtr& startMerge); virtual ~MergeThread(); diff --git a/src/core/include/_NumericRangeQuery.h b/src/core/include/_NumericRangeQuery.h index 375f0f6e..66b0b389 100644 --- a/src/core/include/_NumericRangeQuery.h +++ b/src/core/include/_NumericRangeQuery.h @@ -17,7 +17,7 @@ namespace Lucene { /// Warning: This term enumeration is not guaranteed to be always ordered by {@link Term#compareTo}. The /// ordering depends on how {@link NumericUtils#splitLongRange} and {@link NumericUtils#splitIntRange} /// generates the sub-ranges. For {@link MultiTermQuery} ordering is not relevant. -class NumericRangeTermEnum : public FilteredTermEnum { +class LPPAPI NumericRangeTermEnum : public FilteredTermEnum { public: NumericRangeTermEnum(const NumericRangeQueryPtr& query, const IndexReaderPtr& reader); virtual ~NumericRangeTermEnum(); diff --git a/src/core/include/_SegmentReader.h b/src/core/include/_SegmentReader.h index e04c2fcb..505f8c79 100644 --- a/src/core/include/_SegmentReader.h +++ b/src/core/include/_SegmentReader.h @@ -66,7 +66,7 @@ class CoreReaders : public LuceneObject { }; /// Sets the initial value -class FieldsReaderLocal : public CloseableThreadLocal { +class LPPAPI FieldsReaderLocal : public CloseableThreadLocal { public: FieldsReaderLocal(const SegmentReaderPtr& reader); @@ -77,7 +77,7 @@ class FieldsReaderLocal : public CloseableThreadLocal { virtual FieldsReaderPtr initialValue(); }; -class SegmentReaderRef : public LuceneObject { +class LPPAPI SegmentReaderRef : public LuceneObject { public: SegmentReaderRef(); virtual ~SegmentReaderRef(); @@ -100,7 +100,7 @@ class SegmentReaderRef : public LuceneObject { /// array is all that is needed for sharing between cloned readers. The current norm referencing is for /// sharing between readers whereas the byte[] referencing is for copy on write which is independent of /// reader references (i.e. incRef, decRef). -class Norm : public LuceneObject { +class LPPAPI Norm : public LuceneObject { public: Norm(); Norm(const SegmentReaderPtr& reader, const IndexInputPtr& in, int32_t number, int64_t normSeek); diff --git a/src/core/include/_SimpleFSDirectory.h b/src/core/include/_SimpleFSDirectory.h index 1818f847..4adc582d 100644 --- a/src/core/include/_SimpleFSDirectory.h +++ b/src/core/include/_SimpleFSDirectory.h @@ -12,7 +12,7 @@ namespace Lucene { -class InputFile : public LuceneObject { +class LPPAPI InputFile : public LuceneObject { public: InputFile(const String& path); virtual ~InputFile(); @@ -37,7 +37,7 @@ class InputFile : public LuceneObject { bool isValid(); }; -class SimpleFSIndexInput : public BufferedIndexInput { +class LPPAPI SimpleFSIndexInput : public BufferedIndexInput { public: SimpleFSIndexInput(); SimpleFSIndexInput(const String& path, int32_t bufferSize, int32_t chunkSize); diff --git a/src/test/include/MockRAMDirectory.h b/src/test/include/MockRAMDirectory.h index 707ee020..74014429 100644 --- a/src/test/include/MockRAMDirectory.h +++ b/src/test/include/MockRAMDirectory.h @@ -13,7 +13,7 @@ namespace Lucene { /// This is a subclass of RAMDirectory that adds methods intended to be used only by unit tests. -class MockRAMDirectory : public RAMDirectory { +class LPPAPI MockRAMDirectory : public RAMDirectory { public: MockRAMDirectory(); MockRAMDirectory(const DirectoryPtr& dir); diff --git a/src/test/include/MockRAMOutputStream.h b/src/test/include/MockRAMOutputStream.h index dc0c7d42..50a41ddb 100644 --- a/src/test/include/MockRAMOutputStream.h +++ b/src/test/include/MockRAMOutputStream.h @@ -14,7 +14,7 @@ namespace Lucene { /// Used by MockRAMDirectory to create an output stream that will throw an IOException on fake disk full, track max /// disk space actually used, and maybe throw random IOExceptions. -class MockRAMOutputStream : public RAMOutputStream { +class LPPAPI MockRAMOutputStream : public RAMOutputStream { public: /// Construct an empty output buffer. MockRAMOutputStream(const MockRAMDirectoryPtr& dir, const RAMFilePtr& f, const String& name); From cb8209b5e82452e5709adab4f3bc6c627b7b73d9 Mon Sep 17 00:00:00 2001 From: p01arst0rm Date: Sun, 9 Aug 2020 21:57:45 +0100 Subject: [PATCH 125/157] updated gtest --- src/test/gtest/.clang-format | 4 + src/test/gtest/.gitignore | 84 + src/test/gtest/.travis.yml | 73 + src/test/gtest/BUILD.bazel | 179 + src/test/gtest/CHANGES | 157 - src/test/gtest/CMakeLists.txt | 276 +- src/test/gtest/CONTRIBUTING.md | 142 + src/test/gtest/Makefile.am | 306 - src/test/gtest/README | 435 -- src/test/gtest/README.md | 134 + src/test/gtest/WORKSPACE | 23 + src/test/gtest/appveyor.yml | 154 + src/test/gtest/ci/build-linux-bazel.sh | 37 + src/test/gtest/ci/build-platformio.sh | 2 + src/test/gtest/ci/env-linux.sh | 41 + .../runtests.sh => ci/env-osx.sh} | 47 +- src/test/gtest/ci/get-nprocessors.sh | 48 + src/test/gtest/ci/install-linux.sh | 49 + src/test/gtest/ci/install-osx.sh | 40 + src/test/gtest/ci/install-platformio.sh | 5 + src/test/gtest/ci/log-config.sh | 51 + src/test/gtest/ci/travis.sh | 44 + src/test/gtest/codegear/gtest.cbproj | 138 - src/test/gtest/codegear/gtest.groupproj | 54 - src/test/gtest/codegear/gtest_main.cbproj | 82 - src/test/gtest/codegear/gtest_unittest.cbproj | 88 - src/test/gtest/configure.ac | 68 - src/test/gtest/googlemock/CMakeLists.txt | 233 + src/test/gtest/googlemock/CONTRIBUTORS | 40 + src/test/gtest/googlemock/LICENSE | 28 + src/test/gtest/googlemock/README.md | 44 + src/test/gtest/googlemock/cmake/gmock.pc.in | 11 + .../gtest/googlemock/cmake/gmock_main.pc.in | 11 + src/test/gtest/googlemock/docs/cheat_sheet.md | 781 ++ src/test/gtest/googlemock/docs/cook_book.md | 4270 +++++++++++ src/test/gtest/googlemock/docs/for_dummies.md | 700 ++ src/test/gtest/googlemock/docs/gmock_faq.md | 396 + .../googlemock/include/gmock/gmock-actions.h | 1142 +++ .../include/gmock/gmock-cardinalities.h | 157 + .../include/gmock/gmock-function-mocker.h | 253 + .../include/gmock/gmock-generated-actions.h | 1884 +++++ .../gmock/gmock-generated-actions.h.pump | 627 ++ .../gmock/gmock-generated-function-mockers.h | 752 ++ .../gmock-generated-function-mockers.h.pump | 227 + .../include/gmock/gmock-generated-matchers.h | 1097 +++ .../gmock/gmock-generated-matchers.h.pump | 346 + .../googlemock/include/gmock/gmock-matchers.h | 4568 +++++++++++ .../include/gmock/gmock-more-actions.h | 162 + .../include/gmock/gmock-more-matchers.h | 92 + .../include/gmock/gmock-nice-strict.h | 215 + .../include/gmock/gmock-spec-builders.h | 1985 +++++ .../gtest/googlemock/include/gmock/gmock.h | 101 + .../include/gmock/internal/custom/README.md | 16 + .../internal/custom/gmock-generated-actions.h | 10 + .../custom/gmock-generated-actions.h.pump | 12 + .../gmock/internal/custom/gmock-matchers.h} | 74 +- .../gmock/internal/custom/gmock-port.h} | 79 +- .../gmock/internal/gmock-internal-utils.h | 513 ++ .../include/gmock/internal/gmock-port.h | 87 + .../include/gmock/internal/gmock-pp.h | 317 + .../googlemock/scripts/fuse_gmock_files.py | 240 + .../googlemock/scripts/generator/LICENSE | 203 + .../gtest/googlemock/scripts/generator/README | 34 + .../scripts/generator/README.cppclean | 115 + .../scripts/generator/cpp/__init__.py} | 0 .../googlemock/scripts/generator/cpp/ast.py | 1736 +++++ .../scripts/generator/cpp/gmock_class.py | 227 + .../scripts/generator/cpp/gmock_class_test.py | 466 ++ .../scripts/generator/cpp/keywords.py | 59 + .../scripts/generator/cpp/tokenize.py | 287 + .../googlemock/scripts/generator/cpp/utils.py | 41 + .../googlemock/scripts/generator/gmock_gen.py | 31 + .../gtest/googlemock/scripts/gmock-config.in | 303 + .../gtest/googlemock/scripts/gmock_doctor.py | 640 ++ .../gtest/{ => googlemock}/scripts/upload.py | 8 +- .../gtest/googlemock/scripts/upload_gmock.py | 78 + .../widget.h => googlemock/src/gmock-all.cc} | 41 +- .../googlemock/src/gmock-cardinalities.cc | 155 + .../googlemock/src/gmock-internal-utils.cc | 200 + .../gtest/googlemock/src/gmock-matchers.cc | 462 ++ .../googlemock/src/gmock-spec-builders.cc | 888 +++ src/test/gtest/googlemock/src/gmock.cc | 213 + src/test/gtest/googlemock/src/gmock_main.cc | 65 + src/test/gtest/googlemock/test/BUILD.bazel | 110 + .../googlemock/test/gmock-actions_test.cc | 1445 ++++ .../test/gmock-cardinalities_test.cc | 429 ++ .../test/gmock-function-mocker_nc.cc | 16 + .../test/gmock-function-mocker_nc_test.py | 43 + .../test/gmock-function-mocker_test.cc | 660 ++ .../test/gmock-generated-actions_test.cc | 1064 +++ .../gmock-generated-function-mockers_test.cc | 659 ++ .../test/gmock-generated-matchers_test.cc | 1324 ++++ .../test/gmock-internal-utils_test.cc | 733 ++ .../googlemock/test/gmock-matchers_test.cc | 6801 +++++++++++++++++ .../test/gmock-more-actions_test.cc | 698 ++ .../googlemock/test/gmock-nice-strict_test.cc | 500 ++ .../gtest/googlemock/test/gmock-port_test.cc | 42 + .../googlemock/test/gmock-pp-string_test.cc | 206 + .../gtest/googlemock/test/gmock-pp_test.cc | 73 + .../test/gmock-spec-builders_test.cc | 2775 +++++++ .../gtest/googlemock/test/gmock_all_test.cc | 49 + .../gtest/googlemock/test/gmock_ex_test.cc | 80 + .../gtest/googlemock/test/gmock_leak_test.py | 104 + .../gtest/googlemock/test/gmock_leak_test_.cc | 99 + .../gtest/googlemock/test/gmock_link2_test.cc | 39 + .../gtest/googlemock/test/gmock_link_test.cc | 39 + .../gtest/googlemock/test/gmock_link_test.h | 690 ++ .../googlemock/test/gmock_output_test.py | 183 + .../googlemock/test/gmock_output_test_.cc | 309 + .../test/gmock_output_test_golden.txt | 317 + .../googlemock/test/gmock_stress_test.cc | 240 + src/test/gtest/googlemock/test/gmock_test.cc | 181 + .../gtest/googlemock/test/gmock_test_utils.py | 108 + src/test/gtest/googletest/CMakeLists.txt | 328 + src/test/gtest/{ => googletest}/CONTRIBUTORS | 0 src/test/gtest/googletest/LICENSE | 28 + src/test/gtest/googletest/README.md | 244 + .../gtest/googletest/cmake/Config.cmake.in | 9 + src/test/gtest/googletest/cmake/gtest.pc.in | 10 + .../gtest/googletest/cmake/gtest_main.pc.in | 11 + .../cmake/internal_utils.cmake | 208 +- .../gtest/googletest/cmake/libgtest.la.in | 21 + src/test/gtest/googletest/docs/advanced.md | 2567 +++++++ src/test/gtest/googletest/docs/faq.md | 753 ++ src/test/gtest/googletest/docs/pkgconfig.md | 141 + src/test/gtest/googletest/docs/primer.md | 567 ++ src/test/gtest/googletest/docs/pump_manual.md | 190 + src/test/gtest/googletest/docs/samples.md | 22 + .../include/gtest/gtest-death-test.h | 71 +- .../googletest/include/gtest/gtest-matchers.h | 750 ++ .../include/gtest/gtest-message.h | 56 +- .../include/gtest/gtest-param-test.h} | 270 +- .../include/gtest/gtest-printers.h | 555 +- .../include/gtest/gtest-spi.h | 20 +- .../include/gtest/gtest-test-part.h | 43 +- .../include/gtest/gtest-typed-test.h | 330 + .../{ => googletest}/include/gtest/gtest.h | 1145 +-- .../include/gtest/gtest_pred_impl.h | 81 +- .../include/gtest/gtest_prod.h | 17 +- .../include/gtest/internal/custom/README.md | 56 + .../gtest/internal/custom/gtest-port.h | 37 + .../gtest/internal/custom/gtest-printers.h | 42 + .../include/gtest/internal/custom/gtest.h | 37 + .../internal/gtest-death-test-internal.h | 175 +- .../include/gtest/internal/gtest-filepath.h | 13 +- .../include/gtest/internal/gtest-internal.h | 793 +- .../include/gtest/internal/gtest-param-util.h | 883 +++ .../include/gtest/internal/gtest-port-arch.h | 107 + .../include/gtest/internal/gtest-port.h | 1099 ++- .../include/gtest/internal/gtest-string.h | 30 +- .../include/gtest/internal/gtest-type-util.h | 42 +- .../gtest/internal/gtest-type-util.h.pump | 43 +- .../{ => googletest}/samples/prime_tables.h | 25 +- .../gtest/{ => googletest}/samples/sample1.cc | 6 +- .../gtest/{ => googletest}/samples/sample1.h | 4 +- .../samples/sample10_unittest.cc | 13 +- .../samples/sample1_unittest.cc | 6 +- .../gtest/{ => googletest}/samples/sample2.cc | 4 +- .../gtest/{ => googletest}/samples/sample2.h | 12 +- .../samples/sample2_unittest.cc | 12 +- .../{ => googletest}/samples/sample3-inl.h | 18 +- .../samples/sample3_unittest.cc | 28 +- .../gtest/{ => googletest}/samples/sample4.cc | 12 +- .../gtest/{ => googletest}/samples/sample4.h | 6 +- .../samples/sample4_unittest.cc | 14 +- .../samples/sample5_unittest.cc | 25 +- .../samples/sample6_unittest.cc | 24 +- .../samples/sample7_unittest.cc | 41 +- .../samples/sample8_unittest.cc | 59 +- .../samples/sample9_unittest.cc | 24 +- .../gtest/{ => googletest}/scripts/common.py | 0 .../scripts/fuse_gtest_files.py | 35 +- .../scripts/gen_gtest_pred_impl.py | 20 +- .../{ => googletest}/scripts/gtest-config.in | 0 .../gtest/{ => googletest}/scripts/pump.py | 0 .../{ => googletest}/scripts/release_docs.py | 0 src/test/gtest/googletest/scripts/upload.py | 1387 ++++ .../{ => googletest}/scripts/upload_gtest.py | 0 .../gtest/{ => googletest}/src/gtest-all.cc | 6 +- .../{ => googletest}/src/gtest-death-test.cc | 599 +- .../{ => googletest}/src/gtest-filepath.cc | 45 +- .../{ => googletest}/src/gtest-internal-inl.h | 313 +- .../gtest/googletest/src/gtest-matchers.cc | 97 + .../gtest/{ => googletest}/src/gtest-port.cc | 521 +- .../{ => googletest}/src/gtest-printers.cc | 123 +- .../{ => googletest}/src/gtest-test-part.cc | 34 +- .../{ => googletest}/src/gtest-typed-test.cc | 48 +- src/test/gtest/{ => googletest}/src/gtest.cc | 3101 +++++--- .../gtest/{ => googletest}/src/gtest_main.cc | 15 +- src/test/gtest/googletest/test/BUILD.bazel | 521 ++ .../googletest-break-on-failure-unittest.py} | 14 +- .../googletest-break-on-failure-unittest_.cc} | 6 +- .../test/googletest-catch-exceptions-test.py} | 163 +- .../googletest-catch-exceptions-test_.cc} | 116 +- .../test/googletest-color-test.py} | 9 +- .../test/googletest-color-test_.cc} | 11 +- .../test/googletest-death-test-test.cc} | 251 +- .../test/googletest-death-test_ex_test.cc} | 7 +- .../test/googletest-env-var-test.py} | 26 +- .../test/googletest-env-var-test_.cc} | 10 +- .../test/googletest-filepath-test.cc} | 41 +- .../test/googletest-filter-unittest.py} | 52 +- .../test/googletest-filter-unittest_.cc} | 9 +- .../test/googletest-json-outfiles-test.py | 191 + .../test/googletest-json-output-unittest.py | 778 ++ .../test/googletest-list-tests-unittest.py} | 24 +- .../test/googletest-list-tests-unittest_.cc} | 13 +- .../test/googletest-listener-test.cc | 518 ++ .../test/googletest-message-test.cc} | 7 +- .../test/googletest-options-test.cc} | 31 +- .../googletest-output-test-golden-lin.txt} | 802 +- .../test/googletest-output-test.py} | 65 +- .../test/googletest-output-test_.cc} | 287 +- ...oogletest-param-test-invalid-name1-test.py | 63 + ...ogletest-param-test-invalid-name1-test_.cc | 50 + ...oogletest-param-test-invalid-name2-test.py | 62 + ...ogletest-param-test-invalid-name2-test_.cc | 55 + .../test/googletest-param-test-test.cc} | 445 +- .../test/googletest-param-test-test.h} | 10 +- .../test/googletest-param-test2-test.cc} | 34 +- .../test/googletest-port-test.cc} | 195 +- .../test/googletest-printers-test.cc} | 579 +- .../test/googletest-shuffle-test.py} | 8 +- .../test/googletest-shuffle-test_.cc} | 10 +- .../test/googletest-test-part-test.cc} | 38 +- .../test/googletest-test2_test.cc} | 57 +- .../test/googletest-throw-on-failure-test.py} | 17 +- .../googletest-throw-on-failure-test_.cc} | 7 +- .../test/googletest-uninitialized-test.py} | 13 +- .../test/googletest-uninitialized-test_.cc} | 7 +- .../test/gtest-typed-test2_test.cc | 7 +- .../test/gtest-typed-test_test.cc | 221 +- .../test/gtest-typed-test_test.h | 9 +- .../test/gtest-unittest-api_test.cc | 245 +- .../{ => googletest}/test/gtest_all_test.cc | 21 +- .../test/gtest_assert_by_exception_test.cc | 116 + .../test/gtest_environment_test.cc | 12 +- .../{ => googletest}/test/gtest_help_test.py | 4 +- .../{ => googletest}/test/gtest_help_test_.cc | 3 +- .../test/gtest_json_test_utils.py} | 61 +- .../test/gtest_list_output_unittest.py | 141 + .../test/gtest_list_output_unittest_.cc | 51 + .../test/gtest_main_unittest.cc | 7 +- .../test/gtest_no_test_unittest.cc | 2 - .../test/gtest_pred_impl_unittest.cc | 42 +- .../test/gtest_premature_exit_test.cc | 27 +- .../{ => googletest}/test/gtest_prod_test.cc | 7 +- .../test/gtest_repeat_test.cc | 36 +- ...test_skip_environment_check_output_test.py | 54 + .../gtest_skip_in_environment_setup_test.cc | 49 + .../gtest/googletest/test/gtest_skip_test.cc | 55 + .../test/gtest_sole_header_test.cc | 3 +- .../test/gtest_stress_test.cc | 14 +- .../gtest_test_macro_stack_footprint_test.cc | 89 + .../{ => googletest}/test/gtest_test_utils.py | 42 +- .../googletest/test/gtest_testbridge_test.py | 63 + .../googletest/test/gtest_testbridge_test_.cc | 43 + .../test/gtest_throw_on_failure_ex_test.cc | 6 +- .../{ => googletest}/test/gtest_unittest.cc | 2057 ++--- .../test/gtest_xml_outfile1_test_.cc | 10 +- .../test/gtest_xml_outfile2_test_.cc | 10 +- .../test/gtest_xml_outfiles_test.py | 29 +- .../test/gtest_xml_output_unittest.py | 208 +- .../test/gtest_xml_output_unittest_.cc | 35 +- .../test/gtest_xml_test_utils.py | 50 +- .../gtest/{ => googletest}/test/production.cc | 5 +- .../gtest/{ => googletest}/test/production.h | 5 +- .../gtest/include/gtest/gtest-param-test.h | 1421 ---- .../gtest/include/gtest/gtest-typed-test.h | 259 - .../include/gtest/internal/gtest-linked_ptr.h | 233 - .../internal/gtest-param-util-generated.h | 5143 ------------- .../gtest-param-util-generated.h.pump | 301 - .../include/gtest/internal/gtest-param-util.h | 619 -- .../include/gtest/internal/gtest-tuple.h | 1020 --- .../include/gtest/internal/gtest-tuple.h.pump | 347 - src/test/gtest/library.json | 59 + src/test/gtest/m4/acx_pthread.m4 | 363 - src/test/gtest/m4/gtest.m4 | 74 - src/test/gtest/msvc/gtest-md.sln | 45 - src/test/gtest/msvc/gtest-md.vcproj | 126 - src/test/gtest/msvc/gtest.sln | 45 - src/test/gtest/msvc/gtest.vcproj | 126 - src/test/gtest/msvc/gtest_main-md.vcproj | 129 - src/test/gtest/msvc/gtest_main.vcproj | 129 - src/test/gtest/msvc/gtest_prod_test-md.vcproj | 164 - src/test/gtest/msvc/gtest_prod_test.vcproj | 164 - src/test/gtest/msvc/gtest_unittest-md.vcproj | 147 - src/test/gtest/msvc/gtest_unittest.vcproj | 147 - src/test/gtest/platformio.ini | 31 + src/test/gtest/test/gtest-linked_ptr_test.cc | 154 - src/test/gtest/test/gtest-listener_test.cc | 310 - src/test/gtest/test/gtest-tuple_test.cc | 320 - .../gtest/xcode/Config/DebugProject.xcconfig | 30 - .../xcode/Config/FrameworkTarget.xcconfig | 17 - src/test/gtest/xcode/Config/General.xcconfig | 41 - .../xcode/Config/ReleaseProject.xcconfig | 32 - .../xcode/Config/StaticLibraryTarget.xcconfig | 18 - .../gtest/xcode/Config/TestTarget.xcconfig | 8 - src/test/gtest/xcode/Resources/Info.plist | 30 - .../xcode/Samples/FrameworkSample/Info.plist | 28 - .../WidgetFramework.xcodeproj/project.pbxproj | 457 -- .../xcode/Samples/FrameworkSample/widget.cc | 63 - .../gtest/xcode/Scripts/versiongenerate.py | 100 - .../xcode/gtest.xcodeproj/project.pbxproj | 1135 --- 304 files changed, 70065 insertions(+), 22181 deletions(-) create mode 100644 src/test/gtest/.clang-format create mode 100644 src/test/gtest/.gitignore create mode 100644 src/test/gtest/.travis.yml create mode 100644 src/test/gtest/BUILD.bazel delete mode 100644 src/test/gtest/CHANGES create mode 100644 src/test/gtest/CONTRIBUTING.md delete mode 100644 src/test/gtest/Makefile.am delete mode 100644 src/test/gtest/README create mode 100644 src/test/gtest/README.md create mode 100644 src/test/gtest/WORKSPACE create mode 100644 src/test/gtest/appveyor.yml create mode 100755 src/test/gtest/ci/build-linux-bazel.sh create mode 100644 src/test/gtest/ci/build-platformio.sh create mode 100755 src/test/gtest/ci/env-linux.sh rename src/test/gtest/{xcode/Samples/FrameworkSample/runtests.sh => ci/env-osx.sh} (63%) mode change 100644 => 100755 create mode 100755 src/test/gtest/ci/get-nprocessors.sh create mode 100755 src/test/gtest/ci/install-linux.sh create mode 100755 src/test/gtest/ci/install-osx.sh create mode 100644 src/test/gtest/ci/install-platformio.sh create mode 100755 src/test/gtest/ci/log-config.sh create mode 100755 src/test/gtest/ci/travis.sh delete mode 100644 src/test/gtest/codegear/gtest.cbproj delete mode 100644 src/test/gtest/codegear/gtest.groupproj delete mode 100644 src/test/gtest/codegear/gtest_main.cbproj delete mode 100644 src/test/gtest/codegear/gtest_unittest.cbproj delete mode 100644 src/test/gtest/configure.ac create mode 100644 src/test/gtest/googlemock/CMakeLists.txt create mode 100644 src/test/gtest/googlemock/CONTRIBUTORS create mode 100644 src/test/gtest/googlemock/LICENSE create mode 100644 src/test/gtest/googlemock/README.md create mode 100644 src/test/gtest/googlemock/cmake/gmock.pc.in create mode 100644 src/test/gtest/googlemock/cmake/gmock_main.pc.in create mode 100644 src/test/gtest/googlemock/docs/cheat_sheet.md create mode 100644 src/test/gtest/googlemock/docs/cook_book.md create mode 100644 src/test/gtest/googlemock/docs/for_dummies.md create mode 100644 src/test/gtest/googlemock/docs/gmock_faq.md create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-actions.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-cardinalities.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-function-mocker.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h.pump create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h.pump create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-matchers.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-more-actions.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-more-matchers.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-nice-strict.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock-spec-builders.h create mode 100644 src/test/gtest/googlemock/include/gmock/gmock.h create mode 100644 src/test/gtest/googlemock/include/gmock/internal/custom/README.md create mode 100644 src/test/gtest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h create mode 100644 src/test/gtest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump rename src/test/gtest/{codegear/gtest_all.cc => googlemock/include/gmock/internal/custom/gmock-matchers.h} (80%) rename src/test/gtest/{codegear/gtest_link.cc => googlemock/include/gmock/internal/custom/gmock-port.h} (75%) create mode 100644 src/test/gtest/googlemock/include/gmock/internal/gmock-internal-utils.h create mode 100644 src/test/gtest/googlemock/include/gmock/internal/gmock-port.h create mode 100644 src/test/gtest/googlemock/include/gmock/internal/gmock-pp.h create mode 100755 src/test/gtest/googlemock/scripts/fuse_gmock_files.py create mode 100644 src/test/gtest/googlemock/scripts/generator/LICENSE create mode 100644 src/test/gtest/googlemock/scripts/generator/README create mode 100644 src/test/gtest/googlemock/scripts/generator/README.cppclean rename src/test/gtest/{build-aux/.keep => googlemock/scripts/generator/cpp/__init__.py} (100%) mode change 100644 => 100755 create mode 100755 src/test/gtest/googlemock/scripts/generator/cpp/ast.py create mode 100755 src/test/gtest/googlemock/scripts/generator/cpp/gmock_class.py create mode 100755 src/test/gtest/googlemock/scripts/generator/cpp/gmock_class_test.py create mode 100755 src/test/gtest/googlemock/scripts/generator/cpp/keywords.py create mode 100755 src/test/gtest/googlemock/scripts/generator/cpp/tokenize.py create mode 100755 src/test/gtest/googlemock/scripts/generator/cpp/utils.py create mode 100755 src/test/gtest/googlemock/scripts/generator/gmock_gen.py create mode 100755 src/test/gtest/googlemock/scripts/gmock-config.in create mode 100755 src/test/gtest/googlemock/scripts/gmock_doctor.py rename src/test/gtest/{ => googlemock}/scripts/upload.py (99%) create mode 100755 src/test/gtest/googlemock/scripts/upload_gmock.py rename src/test/gtest/{xcode/Samples/FrameworkSample/widget.h => googlemock/src/gmock-all.cc} (68%) create mode 100644 src/test/gtest/googlemock/src/gmock-cardinalities.cc create mode 100644 src/test/gtest/googlemock/src/gmock-internal-utils.cc create mode 100644 src/test/gtest/googlemock/src/gmock-matchers.cc create mode 100644 src/test/gtest/googlemock/src/gmock-spec-builders.cc create mode 100644 src/test/gtest/googlemock/src/gmock.cc create mode 100644 src/test/gtest/googlemock/src/gmock_main.cc create mode 100644 src/test/gtest/googlemock/test/BUILD.bazel create mode 100644 src/test/gtest/googlemock/test/gmock-actions_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-cardinalities_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-function-mocker_nc.cc create mode 100644 src/test/gtest/googlemock/test/gmock-function-mocker_nc_test.py create mode 100644 src/test/gtest/googlemock/test/gmock-function-mocker_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-generated-actions_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-generated-function-mockers_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-generated-matchers_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-internal-utils_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-matchers_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-more-actions_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-nice-strict_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-port_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-pp-string_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-pp_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock-spec-builders_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock_all_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock_ex_test.cc create mode 100755 src/test/gtest/googlemock/test/gmock_leak_test.py create mode 100644 src/test/gtest/googlemock/test/gmock_leak_test_.cc create mode 100644 src/test/gtest/googlemock/test/gmock_link2_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock_link_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock_link_test.h create mode 100755 src/test/gtest/googlemock/test/gmock_output_test.py create mode 100644 src/test/gtest/googlemock/test/gmock_output_test_.cc create mode 100644 src/test/gtest/googlemock/test/gmock_output_test_golden.txt create mode 100644 src/test/gtest/googlemock/test/gmock_stress_test.cc create mode 100644 src/test/gtest/googlemock/test/gmock_test.cc create mode 100755 src/test/gtest/googlemock/test/gmock_test_utils.py create mode 100644 src/test/gtest/googletest/CMakeLists.txt rename src/test/gtest/{ => googletest}/CONTRIBUTORS (100%) create mode 100644 src/test/gtest/googletest/LICENSE create mode 100644 src/test/gtest/googletest/README.md create mode 100644 src/test/gtest/googletest/cmake/Config.cmake.in create mode 100644 src/test/gtest/googletest/cmake/gtest.pc.in create mode 100644 src/test/gtest/googletest/cmake/gtest_main.pc.in rename src/test/gtest/{ => googletest}/cmake/internal_utils.cmake (51%) create mode 100644 src/test/gtest/googletest/cmake/libgtest.la.in create mode 100644 src/test/gtest/googletest/docs/advanced.md create mode 100644 src/test/gtest/googletest/docs/faq.md create mode 100644 src/test/gtest/googletest/docs/pkgconfig.md create mode 100644 src/test/gtest/googletest/docs/primer.md create mode 100644 src/test/gtest/googletest/docs/pump_manual.md create mode 100644 src/test/gtest/googletest/docs/samples.md rename src/test/gtest/{ => googletest}/include/gtest/gtest-death-test.h (76%) create mode 100644 src/test/gtest/googletest/include/gtest/gtest-matchers.h rename src/test/gtest/{ => googletest}/include/gtest/gtest-message.h (83%) rename src/test/gtest/{include/gtest/gtest-param-test.h.pump => googletest/include/gtest/gtest-param-test.h} (58%) rename src/test/gtest/{ => googletest}/include/gtest/gtest-printers.h (67%) rename src/test/gtest/{ => googletest}/include/gtest/gtest-spi.h (95%) rename src/test/gtest/{ => googletest}/include/gtest/gtest-test-part.h (83%) create mode 100644 src/test/gtest/googletest/include/gtest/gtest-typed-test.h rename src/test/gtest/{ => googletest}/include/gtest/gtest.h (69%) rename src/test/gtest/{ => googletest}/include/gtest/gtest_pred_impl.h (84%) rename src/test/gtest/{ => googletest}/include/gtest/gtest_prod.h (82%) create mode 100644 src/test/gtest/googletest/include/gtest/internal/custom/README.md create mode 100644 src/test/gtest/googletest/include/gtest/internal/custom/gtest-port.h create mode 100644 src/test/gtest/googletest/include/gtest/internal/custom/gtest-printers.h create mode 100644 src/test/gtest/googletest/include/gtest/internal/custom/gtest.h rename src/test/gtest/{ => googletest}/include/gtest/internal/gtest-death-test-internal.h (66%) rename src/test/gtest/{ => googletest}/include/gtest/internal/gtest-filepath.h (96%) rename src/test/gtest/{ => googletest}/include/gtest/internal/gtest-internal.h (59%) create mode 100644 src/test/gtest/googletest/include/gtest/internal/gtest-param-util.h create mode 100644 src/test/gtest/googletest/include/gtest/internal/gtest-port-arch.h rename src/test/gtest/{ => googletest}/include/gtest/internal/gtest-port.h (72%) rename src/test/gtest/{ => googletest}/include/gtest/internal/gtest-string.h (89%) rename src/test/gtest/{ => googletest}/include/gtest/internal/gtest-type-util.h (99%) rename src/test/gtest/{ => googletest}/include/gtest/internal/gtest-type-util.h.pump (89%) rename src/test/gtest/{ => googletest}/samples/prime_tables.h (86%) rename src/test/gtest/{ => googletest}/samples/sample1.cc (94%) rename src/test/gtest/{ => googletest}/samples/sample1.h (95%) rename src/test/gtest/{ => googletest}/samples/sample10_unittest.cc (95%) rename src/test/gtest/{ => googletest}/samples/sample1_unittest.cc (99%) rename src/test/gtest/{ => googletest}/samples/sample2.cc (96%) rename src/test/gtest/{ => googletest}/samples/sample2.h (90%) rename src/test/gtest/{ => googletest}/samples/sample2_unittest.cc (96%) rename src/test/gtest/{ => googletest}/samples/sample3-inl.h (93%) rename src/test/gtest/{ => googletest}/samples/sample3_unittest.cc (90%) rename src/test/gtest/{ => googletest}/samples/sample4.cc (89%) rename src/test/gtest/{ => googletest}/samples/sample4.h (96%) rename src/test/gtest/{ => googletest}/samples/sample4_unittest.cc (93%) rename src/test/gtest/{ => googletest}/samples/sample5_unittest.cc (95%) rename src/test/gtest/{ => googletest}/samples/sample6_unittest.cc (93%) rename src/test/gtest/{ => googletest}/samples/sample7_unittest.cc (78%) rename src/test/gtest/{ => googletest}/samples/sample8_unittest.cc (77%) rename src/test/gtest/{ => googletest}/samples/sample9_unittest.cc (89%) rename src/test/gtest/{ => googletest}/scripts/common.py (100%) rename src/test/gtest/{ => googletest}/scripts/fuse_gtest_files.py (90%) rename src/test/gtest/{ => googletest}/scripts/gen_gtest_pred_impl.py (98%) rename src/test/gtest/{ => googletest}/scripts/gtest-config.in (100%) rename src/test/gtest/{ => googletest}/scripts/pump.py (100%) rename src/test/gtest/{ => googletest}/scripts/release_docs.py (100%) create mode 100755 src/test/gtest/googletest/scripts/upload.py rename src/test/gtest/{ => googletest}/scripts/upload_gtest.py (100%) rename src/test/gtest/{ => googletest}/src/gtest-all.cc (95%) rename src/test/gtest/{ => googletest}/src/gtest-death-test.cc (71%) rename src/test/gtest/{ => googletest}/src/gtest-filepath.cc (92%) rename src/test/gtest/{ => googletest}/src/gtest-internal-inl.h (82%) create mode 100644 src/test/gtest/googletest/src/gtest-matchers.cc rename src/test/gtest/{ => googletest}/src/gtest-port.cc (75%) rename src/test/gtest/{ => googletest}/src/gtest-printers.cc (78%) rename src/test/gtest/{ => googletest}/src/gtest-test-part.cc (79%) rename src/test/gtest/{ => googletest}/src/gtest-typed-test.cc (71%) rename src/test/gtest/{ => googletest}/src/gtest.cc (62%) rename src/test/gtest/{ => googletest}/src/gtest_main.cc (90%) create mode 100644 src/test/gtest/googletest/test/BUILD.bazel rename src/test/gtest/{test/gtest_break_on_failure_unittest.py => googletest/test/googletest-break-on-failure-unittest.py} (95%) rename src/test/gtest/{test/gtest_break_on_failure_unittest_.cc => googletest/test/googletest-break-on-failure-unittest_.cc} (98%) rename src/test/gtest/{test/gtest_catch_exceptions_test.py => googletest/test/googletest-catch-exceptions-test.py} (61%) rename src/test/gtest/{test/gtest_catch_exceptions_test_.cc => googletest/test/googletest-catch-exceptions-test_.cc} (69%) rename src/test/gtest/{test/gtest_color_test.py => googletest/test/googletest-color-test.py} (95%) rename src/test/gtest/{test/gtest_color_test_.cc => googletest/test/googletest-color-test_.cc} (86%) rename src/test/gtest/{test/gtest-death-test_test.cc => googletest/test/googletest-death-test-test.cc} (88%) rename src/test/gtest/{test/gtest-death-test_ex_test.cc => googletest/test/googletest-death-test_ex_test.cc} (95%) rename src/test/gtest/{test/gtest_env_var_test.py => googletest/test/googletest-env-var-test.py} (80%) rename src/test/gtest/{test/gtest_env_var_test_.cc => googletest/test/googletest-env-var-test_.cc} (95%) rename src/test/gtest/{test/gtest-filepath_test.cc => googletest/test/googletest-filepath-test.cc} (94%) rename src/test/gtest/{test/gtest_filter_unittest.py => googletest/test/googletest-filter-unittest.py} (94%) rename src/test/gtest/{test/gtest_filter_unittest_.cc => googletest/test/googletest-filter-unittest_.cc} (93%) create mode 100644 src/test/gtest/googletest/test/googletest-json-outfiles-test.py create mode 100644 src/test/gtest/googletest/test/googletest-json-output-unittest.py rename src/test/gtest/{test/gtest_list_tests_unittest.py => googletest/test/googletest-list-tests-unittest.py} (90%) rename src/test/gtest/{test/gtest_list_tests_unittest_.cc => googletest/test/googletest-list-tests-unittest_.cc} (94%) create mode 100644 src/test/gtest/googletest/test/googletest-listener-test.cc rename src/test/gtest/{test/gtest-message_test.cc => googletest/test/googletest-message-test.cc} (98%) rename src/test/gtest/{test/gtest-options_test.cc => googletest/test/googletest-options-test.cc} (91%) rename src/test/gtest/{test/gtest_output_test_golden_lin.txt => googletest/test/googletest-output-test-golden-lin.txt} (55%) rename src/test/gtest/{test/gtest_output_test.py => googletest/test/googletest-output-test.py} (84%) rename src/test/gtest/{test/gtest_output_test_.cc => googletest/test/googletest-output-test_.cc} (78%) create mode 100644 src/test/gtest/googletest/test/googletest-param-test-invalid-name1-test.py create mode 100644 src/test/gtest/googletest/test/googletest-param-test-invalid-name1-test_.cc create mode 100644 src/test/gtest/googletest/test/googletest-param-test-invalid-name2-test.py create mode 100644 src/test/gtest/googletest/test/googletest-param-test-invalid-name2-test_.cc rename src/test/gtest/{test/gtest-param-test_test.cc => googletest/test/googletest-param-test-test.cc} (69%) rename src/test/gtest/{test/gtest-param-test_test.h => googletest/test/googletest-param-test-test.h} (91%) rename src/test/gtest/{test/gtest-param-test2_test.cc => googletest/test/googletest-param-test2-test.cc} (73%) rename src/test/gtest/{test/gtest-port_test.cc => googletest/test/googletest-port-test.cc} (88%) rename src/test/gtest/{test/gtest-printers_test.cc => googletest/test/googletest-printers-test.cc} (80%) rename src/test/gtest/{test/gtest_shuffle_test.py => googletest/test/googletest-shuffle-test.py} (98%) rename src/test/gtest/{test/gtest_shuffle_test_.cc => googletest/test/googletest-shuffle-test_.cc} (91%) rename src/test/gtest/{test/gtest-test-part_test.cc => googletest/test/googletest-test-part-test.cc} (86%) rename src/test/gtest/{xcode/Samples/FrameworkSample/widget_test.cc => googletest/test/googletest-test2_test.cc} (56%) rename src/test/gtest/{test/gtest_throw_on_failure_test.py => googletest/test/googletest-throw-on-failure-test.py} (90%) rename src/test/gtest/{test/gtest_throw_on_failure_test_.cc => googletest/test/googletest-throw-on-failure-test_.cc} (95%) rename src/test/gtest/{test/gtest_uninitialized_test.py => googletest/test/googletest-uninitialized-test.py} (90%) rename src/test/gtest/{test/gtest_uninitialized_test_.cc => googletest/test/googletest-uninitialized-test_.cc} (93%) rename src/test/gtest/{ => googletest}/test/gtest-typed-test2_test.cc (92%) rename src/test/gtest/{ => googletest}/test/gtest-typed-test_test.cc (56%) rename src/test/gtest/{ => googletest}/test/gtest-typed-test_test.h (92%) rename src/test/gtest/{ => googletest}/test/gtest-unittest-api_test.cc (52%) rename src/test/gtest/{ => googletest}/test/gtest_all_test.cc (85%) create mode 100644 src/test/gtest/googletest/test/gtest_assert_by_exception_test.cc rename src/test/gtest/{ => googletest}/test/gtest_environment_test.cc (96%) rename src/test/gtest/{ => googletest}/test/gtest_help_test.py (98%) rename src/test/gtest/{ => googletest}/test/gtest_help_test_.cc (97%) rename src/test/gtest/{xcode/Scripts/runtests.sh => googletest/test/gtest_json_test_utils.py} (58%) create mode 100644 src/test/gtest/googletest/test/gtest_list_output_unittest.py create mode 100644 src/test/gtest/googletest/test/gtest_list_output_unittest_.cc rename src/test/gtest/{ => googletest}/test/gtest_main_unittest.cc (92%) rename src/test/gtest/{ => googletest}/test/gtest_no_test_unittest.cc (98%) rename src/test/gtest/{ => googletest}/test/gtest_pred_impl_unittest.cc (98%) rename src/test/gtest/{ => googletest}/test/gtest_premature_exit_test.cc (83%) rename src/test/gtest/{ => googletest}/test/gtest_prod_test.cc (94%) rename src/test/gtest/{ => googletest}/test/gtest_repeat_test.cc (86%) create mode 100755 src/test/gtest/googletest/test/gtest_skip_environment_check_output_test.py create mode 100644 src/test/gtest/googletest/test/gtest_skip_in_environment_setup_test.cc create mode 100644 src/test/gtest/googletest/test/gtest_skip_test.cc rename src/test/gtest/{ => googletest}/test/gtest_sole_header_test.cc (97%) rename src/test/gtest/{ => googletest}/test/gtest_stress_test.cc (95%) create mode 100644 src/test/gtest/googletest/test/gtest_test_macro_stack_footprint_test.cc rename src/test/gtest/{ => googletest}/test/gtest_test_utils.py (92%) create mode 100755 src/test/gtest/googletest/test/gtest_testbridge_test.py create mode 100644 src/test/gtest/googletest/test/gtest_testbridge_test_.cc rename src/test/gtest/{ => googletest}/test/gtest_throw_on_failure_ex_test.cc (96%) rename src/test/gtest/{ => googletest}/test/gtest_unittest.cc (83%) rename src/test/gtest/{ => googletest}/test/gtest_xml_outfile1_test_.cc (90%) rename src/test/gtest/{ => googletest}/test/gtest_xml_outfile2_test_.cc (90%) rename src/test/gtest/{ => googletest}/test/gtest_xml_outfiles_test.py (86%) rename src/test/gtest/{ => googletest}/test/gtest_xml_output_unittest.py (57%) rename src/test/gtest/{ => googletest}/test/gtest_xml_output_unittest_.cc (86%) rename src/test/gtest/{ => googletest}/test/gtest_xml_test_utils.py (85%) rename src/test/gtest/{ => googletest}/test/production.cc (93%) rename src/test/gtest/{ => googletest}/test/production.h (95%) delete mode 100644 src/test/gtest/include/gtest/gtest-param-test.h delete mode 100644 src/test/gtest/include/gtest/gtest-typed-test.h delete mode 100644 src/test/gtest/include/gtest/internal/gtest-linked_ptr.h delete mode 100644 src/test/gtest/include/gtest/internal/gtest-param-util-generated.h delete mode 100644 src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump delete mode 100644 src/test/gtest/include/gtest/internal/gtest-param-util.h delete mode 100644 src/test/gtest/include/gtest/internal/gtest-tuple.h delete mode 100644 src/test/gtest/include/gtest/internal/gtest-tuple.h.pump create mode 100644 src/test/gtest/library.json delete mode 100644 src/test/gtest/m4/acx_pthread.m4 delete mode 100644 src/test/gtest/m4/gtest.m4 delete mode 100644 src/test/gtest/msvc/gtest-md.sln delete mode 100644 src/test/gtest/msvc/gtest-md.vcproj delete mode 100644 src/test/gtest/msvc/gtest.sln delete mode 100644 src/test/gtest/msvc/gtest.vcproj delete mode 100644 src/test/gtest/msvc/gtest_main-md.vcproj delete mode 100644 src/test/gtest/msvc/gtest_main.vcproj delete mode 100644 src/test/gtest/msvc/gtest_prod_test-md.vcproj delete mode 100644 src/test/gtest/msvc/gtest_prod_test.vcproj delete mode 100644 src/test/gtest/msvc/gtest_unittest-md.vcproj delete mode 100644 src/test/gtest/msvc/gtest_unittest.vcproj create mode 100644 src/test/gtest/platformio.ini delete mode 100644 src/test/gtest/test/gtest-linked_ptr_test.cc delete mode 100644 src/test/gtest/test/gtest-listener_test.cc delete mode 100644 src/test/gtest/test/gtest-tuple_test.cc delete mode 100644 src/test/gtest/xcode/Config/DebugProject.xcconfig delete mode 100644 src/test/gtest/xcode/Config/FrameworkTarget.xcconfig delete mode 100644 src/test/gtest/xcode/Config/General.xcconfig delete mode 100644 src/test/gtest/xcode/Config/ReleaseProject.xcconfig delete mode 100644 src/test/gtest/xcode/Config/StaticLibraryTarget.xcconfig delete mode 100644 src/test/gtest/xcode/Config/TestTarget.xcconfig delete mode 100644 src/test/gtest/xcode/Resources/Info.plist delete mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/Info.plist delete mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj delete mode 100644 src/test/gtest/xcode/Samples/FrameworkSample/widget.cc delete mode 100644 src/test/gtest/xcode/Scripts/versiongenerate.py delete mode 100644 src/test/gtest/xcode/gtest.xcodeproj/project.pbxproj diff --git a/src/test/gtest/.clang-format b/src/test/gtest/.clang-format new file mode 100644 index 00000000..5b9bfe6d --- /dev/null +++ b/src/test/gtest/.clang-format @@ -0,0 +1,4 @@ +# Run manually to reformat a file: +# clang-format -i --style=file +Language: Cpp +BasedOnStyle: Google diff --git a/src/test/gtest/.gitignore b/src/test/gtest/.gitignore new file mode 100644 index 00000000..f08cb72a --- /dev/null +++ b/src/test/gtest/.gitignore @@ -0,0 +1,84 @@ +# Ignore CI build directory +build/ +xcuserdata +cmake-build-debug/ +.idea/ +bazel-bin +bazel-genfiles +bazel-googletest +bazel-out +bazel-testlogs +# python +*.pyc + +# Visual Studio files +.vs +*.sdf +*.opensdf +*.VC.opendb +*.suo +*.user +_ReSharper.Caches/ +Win32-Debug/ +Win32-Release/ +x64-Debug/ +x64-Release/ + +# Ignore autoconf / automake files +Makefile.in +aclocal.m4 +configure +build-aux/ +autom4te.cache/ +googletest/m4/libtool.m4 +googletest/m4/ltoptions.m4 +googletest/m4/ltsugar.m4 +googletest/m4/ltversion.m4 +googletest/m4/lt~obsolete.m4 +googlemock/m4 + +# Ignore generated directories. +googlemock/fused-src/ +googletest/fused-src/ + +# macOS files +.DS_Store +googletest/.DS_Store +googletest/xcode/.DS_Store + +# Ignore cmake generated directories and files. +CMakeFiles +CTestTestfile.cmake +Makefile +cmake_install.cmake +googlemock/CMakeFiles +googlemock/CTestTestfile.cmake +googlemock/Makefile +googlemock/cmake_install.cmake +googlemock/gtest +/bin +/googlemock/gmock.dir +/googlemock/gmock_main.dir +/googlemock/RUN_TESTS.vcxproj.filters +/googlemock/RUN_TESTS.vcxproj +/googlemock/INSTALL.vcxproj.filters +/googlemock/INSTALL.vcxproj +/googlemock/gmock_main.vcxproj.filters +/googlemock/gmock_main.vcxproj +/googlemock/gmock.vcxproj.filters +/googlemock/gmock.vcxproj +/googlemock/gmock.sln +/googlemock/ALL_BUILD.vcxproj.filters +/googlemock/ALL_BUILD.vcxproj +/lib +/Win32 +/ZERO_CHECK.vcxproj.filters +/ZERO_CHECK.vcxproj +/RUN_TESTS.vcxproj.filters +/RUN_TESTS.vcxproj +/INSTALL.vcxproj.filters +/INSTALL.vcxproj +/googletest-distribution.sln +/CMakeCache.txt +/ALL_BUILD.vcxproj.filters +/ALL_BUILD.vcxproj diff --git a/src/test/gtest/.travis.yml b/src/test/gtest/.travis.yml new file mode 100644 index 00000000..04b51dde --- /dev/null +++ b/src/test/gtest/.travis.yml @@ -0,0 +1,73 @@ +# Build matrix / environment variable are explained on: +# https://docs.travis-ci.com/user/customizing-the-build/ +# This file can be validated on: +# http://lint.travis-ci.org/ + +language: cpp + +# Define the matrix explicitly, manually expanding the combinations of (os, compiler, env). +# It is more tedious, but grants us far more flexibility. +matrix: + include: + - os: linux + before_install: chmod -R +x ./ci/*platformio.sh + install: ./ci/install-platformio.sh + script: ./ci/build-platformio.sh + - os: linux + dist: xenial + compiler: gcc + install: ./ci/install-linux.sh && ./ci/log-config.sh + script: ./ci/build-linux-bazel.sh + - os: linux + dist: xenial + compiler: clang + install: ./ci/install-linux.sh && ./ci/log-config.sh + script: ./ci/build-linux-bazel.sh + - os: linux + compiler: gcc + env: BUILD_TYPE=Debug VERBOSE=1 CXX_FLAGS=-std=c++11 + - os: linux + compiler: clang + env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 -Wgnu-zero-variadic-macro-arguments + - os: linux + compiler: clang + env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 NO_EXCEPTION=ON NO_RTTI=ON COMPILER_IS_GNUCXX=ON + - os: osx + compiler: gcc + env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 HOMEBREW_LOGS=~/homebrew-logs HOMEBREW_TEMP=~/homebrew-temp + - os: osx + compiler: clang + env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 HOMEBREW_LOGS=~/homebrew-logs HOMEBREW_TEMP=~/homebrew-temp + +# These are the install and build (script) phases for the most common entries in the matrix. They could be included +# in each entry in the matrix, but that is just repetitive. +install: + - ./ci/install-${TRAVIS_OS_NAME}.sh + - . ./ci/env-${TRAVIS_OS_NAME}.sh + - ./ci/log-config.sh + +script: ./ci/travis.sh + +# This section installs the necessary dependencies. +addons: + apt: + # List of whitelisted in travis packages for ubuntu-precise can be found here: + # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise + # List of whitelisted in travis apt-sources: + # https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.9 + packages: + - g++-4.9 + - clang-3.9 + update: true + homebrew: + packages: + - ccache + - gcc@4.9 + - llvm@4 + update: true + +notifications: + email: false diff --git a/src/test/gtest/BUILD.bazel b/src/test/gtest/BUILD.bazel new file mode 100644 index 00000000..9b48aee5 --- /dev/null +++ b/src/test/gtest/BUILD.bazel @@ -0,0 +1,179 @@ +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. +# +# Bazel Build for Google C++ Testing Framework(Google Test) + +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +config_setting( + name = "windows", + constraint_values = ["@bazel_tools//platforms:windows"], +) + +config_setting( + name = "has_absl", + values = {"define": "absl=1"}, +) + +# Library that defines the FRIEND_TEST macro. +cc_library( + name = "gtest_prod", + hdrs = ["googletest/include/gtest/gtest_prod.h"], + includes = ["googletest/include"], +) + +# Google Test including Google Mock +cc_library( + name = "gtest", + srcs = glob( + include = [ + "googletest/src/*.cc", + "googletest/src/*.h", + "googletest/include/gtest/**/*.h", + "googlemock/src/*.cc", + "googlemock/include/gmock/**/*.h", + ], + exclude = [ + "googletest/src/gtest-all.cc", + "googletest/src/gtest_main.cc", + "googlemock/src/gmock-all.cc", + "googlemock/src/gmock_main.cc", + ], + ), + hdrs = glob([ + "googletest/include/gtest/*.h", + "googlemock/include/gmock/*.h", + ]), + copts = select({ + ":windows": [], + "//conditions:default": ["-pthread"], + }), + defines = select({ + ":has_absl": ["GTEST_HAS_ABSL=1"], + "//conditions:default": [], + }), + features = select({ + ":windows": ["windows_export_all_symbols"], + "//conditions:default": [], + }), + includes = [ + "googlemock", + "googlemock/include", + "googletest", + "googletest/include", + ], + linkopts = select({ + ":windows": [], + "//conditions:default": ["-pthread"], + }), + deps = select({ + ":has_absl": [ + "@com_google_absl//absl/debugging:failure_signal_handler", + "@com_google_absl//absl/debugging:stacktrace", + "@com_google_absl//absl/debugging:symbolize", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/types:optional", + "@com_google_absl//absl/types:variant", + ], + "//conditions:default": [], + }), +) + +cc_library( + name = "gtest_main", + srcs = ["googlemock/src/gmock_main.cc"], + features = select({ + ":windows": ["windows_export_all_symbols"], + "//conditions:default": [], + }), + deps = [":gtest"], +) + +# The following rules build samples of how to use gTest. +cc_library( + name = "gtest_sample_lib", + srcs = [ + "googletest/samples/sample1.cc", + "googletest/samples/sample2.cc", + "googletest/samples/sample4.cc", + ], + hdrs = [ + "googletest/samples/prime_tables.h", + "googletest/samples/sample1.h", + "googletest/samples/sample2.h", + "googletest/samples/sample3-inl.h", + "googletest/samples/sample4.h", + ], + features = select({ + ":windows": ["windows_export_all_symbols"], + "//conditions:default": [], + }), +) + +cc_test( + name = "gtest_samples", + size = "small", + # All Samples except: + # sample9 (main) + # sample10 (main and takes a command line option and needs to be separate) + srcs = [ + "googletest/samples/sample1_unittest.cc", + "googletest/samples/sample2_unittest.cc", + "googletest/samples/sample3_unittest.cc", + "googletest/samples/sample4_unittest.cc", + "googletest/samples/sample5_unittest.cc", + "googletest/samples/sample6_unittest.cc", + "googletest/samples/sample7_unittest.cc", + "googletest/samples/sample8_unittest.cc", + ], + linkstatic = 0, + deps = [ + "gtest_sample_lib", + ":gtest_main", + ], +) + +cc_test( + name = "sample9_unittest", + size = "small", + srcs = ["googletest/samples/sample9_unittest.cc"], + deps = [":gtest"], +) + +cc_test( + name = "sample10_unittest", + size = "small", + srcs = ["googletest/samples/sample10_unittest.cc"], + deps = [":gtest"], +) diff --git a/src/test/gtest/CHANGES b/src/test/gtest/CHANGES deleted file mode 100644 index 05521324..00000000 --- a/src/test/gtest/CHANGES +++ /dev/null @@ -1,157 +0,0 @@ -Changes for 1.7.0: - -* New feature: death tests are supported on OpenBSD and in iOS - simulator now. -* New feature: Google Test now implements a protocol to allow - a test runner to detect that a test program has exited - prematurely and report it as a failure (before it would be - falsely reported as a success if the exit code is 0). -* New feature: Test::RecordProperty() can now be used outside of the - lifespan of a test method, in which case it will be attributed to - the current test case or the test program in the XML report. -* New feature (potentially breaking): --gtest_list_tests now prints - the type parameters and value parameters for each test. -* Improvement: char pointers and char arrays are now escaped properly - in failure messages. -* Improvement: failure summary in XML reports now includes file and - line information. -* Improvement: the XML element now has a timestamp attribute. -* Improvement: When --gtest_filter is specified, XML report now doesn't - contain information about tests that are filtered out. -* Fixed the bug where long --gtest_filter flag values are truncated in - death tests. -* Potentially breaking change: RUN_ALL_TESTS() is now implemented as a - function instead of a macro in order to work better with Clang. -* Compatibility fixes with C++ 11 and various platforms. -* Bug/warning fixes. - -Changes for 1.6.0: - -* New feature: ADD_FAILURE_AT() for reporting a test failure at the - given source location -- useful for writing testing utilities. -* New feature: the universal value printer is moved from Google Mock - to Google Test. -* New feature: type parameters and value parameters are reported in - the XML report now. -* A gtest_disable_pthreads CMake option. -* Colored output works in GNU Screen sessions now. -* Parameters of value-parameterized tests are now printed in the - textual output. -* Failures from ad hoc test assertions run before RUN_ALL_TESTS() are - now correctly reported. -* Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to - ostream. -* More complete handling of exceptions. -* GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter - name is already used by another library. -* --gtest_catch_exceptions is now true by default, allowing a test - program to continue after an exception is thrown. -* Value-parameterized test fixtures can now derive from Test and - WithParamInterface separately, easing conversion of legacy tests. -* Death test messages are clearly marked to make them more - distinguishable from other messages. -* Compatibility fixes for Android, Google Native Client, MinGW, HP UX, - PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear), - IBM XL C++ (Visual Age C++), and C++0x. -* Bug fixes and implementation clean-ups. -* Potentially incompatible changes: disables the harmful 'make install' - command in autotools. - -Changes for 1.5.0: - - * New feature: assertions can be safely called in multiple threads - where the pthreads library is available. - * New feature: predicates used inside EXPECT_TRUE() and friends - can now generate custom failure messages. - * New feature: Google Test can now be compiled as a DLL. - * New feature: fused source files are included. - * New feature: prints help when encountering unrecognized Google Test flags. - * Experimental feature: CMake build script (requires CMake 2.6.4+). - * Experimental feature: the Pump script for meta programming. - * double values streamed to an assertion are printed with enough precision - to differentiate any two different values. - * Google Test now works on Solaris and AIX. - * Build and test script improvements. - * Bug fixes and implementation clean-ups. - - Potentially breaking changes: - - * Stopped supporting VC++ 7.1 with exceptions disabled. - * Dropped support for 'make install'. - -Changes for 1.4.0: - - * New feature: the event listener API - * New feature: test shuffling - * New feature: the XML report format is closer to junitreport and can - be parsed by Hudson now. - * New feature: when a test runs under Visual Studio, its failures are - integrated in the IDE. - * New feature: /MD(d) versions of VC++ projects. - * New feature: elapsed time for the tests is printed by default. - * New feature: comes with a TR1 tuple implementation such that Boost - is no longer needed for Combine(). - * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. - * New feature: the Xcode project can now produce static gtest - libraries in addition to a framework. - * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, - Symbian, gcc, and C++Builder. - * Bug fixes and implementation clean-ups. - -Changes for 1.3.0: - - * New feature: death tests on Windows, Cygwin, and Mac. - * New feature: ability to use Google Test assertions in other testing - frameworks. - * New feature: ability to run disabled test via - --gtest_also_run_disabled_tests. - * New feature: the --help flag for printing the usage. - * New feature: access to Google Test flag values in user code. - * New feature: a script that packs Google Test into one .h and one - .cc file for easy deployment. - * New feature: support for distributing test functions to multiple - machines (requires support from the test runner). - * Bug fixes and implementation clean-ups. - -Changes for 1.2.1: - - * Compatibility fixes for Linux IA-64 and IBM z/OS. - * Added support for using Boost and other TR1 implementations. - * Changes to the build scripts to support upcoming release of Google C++ - Mocking Framework. - * Added Makefile to the distribution package. - * Improved build instructions in README. - -Changes for 1.2.0: - - * New feature: value-parameterized tests. - * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS) - macros. - * Changed the XML report format to match JUnit/Ant's. - * Added tests to the Xcode project. - * Added scons/SConscript for building with SCons. - * Added src/gtest-all.cc for building Google Test from a single file. - * Fixed compatibility with Solaris and z/OS. - * Enabled running Python tests on systems with python 2.3 installed, - e.g. Mac OS X 10.4. - * Bug fixes. - -Changes for 1.1.0: - - * New feature: type-parameterized tests. - * New feature: exception assertions. - * New feature: printing elapsed time of tests. - * Improved the robustness of death tests. - * Added an Xcode project and samples. - * Adjusted the output format on Windows to be understandable by Visual Studio. - * Minor bug fixes. - -Changes for 1.0.1: - - * Added project files for Visual Studio 7.1. - * Fixed issues with compiling on Mac OS X. - * Fixed issues with compiling on Cygwin. - -Changes for 1.0.0: - - * Initial Open Source release of Google Test diff --git a/src/test/gtest/CMakeLists.txt b/src/test/gtest/CMakeLists.txt index bd78cfe6..f11bbb52 100644 --- a/src/test/gtest/CMakeLists.txt +++ b/src/test/gtest/CMakeLists.txt @@ -1,260 +1,36 @@ -######################################################################## -# CMake build script for Google Test. -# -# To run the tests for Google Test itself on Linux, use 'make test' or -# ctest. You can select which tests to run using 'ctest -R regex'. -# For more options, run 'ctest --help'. +# Note: CMake support is community-based. The maintainers do not use CMake +# internally. -# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to -# make it prominent in the GUI. -option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) +cmake_minimum_required(VERSION 2.8.8) -# When other libraries are using a shared version of runtime libraries, -# Google Test also has to use one. -option( - gtest_force_shared_crt - "Use shared (DLL) run-time lib even when Google Test is built as static lib." - OFF) +if (POLICY CMP0048) + cmake_policy(SET CMP0048 NEW) +endif (POLICY CMP0048) -option(gtest_build_tests "Build all of gtest's own tests." OFF) +project(googletest-distribution) +set(GOOGLETEST_VERSION 1.10.0) -option(gtest_build_samples "Build gtest's sample programs." OFF) - -option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF) - -# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). -include(cmake/hermetic_build.cmake OPTIONAL) - -if (COMMAND pre_project_set_up_hermetic_build) - pre_project_set_up_hermetic_build() -endif() - -######################################################################## -# -# Project-wide settings - -# Name of the project. -# -# CMake files in this project can refer to the root source directory -# as ${gtest_SOURCE_DIR} and to the root binary directory as -# ${gtest_BINARY_DIR}. -# Language "C" is required for find_package(Threads). -project(gtest CXX C) -cmake_minimum_required(VERSION 2.6.2) - -if (COMMAND set_up_hermetic_build) - set_up_hermetic_build() -endif() - -# Define helper functions and macros used by Google Test. -include(cmake/internal_utils.cmake) - -config_compiler_and_linker() # Defined in internal_utils.cmake. - -# Where Google Test's .h files can be found. -include_directories( - ${gtest_SOURCE_DIR}/include - ${gtest_SOURCE_DIR}) - -# Where Google Test's libraries can be found. -link_directories(${gtest_BINARY_DIR}/src) - -# Summary of tuple support for Microsoft Visual Studio: -# Compiler version(MS) version(cmake) Support -# ---------- ----------- -------------- ----------------------------- -# <= VS 2010 <= 10 <= 1600 Use Google Tests's own tuple. -# VS 2012 11 1700 std::tr1::tuple + _VARIADIC_MAX=10 -# VS 2013 12 1800 std::tr1::tuple -if (MSVC AND MSVC_VERSION EQUAL 1700) - add_definitions(/D _VARIADIC_MAX=10) -endif() - -######################################################################## -# -# Defines the gtest & gtest_main libraries. User tests should link -# with one of them. - -# Google Test libraries. We build them using more strict warnings than what -# are used for other targets, to ensure that gtest can be compiled by a user -# aggressive about warnings. -cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) -cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) -target_link_libraries(gtest_main gtest) - -######################################################################## -# -# Samples on how to link user tests with gtest or gtest_main. -# -# They are not built by default. To build them, set the -# gtest_build_samples option to ON. You can do it by running ccmake -# or specifying the -Dgtest_build_samples=ON flag when running cmake. - -if (gtest_build_samples) - cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc) - cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc) - cxx_executable(sample3_unittest samples gtest_main) - cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc) - cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc) - cxx_executable(sample6_unittest samples gtest_main) - cxx_executable(sample7_unittest samples gtest_main) - cxx_executable(sample8_unittest samples gtest_main) - cxx_executable(sample9_unittest samples gtest) - cxx_executable(sample10_unittest samples gtest) -endif() - -######################################################################## -# -# Google Test's own tests. -# -# You can skip this section if you aren't interested in testing -# Google Test itself. -# -# The tests are not built by default. To build them, set the -# gtest_build_tests option to ON. You can do it by running ccmake -# or specifying the -Dgtest_build_tests=ON flag when running cmake. - -if (gtest_build_tests) - # This must be set in the root directory for the tests to be run by - # 'make test' or ctest. - enable_testing() - - ############################################################ - # C++ tests built with standard compiler flags. - - cxx_test(gtest-death-test_test gtest_main) - cxx_test(gtest_environment_test gtest) - cxx_test(gtest-filepath_test gtest_main) - cxx_test(gtest-linked_ptr_test gtest_main) - cxx_test(gtest-listener_test gtest_main) - cxx_test(gtest_main_unittest gtest_main) - cxx_test(gtest-message_test gtest_main) - cxx_test(gtest_no_test_unittest gtest) - cxx_test(gtest-options_test gtest_main) - cxx_test(gtest-param-test_test gtest - test/gtest-param-test2_test.cc) - cxx_test(gtest-port_test gtest_main) - cxx_test(gtest_pred_impl_unittest gtest_main) - cxx_test(gtest_premature_exit_test gtest - test/gtest_premature_exit_test.cc) - cxx_test(gtest-printers_test gtest_main) - cxx_test(gtest_prod_test gtest_main - test/production.cc) - cxx_test(gtest_repeat_test gtest) - cxx_test(gtest_sole_header_test gtest_main) - cxx_test(gtest_stress_test gtest) - cxx_test(gtest-test-part_test gtest_main) - cxx_test(gtest_throw_on_failure_ex_test gtest) - cxx_test(gtest-typed-test_test gtest_main - test/gtest-typed-test2_test.cc) - cxx_test(gtest_unittest gtest_main) - cxx_test(gtest-unittest-api_test gtest) - - ############################################################ - # C++ tests built with non-standard compiler flags. - - # MSVC 7.1 does not support STL with exceptions disabled. - if (NOT MSVC OR MSVC_VERSION GREATER 1310) - cxx_library(gtest_no_exception "${cxx_no_exception}" - src/gtest-all.cc) - cxx_library(gtest_main_no_exception "${cxx_no_exception}" - src/gtest-all.cc src/gtest_main.cc) - endif() - cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" - src/gtest-all.cc src/gtest_main.cc) - - cxx_test_with_flags(gtest-death-test_ex_nocatch_test - "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0" - gtest test/gtest-death-test_ex_test.cc) - cxx_test_with_flags(gtest-death-test_ex_catch_test - "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1" - gtest test/gtest-death-test_ex_test.cc) - - cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" - gtest_main_no_rtti test/gtest_unittest.cc) - - cxx_shared_library(gtest_dll "${cxx_default}" - src/gtest-all.cc src/gtest_main.cc) - - cxx_executable_with_flags(gtest_dll_test_ "${cxx_default}" - gtest_dll test/gtest_all_test.cc) - set_target_properties(gtest_dll_test_ - PROPERTIES - COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") - - if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010. - # Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that - # conflict with our own definitions. Therefore using our own tuple does not - # work on those compilers. - cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}" - src/gtest-all.cc src/gtest_main.cc) - - cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}" - gtest_main_use_own_tuple test/gtest-tuple_test.cc) - - cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}" - gtest_main_use_own_tuple - test/gtest-param-test_test.cc test/gtest-param-test2_test.cc) +if (CMAKE_VERSION VERSION_LESS "3.1") + add_definitions(-std=c++11) +else() + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + if(NOT CYGWIN) + set(CMAKE_CXX_EXTENSIONS OFF) endif() +endif() - ############################################################ - # Python tests. - - cxx_executable(gtest_break_on_failure_unittest_ test gtest) - py_test(gtest_break_on_failure_unittest) - - # Visual Studio .NET 2003 does not support STL with exceptions disabled. - if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003 - cxx_executable_with_flags( - gtest_catch_exceptions_no_ex_test_ - "${cxx_no_exception}" - gtest_main_no_exception - test/gtest_catch_exceptions_test_.cc) - endif() - - cxx_executable_with_flags( - gtest_catch_exceptions_ex_test_ - "${cxx_exception}" - gtest_main - test/gtest_catch_exceptions_test_.cc) - py_test(gtest_catch_exceptions_test) - - cxx_executable(gtest_color_test_ test gtest) - py_test(gtest_color_test) - - cxx_executable(gtest_env_var_test_ test gtest) - py_test(gtest_env_var_test) - - cxx_executable(gtest_filter_unittest_ test gtest) - py_test(gtest_filter_unittest) - - cxx_executable(gtest_help_test_ test gtest_main) - py_test(gtest_help_test) - - cxx_executable(gtest_list_tests_unittest_ test gtest) - py_test(gtest_list_tests_unittest) - - cxx_executable(gtest_output_test_ test gtest) - py_test(gtest_output_test) - - cxx_executable(gtest_shuffle_test_ test gtest) - py_test(gtest_shuffle_test) - - # MSVC 7.1 does not support STL with exceptions disabled. - if (NOT MSVC OR MSVC_VERSION GREATER 1310) - cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception) - set_target_properties(gtest_throw_on_failure_test_ - PROPERTIES - COMPILE_FLAGS "${cxx_no_exception}") - py_test(gtest_throw_on_failure_test) - endif() +enable_testing() - cxx_executable(gtest_uninitialized_test_ test gtest) - py_test(gtest_uninitialized_test) +include(CMakeDependentOption) +include(GNUInstallDirs) - cxx_executable(gtest_xml_outfile1_test_ test gtest_main) - cxx_executable(gtest_xml_outfile2_test_ test gtest_main) - py_test(gtest_xml_outfiles_test) +#Note that googlemock target already builds googletest +option(BUILD_GMOCK "Builds the googlemock subproject" ON) +option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON) - cxx_executable(gtest_xml_output_unittest_ test gtest) - py_test(gtest_xml_output_unittest) +if(BUILD_GMOCK) + add_subdirectory( googlemock ) +else() + add_subdirectory( googletest ) endif() diff --git a/src/test/gtest/CONTRIBUTING.md b/src/test/gtest/CONTRIBUTING.md new file mode 100644 index 00000000..30c8d890 --- /dev/null +++ b/src/test/gtest/CONTRIBUTING.md @@ -0,0 +1,142 @@ +# How to become a contributor and submit your own code + +## Contributor License Agreements + +We'd love to accept your patches! Before we can take them, we have to jump a +couple of legal hurdles. + +Please fill out either the individual or corporate Contributor License Agreement +(CLA). + +* If you are an individual writing original source code and you're sure you + own the intellectual property, then you'll need to sign an + [individual CLA](https://developers.google.com/open-source/cla/individual). +* If you work for a company that wants to allow you to contribute your work, + then you'll need to sign a + [corporate CLA](https://developers.google.com/open-source/cla/corporate). + +Follow either of the two links above to access the appropriate CLA and +instructions for how to sign and return it. Once we receive it, we'll be able to +accept your pull requests. + +## Are you a Googler? + +If you are a Googler, please make an attempt to submit an internal change rather +than a GitHub Pull Request. If you are not able to submit an internal change a +PR is acceptable as an alternative. + +## Contributing A Patch + +1. Submit an issue describing your proposed change to the + [issue tracker](https://github.com/google/googletest). +2. Please don't mix more than one logical change per submittal, because it + makes the history hard to follow. If you want to make a change that doesn't + have a corresponding issue in the issue tracker, please create one. +3. Also, coordinate with team members that are listed on the issue in question. + This ensures that work isn't being duplicated and communicating your plan + early also generally leads to better patches. +4. If your proposed change is accepted, and you haven't already done so, sign a + Contributor License Agreement (see details above). +5. Fork the desired repo, develop and test your code changes. +6. Ensure that your code adheres to the existing style in the sample to which + you are contributing. +7. Ensure that your code has an appropriate set of unit tests which all pass. +8. Submit a pull request. + +## The Google Test and Google Mock Communities + +The Google Test community exists primarily through the +[discussion group](http://groups.google.com/group/googletestframework) and the +GitHub repository. Likewise, the Google Mock community exists primarily through +their own [discussion group](http://groups.google.com/group/googlemock). You are +definitely encouraged to contribute to the discussion and you can also help us +to keep the effectiveness of the group high by following and promoting the +guidelines listed here. + +### Please Be Friendly + +Showing courtesy and respect to others is a vital part of the Google culture, +and we strongly encourage everyone participating in Google Test development to +join us in accepting nothing less. Of course, being courteous is not the same as +failing to constructively disagree with each other, but it does mean that we +should be respectful of each other when enumerating the 42 technical reasons +that a particular proposal may not be the best choice. There's never a reason to +be antagonistic or dismissive toward anyone who is sincerely trying to +contribute to a discussion. + +Sure, C++ testing is serious business and all that, but it's also a lot of fun. +Let's keep it that way. Let's strive to be one of the friendliest communities in +all of open source. + +As always, discuss Google Test in the official GoogleTest discussion group. You +don't have to actually submit code in order to sign up. Your participation +itself is a valuable contribution. + +## Style + +To keep the source consistent, readable, diffable and easy to merge, we use a +fairly rigid coding style, as defined by the +[google-styleguide](https://github.com/google/styleguide) project. All patches +will be expected to conform to the style outlined +[here](https://google.github.io/styleguide/cppguide.html). Use +[.clang-format](https://github.com/google/googletest/blob/master/.clang-format) +to check your formatting + +## Requirements for Contributors + +If you plan to contribute a patch, you need to build Google Test, Google Mock, +and their own tests from a git checkout, which has further requirements: + +* [Python](https://www.python.org/) v2.3 or newer (for running some of the + tests and re-generating certain source files from templates) +* [CMake](https://cmake.org/) v2.6.4 or newer + +## Developing Google Test and Google Mock + +This section discusses how to make your own changes to the Google Test project. + +### Testing Google Test and Google Mock Themselves + +To make sure your changes work as intended and don't break existing +functionality, you'll want to compile and run Google Test and GoogleMock's own +tests. For that you can use CMake: + + mkdir mybuild + cd mybuild + cmake -Dgtest_build_tests=ON -Dgmock_build_tests=ON ${GTEST_REPO_DIR} + +To choose between building only Google Test or Google Mock, you may modify your +cmake command to be one of each + + cmake -Dgtest_build_tests=ON ${GTEST_DIR} # sets up Google Test tests + cmake -Dgmock_build_tests=ON ${GMOCK_DIR} # sets up Google Mock tests + +Make sure you have Python installed, as some of Google Test's tests are written +in Python. If the cmake command complains about not being able to find Python +(`Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)`), try telling it +explicitly where your Python executable can be found: + + cmake -DPYTHON_EXECUTABLE=path/to/python ... + +Next, you can build Google Test and / or Google Mock and all desired tests. On +\*nix, this is usually done by + + make + +To run the tests, do + + make test + +All tests should pass. + +### Regenerating Source Files + +Some of Google Test's source files are generated from templates (not in the C++ +sense) using a script. For example, the file +include/gtest/internal/gtest-type-util.h.pump is used to generate +gtest-type-util.h in the same directory. + +You don't need to worry about regenerating the source files unless you need to +modify them. You would then modify the corresponding `.pump` files and run the +'[pump.py](googletest/scripts/pump.py)' generator script. See the +[Pump Manual](googletest/docs/pump_manual.md). diff --git a/src/test/gtest/Makefile.am b/src/test/gtest/Makefile.am deleted file mode 100644 index 9c96b425..00000000 --- a/src/test/gtest/Makefile.am +++ /dev/null @@ -1,306 +0,0 @@ -# Automake file - -ACLOCAL_AMFLAGS = -I m4 - -# Nonstandard package files for distribution -EXTRA_DIST = \ - CHANGES \ - CONTRIBUTORS \ - LICENSE \ - include/gtest/gtest-param-test.h.pump \ - include/gtest/internal/gtest-param-util-generated.h.pump \ - include/gtest/internal/gtest-tuple.h.pump \ - include/gtest/internal/gtest-type-util.h.pump \ - make/Makefile \ - scripts/fuse_gtest_files.py \ - scripts/gen_gtest_pred_impl.py \ - scripts/pump.py \ - scripts/test/Makefile - -# gtest source files that we don't compile directly. They are -# #included by gtest-all.cc. -GTEST_SRC = \ - src/gtest-death-test.cc \ - src/gtest-filepath.cc \ - src/gtest-internal-inl.h \ - src/gtest-port.cc \ - src/gtest-printers.cc \ - src/gtest-test-part.cc \ - src/gtest-typed-test.cc \ - src/gtest.cc - -EXTRA_DIST += $(GTEST_SRC) - -# Sample files that we don't compile. -EXTRA_DIST += \ - samples/prime_tables.h \ - samples/sample2_unittest.cc \ - samples/sample3_unittest.cc \ - samples/sample4_unittest.cc \ - samples/sample5_unittest.cc \ - samples/sample6_unittest.cc \ - samples/sample7_unittest.cc \ - samples/sample8_unittest.cc \ - samples/sample9_unittest.cc - -# C++ test files that we don't compile directly. -EXTRA_DIST += \ - test/gtest-death-test_ex_test.cc \ - test/gtest-death-test_test.cc \ - test/gtest-filepath_test.cc \ - test/gtest-linked_ptr_test.cc \ - test/gtest-listener_test.cc \ - test/gtest-message_test.cc \ - test/gtest-options_test.cc \ - test/gtest-param-test2_test.cc \ - test/gtest-param-test2_test.cc \ - test/gtest-param-test_test.cc \ - test/gtest-param-test_test.cc \ - test/gtest-param-test_test.h \ - test/gtest-port_test.cc \ - test/gtest_premature_exit_test.cc \ - test/gtest-printers_test.cc \ - test/gtest-test-part_test.cc \ - test/gtest-tuple_test.cc \ - test/gtest-typed-test2_test.cc \ - test/gtest-typed-test_test.cc \ - test/gtest-typed-test_test.h \ - test/gtest-unittest-api_test.cc \ - test/gtest_break_on_failure_unittest_.cc \ - test/gtest_catch_exceptions_test_.cc \ - test/gtest_color_test_.cc \ - test/gtest_env_var_test_.cc \ - test/gtest_environment_test.cc \ - test/gtest_filter_unittest_.cc \ - test/gtest_help_test_.cc \ - test/gtest_list_tests_unittest_.cc \ - test/gtest_main_unittest.cc \ - test/gtest_no_test_unittest.cc \ - test/gtest_output_test_.cc \ - test/gtest_pred_impl_unittest.cc \ - test/gtest_prod_test.cc \ - test/gtest_repeat_test.cc \ - test/gtest_shuffle_test_.cc \ - test/gtest_sole_header_test.cc \ - test/gtest_stress_test.cc \ - test/gtest_throw_on_failure_ex_test.cc \ - test/gtest_throw_on_failure_test_.cc \ - test/gtest_uninitialized_test_.cc \ - test/gtest_unittest.cc \ - test/gtest_unittest.cc \ - test/gtest_xml_outfile1_test_.cc \ - test/gtest_xml_outfile2_test_.cc \ - test/gtest_xml_output_unittest_.cc \ - test/production.cc \ - test/production.h - -# Python tests that we don't run. -EXTRA_DIST += \ - test/gtest_break_on_failure_unittest.py \ - test/gtest_catch_exceptions_test.py \ - test/gtest_color_test.py \ - test/gtest_env_var_test.py \ - test/gtest_filter_unittest.py \ - test/gtest_help_test.py \ - test/gtest_list_tests_unittest.py \ - test/gtest_output_test.py \ - test/gtest_output_test_golden_lin.txt \ - test/gtest_shuffle_test.py \ - test/gtest_test_utils.py \ - test/gtest_throw_on_failure_test.py \ - test/gtest_uninitialized_test.py \ - test/gtest_xml_outfiles_test.py \ - test/gtest_xml_output_unittest.py \ - test/gtest_xml_test_utils.py - -# CMake script -EXTRA_DIST += \ - CMakeLists.txt \ - cmake/internal_utils.cmake - -# MSVC project files -EXTRA_DIST += \ - msvc/gtest-md.sln \ - msvc/gtest-md.vcproj \ - msvc/gtest.sln \ - msvc/gtest.vcproj \ - msvc/gtest_main-md.vcproj \ - msvc/gtest_main.vcproj \ - msvc/gtest_prod_test-md.vcproj \ - msvc/gtest_prod_test.vcproj \ - msvc/gtest_unittest-md.vcproj \ - msvc/gtest_unittest.vcproj - -# xcode project files -EXTRA_DIST += \ - xcode/Config/DebugProject.xcconfig \ - xcode/Config/FrameworkTarget.xcconfig \ - xcode/Config/General.xcconfig \ - xcode/Config/ReleaseProject.xcconfig \ - xcode/Config/StaticLibraryTarget.xcconfig \ - xcode/Config/TestTarget.xcconfig \ - xcode/Resources/Info.plist \ - xcode/Scripts/runtests.sh \ - xcode/Scripts/versiongenerate.py \ - xcode/gtest.xcodeproj/project.pbxproj - -# xcode sample files -EXTRA_DIST += \ - xcode/Samples/FrameworkSample/Info.plist \ - xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \ - xcode/Samples/FrameworkSample/runtests.sh \ - xcode/Samples/FrameworkSample/widget.cc \ - xcode/Samples/FrameworkSample/widget.h \ - xcode/Samples/FrameworkSample/widget_test.cc - -# C++Builder project files -EXTRA_DIST += \ - codegear/gtest.cbproj \ - codegear/gtest.groupproj \ - codegear/gtest_all.cc \ - codegear/gtest_link.cc \ - codegear/gtest_main.cbproj \ - codegear/gtest_unittest.cbproj - -# Distribute and install M4 macro -m4datadir = $(datadir)/aclocal -m4data_DATA = m4/gtest.m4 -EXTRA_DIST += $(m4data_DATA) - -# We define the global AM_CPPFLAGS as everything we compile includes from these -# directories. -AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include - -# Modifies compiler and linker flags for pthreads compatibility. -if HAVE_PTHREADS - AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 - AM_LIBS = @PTHREAD_LIBS@ -else - AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0 -endif - -# Build rules for libraries. -lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la - -lib_libgtest_la_SOURCES = src/gtest-all.cc - -pkginclude_HEADERS = \ - include/gtest/gtest-death-test.h \ - include/gtest/gtest-message.h \ - include/gtest/gtest-param-test.h \ - include/gtest/gtest-printers.h \ - include/gtest/gtest-spi.h \ - include/gtest/gtest-test-part.h \ - include/gtest/gtest-typed-test.h \ - include/gtest/gtest.h \ - include/gtest/gtest_pred_impl.h \ - include/gtest/gtest_prod.h - -pkginclude_internaldir = $(pkgincludedir)/internal -pkginclude_internal_HEADERS = \ - include/gtest/internal/gtest-death-test-internal.h \ - include/gtest/internal/gtest-filepath.h \ - include/gtest/internal/gtest-internal.h \ - include/gtest/internal/gtest-linked_ptr.h \ - include/gtest/internal/gtest-param-util-generated.h \ - include/gtest/internal/gtest-param-util.h \ - include/gtest/internal/gtest-port.h \ - include/gtest/internal/gtest-string.h \ - include/gtest/internal/gtest-tuple.h \ - include/gtest/internal/gtest-type-util.h - -lib_libgtest_main_la_SOURCES = src/gtest_main.cc -lib_libgtest_main_la_LIBADD = lib/libgtest.la - -# Bulid rules for samples and tests. Automake's naming for some of -# these variables isn't terribly obvious, so this is a brief -# reference: -# -# TESTS -- Programs run automatically by "make check" -# check_PROGRAMS -- Programs built by "make check" but not necessarily run - -noinst_LTLIBRARIES = samples/libsamples.la - -samples_libsamples_la_SOURCES = \ - samples/sample1.cc \ - samples/sample1.h \ - samples/sample2.cc \ - samples/sample2.h \ - samples/sample3-inl.h \ - samples/sample4.cc \ - samples/sample4.h - -TESTS= -TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \ - GTEST_BUILD_DIR="$(top_builddir)/test" -check_PROGRAMS= - -# A simple sample on using gtest. -TESTS += samples/sample1_unittest -check_PROGRAMS += samples/sample1_unittest -samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc -samples_sample1_unittest_LDADD = lib/libgtest_main.la \ - lib/libgtest.la \ - samples/libsamples.la - -# Another sample. It also verifies that libgtest works. -TESTS += samples/sample10_unittest -check_PROGRAMS += samples/sample10_unittest -samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc -samples_sample10_unittest_LDADD = lib/libgtest.la - -# This tests most constructs of gtest and verifies that libgtest_main -# and libgtest work. -TESTS += test/gtest_all_test -check_PROGRAMS += test/gtest_all_test -test_gtest_all_test_SOURCES = test/gtest_all_test.cc -test_gtest_all_test_LDADD = lib/libgtest_main.la \ - lib/libgtest.la - -# Tests that fused gtest files compile and work. -FUSED_GTEST_SRC = \ - fused-src/gtest/gtest-all.cc \ - fused-src/gtest/gtest.h \ - fused-src/gtest/gtest_main.cc - -if HAVE_PYTHON -TESTS += test/fused_gtest_test -check_PROGRAMS += test/fused_gtest_test -test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ - samples/sample1.cc samples/sample1_unittest.cc -test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src" - -# Build rules for putting fused Google Test files into the distribution -# package. The user can also create those files by manually running -# scripts/fuse_gtest_files.py. -$(test_fused_gtest_test_SOURCES): fused-gtest - -fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ - $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \ - scripts/fuse_gtest_files.py - mkdir -p "$(srcdir)/fused-src" - chmod -R u+w "$(srcdir)/fused-src" - rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc" - rm -f "$(srcdir)/fused-src/gtest/gtest.h" - "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src" - cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/" - -maintainer-clean-local: - rm -rf "$(srcdir)/fused-src" -endif - -# Death tests may produce core dumps in the build directory. In case -# this happens, clean them to keep distcleancheck happy. -CLEANFILES = core - -# Disables 'make install' as installing a compiled version of Google -# Test can lead to undefined behavior due to violation of the -# One-Definition Rule. - -install-exec-local: - echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." - false - -install-data-local: - echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." - false diff --git a/src/test/gtest/README b/src/test/gtest/README deleted file mode 100644 index 404bf3b8..00000000 --- a/src/test/gtest/README +++ /dev/null @@ -1,435 +0,0 @@ -Google C++ Testing Framework -============================ - -http://code.google.com/p/googletest/ - -Overview --------- - -Google's framework for writing C++ tests on a variety of platforms -(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the -xUnit architecture. Supports automatic test discovery, a rich set of -assertions, user-defined assertions, death tests, fatal and non-fatal -failures, various options for running the tests, and XML test report -generation. - -Please see the project page above for more information as well as the -mailing list for questions, discussions, and development. There is -also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please -join us! - -Requirements for End Users --------------------------- - -Google Test is designed to have fairly minimal requirements to build -and use with your projects, but there are some. Currently, we support -Linux, Windows, Mac OS X, and Cygwin. We will also make our best -effort to support other platforms (e.g. Solaris, AIX, and z/OS). -However, since core members of the Google Test project have no access -to these platforms, Google Test may have outstanding issues there. If -you notice any problems on your platform, please notify -googletestframework@googlegroups.com. Patches for fixing them are -even more welcome! - -### Linux Requirements ### - -These are the base requirements to build and use Google Test from a source -package (as described below): - * GNU-compatible Make or gmake - * POSIX-standard shell - * POSIX(-2) Regular Expressions (regex.h) - * A C++98-standard-compliant compiler - -### Windows Requirements ### - - * Microsoft Visual C++ 7.1 or newer - -### Cygwin Requirements ### - - * Cygwin 1.5.25-14 or newer - -### Mac OS X Requirements ### - - * Mac OS X 10.4 Tiger or newer - * Developer Tools Installed - -Also, you'll need CMake 2.6.4 or higher if you want to build the -samples using the provided CMake script, regardless of the platform. - -Requirements for Contributors ------------------------------ - -We welcome patches. If you plan to contribute a patch, you need to -build Google Test and its own tests from an SVN checkout (described -below), which has further requirements: - - * Python version 2.3 or newer (for running some of the tests and - re-generating certain source files from templates) - * CMake 2.6.4 or newer - -Getting the Source ------------------- - -There are two primary ways of getting Google Test's source code: you -can download a stable source release in your preferred archive format, -or directly check out the source from our Subversion (SVN) repository. -The SVN checkout requires a few extra steps and some extra software -packages on your system, but lets you track the latest development and -make patches much more easily, so we highly encourage it. - -### Source Package ### - -Google Test is released in versioned source packages which can be -downloaded from the download page [1]. Several different archive -formats are provided, but the only difference is the tools used to -manipulate them, and the size of the resulting file. Download -whichever you are most comfortable with. - - [1] http://code.google.com/p/googletest/downloads/list - -Once the package is downloaded, expand it using whichever tools you -prefer for that type. This will result in a new directory with the -name "gtest-X.Y.Z" which contains all of the source code. Here are -some examples on Linux: - - tar -xvzf gtest-X.Y.Z.tar.gz - tar -xvjf gtest-X.Y.Z.tar.bz2 - unzip gtest-X.Y.Z.zip - -### SVN Checkout ### - -To check out the main branch (also known as the "trunk") of Google -Test, run the following Subversion command: - - svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn - -Setting up the Build --------------------- - -To build Google Test and your tests that use it, you need to tell your -build system where to find its headers and source files. The exact -way to do it depends on which build system you use, and is usually -straightforward. - -### Generic Build Instructions ### - -Suppose you put Google Test in directory ${GTEST_DIR}. To build it, -create a library build target (or a project as called by Visual Studio -and Xcode) to compile - - ${GTEST_DIR}/src/gtest-all.cc - -with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR} -in the normal header search path. Assuming a Linux-like system and gcc, -something like the following will do: - - g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ - -pthread -c ${GTEST_DIR}/src/gtest-all.cc - ar -rv libgtest.a gtest-all.o - -(We need -pthread as Google Test uses threads.) - -Next, you should compile your test source file with -${GTEST_DIR}/include in the system header search path, and link it -with gtest and any other necessary libraries: - - g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \ - -o your_test - -As an example, the make/ directory contains a Makefile that you can -use to build Google Test on systems where GNU make is available -(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google -Test's own tests. Instead, it just builds the Google Test library and -a sample test. You can use it as a starting point for your own build -script. - -If the default settings are correct for your environment, the -following commands should succeed: - - cd ${GTEST_DIR}/make - make - ./sample1_unittest - -If you see errors, try to tweak the contents of make/Makefile to make -them go away. There are instructions in make/Makefile on how to do -it. - -### Using CMake ### - -Google Test comes with a CMake build script (CMakeLists.txt) that can -be used on a wide range of platforms ("C" stands for cross-platform.). -If you don't have CMake installed already, you can download it for -free from http://www.cmake.org/. - -CMake works by generating native makefiles or build projects that can -be used in the compiler environment of your choice. The typical -workflow starts with: - - mkdir mybuild # Create a directory to hold the build output. - cd mybuild - cmake ${GTEST_DIR} # Generate native build scripts. - -If you want to build Google Test's samples, you should replace the -last command with - - cmake -Dgtest_build_samples=ON ${GTEST_DIR} - -If you are on a *nix system, you should now see a Makefile in the -current directory. Just type 'make' to build gtest. - -If you use Windows and have Visual Studio installed, a gtest.sln file -and several .vcproj files will be created. You can then build them -using Visual Studio. - -On Mac OS X with Xcode installed, a .xcodeproj file will be generated. - -### Legacy Build Scripts ### - -Before settling on CMake, we have been providing hand-maintained build -projects/scripts for Visual Studio, Xcode, and Autotools. While we -continue to provide them for convenience, they are not actively -maintained any more. We highly recommend that you follow the -instructions in the previous two sections to integrate Google Test -with your existing build system. - -If you still need to use the legacy build scripts, here's how: - -The msvc\ folder contains two solutions with Visual C++ projects. -Open the gtest.sln or gtest-md.sln file using Visual Studio, and you -are ready to build Google Test the same way you build any Visual -Studio project. Files that have names ending with -md use DLL -versions of Microsoft runtime libraries (the /MD or the /MDd compiler -option). Files without that suffix use static versions of the runtime -libraries (the /MT or the /MTd option). Please note that one must use -the same option to compile both gtest and the test code. If you use -Visual Studio 2005 or above, we recommend the -md version as /MD is -the default for new projects in these versions of Visual Studio. - -On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using -Xcode. Build the "gtest" target. The universal binary framework will -end up in your selected build directory (selected in the Xcode -"Preferences..." -> "Building" pane and defaults to xcode/build). -Alternatively, at the command line, enter: - - xcodebuild - -This will build the "Release" configuration of gtest.framework in your -default build location. See the "xcodebuild" man page for more -information about building different configurations and building in -different locations. - -If you wish to use the Google Test Xcode project with Xcode 4.x and -above, you need to either: - * update the SDK configuration options in xcode/Config/General.xconfig. - Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If - you choose this route you lose the ability to target earlier versions - of MacOS X. - * Install an SDK for an earlier version. This doesn't appear to be - supported by Apple, but has been reported to work - (http://stackoverflow.com/questions/5378518). - -Tweaking Google Test --------------------- - -Google Test can be used in diverse environments. The default -configuration may not work (or may not work well) out of the box in -some environments. However, you can easily tweak Google Test by -defining control macros on the compiler command line. Generally, -these macros are named like GTEST_XYZ and you define them to either 1 -or 0 to enable or disable a certain feature. - -We list the most frequently used macros below. For a complete list, -see file include/gtest/internal/gtest-port.h. - -### Choosing a TR1 Tuple Library ### - -Some Google Test features require the C++ Technical Report 1 (TR1) -tuple library, which is not yet available with all compilers. The -good news is that Google Test implements a subset of TR1 tuple that's -enough for its own need, and will automatically use this when the -compiler doesn't provide TR1 tuple. - -Usually you don't need to care about which tuple library Google Test -uses. However, if your project already uses TR1 tuple, you need to -tell Google Test to use the same TR1 tuple library the rest of your -project uses, or the two tuple implementations will clash. To do -that, add - - -DGTEST_USE_OWN_TR1_TUPLE=0 - -to the compiler flags while compiling Google Test and your tests. If -you want to force Google Test to use its own tuple library, just add - - -DGTEST_USE_OWN_TR1_TUPLE=1 - -to the compiler flags instead. - -If you don't want Google Test to use tuple at all, add - - -DGTEST_HAS_TR1_TUPLE=0 - -and all features using tuple will be disabled. - -### Multi-threaded Tests ### - -Google Test is thread-safe where the pthread library is available. -After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE -macro to see whether this is the case (yes if the macro is #defined to -1, no if it's undefined.). - -If Google Test doesn't correctly detect whether pthread is available -in your environment, you can force it with - - -DGTEST_HAS_PTHREAD=1 - -or - - -DGTEST_HAS_PTHREAD=0 - -When Google Test uses pthread, you may need to add flags to your -compiler and/or linker to select the pthread library, or you'll get -link errors. If you use the CMake script or the deprecated Autotools -script, this is taken care of for you. If you use your own build -script, you'll need to read your compiler and linker's manual to -figure out what flags to add. - -### As a Shared Library (DLL) ### - -Google Test is compact, so most users can build and link it as a -static library for the simplicity. You can choose to use Google Test -as a shared library (known as a DLL on Windows) if you prefer. - -To compile *gtest* as a shared library, add - - -DGTEST_CREATE_SHARED_LIBRARY=1 - -to the compiler flags. You'll also need to tell the linker to produce -a shared library instead - consult your linker's manual for how to do -it. - -To compile your *tests* that use the gtest shared library, add - - -DGTEST_LINKED_AS_SHARED_LIBRARY=1 - -to the compiler flags. - -Note: while the above steps aren't technically necessary today when -using some compilers (e.g. GCC), they may become necessary in the -future, if we decide to improve the speed of loading the library (see -http://gcc.gnu.org/wiki/Visibility for details). Therefore you are -recommended to always add the above flags when using Google Test as a -shared library. Otherwise a future release of Google Test may break -your build script. - -### Avoiding Macro Name Clashes ### - -In C++, macros don't obey namespaces. Therefore two libraries that -both define a macro of the same name will clash if you #include both -definitions. In case a Google Test macro clashes with another -library, you can force Google Test to rename its macro to avoid the -conflict. - -Specifically, if both Google Test and some other code define macro -FOO, you can add - - -DGTEST_DONT_DEFINE_FOO=1 - -to the compiler flags to tell Google Test to change the macro's name -from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST. -For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write - - GTEST_TEST(SomeTest, DoesThis) { ... } - -instead of - - TEST(SomeTest, DoesThis) { ... } - -in order to define a test. - -Upgrating from an Earlier Version ---------------------------------- - -We strive to keep Google Test releases backward compatible. -Sometimes, though, we have to make some breaking changes for the -users' long-term benefits. This section describes what you'll need to -do if you are upgrading from an earlier version of Google Test. - -### Upgrading from 1.3.0 or Earlier ### - -You may need to explicitly enable or disable Google Test's own TR1 -tuple library. See the instructions in section "Choosing a TR1 Tuple -Library". - -### Upgrading from 1.4.0 or Earlier ### - -The Autotools build script (configure + make) is no longer officially -supportted. You are encouraged to migrate to your own build system or -use CMake. If you still need to use Autotools, you can find -instructions in the README file from Google Test 1.4.0. - -On platforms where the pthread library is available, Google Test uses -it in order to be thread-safe. See the "Multi-threaded Tests" section -for what this means to your build script. - -If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google -Test will no longer compile. This should affect very few people, as a -large portion of STL (including ) doesn't compile in this mode -anyway. We decided to stop supporting it in order to greatly simplify -Google Test's implementation. - -Developing Google Test ----------------------- - -This section discusses how to make your own changes to Google Test. - -### Testing Google Test Itself ### - -To make sure your changes work as intended and don't break existing -functionality, you'll want to compile and run Google Test's own tests. -For that you can use CMake: - - mkdir mybuild - cd mybuild - cmake -Dgtest_build_tests=ON ${GTEST_DIR} - -Make sure you have Python installed, as some of Google Test's tests -are written in Python. If the cmake command complains about not being -able to find Python ("Could NOT find PythonInterp (missing: -PYTHON_EXECUTABLE)"), try telling it explicitly where your Python -executable can be found: - - cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR} - -Next, you can build Google Test and all of its own tests. On *nix, -this is usually done by 'make'. To run the tests, do - - make test - -All tests should pass. - -### Regenerating Source Files ### - -Some of Google Test's source files are generated from templates (not -in the C++ sense) using a script. A template file is named FOO.pump, -where FOO is the name of the file it will generate. For example, the -file include/gtest/internal/gtest-type-util.h.pump is used to generate -gtest-type-util.h in the same directory. - -Normally you don't need to worry about regenerating the source files, -unless you need to modify them. In that case, you should modify the -corresponding .pump files instead and run the pump.py Python script to -regenerate them. You can find pump.py in the scripts/ directory. -Read the Pump manual [2] for how to use it. - - [2] http://code.google.com/p/googletest/wiki/PumpManual - -### Contributing a Patch ### - -We welcome patches. Please read the Google Test developer's guide [3] -for how you can contribute. In particular, make sure you have signed -the Contributor License Agreement, or we won't be able to accept the -patch. - - [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide - -Happy testing! diff --git a/src/test/gtest/README.md b/src/test/gtest/README.md new file mode 100644 index 00000000..5b417fa8 --- /dev/null +++ b/src/test/gtest/README.md @@ -0,0 +1,134 @@ +# Google Test + +#### OSS Builds Status: + +[![Build Status](https://api.travis-ci.org/google/googletest.svg?branch=master)](https://travis-ci.org/google/googletest) +[![Build status](https://ci.appveyor.com/api/projects/status/4o38plt0xbo1ubc8/branch/master?svg=true)](https://ci.appveyor.com/project/GoogleTestAppVeyor/googletest/branch/master) + +### Future Plans + +#### 1.8.x Release: + +[the 1.8.x](https://github.com/google/googletest/releases/tag/release-1.8.1) is +the last release that works with pre-C++11 compilers. The 1.8.x will not accept +any requests for any new features and any bugfix requests will only be accepted +if proven "critical" + +#### Post 1.8.x: + +On-going work to improve/cleanup/pay technical debt. When this work is completed +there will be a 1.9.x tagged release + +#### Post 1.9.x + +Post 1.9.x googletest will follow +[Abseil Live at Head philosophy](https://abseil.io/about/philosophy) + +## Welcome to **Google Test**, Google's C++ test framework! + +This repository is a merger of the formerly separate GoogleTest and GoogleMock +projects. These were so closely related that it makes sense to maintain and +release them together. + +Please subscribe to the mailing list at googletestframework@googlegroups.com for +questions, discussions, and development. + +### Getting started: + +The information for **Google Test** is available in the +[Google Test Primer](googletest/docs/primer.md) documentation. + +**Google Mock** is an extension to Google Test for writing and using C++ mock +classes. See the separate [Google Mock documentation](googlemock/README.md). + +More detailed documentation for googletest is in its interior +[googletest/README.md](googletest/README.md) file. + +## Features + +* An [xUnit](https://en.wikipedia.org/wiki/XUnit) test framework. +* Test discovery. +* A rich set of assertions. +* User-defined assertions. +* Death tests. +* Fatal and non-fatal failures. +* Value-parameterized tests. +* Type-parameterized tests. +* Various options for running the tests. +* XML test report generation. + +## Platforms + +Google test has been used on a variety of platforms: + +* Linux +* Mac OS X +* Windows +* Cygwin +* MinGW +* Windows Mobile +* Symbian +* PlatformIO + +## Who Is Using Google Test? + +In addition to many internal projects at Google, Google Test is also used by the +following notable projects: + +* The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser + and Chrome OS). +* The [LLVM](http://llvm.org/) compiler. +* [Protocol Buffers](https://github.com/google/protobuf), Google's data + interchange format. +* The [OpenCV](http://opencv.org/) computer vision library. +* [tiny-dnn](https://github.com/tiny-dnn/tiny-dnn): header only, + dependency-free deep learning framework in C++11. + +## Related Open Source Projects + +[GTest Runner](https://github.com/nholthaus/gtest-runner) is a Qt5 based +automated test-runner and Graphical User Interface with powerful features for +Windows and Linux platforms. + +[Google Test UI](https://github.com/ospector/gtest-gbar) is test runner that +runs your test binary, allows you to track its progress via a progress bar, and +displays a list of test failures. Clicking on one shows failure text. Google +Test UI is written in C#. + +[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event +listener for Google Test that implements the +[TAP protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) for test +result output. If your test runner understands TAP, you may find it useful. + +[gtest-parallel](https://github.com/google/gtest-parallel) is a test runner that +runs tests from your binary in parallel to provide significant speed-up. + +[GoogleTest Adapter](https://marketplace.visualstudio.com/items?itemName=DavidSchuldenfrei.gtest-adapter) +is a VS Code extension allowing to view Google Tests in a tree view, and +run/debug your tests. + +## Requirements + +Google Test is designed to have fairly minimal requirements to build and use +with your projects, but there are some. If you notice any problems on your +platform, please notify +[googletestframework@googlegroups.com](https://groups.google.com/forum/#!forum/googletestframework). +Patches for fixing them are welcome! + +### Build Requirements + +These are the base requirements to build and use Google Test from a source +package: + +* [Bazel](https://bazel.build/) or [CMake](https://cmake.org/). NOTE: Bazel is + the build system that googletest is using internally and tests against. + CMake is community-supported. + +* a C++11-standard-compliant compiler + +## Contributing change + +Please read the [`CONTRIBUTING.md`](CONTRIBUTING.md) for details on how to +contribute to this project. + +Happy testing! diff --git a/src/test/gtest/WORKSPACE b/src/test/gtest/WORKSPACE new file mode 100644 index 00000000..2289bdb7 --- /dev/null +++ b/src/test/gtest/WORKSPACE @@ -0,0 +1,23 @@ +workspace(name = "com_google_googletest") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +# Abseil +http_archive( + name = "com_google_absl", + urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"], + strip_prefix = "abseil-cpp-master", +) + +http_archive( + name = "rules_cc", + strip_prefix = "rules_cc-master", + urls = ["https://github.com/bazelbuild/rules_cc/archive/master.zip"], +) + +http_archive( + name = "rules_python", + strip_prefix = "rules_python-master", + urls = ["https://github.com/bazelbuild/rules_python/archive/master.zip"], +) + diff --git a/src/test/gtest/appveyor.yml b/src/test/gtest/appveyor.yml new file mode 100644 index 00000000..a58b7687 --- /dev/null +++ b/src/test/gtest/appveyor.yml @@ -0,0 +1,154 @@ +version: '{build}' + +os: Visual Studio 2015 + +environment: + matrix: + - compiler: msvc-15-seh + generator: "Visual Studio 15 2017" + build_system: cmake + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + + - compiler: msvc-15-seh + generator: "Visual Studio 15 2017 Win64" + build_system: cmake + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + enabled_on_pr: yes + + - compiler: msvc-15-seh + build_system: bazel + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + enabled_on_pr: yes + + - compiler: msvc-14-seh + build_system: cmake + generator: "Visual Studio 14 2015" + enabled_on_pr: yes + + - compiler: msvc-14-seh + build_system: cmake + generator: "Visual Studio 14 2015 Win64" + + - compiler: gcc-6.3.0-posix + build_system: cmake + generator: "MinGW Makefiles" + cxx_path: 'C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin' + enabled_on_pr: yes + +configuration: + - Debug + +build: + verbosity: minimal + +install: +- ps: | + Write-Output "Compiler: $env:compiler" + Write-Output "Generator: $env:generator" + Write-Output "Env:Configuation: $env:configuration" + Write-Output "Env: $env" + if (-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) { + Write-Output "This is *NOT* a pull request build" + } else { + Write-Output "This is a pull request build" + if (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes") { + Write-Output "PR builds are *NOT* explicitly enabled" + } + } + + # install Bazel + if ($env:build_system -eq "bazel") { + appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/0.28.1/bazel-0.28.1-windows-x86_64.exe -FileName bazel.exe + } + + if ($env:build_system -eq "cmake") { + # git bash conflicts with MinGW makefiles + if ($env:generator -eq "MinGW Makefiles") { + $env:path = $env:path.replace("C:\Program Files\Git\usr\bin;", "") + if ($env:cxx_path -ne "") { + $env:path += ";$env:cxx_path" + } + } + } + +before_build: +- ps: | + $env:root=$env:APPVEYOR_BUILD_FOLDER + Write-Output "env:root: $env:root" + +build_script: +- ps: | + # Only enable some builds for pull requests, the AppVeyor queue is too long. + if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) { + return + } else { + # special case - build with Bazel + if ($env:build_system -eq "bazel") { + & $env:root\bazel.exe build -c opt //:gtest_samples + if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error + $host.SetShouldExit(0) + } else { # a real error + throw "Exec: $ErrorMessage" + } + return + } + } + # by default build with CMake + md _build -Force | Out-Null + cd _build + + $conf = if ($env:generator -eq "MinGW Makefiles") {"-DCMAKE_BUILD_TYPE=$env:configuration"} else {"-DCMAKE_CONFIGURATION_TYPES=Debug;Release"} + # Disable test for MinGW (gtest tests fail, gmock tests can not build) + $gtest_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgtest_build_tests=OFF"} else {"-Dgtest_build_tests=ON"} + $gmock_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgmock_build_tests=OFF"} else {"-Dgmock_build_tests=ON"} + & cmake -G "$env:generator" $conf -Dgtest_build_samples=ON $gtest_build_tests $gmock_build_tests .. + if ($LastExitCode -ne 0) { + throw "Exec: $ErrorMessage" + } + $cmake_parallel = if ($env:generator -eq "MinGW Makefiles") {"-j2"} else {"/m"} + & cmake --build . --config $env:configuration -- $cmake_parallel + if ($LastExitCode -ne 0) { + throw "Exec: $ErrorMessage" + } + + +skip_commits: + files: + - '**/*.md' + +test_script: +- ps: | + # Only enable some builds for pull requests, the AppVeyor queue is too long. + if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) { + return + } + if ($env:build_system -eq "bazel") { + # special case - testing with Bazel + & $env:root\bazel.exe test //:gtest_samples + if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error + $host.SetShouldExit(0) + } else { # a real error + throw "Exec: $ErrorMessage" + } + } + if ($env:build_system -eq "cmake") { + # built with CMake - test with CTest + if ($env:generator -eq "MinGW Makefiles") { + return # No test available for MinGW + } + + & ctest -C $env:configuration --timeout 600 --output-on-failure + if ($LastExitCode -ne 0) { + throw "Exec: $ErrorMessage" + } + } + +artifacts: + - path: '_build/CMakeFiles/*.log' + name: logs + - path: '_build/Testing/**/*.xml' + name: test_results + - path: 'bazel-testlogs/**/test.log' + name: test_logs + - path: 'bazel-testlogs/**/test.xml' + name: test_results diff --git a/src/test/gtest/ci/build-linux-bazel.sh b/src/test/gtest/ci/build-linux-bazel.sh new file mode 100755 index 00000000..ae8fb758 --- /dev/null +++ b/src/test/gtest/ci/build-linux-bazel.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +set -e + +bazel version +bazel build --curses=no //...:all +bazel test --curses=no //...:all +bazel test --curses=no //...:all --define absl=1 diff --git a/src/test/gtest/ci/build-platformio.sh b/src/test/gtest/ci/build-platformio.sh new file mode 100644 index 00000000..1d7658d8 --- /dev/null +++ b/src/test/gtest/ci/build-platformio.sh @@ -0,0 +1,2 @@ +# run PlatformIO builds +platformio run diff --git a/src/test/gtest/ci/env-linux.sh b/src/test/gtest/ci/env-linux.sh new file mode 100755 index 00000000..37800d6a --- /dev/null +++ b/src/test/gtest/ci/env-linux.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +# +# This file should be sourced, and not executed as a standalone script. +# + +# TODO() - we can check if this is being sourced using $BASH_VERSION and $BASH_SOURCE[0] != ${0}. + +if [ "${TRAVIS_OS_NAME}" = "linux" ]; then + if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi + if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.9" CC="clang-3.9"; fi +fi diff --git a/src/test/gtest/xcode/Samples/FrameworkSample/runtests.sh b/src/test/gtest/ci/env-osx.sh old mode 100644 new mode 100755 similarity index 63% rename from src/test/gtest/xcode/Samples/FrameworkSample/runtests.sh rename to src/test/gtest/ci/env-osx.sh index 4a0d413e..9c421e14 --- a/src/test/gtest/xcode/Samples/FrameworkSample/runtests.sh +++ b/src/test/gtest/ci/env-osx.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. # -# Copyright 2008, Google Inc. -# All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -29,34 +29,19 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Executes the samples and tests for the Google Test Framework. - -# Help the dynamic linker find the path to the libraries. -export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR -export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR - -# Create some executables. -test_executables=$@ +# +# This file should be sourced, and not executed as a standalone script. +# -# Now execute each one in turn keeping track of how many succeeded and failed. -succeeded=0 -failed=0 -failed_list=() -for test in ${test_executables[*]}; do - "$test" - result=$? - if [ $result -eq 0 ]; then - succeeded=$(( $succeeded + 1 )) - else - failed=$(( failed + 1 )) - failed_list="$failed_list $test" - fi -done +# TODO() - we can check if this is being sourced using $BASH_VERSION and $BASH_SOURCE[0] != ${0}. +# -# Report the successes and failures to the console. -echo "Tests complete with $succeeded successes and $failed failures." -if [ $failed -ne 0 ]; then - echo "The following tests failed:" - echo $failed_list +if [ "${TRAVIS_OS_NAME}" = "osx" ]; then + if [ "$CXX" = "clang++" ]; then + # $PATH needs to be adjusted because the llvm tap doesn't install the + # package to /usr/local/bin, etc, like the gcc tap does. + # See: https://github.com/Homebrew/legacy-homebrew/issues/29733 + clang_version=3.9 + export PATH="/usr/local/opt/llvm@${clang_version}/bin:$PATH"; + fi fi -exit $failed diff --git a/src/test/gtest/ci/get-nprocessors.sh b/src/test/gtest/ci/get-nprocessors.sh new file mode 100755 index 00000000..43635e76 --- /dev/null +++ b/src/test/gtest/ci/get-nprocessors.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +# This file is typically sourced by another script. +# if possible, ask for the precise number of processors, +# otherwise take 2 processors as reasonable default; see +# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization +if [ -x /usr/bin/getconf ]; then + NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN) +else + NPROCESSORS=2 +fi + +# as of 2017-09-04 Travis CI reports 32 processors, but GCC build +# crashes if parallelized too much (maybe memory consumption problem), +# so limit to 4 processors for the time being. +if [ $NPROCESSORS -gt 4 ] ; then + echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4." + NPROCESSORS=4 +fi diff --git a/src/test/gtest/ci/install-linux.sh b/src/test/gtest/ci/install-linux.sh new file mode 100755 index 00000000..05e2cb28 --- /dev/null +++ b/src/test/gtest/ci/install-linux.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +set -eu + +if [ "${TRAVIS_OS_NAME}" != linux ]; then + echo "Not a Linux build; skipping installation" + exit 0 +fi + + +if [ "${TRAVIS_SUDO}" = "true" ]; then + echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ + sudo tee /etc/apt/sources.list.d/bazel.list + curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add - + sudo apt-get update && sudo apt-get install -y bazel gcc-4.9 g++-4.9 clang-3.9 +elif [ "${CXX}" = "clang++" ]; then + # Use ccache, assuming $HOME/bin is in the path, which is true in the Travis build environment. + ln -sf /usr/bin/ccache $HOME/bin/${CXX}; + ln -sf /usr/bin/ccache $HOME/bin/${CC}; +fi diff --git a/src/test/gtest/ci/install-osx.sh b/src/test/gtest/ci/install-osx.sh new file mode 100755 index 00000000..cc475082 --- /dev/null +++ b/src/test/gtest/ci/install-osx.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +set -eu + +if [ "${TRAVIS_OS_NAME}" != "osx" ]; then + echo "Not a macOS build; skipping installation" + exit 0 +fi + +brew update +brew install ccache gcc@4.9 diff --git a/src/test/gtest/ci/install-platformio.sh b/src/test/gtest/ci/install-platformio.sh new file mode 100644 index 00000000..4d7860a5 --- /dev/null +++ b/src/test/gtest/ci/install-platformio.sh @@ -0,0 +1,5 @@ +# install PlatformIO +sudo pip install -U platformio + +# update PlatformIO +platformio update diff --git a/src/test/gtest/ci/log-config.sh b/src/test/gtest/ci/log-config.sh new file mode 100755 index 00000000..5fef1194 --- /dev/null +++ b/src/test/gtest/ci/log-config.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# Copyright 2017 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +set -e + +# ccache on OS X needs installation first +# reset ccache statistics +ccache --zero-stats + +echo PATH=${PATH} + +echo "Compiler configuration:" +echo CXX=${CXX} +echo CC=${CC} +echo CXXFLAGS=${CXXFLAGS} + +echo "C++ compiler version:" +${CXX} --version || echo "${CXX} does not seem to support the --version flag" +${CXX} -v || echo "${CXX} does not seem to support the -v flag" + +echo "C compiler version:" +${CC} --version || echo "${CXX} does not seem to support the --version flag" +${CC} -v || echo "${CXX} does not seem to support the -v flag" diff --git a/src/test/gtest/ci/travis.sh b/src/test/gtest/ci/travis.sh new file mode 100755 index 00000000..9ff3bad3 --- /dev/null +++ b/src/test/gtest/ci/travis.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env sh +set -evx + +. ci/get-nprocessors.sh + +# if possible, ask for the precise number of processors, +# otherwise take 2 processors as reasonable default; see +# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization +if [ -x /usr/bin/getconf ]; then + NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN) +else + NPROCESSORS=2 +fi +# as of 2017-09-04 Travis CI reports 32 processors, but GCC build +# crashes if parallelized too much (maybe memory consumption problem), +# so limit to 4 processors for the time being. +if [ $NPROCESSORS -gt 4 ] ; then + echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4." + NPROCESSORS=4 +fi +# Tell make to use the processors. No preceding '-' required. +MAKEFLAGS="j${NPROCESSORS}" +export MAKEFLAGS + +env | sort + +# Set default values to OFF for these variables if not specified. +: "${NO_EXCEPTION:=OFF}" +: "${NO_RTTI:=OFF}" +: "${COMPILER_IS_GNUCXX:=OFF}" + +mkdir build || true +cd build +cmake -Dgtest_build_samples=ON \ + -Dgtest_build_tests=ON \ + -Dgmock_build_tests=ON \ + -Dcxx_no_exception=$NO_EXCEPTION \ + -Dcxx_no_rtti=$NO_RTTI \ + -DCMAKE_COMPILER_IS_GNUCXX=$COMPILER_IS_GNUCXX \ + -DCMAKE_CXX_FLAGS=$CXX_FLAGS \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ + .. +make +CTEST_OUTPUT_ON_FAILURE=1 make test diff --git a/src/test/gtest/codegear/gtest.cbproj b/src/test/gtest/codegear/gtest.cbproj deleted file mode 100644 index 95c3054b..00000000 --- a/src/test/gtest/codegear/gtest.cbproj +++ /dev/null @@ -1,138 +0,0 @@ - - - - {bca37a72-5b07-46cf-b44e-89f8e06451a2} - Release - - - true - - - true - true - Base - - - true - true - Base - - - true - lib - JPHNE - NO_STRICT - true - true - CppStaticLibrary - true - rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi - false - $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. - rtl.lib;vcl.lib - 32 - $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk - - - false - false - true - _DEBUG;$(Defines) - true - false - true - None - DEBUG - true - Debug - true - true - true - $(BDS)\lib\debug;$(ILINK_LibraryPath) - Full - true - - - NDEBUG;$(Defines) - Release - $(BDS)\lib\release;$(ILINK_LibraryPath) - None - - - CPlusPlusBuilder.Personality - CppStaticLibrary - -FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse - - - CodeGear C++Builder Office 2000 Servers Package - CodeGear C++Builder Office XP Servers Package - FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 - - - - - 3 - - - 4 - - - 5 - - - 6 - - - 7 - - - 8 - - - 0 - - - 1 - - - 2 - - - 9 - - - 10 - - - 11 - - - 12 - - - 14 - - - 13 - - - 15 - - - 16 - - - 17 - - - 18 - - - Cfg_1 - - - Cfg_2 - - - \ No newline at end of file diff --git a/src/test/gtest/codegear/gtest.groupproj b/src/test/gtest/codegear/gtest.groupproj deleted file mode 100644 index faf31cab..00000000 --- a/src/test/gtest/codegear/gtest.groupproj +++ /dev/null @@ -1,54 +0,0 @@ - - - {c1d923e0-6cba-4332-9b6f-3420acbf5091} - - - - - - - - - Default.Personality - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/gtest/codegear/gtest_main.cbproj b/src/test/gtest/codegear/gtest_main.cbproj deleted file mode 100644 index d76ce139..00000000 --- a/src/test/gtest/codegear/gtest_main.cbproj +++ /dev/null @@ -1,82 +0,0 @@ - - - - {bca37a72-5b07-46cf-b44e-89f8e06451a2} - Release - - - true - - - true - true - Base - - - true - true - Base - - - true - lib - JPHNE - NO_STRICT - true - true - CppStaticLibrary - true - rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi - false - $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. - rtl.lib;vcl.lib - 32 - $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk - - - false - false - true - _DEBUG;$(Defines) - true - false - true - None - DEBUG - true - Debug - true - true - true - $(BDS)\lib\debug;$(ILINK_LibraryPath) - Full - true - - - NDEBUG;$(Defines) - Release - $(BDS)\lib\release;$(ILINK_LibraryPath) - None - - - CPlusPlusBuilder.Personality - CppStaticLibrary - -FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse - CodeGear C++Builder Office 2000 Servers Package - CodeGear C++Builder Office XP Servers Package - FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 - - - - - 0 - - - Cfg_1 - - - Cfg_2 - - - diff --git a/src/test/gtest/codegear/gtest_unittest.cbproj b/src/test/gtest/codegear/gtest_unittest.cbproj deleted file mode 100644 index dc5db8e4..00000000 --- a/src/test/gtest/codegear/gtest_unittest.cbproj +++ /dev/null @@ -1,88 +0,0 @@ - - - - {eea63393-5ac5-4b9c-8909-d75fef2daa41} - Release - - - true - - - true - true - Base - - - true - true - Base - - - exe - true - NO_STRICT - JPHNE - true - ..\test - true - CppConsoleApplication - true - true - rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi - false - $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;.. - $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test - true - - - false - false - true - _DEBUG;$(Defines) - true - false - true - None - DEBUG - true - Debug - true - true - true - $(BDS)\lib\debug;$(ILINK_LibraryPath) - Full - true - - - NDEBUG;$(Defines) - Release - $(BDS)\lib\release;$(ILINK_LibraryPath) - None - - - CPlusPlusBuilder.Personality - CppConsoleApplication - -FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse - - - CodeGear C++Builder Office 2000 Servers Package - CodeGear C++Builder Office XP Servers Package - FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test2NO_STRICTSTRICT - - - - - 0 - - - 1 - - - Cfg_1 - - - Cfg_2 - - - \ No newline at end of file diff --git a/src/test/gtest/configure.ac b/src/test/gtest/configure.ac deleted file mode 100644 index cc592e15..00000000 --- a/src/test/gtest/configure.ac +++ /dev/null @@ -1,68 +0,0 @@ -m4_include(m4/acx_pthread.m4) - -# At this point, the Xcode project assumes the version string will be three -# integers separated by periods and surrounded by square brackets (e.g. -# "[1.0.1]"). It also asumes that there won't be any closing parenthesis -# between "AC_INIT(" and the closing ")" including comments and strings. -AC_INIT([Google C++ Testing Framework], - [1.7.0], - [googletestframework@googlegroups.com], - [gtest]) - -# Provide various options to initialize the Autoconf and configure processes. -AC_PREREQ([2.59]) -AC_CONFIG_SRCDIR([./LICENSE]) -AC_CONFIG_MACRO_DIR([m4]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_HEADERS([build-aux/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([scripts/gtest-config], [chmod +x scripts/gtest-config]) - -# Initialize Automake with various options. We require at least v1.9, prevent -# pedantic complaints about package files, and enable various distribution -# targets. -AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects]) - -# Check for programs used in building Google Test. -AC_PROG_CC -AC_PROG_CXX -AC_LANG([C++]) -AC_PROG_LIBTOOL - -# TODO(chandlerc@google.com): Currently we aren't running the Python tests -# against the interpreter detected by AM_PATH_PYTHON, and so we condition -# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's -# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" -# hashbang. -PYTHON= # We *do not* allow the user to specify a python interpreter -AC_PATH_PROG([PYTHON],[python],[:]) -AS_IF([test "$PYTHON" != ":"], - [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) -AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) - -# Configure pthreads. -AC_ARG_WITH([pthreads], - [AS_HELP_STRING([--with-pthreads], - [use pthreads (default is yes)])], - [with_pthreads=$withval], - [with_pthreads=check]) - -have_pthreads=no -AS_IF([test "x$with_pthreads" != "xno"], - [ACX_PTHREAD( - [], - [AS_IF([test "x$with_pthreads" != "xcheck"], - [AC_MSG_FAILURE( - [--with-pthreads was specified, but unable to be used])])]) - have_pthreads="$acx_pthread_ok"]) -AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" = "xyes"]) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_LIBS) - -# TODO(chandlerc@google.com) Check for the necessary system headers. - -# TODO(chandlerc@google.com) Check the types, structures, and other compiler -# and architecture characteristics. - -# Output the generated files. No further autoconf macros may be used. -AC_OUTPUT diff --git a/src/test/gtest/googlemock/CMakeLists.txt b/src/test/gtest/googlemock/CMakeLists.txt new file mode 100644 index 00000000..d32b70b5 --- /dev/null +++ b/src/test/gtest/googlemock/CMakeLists.txt @@ -0,0 +1,233 @@ +######################################################################## +# Note: CMake support is community-based. The maintainers do not use CMake +# internally. +# +# CMake build script for Google Mock. +# +# To run the tests for Google Mock itself on Linux, use 'make test' or +# ctest. You can select which tests to run using 'ctest -R regex'. +# For more options, run 'ctest --help'. + +option(gmock_build_tests "Build all of Google Mock's own tests." OFF) + +# A directory to find Google Test sources. +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt") + set(gtest_dir gtest) +else() + set(gtest_dir ../googletest) +endif() + +# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). +include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL) + +if (COMMAND pre_project_set_up_hermetic_build) + # Google Test also calls hermetic setup functions from add_subdirectory, + # although its changes will not affect things at the current scope. + pre_project_set_up_hermetic_build() +endif() + +######################################################################## +# +# Project-wide settings + +# Name of the project. +# +# CMake files in this project can refer to the root source directory +# as ${gmock_SOURCE_DIR} and to the root binary directory as +# ${gmock_BINARY_DIR}. +# Language "C" is required for find_package(Threads). +if (CMAKE_VERSION VERSION_LESS 3.0) + project(gmock CXX C) +else() + cmake_policy(SET CMP0048 NEW) + project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) +endif() +cmake_minimum_required(VERSION 2.6.4) + +if (COMMAND set_up_hermetic_build) + set_up_hermetic_build() +endif() + +# Instructs CMake to process Google Test's CMakeLists.txt and add its +# targets to the current scope. We are placing Google Test's binary +# directory in a subdirectory of our own as VC compilation may break +# if they are the same (the default). +add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}") + + +# These commands only run if this is the main project +if(CMAKE_PROJECT_NAME STREQUAL "gmock" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution") + # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to + # make it prominent in the GUI. + option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) +else() + mark_as_advanced(gmock_build_tests) +endif() + +# Although Google Test's CMakeLists.txt calls this function, the +# changes there don't affect the current scope. Therefore we have to +# call it again here. +config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake + +# Adds Google Mock's and Google Test's header directories to the search path. +set(gmock_build_include_dirs + "${gmock_SOURCE_DIR}/include" + "${gmock_SOURCE_DIR}" + "${gtest_SOURCE_DIR}/include" + # This directory is needed to build directly from Google Test sources. + "${gtest_SOURCE_DIR}") +include_directories(${gmock_build_include_dirs}) + +######################################################################## +# +# Defines the gmock & gmock_main libraries. User tests should link +# with one of them. + +# Google Mock libraries. We build them using more strict warnings than what +# are used for other targets, to ensure that Google Mock can be compiled by +# a user aggressive about warnings. +if (MSVC) + cxx_library(gmock + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc) + + cxx_library(gmock_main + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc + src/gmock_main.cc) +else() + cxx_library(gmock "${cxx_strict}" src/gmock-all.cc) + target_link_libraries(gmock PUBLIC gtest) + cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc) + target_link_libraries(gmock_main PUBLIC gmock) +endif() +# If the CMake version supports it, attach header directory information +# to the targets for when we are part of a parent build (ie being pulled +# in via add_subdirectory() rather than being a standalone build). +if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + target_include_directories(gmock SYSTEM INTERFACE + "$" + "$/${CMAKE_INSTALL_INCLUDEDIR}>") + target_include_directories(gmock_main SYSTEM INTERFACE + "$" + "$/${CMAKE_INSTALL_INCLUDEDIR}>") +endif() + +######################################################################## +# +# Install rules +install_project(gmock gmock_main) + +######################################################################## +# +# Google Mock's own tests. +# +# You can skip this section if you aren't interested in testing +# Google Mock itself. +# +# The tests are not built by default. To build them, set the +# gmock_build_tests option to ON. You can do it by running ccmake +# or specifying the -Dgmock_build_tests=ON flag when running cmake. + +if (gmock_build_tests) + # This must be set in the root directory for the tests to be run by + # 'make test' or ctest. + enable_testing() + + if (WIN32) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$/RunTest.ps1" + CONTENT +"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$\" +$env:Path = \"$project_bin;$env:Path\" +& $args") + elseif (MINGW OR CYGWIN) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1" + CONTENT +"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin) +$env:Path = \"$project_bin;$env:Path\" +& $args") + endif() + + if (MINGW OR CYGWIN) + if (CMAKE_VERSION VERSION_LESS "2.8.12") + add_compile_options("-Wa,-mbig-obj") + else() + add_definitions("-Wa,-mbig-obj") + endif() + endif() + + ############################################################ + # C++ tests built with standard compiler flags. + + cxx_test(gmock-actions_test gmock_main) + cxx_test(gmock-cardinalities_test gmock_main) + cxx_test(gmock_ex_test gmock_main) + cxx_test(gmock-function-mocker_test gmock_main) + cxx_test(gmock-generated-actions_test gmock_main) + cxx_test(gmock-generated-function-mockers_test gmock_main) + cxx_test(gmock-generated-matchers_test gmock_main) + cxx_test(gmock-internal-utils_test gmock_main) + cxx_test(gmock-matchers_test gmock_main) + cxx_test(gmock-more-actions_test gmock_main) + cxx_test(gmock-nice-strict_test gmock_main) + cxx_test(gmock-port_test gmock_main) + cxx_test(gmock-spec-builders_test gmock_main) + cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc) + cxx_test(gmock_test gmock_main) + + if (DEFINED GTEST_HAS_PTHREAD) + cxx_test(gmock_stress_test gmock) + endif() + + # gmock_all_test is commented to save time building and running tests. + # Uncomment if necessary. + # cxx_test(gmock_all_test gmock_main) + + ############################################################ + # C++ tests built with non-standard compiler flags. + + if (MSVC) + cxx_library(gmock_main_no_exception "${cxx_no_exception}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + else() + cxx_library(gmock_main_no_exception "${cxx_no_exception}" src/gmock_main.cc) + target_link_libraries(gmock_main_no_exception PUBLIC gmock) + + cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" src/gmock_main.cc) + target_link_libraries(gmock_main_no_rtti PUBLIC gmock) + endif() + cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}" + gmock_main_no_exception test/gmock-more-actions_test.cc) + + cxx_test_with_flags(gmock_no_rtti_test "${cxx_no_rtti}" + gmock_main_no_rtti test/gmock-spec-builders_test.cc) + + cxx_shared_library(shared_gmock_main "${cxx_default}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + # Tests that a binary can be built with Google Mock as a shared library. On + # some system configurations, it may not possible to run the binary without + # knowing more details about the system configurations. We do not try to run + # this binary. To get a more robust shared library coverage, configure with + # -DBUILD_SHARED_LIBS=ON. + cxx_executable_with_flags(shared_gmock_test_ "${cxx_default}" + shared_gmock_main test/gmock-spec-builders_test.cc) + set_target_properties(shared_gmock_test_ + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + + ############################################################ + # Python tests. + + cxx_executable(gmock_leak_test_ test gmock_main) + py_test(gmock_leak_test) + + cxx_executable(gmock_output_test_ test gmock) + py_test(gmock_output_test) +endif() diff --git a/src/test/gtest/googlemock/CONTRIBUTORS b/src/test/gtest/googlemock/CONTRIBUTORS new file mode 100644 index 00000000..6e9ae362 --- /dev/null +++ b/src/test/gtest/googlemock/CONTRIBUTORS @@ -0,0 +1,40 @@ +# This file contains a list of people who've made non-trivial +# contribution to the Google C++ Mocking Framework project. People +# who commit code to the project are encouraged to add their names +# here. Please keep the list sorted by first names. + +Benoit Sigoure +Bogdan Piloca +Chandler Carruth +Dave MacLachlan +David Anderson +Dean Sturtevant +Gene Volovich +Hal Burch +Jeffrey Yasskin +Jim Keller +Joe Walnes +Jon Wray +Keir Mierle +Keith Ray +Kostya Serebryany +Lev Makhlis +Manuel Klimek +Mario Tanev +Mark Paskin +Markus Heule +Matthew Simmons +Mike Bland +Neal Norwitz +Nermin Ozkiranartli +Owen Carlsen +Paneendra Ba +Paul Menage +Piotr Kaminski +Russ Rufer +Sverre Sundsdal +Takeshi Yoshino +Vadim Berman +Vlad Losev +Wolfgang Klier +Zhanyong Wan diff --git a/src/test/gtest/googlemock/LICENSE b/src/test/gtest/googlemock/LICENSE new file mode 100644 index 00000000..1941a11f --- /dev/null +++ b/src/test/gtest/googlemock/LICENSE @@ -0,0 +1,28 @@ +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 COPYRIGHT +OWNER OR CONTRIBUTORS 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. diff --git a/src/test/gtest/googlemock/README.md b/src/test/gtest/googlemock/README.md new file mode 100644 index 00000000..183fdb81 --- /dev/null +++ b/src/test/gtest/googlemock/README.md @@ -0,0 +1,44 @@ +# Googletest Mocking (gMock) Framework + +### Overview + +Google's framework for writing and using C++ mock classes. It can help you +derive better designs of your system and write better tests. + +It is inspired by: + +* [jMock](http://www.jmock.org/), +* [EasyMock](http://www.easymock.org/), and +* [Hamcrest](http://code.google.com/p/hamcrest/), + +and designed with C++'s specifics in mind. + +gMock: + +- provides a declarative syntax for defining mocks, +- can define partial (hybrid) mocks, which are a cross of real and mock + objects, +- handles functions of arbitrary types and overloaded functions, +- comes with a rich set of matchers for validating function arguments, +- uses an intuitive syntax for controlling the behavior of a mock, +- does automatic verification of expectations (no record-and-replay needed), +- allows arbitrary (partial) ordering constraints on function calls to be + expressed, +- lets a user extend it by defining new matchers and actions. +- does not use exceptions, and +- is easy to learn and use. + +Details and examples can be found here: + +* [gMock for Dummies](docs/for_dummies.md) +* [Legacy gMock FAQ](docs/gmock_faq.md) +* [gMock Cookbook](docs/cook_book.md) +* [gMock Cheat Sheet](docs/cheat_sheet.md) + +Please note that code under scripts/generator/ is from the [cppclean +project](http://code.google.com/p/cppclean/) and under the Apache +License, which is different from Google Mock's license. + +Google Mock is a part of +[Google Test C++ testing framework](http://github.com/google/googletest/) and a +subject to the same requirements. diff --git a/src/test/gtest/googlemock/cmake/gmock.pc.in b/src/test/gtest/googlemock/cmake/gmock.pc.in new file mode 100644 index 00000000..08e04547 --- /dev/null +++ b/src/test/gtest/googlemock/cmake/gmock.pc.in @@ -0,0 +1,11 @@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: gmock +Description: GoogleMock (without main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Requires: gtest +Libs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ diff --git a/src/test/gtest/googlemock/cmake/gmock_main.pc.in b/src/test/gtest/googlemock/cmake/gmock_main.pc.in new file mode 100644 index 00000000..b22fe614 --- /dev/null +++ b/src/test/gtest/googlemock/cmake/gmock_main.pc.in @@ -0,0 +1,11 @@ +prefix=${pcfiledir}/../.. +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: gmock_main +Description: GoogleMock (with main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Requires: gmock +Libs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ diff --git a/src/test/gtest/googlemock/docs/cheat_sheet.md b/src/test/gtest/googlemock/docs/cheat_sheet.md new file mode 100644 index 00000000..850963af --- /dev/null +++ b/src/test/gtest/googlemock/docs/cheat_sheet.md @@ -0,0 +1,781 @@ +## gMock Cheat Sheet + + + + + +### Defining a Mock Class + +#### Mocking a Normal Class {#MockClass} + +Given + +```cpp +class Foo { + ... + virtual ~Foo(); + virtual int GetSize() const = 0; + virtual string Describe(const char* name) = 0; + virtual string Describe(int type) = 0; + virtual bool Process(Bar elem, int count) = 0; +}; +``` + +(note that `~Foo()` **must** be virtual) we can define its mock as + +```cpp +#include "gmock/gmock.h" + +class MockFoo : public Foo { + ... + MOCK_METHOD(int, GetSize, (), (const, override)); + MOCK_METHOD(string, Describe, (const char* name), (override)); + MOCK_METHOD(string, Describe, (int type), (override)); + MOCK_METHOD(bool, Process, (Bar elem, int count), (override)); +}; +``` + +To create a "nice" mock, which ignores all uninteresting calls, a "naggy" mock, +which warns on all uninteresting calls, or a "strict" mock, which treats them as +failures: + +```cpp +using ::testing::NiceMock; +using ::testing::NaggyMock; +using ::testing::StrictMock; + +NiceMock nice_foo; // The type is a subclass of MockFoo. +NaggyMock naggy_foo; // The type is a subclass of MockFoo. +StrictMock strict_foo; // The type is a subclass of MockFoo. +``` + +**Note:** A mock object is currently naggy by default. We may make it nice by +default in the future. + +#### Mocking a Class Template {#MockTemplate} + +Class templates can be mocked just like any class. + +To mock + +```cpp +template +class StackInterface { + ... + virtual ~StackInterface(); + virtual int GetSize() const = 0; + virtual void Push(const Elem& x) = 0; +}; +``` + +(note that all member functions that are mocked, including `~StackInterface()` +**must** be virtual). + +```cpp +template +class MockStack : public StackInterface { + ... + MOCK_METHOD(int, GetSize, (), (const, override)); + MOCK_METHOD(void, Push, (const Elem& x), (override)); +}; +``` + +#### Specifying Calling Conventions for Mock Functions + +If your mock function doesn't use the default calling convention, you can +specify it by adding `Calltype(convention)` to `MOCK_METHOD`'s 4th parameter. +For example, + +```cpp + MOCK_METHOD(bool, Foo, (int n), (Calltype(STDMETHODCALLTYPE))); + MOCK_METHOD(int, Bar, (double x, double y), + (const, Calltype(STDMETHODCALLTYPE))); +``` + +where `STDMETHODCALLTYPE` is defined by `` on Windows. + +### Using Mocks in Tests {#UsingMocks} + +The typical work flow is: + +1. Import the gMock names you need to use. All gMock symbols are in the + `testing` namespace unless they are macros or otherwise noted. +2. Create the mock objects. +3. Optionally, set the default actions of the mock objects. +4. Set your expectations on the mock objects (How will they be called? What + will they do?). +5. Exercise code that uses the mock objects; if necessary, check the result + using googletest assertions. +6. When a mock object is destructed, gMock automatically verifies that all + expectations on it have been satisfied. + +Here's an example: + +```cpp +using ::testing::Return; // #1 + +TEST(BarTest, DoesThis) { + MockFoo foo; // #2 + + ON_CALL(foo, GetSize()) // #3 + .WillByDefault(Return(1)); + // ... other default actions ... + + EXPECT_CALL(foo, Describe(5)) // #4 + .Times(3) + .WillRepeatedly(Return("Category 5")); + // ... other expectations ... + + EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 +} // #6 +``` + +### Setting Default Actions {#OnCall} + +gMock has a **built-in default action** for any function that returns `void`, +`bool`, a numeric value, or a pointer. In C++11, it will additionally returns +the default-constructed value, if one exists for the given type. + +To customize the default action for functions with return type *`T`*: + +```cpp +using ::testing::DefaultValue; + +// Sets the default value to be returned. T must be CopyConstructible. +DefaultValue::Set(value); +// Sets a factory. Will be invoked on demand. T must be MoveConstructible. +// T MakeT(); +DefaultValue::SetFactory(&MakeT); +// ... use the mocks ... +// Resets the default value. +DefaultValue::Clear(); +``` + +Example usage: + +```cpp + // Sets the default action for return type std::unique_ptr to + // creating a new Buzz every time. + DefaultValue>::SetFactory( + [] { return MakeUnique(AccessLevel::kInternal); }); + + // When this fires, the default action of MakeBuzz() will run, which + // will return a new Buzz object. + EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber()); + + auto buzz1 = mock_buzzer_.MakeBuzz("hello"); + auto buzz2 = mock_buzzer_.MakeBuzz("hello"); + EXPECT_NE(nullptr, buzz1); + EXPECT_NE(nullptr, buzz2); + EXPECT_NE(buzz1, buzz2); + + // Resets the default action for return type std::unique_ptr, + // to avoid interfere with other tests. + DefaultValue>::Clear(); +``` + +To customize the default action for a particular method of a specific mock +object, use `ON_CALL()`. `ON_CALL()` has a similar syntax to `EXPECT_CALL()`, +but it is used for setting default behaviors (when you do not require that the +mock method is called). See [here](cook_book.md#UseOnCall) for a more detailed +discussion. + +```cpp +ON_CALL(mock-object, method(matchers)) + .With(multi-argument-matcher) ? + .WillByDefault(action); +``` + +### Setting Expectations {#ExpectCall} + +`EXPECT_CALL()` sets **expectations** on a mock method (How will it be called? +What will it do?): + +```cpp +EXPECT_CALL(mock-object, method (matchers)?) + .With(multi-argument-matcher) ? + .Times(cardinality) ? + .InSequence(sequences) * + .After(expectations) * + .WillOnce(action) * + .WillRepeatedly(action) ? + .RetiresOnSaturation(); ? +``` + +For each item above, `?` means it can be used at most once, while `*` means it +can be used any number of times. + +In order to pass, `EXPECT_CALL` must be used before the calls are actually made. + +The `(matchers)` is a comma-separated list of matchers that correspond to each +of the arguments of `method`, and sets the expectation only for calls of +`method` that matches all of the matchers. + +If `(matchers)` is omitted, the expectation is the same as if the matchers were +set to anything matchers (for example, `(_, _, _, _)` for a four-arg method). + +If `Times()` is omitted, the cardinality is assumed to be: + +* `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`; +* `Times(n)` when there are `n` `WillOnce()`s but no `WillRepeatedly()`, where + `n` >= 1; or +* `Times(AtLeast(n))` when there are `n` `WillOnce()`s and a + `WillRepeatedly()`, where `n` >= 0. + +A method with no `EXPECT_CALL()` is free to be invoked *any number of times*, +and the default action will be taken each time. + +### Matchers {#MatcherList} + + + +A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or +`EXPECT_CALL()`, or use it to validate a value directly using two macros: + + +| Macro | Description | +| :----------------------------------- | :------------------------------------ | +| `EXPECT_THAT(actual_value, matcher)` | Asserts that `actual_value` matches `matcher`. | +| `ASSERT_THAT(actual_value, matcher)` | The same as `EXPECT_THAT(actual_value, matcher)`, except that it generates a **fatal** failure. | + + +Built-in matchers (where `argument` is the function argument, e.g. +`actual_value` in the example above, or when used in the context of +`EXPECT_CALL(mock_object, method(matchers))`, the arguments of `method`) are +divided into several categories: + +#### Wildcard + +Matcher | Description +:-------------------------- | :----------------------------------------------- +`_` | `argument` can be any value of the correct type. +`A()` or `An()` | `argument` can be any value of type `type`. + +#### Generic Comparison + + +| Matcher | Description | +| :--------------------- | :-------------------------------------------------- | +| `Eq(value)` or `value` | `argument == value` | +| `Ge(value)` | `argument >= value` | +| `Gt(value)` | `argument > value` | +| `Le(value)` | `argument <= value` | +| `Lt(value)` | `argument < value` | +| `Ne(value)` | `argument != value` | +| `IsFalse()` | `argument` evaluates to `false` in a Boolean context. | +| `IsTrue()` | `argument` evaluates to `true` in a Boolean context. | +| `IsNull()` | `argument` is a `NULL` pointer (raw or smart). | +| `NotNull()` | `argument` is a non-null pointer (raw or smart). | +| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. | +| `VariantWith(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. | +| `Ref(variable)` | `argument` is a reference to `variable`. | +| `TypedEq(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. | + + +Except `Ref()`, these matchers make a *copy* of `value` in case it's modified or +destructed later. If the compiler complains that `value` doesn't have a public +copy constructor, try wrap it in `ByRef()`, e.g. +`Eq(ByRef(non_copyable_value))`. If you do that, make sure `non_copyable_value` +is not changed afterwards, or the meaning of your matcher will be changed. + +#### Floating-Point Matchers {#FpMatchers} + + +| Matcher | Description | +| :------------------------------- | :--------------------------------- | +| `DoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal. | +| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. | +| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. | +| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. | + + +The above matchers use ULP-based comparison (the same as used in googletest). +They automatically pick a reasonable error bound based on the absolute value of +the expected value. `DoubleEq()` and `FloatEq()` conform to the IEEE standard, +which requires comparing two NaNs for equality to return false. The +`NanSensitive*` version instead treats two NaNs as equal, which is often what a +user wants. + + +| Matcher | Description | +| :------------------------------------------------ | :----------------------- | +| `DoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | +| `FloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | +| `NanSensitiveDoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. | +| `NanSensitiveFloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. | + + +#### String Matchers + +The `argument` can be either a C string or a C++ string object: + + +| Matcher | Description | +| :---------------------- | :------------------------------------------------- | +| `ContainsRegex(string)` | `argument` matches the given regular expression. | +| `EndsWith(suffix)` | `argument` ends with string `suffix`. | +| `HasSubstr(string)` | `argument` contains `string` as a sub-string. | +| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. | +| `StartsWith(prefix)` | `argument` starts with string `prefix`. | +| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. | +| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. | +| `StrEq(string)` | `argument` is equal to `string`. | +| `StrNe(string)` | `argument` is not equal to `string`. | + + +`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They +use the regular expression syntax defined +[here](../../googletest/docs/advanced.md#regular-expression-syntax). +`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide strings as +well. + +#### Container Matchers + +Most STL-style containers support `==`, so you can use `Eq(expected_container)` +or simply `expected_container` to match a container exactly. If you want to +write the elements in-line, match them more flexibly, or get more informative +messages, you can use: + + +| Matcher | Description | +| :---------------------------------------- | :------------------------------- | +| `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. | +| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | +| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | +| `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. | +| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. | +| `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `IsEmpty()` | `argument` is an empty container (`container.empty()`). | +| `IsSubsetOf({e0, e1, ..., en})`, `IsSubsetOf(a_container)`, `IsSubsetOf(begin, end)`, `IsSubsetOf(array)`, or `IsSubsetOf(array, count)` | `argument` matches `UnorderedElementsAre(x0, x1, ..., xk)` for some subset `{x0, x1, ..., xk}` of the expected matchers. | +| `IsSupersetOf({e0, e1, ..., en})`, `IsSupersetOf(a_container)`, `IsSupersetOf(begin, end)`, `IsSupersetOf(array)`, or `IsSupersetOf(array, count)` | Some subset of `argument` matches `UnorderedElementsAre(`expected matchers`)`. | +| `Pointwise(m, container)`, `Pointwise(m, {e0, e1, ..., en})` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. See more detail below. | +| `SizeIs(m)` | `argument` is a container whose size matches `m`. E.g. `SizeIs(2)` or `SizeIs(Lt(2))`. | +| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, and under *some* permutation of the elements, each element matches an `ei` (for a different `i`), which can be a value or a matcher. | +| `UnorderedElementsAreArray({e0, e1, ..., en})`, `UnorderedElementsAreArray(a_container)`, `UnorderedElementsAreArray(begin, end)`, `UnorderedElementsAreArray(array)`, or `UnorderedElementsAreArray(array, count)` | The same as `UnorderedElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `UnorderedPointwise(m, container)`, `UnorderedPointwise(m, {e0, e1, ..., en})` | Like `Pointwise(m, container)`, but ignores the order of elements. | +| `WhenSorted(m)` | When `argument` is sorted using the `<` operator, it matches container matcher `m`. E.g. `WhenSorted(ElementsAre(1, 2, 3))` verifies that `argument` contains elements 1, 2, and 3, ignoring order. | +| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except that the given comparator instead of `<` is used to sort `argument`. E.g. `WhenSortedBy(std::greater(), ElementsAre(3, 2, 1))`. | + + +**Notes:** + +* These matchers can also match: + 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), + and + 2. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, + int len)` -- see [Multi-argument Matchers](#MultiArgMatchers)). +* The array being matched may be multi-dimensional (i.e. its elements can be + arrays). +* `m` in `Pointwise(m, ...)` should be a matcher for `::std::tuple` + where `T` and `U` are the element type of the actual container and the + expected container, respectively. For example, to compare two `Foo` + containers where `Foo` doesn't support `operator==`, one might write: + + ```cpp + using ::std::get; + MATCHER(FooEq, "") { + return std::get<0>(arg).Equals(std::get<1>(arg)); + } + ... + EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos)); + ``` + +#### Member Matchers + + +| Matcher | Description | +| :------------------------------ | :----------------------------------------- | +| `Field(&class::field, m)` | `argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. | +| `Key(e)` | `argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`. | +| `Pair(m1, m2)` | `argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | +| `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. | + + +#### Matching the Result of a Function, Functor, or Callback + + +| Matcher | Description | +| :--------------- | :------------------------------------------------ | +| `ResultOf(f, m)` | `f(argument)` matches matcher `m`, where `f` is a function or functor. | + + +#### Pointer Matchers + + +| Matcher | Description | +| :------------------------ | :---------------------------------------------- | +| `Pointee(m)` | `argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`. | +| `WhenDynamicCastTo(m)` | when `argument` is passed through `dynamic_cast()`, it matches matcher `m`. | + + + + + + +#### Multi-argument Matchers {#MultiArgMatchers} + +Technically, all matchers match a *single* value. A "multi-argument" matcher is +just one that matches a *tuple*. The following matchers can be used to match a +tuple `(x, y)`: + +Matcher | Description +:------ | :---------- +`Eq()` | `x == y` +`Ge()` | `x >= y` +`Gt()` | `x > y` +`Le()` | `x <= y` +`Lt()` | `x < y` +`Ne()` | `x != y` + +You can use the following selectors to pick a subset of the arguments (or +reorder them) to participate in the matching: + + +| Matcher | Description | +| :------------------------- | :---------------------------------------------- | +| `AllArgs(m)` | Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`. | +| `Args(m)` | The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`. | + + +#### Composite Matchers + +You can make a matcher from one or more other matchers: + + +| Matcher | Description | +| :------------------------------- | :-------------------------------------- | +| `AllOf(m1, m2, ..., mn)` | `argument` matches all of the matchers `m1` to `mn`. | +| `AllOfArray({m0, m1, ..., mn})`, `AllOfArray(a_container)`, `AllOfArray(begin, end)`, `AllOfArray(array)`, or `AllOfArray(array, count)` | The same as `AllOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. | +| `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `Not(m)` | `argument` doesn't match matcher `m`. | + + + + +#### Adapters for Matchers + + +| Matcher | Description | +| :---------------------- | :------------------------------------ | +| `MatcherCast(m)` | casts matcher `m` to type `Matcher`. | +| `SafeMatcherCast(m)` | [safely casts](cook_book.md#casting-matchers) matcher `m` to type `Matcher`. | +| `Truly(predicate)` | `predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor. | + + +`AddressSatisfies(callback)` and `Truly(callback)` take ownership of `callback`, +which must be a permanent callback. + +#### Using Matchers as Predicates {#MatchersAsPredicatesCheat} + + +| Matcher | Description | +| :---------------------------- | :------------------------------------------ | +| `Matches(m)(value)` | evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor. | +| `ExplainMatchResult(m, value, result_listener)` | evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. | +| `Value(value, m)` | evaluates to `true` if `value` matches `m`. | + + +#### Defining Matchers + + +| Matcher | Description | +| :----------------------------------- | :------------------------------------ | +| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | +| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a macher `IsDivisibleBy(n)` to match a number divisible by `n`. | +| `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | + + +**Notes:** + +1. The `MATCHER*` macros cannot be used inside a function or class. +2. The matcher body must be *purely functional* (i.e. it cannot have any side + effect, and the result must not depend on anything other than the value + being matched and the matcher parameters). +3. You can use `PrintToString(x)` to convert a value `x` of any type to a + string. + +### Actions {#ActionList} + +**Actions** specify what a mock function should do when invoked. + +#### Returning a Value + + +| | | +| :-------------------------- | :-------------------------------------------- | +| `Return()` | Return from a `void` mock function. | +| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type at the time the expectation is set, not when the action is executed. | +| `ReturnArg()` | Return the `N`-th (0-based) argument. | +| `ReturnNew(a1, ..., ak)` | Return `new T(a1, ..., ak)`; a different object is created each time. | +| `ReturnNull()` | Return a null pointer. | +| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. | +| `ReturnRef(variable)` | Return a reference to `variable`. | +| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. | + + +#### Side Effects + + +| | | +| :--------------------------------- | :-------------------------------------- | +| `Assign(&variable, value)` | Assign `value` to variable. | +| `DeleteArg()` | Delete the `N`-th (0-based) argument, which must be a pointer. | +| `SaveArg(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. | +| `SaveArgPointee(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. | +| `SetArgReferee(value)` | Assign value to the variable referenced by the `N`-th (0-based) argument. | +| `SetArgPointee(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. | +| `SetArgumentPointee(value)` | Same as `SetArgPointee(value)`. Deprecated. Will be removed in v1.7.0. | +| `SetArrayArgument(first, last)` | Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range. | +| `SetErrnoAndReturn(error, value)` | Set `errno` to `error` and return `value`. | +| `Throw(exception)` | Throws the given exception, which can be any copyable value. Available since v1.1.0. | + + +#### Using a Function, Functor, or Lambda as an Action + +In the following, by "callable" we mean a free function, `std::function`, +functor, or lambda. + + +| | | +| :---------------------------------- | :------------------------------------- | +| `f` | Invoke f with the arguments passed to the mock function, where f is a callable. | +| `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. | +| `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. | +| `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | +| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. | +| `InvokeArgument(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. | + + +The return value of the invoked function is used as the return value of the +action. + +When defining a callable to be used with `Invoke*()`, you can declare any unused +parameters as `Unused`: + +```cpp +using ::testing::Invoke; +double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } +... +EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); +``` + +`Invoke(callback)` and `InvokeWithoutArgs(callback)` take ownership of +`callback`, which must be permanent. The type of `callback` must be a base +callback type instead of a derived one, e.g. + +```cpp + BlockingClosure* done = new BlockingClosure; + ... Invoke(done) ...; // This won't compile! + + Closure* done2 = new BlockingClosure; + ... Invoke(done2) ...; // This works. +``` + +In `InvokeArgument(...)`, if an argument needs to be passed by reference, +wrap it inside `ByRef()`. For example, + +```cpp +using ::testing::ByRef; +using ::testing::InvokeArgument; +... +InvokeArgument<2>(5, string("Hi"), ByRef(foo)) +``` + +calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by +value, and `foo` by reference. + +#### Default Action + + +| Matcher | Description | +| :------------ | :----------------------------------------------------- | +| `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). | + + +**Note:** due to technical reasons, `DoDefault()` cannot be used inside a +composite action - trying to do so will result in a run-time error. + + + +#### Composite Actions + + +| | | +| :----------------------------- | :------------------------------------------ | +| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. | +| `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. | +| `WithArg(a)` | Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. | +| `WithArgs(a)` | Pass the selected (0-based) arguments of the mock function to action `a` and perform it. | +| `WithoutArgs(a)` | Perform action `a` without any arguments. | + + +#### Defining Actions + + + + + + + +
      `struct SumAction {`
      +  `template `
      +  `T operator()(T x, Ty) { return x + y; }`
      + `};` +
      Defines a generic functor that can be used as an action summing its + arguments.
      + + +| | | +| :--------------------------------- | :-------------------------------------- | +| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | +| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | +| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. | + + +The `ACTION*` macros cannot be used inside a function or class. + +### Cardinalities {#CardinalityList} + +These are used in `Times()` to specify how many times a mock function will be +called: + + +| | | +| :---------------- | :----------------------------------------------------- | +| `AnyNumber()` | The function can be called any number of times. | +| `AtLeast(n)` | The call is expected at least `n` times. | +| `AtMost(n)` | The call is expected at most `n` times. | +| `Between(m, n)` | The call is expected between `m` and `n` (inclusive) times. | +| `Exactly(n) or n` | The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0. | + + +### Expectation Order + +By default, the expectations can be matched in *any* order. If some or all +expectations must be matched in a given order, there are two ways to specify it. +They can be used either independently or together. + +#### The After Clause {#AfterClause} + +```cpp +using ::testing::Expectation; +... +Expectation init_x = EXPECT_CALL(foo, InitX()); +Expectation init_y = EXPECT_CALL(foo, InitY()); +EXPECT_CALL(foo, Bar()) + .After(init_x, init_y); +``` + +says that `Bar()` can be called only after both `InitX()` and `InitY()` have +been called. + +If you don't know how many pre-requisites an expectation has when you write it, +you can use an `ExpectationSet` to collect them: + +```cpp +using ::testing::ExpectationSet; +... +ExpectationSet all_inits; +for (int i = 0; i < element_count; i++) { + all_inits += EXPECT_CALL(foo, InitElement(i)); +} +EXPECT_CALL(foo, Bar()) + .After(all_inits); +``` + +says that `Bar()` can be called only after all elements have been initialized +(but we don't care about which elements get initialized before the others). + +Modifying an `ExpectationSet` after using it in an `.After()` doesn't affect the +meaning of the `.After()`. + +#### Sequences {#UsingSequences} + +When you have a long chain of sequential expectations, it's easier to specify +the order using **sequences**, which don't require you to given each expectation +in the chain a different name. *All expected calls* in the same sequence must +occur in the order they are specified. + +```cpp +using ::testing::Return; +using ::testing::Sequence; +Sequence s1, s2; +... +EXPECT_CALL(foo, Reset()) + .InSequence(s1, s2) + .WillOnce(Return(true)); +EXPECT_CALL(foo, GetSize()) + .InSequence(s1) + .WillOnce(Return(1)); +EXPECT_CALL(foo, Describe(A())) + .InSequence(s2) + .WillOnce(Return("dummy")); +``` + +says that `Reset()` must be called before *both* `GetSize()` *and* `Describe()`, +and the latter two can occur in any order. + +To put many expectations in a sequence conveniently: + +```cpp +using ::testing::InSequence; +{ + InSequence seq; + + EXPECT_CALL(...)...; + EXPECT_CALL(...)...; + ... + EXPECT_CALL(...)...; +} +``` + +says that all expected calls in the scope of `seq` must occur in strict order. +The name `seq` is irrelevant. + +### Verifying and Resetting a Mock + +gMock will verify the expectations on a mock object when it is destructed, or +you can do it earlier: + +```cpp +using ::testing::Mock; +... +// Verifies and removes the expectations on mock_obj; +// returns true if and only if successful. +Mock::VerifyAndClearExpectations(&mock_obj); +... +// Verifies and removes the expectations on mock_obj; +// also removes the default actions set by ON_CALL(); +// returns true if and only if successful. +Mock::VerifyAndClear(&mock_obj); +``` + +You can also tell gMock that a mock object can be leaked and doesn't need to be +verified: + +```cpp +Mock::AllowLeak(&mock_obj); +``` + +### Mock Classes + +gMock defines a convenient mock class template + +```cpp +class MockFunction { + public: + MOCK_METHOD(R, Call, (A1, ..., An)); +}; +``` + +See this [recipe](cook_book.md#using-check-points) for one application of it. + +### Flags + + +| Flag | Description | +| :----------------------------- | :---------------------------------------- | +| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. | +| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. | + diff --git a/src/test/gtest/googlemock/docs/cook_book.md b/src/test/gtest/googlemock/docs/cook_book.md new file mode 100644 index 00000000..ea55ab35 --- /dev/null +++ b/src/test/gtest/googlemock/docs/cook_book.md @@ -0,0 +1,4270 @@ +# gMock Cookbook + + + +You can find recipes for using gMock here. If you haven't yet, please read +[this](for_dummies.md) first to make sure you understand the basics. + +**Note:** gMock lives in the `testing` name space. For readability, it is +recommended to write `using ::testing::Foo;` once in your file before using the +name `Foo` defined by gMock. We omit such `using` statements in this section for +brevity, but you should do it in your own code. + +## Creating Mock Classes + +Mock classes are defined as normal classes, using the `MOCK_METHOD` macro to +generate mocked methods. The macro gets 3 or 4 parameters: + +```cpp +class MyMock { + public: + MOCK_METHOD(ReturnType, MethodName, (Args...)); + MOCK_METHOD(ReturnType, MethodName, (Args...), (Specs...)); +}; +``` + +The first 3 parameters are simply the method declaration, split into 3 parts. +The 4th parameter accepts a closed list of qualifiers, which affect the +generated method: + +* **`const`** - Makes the mocked method a `const` method. Required if + overriding a `const` method. +* **`override`** - Marks the method with `override`. Recommended if overriding + a `virtual` method. +* **`noexcept`** - Marks the method with `noexcept`. Required if overriding a + `noexcept` method. +* **`Calltype(...)`** - Sets the call type for the method (e.g. to + `STDMETHODCALLTYPE`), useful in Windows. + +### Dealing with unprotected commas + +Unprotected commas, i.e. commas which are not surrounded by parentheses, prevent +`MOCK_METHOD` from parsing its arguments correctly: + +```cpp {.bad} +class MockFoo { + public: + MOCK_METHOD(std::pair, GetPair, ()); // Won't compile! + MOCK_METHOD(bool, CheckMap, (std::map, bool)); // Won't compile! +}; +``` + +Solution 1 - wrap with parentheses: + +```cpp {.good} +class MockFoo { + public: + MOCK_METHOD((std::pair), GetPair, ()); + MOCK_METHOD(bool, CheckMap, ((std::map), bool)); +}; +``` + +Note that wrapping a return or argument type with parentheses is, in general, +invalid C++. `MOCK_METHOD` removes the parentheses. + +Solution 2 - define an alias: + +```cpp {.good} +class MockFoo { + public: + using BoolAndInt = std::pair; + MOCK_METHOD(BoolAndInt, GetPair, ()); + using MapIntDouble = std::map; + MOCK_METHOD(bool, CheckMap, (MapIntDouble, bool)); +}; +``` + +### Mocking Private or Protected Methods + +You must always put a mock method definition (`MOCK_METHOD`) in a `public:` +section of the mock class, regardless of the method being mocked being `public`, +`protected`, or `private` in the base class. This allows `ON_CALL` and +`EXPECT_CALL` to reference the mock function from outside of the mock class. +(Yes, C++ allows a subclass to change the access level of a virtual function in +the base class.) Example: + +```cpp +class Foo { + public: + ... + virtual bool Transform(Gadget* g) = 0; + + protected: + virtual void Resume(); + + private: + virtual int GetTimeOut(); +}; + +class MockFoo : public Foo { + public: + ... + MOCK_METHOD(bool, Transform, (Gadget* g), (override)); + + // The following must be in the public section, even though the + // methods are protected or private in the base class. + MOCK_METHOD(void, Resume, (), (override)); + MOCK_METHOD(int, GetTimeOut, (), (override)); +}; +``` + +### Mocking Overloaded Methods + +You can mock overloaded functions as usual. No special attention is required: + +```cpp +class Foo { + ... + + // Must be virtual as we'll inherit from Foo. + virtual ~Foo(); + + // Overloaded on the types and/or numbers of arguments. + virtual int Add(Element x); + virtual int Add(int times, Element x); + + // Overloaded on the const-ness of this object. + virtual Bar& GetBar(); + virtual const Bar& GetBar() const; +}; + +class MockFoo : public Foo { + ... + MOCK_METHOD(int, Add, (Element x), (override)); + MOCK_METHOD(int, Add, (int times, Element x), (override)); + + MOCK_METHOD(Bar&, GetBar, (), (override)); + MOCK_METHOD(const Bar&, GetBar, (), (const, override)); +}; +``` + +**Note:** if you don't mock all versions of the overloaded method, the compiler +will give you a warning about some methods in the base class being hidden. To +fix that, use `using` to bring them in scope: + +```cpp +class MockFoo : public Foo { + ... + using Foo::Add; + MOCK_METHOD(int, Add, (Element x), (override)); + // We don't want to mock int Add(int times, Element x); + ... +}; +``` + +### Mocking Class Templates + +You can mock class templates just like any class. + +```cpp +template +class StackInterface { + ... + // Must be virtual as we'll inherit from StackInterface. + virtual ~StackInterface(); + + virtual int GetSize() const = 0; + virtual void Push(const Elem& x) = 0; +}; + +template +class MockStack : public StackInterface { + ... + MOCK_METHOD(int, GetSize, (), (override)); + MOCK_METHOD(void, Push, (const Elem& x), (override)); +}; +``` + +### Mocking Non-virtual Methods {#MockingNonVirtualMethods} + +gMock can mock non-virtual functions to be used in Hi-perf dependency +injection. + +In this case, instead of sharing a common base class with the real class, your +mock class will be *unrelated* to the real class, but contain methods with the +same signatures. The syntax for mocking non-virtual methods is the *same* as +mocking virtual methods (just don't add `override`): + +```cpp +// A simple packet stream class. None of its members is virtual. +class ConcretePacketStream { + public: + void AppendPacket(Packet* new_packet); + const Packet* GetPacket(size_t packet_number) const; + size_t NumberOfPackets() const; + ... +}; + +// A mock packet stream class. It inherits from no other, but defines +// GetPacket() and NumberOfPackets(). +class MockPacketStream { + public: + MOCK_METHOD(const Packet*, GetPacket, (size_t packet_number), (const)); + MOCK_METHOD(size_t, NumberOfPackets, (), (const)); + ... +}; +``` + +Note that the mock class doesn't define `AppendPacket()`, unlike the real class. +That's fine as long as the test doesn't need to call it. + +Next, you need a way to say that you want to use `ConcretePacketStream` in +production code, and use `MockPacketStream` in tests. Since the functions are +not virtual and the two classes are unrelated, you must specify your choice at +*compile time* (as opposed to run time). + +One way to do it is to templatize your code that needs to use a packet stream. +More specifically, you will give your code a template type argument for the type +of the packet stream. In production, you will instantiate your template with +`ConcretePacketStream` as the type argument. In tests, you will instantiate the +same template with `MockPacketStream`. For example, you may write: + +```cpp +template +void CreateConnection(PacketStream* stream) { ... } + +template +class PacketReader { + public: + void ReadPackets(PacketStream* stream, size_t packet_num); +}; +``` + +Then you can use `CreateConnection()` and +`PacketReader` in production code, and use +`CreateConnection()` and `PacketReader` in +tests. + +```cpp + MockPacketStream mock_stream; + EXPECT_CALL(mock_stream, ...)...; + .. set more expectations on mock_stream ... + PacketReader reader(&mock_stream); + ... exercise reader ... +``` + +### Mocking Free Functions + +It's possible to use gMock to mock a free function (i.e. a C-style function or a +static method). You just need to rewrite your code to use an interface (abstract +class). + +Instead of calling a free function (say, `OpenFile`) directly, introduce an +interface for it and have a concrete subclass that calls the free function: + +```cpp +class FileInterface { + public: + ... + virtual bool Open(const char* path, const char* mode) = 0; +}; + +class File : public FileInterface { + public: + ... + virtual bool Open(const char* path, const char* mode) { + return OpenFile(path, mode); + } +}; +``` + +Your code should talk to `FileInterface` to open a file. Now it's easy to mock +out the function. + +This may seem like a lot of hassle, but in practice you often have multiple +related functions that you can put in the same interface, so the per-function +syntactic overhead will be much lower. + +If you are concerned about the performance overhead incurred by virtual +functions, and profiling confirms your concern, you can combine this with the +recipe for [mocking non-virtual methods](#MockingNonVirtualMethods). + +### Old-Style `MOCK_METHODn` Macros + +Before the generic `MOCK_METHOD` macro was introduced, mocks where created using +a family of macros collectively called `MOCK_METHODn`. These macros are still +supported, though migration to the new `MOCK_METHOD` is recommended. + +The macros in the `MOCK_METHODn` family differ from `MOCK_METHOD`: + +* The general structure is `MOCK_METHODn(MethodName, ReturnType(Args))`, + instead of `MOCK_METHOD(ReturnType, MethodName, (Args))`. +* The number `n` must equal the number of arguments. +* When mocking a const method, one must use `MOCK_CONST_METHODn`. +* When mocking a class template, the macro name must be suffixed with `_T`. +* In order to specify the call type, the macro name must be suffixed with + `_WITH_CALLTYPE`, and the call type is the first macro argument. + +Old macros and their new equivalents: + +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      Simple
      Old `MOCK_METHOD1(Foo, bool(int))`
      New `MOCK_METHOD(bool, Foo, (int))`
      Const Method
      Old +`MOCK_CONST_METHOD1(Foo, bool(int))`
      New +`MOCK_METHOD(bool, Foo, (int), (const))`
      Method in a Class Template
      Old `MOCK_METHOD1_T(Foo, bool(int))`
      New +`MOCK_METHOD(bool, Foo, (int))`
      Const Method in a Class Template
      Old + `MOCK_CONST_METHOD1_T(Foo, bool(int))`
      New + `MOCK_METHOD(bool, Foo, (int), (const))`
      Method with Call Type
      Old +`MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))`
      New `MOCK_METHOD(bool, Foo, (int), +(Calltype(STDMETHODCALLTYPE)))`
      Const Method with Call Type
      Old `MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))`
      New `MOCK_METHOD(bool, Foo, (int), (const, +Calltype(STDMETHODCALLTYPE)))`
      Method with Call Type in a Class Template
      Old `MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, +bool(int))`
      New `MOCK_METHOD(bool, Foo, (int), +(Calltype(STDMETHODCALLTYPE)))`
      Const Method with Call Type in a Class Template
      Old `MOCK_CONST_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, +Foo, bool(int))`
      New `MOCK_METHOD(bool, Foo, +(int), (const, Calltype(STDMETHODCALLTYPE)))`
      + +### The Nice, the Strict, and the Naggy {#NiceStrictNaggy} + +If a mock method has no `EXPECT_CALL` spec but is called, we say that it's an +"uninteresting call", and the default action (which can be specified using +`ON_CALL()`) of the method will be taken. Currently, an uninteresting call will +also by default cause gMock to print a warning. (In the future, we might remove +this warning by default.) + +However, sometimes you may want to ignore these uninteresting calls, and +sometimes you may want to treat them as errors. gMock lets you make the decision +on a per-mock-object basis. + +Suppose your test uses a mock class `MockFoo`: + +```cpp +TEST(...) { + MockFoo mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +If a method of `mock_foo` other than `DoThis()` is called, you will get a +warning. However, if you rewrite your test to use `NiceMock` instead, +you can suppress the warning: + +```cpp +using ::testing::NiceMock; + +TEST(...) { + NiceMock mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +`NiceMock` is a subclass of `MockFoo`, so it can be used wherever +`MockFoo` is accepted. + +It also works if `MockFoo`'s constructor takes some arguments, as +`NiceMock` "inherits" `MockFoo`'s constructors: + +```cpp +using ::testing::NiceMock; + +TEST(...) { + NiceMock mock_foo(5, "hi"); // Calls MockFoo(5, "hi"). + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +The usage of `StrictMock` is similar, except that it makes all uninteresting +calls failures: + +```cpp +using ::testing::StrictMock; + +TEST(...) { + StrictMock mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... + + // The test will fail if a method of mock_foo other than DoThis() + // is called. +} +``` + +NOTE: `NiceMock` and `StrictMock` only affects *uninteresting* calls (calls of +*methods* with no expectations); they do not affect *unexpected* calls (calls of +methods with expectations, but they don't match). See +[Understanding Uninteresting vs Unexpected Calls](#uninteresting-vs-unexpected). + +There are some caveats though (I dislike them just as much as the next guy, but +sadly they are side effects of C++'s limitations): + +1. `NiceMock` and `StrictMock` only work for mock methods + defined using the `MOCK_METHOD` macro **directly** in the `MockFoo` class. + If a mock method is defined in a **base class** of `MockFoo`, the "nice" or + "strict" modifier may not affect it, depending on the compiler. In + particular, nesting `NiceMock` and `StrictMock` (e.g. + `NiceMock >`) is **not** supported. +2. `NiceMock` and `StrictMock` may not work correctly if the + destructor of `MockFoo` is not virtual. We would like to fix this, but it + requires cleaning up existing tests. http://b/28934720 tracks the issue. +3. During the constructor or destructor of `MockFoo`, the mock object is *not* + nice or strict. This may cause surprises if the constructor or destructor + calls a mock method on `this` object. (This behavior, however, is consistent + with C++'s general rule: if a constructor or destructor calls a virtual + method of `this` object, that method is treated as non-virtual. In other + words, to the base class's constructor or destructor, `this` object behaves + like an instance of the base class, not the derived class. This rule is + required for safety. Otherwise a base constructor may use members of a + derived class before they are initialized, or a base destructor may use + members of a derived class after they have been destroyed.) + +Finally, you should be **very cautious** about when to use naggy or strict +mocks, as they tend to make tests more brittle and harder to maintain. When you +refactor your code without changing its externally visible behavior, ideally you +shouldn't need to update any tests. If your code interacts with a naggy mock, +however, you may start to get spammed with warnings as the result of your +change. Worse, if your code interacts with a strict mock, your tests may start +to fail and you'll be forced to fix them. Our general recommendation is to use +nice mocks (not yet the default) most of the time, use naggy mocks (the current +default) when developing or debugging tests, and use strict mocks only as the +last resort. + +### Simplifying the Interface without Breaking Existing Code {#SimplerInterfaces} + +Sometimes a method has a long list of arguments that is mostly uninteresting. +For example: + +```cpp +class LogSink { + public: + ... + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const struct tm* tm_time, + const char* message, size_t message_len) = 0; +}; +``` + +This method's argument list is lengthy and hard to work with (the `message` +argument is not even 0-terminated). If we mock it as is, using the mock will be +awkward. If, however, we try to simplify this interface, we'll need to fix all +clients depending on it, which is often infeasible. + +The trick is to redispatch the method in the mock class: + +```cpp +class ScopedMockLog : public LogSink { + public: + ... + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, const tm* tm_time, + const char* message, size_t message_len) { + // We are only interested in the log severity, full file name, and + // log message. + Log(severity, full_filename, std::string(message, message_len)); + } + + // Implements the mock method: + // + // void Log(LogSeverity severity, + // const string& file_path, + // const string& message); + MOCK_METHOD(void, Log, + (LogSeverity severity, const string& file_path, + const string& message)); +}; +``` + +By defining a new mock method with a trimmed argument list, we make the mock +class more user-friendly. + +This technique may also be applied to make overloaded methods more amenable to +mocking. For example, when overloads have been used to implement default +arguments: + +```cpp +class MockTurtleFactory : public TurtleFactory { + public: + Turtle* MakeTurtle(int length, int weight) override { ... } + Turtle* MakeTurtle(int length, int weight, int speed) override { ... } + + // the above methods delegate to this one: + MOCK_METHOD(Turtle*, DoMakeTurtle, ()); +}; +``` + +This allows tests that don't care which overload was invoked to avoid specifying +argument matchers: + +```cpp +ON_CALL(factory, DoMakeTurtle) + .WillByDefault(MakeMockTurtle()); +``` + +### Alternative to Mocking Concrete Classes + +Often you may find yourself using classes that don't implement interfaces. In +order to test your code that uses such a class (let's call it `Concrete`), you +may be tempted to make the methods of `Concrete` virtual and then mock it. + +Try not to do that. + +Making a non-virtual function virtual is a big decision. It creates an extension +point where subclasses can tweak your class' behavior. This weakens your control +on the class because now it's harder to maintain the class invariants. You +should make a function virtual only when there is a valid reason for a subclass +to override it. + +Mocking concrete classes directly is problematic as it creates a tight coupling +between the class and the tests - any small change in the class may invalidate +your tests and make test maintenance a pain. + +To avoid such problems, many programmers have been practicing "coding to +interfaces": instead of talking to the `Concrete` class, your code would define +an interface and talk to it. Then you implement that interface as an adaptor on +top of `Concrete`. In tests, you can easily mock that interface to observe how +your code is doing. + +This technique incurs some overhead: + +* You pay the cost of virtual function calls (usually not a problem). +* There is more abstraction for the programmers to learn. + +However, it can also bring significant benefits in addition to better +testability: + +* `Concrete`'s API may not fit your problem domain very well, as you may not + be the only client it tries to serve. By designing your own interface, you + have a chance to tailor it to your need - you may add higher-level + functionalities, rename stuff, etc instead of just trimming the class. This + allows you to write your code (user of the interface) in a more natural way, + which means it will be more readable, more maintainable, and you'll be more + productive. +* If `Concrete`'s implementation ever has to change, you don't have to rewrite + everywhere it is used. Instead, you can absorb the change in your + implementation of the interface, and your other code and tests will be + insulated from this change. + +Some people worry that if everyone is practicing this technique, they will end +up writing lots of redundant code. This concern is totally understandable. +However, there are two reasons why it may not be the case: + +* Different projects may need to use `Concrete` in different ways, so the best + interfaces for them will be different. Therefore, each of them will have its + own domain-specific interface on top of `Concrete`, and they will not be the + same code. +* If enough projects want to use the same interface, they can always share it, + just like they have been sharing `Concrete`. You can check in the interface + and the adaptor somewhere near `Concrete` (perhaps in a `contrib` + sub-directory) and let many projects use it. + +You need to weigh the pros and cons carefully for your particular problem, but +I'd like to assure you that the Java community has been practicing this for a +long time and it's a proven effective technique applicable in a wide variety of +situations. :-) + +### Delegating Calls to a Fake {#DelegatingToFake} + +Some times you have a non-trivial fake implementation of an interface. For +example: + +```cpp +class Foo { + public: + virtual ~Foo() {} + virtual char DoThis(int n) = 0; + virtual void DoThat(const char* s, int* p) = 0; +}; + +class FakeFoo : public Foo { + public: + char DoThis(int n) override { + return (n > 0) ? '+' : + (n < 0) ? '-' : '0'; + } + + void DoThat(const char* s, int* p) override { + *p = strlen(s); + } +}; +``` + +Now you want to mock this interface such that you can set expectations on it. +However, you also want to use `FakeFoo` for the default behavior, as duplicating +it in the mock object is, well, a lot of work. + +When you define the mock class using gMock, you can have it delegate its default +action to a fake class you already have, using this pattern: + +```cpp +class MockFoo : public Foo { + public: + // Normal mock method definitions using gMock. + MOCK_METHOD(char, DoThis, (int n), (override)); + MOCK_METHOD(void, DoThat, (const char* s, int* p), (override)); + + // Delegates the default actions of the methods to a FakeFoo object. + // This must be called *before* the custom ON_CALL() statements. + void DelegateToFake() { + ON_CALL(*this, DoThis).WillByDefault([this](int n) { + return fake_.DoThis(n); + }); + ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) { + fake_.DoThat(s, p); + }); + } + + private: + FakeFoo fake_; // Keeps an instance of the fake in the mock. +}; +``` + +With that, you can use `MockFoo` in your tests as usual. Just remember that if +you don't explicitly set an action in an `ON_CALL()` or `EXPECT_CALL()`, the +fake will be called upon to do it.: + +```cpp +using ::testing::_; + +TEST(AbcTest, Xyz) { + MockFoo foo; + + foo.DelegateToFake(); // Enables the fake for delegation. + + // Put your ON_CALL(foo, ...)s here, if any. + + // No action specified, meaning to use the default action. + EXPECT_CALL(foo, DoThis(5)); + EXPECT_CALL(foo, DoThat(_, _)); + + int n = 0; + EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked. + foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked. + EXPECT_EQ(2, n); +} +``` + +**Some tips:** + +* If you want, you can still override the default action by providing your own + `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`. +* In `DelegateToFake()`, you only need to delegate the methods whose fake + implementation you intend to use. + +* The general technique discussed here works for overloaded methods, but + you'll need to tell the compiler which version you mean. To disambiguate a + mock function (the one you specify inside the parentheses of `ON_CALL()`), + use [this technique](#SelectOverload); to disambiguate a fake function (the + one you place inside `Invoke()`), use a `static_cast` to specify the + function's type. For instance, if class `Foo` has methods `char DoThis(int + n)` and `bool DoThis(double x) const`, and you want to invoke the latter, + you need to write `Invoke(&fake_, static_cast(&FakeFoo::DoThis))` instead of `Invoke(&fake_, &FakeFoo::DoThis)` + (The strange-looking thing inside the angled brackets of `static_cast` is + the type of a function pointer to the second `DoThis()` method.). + +* Having to mix a mock and a fake is often a sign of something gone wrong. + Perhaps you haven't got used to the interaction-based way of testing yet. Or + perhaps your interface is taking on too many roles and should be split up. + Therefore, **don't abuse this**. We would only recommend to do it as an + intermediate step when you are refactoring your code. + +Regarding the tip on mixing a mock and a fake, here's an example on why it may +be a bad sign: Suppose you have a class `System` for low-level system +operations. In particular, it does file and I/O operations. And suppose you want +to test how your code uses `System` to do I/O, and you just want the file +operations to work normally. If you mock out the entire `System` class, you'll +have to provide a fake implementation for the file operation part, which +suggests that `System` is taking on too many roles. + +Instead, you can define a `FileOps` interface and an `IOOps` interface and split +`System`'s functionalities into the two. Then you can mock `IOOps` without +mocking `FileOps`. + +### Delegating Calls to a Real Object + +When using testing doubles (mocks, fakes, stubs, and etc), sometimes their +behaviors will differ from those of the real objects. This difference could be +either intentional (as in simulating an error such that you can test the error +handling code) or unintentional. If your mocks have different behaviors than the +real objects by mistake, you could end up with code that passes the tests but +fails in production. + +You can use the *delegating-to-real* technique to ensure that your mock has the +same behavior as the real object while retaining the ability to validate calls. +This technique is very similar to the [delegating-to-fake](#DelegatingToFake) +technique, the difference being that we use a real object instead of a fake. +Here's an example: + +```cpp +using ::testing::AtLeast; + +class MockFoo : public Foo { + public: + MockFoo() { + // By default, all calls are delegated to the real object. + ON_CALL(*this, DoThis).WillByDefault([this](int n) { + return real_.DoThis(n); + }); + ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) { + real_.DoThat(s, p); + }); + ... + } + MOCK_METHOD(char, DoThis, ...); + MOCK_METHOD(void, DoThat, ...); + ... + private: + Foo real_; +}; + +... + MockFoo mock; + EXPECT_CALL(mock, DoThis()) + .Times(3); + EXPECT_CALL(mock, DoThat("Hi")) + .Times(AtLeast(1)); + ... use mock in test ... +``` + +With this, gMock will verify that your code made the right calls (with the right +arguments, in the right order, called the right number of times, etc), and a +real object will answer the calls (so the behavior will be the same as in +production). This gives you the best of both worlds. + +### Delegating Calls to a Parent Class + +Ideally, you should code to interfaces, whose methods are all pure virtual. In +reality, sometimes you do need to mock a virtual method that is not pure (i.e, +it already has an implementation). For example: + +```cpp +class Foo { + public: + virtual ~Foo(); + + virtual void Pure(int n) = 0; + virtual int Concrete(const char* str) { ... } +}; + +class MockFoo : public Foo { + public: + // Mocking a pure method. + MOCK_METHOD(void, Pure, (int n), (override)); + // Mocking a concrete method. Foo::Concrete() is shadowed. + MOCK_METHOD(int, Concrete, (const char* str), (override)); +}; +``` + +Sometimes you may want to call `Foo::Concrete()` instead of +`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub action, or +perhaps your test doesn't need to mock `Concrete()` at all (but it would be +oh-so painful to have to define a new mock class whenever you don't need to mock +one of its methods). + +The trick is to leave a back door in your mock class for accessing the real +methods in the base class: + +```cpp +class MockFoo : public Foo { + public: + // Mocking a pure method. + MOCK_METHOD(void, Pure, (int n), (override)); + // Mocking a concrete method. Foo::Concrete() is shadowed. + MOCK_METHOD(int, Concrete, (const char* str), (override)); + + // Use this to call Concrete() defined in Foo. + int FooConcrete(const char* str) { return Foo::Concrete(str); } +}; +``` + +Now, you can call `Foo::Concrete()` inside an action by: + +```cpp +... + EXPECT_CALL(foo, Concrete).WillOnce([&foo](const char* str) { + return foo.FooConcrete(str); + }); +``` + +or tell the mock object that you don't want to mock `Concrete()`: + +```cpp +... + ON_CALL(foo, Concrete).WillByDefault([&foo](const char* str) { + return foo.FooConcrete(str); + }); +``` + +(Why don't we just write `{ return foo.Concrete(str); }`? If you do that, +`MockFoo::Concrete()` will be called (and cause an infinite recursion) since +`Foo::Concrete()` is virtual. That's just how C++ works.) + +## Using Matchers + +### Matching Argument Values Exactly + +You can specify exactly which arguments a mock method is expecting: + +```cpp +using ::testing::Return; +... + EXPECT_CALL(foo, DoThis(5)) + .WillOnce(Return('a')); + EXPECT_CALL(foo, DoThat("Hello", bar)); +``` + +### Using Simple Matchers + +You can use matchers to match arguments that have a certain property: + +```cpp +using ::testing::NotNull; +using ::testing::Return; +... + EXPECT_CALL(foo, DoThis(Ge(5))) // The argument must be >= 5. + .WillOnce(Return('a')); + EXPECT_CALL(foo, DoThat("Hello", NotNull())); + // The second argument must not be NULL. +``` + +A frequently used matcher is `_`, which matches anything: + +```cpp + EXPECT_CALL(foo, DoThat(_, NotNull())); +``` + + +### Combining Matchers {#CombiningMatchers} + +You can build complex matchers from existing ones using `AllOf()`, +`AllOfArray()`, `AnyOf()`, `AnyOfArray()` and `Not()`: + +```cpp +using ::testing::AllOf; +using ::testing::Gt; +using ::testing::HasSubstr; +using ::testing::Ne; +using ::testing::Not; +... + // The argument must be > 5 and != 10. + EXPECT_CALL(foo, DoThis(AllOf(Gt(5), + Ne(10)))); + + // The first argument must not contain sub-string "blah". + EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), + NULL)); +``` + +### Casting Matchers {#SafeMatcherCast} + +gMock matchers are statically typed, meaning that the compiler can catch your +mistake if you use a matcher of the wrong type (for example, if you use `Eq(5)` +to match a `string` argument). Good for you! + +Sometimes, however, you know what you're doing and want the compiler to give you +some slack. One example is that you have a matcher for `long` and the argument +you want to match is `int`. While the two types aren't exactly the same, there +is nothing really wrong with using a `Matcher` to match an `int` - after +all, we can first convert the `int` argument to a `long` losslessly before +giving it to the matcher. + +To support this need, gMock gives you the `SafeMatcherCast(m)` function. It +casts a matcher `m` to type `Matcher`. To ensure safety, gMock checks that +(let `U` be the type `m` accepts : + +1. Type `T` can be *implicitly* cast to type `U`; +2. When both `T` and `U` are built-in arithmetic types (`bool`, integers, and + floating-point numbers), the conversion from `T` to `U` is not lossy (in + other words, any value representable by `T` can also be represented by `U`); + and +3. When `U` is a reference, `T` must also be a reference (as the underlying + matcher may be interested in the address of the `U` value). + +The code won't compile if any of these conditions isn't met. + +Here's one example: + +```cpp +using ::testing::SafeMatcherCast; + +// A base class and a child class. +class Base { ... }; +class Derived : public Base { ... }; + +class MockFoo : public Foo { + public: + MOCK_METHOD(void, DoThis, (Derived* derived), (override)); +}; + +... + MockFoo foo; + // m is a Matcher we got from somewhere. + EXPECT_CALL(foo, DoThis(SafeMatcherCast(m))); +``` + +If you find `SafeMatcherCast(m)` too limiting, you can use a similar function +`MatcherCast(m)`. The difference is that `MatcherCast` works as long as you +can `static_cast` type `T` to type `U`. + +`MatcherCast` essentially lets you bypass C++'s type system (`static_cast` isn't +always safe as it could throw away information, for example), so be careful not +to misuse/abuse it. + +### Selecting Between Overloaded Functions {#SelectOverload} + +If you expect an overloaded function to be called, the compiler may need some +help on which overloaded version it is. + +To disambiguate functions overloaded on the const-ness of this object, use the +`Const()` argument wrapper. + +```cpp +using ::testing::ReturnRef; + +class MockFoo : public Foo { + ... + MOCK_METHOD(Bar&, GetBar, (), (override)); + MOCK_METHOD(const Bar&, GetBar, (), (const, override)); +}; + +... + MockFoo foo; + Bar bar1, bar2; + EXPECT_CALL(foo, GetBar()) // The non-const GetBar(). + .WillOnce(ReturnRef(bar1)); + EXPECT_CALL(Const(foo), GetBar()) // The const GetBar(). + .WillOnce(ReturnRef(bar2)); +``` + +(`Const()` is defined by gMock and returns a `const` reference to its argument.) + +To disambiguate overloaded functions with the same number of arguments but +different argument types, you may need to specify the exact type of a matcher, +either by wrapping your matcher in `Matcher()`, or using a matcher whose +type is fixed (`TypedEq`, `An()`, etc): + +```cpp +using ::testing::An; +using ::testing::Matcher; +using ::testing::TypedEq; + +class MockPrinter : public Printer { + public: + MOCK_METHOD(void, Print, (int n), (override)); + MOCK_METHOD(void, Print, (char c), (override)); +}; + +TEST(PrinterTest, Print) { + MockPrinter printer; + + EXPECT_CALL(printer, Print(An())); // void Print(int); + EXPECT_CALL(printer, Print(Matcher(Lt(5)))); // void Print(int); + EXPECT_CALL(printer, Print(TypedEq('a'))); // void Print(char); + + printer.Print(3); + printer.Print(6); + printer.Print('a'); +} +``` + +### Performing Different Actions Based on the Arguments + +When a mock method is called, the *last* matching expectation that's still +active will be selected (think "newer overrides older"). So, you can make a +method do different things depending on its argument values like this: + +```cpp +using ::testing::_; +using ::testing::Lt; +using ::testing::Return; +... + // The default case. + EXPECT_CALL(foo, DoThis(_)) + .WillRepeatedly(Return('b')); + // The more specific case. + EXPECT_CALL(foo, DoThis(Lt(5))) + .WillRepeatedly(Return('a')); +``` + +Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will be +returned; otherwise `'b'` will be returned. + +### Matching Multiple Arguments as a Whole + +Sometimes it's not enough to match the arguments individually. For example, we +may want to say that the first argument must be less than the second argument. +The `With()` clause allows us to match all arguments of a mock function as a +whole. For example, + +```cpp +using ::testing::_; +using ::testing::Ne; +using ::testing::Lt; +... + EXPECT_CALL(foo, InRange(Ne(0), _)) + .With(Lt()); +``` + +says that the first argument of `InRange()` must not be 0, and must be less than +the second argument. + +The expression inside `With()` must be a matcher of type +`Matcher< ::std::tuple >`, where `A1`, ..., `An` are the types of +the function arguments. + +You can also write `AllArgs(m)` instead of `m` inside `.With()`. The two forms +are equivalent, but `.With(AllArgs(Lt()))` is more readable than `.With(Lt())`. + +You can use `Args(m)` to match the `n` selected arguments (as a +tuple) against `m`. For example, + +```cpp +using ::testing::_; +using ::testing::AllOf; +using ::testing::Args; +using ::testing::Lt; +... + EXPECT_CALL(foo, Blah) + .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); +``` + +says that `Blah` will be called with arguments `x`, `y`, and `z` where `x < y < +z`. Note that in this example, it wasn't necessary specify the positional +matchers. + +As a convenience and example, gMock provides some matchers for 2-tuples, +including the `Lt()` matcher above. See [here](#MultiArgMatchers) for the +complete list. + +Note that if you want to pass the arguments to a predicate of your own (e.g. +`.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to +take a `::std::tuple` as its argument; gMock will pass the `n` selected +arguments as *one* single tuple to the predicate. + +### Using Matchers as Predicates + +Have you noticed that a matcher is just a fancy predicate that also knows how to +describe itself? Many existing algorithms take predicates as arguments (e.g. +those defined in STL's `` header), and it would be a shame if gMock +matchers were not allowed to participate. + +Luckily, you can use a matcher where a unary predicate functor is expected by +wrapping it inside the `Matches()` function. For example, + +```cpp +#include +#include + +using ::testing::Matches; +using ::testing::Ge; + +vector v; +... +// How many elements in v are >= 10? +const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); +``` + +Since you can build complex matchers from simpler ones easily using gMock, this +gives you a way to conveniently construct composite predicates (doing the same +using STL's `` header is just painful). For example, here's a +predicate that's satisfied by any number that is >= 0, <= 100, and != 50: + +```cpp +using testing::AllOf; +using testing::Ge; +using testing::Le; +using testing::Matches; +using testing::Ne; +... +Matches(AllOf(Ge(0), Le(100), Ne(50))) +``` + +### Using Matchers in googletest Assertions + +Since matchers are basically predicates that also know how to describe +themselves, there is a way to take advantage of them in googletest assertions. +It's called `ASSERT_THAT` and `EXPECT_THAT`: + +```cpp + ASSERT_THAT(value, matcher); // Asserts that value matches matcher. + EXPECT_THAT(value, matcher); // The non-fatal version. +``` + +For example, in a googletest test you can write: + +```cpp +#include "gmock/gmock.h" + +using ::testing::AllOf; +using ::testing::Ge; +using ::testing::Le; +using ::testing::MatchesRegex; +using ::testing::StartsWith; + +... + EXPECT_THAT(Foo(), StartsWith("Hello")); + EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); + ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); +``` + +which (as you can probably guess) executes `Foo()`, `Bar()`, and `Baz()`, and +verifies that: + +* `Foo()` returns a string that starts with `"Hello"`. +* `Bar()` returns a string that matches regular expression `"Line \\d+"`. +* `Baz()` returns a number in the range [5, 10]. + +The nice thing about these macros is that *they read like English*. They +generate informative messages too. For example, if the first `EXPECT_THAT()` +above fails, the message will be something like: + +```cpp +Value of: Foo() + Actual: "Hi, world!" +Expected: starts with "Hello" +``` + +**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was borrowed from Joe Walnes' +Hamcrest project, which adds `assertThat()` to JUnit. + +### Using Predicates as Matchers + +gMock provides a [built-in set](#MatcherList) of matchers. In case you find them +lacking, you can use an arbitrary unary predicate function or functor as a +matcher - as long as the predicate accepts a value of the type you want. You do +this by wrapping the predicate inside the `Truly()` function, for example: + +```cpp +using ::testing::Truly; + +int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } +... + // Bar() must be called with an even number. + EXPECT_CALL(foo, Bar(Truly(IsEven))); +``` + +Note that the predicate function / functor doesn't have to return `bool`. It +works as long as the return value can be used as the condition in in statement +`if (condition) ...`. + + + +### Matching Arguments that Are Not Copyable + +When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, gMock saves away a copy of +`bar`. When `Foo()` is called later, gMock compares the argument to `Foo()` with +the saved copy of `bar`. This way, you don't need to worry about `bar` being +modified or destroyed after the `EXPECT_CALL()` is executed. The same is true +when you use matchers like `Eq(bar)`, `Le(bar)`, and so on. + +But what if `bar` cannot be copied (i.e. has no copy constructor)? You could +define your own matcher function or callback and use it with `Truly()`, as the +previous couple of recipes have shown. Or, you may be able to get away from it +if you can guarantee that `bar` won't be changed after the `EXPECT_CALL()` is +executed. Just tell gMock that it should save a reference to `bar`, instead of a +copy of it. Here's how: + +```cpp +using ::testing::ByRef; +using ::testing::Eq; +using ::testing::Lt; +... + // Expects that Foo()'s argument == bar. + EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); + + // Expects that Foo()'s argument < bar. + EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar)))); +``` + +Remember: if you do this, don't change `bar` after the `EXPECT_CALL()`, or the +result is undefined. + +### Validating a Member of an Object + +Often a mock function takes a reference to object as an argument. When matching +the argument, you may not want to compare the entire object against a fixed +object, as that may be over-specification. Instead, you may need to validate a +certain member variable or the result of a certain getter method of the object. +You can do this with `Field()` and `Property()`. More specifically, + +```cpp +Field(&Foo::bar, m) +``` + +is a matcher that matches a `Foo` object whose `bar` member variable satisfies +matcher `m`. + +```cpp +Property(&Foo::baz, m) +``` + +is a matcher that matches a `Foo` object whose `baz()` method returns a value +that satisfies matcher `m`. + +For example: + + +| Expression | Description | +| :--------------------------- | :--------------------------------------- | +| `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`. | +| `Property(&Foo::name, StartsWith("John "))` | Matches `x` where `x.name()` starts with `"John "`. | + + +Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no argument +and be declared as `const`. + +BTW, `Field()` and `Property()` can also match plain pointers to objects. For +instance, + +```cpp +using ::testing::Field; +using ::testing::Ge; +... +Field(&Foo::number, Ge(3)) +``` + +matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, the match +will always fail regardless of the inner matcher. + +What if you want to validate more than one members at the same time? Remember +that there are [`AllOf()` and `AllOfArray()`](#CombiningMatchers). + +Finally `Field()` and `Property()` provide overloads that take the field or +property names as the first argument to include it in the error message. This +can be useful when creating combined matchers. + +```cpp +using ::testing::AllOf; +using ::testing::Field; +using ::testing::Matcher; +using ::testing::SafeMatcherCast; + +Matcher IsFoo(const Foo& foo) { + return AllOf(Field("some_field", &Foo::some_field, foo.some_field), + Field("other_field", &Foo::other_field, foo.other_field), + Field("last_field", &Foo::last_field, foo.last_field)); +} +``` + +### Validating the Value Pointed to by a Pointer Argument + +C++ functions often take pointers as arguments. You can use matchers like +`IsNull()`, `NotNull()`, and other comparison matchers to match a pointer, but +what if you want to make sure the value *pointed to* by the pointer, instead of +the pointer itself, has a certain property? Well, you can use the `Pointee(m)` +matcher. + +`Pointee(m)` matches a pointer if and only if `m` matches the value the pointer +points to. For example: + +```cpp +using ::testing::Ge; +using ::testing::Pointee; +... + EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); +``` + +expects `foo.Bar()` to be called with a pointer that points to a value greater +than or equal to 3. + +One nice thing about `Pointee()` is that it treats a `NULL` pointer as a match +failure, so you can write `Pointee(m)` instead of + +```cpp +using ::testing::AllOf; +using ::testing::NotNull; +using ::testing::Pointee; +... + AllOf(NotNull(), Pointee(m)) +``` + +without worrying that a `NULL` pointer will crash your test. + +Also, did we tell you that `Pointee()` works with both raw pointers **and** +smart pointers (`std::unique_ptr`, `std::shared_ptr`, etc)? + +What if you have a pointer to pointer? You guessed it - you can use nested +`Pointee()` to probe deeper inside the value. For example, +`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points +to a number less than 3 (what a mouthful...). + +### Testing a Certain Property of an Object + +Sometimes you want to specify that an object argument has a certain property, +but there is no existing matcher that does this. If you want good error +messages, you should [define a matcher](#NewMatchers). If you want to do it +quick and dirty, you could get away with writing an ordinary function. + +Let's say you have a mock function that takes an object of type `Foo`, which has +an `int bar()` method and an `int baz()` method, and you want to constrain that +the argument's `bar()` value plus its `baz()` value is a given number. Here's +how you can define a matcher to do it: + +```cpp +using ::testing::Matcher; +using ::testing::MatcherInterface; +using ::testing::MatchResultListener; + +class BarPlusBazEqMatcher : public MatcherInterface { + public: + explicit BarPlusBazEqMatcher(int expected_sum) + : expected_sum_(expected_sum) {} + + bool MatchAndExplain(const Foo& foo, + MatchResultListener* /* listener */) const override { + return (foo.bar() + foo.baz()) == expected_sum_; + } + + void DescribeTo(::std::ostream* os) const override { + *os << "bar() + baz() equals " << expected_sum_; + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "bar() + baz() does not equal " << expected_sum_; + } + private: + const int expected_sum_; +}; + +Matcher BarPlusBazEq(int expected_sum) { + return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); +} + +... + EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; +``` + +### Matching Containers + +Sometimes an STL container (e.g. list, vector, map, ...) is passed to a mock +function and you may want to validate it. Since most STL containers support the +`==` operator, you can write `Eq(expected_container)` or simply +`expected_container` to match a container exactly. + +Sometimes, though, you may want to be more flexible (for example, the first +element must be an exact match, but the second element can be any positive +number, and so on). Also, containers used in tests often have a small number of +elements, and having to define the expected container out-of-line is a bit of a +hassle. + +You can use the `ElementsAre()` or `UnorderedElementsAre()` matcher in such +cases: + +```cpp +using ::testing::_; +using ::testing::ElementsAre; +using ::testing::Gt; +... + MOCK_METHOD(void, Foo, (const vector& numbers), (override)); +... + EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); +``` + +The above matcher says that the container must have 4 elements, which must be 1, +greater than 0, anything, and 5 respectively. + +If you instead write: + +```cpp +using ::testing::_; +using ::testing::Gt; +using ::testing::UnorderedElementsAre; +... + MOCK_METHOD(void, Foo, (const vector& numbers), (override)); +... + EXPECT_CALL(mock, Foo(UnorderedElementsAre(1, Gt(0), _, 5))); +``` + +It means that the container must have 4 elements, which (under some permutation) +must be 1, greater than 0, anything, and 5 respectively. + +As an alternative you can place the arguments in a C-style array and use +`ElementsAreArray()` or `UnorderedElementsAreArray()` instead: + +```cpp +using ::testing::ElementsAreArray; +... + // ElementsAreArray accepts an array of element values. + const int expected_vector1[] = {1, 5, 2, 4, ...}; + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); + + // Or, an array of element matchers. + Matcher expected_vector2[] = {1, Gt(2), _, 3, ...}; + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); +``` + +In case the array needs to be dynamically created (and therefore the array size +cannot be inferred by the compiler), you can give `ElementsAreArray()` an +additional argument to specify the array size: + +```cpp +using ::testing::ElementsAreArray; +... + int* const expected_vector3 = new int[count]; + ... fill expected_vector3 with values ... + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); +``` + +Use `Pair` when comparing maps or other associative containers. + +```cpp +using testing::ElementsAre; +using testing::Pair; +... + std::map m = {{"a", 1}, {"b", 2}, {"c", 3}}; + EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3))); +``` + +**Tips:** + +* `ElementsAre*()` can be used to match *any* container that implements the + STL iterator pattern (i.e. it has a `const_iterator` type and supports + `begin()/end()`), not just the ones defined in STL. It will even work with + container types yet to be written - as long as they follows the above + pattern. +* You can use nested `ElementsAre*()` to match nested (multi-dimensional) + containers. +* If the container is passed by pointer instead of by reference, just write + `Pointee(ElementsAre*(...))`. +* The order of elements *matters* for `ElementsAre*()`. If you are using it + with containers whose element order are undefined (e.g. `hash_map`) you + should use `WhenSorted` around `ElementsAre`. + +### Sharing Matchers + +Under the hood, a gMock matcher object consists of a pointer to a ref-counted +implementation object. Copying matchers is allowed and very efficient, as only +the pointer is copied. When the last matcher that references the implementation +object dies, the implementation object will be deleted. + +Therefore, if you have some complex matcher that you want to use again and +again, there is no need to build it everytime. Just assign it to a matcher +variable and use that variable repeatedly! For example, + +```cpp +using ::testing::AllOf; +using ::testing::Gt; +using ::testing::Le; +using ::testing::Matcher; +... + Matcher in_range = AllOf(Gt(5), Le(10)); + ... use in_range as a matcher in multiple EXPECT_CALLs ... +``` + +### Matchers must have no side-effects {#PureMatchers} + +WARNING: gMock does not guarantee when or how many times a matcher will be +invoked. Therefore, all matchers must be *purely functional*: they cannot have +any side effects, and the match result must not depend on anything other than +the matcher's parameters and the value being matched. + +This requirement must be satisfied no matter how a matcher is defined (e.g., if +it is one of the standard matchers, or a custom matcher). In particular, a +matcher can never call a mock function, as that will affect the state of the +mock object and gMock. + +## Setting Expectations + +### Knowing When to Expect {#UseOnCall} + + + +**`ON_CALL`** is likely the *single most under-utilized construct* in gMock. + +There are basically two constructs for defining the behavior of a mock object: +`ON_CALL` and `EXPECT_CALL`. The difference? `ON_CALL` defines what happens when +a mock method is called, but doesn't imply any expectation on the method +being called. `EXPECT_CALL` not only defines the behavior, but also sets an +expectation that the method will be called with the given arguments, for the +given number of times (and *in the given order* when you specify the order +too). + +Since `EXPECT_CALL` does more, isn't it better than `ON_CALL`? Not really. Every +`EXPECT_CALL` adds a constraint on the behavior of the code under test. Having +more constraints than necessary is *baaad* - even worse than not having enough +constraints. + +This may be counter-intuitive. How could tests that verify more be worse than +tests that verify less? Isn't verification the whole point of tests? + +The answer lies in *what* a test should verify. **A good test verifies the +contract of the code.** If a test over-specifies, it doesn't leave enough +freedom to the implementation. As a result, changing the implementation without +breaking the contract (e.g. refactoring and optimization), which should be +perfectly fine to do, can break such tests. Then you have to spend time fixing +them, only to see them broken again the next time the implementation is changed. + +Keep in mind that one doesn't have to verify more than one property in one test. +In fact, **it's a good style to verify only one thing in one test.** If you do +that, a bug will likely break only one or two tests instead of dozens (which +case would you rather debug?). If you are also in the habit of giving tests +descriptive names that tell what they verify, you can often easily guess what's +wrong just from the test log itself. + +So use `ON_CALL` by default, and only use `EXPECT_CALL` when you actually intend +to verify that the call is made. For example, you may have a bunch of `ON_CALL`s +in your test fixture to set the common mock behavior shared by all tests in the +same group, and write (scarcely) different `EXPECT_CALL`s in different `TEST_F`s +to verify different aspects of the code's behavior. Compared with the style +where each `TEST` has many `EXPECT_CALL`s, this leads to tests that are more +resilient to implementational changes (and thus less likely to require +maintenance) and makes the intent of the tests more obvious (so they are easier +to maintain when you do need to maintain them). + +If you are bothered by the "Uninteresting mock function call" message printed +when a mock method without an `EXPECT_CALL` is called, you may use a `NiceMock` +instead to suppress all such messages for the mock object, or suppress the +message for specific methods by adding `EXPECT_CALL(...).Times(AnyNumber())`. DO +NOT suppress it by blindly adding an `EXPECT_CALL(...)`, or you'll have a test +that's a pain to maintain. + +### Ignoring Uninteresting Calls + +If you are not interested in how a mock method is called, just don't say +anything about it. In this case, if the method is ever called, gMock will +perform its default action to allow the test program to continue. If you are not +happy with the default action taken by gMock, you can override it using +`DefaultValue::Set()` (described [here](#DefaultValue)) or `ON_CALL()`. + +Please note that once you expressed interest in a particular mock method (via +`EXPECT_CALL()`), all invocations to it must match some expectation. If this +function is called but the arguments don't match any `EXPECT_CALL()` statement, +it will be an error. + +### Disallowing Unexpected Calls + +If a mock method shouldn't be called at all, explicitly say so: + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .Times(0); +``` + +If some calls to the method are allowed, but the rest are not, just list all the +expected calls: + +```cpp +using ::testing::AnyNumber; +using ::testing::Gt; +... + EXPECT_CALL(foo, Bar(5)); + EXPECT_CALL(foo, Bar(Gt(10))) + .Times(AnyNumber()); +``` + +A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` statements +will be an error. + +### Understanding Uninteresting vs Unexpected Calls {#uninteresting-vs-unexpected} + +*Uninteresting* calls and *unexpected* calls are different concepts in gMock. +*Very* different. + +A call `x.Y(...)` is **uninteresting** if there's *not even a single* +`EXPECT_CALL(x, Y(...))` set. In other words, the test isn't interested in the +`x.Y()` method at all, as evident in that the test doesn't care to say anything +about it. + +A call `x.Y(...)` is **unexpected** if there are *some* `EXPECT_CALL(x, +Y(...))`s set, but none of them matches the call. Put another way, the test is +interested in the `x.Y()` method (therefore it explicitly sets some +`EXPECT_CALL` to verify how it's called); however, the verification fails as the +test doesn't expect this particular call to happen. + +**An unexpected call is always an error,** as the code under test doesn't behave +the way the test expects it to behave. + +**By default, an uninteresting call is not an error,** as it violates no +constraint specified by the test. (gMock's philosophy is that saying nothing +means there is no constraint.) However, it leads to a warning, as it *might* +indicate a problem (e.g. the test author might have forgotten to specify a +constraint). + +In gMock, `NiceMock` and `StrictMock` can be used to make a mock class "nice" or +"strict". How does this affect uninteresting calls and unexpected calls? + +A **nice mock** suppresses uninteresting call *warnings*. It is less chatty than +the default mock, but otherwise is the same. If a test fails with a default +mock, it will also fail using a nice mock instead. And vice versa. Don't expect +making a mock nice to change the test's result. + +A **strict mock** turns uninteresting call warnings into errors. So making a +mock strict may change the test's result. + +Let's look at an example: + +```cpp +TEST(...) { + NiceMock mock_registry; + EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) + .WillRepeatedly(Return("Larry Page")); + + // Use mock_registry in code under test. + ... &mock_registry ... +} +``` + +The sole `EXPECT_CALL` here says that all calls to `GetDomainOwner()` must have +`"google.com"` as the argument. If `GetDomainOwner("yahoo.com")` is called, it +will be an unexpected call, and thus an error. *Having a nice mock doesn't +change the severity of an unexpected call.* + +So how do we tell gMock that `GetDomainOwner()` can be called with some other +arguments as well? The standard technique is to add a "catch all" `EXPECT_CALL`: + +```cpp + EXPECT_CALL(mock_registry, GetDomainOwner(_)) + .Times(AnyNumber()); // catches all other calls to this method. + EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) + .WillRepeatedly(Return("Larry Page")); +``` + +Remember that `_` is the wildcard matcher that matches anything. With this, if +`GetDomainOwner("google.com")` is called, it will do what the second +`EXPECT_CALL` says; if it is called with a different argument, it will do what +the first `EXPECT_CALL` says. + +Note that the order of the two `EXPECT_CALL`s is important, as a newer +`EXPECT_CALL` takes precedence over an older one. + +For more on uninteresting calls, nice mocks, and strict mocks, read +["The Nice, the Strict, and the Naggy"](#NiceStrictNaggy). + +### Ignoring Uninteresting Arguments {#ParameterlessExpectations} + +If your test doesn't care about the parameters (it only cares about the number +or order of calls), you can often simply omit the parameter list: + +```cpp + // Expect foo.Bar( ... ) twice with any arguments. + EXPECT_CALL(foo, Bar).Times(2); + + // Delegate to the given method whenever the factory is invoked. + ON_CALL(foo_factory, MakeFoo) + .WillByDefault(&BuildFooForTest); +``` + +This functionality is only available when a method is not overloaded; to prevent +unexpected behavior it is a compilation error to try to set an expectation on a +method where the specific overload is ambiguous. You can work around this by +supplying a [simpler mock interface](#SimplerInterfaces) than the mocked class +provides. + +This pattern is also useful when the arguments are interesting, but match logic +is substantially complex. You can leave the argument list unspecified and use +SaveArg actions to [save the values for later verification](#SaveArgVerify). If +you do that, you can easily differentiate calling the method the wrong number of +times from calling it with the wrong arguments. + +### Expecting Ordered Calls {#OrderedCalls} + +Although an `EXPECT_CALL()` statement defined earlier takes precedence when +gMock tries to match a function call with an expectation, by default calls don't +have to happen in the order `EXPECT_CALL()` statements are written. For example, +if the arguments match the matchers in the third `EXPECT_CALL()`, but not those +in the first two, then the third expectation will be used. + +If you would rather have all calls occur in the order of the expectations, put +the `EXPECT_CALL()` statements in a block where you define a variable of type +`InSequence`: + +```cpp +using ::testing::_; +using ::testing::InSequence; + + { + InSequence s; + + EXPECT_CALL(foo, DoThis(5)); + EXPECT_CALL(bar, DoThat(_)) + .Times(2); + EXPECT_CALL(foo, DoThis(6)); + } +``` + +In this example, we expect a call to `foo.DoThis(5)`, followed by two calls to +`bar.DoThat()` where the argument can be anything, which are in turn followed by +a call to `foo.DoThis(6)`. If a call occurred out-of-order, gMock will report an +error. + +### Expecting Partially Ordered Calls {#PartialOrder} + +Sometimes requiring everything to occur in a predetermined order can lead to +brittle tests. For example, we may care about `A` occurring before both `B` and +`C`, but aren't interested in the relative order of `B` and `C`. In this case, +the test should reflect our real intent, instead of being overly constraining. + +gMock allows you to impose an arbitrary DAG (directed acyclic graph) on the +calls. One way to express the DAG is to use the [After](#AfterClause) clause of +`EXPECT_CALL`. + +Another way is via the `InSequence()` clause (not the same as the `InSequence` +class), which we borrowed from jMock 2. It's less flexible than `After()`, but +more convenient when you have long chains of sequential calls, as it doesn't +require you to come up with different names for the expectations in the chains. +Here's how it works: + +If we view `EXPECT_CALL()` statements as nodes in a graph, and add an edge from +node A to node B wherever A must occur before B, we can get a DAG. We use the +term "sequence" to mean a directed path in this DAG. Now, if we decompose the +DAG into sequences, we just need to know which sequences each `EXPECT_CALL()` +belongs to in order to be able to reconstruct the original DAG. + +So, to specify the partial order on the expectations we need to do two things: +first to define some `Sequence` objects, and then for each `EXPECT_CALL()` say +which `Sequence` objects it is part of. + +Expectations in the same sequence must occur in the order they are written. For +example, + +```cpp +using ::testing::Sequence; +... + Sequence s1, s2; + + EXPECT_CALL(foo, A()) + .InSequence(s1, s2); + EXPECT_CALL(bar, B()) + .InSequence(s1); + EXPECT_CALL(bar, C()) + .InSequence(s2); + EXPECT_CALL(foo, D()) + .InSequence(s2); +``` + +specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`): + +```text + +---> B + | + A ---| + | + +---> C ---> D +``` + +This means that A must occur before B and C, and C must occur before D. There's +no restriction about the order other than these. + +### Controlling When an Expectation Retires + +When a mock method is called, gMock only considers expectations that are still +active. An expectation is active when created, and becomes inactive (aka +*retires*) when a call that has to occur later has occurred. For example, in + +```cpp +using ::testing::_; +using ::testing::Sequence; +... + Sequence s1, s2; + + EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 + .Times(AnyNumber()) + .InSequence(s1, s2); + EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 + .InSequence(s1); + EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 + .InSequence(s2); +``` + +as soon as either #2 or #3 is matched, #1 will retire. If a warning `"File too +large."` is logged after this, it will be an error. + +Note that an expectation doesn't retire automatically when it's saturated. For +example, + +```cpp +using ::testing::_; +... + EXPECT_CALL(log, Log(WARNING, _, _)); // #1 + EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 +``` + +says that there will be exactly one warning with the message `"File too +large."`. If the second warning contains this message too, #2 will match again +and result in an upper-bound-violated error. + +If this is not what you want, you can ask an expectation to retire as soon as it +becomes saturated: + +```cpp +using ::testing::_; +... + EXPECT_CALL(log, Log(WARNING, _, _)); // #1 + EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 + .RetiresOnSaturation(); +``` + +Here #2 can be used only once, so if you have two warnings with the message +`"File too large."`, the first will match #2 and the second will match #1 - +there will be no error. + +## Using Actions + +### Returning References from Mock Methods + +If a mock function's return type is a reference, you need to use `ReturnRef()` +instead of `Return()` to return a result: + +```cpp +using ::testing::ReturnRef; + +class MockFoo : public Foo { + public: + MOCK_METHOD(Bar&, GetBar, (), (override)); +}; +... + MockFoo foo; + Bar bar; + EXPECT_CALL(foo, GetBar()) + .WillOnce(ReturnRef(bar)); +... +``` + +### Returning Live Values from Mock Methods + +The `Return(x)` action saves a copy of `x` when the action is created, and +always returns the same value whenever it's executed. Sometimes you may want to +instead return the *live* value of `x` (i.e. its value at the time when the +action is *executed*.). Use either `ReturnRef()` or `ReturnPointee()` for this +purpose. + +If the mock function's return type is a reference, you can do it using +`ReturnRef(x)`, as shown in the previous recipe ("Returning References from Mock +Methods"). However, gMock doesn't let you use `ReturnRef()` in a mock function +whose return type is not a reference, as doing that usually indicates a user +error. So, what shall you do? + +Though you may be tempted, DO NOT use `ByRef()`: + +```cpp +using testing::ByRef; +using testing::Return; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, GetValue, (), (override)); +}; +... + int x = 0; + MockFoo foo; + EXPECT_CALL(foo, GetValue()) + .WillRepeatedly(Return(ByRef(x))); // Wrong! + x = 42; + EXPECT_EQ(42, foo.GetValue()); +``` + +Unfortunately, it doesn't work here. The above code will fail with error: + +```text +Value of: foo.GetValue() + Actual: 0 +Expected: 42 +``` + +The reason is that `Return(*value*)` converts `value` to the actual return type +of the mock function at the time when the action is *created*, not when it is +*executed*. (This behavior was chosen for the action to be safe when `value` is +a proxy object that references some temporary objects.) As a result, `ByRef(x)` +is converted to an `int` value (instead of a `const int&`) when the expectation +is set, and `Return(ByRef(x))` will always return 0. + +`ReturnPointee(pointer)` was provided to solve this problem specifically. It +returns the value pointed to by `pointer` at the time the action is *executed*: + +```cpp +using testing::ReturnPointee; +... + int x = 0; + MockFoo foo; + EXPECT_CALL(foo, GetValue()) + .WillRepeatedly(ReturnPointee(&x)); // Note the & here. + x = 42; + EXPECT_EQ(42, foo.GetValue()); // This will succeed now. +``` + +### Combining Actions + +Want to do more than one thing when a function is called? That's fine. `DoAll()` +allow you to do sequence of actions every time. Only the return value of the +last action in the sequence will be used. + +```cpp +using ::testing::_; +using ::testing::DoAll; + +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, Bar, (int n), (override)); +}; +... + EXPECT_CALL(foo, Bar(_)) + .WillOnce(DoAll(action_1, + action_2, + ... + action_n)); +``` + +### Verifying Complex Arguments {#SaveArgVerify} + +If you want to verify that a method is called with a particular argument but the +match criteria is complex, it can be difficult to distinguish between +cardinality failures (calling the method the wrong number of times) and argument +match failures. Similarly, if you are matching multiple parameters, it may not +be easy to distinguishing which argument failed to match. For example: + +```cpp + // Not ideal: this could fail because of a problem with arg1 or arg2, or maybe + // just the method wasn't called. + EXPECT_CALL(foo, SendValues(_, ElementsAre(1, 4, 4, 7), EqualsProto( ... ))); +``` + +You can instead save the arguments and test them individually: + +```cpp + EXPECT_CALL(foo, SendValues) + .WillOnce(DoAll(SaveArg<1>(&actual_array), SaveArg<2>(&actual_proto))); + ... run the test + EXPECT_THAT(actual_array, ElementsAre(1, 4, 4, 7)); + EXPECT_THAT(actual_proto, EqualsProto( ... )); +``` + +### Mocking Side Effects {#MockingSideEffects} + +Sometimes a method exhibits its effect not via returning a value but via side +effects. For example, it may change some global state or modify an output +argument. To mock side effects, in general you can define your own action by +implementing `::testing::ActionInterface`. + +If all you need to do is to change an output argument, the built-in +`SetArgPointee()` action is convenient: + +```cpp +using ::testing::_; +using ::testing::SetArgPointee; + +class MockMutator : public Mutator { + public: + MOCK_METHOD(void, Mutate, (bool mutate, int* value), (override)); + ... +} +... + MockMutator mutator; + EXPECT_CALL(mutator, Mutate(true, _)) + .WillOnce(SetArgPointee<1>(5)); +``` + +In this example, when `mutator.Mutate()` is called, we will assign 5 to the +`int` variable pointed to by argument #1 (0-based). + +`SetArgPointee()` conveniently makes an internal copy of the value you pass to +it, removing the need to keep the value in scope and alive. The implication +however is that the value must have a copy constructor and assignment operator. + +If the mock method also needs to return a value as well, you can chain +`SetArgPointee()` with `Return()` using `DoAll()`, remembering to put the +`Return()` statement last: + +```cpp +using ::testing::_; +using ::testing::Return; +using ::testing::SetArgPointee; + +class MockMutator : public Mutator { + public: + ... + MOCK_METHOD(bool, MutateInt, (int* value), (override)); +} +... + MockMutator mutator; + EXPECT_CALL(mutator, MutateInt(_)) + .WillOnce(DoAll(SetArgPointee<0>(5), + Return(true))); +``` + +Note, however, that if you use the `ReturnOKWith()` method, it will override the +values provided by `SetArgPointee()` in the response parameters of your function +call. + +If the output argument is an array, use the `SetArrayArgument(first, last)` +action instead. It copies the elements in source range `[first, last)` to the +array pointed to by the `N`-th (0-based) argument: + +```cpp +using ::testing::NotNull; +using ::testing::SetArrayArgument; + +class MockArrayMutator : public ArrayMutator { + public: + MOCK_METHOD(void, Mutate, (int* values, int num_values), (override)); + ... +} +... + MockArrayMutator mutator; + int values[5] = {1, 2, 3, 4, 5}; + EXPECT_CALL(mutator, Mutate(NotNull(), 5)) + .WillOnce(SetArrayArgument<0>(values, values + 5)); +``` + +This also works when the argument is an output iterator: + +```cpp +using ::testing::_; +using ::testing::SetArrayArgument; + +class MockRolodex : public Rolodex { + public: + MOCK_METHOD(void, GetNames, (std::back_insert_iterator>), + (override)); + ... +} +... + MockRolodex rolodex; + vector names; + names.push_back("George"); + names.push_back("John"); + names.push_back("Thomas"); + EXPECT_CALL(rolodex, GetNames(_)) + .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); +``` + +### Changing a Mock Object's Behavior Based on the State + +If you expect a call to change the behavior of a mock object, you can use +`::testing::InSequence` to specify different behaviors before and after the +call: + +```cpp +using ::testing::InSequence; +using ::testing::Return; + +... + { + InSequence seq; + EXPECT_CALL(my_mock, IsDirty()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(my_mock, Flush()); + EXPECT_CALL(my_mock, IsDirty()) + .WillRepeatedly(Return(false)); + } + my_mock.FlushIfDirty(); +``` + +This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called +and return `false` afterwards. + +If the behavior change is more complex, you can store the effects in a variable +and make a mock method get its return value from that variable: + +```cpp +using ::testing::_; +using ::testing::SaveArg; +using ::testing::Return; + +ACTION_P(ReturnPointee, p) { return *p; } +... + int previous_value = 0; + EXPECT_CALL(my_mock, GetPrevValue) + .WillRepeatedly(ReturnPointee(&previous_value)); + EXPECT_CALL(my_mock, UpdateValue) + .WillRepeatedly(SaveArg<0>(&previous_value)); + my_mock.DoSomethingToUpdateValue(); +``` + +Here `my_mock.GetPrevValue()` will always return the argument of the last +`UpdateValue()` call. + +### Setting the Default Value for a Return Type {#DefaultValue} + +If a mock method's return type is a built-in C++ type or pointer, by default it +will return 0 when invoked. Also, in C++ 11 and above, a mock method whose +return type has a default constructor will return a default-constructed value by +default. You only need to specify an action if this default value doesn't work +for you. + +Sometimes, you may want to change this default value, or you may want to specify +a default value for types gMock doesn't know about. You can do this using the +`::testing::DefaultValue` class template: + +```cpp +using ::testing::DefaultValue; + +class MockFoo : public Foo { + public: + MOCK_METHOD(Bar, CalculateBar, (), (override)); +}; + + +... + Bar default_bar; + // Sets the default return value for type Bar. + DefaultValue::Set(default_bar); + + MockFoo foo; + + // We don't need to specify an action here, as the default + // return value works for us. + EXPECT_CALL(foo, CalculateBar()); + + foo.CalculateBar(); // This should return default_bar. + + // Unsets the default return value. + DefaultValue::Clear(); +``` + +Please note that changing the default value for a type can make you tests hard +to understand. We recommend you to use this feature judiciously. For example, +you may want to make sure the `Set()` and `Clear()` calls are right next to the +code that uses your mock. + +### Setting the Default Actions for a Mock Method + +You've learned how to change the default value of a given type. However, this +may be too coarse for your purpose: perhaps you have two mock methods with the +same return type and you want them to have different behaviors. The `ON_CALL()` +macro allows you to customize your mock's behavior at the method level: + +```cpp +using ::testing::_; +using ::testing::AnyNumber; +using ::testing::Gt; +using ::testing::Return; +... + ON_CALL(foo, Sign(_)) + .WillByDefault(Return(-1)); + ON_CALL(foo, Sign(0)) + .WillByDefault(Return(0)); + ON_CALL(foo, Sign(Gt(0))) + .WillByDefault(Return(1)); + + EXPECT_CALL(foo, Sign(_)) + .Times(AnyNumber()); + + foo.Sign(5); // This should return 1. + foo.Sign(-9); // This should return -1. + foo.Sign(0); // This should return 0. +``` + +As you may have guessed, when there are more than one `ON_CALL()` statements, +the newer ones in the order take precedence over the older ones. In other words, +the **last** one that matches the function arguments will be used. This matching +order allows you to set up the common behavior in a mock object's constructor or +the test fixture's set-up phase and specialize the mock's behavior later. + +Note that both `ON_CALL` and `EXPECT_CALL` have the same "later statements take +precedence" rule, but they don't interact. That is, `EXPECT_CALL`s have their +own precedence order distinct from the `ON_CALL` precedence order. + +### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions} + +If the built-in actions don't suit you, you can use an existing callable +(function, `std::function`, method, functor, lambda as an action. + + + +```cpp +using ::testing::_; using ::testing::Invoke; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, Sum, (int x, int y), (override)); + MOCK_METHOD(bool, ComplexJob, (int x), (override)); +}; + +int CalculateSum(int x, int y) { return x + y; } +int Sum3(int x, int y, int z) { return x + y + z; } + +class Helper { + public: + bool ComplexJob(int x); +}; + +... + MockFoo foo; + Helper helper; + EXPECT_CALL(foo, Sum(_, _)) + .WillOnce(&CalculateSum) + .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1))); + EXPECT_CALL(foo, ComplexJob(_)) + .WillOnce(Invoke(&helper, &Helper::ComplexJob)); + .WillRepeatedly([](int x) { return x > 0; }); + + foo.Sum(5, 6); // Invokes CalculateSum(5, 6). + foo.Sum(2, 3); // Invokes Sum3(1, 2, 3). + foo.ComplexJob(10); // Invokes helper.ComplexJob(10). + foo.ComplexJob(-1); // Invokes the inline lambda. +``` + +The only requirement is that the type of the function, etc must be *compatible* +with the signature of the mock function, meaning that the latter's arguments can +be implicitly converted to the corresponding arguments of the former, and the +former's return type can be implicitly converted to that of the latter. So, you +can invoke something whose type is *not* exactly the same as the mock function, +as long as it's safe to do so - nice, huh? + +**`Note:`{.escaped}** + +* The action takes ownership of the callback and will delete it when the + action itself is destructed. +* If the type of a callback is derived from a base callback type `C`, you need + to implicitly cast it to `C` to resolve the overloading, e.g. + + ```cpp + using ::testing::Invoke; + ... + ResultCallback* is_ok = ...; + ... Invoke(is_ok) ...; // This works. + + BlockingClosure* done = new BlockingClosure; + ... Invoke(implicit_cast(done)) ...; // The cast is necessary. + ``` + +### Using Functions with Extra Info as Actions + +The function or functor you call using `Invoke()` must have the same number of +arguments as the mock function you use it for. Sometimes you may have a function +that takes more arguments, and you are willing to pass in the extra arguments +yourself to fill the gap. You can do this in gMock using callbacks with +pre-bound arguments. Here's an example: + +```cpp +using ::testing::Invoke; + +class MockFoo : public Foo { + public: + MOCK_METHOD(char, DoThis, (int n), (override)); +}; + +char SignOfSum(int x, int y) { + const int sum = x + y; + return (sum > 0) ? '+' : (sum < 0) ? '-' : '0'; +} + +TEST_F(FooTest, Test) { + MockFoo foo; + + EXPECT_CALL(foo, DoThis(2)) + .WillOnce(Invoke(NewPermanentCallback(SignOfSum, 5))); + EXPECT_EQ('+', foo.DoThis(2)); // Invokes SignOfSum(5, 2). +} +``` + +### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments + +`Invoke()` is very useful for doing actions that are more complex. It passes the +mock function's arguments to the function, etc being invoked such that the +callee has the full context of the call to work with. If the invoked function is +not interested in some or all of the arguments, it can simply ignore them. + +Yet, a common pattern is that a test author wants to invoke a function without +the arguments of the mock function. `Invoke()` allows her to do that using a +wrapper function that throws away the arguments before invoking an underlining +nullary function. Needless to say, this can be tedious and obscures the intent +of the test. + +`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except that it +doesn't pass the mock function's arguments to the callee. Here's an example: + +```cpp +using ::testing::_; +using ::testing::InvokeWithoutArgs; + +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, ComplexJob, (int n), (override)); +}; + +bool Job1() { ... } +bool Job2(int n, char c) { ... } + +... + MockFoo foo; + EXPECT_CALL(foo, ComplexJob(_)) + .WillOnce(InvokeWithoutArgs(Job1)) + .WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a'))); + + foo.ComplexJob(10); // Invokes Job1(). + foo.ComplexJob(20); // Invokes Job2(5, 'a'). +``` + +**`Note:`{.escaped}** + +* The action takes ownership of the callback and will delete it when the + action itself is destructed. +* If the type of a callback is derived from a base callback type `C`, you need + to implicitly cast it to `C` to resolve the overloading, e.g. + + ```cpp + using ::testing::InvokeWithoutArgs; + ... + ResultCallback* is_ok = ...; + ... InvokeWithoutArgs(is_ok) ...; // This works. + + BlockingClosure* done = ...; + ... InvokeWithoutArgs(implicit_cast(done)) ...; + // The cast is necessary. + ``` + +### Invoking an Argument of the Mock Function + +Sometimes a mock function will receive a function pointer, a functor (in other +words, a "callable") as an argument, e.g. + +```cpp +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, DoThis, (int n, (ResultCallback1* callback)), + (override)); +}; +``` + +and you may want to invoke this callable argument: + +```cpp +using ::testing::_; +... + MockFoo foo; + EXPECT_CALL(foo, DoThis(_, _)) + .WillOnce(...); + // Will execute callback->Run(5), where callback is the + // second argument DoThis() receives. +``` + +NOTE: The section below is legacy documentation from before C++ had lambdas: + +Arghh, you need to refer to a mock function argument but C++ has no lambda +(yet), so you have to define your own action. :-( Or do you really? + +Well, gMock has an action to solve *exactly* this problem: + +```cpp +InvokeArgument(arg_1, arg_2, ..., arg_m) +``` + +will invoke the `N`-th (0-based) argument the mock function receives, with +`arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is a function +pointer, a functor, or a callback. gMock handles them all. + +With that, you could write: + +```cpp +using ::testing::_; +using ::testing::InvokeArgument; +... + EXPECT_CALL(foo, DoThis(_, _)) + .WillOnce(InvokeArgument<1>(5)); + // Will execute callback->Run(5), where callback is the + // second argument DoThis() receives. +``` + +What if the callable takes an argument by reference? No problem - just wrap it +inside `ByRef()`: + +```cpp + ... + MOCK_METHOD(bool, Bar, + ((ResultCallback2* callback)), + (override)); + ... + using ::testing::_; + using ::testing::ByRef; + using ::testing::InvokeArgument; + ... + MockFoo foo; + Helper helper; + ... + EXPECT_CALL(foo, Bar(_)) + .WillOnce(InvokeArgument<0>(5, ByRef(helper))); + // ByRef(helper) guarantees that a reference to helper, not a copy of it, + // will be passed to the callback. +``` + +What if the callable takes an argument by reference and we do **not** wrap the +argument in `ByRef()`? Then `InvokeArgument()` will *make a copy* of the +argument, and pass a *reference to the copy*, instead of a reference to the +original value, to the callable. This is especially handy when the argument is a +temporary value: + +```cpp + ... + MOCK_METHOD(bool, DoThat, (bool (*f)(const double& x, const string& s)), + (override)); + ... + using ::testing::_; + using ::testing::InvokeArgument; + ... + MockFoo foo; + ... + EXPECT_CALL(foo, DoThat(_)) + .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); + // Will execute (*f)(5.0, string("Hi")), where f is the function pointer + // DoThat() receives. Note that the values 5.0 and string("Hi") are + // temporary and dead once the EXPECT_CALL() statement finishes. Yet + // it's fine to perform this action later, since a copy of the values + // are kept inside the InvokeArgument action. +``` + +### Ignoring an Action's Result + +Sometimes you have an action that returns *something*, but you need an action +that returns `void` (perhaps you want to use it in a mock function that returns +`void`, or perhaps it needs to be used in `DoAll()` and it's not the last in the +list). `IgnoreResult()` lets you do that. For example: + +```cpp +using ::testing::_; +using ::testing::DoAll; +using ::testing::IgnoreResult; +using ::testing::Return; + +int Process(const MyData& data); +string DoSomething(); + +class MockFoo : public Foo { + public: + MOCK_METHOD(void, Abc, (const MyData& data), (override)); + MOCK_METHOD(bool, Xyz, (), (override)); +}; + + ... + MockFoo foo; + EXPECT_CALL(foo, Abc(_)) + // .WillOnce(Invoke(Process)); + // The above line won't compile as Process() returns int but Abc() needs + // to return void. + .WillOnce(IgnoreResult(Process)); + EXPECT_CALL(foo, Xyz()) + .WillOnce(DoAll(IgnoreResult(DoSomething), + // Ignores the string DoSomething() returns. + Return(true))); +``` + +Note that you **cannot** use `IgnoreResult()` on an action that already returns +`void`. Doing so will lead to ugly compiler errors. + +### Selecting an Action's Arguments {#SelectingArgs} + +Say you have a mock function `Foo()` that takes seven arguments, and you have a +custom action that you want to invoke when `Foo()` is called. Trouble is, the +custom action only wants three arguments: + +```cpp +using ::testing::_; +using ::testing::Invoke; +... + MOCK_METHOD(bool, Foo, + (bool visible, const string& name, int x, int y, + (const map>), double& weight, double min_weight, + double max_wight)); +... +bool IsVisibleInQuadrant1(bool visible, int x, int y) { + return visible && x >= 0 && y >= 0; +} +... + EXPECT_CALL(mock, Foo) + .WillOnce(Invoke(IsVisibleInQuadrant1)); // Uh, won't compile. :-( +``` + +To please the compiler God, you need to define an "adaptor" that has the same +signature as `Foo()` and calls the custom action with the right arguments: + +```cpp +using ::testing::_; +using ::testing::Invoke; +... +bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, + const map, double>& weight, + double min_weight, double max_wight) { + return IsVisibleInQuadrant1(visible, x, y); +} +... + EXPECT_CALL(mock, Foo) + .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // Now it works. +``` + +But isn't this awkward? + +gMock provides a generic *action adaptor*, so you can spend your time minding +more important business than writing your own adaptors. Here's the syntax: + +```cpp +WithArgs(action) +``` + +creates an action that passes the arguments of the mock function at the given +indices (0-based) to the inner `action` and performs it. Using `WithArgs`, our +original example can be written as: + +```cpp +using ::testing::_; +using ::testing::Invoke; +using ::testing::WithArgs; +... + EXPECT_CALL(mock, Foo) + .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); // No need to define your own adaptor. +``` + +For better readability, gMock also gives you: + +* `WithoutArgs(action)` when the inner `action` takes *no* argument, and +* `WithArg(action)` (no `s` after `Arg`) when the inner `action` takes + *one* argument. + +As you may have realized, `InvokeWithoutArgs(...)` is just syntactic sugar for +`WithoutArgs(Invoke(...))`. + +Here are more tips: + +* The inner action used in `WithArgs` and friends does not have to be + `Invoke()` -- it can be anything. +* You can repeat an argument in the argument list if necessary, e.g. + `WithArgs<2, 3, 3, 5>(...)`. +* You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`. +* The types of the selected arguments do *not* have to match the signature of + the inner action exactly. It works as long as they can be implicitly + converted to the corresponding arguments of the inner action. For example, + if the 4-th argument of the mock function is an `int` and `my_action` takes + a `double`, `WithArg<4>(my_action)` will work. + +### Ignoring Arguments in Action Functions + +The [selecting-an-action's-arguments](#SelectingArgs) recipe showed us one way +to make a mock function and an action with incompatible argument lists fit +together. The downside is that wrapping the action in `WithArgs<...>()` can get +tedious for people writing the tests. + +If you are defining a function (or method, functor, lambda, callback) to be used +with `Invoke*()`, and you are not interested in some of its arguments, an +alternative to `WithArgs` is to declare the uninteresting arguments as `Unused`. +This makes the definition less cluttered and less fragile in case the types of +the uninteresting arguments change. It could also increase the chance the action +function can be reused. For example, given + +```cpp + public: + MOCK_METHOD(double, Foo, double(const string& label, double x, double y), + (override)); + MOCK_METHOD(double, Bar, (int index, double x, double y), (override)); +``` + +instead of + +```cpp +using ::testing::_; +using ::testing::Invoke; + +double DistanceToOriginWithLabel(const string& label, double x, double y) { + return sqrt(x*x + y*y); +} +double DistanceToOriginWithIndex(int index, double x, double y) { + return sqrt(x*x + y*y); +} +... + EXPECT_CALL(mock, Foo("abc", _, _)) + .WillOnce(Invoke(DistanceToOriginWithLabel)); + EXPECT_CALL(mock, Bar(5, _, _)) + .WillOnce(Invoke(DistanceToOriginWithIndex)); +``` + +you could write + +```cpp +using ::testing::_; +using ::testing::Invoke; +using ::testing::Unused; + +double DistanceToOrigin(Unused, double x, double y) { + return sqrt(x*x + y*y); +} +... + EXPECT_CALL(mock, Foo("abc", _, _)) + .WillOnce(Invoke(DistanceToOrigin)); + EXPECT_CALL(mock, Bar(5, _, _)) + .WillOnce(Invoke(DistanceToOrigin)); +``` + +### Sharing Actions + +Just like matchers, a gMock action object consists of a pointer to a ref-counted +implementation object. Therefore copying actions is also allowed and very +efficient. When the last action that references the implementation object dies, +the implementation object will be deleted. + +If you have some complex action that you want to use again and again, you may +not have to build it from scratch everytime. If the action doesn't have an +internal state (i.e. if it always does the same thing no matter how many times +it has been called), you can assign it to an action variable and use that +variable repeatedly. For example: + +```cpp +using ::testing::Action; +using ::testing::DoAll; +using ::testing::Return; +using ::testing::SetArgPointee; +... + Action set_flag = DoAll(SetArgPointee<0>(5), + Return(true)); + ... use set_flag in .WillOnce() and .WillRepeatedly() ... +``` + +However, if the action has its own state, you may be surprised if you share the +action object. Suppose you have an action factory `IncrementCounter(init)` which +creates an action that increments and returns a counter whose initial value is +`init`, using two actions created from the same expression and using a shared +action will exhibit different behaviors. Example: + +```cpp + EXPECT_CALL(foo, DoThis()) + .WillRepeatedly(IncrementCounter(0)); + EXPECT_CALL(foo, DoThat()) + .WillRepeatedly(IncrementCounter(0)); + foo.DoThis(); // Returns 1. + foo.DoThis(); // Returns 2. + foo.DoThat(); // Returns 1 - Blah() uses a different + // counter than Bar()'s. +``` + +versus + +```cpp +using ::testing::Action; +... + Action increment = IncrementCounter(0); + EXPECT_CALL(foo, DoThis()) + .WillRepeatedly(increment); + EXPECT_CALL(foo, DoThat()) + .WillRepeatedly(increment); + foo.DoThis(); // Returns 1. + foo.DoThis(); // Returns 2. + foo.DoThat(); // Returns 3 - the counter is shared. +``` + +### Testing Asynchronous Behavior + +One oft-encountered problem with gMock is that it can be hard to test +asynchronous behavior. Suppose you had a `EventQueue` class that you wanted to +test, and you created a separate `EventDispatcher` interface so that you could +easily mock it out. However, the implementation of the class fired all the +events on a background thread, which made test timings difficult. You could just +insert `sleep()` statements and hope for the best, but that makes your test +behavior nondeterministic. A better way is to use gMock actions and +`Notification` objects to force your asynchronous test to behave synchronously. + +```cpp +using ::testing::DoAll; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +class MockEventDispatcher : public EventDispatcher { + MOCK_METHOD(bool, DispatchEvent, (int32), (override)); +}; + +ACTION_P(Notify, notification) { + notification->Notify(); +} + +TEST(EventQueueTest, EnqueueEventTest) { + MockEventDispatcher mock_event_dispatcher; + EventQueue event_queue(&mock_event_dispatcher); + + const int32 kEventId = 321; + Notification done; + EXPECT_CALL(mock_event_dispatcher, DispatchEvent(kEventId)) + .WillOnce(Notify(&done)); + + event_queue.EnqueueEvent(kEventId); + done.WaitForNotification(); +} +``` + +In the example above, we set our normal gMock expectations, but then add an +additional action to notify the `Notification` object. Now we can just call +`Notification::WaitForNotification()` in the main thread to wait for the +asynchronous call to finish. After that, our test suite is complete and we can +safely exit. + +Note: this example has a downside: namely, if the expectation is not satisfied, +our test will run forever. It will eventually time-out and fail, but it will +take longer and be slightly harder to debug. To alleviate this problem, you can +use `WaitForNotificationWithTimeout(ms)` instead of `WaitForNotification()`. + +## Misc Recipes on Using gMock + +### Mocking Methods That Use Move-Only Types + +C++11 introduced *move-only types*. A move-only-typed value can be moved from +one object to another, but cannot be copied. `std::unique_ptr` is probably +the most commonly used move-only type. + +Mocking a method that takes and/or returns move-only types presents some +challenges, but nothing insurmountable. This recipe shows you how you can do it. +Note that the support for move-only method arguments was only introduced to +gMock in April 2017; in older code, you may find more complex +[workarounds](#LegacyMoveOnly) for lack of this feature. + +Let’s say we are working on a fictional project that lets one post and share +snippets called “buzzesâ€. Your code uses these types: + +```cpp +enum class AccessLevel { kInternal, kPublic }; + +class Buzz { + public: + explicit Buzz(AccessLevel access) { ... } + ... +}; + +class Buzzer { + public: + virtual ~Buzzer() {} + virtual std::unique_ptr MakeBuzz(StringPiece text) = 0; + virtual bool ShareBuzz(std::unique_ptr buzz, int64_t timestamp) = 0; + ... +}; +``` + +A `Buzz` object represents a snippet being posted. A class that implements the +`Buzzer` interface is capable of creating and sharing `Buzz`es. Methods in +`Buzzer` may return a `unique_ptr` or take a `unique_ptr`. Now we +need to mock `Buzzer` in our tests. + +To mock a method that accepts or returns move-only types, you just use the +familiar `MOCK_METHOD` syntax as usual: + +```cpp +class MockBuzzer : public Buzzer { + public: + MOCK_METHOD(std::unique_ptr, MakeBuzz, (StringPiece text), (override)); + MOCK_METHOD(bool, ShareBuzz, (std::unique_ptr buzz, int64_t timestamp), + (override)); +}; +``` + +Now that we have the mock class defined, we can use it in tests. In the +following code examples, we assume that we have defined a `MockBuzzer` object +named `mock_buzzer_`: + +```cpp + MockBuzzer mock_buzzer_; +``` + +First let’s see how we can set expectations on the `MakeBuzz()` method, which +returns a `unique_ptr`. + +As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or +`.WillRepeatedly()` clause), when that expectation fires, the default action for +that method will be taken. Since `unique_ptr<>` has a default constructor that +returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an +action: + +```cpp + // Use the default action. + EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")); + + // Triggers the previous EXPECT_CALL. + EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello")); +``` + +If you are not happy with the default action, you can tweak it as usual; see +[Setting Default Actions](#OnCall). + +If you just need to return a pre-defined move-only value, you can use the +`Return(ByMove(...))` action: + +```cpp + // When this fires, the unique_ptr<> specified by ByMove(...) will + // be returned. + EXPECT_CALL(mock_buzzer_, MakeBuzz("world")) + .WillOnce(Return(ByMove(MakeUnique(AccessLevel::kInternal)))); + + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world")); +``` + +Note that `ByMove()` is essential here - if you drop it, the code won’t compile. + +Quiz time! What do you think will happen if a `Return(ByMove(...))` action is +performed more than once (e.g. you write `... +.WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time +the action runs, the source value will be consumed (since it’s a move-only +value), so the next time around, there’s no value to move from -- you’ll get a +run-time error that `Return(ByMove(...))` can only be run once. + +If you need your mock method to do more than just moving a pre-defined value, +remember that you can always use a lambda or a callable object, which can do +pretty much anything you want: + +```cpp + EXPECT_CALL(mock_buzzer_, MakeBuzz("x")) + .WillRepeatedly([](StringPiece text) { + return MakeUnique(AccessLevel::kInternal); + }); + + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); +``` + +Every time this `EXPECT_CALL` fires, a new `unique_ptr` will be created +and returned. You cannot do this with `Return(ByMove(...))`. + +That covers returning move-only values; but how do we work with methods +accepting move-only arguments? The answer is that they work normally, although +some actions will not compile when any of method's arguments are move-only. You +can always use `Return`, or a [lambda or functor](#FunctionsAsActions): + +```cpp + using ::testing::Unused; + + EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)).WillOnce(Return(true)); + EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal)), + 0); + + EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce( + [](std::unique_ptr buzz, Unused) { return buzz != nullptr; }); + EXPECT_FALSE(mock_buzzer_.ShareBuzz(nullptr, 0)); +``` + +Many built-in actions (`WithArgs`, `WithoutArgs`,`DeleteArg`, `SaveArg`, ...) +could in principle support move-only arguments, but the support for this is not +implemented yet. If this is blocking you, please file a bug. + +A few actions (e.g. `DoAll`) copy their arguments internally, so they can never +work with non-copyable objects; you'll have to use functors instead. + +#### Legacy workarounds for move-only types {#LegacyMoveOnly} + +Support for move-only function arguments was only introduced to gMock in April +2017. In older code, you may encounter the following workaround for the lack of +this feature (it is no longer necessary - we're including it just for +reference): + +```cpp +class MockBuzzer : public Buzzer { + public: + MOCK_METHOD(bool, DoShareBuzz, (Buzz* buzz, Time timestamp)); + bool ShareBuzz(std::unique_ptr buzz, Time timestamp) override { + return DoShareBuzz(buzz.get(), timestamp); + } +}; +``` + +The trick is to delegate the `ShareBuzz()` method to a mock method (let’s call +it `DoShareBuzz()`) that does not take move-only parameters. Then, instead of +setting expectations on `ShareBuzz()`, you set them on the `DoShareBuzz()` mock +method: + +```cpp + MockBuzzer mock_buzzer_; + EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)); + + // When one calls ShareBuzz() on the MockBuzzer like this, the call is + // forwarded to DoShareBuzz(), which is mocked. Therefore this statement + // will trigger the above EXPECT_CALL. + mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal), 0); +``` + +### Making the Compilation Faster + +Believe it or not, the *vast majority* of the time spent on compiling a mock +class is in generating its constructor and destructor, as they perform +non-trivial tasks (e.g. verification of the expectations). What's more, mock +methods with different signatures have different types and thus their +constructors/destructors need to be generated by the compiler separately. As a +result, if you mock many different types of methods, compiling your mock class +can get really slow. + +If you are experiencing slow compilation, you can move the definition of your +mock class' constructor and destructor out of the class body and into a `.cc` +file. This way, even if you `#include` your mock class in N files, the compiler +only needs to generate its constructor and destructor once, resulting in a much +faster compilation. + +Let's illustrate the idea using an example. Here's the definition of a mock +class before applying this recipe: + +```cpp +// File mock_foo.h. +... +class MockFoo : public Foo { + public: + // Since we don't declare the constructor or the destructor, + // the compiler will generate them in every translation unit + // where this mock class is used. + + MOCK_METHOD(int, DoThis, (), (override)); + MOCK_METHOD(bool, DoThat, (const char* str), (override)); + ... more mock methods ... +}; +``` + +After the change, it would look like: + +```cpp +// File mock_foo.h. +... +class MockFoo : public Foo { + public: + // The constructor and destructor are declared, but not defined, here. + MockFoo(); + virtual ~MockFoo(); + + MOCK_METHOD(int, DoThis, (), (override)); + MOCK_METHOD(bool, DoThat, (const char* str), (override)); + ... more mock methods ... +}; +``` + +and + +```cpp +// File mock_foo.cc. +#include "path/to/mock_foo.h" + +// The definitions may appear trivial, but the functions actually do a +// lot of things through the constructors/destructors of the member +// variables used to implement the mock methods. +MockFoo::MockFoo() {} +MockFoo::~MockFoo() {} +``` + +### Forcing a Verification + +When it's being destroyed, your friendly mock object will automatically verify +that all expectations on it have been satisfied, and will generate googletest +failures if not. This is convenient as it leaves you with one less thing to +worry about. That is, unless you are not sure if your mock object will be +destroyed. + +How could it be that your mock object won't eventually be destroyed? Well, it +might be created on the heap and owned by the code you are testing. Suppose +there's a bug in that code and it doesn't delete the mock object properly - you +could end up with a passing test when there's actually a bug. + +Using a heap checker is a good idea and can alleviate the concern, but its +implementation is not 100% reliable. So, sometimes you do want to *force* gMock +to verify a mock object before it is (hopefully) destructed. You can do this +with `Mock::VerifyAndClearExpectations(&mock_object)`: + +```cpp +TEST(MyServerTest, ProcessesRequest) { + using ::testing::Mock; + + MockFoo* const foo = new MockFoo; + EXPECT_CALL(*foo, ...)...; + // ... other expectations ... + + // server now owns foo. + MyServer server(foo); + server.ProcessRequest(...); + + // In case that server's destructor will forget to delete foo, + // this will verify the expectations anyway. + Mock::VerifyAndClearExpectations(foo); +} // server is destroyed when it goes out of scope here. +``` + +**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a `bool` to +indicate whether the verification was successful (`true` for yes), so you can +wrap that function call inside a `ASSERT_TRUE()` if there is no point going +further when the verification has failed. + +### Using Check Points {#UsingCheckPoints} + +Sometimes you may want to "reset" a mock object at various check points in your +test: at each check point, you verify that all existing expectations on the mock +object have been satisfied, and then you set some new expectations on it as if +it's newly created. This allows you to work with a mock object in "phases" whose +sizes are each manageable. + +One such scenario is that in your test's `SetUp()` function, you may want to put +the object you are testing into a certain state, with the help from a mock +object. Once in the desired state, you want to clear all expectations on the +mock, such that in the `TEST_F` body you can set fresh expectations on it. + +As you may have figured out, the `Mock::VerifyAndClearExpectations()` function +we saw in the previous recipe can help you here. Or, if you are using +`ON_CALL()` to set default actions on the mock object and want to clear the +default actions as well, use `Mock::VerifyAndClear(&mock_object)` instead. This +function does what `Mock::VerifyAndClearExpectations(&mock_object)` does and +returns the same `bool`, **plus** it clears the `ON_CALL()` statements on +`mock_object` too. + +Another trick you can use to achieve the same effect is to put the expectations +in sequences and insert calls to a dummy "check-point" function at specific +places. Then you can verify that the mock function calls do happen at the right +time. For example, if you are exercising code: + +```cpp + Foo(1); + Foo(2); + Foo(3); +``` + +and want to verify that `Foo(1)` and `Foo(3)` both invoke `mock.Bar("a")`, but +`Foo(2)` doesn't invoke anything. You can write: + +```cpp +using ::testing::MockFunction; + +TEST(FooTest, InvokesBarCorrectly) { + MyMock mock; + // Class MockFunction has exactly one mock method. It is named + // Call() and has type F. + MockFunction check; + { + InSequence s; + + EXPECT_CALL(mock, Bar("a")); + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(mock, Bar("a")); + } + Foo(1); + check.Call("1"); + Foo(2); + check.Call("2"); + Foo(3); +} +``` + +The expectation spec says that the first `Bar("a")` must happen before check +point "1", the second `Bar("a")` must happen after check point "2", and nothing +should happen between the two check points. The explicit check points make it +easy to tell which `Bar("a")` is called by which call to `Foo()`. + +### Mocking Destructors + +Sometimes you want to make sure a mock object is destructed at the right time, +e.g. after `bar->A()` is called but before `bar->B()` is called. We already know +that you can specify constraints on the [order](#OrderedCalls) of mock function +calls, so all we need to do is to mock the destructor of the mock function. + +This sounds simple, except for one problem: a destructor is a special function +with special syntax and special semantics, and the `MOCK_METHOD` macro doesn't +work for it: + +```cpp +MOCK_METHOD(void, ~MockFoo, ()); // Won't compile! +``` + +The good news is that you can use a simple pattern to achieve the same effect. +First, add a mock function `Die()` to your mock class and call it in the +destructor, like this: + +```cpp +class MockFoo : public Foo { + ... + // Add the following two lines to the mock class. + MOCK_METHOD(void, Die, ()); + virtual ~MockFoo() { Die(); } +}; +``` + +(If the name `Die()` clashes with an existing symbol, choose another name.) Now, +we have translated the problem of testing when a `MockFoo` object dies to +testing when its `Die()` method is called: + +```cpp + MockFoo* foo = new MockFoo; + MockBar* bar = new MockBar; + ... + { + InSequence s; + + // Expects *foo to die after bar->A() and before bar->B(). + EXPECT_CALL(*bar, A()); + EXPECT_CALL(*foo, Die()); + EXPECT_CALL(*bar, B()); + } +``` + +And that's that. + +### Using gMock and Threads {#UsingThreads} + +In a **unit** test, it's best if you could isolate and test a piece of code in a +single-threaded context. That avoids race conditions and dead locks, and makes +debugging your test much easier. + +Yet most programs are multi-threaded, and sometimes to test something we need to +pound on it from more than one thread. gMock works for this purpose too. + +Remember the steps for using a mock: + +1. Create a mock object `foo`. +2. Set its default actions and expectations using `ON_CALL()` and + `EXPECT_CALL()`. +3. The code under test calls methods of `foo`. +4. Optionally, verify and reset the mock. +5. Destroy the mock yourself, or let the code under test destroy it. The + destructor will automatically verify it. + +If you follow the following simple rules, your mocks and threads can live +happily together: + +* Execute your *test code* (as opposed to the code being tested) in *one* + thread. This makes your test easy to follow. +* Obviously, you can do step #1 without locking. +* When doing step #2 and #5, make sure no other thread is accessing `foo`. + Obvious too, huh? +* #3 and #4 can be done either in one thread or in multiple threads - anyway + you want. gMock takes care of the locking, so you don't have to do any - + unless required by your test logic. + +If you violate the rules (for example, if you set expectations on a mock while +another thread is calling its methods), you get undefined behavior. That's not +fun, so don't do it. + +gMock guarantees that the action for a mock function is done in the same thread +that called the mock function. For example, in + +```cpp + EXPECT_CALL(mock, Foo(1)) + .WillOnce(action1); + EXPECT_CALL(mock, Foo(2)) + .WillOnce(action2); +``` + +if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, gMock will +execute `action1` in thread 1 and `action2` in thread 2. + +gMock does *not* impose a sequence on actions performed in different threads +(doing so may create deadlocks as the actions may need to cooperate). This means +that the execution of `action1` and `action2` in the above example *may* +interleave. If this is a problem, you should add proper synchronization logic to +`action1` and `action2` to make the test thread-safe. + +Also, remember that `DefaultValue` is a global resource that potentially +affects *all* living mock objects in your program. Naturally, you won't want to +mess with it from multiple threads or when there still are mocks in action. + +### Controlling How Much Information gMock Prints + +When gMock sees something that has the potential of being an error (e.g. a mock +function with no expectation is called, a.k.a. an uninteresting call, which is +allowed but perhaps you forgot to explicitly ban the call), it prints some +warning messages, including the arguments of the function, the return value, and +the stack trace. Hopefully this will remind you to take a look and see if there +is indeed a problem. + +Sometimes you are confident that your tests are correct and may not appreciate +such friendly messages. Some other times, you are debugging your tests or +learning about the behavior of the code you are testing, and wish you could +observe every mock call that happens (including argument values, the return +value, and the stack trace). Clearly, one size doesn't fit all. + +You can control how much gMock tells you using the `--gmock_verbose=LEVEL` +command-line flag, where `LEVEL` is a string with three possible values: + +* `info`: gMock will print all informational messages, warnings, and errors + (most verbose). At this setting, gMock will also log any calls to the + `ON_CALL/EXPECT_CALL` macros. It will include a stack trace in + "uninteresting call" warnings. +* `warning`: gMock will print both warnings and errors (less verbose); it will + omit the stack traces in "uninteresting call" warnings. This is the default. +* `error`: gMock will print errors only (least verbose). + +Alternatively, you can adjust the value of that flag from within your tests like +so: + +```cpp + ::testing::FLAGS_gmock_verbose = "error"; +``` + +If you find gMock printing too many stack frames with its informational or +warning messages, remember that you can control their amount with the +`--gtest_stack_trace_depth=max_depth` flag. + +Now, judiciously use the right flag to enable gMock serve you better! + +### Gaining Super Vision into Mock Calls + +You have a test using gMock. It fails: gMock tells you some expectations aren't +satisfied. However, you aren't sure why: Is there a typo somewhere in the +matchers? Did you mess up the order of the `EXPECT_CALL`s? Or is the code under +test doing something wrong? How can you find out the cause? + +Won't it be nice if you have X-ray vision and can actually see the trace of all +`EXPECT_CALL`s and mock method calls as they are made? For each call, would you +like to see its actual argument values and which `EXPECT_CALL` gMock thinks it +matches? If you still need some help to figure out who made these calls, how +about being able to see the complete stack trace at each mock call? + +You can unlock this power by running your test with the `--gmock_verbose=info` +flag. For example, given the test program: + +```cpp +#include "gmock/gmock.h" + +using testing::_; +using testing::HasSubstr; +using testing::Return; + +class MockFoo { + public: + MOCK_METHOD(void, F, (const string& x, const string& y)); +}; + +TEST(Foo, Bar) { + MockFoo mock; + EXPECT_CALL(mock, F(_, _)).WillRepeatedly(Return()); + EXPECT_CALL(mock, F("a", "b")); + EXPECT_CALL(mock, F("c", HasSubstr("d"))); + + mock.F("a", "good"); + mock.F("a", "b"); +} +``` + +if you run it with `--gmock_verbose=info`, you will see this output: + +```shell +[ RUN ] Foo.Bar + +foo_test.cc:14: EXPECT_CALL(mock, F(_, _)) invoked +Stack trace: ... + +foo_test.cc:15: EXPECT_CALL(mock, F("a", "b")) invoked +Stack trace: ... + +foo_test.cc:16: EXPECT_CALL(mock, F("c", HasSubstr("d"))) invoked +Stack trace: ... + +foo_test.cc:14: Mock function call matches EXPECT_CALL(mock, F(_, _))... + Function call: F(@0x7fff7c8dad40"a",@0x7fff7c8dad10"good") +Stack trace: ... + +foo_test.cc:15: Mock function call matches EXPECT_CALL(mock, F("a", "b"))... + Function call: F(@0x7fff7c8dada0"a",@0x7fff7c8dad70"b") +Stack trace: ... + +foo_test.cc:16: Failure +Actual function call count doesn't match EXPECT_CALL(mock, F("c", HasSubstr("d")))... + Expected: to be called once + Actual: never called - unsatisfied and active +[ FAILED ] Foo.Bar +``` + +Suppose the bug is that the `"c"` in the third `EXPECT_CALL` is a typo and +should actually be `"a"`. With the above message, you should see that the actual +`F("a", "good")` call is matched by the first `EXPECT_CALL`, not the third as +you thought. From that it should be obvious that the third `EXPECT_CALL` is +written wrong. Case solved. + +If you are interested in the mock call trace but not the stack traces, you can +combine `--gmock_verbose=info` with `--gtest_stack_trace_depth=0` on the test +command line. + + + +### Running Tests in Emacs + +If you build and run your tests in Emacs using the `M-x google-compile` command +(as many googletest users do), the source file locations of gMock and googletest +errors will be highlighted. Just press `` on one of them and you'll be +taken to the offending line. Or, you can just type `C-x`` to jump to the next +error. + +To make it even easier, you can add the following lines to your `~/.emacs` file: + +```text +(global-set-key "\M-m" 'google-compile) ; m is for make +(global-set-key [M-down] 'next-error) +(global-set-key [M-up] '(lambda () (interactive) (next-error -1))) +``` + +Then you can type `M-m` to start a build (if you want to run the test as well, +just make sure `foo_test.run` or `runtests` is in the build command you supply +after typing `M-m`), or `M-up`/`M-down` to move back and forth between errors. + +## Extending gMock + +### Writing New Matchers Quickly {#NewMatchers} + +WARNING: gMock does not guarantee when or how many times a matcher will be +invoked. Therefore, all matchers must be functionally pure. See +[this section](#PureMatchers) for more details. + +The `MATCHER*` family of macros can be used to define custom matchers easily. +The syntax: + +```cpp +MATCHER(name, description_string_expression) { statements; } +``` + +will define a matcher with the given name that executes the statements, which +must return a `bool` to indicate if the match succeeds. Inside the statements, +you can refer to the value being matched by `arg`, and refer to its type by +`arg_type`. + +The *description string* is a `string`-typed expression that documents what the +matcher does, and is used to generate the failure message when the match fails. +It can (and should) reference the special `bool` variable `negation`, and should +evaluate to the description of the matcher when `negation` is `false`, or that +of the matcher's negation when `negation` is `true`. + +For convenience, we allow the description string to be empty (`""`), in which +case gMock will use the sequence of words in the matcher name as the +description. + +For example: + +```cpp +MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } +``` + +allows you to write + +```cpp + // Expects mock_foo.Bar(n) to be called where n is divisible by 7. + EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); +``` + +or, + +```cpp + using ::testing::Not; + ... + // Verifies that two values are divisible by 7. + EXPECT_THAT(some_expression, IsDivisibleBy7()); + EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); +``` + +If the above assertions fail, they will print something like: + +```shell + Value of: some_expression + Expected: is divisible by 7 + Actual: 27 + ... + Value of: some_other_expression + Expected: not (is divisible by 7) + Actual: 21 +``` + +where the descriptions `"is divisible by 7"` and `"not (is divisible by 7)"` are +automatically calculated from the matcher name `IsDivisibleBy7`. + +As you may have noticed, the auto-generated descriptions (especially those for +the negation) may not be so great. You can always override them with a `string` +expression of your own: + +```cpp +MATCHER(IsDivisibleBy7, + absl::StrCat(negation ? "isn't" : "is", " divisible by 7")) { + return (arg % 7) == 0; +} +``` + +Optionally, you can stream additional information to a hidden argument named +`result_listener` to explain the match result. For example, a better definition +of `IsDivisibleBy7` is: + +```cpp +MATCHER(IsDivisibleBy7, "") { + if ((arg % 7) == 0) + return true; + + *result_listener << "the remainder is " << (arg % 7); + return false; +} +``` + +With this definition, the above assertion will give a better message: + +```shell + Value of: some_expression + Expected: is divisible by 7 + Actual: 27 (the remainder is 6) +``` + +You should let `MatchAndExplain()` print *any additional information* that can +help a user understand the match result. Note that it should explain why the +match succeeds in case of a success (unless it's obvious) - this is useful when +the matcher is used inside `Not()`. There is no need to print the argument value +itself, as gMock already prints it for you. + +NOTE: The type of the value being matched (`arg_type`) is determined by the +context in which you use the matcher and is supplied to you by the compiler, so +you don't need to worry about declaring it (nor can you). This allows the +matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match +any type where the value of `(arg % 7) == 0` can be implicitly converted to a +`bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an +`int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will +be `unsigned long`; and so on. + +### Writing New Parameterized Matchers Quickly + +Sometimes you'll want to define a matcher that has parameters. For that you can +use the macro: + +```cpp +MATCHER_P(name, param_name, description_string) { statements; } +``` + +where the description string can be either `""` or a `string` expression that +references `negation` and `param_name`. + +For example: + +```cpp +MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +``` + +will allow you to write: + +```cpp + EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +``` + +which may lead to this message (assuming `n` is 10): + +```shell + Value of: Blah("a") + Expected: has absolute value 10 + Actual: -9 +``` + +Note that both the matcher description and its parameter are printed, making the +message human-friendly. + +In the matcher definition body, you can write `foo_type` to reference the type +of a parameter named `foo`. For example, in the body of +`MATCHER_P(HasAbsoluteValue, value)` above, you can write `value_type` to refer +to the type of `value`. + +gMock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to `MATCHER_P10` to +support multi-parameter matchers: + +```cpp +MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; } +``` + +Please note that the custom description string is for a particular *instance* of +the matcher, where the parameters have been bound to actual values. Therefore +usually you'll want the parameter values to be part of the description. gMock +lets you do that by referencing the matcher parameters in the description string +expression. + +For example, + +```cpp +using ::testing::PrintToString; +MATCHER_P2(InClosedRange, low, hi, + absl::StrFormat("%s in range [%s, %s]", negation ? "isn't" : "is", + PrintToString(low), PrintToString(hi))) { + return low <= arg && arg <= hi; +} +... +EXPECT_THAT(3, InClosedRange(4, 6)); +``` + +would generate a failure that contains the message: + +```shell + Expected: is in range [4, 6] +``` + +If you specify `""` as the description, the failure message will contain the +sequence of words in the matcher name followed by the parameter values printed +as a tuple. For example, + +```cpp + MATCHER_P2(InClosedRange, low, hi, "") { ... } + ... + EXPECT_THAT(3, InClosedRange(4, 6)); +``` + +would generate a failure that contains the text: + +```shell + Expected: in closed range (4, 6) +``` + +For the purpose of typing, you can view + +```cpp +MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +``` + +as shorthand for + +```cpp +template +FooMatcherPk +Foo(p1_type p1, ..., pk_type pk) { ... } +``` + +When you write `Foo(v1, ..., vk)`, the compiler infers the types of the +parameters `v1`, ..., and `vk` for you. If you are not happy with the result of +the type inference, you can specify the types by explicitly instantiating the +template, as in `Foo(5, false)`. As said earlier, you don't get to +(or need to) specify `arg_type` as that's determined by the context in which the +matcher is used. + +You can assign the result of expression `Foo(p1, ..., pk)` to a variable of type +`FooMatcherPk`. This can be useful when composing +matchers. Matchers that don't have a parameter or have only one parameter have +special types: you can assign `Foo()` to a `FooMatcher`-typed variable, and +assign `Foo(p)` to a `FooMatcherP`-typed variable. + +While you can instantiate a matcher template with reference types, passing the +parameters by pointer usually makes your code more readable. If, however, you +still want to pass a parameter by reference, be aware that in the failure +message generated by the matcher you will see the value of the referenced object +but not its address. + +You can overload matchers with different numbers of parameters: + +```cpp +MATCHER_P(Blah, a, description_string_1) { ... } +MATCHER_P2(Blah, a, b, description_string_2) { ... } +``` + +While it's tempting to always use the `MATCHER*` macros when defining a new +matcher, you should also consider implementing `MatcherInterface` or using +`MakePolymorphicMatcher()` instead (see the recipes that follow), especially if +you need to use the matcher a lot. While these approaches require more work, +they give you more control on the types of the value being matched and the +matcher parameters, which in general leads to better compiler error messages +that pay off in the long run. They also allow overloading matchers based on +parameter types (as opposed to just based on the number of parameters). + +### Writing New Monomorphic Matchers + +A matcher of argument type `T` implements `::testing::MatcherInterface` and +does two things: it tests whether a value of type `T` matches the matcher, and +can describe what kind of values it matches. The latter ability is used for +generating readable error messages when expectations are violated. + +The interface looks like this: + +```cpp +class MatchResultListener { + public: + ... + // Streams x to the underlying ostream; does nothing if the ostream + // is NULL. + template + MatchResultListener& operator<<(const T& x); + + // Returns the underlying ostream. + ::std::ostream* stream(); +}; + +template +class MatcherInterface { + public: + virtual ~MatcherInterface(); + + // Returns true if and only if the matcher matches x; also explains the match + // result to 'listener'. + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; + + // Describes this matcher to an ostream. + virtual void DescribeTo(::std::ostream* os) const = 0; + + // Describes the negation of this matcher to an ostream. + virtual void DescribeNegationTo(::std::ostream* os) const; +}; +``` + +If you need a custom matcher but `Truly()` is not a good option (for example, +you may not be happy with the way `Truly(predicate)` describes itself, or you +may want your matcher to be polymorphic as `Eq(value)` is), you can define a +matcher to do whatever you want in two steps: first implement the matcher +interface, and then define a factory function to create a matcher instance. The +second step is not strictly needed but it makes the syntax of using the matcher +nicer. + +For example, you can define a matcher to test whether an `int` is divisible by 7 +and then use it like this: + +```cpp +using ::testing::MakeMatcher; +using ::testing::Matcher; +using ::testing::MatcherInterface; +using ::testing::MatchResultListener; + +class DivisibleBy7Matcher : public MatcherInterface { + public: + bool MatchAndExplain(int n, + MatchResultListener* /* listener */) const override { + return (n % 7) == 0; + } + + void DescribeTo(::std::ostream* os) const override { + *os << "is divisible by 7"; + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "is not divisible by 7"; + } +}; + +Matcher DivisibleBy7() { + return MakeMatcher(new DivisibleBy7Matcher); +} + +... + EXPECT_CALL(foo, Bar(DivisibleBy7())); +``` + +You may improve the matcher message by streaming additional information to the +`listener` argument in `MatchAndExplain()`: + +```cpp +class DivisibleBy7Matcher : public MatcherInterface { + public: + bool MatchAndExplain(int n, + MatchResultListener* listener) const override { + const int remainder = n % 7; + if (remainder != 0) { + *listener << "the remainder is " << remainder; + } + return remainder == 0; + } + ... +}; +``` + +Then, `EXPECT_THAT(x, DivisibleBy7());` may generate a message like this: + +```shell +Value of: x +Expected: is divisible by 7 + Actual: 23 (the remainder is 2) +``` + +### Writing New Polymorphic Matchers + +You've learned how to write your own matchers in the previous recipe. Just one +problem: a matcher created using `MakeMatcher()` only works for one particular +type of arguments. If you want a *polymorphic* matcher that works with arguments +of several types (for instance, `Eq(x)` can be used to match a *`value`* as long +as `value == x` compiles -- *`value`* and `x` don't have to share the same +type), you can learn the trick from `testing/base/public/gmock-matchers.h` but +it's a bit involved. + +Fortunately, most of the time you can define a polymorphic matcher easily with +the help of `MakePolymorphicMatcher()`. Here's how you can define `NotNull()` as +an example: + +```cpp +using ::testing::MakePolymorphicMatcher; +using ::testing::MatchResultListener; +using ::testing::PolymorphicMatcher; + +class NotNullMatcher { + public: + // To implement a polymorphic matcher, first define a COPYABLE class + // that has three members MatchAndExplain(), DescribeTo(), and + // DescribeNegationTo(), like the following. + + // In this example, we want to use NotNull() with any pointer, so + // MatchAndExplain() accepts a pointer of any type as its first argument. + // In general, you can define MatchAndExplain() as an ordinary method or + // a method template, or even overload it. + template + bool MatchAndExplain(T* p, + MatchResultListener* /* listener */) const { + return p != NULL; + } + + // Describes the property of a value matching this matcher. + void DescribeTo(std::ostream* os) const { *os << "is not NULL"; } + + // Describes the property of a value NOT matching this matcher. + void DescribeNegationTo(std::ostream* os) const { *os << "is NULL"; } +}; + +// To construct a polymorphic matcher, pass an instance of the class +// to MakePolymorphicMatcher(). Note the return type. +PolymorphicMatcher NotNull() { + return MakePolymorphicMatcher(NotNullMatcher()); +} + +... + + EXPECT_CALL(foo, Bar(NotNull())); // The argument must be a non-NULL pointer. +``` + +**Note:** Your polymorphic matcher class does **not** need to inherit from +`MatcherInterface` or any other class, and its methods do **not** need to be +virtual. + +Like in a monomorphic matcher, you may explain the match result by streaming +additional information to the `listener` argument in `MatchAndExplain()`. + +### Writing New Cardinalities + +A cardinality is used in `Times()` to tell gMock how many times you expect a +call to occur. It doesn't have to be exact. For example, you can say +`AtLeast(5)` or `Between(2, 4)`. + +If the [built-in set](cheat_sheet.md#CardinalityList) of cardinalities doesn't +suit you, you are free to define your own by implementing the following +interface (in namespace `testing`): + +```cpp +class CardinalityInterface { + public: + virtual ~CardinalityInterface(); + + // Returns true if and only if call_count calls will satisfy this cardinality. + virtual bool IsSatisfiedByCallCount(int call_count) const = 0; + + // Returns true if and only if call_count calls will saturate this + // cardinality. + virtual bool IsSaturatedByCallCount(int call_count) const = 0; + + // Describes self to an ostream. + virtual void DescribeTo(std::ostream* os) const = 0; +}; +``` + +For example, to specify that a call must occur even number of times, you can +write + +```cpp +using ::testing::Cardinality; +using ::testing::CardinalityInterface; +using ::testing::MakeCardinality; + +class EvenNumberCardinality : public CardinalityInterface { + public: + bool IsSatisfiedByCallCount(int call_count) const override { + return (call_count % 2) == 0; + } + + bool IsSaturatedByCallCount(int call_count) const override { + return false; + } + + void DescribeTo(std::ostream* os) const { + *os << "called even number of times"; + } +}; + +Cardinality EvenNumber() { + return MakeCardinality(new EvenNumberCardinality); +} + +... + EXPECT_CALL(foo, Bar(3)) + .Times(EvenNumber()); +``` + +### Writing New Actions Quickly {#QuickNewActions} + +If the built-in actions don't work for you, you can easily define your own one. +Just define a functor class with a (possibly templated) call operator, matching +the signature of your action. + +```cpp +struct Increment { + template + T operator()(T* arg) { + return ++(*arg); + } +} +``` + +The same approach works with stateful functors (or any callable, really): + +``` +struct MultiplyBy { + template + T operator()(T arg) { return arg * multiplier; } + + int multiplier; +} + +// Then use: +// EXPECT_CALL(...).WillOnce(MultiplyBy{7}); +``` + +#### Legacy macro-based Actions + +Before C++11, the functor-based actions were not supported; the old way of +writing actions was through a set of `ACTION*` macros. We suggest to avoid them +in new code; they hide a lot of logic behind the macro, potentially leading to +harder-to-understand compiler errors. Nevertheless, we cover them here for +completeness. + +By writing + +```cpp +ACTION(name) { statements; } +``` + +in a namespace scope (i.e. not inside a class or function), you will define an +action with the given name that executes the statements. The value returned by +`statements` will be used as the return value of the action. Inside the +statements, you can refer to the K-th (0-based) argument of the mock function as +`argK`. For example: + +```cpp +ACTION(IncrementArg1) { return ++(*arg1); } +``` + +allows you to write + +```cpp +... WillOnce(IncrementArg1()); +``` + +Note that you don't need to specify the types of the mock function arguments. +Rest assured that your code is type-safe though: you'll get a compiler error if +`*arg1` doesn't support the `++` operator, or if the type of `++(*arg1)` isn't +compatible with the mock function's return type. + +Another example: + +```cpp +ACTION(Foo) { + (*arg2)(5); + Blah(); + *arg1 = 0; + return arg0; +} +``` + +defines an action `Foo()` that invokes argument #2 (a function pointer) with 5, +calls function `Blah()`, sets the value pointed to by argument #1 to 0, and +returns argument #0. + +For more convenience and flexibility, you can also use the following pre-defined +symbols in the body of `ACTION`: + +`argK_type` | The type of the K-th (0-based) argument of the mock function +:-------------- | :----------------------------------------------------------- +`args` | All arguments of the mock function as a tuple +`args_type` | The type of all arguments of the mock function as a tuple +`return_type` | The return type of the mock function +`function_type` | The type of the mock function + +For example, when using an `ACTION` as a stub action for mock function: + +```cpp +int DoSomething(bool flag, int* ptr); +``` + +we have: + +Pre-defined Symbol | Is Bound To +------------------ | --------------------------------- +`arg0` | the value of `flag` +`arg0_type` | the type `bool` +`arg1` | the value of `ptr` +`arg1_type` | the type `int*` +`args` | the tuple `(flag, ptr)` +`args_type` | the type `std::tuple` +`return_type` | the type `int` +`function_type` | the type `int(bool, int*)` + +#### Legacy macro-based parameterized Actions + +Sometimes you'll want to parameterize an action you define. For that we have +another macro + +```cpp +ACTION_P(name, param) { statements; } +``` + +For example, + +```cpp +ACTION_P(Add, n) { return arg0 + n; } +``` + +will allow you to write + +```cpp +// Returns argument #0 + 5. +... WillOnce(Add(5)); +``` + +For convenience, we use the term *arguments* for the values used to invoke the +mock function, and the term *parameters* for the values used to instantiate an +action. + +Note that you don't need to provide the type of the parameter either. Suppose +the parameter is named `param`, you can also use the gMock-defined symbol +`param_type` to refer to the type of the parameter as inferred by the compiler. +For example, in the body of `ACTION_P(Add, n)` above, you can write `n_type` for +the type of `n`. + +gMock also provides `ACTION_P2`, `ACTION_P3`, and etc to support multi-parameter +actions. For example, + +```cpp +ACTION_P2(ReturnDistanceTo, x, y) { + double dx = arg0 - x; + double dy = arg1 - y; + return sqrt(dx*dx + dy*dy); +} +``` + +lets you write + +```cpp +... WillOnce(ReturnDistanceTo(5.0, 26.5)); +``` + +You can view `ACTION` as a degenerated parameterized action where the number of +parameters is 0. + +You can also easily define actions overloaded on the number of parameters: + +```cpp +ACTION_P(Plus, a) { ... } +ACTION_P2(Plus, a, b) { ... } +``` + +### Restricting the Type of an Argument or Parameter in an ACTION + +For maximum brevity and reusability, the `ACTION*` macros don't ask you to +provide the types of the mock function arguments and the action parameters. +Instead, we let the compiler infer the types for us. + +Sometimes, however, we may want to be more explicit about the types. There are +several tricks to do that. For example: + +```cpp +ACTION(Foo) { + // Makes sure arg0 can be converted to int. + int n = arg0; + ... use n instead of arg0 here ... +} + +ACTION_P(Bar, param) { + // Makes sure the type of arg1 is const char*. + ::testing::StaticAssertTypeEq(); + + // Makes sure param can be converted to bool. + bool flag = param; +} +``` + +where `StaticAssertTypeEq` is a compile-time assertion in googletest that +verifies two types are the same. + +### Writing New Action Templates Quickly + +Sometimes you want to give an action explicit template parameters that cannot be +inferred from its value parameters. `ACTION_TEMPLATE()` supports that and can be +viewed as an extension to `ACTION()` and `ACTION_P*()`. + +The syntax: + +```cpp +ACTION_TEMPLATE(ActionName, + HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), + AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +``` + +defines an action template that takes *m* explicit template parameters and *n* +value parameters, where *m* is in [1, 10] and *n* is in [0, 10]. `name_i` is the +name of the *i*-th template parameter, and `kind_i` specifies whether it's a +`typename`, an integral constant, or a template. `p_i` is the name of the *i*-th +value parameter. + +Example: + +```cpp +// DuplicateArg(output) converts the k-th argument of the mock +// function to type T and copies it to *output. +ACTION_TEMPLATE(DuplicateArg, + // Note the comma between int and k: + HAS_2_TEMPLATE_PARAMS(int, k, typename, T), + AND_1_VALUE_PARAMS(output)) { + *output = T(::std::get(args)); +} +``` + +To create an instance of an action template, write: + +```cpp +ActionName(v1, ..., v_n) +``` + +where the `t`s are the template arguments and the `v`s are the value arguments. +The value argument types are inferred by the compiler. For example: + +```cpp +using ::testing::_; +... + int n; + EXPECT_CALL(mock, Foo).WillOnce(DuplicateArg<1, unsigned char>(&n)); +``` + +If you want to explicitly specify the value argument types, you can provide +additional template arguments: + +```cpp +ActionName(v1, ..., v_n) +``` + +where `u_i` is the desired type of `v_i`. + +`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the number of +value parameters, but not on the number of template parameters. Without the +restriction, the meaning of the following is unclear: + +```cpp + OverloadedAction(x); +``` + +Are we using a single-template-parameter action where `bool` refers to the type +of `x`, or a two-template-parameter action where the compiler is asked to infer +the type of `x`? + +### Using the ACTION Object's Type + +If you are writing a function that returns an `ACTION` object, you'll need to +know its type. The type depends on the macro used to define the action and the +parameter types. The rule is relatively simple: + +| Given Definition | Expression | Has Type | +| ----------------------------- | ------------------- | --------------------- | +| `ACTION(Foo)` | `Foo()` | `FooAction` | +| `ACTION_TEMPLATE(Foo,` | `Foo()` : t_m>` : +: `AND_0_VALUE_PARAMS())` : : : +| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP` | +| `ACTION_TEMPLATE(Bar,` | `Bar` | `FooActionP` : +: `AND_1_VALUE_PARAMS(p1))` : : : +| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value,` | `BazActionP2` : +| `ACTION_TEMPLATE(Baz,` | `Baz` | `FooActionP2` : +: `AND_2_VALUE_PARAMS(p1, p2))` : `int_value)` : : +| ... | ... | ... | + +Note that we have to pick different suffixes (`Action`, `ActionP`, `ActionP2`, +and etc) for actions with different numbers of value parameters, or the action +definitions cannot be overloaded on the number of them. + +### Writing New Monomorphic Actions {#NewMonoActions} + +While the `ACTION*` macros are very convenient, sometimes they are +inappropriate. For example, despite the tricks shown in the previous recipes, +they don't let you directly specify the types of the mock function arguments and +the action parameters, which in general leads to unoptimized compiler error +messages that can baffle unfamiliar users. They also don't allow overloading +actions based on parameter types without jumping through some hoops. + +An alternative to the `ACTION*` macros is to implement +`::testing::ActionInterface`, where `F` is the type of the mock function in +which the action will be used. For example: + +```cpp +template +class ActionInterface { + public: + virtual ~ActionInterface(); + + // Performs the action. Result is the return type of function type + // F, and ArgumentTuple is the tuple of arguments of F. + // + + // For example, if F is int(bool, const string&), then Result would + // be int, and ArgumentTuple would be ::std::tuple. + virtual Result Perform(const ArgumentTuple& args) = 0; +}; +``` + +```cpp +using ::testing::_; +using ::testing::Action; +using ::testing::ActionInterface; +using ::testing::MakeAction; + +typedef int IncrementMethod(int*); + +class IncrementArgumentAction : public ActionInterface { + public: + int Perform(const ::std::tuple& args) override { + int* p = ::std::get<0>(args); // Grabs the first argument. + return *p++; + } +}; + +Action IncrementArgument() { + return MakeAction(new IncrementArgumentAction); +} + +... + EXPECT_CALL(foo, Baz(_)) + .WillOnce(IncrementArgument()); + + int n = 5; + foo.Baz(&n); // Should return 5 and change n to 6. +``` + +### Writing New Polymorphic Actions {#NewPolyActions} + +The previous recipe showed you how to define your own action. This is all good, +except that you need to know the type of the function in which the action will +be used. Sometimes that can be a problem. For example, if you want to use the +action in functions with *different* types (e.g. like `Return()` and +`SetArgPointee()`). + +If an action can be used in several types of mock functions, we say it's +*polymorphic*. The `MakePolymorphicAction()` function template makes it easy to +define such an action: + +```cpp +namespace testing { +template +PolymorphicAction MakePolymorphicAction(const Impl& impl); +} // namespace testing +``` + +As an example, let's define an action that returns the second argument in the +mock function's argument list. The first step is to define an implementation +class: + +```cpp +class ReturnSecondArgumentAction { + public: + template + Result Perform(const ArgumentTuple& args) const { + // To get the i-th (0-based) argument, use ::std::get(args). + return ::std::get<1>(args); + } +}; +``` + +This implementation class does *not* need to inherit from any particular class. +What matters is that it must have a `Perform()` method template. This method +template takes the mock function's arguments as a tuple in a **single** +argument, and returns the result of the action. It can be either `const` or not, +but must be invokable with exactly one template argument, which is the result +type. In other words, you must be able to call `Perform(args)` where `R` is +the mock function's return type and `args` is its arguments in a tuple. + +Next, we use `MakePolymorphicAction()` to turn an instance of the implementation +class into the polymorphic action we need. It will be convenient to have a +wrapper for this: + +```cpp +using ::testing::MakePolymorphicAction; +using ::testing::PolymorphicAction; + +PolymorphicAction ReturnSecondArgument() { + return MakePolymorphicAction(ReturnSecondArgumentAction()); +} +``` + +Now, you can use this polymorphic action the same way you use the built-in ones: + +```cpp +using ::testing::_; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, DoThis, (bool flag, int n), (override)); + MOCK_METHOD(string, DoThat, (int x, const char* str1, const char* str2), + (override)); +}; + + ... + MockFoo foo; + EXPECT_CALL(foo, DoThis).WillOnce(ReturnSecondArgument()); + EXPECT_CALL(foo, DoThat).WillOnce(ReturnSecondArgument()); + ... + foo.DoThis(true, 5); // Will return 5. + foo.DoThat(1, "Hi", "Bye"); // Will return "Hi". +``` + +### Teaching gMock How to Print Your Values + +When an uninteresting or unexpected call occurs, gMock prints the argument +values and the stack trace to help you debug. Assertion macros like +`EXPECT_THAT` and `EXPECT_EQ` also print the values in question when the +assertion fails. gMock and googletest do this using googletest's user-extensible +value printer. + +This printer knows how to print built-in C++ types, native arrays, STL +containers, and any type that supports the `<<` operator. For other types, it +prints the raw bytes in the value and hopes that you the user can figure it out. +[googletest's advanced guide](../../googletest/docs/advanced.md#teaching-googletest-how-to-print-your-values) +explains how to extend the printer to do a better job at printing your +particular type than to dump the bytes. + +## Useful Mocks Created Using gMock + + + + +### Mock std::function {#MockFunction} + +`std::function` is a general function type introduced in C++11. It is a +preferred way of passing callbacks to new interfaces. Functions are copiable, +and are not usually passed around by pointer, which makes them tricky to mock. +But fear not - `MockFunction` can help you with that. + +`MockFunction` has a mock method `Call()` with the signature: + +```cpp + R Call(T1, ..., Tn); +``` + +It also has a `AsStdFunction()` method, which creates a `std::function` proxy +forwarding to Call: + +```cpp + std::function AsStdFunction(); +``` + +To use `MockFunction`, first create `MockFunction` object and set up +expectations on its `Call` method. Then pass proxy obtained from +`AsStdFunction()` to the code you are testing. For example: + +```cpp +TEST(FooTest, RunsCallbackWithBarArgument) { + // 1. Create a mock object. + MockFunction mock_function; + + // 2. Set expectations on Call() method. + EXPECT_CALL(mock_function, Call("bar")).WillOnce(Return(1)); + + // 3. Exercise code that uses std::function. + Foo(mock_function.AsStdFunction()); + // Foo's signature can be either of: + // void Foo(const std::function& fun); + // void Foo(std::function fun); + + // 4. All expectations will be verified when mock_function + // goes out of scope and is destroyed. +} +``` + +Remember that function objects created with `AsStdFunction()` are just +forwarders. If you create multiple of them, they will share the same set of +expectations. + +Although `std::function` supports unlimited number of arguments, `MockFunction` +implementation is limited to ten. If you ever hit that limit... well, your +callback has bigger problems than being mockable. :-) + + diff --git a/src/test/gtest/googlemock/docs/for_dummies.md b/src/test/gtest/googlemock/docs/for_dummies.md new file mode 100644 index 00000000..e11c18d9 --- /dev/null +++ b/src/test/gtest/googlemock/docs/for_dummies.md @@ -0,0 +1,700 @@ +## gMock for Dummies {#GMockForDummies} + + + +### What Is gMock? + +When you write a prototype or test, often it's not feasible or wise to rely on +real objects entirely. A **mock object** implements the same interface as a real +object (so it can be used as one), but lets you specify at run time how it will +be used and what it should do (which methods will be called? in which order? how +many times? with what arguments? what will they return? etc). + +**Note:** It is easy to confuse the term *fake objects* with mock objects. Fakes +and mocks actually mean very different things in the Test-Driven Development +(TDD) community: + +* **Fake** objects have working implementations, but usually take some + shortcut (perhaps to make the operations less expensive), which makes them + not suitable for production. An in-memory file system would be an example of + a fake. +* **Mocks** are objects pre-programmed with *expectations*, which form a + specification of the calls they are expected to receive. + +If all this seems too abstract for you, don't worry - the most important thing +to remember is that a mock allows you to check the *interaction* between itself +and code that uses it. The difference between fakes and mocks shall become much +clearer once you start to use mocks. + +**gMock** is a library (sometimes we also call it a "framework" to make it sound +cool) for creating mock classes and using them. It does to C++ what +jMock/EasyMock does to Java (well, more or less). + +When using gMock, + +1. first, you use some simple macros to describe the interface you want to + mock, and they will expand to the implementation of your mock class; +2. next, you create some mock objects and specify its expectations and behavior + using an intuitive syntax; +3. then you exercise code that uses the mock objects. gMock will catch any + violation to the expectations as soon as it arises. + +### Why gMock? + +While mock objects help you remove unnecessary dependencies in tests and make +them fast and reliable, using mocks manually in C++ is *hard*: + +* Someone has to implement the mocks. The job is usually tedious and + error-prone. No wonder people go great distance to avoid it. +* The quality of those manually written mocks is a bit, uh, unpredictable. You + may see some really polished ones, but you may also see some that were + hacked up in a hurry and have all sorts of ad hoc restrictions. +* The knowledge you gained from using one mock doesn't transfer to the next + one. + +In contrast, Java and Python programmers have some fine mock frameworks (jMock, +EasyMock, [Mox](http://wtf/mox), etc), which automate the creation of mocks. As +a result, mocking is a proven effective technique and widely adopted practice in +those communities. Having the right tool absolutely makes the difference. + +gMock was built to help C++ programmers. It was inspired by jMock and EasyMock, +but designed with C++'s specifics in mind. It is your friend if any of the +following problems is bothering you: + +* You are stuck with a sub-optimal design and wish you had done more + prototyping before it was too late, but prototyping in C++ is by no means + "rapid". +* Your tests are slow as they depend on too many libraries or use expensive + resources (e.g. a database). +* Your tests are brittle as some resources they use are unreliable (e.g. the + network). +* You want to test how your code handles a failure (e.g. a file checksum + error), but it's not easy to cause one. +* You need to make sure that your module interacts with other modules in the + right way, but it's hard to observe the interaction; therefore you resort to + observing the side effects at the end of the action, but it's awkward at + best. +* You want to "mock out" your dependencies, except that they don't have mock + implementations yet; and, frankly, you aren't thrilled by some of those + hand-written mocks. + +We encourage you to use gMock as + +* a *design* tool, for it lets you experiment with your interface design early + and often. More iterations lead to better designs! +* a *testing* tool to cut your tests' outbound dependencies and probe the + interaction between your module and its collaborators. + +### Getting Started + +gMock is bundled with googletest. + +### A Case for Mock Turtles + +Let's look at an example. Suppose you are developing a graphics program that +relies on a [LOGO](http://en.wikipedia.org/wiki/Logo_programming_language)-like +API for drawing. How would you test that it does the right thing? Well, you can +run it and compare the screen with a golden screen snapshot, but let's admit it: +tests like this are expensive to run and fragile (What if you just upgraded to a +shiny new graphics card that has better anti-aliasing? Suddenly you have to +update all your golden images.). It would be too painful if all your tests are +like this. Fortunately, you learned about +[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) and know the right thing +to do: instead of having your application talk to the system API directly, wrap +the API in an interface (say, `Turtle`) and code to that interface: + +```cpp +class Turtle { + ... + virtual ~Turtle() {}; + virtual void PenUp() = 0; + virtual void PenDown() = 0; + virtual void Forward(int distance) = 0; + virtual void Turn(int degrees) = 0; + virtual void GoTo(int x, int y) = 0; + virtual int GetX() const = 0; + virtual int GetY() const = 0; +}; +``` + +(Note that the destructor of `Turtle` **must** be virtual, as is the case for +**all** classes you intend to inherit from - otherwise the destructor of the +derived class will not be called when you delete an object through a base +pointer, and you'll get corrupted program states like memory leaks.) + +You can control whether the turtle's movement will leave a trace using `PenUp()` +and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and +`GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the +turtle. + +Your program will normally use a real implementation of this interface. In +tests, you can use a mock implementation instead. This allows you to easily +check what drawing primitives your program is calling, with what arguments, and +in which order. Tests written this way are much more robust (they won't break +because your new machine does anti-aliasing differently), easier to read and +maintain (the intent of a test is expressed in the code, not in some binary +images), and run *much, much faster*. + +### Writing the Mock Class + +If you are lucky, the mocks you need to use have already been implemented by +some nice people. If, however, you find yourself in the position to write a mock +class, relax - gMock turns this task into a fun game! (Well, almost.) + +#### How to Define It + +Using the `Turtle` interface as example, here are the simple steps you need to +follow: + +* Derive a class `MockTurtle` from `Turtle`. +* Take a *virtual* function of `Turtle` (while it's possible to + [mock non-virtual methods using templates](cook_book.md#MockingNonVirtualMethods), + it's much more involved). +* In the `public:` section of the child class, write `MOCK_METHOD();` +* Now comes the fun part: you take the function signature, cut-and-paste it + into the macro, and add two commas - one between the return type and the + name, another between the name and the argument list. +* If you're mocking a const method, add a 4th parameter containing `(const)` + (the parentheses are required). +* Since you're overriding a virtual method, we suggest adding the `override` + keyword. For const methods the 4th parameter becomes `(const, override)`, + for non-const methods just `(override)`. This isn't mandatory. +* Repeat until all virtual functions you want to mock are done. (It goes + without saying that *all* pure virtual methods in your abstract class must + be either mocked or overridden.) + +After the process, you should have something like: + +```cpp +#include "gmock/gmock.h" // Brings in gMock. + +class MockTurtle : public Turtle { + public: + ... + MOCK_METHOD(void, PenUp, (), (override)); + MOCK_METHOD(void, PenDown, (), (override)); + MOCK_METHOD(void, Forward, (int distance), (override)); + MOCK_METHOD(void, Turn, (int degrees), (override)); + MOCK_METHOD(void, GoTo, (int x, int y), (override)); + MOCK_METHOD(int, GetX, (), (const, override)); + MOCK_METHOD(int, GetY, (), (const, override)); +}; +``` + +You don't need to define these mock methods somewhere else - the `MOCK_METHOD` +macro will generate the definitions for you. It's that simple! + +#### Where to Put It + +When you define a mock class, you need to decide where to put its definition. +Some people put it in a `_test.cc`. This is fine when the interface being mocked +(say, `Foo`) is owned by the same person or team. Otherwise, when the owner of +`Foo` changes it, your test could break. (You can't really expect `Foo`'s +maintainer to fix every test that uses `Foo`, can you?) + +So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, +define the mock class in `Foo`'s package (better, in a `testing` sub-package +such that you can clearly separate production code and testing utilities), put +it in a `.h` and a `cc_library`. Then everyone can reference them from their +tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and +only tests that depend on the changed methods need to be fixed. + +Another way to do it: you can introduce a thin layer `FooAdaptor` on top of +`Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb +changes in `Foo` much more easily. While this is more work initially, carefully +choosing the adaptor interface can make your code easier to write and more +readable (a net win in the long run), as you can choose `FooAdaptor` to fit your +specific domain much better than `Foo` does. + + + +### Using Mocks in Tests + +Once you have a mock class, using it is easy. The typical work flow is: + +1. Import the gMock names from the `testing` namespace such that you can use + them unqualified (You only have to do it once per file. Remember that + namespaces are a good idea. +2. Create some mock objects. +3. Specify your expectations on them (How many times will a method be called? + With what arguments? What should it do? etc.). +4. Exercise some code that uses the mocks; optionally, check the result using + googletest assertions. If a mock method is called more than expected or with + wrong arguments, you'll get an error immediately. +5. When a mock is destructed, gMock will automatically check whether all + expectations on it have been satisfied. + +Here's an example: + +```cpp +#include "path/to/mock-turtle.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using ::testing::AtLeast; // #1 + +TEST(PainterTest, CanDrawSomething) { + MockTurtle turtle; // #2 + EXPECT_CALL(turtle, PenDown()) // #3 + .Times(AtLeast(1)); + + Painter painter(&turtle); // #4 + + EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); // #5 +} +``` + +As you might have guessed, this test checks that `PenDown()` is called at least +once. If the `painter` object didn't call this method, your test will fail with +a message like this: + +```text +path/to/my_test.cc:119: Failure +Actual function call count doesn't match this expectation: +Actually: never called; +Expected: called at least once. +Stack trace: +... +``` + +**Tip 1:** If you run the test from an Emacs buffer, you can hit on the +line number to jump right to the failed expectation. + +**Tip 2:** If your mock objects are never deleted, the final verification won't +happen. Therefore it's a good idea to turn on the heap checker in your tests +when you allocate mocks on the heap. You get that automatically if you use the +`gtest_main` library already. + +**Important note:** gMock requires expectations to be set **before** the mock +functions are called, otherwise the behavior is **undefined**. In particular, +you mustn't interleave `EXPECT_CALL()s` and calls to the mock functions. + +This means `EXPECT_CALL()` should be read as expecting that a call will occur +*in the future*, not that a call has occurred. Why does gMock work like that? +Well, specifying the expectation beforehand allows gMock to report a violation +as soon as it rises, when the context (stack trace, etc) is still available. +This makes debugging much easier. + +Admittedly, this test is contrived and doesn't do much. You can easily achieve +the same effect without using gMock. However, as we shall reveal soon, gMock +allows you to do *so much more* with the mocks. + +### Setting Expectations + +The key to using a mock object successfully is to set the *right expectations* +on it. If you set the expectations too strict, your test will fail as the result +of unrelated changes. If you set them too loose, bugs can slip through. You want +to do it just right such that your test can catch exactly the kind of bugs you +intend it to catch. gMock provides the necessary means for you to do it "just +right." + +#### General Syntax + +In gMock we use the `EXPECT_CALL()` macro to set an expectation on a mock +method. The general syntax is: + +```cpp +EXPECT_CALL(mock_object, method(matchers)) + .Times(cardinality) + .WillOnce(action) + .WillRepeatedly(action); +``` + +The macro has two arguments: first the mock object, and then the method and its +arguments. Note that the two are separated by a comma (`,`), not a period (`.`). +(Why using a comma? The answer is that it was necessary for technical reasons.) +If the method is not overloaded, the macro can also be called without matchers: + +```cpp +EXPECT_CALL(mock_object, non-overloaded-method) + .Times(cardinality) + .WillOnce(action) + .WillRepeatedly(action); +``` + +This syntax allows the test writer to specify "called with any arguments" +without explicitly specifying the number or types of arguments. To avoid +unintended ambiguity, this syntax may only be used for methods which are not +overloaded + +Either form of the macro can be followed by some optional *clauses* that provide +more information about the expectation. We'll discuss how each clause works in +the coming sections. + +This syntax is designed to make an expectation read like English. For example, +you can probably guess that + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetX()) + .Times(5) + .WillOnce(Return(100)) + .WillOnce(Return(150)) + .WillRepeatedly(Return(200)); +``` + +says that the `turtle` object's `GetX()` method will be called five times, it +will return 100 the first time, 150 the second time, and then 200 every time. +Some people like to call this style of syntax a Domain-Specific Language (DSL). + +**Note:** Why do we use a macro to do this? Well it serves two purposes: first +it makes expectations easily identifiable (either by `gsearch` or by a human +reader), and second it allows gMock to include the source file location of a +failed expectation in messages, making debugging easier. + +#### Matchers: What Arguments Do We Expect? + +When a mock function takes arguments, we may specify what arguments we are +expecting, for example: + +```cpp +// Expects the turtle to move forward by 100 units. +EXPECT_CALL(turtle, Forward(100)); +``` + +Oftentimes you do not want to be too specific. Remember that talk about tests +being too rigid? Over specification leads to brittle tests and obscures the +intent of tests. Therefore we encourage you to specify only what's necessary—no +more, no less. If you aren't interested in the value of an argument, write `_` +as the argument, which means "anything goes": + +```cpp +using ::testing::_; +... +// Expects that the turtle jumps to somewhere on the x=50 line. +EXPECT_CALL(turtle, GoTo(50, _)); +``` + +`_` is an instance of what we call **matchers**. A matcher is like a predicate +and can test whether an argument is what we'd expect. You can use a matcher +inside `EXPECT_CALL()` wherever a function argument is expected. `_` is a +convenient way of saying "any value". + +In the above examples, `100` and `50` are also matchers; implicitly, they are +the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be +equal (using `operator==`) to the matcher argument. There are many +[built-in matchers](#MatcherList) for common types (as well as +[custom matchers](cook_book.md#NewMatchers)); for example: + +```cpp +using ::testing::Ge; +... +// Expects the turtle moves forward by at least 100. +EXPECT_CALL(turtle, Forward(Ge(100))); +``` + +If you don't care about *any* arguments, rather than specify `_` for each of +them you may instead omit the parameter list: + +```cpp +// Expects the turtle to move forward. +EXPECT_CALL(turtle, Forward); +// Expects the turtle to jump somewhere. +EXPECT_CALL(turtle, GoTo); +``` + +This works for all non-overloaded methods; if a method is overloaded, you need +to help gMock resolve which overload is expected by specifying the number of +arguments and possibly also the +[types of the arguments](cook_book.md#SelectOverload). + +#### Cardinalities: How Many Times Will It Be Called? + +The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We +call its argument a **cardinality** as it tells *how many times* the call should +occur. It allows us to repeat an expectation many times without actually writing +it as many times. More importantly, a cardinality can be "fuzzy", just like a +matcher can be. This allows a user to express the intent of a test exactly. + +An interesting special case is when we say `Times(0)`. You may have guessed - it +means that the function shouldn't be called with the given arguments at all, and +gMock will report a googletest failure whenever the function is (wrongfully) +called. + +We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the +list of built-in cardinalities you can use, see +[here](cheat_sheet.md#CardinalityList). + +The `Times()` clause can be omitted. **If you omit `Times()`, gMock will infer +the cardinality for you.** The rules are easy to remember: + +* If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the + `EXPECT_CALL()`, the inferred cardinality is `Times(1)`. +* If there are *n* `WillOnce()`'s but **no** `WillRepeatedly()`, where *n* >= + 1, the cardinality is `Times(n)`. +* If there are *n* `WillOnce()`'s and **one** `WillRepeatedly()`, where *n* >= + 0, the cardinality is `Times(AtLeast(n))`. + +**Quick quiz:** what do you think will happen if a function is expected to be +called twice but actually called four times? + +#### Actions: What Should It Do? + +Remember that a mock object doesn't really have a working implementation? We as +users have to tell it what to do when a method is invoked. This is easy in +gMock. + +First, if the return type of a mock function is a built-in type or a pointer, +the function has a **default action** (a `void` function will just return, a +`bool` function will return `false`, and other functions will return 0). In +addition, in C++ 11 and above, a mock function whose return type is +default-constructible (i.e. has a default constructor) has a default action of +returning a default-constructed value. If you don't say anything, this behavior +will be used. + +Second, if a mock function doesn't have a default action, or the default action +doesn't suit you, you can specify the action to be taken each time the +expectation matches using a series of `WillOnce()` clauses followed by an +optional `WillRepeatedly()`. For example, + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(100)) + .WillOnce(Return(200)) + .WillOnce(Return(300)); +``` + +says that `turtle.GetX()` will be called *exactly three times* (gMock inferred +this from how many `WillOnce()` clauses we've written, since we didn't +explicitly write `Times()`), and will return 100, 200, and 300 respectively. + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetY()) + .WillOnce(Return(100)) + .WillOnce(Return(200)) + .WillRepeatedly(Return(300)); +``` + +says that `turtle.GetY()` will be called *at least twice* (gMock knows this as +we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no +explicit `Times()`), will return 100 and 200 respectively the first two times, +and 300 from the third time on. + +Of course, if you explicitly write a `Times()`, gMock will not try to infer the +cardinality itself. What if the number you specified is larger than there are +`WillOnce()` clauses? Well, after all `WillOnce()`s are used up, gMock will do +the *default* action for the function every time (unless, of course, you have a +`WillRepeatedly()`.). + +What can we do inside `WillOnce()` besides `Return()`? You can return a +reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among +[others](cook_book.md#using-actions). + +**Important note:** The `EXPECT_CALL()` statement evaluates the action clause +only once, even though the action may be performed many times. Therefore you +must be careful about side effects. The following may not do what you want: + +```cpp +using ::testing::Return; +... +int n = 100; +EXPECT_CALL(turtle, GetX()) + .Times(4) + .WillRepeatedly(Return(n++)); +``` + +Instead of returning 100, 101, 102, ..., consecutively, this mock function will +always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)` +will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will +return the same pointer every time. If you want the side effect to happen every +time, you need to define a custom action, which we'll teach in the +[cook book](http://). + +Time for another quiz! What do you think the following means? + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetY()) + .Times(4) + .WillOnce(Return(100)); +``` + +Obviously `turtle.GetY()` is expected to be called four times. But if you think +it will return 100 every time, think twice! Remember that one `WillOnce()` +clause will be consumed each time the function is invoked and the default action +will be taken afterwards. So the right answer is that `turtle.GetY()` will +return 100 the first time, but **return 0 from the second time on**, as +returning 0 is the default action for `int` functions. + +#### Using Multiple Expectations {#MultiExpectations} + +So far we've only shown examples where you have a single expectation. More +realistically, you'll specify expectations on multiple mock methods which may be +from multiple mock objects. + +By default, when a mock method is invoked, gMock will search the expectations in +the **reverse order** they are defined, and stop when an active expectation that +matches the arguments is found (you can think of it as "newer rules override +older ones."). If the matching expectation cannot take any more calls, you will +get an upper-bound-violated failure. Here's an example: + +```cpp +using ::testing::_; +... +EXPECT_CALL(turtle, Forward(_)); // #1 +EXPECT_CALL(turtle, Forward(10)) // #2 + .Times(2); +``` + +If `Forward(10)` is called three times in a row, the third time it will be an +error, as the last matching expectation (#2) has been saturated. If, however, +the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK, +as now #1 will be the matching expectation. + +**Note:** Why does gMock search for a match in the *reverse* order of the +expectations? The reason is that this allows a user to set up the default +expectations in a mock object's constructor or the test fixture's set-up phase +and then customize the mock by writing more specific expectations in the test +body. So, if you have two expectations on the same method, you want to put the +one with more specific matchers **after** the other, or the more specific rule +would be shadowed by the more general one that comes after it. + +**Tip:** It is very common to start with a catch-all expectation for a method +and `Times(AnyNumber())` (omitting arguments, or with `_` for all arguments, if +overloaded). This makes any calls to the method expected. This is not necessary +for methods that are not mentioned at all (these are "uninteresting"), but is +useful for methods that have some expectations, but for which other calls are +ok. See +[Understanding Uninteresting vs Unexpected Calls](cook_book.md#uninteresting-vs-unexpected). + +#### Ordered vs Unordered Calls {#OrderedCalls} + +By default, an expectation can match a call even though an earlier expectation +hasn't been satisfied. In other words, the calls don't have to occur in the +order the expectations are specified. + +Sometimes, you may want all the expected calls to occur in a strict order. To +say this in gMock is easy: + +```cpp +using ::testing::InSequence; +... +TEST(FooTest, DrawsLineSegment) { + ... + { + InSequence seq; + + EXPECT_CALL(turtle, PenDown()); + EXPECT_CALL(turtle, Forward(100)); + EXPECT_CALL(turtle, PenUp()); + } + Foo(); +} +``` + +By creating an object of type `InSequence`, all expectations in its scope are +put into a *sequence* and have to occur *sequentially*. Since we are just +relying on the constructor and destructor of this object to do the actual work, +its name is really irrelevant. + +In this example, we test that `Foo()` calls the three expected functions in the +order as written. If a call is made out-of-order, it will be an error. + +(What if you care about the relative order of some of the calls, but not all of +them? Can you specify an arbitrary partial order? The answer is ... yes! The +details can be found [here](cook_book.md#OrderedCalls).) + +#### All Expectations Are Sticky (Unless Said Otherwise) {#StickyExpectations} + +Now let's do a quick quiz to see how well you can use this mock stuff already. +How would you test that the turtle is asked to go to the origin *exactly twice* +(you want to ignore any other instructions it receives)? + +After you've come up with your answer, take a look at ours and compare notes +(solve it yourself first - don't cheat!): + +```cpp +using ::testing::_; +using ::testing::AnyNumber; +... +EXPECT_CALL(turtle, GoTo(_, _)) // #1 + .Times(AnyNumber()); +EXPECT_CALL(turtle, GoTo(0, 0)) // #2 + .Times(2); +``` + +Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, gMock will +see that the arguments match expectation #2 (remember that we always pick the +last matching expectation). Now, since we said that there should be only two +such calls, gMock will report an error immediately. This is basically what we've +told you in the [Using Multiple Expectations](#MultiExpectations) section above. + +This example shows that **expectations in gMock are "sticky" by default**, in +the sense that they remain active even after we have reached their invocation +upper bounds. This is an important rule to remember, as it affects the meaning +of the spec, and is **different** to how it's done in many other mocking +frameworks (Why'd we do that? Because we think our rule makes the common cases +easier to express and understand.). + +Simple? Let's see if you've really understood it: what does the following code +say? + +```cpp +using ::testing::Return; +... +for (int i = n; i > 0; i--) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)); +} +``` + +If you think it says that `turtle.GetX()` will be called `n` times and will +return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we +said, expectations are sticky. So, the second time `turtle.GetX()` is called, +the last (latest) `EXPECT_CALL()` statement will match, and will immediately +lead to an "upper bound violated" error - this piece of code is not very useful! + +One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is +to explicitly say that the expectations are *not* sticky. In other words, they +should *retire* as soon as they are saturated: + +```cpp +using ::testing::Return; +... +for (int i = n; i > 0; i--) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)) + .RetiresOnSaturation(); +} +``` + +And, there's a better way to do it: in this case, we expect the calls to occur +in a specific order, and we line up the actions to match the order. Since the +order is important here, we should make it explicit using a sequence: + +```cpp +using ::testing::InSequence; +using ::testing::Return; +... +{ + InSequence s; + + for (int i = 1; i <= n; i++) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)) + .RetiresOnSaturation(); + } +} +``` + +By the way, the other situation where an expectation may *not* be sticky is when +it's in a sequence - as soon as another expectation that comes after it in the +sequence has been used, it automatically retires (and will never be used to +match any call). + +#### Uninteresting Calls + +A mock object may have many methods, and not all of them are that interesting. +For example, in some tests we may not care about how many times `GetX()` and +`GetY()` get called. + +In gMock, if you are not interested in a method, just don't say anything about +it. If a call to this method occurs, you'll see a warning in the test output, +but it won't be a failure. This is called "naggy" behavior; to change, see +[The Nice, the Strict, and the Naggy](cook_book.md#NiceStrictNaggy). diff --git a/src/test/gtest/googlemock/docs/gmock_faq.md b/src/test/gtest/googlemock/docs/gmock_faq.md new file mode 100644 index 00000000..214aabf1 --- /dev/null +++ b/src/test/gtest/googlemock/docs/gmock_faq.md @@ -0,0 +1,396 @@ +## Legacy gMock FAQ {#GMockFaq} + + + +### When I call a method on my mock object, the method for the real object is invoked instead. What's the problem? + +In order for a method to be mocked, it must be *virtual*, unless you use the +[high-perf dependency injection technique](#MockingNonVirtualMethods). + +### Can I mock a variadic function? + +You cannot mock a variadic function (i.e. a function taking ellipsis (`...`) +arguments) directly in gMock. + +The problem is that in general, there is *no way* for a mock object to know how +many arguments are passed to the variadic method, and what the arguments' types +are. Only the *author of the base class* knows the protocol, and we cannot look +into his or her head. + +Therefore, to mock such a function, the *user* must teach the mock object how to +figure out the number of arguments and their types. One way to do it is to +provide overloaded versions of the function. + +Ellipsis arguments are inherited from C and not really a C++ feature. They are +unsafe to use and don't work with arguments that have constructors or +destructors. Therefore we recommend to avoid them in C++ as much as possible. + +### MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? + +If you compile this using Microsoft Visual C++ 2005 SP1: + +```cpp +class Foo { + ... + virtual void Bar(const int i) = 0; +}; + +class MockFoo : public Foo { + ... + MOCK_METHOD(void, Bar, (const int i), (override)); +}; +``` + +You may get the following warning: + +```shell +warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier +``` + +This is a MSVC bug. The same code compiles fine with gcc, for example. If you +use Visual C++ 2008 SP1, you would get the warning: + +```shell +warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers +``` + +In C++, if you *declare* a function with a `const` parameter, the `const` +modifier is ignored. Therefore, the `Foo` base class above is equivalent to: + +```cpp +class Foo { + ... + virtual void Bar(int i) = 0; // int or const int? Makes no difference. +}; +``` + +In fact, you can *declare* `Bar()` with an `int` parameter, and define it with a +`const int` parameter. The compiler will still match them up. + +Since making a parameter `const` is meaningless in the method declaration, we +recommend to remove it in both `Foo` and `MockFoo`. That should workaround the +VC bug. + +Note that we are talking about the *top-level* `const` modifier here. If the +function parameter is passed by pointer or reference, declaring the pointee or +referee as `const` is still meaningful. For example, the following two +declarations are *not* equivalent: + +```cpp +void Bar(int* p); // Neither p nor *p is const. +void Bar(const int* p); // p is not const, but *p is. +``` + + + +### I can't figure out why gMock thinks my expectations are not satisfied. What should I do? + +You might want to run your test with `--gmock_verbose=info`. This flag lets +gMock print a trace of every mock function call it receives. By studying the +trace, you'll gain insights on why the expectations you set are not met. + +If you see the message "The mock function has no default action set, and its +return type has no default value set.", then try +[adding a default action](for_dummies.md#DefaultValue). Due to a known issue, +unexpected calls on mocks without default actions don't print out a detailed +comparison between the actual arguments and the expected arguments. + +### My program crashed and `ScopedMockLog` spit out tons of messages. Is it a gMock bug? + +gMock and `ScopedMockLog` are likely doing the right thing here. + +When a test crashes, the failure signal handler will try to log a lot of +information (the stack trace, and the address map, for example). The messages +are compounded if you have many threads with depth stacks. When `ScopedMockLog` +intercepts these messages and finds that they don't match any expectations, it +prints an error for each of them. + +You can learn to ignore the errors, or you can rewrite your expectations to make +your test more robust, for example, by adding something like: + +```cpp +using ::testing::AnyNumber; +using ::testing::Not; +... + // Ignores any log not done by us. + EXPECT_CALL(log, Log(_, Not(EndsWith("/my_file.cc")), _)) + .Times(AnyNumber()); +``` + +### How can I assert that a function is NEVER called? + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .Times(0); +``` + + + +### I have a failed test where gMock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? + +When gMock detects a failure, it prints relevant information (the mock function +arguments, the state of relevant expectations, and etc) to help the user debug. +If another failure is detected, gMock will do the same, including printing the +state of relevant expectations. + +Sometimes an expectation's state didn't change between two failures, and you'll +see the same description of the state twice. They are however *not* redundant, +as they refer to *different points in time*. The fact they are the same *is* +interesting information. + +### I get a heapcheck failure when using a mock object, but using a real object is fine. What can be wrong? + +Does the class (hopefully a pure interface) you are mocking have a virtual +destructor? + +Whenever you derive from a base class, make sure its destructor is virtual. +Otherwise Bad Things will happen. Consider the following code: + +```cpp +class Base { + public: + // Not virtual, but should be. + ~Base() { ... } + ... +}; + +class Derived : public Base { + public: + ... + private: + std::string value_; +}; + +... + Base* p = new Derived; + ... + delete p; // Surprise! ~Base() will be called, but ~Derived() will not + // - value_ is leaked. +``` + +By changing `~Base()` to virtual, `~Derived()` will be correctly called when +`delete p` is executed, and the heap checker will be happy. + +### The "newer expectations override older ones" rule makes writing expectations awkward. Why does gMock do that? + +When people complain about this, often they are referring to code like: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. However, I have to write the expectations in the + // reverse order. This sucks big time!!! + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(2)) + .RetiresOnSaturation(); + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .RetiresOnSaturation(); +``` + +The problem, is that they didn't pick the **best** way to express the test's +intent. + +By default, expectations don't have to be matched in *any* particular order. If +you want them to match in a certain order, you need to be explicit. This is +gMock's (and jMock's) fundamental philosophy: it's easy to accidentally +over-specify your tests, and we want to make it harder to do so. + +There are two better ways to write the test spec. You could either put the +expectations in sequence: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. Using a sequence, we can write the expectations + // in their natural order. + { + InSequence s; + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .RetiresOnSaturation(); + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(2)) + .RetiresOnSaturation(); + } +``` + +or you can put the sequence of actions in the same expectation: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .WillOnce(Return(2)) + .RetiresOnSaturation(); +``` + +Back to the original questions: why does gMock search the expectations (and +`ON_CALL`s) from back to front? Because this allows a user to set up a mock's +behavior for the common case early (e.g. in the mock's constructor or the test +fixture's set-up phase) and customize it with more specific rules later. If +gMock searches from front to back, this very useful pattern won't be possible. + +### gMock prints a warning when a function without EXPECT_CALL is called, even if I have set its behavior using ON_CALL. Would it be reasonable not to show the warning in this case? + +When choosing between being neat and being safe, we lean toward the latter. So +the answer is that we think it's better to show the warning. + +Often people write `ON_CALL`s in the mock object's constructor or `SetUp()`, as +the default behavior rarely changes from test to test. Then in the test body +they set the expectations, which are often different for each test. Having an +`ON_CALL` in the set-up part of a test doesn't mean that the calls are expected. +If there's no `EXPECT_CALL` and the method is called, it's possibly an error. If +we quietly let the call go through without notifying the user, bugs may creep in +unnoticed. + +If, however, you are sure that the calls are OK, you can write + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .WillRepeatedly(...); +``` + +instead of + +```cpp +using ::testing::_; +... + ON_CALL(foo, Bar(_)) + .WillByDefault(...); +``` + +This tells gMock that you do expect the calls and no warning should be printed. + +Also, you can control the verbosity by specifying `--gmock_verbose=error`. Other +values are `info` and `warning`. If you find the output too noisy when +debugging, just choose a less verbose level. + +### How can I delete the mock function's argument in an action? + +If your mock function takes a pointer argument and you want to delete that +argument, you can use testing::DeleteArg() to delete the N'th (zero-indexed) +argument: + +```cpp +using ::testing::_; + ... + MOCK_METHOD(void, Bar, (X* x, const Y& y)); + ... + EXPECT_CALL(mock_foo_, Bar(_, _)) + .WillOnce(testing::DeleteArg<0>())); +``` + +### How can I perform an arbitrary action on a mock function's argument? + +If you find yourself needing to perform some action that's not supported by +gMock directly, remember that you can define your own actions using +[`MakeAction()`](#NewMonoActions) or +[`MakePolymorphicAction()`](#NewPolyActions), or you can write a stub function +and invoke it using [`Invoke()`](#FunctionsAsActions). + +```cpp +using ::testing::_; +using ::testing::Invoke; + ... + MOCK_METHOD(void, Bar, (X* p)); + ... + EXPECT_CALL(mock_foo_, Bar(_)) + .WillOnce(Invoke(MyAction(...))); +``` + +### My code calls a static/global function. Can I mock it? + +You can, but you need to make some changes. + +In general, if you find yourself needing to mock a static function, it's a sign +that your modules are too tightly coupled (and less flexible, less reusable, +less testable, etc). You are probably better off defining a small interface and +call the function through that interface, which then can be easily mocked. It's +a bit of work initially, but usually pays for itself quickly. + +This Google Testing Blog +[post](https://testing.googleblog.com/2008/06/defeat-static-cling.html) says it +excellently. Check it out. + +### My mock object needs to do complex stuff. It's a lot of pain to specify the actions. gMock sucks! + +I know it's not a question, but you get an answer for free any way. :-) + +With gMock, you can create mocks in C++ easily. And people might be tempted to +use them everywhere. Sometimes they work great, and sometimes you may find them, +well, a pain to use. So, what's wrong in the latter case? + +When you write a test without using mocks, you exercise the code and assert that +it returns the correct value or that the system is in an expected state. This is +sometimes called "state-based testing". + +Mocks are great for what some call "interaction-based" testing: instead of +checking the system state at the very end, mock objects verify that they are +invoked the right way and report an error as soon as it arises, giving you a +handle on the precise context in which the error was triggered. This is often +more effective and economical to do than state-based testing. + +If you are doing state-based testing and using a test double just to simulate +the real object, you are probably better off using a fake. Using a mock in this +case causes pain, as it's not a strong point for mocks to perform complex +actions. If you experience this and think that mocks suck, you are just not +using the right tool for your problem. Or, you might be trying to solve the +wrong problem. :-) + +### I got a warning "Uninteresting function call encountered - default action taken.." Should I panic? + +By all means, NO! It's just an FYI. :-) + +What it means is that you have a mock function, you haven't set any expectations +on it (by gMock's rule this means that you are not interested in calls to this +function and therefore it can be called any number of times), and it is called. +That's OK - you didn't say it's not OK to call the function! + +What if you actually meant to disallow this function to be called, but forgot to +write `EXPECT_CALL(foo, Bar()).Times(0)`? While one can argue that it's the +user's fault, gMock tries to be nice and prints you a note. + +So, when you see the message and believe that there shouldn't be any +uninteresting calls, you should investigate what's going on. To make your life +easier, gMock dumps the stack trace when an uninteresting call is encountered. +From that you can figure out which mock function it is, and how it is called. + +### I want to define a custom action. Should I use Invoke() or implement the ActionInterface interface? + +Either way is fine - you want to choose the one that's more convenient for your +circumstance. + +Usually, if your action is for a particular function type, defining it using +`Invoke()` should be easier; if your action can be used in functions of +different types (e.g. if you are defining `Return(*value*)`), +`MakePolymorphicAction()` is easiest. Sometimes you want precise control on what +types of functions the action can be used in, and implementing `ActionInterface` +is the way to go here. See the implementation of `Return()` in +`testing/base/public/gmock-actions.h` for an example. + +### I use SetArgPointee() in WillOnce(), but gcc complains about "conflicting return type specified". What does it mean? + +You got this error as gMock has no idea what value it should return when the +mock method is called. `SetArgPointee()` says what the side effect is, but +doesn't say what the return value should be. You need `DoAll()` to chain a +`SetArgPointee()` with a `Return()` that provides a value appropriate to the API +being mocked. + +See this [recipe](cook_book.md#mocking-side-effects) for more details and an +example. + +### I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? + +We've noticed that when the `/clr` compiler flag is used, Visual C++ uses 5~6 +times as much memory when compiling a mock class. We suggest to avoid `/clr` +when compiling native C++ mocks. diff --git a/src/test/gtest/googlemock/include/gmock/gmock-actions.h b/src/test/gtest/googlemock/include/gmock/gmock-actions.h new file mode 100644 index 00000000..f12d39be --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-actions.h @@ -0,0 +1,1142 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ + +#ifndef _WIN32_WCE +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +namespace testing { + +// To implement an action Foo, define: +// 1. a class FooAction that implements the ActionInterface interface, and +// 2. a factory function that creates an Action object from a +// const FooAction*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Action objects can now be copied like plain values. + +namespace internal { + +// BuiltInDefaultValueGetter::Get() returns a +// default-constructed T value. BuiltInDefaultValueGetter::Get() crashes with an error. +// +// This primary template is used when kDefaultConstructible is true. +template +struct BuiltInDefaultValueGetter { + static T Get() { return T(); } +}; +template +struct BuiltInDefaultValueGetter { + static T Get() { + Assert(false, __FILE__, __LINE__, + "Default action undefined for the function return type."); + return internal::Invalid(); + // The above statement will never be reached, but is required in + // order for this function to compile. + } +}; + +// BuiltInDefaultValue::Get() returns the "built-in" default value +// for type T, which is NULL when T is a raw pointer type, 0 when T is +// a numeric type, false when T is bool, or "" when T is string or +// std::string. In addition, in C++11 and above, it turns a +// default-constructed T value if T is default constructible. For any +// other type T, the built-in default T value is undefined, and the +// function will abort the process. +template +class BuiltInDefaultValue { + public: + // This function returns true if and only if type T has a built-in default + // value. + static bool Exists() { + return ::std::is_default_constructible::value; + } + + static T Get() { + return BuiltInDefaultValueGetter< + T, ::std::is_default_constructible::value>::Get(); + } +}; + +// This partial specialization says that we use the same built-in +// default value for T and const T. +template +class BuiltInDefaultValue { + public: + static bool Exists() { return BuiltInDefaultValue::Exists(); } + static T Get() { return BuiltInDefaultValue::Get(); } +}; + +// This partial specialization defines the default values for pointer +// types. +template +class BuiltInDefaultValue { + public: + static bool Exists() { return true; } + static T* Get() { return nullptr; } +}; + +// The following specializations define the default values for +// specific types we care about. +#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \ + template <> \ + class BuiltInDefaultValue { \ + public: \ + static bool Exists() { return true; } \ + static type Get() { return value; } \ + } + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, ""); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0'); + +// There's no need for a default action for signed wchar_t, as that +// type is the same as wchar_t for gcc, and invalid for MSVC. +// +// There's also no need for a default action for unsigned wchar_t, as +// that type is the same as unsigned int for gcc, and invalid for +// MSVC. +#if GMOCK_WCHAR_T_IS_NATIVE_ +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT +#endif + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); + +#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ + +} // namespace internal + +// When an unexpected function call is encountered, Google Mock will +// let it return a default value if the user has specified one for its +// return type, or if the return type has a built-in default value; +// otherwise Google Mock won't know what value to return and will have +// to abort the process. +// +// The DefaultValue class allows a user to specify the +// default value for a type T that is both copyable and publicly +// destructible (i.e. anything that can be used as a function return +// type). The usage is: +// +// // Sets the default value for type T to be foo. +// DefaultValue::Set(foo); +template +class DefaultValue { + public: + // Sets the default value for type T; requires T to be + // copy-constructable and have a public destructor. + static void Set(T x) { + delete producer_; + producer_ = new FixedValueProducer(x); + } + + // Provides a factory function to be called to generate the default value. + // This method can be used even if T is only move-constructible, but it is not + // limited to that case. + typedef T (*FactoryFunction)(); + static void SetFactory(FactoryFunction factory) { + delete producer_; + producer_ = new FactoryValueProducer(factory); + } + + // Unsets the default value for type T. + static void Clear() { + delete producer_; + producer_ = nullptr; + } + + // Returns true if and only if the user has set the default value for type T. + static bool IsSet() { return producer_ != nullptr; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue::Exists(); + } + + // Returns the default value for type T if the user has set one; + // otherwise returns the built-in default value. Requires that Exists() + // is true, which ensures that the return value is well-defined. + static T Get() { + return producer_ == nullptr ? internal::BuiltInDefaultValue::Get() + : producer_->Produce(); + } + + private: + class ValueProducer { + public: + virtual ~ValueProducer() {} + virtual T Produce() = 0; + }; + + class FixedValueProducer : public ValueProducer { + public: + explicit FixedValueProducer(T value) : value_(value) {} + T Produce() override { return value_; } + + private: + const T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); + }; + + class FactoryValueProducer : public ValueProducer { + public: + explicit FactoryValueProducer(FactoryFunction factory) + : factory_(factory) {} + T Produce() override { return factory_(); } + + private: + const FactoryFunction factory_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); + }; + + static ValueProducer* producer_; +}; + +// This partial specialization allows a user to set default values for +// reference types. +template +class DefaultValue { + public: + // Sets the default value for type T&. + static void Set(T& x) { // NOLINT + address_ = &x; + } + + // Unsets the default value for type T&. + static void Clear() { address_ = nullptr; } + + // Returns true if and only if the user has set the default value for type T&. + static bool IsSet() { return address_ != nullptr; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue::Exists(); + } + + // Returns the default value for type T& if the user has set one; + // otherwise returns the built-in default value if there is one; + // otherwise aborts the process. + static T& Get() { + return address_ == nullptr ? internal::BuiltInDefaultValue::Get() + : *address_; + } + + private: + static T* address_; +}; + +// This specialization allows DefaultValue::Get() to +// compile. +template <> +class DefaultValue { + public: + static bool Exists() { return true; } + static void Get() {} +}; + +// Points to the user-set default value for type T. +template +typename DefaultValue::ValueProducer* DefaultValue::producer_ = nullptr; + +// Points to the user-set default value for type T&. +template +T* DefaultValue::address_ = nullptr; + +// Implement this interface to define an action for function type F. +template +class ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + ActionInterface() {} + virtual ~ActionInterface() {} + + // Performs the action. This method is not const, as in general an + // action can have side effects and be stateful. For example, a + // get-the-next-element-from-the-collection action will need to + // remember the current element. + virtual Result Perform(const ArgumentTuple& args) = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); +}; + +// An Action is a copyable and IMMUTABLE (except by assignment) +// object that represents an action to be taken when a mock function +// of type F is called. The implementation of Action is just a +// std::shared_ptr to const ActionInterface. Don't inherit from Action! +// You can view an object implementing ActionInterface as a +// concrete action (including its current state), and an Action +// object as a handle to it. +template +class Action { + // Adapter class to allow constructing Action from a legacy ActionInterface. + // New code should create Actions from functors instead. + struct ActionAdapter { + // Adapter must be copyable to satisfy std::function requirements. + ::std::shared_ptr> impl_; + + template + typename internal::Function::Result operator()(Args&&... args) { + return impl_->Perform( + ::std::forward_as_tuple(::std::forward(args)...)); + } + }; + + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + // Constructs a null Action. Needed for storing Action objects in + // STL containers. + Action() {} + + // Construct an Action from a specified callable. + // This cannot take std::function directly, because then Action would not be + // directly constructible from lambda (it would require two conversions). + template , G>::value>::type> + Action(G&& fun) : fun_(::std::forward(fun)) {} // NOLINT + + // Constructs an Action from its implementation. + explicit Action(ActionInterface* impl) + : fun_(ActionAdapter{::std::shared_ptr>(impl)}) {} + + // This constructor allows us to turn an Action object into an + // Action, as long as F's arguments can be implicitly converted + // to Func's and Func's return type can be implicitly converted to F's. + template + explicit Action(const Action& action) : fun_(action.fun_) {} + + // Returns true if and only if this is the DoDefault() action. + bool IsDoDefault() const { return fun_ == nullptr; } + + // Performs the action. Note that this method is const even though + // the corresponding method in ActionInterface is not. The reason + // is that a const Action means that it cannot be re-bound to + // another concrete action, not that the concrete action it binds to + // cannot change state. (Think of the difference between a const + // pointer and a pointer to const.) + Result Perform(ArgumentTuple args) const { + if (IsDoDefault()) { + internal::IllegalDoDefault(__FILE__, __LINE__); + } + return internal::Apply(fun_, ::std::move(args)); + } + + private: + template + friend class Action; + + // fun_ is an empty function if and only if this is the DoDefault() action. + ::std::function fun_; +}; + +// The PolymorphicAction class template makes it easy to implement a +// polymorphic action (i.e. an action that can be used in mock +// functions of than one type, e.g. Return()). +// +// To define a polymorphic action, a user first provides a COPYABLE +// implementation class that has a Perform() method template: +// +// class FooAction { +// public: +// template +// Result Perform(const ArgumentTuple& args) const { +// // Processes the arguments and returns a result, using +// // std::get(args) to get the N-th (0-based) argument in the tuple. +// } +// ... +// }; +// +// Then the user creates the polymorphic action using +// MakePolymorphicAction(object) where object has type FooAction. See +// the definition of Return(void) and SetArgumentPointee(value) for +// complete examples. +template +class PolymorphicAction { + public: + explicit PolymorphicAction(const Impl& impl) : impl_(impl) {} + + template + operator Action() const { + return Action(new MonomorphicImpl(impl_)); + } + + private: + template + class MonomorphicImpl : public ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} + + Result Perform(const ArgumentTuple& args) override { + return impl_.template Perform(args); + } + + private: + Impl impl_; + + GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); + }; + + Impl impl_; + + GTEST_DISALLOW_ASSIGN_(PolymorphicAction); +}; + +// Creates an Action from its implementation and returns it. The +// created Action object owns the implementation. +template +Action MakeAction(ActionInterface* impl) { + return Action(impl); +} + +// Creates a polymorphic action from its implementation. This is +// easier to use than the PolymorphicAction constructor as it +// doesn't require you to explicitly write the template argument, e.g. +// +// MakePolymorphicAction(foo); +// vs +// PolymorphicAction(foo); +template +inline PolymorphicAction MakePolymorphicAction(const Impl& impl) { + return PolymorphicAction(impl); +} + +namespace internal { + +// Helper struct to specialize ReturnAction to execute a move instead of a copy +// on return. Useful for move-only types, but could be used on any type. +template +struct ByMoveWrapper { + explicit ByMoveWrapper(T value) : payload(std::move(value)) {} + T payload; +}; + +// Implements the polymorphic Return(x) action, which can be used in +// any function that returns the type of x, regardless of the argument +// types. +// +// Note: The value passed into Return must be converted into +// Function::Result when this action is cast to Action rather than +// when that action is performed. This is important in scenarios like +// +// MOCK_METHOD1(Method, T(U)); +// ... +// { +// Foo foo; +// X x(&foo); +// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x)); +// } +// +// In the example above the variable x holds reference to foo which leaves +// scope and gets destroyed. If copying X just copies a reference to foo, +// that copy will be left with a hanging reference. If conversion to T +// makes a copy of foo, the above code is safe. To support that scenario, we +// need to make sure that the type conversion happens inside the EXPECT_CALL +// statement, and conversion of the result of Return to Action is a +// good place for that. +// +// The real life example of the above scenario happens when an invocation +// of gtl::Container() is passed into Return. +// +template +class ReturnAction { + public: + // Constructs a ReturnAction object from the value to be returned. + // 'value' is passed by value instead of by const reference in order + // to allow Return("string literal") to compile. + explicit ReturnAction(R value) : value_(new R(std::move(value))) {} + + // This template type conversion operator allows Return(x) to be + // used in ANY function that returns x's type. + template + operator Action() const { // NOLINT + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename Function::Result Result; + GTEST_COMPILE_ASSERT_( + !std::is_reference::value, + use_ReturnRef_instead_of_Return_to_return_a_reference); + static_assert(!std::is_void::value, + "Can't use Return() on an action expected to return `void`."); + return Action(new Impl(value_)); + } + + private: + // Implements the Return(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + // The implicit cast is necessary when Result has more than one + // single-argument constructor (e.g. Result is std::vector) and R + // has a type conversion operator template. In that case, value_(value) + // won't compile as the compiler doesn't known which constructor of + // Result to call. ImplicitCast_ forces the compiler to convert R to + // Result without considering explicit constructors, thus resolving the + // ambiguity. value_ is then initialized using its copy constructor. + explicit Impl(const std::shared_ptr& value) + : value_before_cast_(*value), + value_(ImplicitCast_(value_before_cast_)) {} + + Result Perform(const ArgumentTuple&) override { return value_; } + + private: + GTEST_COMPILE_ASSERT_(!std::is_reference::value, + Result_cannot_be_a_reference_type); + // We save the value before casting just in case it is being cast to a + // wrapper type. + R value_before_cast_; + Result value_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + }; + + // Partially specialize for ByMoveWrapper. This version of ReturnAction will + // move its contents instead. + template + class Impl, F> : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const std::shared_ptr& wrapper) + : performed_(false), wrapper_(wrapper) {} + + Result Perform(const ArgumentTuple&) override { + GTEST_CHECK_(!performed_) + << "A ByMove() action should only be performed once."; + performed_ = true; + return std::move(wrapper_->payload); + } + + private: + bool performed_; + const std::shared_ptr wrapper_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const std::shared_ptr value_; + + GTEST_DISALLOW_ASSIGN_(ReturnAction); +}; + +// Implements the ReturnNull() action. +class ReturnNullAction { + public: + // Allows ReturnNull() to be used in any pointer-returning function. In C++11 + // this is enforced by returning nullptr, and in non-C++11 by asserting a + // pointer type on compile time. + template + static Result Perform(const ArgumentTuple&) { + return nullptr; + } +}; + +// Implements the Return() action. +class ReturnVoidAction { + public: + // Allows Return() to be used in any void-returning function. + template + static void Perform(const ArgumentTuple&) { + static_assert(std::is_void::value, "Result should be void."); + } +}; + +// Implements the polymorphic ReturnRef(x) action, which can be used +// in any function that returns a reference to the type of x, +// regardless of the argument types. +template +class ReturnRefAction { + public: + // Constructs a ReturnRefAction object from the reference to be returned. + explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT + + // This template type conversion operator allows ReturnRef(x) to be + // used in ANY function that returns a reference to x's type. + template + operator Action() const { + typedef typename Function::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRef(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_(std::is_reference::value, + use_Return_instead_of_ReturnRef_to_return_a_value); + return Action(new Impl(ref_)); + } + + private: + // Implements the ReturnRef(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(T& ref) : ref_(ref) {} // NOLINT + + Result Perform(const ArgumentTuple&) override { return ref_; } + + private: + T& ref_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + T& ref_; + + GTEST_DISALLOW_ASSIGN_(ReturnRefAction); +}; + +// Implements the polymorphic ReturnRefOfCopy(x) action, which can be +// used in any function that returns a reference to the type of x, +// regardless of the argument types. +template +class ReturnRefOfCopyAction { + public: + // Constructs a ReturnRefOfCopyAction object from the reference to + // be returned. + explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT + + // This template type conversion operator allows ReturnRefOfCopy(x) to be + // used in ANY function that returns a reference to x's type. + template + operator Action() const { + typedef typename Function::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRefOfCopy(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_( + std::is_reference::value, + use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); + return Action(new Impl(value_)); + } + + private: + // Implements the ReturnRefOfCopy(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const T& value) : value_(value) {} // NOLINT + + Result Perform(const ArgumentTuple&) override { return value_; } + + private: + T value_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const T value_; + + GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction); +}; + +// Implements the polymorphic DoDefault() action. +class DoDefaultAction { + public: + // This template type conversion operator allows DoDefault() to be + // used in any function. + template + operator Action() const { return Action(); } // NOLINT +}; + +// Implements the Assign action to set a given pointer referent to a +// particular value. +template +class AssignAction { + public: + AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} + + template + void Perform(const ArgumentTuple& /* args */) const { + *ptr_ = value_; + } + + private: + T1* const ptr_; + const T2 value_; + + GTEST_DISALLOW_ASSIGN_(AssignAction); +}; + +#if !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetErrnoAndReturn action to simulate return from +// various system calls and libc functions. +template +class SetErrnoAndReturnAction { + public: + SetErrnoAndReturnAction(int errno_value, T result) + : errno_(errno_value), + result_(result) {} + template + Result Perform(const ArgumentTuple& /* args */) const { + errno = errno_; + return result_; + } + + private: + const int errno_; + const T result_; + + GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction); +}; + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetArgumentPointee(x) action for any function +// whose N-th argument (0-based) is a pointer to x's type. +template +struct SetArgumentPointeeAction { + A value; + + template + void operator()(const Args&... args) const { + *::std::get(std::tie(args...)) = value; + } +}; + +// Implements the Invoke(object_ptr, &Class::Method) action. +template +struct InvokeMethodAction { + Class* const obj_ptr; + const MethodPtr method_ptr; + + template + auto operator()(Args&&... args) const + -> decltype((obj_ptr->*method_ptr)(std::forward(args)...)) { + return (obj_ptr->*method_ptr)(std::forward(args)...); + } +}; + +// Implements the InvokeWithoutArgs(f) action. The template argument +// FunctionImpl is the implementation type of f, which can be either a +// function pointer or a functor. InvokeWithoutArgs(f) can be used as an +// Action as long as f's type is compatible with F. +template +struct InvokeWithoutArgsAction { + FunctionImpl function_impl; + + // Allows InvokeWithoutArgs(f) to be used as any action whose type is + // compatible with f. + template + auto operator()(const Args&...) -> decltype(function_impl()) { + return function_impl(); + } +}; + +// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action. +template +struct InvokeMethodWithoutArgsAction { + Class* const obj_ptr; + const MethodPtr method_ptr; + + using ReturnType = typename std::result_of::type; + + template + ReturnType operator()(const Args&...) const { + return (obj_ptr->*method_ptr)(); + } +}; + +// Implements the IgnoreResult(action) action. +template +class IgnoreResultAction { + public: + explicit IgnoreResultAction(const A& action) : action_(action) {} + + template + operator Action() const { + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename internal::Function::Result Result; + + // Asserts at compile time that F returns void. + static_assert(std::is_void::value, "Result type should be void."); + + return Action(new Impl(action_)); + } + + private: + template + class Impl : public ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const A& action) : action_(action) {} + + void Perform(const ArgumentTuple& args) override { + // Performs the action and ignores its result. + action_.Perform(args); + } + + private: + // Type OriginalFunction is the same as F except that its return + // type is IgnoredValue. + typedef typename internal::Function::MakeResultIgnoredValue + OriginalFunction; + + const Action action_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const A action_; + + GTEST_DISALLOW_ASSIGN_(IgnoreResultAction); +}; + +template +struct WithArgsAction { + InnerAction action; + + // The inner action could be anything convertible to Action. + // We use the conversion operator to detect the signature of the inner Action. + template + operator Action() const { // NOLINT + Action>::type...)> + converted(action); + + return [converted](Args... args) -> R { + return converted.Perform(std::forward_as_tuple( + std::get(std::forward_as_tuple(std::forward(args)...))...)); + }; + } +}; + +template +struct DoAllAction { + private: + template + std::vector> Convert(IndexSequence) const { + return {std::get(actions)...}; + } + + public: + std::tuple actions; + + template + operator Action() const { // NOLINT + struct Op { + std::vector> converted; + Action last; + R operator()(Args... args) const { + auto tuple_args = std::forward_as_tuple(std::forward(args)...); + for (auto& a : converted) { + a.Perform(tuple_args); + } + return last.Perform(tuple_args); + } + }; + return Op{Convert(MakeIndexSequence()), + std::get(actions)}; + } +}; + +} // namespace internal + +// An Unused object can be implicitly constructed from ANY value. +// This is handy when defining actions that ignore some or all of the +// mock function arguments. For example, given +// +// MOCK_METHOD3(Foo, double(const string& label, double x, double y)); +// MOCK_METHOD3(Bar, double(int index, double x, double y)); +// +// instead of +// +// double DistanceToOriginWithLabel(const string& label, double x, double y) { +// return sqrt(x*x + y*y); +// } +// double DistanceToOriginWithIndex(int index, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXPECT_CALL(mock, Foo("abc", _, _)) +// .WillOnce(Invoke(DistanceToOriginWithLabel)); +// EXPECT_CALL(mock, Bar(5, _, _)) +// .WillOnce(Invoke(DistanceToOriginWithIndex)); +// +// you could write +// +// // We can declare any uninteresting argument as Unused. +// double DistanceToOrigin(Unused, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); +// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); +typedef internal::IgnoredValue Unused; + +// Creates an action that does actions a1, a2, ..., sequentially in +// each invocation. +template +internal::DoAllAction::type...> DoAll( + Action&&... action) { + return {std::forward_as_tuple(std::forward(action)...)}; +} + +// WithArg(an_action) creates an action that passes the k-th +// (0-based) argument of the mock function to an_action and performs +// it. It adapts an action accepting one argument to one that accepts +// multiple arguments. For convenience, we also provide +// WithArgs(an_action) (defined below) as a synonym. +template +internal::WithArgsAction::type, k> +WithArg(InnerAction&& action) { + return {std::forward(action)}; +} + +// WithArgs(an_action) creates an action that passes +// the selected arguments of the mock function to an_action and +// performs it. It serves as an adaptor between actions with +// different argument lists. +template +internal::WithArgsAction::type, k, ks...> +WithArgs(InnerAction&& action) { + return {std::forward(action)}; +} + +// WithoutArgs(inner_action) can be used in a mock function with a +// non-empty argument list to perform inner_action, which takes no +// argument. In other words, it adapts an action accepting no +// argument to one that accepts (and ignores) arguments. +template +internal::WithArgsAction::type> +WithoutArgs(InnerAction&& action) { + return {std::forward(action)}; +} + +// Creates an action that returns 'value'. 'value' is passed by value +// instead of const reference - otherwise Return("string literal") +// will trigger a compiler error about using array as initializer. +template +internal::ReturnAction Return(R value) { + return internal::ReturnAction(std::move(value)); +} + +// Creates an action that returns NULL. +inline PolymorphicAction ReturnNull() { + return MakePolymorphicAction(internal::ReturnNullAction()); +} + +// Creates an action that returns from a void function. +inline PolymorphicAction Return() { + return MakePolymorphicAction(internal::ReturnVoidAction()); +} + +// Creates an action that returns the reference to a variable. +template +inline internal::ReturnRefAction ReturnRef(R& x) { // NOLINT + return internal::ReturnRefAction(x); +} + +// Creates an action that returns the reference to a copy of the +// argument. The copy is created when the action is constructed and +// lives as long as the action. +template +inline internal::ReturnRefOfCopyAction ReturnRefOfCopy(const R& x) { + return internal::ReturnRefOfCopyAction(x); +} + +// Modifies the parent action (a Return() action) to perform a move of the +// argument instead of a copy. +// Return(ByMove()) actions can only be executed once and will assert this +// invariant. +template +internal::ByMoveWrapper ByMove(R x) { + return internal::ByMoveWrapper(std::move(x)); +} + +// Creates an action that does the default action for the give mock function. +inline internal::DoDefaultAction DoDefault() { + return internal::DoDefaultAction(); +} + +// Creates an action that sets the variable pointed by the N-th +// (0-based) function argument to 'value'. +template +internal::SetArgumentPointeeAction SetArgPointee(T x) { + return {std::move(x)}; +} + +// The following version is DEPRECATED. +template +internal::SetArgumentPointeeAction SetArgumentPointee(T x) { + return {std::move(x)}; +} + +// Creates an action that sets a pointer referent to a given value. +template +PolymorphicAction > Assign(T1* ptr, T2 val) { + return MakePolymorphicAction(internal::AssignAction(ptr, val)); +} + +#if !GTEST_OS_WINDOWS_MOBILE + +// Creates an action that sets errno and returns the appropriate error. +template +PolymorphicAction > +SetErrnoAndReturn(int errval, T result) { + return MakePolymorphicAction( + internal::SetErrnoAndReturnAction(errval, result)); +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Various overloads for Invoke(). + +// Legacy function. +// Actions can now be implicitly constructed from callables. No need to create +// wrapper objects. +// This function exists for backwards compatibility. +template +typename std::decay::type Invoke(FunctionImpl&& function_impl) { + return std::forward(function_impl); +} + +// Creates an action that invokes the given method on the given object +// with the mock function's arguments. +template +internal::InvokeMethodAction Invoke(Class* obj_ptr, + MethodPtr method_ptr) { + return {obj_ptr, method_ptr}; +} + +// Creates an action that invokes 'function_impl' with no argument. +template +internal::InvokeWithoutArgsAction::type> +InvokeWithoutArgs(FunctionImpl function_impl) { + return {std::move(function_impl)}; +} + +// Creates an action that invokes the given method on the given object +// with no argument. +template +internal::InvokeMethodWithoutArgsAction InvokeWithoutArgs( + Class* obj_ptr, MethodPtr method_ptr) { + return {obj_ptr, method_ptr}; +} + +// Creates an action that performs an_action and throws away its +// result. In other words, it changes the return type of an_action to +// void. an_action MUST NOT return void, or the code won't compile. +template +inline internal::IgnoreResultAction IgnoreResult(const A& an_action) { + return internal::IgnoreResultAction(an_action); +} + +// Creates a reference wrapper for the given L-value. If necessary, +// you can explicitly specify the type of the reference. For example, +// suppose 'derived' is an object of type Derived, ByRef(derived) +// would wrap a Derived&. If you want to wrap a const Base& instead, +// where Base is a base class of Derived, just write: +// +// ByRef(derived) +// +// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper. +// However, it may still be used for consistency with ByMove(). +template +inline ::std::reference_wrapper ByRef(T& l_value) { // NOLINT + return ::std::reference_wrapper(l_value); +} + +} // namespace testing + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-cardinalities.h b/src/test/gtest/googlemock/include/gmock/gmock-cardinalities.h new file mode 100644 index 00000000..46e01e10 --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-cardinalities.h @@ -0,0 +1,157 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used cardinalities. More +// cardinalities can be defined by the user implementing the +// CardinalityInterface interface if necessary. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ + +#include +#include +#include // NOLINT +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// To implement a cardinality Foo, define: +// 1. a class FooCardinality that implements the +// CardinalityInterface interface, and +// 2. a factory function that creates a Cardinality object from a +// const FooCardinality*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Cardinality objects can now be copied like plain values. + +// The implementation of a cardinality. +class CardinalityInterface { + public: + virtual ~CardinalityInterface() {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + virtual int ConservativeLowerBound() const { return 0; } + virtual int ConservativeUpperBound() const { return INT_MAX; } + + // Returns true if and only if call_count calls will satisfy this + // cardinality. + virtual bool IsSatisfiedByCallCount(int call_count) const = 0; + + // Returns true if and only if call_count calls will saturate this + // cardinality. + virtual bool IsSaturatedByCallCount(int call_count) const = 0; + + // Describes self to an ostream. + virtual void DescribeTo(::std::ostream* os) const = 0; +}; + +// A Cardinality is a copyable and IMMUTABLE (except by assignment) +// object that specifies how many times a mock function is expected to +// be called. The implementation of Cardinality is just a std::shared_ptr +// to const CardinalityInterface. Don't inherit from Cardinality! +class GTEST_API_ Cardinality { + public: + // Constructs a null cardinality. Needed for storing Cardinality + // objects in STL containers. + Cardinality() {} + + // Constructs a Cardinality from its implementation. + explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } + int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } + + // Returns true if and only if call_count calls will satisfy this + // cardinality. + bool IsSatisfiedByCallCount(int call_count) const { + return impl_->IsSatisfiedByCallCount(call_count); + } + + // Returns true if and only if call_count calls will saturate this + // cardinality. + bool IsSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count); + } + + // Returns true if and only if call_count calls will over-saturate this + // cardinality, i.e. exceed the maximum number of allowed calls. + bool IsOverSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count) && + !impl_->IsSatisfiedByCallCount(call_count); + } + + // Describes self to an ostream + void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } + + // Describes the given actual call count to an ostream. + static void DescribeActualCallCountTo(int actual_call_count, + ::std::ostream* os); + + private: + std::shared_ptr impl_; +}; + +// Creates a cardinality that allows at least n calls. +GTEST_API_ Cardinality AtLeast(int n); + +// Creates a cardinality that allows at most n calls. +GTEST_API_ Cardinality AtMost(int n); + +// Creates a cardinality that allows any number of calls. +GTEST_API_ Cardinality AnyNumber(); + +// Creates a cardinality that allows between min and max calls. +GTEST_API_ Cardinality Between(int min, int max); + +// Creates a cardinality that allows exactly n calls. +GTEST_API_ Cardinality Exactly(int n); + +// Creates a cardinality from its implementation. +inline Cardinality MakeCardinality(const CardinalityInterface* c) { + return Cardinality(c); +} + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-function-mocker.h b/src/test/gtest/googlemock/include/gmock/gmock-function-mocker.h new file mode 100644 index 00000000..cc1535c8 --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-function-mocker.h @@ -0,0 +1,253 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements MOCK_METHOD. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT +#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT + +#include "gmock/gmock-generated-function-mockers.h" // NOLINT +#include "gmock/internal/gmock-pp.h" + +#define MOCK_METHOD(...) \ + GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \ + GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ()) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \ + GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ + GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \ + GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ + GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ + GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ + GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ + GMOCK_INTERNAL_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \ + (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args))) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_WRONG_ARITY(...) \ + static_assert( \ + false, \ + "MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \ + "_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \ + "enclosed in parentheses. If _Ret is a type with unprotected commas, " \ + "it must also be enclosed in parentheses.") + +#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \ + static_assert( \ + GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \ + GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.") + +#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \ + static_assert( \ + std::is_function<__VA_ARGS__>::value, \ + "Signature must be a function type, maybe return type contains " \ + "unprotected comma."); \ + static_assert( \ + ::testing::tuple_size::ArgumentTuple>::value == _N, \ + "This method does not take " GMOCK_PP_STRINGIZE( \ + _N) " arguments. Parenthesize all types with unproctected commas.") + +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec) + +#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \ + _Override, _Final, _Noexcept, \ + _CallType, _Signature) \ + typename ::testing::internal::Function::Result \ + GMOCK_INTERNAL_EXPAND(_CallType) \ + _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \ + GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \ + GMOCK_PP_IF(_Override, override, ) \ + GMOCK_PP_IF(_Final, final, ) { \ + GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .SetOwnerAndName(this, #_MethodName); \ + return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \ + } \ + ::testing::MockSpec gmock_##_MethodName( \ + GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \ + GMOCK_PP_IF(_Constness, const, ) { \ + GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \ + return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \ + } \ + ::testing::MockSpec gmock_##_MethodName( \ + const ::testing::internal::WithoutMatchers&, \ + GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \ + GMOCK_PP_REMOVE_PARENS(_Signature)>*) \ + const GMOCK_PP_IF(_Noexcept, noexcept, ) { \ + return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \ + GMOCK_PP_IF(_Constness, const, ))(this) \ + ->gmock_##_MethodName(GMOCK_PP_REPEAT( \ + GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \ + } \ + mutable ::testing::FunctionMocker \ + GMOCK_MOCKER_(_N, _Constness, _MethodName) + +#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__ + +// Five Valid modifiers. +#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple)) + +#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \ + GMOCK_PP_HAS_COMMA( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple)) + +#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple)) + +#define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \ + GMOCK_PP_HAS_COMMA( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple)) + +#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple) + +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ + static_assert( \ + (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ + GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \ + GMOCK_PP_STRINGIZE( \ + _elem) " cannot be recognized as a valid specification modifier."); + +// Modifiers implementation. +#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_CONST_I_const , + +#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override , + +#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_FINAL_I_final , + +// TODO(iserna): Maybe noexcept should accept an argument here as well. +#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept , + +#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \ + GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \ + GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \ + (_elem) + +// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and +// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows +// maybe they can be simplified somehow. +#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \ + GMOCK_INTERNAL_IS_CALLTYPE_I( \ + GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) +#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg) + +#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \ + GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \ + GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) +#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \ + GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg) + +#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype + +#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \ + GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \ + GMOCK_PP_IDENTITY) \ + (_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args)) + +#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \ + GMOCK_PP_IDENTITY) \ + (_elem) + +#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \ + GMOCK_PP_REMOVE_PARENS(_Signature)) \ + gmock_a##_i + +#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::std::forward( \ + gmock_a##_i) + +#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \ + GMOCK_PP_REMOVE_PARENS(_Signature)) \ + gmock_a##_i + +#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \ + GMOCK_PP_COMMA_IF(_i) \ + gmock_a##_i + +#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::testing::A() + +#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__) + +#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \ + GMOCK_MATCHER_(_tn, _i, __VA_ARGS__) + +#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h b/src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h new file mode 100644 index 00000000..981af78f --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h @@ -0,0 +1,1884 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-actions.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include +#include + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { +namespace internal { + +// A macro from the ACTION* family (defined later in this file) +// defines an action that can be used in a mock function. Typically, +// these actions only care about a subset of the arguments of the mock +// function. For example, if such an action only uses the second +// argument, it can be used in any mock function that takes >= 2 +// arguments where the type of the second argument is compatible. +// +// Therefore, the action implementation must be prepared to take more +// arguments than it needs. The ExcessiveArg type is used to +// represent those excessive arguments. In order to keep the compiler +// error messages tractable, we define it in the testing namespace +// instead of testing::internal. However, this is an INTERNAL TYPE +// and subject to change without notice, so a user MUST NOT USE THIS +// TYPE DIRECTLY. +struct ExcessiveArg {}; + +// A helper class needed for implementing the ACTION* macros. +template +class ActionHelper { + public: + static Result Perform(Impl* impl, const ::std::tuple<>& args) { + return impl->template gmock_PerformImpl<>(args, ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, std::get<0>(args), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, std::get<0>(args), + std::get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, + std::get<0>(args), std::get<1>(args), std::get<2>(args), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, + std::get<0>(args), std::get<1>(args), std::get<2>(args), + std::get<3>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, + std::get<0>(args), std::get<1>(args), std::get<2>(args), + std::get<3>(args), std::get<4>(args), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, + std::get<0>(args), std::get<1>(args), std::get<2>(args), + std::get<3>(args), std::get<4>(args), std::get<5>(args), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, + std::get<0>(args), std::get<1>(args), std::get<2>(args), + std::get<3>(args), std::get<4>(args), std::get<5>(args), + std::get<6>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, std::get<0>(args), std::get<1>(args), std::get<2>(args), + std::get<3>(args), std::get<4>(args), std::get<5>(args), + std::get<6>(args), std::get<7>(args), ExcessiveArg(), ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, std::get<0>(args), std::get<1>(args), std::get<2>(args), + std::get<3>(args), std::get<4>(args), std::get<5>(args), + std::get<6>(args), std::get<7>(args), std::get<8>(args), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::std::tuple& args) { + return impl->template gmock_PerformImpl(args, std::get<0>(args), std::get<1>(args), std::get<2>(args), + std::get<3>(args), std::get<4>(args), std::get<5>(args), + std::get<6>(args), std::get<7>(args), std::get<8>(args), + std::get<9>(args)); + } +}; + +} // namespace internal +} // namespace testing + +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template +// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// Users can, however, define any local functors (e.g. a lambda) that +// can be used as actions. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +// An internal macro needed for implementing ACTION*(). +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ + const args_type& args GTEST_ATTRIBUTE_UNUSED_, \ + const arg0_type& arg0 GTEST_ATTRIBUTE_UNUSED_, \ + const arg1_type& arg1 GTEST_ATTRIBUTE_UNUSED_, \ + const arg2_type& arg2 GTEST_ATTRIBUTE_UNUSED_, \ + const arg3_type& arg3 GTEST_ATTRIBUTE_UNUSED_, \ + const arg4_type& arg4 GTEST_ATTRIBUTE_UNUSED_, \ + const arg5_type& arg5 GTEST_ATTRIBUTE_UNUSED_, \ + const arg6_type& arg6 GTEST_ATTRIBUTE_UNUSED_, \ + const arg7_type& arg7 GTEST_ATTRIBUTE_UNUSED_, \ + const arg8_type& arg8 GTEST_ATTRIBUTE_UNUSED_, \ + const arg9_type& arg9 GTEST_ATTRIBUTE_UNUSED_ + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::std::get(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. +#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0 +#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) kind0 name0, kind1 name1 +#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) kind0 name0, kind1 name1, kind2 name2 +#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3 +#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \ + kind2 name2, kind3 name3, kind4 name4 +#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5 +#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \ + kind5 name5, kind6 name6 +#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \ + kind4 name4, kind5 name5, kind6 name6, kind7 name7 +#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \ + kind8 name8 +#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \ + kind6 name6, kind7 name7, kind8 name8, kind9 name9 + +// Lists the template parameters. +#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0 +#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) name0, name1 +#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) name0, name1, name2 +#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) name0, name1, name2, name3 +#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \ + name4 +#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \ + name2, name3, name4, name5 +#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) name0, name1, name2, name3, name4, name5, name6 +#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7 +#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \ + name6, name7, name8 +#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \ + name3, name4, name5, name6, name7, name8, name9 + +// Declares the types of value parameters. +#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \ + typename p0##_type, typename p1##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \ + typename p0##_type, typename p1##_type, typename p2##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type, typename p8##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \ + typename p2##_type, typename p3##_type, typename p4##_type, \ + typename p5##_type, typename p6##_type, typename p7##_type, \ + typename p8##_type, typename p9##_type + +// Initializes the value parameters. +#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\ + () +#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\ + (p0##_type gmock_p0) : p0(::std::move(gmock_p0)) +#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ + (p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)) +#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\ + (p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) +#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)) +#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) +#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)) +#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) +#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)) +#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) +#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \ + p9(::std::move(gmock_p9)) + +// Declares the fields for storing the value parameters. +#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0; +#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \ + p1##_type p1; +#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \ + p1##_type p1; p2##_type p2; +#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \ + p1##_type p1; p2##_type p2; p3##_type p3; +#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; +#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; +#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; +#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; p7##_type p7; +#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; +#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \ + p9##_type p9; + +// Lists the value parameters. +#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0 +#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1 +#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2 +#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3 +#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \ + p2, p3, p4 +#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \ + p1, p2, p3, p4, p5 +#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0, p1, p2, p3, p4, p5, p6 +#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0, p1, p2, p3, p4, p5, p6, p7 +#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8 +#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 + +// Lists the value parameter types. +#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \ + p1##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \ + p1##_type, p2##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + p0##_type, p1##_type, p2##_type, p3##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \ + p6##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type, p9##_type + +// Declares the value parameters. +#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0 +#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \ + p1##_type p1 +#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \ + p1##_type p1, p2##_type p2 +#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3 +#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4 +#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5 +#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6 +#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6, p7##_type p7 +#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8 +#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9 + +// The suffix of the class template implementing the action template. +#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P +#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2 +#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3 +#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4 +#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5 +#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6 +#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7 +#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) P8 +#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) P9 +#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) P10 + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +#define ACTION_TEMPLATE(name, template_params, value_params)\ + template \ + class GMOCK_ACTION_CLASS_(name, value_params) {\ + public:\ + explicit GMOCK_ACTION_CLASS_(name, value_params)\ + GMOCK_INTERNAL_INIT_##value_params {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(\ + new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ + }\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ + };\ + template \ + inline GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ + GMOCK_INTERNAL_DECL_##value_params) {\ + return GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ + GMOCK_INTERNAL_LIST_##value_params);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ + gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION(name)\ + class name##Action {\ + public:\ + name##Action() {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl() {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl());\ + }\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##Action);\ + };\ + inline name##Action name() {\ + return name##Action();\ + }\ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##Action::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P(name, p0)\ + template \ + class name##ActionP {\ + public:\ + explicit name##ActionP(p0##_type gmock_p0) : \ + p0(::std::forward(gmock_p0)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl(p0##_type gmock_p0) : \ + p0(::std::forward(gmock_p0)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0));\ + }\ + p0##_type p0;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP);\ + };\ + template \ + inline name##ActionP name(p0##_type p0) {\ + return name##ActionP(p0);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P2(name, p0, p1)\ + template \ + class name##ActionP2 {\ + public:\ + name##ActionP2(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP2);\ + };\ + template \ + inline name##ActionP2 name(p0##_type p0, \ + p1##_type p1) {\ + return name##ActionP2(p0, p1);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP2::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P3(name, p0, p1, p2)\ + template \ + class name##ActionP3 {\ + public:\ + name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP3);\ + };\ + template \ + inline name##ActionP3 name(p0##_type p0, \ + p1##_type p1, p2##_type p2) {\ + return name##ActionP3(p0, p1, p2);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP3::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P4(name, p0, p1, p2, p3)\ + template \ + class name##ActionP4 {\ + public:\ + name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP4);\ + };\ + template \ + inline name##ActionP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3) {\ + return name##ActionP4(p0, p1, \ + p2, p3);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP4::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P5(name, p0, p1, p2, p3, p4)\ + template \ + class name##ActionP5 {\ + public:\ + name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP5);\ + };\ + template \ + inline name##ActionP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4) {\ + return name##ActionP5(p0, p1, p2, p3, p4);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP5::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\ + template \ + class name##ActionP6 {\ + public:\ + name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP6);\ + };\ + template \ + inline name##ActionP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3, p4##_type p4, p5##_type p5) {\ + return name##ActionP6(p0, p1, p2, p3, p4, p5);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP6::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\ + template \ + class name##ActionP7 {\ + public:\ + name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP7);\ + };\ + template \ + inline name##ActionP7 name(p0##_type p0, p1##_type p1, \ + p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6) {\ + return name##ActionP7(p0, p1, p2, p3, p4, p5, p6);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP7::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\ + template \ + class name##ActionP8 {\ + public:\ + name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP8);\ + };\ + template \ + inline name##ActionP8 name(p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6, p7##_type p7) {\ + return name##ActionP8(p0, p1, p2, p3, p4, p5, \ + p6, p7);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP8::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\ + template \ + class name##ActionP9 {\ + public:\ + name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP9);\ + };\ + template \ + inline name##ActionP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ + p8##_type p8) {\ + return name##ActionP9(p0, p1, p2, \ + p3, p4, p5, p6, p7, p8);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP9::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\ + template \ + class name##ActionP10 {\ + public:\ + name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)), \ + p9(::std::forward(gmock_p9)) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::std::forward(gmock_p0)), \ + p1(::std::forward(gmock_p1)), \ + p2(::std::forward(gmock_p2)), \ + p3(::std::forward(gmock_p3)), \ + p4(::std::forward(gmock_p4)), \ + p5(::std::forward(gmock_p5)), \ + p6(::std::forward(gmock_p6)), \ + p7(::std::forward(gmock_p7)), \ + p8(::std::forward(gmock_p8)), \ + p9(::std::forward(gmock_p9)) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, \ + const arg0_type& arg0, const arg1_type& arg1, \ + const arg2_type& arg2, const arg3_type& arg3, \ + const arg4_type& arg4, const arg5_type& arg5, \ + const arg6_type& arg6, const arg7_type& arg7, \ + const arg8_type& arg8, const arg9_type& arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP10);\ + };\ + template \ + inline name##ActionP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9) {\ + return name##ActionP10(p0, \ + p1, p2, p3, p4, p5, p6, p7, p8, p9);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP10::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +namespace testing { + + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +// Various overloads for InvokeArgument(). +// +// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside ByRef(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but ByRef() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. + +namespace internal { +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/callback-actions.h header. + +template +R InvokeArgumentAdl(AdlTag, F f) { + return f(); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1) { + return f(a1); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) { + return f(a1, a2); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) { + return f(a1, a2, a3); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) { + return f(a1, a2, a3, a4); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + return f(a1, a2, a3, a4, a5); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + return f(a1, a2, a3, a4, a5, a6); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7) { + return f(a1, a2, a3, a4, a5, a6, a7); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8) { + return f(a1, a2, a3, a4, a5, a6, a7, a8); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9, A10 a10) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); +} +} // namespace invoke_argument +} // namespace internal + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_0_VALUE_PARAMS()) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args)); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_1_VALUE_PARAMS(p0)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_2_VALUE_PARAMS(p0, p1)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_3_VALUE_PARAMS(p0, p1, p2)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6, p7); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); +} + +// Various overloads for ReturnNew(). +// +// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new +// instance of type T, constructed on the heap with constructor arguments +// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_0_VALUE_PARAMS()) { + return new T(); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_1_VALUE_PARAMS(p0)) { + return new T(p0); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_2_VALUE_PARAMS(p0, p1)) { + return new T(p0, p1); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_3_VALUE_PARAMS(p0, p1, p2)) { + return new T(p0, p1, p2); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { + return new T(p0, p1, p2, p3); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { + return new T(p0, p1, p2, p3, p4); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { + return new T(p0, p1, p2, p3, p4, p5); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { + return new T(p0, p1, p2, p3, p4, p5, p6); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +// Include any custom callback actions added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gmock/internal/custom/gmock-generated-actions.h" + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h.pump b/src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h.pump new file mode 100644 index 00000000..209603c5 --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-generated-actions.h.pump @@ -0,0 +1,627 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert it to +$$ gmock-generated-actions.h. +$$ +$var n = 10 $$ The maximum arity we support. +$$}} This meta comment fixes auto-indentation in editors. +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include +#include + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { +namespace internal { + +// A macro from the ACTION* family (defined later in this file) +// defines an action that can be used in a mock function. Typically, +// these actions only care about a subset of the arguments of the mock +// function. For example, if such an action only uses the second +// argument, it can be used in any mock function that takes >= 2 +// arguments where the type of the second argument is compatible. +// +// Therefore, the action implementation must be prepared to take more +// arguments than it needs. The ExcessiveArg type is used to +// represent those excessive arguments. In order to keep the compiler +// error messages tractable, we define it in the testing namespace +// instead of testing::internal. However, this is an INTERNAL TYPE +// and subject to change without notice, so a user MUST NOT USE THIS +// TYPE DIRECTLY. +struct ExcessiveArg {}; + +// A helper class needed for implementing the ACTION* macros. +template +class ActionHelper { + public: +$range i 0..n +$for i + +[[ +$var template = [[$if i==0 [[]] $else [[ +$range j 0..i-1 + template <$for j, [[typename A$j]]> +]]]] +$range j 0..i-1 +$var As = [[$for j, [[A$j]]]] +$var as = [[$for j, [[std::get<$j>(args)]]]] +$range k 1..n-i +$var eas = [[$for k, [[ExcessiveArg()]]]] +$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]] +$template + static Result Perform(Impl* impl, const ::std::tuple<$As>& args) { + return impl->template gmock_PerformImpl<$As>(args, $arg_list); + } + +]] +}; + +} // namespace internal +} // namespace testing + +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template +// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// Users can, however, define any local functors (e.g. a lambda) that +// can be used as actions. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +$range i 0..n +$range k 0..n-1 + +// An internal macro needed for implementing ACTION*(). +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ + const args_type& args GTEST_ATTRIBUTE_UNUSED_ +$for k [[, \ + const arg$k[[]]_type& arg$k GTEST_ATTRIBUTE_UNUSED_]] + + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::std::get(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. + +$range j 1..n +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_DECL_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]] + + +]] + +// Lists the template parameters. + +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_LIST_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]] + + +]] + +// Declares the types of value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] + + +]] + +// Initializes the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ + ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]] + + +]] + +// Declares the fields for storing the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DEFN_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]] + + +]] + +// Lists the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]] + + +]] + +// Lists the value parameter types. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]] + + +]] + +// Declares the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$for j, [[p$j##_type p$j]] + + +]] + +// The suffix of the class template implementing the action template. +$for i [[ + + +$range j 0..i-1 +#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$if i==1 [[P]] $elif i>=2 [[P$i]] +]] + + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +$range k 0..n-1 + +#define ACTION_TEMPLATE(name, template_params, value_params)\ + template \ + class GMOCK_ACTION_CLASS_(name, value_params) {\ + public:\ + explicit GMOCK_ACTION_CLASS_(name, value_params)\ + GMOCK_INTERNAL_INIT_##value_params {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template <$for k, [[typename arg$k[[]]_type]]>\ + return_type gmock_PerformImpl(const args_type& args[[]] +$for k [[, const arg$k[[]]_type& arg$k]]) const;\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(\ + new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ + }\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ + };\ + template \ + inline GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ + GMOCK_INTERNAL_DECL_##value_params) {\ + return GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ + GMOCK_INTERNAL_LIST_##value_params);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ + gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +$for i + +[[ +$var template = [[$if i==0 [[]] $else [[ +$range j 0..i-1 + + template <$for j, [[typename p$j##_type]]>\ +]]]] +$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] + $else [[P$i]]]]]] +$range j 0..i-1 +$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::forward(gmock_p$j))]]]]]] +$var param_field_decls = [[$for j +[[ + + p$j##_type p$j;\ +]]]] +$var param_field_decls2 = [[$for j +[[ + + p$j##_type p$j;\ +]]]] +$var params = [[$for j, [[p$j]]]] +$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] +$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]] +$var arg_types_and_names = [[$for k, [[const arg$k[[]]_type& arg$k]]]] +$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]] + $else [[ACTION_P$i]]]] + +#define $macro_name(name$for j [[, p$j]])\$template + class $class_name {\ + public:\ + [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template <$typename_arg_types>\ + return_type gmock_PerformImpl(const args_type& args, [[]] +$arg_types_and_names) const;\$param_field_decls + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl($params));\ + }\$param_field_decls2 + private:\ + GTEST_DISALLOW_ASSIGN_($class_name);\ + };\$template + inline $class_name$param_types name($param_types_and_names) {\ + return $class_name$param_types($params);\ + }\$template + template \ + template <$typename_arg_types>\ + typename ::testing::internal::Function::Result\ + $class_name$param_types::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const +]] +$$ } // This meta comment fixes auto-indentation in Emacs. It won't +$$ // show up in the generated code. + + +namespace testing { + + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +// Various overloads for InvokeArgument(). +// +// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside ByRef(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but ByRef() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. + +namespace internal { +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/callback-actions.h header. + +$range i 0..n +$for i +[[ +$range j 1..i + +template +R InvokeArgumentAdl(AdlTag, F f[[$for j [[, A$j a$j]]]]) { + return f([[$for j, [[a$j]]]]); +} +]] + +} // namespace invoke_argument +} // namespace internal + +$range i 0..n +$for i [[ +$range j 0..i-1 + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::std::get(args)$for j [[, p$j]]); +} + +]] + +// Various overloads for ReturnNew(). +// +// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new +// instance of type T, constructed on the heap with constructor arguments +// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. +$range i 0..n +$for i [[ +$range j 0..i-1 +$var ps = [[$for j, [[p$j]]]] + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_$i[[]]_VALUE_PARAMS($ps)) { + return new T($ps); +} + +]] + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +// Include any custom callback actions added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gmock/internal/custom/gmock-generated-actions.h" + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h b/src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h new file mode 100644 index 00000000..cd957817 --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h @@ -0,0 +1,752 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-function-mockers.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements function mockers of various arities. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ + +#include +#include + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" + +namespace testing { +namespace internal { +// Removes the given pointer; this is a helper for the expectation setter method +// for parameterless matchers. +// +// We want to make sure that the user cannot set a parameterless expectation on +// overloaded methods, including methods which are overloaded on const. Example: +// +// class MockClass { +// MOCK_METHOD0(GetName, string&()); +// MOCK_CONST_METHOD0(GetName, const string&()); +// }; +// +// TEST() { +// // This should be an error, as it's not clear which overload is expected. +// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); +// } +// +// Here are the generated expectation-setter methods: +// +// class MockClass { +// // Overload 1 +// MockSpec gmock_GetName() { ... } +// // Overload 2. Declared const so that the compiler will generate an +// // error when trying to resolve between this and overload 4 in +// // 'gmock_GetName(WithoutMatchers(), nullptr)'. +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Removes const from this, calls overload 1 +// return AdjustConstness_(this)->gmock_GetName(); +// } +// +// // Overload 3 +// const string& gmock_GetName() const { ... } +// // Overload 4 +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Does not remove const, calls overload 3 +// return AdjustConstness_const(this)->gmock_GetName(); +// } +// } +// +template +const MockType* AdjustConstness_const(const MockType* mock) { + return mock; +} + +// Removes const from and returns the given pointer; this is a helper for the +// expectation setter method for parameterless matchers. +template +MockType* AdjustConstness_(const MockType* mock) { + return const_cast(mock); +} + +} // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; + +// GMOCK_RESULT_(tn, F) expands to the result type of function type F. +// We define this as a variadic macro in case F contains unprotected +// commas (the same reason that we use variadic macros in other places +// in this file). +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_RESULT_(tn, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Result + +// The type of argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_ARG_(tn, N, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::template Arg::type + +// The matcher type for argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MATCHER_(tn, N, ...) \ + const ::testing::Matcher& + +// The variable for mocking the given method. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ + static_assert(0 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + ) constness { \ + GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(0, constness, Method).Invoke(); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method() constness { \ + GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(0, constness, Method).With(); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ + static_assert(1 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ + GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(1, constness, \ + Method).Invoke(::std::forward(gmock_a1)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ + GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \ + static_assert(2 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2) constness { \ + GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(2, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ + GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \ + static_assert(3 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, \ + __VA_ARGS__) gmock_a3) constness { \ + GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(3, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ + GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \ + static_assert(4 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ + GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(4, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ + GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \ + static_assert(5 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5) constness { \ + GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(5, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ + GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \ + static_assert(6 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, \ + __VA_ARGS__) gmock_a6) constness { \ + GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(6, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ + GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \ + static_assert(7 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ + GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(7, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ + GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \ + static_assert(8 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ + __VA_ARGS__) gmock_a8) constness { \ + GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(8, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7), \ + ::std::forward(gmock_a8)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ + GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \ + static_assert(9 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ + __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, \ + __VA_ARGS__) gmock_a9) constness { \ + GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(9, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7), \ + ::std::forward(gmock_a8), \ + ::std::forward(gmock_a9)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ + GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ + gmock_a9); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \ + static_assert(10 == \ + ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \ + "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \ + __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \ + __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \ + __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \ + GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ + GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(10, constness, \ + Method).Invoke(::std::forward(gmock_a1), \ + ::std::forward(gmock_a2), \ + ::std::forward(gmock_a3), \ + ::std::forward(gmock_a4), \ + ::std::forward(gmock_a5), \ + ::std::forward(gmock_a6), \ + ::std::forward(gmock_a7), \ + ::std::forward(gmock_a8), \ + ::std::forward(gmock_a9), \ + ::std::forward(gmock_a10)); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \ + GMOCK_MATCHER_(tn, 10, \ + __VA_ARGS__) gmock_a10) constness { \ + GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ + gmock_a10); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method(::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A(), \ + ::testing::A()); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \ + Method) + +#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__) +#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__) +#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__) +#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__) +#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__) +#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__) +#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__) +#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__) +#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__) +#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__) +#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__) + +#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T(m, ...) \ + GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T(m, ...) \ + GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T(m, ...) \ + GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T(m, ...) \ + GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T(m, ...) \ + GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T(m, ...) \ + GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T(m, ...) \ + GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T(m, ...) \ + GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T(m, ...) \ + GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T(m, ...) \ + GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T(m, ...) \ + GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__) + +#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(, , ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__) + +#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__) + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump new file mode 100644 index 00000000..a56e132f --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump @@ -0,0 +1,227 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert +$$ it to gmock-generated-function-mockers.h. +$$ +$var n = 10 $$ The maximum arity we support. +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements function mockers of various arities. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ + +#include +#include + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" + +namespace testing { +namespace internal { + +$range i 0..n +// Removes the given pointer; this is a helper for the expectation setter method +// for parameterless matchers. +// +// We want to make sure that the user cannot set a parameterless expectation on +// overloaded methods, including methods which are overloaded on const. Example: +// +// class MockClass { +// MOCK_METHOD0(GetName, string&()); +// MOCK_CONST_METHOD0(GetName, const string&()); +// }; +// +// TEST() { +// // This should be an error, as it's not clear which overload is expected. +// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); +// } +// +// Here are the generated expectation-setter methods: +// +// class MockClass { +// // Overload 1 +// MockSpec gmock_GetName() { ... } +// // Overload 2. Declared const so that the compiler will generate an +// // error when trying to resolve between this and overload 4 in +// // 'gmock_GetName(WithoutMatchers(), nullptr)'. +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Removes const from this, calls overload 1 +// return AdjustConstness_(this)->gmock_GetName(); +// } +// +// // Overload 3 +// const string& gmock_GetName() const { ... } +// // Overload 4 +// MockSpec gmock_GetName( +// const WithoutMatchers&, const Function*) const { +// // Does not remove const, calls overload 3 +// return AdjustConstness_const(this)->gmock_GetName(); +// } +// } +// +template +const MockType* AdjustConstness_const(const MockType* mock) { + return mock; +} + +// Removes const from and returns the given pointer; this is a helper for the +// expectation setter method for parameterless matchers. +template +MockType* AdjustConstness_(const MockType* mock) { + return const_cast(mock); +} + +} // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; + +// GMOCK_RESULT_(tn, F) expands to the result type of function type F. +// We define this as a variadic macro in case F contains unprotected +// commas (the same reason that we use variadic macros in other places +// in this file). +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_RESULT_(tn, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Result + +// The type of argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_ARG_(tn, N, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::template Arg::type + +// The matcher type for argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MATCHER_(tn, N, ...) \ + const ::testing::Matcher& + +// The variable for mocking the given method. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) + + +$for i [[ +$range j 1..i +$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] +$var as = [[$for j, \ + [[::std::forward(gmock_a$j)]]]] +$var matcher_arg_as = [[$for j, \ + [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] +$var matcher_as = [[$for j, [[gmock_a$j]]]] +$var anything_matchers = [[$for j, \ + [[::testing::A()]]]] +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ + static_assert($i == ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, "MOCK_METHOD must match argument count.");\ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + $arg_as) constness { \ + GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ + } \ + ::testing::MockSpec<__VA_ARGS__> \ + gmock_##Method($matcher_arg_as) constness { \ + GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \ + } \ + ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ + const ::testing::internal::WithoutMatchers&, \ + constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ + return ::testing::internal::AdjustConstness_##constness(this)-> \ + gmock_##Method($anything_matchers); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) + + +]] +$for i [[ +#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ + GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) + +]] + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h b/src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h new file mode 100644 index 00000000..690a57f1 --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h @@ -0,0 +1,1097 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-matchers.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic matchers. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ + +#include +#include +#include +#include +#include +#include "gmock/gmock-matchers.h" + +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// std::string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template +// FooMatcherPk +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +#define MATCHER(name, description)\ + class name##Matcher {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl()\ + {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple<>()));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl());\ + }\ + name##Matcher() {\ + }\ + private:\ + };\ + inline name##Matcher name() {\ + return name##Matcher();\ + }\ + template \ + bool name##Matcher::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P(name, p0, description)\ + template \ + class name##MatcherP {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + explicit gmock_Impl(p0##_type gmock_p0)\ + : p0(::std::move(gmock_p0)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0));\ + }\ + explicit name##MatcherP(p0##_type gmock_p0) : p0(::std::move(gmock_p0)) {\ + }\ + p0##_type const p0;\ + private:\ + };\ + template \ + inline name##MatcherP name(p0##_type p0) {\ + return name##MatcherP(p0);\ + }\ + template \ + template \ + bool name##MatcherP::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P2(name, p0, p1, description)\ + template \ + class name##MatcherP2 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1));\ + }\ + name##MatcherP2(p0##_type gmock_p0, \ + p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + private:\ + };\ + template \ + inline name##MatcherP2 name(p0##_type p0, \ + p1##_type p1) {\ + return name##MatcherP2(p0, p1);\ + }\ + template \ + template \ + bool name##MatcherP2::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P3(name, p0, p1, p2, description)\ + template \ + class name##MatcherP3 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2));\ + }\ + name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + private:\ + };\ + template \ + inline name##MatcherP3 name(p0##_type p0, \ + p1##_type p1, p2##_type p2) {\ + return name##MatcherP3(p0, p1, p2);\ + }\ + template \ + template \ + bool name##MatcherP3::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P4(name, p0, p1, p2, p3, description)\ + template \ + class name##MatcherP4 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, \ + p1, p2, p3)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3));\ + }\ + name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + private:\ + };\ + template \ + inline name##MatcherP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3) {\ + return name##MatcherP4(p0, \ + p1, p2, p3);\ + }\ + template \ + template \ + bool name##MatcherP4::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\ + template \ + class name##MatcherP5 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4));\ + }\ + name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + private:\ + };\ + template \ + inline name##MatcherP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4) {\ + return name##MatcherP5(p0, p1, p2, p3, p4);\ + }\ + template \ + template \ + bool name##MatcherP5::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\ + template \ + class name##MatcherP6 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5));\ + }\ + name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + private:\ + };\ + template \ + inline name##MatcherP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3, p4##_type p4, p5##_type p5) {\ + return name##MatcherP6(p0, p1, p2, p3, p4, p5);\ + }\ + template \ + template \ + bool name##MatcherP6::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\ + template \ + class name##MatcherP7 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5, \ + p6)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6));\ + }\ + name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + private:\ + };\ + template \ + inline name##MatcherP7 name(p0##_type p0, p1##_type p1, \ + p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6) {\ + return name##MatcherP7(p0, p1, p2, p3, p4, p5, p6);\ + }\ + template \ + template \ + bool name##MatcherP7::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\ + template \ + class name##MatcherP8 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, \ + p3, p4, p5, p6, p7)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7));\ + }\ + name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + private:\ + };\ + template \ + inline name##MatcherP8 name(p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6, p7##_type p7) {\ + return name##MatcherP8(p0, p1, p2, p3, p4, p5, \ + p6, p7);\ + }\ + template \ + template \ + bool name##MatcherP8::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\ + template \ + class name##MatcherP9 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \ + p8(::std::move(gmock_p8)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8));\ + }\ + name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + private:\ + };\ + template \ + inline name##MatcherP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ + p8##_type p8) {\ + return name##MatcherP9(p0, p1, p2, \ + p3, p4, p5, p6, p7, p8);\ + }\ + template \ + template \ + bool name##MatcherP9::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\ + template \ + class name##MatcherP10 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9)\ + : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \ + p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \ + p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \ + p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \ + p8(::std::move(gmock_p8)), p9(::std::move(gmock_p9)) {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + p9##_type const p9;\ + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\ + }\ + name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8, p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \ + p9(::std::move(gmock_p9)) {\ + }\ + p0##_type const p0;\ + p1##_type const p1;\ + p2##_type const p2;\ + p3##_type const p3;\ + p4##_type const p4;\ + p5##_type const p5;\ + p6##_type const p6;\ + p7##_type const p7;\ + p8##_type const p8;\ + p9##_type const p9;\ + private:\ + };\ + template \ + inline name##MatcherP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9) {\ + return name##MatcherP10(p0, \ + p1, p2, p3, p4, p5, p6, p7, p8, p9);\ + }\ + template \ + template \ + bool name##MatcherP10::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h.pump b/src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h.pump new file mode 100644 index 00000000..ae90917c --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-generated-matchers.h.pump @@ -0,0 +1,346 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert +$$ it to gmock-generated-matchers.h. +$$ +$var n = 10 $$ The maximum arity we support. +$$ }} This line fixes auto-indentation of the following code in Emacs. +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic matchers. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ + +#include +#include +#include +#include +#include +#include "gmock/gmock-matchers.h" + +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// std::string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template +// FooMatcherPk +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +$range i 0..n +$for i + +[[ +$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]] + $else [[MATCHER_P$i]]]] +$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]] + $else [[P$i]]]]]] +$range j 0..i-1 +$var template = [[$if i==0 [[]] $else [[ + + template <$for j, [[typename p$j##_type]]>\ +]]]] +$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]] +$var params = [[$for j, [[p$j]]]] +$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] +$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] +$var param_field_decls = [[$for j +[[ + + p$j##_type const p$j;\ +]]]] +$var param_field_decls2 = [[$for j +[[ + + p$j##_type const p$j;\ +]]]] + +#define $macro_name(name$for j [[, p$j]], description)\$template + class $class_name {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface<\ + GTEST_REFERENCE_TO_CONST_(arg_type)> {\ + public:\ + [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\ + $impl_inits {}\ + virtual bool MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\$param_field_decls + private:\ + ::std::string FormatDescription(bool negation) const {\ + ::std::string gmock_description = (description);\ + if (!gmock_description.empty()) {\ + return gmock_description;\ + }\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::std::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ + }\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl($params));\ + }\ + [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ + }\$param_field_decls2 + private:\ + };\$template + inline $class_name$param_types name($param_types_and_names) {\ + return $class_name$param_types($params);\ + }\$template + template \ + bool $class_name$param_types::gmock_Impl::MatchAndExplain(\ + GTEST_REFERENCE_TO_CONST_(arg_type) arg,\ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const +]] + + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/src/test/gtest/googlemock/include/gmock/gmock-matchers.h b/src/test/gtest/googlemock/include/gmock/gmock-matchers.h new file mode 100644 index 00000000..28e188bb --- /dev/null +++ b/src/test/gtest/googlemock/include/gmock/gmock-matchers.h @@ -0,0 +1,4568 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used argument matchers. More +// matchers can be defined by the user implementing the +// MatcherInterface interface if necessary. +// +// See googletest/include/gtest/gtest-matchers.h for the definition of class +// Matcher, class MatcherInterface, and others. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ + +#include +#include +#include +#include +#include +#include +#include // NOLINT +#include +#include +#include +#include +#include +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +// MSVC warning C5046 is new as of VS2017 version 15.8. +#if defined(_MSC_VER) && _MSC_VER >= 1915 +#define GMOCK_MAYBE_5046_ 5046 +#else +#define GMOCK_MAYBE_5046_ +#endif + +GTEST_DISABLE_MSC_WARNINGS_PUSH_( + 4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by + clients of class B */ + /* Symbol involving type with internal linkage not defined */) + +namespace testing { + +// To implement a matcher Foo for type T, define: +// 1. a class FooMatcherImpl that implements the +// MatcherInterface interface, and +// 2. a factory function that creates a Matcher object from a +// FooMatcherImpl*. +// +// The two-level delegation design makes it possible to allow a user +// to write "v" instead of "Eq(v)" where a Matcher is expected, which +// is impossible if we pass matchers by pointers. It also eases +// ownership management as Matcher objects can now be copied like +// plain values. + +// A match result listener that stores the explanation in a string. +class StringMatchResultListener : public MatchResultListener { + public: + StringMatchResultListener() : MatchResultListener(&ss_) {} + + // Returns the explanation accumulated so far. + std::string str() const { return ss_.str(); } + + // Clears the explanation accumulated so far. + void Clear() { ss_.str(""); } + + private: + ::std::stringstream ss_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); +}; + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// The MatcherCastImpl class template is a helper for implementing +// MatcherCast(). We need this helper in order to partially +// specialize the implementation of MatcherCast() (C++ allows +// class/struct templates to be partially specialized, but not +// function templates.). + +// This general version is used when MatcherCast()'s argument is a +// polymorphic matcher (i.e. something that can be converted to a +// Matcher but is not one yet; for example, Eq(value)) or a value (for +// example, "hello"). +template +class MatcherCastImpl { + public: + static Matcher Cast(const M& polymorphic_matcher_or_value) { + // M can be a polymorphic matcher, in which case we want to use + // its conversion operator to create Matcher. Or it can be a value + // that should be passed to the Matcher's constructor. + // + // We can't call Matcher(polymorphic_matcher_or_value) when M is a + // polymorphic matcher because it'll be ambiguous if T has an implicit + // constructor from M (this usually happens when T has an implicit + // constructor from any type). + // + // It won't work to unconditionally implict_cast + // polymorphic_matcher_or_value to Matcher because it won't trigger + // a user-defined conversion from M to T if one exists (assuming M is + // a value). + return CastImpl(polymorphic_matcher_or_value, + std::is_convertible>{}, + std::is_convertible{}); + } + + private: + template + static Matcher CastImpl(const M& polymorphic_matcher_or_value, + std::true_type /* convertible_to_matcher */, + bool_constant) { + // M is implicitly convertible to Matcher, which means that either + // M is a polymorphic matcher or Matcher has an implicit constructor + // from M. In both cases using the implicit conversion will produce a + // matcher. + // + // Even if T has an implicit constructor from M, it won't be called because + // creating Matcher would require a chain of two user-defined conversions + // (first to create T from M and then to create Matcher from T). + return polymorphic_matcher_or_value; + } + + // M can't be implicitly converted to Matcher, so M isn't a polymorphic + // matcher. It's a value of a type implicitly convertible to T. Use direct + // initialization to create a matcher. + static Matcher CastImpl(const M& value, + std::false_type /* convertible_to_matcher */, + std::true_type /* convertible_to_T */) { + return Matcher(ImplicitCast_(value)); + } + + // M can't be implicitly converted to either Matcher or T. Attempt to use + // polymorphic matcher Eq(value) in this case. + // + // Note that we first attempt to perform an implicit cast on the value and + // only fall back to the polymorphic Eq() matcher afterwards because the + // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end + // which might be undefined even when Rhs is implicitly convertible to Lhs + // (e.g. std::pair vs. std::pair). + // + // We don't define this method inline as we need the declaration of Eq(). + static Matcher CastImpl(const M& value, + std::false_type /* convertible_to_matcher */, + std::false_type /* convertible_to_T */); +}; + +// This more specialized version is used when MatcherCast()'s argument +// is already a Matcher. This only compiles when type T can be +// statically converted to type U. +template +class MatcherCastImpl > { + public: + static Matcher Cast(const Matcher& source_matcher) { + return Matcher(new Impl(source_matcher)); + } + + private: + class Impl : public MatcherInterface { + public: + explicit Impl(const Matcher& source_matcher) + : source_matcher_(source_matcher) {} + + // We delegate the matching logic to the source matcher. + bool MatchAndExplain(T x, MatchResultListener* listener) const override { + using FromType = typename std::remove_cv::type>::type>::type; + using ToType = typename std::remove_cv::type>::type>::type; + // Do not allow implicitly converting base*/& to derived*/&. + static_assert( + // Do not trigger if only one of them is a pointer. That implies a + // regular conversion and not a down_cast. + (std::is_pointer::type>::value != + std::is_pointer::type>::value) || + std::is_same::value || + !std::is_base_of::value, + "Can't implicitly convert from to "); + + return source_matcher_.MatchAndExplain(static_cast(x), listener); + } + + void DescribeTo(::std::ostream* os) const override { + source_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + source_matcher_.DescribeNegationTo(os); + } + + private: + const Matcher source_matcher_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; +}; + +// This even more specialized version is used for efficiently casting +// a matcher to its own type. +template +class MatcherCastImpl > { + public: + static Matcher Cast(const Matcher& matcher) { return matcher; } +}; + +} // namespace internal + +// In order to be safe and clear, casting between different matcher +// types is done explicitly via MatcherCast(m), which takes a +// matcher m and returns a Matcher. It compiles only when T can be +// statically converted to the argument type of m. +template +inline Matcher MatcherCast(const M& matcher) { + return internal::MatcherCastImpl::Cast(matcher); +} + +// Implements SafeMatcherCast(). +// +// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a +// workaround for a compiler bug, and can now be removed. +template +class SafeMatcherCastImpl { + public: + // This overload handles polymorphic matchers and values only since + // monomorphic matchers are handled by the next one. + template + static inline Matcher Cast(const M& polymorphic_matcher_or_value) { + return internal::MatcherCastImpl::Cast(polymorphic_matcher_or_value); + } + + // This overload handles monomorphic matchers. + // + // In general, if type T can be implicitly converted to type U, we can + // safely convert a Matcher to a Matcher (i.e. Matcher is + // contravariant): just keep a copy of the original Matcher, convert the + // argument from type T to U, and then pass it to the underlying Matcher. + // The only exception is when U is a reference and T is not, as the + // underlying Matcher may be interested in the argument's address, which + // is not preserved in the conversion from T to U. + template + static inline Matcher Cast(const Matcher& matcher) { + // Enforce that T can be implicitly converted to U. + GTEST_COMPILE_ASSERT_((std::is_convertible::value), + "T must be implicitly convertible to U"); + // Enforce that we are not converting a non-reference type T to a reference + // type U. + GTEST_COMPILE_ASSERT_( + std::is_reference::value || !std::is_reference::value, + cannot_convert_non_reference_arg_to_reference); + // In case both T and U are arithmetic types, enforce that the + // conversion is not lossy. + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; + const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; + const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; + GTEST_COMPILE_ASSERT_( + kTIsOther || kUIsOther || + (internal::LosslessArithmeticConvertible::value), + conversion_of_arithmetic_types_must_be_lossless); + return MatcherCast(matcher); + } +}; + +template +inline Matcher SafeMatcherCast(const M& polymorphic_matcher) { + return SafeMatcherCastImpl::Cast(polymorphic_matcher); +} + +// A() returns a matcher that matches any value of type T. +template +Matcher A(); + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// If the explanation is not empty, prints it to the ostream. +inline void PrintIfNotEmpty(const std::string& explanation, + ::std::ostream* os) { + if (explanation != "" && os != nullptr) { + *os << ", " << explanation; + } +} + +// Returns true if the given type name is easy to read by a human. +// This is used to decide whether printing the type of a value might +// be helpful. +inline bool IsReadableTypeName(const std::string& type_name) { + // We consider a type name readable if it's short or doesn't contain + // a template or function type. + return (type_name.length() <= 20 || + type_name.find_first_of("<(") == std::string::npos); +} + +// Matches the value against the given matcher, prints the value and explains +// the match result to the listener. Returns the match result. +// 'listener' must not be NULL. +// Value cannot be passed by const reference, because some matchers take a +// non-const argument. +template +bool MatchPrintAndExplain(Value& value, const Matcher& matcher, + MatchResultListener* listener) { + if (!listener->IsInterested()) { + // If the listener is not interested, we do not need to construct the + // inner explanation. + return matcher.Matches(value); + } + + StringMatchResultListener inner_listener; + const bool match = matcher.MatchAndExplain(value, &inner_listener); + + UniversalPrint(value, listener->stream()); +#if GTEST_HAS_RTTI + const std::string& type_name = GetTypeName(); + if (IsReadableTypeName(type_name)) + *listener->stream() << " (of type " << type_name << ")"; +#endif + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + + return match; +} + +// An internal helper class for doing compile-time loop on a tuple's +// fields. +template +class TuplePrefix { + public: + // TuplePrefix::Matches(matcher_tuple, value_tuple) returns true + // if and only if the first N fields of matcher_tuple matches + // the first N fields of value_tuple, respectively. + template + static bool Matches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + return TuplePrefix::Matches(matcher_tuple, value_tuple) && + std::get(matcher_tuple).Matches(std::get(value_tuple)); + } + + // TuplePrefix::ExplainMatchFailuresTo(matchers, values, os) + // describes failures in matching the first N fields of matchers + // against the first N fields of values. If there is no failure, + // nothing will be streamed to os. + template + static void ExplainMatchFailuresTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + // First, describes failures in the first N - 1 fields. + TuplePrefix::ExplainMatchFailuresTo(matchers, values, os); + + // Then describes the failure (if any) in the (N - 1)-th (0-based) + // field. + typename std::tuple_element::type matcher = + std::get(matchers); + typedef typename std::tuple_element::type Value; + const Value& value = std::get(values); + StringMatchResultListener listener; + if (!matcher.MatchAndExplain(value, &listener)) { + *os << " Expected arg #" << N - 1 << ": "; + std::get(matchers).DescribeTo(os); + *os << "\n Actual: "; + // We remove the reference in type Value to prevent the + // universal printer from printing the address of value, which + // isn't interesting to the user most of the time. The + // matcher's MatchAndExplain() method handles the case when + // the address is interesting. + internal::UniversalPrint(value, os); + PrintIfNotEmpty(listener.str(), os); + *os << "\n"; + } + } +}; + +// The base case. +template <> +class TuplePrefix<0> { + public: + template + static bool Matches(const MatcherTuple& /* matcher_tuple */, + const ValueTuple& /* value_tuple */) { + return true; + } + + template + static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */, + const ValueTuple& /* values */, + ::std::ostream* /* os */) {} +}; + +// TupleMatches(matcher_tuple, value_tuple) returns true if and only if +// all matchers in matcher_tuple match the corresponding fields in +// value_tuple. It is a compiler error if matcher_tuple and +// value_tuple have different number of fields or incompatible field +// types. +template +bool TupleMatches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + // Makes sure that matcher_tuple and value_tuple have the same + // number of fields. + GTEST_COMPILE_ASSERT_(std::tuple_size::value == + std::tuple_size::value, + matcher_and_value_have_different_numbers_of_fields); + return TuplePrefix::value>::Matches(matcher_tuple, + value_tuple); +} + +// Describes failures in matching matchers against values. If there +// is no failure, nothing will be streamed to os. +template +void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + TuplePrefix::value>::ExplainMatchFailuresTo( + matchers, values, os); +} + +// TransformTupleValues and its helper. +// +// TransformTupleValuesHelper hides the internal machinery that +// TransformTupleValues uses to implement a tuple traversal. +template +class TransformTupleValuesHelper { + private: + typedef ::std::tuple_size TupleSize; + + public: + // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. + // Returns the final value of 'out' in case the caller needs it. + static OutIter Run(Func f, const Tuple& t, OutIter out) { + return IterateOverTuple()(f, t, out); + } + + private: + template + struct IterateOverTuple { + OutIter operator() (Func f, const Tup& t, OutIter out) const { + *out++ = f(::std::get(t)); + return IterateOverTuple()(f, t, out); + } + }; + template + struct IterateOverTuple { + OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { + return out; + } + }; +}; + +// Successively invokes 'f(element)' on each element of the tuple 't', +// appending each result to the 'out' iterator. Returns the final value +// of 'out'. +template +OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { + return TransformTupleValuesHelper::Run(f, t, out); +} + +// Implements A(). +template +class AnyMatcherImpl : public MatcherInterface { + public: + bool MatchAndExplain(const T& /* x */, + MatchResultListener* /* listener */) const override { + return true; + } + void DescribeTo(::std::ostream* os) const override { *os << "is anything"; } + void DescribeNegationTo(::std::ostream* os) const override { + // This is mostly for completeness' safe, as it's not very useful + // to write Not(A()). However we cannot completely rule out + // such a possibility, and it doesn't hurt to be prepared. + *os << "never matches"; + } +}; + +// Implements _, a matcher that matches any value of any +// type. This is a polymorphic matcher, so we need a template type +// conversion operator to make it appearing as a Matcher for any +// type T. +class AnythingMatcher { + public: + template + operator Matcher() const { return A(); } +}; + +// Implements the polymorphic IsNull() matcher, which matches any raw or smart +// pointer that is NULL. +class IsNullMatcher { + public: + template + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return p == nullptr; + } + + void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "isn't NULL"; + } +}; + +// Implements the polymorphic NotNull() matcher, which matches any raw or smart +// pointer that is not NULL. +class NotNullMatcher { + public: + template + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return p != nullptr; + } + + void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "is NULL"; + } +}; + +// Ref(variable) matches any argument that is a reference to +// 'variable'. This matcher is polymorphic as it can match any +// super type of the type of 'variable'. +// +// The RefMatcher template class implements Ref(variable). It can +// only be instantiated with a reference type. This prevents a user +// from mistakenly using Ref(x) to match a non-reference function +// argument. For example, the following will righteously cause a +// compiler error: +// +// int n; +// Matcher m1 = Ref(n); // This won't compile. +// Matcher m2 = Ref(n); // This will compile. +template +class RefMatcher; + +template +class RefMatcher { + // Google Mock is a generic framework and thus needs to support + // mocking any function types, including those that take non-const + // reference arguments. Therefore the template parameter T (and + // Super below) can be instantiated to either a const type or a + // non-const type. + public: + // RefMatcher() takes a T& instead of const T&, as we want the + // compiler to catch using Ref(const_value) as a matcher for a + // non-const reference. + explicit RefMatcher(T& x) : object_(x) {} // NOLINT + + template + operator Matcher() const { + // By passing object_ (type T&) to Impl(), which expects a Super&, + // we make sure that Super is a super type of T. In particular, + // this catches using Ref(const_value) as a matcher for a + // non-const reference, as you cannot implicitly convert a const + // reference to a non-const reference. + return MakeMatcher(new Impl(object_)); + } + + private: + template + class Impl : public MatcherInterface { + public: + explicit Impl(Super& x) : object_(x) {} // NOLINT + + // MatchAndExplain() takes a Super& (as opposed to const Super&) + // in order to match the interface MatcherInterface. + bool MatchAndExplain(Super& x, + MatchResultListener* listener) const override { + *listener << "which is located @" << static_cast(&x); + return &x == &object_; + } + + void DescribeTo(::std::ostream* os) const override { + *os << "references the variable "; + UniversalPrinter::Print(object_, os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "does not reference the variable "; + UniversalPrinter::Print(object_, os); + } + + private: + const Super& object_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + T& object_; + + GTEST_DISALLOW_ASSIGN_(RefMatcher); +}; + +// Polymorphic helper functions for narrow and wide string matchers. +inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { + return String::CaseInsensitiveCStringEquals(lhs, rhs); +} + +inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + return String::CaseInsensitiveWideCStringEquals(lhs, rhs); +} + +// String comparison for narrow or wide strings that can have embedded NUL +// characters. +template +bool CaseInsensitiveStringEquals(const StringType& s1, + const StringType& s2) { + // Are the heads equal? + if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { + return false; + } + + // Skip the equal heads. + const typename StringType::value_type nul = 0; + const size_t i1 = s1.find(nul), i2 = s2.find(nul); + + // Are we at the end of either s1 or s2? + if (i1 == StringType::npos || i2 == StringType::npos) { + return i1 == i2; + } + + // Are the tails equal? + return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); +} + +// String matchers. + +// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. +template +class StrEqualityMatcher { + public: + StrEqualityMatcher(const StringType& str, bool expect_eq, + bool case_sensitive) + : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + if (s == nullptr) { + return !expect_eq_; + } + return MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + const bool eq = case_sensitive_ ? s2 == string_ : + CaseInsensitiveStringEquals(s2, string_); + return expect_eq_ == eq; + } + + void DescribeTo(::std::ostream* os) const { + DescribeToHelper(expect_eq_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + DescribeToHelper(!expect_eq_, os); + } + + private: + void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { + *os << (expect_eq ? "is " : "isn't "); + *os << "equal to "; + if (!case_sensitive_) { + *os << "(ignoring case) "; + } + UniversalPrint(string_, os); + } + + const StringType string_; + const bool expect_eq_; + const bool case_sensitive_; + + GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher); +}; + +// Implements the polymorphic HasSubstr(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class HasSubstrMatcher { + public: + explicit HasSubstrMatcher(const StringType& substring) + : substring_(substring) {} + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.find(substring_) != StringType::npos; + } + + // Describes what this matcher matches. + void DescribeTo(::std::ostream* os) const { + *os << "has substring "; + UniversalPrint(substring_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "has no substring "; + UniversalPrint(substring_, os); + } + + private: + const StringType substring_; + + GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher); +}; + +// Implements the polymorphic StartsWith(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class StartsWithMatcher { + public: + explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { + } + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= prefix_.length() && + s2.substr(0, prefix_.length()) == prefix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "starts with "; + UniversalPrint(prefix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't start with "; + UniversalPrint(prefix_, os); + } + + private: + const StringType prefix_; + + GTEST_DISALLOW_ASSIGN_(StartsWithMatcher); +}; + +// Implements the polymorphic EndsWith(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class EndsWithMatcher { + public: + explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} + +#if GTEST_HAS_ABSL + bool MatchAndExplain(const absl::string_view& s, + MatchResultListener* listener) const { + // This should fail to compile if absl::string_view is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_HAS_ABSL + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because absl::string_view has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= suffix_.length() && + s2.substr(s2.length() - suffix_.length()) == suffix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "ends with "; + UniversalPrint(suffix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't end with "; + UniversalPrint(suffix_, os); + } + + private: + const StringType suffix_; + + GTEST_DISALLOW_ASSIGN_(EndsWithMatcher); +}; + +// Implements a matcher that compares the two fields of a 2-tuple +// using one of the ==, <=, <, etc, operators. The two fields being +// compared don't have to have the same type. +// +// The matcher defined here is polymorphic (for example, Eq() can be +// used to match a std::tuple, a std::tuple, +// etc). Therefore we use a template type conversion operator in the +// implementation. +template +class PairMatchBase { + public: + template + operator Matcher<::std::tuple>() const { + return Matcher<::std::tuple>(new Impl&>); + } + template + operator Matcher&>() const { + return MakeMatcher(new Impl&>); + } + + private: + static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT + return os << D::Desc(); + } + + template + class Impl : public MatcherInterface { + public: + bool MatchAndExplain(Tuple args, + MatchResultListener* /* listener */) const override { + return Op()(::std::get<0>(args), ::std::get<1>(args)); + } + void DescribeTo(::std::ostream* os) const override { + *os << "are " << GetDesc; + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << "aren't " << GetDesc; + } + }; +}; + +class Eq2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "an equal pair"; } +}; +class Ne2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "an unequal pair"; } +}; +class Lt2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first < the second"; } +}; +class Gt2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first > the second"; } +}; +class Le2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first <= the second"; } +}; +class Ge2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first >= the second"; } +}; + +// Implements the Not(...) matcher for a particular argument type T. +// We do not nest it inside the NotMatcher class template, as that +// will prevent different instantiations of NotMatcher from sharing +// the same NotMatcherImpl class. +template +class NotMatcherImpl : public MatcherInterface { + public: + explicit NotMatcherImpl(const Matcher& matcher) + : matcher_(matcher) {} + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + return !matcher_.MatchAndExplain(x, listener); + } + + void DescribeTo(::std::ostream* os) const override { + matcher_.DescribeNegationTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + matcher_.DescribeTo(os); + } + + private: + const Matcher matcher_; + + GTEST_DISALLOW_ASSIGN_(NotMatcherImpl); +}; + +// Implements the Not(m) matcher, which matches a value that doesn't +// match matcher m. +template +class NotMatcher { + public: + explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} + + // This template type conversion operator allows Not(m) to be used + // to match any type m can match. + template + operator Matcher() const { + return Matcher(new NotMatcherImpl(SafeMatcherCast(matcher_))); + } + + private: + InnerMatcher matcher_; + + GTEST_DISALLOW_ASSIGN_(NotMatcher); +}; + +// Implements the AllOf(m1, m2) matcher for a particular argument type +// T. We do not nest it inside the BothOfMatcher class template, as +// that will prevent different instantiations of BothOfMatcher from +// sharing the same BothOfMatcherImpl class. +template +class AllOfMatcherImpl : public MatcherInterface { + public: + explicit AllOfMatcherImpl(std::vector > matchers) + : matchers_(std::move(matchers)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") and ("; + matchers_[i].DescribeTo(os); + } + *os << ")"; + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") or ("; + matchers_[i].DescribeNegationTo(os); + } + *os << ")"; + } + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + // If either matcher1_ or matcher2_ doesn't match x, we only need + // to explain why one of them fails. + std::string all_match_result; + + for (size_t i = 0; i < matchers_.size(); ++i) { + StringMatchResultListener slistener; + if (matchers_[i].MatchAndExplain(x, &slistener)) { + if (all_match_result.empty()) { + all_match_result = slistener.str(); + } else { + std::string result = slistener.str(); + if (!result.empty()) { + all_match_result += ", and "; + all_match_result += result; + } + } + } else { + *listener << slistener.str(); + return false; + } + } + + // Otherwise we need to explain why *both* of them match. + *listener << all_match_result; + return true; + } + + private: + const std::vector > matchers_; + + GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl); +}; + +// VariadicMatcher is used for the variadic implementation of +// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). +// CombiningMatcher is used to recursively combine the provided matchers +// (of type Args...). +template